diff --git a/.github/workflows/codeql.yaml b/.github/workflows/codeql.yaml new file mode 100644 index 00000000000..e5bd9a22109 --- /dev/null +++ b/.github/workflows/codeql.yaml @@ -0,0 +1,162 @@ +name: "CodeQL Scanner" +on: + push: + branches: + - 'master' + - 'release/**' + - 'hotfix/**' + paths-ignore: + - '**/README.md' + - '**/LICENSE' + - '.github/**' + #pull_request: + # branches: + # - 'master' + # - 'release/**' + # - 'hotfix/**' + schedule: + - cron: '00 19 * * 5' + +# This job take a lot of time, so if the number of worker +# processes from one branch or one PR exceeds 1, all previous +# running processes will be automatically canceled to avoid the accumulation +# of a large number of concurrent workers +concurrency: + group: codeql-${{ github.event.pull_request.number || github.ref_name }} + cancel-in-progress: true + +env: + SOURCE_ROOT: "/build/core" + +jobs: + analyze: + name: Analyze + runs-on: ${{ 'ubuntu-latest' }} + container: + image: ${{ matrix.image }} + options: --privileged + volumes: + - /usr/local/lib:/foovolume/android + - /usr/local/share:/foovolume/boost + - /usr/share:/foovolume/dotnet + - /opt:/foovolume/opt + - /opt/hostedtoolcache:/foovolume/tool + timeout-minutes: ${{ (matrix.language == 'swift' && 120) || 360 }} + permissions: + actions: read + contents: read + security-events: write + + strategy: + fail-fast: false + matrix: + language: [ 'c-cpp' ] + image: ["ubuntu:20.04"] + # CodeQL supports [ 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'swift' ] + # Use only 'java-kotlin' to analyze code written in Java, Kotlin or both + # Use only 'javascript-typescript' to analyze code written in JavaScript, TypeScript or both + # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support + + steps: + - uses: actions/setup-node@v4 + with: + node-version: 20 + + - name: make free space in container + run: | + rm -rf /foovolume/android/android + rm -rf /foovolume/dotnet/dotnet + rm -rf /foovolume/boost/boost + rm -rf /foovolume/opt/ghc + rm -rf /foovolume/tool/* + df -h + + # Prepare container environment + # Install some deps + # Set cache restore keys + - name: Prepare environment + id: prepare + shell: bash + env: + TZ: Etc/UTC + run: | + pwd + ls -la + ln -snf /usr/share/zoneinfo/$TZ /etc/localtime + echo $TZ > /etc/timezone + apt-get update + apt-get install -y python3 python2 sudo curl jq git + apt-get install -y python || true + rm /usr/bin/python || true + ln -s /usr/bin/python2 /usr/bin/python + mkdir -p /build + git clone --depth 1 \ + --single-branch \ + --branch ${{ github.base_ref || github.ref_name }} https://github.com/ONLYOFFICE/core.git ${SOURCE_ROOT} + git clone --depth 1 \ + --single-branch \ + --branch ${{ github.base_ref || github.ref_name }} https://github.com/ONLYOFFICE/build_tools.git /build/build_tools + echo "party-key=$(curl -L -H "Accept: application/vnd.github+json" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + "https://api.github.com/repos/ONLYOFFICE/core/commits?per_page=1&path=/Common/3dParty&sha=${{ github.base_ref || github.ref_name }}" | \ + jq -r '.[].sha')" >> "$GITHUB_OUTPUT" + echo "qt-key=$(cat /build/build_tools/tools/linux/automate.py | egrep -m1 -o "qt_source_([0-9])?.([0-9])?.([0-9])?")" >> "$GITHUB_OUTPUT" + + # Restore 3dParty from cache if cache key is match + - uses: actions/cache/restore@v3 + id: restore-3d + with: + path: /build/core/Common/3dParty + key: 3dParty-${{ steps.prepare.outputs.party-key }} + + # Restore qt tool from cache if cache key is match + - uses: actions/cache/restore@v3 + id: restore-qt + with: + path: /build/build_tools/tools/linux/qt_build + key: qt-${{ steps.prepare.outputs.qt-key }} + + # NOTE: + # init codeql with custom source-root dir + # because sources code was checkout with git from cli + # NOT with checkout action + # Also. Init and scan with codeql only if all cache hit + # otherwise will no initialization, just build and cache depends + - name: Initialize CodeQL + if: > + steps.restore-3d.outputs.cache-hit == 'true' + && steps.restore-qt.outputs.cache-hit == 'true' + uses: github/codeql-action/init@v3 + with: + languages: ${{ matrix.language }} + source-root: ${{ env.SOURCE_ROOT }} + + - name: build + shell: bash + run: | + cd /build/build_tools/tools/linux + python3 ./automate.py core + + - name: Perform CodeQL Analysis + if: > + steps.restore-3d.outputs.cache-hit == 'true' + && steps.restore-qt.outputs.cache-hit == 'true' + uses: github/codeql-action/analyze@v3 + with: + category: "/language:${{matrix.language}}" + + # Make new 3dParty cache if restore action do not restore any cache + - uses: actions/cache/save@v3 + if: steps.restore-3d.outputs.cache-hit != 'true' + id: save-3d + with: + path: /build/core/Common/3dParty + key: 3dParty-${{ steps.prepare.outputs.party-key }} + + # Make new qt tool cache if restore action do not restore any cache + - uses: actions/cache/save@v3 + if: steps.restore-qt.outputs.cache-hit != 'true' + id: save-qt + with: + path: /build/build_tools/tools/linux/qt_build + key: qt-${{ steps.prepare.outputs.qt-key }} diff --git a/.gitignore b/.gitignore index a8205889060..0cc29c3ddd8 100644 --- a/.gitignore +++ b/.gitignore @@ -46,3 +46,5 @@ DesktopEditor/fontengine/js/common/freetype-2.10.4 .qtc_clangd Common/3dParty/openssl/openssl/ + +msvc_make.bat diff --git a/3DPARTY.md b/3DPARTY.md new file mode 100644 index 00000000000..c4fb68308e6 --- /dev/null +++ b/3DPARTY.md @@ -0,0 +1,18 @@ + +## Third-party + +- boost ([BSL](https://raw.githubusercontent.com/boostorg/boost/master/LICENSE_1_0.txt)) +- icu ([UNICODE LICENSE V3](https://raw.githubusercontent.com/unicode-org/icu/main/LICENSE)) +- freetype ([FTL](https://raw.githubusercontent.com/freetype/freetype/master/docs/FTL.TXT)) +- harfbuzz ([MIT](https://raw.githubusercontent.com/harfbuzz/harfbuzz/main/COPYING)) +- hyphen ([MPL](https://raw.githubusercontent.com/hunspell/hyphen/master/COPYING)) +- hunspell ([MPL](https://raw.githubusercontent.com/hunspell/hunspell/master/COPYING.MPL)) +- gumbo ([Apache-2.0](https://raw.githubusercontent.com/google/gumbo-parser/master/COPYING)) +- katana ([MIT](https://raw.githubusercontent.com/jasenhuang/katana-parser/master/LICENSE)) +- cximage ([CXIMAGE LICENCE](https://raw.githubusercontent.com/movableink/cximage/master/license.txt)) +- openjpeg ([2-clause BSD License](https://raw.githubusercontent.com/uclouvain/openjpeg/master/LICENSE)) +- socket.io-client-cpp ([MIT](https://raw.githubusercontent.com/socketio/socket.io-client-cpp/master/LICENSE)) +- curl ([CURL LICENCE](https://raw.githubusercontent.com/curl/curl/master/COPYING)) +- cryptopp ([BSL](https://raw.githubusercontent.com/weidai11/cryptopp/master/License.txt)) +- openssl ([Apache-2.0](https://raw.githubusercontent.com/openssl/openssl/master/LICENSE.txt)) +- v8 ([3-clause BSD License](https://raw.githubusercontent.com/v8/v8/main/LICENSE)) diff --git a/Apple/IWork.cpp b/Apple/IWork.cpp new file mode 100644 index 00000000000..bf1d9e2f65c --- /dev/null +++ b/Apple/IWork.cpp @@ -0,0 +1,141 @@ +#include "IWork.h" +#include "../DesktopEditor/common/File.h" +#include "../DesktopEditor/common/Directory.h" + +#include +#include +#include +#include +#include + +#include +#include + +class CIWorkFile_Private +{ +public: + std::wstring m_sTempDirectory; + +public: + CIWorkFile_Private() + { + } + ~CIWorkFile_Private() + { + } +}; + +CIWorkFile::CIWorkFile() +{ + m_internal = new CIWorkFile_Private(); +} + +CIWorkFile::~CIWorkFile() +{ + delete m_internal; +} + +#if !defined(_WIN32) && !defined(_WIN64) + #define DATA_TYPE_INPUTFILE std::string +#else + #define DATA_TYPE_INPUTFILE std::wstring +#endif + +bool GetRVNGInputStream(const DATA_TYPE_INPUTFILE& sFile, std::shared_ptr& oRVNGInputStream, libetonyek::EtonyekDocument::Type& oDocumentType) +{ + oRVNGInputStream.reset(new librevenge::RVNGFileStream(sFile.c_str())); + + oDocumentType = libetonyek::EtonyekDocument::TYPE_UNKNOWN; + const libetonyek::EtonyekDocument::Confidence confidence = libetonyek::EtonyekDocument::isSupported(oRVNGInputStream.get(), &oDocumentType); + + return libetonyek::EtonyekDocument::CONFIDENCE_NONE != confidence; +} + +IWorkFileType CIWorkFile::GetType(const std::wstring& sFile) const +{ + //TODO:: так как на данный момент мы работает только напрямую с файлом, то работа с директорией нам пока не нужна + if (NSDirectory::PathIsDirectory(sFile)) + return IWorkFileType::None; + + std::shared_ptr input; + libetonyek::EtonyekDocument::Type oDocumentType; + + #if !defined(_WIN32) && !defined(_WIN64) + std::string sFileA = U_TO_UTF8(sFile); + if (!GetRVNGInputStream(sFileA, input, oDocumentType)) + return IWorkFileType::None; + #else + if (!GetRVNGInputStream(sFile, input, oDocumentType)) + return IWorkFileType::None; + #endif + + switch (oDocumentType) + { + case libetonyek::EtonyekDocument::TYPE_PAGES: + return IWorkFileType::Pages; + case libetonyek::EtonyekDocument::TYPE_NUMBERS: + return IWorkFileType::Numbers; + case libetonyek::EtonyekDocument::TYPE_KEYNOTE: + return IWorkFileType::Keynote; + default: + break; + } + + return IWorkFileType::None; +} + +template +int Convert(const std::wstring& wsOutputFile, std::shared_ptr& ptrInput, const std::wstring& wsPassword = L"", const std::wstring& wsTempDirectory = L"") +{ + StringDocumentHandler content; + Generator generator; + generator.addDocumentHandler(&content, ODF_FLAT_XML); + + bool bRes = libetonyek::EtonyekDocument::parse(ptrInput.get(), &generator); + if (!bRes) + return 1; + + const std::string sOutputFileA = U_TO_UTF8(wsOutputFile); + std::ofstream output(sOutputFileA.c_str()); + output << content.cstr(); + + if (output.bad()) + return -1; + + return 0; +} + +int CIWorkFile::Convert2Odf(const std::wstring& sFile, const std::wstring& sOutputFile) const +{ + //TODO:: так как на данный момент мы работает только напрямую с файлом, то работа с директорией нам пока не нужна + if (NSDirectory::PathIsDirectory(sFile)) + return -1; + + std::shared_ptr input; + libetonyek::EtonyekDocument::Type oDocumentType; + + #if !defined(_WIN32) && !defined(_WIN64) + std::string sFileA = U_TO_UTF8(sFile); + if (!GetRVNGInputStream(sFileA, input, oDocumentType)) + return -1; + #else + if (!GetRVNGInputStream(sFile, input, oDocumentType)) + return -1; + #endif + + switch (oDocumentType) + { + case libetonyek::EtonyekDocument::TYPE_PAGES: return Convert(sOutputFile, input); + case libetonyek::EtonyekDocument::TYPE_NUMBERS: return Convert(sOutputFile, input); + case libetonyek::EtonyekDocument::TYPE_KEYNOTE: return Convert(sOutputFile, input); + default: + break; + } + + return -1; +} + +void CIWorkFile::SetTmpDirectory(const std::wstring& sFolder) +{ + m_internal->m_sTempDirectory = sFolder; +} diff --git a/Apple/IWork.h b/Apple/IWork.h new file mode 100644 index 00000000000..2de5ec96b0f --- /dev/null +++ b/Apple/IWork.h @@ -0,0 +1,36 @@ +#ifndef _IWORKFILE_IWORKFILE_H +#define _IWORKFILE_IWORKFILE_H + +#include + +#ifndef IWORK_USE_DYNAMIC_LIBRARY +#define IWORK_FILE_DECL_EXPORT +#else +#include "../DesktopEditor/common/base_export.h" +#define IWORK_FILE_DECL_EXPORT Q_DECL_EXPORT +#endif + +enum class IWorkFileType +{ + Pages = 0, + Numbers = 1, + Keynote = 2, + + None = 255 +}; + +class CIWorkFile_Private; +class IWORK_FILE_DECL_EXPORT CIWorkFile +{ +private: + CIWorkFile_Private* m_internal; +public: + CIWorkFile(); + ~CIWorkFile(); + + IWorkFileType GetType(const std::wstring& sFile) const; + int Convert2Odf(const std::wstring& sFile, const std::wstring& sOutputFile) const; + void SetTmpDirectory(const std::wstring& sFolder); +}; + +#endif // _IWORKFILE_IWORKFILE_H diff --git a/Apple/IWork.pro b/Apple/IWork.pro new file mode 100644 index 00000000000..f4319843a29 --- /dev/null +++ b/Apple/IWork.pro @@ -0,0 +1,46 @@ +QT -= core +QT -= gui + +VERSION = 0.0.0.1 +TARGET = IWorkFile +TEMPLATE = lib + +CONFIG += shared +CONFIG += plugin + +DEFINES += IWORK_USE_DYNAMIC_LIBRARY + +CORE_ROOT_DIR = $$PWD/.. +PWD_ROOT_DIR = $$PWD +include($$CORE_ROOT_DIR/Common/base.pri) + +ADD_DEPENDENCY(kernel, UnicodeConverter) + +INCLUDEPATH += \ + $$PWD + +core_android:DEFINES += NOT_USE_PTHREAD_CANCEL USE_FILE32API + +# BOOST +CONFIG += core_boost_regex +include($$CORE_ROOT_DIR/Common/3dParty/boost/boost.pri) + +# ZLIB +CONFIG += build_all_zlib build_zlib_as_sources +include($$PWD/../OfficeUtils/OfficeUtils.pri) + +# LIBXML +CONFIG += core_static_link_xml_full +CONFIG += core_only_libxml +include($$PWD/../DesktopEditor/xml/build/qt/libxml2.pri) + +# +include($$CORE_ROOT_DIR/Common/3dParty/apple/apple.pri) + +# TEST +HEADERS += $$ODF_LIB_ROOT/test/StringDocumentHandler.h +SOURCES += $$ODF_LIB_ROOT/test/StringDocumentHandler.cxx + +SOURCES += IWork.cpp + +HEADERS += IWork.h diff --git a/Apple/test/examples/DO NOT REMOVE b/Apple/test/examples/DO NOT REMOVE new file mode 100644 index 00000000000..e69de29bb2d diff --git a/Apple/test/main.cpp b/Apple/test/main.cpp new file mode 100644 index 00000000000..27ee48db62f --- /dev/null +++ b/Apple/test/main.cpp @@ -0,0 +1,45 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ + +#include "../IWork.h" +#include "../../DesktopEditor/common/File.h" + +int main(int argc, char *argv[]) +{ + CIWorkFile oFile; + + std::wstring sExamplesDir = NSFile::GetProcessDirectory() + L"/../examples"; + oFile.Convert2Odf(sExamplesDir + L"/new.pages", sExamplesDir + L"/out_new.odt"); + oFile.Convert2Odf(sExamplesDir + L"/old.pages", sExamplesDir + L"/out_old.odt"); + + return 0; +} diff --git a/Apple/test/test.pro b/Apple/test/test.pro new file mode 100644 index 00000000000..eaabb05de86 --- /dev/null +++ b/Apple/test/test.pro @@ -0,0 +1,20 @@ +CONFIG -= qt +QT -= core gui + +TARGET = test +CONFIG += console +CONFIG -= app_bundle +TEMPLATE = app + +CORE_ROOT_DIR = $$PWD/../.. +PWD_ROOT_DIR = $$PWD +include($$CORE_ROOT_DIR/Common/base.pri) + +ADD_DEPENDENCY(UnicodeConverter, kernel, IWorkFile) + +core_linux:include($$PWD/../../Common/3dParty/icu/icu.pri) +core_windows:LIBS += -lgdi32 -ladvapi32 -luser32 -lshell32 + +SOURCES += main.cpp + +DESTDIR = $$PWD/build diff --git a/Common/3dParty/apple/.gitignore b/Common/3dParty/apple/.gitignore new file mode 100644 index 00000000000..e9eaf6ae6ac --- /dev/null +++ b/Common/3dParty/apple/.gitignore @@ -0,0 +1,8 @@ +# Ignore everything in this directory +glm +mdds +librevenge +libodfgen +libetonyek +# Except this file +!.gitignore diff --git a/Common/3dParty/apple/apple.pri b/Common/3dParty/apple/apple.pri new file mode 100644 index 00000000000..75dc6a8941d --- /dev/null +++ b/Common/3dParty/apple/apple.pri @@ -0,0 +1,36 @@ +INCLUDEPATH += $$PWD + +# LIBREVENGE +REVENGE_LIB_ROOT = $$PWD/librevenge + +INCLUDEPATH += \ + $$REVENGE_LIB_ROOT/inc + +HEADERS += $$files($$REVENGE_LIB_ROOT/inc/*.h, true) +HEADERS += $$files($$REVENGE_LIB_ROOT/src/lib/*.h, true) +SOURCES += $$files($$REVENGE_LIB_ROOT/src/lib/*.cpp, true) + +# LIBODFGEN +ODF_LIB_ROOT = $$PWD/libodfgen + +INCLUDEPATH += \ + $$ODF_LIB_ROOT/inc + +HEADERS += $$files($$ODF_LIB_ROOT/inc/libodfgen/*.hxx, true) +HEADERS += $$files($$ODF_LIB_ROOT/src/*.hxx, true) +SOURCES += $$files($$ODF_LIB_ROOT/src/*.cxx, true) + +# LIBETONYEK +ETONYEK_LIB_ROOT = $$PWD/libetonyek + +INCLUDEPATH += \ + $$ETONYEK_LIB_ROOT/inc \ + $$ETONYEK_LIB_ROOT/src/lib \ + $$ETONYEK_LIB_ROOT/src/lib/contexts \ + $$PWD/mdds/include \ + $$PWD/glm + +HEADERS += $$files($$ETONYEK_LIB_ROOT/inc/libetonyek/*.h, true) +HEADERS += $$files($$ETONYEK_LIB_ROOT/src/lib/*.h, true) +SOURCES += $$files($$ETONYEK_LIB_ROOT/src/lib/*.cpp, true) + diff --git a/Common/3dParty/apple/fetch.py b/Common/3dParty/apple/fetch.py new file mode 100644 index 00000000000..dd233861fb7 --- /dev/null +++ b/Common/3dParty/apple/fetch.py @@ -0,0 +1,121 @@ +import sys +sys.path.append('../../../../build_tools/scripts') +import base +import os + +if not base.is_dir("glm"): + base.cmd("git", ["clone", "https://github.com/g-truc/glm.git"]) + base.cmd_in_dir("glm", "git", ["checkout", "33b4a621a697a305bc3a7610d290677b96beb181", "--quiet"]) + +if not base.is_dir("mdds"): + base.cmd("git", ["clone", "https://github.com/kohei-us/mdds.git"]) + base.cmd_in_dir("mdds", "git", ["checkout", "0783158939c6ce4b0b1b89e345ab983ccb0f0ad0"], "--quiet") + + fix_cpp_version = "#if __cplusplus < 201402L\n" + fix_cpp_version += "#ifndef _MSC_VER\n" + fix_cpp_version += "namespace std {\n" + fix_cpp_version += " template\n" + fix_cpp_version += " using bool_constant = integral_constant;\n\n" + fix_cpp_version += " template \n" + fix_cpp_version += " using void_t = void;\n" + fix_cpp_version += "}\n#endif\n" + fix_cpp_version += "#endif\n\n" + fix_cpp_version += "namespace mdds {" + + base.replaceInFile("./mdds/include/mdds/global.hpp", "namespace mdds {", fix_cpp_version) + +if not base.is_dir("librevenge"): + base.cmd("git", ["clone", "https://github.com/Distrotech/librevenge.git"]) + base.cmd_in_dir("librevenge", "git", ["checkout", "becd044b519ab83893ad6398e3cbb499a7f0aaf4", "--quiet"]) + + stat_windows = "" + stat_windows += "#if !defined(S_ISREG) && defined(S_IFMT) && defined(S_IFREG)\n" + stat_windows += "#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)\n" + stat_windows += "#endif\n" + stat_windows += "#if !defined(S_ISDIR) && defined(S_IFMT) && defined(S_IFDIR)\n" + stat_windows += "#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)\n" + stat_windows += "#endif\n" + + base.replaceInFile("./librevenge/src/lib/RVNGDirectoryStream.cpp", "#include ", + "#include \n\n" + stat_windows) + + fix_RVNG_H = "explicit RVNGFileStream(const char *filename);\n" + fix_RVNG_H += " #if defined(_WIN32) || defined(_WIN64)\n" + fix_RVNG_H += " explicit RVNGFileStream(const wchar_t *filename);\n" + fix_RVNG_H += " #endif\n" + + base.replaceInFile("./librevenge/inc/librevenge-stream/RVNGStreamImplementation.h", "explicit RVNGFileStream(const char *filename);", fix_RVNG_H) + + fix_RVNG_CPP_include = "#if defined(_WIN32) || defined(_WIN64)\n" + fix_RVNG_CPP_include += "#include \n\n" + fix_RVNG_CPP_include += "static __inline int wstat(wchar_t const* const _FileName, struct stat* const _Stat)\n" + fix_RVNG_CPP_include += "{\n" + fix_RVNG_CPP_include += " _STATIC_ASSERT(sizeof(struct stat) == sizeof(struct _stat64i32));\n"; + fix_RVNG_CPP_include += " return _wstat64i32(_FileName, (struct _stat64i32*)_Stat);\n"; + fix_RVNG_CPP_include += "}\n" + fix_RVNG_CPP_include += "#endif\n\n" + fix_RVNG_CPP_include += "namespace librevenge" + + base.replaceInFile("./librevenge/src/lib/RVNGStreamImplementation.cpp", "namespace librevenge", fix_RVNG_CPP_include) + + fix_RVNG_CPP = "#if defined(_WIN32) || defined(_WIN64)\n" + fix_RVNG_CPP += "RVNGFileStream::RVNGFileStream(const wchar_t *filename) :\n" + fix_RVNG_CPP += " RVNGInputStream(),\n" + fix_RVNG_CPP += " d(new RVNGFileStreamPrivate())\n" + fix_RVNG_CPP += "{\n" + fix_RVNG_CPP += " d->file = _wfopen(filename, L\"rb\");\n" + fix_RVNG_CPP += " if (!d->file || ferror(d->file))\n" + fix_RVNG_CPP += " {\n" + fix_RVNG_CPP += " delete d;\n" + fix_RVNG_CPP += " d = 0;\n" + fix_RVNG_CPP += " return;\n" + fix_RVNG_CPP += " }\n\n" + fix_RVNG_CPP += " struct stat status;\n" + fix_RVNG_CPP += " const int retval = wstat(filename, &status);\n" + fix_RVNG_CPP += " if ((0 != retval) || !S_ISREG(status.st_mode))\n" + fix_RVNG_CPP += " {\n" + fix_RVNG_CPP += " delete d;\n" + fix_RVNG_CPP += " d = 0;\n" + fix_RVNG_CPP += " return;\n" + fix_RVNG_CPP += " }\n\n" + fix_RVNG_CPP += " fseek(d->file, 0, SEEK_END);\n\n" + fix_RVNG_CPP += " d->streamSize = (unsigned long) ftell(d->file);\n" + fix_RVNG_CPP += " if (d->streamSize == (unsigned long)-1)\n" + fix_RVNG_CPP += " d->streamSize = 0;\n" + fix_RVNG_CPP += " if (d->streamSize > (std::numeric_limits::max)() / 2)\n" + fix_RVNG_CPP += " d->streamSize = (std::numeric_limits::max)() / 2;\n" + fix_RVNG_CPP += " fseek(d->file, 0, SEEK_SET);\n" + fix_RVNG_CPP += "}\n" + fix_RVNG_CPP += "#endif\n\n" + fix_RVNG_CPP += "RVNGFileStream::~RVNGFileStream()" + + base.replaceInFile("./librevenge/src/lib/RVNGStreamImplementation.cpp", "RVNGFileStream::~RVNGFileStream()", fix_RVNG_CPP) + +if not base.is_dir("libodfgen"): + base.cmd("git", ["clone", "https://github.com/Distrotech/libodfgen.git"]) + base.cmd_in_dir("libodfgen", "git", ["checkout", "8ef8c171ebe3c5daebdce80ee422cf7bb96aa3bc", "--quiet"]) + +if not base.is_dir("libetonyek"): + base.cmd("git", ["clone", "https://github.com/LibreOffice/libetonyek.git"]) + base.cmd_in_dir("libetonyek", "git", ["checkout", "cb396b4a9453a457469b62a740d8fb933c9442c3", "--quiet"]) + + base.replaceInFile("./libetonyek/src/lib/IWORKTable.cpp", "is_tree_valid", "valid_tree") + +cmd_args = sys.argv[1:] +use_gperf = False + +for arg in cmd_args: + if '--gperf' == arg: + use_gperf = True + +if use_gperf: + base_gperf_args = ["--compare-strncmp", "--enum", "--null-strings", "--readonly-tables", "--language", "C++"] + base_gperf_files = ["IWORKToken.gperf", "KEY1Token.gperf", "KEY2Token.gperf", "NUM1Token.gperf", "PAG1Token.gperf"] + + for file in base_gperf_files: + base.cmd_in_dir("./libetonyek/src/lib", "gperf", base_gperf_args + [file, "--output-file", file[0:file.find(".")] + ".inc"]) +else: + base.copy_dir_content("./headers", "./libetonyek/src/lib") + + + diff --git a/Common/3dParty/apple/headers/IWORKToken.inc b/Common/3dParty/apple/headers/IWORKToken.inc new file mode 100644 index 00000000000..56c1cbc1510 --- /dev/null +++ b/Common/3dParty/apple/headers/IWORKToken.inc @@ -0,0 +1,2563 @@ +/* C++ code produced by gperf version 3.0.1 */ +/* Command-line: gperf --compare-strncmp --enum --null-strings --readonly-tables --language C++ --output-file IWORKToken.inc IWORKToken.gperf */ +/* Computed positions: -k'1-2,4-8,11,13,22,24,$' */ + +#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ + && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \ + && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \ + && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \ + && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \ + && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \ + && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \ + && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \ + && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \ + && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \ + && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \ + && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \ + && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \ + && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \ + && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \ + && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \ + && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \ + && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \ + && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \ + && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \ + && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \ + && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \ + && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126)) +/* The character set is not based on ISO-646. */ +#error "gperf generated tables don't work with this execution character set. Please report a bug to ." +#endif + +#line 10 "IWORKToken.gperf" + +#if defined(__GNUC__) +#pragma GCC diagnostic ignored "-Wmissing-field-initializers" +#endif + +using namespace IWORKToken; +#line 18 "IWORKToken.gperf" +struct Token +{ + const char *name; + int id; +}; +#include +/* maximum key range = 4146, duplicates = 0 */ + +class Perfect_Hash +{ +private: + static inline unsigned int hash (const char *str, unsigned int len); +public: + static const struct Token *in_word_set (const char *str, unsigned int len); +}; + +inline unsigned int +Perfect_Hash::hash (register const char *str, register unsigned int len) +{ + static const unsigned short asso_values[] = + { + 4147, 4147, 4147, 4147, 4147, 4147, 4147, 4147, 4147, 4147, + 4147, 4147, 4147, 4147, 4147, 4147, 4147, 4147, 4147, 4147, + 4147, 4147, 4147, 4147, 4147, 4147, 4147, 4147, 4147, 4147, + 4147, 4147, 4147, 4147, 4147, 4147, 4147, 4147, 4147, 4147, + 4147, 4147, 4147, 4147, 4147, 5, 25, 5, 55, 115, + 125, 10, 15, 25, 40, 20, 5, 30, 5, 4147, + 4147, 4147, 4147, 4147, 4147, 40, 5, 15, 0, 5, + 0, 30, 55, 180, 4147, 4147, 40, 15, 0, 0, + 5, 0, 5, 5, 0, 35, 25, 0, 30, 85, + 4147, 4147, 4147, 4147, 4147, 0, 4147, 75, 595, 45, + 495, 0, 0, 475, 410, 5, 605, 50, 235, 30, + 40, 35, 650, 10, 130, 15, 5, 100, 780, 90, + 180, 920, 10, 4147, 4147, 4147, 4147, 4147, 4147, 4147, + 4147, 4147, 4147, 4147, 4147, 4147, 4147, 4147, 4147, 4147, + 4147, 4147, 4147, 4147, 4147, 4147, 4147, 4147, 4147, 4147, + 4147, 4147, 4147, 4147, 4147, 4147, 4147, 4147, 4147, 4147, + 4147, 4147, 4147, 4147, 4147, 4147, 4147, 4147, 4147, 4147, + 4147, 4147, 4147, 4147, 4147, 4147, 4147, 4147, 4147, 4147, + 4147, 4147, 4147, 4147, 4147, 4147, 4147, 4147, 4147, 4147, + 4147, 4147, 4147, 4147, 4147, 4147, 4147, 4147, 4147, 4147, + 4147, 4147, 4147, 4147, 4147, 4147, 4147, 4147, 4147, 4147, + 4147, 4147, 4147, 4147, 4147, 4147, 4147, 4147, 4147, 4147, + 4147, 4147, 4147, 4147, 4147, 4147, 4147, 4147, 4147, 4147, + 4147, 4147, 4147, 4147, 4147, 4147, 4147, 4147, 4147, 4147, + 4147, 4147, 4147, 4147, 4147, 4147, 4147, 4147, 4147, 4147, + 4147, 4147, 4147, 4147, 4147, 4147, 4147 + }; + register int hval = len; + + switch (hval) + { + default: + hval += asso_values[(unsigned char)str[23]]; + /*FALLTHROUGH*/ + case 23: + case 22: + hval += asso_values[(unsigned char)str[21]]; + /*FALLTHROUGH*/ + case 21: + case 20: + case 19: + case 18: + case 17: + case 16: + case 15: + case 14: + case 13: + hval += asso_values[(unsigned char)str[12]]; + /*FALLTHROUGH*/ + case 12: + case 11: + hval += asso_values[(unsigned char)str[10]]; + /*FALLTHROUGH*/ + case 10: + case 9: + case 8: + hval += asso_values[(unsigned char)str[7]]; + /*FALLTHROUGH*/ + case 7: + hval += asso_values[(unsigned char)str[6]]; + /*FALLTHROUGH*/ + case 6: + hval += asso_values[(unsigned char)str[5]]; + /*FALLTHROUGH*/ + case 5: + hval += asso_values[(unsigned char)str[4]]; + /*FALLTHROUGH*/ + case 4: + hval += asso_values[(unsigned char)str[3]+1]; + /*FALLTHROUGH*/ + case 3: + case 2: + hval += asso_values[(unsigned char)str[1]]; + /*FALLTHROUGH*/ + case 1: + hval += asso_values[(unsigned char)str[0]]; + break; + } + return hval + asso_values[(unsigned char)str[len - 1]]; +} + +const struct Token * +Perfect_Hash::in_word_set (register const char *str, register unsigned int len) +{ + enum + { + TOTAL_KEYWORDS = 655, + MIN_WORD_LENGTH = 1, + MAX_WORD_LENGTH = 44, + MIN_HASH_VALUE = 1, + MAX_HASH_VALUE = 4146 + }; + + static const struct Token wordlist[] = + { + {(char*)0}, +#line 229 "IWORKToken.gperf" + {"f",f}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, +#line 566 "IWORKToken.gperf" + {"t",t}, + {(char*)0}, +#line 247 "IWORKToken.gperf" + {"fit",fit}, +#line 635 "IWORKToken.gperf" + {"tile",tile}, + {(char*)0}, {(char*)0}, +#line 528 "IWORKToken.gperf" + {"sf",sf}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, +#line 534 "IWORKToken.gperf" + {"size",size}, +#line 244 "IWORKToken.gperf" + {"first",first}, + {(char*)0}, +#line 548 "IWORKToken.gperf" + {"st",st}, + {(char*)0}, {(char*)0}, +#line 634 "IWORKToken.gperf" + {"tight",tight}, +#line 517 "IWORKToken.gperf" + {"s",s}, +#line 290 "IWORKToken.gperf" + {"fs",fs}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 449 "IWORKToken.gperf" + {"of",of}, +#line 254 "IWORKToken.gperf" + {"fmt",fmt}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, +#line 636 "IWORKToken.gperf" + {"title",title}, + {(char*)0}, +#line 154 "IWORKToken.gperf" + {"cf",cf}, + {(char*)0}, {(char*)0}, +#line 550 "IWORKToken.gperf" + {"start",start}, +#line 425 "IWORKToken.gperf" + {"mf-ref",mf_ref}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 560 "IWORKToken.gperf" + {"style",style}, +#line 450 "IWORKToken.gperf" + {"offset",offset}, +#line 196 "IWORKToken.gperf" + {"ct",ct}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 409 "IWORKToken.gperf" + {"m",m}, +#line 253 "IWORKToken.gperf" + {"fm",fm}, + {(char*)0}, {(char*)0}, +#line 554 "IWORKToken.gperf" + {"stops",stops}, +#line 155 "IWORKToken.gperf" + {"cf-ref",cf_ref}, + {(char*)0}, {(char*)0}, +#line 423 "IWORKToken.gperf" + {"mode",mode}, + {(char*)0}, +#line 447 "IWORKToken.gperf" + {"o",o}, +#line 255 "IWORKToken.gperf" + {"fo",fo}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, +#line 436 "IWORKToken.gperf" + {"none",none}, + {(char*)0}, +#line 428 "IWORKToken.gperf" + {"n",n}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 231 "IWORKToken.gperf" + {"false",false_}, +#line 562 "IWORKToken.gperf" + {"styles",styles}, +#line 540 "IWORKToken.gperf" + {"so",so}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 133 "IWORKToken.gperf" + {"c",c}, + {(char*)0}, +#line 529 "IWORKToken.gperf" + {"sfa",sfa}, + {(char*)0}, +#line 520 "IWORKToken.gperf" + {"scale",scale}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, +#line 355 "IWORKToken.gperf" + {"k",k}, + {(char*)0}, +#line 435 "IWORKToken.gperf" + {"nsc",nsc}, +#line 604 "IWORKToken.gperf" + {"tabs",tabs}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, +#line 24 "IWORKToken.gperf" + {"0",_0}, + {(char*)0}, +#line 98 "IWORKToken.gperf" + {"amt",amt}, +#line 623 "IWORKToken.gperf" + {"text",text}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 429 "IWORKToken.gperf" + {"name",name}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, +#line 191 "IWORKToken.gperf" + {"count",count}, + {(char*)0}, +#line 432 "IWORKToken.gperf" + {"nc",nc}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, +#line 620 "IWORKToken.gperf" + {"tailSize",tailSize}, +#line 647 "IWORKToken.gperf" + {"true",true_}, + {(char*)0}, +#line 353 "IWORKToken.gperf" + {"italic",italic}, +#line 516 "IWORKToken.gperf" + {"rt",rt}, + {(char*)0}, +#line 341 "IWORKToken.gperf" + {"increment",increment}, + {(char*)0}, +#line 573 "IWORKToken.gperf" + {"table-style",table_style}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 99 "IWORKToken.gperf" + {"angle",angle}, +#line 87 "IWORKToken.gperf" + {"a",a}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 508 "IWORKToken.gperf" + {"right",right}, + {(char*)0}, {(char*)0}, +#line 232 "IWORKToken.gperf" + {"filename",filename}, +#line 542 "IWORKToken.gperf" + {"sort",sort}, +#line 245 "IWORKToken.gperf" + {"firstLineIndent",firstLineIndent}, + {(char*)0}, {(char*)0}, +#line 260 "IWORKToken.gperf" + {"fontSize",fontSize}, + {(char*)0}, {(char*)0}, +#line 267 "IWORKToken.gperf" + {"format",format}, + {(char*)0}, {(char*)0}, +#line 549 "IWORKToken.gperf" + {"star",star}, + {(char*)0}, {(char*)0}, +#line 530 "IWORKToken.gperf" + {"sfclass",sfclass}, + {(char*)0}, +#line 622 "IWORKToken.gperf" + {"technique",technique}, +#line 285 "IWORKToken.gperf" + {"frame",frame}, +#line 278 "IWORKToken.gperf" + {"format-type",format_type}, +#line 176 "IWORKToken.gperf" + {"comment",comment}, +#line 234 "IWORKToken.gperf" + {"fill-ref",fill_ref}, +#line 569 "IWORKToken.gperf" + {"table-cell-ref",table_cell_ref}, +#line 343 "IWORKToken.gperf" + {"inflection",inflection}, +#line 669 "IWORKToken.gperf" + {"w",w}, +#line 31 "IWORKToken.gperf" + {"ID",ID}, + {(char*)0}, {(char*)0}, +#line 32 "IWORKToken.gperf" + {"IDREF",IDREF}, +#line 570 "IWORKToken.gperf" + {"table-cell-style",table_cell_style}, + {(char*)0}, {(char*)0}, +#line 515 "IWORKToken.gperf" + {"rows",rows}, +#line 571 "IWORKToken.gperf" + {"table-cell-style-ref",table_cell_style_ref}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 177 "IWORKToken.gperf" + {"connection-line",connection_line}, +#line 179 "IWORKToken.gperf" + {"connection-style",connection_style}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 180 "IWORKToken.gperf" + {"connection-style-ref",connection_style_ref}, + {(char*)0}, {(char*)0}, +#line 677 "IWORKToken.gperf" + {"xsi",xsi}, + {(char*)0}, +#line 572 "IWORKToken.gperf" + {"table-info",table_info}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 340 "IWORKToken.gperf" + {"implicit-format-type",implicit_format_type}, +#line 274 "IWORKToken.gperf" + {"format-name",format_name}, +#line 510 "IWORKToken.gperf" + {"rn",rn}, + {(char*)0}, {(char*)0}, +#line 521 "IWORKToken.gperf" + {"scale-with-text",scale_with_text}, + {(char*)0}, +#line 454 "IWORKToken.gperf" + {"outline",outline}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, +#line 263 "IWORKToken.gperf" + {"footnote",footnote}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 605 "IWORKToken.gperf" + {"tabs-ref",tabs_ref}, + {(char*)0}, {(char*)0}, +#line 25 "IWORKToken.gperf" + {"1",_1}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 225 "IWORKToken.gperf" + {"extent",extent}, +#line 183 "IWORKToken.gperf" + {"content",content}, + {(char*)0}, +#line 266 "IWORKToken.gperf" + {"footnotes",footnotes}, + {(char*)0}, {(char*)0}, +#line 522 "IWORKToken.gperf" + {"section",section}, + {(char*)0}, +#line 385 "IWORKToken.gperf" + {"line",line}, + {(char*)0}, +#line 646 "IWORKToken.gperf" + {"transition-attributes",transition_attributes}, + {(char*)0}, +#line 259 "IWORKToken.gperf" + {"fontName",fontName}, + {(char*)0}, +#line 645 "IWORKToken.gperf" + {"transition",transition}, + {(char*)0}, +#line 184 "IWORKToken.gperf" + {"content-size",content_size}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, +#line 512 "IWORKToken.gperf" + {"row",row}, + {(char*)0}, {(char*)0}, +#line 496 "IWORKToken.gperf" + {"r",r}, + {(char*)0}, {(char*)0}, +#line 242 "IWORKToken.gperf" + {"filterset",filterset}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 241 "IWORKToken.gperf" + {"filters",filters}, + {(char*)0}, +#line 233 "IWORKToken.gperf" + {"fill",fill}, +#line 29 "IWORKToken.gperf" + {"1347307366",_1347307366}, + {(char*)0}, {(char*)0}, +#line 618 "IWORKToken.gperf" + {"tailPositionX",tailPositionX}, +#line 152 "IWORKToken.gperf" + {"cell-text",cell_text}, +#line 574 "IWORKToken.gperf" + {"table-style-ref",table_style_ref}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, +#line 537 "IWORKToken.gperf" + {"slide-style",slide_style}, +#line 187 "IWORKToken.gperf" + {"core-image-filter-descriptor-ref",core_image_filter_descriptor_ref}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, +#line 188 "IWORKToken.gperf" + {"core-image-filter-info",core_image_filter_info}, + {(char*)0}, {(char*)0}, +#line 422 "IWORKToken.gperf" + {"miter",miter}, +#line 275 "IWORKToken.gperf" + {"format-negative-style",format_negative_style}, +#line 262 "IWORKToken.gperf" + {"footers",footers}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 146 "IWORKToken.gperf" + {"cell-coordinates",cell_coordinates}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 438 "IWORKToken.gperf" + {"num-footer-rows",num_footer_rows}, + {(char*)0}, +#line 616 "IWORKToken.gperf" + {"tailAtCenter",tailAtCenter}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 446 "IWORKToken.gperf" + {"numrows", numrows}, +#line 169 "IWORKToken.gperf" + {"col",col}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, +#line 192 "IWORKToken.gperf" + {"crbr",crbr}, + {(char*)0}, {(char*)0}, +#line 356 "IWORKToken.gperf" + {"keepLinesTogether",keepLinesTogether}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 218 "IWORKToken.gperf" + {"element",element}, + {(char*)0}, +#line 561 "IWORKToken.gperf" + {"style-run",style_run}, +#line 603 "IWORKToken.gperf" + {"tableVectorStyle-ref",tableVectorStyle_ref}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, +#line 144 "IWORKToken.gperf" + {"cell-comment-drawable-info",cell_comment_drawable_info}, + {(char*)0}, {(char*)0}, +#line 382 "IWORKToken.gperf" + {"left",left}, + {(char*)0}, +#line 194 "IWORKToken.gperf" + {"custom",custom}, +#line 279 "IWORKToken.gperf" + {"format-use-accounting-style",format_use_accounting_style}, + {(char*)0}, +#line 615 "IWORKToken.gperf" + {"tail",tail}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, +#line 265 "IWORKToken.gperf" + {"footnotebr",footnotebr}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, +#line 675 "IWORKToken.gperf" + {"x",x}, +#line 287 "IWORKToken.gperf" + {"frame-w",frame_w}, + {(char*)0}, {(char*)0}, +#line 256 "IWORKToken.gperf" + {"followingLayoutStyle",followingLayoutStyle}, +#line 601 "IWORKToken.gperf" + {"tableVectorBegin",tableVectorBegin}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, +#line 444 "IWORKToken.gperf" + {"number-format-ref",number_format_ref}, +#line 443 "IWORKToken.gperf" + {"number-format",number_format}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, +#line 26 "IWORKToken.gperf" + {"1246774599",_1246774599}, + {(char*)0}, +#line 115 "IWORKToken.gperf" + {"authors",authors}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, +#line 619 "IWORKToken.gperf" + {"tailPositionY",tailPositionY}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, +#line 415 "IWORKToken.gperf" + {"mark",mark}, +#line 271 "IWORKToken.gperf" + {"format-currency-code",format_currency_code}, +#line 189 "IWORKToken.gperf" + {"core-image-filter-info-ref",core_image_filter_info_ref}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 261 "IWORKToken.gperf" + {"footer",footer}, + {(char*)0}, +#line 264 "IWORKToken.gperf" + {"footnote-mark",footnote_mark}, + {(char*)0}, +#line 568 "IWORKToken.gperf" + {"table-cell",table_cell}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 437 "IWORKToken.gperf" + {"null",null}, +#line 342 "IWORKToken.gperf" + {"index",index}, +#line 153 "IWORKToken.gperf" + {"center",center}, + {(char*)0}, +#line 186 "IWORKToken.gperf" + {"core-image-filter-descriptor",core_image_filter_descriptor}, + {(char*)0}, {(char*)0}, +#line 582 "IWORKToken.gperf" + {"tableCellMinXSide-ref",tableCellMinXSide_ref}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 580 "IWORKToken.gperf" + {"tableCellContent",tableCellContent}, +#line 330 "IWORKToken.gperf" + {"ht",ht}, + {(char*)0}, +#line 404 "IWORKToken.gperf" + {"lnbr",lnbr}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, +#line 28 "IWORKToken.gperf" + {"1346651680",_1346651680}, +#line 518 "IWORKToken.gperf" + {"scalar",scalar}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 276 "IWORKToken.gperf" + {"format-show-thousands-separator",format_show_thousands_separator}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 531 "IWORKToken.gperf" + {"shape",shape}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, +#line 337 "IWORKToken.gperf" + {"image",image}, +#line 441 "IWORKToken.gperf" + {"number",number}, +#line 190 "IWORKToken.gperf" + {"cornerRadius",cornerRadius}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 565 "IWORKToken.gperf" + {"superscript",superscript}, +#line 523 "IWORKToken.gperf" + {"sectionstyle",sectionstyle}, +#line 91 "IWORKToken.gperf" + {"animationAuto",animationAuto}, + {(char*)0}, {(char*)0}, +#line 551 "IWORKToken.gperf" + {"start-index",start_index}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 524 "IWORKToken.gperf" + {"sectionstyle-ref",sectionstyle_ref}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 584 "IWORKToken.gperf" + {"tableCellMinYSide-ref",tableCellMinYSide_ref}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 374 "IWORKToken.gperf" + {"layers",layers}, +#line 502 "IWORKToken.gperf" + {"restart-list",restart_list}, + {(char*)0}, {(char*)0}, +#line 30 "IWORKToken.gperf" + {"1414088262",_1414088262}, + {(char*)0}, +#line 329 "IWORKToken.gperf" + {"ho",ho}, +#line 538 "IWORKToken.gperf" + {"slider-orientation",slider_orientation}, + {(char*)0}, +#line 27 "IWORKToken.gperf" + {"1299148630",_1299148630}, +#line 583 "IWORKToken.gperf" + {"tableCellMaxXSide-ref",tableCellMaxXSide_ref}, +#line 536 "IWORKToken.gperf" + {"sl",sl}, + {(char*)0}, {(char*)0}, +#line 563 "IWORKToken.gperf" + {"stylesheet",stylesheet}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 564 "IWORKToken.gperf" + {"stylesheet-ref",stylesheet_ref}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 328 "IWORKToken.gperf" + {"hc",hc}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 621 "IWORKToken.gperf" + {"target",target}, +#line 94 "IWORKToken.gperf" + {"animationDuration",animationDuration}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 165 "IWORKToken.gperf" + {"chart-style",chart_style}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 581 "IWORKToken.gperf" + {"tableCellFormula",tableCellFormula}, + {(char*)0}, +#line 163 "IWORKToken.gperf" + {"chart-series-style",chart_series_style}, + {(char*)0}, +#line 600 "IWORKToken.gperf" + {"tableVectorAxis",tableVectorAxis}, + {(char*)0}, +#line 164 "IWORKToken.gperf" + {"chart-series-style-ref",chart_series_style_ref}, + {(char*)0}, +#line 599 "IWORKToken.gperf" + {"tableVectorArrayColumnVectors",tableVectorArrayColumnVectors}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 195 "IWORKToken.gperf" + {"custom-space-color",custom_space_color}, +#line 391 "IWORKToken.gperf" + {"link",link}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 220 "IWORKToken.gperf" + {"end",end}, + {(char*)0}, {(char*)0}, +#line 585 "IWORKToken.gperf" + {"tableCellMaxYSide-ref",tableCellMaxYSide_ref}, +#line 288 "IWORKToken.gperf" + {"frame-x",frame_x}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, +#line 588 "IWORKToken.gperf" + {"tableCellValue",tableCellValue}, +#line 335 "IWORKToken.gperf" + {"ident",ident}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 360 "IWORKToken.gperf" + {"kind",kind}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 651 "IWORKToken.gperf" + {"underline",underline}, + {(char*)0}, +#line 598 "IWORKToken.gperf" + {"tableVectorArrayRowVectors",tableVectorArrayRowVectors}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, +#line 280 "IWORKToken.gperf" + {"formula",formula}, + {(char*)0}, {(char*)0}, +#line 159 "IWORKToken.gperf" + {"chart-info",chart_info}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 372 "IWORKToken.gperf" + {"layer",layer}, + {(char*)0}, +#line 317 "IWORKToken.gperf" + {"headers",headers}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 387 "IWORKToken.gperf" + {"linear",linear}, + {(char*)0}, {(char*)0}, +#line 373 "IWORKToken.gperf" + {"layer-ref",layer_ref}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 339 "IWORKToken.gperf" + {"image-ref",image_ref}, +#line 236 "IWORKToken.gperf" + {"filterClassName",filterClassName}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 258 "IWORKToken.gperf" + {"fontColor",fontColor}, + {(char*)0}, +#line 631 "IWORKToken.gperf" + {"texture-fill-ref",texture_fill_ref}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 161 "IWORKToken.gperf" + {"chart-name",chart_name}, +#line 414 "IWORKToken.gperf" + {"margin",margin}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 587 "IWORKToken.gperf" + {"tableCellStyle-ref",tableCellStyle_ref}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 148 "IWORKToken.gperf" + {"cell-storage",cell_storage}, +#line 158 "IWORKToken.gperf" + {"chart-column_names",chart_column_names}, +#line 204 "IWORKToken.gperf" + {"date-time",date_time}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 433 "IWORKToken.gperf" + {"ncoc",ncoc}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 625 "IWORKToken.gperf" + {"text-cell",text_cell}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 208 "IWORKToken.gperf" + {"direction",direction}, +#line 526 "IWORKToken.gperf" + {"self-contained-movie",self_contained_movie}, +#line 338 "IWORKToken.gperf" + {"image-media",image_media}, + {(char*)0}, +#line 257 "IWORKToken.gperf" + {"followingParagraphStyle",followingParagraphStyle}, + {(char*)0}, +#line 166 "IWORKToken.gperf" + {"chart-style-ref",chart_style_ref}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, +#line 628 "IWORKToken.gperf" + {"text-storage",text_storage}, +#line 36 "IWORKToken.gperf" + {"Series_3",Series_3}, +#line 589 "IWORKToken.gperf" + {"tableInfoTable",tableInfoTable}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, +#line 408 "IWORKToken.gperf" + {"lower-roman",lower_roman}, + {(char*)0}, +#line 37 "IWORKToken.gperf" + {"Series_4",Series_4}, +#line 147 "IWORKToken.gperf" + {"cell-date",cell_date}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 40 "IWORKToken.gperf" + {"Series_7",Series_7}, + {(char*)0}, +#line 178 "IWORKToken.gperf" + {"connection-path",connection_path}, +#line 316 "IWORKToken.gperf" + {"header",header}, +#line 357 "IWORKToken.gperf" + {"keepWithNext",keepWithNext}, +#line 567 "IWORKToken.gperf" + {"tab",tab}, + {(char*)0}, +#line 250 "IWORKToken.gperf" + {"flags",flags}, + {(char*)0}, {(char*)0}, +#line 38 "IWORKToken.gperf" + {"Series_5",Series_5}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 228 "IWORKToken.gperf" + {"external-text-wrap-ref",external_text_wrap_ref}, + {(char*)0}, {(char*)0}, +#line 336 "IWORKToken.gperf" + {"identifier",identifier}, + {(char*)0}, {(char*)0}, +#line 641 "IWORKToken.gperf" + {"top",top}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 214 "IWORKToken.gperf" + {"du",du}, +#line 118 "IWORKToken.gperf" + {"baseSize",baseSize}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 487 "IWORKToken.gperf" + {"pos",pos}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 484 "IWORKToken.gperf" + {"pm",pm}, +#line 39 "IWORKToken.gperf" + {"Series_6",Series_6}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, +#line 354 "IWORKToken.gperf" + {"join",join}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, +#line 558 "IWORKToken.gperf" + {"stroke",stroke}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 145 "IWORKToken.gperf" + {"cell-comment-mapping",cell_comment_mapping}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 485 "IWORKToken.gperf" + {"point",point}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, +#line 131 "IWORKToken.gperf" + {"bullet",bullet}, + {(char*)0}, +#line 33 "IWORKToken.gperf" + {"Series_0",Series_0}, +#line 546 "IWORKToken.gperf" + {"span",span}, +#line 162 "IWORKToken.gperf" + {"chart-row_names",chart_row_names}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, +#line 333 "IWORKToken.gperf" + {"http://www.w3.org/2001/XMLSchema-instance",NS_URI_XSI}, +#line 371 "IWORKToken.gperf" + {"largest",largest}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 596 "IWORKToken.gperf" + {"tableModelVectors",tableModelVectors}, +#line 284 "IWORKToken.gperf" + {"fraction",fraction}, + {(char*)0}, {(char*)0}, +#line 201 "IWORKToken.gperf" + {"date-format",date_format}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 553 "IWORKToken.gperf" + {"stop-index",stop_index}, +#line 268 "IWORKToken.gperf" + {"format-base",format_base}, + {(char*)0}, {(char*)0}, +#line 181 "IWORKToken.gperf" + {"container-hint",container_hint}, + {(char*)0}, +#line 272 "IWORKToken.gperf" + {"format-decimal-places",format_decimal_places}, + {(char*)0}, +#line 139 "IWORKToken.gperf" + {"cap",cap}, +#line 579 "IWORKToken.gperf" + {"tableCellArrayCellsByRow",tableCellArrayCellsByRow}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 453 "IWORKToken.gperf" + {"other-datas",other_datas}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 418 "IWORKToken.gperf" + {"media",media}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 246 "IWORKToken.gperf" + {"firstPageMaster",firstPageMaster}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, +#line 109 "IWORKToken.gperf" + {"aspectRatioLocked",aspectRatioLocked}, + {(char*)0}, +#line 132 "IWORKToken.gperf" + {"butt",butt}, +#line 88 "IWORKToken.gperf" + {"align",align}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 221 "IWORKToken.gperf" + {"end-point",end_point}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, +#line 211 "IWORKToken.gperf" + {"double",double_}, +#line 434 "IWORKToken.gperf" + {"neither",neither}, +#line 101 "IWORKToken.gperf" + {"angle-gradient-ref",angle_gradient_ref}, +#line 100 "IWORKToken.gperf" + {"angle-gradient",angle_gradient}, + {(char*)0}, +#line 314 "IWORKToken.gperf" + {"h",h}, +#line 630 "IWORKToken.gperf" + {"texture-fill",texture_fill}, + {(char*)0}, +#line 282 "IWORKToken.gperf" + {"formula-chart-model",formula_chart_model}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, +#line 126 "IWORKToken.gperf" + {"bottom",bottom}, + {(char*)0}, {(char*)0}, +#line 53 "IWORKToken.gperf" + {"SFTCellStylePropertyDateTimeFormat",SFTCellStylePropertyDateTimeFormat}, + {(char*)0}, {(char*)0}, +#line 474 "IWORKToken.gperf" + {"parent-ident",parent_ident}, +#line 160 "IWORKToken.gperf" + {"chart-model-object",chart_model_object}, + {(char*)0}, +#line 461 "IWORKToken.gperf" + {"page-start",page_start}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 90 "IWORKToken.gperf" + {"alignment",alignment}, + {(char*)0}, +#line 442 "IWORKToken.gperf" + {"number-cell",number_cell}, + {(char*)0}, {(char*)0}, +#line 156 "IWORKToken.gperf" + {"characterstyle",characterstyle}, + {(char*)0}, {(char*)0}, +#line 668 "IWORKToken.gperf" + {"vo",vo}, +#line 157 "IWORKToken.gperf" + {"characterstyle-ref",characterstyle_ref}, + {(char*)0}, {(char*)0}, +#line 648 "IWORKToken.gperf" + {"tscale",tscale}, +#line 128 "IWORKToken.gperf" + {"br",br}, + {(char*)0}, +#line 602 "IWORKToken.gperf" + {"tableVectorEnd",tableVectorEnd}, + {(char*)0}, +#line 56 "IWORKToken.gperf" + {"SFTCellStylePropertyLayoutStyle",SFTCellStylePropertyLayoutStyle}, + {(char*)0}, +#line 34 "IWORKToken.gperf" + {"Series_1",Series_1}, +#line 629 "IWORKToken.gperf" + {"textBackground",textBackground}, +#line 559 "IWORKToken.gperf" + {"stroke-ref",stroke_ref}, +#line 424 "IWORKToken.gperf" + {"movie-media",movie_media}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 462 "IWORKToken.gperf" + {"pair",pair}, + {(char*)0}, +#line 407 "IWORKToken.gperf" + {"lower-alpha",lower_alpha}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 509 "IWORKToken.gperf" + {"rightIndent",rightIndent}, +#line 578 "IWORKToken.gperf" + {"tableCellArrayCellsByColumn",tableCellArrayCellsByColumn}, +#line 35 "IWORKToken.gperf" + {"Series_2",Series_2}, +#line 673 "IWORKToken.gperf" + {"wrap",wrap}, +#line 105 "IWORKToken.gperf" + {"annotation-field-ref",annotation_field_ref}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 202 "IWORKToken.gperf" + {"date-format-ref",date_format_ref}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 351 "IWORKToken.gperf" + {"insertion-point",insertion_point}, +#line 106 "IWORKToken.gperf" + {"annotations",annotations}, +#line 555 "IWORKToken.gperf" + {"stretch",stretch}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, +#line 347 "IWORKToken.gperf" + {"inputDistance",inputDistance}, +#line 57 "IWORKToken.gperf" + {"SFTCellStylePropertyParagraphStyle",SFTCellStylePropertyParagraphStyle}, +#line 103 "IWORKToken.gperf" + {"annotation",annotation}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 315 "IWORKToken.gperf" + {"head",head}, + {(char*)0}, {(char*)0}, +#line 663 "IWORKToken.gperf" + {"version",version}, + {(char*)0}, {(char*)0}, +#line 475 "IWORKToken.gperf" + {"parent-ref",parent_ref}, + {(char*)0}, {(char*)0}, +#line 492 "IWORKToken.gperf" + {"projects",projects}, + {(char*)0}, +#line 294 "IWORKToken.gperf" + {"ghost-text",ghost_text}, + {(char*)0}, {(char*)0}, +#line 644 "IWORKToken.gperf" + {"transform-gradient",transform_gradient}, +#line 295 "IWORKToken.gperf" + {"ghost-text-ref",ghost_text_ref}, +#line 458 "IWORKToken.gperf" + {"page-count",page_count}, + {(char*)0}, {(char*)0}, +#line 359 "IWORKToken.gperf" + {"keywords",keywords}, +#line 649 "IWORKToken.gperf" + {"type",type}, + {(char*)0}, +#line 270 "IWORKToken.gperf" + {"format-base-use-minus-sign",format_base_use_minus_sign}, + {(char*)0}, +#line 170 "IWORKToken.gperf" + {"col-span",col_span}, +#line 54 "IWORKToken.gperf" + {"SFTCellStylePropertyDurationFormat",SFTCellStylePropertyDurationFormat}, +#line 590 "IWORKToken.gperf" + {"tableModelCells",tableModelCells}, +#line 168 "IWORKToken.gperf" + {"chisel",chisel}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, +#line 445 "IWORKToken.gperf" + {"numcols", numcols}, + {(char*)0}, +#line 318 "IWORKToken.gperf" + {"headline-style",headline_style}, + {(char*)0}, +#line 113 "IWORKToken.gperf" + {"audio-only-image",audio_only_image}, + {(char*)0}, +#line 452 "IWORKToken.gperf" + {"original-size",original_size}, + {(char*)0}, +#line 114 "IWORKToken.gperf" + {"audio-only-image-ref",audio_only_image_ref}, +#line 291 "IWORKToken.gperf" + {"g",g}, + {(char*)0}, +#line 576 "IWORKToken.gperf" + {"table-vector-style",table_vector_style}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 577 "IWORKToken.gperf" + {"table-vector-style-ref",table_vector_style_ref}, + {(char*)0}, {(char*)0}, +#line 593 "IWORKToken.gperf" + {"tableModelPartitionSource",tableModelPartitionSource}, +#line 175 "IWORKToken.gperf" + {"columns-ref",columns_ref}, + {(char*)0}, +#line 302 "IWORKToken.gperf" + {"grid-row",grid_row}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 174 "IWORKToken.gperf" + {"columns",columns}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 281 "IWORKToken.gperf" + {"formula-cell",formula_cell}, +#line 358 "IWORKToken.gperf" + {"key",key}, + {(char*)0}, {(char*)0}, +#line 172 "IWORKToken.gperf" + {"column",column}, + {(char*)0}, +#line 117 "IWORKToken.gperf" + {"baselineShift",baselineShift}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, +#line 466 "IWORKToken.gperf" + {"pageBreakBefore",pageBreakBefore}, +#line 637 "IWORKToken.gperf" + {"title-placeholder-ref",title_placeholder_ref}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 467 "IWORKToken.gperf" + {"pagemaster",pagemaster}, +#line 197 "IWORKToken.gperf" + {"d",d}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 171 "IWORKToken.gperf" + {"color",color}, + {(char*)0}, +#line 334 "IWORKToken.gperf" + {"id",id}, +#line 222 "IWORKToken.gperf" + {"equal-columns",equal_columns}, +#line 586 "IWORKToken.gperf" + {"tableCellPreferredHeight",tableCellPreferredHeight}, +#line 410 "IWORKToken.gperf" + {"main-movie",main_movie}, +#line 592 "IWORKToken.gperf" + {"tableModelIsHeaderRow",tableModelIsHeaderRow}, +#line 286 "IWORKToken.gperf" + {"frame-h",frame_h}, + {(char*)0}, {(char*)0}, +#line 95 "IWORKToken.gperf" + {"alpha-mask-path",alpha_mask_path}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 411 "IWORKToken.gperf" + {"main-movie-ref",main_movie_ref}, + {(char*)0}, +#line 479 "IWORKToken.gperf" + {"pattern-ref",pattern_ref}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 301 "IWORKToken.gperf" + {"grid-column",grid_column}, + {(char*)0}, +#line 514 "IWORKToken.gperf" + {"row-span",row_span}, +#line 327 "IWORKToken.gperf" + {"href",href}, +#line 671 "IWORKToken.gperf" + {"width",width}, +#line 84 "IWORKToken.gperf" + {"SFTTableNameStylePropertyLayoutStyle",SFTTableNameStylePropertyLayoutStyle}, +#line 322 "IWORKToken.gperf" + {"host-cell-ID",host_cell_ID}, + {(char*)0}, +#line 85 "IWORKToken.gperf" + {"SFTTableNameStylePropertyParagraphStyle",SFTTableNameStylePropertyParagraphStyle}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, +#line 149 "IWORKToken.gperf" + {"cell-style",cell_style}, +#line 235 "IWORKToken.gperf" + {"filled",filled}, +#line 459 "IWORKToken.gperf" + {"page-margins",page_margins}, + {(char*)0}, +#line 627 "IWORKToken.gperf" + {"text-label-ref",text_label_ref}, + {(char*)0}, +#line 597 "IWORKToken.gperf" + {"tableVectorAlong",tableVectorAlong}, + {(char*)0}, {(char*)0}, +#line 151 "IWORKToken.gperf" + {"cell-style-ref",cell_style_ref}, + {(char*)0}, +#line 182 "IWORKToken.gperf" + {"contbr",contbr}, +#line 478 "IWORKToken.gperf" + {"pattern",pattern}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, +#line 127 "IWORKToken.gperf" + {"both",both}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 130 "IWORKToken.gperf" + {"bubble-offset",bubble_offset}, + {(char*)0}, +#line 331 "IWORKToken.gperf" + {"http://developer.apple.com/namespaces/sf",NS_URI_SF}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 48 "IWORKToken.gperf" + {"SFIUDropShadow",SFIUDropShadow}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 248 "IWORKToken.gperf" + {"fitting-height",fitting_height}, +#line 383 "IWORKToken.gperf" + {"leftIndent",leftIndent}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 480 "IWORKToken.gperf" + {"phase",phase}, +#line 209 "IWORKToken.gperf" + {"directional",directional}, +#line 575 "IWORKToken.gperf" + {"table-vector",table_vector}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 375 "IWORKToken.gperf" + {"layout",layout}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, +#line 381 "IWORKToken.gperf" + {"layoutStyle",layoutStyle}, +#line 633 "IWORKToken.gperf" + {"textured-fill-ref",textured_fill_ref}, + {(char*)0}, {(char*)0}, +#line 401 "IWORKToken.gperf" + {"listTextIndents",listTextIndents}, + {(char*)0}, {(char*)0}, +#line 657 "IWORKToken.gperf" + {"val",val}, +#line 591 "IWORKToken.gperf" + {"tableModelIsHeaderColumn",tableModelIsHeaderColumn}, + {(char*)0}, +#line 379 "IWORKToken.gperf" + {"layoutstyle",layoutstyle}, + {(char*)0}, {(char*)0}, +#line 199 "IWORKToken.gperf" + {"date-cell",date_cell}, +#line 539 "IWORKToken.gperf" + {"slider-position",slider_position}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 300 "IWORKToken.gperf" + {"grid",grid}, +#line 150 "IWORKToken.gperf" + {"cell-style-default-line-height",cell_style_default_line_height}, + {(char*)0}, {(char*)0}, +#line 525 "IWORKToken.gperf" + {"selection-end",selection_end}, + {(char*)0}, +#line 416 "IWORKToken.gperf" + {"masking-shape-path-source",masking_shape_path_source}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 397 "IWORKToken.gperf" + {"listLabelGeometries",listLabelGeometries}, +#line 368 "IWORKToken.gperf" + {"labelCharacterStyle8",labelCharacterStyle8}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 303 "IWORKToken.gperf" + {"gridline-index",gridline_index,}, +#line 363 "IWORKToken.gperf" + {"labelCharacterStyle3",labelCharacterStyle3}, +#line 398 "IWORKToken.gperf" + {"listLabelIndents",listLabelIndents}, +#line 499 "IWORKToken.gperf" + {"rd",rd}, +#line 405 "IWORKToken.gperf" + {"localize",localize}, +#line 185 "IWORKToken.gperf" + {"copyright",copyright}, +#line 364 "IWORKToken.gperf" + {"labelCharacterStyle4",labelCharacterStyle4}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 125 "IWORKToken.gperf" + {"bold",bold}, +#line 367 "IWORKToken.gperf" + {"labelCharacterStyle7",labelCharacterStyle7}, +#line 332 "IWORKToken.gperf" + {"http://developer.apple.com/namespaces/sfa",NS_URI_SFA}, + {(char*)0}, {(char*)0}, +#line 653 "IWORKToken.gperf" + {"unfiltered-ref",unfiltered_ref}, +#line 365 "IWORKToken.gperf" + {"labelCharacterStyle5",labelCharacterStyle5}, +#line 102 "IWORKToken.gperf" + {"anon-styles",anon_styles}, + {(char*)0}, {(char*)0}, +#line 140 "IWORKToken.gperf" + {"capitalization",capitalization}, +#line 369 "IWORKToken.gperf" + {"labelCharacterStyle9",labelCharacterStyle9}, +#line 655 "IWORKToken.gperf" + {"upper-roman",upper_roman}, +#line 292 "IWORKToken.gperf" + {"generic-cell",generic_cell}, +#line 277 "IWORKToken.gperf" + {"format-string",format_string}, +#line 476 "IWORKToken.gperf" + {"path",path}, + {(char*)0}, +#line 135 "IWORKToken.gperf" + {"calc-engine",calc_engine}, + {(char*)0}, {(char*)0}, +#line 283 "IWORKToken.gperf" + {"formula-string",formula_string}, +#line 366 "IWORKToken.gperf" + {"labelCharacterStyle6",labelCharacterStyle6}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, +#line 535 "IWORKToken.gperf" + {"sizesLocked",sizesLocked}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 348 "IWORKToken.gperf" + {"inputGlossiness",inputGlossiness}, + {(char*)0}, +#line 325 "IWORKToken.gperf" + {"horizontal-offset",horizontal_offset}, + {(char*)0}, {(char*)0}, +#line 136 "IWORKToken.gperf" + {"calc-engine-entities",calc_engine_entities}, +#line 460 "IWORKToken.gperf" + {"page-number",page_number}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 110 "IWORKToken.gperf" + {"attachment",attachment}, +#line 544 "IWORKToken.gperf" + {"spaceBefore",spaceBefore}, + {(char*)0}, {(char*)0}, +#line 111 "IWORKToken.gperf" + {"attachment-ref",attachment_ref}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 61 "IWORKToken.gperf" + {"SFTDefaultFooterBodyVectorStyleProperty",SFTDefaultFooterBodyVectorStyleProperty}, +#line 674 "IWORKToken.gperf" + {"wrap-style",wrap_style}, + {(char*)0}, +#line 143 "IWORKToken.gperf" + {"cell-address",cell_address}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 116 "IWORKToken.gperf" + {"b",b}, + {(char*)0}, {(char*)0}, +#line 650 "IWORKToken.gperf" + {"unaligned",unaligned}, +#line 511 "IWORKToken.gperf" + {"round",round}, +#line 617 "IWORKToken.gperf" + {"tailLineEnd",tailLineEnd,}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 556 "IWORKToken.gperf" + {"strikethru",strikethru}, +#line 112 "IWORKToken.gperf" + {"attachments",attachments}, + {(char*)0}, +#line 376 "IWORKToken.gperf" + {"layoutMargins",layoutMargins}, + {(char*)0}, +#line 44 "IWORKToken.gperf" + {"SFC2DPieFillProperty",SFC2DPieFillProperty}, + {(char*)0}, +#line 670 "IWORKToken.gperf" + {"widowControl",widowControl}, +#line 640 "IWORKToken.gperf" + {"tocStyle",tocStyle}, + {(char*)0}, +#line 47 "IWORKToken.gperf" + {"SFC3DPieFillProperty",SFC3DPieFillProperty}, +#line 173 "IWORKToken.gperf" + {"column-label-formulas",column_label_formulas}, + {(char*)0}, +#line 638 "IWORKToken.gperf" + {"tocstyle",tocstyle}, + {(char*)0}, +#line 440 "IWORKToken.gperf" + {"num-header-rows",num_header_rows}, + {(char*)0}, +#line 639 "IWORKToken.gperf" + {"tocstyle-ref",tocstyle_ref}, +#line 439 "IWORKToken.gperf" + {"num-header-columns",num_header_columns}, +#line 73 "IWORKToken.gperf" + {"SFTDefaultGroupingRow3CellStyleProperty",SFTDefaultGroupingRowCell3StyleProperty}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 67 "IWORKToken.gperf" + {"SFTDefaultGroupingLevel3VectorStyleProperty",SFTDefaultGroupingLevel3VectorStyleProperty}, +#line 74 "IWORKToken.gperf" + {"SFTDefaultGroupingRow4CellStyleProperty",SFTDefaultGroupingRowCell4StyleProperty}, +#line 361 "IWORKToken.gperf" + {"labelCharacterStyle1",labelCharacterStyle1}, +#line 527 "IWORKToken.gperf" + {"seriesIndex",seriesIndex}, + {(char*)0}, +#line 68 "IWORKToken.gperf" + {"SFTDefaultGroupingLevel4VectorStyleProperty",SFTDefaultGroupingLevel4VectorStyleProperty}, +#line 547 "IWORKToken.gperf" + {"span-cell",span_cell}, +#line 380 "IWORKToken.gperf" + {"layoutstyle-ref",layoutstyle_ref}, + {(char*)0}, {(char*)0}, +#line 237 "IWORKToken.gperf" + {"filtered",filtered}, +#line 75 "IWORKToken.gperf" + {"SFTDefaultGroupingRow5CellStyleProperty",SFTDefaultGroupingRowCell5StyleProperty}, +#line 362 "IWORKToken.gperf" + {"labelCharacterStyle2",labelCharacterStyle2}, + {(char*)0}, +#line 142 "IWORKToken.gperf" + {"cb",cb}, +#line 69 "IWORKToken.gperf" + {"SFTDefaultGroupingLevel5VectorStyleProperty",SFTDefaultGroupingLevel5VectorStyleProperty}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 323 "IWORKToken.gperf" + {"host-table-ID",host_table_ID}, +#line 198 "IWORKToken.gperf" + {"data",data}, + {(char*)0}, +#line 320 "IWORKToken.gperf" + {"height",height}, + {(char*)0}, {(char*)0}, +#line 238 "IWORKToken.gperf" + {"filtered-image",filtered_image}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 239 "IWORKToken.gperf" + {"filtered-image-ref",filtered_image_ref}, + {(char*)0}, +#line 346 "IWORKToken.gperf" + {"inputColor",inputColor}, + {(char*)0}, {(char*)0}, +#line 513 "IWORKToken.gperf" + {"row-label-formulas",row_label_formulas}, +#line 421 "IWORKToken.gperf" + {"min-value",min_value}, +#line 626 "IWORKToken.gperf" + {"text-label",text_label}, +#line 465 "IWORKToken.gperf" + {"padding-ref",padding_ref}, + {(char*)0}, {(char*)0}, +#line 70 "IWORKToken.gperf" + {"SFTDefaultGroupingRow0CellStyleProperty",SFTDefaultGroupingRowCell0StyleProperty}, + {(char*)0}, {(char*)0}, +#line 595 "IWORKToken.gperf" + {"tableModelTableID",tableModelTableID}, +#line 64 "IWORKToken.gperf" + {"SFTDefaultGroupingLevel0VectorStyleProperty",SFTDefaultGroupingLevel0VectorStyleProperty}, + {(char*)0}, {(char*)0}, +#line 532 "IWORKToken.gperf" + {"shearXAngle",shearXAngle}, + {(char*)0}, {(char*)0}, +#line 463 "IWORKToken.gperf" + {"pgbr",pgbr}, +#line 666 "IWORKToken.gperf" + {"vertical-offset",vertical_offset}, + {(char*)0}, {(char*)0}, +#line 393 "IWORKToken.gperf" + {"list-label-geometry-ref",list_label_geometry_ref}, +#line 76 "IWORKToken.gperf" + {"SFTDefaultHeaderBodyVectorStyleProperty",SFTDefaultHeaderBodyVectorStyleProperty}, + {(char*)0}, +#line 134 "IWORKToken.gperf" + {"cached-data",cached_data}, + {(char*)0}, +#line 390 "IWORKToken.gperf" + {"line-end",line_end}, +#line 93 "IWORKToken.gperf" + {"animationDelay",animationDelay}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 42 "IWORKToken.gperf" + {"SFC2DColumnFillProperty",SFC2DColumnFillProperty}, +#line 63 "IWORKToken.gperf" + {"SFTDefaultFooterSeparatorVectorStyleProperty",SFTDefaultFooterSeparatorVectorStyleProperty}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 46 "IWORKToken.gperf" + {"SFC3DColumnFillProperty",SFC3DColumnFillProperty}, + {(char*)0}, {(char*)0}, +#line 457 "IWORKToken.gperf" + {"p",p}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, +#line 664 "IWORKToken.gperf" + {"verticalAlignment",verticalAlignment}, +#line 203 "IWORKToken.gperf" + {"data-ref",data_ref}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 661 "IWORKToken.gperf" + {"vector-style",vector_style}, + {(char*)0}, +#line 77 "IWORKToken.gperf" + {"SFTDefaultHeaderColumnCellStyleProperty",SFTDefaultHeaderColumnCellStyleProperty}, +#line 97 "IWORKToken.gperf" + {"attachment-wrap-type",attachment_wrap_type}, + {(char*)0}, {(char*)0}, +#line 632 "IWORKToken.gperf" + {"textured-fill",textured_fill}, + {(char*)0}, {(char*)0}, +#line 662 "IWORKToken.gperf" + {"vector-style-ref",vector_style_ref}, +#line 498 "IWORKToken.gperf" + {"rb",rb}, +#line 138 "IWORKToken.gperf" + {"callout2-path",callout2_path}, +#line 71 "IWORKToken.gperf" + {"SFTDefaultGroupingRow1CellStyleProperty",SFTDefaultGroupingRowCell1StyleProperty}, + {(char*)0}, +#line 533 "IWORKToken.gperf" + {"shearYAngle",shearYAngle}, +#line 297 "IWORKToken.gperf" + {"gradient-stop-ref",gradient_stop_ref}, +#line 65 "IWORKToken.gperf" + {"SFTDefaultGroupingLevel1VectorStyleProperty",SFTDefaultGroupingLevel1VectorStyleProperty}, +#line 417 "IWORKToken.gperf" + {"max-value",max_value}, + {(char*)0}, {(char*)0}, +#line 419 "IWORKToken.gperf" + {"menu-choices",menu_choices}, +#line 227 "IWORKToken.gperf" + {"external-text-wrap",external_text_wrap}, +#line 72 "IWORKToken.gperf" + {"SFTDefaultGroupingRow2CellStyleProperty",SFTDefaultGroupingRowCell2StyleProperty}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 66 "IWORKToken.gperf" + {"SFTDefaultGroupingLevel2VectorStyleProperty",SFTDefaultGroupingLevel2VectorStyleProperty}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, +#line 543 "IWORKToken.gperf" + {"spaceAfter",spaceAfter}, + {(char*)0}, +#line 92 "IWORKToken.gperf" + {"animationAutoPlay",animationAutoPlay}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 431 "IWORKToken.gperf" + {"naturalSize",naturalSize}, +#line 610 "IWORKToken.gperf" + {"tabular-info",tabular_info}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 654 "IWORKToken.gperf" + {"upper-alpha",upper_alpha}, + {(char*)0}, +#line 420 "IWORKToken.gperf" + {"metadata",metadata}, +#line 216 "IWORKToken.gperf" + {"duration-format-ref",duration_format_ref}, +#line 215 "IWORKToken.gperf" + {"duration-format",duration_format}, +#line 497 "IWORKToken.gperf" + {"radial",radial}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 41 "IWORKToken.gperf" + {"SFC2DAreaFillProperty",SFC2DAreaFillProperty}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 96 "IWORKToken.gperf" + {"alpha-threshold",alpha_threshold}, +#line 45 "IWORKToken.gperf" + {"SFC3DAreaFillProperty",SFC3DAreaFillProperty}, + {(char*)0}, +#line 448 "IWORKToken.gperf" + {"oddPageMaster",oddPageMaster}, + {(char*)0}, {(char*)0}, +#line 104 "IWORKToken.gperf" + {"annotation-field",annotation_field}, + {(char*)0}, +#line 370 "IWORKToken.gperf" + {"language",language}, + {(char*)0}, +#line 473 "IWORKToken.gperf" + {"parameters",parameters}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 79 "IWORKToken.gperf" + {"SFTDefaultHeaderSeparatorVectorStyleProperty",SFTDefaultHeaderSeparatorVectorStyleProperty}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, +#line 345 "IWORKToken.gperf" + {"inputAngle",inputAngle}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, +#line 60 "IWORKToken.gperf" + {"SFTDefaultBorderVectorStyleProperty",SFTDefaultBorderVectorStyleProperty}, + {(char*)0}, +#line 489 "IWORKToken.gperf" + {"poster-image",poster_image}, + {(char*)0}, {(char*)0}, +#line 167 "IWORKToken.gperf" + {"chart-type",chart_type}, +#line 62 "IWORKToken.gperf" + {"SFTDefaultFooterRowCellStyleProperty",SFTDefaultFooterRowCellStyleProperty}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, +#line 488 "IWORKToken.gperf" + {"position",position}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, +#line 477 "IWORKToken.gperf" + {"path-join",path_join}, + {(char*)0}, {(char*)0}, +#line 606 "IWORKToken.gperf" + {"tabstop",tabstop}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, +#line 269 "IWORKToken.gperf" + {"format-base-places",format_base_places}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 350 "IWORKToken.gperf" + {"inputRadius",inputRadius}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, +#line 55 "IWORKToken.gperf" + {"SFTCellStylePropertyNumberFormat",SFTCellStylePropertyNumberFormat}, + {(char*)0}, {(char*)0}, +#line 205 "IWORKToken.gperf" + {"datasource",datasource}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, +#line 507 "IWORKToken.gperf" + {"result-text-cell",result_text_cell}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 119 "IWORKToken.gperf" + {"bezier",bezier}, +#line 384 "IWORKToken.gperf" + {"leveled",leveled}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 121 "IWORKToken.gperf" + {"bezier-ref",bezier_ref}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 455 "IWORKToken.gperf" + {"overrides",overrides}, + {(char*)0}, {(char*)0}, +#line 500 "IWORKToken.gperf" + {"regular",regular}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 319 "IWORKToken.gperf" + {"headLineEnd",headLineEnd}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 406 "IWORKToken.gperf" + {"locked",locked}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 226 "IWORKToken.gperf" + {"externalTextWrap",externalTextWrap}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 78 "IWORKToken.gperf" + {"SFTDefaultHeaderRowCellStyleProperty",SFTDefaultHeaderRowCellStyleProperty}, + {(char*)0}, {(char*)0}, +#line 400 "IWORKToken.gperf" + {"listStyle",listStyle}, + {(char*)0}, {(char*)0}, +#line 676 "IWORKToken.gperf" + {"x-coordinate",x_coordinate}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, +#line 501 "IWORKToken.gperf" + {"relative",relative}, +#line 402 "IWORKToken.gperf" + {"liststyle",liststyle}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 224 "IWORKToken.gperf" + {"evenPageMaster",evenPageMaster}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 552 "IWORKToken.gperf" + {"sticky-note",sticky_note}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, +#line 324 "IWORKToken.gperf" + {"horizontal-gridline-styles",horizontal_gridline_styles}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 656 "IWORKToken.gperf" + {"v",v}, +#line 352 "IWORKToken.gperf" + {"intratopicbr",intratopicbr}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, +#line 430 "IWORKToken.gperf" + {"natural",natural}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, +#line 594 "IWORKToken.gperf" + {"tableModelStyle-ref",tableModelStyle_ref}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 456 "IWORKToken.gperf" + {"overrides-ref",overrides_ref}, + {(char*)0}, +#line 396 "IWORKToken.gperf" + {"list-level",list_level}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 200 "IWORKToken.gperf" + {"data-formulas",data_formulas}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, +#line 207 "IWORKToken.gperf" + {"decimal-number",number}, +#line 652 "IWORKToken.gperf" + {"unfiltered",unfiltered}, +#line 557 "IWORKToken.gperf" + {"string",string}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 608 "IWORKToken.gperf" + {"tabuar-style-name-internal",tabular_style_name_internal}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, +#line 658 "IWORKToken.gperf" + {"value",value}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 389 "IWORKToken.gperf" + {"linespacing-ref",linespacing_ref}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 541 "IWORKToken.gperf" + {"solid",solid}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 403 "IWORKToken.gperf" + {"liststyle-ref",liststyle_ref}, + {(char*)0}, {(char*)0}, +#line 660 "IWORKToken.gperf" + {"value-title",value_title}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 504 "IWORKToken.gperf" + {"result-cell",result_cell}, +#line 206 "IWORKToken.gperf" + {"decimal",decimal}, +#line 643 "IWORKToken.gperf" + {"tracking",tracking}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, +#line 240 "IWORKToken.gperf" + {"filter-properties",filter_properties}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 377 "IWORKToken.gperf" + {"layoutParagraphStyle",layoutParagraphStyle}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 464 "IWORKToken.gperf" + {"padding",padding}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, +#line 213 "IWORKToken.gperf" + {"drawables",drawables}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, +#line 89 "IWORKToken.gperf" + {"aligned",aligned}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 81 "IWORKToken.gperf" + {"SFTHeaderRowRepeatsProperty",SFTHeaderRowRepeatsProperty}, + {(char*)0}, +#line 659 "IWORKToken.gperf" + {"value-ref",value_ref}, + {(char*)0}, +#line 519 "IWORKToken.gperf" + {"scalar-path",scalar_path}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, +#line 137 "IWORKToken.gperf" + {"calligraphy-stroke",calligraphy_stroke}, + {(char*)0}, {(char*)0}, +#line 210 "IWORKToken.gperf" + {"displayname",displayname}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, +#line 326 "IWORKToken.gperf" + {"horizontalFlip",horizontalFlip}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 678 "IWORKToken.gperf" + {"y",y}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 378 "IWORKToken.gperf" + {"layoutParagraphStyle-ref",layoutParagraphStyle_ref}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, +#line 108 "IWORKToken.gperf" + {"array-ref",array_ref}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, +#line 486 "IWORKToken.gperf" + {"point-path",point_path}, +#line 58 "IWORKToken.gperf" + {"SFTDefaultBodyCellStyleProperty",SFTDefaultBodyCellStyleProperty}, +#line 230 "IWORKToken.gperf" + {"facing-pages",facing_pages}, +#line 59 "IWORKToken.gperf" + {"SFTDefaultBodyVectorStyleProperty",SFTDefaultBodyVectorStyleProperty}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 667 "IWORKToken.gperf" + {"verticalFlip",verticalFlip}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, +#line 141 "IWORKToken.gperf" + {"category-title",category_title}, +#line 217 "IWORKToken.gperf" + {"editable-bezier-path",editable_bezier_path}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 50 "IWORKToken.gperf" + {"SFTableStylePropertyCellStyle",SFTableStylePropertyCellStyle}, + {(char*)0}, {(char*)0}, +#line 82 "IWORKToken.gperf" + {"SFTStrokeProperty", SFTStrokeProperty}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 505 "IWORKToken.gperf" + {"result-date-cell",result_date_cell}, + {(char*)0}, {(char*)0}, +#line 344 "IWORKToken.gperf" + {"inline-wrap-enabled",inline_wrap_enabled}, + {(char*)0}, +#line 490 "IWORKToken.gperf" + {"preferred-height",preferred_height}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, +#line 249 "IWORKToken.gperf" + {"fitting-width",fitting_width}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 243 "IWORKToken.gperf" + {"filter_visibility",filter_visibility}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, +#line 296 "IWORKToken.gperf" + {"gradient-stop",gradient_stop}, + {(char*)0}, +#line 219 "IWORKToken.gperf" + {"empty",empty}, +#line 386 "IWORKToken.gperf" + {"lineSpacing",lineSpacing}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 80 "IWORKToken.gperf" + {"SFTHeaderColumnRepeatsProperty",SFTHeaderColumnRepeatsProperty}, +#line 388 "IWORKToken.gperf" + {"linespacing",linespacing}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 399 "IWORKToken.gperf" + {"listLabelTypes",listLabelTypes}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, +#line 298 "IWORKToken.gperf" + {"graphic-style",graphic_style}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 299 "IWORKToken.gperf" + {"graphic-style-ref",graphic_style_ref}, +#line 321 "IWORKToken.gperf" + {"hfs-type",hfs_type}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 289 "IWORKToken.gperf" + {"frame-y",frame_y}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 223 "IWORKToken.gperf" + {"error_warning_mapping",error_warning_mapping}, +#line 612 "IWORKToken.gperf" + {"tabular-model-ref",tabular_model_ref}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, +#line 86 "IWORKToken.gperf" + {"__multilingual",__multilingual}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 672 "IWORKToken.gperf" + {"workspace-style",workspace_style}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, +#line 273 "IWORKToken.gperf" + {"format-fraction-accuracy",format_fraction_accuracy}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 252 "IWORKToken.gperf" + {"floating-wrap-type",floating_wrap_type}, +#line 665 "IWORKToken.gperf" + {"vertical-gridline-styles",vertical_gridline_styles,}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 545 "IWORKToken.gperf" + {"spacing",spacing}, + {(char*)0}, +#line 624 "IWORKToken.gperf" + {"text-body",text_body}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 506 "IWORKToken.gperf" + {"result-number-cell",result_number_cell}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 43 "IWORKToken.gperf" + {"SFC2DMixedColumnFillProperty",SFC2DMixedColumnFillProperty}, +#line 392 "IWORKToken.gperf" + {"list-label-geometry",list_label_geometry}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 395 "IWORKToken.gperf" + {"list-label-typeinfo-ref",list_label_typeinfo_ref}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, +#line 52 "IWORKToken.gperf" + {"SFTableStylePropertyHeaderRowCellStyle",SFTableStylePropertyHeaderRowCellStyle}, + {(char*)0}, {(char*)0}, +#line 51 "IWORKToken.gperf" + {"SFTableStylePropertyHeaderColumnCellStyle",SFTableStylePropertyHeaderColumnCellStyle}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, +#line 481 "IWORKToken.gperf" + {"placeholder-size",placeholder_size}, +#line 482 "IWORKToken.gperf" + {"placeholder-style",placeholder_style}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 483 "IWORKToken.gperf" + {"placeholder-style-ref",placeholder_style_ref}, + {(char*)0}, {(char*)0}, +#line 394 "IWORKToken.gperf" + {"list-label-typeinfo",list_label_typeinfo}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 613 "IWORKToken.gperf" + {"tabular-style",tabular_style}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 614 "IWORKToken.gperf" + {"tabular-style-ref",tabular_style_ref}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, +#line 679 "IWORKToken.gperf" + {"y-coordinate",y_coordinate}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, +#line 129 "IWORKToken.gperf" + {"bubble-cellid",bubble_cellid}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, +#line 306 "IWORKToken.gperf" + {"group-formula-value",group_formula_value}, +#line 124 "IWORKToken.gperf" + {"body-placeholder-ref",body_placeholder_ref}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, +#line 503 "IWORKToken.gperf" + {"result-bool-cell",result_bool_cell}, + {(char*)0}, +#line 611 "IWORKToken.gperf" + {"tabular-model",tabular_model}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, +#line 412 "IWORKToken.gperf" + {"manipulated-stroke",manipulated_stroke}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 123 "IWORKToken.gperf" + {"binary-ref",binary_ref}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, +#line 494 "IWORKToken.gperf" + {"proxied-cell-ref",proxied_cell_ref}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, +#line 349 "IWORKToken.gperf" + {"inputOpacity",inputOpacity}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, +#line 293 "IWORKToken.gperf" + {"geometry",geometry}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, +#line 491 "IWORKToken.gperf" + {"preferred-width",preferred_width}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 193 "IWORKToken.gperf" + {"crop-geometry",crop_geometry}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, +#line 313 "IWORKToken.gperf" + {"groupings-element",groupings_element}, + {(char*)0}, +#line 312 "IWORKToken.gperf" + {"grouping-state",grouping_state}, + {(char*)0}, {(char*)0}, +#line 493 "IWORKToken.gperf" + {"property-map",property_map}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 642 "IWORKToken.gperf" + {"traced-path",traced_path}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, +#line 609 "IWORKToken.gperf" + {"tabular-style-name-internal",tabular_style_name_internal}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 427 "IWORKToken.gperf" + {"mutable-array-ref",mutable_array_ref}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, +#line 107 "IWORKToken.gperf" + {"array",array}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, +#line 251 "IWORKToken.gperf" + {"floating-wrap-enabled",floating_wrap_enabled}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, +#line 304 "IWORKToken.gperf" + {"group",group}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, +#line 470 "IWORKToken.gperf" + {"paragraphStroke",paragraphStroke}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, +#line 83 "IWORKToken.gperf" + {"SFTTableBandedRowsProperty",SFTTableBandedRowsProperty}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, +#line 305 "IWORKToken.gperf" + {"group-formula-string",group_formula_string}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, +#line 212 "IWORKToken.gperf" + {"drawable-shape",drawable_shape}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 120 "IWORKToken.gperf" + {"bezier-path",bezier_path}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 311 "IWORKToken.gperf" + {"grouping-order",grouping_order}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 307 "IWORKToken.gperf" + {"group-formula-value-valid",group_formula_value_valid}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, +#line 413 "IWORKToken.gperf" + {"manually-sized",manually_sized}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, +#line 495 "IWORKToken.gperf" + {"proxy-master-layer",proxy_master_layer}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 471 "IWORKToken.gperf" + {"paragraphstyle",paragraphstyle}, + {(char*)0}, +#line 308 "IWORKToken.gperf" + {"group-value",group_value}, + {(char*)0}, +#line 472 "IWORKToken.gperf" + {"paragraphstyle-ref",paragraphstyle_ref}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, +#line 49 "IWORKToken.gperf" + {"SFTableCellStylePropertyFill",SFTableCellStylePropertyFill}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, +#line 451 "IWORKToken.gperf" + {"opacity",opacity}, +#line 309 "IWORKToken.gperf" + {"grouping",grouping}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 469 "IWORKToken.gperf" + {"paragraphFill",paragraphFill}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 122 "IWORKToken.gperf" + {"binary",binary}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 468 "IWORKToken.gperf" + {"paragraphBorderType",paragraphBorderType}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 426 "IWORKToken.gperf" + {"mutable-array",mutable_array}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, +#line 310 "IWORKToken.gperf" + {"grouping-display",grouping_display} + }; + + if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) + { + register int key = hash (str, len); + + if (key <= MAX_HASH_VALUE && key >= 0) + { + register const char *s = wordlist[key].name; + + if (s && *str == *s && !strncmp (str + 1, s + 1, len - 1) && s[len] == '\0') + return &wordlist[key]; + } + } + return 0; +} +#line 680 "IWORKToken.gperf" + diff --git a/Common/3dParty/apple/headers/KEY1Token.inc b/Common/3dParty/apple/headers/KEY1Token.inc new file mode 100644 index 00000000000..d49ddb0deb5 --- /dev/null +++ b/Common/3dParty/apple/headers/KEY1Token.inc @@ -0,0 +1,727 @@ +/* C++ code produced by gperf version 3.0.1 */ +/* Command-line: gperf --compare-strncmp --enum --null-strings --readonly-tables --language C++ --output-file KEY1Token.inc KEY1Token.gperf */ +/* Computed positions: -k'1,3,6,9,14,$' */ + +#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ + && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \ + && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \ + && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \ + && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \ + && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \ + && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \ + && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \ + && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \ + && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \ + && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \ + && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \ + && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \ + && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \ + && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \ + && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \ + && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \ + && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \ + && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \ + && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \ + && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \ + && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \ + && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126)) +/* The character set is not based on ISO-646. */ +#error "gperf generated tables don't work with this execution character set. Please report a bug to ." +#endif + +#line 10 "KEY1Token.gperf" + +#if defined __GNUC__ +#pragma GCC diagnostic ignored "-Wmissing-field-initializers" +#endif + +using namespace KEY1Token; +#line 18 "KEY1Token.gperf" +struct Token +{ + const char *name; + int id; +}; +#include +/* maximum key range = 602, duplicates = 0 */ + +class Perfect_Hash +{ +private: + static inline unsigned int hash (const char *str, unsigned int len); +public: + static const struct Token *in_word_set (const char *str, unsigned int len); +}; + +inline unsigned int +Perfect_Hash::hash (register const char *str, register unsigned int len) +{ + static const unsigned short asso_values[] = + { + 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, + 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, + 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, + 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, + 612, 612, 612, 612, 612, 220, 612, 0, 612, 612, + 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, + 612, 612, 612, 612, 612, 612, 0, 0, 0, 0, + 0, 0, 10, 612, 612, 612, 0, 612, 30, 15, + 55, 612, 5, 60, 5, 612, 10, 612, 612, 612, + 612, 612, 612, 612, 612, 0, 612, 20, 165, 115, + 65, 0, 105, 135, 175, 60, 0, 0, 30, 145, + 10, 5, 155, 10, 5, 30, 5, 200, 15, 20, + 0, 190, 0, 612, 612, 612, 612, 612, 612, 612, + 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, + 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, + 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, + 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, + 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, + 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, + 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, + 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, + 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, + 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, + 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, + 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, + 612, 612, 612, 612, 612, 612 + }; + register int hval = len; + + switch (hval) + { + default: + hval += asso_values[(unsigned char)str[13]]; + /*FALLTHROUGH*/ + case 13: + case 12: + case 11: + case 10: + case 9: + hval += asso_values[(unsigned char)str[8]]; + /*FALLTHROUGH*/ + case 8: + case 7: + case 6: + hval += asso_values[(unsigned char)str[5]]; + /*FALLTHROUGH*/ + case 5: + case 4: + case 3: + hval += asso_values[(unsigned char)str[2]]; + /*FALLTHROUGH*/ + case 2: + case 1: + hval += asso_values[(unsigned char)str[0]]; + break; + } + return hval + asso_values[(unsigned char)str[len - 1]]; +} + +const struct Token * +Perfect_Hash::in_word_set (register const char *str, register unsigned int len) +{ + enum + { + TOTAL_KEYWORDS = 203, + MIN_WORD_LENGTH = 1, + MAX_WORD_LENGTH = 39, + MIN_HASH_VALUE = 10, + MAX_HASH_VALUE = 611 + }; + + static const struct Token wordlist[] = + { + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, +#line 199 "KEY1Token.gperf" + {"theme",theme}, + {(char*)0}, +#line 211 "KEY1Token.gperf" + {"tr",tr}, + {(char*)0}, +#line 196 "KEY1Token.gperf" + {"text",text}, +#line 207 "KEY1Token.gperf" + {"title",title}, + {(char*)0}, +#line 198 "KEY1Token.gperf" + {"textbox",textbox}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 65 "KEY1Token.gperf" + {"element",element}, + {(char*)0}, +#line 132 "KEY1Token.gperf" + {"none",none}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, +#line 175 "KEY1Token.gperf" + {"size",size}, + {(char*)0}, {(char*)0}, +#line 209 "KEY1Token.gperf" + {"tl",tl}, + {(char*)0}, +#line 206 "KEY1Token.gperf" + {"tile",tile}, +#line 168 "KEY1Token.gperf" + {"serie",serie}, + {(char*)0}, +#line 221 "KEY1Token.gperf" + {"version",version}, + {(char*)0}, +#line 112 "KEY1Token.gperf" + {"line",line}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 174 "KEY1Token.gperf" + {"showZero",showZero}, + {(char*)0}, +#line 133 "KEY1Token.gperf" + {"notes",notes}, + {(char*)0}, +#line 188 "KEY1Token.gperf" + {"stroke-style",stroke_style}, + {(char*)0}, +#line 32 "KEY1Token.gperf" + {"axes",axes}, +#line 172 "KEY1Token.gperf" + {"shape",shape}, + {(char*)0}, +#line 187 "KEY1Token.gperf" + {"stroke-color",stroke_color}, +#line 166 "KEY1Token.gperf" + {"sequence",sequence}, + {(char*)0}, +#line 183 "KEY1Token.gperf" + {"start",start}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 182 "KEY1Token.gperf" + {"span",span}, +#line 185 "KEY1Token.gperf" + {"steps",steps}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 93 "KEY1Token.gperf" + {"ident",ident}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 134 "KEY1Token.gperf" + {"null",null}, +#line 197 "KEY1Token.gperf" + {"text-attributes",text_attributes}, + {(char*)0}, +#line 130 "KEY1Token.gperf" + {"natural-size",natural_size}, + {(char*)0}, +#line 131 "KEY1Token.gperf" + {"node",node}, +#line 111 "KEY1Token.gperf" + {"level",level}, + {(char*)0}, +#line 225 "KEY1Token.gperf" + {"visible",visible}, + {(char*)0}, {(char*)0}, +#line 95 "KEY1Token.gperf" + {"image",image}, + {(char*)0}, +#line 171 "KEY1Token.gperf" + {"shadow-style",shadow_style}, + {(char*)0}, +#line 67 "KEY1Token.gperf" + {"end-color",end_color}, + {(char*)0}, {(char*)0}, +#line 208 "KEY1Token.gperf" + {"titleVisible",titleVisible}, +#line 212 "KEY1Token.gperf" + {"tracks-master",tracks_master}, +#line 53 "KEY1Token.gperf" + {"data",data}, +#line 177 "KEY1Token.gperf" + {"slide",slide}, + {(char*)0}, {(char*)0}, +#line 62 "KEY1Token.gperf" + {"div",div}, +#line 195 "KEY1Token.gperf" + {"tail",tail}, +#line 170 "KEY1Token.gperf" + {"seriesDirection",seriesDirection}, +#line 169 "KEY1Token.gperf" + {"series",series}, + {(char*)0}, +#line 162 "KEY1Token.gperf" + {"relative",relative}, +#line 60 "KEY1Token.gperf" + {"direction",direction}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 27 "KEY1Token.gperf" + {"altLineVisible",altLineVisible}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 173 "KEY1Token.gperf" + {"showGrid",showGrid}, +#line 33 "KEY1Token.gperf" + {"axis",axis}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 161 "KEY1Token.gperf" + {"reference",reference}, +#line 114 "KEY1Token.gperf" + {"line-tail-style",line_tail_style}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 73 "KEY1Token.gperf" + {"font",font}, + {(char*)0}, +#line 137 "KEY1Token.gperf" + {"offset",offset}, +#line 92 "KEY1Token.gperf" + {"id",id}, + {(char*)0}, +#line 160 "KEY1Token.gperf" + {"rect",rect}, +#line 180 "KEY1Token.gperf" + {"solid",solid}, + {(char*)0}, {(char*)0}, +#line 66 "KEY1Token.gperf" + {"end",end}, +#line 77 "KEY1Token.gperf" + {"font-name",font_name}, + {(char*)0}, +#line 159 "KEY1Token.gperf" + {"radius",radius}, +#line 61 "KEY1Token.gperf" + {"display-name",display_name}, + {(char*)0}, +#line 68 "KEY1Token.gperf" + {"file",file}, + {(char*)0}, +#line 45 "KEY1Token.gperf" + {"center",center}, + {(char*)0}, {(char*)0}, +#line 109 "KEY1Token.gperf" + {"left",left}, + {(char*)0}, {(char*)0}, +#line 51 "KEY1Token.gperf" + {"content",content}, +#line 64 "KEY1Token.gperf" + {"duration",duration}, +#line 71 "KEY1Token.gperf" + {"fill-type",fill_type}, +#line 163 "KEY1Token.gperf" + {"right",right}, +#line 139 "KEY1Token.gperf" + {"orientation",orientation}, + {(char*)0}, {(char*)0}, +#line 78 "KEY1Token.gperf" + {"font-size",font_size}, +#line 50 "KEY1Token.gperf" + {"color",color}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 129 "KEY1Token.gperf" + {"name",name}, +#line 28 "KEY1Token.gperf" + {"angle",angle}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 215 "KEY1Token.gperf" + {"type",type}, +#line 52 "KEY1Token.gperf" + {"dash-style",dash_style}, + {(char*)0}, {(char*)0}, +#line 82 "KEY1Token.gperf" + {"gradient",gradient}, +#line 56 "KEY1Token.gperf" + {"dataFormatterPrefix",dataFormatterPrefix}, +#line 54 "KEY1Token.gperf" + {"dataFormatterHasThousandsSeparators",dataFormatterHasThousandsSeparators}, +#line 135 "KEY1Token.gperf" + {"number",number}, +#line 38 "KEY1Token.gperf" + {"br",br}, +#line 222 "KEY1Token.gperf" + {"vertical",vertical}, +#line 57 "KEY1Token.gperf" + {"dataFormatterSuffix",dataFormatterSuffix}, +#line 193 "KEY1Token.gperf" + {"table",table}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 24 "KEY1Token.gperf" + {"DefaultLegendRelativePosition",DefaultLegendRelativePosition}, + {(char*)0}, {(char*)0}, +#line 146 "KEY1Token.gperf" + {"pattern",pattern}, + {(char*)0}, +#line 55 "KEY1Token.gperf" + {"dataFormatterNumberOfDecimals",dataFormatterNumberOfDecimals}, + {(char*)0}, {(char*)0}, +#line 165 "KEY1Token.gperf" + {"segment",segment}, + {(char*)0}, +#line 59 "KEY1Token.gperf" + {"dict",dict}, + {(char*)0}, {(char*)0}, +#line 153 "KEY1Token.gperf" + {"presentation",presentation}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 35 "KEY1Token.gperf" + {"bl",bl}, +#line 126 "KEY1Token.gperf" + {"metadata",metadata}, + {(char*)0}, +#line 86 "KEY1Token.gperf" + {"guide",guide}, + {(char*)0}, +#line 181 "KEY1Token.gperf" + {"spacing",spacing}, +#line 120 "KEY1Token.gperf" + {"majorTickPositions",majorTickPositions}, + {(char*)0}, +#line 70 "KEY1Token.gperf" + {"fill-style",fill_style}, + {(char*)0}, +#line 118 "KEY1Token.gperf" + {"lock-aspect-ratio",lock_aspect_ratio}, + {(char*)0}, +#line 44 "KEY1Token.gperf" + {"byte-size",byte_size}, + {(char*)0}, +#line 40 "KEY1Token.gperf" + {"bullet",bullet}, +#line 25 "KEY1Token.gperf" + {"DefaultLegendSize",DefaultLegendSize}, +#line 128 "KEY1Token.gperf" + {"minorTickPositions",minorTickPositions}, + {(char*)0}, +#line 202 "KEY1Token.gperf" + {"tickLabelsAngle",tickLabelsAngle}, +#line 127 "KEY1Token.gperf" + {"middle",middle}, + {(char*)0}, +#line 152 "KEY1Token.gperf" + {"pos",pos}, +#line 155 "KEY1Token.gperf" + {"prototype-data",prototype_data}, +#line 31 "KEY1Token.gperf" + {"array",array}, + {(char*)0}, +#line 122 "KEY1Token.gperf" + {"master-slide",master_slide}, +#line 117 "KEY1Token.gperf" + {"location",location}, +#line 176 "KEY1Token.gperf" + {"size-technique",size_technique}, + {(char*)0}, +#line 79 "KEY1Token.gperf" + {"font-superscript",font_superscript}, +#line 138 "KEY1Token.gperf" + {"opacity",opacity}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 100 "KEY1Token.gperf" + {"interBarGap",interBarGap}, + {(char*)0}, {(char*)0}, +#line 156 "KEY1Token.gperf" + {"prototype-drawables",prototype_drawables}, + {(char*)0}, +#line 58 "KEY1Token.gperf" + {"description",description}, +#line 43 "KEY1Token.gperf" + {"bullets",bullets}, + {(char*)0}, +#line 76 "KEY1Token.gperf" + {"font-ligatures",font_ligatures}, + {(char*)0}, +#line 191 "KEY1Token.gperf" + {"symbol",symbol}, +#line 154 "KEY1Token.gperf" + {"prototype-bullets",prototype_bullets}, + {(char*)0}, +#line 194 "KEY1Token.gperf" + {"tab-stops",tab_stops}, +#line 90 "KEY1Token.gperf" + {"horizontal",horizontal}, + {(char*)0}, +#line 204 "KEY1Token.gperf" + {"tickLabelsVisible",tickLabelsVisible}, + {(char*)0}, +#line 192 "KEY1Token.gperf" + {"symbolFillMode",symbolFillMode}, +#line 74 "KEY1Token.gperf" + {"font-color",font_color}, + {(char*)0}, {(char*)0}, +#line 124 "KEY1Token.gperf" + {"master-slides",master_slides}, +#line 147 "KEY1Token.gperf" + {"pieSliceOffset",pieSliceOffset}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 42 "KEY1Token.gperf" + {"bullet-indentation",bullet_indentation}, + {(char*)0}, {(char*)0}, +#line 87 "KEY1Token.gperf" + {"guides",guides}, + {(char*)0}, {(char*)0}, +#line 88 "KEY1Token.gperf" + {"head",head}, +#line 226 "KEY1Token.gperf" + {"width",width}, +#line 89 "KEY1Token.gperf" + {"hidden",hidden}, + {(char*)0}, {(char*)0}, +#line 46 "KEY1Token.gperf" + {"character",character}, +#line 69 "KEY1Token.gperf" + {"fill-color",fill_color}, +#line 81 "KEY1Token.gperf" + {"g",g}, +#line 75 "KEY1Token.gperf" + {"font-kerning",font_kerning}, + {(char*)0}, +#line 103 "KEY1Token.gperf" + {"justified",justified}, + {(char*)0}, +#line 116 "KEY1Token.gperf" + {"lineVisible",lineVisible}, +#line 107 "KEY1Token.gperf" + {"labelVisible",labelVisible}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 119 "KEY1Token.gperf" + {"locked",locked}, +#line 189 "KEY1Token.gperf" + {"stroke-width",stroke_width}, + {(char*)0}, +#line 200 "KEY1Token.gperf" + {"thumbnail",thumbnail}, +#line 201 "KEY1Token.gperf" + {"thumbnails",thumbnails}, +#line 190 "KEY1Token.gperf" + {"styles",styles}, + {(char*)0}, {(char*)0}, +#line 136 "KEY1Token.gperf" + {"numberOfPoints",numberOfPoints}, +#line 49 "KEY1Token.gperf" + {"chartFrame",chartFrame}, +#line 167 "KEY1Token.gperf" + {"sequence-bullet-style",sequence_bullet_style}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 214 "KEY1Token.gperf" + {"transition-style",transition_style}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 110 "KEY1Token.gperf" + {"legend",legend}, +#line 148 "KEY1Token.gperf" + {"pieSlicePercentVisible",pieSlicePercentVisible}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 47 "KEY1Token.gperf" + {"character-bullet-style",character_bullet_style}, + {(char*)0}, +#line 213 "KEY1Token.gperf" + {"transformation",transformation}, +#line 224 "KEY1Token.gperf" + {"visibility",visibility}, +#line 186 "KEY1Token.gperf" + {"string",string}, + {(char*)0}, +#line 39 "KEY1Token.gperf" + {"buildChunkingStyle",buildChunkingStyle}, + {(char*)0}, {(char*)0}, +#line 184 "KEY1Token.gperf" + {"start-color",start_color}, + {(char*)0}, +#line 210 "KEY1Token.gperf" + {"top",top}, +#line 63 "KEY1Token.gperf" + {"drawables",drawables}, +#line 179 "KEY1Token.gperf" + {"slide-size",slide_size}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 113 "KEY1Token.gperf" + {"line-head-style",line_head_style}, +#line 157 "KEY1Token.gperf" + {"prototype-plugin",prototype_plugin}, + {(char*)0}, {(char*)0}, +#line 80 "KEY1Token.gperf" + {"font-underline",font_underline}, + {(char*)0}, +#line 97 "KEY1Token.gperf" + {"image-scale",image_scale}, + {(char*)0}, +#line 106 "KEY1Token.gperf" + {"labelPosition",labelPosition}, + {(char*)0}, +#line 96 "KEY1Token.gperf" + {"image-data",image_data}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 145 "KEY1Token.gperf" + {"path",path}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, +#line 34 "KEY1Token.gperf" + {"background-fill-style",background_fill_style}, +#line 158 "KEY1Token.gperf" + {"prototype-plugins",prototype_plugins}, + {(char*)0}, {(char*)0}, +#line 123 "KEY1Token.gperf" + {"master-slide-id",master_slide_id}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 178 "KEY1Token.gperf" + {"slide-list",slide_list}, +#line 121 "KEY1Token.gperf" + {"marker-type",marker_type}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, +#line 91 "KEY1Token.gperf" + {"http://developer.apple.com/schemas/APXL",NS_URI_KEY}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 98 "KEY1Token.gperf" + {"image-bullet-style",image_bullet_style}, +#line 30 "KEY1Token.gperf" + {"application-version",application_version}, + {(char*)0}, +#line 149 "KEY1Token.gperf" + {"plugin",plugin}, +#line 151 "KEY1Token.gperf" + {"point_at_top",point_at_top}, +#line 104 "KEY1Token.gperf" + {"key",key}, + {(char*)0}, {(char*)0}, +#line 29 "KEY1Token.gperf" + {"application-name",application_name}, + {(char*)0}, +#line 223 "KEY1Token.gperf" + {"vertical-alignment",vertical_alignment}, +#line 83 "KEY1Token.gperf" + {"gradient-angle",gradient_angle}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, +#line 144 "KEY1Token.gperf" + {"paragraph-tail-indent",paragraph_tail_indent}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, +#line 142 "KEY1Token.gperf" + {"paragraph-first-line-indent",paragraph_first_line_indent}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 72 "KEY1Token.gperf" + {"floating-content",floating_content}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 150 "KEY1Token.gperf" + {"plugin-data",plugin_data}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 36 "KEY1Token.gperf" + {"body",body}, + {(char*)0}, {(char*)0}, +#line 41 "KEY1Token.gperf" + {"bullet-characters",bullet_characters}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 143 "KEY1Token.gperf" + {"paragraph-head-indent",paragraph_head_indent}, + {(char*)0}, {(char*)0}, +#line 99 "KEY1Token.gperf" + {"inherited",inherited}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 125 "KEY1Token.gperf" + {"match-point",match_point}, + {(char*)0}, +#line 216 "KEY1Token.gperf" + {"ui-state",ui_state}, +#line 102 "KEY1Token.gperf" + {"is-filled",is_filled}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, +#line 115 "KEY1Token.gperf" + {"lineOpacity",lineOpacity}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, +#line 37 "KEY1Token.gperf" + {"bottom",bottom}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, +#line 140 "KEY1Token.gperf" + {"page-number",page_number}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 205 "KEY1Token.gperf" + {"time-stamp",time_stamp}, + {(char*)0}, +#line 203 "KEY1Token.gperf" + {"tickLabelsOpacity",tickLabelsOpacity}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 94 "KEY1Token.gperf" + {"id-ref",id_ref}, + {(char*)0}, {(char*)0}, +#line 141 "KEY1Token.gperf" + {"paragraph-alignment",paragraph_alignment}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 164 "KEY1Token.gperf" + {"scale-to-fit",scale_to_fit}, + {(char*)0}, +#line 101 "KEY1Token.gperf" + {"interSeriesGap",interSeriesGap}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 219 "KEY1Token.gperf" + {"userMaximum",userMaximum}, + {(char*)0}, {(char*)0}, +#line 217 "KEY1Token.gperf" + {"useUserMaximum",useUserMaximum}, +#line 108 "KEY1Token.gperf" + {"layerElementsForShadowing",layerElementsForShadowing}, + {(char*)0}, +#line 105 "KEY1Token.gperf" + {"labelOpacity",labelOpacity}, + {(char*)0}, {(char*)0}, +#line 48 "KEY1Token.gperf" + {"chart-prototype",chart_prototype}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, +#line 220 "KEY1Token.gperf" + {"userMinimum",userMinimum}, + {(char*)0}, {(char*)0}, +#line 218 "KEY1Token.gperf" + {"useUserMinimum",useUserMinimum}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 26 "KEY1Token.gperf" + {"altLineOpacity",altLineOpacity}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, +#line 85 "KEY1Token.gperf" + {"grow-horizontally",grow_horizontally}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 84 "KEY1Token.gperf" + {"gridOpacity",gridOpacity} + }; + + if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) + { + register int key = hash (str, len); + + if (key <= MAX_HASH_VALUE && key >= 0) + { + register const char *s = wordlist[key].name; + + if (s && *str == *s && !strncmp (str + 1, s + 1, len - 1) && s[len] == '\0') + return &wordlist[key]; + } + } + return 0; +} +#line 227 "KEY1Token.gperf" + diff --git a/Common/3dParty/apple/headers/KEY2Token.inc b/Common/3dParty/apple/headers/KEY2Token.inc new file mode 100644 index 00000000000..0b481cd6f95 --- /dev/null +++ b/Common/3dParty/apple/headers/KEY2Token.inc @@ -0,0 +1,300 @@ +/* C++ code produced by gperf version 3.0.1 */ +/* Command-line: gperf --compare-strncmp --enum --null-strings --readonly-tables --language C++ --output-file KEY2Token.inc KEY2Token.gperf */ +/* Computed positions: -k'1,4,$' */ + +#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ + && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \ + && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \ + && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \ + && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \ + && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \ + && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \ + && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \ + && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \ + && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \ + && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \ + && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \ + && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \ + && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \ + && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \ + && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \ + && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \ + && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \ + && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \ + && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \ + && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \ + && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \ + && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126)) +/* The character set is not based on ISO-646. */ +#error "gperf generated tables don't work with this execution character set. Please report a bug to ." +#endif + +#line 10 "KEY2Token.gperf" + +#if defined __GNUC__ +#pragma GCC diagnostic ignored "-Wmissing-field-initializers" +#endif + +using namespace KEY2Token; +#line 18 "KEY2Token.gperf" +struct Token +{ + const char *name; + int id; +}; +#include +/* maximum key range = 140, duplicates = 0 */ + +class Perfect_Hash +{ +private: + static inline unsigned int hash (const char *str, unsigned int len); +public: + static const struct Token *in_word_set (const char *str, unsigned int len); +}; + +inline unsigned int +Perfect_Hash::hash (register const char *str, register unsigned int len) +{ + static const unsigned char asso_values[] = + { + 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, + 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, + 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, + 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, + 141, 141, 141, 141, 141, 141, 141, 141, 5, 65, + 0, 141, 35, 0, 141, 5, 141, 0, 141, 141, + 141, 141, 141, 141, 141, 141, 0, 141, 141, 141, + 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, + 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, + 141, 141, 141, 141, 141, 141, 141, 0, 25, 0, + 15, 0, 55, 10, 10, 5, 141, 15, 20, 0, + 10, 25, 40, 141, 25, 25, 5, 0, 30, 5, + 141, 40, 141, 141, 141, 141, 141, 141, 141, 141, + 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, + 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, + 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, + 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, + 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, + 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, + 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, + 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, + 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, + 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, + 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, + 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, + 141, 141, 141, 141, 141, 141 + }; + register int hval = len; + + switch (hval) + { + default: + hval += asso_values[(unsigned char)str[3]]; + /*FALLTHROUGH*/ + case 3: + case 2: + case 1: + hval += asso_values[(unsigned char)str[0]]; + break; + } + return hval + asso_values[(unsigned char)str[len - 1]]; +} + +const struct Token * +Perfect_Hash::in_word_set (register const char *str, register unsigned int len) +{ + enum + { + TOTAL_KEYWORDS = 67, + MIN_WORD_LENGTH = 1, + MAX_WORD_LENGTH = 46, + MIN_HASH_VALUE = 1, + MAX_HASH_VALUE = 140 + }; + + static const struct Token wordlist[] = + { + {(char*)0}, +#line 49 "KEY2Token.gperf" + {"c",c}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, +#line 65 "KEY2Token.gperf" + {"metadata",metadata}, +#line 89 "KEY2Token.gperf" + {"type",type}, +#line 84 "KEY2Token.gperf" + {"theme",theme}, +#line 58 "KEY2Token.gperf" + {"i",i}, +#line 50 "KEY2Token.gperf" + {"comment",comment}, +#line 41 "KEY2Token.gperf" + {"animationType",animationType}, +#line 66 "KEY2Token.gperf" + {"name",name}, +#line 26 "KEY2Token.gperf" + {"2005112100",VERSION_STR_3}, + {(char*)0}, +#line 62 "KEY2Token.gperf" + {"master-slide",master_slide}, + {(char*)0}, +#line 83 "KEY2Token.gperf" + {"text",text}, +#line 85 "KEY2Token.gperf" + {"theme-list",theme_list}, +#line 28 "KEY2Token.gperf" + {"92008102400",VERSION_STR_5}, + {(char*)0}, +#line 36 "KEY2Token.gperf" + {"animationEndOffset",animationEndOffset}, + {(char*)0}, +#line 39 "KEY2Token.gperf" + {"animationStartOffset",animationStartOffset}, +#line 27 "KEY2Token.gperf" + {"72007061400",VERSION_STR_4}, +#line 35 "KEY2Token.gperf" + {"animationDuration",animationDuration}, +#line 40 "KEY2Token.gperf" + {"animationTimingReferent",animationTimingReferent}, +#line 73 "KEY2Token.gperf" + {"size",size}, +#line 86 "KEY2Token.gperf" + {"title",title}, + {(char*)0}, {(char*)0}, +#line 55 "KEY2Token.gperf" + {"headline",headline}, +#line 53 "KEY2Token.gperf" + {"direction",direction}, +#line 52 "KEY2Token.gperf" + {"depth",depth}, +#line 78 "KEY2Token.gperf" + {"sticky-note",sticky_note}, +#line 34 "KEY2Token.gperf" + {"animationDelayAutomaticWith",animationDelayAutomaticWith}, +#line 30 "KEY2Token.gperf" + {"animationAuto",animationAuto}, + {(char*)0}, +#line 67 "KEY2Token.gperf" + {"notes",notes}, +#line 54 "KEY2Token.gperf" + {"events",events}, +#line 42 "KEY2Token.gperf" + {"authors",authors}, +#line 63 "KEY2Token.gperf" + {"master-slides",master_slides}, +#line 70 "KEY2Token.gperf" + {"page",page}, +#line 74 "KEY2Token.gperf" + {"slide",slide}, +#line 80 "KEY2Token.gperf" + {"string",string}, +#line 56 "KEY2Token.gperf" + {"headlineParagraphStyle",headlineParagraphStyle}, +#line 37 "KEY2Token.gperf" + {"animationInterchunkAuto",animationInterchunkAuto}, + {(char*)0}, +#line 24 "KEY2Token.gperf" + {"2004102100",VERSION_STR_2}, +#line 77 "KEY2Token.gperf" + {"slide-style",slide_style}, +#line 33 "KEY2Token.gperf" + {"animationDelayAutmaticAfter",animationDelayAutomaticAfter}, +#line 61 "KEY2Token.gperf" + {"keywords",keywords}, +#line 32 "KEY2Token.gperf" + {"animationDelay",animationDelay}, +#line 75 "KEY2Token.gperf" + {"slide-list",slide_list}, + {(char*)0}, +#line 31 "KEY2Token.gperf" + {"animationAutoPlay",animationAutoPlay}, +#line 60 "KEY2Token.gperf" + {"key",key}, +#line 51 "KEY2Token.gperf" + {"decimal-number",number}, +#line 82 "KEY2Token.gperf" + {"stylesheet",stylesheet}, + {(char*)0}, +#line 79 "KEY2Token.gperf" + {"sticky-notes",sticky_notes}, +#line 29 "KEY2Token.gperf" + {"BGBuildDurationProperty",BGBuildDurationProperty}, +#line 38 "KEY2Token.gperf" + {"animationInterchunkDelay",animationInterchunkDelay}, +#line 45 "KEY2Token.gperf" + {"build",build}, +#line 68 "KEY2Token.gperf" + {"number",number}, +#line 87 "KEY2Token.gperf" + {"title-placeholder",title_placeholder}, +#line 69 "KEY2Token.gperf" + {"object-placeholder",object_placeholder}, + {(char*)0}, +#line 64 "KEY2Token.gperf" + {"master-ref",master_ref}, +#line 46 "KEY2Token.gperf" + {"build-chunk",build_chunk}, +#line 90 "KEY2Token.gperf" + {"version",version}, + {(char*)0}, {(char*)0}, +#line 25 "KEY2Token.gperf" + {"2005092101",COMPATIBLE_VERSION_STR_3,}, + {(char*)0}, +#line 48 "KEY2Token.gperf" + {"bullets",bullets}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 47 "KEY2Token.gperf" + {"build-chunks",build_chunks}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 72 "KEY2Token.gperf" + {"presentation",presentation}, + {(char*)0}, +#line 76 "KEY2Token.gperf" + {"slide-number-placeholder",slide_number_placeholder}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 59 "KEY2Token.gperf" + {"info-ref",info_ref}, + {(char*)0}, {(char*)0}, +#line 57 "KEY2Token.gperf" + {"http://developer.apple.com/namespaces/keynote2",NS_URI_KEY}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 88 "KEY2Token.gperf" + {"title-placeholder-ref",title_placeholder_ref}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 43 "KEY2Token.gperf" + {"body-placeholder",body_placeholder}, + {(char*)0}, {(char*)0}, +#line 81 "KEY2Token.gperf" + {"style-ref",style_ref}, + {(char*)0}, +#line 71 "KEY2Token.gperf" + {"parent-build-ref",parent_build_ref}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 44 "KEY2Token.gperf" + {"body-placeholder-ref",body_placeholder_ref} + }; + + if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) + { + register int key = hash (str, len); + + if (key <= MAX_HASH_VALUE && key >= 0) + { + register const char *s = wordlist[key].name; + + if (s && *str == *s && !strncmp (str + 1, s + 1, len - 1) && s[len] == '\0') + return &wordlist[key]; + } + } + return 0; +} +#line 91 "KEY2Token.gperf" + diff --git a/Common/3dParty/apple/headers/NUM1Token.inc b/Common/3dParty/apple/headers/NUM1Token.inc new file mode 100644 index 00000000000..88b256ad1ae --- /dev/null +++ b/Common/3dParty/apple/headers/NUM1Token.inc @@ -0,0 +1,151 @@ +/* C++ code produced by gperf version 3.0.1 */ +/* Command-line: gperf --compare-strncmp --enum --null-strings --readonly-tables --language C++ --output-file NUM1Token.inc NUM1Token.gperf */ +/* Computed positions: -k'$' */ + +#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ + && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \ + && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \ + && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \ + && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \ + && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \ + && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \ + && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \ + && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \ + && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \ + && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \ + && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \ + && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \ + && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \ + && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \ + && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \ + && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \ + && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \ + && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \ + && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \ + && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \ + && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \ + && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126)) +/* The character set is not based on ISO-646. */ +#error "gperf generated tables don't work with this execution character set. Please report a bug to ." +#endif + +#line 10 "NUM1Token.gperf" + +#if defined __GNUC__ +#pragma GCC diagnostic ignored "-Wmissing-field-initializers" +#endif + +using namespace NUM1Token; +#line 18 "NUM1Token.gperf" +struct Token +{ + const char *name; + int id; +}; +#include +/* maximum key range = 34, duplicates = 0 */ + +class Perfect_Hash +{ +private: + static inline unsigned int hash (const char *str, unsigned int len); +public: + static const struct Token *in_word_set (const char *str, unsigned int len); +}; + +inline unsigned int +Perfect_Hash::hash (register const char *str, register unsigned int len) +{ + static const unsigned char asso_values[] = + { + 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 41, 0, 41, + 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, + 41, 0, 41, 41, 41, 41, 41, 41, 41, 41, + 0, 10, 41, 41, 41, 0, 0, 41, 41, 41, + 41, 5, 41, 41, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 41 + }; + return len + asso_values[(unsigned char)str[len - 1]]; +} + +const struct Token * +Perfect_Hash::in_word_set (register const char *str, register unsigned int len) +{ + enum + { + TOTAL_KEYWORDS = 10, + MIN_WORD_LENGTH = 7, + MAX_WORD_LENGTH = 40, + MIN_HASH_VALUE = 7, + MAX_HASH_VALUE = 40 + }; + + static const struct Token wordlist[] = + { + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 29 "NUM1Token.gperf" + {"version",version}, +#line 25 "NUM1Token.gperf" + {"document",document}, +#line 30 "NUM1Token.gperf" + {"workspace",workspace}, +#line 28 "NUM1Token.gperf" + {"stylesheet",stylesheet}, +#line 24 "NUM1Token.gperf" + {"92008102400",VERSION_STR_2}, + {(char*)0}, {(char*)0}, +#line 32 "NUM1Token.gperf" + {"workspace-name",workspace_name}, +#line 33 "NUM1Token.gperf" + {"workspace-style",workspace_style}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 27 "NUM1Token.gperf" + {"page-info",page_info}, +#line 31 "NUM1Token.gperf" + {"workspace-array",workspace_array}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 26 "NUM1Token.gperf" + {"http://developer.apple.com/namespaces/ls",NS_URI_LS} + }; + + if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) + { + register int key = hash (str, len); + + if (key <= MAX_HASH_VALUE && key >= 0) + { + register const char *s = wordlist[key].name; + + if (s && *str == *s && !strncmp (str + 1, s + 1, len - 1) && s[len] == '\0') + return &wordlist[key]; + } + } + return 0; +} +#line 34 "NUM1Token.gperf" + diff --git a/Common/3dParty/apple/headers/PAG1Token.inc b/Common/3dParty/apple/headers/PAG1Token.inc new file mode 100644 index 00000000000..2e2712da682 --- /dev/null +++ b/Common/3dParty/apple/headers/PAG1Token.inc @@ -0,0 +1,209 @@ +/* C++ code produced by gperf version 3.0.1 */ +/* Command-line: gperf --compare-strncmp --enum --null-strings --readonly-tables --language C++ --output-file PAG1Token.inc PAG1Token.gperf */ +/* Computed positions: -k'1,6' */ + +#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ + && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \ + && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \ + && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \ + && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \ + && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \ + && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \ + && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \ + && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \ + && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \ + && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \ + && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \ + && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \ + && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \ + && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \ + && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \ + && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \ + && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \ + && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \ + && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \ + && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \ + && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \ + && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126)) +/* The character set is not based on ISO-646. */ +#error "gperf generated tables don't work with this execution character set. Please report a bug to ." +#endif + +#line 10 "PAG1Token.gperf" + +#if defined __GNUC__ +#pragma GCC diagnostic ignored "-Wmissing-field-initializers" +#endif + +using namespace PAG1Token; +#line 18 "PAG1Token.gperf" +struct Token +{ + const char *name; + int id; +}; +#include +/* maximum key range = 51, duplicates = 0 */ + +class Perfect_Hash +{ +private: + static inline unsigned int hash (const char *str, unsigned int len); +public: + static const struct Token *in_word_set (const char *str, unsigned int len); +}; + +inline unsigned int +Perfect_Hash::hash (register const char *str, register unsigned int len) +{ + static const unsigned char asso_values[] = + { + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 25, 55, 0, 55, 10, + 55, 55, 55, 55, 55, 55, 55, 10, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 5, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 5, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 5, 25, 15, + 20, 0, 20, 15, 5, 55, 55, 5, 10, 55, + 0, 15, 5, 55, 0, 0, 0, 55, 5, 10, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55 + }; + register int hval = len; + + switch (hval) + { + default: + hval += asso_values[(unsigned char)str[5]]; + /*FALLTHROUGH*/ + case 5: + case 4: + case 3: + case 2: + case 1: + hval += asso_values[(unsigned char)str[0]]; + break; + } + return hval; +} + +const struct Token * +Perfect_Hash::in_word_set (register const char *str, register unsigned int len) +{ + enum + { + TOTAL_KEYWORDS = 31, + MIN_WORD_LENGTH = 4, + MAX_WORD_LENGTH = 40, + MIN_HASH_VALUE = 4, + MAX_HASH_VALUE = 54 + }; + + static const struct Token wordlist[] = + { + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 38 "PAG1Token.gperf" + {"note",note}, +#line 49 "PAG1Token.gperf" + {"rpage",rpage}, +#line 39 "PAG1Token.gperf" + {"number",number}, + {(char*)0}, {(char*)0}, +#line 41 "PAG1Token.gperf" + {"page",page}, +#line 52 "PAG1Token.gperf" + {"stylesheet",stylesheet}, +#line 33 "PAG1Token.gperf" + {"header",header}, +#line 51 "PAG1Token.gperf" + {"slprint-info",slprint_info}, + {(char*)0}, +#line 47 "PAG1Token.gperf" + {"prototype",prototype}, +#line 44 "PAG1Token.gperf" + {"page-scale",page_scale}, +#line 37 "PAG1Token.gperf" + {"layout",layout}, + {(char*)0}, {(char*)0}, +#line 27 "PAG1Token.gperf" + {"cell",cell}, +#line 40 "PAG1Token.gperf" + {"order",order}, +#line 43 "PAG1Token.gperf" + {"page-height",page_height}, +#line 53 "PAG1Token.gperf" + {"textbox",textbox}, + {(char*)0}, +#line 28 "PAG1Token.gperf" + {"date",date}, +#line 45 "PAG1Token.gperf" + {"page-width",page_width}, +#line 31 "PAG1Token.gperf" + {"footer",footer}, +#line 54 "PAG1Token.gperf" + {"version",version}, +#line 29 "PAG1Token.gperf" + {"document",document}, +#line 26 "PAG1Token.gperf" + {"body",body}, +#line 42 "PAG1Token.gperf" + {"page-group",page_group}, +#line 24 "PAG1Token.gperf" + {"92008102400",VERSION_STR_4}, +#line 25 "PAG1Token.gperf" + {"SLCreationDateProperty",SLCreationDateProperty}, +#line 50 "PAG1Token.gperf" + {"section-prototypes",section_prototypes}, +#line 35 "PAG1Token.gperf" + {"kSFWPFootnoteGapProperty",kSFWPFootnoteGapProperty}, +#line 36 "PAG1Token.gperf" + {"kSFWPFootnoteKindProperty",kSFWPFootnoteKindProperty}, +#line 48 "PAG1Token.gperf" + {"publication-info",publication_info}, + {(char*)0}, {(char*)0}, {(char*)0}, +#line 46 "PAG1Token.gperf" + {"print-info",print_info}, + {(char*)0}, {(char*)0}, +#line 32 "PAG1Token.gperf" + {"footnote",footnote}, + {(char*)0}, +#line 34 "PAG1Token.gperf" + {"http://developer.apple.com/namespaces/sl",NS_URI_SL}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, + {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 30 "PAG1Token.gperf" + {"drawables",drawables} + }; + + if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) + { + register int key = hash (str, len); + + if (key <= MAX_HASH_VALUE && key >= 0) + { + register const char *s = wordlist[key].name; + + if (s && *str == *s && !strncmp (str + 1, s + 1, len - 1) && s[len] == '\0') + return &wordlist[key]; + } + } + return 0; +} +#line 55 "PAG1Token.gperf" + diff --git a/Common/3dParty/boost/boost.pri b/Common/3dParty/boost/boost.pri index e590f9c27d2..7a0278cea43 100644 --- a/Common/3dParty/boost/boost.pri +++ b/Common/3dParty/boost/boost.pri @@ -1,9 +1,20 @@ INCLUDEPATH += $$PWD/build/$$CORE_BUILDS_PLATFORM_PREFIX/include CORE_BOOST_LIBS = $$PWD/build/$$CORE_BUILDS_PLATFORM_PREFIX/lib +core_ios:CONFIG += disable_enum_constexpr_conversion +core_android:CONFIG += disable_enum_constexpr_conversion +core_mac:CONFIG += disable_enum_constexpr_conversion + core_android { INCLUDEPATH += $$PWD/build/android/include CORE_BOOST_LIBS = $$PWD/build/android/lib/$$CORE_BUILDS_PLATFORM_PREFIX + + DEFINES += "_HAS_AUTO_PTR_ETC=0" +} + +disable_enum_constexpr_conversion { + QMAKE_CFLAGS += -Wno-enum-constexpr-conversion + QMAKE_CXXFLAGS += -Wno-enum-constexpr-conversion } bundle_xcframeworks { diff --git a/Common/3dParty/boost/boost_android.sh b/Common/3dParty/boost/boost_android.sh deleted file mode 100755 index e5510d28113..00000000000 --- a/Common/3dParty/boost/boost_android.sh +++ /dev/null @@ -1,326 +0,0 @@ -#!/bin/bash - -cd boost_1_72_0 -OUTPUT_DIR="../build/android" - -BOOST_LIBS="filesystem system date_time regex" - -CPPSTD="-std=c++11 -frtti -fexceptions" - -# Must set these after parseArgs to fill in overriden values -# Todo: -g -DNDEBUG are for debug builds only... -# Boost.test defines are needed to build correct instrumentable boost_unit_test_framework static lib -# it does not affect the functionality of single-header usage. -# See http://www.boost.org/doc/libs/1_66_0/libs/test/doc/html/boost_test/adv_scenarios/static_lib_customizations/entry_point.html -EXTRA_FLAGS="-DBOOST_AC_USE_PTHREADS -DBOOST_SP_USE_PTHREADS \ - -DBOOST_TEST_NO_MAIN -DBOOST_TEST_ALTERNATIVE_INIT_API -DANDROID_STL=c++_static \ - -Wno-unused-local-typedef" -EXTRA_ANDROID_FLAGS="$EXTRA_FLAGS" - -if [[ -n "$USE_CXX11_ABI" ]]; then - EXTRA_LINUX_FLAGS="$EXTRA_FLAGS -D_GLIBCXX_USE_CXX11_ABI=$USE_CXX11_ABI" -else - EXTRA_LINUX_FLAGS="$EXTRA_FLAGS" -fi - -doneSection() -{ - echo - echo "Done" - echo "=================================================================" - echo -} - -bootstrapBoost() -{ - BOOTSTRAP_LIBS=$BOOST_LIBS - BOOST_LIBS_COMMA=$(echo $BOOTSTRAP_LIBS | sed -e "s/ /,/g") - echo "Bootstrapping for $1 (with libs $BOOST_LIBS_COMMA)" - ./bootstrap.sh --with-libraries=$BOOST_LIBS_COMMA - - doneSection -} - -generateAndroidUserConfig() -{ - HOSTOS="$(uname | awk '{ print $1}' | tr [:upper:] [:lower:])-" # darwin or linux - OSARCH="$(uname -m)" - - # Boost doesn't build with -Werror - # Reported to boost-users@lists.boost.org - - cat > "./tools/build/src/user-config.jam" <x86 android ---target=i686-none-linux-android ---gcc-toolchain=$ANDROID_NDK_ROOT/toolchains/x86-4.9/prebuilt/$HOSTOS$OSARCH ---sysroot=$ANDROID_NDK_ROOT/sysroot --isystem $ANDROID_NDK_ROOT/sources/cxx-stl/llvm-libc++/include --isystem $ANDROID_NDK_ROOT/sources/cxx-stl/llvm-libc++abi/include --isystem $ANDROID_NDK_ROOT/sources/android/support/include --isystem $ANDROID_NDK_ROOT/sysroot/usr/include --isystem $ANDROID_NDK_ROOT/sysroot/usr/include/i686-linux-android --DANDROID --D__ANDROID_API__=19 --ffunction-sections --funwind-tables --fstack-protector-strong --fno-limit-debug-info --fPIC --no-canonical-prefixes --mstackrealign --Wa,--noexecstack --Wformat --Werror=format-security --Wall --Wshadow -; -using clang : 5.0~x86_64 -: $ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/$HOSTOS$OSARCH/bin/clang++ $EXTRA_ANDROID_FLAGS -: -x86 android ---target=x86_64-none-linux-android ---gcc-toolchain=$ANDROID_NDK_ROOT/toolchains/x86_64-4.9/prebuilt/$HOSTOS$OSARCH ---sysroot=$ANDROID_NDK_ROOT/sysroot --isystem $ANDROID_NDK_ROOT/sources/cxx-stl/llvm-libc++/include --isystem $ANDROID_NDK_ROOT/sources/cxx-stl/llvm-libc++abi/include --isystem $ANDROID_NDK_ROOT/sources/android/support/include --isystem $ANDROID_NDK_ROOT/sysroot/usr/include --isystem $ANDROID_NDK_ROOT/sysroot/usr/include/x86_64-linux-android --DANDROID --D__ANDROID_API__=21 --ffunction-sections --funwind-tables --fstack-protector-strong --fno-limit-debug-info --fPIC --no-canonical-prefixes --mstackrealign --Wa,--noexecstack --Wformat --Werror=format-security --Wall --Wshadow -; -using clang : 5.0~arm -: $ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/$HOSTOS$OSARCH/bin/clang++ $EXTRA_ANDROID_FLAGS -: -arm android ---target=armv7-none-linux-androideabi ---gcc-toolchain=$ANDROID_NDK_ROOT/toolchains/arm-linux-androideabi-4.9/prebuilt/$HOSTOS$OSARCH ---sysroot=$ANDROID_NDK_ROOT/sysroot --isystem $ANDROID_NDK_ROOT/sources/cxx-stl/llvm-libc++/include --isystem $ANDROID_NDK_ROOT/sources/cxx-stl/llvm-libc++abi/include --isystem $ANDROID_NDK_ROOT/sources/android/support/include --isystem $ANDROID_NDK_ROOT/sysroot/usr/include --isystem $ANDROID_NDK_ROOT/sysroot/usr/include/arm-linux-androideabi --DANDROID --D__ANDROID_API__=19 --ffunction-sections --funwind-tables --fstack-protector-strong --fno-limit-debug-info --fPIC --fno-integrated-as --no-canonical-prefixes --Wa,--noexecstack --Wformat --Werror=format-security --Wall --Wshadow --march=armv7-a --mfloat-abi=softfp --mfpu=vfpv3-d16 --mthumb -; -using clang : 5.0~arm64 -: $ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/$HOSTOS$OSARCH/bin/clang++ $EXTRA_ANDROID_FLAGS -: -arm android ---target=aarch64-none-linux-android ---gcc-toolchain=$ANDROID_NDK_ROOT/toolchains/aarch64-linux-android-4.9/prebuilt/$HOSTOS$OSARCH ---sysroot=$ANDROID_NDK_ROOT/sysroot --isystem $ANDROID_NDK_ROOT/sources/cxx-stl/llvm-libc++/include --isystem $ANDROID_NDK_ROOT/sources/cxx-stl/llvm-libc++abi/include --isystem $ANDROID_NDK_ROOT/sources/android/support/include --isystem $ANDROID_NDK_ROOT/sysroot/usr/include --isystem $ANDROID_NDK_ROOT/sysroot/usr/include/aarch64-linux-android --DANDROID --D__ANDROID_API__=21 --ffunction-sections --funwind-tables --fstack-protector-strong --fno-limit-debug-info --fPIC --no-canonical-prefixes --Wa,--noexecstack --Wformat --Werror=format-security --Wall --Wshadow -; -EOF -} - -buildBoost_Android() -{ - mkdir -p $OUTPUT_DIR - echo > ${OUTPUT_DIR}/android-build.log - - if [[ -z "$ANDROID_NDK_ROOT" ]]; then - echo "Must specify ANDROID_NDK_ROOT" - exit 1 - fi - - export NO_BZIP2=1 - - # build libicu if locale requested but not provided - # if echo $LIBRARIES | grep locale; then - # if [ -e libiconv-libicu-android ]; then - # echo "ICONV and ICU already compiled" - # else - # echo "boost_locale selected - compiling ICONV and ICU" - # git clone https://github.com/pelya/libiconv-libicu-android.git - # cd libiconv-libicu-android - # ./build.sh || exit 1 - # cd .. - # fi - # fi - - echo clean - ./b2 --clean - - echo Building release x86 Boost for Android Emulator - - ./b2 --build-dir=android-build --stagedir=android-build/stage \ - --prefix="$OUTPUT_DIR" \ - --libdir="$OUTPUT_DIR/lib/x86" toolset=clang-5.0~x86 \ - architecture=x86 target-os=android define=_LITTLE_ENDIAN \ - optimization=speed \ - address-model=32 variant=release cxxflags="${CPPSTD}" \ - link=static threading=multi install >> "${OUTPUT_DIR}/android-build.log" 2>&1 - if [ $? != 0 ]; then echo "Error staging Android. Check ${OUTPUT_DIR}/android-build.log"; exit 1; fi - - doneSection - - echo Building release x86_64 Boost for Android Emulator - - ./b2 --build-dir=android-build --stagedir=android-build/stage \ - --prefix="$OUTPUT_DIR" \ - --libdir="$OUTPUT_DIR/lib/x86_64" toolset=clang-5.0~x86_64 \ - architecture=x86 target-os=android define=_LITTLE_ENDIAN \ - optimization=speed \ - address-model=64 variant=release cxxflags="${CPPSTD}" \ - link=static threading=multi install >> "${OUTPUT_DIR}/android-build.log" 2>&1 - if [ $? != 0 ]; then echo "Error staging Android. Check ${OUTPUT_DIR}/android-build.log"; exit 1; fi - - doneSection - - echo Building release armv7 Boost for Android - - ./b2 --build-dir=android-build --stagedir=android-build/stage \ - --prefix="$OUTPUT_DIR" \ - --libdir="$OUTPUT_DIR/lib/armeabi-v7a" toolset=clang-5.0~arm \ - abi=aapcs architecture=arm address-model=32 binary-format=elf threading=multi \ - optimization=space \ - target-os=android variant=release cxxflags="${CPPSTD}" \ - link=static install >> "${OUTPUT_DIR}/android-build.log" 2>&1 - if [ $? != 0 ]; then echo "Error installing Android. Check ${OUTPUT_DIR}/android-build.log"; exit 1; fi - - doneSection - - echo Building release arm64 Boost for Android - - ./b2 --build-dir=android-build --stagedir=android-build/stage \ - --prefix="$OUTPUT_DIR" \ - --libdir="$OUTPUT_DIR/lib/arm64-v8a" toolset=clang-5.0~arm64 \ - abi=aapcs architecture=arm address-model=64 binary-format=elf threading=multi \ - optimization=space \ - target-os=android variant=release cxxflags="${CPPSTD}" \ - link=static install >> "${OUTPUT_DIR}/android-build.log" 2>&1 - if [ $? != 0 ]; then echo "Error installing Android. Check ${OUTPUT_DIR}/android-build.log"; exit 1; fi - - doneSection -} - -buildBoost_Android_debug() -{ - mkdir -p $OUTPUT_DIR - echo > ${OUTPUT_DIR}/android-build.log - - export NO_BZIP2=1 - - # build libicu if locale requested but not provided - # if echo $LIBRARIES | grep locale; then - # if [ -e libiconv-libicu-android ]; then - # echo "ICONV and ICU already compiled" - # else - # echo "boost_locale selected - compiling ICONV and ICU" - # git clone https://github.com/pelya/libiconv-libicu-android.git - # cd libiconv-libicu-android - # ./build.sh || exit 1 - # cd .. - # fi - # fi - - echo Building debug x86 Boost for Android Emulator - - ./b2 $THREADS --build-dir=android-build --stagedir=android-build/stage \ - --prefix="$OUTPUT_DIR" \ - --libdir="$OUTPUT_DIR/lib/debug/x86" toolset=clang-5.0~x86 \ - architecture=x86 target-os=android define=_LITTLE_ENDIAN \ - optimization=speed \ - address-model=32 variant=debug cxxflags="${CPPSTD}" \ - link=static threading=multi install >> "${OUTPUT_DIR}/android-build.log" 2>&1 - if [ $? != 0 ]; then echo "Error staging Android. Check ${OUTPUT_DIR}/android-build.log"; exit 1; fi - - doneSection - - echo Building debug x86_64 Boost for Android Emulator - - ./b2 $THREADS --build-dir=android-build --stagedir=android-build/stage \ - --prefix="$OUTPUT_DIR" \ - --libdir="$OUTPUT_DIR/lib/debug/x86_64" toolset=clang-5.0~x86_64 \ - architecture=x86 target-os=android define=_LITTLE_ENDIAN \ - optimization=speed \ - address-model=64 variant=debug cxxflags="${CPPSTD}" \ - link=static threading=multi install >> "${OUTPUT_DIR}/android-build.log" 2>&1 - if [ $? != 0 ]; then echo "Error staging Android. Check ${OUTPUT_DIR}/android-build.log"; exit 1; fi - - doneSection - - echo Building debug armv7 Boost for Android - - ./b2 $THREADS --build-dir=android-build --stagedir=android-build/stage \ - --prefix="$OUTPUT_DIR" \ - --libdir="$OUTPUT_DIR/lib/debug/armeabi-v7a" toolset=clang-5.0~arm \ - abi=aapcs architecture=arm address-model=32 binary-format=elf threading=multi \ - optimization=space \ - target-os=android variant=debug cxxflags="${CPPSTD}" \ - link=static install >> "${OUTPUT_DIR}/android-build.log" 2>&1 - if [ $? != 0 ]; then echo "Error installing Android. Check ${OUTPUT_DIR}/android-build.log"; exit 1; fi - - doneSection - - echo Building debug arm64 Boost for Android - - ./b2 $THREADS --build-dir=android-build --stagedir=android-build/stage \ - --prefix="$OUTPUT_DIR" \ - --libdir="$OUTPUT_DIR/lib/debug/arm64-v8a" toolset=clang-5.0~arm64 \ - abi=aapcs architecture=arm address-model=64 binary-format=elf threading=multi \ - optimization=space \ - target-os=android variant=debug cxxflags="${CPPSTD}" \ - link=static install >> "${OUTPUT_DIR}/android-build.log" 2>&1 - if [ $? != 0 ]; then echo "Error installing Android. Check ${OUTPUT_DIR}/android-build.log"; exit 1; fi - - doneSection -} - -bootstrapBoost -generateAndroidUserConfig -buildBoost_Android -#buildBoost_Android_debug - -echo "Completed successfully" diff --git a/Common/3dParty/boost/boost_ios.sh b/Common/3dParty/boost/boost_ios.sh index 6114f9f579e..4e3112fc470 100755 --- a/Common/3dParty/boost/boost_ios.sh +++ b/Common/3dParty/boost/boost_ios.sh @@ -27,7 +27,7 @@ CLEAN= BOOST_VERSION=1.72.0 BOOST_VERSION2=1_72_0 MIN_IOS_VERSION=8.0 -IOS_SDK_VERSION=`xcodebuild BITCODE_GENERATION_MODE="bitcode" ENABLE_BITCODE="YES" OTHER_CFLAGS="-fembed-bitcode" -showsdks | grep iphoneos | \ +IOS_SDK_VERSION=`xcodebuild BITCODE_GENERATION_MODE="bitcode" ENABLE_BITCODE="NO" -showsdks | grep iphoneos | \ egrep "[[:digit:]]+\.[[:digit:]]+" -o | tail -1` OSX_SDK_VERSION=`xcodebuild BITCODE_GENERATION_MODE="bitcode" ENABLE_BITCODE="YES" OTHER_CFLAGS="-fembed-bitcode" -showsdks | grep macosx | \ egrep "[[:digit:]]+\.[[:digit:]]+" -o | tail -1` @@ -42,7 +42,7 @@ XCODE_ROOT=`xcode-select -print-path` # # Should perhaps also consider/use instead: -BOOST_SP_USE_PTHREADS EXTRA_CPPFLAGS="-DBOOST_AC_USE_PTHREADS -DBOOST_SP_USE_PTHREADS -g -DNDEBUG \ - -std=c++11 -stdlib=libc++ -fvisibility=hidden -fvisibility-inlines-hidden -fembed-bitcode" + -std=c++11 -stdlib=libc++ -fvisibility=hidden -fvisibility-inlines-hidden" EXTRA_IOS_CPPFLAGS="$EXTRA_CPPFLAGS -mios-version-min=$MIN_IOS_VERSION" EXTRA_OSX_CPPFLAGS="$EXTRA_CPPFLAGS" @@ -259,20 +259,17 @@ buildBoost() echo Building Boost for iPhone # Install this one so we can copy the headers for the frameworks... ./b2 -j16 --build-dir=iphone-build --stagedir=iphone-build/stage \ - cxxflags="-fembed-bitcode" \ --prefix=$PREFIXDIR toolset=darwin architecture=arm target-os=iphone \ macosx-version=iphone-${IOS_SDK_VERSION} define=_LITTLE_ENDIAN \ link=static stage ./b2 -j16 --build-dir=iphone-build --stagedir=iphone-build/stage \ --prefix=$PREFIXDIR toolset=darwin architecture=arm \ - cxxflags="-fembed-bitcode" \ target-os=iphone macosx-version=iphone-${IOS_SDK_VERSION} \ define=_LITTLE_ENDIAN link=static install doneSection echo Building Boost for iPhoneSimulator ./b2 -j16 --build-dir=iphonesim-build --stagedir=iphonesim-build/stage \ - cxxflags="-fembed-bitcode" \ toolset=darwin-${IOS_SDK_VERSION}~iphonesim architecture=x86 \ target-os=iphone macosx-version=iphonesim-${IOS_SDK_VERSION} \ link=static stage diff --git a/Common/3dParty/curl/build-android-common.sh b/Common/3dParty/curl/build-android-common.sh deleted file mode 100755 index d1b069c0473..00000000000 --- a/Common/3dParty/curl/build-android-common.sh +++ /dev/null @@ -1,220 +0,0 @@ -#!/bin/bash -# -# Copyright 2016 leenjewel -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -source ./build-common.sh - -export PLATFORM_TYPE="Android" -export ARCHS=("arm" "arm64" "x86" "x86_64") -export ABIS=("armeabi-v7a" "arm64-v8a" "x86" "x86_64") -export ABI_TRIPLES=("arm-linux-androideabi" "aarch64-linux-android" "i686-linux-android" "x86_64-linux-android") -export ANDROID_API=21 - -# for test -# export ARCHS=("x86_64") -# export ABIS=("x86_64") -# export ABI_TRIPLES=("x86_64-linux-android") - -if [[ -z ${ANDROID_NDK_ROOT} ]]; then - echo "ANDROID_NDK_ROOT not defined" - exit 1 -fi - -function get_toolchain() { - HOST_OS=$(uname -s) - case ${HOST_OS} in - Darwin) HOST_OS=darwin ;; - Linux) HOST_OS=linux ;; - FreeBsd) HOST_OS=freebsd ;; - CYGWIN* | *_NT-*) HOST_OS=cygwin ;; - esac - - HOST_ARCH=$(uname -m) - case ${HOST_ARCH} in - i?86) HOST_ARCH=x86 ;; - x86_64 | amd64) HOST_ARCH=x86_64 ;; - esac - - echo "${HOST_OS}-${HOST_ARCH}" -} - -function get_android_arch() { - local common_arch=$1 - case ${common_arch} in - arm) - echo "arm-v7a" - ;; - arm64) - echo "arm64-v8a" - ;; - x86) - echo "x86" - ;; - x86_64) - echo "x86-64" - ;; - esac -} - -function get_target_build() { - local arch=$1 - case ${arch} in - arm-v7a) - echo "arm" - ;; - arm64-v8a) - echo "arm64" - ;; - x86) - echo "x86" - ;; - x86-64) - echo "x86_64" - ;; - esac -} - -function get_build_host_internal() { - local arch=$1 - case ${arch} in - arm-v7a | arm-v7a-neon) - echo "arm-linux-androideabi" - ;; - arm64-v8a) - echo "aarch64-linux-android" - ;; - x86) - echo "i686-linux-android" - ;; - x86-64) - echo "x86_64-linux-android" - ;; - esac -} - -function android_get_build_host() { - local arch=$(get_android_arch $1) - get_build_host_internal $arch -} - -function get_clang_target_host() { - local arch=$1 - local api=$2 - case ${arch} in - arm-v7a | arm-v7a-neon) - echo "armv7a-linux-androideabi${api}" - ;; - arm64-v8a) - echo "aarch64-linux-android${api}" - ;; - x86) - echo "i686-linux-android${api}" - ;; - x86-64) - echo "x86_64-linux-android${api}" - ;; - esac -} - -function set_android_toolchain_bin() { - export PATH=${ANDROID_NDK_ROOT}/toolchains/llvm/prebuilt/$(get_toolchain)/bin:$PATH - echo PATH=$PATH -} - -function set_android_toolchain() { - local name=$1 - local arch=$(get_android_arch $2) - local api=$3 - local build_host=$(get_build_host_internal "$arch") - local clang_target_host=$(get_clang_target_host "$arch" "$api") - - export AR=${build_host}-ar - export CC=${clang_target_host}-clang - export CXX=${clang_target_host}-clang++ - export AS=${build_host}-as - export LD=${build_host}-ld - export RANLIB=${build_host}-ranlib - export STRIP=${build_host}-strip -} - -function get_common_includes() { - local toolchain=$(get_toolchain) - echo "-I${ANDROID_NDK_ROOT}/toolchains/llvm/prebuilt/${toolchain}/sysroot/usr/include -I${ANDROID_NDK_ROOT}/toolchains/llvm/prebuilt/${toolchain}/sysroot/usr/local/include" -} -function get_common_linked_libraries() { - local api=$1 - local arch=$2 - local toolchain=$(get_toolchain) - local build_host=$(get_build_host_internal "$arch") - echo "-L${ANDROID_NDK_ROOT}/toolchains/llvm/prebuilt/${toolchain}/${build_host}/lib -L${ANDROID_NDK_ROOT}/toolchains/llvm/prebuilt/${toolchain}/sysroot/usr/lib/${build_host}/${api} -L${ANDROID_NDK_ROOT}/toolchains/llvm/prebuilt/${toolchain}/lib" -} - -function set_android_cpu_feature() { - local name=$1 - local arch=$(get_android_arch $2) - local api=$3 - case ${arch} in - arm-v7a | arm-v7a-neon) - export CFLAGS="-march=armv7-a -mfpu=vfpv3-d16 -mfloat-abi=softfp -Wno-unused-function -fno-integrated-as -fstrict-aliasing -fPIC -DANDROID -D__ANDROID_API__=${api} -Os -ffunction-sections -fdata-sections $(get_common_includes)" - export CXXFLAGS="-std=c++11 -Os -ffunction-sections -fdata-sections" - export LDFLAGS="-march=armv7-a -mfpu=vfpv3-d16 -mfloat-abi=softfp -Wl,--fix-cortex-a8 -Wl,--gc-sections -Os -ffunction-sections -fdata-sections $(get_common_linked_libraries ${api} ${arch})" - export CPPFLAGS=${CFLAGS} - ;; - arm64-v8a) - export CFLAGS="-march=armv8-a -Wno-unused-function -fno-integrated-as -fstrict-aliasing -fPIC -DANDROID -D__ANDROID_API__=${api} -Os -ffunction-sections -fdata-sections $(get_common_includes)" - export CXXFLAGS="-std=c++11 -Os -ffunction-sections -fdata-sections" - export LDFLAGS="-march=armv8-a -Wl,--gc-sections -Os -ffunction-sections -fdata-sections $(get_common_linked_libraries ${api} ${arch})" - export CPPFLAGS=${CFLAGS} - ;; - x86) - export CFLAGS="-march=i686 -mtune=intel -mssse3 -mfpmath=sse -m32 -Wno-unused-function -fno-integrated-as -fstrict-aliasing -fPIC -DANDROID -D__ANDROID_API__=${api} -Os -ffunction-sections -fdata-sections $(get_common_includes)" - export CXXFLAGS="-std=c++11 -Os -ffunction-sections -fdata-sections" - export LDFLAGS="-march=i686 -Wl,--gc-sections -Os -ffunction-sections -fdata-sections $(get_common_linked_libraries ${api} ${arch})" - export CPPFLAGS=${CFLAGS} - ;; - x86-64) - export CFLAGS="-march=x86-64 -msse4.2 -mpopcnt -m64 -mtune=intel -Wno-unused-function -fno-integrated-as -fstrict-aliasing -fPIC -DANDROID -D__ANDROID_API__=${api} -Os -ffunction-sections -fdata-sections $(get_common_includes)" - export CXXFLAGS="-std=c++11 -Os -ffunction-sections -fdata-sections" - export LDFLAGS="-march=x86-64 -Wl,--gc-sections -Os -ffunction-sections -fdata-sections $(get_common_linked_libraries ${api} ${arch})" - export CPPFLAGS=${CFLAGS} - ;; - esac -} - -function android_printf_global_params() { - local arch=$1 - local abi=$2 - local abi_triple=$3 - local in_dir=$4 - local out_dir=$5 - echo -e "arch = $arch" - echo -e "abi = $abi" - echo -e "abi_triple = $abi_triple" - echo -e "PLATFORM_TYPE = $PLATFORM_TYPE" - echo -e "ANDROID_API = $ANDROID_API" - echo -e "in_dir = $in_dir" - echo -e "out_dir = $out_dir" - echo -e "AR = $AR" - echo -e "CC = $CC" - echo -e "CXX = $CXX" - echo -e "AS = $AS" - echo -e "LD = $LD" - echo -e "RANLIB = $RANLIB" - echo -e "STRIP = $STRIP" - echo -e "CFLAGS = $CFLAGS" - echo -e "CXXFLAGS = $CXXFLAGS" - echo -e "LDFLAGS = $LDFLAGS" - echo -e "CPPFLAGS = $CPPFLAGS" -} diff --git a/Common/3dParty/curl/build-android-curl.sh b/Common/3dParty/curl/build-android-curl.sh deleted file mode 100755 index 697e8845b9c..00000000000 --- a/Common/3dParty/curl/build-android-curl.sh +++ /dev/null @@ -1,128 +0,0 @@ -#!/bin/bash -# -# Copyright 2016 leenjewel -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# # read -n1 -p "Press any key to continue..." - -set -u - -source ./build-android-common.sh - -init_log_color - -TOOLS_ROOT=$(pwd) - -SOURCE="$0" -while [ -h "$SOURCE" ]; do - DIR="$(cd -P "$(dirname "$SOURCE")" && pwd)" - SOURCE="$(readlink "$SOURCE")" - [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" -done -pwd_path="$(cd -P "$(dirname "$SOURCE")" && pwd)" - -echo pwd_path=${pwd_path} -echo TOOLS_ROOT=${TOOLS_ROOT} - -LIB_VERSION="curl-7_68_0" -LIB_NAME="curl-7.68.0" -LIB_DEST_DIR="${pwd_path}/build/android/curl-universal" - -echo "https://github.com/curl/curl/releases/download/${LIB_VERSION}/${LIB_NAME}.tar.gz" - -# https://curl.haxx.se/download/${LIB_NAME}.tar.gz -# https://github.com/curl/curl/releases/download/curl-7_69_0/curl-7.69.0.tar.gz -# https://github.com/curl/curl/releases/download/curl-7_68_0/curl-7.68.0.tar.gz -rm -rf "${LIB_DEST_DIR}" "${LIB_NAME}" -[ -f "${LIB_NAME}.tar.gz" ] || curl -L -o ${LIB_NAME}.tar.gz https://github.com/curl/curl/releases/download/${LIB_VERSION}/${LIB_NAME}.tar.gz -s -[ -f "${LIB_NAME}.tar.gz" ] || log_error "curl download error!" - -set_android_toolchain_bin - -function configure_make() { - - ARCH=$1 - ABI=$2 - ABI_TRIPLE=$3 - - log_info "configure $ABI start..." - - if [ -d "${LIB_NAME}" ]; then - rm -fr "${LIB_NAME}" - fi - tar xfz "${LIB_NAME}.tar.gz" - pushd . - cd "${LIB_NAME}" - - PREFIX_DIR="${pwd_path}/build/android/${ABI}" - if [ -d "${PREFIX_DIR}" ]; then - rm -fr "${PREFIX_DIR}" - fi - mkdir -p "${PREFIX_DIR}" - - OUTPUT_ROOT=${TOOLS_ROOT}/build/android/${ABI} - mkdir -p ${OUTPUT_ROOT}/log - - set_android_toolchain "curl" "${ARCH}" "${ANDROID_API}" - set_android_cpu_feature "curl" "${ARCH}" "${ANDROID_API}" - - export ANDROID_NDK_HOME=${ANDROID_NDK_ROOT} - echo ANDROID_NDK_HOME=${ANDROID_NDK_HOME} - - OPENSSL_OUT_DIR="${pwd_path}/../openssl/build/android/${ABI}" - - export LDFLAGS="${LDFLAGS} -L${OPENSSL_OUT_DIR}/lib" - # export LDFLAGS="-Wl,-rpath-link,-L${OPENSSL_OUT_DIR}/lib $LDFLAGS " - - android_printf_global_params "$ARCH" "$ABI" "$ABI_TRIPLE" "$PREFIX_DIR" "$OUTPUT_ROOT" - - if [[ "${ARCH}" == "x86_64" ]]; then - - ./configure --host=$(android_get_build_host "${ARCH}") --prefix="${PREFIX_DIR}" --enable-ipv6 --with-ssl=${OPENSSL_OUT_DIR} --enable-static --disable-shared >"${OUTPUT_ROOT}/log/${ABI}.log" 2>&1 - - elif [[ "${ARCH}" == "x86" ]]; then - - ./configure --host=$(android_get_build_host "${ARCH}") --prefix="${PREFIX_DIR}" --enable-ipv6 --with-ssl=${OPENSSL_OUT_DIR} --enable-static --disable-shared >"${OUTPUT_ROOT}/log/${ABI}.log" 2>&1 - - elif [[ "${ARCH}" == "arm" ]]; then - - ./configure --host=$(android_get_build_host "${ARCH}") --prefix="${PREFIX_DIR}" --enable-ipv6 --with-ssl=${OPENSSL_OUT_DIR} --enable-static --disable-shared >"${OUTPUT_ROOT}/log/${ABI}.log" 2>&1 - - elif [[ "${ARCH}" == "arm64" ]]; then - - ./configure --host=$(android_get_build_host "${ARCH}") --prefix="${PREFIX_DIR}" --enable-ipv6 --with-ssl=${OPENSSL_OUT_DIR} --enable-static --disable-shared >"${OUTPUT_ROOT}/log/${ABI}.log" 2>&1 - - else - log_error "not support" && exit 1 - fi - - log_info "make $ABI start..." - - make clean >>"${OUTPUT_ROOT}/log/${ABI}.log" - if make -j$(get_cpu_count) >>"${OUTPUT_ROOT}/log/${ABI}.log" 2>&1; then - make install >>"${OUTPUT_ROOT}/log/${ABI}.log" 2>&1 - fi - - popd -} - -log_info "${PLATFORM_TYPE} ${LIB_NAME} start..." - -for ((i = 0; i < ${#ARCHS[@]}; i++)); do - if [[ $# -eq 0 || "$1" == "${ARCHS[i]}" ]]; then - configure_make "${ARCHS[i]}" "${ABIS[i]}" "${ABI_TRIPLES[i]}" - fi -done - -log_info "${PLATFORM_TYPE} ${LIB_NAME} end..." diff --git a/Common/3dParty/curl/build-ios-common.sh b/Common/3dParty/curl/build-ios-common.sh index a8ee26de586..f84cdf37533 100755 --- a/Common/3dParty/curl/build-ios-common.sh +++ b/Common/3dParty/curl/build-ios-common.sh @@ -78,24 +78,24 @@ function set_ios_cpu_feature() { armv7) export CC="xcrun -sdk iphoneos clang -arch armv7" export CXX="xcrun -sdk iphoneos clang++ -arch armv7" - export CFLAGS="-arch armv7 -target armv7-ios-darwin -march=armv7 -mcpu=cortex-a8 -mfpu=neon -mfloat-abi=softfp -Wno-unused-function -fstrict-aliasing -Oz -Wno-ignored-optimization-argument -DIOS -isysroot ${sysroot} -fembed-bitcode -miphoneos-version-min=${ios_min_target} -I${sysroot}/usr/include" - export LDFLAGS="-arch armv7 -target armv7-ios-darwin -march=armv7 -isysroot ${sysroot} -fembed-bitcode -L${sysroot}/usr/lib " - export CXXFLAGS="-std=c++11 -arch armv7 -target armv7-ios-darwin -march=armv7 -mcpu=cortex-a8 -mfpu=neon -mfloat-abi=softfp -fstrict-aliasing -fembed-bitcode -DIOS -miphoneos-version-min=${ios_min_target} -I${sysroot}/usr/include" + export CFLAGS="-arch armv7 -target armv7-ios-darwin -march=armv7 -mcpu=cortex-a8 -mfpu=neon -mfloat-abi=softfp -Wno-unused-function -fstrict-aliasing -Oz -Wno-ignored-optimization-argument -DIOS -isysroot ${sysroot} -miphoneos-version-min=${ios_min_target} -I${sysroot}/usr/include" + export LDFLAGS="-arch armv7 -target armv7-ios-darwin -march=armv7 -isysroot ${sysroot} -L${sysroot}/usr/lib " + export CXXFLAGS="-std=c++11 -arch armv7 -target armv7-ios-darwin -march=armv7 -mcpu=cortex-a8 -mfpu=neon -mfloat-abi=softfp -fstrict-aliasing -DIOS -miphoneos-version-min=${ios_min_target} -I${sysroot}/usr/include" ;; arm64) export CC="xcrun -sdk iphoneos clang -arch arm64" export CXX="xcrun -sdk iphoneos clang++ -arch arm64" - export CFLAGS="-arch arm64 -target aarch64-ios-darwin -march=armv8 -mcpu=generic -Wno-unused-function -fstrict-aliasing -Oz -Wno-ignored-optimization-argument -DIOS -isysroot ${sysroot} -fembed-bitcode -miphoneos-version-min=${ios_min_target} -I${sysroot}/usr/include" - export LDFLAGS="-arch arm64 -target aarch64-ios-darwin -march=armv8 -isysroot ${sysroot} -fembed-bitcode -L${sysroot}/usr/lib " - export CXXFLAGS="-std=c++11 -arch arm64 -target aarch64-ios-darwin -march=armv8 -mcpu=generic -fstrict-aliasing -fembed-bitcode -DIOS -miphoneos-version-min=${ios_min_target} -I${sysroot}/usr/include" + export CFLAGS="-arch arm64 -target aarch64-ios-darwin -march=armv8 -mcpu=generic -Wno-unused-function -fstrict-aliasing -Oz -Wno-ignored-optimization-argument -DIOS -isysroot ${sysroot} -miphoneos-version-min=${ios_min_target} -I${sysroot}/usr/include" + export LDFLAGS="-arch arm64 -target aarch64-ios-darwin -march=armv8 -isysroot ${sysroot} -L${sysroot}/usr/lib " + export CXXFLAGS="-std=c++11 -arch arm64 -target aarch64-ios-darwin -march=armv8 -mcpu=generic -fstrict-aliasing -DIOS -miphoneos-version-min=${ios_min_target} -I${sysroot}/usr/include" ;; arm64e) # -march=armv8.3 ??? export CC="xcrun -sdk iphoneos clang -arch arm64e" export CXX="xcrun -sdk iphoneos clang++ -arch arm64e" - export CFLAGS="-arch arm64e -target aarch64-ios-darwin -Wno-unused-function -fstrict-aliasing -DIOS -isysroot ${sysroot} -fembed-bitcode -miphoneos-version-min=${ios_min_target} -I${sysroot}/usr/include" - export LDFLAGS="-arch arm64e -target aarch64-ios-darwin -isysroot ${sysroot} -fembed-bitcode -L${sysroot}/usr/lib " - export CXXFLAGS="-std=c++11 -arch arm64e -target aarch64-ios-darwin -fstrict-aliasing -fembed-bitcode -DIOS -miphoneos-version-min=${ios_min_target} -I${sysroot}/usr/include" + export CFLAGS="-arch arm64e -target aarch64-ios-darwin -Wno-unused-function -fstrict-aliasing -DIOS -isysroot ${sysroot} -miphoneos-version-min=${ios_min_target} -I${sysroot}/usr/include" + export LDFLAGS="-arch arm64e -target aarch64-ios-darwin -isysroot ${sysroot} -L${sysroot}/usr/lib " + export CXXFLAGS="-std=c++11 -arch arm64e -target aarch64-ios-darwin -fstrict-aliasing -DIOS -miphoneos-version-min=${ios_min_target} -I${sysroot}/usr/include" ;; i386) export CC="xcrun -sdk iphonesimulator clang -arch i386" diff --git a/Common/3dParty/curl/curl.pri b/Common/3dParty/curl/curl.pri index d1178d404ef..6d24ea212d6 100644 --- a/Common/3dParty/curl/curl.pri +++ b/Common/3dParty/curl/curl.pri @@ -1,18 +1,10 @@ core_android { - - ABI_PATH = $$replace(CORE_BUILDS_PLATFORM_PREFIX, "android_", "") - contains(ABI_PATH, "armv7" ) { - ABI_PATH = $$replace(ABI_PATH, "armv7", "armeabi-v7a") - } - contains(ABI_PATH, "arm64_v8a" ) { - ABI_PATH = $$replace(ABI_PATH, "arm64_v8a", "arm64-v8a") - } INCLUDEPATH += \ - $$PWD/build/android/$$ABI_PATH/include \ - $$PWD/../openssl/build/android/$$ABI_PATH/include \ + $$PWD/build/android/include \ + $$PWD/../openssl/build/android/$$CORE_BUILDS_PLATFORM_PREFIX_DST/include LIBS += \ - $$PWD/build/android/$$ABI_PATH/lib/libcurl.a \ - $$PWD/../openssl/build/android/$$ABI_PATH/lib/libssl.a \ - $$PWD/../openssl/build/android/$$ABI_PATH/lib/libcrypto.a \ + $$PWD/build/android/$$CORE_BUILDS_PLATFORM_PREFIX_DST/libcurl.a \ + $$PWD/../openssl/build/android/$$CORE_BUILDS_PLATFORM_PREFIX_DST/lib/libssl.a \ + $$PWD/../openssl/build/android/$$CORE_BUILDS_PLATFORM_PREFIX_DST/lib/libcrypto.a \ } diff --git a/Common/3dParty/harfbuzz/.gitignore b/Common/3dParty/harfbuzz/.gitignore index 61c4c49726a..6096c5eddf1 100644 --- a/Common/3dParty/harfbuzz/.gitignore +++ b/Common/3dParty/harfbuzz/.gitignore @@ -1,2 +1,3 @@ harfbuzz/ harfbuzz.pri +module.version diff --git a/Common/3dParty/harfbuzz/make.py b/Common/3dParty/harfbuzz/make.py index 5d3667686d6..fbee78e985b 100755 --- a/Common/3dParty/harfbuzz/make.py +++ b/Common/3dParty/harfbuzz/make.py @@ -5,24 +5,54 @@ sys.path.append("../../../../build_tools/scripts") import base +def apply_patch(file, patch): + file_content = base.readFile(file) + patch_content = base.readFile(patch) + index1 = patch_content.find("<<<<<<<") + index2 = patch_content.find("=======") + index3 = patch_content.find(">>>>>>>") + file_content_old = patch_content[index1 + 7:index2] + file_content_new = "\n#if 0" + file_content_old + "#else" + patch_content[index2 + 7:index3] + "#endif\n" + base.replaceInFile(file, file_content_old, file_content_new) + return + +def read_files(folder, addon=""): + ret_data = os.listdir(folder) + for i in range(len(ret_data)): + ret_data[i] = addon + ret_data[i] + return ret_data + +def clear_module(): + if base.is_dir("harfbuzz"): + base.delete_dir_with_access_error("harfbuzz") + return + +base.check_module_version("1", clear_module) + # fetch harfbuzz if not base.is_dir("harfbuzz"): base.cmd("git", ["clone", "https://github.com/harfbuzz/harfbuzz.git"]) os.chdir("harfbuzz") - base.cmd("git", ["checkout", "8d1b000a3edc90c12267b836b4ef3f81c0e53edc"]) + base.cmd("git", ["checkout", "894a1f72ee93a1fd8dc1d9218cb3fd8f048be29a"]) os.chdir("../") + apply_patch("./harfbuzz/src/hb-ft.cc", "./patch/hb-ft.cc.patch") + qmake_content_lines = [] qmake_content_lines.append("SRC_DIR = $$PWD/harfbuzz/src") qmake_content_lines.append("") - qmake_content_lines.append("DEFINES += HAVE_FREETYPE") + qmake_content_lines.append("DEFINES += \\") + qmake_content_lines.append(" HAVE_FREETYPE \\") + qmake_content_lines.append(" HB_NO_VISIBILITY") qmake_content_lines.append("") qmake_content_lines.append("INCLUDEPATH += \\") qmake_content_lines.append(" $$SRC_DIR \\") qmake_content_lines.append("") - all_files = os.listdir("./harfbuzz/src") + all_files = read_files("./harfbuzz/src") + all_files += read_files("./harfbuzz/src/graph", "graph/") + headers_files = [] sources_files = [] @@ -32,14 +62,21 @@ sources_exclude.append("main.cc") sources_exclude.append("failing-alloc.c") + sources_exclude_filter = [] + sources_exclude_filter.append("test") + sources_exclude_filter.append("harfbuzz") + for item in all_files: arr_split = os.path.splitext(item) if len(arr_split) == 0: continue ext = arr_split[-1] if (ext == ".h") or (ext == ".hh") or (ext == ".c") or (ext == ".cc"): - if (0 == os.path.basename(item).find("test")): - sources_exclude.append(item) + test_file_name = os.path.basename(item) + for extest in sources_exclude_filter: + if (0 == test_file_name.find(extest)): + sources_exclude.append(item) + break for item in all_files: arr_split = os.path.splitext(item) @@ -90,5 +127,5 @@ with open("./harfbuzz.pri", "w") as file: file.write("\n".join(qmake_content_lines)) - base.delete_file("./harfbuzz/src/hb-ft.cc") - base.copy_file("./patch/hb-ft.cc", "./harfbuzz/src/hb-ft.cc") + #base.delete_file("./harfbuzz/src/hb-ft.cc") + #base.copy_file("./patch/hb-ft.cc", "./harfbuzz/src/hb-ft.cc") diff --git a/Common/3dParty/harfbuzz/patch/hb-ft.cc b/Common/3dParty/harfbuzz/patch/hb-ft.cc deleted file mode 100644 index a9ac8be6885..00000000000 --- a/Common/3dParty/harfbuzz/patch/hb-ft.cc +++ /dev/null @@ -1,1155 +0,0 @@ -/* - * Copyright © 2009 Red Hat, Inc. - * Copyright © 2009 Keith Stribley - * Copyright © 2015 Google, Inc. - * - * This is part of HarfBuzz, a text shaping library. - * - * Permission is hereby granted, without written agreement and without - * license or royalty fees, to use, copy, modify, and distribute this - * software and its documentation for any purpose, provided that the - * above copyright notice and the following two paragraphs appear in - * all copies of this software. - * - * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN - * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, - * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO - * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - * - * Red Hat Author(s): Behdad Esfahbod - * Google Author(s): Behdad Esfahbod - */ - -#include "hb.hh" - -#ifdef HAVE_FREETYPE - -#include "hb-ft.h" - -#include "hb-draw.hh" -#include "hb-font.hh" -#include "hb-machinery.hh" -#include "hb-cache.hh" - -#include FT_ADVANCES_H -#include FT_MULTIPLE_MASTERS_H -#include FT_OUTLINE_H -#include FT_TRUETYPE_TABLES_H - - -/** - * SECTION:hb-ft - * @title: hb-ft - * @short_description: FreeType integration - * @include: hb-ft.h - * - * Functions for using HarfBuzz with the FreeType library. - * - * HarfBuzz supports using FreeType to provide face and - * font data. - * - * Note that FreeType is not thread-safe, therefore these - * functions are not thread-safe either. - **/ - - -/* TODO: - * - * In general, this file does a fine job of what it's supposed to do. - * There are, however, things that need more work: - * - * - FreeType works in 26.6 mode. Clients can decide to use that mode, and everything - * would work fine. However, we also abuse this API for performing in font-space, - * but don't pass the correct flags to FreeType. We just abuse the no-hinting mode - * for that, such that no rounding etc happens. As such, we don't set ppem, and - * pass NO_HINTING as load_flags. Would be much better to use NO_SCALE, and scale - * ourselves. - * - * - We don't handle / allow for emboldening / obliqueing. - * - * - In the future, we should add constructors to create fonts in font space? - */ - - -struct hb_ft_font_t -{ - mutable hb_mutex_t lock; - FT_Face ft_face; - int load_flags; - bool symbol; /* Whether selected cmap is symbol cmap. */ - bool unref; /* Whether to destroy ft_face when done. */ - - mutable int cached_x_scale; - mutable hb_advance_cache_t advance_cache; -}; - -static hb_ft_font_t * -_hb_ft_font_create (FT_Face ft_face, bool symbol, bool unref) -{ - hb_ft_font_t *ft_font = (hb_ft_font_t *) hb_calloc (1, sizeof (hb_ft_font_t)); - if (unlikely (!ft_font)) return nullptr; - - ft_font->lock.init (); - ft_font->ft_face = ft_face; - ft_font->symbol = symbol; - ft_font->unref = unref; - - ft_font->load_flags = FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING; - - ft_font->cached_x_scale = 0; - ft_font->advance_cache.init (); - - return ft_font; -} - -static void -_hb_ft_face_destroy (void *data) -{ - FT_Done_Face ((FT_Face) data); -} - -static void -_hb_ft_font_destroy (void *data) -{ - hb_ft_font_t *ft_font = (hb_ft_font_t *) data; - - ft_font->advance_cache.fini (); - - if (ft_font->unref) - _hb_ft_face_destroy (ft_font->ft_face); - - ft_font->lock.fini (); - - hb_free (ft_font); -} - -/** - * hb_ft_font_set_load_flags: - * @font: #hb_font_t to work upon - * @load_flags: The FreeType load flags to set - * - * Sets the FT_Load_Glyph load flags for the specified #hb_font_t. - * - * For more information, see - * https://www.freetype.org/freetype2/docs/reference/ft2-base_interface.html#ft_load_xxx - * - * Since: 1.0.5 - **/ -void -hb_ft_font_set_load_flags (hb_font_t *font, int load_flags) -{ - if (hb_object_is_immutable (font)) - return; - - if (unlikely (font->destroy != (hb_destroy_func_t) _hb_ft_font_destroy)) - return; - - hb_ft_font_t *ft_font = (hb_ft_font_t *) font->user_data; - - ft_font->load_flags = load_flags; -} - -/** - * hb_ft_font_get_load_flags: - * @font: #hb_font_t to work upon - * - * Fetches the FT_Load_Glyph load flags of the specified #hb_font_t. - * - * For more information, see - * https://www.freetype.org/freetype2/docs/reference/ft2-base_interface.html#ft_load_xxx - * - * Return value: FT_Load_Glyph flags found - * - * Since: 1.0.5 - **/ -int -hb_ft_font_get_load_flags (hb_font_t *font) -{ - if (unlikely (font->destroy != (hb_destroy_func_t) _hb_ft_font_destroy)) - return 0; - - const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font->user_data; - - return ft_font->load_flags; -} - -/** - * hb_ft_font_get_face: - * @font: #hb_font_t to work upon - * - * Fetches the FT_Face associated with the specified #hb_font_t - * font object. - * - * Return value: (nullable): the FT_Face found or %NULL - * - * Since: 0.9.2 - **/ -FT_Face -hb_ft_font_get_face (hb_font_t *font) -{ - if (unlikely (font->destroy != (hb_destroy_func_t) _hb_ft_font_destroy)) - return nullptr; - - const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font->user_data; - - return ft_font->ft_face; -} - -/** - * hb_ft_font_lock_face: - * @font: #hb_font_t to work upon - * - * Gets the FT_Face associated with @font, This face will be kept around until - * you call hb_ft_font_unlock_face(). - * - * Return value: (nullable): the FT_Face associated with @font or %NULL - * Since: 2.6.5 - **/ -FT_Face -hb_ft_font_lock_face (hb_font_t *font) -{ - if (unlikely (font->destroy != (hb_destroy_func_t) _hb_ft_font_destroy)) - return nullptr; - - const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font->user_data; - - ft_font->lock.lock (); - - return ft_font->ft_face; -} - -/** - * hb_ft_font_unlock_face: - * @font: #hb_font_t to work upon - * - * Releases an FT_Face previously obtained with hb_ft_font_lock_face(). - * - * Since: 2.6.5 - **/ -void -hb_ft_font_unlock_face (hb_font_t *font) -{ - if (unlikely (font->destroy != (hb_destroy_func_t) _hb_ft_font_destroy)) - return; - - const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font->user_data; - - ft_font->lock.unlock (); -} - -static FT_UInt -hb_ft_get_index_by_unicode(FT_Face face, FT_ULong charcode) -{ - FT_CharMap charmap; - FT_UInt gindex = 0; - FT_Int charmap_index = 0; - FT_Encoding cur_encoding = FT_ENCODING_NONE; - bool is_symbol = false; - if (face && face->charmap) - cur_encoding = face->charmap->encoding; - - while (charmap_index < face->num_charmaps) - { - charmap = face->charmaps[charmap_index]; - is_symbol = (0 == charmap->encoding_id && 3 == charmap->platform_id) ? true : false; - - if (0 == FT_Set_Charmap(face, charmap)) - { - gindex = FT_Get_Char_Index(face, charcode); - - if (!gindex && is_symbol) - gindex = FT_Get_Char_Index(face, 0xF000); - - if (gindex) - return gindex; - } - - charmap_index++; - } - - FT_Select_Charmap(face, cur_encoding); - return gindex; -} - -static hb_bool_t -hb_ft_get_nominal_glyph (hb_font_t *font HB_UNUSED, - void *font_data, - hb_codepoint_t unicode, - hb_codepoint_t *glyph, - void *user_data HB_UNUSED) -{ - const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; - hb_lock_t lock (ft_font->lock); - unsigned int g = FT_Get_Char_Index (ft_font->ft_face, unicode); - - if (unlikely (!g)) - { - if (unlikely (ft_font->symbol) && unicode <= 0x00FFu) - { - /* For symbol-encoded OpenType fonts, we duplicate the - * U+F000..F0FF range at U+0000..U+00FF. That's what - * Windows seems to do, and that's hinted about at: - * https://docs.microsoft.com/en-us/typography/opentype/spec/recom - * under "Non-Standard (Symbol) Fonts". */ - g = FT_Get_Char_Index (ft_font->ft_face, 0xF000u + unicode); - } - } - - if (!g) - g = hb_ft_get_index_by_unicode(ft_font->ft_face, unicode); - if (!g) - return false; - - *glyph = g; - return true; -} - -static unsigned int -hb_ft_get_nominal_glyphs (hb_font_t *font HB_UNUSED, - void *font_data, - unsigned int count, - const hb_codepoint_t *first_unicode, - unsigned int unicode_stride, - hb_codepoint_t *first_glyph, - unsigned int glyph_stride, - void *user_data HB_UNUSED) -{ - const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; - hb_lock_t lock (ft_font->lock); - unsigned int done; - for (done = 0; - done < count && (*first_glyph = FT_Get_Char_Index (ft_font->ft_face, *first_unicode)); - done++) - { - first_unicode = &StructAtOffsetUnaligned (first_unicode, unicode_stride); - first_glyph = &StructAtOffsetUnaligned (first_glyph, glyph_stride); - } - /* We don't need to do ft_font->symbol dance here, since HB calls the singular - * nominal_glyph() for what we don't handle here. */ - return done; -} - - -static hb_bool_t -hb_ft_get_variation_glyph (hb_font_t *font HB_UNUSED, - void *font_data, - hb_codepoint_t unicode, - hb_codepoint_t variation_selector, - hb_codepoint_t *glyph, - void *user_data HB_UNUSED) -{ - const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; - hb_lock_t lock (ft_font->lock); - unsigned int g = FT_Face_GetCharVariantIndex (ft_font->ft_face, unicode, variation_selector); - - if (unlikely (!g)) - return false; - - *glyph = g; - return true; -} - -static void -hb_ft_get_glyph_h_advances (hb_font_t* font, void* font_data, - unsigned count, - const hb_codepoint_t *first_glyph, - unsigned glyph_stride, - hb_position_t *first_advance, - unsigned advance_stride, - void *user_data HB_UNUSED) -{ - const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; - hb_lock_t lock (ft_font->lock); - FT_Face ft_face = ft_font->ft_face; - int load_flags = ft_font->load_flags; - int mult = font->x_scale < 0 ? -1 : +1; - - if (font->x_scale != ft_font->cached_x_scale) - { - ft_font->advance_cache.clear (); - ft_font->cached_x_scale = font->x_scale; - } - - for (unsigned int i = 0; i < count; i++) - { - FT_Fixed v = 0; - hb_codepoint_t glyph = *first_glyph; - - unsigned int cv; - if (ft_font->advance_cache.get (glyph, &cv)) - v = cv; - else - { - FT_Get_Advance (ft_face, glyph, load_flags, &v); - ft_font->advance_cache.set (glyph, v); - } - - *first_advance = (v * mult + (1<<9)) >> 10; - first_glyph = &StructAtOffsetUnaligned (first_glyph, glyph_stride); - first_advance = &StructAtOffsetUnaligned (first_advance, advance_stride); - } -} - -#ifndef HB_NO_VERTICAL -static hb_position_t -hb_ft_get_glyph_v_advance (hb_font_t *font, - void *font_data, - hb_codepoint_t glyph, - void *user_data HB_UNUSED) -{ - const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; - hb_lock_t lock (ft_font->lock); - FT_Fixed v; - - if (unlikely (FT_Get_Advance (ft_font->ft_face, glyph, ft_font->load_flags | FT_LOAD_VERTICAL_LAYOUT, &v))) - return 0; - - if (font->y_scale < 0) - v = -v; - - /* Note: FreeType's vertical metrics grows downward while other FreeType coordinates - * have a Y growing upward. Hence the extra negation. */ - return (-v + (1<<9)) >> 10; -} -#endif - -#ifndef HB_NO_VERTICAL -static hb_bool_t -hb_ft_get_glyph_v_origin (hb_font_t *font, - void *font_data, - hb_codepoint_t glyph, - hb_position_t *x, - hb_position_t *y, - void *user_data HB_UNUSED) -{ - const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; - hb_lock_t lock (ft_font->lock); - FT_Face ft_face = ft_font->ft_face; - - if (unlikely (FT_Load_Glyph (ft_face, glyph, ft_font->load_flags))) - return false; - - /* Note: FreeType's vertical metrics grows downward while other FreeType coordinates - * have a Y growing upward. Hence the extra negation. */ - *x = ft_face->glyph->metrics.horiBearingX - ft_face->glyph->metrics.vertBearingX; - *y = ft_face->glyph->metrics.horiBearingY - (-ft_face->glyph->metrics.vertBearingY); - - if (font->x_scale < 0) - *x = -*x; - if (font->y_scale < 0) - *y = -*y; - - return true; -} -#endif - -#ifndef HB_NO_OT_SHAPE_FALLBACK -static hb_position_t -hb_ft_get_glyph_h_kerning (hb_font_t *font, - void *font_data, - hb_codepoint_t left_glyph, - hb_codepoint_t right_glyph, - void *user_data HB_UNUSED) -{ - const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; - FT_Vector kerningv; - - FT_Kerning_Mode mode = font->x_ppem ? FT_KERNING_DEFAULT : FT_KERNING_UNFITTED; - if (FT_Get_Kerning (ft_font->ft_face, left_glyph, right_glyph, mode, &kerningv)) - return 0; - - return kerningv.x; -} -#endif - -static hb_bool_t -hb_ft_get_glyph_extents (hb_font_t *font, - void *font_data, - hb_codepoint_t glyph, - hb_glyph_extents_t *extents, - void *user_data HB_UNUSED) -{ - const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; - hb_lock_t lock (ft_font->lock); - FT_Face ft_face = ft_font->ft_face; - - if (unlikely (FT_Load_Glyph (ft_face, glyph, ft_font->load_flags))) - return false; - - extents->x_bearing = ft_face->glyph->metrics.horiBearingX; - extents->y_bearing = ft_face->glyph->metrics.horiBearingY; - extents->width = ft_face->glyph->metrics.width; - extents->height = -ft_face->glyph->metrics.height; - if (font->x_scale < 0) - { - extents->x_bearing = -extents->x_bearing; - extents->width = -extents->width; - } - if (font->y_scale < 0) - { - extents->y_bearing = -extents->y_bearing; - extents->height = -extents->height; - } - return true; -} - -static hb_bool_t -hb_ft_get_glyph_contour_point (hb_font_t *font HB_UNUSED, - void *font_data, - hb_codepoint_t glyph, - unsigned int point_index, - hb_position_t *x, - hb_position_t *y, - void *user_data HB_UNUSED) -{ - const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; - hb_lock_t lock (ft_font->lock); - FT_Face ft_face = ft_font->ft_face; - - if (unlikely (FT_Load_Glyph (ft_face, glyph, ft_font->load_flags))) - return false; - - if (unlikely (ft_face->glyph->format != FT_GLYPH_FORMAT_OUTLINE)) - return false; - - if (unlikely (point_index >= (unsigned int) ft_face->glyph->outline.n_points)) - return false; - - *x = ft_face->glyph->outline.points[point_index].x; - *y = ft_face->glyph->outline.points[point_index].y; - - return true; -} - -static hb_bool_t -hb_ft_get_glyph_name (hb_font_t *font HB_UNUSED, - void *font_data, - hb_codepoint_t glyph, - char *name, unsigned int size, - void *user_data HB_UNUSED) -{ - const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; - hb_lock_t lock (ft_font->lock); - FT_Face ft_face = ft_font->ft_face; - - hb_bool_t ret = !FT_Get_Glyph_Name (ft_face, glyph, name, size); - if (ret && (size && !*name)) - ret = false; - - return ret; -} - -static hb_bool_t -hb_ft_get_glyph_from_name (hb_font_t *font HB_UNUSED, - void *font_data, - const char *name, int len, /* -1 means nul-terminated */ - hb_codepoint_t *glyph, - void *user_data HB_UNUSED) -{ - const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; - hb_lock_t lock (ft_font->lock); - FT_Face ft_face = ft_font->ft_face; - - if (len < 0) - *glyph = FT_Get_Name_Index (ft_face, (FT_String *) name); - else { - /* Make a nul-terminated version. */ - char buf[128]; - len = hb_min (len, (int) sizeof (buf) - 1); - strncpy (buf, name, len); - buf[len] = '\0'; - *glyph = FT_Get_Name_Index (ft_face, buf); - } - - if (*glyph == 0) - { - /* Check whether the given name was actually the name of glyph 0. */ - char buf[128]; - if (!FT_Get_Glyph_Name(ft_face, 0, buf, sizeof (buf)) && - len < 0 ? !strcmp (buf, name) : !strncmp (buf, name, len)) - return true; - } - - return *glyph != 0; -} - -static hb_bool_t -hb_ft_get_font_h_extents (hb_font_t *font HB_UNUSED, - void *font_data, - hb_font_extents_t *metrics, - void *user_data HB_UNUSED) -{ - const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; - hb_lock_t lock (ft_font->lock); - FT_Face ft_face = ft_font->ft_face; - metrics->ascender = FT_MulFix(ft_face->ascender, ft_face->size->metrics.y_scale); - metrics->descender = FT_MulFix(ft_face->descender, ft_face->size->metrics.y_scale); - metrics->line_gap = FT_MulFix( ft_face->height, ft_face->size->metrics.y_scale ) - (metrics->ascender - metrics->descender); - if (font->y_scale < 0) - { - metrics->ascender = -metrics->ascender; - metrics->descender = -metrics->descender; - metrics->line_gap = -metrics->line_gap; - } - return true; -} - -#ifndef HB_NO_DRAW - -static int -_hb_ft_move_to (const FT_Vector *to, - hb_draw_session_t *drawing) -{ - drawing->move_to (to->x, to->y); - return FT_Err_Ok; -} - -static int -_hb_ft_line_to (const FT_Vector *to, - hb_draw_session_t *drawing) -{ - drawing->line_to (to->x, to->y); - return FT_Err_Ok; -} - -static int -_hb_ft_conic_to (const FT_Vector *control, - const FT_Vector *to, - hb_draw_session_t *drawing) -{ - drawing->quadratic_to (control->x, control->y, - to->x, to->y); - return FT_Err_Ok; -} - -static int -_hb_ft_cubic_to (const FT_Vector *control1, - const FT_Vector *control2, - const FT_Vector *to, - hb_draw_session_t *drawing) -{ - drawing->cubic_to (control1->x, control1->y, - control2->x, control2->y, - to->x, to->y); - return FT_Err_Ok; -} - -static void -hb_ft_get_glyph_shape (hb_font_t *font HB_UNUSED, - void *font_data, - hb_codepoint_t glyph, - hb_draw_funcs_t *draw_funcs, void *draw_data, - void *user_data HB_UNUSED) -{ - const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; - hb_lock_t lock (ft_font->lock); - FT_Face ft_face = ft_font->ft_face; - - if (unlikely (FT_Load_Glyph (ft_face, glyph, - FT_LOAD_NO_BITMAP | ft_font->load_flags))) - return; - - if (ft_face->glyph->format != FT_GLYPH_FORMAT_OUTLINE) - return; - - const FT_Outline_Funcs outline_funcs = { - (FT_Outline_MoveToFunc) _hb_ft_move_to, - (FT_Outline_LineToFunc) _hb_ft_line_to, - (FT_Outline_ConicToFunc) _hb_ft_conic_to, - (FT_Outline_CubicToFunc) _hb_ft_cubic_to, - 0, /* shift */ - 0, /* delta */ - }; - - hb_draw_session_t draw_session (draw_funcs, draw_data, font->slant_xy); - - FT_Outline_Decompose (&ft_face->glyph->outline, - &outline_funcs, - &draw_session); -} -#endif - - -static inline void free_static_ft_funcs (); - -static struct hb_ft_font_funcs_lazy_loader_t : hb_font_funcs_lazy_loader_t -{ - static hb_font_funcs_t *create () - { - hb_font_funcs_t *funcs = hb_font_funcs_create (); - - hb_font_funcs_set_nominal_glyph_func (funcs, hb_ft_get_nominal_glyph, nullptr, nullptr); - hb_font_funcs_set_nominal_glyphs_func (funcs, hb_ft_get_nominal_glyphs, nullptr, nullptr); - hb_font_funcs_set_variation_glyph_func (funcs, hb_ft_get_variation_glyph, nullptr, nullptr); - - hb_font_funcs_set_font_h_extents_func (funcs, hb_ft_get_font_h_extents, nullptr, nullptr); - hb_font_funcs_set_glyph_h_advances_func (funcs, hb_ft_get_glyph_h_advances, nullptr, nullptr); - //hb_font_funcs_set_glyph_h_origin_func (funcs, hb_ft_get_glyph_h_origin, nullptr, nullptr); - -#ifndef HB_NO_VERTICAL - //hb_font_funcs_set_font_v_extents_func (funcs, hb_ft_get_font_v_extents, nullptr, nullptr); - hb_font_funcs_set_glyph_v_advance_func (funcs, hb_ft_get_glyph_v_advance, nullptr, nullptr); - hb_font_funcs_set_glyph_v_origin_func (funcs, hb_ft_get_glyph_v_origin, nullptr, nullptr); -#endif - -#ifndef HB_NO_OT_SHAPE_FALLBACK - hb_font_funcs_set_glyph_h_kerning_func (funcs, hb_ft_get_glyph_h_kerning, nullptr, nullptr); -#endif - //hb_font_funcs_set_glyph_v_kerning_func (funcs, hb_ft_get_glyph_v_kerning, nullptr, nullptr); - hb_font_funcs_set_glyph_extents_func (funcs, hb_ft_get_glyph_extents, nullptr, nullptr); - hb_font_funcs_set_glyph_contour_point_func (funcs, hb_ft_get_glyph_contour_point, nullptr, nullptr); - hb_font_funcs_set_glyph_name_func (funcs, hb_ft_get_glyph_name, nullptr, nullptr); - hb_font_funcs_set_glyph_from_name_func (funcs, hb_ft_get_glyph_from_name, nullptr, nullptr); - -#ifndef HB_NO_DRAW - hb_font_funcs_set_glyph_shape_func (funcs, hb_ft_get_glyph_shape, nullptr, nullptr); -#endif - - hb_font_funcs_make_immutable (funcs); - - hb_atexit (free_static_ft_funcs); - - return funcs; - } -} static_ft_funcs; - -static inline -void free_static_ft_funcs () -{ - static_ft_funcs.free_instance (); -} - -static hb_font_funcs_t * -_hb_ft_get_font_funcs () -{ - return static_ft_funcs.get_unconst (); -} - -static void -_hb_ft_font_set_funcs (hb_font_t *font, FT_Face ft_face, bool unref) -{ - bool symbol = ft_face->charmap && ft_face->charmap->encoding == FT_ENCODING_MS_SYMBOL; - - hb_ft_font_t *ft_font = _hb_ft_font_create (ft_face, symbol, unref); - if (unlikely (!ft_font)) return; - - hb_font_set_funcs (font, - _hb_ft_get_font_funcs (), - ft_font, - _hb_ft_font_destroy); -} - - -static hb_blob_t * -_hb_ft_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data) -{ - FT_Face ft_face = (FT_Face) user_data; - FT_Byte *buffer; - FT_ULong length = 0; - FT_Error error; - - /* Note: FreeType like HarfBuzz uses the NONE tag for fetching the entire blob */ - - error = FT_Load_Sfnt_Table (ft_face, tag, 0, nullptr, &length); - if (error) - return nullptr; - - buffer = (FT_Byte *) hb_malloc (length); - if (!buffer) - return nullptr; - - error = FT_Load_Sfnt_Table (ft_face, tag, 0, buffer, &length); - if (error) - { - hb_free (buffer); - return nullptr; - } - - return hb_blob_create ((const char *) buffer, length, - HB_MEMORY_MODE_WRITABLE, - buffer, hb_free); -} - -/** - * hb_ft_face_create: - * @ft_face: (destroy destroy) (scope notified): FT_Face to work upon - * @destroy: (nullable): A callback to call when the face object is not needed anymore - * - * Creates an #hb_face_t face object from the specified FT_Face. - * - * This variant of the function does not provide any life-cycle management. - * - * Most client programs should use hb_ft_face_create_referenced() - * (or, perhaps, hb_ft_face_create_cached()) instead. - * - * If you know you have valid reasons not to use hb_ft_face_create_referenced(), - * then it is the client program's responsibility to destroy @ft_face - * after the #hb_face_t face object has been destroyed. - * - * Return value: (transfer full): the new #hb_face_t face object - * - * Since: 0.9.2 - **/ -hb_face_t * -hb_ft_face_create (FT_Face ft_face, - hb_destroy_func_t destroy) -{ - hb_face_t *face; - - if (!ft_face->stream->read) { - hb_blob_t *blob; - - blob = hb_blob_create ((const char *) ft_face->stream->base, - (unsigned int) ft_face->stream->size, - HB_MEMORY_MODE_READONLY, - ft_face, destroy); - face = hb_face_create (blob, ft_face->face_index); - hb_blob_destroy (blob); - } else { - face = hb_face_create_for_tables (_hb_ft_reference_table, ft_face, destroy); - } - - hb_face_set_index (face, ft_face->face_index); - hb_face_set_upem (face, ft_face->units_per_EM); - - return face; -} - -/** - * hb_ft_face_create_referenced: - * @ft_face: FT_Face to work upon - * - * Creates an #hb_face_t face object from the specified FT_Face. - * - * This is the preferred variant of the hb_ft_face_create* - * function family, because it calls FT_Reference_Face() on @ft_face, - * ensuring that @ft_face remains alive as long as the resulting - * #hb_face_t face object remains alive. Also calls FT_Done_Face() - * when the #hb_face_t face object is destroyed. - * - * Use this version unless you know you have good reasons not to. - * - * Return value: (transfer full): the new #hb_face_t face object - * - * Since: 0.9.38 - **/ -hb_face_t * -hb_ft_face_create_referenced (FT_Face ft_face) -{ - FT_Reference_Face (ft_face); - return hb_ft_face_create (ft_face, _hb_ft_face_destroy); -} - -static void -hb_ft_face_finalize (FT_Face ft_face) -{ - hb_face_destroy ((hb_face_t *) ft_face->generic.data); -} - -/** - * hb_ft_face_create_cached: - * @ft_face: FT_Face to work upon - * - * Creates an #hb_face_t face object from the specified FT_Face. - * - * This variant of the function caches the newly created #hb_face_t - * face object, using the @generic pointer of @ft_face. Subsequent function - * calls that are passed the same @ft_face parameter will have the same - * #hb_face_t returned to them, and that #hb_face_t will be correctly - * reference counted. - * - * However, client programs are still responsible for destroying - * @ft_face after the last #hb_face_t face object has been destroyed. - * - * Return value: (transfer full): the new #hb_face_t face object - * - * Since: 0.9.2 - **/ -hb_face_t * -hb_ft_face_create_cached (FT_Face ft_face) -{ - if (unlikely (!ft_face->generic.data || ft_face->generic.finalizer != (FT_Generic_Finalizer) hb_ft_face_finalize)) - { - if (ft_face->generic.finalizer) - ft_face->generic.finalizer (ft_face); - - ft_face->generic.data = hb_ft_face_create (ft_face, nullptr); - ft_face->generic.finalizer = (FT_Generic_Finalizer) hb_ft_face_finalize; - } - - return hb_face_reference ((hb_face_t *) ft_face->generic.data); -} - -/** - * hb_ft_font_create: - * @ft_face: (destroy destroy) (scope notified): FT_Face to work upon - * @destroy: (nullable): A callback to call when the font object is not needed anymore - * - * Creates an #hb_font_t font object from the specified FT_Face. - * - * Note: You must set the face size on @ft_face before calling - * hb_ft_font_create() on it. HarfBuzz assumes size is always set and will - * access `size` member of FT_Face unconditionally. - * - * This variant of the function does not provide any life-cycle management. - * - * Most client programs should use hb_ft_font_create_referenced() - * instead. - * - * If you know you have valid reasons not to use hb_ft_font_create_referenced(), - * then it is the client program's responsibility to destroy @ft_face - * after the #hb_font_t font object has been destroyed. - * - * HarfBuzz will use the @destroy callback on the #hb_font_t font object - * if it is supplied when you use this function. However, even if @destroy - * is provided, it is the client program's responsibility to destroy @ft_face, - * and it is the client program's responsibility to ensure that @ft_face is - * destroyed only after the #hb_font_t font object has been destroyed. - * - * Return value: (transfer full): the new #hb_font_t font object - * - * Since: 0.9.2 - **/ -hb_font_t * -hb_ft_font_create (FT_Face ft_face, - hb_destroy_func_t destroy) -{ - hb_font_t *font; - hb_face_t *face; - - face = hb_ft_face_create (ft_face, destroy); - font = hb_font_create (face); - hb_face_destroy (face); - _hb_ft_font_set_funcs (font, ft_face, false); - hb_ft_font_changed (font); - return font; -} - -/** - * hb_ft_font_changed: - * @font: #hb_font_t to work upon - * - * Refreshes the state of @font when the underlying FT_Face has changed. - * This function should be called after changing the size or - * variation-axis settings on the FT_Face. - * - * Since: 1.0.5 - **/ -void -hb_ft_font_changed (hb_font_t *font) -{ - if (font->destroy != (hb_destroy_func_t) _hb_ft_font_destroy) - return; - - hb_ft_font_t *ft_font = (hb_ft_font_t *) font->user_data; - - FT_Face ft_face = ft_font->ft_face; - - hb_font_set_scale (font, - (int) (((uint64_t) ft_face->size->metrics.x_scale * (uint64_t) ft_face->units_per_EM + (1u<<15)) >> 16), - (int) (((uint64_t) ft_face->size->metrics.y_scale * (uint64_t) ft_face->units_per_EM + (1u<<15)) >> 16)); -#if 0 /* hb-ft works in no-hinting model */ - hb_font_set_ppem (font, - ft_face->size->metrics.x_ppem, - ft_face->size->metrics.y_ppem); -#endif - -#if defined(HAVE_FT_GET_VAR_BLEND_COORDINATES) && !defined(HB_NO_VAR) - FT_MM_Var *mm_var = nullptr; - if (!FT_Get_MM_Var (ft_face, &mm_var)) - { - FT_Fixed *ft_coords = (FT_Fixed *) hb_calloc (mm_var->num_axis, sizeof (FT_Fixed)); - int *coords = (int *) hb_calloc (mm_var->num_axis, sizeof (int)); - if (coords && ft_coords) - { - if (!FT_Get_Var_Blend_Coordinates (ft_face, mm_var->num_axis, ft_coords)) - { - bool nonzero = false; - - for (unsigned int i = 0; i < mm_var->num_axis; ++i) - { - coords[i] = ft_coords[i] >>= 2; - nonzero = nonzero || coords[i]; - } - - if (nonzero) - hb_font_set_var_coords_normalized (font, coords, mm_var->num_axis); - else - hb_font_set_var_coords_normalized (font, nullptr, 0); - } - } - hb_free (coords); - hb_free (ft_coords); -#ifdef HAVE_FT_DONE_MM_VAR - FT_Done_MM_Var (ft_face->glyph->library, mm_var); -#else - hb_free (mm_var); -#endif - } -#endif -} - -/** - * hb_ft_font_create_referenced: - * @ft_face: FT_Face to work upon - * - * Creates an #hb_font_t font object from the specified FT_Face. - * - * Note: You must set the face size on @ft_face before calling - * hb_ft_font_create_referenced() on it. HarfBuzz assumes size is always set - * and will access `size` member of FT_Face unconditionally. - * - * This is the preferred variant of the hb_ft_font_create* - * function family, because it calls FT_Reference_Face() on @ft_face, - * ensuring that @ft_face remains alive as long as the resulting - * #hb_font_t font object remains alive. - * - * Use this version unless you know you have good reasons not to. - * - * Return value: (transfer full): the new #hb_font_t font object - * - * Since: 0.9.38 - **/ -hb_font_t * -hb_ft_font_create_referenced (FT_Face ft_face) -{ - FT_Reference_Face (ft_face); - return hb_ft_font_create (ft_face, _hb_ft_face_destroy); -} - -static inline void free_static_ft_library (); - -static struct hb_ft_library_lazy_loader_t : hb_lazy_loader_t, - hb_ft_library_lazy_loader_t> -{ - static FT_Library create () - { - FT_Library l; - if (FT_Init_FreeType (&l)) - return nullptr; - - hb_atexit (free_static_ft_library); - - return l; - } - static void destroy (FT_Library l) - { - FT_Done_FreeType (l); - } - static FT_Library get_null () - { - return nullptr; - } -} static_ft_library; - -static inline -void free_static_ft_library () -{ - static_ft_library.free_instance (); -} - -static FT_Library -get_ft_library () -{ - return static_ft_library.get_unconst (); -} - -static void -_release_blob (FT_Face ft_face) -{ - hb_blob_destroy ((hb_blob_t *) ft_face->generic.data); -} - -/** - * hb_ft_font_set_funcs: - * @font: #hb_font_t to work upon - * - * Configures the font-functions structure of the specified - * #hb_font_t font object to use FreeType font functions. - * - * In particular, you can use this function to configure an - * existing #hb_face_t face object for use with FreeType font - * functions even if that #hb_face_t face object was initially - * created with hb_face_create(), and therefore was not - * initially configured to use FreeType font functions. - * - * An #hb_face_t face object created with hb_ft_face_create() - * is preconfigured for FreeType font functions and does not - * require this function to be used. - * - * Note: Internally, this function creates an FT_Face. -* - * - * Since: 1.0.5 - **/ -void -hb_ft_font_set_funcs (hb_font_t *font) -{ - hb_blob_t *blob = hb_face_reference_blob (font->face); - unsigned int blob_length; - const char *blob_data = hb_blob_get_data (blob, &blob_length); - if (unlikely (!blob_length)) - DEBUG_MSG (FT, font, "Font face has empty blob"); - - FT_Face ft_face = nullptr; - FT_Error err = FT_New_Memory_Face (get_ft_library (), - (const FT_Byte *) blob_data, - blob_length, - hb_face_get_index (font->face), - &ft_face); - - if (unlikely (err)) { - hb_blob_destroy (blob); - DEBUG_MSG (FT, font, "Font face FT_New_Memory_Face() failed"); - return; - } - - if (FT_Select_Charmap (ft_face, FT_ENCODING_MS_SYMBOL)) - FT_Select_Charmap (ft_face, FT_ENCODING_UNICODE); - - FT_Set_Char_Size (ft_face, - abs (font->x_scale), abs (font->y_scale), - 0, 0); -#if 0 - font->x_ppem * 72 * 64 / font->x_scale, - font->y_ppem * 72 * 64 / font->y_scale); -#endif - if (font->x_scale < 0 || font->y_scale < 0) - { - FT_Matrix matrix = { font->x_scale < 0 ? -1 : +1, 0, - 0, font->y_scale < 0 ? -1 : +1}; - FT_Set_Transform (ft_face, &matrix, nullptr); - } - -#if defined(HAVE_FT_GET_VAR_BLEND_COORDINATES) && !defined(HB_NO_VAR) - unsigned int num_coords; - const int *coords = hb_font_get_var_coords_normalized (font, &num_coords); - if (num_coords) - { - FT_Fixed *ft_coords = (FT_Fixed *) hb_calloc (num_coords, sizeof (FT_Fixed)); - if (ft_coords) - { - for (unsigned int i = 0; i < num_coords; i++) - ft_coords[i] = coords[i] * 4; - FT_Set_Var_Blend_Coordinates (ft_face, num_coords, ft_coords); - hb_free (ft_coords); - } - } -#endif - - ft_face->generic.data = blob; - ft_face->generic.finalizer = (FT_Generic_Finalizer) _release_blob; - - _hb_ft_font_set_funcs (font, ft_face, true); - hb_ft_font_set_load_flags (font, FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING); -} - - -#endif diff --git a/Common/3dParty/harfbuzz/patch/hb-ft.cc.patch b/Common/3dParty/harfbuzz/patch/hb-ft.cc.patch new file mode 100644 index 00000000000..679ea953dee --- /dev/null +++ b/Common/3dParty/harfbuzz/patch/hb-ft.cc.patch @@ -0,0 +1,130 @@ +<<<<<<< +static hb_bool_t +hb_ft_get_nominal_glyph (hb_font_t *font, + void *font_data, + hb_codepoint_t unicode, + hb_codepoint_t *glyph, + void *user_data HB_UNUSED) +{ + const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; + hb_lock_t lock (ft_font->lock); + unsigned int g = FT_Get_Char_Index (ft_font->ft_face, unicode); + + if (unlikely (!g)) + { + if (unlikely (ft_font->symbol)) + { + switch ((unsigned) font->face->table.OS2->get_font_page ()) { + case OT::OS2::font_page_t::FONT_PAGE_NONE: + if (unicode <= 0x00FFu) + /* For symbol-encoded OpenType fonts, we duplicate the + * U+F000..F0FF range at U+0000..U+00FF. That's what + * Windows seems to do, and that's hinted about at: + * https://docs.microsoft.com/en-us/typography/opentype/spec/recom + * under "Non-Standard (Symbol) Fonts". */ + g = FT_Get_Char_Index (ft_font->ft_face, 0xF000u + unicode); + break; +#ifndef HB_NO_OT_SHAPER_ARABIC_FALLBACK + case OT::OS2::font_page_t::FONT_PAGE_SIMP_ARABIC: + g = FT_Get_Char_Index (ft_font->ft_face, _hb_arabic_pua_simp_map (unicode)); + break; + case OT::OS2::font_page_t::FONT_PAGE_TRAD_ARABIC: + g = FT_Get_Char_Index (ft_font->ft_face, _hb_arabic_pua_trad_map (unicode)); + break; +#endif + default: + break; + } + if (!g) + return false; + } + else + return false; + } + + *glyph = g; + return true; +} +======= +static FT_UInt +hb_ft_get_index_by_unicode(FT_Face face, FT_ULong charcode) +{ + FT_CharMap charmap; + FT_UInt gindex = 0; + FT_Int charmap_index = 0; + FT_Encoding cur_encoding = FT_ENCODING_NONE; + bool is_symbol = false; + if (face && face->charmap) + cur_encoding = face->charmap->encoding; + + while (charmap_index < face->num_charmaps) + { + charmap = face->charmaps[charmap_index]; + is_symbol = (0 == charmap->encoding_id && 3 == charmap->platform_id) ? true : false; + + if (0 == FT_Set_Charmap(face, charmap)) + { + gindex = FT_Get_Char_Index(face, charcode); + + if (!gindex && is_symbol) + gindex = FT_Get_Char_Index(face, 0xF000); + + if (gindex) + return gindex; + } + + charmap_index++; + } + + FT_Select_Charmap(face, cur_encoding); + return gindex; +} + +static hb_bool_t +hb_ft_get_nominal_glyph (hb_font_t *font, + void *font_data, + hb_codepoint_t unicode, + hb_codepoint_t *glyph, + void *user_data HB_UNUSED) +{ + const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; + hb_lock_t lock (ft_font->lock); + unsigned int g = FT_Get_Char_Index (ft_font->ft_face, unicode); + + if (unlikely (!g)) + { + if (unlikely (ft_font->symbol)) + { + switch ((unsigned) font->face->table.OS2->get_font_page ()) { + case OT::OS2::font_page_t::FONT_PAGE_NONE: + if (unicode <= 0x00FFu) + /* For symbol-encoded OpenType fonts, we duplicate the + * U+F000..F0FF range at U+0000..U+00FF. That's what + * Windows seems to do, and that's hinted about at: + * https://docs.microsoft.com/en-us/typography/opentype/spec/recom + * under "Non-Standard (Symbol) Fonts". */ + g = FT_Get_Char_Index (ft_font->ft_face, 0xF000u + unicode); + break; +#ifndef HB_NO_OT_SHAPER_ARABIC_FALLBACK + case OT::OS2::font_page_t::FONT_PAGE_SIMP_ARABIC: + g = FT_Get_Char_Index (ft_font->ft_face, _hb_arabic_pua_simp_map (unicode)); + break; + case OT::OS2::font_page_t::FONT_PAGE_TRAD_ARABIC: + g = FT_Get_Char_Index (ft_font->ft_face, _hb_arabic_pua_trad_map (unicode)); + break; +#endif + default: + break; + } + } + } + + if (!g) + g = hb_ft_get_index_by_unicode(ft_font->ft_face, unicode); + if (!g) + return false; + + *glyph = g; + return true; +} +>>>>>>> diff --git a/Common/3dParty/html/css/src/CCompiledStyle.cpp b/Common/3dParty/html/css/src/CCompiledStyle.cpp index 91152db7bcd..1d5d8d355ed 100644 --- a/Common/3dParty/html/css/src/CCompiledStyle.cpp +++ b/Common/3dParty/html/css/src/CCompiledStyle.cpp @@ -12,22 +12,20 @@ #include "StaticFunctions.h" #include "ConstValues.h" -#define DEFAULTFONTSIZE 28 // 14 * 2 +#define DEFAULT_FONT_SIZE 14 namespace NSCSS { typedef std::map::const_iterator styles_iterator; - CCompiledStyle::CCompiledStyle() : m_nDpi(96), m_UnitMeasure(Point) - { - m_oFont.SetSize(std::to_wstring(DEFAULTFONTSIZE), 0, true); - } + CCompiledStyle::CCompiledStyle() : m_nDpi(96), m_UnitMeasure(Point), m_dCoreFontSize(DEFAULT_FONT_SIZE) + {} - CCompiledStyle::CCompiledStyle(const CCompiledStyle& oStyle) : - m_arParentsStyles(oStyle.m_arParentsStyles), m_sId(oStyle.m_sId), - m_nDpi(oStyle.m_nDpi), m_UnitMeasure(oStyle.m_UnitMeasure), - m_oFont(oStyle.m_oFont), m_oMargin(oStyle.m_oMargin), m_oPadding(oStyle.m_oPadding), m_oBackground(oStyle.m_oBackground), - m_oText(oStyle.m_oText), m_oBorder(oStyle.m_oBorder), m_oDisplay(oStyle.m_oDisplay){} + CCompiledStyle::CCompiledStyle(const CCompiledStyle& oStyle) : + m_arParentsStyles(oStyle.m_arParentsStyles), m_sId(oStyle.m_sId), + m_nDpi(oStyle.m_nDpi), m_UnitMeasure(oStyle.m_UnitMeasure), m_dCoreFontSize(oStyle.m_dCoreFontSize), + m_oFont(oStyle.m_oFont), m_oMargin(oStyle.m_oMargin), m_oPadding(oStyle.m_oPadding), m_oBackground(oStyle.m_oBackground), + m_oText(oStyle.m_oText), m_oBorder(oStyle.m_oBorder), m_oDisplay(oStyle.m_oDisplay), m_oTransform(oStyle.m_oTransform){} CCompiledStyle::~CCompiledStyle() { @@ -36,6 +34,9 @@ namespace NSCSS CCompiledStyle& CCompiledStyle::operator+= (const CCompiledStyle &oElement) { + if (oElement.Empty()) + return *this; + m_oBackground += oElement.m_oBackground; m_oBorder += oElement.m_oBorder; m_oFont += oElement.m_oFont; @@ -43,6 +44,10 @@ namespace NSCSS m_oPadding += oElement.m_oPadding; m_oText += oElement.m_oText; m_oDisplay += oElement.m_oDisplay; + m_oTransform += oElement.m_oTransform; + + if (!oElement.m_sId.empty()) + m_sId += L'+' + oElement.m_sId; return *this; } @@ -62,21 +67,21 @@ namespace NSCSS m_oPadding = oElement.m_oPadding; m_oText = oElement.m_oText; m_oDisplay = oElement.m_oDisplay; + m_oTransform = oElement.m_oTransform; return *this; } bool CCompiledStyle::operator== (const CCompiledStyle& oStyle) const { - return GetId()[0] == oStyle.GetId()[0] && - m_arParentsStyles == oStyle.m_arParentsStyles && - m_oBackground == oStyle.m_oBackground && + return m_oBackground == oStyle.m_oBackground && m_oBorder == oStyle.m_oBorder && m_oFont == oStyle.m_oFont && m_oMargin == oStyle.m_oMargin && m_oPadding == oStyle.m_oPadding && m_oText == oStyle.m_oText && - m_oDisplay == oStyle.m_oDisplay; + m_oDisplay == oStyle.m_oDisplay && + m_oTransform == oStyle.m_oTransform; } void CCompiledStyle::StyleEquation(CCompiledStyle &oFirstStyle, CCompiledStyle &oSecondStyle) @@ -88,6 +93,7 @@ namespace NSCSS NSProperties::CText ::Equation(oFirstStyle.m_oText, oSecondStyle.m_oText); NSProperties::CBorder ::Equation(oFirstStyle.m_oBorder, oSecondStyle.m_oBorder); NSProperties::CDisplay ::Equation(oFirstStyle.m_oDisplay, oSecondStyle.m_oDisplay); + NSProperties::CTransform ::Equation(oFirstStyle.m_oTransform, oSecondStyle.m_oTransform); } void CCompiledStyle::SetDpi(const unsigned short &uiDpi) @@ -100,16 +106,6 @@ namespace NSCSS m_UnitMeasure = enUnitMeasure; } - void CCompiledStyle::SetSizeSourceWindow(const CSizeWindow &oSizeWindow) - { - m_oSourceWindow = oSizeWindow; - } - - void CCompiledStyle::SetSizeDeviceWindow(const CSizeWindow &oSizeWindow) - { - m_oDeviceWindow = oSizeWindow; - } - bool CCompiledStyle::Empty() const { return m_oBackground.Empty() && m_oBorder.Empty() && m_oFont.Empty() && @@ -124,8 +120,11 @@ namespace NSCSS void CCompiledStyle::AddStyle(const std::map& mStyle, const unsigned int unLevel, const bool& bHardMode) { const bool bIsThereBorder = (m_oBorder.Empty()) ? false : true; - const double dFontSize = m_oFont.GetSize().ToDouble(NSCSS::Twips); - + const double dParentFontSize = (!m_oFont.GetSize().Empty()) ? m_oFont.GetSize().ToDouble(NSCSS::Point) : DEFAULT_FONT_SIZE; + + if (0 == unLevel) + m_dCoreFontSize = dParentFontSize; + for (std::pair pPropertie : mStyle) { std::transform(pPropertie.first.begin(), pPropertie.first.end(), pPropertie.first.begin(), tolower); @@ -136,15 +135,15 @@ namespace NSCSS CASE(L"font"): { m_oFont.SetValue(pPropertie.second, unLevel, bHardMode); - m_oFont.UpdateSize(dFontSize); - m_oFont.UpdateLineHeight(dFontSize); + m_oFont.UpdateSize(dParentFontSize, m_dCoreFontSize); + m_oFont.UpdateLineHeight(dParentFontSize, m_dCoreFontSize); break; } CASE(L"font-size"): CASE(L"font-size-adjust"): { m_oFont.SetSize(pPropertie.second, unLevel, bHardMode); - m_oFont.UpdateSize(dFontSize); + m_oFont.UpdateSize(dParentFontSize, m_dCoreFontSize); break; } CASE(L"font-stretch"): @@ -183,82 +182,85 @@ namespace NSCSS if (bIsThereBorder) break; - m_oMargin.AddValue(pPropertie.second, unLevel, bHardMode); - m_oMargin.UpdateAll(dFontSize); + m_oMargin.SetValues(pPropertie.second, unLevel, bHardMode); + m_oMargin.UpdateAll(dParentFontSize, m_dCoreFontSize); break; } CASE(L"margin-top"): + CASE(L"topmargin"): { if (bIsThereBorder) break; - m_oMargin.AddTop(pPropertie.second, unLevel, bHardMode); - m_oMargin.UpdateTop(dFontSize); + m_oMargin.SetTop(pPropertie.second, unLevel, bHardMode); break; } CASE(L"margin-right"): CASE(L"margin-block-end"): + CASE(L"rightmargin"): { if (bIsThereBorder) break; - m_oMargin.AddRight(pPropertie.second, unLevel, bHardMode); - m_oMargin.UpdateRight(dFontSize); + m_oMargin.SetRight(pPropertie.second, unLevel, bHardMode); + m_oMargin.UpdateRight(dParentFontSize, m_dCoreFontSize); break; } CASE(L"margin-bottom"): + CASE(L"bottommargin"): { if (bIsThereBorder) break; - m_oMargin.AddBottom(pPropertie.second, unLevel, bHardMode); - m_oMargin.UpdateBottom(dFontSize); + m_oMargin.SetBottom(pPropertie.second, unLevel, bHardMode); + m_oMargin.UpdateBottom(dParentFontSize, m_dCoreFontSize); break; } CASE(L"margin-left"): CASE(L"margin-block-start"): + CASE(L"leftmargin"): { if (bIsThereBorder) break; - m_oMargin.AddLeft(pPropertie.second, unLevel, bHardMode); - m_oMargin.UpdateLeft(dFontSize); + m_oMargin.SetLeft(pPropertie.second, unLevel, bHardMode); + m_oMargin.UpdateLeft(dParentFontSize, m_dCoreFontSize); break; } //PADDING CASE(L"padding"): CASE(L"mso-padding-alt"): { - m_oPadding.AddValue(pPropertie.second, unLevel, bHardMode); - m_oPadding.UpdateAll(dFontSize); + m_oPadding.SetValues(pPropertie.second, unLevel, bHardMode); + m_oPadding.UpdateAll(dParentFontSize, m_dCoreFontSize); break; } CASE(L"padding-top"): CASE(L"mso-padding-top-alt"): { - m_oPadding.AddTop(pPropertie.second, unLevel, bHardMode); - m_oPadding.UpdateTop(dFontSize); + m_oPadding.SetTop(pPropertie.second, unLevel, bHardMode); + m_oPadding.UpdateTop(dParentFontSize, m_dCoreFontSize); break; } CASE(L"padding-right"): CASE(L"mso-padding-right-alt"): { - m_oPadding.AddRight(pPropertie.second, unLevel, bHardMode); - m_oPadding.UpdateRight(dFontSize); + m_oPadding.SetRight(pPropertie.second, unLevel, bHardMode); + m_oPadding.UpdateRight(dParentFontSize, m_dCoreFontSize); break; } CASE(L"padding-bottom"): CASE(L"mso-padding-bottom-alt"): { - m_oPadding.AddBottom(pPropertie.second, unLevel, bHardMode); - m_oPadding.UpdateBottom(dFontSize); + m_oPadding.SetBottom(pPropertie.second, unLevel, bHardMode); + m_oPadding.UpdateBottom(dParentFontSize, m_dCoreFontSize); break; } CASE(L"padding-left"): CASE(L"mso-padding-left-alt"): { - m_oPadding.AddLeft(pPropertie.second, unLevel, bHardMode); - m_oPadding.UpdateLeft(dFontSize); + m_oPadding.SetLeft(pPropertie.second, unLevel, bHardMode); + m_oPadding.UpdateLeft(dParentFontSize, m_dCoreFontSize); break; } // TEXT @@ -305,6 +307,11 @@ namespace NSCSS m_oBorder.SetColor(pPropertie.second, unLevel, bHardMode); break; } + CASE(L"border-collapse"): + { + m_oBorder.SetCollapse(pPropertie.second, unLevel, bHardMode); + break; + } //BORDER TOP CASE(L"border-top"): { @@ -393,20 +400,12 @@ namespace NSCSS CASE(L"background-color"): { m_oBackground.SetColor(pPropertie.second, unLevel, bHardMode); - - if (bIsThereBorder) - m_oBackground.InBorder(); - break; } CASE(L"background"): CASE(L"bgcolor"): { m_oBackground.SetBackground(pPropertie.second, unLevel, bHardMode); - - if (bIsThereBorder) - m_oBackground.InBorder(); - break; } //DISPLAY @@ -431,10 +430,17 @@ namespace NSCSS break; } CASE(L"vertical-align"): + CASE(L"valign"): { m_oDisplay.SetVAlign(pPropertie.second, unLevel, bHardMode); break; } + //TRANSFORM + CASE(L"transform"): + { + m_oTransform.SetMatrix(pPropertie.second, unLevel, bHardMode); + break; + } default: AddOtherStyle(pPropertie, unLevel, bHardMode); } } @@ -460,9 +466,6 @@ namespace NSCSS { sValue += *iWord; - if (L' ' == sValue.front()) - sValue.erase(0, 1); - if (!sValue.empty() && ((*iWord).back() == L';' || iWord == (arWords.end() - 1))) { if (sValue.back() == L';') @@ -470,6 +473,10 @@ namespace NSCSS std::transform(sProperty.begin(), sProperty.end(), sProperty.begin(), tolower); std::transform(sValue.begin(), sValue.end(), sValue.begin(), tolower); + + NS_STATIC_FUNCTIONS::RemoveSpaces(sProperty); + NS_STATIC_FUNCTIONS::RemoveSpaces(sValue); + AddPropSel(sProperty, sValue, unLevel, bHardMode); sProperty.clear(); sValue.clear(); @@ -500,6 +507,11 @@ namespace NSCSS return arParentsName; } + std::set CCompiledStyle::GetParentsNamesSet() const + { + return m_arParentsStyles; + } + void CCompiledStyle::SetID(const std::wstring& sId) { m_sId = sId; @@ -509,4 +521,9 @@ namespace NSCSS { return m_sId; } + + bool CCompiledStyle::HaveThisParent(const std::wstring &wsParentName) const + { + return m_arParentsStyles.end() != m_arParentsStyles.find(wsParentName); + } } diff --git a/Common/3dParty/html/css/src/CCompiledStyle.h b/Common/3dParty/html/css/src/CCompiledStyle.h index 192db0328e9..2a597c58c9e 100644 --- a/Common/3dParty/html/css/src/CCompiledStyle.h +++ b/Common/3dParty/html/css/src/CCompiledStyle.h @@ -22,9 +22,7 @@ namespace NSCSS unsigned short int m_nDpi; UnitMeasure m_UnitMeasure; - CSizeWindow m_oSourceWindow; - CSizeWindow m_oDeviceWindow; - + double m_dCoreFontSize; public: NSProperties::CFont m_oFont; NSProperties::CIndent m_oMargin; @@ -33,16 +31,15 @@ namespace NSCSS NSProperties::CText m_oText; NSProperties::CBorder m_oBorder; NSProperties::CDisplay m_oDisplay; + NSProperties::CTransform m_oTransform; CCompiledStyle(); CCompiledStyle(const CCompiledStyle& oStyle); - ~CCompiledStyle(); + virtual ~CCompiledStyle(); void SetDpi(const unsigned short& uiDpi); void SetUnitMeasure(const UnitMeasure& enUnitMeasure); - void SetSizeSourceWindow(const CSizeWindow& oSizeWindow); - void SetSizeDeviceWindow(const CSizeWindow& oSizeWindow); bool Empty() const; @@ -53,10 +50,13 @@ namespace NSCSS void AddParent(const std::wstring& sParentName); std::vector GetParentsName() const; + std::set GetParentsNamesSet() const; void SetID(const std::wstring& sId); std::wstring GetId() const; + bool HaveThisParent(const std::wstring& wsParentName) const; + CCompiledStyle& operator+= (const CCompiledStyle& oElement); CCompiledStyle& operator= (const CCompiledStyle& oElement); bool operator== (const CCompiledStyle& oElement) const; diff --git a/Common/3dParty/html/css/src/CCssCalculator.cpp b/Common/3dParty/html/css/src/CCssCalculator.cpp index c823ee229db..86dabcf7cab 100644 --- a/Common/3dParty/html/css/src/CCssCalculator.cpp +++ b/Common/3dParty/html/css/src/CCssCalculator.cpp @@ -1,7 +1,6 @@ #include "CCssCalculator.h" #include "CCssCalculator_Private.h" - namespace NSCSS { CCssCalculator::CCssCalculator() @@ -14,14 +13,24 @@ namespace NSCSS delete m_pInternal; } - CCompiledStyle CCssCalculator::GetCompiledStyle(const std::vector &arSelectors, const bool& bIsSettings, const UnitMeasure& unitMeasure) const + CCompiledStyle CCssCalculator::GetCompiledStyle(const std::vector &arSelectors) const + { + return m_pInternal->GetCompiledStyle(arSelectors); + } + + bool CCssCalculator::GetCompiledStyle(CCompiledStyle &oStyle, const std::vector &arSelectors) const + { + return m_pInternal->GetCompiledStyle(oStyle, arSelectors); + } + + std::wstring CCssCalculator::CalculateStyleId(const CNode& oNode) { - return m_pInternal->GetCompiledStyle(arSelectors, bIsSettings, unitMeasure); + return m_pInternal->CalculateStyleId(oNode); } - bool CCssCalculator::GetCompiledStyle(CCompiledStyle &oStyle, const std::vector &arSelectors, const bool &bIsSettings, const UnitMeasure &unitMeasure) const + bool CCssCalculator::CalculatePageStyle(NSProperties::CPage& oPageData, const std::vector &arSelectors) { - return m_pInternal->GetCompiledStyle(oStyle, arSelectors, bIsSettings, unitMeasure); + return m_pInternal->CalculatePageStyle(oPageData, arSelectors); } void CCssCalculator::AddStyles(const std::string &sStyle) @@ -39,54 +48,39 @@ namespace NSCSS m_pInternal->AddStylesFromFile(wsFileName); } - void CCssCalculator::SetUnitMeasure(const UnitMeasure& nType) - { - m_pInternal->SetUnitMeasure(nType); - } - void CCssCalculator::SetDpi(const unsigned short int& nValue) { m_pInternal->SetDpi(nValue); } - void CCssCalculator::SetBodyTree(const CTree &oTree) - { - m_pInternal->SetBodyTree(oTree); - } - - void CCssCalculator::SetSizeSourceWindow(const CSizeWindow &oSizeWindow) - { - m_pInternal->SetSizeSourceWindow(oSizeWindow); - } - - void CCssCalculator::SetSizeDeviceWindow(const CSizeWindow &oSizeWindow) + std::wstring CCssCalculator::GetEncoding() const { - m_pInternal->SetSizeDeviceWindow(oSizeWindow); + return m_pInternal->GetEncoding(); } - CSizeWindow CCssCalculator::GetSizeSourceWindow() const + unsigned short int CCssCalculator::GetDpi() const { - return m_pInternal->GetSizeSourceWindow(); + return m_pInternal->GetDpi(); } - CSizeWindow CCssCalculator::GetSizeDeviceWindow() const + void CCssCalculator::ClearPageData() { - return m_pInternal->GetSizeDeviceWindow(); + m_pInternal->ClearPageData(); } - UnitMeasure CCssCalculator::GetUnitMeasure() const + void CCssCalculator::ClearEmbeddedStyles() { - return m_pInternal->GetUnitMeasure(); + m_pInternal->ClearEmbeddedStyles(); } - std::wstring CCssCalculator::GetEncoding() const + void CCssCalculator::ClearAllowedStyleFiles() { - return m_pInternal->GetEncoding(); + m_pInternal->ClearAllowedStyleFiles(); } - unsigned short int CCssCalculator::GetDpi() const + void CCssCalculator::ClearStylesFromFile(const std::wstring& wsFilePath) { - return m_pInternal->GetDpi(); + m_pInternal->ClearStylesFromFile(wsFilePath); } void CCssCalculator::Clear() diff --git a/Common/3dParty/html/css/src/CCssCalculator.h b/Common/3dParty/html/css/src/CCssCalculator.h index fab353426b1..d5410e5e35d 100644 --- a/Common/3dParty/html/css/src/CCssCalculator.h +++ b/Common/3dParty/html/css/src/CCssCalculator.h @@ -19,28 +19,26 @@ namespace NSCSS CCssCalculator(); ~CCssCalculator(); - CCompiledStyle GetCompiledStyle(const std::vector &arSelectors, const bool& bIsSettings = false, const UnitMeasure& unitMeasure = Point) const; - bool GetCompiledStyle(CCompiledStyle& oStyle, const std::vector &arSelectors, const bool& bIsSettings = false, const UnitMeasure& unitMeasure = Point) const; + CCompiledStyle GetCompiledStyle(const std::vector &arSelectors) const; + bool GetCompiledStyle(CCompiledStyle& oStyle, const std::vector &arSelectors) const; + + std::wstring CalculateStyleId(const CNode& oNode); + bool CalculatePageStyle(NSProperties::CPage& oPageData, const std::vector &arSelectors); // void AddStyle(const std::vector& sSelectors, const std::string& sStyle); void AddStyles (const std::string& sStyle); void AddStyles (const std::wstring& wsStyle); void AddStylesFromFile(const std::wstring& wsFileName); - void SetUnitMeasure(const UnitMeasure& nType); void SetDpi(const unsigned short int& nValue); - void SetBodyTree(const CTree &oTree); - - void SetSizeSourceWindow(const CSizeWindow& oSizeWindow); - void SetSizeDeviceWindow(const CSizeWindow& oSizeWindow); - - CSizeWindow GetSizeSourceWindow() const; - CSizeWindow GetSizeDeviceWindow() const; - UnitMeasure GetUnitMeasure() const; std::wstring GetEncoding() const; unsigned short int GetDpi() const; + void ClearPageData(); + void ClearEmbeddedStyles(); + void ClearAllowedStyleFiles(); + void ClearStylesFromFile(const std::wstring& wsFilePath); void Clear(); }; } diff --git a/Common/3dParty/html/css/src/CCssCalculator_Private.cpp b/Common/3dParty/html/css/src/CCssCalculator_Private.cpp index c95a7243c76..ea30b495025 100644 --- a/Common/3dParty/html/css/src/CCssCalculator_Private.cpp +++ b/Common/3dParty/html/css/src/CCssCalculator_Private.cpp @@ -5,19 +5,17 @@ #include #include #include -#include #include #include "../../katana-parser/src/selector.h" -#include "../../../../../UnicodeConverter/UnicodeConverter.h" -#include "ConstValues.h" #include "../../../../../DesktopEditor/common/File.h" #include "StaticFunctions.h" #define MaxNumberRepetitions 6 -inline static std::wstring StringifyValueList(const KatanaArray* oValues); -inline static std::wstring StringifyValue(const KatanaValue* oValue); +inline static std::wstring StringifyValueList(const KatanaArray* oValues); +inline static std::wstring StringifyValue(const KatanaValue* oValue); +inline static bool IsTableElement(const std::wstring& wsNameTag); bool operator<(const std::vector &arLeftSelectors, const std::vector &arRightSelectors) { @@ -40,62 +38,212 @@ bool operator<(const std::vector &arLeftSelectors, const std::vect namespace NSCSS { - CCssCalculator_Private::CCssCalculator_Private() : m_nDpi(96), m_nCountNodes(0), m_UnitMeasure(Point), m_mStatictics(NULL), m_sEncoding(L"UTF-8"){} + CStyleStorage::CStyleStorage() + {} - CCssCalculator_Private::~CCssCalculator_Private() + CStyleStorage::~CStyleStorage() { - m_arFiles.clear(); + Clear(); + } - for (std::map::iterator oIter = m_mData.begin(); oIter != m_mData.end(); ++oIter) - if (oIter->second != NULL) - delete oIter->second; + void CStyleStorage::Clear() + { + for (TStyleFileData* pStyleFileData : m_arStyleFiles) + { + if (nullptr == pStyleFileData) + continue; - m_mData.clear(); + for (std::map::iterator oIter = pStyleFileData->m_mStyleData.begin(); oIter != pStyleFileData->m_mStyleData.end(); ++oIter) + if (oIter->second != nullptr) + delete oIter->second; + + delete pStyleFileData; + } + + m_arStyleFiles.clear(); + m_arEmptyStyleFiles.clear(); + + ClearEmbeddedStyles(); + ClearAllowedStyleFiles(); #ifdef CSS_CALCULATOR_WITH_XHTML - for (std::map, CCompiledStyle*>::iterator iter = m_mUsedStyles.begin(); iter != m_mUsedStyles.end(); ++iter) - delete iter->second; + ClearPageData(); + #endif + } - m_mUsedStyles.clear(); + void CStyleStorage::AddStyles(const std::string& sStyle) + { + if (sStyle.empty()) + return; + + KatanaOutput *output = katana_parse(sStyle.c_str(), sStyle.length(), KatanaParserModeStylesheet); + this->GetOutputData(output, m_mEmbeddedStyleData); + katana_destroy_output(output); + } + + void CStyleStorage::AddStyles(const std::wstring& wsStyle) + { + if (wsStyle.empty()) + return; + + #ifdef CSS_CALCULATOR_WITH_XHTML + std::wregex oRegex(L"@page\\s*([^{]*)(\\{[^}]*\\})"); + std::wsmatch oMatch; + std::wstring::const_iterator oSearchStart(wsStyle.cbegin()); + + while (std::regex_search(oSearchStart, wsStyle.cend(), oMatch, oRegex)) + { + AddPageData(oMatch[1].str(), oMatch[2].str()); + oSearchStart = oMatch.suffix().first; + } #endif - if (NULL != m_mStatictics) - delete m_mStatictics; + AddStyles(U_TO_UTF8(wsStyle)); } - inline void CCssCalculator_Private::GetOutputData(KatanaOutput *oOutput) + void CStyleStorage::AddStylesFromFile(const std::wstring& wsFileName) { - if ( NULL == oOutput ) + std::set::const_iterator itEmptyFileFound = m_arEmptyStyleFiles.find(wsFileName); + + if (m_arEmptyStyleFiles.cend() != itEmptyFileFound) return; - switch (oOutput->mode) { - case KatanaParserModeStylesheet: - GetStylesheet(oOutput->stylesheet); - break; - case KatanaParserModeRule: - GetRule(oOutput->rule); - break; - case KatanaParserModeKeyframeRule: - case KatanaParserModeKeyframeKeyList: - case KatanaParserModeMediaList: - case KatanaParserModeValue: - case KatanaParserModeSelector: - case KatanaParserModeDeclarationList: - break; + std::vector::const_iterator itFound = std::find_if(m_arStyleFiles.cbegin(), m_arStyleFiles.cend(), + [wsFileName](const TStyleFileData* pStyleFileData) + { return wsFileName == pStyleFileData->m_wsStyleFilepath; }); + + m_arAllowedStyleFiles.insert(wsFileName); + + if (m_arStyleFiles.cend() != itFound) + return; + + TStyleFileData *pStyleFileData = new TStyleFileData(); + + pStyleFileData->m_wsStyleFilepath = wsFileName; + + AddStyles(NS_STATIC_FUNCTIONS::GetContentAsUTF8(wsFileName), pStyleFileData->m_mStyleData); + + if (!pStyleFileData->m_mStyleData.empty()) + m_arStyleFiles.push_back(pStyleFileData); + else + { + m_arEmptyStyleFiles.insert(wsFileName); + delete pStyleFileData; + } + } + + void CStyleStorage::ClearStylesFromFile(const std::wstring& wsFileName) + { + std::vector::const_iterator itFound = std::find_if(m_arStyleFiles.cbegin(), m_arStyleFiles.cend(), + [wsFileName](const TStyleFileData* pStyleFileData) + { return wsFileName == pStyleFileData->m_wsStyleFilepath; }); + + if (m_arStyleFiles.cend() != itFound) + { + m_arStyleFiles.erase(itFound); + delete *itFound; + } + } + + #ifdef CSS_CALCULATOR_WITH_XHTML + void CStyleStorage::AddPageData(const std::wstring& wsPageName, const std::wstring& wsStyles) + { + m_arPageDatas.push_back({NS_STATIC_FUNCTIONS::GetWordsW(wsPageName), NS_STATIC_FUNCTIONS::GetRules(wsStyles)}); + } + + void CStyleStorage::SetPageData(NSProperties::CPage& oPage, const std::map& mData, unsigned int unLevel, bool bHardMode) + { + for (const std::pair &oData : mData) + { + if (L"margin" == oData.first) + oPage.SetMargin(oData.second, unLevel, bHardMode); + else if (L"size" == oData.first) + oPage.SetSize(oData.second, unLevel, bHardMode); + else if (L"mso-header-margin" == oData.first) + oPage.SetHeader(oData.second, unLevel, bHardMode); + else if (L"mso-footer-margin" == oData.first) + oPage.SetFooter(oData.second, unLevel, bHardMode); + } + } + + std::map CStyleStorage::GetPageData(const std::wstring& wsPageName) + { + if (m_arPageDatas.empty()) + return {}; + + for (const TPageData& oPageData : m_arPageDatas) + { + if (std::find(oPageData.m_wsNames.begin(), oPageData.m_wsNames.end(), wsPageName) != oPageData.m_wsNames.end()) + return oPageData.m_mData; + } + + return {}; + } + + void CStyleStorage::ClearPageData() + { + m_arPageDatas.clear(); + } + #endif + + const CElement* CStyleStorage::FindElement(const std::wstring& wsSelector) + { + if (wsSelector.empty()) + return nullptr; + + const CElement* pFoundElement = FindSelectorFromStyleData(wsSelector, m_mEmbeddedStyleData); + + if (nullptr != pFoundElement) + return pFoundElement; + + for (std::vector::const_reverse_iterator itIter = m_arStyleFiles.crbegin(); itIter < m_arStyleFiles.crend(); ++itIter) + { + if (m_arAllowedStyleFiles.cend() == std::find(m_arAllowedStyleFiles.cbegin(), m_arAllowedStyleFiles.cend(), (*itIter)->m_wsStyleFilepath)) + continue; + + pFoundElement = FindSelectorFromStyleData(wsSelector, (*itIter)->m_mStyleData); + + if (nullptr != pFoundElement) + return pFoundElement; } + return nullptr; + } + + void CStyleStorage::AddStyles(const std::string& sStyle, std::map& mStyleData) + { + if (sStyle.empty()) + return; + + KatanaOutput *output = katana_parse(sStyle.c_str(), sStyle.length(), KatanaParserModeStylesheet); + this->GetOutputData(output, mStyleData); + katana_destroy_output(output); + } + + void CStyleStorage::ClearEmbeddedStyles() + { + for (std::map::iterator oIter = m_mEmbeddedStyleData.begin(); oIter != m_mEmbeddedStyleData.end(); ++oIter) + if (oIter->second != nullptr) + delete oIter->second; + + m_mEmbeddedStyleData.clear(); } - inline void CCssCalculator_Private::GetStylesheet(const KatanaStylesheet *oStylesheet) + void CStyleStorage::ClearAllowedStyleFiles() + { + m_arAllowedStyleFiles.clear(); + } + + void CStyleStorage::GetStylesheet(const KatanaStylesheet* oStylesheet, std::map& mStyleData) { for (size_t i = 0; i < oStylesheet->imports.length; ++i) - GetRule((KatanaRule*)oStylesheet->imports.data[i]); + GetRule((KatanaRule*)oStylesheet->imports.data[i], mStyleData); for (size_t i = 0; i < oStylesheet->rules.length; ++i) - GetRule((KatanaRule*)oStylesheet->rules.data[i]); + GetRule((KatanaRule*)oStylesheet->rules.data[i], mStyleData); } - inline void CCssCalculator_Private::GetRule(const KatanaRule *oRule) + void CStyleStorage::GetRule(const KatanaRule* oRule, std::map& mStyleData) { if ( NULL == oRule ) return; @@ -103,7 +251,7 @@ namespace NSCSS switch (oRule->type) { case KatanaRuleStyle: { - GetStyleRule((KatanaStyleRule*)oRule); + GetStyleRule((KatanaStyleRule*)oRule, mStyleData); break; } default: @@ -111,7 +259,7 @@ namespace NSCSS } } - inline void CCssCalculator_Private::GetStyleRule(const KatanaStyleRule *oRule) + void CStyleStorage::GetStyleRule(const KatanaStyleRule* oRule, std::map& mStyleData) { if (oRule->declarations->length == 0) return; @@ -127,7 +275,7 @@ namespace NSCSS for (std::vector::reverse_iterator oWord = arWords.rbegin(); oWord != arWords.rend(); ++oWord) { - const size_t posPoint = oWord->find(L'.'); + const size_t posPoint = oWord->find(L'.'); const size_t posLattice = oWord->find(L'#'); const std::wstring sName = (posPoint != std::wstring::npos) ? oWord->substr(0, posPoint) : (posLattice != std::wstring::npos) ? oWord->substr(0, posLattice) : *oWord; @@ -143,8 +291,8 @@ namespace NSCSS { if (NULL == oFirstElement && bCreateFirst) { - const std::map::const_iterator& oFindId = m_mData.find(sId); - if (oFindId != m_mData.end()) + const std::map::const_iterator& oFindId = mStyleData.find(sId); + if (oFindId != mStyleData.end()) { oIdElement = oFindId->second; bCreateFirst = false; @@ -172,8 +320,8 @@ namespace NSCSS { if (NULL == oFirstElement && bCreateFirst) { - const std::map::const_iterator& oFindClass = m_mData.find(sClass); - if (oFindClass != m_mData.end()) + const std::map::const_iterator& oFindClass = mStyleData.find(sClass); + if (oFindClass != mStyleData.end()) { oClassElement = oFindClass->second; bCreateFirst = false; @@ -205,8 +353,8 @@ namespace NSCSS { if (NULL == oFirstElement && bCreateFirst) { - const std::map::const_iterator& oFindName = m_mData.find(sName); - if (oFindName != m_mData.end()) + const std::map::const_iterator& oFindName = mStyleData.find(sName); + if (oFindName != mStyleData.end()) { oNameElement = oFindName->second; bCreateFirst = false; @@ -238,11 +386,16 @@ namespace NSCSS oLastElement->AddProperties(mStyle); if (NULL != oFirstElement) - m_mData[oFirstElement->GetSelector()] = oFirstElement; + mStyleData[oFirstElement->GetSelector()] = oFirstElement; } } - inline std::vector CCssCalculator_Private::GetSelectorList(const KatanaArray* oSelectors) const + std::wstring CStyleStorage::GetValueList(const KatanaArray* oValues) + { + return StringifyValueList(oValues); + } + + std::vector CStyleStorage::GetSelectorList(const KatanaArray* oSelectors) const { if (oSelectors->length == 0) return std::vector(); @@ -255,7 +408,7 @@ namespace NSCSS return arSelectors; } - inline std::wstring CCssCalculator_Private::GetSelector(const KatanaSelector *oSelector) const + std::wstring CStyleStorage::GetSelector(const KatanaSelector* oSelector) const { KatanaParser oParser; oParser.options = &kKatanaDefaultOptions; @@ -274,7 +427,7 @@ namespace NSCSS return wsText; } - inline std::map CCssCalculator_Private::GetDeclarationList(const KatanaArray* oDeclarations) const + std::map CStyleStorage::GetDeclarationList(const KatanaArray* oDeclarations) const { if(oDeclarations->length == 0) return std::map(); @@ -287,7 +440,7 @@ namespace NSCSS return arDeclarations; } - inline std::pair CCssCalculator_Private::GetDeclaration(const KatanaDeclaration* oDecl) const + std::pair CStyleStorage::GetDeclaration(const KatanaDeclaration* oDecl) const { std::wstring sValueList = StringifyValueList(oDecl->values); @@ -297,63 +450,69 @@ namespace NSCSS return std::make_pair(UTF8_TO_U(std::string(oDecl->property)), sValueList); } - inline std::wstring CCssCalculator_Private::GetValueList(const KatanaArray *oValues) + void CStyleStorage::GetOutputData(KatanaOutput* oOutput, std::map& mStyleData) { - return StringifyValueList(oValues); + if ( NULL == oOutput ) + return; + + switch (oOutput->mode) { + case KatanaParserModeStylesheet: + GetStylesheet(oOutput->stylesheet, mStyleData); + break; + case KatanaParserModeRule: + GetRule(oOutput->rule, mStyleData); + break; + case KatanaParserModeKeyframeRule: + case KatanaParserModeKeyframeKeyList: + case KatanaParserModeMediaList: + case KatanaParserModeValue: + case KatanaParserModeSelector: + case KatanaParserModeDeclarationList: + break; + } } - #ifdef CSS_CALCULATOR_WITH_XHTML - CCompiledStyle CCssCalculator_Private::GetCompiledStyle(const std::vector& arSelectors, const bool& bIsSettings, const UnitMeasure& unitMeasure) + const CElement* CStyleStorage::FindSelectorFromStyleData(const std::wstring& wsSelector, const std::map& mStyleData) { - if (arSelectors.empty()) - return CCompiledStyle(); + std::map::const_iterator itFound = mStyleData.find(wsSelector); - SetUnitMeasure(unitMeasure); + if (mStyleData.cend() != itFound) + return itFound->second; - if (!bIsSettings) - { - const std::map, CCompiledStyle*>::iterator oItem = m_mUsedStyles.find(arSelectors); - - if (oItem != m_mUsedStyles.end()) - return *oItem->second; - } - else if (NULL == m_mStatictics || m_mStatictics->empty()) - { - CCompiledStyle oStyle; - oStyle.SetDpi(m_nDpi); - oStyle.SetUnitMeasure(m_UnitMeasure); - oStyle.SetID(arSelectors.back().m_wsName + ((!arSelectors.back().m_wsClass.empty()) ? L'.' + arSelectors.back().m_wsClass : L"") + ((arSelectors.back().m_wsId.empty()) ? L"" : L'#' + arSelectors.back().m_wsId) + L'-' + std::to_wstring(++m_nCountNodes)); - - oStyle.SetSizeDeviceWindow(m_oDeviceWindow); - oStyle.SetSizeSourceWindow(m_oSourceWindow); - - return oStyle; - } + return nullptr; + } - CCompiledStyle *pStyle = new CCompiledStyle(); + CCssCalculator_Private::CCssCalculator_Private() : m_nDpi(96), m_nCountNodes(0), m_sEncoding(L"UTF-8"){} - pStyle->SetDpi(m_nDpi); - pStyle->SetUnitMeasure(m_UnitMeasure); + CCssCalculator_Private::~CCssCalculator_Private() + {} - pStyle->SetSizeDeviceWindow(m_oDeviceWindow); - pStyle->SetSizeSourceWindow(m_oSourceWindow); + #ifdef CSS_CALCULATOR_WITH_XHTML + void CCssCalculator_Private::SetPageData(NSProperties::CPage &oPage, const std::map &mData, unsigned int unLevel, bool bHardMode) + { + //TODO:: пересмотреть данный метод + m_oStyleStorage.SetPageData(oPage, mData, unLevel, bHardMode); + } - std::vector arWords; - arWords.reserve(arSelectors.size() * 2); + std::map CCssCalculator_Private::GetPageData(const std::wstring &wsPageName) + { + return m_oStyleStorage.GetPageData(wsPageName); + } - std::vector arNextNodes; - arNextNodes.reserve(arSelectors.size() * 2); + void CCssCalculator_Private::ClearPageData() + { + m_oStyleStorage.ClearPageData(); + } + #endif + std::vector CCssCalculator_Private::CalculateAllNodes(const std::vector &arSelectors) + { + std::vector arNodes; + for (std::vector::const_reverse_iterator oNode = arSelectors.rbegin(); oNode != arSelectors.rend(); ++oNode) { - arWords.push_back(oNode->m_wsName); - - //TODO:: проверить данный момент -// if (oNode->m_sName == L"td") -// pStyle->m_oMargin.SetPermission(false); - - if (oNode->m_wsName == L"table") - pStyle->m_oBorder.Block(); + if (!oNode->m_wsName.empty()) + arNodes.push_back(oNode->m_wsName); if (!oNode->m_wsClass.empty()) { @@ -361,440 +520,240 @@ namespace NSCSS { std::vector arClasses = NS_STATIC_FUNCTIONS::GetWordsW(oNode->m_wsClass, false, L" "); - if (arClasses.size() > 1) - arClasses.resize(unique(arClasses.begin(),arClasses.end()) - arClasses.begin()); - switch (arClasses.size()) - { - case 1: - { - arWords.push_back(L'.' + arClasses[0]); - break; - } - case 2: - { - arWords.push_back(L'.' + arClasses[0] + L" ." + arClasses[1]); - break; - } - case 3: - { - arWords.push_back(L'.' + arClasses[0] + L" ." + arClasses[1] + L" ." + arClasses[2]); - break; - } - default: - { - arWords.push_back(std::accumulate(arClasses.begin(), arClasses.end(), std::wstring(), - [](std::wstring sRes, const std::wstring& sClass) - {return sRes += L'.' + sClass + L' ';})); - break; - } - } + arNodes.push_back(std::accumulate(arClasses.begin(), arClasses.end(), std::wstring(), + [](std::wstring sRes, const std::wstring& sClass) + {return sRes += L'.' + sClass + L' ';})); } else - arWords.push_back(L'.' + oNode->m_wsClass); + arNodes.push_back(L'.' + oNode->m_wsClass); } + if (!oNode->m_wsId.empty()) - arWords.push_back(L'#' + oNode->m_wsId); + arNodes.push_back(L'#' + oNode->m_wsId); } - std::vector arElements; - - for (size_t i = 0; i < arSelectors.size(); ++i) - { - std::wstring sName, sId; - std::vector arClasses; + return arNodes; + } - if (arWords.back()[0] == L'#') - { - sId = arWords.back(); - arWords.pop_back(); - arNextNodes.push_back(sId); - } + void CCssCalculator_Private::FindPrevAndKindElements(const CElement *pElement, const std::vector &arNextNodes, std::vector& arFindedElements, const std::wstring &wsName, const std::vector &arClasses) + { + if (arNextNodes.empty()) + return; - if (arWords.back()[0] == L'.') - { - arClasses = NS_STATIC_FUNCTIONS::GetWordsW(arWords.back(), false, L" "); - arNextNodes.push_back(arWords.back()); - arWords.pop_back(); - } + const std::vector arTempPrev = pElement->GetPrevElements(arNextNodes.crbegin() + 1, arNextNodes.crend()); + const std::vector arTempKins = pElement->GetNextOfKin(wsName, arClasses); - sName = arWords.back(); - arWords.pop_back(); - arNextNodes.push_back(sName); - pStyle->AddParent(sName); + if (!arTempPrev.empty()) + arFindedElements.insert(arFindedElements.end(), arTempPrev.begin(), arTempPrev.end()); - const std::map::const_iterator oFindName = m_mData.find(sName); - std::map::const_iterator oFindId; - std::vector arFindElements; + if (!arTempKins.empty()) + arFindedElements.insert(arFindedElements.end(), arTempKins.begin(), arTempKins.end()); + } - if (!sId.empty()) - { - oFindId = m_mData.find(sId); + std::vector CCssCalculator_Private::FindElements(std::vector &arNodes, std::vector &arNextNodes) + { + if (arNodes.empty()) + return {}; - if (oFindId != m_mData.end() && NULL != m_mStatictics) - { - std::map::const_iterator oFindCountId = m_mStatictics->find(StatistickElement{StatistickElement::IsId, sId}); + std::vector arFindedElements; - if ((m_mStatictics->end() != oFindCountId) && - (((bIsSettings && oFindCountId->second < MaxNumberRepetitions) || - (!bIsSettings && oFindCountId->second >= MaxNumberRepetitions)))) - { - if (!oFindId->second->Empty()) - arFindElements.push_back(oFindId->second); - } + std::wstring wsName, wsId; + std::vector arClasses; - const std::vector arTempPrev = oFindId->second->GetPrevElements(arNextNodes.rbegin() + ((arClasses.empty()) ? 1 : 2), arNextNodes.rend()); + if (!arNodes.empty() && arNodes.back()[0] == L'#') + { + wsId = arNodes.back(); + arNodes.pop_back(); + arNextNodes.push_back(wsId); + } - if (!arTempPrev.empty()) - arFindElements.insert(arFindElements.end(), arTempPrev.begin(), arTempPrev.end()); - } - } + if (!arNodes.empty() && arNodes.back()[0] == L'.') + { + arClasses = NS_STATIC_FUNCTIONS::GetWordsW(arNodes.back(), false, L" "); + arNextNodes.push_back(arNodes.back()); + arNodes.pop_back(); + } - if (!arClasses.empty()) - { - if (!bIsSettings) - { - for (std::vector::const_reverse_iterator iClass = arClasses.rbegin(); iClass != arClasses.rend(); ++iClass) - { - const std::map::const_iterator oFindClass = m_mData.find(*iClass); - if (oFindClass != m_mData.end()) - { - if (!oFindClass->second->Empty()) - arFindElements.push_back(oFindClass->second); + if (!arNodes.empty()) + { + wsName = arNodes.back(); + arNodes.pop_back(); + arNextNodes.push_back(wsName); + } - const std::vector arTempPrev = oFindClass->second->GetPrevElements(arNextNodes.rbegin() + 2, arNextNodes.rend()); - const std::vector arTempKins = oFindClass->second->GetNextOfKin(sName); + if (!wsId.empty()) + { + const CElement* pFoundId = m_oStyleStorage.FindElement(wsId); - if (!arTempPrev.empty()) - arFindElements.insert(arFindElements.end(), arTempPrev.begin(), arTempPrev.end()); + if(nullptr != pFoundId) + { + if (!pFoundId->Empty()) + arFindedElements.push_back(pFoundId); - if (!arTempKins.empty()) - arFindElements.insert(arFindElements.end(), arTempKins.begin(), arTempKins.end()); - } - } - } + FindPrevAndKindElements(pFoundId, arNextNodes, arFindedElements, wsName); } + } - if (oFindName != m_mData.end()) + if (!arClasses.empty()) + { + for (std::vector::const_reverse_iterator iClass = arClasses.rbegin(); iClass != arClasses.rend(); ++iClass) { - if (!bIsSettings) - { - if (!oFindName->second->Empty()) - arFindElements.push_back(oFindName->second); + const CElement* pFoundClass = m_oStyleStorage.FindElement(*iClass); - const std::vector arTempPrev = oFindName->second->GetPrevElements(arNextNodes.rbegin() + 1, arNextNodes.rend()); - const std::vector arTempKins = oFindName->second->GetNextOfKin(sName, arClasses); - - if (!arTempPrev.empty()) - arFindElements.insert(arFindElements.end(), arTempPrev.begin(), arTempPrev.end()); + if (nullptr != pFoundClass) + { + if (!pFoundClass->Empty()) + arFindedElements.push_back(pFoundClass); - if (!arTempKins.empty()) - arFindElements.insert(arFindElements.end(), arTempKins.begin(), arTempKins.end()); + FindPrevAndKindElements(pFoundClass, arNextNodes, arFindedElements, wsName); } } + } + const CElement* pFoundName = m_oStyleStorage.FindElement(wsName); - if (arFindElements.size() > 1) - { - std::sort(arFindElements.rbegin(), arFindElements.rend(), - [](CElement* oFirstElement, CElement* oSecondElement) - { - return oFirstElement->GetWeight() > oSecondElement->GetWeight(); - }); - } - - pStyle->AddStyle(arSelectors[i].m_mAttributes, i + 1); - - for (const CElement* oElement : arFindElements) - pStyle->AddStyle(oElement->GetStyle(), i + 1); - - if (NULL != m_mStatictics) - { - std::map::const_iterator oFindCountStyle = m_mStatictics->find(StatistickElement{StatistickElement::IsStyle, arSelectors[i].m_wsStyle}); + if (nullptr != pFoundName) + { + if (!pFoundName->Empty()) + arFindedElements.push_back(pFoundName); - if (oFindCountStyle != m_mStatictics->end()) - { - if ((bIsSettings && oFindCountStyle->second < MaxNumberRepetitions) || - (!bIsSettings && oFindCountStyle->second >= MaxNumberRepetitions)) - pStyle->AddStyle(arSelectors[i].m_wsStyle, i + 1, true); - else if (!bIsSettings) - pStyle->AddStyle(arSelectors[i].m_wsStyle, i + 1, true); - } - else if (bIsSettings) - pStyle->AddStyle(arSelectors[i].m_wsStyle, i + 1, true); - } - else - pStyle->AddStyle(arSelectors[i].m_wsStyle, i + 1, true); + FindPrevAndKindElements(pFoundName, arNextNodes, arFindedElements, wsName, arClasses); } - if (!bIsSettings) + if (arFindedElements.size() > 1) { - pStyle->SetID(arSelectors.back().m_wsName + ((!arSelectors.back().m_wsClass.empty()) ? L'.' + arSelectors.back().m_wsClass : L"") + ((arSelectors.back().m_wsId.empty()) ? L"" : L'#' + arSelectors.back().m_wsId) + L'-' + std::to_wstring(++m_nCountNodes)); - m_mUsedStyles[arSelectors] = pStyle; + std::sort(arFindedElements.rbegin(), arFindedElements.rend(), + [](const CElement* oFirstElement, const CElement* oSecondElement) + { return oFirstElement->GetWeight() > oSecondElement->GetWeight(); }); } - return *pStyle; + return arFindedElements; } - bool CCssCalculator_Private::GetCompiledStyle(CCompiledStyle &oStyle, const std::vector &arSelectors, const bool &bIsSettings, const UnitMeasure &unitMeasure) + #ifdef CSS_CALCULATOR_WITH_XHTML + CCompiledStyle CCssCalculator_Private::GetCompiledStyle(const std::vector& arSelectors) { if (arSelectors.empty()) - return false; + return CCompiledStyle(); - SetUnitMeasure(unitMeasure); + CCompiledStyle oStyle; - if (!bIsSettings) - { - const std::map, CCompiledStyle*>::iterator oItem = m_mUsedStyles.find(arSelectors); + GetCompiledStyle(oStyle, arSelectors); - if (oItem != m_mUsedStyles.end()) - { - oStyle = *oItem->second; - return true; - } - } - else if (NULL == m_mStatictics || m_mStatictics->empty()) - { - oStyle.SetDpi(m_nDpi); - oStyle.SetUnitMeasure(m_UnitMeasure); - oStyle.SetID(arSelectors.back().m_wsName + ((!arSelectors.back().m_wsClass.empty()) ? L'.' + arSelectors.back().m_wsClass : L"") + ((arSelectors.back().m_wsId.empty()) ? L"" : L'#' + arSelectors.back().m_wsId) + L'-' + std::to_wstring(++m_nCountNodes)); - - oStyle.SetSizeDeviceWindow(m_oDeviceWindow); - oStyle.SetSizeSourceWindow(m_oSourceWindow); + return oStyle; + } + bool CCssCalculator_Private::GetCompiledStyle(CCompiledStyle &oStyle, const std::vector &arSelectors) + { + if (arSelectors.empty()) return false; - } - - oStyle.SetDpi(m_nDpi); - oStyle.SetUnitMeasure(m_UnitMeasure); - oStyle.SetSizeDeviceWindow(m_oDeviceWindow); - oStyle.SetSizeSourceWindow(m_oSourceWindow); + const std::map, CCompiledStyle>::iterator oItem = m_mUsedStyles.find(arSelectors); - std::vector arWords; - arWords.reserve(arSelectors.size() * 2); - - std::vector arNextNodes; - arNextNodes.reserve(arSelectors.size() * 2); - - for (std::vector::const_reverse_iterator oNode = arSelectors.rbegin(); oNode != arSelectors.rend(); ++oNode) + if (oItem != m_mUsedStyles.end()) { - arWords.push_back(oNode->m_wsName); - -// if (oNode->m_sName == L"td") -// oStyle.m_pMargin.SetPermission(false); - - if (oNode->m_wsName == L"table") - oStyle.m_oBorder.Block(); - - if (!oNode->m_wsClass.empty()) - { - if (oNode->m_wsClass.find(L' ') != std::wstring::npos) - { - std::vector arClasses = NS_STATIC_FUNCTIONS::GetWordsW(oNode->m_wsClass, false, L" "); - - if (arClasses.size() > 1) - arClasses.resize(unique(arClasses.begin(),arClasses.end()) - arClasses.begin()); - switch (arClasses.size()) - { - case 1: - { - arWords.push_back(L'.' + arClasses[0]); - break; - } - case 2: - { - arWords.push_back(L'.' + arClasses[0] + L" ." + arClasses[1]); - break; - } - case 3: - { - arWords.push_back(L'.' + arClasses[0] + L" ." + arClasses[1] + L" ." + arClasses[2]); - break; - } - default: - { - arWords.push_back(std::accumulate(arClasses.begin(), arClasses.end(), std::wstring(), - [](std::wstring sRes, const std::wstring& sClass) - {return sRes += L'.' + sClass + L' ';})); - break; - } - } - } - else - arWords.push_back(L'.' + oNode->m_wsClass); - } - if (!oNode->m_wsId.empty()) - arWords.push_back(L'#' + oNode->m_wsId); + oStyle = oItem->second; + return true; } - std::vector arElements; + oStyle.SetDpi(m_nDpi); + std::vector arNodes = CalculateAllNodes(arSelectors); + std::vector arPrevNodes; + bool bInTable = false; + for (size_t i = 0; i < arSelectors.size(); ++i) { - std::wstring sName, sId; - std::vector arClasses; + oStyle.AddParent(arSelectors[i].m_wsName); - if (arWords.back()[0] == L'#') - { - sId = arWords.back(); - arWords.pop_back(); - arNextNodes.push_back(sId); - } + if (!bInTable) + bInTable = IsTableElement(arSelectors[i].m_wsName); - if (arWords.back()[0] == L'.') + if (bInTable) { - arClasses = NS_STATIC_FUNCTIONS::GetWordsW(arWords.back(), false, L" "); - arNextNodes.push_back(arWords.back()); - arWords.pop_back(); + oStyle.m_oBackground.Clear(); + oStyle.m_oBorder.Clear(); } - sName = arWords.back(); - arWords.pop_back(); - arNextNodes.push_back(sName); - oStyle.AddParent(sName); - - const std::map::const_iterator oFindName = m_mData.find(sName); - std::map::const_iterator oFindId; - std::vector arFindElements; + CCompiledStyle oTempStyle; - if (!sId.empty()) - { - oFindId = m_mData.find(sId); + oTempStyle.AddStyle(arSelectors[i].m_mAttributes, i + 1); - if (oFindId != m_mData.end() && NULL != m_mStatictics) - { - std::map::const_iterator oFindCountId = m_mStatictics->find(StatistickElement{StatistickElement::IsId, sId}); + for (const CElement* oElement : FindElements(arNodes, arPrevNodes)) + oTempStyle.AddStyle(oElement->GetStyle(), i + 1); - if ((m_mStatictics->end() != oFindCountId) && - (((bIsSettings && oFindCountId->second < MaxNumberRepetitions) || - (!bIsSettings && oFindCountId->second >= MaxNumberRepetitions)))) - { - if (!oFindId->second->Empty()) - arFindElements.push_back(oFindId->second); - } + if (!arSelectors[i].m_wsStyle.empty()) + oTempStyle.AddStyle(arSelectors[i].m_wsStyle, i + 1, true); - const std::vector arTempPrev = oFindId->second->GetPrevElements(arNextNodes.rbegin() + ((arClasses.empty()) ? 1 : 2), arNextNodes.rend()); + oStyle += oTempStyle; - if (!arTempPrev.empty()) - arFindElements.insert(arFindElements.end(), arTempPrev.begin(), arTempPrev.end()); - } - } - - if (!arClasses.empty()) + // Скидываем некоторые внешние стили, которые внутри таблицы переопределяются + if (bInTable && i < arSelectors.size() - 1) { - if (!bIsSettings) - { - for (std::vector::const_reverse_iterator iClass = arClasses.rbegin(); iClass != arClasses.rend(); ++iClass) - { - const std::map::const_iterator oFindClass = m_mData.find(*iClass); - if (oFindClass != m_mData.end()) - { - if (!oFindClass->second->Empty()) - arFindElements.push_back(oFindClass->second); - - const std::vector arTempPrev = oFindClass->second->GetPrevElements(arNextNodes.rbegin() + 2, arNextNodes.rend()); - const std::vector arTempKins = oFindClass->second->GetNextOfKin(sName); - - if (!arTempPrev.empty()) - arFindElements.insert(arFindElements.end(), arTempPrev.begin(), arTempPrev.end()); - - if (!arTempKins.empty()) - arFindElements.insert(arFindElements.end(), arTempKins.begin(), arTempKins.end()); - } - } - } + oStyle.m_oFont.GetLineHeight().Clear(); + oStyle.m_oPadding.Clear(); + oStyle.m_oMargin.Clear(); } + } - if (oFindName != m_mData.end()) - { - if (!bIsSettings) - { - if (!oFindName->second->Empty()) - arFindElements.push_back(oFindName->second); + oStyle.SetID(CalculateStyleId(arSelectors.back())); - const std::vector arTempPrev = oFindName->second->GetPrevElements(arNextNodes.rbegin() + 1, arNextNodes.rend()); - const std::vector arTempKins = oFindName->second->GetNextOfKin(sName, arClasses); + if (!oStyle.Empty()) + m_mUsedStyles[arSelectors] = oStyle; - if (!arTempPrev.empty()) - arFindElements.insert(arFindElements.end(), arTempPrev.begin(), arTempPrev.end()); + return true; + } - if (!arTempKins.empty()) - arFindElements.insert(arFindElements.end(), arTempKins.begin(), arTempKins.end()); - } - } + std::wstring CCssCalculator_Private::CalculateStyleId(const CNode& oNode) + { + return oNode.m_wsName + ((!oNode.m_wsClass.empty()) ? L'.' + oNode.m_wsClass : L"") + ((oNode.m_wsId.empty()) ? L"" : L'#' + oNode.m_wsId) + L'-' + std::to_wstring(++m_nCountNodes); + } + bool CCssCalculator_Private::CalculatePageStyle(NSProperties::CPage &oPageData, const std::vector &arSelectors) + { + if (arSelectors.empty()) + return false; - if (arFindElements.size() > 1) + std::vector arNodes = CalculateAllNodes(arSelectors); + std::vector arNextNodes; + + for (size_t i = 0; i < arSelectors.size(); ++i) + { + if (!arSelectors[i].m_wsStyle.empty() && std::wstring::npos != arSelectors[i].m_wsStyle.find(L"page")) { - std::sort(arFindElements.rbegin(), arFindElements.rend(), - [](CElement* oFirstElement, CElement* oSecondElement) - { - return oFirstElement->GetWeight() > oSecondElement->GetWeight(); - }); + std::map mRules = NS_STATIC_FUNCTIONS::GetRules(arSelectors[i].m_wsStyle); + if (mRules.end() != mRules.find(L"page")) + SetPageData(oPageData, GetPageData(mRules[L"page"]), i + 1, true); } - if (NULL != m_mStatictics) + for (const CElement* oElement : FindElements(arNodes, arNextNodes)) { - std::map::const_iterator oFindCountStyle = m_mStatictics->find(StatistickElement{StatistickElement::IsStyle, arSelectors[i].m_wsStyle}); - - if (oFindCountStyle != m_mStatictics->end()) - { - if ((bIsSettings && oFindCountStyle->second < MaxNumberRepetitions) || - (!bIsSettings && oFindCountStyle->second >= MaxNumberRepetitions)) - oStyle.AddStyle(arSelectors[i].m_wsStyle, i + 1, true); - else if (!bIsSettings) - oStyle.AddStyle(arSelectors[i].m_wsStyle, i + 1, true); - } - else if (bIsSettings) - oStyle.AddStyle(arSelectors[i].m_wsStyle, i + 1, true); + std::map mRules = oElement->GetStyle(); + if (mRules.end() != mRules.find(L"page")) + SetPageData(oPageData, GetPageData(mRules[L"page"]), i + 1, true); } - else - oStyle.AddStyle(arSelectors[i].m_wsStyle, i + 1, true); - - for (const CElement* oElement : arFindElements) - oStyle.AddStyle(oElement->GetStyle(), i + 1); - - oStyle.AddStyle(arSelectors[i].m_mAttributes, i + 1); - } - - if (!bIsSettings) - { - oStyle.SetID(arSelectors.back().m_wsName + ((!arSelectors.back().m_wsClass.empty()) ? L'.' + arSelectors.back().m_wsClass : L"") + ((arSelectors.back().m_wsId.empty()) ? L"" : L'#' + arSelectors.back().m_wsId) + L'-' + std::to_wstring(++m_nCountNodes)); - CCompiledStyle *pTemp = new CCompiledStyle(oStyle); - - m_mUsedStyles[arSelectors] = pTemp; + if (arSelectors[i].m_mAttributes.end() != arSelectors[i].m_mAttributes.find(L"page")) + SetPageData(oPageData, GetPageData(arSelectors[i].m_mAttributes.at(L"page")), i + 1, false); } - + return true; } #endif - void CCssCalculator_Private::AddStyles(const std::string &sStyle) - { - if (sStyle.empty()) - return; - KatanaOutput *output = katana_parse(sStyle.c_str(), sStyle.length(), KatanaParserModeStylesheet); - this->GetOutputData(output); - katana_destroy_output(output); + void CCssCalculator_Private::AddStyles(const std::string& sStyle) + { + m_oStyleStorage.AddStyles(sStyle); } - void CCssCalculator_Private::AddStyles(const std::wstring &wsStyle) + void CCssCalculator_Private::AddStyles(const std::wstring& wsStyle) { - if (wsStyle.empty()) - return; - - AddStyles(U_TO_UTF8(wsStyle)); + m_oStyleStorage.AddStyles(wsStyle); } void CCssCalculator_Private::AddStylesFromFile(const std::wstring& wsFileName) { - if (std::find(m_arFiles.begin(), m_arFiles.end(), wsFileName) != m_arFiles.end()) - return; - - m_arFiles.push_back(wsFileName); - - AddStyles(NS_STATIC_FUNCTIONS::GetContentAsUTF8(wsFileName)); + m_oStyleStorage.AddStylesFromFile(wsFileName); } void CCssCalculator_Private::SetDpi(unsigned short int nValue) @@ -802,52 +761,28 @@ namespace NSCSS m_nDpi = nValue; } - void CCssCalculator_Private::SetBodyTree(const CTree &oTree) - { - if (NULL == m_mStatictics) - m_mStatictics = new std::map(); - - CTree::CountingNumberRepetitions(oTree, *m_mStatictics); - } - - void CCssCalculator_Private::SetSizeSourceWindow(const CSizeWindow &oSizeWindow) - { - m_oSourceWindow = oSizeWindow; - } - - void CCssCalculator_Private::SetSizeDeviceWindow(const CSizeWindow &oSizeWindow) - { - m_oDeviceWindow = oSizeWindow; - } - - CSizeWindow CCssCalculator_Private::GetSizeSourceWindow() const - { - return m_oSourceWindow; - } - - CSizeWindow CCssCalculator_Private::GetSizeDeviceWindow() const + unsigned short int CCssCalculator_Private::GetDpi() const { - return m_oDeviceWindow; + return m_nDpi; } - void CCssCalculator_Private::SetUnitMeasure(const UnitMeasure& nType) + void CCssCalculator_Private::ClearEmbeddedStyles() { - m_UnitMeasure = nType; - } + m_oStyleStorage.ClearEmbeddedStyles(); - unsigned short int CCssCalculator_Private::GetDpi() const - { - return m_nDpi; + #ifdef CSS_CALCULATOR_WITH_XHTML + m_mUsedStyles.clear(); + #endif } - const std::map *CCssCalculator_Private::GetData() const + void CCssCalculator_Private::ClearAllowedStyleFiles() { - return &m_mData; + m_oStyleStorage.ClearAllowedStyleFiles(); } - UnitMeasure CCssCalculator_Private::GetUnitMeasure() const + void CCssCalculator_Private::ClearStylesFromFile(const std::wstring& wsFilePath) { - return m_UnitMeasure; + m_oStyleStorage.ClearStylesFromFile(wsFilePath); } std::wstring CCssCalculator_Private::GetEncoding() const @@ -859,15 +794,22 @@ namespace NSCSS { m_sEncoding = L"UTF-8"; m_nDpi = 96; - m_UnitMeasure = Point; - m_mData.clear(); - m_arFiles.clear(); + m_oStyleStorage.Clear(); + + #ifdef CSS_CALCULATOR_WITH_XHTML + m_mUsedStyles.clear(); + #endif + } - m_oDeviceWindow.Clear(); - m_oSourceWindow.Clear(); + bool IsTableElement(const std::wstring& wsNameTag) + { + return L"td" == wsNameTag || L"tr" == wsNameTag || L"table" == wsNameTag || + L"tbody" == wsNameTag || L"thead" == wsNameTag || L"tfoot" == wsNameTag || + L"th" == wsNameTag; } } + inline static std::wstring StringifyValueList(const KatanaArray* oValues) { if (NULL == oValues) diff --git a/Common/3dParty/html/css/src/CCssCalculator_Private.h b/Common/3dParty/html/css/src/CCssCalculator_Private.h index 7d0e0bfd47c..617812e0679 100644 --- a/Common/3dParty/html/css/src/CCssCalculator_Private.h +++ b/Common/3dParty/html/css/src/CCssCalculator_Private.h @@ -3,11 +3,9 @@ #include #include -#include -#include +#include #include "CElement.h" -#include "ConstValues.h" -#include "CUnitMeasureConverter.h" +#include "StyleProperties.h" #include "../../katana-parser/src/katana.h" #ifdef CSS_CALCULATOR_WITH_XHTML @@ -16,31 +14,58 @@ namespace NSCSS { - class CCssCalculator_Private + class CStyleStorage { - unsigned short int m_nDpi; - unsigned short int m_nCountNodes; - UnitMeasure m_UnitMeasure; + public: + CStyleStorage(); + ~CStyleStorage(); - std::list m_arFiles; + void Clear(); - std::map m_mData; + void AddStyles(const std::string& sStyle); + void AddStyles(const std::wstring& wsStyle); + void AddStylesFromFile(const std::wstring& wsFileName); - std::map *m_mStatictics; // Количество повторений свойств id и style у селекторов + void ClearEmbeddedStyles(); + void ClearAllowedStyleFiles(); + void ClearStylesFromFile(const std::wstring& wsFileName); #ifdef CSS_CALCULATOR_WITH_XHTML - std::map, CCompiledStyle*> m_mUsedStyles; + void AddPageData(const std::wstring& wsPageName, const std::wstring& wsStyles); + void SetPageData(NSProperties::CPage& oPage, const std::map& mData, unsigned int unLevel, bool bHardMode = false); + std::map GetPageData(const std::wstring& wsPageName); + void ClearPageData(); #endif - std::wstring m_sEncoding; + const CElement* FindElement(const std::wstring& wsSelector); + private: + typedef struct + { + std::wstring m_wsStyleFilepath; + std::map m_mStyleData; + } TStyleFileData; - CSizeWindow m_oSourceWindow; - CSizeWindow m_oDeviceWindow; + std::set m_arEmptyStyleFiles; + std::set m_arAllowedStyleFiles; + std::vector m_arStyleFiles; + std::map m_mEmbeddedStyleData; - void GetStylesheet(const KatanaStylesheet* oStylesheet); - void GetRule(const KatanaRule* oRule); + #ifdef CSS_CALCULATOR_WITH_XHTML + typedef struct + { + std::vector m_wsNames; + std::map m_mData; + } TPageData; + + std::vector m_arPageDatas; + #endif + private: + void AddStyles(const std::string& sStyle, std::map& mStyleData); - void GetStyleRule(const KatanaStyleRule* oRule); + void GetStylesheet(const KatanaStylesheet* oStylesheet, std::map& mStyleData); + void GetRule(const KatanaRule* oRule, std::map& mStyleData); + + void GetStyleRule(const KatanaStyleRule* oRule, std::map& mStyleData); std::wstring GetValueList(const KatanaArray* oValues); @@ -50,39 +75,60 @@ namespace NSCSS std::map GetDeclarationList(const KatanaArray* oDeclarations) const; std::pair GetDeclaration(const KatanaDeclaration* oDecl) const; - void GetOutputData(KatanaOutput* oOutput); + void GetOutputData(KatanaOutput* oOutput, std::map& mStyleData); + const CElement* FindSelectorFromStyleData(const std::wstring& wsSelector, const std::map& mStyleData); + }; + + class CCssCalculator_Private + { + unsigned short int m_nDpi; + unsigned short int m_nCountNodes; + + CStyleStorage m_oStyleStorage; + + #ifdef CSS_CALCULATOR_WITH_XHTML + std::map, CCompiledStyle> m_mUsedStyles; + + void SetPageData(NSProperties::CPage& oPage, const std::map& mData, unsigned int unLevel, bool bHardMode = false); + std::map GetPageData(const std::wstring &wsPageName); + #endif + + void FindPrevAndKindElements(const CElement* pElement, const std::vector& arNextNodes, std::vector& arFindedElements, const std::wstring& wsName, const std::vector& arClasses = {}); + + std::wstring m_sEncoding; public: CCssCalculator_Private(); ~CCssCalculator_Private(); #ifdef CSS_CALCULATOR_WITH_XHTML - CCompiledStyle GetCompiledStyle(const std::vector &arSelectors, const bool& bIsSettings = false, const UnitMeasure& unitMeasure = Point); - bool GetCompiledStyle(CCompiledStyle& oStyle, const std::vector &arSelectors, const bool& bIsSettings = false, const UnitMeasure& unitMeasure = Point); + CCompiledStyle GetCompiledStyle(const std::vector &arSelectors); + bool GetCompiledStyle(CCompiledStyle& oStyle, const std::vector &arSelectors); + + std::wstring CalculateStyleId(const CNode& oNode); + bool CalculatePageStyle(NSProperties::CPage& oPageData, const std::vector &arSelectors); + + void ClearPageData(); #endif + std::vector CalculateAllNodes(const std::vector& arSelectors); + std::vector FindElements(std::vector& arNodes, std::vector& arNextNodes); + void AddStyles(const std::string& sStyle); void AddStyles(const std::wstring& wsStyle); void AddStylesFromFile(const std::wstring& wsFileName); - void SetUnitMeasure(const UnitMeasure& nType); void SetDpi(unsigned short int nValue); - void SetBodyTree(const CTree &oTree); - - void SetSizeSourceWindow(const CSizeWindow& oSizeWindow); - void SetSizeDeviceWindow(const CSizeWindow& oSizeWindow); - CSizeWindow GetSizeSourceWindow() const; - CSizeWindow GetSizeDeviceWindow() const; - - UnitMeasure GetUnitMeasure() const; std::wstring GetEncoding() const; unsigned short int GetDpi() const; - const std::map* GetData() const; - + void ClearEmbeddedStyles(); + void ClearAllowedStyleFiles(); + void ClearStylesFromFile(const std::wstring& wsFilePath); void Clear(); - }; + + inline bool IsTableElement(const std::wstring& wsNameTag); } #endif // CCSSCALCULATOR_PRIVATE_H diff --git a/Common/3dParty/html/css/src/CElement.cpp b/Common/3dParty/html/css/src/CElement.cpp index 2d33e11a128..1ceda93ff49 100644 --- a/Common/3dParty/html/css/src/CElement.cpp +++ b/Common/3dParty/html/css/src/CElement.cpp @@ -40,6 +40,7 @@ namespace NSCSS { m_sSelector = sSelector; m_sFullSelector = m_sSelector; + UpdateWeight(); } void NSCSS::CElement::AddPropertie(const std::wstring &sName, const std::wstring& sValue) @@ -67,6 +68,7 @@ namespace NSCSS m_arPrevElements.push_back(oPrevElement); oPrevElement->m_sFullSelector += L' ' + m_sFullSelector; + UpdateWeight(); } void CElement::AddKinElement(CElement *oKinElement) @@ -76,6 +78,7 @@ namespace NSCSS m_arKinElements.push_back(oKinElement); oKinElement->m_sFullSelector += m_sFullSelector; + oKinElement->UpdateWeight(); } std::map CElement::GetStyle() const @@ -173,26 +176,26 @@ namespace NSCSS return arElements; } - std::vector CElement::GetPrevElements(const std::vector::reverse_iterator &arNodesRBegin, const std::vector::reverse_iterator &arNodesREnd) const + std::vector CElement::GetPrevElements(const std::vector::const_reverse_iterator& oNodesRBegin, const std::vector::const_reverse_iterator& oNodesREnd) const { - if (arNodesRBegin >= arNodesREnd || m_arPrevElements.empty()) + if (oNodesRBegin >= oNodesREnd || m_arPrevElements.empty()) return std::vector(); std::vector arElements; - for (std::vector::reverse_iterator iWord = arNodesRBegin; iWord != arNodesREnd; ++iWord) + for (std::vector::const_reverse_iterator iWord = oNodesRBegin; iWord != oNodesREnd; ++iWord) { if ((*iWord)[0] == L'.' && ((*iWord).find(L" ") != std::wstring::npos)) { std::vector arClasses = NS_STATIC_FUNCTIONS::GetWordsW(*iWord, false, L" "); - for (std::wstring sClass : arClasses) + for (const std::wstring& wsClass : arClasses) { for (CElement* oPrevElement : m_arPrevElements) { - if (oPrevElement->m_sSelector == sClass) + if (oPrevElement->m_sSelector == wsClass) { arElements.push_back(oPrevElement); - std::vector arTempElements = oPrevElement->GetPrevElements(iWord + 1, arNodesREnd); + std::vector arTempElements = oPrevElement->GetPrevElements(iWord + 1, oNodesREnd); arElements.insert(arElements.end(), arTempElements.begin(), arTempElements.end()); } } @@ -205,7 +208,7 @@ namespace NSCSS if (oPrevElement->m_sSelector == *iWord) { arElements.push_back(oPrevElement); - std::vector arTempElements = oPrevElement->GetPrevElements(iWord + 1, arNodesREnd); + std::vector arTempElements = oPrevElement->GetPrevElements(iWord + 1, oNodesREnd); arElements.insert(arElements.end(), arTempElements.begin(), arTempElements.end()); // return arElements; } @@ -230,11 +233,14 @@ namespace NSCSS return NULL; } - std::vector CElement::GetWeight() + void CElement::UpdateWeight() { if (m_arWeight.empty()) m_arWeight = NS_STATIC_FUNCTIONS::GetWeightSelector(m_sFullSelector); + } + std::vector CElement::GetWeight() const + { return m_arWeight; } diff --git a/Common/3dParty/html/css/src/CElement.h b/Common/3dParty/html/css/src/CElement.h index 1669b07d90f..9844b27cc6f 100644 --- a/Common/3dParty/html/css/src/CElement.h +++ b/Common/3dParty/html/css/src/CElement.h @@ -39,12 +39,13 @@ namespace NSCSS std::map GetFullStyle(const std::vector& arSelectors) const; std::map GetFullStyle(const std::vector& arNodes) const; std::vector GetNextOfKin(const std::wstring& sName, const std::vector& arClasses = {}) const; - std::vector GetPrevElements(const std::vector::reverse_iterator &arNodesRBegin, const std::vector::reverse_iterator &arNodesREnd) const; + std::vector GetPrevElements(const std::vector::const_reverse_iterator& oNodesRBegin, const std::vector::const_reverse_iterator& oNodesREnd) const; std::map GetConvertStyle(const std::vector& arNodes) const; CElement *FindPrevElement(const std::wstring& sSelector) const; - std::vector GetWeight(); + void UpdateWeight(); + std::vector GetWeight() const; void IncreasedWeight(); }; } diff --git a/Common/3dParty/html/css/src/CNode.cpp b/Common/3dParty/html/css/src/CNode.cpp index 8b2cdc27b8b..2799e375c3c 100644 --- a/Common/3dParty/html/css/src/CNode.cpp +++ b/Common/3dParty/html/css/src/CNode.cpp @@ -5,7 +5,7 @@ namespace NSCSS CNode::CNode() {} - CNode::CNode(std::wstring wsName, std::wstring wsClass, std::wstring wsId) + CNode::CNode(const std::wstring& wsName, const std::wstring& wsClass, const std::wstring& wsId) : m_wsName(wsName), m_wsClass(wsClass), m_wsId(wsId) {} @@ -14,6 +14,15 @@ namespace NSCSS return m_wsName.empty() && m_wsClass.empty() && m_wsId.empty() && m_wsStyle.empty(); } + void CNode::Clear() + { + m_wsName .clear(); + m_wsClass .clear(); + m_wsId .clear(); + m_wsStyle .clear(); + m_mAttributes.clear(); + } + std::vector CNode::GetData() const { std::vector arValues; diff --git a/Common/3dParty/html/css/src/CNode.h b/Common/3dParty/html/css/src/CNode.h index a7c7de05393..d8f6d8e4f04 100644 --- a/Common/3dParty/html/css/src/CNode.h +++ b/Common/3dParty/html/css/src/CNode.h @@ -18,10 +18,12 @@ namespace NSCSS public: CNode(); - CNode(std::wstring wsName, std::wstring wsClass, std::wstring wsId); + CNode(const std::wstring& wsName, const std::wstring& wsClass, const std::wstring& wsId); bool Empty() const; + void Clear(); + std::vector GetData() const; bool operator< (const CNode& oNode) const; bool operator== (const CNode& oNode) const; diff --git a/Common/3dParty/html/css/src/CUnitMeasureConverter.cpp b/Common/3dParty/html/css/src/CUnitMeasureConverter.cpp index 19659e995f1..3f80a95ed5a 100644 --- a/Common/3dParty/html/css/src/CUnitMeasureConverter.cpp +++ b/Common/3dParty/html/css/src/CUnitMeasureConverter.cpp @@ -14,23 +14,21 @@ namespace NSCSS { switch (enUnitMeasure) { - case NSCSS::Pixel: - return dValue; case NSCSS::Point: - return 72. / (double)ushDPI * dValue; + return dValue * 72. / (double)ushDPI; case NSCSS::Cantimeter: return dValue / (double)ushDPI * 2.54; case NSCSS::Millimeter: return dValue / (double)ushDPI * 25.4; case NSCSS::Inch: - return 1. / (double)ushDPI * dValue; + return dValue / (double)ushDPI; case NSCSS::Peak: - return 0.16667 / (double)ushDPI * dValue; + return dValue * 6. / (double)ushDPI; // 1 дюйм = 6 пик case NSCSS::Twips: - return (dValue / (double)ushDPI) * 144.; + return dValue * 1440. / (double)ushDPI; + default: + return dValue; } - - return 0.; } double CUnitMeasureConverter::ConvertCm(double dValue, UnitMeasure enUnitMeasure, unsigned short ushDPI) @@ -38,22 +36,20 @@ namespace NSCSS switch (enUnitMeasure) { case NSCSS::Point: - return 28.35 * dValue; + return dValue * 28.3465 ; // 1 см = (2.54 / 72) пункта case NSCSS::Pixel: - return (double)ushDPI / 2.54 * dValue; - case NSCSS::Cantimeter: - return dValue; + return dValue * (double)ushDPI / 2.54; case NSCSS::Millimeter: return dValue * 10.; case NSCSS::Inch: - return dValue / 2.54f; + return dValue / 2.54; // 1 дюйм = 2.54 см case NSCSS::Peak: - return 2.36 * dValue; + return dValue * 2.36; // 2.36 = 6 / 2.54 case NSCSS::Twips: - return (dValue) * 0.3937 * (double)ushDPI; + return dValue * 567.; // 1 см = (1440 / 2.54) твипов + default: + return dValue; } - - return 0.; } double CUnitMeasureConverter::ConvertMm(double dValue, NSCSS::UnitMeasure enUnitMeasure, unsigned short ushDPI) @@ -61,22 +57,20 @@ namespace NSCSS switch (enUnitMeasure) { case NSCSS::Point: - return 2.835 * dValue; + return dValue * 2.8346; // 1 мм = (25.4 / 72) пункта case NSCSS::Pixel: - return (double)ushDPI / 25.4 * dValue; + return dValue * (double)ushDPI / 25.4; case NSCSS::Cantimeter: return dValue / 10.; - case NSCSS::Millimeter: - return dValue; case NSCSS::Inch: return dValue / 25.4; case NSCSS::Peak: - return 0.236 * dValue; + return dValue * 0.236; // 0.236 = 6 / 25.4 case NSCSS::Twips: - return (dValue / 10.) * 0.3937 * (double)ushDPI; + return dValue * 56.7; + default: + return dValue; } - - return 0.; } double CUnitMeasureConverter::ConvertIn(double dValue, NSCSS::UnitMeasure enUnitMeasure, unsigned short ushDPI) @@ -84,45 +78,41 @@ namespace NSCSS switch (enUnitMeasure) { case NSCSS::Point: - return dValue / 6.; + return dValue / 72.; case NSCSS::Pixel: return dValue * (double)ushDPI; case NSCSS::Cantimeter: - return dValue * 2.54; + return dValue * 2.54; // 1 дюйм = 2.54 см case NSCSS::Millimeter: return dValue * 25.4; - case NSCSS::Inch: - return dValue; case NSCSS::Peak: - return dValue / 72.; + return dValue * 6.; case NSCSS::Twips: - return dValue * 144.; + return dValue * 1440.; + default: + return dValue; } - - return 0.; } double CUnitMeasureConverter::ConvertPt(double dValue, NSCSS::UnitMeasure enUnitMeasure, unsigned short ushDPI) { switch (enUnitMeasure) { - case NSCSS::Point: - return dValue; case NSCSS::Pixel: - return (double)ushDPI / 72. * dValue; + return dValue * (double)ushDPI / 72.; case NSCSS::Cantimeter: - return dValue * 0.03528; + return dValue * 0.03528; // 0.03528 = 2.54 / 72 case NSCSS::Millimeter: return dValue * 0.3528; case NSCSS::Inch: - return dValue / 72.; + return dValue / 72.; // 1 дюйм = 72 пункта case NSCSS::Peak: - return dValue / 12.; + return dValue * 0.0833; // 0.0833 = 6 / 72 (1 пункт = 1/72 дюйма) case NSCSS::Twips: - return (dValue / 72.) * 144.; + return dValue * 20.; // 20 = 1440 / 72 + default: + return dValue; } - - return 0.; } double CUnitMeasureConverter::ConvertPc(double dValue, NSCSS::UnitMeasure enUnitMeasure, unsigned short ushDPI) @@ -130,27 +120,49 @@ namespace NSCSS switch (enUnitMeasure) { case NSCSS::Point: - return dValue * 12.; + return dValue * 12.; // 12 = 72 / 6 case NSCSS::Pixel: - return (double)ushDPI / 6. * dValue; + return dValue * (double)ushDPI / 6.; // 1 дюйм = 6 пика case NSCSS::Cantimeter: - return dValue * 0.423; + return dValue * 0.423; // 0.423 = 2.54 / 6 case NSCSS::Millimeter: - return dValue * 4.23; + return dValue * 4.233; // 4.23 = 25.4 / 6 case NSCSS::Inch: return dValue / 6.; + case NSCSS::Twips: + return dValue * 3.333; // 3.333 = 20 / 6 + default: + return dValue; + } + } + + double CUnitMeasureConverter::ConvertTw(double dValue, UnitMeasure enUnitMeasure, unsigned short ushDPI) + { + switch (enUnitMeasure) + { + case NSCSS::Point: + return dValue * 0.05; // 0.05 = 72. / 1440. + case NSCSS::Pixel: + return dValue * (double)ushDPI / 1440.; // 1 дюйм = 1440 твипов + case NSCSS::Cantimeter: + return dValue * 0.001764; // 0.001764 = 2.54 / 1440 + case NSCSS::Millimeter: + return dValue * 0.01764; + case NSCSS::Inch: + return dValue * 1440.; case NSCSS::Peak: + return dValue * 0.004167; // 0.004167 = 6 / 1440 + default: return dValue; - case NSCSS::Twips: - return dValue * 24.; } - - return 0.; } bool CUnitMeasureConverter::GetValue(const std::wstring &wsValue, double &dValue, UnitMeasure &enUnitMeasure) { - std::wregex oRegex(LR"((-?\.\d+|-?\d+(\.\d+)?)\s*(px|pt|cm|mm|in|pc|%|em|rem)?)"); + if (wsValue.empty() || wsValue.end() == std::find_if(wsValue.begin(), wsValue.end(), [](wchar_t wChar) { return iswdigit(wChar);})) + return false; + + std::wregex oRegex(LR"((-?\.\d+|-?\d+(\.\d+)?)\s*(px|pt|cm|mm|in|pc|%|em|rem|tw)?)"); std::wsmatch oMatches; if(!std::regex_search(wsValue, oMatches, oRegex)) @@ -176,6 +188,8 @@ namespace NSCSS enUnitMeasure = Em; else if (L"rem" == oMatches[3]) enUnitMeasure = Rem; + else if (L"tw" == oMatches[3]) + enUnitMeasure = Twips; else enUnitMeasure = None; diff --git a/Common/3dParty/html/css/src/CUnitMeasureConverter.h b/Common/3dParty/html/css/src/CUnitMeasureConverter.h index f8a87e946c9..f6180f95b6d 100644 --- a/Common/3dParty/html/css/src/CUnitMeasureConverter.h +++ b/Common/3dParty/html/css/src/CUnitMeasureConverter.h @@ -30,6 +30,7 @@ namespace NSCSS static double ConvertIn(double dValue, UnitMeasure enUnitMeasure, unsigned short ushDPI); static double ConvertPt(double dValue, UnitMeasure enUnitMeasure, unsigned short ushDPI); static double ConvertPc(double dValue, UnitMeasure enUnitMeasure, unsigned short ushDPI); + static double ConvertTw(double dValue, UnitMeasure enUnitMeasure, unsigned short ushDPI); static bool GetValue(const std::wstring& wsValue, double& dValue, UnitMeasure& enUnitMeasure); }; diff --git a/Common/3dParty/html/css/src/ConstValues.cpp b/Common/3dParty/html/css/src/ConstValues.cpp index 9ebcd733d37..83d78fba90a 100644 --- a/Common/3dParty/html/css/src/ConstValues.cpp +++ b/Common/3dParty/html/css/src/ConstValues.cpp @@ -2,51 +2,6 @@ namespace NSCSS { - CSizeWindow::CSizeWindow() - : m_ushWidth(0), m_ushHeight(0) - {} - - CSizeWindow::CSizeWindow(unsigned short unWidth, unsigned short unHeight) - : m_ushWidth(unWidth), m_ushHeight(unHeight) - {} - - bool CSizeWindow::Empty() const - { - return ((0 == m_ushWidth) && (0 == m_ushHeight)); - } - - void CSizeWindow::Clear() - { - m_ushWidth = m_ushHeight = 0; - } - - bool CSizeWindow::operator==(const CSizeWindow &oSizeWindow) const - { - return ((m_ushWidth == oSizeWindow.m_ushWidth) && (m_ushHeight == oSizeWindow.m_ushHeight)); - } - - bool CSizeWindow::operator!=(const CSizeWindow &oSizeWindow) const - { - return ((m_ushWidth != oSizeWindow.m_ushWidth) || (m_ushHeight != oSizeWindow.m_ushHeight)); - } - - bool StatistickElement::operator<(const StatistickElement &oStatistickElement) const - { - return sValue < oStatistickElement.sValue; - } - - void CTree::CountingNumberRepetitions(const CTree &oTree, std::map &mStatictics) - { - if (!oTree.m_oNode.m_wsId.empty()) - ++mStatictics[StatistickElement{StatistickElement::IsId, L'#' + oTree.m_oNode.m_wsId}]; - if (!oTree.m_oNode.m_wsStyle.empty()) - ++mStatictics[StatistickElement{StatistickElement::IsStyle, oTree.m_oNode.m_wsStyle}]; - - if (!oTree.m_arrChild.empty()) - for (const CTree& oChildren : oTree.m_arrChild) - CountingNumberRepetitions(oChildren, mStatictics); - } - namespace NSConstValues { const std::map COLORS @@ -98,7 +53,7 @@ namespace NSCSS {L"deepskyblue", L"00BFFF"}, {L"dodgerblue", L"1E90FF"}, {L"cornflowerblue",L"6495ED"}, {L"mediumdlateblue", L"7B68EE"}, {L"royalblue", L"4169E1"}, {L"blue", L"0000FF"}, {L"LightCoral", L"#F08080"}, {L"LightCoral", L"#F08080"}, {L"LightCoral", L"#F08080"}, {L"mediumblue", L"0000CD"}, {L"darkblue", L"00008B"}, {L"navy", L"000080"}, - {L"midnightblue", L"191970"}, + {L"midnightblue", L"191970"}, {L"navyblue", L"A0B0E0"}, /* White tones */ {L"white", L"FFFFFF"}, {L"snow", L"FFFAFA"}, {L"honeydew", L"F0FFF0"}, {L"mintcream", L"F5FFFA"}, {L"azure", L"F0FFFF"}, {L"aliceblue", L"F0F8FF"}, @@ -110,7 +65,7 @@ namespace NSCSS {L"gainsboro", L"DCDCDC"}, {L"lightgray", L"D3D3D3"}, {L"silver", L"C0C0C0"}, {L"darkgray", L"A9A9A9"}, {L"gray", L"808080"}, {L"dimgray", L"696969"}, {L"lightslategray", L"778899"}, {L"slategray", L"708090"}, {L"darkslategray", L"2F4F4F"}, - {L"black", L"000000"}, + {L"black", L"000000"}, {L"grey", L"808080"}, /* Outdated */ {L"windowtext", L"000000"}, {L"transparent", L"000000"} }; diff --git a/Common/3dParty/html/css/src/ConstValues.h b/Common/3dParty/html/css/src/ConstValues.h index 145aa1caa71..de5a434faac 100644 --- a/Common/3dParty/html/css/src/ConstValues.h +++ b/Common/3dParty/html/css/src/ConstValues.h @@ -16,41 +16,6 @@ namespace NSCSS ScalingDirectionY = 2 } ScalingDirection; - struct CSizeWindow - { - unsigned short m_ushWidth; - unsigned short m_ushHeight; - - CSizeWindow(); - CSizeWindow(unsigned short unWidth, unsigned short unHeight); - - bool Empty() const; - void Clear(); - - bool operator==(const CSizeWindow& oSizeWindow) const; - bool operator!=(const CSizeWindow& oSizeWindow) const; - }; - - struct StatistickElement - { - enum TypeElement - { - IsStyle = 0, - IsId - } m_enType; - std::wstring sValue; - - bool operator<(const StatistickElement& oStatistickElement) const; - }; - - struct CTree - { - NSCSS::CNode m_oNode; - std::vector m_arrChild; - - static void CountingNumberRepetitions(const CTree &oTree, std::map &mStatictics); - }; - namespace NSConstValues { extern const std::map COLORS; @@ -61,66 +26,69 @@ namespace NSCSS { typedef enum { - B_CustomStyle = 0, - B_StyleId = 1, - B_Type = 2, - B_Default = 3, - - B_Name = 4, - B_BasedOn = 5, - B_QFormat = 6, - B_Link = 7, - B_UnhideWhenUsed = 8, - B_UiPriority = 9, + B_CustomStyle, + B_StyleId, + B_Type, + B_Default, + + B_Name, + B_BasedOn, + B_QFormat, + B_Link, + B_UnhideWhenUsed, + B_UiPriority, + B_SemiHidden } BasicProperties; typedef enum { - P_Jc = 0, - P_Spacing = 1, - P_ContextualSpacing = 2, - P_Ind = 3, - P_OutlineLvl = 4, - P_Shd = 5, + P_Jc, + P_Spacing, + P_ContextualSpacing, + P_Ind, + P_OutlineLvl, + P_Shd, // - P_TopBorder = 6, - P_LeftBorder = 7, - P_BottomBorder = 8, - P_RightBorder = 9, + P_TopBorder, + P_LeftBorder, + P_BottomBorder, + P_RightBorder, // - P_KeepLines = 10, - P_KeepNext = 11, + P_KeepLines, + P_KeepNext, } ParagraphProperties; typedef enum { - R_RFonts = 0, - R_Sz = 1, - R_B = 2, - R_I = 3, - R_Color = 4, - R_U = 5, - R_Highlight = 6, - R_SmallCaps = 7 + R_RFonts , + R_Sz, + R_B, + R_I, + R_Color, + R_U, + R_Highlight, + R_Shd, + R_SmallCaps, + R_Kern } RunnerProperties; typedef enum { - T_TblInd = 0, + T_TblInd , // - T_CellTop = 1, - T_CellLeft = 2, - T_CellBottom = 3, - T_CellRight = 4, + T_CellTop, + T_CellLeft, + T_CellBottom, + T_CellRight, // // - T_BorderTop = 5, - T_BorderLeft = 6, - T_BorderBottom = 7, - T_BorderRight = 8, - T_BorderInsideH = 9, - T_BorderInsideV = 10 + T_BorderTop , + T_BorderLeft, + T_BorderBottom, + T_BorderRight, + T_BorderInsideH, + T_BorderInsideV // } TableProperties; } diff --git a/Common/3dParty/html/css/src/StaticFunctions.cpp b/Common/3dParty/html/css/src/StaticFunctions.cpp index d9e9bad05d8..4ef042783bf 100644 --- a/Common/3dParty/html/css/src/StaticFunctions.cpp +++ b/Common/3dParty/html/css/src/StaticFunctions.cpp @@ -48,7 +48,6 @@ namespace NS_STATIC_FUNCTIONS if (sEncoding.empty()) sEncoding = "utf-8"; - if (!sEncoding.empty() && sEncoding != "utf-8" && sEncoding != "UTF-8") { NSUnicodeConverter::CUnicodeConverter oConverter; @@ -80,6 +79,52 @@ namespace NS_STATIC_FUNCTIONS return arValues; } + std::vector ParseCSSPropertie(const std::wstring& wsInput) + { + std::vector arResult; + std::wstring wsCurrent; + bool bInQuotes = false; + bool bInFunction = false; + int nParenDepth = 0; + + for (wchar_t c : wsInput) + { + if (c == ' ' && !bInQuotes && !bInFunction) + { + if (!wsCurrent.empty()) + { + arResult.push_back(wsCurrent); + wsCurrent.clear(); + } + } + else if (c == '"' || c == '\'') + { + bInQuotes = !bInQuotes; + wsCurrent += c; + } + else if (c == '(') + { + bInFunction = true; + nParenDepth++; + wsCurrent += c; + } + else if (c == ')') + { + nParenDepth--; + if (nParenDepth == 0) + bInFunction = false; + wsCurrent += c; + } + else + wsCurrent += c; + } + + if (!wsCurrent.empty()) + arResult.push_back(wsCurrent); + + return arResult; + } + std::vector GetWordsW(const std::wstring& wsLine, bool bWithSigns, const std::wstring& wsDelimiters) { if (wsLine.empty()) @@ -95,12 +140,15 @@ namespace NS_STATIC_FUNCTIONS while (std::wstring::npos != unEnd) { - arWords.emplace_back(wsLine.data() + unStart, unEnd - unStart + ((bWithSigns) ? 1 : 0)); + if (unStart != unEnd) + arWords.emplace_back(wsLine.data() + unStart, unEnd - unStart + ((bWithSigns) ? 1 : 0)); + unStart = wsLine.find_first_not_of(wsDelimiters, unEnd); unEnd = wsLine.find_first_of(wsDelimiters, unStart); } - arWords.emplace_back(wsLine.data() + unStart); + if (std::wstring::npos != unStart) + arWords.emplace_back(wsLine.data() + unStart); return arWords; } @@ -140,42 +188,43 @@ namespace NS_STATIC_FUNCTIONS std::map GetRules(const std::wstring& wsStyles) { - if (wsStyles.empty()) - return {}; + std::wregex oCssPropertyRegex(L"([a-zA-Z-]+)\\s*:\\s*([^;\t\n\r\f\v]+)"); + std::wsmatch oMatch; - std::map mRules; + std::wstring::const_iterator oSearchStart(wsStyles.cbegin()); - std::wstring::const_iterator oStartProperty = std::find_if_not(wsStyles.begin(), wsStyles.end(), std::iswspace); - std::wstring::const_iterator oEndProperty, oStartValue, oEndValue; + std::map mRules; - while (wsStyles.end() != oStartProperty) + while (std::regex_search(oSearchStart, wsStyles.cend(), oMatch, oCssPropertyRegex)) { - oEndProperty = std::find_if(oStartProperty, wsStyles.end(), [](const wchar_t &wcChar){ return L':' == wcChar;}); - oStartValue = std::find_if_not(oEndProperty + 1, wsStyles.end(), std::iswspace); - - if (wsStyles.end() == oEndProperty || wsStyles.end() == oStartValue) - break; - - oEndValue = std::find_if(oStartValue, wsStyles.end(), [](const wchar_t &wcChar){ return L';' == wcChar;}); - - mRules.insert({std::wstring(oStartProperty, oEndProperty), std::wstring(oStartValue, oEndValue)}); - - if (wsStyles.end() == oEndValue) - break; - - oStartProperty = std::find_if_not(oEndValue + 1, wsStyles.end(), std::iswspace); + mRules.insert(std::make_pair(oMatch[1], oMatch[2])); + oSearchStart = oMatch.suffix().first; } return mRules; } - std::wstring RemoveSpaces(std::wstring &wsString) + void RemoveSpaces(std::wstring &wsString) { std::wstring::const_iterator ciStart = std::find_if_not(wsString.begin(), wsString.end(), std::iswspace); + if (ciStart == wsString.end()) - return L""; + return wsString.clear(); + std::wstring::const_reverse_iterator criEnd = std::find_if_not(wsString.rbegin(),wsString.rend(), std::iswspace); - return std::wstring(ciStart, criEnd.base()); + + wsString = std::wstring(ciStart, criEnd.base()); + } + + double CalculatePersentage(const std::wstring &wsValue, double dRelativeValue) + { + double dValue = ReadDouble(wsValue); + + if (std::wstring::npos != wsValue.find(L'%')) + return dValue / 100. * dRelativeValue; + + return dValue; } + } } diff --git a/Common/3dParty/html/css/src/StaticFunctions.h b/Common/3dParty/html/css/src/StaticFunctions.h index 2a4759e1570..2bb29fe20e4 100644 --- a/Common/3dParty/html/css/src/StaticFunctions.h +++ b/Common/3dParty/html/css/src/StaticFunctions.h @@ -20,11 +20,14 @@ namespace NSCSS double ReadDouble(const std::wstring& wsValue); std::vector ReadDoubleValues(const std::wstring& wsValue); + std::vector ParseCSSPropertie(const std::wstring& wsInput); std::vector GetWordsW(const std::wstring& wsLine, bool bWithSigns = false, const std::wstring& wsDelimiters = L" \n\r\t\f\v:;,!"); std::vector GetWeightSelector(const std::wstring& sSelector); std::map GetRules(const std::wstring& wsStyles); - std::wstring RemoveSpaces(std::wstring& wsString); + void RemoveSpaces(std::wstring& wsString); + + double CalculatePersentage(const std::wstring& wsValue, double dRelativeValue); } #define SWITCH(str) switch(SWITCH_CASE::str_hash_for_switch(str)) diff --git a/Common/3dParty/html/css/src/StyleProperties.cpp b/Common/3dParty/html/css/src/StyleProperties.cpp index c055a8f1714..69426ca486d 100644 --- a/Common/3dParty/html/css/src/StyleProperties.cpp +++ b/Common/3dParty/html/css/src/StyleProperties.cpp @@ -3,6 +3,7 @@ #include "StaticFunctions.h" #include "ConstValues.h" #include +#include #include namespace NSCSS @@ -24,7 +25,7 @@ namespace NSCSS } CString::CString() - : CValue(L"", 0, false) + : CValue(L"", 0, false) {} CString::CString(const std::wstring &wsValue, unsigned int unLevel, bool bImportant) @@ -38,13 +39,17 @@ namespace NSCSS std::wstring wsNewValue = wsValue; - bool bImportant = CutImportant(wsNewValue); + const bool bImportant{CutImportant(wsNewValue)}; if (m_bImportant && !bImportant) return false; + if (UINT_MAX == unLevel) + m_unLevel++; + else + m_unLevel = unLevel; + m_oValue = wsNewValue; - m_unLevel = unLevel; m_bImportant = bImportant; return true; @@ -57,15 +62,19 @@ namespace NSCSS std::wstring wsNewValue = wsValue; - bool bImportant = CutImportant(wsNewValue); + const bool bImportant{CutImportant(wsNewValue)}; if (m_bImportant && !bImportant) return false; - if (arValiableValues.end() != std::find(arValiableValues.begin(), arValiableValues.end(), wsNewValue))\ + if (arValiableValues.end() != std::find(arValiableValues.begin(), arValiableValues.end(), wsNewValue)) { + if (UINT_MAX == unLevel) + m_unLevel++; + else + m_unLevel = unLevel; + m_oValue = wsNewValue; - m_unLevel = unLevel; m_bImportant = bImportant; return true; @@ -81,7 +90,7 @@ namespace NSCSS std::wstring wsNewValue = wsValue; - bool bImportant = CutImportant(wsNewValue); + const bool bImportant{CutImportant(wsNewValue)}; if (m_bImportant && !bImportant) return false; @@ -90,8 +99,12 @@ namespace NSCSS if (arValiableValues.end() != oFoundValue) { + if (UINT_MAX == unLevel) + m_unLevel++; + else + m_unLevel = unLevel; + m_oValue = oFoundValue->second; - m_unLevel = unLevel; m_bImportant = bImportant; return true; @@ -108,6 +121,8 @@ namespace NSCSS void CString::Clear() { m_oValue.clear(); + m_unLevel = 0; + m_bImportant = false; } int CString::ToInt() const @@ -148,15 +163,15 @@ namespace NSCSS case Millimeter: return CUnitMeasureConverter::ConvertMm(m_oValue, enUnitMeasure, 96); case Inch: return CUnitMeasureConverter::ConvertIn(m_oValue, enUnitMeasure, 96); case Peak: return CUnitMeasureConverter::ConvertPc(m_oValue, enUnitMeasure, 96); + case Twips: return CUnitMeasureConverter::ConvertTw(m_oValue, enUnitMeasure, 96); case Em: case Rem: return m_oValue * dPrevValue; - case None: - case Twips: return m_oValue; + case None: return m_oValue; } } CDigit::CDigit() - : CValue(DBL_MIN, 0, false), m_enUnitMeasure(None) + : CValue(DBL_MAX, 0, false), m_enUnitMeasure(None) {} CDigit::CDigit(double dValue) @@ -169,17 +184,20 @@ namespace NSCSS bool CDigit::Empty() const { - return DBL_MIN == m_oValue; + return DBL_MAX == m_oValue; } bool CDigit::Zero() const { - return (std::abs(m_oValue) <= DBL_EPSILON); + return (std::abs(0. - m_oValue) <= DBL_EPSILON); } void CDigit::Clear() { - m_oValue = DBL_MIN; + m_oValue = DBL_MAX; + m_unLevel = 0; + m_enUnitMeasure = None; + m_bImportant = false; } void CDigit::ConvertTo(UnitMeasure enUnitMeasure, double dPrevValue) @@ -190,7 +208,7 @@ namespace NSCSS int CDigit::ToInt() const { - if (DBL_MIN == m_oValue) + if (Empty()) return 0; return static_cast(m_oValue + 0.5); @@ -198,7 +216,7 @@ namespace NSCSS double CDigit::ToDouble() const { - if (DBL_MIN == m_oValue) + if (Empty()) return 0.; return m_oValue; @@ -206,7 +224,7 @@ namespace NSCSS std::wstring CDigit::ToWString() const { - if (DBL_MIN == m_oValue) + if (DBL_MAX == m_oValue) return std::wstring(); return std::to_wstring(m_oValue); @@ -214,7 +232,7 @@ namespace NSCSS int CDigit::ToInt(UnitMeasure enUnitMeasure, double dPrevValue) const { - if (DBL_MIN == m_oValue) + if (DBL_MAX == m_oValue) return 0; return static_cast(ConvertValue(dPrevValue, enUnitMeasure) + 0.5); @@ -222,7 +240,7 @@ namespace NSCSS double CDigit::ToDouble(UnitMeasure enUnitMeasure, double dPrevValue) const { - if (DBL_MIN == m_oValue) + if (DBL_MAX == m_oValue) return 0; return ConvertValue(dPrevValue, enUnitMeasure); @@ -230,8 +248,8 @@ namespace NSCSS std::wstring CDigit::ToWString(UnitMeasure enUnitMeasure, double dPrevValue) const { - if (DBL_MIN == m_oValue) - return 0; + if (DBL_MAX == m_oValue) + return std::wstring(); return std::to_wstring(ConvertValue(dPrevValue, enUnitMeasure)); } @@ -248,7 +266,19 @@ namespace NSCSS bool CDigit::operator==(const CDigit &oDigit) const { - return (std::abs(oDigit.m_oValue - m_oValue) <= DBL_EPSILON); + return (Empty() && oDigit.Empty()) || + ((std::abs(oDigit.m_oValue - m_oValue) <= DBL_EPSILON) && + m_enUnitMeasure == oDigit.m_enUnitMeasure); + } + + bool CDigit::operator!=(const double &oValue) const + { + return (std::abs(oValue - m_oValue) > DBL_EPSILON); + } + + bool CDigit::operator!=(const CDigit &oDigit) const + { + return (std::abs(oDigit.m_oValue - m_oValue) > DBL_EPSILON); } CDigit CDigit::operator+(const CDigit &oDigit) const @@ -306,10 +336,19 @@ namespace NSCSS CDigit &CDigit::operator+=(const CDigit &oDigit) { - if (m_unLevel > oDigit.m_unLevel || (m_bImportant && !oDigit.m_bImportant) || DBL_MIN == oDigit.m_oValue) + if (m_unLevel > oDigit.m_unLevel || (m_bImportant && !oDigit.m_bImportant) || oDigit.Empty()) + return *this; + + if (Empty()) + { + *this = oDigit; return *this; + } + else if (NSCSS::Percent == oDigit.m_enUnitMeasure && !Empty()) + m_oValue *= oDigit.m_oValue / 100.; + else + m_oValue += oDigit.ToDouble(m_enUnitMeasure); - m_oValue += oDigit.ToDouble(m_enUnitMeasure); m_unLevel = oDigit.m_unLevel; m_bImportant = oDigit.m_bImportant; @@ -353,29 +392,61 @@ namespace NSCSS std::wstring wsNewValue = wsValue; - bool bImportant = CutImportant(wsNewValue); //TODO:: иногда мы знаем, что "!important" точно не встретится - // возможно стоит добавить ещё метод + const bool bImportant{CutImportant(wsNewValue)}; //TODO:: иногда мы знаем, что "!important" точно не встретится + // возможно стоит добавить ещё метод if (m_bImportant && !bImportant) return false; - double dNewValue; - UnitMeasure enNewUnitMeasure; + if (!CUnitMeasureConverter::GetValue(wsValue, m_oValue, m_enUnitMeasure)) + return false; + + if (UINT_MAX == unLevel) + m_unLevel++; + else + m_unLevel = unLevel; + + m_bImportant = bImportant; - if (!CUnitMeasureConverter::GetValue(wsValue, dNewValue, enNewUnitMeasure)) + return true; + } + + bool CDigit::SetValue(const CDigit &oValue) + { + if (oValue.Empty() || m_unLevel > oValue.m_unLevel || (m_bImportant && !oValue.m_bImportant)) return false; - if (Percent == enNewUnitMeasure && !Empty() && unLevel > m_unLevel) + if (Empty()) { - m_oValue *= dNewValue / 100.; + m_oValue = oValue.m_oValue; + m_enUnitMeasure = oValue.m_enUnitMeasure; } - else + else if (NSCSS::Percent == oValue.m_enUnitMeasure) { - m_oValue = dNewValue; - m_enUnitMeasure = enNewUnitMeasure; + if (m_unLevel == oValue.m_unLevel) + m_oValue = oValue.m_oValue; + else + m_oValue *= oValue.m_oValue / 100.; } + else + m_oValue = oValue.ToDouble(m_enUnitMeasure); - m_unLevel = unLevel; - m_bImportant = bImportant; + m_unLevel = oValue.m_unLevel; + m_bImportant = oValue.m_bImportant; + + return true; + } + + bool CDigit::SetValue(const double& dValue, unsigned int unLevel, bool bHardMode) + { + if (CHECK_CONDITIONS && !bHardMode) + return false; + + m_oValue = dValue; + + if (UINT_MAX == unLevel) + m_unLevel++; + else + m_unLevel = unLevel; return true; } @@ -392,6 +463,13 @@ namespace NSCSS uchBlue == oRGB.uchBlue; } + bool TRGB::operator!=(const TRGB& oRGB) const + { + return uchRed != oRGB.uchRed || + uchGreen != oRGB.uchGreen || + uchBlue != oRGB.uchBlue; + } + TRGB CColor::ConvertHEXtoRGB(const std::wstring &wsValue) { TRGB oRGB; @@ -419,30 +497,220 @@ namespace NSCSS return std::wstring(arTemp, 6); } - std::wstring CColor::CutURL(const std::wstring &wsValue) + bool CColor::operator==(const CColor& oColor) const { - if (wsValue.length() < 6) - return std::wstring(); + if (m_enType != oColor.m_enType || m_oOpacity != oColor.m_oOpacity) + return false; - size_t unBegin = wsValue.find(L"(#"); + switch(m_enType) + { + case ColorEmpty: + case ColorNone: + return true; + case ColorRGB: + return (*static_cast(m_oValue)) == (*static_cast(oColor.m_oValue)); + case ColorHEX: + return (*static_cast(m_oValue)) == (*static_cast(oColor.m_oValue)); + case ColorUrl: + return (*static_cast(m_oValue)) == (*static_cast(oColor.m_oValue)); + case ColorContextStroke: + case ColorContextFill: + return false; + } + } - if (std::wstring::npos == unBegin || unBegin < 3 || wsValue.length() - unBegin < 2) - return std::wstring(); + bool CColor::operator!=(const CColor& oColor) const + { + if (m_enType != oColor.m_enType || m_oOpacity != oColor.m_oOpacity) + return true; - std::wstring wsCopyValue(wsValue); + switch(m_enType) + { + case ColorEmpty: + case ColorNone: + return false; + case ColorRGB: + return (*static_cast(m_oValue)) != (*static_cast(oColor.m_oValue)); + case ColorHEX: + return (*static_cast(m_oValue)) != (*static_cast(oColor.m_oValue)); + case ColorUrl: + return (*static_cast(m_oValue)) != (*static_cast(oColor.m_oValue)); + case ColorContextStroke: + case ColorContextFill: + return false; + } + } - std::transform(wsCopyValue.begin(), wsCopyValue.begin() + unBegin, wsCopyValue.begin(), std::towlower); + CColor& CColor::operator =(const CColor& oColor) + { + m_enType = oColor.m_enType; + m_oOpacity = oColor.m_oOpacity; + m_unLevel = oColor.m_unLevel; - if (std::wstring::npos == wsCopyValue.find(L"url(#")) - return std::wstring(); + switch(m_enType) + { + case ColorEmpty: + case ColorNone: + break; + case ColorRGB: + { + m_oValue = new TRGB{(*static_cast(oColor.m_oValue))}; + break; + } + case ColorHEX: + { + m_oValue = new std::wstring(*static_cast(oColor.m_oValue)); + break; + } + case ColorUrl: + { + m_oValue = new CURL(*static_cast(oColor.m_oValue)); + break; + } + case ColorContextStroke: + case ColorContextFill: + break; + } - return wsCopyValue.substr(unBegin + 2, wsCopyValue.find(L')') - unBegin - 2); + return *this; + } + + CColor& CColor::operator+=(const CColor& oColor) + { + if (m_unLevel > oColor.m_unLevel || (m_bImportant && !oColor.m_bImportant) || oColor.Empty()) + return *this; + + *this = oColor; + + return *this; } CColor::CColor() - : CValue({}, 0, false), m_oOpacity(1.) + : CValue(NULL, 0, false), m_oOpacity(1.), m_enType(ColorEmpty) {} + CColor::CColor(const CColor& oColor) + : CValue(NULL, 0, false), m_oOpacity(oColor.m_oOpacity), m_enType(oColor.m_enType) + { + switch (m_enType) + { + case ColorRGB: + { + TRGB *pRGB = static_cast(oColor.m_oValue); + m_oValue = new TRGB(*pRGB); + break; + } + case ColorHEX: + { + std::wstring* pValue = static_cast(oColor.m_oValue); + m_oValue = new std::wstring(*pValue); + break; + } + case ColorUrl: + { + CURL *pURL = static_cast(oColor.m_oValue); + m_oValue = new CURL(*pURL); + break; + } + default: + break; + } + } + + CColor::~CColor() + { + Clear(); + } + + void CColor::SetEmpty(unsigned int unLevel) + { + Clear(); + m_enType = ColorEmpty; + m_unLevel = unLevel; + m_bImportant = false; + } + + void CColor::SetRGB(unsigned char uchR, unsigned char uchG, unsigned char uchB) + { + Clear(); + + m_oValue = new TRGB{uchR, uchG, uchB}; + + if (NULL == m_oValue) + return; + + m_enType = ColorRGB; + } + + void CColor::SetRGB(const TRGB &oRGB) + { + Clear(); + + m_oValue = new TRGB{oRGB}; + + if (NULL == m_oValue) + return; + + m_enType = ColorRGB; + } + + void CColor::SetHEX(const std::wstring &wsValue) + { + if (6 != wsValue.length() && 3 != wsValue.length()) + return; + + Clear(); + + if (6 == wsValue.length()) + m_oValue = new std::wstring(wsValue); + else + m_oValue = new std::wstring({wsValue[0], wsValue[0], wsValue[1], wsValue[1], wsValue[2], wsValue[2]}); + + if (NULL == m_oValue) + return; + + m_enType = ColorHEX; + } + + void CColor::SetUrl(const std::wstring &wsValue) + { + if (wsValue.empty()) + return; + + CURL *pURL = new CURL(); + + if (NULL == pURL) + return; + + if (!pURL->SetValue(wsValue)) + { + delete pURL; + return; + } + + Clear(); + + m_oValue = pURL; + m_enType = ColorUrl; + } + + void CColor::SetNone() + { + Clear(); + + m_enType = ColorNone; + } + + char NormalizeNegativeColorValue(INT nValue) + { + if (nValue > 255) + return 0xff; + else if (nValue < 0) + return (char)(std::abs(nValue) % 255); + + return (char)nValue; + } + bool CColor::SetValue(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode) { if ((CHECK_CONDITIONS && !bHardMode) || (wsValue.empty() && unLevel == m_unLevel)) @@ -450,42 +718,41 @@ namespace NSCSS if (wsValue.empty()) { - m_oValue.Clear(); - m_oValue.m_enType = ColorEmpty; - m_unLevel = unLevel; - m_bImportant = false; - return true; + SetEmpty(unLevel); + return false; } std::wstring wsNewValue(wsValue); - bool bImportant = CutImportant(wsNewValue); + const bool bImportant = CutImportant(wsNewValue); std::transform(wsNewValue.begin(), wsNewValue.end(), wsNewValue.begin(), std::towlower); + NS_STATIC_FUNCTIONS::RemoveSpaces(wsNewValue); if (m_bImportant && !bImportant) return false; + bool bResult{false}; + if (wsNewValue[0] == L'#') { - m_oValue.SetHEX(wsNewValue.substr(1, wsNewValue.length() - 1)); - m_unLevel = unLevel; - m_bImportant = bImportant; - return true; + SetHEX(wsNewValue.substr(1, wsNewValue.length() - 1)); + bResult = true; } - else if (L"none" == wsNewValue) + else if (L"none" == wsNewValue || wsNewValue == L"transparent") { - m_oValue.SetNone(); - m_unLevel = unLevel; - m_bImportant = bImportant; - return true; + SetNone(); + bResult = true; } - else if (wsNewValue == L"transparent") + else if (L"context-stroke" == wsNewValue) { - m_oValue.SetNone(); - m_unLevel = unLevel; - m_bImportant = bImportant; - return true; + Clear(); + m_enType = ColorContextStroke; + } + else if (L"context-fill" == wsNewValue) + { + Clear(); + m_enType = ColorContextFill; } else if (10 <= wsNewValue.length() && wsNewValue.substr(0, 3) == L"rgb") { @@ -494,45 +761,51 @@ namespace NSCSS if (std::wstring::npos == unEnd) return false; - std::vector arValues = NS_STATIC_FUNCTIONS::GetWordsW(wsNewValue.substr(4, unEnd - 3), false, L" (),"); + std::vector arValues = NS_STATIC_FUNCTIONS::GetWordsW(wsNewValue.substr(4, unEnd - 4), false, L" (),"); if (3 > arValues.size()) return false; - m_oValue.SetRGB(NS_STATIC_FUNCTIONS::ReadDouble(arValues[0]), - NS_STATIC_FUNCTIONS::ReadDouble(arValues[1]), - NS_STATIC_FUNCTIONS::ReadDouble(arValues[2])); + const char chRed = NormalizeNegativeColorValue(std::ceil(NS_STATIC_FUNCTIONS::CalculatePersentage(arValues[0], 255))); + const char chGreen = NormalizeNegativeColorValue(std::ceil(NS_STATIC_FUNCTIONS::CalculatePersentage(arValues[1], 255))); + const char chBlue = NormalizeNegativeColorValue(std::ceil(NS_STATIC_FUNCTIONS::CalculatePersentage(arValues[2], 255))); + + SetRGB(chRed, chGreen, chBlue); if (wsNewValue.substr(0, 4) == L"rgba" && 4 == arValues.size()) m_oOpacity.SetValue(arValues[3], unLevel, bHardMode); - m_unLevel = unLevel; - m_bImportant = bImportant; - return true; + bResult = true; } - - if (5 <= wsNewValue.length()) + else if (5 <= wsNewValue.length()) { - m_oValue.SetUrl(CutURL(wsValue)); + SetUrl(wsValue); - if (m_oValue.m_enType == ColorUrl) - { - m_unLevel = unLevel; - m_bImportant = bImportant;; - return true; - } + if (m_enType == ColorUrl) + bResult = true; } - const std::map::const_iterator oHEX = NSConstValues::COLORS.find(wsNewValue); - if (oHEX != NSConstValues::COLORS.end()) + if (!bResult) { - m_oValue.SetHEX(oHEX->second); - m_unLevel = unLevel; - m_bImportant = bImportant; - return true; + const std::map::const_iterator oHEX = NSConstValues::COLORS.find(wsNewValue); + if (oHEX != NSConstValues::COLORS.end()) + { + SetHEX(oHEX->second); + bResult = true; + } } - return false; + if (!bResult) + return false; + + m_bImportant = bImportant; + + if (UINT_MAX == unLevel) + m_unLevel++; + else + m_unLevel = unLevel; + + return true; } bool CColor::SetOpacity(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode) @@ -545,25 +818,64 @@ namespace NSCSS bool CColor::Empty() const { - return m_oValue.Empty(); + return ColorEmpty == m_enType; + } + + bool CColor::None() const + { + return ColorNone == m_enType; + } + + bool CColor::Url() const + { + return ColorUrl == m_enType; } void CColor::Clear() { - m_oValue.Clear(); + switch (m_enType) + { + case ColorRGB: + { + TRGB *pRGB = static_cast(m_oValue); + RELEASEOBJECT(pRGB); + break; + } + case ColorHEX: + { + std::wstring* pValue = static_cast(m_oValue); + RELEASEOBJECT(pValue); + break; + } + case ColorUrl: + { + CURL *pURL = static_cast(m_oValue); + RELEASEOBJECT(pURL); + break; + } + default: + break; + } + + m_enType = ColorEmpty; + m_unLevel = NULL; + m_bImportant = false; } ColorType CColor::GetType() const { - return m_oValue.m_enType; + return m_enType; } double CColor::GetOpacity() const { - if (Percent == m_oOpacity.GetUnitMeasure()) + if (m_oOpacity.Empty()) + return 1.; + + if (UnitMeasure::Percent == m_oOpacity.GetUnitMeasure()) return m_oOpacity.ToDouble() / 100.; - if (None == m_oOpacity.GetUnitMeasure() && m_oOpacity.ToDouble() <= 1.) + if (UnitMeasure::None == m_oOpacity.GetUnitMeasure() && m_oOpacity.ToDouble() <= 1.) return m_oOpacity.ToDouble(); return 1.; @@ -571,22 +883,22 @@ namespace NSCSS int CColor::ToInt() const { - switch(m_oValue.m_enType) + switch(m_enType) { case ColorRGB: { - TRGB* pRGB = static_cast(m_oValue.m_pColor); + TRGB* pRGB = static_cast(m_oValue); return RGB_TO_INT(pRGB->uchRed, pRGB->uchGreen, pRGB->uchBlue); } case ColorHEX: { - std::wstring *pValue = static_cast(m_oValue.m_pColor); + std::wstring *pValue = static_cast(m_oValue); TRGB oRGB = ConvertHEXtoRGB(*pValue); return RGB_TO_INT(oRGB.uchRed, oRGB.uchGreen, oRGB.uchBlue); } + default: + return 0; } - - return 0; } double CColor::ToDouble() const @@ -596,20 +908,72 @@ namespace NSCSS std::wstring CColor::ToWString() const { - switch(m_oValue.m_enType) + switch(m_enType) { - case ColorRGB: return ConvertRGBtoHEX(*static_cast(m_oValue.m_pColor)); - case ColorHEX: case ColorUrl: return *static_cast(m_oValue.m_pColor); + case ColorRGB: return ConvertRGBtoHEX(*static_cast(m_oValue)); + case ColorHEX: return *static_cast(m_oValue); + case ColorUrl: return static_cast(m_oValue)->GetValue(); default: return std::wstring(); } } + std::wstring CColor::ToHEX() const + { + switch(m_enType) + { + case ColorRGB: + { + TRGB* pRGB = static_cast(m_oValue); + return ConvertRGBtoHEX(*pRGB); + } + case ColorHEX: + { + std::wstring *pValue = static_cast(m_oValue); + return *pValue; + } + default: + return std::wstring(); + } + } + + std::wstring CColor::EquateToColor(const std::vector> &arColors) const + { + if (arColors.empty()) + return L"none"; + + TRGB oCurrentColor; + + switch(m_enType) + { + case ColorRGB: oCurrentColor = *static_cast(m_oValue); break; + case ColorHEX: oCurrentColor = ConvertHEXtoRGB(*static_cast(m_oValue)); break; + default: return L"none"; + } + + std::wstring wsSelectedColor; + double dMinDistance = DBL_MAX; + double dDistance; + + for (const std::pair& oColor : arColors) + { + dDistance = sqrt(pow(oCurrentColor.uchRed - oColor.first.uchRed, 2) + pow(oCurrentColor.uchGreen - oColor.first.uchGreen, 2) + pow(oCurrentColor.uchBlue - oColor.first.uchBlue, 2)); + + if (dDistance < dMinDistance) + { + dMinDistance = dDistance; + wsSelectedColor = oColor.second; + } + } + + return wsSelectedColor; + } + TRGB CColor::ToRGB() const { - switch(m_oValue.m_enType) + switch(m_enType) { - case ColorRGB: return *static_cast(m_oValue.m_pColor); - case ColorHEX: return ConvertHEXtoRGB(*static_cast(m_oValue.m_pColor)); + case ColorRGB: return *static_cast(m_oValue); + case ColorHEX: return ConvertHEXtoRGB(*static_cast(m_oValue)); default: return TRGB(); } } @@ -765,6 +1129,8 @@ namespace NSCSS break; } + default: + break; } return true; @@ -841,6 +1207,8 @@ namespace NSCSS wsValue = L"rotate("; break; } + default: + break; } return wsValue; @@ -1034,7 +1402,7 @@ namespace NSCSS bool CDisplay::SetDisplay(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode) { - return m_oHAlign.SetValue(wsValue, NSConstValues::DISPLAY_VALUES, unLevel, bHardMode); + return m_oDisplay.SetValue(wsValue, NSConstValues::DISPLAY_VALUES, unLevel, bHardMode); } const CDigit& CDisplay::GetX() const @@ -1082,8 +1450,8 @@ namespace NSCSS { m_oX += oDisplay.m_oX; m_oY += oDisplay.m_oY; - m_oWidth += oDisplay.m_oWidth; - m_oHeight += oDisplay.m_oHeight; + m_oWidth = oDisplay.m_oWidth; + m_oHeight = oDisplay.m_oHeight; m_oHAlign += oDisplay.m_oHAlign; m_oVAlign += oDisplay.m_oVAlign; m_oDisplay += oDisplay.m_oDisplay; @@ -1152,7 +1520,7 @@ namespace NSCSS } // BACKGROUND - CBackground::CBackground() : m_bInBorder(false) + CBackground::CBackground() {} void CBackground::Equation(CBackground &oFirstBackground, CBackground &oSecondBackground) @@ -1178,19 +1546,14 @@ namespace NSCSS return false; } - void CBackground::InBorder() - { - m_bInBorder = true; - } - const CColor& CBackground::GetColor() const { return m_oColor; } - - bool CBackground::IsInBorder() const + + void CBackground::Clear() { - return m_bInBorder; + m_oColor.Clear(); } bool CBackground::Empty() const @@ -1198,10 +1561,14 @@ namespace NSCSS return m_oColor.Empty(); } + bool CBackground::IsNone() const + { + return ColorType::ColorNone == m_oColor.GetType(); + } + CBackground &CBackground::operator=(const CBackground &oBackground) { m_oColor = oBackground.m_oColor; - m_bInBorder = oBackground.m_bInBorder; return *this; } @@ -1210,16 +1577,12 @@ namespace NSCSS { m_oColor += oBackground.m_oColor; - if (oBackground.m_bInBorder) - m_bInBorder = true; - return *this; } bool CBackground::operator==(const CBackground &oBackground) const { - return m_oColor == oBackground.m_oColor && - m_bInBorder == oBackground.m_bInBorder; + return m_oColor == oBackground.m_oColor; } // TRANSFORM @@ -1247,6 +1610,26 @@ namespace NSCSS return true; } + void CTransform::Translate(double dOffsetX, double dOffsetY) + { + m_oMatrix.AddValue({dOffsetX, dOffsetY}, TransformTranslate); + } + + void CTransform::Scale(double dScaleX, double dScaleY) + { + m_oMatrix.AddValue({dScaleX, dScaleY}, TransformScale); + } + + void CTransform::Rotate(double dValue) + { + m_oMatrix.AddValue({dValue}, TransformRotate); + } + + void CTransform::RotateAt(double dValue, double dX, double dY) + { + m_oMatrix.AddValue({dValue, dX, dY}, TransformRotate); + } + const CMatrix& CTransform::GetMatrix() const { return m_oMatrix; @@ -1271,9 +1654,20 @@ namespace NSCSS // BORDER SIDE CBorderSide::CBorderSide() - : m_bBlock(false) + : m_bBlock(false) {} + CBorderSide::CBorderSide(const CBorderSide& oBorderSide) + : m_oWidth(oBorderSide.m_oWidth), m_oStyle(oBorderSide.m_oStyle), m_oColor(oBorderSide.m_oColor), m_bBlock(oBorderSide.m_bBlock) + {} + + void CBorderSide::Clear() + { + m_oWidth.Clear(); + m_oStyle.Clear(); + m_oColor.Clear(); + } + void CBorderSide::Equation(CBorderSide &oFirstBorderSide, CBorderSide &oSecondBorderSide) { CDigit::Equation (oFirstBorderSide.m_oWidth, oSecondBorderSide.m_oWidth); @@ -1285,11 +1679,14 @@ namespace NSCSS { if (wsValue.empty()) return false; - + if (L"none" == wsValue) + { + SetNone(unLevel, bHardMode); return true; + } - const std::vector arValues = NS_STATIC_FUNCTIONS::GetWordsW(wsValue, false, L" "); + const std::vector arValues = NS_STATIC_FUNCTIONS::ParseCSSPropertie(wsValue); for (const std::wstring& sValue : arValues) { if (SetColor(sValue, unLevel, bHardMode)) @@ -1325,11 +1722,16 @@ namespace NSCSS return m_oWidth.SetValue(wsNewValue, unLevel, bHardMode); } + bool CBorderSide::SetWidth(const double& dValue, unsigned int unLevel, bool bHardMode) + { + return m_oWidth.SetValue(dValue, unLevel, bHardMode); + } + bool CBorderSide::SetStyle(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode) { return m_oStyle.SetValue(wsValue, {std::make_pair(L"dotted", L"dotted"), std::make_pair(L"dashed", L"dashed"), std::make_pair(L"solid", L"single"), std::make_pair(L"double", L"double"), std::make_pair(L"groove", L"threeDEmboss"), std::make_pair(L"ridge", L"threeDEngrave"), - std::make_pair(L"inset", L"thinThickMediumGap"), std::make_pair(L"outset", L"thickThinMediumGap")}, unLevel, bHardMode); + std::make_pair(L"inset", L"inset"), std::make_pair(L"outset", L"outset")}, unLevel, bHardMode); } bool CBorderSide::SetColor(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode) @@ -1337,6 +1739,13 @@ namespace NSCSS return m_oColor.SetValue(wsValue, unLevel, bHardMode); } + void CBorderSide::SetNone(unsigned int unLevel, bool bHardMode) + { + SetColor(L"#ffffff", unLevel, bHardMode); + SetStyle(L"solid", unLevel, bHardMode); + SetWidth(L"0",unLevel,bHardMode); + } + void CBorderSide::Block() { m_bBlock = true; @@ -1377,14 +1786,24 @@ namespace NSCSS bool CBorderSide::Empty() const { - return (m_oWidth.Empty() || m_oWidth == 0) && m_oStyle.Empty() && m_oColor.Empty(); + return m_oWidth.Empty() || m_oColor.None(); + } + + bool CBorderSide::Zero() const + { + return m_oWidth.Zero(); + } + + bool CBorderSide::Valid() const + { + return !m_oWidth.Empty() && !m_oWidth.Zero(); } CBorderSide &CBorderSide::operator+=(const CBorderSide &oBorderSide) { - m_oWidth += oBorderSide.m_oWidth; - m_oStyle += oBorderSide.m_oStyle; - m_oColor += oBorderSide.m_oColor; + m_oWidth = oBorderSide.m_oWidth; + m_oStyle = oBorderSide.m_oStyle; + m_oColor = oBorderSide.m_oColor; if (oBorderSide.m_bBlock) m_bBlock = true; @@ -1399,9 +1818,55 @@ namespace NSCSS m_oColor == oBorderSide.m_oColor; } + bool CBorderSide::operator!=(const CBorderSide& oBorderSide) const + { + return m_oWidth != oBorderSide.m_oWidth || + m_oStyle != oBorderSide.m_oStyle || + m_oColor != oBorderSide.m_oColor; + } + + CBorderSide &CBorderSide::operator =(const CBorderSide &oBorderSide) + { + m_oWidth = oBorderSide.m_oWidth; + m_oStyle = oBorderSide.m_oStyle; + m_oColor = oBorderSide.m_oColor; + + return *this; + } + // BORDER CBorder::CBorder() - {} + { + m_enCollapse.SetMapping({{L"collapse", BorderCollapse::Collapse}, {L"separate", BorderCollapse::Separate}}, BorderCollapse::Separate); + } + + void CBorder::Clear() + { + ClearLeftSide(); + ClearTopSide(); + ClearRightSide(); + ClearBottomSide(); + } + + void CBorder::ClearLeftSide() + { + m_oLeft.Clear(); + } + + void CBorder::ClearTopSide() + { + m_oTop.Clear(); + } + + void CBorder::ClearRightSide() + { + m_oRight.Clear(); + } + + void CBorder::ClearBottomSide() + { + m_oBottom.Clear(); + } void CBorder::Equation(CBorder &oFirstBorder, CBorder &oSecondBorder) { @@ -1413,34 +1878,67 @@ namespace NSCSS bool CBorder::SetSides(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode) { - return m_oLeft .SetValue(wsValue, unLevel, bHardMode) || - m_oTop .SetValue(wsValue, unLevel, bHardMode) || - m_oRight .SetValue(wsValue, unLevel, bHardMode) || - m_oBottom.SetValue(wsValue, unLevel, bHardMode); + bool bResult = false; + + if (m_oLeft .SetValue(wsValue, unLevel, bHardMode)) bResult = true; + if (m_oTop .SetValue(wsValue, unLevel, bHardMode)) bResult = true; + if (m_oRight .SetValue(wsValue, unLevel, bHardMode)) bResult = true; + if (m_oBottom.SetValue(wsValue, unLevel, bHardMode)) bResult = true; + + return bResult; } bool CBorder::SetWidth(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode) { - return m_oLeft .SetWidth(wsValue, unLevel, bHardMode) || - m_oTop .SetWidth(wsValue, unLevel, bHardMode) || - m_oRight .SetWidth(wsValue, unLevel, bHardMode) || - m_oBottom.SetWidth(wsValue, unLevel, bHardMode); + bool bResult = false; + + if (m_oLeft .SetWidth(wsValue, unLevel, bHardMode)) bResult = true; + if (m_oTop .SetWidth(wsValue, unLevel, bHardMode)) bResult = true; + if (m_oRight .SetWidth(wsValue, unLevel, bHardMode)) bResult = true; + if (m_oBottom.SetWidth(wsValue, unLevel, bHardMode)) bResult = true; + + return bResult; + } + + bool CBorder::SetWidth(const double& dValue, unsigned int unLevel, bool bHardMode) + { + bool bResult = false; + + if (m_oLeft .SetWidth(dValue, unLevel, bHardMode)) bResult = true; + if (m_oTop .SetWidth(dValue, unLevel, bHardMode)) bResult = true; + if (m_oRight .SetWidth(dValue, unLevel, bHardMode)) bResult = true; + if (m_oBottom.SetWidth(dValue, unLevel, bHardMode)) bResult = true; + + return bResult; } bool CBorder::SetStyle(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode) { - return m_oLeft .SetStyle(wsValue, unLevel, bHardMode) || - m_oTop .SetStyle(wsValue, unLevel, bHardMode) || - m_oRight .SetStyle(wsValue, unLevel, bHardMode) || - m_oBottom.SetStyle(wsValue, unLevel, bHardMode); + bool bResult = false; + + if (m_oLeft .SetStyle(wsValue, unLevel, bHardMode)) bResult = true; + if (m_oTop .SetStyle(wsValue, unLevel, bHardMode)) bResult = true; + if (m_oRight .SetStyle(wsValue, unLevel, bHardMode)) bResult = true; + if (m_oBottom.SetStyle(wsValue, unLevel, bHardMode)) bResult = true; + + return bResult; } bool CBorder::SetColor(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode) { - return m_oLeft .SetColor(wsValue, unLevel, bHardMode) || - m_oTop .SetColor(wsValue, unLevel, bHardMode) || - m_oRight .SetColor(wsValue, unLevel, bHardMode) || - m_oBottom.SetColor(wsValue, unLevel, bHardMode); + bool bResult = false; + + if (m_oLeft .SetColor(wsValue, unLevel, bHardMode)) bResult = true; + if (m_oTop .SetColor(wsValue, unLevel, bHardMode)) bResult = true; + if (m_oRight .SetColor(wsValue, unLevel, bHardMode)) bResult = true; + if (m_oBottom.SetColor(wsValue, unLevel, bHardMode)) bResult = true; + + return bResult; + } + + bool CBorder::SetCollapse(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode) + { + return m_enCollapse.SetValue(wsValue, unLevel, bHardMode); } bool CBorder::SetLeftSide(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode) @@ -1453,6 +1951,11 @@ namespace NSCSS return m_oLeft.SetWidth(wsValue, unLevel, bHardMode); } + bool CBorder::SetWidthLeftSide(const double& dValue, unsigned int unLevel, bool bHardMode) + { + return m_oLeft.SetWidth(dValue, unLevel, bHardMode); + } + bool CBorder::SetStyleLeftSide(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode) { return m_oLeft.SetStyle(wsValue, unLevel, bHardMode); @@ -1473,6 +1976,11 @@ namespace NSCSS return m_oTop.SetWidth(wsValue, unLevel, bHardMode); } + bool CBorder::SetWidthTopSide(const double& dValue, unsigned int unLevel, bool bHardMode) + { + return m_oTop.SetWidth(dValue, unLevel, bHardMode); + } + bool CBorder::SetStyleTopSide(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode) { return m_oTop.SetStyle(wsValue, unLevel, bHardMode); @@ -1493,6 +2001,11 @@ namespace NSCSS return m_oRight.SetWidth(wsValue, unLevel, bHardMode); } + bool CBorder::SetWidthRightSide(const double& dValue, unsigned int unLevel, bool bHardMode) + { + return m_oRight.SetWidth(dValue, unLevel, bHardMode); + } + bool CBorder::SetStyleRightSide(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode) { return m_oRight.SetStyle(wsValue, unLevel, bHardMode); @@ -1513,6 +2026,11 @@ namespace NSCSS return m_oBottom.SetWidth(wsValue, unLevel, bHardMode); } + bool CBorder::SetWidthBottomSide(const double& dValue, unsigned int unLevel, bool bHardMode) + { + return m_oBottom.SetWidth(dValue, unLevel, bHardMode); + } + bool CBorder::SetStyleBottomSide(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode) { return m_oBottom.SetStyle(wsValue, unLevel, bHardMode); @@ -1523,6 +2041,14 @@ namespace NSCSS return m_oBottom.SetColor(wsValue, unLevel, bHardMode); } + void CBorder::SetNone(unsigned int unLevel, bool bHardMode) + { + m_oLeft .SetNone(unLevel, bHardMode); + m_oTop .SetNone(unLevel, bHardMode); + m_oRight .SetNone(unLevel, bHardMode); + m_oBottom.SetNone(unLevel, bHardMode); + } + void CBorder::Block() { m_oLeft .Block(); @@ -1545,9 +2071,20 @@ namespace NSCSS m_oRight.Empty() && m_oBottom.Empty(); } + bool CBorder::Zero() const + { + return m_oLeft.Zero() && m_oTop.Zero() && + m_oRight.Zero() && m_oBottom.Zero(); + } + bool CBorder::EqualSides() const { - return m_oLeft == m_oTop && m_oTop == m_oRight && m_oRight == m_oBottom; + return m_oLeft == m_oTop && m_oTop == m_oRight && m_oRight == m_oBottom; + } + + const CEnum &CBorder::GetCollapse() const + { + return m_enCollapse; } const CBorderSide& CBorder::GetLeftBorder() const @@ -1572,10 +2109,15 @@ namespace NSCSS CBorder &CBorder::operator+=(const CBorder &oBorder) { - m_oLeft += oBorder.m_oLeft; - m_oTop += oBorder.m_oTop; - m_oRight += oBorder.m_oRight; - m_oBottom += oBorder.m_oBottom; + m_enCollapse = oBorder.m_enCollapse; + + if (oBorder.Empty()) + return *this; + + m_oLeft = oBorder.m_oLeft; + m_oTop = oBorder.m_oTop; + m_oRight = oBorder.m_oRight; + m_oBottom = oBorder.m_oBottom; return *this; } @@ -1588,6 +2130,26 @@ namespace NSCSS m_oBottom == oBorder.m_oBottom; } + bool CBorder::operator!=(const CBorder& oBorder) const + { + return m_oLeft != oBorder.m_oLeft || + m_oTop != oBorder.m_oTop || + m_oRight != oBorder.m_oRight || + m_oBottom != oBorder.m_oBottom; + } + + CBorder &CBorder::operator =(const CBorder &oBorder) + { + m_oLeft = oBorder.m_oLeft; + m_oTop = oBorder.m_oTop; + m_oRight = oBorder.m_oRight; + m_oBottom = oBorder.m_oBottom; + + m_enCollapse = oBorder.m_enCollapse; + + return *this; + } + // TEXT CText::CText() {} @@ -1598,6 +2160,7 @@ namespace NSCSS CString::Equation(oFirstText.m_oAlign, oSecondText.m_oAlign); // CString::Equation(oFirstText.m_oDecoration, oSecondText.m_oDecoration); CColor ::Equation(oFirstText.m_oColor, oSecondText.m_oColor); + CColor ::Equation(oFirstText.m_oHighlight, oSecondText.m_oHighlight); } bool CText::SetIndent(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode) @@ -1633,6 +2196,11 @@ namespace NSCSS return m_oColor.SetValue(wsValue, unLevel, bHardMode); } + bool CText::SetHighlight(const std::wstring& wsValue, unsigned int unLevel, bool bHardMode) + { + return m_oHighlight.SetValue(wsValue, unLevel, bHardMode); + } + const CDigit& CText::GetIndent() const { return m_oIndent; @@ -1653,6 +2221,11 @@ namespace NSCSS return m_oColor; } + const CColor& CText::GetHighlight() const + { + return m_oHighlight; + } + bool CText::Empty() const { return m_oIndent.Empty() && m_oAlign.Empty() && @@ -1680,6 +2253,7 @@ namespace NSCSS m_oAlign += oText.m_oAlign; m_oDecoration += oText.m_oDecoration; m_oColor += oText.m_oColor; + m_oHighlight += oText.m_oHighlight; return *this; } @@ -1688,14 +2262,28 @@ namespace NSCSS { return m_oIndent == oText.m_oIndent && m_oAlign == oText.m_oAlign && -// m_oDecoration == oText.m_oDecoration && - m_oColor == oText.m_oColor; + m_oDecoration == oText.m_oDecoration && + m_oColor == oText.m_oColor && + m_oHighlight == oText.m_oHighlight; } // MARGIN CIndent::CIndent() - : m_bPermission(true) - {} + : m_bPermission(true) + {} + + void CIndent::Clear() + { + m_oTop .Clear(); + m_oRight .Clear(); + m_oBottom.Clear(); + m_oLeft .Clear(); + } + + void CIndent::SetPermisson(bool bPermission) + { + m_bPermission = bPermission; + } void CIndent::Equation(CIndent &oFirstMargin, CIndent &oSecondMargin) { @@ -1705,175 +2293,178 @@ namespace NSCSS CDigit::Equation(oFirstMargin.m_oBottom, oSecondMargin.m_oBottom); } - void CIndent::SetPermisson(bool bPermission) + bool CIndent::Equals() const { - m_bPermission = bPermission; + if (Empty()) + return true; + + return m_oLeft == m_oTop && m_oTop == m_oRight && m_oRight == m_oBottom; } - bool CIndent::AddValue(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode) + bool CIndent::SetValues(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode) { + if (!m_bPermission) + return false; + const std::vector arValues = NS_STATIC_FUNCTIONS::GetWordsW(wsValue, false, L" "); switch (arValues.size()) { case 1: - { - // TODO:: иногда будет не верный рельтат, если до этого одиен из элементом был с '!important' - // Необходимо добавить обработку такого случая - if (AddValue(m_oLeft, arValues[0], unLevel, bHardMode)) - { - m_oTop = m_oRight = m_oBottom = m_oLeft; - return true; - } - break; - } + return SetValues(arValues[0], arValues[0], arValues[0], arValues[0], unLevel, bHardMode); case 2: - { - if (AddValue(m_oTop, arValues[0], unLevel, bHardMode) && - AddValue(m_oLeft, arValues[1], unLevel, bHardMode)) - { - m_oBottom = m_oTop; - m_oRight = m_oLeft; - - return true; - } - break; - } + return SetValues(arValues[0], arValues[1], arValues[0], arValues[1], unLevel, bHardMode); case 3: - { - if (AddValue(m_oTop, arValues[0], unLevel, bHardMode) && - AddValue(m_oLeft, arValues[1], unLevel, bHardMode) && - AddValue(m_oBottom, arValues[2], unLevel, bHardMode)) - { - m_oRight = m_oLeft; - - return true; - } - - break; - } + return SetValues(arValues[0], arValues[1], arValues[2], arValues[1], unLevel, bHardMode); case 4: - { - if (AddValue(m_oTop, arValues[0], unLevel, bHardMode) && - AddValue(m_oRight, arValues[1], unLevel, bHardMode) && - AddValue(m_oBottom, arValues[2], unLevel, bHardMode) && - AddValue(m_oLeft, arValues[3], unLevel, bHardMode)) - return true; - - break; - } + return SetValues(arValues[0], arValues[1], arValues[2], arValues[3], unLevel, bHardMode); } return false; } - bool CIndent::AddLeft(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode) + bool CIndent::SetTop(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode) { - return AddValue(m_oLeft, wsValue, unLevel, bHardMode); + return m_oTop.SetValue(wsValue, unLevel, bHardMode); } - bool CIndent::AddTop(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode) + bool CIndent::SetTop(const double& dValue, unsigned int unLevel, bool bHardMode) { - return AddValue(m_oTop, wsValue, unLevel, bHardMode); + return m_oTop.SetValue(dValue, unLevel, bHardMode); } - bool CIndent::AddRight(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode) + bool CIndent::SetRight(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode) { - return AddValue(m_oRight, wsValue, unLevel, bHardMode); + return m_oRight.SetValue(wsValue, unLevel, bHardMode); } - bool CIndent::AddBottom(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode) + bool CIndent::SetRight(const double& dValue, unsigned int unLevel, bool bHardMode) { - return AddValue(m_oBottom, wsValue, unLevel, bHardMode); + return m_oRight.SetValue(dValue, unLevel, bHardMode); } - - void CIndent::UpdateAll(double dFontSize) + + bool CIndent::SetBottom(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode) + { + return m_oBottom.SetValue(wsValue, unLevel, bHardMode); + } + + bool CIndent::SetBottom(const double& dValue, unsigned int unLevel, bool bHardMode) { - UpdateLeft(dFontSize); - UpdateTop(dFontSize); - UpdateRight(dFontSize); - UpdateBottom(dFontSize); + return m_oBottom.SetValue(dValue, unLevel, bHardMode); } - - void CIndent::UpdateLeft(double dFontSize) + + bool CIndent::SetLeft(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode) { - if (NSCSS::Em == m_oLeft.GetUnitMeasure() || NSCSS::Rem == m_oLeft.GetUnitMeasure()) - m_oLeft.ConvertTo(NSCSS::Twips, dFontSize); + return m_oLeft.SetValue(wsValue, unLevel, bHardMode); } - - void CIndent::UpdateTop(double dFontSize) + + bool CIndent::SetLeft(const double& dValue, unsigned int unLevel, bool bHardMode) { - if (NSCSS::Em == m_oTop.GetUnitMeasure() || NSCSS::Rem == m_oTop.GetUnitMeasure()) - m_oTop.ConvertTo(NSCSS::Twips, dFontSize); + return m_oLeft.SetValue(dValue, unLevel, bHardMode); } - - void CIndent::UpdateRight(double dFontSize) + + void CIndent::UpdateAll(const double& dParentFontSize, const double& dCoreFontSize) { - if (NSCSS::Em == m_oRight.GetUnitMeasure() || NSCSS::Rem == m_oRight.GetUnitMeasure()) - m_oRight.ConvertTo(NSCSS::Twips, dFontSize); + UpdateTop (dParentFontSize, dCoreFontSize); + UpdateRight (dParentFontSize, dCoreFontSize); + UpdateBottom(dParentFontSize, dCoreFontSize); + UpdateLeft (dParentFontSize, dCoreFontSize); } - - void CIndent::UpdateBottom(double dFontSize) + + void CIndent::UpdateTop(const double& dParentFontSize, const double& dCoreFontSize) { - if (NSCSS::Em == m_oBottom.GetUnitMeasure() || NSCSS::Rem == m_oBottom.GetUnitMeasure()) - m_oBottom.ConvertTo(NSCSS::Twips, dFontSize); + UpdateSide(m_oTop, dParentFontSize, dCoreFontSize); } - const CDigit& CIndent::GetLeft() const + void CIndent::UpdateRight(const double& dParentFontSize, const double& dCoreFontSize) { - return m_oLeft; + UpdateSide(m_oRight, dParentFontSize, dCoreFontSize); + } + + void CIndent::UpdateBottom(const double& dParentFontSize, const double& dCoreFontSize) + { + UpdateSide(m_oBottom, dParentFontSize, dCoreFontSize); } - const CDigit& CIndent::GetTop() const + void CIndent::UpdateLeft(const double& dParentFontSize, const double& dCoreFontSize) + { + UpdateSide(m_oLeft, dParentFontSize, dCoreFontSize); + } + + const CDigit &CIndent::GetTop() const { return m_oTop; } - const CDigit& CIndent::GetRight() const + const CDigit &CIndent::GetRight() const { return m_oRight; } - const CDigit& CIndent::GetBottom() const + const CDigit &CIndent::GetBottom() const { return m_oBottom; } + const CDigit &CIndent::GetLeft() const + { + return m_oLeft; + } + bool CIndent::Empty() const { - return m_oLeft.Empty() && m_oTop.Empty() && m_oRight.Empty() && m_oBottom.Empty(); + return m_oTop.Empty() && m_oRight.Empty() && m_oBottom.Empty() && m_oLeft.Empty(); + } + + bool CIndent::Zero() const + { + return m_oTop.Zero() && m_oRight.Zero() && m_oBottom.Zero() && m_oLeft.Zero(); } - CIndent &CIndent::operator+=(const CIndent &oMargin) + CIndent &CIndent::operator+=(const CIndent &oIndent) { - m_oLeft += oMargin.m_oLeft; - m_oTop += oMargin.m_oTop; - m_oRight += oMargin.m_oRight; - m_oBottom += oMargin.m_oBottom; + if (!oIndent.m_oTop.Empty()) m_oTop = oIndent.m_oTop; + if (!oIndent.m_oRight.Empty()) m_oRight = oIndent.m_oRight; + if (!oIndent.m_oBottom.Empty()) m_oBottom = oIndent.m_oBottom; + if (!oIndent.m_oLeft.Empty()) m_oLeft = oIndent.m_oLeft; return *this; } - - bool CIndent::operator==(const CIndent &oMargin) const + + bool CIndent::operator==(const CIndent &oIndent) const { - return m_oLeft == oMargin.m_oLeft && - m_oTop == oMargin.m_oTop && - m_oRight == oMargin.m_oRight && - m_oBottom == oMargin.m_oBottom; + return m_oTop == oIndent.m_oTop && + m_oRight == oIndent.m_oRight && + m_oBottom == oIndent.m_oBottom && + m_oLeft == oIndent.m_oLeft; + } + + bool CIndent::operator!=(const CIndent &oIndent) const + { + return m_oTop != oIndent.m_oTop || + m_oRight != oIndent.m_oRight || + m_oBottom != oIndent.m_oBottom || + m_oLeft != oIndent.m_oLeft; } - bool CIndent::AddValue(CDigit &oValue, const std::wstring &wsValue, unsigned int unLevel, bool bHardMode) + bool CIndent::SetValues(const std::wstring &wsTopValue, const std::wstring &wsRightValue, const std::wstring &wsBottomValue, const std::wstring &wsLeftValue, unsigned int unLevel, bool bHardMode) { - if (!m_bPermission) - return false; + const bool bTopResult = SetTop (wsTopValue, unLevel, bHardMode); + const bool bRightResult = SetRight (wsRightValue, unLevel, bHardMode); + const bool bBottomResult = SetBottom (wsBottomValue, unLevel, bHardMode); + const bool bLeftResult = SetLeft (wsLeftValue, unLevel, bHardMode); - CDigit oTempValue; - - if (!oTempValue.SetValue(wsValue, unLevel, bHardMode)) - return false; - - oValue += oTempValue; + return bTopResult || bRightResult || bBottomResult || bLeftResult; + } + + void CIndent::UpdateSide(CDigit &oSide, const double& dParentFontSize, const double& dCoreFontSize) + { + if (oSide.Empty()) + return; - return true; + if (NSCSS::Em == oSide.GetUnitMeasure()) + oSide.ConvertTo(NSCSS::Twips, dParentFontSize); + else if (NSCSS::Rem == oSide.GetUnitMeasure()) + oSide.ConvertTo(NSCSS::Twips, dCoreFontSize); } // FONT @@ -1939,6 +2530,13 @@ namespace NSCSS return *this; } + bool CTextDecorationLine::operator==(const CTextDecorationLine &oTextDecorationLine) const + { + return m_bUnderline == oTextDecorationLine.m_bUnderline && + m_bOverline == oTextDecorationLine.m_bOverline && + m_bLineThrough == oTextDecorationLine.m_bLineThrough; + } + TTextDecoration &TTextDecoration::operator+=(const TTextDecoration &oTextDecoration) { m_oLine += oTextDecoration.m_oLine; @@ -1948,6 +2546,13 @@ namespace NSCSS return *this; } + bool TTextDecoration::operator==(const TTextDecoration &oTextDecoration) const + { + return m_oLine == oTextDecoration.m_oLine && + m_oStyle == oTextDecoration.m_oStyle && + m_oColor == oTextDecoration.m_oColor; + } + CFont::CFont() {} @@ -2027,16 +2632,16 @@ namespace NSCSS bool CFont::SetSize(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode) { - const std::map arAbsoluteFontValues = - {{L"xx-small", L"0.6em"}, {L"x-small", L"0.75em"}, - {L"small", L"0.875em"}, {L"medium", L"1em"}, - {L"large", L"1.125em"}, {L"x-large", L"1.25em"}, - {L"xx-large", L"1.5em"}}; + const std::vector> arAbsoluteFontValues = + {{L"xx-small", L"7.5pt"}, {L"xx-large", L"36pt" }, + {L"x-small", L"10pt" }, {L"x-large", L"24pt" }, + {L"small", L"12pt" }, {L"medium", L"13.5pt"}, + {L"large", L"18pt" }}; size_t unFoundPos = std::wstring::npos; std::wstring wsNewValue(wsValue); - for (const std::pair oAbsValue : arAbsoluteFontValues) + for (const std::pair& oAbsValue : arAbsoluteFontValues) { unFoundPos = wsNewValue.find(oAbsValue.first); if (std::wstring::npos != unFoundPos) @@ -2046,6 +2651,11 @@ namespace NSCSS return m_oSize.SetValue(wsNewValue, unLevel, bHardMode); } + bool CFont:: SetSize(const double& dValue, unsigned int unLevel, bool bHardMode) + { + return m_oSize.SetValue(dValue, unLevel, bHardMode); + } + bool CFont::SetLineHeight(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode) { return m_oLineHeight.SetValue(wsValue, unLevel, bHardMode); @@ -2053,20 +2663,22 @@ namespace NSCSS bool CFont::SetFamily(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode) { - std::wstring wsNewFamily(wsValue); + // std::wstring wsNewFamily(wsValue); // if (wsNewFamily.end() == wsNewFamily.erase(std::remove(wsNewFamily.begin(), wsNewFamily.end(), L'\''), wsNewFamily.end()) && // wsNewFamily.end() == wsNewFamily.erase(std::remove(wsNewFamily.begin(), wsNewFamily.end(), L'"'), wsNewFamily.end())) // return false; - std::vector arWords = NS_STATIC_FUNCTIONS::GetWordsW(wsNewFamily, false, L"\"\',"); + std::vector arWords = NS_STATIC_FUNCTIONS::GetWordsW(wsValue, false, L"\"\',"); for (std::vector::iterator iWord = arWords.begin(); iWord != arWords.end(); ++iWord) { if ((*iWord).empty()) continue; - return m_oFamily.SetValue(NSCSS::NS_STATIC_FUNCTIONS::RemoveSpaces(*iWord), unLevel, bHardMode); + NSCSS::NS_STATIC_FUNCTIONS::RemoveSpaces(*iWord); + + return m_oFamily.SetValue(*iWord, unLevel, bHardMode); } return false; @@ -2092,19 +2704,23 @@ namespace NSCSS { return m_oWeight.SetValue(wsValue, {std::make_pair(L"normal", L"normal"), std::make_pair(L"300", L"normal"), std::make_pair(L"400", L"normal"), std::make_pair(L"500", L"normal"), std::make_pair(L"bold", L"bold"), std::make_pair(L"bolder", L"bold"), std::make_pair(L"600", L"bold"), - std::make_pair(L"700", L"bold"), std::make_pair(L"800", L"bold"), std::make_pair(L"900", L"bold")}, unLevel, bHardMode); + std::make_pair(L"700", L"bold"), std::make_pair(L"800", L"bold"), std::make_pair(L"900", L"bold")}, unLevel, bHardMode); } - void CFont::UpdateSize(double dFontSize) + void CFont::UpdateSize(const double& dParentFontSize, const double& dCoreFontSize) { - if (NSCSS::Em == m_oSize.GetUnitMeasure() || NSCSS::Rem == m_oSize.GetUnitMeasure()) - m_oSize.ConvertTo(NSCSS::Twips, dFontSize); + if (NSCSS::Em == m_oSize.GetUnitMeasure() || NSCSS::Percent == m_oSize.GetUnitMeasure()) + m_oSize.ConvertTo(NSCSS::Point, dParentFontSize); + else if (NSCSS::Rem == m_oSize.GetUnitMeasure()) + m_oSize.ConvertTo(NSCSS::Point, dCoreFontSize); } - void CFont::UpdateLineHeight(double dFontSize) + void CFont::UpdateLineHeight(const double& dParentFontSize, const double& dCoreFontSize) { - if (NSCSS::Em == m_oLineHeight.GetUnitMeasure() || NSCSS::Rem == m_oLineHeight.GetUnitMeasure()) - m_oLineHeight.ConvertTo(NSCSS::Twips, dFontSize); + if (NSCSS::Em == m_oLineHeight.GetUnitMeasure()) + m_oLineHeight.ConvertTo(NSCSS::Twips, dParentFontSize); + else if (NSCSS::Rem == m_oLineHeight.GetUnitMeasure()) + m_oLineHeight.ConvertTo(NSCSS::Twips, dCoreFontSize); } bool CFont::Bold() const @@ -2119,8 +2735,7 @@ namespace NSCSS void CFont::Clear() { - m_oSize = CDigit(24., 0); - + m_oSize .Clear(); m_oLineHeight.Clear(); m_oFamily .Clear(); m_oStretch .Clear(); @@ -2139,6 +2754,11 @@ namespace NSCSS return m_oLineHeight; } + CDigit &CFont::GetLineHeight() + { + return m_oLineHeight; + } + const CString &CFont::GetFamily() const { return m_oFamily; @@ -2172,7 +2792,7 @@ namespace NSCSS CFont &CFont::operator+=(const CFont &oFont) { - m_oSize += oFont.m_oSize; + m_oSize.SetValue(oFont.m_oSize); m_oLineHeight += oFont.m_oLineHeight; m_oFamily += oFont.m_oFamily; m_oStretch += oFont.m_oStretch; @@ -2191,167 +2811,61 @@ namespace NSCSS m_oStretch == oFont.m_oStretch && m_oStyle == oFont.m_oStyle && m_oVariant == oFont.m_oVariant && - m_oWeight == oFont.m_oWeight; + m_oWeight == oFont.m_oWeight; } - CColorValue::CColorValue() - : m_enType(ColorEmpty), m_pColor(NULL) + CURL::CURL() {} - CColorValue::CColorValue(const CColorValue &oColorValue) - : m_enType() - { - switch(oColorValue.m_enType) - { - case ColorRGB: SetRGB(*static_cast(oColorValue.m_pColor)); break; - case ColorHEX: SetHEX(*static_cast(oColorValue.m_pColor)); break; - case ColorUrl: SetUrl(*static_cast(oColorValue.m_pColor)); break; - default: m_enType = oColorValue.m_enType; break; - } - - } - - CColorValue::~CColorValue() - { - Clear(); - } - - void CColorValue::SetRGB(unsigned char uchR, unsigned char uchG, unsigned char uchB) + bool CURL::Empty() const { - Clear(); - - m_pColor = new TRGB{uchR, uchG, uchB}; - - if (NULL == m_pColor) - { - m_enType = ColorEmpty; - return; - } - - m_enType = ColorRGB; + return m_wsValue.empty(); } - void CColorValue::SetRGB(const TRGB &oRGB) + bool CURL::LinkToId() const { - Clear(); - - m_pColor = new TRGB{oRGB}; - - if (NULL == m_pColor) - { - m_enType = ColorEmpty; - return; - } - - m_enType = ColorRGB; + return m_wsValue.length() > 1 && L'#' == m_wsValue.front(); } - - void CColorValue::SetHEX(const std::wstring &wsValue) + + void CURL::Clear() { - Clear(); - - m_pColor = new std::wstring(wsValue); - - if (NULL == m_pColor) - { - m_enType = ColorEmpty; - return; - } - - m_enType = ColorHEX; + m_wsValue.clear(); } - void CColorValue::SetUrl(const std::wstring &wsValue) + bool CURL::SetValue(const std::wstring &wsValue) { - Clear(); - - m_pColor = new std::wstring(wsValue); - - if (NULL == m_pColor || ((std::wstring*)m_pColor)->empty()) - { - m_enType = ColorEmpty; - return; - } - - m_enType = ColorUrl; - } + if (wsValue.empty()) + return false; - void CColorValue::SetNone() - { - Clear(); + std::wregex oRegex(L"url\\s*\\(\\s*(?:'|\"|)([#]?[^'\"()]+)(?:'|\"|)\\s*\\)"); + std::wsmatch oMatch; - m_enType = ColorNone; - } + if (!std::regex_search(wsValue.cbegin(), wsValue.cend(), oMatch, oRegex) || oMatch[1].str().empty()) + return false; - bool CColorValue::Empty() const - { - return ColorEmpty == m_enType; - } + m_wsValue = oMatch[1].str(); + NS_STATIC_FUNCTIONS::RemoveSpaces(m_wsValue); - std::wstring CColorValue::GetColor() const - { - return *(std::wstring*)m_pColor; + return true; } - - bool CColorValue::operator==(const CColorValue &oColorValue) const + + std::wstring CURL::GetValue() const { - if (m_enType != oColorValue.m_enType) - return false; - - if (ColorEmpty == m_enType || - ColorNone == m_enType) - return true; - - switch (m_enType) - { - case ColorRGB: - return *static_cast(m_pColor) == *static_cast(oColorValue.m_pColor); - case ColorHEX: - case ColorUrl: - return *static_cast(m_pColor) == *static_cast(oColorValue.m_pColor); - default: - break; - } - - return false; + return m_wsValue; } - CColorValue &CColorValue::operator=(const CColorValue &oColorValue) + bool CURL::operator==(const CURL& oValue) const { - switch(oColorValue.m_enType) - { - case ColorRGB: SetRGB(*static_cast(oColorValue.m_pColor)); break; - case ColorHEX: SetHEX(*static_cast(oColorValue.m_pColor)); break; - case ColorUrl: SetUrl(*static_cast(oColorValue.m_pColor)); break; - default: m_enType = oColorValue.m_enType; break; - } - - return *this; + return m_wsValue == oValue.m_wsValue; } - void CColorValue::Clear() + bool CURL::operator!=(const CURL& oValue) const { - switch (m_enType) - { - case ColorRGB: - { - TRGB *pRGB = static_cast(m_pColor); - RELEASEOBJECT(pRGB); - break; - } - case ColorHEX: case ColorUrl: - { - std::wstring* pValue = static_cast(m_pColor); - RELEASEOBJECT(pValue); - break; - } - } - - m_enType = ColorEmpty; + return m_wsValue != oValue.m_wsValue; } CEnum::CEnum() - : CValue(INT_MIN, 0, false){} + : CValue(INT_MAX, 0, false){} bool CEnum::SetValue(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode) { @@ -2367,31 +2881,34 @@ namespace NSCSS std::map::const_iterator oFound = m_mMap.find(wsNewValue); - if (m_mMap.end() != oFound) - { - m_oValue = oFound->second; - m_unLevel = unLevel; - m_bImportant = bImportant; - } - else + if (m_mMap.end() == oFound) return false; + m_oValue = oFound->second; + m_unLevel = unLevel; + m_bImportant = bImportant; + return true; } - void CEnum::SetMapping(const std::map &mMap) + void CEnum::SetMapping(const std::map &mMap, int nDefaulvalue) { m_mMap = mMap; + + if (-1 != nDefaulvalue) + m_oValue = nDefaulvalue; } bool CEnum::Empty() const { - return m_mMap.empty() || INT_MIN == m_oValue; + return m_mMap.empty() || INT_MAX == m_oValue; } void CEnum::Clear() { - m_oValue = INT_MIN; + m_oValue = INT_MAX; + m_unLevel = NULL; + m_bImportant = false; } CEnum &CEnum::operator =(int nValue) @@ -2417,12 +2934,73 @@ namespace NSCSS double CEnum::ToDouble() const { - return 0.; + return (double)m_oValue; } std::wstring CEnum::ToWString() const { - return std::wstring(); + if (m_mMap.empty()) + return std::wstring(); + + return std::find_if(m_mMap.begin(), m_mMap.end(), [this](const std::pair& oValue){ return m_oValue == oValue.second; })->first; + } + + CPage::CPage() + {} + + bool CPage::SetMargin(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode) + { + return m_oMargin.SetValues(wsValue, unLevel, bHardMode); + } + + bool CPage::SetSize(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode) + { + if (wsValue.empty()) + return false; + + std::vector arValues = NS_STATIC_FUNCTIONS::GetWordsW(wsValue); + + if (1 == arValues.size()) + return m_oWidth.SetValue(arValues[0], unLevel, bHardMode) && m_oHeight.SetValue(arValues[0], unLevel, bHardMode); + else if (2 == arValues.size()) + return m_oWidth.SetValue(arValues[0], unLevel, bHardMode) && m_oHeight.SetValue(arValues[1], unLevel, bHardMode); + + return false; + } + + bool CPage::SetFooter(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode) + { + return m_oFooter.SetValue(wsValue, unLevel, bHardMode); + } + + bool CPage::SetHeader(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode) + { + return m_oHeader.SetValue(wsValue, unLevel, bHardMode); + } + + const CDigit &CPage::GetWidth() const + { + return m_oWidth; + } + + const CDigit &CPage::GetHeight() const + { + return m_oHeight; + } + + const CIndent &CPage::GetMargin() const + { + return m_oMargin; + } + + const CDigit &CPage::GetFooter() const + { + return m_oFooter; + } + + const CDigit &CPage::GetHeader() const + { + return m_oHeader; } } diff --git a/Common/3dParty/html/css/src/StyleProperties.h b/Common/3dParty/html/css/src/StyleProperties.h index 42eb94ff0ff..2fa1ce19358 100644 --- a/Common/3dParty/html/css/src/StyleProperties.h +++ b/Common/3dParty/html/css/src/StyleProperties.h @@ -13,6 +13,8 @@ namespace NSCSS { namespace NSProperties { + #define NEXT_LEVEL UINT_MAX, true + template class CValue { @@ -21,6 +23,7 @@ namespace NSCSS friend class CDigit; friend class CColor; friend class CEnum; + friend class CURL; T m_oValue; unsigned int m_unLevel; @@ -54,6 +57,11 @@ namespace NSCSS } } + static bool LevelIsSame(const CValue& oFirstValue, const CValue& oSecondValue) + { + return oFirstValue.m_unLevel == oSecondValue.m_unLevel; + } + bool operator==(const T& oValue) const { return m_oValue == oValue; } bool operator>=(const T& oValue) const { return m_oValue >= oValue; } bool operator<=(const T& oValue) const { return m_oValue <= oValue; } @@ -69,28 +77,33 @@ namespace NSCSS return *this; } - CValue& operator =(const T& oValue) + virtual CValue& operator =(const T& oValue) { //m_oValue = oValue.m_oValue; return *this; } - CValue& operator+=(const CValue& oValue) + virtual CValue& operator+=(const CValue& oValue) { if (m_unLevel > oValue.m_unLevel || (m_bImportant && !oValue.m_bImportant) || oValue.Empty()) return *this; m_oValue = oValue.m_oValue; - m_unLevel = std::max(m_unLevel, oValue.m_unLevel); - m_bImportant = std::max(m_bImportant, oValue.m_bImportant); + m_unLevel = oValue.m_unLevel; + m_bImportant = oValue.m_bImportant; return *this; } - bool operator==(const CValue& oValue) const + virtual bool operator==(const CValue& oValue) const { return m_oValue == oValue.m_oValue; } + + virtual bool operator!=(const CValue& oValue) const + { + return m_oValue != oValue.m_oValue; + } }; class CString : public CValue @@ -124,13 +137,15 @@ namespace NSCSS CDigit(double dValue, unsigned int unLevel, bool bImportant = false); bool SetValue(const std::wstring& wsValue, unsigned int unLevel = 0, bool bHardMode = true) override; + bool SetValue(const CDigit& oValue); + bool SetValue(const double& dValue, unsigned int unLevel, bool bHardMode); bool Empty() const override; bool Zero() const; void Clear() override; void ConvertTo(UnitMeasure enUnitMeasure, double dPrevValue = 0.); - + int ToInt() const override; double ToDouble() const override; std::wstring ToWString() const override; @@ -144,6 +159,9 @@ namespace NSCSS bool operator==(const double& oValue) const; bool operator==(const CDigit& oDigit) const; + bool operator!=(const double& oValue) const; + bool operator!=(const CDigit& oDigit) const; + CDigit operator+(const CDigit& oDigit) const; CDigit operator-(const CDigit& oDigit) const; CDigit operator*(const CDigit& oDigit) const; @@ -169,56 +187,52 @@ namespace NSCSS bool Empty() const; bool operator==(const TRGB& oRGB) const; + bool operator!=(const TRGB& oRGB) const; }; - typedef enum - { - ColorEmpty, - ColorNone, - ColorRGB, - ColorHEX, - ColorUrl - } ColorType; - - class Q_DECL_EXPORT CColorValue + class CURL { public: - CColorValue(); - CColorValue(const CColorValue& oColorValue); - ~CColorValue(); - - void SetRGB(unsigned char uchR, unsigned char uchG, unsigned char uchB); - void SetRGB(const TRGB& oRGB); - void SetHEX(const std::wstring& wsValue); - void SetUrl(const std::wstring& wsValue); - void SetNone(); - - void Clear(); + CURL(); bool Empty() const; + bool LinkToId() const; - ColorType m_enType; - void* m_pColor = NULL; + void Clear(); - std::wstring GetColor() const; + bool SetValue(const std::wstring& wsValue); + std::wstring GetValue() const; - bool operator==(const CColorValue& oColorValue) const; - CColorValue& operator= (const CColorValue& oColorValue); + bool operator==(const CURL& oValue) const; + bool operator!=(const CURL& oValue) const; + private: + std::wstring m_wsValue; }; + + typedef enum + { + ColorEmpty, + ColorNone, + ColorRGB, + ColorHEX, + ColorUrl, + ColorContextStroke, + ColorContextFill + } ColorType; - class CColor : public CValue + class CColor : public CValue { - CDigit m_oOpacity; - static TRGB ConvertHEXtoRGB(const std::wstring& wsValue); - static std::wstring ConvertRGBtoHEX(const TRGB& oValue); - static std::wstring CutURL(const std::wstring& wsValue); public: CColor(); + CColor(const CColor& oColor); + ~CColor(); bool SetValue(const std::wstring& wsValue, unsigned int unLevel = 0, bool bHardMode = true) override; bool SetOpacity(const std::wstring& wsValue, unsigned int unLevel = 0, bool bHardMode = true); bool Empty() const override; + bool None() const; + bool Url() const; void Clear() override; ColorType GetType() const; @@ -228,7 +242,28 @@ namespace NSCSS int ToInt() const override; double ToDouble() const override; std::wstring ToWString() const override; + std::wstring ToHEX() const; + std::wstring EquateToColor(const std::vector>& arColors) const; TRGB ToRGB() const; + + static TRGB ConvertHEXtoRGB(const std::wstring& wsValue); + static std::wstring ConvertRGBtoHEX(const TRGB& oValue); + + bool operator==(const CColor& oColor) const; + bool operator!=(const CColor& oColor) const; + + CColor& operator =(const CColor& oColor); + CColor& operator+=(const CColor& oColor); + private: + CDigit m_oOpacity; + ColorType m_enType; + + void SetEmpty(unsigned int unLevel = 0); + void SetRGB(unsigned char uchR, unsigned char uchG, unsigned char uchB); + void SetRGB(const TRGB& oRGB); + void SetHEX(const std::wstring& wsValue); + void SetUrl(const std::wstring& wsValue); + void SetNone(); }; typedef enum @@ -276,7 +311,7 @@ namespace NSCSS CEnum(); bool SetValue(const std::wstring& wsValue, unsigned int unLevel, bool bHardMode) override; - void SetMapping(const std::map& mMap); + void SetMapping(const std::map& mMap, int nDefaulvalue = -1); bool Empty() const override; void Clear() override; @@ -369,19 +404,18 @@ namespace NSCSS bool SetColor (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); bool SetBackground(const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); - void InBorder(); const CColor& GetColor() const; - bool IsInBorder() const; - bool Empty() const; + void Clear(); + bool Empty() const; + bool IsNone() const; CBackground& operator =(const CBackground& oBackground); CBackground& operator+=(const CBackground& oBackground); bool operator==(const CBackground& oBackground) const; private: CColor m_oColor; - bool m_bInBorder; }; class CTransform @@ -396,6 +430,11 @@ namespace NSCSS bool SetMatrix(const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); bool SetMatrix(const Aggplus::CMatrix &oMatrix); + void Translate(double dOffsetX, double dOffsetY); + void Scale(double dScaleX, double dScaleY); + void Rotate(double dValue); + void RotateAt(double dValue, double dX, double dY); + const CMatrix& GetMatrix() const; bool Empty() const; @@ -410,14 +449,20 @@ namespace NSCSS { public: CBorderSide(); + CBorderSide(const CBorderSide& oBorderSide); + + void Clear(); static void Equation(CBorderSide &oFirstBorderSide, CBorderSide &oSecondBorderSide); bool SetValue(const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); bool SetWidth(const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); + bool SetWidth(const double& dValue, unsigned int unLevel, bool bHardMode = false); bool SetStyle(const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); bool SetColor(const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); + void SetNone(unsigned int unLevel, bool bHardMode); + void Block(); void Unblock(); @@ -428,9 +473,13 @@ namespace NSCSS const CColor& GetColor() const; bool Empty() const; + bool Zero() const; + bool Valid() const; CBorderSide& operator+=(const CBorderSide& oBorderSide); bool operator==(const CBorderSide& oBorderSide) const; + bool operator!=(const CBorderSide& oBorderSide) const; + CBorderSide& operator =(const CBorderSide& oBorderSide); private: CDigit m_oWidth; CString m_oStyle; @@ -439,48 +488,71 @@ namespace NSCSS bool m_bBlock; }; + typedef enum + { + Collapse, + Separate + } BorderCollapse; + class CBorder { public: CBorder(); + void Clear(); + void ClearLeftSide(); + void ClearTopSide(); + void ClearRightSide(); + void ClearBottomSide(); + static void Equation(CBorder &oFirstBorder, CBorder &oSecondBorder); - bool SetSides(const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); - bool SetWidth(const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); - bool SetStyle(const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); - bool SetColor(const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); + bool SetSides(const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); + bool SetWidth(const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); + bool SetWidth(const double& dValue, unsigned int unLevel, bool bHardMode = false); + bool SetStyle(const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); + bool SetColor(const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); + bool SetCollapse(const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); //Left Side bool SetLeftSide (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); bool SetWidthLeftSide (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); + bool SetWidthLeftSide (const double& dValue, unsigned int unLevel, bool bHardMode = false); bool SetStyleLeftSide (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); bool SetColorLeftSide (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); //Top Side bool SetTopSide (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); bool SetWidthTopSide (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); + bool SetWidthTopSide (const double& dValue, unsigned int unLevel, bool bHardMode = false); bool SetStyleTopSide (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); bool SetColorTopSide (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); //Right Side bool SetRightSide (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); bool SetWidthRightSide (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); + bool SetWidthRightSide (const double& dValue, unsigned int unLevel, bool bHardMode = false); bool SetStyleRightSide (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); bool SetColorRightSide (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); //Bottom Side bool SetBottomSide (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); bool SetWidthBottomSide(const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); + bool SetWidthBottomSide(const double& dValue, unsigned int unLevel, bool bHardMode = false); bool SetStyleBottomSide(const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); bool SetColorBottomSide(const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); + void SetNone(unsigned int unLevel, bool bHardMode = false); + void Block(); void Unblock(); bool Empty() const; + bool Zero() const; bool EqualSides() const; + const CEnum& GetCollapse() const; + const CBorderSide& GetLeftBorder() const; const CBorderSide& GetTopBorder() const; const CBorderSide& GetRightBorder() const; @@ -488,11 +560,15 @@ namespace NSCSS CBorder& operator+=(const CBorder& oBorder); bool operator==(const CBorder& oBorder) const; + bool operator!=(const CBorder& oBorder) const; + CBorder& operator =(const CBorder& oBorder); private: CBorderSide m_oLeft; CBorderSide m_oTop; CBorderSide m_oRight; CBorderSide m_oBottom; + + CEnum m_enCollapse; }; class CTextDecorationLine @@ -512,6 +588,7 @@ namespace NSCSS bool LineThrough() const; CTextDecorationLine &operator+=(const CTextDecorationLine& oTextDecoration); + bool operator==(const CTextDecorationLine& oTextDecorationLine) const; }; struct TTextDecoration @@ -521,6 +598,7 @@ namespace NSCSS CColor m_oColor; TTextDecoration& operator+=(const TTextDecoration& oTextDecoration); + bool operator==(const TTextDecoration& oTextDecoration) const; }; class CText @@ -534,11 +612,13 @@ namespace NSCSS bool SetAlign (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); bool SetDecoration(const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); bool SetColor (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); + bool SetHighlight (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); const CDigit& GetIndent() const; const CString& GetAlign() const; const TTextDecoration& GetDecoration() const; const CColor& GetColor() const; + const CColor& GetHighlight() const; bool Empty() const; @@ -553,6 +633,7 @@ namespace NSCSS CDigit m_oIndent; CString m_oAlign; CColor m_oColor; + CColor m_oHighlight; }; class CIndent @@ -560,33 +641,44 @@ namespace NSCSS public: CIndent(); + void Clear(); + static void Equation(CIndent &oFirstMargin, CIndent &oSecondMargin); + bool Equals() const; + void SetPermisson(bool bPermission); - bool AddValue (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); - bool AddLeft (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); - bool AddTop (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); - bool AddRight (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); - bool AddBottom (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); - - void UpdateAll(double dFontSize); - void UpdateLeft(double dFontSize); - void UpdateTop(double dFontSize); - void UpdateRight(double dFontSize); - void UpdateBottom(double dFontSize); + bool SetValues (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); + bool SetTop (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); + bool SetTop (const double& dValue, unsigned int unLevel, bool bHardMode = false); + bool SetRight (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); + bool SetRight (const double& dValue, unsigned int unLevel, bool bHardMode = false); + bool SetBottom (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); + bool SetBottom (const double& dValue, unsigned int unLevel, bool bHardMode = false); + bool SetLeft (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); + bool SetLeft (const double& dValue, unsigned int unLevel, bool bHardMode = false); + + void UpdateAll (const double& dParentFontSize, const double& dCoreFontSize); + void UpdateTop (const double& dParentFontSize, const double& dCoreFontSize); + void UpdateRight (const double& dParentFontSize, const double& dCoreFontSize); + void UpdateBottom(const double& dParentFontSize, const double& dCoreFontSize); + void UpdateLeft (const double& dParentFontSize, const double& dCoreFontSize); - const CDigit& GetLeft () const; const CDigit& GetTop () const; const CDigit& GetRight () const; const CDigit& GetBottom() const; + const CDigit& GetLeft () const; bool Empty() const; + bool Zero() const; - CIndent& operator+=(const CIndent& oMargin); - bool operator==(const CIndent& oMargin) const; + CIndent& operator+=(const CIndent& oIndent); + bool operator==(const CIndent& oIndent) const; + bool operator!=(const CIndent& oIndent) const; private: - bool AddValue(CDigit& oValue, const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); + bool SetValues(const std::wstring& wsTopValue, const std::wstring& wsRightValue, const std::wstring& wsBottomValue, const std::wstring& wsLeftValue, unsigned int unLevel, bool bHardMode = false); + void UpdateSide(CDigit& oSide, const double& dParentFontSize, const double& dCoreFontSize); CDigit m_oLeft; CDigit m_oTop; @@ -605,6 +697,7 @@ namespace NSCSS bool SetValue (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); bool SetSize (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); + bool SetSize (const double& dValue, unsigned int unLevel, bool bHardMode = false); bool SetLineHeight (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); bool SetFamily (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); bool SetStretch (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); @@ -612,8 +705,8 @@ namespace NSCSS bool SetVariant (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); bool SetWeight (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); - void UpdateSize(double dFontSize); - void UpdateLineHeight(double dFontSize); + void UpdateSize(const double& dParentFontSize, const double& dCoreFontSize); + void UpdateLineHeight(const double& dParentFontSize, const double& dCoreFontSize); void Clear(); @@ -622,6 +715,7 @@ namespace NSCSS const CDigit& GetSize() const; const CDigit& GetLineHeight() const; + CDigit& GetLineHeight(); const CString& GetFamily() const; const CString& GetStretch() const; const CString& GetStyle() const; @@ -641,8 +735,29 @@ namespace NSCSS CString m_oStyle; CString m_oVariant; CString m_oWeight; + }; - TTextDecoration m_oTextDecoration; + class CPage + { + public: + CPage(); + + bool SetMargin (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); + bool SetSize (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); + bool SetFooter (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); + bool SetHeader (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); + + const CDigit& GetWidth() const; + const CDigit& GetHeight() const; + const CIndent& GetMargin() const; + const CDigit& GetFooter() const; + const CDigit& GetHeader() const; + private: + CDigit m_oWidth; + CDigit m_oHeight; + CIndent m_oMargin; + CDigit m_oFooter; + CDigit m_oHeader; }; } } diff --git a/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp b/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp index 6f4330d24a4..e01d31d89c7 100644 --- a/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp +++ b/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp @@ -1,19 +1,20 @@ #include "CDocumentStyle.h" #include +#include #include #include +#include #include #include +#define DEFAULT_LINEHEIGHT 240 #define LINEHEIGHTSCALE 10 // Значение LineHeight в OOXML должно быть в 10 раз больше чем указано в стиле -#define LINEHEIGHTCOEF 24 // Используется когда необходимо перевести в twips значение -#define POINTCOEF 20 // Используется для конвертации в OOXML значение интервала между абзацами (Измерение в двадцатых долях от точки) -#define PAGEWIDTH (12240 / POINTCOEF) -#define PAGEHEIGHT (15840 / POINTCOEF) - -#define DOUBLE_TO_INTW(dValue) std::to_wstring(static_cast(dValue + 0.5)) +#define VALUE_TO_INT(value, unit_measure) \ + (NSCSS::UnitMeasure::None != value.GetUnitMeasure()) ? \ + value.ToInt(unit_measure) : \ + static_cast(NSCSS::CUnitMeasureConverter::ConvertPx(value.ToDouble(), unit_measure, 96) + 0.5) namespace NSCSS { @@ -21,24 +22,55 @@ namespace NSCSS : m_oStyle(oStyle), m_bIsPStyle(bIsPStyle) {} + bool CheckArrays(const std::vector& arInitial, const std::set& arFirst, const std::set& arSecond) + { + std::unordered_set arInitialSet(arInitial.begin(), arInitial.end()); + + std::vector arCommonElements1; + std::vector arCommonElements2; + + for (const std::wstring& wsValue : arFirst) + { + if (arInitialSet.count(wsValue) > 0) + arCommonElements1.push_back(wsValue); + } + + for (const std::wstring& wsValue : arSecond) + { + if (arInitialSet.count(wsValue) > 0) + arCommonElements2.push_back(wsValue); + } + + if (arCommonElements1.size() != arCommonElements2.size()) + return false; + + std::sort(arCommonElements1.begin(), arCommonElements1.end()); + std::sort(arCommonElements2.begin(), arCommonElements2.end()); + + return arCommonElements1 == arCommonElements2; + } + bool CStyleUsed::operator==(const CStyleUsed &oUsedStyle) const { - return (m_bIsPStyle == oUsedStyle.m_bIsPStyle) && (m_oStyle == oUsedStyle.m_oStyle); + return m_bIsPStyle == oUsedStyle.m_bIsPStyle && + CheckArrays(Names_Standard_Styles, m_oStyle.GetParentsNamesSet(), oUsedStyle.m_oStyle.GetParentsNamesSet()) && + m_oStyle == oUsedStyle.m_oStyle; } std::wstring CStyleUsed::getId() { - return m_sId; + if (m_bIsPStyle) + return m_oStyle.GetId(); + + return m_oStyle.GetId() + L"-c"; } - void CStyleUsed::setId(const std::wstring &sId) + CDocumentStyle::CDocumentStyle() : m_arStandardStyles(Names_Standard_Styles) { - m_sId = sId; + for (const std::wstring& oNameStandardStyle : Names_Standard_Styles) + m_arStandardStyles.push_back(oNameStandardStyle + L"-c"); } - CDocumentStyle::CDocumentStyle() : m_arStandardStyles({L"a", L"li", L"h1", L"h2", L"h3", L"h4", L"h5", L"h6", L"h1-c", - L"h2-c", L"h3-c", L"h4-c", L"h5-c", L"h6-c", L"p-c", L"p", L"div-c", L"div", L"a-c"}) {} - CDocumentStyle::~CDocumentStyle() { m_arStandardStyles. clear(); @@ -157,6 +189,7 @@ namespace NSCSS if (!oParentStyle.Empty()) { + oParentStyle.AddBasicProperties(BProperties::B_BasedOn, L"normal"); oParentStyle.AddBasicProperties(BProperties::B_StyleId, L"(" + oParentStyle.GetStyleId() + L")"); if (!bIsPStyle) { @@ -271,250 +304,308 @@ namespace NSCSS oElement.AddBasicProperties(BProperties::B_CustomStyle, L"1"); } - void CDocumentStyle::SetPStyle (const NSCSS::CCompiledStyle& oStyle, CXmlElement& oXmlElement) + void CDocumentStyle::SetPStyle (const NSCSS::CCompiledStyle& oStyle, CXmlElement& oXmlElement, bool bIsLite) { - ConvertStyle(oStyle, oXmlElement, true); - if (oStyle.Empty() && oXmlElement.Empty()) + if (!bIsLite) + ConvertStyle(oStyle, oXmlElement, true); + + if (oStyle.Empty()) return; - - oXmlElement.AddPropertiesInP(PProperties::P_Jc, oStyle.m_oText.GetAlign().ToWString()); + + const bool bInTable{oStyle.HaveThisParent(L"table")}; + + std::wstring wsTextAlign{oStyle.m_oText.GetAlign().ToWString()}; + + if (wsTextAlign.empty()) + wsTextAlign = oStyle.m_oDisplay.GetHAlign().ToWString(); + + oXmlElement.AddPropertiesInP(PProperties::P_Jc, wsTextAlign); std::wstring sInfValue; sInfValue.reserve(64); - //TODO:: проверить Permission в Margin - if (!oStyle.m_oMargin.Empty() || !oStyle.m_oPadding.Empty() /*&& oStyle.m_oMargin.GetPermission()*/) - { - const double dLeftSide = oStyle.m_oMargin.GetLeft() .ToDouble(NSCSS::Twips) + oStyle.m_oPadding.GetLeft() .ToDouble(NSCSS::Twips); - const double dRightSide = oStyle.m_oMargin.GetRight().ToDouble(NSCSS::Twips) + oStyle.m_oPadding.GetRight().ToDouble(NSCSS::Twips); + if (!oStyle.m_oMargin.GetLeft().Empty() && !oStyle.m_oMargin.GetLeft().Zero()) + sInfValue += L"w:left=\"" + std::to_wstring(oStyle.m_oMargin.GetLeft().ToInt(NSCSS::Twips)) + L"\" "; - sInfValue += L"w:left=\"" + DOUBLE_TO_INTW(dLeftSide * POINTCOEF) + L"\" "; - sInfValue += L"w:right=\"" + DOUBLE_TO_INTW(dRightSide * POINTCOEF) + L"\" "; - } + if (!oStyle.m_oMargin.GetRight().Empty() && !oStyle.m_oMargin.GetRight().Zero()) + sInfValue += L"w:right=\"" + std::to_wstring(oStyle.m_oMargin.GetRight().ToInt(NSCSS::Twips)) + L"\" "; - const double dIndent = oStyle.m_oText.GetIndent().ToDouble(NSCSS::Twips); - - if (0. != dIndent) - sInfValue += L"w:firstLine=\"" + DOUBLE_TO_INTW(dIndent) + L"\" "; + const int nIndent = oStyle.m_oText.GetIndent().ToInt(NSCSS::Twips); + + if (0 != nIndent) + sInfValue += L"w:firstLine=\"" + std::to_wstring(nIndent) + L"\" "; oXmlElement.AddPropertiesInP(PProperties::P_Ind, sInfValue); std::wstring sSpacingValue; sSpacingValue.reserve(128); - //TODO:: проверить Permission в Margin - if (!oStyle.m_oMargin.Empty() || !oStyle.m_oPadding.Empty()/*&& oStyle.m_oMargin.GetPermission()*/) - { - const double dSpacingBottom = oStyle.m_oMargin.GetBottom().ToDouble(NSCSS::Twips) + oStyle.m_oPadding.GetBottom().ToDouble(NSCSS::Twips); - const double dSpacingTop = oStyle.m_oMargin.GetTop() .ToDouble(NSCSS::Twips) + oStyle.m_oPadding.GetTop() .ToDouble(NSCSS::Twips);; - - sSpacingValue += L" w:after=\"" + DOUBLE_TO_INTW(dSpacingBottom * POINTCOEF) + L"\" "; - sSpacingValue += L" w:before=\"" + DOUBLE_TO_INTW(dSpacingTop * POINTCOEF) + L"\" "; - } - else/* if (!oStyle.m_pBorder.Empty() || !oStyle.m_oMargin.GetPermission())*/ - sSpacingValue += L"w:after=\"0\" w:before=\"0\""; + if (!oStyle.m_oMargin.GetTop().Empty() && !oStyle.m_oMargin.GetTop().Zero()) + sSpacingValue += L"w:before=\"" + std::to_wstring(VALUE_TO_INT(oStyle.m_oMargin.GetTop(), NSCSS::Twips)) + L"\" w:beforeAutospacing=\"0\""; + else if (oStyle.m_oMargin.GetBottom().Zero() || bInTable) + sSpacingValue += L"w:before=\"0\" w:beforeAutospacing=\"0\""; - std::wstring wsLineHeight; - - if (!oStyle.m_oFont.GetLineHeight().Empty()) - { - double dLineHeight = oStyle.m_oFont.GetLineHeight().ToDouble(NSCSS::Twips, LINEHEIGHTCOEF) * LINEHEIGHTSCALE; + if (!oStyle.m_oMargin.GetBottom().Empty() && !oStyle.m_oMargin.GetBottom().Zero()) + sSpacingValue += L" w:after=\"" + std::to_wstring(VALUE_TO_INT(oStyle.m_oMargin.GetBottom(), NSCSS::Twips)) + L"\" w:afterAutospacing=\"0\""; + else if (oStyle.m_oMargin.GetBottom().Zero() || bInTable) + sSpacingValue += L" w:after=\"0\" w:afterAutospacing=\"0\""; - if (NSCSS::None == oStyle.m_oFont.GetLineHeight().GetUnitMeasure()) - dLineHeight *= LINEHEIGHTCOEF; - - if (0. != dLineHeight) - wsLineHeight = DOUBLE_TO_INTW(dLineHeight); - } - - if (!wsLineHeight.empty()) + if (!oStyle.m_oFont.GetLineHeight().Empty() && !oStyle.m_oFont.GetLineHeight().Zero()) { - sSpacingValue += L" w:line=\"" + wsLineHeight + L"\" w:lineRule=\"auto\""; + const std::wstring wsLine{std::to_wstring(oStyle.m_oFont.GetLineHeight().ToInt(NSCSS::Twips, DEFAULT_LINEHEIGHT))}; + const std::wstring wsLineRule{(NSCSS::Percent == oStyle.m_oFont.GetLineHeight().GetUnitMeasure() ? L"auto" : L"atLeast")}; + + sSpacingValue += L" w:line=\"" + wsLine + L"\" w:lineRule=\"" + wsLineRule + L"\""; } -// else if (!oStyle.m_oBorder.Empty()) -// { -// sSpacingValue += L" w:line=\"" + std::to_wstring(static_cast(oStyle.m_oFont.GetSize().ToDouble(NSCSS::Twips) * 2 * POINTCOEF + 0.5f)) + L"\" w:lineRule=\"auto\""; -// } - else if (!oStyle.m_oBorder.Empty()) - sSpacingValue += L" w:line=\"240\" w:lineRule=\"auto\" "; + else if (oStyle.m_oFont.GetLineHeight().Zero() || bInTable) + sSpacingValue += L" w:lineRule=\"auto\" w:line=\"240\""; if (!sSpacingValue.empty()) - { oXmlElement.AddPropertiesInP(PProperties::P_Spacing, sSpacingValue); - oXmlElement.AddPropertiesInP(PProperties::P_ContextualSpacing, L"true"); - } - if (!oStyle.m_oBackground.Empty()) - { - const std::wstring wsColor = oStyle.m_oBackground.GetColor().ToWString(); - if (wsColor != L"ffffff") - oXmlElement.AddPropertiesInP(PProperties::P_Shd, wsColor); - } + if (!oStyle.m_oBackground.Empty() && !bInTable) + oXmlElement.AddPropertiesInP(PProperties::P_Shd, oStyle.m_oBackground.IsNone() ? L"auto" : oStyle.m_oBackground.GetColor().ToWString()); - if (!oStyle.m_oBorder.Empty()) + if (!oStyle.m_oBorder.Empty() && !bInTable) { if (oStyle.m_oBorder.EqualSides()) { - const std::wstring sBorderColor = oStyle.m_oBorder.GetLeftBorder().GetColor().ToWString(); - const std::wstring sBorderStyle = oStyle.m_oBorder.GetLeftBorder().GetStyle().ToWString(); - const std::wstring sBorderWidth = oStyle.m_oBorder.GetLeftBorder().GetWidth().ToWString(); - - const std::wstring sBorder = L" w:color=\"" + sBorderColor + L"\" w:space=\"0\" w:sz=\"" + - sBorderWidth + L"\" w:val=\"" + sBorderStyle + L"\""; - - oXmlElement.AddPropertiesInP(PProperties::P_TopBorder, sBorder); - oXmlElement.AddPropertiesInP(PProperties::P_LeftBorder, sBorder); - oXmlElement.AddPropertiesInP(PProperties::P_BottomBorder, sBorder); - oXmlElement.AddPropertiesInP(PProperties::P_RightBorder, sBorder); + SetBorderStyle(oStyle, oXmlElement, PProperties::P_TopBorder); + SetBorderStyle(oStyle, oXmlElement, PProperties::P_LeftBorder); + SetBorderStyle(oStyle, oXmlElement, PProperties::P_BottomBorder); + SetBorderStyle(oStyle, oXmlElement, PProperties::P_RightBorder); } else { if (!oStyle.m_oBorder.GetTopBorder().Empty()) - { - const std::wstring sBorderColor = oStyle.m_oBorder.GetTopBorder().GetColor().ToWString(); - const std::wstring sBorderStyle = oStyle.m_oBorder.GetTopBorder().GetStyle().ToWString(); - const std::wstring sBorderWidth = oStyle.m_oBorder.GetTopBorder().GetWidth().ToWString(); + SetBorderStyle(oStyle, oXmlElement, PProperties::P_TopBorder); - const std::wstring sBorder = L" w:color=\"" + sBorderColor + L"\" w:space=\"4\" w:sz=\"" + - sBorderWidth + L"\" w:val=\"" + sBorderStyle + L"\""; + if (!oStyle.m_oBorder.GetRightBorder().Empty()) + SetBorderStyle(oStyle, oXmlElement, PProperties::P_RightBorder); - oXmlElement.AddPropertiesInP(PProperties::P_TopBorder, sBorder); - } + if (!oStyle.m_oBorder.GetBottomBorder().Empty()) + SetBorderStyle(oStyle, oXmlElement, PProperties::P_BottomBorder); - if (!oStyle.m_oBorder.GetRightBorder().Empty()) - { - const std::wstring sBorderColor = oStyle.m_oBorder.GetRightBorder().GetColor().ToWString(); - const std::wstring sBorderStyle = oStyle.m_oBorder.GetRightBorder().GetStyle().ToWString(); - const std::wstring sBorderWidth = oStyle.m_oBorder.GetRightBorder().GetWidth().ToWString(); + if (!oStyle.m_oBorder.GetLeftBorder().Empty()) + SetBorderStyle(oStyle, oXmlElement, PProperties::P_LeftBorder); + } + } + } - const std::wstring sBorder = L" w:color=\"" + sBorderColor + L"\" w:space=\"4\" w:sz=\"" + - sBorderWidth + L"\" w:val=\"" + sBorderStyle + L"\""; + void CDocumentStyle::SetBorderStyle(const CCompiledStyle &oStyle, CXmlElement &oXmlElement, const PProperties &enBorderProperty) + { + const NSCSS::NSProperties::CBorderSide* pBorder = NULL; + const NSCSS::NSProperties::CDigit* pPadding = NULL; - oXmlElement.AddPropertiesInP(PProperties::P_RightBorder, sBorder); - } + switch(enBorderProperty) + { + case PProperties::P_BottomBorder: + { + pBorder = &oStyle.m_oBorder.GetBottomBorder(); + pPadding = &oStyle.m_oPadding.GetBottom(); + break; + } + case PProperties::P_LeftBorder: + { + pBorder = &oStyle.m_oBorder.GetLeftBorder(); + pPadding = &oStyle.m_oPadding.GetLeft(); + break; + } + case PProperties::P_RightBorder: + { + pBorder = &oStyle.m_oBorder.GetRightBorder(); + pPadding = &oStyle.m_oPadding.GetRight(); + break; + } + case PProperties::P_TopBorder: + { + pBorder = &oStyle.m_oBorder.GetTopBorder(); + pPadding = &oStyle.m_oPadding.GetTop(); + break; + } + default: + return; + } - if (!oStyle.m_oBorder.GetBottomBorder().Empty()) - { - const std::wstring sBorderColor = oStyle.m_oBorder.GetBottomBorder().GetColor().ToWString(); - const std::wstring sBorderStyle = oStyle.m_oBorder.GetBottomBorder().GetStyle().ToWString(); - const std::wstring sBorderWidth = oStyle.m_oBorder.GetBottomBorder().GetWidth().ToWString(); + oXmlElement.AddPropertiesInP(enBorderProperty, CalculateBorderStyle(*pBorder, pPadding)); + } - const std::wstring sBorder = L" w:color=\"" + sBorderColor + L"\" w:space=\"4\" w:sz=\"" + - sBorderWidth + L"\" w:val=\"" + sBorderStyle + L"\""; + std::wstring CDocumentStyle::CalculateBorderStyle(const NSProperties::CBorderSide &oBorder, const NSProperties::CDigit *pPadding) + { + if (oBorder.Empty()) + return L""; + + std::wstring wsColor = oBorder.GetColor().ToWString(); + std::wstring wsStyle = oBorder.GetStyle().ToWString(); + + int nWidth = static_cast(std::round(oBorder.GetWidth().ToDouble(Point) * 8.)); + + if (L"double" == wsStyle) + nWidth /= 3; // в ooxml double граница формируется из трёх линий + + if (nWidth <= 3) + nWidth = 2; + else if (nWidth <= 5) + nWidth = 4; + else if (nWidth <= 7) + nWidth = 6; + else if (nWidth <= 9) + nWidth = 8; + else if (nWidth <= 15) + nWidth = 12; + else if (nWidth <= 21) + nWidth = 18; + else if (nWidth <= 29) + nWidth = 24; + else if (nWidth <= 41) + nWidth = 36; + else + nWidth = 48; - oXmlElement.AddPropertiesInP(PProperties::P_BottomBorder, sBorder); - } + if (wsColor.empty()) + wsColor = L"auto"; - if (!oStyle.m_oBorder.GetLeftBorder().Empty()) - { - const std::wstring sBorderColor = oStyle.m_oBorder.GetLeftBorder().GetColor().ToWString(); - const std::wstring sBorderStyle = oStyle.m_oBorder.GetLeftBorder().GetStyle().ToWString(); - const std::wstring sBorderWidth = oStyle.m_oBorder.GetLeftBorder().GetWidth().ToWString(); + if (wsStyle.empty()) + wsStyle = L"single"; - const std::wstring sBorder = L" w:color=\"" + sBorderColor + L"\" w:space=\"4\" w:sz=\"" + - sBorderWidth + L"\" w:val=\"" + sBorderStyle + L"\""; + int nSpace{0}; - oXmlElement.AddPropertiesInP(PProperties::P_LeftBorder, sBorder); - } - } - } + if (NULL != pPadding && !pPadding->Empty() && !pPadding->Zero()) + nSpace = pPadding->ToInt(NSCSS::Point); + + return L"w:val=\"" + wsStyle + L"\" w:sz=\"" + std::to_wstring(nWidth) + + L"\" w:space=\"" + std::to_wstring(nSpace) + L"\" w:color=\"" + wsColor + L"\""; } - void CDocumentStyle::SetRStyle(const NSCSS::CCompiledStyle& oStyle, CXmlElement& oXmlElement) + void CDocumentStyle::SetRStyle(const NSCSS::CCompiledStyle& oStyle, CXmlElement& oXmlElement, bool bIsLite) { - ConvertStyle(oStyle, oXmlElement, false); + if (!bIsLite) + ConvertStyle(oStyle, oXmlElement, false); + if (oStyle.Empty() && oXmlElement.Empty()) return; if (!oStyle.m_oFont.GetSize().Empty()) - oXmlElement.AddPropertiesInR(RProperties::R_Sz, DOUBLE_TO_INTW(oStyle.m_oFont.GetSize().ToDouble(NSCSS::Twips))); + oXmlElement.AddPropertiesInR(RProperties::R_Sz, std::to_wstring(static_cast(oStyle.m_oFont.GetSize().ToDouble(NSCSS::Point) * 2. * oStyle.m_oTransform.GetMatrix().GetFinalValue().sy() + 0.5))); // Значения шрифта увеличивает на 2 + + if (oStyle.m_oText.GetDecoration().m_oLine.Underline()) + oXmlElement.AddPropertiesInR(RProperties::R_U, (!oStyle.m_oText.GetDecoration().m_oStyle.Empty()) ? oStyle.m_oText.GetDecoration().m_oStyle.ToWString() : L"single"); + + if (!oStyle.m_oBackground.GetColor().Empty() && !oStyle.m_oBackground.GetColor().None() && !oStyle.m_oBackground.GetColor().Url()) + oXmlElement.AddPropertiesInR(RProperties::R_Shd, oStyle.m_oBackground.GetColor().ToWString()); + + const std::wstring wsHighlight{oStyle.m_oText.GetHighlight().EquateToColor({{{0, 0, 0}, L"black"}, {{0, 0, 255}, L"blue"}, {{0, 255, 255}, L"cyan"}, + {{0, 255, 0}, L"green"}, {{255, 0, 255}, L"magenta"}, {{255, 0, 0}, L"red"}, + {{255, 255, 0}, L"yellow"}, {{255, 255, 255}, L"white"}, {{0, 0, 139}, L"darkBlue"}, + {{0, 139, 139}, L"darkCyan"}, {{0, 100, 0}, L"darkGreen"}, {{139, 0, 139}, L"darkMagenta"}, + {{139, 0, 0}, L"darkRed"}, {{128, 128, 0}, L"darkYellow"},{{169, 169, 169}, L"darkGray"}, + {{211, 211, 211}, L"lightGray"}})}; + + if (L"none" != wsHighlight) + oXmlElement.AddPropertiesInR(RProperties::R_Highlight, wsHighlight); - oXmlElement.AddPropertiesInR(RProperties::R_Highlight, oStyle.m_oBackground.GetColor().ToWString()); oXmlElement.AddPropertiesInR(RProperties::R_Color, oStyle.m_oText.GetColor().ToWString()); - oXmlElement.AddPropertiesInR(RProperties::R_U, (oStyle.m_oText.GetDecoration().m_oLine.Underline()) ? L"underline" : L""); + + std::wstring wsFontFamily{oStyle.m_oFont.GetFamily().ToWString()}; + + if (L"sans-serif" == wsFontFamily) + wsFontFamily = L"Arial"; + else if (L"serif" == wsFontFamily) + wsFontFamily = L"Times New Roman"; + oXmlElement.AddPropertiesInR(RProperties::R_RFonts, oStyle.m_oFont.GetFamily().ToWString()); oXmlElement.AddPropertiesInR(RProperties::R_I, oStyle.m_oFont.GetStyle().ToWString()); oXmlElement.AddPropertiesInR(RProperties::R_B, oStyle.m_oFont.GetWeight().ToWString()); oXmlElement.AddPropertiesInR(RProperties::R_SmallCaps, oStyle.m_oFont.GetVariant().ToWString()); } - void CDocumentStyle::WriteRStyle (const NSCSS::CCompiledStyle& oStyle) + bool CDocumentStyle::WriteRStyle(const NSCSS::CCompiledStyle& oStyle) { + Clear(); + if(oStyle.GetId().empty()) - { - m_sId = L"normal"; - return; - } + return false; CStyleUsed structStyle(oStyle, false); - std::list::iterator oItem = std::find(m_arStyleUsed.begin(), m_arStyleUsed.end(), structStyle); + std::vector::iterator oItem = std::find(m_arStyleUsed.begin(), m_arStyleUsed.end(), structStyle); if (oItem != m_arStyleUsed.end()) { m_sId = (*oItem).getId(); - return; + return true; } + CXmlElement oXmlElement; SetRStyle(oStyle, oXmlElement); - if (!oStyle.Empty() || !oXmlElement.Empty()) - { - structStyle.setId(oXmlElement.GetStyleId()); - m_arStyleUsed.push_back(structStyle); - m_sStyle += oXmlElement.GetRStyle(); - } + if (oXmlElement.Empty()) + return false; + + m_arStyleUsed.push_back(structStyle); + m_sStyle += oXmlElement.GetRStyle(); + + return true; } - void CDocumentStyle::WriteLitePStyle(const CCompiledStyle &oStyle) + bool CDocumentStyle::WriteLitePStyle(const CCompiledStyle &oStyle) { + Clear(); + if (oStyle.Empty()) - return; + return false; CXmlElement oXmlElement; - SetPStyle(oStyle, oXmlElement); + SetPStyle(oStyle, oXmlElement, true); - if (!oXmlElement.Empty()) - m_sStyle += oXmlElement.GetPStyle(true); + if (oXmlElement.Empty()) + return false; + + m_sStyle += oXmlElement.GetPStyle(true); + return true; } - void CDocumentStyle::WriteLiteRStyle(const CCompiledStyle &oStyle) + bool CDocumentStyle::WriteLiteRStyle(const CCompiledStyle &oStyle) { + Clear(); + if (oStyle.Empty()) - return; + return false; CXmlElement oXmlElement; - SetRStyle(oStyle, oXmlElement); + SetRStyle(oStyle, oXmlElement, true); - if (!oXmlElement.Empty()) - m_sStyle += oXmlElement.GetRStyle(true); + if (oXmlElement.Empty()) + return false; + + m_sStyle += oXmlElement.GetRStyle(true); + return true; } - void CDocumentStyle::WritePStyle (const NSCSS::CCompiledStyle& oStyle) + bool CDocumentStyle::WritePStyle(const NSCSS::CCompiledStyle& oStyle) { + Clear(); + if(oStyle.GetId().empty()) - { - m_sId = L"normal"; - return; - } + return false; CStyleUsed structStyle(oStyle, true); - std::list::iterator oItem = std::find(m_arStyleUsed.begin(), m_arStyleUsed.end(), structStyle); + std::vector::iterator oItem = std::find(m_arStyleUsed.begin(), m_arStyleUsed.end(), structStyle); if (oItem != m_arStyleUsed.end()) { m_sId = (*oItem).getId(); - return; + return true; } CXmlElement oXmlElement; SetPStyle(oStyle, oXmlElement); - if (!oStyle.Empty() || !oXmlElement.Empty()) - { - structStyle.setId(oXmlElement.GetStyleId()); - m_arStyleUsed.push_back(structStyle); - m_sStyle += oXmlElement.GetPStyle(); - } + if (oXmlElement.Empty()) + return false; + + m_arStyleUsed.push_back(structStyle); + m_sStyle += oXmlElement.GetPStyle(); + + return true; } } diff --git a/Common/3dParty/html/css/src/xhtml/CDocumentStyle.h b/Common/3dParty/html/css/src/xhtml/CDocumentStyle.h index 886abc8c62d..4d9a349db21 100644 --- a/Common/3dParty/html/css/src/xhtml/CDocumentStyle.h +++ b/Common/3dParty/html/css/src/xhtml/CDocumentStyle.h @@ -12,7 +12,6 @@ namespace NSCSS { CCompiledStyle m_oStyle; bool m_bIsPStyle; - std::wstring m_sId; public: CStyleUsed(const CCompiledStyle& oStyle, bool bIsPStyle); @@ -20,18 +19,19 @@ namespace NSCSS bool operator==(const CStyleUsed& oUsedStyle) const; std::wstring getId(); - void setId(const std::wstring& sId); }; + static const std::vector Names_Standard_Styles = {L"a", L"li", L"h1", L"h2", L"h3", L"h4", L"h5", L"h6",L"p", L"div"}; + class CSSCALCULATOR_EXPORT CDocumentStyle { typedef NSConstValues::NSProperties::BasicProperties BProperties; typedef NSConstValues::NSProperties::ParagraphProperties PProperties; typedef NSConstValues::NSProperties::RunnerProperties RProperties; - std::list m_arStandardStylesUsed; - std::list m_arStandardStyles; - std::list m_arStyleUsed; + std::vector m_arStandardStylesUsed; + std::vector m_arStandardStyles; + std::vector m_arStyleUsed; std::wstring m_sStyle; std::wstring m_sId; @@ -40,17 +40,18 @@ namespace NSCSS void CreateStandardStyle (const std::wstring& sNameStyle, CXmlElement& oElement); void ConvertStyle (const NSCSS::CCompiledStyle& oStyle, CXmlElement& oElement, bool bIsPStyle); - void SetRStyle(const NSCSS::CCompiledStyle& oStyle, CXmlElement& oXmlElement); - void SetPStyle(const NSCSS::CCompiledStyle& oStyle, CXmlElement& oXmlElement); + void SetRStyle(const NSCSS::CCompiledStyle& oStyle, CXmlElement& oXmlElement, bool bIsLite = false); + void SetPStyle(const NSCSS::CCompiledStyle& oStyle, CXmlElement& oXmlElement, bool bIsLite = false); + void SetBorderStyle(const NSCSS::CCompiledStyle& oStyle, CXmlElement& oXmlElement, const PProperties& enBorderProperty); public: CDocumentStyle(); ~CDocumentStyle(); - void WritePStyle(const NSCSS::CCompiledStyle& oStyle); - void WriteRStyle(const NSCSS::CCompiledStyle& oStyle); - void WriteLitePStyle(const NSCSS::CCompiledStyle& oStyle); - void WriteLiteRStyle(const NSCSS::CCompiledStyle& oStyle); + bool WritePStyle(const NSCSS::CCompiledStyle& oStyle); + bool WriteRStyle(const NSCSS::CCompiledStyle& oStyle); + bool WriteLitePStyle(const NSCSS::CCompiledStyle& oStyle); + bool WriteLiteRStyle(const NSCSS::CCompiledStyle& oStyle); void SetStyle(const std::wstring& sStyle); void SetId (const std::wstring& sId); @@ -59,6 +60,8 @@ namespace NSCSS std::wstring GetIdAndClear(); void Clear(); + + static std::wstring CalculateBorderStyle(const NSCSS::NSProperties::CBorderSide& oBorder, const NSCSS::NSProperties::CDigit* pPadding = NULL); }; } #endif // CDOCUMENTSTYLE_H diff --git a/Common/3dParty/html/css/src/xhtml/CXmlElement.cpp b/Common/3dParty/html/css/src/xhtml/CXmlElement.cpp index a3cb37abe29..6eb112e02a7 100644 --- a/Common/3dParty/html/css/src/xhtml/CXmlElement.cpp +++ b/Common/3dParty/html/css/src/xhtml/CXmlElement.cpp @@ -27,7 +27,7 @@ CXmlElement::CXmlElement(const std::wstring& sNameDefaultElement) bool CXmlElement::Empty() const { - return m_mBasicValues.empty() && m_mPStyleValues.empty() && m_mRStyleValues.empty(); + return m_mPStyleValues.empty() && m_mRStyleValues.empty() && GetBasedOn().empty(); } void CXmlElement::CreateDefaultElement(const std::wstring& sNameDefaultElement) @@ -35,7 +35,19 @@ void CXmlElement::CreateDefaultElement(const std::wstring& sNameDefaultElement) if (!Empty()) Clear(); - if (sNameDefaultElement == L"li") +/* if (sNameDefaultElement == L"p") + { + AddBasicProperties(CSSProperties::BasicProperties::B_Type, L"paragraph"); + AddBasicProperties(CSSProperties::BasicProperties::B_StyleId, L"p"); + AddBasicProperties(CSSProperties::BasicProperties::B_Name, L"Normal (Web)"); + AddBasicProperties(CSSProperties::BasicProperties::B_BasedOn, L"normal"); + AddBasicProperties(CSSProperties::BasicProperties::B_UiPriority, L"99"); + AddBasicProperties(CSSProperties::BasicProperties::B_UnhideWhenUsed, L"true"); + AddBasicProperties(CSSProperties::BasicProperties::B_SemiHidden, L"true"); + +// AddPropertiesInP(CSSProperties::ParagraphProperties::P_Spacing, L"w:before=\"100\" w:beforeAutospacing=\"1\" w:after=\"100\" w:afterAutospacing=\"1\""); + } + else */if (sNameDefaultElement == L"li") { AddBasicProperties(CSSProperties::BasicProperties::B_Type, L"paragraph"); AddBasicProperties(CSSProperties::BasicProperties::B_StyleId, L"li"); @@ -55,7 +67,7 @@ void CXmlElement::CreateDefaultElement(const std::wstring& sNameDefaultElement) AddBasicProperties(CSSProperties::BasicProperties::B_Link, L"h1-c"); AddPropertiesInP(CSSProperties::ParagraphProperties::P_OutlineLvl, L"0"); - AddPropertiesInP(CSSProperties::ParagraphProperties::P_Spacing, L"w:after=\"0\" w:before=\"480\""); +// AddPropertiesInP(CSSProperties::ParagraphProperties::P_Spacing, L"w:before=\"100\" w:beforeAutospacing=\"1\" w:after=\"100\" w:afterAutospacing=\"1\""); } else if (sNameDefaultElement == L"h2") { @@ -66,7 +78,7 @@ void CXmlElement::CreateDefaultElement(const std::wstring& sNameDefaultElement) AddBasicProperties(CSSProperties::BasicProperties::B_Link, L"h2-c"); AddPropertiesInP(CSSProperties::ParagraphProperties::P_OutlineLvl, L"1"); - AddPropertiesInP(CSSProperties::ParagraphProperties::P_Spacing, L"w:after=\"0\" w:before=\"400\""); +// AddPropertiesInP(CSSProperties::ParagraphProperties::P_Spacing, L"w:before=\"100\" w:beforeAutospacing=\"1\" w:after=\"100\" w:afterAutospacing=\"1\""); } else if (sNameDefaultElement == L"h3") { @@ -77,7 +89,7 @@ void CXmlElement::CreateDefaultElement(const std::wstring& sNameDefaultElement) AddBasicProperties(CSSProperties::BasicProperties::B_Link, L"h3-c"); AddPropertiesInP(CSSProperties::ParagraphProperties::P_OutlineLvl, L"2"); - AddPropertiesInP(CSSProperties::ParagraphProperties::P_Spacing, L"w:after=\"0\" w:before=\"360\""); +// AddPropertiesInP(CSSProperties::ParagraphProperties::P_Spacing, L"w:before=\"100\" w:beforeAutospacing=\"1\" w:after=\"100\" w:afterAutospacing=\"1\""); } else if (sNameDefaultElement == L"h4") { @@ -88,7 +100,7 @@ void CXmlElement::CreateDefaultElement(const std::wstring& sNameDefaultElement) AddBasicProperties(CSSProperties::BasicProperties::B_Link, L"h4-c"); AddPropertiesInP(CSSProperties::ParagraphProperties::P_OutlineLvl, L"3"); - AddPropertiesInP(CSSProperties::ParagraphProperties::P_Spacing, L"w:after=\"0\" w:before=\"320\""); +// AddPropertiesInP(CSSProperties::ParagraphProperties::P_Spacing, L"w:before=\"100\" w:beforeAutospacing=\"1\" w:after=\"100\" w:afterAutospacing=\"1\""); } else if (sNameDefaultElement == L"h5") { @@ -99,7 +111,7 @@ void CXmlElement::CreateDefaultElement(const std::wstring& sNameDefaultElement) AddBasicProperties(CSSProperties::BasicProperties::B_Link, L"h5-c"); AddPropertiesInP(CSSProperties::ParagraphProperties::P_OutlineLvl, L"4"); - AddPropertiesInP(CSSProperties::ParagraphProperties::P_Spacing, L"w:after=\"0\" w:before=\"280\""); +// AddPropertiesInP(CSSProperties::ParagraphProperties::P_Spacing, L"w:before=\"100\" w:beforeAutospacing=\"1\" w:after=\"100\" w:afterAutospacing=\"1\""); } else if (sNameDefaultElement == L"h6") @@ -111,7 +123,7 @@ void CXmlElement::CreateDefaultElement(const std::wstring& sNameDefaultElement) AddBasicProperties(CSSProperties::BasicProperties::B_Link, L"h6-c"); AddPropertiesInP(CSSProperties::ParagraphProperties::P_OutlineLvl, L"5"); - AddPropertiesInP(CSSProperties::ParagraphProperties::P_Spacing, L"w:after=\"0\" w:before=\"280\""); +// AddPropertiesInP(CSSProperties::ParagraphProperties::P_Spacing, L"w:before=\"100\" w:beforeAutospacing=\"1\" w:after=\"100\" w:afterAutospacing=\"1\""); } else if (sNameDefaultElement == L"h1-c") { @@ -122,9 +134,9 @@ void CXmlElement::CreateDefaultElement(const std::wstring& sNameDefaultElement) AddBasicProperties(CSSProperties::BasicProperties::B_UiPriority, L"9"); AddBasicProperties(CSSProperties::BasicProperties::B_Link, L"h1"); - AddPropertiesInR(CSSProperties::RunnerProperties::R_RFonts, DEFAULTFONTNAME); AddPropertiesInR(CSSProperties::RunnerProperties::R_B, L"bold"); - AddPropertiesInR(CSSProperties::RunnerProperties::R_Sz, L"44"); + AddPropertiesInR(CSSProperties::RunnerProperties::R_Sz, L"48"); + AddPropertiesInR(CSSProperties::RunnerProperties::R_Kern, L"36"); } else if (sNameDefaultElement == L"h2-c") { @@ -136,9 +148,8 @@ void CXmlElement::CreateDefaultElement(const std::wstring& sNameDefaultElement) AddBasicProperties(CSSProperties::BasicProperties::B_UnhideWhenUsed, L"true"); AddBasicProperties(CSSProperties::BasicProperties::B_Link, L"h2"); - AddPropertiesInR(CSSProperties::RunnerProperties::R_RFonts, DEFAULTFONTNAME); AddPropertiesInR(CSSProperties::RunnerProperties::R_B, L"bold"); - AddPropertiesInR(CSSProperties::RunnerProperties::R_Sz, L"33"); + AddPropertiesInR(CSSProperties::RunnerProperties::R_Sz, L"36"); } else if (sNameDefaultElement == L"h3-c") { @@ -150,9 +161,8 @@ void CXmlElement::CreateDefaultElement(const std::wstring& sNameDefaultElement) AddBasicProperties(CSSProperties::BasicProperties::B_UnhideWhenUsed, L"true"); AddBasicProperties(CSSProperties::BasicProperties::B_Link, L"h3"); - AddPropertiesInR(CSSProperties::RunnerProperties::R_RFonts, DEFAULTFONTNAME); AddPropertiesInR(CSSProperties::RunnerProperties::R_B, L"bold"); - AddPropertiesInR(CSSProperties::RunnerProperties::R_Sz, L"26"); + AddPropertiesInR(CSSProperties::RunnerProperties::R_Sz, L"27"); } else if (sNameDefaultElement == L"h4-c") { @@ -164,9 +174,8 @@ void CXmlElement::CreateDefaultElement(const std::wstring& sNameDefaultElement) AddBasicProperties(CSSProperties::BasicProperties::B_UnhideWhenUsed, L"true"); AddBasicProperties(CSSProperties::BasicProperties::B_Link, L"h4"); - AddPropertiesInR(CSSProperties::RunnerProperties::R_RFonts, DEFAULTFONTNAME); + AddPropertiesInR(CSSProperties::RunnerProperties::R_Sz, L"24"); AddPropertiesInR(CSSProperties::RunnerProperties::R_B, L"bold"); - AddPropertiesInR(CSSProperties::RunnerProperties::R_Sz, L"22"); } else if (sNameDefaultElement == L"h5-c") { @@ -178,9 +187,8 @@ void CXmlElement::CreateDefaultElement(const std::wstring& sNameDefaultElement) AddBasicProperties(CSSProperties::BasicProperties::B_UnhideWhenUsed, L"true"); AddBasicProperties(CSSProperties::BasicProperties::B_Link, L"h5"); - AddPropertiesInR(CSSProperties::RunnerProperties::R_RFonts, DEFAULTFONTNAME); + AddPropertiesInR(CSSProperties::RunnerProperties::R_Sz, L"20"); AddPropertiesInR(CSSProperties::RunnerProperties::R_B, L"bold"); - AddPropertiesInR(CSSProperties::RunnerProperties::R_Sz, L"18"); } else if (sNameDefaultElement == L"h6-c") { @@ -192,38 +200,16 @@ void CXmlElement::CreateDefaultElement(const std::wstring& sNameDefaultElement) AddBasicProperties(CSSProperties::BasicProperties::B_UnhideWhenUsed, L"true"); AddBasicProperties(CSSProperties::BasicProperties::B_Link, L"h6"); - AddPropertiesInR(CSSProperties::RunnerProperties::R_RFonts, DEFAULTFONTNAME); - AddPropertiesInR(CSSProperties::RunnerProperties::R_B, L"bold"); AddPropertiesInR(CSSProperties::RunnerProperties::R_Sz, L"15"); + AddPropertiesInR(CSSProperties::RunnerProperties::R_B, L"bold"); } - else if (sNameDefaultElement == L"p-c") - { - AddBasicProperties(CSSProperties::BasicProperties::B_Type, L"character"); - AddBasicProperties(CSSProperties::BasicProperties::B_StyleId, L"p-c"); - AddBasicProperties(CSSProperties::BasicProperties::B_CustomStyle, L"1"); - AddBasicProperties(CSSProperties::BasicProperties::B_Name, L"Paragraph character"); - AddBasicProperties(CSSProperties::BasicProperties::B_Link, L"p"); - - AddPropertiesInR(CSSProperties::RunnerProperties::R_RFonts, DEFAULTFONTNAME); - } - else if (sNameDefaultElement == L"p") - { - AddBasicProperties(CSSProperties::BasicProperties::B_Type, L"paragraph"); - AddBasicProperties(CSSProperties::BasicProperties::B_StyleId, L"p"); - AddBasicProperties(CSSProperties::BasicProperties::B_CustomStyle, L"1"); - AddBasicProperties(CSSProperties::BasicProperties::B_Name, L"Paragraph"); - AddBasicProperties(CSSProperties::BasicProperties::B_BasedOn, L"normal"); - AddBasicProperties(CSSProperties::BasicProperties::B_Link, L"p-c"); - } - else if (sNameDefaultElement == L"div-c") + /*else if (sNameDefaultElement == L"div-c") { AddBasicProperties(CSSProperties::BasicProperties::B_Type, L"character"); AddBasicProperties(CSSProperties::BasicProperties::B_StyleId, L"div-c"); AddBasicProperties(CSSProperties::BasicProperties::B_CustomStyle, L"1"); AddBasicProperties(CSSProperties::BasicProperties::B_Name, L"Div character"); AddBasicProperties(CSSProperties::BasicProperties::B_Link, L"div"); - - AddPropertiesInR(CSSProperties::RunnerProperties::R_RFonts, DEFAULTFONTNAME); } else if (sNameDefaultElement == L"div") { @@ -233,7 +219,7 @@ void CXmlElement::CreateDefaultElement(const std::wstring& sNameDefaultElement) AddBasicProperties(CSSProperties::BasicProperties::B_Name, L"Div paragraph"); AddBasicProperties(CSSProperties::BasicProperties::B_BasedOn, L"normal"); AddBasicProperties(CSSProperties::BasicProperties::B_Link, L"div-c"); - } + }*/ else if (sNameDefaultElement == L"a-c") { AddBasicProperties(CSSProperties::BasicProperties::B_Type, L"character"); @@ -242,9 +228,9 @@ void CXmlElement::CreateDefaultElement(const std::wstring& sNameDefaultElement) AddBasicProperties(CSSProperties::BasicProperties::B_UiPriority, L"99"); AddBasicProperties(CSSProperties::BasicProperties::B_UnhideWhenUsed, L"true"); + AddPropertiesInR(CSSProperties::RunnerProperties::R_Sz, L"24"); AddPropertiesInR(CSSProperties::RunnerProperties::R_Color, L"0000FF"); AddPropertiesInR(CSSProperties::RunnerProperties::R_U, L"single"); - AddPropertiesInR(CSSProperties::RunnerProperties::R_RFonts, DEFAULTFONTNAME); } else if (sNameDefaultElement == L"a") { @@ -312,7 +298,7 @@ CXmlElement& CXmlElement::operator=(const CXmlElement& oElement) return *this; } -bool CXmlElement::operator==(const CXmlElement &oElement) +bool CXmlElement::operator==(const CXmlElement &oElement) const { return m_mBasicValues == oElement.m_mBasicValues && m_mPStyleValues == oElement.m_mPStyleValues && @@ -364,22 +350,22 @@ std::wstring CXmlElement::ConvertPStyle(bool bIsLite) const case CSSProperties::ParagraphProperties::P_TopBorder: { - sPBdr += L""; + sPBdr += L""; break; } case CSSProperties::ParagraphProperties::P_LeftBorder: { - sPBdr += L""; + sPBdr += L""; break; } case CSSProperties::ParagraphProperties::P_BottomBorder: { - sPBdr += L""; + sPBdr += L""; break; } case CSSProperties::ParagraphProperties::P_RightBorder: { - sPBdr += L""; + sPBdr += L""; break; } case CSSProperties::ParagraphProperties::P_KeepLines: @@ -429,8 +415,8 @@ std::wstring CXmlElement::ConvertRStyle(bool bIsLite) const } case CSSProperties::RunnerProperties::R_Sz: { - sRStyle += L"" + L""; + sRStyle += L"" + + L""; break; } case CSSProperties::RunnerProperties::R_B: @@ -462,11 +448,18 @@ std::wstring CXmlElement::ConvertRStyle(bool bIsLite) const sRStyle += L""; break; } -// case CSSProperties::RunnerProperties::R_Highlight: -// { -// sRStyle += L""; -// break; -// } + case CSSProperties::RunnerProperties::R_Highlight: + { + if (!oItem.second.empty()) + sRStyle += L""; + break; + } + case CSSProperties::RunnerProperties::R_Shd: + { + if (!oItem.second.empty()) + sRStyle += L""; + break; + } case CSSProperties::RunnerProperties::R_SmallCaps: { if (oItem.second == L"smallCaps") @@ -475,6 +468,11 @@ std::wstring CXmlElement::ConvertRStyle(bool bIsLite) const sRStyle += L""; break; } + case CSSProperties::RunnerProperties::R_Kern: + { + sRStyle += L""; + break; + } default: break; } @@ -519,7 +517,8 @@ std::wstring CXmlElement::ConvertBasicInfoStyle() const } case CSSProperties::BasicProperties::B_UnhideWhenUsed: { - sBasicInfo += L""; + if (L"true" == oItem.second) + sBasicInfo += L""; break; } case CSSProperties::BasicProperties::B_UiPriority: @@ -527,6 +526,12 @@ std::wstring CXmlElement::ConvertBasicInfoStyle() const sBasicInfo += L""; break; } + case CSSProperties::BasicProperties::B_SemiHidden: + { + if (L"true" == oItem.second) + sBasicInfo += L""; + break; + } default: break; } @@ -598,7 +603,7 @@ std::wstring CXmlElement::GetPStyle(bool bIsLite) const { if (bIsLite) return ConvertPStyle(true); - + return GetStyle(true, true, false); } @@ -606,7 +611,7 @@ std::wstring CXmlElement::GetRStyle(bool bIsLite) const { if (bIsLite) return ConvertRStyle(true); - + return GetStyle(true, false, true); } diff --git a/Common/3dParty/html/css/src/xhtml/CXmlElement.h b/Common/3dParty/html/css/src/xhtml/CXmlElement.h index 4a7b0fa4bd8..8c5835abe76 100644 --- a/Common/3dParty/html/css/src/xhtml/CXmlElement.h +++ b/Common/3dParty/html/css/src/xhtml/CXmlElement.h @@ -47,7 +47,7 @@ class CXmlElement CXmlElement& operator+=(const CXmlElement& oElement); CXmlElement& operator= (const CXmlElement& oelement); - bool operator== (const CXmlElement& oElement); + bool operator== (const CXmlElement& oElement) const; }; #endif // CXMLELEMENT_H diff --git a/Common/3dParty/html/fetch.py b/Common/3dParty/html/fetch.py index e9a44930c5b..4a0d3f5068f 100644 --- a/Common/3dParty/html/fetch.py +++ b/Common/3dParty/html/fetch.py @@ -5,7 +5,6 @@ import config import base import os -import build base_directory = os.getcwd() diff --git a/Common/3dParty/html/htmltoxhtml.h b/Common/3dParty/html/htmltoxhtml.h index 945bb8286ee..3fdf63a5d10 100644 --- a/Common/3dParty/html/htmltoxhtml.h +++ b/Common/3dParty/html/htmltoxhtml.h @@ -11,7 +11,9 @@ #include "../../../DesktopEditor/common/File.h" #include "../../../DesktopEditor/common/Directory.h" #include "../../../DesktopEditor/common/StringBuilder.h" +#include "../../../DesktopEditor/xml/include/xmlutils.h" #include "../../../UnicodeConverter/UnicodeConverter.h" +#include "../../../HtmlFile2/src/StringFinder.h" static std::string nonbreaking_inline = "|a|abbr|acronym|b|bdo|big|cite|code|dfn|em|font|i|img|kbd|nobr|s|small|span|strike|strong|sub|sup|tt|"; static std::string empty_tags = "|area|base|basefont|bgsound|br|command|col|embed|event-source|frame|hr|image|img|input|keygen|link|menuitem|meta|param|source|spacer|track|wbr|"; @@ -20,8 +22,27 @@ static std::string special_handling = "|html|body|"; static std::string no_entity_sub = ""; //"|style|"; static std::string treat_like_inline = "|p|"; -static void prettyprint(GumboNode*, NSStringUtils::CStringBuilderA& oBuilder); -static std::string mhtTohtml(std::string& sFileContent); +static std::vector html_tags = {"div","span","a","img","p","h1","h2","h3","h4","h5","h6", + "ul", "ol", "li","td","tr","table","thead","tbody","tfoot","th", + "br","form","input","button","section","nav","header","footer", + "main","figure","figcaption","strong","em","i", "b", "u","pre", + "code","blockquote","hr","script","link","meta","style","title", + "head","body","html","legend","optgroup","option","select","dl", + "dt","dd","time","data","abbr","address","area","base","bdi", + "bdo","cite","col","iframe","video","source","track","textarea", + "label","fieldset","colgroup","del","ins","details","summary", + "dialog","embed","kbd","map","mark","menu","meter","object", + "output","param","progress","q","samp","small","sub","sup","var", + "wbr","acronym","applet","article","aside","audio","basefont", + "bgsound","big","blink","canvas","caption","center","command", + "comment","datalist","dfn","dir","font","frame","frameset", + "hgroup","isindex","keygen","marquee","nobr","noembed","noframes", + "noscript","plaintext","rp","rt","ruby","s","strike","tt","xmp"}; + +static std::vector unchecked_nodes_new = {"svg"}; + +static void prettyprint(GumboNode*, NSStringUtils::CStringBuilderA& oBuilder, bool bCheckValidNode = true); +static std::string mhtTohtml(const std::string &sFileContent); // Заменяет в строке s все символы s1 на s2 static void replace_all(std::string& s, const std::string& s1, const std::string& s2) @@ -34,70 +55,45 @@ static void replace_all(std::string& s, const std::string& s1, const std::string } } +static bool NodeIsUnprocessed(const std::string& wsTagName) +{ + return "xml" == wsTagName; +} + +static bool IsUnckeckedNodes(const std::string& sValue) +{ + return unchecked_nodes_new.end() != std::find(unchecked_nodes_new.begin(), unchecked_nodes_new.end(), sValue); +} + static std::wstring htmlToXhtml(std::string& sFileContent, bool bNeedConvert) { - // Распознование кодировки if (bNeedConvert) - { - size_t posEncoding = sFileContent.find("charset="); - if (posEncoding == std::string::npos) - posEncoding = sFileContent.find("encoding="); - if (posEncoding != std::string::npos) - { - posEncoding = sFileContent.find("=", posEncoding) + 1; - char quoteSymbol = '\"'; - if(sFileContent[posEncoding] == '\"' || sFileContent[posEncoding] == '\'') - { - quoteSymbol = sFileContent[posEncoding]; - posEncoding += 1; - } + { // Определение кодировки + std::string sEncoding = NSStringFinder::FindPropety(sFileContent, "charset", {"="}, {";", "\\n", "\\r", " ", "\""}).m_sValue; - size_t posEnd = sFileContent.find(quoteSymbol, posEncoding); - if (std::string::npos != posEnd) - { - std::string sEncoding = sFileContent.substr(posEncoding, posEnd - posEncoding); - if (sEncoding != "utf-8" && sEncoding != "UTF-8") - { - NSUnicodeConverter::CUnicodeConverter oConverter; - sFileContent = U_TO_UTF8(oConverter.toUnicode(sFileContent, sEncoding.c_str())); - } - } + if (sEncoding.empty()) + sEncoding = NSStringFinder::FindPropety(sFileContent, "encoding", {"="}, {";", "\\n", "\\r", " "}).m_sValue; + + if (!sEncoding.empty() && !NSStringFinder::Equals("utf-8", sEncoding)) + { + NSUnicodeConverter::CUnicodeConverter oConverter; + sFileContent = U_TO_UTF8(oConverter.toUnicode(sFileContent, sEncoding.c_str())); } } - // Избавление от - size_t posA = sFileContent.find("", posA); - if(nEnd < nBegin) - sFileContent.replace(nEnd, 2, ">"); - posA = sFileContent.find(" - posA = sFileContent.find(""); - while (posA != std::string::npos) - { - sFileContent.replace(posA, 8, "<title>"); - posA = sFileContent.find("", posA); - } - // Избавление от <script/> - posA = sFileContent.find("<script"); - while (posA != std::string::npos) - { - size_t nEnd = 0; - size_t nEnd1 = sFileContent.find("/>", posA); - size_t nEnd2 = sFileContent.find("</script>", posA); - if (nEnd1 != std::string::npos) - nEnd = nEnd1 + 2; - if (nEnd2 != std::string::npos && (nEnd == 0 || (nEnd > 0 && nEnd2 < nEnd))) - nEnd = nEnd2 + 9; + // Избавляемся от лишних символов до <... + boost::regex oRegex("<[a-zA-Z]"); + boost::match_results<typename std::string::const_iterator> oResult; - sFileContent.erase(posA, nEnd - posA); + if (boost::regex_search(sFileContent, oResult, oRegex)) + sFileContent.erase(0, oResult.position()); - posA = sFileContent.find("<script", posA); - } + //Избавление от <a ... /> + while (NSStringFinder::RemoveEmptyTag(sFileContent, "a")); + //Избавление от <title ... /> + while (NSStringFinder::RemoveEmptyTag(sFileContent, "title")); + //Избавление от <script ... /> + while (NSStringFinder::RemoveEmptyTag(sFileContent, "script")); // Gumbo GumboOptions options = kGumboDefaultOptions; @@ -120,7 +116,7 @@ static std::string Base64ToString(const std::string& sContent, const std::string if (TRUE == NSBase64::Base64Decode(sContent.c_str(), nSrcLen, pData, &nDecodeLen)) { std::wstring sConvert; - if(!sCharset.empty() && sCharset != "utf-8" && sCharset != "UTF-8") + if(!sCharset.empty() && NSStringFinder::Equals<std::string>("utf-8", sCharset)) { NSUnicodeConverter::CUnicodeConverter oConverter; sConvert = oConverter.toUnicode(reinterpret_cast<char *>(pData), (unsigned)nDecodeLen, sCharset.data()); @@ -208,174 +204,125 @@ static std::string QuotedPrintableDecode(const std::string& sContent, std::strin return sRes.GetData(); } -static void ReadMht(std::string& sFileContent, size_t& nFound, size_t& nNextFound, const std::string& sBoundary, - std::map<std::string, std::string>& sRes, NSStringUtils::CStringBuilderA& oRes) +static void ReadMht(const std::string& sMhtContent, std::map<std::string, std::string>& sRes, NSStringUtils::CStringBuilderA& oRes) { - // Content - size_t nContentTag = sFileContent.find("\n\n", nFound); - if(nContentTag == std::string::npos || nContentTag > nNextFound) - { - nContentTag = sFileContent.find("\r\r", nFound); - if(nContentTag == std::string::npos || nContentTag > nNextFound) - { - nContentTag = sFileContent.find("\r\n\r\n", nFound); - if(nContentTag == std::string::npos || nContentTag > nNextFound) - { - nFound = nNextFound; - return; - } - else - nContentTag += 4; - } - else - nContentTag += 2; - } - else - nContentTag += 2; + size_t unContentPosition = 0, unCharsetBegin = 0, unCharsetEnd = std::string::npos; + NSStringFinder::TFoundedData<char> oData; + // Content-Type - size_t nTag = sFileContent.find("Content-Type: ", nFound); - if(nTag == std::string::npos || nTag > nContentTag) - { - nFound = nNextFound; + oData = NSStringFinder::FindPropety(sMhtContent, "content-type", {":"}, {";", "\\n", "\\r"}); + const std::string sContentType{oData.m_sValue}; + + if (sContentType.empty()) return; - } - size_t nTagEnd = sFileContent.find_first_of(";\n\r", nTag); - nTag += 14; - if(nTagEnd == std::string::npos || nTagEnd > nContentTag) + + if (NSStringFinder::Equals(sContentType, "multipart/alternative")) { - nFound = nNextFound; + oRes.WriteString(mhtTohtml(sMhtContent.substr(oData.m_unEndPosition, sMhtContent.length() - oData.m_unEndPosition))); return; } - std::string sContentType = sFileContent.substr(nTag, nTagEnd - nTag); - if(sContentType == "multipart/alternative") - nContentTag = nFound; - // name - std::string sName; - nTag = sFileContent.find(" name=", nFound); - if(nTag != std::string::npos && nTag < nContentTag) - { - nTagEnd = sFileContent.find_first_of(";\n\r", nTag); - nTag += 6; - if(nTagEnd != std::string::npos && nTagEnd < nContentTag) - sName = sFileContent.substr(nTag, nTagEnd - nTag); - } + unContentPosition = std::max(unContentPosition, oData.m_unEndPosition); + unCharsetBegin = oData.m_unEndPosition; - // charset - std::string sCharset; - nTag = sFileContent.find("charset=", nFound); - if(nTag != std::string::npos && nTag < nContentTag) - { - nTagEnd = sFileContent.find_first_of(";\n\r", nTag); - nTag += 8; - if(nTagEnd != std::string::npos && nTagEnd < nContentTag) - { - if(sFileContent[nTag] == '\"') - { - nTag++; - nTagEnd--; - } - sCharset = sFileContent.substr(nTag, nTagEnd - nTag); - } - } + // name +// std::string sName = NSStringFinder::FindPropety(sMhtContent, "name", {"="}, {";", "\\n", "\\r"}, 0, unLastPosition); +// unContentPosition = std::max(unContentPosition, unLastPosition); // Content-Location - std::string sContentLocation; - nTag = sFileContent.find("Content-Location: ", nFound); - if(nTag != std::string::npos && nTag < nContentTag) - { - nTagEnd = sFileContent.find_first_of(";\n\r", nTag); - nTag += 18; - if(nTagEnd != std::string::npos && nTagEnd < nContentTag) - sContentLocation = sFileContent.substr(nTag, nTagEnd - nTag); - } + oData = NSStringFinder::FindPropety(sMhtContent, "content-location", {":"}, {";", "\\n", "\\r"}); + std::string sContentLocation{oData.m_sValue}; - if (sContentLocation.empty()) - { - // Content-ID - std::string sContentID; - nTag = sFileContent.find("Content-ID: <", nFound); - if(nTag != std::string::npos && nTag < nContentTag) - { - nTagEnd = sFileContent.find_first_of(">", nTag); - nTag += 13; - if(nTagEnd != std::string::npos && nTagEnd < nContentTag) - sContentID = sFileContent.substr(nTag, nTagEnd - nTag); - } + if (!oData.Empty()) + unContentPosition = std::max(unContentPosition, oData.m_unEndPosition); + + // Content-ID + oData = NSStringFinder::FindPropety(sMhtContent, "content-id", {":"}, {";", "\\n", "\\r"}); + std::string sContentID{oData.m_sValue}; - if (!sContentID.empty()) - sContentLocation = "cid:" + sContentID; + if (!oData.Empty()) + { + unContentPosition = std::max(unContentPosition, oData.m_unEndPosition); + unCharsetEnd = std::min(unCharsetEnd, oData.m_unBeginPosition); + NSStringFinder::CutInside<std::string>(sContentID, "<", ">"); } + if (sContentLocation.empty() && !sContentID.empty()) + sContentLocation = "cid:" + sContentID; + // Content-Transfer-Encoding - std::string sContentEncoding; - nTag = sFileContent.find("Content-Transfer-Encoding: ", nFound); - if(nTag != std::string::npos && nTag < nContentTag) + oData = NSStringFinder::FindPropety(sMhtContent, "content-transfer-encoding", {":"}, {";", "\\n", "\\r"}); + const std::string sContentEncoding{oData.m_sValue}; + + if (!oData.Empty()) { - nTagEnd = sFileContent.find_first_of(";\n\r", nTag); - nTag += 27; - if(nTagEnd != std::string::npos && nTagEnd < nContentTag) - sContentEncoding = sFileContent.substr(nTag, nTagEnd - nTag); + unContentPosition = std::max(unContentPosition, oData.m_unEndPosition); + unCharsetEnd = std::min(unCharsetEnd, oData.m_unBeginPosition); } - // Content - nTagEnd = nNextFound - 2; - if(nTagEnd == std::string::npos || nTagEnd < nContentTag) + // charset + std::string sCharset = "utf-8"; + + if (std::string::npos != unCharsetEnd && unCharsetBegin < unCharsetEnd) { - nFound = nNextFound; - return; + sCharset = NSStringFinder::FindPropety(sMhtContent.substr(unCharsetBegin, unCharsetEnd - unCharsetBegin), "charset", {"="}, {";", "\\n", "\\r"}).m_sValue; + NSStringFinder::CutInside<std::string>(sCharset, "\""); } - std::string sContent = sFileContent.substr(nContentTag, nTagEnd - nContentTag); - // Удаляем лишнее - sFileContent.erase(0, nNextFound); - nFound = sFileContent.find(sBoundary); + // Content + std::string sContent = sMhtContent.substr(unContentPosition, sMhtContent.length() - unContentPosition); - std::wstring sExtention = NSFile::GetFileExtention(UTF8_TO_U(sName)); - std::transform(sExtention.begin(), sExtention.end(), sExtention.begin(), tolower); +// std::wstring sExtention = NSFile::GetFileExtention(UTF8_TO_U(sName)); +// std::transform(sExtention.begin(), sExtention.end(), sExtention.begin(), tolower); // Основной документ - if(sContentType == "multipart/alternative") + if (NSStringFinder::Equals(sContentType, "multipart/alternative")) oRes.WriteString(mhtTohtml(sContent)); - else if((sContentType.find("text") != std::string::npos && (sExtention.empty() || sExtention == L"htm" || sExtention == L"html" || sExtention - == L"xhtml" || sExtention == L"css")) || (sContentType == "application/octet-stream" && (sContentLocation.find("css") != - std::string::npos))) + else if ((NSStringFinder::Find(sContentType, "text") /*&& (sExtention.empty() || NSStringFinder::EqualOf(sExtention, {L"htm", L"html", L"xhtml", L"css"}))*/) + || (NSStringFinder::Equals(sContentType, "application/octet-stream") && NSStringFinder::Find(sContentLocation, "css"))) { // Стили заключаются в тэг <style> - if(sContentType == "text/css" || sExtention == L"css" || sContentLocation.find("css") != std::string::npos) + const bool bAddTagStyle = NSStringFinder::Equals(sContentType, "text/css") /*|| NSStringFinder::Equals(sExtention, L"css")*/ || NSStringFinder::Find(sContentLocation, "css"); + + if (bAddTagStyle) oRes.WriteString("<style>"); - if(sContentEncoding == "Base64" || sContentEncoding == "base64") - oRes.WriteString(Base64ToString(sContent, sCharset)); - else if(sContentEncoding == "8bit" || sContentEncoding == "7bit" || sContentEncoding.empty()) + + if (NSStringFinder::Equals(sContentEncoding, "base64")) + sContent = Base64ToString(sContent, sCharset); + else if (NSStringFinder::EqualOf(sContentEncoding, {"8bit", "7bit"}) || sContentEncoding.empty()) { - if (sCharset != "utf-8" && sCharset != "UTF-8" && !sCharset.empty()) + if (!NSStringFinder::Equals(sCharset, "utf-8") && !sCharset.empty()) { NSUnicodeConverter::CUnicodeConverter oConverter; sContent = U_TO_UTF8(oConverter.toUnicode(sContent, sCharset.data())); } - oRes.WriteString(sContent); } - else if(sContentEncoding == "quoted-printable" || sContentEncoding == "Quoted-Printable") + else if (NSStringFinder::Equals(sContentEncoding, "quoted-printable")) { sContent = QuotedPrintableDecode(sContent, sCharset); - if (sCharset != "utf-8" && sCharset != "UTF-8" && !sCharset.empty()) + if (!NSStringFinder::Equals(sCharset, "utf-8") && !sCharset.empty()) { NSUnicodeConverter::CUnicodeConverter oConverter; sContent = U_TO_UTF8(oConverter.toUnicode(sContent, sCharset.data())); } - oRes.WriteString(sContent); } - if(sContentType == "text/css" || sExtention == L"css" || sContentLocation.find("css") != std::string::npos) + + if (NSStringFinder::Equals(sContentType, "text/html")) + sContent = U_TO_UTF8(htmlToXhtml(sContent, false)); + + oRes.WriteString(sContent); + + if(bAddTagStyle) oRes.WriteString("</style>"); } // Картинки - else if((sContentType.find("image") != std::string::npos || sExtention == L"gif" || sContentType == "application/octet-stream") && - (sContentEncoding == "Base64" || sContentEncoding == "base64")) + else if ((NSStringFinder::Find(sContentType, "image") /*|| NSStringFinder::Equals(sExtention, L"gif")*/ || NSStringFinder::Equals(sContentType, "application/octet-stream")) && + NSStringFinder::Equals(sContentEncoding, "base64")) { - if(sExtention == L"ico" || sContentType.find("ico") != std::string::npos) - sContentType = "image/jpg"; - else if(sExtention == L"gif") - sContentType = "image/gif"; +// if (NSStringFinder::Equals(sExtention, L"ico") || NSStringFinder::Find(sContentType, "ico")) +// sContentType = "image/jpg"; +// else if(NSStringFinder::Equals(sExtention, L"gif")) +// sContentType = "image/gif"; int nSrcLen = (int)sContent.length(); int nDecodeLen = NSBase64::Base64DecodeGetRequiredLength(nSrcLen); BYTE* pData = new BYTE[nDecodeLen]; @@ -385,50 +332,46 @@ static void ReadMht(std::string& sFileContent, size_t& nFound, size_t& nNextFoun } } -static std::string mhtTohtml(std::string& sFileContent) +static std::string mhtTohtml(const std::string& sFileContent) { std::map<std::string, std::string> sRes; NSStringUtils::CStringBuilderA oRes; // Поиск boundary - size_t nFound = sFileContent.find("boundary="); - if(nFound == std::string::npos) + NSStringFinder::TFoundedData<char> oData{NSStringFinder::FindPropety(sFileContent, "boundary", {"="}, {"\\r", "\\n", "\""})}; + + size_t nFound{oData.m_unEndPosition}; + std::string sBoundary{oData.m_sValue}; + + if (sBoundary.empty()) { size_t nFoundEnd = sFileContent.length(); nFound = 0; - ReadMht(sFileContent, nFound, nFoundEnd, "no", sRes, oRes); + ReadMht(sFileContent.substr(nFound, nFoundEnd), sRes, oRes); return oRes.GetData(); } - size_t nFoundEnd = sFileContent.find_first_of(";\n\r", nFound); - if(nFoundEnd == std::string::npos) - return ""; - nFound += 9; - if(sFileContent[nFound] == '\"') - { - nFound++; - nFoundEnd--; - } - if(nFound > nFoundEnd) - return ""; - std::string sBoundary = sFileContent.substr(nFound, nFoundEnd - nFound); + + NSStringFinder::CutInside<std::string>(sBoundary, "\""); + + size_t nFoundEnd{nFound}; + + sBoundary = "--" + sBoundary; size_t nBoundaryLength = sBoundary.length(); - // Удаляем лишнее - nFound = sFileContent.find(sBoundary, nFoundEnd); - sFileContent.erase(0, nFound); + nFound = sFileContent.find(sBoundary, nFound) + nBoundaryLength; // Цикл по boundary - nFound = 0; while(nFound != std::string::npos) { - // Выход по --boundary-- - if(sFileContent[nFound + nBoundaryLength + 1] == '-') - break; nFoundEnd = sFileContent.find(sBoundary, nFound + nBoundaryLength); if(nFoundEnd == std::string::npos) break; - ReadMht(sFileContent, nFound, nFoundEnd, sBoundary, sRes, oRes); + + ReadMht(sFileContent.substr(nFound, nFoundEnd - nFound), sRes, oRes); + + nFound = sFileContent.find(sBoundary, nFoundEnd); } + std::string sFile = oRes.GetData(); for(const std::pair<std::string, std::string>& item : sRes) { @@ -440,10 +383,18 @@ static std::string mhtTohtml(std::string& sFileContent) while(found != std::string::npos) { size_t fq = sFile.find_last_of("\"\'>=", found); + + if (std::string::npos == fq) + break; + char ch = sFile[fq]; if(ch != '\"' && ch != '\'') fq++; size_t tq = sFile.find_first_of("\"\'<> ", found) + 1; + + if (std::string::npos == tq) + break; + if(sFile[tq] != '\"' && sFile[tq] != '\'') tq--; if(ch != '>') @@ -456,6 +407,7 @@ static std::string mhtTohtml(std::string& sFileContent) found = sFile.find(sName, tq); } } + return sFile; } @@ -587,7 +539,7 @@ static void build_attributes(const GumboVector* attribs, bool no_entities, NSStr } } -static void prettyprint_contents(GumboNode* node, NSStringUtils::CStringBuilderA& contents) +static void prettyprint_contents(GumboNode* node, NSStringUtils::CStringBuilderA& contents, bool bCheckValidNode) { std::string key = "|" + get_tag_name(node) + "|"; bool no_entity_substitution = no_entity_sub.find(key) != std::string::npos; @@ -618,7 +570,7 @@ static void prettyprint_contents(GumboNode* node, NSStringUtils::CStringBuilderA contents.WriteString(val); } else if ((child->type == GUMBO_NODE_ELEMENT) || (child->type == GUMBO_NODE_TEMPLATE)) - prettyprint(child, contents); + prettyprint(child, contents, bCheckValidNode); else if (child->type == GUMBO_NODE_WHITESPACE) { if (keep_whitespace || is_inline || is_like_inline) @@ -633,23 +585,36 @@ static void prettyprint_contents(GumboNode* node, NSStringUtils::CStringBuilderA } } -static void prettyprint(GumboNode* node, NSStringUtils::CStringBuilderA& oBuilder) +static void prettyprint(GumboNode* node, NSStringUtils::CStringBuilderA& oBuilder, bool bCheckValidNode) { // special case the document node if (node->type == GUMBO_NODE_DOCUMENT) { build_doctype(node, oBuilder); - prettyprint_contents(node, oBuilder); + prettyprint_contents(node, oBuilder, bCheckValidNode); + return; + } + + std::string tagname = get_tag_name(node); + + if (NodeIsUnprocessed(tagname)) + return; + + if (bCheckValidNode) + bCheckValidNode = !IsUnckeckedNodes(tagname); + + if (bCheckValidNode && html_tags.end() == std::find(html_tags.begin(), html_tags.end(), tagname)) + { + prettyprint_contents(node, oBuilder, bCheckValidNode); return; } std::string close = ""; std::string closeTag = ""; - std::string tagname = get_tag_name(node); std::string key = "|" + tagname + "|"; bool is_empty_tag = empty_tags.find(key) != std::string::npos; bool no_entity_substitution = no_entity_sub.find(key) != std::string::npos; - + // determine closing tag type if (is_empty_tag) close = "/"; @@ -665,7 +630,7 @@ static void prettyprint(GumboNode* node, NSStringUtils::CStringBuilderA& oBuilde oBuilder.WriteString(close + ">"); // prettyprint your contents - prettyprint_contents(node, oBuilder); + prettyprint_contents(node, oBuilder, bCheckValidNode); oBuilder.WriteString(closeTag); } diff --git a/Common/3dParty/hunspell/.gitignore b/Common/3dParty/hunspell/.gitignore index 26759af2b14..e08b85ec575 100644 --- a/Common/3dParty/hunspell/.gitignore +++ b/Common/3dParty/hunspell/.gitignore @@ -2,3 +2,4 @@ emsdk/ hunspell/ deploy/ o +hunspell.data diff --git a/Common/3dParty/hunspell/before.py b/Common/3dParty/hunspell/before.py index 453db870c11..40bcb2b3154 100644 --- a/Common/3dParty/hunspell/before.py +++ b/Common/3dParty/hunspell/before.py @@ -14,6 +14,12 @@ def get_hunspell(stable_commit): base.replaceInFile("./src/hunspell/csutil.cxx", "void free_utf_tbl() {", "void free_utf_tbl() { \n return;\n") # bug fix, we need to keep this utf table # free_utf_tbl doesnt delete anything so we can destroy hunspell object + + # replace & add defines to easy control of time limits (CUSTOM_LIMIT) + default_tl_defines = "#define TIMELIMIT_GLOBAL (CLOCKS_PER_SEC / 4)\n#define TIMELIMIT_SUGGESTION (CLOCKS_PER_SEC / 10)\n#define TIMELIMIT (CLOCKS_PER_SEC / 20)\n" + custom_tl_defines_tl = "#define TIMELIMIT_GLOBAL CUSTOM_TIMELIMIT_GLOBAL\n#define TIMELIMIT_SUGGESTION CUSTOM_TIMELIMIT_SUGGESTION\n#define TIMELIMIT CUSTOM_TIMELIMIT\n" + tl_defines = "#ifndef CUSTOM_TIMELIMITS\n" + default_tl_defines + "#else\n" + custom_tl_defines_tl + "#endif\n" + base.replaceInFile("./src/hunspell/atypes.hxx", default_tl_defines, tl_defines) os.chdir("../") diff --git a/Common/3dParty/hunspell/test/main.cpp b/Common/3dParty/hunspell/test/main.cpp new file mode 100644 index 00000000000..34b91a28747 --- /dev/null +++ b/Common/3dParty/hunspell/test/main.cpp @@ -0,0 +1,163 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ + +#include "../../../../Common/3dParty/hunspell/hunspell/src/hunspell/hunspell.h" +#include "../../../../DesktopEditor/common/StringExt.h" +#include "../../../../DesktopEditor/common/Directory.h" +#include <iostream> + +bool CheckCaret(std::vector<std::wstring>& words) +{ + bool bIsCaret = false; + for (int i = 0, len = (int)words.size(); i < len; ++i) + { + if (words[i].find('\r') == (words[i].length() - 1)) + { + words[i] = words[i].substr(0, words[i].length() - 1); + bIsCaret = true; + } + } + return bIsCaret; +} + +std::wstring CheckWord(Hunhandle* pDic, const std::wstring& sWord, const bool& bIsCaret) +{ + std::wstring sResult = sWord; + + std::string sWordA = U_TO_UTF8(sWord); + int nSpellResult = Hunspell_spell(pDic, sWordA.c_str()); + + if (0 == nSpellResult) + { + char** pSuggest; + int nSuggestCount = Hunspell_suggest(pDic, &pSuggest, sWordA.c_str()); + + sResult += L" ["; + + for (int i = 0; i < nSuggestCount; ++i) + { + std::string sSuggestA(pSuggest[i], strlen(pSuggest[i])); + std::wstring sSuggest = UTF8_TO_U(sSuggestA); + + sResult += sSuggest; + if (i != (nSuggestCount - 1)) + sResult += (L", "); + } + + if (0 < nSuggestCount) + Hunspell_free_list(pDic, &pSuggest, nSuggestCount); + + sResult += L"]"; + } + + if (bIsCaret) + sResult += L"\r"; + sResult += L"\n"; + + return sResult; +} + +#if defined(_WIN32) || defined(_WIN64) +#define USE_WCHAR_ARGC +#endif + +#ifdef USE_WCHAR_ARGC +std::wstring GetParam(wchar_t* arg) +{ + return std::wstring(arg); +} +#else +std::wstring GetParam(char* arg) +{ + return NSFile::CUtf8Converter::GetUnicodeStringFromUTF8((BYTE *)arg, (LONG)strlen(arg)); +} +#endif + +#ifdef USE_WCHAR_ARGC +int wmain(int argc, wchar_t *argv[]) +#else +int main(int argc, char *argv[]) +#endif +{ + std::wstring sSrcDir = NSFile::GetProcessDirectory() + L"/../src"; + std::wstring sDstDir = NSFile::GetProcessDirectory() + L"/../dst"; + std::wstring sDictionariesDir = NSFile::GetProcessDirectory() + L"/../../../../../../dictionaries"; + + if (argc > 1) sSrcDir = GetParam(argv[1]); + if (argc > 2) sDstDir = GetParam(argv[2]); + if (argc > 3) sDictionariesDir = GetParam(argv[3]); + + std::vector<std::wstring> arSrcFiles = NSDirectory::GetFiles(sSrcDir); + + for (int i = 0, len = (int)arSrcFiles.size(); i < len; ++i) + { + std::wstring sFileWords = arSrcFiles[i]; + std::wstring sName = NSFile::GetFileName(sFileWords); + std::wstring::size_type sNamePos = sName.find(L"."); + if (std::wstring::npos != sNamePos) + sName = sName.substr(0, sNamePos); + + std::wstring sFileWordsContent = L""; + NSFile::CFileBinary::ReadAllTextUtf8(sFileWords, sFileWordsContent); + + std::vector<std::wstring> arWords = NSStringExt::Split(sFileWordsContent, '\n'); + bool bIsCaret = CheckCaret(arWords); + + std::wstring sAff = sDictionariesDir + L"/" + sName + L"/" + sName + L".aff"; + std::wstring sDic = sDictionariesDir + L"/" + sName + L"/" + sName + L".dic"; + + // skip check diffs if dictionary is not exists + if (!NSFile::CFileBinary::Exists(sAff) || !NSFile::CFileBinary::Exists(sDic)) + continue; + + std::string sAffA = U_TO_UTF8(sAff); + std::string sDicA = U_TO_UTF8(sDic); + + Hunhandle* pDictionary = Hunspell_create(sAffA.c_str(), sDicA.c_str()); + + std::wstring sFileDst = sDstDir + L"/" + sName + L".txt"; + + std::wstring sResult = L""; + for (const std::wstring& word : arWords) + { + sResult += CheckWord(pDictionary, word, bIsCaret); + } + + Hunspell_destroy(pDictionary); + + NSFile::CFileBinary::SaveToFile(sFileDst, sResult, true); + + std::cout << "[" << (i + 1) << " of " << (int)arSrcFiles.size() << "] " << U_TO_UTF8(sName) << std::endl; + } + + return 0; +} diff --git a/Common/3dParty/hunspell/test/test.pro b/Common/3dParty/hunspell/test/test.pro new file mode 100644 index 00000000000..28b36d0dece --- /dev/null +++ b/Common/3dParty/hunspell/test/test.pro @@ -0,0 +1,48 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2015-07-21T18:28:42 +# +#------------------------------------------------- + +QT -= core gui + +TARGET = dictionariestester +CONFIG += console +CONFIG -= app_bundle + +DEFINES += KERNEL_USE_DYNAMIC_LIBRARY + +TEMPLATE = app + +CONFIG += hunspell_build_static + +CORE_ROOT_DIR = $$PWD/../../../.. +PWD_ROOT_DIR = $$PWD +include($$CORE_ROOT_DIR/Common/base.pri) +include($$CORE_ROOT_DIR/Common/3dParty/icu/icu.pri) +include($$CORE_ROOT_DIR/Common/3dParty/hunspell/qt/hunspell.pri) + +# custom time limits of hunspell in clocks (if before.py was executed) +# when increasing the limit for each case, it is important to consider that the total time will +# also increase, so it is good to increase the global limit. this works the same for the candidate limit with suggest limit +DEFINES += CUSTOM_TIMELIMITS + +escape_bracket= +!core_windows:escape_bracket=\\ + +# total time limit per word for all cases. (default is CLOCKS_PER_SEC/4) +DEFINES += "CUSTOM_TIMELIMIT_GLOBAL=$${escape_bracket}(20*CLOCKS_PER_SEC$${escape_bracket})" + +# total time limit per "1 case" - forgotten char, double char, moved char and so on for all candidates. (default is CLOCKS_PER_SEC/10) +DEFINES += "CUSTOM_TIMELIMIT_SUGGESTION=$${escape_bracket}(5*CLOCKS_PER_SEC$${escape_bracket})" + +# time limit per candidate (default is CLOCKS_PER_SEC/20) +DEFINES += "CUSTOM_TIMELIMIT=$${escape_bracket}(CLOCKS_PER_SEC$${escape_bracket}\)" + +ADD_DEPENDENCY(UnicodeConverter kernel) + +core_windows:LIBS += -lgdi32 -ladvapi32 -luser32 -lshell32 + +SOURCES += main.cpp + +DESTDIR = $$CORE_BUILDS_BINARY_PATH diff --git a/Common/3dParty/icu/icu.pri b/Common/3dParty/icu/icu.pri index d63020fa5c3..c5ae929f8ac 100644 --- a/Common/3dParty/icu/icu.pri +++ b/Common/3dParty/icu/icu.pri @@ -43,8 +43,7 @@ core_ios { core_android { INCLUDEPATH += $$PWD/android/build/include - ICU_LIBS_PATH = $$replace(CORE_BUILDS_PLATFORM_PREFIX, "android_", "") - LIBS += $$PWD/android/build/$$ICU_LIBS_PATH/libicuuc.a - LIBS += $$PWD/android/build/$$ICU_LIBS_PATH/libicudata.a + LIBS += $$PWD/android/build/$$CORE_BUILDS_PLATFORM_PREFIX_DST/libicuuc.a + LIBS += $$PWD/android/build/$$CORE_BUILDS_PLATFORM_PREFIX_DST/libicudata.a } diff --git a/Common/3dParty/icu/icu_ios.sh b/Common/3dParty/icu/icu_ios.sh index 7de74b8e1ae..7b6bbba71b2 100755 --- a/Common/3dParty/icu/icu_ios.sh +++ b/Common/3dParty/icu/icu_ios.sh @@ -20,9 +20,9 @@ CONFIG_PREFIX=" --enable-extras=yes \ --enable-dyload=no \ --with-data-packaging=static" -CFLAGS="-O3 -D__STDC_INT64__ -fno-exceptions -fno-short-wchar -fno-short-enums -fembed-bitcode" +CFLAGS="-O3 -D__STDC_INT64__ -fno-exceptions -fno-short-wchar -fno-short-enums" -CXXFLAGS="${CFLAGS} -std=c++11 -fembed-bitcode" +CXXFLAGS="${CFLAGS} -std=c++11" #will set value to 1 defines_config_set_1=( @@ -215,9 +215,9 @@ function build() { export CXX="$(xcrun -find clang++)" export CC="$(xcrun -find clang)" - export CFLAGS="-fembed-bitcode -isysroot $SDKROOT -I$SDKROOT/usr/include/ -I./include/ -arch $ARCH $IOS_MIN_VER $ICU_FLAGS $CFLAGS ${ADDITION_FLAG}" - export CXXFLAGS="${CXXFLAGS} -fembed-bitcode -stdlib=libc++ -isysroot $SDKROOT -I$SDKROOT/usr/include/ -I./include/ -arch $ARCH $IOS_MIN_VER $ICU_FLAGS ${ADDITION_FLAG}" - export LDFLAGS="-fembed-bitcode -stdlib=libc++ -L$SDKROOT/usr/lib/ -isysroot $SDKROOT -Wl,-dead_strip $IOS_MIN_VER -lstdc++ ${ADDITION_FLAG}" + export CFLAGS="-isysroot $SDKROOT -I$SDKROOT/usr/include/ -I./include/ -arch $ARCH $IOS_MIN_VER $ICU_FLAGS $CFLAGS ${ADDITION_FLAG}" + export CXXFLAGS="${CXXFLAGS} -stdlib=libc++ -isysroot $SDKROOT -I$SDKROOT/usr/include/ -I./include/ -arch $ARCH $IOS_MIN_VER $ICU_FLAGS ${ADDITION_FLAG}" + export LDFLAGS="-stdlib=libc++ -L$SDKROOT/usr/lib/ -isysroot $SDKROOT -Wl,-dead_strip $IOS_MIN_VER -lstdc++ ${ADDITION_FLAG}" mkdir -p ${BUILD_DIR} cd ${BUILD_DIR} diff --git a/Common/3dParty/libvlc/build/linux_64/lib/libva-drm.so b/Common/3dParty/libvlc/build/linux_64/lib/libva-drm.so new file mode 100644 index 00000000000..f9e2ea76c07 Binary files /dev/null and b/Common/3dParty/libvlc/build/linux_64/lib/libva-drm.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/libva-drm.so.2 b/Common/3dParty/libvlc/build/linux_64/lib/libva-drm.so.2 new file mode 100644 index 00000000000..f9e2ea76c07 Binary files /dev/null and b/Common/3dParty/libvlc/build/linux_64/lib/libva-drm.so.2 differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/libva-drm.so.2.2100.0 b/Common/3dParty/libvlc/build/linux_64/lib/libva-drm.so.2.2100.0 new file mode 100644 index 00000000000..f9e2ea76c07 Binary files /dev/null and b/Common/3dParty/libvlc/build/linux_64/lib/libva-drm.so.2.2100.0 differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/libva-glx.so b/Common/3dParty/libvlc/build/linux_64/lib/libva-glx.so new file mode 100644 index 00000000000..4a96abbbf43 Binary files /dev/null and b/Common/3dParty/libvlc/build/linux_64/lib/libva-glx.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/libva-glx.so.2 b/Common/3dParty/libvlc/build/linux_64/lib/libva-glx.so.2 new file mode 100644 index 00000000000..4a96abbbf43 Binary files /dev/null and b/Common/3dParty/libvlc/build/linux_64/lib/libva-glx.so.2 differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/libva-glx.so.2.2100.0 b/Common/3dParty/libvlc/build/linux_64/lib/libva-glx.so.2.2100.0 new file mode 100644 index 00000000000..4a96abbbf43 Binary files /dev/null and b/Common/3dParty/libvlc/build/linux_64/lib/libva-glx.so.2.2100.0 differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/libva-wayland.so b/Common/3dParty/libvlc/build/linux_64/lib/libva-wayland.so new file mode 100644 index 00000000000..ed33e0d66b3 Binary files /dev/null and b/Common/3dParty/libvlc/build/linux_64/lib/libva-wayland.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/libva-wayland.so.2 b/Common/3dParty/libvlc/build/linux_64/lib/libva-wayland.so.2 new file mode 100644 index 00000000000..ed33e0d66b3 Binary files /dev/null and b/Common/3dParty/libvlc/build/linux_64/lib/libva-wayland.so.2 differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/libva-wayland.so.2.2100.0 b/Common/3dParty/libvlc/build/linux_64/lib/libva-wayland.so.2.2100.0 new file mode 100644 index 00000000000..ed33e0d66b3 Binary files /dev/null and b/Common/3dParty/libvlc/build/linux_64/lib/libva-wayland.so.2.2100.0 differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/libva-x11.so b/Common/3dParty/libvlc/build/linux_64/lib/libva-x11.so new file mode 100644 index 00000000000..232b1fbc32c Binary files /dev/null and b/Common/3dParty/libvlc/build/linux_64/lib/libva-x11.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/libva-x11.so.2 b/Common/3dParty/libvlc/build/linux_64/lib/libva-x11.so.2 new file mode 100644 index 00000000000..232b1fbc32c Binary files /dev/null and b/Common/3dParty/libvlc/build/linux_64/lib/libva-x11.so.2 differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/libva-x11.so.2.2100.0 b/Common/3dParty/libvlc/build/linux_64/lib/libva-x11.so.2.2100.0 new file mode 100644 index 00000000000..232b1fbc32c Binary files /dev/null and b/Common/3dParty/libvlc/build/linux_64/lib/libva-x11.so.2.2100.0 differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/libva.so b/Common/3dParty/libvlc/build/linux_64/lib/libva.so new file mode 100644 index 00000000000..874b158442c Binary files /dev/null and b/Common/3dParty/libvlc/build/linux_64/lib/libva.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/libva.so.2 b/Common/3dParty/libvlc/build/linux_64/lib/libva.so.2 new file mode 100644 index 00000000000..874b158442c Binary files /dev/null and b/Common/3dParty/libvlc/build/linux_64/lib/libva.so.2 differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/libva.so.2.2100.0 b/Common/3dParty/libvlc/build/linux_64/lib/libva.so.2.2100.0 new file mode 100644 index 00000000000..874b158442c Binary files /dev/null and b/Common/3dParty/libvlc/build/linux_64/lib/libva.so.2.2100.0 differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/libvlc.so b/Common/3dParty/libvlc/build/linux_64/lib/libvlc.so index d643c7ab0da..98e14e20786 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/libvlc.so and b/Common/3dParty/libvlc/build/linux_64/lib/libvlc.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/libvlc.so.5 b/Common/3dParty/libvlc/build/linux_64/lib/libvlc.so.5 index d643c7ab0da..98e14e20786 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/libvlc.so.5 and b/Common/3dParty/libvlc/build/linux_64/lib/libvlc.so.5 differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/libvlc.so.5.6.1 b/Common/3dParty/libvlc/build/linux_64/lib/libvlc.so.5.6.1 index d643c7ab0da..98e14e20786 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/libvlc.so.5.6.1 and b/Common/3dParty/libvlc/build/linux_64/lib/libvlc.so.5.6.1 differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/libvlccore.so b/Common/3dParty/libvlc/build/linux_64/lib/libvlccore.so index ddf83683dbc..221d39244bd 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/libvlccore.so and b/Common/3dParty/libvlc/build/linux_64/lib/libvlccore.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/libvlccore.so.9 b/Common/3dParty/libvlc/build/linux_64/lib/libvlccore.so.9 index ddf83683dbc..221d39244bd 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/libvlccore.so.9 and b/Common/3dParty/libvlc/build/linux_64/lib/libvlccore.so.9 differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/libvlccore.so.9.0.1 b/Common/3dParty/libvlc/build/linux_64/lib/libvlccore.so.9.0.1 index ddf83683dbc..221d39244bd 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/libvlccore.so.9.0.1 and b/Common/3dParty/libvlc/build/linux_64/lib/libvlccore.so.9.0.1 differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/libvlc_pulse.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/libvlc_pulse.so index 53a59fb7fa7..2d6b4743dfd 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/libvlc_pulse.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/libvlc_pulse.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/libvlc_pulse.so.0 b/Common/3dParty/libvlc/build/linux_64/lib/vlc/libvlc_pulse.so.0 index 53a59fb7fa7..2d6b4743dfd 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/libvlc_pulse.so.0 and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/libvlc_pulse.so.0 differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/libvlc_pulse.so.0.0.0 b/Common/3dParty/libvlc/build/linux_64/lib/vlc/libvlc_pulse.so.0.0.0 index 53a59fb7fa7..2d6b4743dfd 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/libvlc_pulse.so.0.0.0 and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/libvlc_pulse.so.0.0.0 differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/libvlc_xcb_events.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/libvlc_xcb_events.so index f5639fd8f87..f40bcd12254 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/libvlc_xcb_events.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/libvlc_xcb_events.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/libvlc_xcb_events.so.0 b/Common/3dParty/libvlc/build/linux_64/lib/vlc/libvlc_xcb_events.so.0 index f5639fd8f87..f40bcd12254 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/libvlc_xcb_events.so.0 and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/libvlc_xcb_events.so.0 differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/libvlc_xcb_events.so.0.0.0 b/Common/3dParty/libvlc/build/linux_64/lib/vlc/libvlc_xcb_events.so.0.0.0 index f5639fd8f87..f40bcd12254 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/libvlc_xcb_events.so.0.0.0 and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/libvlc_xcb_events.so.0.0.0 differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libaccess_alsa_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libaccess_alsa_plugin.so index dbef13d64ac..094af07fc15 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libaccess_alsa_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libaccess_alsa_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libaccess_concat_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libaccess_concat_plugin.so index 6107aff8568..6e8e08da817 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libaccess_concat_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libaccess_concat_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libaccess_imem_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libaccess_imem_plugin.so index 3f00e1efe08..9a4378f7506 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libaccess_imem_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libaccess_imem_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libaccess_jack_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libaccess_jack_plugin.so index 0eb81b2ad3f..77175309dc9 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libaccess_jack_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libaccess_jack_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libaccess_mms_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libaccess_mms_plugin.so index 2d840975932..d1ede0bcbeb 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libaccess_mms_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libaccess_mms_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libattachment_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libattachment_plugin.so index a66ebe24a81..c2ef1735619 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libattachment_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libattachment_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libavio_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libavio_plugin.so index 57180b1cc61..bdaa0f24323 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libavio_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libavio_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libdtv_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libdtv_plugin.so index 2ad2bc3119d..3fb16c4efd5 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libdtv_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libdtv_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libfilesystem_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libfilesystem_plugin.so index 52b3e75e721..e180b2fa57c 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libfilesystem_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libfilesystem_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libftp_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libftp_plugin.so index 064a5b3e31b..f657ae43ef0 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libftp_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libftp_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libhttp_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libhttp_plugin.so index 9972dac3f95..c3ca28b0fd7 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libhttp_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libhttp_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libhttps_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libhttps_plugin.so index e22ad25a90c..838b7c256aa 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libhttps_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libhttps_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libidummy_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libidummy_plugin.so index 2317d3fea71..d62e8671e13 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libidummy_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libidummy_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libimem_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libimem_plugin.so index 1b35e161951..ab4b1945e47 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libimem_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libimem_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libpulsesrc_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libpulsesrc_plugin.so index e34205a7630..a062cde28e8 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libpulsesrc_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libpulsesrc_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/librist_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/librist_plugin.so index d9a20d74760..5b89af5eaa4 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/librist_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/librist_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/librtp_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/librtp_plugin.so index 4a12b0ae425..a8367e2d6ff 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/librtp_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/librtp_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libsatip_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libsatip_plugin.so index c5832724ab7..7dc21b427dd 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libsatip_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libsatip_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libsdp_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libsdp_plugin.so index bbc519de88e..f777efeda50 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libsdp_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libsdp_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libshm_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libshm_plugin.so index c058a165d64..8fbfc3a3111 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libshm_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libshm_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libtcp_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libtcp_plugin.so index 09dd1a3b4a0..9960b73e481 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libtcp_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libtcp_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libtimecode_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libtimecode_plugin.so index 8292d424902..b9b8d8294bd 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libtimecode_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libtimecode_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libudp_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libudp_plugin.so index b58e7b88c73..d091bb102ba 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libudp_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libudp_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libvdr_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libvdr_plugin.so index 6c3865256dc..abc26f134a6 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libvdr_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libvdr_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libxcb_screen_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libxcb_screen_plugin.so index e9470dc5a43..91225d59fd0 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libxcb_screen_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/access/libxcb_screen_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libaudio_format_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libaudio_format_plugin.so index 17c39f45a19..09d3b8c7147 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libaudio_format_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libaudio_format_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libaudiobargraph_a_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libaudiobargraph_a_plugin.so index 0cca4951644..0cb42d60dfb 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libaudiobargraph_a_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libaudiobargraph_a_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libchorus_flanger_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libchorus_flanger_plugin.so index 90a267e126a..3a56ac1187e 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libchorus_flanger_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libchorus_flanger_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libcompressor_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libcompressor_plugin.so index 58a4a1feb56..2a21104285b 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libcompressor_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libcompressor_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libdolby_surround_decoder_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libdolby_surround_decoder_plugin.so index aa3b8a93a14..5bf9b14bee7 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libdolby_surround_decoder_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libdolby_surround_decoder_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libequalizer_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libequalizer_plugin.so index f4bca3b65f0..70b7c324d5a 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libequalizer_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libequalizer_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libgain_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libgain_plugin.so index 53ada09b580..2b60f265d6d 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libgain_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libgain_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libheadphone_channel_mixer_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libheadphone_channel_mixer_plugin.so index 0afc28d34c7..2ff4dba56bc 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libheadphone_channel_mixer_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libheadphone_channel_mixer_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libkaraoke_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libkaraoke_plugin.so index 827c07d72a1..164db683cbe 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libkaraoke_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libkaraoke_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libmad_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libmad_plugin.so index 8178e2aba24..1b2d08446d8 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libmad_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libmad_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libmono_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libmono_plugin.so index 933599f5976..d1c9c84fa8a 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libmono_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libmono_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libnormvol_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libnormvol_plugin.so index 832e656b330..b12b8f87294 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libnormvol_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libnormvol_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libparam_eq_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libparam_eq_plugin.so index d23118486bb..290e2d0b5fb 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libparam_eq_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libparam_eq_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libremap_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libremap_plugin.so index 67a19beb8b0..ca494228226 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libremap_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libremap_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libsamplerate_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libsamplerate_plugin.so index 342b5dc6120..914008d9229 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libsamplerate_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libsamplerate_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libscaletempo_pitch_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libscaletempo_pitch_plugin.so index 653d94d480b..5a84d0efa62 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libscaletempo_pitch_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libscaletempo_pitch_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libscaletempo_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libscaletempo_plugin.so index fdcbc982ab9..22f15ab14fc 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libscaletempo_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libscaletempo_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libsimple_channel_mixer_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libsimple_channel_mixer_plugin.so index 10b5d7a583d..ccb654ecfbf 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libsimple_channel_mixer_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libsimple_channel_mixer_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libspatialaudio_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libspatialaudio_plugin.so index 497123603b9..f664ff5768e 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libspatialaudio_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libspatialaudio_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libspatializer_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libspatializer_plugin.so index a561a3699b2..f030095f55a 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libspatializer_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libspatializer_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libspeex_resampler_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libspeex_resampler_plugin.so index 58c312a204d..bff098ff4b7 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libspeex_resampler_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libspeex_resampler_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libstereo_widen_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libstereo_widen_plugin.so index ac87b9290a7..93c306e7102 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libstereo_widen_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libstereo_widen_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libtospdif_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libtospdif_plugin.so index da7b19ee64a..6610747a82f 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libtospdif_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libtospdif_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libtrivial_channel_mixer_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libtrivial_channel_mixer_plugin.so index beb3a957d8c..45ae8483f91 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libtrivial_channel_mixer_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libtrivial_channel_mixer_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libugly_resampler_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libugly_resampler_plugin.so index 4447a7c1ba6..9d6dad9969a 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libugly_resampler_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_filter/libugly_resampler_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_mixer/libfloat_mixer_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_mixer/libfloat_mixer_plugin.so index 64388bb6216..222658c6254 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_mixer/libfloat_mixer_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_mixer/libfloat_mixer_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_mixer/libinteger_mixer_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_mixer/libinteger_mixer_plugin.so index dd852dcfd05..b82c7bc62c5 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_mixer/libinteger_mixer_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_mixer/libinteger_mixer_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_output/libadummy_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_output/libadummy_plugin.so index 32f22003a20..89f955e311f 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_output/libadummy_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_output/libadummy_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_output/libafile_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_output/libafile_plugin.so index 8d97d59b19a..5bf49a51dc6 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_output/libafile_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_output/libafile_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_output/libalsa_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_output/libalsa_plugin.so index ab7aa1f6a3b..63e9a011660 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_output/libalsa_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_output/libalsa_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_output/libamem_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_output/libamem_plugin.so index fb644532a06..da7cb1dabd9 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_output/libamem_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_output/libamem_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_output/libjack_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_output/libjack_plugin.so index 3e0d3189a8f..2744a8d2b7f 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_output/libjack_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_output/libjack_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_output/libpulse_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_output/libpulse_plugin.so index 3e7a283c867..015ad57d2b5 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_output/libpulse_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/audio_output/libpulse_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libadpcm_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libadpcm_plugin.so index 1992a834ba8..f6b17eecc6d 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libadpcm_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libadpcm_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libaes3_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libaes3_plugin.so index f92451443cc..3b7c48ddb70 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libaes3_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libaes3_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libaom_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libaom_plugin.so index ac50f0506f0..8007312d8b8 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libaom_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libaom_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libaraw_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libaraw_plugin.so index 8944f8009d7..cb90f679805 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libaraw_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libaraw_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libaribsub_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libaribsub_plugin.so index 2ce6e923832..9c32a07734a 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libaribsub_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libaribsub_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libavcodec_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libavcodec_plugin.so index 0d88db22da7..1aa87be6cc4 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libavcodec_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libavcodec_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libcc_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libcc_plugin.so index ab32568784e..75af8d622cb 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libcc_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libcc_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libcdg_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libcdg_plugin.so index e5efb12add1..b4dbd1bc5ee 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libcdg_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libcdg_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libcvdsub_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libcvdsub_plugin.so index 9fd84ef5924..735e8bbece5 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libcvdsub_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libcvdsub_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libdav1d_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libdav1d_plugin.so index e59986949e7..53885671c1b 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libdav1d_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libdav1d_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libdca_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libdca_plugin.so index 8b40edc436a..4942e4117cf 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libdca_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libdca_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libddummy_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libddummy_plugin.so index 0f43f857bd6..7b35d1efacd 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libddummy_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libddummy_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libdvbsub_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libdvbsub_plugin.so index 1f379f02638..aa3b4d5666e 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libdvbsub_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libdvbsub_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libfaad_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libfaad_plugin.so index 9e1e20bc051..3d9628b41bd 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libfaad_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libfaad_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libflac_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libflac_plugin.so index 0c9d70c1dea..abfe1d6b335 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libflac_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libflac_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libg711_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libg711_plugin.so index fe96cdbdf50..d076c8c54a2 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libg711_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libg711_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libkate_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libkate_plugin.so index c7b1eb2bcf0..2d79dc96eae 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libkate_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libkate_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/liblibass_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/liblibass_plugin.so index f6b56f08b76..4311f0a170b 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/liblibass_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/liblibass_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/liblibmpeg2_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/liblibmpeg2_plugin.so index c65e629623a..bd1343318bd 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/liblibmpeg2_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/liblibmpeg2_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/liblpcm_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/liblpcm_plugin.so index 7abb57dc14a..de488683d67 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/liblpcm_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/liblpcm_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libmpg123_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libmpg123_plugin.so index ea071705566..dd3f8653a5a 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libmpg123_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libmpg123_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/liboggspots_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/liboggspots_plugin.so index bdb882d32b9..9deac4061a3 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/liboggspots_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/liboggspots_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libopus_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libopus_plugin.so index e100185fdf4..0f6faa4484d 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libopus_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libopus_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/librawvideo_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/librawvideo_plugin.so index d7370294431..d590f959777 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/librawvideo_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/librawvideo_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libschroedinger_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libschroedinger_plugin.so index 4bae8461e74..20326c0f331 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libschroedinger_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libschroedinger_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libscte18_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libscte18_plugin.so index adee52e8ea6..02a2dbea471 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libscte18_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libscte18_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libscte27_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libscte27_plugin.so index 4657cc22cee..4f890817a41 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libscte27_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libscte27_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libspdif_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libspdif_plugin.so index ca681616242..b80777af913 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libspdif_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libspdif_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libspeex_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libspeex_plugin.so index b686f5d2c60..3bf2b7e3aed 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libspeex_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libspeex_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libspudec_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libspudec_plugin.so index e6dbca7434a..45291718b2d 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libspudec_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libspudec_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libstl_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libstl_plugin.so index fbf3912f38c..9a3d6d573fa 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libstl_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libstl_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libsubsdec_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libsubsdec_plugin.so index 5e6fe544e02..d0f6b8ce716 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libsubsdec_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libsubsdec_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libsubstx3g_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libsubstx3g_plugin.so index 3121b3cb8f7..ceba4324ed9 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libsubstx3g_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libsubstx3g_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libsubsusf_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libsubsusf_plugin.so index 9b4d5b2a258..4bea48e705f 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libsubsusf_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libsubsusf_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libsvcdsub_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libsvcdsub_plugin.so index c7499ff0709..48b4954fdb6 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libsvcdsub_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libsvcdsub_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libtextst_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libtextst_plugin.so index 2eaae76874b..a90d466f97c 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libtextst_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libtextst_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libtheora_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libtheora_plugin.so index 0e2c7b2a4f0..d5c894b9cdb 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libtheora_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libtheora_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libttml_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libttml_plugin.so index d89f61676b0..9a26fea35c6 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libttml_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libttml_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libuleaddvaudio_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libuleaddvaudio_plugin.so index cc582133d6e..bc50c001e9b 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libuleaddvaudio_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libuleaddvaudio_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libvaapi_drm_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libvaapi_drm_plugin.so index 39b5640a129..504d90a0b35 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libvaapi_drm_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libvaapi_drm_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libvaapi_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libvaapi_plugin.so index cc0339b22f9..5ddfdfa2f6d 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libvaapi_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libvaapi_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libvorbis_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libvorbis_plugin.so index d516d7365fe..8a3eb6d1bf2 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libvorbis_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libvorbis_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libvpx_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libvpx_plugin.so index 4e2399850e8..2f451dcfa96 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libvpx_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libvpx_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libwebvtt_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libwebvtt_plugin.so index e290dd8d7e6..f76eb07e045 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libwebvtt_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libwebvtt_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libxwd_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libxwd_plugin.so index 8d89366c68a..1475dd87d5c 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libxwd_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/codec/libxwd_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/control/libdummy_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/control/libdummy_plugin.so index 37dbfe39c09..3ee46413a55 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/control/libdummy_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/control/libdummy_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/control/libgestures_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/control/libgestures_plugin.so index ad755818af8..7744d804cef 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/control/libgestures_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/control/libgestures_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/control/libhotkeys_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/control/libhotkeys_plugin.so index 002c4c14d46..e529900ea22 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/control/libhotkeys_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/control/libhotkeys_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/control/libmotion_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/control/libmotion_plugin.so index cb6b1a5d6de..46943f1d06a 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/control/libmotion_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/control/libmotion_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/control/libnetsync_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/control/libnetsync_plugin.so index 5e7c45776d3..ab544e72611 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/control/libnetsync_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/control/libnetsync_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/control/liboldrc_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/control/liboldrc_plugin.so index 47a9dc05ca2..eeced52b37e 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/control/liboldrc_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/control/liboldrc_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/control/libxcb_hotkeys_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/control/libxcb_hotkeys_plugin.so index b6bc5e9c4c8..4c8849ae7f2 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/control/libxcb_hotkeys_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/control/libxcb_hotkeys_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libadaptive_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libadaptive_plugin.so index a0a905b1225..b86c305a59f 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libadaptive_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libadaptive_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libaiff_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libaiff_plugin.so index 9ce2ee86343..7f70e59cdf1 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libaiff_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libaiff_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libasf_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libasf_plugin.so index 333d4f447af..aeb5cb591fe 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libasf_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libasf_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libau_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libau_plugin.so index 315e8b11664..3abffaa4e2f 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libau_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libau_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libavformat_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libavformat_plugin.so index 864ab6b3006..436af877ac7 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libavformat_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libavformat_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libavi_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libavi_plugin.so index 38886c2dd93..a66d88e410a 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libavi_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libavi_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libcaf_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libcaf_plugin.so index 34ddc433d75..eb964987798 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libcaf_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libcaf_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libdemux_cdg_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libdemux_cdg_plugin.so index 83ae6f72e63..94022b1c712 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libdemux_cdg_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libdemux_cdg_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libdemux_stl_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libdemux_stl_plugin.so index e6dbfd6d8d7..9e82043f46e 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libdemux_stl_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libdemux_stl_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libdemuxdump_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libdemuxdump_plugin.so index 5c687beae68..81d7af9c69b 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libdemuxdump_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libdemuxdump_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libdiracsys_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libdiracsys_plugin.so index 88e00e2fdd7..57313885693 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libdiracsys_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libdiracsys_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libdirectory_demux_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libdirectory_demux_plugin.so index 812a1d8b500..1139403d7f5 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libdirectory_demux_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libdirectory_demux_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libes_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libes_plugin.so index 037cbdbb368..85e27a3a9b7 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libes_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libes_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libflacsys_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libflacsys_plugin.so index e1fe308c2b5..f2743eba398 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libflacsys_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libflacsys_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libh26x_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libh26x_plugin.so index 33ea8dc2e9e..57264e281ea 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libh26x_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libh26x_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libimage_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libimage_plugin.so index 1df3944a3f3..d71926adf9e 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libimage_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libimage_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libmjpeg_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libmjpeg_plugin.so index 6e19f64bf23..a772ee57f1f 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libmjpeg_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libmjpeg_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libmkv_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libmkv_plugin.so index 9dd69d8bb88..043866eebde 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libmkv_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libmkv_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libmp4_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libmp4_plugin.so index 892c27fb8a9..3336992f16e 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libmp4_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libmp4_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libmpgv_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libmpgv_plugin.so index 6c33308c147..62c20105b9f 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libmpgv_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libmpgv_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libnoseek_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libnoseek_plugin.so index d6169305d9e..775a86b6ba8 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libnoseek_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libnoseek_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libnsc_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libnsc_plugin.so index a477ef237b0..7d5e4e88f0c 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libnsc_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libnsc_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libnsv_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libnsv_plugin.so index 0fab342549e..997b550e353 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libnsv_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libnsv_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libnuv_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libnuv_plugin.so index df56955e6e7..8b038c8eb72 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libnuv_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libnuv_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libogg_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libogg_plugin.so index 29b63d8549f..e3d96f8b7b0 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libogg_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libogg_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libplaylist_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libplaylist_plugin.so index 5d01f0aed81..05ef325968b 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libplaylist_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libplaylist_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libps_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libps_plugin.so index c0f01f540e2..6be65c36fdd 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libps_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libps_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libpva_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libpva_plugin.so index 8673db2062e..af76393dcb3 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libpva_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libpva_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/librawaud_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/librawaud_plugin.so index 23aa7b54139..ba66595ff8c 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/librawaud_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/librawaud_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/librawdv_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/librawdv_plugin.so index 0ec60499af4..878059b6d03 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/librawdv_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/librawdv_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/librawvid_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/librawvid_plugin.so index 9c809776151..367c84497f6 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/librawvid_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/librawvid_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libreal_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libreal_plugin.so index 887882a8592..09afee0d14a 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libreal_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libreal_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libsmf_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libsmf_plugin.so index d8ee4cae428..caa4b6dd40c 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libsmf_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libsmf_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libsubtitle_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libsubtitle_plugin.so index bea9cb0aca4..e526b093a94 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libsubtitle_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libsubtitle_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libtta_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libtta_plugin.so index 3db350d458a..6e50d0bb64a 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libtta_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libtta_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libty_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libty_plugin.so index 2b481f71720..58fb62b37af 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libty_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libty_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libvc1_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libvc1_plugin.so index 7b4d6f44d8d..87d9a7ed63f 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libvc1_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libvc1_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libvobsub_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libvobsub_plugin.so index a987d89658f..f3fc6b25137 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libvobsub_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libvobsub_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libvoc_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libvoc_plugin.so index 5cf4e3ef2b0..eba8cdf312f 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libvoc_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libvoc_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libwav_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libwav_plugin.so index 5c6e1126edb..725014cb8a8 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libwav_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libwav_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libxa_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libxa_plugin.so index 8b9dea43fc7..67b500116d4 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libxa_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/demux/libxa_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/keystore/libfile_keystore_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/keystore/libfile_keystore_plugin.so index eb1d321305f..9663aa3fe95 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/keystore/libfile_keystore_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/keystore/libfile_keystore_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/keystore/libmemory_keystore_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/keystore/libmemory_keystore_plugin.so index 8078493ab81..edf6ddafd72 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/keystore/libmemory_keystore_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/keystore/libmemory_keystore_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/logger/libconsole_logger_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/logger/libconsole_logger_plugin.so index 968e3dcd4b6..7b781719141 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/logger/libconsole_logger_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/logger/libconsole_logger_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/logger/libfile_logger_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/logger/libfile_logger_plugin.so index 3eb4332e058..8ac120bfd9f 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/logger/libfile_logger_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/logger/libfile_logger_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/logger/libsyslog_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/logger/libsyslog_plugin.so index 37d99cdd453..7686dfff99b 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/logger/libsyslog_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/logger/libsyslog_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/meta_engine/libfolder_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/meta_engine/libfolder_plugin.so index a6ab03436e3..13aee4013e4 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/meta_engine/libfolder_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/meta_engine/libfolder_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/meta_engine/libtaglib_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/meta_engine/libtaglib_plugin.so index c3ea045ce65..193a4d17ab7 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/meta_engine/libtaglib_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/meta_engine/libtaglib_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/misc/libaudioscrobbler_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/misc/libaudioscrobbler_plugin.so index 46e4f6d188b..8d973bb431b 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/misc/libaudioscrobbler_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/misc/libaudioscrobbler_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/misc/libexport_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/misc/libexport_plugin.so index 8b510a6472b..d508263586d 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/misc/libexport_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/misc/libexport_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/misc/libfingerprinter_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/misc/libfingerprinter_plugin.so index 53775f09b80..e392a5b14f5 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/misc/libfingerprinter_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/misc/libfingerprinter_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/misc/liblogger_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/misc/liblogger_plugin.so index 64a0cc63ed0..961f223d108 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/misc/liblogger_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/misc/liblogger_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/misc/libstats_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/misc/libstats_plugin.so index efed68495ce..774be6a15b3 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/misc/libstats_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/misc/libstats_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/misc/libxdg_screensaver_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/misc/libxdg_screensaver_plugin.so index af2a63fd9db..f5f7afbce7a 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/misc/libxdg_screensaver_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/misc/libxdg_screensaver_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/packetizer/libpacketizer_a52_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/packetizer/libpacketizer_a52_plugin.so index 89c6b3f3615..3705a58df26 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/packetizer/libpacketizer_a52_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/packetizer/libpacketizer_a52_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/packetizer/libpacketizer_av1_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/packetizer/libpacketizer_av1_plugin.so index 99c77c8789e..dad237e2f22 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/packetizer/libpacketizer_av1_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/packetizer/libpacketizer_av1_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/packetizer/libpacketizer_avparser_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/packetizer/libpacketizer_avparser_plugin.so index af5f02e3849..41d922bff91 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/packetizer/libpacketizer_avparser_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/packetizer/libpacketizer_avparser_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/packetizer/libpacketizer_copy_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/packetizer/libpacketizer_copy_plugin.so index 5af34b2c883..e2c32bdb972 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/packetizer/libpacketizer_copy_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/packetizer/libpacketizer_copy_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/packetizer/libpacketizer_dirac_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/packetizer/libpacketizer_dirac_plugin.so index dbc7cfff373..32a6b61182c 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/packetizer/libpacketizer_dirac_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/packetizer/libpacketizer_dirac_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/packetizer/libpacketizer_dts_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/packetizer/libpacketizer_dts_plugin.so index 6e136fa31e1..99432d41aa7 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/packetizer/libpacketizer_dts_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/packetizer/libpacketizer_dts_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/packetizer/libpacketizer_flac_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/packetizer/libpacketizer_flac_plugin.so index 6eb67fe1d83..8d7a51098e9 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/packetizer/libpacketizer_flac_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/packetizer/libpacketizer_flac_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/packetizer/libpacketizer_h264_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/packetizer/libpacketizer_h264_plugin.so index a7929731253..d34cc8cc7ea 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/packetizer/libpacketizer_h264_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/packetizer/libpacketizer_h264_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/packetizer/libpacketizer_hevc_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/packetizer/libpacketizer_hevc_plugin.so index 69a738f776b..23d09c5d356 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/packetizer/libpacketizer_hevc_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/packetizer/libpacketizer_hevc_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/packetizer/libpacketizer_mlp_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/packetizer/libpacketizer_mlp_plugin.so index 33bc1a7fd92..ab08dca3688 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/packetizer/libpacketizer_mlp_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/packetizer/libpacketizer_mlp_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/packetizer/libpacketizer_mpeg4audio_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/packetizer/libpacketizer_mpeg4audio_plugin.so index c40fa1f0e60..5a5e9577086 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/packetizer/libpacketizer_mpeg4audio_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/packetizer/libpacketizer_mpeg4audio_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/packetizer/libpacketizer_mpeg4video_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/packetizer/libpacketizer_mpeg4video_plugin.so index d226b99be2e..45811ef006e 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/packetizer/libpacketizer_mpeg4video_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/packetizer/libpacketizer_mpeg4video_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/packetizer/libpacketizer_mpegaudio_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/packetizer/libpacketizer_mpegaudio_plugin.so index 13f5402d032..047d7c22736 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/packetizer/libpacketizer_mpegaudio_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/packetizer/libpacketizer_mpegaudio_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/packetizer/libpacketizer_mpegvideo_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/packetizer/libpacketizer_mpegvideo_plugin.so index b679eaab4de..7f59c21e284 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/packetizer/libpacketizer_mpegvideo_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/packetizer/libpacketizer_mpegvideo_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/packetizer/libpacketizer_vc1_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/packetizer/libpacketizer_vc1_plugin.so index 08f5d7fbbf4..3d56854752e 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/packetizer/libpacketizer_vc1_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/packetizer/libpacketizer_vc1_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/plugins.dat b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/plugins.dat index d2dcd41a031..d236cbd1f1b 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/plugins.dat and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/plugins.dat differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/services_discovery/libmediadirs_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/services_discovery/libmediadirs_plugin.so index c1becc5463b..ef544efd995 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/services_discovery/libmediadirs_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/services_discovery/libmediadirs_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/services_discovery/libpodcast_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/services_discovery/libpodcast_plugin.so index 109299b4c72..ea3b59cff63 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/services_discovery/libpodcast_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/services_discovery/libpodcast_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/services_discovery/libpulselist_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/services_discovery/libpulselist_plugin.so index c2c0a16be00..8ab10457be0 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/services_discovery/libpulselist_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/services_discovery/libpulselist_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/services_discovery/libsap_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/services_discovery/libsap_plugin.so index 721816b0096..45155e79414 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/services_discovery/libsap_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/services_discovery/libsap_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/services_discovery/libxcb_apps_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/services_discovery/libxcb_apps_plugin.so index dcc44025e05..704e7835f82 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/services_discovery/libxcb_apps_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/services_discovery/libxcb_apps_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/spu/libaudiobargraph_v_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/spu/libaudiobargraph_v_plugin.so index 1fa476df2ef..9e83bb11f30 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/spu/libaudiobargraph_v_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/spu/libaudiobargraph_v_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/spu/libdynamicoverlay_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/spu/libdynamicoverlay_plugin.so index dced46aad76..838bbf4cec4 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/spu/libdynamicoverlay_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/spu/libdynamicoverlay_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/spu/liblogo_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/spu/liblogo_plugin.so index 1ad8bb2c8a2..52e20a3c6ca 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/spu/liblogo_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/spu/liblogo_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/spu/libmarq_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/spu/libmarq_plugin.so index 42d07d03109..f2c0ba977d5 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/spu/libmarq_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/spu/libmarq_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/spu/libmosaic_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/spu/libmosaic_plugin.so index 9e10497c0c4..9b2e0452b35 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/spu/libmosaic_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/spu/libmosaic_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/spu/librss_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/spu/librss_plugin.so index 1fef50a3f06..f209469433b 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/spu/librss_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/spu/librss_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/spu/libsubsdelay_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/spu/libsubsdelay_plugin.so index 38ec8dd9330..21f4b2c435d 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/spu/libsubsdelay_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/spu/libsubsdelay_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/stream_filter/libadf_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/stream_filter/libadf_plugin.so index 40b8011b7cd..2e2afc73afa 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/stream_filter/libadf_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/stream_filter/libadf_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/stream_filter/libcache_block_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/stream_filter/libcache_block_plugin.so index 0504f445232..6ce216f9460 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/stream_filter/libcache_block_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/stream_filter/libcache_block_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/stream_filter/libcache_read_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/stream_filter/libcache_read_plugin.so index 9e97b1f5ca8..ced9bcd7a31 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/stream_filter/libcache_read_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/stream_filter/libcache_read_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/stream_filter/libdecomp_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/stream_filter/libdecomp_plugin.so index 0964e6f3095..dc61161392e 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/stream_filter/libdecomp_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/stream_filter/libdecomp_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/stream_filter/libhds_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/stream_filter/libhds_plugin.so index 0310730a0a4..f2d0d0038e8 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/stream_filter/libhds_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/stream_filter/libhds_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/stream_filter/libinflate_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/stream_filter/libinflate_plugin.so index 72ae3d4aad0..3f178f2daf5 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/stream_filter/libinflate_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/stream_filter/libinflate_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/stream_filter/libprefetch_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/stream_filter/libprefetch_plugin.so index 0556af6067e..4771510fb16 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/stream_filter/libprefetch_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/stream_filter/libprefetch_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/stream_filter/librecord_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/stream_filter/librecord_plugin.so index 3360fcf1a90..ca799b82b1e 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/stream_filter/librecord_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/stream_filter/librecord_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/stream_filter/libskiptags_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/stream_filter/libskiptags_plugin.so index d3f968c1d47..de0f38de9db 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/stream_filter/libskiptags_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/stream_filter/libskiptags_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/text_renderer/libfreetype_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/text_renderer/libfreetype_plugin.so index d55e02e724f..393711cb7ff 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/text_renderer/libfreetype_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/text_renderer/libfreetype_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/text_renderer/libtdummy_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/text_renderer/libtdummy_plugin.so index 3538698a6a5..f13e1a64f15 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/text_renderer/libtdummy_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/text_renderer/libtdummy_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/vaapi/libvaapi_filters_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/vaapi/libvaapi_filters_plugin.so index d006b2bd30c..0402b4bdd07 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/vaapi/libvaapi_filters_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/vaapi/libvaapi_filters_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/vdpau/libvdpau_adjust_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/vdpau/libvdpau_adjust_plugin.so index 07fb8483e0e..ed8a828da04 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/vdpau/libvdpau_adjust_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/vdpau/libvdpau_adjust_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/vdpau/libvdpau_avcodec_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/vdpau/libvdpau_avcodec_plugin.so index 26cd9edf0bc..e10cf75e5e8 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/vdpau/libvdpau_avcodec_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/vdpau/libvdpau_avcodec_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/vdpau/libvdpau_chroma_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/vdpau/libvdpau_chroma_plugin.so index d2f8bad168b..fe93f080a08 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/vdpau/libvdpau_chroma_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/vdpau/libvdpau_chroma_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/vdpau/libvdpau_deinterlace_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/vdpau/libvdpau_deinterlace_plugin.so index 7d6b2a5ca4a..baf2bba877a 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/vdpau/libvdpau_deinterlace_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/vdpau/libvdpau_deinterlace_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/vdpau/libvdpau_display_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/vdpau/libvdpau_display_plugin.so index e4107b831e5..d987300a064 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/vdpau/libvdpau_display_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/vdpau/libvdpau_display_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/vdpau/libvdpau_sharpen_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/vdpau/libvdpau_sharpen_plugin.so index 930ea366a2f..788a0f42c71 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/vdpau/libvdpau_sharpen_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/vdpau/libvdpau_sharpen_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_chroma/libchain_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_chroma/libchain_plugin.so index fed641833af..5a5a919b3ef 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_chroma/libchain_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_chroma/libchain_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_chroma/libgrey_yuv_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_chroma/libgrey_yuv_plugin.so index d9af1c324d4..f545ff8ba04 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_chroma/libgrey_yuv_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_chroma/libgrey_yuv_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_chroma/libi420_10_p010_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_chroma/libi420_10_p010_plugin.so index e6a334e0e4a..89041cfcd79 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_chroma/libi420_10_p010_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_chroma/libi420_10_p010_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_chroma/libi420_nv12_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_chroma/libi420_nv12_plugin.so index eb031047a78..d8cc29b723d 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_chroma/libi420_nv12_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_chroma/libi420_nv12_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_chroma/libi420_rgb_mmx_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_chroma/libi420_rgb_mmx_plugin.so index e4a8f05670e..f625c12b056 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_chroma/libi420_rgb_mmx_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_chroma/libi420_rgb_mmx_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_chroma/libi420_rgb_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_chroma/libi420_rgb_plugin.so index 4535367b6f8..ffd2ee67418 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_chroma/libi420_rgb_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_chroma/libi420_rgb_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_chroma/libi420_rgb_sse2_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_chroma/libi420_rgb_sse2_plugin.so index c590bf6299f..2742ef95a19 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_chroma/libi420_rgb_sse2_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_chroma/libi420_rgb_sse2_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_chroma/libi420_yuy2_mmx_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_chroma/libi420_yuy2_mmx_plugin.so index 6ce49971f16..e49553099b1 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_chroma/libi420_yuy2_mmx_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_chroma/libi420_yuy2_mmx_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_chroma/libi420_yuy2_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_chroma/libi420_yuy2_plugin.so index 84e0a429be9..4259b807377 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_chroma/libi420_yuy2_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_chroma/libi420_yuy2_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_chroma/libi420_yuy2_sse2_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_chroma/libi420_yuy2_sse2_plugin.so index 214be9214db..9d0d5f4ba1c 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_chroma/libi420_yuy2_sse2_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_chroma/libi420_yuy2_sse2_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_chroma/libi422_i420_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_chroma/libi422_i420_plugin.so index 63742ece15a..ca5dba71c0d 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_chroma/libi422_i420_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_chroma/libi422_i420_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_chroma/libi422_yuy2_mmx_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_chroma/libi422_yuy2_mmx_plugin.so index d2f4873f2ad..7a22c782b40 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_chroma/libi422_yuy2_mmx_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_chroma/libi422_yuy2_mmx_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_chroma/libi422_yuy2_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_chroma/libi422_yuy2_plugin.so index 272d98b41e1..2258de10a0d 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_chroma/libi422_yuy2_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_chroma/libi422_yuy2_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_chroma/libi422_yuy2_sse2_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_chroma/libi422_yuy2_sse2_plugin.so index 4895a8d0672..2c535562ddf 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_chroma/libi422_yuy2_sse2_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_chroma/libi422_yuy2_sse2_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_chroma/librv32_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_chroma/librv32_plugin.so index f7f01224daf..97740f7ba54 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_chroma/librv32_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_chroma/librv32_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_chroma/libyuvp_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_chroma/libyuvp_plugin.so index a1deb50da30..1bd065d8711 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_chroma/libyuvp_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_chroma/libyuvp_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_chroma/libyuy2_i420_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_chroma/libyuy2_i420_plugin.so index 57c10b7aa77..551b25af468 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_chroma/libyuy2_i420_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_chroma/libyuy2_i420_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_chroma/libyuy2_i422_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_chroma/libyuy2_i422_plugin.so index 2f8b04cabed..3c9270d3c64 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_chroma/libyuy2_i422_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_chroma/libyuy2_i422_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libadjust_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libadjust_plugin.so index d74ad417c0b..e02c6d28753 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libadjust_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libadjust_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libalphamask_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libalphamask_plugin.so index ddb51cd0cc5..a7409a418e8 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libalphamask_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libalphamask_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libanaglyph_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libanaglyph_plugin.so index a613d86a46c..970015a4b2a 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libanaglyph_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libanaglyph_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libantiflicker_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libantiflicker_plugin.so index d3e312eccd4..7689c8fec21 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libantiflicker_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libantiflicker_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libball_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libball_plugin.so index 97554a6517b..3f848a0da81 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libball_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libball_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libblend_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libblend_plugin.so index 6b9080a183f..2dac3aff571 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libblend_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libblend_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libblendbench_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libblendbench_plugin.so index 0288f90e44f..cdaff6ab2b0 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libblendbench_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libblendbench_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libbluescreen_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libbluescreen_plugin.so index 9e33d3f7193..8f42ad5e2fa 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libbluescreen_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libbluescreen_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libcanvas_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libcanvas_plugin.so index ee5e063e30a..99b33a1a91e 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libcanvas_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libcanvas_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libcolorthres_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libcolorthres_plugin.so index cb4fb802619..21fc3515b50 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libcolorthres_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libcolorthres_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libcroppadd_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libcroppadd_plugin.so index bd5f9828c68..bd0801dc57c 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libcroppadd_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libcroppadd_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libdeinterlace_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libdeinterlace_plugin.so index 023915e09f9..9d9d4d3d2b7 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libdeinterlace_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libdeinterlace_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libedgedetection_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libedgedetection_plugin.so index 5ca0ba8b718..18509ded368 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libedgedetection_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libedgedetection_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/liberase_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/liberase_plugin.so index c57d22a874c..699147ee9c9 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/liberase_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/liberase_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libextract_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libextract_plugin.so index 70f652f0e51..eec5cf0fabd 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libextract_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libextract_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libfps_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libfps_plugin.so index 82cd5a0c4e2..c6012fccc25 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libfps_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libfps_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libfreeze_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libfreeze_plugin.so index b0ab95f322c..77e5cc1ca91 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libfreeze_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libfreeze_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libgaussianblur_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libgaussianblur_plugin.so index eda3be109e8..41cd5e3dd62 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libgaussianblur_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libgaussianblur_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libgradfun_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libgradfun_plugin.so index b5cae65d078..3dfc66d2ed0 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libgradfun_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libgradfun_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libgradient_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libgradient_plugin.so index 75fe10565b5..59e9bf77523 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libgradient_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libgradient_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libgrain_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libgrain_plugin.so index 487595006d9..516c207a55f 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libgrain_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libgrain_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libhqdn3d_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libhqdn3d_plugin.so index 914fe0427f2..456cc87e215 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libhqdn3d_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libhqdn3d_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libinvert_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libinvert_plugin.so index 77bbb247d8c..125756ee851 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libinvert_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libinvert_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libmagnify_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libmagnify_plugin.so index fa63c8eb1e2..2feaf337d98 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libmagnify_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libmagnify_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libmirror_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libmirror_plugin.so index ea1b4163275..a0b0a3f37ec 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libmirror_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libmirror_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libmotionblur_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libmotionblur_plugin.so index 47d10b6407d..73ac85c7cca 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libmotionblur_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libmotionblur_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libmotiondetect_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libmotiondetect_plugin.so index eff79683ec3..8fad522a2aa 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libmotiondetect_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libmotiondetect_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/liboldmovie_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/liboldmovie_plugin.so index 4529609f202..627b0bc6db1 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/liboldmovie_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/liboldmovie_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libposterize_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libposterize_plugin.so index ac5b6cd077b..40f824a7d23 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libposterize_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libposterize_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libpsychedelic_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libpsychedelic_plugin.so index 80315a91e58..0d429bf6ec8 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libpsychedelic_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libpsychedelic_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libpuzzle_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libpuzzle_plugin.so index 3c64e87f566..4c366327c92 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libpuzzle_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libpuzzle_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libripple_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libripple_plugin.so index 443a80c0697..7e12d9e89bb 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libripple_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libripple_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/librotate_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/librotate_plugin.so index 4150c020444..a3a63138525 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/librotate_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/librotate_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libscale_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libscale_plugin.so index 164e3a44513..9eee41a5c58 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libscale_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libscale_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libscene_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libscene_plugin.so index 9307f297f9d..37d2097eb83 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libscene_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libscene_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libsepia_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libsepia_plugin.so index a538901cdae..5b8c4908412 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libsepia_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libsepia_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libsharpen_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libsharpen_plugin.so index d49361fa847..538c29af623 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libsharpen_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libsharpen_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libtransform_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libtransform_plugin.so index 6f77d601292..b16f054ec5d 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libtransform_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libtransform_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libvhs_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libvhs_plugin.so index 7fd00816000..3323443b3ef 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libvhs_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libvhs_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libwave_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libwave_plugin.so index 0a98bdf6caf..8dad4084608 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libwave_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_filter/libwave_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_output/libegl_x11_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_output/libegl_x11_plugin.so index 68cf8b93be6..4be2e1450a5 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_output/libegl_x11_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_output/libegl_x11_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_output/libfb_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_output/libfb_plugin.so index 5276bfcf45c..bfc400398a2 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_output/libfb_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_output/libfb_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_output/libflaschen_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_output/libflaschen_plugin.so index 30aec9fb484..f50432dc760 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_output/libflaschen_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_output/libflaschen_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_output/libgl_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_output/libgl_plugin.so index 481dae7b3dc..82c90907d8e 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_output/libgl_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_output/libgl_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_output/libglconv_vaapi_drm_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_output/libglconv_vaapi_drm_plugin.so index 4e8c03aeff8..51703f3b1a2 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_output/libglconv_vaapi_drm_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_output/libglconv_vaapi_drm_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_output/libglconv_vaapi_x11_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_output/libglconv_vaapi_x11_plugin.so index f75de62d030..4db743169e0 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_output/libglconv_vaapi_x11_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_output/libglconv_vaapi_x11_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_output/libglconv_vdpau_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_output/libglconv_vdpau_plugin.so index 4e4da15b6fc..c0bf057971a 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_output/libglconv_vdpau_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_output/libglconv_vdpau_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_output/libglx_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_output/libglx_plugin.so index 80beb69612b..65b02e013a9 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_output/libglx_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_output/libglx_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_output/libvdummy_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_output/libvdummy_plugin.so index d9129cd6e6f..6e80aaa9add 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_output/libvdummy_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_output/libvdummy_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_output/libvmem_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_output/libvmem_plugin.so index 6c74e90e886..1ec5e105d11 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_output/libvmem_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_output/libvmem_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_output/libxcb_window_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_output/libxcb_window_plugin.so index 94464a5a10b..13cdd4f8237 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_output/libxcb_window_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_output/libxcb_window_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_output/libxcb_x11_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_output/libxcb_x11_plugin.so index b85668e7107..43f55693a83 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_output/libxcb_x11_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_output/libxcb_x11_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_output/libxcb_xv_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_output/libxcb_xv_plugin.so index 08910405879..d982b183a94 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_output/libxcb_xv_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_output/libxcb_xv_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_output/libyuv_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_output/libyuv_plugin.so index a9a5f106742..0ea17d408da 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_output/libyuv_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_output/libyuv_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_splitter/libclone_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_splitter/libclone_plugin.so index 1a67fd93f7f..0d1e1ec7f4d 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_splitter/libclone_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_splitter/libclone_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_splitter/libpanoramix_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_splitter/libpanoramix_plugin.so index 50c45ed472b..117c2ee90e6 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_splitter/libpanoramix_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_splitter/libpanoramix_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_splitter/libwall_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_splitter/libwall_plugin.so index 9e1dadd8682..65bfac445d4 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_splitter/libwall_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/video_splitter/libwall_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/visualization/libglspectrum_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/visualization/libglspectrum_plugin.so index 9839ddcf06a..7f8fd72ce71 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/visualization/libglspectrum_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/visualization/libglspectrum_plugin.so differ diff --git a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/visualization/libvisual_plugin.so b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/visualization/libvisual_plugin.so index 860b3035071..8188eada62b 100644 Binary files a/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/visualization/libvisual_plugin.so and b/Common/3dParty/libvlc/build/linux_64/lib/vlc/plugins/visualization/libvisual_plugin.so differ diff --git a/Common/3dParty/libvlc/tools/linux_64/Dockerfile b/Common/3dParty/libvlc/tools/linux_64/Dockerfile index add16e4d229..8c2d033f2e8 100644 --- a/Common/3dParty/libvlc/tools/linux_64/Dockerfile +++ b/Common/3dParty/libvlc/tools/linux_64/Dockerfile @@ -45,6 +45,17 @@ RUN cd /build && \ sed -i.orig 's,#ifdef _MSC_VER,#if 1,' "src/google/protobuf/repeated_field.h" && \ cmake -S cmake -B build -DBUILD_SHARED_LIBS=OFF -Dprotobuf_BUILD_TESTS=OFF -Dprotobuf_BUILD_EXAMPLES=OFF && \ cmake --build build --parallel $CORES && cmake --install build --prefix /opt/protobuf +# LIBVA +RUN apt-get purge --autoremove -y libva-dev && \ + cd /build && \ + LIBVA_VERSION=2.21.0 && \ + wget -q https://github.com/intel/libva/archive/refs/tags/$LIBVA_VERSION.tar.gz && \ + tar -xzf $LIBVA_VERSION.tar.gz && \ + cd libva-$LIBVA_VERSION && \ +# change 'private-code' to 'code' for older versions of `wayland-scanner` + sed -i 's/$(AM_V_GEN)$(WAYLAND_SCANNER) private-code < $< > $@/$(AM_V_GEN)$(WAYLAND_SCANNER) code < $< > $@/' va/wayland/Makefile.am && \ + ./autogen.sh --prefix=/usr --libdir=/usr/lib/x86_64-linux-gnu && \ + make && make install ENV PATH=/opt/protobuf/bin:$PATH @@ -69,9 +80,16 @@ CMD cd /vlc && \ make -j$CORES install-strip && \ # correct build files cd build/linux_64 && \ +# change rpaths + echo "CHANGING RPATHS..." && \ + /vlc/change-rpaths.sh && \ +# copy libva libraries + (for f in $(find /usr/lib/x86_64-linux-gnu/ -name 'libva*.so*'); do cp $f lib; done;) && \ # convert all symlinks to files + echo "CONVERTING SYMLINKS..." && \ (for f in $(find . -type l); do cp --remove-destination $(readlink -f $f) $f; done;) && \ # delete all .la files find lib -name "*.la" -type f -delete && \ # generate plugins.dat + echo "GENERATING plugins.dat..." && \ lib/vlc/vlc-cache-gen lib/vlc/plugins diff --git a/Common/3dParty/libvlc/tools/linux_64/change-rpaths.sh b/Common/3dParty/libvlc/tools/linux_64/change-rpaths.sh new file mode 100644 index 00000000000..d1310902667 --- /dev/null +++ b/Common/3dParty/libvlc/tools/linux_64/change-rpaths.sh @@ -0,0 +1,53 @@ +#!/bin/bash + +# Root directory containing the libraries +root_dir="/vlc" +lib_dir="$root_dir/build/linux_64/lib" +patchelf="$root_dir/patchelf" + +# Function for concatenating paths +add_to_path() { + local path1="$1" + local path2="$2" + + if [[ -n "$path1" ]]; then + path1="$path1:$path2" + else + path1="$path2" + fi + + echo "$path1" +} + +# Function to convert an absolute path to a relative path with $ORIGIN +convert_to_origin() { + local lib_path="$1" + local rpath="$2" + local relative_rpath="" + + # Split rpath by ':' and process each path + local IFS=":" + for path in $rpath; do + # If path is already with '$ORIGIN', skip + if [[ $path == *"\$ORIGIN"* ]]; then + relative_rpath=$(add_to_path "$relative_rpath" "$path") + continue + fi + # Calculate the relative path + rel_path=$(realpath --relative-to="$(dirname "$lib_path")" "$path") + relative_rpath=$(add_to_path "$relative_rpath" "\$ORIGIN/$rel_path") + done + + echo "$relative_rpath" +} + +# Find all shared libraries and update their RPATH +libs=$(find "$lib_dir" -name '*.so*' -type f) +for lib in $libs; do + current_rpath=$($patchelf --print-rpath "$lib") + if [[ -n "$current_rpath" ]]; then + new_rpath=$(convert_to_origin "$lib" "$current_rpath") + echo "Updating RPATH of $lib to $new_rpath" + $patchelf --set-rpath "$new_rpath" "$lib" + fi +done diff --git a/Common/3dParty/libvlc/vlcmedia.cpp b/Common/3dParty/libvlc/vlcmedia.cpp index 1516189b75d..b7be6b3522b 100644 --- a/Common/3dParty/libvlc/vlcmedia.cpp +++ b/Common/3dParty/libvlc/vlcmedia.cpp @@ -1,6 +1,5 @@ #include "vlcmedia.h" -#include <iostream> #include <QUrl> CVlcMedia::CVlcMedia(libvlc_instance_t* pVlcInstance, const QString& sFile, bool bEventForwarding) diff --git a/Common/3dParty/libvlc/vlcplayer.cpp b/Common/3dParty/libvlc/vlcplayer.cpp index c46a3f2bb8f..3763504147c 100644 --- a/Common/3dParty/libvlc/vlcplayer.cpp +++ b/Common/3dParty/libvlc/vlcplayer.cpp @@ -1,7 +1,5 @@ #include "vlcplayer.h" -#include <iostream> - CVlcPlayer::CVlcPlayer(QWidget* parent) : QWidget(parent) { // initialize vlc media player @@ -19,6 +17,8 @@ CVlcPlayer::CVlcPlayer(QWidget* parent) : QWidget(parent) } libvlc_event_attach(m_pEventManager, libvlc_MediaPlayerTimeChanged , onTimeChanged, this); libvlc_event_attach(m_pEventManager, libvlc_MediaPlayerPositionChanged , onPositionChanged, this); + + libvlc_event_attach(m_pEventManager, libvlc_MediaPlayerVout , onVideoOutputChanged, this); } CVlcPlayer::~CVlcPlayer() @@ -45,6 +45,12 @@ void CVlcPlayer::onPositionChanged(const libvlc_event_t* pEvent, void* pData) emit pVlcPlayer->positionChanged(pEvent->u.media_player_position_changed.new_position); } +void CVlcPlayer::onVideoOutputChanged(const libvlc_event_t* pEvent, void* pData) +{ + CVlcPlayer* pVlcPlayer = reinterpret_cast<CVlcPlayer*>(pData); + emit pVlcPlayer->videoOutputChanged(pEvent->u.media_player_vout.new_count); +} + void CVlcPlayer::integrateIntoWidget(QWidget* pWidget) { #if defined(_MAC) @@ -97,9 +103,20 @@ void CVlcPlayer::setTime(qint64 nTime) libvlc_media_player_set_time(m_pVlcPlayer, nTime); } +qint64 CVlcPlayer::time() +{ + return libvlc_media_player_get_time(m_pVlcPlayer); +} + void CVlcPlayer::setPosition(float fPos) { libvlc_media_player_set_position(m_pVlcPlayer, fPos); + emit positionChanged(libvlc_media_player_get_position(m_pVlcPlayer)); +} + +float CVlcPlayer::position() +{ + return libvlc_media_player_get_position(m_pVlcPlayer); } bool CVlcPlayer::isAudio() diff --git a/Common/3dParty/libvlc/vlcplayer.h b/Common/3dParty/libvlc/vlcplayer.h index 1158d517876..b23cd5abb9a 100644 --- a/Common/3dParty/libvlc/vlcplayer.h +++ b/Common/3dParty/libvlc/vlcplayer.h @@ -20,16 +20,25 @@ class CVlcPlayer : public QWidget static void onStateChanged(const libvlc_event_t* pEvent, void *pData); static void onTimeChanged(const libvlc_event_t* pEvent, void *pData); static void onPositionChanged(const libvlc_event_t* pEvent, void *pData); + static void onVideoOutputChanged(const libvlc_event_t* pEvent, void *pData); public: void integrateIntoWidget(QWidget* pWidget); void open(CVlcMedia* pMedia); + // control playback void pause(); void play(); void stop(); + // volume void setVolume(int nVolume); + // time (in ms) void setTime(qint64 nTime); + qint64 time(); + // position (in range 0.0...1.0) void setPosition(float fPos); + float position(); + + // NOTE: isAudio() will always return true until event libvlc_MediaPlayerVout is occurred (see onVideoOutputChanged()) bool isAudio(); bool isPlaying(); libvlc_state_t getState(); @@ -38,6 +47,7 @@ class CVlcPlayer : public QWidget void stateChanged(int newState); void timeChanged(qint64 nNewTime); void positionChanged(float fNewPos); + void videoOutputChanged(int nVoutCount); public: libvlc_media_player_t* m_pVlcPlayer; diff --git a/Common/3dParty/openssl/build-android-common.sh b/Common/3dParty/openssl/build-android-common.sh deleted file mode 100755 index d1b069c0473..00000000000 --- a/Common/3dParty/openssl/build-android-common.sh +++ /dev/null @@ -1,220 +0,0 @@ -#!/bin/bash -# -# Copyright 2016 leenjewel -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -source ./build-common.sh - -export PLATFORM_TYPE="Android" -export ARCHS=("arm" "arm64" "x86" "x86_64") -export ABIS=("armeabi-v7a" "arm64-v8a" "x86" "x86_64") -export ABI_TRIPLES=("arm-linux-androideabi" "aarch64-linux-android" "i686-linux-android" "x86_64-linux-android") -export ANDROID_API=21 - -# for test -# export ARCHS=("x86_64") -# export ABIS=("x86_64") -# export ABI_TRIPLES=("x86_64-linux-android") - -if [[ -z ${ANDROID_NDK_ROOT} ]]; then - echo "ANDROID_NDK_ROOT not defined" - exit 1 -fi - -function get_toolchain() { - HOST_OS=$(uname -s) - case ${HOST_OS} in - Darwin) HOST_OS=darwin ;; - Linux) HOST_OS=linux ;; - FreeBsd) HOST_OS=freebsd ;; - CYGWIN* | *_NT-*) HOST_OS=cygwin ;; - esac - - HOST_ARCH=$(uname -m) - case ${HOST_ARCH} in - i?86) HOST_ARCH=x86 ;; - x86_64 | amd64) HOST_ARCH=x86_64 ;; - esac - - echo "${HOST_OS}-${HOST_ARCH}" -} - -function get_android_arch() { - local common_arch=$1 - case ${common_arch} in - arm) - echo "arm-v7a" - ;; - arm64) - echo "arm64-v8a" - ;; - x86) - echo "x86" - ;; - x86_64) - echo "x86-64" - ;; - esac -} - -function get_target_build() { - local arch=$1 - case ${arch} in - arm-v7a) - echo "arm" - ;; - arm64-v8a) - echo "arm64" - ;; - x86) - echo "x86" - ;; - x86-64) - echo "x86_64" - ;; - esac -} - -function get_build_host_internal() { - local arch=$1 - case ${arch} in - arm-v7a | arm-v7a-neon) - echo "arm-linux-androideabi" - ;; - arm64-v8a) - echo "aarch64-linux-android" - ;; - x86) - echo "i686-linux-android" - ;; - x86-64) - echo "x86_64-linux-android" - ;; - esac -} - -function android_get_build_host() { - local arch=$(get_android_arch $1) - get_build_host_internal $arch -} - -function get_clang_target_host() { - local arch=$1 - local api=$2 - case ${arch} in - arm-v7a | arm-v7a-neon) - echo "armv7a-linux-androideabi${api}" - ;; - arm64-v8a) - echo "aarch64-linux-android${api}" - ;; - x86) - echo "i686-linux-android${api}" - ;; - x86-64) - echo "x86_64-linux-android${api}" - ;; - esac -} - -function set_android_toolchain_bin() { - export PATH=${ANDROID_NDK_ROOT}/toolchains/llvm/prebuilt/$(get_toolchain)/bin:$PATH - echo PATH=$PATH -} - -function set_android_toolchain() { - local name=$1 - local arch=$(get_android_arch $2) - local api=$3 - local build_host=$(get_build_host_internal "$arch") - local clang_target_host=$(get_clang_target_host "$arch" "$api") - - export AR=${build_host}-ar - export CC=${clang_target_host}-clang - export CXX=${clang_target_host}-clang++ - export AS=${build_host}-as - export LD=${build_host}-ld - export RANLIB=${build_host}-ranlib - export STRIP=${build_host}-strip -} - -function get_common_includes() { - local toolchain=$(get_toolchain) - echo "-I${ANDROID_NDK_ROOT}/toolchains/llvm/prebuilt/${toolchain}/sysroot/usr/include -I${ANDROID_NDK_ROOT}/toolchains/llvm/prebuilt/${toolchain}/sysroot/usr/local/include" -} -function get_common_linked_libraries() { - local api=$1 - local arch=$2 - local toolchain=$(get_toolchain) - local build_host=$(get_build_host_internal "$arch") - echo "-L${ANDROID_NDK_ROOT}/toolchains/llvm/prebuilt/${toolchain}/${build_host}/lib -L${ANDROID_NDK_ROOT}/toolchains/llvm/prebuilt/${toolchain}/sysroot/usr/lib/${build_host}/${api} -L${ANDROID_NDK_ROOT}/toolchains/llvm/prebuilt/${toolchain}/lib" -} - -function set_android_cpu_feature() { - local name=$1 - local arch=$(get_android_arch $2) - local api=$3 - case ${arch} in - arm-v7a | arm-v7a-neon) - export CFLAGS="-march=armv7-a -mfpu=vfpv3-d16 -mfloat-abi=softfp -Wno-unused-function -fno-integrated-as -fstrict-aliasing -fPIC -DANDROID -D__ANDROID_API__=${api} -Os -ffunction-sections -fdata-sections $(get_common_includes)" - export CXXFLAGS="-std=c++11 -Os -ffunction-sections -fdata-sections" - export LDFLAGS="-march=armv7-a -mfpu=vfpv3-d16 -mfloat-abi=softfp -Wl,--fix-cortex-a8 -Wl,--gc-sections -Os -ffunction-sections -fdata-sections $(get_common_linked_libraries ${api} ${arch})" - export CPPFLAGS=${CFLAGS} - ;; - arm64-v8a) - export CFLAGS="-march=armv8-a -Wno-unused-function -fno-integrated-as -fstrict-aliasing -fPIC -DANDROID -D__ANDROID_API__=${api} -Os -ffunction-sections -fdata-sections $(get_common_includes)" - export CXXFLAGS="-std=c++11 -Os -ffunction-sections -fdata-sections" - export LDFLAGS="-march=armv8-a -Wl,--gc-sections -Os -ffunction-sections -fdata-sections $(get_common_linked_libraries ${api} ${arch})" - export CPPFLAGS=${CFLAGS} - ;; - x86) - export CFLAGS="-march=i686 -mtune=intel -mssse3 -mfpmath=sse -m32 -Wno-unused-function -fno-integrated-as -fstrict-aliasing -fPIC -DANDROID -D__ANDROID_API__=${api} -Os -ffunction-sections -fdata-sections $(get_common_includes)" - export CXXFLAGS="-std=c++11 -Os -ffunction-sections -fdata-sections" - export LDFLAGS="-march=i686 -Wl,--gc-sections -Os -ffunction-sections -fdata-sections $(get_common_linked_libraries ${api} ${arch})" - export CPPFLAGS=${CFLAGS} - ;; - x86-64) - export CFLAGS="-march=x86-64 -msse4.2 -mpopcnt -m64 -mtune=intel -Wno-unused-function -fno-integrated-as -fstrict-aliasing -fPIC -DANDROID -D__ANDROID_API__=${api} -Os -ffunction-sections -fdata-sections $(get_common_includes)" - export CXXFLAGS="-std=c++11 -Os -ffunction-sections -fdata-sections" - export LDFLAGS="-march=x86-64 -Wl,--gc-sections -Os -ffunction-sections -fdata-sections $(get_common_linked_libraries ${api} ${arch})" - export CPPFLAGS=${CFLAGS} - ;; - esac -} - -function android_printf_global_params() { - local arch=$1 - local abi=$2 - local abi_triple=$3 - local in_dir=$4 - local out_dir=$5 - echo -e "arch = $arch" - echo -e "abi = $abi" - echo -e "abi_triple = $abi_triple" - echo -e "PLATFORM_TYPE = $PLATFORM_TYPE" - echo -e "ANDROID_API = $ANDROID_API" - echo -e "in_dir = $in_dir" - echo -e "out_dir = $out_dir" - echo -e "AR = $AR" - echo -e "CC = $CC" - echo -e "CXX = $CXX" - echo -e "AS = $AS" - echo -e "LD = $LD" - echo -e "RANLIB = $RANLIB" - echo -e "STRIP = $STRIP" - echo -e "CFLAGS = $CFLAGS" - echo -e "CXXFLAGS = $CXXFLAGS" - echo -e "LDFLAGS = $LDFLAGS" - echo -e "CPPFLAGS = $CPPFLAGS" -} diff --git a/Common/3dParty/openssl/build-android-openssl.sh b/Common/3dParty/openssl/build-android-openssl.sh deleted file mode 100755 index e710b6fb6e3..00000000000 --- a/Common/3dParty/openssl/build-android-openssl.sh +++ /dev/null @@ -1,126 +0,0 @@ -#!/bin/bash -# -# Copyright 2016 leenjewel -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# # read -n1 -p "Press any key to continue..." - -set -u - -source ./build-android-common.sh - -init_log_color - -TOOLS_ROOT=$(pwd) - -SOURCE="$0" -while [ -h "$SOURCE" ]; do - DIR="$(cd -P "$(dirname "$SOURCE")" && pwd)" - SOURCE="$(readlink "$SOURCE")" - [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" -done -pwd_path="$(cd -P "$(dirname "$SOURCE")" && pwd)" - -echo pwd_path=${pwd_path} -echo TOOLS_ROOT=${TOOLS_ROOT} - -# openssl-1.1.0f has a configure bug -# openssl-1.1.1d has fix configure bug -LIB_VERSION="OpenSSL_1_1_1i" -LIB_NAME="openssl-1.1.1i" - -echo "https://www.openssl.org/source/${LIB_NAME}.tar.gz" - -# https://github.com/openssl/openssl/archive/OpenSSL_1_1_1d.tar.gz -# https://github.com/openssl/openssl/archive/OpenSSL_1_1_1f.tar.gz -[ -f "${LIB_NAME}.tar.gz" ] || curl -L -o ${LIB_NAME}.tar.gz https://www.openssl.org/source/${LIB_NAME}.tar.gz -s -[ -f "${LIB_NAME}.tar.gz" ] || log_error "openssl download error!" - -set_android_toolchain_bin - -function configure_make() { - - ARCH=$1 - ABI=$2 - ABI_TRIPLE=$3 - - log_info "configure $ABI start..." - - if [ -d "${LIB_NAME}" ]; then - rm -fr "${LIB_NAME}" - fi - tar xfz "${LIB_NAME}.tar.gz" - pushd . - cd "${LIB_NAME}" - - PREFIX_DIR="${pwd_path}/build/android/${ABI}" - if [ -d "${PREFIX_DIR}" ]; then - rm -fr "${PREFIX_DIR}" - fi - mkdir -p "${PREFIX_DIR}" - - OUTPUT_ROOT=${TOOLS_ROOT}/build/android/${ABI} - mkdir -p ${OUTPUT_ROOT}/log - - set_android_toolchain "openssl" "${ARCH}" "${ANDROID_API}" - set_android_cpu_feature "openssl" "${ARCH}" "${ANDROID_API}" - - export ANDROID_NDK_HOME=${ANDROID_NDK_ROOT} - echo ANDROID_NDK_HOME=${ANDROID_NDK_HOME} - - android_printf_global_params "$ARCH" "$ABI" "$ABI_TRIPLE" "$PREFIX_DIR" "$OUTPUT_ROOT" - - if [[ "${ARCH}" == "x86_64" ]]; then - - ./Configure android-x86_64 --prefix="${PREFIX_DIR}" no-shared no-tests enable-ssl3 enable-ssl3-method enable-md2 no-asm - - elif [[ "${ARCH}" == "x86" ]]; then - - ./Configure android-x86 --prefix="${PREFIX_DIR}" no-shared no-tests enable-ssl3 enable-ssl3-method enable-md2 no-asm - - elif [[ "${ARCH}" == "arm" ]]; then - - ./Configure android-arm --prefix="${PREFIX_DIR}" no-shared no-tests enable-ssl3 enable-ssl3-method enable-md2 no-asm - - elif [[ "${ARCH}" == "arm64" ]]; then - - ./Configure android-arm64 --prefix="${PREFIX_DIR}" no-shared no-tests enable-ssl3 enable-ssl3-method enable-md2 no-asm - - else - log_error "not support" && exit 1 - fi - - log_info "make $ABI start..." - - sed -ie 's/LIB_CFLAGS=/LIB_CFLAGS=-fvisibility=hidden /g' ./Makefile - sed -ie 's/LIB_CXXFLAGS=/LIB_CXXFLAGS=-fvisibility=hidden /g' ./Makefile - - make clean >"${OUTPUT_ROOT}/log/${ABI}.log" - if make -j$(get_cpu_count) >>"${OUTPUT_ROOT}/log/${ABI}.log" 2>&1; then - make install_sw >>"${OUTPUT_ROOT}/log/${ABI}.log" 2>&1 - make install_ssldirs >>"${OUTPUT_ROOT}/log/${ABI}.log" 2>&1 - fi - - popd -} - -log_info "${PLATFORM_TYPE} ${LIB_NAME} start..." - -for ((i = 0; i < ${#ARCHS[@]}; i++)); do - if [[ $# -eq 0 || "$1" == "${ARCHS[i]}" ]]; then - configure_make "${ARCHS[i]}" "${ABIS[i]}" "${ABI_TRIPLES[i]}" - fi -done - -log_info "${PLATFORM_TYPE} ${LIB_NAME} end..." diff --git a/Common/3dParty/openssl/build-ios-common.sh b/Common/3dParty/openssl/build-ios-common.sh index bbfe97ee336..f0084c7bfb6 100755 --- a/Common/3dParty/openssl/build-ios-common.sh +++ b/Common/3dParty/openssl/build-ios-common.sh @@ -84,24 +84,24 @@ function set_ios_cpu_feature() { armv7) export CC="xcrun -sdk iphoneos clang -arch armv7" export CXX="xcrun -sdk iphoneos clang++ -arch armv7" - export CFLAGS="-arch armv7 -target armv7-ios-darwin -march=armv7 -mcpu=cortex-a8 -mfpu=neon -mfloat-abi=softfp -Wno-unused-function -fstrict-aliasing -Oz -Wno-ignored-optimization-argument -DIOS -isysroot ${sysroot} -fembed-bitcode -miphoneos-version-min=${ios_min_target} -I${sysroot}/usr/include" - export LDFLAGS="-arch armv7 -target armv7-ios-darwin -march=armv7 -isysroot ${sysroot} -fembed-bitcode -L${sysroot}/usr/lib " - export CXXFLAGS="-std=c++11 -arch armv7 -target armv7-ios-darwin -march=armv7 -mcpu=cortex-a8 -mfpu=neon -mfloat-abi=softfp -fstrict-aliasing -fembed-bitcode -DIOS -miphoneos-version-min=${ios_min_target} -I${sysroot}/usr/include" + export CFLAGS="-arch armv7 -target armv7-ios-darwin -march=armv7 -mcpu=cortex-a8 -mfpu=neon -mfloat-abi=softfp -Wno-unused-function -fstrict-aliasing -Oz -Wno-ignored-optimization-argument -DIOS -isysroot ${sysroot} -miphoneos-version-min=${ios_min_target} -I${sysroot}/usr/include" + export LDFLAGS="-arch armv7 -target armv7-ios-darwin -march=armv7 -isysroot ${sysroot} -L${sysroot}/usr/lib " + export CXXFLAGS="-std=c++11 -arch armv7 -target armv7-ios-darwin -march=armv7 -mcpu=cortex-a8 -mfpu=neon -mfloat-abi=softfp -fstrict-aliasing -DIOS -miphoneos-version-min=${ios_min_target} -I${sysroot}/usr/include" ;; arm64) export CC="xcrun -sdk iphoneos clang -arch arm64" export CXX="xcrun -sdk iphoneos clang++ -arch arm64" - export CFLAGS="-arch arm64 -target aarch64-ios-darwin -march=armv8 -mcpu=generic -Wno-unused-function -fstrict-aliasing -Oz -Wno-ignored-optimization-argument -DIOS -isysroot ${sysroot} -fembed-bitcode -miphoneos-version-min=${ios_min_target} -I${sysroot}/usr/include" - export LDFLAGS="-arch arm64 -target aarch64-ios-darwin -march=armv8 -isysroot ${sysroot} -fembed-bitcode -L${sysroot}/usr/lib " - export CXXFLAGS="-std=c++11 -arch arm64 -target aarch64-ios-darwin -march=armv8 -mcpu=generic -fstrict-aliasing -fembed-bitcode -DIOS -miphoneos-version-min=${ios_min_target} -I${sysroot}/usr/include" + export CFLAGS="-arch arm64 -target aarch64-ios-darwin -march=armv8 -mcpu=generic -Wno-unused-function -fstrict-aliasing -Oz -Wno-ignored-optimization-argument -DIOS -isysroot ${sysroot} -miphoneos-version-min=${ios_min_target} -I${sysroot}/usr/include" + export LDFLAGS="-arch arm64 -target aarch64-ios-darwin -march=armv8 -isysroot ${sysroot} -L${sysroot}/usr/lib " + export CXXFLAGS="-std=c++11 -arch arm64 -target aarch64-ios-darwin -march=armv8 -mcpu=generic -fstrict-aliasing -DIOS -miphoneos-version-min=${ios_min_target} -I${sysroot}/usr/include" ;; arm64e) # -march=armv8.3 ??? export CC="xcrun -sdk iphoneos clang -arch arm64e" export CXX="xcrun -sdk iphoneos clang++ -arch arm64e" - export CFLAGS="-arch arm64e -target aarch64-ios-darwin -Wno-unused-function -fstrict-aliasing -DIOS -isysroot ${sysroot} -fembed-bitcode -miphoneos-version-min=${ios_min_target} -I${sysroot}/usr/include" - export LDFLAGS="-arch arm64e -target aarch64-ios-darwin -isysroot ${sysroot} -fembed-bitcode -L${sysroot}/usr/lib " - export CXXFLAGS="-std=c++11 -arch arm64e -target aarch64-ios-darwin -fstrict-aliasing -fembed-bitcode -DIOS -miphoneos-version-min=${ios_min_target} -I${sysroot}/usr/include" + export CFLAGS="-arch arm64e -target aarch64-ios-darwin -Wno-unused-function -fstrict-aliasing -DIOS -isysroot ${sysroot} -miphoneos-version-min=${ios_min_target} -I${sysroot}/usr/include" + export LDFLAGS="-arch arm64e -target aarch64-ios-darwin -isysroot ${sysroot} -L${sysroot}/usr/lib " + export CXXFLAGS="-std=c++11 -arch arm64e -target aarch64-ios-darwin -fstrict-aliasing -DIOS -miphoneos-version-min=${ios_min_target} -I${sysroot}/usr/include" ;; i386) export CC="xcrun -sdk iphonesimulator clang -arch i386" @@ -120,9 +120,9 @@ function set_ios_cpu_feature() { sim-arm64) export CC="xcrun -sdk iphonesimulator clang -arch arm64" export CXX="xcrun -sdk iphonesimulator clang++ -arch arm64" - export CFLAGS="-arch arm64 -target aarch64-apple-darwin -march=armv8 -mcpu=generic -Wno-unused-function -fstrict-aliasing -Oz -Wno-ignored-optimization-argument -DIOS -isysroot ${sysroot} -fembed-bitcode -mios-simulator-version-min=${ios_min_target} -I${sysroot}/usr/include" - export LDFLAGS="-arch arm64 -target aaarch64-apple-darwin -march=armv8 -isysroot ${sysroot} -fembed-bitcode -L${sysroot}/usr/lib " - export CXXFLAGS="-std=c++11 -arch arm64 -target aarch64-apple-darwin -march=armv8 -mcpu=generic -fstrict-aliasing -fembed-bitcode -DIOS -mios-simulator-version-min=${ios_min_target} -I${sysroot}/usr/include" + export CFLAGS="-arch arm64 -target aarch64-apple-darwin -march=armv8 -mcpu=generic -Wno-unused-function -fstrict-aliasing -Oz -Wno-ignored-optimization-argument -DIOS -isysroot ${sysroot} -mios-simulator-version-min=${ios_min_target} -I${sysroot}/usr/include" + export LDFLAGS="-arch arm64 -target aaarch64-apple-darwin -march=armv8 -isysroot ${sysroot} -L${sysroot}/usr/lib " + export CXXFLAGS="-std=c++11 -arch arm64 -target aarch64-apple-darwin -march=armv8 -mcpu=generic -fstrict-aliasing -DIOS -mios-simulator-version-min=${ios_min_target} -I${sysroot}/usr/include" ;; *) log_error "not support" && exit 1 diff --git a/Common/3dParty/openssl/build-ios-openssl.sh b/Common/3dParty/openssl/build-ios-openssl.sh index a1d07bdb611..f884c7fcef8 100755 --- a/Common/3dParty/openssl/build-ios-openssl.sh +++ b/Common/3dParty/openssl/build-ios-openssl.sh @@ -107,26 +107,26 @@ function configure_make() { # openssl1.1.1d can be set normally, 1.1.0f does not take effect ./Configure iphoneos-cross no-shared --prefix="${PREFIX_DIR}" enable-ssl3 enable-ssl3-method enable-md2 - sed -ie "s!-fno-common!-fno-common -fembed-bitcode !" "Makefile" + #sed -ie "s!-fno-common!-fno-common -fembed-bitcode !" "Makefile" elif [[ "${ARCH_NAME}" == "arm64" ]]; then # openssl1.1.1d can be set normally, 1.1.0f does not take effect ./Configure iphoneos-cross no-shared --prefix="${PREFIX_DIR}" enable-ssl3 enable-ssl3-method enable-md2 - sed -ie "s!-fno-common!-fno-common -fembed-bitcode !" "Makefile" + #sed -ie "s!-fno-common!-fno-common -fembed-bitcode !" "Makefile" elif [[ "${ARCH_NAME}" == "i386" ]]; then # openssl1.1.1d can be set normally, 1.1.0f does not take effect ./Configure darwin-i386-cc no-shared --prefix="${PREFIX_DIR}" enable-ssl3 enable-ssl3-method enable-md2 - sed -ie "s!-fno-common!-fno-common -fembed-bitcode !" "Makefile" + #sed -ie "s!-fno-common!-fno-common -fembed-bitcode !" "Makefile" sed -i -e 's/-mtune=intel//g' "Makefile" elif [[ "${ARCH_NAME}" == "sim_arm64" ]]; then # openssl1.1.1d can be set normally, 1.1.0f does not take effect ./Configure iphoneos-cross no-shared --prefix="${PREFIX_DIR}" enable-ssl3 enable-ssl3-method enable-md2 - sed -ie "s!-fno-common!-fno-common -fembed-bitcode !" "Makefile" + #sed -ie "s!-fno-common!-fno-common -fembed-bitcode !" "Makefile" else log_error "not support" && exit 1 diff --git a/Common/3dParty/openssl/openssl.pri b/Common/3dParty/openssl/openssl.pri index 861eb4d3433..cb565d46210 100644 --- a/Common/3dParty/openssl/openssl.pri +++ b/Common/3dParty/openssl/openssl.pri @@ -11,16 +11,7 @@ open_ssl_common { OPENSSL_LIBS_DIRECTORY = $$PWD/build/$$OPEN_SSL_PLATFORM/lib core_android { - - OPENSSL_ABI_PATH = $$replace(CORE_BUILDS_PLATFORM_PREFIX, "android_", "") - contains(OPENSSL_ABI_PATH, "armv7" ) { - OPENSSL_ABI_PATH = $$replace(OPENSSL_ABI_PATH, "armv7", "armeabi-v7a") - } - contains(OPENSSL_ABI_PATH, "arm64_v8a" ) { - OPENSSL_ABI_PATH = $$replace(OPENSSL_ABI_PATH, "arm64_v8a", "arm64-v8a") - } - - OPENSSL_LIBS_DIRECTORY = $$PWD/build/android/$$OPENSSL_ABI_PATH/lib + OPENSSL_LIBS_DIRECTORY = $$PWD/build/android/$$CORE_BUILDS_PLATFORM_PREFIX_DST/lib } core_ios { diff --git a/Common/3dParty/pole/pole.cpp b/Common/3dParty/pole/pole.cpp index 3f93d1e1451..fbbd2a4b3df 100644 --- a/Common/3dParty/pole/pole.cpp +++ b/Common/3dParty/pole/pole.cpp @@ -985,7 +985,7 @@ void DirTree::load( unsigned char* buffer, uint64 size ) std::wstring name; - if (name_len > 0) + if (name_len > 1) { if (sizeof(wchar_t) == 2) { diff --git a/Common/3dParty/socketio/patches/sio_client_impl_close_timeout.patch b/Common/3dParty/socketio/patches/sio_client_impl_close_timeout.patch new file mode 100644 index 00000000000..eb86aeb7cfd --- /dev/null +++ b/Common/3dParty/socketio/patches/sio_client_impl_close_timeout.patch @@ -0,0 +1,7 @@ +<<<<<<< + m_packet_mgr.set_encode_callback(std::bind(&client_impl::on_encode,this,_1,_2)); +======= + m_packet_mgr.set_encode_callback(std::bind(&client_impl::on_encode,this,_1,_2)); + + m_client.set_close_handshake_timeout(1); +>>>>>>> diff --git a/Common/3dParty/socketio/patches/sio_client_impl_fail.patch b/Common/3dParty/socketio/patches/sio_client_impl_fail.patch new file mode 100644 index 00000000000..5c5a8a8f9e2 --- /dev/null +++ b/Common/3dParty/socketio/patches/sio_client_impl_fail.patch @@ -0,0 +1,22 @@ +<<<<<<< + if (m_con_state == con_closing) { + LOG("Connection failed while closing." << endl); + this->close(); + return; + } + + m_con.reset(); + m_con_state = con_closed; + this->sockets_invoke_void(&sio_no_tls::socket::on_disconnect); +======= + con_state con_state_old = m_con_state; + m_con.reset(); + m_con_state = con_closed; + this->sockets_invoke_void(&sio::socket::on_disconnect); + + if (con_state_old == con_closing) { + LOG("Connection failed while closing." << endl); + this->close(); + return; + } +>>>>>>> diff --git a/Common/3dParty/socketio/patches/sio_client_impl_open.patch b/Common/3dParty/socketio/patches/sio_client_impl_open.patch new file mode 100644 index 00000000000..1b0c811c712 --- /dev/null +++ b/Common/3dParty/socketio/patches/sio_client_impl_open.patch @@ -0,0 +1,24 @@ +<<<<<<< + if (m_con_state == con_closing) { + LOG("Connection opened while closing." << endl); + this->close(); + return; + } + + LOG("Connected." << endl); + m_con_state = con_opened; + m_con = con; + m_reconn_made = 0; +======= + con_state con_state_old = m_con_state; + LOG("Connected." << endl); + m_con_state = con_opened; + m_con = con; + m_reconn_made = 0; + + if (con_state_old == con_closing) { + LOG("Connection opened while closing." << endl); + this->close(); + return; + } +>>>>>>> diff --git a/Common/3dParty/socketio/patches/websocketpp.patch b/Common/3dParty/socketio/patches/websocketpp.patch new file mode 100644 index 00000000000..b2291a6bf20 --- /dev/null +++ b/Common/3dParty/socketio/patches/websocketpp.patch @@ -0,0 +1,40 @@ +<<<<<<< +template <typename config> +void connection<config>::handle_terminate(terminate_status tstat, + lib::error_code const & ec) +{ + if (m_alog->static_test(log::alevel::devel)) { + m_alog->write(log::alevel::devel,"connection handle_terminate"); + } + + if (ec) { + // there was an error actually shutting down the connection + log_err(log::elevel::devel,"handle_terminate",ec); + } +======= +template <typename config> +void connection<config>::handle_terminate(terminate_status tstat, + lib::error_code const & ec) +{ + if (m_alog->static_test(log::alevel::devel)) { + m_alog->write(log::alevel::devel,"connection handle_terminate"); + } + + if (ec) { + // there was an error actually shutting down the connection + log_err(log::elevel::devel,"handle_terminate",ec); + } + + // Even with all workarounds and bug fixes in socket-io master branch, still running into + // cases like https://github.com/socketio/socket.io-client-cpp/issues/254. + // + // After much investigation and debugging, seems like the socket is remaining + // open and preventing the network thread from ending. Perhaps this is specific to the + // environment where this code is run by Solink. The only solution seems to be manually + // closing the socket as described here: https://github.com/zaphoyd/websocketpp/issues/805 + + bool isSocketOpen = transport_con_type::get_raw_socket().is_open(); + if (isSocketOpen) { + transport_con_type::get_raw_socket().close(); + } +>>>>>>> diff --git a/Common/3dParty/v8/android/howto.txt b/Common/3dParty/v8/android/howto.txt new file mode 100644 index 00000000000..099db5a4a70 --- /dev/null +++ b/Common/3dParty/v8/android/howto.txt @@ -0,0 +1,46 @@ +Fixes for build 12.1 version for android with use_custom_libcxx: + +1) src/build/config/BUILD.gn + +group("common_deps") { ... } + +if (use_custom_libcxx) { + public_deps += [ "//buildtools/third_party/libc++" ] +} + +=> + +if (use_custom_libcxx) { + public_deps += [ "//buildtools/third_party/libc++" ] +} else { + # ONLYOFFICE-HACK + public_deps += [ "//buildtools/third_party/libunwind" ] +} + +2) src/buildtools/third_party/libunbind/BUILD.gn + +visibility = [ "//buildtools/third_party/libc++abi" ] + +=> +visibility = [ "//buildtools/third_party/libc++abi" ] +# ONLYOFFICE-HACK +visibility += ["//build/config:common_deps"] + +3) src/zone/zone.h + +all records: +static_assert(alignof(T) <= kAlignmentInBytes); + +=> + +// ONLYOFFICE-HACK +//static_assert(alignof(T) <= kAlignmentInBytes); + +Fixes for link static library WITH custom libc++: + +v8.pri: +v8_custom_libcxx { + LIBS += $$CORE_V8_PATH_LIBS/third_party/libc++/libc++/*.o + LIBS += $$CORE_V8_PATH_LIBS/third_party/libc++abi/libc++abi/*.o + LIBS += $$CORE_V8_PATH_LIBS/third_party/libunwind/libunwind/*.o +} diff --git a/Common/3dParty/v8/v8.pri b/Common/3dParty/v8/v8.pri index 24f6fe1afb2..11c7c72d1b1 100644 --- a/Common/3dParty/v8/v8.pri +++ b/Common/3dParty/v8/v8.pri @@ -5,6 +5,7 @@ v8_version_89 { CONFIG += c++14 CONFIG += use_v8_monolith DEFINES += V8_VERSION_89_PLUS + DEFINES += V8_SUPPORT_SNAPSHOTS core_win_32:CONFIG += build_platform_32 core_linux_32:CONFIG += build_platform_32 diff --git a/Common/Network/FileTransporter/src/FileTransporter_private.h b/Common/Network/FileTransporter/src/FileTransporter_private.h index 1cfc2f7b672..9de9dd28c2d 100644 --- a/Common/Network/FileTransporter/src/FileTransporter_private.h +++ b/Common/Network/FileTransporter/src/FileTransporter_private.h @@ -34,6 +34,7 @@ #include "../../../../DesktopEditor/common/File.h" #include "../../../../DesktopEditor/graphics/BaseThread.h" #include "../include/FileTransporter.h" +#include "../../../../DesktopEditor/common/ProcessEnv.h" namespace NSNetwork { @@ -240,13 +241,25 @@ namespace NSNetwork { m_pInternal->m_bComplete = false; + bool bIsCanUseNetwork = true; + if (NSProcessEnv::IsPresent(NSProcessEnv::Converter::gc_allowNetworkRequest)) + bIsCanUseNetwork = NSProcessEnv::GetBoolValue(NSProcessEnv::Converter::gc_allowNetworkRequest); + int hrResultAll = 0; - if(m_pInternal->m_eLoadType == m_pInternal->DOWNLOADFILE) - hrResultAll = m_pInternal->DownloadFile(); - else if(m_pInternal->m_eLoadType == m_pInternal->UPLOADFILE) - hrResultAll = m_pInternal->UploadFile(); - else if(m_pInternal->m_eLoadType == m_pInternal->UPLOADDATA) - hrResultAll = m_pInternal->UploadData(); + + if (bIsCanUseNetwork) + { + if(m_pInternal->m_eLoadType == m_pInternal->DOWNLOADFILE) + hrResultAll = m_pInternal->DownloadFile(); + else if(m_pInternal->m_eLoadType == m_pInternal->UPLOADFILE) + hrResultAll = m_pInternal->UploadFile(); + else if(m_pInternal->m_eLoadType == m_pInternal->UPLOADDATA) + hrResultAll = m_pInternal->UploadData(); + } + else + { + hrResultAll = 1; + } if (0 == hrResultAll) m_pInternal->m_bComplete = true; diff --git a/Common/Network/FileTransporter/src/FileTransporter_win.cpp b/Common/Network/FileTransporter/src/FileTransporter_win.cpp index e769c4cc4a0..ac1add66726 100644 --- a/Common/Network/FileTransporter/src/FileTransporter_win.cpp +++ b/Common/Network/FileTransporter/src/FileTransporter_win.cpp @@ -442,6 +442,36 @@ namespace NSNetwork std::function<void(int)> func_onProgress = nullptr; }; + void EscapeQuotesPS(std::wstring& command, bool isPath) + { + /* + var symbols = [0x22, 0x27, 0x2018, 0x2019, 0x201a, 0x201b, 0x201c, 0x201d, 0x201e, 0x201f]; + var output = ""; + for (let i = 0; i < symbols.length; i++) output += (" " + encodeURI(String.fromCharCode(symbols[i]))); + console.log(output); + + result: + "%22 %27 %E2%80%98 %E2%80%99 %E2%80%9A %E2%80%9B %E2%80%9C %E2%80%9D %E2%80%9E %E2%80%9F" + */ + + std::wstring sTmp = L" "; + + if (isPath) + { + sTmp[0] = (wchar_t)'\\'; NSStringExt::Replace(command, sTmp, L"/"); + } + + sTmp[0] = (wchar_t)0x22; NSStringExt::Replace(command, sTmp, L"%22"); + sTmp[0] = (wchar_t)0x27; NSStringExt::Replace(command, sTmp, L"%27"); + sTmp[0] = (wchar_t)0x2018; NSStringExt::Replace(command, sTmp, L"%E2%80%98"); + sTmp[0] = (wchar_t)0x2019; NSStringExt::Replace(command, sTmp, L"%E2%80%99"); + sTmp[0] = (wchar_t)0x201a; NSStringExt::Replace(command, sTmp, L"%E2%80%9A"); + sTmp[0] = (wchar_t)0x201b; NSStringExt::Replace(command, sTmp, L"%E2%80%9B"); + sTmp[0] = (wchar_t)0x201c; NSStringExt::Replace(command, sTmp, L"%E2%80%9C"); + sTmp[0] = (wchar_t)0x201d; NSStringExt::Replace(command, sTmp, L"%E2%80%9D"); + sTmp[0] = (wchar_t)0x201e; NSStringExt::Replace(command, sTmp, L"%E2%80%9E"); + sTmp[0] = (wchar_t)0x201f; NSStringExt::Replace(command, sTmp, L"%E2%80%9F"); + } bool DownloadFilePS(const std::wstring& sFileURLOriginal, const std::wstring& strFileOutput) { @@ -452,8 +482,8 @@ namespace NSNetwork std::wstring sFileDst = strFileOutput; std::wstring sFileURL = sFileURLOriginal; - NSStringExt::Replace(sFileDst, L"\\", L"/"); - NSStringExt::Replace(sFileURL, L"'", L"%27"); + EscapeQuotesPS(sFileDst, true); + EscapeQuotesPS(sFileURL, false); std::wstring sApp = L"powershell.exe –c \"(new-object System.Net.WebClient).DownloadFile('" + sFileURL + L"','" + sFileDst + L"')\""; wchar_t* pCommandLine = new wchar_t[sApp.length() + 1]; diff --git a/Common/Network/FileTransporter/src/manager.cpp b/Common/Network/FileTransporter/src/manager.cpp index 78aa9cd01f4..834a114f099 100644 --- a/Common/Network/FileTransporter/src/manager.cpp +++ b/Common/Network/FileTransporter/src/manager.cpp @@ -32,8 +32,8 @@ #include <list> #include "./../include/manager.h" -#include "./../../../core/DesktopEditor/graphics/TemporaryCS.h" -#include "./../../../core/DesktopEditor/graphics/BaseThread.h" +#include "./../../../../DesktopEditor/graphics/TemporaryCS.h" +#include "./../../../../DesktopEditor/graphics/BaseThread.h" namespace ASC { diff --git a/Common/Network/FileTransporter/src/transport_external.h b/Common/Network/FileTransporter/src/transport_external.h index 32f6e30fe59..89fb51aa4c3 100644 --- a/Common/Network/FileTransporter/src/transport_external.h +++ b/Common/Network/FileTransporter/src/transport_external.h @@ -33,6 +33,7 @@ #include <iostream> #include <unistd.h> #include "../../DesktopEditor/common/Directory.h" +#include "../../DesktopEditor/common/ProcessEnv.h" #ifdef USE_EXTERNAL_TRANSPORT @@ -96,7 +97,7 @@ namespace NSNetwork { std::string sProgramBinA = U_TO_UTF8(sCurlBin); - const char* nargs[10]; + const char* nargs[16]; nargs[0] = sProgramBinA.c_str(); nargs[1] = "--url"; nargs[2] = sUrlA.c_str(); @@ -107,6 +108,36 @@ namespace NSNetwork nargs[7] = "--connect-timeout"; nargs[8] = "10"; nargs[9] = NULL; + nargs[10] = NULL; + nargs[11] = NULL; + nargs[12] = NULL; + nargs[13] = NULL; + nargs[14] = NULL; + nargs[15] = NULL; + + std::string sProxy; + std::string sProxyIser; + std::string sProxyHeader; + + int nIndexLast = 9; + if (NSProcessEnv::IsPresent(NSProcessEnv::Converter::gc_proxy)) + { + sProxy = NSProcessEnv::GetStringValueA(NSProcessEnv::Converter::gc_proxy); + nargs[nIndexLast++] = "--proxy"; + nargs[nIndexLast++] = sProxy.c_str(); + } + if (NSProcessEnv::IsPresent(NSProcessEnv::Converter::gc_proxyUser)) + { + sProxyIser = NSProcessEnv::GetStringValueA(NSProcessEnv::Converter::gc_proxyUser); + nargs[nIndexLast++] = "--proxy-user"; + nargs[nIndexLast++] = sProxyIser.c_str(); + } + if (NSProcessEnv::IsPresent(NSProcessEnv::Converter::gc_proxyHeader)) + { + sProxyHeader = NSProcessEnv::GetStringValueA(NSProcessEnv::Converter::gc_proxyHeader); + nargs[nIndexLast++] = "--proxy-header"; + nargs[nIndexLast++] = sProxyHeader.c_str(); + } const char* nenv[3]; nenv[0] = "LD_PRELOAD="; diff --git a/Common/Network/WebSocket/src/socketio/socketio_internal_private.h b/Common/Network/WebSocket/src/socketio/socketio_internal_private.h index 3cd44fe1efe..a5f68b2c319 100644 --- a/Common/Network/WebSocket/src/socketio/socketio_internal_private.h +++ b/Common/Network/WebSocket/src/socketio/socketio_internal_private.h @@ -88,6 +88,17 @@ namespace NSNetwork m_base->listener->onError(""); } + void event_onReconnecting() + { + CTemporaryCS oCS(&m_oCS_Events); + m_connecting_in_process = true; + } + void event_onReconnect(unsigned, unsigned) + { + CTemporaryCS oCS(&m_oCS_Events); + m_connecting_in_process = false; + } + public: virtual void open(const std::map<std::string, std::string>& query) override { @@ -96,6 +107,10 @@ namespace NSNetwork m_socket->set_close_listener(std::bind(&CIOWebSocket_private_tls::event_onClose, this, std::placeholders::_1)); m_socket->set_fail_listener (std::bind(&CIOWebSocket_private_tls::event_onFail, this)); + m_socket->set_reconnect_listener(std::bind(&CIOWebSocket_private_tls::event_onReconnect, this, + std::placeholders::_1, std::placeholders::_2)); + m_socket->set_reconnecting_listener(std::bind(&CIOWebSocket_private_tls::event_onReconnecting, this)); + sio::message::ptr objAuth = sio::object_message::create(); //std::string sAuth; diff --git a/Common/OfficeFileErrorDescription.h b/Common/OfficeFileErrorDescription.h index 894c3a541d3..898cb85cf93 100644 --- a/Common/OfficeFileErrorDescription.h +++ b/Common/OfficeFileErrorDescription.h @@ -244,3 +244,4 @@ #define AVS_FILEUTILS_ERROR_CONVERT_LIMITS (AVS_ERROR_FIRST + AVS_FILEUTILS_ERROR_FIRST + 0x005d) #define AVS_FILEUTILS_ERROR_CONVERT_ROWLIMITS (AVS_ERROR_FIRST + AVS_FILEUTILS_ERROR_FIRST + 0x005e) #define AVS_FILEUTILS_ERROR_CONVERT_DETECT (AVS_ERROR_FIRST + AVS_FILEUTILS_ERROR_FIRST + 0x005f) +#define AVS_FILEUTILS_ERROR_CONVERT_CELLLIMITS (AVS_ERROR_FIRST + AVS_FILEUTILS_ERROR_FIRST + 0x0060) diff --git a/Common/OfficeFileFormatChecker.h b/Common/OfficeFileFormatChecker.h index a147b799cd0..d8a9fe07557 100644 --- a/Common/OfficeFileFormatChecker.h +++ b/Common/OfficeFileFormatChecker.h @@ -95,6 +95,7 @@ class COfficeFileFormatChecker bool isHtmlFormatFile(unsigned char* pBuffer, int dwBytes, bool testCloseTag); bool isMultiPartsHtmlFormatFile(unsigned char* pBuffer, int dwBytes); bool isPdfFormatFile(unsigned char* pBuffer, int dwBytes, std::wstring& documentID); + bool isPdfOformFormatFile(unsigned char* pBuffer, int dwBytes); bool isOpenOfficeFlatFormatFile(unsigned char* pBuffer, int dwBytes); bool isBinaryDoctFormatFile(unsigned char* pBuffer, int dwBytes); diff --git a/Common/OfficeFileFormatChecker2.cpp b/Common/OfficeFileFormatChecker2.cpp index 2670b29bc2d..d2887d78fd7 100644 --- a/Common/OfficeFileFormatChecker2.cpp +++ b/Common/OfficeFileFormatChecker2.cpp @@ -35,13 +35,18 @@ #include "../DesktopEditor/xml/include/xmlutils.h" #include "../OOXML/Base/Base.h" #include "../OfficeUtils/src/OfficeUtils.h" -// #if defined FILE_FORMAT_CHECKER_WITH_MACRO -// #include "../MsBinaryFile/PptFile/Main/PPTFormatLib.h" -// #endif + +//#define FILE_FORMAT_CHECKER_WITH_MACRO + +#if defined FILE_FORMAT_CHECKER_WITH_MACRO + #include "../MsBinaryFile/PptFile/Main/PPTFormatLib.h" + #endif #include "3dParty/pole/pole.h" #include <algorithm> +#include "OfficeFileFormatDefines.h" + #define MIN_SIZE_BUFFER 4096 #define MAX_SIZE_BUFFER 102400 @@ -63,7 +68,7 @@ std::string ReadStringFromOle(POLE::Stream *stream, unsigned int max_size) if (cch > max_size) { // error ... skip to 0 - unsigned int pos_orinal = stream->tell(); + unsigned int pos_orinal = (unsigned int)stream->tell(); unsigned int pos = 0; stream->read(stringBytes, max_size); @@ -81,7 +86,7 @@ std::string ReadStringFromOle(POLE::Stream *stream, unsigned int max_size) if (cch > 0) { // dont read the terminating zero - cch = stream->read(stringBytes, cch); + cch = (_UINT32)stream->read(stringBytes, cch); result = std::string((char *)stringBytes, cch); } } @@ -231,6 +236,28 @@ bool COfficeFileFormatChecker::isPdfFormatFile(unsigned char *pBuffer, int dwByt char *pFirst = strstr((char *)pBuffer, "%PDF-"); + if (NULL == pFirst) + { + char* pData = (char*)pBuffer; + for (int i = 0; i < dwBytes - 5; ++i) + { + int nPDF = strncmp(&pData[i], "%PDF-", 5); + if (!nPDF) + { + pFirst = (char*)pBuffer + i; + break; + } + } + if (NULL == pFirst) + { + //skip special + _UINT16 sz = pBuffer[0] + (pBuffer[1] << 8); + if (sz < dwBytes - 8) + { + pFirst = strstr((char*)(pBuffer + sz), "%PDF-"); + } + } + } if (NULL != pFirst) { pFirst = strstr((char *)pBuffer, "%DocumentID "); @@ -241,7 +268,7 @@ bool COfficeFileFormatChecker::isPdfFormatFile(unsigned char *pBuffer, int dwByt if (NULL != pLast) { std::string s(pFirst, pLast - pFirst); - documentID = NSFile::CUtf8Converter::GetUnicodeStringFromUTF8((BYTE *)s.c_str(), s.length()); + documentID = NSFile::CUtf8Converter::GetUnicodeStringFromUTF8((BYTE*)pFirst, (LONG)(pLast - pFirst)); } } return true; @@ -249,6 +276,39 @@ bool COfficeFileFormatChecker::isPdfFormatFile(unsigned char *pBuffer, int dwByt return false; } +bool COfficeFileFormatChecker::isPdfOformFormatFile(unsigned char *pBuffer, int dwBytes) +{ + pBuffer[dwBytes - 1] = 0; + char* pFirst = strstr((char*)pBuffer, "%\315\312\322\251\015"); + + if (!pFirst || pFirst - (char*)pBuffer + 6 >= dwBytes) + return false; + + pFirst += 6; + + if (strncmp(pFirst, "1 0 obj\012<<\012", 11) != 0 || pFirst - (char*)pBuffer + 11 >= dwBytes) + return false; + + pFirst += 11; + + char* pStream = strstr(pFirst, "stream\015\012"); + char* pMeta = strstr(pFirst, g_format_oform_pdf_meta_tag); + if (!pStream || !pMeta || pStream < pMeta) + return false; + + pMeta += strlen(g_format_oform_pdf_meta_tag) + 3; + + char* pMetaLast = strstr(pMeta, " "); + if (!pMetaLast) + return false; + + pMeta = pMetaLast + 1; + pMetaLast = strstr(pMeta, " "); + if (!pMetaLast) + return false; + + return true; +} bool COfficeFileFormatChecker::isOleObjectFile(POLE::Storage *storage) { if (storage == NULL) @@ -261,45 +321,51 @@ bool COfficeFileFormatChecker::isOleObjectFile(POLE::Storage *storage) std::string UserType, ClipboardFormat, Program; POLE::Stream streamCompObject(storage, L"CompObj"); - if (false == streamCompObject.fail()) + if (false == streamCompObject.fail() && streamCompObject.size() >= 28) { streamCompObject.seek(28); // skip Header - unsigned int sz_obj = streamCompObject.size() - streamCompObject.tell(); + unsigned int sz_obj = (unsigned int)(streamCompObject.size() - streamCompObject.tell()); if (sz_obj > 4) { UserType = ReadStringFromOle(&streamCompObject, sz_obj); - sz_obj = streamCompObject.size() - streamCompObject.tell(); + sz_obj = (unsigned int)(streamCompObject.size() - streamCompObject.tell()); if (sz_obj > 4) ClipboardFormat = ReadStringFromOle(&streamCompObject, sz_obj); - sz_obj = streamCompObject.size() - streamCompObject.tell(); + sz_obj = (unsigned int)(streamCompObject.size() - streamCompObject.tell()); if (sz_obj > 4) Program = ReadStringFromOle(&streamCompObject, sz_obj); } - if (std::string::npos != Program.find("Excel") || std::string::npos != UserType.find("Excel")) + POLE::Stream streamPackage(storage, L"Package"); + if (false == streamPackage.fail()) + { + nFileType = AVS_OFFICESTUDIO_FILE_OTHER_PACKAGE_IN_OLE; + } + else if (std::string::npos != Program.find("Excel") || std::string::npos != UserType.find("Excel")) { if (isXlsFormatFile(storage)) { nFileType = AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLS; } } - if (std::string::npos != Program.find("Word") || std::string::npos != UserType.find("Word")) + else if (std::string::npos != Program.find("Word") || std::string::npos != UserType.find("Word")) { if (isDocFormatFile(storage)) { //nFileType inside } } - if (std::string::npos != Program.find("PowerPoint") || std::string::npos != UserType.find("PowerPoint")) + else if (std::string::npos != Program.find("PowerPoint") || std::string::npos != UserType.find("PowerPoint")) { if (isPptFormatFile(storage)) { nFileType = AVS_OFFICESTUDIO_FILE_PRESENTATION_PPT; } } + return true; } else @@ -311,7 +377,7 @@ bool COfficeFileFormatChecker::isOleObjectFile(POLE::Storage *storage) if (2 == streamLinkInfo.read((BYTE *)&cch, 2)) { unsigned char *str = new unsigned char[cch]; - cch = streamLinkInfo.read(str, cch); + cch = (short)streamLinkInfo.read(str, cch); ClipboardFormat = std::string((char *)str, cch); RELEASEARRAYOBJECTS(str); @@ -555,7 +621,7 @@ bool COfficeFileFormatChecker::isMS_OFFICECRYPTOFormatFile(POLE::Storage *storag sData.resize(stream.size()); if (stream.read((BYTE *)sData.c_str(), stream.size()) > 0) { - documentID = NSFile::CUtf8Converter::GetUnicodeStringFromUTF8((BYTE *)sData.c_str(), sData.length()); + documentID = UTF8_TO_U(sData); } } return result; @@ -674,13 +740,33 @@ bool COfficeFileFormatChecker::isOfficeFile(const std::wstring &_fileName) if (OfficeUtils.IsArchive(fileName) == S_OK && (false == isPdfFormatFile(bufferDetect, dwDetectdBytes, sDocumentID))) { if (isOOXFormatFile(fileName)) + { + if (bufferDetect) + delete[] bufferDetect; + bufferDetect = NULL; return true; + } else if (isOpenOfficeFormatFile(fileName, sDocumentID)) - return true; + { + if (bufferDetect) + delete[] bufferDetect; + bufferDetect = NULL; + return true; + } else if (isOnlyOfficeFormatFile(fileName)) - return true; + { + if (bufferDetect) + delete[] bufferDetect; + bufferDetect = NULL; + return true; + } else if (isXpsFile(fileName)) - return true; + { + if (bufferDetect) + delete[] bufferDetect; + bufferDetect = NULL; + return true; + } } //----------------------------------------------------------------------------------------------- @@ -715,6 +801,9 @@ bool COfficeFileFormatChecker::isOfficeFile(const std::wstring &_fileName) else if (isPdfFormatFile(bufferDetect, sizeRead, sDocumentID)) // min size - 5 { nFileType = AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_PDF; + + if (isPdfOformFormatFile(bufferDetect, sizeRead)) + nFileType = AVS_OFFICESTUDIO_FILE_DOCUMENT_OFORM_PDF; } else if (isDjvuFormatFile(bufferDetect, sizeRead)) // min size - 8 { @@ -727,7 +816,6 @@ bool COfficeFileFormatChecker::isOfficeFile(const std::wstring &_fileName) { file.SeekFile(fileSize - MIN_SIZE_BUFFER); file.ReadFile(bufferDetect, MIN_SIZE_BUFFER, dwDetectdBytes); - int sizeRead = (int)dwDetectdBytes; } if (isHtmlFormatFile(bufferDetect, sizeRead, true)) // min size - 6 { @@ -756,7 +844,6 @@ bool COfficeFileFormatChecker::isOfficeFile(const std::wstring &_fileName) } //------------------------------------------------------------------------------------------------ file.CloseFile(); - } if (bufferDetect) delete[] bufferDetect; @@ -791,7 +878,8 @@ bool COfficeFileFormatChecker::isOfficeFile(const std::wstring &_fileName) nFileType = AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX; else if (0 == sExt.compare(L".pptx")) nFileType = AVS_OFFICESTUDIO_FILE_PRESENTATION_PPTX; - + else if (0 == sExt.compare(L".vsxd")) + nFileType = AVS_OFFICESTUDIO_FILE_DRAW_VSDX; else if (0 == sExt.compare(L".ods")) nFileType = AVS_OFFICESTUDIO_FILE_SPREADSHEET_ODS; else if (0 == sExt.compare(L".odt")) @@ -801,7 +889,7 @@ bool COfficeFileFormatChecker::isOfficeFile(const std::wstring &_fileName) } else if (0 == sExt.compare(L".mht") || 0 == sExt.compare(L".mhtml")) nFileType = AVS_OFFICESTUDIO_FILE_DOCUMENT_MHT; - else if (0 == sExt.compare(L".csv") || 0 == sExt.compare(L".xlsx")) + else if (0 == sExt.compare(L".csv") || 0 == sExt.compare(L".xls") || 0 == sExt.compare(L".xlsx") || 0 == sExt.compare(L".xlsb")) nFileType = AVS_OFFICESTUDIO_FILE_SPREADSHEET_CSV; else if (0 == sExt.compare(L".html") || 0 == sExt.compare(L".htm")) nFileType = AVS_OFFICESTUDIO_FILE_DOCUMENT_HTML; @@ -809,10 +897,18 @@ bool COfficeFileFormatChecker::isOfficeFile(const std::wstring &_fileName) nFileType = AVS_OFFICESTUDIO_FILE_CANVAS_PDF; else if (0 == sExt.compare(L".doct")) // случай архива с html viewer nFileType = AVS_OFFICESTUDIO_FILE_TEAMLAB_DOCY; - else if (0 == sExt.compare(L".xlsb")) - nFileType = AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSB; - else // if (0 == sExt.compare(L".txt") || 0 == sExt.compare(L".xml")) //volsciv.rtf -или любой другой + else if (0 == sExt.compare(L".txt") || 0 == sExt.compare(L".xml") || 0 == sExt.compare(L".rtf") || 0 == sExt.compare(L".doc") || 0 == sExt.compare(L".docx") || 0 == sExt.compare(L".md")) nFileType = AVS_OFFICESTUDIO_FILE_DOCUMENT_TXT; + else if (0 == sExt.compare(L".pages")) + nFileType = AVS_OFFICESTUDIO_FILE_DOCUMENT_PAGES; + else if (0 == sExt.compare(L".numbers")) + nFileType = AVS_OFFICESTUDIO_FILE_SPREADSHEET_NUMBERS; + else if (0 == sExt.compare(L".key")) + nFileType = AVS_OFFICESTUDIO_FILE_PRESENTATION_KEY; + else if (0 == sExt.compare(L".hwp")) + nFileType = AVS_OFFICESTUDIO_FILE_DOCUMENT_HWP; + else if (0 == sExt.compare(L".hwpx")) + nFileType = AVS_OFFICESTUDIO_FILE_DOCUMENT_HWPX; if (nFileType != AVS_OFFICESTUDIO_FILE_UNKNOWN) return true; @@ -860,10 +956,14 @@ bool COfficeFileFormatChecker::isOOXFormatFile(const std::wstring &fileName, boo const char *ppsmFormatLine = "application/vnd.ms-powerpoint.slideshow.macroEnabled.main+xml"; const char *potmFormatLine = "application/vnd.ms-powerpoint.template.macroEnabled.main+xml"; - std::string strContentTypes((char *)pBuffer, nBufferSize); + const char *vsdxFormatLine = "application/vnd.ms-visio.drawing.main+xml"; + const char *vssxFormatLine = "application/vnd.ms-visio.stencil.main+xml"; + const char *vstxFormatLine = "application/vnd.ms-visio.template.main+xml"; + const char *vsdmFormatLine = "application/vnd.ms-visio.drawing.macroEnabled.main+xml"; + const char *vssmFormatLine = "application/vnd.ms-visio.stencil.macroEnabled.main+xml"; + const char *vstmFormatLine = "application/vnd.ms-visio.template.macroEnabled.main+xml"; - std::string::size_type res1 = std::string::npos; - std::string::size_type res = 0; + std::string strContentTypes((char*)pBuffer, nBufferSize); if (std::string::npos != strContentTypes.find(oformFormatLine)) { @@ -941,7 +1041,34 @@ bool COfficeFileFormatChecker::isOOXFormatFile(const std::wstring &fileName, boo nFileType = AVS_OFFICESTUDIO_FILE_PRESENTATION_POTM; bMacroEnabled = true; } - delete[] pBuffer; + else if (std::string::npos != strContentTypes.find(vsdxFormatLine)) + { + nFileType = AVS_OFFICESTUDIO_FILE_DRAW_VSDX; + } + else if (std::string::npos != strContentTypes.find(vssxFormatLine)) + { + nFileType = AVS_OFFICESTUDIO_FILE_DRAW_VSSX; + } + else if (std::string::npos != strContentTypes.find(vstxFormatLine)) + { + nFileType = AVS_OFFICESTUDIO_FILE_DRAW_VSTX; + } + else if (std::string::npos != strContentTypes.find(vsdmFormatLine)) + { + nFileType = AVS_OFFICESTUDIO_FILE_DRAW_VSDM; + bMacroEnabled = true; + } + else if (std::string::npos != strContentTypes.find(vssmFormatLine)) + { + nFileType = AVS_OFFICESTUDIO_FILE_DRAW_VSSM; + bMacroEnabled = true; + } + else if (std::string::npos != strContentTypes.find(vstmFormatLine)) + { + nFileType = AVS_OFFICESTUDIO_FILE_DRAW_VSTM; + bMacroEnabled = true; + } + delete []pBuffer; pBuffer = NULL; if (nFileType != AVS_OFFICESTUDIO_FILE_UNKNOWN) @@ -1013,6 +1140,7 @@ bool COfficeFileFormatChecker::isOpenOfficeFormatFile(const std::wstring &fileNa const char *odtFormatLine = "application/vnd.oasis.opendocument.text"; const char *odsFormatLine = "application/vnd.oasis.opendocument.spreadsheet"; const char *odpFormatLine = "application/vnd.oasis.opendocument.presentation"; + const char* odgFormatLine = "application/vnd.oasis.opendocument.graphics"; const char *ottFormatLine = "application/vnd.oasis.opendocument.text-template"; const char *otsFormatLine = "application/vnd.oasis.opendocument.spreadsheet-template"; const char *otpFormatLine = "application/vnd.oasis.opendocument.presentation-template"; @@ -1039,31 +1167,38 @@ bool COfficeFileFormatChecker::isOpenOfficeFormatFile(const std::wstring &fileNa hresult = OfficeUtils.LoadFileFromArchive(fileName, L"mimetype", &pBuffer, nBufferSize); if (hresult == S_OK && pBuffer != NULL) { - if (NULL != strstr((char *)pBuffer, ottFormatLine)) + if (48 <= nBufferSize && NULL != strstr((char *)pBuffer, ottFormatLine)) { nFileType = AVS_OFFICESTUDIO_FILE_DOCUMENT_OTT; } - else if (NULL != strstr((char *)pBuffer, otsFormatLine)) + else if (55 <= nBufferSize && NULL != strstr((char *)pBuffer, otsFormatLine)) { nFileType = AVS_OFFICESTUDIO_FILE_SPREADSHEET_OTS; } - else if (NULL != strstr((char *)pBuffer, otpFormatLine)) + else if (56 <= nBufferSize && NULL != strstr((char *)pBuffer, otpFormatLine)) { nFileType = AVS_OFFICESTUDIO_FILE_PRESENTATION_OTP; } - else if (NULL != strstr((char *)pBuffer, odtFormatLine) || NULL != strstr((char *)pBuffer, sxwFormatLine)) + else if ((39 <= nBufferSize && NULL != strstr((char *)pBuffer, odtFormatLine)) || + (30 <= nBufferSize && NULL != strstr((char *)pBuffer, sxwFormatLine))) { nFileType = AVS_OFFICESTUDIO_FILE_DOCUMENT_ODT; } - else if (NULL != strstr((char *)pBuffer, odsFormatLine) || NULL != strstr((char *)pBuffer, sxcFormatLine)) + else if ((46 <= nBufferSize && NULL != strstr((char *)pBuffer, odsFormatLine)) || + (28 <= nBufferSize && NULL != strstr((char *)pBuffer, sxcFormatLine))) { nFileType = AVS_OFFICESTUDIO_FILE_SPREADSHEET_ODS; } - else if (NULL != strstr((char *)pBuffer, odpFormatLine) || NULL != strstr((char *)pBuffer, sxiFormatLine)) + else if ((47 <= nBufferSize && NULL != strstr((char *)pBuffer, odpFormatLine)) || + (31 <= nBufferSize && NULL != strstr((char *)pBuffer, sxiFormatLine))) { nFileType = AVS_OFFICESTUDIO_FILE_PRESENTATION_ODP; } - else if (NULL != strstr((char *)pBuffer, epubFormatLine)) + else if (43 <= nBufferSize && NULL != strstr((char*)pBuffer, odgFormatLine)) + { + nFileType = AVS_OFFICESTUDIO_FILE_PRESENTATION_ODG; + } + else if (20 <= nBufferSize && NULL != strstr((char *)pBuffer, epubFormatLine)) { nFileType = AVS_OFFICESTUDIO_FILE_DOCUMENT_EPUB; } @@ -1178,7 +1313,7 @@ bool COfficeFileFormatChecker::isOOXFlatFormatFile(unsigned char *pBuffer, int d { // utf-16- big // swap bytes DWORD file_size_round = (dwBytes / 2) * 2; - for (long i = 0; i < file_size_round; i += 2) + for (DWORD i = 0; i < file_size_round; i += 2) { char v = pBuffer[i]; pBuffer[i] = pBuffer[i + 1]; @@ -1240,6 +1375,7 @@ std::wstring COfficeFileFormatChecker::GetExtensionByType(int type) case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOTM: return L".dotm"; case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOC: + case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOC_FLAT: return L".doc"; case AVS_OFFICESTUDIO_FILE_DOCUMENT_ODT: return L".odt"; @@ -1305,6 +1441,7 @@ std::wstring COfficeFileFormatChecker::GetExtensionByType(int type) return L".ots"; case AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_PDF: + case AVS_OFFICESTUDIO_FILE_DOCUMENT_OFORM_PDF: return L".pdf"; case AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_SWF: return L".swf"; @@ -1363,6 +1500,19 @@ std::wstring COfficeFileFormatChecker::GetExtensionByType(int type) case AVS_OFFICESTUDIO_FILE_OTHER_OLD_DRAWING: case AVS_OFFICESTUDIO_FILE_TEAMLAB_PPTY: return L".pptt"; + + case AVS_OFFICESTUDIO_FILE_DRAW_VSDX: + return L".vsdx"; + case AVS_OFFICESTUDIO_FILE_DRAW_VSSX: + return L".vssx"; + case AVS_OFFICESTUDIO_FILE_DRAW_VSTX: + return L".vstx"; + case AVS_OFFICESTUDIO_FILE_DRAW_VSDM: + return L".vsdm"; + case AVS_OFFICESTUDIO_FILE_DRAW_VSSM: + return L".vssm"; + case AVS_OFFICESTUDIO_FILE_DRAW_VSTM: + return L".vstm"; } return L""; } @@ -1461,7 +1611,7 @@ int COfficeFileFormatChecker::GetFormatByExtension(const std::wstring &sExt) return AVS_OFFICESTUDIO_FILE_SPREADSHEET_OTS; if (L".ods" == ext) return AVS_OFFICESTUDIO_FILE_SPREADSHEET_ODS; - + if (L".ooxml" == ext) return AVS_OFFICESTUDIO_FILE_OTHER_OOXML; if (L".odf" == ext) @@ -1507,6 +1657,19 @@ int COfficeFileFormatChecker::GetFormatByExtension(const std::wstring &sExt) return AVS_OFFICESTUDIO_FILE_TEAMLAB_XLSY; if (L".pptt" == ext) return AVS_OFFICESTUDIO_FILE_TEAMLAB_PPTY; + + if (L".vsdx" == ext) + return AVS_OFFICESTUDIO_FILE_DRAW_VSDX; + if (L".vssx" == ext) + return AVS_OFFICESTUDIO_FILE_DRAW_VSSX; + if (L".vstx" == ext) + return AVS_OFFICESTUDIO_FILE_DRAW_VSTX; + if (L".vsdm" == ext) + return AVS_OFFICESTUDIO_FILE_DRAW_VSDM; + if (L".vssm" == ext) + return AVS_OFFICESTUDIO_FILE_DRAW_VSSM; + if (L".vstm" == ext) + return AVS_OFFICESTUDIO_FILE_DRAW_VSTM; return 0; } @@ -1573,7 +1736,8 @@ bool COfficeFileFormatChecker::isXpsFile(const std::wstring &fileName) { // http://schemas.microsoft.com/xps/2005/06/fixedrepresentation // http://schemas.openxps.org/oxps/v1.0/fixedrepresentation - if (NULL != strstr((char *)pBuffer, "fixedrepresentation") && (NULL != strstr((char *)pBuffer, "/xps/") || NULL != strstr((char *)pBuffer, "/oxps/"))) + if ((19 <= nBufferSize && NULL != strstr((char *)pBuffer, "fixedrepresentation") && (NULL != strstr((char *)pBuffer, "/xps/")) || + (6 <= nBufferSize && NULL != strstr((char *)pBuffer, "/oxps/")))) { nFileType = AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_XPS; } diff --git a/X2tConverter/test/iosTest/TestIOSX2tConverter/ViewController.h b/Common/OfficeFileFormatDefines.h similarity index 95% rename from X2tConverter/test/iosTest/TestIOSX2tConverter/ViewController.h rename to Common/OfficeFileFormatDefines.h index 990f13279ce..a9aa8bee33c 100644 --- a/X2tConverter/test/iosTest/TestIOSX2tConverter/ViewController.h +++ b/Common/OfficeFileFormatDefines.h @@ -29,11 +29,6 @@ * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode * */ +#pragma once -#import <UIKit/UIKit.h> - -@interface ViewController : UIViewController - - -@end - +static const char* g_format_oform_pdf_meta_tag = "ONLYOFFICEFORM"; diff --git a/Common/OfficeFileFormats.h b/Common/OfficeFileFormats.h index 488dd27b4b1..fb7d280ac32 100644 --- a/Common/OfficeFileFormats.h +++ b/Common/OfficeFileFormats.h @@ -55,6 +55,10 @@ #define AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX_PACKAGE AVS_OFFICESTUDIO_FILE_DOCUMENT + 0x0014 #define AVS_OFFICESTUDIO_FILE_DOCUMENT_OFORM AVS_OFFICESTUDIO_FILE_DOCUMENT + 0x0015 #define AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCXF AVS_OFFICESTUDIO_FILE_DOCUMENT + 0x0016 +#define AVS_OFFICESTUDIO_FILE_DOCUMENT_OFORM_PDF AVS_OFFICESTUDIO_FILE_DOCUMENT + 0x0017 +#define AVS_OFFICESTUDIO_FILE_DOCUMENT_PAGES AVS_OFFICESTUDIO_FILE_DOCUMENT + 0x0018 +#define AVS_OFFICESTUDIO_FILE_DOCUMENT_HWP AVS_OFFICESTUDIO_FILE_DOCUMENT + 0x0019 +#define AVS_OFFICESTUDIO_FILE_DOCUMENT_HWPX AVS_OFFICESTUDIO_FILE_DOCUMENT + 0x0020 #define AVS_OFFICESTUDIO_FILE_DOCUMENT_XML AVS_OFFICESTUDIO_FILE_DOCUMENT + 0x0030 @@ -70,6 +74,8 @@ #define AVS_OFFICESTUDIO_FILE_PRESENTATION_ODP_FLAT AVS_OFFICESTUDIO_FILE_PRESENTATION + 0x0009 #define AVS_OFFICESTUDIO_FILE_PRESENTATION_OTP AVS_OFFICESTUDIO_FILE_PRESENTATION + 0x000a #define AVS_OFFICESTUDIO_FILE_PRESENTATION_PPTX_PACKAGE AVS_OFFICESTUDIO_FILE_PRESENTATION + 0x000b +#define AVS_OFFICESTUDIO_FILE_PRESENTATION_ODG AVS_OFFICESTUDIO_FILE_PRESENTATION + 0x000c +#define AVS_OFFICESTUDIO_FILE_PRESENTATION_KEY AVS_OFFICESTUDIO_FILE_PRESENTATION + 0x000d #define AVS_OFFICESTUDIO_FILE_SPREADSHEET 0x0100 #define AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSX AVS_OFFICESTUDIO_FILE_SPREADSHEET + 0x0001 @@ -85,6 +91,7 @@ #define AVS_OFFICESTUDIO_FILE_SPREADSHEET_OTS AVS_OFFICESTUDIO_FILE_SPREADSHEET + 0x000a #define AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSX_FLAT AVS_OFFICESTUDIO_FILE_SPREADSHEET + 0x000b #define AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSX_PACKAGE AVS_OFFICESTUDIO_FILE_SPREADSHEET + 0x000c +#define AVS_OFFICESTUDIO_FILE_SPREADSHEET_NUMBERS AVS_OFFICESTUDIO_FILE_SPREADSHEET + 0x000d #define AVS_OFFICESTUDIO_FILE_CROSSPLATFORM 0x0200 #define AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_PDF AVS_OFFICESTUDIO_FILE_CROSSPLATFORM + 0x0001 @@ -125,6 +132,7 @@ #define AVS_OFFICESTUDIO_FILE_OTHER_ODF AVS_OFFICESTUDIO_FILE_OTHER + 0x000a #define AVS_OFFICESTUDIO_FILE_OTHER_MS_MITCRYPTO AVS_OFFICESTUDIO_FILE_OTHER + 0x000b #define AVS_OFFICESTUDIO_FILE_OTHER_MS_VBAPROJECT AVS_OFFICESTUDIO_FILE_OTHER + 0x000c +#define AVS_OFFICESTUDIO_FILE_OTHER_PACKAGE_IN_OLE AVS_OFFICESTUDIO_FILE_OTHER + 0x000d #define AVS_OFFICESTUDIO_FILE_TEAMLAB 0x1000 #define AVS_OFFICESTUDIO_FILE_TEAMLAB_DOCY AVS_OFFICESTUDIO_FILE_TEAMLAB + 0x0001 @@ -136,3 +144,11 @@ #define AVS_OFFICESTUDIO_FILE_CANVAS_SPREADSHEET AVS_OFFICESTUDIO_FILE_CANVAS + 0x0002 #define AVS_OFFICESTUDIO_FILE_CANVAS_PRESENTATION AVS_OFFICESTUDIO_FILE_CANVAS + 0x0003 #define AVS_OFFICESTUDIO_FILE_CANVAS_PDF AVS_OFFICESTUDIO_FILE_CANVAS + 0x0004 + +#define AVS_OFFICESTUDIO_FILE_DRAW 0x4000 +#define AVS_OFFICESTUDIO_FILE_DRAW_VSDX AVS_OFFICESTUDIO_FILE_DRAW + 0x0001 +#define AVS_OFFICESTUDIO_FILE_DRAW_VSSX AVS_OFFICESTUDIO_FILE_DRAW + 0x0002 +#define AVS_OFFICESTUDIO_FILE_DRAW_VSTX AVS_OFFICESTUDIO_FILE_DRAW + 0x0003 +#define AVS_OFFICESTUDIO_FILE_DRAW_VSDM AVS_OFFICESTUDIO_FILE_DRAW + 0x0004 +#define AVS_OFFICESTUDIO_FILE_DRAW_VSSM AVS_OFFICESTUDIO_FILE_DRAW + 0x0005 +#define AVS_OFFICESTUDIO_FILE_DRAW_VSTM AVS_OFFICESTUDIO_FILE_DRAW + 0x0006 diff --git a/Common/base.pri b/Common/base.pri index 9a528b063b3..e8dc81b132e 100644 --- a/Common/base.pri +++ b/Common/base.pri @@ -19,6 +19,11 @@ isEmpty(PUBLISHER_NAME){ PUBLISHER_NAME = $$cat(copyright.txt) } +DEST_MAKEFILE_NAME = $$(DEST_MAKEFILE_NAME) +!isEmpty(DEST_MAKEFILE_NAME){ + MAKEFILE = $${DEST_MAKEFILE_NAME} +} + APPLICATION_NAME_DEFAULT = $$(APPLICATION_NAME_DEFAULT) !isEmpty(APPLICATION_NAME_DEFAULT){ DEFINES += "APPLICATION_NAME_DEFAULT=$${APPLICATION_NAME_DEFAULT}" @@ -143,7 +148,7 @@ mac { CONFIG += core_mac CONFIG += core_mac_64 - DEFINES += _LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION + DEFINES += _LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION } } @@ -180,7 +185,7 @@ core_mac { QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.11 QMAKE_LFLAGS += -isysroot $$QMAKE_MAC_SDK_PATH - # xcode15 add new linker + # xcode15 add new linker QMAKE_LFLAGS += -Wl,-ld_classic QMAKE_CFLAGS += "-Wno-implicit-function-declaration" @@ -229,6 +234,14 @@ core_linux { QMAKE_LFLAGS += "-Wl,-rpath,\'\$$ORIGIN\'" QMAKE_LFLAGS += "-Wl,-rpath,\'\$$ORIGIN/system\'" QMAKE_LFLAGS += -Wl,--disable-new-dtags + + !disable_rpath_addon { + RUN_PATH_ADDON = $$(RUN_PATH_ADDON) + !isEmpty(RUN_PATH_ADDON){ + RUN_PATH_ADDON_ARRAY = $$split(RUN_PATH_ADDON, ";;") + for(rpath_item, RUN_PATH_ADDON_ARRAY):QMAKE_LFLAGS += "-Wl,-rpath,\'$$rpath_item\'" + } + } } } @@ -288,16 +301,26 @@ linux_arm64 { core_ios { CORE_BUILDS_PLATFORM_PREFIX = ios + !versionAtLeast(QMAKE_XCODE_VERSION, 16.0) { + QMAKE_CFLAGS += -fembed-bitcode + QMAKE_CXXFLAGS += -fembed-bitcode + QMAKE_LFLAGS += -fembed-bitcode + } else { + CONFIG -= bitcode + } + + CONFIG(iphonesimulator, iphoneos|iphonesimulator): { message("iphonesimulator") CORE_BUILDS_PLATFORM_PREFIX = ios_simulator + + QMAKE_CFLAGS += -fobjc-arc + QMAKE_CXXFLAGS += -fobjc-arc } else { QMAKE_IOS_DEPLOYMENT_TARGET = 11.0 - QMAKE_CFLAGS += -fembed-bitcode - QMAKE_CXXFLAGS += -fembed-bitcode - QMAKE_LFLAGS += -fembed-bitcode + QMAKE_CFLAGS += -fobjc-arc QMAKE_CXXFLAGS += -fobjc-arc bundle_xcframeworks { @@ -358,6 +381,7 @@ core_android { CORE_BUILDS_PLATFORM_PREFIX = $$replace(CORE_BUILDS_PLATFORM_PREFIX, "-", "_") CORE_BUILDS_PLATFORM_PREFIX = $$replace(CORE_BUILDS_PLATFORM_PREFIX, "armeabi_v7", "armv7") CORE_BUILDS_PLATFORM_PREFIX = $$replace(CORE_BUILDS_PLATFORM_PREFIX, "armv7a", "armv7") + CORE_BUILDS_PLATFORM_PREFIX_DST = $$replace(CORE_BUILDS_PLATFORM_PREFIX, "android_", "") !isEmpty(OO_DESTDIR_BUILD_OVERRIDE) { isEqual(CORE_BUILDS_PLATFORM_PREFIX, android_arm64_v8a):OO_DESTDIR_BUILD_OVERRIDE=$$OO_DESTDIR_BUILD_OVERRIDE/arm64-v8a @@ -552,7 +576,7 @@ defineTest(ADD_DEPENDENCY) { libs = $$ARGS for(lib, libs) { CORE_BUILDS_LIBRARIES_PATH_DST=$$CORE_BUILDS_LIBRARIES_PATH - + isEqual(lib, videoplayer) { libvlc { CORE_BUILDS_LIBRARIES_PATH_DST=$$CORE_BUILDS_LIBRARIES_PATH/mediaplayer @@ -565,7 +589,7 @@ defineTest(ADD_DEPENDENCY) { isEqual(lib, qtascdocumentscore):CORE_BUILDS_LIBRARIES_PATH_DST=$$CORE_BUILDS_LIBRARIES_PATH_DST/xp isEqual(lib, videoplayer):CORE_BUILDS_LIBRARIES_PATH_DST=$$CORE_BUILDS_LIBRARIES_PATH_DST/xp isEqual(lib, ooxmlsignature):CORE_BUILDS_LIBRARIES_PATH_DST=$$CORE_BUILDS_LIBRARIES_PATH_DST/xp - } + } !bundle_dylibs:LIBS += -L$$CORE_BUILDS_LIBRARIES_PATH_DST -l$$lib bundle_dylibs:LIBS += -F$$CORE_BUILDS_LIBRARIES_PATH_DST -framework $$lib } diff --git a/Common/js/desktop_fetch.js b/Common/js/desktop_fetch.js index 0ba9f62aeb0..e5f20e587a5 100644 --- a/Common/js/desktop_fetch.js +++ b/Common/js/desktop_fetch.js @@ -45,5 +45,5 @@ if (internal_isLocal()) } else { - getBinaryPromise = function() { return getBinaryPromise2(); } + getBinaryPromise = function() { return getBinaryPromise2.apply(undefined, arguments); } } diff --git a/Common/js/logging.h b/Common/js/logging.h new file mode 100644 index 00000000000..101db30593c --- /dev/null +++ b/Common/js/logging.h @@ -0,0 +1,57 @@ +#ifndef _LOG_FILE_H +#define _LOG_FILE_H + +#include <stdio.h> +#define LOG_BUFFER_SIZE 1000 + +// not intended for use in production. only for testing/debugging purposes +namespace Logging +{ +void logBytes(char* name, unsigned char* str, int len) +{ + char buffer[LOG_BUFFER_SIZE]; + char* name_cur = name; + char* buf_cur = buffer; + + while (*name_cur != 0) + { + *buf_cur++ = *name_cur++; + } + + *buf_cur++ = ':'; + *buf_cur++ = ' '; + *buf_cur++ = '['; + + for (int i = 0; i < len; ++i) + { + unsigned char c = str[i]; + + unsigned char n1 = (unsigned char)(c / 100); + c -= (n1 * 100); + + unsigned char n2 = (unsigned char)(c / 10); + c -= (n2 * 10); + + if (buf_cur - buffer + 4 >= LOG_BUFFER_SIZE) + { + *buf_cur++ = '\0'; + printf("%s\n", buffer); + + buf_cur = buffer; + } + + *buf_cur++ = (char)('0' + n1); + *buf_cur++ = (char)('0' + n2); + *buf_cur++ = (char)('0' + c); + *buf_cur++ = ','; + } + + buf_cur--; + *buf_cur++ = ']'; + *buf_cur++ = '\0'; + + printf("%s\n", buffer); +} +} + +#endif // _LOG_FILE_H diff --git a/Common/js/make.py b/Common/js/make.py index 62a8f9c7674..00b52649426 100644 --- a/Common/js/make.py +++ b/Common/js/make.py @@ -15,6 +15,7 @@ if not base.is_dir("emsdk"): base.cmd("git", ["clone", "https://github.com/emscripten-core/emsdk.git"]) os.chdir("emsdk") + base.cmd("git", ["checkout", "f677ef915645c09794f0ae88f21d3cba2886459f"]) base.cmd(command_prefix + "emsdk", ["install", "latest"]) base.cmd(command_prefix + "emsdk", ["activate", "latest"]) os.chdir("../") @@ -32,7 +33,13 @@ def exec_wasm(data, work, compiler_flags, wasm): compiler_flags.append("-DBUILDING_ASMJS_MODULE") compiler_flags.append("-D_ARM_ALIGN_") + compiler_flags.append("-Wno-deprecated-non-prototype") compiler_flags.append("-Wno-deprecated-register") + compiler_flags.append("-Wno-register") + + compiler_flags.append("-fvisibility=hidden") + #compiler_flags.append("-Wl,--no-entry") + #compiler_flags.append("-Wl,--strip-all") # arguments arguments = "" @@ -106,6 +113,11 @@ def exec_wasm(data, work, compiler_flags, wasm): if not wasm: engine_js_content = engine_js_content.replace("//polyfill", polyfill_js_content) + if "replaces" in data: + for item in data["replaces"]: + replace_file_content = base.readFile(data["replaces"][item]) + engine_js_content = engine_js_content.replace("//" + item, replace_file_content) + # write new version base.writeFile(data["res_folder"] + "/" + data["name"] + ("" if wasm else "_ie") + ".js", engine_js_content) base.copy_file("./" + data["name"] + (".wasm" if wasm else ".js.mem"), data["res_folder"] + "/" + data["name"] + (".wasm" if wasm else ".js.mem")) @@ -146,7 +158,10 @@ def exec_wasm(data, work, compiler_flags, wasm): if json_data["asm"]: flags = json_data["compiler_flags"][:] flags.append("-s WASM=0") + flags.append("--closure 0") flags.append("-s MIN_IE_VERSION=11") + # do it in min.py + #flags.append("--closure-args=--language_out=ECMASCRIPT5_STRICT") if "embed_mem_file" in json_data and (json_data["embed_mem_file"]): flags.append("--memory-init-file 0") exec_wasm(json_data, work_dir, flags, False) diff --git a/Common/js/min.py b/Common/js/min.py index df936dd7aa2..39fb4f5bd8b 100644 --- a/Common/js/min.py +++ b/Common/js/min.py @@ -17,6 +17,7 @@ base.cmd("java", ["-jar", "../../../sdkjs/build/node_modules/google-closure-compiler-java/compiler.jar", "--compilation_level", compilation_level, + "--language_out", "ECMASCRIPT5_STRICT", "--js_output_file", file_path_min, "--js", file_path]) diff --git a/Common/js/polyfill.js b/Common/js/polyfill.js index 4cae43c5b90..0a0b99904b4 100644 --- a/Common/js/polyfill.js +++ b/Common/js/polyfill.js @@ -30,8 +30,8 @@ Math.imul = Math.imul || function(a, b) { var al = a & 0xffff; var bh = (b >>> 16) & 0xffff; var bl = b & 0xffff; - // сдвиг на 0 бит закрепляет знак в старшей части числа - // окончательный |0 преобразует беззнаковое значение обратно в знаковое значение + // shift by 0 bits fixes the sign in the high part of the number + // final |0 converts the unsigned value back to a signed value return ((al * bl) + (((ah * bl + al * bh) << 16) >>> 0)|0); }; diff --git a/Common/kernel.pro b/Common/kernel.pro index d935cffa869..6eb4e3cdccd 100644 --- a/Common/kernel.pro +++ b/Common/kernel.pro @@ -30,25 +30,27 @@ HEADERS += ./kernel_config.h # BLOCKER HEADERS += \ - ./../DesktopEditor/graphics/TemporaryCS.h + ./../DesktopEditor/graphics/TemporaryCS.h SOURCES += \ - ./../DesktopEditor/graphics/TemporaryCS.cpp + ./../DesktopEditor/graphics/TemporaryCS.cpp # THREAD core_android:DEFINES += NOT_USE_PTHREAD_CANCEL USE_FILE32API HEADERS += \ - ./../DesktopEditor/graphics/BaseThread.h + ./../DesktopEditor/graphics/BaseThread.h \ + ./../DesktopEditor/graphics/BaseThreadMonitor.h SOURCES += \ - ./../DesktopEditor/graphics/BaseThread.cpp + ./../DesktopEditor/graphics/BaseThread.cpp \ + ./../DesktopEditor/graphics/BaseThreadMonitor.cpp # TIMER HEADERS += \ - ./../DesktopEditor/graphics/Timer.h + ./../DesktopEditor/graphics/Timer.h SOURCES += \ - ./../DesktopEditor/graphics/Timer.cpp + ./../DesktopEditor/graphics/Timer.cpp # PATH HEADERS += ./../DesktopEditor/common/Path.h @@ -92,11 +94,11 @@ HEADERS += ./../DesktopEditor/common/ProcessEnv.h SOURCES += ./../DesktopEditor/common/ProcessEnv.cpp core_windows { - LIBS += -lRpcrt4 - LIBS += -lShell32 + LIBS += -lRpcrt4 + LIBS += -lShell32 } core_ios { - OBJECTIVE_SOURCES += ./../DesktopEditor/common/File_ios.mm - LIBS += -framework Foundation + OBJECTIVE_SOURCES += ./../DesktopEditor/common/File_ios.mm + LIBS += -framework Foundation } diff --git a/DesktopEditor/AllFontsGen/main.cpp b/DesktopEditor/AllFontsGen/main.cpp index a33bc9a38e9..bfa7b8c2dca 100644 --- a/DesktopEditor/AllFontsGen/main.cpp +++ b/DesktopEditor/AllFontsGen/main.cpp @@ -32,10 +32,10 @@ #include <iostream> #include <set> -#include "../fontengine/ApplicationFontsWorker.h" #include "../common/Directory.h" +#include "../fontengine/ApplicationFontsWorker.h" -//#define _GENERATE_FONT_MAP_ +// #define _GENERATE_FONT_MAP_ #ifdef _GENERATE_FONT_MAP_ #include "../freetype_names/FontMaps/FontDictionary.h" @@ -43,37 +43,37 @@ std::wstring CorrectDir(const std::wstring& sDir) { - if (sDir.empty()) - return L""; + if (sDir.empty()) + return L""; - const wchar_t* data = sDir.c_str(); + const wchar_t* data = sDir.c_str(); - std::wstring::size_type pos1 = (data[0] == '\"') ? 1 : 0; - std::wstring::size_type pos2 = sDir.length(); + std::wstring::size_type pos1 = (data[0] == '\"') ? 1 : 0; + std::wstring::size_type pos2 = sDir.length(); - if (data[pos2 - 1] == '\"') - --pos2; + if (data[pos2 - 1] == '\"') + --pos2; - if (pos2 > 0 && ((data[pos2 - 1] == '\\') || (data[pos2 - 1] == '/'))) - --pos2; + if (pos2 > 0 && ((data[pos2 - 1] == '\\') || (data[pos2 - 1] == '/'))) + --pos2; - return sDir.substr(pos1, pos2 - pos1); + return sDir.substr(pos1, pos2 - pos1); } std::wstring CorrectValue(const std::wstring& value) { - if (value.empty()) - return L""; + if (value.empty()) + return L""; - const wchar_t* data = value.c_str(); + const wchar_t* data = value.c_str(); - std::wstring::size_type pos1 = (data[0] == '\"') ? 1 : 0; - std::wstring::size_type pos2 = value.length(); + std::wstring::size_type pos1 = (data[0] == '\"') ? 1 : 0; + std::wstring::size_type pos2 = value.length(); - if (data[pos2 - 1] == '\"') - --pos2; + if (data[pos2 - 1] == '\"') + --pos2; - return value.substr(pos1, pos2 - pos1); + return value.substr(pos1, pos2 - pos1); } #ifdef WIN32 @@ -82,149 +82,157 @@ int wmain(int argc, wchar_t** argv) int main(int argc, char** argv) #endif { - std::vector<std::wstring> arFontsDirs; - bool bIsUseSystemFonts = false; - std::wstring strAllFontsWebPath = L""; - std::wstring strAllFontsPath = L""; - std::wstring strThumbnailsFolder = L""; - std::wstring strFontsSelectionBin = L""; - std::wstring strOutputDir = L""; - int nFontFlag = 3; - - for (int i = 0; i < argc; ++i) - { + std::vector<std::wstring> arFontsDirs; + bool bIsUseSystemFonts = false; + bool bIsUseSystemUserFonts = true; + std::wstring strAllFontsWebPath = L""; + std::wstring strAllFontsPath = L""; + std::wstring strThumbnailsFolder = L""; + std::wstring strFontsSelectionBin = L""; + std::wstring strOutputDir = L""; + int nFontFlag = 3; + + for (int i = 0; i < argc; ++i) + { #ifdef WIN32 - std::wstring sParam(argv[i]); + std::wstring sParam(argv[i]); #else - std::string sParamA(argv[i]); - std::wstring sParam = UTF8_TO_U(sParamA); + 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"--use-system") - { - sValue = CorrectValue(sValue); - if (sValue == L"1" || sValue == L"true") - bIsUseSystemFonts = true; - } - else if (sKey == L"--allfonts-web") - { - strAllFontsWebPath = CorrectDir(sValue); - } - else if (sKey == L"--allfonts") - { - strAllFontsPath = CorrectDir(sValue); - } - else if (sKey == L"--images") - { - strThumbnailsFolder = CorrectDir(sValue); - } - else if (sKey == L"--selection") - { - strFontsSelectionBin = CorrectDir(sValue); - } - else if (sKey == L"--input") - { - 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(CorrectDir(std::wstring(srcPrev, src - srcPrev))); - } - src++; - srcPrev = src; - } - else - src++; - } - - if (src > srcPrev) - { - arFontsDirs.push_back(CorrectDir(std::wstring(srcPrev, src - srcPrev))); - } - } - else if (sKey == L"--output-web") - { - strOutputDir = CorrectDir(sValue); - } - else if (sKey == L"--font-format") - { - // first byte => isSupportCFF - // second byte => isUnsupport DFont (mac) - - int nFlag = std::stoi(sValue); - if (nFlag > 0) - nFontFlag = nFlag; - } - } - } - - /* - --input="./fontsInput" --allfonts="./fonts/AllFonts.js" --allfonts-web="./fonts/AllFonts2.js" --images="./fonts" --selection="./fonts/font_selection.bin" --output-web="./fonts" --use-system="false" - */ - - CApplicationFontsWorker oWorker; - // это не рабочая папка, где только шрифты - oWorker.m_bIsCleanDirectory = false; - oWorker.m_bIsRemoveOldThumbnails = true; - - // input fonts - oWorker.m_bIsUseSystemFonts = bIsUseSystemFonts; - oWorker.m_arAdditionalFolders = arFontsDirs; - - // font_selection.bin - // fonts.log - oWorker.m_sDirectory = NSFile::GetDirectoryName(strFontsSelectionBin); - - // thumbnails - oWorker.m_sThumbnailsDirectory = strThumbnailsFolder; - oWorker.m_bIsNeedThumbnails = !oWorker.m_sThumbnailsDirectory.empty(); - oWorker.m_bSeparateThumbnails = true; - - // allfonts - oWorker.m_sAllFontsJSPath = strAllFontsPath; - oWorker.m_sWebAllFontsJSPath = strAllFontsWebPath; - - // webfonts - oWorker.m_sWebFontsDirectory = strOutputDir; - - // opentype - oWorker.m_bIsUseOpenType = (0x01 == (0x01 & nFontFlag)); - - NSFonts::IApplicationFonts* pApplicationFonts = oWorker.Check(); - if (oWorker.m_bIsNeedThumbnails) - oWorker.CheckThumbnails(); - - RELEASEINTERFACE(pApplicationFonts); - + 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"--use-system") + { + sValue = CorrectValue(sValue); + if (sValue == L"1" || sValue == L"true") + bIsUseSystemFonts = true; + } + else if (sKey == L"--use-system-user-fonts") + { + sValue = CorrectValue(sValue); + if (sValue == L"0" || sValue == L"false") + bIsUseSystemUserFonts = false; + } + else if (sKey == L"--allfonts-web") + { + strAllFontsWebPath = CorrectDir(sValue); + } + else if (sKey == L"--allfonts") + { + strAllFontsPath = CorrectDir(sValue); + } + else if (sKey == L"--images") + { + strThumbnailsFolder = CorrectDir(sValue); + } + else if (sKey == L"--selection") + { + strFontsSelectionBin = CorrectDir(sValue); + } + else if (sKey == L"--input") + { + 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(CorrectDir(std::wstring(srcPrev, src - srcPrev))); + } + src++; + srcPrev = src; + } + else + src++; + } + + if (src > srcPrev) + { + arFontsDirs.push_back(CorrectDir(std::wstring(srcPrev, src - srcPrev))); + } + } + else if (sKey == L"--output-web") + { + strOutputDir = CorrectDir(sValue); + } + else if (sKey == L"--font-format") + { + // first byte => isSupportCFF + // second byte => isUnsupport DFont (mac) + + int nFlag = std::stoi(sValue); + if (nFlag > 0) + nFontFlag = nFlag; + } + } + } + + /* + --input="./fontsInput" --allfonts="./fonts/AllFonts.js" --allfonts-web="./fonts/AllFonts2.js" --images="./fonts" --selection="./fonts/font_selection.bin" --output-web="./fonts" + --use-system="false" + */ + + CApplicationFontsWorker oWorker; + // это не рабочая папка, где только шрифты + oWorker.m_bIsCleanDirectory = false; + oWorker.m_bIsRemoveOldThumbnails = true; + + // input fonts + oWorker.m_bIsUseSystemFonts = bIsUseSystemFonts; + if (bIsUseSystemFonts) + oWorker.m_bIsUseSystemUserFonts = bIsUseSystemUserFonts; + oWorker.m_arAdditionalFolders = arFontsDirs; + + // font_selection.bin + // fonts.log + oWorker.m_sDirectory = NSFile::GetDirectoryName(strFontsSelectionBin); + + // thumbnails + oWorker.m_sThumbnailsDirectory = strThumbnailsFolder; + oWorker.m_bIsNeedThumbnails = !oWorker.m_sThumbnailsDirectory.empty(); + oWorker.m_bSeparateThumbnails = true; + + // allfonts + oWorker.m_sAllFontsJSPath = strAllFontsPath; + oWorker.m_sWebAllFontsJSPath = strAllFontsWebPath; + + // webfonts + oWorker.m_sWebFontsDirectory = strOutputDir; + + // opentype + oWorker.m_bIsUseOpenType = (0x01 == (0x01 & nFontFlag)); + + NSFonts::IApplicationFonts* pApplicationFonts = oWorker.Check(); + if (oWorker.m_bIsNeedThumbnails) + oWorker.CheckThumbnails(); + + RELEASEINTERFACE(pApplicationFonts); #ifdef _GENERATE_FONT_MAP_ - NSCommon::DumpFontsDictionary(L"./fonts_dictionary.txt"); + NSCommon::DumpFontsDictionary(L"./fonts_dictionary.txt"); #endif - return 0; + return 0; } - diff --git a/DesktopEditor/agg-2.4/include/agg_alpha_mask_u8.h b/DesktopEditor/agg-2.4/include/agg_alpha_mask_u8.h index f7dd369fae7..78148e221ed 100644 --- a/DesktopEditor/agg-2.4/include/agg_alpha_mask_u8.h +++ b/DesktopEditor/agg-2.4/include/agg_alpha_mask_u8.h @@ -30,7 +30,7 @@ namespace agg { static unsigned calculate(const int8u* p) { return *p; } }; - + //=====================================================rgb_to_gray_mask_u8 template<unsigned R, unsigned G, unsigned B> diff --git a/DesktopEditor/agg-2.4/include/test_grads/custom_gradients.h b/DesktopEditor/agg-2.4/include/test_grads/custom_gradients.h index f532a314646..46314feb5c4 100644 --- a/DesktopEditor/agg-2.4/include/test_grads/custom_gradients.h +++ b/DesktopEditor/agg-2.4/include/test_grads/custom_gradients.h @@ -847,40 +847,10 @@ namespace agg if (calculate_tensor_coefs) calculate_tensor(); - float minxres = m_oGradientInfo.shading.patch[0][0].x; - float minyres = m_oGradientInfo.shading.patch[0][0].y; - float maxxres = m_oGradientInfo.shading.patch[0][0].x; - float maxyres = m_oGradientInfo.shading.patch[0][0].y; - for (int i = 0; i < 4; i++) - { - for (int j = 0; j < 4; j++) - { - if (m_oGradientInfo.shading.patch[i][j].x > maxxres) - { - maxxres = m_oGradientInfo.shading.patch[i][j].x; - } - if (m_oGradientInfo.shading.patch[i][j].y > maxyres) - { - maxyres = m_oGradientInfo.shading.patch[i][j].y; - } - if (m_oGradientInfo.shading.patch[i][j].x < minxres) - { - minxres = m_oGradientInfo.shading.patch[i][j].x; - } - if (m_oGradientInfo.shading.patch[i][j].y < minyres) - { - minyres = m_oGradientInfo.shading.patch[i][j].y; - } - } - } - - RES = std::max(1.0f, std::max(maxxres - minxres, maxyres - minyres) / 3); - float delta = 1.0 / RES; float u = 0, v = 0; auto start_p = get_p_curve(u, v); xmax_curve = xmin_curve = start_p.x; ymax_curve = ymin_curve = start_p.y; - precalc = std::vector<std::vector<ColorT>>(RES, std::vector<ColorT>(RES, {0, 0, 0, 0})); /* * Небольшая оптимизация основанная на том, что данная фигура не выходит за границы своих опорных точек. @@ -918,7 +888,7 @@ namespace agg RES = nRES; } precalc = std::vector<std::vector<ColorT>>(RES, std::vector<ColorT>(RES, {0, 0, 0, 0})); - delta = 1.0f / RES; + float delta = 1.0f / RES; std::vector<std::pair<int, int>> next_indexes(RES + 1); u = 0; for (int i = 0; i < RES; ++i) @@ -956,8 +926,6 @@ namespace agg } ColorT ifswapRGB(const ColorT &c) { - - if (m_bSwapRGB) { return c; } diff --git a/DesktopEditor/allthemesgen/allthemesgen.pro b/DesktopEditor/allthemesgen/allthemesgen.pro index 7746933ab20..8455c0259c8 100644 --- a/DesktopEditor/allthemesgen/allthemesgen.pro +++ b/DesktopEditor/allthemesgen/allthemesgen.pro @@ -15,7 +15,7 @@ TARGET = allthemesgen DEFINES += KERNEL_USE_DYNAMIC_LIBRARY DEFINES += GRAPHICS_USE_DYNAMIC_LIBRARY -ADD_DEPENDENCY(graphics, kernel, kernel_network, UnicodeConverter, doctrenderer) +ADD_DEPENDENCY(graphics, kernel, kernel_network, UnicodeConverter, doctrenderer, PdfFile, XpsFile, DjVuFile, DocxRenderer) core_windows { DEFINES -= UNICODE diff --git a/DesktopEditor/common/Base64.cpp b/DesktopEditor/common/Base64.cpp index 5b7080b70e5..95003a02160 100644 --- a/DesktopEditor/common/Base64.cpp +++ b/DesktopEditor/common/Base64.cpp @@ -250,3 +250,123 @@ namespace NSBase64 return Base64DecodeBase(szSrc, nSrcLen, pbDest, pnDestLen); } } + +#include <cstring> +namespace NSBase32 +{ + const unsigned char PADDING_CHAR_32 = '='; + + inline void pad(unsigned char* buf, int len) + { + for (int i = 0; i < len; i++) + buf[i] = PADDING_CHAR_32; + } + inline unsigned char shift_right(unsigned char byte, signed char offset) + { + if (offset > 0) + return byte >> offset; + else + return byte << -offset; + } + inline unsigned char shift_left(unsigned char byte, signed char offset) + { + return shift_right(byte, - offset); + } + + unsigned char encode_char(unsigned char c) + { + static unsigned char base32[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"; + return base32[c & 0x1F]; + } + + int decode_char(unsigned char c) + { + char retval = -2; + + if (c >= 'A' && c <= 'Z') + retval = c - 'A'; + else if (c >= '2' && c <= '7') + retval = c - '2' + 26; + else if (c == PADDING_CHAR_32) + retval = -1; + + return retval; + } + + int decode_sequence(const unsigned char* coded, unsigned char* plain) + { + plain[0] = 0; + for (int block = 0; block < 8; block++) + { + int offset = (8 - 5 - (5*block) % 8); + int octet = (block*5) / 8; + + int c = decode_char(coded[block]); + if (c < 0) + return c; + + plain[octet] |= shift_left(c, offset); + if (offset < 0) + { // does this block overflows to next octet? + plain[octet+1] = shift_left(c, 8 + offset); + } + } + return 5; + } + + bool Decode(unsigned char* in, int inLen, unsigned char* out) + { + for (size_t i = 0, j = 0; (i + 8) <= inLen; i += 8, j += 5) + { + int n = decode_sequence(&in[i], &out[j]); + if (n == -2) + return false; + if (n < 5) + break; + } + return true; + } + + void encode_sequence(const unsigned char* plain, int len, unsigned char* coded) + { + for (int block = 0; block < 8; block++) + { + int octet = (block*5) / 8; + int junk = (8 - 5 - (5*block) % 8); + + if (octet >= len) + { + pad(&coded[block], 8 - block); + return; + } + + unsigned char c = shift_right(plain[octet], junk); // first part + + if (junk < 0 // is there a second part? + && octet < len - 1) // is there still something to read? + { + c |= shift_right(plain[octet+1], 8 + junk); + } + coded[block] = encode_char(c); + } + } + + bool Encode(unsigned char* src, int len, unsigned char* dst) + { + for (int i = 0, j = 0; i < len; i += 5, j += 8) + { + int tmpLen = len - i; + encode_sequence(&src[i], tmpLen > 5 ? 5 : tmpLen, &dst[j]); + } + return true; + } + + int DecodeGetRequiredLength(int bytes) + { + return (((bytes)/8)*5); + } + int EncodeGetRequiredLength(int bytes) + { + return (((bytes)/5)*8 + ((bytes) % 5 ? 8 : 0)); + } +} diff --git a/DesktopEditor/common/Base64.h b/DesktopEditor/common/Base64.h index 4f49f5ef45a..f03e0cde180 100644 --- a/DesktopEditor/common/Base64.h +++ b/DesktopEditor/common/Base64.h @@ -58,4 +58,13 @@ namespace NSBase64 KERNEL_DECL int Base64Decode(const wchar_t* szSrc, int nSrcLen, BYTE *pbDest, int *pnDestLen); } +namespace NSBase32 +{ + KERNEL_DECL bool Decode(unsigned char* in, int inLen, unsigned char* out); + KERNEL_DECL bool Encode(unsigned char* in, int inLen, unsigned char* out); + + KERNEL_DECL int DecodeGetRequiredLength(int bytes); + KERNEL_DECL int EncodeGetRequiredLength(int bytes); +} + #endif//_BUILD_BASE64_CROSSPLATFORM_DEFINE diff --git a/DesktopEditor/common/CalculatorCRC32.h b/DesktopEditor/common/CalculatorCRC32.h index 4c22530107b..0d003e2d888 100644 --- a/DesktopEditor/common/CalculatorCRC32.h +++ b/DesktopEditor/common/CalculatorCRC32.h @@ -34,24 +34,25 @@ #include <string> -const int g_clFilePartSize = 20*1024; +const int g_clFilePartSize = 20 * 1024; class CCalculatorCRC32 -{ +{ public: CCalculatorCRC32() { - m_dwMagicWord = 0xEDB88320; - m_dwInitCrc = 0xFFFFFFFF; - m_bInitTable = false; + m_dwMagicWord = 0xEDB88320; + m_dwInitCrc = 0xFFFFFFFF; + m_bInitTable = false; } + public: unsigned int Calc(const unsigned char* pStream, unsigned int nSize) { InitCRCTable(); - unsigned int dwRes = m_dwInitCrc; - for (unsigned int i=0;i<nSize;i++) + unsigned int dwRes = m_dwInitCrc; + for (unsigned int i = 0; i < nSize; i++) { - dwRes = m_arCRCTable[(dwRes ^ pStream[i])& 0xFF] ^ (dwRes >> 8); + dwRes = m_arCRCTable[(dwRes ^ pStream[i]) & 0xFF] ^ (dwRes >> 8); } dwRes = dwRes ^ 0xFFFFFFFF; @@ -64,13 +65,13 @@ class CCalculatorCRC32 if (m_bInitTable) return; - unsigned int dwTemp; - for (int i=0;i<256;i++) + unsigned int dwTemp; + for (int i = 0; i < 256; i++) { dwTemp = i; - for (int j=0;j<8;j++) + for (int j = 0; j < 8; j++) { - if (0x1==(dwTemp & 0x1)) + if (0x1 == (dwTemp & 0x1)) dwTemp = (dwTemp >> 1) ^ m_dwMagicWord; else dwTemp = dwTemp >> 1; @@ -80,10 +81,10 @@ class CCalculatorCRC32 m_bInitTable = true; } - unsigned int m_dwMagicWord; - unsigned int m_dwInitCrc; - unsigned int m_arCRCTable[255]; - bool m_bInitTable; + unsigned int m_dwMagicWord; + unsigned int m_dwInitCrc; + unsigned int m_arCRCTable[255]; + bool m_bInitTable; }; #endif // _ASC_COMMON_CALCULATOR_CRC32_ diff --git a/DesktopEditor/common/Directory.cpp b/DesktopEditor/common/Directory.cpp index 298031f4b2e..ad4d9f8bbe4 100644 --- a/DesktopEditor/common/Directory.cpp +++ b/DesktopEditor/common/Directory.cpp @@ -60,6 +60,10 @@ namespace NSDirectory #if !defined(_WIN32) && !defined (_WIN64) static bool is_directory_exist(char* dir) { +#ifdef __ANDROID__ + if (0 == strcmp("/storage/emulated", dir)) + return true; +#endif struct stat st; bool bRes = (0 == stat(dir, &st)) && S_ISDIR(st.st_mode); return bRes; @@ -515,17 +519,26 @@ namespace NSDirectory } std::wstring GetFolderPath(const std::wstring& wsFolderPath) { - int n1 = (int)wsFolderPath.rfind('\\'); - if (n1 < 0) - { - n1 = (int)wsFolderPath.rfind('/'); - if (n1 < 0) - { - return L""; - } - return wsFolderPath.substr(0, n1); - } - return wsFolderPath.substr(0, n1); +#ifdef _WIN32 + std::wstring::size_type nPos1 = wsFolderPath.rfind('\\'); +#else + std::wstring::size_type nPos1 = std::wstring::npos; +#endif + std::wstring::size_type nPos2 = wsFolderPath.rfind('/'); + std::wstring::size_type nPos = std::wstring::npos; + + if (nPos1 != std::wstring::npos) + { + nPos = nPos1; + if (nPos2 != std::wstring::npos && nPos2 > nPos) + nPos = nPos2; + } + else + nPos = nPos2; + + if (nPos == std::wstring::npos) + return wsFolderPath; + return wsFolderPath.substr(0, nPos); } std::wstring CreateTempFileWithUniqueName (const std::wstring & strFolderPathRoot, std::wstring Prefix) { @@ -577,11 +590,7 @@ namespace NSDirectory int GetFilesCount(const std::wstring& path, const bool& recursive) { std::vector<std::wstring> arrFiles = NSDirectory::GetFiles(path, recursive); -#if defined(_WIN32) || defined (_WIN64) return (int)arrFiles.size(); -#endif - return (int)arrFiles.size() + 1; - // ??? } bool PathIsDirectory(const std::wstring& pathName) { diff --git a/DesktopEditor/common/File.cpp b/DesktopEditor/common/File.cpp index b0a4415998a..e836df13439 100644 --- a/DesktopEditor/common/File.cpp +++ b/DesktopEditor/common/File.cpp @@ -43,12 +43,20 @@ #include <unistd.h> #include <string.h> #include <sys/stat.h> +#include <sys/time.h> +#include <utime.h> #endif #ifdef _MAC #include <mach-o/dyld.h> #endif +#if defined(__APPLE__) || defined(__NetBSD__) +#define st_atim st_atimespec +#define st_ctim st_ctimespec +#define st_mtim st_mtimespec +#endif + #ifndef MAX_PATH #define MAX_PATH 1024 #endif @@ -256,7 +264,7 @@ namespace NSFile } pUnicodeString[lIndexUnicode++] = (WCHAR)(val); - lIndex += 5; + lIndex += 6; } } @@ -986,14 +994,16 @@ namespace NSFile } long CFileBinary::GetFilePosition() { - m_lFilePosition = ftell(m_pFile); - + if (!m_pFile) return 0; + + m_lFilePosition = ftell(m_pFile); return m_lFilePosition; } unsigned long CFileBinary::GetPosition() { - m_lFilePosition = ftell(m_pFile); + if (!m_pFile) return 0; + m_lFilePosition = ftell(m_pFile); return (unsigned long)m_lFilePosition; } @@ -1525,6 +1535,11 @@ namespace NSFile return bIsSuccess; } + bool CFileBinary::IsGlobalTempPathUse() + { + return g_overrideTmpPath.empty() ? false : true; + } + std::wstring CFileBinary::GetTempPath() { if (!g_overrideTmpPath.empty()) @@ -1688,38 +1703,161 @@ namespace NSFile g_overrideTmpPath = strTempPath; } - unsigned long CFileBinary::GetDateTime(const std::wstring & inputFile) + bool CFileBinary::GetTime(const std::wstring& sFilename, struct tm* ptmLastWrite, struct tm* ptmLastAccess) { - unsigned long result = 0; -#if defined(_WIN32) || defined (_WIN64) + bool result = true; + + if (ptmLastWrite) memset(ptmLastWrite, 0, sizeof(struct tm)); + if (ptmLastAccess) memset(ptmLastAccess, 0, sizeof(struct tm)); + +#if defined(_WIN32) || defined (_WIN64) // windows + HANDLE hFile; - hFile = ::CreateFileW(inputFile.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + hFile = ::CreateFileW(sFilename.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile) { - FILETIME ft; ft.dwLowDateTime = ft.dwHighDateTime = 0; - if (GetFileTime(hFile, NULL, NULL, &ft)) + FILETIME ftLastWrite{}, ftLastAccess{}; + if (::GetFileTime(hFile, NULL, &ftLastAccess, &ftLastWrite)) { - WORD fatDate = 0, fatTime = 0; - if (FileTimeToDosDateTime(&ft, &fatDate, &fatTime)) + FILETIME ftLastWriteLocal{}, ftLastAccessLocal{}; + result = result && ::FileTimeToLocalFileTime(&ftLastWrite, &ftLastWriteLocal); + result = result && ::FileTimeToLocalFileTime(&ftLastAccess, &ftLastAccessLocal); + + SYSTEMTIME stLastWrite{}, stLastAccess{}; + result = result && ::FileTimeToSystemTime(&ftLastWriteLocal, &stLastWrite); + result = result && ::FileTimeToSystemTime(&ftLastAccessLocal, &stLastAccess); + + auto set_tm_by_st = [] (struct tm* time_tm, SYSTEMTIME* time_st) { + time_tm->tm_sec = static_cast<int>(time_st->wSecond); + time_tm->tm_min = static_cast<int>(time_st->wMinute); + time_tm->tm_hour = static_cast<int>(time_st->wHour); + time_tm->tm_mday = static_cast<int>(time_st->wDay); + time_tm->tm_mon = static_cast<int>(time_st->wMonth); + time_tm->tm_year = static_cast<int>(time_st->wYear); + }; + + if (result) { - result = (fatDate << 16) + fatTime; + if (ptmLastWrite) set_tm_by_st(ptmLastWrite, &stLastWrite); + if (ptmLastAccess) set_tm_by_st(ptmLastAccess, &stLastAccess); } } + else + result = false; + CloseHandle(hFile); } -#else - std::string inputFileA = U_TO_UTF8(inputFile); -#if defined(__linux__) && !defined(_MAC) - struct stat attrib; - stat(inputFileA.c_str(), &attrib); - result = attrib.st_mtim.tv_nsec; -#else - struct stat attrib; - stat(inputFileA.c_str(), &attrib); - result = (unsigned long)attrib.st_mtimespec.tv_nsec; -#endif -#endif + else + result = false; + + +#else // linux or macOS + struct stat attr; + result = (0 == stat(U_TO_UTF8(sFilename).c_str(), &attr)); + + if (result) + { + auto set_tm_by_secs = [] (struct tm* time_tm, time_t time_secs) { + struct tm* ltime = localtime(&time_secs); + *time_tm = *ltime; + time_tm->tm_year += 1900; + time_tm->tm_mon += 1; + }; + + time_t m_secs = attr.st_mtim.tv_sec; // edit + time_t a_secs = attr.st_atim.tv_sec; // access + + if (ptmLastWrite) set_tm_by_secs(ptmLastWrite, m_secs); + if (ptmLastAccess) set_tm_by_secs(ptmLastAccess, a_secs); + } + +#endif // defined(_WIN32) || defined (_WIN64) + return result; + } + + bool CFileBinary::SetTime(const std::wstring& sFilename, struct tm* ptmLastWrite, struct tm* ptmLastAccess) + { + bool result = true; + +#if defined(_WIN32) || defined (_WIN64) // windows + + auto set_st_by_tm = [] (SYSTEMTIME* time_st, struct tm* time_tm) { + time_st->wSecond = static_cast<WORD>(time_tm->tm_sec); + time_st->wMinute = static_cast<WORD>(time_tm->tm_min); + time_st->wHour = static_cast<WORD>(time_tm->tm_hour); + time_st->wDay = static_cast<WORD>(time_tm->tm_mday); + time_st->wMonth = static_cast<WORD>(time_tm->tm_mon); + time_st->wYear = static_cast<WORD>(time_tm->tm_year); + }; + + SYSTEMTIME stLastWrite{}, stLastAccess{}; + if (ptmLastWrite) set_st_by_tm(&stLastWrite, ptmLastWrite); + if (ptmLastAccess) set_st_by_tm(&stLastAccess, ptmLastAccess); + + FILETIME ftLastWriteLocal{}, ftLastAccessLocal{}; + if (ptmLastWrite) result = result && ::SystemTimeToFileTime(&stLastWrite, &ftLastWriteLocal); + if (ptmLastAccess) result = result && ::SystemTimeToFileTime(&stLastAccess, &ftLastAccessLocal); + + FILETIME ftLastWrite{}, ftLastAccess{}; + if (ptmLastWrite) result = result && ::LocalFileTimeToFileTime(&ftLastWriteLocal, &ftLastWrite); + if (ptmLastAccess) result = result && ::LocalFileTimeToFileTime(&ftLastAccessLocal, &ftLastAccess); + + if (result) + { + HANDLE hFile; + hFile = ::CreateFileW(sFilename.c_str(), GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if (hFile) + { + FILETIME* pftLastWrite = NULL; + FILETIME* pftLastAccess = NULL; + + if (ptmLastWrite) pftLastWrite = &ftLastWrite; + if (ptmLastAccess) pftLastAccess = &ftLastAccess; + + result = SetFileTime(hFile, NULL, pftLastAccess, pftLastWrite); + } + else + result = false; + + CloseHandle(hFile); + } + + +#else // linux or macOS + struct stat attr; + std::string sFilenameA = U_TO_UTF8(sFilename); + result = (0 == stat(sFilenameA.c_str(), &attr)); + + if (result) + { + time_t m_secs = attr.st_mtim.tv_sec; // edit + time_t a_secs = attr.st_atim.tv_sec; // access + + time_t new_m_secs = m_secs; + time_t new_a_secs = a_secs; + + if (ptmLastWrite) + { + struct tm tmLastWriteUnix = *ptmLastWrite; + tmLastWriteUnix.tm_year -= 1900; + tmLastWriteUnix.tm_mon -= 1; + new_m_secs = mktime(&tmLastWriteUnix); + } + if (ptmLastAccess) + { + struct tm tmLastAccessUnix = *ptmLastAccess; + tmLastAccessUnix.tm_year -= 1900; + tmLastAccessUnix.tm_mon -= 1; + new_a_secs = mktime(&tmLastAccessUnix); + } + + utimbuf new_time{}; + new_time.actime = new_a_secs; + new_time.modtime = new_m_secs; + utime(sFilenameA.c_str(), &new_time); + } +#endif // defined(_WIN32) || defined (_WIN64) return result; } } diff --git a/DesktopEditor/common/File.h b/DesktopEditor/common/File.h index dfe3ac4170b..b232ef680de 100644 --- a/DesktopEditor/common/File.h +++ b/DesktopEditor/common/File.h @@ -189,12 +189,24 @@ namespace NSFile static void SetTempPath(const std::wstring& strTempPath); static std::wstring GetTempPath(); + static bool IsGlobalTempPathUse(); static std::wstring CreateTempFileWithUniqueName(const std::wstring& strFolderPathRoot, const std::wstring& Prefix); static bool OpenTempFile(std::wstring *pwsName, FILE **ppFile, wchar_t *wsMode, wchar_t *wsExt, wchar_t *wsFolder, wchar_t* wsName = NULL); static FILE* OpenFileNative(const std::wstring& sFileName, const std::wstring& sMode); - static unsigned long GetDateTime(const std::wstring & strFileName); + // returns true if everything is OK; + // you can set ptmLastWrite / ptmLastAccess to nullptr if you are not going to use them; + // tm_wday && tm_yday && tm_isdst is unused on windows + static bool GetTime(const std::wstring& sFilename, + struct tm* ptmLastWrite = nullptr, + struct tm* ptmLastAccess = nullptr); + + // returns true if everything is OK; + // you can set ptmLastWrite / ptmLastAccess to nullptr if you are not going to change them + static bool SetTime(const std::wstring& sFilename, + struct tm* ptmLastWrite = nullptr, + struct tm* ptmLastAccess = nullptr); }; class KERNEL_DECL CBase64Converter diff --git a/DesktopEditor/common/IGrObject.h b/DesktopEditor/common/IGrObject.h index 953c67ce32b..b0a8d318048 100644 --- a/DesktopEditor/common/IGrObject.h +++ b/DesktopEditor/common/IGrObject.h @@ -38,6 +38,8 @@ #include <libkern/OSAtomic.h> #endif +#define UNUSED_VARIABLE(x) (void)((x)) + class IGrObject { protected: diff --git a/DesktopEditor/common/Path.cpp b/DesktopEditor/common/Path.cpp index 118f41cbc44..02dbafcbdea 100644 --- a/DesktopEditor/common/Path.cpp +++ b/DesktopEditor/common/Path.cpp @@ -31,6 +31,7 @@ */ #include "Path.h" #include "File.h" +#include <stack> #if defined(_WIN32) || defined (_WIN64) #include <tchar.h> @@ -110,7 +111,7 @@ namespace NSSystemPath } template<class CHAR, class STRING = std::basic_string<CHAR, std::char_traits<CHAR>, std::allocator<CHAR>>> - STRING NormalizePathTemplate(const STRING& strFileName) + STRING NormalizePathTemplate(const STRING& strFileName, const bool& canHead = false) { const CHAR* pData = strFileName.c_str(); int nLen = (int) strFileName.length(); @@ -124,6 +125,12 @@ namespace NSSystemPath int nCurrentW = 0; bool bIsUp = false; + if (canHead) + { + nCurrentSlash = 0; + pSlashPoints[0] = 0; + } + if (pData[nCurrent] == '/' || pData[nCurrent] == '\\') { #if !defined(_WIN32) && !defined (_WIN64) @@ -177,12 +184,69 @@ namespace NSSystemPath return result; } - std::string NormalizePath(const std::string& strFileName) + std::string NormalizePath(const std::string& strFileName, const bool& canHead) { - return NormalizePathTemplate<char>(strFileName); + return NormalizePathTemplate<char>(strFileName, canHead); } - std::wstring NormalizePath(const std::wstring& strFileName) + std::wstring NormalizePath(const std::wstring& strFileName, const bool& canHead) { - return NormalizePathTemplate<wchar_t>(strFileName); + return NormalizePathTemplate<wchar_t>(strFileName, canHead); + } + + std::wstring ShortenPath(const std::wstring &strPath, const bool& bRemoveExternalPath) + { + std::stack<std::wstring> arStack; + std::wstring wsToken; + + for (size_t i = 0; i < strPath.size(); ++i) + { + if (L'/' == strPath[i] || L'\\' == strPath[i]) + { + if (L".." == wsToken) + { + if (!arStack.empty() && L".." != arStack.top()) + arStack.pop(); + else + arStack.push(wsToken); + } + else if (L"." != wsToken && !wsToken.empty()) + arStack.push(wsToken); + + wsToken.clear(); + } + else + wsToken += strPath[i]; + } + + if (L".." == wsToken) + { + if (!arStack.empty() && L".." == arStack.top()) + arStack.pop(); + else + arStack.push(wsToken); + } + else if (L"." != wsToken && !wsToken.empty()) + arStack.push(wsToken); + + wsToken.clear(); + + if (arStack.empty()) + return std::wstring(); + + std::wstring wsNewPath; + + while (!arStack.empty()) + { + if (bRemoveExternalPath && L".." == arStack.top()) + break; + + wsNewPath = arStack.top() + L'/' + wsNewPath; + arStack.pop(); + } + + wsNewPath.pop_back(); + + return wsNewPath; } + } diff --git a/DesktopEditor/common/Path.h b/DesktopEditor/common/Path.h index 494c8a06bcd..af620583744 100644 --- a/DesktopEditor/common/Path.h +++ b/DesktopEditor/common/Path.h @@ -41,8 +41,9 @@ namespace NSSystemPath KERNEL_DECL std::wstring GetDirectoryName(const std::wstring& strFileName); KERNEL_DECL std::wstring GetFileName(const std::wstring& strFileName); KERNEL_DECL std::wstring Combine(const std::wstring& strLeft, const std::wstring& strRight); - KERNEL_DECL std::string NormalizePath(const std::string& strFileName); - KERNEL_DECL std::wstring NormalizePath(const std::wstring& strFileName); + KERNEL_DECL std::string NormalizePath(const std::string& strFileName, const bool& canHead = false); + KERNEL_DECL std::wstring NormalizePath(const std::wstring& strFileName, const bool& canHead = false); + KERNEL_DECL std::wstring ShortenPath(const std::wstring& strPath, const bool& bRemoveExternalPath = false); } #endif //_BUILD_PATH_CROSSPLATFORM_H_ diff --git a/DesktopEditor/common/StringBuilder.cpp b/DesktopEditor/common/StringBuilder.cpp index 2a8d1b4ed79..99f4eb626b4 100644 --- a/DesktopEditor/common/StringBuilder.cpp +++ b/DesktopEditor/common/StringBuilder.cpp @@ -648,7 +648,7 @@ namespace NSStringUtils } void CStringBuilder::AddInt(int val) { - AddSize(10); + AddSize(11); AddIntNoCheck(val); } void CStringBuilder::AddUInt(unsigned int val) @@ -682,7 +682,11 @@ namespace NSStringUtils } if (val < 0) { - val = -val; + if (val == -2147483648) + val = 2147483647; + else + val = -val; + *m_pDataCur++ = (wchar_t)'-'; ++m_lSizeCur; } diff --git a/DesktopEditor/common/StringUTF32.cpp b/DesktopEditor/common/StringUTF32.cpp index 3f745a2b6ca..d98ad05d707 100644 --- a/DesktopEditor/common/StringUTF32.cpp +++ b/DesktopEditor/common/StringUTF32.cpp @@ -30,125 +30,148 @@ * */ #include "StringUTF32.h" +#include "StringExt.h" using namespace std; using namespace NSStringUtils; -CStringUTF32::CStringUTF32() {} -CStringUTF32::CStringUTF32(const CStringUTF32 &other): m_vec(other.m_vec) {} -CStringUTF32::CStringUTF32(const wchar_t *other) { *this = other; } -CStringUTF32::CStringUTF32(const wstring &other) { *this = other; } -CStringUTF32::CStringUTF32(const vector<uint32_t> &other): m_vec(other) {} +CStringUTF32::CStringUTF32() +{ +} +CStringUTF32::CStringUTF32(const CStringUTF32& other) : m_vec(other.m_vec) +{ +} +CStringUTF32::CStringUTF32(const wchar_t* other) +{ + *this = other; +} +CStringUTF32::CStringUTF32(const wstring& other) +{ + *this = other; +} +CStringUTF32::CStringUTF32(const vector<uint32_t>& other) : m_vec(other) +{ +} CStringUTF32::CStringUTF32(const uint32_t* data, const size_t& len) { - m_vec.reserve(len); - for (size_t i = 0; i < len; ++i) - this->m_vec.push_back(data[i]); + m_vec.reserve(len); + for (size_t i = 0; i < len; ++i) + this->m_vec.push_back(data[i]); } -CStringUTF32::~CStringUTF32() {} +CStringUTF32::~CStringUTF32() +{ +} bool CStringUTF32::empty() const { - return this->m_vec.empty(); + return this->m_vec.empty(); } size_t CStringUTF32::length() const { - return this->m_vec.size(); + return this->m_vec.size(); } wstring CStringUTF32::ToStdWString() const { - if (0 == length()) - return L""; - return NSStringExt::CConverter::GetUnicodeFromUTF32(&this->m_vec[0], static_cast<long>(this->length())); + if (0 == length()) + return L""; + return NSStringExt::CConverter::GetUnicodeFromUTF32(&this->m_vec[0], static_cast<long>(this->length())); } -bool CStringUTF32::operator == (const CStringUTF32 &right) const +bool CStringUTF32::operator==(const CStringUTF32& right) const { - return this->m_vec == right.m_vec; + return this->m_vec == right.m_vec; } -bool CStringUTF32::operator != (const CStringUTF32 &right) const +bool CStringUTF32::operator!=(const CStringUTF32& right) const { - return !(this->m_vec == right.m_vec); + return !(this->m_vec == right.m_vec); } -uint32_t& CStringUTF32::operator [] (size_t index) +uint32_t& CStringUTF32::operator[](size_t index) { - return this->m_vec[index]; + return this->m_vec[index]; } -CStringUTF32& CStringUTF32::operator = (const CStringUTF32 &right) +CStringUTF32& CStringUTF32::operator=(const CStringUTF32& right) { - this->m_vec = right.m_vec; - return *this; + this->m_vec = right.m_vec; + return *this; } -CStringUTF32& CStringUTF32::operator = (const wchar_t *right) +CStringUTF32& CStringUTF32::operator=(const wchar_t* right) { - if (!right) - { - m_vec.clear(); - return *this; - } + if (!right) + { + m_vec.clear(); + return *this; + } - return (*this = std::wstring(right)); + return (*this = std::wstring(right)); } -CStringUTF32& CStringUTF32::operator = (const wstring &right) +CStringUTF32& CStringUTF32::operator=(const wstring& right) { - if (right.empty()) - { - m_vec.clear(); - return *this; - } - - unsigned int utf32_len = 0; - unsigned int* utf32 = NSStringExt::CConverter::GetUtf32FromUnicode(right, utf32_len); - this->m_vec.clear(); - this->m_vec.reserve(utf32_len); - for (size_t i = 0; i < utf32_len; ++i) - this->m_vec.push_back(utf32[i]); - - delete [] utf32; - return *this; + if (right.empty()) + { + m_vec.clear(); + return *this; + } + + unsigned int utf32_len = 0; + unsigned int* utf32 = NSStringExt::CConverter::GetUtf32FromUnicode(right, utf32_len); + this->m_vec.clear(); + this->m_vec.reserve(utf32_len); + for (size_t i = 0; i < utf32_len; ++i) + this->m_vec.push_back(utf32[i]); + + delete[] utf32; + return *this; } -CStringUTF32& CStringUTF32::operator = (const std::vector<uint32_t> &right) +CStringUTF32& CStringUTF32::operator=(const std::vector<uint32_t>& right) { - this->m_vec = right; - return *this; + this->m_vec = right; + return *this; } - -CStringUTF32 CStringUTF32::operator + (const CStringUTF32 &right) const +CStringUTF32 CStringUTF32::operator+(const CStringUTF32& right) const { - CStringUTF32 result; - result.m_vec.reserve(this->length() + right.length()); - result.m_vec.insert(result.m_vec.end(), m_vec.begin(), m_vec.end()); - result.m_vec.insert(result.m_vec.end(), right.m_vec.begin(), right.m_vec.end()); - return result; + CStringUTF32 result; + result.m_vec.reserve(this->length() + right.length()); + result.m_vec.insert(result.m_vec.end(), m_vec.begin(), m_vec.end()); + result.m_vec.insert(result.m_vec.end(), right.m_vec.begin(), right.m_vec.end()); + return result; } -CStringUTF32& CStringUTF32::operator += (const CStringUTF32 &right) +CStringUTF32& CStringUTF32::operator+=(const CStringUTF32& right) { - m_vec.insert(m_vec.end(), right.m_vec.begin(), right.m_vec.end()); - return *this; + m_vec.insert(m_vec.end(), right.m_vec.begin(), right.m_vec.end()); + return *this; } -CStringUTF32& CStringUTF32::operator += (const uint32_t& symbol) +CStringUTF32& CStringUTF32::operator+=(const uint32_t& symbol) { - m_vec.push_back(symbol); - return *this; + m_vec.push_back(symbol); + return *this; } CStringUTF32 CStringUTF32::substr(size_t start, size_t count) const { - CStringUTF32 result; - result.m_vec.reserve(count); - result.m_vec.insert(result.m_vec.end(), m_vec.begin() + start, m_vec.begin() + start + count); - return result; + CStringUTF32 result; + result.m_vec.reserve(count); + result.m_vec.insert(result.m_vec.end(), m_vec.begin() + start, m_vec.begin() + start + count); + return result; +} + +const uint32_t& CStringUTF32::at(size_t index) const +{ + return this->m_vec.at(index); +} +uint32_t& CStringUTF32::at(size_t index) +{ + return this->m_vec.at(index); } diff --git a/DesktopEditor/common/StringUTF32.h b/DesktopEditor/common/StringUTF32.h index 2341fa7397b..561de1afced 100644 --- a/DesktopEditor/common/StringUTF32.h +++ b/DesktopEditor/common/StringUTF32.h @@ -32,45 +32,49 @@ #ifndef STRINGUTF32_HPP #define STRINGUTF32_HPP +#include <stdint.h> #include <string> #include <vector> -#include <stdint.h> -#include "StringExt.h" +#include "../../Common/kernel_config.h" namespace NSStringUtils { - class KERNEL_DECL CStringUTF32 - { - std::vector<uint32_t> m_vec; - public: - CStringUTF32(); - CStringUTF32(const CStringUTF32 &other); - CStringUTF32(const wchar_t *other); - CStringUTF32(const std::wstring &other); - CStringUTF32(const std::vector<uint32_t> &other); - CStringUTF32(const uint32_t* data, const size_t& count); - virtual ~CStringUTF32(); + class KERNEL_DECL CStringUTF32 + { + std::vector<uint32_t> m_vec; + + public: + CStringUTF32(); + CStringUTF32(const CStringUTF32 &other); + CStringUTF32(const wchar_t *other); + CStringUTF32(const std::wstring &other); + CStringUTF32(const std::vector<uint32_t> &other); + CStringUTF32(const uint32_t *data, const size_t &count); + virtual ~CStringUTF32(); + + bool empty() const; + size_t length() const; - bool empty() const; - size_t length() const; + std::wstring ToStdWString() const; - std::wstring ToStdWString() const; + bool operator==(const CStringUTF32 &right) const; + bool operator!=(const CStringUTF32 &right) const; + uint32_t &operator[](size_t index); - bool operator == (const CStringUTF32 &right) const; - bool operator != (const CStringUTF32 &right) const; - uint32_t &operator [] (size_t index); + CStringUTF32 &operator=(const CStringUTF32 &right); + CStringUTF32 &operator=(const wchar_t *right); + CStringUTF32 &operator=(const std::wstring &right); + CStringUTF32 &operator=(const std::vector<uint32_t> &right); - CStringUTF32 &operator = (const CStringUTF32 &right); - CStringUTF32 &operator = (const wchar_t *right); - CStringUTF32 &operator = (const std::wstring &right); - CStringUTF32 &operator = (const std::vector<uint32_t> &right); + CStringUTF32 operator+(const CStringUTF32 &right) const; + CStringUTF32 &operator+=(const CStringUTF32 &right); + CStringUTF32 &operator+=(const uint32_t &symbol); - CStringUTF32 operator + (const CStringUTF32 &right) const; - CStringUTF32 &operator += (const CStringUTF32 &right); - CStringUTF32 &operator += (const uint32_t& symbol); + CStringUTF32 substr(size_t start, size_t count) const; - CStringUTF32 substr(size_t start, size_t count) const; - }; -} + const uint32_t &at(size_t index) const; + uint32_t &at(size_t index); + }; +} // namespace NSStringUtils #endif // STRINGUTF32_HPP diff --git a/DesktopEditor/cximage/CxImage/ximacfg.h b/DesktopEditor/cximage/CxImage/ximacfg.h index b5dcefb5598..d6189f4bdce 100644 --- a/DesktopEditor/cximage/CxImage/ximacfg.h +++ b/DesktopEditor/cximage/CxImage/ximacfg.h @@ -37,14 +37,20 @@ #define CXIMAGE_SUPPORT_PGX 1 #define CXIMAGE_SUPPORT_PNM 1 #define CXIMAGE_SUPPORT_RAS 1 +#define CXIMAGE_SUPPORT_PIC 1 #define CXIMAGE_SUPPORT_JBG 0 // GPL'd see ../jbig/copying.txt & ../jbig/patents.htm #define CXIMAGE_SUPPORT_MNG 1 #define CXIMAGE_SUPPORT_SKA 1 -#define CXIMAGE_SUPPORT_RAW 1 #define CXIMAGE_SUPPORT_PSD 1 +#ifndef BUILDING_WASM_MODULE +#define CXIMAGE_SUPPORT_RAW 1 +#else +#define CXIMAGE_SUPPORT_RAW 0 +#endif + #ifdef CXIMAGE_DISABLE_SUPPORT_MNG #undef CXIMAGE_SUPPORT_MNG #define CXIMAGE_SUPPORT_MNG 0 diff --git a/DesktopEditor/cximage/CxImage/ximage.h b/DesktopEditor/cximage/CxImage/ximage.h index 8ffe4c77ad8..4ac5415f812 100644 --- a/DesktopEditor/cximage/CxImage/ximage.h +++ b/DesktopEditor/cximage/CxImage/ximage.h @@ -130,10 +130,13 @@ CXIMAGE_FORMAT_RAW = 19, #if CXIMAGE_SUPPORT_PSD CXIMAGE_FORMAT_PSD = 20, #endif +#if CXIMAGE_SUPPORT_PIC +CXIMAGE_FORMAR_PIC = 25, +#endif CMAX_IMAGE_FORMATS = CXIMAGE_SUPPORT_BMP + CXIMAGE_SUPPORT_GIF + CXIMAGE_SUPPORT_JPG + CXIMAGE_SUPPORT_PNG + CXIMAGE_SUPPORT_MNG + CXIMAGE_SUPPORT_ICO + CXIMAGE_SUPPORT_TIF + CXIMAGE_SUPPORT_TGA + CXIMAGE_SUPPORT_PCX + - CXIMAGE_SUPPORT_WBMP+ CXIMAGE_SUPPORT_WMF + + CXIMAGE_SUPPORT_WBMP+ CXIMAGE_SUPPORT_WMF + CXIMAGE_SUPPORT_PIC + CXIMAGE_SUPPORT_JBG + CXIMAGE_SUPPORT_JP2 + CXIMAGE_SUPPORT_JPC + CXIMAGE_SUPPORT_PGX + CXIMAGE_SUPPORT_PNM + CXIMAGE_SUPPORT_RAS + CXIMAGE_SUPPORT_SKA + CXIMAGE_SUPPORT_RAW + CXIMAGE_SUPPORT_PSD + 1 diff --git a/DesktopEditor/cximage/raw/libdcr.h b/DesktopEditor/cximage/raw/libdcr.h index 0b828454aac..6d74732a87e 100644 --- a/DesktopEditor/cximage/raw/libdcr.h +++ b/DesktopEditor/cximage/raw/libdcr.h @@ -58,7 +58,7 @@ #ifdef __ANDROID__ #include <unistd.h> -#if __ANDROID_API__ < 28 +#if __ANDROID_API__ < 22 static void swab(const char* __src, char* __dst, ssize_t __byte_count) { ssize_t len = __byte_count; diff --git a/DesktopEditor/doctrenderer/app_builder/docbuilder.pro b/DesktopEditor/doctrenderer/app_builder/docbuilder.pro index e414a3f70d0..ceb33c54a59 100644 --- a/DesktopEditor/doctrenderer/app_builder/docbuilder.pro +++ b/DesktopEditor/doctrenderer/app_builder/docbuilder.pro @@ -25,7 +25,7 @@ core_windows { DESTDIR = $$CORE_BUILDS_BINARY_PATH ################################################ -ADD_DEPENDENCY(graphics, kernel, kernel_network, UnicodeConverter, doctrenderer) +ADD_DEPENDENCY(graphics, kernel, kernel_network, UnicodeConverter, doctrenderer, PdfFile, XpsFile, DjVuFile, DocxRenderer) core_linux { LIBS += -ldl diff --git a/DesktopEditor/doctrenderer/app_builder/main.cpp b/DesktopEditor/doctrenderer/app_builder/main.cpp index 76db8e75be2..0507c86a16e 100644 --- a/DesktopEditor/doctrenderer/app_builder/main.cpp +++ b/DesktopEditor/doctrenderer/app_builder/main.cpp @@ -147,6 +147,7 @@ int main(int argc, char *argv[]) std::wstring sBuildFile = UTF8_TO_U(sBuildFileA); #endif + bool bResult = true; if (true) { NSDoctRenderer::CDocBuilder oBuilder; @@ -159,9 +160,9 @@ int main(int argc, char *argv[]) parse_args(&oBuilder, argc - 1, argv); - oBuilder.Run(sBuildFile.c_str()); + bResult = oBuilder.Run(sBuildFile.c_str()); } NSDoctRenderer::CDocBuilder::Dispose(); - return 0; + return bResult ? 0 : 1; } diff --git a/DesktopEditor/doctrenderer/common_deploy.h b/DesktopEditor/doctrenderer/common_deploy.h index cbfff54c603..81ffc9d1fb8 100644 --- a/DesktopEditor/doctrenderer/common_deploy.h +++ b/DesktopEditor/doctrenderer/common_deploy.h @@ -16,6 +16,7 @@ #define OFFICESTUDIO_FILE_DOCUMENT_DOTX OFFICESTUDIO_FILE_DOCUMENT + 0x000c #define OFFICESTUDIO_FILE_DOCUMENT_OTT OFFICESTUDIO_FILE_DOCUMENT + 0x000f #define OFFICESTUDIO_FILE_DOCUMENT_HTML OFFICESTUDIO_FILE_DOCUMENT + 0x0012 +#define OFFICESTUDIO_FILE_DOCUMENT_OFORM_PDF OFFICESTUDIO_FILE_DOCUMENT + 0x0017 #define OFFICESTUDIO_FILE_PRESENTATION 0x0080 #define OFFICESTUDIO_FILE_PRESENTATION_PPTX OFFICESTUDIO_FILE_PRESENTATION + 0x0001 diff --git a/DesktopEditor/doctrenderer/config.h b/DesktopEditor/doctrenderer/config.h index 72831432bd8..1f04514b3c5 100644 --- a/DesktopEditor/doctrenderer/config.h +++ b/DesktopEditor/doctrenderer/config.h @@ -38,25 +38,58 @@ #include "../xml/include/xmlutils.h" #include "../fontengine/TextHyphen.h" +#define VALUE_TO_STRING(x) #x +#define VALUE(x) VALUE_TO_STRING(x) + namespace NSDoctRenderer { + class CAdditionalData + { + public: + CAdditionalData() {} + virtual ~CAdditionalData() {} + virtual std::string getParam(const std::wstring& name) { return ""; } + }; + + class CDocBuilderParams + { + public: + CDocBuilderParams() : + m_bCheckFonts(false), + m_sWorkDir(L""), + m_bSaveWithDoctrendererMode(false), + m_sArgumentJSON(""), + m_bIsSystemFonts(true) + { + } + + public: + bool m_bCheckFonts; + std::wstring m_sWorkDir; + bool m_bSaveWithDoctrendererMode; + std::string m_sArgumentJSON; + + bool m_bIsSystemFonts; + std::vector<std::wstring> m_arFontDirs; + }; + class CDoctRendererConfig { public: - std::vector<std::wstring> m_arrFiles; + std::wstring m_strSdkPath; - std::vector<std::wstring> m_arDoctSDK; - std::vector<std::wstring> m_arPpttSDK; - std::vector<std::wstring> m_arXlstSDK; + std::vector<std::wstring> m_arrFiles; std::wstring m_strAllFonts; bool m_bIsNotUseConfigAllFontsDir; + bool m_bIsUseCache; + std::wstring m_sConsoleLogFile; std::wstring m_sErrorsLogFile; public: - CDoctRendererConfig() : m_bIsNotUseConfigAllFontsDir(false) + CDoctRendererConfig() : m_bIsNotUseConfigAllFontsDir(false), m_bIsUseCache(true) { } @@ -91,9 +124,6 @@ namespace NSDoctRenderer void Parse(const std::wstring& sWorkDir) { m_arrFiles.clear(); - m_arDoctSDK.clear(); - m_arPpttSDK.clear(); - m_arXlstSDK.clear(); std::wstring sConfigDir = sWorkDir + L"/"; std::wstring sConfigPath = sConfigDir + L"DoctRenderer.config"; @@ -118,13 +148,23 @@ namespace NSDoctRenderer NSHyphen::CEngine::Init(private_GetFile(sConfigDir, oNodeDict.GetText())); } - bool bIsAbsoluteFontsPath = false; if (!m_bIsNotUseConfigAllFontsDir) { std::wstring sAllFontsPath = oNode.ReadNodeText(L"allfonts"); if (!sAllFontsPath.empty()) { - m_strAllFonts = private_GetFile(sConfigDir, sAllFontsPath); + if (NSFile::CFileBinary::Exists(sConfigDir + sAllFontsPath)) + m_strAllFonts = sConfigDir + sAllFontsPath; + else if (NSFile::CFileBinary::Exists(sAllFontsPath)) + m_strAllFonts = sAllFontsPath; + else + { + std::wstring sAllFontsDir = NSFile::GetDirectoryName(sAllFontsPath); + if (NSDirectory::Exists(sConfigDir + sAllFontsDir)) + m_strAllFonts = sConfigDir + sAllFontsPath; + else + m_strAllFonts = sAllFontsPath; + } // на папку может не быть прав if (!NSFile::CFileBinary::Exists(m_strAllFonts)) @@ -136,47 +176,23 @@ namespace NSDoctRenderer if (NSDirectory::CreateDirectory(sAppDir + L"/docbuilder")) { m_strAllFonts = sAppDir + L"/docbuilder/AllFonts.js"; - // файл может не существовать пока - и тогда private_GetFile не учтет его - bIsAbsoluteFontsPath = true; } } else { fclose(pFileNative); + NSFile::CFileBinary::Remove(m_strAllFonts); } } } } - m_arrFiles.push_back(bIsAbsoluteFontsPath ? m_strAllFonts : private_GetFile(sConfigDir, m_strAllFonts)); } - std::wstring sSdkPath = oNode.ReadNodeText(L"sdkjs"); - if (!sSdkPath.empty()) + m_strSdkPath = oNode.ReadNodeText(L"sdkjs"); + if (!m_strSdkPath.empty()) { - if (!NSDirectory::Exists(sSdkPath)) - sSdkPath = sConfigDir + sSdkPath; - - std::wstring sFontsPath = sSdkPath + L"/common/libfont/engine"; - if (!sFontsPath.empty()) - { -#ifdef SUPPORT_HARFBUZZ_SHAPER - sFontsPath += L"/fonts_native.js"; -#else - sFontsPath += L"/fonts_ie.js"; -#endif - } - - m_arDoctSDK.push_back(sSdkPath + L"/word/sdk-all-min.js"); - m_arDoctSDK.push_back(sFontsPath); - m_arDoctSDK.push_back(sSdkPath + L"/word/sdk-all.js"); - - m_arPpttSDK.push_back(sSdkPath + L"/slide/sdk-all-min.js"); - m_arPpttSDK.push_back(sFontsPath); - m_arPpttSDK.push_back(sSdkPath + L"/slide/sdk-all.js"); - - m_arXlstSDK.push_back(sSdkPath + L"/cell/sdk-all-min.js"); - m_arXlstSDK.push_back(sFontsPath); - m_arXlstSDK.push_back(sSdkPath + L"/cell/sdk-all.js"); + if (!NSDirectory::Exists(m_strSdkPath)) + m_strSdkPath = sConfigDir + m_strSdkPath; } m_sConsoleLogFile = oNode.ReadNodeText(L"LogFileConsoleLog"); @@ -187,7 +203,21 @@ namespace NSDoctRenderer if (!m_sErrorsLogFile.empty()) m_sErrorsLogFile = private_GetFile(sConfigDir, m_sErrorsLogFile); } + + char* GetVersion() + { + std::string sVersion = VALUE(INTVER); + + size_t sSrcLen = sVersion.size(); + if (sSrcLen == 0) + return NULL; + + char* sRet = new char[sSrcLen + 1]; + memcpy(sRet, sVersion.c_str(), sSrcLen); + sRet[sSrcLen] = '\0'; + return sRet; + } }; -} // namespace NSDoctRenderer +} #endif // DOC_BUILDER_CONFIG diff --git a/DesktopEditor/doctrenderer/docbuilder.cpp b/DesktopEditor/doctrenderer/docbuilder.cpp index b0e4dd7bb6f..bfb37ac573d 100644 --- a/DesktopEditor/doctrenderer/docbuilder.cpp +++ b/DesktopEditor/doctrenderer/docbuilder.cpp @@ -68,8 +68,8 @@ namespace NSDoctRenderer return m_pInternal->ExecuteCommand(command, retValue); } - CDocBuilderContext CDocBuilder::GetContext() + CDocBuilderContext CDocBuilder::GetContext(bool enterContext) { - return m_pInternal->GetContext(); + return m_pInternal->GetContext(enterContext); } } diff --git a/DesktopEditor/doctrenderer/docbuilder.h b/DesktopEditor/doctrenderer/docbuilder.h index e84b9ba732b..1177046c846 100644 --- a/DesktopEditor/doctrenderer/docbuilder.h +++ b/DesktopEditor/doctrenderer/docbuilder.h @@ -199,6 +199,16 @@ namespace NSDoctRenderer * Creates a null value. This method returns the current context and calls its CreateNull method. */ static CDocBuilderValue CreateNull(); + /** + * Please use CDocBuilderContext::CreateArray + * Creates an array. This method returns the current context and calls its CreateArray method. + */ + static CDocBuilderValue CreateArray(const int& length); + /** + * Please use CDocBuilderContext::CreateObject + * Creates an object. This method returns the current context and calls its CreateObject method. + */ + static CDocBuilderValue CreateObject(); public: /** @@ -352,6 +362,7 @@ namespace NSDoctRenderer /** * Creates a new file. The type of the file which will be created needs to be set. * @param type The type of the file to be created set as a hexadecimal integer for the C++ code or docx, xlsx or pptx for the .docbuilder script file (see AVS_OFFICESTUDIO_FILE_XXX values). + * Possible values for wchar_t version: "docx", "pptx", "xlsx", "pdf", "form" * @return True if the operation is successful */ bool CreateFile(const int& type); @@ -486,9 +497,10 @@ namespace NSDoctRenderer /** * Returns the current JS context. + * @param enterContext Whether returned context should be entered or not. * @return The current JS context */ - CDocBuilderContext GetContext(); + CDocBuilderContext GetContext(bool enterContext = true); public: /** @@ -541,7 +553,7 @@ namespace NSDoctRenderer * 3) The builder object methods cannot be called with the JS variables. Wrap them with the jsValue instruction if necessary: * var jsVar = "123.docx"; * builder.SaveFile("docx", jsVar); // Incorrect - * builder.SaveFile("docx", jsValue(jsVar)); // Correct + * builder.SaveFile("docx", "jsValue(jsVar)"); // Correct * * 4) For convenience, format types are replaced with strings. * For example, builder.CreateFile("docx"); is the same as CDocBuilder.CreateFile(AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX); diff --git a/DesktopEditor/doctrenderer/docbuilder.java/.gitignore b/DesktopEditor/doctrenderer/docbuilder.java/.gitignore new file mode 100644 index 00000000000..f51d072bd61 --- /dev/null +++ b/DesktopEditor/doctrenderer/docbuilder.java/.gitignore @@ -0,0 +1,3 @@ +result.docx +*.class +*.jar diff --git a/DesktopEditor/doctrenderer/docbuilder.java/make.py b/DesktopEditor/doctrenderer/docbuilder.java/make.py new file mode 100644 index 00000000000..9578394f177 --- /dev/null +++ b/DesktopEditor/doctrenderer/docbuilder.java/make.py @@ -0,0 +1,112 @@ +import os +import argparse +import platform +import subprocess +import re + +# NOTE: In JDK 8 and earlier, `javac` does not create the directories specified in the -d option if they do not already exist +# So we need to create them manually +def makedirs(dir): + if not os.path.exists(dir): + os.makedirs(dir) + return + +def is_javac_available(javac): + try: + process = subprocess.Popen([javac, '-version'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) + ret = process.wait() + return ret == 0 + except Exception: + return False + +def get_jdk_version(javac): + try: + process = subprocess.Popen([javac, '-version'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) + stdout, stderr = process.communicate() + output = stdout if stdout else stderr + if not output: + return 0 + + javac_version_str = output.decode('utf-8').strip() + match = re.search('(\d+)(?:\.(\d+))?', javac_version_str) + if not match: + return 0 + + major_version = int(match.group(1)) + minor_version = int(match.group(2)) if match.group(2) else 0 + + # for JDK 9 and earlier command `javac -version` would give '1.x.xx' + if major_version == 1: + return minor_version + return major_version + + except Exception: + return 0 + +# return all files with extension `ext` in directory `dir` as string +def getFilesInDir(dir, ext): + files = []; + for file in os.listdir(dir): + if file.endswith(ext): + files.append(os.path.join(dir, file)) + + return files + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description='Build Java wrapper for docbuilder library') + parser.add_argument('-H', '--headers', action='store_true', help='Generate C++ JNI header files') + parser.add_argument('-n', '--no-jar', dest='no_jar', action='store_true', help='Build only classes without JAR archive') + args = parser.parse_args() + + file_dir = os.path.dirname(os.path.realpath(__file__)); + os.chdir(file_dir + '/src/java') + + java_files = getFilesInDir('docbuilder', '.java') + java_files += getFilesInDir('docbuilder/utils', '.java') + + # INITIALIZE JDK TOOLS + javac = 'javac' + jar = 'jar' + ext = '.exe' if platform.system().lower() == 'windows' else '' + java_home = os.environ.get('JAVA_HOME') + if java_home: + javac = os.path.join(java_home, 'bin', 'javac' + ext) + if not os.path.exists(javac): + print('Error: Cannot find: ' + javac) + exit() + jar = os.path.join(java_home, 'bin', 'jar' + ext) + else: + print('Warning: environment variable JAVA_HOME wasn\'t set. Default Java compiler will be used (if any).') + + if not is_javac_available(javac): + print('Error: javac is not available') + exit() + + # CHECK JDK VERSION + jdk_version = get_jdk_version(javac) + if jdk_version < 8: + print('Error: javac version is not supported') + exit() + + # BUILD + release_flags = [] + if jdk_version > 8: + release_flags = ['--release', '8'] + + gen_headers_flags = [] + if args.headers: + headers_dir = file_dir + '/src/jni' + gen_headers_flags = ['-h', headers_dir] + + classes_dir = file_dir + '/build/classes' + makedirs(classes_dir + '/docbuilder/utils') + # build all Java classes + subprocess.call([javac, '-d', classes_dir] + release_flags + gen_headers_flags + java_files, cwd=os.getcwd(), stderr=subprocess.STDOUT) + + # PACKING TO JAR + if not args.no_jar: + os.chdir(classes_dir) + class_files = getFilesInDir('docbuilder', '.class') + class_files += getFilesInDir('docbuilder/utils', '.class') + makedirs('../libs') + subprocess.call([jar, '-cvf', '../libs/docbuilder.jar'] + class_files, cwd=os.getcwd(), stderr=subprocess.STDOUT) diff --git a/DesktopEditor/doctrenderer/docbuilder.java/src/java/docbuilder/CDocBuilder.java b/DesktopEditor/doctrenderer/docbuilder.java/src/java/docbuilder/CDocBuilder.java new file mode 100644 index 00000000000..72b14869659 --- /dev/null +++ b/DesktopEditor/doctrenderer/docbuilder.java/src/java/docbuilder/CDocBuilder.java @@ -0,0 +1,147 @@ +package docbuilder; + +import docbuilder.utils.NativeLibraryLoader; + +public class CDocBuilder { + public CDocBuilder() { + c_internal = c_Create(); + } + + protected void finalize() { + c_Destroy(c_internal); + } + + public int openFile(String path, String params) { + return c_OpenFile(c_internal, path, params); + } + + public boolean createFile(int type) { + return c_CreateFileByType(c_internal, type); + } + + public boolean createFile(String extension) { + return c_CreateFileByExtension(c_internal, extension); + } + + public void setTmpFolder(String folder) { + c_SetTmpFolder(c_internal, folder); + } + + public int saveFile(int type, String path) { + return c_SaveFileByType(c_internal, type, path); + } + + public int saveFile(int type, String path, String params) { + return c_SaveFileByTypeWithParams(c_internal, type, path, params); + } + + public int saveFile(String extension, String path) { + return c_SaveFileByExtension(c_internal, extension, path); + } + + public int saveFile(String extension, String path, String params) { + return c_SaveFileByExtensionWithParams(c_internal, extension, path, params); + } + + public void closeFile() { + c_CloseFile(c_internal); + } + + public boolean executeCommand(String command) { + return c_ExecuteCommand(c_internal, command); + } + + public boolean executeCommand(String command, CDocBuilderValue retValue) { + return c_ExecuteCommandWithRetValue(c_internal, command, retValue.c_internal); + } + + public boolean run(String path) { + return c_Run(c_internal, path); + } + + public boolean runText(String commands) { + return c_RunText(c_internal, commands); + } + + public void setProperty(String param, String value) { + c_SetProperty(c_internal, param, value); + } + + public void writeData(String path, String value, boolean append) { + c_WriteData(c_internal, path, value, append); + } + + public boolean isSaveWithDoctrendererMode() { + return c_IsSaveWithDoctrendererMode(c_internal); + } + + public String getVersion() { + return c_GetVersion(c_internal); + } + + public CDocBuilderContext getContext() { + return new CDocBuilderContext(c_GetContext(c_internal)); + } + + public CDocBuilderContext getContext(boolean enterContext) { + return new CDocBuilderContext(c_GetContextWithEnterParam(c_internal, enterContext)); + } + + public static void initialize() { + c_Initialize(); + } + + public static void initialize(String directory) { + if (directory.isEmpty()) + directory = NativeLibraryLoader.getLibPath().toString(); + c_InitializeWithDirectory(directory); + } + + public static void dispose() { + c_Dispose(); + } + + // Native code + static { + docbuilder.utils.NativeLibraryLoader.loadLibraries(); + } + + long c_internal = 0; + + private static native long c_Create(); + private static native void c_Destroy(long self); + + private static native int c_OpenFile(long self, String path, String params); + private static native boolean c_CreateFileByType(long self, int type); + private static native boolean c_CreateFileByExtension(long self, String extension); + + private static native void c_SetTmpFolder(long self, String folder); + + private static native int c_SaveFileByType(long self, int type, String path); + private static native int c_SaveFileByTypeWithParams(long self, int type, String path, String params); + private static native int c_SaveFileByExtension(long self, String extension, String path); + private static native int c_SaveFileByExtensionWithParams(long self, String extension, String path, String params); + + private static native void c_CloseFile(long self); + + private static native boolean c_ExecuteCommand(long self, String command); + private static native boolean c_ExecuteCommandWithRetValue(long self, String command, long retValue); + + private static native boolean c_Run(long self, String path); + private static native boolean c_RunText(long self, String commands); + + private static native void c_SetProperty(long self, String param, String value); + + private static native void c_WriteData(long self, String path, String value, boolean append); + + private static native boolean c_IsSaveWithDoctrendererMode(long self); + + private static native String c_GetVersion(long self); + + private static native long c_GetContext(long self); + private static native long c_GetContextWithEnterParam(long self, boolean enterContext); + + private static native void c_Initialize(); + private static native void c_InitializeWithDirectory(String directory); + private static native void c_Dispose(); +} diff --git a/DesktopEditor/doctrenderer/docbuilder.java/src/java/docbuilder/CDocBuilderContext.java b/DesktopEditor/doctrenderer/docbuilder.java/src/java/docbuilder/CDocBuilderContext.java new file mode 100644 index 00000000000..68b199f3ee9 --- /dev/null +++ b/DesktopEditor/doctrenderer/docbuilder.java/src/java/docbuilder/CDocBuilderContext.java @@ -0,0 +1,69 @@ +package docbuilder; + +public class CDocBuilderContext { + public CDocBuilderContext() { + c_internal = c_Create(); + } + + CDocBuilderContext(long internal) { + c_internal = internal; + } + + public CDocBuilderContext(CDocBuilderContext other) { + c_internal = c_Copy(other.c_internal); + } + + protected void finalize() { + c_Destroy(c_internal); + } + + public CDocBuilderValue createUndefined() { + return new CDocBuilderValue(c_CreateUndefined(c_internal)); + } + + public CDocBuilderValue createNull() { + return new CDocBuilderValue(c_CreateNull(c_internal)); + } + + public CDocBuilderValue createObject() { + return new CDocBuilderValue(c_CreateObject(c_internal)); + } + + public CDocBuilderValue createArray(int length) { + return new CDocBuilderValue(c_CreateArray(c_internal, length)); + } + + public CDocBuilderValue getGlobal() { + return new CDocBuilderValue(c_GetGlobal(c_internal)); + } + + public CDocBuilderContextScope createScope() { + return new CDocBuilderContextScope(c_CreateScope(c_internal)); + } + + public boolean isError() { + return c_IsError(c_internal); + } + + // Native code + static { + docbuilder.utils.NativeLibraryLoader.loadLibraries(); + } + + long c_internal = 0; + + private static native long c_Create(); + private static native long c_Copy(long other); + private static native void c_Destroy(long self); + + private static native long c_CreateUndefined(long self); + private static native long c_CreateNull(long self); + private static native long c_CreateObject(long self); + private static native long c_CreateArray(long self, int length); + + private static native long c_GetGlobal(long self); + + private static native long c_CreateScope(long self); + + private static native boolean c_IsError(long self); +} diff --git a/DesktopEditor/doctrenderer/docbuilder.java/src/java/docbuilder/CDocBuilderContextScope.java b/DesktopEditor/doctrenderer/docbuilder.java/src/java/docbuilder/CDocBuilderContextScope.java new file mode 100644 index 00000000000..e50742f35f1 --- /dev/null +++ b/DesktopEditor/doctrenderer/docbuilder.java/src/java/docbuilder/CDocBuilderContextScope.java @@ -0,0 +1,36 @@ +package docbuilder; + +public class CDocBuilderContextScope { + public CDocBuilderContextScope() { + c_internal = c_Create(); + } + + CDocBuilderContextScope(long internal) { + c_internal = internal; + } + + public CDocBuilderContextScope(CDocBuilderContextScope other) { + c_internal = c_Copy(other.c_internal); + } + + protected void finalize() { + c_Destroy(c_internal); + } + + public void close() { + c_Close(c_internal); + } + + // Native code + static { + docbuilder.utils.NativeLibraryLoader.loadLibraries(); + } + + long c_internal = 0; + + private static native long c_Create(); + private static native long c_Copy(long other); + private static native void c_Destroy(long self); + + private static native void c_Close(long self); +} diff --git a/DesktopEditor/doctrenderer/docbuilder.java/src/java/docbuilder/CDocBuilderValue.java b/DesktopEditor/doctrenderer/docbuilder.java/src/java/docbuilder/CDocBuilderValue.java new file mode 100644 index 00000000000..a1c49361ba4 --- /dev/null +++ b/DesktopEditor/doctrenderer/docbuilder.java/src/java/docbuilder/CDocBuilderValue.java @@ -0,0 +1,284 @@ +package docbuilder; + +public class CDocBuilderValue { + public CDocBuilderValue() { + c_internal = c_Create(); + } + + CDocBuilderValue(long internal) { + c_internal = internal; + } + + public CDocBuilderValue(CDocBuilderValue other) { + c_internal = c_Copy(other.c_internal); + } + + protected void finalize() + { + c_Destroy(c_internal); + } + + public boolean isEmpty() + { + return c_IsEmpty(c_internal); + } + + public void clear() + { + c_Clear(c_internal); + } + + public boolean isNull() + { + return c_IsNull(c_internal); + } + + public boolean isUndefined() + { + return c_IsUndefined(c_internal); + } + + public boolean isBool() + { + return c_IsBool(c_internal); + } + + public boolean isInt() + { + return c_IsInt(c_internal); + } + + public boolean isDouble() + { + return c_IsDouble(c_internal); + } + + public boolean isString() + { + return c_IsString(c_internal); + } + + public boolean isFunction() + { + return c_IsFunction(c_internal); + } + + public boolean isObject() + { + return c_IsObject(c_internal); + } + + public boolean isArray() + { + return c_IsArray(c_internal); + } + + public int getLength() + { + return c_GetLength(c_internal); + } + + public boolean toBool() + { + return c_ToBool(c_internal); + } + + public int toInt() + { + return c_ToInt(c_internal); + } + + public double toDouble() + { + return c_ToDouble(c_internal); + } + + public String toString() + { + return c_ToString(c_internal); + } + + public CDocBuilderValue getProperty(String name) { + return new CDocBuilderValue(c_GetProperty(c_internal, name)); + } + + public CDocBuilderValue get(String name) { + return new CDocBuilderValue(c_GetProperty(c_internal, name)); + } + + public CDocBuilderValue get(int index) { + return new CDocBuilderValue(c_GetByIndex(c_internal, index)); + } + + public void setProperty(String name, Object value) { + CDocBuilderValue docBuilderValue = getValueFromObject(value); + c_SetProperty(c_internal, name, docBuilderValue.c_internal); + } + + public void set(String name, Object value) { + CDocBuilderValue docBuilderValue = getValueFromObject(value); + c_SetProperty(c_internal, name, docBuilderValue.c_internal); + } + + public void set(int index, Object value) { + CDocBuilderValue docBuilderValue = getValueFromObject(value); + c_SetByIndex(c_internal, index, docBuilderValue.c_internal); + } + + public CDocBuilderValue(boolean value) { + c_internal = c_CreateWithBool(value); + } + + public CDocBuilderValue(int value) { + c_internal = c_CreateWithInt(value); + } + + public CDocBuilderValue(double value) { + c_internal = c_CreateWithDouble(value); + } + + public CDocBuilderValue(String value) { + c_internal = c_CreateWithString(value); + } + + public CDocBuilderValue(Object[] values) { + int length = values.length; + c_internal = c_CreateArray(length); + for (int i = 0; i < length; i++) { + this.set(i, getValueFromObject(values[i])); + } + } + + static CDocBuilderValue getValueFromObject(Object obj) { + if (obj instanceof CDocBuilderValue) { + return (CDocBuilderValue)obj; + } else if (obj instanceof Boolean) { + return new CDocBuilderValue((Boolean)obj); + } else if (obj instanceof Integer) { + return new CDocBuilderValue((Integer)obj); + } else if (obj instanceof Double) { + return new CDocBuilderValue((Double)obj); + } else if (obj instanceof String) { + return new CDocBuilderValue((String)obj); + } else if (obj instanceof Object[]) { + return new CDocBuilderValue((Object[])obj); + } else { + throw new IllegalArgumentException("Unsupported type for CDocBuilderValue"); + } + } + + public static CDocBuilderValue createUndefined() { + return new CDocBuilderValue(c_CreateUndefined()); + } + + public static CDocBuilderValue createNull() { + return new CDocBuilderValue(c_CreateNull()); + } + + public static CDocBuilderValue createArray(int length) { + return new CDocBuilderValue(c_CreateArray(length)); + } + + public CDocBuilderValue call(String name) { + return new CDocBuilderValue(c_Call0(c_internal, name)); + } + + public CDocBuilderValue call(String name, Object p1) { + CDocBuilderValue pValue1 = getValueFromObject(p1); + return new CDocBuilderValue(c_Call1(c_internal, name, pValue1.c_internal)); + } + + public CDocBuilderValue call(String name, Object p1, Object p2) { + CDocBuilderValue pValue1 = getValueFromObject(p1); + CDocBuilderValue pValue2 = getValueFromObject(p2); + return new CDocBuilderValue(c_Call2(c_internal, name, pValue1.c_internal, pValue2.c_internal)); + } + + public CDocBuilderValue call(String name, Object p1, Object p2, Object p3) { + CDocBuilderValue pValue1 = getValueFromObject(p1); + CDocBuilderValue pValue2 = getValueFromObject(p2); + CDocBuilderValue pValue3 = getValueFromObject(p3); + return new CDocBuilderValue(c_Call3(c_internal, name, pValue1.c_internal, pValue2.c_internal, pValue3.c_internal)); + } + + public CDocBuilderValue call(String name, Object p1, Object p2, Object p3, Object p4) { + CDocBuilderValue pValue1 = getValueFromObject(p1); + CDocBuilderValue pValue2 = getValueFromObject(p2); + CDocBuilderValue pValue3 = getValueFromObject(p3); + CDocBuilderValue pValue4 = getValueFromObject(p4); + return new CDocBuilderValue(c_Call4(c_internal, name, pValue1.c_internal, pValue2.c_internal, pValue3.c_internal, pValue4.c_internal)); + } + + public CDocBuilderValue call(String name, Object p1, Object p2, Object p3, Object p4, Object p5) { + CDocBuilderValue pValue1 = getValueFromObject(p1); + CDocBuilderValue pValue2 = getValueFromObject(p2); + CDocBuilderValue pValue3 = getValueFromObject(p3); + CDocBuilderValue pValue4 = getValueFromObject(p4); + CDocBuilderValue pValue5 = getValueFromObject(p5); + return new CDocBuilderValue(c_Call5(c_internal, name, pValue1.c_internal, pValue2.c_internal, pValue3.c_internal, pValue4.c_internal, pValue5.c_internal)); + } + + public CDocBuilderValue call(String name, Object p1, Object p2, Object p3, Object p4, Object p5, Object p6) { + CDocBuilderValue pValue1 = getValueFromObject(p1); + CDocBuilderValue pValue2 = getValueFromObject(p2); + CDocBuilderValue pValue3 = getValueFromObject(p3); + CDocBuilderValue pValue4 = getValueFromObject(p4); + CDocBuilderValue pValue5 = getValueFromObject(p5); + CDocBuilderValue pValue6 = getValueFromObject(p6); + return new CDocBuilderValue(c_Call6(c_internal, name, pValue1.c_internal, pValue2.c_internal, pValue3.c_internal, pValue4.c_internal, pValue5.c_internal, pValue6.c_internal)); + } + + // Native code + static { + docbuilder.utils.NativeLibraryLoader.loadLibraries(); + } + + long c_internal = 0; + + private static native long c_Create(); + private static native long c_Copy(long other); + private static native void c_Destroy(long self); + + private static native boolean c_IsEmpty(long self); + private static native void c_Clear(long self); + + private static native boolean c_IsNull(long self); + private static native boolean c_IsUndefined(long self); + private static native boolean c_IsBool(long self); + private static native boolean c_IsInt(long self); + private static native boolean c_IsDouble(long self); + private static native boolean c_IsString(long self); + private static native boolean c_IsFunction(long self); + private static native boolean c_IsObject(long self); + private static native boolean c_IsArray(long self); + + private static native int c_GetLength(long self); + + private static native boolean c_ToBool(long self); + private static native int c_ToInt(long self); + private static native double c_ToDouble(long self); + private static native String c_ToString(long self); + + private static native long c_GetProperty(long self, String name); + private static native long c_GetByIndex(long self, int index); + + private static native void c_SetProperty(long self, String name, long value); + private static native void c_SetByIndex(long self, int index, long value); + + private static native long c_CreateWithBool(boolean value); + private static native long c_CreateWithInt(int value); + private static native long c_CreateWithDouble(double value); + private static native long c_CreateWithString(String value); + + private static native long c_CreateUndefined(); + private static native long c_CreateNull(); + private static native long c_CreateArray(int length); + + private static native long c_Call0(long self, String name); + private static native long c_Call1(long self, String name, long p1); + private static native long c_Call2(long self, String name, long p1, long p2); + private static native long c_Call3(long self, String name, long p1, long p2, long p3); + private static native long c_Call4(long self, String name, long p1, long p2, long p3, long p4); + private static native long c_Call5(long self, String name, long p1, long p2, long p3, long p4, long p5); + private static native long c_Call6(long self, String name, long p1, long p2, long p3, long p4, long p5, long p6); +} diff --git a/DesktopEditor/doctrenderer/docbuilder.java/src/java/docbuilder/FileTypes.java b/DesktopEditor/doctrenderer/docbuilder.java/src/java/docbuilder/FileTypes.java new file mode 100644 index 00000000000..138248181b5 --- /dev/null +++ b/DesktopEditor/doctrenderer/docbuilder.java/src/java/docbuilder/FileTypes.java @@ -0,0 +1,47 @@ +package docbuilder; + +public class FileTypes { + public class Document { + private static final int MASK = 0x0040; + public static final int DOCX = MASK + 0x0001; + public static final int DOC = MASK + 0x0002; + public static final int ODT = MASK + 0x0003; + public static final int RTF = MASK + 0x0004; + public static final int TXT = MASK + 0x0005; + public static final int DOTX = MASK + 0x000c; + public static final int OTT = MASK + 0x000f; + public static final int HTML = MASK + 0x0012; + public static final int OFORM_PDF = MASK + 0x0017; + } + + public class Presentation { + private static final int MASK = 0x0080; + public static final int PPTX = MASK + 0x0001; + public static final int PPT = MASK + 0x0002; + public static final int ODP = MASK + 0x0003; + public static final int PPSX = MASK + 0x0004; + public static final int POTX = MASK + 0x0007; + public static final int OTP = MASK + 0x000a; + } + + public class Spreadsheet { + private static final int MASK = 0x0100; + public static final int XLSX = MASK + 0x0001; + public static final int XLS = MASK + 0x0002; + public static final int ODS = MASK + 0x0003; + public static final int CSV = MASK + 0x0004; + public static final int XLTX = MASK + 0x0006; + public static final int OTS = MASK + 0x0009; + } + + public class Graphics { + private static final int PDF_MASK = 0x0200; + public static final int PDF = PDF_MASK + 0x0001; + public static final int PDFA = PDF_MASK + 0x0009; + + private static final int IMAGE_MASK = 0x0400; + public static final int JPG = IMAGE_MASK + 0x0001; + public static final int PNG = IMAGE_MASK + 0x0005; + public static final int BMP = IMAGE_MASK + 0x0008; + } +} diff --git a/DesktopEditor/doctrenderer/docbuilder.java/src/java/docbuilder/utils/NativeLibraryLoader.java b/DesktopEditor/doctrenderer/docbuilder.java/src/java/docbuilder/utils/NativeLibraryLoader.java new file mode 100644 index 00000000000..d4fede06874 --- /dev/null +++ b/DesktopEditor/doctrenderer/docbuilder.java/src/java/docbuilder/utils/NativeLibraryLoader.java @@ -0,0 +1,86 @@ +package docbuilder.utils; + +import java.io.File; +import java.net.URISyntaxException; +import java.net.URL; +import java.nio.file.Path; + +public class NativeLibraryLoader { + // helper class for retrieving information about current OS + public static class OSChecker { + private static String osName = System.getProperty("os.name").toLowerCase(); + + public static boolean isWindows() { + return (osName.indexOf("win") >= 0); + } + + public static boolean isMac() { + return (osName.indexOf("mac") >= 0); + } + + public static boolean isLinux() { + return (osName.indexOf("nix") >= 0 || osName.indexOf("nux") >= 0 || osName.indexOf("aix") > 0); + } + } + + static { + try { + Path libDirPath = getLibPath(); + // load icu libraries + if (OSChecker.isWindows()) { + System.load(libDirPath.resolve("icudt58.dll").toString()); + System.load(libDirPath.resolve("icuuc58.dll").toString()); + } else if (OSChecker.isMac()) { + System.load(libDirPath.resolve("libicudata.58.dylib").toString()); + System.load(libDirPath.resolve("libicuuc.58.dylib").toString()); + } else if (OSChecker.isLinux()) { + System.load(libDirPath.resolve("libicudata.so.58").toString()); + System.load(libDirPath.resolve("libicuuc.so.58").toString()); + } else { + throw new RuntimeException("Unsupported OS"); + } + + String[] libs = {"UnicodeConverter", "kernel", "kernel_network", "graphics", "PdfFile", "XpsFile", "DjVuFile", "DocxRenderer", "doctrenderer", "docbuilder.jni"}; + + String prefix = ""; + if (OSChecker.isMac() || OSChecker.isLinux()) { + prefix = "lib"; + } + + String extension = ""; + if (OSChecker.isWindows()) { + extension = ".dll"; + } else if (OSChecker.isMac()) { + extension = ".dylib"; + } else { + extension = ".so"; + } + + for (String lib : libs) { + System.load(libDirPath.resolve(prefix + lib + extension).toString()); + } + } catch (UnsatisfiedLinkError e) { + throw new RuntimeException("Cannot load dynamic libraries. Check if JAR file is in the same directory as all docbuilder libraries."); + } + } + + // Returns path to the directory containing current JAR + public static Path getLibPath() + { + URL url = NativeLibraryLoader.class.getProtectionDomain().getCodeSource().getLocation(); + try { + File jarFile = new File(url.toURI()); + Path jarPath = jarFile.toPath(); + Path libDirPath = jarPath.getParent(); + + return libDirPath; + } catch (URISyntaxException exception) { + // Very unlikely to be happened + throw new RuntimeException("Cannot convert URI of the NativeLibraryLoader.class to URL"); + } + } + + public static void loadLibraries() { + // No-op, just to force the class loading + } +} diff --git a/DesktopEditor/doctrenderer/docbuilder.java/src/jni/docbuilder_CDocBuilder.cpp b/DesktopEditor/doctrenderer/docbuilder.java/src/jni/docbuilder_CDocBuilder.cpp new file mode 100644 index 00000000000..52e9be8fa21 --- /dev/null +++ b/DesktopEditor/doctrenderer/docbuilder.java/src/jni/docbuilder_CDocBuilder.cpp @@ -0,0 +1,185 @@ +#include "docbuilder_CDocBuilder.h" + +#include <string> + +#include "docbuilder.h" +// for wchar_t <=> char conversion +#include "../../../../common/File.h" + +using namespace NSDoctRenderer; + +static std::wstring wstringFromJavaString(JNIEnv* env, jstring jstr) +{ + const char* strUtf = env->GetStringUTFChars(jstr, nullptr); + std::wstring wstr = NSFile::CUtf8Converter::GetUnicodeStringFromUTF8((BYTE*)strUtf, (LONG)strlen(strUtf)); + env->ReleaseStringUTFChars(jstr, strUtf); + return wstr; +} + +jlong Java_docbuilder_CDocBuilder_c_1Create(JNIEnv* env, jclass cls) +{ + return reinterpret_cast<jlong>(new CDocBuilder()); +} + +void Java_docbuilder_CDocBuilder_c_1Destroy(JNIEnv* env, jclass cls, jlong self) +{ + CDocBuilder* pSelf = reinterpret_cast<CDocBuilder*>(self); + delete pSelf; +} + +jint Java_docbuilder_CDocBuilder_c_1OpenFile(JNIEnv* env, jclass cls, jlong self, jstring path, jstring params) +{ + CDocBuilder* pSelf = reinterpret_cast<CDocBuilder*>(self); + std::wstring strPath = wstringFromJavaString(env, path); + std::wstring strParams = wstringFromJavaString(env, params); + return (jint)pSelf->OpenFile(strPath.c_str(), strParams.c_str()); +} + +jboolean Java_docbuilder_CDocBuilder_c_1CreateFileByType(JNIEnv* env, jclass cls, jlong self, jint type) +{ + CDocBuilder* pSelf = reinterpret_cast<CDocBuilder*>(self); + return (jboolean)pSelf->CreateFile((int)type); +} + +jboolean Java_docbuilder_CDocBuilder_c_1CreateFileByExtension(JNIEnv* env, jclass cls, jlong self, jstring extension) +{ + CDocBuilder* pSelf = reinterpret_cast<CDocBuilder*>(self); + std::wstring strExtension = wstringFromJavaString(env, extension); + return (jboolean)pSelf->CreateFile(strExtension.c_str()); +} + +void Java_docbuilder_CDocBuilder_c_1SetTmpFolder(JNIEnv* env, jclass cls, jlong self, jstring folder) +{ + CDocBuilder* pSelf = reinterpret_cast<CDocBuilder*>(self); + std::wstring strFolder = wstringFromJavaString(env, folder); + pSelf->SetTmpFolder(strFolder.c_str()); +} + +jint Java_docbuilder_CDocBuilder_c_1SaveFileByType(JNIEnv* env, jclass cls, jlong self, jint type, jstring path) +{ + CDocBuilder* pSelf = reinterpret_cast<CDocBuilder*>(self); + std::wstring strPath = wstringFromJavaString(env, path); + return (jint)pSelf->SaveFile((int)type, strPath.c_str()); +} + +jint Java_docbuilder_CDocBuilder_c_1SaveFileByTypeWithParams(JNIEnv* env, jclass cls, jlong self, jint type, jstring path, jstring params) +{ + CDocBuilder* pSelf = reinterpret_cast<CDocBuilder*>(self); + std::wstring strPath = wstringFromJavaString(env, path); + std::wstring strParams = wstringFromJavaString(env, params); + return (jint)pSelf->SaveFile((int)type, strPath.c_str(), strParams.c_str()); +} + +jint Java_docbuilder_CDocBuilder_c_1SaveFileByExtension(JNIEnv* env, jclass cls, jlong self, jstring extension, jstring path) +{ + CDocBuilder* pSelf = reinterpret_cast<CDocBuilder*>(self); + std::wstring strExtension = wstringFromJavaString(env, extension); + std::wstring strPath = wstringFromJavaString(env, path); + return (jint)pSelf->SaveFile(strExtension.c_str(), strPath.c_str()); +} + +jint Java_docbuilder_CDocBuilder_c_1SaveFileByExtensionWithParams(JNIEnv* env, jclass cls, jlong self, jstring extension, jstring path, jstring params) +{ + CDocBuilder* pSelf = reinterpret_cast<CDocBuilder*>(self); + std::wstring strExtension = wstringFromJavaString(env, extension); + std::wstring strPath = wstringFromJavaString(env, path); + std::wstring strParams = wstringFromJavaString(env, params); + return (jint)pSelf->SaveFile(strExtension.c_str(), strPath.c_str(), strParams.c_str()); +} + +void Java_docbuilder_CDocBuilder_c_1CloseFile(JNIEnv* env, jclass cls, jlong self) +{ + CDocBuilder* pSelf = reinterpret_cast<CDocBuilder*>(self); + pSelf->CloseFile(); +} + +jboolean Java_docbuilder_CDocBuilder_c_1ExecuteCommand(JNIEnv* env, jclass cls, jlong self, jstring command) +{ + CDocBuilder* pSelf = reinterpret_cast<CDocBuilder*>(self); + std::wstring strCommand = wstringFromJavaString(env, command); + return (jboolean)pSelf->ExecuteCommand(strCommand.c_str()); +} + +jboolean Java_docbuilder_CDocBuilder_c_1ExecuteCommandWithRetValue(JNIEnv* env, jclass cls, jlong self, jstring command, jlong retValue) +{ + CDocBuilder* pSelf = reinterpret_cast<CDocBuilder*>(self); + std::wstring strCommand = wstringFromJavaString(env, command); + CDocBuilderValue* pRetValue = reinterpret_cast<CDocBuilderValue*>(retValue); + return (jboolean)pSelf->ExecuteCommand(strCommand.c_str(), pRetValue); +} + +jboolean Java_docbuilder_CDocBuilder_c_1Run(JNIEnv* env, jclass cls, jlong self, jstring path) +{ + CDocBuilder* pSelf = reinterpret_cast<CDocBuilder*>(self); + std::wstring strPath = wstringFromJavaString(env, path); + return (jboolean)pSelf->Run(strPath.c_str()); +} + +jboolean Java_docbuilder_CDocBuilder_c_1RunText(JNIEnv* env, jclass cls, jlong self, jstring commands) +{ + CDocBuilder* pSelf = reinterpret_cast<CDocBuilder*>(self); + const char* strUtfCommands = env->GetStringUTFChars(commands, nullptr); + jboolean result = (jboolean)pSelf->RunTextA(strUtfCommands); + env->ReleaseStringUTFChars(commands, strUtfCommands); + return result; +} + +void Java_docbuilder_CDocBuilder_c_1SetProperty(JNIEnv* env, jclass cls, jlong self, jstring param, jstring value) +{ + CDocBuilder* pSelf = reinterpret_cast<CDocBuilder*>(self); + const char* strUtfParam = env->GetStringUTFChars(param, nullptr); + std::wstring strValue = wstringFromJavaString(env, value); + pSelf->SetProperty(strUtfParam, strValue.c_str()); + env->ReleaseStringUTFChars(param, strUtfParam); +} + +void Java_docbuilder_CDocBuilder_c_1WriteData(JNIEnv* env, jclass cls, jlong self, jstring path, jstring data, jboolean append) +{ + CDocBuilder* pSelf = reinterpret_cast<CDocBuilder*>(self); + std::wstring strPath = wstringFromJavaString(env, path); + std::wstring strData = wstringFromJavaString(env, data); + pSelf->WriteData(strPath.c_str(), strData.c_str(), (bool)append); +} + +jboolean Java_docbuilder_CDocBuilder_c_1IsSaveWithDoctrendererMode(JNIEnv* env, jclass cls, jlong self) +{ + CDocBuilder* pSelf = reinterpret_cast<CDocBuilder*>(self); + return (jboolean)pSelf->IsSaveWithDoctrendererMode(); +} + +jstring Java_docbuilder_CDocBuilder_c_1GetVersion(JNIEnv* env, jclass cls, jlong self) +{ + CDocBuilder* pSelf = reinterpret_cast<CDocBuilder*>(self); + char* strUtfVersion = pSelf->GetVersion(); + jstring jstrVersion = env->NewStringUTF(strUtfVersion); + delete[] strUtfVersion; + return jstrVersion; +} + +jlong Java_docbuilder_CDocBuilder_c_1GetContext(JNIEnv* env, jclass cls, jlong self) +{ + CDocBuilder* pSelf = reinterpret_cast<CDocBuilder*>(self); + return reinterpret_cast<jlong>(new CDocBuilderContext(pSelf->GetContext())); +} + +jlong Java_docbuilder_CDocBuilder_c_1GetContextWithEnterParam(JNIEnv* env, jclass cls, jlong self, jboolean enterContext) +{ + CDocBuilder* pSelf = reinterpret_cast<CDocBuilder*>(self); + return reinterpret_cast<jlong>(new CDocBuilderContext(pSelf->GetContext((bool)enterContext))); +} + +void Java_docbuilder_CDocBuilder_c_1Initialize(JNIEnv* env, jclass cls) +{ + CDocBuilder::Initialize(); +} + +void Java_docbuilder_CDocBuilder_c_1InitializeWithDirectory(JNIEnv* env, jclass cls, jstring directory) +{ + std::wstring strDirectory = wstringFromJavaString(env, directory); + CDocBuilder::Initialize(strDirectory.c_str()); +} + +void Java_docbuilder_CDocBuilder_c_1Dispose(JNIEnv* env, jclass cls) +{ + CDocBuilder::Dispose(); +} diff --git a/DesktopEditor/doctrenderer/docbuilder.java/src/jni/docbuilder_CDocBuilder.h b/DesktopEditor/doctrenderer/docbuilder.java/src/jni/docbuilder_CDocBuilder.h new file mode 100644 index 00000000000..1ea3ad5ec1f --- /dev/null +++ b/DesktopEditor/doctrenderer/docbuilder.java/src/jni/docbuilder_CDocBuilder.h @@ -0,0 +1,205 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include <jni.h> +/* Header for class docbuilder_CDocBuilder */ + +#ifndef _Included_docbuilder_CDocBuilder +#define _Included_docbuilder_CDocBuilder +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: docbuilder_CDocBuilder + * Method: c_Create + * Signature: ()J + */ +JNIEXPORT jlong JNICALL Java_docbuilder_CDocBuilder_c_1Create + (JNIEnv *, jclass); + +/* + * Class: docbuilder_CDocBuilder + * Method: c_Destroy + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_docbuilder_CDocBuilder_c_1Destroy + (JNIEnv *, jclass, jlong); + +/* + * Class: docbuilder_CDocBuilder + * Method: c_OpenFile + * Signature: (JLjava/lang/String;Ljava/lang/String;)I + */ +JNIEXPORT jint JNICALL Java_docbuilder_CDocBuilder_c_1OpenFile + (JNIEnv *, jclass, jlong, jstring, jstring); + +/* + * Class: docbuilder_CDocBuilder + * Method: c_CreateFileByType + * Signature: (JI)Z + */ +JNIEXPORT jboolean JNICALL Java_docbuilder_CDocBuilder_c_1CreateFileByType + (JNIEnv *, jclass, jlong, jint); + +/* + * Class: docbuilder_CDocBuilder + * Method: c_CreateFileByExtension + * Signature: (JLjava/lang/String;)Z + */ +JNIEXPORT jboolean JNICALL Java_docbuilder_CDocBuilder_c_1CreateFileByExtension + (JNIEnv *, jclass, jlong, jstring); + +/* + * Class: docbuilder_CDocBuilder + * Method: c_SetTmpFolder + * Signature: (JLjava/lang/String;)V + */ +JNIEXPORT void JNICALL Java_docbuilder_CDocBuilder_c_1SetTmpFolder + (JNIEnv *, jclass, jlong, jstring); + +/* + * Class: docbuilder_CDocBuilder + * Method: c_SaveFileByType + * Signature: (JILjava/lang/String;)I + */ +JNIEXPORT jint JNICALL Java_docbuilder_CDocBuilder_c_1SaveFileByType + (JNIEnv *, jclass, jlong, jint, jstring); + +/* + * Class: docbuilder_CDocBuilder + * Method: c_SaveFileByTypeWithParams + * Signature: (JILjava/lang/String;Ljava/lang/String;)I + */ +JNIEXPORT jint JNICALL Java_docbuilder_CDocBuilder_c_1SaveFileByTypeWithParams + (JNIEnv *, jclass, jlong, jint, jstring, jstring); + +/* + * Class: docbuilder_CDocBuilder + * Method: c_SaveFileByExtension + * Signature: (JLjava/lang/String;Ljava/lang/String;)I + */ +JNIEXPORT jint JNICALL Java_docbuilder_CDocBuilder_c_1SaveFileByExtension + (JNIEnv *, jclass, jlong, jstring, jstring); + +/* + * Class: docbuilder_CDocBuilder + * Method: c_SaveFileByExtensionWithParams + * Signature: (JLjava/lang/String;Ljava/lang/String;Ljava/lang/String;)I + */ +JNIEXPORT jint JNICALL Java_docbuilder_CDocBuilder_c_1SaveFileByExtensionWithParams + (JNIEnv *, jclass, jlong, jstring, jstring, jstring); + +/* + * Class: docbuilder_CDocBuilder + * Method: c_CloseFile + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_docbuilder_CDocBuilder_c_1CloseFile + (JNIEnv *, jclass, jlong); + +/* + * Class: docbuilder_CDocBuilder + * Method: c_ExecuteCommand + * Signature: (JLjava/lang/String;)Z + */ +JNIEXPORT jboolean JNICALL Java_docbuilder_CDocBuilder_c_1ExecuteCommand + (JNIEnv *, jclass, jlong, jstring); + +/* + * Class: docbuilder_CDocBuilder + * Method: c_ExecuteCommandWithRetValue + * Signature: (JLjava/lang/String;J)Z + */ +JNIEXPORT jboolean JNICALL Java_docbuilder_CDocBuilder_c_1ExecuteCommandWithRetValue + (JNIEnv *, jclass, jlong, jstring, jlong); + +/* + * Class: docbuilder_CDocBuilder + * Method: c_Run + * Signature: (JLjava/lang/String;)Z + */ +JNIEXPORT jboolean JNICALL Java_docbuilder_CDocBuilder_c_1Run + (JNIEnv *, jclass, jlong, jstring); + +/* + * Class: docbuilder_CDocBuilder + * Method: c_RunText + * Signature: (JLjava/lang/String;)Z + */ +JNIEXPORT jboolean JNICALL Java_docbuilder_CDocBuilder_c_1RunText + (JNIEnv *, jclass, jlong, jstring); + +/* + * Class: docbuilder_CDocBuilder + * Method: c_SetProperty + * Signature: (JLjava/lang/String;Ljava/lang/String;)V + */ +JNIEXPORT void JNICALL Java_docbuilder_CDocBuilder_c_1SetProperty + (JNIEnv *, jclass, jlong, jstring, jstring); + +/* + * Class: docbuilder_CDocBuilder + * Method: c_WriteData + * Signature: (JLjava/lang/String;Ljava/lang/String;Z)V + */ +JNIEXPORT void JNICALL Java_docbuilder_CDocBuilder_c_1WriteData + (JNIEnv *, jclass, jlong, jstring, jstring, jboolean); + +/* + * Class: docbuilder_CDocBuilder + * Method: c_IsSaveWithDoctrendererMode + * Signature: (J)Z + */ +JNIEXPORT jboolean JNICALL Java_docbuilder_CDocBuilder_c_1IsSaveWithDoctrendererMode + (JNIEnv *, jclass, jlong); + +/* + * Class: docbuilder_CDocBuilder + * Method: c_GetVersion + * Signature: (J)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_docbuilder_CDocBuilder_c_1GetVersion + (JNIEnv *, jclass, jlong); + +/* + * Class: docbuilder_CDocBuilder + * Method: c_GetContext + * Signature: (J)J + */ +JNIEXPORT jlong JNICALL Java_docbuilder_CDocBuilder_c_1GetContext + (JNIEnv *, jclass, jlong); + +/* + * Class: docbuilder_CDocBuilder + * Method: c_GetContextWithEnterParam + * Signature: (JZ)J + */ +JNIEXPORT jlong JNICALL Java_docbuilder_CDocBuilder_c_1GetContextWithEnterParam + (JNIEnv *, jclass, jlong, jboolean); + +/* + * Class: docbuilder_CDocBuilder + * Method: c_Initialize + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_docbuilder_CDocBuilder_c_1Initialize + (JNIEnv *, jclass); + +/* + * Class: docbuilder_CDocBuilder + * Method: c_InitializeWithDirectory + * Signature: (Ljava/lang/String;)V + */ +JNIEXPORT void JNICALL Java_docbuilder_CDocBuilder_c_1InitializeWithDirectory + (JNIEnv *, jclass, jstring); + +/* + * Class: docbuilder_CDocBuilder + * Method: c_Dispose + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_docbuilder_CDocBuilder_c_1Dispose + (JNIEnv *, jclass); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/DesktopEditor/doctrenderer/docbuilder.java/src/jni/docbuilder_CDocBuilderContext.cpp b/DesktopEditor/doctrenderer/docbuilder.java/src/jni/docbuilder_CDocBuilderContext.cpp new file mode 100644 index 00000000000..8398d14c37d --- /dev/null +++ b/DesktopEditor/doctrenderer/docbuilder.java/src/jni/docbuilder_CDocBuilderContext.cpp @@ -0,0 +1,64 @@ +#include "docbuilder_CDocBuilderContext.h" + +#include "docbuilder.h" + +using namespace NSDoctRenderer; + +jlong Java_docbuilder_CDocBuilderContext_c_1Create(JNIEnv* env, jclass cls) +{ + return reinterpret_cast<jlong>(new CDocBuilderContext()); +} + +jlong Java_docbuilder_CDocBuilderContext_c_1Copy(JNIEnv* env, jclass cls, jlong other) +{ + CDocBuilderContext* pOther = reinterpret_cast<CDocBuilderContext*>(other); + return reinterpret_cast<jlong>(new CDocBuilderContext(*pOther)); +} + +void Java_docbuilder_CDocBuilderContext_c_1Destroy(JNIEnv* env, jclass cls, jlong self) +{ + CDocBuilderContext* pSelf = reinterpret_cast<CDocBuilderContext*>(self); + delete pSelf; +} + +jlong Java_docbuilder_CDocBuilderContext_c_1CreateUndefined(JNIEnv* env, jclass cls, jlong self) +{ + CDocBuilderContext* pSelf = reinterpret_cast<CDocBuilderContext*>(self); + return reinterpret_cast<jlong>(new CDocBuilderValue(pSelf->CreateUndefined())); +} + +jlong Java_docbuilder_CDocBuilderContext_c_1CreateNull(JNIEnv* env, jclass cls, jlong self) +{ + CDocBuilderContext* pSelf = reinterpret_cast<CDocBuilderContext*>(self); + return reinterpret_cast<jlong>(new CDocBuilderValue(pSelf->CreateNull())); +} + +jlong Java_docbuilder_CDocBuilderContext_c_1CreateObject(JNIEnv* env, jclass cls, jlong self) +{ + CDocBuilderContext* pSelf = reinterpret_cast<CDocBuilderContext*>(self); + return reinterpret_cast<jlong>(new CDocBuilderValue(pSelf->CreateObject())); +} + +jlong Java_docbuilder_CDocBuilderContext_c_1CreateArray(JNIEnv* env, jclass cls, jlong self, jint length) +{ + CDocBuilderContext* pSelf = reinterpret_cast<CDocBuilderContext*>(self); + return reinterpret_cast<jlong>(new CDocBuilderValue(pSelf->CreateArray((int)length))); +} + +jlong Java_docbuilder_CDocBuilderContext_c_1GetGlobal(JNIEnv* env, jclass cls, jlong self) +{ + CDocBuilderContext* pSelf = reinterpret_cast<CDocBuilderContext*>(self); + return reinterpret_cast<jlong>(new CDocBuilderValue(pSelf->GetGlobal())); +} + +jlong Java_docbuilder_CDocBuilderContext_c_1CreateScope(JNIEnv* env, jclass cls, jlong self) +{ + CDocBuilderContext* pSelf = reinterpret_cast<CDocBuilderContext*>(self); + return reinterpret_cast<jlong>(new CDocBuilderContextScope(pSelf->CreateScope())); +} + +jboolean Java_docbuilder_CDocBuilderContext_c_1IsError(JNIEnv* env, jclass cls, jlong self) +{ + CDocBuilderContext* pSelf = reinterpret_cast<CDocBuilderContext*>(self); + return (jboolean)pSelf->IsError(); +} diff --git a/DesktopEditor/doctrenderer/docbuilder.java/src/jni/docbuilder_CDocBuilderContext.h b/DesktopEditor/doctrenderer/docbuilder.java/src/jni/docbuilder_CDocBuilderContext.h new file mode 100644 index 00000000000..43e72ee4f15 --- /dev/null +++ b/DesktopEditor/doctrenderer/docbuilder.java/src/jni/docbuilder_CDocBuilderContext.h @@ -0,0 +1,93 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include <jni.h> +/* Header for class docbuilder_CDocBuilderContext */ + +#ifndef _Included_docbuilder_CDocBuilderContext +#define _Included_docbuilder_CDocBuilderContext +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: docbuilder_CDocBuilderContext + * Method: c_Create + * Signature: ()J + */ +JNIEXPORT jlong JNICALL Java_docbuilder_CDocBuilderContext_c_1Create + (JNIEnv *, jclass); + +/* + * Class: docbuilder_CDocBuilderContext + * Method: c_Copy + * Signature: (J)J + */ +JNIEXPORT jlong JNICALL Java_docbuilder_CDocBuilderContext_c_1Copy + (JNIEnv *, jclass, jlong); + +/* + * Class: docbuilder_CDocBuilderContext + * Method: c_Destroy + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_docbuilder_CDocBuilderContext_c_1Destroy + (JNIEnv *, jclass, jlong); + +/* + * Class: docbuilder_CDocBuilderContext + * Method: c_CreateUndefined + * Signature: (J)J + */ +JNIEXPORT jlong JNICALL Java_docbuilder_CDocBuilderContext_c_1CreateUndefined + (JNIEnv *, jclass, jlong); + +/* + * Class: docbuilder_CDocBuilderContext + * Method: c_CreateNull + * Signature: (J)J + */ +JNIEXPORT jlong JNICALL Java_docbuilder_CDocBuilderContext_c_1CreateNull + (JNIEnv *, jclass, jlong); + +/* + * Class: docbuilder_CDocBuilderContext + * Method: c_CreateObject + * Signature: (J)J + */ +JNIEXPORT jlong JNICALL Java_docbuilder_CDocBuilderContext_c_1CreateObject + (JNIEnv *, jclass, jlong); + +/* + * Class: docbuilder_CDocBuilderContext + * Method: c_CreateArray + * Signature: (JI)J + */ +JNIEXPORT jlong JNICALL Java_docbuilder_CDocBuilderContext_c_1CreateArray + (JNIEnv *, jclass, jlong, jint); + +/* + * Class: docbuilder_CDocBuilderContext + * Method: c_GetGlobal + * Signature: (J)J + */ +JNIEXPORT jlong JNICALL Java_docbuilder_CDocBuilderContext_c_1GetGlobal + (JNIEnv *, jclass, jlong); + +/* + * Class: docbuilder_CDocBuilderContext + * Method: c_CreateScope + * Signature: (J)J + */ +JNIEXPORT jlong JNICALL Java_docbuilder_CDocBuilderContext_c_1CreateScope + (JNIEnv *, jclass, jlong); + +/* + * Class: docbuilder_CDocBuilderContext + * Method: c_IsError + * Signature: (J)Z + */ +JNIEXPORT jboolean JNICALL Java_docbuilder_CDocBuilderContext_c_1IsError + (JNIEnv *, jclass, jlong); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/DesktopEditor/doctrenderer/docbuilder.java/src/jni/docbuilder_CDocBuilderContextScope.cpp b/DesktopEditor/doctrenderer/docbuilder.java/src/jni/docbuilder_CDocBuilderContextScope.cpp new file mode 100644 index 00000000000..c63c69ae487 --- /dev/null +++ b/DesktopEditor/doctrenderer/docbuilder.java/src/jni/docbuilder_CDocBuilderContextScope.cpp @@ -0,0 +1,28 @@ +#include "docbuilder_CDocBuilderContextScope.h" + +#include "docbuilder.h" + +using namespace NSDoctRenderer; + +jlong Java_docbuilder_CDocBuilderContextScope_c_1Create(JNIEnv* env, jclass cls) +{ + return reinterpret_cast<jlong>(new CDocBuilderContextScope()); +} + +jlong Java_docbuilder_CDocBuilderContextScope_c_1Copy(JNIEnv* env, jclass cls, jlong other) +{ + CDocBuilderContextScope* pOther = reinterpret_cast<CDocBuilderContextScope*>(other); + return reinterpret_cast<jlong>(new CDocBuilderContextScope(*pOther)); +} + +void Java_docbuilder_CDocBuilderContextScope_c_1Destroy(JNIEnv* env, jclass cls, jlong self) +{ + CDocBuilderContextScope* pSelf = reinterpret_cast<CDocBuilderContextScope*>(self); + delete pSelf; +} + +void Java_docbuilder_CDocBuilderContextScope_c_1Close(JNIEnv* env, jclass cls, jlong self) +{ + CDocBuilderContextScope* pSelf = reinterpret_cast<CDocBuilderContextScope*>(self); + pSelf->Close(); +} diff --git a/DesktopEditor/doctrenderer/docbuilder.java/src/jni/docbuilder_CDocBuilderContextScope.h b/DesktopEditor/doctrenderer/docbuilder.java/src/jni/docbuilder_CDocBuilderContextScope.h new file mode 100644 index 00000000000..3ead55b861e --- /dev/null +++ b/DesktopEditor/doctrenderer/docbuilder.java/src/jni/docbuilder_CDocBuilderContextScope.h @@ -0,0 +1,45 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include <jni.h> +/* Header for class docbuilder_CDocBuilderContextScope */ + +#ifndef _Included_docbuilder_CDocBuilderContextScope +#define _Included_docbuilder_CDocBuilderContextScope +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: docbuilder_CDocBuilderContextScope + * Method: c_Create + * Signature: ()J + */ +JNIEXPORT jlong JNICALL Java_docbuilder_CDocBuilderContextScope_c_1Create + (JNIEnv *, jclass); + +/* + * Class: docbuilder_CDocBuilderContextScope + * Method: c_Copy + * Signature: (J)J + */ +JNIEXPORT jlong JNICALL Java_docbuilder_CDocBuilderContextScope_c_1Copy + (JNIEnv *, jclass, jlong); + +/* + * Class: docbuilder_CDocBuilderContextScope + * Method: c_Destroy + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_docbuilder_CDocBuilderContextScope_c_1Destroy + (JNIEnv *, jclass, jlong); + +/* + * Class: docbuilder_CDocBuilderContextScope + * Method: c_Close + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_docbuilder_CDocBuilderContextScope_c_1Close + (JNIEnv *, jclass, jlong); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/DesktopEditor/doctrenderer/docbuilder.java/src/jni/docbuilder_CDocBuilderValue.cpp b/DesktopEditor/doctrenderer/docbuilder.java/src/jni/docbuilder_CDocBuilderValue.cpp new file mode 100644 index 00000000000..d5bb3c18c4e --- /dev/null +++ b/DesktopEditor/doctrenderer/docbuilder.java/src/jni/docbuilder_CDocBuilderValue.cpp @@ -0,0 +1,279 @@ +#include "docbuilder_CDocBuilderValue.h" + +#include <wchar.h> + +#include "docbuilder.h" +// for wchar_t <=> char conversion +#include "../../../../common/File.h" + +using namespace NSDoctRenderer; + +jlong Java_docbuilder_CDocBuilderValue_c_1Create(JNIEnv* env, jclass cls) +{ + return reinterpret_cast<jlong>(new CDocBuilderValue()); +} + +jlong Java_docbuilder_CDocBuilderValue_c_1Copy(JNIEnv* env, jclass cls, jlong other) +{ + CDocBuilderValue* pOther = reinterpret_cast<CDocBuilderValue*>(other); + return reinterpret_cast<jlong>(new CDocBuilderValue(*pOther)); +} + +void Java_docbuilder_CDocBuilderValue_c_1Destroy(JNIEnv* env, jclass cls, jlong self) +{ + CDocBuilderValue* pSelf = reinterpret_cast<CDocBuilderValue*>(self); + delete pSelf; +} + +jboolean Java_docbuilder_CDocBuilderValue_c_1IsEmpty(JNIEnv* env, jclass cls, jlong self) +{ + CDocBuilderValue* pSelf = reinterpret_cast<CDocBuilderValue*>(self); + return (jboolean)pSelf->IsEmpty(); +} + +void Java_docbuilder_CDocBuilderValue_c_1Clear(JNIEnv* env, jclass cls, jlong self) +{ + CDocBuilderValue* pSelf = reinterpret_cast<CDocBuilderValue*>(self); + pSelf->Clear(); +} + +jboolean Java_docbuilder_CDocBuilderValue_c_1IsNull(JNIEnv* env, jclass cls, jlong self) +{ + CDocBuilderValue* pSelf = reinterpret_cast<CDocBuilderValue*>(self); + return (jboolean)pSelf->IsNull(); +} + +jboolean Java_docbuilder_CDocBuilderValue_c_1IsUndefined(JNIEnv* env, jclass cls, jlong self) +{ + CDocBuilderValue* pSelf = reinterpret_cast<CDocBuilderValue*>(self); + return (jboolean)pSelf->IsUndefined(); +} + +jboolean Java_docbuilder_CDocBuilderValue_c_1IsBool(JNIEnv* env, jclass cls, jlong self) +{ + CDocBuilderValue* pSelf = reinterpret_cast<CDocBuilderValue*>(self); + return (jboolean)pSelf->IsBool(); +} + +jboolean Java_docbuilder_CDocBuilderValue_c_1IsInt(JNIEnv* env, jclass cls, jlong self) +{ + CDocBuilderValue* pSelf = reinterpret_cast<CDocBuilderValue*>(self); + return (jboolean)pSelf->IsInt(); +} + +jboolean Java_docbuilder_CDocBuilderValue_c_1IsDouble(JNIEnv* env, jclass cls, jlong self) +{ + CDocBuilderValue* pSelf = reinterpret_cast<CDocBuilderValue*>(self); + return (jboolean)pSelf->IsDouble(); +} + +jboolean Java_docbuilder_CDocBuilderValue_c_1IsString(JNIEnv* env, jclass cls, jlong self) +{ + CDocBuilderValue* pSelf = reinterpret_cast<CDocBuilderValue*>(self); + return (jboolean)pSelf->IsString(); +} + +jboolean Java_docbuilder_CDocBuilderValue_c_1IsFunction(JNIEnv* env, jclass cls, jlong self) +{ + CDocBuilderValue* pSelf = reinterpret_cast<CDocBuilderValue*>(self); + return (jboolean)pSelf->IsFunction(); +} + +jboolean Java_docbuilder_CDocBuilderValue_c_1IsObject(JNIEnv* env, jclass cls, jlong self) +{ + CDocBuilderValue* pSelf = reinterpret_cast<CDocBuilderValue*>(self); + return (jboolean)pSelf->IsObject(); +} + +jboolean Java_docbuilder_CDocBuilderValue_c_1IsArray(JNIEnv* env, jclass cls, jlong self) +{ + CDocBuilderValue* pSelf = reinterpret_cast<CDocBuilderValue*>(self); + return (jboolean)pSelf->IsArray(); +} + +jint Java_docbuilder_CDocBuilderValue_c_1GetLength(JNIEnv* env, jclass cls, jlong self) +{ + CDocBuilderValue* pSelf = reinterpret_cast<CDocBuilderValue*>(self); + return (jint)pSelf->GetLength(); +} + +jboolean Java_docbuilder_CDocBuilderValue_c_1ToBool(JNIEnv* env, jclass cls, jlong self) +{ + CDocBuilderValue* pSelf = reinterpret_cast<CDocBuilderValue*>(self); + return (jboolean)pSelf->ToBool(); +} + +jint Java_docbuilder_CDocBuilderValue_c_1ToInt(JNIEnv* env, jclass cls, jlong self) +{ + CDocBuilderValue* pSelf = reinterpret_cast<CDocBuilderValue*>(self); + return (jint)pSelf->ToInt(); +} + +jdouble Java_docbuilder_CDocBuilderValue_c_1ToDouble(JNIEnv* env, jclass cls, jlong self) +{ + CDocBuilderValue* pSelf = reinterpret_cast<CDocBuilderValue*>(self); + return (jdouble)pSelf->ToDouble(); +} + +jstring Java_docbuilder_CDocBuilderValue_c_1ToString(JNIEnv* env, jclass cls, jlong self) +{ + CDocBuilderValue* pSelf = reinterpret_cast<CDocBuilderValue*>(self); + CString strValue = pSelf->ToString(); + std::string strUtfData = NSFile::CUtf8Converter::GetUtf8StringFromUnicode2(strValue.c_str(), (LONG)wcslen(strValue.c_str())); + return env->NewStringUTF(strUtfData.c_str()); +} + +jlong Java_docbuilder_CDocBuilderValue_c_1GetProperty(JNIEnv* env, jclass cls, jlong self, jstring name) +{ + CDocBuilderValue* pSelf = reinterpret_cast<CDocBuilderValue*>(self); + const char* strUtfName = env->GetStringUTFChars(name, nullptr); + CDocBuilderValue* pValue = new CDocBuilderValue(pSelf->Get(strUtfName)); + env->ReleaseStringUTFChars(name, strUtfName); + return reinterpret_cast<jlong>(pValue); +} + +jlong Java_docbuilder_CDocBuilderValue_c_1GetByIndex(JNIEnv* env, jclass cls, jlong self, jint index) +{ + CDocBuilderValue* pSelf = reinterpret_cast<CDocBuilderValue*>(self); + CDocBuilderValue* pValue = new CDocBuilderValue(pSelf->Get((int)index)); + return reinterpret_cast<jlong>(pValue); +} + +void Java_docbuilder_CDocBuilderValue_c_1SetProperty(JNIEnv* env, jclass cls, jlong self, jstring name, jlong value) +{ + CDocBuilderValue* pSelf = reinterpret_cast<CDocBuilderValue*>(self); + CDocBuilderValue* pValue = reinterpret_cast<CDocBuilderValue*>(value); + const char* strUtfName = env->GetStringUTFChars(name, nullptr); + std::wstring strName = NSFile::CUtf8Converter::GetUnicodeStringFromUTF8((BYTE*)strUtfName, (LONG)strlen(strUtfName)); + pSelf->Set(strName.c_str(), *pValue); + env->ReleaseStringUTFChars(name, strUtfName); +} + +void Java_docbuilder_CDocBuilderValue_c_1SetByIndex(JNIEnv* env, jclass cls, jlong self, jint index, jlong value) +{ + CDocBuilderValue* pSelf = reinterpret_cast<CDocBuilderValue*>(self); + CDocBuilderValue* pValue = reinterpret_cast<CDocBuilderValue*>(value); + pSelf->Set((int)index, *pValue); +} + +jlong Java_docbuilder_CDocBuilderValue_c_1CreateWithBool(JNIEnv* env, jclass cls, jboolean value) +{ + return reinterpret_cast<jlong>(new CDocBuilderValue((bool)value)); +} + +jlong Java_docbuilder_CDocBuilderValue_c_1CreateWithInt(JNIEnv* env, jclass cls, jint value) +{ + return reinterpret_cast<jlong>(new CDocBuilderValue((int)value)); +} + +jlong Java_docbuilder_CDocBuilderValue_c_1CreateWithDouble(JNIEnv* env, jclass cls, jdouble value) +{ + return reinterpret_cast<jlong>(new CDocBuilderValue((double)value)); +} + +jlong Java_docbuilder_CDocBuilderValue_c_1CreateWithString(JNIEnv* env, jclass cls, jstring str) +{ + const char* strUtf = env->GetStringUTFChars(str, nullptr); + CDocBuilderValue* pValue = new CDocBuilderValue(strUtf); + env->ReleaseStringUTFChars(str, strUtf); + return reinterpret_cast<jlong>(pValue); +} + +jlong Java_docbuilder_CDocBuilderValue_c_1CreateUndefined(JNIEnv* env, jclass cls) +{ + return reinterpret_cast<jlong>(new CDocBuilderValue(CDocBuilderValue::CreateUndefined())); +} + +jlong Java_docbuilder_CDocBuilderValue_c_1CreateNull(JNIEnv* env, jclass cls) +{ + return reinterpret_cast<jlong>(new CDocBuilderValue(CDocBuilderValue::CreateNull())); +} + +jlong Java_docbuilder_CDocBuilderValue_c_1CreateArray(JNIEnv* env, jclass cls, jint length) +{ + return reinterpret_cast<jlong>(new CDocBuilderValue(CDocBuilderValue::CreateArray((int)length))); +} + +jlong Java_docbuilder_CDocBuilderValue_c_1Call0(JNIEnv* env, jclass cls, jlong self, jstring name) +{ + CDocBuilderValue* pSelf = reinterpret_cast<CDocBuilderValue*>(self); + const char* strUtfName = env->GetStringUTFChars(name, nullptr); + CDocBuilderValue* pReturnValue = new CDocBuilderValue(pSelf->Call(strUtfName)); + env->ReleaseStringUTFChars(name, strUtfName); + return reinterpret_cast<jlong>(pReturnValue); +} + +jlong Java_docbuilder_CDocBuilderValue_c_1Call1(JNIEnv* env, jclass cls, jlong self, jstring name, jlong p1) +{ + CDocBuilderValue* pSelf = reinterpret_cast<CDocBuilderValue*>(self); + CDocBuilderValue* pParam1 = reinterpret_cast<CDocBuilderValue*>(p1); + const char* strUtfName = env->GetStringUTFChars(name, nullptr); + CDocBuilderValue* pReturnValue = new CDocBuilderValue(pSelf->Call(strUtfName, *pParam1)); + env->ReleaseStringUTFChars(name, strUtfName); + return reinterpret_cast<jlong>(pReturnValue); +} + +jlong Java_docbuilder_CDocBuilderValue_c_1Call2(JNIEnv* env, jclass cls, jlong self, jstring name, jlong p1, jlong p2) +{ + CDocBuilderValue* pSelf = reinterpret_cast<CDocBuilderValue*>(self); + CDocBuilderValue* pParam1 = reinterpret_cast<CDocBuilderValue*>(p1); + CDocBuilderValue* pParam2 = reinterpret_cast<CDocBuilderValue*>(p2); + const char* strUtfName = env->GetStringUTFChars(name, nullptr); + CDocBuilderValue* pReturnValue = new CDocBuilderValue(pSelf->Call(strUtfName, *pParam1, *pParam2)); + env->ReleaseStringUTFChars(name, strUtfName); + return reinterpret_cast<jlong>(pReturnValue); +} + +jlong Java_docbuilder_CDocBuilderValue_c_1Call3(JNIEnv* env, jclass cls, jlong self, jstring name, jlong p1, jlong p2, jlong p3) +{ + CDocBuilderValue* pSelf = reinterpret_cast<CDocBuilderValue*>(self); + CDocBuilderValue* pParam1 = reinterpret_cast<CDocBuilderValue*>(p1); + CDocBuilderValue* pParam2 = reinterpret_cast<CDocBuilderValue*>(p2); + CDocBuilderValue* pParam3 = reinterpret_cast<CDocBuilderValue*>(p3); + const char* strUtfName = env->GetStringUTFChars(name, nullptr); + CDocBuilderValue* pReturnValue = new CDocBuilderValue(pSelf->Call(strUtfName, *pParam1, *pParam2, *pParam3)); + env->ReleaseStringUTFChars(name, strUtfName); + return reinterpret_cast<jlong>(pReturnValue); +} + +jlong Java_docbuilder_CDocBuilderValue_c_1Call4(JNIEnv* env, jclass cls, jlong self, jstring name, jlong p1, jlong p2, jlong p3, jlong p4) +{ + CDocBuilderValue* pSelf = reinterpret_cast<CDocBuilderValue*>(self); + CDocBuilderValue* pParam1 = reinterpret_cast<CDocBuilderValue*>(p1); + CDocBuilderValue* pParam2 = reinterpret_cast<CDocBuilderValue*>(p2); + CDocBuilderValue* pParam3 = reinterpret_cast<CDocBuilderValue*>(p3); + CDocBuilderValue* pParam4 = reinterpret_cast<CDocBuilderValue*>(p4); + const char* strUtfName = env->GetStringUTFChars(name, nullptr); + CDocBuilderValue* pReturnValue = new CDocBuilderValue(pSelf->Call(strUtfName, *pParam1, *pParam2, *pParam3, *pParam4)); + env->ReleaseStringUTFChars(name, strUtfName); + return reinterpret_cast<jlong>(pReturnValue); +} + +jlong Java_docbuilder_CDocBuilderValue_c_1Call5(JNIEnv* env, jclass cls, jlong self, jstring name, jlong p1, jlong p2, jlong p3, jlong p4, jlong p5) +{ + CDocBuilderValue* pSelf = reinterpret_cast<CDocBuilderValue*>(self); + CDocBuilderValue* pParam1 = reinterpret_cast<CDocBuilderValue*>(p1); + CDocBuilderValue* pParam2 = reinterpret_cast<CDocBuilderValue*>(p2); + CDocBuilderValue* pParam3 = reinterpret_cast<CDocBuilderValue*>(p3); + CDocBuilderValue* pParam4 = reinterpret_cast<CDocBuilderValue*>(p4); + CDocBuilderValue* pParam5 = reinterpret_cast<CDocBuilderValue*>(p5); + const char* strUtfName = env->GetStringUTFChars(name, nullptr); + CDocBuilderValue* pReturnValue = new CDocBuilderValue(pSelf->Call(strUtfName, *pParam1, *pParam2, *pParam3, *pParam4, *pParam5)); + env->ReleaseStringUTFChars(name, strUtfName); + return reinterpret_cast<jlong>(pReturnValue); +} + +jlong Java_docbuilder_CDocBuilderValue_c_1Call6(JNIEnv* env, jclass cls, jlong self, jstring name, jlong p1, jlong p2, jlong p3, jlong p4, jlong p5, jlong p6) +{ + CDocBuilderValue* pSelf = reinterpret_cast<CDocBuilderValue*>(self); + CDocBuilderValue* pParam1 = reinterpret_cast<CDocBuilderValue*>(p1); + CDocBuilderValue* pParam2 = reinterpret_cast<CDocBuilderValue*>(p2); + CDocBuilderValue* pParam3 = reinterpret_cast<CDocBuilderValue*>(p3); + CDocBuilderValue* pParam4 = reinterpret_cast<CDocBuilderValue*>(p4); + CDocBuilderValue* pParam5 = reinterpret_cast<CDocBuilderValue*>(p5); + CDocBuilderValue* pParam6 = reinterpret_cast<CDocBuilderValue*>(p6); + const char* strUtfName = env->GetStringUTFChars(name, nullptr); + CDocBuilderValue* pReturnValue = new CDocBuilderValue(pSelf->Call(strUtfName, *pParam1, *pParam2, *pParam3, *pParam4, *pParam5, *pParam6)); + env->ReleaseStringUTFChars(name, strUtfName); + return reinterpret_cast<jlong>(pReturnValue); +} diff --git a/DesktopEditor/doctrenderer/docbuilder.java/src/jni/docbuilder_CDocBuilderValue.h b/DesktopEditor/doctrenderer/docbuilder.java/src/jni/docbuilder_CDocBuilderValue.h new file mode 100644 index 00000000000..32d0018345a --- /dev/null +++ b/DesktopEditor/doctrenderer/docbuilder.java/src/jni/docbuilder_CDocBuilderValue.h @@ -0,0 +1,309 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include <jni.h> +/* Header for class docbuilder_CDocBuilderValue */ + +#ifndef _Included_docbuilder_CDocBuilderValue +#define _Included_docbuilder_CDocBuilderValue +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: docbuilder_CDocBuilderValue + * Method: c_Create + * Signature: ()J + */ +JNIEXPORT jlong JNICALL Java_docbuilder_CDocBuilderValue_c_1Create + (JNIEnv *, jclass); + +/* + * Class: docbuilder_CDocBuilderValue + * Method: c_Copy + * Signature: (J)J + */ +JNIEXPORT jlong JNICALL Java_docbuilder_CDocBuilderValue_c_1Copy + (JNIEnv *, jclass, jlong); + +/* + * Class: docbuilder_CDocBuilderValue + * Method: c_Destroy + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_docbuilder_CDocBuilderValue_c_1Destroy + (JNIEnv *, jclass, jlong); + +/* + * Class: docbuilder_CDocBuilderValue + * Method: c_IsEmpty + * Signature: (J)Z + */ +JNIEXPORT jboolean JNICALL Java_docbuilder_CDocBuilderValue_c_1IsEmpty + (JNIEnv *, jclass, jlong); + +/* + * Class: docbuilder_CDocBuilderValue + * Method: c_Clear + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_docbuilder_CDocBuilderValue_c_1Clear + (JNIEnv *, jclass, jlong); + +/* + * Class: docbuilder_CDocBuilderValue + * Method: c_IsNull + * Signature: (J)Z + */ +JNIEXPORT jboolean JNICALL Java_docbuilder_CDocBuilderValue_c_1IsNull + (JNIEnv *, jclass, jlong); + +/* + * Class: docbuilder_CDocBuilderValue + * Method: c_IsUndefined + * Signature: (J)Z + */ +JNIEXPORT jboolean JNICALL Java_docbuilder_CDocBuilderValue_c_1IsUndefined + (JNIEnv *, jclass, jlong); + +/* + * Class: docbuilder_CDocBuilderValue + * Method: c_IsBool + * Signature: (J)Z + */ +JNIEXPORT jboolean JNICALL Java_docbuilder_CDocBuilderValue_c_1IsBool + (JNIEnv *, jclass, jlong); + +/* + * Class: docbuilder_CDocBuilderValue + * Method: c_IsInt + * Signature: (J)Z + */ +JNIEXPORT jboolean JNICALL Java_docbuilder_CDocBuilderValue_c_1IsInt + (JNIEnv *, jclass, jlong); + +/* + * Class: docbuilder_CDocBuilderValue + * Method: c_IsDouble + * Signature: (J)Z + */ +JNIEXPORT jboolean JNICALL Java_docbuilder_CDocBuilderValue_c_1IsDouble + (JNIEnv *, jclass, jlong); + +/* + * Class: docbuilder_CDocBuilderValue + * Method: c_IsString + * Signature: (J)Z + */ +JNIEXPORT jboolean JNICALL Java_docbuilder_CDocBuilderValue_c_1IsString + (JNIEnv *, jclass, jlong); + +/* + * Class: docbuilder_CDocBuilderValue + * Method: c_IsFunction + * Signature: (J)Z + */ +JNIEXPORT jboolean JNICALL Java_docbuilder_CDocBuilderValue_c_1IsFunction + (JNIEnv *, jclass, jlong); + +/* + * Class: docbuilder_CDocBuilderValue + * Method: c_IsObject + * Signature: (J)Z + */ +JNIEXPORT jboolean JNICALL Java_docbuilder_CDocBuilderValue_c_1IsObject + (JNIEnv *, jclass, jlong); + +/* + * Class: docbuilder_CDocBuilderValue + * Method: c_IsArray + * Signature: (J)Z + */ +JNIEXPORT jboolean JNICALL Java_docbuilder_CDocBuilderValue_c_1IsArray + (JNIEnv *, jclass, jlong); + +/* + * Class: docbuilder_CDocBuilderValue + * Method: c_GetLength + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_docbuilder_CDocBuilderValue_c_1GetLength + (JNIEnv *, jclass, jlong); + +/* + * Class: docbuilder_CDocBuilderValue + * Method: c_ToBool + * Signature: (J)Z + */ +JNIEXPORT jboolean JNICALL Java_docbuilder_CDocBuilderValue_c_1ToBool + (JNIEnv *, jclass, jlong); + +/* + * Class: docbuilder_CDocBuilderValue + * Method: c_ToInt + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_docbuilder_CDocBuilderValue_c_1ToInt + (JNIEnv *, jclass, jlong); + +/* + * Class: docbuilder_CDocBuilderValue + * Method: c_ToDouble + * Signature: (J)D + */ +JNIEXPORT jdouble JNICALL Java_docbuilder_CDocBuilderValue_c_1ToDouble + (JNIEnv *, jclass, jlong); + +/* + * Class: docbuilder_CDocBuilderValue + * Method: c_ToString + * Signature: (J)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_docbuilder_CDocBuilderValue_c_1ToString + (JNIEnv *, jclass, jlong); + +/* + * Class: docbuilder_CDocBuilderValue + * Method: c_GetProperty + * Signature: (JLjava/lang/String;)J + */ +JNIEXPORT jlong JNICALL Java_docbuilder_CDocBuilderValue_c_1GetProperty + (JNIEnv *, jclass, jlong, jstring); + +/* + * Class: docbuilder_CDocBuilderValue + * Method: c_GetByIndex + * Signature: (JI)J + */ +JNIEXPORT jlong JNICALL Java_docbuilder_CDocBuilderValue_c_1GetByIndex + (JNIEnv *, jclass, jlong, jint); + +/* + * Class: docbuilder_CDocBuilderValue + * Method: c_SetProperty + * Signature: (JLjava/lang/String;J)V + */ +JNIEXPORT void JNICALL Java_docbuilder_CDocBuilderValue_c_1SetProperty + (JNIEnv *, jclass, jlong, jstring, jlong); + +/* + * Class: docbuilder_CDocBuilderValue + * Method: c_SetByIndex + * Signature: (JIJ)V + */ +JNIEXPORT void JNICALL Java_docbuilder_CDocBuilderValue_c_1SetByIndex + (JNIEnv *, jclass, jlong, jint, jlong); + +/* + * Class: docbuilder_CDocBuilderValue + * Method: c_CreateWithBool + * Signature: (Z)J + */ +JNIEXPORT jlong JNICALL Java_docbuilder_CDocBuilderValue_c_1CreateWithBool + (JNIEnv *, jclass, jboolean); + +/* + * Class: docbuilder_CDocBuilderValue + * Method: c_CreateWithInt + * Signature: (I)J + */ +JNIEXPORT jlong JNICALL Java_docbuilder_CDocBuilderValue_c_1CreateWithInt + (JNIEnv *, jclass, jint); + +/* + * Class: docbuilder_CDocBuilderValue + * Method: c_CreateWithDouble + * Signature: (D)J + */ +JNIEXPORT jlong JNICALL Java_docbuilder_CDocBuilderValue_c_1CreateWithDouble + (JNIEnv *, jclass, jdouble); + +/* + * Class: docbuilder_CDocBuilderValue + * Method: c_CreateWithString + * Signature: (Ljava/lang/String;)J + */ +JNIEXPORT jlong JNICALL Java_docbuilder_CDocBuilderValue_c_1CreateWithString + (JNIEnv *, jclass, jstring); + +/* + * Class: docbuilder_CDocBuilderValue + * Method: c_CreateUndefined + * Signature: ()J + */ +JNIEXPORT jlong JNICALL Java_docbuilder_CDocBuilderValue_c_1CreateUndefined + (JNIEnv *, jclass); + +/* + * Class: docbuilder_CDocBuilderValue + * Method: c_CreateNull + * Signature: ()J + */ +JNIEXPORT jlong JNICALL Java_docbuilder_CDocBuilderValue_c_1CreateNull + (JNIEnv *, jclass); + +/* + * Class: docbuilder_CDocBuilderValue + * Method: c_CreateArray + * Signature: (I)J + */ +JNIEXPORT jlong JNICALL Java_docbuilder_CDocBuilderValue_c_1CreateArray + (JNIEnv *, jclass, jint); + +/* + * Class: docbuilder_CDocBuilderValue + * Method: c_Call0 + * Signature: (JLjava/lang/String;)J + */ +JNIEXPORT jlong JNICALL Java_docbuilder_CDocBuilderValue_c_1Call0 + (JNIEnv *, jclass, jlong, jstring); + +/* + * Class: docbuilder_CDocBuilderValue + * Method: c_Call1 + * Signature: (JLjava/lang/String;J)J + */ +JNIEXPORT jlong JNICALL Java_docbuilder_CDocBuilderValue_c_1Call1 + (JNIEnv *, jclass, jlong, jstring, jlong); + +/* + * Class: docbuilder_CDocBuilderValue + * Method: c_Call2 + * Signature: (JLjava/lang/String;JJ)J + */ +JNIEXPORT jlong JNICALL Java_docbuilder_CDocBuilderValue_c_1Call2 + (JNIEnv *, jclass, jlong, jstring, jlong, jlong); + +/* + * Class: docbuilder_CDocBuilderValue + * Method: c_Call3 + * Signature: (JLjava/lang/String;JJJ)J + */ +JNIEXPORT jlong JNICALL Java_docbuilder_CDocBuilderValue_c_1Call3 + (JNIEnv *, jclass, jlong, jstring, jlong, jlong, jlong); + +/* + * Class: docbuilder_CDocBuilderValue + * Method: c_Call4 + * Signature: (JLjava/lang/String;JJJJ)J + */ +JNIEXPORT jlong JNICALL Java_docbuilder_CDocBuilderValue_c_1Call4 + (JNIEnv *, jclass, jlong, jstring, jlong, jlong, jlong, jlong); + +/* + * Class: docbuilder_CDocBuilderValue + * Method: c_Call5 + * Signature: (JLjava/lang/String;JJJJJ)J + */ +JNIEXPORT jlong JNICALL Java_docbuilder_CDocBuilderValue_c_1Call5 + (JNIEnv *, jclass, jlong, jstring, jlong, jlong, jlong, jlong, jlong); + +/* + * Class: docbuilder_CDocBuilderValue + * Method: c_Call6 + * Signature: (JLjava/lang/String;JJJJJJ)J + */ +JNIEXPORT jlong JNICALL Java_docbuilder_CDocBuilderValue_c_1Call6 + (JNIEnv *, jclass, jlong, jstring, jlong, jlong, jlong, jlong, jlong, jlong); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/DesktopEditor/doctrenderer/docbuilder.java/src/jni/docbuilder_jni.pro b/DesktopEditor/doctrenderer/docbuilder.java/src/jni/docbuilder_jni.pro new file mode 100644 index 00000000000..27db8247bf7 --- /dev/null +++ b/DesktopEditor/doctrenderer/docbuilder.java/src/jni/docbuilder_jni.pro @@ -0,0 +1,47 @@ +QT -= core +QT -= gui + +TARGET = docbuilder.jni + +TEMPLATE = lib + +CONFIG += shared +CONFIG += plugin + +CORE_ROOT_DIR = $$PWD/../../../../.. +PWD_ROOT_DIR = $$PWD + +include($$CORE_ROOT_DIR/Common/base.pri) +include($$CORE_ROOT_DIR/Common/3dParty/icu/icu.pri) + +ADD_DEPENDENCY(graphics, kernel, kernel_network, UnicodeConverter, doctrenderer) + +INCLUDEPATH += ../../.. + +# get path to JDK from environment variable JAVA_HOME (preferable way) or take the default one +JDK_PATH = $$(JAVA_HOME) +isEmpty(JDK_PATH) { + core_windows:JDK_PATH = "C:/Program Files/Java/jdk1.8.0_202" + core_linux:JDK_PATH = "/usr/lib/jvm/java-8-openjdk-amd64" + core_mac:JDK_PATH = "/Library/Java/JavaVirtualMachines/jdk-1.8.jdk/Contents/Home" +} + +INCLUDEPATH += $$JDK_PATH/include + +core_windows:JAVA_ARCH = win32 +core_linux:JAVA_ARCH = linux +core_mac:JAVA_ARCH = darwin + +INCLUDEPATH += $$JDK_PATH/include/$$JAVA_ARCH + +SOURCES += \ + docbuilder_CDocBuilderValue.cpp \ + docbuilder_CDocBuilder.cpp \ + docbuilder_CDocBuilderContextScope.cpp \ + docbuilder_CDocBuilderContext.cpp + +HEADERS += \ + docbuilder_CDocBuilderValue.h \ + docbuilder_CDocBuilder.h \ + docbuilder_CDocBuilderContextScope.h \ + docbuilder_CDocBuilderContext.h diff --git a/DesktopEditor/doctrenderer/docbuilder.java/test/Program.java b/DesktopEditor/doctrenderer/docbuilder.java/test/Program.java new file mode 100644 index 00000000000..bf1edbe86d0 --- /dev/null +++ b/DesktopEditor/doctrenderer/docbuilder.java/test/Program.java @@ -0,0 +1,43 @@ +import docbuilder.*; + +public class Program { + public static void main(String[] args) { + String resultPath = "result.docx"; + + test(resultPath); + + // Need to explicitly call System.gc() because finalizers might not automatically get called + // Note: Even System.gc() can not guarantee that finalizers will be actually called. Possible memory leaks! + System.gc(); + } + + public static void test(String resultPath) { + CDocBuilder.initialize(""); + CDocBuilder builder = new CDocBuilder(); + builder.createFile(FileTypes.Document.DOCX); + + CDocBuilderContext context = builder.getContext(); + + CDocBuilderValue global = context.getGlobal(); + + CDocBuilderValue api = global.get("Api"); + CDocBuilderValue document = api.call("GetDocument"); + CDocBuilderValue paragraph1 = api.call("CreateParagraph"); + + paragraph1.call("SetSpacingAfter", 1000, false); + paragraph1.call("AddText", "Hello from Java!"); + + CDocBuilderValue paragraph2 = api.call("CreateParagraph"); + paragraph2.call("AddText", "Goodbye!"); + + CDocBuilderValue[] paragraphs = { paragraph1, paragraph2 }; + CDocBuilderValue content = new CDocBuilderValue(paragraphs); + + document.call("InsertContent", content); + + builder.saveFile(FileTypes.Document.DOCX, resultPath); + builder.closeFile(); + + CDocBuilder.dispose(); + } +} diff --git a/DesktopEditor/doctrenderer/docbuilder.java/test/make_test.py b/DesktopEditor/doctrenderer/docbuilder.java/test/make_test.py new file mode 100644 index 00000000000..be85207716d --- /dev/null +++ b/DesktopEditor/doctrenderer/docbuilder.java/test/make_test.py @@ -0,0 +1,45 @@ +import os +import argparse +import subprocess +import platform + +# NOTE: In JDK 8 and earlier, `javac` does not create the directories specified in the -d option if they do not already exist +# So we need to create them manually +def makedirs(dir): + if not os.path.exists(dir): + os.makedirs(dir) + return + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description='Build and run the test example for docbuilder Java wrapper') + parser.add_argument('-r', '--run', dest='builder_dir', metavar='<directory>', help='Run the test example with specified docbuilder directory') + args = parser.parse_args() + + file_dir = os.path.dirname(os.path.realpath(__file__)); + os.chdir(file_dir) + + java_file = 'Program.java' + + # INITIALIZE JAVA TOOLS + javac = 'javac' + java = 'java' + ext = '.exe' if platform.system().lower() == 'windows' else '' + java_home = os.environ.get('JAVA_HOME') + if java_home: + javac = os.path.join(java_home, 'bin', 'javac' + ext) + if not os.path.exists(javac): + print('Error: Cannot find: ' + javac) + exit() + java = os.path.join(java_home, 'bin', 'java' + ext) + else: + print('Warning: environment variable JAVA_HOME wasn\'t set. Default Java compiler will be used (if any).') + + if args.builder_dir: + builder_dir = args.builder_dir + subprocess.call([java, '-cp', os.path.join(builder_dir, 'docbuilder.jar') + os.pathsep + 'build/classes', 'Program'], cwd=os.getcwd(), stderr=subprocess.STDOUT) + else: + makedirs('build/classes') + subprocess.call([javac, '-d', 'build/classes', '-cp', '../build/libs/docbuilder.jar', java_file], cwd=os.getcwd(), stderr=subprocess.STDOUT) + print('Program was built successfully') + print('Run it with: java -cp \"/path/to/docbuilder/docbuilder.jar' + os.pathsep + 'build/classes\" Program') + print('Or just run: python make_test.py --run \"/path/to/docbuilder\"') diff --git a/DesktopEditor/doctrenderer/docbuilder.net/src/docbuilder.net.cpp b/DesktopEditor/doctrenderer/docbuilder.net/src/docbuilder.net.cpp index 35668133285..e8e0fcacd5b 100644 --- a/DesktopEditor/doctrenderer/docbuilder.net/src/docbuilder.net.cpp +++ b/DesktopEditor/doctrenderer/docbuilder.net/src/docbuilder.net.cpp @@ -50,7 +50,8 @@ namespace docbuilder_net TXT = MASK + 0x0005, DOTX = MASK + 0x000c, OTT = MASK + 0x000f, - HTML = MASK + 0x0012 + HTML = MASK + 0x0012, + OFORM_PDF = MASK + 0x0017 }; public enum class Spreadsheet : int @@ -136,6 +137,10 @@ namespace docbuilder_net bool CDocBuilderValue::IsUndefined() { return m_internal->IsUndefined(); + } + bool CDocBuilderValue::IsBool() + { + return m_internal->IsBool(); } bool CDocBuilderValue::IsInt() { @@ -244,6 +249,16 @@ namespace docbuilder_net m_internal = new NSDoctRenderer::CDocBuilderValue(StringToStdString(value)); } + CDocBuilderValue::CDocBuilderValue(array<CDocBuilderValue^>^ values) + { + int length = values->Length; + m_internal = new NSDoctRenderer::CDocBuilderValue(NSDoctRenderer::CDocBuilderValue::CreateArray(length)); + for (int i = 0; i < length; i++) + { + Set(i, values[i]); + } + } + CDocBuilderValue::operator CDocBuilderValue ^ (bool value) { return gcnew CDocBuilderValue(value); @@ -265,6 +280,11 @@ namespace docbuilder_net return gcnew CDocBuilderValue(value); } + CDocBuilderValue::operator CDocBuilderValue ^ (array<CDocBuilderValue^>^ values) + { + return gcnew CDocBuilderValue(values); + } + CDocBuilderValue^ CDocBuilderValue::CreateUndefined() { CDocBuilderValue^ value = gcnew CDocBuilderValue(); @@ -522,4 +542,3 @@ namespace docbuilder_net return m_internal->IsError(); } } - diff --git a/DesktopEditor/doctrenderer/docbuilder.net/src/docbuilder.net.h b/DesktopEditor/doctrenderer/docbuilder.net/src/docbuilder.net.h index 749e66dbd48..226c4c84d71 100644 --- a/DesktopEditor/doctrenderer/docbuilder.net/src/docbuilder.net.h +++ b/DesktopEditor/doctrenderer/docbuilder.net/src/docbuilder.net.h @@ -1,559 +1,564 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2023 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ - -// docbuilder.net.h - -#include "../../docbuilder.h" - -#pragma once - -using namespace System; - -namespace docbuilder_net -{ - ref class CDocBuilderValue; - ref class CDocBuilder; - ref class CDocBuilderContextScope; - ref class CDocBuilderContext; - - /// <summary> - /// Class for getting the results of called JS commands. - /// It represents a wrapper for a JS object. - /// </summary> - public ref class CDocBuilderValue - { - public: - CDocBuilderValue(); - CDocBuilderValue(const CDocBuilderValue% other); - ~CDocBuilderValue(); - - protected: - !CDocBuilderValue(); - - public: - /// <returns> True if this object is empty. </returns> - bool IsEmpty(); - - /// <summary> Clears the object. </summary> - void Clear(); - - /// <returns> True if this object is null. </returns> - bool IsNull(); - - /// <returns> True if this object is undefined. </returns> - bool IsUndefined(); - - /// <returns> True if this object is an integer. </returns> - bool IsInt(); - - /// <returns> True if this object is a double value. </returns> - bool IsDouble(); - - /// <returns> True if this object is a string. </returns> - bool IsString(); - - /// <returns> True if this object is a function. </returns> - bool IsFunction(); - - /// <returns> True if this object is an object. </returns> - bool IsObject(); - - /// <returns> True if this object is an array. </returns> - bool IsArray(); - - /// <returns> True if this object is a typed array. </returns> - bool IsTypedArray(); - - - /// <returns> The length if this object is an array/typed array. Otherwise, returns 0. </returns> - unsigned int GetLength(); - - - /// <summary> Converts this object to a boolean value. </summary> - bool ToBool(); - - /// <summary> Converts this object to an integer. </summary> - int ToInt(); - - /// <summary> Converts this object to a double value. </summary> - double ToDouble(); - - /// <summary> Converts this object to a string. </summary> - String^ ToString() override; - - - /// <summary> Returns a property of this object. </summary> - /// <param name="name"> The name of the CDocBuilderValue object property. </param> - CDocBuilderValue^ GetProperty(String^ name); - - /// <summary> Analogue of the GetProperty method. </summary> - /// <param name="name"> The name of the CDocBuilderValue object property. </param> - CDocBuilderValue^ Get(String^ name); - - /// <summary> Returns an array value by its index. </summary> - /// <param name="index"> The index of the array value. </param> - CDocBuilderValue^ Get(int index); - - - /// <summary> Sets a property to this object. </summary> - /// <param name="name"> The name of the CDocBuilderValue object property. </param> - /// <param name="value"> The value of the CDocBuilderValue object property. </param> - void SetProperty(String^ name, CDocBuilderValue^ value); - - /// <summary> Analogue of the SetProperty method. </summary> - /// <param name="name"> The name of the CDocBuilderValue object property. </param> - /// <param name="value"> The value of the CDocBuilderValue object property. </param> - void Set(String^ name, CDocBuilderValue^ value); - - /// <summary> Sets an array value by its index. </summary> - /// <param name="index"> The index of the array value. </param> - /// <param name="value"> The array value to be set. </param> - void Set(int index, CDocBuilderValue^ value); - - - /// <summary> Returns/Sets an array value by its index. </summary> - /// <param name="index"> The index of the array value. </param> - /// <param name="value"> The array value to be set. </param> - property CDocBuilderValue^ default[int] - { - CDocBuilderValue ^ get(int index) { return Get(index); } - void set(int index, CDocBuilderValue ^ value) { Set(index, value); } - } - - /// <summary> The indexer analogue of the GetProperty/SetProperty methods. </summary> - /// <param name="name"> The name of the CDocBuilderValue object property. </param> - /// <param name="value"> The value of the CDocBuilderValue object property. </param> - property CDocBuilderValue^ default[String^] - { - CDocBuilderValue ^ get(String^ name) { return Get(name); } - void set(String^ name, CDocBuilderValue ^ value) { Set(name, value); } - } - - public: - /// <summary> Creates an object from primitive types. </summary> - CDocBuilderValue(bool value); - CDocBuilderValue(int value); - CDocBuilderValue(unsigned int value); - CDocBuilderValue(double value); - CDocBuilderValue(String^ value); - - static operator CDocBuilderValue^ (bool value); - static operator CDocBuilderValue^ (int value); - static operator CDocBuilderValue^ (unsigned int value); - static operator CDocBuilderValue^ (double value); - static operator CDocBuilderValue^ (String^ value); - - /// <summary> - /// Please use CDocBuilderContext.CreateUndefined. - /// Creates an undefined value. This method returns the current context and calls its CreateUndefined method. - /// </summary> - static CDocBuilderValue^ CreateUndefined(); - - /// <summary> - /// Please use CDocBuilderContext.CreateNull. - /// Creates a null value. This method returns the current context and calls its CreateNull method. - /// </summary> - static CDocBuilderValue^ CreateNull(); - - public: - /// <summary> Calls the specified Document Builder method. </summary> - /// <param name="name"> The name of the Document Builder method. </param> - CDocBuilderValue^ Call(String^ name); - - /// <summary> Calls the specified Document Builder method. </summary> - /// <param name="name"> The name of the Document Builder method. </param> - /// <param name="p1"> The first parameter that the Document Builder method takes as an arguments. </param> - CDocBuilderValue^ Call(String^ name, CDocBuilderValue^ p1); - - /// <summary> Calls the specified Document Builder method. </summary> - /// <param name="name"> The name of the Document Builder method. </param> - /// <param name="p1"> The first parameter that the Document Builder method takes as an arguments. </param> - /// <param name="p2"> The second parameter that the Document Builder method takes as an arguments. </param> - CDocBuilderValue^ Call(String^ name, CDocBuilderValue^ p1, CDocBuilderValue^ p2); - - /// <summary> Calls the specified Document Builder method. </summary> - /// <param name="name"> The name of the Document Builder method. </param> - /// <param name="p1"> The first parameter that the Document Builder method takes as an arguments. </param> - /// <param name="p2"> The second parameter that the Document Builder method takes as an arguments. </param> - /// <param name="p3"> The third parameter that the Document Builder method takes as an arguments. </param> - CDocBuilderValue^ Call(String^ name, CDocBuilderValue^ p1, CDocBuilderValue^ p2, CDocBuilderValue^ p3); - - /// <summary> Calls the specified Document Builder method. </summary> - /// <param name="name"> The name of the Document Builder method. </param> - /// <param name="p1"> The first parameter that the Document Builder method takes as an arguments. </param> - /// <param name="p2"> The second parameter that the Document Builder method takes as an arguments. </param> - /// <param name="p3"> The third parameter that the Document Builder method takes as an arguments. </param> - /// <param name="p4"> The fourth parameter that the Document Builder method takes as an arguments. </param> - CDocBuilderValue^ Call(String^ name, CDocBuilderValue^ p1, CDocBuilderValue^ p2, CDocBuilderValue^ p3, CDocBuilderValue^ p4); - - /// <summary> Calls the specified Document Builder method. </summary> - /// <param name="name"> The name of the Document Builder method. </param> - /// <param name="p1"> The first parameter that the Document Builder method takes as an arguments. </param> - /// <param name="p2"> The second parameter that the Document Builder method takes as an arguments. </param> - /// <param name="p3"> The third parameter that the Document Builder method takes as an arguments. </param> - /// <param name="p4"> The fourth parameter that the Document Builder method takes as an arguments. </param> - /// <param name="p5"> The fifth parameter that the Document Builder method takes as an arguments. </param> - CDocBuilderValue^ Call(String^ name, CDocBuilderValue^ p1, CDocBuilderValue^ p2, CDocBuilderValue^ p3, CDocBuilderValue^ p4, CDocBuilderValue^ p5); - - /// <summary> Calls the specified Document Builder method. </summary> - /// <param name="name"> The name of the Document Builder method. </param> - /// <param name="p1"> The first parameter that the Document Builder method takes as an arguments. </param> - /// <param name="p2"> The second parameter that the Document Builder method takes as an arguments. </param> - /// <param name="p3"> The third parameter that the Document Builder method takes as an arguments. </param> - /// <param name="p4"> The fourth parameter that the Document Builder method takes as an arguments. </param> - /// <param name="p5"> The fifth parameter that the Document Builder method takes as an arguments. </param> - /// <param name="p6"> The sixth parameter that the Document Builder method takes as an arguments. </param> - CDocBuilderValue^ Call(String^ name, CDocBuilderValue^ p1, CDocBuilderValue^ p2, CDocBuilderValue^ p3, CDocBuilderValue^ p4, CDocBuilderValue^ p5, CDocBuilderValue^ p6); - - internal: - NSDoctRenderer::CDocBuilderValue* m_internal; - }; - - public ref class CDocBuilder - { - public: - CDocBuilder(); - ~CDocBuilder(); - - protected: - !CDocBuilder(); - - public: - /// <summary> - /// Opens the document file which will be edited and saved afterwards. - /// </summary> - /// <param name="path"> The path to the file to be opened together with its name and extension. </param> - /// <param name="params"> - /// The parameters needed for the correct file opening (most commonly, the encoding is used for the txt and csv file types or the delimiter for the csv files, - /// for other file types this is just an empty string). The parameters are added in the form of XML tags, where m_nCsvTxtEncoding is used for the text encoding - /// and m_nCsvDelimiter is used for the csv delimiter. The supported values for the csv delimiters include: 0 - no delimiter; 1 - tab; 2 - semicolon; 3 - colon; 4 - comma; 5 - space. - /// </param> - /// <returns> Process x2t return code. </returns> - int OpenFile(String^ path, String^ params); - - /// <summary> - /// Creates a new file. The type of the file which will be created needs to be set. - /// </summary> - /// <param name="type"> - /// The type of the file to be created set as a hexadecimal - /// integer for the .Net code or docx, xlsx or pptx for the .docbuilder script file (see AVS_OFFICESTUDIO_FILE_XXX values). - /// </param> - /// <returns> True if the operation is successful. </returns> - bool CreateFile(int type); - - /// <summary> - /// Sets the path to the folder where the program will temporarily save files needed for the program correct work. - /// After the successful document file creation, all the files will be deleted from the folder.If no temporary folder is set, the system one will be used. - /// </summary> - /// <param name="folder"> The path to the folder where the temporary files will be saved. </param> - void SetTmpFolder(String^ folder); - - - /// <summary> - /// Saves the file after all the changes are made. The type of the file which will be saved needs to be set. - /// </summary> - /// <param name="type"> - /// The type of the file to be saved set as a hexadecimal integer for the .Net code; for the .docbuilder script file the following values are possible: - /// docx, odt, rtf, txt, pptx, xlsx, ods, csv, pdf (see AVS_OFFICESTUDIO_FILE_XXX values). - /// </param> - /// <param name="path"> The path to the file to be saved together with its name and extension. </param> - /// <returns> Process x2t return code. </returns> - bool SaveFile(int type, String^ path); - - /// <summary> - /// Saves the file after all the changes are made. The type of the file which will be saved needs to be set. - /// </summary> - /// <param name="type"> - /// The type of the file to be saved set as a hexadecimal integer for the .Net code; for the .docbuilder script file the following values are possible: - /// docx, odt, rtf, txt, pptx, xlsx, ods, csv, pdf (see AVS_OFFICESTUDIO_FILE_XXX values). - /// </param> - /// <param name="path"> The path to the file to be saved together with its name and extension. </param> - /// <param name="params"> - /// The parameters needed for the correct file opening (most commonly, the encoding is used for the txt and csv file types or the delimiter for the csv files, - /// for other file types this is just an empty string). The parameters are added in the form of XML tags, where m_nCsvTxtEncoding is used for the text encoding - /// and m_nCsvDelimiter is used for the csv delimiter. The supported values for the csv delimiters include : 0 - no delimiter; 1 - tab; 2 - semicolon; 3 - colon; 4 - comma; 5 - space. - /// When saving into an image file (png or jpg) for creating thumbnails, the additional parameters in the form of XML tags are used: - /// m_oThumbnail - the core tag showing that the inner nodes will be used to create a thumbnail out of the document file; - /// format - the image file format used to create a thumbnail (can be of the following values: 3 - for a JPG file, 4 - for a PNG file); - /// aspect - the image aspect when creating a thumbnail from the document file (can be of the following values: 1 - will keep the original aspect, 0 - will stretch the image to fit the width and the height set below; - /// first - whether only the first page or all the pages should be converted into a thumbnail (can be of the following values: true - only the first page will be converted, false - all the document pages will be used to create thumbnails, in this case the file will be saved as an archive of images, one for each page); - /// width - the image width in pixels; - /// height - the image height in pixels. - /// For example: oBuilder.SaveFile(OFFICESTUDIO_FILE_IMAGE, L"thumbnail.png", "<m_oThumbnail><format>4</format><aspect>1</aspect><first>false</first><width>1000</width><height>1000</height></m_oThumbnail>"); - /// </param> - /// <returns> Process x2t return code. </returns> - bool SaveFile(int type, String^ path, String^ params); - - - /// <summary> - /// Closes the file to stop working with it. You can use a single ONLYOFFICE Document Builder instance - /// to work with all your files, but you need to close the previous file before you can - /// start working with the next one in this case. - /// - /// Attention!!! - /// There is always a chance that you will need to exchange the data among the documents. - /// For example, you might need to open some document, copy style from it, or some data values, - /// close the document, create a new one and paste the copied data to it or use it to form some report. - /// But once you close the file (using the CloseFile method (or new OpenFile), all the variable data you worked - /// with will be void and cleared, and you will not be able to use it with any other file. - /// To exchange the data between the files GlobalVariable is introduced. - /// What you need, is to create a variable in the first opened or created file using the GlobalVariable method, e.g.: - /// builder.OpenFile("file1"); - /// var tmpVariable = Api.GetDocument().GetCommentsReport(); - /// GlobalVariable["CommentsReport"] = tmpVariable; - /// builder.CloseFile(); - /// builder.OpenFile("file2"); - /// tmpVariable now undefined - /// GlobalVariable["CommentsReport"] - valid object - /// </summary> - void CloseFile(); - - /// <summary> - /// Executes the command which will be used to create the document file (text document, spreadsheet, presentation, form document, PDF). - /// </summary> - /// <param name="command"> - /// The command in the form of JavaScript code which will be used to create the document file - /// (in .Net, the escape character must be used when the command contains quotation symbols). - /// </param> - /// <returns> True if the operation is successful. </returns> - bool ExecuteCommand(String^ command); - - /// <summary> - /// Executes the command which will be used to create the document file (text document, spreadsheet, presentation, form document, PDF). - /// </summary> - /// <param name="command"> - /// The command in the form of JavaScript code which will be used to create the document file - /// (in .Net, the escape character must be used when the command contains quotation symbols). - /// </param> - /// <param name="retValue"> The command return value. </param> - /// <returns> True if the operation is successful. </returns> - bool ExecuteCommand(String^ command, [Runtime::InteropServices::Out] CDocBuilderValue^% retValue); - - - /// <summary> - /// Runs the ONLYOFFICE Document Builder executable. If you do not want to write a .Net application, - /// you can simply use the docbuilder.exe executable file and run it with the.docbuilder file as an argument, - /// where all the code for the document file creation will be written. For .Net, create the CDocBuilder object - /// and call the Run method with the path to the executable file from the sPath parameter. - /// </summary> - /// <param name="path"> The path to the ONLYOFFICE Document Builder executable. </param> - /// <returns> True if the operation is successful. </returns> - bool Run(String^ path); - - /// <summary> - /// Runs all the commands for the document creation using a single command. - /// Compared to CDocBuilder.ExecuteCommand where only one command at a time is allowed, CDocBuilder.RunText - /// makes it possible to enter all the commands for the document creation at once. - /// </summary> - /// <param name="commands"> - /// The commands which will be used to create the document file. - /// All the commands containing builder. are line separated, i.e. you cannot write them in one line, each command must start with its own line. - /// </param> - /// <returns> True if the operation is successful. </returns> - bool RunText(String^ commands); - - /// <summary> - /// Sets an argument to the builder class which can be trasferred to the program outside the CDocBuilder.ExecuteCommand method, - /// i.e. either as an additional property when running ONLYOFFICE Document Builder executable file or as a part of program code, but not included into the document file script. - /// </summary> - /// <remarks> - /// Supported properties: - /// <para> - /// --use-doctrenderer-scheme - Specifies if the doctrenderer mode is used when building a document or getting content from the editor when saving a file (true / false). - /// Default: false - /// </para> - /// <para> - /// --check-fonts - Specifies if the system fonts are cached for faster work (true / false). - /// Default: true - /// </para> - /// <para> - /// --work-directory - The path to the temporary directory. - /// Default: "" - /// </para> - /// <para> - /// --cache-scripts - Specifies if the sdkjs scripts are cached (true / false). - /// Default: true - /// </para> - /// <para> - /// --save-use-only-names - Specifies if the destination paths are used (for server work) (true / false). - /// <example> - /// For example: /home/user/1.txt = > /tmp/1.txt - /// </example> - /// Default: false - /// </para> - /// <para> - /// --all-fonts-path - The path to the AllFonts.js script. - /// --argument - The JSON argument which is sent to the global parameters of all the opened JS context. - /// --fonts-system - Specifies if the system fonts are used (true / false). - /// Default: true - /// </para> - /// --fonts-dir - The path to the additional fonts directory (may be many records). - /// </remarks> - /// <param name="param"> The parameter name, the value is always --argument. </param> - /// <param name="value"> The parameter value which will be used in the document. </param> - void SetProperty(String^ param, String^ value); - - - /// <summary> - /// Writes data to the log file. It is used for logs in JS code. - /// <param name="path"> The path to the file where all the logs will be written. </param> - /// <param name="value"> The data which will be written to the log file. </param> - /// <param name="append"> Specifies if the new data will be appended to the already existing log file or a new file will be created. </param> - /// </summary> - void WriteData(String^ path, String^ value, bool append); - - /// <summary> - /// Specifies if the doctrenderer mode is used when building - /// a document or getting content from the editor when saving a file. - /// </summary> - /// <returns> True if the doctrenderer mode is used on saving. See the --use-doctrenderer-scheme property. </returns> - bool IsSaveWithDoctrendererMode(); - - /// <summary> Returns the ONLYOFFICE Document Builder engine version. </summary> - String^ GetVersion(); - - /// <summary> Returns the current JS context. </summary> - CDocBuilderContext^ GetContext(); - - public: - /// <summary> - /// Initializes the ONLYOFFICE Document Builder as a library for the application to be able to work with it. - /// This method just sets the directory to the main Document Builder resources (icu files, etc). If this method is not called, - /// the Document Builder will find resources from the current process directory. - /// </summary> - /// <param name="directory"> The path to the main Document Builder resources. </param> - static void Initialize(String^ directory); - - /// <summary> - /// Initializes the ONLYOFFICE Document Builder as a library for the application to be able to work with it. - /// This method just sets the directory to the main Document Builder resources (icu files, etc). If this method is not called, - /// the Document Builder will find resources from the current process directory. - /// </summary> - static void Initialize(); - - /// <summary> - /// Unloads the ONLYOFFICE Document Builder from the application memory when it is no longer needed. - /// Generally, there is no need to dispose JS before exiting - /// the process, it should happen automatically. It should only be used if the process needs the resources taken up by JS. - /// </summary> - static void Destroy(); - - internal: - NSDoctRenderer::CDocBuilder* m_internal; - }; - - /// <summary> - /// The stack-allocated class which sets the execution context for all operations executed within a local scope. - /// All opened scopes will be closed automatically when the builder CloseFile method is called. - /// </summary> - public ref class CDocBuilderContextScope - { - public: - CDocBuilderContextScope(); - CDocBuilderContextScope(const CDocBuilderContextScope% other); - ~CDocBuilderContextScope(); - - protected: - !CDocBuilderContextScope(); - - public: - /// <summary> - /// Closes the current scope. - /// This method will be called automatically when the destructor is executed. - /// </summary> - void Close(); - - internal: - NSDoctRenderer::CDocBuilderContextScope* m_internal; - }; - - /// <summary> - /// Class for getting JS context for working. - /// </summary> - public ref class CDocBuilderContext - { - public: - CDocBuilderContext(); - CDocBuilderContext(const CDocBuilderContext% other); - ~CDocBuilderContext(); - - protected: - !CDocBuilderContext(); - - public: - /// <summary> - /// Creates an undefined value, an analogue of undefined in JS. - /// </summary> - CDocBuilderValue^ CreateUndefined(); - - /// <summary> - /// Creates a null value, an analogue of null in JS. - /// </summary> - CDocBuilderValue^ CreateNull(); - - /// <summary> - /// Creates an empty object, an analogue of {} in JS. - /// </summary> - CDocBuilderValue^ CreateObject(); - - /// <summary> - /// Creates an array value, an analogue of new Array (length) in JS. - /// </summary> - /// <param name="length"> The array length. </param> - CDocBuilderValue^ CreateArray(int length); - - /// <summary> - /// Creates a Uint8Array value, an analogue of Uint8Array in JS. - /// </summary> - /// <param name="buffer"> The array buffer. </param> - CDocBuilderValue^ CreateTypedArray(array<Byte>^ buffer); - - /// <summary> - /// Returns the global object for the current context. - /// </summary> - CDocBuilderValue^ GetGlobal(); - - /// <summary> - /// Creates a context scope which sets the execution context for all operations executed within a local scope. - /// </summary> - CDocBuilderContextScope^ CreateScope(); - - /// <summary> - /// Checks for errors in JS. - /// The error message and call stack will be written to std::cerr. - /// </summary> - bool IsError(); - - internal: - NSDoctRenderer::CDocBuilderContext* m_internal; - }; -} +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ + +// docbuilder.net.h + +#include "../../docbuilder.h" + +#pragma once + +using namespace System; + +namespace docbuilder_net +{ + ref class CDocBuilderValue; + ref class CDocBuilder; + ref class CDocBuilderContextScope; + ref class CDocBuilderContext; + + /// <summary> + /// Class for getting the results of called JS commands. + /// It represents a wrapper for a JS object. + /// </summary> + public ref class CDocBuilderValue + { + public: + CDocBuilderValue(); + CDocBuilderValue(const CDocBuilderValue% other); + ~CDocBuilderValue(); + + protected: + !CDocBuilderValue(); + + public: + /// <returns> True if this object is empty. </returns> + bool IsEmpty(); + + /// <summary> Clears the object. </summary> + void Clear(); + + /// <returns> True if this object is null. </returns> + bool IsNull(); + + /// <returns> True if this object is undefined. </returns> + bool IsUndefined(); + + /// <returns> True if this object is a boolean value. </returns> + bool IsBool(); + + /// <returns> True if this object is an integer. </returns> + bool IsInt(); + + /// <returns> True if this object is a double value. </returns> + bool IsDouble(); + + /// <returns> True if this object is a string. </returns> + bool IsString(); + + /// <returns> True if this object is a function. </returns> + bool IsFunction(); + + /// <returns> True if this object is an object. </returns> + bool IsObject(); + + /// <returns> True if this object is an array. </returns> + bool IsArray(); + + /// <returns> True if this object is a typed array. </returns> + bool IsTypedArray(); + + + /// <returns> The length if this object is an array/typed array. Otherwise, returns 0. </returns> + unsigned int GetLength(); + + + /// <summary> Converts this object to a boolean value. </summary> + bool ToBool(); + + /// <summary> Converts this object to an integer. </summary> + int ToInt(); + + /// <summary> Converts this object to a double value. </summary> + double ToDouble(); + + /// <summary> Converts this object to a string. </summary> + String^ ToString() override; + + + /// <summary> Returns a property of this object. </summary> + /// <param name="name"> The name of the CDocBuilderValue object property. </param> + CDocBuilderValue^ GetProperty(String^ name); + + /// <summary> Analogue of the GetProperty method. </summary> + /// <param name="name"> The name of the CDocBuilderValue object property. </param> + CDocBuilderValue^ Get(String^ name); + + /// <summary> Returns an array value by its index. </summary> + /// <param name="index"> The index of the array value. </param> + CDocBuilderValue^ Get(int index); + + + /// <summary> Sets a property to this object. </summary> + /// <param name="name"> The name of the CDocBuilderValue object property. </param> + /// <param name="value"> The value of the CDocBuilderValue object property. </param> + void SetProperty(String^ name, CDocBuilderValue^ value); + + /// <summary> Analogue of the SetProperty method. </summary> + /// <param name="name"> The name of the CDocBuilderValue object property. </param> + /// <param name="value"> The value of the CDocBuilderValue object property. </param> + void Set(String^ name, CDocBuilderValue^ value); + + /// <summary> Sets an array value by its index. </summary> + /// <param name="index"> The index of the array value. </param> + /// <param name="value"> The array value to be set. </param> + void Set(int index, CDocBuilderValue^ value); + + + /// <summary> Returns/Sets an array value by its index. </summary> + /// <param name="index"> The index of the array value. </param> + /// <param name="value"> The array value to be set. </param> + property CDocBuilderValue^ default[int] + { + CDocBuilderValue ^ get(int index) { return Get(index); } + void set(int index, CDocBuilderValue ^ value) { Set(index, value); } + } + + /// <summary> The indexer analogue of the GetProperty/SetProperty methods. </summary> + /// <param name="name"> The name of the CDocBuilderValue object property. </param> + /// <param name="value"> The value of the CDocBuilderValue object property. </param> + property CDocBuilderValue^ default[String^] + { + CDocBuilderValue ^ get(String^ name) { return Get(name); } + void set(String^ name, CDocBuilderValue ^ value) { Set(name, value); } + } + + public: + /// <summary> Creates an object from primitive types. </summary> + CDocBuilderValue(bool value); + CDocBuilderValue(int value); + CDocBuilderValue(unsigned int value); + CDocBuilderValue(double value); + CDocBuilderValue(String^ value); + CDocBuilderValue(array<CDocBuilderValue^>^ values); + + static operator CDocBuilderValue^ (bool value); + static operator CDocBuilderValue^ (int value); + static operator CDocBuilderValue^ (unsigned int value); + static operator CDocBuilderValue^ (double value); + static operator CDocBuilderValue^ (String^ value); + static operator CDocBuilderValue^ (array<CDocBuilderValue^>^ values); + + /// <summary> + /// Please use CDocBuilderContext.CreateUndefined. + /// Creates an undefined value. This method returns the current context and calls its CreateUndefined method. + /// </summary> + static CDocBuilderValue^ CreateUndefined(); + + /// <summary> + /// Please use CDocBuilderContext.CreateNull. + /// Creates a null value. This method returns the current context and calls its CreateNull method. + /// </summary> + static CDocBuilderValue^ CreateNull(); + + public: + /// <summary> Calls the specified Document Builder method. </summary> + /// <param name="name"> The name of the Document Builder method. </param> + CDocBuilderValue^ Call(String^ name); + + /// <summary> Calls the specified Document Builder method. </summary> + /// <param name="name"> The name of the Document Builder method. </param> + /// <param name="p1"> The first parameter that the Document Builder method takes as an arguments. </param> + CDocBuilderValue^ Call(String^ name, CDocBuilderValue^ p1); + + /// <summary> Calls the specified Document Builder method. </summary> + /// <param name="name"> The name of the Document Builder method. </param> + /// <param name="p1"> The first parameter that the Document Builder method takes as an arguments. </param> + /// <param name="p2"> The second parameter that the Document Builder method takes as an arguments. </param> + CDocBuilderValue^ Call(String^ name, CDocBuilderValue^ p1, CDocBuilderValue^ p2); + + /// <summary> Calls the specified Document Builder method. </summary> + /// <param name="name"> The name of the Document Builder method. </param> + /// <param name="p1"> The first parameter that the Document Builder method takes as an arguments. </param> + /// <param name="p2"> The second parameter that the Document Builder method takes as an arguments. </param> + /// <param name="p3"> The third parameter that the Document Builder method takes as an arguments. </param> + CDocBuilderValue^ Call(String^ name, CDocBuilderValue^ p1, CDocBuilderValue^ p2, CDocBuilderValue^ p3); + + /// <summary> Calls the specified Document Builder method. </summary> + /// <param name="name"> The name of the Document Builder method. </param> + /// <param name="p1"> The first parameter that the Document Builder method takes as an arguments. </param> + /// <param name="p2"> The second parameter that the Document Builder method takes as an arguments. </param> + /// <param name="p3"> The third parameter that the Document Builder method takes as an arguments. </param> + /// <param name="p4"> The fourth parameter that the Document Builder method takes as an arguments. </param> + CDocBuilderValue^ Call(String^ name, CDocBuilderValue^ p1, CDocBuilderValue^ p2, CDocBuilderValue^ p3, CDocBuilderValue^ p4); + + /// <summary> Calls the specified Document Builder method. </summary> + /// <param name="name"> The name of the Document Builder method. </param> + /// <param name="p1"> The first parameter that the Document Builder method takes as an arguments. </param> + /// <param name="p2"> The second parameter that the Document Builder method takes as an arguments. </param> + /// <param name="p3"> The third parameter that the Document Builder method takes as an arguments. </param> + /// <param name="p4"> The fourth parameter that the Document Builder method takes as an arguments. </param> + /// <param name="p5"> The fifth parameter that the Document Builder method takes as an arguments. </param> + CDocBuilderValue^ Call(String^ name, CDocBuilderValue^ p1, CDocBuilderValue^ p2, CDocBuilderValue^ p3, CDocBuilderValue^ p4, CDocBuilderValue^ p5); + + /// <summary> Calls the specified Document Builder method. </summary> + /// <param name="name"> The name of the Document Builder method. </param> + /// <param name="p1"> The first parameter that the Document Builder method takes as an arguments. </param> + /// <param name="p2"> The second parameter that the Document Builder method takes as an arguments. </param> + /// <param name="p3"> The third parameter that the Document Builder method takes as an arguments. </param> + /// <param name="p4"> The fourth parameter that the Document Builder method takes as an arguments. </param> + /// <param name="p5"> The fifth parameter that the Document Builder method takes as an arguments. </param> + /// <param name="p6"> The sixth parameter that the Document Builder method takes as an arguments. </param> + CDocBuilderValue^ Call(String^ name, CDocBuilderValue^ p1, CDocBuilderValue^ p2, CDocBuilderValue^ p3, CDocBuilderValue^ p4, CDocBuilderValue^ p5, CDocBuilderValue^ p6); + + internal: + NSDoctRenderer::CDocBuilderValue* m_internal; + }; + + public ref class CDocBuilder + { + public: + CDocBuilder(); + ~CDocBuilder(); + + protected: + !CDocBuilder(); + + public: + /// <summary> + /// Opens the document file which will be edited and saved afterwards. + /// </summary> + /// <param name="path"> The path to the file to be opened together with its name and extension. </param> + /// <param name="params"> + /// The parameters needed for the correct file opening (most commonly, the encoding is used for the txt and csv file types or the delimiter for the csv files, + /// for other file types this is just an empty string). The parameters are added in the form of XML tags, where m_nCsvTxtEncoding is used for the text encoding + /// and m_nCsvDelimiter is used for the csv delimiter. The supported values for the csv delimiters include: 0 - no delimiter; 1 - tab; 2 - semicolon; 3 - colon; 4 - comma; 5 - space. + /// </param> + /// <returns> Process x2t return code. </returns> + int OpenFile(String^ path, String^ params); + + /// <summary> + /// Creates a new file. The type of the file which will be created needs to be set. + /// </summary> + /// <param name="type"> + /// The type of the file to be created set as a hexadecimal + /// integer for the .Net code or docx, xlsx or pptx for the .docbuilder script file (see AVS_OFFICESTUDIO_FILE_XXX values). + /// </param> + /// <returns> True if the operation is successful. </returns> + bool CreateFile(int type); + + /// <summary> + /// Sets the path to the folder where the program will temporarily save files needed for the program correct work. + /// After the successful document file creation, all the files will be deleted from the folder.If no temporary folder is set, the system one will be used. + /// </summary> + /// <param name="folder"> The path to the folder where the temporary files will be saved. </param> + void SetTmpFolder(String^ folder); + + + /// <summary> + /// Saves the file after all the changes are made. The type of the file which will be saved needs to be set. + /// </summary> + /// <param name="type"> + /// The type of the file to be saved set as a hexadecimal integer for the .Net code; for the .docbuilder script file the following values are possible: + /// docx, odt, rtf, txt, pptx, xlsx, ods, csv, pdf (see AVS_OFFICESTUDIO_FILE_XXX values). + /// </param> + /// <param name="path"> The path to the file to be saved together with its name and extension. </param> + /// <returns> Process x2t return code. </returns> + bool SaveFile(int type, String^ path); + + /// <summary> + /// Saves the file after all the changes are made. The type of the file which will be saved needs to be set. + /// </summary> + /// <param name="type"> + /// The type of the file to be saved set as a hexadecimal integer for the .Net code; for the .docbuilder script file the following values are possible: + /// docx, odt, rtf, txt, pptx, xlsx, ods, csv, pdf (see AVS_OFFICESTUDIO_FILE_XXX values). + /// </param> + /// <param name="path"> The path to the file to be saved together with its name and extension. </param> + /// <param name="params"> + /// The parameters needed for the correct file opening (most commonly, the encoding is used for the txt and csv file types or the delimiter for the csv files, + /// for other file types this is just an empty string). The parameters are added in the form of XML tags, where m_nCsvTxtEncoding is used for the text encoding + /// and m_nCsvDelimiter is used for the csv delimiter. The supported values for the csv delimiters include : 0 - no delimiter; 1 - tab; 2 - semicolon; 3 - colon; 4 - comma; 5 - space. + /// When saving into an image file (png or jpg) for creating thumbnails, the additional parameters in the form of XML tags are used: + /// m_oThumbnail - the core tag showing that the inner nodes will be used to create a thumbnail out of the document file; + /// format - the image file format used to create a thumbnail (can be of the following values: 3 - for a JPG file, 4 - for a PNG file); + /// aspect - the image aspect when creating a thumbnail from the document file (can be of the following values: 1 - will keep the original aspect, 0 - will stretch the image to fit the width and the height set below; + /// first - whether only the first page or all the pages should be converted into a thumbnail (can be of the following values: true - only the first page will be converted, false - all the document pages will be used to create thumbnails, in this case the file will be saved as an archive of images, one for each page); + /// width - the image width in pixels; + /// height - the image height in pixels. + /// For example: oBuilder.SaveFile(OFFICESTUDIO_FILE_IMAGE, L"thumbnail.png", "<m_oThumbnail><format>4</format><aspect>1</aspect><first>false</first><width>1000</width><height>1000</height></m_oThumbnail>"); + /// </param> + /// <returns> Process x2t return code. </returns> + bool SaveFile(int type, String^ path, String^ params); + + + /// <summary> + /// Closes the file to stop working with it. You can use a single ONLYOFFICE Document Builder instance + /// to work with all your files, but you need to close the previous file before you can + /// start working with the next one in this case. + /// + /// Attention!!! + /// There is always a chance that you will need to exchange the data among the documents. + /// For example, you might need to open some document, copy style from it, or some data values, + /// close the document, create a new one and paste the copied data to it or use it to form some report. + /// But once you close the file (using the CloseFile method (or new OpenFile), all the variable data you worked + /// with will be void and cleared, and you will not be able to use it with any other file. + /// To exchange the data between the files GlobalVariable is introduced. + /// What you need, is to create a variable in the first opened or created file using the GlobalVariable method, e.g.: + /// builder.OpenFile("file1"); + /// var tmpVariable = Api.GetDocument().GetCommentsReport(); + /// GlobalVariable["CommentsReport"] = tmpVariable; + /// builder.CloseFile(); + /// builder.OpenFile("file2"); + /// tmpVariable now undefined + /// GlobalVariable["CommentsReport"] - valid object + /// </summary> + void CloseFile(); + + /// <summary> + /// Executes the command which will be used to create the document file (text document, spreadsheet, presentation, form document, PDF). + /// </summary> + /// <param name="command"> + /// The command in the form of JavaScript code which will be used to create the document file + /// (in .Net, the escape character must be used when the command contains quotation symbols). + /// </param> + /// <returns> True if the operation is successful. </returns> + bool ExecuteCommand(String^ command); + + /// <summary> + /// Executes the command which will be used to create the document file (text document, spreadsheet, presentation, form document, PDF). + /// </summary> + /// <param name="command"> + /// The command in the form of JavaScript code which will be used to create the document file + /// (in .Net, the escape character must be used when the command contains quotation symbols). + /// </param> + /// <param name="retValue"> The command return value. </param> + /// <returns> True if the operation is successful. </returns> + bool ExecuteCommand(String^ command, [Runtime::InteropServices::Out] CDocBuilderValue^% retValue); + + + /// <summary> + /// Runs the ONLYOFFICE Document Builder executable. If you do not want to write a .Net application, + /// you can simply use the docbuilder.exe executable file and run it with the.docbuilder file as an argument, + /// where all the code for the document file creation will be written. For .Net, create the CDocBuilder object + /// and call the Run method with the path to the executable file from the sPath parameter. + /// </summary> + /// <param name="path"> The path to the ONLYOFFICE Document Builder executable. </param> + /// <returns> True if the operation is successful. </returns> + bool Run(String^ path); + + /// <summary> + /// Runs all the commands for the document creation using a single command. + /// Compared to CDocBuilder.ExecuteCommand where only one command at a time is allowed, CDocBuilder.RunText + /// makes it possible to enter all the commands for the document creation at once. + /// </summary> + /// <param name="commands"> + /// The commands which will be used to create the document file. + /// All the commands containing builder. are line separated, i.e. you cannot write them in one line, each command must start with its own line. + /// </param> + /// <returns> True if the operation is successful. </returns> + bool RunText(String^ commands); + + /// <summary> + /// Sets an argument to the builder class which can be trasferred to the program outside the CDocBuilder.ExecuteCommand method, + /// i.e. either as an additional property when running ONLYOFFICE Document Builder executable file or as a part of program code, but not included into the document file script. + /// </summary> + /// <remarks> + /// Supported properties: + /// <para> + /// --use-doctrenderer-scheme - Specifies if the doctrenderer mode is used when building a document or getting content from the editor when saving a file (true / false). + /// Default: false + /// </para> + /// <para> + /// --check-fonts - Specifies if the system fonts are cached for faster work (true / false). + /// Default: true + /// </para> + /// <para> + /// --work-directory - The path to the temporary directory. + /// Default: "" + /// </para> + /// <para> + /// --cache-scripts - Specifies if the sdkjs scripts are cached (true / false). + /// Default: true + /// </para> + /// <para> + /// --save-use-only-names - Specifies if the destination paths are used (for server work) (true / false). + /// <example> + /// For example: /home/user/1.txt = > /tmp/1.txt + /// </example> + /// Default: false + /// </para> + /// <para> + /// --all-fonts-path - The path to the AllFonts.js script. + /// --argument - The JSON argument which is sent to the global parameters of all the opened JS context. + /// --fonts-system - Specifies if the system fonts are used (true / false). + /// Default: true + /// </para> + /// --fonts-dir - The path to the additional fonts directory (may be many records). + /// </remarks> + /// <param name="param"> The parameter name, the value is always --argument. </param> + /// <param name="value"> The parameter value which will be used in the document. </param> + void SetProperty(String^ param, String^ value); + + + /// <summary> + /// Writes data to the log file. It is used for logs in JS code. + /// <param name="path"> The path to the file where all the logs will be written. </param> + /// <param name="value"> The data which will be written to the log file. </param> + /// <param name="append"> Specifies if the new data will be appended to the already existing log file or a new file will be created. </param> + /// </summary> + void WriteData(String^ path, String^ value, bool append); + + /// <summary> + /// Specifies if the doctrenderer mode is used when building + /// a document or getting content from the editor when saving a file. + /// </summary> + /// <returns> True if the doctrenderer mode is used on saving. See the --use-doctrenderer-scheme property. </returns> + bool IsSaveWithDoctrendererMode(); + + /// <summary> Returns the ONLYOFFICE Document Builder engine version. </summary> + String^ GetVersion(); + + /// <summary> Returns the current JS context. </summary> + CDocBuilderContext^ GetContext(); + + public: + /// <summary> + /// Initializes the ONLYOFFICE Document Builder as a library for the application to be able to work with it. + /// This method just sets the directory to the main Document Builder resources (icu files, etc). If this method is not called, + /// the Document Builder will find resources from the current process directory. + /// </summary> + /// <param name="directory"> The path to the main Document Builder resources. </param> + static void Initialize(String^ directory); + + /// <summary> + /// Initializes the ONLYOFFICE Document Builder as a library for the application to be able to work with it. + /// This method just sets the directory to the main Document Builder resources (icu files, etc). If this method is not called, + /// the Document Builder will find resources from the current process directory. + /// </summary> + static void Initialize(); + + /// <summary> + /// Unloads the ONLYOFFICE Document Builder from the application memory when it is no longer needed. + /// Generally, there is no need to dispose JS before exiting + /// the process, it should happen automatically. It should only be used if the process needs the resources taken up by JS. + /// </summary> + static void Destroy(); + + internal: + NSDoctRenderer::CDocBuilder* m_internal; + }; + + /// <summary> + /// The stack-allocated class which sets the execution context for all operations executed within a local scope. + /// All opened scopes will be closed automatically when the builder CloseFile method is called. + /// </summary> + public ref class CDocBuilderContextScope + { + public: + CDocBuilderContextScope(); + CDocBuilderContextScope(const CDocBuilderContextScope% other); + ~CDocBuilderContextScope(); + + protected: + !CDocBuilderContextScope(); + + public: + /// <summary> + /// Closes the current scope. + /// This method will be called automatically when the destructor is executed. + /// </summary> + void Close(); + + internal: + NSDoctRenderer::CDocBuilderContextScope* m_internal; + }; + + /// <summary> + /// Class for getting JS context for working. + /// </summary> + public ref class CDocBuilderContext + { + public: + CDocBuilderContext(); + CDocBuilderContext(const CDocBuilderContext% other); + ~CDocBuilderContext(); + + protected: + !CDocBuilderContext(); + + public: + /// <summary> + /// Creates an undefined value, an analogue of undefined in JS. + /// </summary> + CDocBuilderValue^ CreateUndefined(); + + /// <summary> + /// Creates a null value, an analogue of null in JS. + /// </summary> + CDocBuilderValue^ CreateNull(); + + /// <summary> + /// Creates an empty object, an analogue of {} in JS. + /// </summary> + CDocBuilderValue^ CreateObject(); + + /// <summary> + /// Creates an array value, an analogue of new Array (length) in JS. + /// </summary> + /// <param name="length"> The array length. </param> + CDocBuilderValue^ CreateArray(int length); + + /// <summary> + /// Creates a Uint8Array value, an analogue of Uint8Array in JS. + /// </summary> + /// <param name="buffer"> The array buffer. </param> + CDocBuilderValue^ CreateTypedArray(array<Byte>^ buffer); + + /// <summary> + /// Returns the global object for the current context. + /// </summary> + CDocBuilderValue^ GetGlobal(); + + /// <summary> + /// Creates a context scope which sets the execution context for all operations executed within a local scope. + /// </summary> + CDocBuilderContextScope^ CreateScope(); + + /// <summary> + /// Checks for errors in JS. + /// The error message and call stack will be written to std::cerr. + /// </summary> + bool IsError(); + + internal: + NSDoctRenderer::CDocBuilderContext* m_internal; + }; +} diff --git a/DesktopEditor/doctrenderer/docbuilder.net/test/Program.cs b/DesktopEditor/doctrenderer/docbuilder.net/test/Program.cs index 77bd67a45d4..fd1e9daad9a 100644 --- a/DesktopEditor/doctrenderer/docbuilder.net/test/Program.cs +++ b/DesktopEditor/doctrenderer/docbuilder.net/test/Program.cs @@ -1,4 +1,4 @@ -using docbuilder_net; +using docbuilder_net; using OfficeFileTypes = docbuilder_net.FileTypes; using CValue = docbuilder_net.CDocBuilderValue; @@ -11,7 +11,7 @@ public class Program { public static void Main(string[] args) { - string workDirectory = "C:/Program Files/ONLYOFFICE/DocumentBuilder"; + string workDirectory = "C:/Program Files/ONLYOFFICE/DocumentBuilder"; string resultPath = "result.docx"; // add Docbuilder dlls in path @@ -38,12 +38,16 @@ public static void Test(string workDirectory, string resultPath) CValue oApi = oGlobal["Api"]; CValue oDocument = oApi.Call("GetDocument"); - CValue oParagraph = oApi.Call("CreateParagraph"); - CValue oContent = oContext.CreateArray(1); + CValue oParagraph1 = oApi.Call("CreateParagraph"); + + oParagraph1.Call("SetSpacingAfter", 1000, false); + oParagraph1.Call("AddText", "Hello from .net!"); + + CValue oParagraph2 = oApi.Call("CreateParagraph"); + oParagraph2.Call("AddText", "Goodbye!"); + + CValue oContent = new CValue[] { oParagraph1, oParagraph2 }; - oParagraph.Call("SetSpacingAfter", 1000, false); - oParagraph.Call("AddText", "Hello from .net!"); - oContent[0] = oParagraph; oDocument.Call("InsertContent", oContent); oBuilder.SaveFile(doctype, resultPath); diff --git a/DesktopEditor/doctrenderer/docbuilder.python/.gitignore b/DesktopEditor/doctrenderer/docbuilder.python/.gitignore new file mode 100644 index 00000000000..71ac840d032 --- /dev/null +++ b/DesktopEditor/doctrenderer/docbuilder.python/.gitignore @@ -0,0 +1,2 @@ +result.docx +*.pyc diff --git a/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder.py b/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder.py new file mode 100644 index 00000000000..ac066153860 --- /dev/null +++ b/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder.py @@ -0,0 +1,615 @@ +import ctypes +import os +import platform +import atexit + +OBJECT_HANDLE = ctypes.c_void_p +STRING_HANDLE = ctypes.c_void_p + +_lib = None + +def _loadLibrary(path): + global _lib + if _lib is not None: + return + + os_name = platform.system().lower() + library_name = '' + if 'windows' == os_name: + # modify PATH to load all DLLs + os.environ['PATH'] = path + os.pathsep + os.environ['PATH'] + library_name = 'docbuilder.c.dll' + elif 'linux' == os_name: + library_name = 'libdocbuilder.c.so' + elif 'darwin' == os_name: + library_name = 'libdocbuilder.c.dylib' + + _lib = ctypes.CDLL(path + '/' + library_name) + + # init all function signatures + # ===== CDocBuilderValue ===== + _lib.CDocBuilderValue_Create.argtypes = [] + _lib.CDocBuilderValue_Create.restype = OBJECT_HANDLE + + _lib.CDocBuilderValue_Copy.argtypes = [OBJECT_HANDLE] + _lib.CDocBuilderValue_Copy.restype = OBJECT_HANDLE + + _lib.CDocBuilderValue_Destroy.argtypes = [OBJECT_HANDLE] + _lib.CDocBuilderValue_Destroy.restype = None + + _lib.CDocBuilderValue_IsEmpty.argtypes = [OBJECT_HANDLE] + _lib.CDocBuilderValue_IsEmpty.restype = ctypes.c_bool + + _lib.CDocBuilderValue_Clear.argtypes = [OBJECT_HANDLE] + _lib.CDocBuilderValue_Clear.restype = None + + _lib.CDocBuilderValue_IsNull.argtypes = [OBJECT_HANDLE] + _lib.CDocBuilderValue_IsNull.restype = ctypes.c_bool + + _lib.CDocBuilderValue_IsUndefined.argtypes = [OBJECT_HANDLE] + _lib.CDocBuilderValue_IsUndefined.restype = ctypes.c_bool + + _lib.CDocBuilderValue_IsBool.argtypes = [OBJECT_HANDLE] + _lib.CDocBuilderValue_IsBool.restype = ctypes.c_bool + + _lib.CDocBuilderValue_IsInt.argtypes = [OBJECT_HANDLE] + _lib.CDocBuilderValue_IsInt.restype = ctypes.c_bool + + _lib.CDocBuilderValue_IsDouble.argtypes = [OBJECT_HANDLE] + _lib.CDocBuilderValue_IsDouble.restype = ctypes.c_bool + + _lib.CDocBuilderValue_IsString.argtypes = [OBJECT_HANDLE] + _lib.CDocBuilderValue_IsString.restype = ctypes.c_bool + + _lib.CDocBuilderValue_IsFunction.argtypes = [OBJECT_HANDLE] + _lib.CDocBuilderValue_IsFunction.restype = ctypes.c_bool + + _lib.CDocBuilderValue_IsObject.argtypes = [OBJECT_HANDLE] + _lib.CDocBuilderValue_IsObject.restype = ctypes.c_bool + + _lib.CDocBuilderValue_IsArray.argtypes = [OBJECT_HANDLE] + _lib.CDocBuilderValue_IsArray.restype = ctypes.c_bool + + _lib.CDocBuilderValue_GetLength.argtypes = [OBJECT_HANDLE] + _lib.CDocBuilderValue_GetLength.restype = ctypes.c_uint + + _lib.CDocBuilderValue_ToBool.argtypes = [OBJECT_HANDLE] + _lib.CDocBuilderValue_ToBool.restype = ctypes.c_bool + + _lib.CDocBuilderValue_ToInt.argtypes = [OBJECT_HANDLE] + _lib.CDocBuilderValue_ToInt.restype = ctypes.c_int + + _lib.CDocBuilderValue_ToDouble.argtypes = [OBJECT_HANDLE] + _lib.CDocBuilderValue_ToDouble.restype = ctypes.c_double + + _lib.CDocBuilderValue_ToString.argtypes = [OBJECT_HANDLE] + _lib.CDocBuilderValue_ToString.restype = STRING_HANDLE + + _lib.CDocBuilderValue_GetProperty.argtypes = [OBJECT_HANDLE, ctypes.c_wchar_p] + _lib.CDocBuilderValue_GetProperty.restype = OBJECT_HANDLE + + _lib.CDocBuilderValue_GetByIndex.argtypes = [OBJECT_HANDLE, ctypes.c_int] + _lib.CDocBuilderValue_GetByIndex.restype = OBJECT_HANDLE + + _lib.CDocBuilderValue_SetProperty.argtypes = [OBJECT_HANDLE, ctypes.c_wchar_p, OBJECT_HANDLE] + _lib.CDocBuilderValue_SetProperty.restype = None + + _lib.CDocBuilderValue_SetByIndex.argtypes = [OBJECT_HANDLE, ctypes.c_int, OBJECT_HANDLE] + _lib.CDocBuilderValue_SetByIndex.restype = None + + _lib.CDocBuilderValue_CreateWithBool.argtypes = [ctypes.c_bool] + _lib.CDocBuilderValue_CreateWithBool.restype = OBJECT_HANDLE + + _lib.CDocBuilderValue_CreateWithInt.argtypes = [ctypes.c_int] + _lib.CDocBuilderValue_CreateWithInt.restype = OBJECT_HANDLE + + _lib.CDocBuilderValue_CreateWithUInt.argtypes = [ctypes.c_uint] + _lib.CDocBuilderValue_CreateWithUInt.restype = OBJECT_HANDLE + + _lib.CDocBuilderValue_CreateWithDouble.argtypes = [ctypes.c_double] + _lib.CDocBuilderValue_CreateWithDouble.restype = OBJECT_HANDLE + + _lib.CDocBuilderValue_CreateWithString.argtypes = [ctypes.c_wchar_p] + _lib.CDocBuilderValue_CreateWithString.restype = OBJECT_HANDLE + + _lib.CDocBuilderValue_CreateUndefined.argtypes = [] + _lib.CDocBuilderValue_CreateUndefined.restype = OBJECT_HANDLE + + _lib.CDocBuilderValue_CreateNull.argtypes = [] + _lib.CDocBuilderValue_CreateNull.restype = OBJECT_HANDLE + + _lib.CDocBuilderValue_CreateArray.argtypes = [ctypes.c_int] + _lib.CDocBuilderValue_CreateArray.restype = OBJECT_HANDLE + + _lib.CDocBuilderValue_CreateObject.argtypes = [] + _lib.CDocBuilderValue_CreateObject.restype = OBJECT_HANDLE + + _lib.CDocBuilderValue_Call0.argtypes = [OBJECT_HANDLE, ctypes.c_wchar_p] + _lib.CDocBuilderValue_Call0.restype = OBJECT_HANDLE + + _lib.CDocBuilderValue_Call1.argtypes = [OBJECT_HANDLE, ctypes.c_wchar_p, OBJECT_HANDLE] + _lib.CDocBuilderValue_Call1.restype = OBJECT_HANDLE + + _lib.CDocBuilderValue_Call2.argtypes = [OBJECT_HANDLE, ctypes.c_wchar_p, OBJECT_HANDLE, OBJECT_HANDLE] + _lib.CDocBuilderValue_Call2.restype = OBJECT_HANDLE + + _lib.CDocBuilderValue_Call3.argtypes = [OBJECT_HANDLE, ctypes.c_wchar_p, OBJECT_HANDLE, OBJECT_HANDLE, OBJECT_HANDLE] + _lib.CDocBuilderValue_Call3.restype = OBJECT_HANDLE + + _lib.CDocBuilderValue_Call4.argtypes = [OBJECT_HANDLE, ctypes.c_wchar_p, OBJECT_HANDLE, OBJECT_HANDLE, OBJECT_HANDLE, OBJECT_HANDLE] + _lib.CDocBuilderValue_Call4.restype = OBJECT_HANDLE + + _lib.CDocBuilderValue_Call5.argtypes = [OBJECT_HANDLE, ctypes.c_wchar_p, OBJECT_HANDLE, OBJECT_HANDLE, OBJECT_HANDLE, OBJECT_HANDLE, OBJECT_HANDLE] + _lib.CDocBuilderValue_Call5.restype = OBJECT_HANDLE + + _lib.CDocBuilderValue_Call6.argtypes = [OBJECT_HANDLE, ctypes.c_wchar_p, OBJECT_HANDLE, OBJECT_HANDLE, OBJECT_HANDLE, OBJECT_HANDLE, OBJECT_HANDLE, OBJECT_HANDLE] + _lib.CDocBuilderValue_Call6.restype = OBJECT_HANDLE + + # ===== CDocBuilder ===== + _lib.CDocBuilder_Create.argtypes = [] + _lib.CDocBuilder_Create.restype = OBJECT_HANDLE + + _lib.CDocBuilder_Destroy.argtypes = [OBJECT_HANDLE] + _lib.CDocBuilder_Destroy.restype = None + + _lib.CDocBuilder_OpenFile.argtypes = [OBJECT_HANDLE, ctypes.c_wchar_p, ctypes.c_wchar_p] + _lib.CDocBuilder_OpenFile.restype = ctypes.c_int + + _lib.CDocBuilder_CreateFileByType.argtypes = [OBJECT_HANDLE, ctypes.c_int] + _lib.CDocBuilder_CreateFileByType.restype = ctypes.c_bool + + _lib.CDocBuilder_CreateFileByExtension.argtypes = [OBJECT_HANDLE, ctypes.c_wchar_p] + _lib.CDocBuilder_CreateFileByExtension.restype = ctypes.c_bool + + _lib.CDocBuilder_SetTmpFolder.argtypes = [OBJECT_HANDLE, ctypes.c_wchar_p] + _lib.CDocBuilder_SetTmpFolder.restype = None + + _lib.CDocBuilder_SaveFileByType.argtypes = [OBJECT_HANDLE, ctypes.c_int, ctypes.c_wchar_p] + _lib.CDocBuilder_SaveFileByType.restype = ctypes.c_int + + _lib.CDocBuilder_SaveFileByTypeWithParams.argtypes = [OBJECT_HANDLE, ctypes.c_int, ctypes.c_wchar_p, ctypes.c_wchar_p] + _lib.CDocBuilder_SaveFileByTypeWithParams.restype = ctypes.c_int + + _lib.CDocBuilder_SaveFileByExtension.argtypes = [OBJECT_HANDLE, ctypes.c_wchar_p, ctypes.c_wchar_p] + _lib.CDocBuilder_SaveFileByExtension.restype = ctypes.c_int + + _lib.CDocBuilder_SaveFileByExtensionWithParams.argtypes = [OBJECT_HANDLE, ctypes.c_wchar_p, ctypes.c_wchar_p, ctypes.c_wchar_p] + _lib.CDocBuilder_SaveFileByExtensionWithParams.restype = ctypes.c_int + + _lib.CDocBuilder_CloseFile.argtypes = [OBJECT_HANDLE] + _lib.CDocBuilder_CloseFile.restype = None + + _lib.CDocBuilder_ExecuteCommand.argtypes = [OBJECT_HANDLE, ctypes.c_wchar_p] + _lib.CDocBuilder_ExecuteCommand.restype = ctypes.c_bool + + _lib.CDocBuilder_ExecuteCommandWithRetValue.argtypes = [OBJECT_HANDLE, ctypes.c_wchar_p, OBJECT_HANDLE] + _lib.CDocBuilder_ExecuteCommandWithRetValue.restype = ctypes.c_bool + + _lib.CDocBuilder_Run.argtypes = [OBJECT_HANDLE, ctypes.c_wchar_p] + _lib.CDocBuilder_Run.restype = ctypes.c_bool + + _lib.CDocBuilder_RunText.argtypes = [OBJECT_HANDLE, ctypes.c_wchar_p] + _lib.CDocBuilder_RunText.restype = ctypes.c_bool + + _lib.CDocBuilder_SetProperty.argtypes = [OBJECT_HANDLE, ctypes.c_wchar_p, ctypes.c_wchar_p] + _lib.CDocBuilder_SetProperty.restype = None + + _lib.CDocBuilder_WriteData.argtypes = [OBJECT_HANDLE, ctypes.c_wchar_p, ctypes.c_wchar_p, ctypes.c_bool] + _lib.CDocBuilder_WriteData.restype = None + + _lib.CDocBuilder_IsSaveWithDoctrendererMode.argtypes = [OBJECT_HANDLE] + _lib.CDocBuilder_IsSaveWithDoctrendererMode.restype = ctypes.c_bool + + _lib.CDocBuilder_GetVersion.argtypes = [OBJECT_HANDLE] + _lib.CDocBuilder_GetVersion.restype = STRING_HANDLE + + _lib.CDocBuilder_GetContext.argtypes = [OBJECT_HANDLE, ctypes.c_bool] + _lib.CDocBuilder_GetContext.restype = OBJECT_HANDLE + + _lib.CDocBuilder_Initialize.argtypes = [] + _lib.CDocBuilder_Initialize.restype = None + + _lib.CDocBuilder_InitializeWithDirectory.argtypes = [ctypes.c_wchar_p] + _lib.CDocBuilder_InitializeWithDirectory.restype = None + + _lib.CDocBuilder_Dispose.argtypes = [] + _lib.CDocBuilder_Dispose.restype = None + + # ===== CDocBuilderContextScope ===== + _lib.CDocBuilderContextScope_Create.argtypes = [] + _lib.CDocBuilderContextScope_Create.restype = OBJECT_HANDLE + + _lib.CDocBuilderContextScope_Copy.argtypes = [OBJECT_HANDLE] + _lib.CDocBuilderContextScope_Copy.restype = OBJECT_HANDLE + + _lib.CDocBuilderContextScope_Destroy.argtypes = [OBJECT_HANDLE] + _lib.CDocBuilderContextScope_Destroy.restype = None + + _lib.CDocBuilderContextScope_Close.argtypes = [OBJECT_HANDLE] + _lib.CDocBuilderContextScope_Close.restype = None + + # ===== CDocBuilderContext ===== + _lib.CDocBuilderContext_Create.argtypes = [] + _lib.CDocBuilderContext_Create.restype = OBJECT_HANDLE + + _lib.CDocBuilderContext_Copy.argtypes = [OBJECT_HANDLE] + _lib.CDocBuilderContext_Copy.restype = OBJECT_HANDLE + + _lib.CDocBuilderContext_Destroy.argtypes = [OBJECT_HANDLE] + _lib.CDocBuilderContext_Destroy.restype = None + + _lib.CDocBuilderContext_CreateUndefined.argtypes = [OBJECT_HANDLE] + _lib.CDocBuilderContext_CreateUndefined.restype = OBJECT_HANDLE + + _lib.CDocBuilderContext_CreateNull.argtypes = [OBJECT_HANDLE] + _lib.CDocBuilderContext_CreateNull.restype = OBJECT_HANDLE + + _lib.CDocBuilderContext_CreateObject.argtypes = [OBJECT_HANDLE] + _lib.CDocBuilderContext_CreateObject.restype = OBJECT_HANDLE + + _lib.CDocBuilderContext_CreateArray.argtypes = [OBJECT_HANDLE, ctypes.c_int] + _lib.CDocBuilderContext_CreateArray.restype = OBJECT_HANDLE + + _lib.CDocBuilderContext_GetGlobal.argtypes = [OBJECT_HANDLE] + _lib.CDocBuilderContext_GetGlobal.restype = OBJECT_HANDLE + + _lib.CDocBuilderContext_CreateScope.argtypes = [OBJECT_HANDLE] + _lib.CDocBuilderContext_CreateScope.restype = OBJECT_HANDLE + + _lib.CDocBuilderContext_IsError.argtypes = [OBJECT_HANDLE] + _lib.CDocBuilderContext_IsError.restype = ctypes.c_bool + + # ===== Utility ===== + _lib.DeleteWCharP.argtypes = [ctypes.c_wchar_p] + _lib.DeleteWCharP.restype = None + + _lib.DeleteCharP.argtypes = [ctypes.c_char_p] + _lib.DeleteCharP.restype = None + +class CDocBuilderValue: + def __init__(self, value=None): + if value is None: + self._internal = _lib.CDocBuilderValue_Create() + elif isinstance(value, bool): + self._internal = _lib.CDocBuilderValue_CreateWithBool(ctypes.c_bool(value)) + elif isinstance(value, int): + self._internal = _lib.CDocBuilderValue_CreateWithInt(ctypes.c_int(value)) + elif isinstance(value, float): + self._internal = _lib.CDocBuilderValue_CreateWithDouble(ctypes.c_double(value)) + elif isinstance(value, str): + self._internal = _lib.CDocBuilderValue_CreateWithString(ctypes.c_wchar_p(value)) + elif isinstance(value, list): + length = len(value) + self._internal = _lib.CDocBuilderValue_CreateArray(length) + for i in range(length): + self.Set(i, value[i]) + elif isinstance(value, dict): + self._internal = _lib.CDocBuilderValue_CreateObject() + for key in value.keys(): + if not isinstance(key, str): + raise TypeError("CDocBuilderValue constructor supports only str keys in dict") + self.SetProperty(key, value[key]) + elif isinstance(value, CDocBuilderValue): + self._internal = _lib.CDocBuilderValue_Copy(value._internal) + elif isinstance(value, OBJECT_HANDLE): + self._internal = value + else: + raise TypeError("Unsupported type for CDocBuilderValue constructor") + self._lib = _lib + + def __del__(self): + # using self._lib instead of global _lib because it might be already garbage collected during this function call + self._lib.CDocBuilderValue_Destroy(self._internal) + + def IsEmpty(self): + return _lib.CDocBuilderValue_IsEmpty(self._internal) + + def Clear(self): + _lib.CDocBuilderValue_Clear(self._internal) + + def IsNull(self): + return _lib.CDocBuilderValue_IsNull(self._internal) + + def IsUndefined(self): + return _lib.CDocBuilderValue_IsUndefined(self._internal) + + def IsBool(self): + return _lib.CDocBuilderValue_IsBool(self._internal) + + def IsInt(self): + return _lib.CDocBuilderValue_IsInt(self._internal) + + def IsDouble(self): + return _lib.CDocBuilderValue_IsDouble(self._internal) + + def IsString(self): + return _lib.CDocBuilderValue_IsString(self._internal) + + def IsFunction(self): + return _lib.CDocBuilderValue_IsFunction(self._internal) + + def IsObject(self): + return _lib.CDocBuilderValue_IsObject(self._internal) + + def IsArray(self): + return _lib.CDocBuilderValue_IsArray(self._internal) + + def GetLength(self): + return _lib.CDocBuilderValue_GetLength(self._internal) + + def ToBool(self): + return _lib.CDocBuilderValue_ToBool(self._internal) + + def ToInt(self): + return _lib.CDocBuilderValue_ToInt(self._internal) + + def ToDouble(self): + return _lib.CDocBuilderValue_ToDouble(self._internal) + + def ToString(self): + strRes = _lib.CDocBuilderValue_ToString(self._internal) + res = ctypes.cast(strRes, ctypes.c_wchar_p).value + _lib.DeleteWCharP(ctypes.cast(strRes, ctypes.c_wchar_p)) + return res + + def GetProperty(self, name): + return CDocBuilderValue(OBJECT_HANDLE(_lib.CDocBuilderValue_GetProperty(self._internal, ctypes.c_wchar_p(name)))) + + def Get(self, key): + if isinstance(key, int): + return CDocBuilderValue(OBJECT_HANDLE(_lib.CDocBuilderValue_GetByIndex(self._internal, ctypes.c_int(key)))) + elif isinstance(key, str): + return CDocBuilderValue(OBJECT_HANDLE(_lib.CDocBuilderValue_GetProperty(self._internal, ctypes.c_wchar_p(key)))) + else: + return None + + def SetProperty(self, name, value): + if not isinstance(value, CDocBuilderValue): + value = CDocBuilderValue(value) + _lib.CDocBuilderValue_SetProperty(self._internal, ctypes.c_wchar_p(name), value._internal) + + def Set(self, key, value): + if not isinstance(value, CDocBuilderValue): + value = CDocBuilderValue(value) + if isinstance(key, int): + _lib.CDocBuilderValue_SetByIndex(self._internal, ctypes.c_int(key), value._internal) + elif isinstance(key, str): + _lib.CDocBuilderValue_SetProperty(self._internal, ctypes.c_wchar_p(key), value._internal) + + def __getitem__(self, key): + return self.Get(key) + + def __setitem__(self, key, value): + self.Set(key, value) + + @staticmethod + def CreateUndefined(): + return CDocBuilderValue(OBJECT_HANDLE(_lib.CDocBuilderValue_CreateUndefined())) + + @staticmethod + def CreateNull(): + return CDocBuilderValue(OBJECT_HANDLE(_lib.CDocBuilderValue_CreateNull())) + + @staticmethod + def CreateArray(length): + return CDocBuilderValue(OBJECT_HANDLE(_lib.CDocBuilderValue_CreateArray(length))) + + @staticmethod + def CreateObject(): + return CDocBuilderValue(OBJECT_HANDLE(_lib.CDocBuilderValue_CreateObject())) + + def Call(self, name, *args): + if len(args) == 0: + return CDocBuilderValue(OBJECT_HANDLE(_lib.CDocBuilderValue_Call0(self._internal, ctypes.c_wchar_p(name)))) + elif len(args) < 7: + values = [] + for i in range(len(args)): + p = args[i] + if not isinstance(p, CDocBuilderValue): + p = CDocBuilderValue(p) + values.append(p) + if len(args) == 1: + return CDocBuilderValue(OBJECT_HANDLE(_lib.CDocBuilderValue_Call1(self._internal, ctypes.c_wchar_p(name), values[0]._internal))) + elif len(args) == 2: + return CDocBuilderValue(OBJECT_HANDLE(_lib.CDocBuilderValue_Call2(self._internal, ctypes.c_wchar_p(name), values[0]._internal, values[1]._internal))) + elif len(args) == 3: + return CDocBuilderValue(OBJECT_HANDLE(_lib.CDocBuilderValue_Call3(self._internal, ctypes.c_wchar_p(name), values[0]._internal, values[1]._internal, values[2]._internal))) + elif len(args) == 4: + return CDocBuilderValue(OBJECT_HANDLE(_lib.CDocBuilderValue_Call4(self._internal, ctypes.c_wchar_p(name), values[0]._internal, values[1]._internal, values[2]._internal, values[3]._internal))) + elif len(args) == 5: + return CDocBuilderValue(OBJECT_HANDLE(_lib.CDocBuilderValue_Call5(self._internal, ctypes.c_wchar_p(name), values[0]._internal, values[1]._internal, values[2]._internal, values[3]._internal, values[4]._internal))) + elif len(args) == 6: + return CDocBuilderValue(OBJECT_HANDLE(_lib.CDocBuilderValue_Call6(self._internal, ctypes.c_wchar_p(name), values[0]._internal, values[1]._internal, values[2]._internal, values[3]._internal, values[4]._internal, values[5]._internal))) + else: + raise TypeError("Call() expects at most 6 arguments") + +class CDocBuilder: + _initialized = False + + def __init__(self): + self._internal = _lib.CDocBuilder_Create() + self._lib = _lib + + def __del__(self): + # using self._lib instead of global _lib because it might be already garbage collected during this function call + self._lib.CDocBuilder_Destroy(self._internal) + + def OpenFile(self, path, params): + return _lib.CDocBuilder_OpenFile(self._internal, ctypes.c_wchar_p(path), ctypes.c_wchar_p(params)) + + def CreateFile(self, type): + if isinstance(type, int): + return _lib.CDocBuilder_CreateFileByType(self._internal, ctypes.c_int(type)) + elif isinstance(type, str): + return _lib.CDocBuilder_CreateFileByExtension(self._internal, ctypes.c_wchar_p(type)) + else: + return False + + def SetTmpFolder(self, folder): + _lib.CDocBuilder_SetTmpFolder(self._internal, ctypes.c_wchar_p(folder)) + + def SaveFile(self, type, path, params=None): + if isinstance(type, int): + if params is None: + return _lib.CDocBuilder_SaveFileByType(self._internal, ctypes.c_int(type), ctypes.c_wchar_p(path)) + else: + return _lib.CDocBuilder_SaveFileByTypeWithParams(self._internal, ctypes.c_int(type), ctypes.c_wchar_p(path), ctypes.c_wchar_p(params)) + elif isinstance(type, str): + if params is None: + return _lib.CDocBuilder_SaveFileByExtension(self._internal, ctypes.c_wchar_p(type), ctypes.c_wchar_p(path)) + else: + return _lib.CDocBuilder_SaveFileByExtensionWithParams(self._internal, ctypes.c_wchar_p(type), ctypes.c_wchar_p(path), ctypes.c_wchar_p(params)) + else: + return -1 + + def CloseFile(self): + _lib.CDocBuilder_CloseFile(self._internal) + + def ExecuteCommand(self, command, retValue=None): + if retValue is None: + return _lib.CDocBuilder_ExecuteCommand(self._internal, ctypes.c_wchar_p(command)) + else: + return _lib.CDocBuilder_ExecuteCommandWithRetValue(self._internal, ctypes.c_wchar_p(command), retValue._internal) + + def Run(self, path): + return _lib.CDocBuilder_Run(self._internal, ctypes.c_wchar_p(path)) + + def RunText(self, commands): + return _lib.CDocBuilder_RunText(self._internal, ctypes.c_wchar_p(commands)) + + def SetProperty(self, param, value): + _lib.CDocBuilder_SetProperty(self._internal, ctypes.c_wchar_p(param), ctypes.c_wchar_p(value)) + + def WriteData(self, path, value, append): + _lib.CDocBuilder_WriteData(self._internal, ctypes.c_wchar_p(path), ctypes.c_wchar_p(value), ctypes.c_bool(append)) + + def IsSaveWithDoctrendererMode(self): + return _lib.CDocBuilder_IsSaveWithDoctrendererMode(self._internal) + + def GetVersion(self): + strVersion = _lib.CDocBuilder_GetVersion(self._internal) + version = ctypes.cast(strVersion, ctypes.c_char_p).value + _lib.DeleteCharP(ctypes.cast(strVersion, ctypes.c_char_p)) + return version + + def GetContext(self, enterContext=True): + return CDocBuilderContext(OBJECT_HANDLE(_lib.CDocBuilder_GetContext(self._internal, ctypes.c_bool(enterContext)))) + + @classmethod + def Initialize(cls, directory=None): + if directory is None: + _lib.CDocBuilder_Initialize() + else: + _lib.CDocBuilder_InitializeWithDirectory(ctypes.c_wchar_p(directory)) + cls._initialized = True + + @classmethod + def Dispose(cls): + if (cls._initialized): + _lib.CDocBuilder_Dispose() + cls._initialized = False + +class CDocBuilderContextScope: + def __init__(self, value=None): + self._lib = _lib + if value is None: + self._internal = _lib.CDocBuilderContextScope_Create() + elif isinstance(value, CDocBuilderContextScope): + self._internal = _lib.CDocBuilderContextScope_Copy(value._internal) + elif isinstance(value, OBJECT_HANDLE): + self._internal = value + else: + raise TypeError("Unsupported type for CDocBuilderContextScope constructor") + self._lib = _lib + + def __del__(self): + # using self._lib instead of global _lib because it might be already garbage collected during this function call + self._lib.CDocBuilderContextScope_Destroy(self._internal) + + def Close(self): + _lib.CDocBuilderContextScope_Close(self._internal) + +class CDocBuilderContext: + def __init__(self, value=None): + if value is None: + self._internal = _lib.CDocBuilderContext_Create() + elif isinstance(value, CDocBuilderContext): + self._internal = _lib.CDocBuilderContext_Copy(value._internal) + elif isinstance(value, OBJECT_HANDLE): + self._internal = value + else: + raise TypeError("Unsupported type for CDocBuilderContext constructor") + self._lib = _lib + + def __del__(self): + # using self._lib instead of global _lib because it might be already garbage collected during this function call + self._lib.CDocBuilderContext_Destroy(self._internal) + + def CreateUndefined(self): + return CDocBuilderValue(OBJECT_HANDLE(_lib.CDocBuilderContext_CreateUndefined(self._internal))) + + def CreateNull(self): + return CDocBuilderValue(OBJECT_HANDLE(_lib.CDocBuilderContext_CreateNull(self._internal))) + + def CreateObject(self): + return CDocBuilderValue(OBJECT_HANDLE(_lib.CDocBuilderContext_CreateObject(self._internal))) + + def CreateArray(self, length): + return CDocBuilderValue(OBJECT_HANDLE(_lib.CDocBuilderContext_CreateArray(self._internal, ctypes.c_int(length)))) + + def GetGlobal(self): + return CDocBuilderValue(OBJECT_HANDLE(_lib.CDocBuilderContext_GetGlobal(self._internal))) + + def CreateScope(self): + return CDocBuilderContextScope(OBJECT_HANDLE(_lib.CDocBuilderContext_CreateScope(self._internal))) + + def IsError(self): + return _lib.CDocBuilderContext_IsError(self._internal) + +# Constants +class FileTypes: + class Document: + _MASK = 0x0040 + DOCX = _MASK + 0x0001 + DOC = _MASK + 0x0002 + ODT = _MASK + 0x0003 + RTF = _MASK + 0x0004 + TXT = _MASK + 0x0005 + DOTX = _MASK + 0x000c + OTT = _MASK + 0x000f + HTML = _MASK + 0x0012 + OFORM_PDF = _MASK + 0x0017 + + class Presentation: + _MASK = 0x0080 + PPTX = _MASK + 0x0001 + PPT = _MASK + 0x0002 + ODP = _MASK + 0x0003 + PPSX = _MASK + 0x0004 + POTX = _MASK + 0x0007 + OTP = _MASK + 0x000a + + class Spreadsheet: + _MASK = 0x0100 + XLSX = _MASK + 0x0001 + XLS = _MASK + 0x0002 + ODS = _MASK + 0x0003 + CSV = _MASK + 0x0004 + XLTX = _MASK + 0x0006 + OTS = _MASK + 0x0009 + + class Graphics: + _PDF_MASK = 0x0200 + PDF = _PDF_MASK + 0x0001 + PDFA = _PDF_MASK + 0x0009 + + _IMAGE_MASK = 0x0400 + JPG = _IMAGE_MASK + 0x0001 + PNG = _IMAGE_MASK + 0x0005 + BMP = _IMAGE_MASK + 0x0008 + +builder_path = os.path.dirname(os.path.realpath(__file__)) +_loadLibrary(builder_path) +CDocBuilder.Initialize(builder_path) + +atexit.register(CDocBuilder.Dispose) diff --git a/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder_func_lib.pro b/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder_func_lib.pro new file mode 100644 index 00000000000..9bfc8f16485 --- /dev/null +++ b/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder_func_lib.pro @@ -0,0 +1,27 @@ +QT -= core +QT -= gui + +TARGET = docbuilder.c + +TEMPLATE = lib + +CONFIG += shared +CONFIG += plugin + +CORE_ROOT_DIR = $$PWD/../../../.. +PWD_ROOT_DIR = $$PWD + +include($$CORE_ROOT_DIR/Common/base.pri) +include($$CORE_ROOT_DIR/Common/3dParty/icu/icu.pri) + +ADD_DEPENDENCY(graphics, kernel, kernel_network, UnicodeConverter, doctrenderer) + +INCLUDEPATH += ../.. + +DEFINES += DOCBUILDER_FUNCTIONS_EXPORT + +SOURCES += \ + docbuilder_functions.cpp + +HEADERS += \ + docbuilder_functions.h diff --git a/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder_functions.cpp b/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder_functions.cpp new file mode 100644 index 00000000000..0cdeda73e62 --- /dev/null +++ b/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder_functions.cpp @@ -0,0 +1,405 @@ +#include "docbuilder_functions.h" + +#include <cstring> +#include <wchar.h> + +// ===== CDocBuilderValue ===== +CDocBuilderValue* CDocBuilderValue_Create() +{ + return new CDocBuilderValue(); +} + +CDocBuilderValue* CDocBuilderValue_Copy(CDocBuilderValue* other) +{ + return new CDocBuilderValue(*other); +} + +void CDocBuilderValue_Destroy(CDocBuilderValue* self) +{ + delete self; +} + +bool CDocBuilderValue_IsEmpty(CDocBuilderValue* self) +{ + return self->IsEmpty(); +} + +void CDocBuilderValue_Clear(CDocBuilderValue* self) +{ + self->Clear(); +} + +bool CDocBuilderValue_IsNull(CDocBuilderValue* self) +{ + return self->IsNull(); +} + +bool CDocBuilderValue_IsUndefined(CDocBuilderValue* self) +{ + return self->IsUndefined(); +} + +bool CDocBuilderValue_IsBool(CDocBuilderValue* self) +{ + return self->IsBool(); +} + +bool CDocBuilderValue_IsInt(CDocBuilderValue* self) +{ + return self->IsInt(); +} + +bool CDocBuilderValue_IsDouble(CDocBuilderValue* self) +{ + return self->IsDouble(); +} + +bool CDocBuilderValue_IsString(CDocBuilderValue* self) +{ + return self->IsString(); +} + +bool CDocBuilderValue_IsFunction(CDocBuilderValue* self) +{ + return self->IsFunction(); +} + +bool CDocBuilderValue_IsObject(CDocBuilderValue* self) +{ + return self->IsObject(); +} + +bool CDocBuilderValue_IsArray(CDocBuilderValue* self) +{ + return self->IsArray(); +} + +unsigned int CDocBuilderValue_GetLength(CDocBuilderValue* self) +{ + return self->GetLength(); +} + +bool CDocBuilderValue_ToBool(CDocBuilderValue* self) +{ + return self->ToBool(); +} + +int CDocBuilderValue_ToInt(CDocBuilderValue* self) +{ + return self->ToInt(); +} + +double CDocBuilderValue_ToDouble(CDocBuilderValue* self) +{ + return self->ToDouble(); +} + +const wchar_t* CDocBuilderValue_ToString(CDocBuilderValue* self) +{ + // NOTE: User is responsible for calling DeleteWCharP() on returned pointer + CString strValue = self->ToString(); + size_t len = wcslen(strValue.c_str()); + wchar_t* strRes = new wchar_t[len + 1]; + memcpy(strRes, strValue.c_str(), (len + 1) * sizeof(wchar_t)); + return strRes; +} + +CDocBuilderValue* CDocBuilderValue_GetProperty(CDocBuilderValue* self, const wchar_t* name) +{ + return new CDocBuilderValue(self->GetProperty(name)); +} + +CDocBuilderValue* CDocBuilderValue_GetByIndex(CDocBuilderValue* self, int index) +{ + return new CDocBuilderValue(self->Get(index)); +} + +void CDocBuilderValue_SetProperty(CDocBuilderValue* self, const wchar_t* name, CDocBuilderValue* value) +{ + self->Set(name, *value); +} + +void CDocBuilderValue_SetByIndex(CDocBuilderValue* self, int index, CDocBuilderValue* value) +{ + self->Set(index, *value); +} + +CDocBuilderValue* CDocBuilderValue_CreateWithBool(bool value) +{ + return new CDocBuilderValue(value); +} + +CDocBuilderValue* CDocBuilderValue_CreateWithInt(int value) +{ + return new CDocBuilderValue(value); +} + +CDocBuilderValue* CDocBuilderValue_CreateWithUInt(unsigned int value) +{ + return new CDocBuilderValue(value); +} + +CDocBuilderValue* CDocBuilderValue_CreateWithDouble(double value) +{ + return new CDocBuilderValue(value); +} + +CDocBuilderValue* CDocBuilderValue_CreateWithString(const wchar_t* value) +{ + return new CDocBuilderValue(value); +} + +CDocBuilderValue* CDocBuilderValue_CreateUndefined() +{ + return new CDocBuilderValue(CDocBuilderValue::CreateUndefined()); +} + +CDocBuilderValue* CDocBuilderValue_CreateNull() +{ + return new CDocBuilderValue(CDocBuilderValue::CreateNull()); +} + +CDocBuilderValue* CDocBuilderValue_CreateArray(int length) +{ + return new CDocBuilderValue(CDocBuilderValue::CreateArray(length)); +} + +CDocBuilderValue* CDocBuilderValue_CreateObject() +{ + return new CDocBuilderValue(CDocBuilderValue::CreateObject()); +} + +CDocBuilderValue* CDocBuilderValue_Call0(CDocBuilderValue* self, const wchar_t* name) +{ + return new CDocBuilderValue(self->Call(name)); +} + +CDocBuilderValue* CDocBuilderValue_Call1(CDocBuilderValue* self, const wchar_t* name, CDocBuilderValue* p1) +{ + return new CDocBuilderValue(self->Call(name, *p1)); +} + +CDocBuilderValue* CDocBuilderValue_Call2(CDocBuilderValue* self, const wchar_t* name, CDocBuilderValue* p1, CDocBuilderValue* p2) +{ + return new CDocBuilderValue(self->Call(name, *p1, *p2)); +} + +CDocBuilderValue* CDocBuilderValue_Call3(CDocBuilderValue* self, const wchar_t* name, CDocBuilderValue* p1, CDocBuilderValue* p2, CDocBuilderValue* p3) +{ + return new CDocBuilderValue(self->Call(name, *p1, *p2, *p3)); +} + +CDocBuilderValue* CDocBuilderValue_Call4(CDocBuilderValue* self, const wchar_t* name, CDocBuilderValue* p1, CDocBuilderValue* p2, CDocBuilderValue* p3, CDocBuilderValue* p4) +{ + return new CDocBuilderValue(self->Call(name, *p1, *p2, *p3, *p4)); +} + +CDocBuilderValue* CDocBuilderValue_Call5(CDocBuilderValue* self, const wchar_t* name, CDocBuilderValue* p1, CDocBuilderValue* p2, CDocBuilderValue* p3, CDocBuilderValue* p4, CDocBuilderValue* p5) +{ + return new CDocBuilderValue(self->Call(name, *p1, *p2, *p3, *p4, *p5)); +} + +CDocBuilderValue* CDocBuilderValue_Call6(CDocBuilderValue* self, const wchar_t* name, CDocBuilderValue* p1, CDocBuilderValue* p2, CDocBuilderValue* p3, CDocBuilderValue* p4, CDocBuilderValue* p5, CDocBuilderValue* p6) +{ + return new CDocBuilderValue(self->Call(name, *p1, *p2, *p3, *p4, *p5, *p6)); +} + +// ===== CDocBuilder ===== +CDocBuilder* CDocBuilder_Create() +{ + return new CDocBuilder(); +} + +void CDocBuilder_Destroy(CDocBuilder* self) +{ + delete self; +} + +int CDocBuilder_OpenFile(CDocBuilder* self, const wchar_t* path, const wchar_t* params) +{ + return self->OpenFile(path, params); +} + +bool CDocBuilder_CreateFileByType(CDocBuilder* self, int type) +{ + return self->CreateFile(type); +} + +bool CDocBuilder_CreateFileByExtension(CDocBuilder* self, const wchar_t* extension) +{ + return self->CreateFile(extension); +} + +void CDocBuilder_SetTmpFolder(CDocBuilder* self, const wchar_t* folder) +{ + self->SetTmpFolder(folder); +} + +int CDocBuilder_SaveFileByType(CDocBuilder* self, int type, const wchar_t* path) +{ + return self->SaveFile(type, path); +} + +int CDocBuilder_SaveFileByTypeWithParams(CDocBuilder* self, int type, const wchar_t* path, const wchar_t* params) +{ + return self->SaveFile(type, path, params); +} + +int CDocBuilder_SaveFileByExtension(CDocBuilder* self, const wchar_t* extension, const wchar_t* path) +{ + return self->SaveFile(extension, path); +} + +int CDocBuilder_SaveFileByExtensionWithParams(CDocBuilder* self, const wchar_t* extension, const wchar_t* path, const wchar_t* params) +{ + return self->SaveFile(extension, path, params); +} + +void CDocBuilder_CloseFile(CDocBuilder* self) +{ + self->CloseFile(); +} + +bool CDocBuilder_ExecuteCommand(CDocBuilder* self, const wchar_t* command) +{ + return self->ExecuteCommand(command); +} + +bool CDocBuilder_ExecuteCommandWithRetValue(CDocBuilder* self, const wchar_t* command, CDocBuilderValue* retValue) +{ + return self->ExecuteCommand(command, retValue); +} + +bool CDocBuilder_Run(CDocBuilder* self, const wchar_t* path) +{ + return self->Run(path); +} + +bool CDocBuilder_RunText(CDocBuilder* self, const wchar_t* commands) +{ + return self->RunTextW(commands); +} + +void CDocBuilder_SetProperty(CDocBuilder* self, const wchar_t* param, const wchar_t* value) +{ + self->SetPropertyW(param, value); +} + +void CDocBuilder_WriteData(CDocBuilder* self, const wchar_t* path, const wchar_t* value, bool append) +{ + self->WriteData(path, value, append); +} + +bool CDocBuilder_IsSaveWithDoctrendererMode(CDocBuilder* self) +{ + return self->IsSaveWithDoctrendererMode(); +} + +char* CDocBuilder_GetVersion(CDocBuilder* self) +{ + // NOTE: User is responsible for calling DeleteCharP() on returned pointer + return self->GetVersion(); +} + +CDocBuilderContext* CDocBuilder_GetContext(CDocBuilder* self, bool enterContext) +{ + return new CDocBuilderContext(self->GetContext(enterContext)); +} + +void CDocBuilder_Initialize() +{ + CDocBuilder::Initialize(); +} + +void CDocBuilder_InitializeWithDirectory(const wchar_t* directory) +{ + CDocBuilder::Initialize(directory); +} + +void CDocBuilder_Dispose() +{ + CDocBuilder::Dispose(); +} + +// ===== CDocBuilderContextScope ===== +CDocBuilderContextScope* CDocBuilderContextScope_Create() +{ + return new CDocBuilderContextScope(); +} + +CDocBuilderContextScope* CDocBuilderContextScope_Copy(CDocBuilderContextScope* other) +{ + return new CDocBuilderContextScope(*other); +} + +void CDocBuilderContextScope_Destroy(CDocBuilderContextScope* self) +{ + delete self; +} + +void CDocBuilderContextScope_Close(CDocBuilderContextScope* self) +{ + self->Close(); +} + +// ===== CDocBuilderContext ===== +CDocBuilderContext* CDocBuilderContext_Create() +{ + return new CDocBuilderContext(); +} + +CDocBuilderContext* CDocBuilderContext_Copy(CDocBuilderContext* other) +{ + return new CDocBuilderContext(*other); +} + +void CDocBuilderContext_Destroy(CDocBuilderContext* self) +{ + delete self; +} + +CDocBuilderValue* CDocBuilderContext_CreateUndefined(CDocBuilderContext* self) +{ + return new CDocBuilderValue(self->CreateUndefined()); +} + +CDocBuilderValue* CDocBuilderContext_CreateNull(CDocBuilderContext* self) +{ + return new CDocBuilderValue(self->CreateNull()); +} + +CDocBuilderValue* CDocBuilderContext_CreateObject(CDocBuilderContext* self) +{ + return new CDocBuilderValue(self->CreateObject()); +} + +CDocBuilderValue* CDocBuilderContext_CreateArray(CDocBuilderContext* self, int length) +{ + return new CDocBuilderValue(self->CreateArray(length)); +} + +CDocBuilderValue* CDocBuilderContext_GetGlobal(CDocBuilderContext* self) +{ + return new CDocBuilderValue(self->GetGlobal()); +} + +CDocBuilderContextScope* CDocBuilderContext_CreateScope(CDocBuilderContext* self) +{ + return new CDocBuilderContextScope(self->CreateScope()); +} + +bool CDocBuilderContext_IsError(CDocBuilderContext* self) +{ + return self->IsError(); +} + +// ===== Utility ===== +void DeleteWCharP(wchar_t* str) +{ + delete[] str; +} + +void DeleteCharP(char* str) +{ + delete[] str; +} diff --git a/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder_functions.h b/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder_functions.h new file mode 100644 index 00000000000..ae3f9b1fda3 --- /dev/null +++ b/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder_functions.h @@ -0,0 +1,136 @@ +#ifndef DOCBUILDER_FUNCTIONS_H +#define DOCBUILDER_FUNCTIONS_H + +#include "docbuilder.h" + +#include "../common/base_export.h" +#ifdef DOCBUILDER_FUNCTIONS_EXPORT +#define DOCBUILDER_FUNC_DECL Q_DECL_EXPORT +#else +#define DOCBUILDER_FUNC_DECL Q_DECL_IMPORT +#endif + +using namespace NSDoctRenderer; + +extern "C" +{ +// ===== CDocBuilderValue ===== +DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderValue_Create(); +DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderValue_Copy(CDocBuilderValue* other); +DOCBUILDER_FUNC_DECL void CDocBuilderValue_Destroy(CDocBuilderValue* self); + +DOCBUILDER_FUNC_DECL bool CDocBuilderValue_IsEmpty(CDocBuilderValue* self); +DOCBUILDER_FUNC_DECL void CDocBuilderValue_Clear(CDocBuilderValue* self); + +DOCBUILDER_FUNC_DECL bool CDocBuilderValue_IsNull(CDocBuilderValue* self); +DOCBUILDER_FUNC_DECL bool CDocBuilderValue_IsUndefined(CDocBuilderValue* self); +DOCBUILDER_FUNC_DECL bool CDocBuilderValue_IsBool(CDocBuilderValue* self); +DOCBUILDER_FUNC_DECL bool CDocBuilderValue_IsInt(CDocBuilderValue* self); +DOCBUILDER_FUNC_DECL bool CDocBuilderValue_IsDouble(CDocBuilderValue* self); +DOCBUILDER_FUNC_DECL bool CDocBuilderValue_IsString(CDocBuilderValue* self); +DOCBUILDER_FUNC_DECL bool CDocBuilderValue_IsFunction(CDocBuilderValue* self); +DOCBUILDER_FUNC_DECL bool CDocBuilderValue_IsObject(CDocBuilderValue* self); +DOCBUILDER_FUNC_DECL bool CDocBuilderValue_IsArray(CDocBuilderValue* self); +// TODO: +// DOCBUILDER_FUNC_DECL bool CDocBuilderValue_IsTypedArray(CDocBuilderValue* self); + +DOCBUILDER_FUNC_DECL unsigned int CDocBuilderValue_GetLength(CDocBuilderValue* self); + +DOCBUILDER_FUNC_DECL bool CDocBuilderValue_ToBool(CDocBuilderValue* self); +DOCBUILDER_FUNC_DECL int CDocBuilderValue_ToInt(CDocBuilderValue* self); +DOCBUILDER_FUNC_DECL double CDocBuilderValue_ToDouble(CDocBuilderValue* self); +DOCBUILDER_FUNC_DECL const wchar_t* CDocBuilderValue_ToString(CDocBuilderValue* self); + +DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderValue_GetProperty(CDocBuilderValue* self, const wchar_t* name); +DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderValue_GetByIndex(CDocBuilderValue* self, int index); + +DOCBUILDER_FUNC_DECL void CDocBuilderValue_SetProperty(CDocBuilderValue* self, const wchar_t* name, CDocBuilderValue* value); +DOCBUILDER_FUNC_DECL void CDocBuilderValue_SetByIndex(CDocBuilderValue* self, int index, CDocBuilderValue* value); + +DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderValue_CreateWithBool(bool value); +DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderValue_CreateWithInt(int value); +DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderValue_CreateWithUInt(unsigned int value); +DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderValue_CreateWithDouble(double value); +DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderValue_CreateWithString(const wchar_t* value); + +DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderValue_CreateUndefined(); +DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderValue_CreateNull(); +DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderValue_CreateArray(int length); +DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderValue_CreateObject(); + +DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderValue_Call0(CDocBuilderValue* self, const wchar_t* name); +DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderValue_Call1(CDocBuilderValue* self, const wchar_t* name, CDocBuilderValue* p1); +DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderValue_Call2(CDocBuilderValue* self, const wchar_t* name, CDocBuilderValue* p1, CDocBuilderValue* p2); +DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderValue_Call3(CDocBuilderValue* self, const wchar_t* name, CDocBuilderValue* p1, CDocBuilderValue* p2, CDocBuilderValue* p3); +DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderValue_Call4(CDocBuilderValue* self, const wchar_t* name, CDocBuilderValue* p1, CDocBuilderValue* p2, CDocBuilderValue* p3, CDocBuilderValue* p4); +DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderValue_Call5(CDocBuilderValue* self, const wchar_t* name, CDocBuilderValue* p1, CDocBuilderValue* p2, CDocBuilderValue* p3, CDocBuilderValue* p4, CDocBuilderValue* p5); +DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderValue_Call6(CDocBuilderValue* self, const wchar_t* name, CDocBuilderValue* p1, CDocBuilderValue* p2, CDocBuilderValue* p3, CDocBuilderValue* p4, CDocBuilderValue* p5, CDocBuilderValue* p6); + +// ===== CDocBuilder ===== +DOCBUILDER_FUNC_DECL CDocBuilder* CDocBuilder_Create(); +DOCBUILDER_FUNC_DECL void CDocBuilder_Destroy(CDocBuilder* self); + +DOCBUILDER_FUNC_DECL int CDocBuilder_OpenFile(CDocBuilder* self, const wchar_t* path, const wchar_t* params); +DOCBUILDER_FUNC_DECL bool CDocBuilder_CreateFileByType(CDocBuilder* self, int type); +DOCBUILDER_FUNC_DECL bool CDocBuilder_CreateFileByExtension(CDocBuilder* self, const wchar_t* extension); + +DOCBUILDER_FUNC_DECL void CDocBuilder_SetTmpFolder(CDocBuilder* self, const wchar_t* folder); + +DOCBUILDER_FUNC_DECL int CDocBuilder_SaveFileByType(CDocBuilder* self, int type, const wchar_t* path); +DOCBUILDER_FUNC_DECL int CDocBuilder_SaveFileByTypeWithParams(CDocBuilder* self, int type, const wchar_t* path, const wchar_t* params); +DOCBUILDER_FUNC_DECL int CDocBuilder_SaveFileByExtension(CDocBuilder* self, const wchar_t* extension, const wchar_t* path); +DOCBUILDER_FUNC_DECL int CDocBuilder_SaveFileByExtensionWithParams(CDocBuilder* self, const wchar_t* extension, const wchar_t* path, const wchar_t* params); + +DOCBUILDER_FUNC_DECL void CDocBuilder_CloseFile(CDocBuilder* self); + +DOCBUILDER_FUNC_DECL bool CDocBuilder_ExecuteCommand(CDocBuilder* self, const wchar_t* command); +DOCBUILDER_FUNC_DECL bool CDocBuilder_ExecuteCommandWithRetValue(CDocBuilder* self, const wchar_t* command, CDocBuilderValue* retValue); + +DOCBUILDER_FUNC_DECL bool CDocBuilder_Run(CDocBuilder* self, const wchar_t* path); +DOCBUILDER_FUNC_DECL bool CDocBuilder_RunText(CDocBuilder* self, const wchar_t* commands); + +DOCBUILDER_FUNC_DECL void CDocBuilder_SetProperty(CDocBuilder* self, const wchar_t* param, const wchar_t* value); + +DOCBUILDER_FUNC_DECL void CDocBuilder_WriteData(CDocBuilder* self, const wchar_t* path, const wchar_t* value, bool append); + +DOCBUILDER_FUNC_DECL bool CDocBuilder_IsSaveWithDoctrendererMode(CDocBuilder* self); + +DOCBUILDER_FUNC_DECL char* CDocBuilder_GetVersion(CDocBuilder* self); + +DOCBUILDER_FUNC_DECL CDocBuilderContext* CDocBuilder_GetContext(CDocBuilder* self, bool enterContext); + +DOCBUILDER_FUNC_DECL void CDocBuilder_Initialize(); +DOCBUILDER_FUNC_DECL void CDocBuilder_InitializeWithDirectory(const wchar_t* directory); +DOCBUILDER_FUNC_DECL void CDocBuilder_Dispose(); + +// ===== CDocBuilderContextScope ===== +DOCBUILDER_FUNC_DECL CDocBuilderContextScope* CDocBuilderContextScope_Create(); +DOCBUILDER_FUNC_DECL CDocBuilderContextScope* CDocBuilderContextScope_Copy(CDocBuilderContextScope* other); +DOCBUILDER_FUNC_DECL void CDocBuilderContextScope_Destroy(CDocBuilderContextScope* self); + +DOCBUILDER_FUNC_DECL void CDocBuilderContextScope_Close(CDocBuilderContextScope* self); + +// ===== CDocBuilderContext ===== +DOCBUILDER_FUNC_DECL CDocBuilderContext* CDocBuilderContext_Create(); +DOCBUILDER_FUNC_DECL CDocBuilderContext* CDocBuilderContext_Copy(CDocBuilderContext* other); +DOCBUILDER_FUNC_DECL void CDocBuilderContext_Destroy(CDocBuilderContext* self); + +DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderContext_CreateUndefined(CDocBuilderContext* self); +DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderContext_CreateNull(CDocBuilderContext* self); +DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderContext_CreateObject(CDocBuilderContext* self); +DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderContext_CreateArray(CDocBuilderContext* self, int length); +// TODO: +// CDocBuilderContext_CreateTypedArray(CDocBuilderContext* self, unsigned char* buffer); + +DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderContext_GetGlobal(CDocBuilderContext* self); + +DOCBUILDER_FUNC_DECL CDocBuilderContextScope* CDocBuilderContext_CreateScope(CDocBuilderContext* self); + +DOCBUILDER_FUNC_DECL bool CDocBuilderContext_IsError(CDocBuilderContext* self); + +// ===== Utility ===== +DOCBUILDER_FUNC_DECL void DeleteWCharP(wchar_t* str); +DOCBUILDER_FUNC_DECL void DeleteCharP(char* str); +} + +#endif // DOCBUILDER_FUNCTIONS_H diff --git a/DesktopEditor/doctrenderer/docbuilder.python/test/docbuilder_func_lib/docbuilder_func_test.pro b/DesktopEditor/doctrenderer/docbuilder.python/test/docbuilder_func_lib/docbuilder_func_test.pro new file mode 100644 index 00000000000..9624461e5ec --- /dev/null +++ b/DesktopEditor/doctrenderer/docbuilder.python/test/docbuilder_func_lib/docbuilder_func_test.pro @@ -0,0 +1,27 @@ +QT -= core +QT -= gui + +TARGET = test + +TEMPLATE = app + +CONFIG -= app_bundle +CONFIG += console + +CORE_ROOT_DIR = $$PWD/../../../../.. +PWD_ROOT_DIR = $$PWD + +include($$CORE_ROOT_DIR/Common/base.pri) + +# Set docbuilder path here +DOCUMENT_BUILDER_INSTALL_PATH=C:/Program Files/ONLYOFFICE/DocumentBuilder + +DEFINES += "DOCUMENT_BUILDER_INSTALL_PATH=\"$$DOCUMENT_BUILDER_INSTALL_PATH\"" +LIBS += -L'$$DOCUMENT_BUILDER_INSTALL_PATH' -ldocbuilder.c + +DESTDIR = $$PWD/build + +INCLUDEPATH += ../../.. + +SOURCES += \ + main.cpp diff --git a/DesktopEditor/doctrenderer/docbuilder.python/test/docbuilder_func_lib/main.cpp b/DesktopEditor/doctrenderer/docbuilder.python/test/docbuilder_func_lib/main.cpp new file mode 100644 index 00000000000..cde089b7aa9 --- /dev/null +++ b/DesktopEditor/doctrenderer/docbuilder.python/test/docbuilder_func_lib/main.cpp @@ -0,0 +1,74 @@ +#include "docbuilder.python/src/docbuilder_functions.h" + +#include <string> +#include <iostream> + +#include "app_builder_lib/utils.cpp" + +#define DECLARE_RAII_DOCBUILDER_FUNC_CLASS( CLASS_NAME ) \ +class CLASS_NAME ## F \ +{ \ +public: \ + CLASS_NAME ## F(CLASS_NAME* internal) { m_internal = internal; } \ + ~CLASS_NAME ## F() { CLASS_NAME ## _Destroy(m_internal); } \ + \ + CLASS_NAME* get() { return m_internal; } \ + \ +private: \ + CLASS_NAME* m_internal; \ +}; + +DECLARE_RAII_DOCBUILDER_FUNC_CLASS(CDocBuilder) +DECLARE_RAII_DOCBUILDER_FUNC_CLASS(CDocBuilderValue) +DECLARE_RAII_DOCBUILDER_FUNC_CLASS(CDocBuilderContext) +DECLARE_RAII_DOCBUILDER_FUNC_CLASS(CDocBuilderContextScope) + +int main() +{ + std::wstring sWorkDirectory = NSUtils::GetBuilderDirectory(); + +#if 0 + // Simple test that shows builder version if everything is correct + CDocBuilder_InitializeWithDirectory(sWorkDirectory.c_str()); + CDocBuilder* pBuilder = CDocBuilder_Create(); + + char* sVersion = CDocBuilder_GetVersion(pBuilder); + std::cout << sVersion << std::endl; + DeleteCharP(sVersion); + + CDocBuilder_Dispose(); + CDocBuilder_Destroy(pBuilder); +#else + // Test is identical to app_builder_lib.pro + // The test uses RAII wrappers - classes with 'F' postfix, which are destroyed automatically + CDocBuilder_InitializeWithDirectory(sWorkDirectory.c_str()); + + CDocBuilderF oBuilder = CDocBuilder_Create(); + CDocBuilder_SetProperty(oBuilder.get(), L"--work-directory", sWorkDirectory.c_str()); + + CDocBuilder_CreateFileByExtension(oBuilder.get(), L"docx"); + + CDocBuilderContextF oContext = CDocBuilder_GetContext(oBuilder.get()); + CDocBuilderContextScopeF oScope = CDocBuilderContext_CreateScope(oContext.get()); + + CDocBuilderValueF oGlobal = CDocBuilderContext_GetGlobal(oContext.get()); + + CDocBuilderValueF oApi = CDocBuilderValue_GetProperty(oGlobal.get(), L"Api"); + CDocBuilderValueF oDocument = CDocBuilderValue_Call0(oApi.get(), L"GetDocument"); + CDocBuilderValueF oParagraph = CDocBuilderValue_Call0(oApi.get(), L"CreateParagraph"); + CDocBuilderValue_Call2(oParagraph.get(), L"SetSpacingAfter", CDocBuilderValueF(CDocBuilderValue_CreateWithInt(1000)).get(), CDocBuilderValueF(CDocBuilderValue_CreateWithBool(false)).get()); + CDocBuilderValue_Call1(oParagraph.get(), L"AddText", CDocBuilderValueF(CDocBuilderValue_CreateWithString(L"Hello, world!")).get()); + CDocBuilderValueF oContent = CDocBuilderContext_CreateArray(oContext.get(), 1); + CDocBuilderValue_SetByIndex(oContent.get(), 0, oParagraph.get()); + CDocBuilderValue_Call1(oDocument.get(), L"InsertContent", oContent.get()); + + std::wstring sProcessDirectory = NSUtils::GetProcessDirectory(); + std::wstring sDstPath = sProcessDirectory + L"/result.docx"; + CDocBuilder_SaveFileByExtension(oBuilder.get(), L"docx", sDstPath.c_str()); + CDocBuilder_CloseFile(oBuilder.get()); + + CDocBuilder_Dispose(); +#endif + + return 0; +} diff --git a/DesktopEditor/doctrenderer/docbuilder.python/test/docbuilder_test.py b/DesktopEditor/doctrenderer/docbuilder.python/test/docbuilder_test.py new file mode 100644 index 00000000000..851847e024f --- /dev/null +++ b/DesktopEditor/doctrenderer/docbuilder.python/test/docbuilder_test.py @@ -0,0 +1,29 @@ +import os +import sys +sys.path.append('path_to_docbuilder') +import docbuilder + +builder = docbuilder.CDocBuilder() + +builder.CreateFile(docbuilder.FileTypes.Document.DOCX) + +context = builder.GetContext() +scope = context.CreateScope() + +globalObj = context.GetGlobal() + +api = globalObj['Api'] +document = api.Call('GetDocument') +paragraph1 = api.Call('CreateParagraph') +paragraph1.Call('SetSpacingAfter', 1000, False) +paragraph1.Call('AddText', 'Hello from Python!') + +paragraph2 = api.Call('CreateParagraph') +paragraph2.Call('AddText', 'Goodbye!') + +content = [paragraph1, paragraph2] +document.Call('InsertContent', content) + +dstPath = os.getcwd() + '/result.docx' +builder.SaveFile(docbuilder.FileTypes.Document.DOCX, dstPath) +builder.CloseFile() diff --git a/DesktopEditor/doctrenderer/docbuilder_p.cpp b/DesktopEditor/doctrenderer/docbuilder_p.cpp index 2382cfb6407..e23743cc8c8 100644 --- a/DesktopEditor/doctrenderer/docbuilder_p.cpp +++ b/DesktopEditor/doctrenderer/docbuilder_p.cpp @@ -30,6 +30,7 @@ * */ #include "docbuilder_p.h" +#include "server.h" std::wstring NSDoctRenderer::CDocBuilder_Private::m_sExternalDirectory = L""; @@ -43,15 +44,18 @@ void CV8RealTimeWorker::_LOGGING_ERROR_(const std::wstring& strType, const std:: using namespace NSJSBase; -CV8RealTimeWorker::CV8RealTimeWorker(NSDoctRenderer::CDocBuilder* pBuilder) +CV8RealTimeWorker::CV8RealTimeWorker(NSDoctRenderer::CDocBuilder* pBuilder, const NSDoctRenderer::DoctRendererEditorType& type, NSDoctRenderer::CDoctRendererConfig* config) { m_nFileType = -1; - m_context = new CJSContext(); + if (NSDoctRenderer::DoctRendererEditorType::INVALID == type) + m_context = new CJSContext(); + else + m_context = NSDoctRenderer::CreateEditorContext(type, config); + CJSContextScope scope(m_context); CJSContext::Embed<CNativeControlEmbed>(false); - CJSContext::Embed<CGraphicsEmbed>(); NSJSBase::CreateDefaults(); JSSmart<CJSTryCatch> try_catch = m_context->GetExceptions(); @@ -61,6 +65,7 @@ CV8RealTimeWorker::CV8RealTimeWorker(NSDoctRenderer::CDocBuilder* pBuilder) JSSmart<CJSObject> global = m_context->GetGlobal(); global->set("window", global); + global->set("self", global); JSSmart<CJSObject> oBuilderJS = CJSContext::createEmbedObject("CBuilderEmbed"); global->set("builderJS", oBuilderJS); @@ -203,21 +208,11 @@ std::string GetCorrectArgument(const std::string& sInput) return sResult; } -bool CV8RealTimeWorker::OpenFile(const std::wstring& sBasePath, const std::wstring& path, const std::string& sString, const std::wstring& sCachePath, CV8Params* pParams) +bool CV8RealTimeWorker::InitVariables() { - LOGGER_SPEED_START(); - CJSContextScope scope(m_context); JSSmart<CJSTryCatch> try_catch = m_context->GetExceptions(); - LOGGER_SPEED_LAP("compile"); - - m_context->runScript(sString, try_catch, sCachePath); - if(try_catch->Check()) - return false; - - LOGGER_SPEED_LAP("run"); - if (true) { std::string sArg = GetCorrectArgument(m_sUtf8ArgumentJSON); @@ -246,6 +241,34 @@ bool CV8RealTimeWorker::OpenFile(const std::wstring& sBasePath, const std::wstri return false; } + if (!m_sJSCodeStart.empty()) + { + m_context->runScript(m_sJSCodeStart, try_catch); + if (try_catch->Check()) + return false; + } + + return true; +} + +bool CV8RealTimeWorker::OpenFile(const std::wstring& sBasePath, const std::wstring& path, const NSDoctRenderer::DoctRendererEditorType& editorType, NSDoctRenderer::CDoctRendererConfig* config, CV8Params* pParams) +{ + LOGGER_SPEED_START(); + + CJSContextScope scope(m_context); + JSSmart<CJSTryCatch> try_catch = m_context->GetExceptions(); + + LOGGER_SPEED_LAP("compile"); + + NSDoctRenderer::RunEditor(editorType, m_context, try_catch, config); + if(try_catch->Check()) + return false; + + LOGGER_SPEED_LAP("run"); + + if (!InitVariables()) + return false; + NSNativeControl::CNativeControl* pNative = NULL; bool bIsBreak = false; @@ -280,6 +303,8 @@ bool CV8RealTimeWorker::OpenFile(const std::wstring& sBasePath, const std::wstri pNative->m_strEditorType = L"document"; else if (1 == m_nFileType) pNative->m_strEditorType = L"presentation"; + else if (7 == m_nFileType) + pNative->m_strEditorType = L"visio"; else pNative->m_strEditorType = L"spreadsheet"; @@ -328,6 +353,8 @@ bool CV8RealTimeWorker::SaveFileWithChanges(int type, const std::wstring& _path, _formatDst = NSDoctRenderer::DoctRendererFormat::XLST; else if (type & AVS_OFFICESTUDIO_FILE_CROSSPLATFORM) _formatDst = NSDoctRenderer::DoctRendererFormat::PDF; + else if (type & AVS_OFFICESTUDIO_FILE_DRAW) + _formatDst = NSDoctRenderer::DoctRendererFormat::VSDT; else if (type & AVS_OFFICESTUDIO_FILE_IMAGE) { _formatDst = NSDoctRenderer::DoctRendererFormat::IMAGE; @@ -337,6 +364,7 @@ bool CV8RealTimeWorker::SaveFileWithChanges(int type, const std::wstring& _path, case 0: { _formatDst = NSDoctRenderer::DoctRendererFormat::DOCT; break; } case 1: { _formatDst = NSDoctRenderer::DoctRendererFormat::PPTT; break; } case 2: { _formatDst = NSDoctRenderer::DoctRendererFormat::XLST; break; } + case 7: { _formatDst = NSDoctRenderer::DoctRendererFormat::VSDT; break; } default: break; } @@ -487,12 +515,12 @@ namespace NSDoctRenderer if (oParent->isArray()) { JSSmart<CJSArray> oParentArray = oParent->toArray(); - oParentArray->set(m_internal->m_parent->m_parent_index, m_internal->m_value.GetPointer()); + oParentArray->set(m_internal->m_parent->m_parent_index, m_internal->m_value); } else if (oParent->isObject() && !m_internal->m_parent->m_parent_prop_name.empty()) { JSSmart<CJSObject> oParentObject = oParent->toObject(); - oParentObject->set(m_internal->m_parent->m_parent_prop_name.c_str(), m_internal->m_value.GetPointer()); + oParentObject->set(m_internal->m_parent->m_parent_prop_name.c_str(), m_internal->m_value); } } @@ -647,10 +675,17 @@ namespace NSDoctRenderer } if (IsEmpty() || !m_internal->m_value->isString()) + { + ret.m_internal->MakeEmpty(); return ret; + } std::wstring sValue = m_internal->m_value->toStringW(); if (sValue.empty()) + { + // return valid empty string + ret.m_internal->MakeEmpty(); return ret; + } size_t len = sValue.length(); wchar_t* buffer = new wchar_t[len + 1]; memcpy(buffer, sValue.c_str(), len * sizeof(wchar_t)); @@ -724,7 +759,7 @@ namespace NSDoctRenderer std::string sPropA = U_TO_UTF8(sProp); value.m_internal->CheckNative(); - m_internal->m_value->toObject()->set(sPropA.c_str(), value.m_internal->m_value.GetPointer()); + m_internal->m_value->toObject()->set(sPropA.c_str(), value.m_internal->m_value); } void CDocBuilderValue::SetProperty(const wchar_t* name, CDocBuilderValue value) { @@ -737,7 +772,7 @@ namespace NSDoctRenderer JSSmart<CJSArray> array = m_internal->m_value->toArray(); value.m_internal->CheckNative(); - array->set(index, value.m_internal->m_value.GetPointer()); + array->set(index, value.m_internal->m_value); } // primitives @@ -785,6 +820,22 @@ namespace NSDoctRenderer return ret; } + CDocBuilderValue CDocBuilderValue::CreateArray(const int& length) + { + CDocBuilderValue ret; + ret.m_internal->m_context = NSJSBase::CJSContext::GetCurrent(); + ret.m_internal->m_value = NSJSBase::CJSContext::createArray(length); + return ret; + } + + CDocBuilderValue CDocBuilderValue::CreateObject() + { + CDocBuilderValue ret; + ret.m_internal->m_context = NSJSBase::CJSContext::GetCurrent(); + ret.m_internal->m_value = NSJSBase::CJSContext::createObject(); + return ret; + } + // Functions CDocBuilderValue CDocBuilderValue::Call(const char* name) { @@ -1205,6 +1256,8 @@ namespace NSDoctRenderer type = AVS_OFFICESTUDIO_FILE_PRESENTATION; else if (L"xlsx" == sType) type = AVS_OFFICESTUDIO_FILE_SPREADSHEET; + else if (L"vsdx" == sType) + type = AVS_OFFICESTUDIO_FILE_DRAW; return CreateFile(type); } @@ -1223,45 +1276,7 @@ namespace NSDoctRenderer char* CDocBuilder::GetVersion() { m_pInternal->Init(); - - if (0 == m_pInternal->m_arDoctSDK.size()) - return NULL; - - std::wstring sFile; - for (std::vector<std::wstring>::iterator i = m_pInternal->m_arDoctSDK.begin(); i != m_pInternal->m_arDoctSDK.end(); i++) - { - if (std::wstring::npos != i->find(L"sdk-all-min.js")) - { - sFile = *i; - break; - } - } - - if (sFile.empty()) - return NULL; - - std::string sData; - if (!NSFile::CFileBinary::ReadAllTextUtf8A(sFile, sData)) - return NULL; - - std::string::size_type startPos = sData.find("Version:"); - if (std::string::npos == startPos) - return NULL; - - startPos += 8; - - std::string::size_type endPos = sData.find(')', startPos); - if (std::string::npos == endPos) - return NULL; - - size_t sSrcLen = endPos - startPos + 1; - if (sSrcLen == 0) - return NULL; - - char* sRet = new char[sSrcLen + 1]; - memcpy(sRet, sData.c_str() + startPos, sSrcLen); - sRet[sSrcLen] = '\0'; - return sRet; + return m_pInternal->GetVersion(); } bool CDocBuilder::Run(const wchar_t* path) @@ -1312,7 +1327,7 @@ namespace NSDoctRenderer while (_start2 < _currentPos && (commands[_start2] == '\t' || commands[_start2] == ' ')) ++_start2; - if (_currentPos > _start2 && (commands[_start2] != '#' && commands[_start2] != '/')) + if (_currentPos > _start2 && (commands[_start2] != '#')) { _commands.push_back(std::string(commands + _start2, _currentPos - _start2)); // DEBUG @@ -1414,12 +1429,18 @@ namespace NSDoctRenderer bIsNoError = (0 == this->OpenFile(_builder_params[0].c_str(), _builder_params[1].c_str())); else if ("CreateFile" == sFuncNum) { - if (L"docx" == _builder_params[0] || L"docxf" == _builder_params[0] || L"oform" == _builder_params[0]) + if (L"docx" == _builder_params[0] || + L"docxf" == _builder_params[0] || + L"oform" == _builder_params[0] || + L"pdf" == _builder_params[0] || + L"form" == _builder_params[0]) bIsNoError = this->CreateFile(AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX); else if (L"pptx" == _builder_params[0]) bIsNoError = this->CreateFile(AVS_OFFICESTUDIO_FILE_PRESENTATION_PPTX); else if (L"xlsx" == _builder_params[0]) bIsNoError = this->CreateFile(AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSX); + else if (L"vsdx" == _builder_params[0]) + bIsNoError = this->CreateFile(AVS_OFFICESTUDIO_FILE_DRAW_VSDX); } else if ("SetTmpFolder" == sFuncNum) this->SetTmpFolder(_builder_params[0].c_str()); @@ -1489,11 +1510,13 @@ namespace NSDoctRenderer else if (sParam == "--work-directory") m_pInternal->m_oParams.m_sWorkDir = std::wstring(value); else if (sParam == "--cache-scripts") - m_pInternal->m_bIsCacheScript = (std::wstring(value) == L"true"); + m_pInternal->m_bIsUseCache = (std::wstring(value) == L"true"); else if (sParam == "--save-use-only-names") { m_pInternal->m_bIsServerSafeVersion = true; m_pInternal->m_sFolderForSaveOnlyUseNames = std::wstring(value); + + CServerInstance::getInstance().Enable(true); } else if (sParam == "--all-fonts-path") { diff --git a/DesktopEditor/doctrenderer/docbuilder_p.h b/DesktopEditor/doctrenderer/docbuilder_p.h index c11263b83c2..9a49b87f276 100644 --- a/DesktopEditor/doctrenderer/docbuilder_p.h +++ b/DesktopEditor/doctrenderer/docbuilder_p.h @@ -32,7 +32,7 @@ #ifndef DOC_BUILDER_PRIVATE #define DOC_BUILDER_PRIVATE -#include "./config.h" +#include "./editors.h" #include "docbuilder.h" #include "doctrenderer.h" @@ -102,12 +102,16 @@ namespace NSDoctRenderer nFormat = AVS_OFFICESTUDIO_FILE_IMAGE_JPG; else if (L"png" == sExt) nFormat = AVS_OFFICESTUDIO_FILE_IMAGE_PNG; + else if (L"vsdx" == sExt) + nFormat = AVS_OFFICESTUDIO_FILE_DRAW_VSDX; else if (L"docxf" == sExt) nFormat = AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCXF; else if (L"oform" == sExt) nFormat = AVS_OFFICESTUDIO_FILE_DOCUMENT_OFORM; else if (L"html" == sExt) nFormat = AVS_OFFICESTUDIO_FILE_DOCUMENT_HTML_IN_CONTAINER; + else if (L"form" == sExt) + nFormat = AVS_OFFICESTUDIO_FILE_DOCUMENT_OFORM_PDF; return nFormat; } } @@ -126,12 +130,12 @@ namespace NSDoctRenderer } ~CString_Private() { - if (m_data) - delete [] m_data; + delete[] m_data; } void Attach(wchar_t* data) { + delete[] m_data; m_data = data; } @@ -139,7 +143,7 @@ namespace NSDoctRenderer { if (copy->m_data) { - delete [] copy->m_data; + delete[] copy->m_data; copy->m_data = NULL; } @@ -150,6 +154,13 @@ namespace NSDoctRenderer copy->m_data = new wchar_t[len + 1]; memcpy(copy->m_data, m_data, (len + 1) * sizeof(wchar_t)); } + + void MakeEmpty() + { + delete[] m_data; + m_data = new wchar_t[1]; + m_data[0] = '\0'; + } }; } @@ -396,6 +407,11 @@ class CJSContextData { m_scopes.push_back(scope); } + + void AddNewScope(NSDoctRenderer::CDocBuilderContextScopeWrap* scope) + { + m_scopes.emplace_back(scope); + } }; class CV8RealTimeWorker @@ -406,12 +422,13 @@ class CV8RealTimeWorker int m_nFileType; std::string m_sUtf8ArgumentJSON; std::string m_sGlobalVariable; + std::string m_sJSCodeStart; CJSContextData m_oContextData; public: - CV8RealTimeWorker(NSDoctRenderer::CDocBuilder* pBuilder); + CV8RealTimeWorker(NSDoctRenderer::CDocBuilder* pBuilder, const NSDoctRenderer::DoctRendererEditorType& type, NSDoctRenderer::CDoctRendererConfig* config); ~CV8RealTimeWorker(); public: @@ -423,35 +440,13 @@ class CV8RealTimeWorker std::string GetGlobalVariable(); std::wstring GetJSVariable(std::wstring sParam); - bool OpenFile(const std::wstring& sBasePath, const std::wstring& path, const std::string& sString, const std::wstring& sCachePath, CV8Params* pParams = NULL); + bool OpenFile(const std::wstring& sBasePath, const std::wstring& path, const NSDoctRenderer::DoctRendererEditorType& editorType, NSDoctRenderer::CDoctRendererConfig* config, CV8Params* pParams = NULL); bool SaveFileWithChanges(int type, const std::wstring& _path, const std::wstring& sJsonParams = L""); + bool InitVariables(); }; namespace NSDoctRenderer { - class CAdditionalData - { - public: - CAdditionalData() {} - virtual ~CAdditionalData() {} - virtual std::string getParam(const std::wstring& name) { return ""; } - }; - - class CDocBuilderParams - { - public: - CDocBuilderParams() : m_bCheckFonts(false), m_sWorkDir(L""), m_bSaveWithDoctrendererMode(false), m_sArgumentJSON(""), m_bIsSystemFonts(true) {} - - public: - bool m_bCheckFonts; - std::wstring m_sWorkDir; - bool m_bSaveWithDoctrendererMode; - std::string m_sArgumentJSON; - - bool m_bIsSystemFonts; - std::vector<std::wstring> m_arFontDirs; - }; - class CDocBuilder_Private : public CDoctRendererConfig { public: @@ -461,7 +456,8 @@ namespace NSDoctRenderer std::wstring m_sTmpFolder; std::wstring m_sFileDir; int m_nFileType; - bool m_bJavascriptBeforeEditor; + + std::wstring m_sCommandsBeforeContextCreated; std::wstring m_sX2tPath; @@ -472,8 +468,6 @@ namespace NSDoctRenderer CDocBuilderParams m_oParams; bool m_bIsInit; - bool m_bIsCacheScript; - bool m_bIsServerSafeVersion; std::wstring m_sFolderForSaveOnlyUseNames; @@ -485,8 +479,8 @@ namespace NSDoctRenderer static std::wstring m_sExternalDirectory; public: CDocBuilder_Private() : CDoctRendererConfig(), m_sTmpFolder(NSFile::CFileBinary::GetTempPath()), m_nFileType(-1), - m_pWorker(NULL), m_pAdditionalData(NULL), m_bIsInit(false), m_bIsCacheScript(true), m_bIsServerSafeVersion(false), - m_sGlobalVariable(""), m_bIsGlobalVariableUse(false), m_pParent(NULL), m_bJavascriptBeforeEditor(false) + m_pWorker(NULL), m_pAdditionalData(NULL), m_bIsInit(false), m_bIsServerSafeVersion(false), + m_sGlobalVariable(""), m_bIsGlobalVariableUse(false), m_pParent(NULL), m_sCommandsBeforeContextCreated(L"") { } @@ -598,6 +592,11 @@ namespace NSDoctRenderer sEmptyPath = sEmptyPath + L"xlsx.bin"; m_nFileType = 2; } + else if (type & AVS_OFFICESTUDIO_FILE_DRAW) + { + sEmptyPath = sEmptyPath + L"vsdx.bin"; + m_nFileType = 7; + } else return false; @@ -611,7 +610,10 @@ namespace NSDoctRenderer if (type & AVS_OFFICESTUDIO_FILE_DOCUMENT) { - sEmptyPath = sEmptyPath + L"new.docx"; + if (type == AVS_OFFICESTUDIO_FILE_DOCUMENT_OFORM_PDF) + sEmptyPath = sEmptyPath + L"new.pdf"; + else + sEmptyPath = sEmptyPath + L"new.docx"; m_nFileType = 0; } else if (type & AVS_OFFICESTUDIO_FILE_PRESENTATION) @@ -624,6 +626,11 @@ namespace NSDoctRenderer sEmptyPath = sEmptyPath + L"new.xlsx"; m_nFileType = 2; } + else if (type & AVS_OFFICESTUDIO_FILE_DRAW) + { + sEmptyPath = sEmptyPath + L"new.vsdx"; + m_nFileType = 7; + } else return false; @@ -634,9 +641,6 @@ namespace NSDoctRenderer NSDirectory::CreateDirectory(m_sFileDir + L"/changes"); } - if (m_bJavascriptBeforeEditor) - CheckWorkerAfterOpen(); - return bRet; #else std::wstring sPath = m_sX2tPath + L"/empty/new."; @@ -646,6 +650,8 @@ namespace NSDoctRenderer sPath += L"pptx"; else if (type & AVS_OFFICESTUDIO_FILE_SPREADSHEET) sPath += L"xlsx"; + else if (type & AVS_OFFICESTUDIO_FILE_DRAW) + sPath += L"vsdx"; return this->OpenFile(sPath, L""); #endif } @@ -721,22 +727,13 @@ namespace NSDoctRenderer oBuilder.WriteEncodeXmlString(sFolder); oBuilder.WriteString(L"/Editor.bin</m_sFileTo><m_nFormatTo>8192</m_nFormatTo>"); - if (!m_bIsNotUseConfigAllFontsDir) - { - oBuilder.WriteString(L"<m_sFontDir>"); - oBuilder.WriteEncodeXmlString(m_sX2tPath + L"/sdkjs/common"); - oBuilder.WriteString(L"</m_sFontDir>"); - } - else - { - oBuilder.WriteString(L"<m_sFontDir>"); - oBuilder.WriteEncodeXmlString(NSFile::GetDirectoryName(m_strAllFonts)); - oBuilder.WriteString(L"</m_sFontDir>"); + oBuilder.WriteString(L"<m_sFontDir>"); + oBuilder.WriteEncodeXmlString(NSFile::GetDirectoryName(m_strAllFonts)); + oBuilder.WriteString(L"</m_sFontDir>"); - oBuilder.WriteString(L"<m_sAllFontsPath>"); - oBuilder.WriteEncodeXmlString(m_strAllFonts); - oBuilder.WriteString(L"</m_sAllFontsPath>"); - } + oBuilder.WriteString(L"<m_sAllFontsPath>"); + oBuilder.WriteEncodeXmlString(m_strAllFonts); + oBuilder.WriteString(L"</m_sAllFontsPath>"); oBuilder.WriteString(L"<m_bIsNoBase64>true</m_bIsNoBase64>"); oBuilder.WriteString(L"<m_sThemeDir>./sdkjs/slide/themes</m_sThemeDir><m_bDontSaveAdditional>true</m_bDontSaveAdditional>"); @@ -924,17 +921,15 @@ namespace NSDoctRenderer m_nFileType = 1; if (oChecker.nFileType & AVS_OFFICESTUDIO_FILE_SPREADSHEET) m_nFileType = 2; + if (oChecker.nFileType & AVS_OFFICESTUDIO_FILE_DRAW) + m_nFileType = 7; int nReturnCode = ConvertToInternalFormat(m_sFileDir, sFileCopy, params); LOGGER_SPEED_LAP("open_convert"); if (0 == nReturnCode) - { - if (m_bJavascriptBeforeEditor) - CheckWorkerAfterOpen(); return 0; - } NSDirectory::DeleteDirectory(m_sFileDir); m_sFileDir = L""; @@ -1045,22 +1040,13 @@ namespace NSDoctRenderer oBuilder.WriteString(L"</m_sThemeDir><m_bFromChanges>true</m_bFromChanges><m_bDontSaveAdditional>true</m_bDontSaveAdditional>"); oBuilder.WriteString(L"<m_nCsvTxtEncoding>46</m_nCsvTxtEncoding><m_nCsvDelimiter>4</m_nCsvDelimiter>"); - if (!m_bIsNotUseConfigAllFontsDir) - { - oBuilder.WriteString(L"<m_sFontDir>"); - oBuilder.WriteEncodeXmlString(m_sX2tPath + L"/sdkjs/common"); - oBuilder.WriteString(L"</m_sFontDir>"); - } - else - { - oBuilder.WriteString(L"<m_sFontDir>"); - oBuilder.WriteEncodeXmlString(NSFile::GetDirectoryName(m_strAllFonts)); - oBuilder.WriteString(L"</m_sFontDir>"); + oBuilder.WriteString(L"<m_sFontDir>"); + oBuilder.WriteEncodeXmlString(NSFile::GetDirectoryName(m_strAllFonts)); + oBuilder.WriteString(L"</m_sFontDir>"); - oBuilder.WriteString(L"<m_sAllFontsPath>"); - oBuilder.WriteEncodeXmlString(m_strAllFonts); - oBuilder.WriteString(L"</m_sAllFontsPath>"); - } + oBuilder.WriteString(L"<m_sAllFontsPath>"); + oBuilder.WriteEncodeXmlString(m_strAllFonts); + oBuilder.WriteString(L"</m_sAllFontsPath>"); if (!sConvertionParams.empty()) { @@ -1229,37 +1215,25 @@ namespace NSDoctRenderer { if (NULL == m_pWorker) { - m_pWorker = new CV8RealTimeWorker(m_pParent); + NSDoctRenderer::DoctRendererEditorType editorType = GetEditorType(); + if (NSDoctRenderer::DoctRendererEditorType::INVALID == editorType) + return false; + + m_pWorker = new CV8RealTimeWorker(m_pParent, editorType, this); m_pWorker->m_sUtf8ArgumentJSON = m_oParams.m_sArgumentJSON; m_pWorker->m_sGlobalVariable = m_sGlobalVariable; + m_pWorker->m_sJSCodeStart = U_TO_UTF8(m_sCommandsBeforeContextCreated); + m_sCommandsBeforeContextCreated = L""; - return CheckWorkerAfterOpen(); - } - return true; - } + m_pWorker->m_nFileType = m_nFileType; - bool CheckWorkerAfterOpen() - { - if (!m_pWorker) - return false; + CV8Params oParams; + oParams.IsServerSaveVersion = m_bIsServerSafeVersion; + oParams.DocumentDirectory = m_sFileDir; - m_pWorker->m_nFileType = m_nFileType; - if (-1 == m_nFileType) - { - m_bJavascriptBeforeEditor = true; - return false; + return m_pWorker->OpenFile(m_sX2tPath, m_sFileDir, editorType, this, &oParams); } - - m_bJavascriptBeforeEditor = false; - std::wstring sCachePath = L""; - if (m_bIsCacheScript) - sCachePath = GetScriptCache(); - - CV8Params oParams; - oParams.IsServerSaveVersion = m_bIsServerSafeVersion; - oParams.DocumentDirectory = m_sFileDir; - - return m_pWorker->OpenFile(m_sX2tPath, m_sFileDir, GetScript(), sCachePath, &oParams); + return true; } int SaveFile(const std::wstring& ext, const std::wstring& path, const wchar_t* params = NULL) @@ -1273,126 +1247,56 @@ namespace NSDoctRenderer if (command.length() < 7 && !retValue) // minimum command (!!!) return true; + if (m_nFileType == -1) + { + m_sCommandsBeforeContextCreated += command; + return true; + } + Init(); - CheckWorker(); - return m_pWorker->ExecuteCommand(command, retValue); + if (CheckWorker()) + return m_pWorker->ExecuteCommand(command, retValue); + + return false; } - CDocBuilderContext GetContext() + CDocBuilderContext GetContext(bool enterContext) { CDocBuilderContext ctx; - CheckWorker(); + if (!CheckWorker()) + return ctx; ctx.m_internal->m_context = m_pWorker->m_context; ctx.m_internal->m_context_data = &m_pWorker->m_oContextData; - return ctx; - } - std::string GetScript() - { - std::vector<std::wstring>* arSdkFiles = NULL; - - switch (m_nFileType) - { - case 0: + if (enterContext) { - arSdkFiles = &m_arDoctSDK; - break; - } - case 1: - { - arSdkFiles = &m_arPpttSDK; - break; - } - case 2: - { - arSdkFiles = &m_arXlstSDK; - break; - } - default: - return ""; - } - - std::string strScript = ""; - for (size_t i = 0; i < m_arrFiles.size(); ++i) - { - strScript += ReadScriptFile(m_arrFiles[i]); - strScript += "\n\n"; - } - - if (NULL != arSdkFiles) - { - for (const std::wstring& i : *arSdkFiles) - { - strScript += ReadScriptFile(i); - strScript += "\n\n"; - } + CDocBuilderContextScopeWrap* scopeWrap = new CDocBuilderContextScopeWrap(); + scopeWrap->m_scope = new CJSContextScope(m_pWorker->m_context); + m_pWorker->m_oContextData.AddNewScope(scopeWrap); } - if (m_nFileType == 2) - strScript += "\n$.ready();"; - - return strScript; + return ctx; } - std::wstring GetScriptCache() + NSDoctRenderer::DoctRendererEditorType GetEditorType() { - std::vector<std::wstring>* arSdkFiles = NULL; switch (m_nFileType) { case 0: - { - arSdkFiles = &m_arDoctSDK; - break; - } + return NSDoctRenderer::DoctRendererEditorType::WORD; case 1: - { - arSdkFiles = &m_arPpttSDK; - break; - } + return NSDoctRenderer::DoctRendererEditorType::SLIDE; case 2: - { - arSdkFiles = &m_arXlstSDK; - break; - } + return NSDoctRenderer::DoctRendererEditorType::CELL; + case 7: + return NSDoctRenderer::DoctRendererEditorType::VISIO; default: - return L""; - } - - if (0 < arSdkFiles->size()) - { - return NSFile::GetDirectoryName(*arSdkFiles->begin()) + L"/sdk-all.cache"; - } - return L""; - } - - 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; + break; } - - std::string sReturn((char*)(pData + nOffset), nSize - nOffset); - - RELEASEARRAYOBJECTS(pData); - return sReturn; + return NSDoctRenderer::DoctRendererEditorType::INVALID; } void WriteData(const wchar_t* path, const wchar_t* value, const bool& append) diff --git a/DesktopEditor/doctrenderer/doctrenderer.cpp b/DesktopEditor/doctrenderer/doctrenderer.cpp index 08c94a603a9..ac24efa8b24 100644 --- a/DesktopEditor/doctrenderer/doctrenderer.cpp +++ b/DesktopEditor/doctrenderer/doctrenderer.cpp @@ -39,8 +39,9 @@ #include "embed/Default.h" #include "embed/NativeControlEmbed.h" #include "embed/GraphicsEmbed.h" +#include "embed/DrawingFileEmbed.h" -#include "./config.h" +#include "./editors.h" #include <iostream> namespace NSDoctRenderer @@ -99,9 +100,8 @@ namespace NSDoctRenderer std::wstring m_sJsonParams; int m_nLcid; - std::wstring m_sScriptsCacheDirectory; - std::vector<int> m_arThemesThumbnailsParams; + public: CExecuteParams() : m_arChanges() { @@ -123,7 +123,6 @@ namespace NSDoctRenderer m_nMailMergeIndexEnd = -1; m_nLcid = -1; - m_sScriptsCacheDirectory = L""; } ~CExecuteParams() { @@ -152,13 +151,13 @@ namespace NSDoctRenderer { m_nCountChangesItems = oNodeChanges.ReadAttributeInt(L"TopItem", -1); - std::vector<XmlUtils::CXmlNode> oNodes; + std::vector<XmlUtils::CXmlNode> oNodes; oNodeChanges.GetNodes(L"Change", oNodes); - size_t nCount = oNodes.size(); - for (size_t i = 0; i < nCount; ++i) + size_t nCount = oNodes.size(); + for (size_t i = 0; i < nCount; ++i) { - XmlUtils::CXmlNode & _node = oNodes[i]; + XmlUtils::CXmlNode& _node = oNodes[i]; m_arChanges.push_back(_node.GetText()); } } @@ -175,8 +174,6 @@ namespace NSDoctRenderer m_nLcid = oNode.ReadValueInt(L"Lcid", -1); m_sJsonParams = oNode.ReadValueString(L"JsonParams"); - m_sScriptsCacheDirectory = oNode.ReadValueString(L"ScriptsCacheDirectory", L""); - m_arThemesThumbnailsParams.clear(); std::wstring sThemesThumbnailsParams = oNode.ReadValueString(L"ThemesThumbnailsParams"); if (!sThemesThumbnailsParams.empty()) @@ -190,21 +187,21 @@ namespace NSDoctRenderer return true; } }; -} +} // namespace NSDoctRenderer namespace NSDoctRenderer { std::wstring string_replaceAll(std::wstring str, const std::wstring& from, const std::wstring& to) { size_t start_pos = 0; - while((start_pos = str.find(from, start_pos)) != std::wstring::npos) + while ((start_pos = str.find(from, start_pos)) != std::wstring::npos) { str.replace(start_pos, from.length(), to); start_pos += to.length(); } return str; } -} +} // namespace NSDoctRenderer namespace NSDoctRenderer { @@ -236,14 +233,16 @@ namespace NSDoctRenderer std::vector<std::wstring> m_arImagesInChanges; + IOfficeDrawingFile* m_pDrawingFile; + public: CDoctRenderer_Private(const std::wstring& sAllFontsPath = L"") : CDoctRendererConfig() { LoadConfig(NSFile::GetProcessDirectory(), sAllFontsPath); + m_pDrawingFile = NULL; } ~CDoctRenderer_Private() { - } void LoadConfig(const std::wstring& sConfigDir, const std::wstring& sAllFontsPath = L"") { @@ -256,7 +255,6 @@ namespace NSDoctRenderer } public: - static void _LOGGING_ERROR_(const std::wstring& strType, const std::wstring& strError) { #if 0 @@ -281,15 +279,11 @@ namespace NSDoctRenderer } static bool Doct_renderer_SaveFile(CExecuteParams* pParams, - NSNativeControl::CNativeControl* pNative, - JSSmart<CJSContext> context, - JSSmart<CJSValue>* args, - std::wstring& strError, - JSSmart<CJSObject>& api_js_maybe_null, - bool bIsPdfBase64 = false) + NSNativeControl::CNativeControl* pNative, JSSmart<CJSContext> context, + JSSmart<CJSValue>* args, std::wstring& strError, JSSmart<CJSObject>& api_js_maybe_null) { JSSmart<CJSTryCatch> try_catch = context->GetExceptions(); - JSSmart<CJSObject> global_js = context->GetGlobal(); + JSSmart<CJSObject> global_js = context->GetGlobal(); JSSmart<CJSObject> js_objectApi = api_js_maybe_null; if (!js_objectApi.IsInit() || js_objectApi->isUndefined()) @@ -313,7 +307,7 @@ namespace NSDoctRenderer case DoctRendererFormat::XLST: { JSSmart<CJSValue> js_result2 = js_objectApi->call_func("asc_nativeGetFileData", 1, args); - if(try_catch->Check()) + if (try_catch->Check()) { strError = L"code=\"save\""; bIsBreak = true; @@ -362,14 +356,14 @@ namespace NSDoctRenderer } JSSmart<CJSValue> js_result1 = js_objectApi->call_func("asc_nativeCalculateFile", 1, args); - if(try_catch->Check()) + if (try_catch->Check()) { strError = L"code=\"calculate\""; bIsBreak = true; } JSSmart<CJSValue> js_result2 = js_objectApi->call_func("asc_nativeGetHtml", 1, args); - if(try_catch->Check()) + if (try_catch->Check()) { strError = L"code=\"save\""; bIsBreak = true; @@ -401,7 +395,7 @@ namespace NSDoctRenderer } JSSmart<CJSValue> js_result2 = js_objectApi->call_func("asc_nativeCalculateFile", 1, args); - if(try_catch->Check()) + if (try_catch->Check()) { strError = L"code=\"calculate\""; bIsBreak = true; @@ -412,7 +406,7 @@ namespace NSDoctRenderer if (!bIsBreak) { JSSmart<CJSValue> js_result1 = js_objectApi->call_func("asc_nativePrintPagesCount", 1, args); - if(try_catch->Check()) + if (try_catch->Check()) { strError = L"code=\"calculate\""; bIsBreak = true; @@ -422,8 +416,7 @@ namespace NSDoctRenderer } // RENDER - if (!bIsBreak && - (DoctRendererFormat::PDF == pParams->m_eDstFormat || DoctRendererFormat::IMAGE == pParams->m_eDstFormat)) + if (!bIsBreak && (DoctRendererFormat::PDF == pParams->m_eDstFormat || DoctRendererFormat::IMAGE == pParams->m_eDstFormat)) { if (pParams->m_sJsonParams.empty()) { @@ -447,33 +440,22 @@ namespace NSDoctRenderer } JSSmart<CJSValue> js_result2 = js_objectApi->call_func("asc_nativeGetPDF", 1, args); - if(try_catch->Check()) + if (try_catch->Check()) { strError = L"code=\"save\""; bIsBreak = true; } - else + else if (!js_result2->isNull()) { JSSmart<CJSTypedArray> typedArray = js_result2->toTypedArray(); NSJSBase::CJSDataBuffer oBuffer = typedArray->getData(); + DWORD bufferSize = (pNative->m_nSaveBinaryLen == 0) ? (DWORD)oBuffer.Len : (DWORD)pNative->m_nSaveBinaryLen; + NSFile::CFileBinary oFile; if (true == oFile.CreateFileW(pParams->m_strDstFilePath)) { - if (!bIsPdfBase64) - { - oFile.WriteFile(oBuffer.Data, (DWORD)pNative->m_nSaveBinaryLen); - } - else - { - char* pDataDst = NULL; - int nDataDst = 0; - if (NSFile::CBase64Converter::Encode(oBuffer.Data, pNative->m_nSaveBinaryLen, pDataDst, nDataDst)) - { - oFile.WriteFile((BYTE*)pDataDst, (DWORD)nDataDst); - RELEASEARRAYOBJECTS(pDataDst); - } - } + oFile.WriteFile(oBuffer.Data, bufferSize); oFile.CloseFile(); } @@ -500,7 +482,7 @@ namespace NSDoctRenderer js_result2 = js_objectApi->call_func("asc_nativeGetThemeThumbnail", 1, args); } - if(try_catch->Check()) + if (try_catch->Check()) { strError = L"code=\"save\""; bIsBreak = true; @@ -540,32 +522,66 @@ namespace NSDoctRenderer } break; } + case DoctRendererFormat::WATERMARK: + { + if (!pParams->m_sJsonParams.empty()) + { + std::string sTmp = U_TO_UTF8((pParams->m_sJsonParams)); + args[0] = context->JSON_Parse(sTmp.c_str()); + + JSSmart<CJSValue> js_watermark = js_objectApi->call_func("asc_nativeGetWatermark", 1, args); + if (!try_catch->Check() && js_watermark->isString()) + { + std::string sWatermark = js_watermark->toStringA(); + std::string::size_type pos = sWatermark.find(','); + if (pos != std::string::npos) + { + int nInputSize = (int)(sWatermark.length() - pos) - 1; + char* pInput = (char*)(sWatermark.c_str() + pos + 1); + + int nOutputSize = 0; + BYTE* pOutput = NULL; + + if (NSFile::CBase64Converter::Decode(pInput, nInputSize, pOutput, nOutputSize)) + { + NSFile::CFileBinary oFileWatermark; + if (oFileWatermark.CreateFileW(pParams->m_strDstFilePath)) + { + oFileWatermark.WriteFile(pOutput, nOutputSize); + oFileWatermark.CloseFile(); + } + + RELEASEARRAYOBJECTS(pOutput); + } + } + } + } + break; + } default: break; } return bIsBreak; } - bool ExecuteScript(const std::string& strScript, const std::wstring& sCachePath, std::wstring& strError, std::wstring& strReturnParams) + bool ExecuteScript(NSDoctRenderer::DoctRendererEditorType& editorType, std::wstring& strError, std::wstring& strReturnParams) { - if (strScript.empty() && sCachePath.empty()) return true; - LOGGER_SPEED_START(); bool bIsBreak = false; - JSSmart<CJSContext> context = new CJSContext(); + JSSmart<CJSContext> context = NSDoctRenderer::CreateEditorContext(editorType, this); if (true) { CJSContextScope scope(context); CJSContext::Embed<CNativeControlEmbed>(false); - CJSContext::Embed<CGraphicsEmbed>(); NSJSBase::CreateDefaults(); - JSSmart<CJSTryCatch> try_catch = context->GetExceptions(); + JSSmart<CJSTryCatch> try_catch = context->GetExceptions(); JSSmart<CJSObject> global_js = context->GetGlobal(); global_js->set("window", global_js); + global_js->set("self", global_js); JSSmart<CJSObject> oNativeCtrl = CJSContext::createEmbedObject("CNativeControlEmbed"); global_js->set("native", oNativeCtrl); @@ -575,8 +591,12 @@ namespace NSDoctRenderer LOGGER_SPEED_LAP("compile"); - JSSmart<CJSValue> res = context->runScript(strScript, try_catch, sCachePath); - if(try_catch->Check()) + NSDoctRenderer::RunEditor(editorType, context, try_catch, this); + + if (editorType == DoctRendererEditorType::PDF && m_pDrawingFile) + EmbedDrawingFile(context, m_pDrawingFile); + + if (try_catch->Check()) { strError = L"code=\"run\""; bIsBreak = true; @@ -606,27 +626,20 @@ namespace NSDoctRenderer // Api object JSSmart<CJSObject> js_objectApi; - // OPEN + bool bIsWatermark = (m_oParams.m_eDstFormat == NSDoctRenderer::DoctRendererFormat::WATERMARK) ? true : false; + JSSmart<CJSValue> openOptions; + if (!bIsBreak) { - CChangesWorker oWorkerLoader; - int nVersion = oWorkerLoader.OpenNative(pNative->GetFilePath()); - - JSSmart<CJSValue> args_open[4]; - args_open[0] = oWorkerLoader.GetDataFull()->toValue(); - args_open[1] = CJSContext::createInt(nVersion); - std::wstring sXlsx = NSFile::GetDirectoryName(pNative->GetFilePath()) + L"/Editor.xlsx"; - args_open[2] = NSFile::CFileBinary::Exists(sXlsx) ? CJSContext::createString(sXlsx) : CJSContext::createUndefined(); - if (!m_oParams.m_sJsonParams.empty()) { std::string sTmp = U_TO_UTF8((m_oParams.m_sJsonParams)); - args_open[3] = context->JSON_Parse(sTmp.c_str()); + openOptions = context->JSON_Parse(sTmp.c_str()); if (0 < m_oParams.m_nLcid) { - if (args_open[3]->isObject()) - args_open[3]->toObject()->set("locale", CJSContext::createInt(m_oParams.m_nLcid)); + if (openOptions->isObject()) + openOptions->toObject()->set("locale", CJSContext::createInt(m_oParams.m_nLcid)); } } else @@ -634,10 +647,40 @@ namespace NSDoctRenderer JSSmart<CJSObject> optionsParams = CJSContext::createObject(); if (0 < m_oParams.m_nLcid) optionsParams->set("locale", CJSContext::createInt(m_oParams.m_nLcid)); - args_open[3] = optionsParams->toValue(); + openOptions = optionsParams->toValue(); + } + } + + // OPEN + if (!bIsBreak) + { + if (!bIsWatermark) + { + CChangesWorker oWorkerLoader; + int nVersion = 0; + + if (editorType == DoctRendererEditorType::PDF) + nVersion = -1; + else + nVersion = oWorkerLoader.OpenNative(pNative->GetFilePath()); + + JSSmart<CJSValue> args_open[4]; + args_open[0] = (nVersion != -1) ? oWorkerLoader.GetDataFull()->toValue() : CJSContext::createUndefined(); + args_open[1] = CJSContext::createInt(nVersion); + std::wstring sXlsx = NSFile::GetDirectoryName(pNative->GetFilePath()) + L"/Editor.xlsx"; + args_open[2] = NSFile::CFileBinary::Exists(sXlsx) ? CJSContext::createString(sXlsx) : CJSContext::createUndefined(); + args_open[3] = openOptions; + + global_js->call_func("NativeOpenFileData", 4, args_open); + } + else + { + JSSmart<CJSValue> args_open[1]; + args_open[0] = openOptions; + + global_js->call_func("NativeCreateApi", 1, args_open); } - global_js->call_func("NativeOpenFileData", 4, args_open); if (try_catch->Check()) { strError = L"code=\"open\""; @@ -655,7 +698,7 @@ namespace NSDoctRenderer LOGGER_SPEED_LAP("open"); // CHANGES - if (!bIsBreak) + if (!bIsBreak && !bIsWatermark) { if (m_oParams.m_arChanges.size() != 0) { @@ -694,8 +737,7 @@ namespace NSDoctRenderer // images in changes if (NULL != pNative) { - for (std::map<std::wstring, bool>::const_iterator iter = pNative->m_mapImagesInChanges.begin(); - iter != pNative->m_mapImagesInChanges.end(); iter++) + for (std::map<std::wstring, bool>::const_iterator iter = pNative->m_mapImagesInChanges.begin(); iter != pNative->m_mapImagesInChanges.end(); iter++) { m_arImagesInChanges.push_back(iter->first); } @@ -706,9 +748,7 @@ namespace NSDoctRenderer LOGGER_SPEED_LAP("changes"); bool bIsMailMerge = false; - if (!m_oParams.m_strMailMergeDatabasePath.empty() && - m_oParams.m_nMailMergeIndexEnd >= m_oParams.m_nMailMergeIndexStart && - m_oParams.m_nMailMergeIndexEnd >= 0) + if (!m_oParams.m_strMailMergeDatabasePath.empty() && m_oParams.m_nMailMergeIndexEnd >= m_oParams.m_nMailMergeIndexStart && m_oParams.m_nMailMergeIndexEnd >= 0) { bIsMailMerge = true; } @@ -765,11 +805,10 @@ namespace NSDoctRenderer if (!bIsBreak) { - std::string sFieldUtf8 = NSFile::CUtf8Converter::GetUtf8StringFromUnicode2(m_oParams.m_strMailMergeField.c_str(), - (LONG)m_oParams.m_strMailMergeField.length()); + std::string sFieldUtf8 = NSFile::CUtf8Converter::GetUtf8StringFromUnicode2(m_oParams.m_strMailMergeField.c_str(), (LONG)m_oParams.m_strMailMergeField.length()); strReturnParams += L"<MailMergeFields>"; - for (int nIndexMM = m_oParams.m_nMailMergeIndexStart; nIndexMM <= m_oParams.m_nMailMergeIndexEnd && !bIsBreak; ++nIndexMM) + for (int nIndexMM = m_oParams.m_nMailMergeIndexStart; nIndexMM <= m_oParams.m_nMailMergeIndexEnd && !bIsBreak; ++nIndexMM) { JSSmart<CJSValue> args_changes[1]; args_changes[0] = CJSContext::createInt(nIndexMM); @@ -881,7 +920,7 @@ namespace NSDoctRenderer m_pInternal->m_oParams.FromXml(strXml); m_pInternal->m_arImagesInChanges.clear(); - std::vector<std::wstring>* arSdkFiles = NULL; + NSDoctRenderer::DoctRendererEditorType editorType = NSDoctRenderer::DoctRendererEditorType::INVALID; switch (m_pInternal->m_oParams.m_eSrcFormat) { case DoctRendererFormat::DOCT: @@ -892,8 +931,9 @@ namespace NSDoctRenderer case DoctRendererFormat::PDF: case DoctRendererFormat::IMAGE: case DoctRendererFormat::HTML: + case DoctRendererFormat::WATERMARK: { - arSdkFiles = &m_pInternal->m_arDoctSDK; + editorType = NSDoctRenderer::DoctRendererEditorType::WORD; m_pInternal->m_strEditorType = L"document"; break; } @@ -911,7 +951,7 @@ namespace NSDoctRenderer case DoctRendererFormat::IMAGE: case DoctRendererFormat::PPTX_THEME_THUMBNAIL: { - arSdkFiles = &m_pInternal->m_arPpttSDK; + editorType = NSDoctRenderer::DoctRendererEditorType::SLIDE; m_pInternal->m_strEditorType = L"presentation"; break; } @@ -928,7 +968,7 @@ namespace NSDoctRenderer case DoctRendererFormat::PDF: case DoctRendererFormat::IMAGE: { - arSdkFiles = &m_pInternal->m_arXlstSDK; + editorType = NSDoctRenderer::DoctRendererEditorType::CELL; m_pInternal->m_strEditorType = L"spreadsheet"; break; } @@ -937,6 +977,39 @@ namespace NSDoctRenderer } break; } + case DoctRendererFormat::VSDT: + { + switch (m_pInternal->m_oParams.m_eDstFormat) + { + case DoctRendererFormat::VSDT: + case DoctRendererFormat::PDF: + case DoctRendererFormat::IMAGE: + { + editorType = NSDoctRenderer::DoctRendererEditorType::VISIO; + m_pInternal->m_strEditorType = L"visio"; + break; + } + default: + return false; + } + break; + } + case DoctRendererFormat::PDF: + { + switch (m_pInternal->m_oParams.m_eDstFormat) + { + case DoctRendererFormat::PDF: + { + editorType = NSDoctRenderer::DoctRendererEditorType::PDF; + m_pInternal->m_strEditorType = L"pdf"; + break; + } + default: + return false; + } + break; + } + default: return false; } @@ -953,48 +1026,8 @@ namespace NSDoctRenderer m_pInternal->m_strFilePath = strFileName; - std::string strScript = ""; - for (size_t i = 0; i < m_pInternal->m_arrFiles.size(); ++i) - { - strScript += m_pInternal->ReadScriptFile(m_pInternal->m_arrFiles[i]); - strScript += "\n\n"; - } - - std::wstring sCachePath = L""; - if (arSdkFiles && (0 < arSdkFiles->size())) - { - if (m_pInternal->m_oParams.m_sScriptsCacheDirectory.empty()) - { - sCachePath = NSFile::GetDirectoryName(*arSdkFiles->begin()) + L"/sdk-all.cache"; - } - else if (m_pInternal->m_oParams.m_sScriptsCacheDirectory != L"empty") - { - sCachePath = m_pInternal->m_oParams.m_sScriptsCacheDirectory; - wchar_t lastSymbol = sCachePath.back(); - if (lastSymbol != '\\' && lastSymbol != '/') - sCachePath += L"/"; - - wchar_t editorFirst = m_pInternal->m_strEditorType.at(0); - if (editorFirst == 'd') - sCachePath += L"word"; - else if (editorFirst == 'p') - sCachePath += L"slide"; - else - sCachePath += L"cell"; - } - - for (std::vector<std::wstring>::iterator i = arSdkFiles->begin(); i != arSdkFiles->end(); i++) - { - strScript += m_pInternal->ReadScriptFile(*i); - strScript += "\n\n"; - } - } - - if (m_pInternal->m_strEditorType == L"spreadsheet") - strScript += "\n$.ready();"; - std::wstring sReturnParams = L""; - bool bResult = m_pInternal->ExecuteScript(strScript, sCachePath, strError, sReturnParams); + bool bResult = m_pInternal->ExecuteScript(editorType, strError, sReturnParams); if (strError.length() != 0) { @@ -1018,95 +1051,73 @@ namespace NSDoctRenderer #ifndef JS_ENGINE_JAVASCRIPTCORE LoadConfig(NSFile::GetProcessDirectory(), sAllFontsPath); - std::wstring sCacheDirectory = sCacheDir; - if (sCacheDirectory.empty() && m_pInternal->m_arDoctSDK.size() > 0) - { - sCacheDirectory = NSFile::GetDirectoryName(m_pInternal->m_arDoctSDK[0]); - sCacheDirectory = NSFile::GetDirectoryName(sCacheDirectory); - } - - if (sCacheDirectory.empty()) - return; - - std::string strScriptAll = ""; - for (size_t i = 0; i < m_pInternal->m_arrFiles.size(); ++i) - { - strScriptAll += m_pInternal->ReadScriptFile(m_pInternal->m_arrFiles[i]); - strScriptAll += "\n\n"; - } + std::vector<NSDoctRenderer::DoctRendererEditorType> editors; + editors.push_back(NSDoctRenderer::DoctRendererEditorType::WORD); + editors.push_back(NSDoctRenderer::DoctRendererEditorType::SLIDE); + editors.push_back(NSDoctRenderer::DoctRendererEditorType::CELL); + editors.push_back(NSDoctRenderer::DoctRendererEditorType::VISIO); + editors.push_back(NSDoctRenderer::DoctRendererEditorType::PDF); - for (int i = 0; i < 3; ++i) + for (std::vector<NSDoctRenderer::DoctRendererEditorType>::const_iterator i = editors.begin(); i != editors.end(); i++) { - std::string strScript = strScriptAll; - std::wstring sCachePath = sCacheDirectory; - - std::vector<std::wstring>* arSdkFiles = NULL; - - switch (i) - { - case 0: - { - arSdkFiles = &m_pInternal->m_arDoctSDK; - sCachePath += L"/word/sdk-all.cache"; - break; - } - case 1: - { - arSdkFiles = &m_pInternal->m_arPpttSDK; - sCachePath += L"/slide/sdk-all.cache"; - break; - } - case 2: - { - arSdkFiles = &m_pInternal->m_arXlstSDK; - sCachePath += L"/cell/sdk-all.cache"; - break; - } - default: - break; - } - - if (NSFile::CFileBinary::Exists(sCachePath)) - NSFile::CFileBinary::Remove(sCachePath); - - for (std::vector<std::wstring>::iterator i = arSdkFiles->begin(); i != arSdkFiles->end(); i++) - { - strScript += m_pInternal->ReadScriptFile(*i); - strScript += "\n\n"; - } - - if (2 == i) - strScript += "\n$.ready();"; - JSSmart<CJSContext> context = new CJSContext(); if (true) { CJSContextScope scope(context); CJSContext::Embed<CNativeControlEmbed>(); - CJSContext::Embed<CGraphicsEmbed>(); NSJSBase::CreateDefaults(); JSSmart<CJSObject> global = context->GetGlobal(); global->set("window", global); + global->set("self", global); global->set("native", CJSContext::createEmbedObject("CNativeControlEmbed")); JSSmart<CJSTryCatch> try_catch = context->GetExceptions(); - context->runScript(strScript, try_catch, sCachePath); + NSDoctRenderer::RunEditor(*i, context, try_catch, m_pInternal); } context->Dispose(); } #endif } -} -bool Doct_renderer_SaveFile_ForBuilder(int nFormat, const std::wstring& strDstFile, - NSNativeControl::CNativeControl* pNative, - JSSmart<CJSContext> context, - JSSmart<CJSValue>* args, - std::wstring& strError, const std::wstring& jsonParams) + void CDoctrenderer::CreateSnapshots() + { +#ifdef V8_SUPPORT_SNAPSHOTS + std::vector<NSDoctRenderer::DoctRendererEditorType> editors; + editors.push_back(NSDoctRenderer::DoctRendererEditorType::WORD); + editors.push_back(NSDoctRenderer::DoctRendererEditorType::SLIDE); + editors.push_back(NSDoctRenderer::DoctRendererEditorType::CELL); + editors.push_back(NSDoctRenderer::DoctRendererEditorType::VISIO); + editors.push_back(NSDoctRenderer::DoctRendererEditorType::PDF); + + // initialize v8 + JSSmart<CJSContext> context = new CJSContext(); + + for (std::vector<NSDoctRenderer::DoctRendererEditorType>::const_iterator i = editors.begin(); i != editors.end(); i++) + { + NSDoctRenderer::GenerateEditorSnapshot(*i, m_pInternal); + } +#endif + } + + void CDoctrenderer::SetAdditionalParam(const AdditionalParamType& type, void* data) + { + switch (type) + { + case AdditionalParamType::DRAWINGFILE: + m_pInternal->m_pDrawingFile = (IOfficeDrawingFile*)data; + break; + default: + break; + } + } +} // namespace NSDoctRenderer + +bool Doct_renderer_SaveFile_ForBuilder( + int nFormat, const std::wstring& strDstFile, NSNativeControl::CNativeControl* pNative, JSSmart<CJSContext> context, JSSmart<CJSValue>* args, std::wstring& strError, const std::wstring& jsonParams) { NSDoctRenderer::CExecuteParams oParams; oParams.m_eDstFormat = (NSDoctRenderer::DoctRendererFormat::FormatFile)nFormat; @@ -1114,6 +1125,5 @@ bool Doct_renderer_SaveFile_ForBuilder(int nFormat, const std::wstring& strDstFi oParams.m_sJsonParams = jsonParams; JSSmart<CJSObject> js_objectApi; // empty - return NSDoctRenderer::CDoctRenderer_Private::Doct_renderer_SaveFile(&oParams, - pNative, context, args, strError, js_objectApi, false); + return NSDoctRenderer::CDoctRenderer_Private::Doct_renderer_SaveFile(&oParams, pNative, context, args, strError, js_objectApi); } diff --git a/DesktopEditor/doctrenderer/doctrenderer.h b/DesktopEditor/doctrenderer/doctrenderer.h index 462367b713b..b3aa76d8d74 100644 --- a/DesktopEditor/doctrenderer/doctrenderer.h +++ b/DesktopEditor/doctrenderer/doctrenderer.h @@ -42,17 +42,25 @@ namespace NSDoctRenderer { enum FormatFile { - DOCT = 0, - XLST = 1, - PPTT = 2, - PDF = 3, - HTML = 4, + DOCT = 0, + XLST = 1, + PPTT = 2, + PDF = 3, + HTML = 4, PPTX_THEME_THUMBNAIL = 5, - IMAGE = 6, + IMAGE = 6, + VSDT = 7, + WATERMARK = 8, INVALID = 255 }; } + + enum class AdditionalParamType + { + DRAWINGFILE = 0, + INVALID = 255 + }; } namespace NSDoctRenderer @@ -69,6 +77,9 @@ namespace NSDoctRenderer bool Execute(const std::wstring& strXml, std::wstring& strError); std::vector<std::wstring> GetImagesInChanges(); void CreateCache(const std::wstring& sAllFontsPath, const std::wstring& sCacheDir); + void CreateSnapshots(); + + void SetAdditionalParam(const AdditionalParamType& type, void* data); private: CDoctRenderer_Private* m_pInternal; diff --git a/DesktopEditor/doctrenderer/doctrenderer.pro b/DesktopEditor/doctrenderer/doctrenderer.pro index 17a3ff8cffb..288e41fe083 100644 --- a/DesktopEditor/doctrenderer/doctrenderer.pro +++ b/DesktopEditor/doctrenderer/doctrenderer.pro @@ -21,62 +21,76 @@ ADD_DEPENDENCY(graphics, kernel, UnicodeConverter, kernel_network) core_android:DEFINES += DISABLE_MEMORY_LIMITATION HEADERS += \ - config.h \ - doctrenderer.h \ - docbuilder.h + config.h \ + editors.h \ + doctrenderer.h \ + docbuilder.h SOURCES += \ - nativecontrol.cpp \ - doctrenderer.cpp \ - docbuilder.cpp \ - docbuilder_p.cpp \ - graphics.cpp \ + editors.cpp \ + nativecontrol.cpp \ + doctrenderer.cpp \ + docbuilder.cpp \ + docbuilder_p.cpp \ + graphics.cpp \ hash.cpp SOURCES += \ - ../../Common/OfficeFileFormatChecker2.cpp \ - ../../Common/3dParty/pole/pole.cpp \ - ../../OOXML/Base/unicode_util.cpp + ../../Common/OfficeFileFormatChecker2.cpp \ + ../../Common/3dParty/pole/pole.cpp \ + ../../OOXML/Base/unicode_util.cpp HEADERS += \ - docbuilder_p.h \ - nativecontrol.h \ - graphics.h \ - hash.h + docbuilder_p.h \ + nativecontrol.h \ + graphics.h \ + hash.h \ + server.h HEADERS += \ - embed/PointerEmbed.h \ - embed/ZipEmbed.h \ - embed/GraphicsEmbed.h \ - embed/MemoryStreamEmbed.h \ - embed/NativeControlEmbed.h \ - embed/NativeBuilderEmbed.h \ - embed/NativeBuilderDocumentEmbed.h \ - embed/TextMeasurerEmbed.h \ - embed/HashEmbed.h \ - embed/Default.h \ - js_internal/js_base.h + embed/PointerEmbed.h \ + embed/ZipEmbed.h \ + embed/GraphicsEmbed.h \ + embed/MemoryStreamEmbed.h \ + embed/NativeControlEmbed.h \ + embed/NativeBuilderEmbed.h \ + embed/NativeBuilderDocumentEmbed.h \ + embed/TextMeasurerEmbed.h \ + embed/HashEmbed.h \ + embed/Default.h \ + js_internal/js_base.h SOURCES += \ - embed/PointerEmbed.cpp \ - embed/ZipEmbed.cpp \ - embed/GraphicsEmbed.cpp \ - embed/MemoryStreamEmbed.cpp \ - embed/NativeControlEmbed.cpp \ - embed/NativeBuilderEmbed.cpp \ - embed/NativeBuilderDocumentEmbed.cpp \ - embed/TextMeasurerEmbed.cpp \ - embed/HashEmbed.cpp \ - embed/Default.cpp + embed/PointerEmbed.cpp \ + embed/ZipEmbed.cpp \ + embed/GraphicsEmbed.cpp \ + embed/MemoryStreamEmbed.cpp \ + embed/NativeControlEmbed.cpp \ + embed/NativeBuilderEmbed.cpp \ + embed/NativeBuilderDocumentEmbed.cpp \ + embed/TextMeasurerEmbed.cpp \ + embed/HashEmbed.cpp \ + embed/Default.cpp + +# Serialize objects to JS +HEADERS += \ + json/json.h \ + json/json_p.h \ + json/json_values.h \ + json/serialization.h + +SOURCES += \ + json/json.cpp \ + json/json_values.cpp include($$PWD/js_internal/js_base.pri) !use_javascript_core { - build_xp:DESTDIR=$$DESTDIR/xp + build_xp:DESTDIR=$$DESTDIR/xp } use_javascript_core { - OBJECTIVE_SOURCES += ../common/Mac/NSString+StringUtils.mm + OBJECTIVE_SOURCES += ../common/Mac/NSString+StringUtils.mm } # files for embedded classes @@ -96,3 +110,19 @@ include(../../Common/3dParty/openssl/openssl.pri) # downloader DEFINES += BUIDLER_OPEN_DOWNLOAD_ENABLED DEFINES += BUIDLER_OPEN_BASE64_ENABLED + +CONFIG += drawingfile_support +drawingfile_support { + DEFINES += WASM_SERIALIZER_USE_ALLOCATOR + ADD_DEPENDENCY(PdfFile, XpsFile, DjVuFile, DocxRenderer) + + HEADERS += \ + drawingfile.h \ + embed/DrawingFileEmbed.h + + SOURCES += \ + ../graphics/pro/js/wasm/src/HTMLRendererText.cpp \ + embed/DrawingFileEmbed.cpp + + ADD_FILES_FOR_EMBEDDED_CLASS_HEADER(embed/DrawingFileEmbed.h) +} diff --git a/DesktopEditor/doctrenderer/drawingfile.h b/DesktopEditor/doctrenderer/drawingfile.h new file mode 100644 index 00000000000..9cb406f0dd6 --- /dev/null +++ b/DesktopEditor/doctrenderer/drawingfile.h @@ -0,0 +1,590 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#ifndef DRAWINGFILE_H +#define DRAWINGFILE_H + +#include "./common.h" +#include <stddef.h> + +#include "../../PdfFile/PdfFile.h" +#include "../../XpsFile/XpsFile.h" +#include "../../DjVuFile/DjVu.h" +#include "../graphics/pro/js/wasm/src/serialize.h" +#include "../graphics/pro/js/wasm/src/HTMLRendererText.h" +#include "../../DocxRenderer/DocxRenderer.h" + +#define CHECKER_FILE_BUFFER_LEN 4096 + +class CDrawingFile +{ +private: + NSFonts::IApplicationFonts* m_pApplicationFonts; + NSFonts::IFontManager* m_pFontManager; + NSHtmlRenderer::CHTMLRendererText* m_pTextRenderer; + NSDocxRenderer::IImageStorage* m_pImageStorage; + + IOfficeDrawingFile* m_pFile; + int m_nType = -1; + + bool m_bIsExternalFile; + +public: + CDrawingFile(NSFonts::IApplicationFonts* pFonts) + { + m_pApplicationFonts = pFonts; + ADDREFINTERFACE(m_pApplicationFonts); + + m_pFontManager = m_pApplicationFonts->GenerateFontManager(); + NSFonts::IFontsCache* pFontCache = NSFonts::NSFontCache::Create(); + pFontCache->SetStreams(m_pApplicationFonts->GetStreams()); + pFontCache->SetCacheSize(8); + m_pFontManager->SetOwnerCache(pFontCache); + + m_pTextRenderer = NULL; + m_pImageStorage = NULL; + + m_pFile = NULL; + m_bIsExternalFile = false; + } + ~CDrawingFile() + { + if (!m_bIsExternalFile) + RELEASEOBJECT(m_pFile); + RELEASEOBJECT(m_pTextRenderer); + RELEASEOBJECT(m_pFontManager); + RELEASEINTERFACE(m_pApplicationFonts); + RELEASEOBJECT(m_pImageStorage); + } + + void SetInternalFile(IOfficeDrawingFile* pFile) + { + m_pFile = pFile; + if (!m_pFile) + return; + + m_bIsExternalFile = true; + switch (m_pFile->GetType()) + { + case odftPDF: + m_nType = 0; + break; + case odftDJVU: + m_nType = 1; + break; + case odftXPS: + m_nType = 2; + break; + default: + break; + } + } + +public: + static void InitFontsGlobalStorage() + { + NSFonts::NSApplicationFontStream::SetGlobalMemoryStorage(NSFonts::NSApplicationFontStream::CreateDefaultGlobalMemoryStorage()); + } + + static NSFonts::IFontsMemoryStorage* GetFontsStorage() + { + return NSFonts::NSApplicationFontStream::GetGlobalMemoryStorage(); + } + +public: + bool OpenFile(const std::wstring& sFile, const std::wstring& sPassword) + { + CloseFile(); + + int nType = DetectFormat(sFile); + + switch (nType) + { + case 0: + { + m_pFile = new CPdfFile(m_pApplicationFonts); + if (!m_pFile->LoadFromFile(sFile, L"", sPassword, sPassword)) + { + if (4 != ((CPdfFile*)m_pFile)->GetError()) + { + RELEASEOBJECT(m_pFile); + } + else + m_nType = 0; + } + else + m_nType = 0; + break; + } + case 1: + { + m_pFile = new CDjVuFile(m_pApplicationFonts); + if (!m_pFile->LoadFromFile(sFile, L"", sPassword, sPassword)) + { + RELEASEOBJECT(m_pFile); + } + else + m_nType = 1; + break; + } + case 2: + { + m_pFile = new CXpsFile(m_pApplicationFonts); + if (!m_pFile->LoadFromFile(sFile, L"", sPassword, sPassword)) + { + RELEASEOBJECT(m_pFile); + } + else + m_nType = 2; + } + default: + break; + } + + return m_pFile ? true : false; + } + + bool OpenFile(BYTE* data, LONG size, const std::wstring& sPassword) + { + CloseFile(); + + int nType = DetectFormat(data, size); + switch (nType) + { + case 0: + { + m_pFile = new CPdfFile(m_pApplicationFonts); + if (!m_pFile->LoadFromMemory(data, size, L"", sPassword, sPassword)) + { + if (4 != ((CPdfFile*)m_pFile)->GetError()) + { + RELEASEOBJECT(m_pFile); + } + else + m_nType = 0; + } + else + m_nType = 0; + break; + } + case 1: + { + m_pFile = new CDjVuFile(m_pApplicationFonts); + if (!m_pFile->LoadFromMemory(data, size, L"", sPassword, sPassword)) + { + RELEASEOBJECT(m_pFile); + } + else + m_nType = 1; + break; + } + case 2: + { + m_pFile = new CXpsFile(m_pApplicationFonts); + if (!m_pFile->LoadFromMemory(data, size, L"", sPassword, sPassword)) + { + RELEASEOBJECT(m_pFile); + } + else + m_nType = 2; + } + default: + break; + } + + return m_pFile ? true : false; + } + + void CloseFile() + { + if (m_pFile) + RELEASEOBJECT(m_pFile); + + m_nType = -1; + } + + int GetType() + { + return m_nType; + } + + int GetErrorCode() + { + if (!m_pFile) + return -1; + + if (0 == m_nType) + return ((CPdfFile*)m_pFile)->GetError(); + + return 0; + } + + BYTE* GetInfo() + { + NSWasm::CData oRes; + oRes.SkipLen(); + + oRes.AddInt(GetMaxRefID()); + + int pages_count = GetPagesCount(); + oRes.AddInt(pages_count); + for (int page = 0; page < pages_count; ++page) + { + int nW = 0; + int nH = 0; + int nDpi = 0; + int nRotate = 0; + GetPageInfo(page, nW, nH, nDpi, nRotate); + oRes.AddInt(nW); + oRes.AddInt(nH); + oRes.AddInt(nDpi); + oRes.AddInt(nRotate); + } + std::wstring wsInfo = m_pFile->GetInfo(); + std::string sInfo = U_TO_UTF8(wsInfo); + oRes.WriteString((BYTE*)sInfo.c_str(), sInfo.length()); + + oRes.WriteLen(); + BYTE* bRes = oRes.GetBuffer(); + oRes.ClearWithoutAttack(); + return bRes; + } + + BYTE* GetPixmap(int nPageIndex, int nRasterW, int nRasterH, int nBackgroundColor) + { + if (!m_pFile) + return NULL; + return m_pFile->ConvertToPixels(nPageIndex, nRasterW, nRasterH, true, m_pFontManager, nBackgroundColor, (nBackgroundColor == 0xFFFFFF) ? false : true); + } + + BYTE* GetGlyphs(int nPageIndex) + { + if (NULL == m_pTextRenderer) + m_pTextRenderer = new NSHtmlRenderer::CHTMLRendererText(); + + m_pTextRenderer->Init(m_pFile, 8); + m_pFile->DrawPageOnRenderer(m_pTextRenderer, nPageIndex, NULL); + + return m_pTextRenderer->GetBuffer(); + } + BYTE* GetLinks(int nPageIndex) + { + return m_pFile->GetLinks(nPageIndex); + } + BYTE* GetStructure() + { + return m_pFile->GetStructure(); + } + BYTE* GetInteractiveFormsInfo() + { + if (m_nType == 0) + return ((CPdfFile*)m_pFile)->GetWidgets(); + return NULL; + } + BYTE* GetInteractiveFormsFonts(int nTypeFonts) + { + if (m_nType == 0) + { + if (nTypeFonts == 1) + return ((CPdfFile*)m_pFile)->GetAnnotEmbeddedFonts(); + if (nTypeFonts == 2) + return ((CPdfFile*)m_pFile)->GetAnnotStandardFonts(); + } + return NULL; + } + + BYTE* GetInteractiveFormsAP(int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex, int nWidget, int nView, int nButtonView) + { + if (0 != m_nType) + return NULL; + + const char* sView = NULL; + if (nView == 0) + sView = "N"; + else if (nView == 1) + sView = "D"; + else if (nView == 2) + sView = "R"; + + const char* sButtonView = NULL; + if (nButtonView == 0) + sButtonView = "Off"; + else if (nButtonView == 1) + sButtonView = "Yes"; + + return ((CPdfFile*)m_pFile)->GetAPWidget(nRasterW, nRasterH, nBackgroundColor, nPageIndex, nWidget, sView, sButtonView); + } + BYTE* GetButtonIcons(int nBackgroundColor, int nPageIndex, int bBase64, int nButtonWidget, int nIconView) + { + if (0 != m_nType) + return NULL; + + const char* sIconView = NULL; + if (nIconView == 0) + sIconView = "I"; + else if (nIconView == 1) + sIconView = "RI"; + else if (nIconView == 2) + sIconView = "IX"; + + return ((CPdfFile*)m_pFile)->GetButtonIcon(nBackgroundColor, nPageIndex, bBase64 ? true : false, nButtonWidget, sIconView); + } + BYTE* GetAnnotationsInfo(int nPageIndex) + { + if (m_nType == 0) + return ((CPdfFile*)m_pFile)->GetAnnots(nPageIndex); + return NULL; + } + BYTE* GetAnnotationsAP(int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex, int nAnnot, int nView) + { + if (m_nType != 0) + return NULL; + + const char* sView = NULL; + if (nView == 0) + sView = "N"; + else if (nView == 1) + sView = "D"; + else if (nView == 2) + sView = "R"; + + return ((CPdfFile*)m_pFile)->GetAPAnnots(nRasterW, nRasterH, nBackgroundColor, nPageIndex, nAnnot, sView); + } + + void DestroyTextInfo() + { + RELEASEOBJECT(m_pTextRenderer); + } + bool IsNeedCMap() + { + if (m_nType == 0) + return ((CPdfFile*)m_pFile)->IsNeedCMap(); + return false; + } + void SetCMapData(BYTE* data, int size) + { + if (m_nType == 0) + ((CPdfFile*)m_pFile)->SetCMapMemory(data, size); + } + BYTE* ScanPage(int nPageIndex, int mode) + { + if (NULL == m_pImageStorage) + m_pImageStorage = NSDocxRenderer::CreateWasmImageStorage(); + + CDocxRenderer oRenderer(m_pApplicationFonts); + oRenderer.SetExternalImageStorage(m_pImageStorage); + oRenderer.SetTextAssociationType(NSDocxRenderer::TextAssociationType::tatParagraphToShape); + + std::vector<std::wstring> arShapes; + if (0 == mode) + arShapes = oRenderer.ScanPage(m_pFile, nPageIndex); + else + arShapes = oRenderer.ScanPagePptx(m_pFile, nPageIndex); + + int nLen = (int)arShapes.size(); + + NSWasm::CData oRes; + oRes.SkipLen(); + oRes.AddInt(nLen); + + for (int i = 0; i < nLen; ++i) + oRes.WriteString(arShapes[i]); + + oRes.WriteLen(); + + BYTE* res = oRes.GetBuffer(); + oRes.ClearWithoutAttack(); + return res; + } + + void* GetImageBase64(int rId) + { + if (NULL == m_pImageStorage) + return NULL; + return m_pImageStorage->GetBase64(rId); + } + int GetImageBase64Len(std::string* p) + { + return (int)p->length(); + } + char* GetImageBase64Ptr(std::string* p) + { + return (char*)p->c_str(); + } + void GetImageBase64Free(std::string* p) + { + *p = ""; + } + + void SetFontBinary(char* path, BYTE* data, int size) + { + NSFonts::IFontsMemoryStorage* pStorage = NSFonts::NSApplicationFontStream::GetGlobalMemoryStorage(); + if (pStorage) + { + std::string sPathA(path); + pStorage->Add(UTF8_TO_U(sPathA), data, size, true); + } + } + int IsFontBinaryExist(char* path) + { + NSFonts::IFontsMemoryStorage* pStorage = NSFonts::NSApplicationFontStream::GetGlobalMemoryStorage(); + if (pStorage) + { + std::string sPathA(path); + NSFonts::IFontStream* pStream = pStorage->Get(UTF8_TO_U(sPathA)); + if (pStream) + return 1; + } + return 0; + } + + BYTE* GetFontBinary(const std::string& sPathA) + { + std::wstring sFontName = UTF8_TO_U(sPathA); + + std::wstring sFontFile; + if (m_nType == 0) + sFontFile = ((CPdfFile*)m_pFile)->GetFontPath(sFontName); + + if (sFontFile.empty()) + sFontFile = sFontName; + + NSFonts::IFontsMemoryStorage* pStorage = GetFontsStorage(); + if (pStorage) + { + NSFonts::IFontStream* pStream = pStorage->Get(sFontFile); + if (pStream) + { + BYTE* pData = NULL; + LONG lLength = 0; + pStream->GetMemory(pData, lLength); + + if (pData) + { + NSWasm::CData oRes; + oRes.SkipLen(); + + oRes.AddInt(lLength); + + unsigned long long npSubMatrix = (unsigned long long)pData; + unsigned int npSubMatrix1 = npSubMatrix & 0xFFFFFFFF; + oRes.AddInt(npSubMatrix1); + oRes.AddInt(npSubMatrix >> 32); + + oRes.WriteLen(); + BYTE* bRes = oRes.GetBuffer(); + oRes.ClearWithoutAttack(); + return bRes; + } + } + } + return NULL; + } + + std::wstring GetFontBinaryNative(const std::wstring& sName) + { + if (0 != m_nType) + return L""; + + return ((CPdfFile*)m_pFile)->GetEmbeddedFontPath(sName); + } + +private: + int GetPagesCount() + { + return m_pFile->GetPagesCount(); + } + int GetMaxRefID() + { + if (m_nType == 0) + return ((CPdfFile*)m_pFile)->GetMaxRefID(); + return 0; + } + + void GetPageInfo(int nPageIndex, int& nWidth, int& nHeight, int& nPageDpiX, int& nRotate) + { + double dPageDpiX, dPageDpiY; + double dWidth, dHeight; + m_pFile->GetPageInfo(nPageIndex, &dWidth, &dHeight, &dPageDpiX, &dPageDpiY); + if (m_nType == 2) + { + dWidth = dWidth / 25.4 * 96.0; + dHeight = dHeight / 25.4 * 96.0; + dPageDpiX = dPageDpiX / 25.4 * 96.0; + } + if (m_nType == 0) + nRotate = ((CPdfFile*)m_pFile)->GetRotate(nPageIndex); + nWidth = round(dWidth); + nHeight = round(dHeight); + nPageDpiX = dPageDpiX; + } + + int DetectFormat(const std::wstring& sFile) + { + NSFile::CFileBinary oFile; + if (oFile.OpenFile(sFile)) + { + LONG size = oFile.GetFileSize(); + if (size > CHECKER_FILE_BUFFER_LEN) + size = CHECKER_FILE_BUFFER_LEN; + + BYTE* data = new BYTE[size]; + oFile.ReadFile(data, size); + + int nType = DetectFormat(data, size); + + RELEASEARRAYOBJECTS(data); + return nType; + } + return -1; + } + + int DetectFormat(BYTE* data, LONG size) + { + // 0 - PDF + // 1 - DJVU + // 2 - XPS + LONG nSize = size < CHECKER_FILE_BUFFER_LEN ? size : CHECKER_FILE_BUFFER_LEN; + char* pData = (char*)data; + for (int i = 0; i < nSize - 5; ++i) + { + int nPDF = strncmp(&pData[i], "%PDF-", 5); + if (!nPDF) + return 0; + } + if ( (8 <= size) && (0x41 == data[0] && 0x54 == data[1] && 0x26 == data[2] && 0x54 == data[3] && + 0x46 == data[4] && 0x4f == data[5] && 0x52 == data[6] && 0x4d == data[7])) + return 1; + return 2; + } +}; + +#endif // DRAWINGFILE_H diff --git a/DesktopEditor/doctrenderer/editors.cpp b/DesktopEditor/doctrenderer/editors.cpp new file mode 100644 index 00000000000..3c1d5fd61d6 --- /dev/null +++ b/DesktopEditor/doctrenderer/editors.cpp @@ -0,0 +1,259 @@ +#include "./editors.h" + +#include "../common/StringBuilder.h" + +namespace NSDoctRenderer +{ + namespace + { + bool AppendScript(NSStringUtils::CStringBuilderA* builder, const std::wstring& path, const std::string& header = "", const std::string& footer = "") + { + NSFile::CFileBinary oFile; + + if (!oFile.OpenFile(path)) + return false; + + int size = (int)oFile.GetFileSize(); + if (size < 3) + return false; + + BYTE* pData = new BYTE[size]; + DWORD dwReadSize = 0; + oFile.ReadFile(pData, (DWORD)size, dwReadSize); + oFile.CloseFile(); + + int nOffset = 0; + if (pData[0] == 0xEF && pData[1] == 0xBB && pData[2] == 0xBF) + nOffset = 3; + + if (!header.empty()) + builder->WriteString(header); + + builder->WriteString((char*)(pData + nOffset), size - nOffset); + + if (!footer.empty()) + builder->WriteString(footer); + + builder->WriteString("\n\n"); + RELEASEARRAYOBJECTS(pData); + + return true; + } + + bool RunScript(JSSmart<NSJSBase::CJSContext>& context, JSSmart<NSJSBase::CJSTryCatch>& try_catch, const std::wstring& path) + { + NSFile::CFileBinary oFile; + + if (!oFile.OpenFile(path)) + return false; + + int size = (int)oFile.GetFileSize(); + if (size < 3) + return false; + + BYTE* pData = new BYTE[size]; + DWORD dwReadSize = 0; + oFile.ReadFile(pData, (DWORD)size, dwReadSize); + oFile.CloseFile(); + + int nOffset = 0; + if (pData[0] == 0xEF && pData[1] == 0xBB && pData[2] == 0xBF) + nOffset = 3; + + context->runScript(std::string((char*)(pData + nOffset), size - nOffset), try_catch); + RELEASEARRAYOBJECTS(pData); + + return !try_catch->Check(); + } + + std::wstring GetAllScript(NSStringUtils::CStringBuilderA* builder, const DoctRendererEditorType& type, CDoctRendererConfig* config, const bool& isSnapshot = false) + { + for (std::vector<std::wstring>::const_iterator i = config->m_arrFiles.cbegin(); i != config->m_arrFiles.cend(); i++) + AppendScript(builder, *i); + + std::wstring sFontsPath = config->m_strSdkPath + L"/common/libfont/engine"; +#ifdef SUPPORT_HARFBUZZ_SHAPER + sFontsPath += L"/fonts_native.js"; +#else + sFontsPath += L"/fonts_ie.js"; +#endif + + std::wstring sCachePath = L""; + + switch (type) + { + case DoctRendererEditorType::WORD: + { + AppendScript(builder, config->m_strSdkPath + L"/word/sdk-all-min.js"); + AppendScript(builder, sFontsPath); + AppendScript(builder, config->m_strSdkPath + L"/word/sdk-all.js"); + sCachePath = config->m_strSdkPath + L"/word/sdk-all"; + break; + } + case DoctRendererEditorType::SLIDE: + { + AppendScript(builder, config->m_strSdkPath + L"/slide/sdk-all-min.js"); + AppendScript(builder, sFontsPath); + AppendScript(builder, config->m_strSdkPath + L"/slide/sdk-all.js"); + sCachePath = config->m_strSdkPath + L"/slide/sdk-all"; + break; + } + case DoctRendererEditorType::CELL: + { + AppendScript(builder, config->m_strSdkPath + L"/cell/sdk-all-min.js"); + AppendScript(builder, sFontsPath); + AppendScript(builder, config->m_strSdkPath + L"/cell/sdk-all.js"); + builder->WriteString("\n$.ready();", 11); + sCachePath = config->m_strSdkPath + L"/cell/sdk-all"; + break; + } + case DoctRendererEditorType::VISIO: + { + if (!NSFile::CFileBinary::Exists(config->m_strSdkPath + L"/visio/sdk-all-min.js")) + return L""; + AppendScript(builder, config->m_strSdkPath + L"/visio/sdk-all-min.js"); + AppendScript(builder, sFontsPath); + AppendScript(builder, config->m_strSdkPath + L"/visio/sdk-all.js"); + sCachePath = config->m_strSdkPath + L"/visio/sdk-all"; + break; + } + case DoctRendererEditorType::PDF: + { + AppendScript(builder, config->m_strSdkPath + L"/word/sdk-all-min.js"); + AppendScript(builder, sFontsPath); + AppendScript(builder, config->m_strSdkPath + L"/word/sdk-all.js"); + AppendScript(builder, config->m_strSdkPath + L"/pdf/src/engine/drawingfile_native.js"); + AppendScript(builder, config->m_strSdkPath + L"/pdf/src/annotations/stamps.json", "window[\"native_pdf_stamps\"]=", ";"); + sCachePath = config->m_strSdkPath + L"/pdf/sdk-all"; + break; + } + default: + break; + } + + if (!sCachePath.empty()) + sCachePath += (isSnapshot ? L".bin" : L".cache"); + + return sCachePath; + } + + std::wstring GetSnapshotPath(const DoctRendererEditorType& type, CDoctRendererConfig* config) + { + std::wstring sCachePath = L""; + + switch (type) + { + case DoctRendererEditorType::WORD: + { + return config->m_strSdkPath + L"/word/sdk-all.bin"; + } + case DoctRendererEditorType::SLIDE: + { + return config->m_strSdkPath + L"/slide/sdk-all.bin"; + } + case DoctRendererEditorType::CELL: + { + return config->m_strSdkPath + L"/cell/sdk-all.bin"; + } + case DoctRendererEditorType::VISIO: + { + return config->m_strSdkPath + L"/visio/sdk-all.bin"; + } + case DoctRendererEditorType::PDF: + { + return config->m_strSdkPath + L"/pdf/sdk-all.bin"; + } + default: + break; + } + return L""; + } + + bool RunEditorFooter(JSSmart<NSJSBase::CJSContext>& context, JSSmart<NSJSBase::CJSTryCatch>& try_catch, CDoctRendererConfig* config) + { + if (!RunScript(context, try_catch, config->m_strAllFonts)) + return false; + + std::string sFooter = "window.InitNativeEditors();"; + + if (context->isSnapshotUsed()) + { + sFooter += "\ +if (undefined === String.prototype.replaceAll)\ +{\ +String.prototype.replaceAll = function(str, newStr)\ +{\ + if (Object.prototype.toString.call(str).toLowerCase() === '[object regexp]')\ + return this.replace(str, newStr);\ + return this.split(str).join(newStr);\ +};\ +}\n"; + } + + context->runScript(sFooter, try_catch); + return !try_catch->Check(); + } + } // namespace + + bool RunEditor(const DoctRendererEditorType& type, JSSmart<NSJSBase::CJSContext>& context, JSSmart<NSJSBase::CJSTryCatch>& try_catch, CDoctRendererConfig* config) + { + if (context->isSnapshotUsed()) + return RunEditorFooter(context, try_catch, config); + + NSStringUtils::CStringBuilderA builder; + builder.AddSize(10 * 1024 * 1024); + std::wstring sCachePath = GetAllScript(&builder, type, config); + + if (!sCachePath.empty()) + { + context->runScript(builder.GetData(), try_catch, config->m_bIsUseCache ? sCachePath : L""); + RunEditorFooter(context, try_catch, config); + } + + return !try_catch->Check(); + } + + bool GenerateEditorSnapshot(const DoctRendererEditorType& type, CDoctRendererConfig* config) + { + NSStringUtils::CStringBuilderA builder; + builder.AddSize(10 * 1024 * 1024); + std::wstring sCachePath = GetAllScript(&builder, type, config, true); + + builder.WriteString("delete String.prototype.replaceAll;"); + + if (sCachePath.empty()) + return false; + + return NSJSBase::CJSContext::generateSnapshot(builder.GetData(), sCachePath); + } + + namespace + { + JSSmart<NSJSBase::CJSContext> RunEditorWithSnapshot(const DoctRendererEditorType& type, CDoctRendererConfig* config) + { + #ifndef V8_SUPPORT_SNAPSHOTS + return NULL; + #endif + + std::wstring sCachePath = GetSnapshotPath(type, config); + if (!NSFile::CFileBinary::Exists(sCachePath)) + return NULL; + + if (sCachePath.empty()) + return NULL; + + JSSmart<NSJSBase::CJSContext> context = new NSJSBase::CJSContext(false); + context->Initialize(sCachePath); + + return context; + } + } // namespace + + JSSmart<NSJSBase::CJSContext> CreateEditorContext(const DoctRendererEditorType& type, CDoctRendererConfig* config) + { + JSSmart<NSJSBase::CJSContext> context = RunEditorWithSnapshot(type, config); + if (context.is_init()) + return context; + return new NSJSBase::CJSContext(); + } +} // namespace NSDoctRenderer diff --git a/DesktopEditor/doctrenderer/editors.h b/DesktopEditor/doctrenderer/editors.h new file mode 100644 index 00000000000..13f008f05b0 --- /dev/null +++ b/DesktopEditor/doctrenderer/editors.h @@ -0,0 +1,62 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#ifndef DOC_BUILDER_EDITORS_CONFIG +#define DOC_BUILDER_EDITORS_CONFIG + +#include "./config.h" +#include "../js_internal/js_base.h" + +#ifdef CreateFile +#undef CreateFile +#endif + +namespace NSDoctRenderer +{ + enum class DoctRendererEditorType + { + WORD = 0, + CELL = 1, + SLIDE = 2, + VISIO = 3, + PDF = 4, + + INVALID = 255 + }; + + bool RunEditor(const DoctRendererEditorType& type, JSSmart<NSJSBase::CJSContext>& context, JSSmart<NSJSBase::CJSTryCatch>& try_catch, CDoctRendererConfig* config); + + bool GenerateEditorSnapshot(const DoctRendererEditorType& type, CDoctRendererConfig* config); + + JSSmart<NSJSBase::CJSContext> CreateEditorContext(const DoctRendererEditorType& type, CDoctRendererConfig* config); +} + +#endif // DOC_BUILDER_EDITORS_CONFIG diff --git a/DesktopEditor/doctrenderer/embed/Default.cpp b/DesktopEditor/doctrenderer/embed/Default.cpp index 52d814ce586..7c5db97160d 100644 --- a/DesktopEditor/doctrenderer/embed/Default.cpp +++ b/DesktopEditor/doctrenderer/embed/Default.cpp @@ -4,6 +4,7 @@ #include "./MemoryStreamEmbed.h" #include "./TextMeasurerEmbed.h" #include "./HashEmbed.h" +#include "./GraphicsEmbed.h" namespace NSJSBase { @@ -13,5 +14,6 @@ namespace NSJSBase CJSContext::Embed<CMemoryStreamEmbed>(); CJSContext::Embed<CTextMeasurerEmbed>(); CJSContext::Embed<CHashEmbed>(); + CJSContext::Embed<CGraphicsEmbed>(); } } diff --git a/DesktopEditor/doctrenderer/embed/Default.h b/DesktopEditor/doctrenderer/embed/Default.h index 9131ec6a36e..2716b5215b1 100644 --- a/DesktopEditor/doctrenderer/embed/Default.h +++ b/DesktopEditor/doctrenderer/embed/Default.h @@ -1,7 +1,7 @@ #ifndef _BUILD_NATIVE_DEFAULT_EMBED_H_ #define _BUILD_NATIVE_DEFAULT_EMBED_H_ - #include "../js_internal/js_base.h" +#include "../js_internal/js_base.h" namespace NSJSBase { diff --git a/DesktopEditor/doctrenderer/embed/DrawingFileEmbed.cpp b/DesktopEditor/doctrenderer/embed/DrawingFileEmbed.cpp new file mode 100644 index 00000000000..c11d043e08b --- /dev/null +++ b/DesktopEditor/doctrenderer/embed/DrawingFileEmbed.cpp @@ -0,0 +1,181 @@ +#include "DrawingFileEmbed.h" +#include "../drawingfile.h" +#include "../../raster/BgraFrame.h" + +JSSmart<CJSValue> WasmMemoryToJS(BYTE* pWasmData) +{ + if (NULL == pWasmData) + return CJSContext::createNull(); + + int nLen = 0; + memcpy(&nLen, pWasmData, sizeof(int)); + if (4 >= nLen) + return CJSContext::createNull(); + + return NSJSBase::CJSContext::createUint8Array(pWasmData + 4, nLen - 4, true); +} + +CDrawingFileEmbed::CDrawingFileEmbed() +{ + m_pFile = NULL; +} +CDrawingFileEmbed::~CDrawingFileEmbed() +{ + RELEASEOBJECT(m_pFile); +} + +JSSmart<CJSValue> CDrawingFileEmbed::OpenFile(JSSmart<CJSValue> sFile, JSSmart<CJSValue> sPassword) +{ + bool bResult = m_pFile->OpenFile(sFile->toStringW(), sPassword->isString() ? sPassword->toStringW() : L""); + return CJSContext::createBool(bResult); +} +JSSmart<CJSValue> CDrawingFileEmbed::CloseFile() +{ + m_pFile->CloseFile(); + return CJSContext::createUndefined(); +} + +JSSmart<CJSValue> CDrawingFileEmbed::GetType() +{ + return CJSContext::createInt(m_pFile->GetType()); +} +JSSmart<CJSValue> CDrawingFileEmbed::GetErrorCode() +{ + return CJSContext::createInt(m_pFile->GetErrorCode()); +} + +JSSmart<CJSValue> CDrawingFileEmbed::GetInfo() +{ + return WasmMemoryToJS(m_pFile->GetInfo()); +} + +JSSmart<CJSValue> CDrawingFileEmbed::GetPixmap(JSSmart<CJSValue> nPageIndex, JSSmart<CJSValue> nRasterW, JSSmart<CJSValue> nRasterH, JSSmart<CJSValue> nBackgroundColor) +{ + int nW = nRasterW->toInt32(); + int nH = nRasterH->toInt32(); + BYTE* pData = m_pFile->GetPixmap(nPageIndex->toInt32(), nW, nH, nBackgroundColor->toInt32()); + + if (NULL == pData) + return CJSContext::createNull(); + + return NSJSBase::CJSContext::createUint8Array(pData, 4 * nW * nH, true); +} + +JSSmart<CJSValue> CDrawingFileEmbed::DestroyPixmap(JSSmart<CJSValue> typedArray) +{ + if (!typedArray->isTypedArray()) + return NULL; + + CBgraFrame oFrame; + oFrame.put_Data(typedArray->toTypedArray()->getData().Data); + // free on destructor + return NULL; +} + +JSSmart<CJSValue> CDrawingFileEmbed::GetFontBinary(JSSmart<CJSValue> Id) +{ + if (0 != m_pFile->GetType()) + return NULL; + + std::wstring sName = Id->toStringW(); + std::wstring sFile = m_pFile->GetFontBinaryNative(sName); + if (sFile.empty()) + return NULL; + + return CJSContext::createUint8Array(sFile); +} + +JSSmart<CJSValue> CDrawingFileEmbed::GetGlyphs(JSSmart<CJSValue> nPageIndex) +{ + return WasmMemoryToJS(m_pFile->GetGlyphs(nPageIndex->toInt32())); +} +JSSmart<CJSValue> CDrawingFileEmbed::GetLinks(JSSmart<CJSValue> nPageIndex) +{ + return WasmMemoryToJS(m_pFile->GetLinks(nPageIndex->toInt32())); +} +JSSmart<CJSValue> CDrawingFileEmbed::GetStructure() +{ + return WasmMemoryToJS(m_pFile->GetStructure()); +} +JSSmart<CJSValue> CDrawingFileEmbed::GetInteractiveFormsInfo() +{ + return WasmMemoryToJS(m_pFile->GetInteractiveFormsInfo()); +} +JSSmart<CJSValue> CDrawingFileEmbed::GetInteractiveFormsFonts(JSSmart<CJSValue> nTypeFonts) +{ + return WasmMemoryToJS(m_pFile->GetInteractiveFormsFonts(nTypeFonts->toInt32())); +} + +JSSmart<CJSValue> CDrawingFileEmbed::GetInteractiveFormsAP(JSSmart<CJSValue> nRasterW, JSSmart<CJSValue> nRasterH, JSSmart<CJSValue> nBackgroundColor, + JSSmart<CJSValue> nPageIndex, + JSSmart<CJSValue> nWidget, JSSmart<CJSValue> nView, JSSmart<CJSValue> nButtonView) +{ + return WasmMemoryToJS(m_pFile->GetInteractiveFormsAP(nRasterW->toInt32(), nRasterH->toInt32(), nBackgroundColor->toInt32(), + nPageIndex->toInt32(), + nWidget->toInt32(), nView->toInt32(), nButtonView->toInt32())); +} +JSSmart<CJSValue> CDrawingFileEmbed::GetButtonIcons(JSSmart<CJSValue> nBackgroundColor, JSSmart<CJSValue> nPageIndex, JSSmart<CJSValue> bBase64, + JSSmart<CJSValue> nButtonWidget, JSSmart<CJSValue> nIconView) +{ + return WasmMemoryToJS(m_pFile->GetButtonIcons(nBackgroundColor->toInt32(), nPageIndex->toInt32(), bBase64->toInt32(), + nButtonWidget->toInt32(), nIconView->toInt32())); +} +JSSmart<CJSValue> CDrawingFileEmbed::GetAnnotationsInfo(JSSmart<CJSValue> nPageIndex) +{ + return WasmMemoryToJS(m_pFile->GetAnnotationsInfo(nPageIndex->toInt32())); +} +JSSmart<CJSValue> CDrawingFileEmbed::GetAnnotationsAP(JSSmart<CJSValue> nRasterW, JSSmart<CJSValue> nRasterH, JSSmart<CJSValue> nBackgroundColor, + JSSmart<CJSValue> nPageIndex, JSSmart<CJSValue> nAnnot, JSSmart<CJSValue> nView) +{ + return WasmMemoryToJS(m_pFile->GetAnnotationsAP(nRasterW->toInt32(), nRasterH->toInt32(), nBackgroundColor->toInt32(), + nPageIndex->toInt32(), nAnnot->toInt32(), nView->toInt32())); +} + +JSSmart<CJSValue> CDrawingFileEmbed::DestroyTextInfo() +{ + m_pFile->DestroyTextInfo(); + return CJSContext::createUndefined(); +} +JSSmart<CJSValue> CDrawingFileEmbed::IsNeedCMap() +{ + return CJSContext::createBool(false); +} +JSSmart<CJSValue> CDrawingFileEmbed::ScanPage(JSSmart<CJSValue> nPageIndex, JSSmart<CJSValue> mode) +{ + return WasmMemoryToJS(m_pFile->ScanPage(nPageIndex->toInt32(), mode->toInt32())); +} + +JSSmart<CJSValue> CDrawingFileEmbed::GetImageBase64(JSSmart<CJSValue> rId) +{ + std::string* pData = (std::string*)m_pFile->GetImageBase64(rId->toInt32()); + if (!pData) + return CJSContext::createNull(); + JSSmart<CJSValue> ret = CJSContext::createString(*pData); + *pData = ""; + return ret; +} + +JSSmart<CJSValue> CDrawingFileEmbed::FreeWasmData(JSSmart<CJSValue> typedArray) +{ + if (!typedArray->isTypedArray()) + return NULL; + BYTE* data = typedArray->toTypedArray()->getData().Data; + typedArray->toTypedArray()->Detach(); + data -= 4; // sizeof int (length in NSWasm::Data) + free(data); + return NULL; +} + +bool EmbedDrawingFile(JSSmart<NSJSBase::CJSContext>& context, IOfficeDrawingFile* pFile) +{ + CJSContext::Embed<CDrawingFileEmbed>(false); + + JSSmart<CJSObject> oNativeDrawingFile = CJSContext::createEmbedObject("CDrawingFileEmbed"); + context->GetGlobal()->set("g_native_drawing_file", oNativeDrawingFile); + + CDrawingFile* pDrFile = new CDrawingFile(pFile->GetFonts()); + pDrFile->SetInternalFile(pFile); + ((CDrawingFileEmbed*)oNativeDrawingFile->getNative())->m_pFile = pDrFile; + + return true; +} diff --git a/DesktopEditor/doctrenderer/embed/DrawingFileEmbed.h b/DesktopEditor/doctrenderer/embed/DrawingFileEmbed.h new file mode 100644 index 00000000000..06ad7e8f60b --- /dev/null +++ b/DesktopEditor/doctrenderer/embed/DrawingFileEmbed.h @@ -0,0 +1,59 @@ +#ifndef _BUILD_DRAWING_EMBED_H_ +#define _BUILD_DRAWING_EMBED_H_ + +#include "../js_internal/js_base.h" +#include "../../graphics/pro/officedrawingfile.h" + +class CDrawingFile; + +using namespace NSJSBase; +class JS_DECL CDrawingFileEmbed : public CJSEmbedObject +{ +public: + CDrawingFile* m_pFile; + +public: + CDrawingFileEmbed(); + ~CDrawingFileEmbed(); + + virtual void* getObject() override { return (void*)m_pFile; } + +public: + JSSmart<CJSValue> OpenFile(JSSmart<CJSValue> sFile, JSSmart<CJSValue> sPassword); + JSSmart<CJSValue> CloseFile(); + + JSSmart<CJSValue> GetType(); + JSSmart<CJSValue> GetErrorCode(); + + JSSmart<CJSValue> GetInfo(); + + JSSmart<CJSValue> GetPixmap(JSSmart<CJSValue> nPageIndex, JSSmart<CJSValue> nRasterW, JSSmart<CJSValue> nRasterH, JSSmart<CJSValue> nBackgroundColor); + JSSmart<CJSValue> DestroyPixmap(JSSmart<CJSValue> typedArray); + + JSSmart<CJSValue> GetLinks(JSSmart<CJSValue> nPageIndex); + JSSmart<CJSValue> GetStructure(); + JSSmart<CJSValue> GetInteractiveFormsInfo(); + JSSmart<CJSValue> GetInteractiveFormsFonts(JSSmart<CJSValue> nTypeFonts); + + JSSmart<CJSValue> GetInteractiveFormsAP(JSSmart<CJSValue> nRasterW, JSSmart<CJSValue> nRasterH, JSSmart<CJSValue> nBackgroundColor, JSSmart<CJSValue> nPageIndex, JSSmart<CJSValue> nWidget, JSSmart<CJSValue> nView, JSSmart<CJSValue> nButtonView); + JSSmart<CJSValue> GetButtonIcons(JSSmart<CJSValue> nBackgroundColor, JSSmart<CJSValue> nPageIndex, JSSmart<CJSValue> bBase64, JSSmart<CJSValue> nButtonWidget, JSSmart<CJSValue> nIconView); + JSSmart<CJSValue> GetAnnotationsInfo(JSSmart<CJSValue> nPageIndex); + JSSmart<CJSValue> GetAnnotationsAP(JSSmart<CJSValue> nRasterW, JSSmart<CJSValue> nRasterH, JSSmart<CJSValue> nBackgroundColor, JSSmart<CJSValue> nPageIndex, JSSmart<CJSValue> nAnnot, JSSmart<CJSValue> nView); + + JSSmart<CJSValue> GetFontBinary(JSSmart<CJSValue> Id); + JSSmart<CJSValue> GetGlyphs(JSSmart<CJSValue> nPageIndex); + JSSmart<CJSValue> DestroyTextInfo(); + + JSSmart<CJSValue> IsNeedCMap(); + JSSmart<CJSValue> ScanPage(JSSmart<CJSValue> nPageIndex, JSSmart<CJSValue> mode); + + JSSmart<CJSValue> GetImageBase64(JSSmart<CJSValue> rId); + + JSSmart<CJSValue> FreeWasmData(JSSmart<CJSValue> typedArray); + + DECLARE_EMBED_METHODS +}; + +bool EmbedDrawingFile(JSSmart<NSJSBase::CJSContext>& context, IOfficeDrawingFile* pFile); + +#endif // _BUILD_NATIVE_ZIP_EMBED_H_ diff --git a/DesktopEditor/doctrenderer/embed/GraphicsEmbed.cpp b/DesktopEditor/doctrenderer/embed/GraphicsEmbed.cpp index 69f21471bb1..b2677c4b85e 100644 --- a/DesktopEditor/doctrenderer/embed/GraphicsEmbed.cpp +++ b/DesktopEditor/doctrenderer/embed/GraphicsEmbed.cpp @@ -1,8 +1,178 @@ -#include "GraphicsEmbed.h" +#include "../graphics.h" +#include <map> +#include "../../../Common/Network/FileTransporter/include/FileTransporter.h" + +// APPLICATION INFO +class CGraphicsAppImage_private +{ +public: + NSFonts::IApplicationFonts* m_pFonts; + std::wstring m_sFontsDirectory; + std::wstring m_sImagesDirectory; + std::wstring m_sThemesDirectory; + bool m_bIsRgba; + + std::map<std::wstring, std::wstring> m_mapDownloads; + + CGraphicsAppImage_private() + { + m_pFonts = NULL; + m_sFontsDirectory = L""; + m_sImagesDirectory = L""; + m_sThemesDirectory = L""; + m_bIsRgba = false; + } + ~CGraphicsAppImage_private() + { + RELEASEINTERFACE(m_pFonts); + + for (std::map<std::wstring, std::wstring>::iterator i = m_mapDownloads.begin(); i != m_mapDownloads.end(); i++) + { + std::wstring sTmp = i->second; + if (NSFile::CFileBinary::Exists(sTmp)) + NSFile::CFileBinary::Remove(sTmp); + } + } + + bool IsNeedDownload(const std::wstring& sUrl) + { + if ((0 == sUrl.find(L"www.")) || + (0 == sUrl.find(L"http://")) || + (0 == sUrl.find(L"https://"))) + return true; + return false; + } + + std::wstring GetImagePath(const std::wstring& sUrl) + { + std::map<std::wstring, std::wstring>::iterator find = m_mapDownloads.find(sUrl); + if (find != m_mapDownloads.end()) + return find->second; + + NSNetwork::NSFileTransport::CFileDownloader oDownloader(sUrl, false); + + std::wstring sTmpFile = NSFile::CFileBinary::CreateTempFileWithUniqueName(NSFile::CFileBinary::GetTempPath(), L"IMG"); + if (NSFile::CFileBinary::Exists(sTmpFile)) + NSFile::CFileBinary::Remove(sTmpFile); + sTmpFile = sTmpFile + L".png"; + + oDownloader.SetFilePath(sTmpFile); + oDownloader.Start(0); + while ( oDownloader.IsRunned() ) + { + NSThreads::Sleep( 10 ); + } + bool bIsDownloaded = oDownloader.IsFileDownloaded(); + + if (bIsDownloaded) + { + m_mapDownloads.insert(std::pair<std::wstring, std::wstring>(sUrl, sTmpFile)); + return sTmpFile; + } + + return sUrl; + } +}; + +CGraphicsAppImage::CGraphicsAppImage() +{ + m_internal = new CGraphicsAppImage_private(); +} +CGraphicsAppImage::~CGraphicsAppImage() +{ + delete m_internal; +} + +void CGraphicsAppImage::SetFontsDirectory(const std::wstring& dir) +{ + m_internal->m_sFontsDirectory = dir; +} +std::wstring CGraphicsAppImage::GetFontsDirectory() +{ + return m_internal->m_sFontsDirectory; +} + +void CGraphicsAppImage::SetImagesDirectory(const std::wstring& dir) +{ + m_internal->m_sImagesDirectory = dir; +} +std::wstring CGraphicsAppImage::GetImagesDirectory() +{ + return m_internal->m_sImagesDirectory; +} + +void CGraphicsAppImage::SetThemesDirectory(const std::wstring& dir) +{ + m_internal->m_sThemesDirectory = dir; +} +std::wstring CGraphicsAppImage::GetThemesDirectory() +{ + return m_internal->m_sThemesDirectory; +} + +void CGraphicsAppImage::SetFonts(NSFonts::IApplicationFonts* fonts) +{ + m_internal->m_pFonts = fonts; + ADDREFINTERFACE(fonts); +} +NSFonts::IApplicationFonts* CGraphicsAppImage::GetFonts() +{ + return m_internal->m_pFonts; +} + +void CGraphicsAppImage::SetRgba(const bool& isRgba) +{ + m_internal->m_bIsRgba = isRgba; +} +bool CGraphicsAppImage::GetRgba() +{ + return m_internal->m_bIsRgba; +} + +unsigned char* CGraphicsAppImage::GetBits(int& w, int& h) +{ + return NULL; +} +unsigned char* CGraphicsAppImage::AllocBits(const int& w, const int& h) +{ + return new unsigned char[4 * w * h]; +} + +// APPLICATION INFO END + +CGraphicsEmbed::CGraphicsEmbed() : m_pInternal(new NSGraphics::CGraphics()) +{ +} +CGraphicsEmbed::~CGraphicsEmbed() +{ + RELEASEOBJECT(m_pInternal); +} + +CGraphicsAppImage* CGraphicsEmbed::GetAppImage() +{ + return m_pInternal->m_pAppImage; +} + +void CGraphicsEmbed::SetAppImage(CGraphicsAppImage* appImage) +{ + m_pInternal->m_pAppImage = appImage; +} JSSmart<CJSValue> CGraphicsEmbed::create(JSSmart<CJSValue> Native, JSSmart<CJSValue> width_px, JSSmart<CJSValue> height_px, JSSmart<CJSValue> width_mm, JSSmart<CJSValue> height_mm) { - m_pInternal->init((NSNativeControl::CNativeControl*)Native->toObject()->getNative()->getObject(), width_px->toDouble(), height_px->toDouble(), width_mm->toDouble(), height_mm->toDouble()); + NSNativeControl::CNativeControl* pControl = NULL; + if (!Native->isNull()) + { + pControl = (NSNativeControl::CNativeControl*)Native->toObject()->getNative()->getObject(); + + if (m_pInternal->m_pAppImage) + delete m_pInternal->m_pAppImage; + m_pInternal->m_pAppImage = new CGraphicsAppImage(); + m_pInternal->m_pAppImage->SetFontsDirectory(pControl->m_strFontsDirectory); + m_pInternal->m_pAppImage->SetImagesDirectory(pControl->m_strImagesDirectory); + } + + m_pInternal->init(width_px->toDouble(), height_px->toDouble(), width_mm->toDouble(), height_mm->toDouble()); return NULL; } JSSmart<CJSValue> CGraphicsEmbed::Destroy() @@ -150,11 +320,19 @@ JSSmart<CJSValue> CGraphicsEmbed::ClearLastFont() } JSSmart<CJSValue> CGraphicsEmbed::drawImage2(JSSmart<CJSValue> img, JSSmart<CJSValue> x, JSSmart<CJSValue> y, JSSmart<CJSValue> w, JSSmart<CJSValue> h, JSSmart<CJSValue> alpha, JSSmart<CJSValue> srcRect) { - m_pInternal->drawImage(img->toStringW(), x->toDouble(), y->toDouble(), w->toDouble(), h->toDouble(), alpha->toInt32()); + std::wstring sUrl = img->toStringW(); + if (m_pInternal->m_pAppImage && m_pInternal->m_pAppImage->m_internal->IsNeedDownload(sUrl)) + sUrl = m_pInternal->m_pAppImage->m_internal->GetImagePath(sUrl); + + m_pInternal->drawImage(sUrl, x->toDouble(), y->toDouble(), w->toDouble(), h->toDouble(), alpha->toInt32()); return NULL; } JSSmart<CJSValue> CGraphicsEmbed::drawImage (JSSmart<CJSValue> img, JSSmart<CJSValue> x, JSSmart<CJSValue> y, JSSmart<CJSValue> w, JSSmart<CJSValue> h, JSSmart<CJSValue> alpha, JSSmart<CJSValue> srcRect, JSSmart<CJSValue> nativeImage) { + std::wstring sUrl = img->toStringW(); + if (m_pInternal->m_pAppImage && m_pInternal->m_pAppImage->m_internal->IsNeedDownload(sUrl)) + sUrl = m_pInternal->m_pAppImage->m_internal->GetImagePath(sUrl); + m_pInternal->drawImage(img->toStringW(), x->toDouble(), y->toDouble(), w->toDouble(), h->toDouble(), alpha->toInt32()); return NULL; } @@ -459,7 +637,11 @@ JSSmart<CJSValue> CGraphicsEmbed::GetBrushColor() } JSSmart<CJSValue> CGraphicsEmbed::put_brushTexture(JSSmart<CJSValue> src, JSSmart<CJSValue> type) { - m_pInternal->put_brushTexture(src->toStringW(), type->toInt32()); + std::wstring sUrl = src->toStringW(); + if (m_pInternal->m_pAppImage && m_pInternal->m_pAppImage->m_internal->IsNeedDownload(sUrl)) + sUrl = m_pInternal->m_pAppImage->m_internal->GetImagePath(sUrl); + + m_pInternal->put_brushTexture(sUrl, type->toInt32()); return NULL; } JSSmart<CJSValue> CGraphicsEmbed::put_brushTextureMode(JSSmart<CJSValue> mode) @@ -564,3 +746,14 @@ JSSmart<CJSValue> CGraphicsEmbed::GetTransform() e->set("ty", res.ty); return e->toValue(); } + +JSSmart<CJSValue> CGraphicsEmbed::CreateLayer(JSSmart<CJSValue> opacity) +{ + m_pInternal->CreateLayer(opacity->toDouble()); + return NULL; +} +JSSmart<CJSValue> CGraphicsEmbed::BlendLayer() +{ + m_pInternal->BlendLayer(); + return NULL; +} diff --git a/DesktopEditor/doctrenderer/embed/GraphicsEmbed.h b/DesktopEditor/doctrenderer/embed/GraphicsEmbed.h index 5982da98923..f6839e993c6 100644 --- a/DesktopEditor/doctrenderer/embed/GraphicsEmbed.h +++ b/DesktopEditor/doctrenderer/embed/GraphicsEmbed.h @@ -1,21 +1,57 @@ #ifndef _BUILD_NATIVE_GRAPHICS_EMBED_H_ #define _BUILD_NATIVE_GRAPHICS_EMBED_H_ -#include "../graphics.h" +#include "../../graphics/pro/Fonts.h" #include "../js_internal/js_base.h" +class CGraphicsAppImage_private; +class JS_DECL CGraphicsAppImage +{ +public: + CGraphicsAppImage(); + virtual ~CGraphicsAppImage(); +public: + void SetFontsDirectory(const std::wstring& dir); + std::wstring GetFontsDirectory(); + + void SetImagesDirectory(const std::wstring& dir); + std::wstring GetImagesDirectory(); + + void SetThemesDirectory(const std::wstring& dir); + std::wstring GetThemesDirectory(); + + void SetFonts(NSFonts::IApplicationFonts* fonts); + NSFonts::IApplicationFonts* GetFonts(); + + void SetRgba(const bool& isRgba); + bool GetRgba(); + + virtual unsigned char* GetBits(int& w, int& h); + virtual unsigned char* AllocBits(const int& w, const int& h); + +private: + CGraphicsAppImage_private* m_internal; + + friend class CGraphicsEmbed; +}; + +namespace NSGraphics { class CGraphics; } + using namespace NSJSBase; -class CGraphicsEmbed : public CJSEmbedObject +class JS_DECL CGraphicsEmbed : public CJSEmbedObject { public: NSGraphics::CGraphics* m_pInternal; public: - CGraphicsEmbed() : m_pInternal(new NSGraphics::CGraphics()) {} - ~CGraphicsEmbed() { RELEASEOBJECT(m_pInternal); } + CGraphicsEmbed(); + ~CGraphicsEmbed(); virtual void* getObject() override { return (void*)m_pInternal; } + CGraphicsAppImage* GetAppImage(); + void SetAppImage(CGraphicsAppImage* appImage); + public: JSSmart<CJSValue> create(JSSmart<CJSValue> Native, JSSmart<CJSValue> width_px, JSSmart<CJSValue> height_px, JSSmart<CJSValue> width_mm, JSSmart<CJSValue> height_mm); JSSmart<CJSValue> Destroy(); @@ -82,11 +118,11 @@ class CGraphicsEmbed : public CJSEmbedObject JSSmart<CJSValue> drawHorLine (JSSmart<CJSValue> align, JSSmart<CJSValue> y, JSSmart<CJSValue> x, JSSmart<CJSValue> r, JSSmart<CJSValue> penW); JSSmart<CJSValue> drawHorLine2(JSSmart<CJSValue> align, JSSmart<CJSValue> y, JSSmart<CJSValue> x, JSSmart<CJSValue> r, JSSmart<CJSValue> penW); JSSmart<CJSValue> drawVerLine (JSSmart<CJSValue> align, JSSmart<CJSValue> x, JSSmart<CJSValue> y, JSSmart<CJSValue> b, JSSmart<CJSValue> penW); - // мега крутые функции для таблиц + JSSmart<CJSValue> drawHorLineExt(JSSmart<CJSValue> align, JSSmart<CJSValue> y, JSSmart<CJSValue> x, JSSmart<CJSValue> r, JSSmart<CJSValue> penW, JSSmart<CJSValue> leftMW, JSSmart<CJSValue> rightMW); JSSmart<CJSValue> rect (JSSmart<CJSValue> x, JSSmart<CJSValue> y, JSSmart<CJSValue> w, JSSmart<CJSValue> h); JSSmart<CJSValue> TableRect(JSSmart<CJSValue> x, JSSmart<CJSValue> y, JSSmart<CJSValue> w, JSSmart<CJSValue> h); - // функции клиппирования + JSSmart<CJSValue> AddClipRect(JSSmart<CJSValue> x, JSSmart<CJSValue> y, JSSmart<CJSValue> w, JSSmart<CJSValue> h); JSSmart<CJSValue> RemoveClipRect(); JSSmart<CJSValue> SetClip(JSSmart<CJSValue> x, JSSmart<CJSValue> y, JSSmart<CJSValue> w, JSSmart<CJSValue> h); @@ -132,6 +168,10 @@ class CGraphicsEmbed : public CJSEmbedObject JSSmart<CJSValue> CoordTransformOffset(JSSmart<CJSValue> tx, JSSmart<CJSValue> ty); JSSmart<CJSValue> GetTransform(); + // layer + JSSmart<CJSValue> CreateLayer(JSSmart<CJSValue> opacity); + JSSmart<CJSValue> BlendLayer(); + DECLARE_EMBED_METHODS }; diff --git a/DesktopEditor/doctrenderer/embed/NativeBuilderDocumentEmbed.cpp b/DesktopEditor/doctrenderer/embed/NativeBuilderDocumentEmbed.cpp index 40c05ada63b..d33417f9871 100644 --- a/DesktopEditor/doctrenderer/embed/NativeBuilderDocumentEmbed.cpp +++ b/DesktopEditor/doctrenderer/embed/NativeBuilderDocumentEmbed.cpp @@ -2,6 +2,7 @@ #include "./../docbuilder_p.h" #include "../../common/Directory.h" +#include "../server.h" JSSmart<CJSValue> CBuilderDocumentEmbed::IsValid() { @@ -68,13 +69,23 @@ void CBuilderDocumentEmbed::_OpenFile(const std::wstring& sFile, const std::wstr int nConvertResult = pBuilder->ConvertToInternalFormat(m_sFolder, sFileCopy, sParams); if (0 == nConvertResult) + { + if (CServerInstance::getInstance().IsEnable()) + CServerInstance::getInstance().AddTmpFile(m_sFolder); m_bIsValid = true; + } } void CBuilderDocumentEmbed::_CloseFile() { if (!m_sFolder.empty()) + { NSDirectory::DeleteDirectory(m_sFolder); + + if (m_bIsValid && CServerInstance::getInstance().IsEnable()) + CServerInstance::getInstance().RemoveTmpFile(m_sFolder); + } + m_bIsValid = false; m_sFolder = L""; } diff --git a/DesktopEditor/doctrenderer/embed/NativeControlEmbed.cpp b/DesktopEditor/doctrenderer/embed/NativeControlEmbed.cpp index 797890b4c27..e1bf018f6ad 100644 --- a/DesktopEditor/doctrenderer/embed/NativeControlEmbed.cpp +++ b/DesktopEditor/doctrenderer/embed/NativeControlEmbed.cpp @@ -1,4 +1,5 @@ #include "NativeControlEmbed.h" +#include "../server.h" JSSmart<CJSValue> CNativeControlEmbed::SetFilePath(JSSmart<CJSValue> path) { @@ -24,7 +25,17 @@ JSSmart<CJSValue> CNativeControlEmbed::GetFileId() JSSmart<CJSValue> CNativeControlEmbed::GetFileBinary(JSSmart<CJSValue> file) { - return CJSContext::createUint8Array(file->toStringW()); + std::wstring sFilePath = file->toStringW(); + + if (CServerInstance::getInstance().IsEnable()) + { + std::wstring sFileFolder = NSFile::GetDirectoryName(m_pInternal->GetFilePath()); + if (0 == sFilePath.find(sFileFolder)) + return CJSContext::createUint8Array(sFilePath); + return CJSContext::createNull(); + } + + return CJSContext::createUint8Array(sFilePath); } JSSmart<CJSValue> CNativeControlEmbed::GetFontBinary(JSSmart<CJSValue> file) @@ -59,6 +70,8 @@ JSSmart<CJSValue> CNativeControlEmbed::GetFontsDirectory() JSSmart<CJSValue> CNativeControlEmbed::GetFileString(JSSmart<CJSValue> file) { + if (CServerInstance::getInstance().IsEnable()) + return CJSContext::createNull(); return CJSContext::createUint8Array(file->toStringW()); } diff --git a/DesktopEditor/doctrenderer/embed/TextMeasurerEmbed.cpp b/DesktopEditor/doctrenderer/embed/TextMeasurerEmbed.cpp index 269a6b9e3b2..76ceb51259a 100644 --- a/DesktopEditor/doctrenderer/embed/TextMeasurerEmbed.cpp +++ b/DesktopEditor/doctrenderer/embed/TextMeasurerEmbed.cpp @@ -134,7 +134,11 @@ JSSmart<CJSValue> CTextMeasurerEmbed::FT_Get_Glyph_Render_Params(JSSmart<CJSValu JSSmart<CJSValue> CTextMeasurerEmbed::FT_Get_Glyph_Render_Buffer(JSSmart<CJSValue> face, JSSmart<CJSValue> size) { void* Data = NSShaper::FT_Get_Glyph_Render_Buffer(RAW_POINTER(face)); - return CJSContext::createUint8Array((unsigned char*)Data, size->toInt32(), true); + int nSize = size->toInt32(); + int nSizeMax = NSShaper::FT_Get_Glyph_Render_BufferSize(RAW_POINTER(face)); + if (nSize > nSizeMax) + nSize = nSizeMax; + return CJSContext::createUint8Array((unsigned char*)Data, nSize, true); } JSSmart<CJSValue> CTextMeasurerEmbed::FT_Set_Transform(JSSmart<CJSValue> face, JSSmart<CJSValue> xx, JSSmart<CJSValue> yx, JSSmart<CJSValue> xy, JSSmart<CJSValue> yy) diff --git a/DesktopEditor/doctrenderer/embed/ZipEmbed.cpp b/DesktopEditor/doctrenderer/embed/ZipEmbed.cpp index 80364323d2a..1d76d6cb5fa 100644 --- a/DesktopEditor/doctrenderer/embed/ZipEmbed.cpp +++ b/DesktopEditor/doctrenderer/embed/ZipEmbed.cpp @@ -2,6 +2,7 @@ #include "../../raster/BgraFrame.h" #include "../../graphics/pro/Image.h" #include "../../raster/ImageFileFormatChecker.h" +#include "server.h" JSSmart<CJSValue> CZipEmbed::open(JSSmart<CJSValue> typedArray_or_Folder) { @@ -18,7 +19,8 @@ JSSmart<CJSValue> CZipEmbed::open(JSSmart<CJSValue> typedArray_or_Folder) } else if (typedArray_or_Folder->isString()) { - m_pFolder = new CFolderSystem(typedArray_or_Folder->toStringW()); + if (!CServerInstance::getInstance().IsEnable()) + m_pFolder = new CFolderSystem(typedArray_or_Folder->toStringW()); } if (!m_pFolder) @@ -174,7 +176,7 @@ JSSmart<CJSValue> CZipEmbed::encodeImageData(JSSmart<CJSValue> typedArray, JSSma if (oFrame.Encode(pBuffer, nEncodedSize, format->toInt32())) { BYTE* pData = NSAllocator::Alloc((size_t)nEncodedSize); - memcpy(pData, oFrame.get_Data(), (size_t)nEncodedSize); + memcpy(pData, pBuffer, (size_t)nEncodedSize); oFrame.FreeEncodedMemory(pBuffer); oFrame.put_Data(NULL); @@ -228,7 +230,7 @@ JSSmart<CJSValue> CZipEmbed::encodeImage(JSSmart<CJSValue> typedArray, JSSmart<C if (oFrame.Encode(pBuffer, nEncodedSize, format->toInt32())) { BYTE* pData = NSAllocator::Alloc((size_t)nEncodedSize); - memcpy(pData, oFrame.get_Data(), (size_t)nEncodedSize); + memcpy(pData, pBuffer, (size_t)nEncodedSize); oFrame.FreeEncodedMemory(pBuffer); oFrame.put_Data(NULL); @@ -256,3 +258,64 @@ JSSmart<CJSValue> CZipEmbed::getImageType(JSSmart<CJSValue> typedArray) oBuffer.Free(); return CJSContext::createInt(bIsImageFile ? oChecker.eFileType : 0); } + +JSSmart<CJSValue> CZipEmbed::getImageBuffer(JSSmart<CJSValue> filePath) +{ + if (!m_pFolder || !filePath->isString()) + return CJSContext::createNull(); + + std::wstring sFilePath = filePath->toStringW(); + IFolder::CBuffer* pBuffer; + if (!m_pFolder->read(sFilePath, pBuffer)) + return CJSContext::createNull(); + + size_t nBufferSize = (size_t)pBuffer->Size; + + CImageFileFormatChecker oChecker; + bool bIsImageFile = oChecker.isImageFile(pBuffer->Buffer, (DWORD)pBuffer->Size); + + if (!bIsImageFile) + { + RELEASEOBJECT(pBuffer); + return CJSContext::createNull(); + } + + bool bIsNeedConvertMetfileToSvg = false; + + // Make as wasm module + if (oChecker.eFileType == _CXIMAGE_FORMAT_WMF || oChecker.eFileType == _CXIMAGE_FORMAT_EMF) + oChecker.eFileType = _CXIMAGE_FORMAT_SVG; + else + bIsNeedConvertMetfileToSvg = false; + + if (!bIsNeedConvertMetfileToSvg) + { + BYTE* pMemory = NSJSBase::NSAllocator::Alloc(nBufferSize); + memcpy(pMemory, pBuffer->Buffer, nBufferSize); + RELEASEOBJECT(pBuffer); + + JSSmart<CJSObject> retObject = CJSContext::createObject(); + retObject->set("type", CJSContext::createInt(oChecker.eFileType)); + retObject->set("data", NSJSBase::CJSContext::createUint8Array(pMemory, (int)nBufferSize, false)); + return retObject->toValue(); + } + +#ifndef GRAPHICS_DISABLE_METAFILE + MetaFile::IMetaFile* pMetaFile = MetaFile::Create(NULL); + pMetaFile->LoadFromBuffer(pBuffer->Buffer, (unsigned int)pBuffer->Size); + std::wstring wsSvg = pMetaFile->ConvertToSvg(); + std::string sSvg = U_TO_UTF8(wsSvg); + pMetaFile->Release(); + RELEASEOBJECT(pBuffer); + + BYTE* pData = NSAllocator::Alloc(sSvg.length()); + memcpy(pData, sSvg.c_str(), sSvg.length()); + + JSSmart<CJSObject> retObject = CJSContext::createObject(); + retObject->set("type", CJSContext::createInt(24)); + retObject->set("data", NSJSBase::CJSContext::createUint8Array(pData, sSvg.length(), false)); + return retObject->toValue(); +#else + return CJSContext::createNull(); +#endif +} diff --git a/DesktopEditor/doctrenderer/embed/ZipEmbed.h b/DesktopEditor/doctrenderer/embed/ZipEmbed.h index 35bb724ffbd..02a4e860605 100644 --- a/DesktopEditor/doctrenderer/embed/ZipEmbed.h +++ b/DesktopEditor/doctrenderer/embed/ZipEmbed.h @@ -36,6 +36,7 @@ class JS_DECL CZipEmbed : public CJSEmbedObject JSSmart<CJSValue> encodeImageData(JSSmart<CJSValue> typedArray, JSSmart<CJSValue> w, JSSmart<CJSValue> h, JSSmart<CJSValue> stride, JSSmart<CJSValue> format, JSSmart<CJSValue> isRgba); JSSmart<CJSValue> encodeImage(JSSmart<CJSValue> typedArray, JSSmart<CJSValue> format); JSSmart<CJSValue> getImageType(JSSmart<CJSValue> typedArray); + JSSmart<CJSValue> getImageBuffer(JSSmart<CJSValue> path); DECLARE_EMBED_METHODS }; diff --git a/DesktopEditor/doctrenderer/embed/jsc/jsc_DrawingFileEmbed.mm b/DesktopEditor/doctrenderer/embed/jsc/jsc_DrawingFileEmbed.mm new file mode 100644 index 00000000000..bc460ff302d --- /dev/null +++ b/DesktopEditor/doctrenderer/embed/jsc/jsc_DrawingFileEmbed.mm @@ -0,0 +1,87 @@ +// THIS FILE WAS GENERATED AUTOMATICALLY. DO NOT CHANGE IT! +// IF YOU NEED TO UPDATE THIS CODE, JUST RERUN PYTHON SCRIPT WITH "--internal" OPTION. + +#include "../DrawingFileEmbed.h" +#include "../../js_internal/jsc/jsc_base.h" + +@protocol IJSCDrawingFileEmbed <JSExport> +-(JSValue*) OpenFile : (JSValue*)sFile : (JSValue*)sPassword; +-(JSValue*) CloseFile; +-(JSValue*) GetType; +-(JSValue*) GetErrorCode; +-(JSValue*) GetInfo; +-(JSValue*) GetPixmap : (JSValue*)nPageIndex : (JSValue*)nRasterW : (JSValue*)nRasterH : (JSValue*)nBackgroundColor; +-(JSValue*) DestroyPixmap : (JSValue*)typedArray; +-(JSValue*) GetLinks : (JSValue*)nPageIndex; +-(JSValue*) GetStructure; +-(JSValue*) GetInteractiveFormsInfo; +-(JSValue*) GetInteractiveFormsFonts : (JSValue*)nTypeFonts; +-(JSValue*) GetInteractiveFormsAP : (JSValue*)nRasterW : (JSValue*)nRasterH : (JSValue*)nBackgroundColor : (JSValue*)nPageIndex : (JSValue*)nWidget : (JSValue*)nView : (JSValue*)nButtonView; +-(JSValue*) GetButtonIcons : (JSValue*)nBackgroundColor : (JSValue*)nPageIndex : (JSValue*)bBase64 : (JSValue*)nButtonWidget : (JSValue*)nIconView; +-(JSValue*) GetAnnotationsInfo : (JSValue*)nPageIndex; +-(JSValue*) GetAnnotationsAP : (JSValue*)nRasterW : (JSValue*)nRasterH : (JSValue*)nBackgroundColor : (JSValue*)nPageIndex : (JSValue*)nAnnot : (JSValue*)nView; +-(JSValue*) GetFontBinary : (JSValue*)Id; +-(JSValue*) GetGlyphs : (JSValue*)nPageIndex; +-(JSValue*) DestroyTextInfo; +-(JSValue*) IsNeedCMap; +-(JSValue*) ScanPage : (JSValue*)nPageIndex : (JSValue*)mode; +-(JSValue*) GetImageBase64 : (JSValue*)rId; +-(JSValue*) FreeWasmData : (JSValue*)typedArray; +@end + +@interface CJSCDrawingFileEmbed : NSObject<IJSCDrawingFileEmbed, JSEmbedObjectProtocol> +{ +@public + CDrawingFileEmbed* m_internal; +} +@end + +@implementation CJSCDrawingFileEmbed +EMBED_OBJECT_WRAPPER_METHODS(CDrawingFileEmbed); + +FUNCTION_WRAPPER_JS_2(OpenFile, OpenFile) +FUNCTION_WRAPPER_JS_0(CloseFile, CloseFile) +FUNCTION_WRAPPER_JS_0(GetType, GetType) +FUNCTION_WRAPPER_JS_0(GetErrorCode, GetErrorCode) +FUNCTION_WRAPPER_JS_0(GetInfo, GetInfo) +FUNCTION_WRAPPER_JS_4(GetPixmap, GetPixmap) +FUNCTION_WRAPPER_JS_1(DestroyPixmap, DestroyPixmap) +FUNCTION_WRAPPER_JS_1(GetLinks, GetLinks) +FUNCTION_WRAPPER_JS_0(GetStructure, GetStructure) +FUNCTION_WRAPPER_JS_0(GetInteractiveFormsInfo, GetInteractiveFormsInfo) +FUNCTION_WRAPPER_JS_1(GetInteractiveFormsFonts, GetInteractiveFormsFonts) +FUNCTION_WRAPPER_JS_7(GetInteractiveFormsAP, GetInteractiveFormsAP) +FUNCTION_WRAPPER_JS_5(GetButtonIcons, GetButtonIcons) +FUNCTION_WRAPPER_JS_1(GetAnnotationsInfo, GetAnnotationsInfo) +FUNCTION_WRAPPER_JS_6(GetAnnotationsAP, GetAnnotationsAP) +FUNCTION_WRAPPER_JS_1(GetFontBinary, GetFontBinary) +FUNCTION_WRAPPER_JS_1(GetGlyphs, GetGlyphs) +FUNCTION_WRAPPER_JS_0(DestroyTextInfo, DestroyTextInfo) +FUNCTION_WRAPPER_JS_0(IsNeedCMap, IsNeedCMap) +FUNCTION_WRAPPER_JS_2(ScanPage, ScanPage) +FUNCTION_WRAPPER_JS_1(GetImageBase64, GetImageBase64) +FUNCTION_WRAPPER_JS_1(FreeWasmData, FreeWasmData) +@end + +class CDrawingFileEmbedAdapter : public CJSEmbedObjectAdapterJSC +{ +public: + virtual id getExportedObject(CJSEmbedObject* pNative) override + { + return [[CJSCDrawingFileEmbed alloc] init:(CDrawingFileEmbed*)pNative]; + } +}; + +CJSEmbedObjectAdapterBase* CDrawingFileEmbed::getAdapter() +{ + if (m_pAdapter == nullptr) + m_pAdapter = new CDrawingFileEmbedAdapter(); + return m_pAdapter; +} + +std::string CDrawingFileEmbed::getName() { return "CDrawingFileEmbed"; } + +CJSEmbedObject* CDrawingFileEmbed::getCreator() +{ + return new CDrawingFileEmbed(); +} diff --git a/DesktopEditor/doctrenderer/embed/jsc/jsc_GraphicsEmbed.mm b/DesktopEditor/doctrenderer/embed/jsc/jsc_GraphicsEmbed.mm index 0928dcb2d68..cb6ddd924a2 100644 --- a/DesktopEditor/doctrenderer/embed/jsc/jsc_GraphicsEmbed.mm +++ b/DesktopEditor/doctrenderer/embed/jsc/jsc_GraphicsEmbed.mm @@ -108,6 +108,8 @@ -(JSValue*) GetlineWidth; -(JSValue*) DrawPath : (JSValue*)path; -(JSValue*) CoordTransformOffset : (JSValue*)tx : (JSValue*)ty; -(JSValue*) GetTransform; +-(JSValue*) CreateLayer : (JSValue*)opacity; +-(JSValue*) BlendLayer; @end @interface CJSCGraphicsEmbed : NSObject<IJSCGraphicsEmbed, JSEmbedObjectProtocol> @@ -223,6 +225,8 @@ @implementation CJSCGraphicsEmbed FUNCTION_WRAPPER_JS_1(DrawPath, DrawPath) FUNCTION_WRAPPER_JS_2(CoordTransformOffset, CoordTransformOffset) FUNCTION_WRAPPER_JS_0(GetTransform, GetTransform) +FUNCTION_WRAPPER_JS_1(CreateLayer, CreateLayer) +FUNCTION_WRAPPER_JS_0(BlendLayer, BlendLayer) @end class CGraphicsEmbedAdapter : public CJSEmbedObjectAdapterJSC diff --git a/DesktopEditor/doctrenderer/embed/jsc/jsc_ZipEmbed.mm b/DesktopEditor/doctrenderer/embed/jsc/jsc_ZipEmbed.mm index 1c831a0aab6..2da39ec0bcf 100644 --- a/DesktopEditor/doctrenderer/embed/jsc/jsc_ZipEmbed.mm +++ b/DesktopEditor/doctrenderer/embed/jsc/jsc_ZipEmbed.mm @@ -17,6 +17,7 @@ -(JSValue*) decodeImage : (JSValue*)typedArray : (JSValue*)isRgba; -(JSValue*) encodeImageData : (JSValue*)typedArray : (JSValue*)w : (JSValue*)h : (JSValue*)stride : (JSValue*)format : (JSValue*)isRgba; -(JSValue*) encodeImage : (JSValue*)typedArray : (JSValue*)format; -(JSValue*) getImageType : (JSValue*)typedArray; +-(JSValue*) getImageBuffer : (JSValue*)path; @end @interface CJSCZipEmbed : NSObject<IJSCZipEmbed, JSEmbedObjectProtocol> @@ -41,6 +42,7 @@ @implementation CJSCZipEmbed FUNCTION_WRAPPER_JS_6(encodeImageData, encodeImageData) FUNCTION_WRAPPER_JS_2(encodeImage, encodeImage) FUNCTION_WRAPPER_JS_1(getImageType, getImageType) +FUNCTION_WRAPPER_JS_1(getImageBuffer, getImageBuffer) @end class CZipEmbedAdapter : public CJSEmbedObjectAdapterJSC diff --git a/DesktopEditor/doctrenderer/embed/v8/v8_DrawingFileEmbed.cpp b/DesktopEditor/doctrenderer/embed/v8/v8_DrawingFileEmbed.cpp new file mode 100644 index 00000000000..454b4790b2c --- /dev/null +++ b/DesktopEditor/doctrenderer/embed/v8/v8_DrawingFileEmbed.cpp @@ -0,0 +1,90 @@ +// THIS FILE WAS GENERATED AUTOMATICALLY. DO NOT CHANGE IT! +// IF YOU NEED TO UPDATE THIS CODE, JUST RERUN PYTHON SCRIPT WITH "--internal" OPTION. + +#include "../DrawingFileEmbed.h" +#include "../../js_internal/v8/v8_base.h" + +namespace NSDrawingFileEmbed +{ +#define CURRENTWRAPPER CDrawingFileEmbed + + FUNCTION_WRAPPER_V8_2(_OpenFile, OpenFile) + FUNCTION_WRAPPER_V8_0(_CloseFile, CloseFile) + FUNCTION_WRAPPER_V8_0(_GetType, GetType) + FUNCTION_WRAPPER_V8_0(_GetErrorCode, GetErrorCode) + FUNCTION_WRAPPER_V8_0(_GetInfo, GetInfo) + FUNCTION_WRAPPER_V8_4(_GetPixmap, GetPixmap) + FUNCTION_WRAPPER_V8_1(_DestroyPixmap, DestroyPixmap) + FUNCTION_WRAPPER_V8_1(_GetLinks, GetLinks) + FUNCTION_WRAPPER_V8_0(_GetStructure, GetStructure) + FUNCTION_WRAPPER_V8_0(_GetInteractiveFormsInfo, GetInteractiveFormsInfo) + FUNCTION_WRAPPER_V8_1(_GetInteractiveFormsFonts, GetInteractiveFormsFonts) + FUNCTION_WRAPPER_V8_7(_GetInteractiveFormsAP, GetInteractiveFormsAP) + FUNCTION_WRAPPER_V8_5(_GetButtonIcons, GetButtonIcons) + FUNCTION_WRAPPER_V8_1(_GetAnnotationsInfo, GetAnnotationsInfo) + FUNCTION_WRAPPER_V8_6(_GetAnnotationsAP, GetAnnotationsAP) + FUNCTION_WRAPPER_V8_1(_GetFontBinary, GetFontBinary) + FUNCTION_WRAPPER_V8_1(_GetGlyphs, GetGlyphs) + FUNCTION_WRAPPER_V8_0(_DestroyTextInfo, DestroyTextInfo) + FUNCTION_WRAPPER_V8_0(_IsNeedCMap, IsNeedCMap) + FUNCTION_WRAPPER_V8_2(_ScanPage, ScanPage) + FUNCTION_WRAPPER_V8_1(_GetImageBase64, GetImageBase64) + FUNCTION_WRAPPER_V8_1(_FreeWasmData, FreeWasmData) + + v8::Handle<v8::ObjectTemplate> CreateTemplate(v8::Isolate* isolate) + { + v8::EscapableHandleScope handle_scope(isolate); + v8::Local<v8::ObjectTemplate> result = v8::ObjectTemplate::New(isolate); + result->SetInternalFieldCount(1); + + NSV8Objects::Template_Set(result, "OpenFile", _OpenFile); + NSV8Objects::Template_Set(result, "CloseFile", _CloseFile); + NSV8Objects::Template_Set(result, "GetType", _GetType); + NSV8Objects::Template_Set(result, "GetErrorCode", _GetErrorCode); + NSV8Objects::Template_Set(result, "GetInfo", _GetInfo); + NSV8Objects::Template_Set(result, "GetPixmap", _GetPixmap); + NSV8Objects::Template_Set(result, "DestroyPixmap", _DestroyPixmap); + NSV8Objects::Template_Set(result, "GetLinks", _GetLinks); + NSV8Objects::Template_Set(result, "GetStructure", _GetStructure); + NSV8Objects::Template_Set(result, "GetInteractiveFormsInfo", _GetInteractiveFormsInfo); + NSV8Objects::Template_Set(result, "GetInteractiveFormsFonts", _GetInteractiveFormsFonts); + NSV8Objects::Template_Set(result, "GetInteractiveFormsAP", _GetInteractiveFormsAP); + NSV8Objects::Template_Set(result, "GetButtonIcons", _GetButtonIcons); + NSV8Objects::Template_Set(result, "GetAnnotationsInfo", _GetAnnotationsInfo); + NSV8Objects::Template_Set(result, "GetAnnotationsAP", _GetAnnotationsAP); + NSV8Objects::Template_Set(result, "GetFontBinary", _GetFontBinary); + NSV8Objects::Template_Set(result, "GetGlyphs", _GetGlyphs); + NSV8Objects::Template_Set(result, "DestroyTextInfo", _DestroyTextInfo); + NSV8Objects::Template_Set(result, "IsNeedCMap", _IsNeedCMap); + NSV8Objects::Template_Set(result, "ScanPage", _ScanPage); + NSV8Objects::Template_Set(result, "GetImageBase64", _GetImageBase64); + NSV8Objects::Template_Set(result, "FreeWasmData", _FreeWasmData); + + return handle_scope.Escape(result); + } +} + +class CDrawingFileEmbedAdapter : public CJSEmbedObjectAdapterV8Template +{ +public: + virtual v8::Local<v8::ObjectTemplate> getTemplate(v8::Isolate* isolate) override + { + v8::EscapableHandleScope handle_scope(isolate); + v8::Local<v8::ObjectTemplate> templ = NSDrawingFileEmbed::CreateTemplate(isolate); + return handle_scope.Escape(templ); + } +}; + +CJSEmbedObjectAdapterBase* CDrawingFileEmbed::getAdapter() +{ + if (m_pAdapter == nullptr) + m_pAdapter = new CDrawingFileEmbedAdapter(); + return m_pAdapter; +} + +std::string CDrawingFileEmbed::getName() { return "CDrawingFileEmbed"; } + +CJSEmbedObject* CDrawingFileEmbed::getCreator() +{ + return new CDrawingFileEmbed(); +} diff --git a/DesktopEditor/doctrenderer/embed/v8/v8_GraphicsEmbed.cpp b/DesktopEditor/doctrenderer/embed/v8/v8_GraphicsEmbed.cpp index ce4aac9e742..8724353630b 100644 --- a/DesktopEditor/doctrenderer/embed/v8/v8_GraphicsEmbed.cpp +++ b/DesktopEditor/doctrenderer/embed/v8/v8_GraphicsEmbed.cpp @@ -111,6 +111,8 @@ namespace NSGraphicsEmbed FUNCTION_WRAPPER_V8_1(_DrawPath, DrawPath) FUNCTION_WRAPPER_V8_2(_CoordTransformOffset, CoordTransformOffset) FUNCTION_WRAPPER_V8_0(_GetTransform, GetTransform) + FUNCTION_WRAPPER_V8_1(_CreateLayer, CreateLayer) + FUNCTION_WRAPPER_V8_0(_BlendLayer, BlendLayer) v8::Handle<v8::ObjectTemplate> CreateTemplate(v8::Isolate* isolate) { @@ -221,6 +223,8 @@ namespace NSGraphicsEmbed NSV8Objects::Template_Set(result, "DrawPath", _DrawPath); NSV8Objects::Template_Set(result, "CoordTransformOffset", _CoordTransformOffset); NSV8Objects::Template_Set(result, "GetTransform", _GetTransform); + NSV8Objects::Template_Set(result, "CreateLayer", _CreateLayer); + NSV8Objects::Template_Set(result, "BlendLayer", _BlendLayer); return handle_scope.Escape(result); } diff --git a/DesktopEditor/doctrenderer/embed/v8/v8_ZipEmbed.cpp b/DesktopEditor/doctrenderer/embed/v8/v8_ZipEmbed.cpp index 7e6b00e67ee..ffedb7a4725 100644 --- a/DesktopEditor/doctrenderer/embed/v8/v8_ZipEmbed.cpp +++ b/DesktopEditor/doctrenderer/embed/v8/v8_ZipEmbed.cpp @@ -20,6 +20,7 @@ namespace NSZipEmbed FUNCTION_WRAPPER_V8_6(_encodeImageData, encodeImageData) FUNCTION_WRAPPER_V8_2(_encodeImage, encodeImage) FUNCTION_WRAPPER_V8_1(_getImageType, getImageType) + FUNCTION_WRAPPER_V8_1(_getImageBuffer, getImageBuffer) v8::Handle<v8::ObjectTemplate> CreateTemplate(v8::Isolate* isolate) { @@ -39,6 +40,7 @@ namespace NSZipEmbed NSV8Objects::Template_Set(result, "encodeImageData", _encodeImageData); NSV8Objects::Template_Set(result, "encodeImage", _encodeImage); NSV8Objects::Template_Set(result, "getImageType", _getImageType); + NSV8Objects::Template_Set(result, "getImageBuffer", _getImageBuffer); return handle_scope.Escape(result); } diff --git a/DesktopEditor/doctrenderer/graphics.cpp b/DesktopEditor/doctrenderer/graphics.cpp index 84bc587a59d..1df4b26bae8 100644 --- a/DesktopEditor/doctrenderer/graphics.cpp +++ b/DesktopEditor/doctrenderer/graphics.cpp @@ -1,5 +1,6 @@ #include "graphics.h" #include "../common/Base64.h" +#include "../raster/Metafile/MetaFileCommon.h" #include <string> #include <iostream> @@ -9,18 +10,35 @@ #define M_PI 3.14159265358979323846 #endif +#ifdef _DEBUG +//#define ENABLE_GR_LOGS +#endif + namespace NSGraphics { - void CGraphics::init(NSNativeControl::CNativeControl* oNative, double width_px, double height_px, double width_mm, double height_mm) + void CGraphics::init(double width_px, double height_px, double width_mm, double height_mm) { - m_sApplicationImagesDirectory = oNative->m_strImagesDirectory; - m_sApplicationFontsDirectory = oNative->m_strFontsDirectory; -#ifdef _DEBUG - std::wcout << L"init "<< m_sApplicationImagesDirectory << L" " << m_sApplicationFontsDirectory << L" " << width_px << L" " << height_px << L" " << width_mm << L" " << height_mm << std::endl; + if (!m_pAppImage) + return; + + if (NULL == m_pAppImage->GetFonts()) + { + NSFonts::IApplicationFonts* pFonts = NSFonts::NSApplication::Create(); + std::wstring sFontsDir = m_pAppImage->GetFontsDirectory(); + pFonts->InitializeFromFolder(sFontsDir.empty() ? NSFile::GetProcessDirectory() : sFontsDir); + m_pAppImage->SetFonts(pFonts); + RELEASEINTERFACE(pFonts); + } + + NSFonts::IFontManager* pManager = m_pAppImage->GetFonts()->GenerateFontManager(); + +#ifdef ENABLE_GR_LOGS + std::wcout << L"init "<< + m_pAppImage->GetImagesDirectory() << L" " << + m_pAppImage->GetFontsDirectory() << L" " << + width_px << L" " << height_px << L" " << + width_mm << L" " << height_mm << std::endl; #endif - m_pApplicationFonts = NSFonts::NSApplication::Create(); - m_pApplicationFonts->InitializeFromFolder(m_sApplicationFontsDirectory.empty() ? NSFile::GetProcessDirectory() : m_sApplicationFontsDirectory); - NSFonts::IFontManager* pManager = m_pApplicationFonts->GenerateFontManager(); m_pRenderer = NSGraphics::Create(); m_pRenderer->SetFontManager(pManager); @@ -41,7 +59,19 @@ namespace NSGraphics if (nRasterH < 1) nRasterH = 0; } - BYTE* pData = new BYTE[4 * nRasterW * nRasterH]; + int nExistW = 0; + int nExistH = 0; + BYTE* pData = m_pAppImage->GetBits(nExistW, nExistH); + if (pData != NULL) + { + nRasterW = nExistW; + nRasterH = nExistH; + } + else + { + pData = m_pAppImage->AllocBits(nRasterW, nRasterH); + } + unsigned int back = 0xffffff; unsigned int* pData32 = (unsigned int*)pData; unsigned int* pData32End = pData32 + nRasterW * nRasterH; @@ -54,21 +84,21 @@ namespace NSGraphics m_oFrame.put_Stride(4 * nRasterW); m_pRenderer->CreateFromBgraFrame(&m_oFrame); - m_pRenderer->SetSwapRGB(false); + m_pRenderer->SetSwapRGB(m_pAppImage->GetRgba()); m_pRenderer->put_Width(width_mm); m_pRenderer->put_Height(height_mm); } void CGraphics::put_GlobalAlpha(bool enable, double alpha) { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "put_GlobalAlpha " << enable << " " << alpha << std::endl; #endif m_pRenderer->put_GlobalAlphaEnabled(enable, alpha); } void CGraphics::End_GlobalAlpha() { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "End_GlobalAlpha " << std::endl; #endif bool bIsInteger = m_pRenderer->get_IntegerGrid(); @@ -85,7 +115,7 @@ namespace NSGraphics } void CGraphics::p_color(int r, int g, int b, int a) { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "p_color " << r << " " << g << " " << b << " " << a << std::endl; #endif m_pRenderer->put_PenColor(r | (g << 8) | (b << 16)); @@ -93,14 +123,14 @@ namespace NSGraphics } void CGraphics::p_width(double w) { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "p_width " << w << std::endl; #endif m_pRenderer->put_PenSize(w / 1000.0); } void CGraphics::p_dash(size_t length, double* dash) { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "p_dash " << length << std::endl; #endif if(length > 0) @@ -118,7 +148,7 @@ namespace NSGraphics } void CGraphics::b_color1(int r, int g, int b, int a) { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "b_color1 " << r << " " << g << " " << b << " " << a << std::endl; #endif m_pRenderer->put_BrushType(c_BrushTypeSolid); @@ -127,7 +157,7 @@ namespace NSGraphics } void CGraphics::b_color2(int r, int g, int b, int a) { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "b_color2 " << r << " " << g << " " << b << " " << a << std::endl; #endif m_pRenderer->put_BrushColor2(r | (g << 8) | (b << 16)); @@ -135,42 +165,42 @@ namespace NSGraphics } void CGraphics::transform(double sx, double shy, double shx, double sy, double tx, double ty) { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "transform " << sx << " " << shy << " " << shx << " " << sy << " " << tx << " " << ty << std::endl; #endif m_pRenderer->SetTransform(sx, shy, shx, sy, tx, ty); } void CGraphics::CalculateFullTransform() { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "CalculateFullTransform " << std::endl; #endif m_pRenderer->CalculateFullTransform(); } void CGraphics::_s() { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "_s " << std::endl; #endif m_pRenderer->PathCommandEnd(); } void CGraphics::_e() { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "_e " << std::endl; #endif m_pRenderer->PathCommandEnd(); } void CGraphics::_z() { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "_z " << std::endl; #endif m_pRenderer->PathCommandClose(); } void CGraphics::_m(double x, double y) { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "_m " << x << " " << y << std::endl; #endif if (!m_pRenderer->get_IntegerGrid()) @@ -183,7 +213,7 @@ namespace NSGraphics } void CGraphics::_l(double x, double y) { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "_l " << x << " " << y << std::endl; #endif if (!m_pRenderer->get_IntegerGrid()) @@ -196,7 +226,7 @@ namespace NSGraphics } void CGraphics::_c (double x1, double y1, double x2, double y2, double x3, double y3) { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "_c " << x1 << " " << y1 << " " << x2 << " " << y2 << " " << x3 << " " << y3 << std::endl; #endif if (!m_pRenderer->get_IntegerGrid()) @@ -211,7 +241,7 @@ namespace NSGraphics } void CGraphics::_c2(double x1, double y1, double x2, double y2) { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "_c2 " << x1 << " " << y1 << " " << x2 << " " << y2 << std::endl; #endif if (!m_pRenderer->get_IntegerGrid()) @@ -225,28 +255,28 @@ namespace NSGraphics } void CGraphics::ds() { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "ds " << std::endl; #endif m_pRenderer->Stroke(); } void CGraphics::df() { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "df " << std::endl; #endif m_pRenderer->Fill(); } void CGraphics::save() { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "save " << std::endl; #endif - m_oFrame.SaveFile(m_sApplicationImagesDirectory + L"/img.png", _CXIMAGE_FORMAT_PNG); + m_oFrame.SaveFile(m_pAppImage->GetImagesDirectory() + L"/img.png", _CXIMAGE_FORMAT_PNG); } void CGraphics::restore() { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "restore " << std::endl; #endif m_pRenderer->BeginCommand(c_nResetClipType); @@ -254,7 +284,7 @@ namespace NSGraphics } void CGraphics::clip() { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "clip " << std::endl; #endif m_pRenderer->BeginCommand(c_nClipType); @@ -262,43 +292,46 @@ namespace NSGraphics } void CGraphics::reset() { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "reset " << std::endl; #endif m_pRenderer->ResetTransform(); } void CGraphics::FreeFont() { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "FreeFont " << std::endl; #endif m_pRenderer->CloseFont(); } void CGraphics::ClearLastFont() { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "ClearLastFont " << std::endl; #endif m_pRenderer->ClearInstallFont(); } void CGraphics::drawImage(const std::wstring& img, double x, double y, double w, double h, BYTE alpha) { - std::wstring strImage = (0 == img.find(L"theme") ? m_sApplicationThemesDirectory : m_sApplicationImagesDirectory) + L'/' + img; -#ifdef _DEBUG + std::wstring strImage = img; + if (!NSFile::CFileBinary::Exists(img)) + strImage = (0 == img.find(L"theme") ? m_pAppImage->GetThemesDirectory() : m_pAppImage->GetImagesDirectory()) + L'/' + img; + +#ifdef ENABLE_GR_LOGS std::wcout << L"drawImage " << strImage << L" " << x << " " << y << L" " << w << L" " << h << L" " << alpha << std::endl; #endif m_pRenderer->DrawImageFromFile(strImage, x, y, w, h, alpha); } std::wstring CGraphics::GetFont() { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "GetFont " << std::endl; #endif return m_pRenderer->GetFontManager()->GetName(); } void CGraphics::SetFont(const std::wstring& name, int face, double size, int style) { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::wcout << L"SetFont " << name << L" " << face << L" " << size << L" " << style << std::endl; #endif double DpiX, DpiY; @@ -313,21 +346,21 @@ namespace NSGraphics } void CGraphics::FillText(double x, double y, int text) { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::wcout << L"FillText " << (wchar_t)text << L" " << x << L" " << y << std::endl; #endif m_pRenderer->CommandDrawTextCHAR(text, x, y, 0, 0); } void CGraphics::t(double x, double y, const std::wstring& text) { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::wcout << L"t " << text << L" " << x << L" " << y << std::endl; #endif m_pRenderer->CommandDrawText(text, x, y, 0, 0); } void CGraphics::tg(int text, double x, double y) { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::wcout << L"tg " << text << L" " << x << L" " << y << std::endl; #endif m_pRenderer->put_FontStringGID(TRUE); @@ -336,21 +369,21 @@ namespace NSGraphics } void CGraphics::SetIntegerGrid(bool param) { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "SetIntegerGrid " << param << std::endl; #endif m_pRenderer->put_IntegerGrid(param); } bool CGraphics::GetIntegerGrid() { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "GetIntegerGrid " << std::endl; #endif return m_pRenderer->get_IntegerGrid(); } void CGraphics::DrawStringASCII (const std::wstring& text, double x, double y) { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::wcout << L"DrawStringASCII " << text << L" " << x << L" " << y << std::endl; #endif double DpiY; @@ -372,7 +405,7 @@ namespace NSGraphics } void CGraphics::DrawHeaderEdit(double yPos) { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "DrawHeaderEdit " << std::endl; #endif m_pRenderer->PathCommandEnd(); @@ -415,7 +448,7 @@ namespace NSGraphics } void CGraphics::DrawFooterEdit(double yPos) { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "DrawFooterEdit " << std::endl; #endif m_pRenderer->PathCommandEnd(); @@ -458,7 +491,7 @@ namespace NSGraphics } void CGraphics::DrawLockParagraph (double x, double y1, double y2) { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "DrawLockParagraph " << std::endl; #endif m_pRenderer->PathCommandEnd(); @@ -530,7 +563,7 @@ namespace NSGraphics } void CGraphics::DrawLockObjectRect(double x, double y, double w, double h) { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "DrawLockObjectRect " << std::endl; #endif m_pRenderer->PathCommandEnd(); @@ -556,7 +589,7 @@ namespace NSGraphics } void CGraphics::DrawEmptyTableLine(double x1, double y1, double x2, double y2) { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "DrawEmptyTableLine " << std::endl; #endif m_pRenderer->PathCommandEnd(); @@ -641,7 +674,7 @@ namespace NSGraphics } void CGraphics::DrawSpellingLine (double y0, double x0, double x1, double w) { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "DrawSpellingLine " << std::endl; #endif Aggplus::CMatrix* pMatrix = m_pRenderer->GetTransformMatrix(); @@ -987,7 +1020,7 @@ namespace NSGraphics } void CGraphics::SaveGrState() { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "SaveGrState " << std::endl; #endif CGrStateState* pState = new CGrStateState(); @@ -1003,7 +1036,7 @@ namespace NSGraphics } void CGraphics::RestoreGrState() { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "RestoreGrState " << std::endl; #endif if (m_oGrState.States.empty()) @@ -1067,14 +1100,14 @@ namespace NSGraphics } void CGraphics::StartClipPath() { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "StartClipPath " << std::endl; #endif m_pRenderer->BeginCommand(c_nClipType); } void CGraphics::EndClipPath() { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "EndClipPath " << std::endl; #endif m_pRenderer->EndCommand(c_nClipType); @@ -1132,28 +1165,30 @@ namespace NSGraphics } std::string CGraphics::toDataURL(std::wstring type) { - std::wstring sPath = NSFile::CFileBinary::CreateTempFileWithUniqueName(m_sApplicationImagesDirectory, L"img"); -#ifdef _DEBUG - std::wcout << "toDataURL " << sPath << std::endl; +#ifdef ENABLE_GR_LOGS + std::wcout << "toDataURL " << type << std::endl; #endif - m_oFrame.SaveFile(sPath, _CXIMAGE_FORMAT_PNG); + std::wstring sFormat = (type.length() > 6) ? type.substr(6) : type; - NSFile::CFileBinary oReader; - if (oReader.OpenFile(sPath)) + BYTE* pDataImage = NULL; + int nDataImageSize = 0; + int nImageFormat = _CXIMAGE_FORMAT_PNG; + if ((L"jpg" == sFormat) ||(L"jpeg" == sFormat)) + nImageFormat = _CXIMAGE_FORMAT_JPG; + + std::string sRes = ""; + if (m_oFrame.Encode(pDataImage, nDataImageSize, nImageFormat)) { - DWORD dwFileSize = oReader.GetFileSize(); - BYTE* pFileContent = new BYTE[dwFileSize]; - DWORD dwReaded; - oReader.ReadFile(pFileContent, dwFileSize, dwReaded); - oReader.CloseFile(); - - NSFile::CFileBinary::Remove(sPath); - int nEncodeLen = NSBase64::Base64EncodeGetRequiredLength(dwFileSize); - BYTE* pImageData = new BYTE[nEncodeLen]; - if (TRUE == NSBase64::Base64Encode(pFileContent, dwFileSize, pImageData, &nEncodeLen)) - return "data:" + U_TO_UTF8(type) + ";base64, " + std::string((char*)pImageData, nEncodeLen); + char* cData64 = NULL; + int nData64Dst = 0; + if (NSFile::CBase64Converter::Encode(pDataImage, nDataImageSize, cData64, nData64Dst, NSBase64::B64_BASE64_FLAG_NOCRLF)) + { + sRes = ("data:" + U_TO_UTF8(type) + ";base64," + std::string(cData64, nData64Dst)); + } + RELEASEARRAYOBJECTS(cData64); } - return ""; + RELEASEARRAYOBJECTS(pDataImage); + return sRes; } CColor CGraphics::GetPenColor() { @@ -1175,11 +1210,11 @@ namespace NSGraphics { if (src.find(L"data:") == 0) { - std::wstring strImage = m_sApplicationImagesDirectory + L"/texture.png"; + std::wstring strImage = m_pAppImage->GetImagesDirectory() + L"/texture.png"; bool bIsOnlyOfficeHatch = false; if(src.find(L"onlyoffice_hatch") != std::wstring::npos) bIsOnlyOfficeHatch = true; -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::wcout << L"put_brushTexture " << src << L" " << type << std::endl; #endif src.erase(0, src.find(L',') + 1); @@ -1218,7 +1253,10 @@ namespace NSGraphics } else { - std::wstring strImage = (0 == src.find(L"theme") ? m_sApplicationThemesDirectory : m_sApplicationImagesDirectory) + L'/' + src; + std::wstring strImage = src; + if (!NSFile::CFileBinary::Exists(src)) + strImage = (0 == src.find(L"theme") ? m_pAppImage->GetThemesDirectory() : m_pAppImage->GetImagesDirectory()) + L'/' + src; + std::wstring sName = strImage.substr(0, strImage.rfind(L'.') + 1); std::wstring sExt = src.substr(src.rfind(L'.') + 1); if (sExt == L"svg") @@ -1228,20 +1266,20 @@ namespace NSGraphics else if (NSFile::CFileBinary::Exists(sName + L"emf") && src.find(L"display") == 0) strImage = sName + L"emf"; - MetaFile::IMetaFile* pMetafile = MetaFile::Create(m_pApplicationFonts); + MetaFile::IMetaFile* pMetafile = MetaFile::Create(m_pAppImage->GetFonts()); pMetafile->LoadFromFile(strImage.c_str()); double x = 0, y = 0, w = 0, h = 0; pMetafile->GetBounds(&x, &y, &w, &h); sName += L"png"; - pMetafile->ConvertToRaster(sName.c_str(), 4, 1000); + MetaFile::ConvertToRasterMaxSize(pMetafile, sName.c_str(), 4, 1000); RELEASEOBJECT(pMetafile); } else sName += sExt; -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::wcout << L"put_brushTexture " << sName << L" " << type << std::endl; #endif m_pRenderer->put_BrushType(c_BrushTypeTexture); @@ -1251,21 +1289,21 @@ namespace NSGraphics } void CGraphics::put_brushTextureMode(int mode) { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "put_brushTextureMode " << mode << std::endl; #endif m_pRenderer->put_BrushTextureMode(mode); } void CGraphics::put_BrushTextureAlpha(int a) { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "put_BrushTextureAlpha " << a << std::endl; #endif m_pRenderer->put_BrushTextureAlpha(a == 0 ? 255 : a); } void CGraphics::put_BrushGradient(LONG* pColors, double* pPositions, size_t nCount, double x0, double y0, double x1, double y1, double r0, double r1) { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "put_BrushGradient " << nCount << " " << x0 << " " << y0 << " " << x1 << " " << y1 << " " << r0 << " " << r1 << std::endl; for (size_t i = 0; i < nCount; i++) std::cout << pPositions[i] << " " << pColors[i] << " "; @@ -1290,7 +1328,7 @@ namespace NSGraphics } double CGraphics::TransformPointX(double x, double y) { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "TransformPointX " << std::endl; #endif m_pRenderer->GetFullTransform()->TransformPoint(x, y); @@ -1298,7 +1336,7 @@ namespace NSGraphics } double CGraphics::TransformPointY(double x, double y) { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "TransformPointY " << std::endl; #endif m_pRenderer->GetFullTransform()->TransformPoint(x, y); @@ -1306,14 +1344,14 @@ namespace NSGraphics } void CGraphics::put_LineJoin(int nJoin) { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "put_LineJoin " << std::endl; #endif m_pRenderer->put_PenLineJoin(nJoin); } int CGraphics::GetLineJoin() { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "GetLineJoin " << std::endl; #endif BYTE nRes; @@ -1322,7 +1360,7 @@ namespace NSGraphics } void CGraphics::put_TextureBounds(double x, double y, double w, double h) { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "put_TextureBounds " << x << " " << y << " " << w << " " << h << std::endl; #endif if(m_pRenderer->get_IntegerGrid()) @@ -1338,7 +1376,7 @@ namespace NSGraphics } double CGraphics::GetlineWidth() { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "GetlineWidth " << std::endl; #endif double nRes; @@ -1347,7 +1385,7 @@ namespace NSGraphics } void CGraphics::DrawPath(int path) { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "DrawPath " << path << std::endl; #endif if(path == 257) @@ -1360,7 +1398,7 @@ namespace NSGraphics } void CGraphics::CoordTransformOffset(double tx, double ty) { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "CoordTransformOffset " << tx << " " << ty << std::endl; #endif m_pRenderer->SetCoordTransformOffset(tx, ty); @@ -1371,4 +1409,14 @@ namespace NSGraphics m_pRenderer->GetTransform(&oRes.sx, &oRes.shy, &oRes.shx, &oRes.sy, &oRes.tx, &oRes.ty); return oRes; } + + void CGraphics::CreateLayer(double opacity) + { + m_pRenderer->BeginCommand(c_nLayerType); + m_pRenderer->put_LayerOpacity(opacity); + } + void CGraphics::BlendLayer() + { + m_pRenderer->EndCommand(c_nLayerType); + } } diff --git a/DesktopEditor/doctrenderer/graphics.h b/DesktopEditor/doctrenderer/graphics.h index 2b8a45b1c7c..8146c45a087 100644 --- a/DesktopEditor/doctrenderer/graphics.h +++ b/DesktopEditor/doctrenderer/graphics.h @@ -7,6 +7,7 @@ #include "../common/File.h" #include "nativecontrol.h" #include "../graphics/pro/Graphics.h" +#include "embed/GraphicsEmbed.h" namespace NSGraphics { @@ -114,28 +115,32 @@ namespace NSGraphics class CGraphics { public: - std::wstring m_sApplicationFontsDirectory; - std::wstring m_sApplicationImagesDirectory; - std::wstring m_sApplicationThemesDirectory; + CGraphicsAppImage* m_pAppImage; + CBgraFrame m_oFrame; private: - NSFonts ::IApplicationFonts* m_pApplicationFonts; NSGraphics::IGraphicsRenderer* m_pRenderer; - CBgraFrame m_oFrame; CGrState m_oGrState; public: - CGraphics() {} + CGraphics() + { + m_pAppImage = NULL; + } ~CGraphics() { Destroy(); } - void init(NSNativeControl::CNativeControl* oNative, double width_px, double height_px, double width_mm, double height_mm); + void init(double width_px, double height_px, double width_mm, double height_mm); void Destroy() { + int w, h; + if (m_pAppImage && m_pAppImage->GetBits(w, h)) + m_oFrame.put_Data(NULL); + RELEASEINTERFACE(m_pRenderer); - RELEASEINTERFACE(m_pApplicationFonts); + RELEASEOBJECT(m_pAppImage); } void EndDraw() {} void put_GlobalAlpha(bool enable, double globalAlpha); @@ -235,6 +240,10 @@ namespace NSGraphics void DrawPath(int path); void CoordTransformOffset(double tx, double ty); CTransform GetTransform(); + + // layer + void CreateLayer(double opacity); + void BlendLayer(); }; } diff --git a/DesktopEditor/doctrenderer/js_internal/js_base.cpp b/DesktopEditor/doctrenderer/js_internal/js_base.cpp index 4f275ae2d2f..7df327b7038 100644 --- a/DesktopEditor/doctrenderer/js_internal/js_base.cpp +++ b/DesktopEditor/doctrenderer/js_internal/js_base.cpp @@ -65,14 +65,9 @@ namespace NSJSBase { { } - void CJSObject::set(const char* name, JSSmart<CJSValue> value) - { - this->set(name, value.GetPointer()); - } void CJSObject::set(const char* name, JSSmart<CJSObject> obj) { - JSSmart<CJSValue> value = obj->toValue(); - this->set(name, value.GetPointer()); + this->set(name, obj->toValue()); } CJSArray::CJSArray() diff --git a/DesktopEditor/doctrenderer/js_internal/js_base.h b/DesktopEditor/doctrenderer/js_internal/js_base.h index 319308308d1..ffa1c7a7f0c 100644 --- a/DesktopEditor/doctrenderer/js_internal/js_base.h +++ b/DesktopEditor/doctrenderer/js_internal/js_base.h @@ -215,19 +215,22 @@ namespace NSJSBase * Returns specified property of the object. * @param name The name of a property. */ - virtual JSSmart<CJSValue> get(const char* name) = 0; + virtual JSSmart<CJSValue> get(const char* name) = 0; /** * Sets a property of the object. * @param name The name of a property. * @param value The value of a property. */ - virtual void set(const char* name, CJSValue* value) = 0; + virtual void set(const char* name, JSSmart<CJSValue> value) = 0; virtual void set(const char* name, const int& value) = 0; virtual void set(const char* name, const double& value) = 0; - // Common funcs - void set(const char* name, JSSmart<CJSValue> value); + // Common function void set(const char* name, JSSmart<CJSObject> value); + /** + * Returns a vector containing the names of the properties of this object as strings, including properties from prototype objects. + */ + virtual std::vector<std::string> getPropertyNames() = 0; /** * Returns a pointer to the native embedded object. */ @@ -269,8 +272,7 @@ namespace NSJSBase * @param index The index of the array value. * @param value The array value to be set. */ - virtual void set(const int& index, CJSValue* value) = 0; - virtual void set(const int& index, const bool& value) = 0; + virtual void set(const int& index, JSSmart<CJSValue> value) = 0; virtual void set(const int& index, const int& value) = 0; virtual void set(const int& index, const double& value) = 0; @@ -278,7 +280,7 @@ namespace NSJSBase * Add the specified value to the array. * @param value The value to be added. */ - virtual void add(CJSValue* value) = 0; + virtual void add(JSSmart<CJSValue> value) = 0; /** * Add null to the array. */ @@ -384,6 +386,14 @@ namespace NSJSBase * Converts the typed array to a value. */ virtual JSSmart<CJSValue> toValue() = 0; + + /** + * Detaches this ArrayBuffer and all its views (typed arrays). + * Detaching sets the byte length of the buffer and all typed arrays to zero, + * preventing JavaScript from ever accessing underlying backing store. + * ArrayBuffer should have been externalized. + */ + virtual void Detach() = 0; }; /** @@ -438,14 +448,21 @@ namespace NSJSBase /** * Initializes the JS context. * By default it happens automatically when creating a CJSConext instance. + * @param snapshotPath Path to snapshot file. */ - void Initialize(); + void Initialize(const std::wstring& snapshotPath = L""); /** * Releases any resources taken by the JS context. * Generally there is no need to call it manually, cause this method called when CJSConext is being destructed. */ void Dispose(); + /** + * Get information about snapshot + * @return Returns true if snapshot was used on Initialize method + */ + bool isSnapshotUsed(); + /** * Creates and returns the pointer to an object for tracking exceptions during code execution in current JS context. */ @@ -478,6 +495,14 @@ namespace NSJSBase AddEmbedCreator(T::getName(), T::getCreator, isAllowedInJS); } + /** + * Generate snapshot by script. + * @param script The script to be executed. + * @param snapshotPath The path to the snapshot + * @return Returns true whether a snapshot has been created. + */ + static bool generateSnapshot(const std::string& script, const std::wstring& snapshotPath); + /** * Run the script in the current JS context. * @param script The script to be executed. @@ -493,6 +518,12 @@ namespace NSJSBase * @return The pointer to resulted JS value after parsing. */ JSSmart<CJSValue> JSON_Parse(const char* json_content); + /** + * Creates a string that contains the JSON-serialized representation of a JS value. + * @param value The JS value to serialize. + * @return The string that contains the result of serialization, or empty string in case of errors. + */ + std::string JSON_Stringify(JSSmart<CJSValue> value); /** * Do not use this function. It is for internal needs. * Associates current context with the specifed thread id. @@ -673,7 +704,7 @@ namespace NSJSBase * * NOTE: If you don't want to export certain functions from your embedded class for some reason, * then add the inline comment "[noexport]" at the start of a function declaration. - * Also you can use `#ifdef ... #endif` blocks (see doctrenderer/test/internal/Embed.h for an example). + * Also you can use `#ifdef ... #endif` blocks (see doctrenderer/test/embed/external/Embed.h for an example). */ #endif // _CORE_EXT_JS_BASE_H_ diff --git a/DesktopEditor/doctrenderer/js_internal/jsc/jsc_base.h b/DesktopEditor/doctrenderer/js_internal/jsc/jsc_base.h index 1a82a4e0b18..0093c002956 100644 --- a/DesktopEditor/doctrenderer/js_internal/jsc/jsc_base.h +++ b/DesktopEditor/doctrenderer/js_internal/jsc/jsc_base.h @@ -12,25 +12,25 @@ namespace NSJSBase { - class CJSContextPrivate - { - public: - JSContext* context; - std::vector<ASC_THREAD_ID> m_arThreads; - - public: - CJSContextPrivate() - { - context = nil; - } - ~CJSContextPrivate() - { - context = nil; - } - - static JSContext* GetCurrentContext(); - static bool IsOldVersion(); - }; + class CJSContextPrivate + { + public: + JSContext* context; + std::vector<ASC_THREAD_ID> m_arThreads; + + public: + CJSContextPrivate() + { + context = nil; + } + ~CJSContextPrivate() + { + context = nil; + } + + static JSContext* GetCurrentContext(); + static bool IsOldVersion(); + }; // embed id CreateEmbedNativeObject(NSString* name); @@ -38,495 +38,506 @@ namespace NSJSBase namespace NSJSBase { - template<typename T> - class CJSValueJSCTemplate : public T - { - public: - JSValue* value; - - CJSValueJSCTemplate() - { - value = nil; - } - CJSValueJSCTemplate(JSValue* _value) - { - value = _value; - } - - public: - - virtual ~CJSValueJSCTemplate() - { - value = nil; - } - - virtual bool isUndefined(); - virtual bool isNull(); - virtual bool isBool(); - virtual bool isNumber(); - virtual bool isString(); - virtual bool isArray(); - virtual bool isTypedArray(); - virtual bool isObject(); - virtual bool isFunction(); - virtual bool isEmpty(); - - virtual void doUndefined(); - virtual void doNull(); - virtual bool toBool(); - virtual int toInt32(); - virtual unsigned int toUInt32(); - virtual double toDouble(); - virtual std::string toStringA(); - virtual std::wstring toStringW(); + template <typename T> + class CJSValueJSCTemplate : public T + { + public: + JSValue* value; + + CJSValueJSCTemplate() + { + value = nil; + } + CJSValueJSCTemplate(JSValue* _value) + { + value = _value; + } + + public: + virtual ~CJSValueJSCTemplate() + { + value = nil; + } + + virtual bool isUndefined(); + virtual bool isNull(); + virtual bool isBool(); + virtual bool isNumber(); + virtual bool isString(); + virtual bool isArray(); + virtual bool isTypedArray(); + virtual bool isObject(); + virtual bool isFunction(); + virtual bool isEmpty(); + + virtual void doUndefined(); + virtual void doNull(); + virtual bool toBool(); + virtual int toInt32(); + virtual unsigned int toUInt32(); + virtual double toDouble(); + virtual std::string toStringA(); + virtual std::wstring toStringW(); virtual JSSmart<CJSObject> toObject(); virtual JSSmart<CJSArray> toArray(); virtual JSSmart<CJSTypedArray> toTypedArray(); virtual JSSmart<CJSFunction> toFunction(); - JSContext* getContext() - { - if (nil == value || nil == value.context) - return CJSContextPrivate::GetCurrentContext(); - return value.context; - } - }; - - typedef CJSValueJSCTemplate<CJSValue> CJSValueJSC; - - class CJSObjectJSC : public CJSValueJSCTemplate<CJSObject> - { - public: - CJSObjectJSC() - { - } - CJSObjectJSC(JSValue* _value) : CJSValueJSCTemplate<CJSObject>(_value) - { - } - - virtual ~CJSObjectJSC() - { - value = nil; - } + JSContext* getContext() + { + if (nil == value || nil == value.context) + return CJSContextPrivate::GetCurrentContext(); + return value.context; + } + }; + + typedef CJSValueJSCTemplate<CJSValue> CJSValueJSC; + + class CJSObjectJSC : public CJSValueJSCTemplate<CJSObject> + { + public: + CJSObjectJSC() + { + } + CJSObjectJSC(JSValue* _value) : CJSValueJSCTemplate<CJSObject>(_value) + { + } + + virtual ~CJSObjectJSC() + { + value = nil; + } virtual JSSmart<CJSValue> get(const char* name) - { - CJSValueJSC* _value = new CJSValueJSC(); - _value->value = [value valueForProperty:[[NSString alloc] initWithUTF8String:name]]; - return _value; - } - - virtual void set(const char* name, CJSValue* value_param) - { - CJSValueJSC* _value = static_cast<CJSValueJSC*>(value_param); - [value setValue:_value->value forProperty:[[NSString alloc] initWithUTF8String:name]]; - } - - virtual void set(const char* name, const int& _value) - { - [value setValue:[JSValue valueWithInt32:_value inContext: getContext()] forProperty:[[NSString alloc] initWithUTF8String:name]]; - } - - virtual void set(const char* name, const double& _value) - { - [value setValue:[JSValue valueWithDouble:_value inContext: getContext()] forProperty:[[NSString alloc] initWithUTF8String:name]]; - } - - virtual CJSEmbedObject* getNative() - { - id _wrapper = [value toObject]; - if ([_wrapper conformsToProtocol:@protocol(JSEmbedObjectProtocol)]) - { - return (CJSEmbedObject*)([_wrapper getNative]); - } - return NULL; - } - - virtual JSSmart<CJSValue> call_func(const char* name, const int argc = 0, JSSmart<CJSValue> argv[] = NULL) - { - NSMutableArray* arr = nil; - - if (argc > 0) - { - arr = [[NSMutableArray alloc] init]; - for (int i = 0; i < argc; ++i) - { - CJSValueJSC* _val = (CJSValueJSC*)argv[i].operator ->(); - [arr addObject:_val->value]; - } - } - - CJSValueJSC* _return = new CJSValueJSC(); - _return->value = [value invokeMethod: [[NSString alloc] initWithUTF8String:name] - withArguments: arr]; - - return _return; - } - - virtual JSSmart<CJSValue> toValue() - { - CJSValueJSC* _value = new CJSValueJSC(); - _value->value = value; - //_value->value = [JSValue valueWithJSValueRef:[value JSValueRef] inContext:context]; - return _value; - } - }; - - class CJSArrayJSC : public CJSValueJSCTemplate<CJSArray> - { - public: - int m_count; - public: - CJSArrayJSC() - { - m_count = 0; - } - virtual ~CJSArrayJSC() - { - value = nil; - } - - virtual int getCount() - { - int nCount = 0; - JSValue* _ret = [value valueForProperty:@"length"]; - if (nil != _ret && NO == [_ret isUndefined]) - nCount = [_ret toInt32]; - _ret = nil; - return nCount; - } - - virtual JSSmart<CJSValue> get(const int& index) - { - CJSValueJSC* _value = new CJSValueJSC(); - _value->value = [value valueAtIndex:(NSUInteger)index]; - return _value; - } - - virtual void set(const int& index, CJSValue* value_param) - { - CJSValueJSC* _value = static_cast<CJSValueJSC*>(value_param); - [value setValue:_value->value atIndex:index]; - } - - virtual void add(CJSValue* value_param) - { - set(getCount(), value_param); - } - - virtual void set(const int& index, const bool& _value) - { - [value setValue:[JSValue valueWithBool:_value inContext : getContext()] atIndex:index]; - } - - virtual void set(const int& index, const int& _value) - { - [value setValue:[JSValue valueWithInt32:_value inContext : getContext()] atIndex:index]; - } - - virtual void set(const int& index, const double& _value) - { - [value setValue:[JSValue valueWithDouble:_value inContext : getContext()] atIndex:index]; - } - - virtual void add_null() - { - [value setValue:[JSValue valueWithNullInContext:getContext()] atIndex:m_count++]; - } - - virtual void add_undefined() - { - [value setValue:nil atIndex:m_count++]; - } - - virtual void add_bool(const bool& _value) - { - [value setValue:[JSValue valueWithBool:_value inContext : getContext()] atIndex:m_count++]; - } - - virtual void add_byte(const BYTE& _value) - { - [value setValue:[JSValue valueWithInt32:(int)_value inContext : getContext()] atIndex:m_count++]; - } - - virtual void add_int(const int& _value) - { - [value setValue:[JSValue valueWithInt32:_value inContext : getContext()] atIndex:m_count++]; - } - - virtual void add_double(const double& _value) - { - [value setValue:[JSValue valueWithDouble:_value inContext : getContext()] atIndex:m_count++]; - } - - virtual void add_stringa(const std::string& _value) - { - [value setValue:[NSString stringWithAString:_value] atIndex:m_count++]; - } - - virtual void add_string(const std::wstring& _value) - { - [value setValue:[NSString stringWithWString:_value] atIndex:m_count++]; - } - - virtual JSSmart<CJSValue> toValue() - { - CJSValueJSC* _value = new CJSValueJSC(); - _value->value = value; - return _value; - } - }; - - class CJSTypedArrayJSC : public CJSValueJSCTemplate<CJSTypedArray> - { - public: - CJSTypedArrayJSC(JSContext* _context, BYTE* data = NULL, int count = 0, const bool& isExternalize = true) - { - if (0 >= count) - return; - - if (!CJSContextPrivate::IsOldVersion()) - { - JSObjectRef object = JSObjectMakeTypedArrayWithBytesNoCopy(_context.JSGlobalContextRef, - kJSTypedArrayTypeUint8Array, - (void*)data, (size_t)count, - isExternalize ? data_no_destroy_memory : data_destroy_memory, - nullptr, nullptr); - if (object) - { - value = [JSValue valueWithJSValueRef:object inContext:_context]; - } - } - else - { - char* pDst = NULL; - int nDstLen = 0; - NSFile::CBase64Converter::Encode(data, count, pDst, nDstLen, NSBase64::B64_BASE64_FLAG_NOCRLF); - - std::string sCode = "jsc_fromBase64(\"" + std::string(pDst, nDstLen) + "\", " + std::to_string(count) + ");"; - RELEASEARRAYOBJECTS(pDst); - value = [_context evaluateScript:[NSString stringWithAString:sCode]]; - } - } - virtual ~CJSTypedArrayJSC() - { - value = nil; - } - - static void data_destroy_memory(void* bytes, void* deallocatorContext) - { - NSJSBase::NSAllocator::Free((unsigned char*)bytes, 0); - } - static void data_no_destroy_memory(void* bytes, void* deallocatorContext) - { - } - - virtual int getCount() - { - if (nil == value) - return 0; - JSContext* context = getContext(); - if (!CJSContextPrivate::IsOldVersion()) - { - JSObjectRef obj = JSValueToObject(context.JSGlobalContextRef, value.JSValueRef, NULL); - return (int)JSObjectGetTypedArrayByteLength(context.JSGlobalContextRef, obj, NULL); - } - int nCount = 0; - JSValue* _ret = [value valueForProperty:@"length"]; - if (nil != _ret && NO == [_ret isUndefined]) - nCount = [_ret toInt32]; - _ret = nil; - return nCount; - } - - virtual CJSDataBuffer getData() - { - JSContext* context = getContext(); - CJSDataBuffer buffer; - if (!CJSContextPrivate::IsOldVersion()) - { - JSObjectRef obj = JSValueToObject(context.JSGlobalContextRef, value.JSValueRef, NULL); - buffer.IsExternalize = false; - buffer.Data = (BYTE*)JSObjectGetTypedArrayBytesPtr(context.JSGlobalContextRef, obj, NULL); - buffer.Len = (size_t)JSObjectGetTypedArrayByteLength(context.JSGlobalContextRef, obj, NULL); - return buffer; - } - - NSMutableArray* arr = [[NSMutableArray alloc] init]; - [arr addObject:value]; - - JSValue* dataBase64 = [context[@"jsc_toBase64"] callWithArguments:arr]; - std::string sBase64Data = [[dataBase64 toString] stdstring]; - dataBase64 = nil; - - buffer.IsExternalize = true; - - int nLenDst = NSBase64::Base64DecodeGetRequiredLength((int)sBase64Data.length()); - buffer.Data = NSAllocator::Alloc(nLenDst); - - if (FALSE == NSBase64::Base64Decode(sBase64Data.c_str(), (int)sBase64Data.length(), buffer.Data, &nLenDst)) - { - buffer.Free(); - return buffer; - } - return buffer; - } - - virtual JSSmart<CJSValue> toValue() - { - CJSValueJSC* _value = new CJSValueJSC(); - _value->value = value; - return _value; - } - }; - - class CJSFunctionJSC : public CJSValueJSCTemplate<CJSFunction> - { - public: - CJSFunctionJSC() - { - } - virtual ~CJSFunctionJSC() - { - value = nil; - } + { + CJSValueJSC* _value = new CJSValueJSC(); + _value->value = [value valueForProperty:[[NSString alloc] initWithUTF8String:name]]; + return _value; + } + + virtual void set(const char* name, JSSmart<CJSValue> value_param) + { + CJSValueJSC* _value = static_cast<CJSValueJSC*>(value_param.GetPointer()); + [value setValue:_value->value forProperty:[[NSString alloc] initWithUTF8String:name]]; + } + + virtual void set(const char* name, const int& _value) + { + [value setValue:[JSValue valueWithInt32:_value inContext:getContext()] forProperty:[[NSString alloc] initWithUTF8String:name]]; + } + + virtual void set(const char* name, const double& _value) + { + [value setValue:[JSValue valueWithDouble:_value inContext:getContext()] forProperty:[[NSString alloc] initWithUTF8String:name]]; + } + + virtual std::vector<std::string> getPropertyNames() + { + NSArray* names = [[value toObject] allKeys]; + uint32_t len = [names count]; + + std::vector<std::string> ret(len); + for (uint32_t i = 0; i < len; i++) + { + NSString* name = [names objectAtIndex:i]; + ret[i] = [name stdstring]; + } + + return ret; + } + + virtual CJSEmbedObject* getNative() + { + id _wrapper = [value toObject]; + if ([_wrapper conformsToProtocol:@protocol(JSEmbedObjectProtocol)]) + { + return (CJSEmbedObject*)([_wrapper getNative]); + } + return NULL; + } + + virtual JSSmart<CJSValue> call_func(const char* name, const int argc = 0, JSSmart<CJSValue> argv[] = NULL) + { + NSMutableArray* arr = nil; + + if (argc > 0) + { + arr = [[NSMutableArray alloc] init]; + for (int i = 0; i < argc; ++i) + { + CJSValueJSC* _val = (CJSValueJSC*)argv[i].operator->(); + [arr addObject:_val->value]; + } + } + + CJSValueJSC* _return = new CJSValueJSC(); + _return->value = [value invokeMethod:[[NSString alloc] initWithUTF8String:name] withArguments:arr]; + + return _return; + } + + virtual JSSmart<CJSValue> toValue() + { + CJSValueJSC* _value = new CJSValueJSC(); + _value->value = value; + //_value->value = [JSValue valueWithJSValueRef:[value JSValueRef] inContext:context]; + return _value; + } + }; + + class CJSArrayJSC : public CJSValueJSCTemplate<CJSArray> + { + public: + int m_count; + + public: + CJSArrayJSC() + { + m_count = 0; + } + virtual ~CJSArrayJSC() + { + value = nil; + } + + virtual int getCount() + { + int nCount = 0; + JSValue* _ret = [value valueForProperty:@"length"]; + if (nil != _ret && NO == [_ret isUndefined]) + nCount = [_ret toInt32]; + _ret = nil; + return nCount; + } + + virtual JSSmart<CJSValue> get(const int& index) + { + CJSValueJSC* _value = new CJSValueJSC(); + _value->value = [value valueAtIndex:(NSUInteger)index]; + return _value; + } + + virtual void set(const int& index, JSSmart<CJSValue> value_param) + { + CJSValueJSC* _value = static_cast<CJSValueJSC*>(value_param.GetPointer()); + [value setValue:_value->value atIndex:index]; + } + + virtual void add(JSSmart<CJSValue> value_param) + { + set(getCount(), value_param); + } + + virtual void set(const int& index, const int& _value) + { + [value setValue:[JSValue valueWithInt32:_value inContext:getContext()] atIndex:index]; + } + + virtual void set(const int& index, const double& _value) + { + [value setValue:[JSValue valueWithDouble:_value inContext:getContext()] atIndex:index]; + } + + virtual void add_null() + { + [value setValue:[JSValue valueWithNullInContext:getContext()] atIndex:m_count++]; + } + + virtual void add_undefined() + { + [value setValue:nil atIndex:m_count++]; + } + + virtual void add_bool(const bool& _value) + { + [value setValue:[JSValue valueWithBool:_value inContext:getContext()] atIndex:m_count++]; + } + + virtual void add_byte(const BYTE& _value) + { + [value setValue:[JSValue valueWithInt32:(int)_value inContext:getContext()] atIndex:m_count++]; + } + + virtual void add_int(const int& _value) + { + [value setValue:[JSValue valueWithInt32:_value inContext:getContext()] atIndex:m_count++]; + } + + virtual void add_double(const double& _value) + { + [value setValue:[JSValue valueWithDouble:_value inContext:getContext()] atIndex:m_count++]; + } + + virtual void add_stringa(const std::string& _value) + { + [value setValue:[NSString stringWithAString:_value] atIndex:m_count++]; + } + + virtual void add_string(const std::wstring& _value) + { + [value setValue:[NSString stringWithWString:_value] atIndex:m_count++]; + } + + virtual JSSmart<CJSValue> toValue() + { + CJSValueJSC* _value = new CJSValueJSC(); + _value->value = value; + return _value; + } + }; + + class CJSTypedArrayJSC : public CJSValueJSCTemplate<CJSTypedArray> + { + public: + CJSTypedArrayJSC(JSContext* _context, BYTE* data = NULL, int count = 0, const bool& isExternalize = true) + { + if (0 >= count) + return; + + if (!CJSContextPrivate::IsOldVersion()) + { + JSObjectRef object = JSObjectMakeTypedArrayWithBytesNoCopy( + _context.JSGlobalContextRef, kJSTypedArrayTypeUint8Array, (void*)data, (size_t)count, isExternalize ? data_no_destroy_memory : data_destroy_memory, nullptr, nullptr); + if (object) + { + value = [JSValue valueWithJSValueRef:object inContext:_context]; + } + } + else + { + char* pDst = NULL; + int nDstLen = 0; + NSFile::CBase64Converter::Encode(data, count, pDst, nDstLen, NSBase64::B64_BASE64_FLAG_NOCRLF); + + std::string sCode = "jsc_fromBase64(\"" + std::string(pDst, nDstLen) + "\", " + std::to_string(count) + ");"; + RELEASEARRAYOBJECTS(pDst); + value = [_context evaluateScript:[NSString stringWithAString:sCode]]; + } + } + virtual ~CJSTypedArrayJSC() + { + value = nil; + } + + static void data_destroy_memory(void* bytes, void* deallocatorContext) + { + NSJSBase::NSAllocator::Free((unsigned char*)bytes, 0); + } + static void data_no_destroy_memory(void* bytes, void* deallocatorContext) + { + } + + virtual int getCount() + { + if (nil == value) + return 0; + JSContext* context = getContext(); + if (!CJSContextPrivate::IsOldVersion()) + { + JSObjectRef obj = JSValueToObject(context.JSGlobalContextRef, value.JSValueRef, NULL); + return (int)JSObjectGetTypedArrayByteLength(context.JSGlobalContextRef, obj, NULL); + } + int nCount = 0; + JSValue* _ret = [value valueForProperty:@"length"]; + if (nil != _ret && NO == [_ret isUndefined]) + nCount = [_ret toInt32]; + _ret = nil; + return nCount; + } + + virtual CJSDataBuffer getData() + { + JSContext* context = getContext(); + CJSDataBuffer buffer; + if (!CJSContextPrivate::IsOldVersion()) + { + JSObjectRef obj = JSValueToObject(context.JSGlobalContextRef, value.JSValueRef, NULL); + buffer.IsExternalize = false; + buffer.Data = (BYTE*)JSObjectGetTypedArrayBytesPtr(context.JSGlobalContextRef, obj, NULL); + buffer.Len = (size_t)JSObjectGetTypedArrayByteLength(context.JSGlobalContextRef, obj, NULL); + return buffer; + } + + NSMutableArray* arr = [[NSMutableArray alloc] init]; + [arr addObject:value]; + + JSValue* dataBase64 = [context[@"jsc_toBase64"] callWithArguments:arr]; + std::string sBase64Data = [[dataBase64 toString] stdstring]; + dataBase64 = nil; + + buffer.IsExternalize = true; + + int nLenDst = NSBase64::Base64DecodeGetRequiredLength((int)sBase64Data.length()); + buffer.Data = NSAllocator::Alloc(nLenDst); + + if (FALSE == NSBase64::Base64Decode(sBase64Data.c_str(), (int)sBase64Data.length(), buffer.Data, &nLenDst)) + { + buffer.Free(); + return buffer; + } + return buffer; + } + + virtual JSSmart<CJSValue> toValue() + { + CJSValueJSC* _value = new CJSValueJSC(); + _value->value = value; + return _value; + } + + virtual void Detach() + { + // None + } + }; + + class CJSFunctionJSC : public CJSValueJSCTemplate<CJSFunction> + { + public: + CJSFunctionJSC() + { + } + virtual ~CJSFunctionJSC() + { + value = nil; + } virtual JSSmart<CJSValue> Call(CJSValue* recv, int argc, JSSmart<CJSValue> argv[]) - { - NSMutableArray* arr = [[NSMutableArray alloc] init]; - for (int i = 0; i < argc; ++i) - { - CJSValueJSC* _val = (CJSValueJSC*)argv[i].operator ->(); - [arr addObject:_val->value]; - } - - CJSValueJSC* _return = new CJSValueJSC(); - _return->value = [value callWithArguments:arr]; - - return _return; - } - }; - - template<typename T> + { + NSMutableArray* arr = [[NSMutableArray alloc] init]; + for (int i = 0; i < argc; ++i) + { + CJSValueJSC* _val = (CJSValueJSC*)argv[i].operator->(); + [arr addObject:_val->value]; + } + + CJSValueJSC* _return = new CJSValueJSC(); + _return->value = [value callWithArguments:arr]; + + return _return; + } + }; + + template <typename T> JSSmart<CJSObject> CJSValueJSCTemplate<T>::toObject() - { - CJSObjectJSC* _value = new CJSObjectJSC(); - _value->value = value; - return _value; - } + { + CJSObjectJSC* _value = new CJSObjectJSC(); + _value->value = value; + return _value; + } - template<typename T> + template <typename T> JSSmart<CJSArray> CJSValueJSCTemplate<T>::toArray() - { - CJSArrayJSC* _value = new CJSArrayJSC(); - _value->value = value; - return _value; - } + { + CJSArrayJSC* _value = new CJSArrayJSC(); + _value->value = value; + return _value; + } - template<typename T> + template <typename T> JSSmart<CJSTypedArray> CJSValueJSCTemplate<T>::toTypedArray() - { - CJSTypedArrayJSC* _value = new CJSTypedArrayJSC(getContext()); - _value->value = value; - return _value; - } + { + CJSTypedArrayJSC* _value = new CJSTypedArrayJSC(getContext()); + _value->value = value; + return _value; + } - template<typename T> + template <typename T> JSSmart<CJSFunction> CJSValueJSCTemplate<T>::toFunction() - { - CJSFunctionJSC* _value = new CJSFunctionJSC(); - _value->value = value; - return _value; - } -} + { + CJSFunctionJSC* _value = new CJSFunctionJSC(); + _value->value = value; + return _value; + } +} // namespace NSJSBase namespace NSJSBase { - // TRY - CATCH - class CJSCTryCatch : public CJSTryCatch - { - public: - JSContext* context; - - public: - CJSCTryCatch() : CJSTryCatch() - { - context = CJSContextPrivate::GetCurrentContext(); - } - virtual ~CJSCTryCatch() - { - context = nil; - } - - public: - virtual bool Check(); - }; + // TRY - CATCH + class CJSCTryCatch : public CJSTryCatch + { + public: + JSContext* context; + + public: + CJSCTryCatch() : CJSTryCatch() + { + context = CJSContextPrivate::GetCurrentContext(); + } + virtual ~CJSCTryCatch() + { + context = nil; + } + + public: + virtual bool Check(); + }; } inline JSSmart<NSJSBase::CJSValue> js_value(JSValue* _value) { - return new NSJSBase::CJSValueJSC(_value); + return new NSJSBase::CJSValueJSC(_value); } inline JSSmart<NSJSBase::CJSValue> js_object(JSValue* _value) { - return new NSJSBase::CJSObjectJSC(_value); + return new NSJSBase::CJSObjectJSC(_value); } inline JSValue* js_return(JSSmart<NSJSBase::CJSValue> _value) { - if (!_value.is_init()) - return nil; - NSJSBase::CJSValueJSC* _tmp = (NSJSBase::CJSValueJSC*)(_value.operator ->()); - return _tmp->value; + if (!_value.is_init()) + return nil; + NSJSBase::CJSValueJSC* _tmp = (NSJSBase::CJSValueJSC*)(_value.operator->()); + return _tmp->value; } -#define FUNCTION_WRAPPER_JS_0(NAME, NAME_EMBED) \ - -(JSValue*) NAME \ - { \ - return js_return(m_internal->NAME_EMBED()); \ - } +#define FUNCTION_WRAPPER_JS_0(NAME, NAME_EMBED) \ + -(JSValue*)NAME \ + { \ + return js_return(m_internal->NAME_EMBED()); \ + } #define FUNCTION_WRAPPER_JS(NAME, NAME_EMBED) FUNCTION_WRAPPER_JS_0(NAME, NAME_EMBED) -#define FUNCTION_WRAPPER_JS_1(NAME, NAME_EMBED) \ - -(JSValue*) NAME:(JSValue*)p1 \ - { \ - return js_return(m_internal->NAME_EMBED(js_value(p1))); \ - } -#define FUNCTION_WRAPPER_JS_2(NAME, NAME_EMBED) \ - -(JSValue*) NAME:(JSValue*)p1 : (JSValue*)p2 \ - { \ - return js_return(m_internal->NAME_EMBED(js_value(p1), js_value(p2))); \ - } -#define FUNCTION_WRAPPER_JS_3(NAME, NAME_EMBED) \ - -(JSValue*) NAME:(JSValue*)p1 : (JSValue*)p2 : (JSValue*)p3 \ - { \ - return js_return(m_internal->NAME_EMBED(js_value(p1), js_value(p2), js_value(p3))); \ - } -#define FUNCTION_WRAPPER_JS_4(NAME, NAME_EMBED) \ - -(JSValue*) NAME:(JSValue*)p1 : (JSValue*)p2 : (JSValue*)p3 : (JSValue*)p4 \ - { \ - return js_return(m_internal->NAME_EMBED(js_value(p1), js_value(p2), js_value(p3), js_value(p4))); \ - } -#define FUNCTION_WRAPPER_JS_5(NAME, NAME_EMBED) \ - -(JSValue*) NAME:(JSValue*)p1 : (JSValue*)p2 : (JSValue*)p3 : (JSValue*)p4 : (JSValue*)p5 \ - { \ - return js_return(m_internal->NAME_EMBED(js_value(p1), js_value(p2), js_value(p3), js_value(p4), js_value(p5))); \ - } -#define FUNCTION_WRAPPER_JS_6(NAME, NAME_EMBED) \ - -(JSValue*) NAME:(JSValue*)p1 : (JSValue*)p2 : (JSValue*)p3 : (JSValue*)p4 : (JSValue*)p5 : (JSValue*)p6 \ - { \ - return js_return(m_internal->NAME_EMBED(js_value(p1), js_value(p2), js_value(p3), js_value(p4), js_value(p5), js_value(p6))); \ - } -#define FUNCTION_WRAPPER_JS_7(NAME, NAME_EMBED) \ - -(JSValue*) NAME:(JSValue*)p1 : (JSValue*)p2 : (JSValue*)p3 : (JSValue*)p4 : (JSValue*)p5 : (JSValue*)p6 : (JSValue*)p7 \ - { \ - return js_return(m_internal->NAME_EMBED(js_value(p1), js_value(p2), js_value(p3), js_value(p4), js_value(p5), js_value(p6), js_value(p7))); \ - } -#define FUNCTION_WRAPPER_JS_8(NAME, NAME_EMBED) \ - -(JSValue*) NAME:(JSValue*)p1 : (JSValue*)p2 : (JSValue*)p3 : (JSValue*)p4 : (JSValue*)p5 : (JSValue*)p6 : (JSValue*)p7 : (JSValue*)p8 \ - { \ - return js_return(m_internal->NAME_EMBED(js_value(p1), js_value(p2), js_value(p3), js_value(p4), js_value(p5), js_value(p6), js_value(p7), js_value(p8))); \ - } +#define FUNCTION_WRAPPER_JS_1(NAME, NAME_EMBED) \ + -(JSValue*)NAME : (JSValue*)p1 \ + { \ + return js_return(m_internal->NAME_EMBED(js_value(p1))); \ + } +#define FUNCTION_WRAPPER_JS_2(NAME, NAME_EMBED) \ + -(JSValue*)NAME : (JSValue*)p1 : (JSValue*)p2 \ + { \ + return js_return(m_internal->NAME_EMBED(js_value(p1), js_value(p2))); \ + } +#define FUNCTION_WRAPPER_JS_3(NAME, NAME_EMBED) \ + -(JSValue*)NAME : (JSValue*)p1 : (JSValue*)p2 : (JSValue*)p3 \ + { \ + return js_return(m_internal->NAME_EMBED(js_value(p1), js_value(p2), js_value(p3))); \ + } +#define FUNCTION_WRAPPER_JS_4(NAME, NAME_EMBED) \ + -(JSValue*)NAME : (JSValue*)p1 : (JSValue*)p2 : (JSValue*)p3 : (JSValue*)p4 \ + { \ + return js_return(m_internal->NAME_EMBED(js_value(p1), js_value(p2), js_value(p3), js_value(p4))); \ + } +#define FUNCTION_WRAPPER_JS_5(NAME, NAME_EMBED) \ + -(JSValue*)NAME : (JSValue*)p1 : (JSValue*)p2 : (JSValue*)p3 : (JSValue*)p4 : (JSValue*)p5 \ + { \ + return js_return(m_internal->NAME_EMBED(js_value(p1), js_value(p2), js_value(p3), js_value(p4), js_value(p5))); \ + } +#define FUNCTION_WRAPPER_JS_6(NAME, NAME_EMBED) \ + -(JSValue*)NAME : (JSValue*)p1 : (JSValue*)p2 : (JSValue*)p3 : (JSValue*)p4 : (JSValue*)p5 : (JSValue*)p6 \ + { \ + return js_return(m_internal->NAME_EMBED(js_value(p1), js_value(p2), js_value(p3), js_value(p4), js_value(p5), js_value(p6))); \ + } +#define FUNCTION_WRAPPER_JS_7(NAME, NAME_EMBED) \ + -(JSValue*)NAME : (JSValue*)p1 : (JSValue*)p2 : (JSValue*)p3 : (JSValue*)p4 : (JSValue*)p5 : (JSValue*)p6 : (JSValue*)p7 \ + { \ + return js_return(m_internal->NAME_EMBED(js_value(p1), js_value(p2), js_value(p3), js_value(p4), js_value(p5), js_value(p6), js_value(p7))); \ + } +#define FUNCTION_WRAPPER_JS_8(NAME, NAME_EMBED) \ + -(JSValue*)NAME : (JSValue*)p1 : (JSValue*)p2 : (JSValue*)p3 : (JSValue*)p4 : (JSValue*)p5 : (JSValue*)p6 : (JSValue*)p7 : (JSValue*)p8 \ + { \ + return js_return(m_internal->NAME_EMBED(js_value(p1), js_value(p2), js_value(p3), js_value(p4), js_value(p5), js_value(p6), js_value(p7), js_value(p8))); \ + } #endif // _BUILD_NATIVE_CONTROL_JSC_BASE_H_ diff --git a/DesktopEditor/doctrenderer/js_internal/jsc/jsc_base.mm b/DesktopEditor/doctrenderer/js_internal/jsc/jsc_base.mm index 504aec74bf6..4345f33a4a1 100644 --- a/DesktopEditor/doctrenderer/js_internal/jsc/jsc_base.mm +++ b/DesktopEditor/doctrenderer/js_internal/jsc/jsc_base.mm @@ -6,436 +6,473 @@ class CGlobalContext { private: - // считаем, что vector будет небольшим, поэтому он будет быстрее, чем map - std::vector<std::pair<ASC_THREAD_ID, CJSContextPrivate*>> m_contexts; - bool m_bIsOldVersion; - - CGlobalContext() - { - m_bIsOldVersion = false; - #ifndef _IOS - if (@available(macOS 10.12, *)) - { - // none - } - else - { - m_bIsOldVersion = true; - } - #endif - } - ~CGlobalContext() - { - for (std::vector<std::pair<ASC_THREAD_ID, CJSContextPrivate*>>::iterator i = m_contexts.begin(); i != m_contexts.end(); i++) - { - CJSContextPrivate* ctx = i->second; - delete ctx; - } - m_contexts.clear(); - } + // считаем, что vector будет небольшим, поэтому он будет быстрее, чем map + std::vector<std::pair<ASC_THREAD_ID, CJSContextPrivate*>> m_contexts; + bool m_bIsOldVersion; + + CGlobalContext() + { + m_bIsOldVersion = false; +#ifndef _IOS + if (@available(macOS 10.12, *)) + { + // none + } + else + { + m_bIsOldVersion = true; + } +#endif + } + ~CGlobalContext() + { + for (std::vector<std::pair<ASC_THREAD_ID, CJSContextPrivate*>>::iterator i = m_contexts.begin(); i != m_contexts.end(); i++) + { + CJSContextPrivate* ctx = i->second; + delete ctx; + } + m_contexts.clear(); + } public: - bool RegisterContext(CJSContextPrivate* ctx, ASC_THREAD_ID* id = NULL) - { - ASC_THREAD_ID nCurrentThread = (id == NULL) ? NSThreads::GetCurrentThreadId() : *id; - for (std::vector<std::pair<ASC_THREAD_ID, CJSContextPrivate*>>::const_iterator i = m_contexts.begin(); i != m_contexts.end(); i++) - { - if (i->first == nCurrentThread) - { - return false; - } - } - - CJSContextPrivate* pContext = new CJSContextPrivate(); - pContext->context = ctx->context; - m_contexts.push_back(std::pair<ASC_THREAD_ID, CJSContextPrivate*>(nCurrentThread, pContext)); - return true; - } - void UnregisterContextForId(ASC_THREAD_ID nCurrentThread) - { - for (std::vector<std::pair<ASC_THREAD_ID, CJSContextPrivate*>>::iterator i = m_contexts.begin(); i != m_contexts.end(); i++) - { - if (i->first == nCurrentThread) - { - CJSContextPrivate* ctx = i->second; - delete ctx; - - m_contexts.erase(i); - return; - } - } - } - void UnregisterContext() - { - UnregisterContextForId(NSThreads::GetCurrentThreadId()); - } - - bool IsOldVersion() - { - return m_bIsOldVersion; - } - - JSContext* GetCurrent() - { - ASC_THREAD_ID nCurrentThread = NSThreads::GetCurrentThreadId(); - for (std::vector<std::pair<ASC_THREAD_ID, CJSContextPrivate*>>::const_iterator i = m_contexts.begin(); i != m_contexts.end(); i++) - { - if (i->first == nCurrentThread) - { - return i->second->context; - } - } - return [JSContext currentContext]; - } - - static CGlobalContext& GetInstance() - { - static CGlobalContext instance; - return instance; - } + bool RegisterContext(CJSContextPrivate* ctx, ASC_THREAD_ID* id = NULL) + { + ASC_THREAD_ID nCurrentThread = (id == NULL) ? NSThreads::GetCurrentThreadId() : *id; + for (std::vector<std::pair<ASC_THREAD_ID, CJSContextPrivate*>>::const_iterator i = m_contexts.begin(); i != m_contexts.end(); i++) + { + if (i->first == nCurrentThread) + { + return false; + } + } + + CJSContextPrivate* pContext = new CJSContextPrivate(); + pContext->context = ctx->context; + m_contexts.push_back(std::pair<ASC_THREAD_ID, CJSContextPrivate*>(nCurrentThread, pContext)); + return true; + } + void UnregisterContextForId(ASC_THREAD_ID nCurrentThread) + { + for (std::vector<std::pair<ASC_THREAD_ID, CJSContextPrivate*>>::iterator i = m_contexts.begin(); i != m_contexts.end(); i++) + { + if (i->first == nCurrentThread) + { + CJSContextPrivate* ctx = i->second; + delete ctx; + + m_contexts.erase(i); + return; + } + } + } + void UnregisterContext() + { + UnregisterContextForId(NSThreads::GetCurrentThreadId()); + } + + bool IsOldVersion() + { + return m_bIsOldVersion; + } + + JSContext* GetCurrent() + { + ASC_THREAD_ID nCurrentThread = NSThreads::GetCurrentThreadId(); + for (std::vector<std::pair<ASC_THREAD_ID, CJSContextPrivate*>>::const_iterator i = m_contexts.begin(); i != m_contexts.end(); i++) + { + if (i->first == nCurrentThread) + { + return i->second->context; + } + } + return [JSContext currentContext]; + } + + static CGlobalContext& GetInstance() + { + static CGlobalContext instance; + return instance; + } }; JSContext* CJSContextPrivate::GetCurrentContext() { - return CGlobalContext::GetInstance().GetCurrent(); + return CGlobalContext::GetInstance().GetCurrent(); } bool CJSContextPrivate::IsOldVersion() { - return CGlobalContext::GetInstance().IsOldVersion(); + return CGlobalContext::GetInstance().IsOldVersion(); } -template<typename T> +template <typename T> bool CJSValueJSCTemplate<T>::isUndefined() { - return (value == nil) ? true : ([value isUndefined] == YES); + return (value == nil) ? true : ([value isUndefined] == YES); } -template<typename T> +template <typename T> bool CJSValueJSCTemplate<T>::isNull() { - return (value == nil) ? false : ([value isNull] == YES); + return (value == nil) ? false : ([value isNull] == YES); } -template<typename T> +template <typename T> bool CJSValueJSCTemplate<T>::isBool() { - return (value == nil) ? false : ([value isBoolean] == YES); + return (value == nil) ? false : ([value isBoolean] == YES); } -template<typename T> +template <typename T> bool CJSValueJSCTemplate<T>::isNumber() { - return (value == nil) ? false : ([value isNumber] == YES); + return (value == nil) ? false : ([value isNumber] == YES); } -template<typename T> +template <typename T> bool CJSValueJSCTemplate<T>::isString() { - return (value == nil) ? false : ([value isString] == YES); + return (value == nil) ? false : ([value isString] == YES); } -template<typename T> +template <typename T> bool CJSValueJSCTemplate<T>::isArray() { - return (value == nil) ? false : JSValueIsArray(getContext().JSGlobalContextRef, value.JSValueRef); + return (value == nil) ? false : JSValueIsArray(getContext().JSGlobalContextRef, value.JSValueRef); } -template<typename T> +template <typename T> bool CJSValueJSCTemplate<T>::isTypedArray() { - return (value == nil) ? false : (kJSTypedArrayTypeNone != JSValueGetTypedArrayType(getContext().JSGlobalContextRef, value.JSValueRef, NULL)); + return (value == nil) ? false : (kJSTypedArrayTypeNone != JSValueGetTypedArrayType(getContext().JSGlobalContextRef, value.JSValueRef, NULL)); } -template<typename T> +template <typename T> bool CJSValueJSCTemplate<T>::isObject() { - return (value == nil) ? false : ([value isObject] == YES); + return (value == nil) ? false : ([value isObject] == YES); } -template<typename T> +template <typename T> bool CJSValueJSCTemplate<T>::isFunction() { - return isObject(); + return isObject(); } -template<typename T> +template <typename T> bool CJSValueJSCTemplate<T>::isEmpty() { - return (value == nil) ? true : false; + return (value == nil) ? true : false; } -template<typename T> +template <typename T> void CJSValueJSCTemplate<T>::doUndefined() { - value = [JSValue valueWithUndefinedInContext:NSJSBase::CJSContextPrivate::GetCurrentContext()]; + value = [JSValue valueWithUndefinedInContext:NSJSBase::CJSContextPrivate::GetCurrentContext()]; } -template<typename T> +template <typename T> void CJSValueJSCTemplate<T>::doNull() { - value = [JSValue valueWithNullInContext:NSJSBase::CJSContextPrivate::GetCurrentContext()]; + value = [JSValue valueWithNullInContext:NSJSBase::CJSContextPrivate::GetCurrentContext()]; } -template<typename T> +template <typename T> bool CJSValueJSCTemplate<T>::toBool() { - return ([value toBool] == YES) ? true : false; + return ([value toBool] == YES) ? true : false; } -template<typename T> +template <typename T> int CJSValueJSCTemplate<T>::toInt32() { - return [value toInt32]; + return [value toInt32]; } -template<typename T> +template <typename T> unsigned int CJSValueJSCTemplate<T>::toUInt32() { - return [value toUInt32]; + return [value toUInt32]; } -template<typename T> +template <typename T> double CJSValueJSCTemplate<T>::toDouble() { - return [value toDouble]; + return [value toDouble]; } -template<typename T> +template <typename T> std::string CJSValueJSCTemplate<T>::toStringA() { - return [[value toString] stdstring]; + return [[value toString] stdstring]; } -template<typename T> +template <typename T> std::wstring CJSValueJSCTemplate<T>::toStringW() { - return [[value toString] stdwstring]; + return [[value toString] stdwstring]; } namespace NSJSBase { - CJSContext::CJSContext(const bool& bIsInitialize) - { - m_internal = new CJSContextPrivate(); - if (bIsInitialize) - Initialize(); - } - CJSContext::~CJSContext() - { - m_internal->context = nil; - RELEASEOBJECT(m_internal); - } + CJSContext::CJSContext(const bool& bIsInitialize) + { + m_internal = new CJSContextPrivate(); + if (bIsInitialize) + Initialize(); + } + CJSContext::~CJSContext() + { + if (m_internal->context) + Dispose(); + RELEASEOBJECT(m_internal); + } JSSmart<CJSTryCatch> CJSContext::GetExceptions() - { - return new CJSCTryCatch(); - } - - void CJSContext::Initialize() - { - m_internal->context = [[JSContext alloc] init]; - - ASC_THREAD_ID nThreadId = NSThreads::GetCurrentThreadId(); - MoveToThread(&nThreadId); - if (CGlobalContext::GetInstance().IsOldVersion()) - { - [m_internal->context evaluateScript:@"function jsc_toBase64(r){for(var o=[\"A\",\"B\",\"C\",\"D\",\"E\",\"F\",\"G\",\"H\",\"I\",\"J\",\"K\",\"L\",\"M\",\"N\",\"O\",\"P\",\"Q\",\"R\",\"S\",\"T\",\"U\",\"V\",\"W\",\"X\",\"Y\",\"Z\",\"a\",\"b\",\"c\",\"d\",\"e\",\"f\",\"g\",\"h\",\"i\",\"j\",\"k\",\"l\",\"m\",\"n\",\"o\",\"p\",\"q\",\"r\",\"s\",\"t\",\"u\",\"v\",\"w\",\"x\",\"y\",\"z\",\"0\",\"1\",\"2\",\"3\",\"4\",\"5\",\"6\",\"7\",\"8\",\"9\",\"+\",\"/\"],a=r.length,f=4*(a/3>>0),n=f/76>>0,t=19,v=0,e=[],i=\"\",s=0;s<=n;s++){s==n&&(t=f%76/4>>0);for(var u=0;u<t;u++){for(var c=0,h=0;h<3;h++)c|=r[0+v++],c<<=8;i=\"\";for(var A=0;A<4;A++){i+=o[c>>>26&255],c<<=6,c&=4294967295}e.push(i)}}if(n=a%3!=0?a%3+1:0){for(c=0,h=0;h<3;h++)h<a%3&&(c|=r[0+v++]),c<<=8;i=\"\";for(A=0;A<n;A++){i+=o[c>>>26&255],c<<=6}t=0!=n?4-n:0;for(u=0;u<t;u++)i+=\"=\";e.push(i)}return e.join(\"\")}function jsc_fromBase64(r,o){for(var a,f=r.length,n=0,t=new Array(void 0===o?f:o),v=t,e=0,i=0;e<f;){for(var s=0,u=0,c=0;c<4&&!(f<=e);c++){var h=65<=(a=r.charCodeAt(e++))&&a<=90?a-65:97<=a&&a<=122?a-71:48<=a&&a<=57?a+4:43==a?62:47==a?63:-1;-1!=h?(s<<=6,s|=h,u+=6):c--}for(s<<=24-u,i=u>>>3,c=0;c<i;c++)v[n++]=(16711680&s)>>>16,s<<=8}return t}\n"]; - } + { + return new CJSCTryCatch(); + } + + void CJSContext::Initialize(const std::wstring& snapshotPath) + { + m_internal->context = [[JSContext alloc] init]; + +#ifdef _DEBUG + if (@available(macOS 10.11, iOS 16.0, *)) + { + JSGlobalContextSetInspectable(m_internal->context.JSGlobalContextRef, true); + } +#endif + + ASC_THREAD_ID nThreadId = NSThreads::GetCurrentThreadId(); + MoveToThread(&nThreadId); + if (CGlobalContext::GetInstance().IsOldVersion()) + { + [m_internal->context evaluateScript:@"function jsc_toBase64(r){for(var o=[\"A\",\"B\",\"C\",\"D\",\"E\",\"F\",\"G\",\"H\",\"I\",\"J\",\"K\",\"L\",\"M\",\"N\",\"O\",\"P\",\"Q\",\"R\",\"S\",\"T\",\"U\",\"V\",\"W\",\"X\",\"Y\",\"Z\",\"a\",\"b\",\"c\",\"d\",\"e\",\"f\",\"g\",\"h\",\"i\",\"j\",\"k\",\"l\",\"m\",\"n\",\"o\",\"p\",\"q\",\"r\",\"s\",\"t\",\"u\",\"v\",\"w\",\"x\",\"y\",\"z\",\"0\",\"1\",\"2\",\"3\",\"4\",\"5\",\"6\",\"7\",\"8\",\"9\",\"+\",\"/\"],a=r.length,f=4*(a/3>>0),n=f/76>>0,t=19,v=0,e=[],i=\"\",s=0;s<=n;s++){s==n&&(t=f%76/4>>0);for(var u=0;u<t;u++){for(var c=0,h=0;h<3;h++)c|=r[0+v++],c<<=8;i=\"\";for(var A=0;A<4;A++){i+=o[c>>>26&255],c<<=6,c&=4294967295}e.push(i)}}if(n=a%3!=0?a%3+1:0){for(c=0,h=0;h<3;h++)h<a%3&&(c|=r[0+v++]),c<<=8;i=\"\";for(A=0;A<n;A++){i+=o[c>>>26&255],c<<=6}t=0!=n?4-n:0;for(u=0;u<t;u++)i+=\"=\";e.push(i)}return e.join(\"\")}function jsc_fromBase64(r,o){for(var a,f=r.length,n=0,t=new Array(void 0===o?f:o),v=t,e=0,i=0;e<f;){for(var s=0,u=0,c=0;c<4&&!(f<=e);c++){var h=65<=(a=r.charCodeAt(e++))&&a<=90?a-65:97<=a&&a<=122?a-71:48<=a&&a<=57?a+4:43==a?62:47==a?63:-1;-1!=h?(s<<=6,s|=h,u+=6):c--}for(s<<=24-u,i=u>>>3,c=0;c<i;c++)v[n++]=(16711680&s)>>>16,s<<=8}return t}\n"]; + } // insert CreateEmbedObject() function to global object of this context m_internal->context[@"CreateEmbedObject"] = ^(NSString* name) { return CreateEmbedNativeObject(name); }; - JSValue* global_js = [m_internal->context globalObject]; - [global_js setValue:global_js forProperty:[[NSString alloc] initWithUTF8String:"window"]]; - } - void CJSContext::Dispose() - { - for (std::vector<ASC_THREAD_ID>::const_iterator i = m_internal->m_arThreads.begin(); i != m_internal->m_arThreads.end(); i++) - { - CGlobalContext::GetInstance().UnregisterContextForId(*i); - } - m_internal->context = nil; - } + JSValue* global_js = [m_internal->context globalObject]; + [global_js setValue:global_js forProperty:[[NSString alloc] initWithUTF8String:"window"]]; + } + void CJSContext::Dispose() + { + for (std::vector<ASC_THREAD_ID>::const_iterator i = m_internal->m_arThreads.begin(); i != m_internal->m_arThreads.end(); i++) + { + CGlobalContext::GetInstance().UnregisterContextForId(*i); + } + m_internal->context = nil; + } + + bool CJSContext::isSnapshotUsed() + { + return false; + } JSSmart<CJSObject> CJSContext::GetGlobal() - { - CJSObjectJSC* ret = new CJSObjectJSC(); - ret->value = [m_internal->context globalObject]; - return ret; - } - - CJSValue* CJSContext::createUndefined() - { - CJSValueJSC* _value = new CJSValueJSC(); - _value->doUndefined(); - return _value; - } - - CJSValue* CJSContext::createNull() - { - CJSValueJSC* _value = new CJSValueJSC(); - _value->doNull(); - return _value; - } - - CJSValue* CJSContext::createBool(const bool& value) - { - CJSValueJSC* _value = new CJSValueJSC(); - _value->value = [JSValue valueWithBool:(value ? YES : NO) inContext:NSJSBase::CJSContextPrivate::GetCurrentContext()]; - return _value; - } - - CJSValue* CJSContext::createInt(const int& value) - { - CJSValueJSC* _value = new CJSValueJSC(); - _value->value = [JSValue valueWithInt32:((int32_t) value) inContext:NSJSBase::CJSContextPrivate::GetCurrentContext()]; - return _value; - } - - CJSValue* CJSContext::createUInt(const unsigned int& value) - { - CJSValueJSC* _value = new CJSValueJSC(); - _value->value = [JSValue valueWithUInt32:((uint32_t) value) inContext:NSJSBase::CJSContextPrivate::GetCurrentContext()]; - return _value; - } - - CJSValue* CJSContext::createDouble(const double& value) - { - CJSValueJSC* _value = new CJSValueJSC(); - _value->value = [JSValue valueWithDouble:value inContext:NSJSBase::CJSContextPrivate::GetCurrentContext()]; - return _value; - } - - CJSValue* CJSContext::createString(const char* value, const int& len) - { - CJSValueJSC* _value = new CJSValueJSC(); - _value->value = [NSString stringWithUtf8Buffer:value length:(size_t)((len == -1) ? strlen(value) : len)]; - return _value; - } - - CJSValue* CJSContext::createString(const wchar_t* value, const int& length) - { - std::string sUtf8 = NSFile::CUtf8Converter::GetUtf8StringFromUnicode2(value, (length != -1) ? (LONG)length : (LONG)wcslen(value)); - return createString((const char*)sUtf8.c_str(), (int)sUtf8.length()); - } - - CJSValue* CJSContext::createString(const std::string& value) - { - CJSValueJSC* _value = new CJSValueJSC(); - _value->value = [NSString stringWithAString:value]; - return _value; - } - - CJSValue* CJSContext::createString(const std::wstring& value) - { - CJSValueJSC* _value = new CJSValueJSC(); - _value->value = [NSString stringWithWString:value]; - return _value; - } - - CJSObject* CJSContext::createObject() - { - CJSObjectJSC* _value = new CJSObjectJSC(); - _value->value = [JSValue valueWithNewObjectInContext:NSJSBase::CJSContextPrivate::GetCurrentContext()]; - return _value; - } - - CJSArray* CJSContext::createArray(const int& count) - { - CJSArrayJSC* _value = new CJSArrayJSC(); - _value->value = [JSValue valueWithNewArrayInContext:NSJSBase::CJSContextPrivate::GetCurrentContext()]; - return _value; - } - - CJSTypedArray* CJSContext::createUint8Array(BYTE* data, int count, const bool& isExternalize) - { - JSContext* _current = NSJSBase::CJSContextPrivate::GetCurrentContext(); - CJSTypedArrayJSC* _value = new CJSTypedArrayJSC(_current, data, count, isExternalize); - return _value; - } - - JSSmart<CJSValue> CJSContext::runScript(const std::string& script, JSSmart<CJSTryCatch> exception, const std::wstring& scriptPath) - { - CJSValueJSC* _value = new CJSValueJSC(); - _value->value = [m_internal->context evaluateScript:[NSString stringWithAString:script]]; - return _value; - } - - unsigned char* NSAllocator::Alloc(const size_t& size) - { - return (unsigned char*)malloc(size); - } - void NSAllocator::Free(unsigned char* data, const size_t& size) - { - free(data); - } - - JSSmart<CJSContext> CJSContext::GetCurrent() - { - CJSContext* ret = new CJSContext(); - ret->m_internal->context = NSJSBase::CJSContextPrivate::GetCurrentContext(); - return ret; - } - - void CJSContext::ExternalInitialize(const std::wstring& sDirectory) - { - } - void CJSContext::ExternalDispose() - { - } - bool CJSContext::IsSupportNativeTypedArrays() - { - return (CJSContextPrivate::IsOldVersion() == false) ? true : false; - } - - JSSmart<CJSValue> CJSContext::JSON_Parse(const char *sTmp) - { - if (!sTmp) - return CJSContext::createUndefined(); - - NSString* sValue = [[NSString alloc] initWithUTF8String:sTmp]; - JSStringRef sValueRef = JSStringCreateWithCFString((__bridge CFStringRef)sValue); - JSValueRef oValueJSRef = JSValueMakeFromJSONString(m_internal->context.JSGlobalContextRef, sValueRef); - - CJSValueJSC* _value = new CJSValueJSC(); - _value->value = [JSValue valueWithJSValueRef:oValueJSRef inContext: m_internal->context]; - return _value; - } - - void CJSContext::MoveToThread(ASC_THREAD_ID* id) - { - if (CGlobalContext::GetInstance().RegisterContext(m_internal, id)) - { - m_internal->m_arThreads.push_back((NULL == id) ? NSThreads::GetCurrentThreadId() : *id); - } - } - - void CJSContext::Enter() - { - } - - void CJSContext::Exit() - { - } - - class CJSLocalScopePrivate - { - public: - CJSLocalScopePrivate() - { - } - ~CJSLocalScopePrivate() - { - } - }; - CJSLocalScope::CJSLocalScope() : m_internal(nullptr) - { - } - - CJSLocalScope::~CJSLocalScope() - { - } + { + CJSObjectJSC* ret = new CJSObjectJSC(); + ret->value = [m_internal->context globalObject]; + return ret; + } + + CJSValue* CJSContext::createUndefined() + { + CJSValueJSC* _value = new CJSValueJSC(); + _value->doUndefined(); + return _value; + } + + CJSValue* CJSContext::createNull() + { + CJSValueJSC* _value = new CJSValueJSC(); + _value->doNull(); + return _value; + } + + CJSValue* CJSContext::createBool(const bool& value) + { + CJSValueJSC* _value = new CJSValueJSC(); + _value->value = [JSValue valueWithBool:(value ? YES : NO) inContext:NSJSBase::CJSContextPrivate::GetCurrentContext()]; + return _value; + } + + CJSValue* CJSContext::createInt(const int& value) + { + CJSValueJSC* _value = new CJSValueJSC(); + _value->value = [JSValue valueWithInt32:((int32_t)value) inContext:NSJSBase::CJSContextPrivate::GetCurrentContext()]; + return _value; + } + + CJSValue* CJSContext::createUInt(const unsigned int& value) + { + CJSValueJSC* _value = new CJSValueJSC(); + _value->value = [JSValue valueWithUInt32:((uint32_t)value) inContext:NSJSBase::CJSContextPrivate::GetCurrentContext()]; + return _value; + } + + CJSValue* CJSContext::createDouble(const double& value) + { + CJSValueJSC* _value = new CJSValueJSC(); + _value->value = [JSValue valueWithDouble:value inContext:NSJSBase::CJSContextPrivate::GetCurrentContext()]; + return _value; + } + + CJSValue* CJSContext::createString(const char* value, const int& len) + { + CJSValueJSC* _value = new CJSValueJSC(); + _value->value = [JSValue valueWithObject:[NSString stringWithUtf8Buffer:value length:(size_t)((len == -1) ? strlen(value) : len)] inContext:NSJSBase::CJSContextPrivate::GetCurrentContext()]; + return _value; + } + + CJSValue* CJSContext::createString(const wchar_t* value, const int& length) + { + std::string sUtf8 = NSFile::CUtf8Converter::GetUtf8StringFromUnicode2(value, (length != -1) ? (LONG)length : (LONG)wcslen(value)); + return createString((const char*)sUtf8.c_str(), (int)sUtf8.length()); + } + + CJSValue* CJSContext::createString(const std::string& value) + { + CJSValueJSC* _value = new CJSValueJSC(); + _value->value = [JSValue valueWithObject:[NSString stringWithAString:value] inContext:NSJSBase::CJSContextPrivate::GetCurrentContext()]; + return _value; + } + + CJSValue* CJSContext::createString(const std::wstring& value) + { + CJSValueJSC* _value = new CJSValueJSC(); + _value->value = [JSValue valueWithObject:[NSString stringWithWString:value] inContext:NSJSBase::CJSContextPrivate::GetCurrentContext()]; + return _value; + } + + CJSObject* CJSContext::createObject() + { + CJSObjectJSC* _value = new CJSObjectJSC(); + _value->value = [JSValue valueWithNewObjectInContext:NSJSBase::CJSContextPrivate::GetCurrentContext()]; + return _value; + } + + CJSArray* CJSContext::createArray(const int& count) + { + CJSArrayJSC* _value = new CJSArrayJSC(); + _value->value = [JSValue valueWithNewArrayInContext:NSJSBase::CJSContextPrivate::GetCurrentContext()]; + return _value; + } + + CJSTypedArray* CJSContext::createUint8Array(BYTE* data, int count, const bool& isExternalize) + { + JSContext* _current = NSJSBase::CJSContextPrivate::GetCurrentContext(); + CJSTypedArrayJSC* _value = new CJSTypedArrayJSC(_current, data, count, isExternalize); + return _value; + } + + bool CJSContext::generateSnapshot(const std::string& script, const std::wstring& snapshotPath) + { + return false; + } + + JSSmart<CJSValue> CJSContext::runScript(const std::string& script, JSSmart<CJSTryCatch> exception, const std::wstring& scriptPath) + { + CJSValueJSC* _value = new CJSValueJSC(); + _value->value = [m_internal->context evaluateScript:[NSString stringWithAString:script]]; + return _value; + } + + unsigned char* NSAllocator::Alloc(const size_t& size) + { + return (unsigned char*)malloc(size); + } + void NSAllocator::Free(unsigned char* data, const size_t& size) + { + free(data); + } + + JSSmart<CJSContext> CJSContext::GetCurrent() + { + CJSContext* ret = new CJSContext(); + ret->m_internal->context = NSJSBase::CJSContextPrivate::GetCurrentContext(); + return ret; + } + + void CJSContext::ExternalInitialize(const std::wstring& sDirectory) + { + } + void CJSContext::ExternalDispose() + { + } + bool CJSContext::IsSupportNativeTypedArrays() + { + return (CJSContextPrivate::IsOldVersion() == false) ? true : false; + } + + JSSmart<CJSValue> CJSContext::JSON_Parse(const char* sTmp) + { + if (!sTmp) + return CJSContext::createUndefined(); + + NSString* sValue = [[NSString alloc] initWithUTF8String:sTmp]; + JSStringRef sValueRef = JSStringCreateWithCFString((__bridge CFStringRef)sValue); + JSValueRef oValueJSRef = JSValueMakeFromJSONString(m_internal->context.JSGlobalContextRef, sValueRef); + + CJSValueJSC* _value = new CJSValueJSC(); + _value->value = [JSValue valueWithJSValueRef:oValueJSRef inContext:m_internal->context]; + return _value; + } + + std::string CJSContext::JSON_Stringify(JSSmart<CJSValue> value) + { + CJSValueJSC* _value = static_cast<CJSValueJSC*>(value.GetPointer()); + JSStringRef ret = JSValueCreateJSONString(m_internal->context.JSGlobalContextRef, _value->value.JSValueRef, 0, nullptr); + if (ret == nullptr) + return ""; + + const size_t nBufferSize = JSStringGetMaximumUTF8CStringSize(ret); + char* buffer = new char[nBufferSize]; + if (buffer == nullptr) + return ""; + + JSStringGetUTF8CString(ret, buffer, nBufferSize); + std::string sRet(buffer); + delete[] buffer; + + return sRet; + } + + void CJSContext::MoveToThread(ASC_THREAD_ID* id) + { + if (CGlobalContext::GetInstance().RegisterContext(m_internal, id)) + { + m_internal->m_arThreads.push_back((NULL == id) ? NSThreads::GetCurrentThreadId() : *id); + } + } + + void CJSContext::Enter() + { + } + + void CJSContext::Exit() + { + } + + class CJSLocalScopePrivate + { + public: + CJSLocalScopePrivate() + { + } + ~CJSLocalScopePrivate() + { + } + }; + CJSLocalScope::CJSLocalScope() : m_internal(nullptr) + { + } + + CJSLocalScope::~CJSLocalScope() + { + } } namespace NSJSBase { - bool CJSCTryCatch::Check() - { - JSValue* exc = [context exception]; - if (exc == nil || [exc isNull] || [exc isUndefined]) - return false; - - NSString* pExсeption = [exc toString]; - std::cerr << [pExсeption stdstring] << std::endl; - NSLog(@"%@", pExсeption); - - exc = nil; - return true; - } + bool CJSCTryCatch::Check() + { + JSValue* exc = [context exception]; + if (exc == nil || [exc isNull] || [exc isUndefined]) + return false; + + NSString* pExсeption = [exc toString]; + std::cerr << [pExсeption stdstring] << std::endl; + NSLog(@"%@", pExсeption); + + exc = nil; + return true; + } } // embed diff --git a/DesktopEditor/doctrenderer/js_internal/v8/v8_base.cpp b/DesktopEditor/doctrenderer/js_internal/v8/v8_base.cpp index 06bbc067177..c8884fecf0e 100644 --- a/DesktopEditor/doctrenderer/js_internal/v8/v8_base.cpp +++ b/DesktopEditor/doctrenderer/js_internal/v8/v8_base.cpp @@ -98,12 +98,8 @@ namespace NSJSBase if (pCacheData) { // save cache to file - NSFile::CFileBinary oFileTest; - if (oFileTest.CreateFileW(Path)) - { - oFileTest.WriteFile(pCacheData->data, (DWORD)pCacheData->length); - oFileTest.CloseFile(); - } + oFileTest.WriteFile(pCacheData->data, (DWORD)pCacheData->length); + oFileTest.CloseFile(); } } @@ -192,12 +188,25 @@ namespace NSJSBase return new CV8TryCatch(); } - void CJSContext::Initialize() + void CJSContext::Initialize(const std::wstring& snapshotPath) { if (m_internal->m_isolate == NULL) { +#ifdef V8_SUPPORT_SNAPSHOTS + if (!snapshotPath.empty()) + { + BYTE* data = NULL; + DWORD dataLength = 0; + if (NSFile::CFileBinary::ReadAllBytes(snapshotPath, &data, dataLength)) + { + m_internal->m_startup_data.data = reinterpret_cast<const char*>(data); + m_internal->m_startup_data.raw_size = (int)dataLength; + } + } +#endif + // get new isolate - v8::Isolate* isolate = CV8Worker::getInitializer().CreateNew(); + v8::Isolate* isolate = CV8Worker::getInitializer().CreateNew(m_internal->m_startup_data.data ? &m_internal->m_startup_data : nullptr); m_internal->m_isolate = isolate; // get new context v8::Isolate::Scope iscope(isolate); @@ -223,6 +232,11 @@ namespace NSJSBase m_internal->m_isolate = NULL; } + bool CJSContext::isSnapshotUsed() + { + return m_internal->m_startup_data.data != NULL; + } + JSSmart<CJSObject> CJSContext::GetGlobal() { CJSObjectV8* ret = new CJSObjectV8(); @@ -395,6 +409,50 @@ namespace NSJSBase return _return; } + bool CJSContext::generateSnapshot(const std::string& script, const std::wstring& snapshotPath) + { +#ifdef V8_SUPPORT_SNAPSHOTS + bool result = false; + // Snapshot creator should be in its own scope, because it handles entering, exiting and disposing the isolate + v8::SnapshotCreator snapshotCreator; + v8::Isolate* isolate = snapshotCreator.GetIsolate(); + { + v8::HandleScope handle_scope(isolate); + // Create a new context + v8::Local<v8::Context> context = v8::Context::New(isolate); + v8::Context::Scope context_scope(context); + + // Handle compile & run errors + v8::Local<v8::Object> global = context->Global(); + global->Set(context, v8::String::NewFromUtf8Literal(isolate, "window"), global).Check(); + global->Set(context, v8::String::NewFromUtf8Literal(isolate, "self"), global).Check(); + global->Set(context, v8::String::NewFromUtf8Literal(isolate, "native"), v8::Undefined(isolate)).Check(); + + // Compile and run + v8::Local<v8::String> source = v8::String::NewFromUtf8(isolate, script.c_str()).ToLocalChecked(); + v8::Local<v8::Script> script = v8::Script::Compile(context, source).ToLocalChecked(); + + script->Run(context).IsEmpty(); + snapshotCreator.SetDefaultContext(context); + } + v8::StartupData data = snapshotCreator.CreateBlob(v8::SnapshotCreator::FunctionCodeHandling::kKeep); + // Save snapshot to file + NSFile::CFileBinary snapshotFile; + if (data.data && snapshotFile.CreateFile(snapshotPath)) + { + snapshotFile.WriteFile(data.data, (DWORD)data.raw_size); + snapshotFile.CloseFile(); + result = true; + } + + delete[] data.data; + + return result; +#else + return false; +#endif + } + JSSmart<CJSContext> CJSContext::GetCurrent() { CJSContext* ret = new CJSContext(false); @@ -413,11 +471,44 @@ namespace NSJSBase else _value->doUndefined(); #else + // TODO: Use MaybeLocal version _value->value = v8::JSON::Parse(CreateV8String(CV8Worker::GetCurrent(), sTmp)); #endif return _value; } + std::string CJSContext::JSON_Stringify(JSSmart<CJSValue> value) + { + // if don't return an empty string explicitly, V8 will return "undefined", which is incorrect + if (value->isUndefined()) + return ""; + + CJSValueV8* _value = static_cast<CJSValueV8*>(value.GetPointer()); + v8::MaybeLocal<v8::String> result; +#ifndef V8_OS_XP +#ifdef V8_VERSION_89_PLUS + result = v8::JSON::Stringify(m_internal->m_context, _value->value); +#else + v8::MaybeLocal<v8::Object> json_object = _value->value->ToObject(m_internal->m_context); + if (json_object.IsEmpty()) + // in case of null and other non-object values + result = _value->value->ToString(m_internal->m_context); + else + result = v8::JSON::Stringify(m_internal->m_context, json_object.ToLocalChecked()); +#endif +#else + // there is no built-in stringifier in V8_XP, so use JSON.stringify() from JS + v8::Local<v8::Object> json = m_internal->m_context->Global()->Get(CreateV8String(m_internal->m_isolate, "JSON"))->ToObject(); + v8::Local<v8::Function> stringify = json->Get(CreateV8String(m_internal->m_isolate, "stringify")).As<v8::Function>(); + result = stringify->Call(json, 1, &_value->value)->ToString(m_internal->m_context); +#endif + if (result.IsEmpty()) + return ""; + + v8::String::Utf8Value data(V8IsolateFirstArg result.ToLocalChecked()); + return std::string((char*)(*data), data.length()); + } + void CJSContext::MoveToThread(ASC_THREAD_ID* id) { // none diff --git a/DesktopEditor/doctrenderer/js_internal/v8/v8_base.h b/DesktopEditor/doctrenderer/js_internal/v8/v8_base.h index c90f2966d4a..247ab50f557 100644 --- a/DesktopEditor/doctrenderer/js_internal/v8/v8_base.h +++ b/DesktopEditor/doctrenderer/js_internal/v8/v8_base.h @@ -52,8 +52,18 @@ v8::Local<v8::String> CreateV8String(v8::Isolate* i, const char* str, const int& len = -1); v8::Local<v8::String> CreateV8String(v8::Isolate* i, const std::string& str); +#ifdef __ANDROID__ + +//#ifdef _DEBUG +#define ANDROID_LOGS +//#endif + #ifdef ANDROID_LOGS -#include <JniLogUtils.h> +#include <android/log.h> +#define LOGW(...) __android_log_print(ANDROID_LOG_WARN, "js", __VA_ARGS__) +#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, "js", __VA_ARGS__) +#endif + #endif #ifdef V8_OS_XP @@ -144,7 +154,11 @@ class CV8Initializer #endif v8::V8::Dispose(); + #ifdef V8_VERSION_121_PLUS + v8::V8::DisposePlatform(); + #else v8::V8::ShutdownPlatform(); + #endif if (m_pAllocator) delete m_pAllocator; @@ -166,7 +180,7 @@ class CV8Initializer return m_pAllocator; } - v8::Isolate* CreateNew() + v8::Isolate* CreateNew(v8::StartupData* startupData = nullptr) { v8::Isolate::CreateParams create_params; #ifndef V8_OS_XP @@ -186,6 +200,10 @@ class CV8Initializer nMaxVirtualMemory); #endif +#ifdef V8_SUPPORT_SNAPSHOTS + create_params.snapshot_blob = startupData; +#endif + return v8::Isolate::New(create_params); } }; @@ -425,9 +443,9 @@ namespace NSJSBase return _value; } - virtual void set(const char* name, CJSValue* value_param) + virtual void set(const char* name, JSSmart<CJSValue> value_param) { - CJSValueV8* _value = static_cast<CJSValueV8*>(value_param); + CJSValueV8* _value = static_cast<CJSValueV8*>(value_param.GetPointer()); v8::Local<v8::String> _name = CreateV8String(CV8Worker::GetCurrent(), name); value->Set(V8ContextFirstArg _name, _value->value); } @@ -446,9 +464,35 @@ namespace NSJSBase value->Set(V8ContextFirstArg _name, v8::Number::New(isolate, _value)); } + virtual std::vector<std::string> getPropertyNames() + { + v8::Local<v8::Context> context = CV8Worker::GetCurrentContext(); + v8::Local<v8::Array> names = value->GetPropertyNames(context).ToLocalChecked(); + uint32_t len = names->Length(); + + std::vector<std::string> ret; + for (uint32_t i = 0; i < len; i++) + { + v8::Local<v8::Value> propertyName = names->Get(context, i).ToLocalChecked(); + v8::Local<v8::Value> propertyValue = value->Get(context, propertyName).ToLocalChecked(); + // skip undefined properties + if (propertyValue->IsUndefined()) + continue; + CJSValueV8 _value; + _value.value = propertyName; + ret.push_back(_value.toStringA()); + } + + return ret; + } + virtual CJSEmbedObject* getNative() { + if (0 == value->InternalFieldCount()) + return NULL; v8::Handle<v8::External> field = v8::Handle<v8::External>::Cast(value->GetInternalField(0)); + if (field.IsEmpty()) + return NULL; return (CJSEmbedObject*)field->Value(); } @@ -461,7 +505,7 @@ namespace NSJSBase LOGGER_START - v8::Local<v8::String> _name = CreateV8String(CV8Worker::GetCurrent(), name); + v8::Local<v8::String> _name = CreateV8String(CV8Worker::GetCurrent(), name); v8::Handle<v8::Value> _func = value->Get(V8ContextFirstArg _name).ToLocalChecked(); CJSValueV8* _return = new CJSValueV8(); @@ -492,7 +536,7 @@ namespace NSJSBase LOGGER_LAP_NAME(name) - JSSmart<CJSValue> _ret = _return; + JSSmart<CJSValue> _ret = _return; return _ret; } @@ -530,23 +574,18 @@ namespace NSJSBase return _value; } - virtual void set(const int& index, CJSValue* value_param) + virtual void set(const int& index, JSSmart<CJSValue> value_param) { - CJSValueV8* _value = static_cast<CJSValueV8*>(value_param); + CJSValueV8* _value = static_cast<CJSValueV8*>(value_param.GetPointer()); value->Set(V8ContextFirstArg index, _value->value); } - virtual void add(CJSValue* value_param) + virtual void add(JSSmart<CJSValue> value_param) { - CJSValueV8* _value = static_cast<CJSValueV8*>(value_param); + CJSValueV8* _value = static_cast<CJSValueV8*>(value_param.GetPointer()); value->Set(V8ContextFirstArg getCount(), _value->value); } - virtual void set(const int& index, const bool& _value) - { - value->Set(V8ContextFirstArg index, v8::Boolean::New(CV8Worker::GetCurrent(), _value)); - } - virtual void set(const int& index, const int& _value) { value->Set(V8ContextFirstArg index, v8::Integer::New(CV8Worker::GetCurrent(), _value)); @@ -670,6 +709,15 @@ namespace NSJSBase _value->value = value; return _value; } + + virtual void Detach() + { +#ifdef V8_ARRAY_BUFFER_USE_BACKING_STORE + value->Buffer()->Detach(); +#else + value->Buffer()->Neuter(); +#endif + } }; class CJSFunctionV8 : public CJSValueV8Template<v8::Function, CJSFunction> @@ -787,10 +835,8 @@ namespace NSJSBase #endif #ifdef ANDROID_LOGS - LOGE("NSJSBase::CV8TryCatch::Check() - error:"); - LOGE(std::to_string(nLineNumber).c_str()); - LOGE(strCode.c_str()); - LOGE(strException.c_str()); + std::string sLog = "[JS (" + std::to_string(nLineNumber) + ")]: " + strCode + ", " + strException; + LOGE(sLog.c_str()); #endif return true; } @@ -810,9 +856,13 @@ namespace NSJSBase v8::Persistent<v8::Context> m_contextPersistent; v8::Local<v8::Context> m_context; + v8::StartupData m_startup_data; + public: CJSContextPrivate() : m_isolate(NULL) { + m_startup_data.data = NULL; + m_startup_data.raw_size = 0; } void InsertToGlobal(const std::string& name, v8::FunctionCallback creator) @@ -821,6 +871,12 @@ namespace NSJSBase v8::MaybeLocal<v8::Function> oFuncMaybeLocal = templ->GetFunction(m_context); m_context->Global()->Set(m_context, CreateV8String(m_isolate, name.c_str()), oFuncMaybeLocal.ToLocalChecked()); } + + ~CJSContextPrivate() + { + if (m_startup_data.data) + delete [] m_startup_data.data; + } }; // embed @@ -939,67 +995,76 @@ inline void js_return(const v8::PropertyCallbackInfo<v8::Value>& info, JSSmart<N #define PROPERTY_GET(NAME, NAME_EMBED) \ void NAME(v8::Local<v8::String> _name, const v8::PropertyCallbackInfo<v8::Value>& info) \ { \ - CURRENTWRAPPER* _this = (CURRENTWRAPPER*)unwrap_native(info.Holder()); \ + CURRENTWRAPPER* _this = dynamic_cast<CURRENTWRAPPER*>(unwrap_native(info.Holder())); \ + if (!_this) return; \ JSSmart<CJSValue> ret = _this->NAME_EMBED(); \ js_return(info, ret); \ } -#define FUNCTION_WRAPPER_V8_0(NAME, NAME_EMBED) \ - void NAME(const v8::FunctionCallbackInfo<v8::Value>& args) \ -{ \ - CURRENTWRAPPER* _this = (CURRENTWRAPPER*)unwrap_native(args.Holder()); \ - JSSmart<CJSValue> ret = _this->NAME_EMBED(); \ - js_return(args, ret); \ +#define FUNCTION_WRAPPER_V8_0(NAME, NAME_EMBED) \ + void NAME(const v8::FunctionCallbackInfo<v8::Value>& args) \ +{ \ + CURRENTWRAPPER* _this = dynamic_cast<CURRENTWRAPPER*>(unwrap_native(args.Holder())); \ + if (!_this) return; \ + JSSmart<CJSValue> ret = _this->NAME_EMBED(); \ + js_return(args, ret); \ } #define FUNCTION_WRAPPER_V8(NAME, NAME_EMBED) FUNCTION_WRAPPER_V8_0(NAME, NAME_EMBED) -#define FUNCTION_WRAPPER_V8_1(NAME, NAME_EMBED) \ - void NAME(const v8::FunctionCallbackInfo<v8::Value>& args) \ -{ \ - CURRENTWRAPPER* _this = (CURRENTWRAPPER*)unwrap_native(args.Holder()); \ - JSSmart<CJSValue> ret = _this->NAME_EMBED(js_value(args[0])); \ - js_return(args, ret); \ +#define FUNCTION_WRAPPER_V8_1(NAME, NAME_EMBED) \ + void NAME(const v8::FunctionCallbackInfo<v8::Value>& args) \ +{ \ + CURRENTWRAPPER* _this = dynamic_cast<CURRENTWRAPPER*>(unwrap_native(args.Holder())); \ + if (!_this) return; \ + JSSmart<CJSValue> ret = _this->NAME_EMBED(js_value(args[0])); \ + js_return(args, ret); \ } -#define FUNCTION_WRAPPER_V8_2(NAME, NAME_EMBED) \ - void NAME(const v8::FunctionCallbackInfo<v8::Value>& args) \ -{ \ - CURRENTWRAPPER* _this = (CURRENTWRAPPER*)unwrap_native(args.Holder()); \ - JSSmart<CJSValue> ret = _this->NAME_EMBED(js_value(args[0]), js_value(args[1])); \ - js_return(args, ret); \ +#define FUNCTION_WRAPPER_V8_2(NAME, NAME_EMBED) \ + void NAME(const v8::FunctionCallbackInfo<v8::Value>& args) \ +{ \ + CURRENTWRAPPER* _this = dynamic_cast<CURRENTWRAPPER*>(unwrap_native(args.Holder())); \ + if (!_this) return; \ + JSSmart<CJSValue> ret = _this->NAME_EMBED(js_value(args[0]), js_value(args[1])); \ + js_return(args, ret); \ } #define FUNCTION_WRAPPER_V8_3(NAME, NAME_EMBED) \ void NAME(const v8::FunctionCallbackInfo<v8::Value>& args) \ { \ - CURRENTWRAPPER* _this = (CURRENTWRAPPER*)unwrap_native(args.Holder()); \ + CURRENTWRAPPER* _this = dynamic_cast<CURRENTWRAPPER*>(unwrap_native(args.Holder())); \ + if (!_this) return; \ JSSmart<CJSValue> ret = _this->NAME_EMBED(js_value(args[0]), js_value(args[1]), js_value(args[2])); \ js_return(args, ret); \ } #define FUNCTION_WRAPPER_V8_4(NAME, NAME_EMBED) \ void NAME(const v8::FunctionCallbackInfo<v8::Value>& args) \ { \ - CURRENTWRAPPER* _this = (CURRENTWRAPPER*)unwrap_native(args.Holder()); \ + CURRENTWRAPPER* _this = dynamic_cast<CURRENTWRAPPER*>(unwrap_native(args.Holder())); \ + if (!_this) return; \ JSSmart<CJSValue> ret = _this->NAME_EMBED(js_value(args[0]), js_value(args[1]), js_value(args[2]), js_value(args[3])); \ js_return(args, ret); \ } #define FUNCTION_WRAPPER_V8_5(NAME, NAME_EMBED) \ void NAME(const v8::FunctionCallbackInfo<v8::Value>& args) \ { \ - CURRENTWRAPPER* _this = (CURRENTWRAPPER*)unwrap_native(args.Holder()); \ + CURRENTWRAPPER* _this = dynamic_cast<CURRENTWRAPPER*>(unwrap_native(args.Holder())); \ + if (!_this) return; \ JSSmart<CJSValue> ret = _this->NAME_EMBED(js_value(args[0]), js_value(args[1]), js_value(args[2]), js_value(args[3]), js_value(args[4])); \ js_return(args, ret); \ } #define FUNCTION_WRAPPER_V8_6(NAME, NAME_EMBED) \ void NAME(const v8::FunctionCallbackInfo<v8::Value>& args) \ { \ - CURRENTWRAPPER* _this = (CURRENTWRAPPER*)unwrap_native(args.Holder()); \ + CURRENTWRAPPER* _this = dynamic_cast<CURRENTWRAPPER*>(unwrap_native(args.Holder())); \ + if (!_this) return; \ JSSmart<CJSValue> ret = _this->NAME_EMBED(js_value(args[0]), js_value(args[1]), js_value(args[2]), js_value(args[3]), js_value(args[4]), js_value(args[5])); \ js_return(args, ret); \ } #define FUNCTION_WRAPPER_V8_7(NAME, NAME_EMBED) \ void NAME(const v8::FunctionCallbackInfo<v8::Value>& args) \ { \ - CURRENTWRAPPER* _this = (CURRENTWRAPPER*)unwrap_native(args.Holder()); \ + CURRENTWRAPPER* _this = dynamic_cast<CURRENTWRAPPER*>(unwrap_native(args.Holder())); \ + if (!_this) return; \ JSSmart<CJSValue> ret = _this->NAME_EMBED(js_value(args[0]), js_value(args[1]), js_value(args[2]), js_value(args[3]), js_value(args[4]), \ js_value(args[5]), js_value(args[6])); \ js_return(args, ret); \ @@ -1007,7 +1072,8 @@ inline void js_return(const v8::PropertyCallbackInfo<v8::Value>& info, JSSmart<N #define FUNCTION_WRAPPER_V8_8(NAME, NAME_EMBED) \ void NAME(const v8::FunctionCallbackInfo<v8::Value>& args) \ { \ - CURRENTWRAPPER* _this = (CURRENTWRAPPER*)unwrap_native(args.Holder()); \ + CURRENTWRAPPER* _this = dynamic_cast<CURRENTWRAPPER*>(unwrap_native(args.Holder())); \ + if (!_this) return; \ JSSmart<CJSValue> ret = _this->NAME_EMBED(js_value(args[0]), js_value(args[1]), js_value(args[2]), js_value(args[3]), js_value(args[4]), \ js_value(args[5]), js_value(args[6]), js_value(args[7])); \ js_return(args, ret); \ @@ -1015,7 +1081,8 @@ inline void js_return(const v8::PropertyCallbackInfo<v8::Value>& info, JSSmart<N #define FUNCTION_WRAPPER_V8_9(NAME, NAME_EMBED) \ void NAME(const v8::FunctionCallbackInfo<v8::Value>& args) \ { \ - CURRENTWRAPPER* _this = (CURRENTWRAPPER*)unwrap_native(args.Holder()); \ + CURRENTWRAPPER* _this = dynamic_cast<CURRENTWRAPPER*>(unwrap_native(args.Holder())); \ + if (!_this) return; \ JSSmart<CJSValue> ret = _this->NAME_EMBED(js_value(args[0]), js_value(args[1]), js_value(args[2]), js_value(args[3]), js_value(args[4]), \ js_value(args[5]), js_value(args[6]), js_value(args[7]), js_value(args[8])); \ js_return(args, ret); \ @@ -1023,7 +1090,8 @@ inline void js_return(const v8::PropertyCallbackInfo<v8::Value>& info, JSSmart<N #define FUNCTION_WRAPPER_V8_10(NAME, NAME_EMBED) \ void NAME(const v8::FunctionCallbackInfo<v8::Value>& args) \ { \ - CURRENTWRAPPER* _this = (CURRENTWRAPPER*)unwrap_native(args.Holder()); \ + CURRENTWRAPPER* _this = dynamic_cast<CURRENTWRAPPER*>(unwrap_native(args.Holder())); \ + if (!_this) return; \ JSSmart<CJSValue> ret = _this->NAME_EMBED(js_value(args[0]), js_value(args[1]), js_value(args[2]), js_value(args[3]), js_value(args[4]), js_value(args[5]), \ js_value(args[6]), js_value(args[7]), js_value(args[8]), js_value(args[9])); \ js_return(args, ret); \ @@ -1031,7 +1099,8 @@ inline void js_return(const v8::PropertyCallbackInfo<v8::Value>& info, JSSmart<N #define FUNCTION_WRAPPER_V8_13(NAME, NAME_EMBED) \ void NAME(const v8::FunctionCallbackInfo<v8::Value>& args) \ { \ - CURRENTWRAPPER* _this = (CURRENTWRAPPER*)unwrap_native(args.Holder()); \ + CURRENTWRAPPER* _this = dynamic_cast<CURRENTWRAPPER*>(unwrap_native(args.Holder())); \ + if (!_this) return; \ JSSmart<CJSValue> ret = _this->NAME_EMBED(js_value(args[0]), js_value(args[1]), js_value(args[2]), js_value(args[3]), js_value(args[4]), js_value(args[5]), \ js_value(args[6]), js_value(args[7]), js_value(args[8]), js_value(args[9]), js_value(args[10]), js_value(args[11]), \ js_value(args[12])); \ diff --git a/DesktopEditor/doctrenderer/json/json.cpp b/DesktopEditor/doctrenderer/json/json.cpp new file mode 100644 index 00000000000..74350430722 --- /dev/null +++ b/DesktopEditor/doctrenderer/json/json.cpp @@ -0,0 +1,1071 @@ +#include "json.h" +#include "json_p.h" +#include "json_values.h" + +// for working with typed arrays: Alloc() and Free() +#include "js_base.h" + +// for converting primitive types to JSON-string +#include <sstream> +#include <iomanip> +#include <limits> +// for strtod() +#include <cstdlib> +// for modf() +#include <cmath> + +namespace NSJSON +{ + CTypedValue::CTypedValue() : m_type(vtUndefined) + { + } + + CTypedValue::CTypedValue(IBaseValue* value, ValueType type) : m_value(value), m_type(type) + { + } + + CTypedValue::~CTypedValue() + { + } + + + IValue::IValue() : m_internal(new CTypedValue()) + { + } + + IValue::IValue(const std::shared_ptr<CTypedValue>& internal) : m_internal(internal) + { + } + + IValue::~IValue() + { + } + + bool IValue::IsUndefined() const + { + return m_internal->m_type == CTypedValue::vtUndefined; + } + + bool IValue::IsNull() const + { + return m_internal->m_type == CTypedValue::vtNull; + } + + bool IValue::IsInit() const + { + // the same as (m_internal->m_type != CTypedValue::vtUndefined && m_internal->m_type != CTypedValue::vtNull) but a little bit faster + return m_internal->m_value.get() != nullptr; + } + + bool IValue::IsBool() const + { + return (m_internal->m_type == CTypedValue::vtPrimitive && + static_cast<CPrimitive*>(m_internal->m_value.get())->isBool()); + } + + bool IValue::IsInt() const + { + return (m_internal->m_type == CTypedValue::vtPrimitive && + static_cast<CPrimitive*>(m_internal->m_value.get())->isInt()); + } + + bool IValue::IsDouble() const + { + return (m_internal->m_type == CTypedValue::vtPrimitive && + static_cast<CPrimitive*>(m_internal->m_value.get())->isDouble()); + } + + bool IValue::IsString() const + { + if (m_internal->m_type != CTypedValue::vtPrimitive) + return false; + + CPrimitive* pPrimitive = static_cast<CPrimitive*>(m_internal->m_value.get()); + return (pPrimitive->isStringA() || pPrimitive->isStringW()); + } + + bool IValue::IsArray() const + { + return m_internal->m_type == CTypedValue::vtArray; + } + + bool IValue::IsTypedArray() const + { + return m_internal->m_type == CTypedValue::vtTypedArray; + } + + bool IValue::IsObject() const + { + return m_internal->m_type == CTypedValue::vtObject; + } + + bool IValue::IsImage() const + { + return m_internal->m_type == CTypedValue::vtImage; + } + + bool IValue::ToBool() const + { + if (m_internal->m_type != CTypedValue::vtPrimitive) + { +#ifdef JSON_DEBUG + throw std::bad_cast(); +#endif + return false; + } + return static_cast<CPrimitive*>(m_internal->m_value.get())->toBool(); + } + + int IValue::ToInt() const + { + if (m_internal->m_type != CTypedValue::vtPrimitive) + { +#ifdef JSON_DEBUG + throw std::bad_cast(); +#endif + return 0; + } + return static_cast<CPrimitive*>(m_internal->m_value.get())->toInt(); + } + + double IValue::ToDouble() const + { + if (m_internal->m_type != CTypedValue::vtPrimitive) + { +#ifdef JSON_DEBUG + throw std::bad_cast(); +#endif + return 0.0; + } + return static_cast<CPrimitive*>(m_internal->m_value.get())->toDouble(); + } + + std::string IValue::ToStringA() const + { + if (m_internal->m_type != CTypedValue::vtPrimitive) + { +#ifdef JSON_DEBUG + throw std::bad_cast(); +#endif + return ""; + } + return static_cast<CPrimitive*>(m_internal->m_value.get())->toStringA(); + } + + std::wstring IValue::ToStringW() const + { + if (m_internal->m_type != CTypedValue::vtPrimitive) + { +#ifdef JSON_DEBUG + throw std::bad_cast(); +#endif + return L""; + } + return static_cast<CPrimitive*>(m_internal->m_value.get())->toStringW(); + } + + IValue::operator bool() const + { + return ToBool(); + } + + IValue::operator int() const + { + return ToInt(); + } + + IValue::operator double() const + { + return ToDouble(); + } + + IValue::operator std::string() const + { + return ToStringA(); + } + + IValue::operator std::wstring() const + { + return ToStringW(); + } + + namespace + { + std::string doubleToJsonString(double value) + { + // handle special cases + if (std::isnan(value) || std::isinf(value)) + return "null"; + + // convert to string with full precision + std::ostringstream oss; + oss.precision(std::numeric_limits<double>::digits10); + oss << std::noshowpoint << value; + + return oss.str(); + } + + std::string stringToJsonString(const std::string& value) + { + std::string result; + for (char ch : value) + { + if (ch <= 0x1F) + { + result += '\\'; + if (ch == '\b') + { + result += 'b'; + } + else if (ch == '\t') + { + result += 't'; + } + else if (ch == '\n') + { + result += 'n'; + } + else if (ch == '\f') + { + result += 'f'; + } + else if (ch == '\r') + { + result += 'r'; + } + else + { + result += "u00"; + std::ostringstream oss; + oss << std::setfill('0') << std::setw(2) << std::hex << (int)ch; + result += oss.str(); + } + } + else if (ch == '\\') + { + result += "\\\\"; + } + else if (ch == '\"') + { + result += "\\\""; + } + else + { + result += ch; + } + } + + return result; + } + } + + std::string IValue::ToJSON() + { + std::string strRes; + CTypedValue::ValueType type = m_internal->m_type; + switch (type) + { + case CTypedValue::vtUndefined: + { + break; + } + case CTypedValue::vtNull: + { + strRes = "null"; + break; + } + case CTypedValue::vtPrimitive: + { + CPrimitive* pPrimitiveValue = static_cast<CPrimitive*>(m_internal->m_value.get()); + if (pPrimitiveValue->isBool()) + { + strRes = pPrimitiveValue->toBool() ? "true" : "false"; + } + else if (pPrimitiveValue->isInt()) + { + strRes = std::to_string(pPrimitiveValue->toInt()); + } + else if (pPrimitiveValue->isDouble()) + { + strRes = doubleToJsonString(pPrimitiveValue->toDouble()); + } + else + { + strRes = "\"" + stringToJsonString(pPrimitiveValue->toStringA()) + "\""; + } + break; + } + case CTypedValue::vtArray: + { + CArray* pArrayValue = static_cast<CArray*>(m_internal->m_value.get()); + strRes = "["; + const int len = pArrayValue->getCount(); + for (int i = 0; i < len; i++) + { + CValue& value = pArrayValue->get(i); + if (value.IsUndefined()) + strRes += "null"; + else + strRes += value.ToJSON(); + strRes += ','; + } + // remove last ',' + if (strRes.back() == ',') + strRes.pop_back(); + strRes += "]"; + break; + } + case CTypedValue::vtTypedArray: + { + CTypedArray* pTypedArrayValue = static_cast<CTypedArray*>(m_internal->m_value.get()); + strRes += "{"; + const int size = pTypedArrayValue->getCount(); + BYTE* data = pTypedArrayValue->getData(); + for (int i = 0; i < size; i++) + { + strRes += "\"" + std::to_string(i) + "\":"; + strRes += std::to_string((int)data[i]); + strRes += ','; + } + // remove last ',' + if (strRes.back() == ',') + strRes.pop_back(); + strRes += "}"; + break; + } + case CTypedValue::vtObject: + { + CObject* pObjectValue = static_cast<CObject*>(m_internal->m_value.get()); + strRes += "{"; + std::vector<std::string> propertyNames = pObjectValue->getPropertyNames(); + const int count = propertyNames.size(); + for (int i = 0; i < count; i++) + { + CValue& value = pObjectValue->get(propertyNames[i]); + if (value.IsUndefined()) + continue; + + strRes += "\"" + propertyNames[i] + "\":"; + strRes += value.ToJSON(); + strRes += ','; + } + // remove last ',' + if (strRes.back() == ',') + strRes.pop_back(); + strRes += "}"; + break; + } + case CTypedValue::vtImage: + { + // TODO: implement like typed array? + break; + } + } + + return strRes; + } + + IValue::IValue(bool value) : m_internal(new CTypedValue(new CPrimitive(value), CTypedValue::vtPrimitive)) + { + } + + IValue::IValue(int value) : m_internal(new CTypedValue(new CPrimitive(value), CTypedValue::vtPrimitive)) + { + } + + IValue::IValue(double value) : m_internal(new CTypedValue(new CPrimitive(value), CTypedValue::vtPrimitive)) + { + } + + IValue::IValue(const char* value) : m_internal(new CTypedValue(new CPrimitive(std::string(value)), CTypedValue::vtPrimitive)) + { + } + + IValue::IValue(const std::string& value) : m_internal(new CTypedValue(new CPrimitive(value), CTypedValue::vtPrimitive)) + { + } + + IValue::IValue(const wchar_t* value) : m_internal(new CTypedValue(new CPrimitive(std::wstring(value)), CTypedValue::vtPrimitive)) + { + } + + IValue::IValue(const std::wstring& value) : m_internal(new CTypedValue(new CPrimitive(value), CTypedValue::vtPrimitive)) + { + } + + int IValue::GetCount() const + { + if (m_internal->m_type == CTypedValue::vtArray) + { + return static_cast<CArray*>(m_internal->m_value.get())->getCount(); + } + else if (m_internal->m_type == CTypedValue::vtTypedArray) + { + return static_cast<CTypedArray*>(m_internal->m_value.get())->getCount(); + } + else + { +#ifdef JSON_DEBUG + throw std::bad_cast(); +#endif + return 0; + } + } + + const CValueRef IValue::Get(int index) const + { + if (m_internal->m_type != CTypedValue::vtArray) + { +#ifdef JSON_DEBUG + throw std::bad_cast(); +#endif + return CValue(); + } + + if (index < 0 || index >= GetCount()) + { +#ifdef JSON_DEBUG + throw std::out_of_range("std::out_of_range"); +#endif + return CValue(); + } + return static_cast<CArray*>(m_internal->m_value.get())->get(index); + } + + CValueRef IValue::Get(int index) + { + return static_cast<const IValue&>(*this).Get(index); + } + + const CValueRef IValue::operator[](int index) const + { + return Get(index); + } + + CValueRef IValue::operator[](int index) + { + return Get(index); + } + + IValue::IValue(std::initializer_list<CValue> elements) : m_internal(new CTypedValue(new CArray(elements), CTypedValue::vtArray)) + { + } + + const BYTE* IValue::GetData() const + { + if (m_internal->m_type != CTypedValue::vtTypedArray) + { +#ifdef JSON_DEBUG + throw std::bad_cast(); +#endif + return nullptr; + } + return static_cast<CTypedArray*>(m_internal->m_value.get())->getData(); + } + + BYTE* IValue::GetData() + { + return const_cast<BYTE*>(static_cast<const CValue&>(*this).GetData()); + } + + const CValueRef IValue::Get(const char* name) const + { + if (m_internal->m_type != CTypedValue::vtObject) + { +#ifdef JSON_DEBUG + throw std::bad_cast(); +#endif + return CValue(); + } + return static_cast<CObject*>(m_internal->m_value.get())->get(name); + } + + CValueRef IValue::Get(const char* name) + { + return static_cast<const IValue&>(*this).Get(name); + } + + const CValueRef IValue::operator[](const char* name) const + { + return Get(name); + } + + CValueRef IValue::operator[](const char* name) + { + return Get(name); + } + + std::vector<std::string> IValue::GetPropertyNames() const + { + if (m_internal->m_type != CTypedValue::vtObject) + { +#ifdef JSON_DEBUG + throw std::bad_cast(); +#endif + return {}; + } + return static_cast<CObject*>(m_internal->m_value.get())->getPropertyNames(); + } + + const BYTE* IValue::GetImageBits() const + { + if (m_internal->m_type != CTypedValue::vtImage) + { +#ifdef JSON_DEBUG + throw std::bad_cast(); +#endif + return nullptr; + } + return static_cast<CImage*>(m_internal->m_value.get())->getBits(); + } + + BYTE* IValue::GetImageBits() + { + return const_cast<BYTE*>(static_cast<const CValue&>(*this).GetImageBits()); + } + + int IValue::GetImageWidth() const + { + if (m_internal->m_type != CTypedValue::vtImage) + { +#ifdef JSON_DEBUG + throw std::bad_cast(); +#endif + return 0; + } + return static_cast<CImage*>(m_internal->m_value.get())->getWidth(); + } + + int IValue::GetImageHeight() const + { + if (m_internal->m_type != CTypedValue::vtImage) + { +#ifdef JSON_DEBUG + throw std::bad_cast(); +#endif + return 0; + } + return static_cast<CImage*>(m_internal->m_value.get())->getHeight(); + } + + ImageFormat IValue::GetImageFormat() const + { + if (m_internal->m_type != CTypedValue::vtImage) + { +#ifdef JSON_DEBUG + throw std::bad_cast(); +#endif + return ImageFormat::ifInvalid; + } + return static_cast<CImage*>(m_internal->m_value.get())->getFormat(); + } + + void IValue::ImageExternalize() + { + if (m_internal->m_type != CTypedValue::vtImage) + { +#ifdef JSON_DEBUG + throw std::bad_cast(); +#endif + return; + } + static_cast<CImage*>(m_internal->m_value.get())->externalize(); + } + + void IValue::ImageAlloc(const int& width, const int& height, const ImageFormat& format) + { + if (m_internal->m_type != CTypedValue::vtImage) + { +#ifdef JSON_DEBUG + throw std::bad_cast(); +#endif + return; + } + static_cast<CImage*>(m_internal->m_value.get())->alloc(width, height, format); + } + + CValue::CValue() : IValue() + { + } + + CValue::CValue(const CValue& other) : IValue(std::make_shared<CTypedValue>(*other.m_internal)) + { + } + + CValue::CValue(const CValueRef& ref) : IValue(std::make_shared<CTypedValue>(*ref.m_internal)) + { + } + + CValue::~CValue() + { + } + + CValue& CValue::operator=(const CValue& other) + { + *m_internal = *other.m_internal; + return *this; + } + + CValue& CValue::operator=(const CValueRef& ref) + { + *m_internal = *ref.m_internal; + return *this; + } + + CValue::CValue(bool value) : IValue(value) + { + } + + CValue::CValue(int value) : IValue(value) + { + } + + CValue::CValue(double value) : IValue(value) + { + } + + CValue::CValue(const char* value) : IValue(value) + { + } + + CValue::CValue(const std::string& value) : IValue(value) + { + } + + CValue::CValue(const wchar_t* value) : IValue(value) + { + } + + CValue::CValue(const std::wstring& value) : IValue(value) + { + } + + CValue::CValue(std::initializer_list<CValue> elements) : IValue(elements) + { + } + + CValue CValue::CreateArray(int count) + { + CValue ret; + if (count < 0) + return ret; + + ret.m_internal->m_value = std::make_shared<CArray>(count); + ret.m_internal->m_type = CTypedValue::vtArray; + return ret; + } + + CValue CValue::CreateTypedArray(BYTE* data, int count, bool isExternalize) + { + CValue ret; + if (count <= 0) + return ret; + + ret.m_internal->m_value = std::make_shared<CTypedArray>(data, count, isExternalize); + ret.m_internal->m_type = CTypedValue::vtTypedArray; + return ret; + } + + BYTE* CValue::AllocTypedArray(size_t size) + { + return NSJSBase::NSAllocator::Alloc(size); + } + + void CValue::FreeTypedArray(BYTE* data, size_t size) + { + NSJSBase::NSAllocator::Free(data, size); + } + + CValue CValue::CreateImage(BYTE* bits, int width, int height, ImageFormat format, bool isExternalize) + { + CValue ret; + if (width <= 0 || height <= 0) + return ret; + + ret.m_internal->m_value = std::make_shared<CImage>(bits, width, height, format, isExternalize); + ret.m_internal->m_type = CTypedValue::vtImage; + return ret; + } + + CValue CValue::CreateEmptyImage(ImageFormat format) + { + CValue ret; + ret.m_internal->m_value = std::make_shared<CImage>((BYTE*)NULL, 0, 0, format, false); + ret.m_internal->m_type = CTypedValue::vtImage; + return ret; + } + + BYTE* CValue::AllocImageBits(int width, int height) + { + return new BYTE[4 * width * height]; + } + + void CValue::FreeImageBits(BYTE* bits) + { + delete[] bits; + } + + CValue CValue::CreateObject() + { + CValue ret; + ret.m_internal->m_value = std::make_shared<CObject>(); + ret.m_internal->m_type = CTypedValue::vtObject; + return ret; + } + + CValue CValue::CreateUndefined() + { + return CValue(); + } + + CValue CValue::CreateNull() + { + CValue ret; + ret.m_internal->m_type = CTypedValue::vtNull; + return ret; + } + + namespace + { + // moves pos to first non-space symbol and returns false if end of the string was reached + bool skipWhitespaces(const std::string& str, int& pos) + { + for (; pos < str.size(); pos++) + { + char ch = str[pos]; + if (ch != '\t' && ch != '\n' && ch != '\r' && ch != ' ') + break; + } + return pos < str.size(); + } + + CValue parseNumberFromJSON(const std::string& str, int& pos) + { + const char* startPos = str.c_str() + pos; + char* newPos; + double number = std::strtod(startPos, &newPos); + if (newPos == startPos) + return CValue(); + + CValue value; + if (std::isfinite(number)) + { + // check if number can be represented as an integer type without loss of precision + double integral; // integral part + double fractional = std::modf(number, &integral); // fractional part + if (fractional == 0.0 && integral >= std::numeric_limits<int>::min() && integral <= std::numeric_limits<int>::max()) + value = (int)integral; + else + value = number; + } + else + { + value = number; + } + + pos += newPos - startPos; + return value; + } + + CValue parseStringFromJSON(const std::string& str, int& pos) + { + // skip '\"' cause it has already been checked + pos++; + std::string result; + while (pos < str.size() && str[pos] != '\"') + { + // any non-escaped control characters are not allowed + if (str[pos] < 0x20) + return CValue(); + + if (str[pos] != '\\') + { + result += str[pos++]; + } + else + { + pos++; + if (pos >= str.size()) + return CValue(); + + char ch = str[pos++]; + if (ch == '\\' || ch == '\"' || ch == '/') + { + result += ch; + } + else if (ch == 'b') + { + result += '\b'; + } + else if (ch == 't') + { + result += '\t'; + } + else if (ch == 'n') + { + result += '\n'; + } + else if (ch == 'f') + { + result += '\f'; + } + else if (ch == 'r') + { + result += '\r'; + } + else if (ch == 'u') + { + if (str.size() - pos < 4) + return CValue(); + // TODO: support unicode symbols with codes > U+0020 + if (str[pos] != '0' || str[pos + 1] != '0') + return CValue(); + pos += 2; + std::string strHex = str.substr(pos, 2); + pos += 2; + // std::stoi throws std::invalid_argument if string is invalid + try + { + std::size_t count; + char symbol = (char)std::stoi(strHex, &count, 16); + if (count < 2) + return CValue(); + + result += symbol; + } + catch (std::invalid_argument& e) + { + return CValue(); + } + } + else + { + return CValue(); + } + } + } + // if did not encounter closing qoutes, return undefined + if (pos == str.size()) + return CValue(); + pos++; + + return result; + } + + // parse one value of JSON-string `str` starting from `pos` + CValue valueFromJSON(const std::string& str, int& pos); + + CValue parseArrayFromJSON(const std::string& str, int& pos) + { + // skip opening bracket '[' cause it has already been checked + pos++; + // handle first element separately to get pattern: [(firstValue)(,value)(,value)...] + CValue firstValue = valueFromJSON(str, pos); + if (firstValue.IsUndefined()) + { + if (pos < str.size() && str[pos] == ']') + { + pos++; + return CValue::CreateArray(0); + } + else + { + return CValue(); + } + } + + std::vector<CValue> values; + values.emplace_back(firstValue); + while (skipWhitespaces(str, pos) && str[pos] != ']') + { + // expect ',' + if (str[pos] != ',') + return CValue(); + pos++; + // expect value + CValue value = valueFromJSON(str, pos); + if (value.IsUndefined()) + return CValue(); + values.emplace_back(value); + } + // if did not encounter closing bracket ']', return undefined + if (pos == str.size()) + return CValue(); + pos++; + + // copy values from vector to CValue array + CValue result = CValue::CreateArray(values.size()); + for (int i = 0; i < values.size(); i++) + { + result[i] = values[i]; + } + + return result; + } + + std::pair<std::string, CValue> parseKeyValuePair(const std::string& str, int& pos) + { + std::pair<std::string, CValue> result; + + if (!skipWhitespaces(str, pos) || str[pos] != '\"') + return result; + // parse key + CValue key = parseStringFromJSON(str, pos); + if (key.IsUndefined()) + return result; + result.first = key.ToStringA(); + // expect ':' + if (!skipWhitespaces(str, pos) || str[pos] != ':') + return result; + pos++; + // parse value + CValue value = valueFromJSON(str, pos); + if (value.IsUndefined()) + return result; + result.second = value; + + return result; + } + + CValue parseObjectFromJSON(const std::string& str, int& pos) + { + CValue result = CValue::CreateObject(); + // skip opening curly brace '{' cause it has already been checked + pos++; + // handle first key-value pair separately to get pattern: [(firstKey:firstValue)(,key:value)(,key:value)...] + std::pair<std::string, CValue> keyValue = parseKeyValuePair(str, pos); + // if value is undefined, then something went wrong or object is empty + if (keyValue.second.IsUndefined()) + { + if (pos < str.size() && str[pos] == '}' && keyValue.first.empty()) + { + pos++; + return result; + } + else + { + return CValue(); + } + } + + result[keyValue.first.c_str()] = keyValue.second; + while (skipWhitespaces(str, pos) && str[pos] != '}') + { + // expect ',' + if (str[pos] != ',') + return CValue(); + pos++; + // expect key-value pair + std::pair<std::string, CValue> keyValue = parseKeyValuePair(str, pos); + if (keyValue.second.IsUndefined()) + return CValue(); + result[keyValue.first.c_str()] = keyValue.second; + } + // if did not encounter closing curly brace '}', return undefined + if (pos == str.size()) + return CValue(); + pos++; + + return result; + } + + CValue valueFromJSON(const std::string& str, int& pos) + { + if (!skipWhitespaces(str, pos)) + return CValue(); + + CValue value; + char ch = str[pos]; + if (ch == '\"') + { + // string + value = parseStringFromJSON(str, pos); + } + else if (ch == '[') + { + // array + value = parseArrayFromJSON(str, pos); + } + else if (ch == '{') + { + // object + value = parseObjectFromJSON(str, pos); + } + else if (ch == 'n') + { + // null + if (str.substr(pos, 4) == "null") + value = CValue::CreateNull(); + else + return CValue(); + pos += 4; + } + else if (ch == 't') + { + // true (bool) + if (str.substr(pos, 4) == "true") + value = true; + else + return CValue(); + pos += 4; + } + else if (ch == 'f') + { + // false (bool) + if (str.substr(pos, 5) == "false") + value = false; + else + return CValue(); + pos += 5; + } + else if (ch == '-' || (ch >= '0' && ch <= '9')) + { + value = parseNumberFromJSON(str, pos); + } + else + { + return CValue(); + } + + return value; + } + } + + CValue CValue::FromJSON(const std::string& jsonString) + { + int pos = 0; + CValue value = valueFromJSON(jsonString, pos); + // if there are still some non-space characters after the value has been parsed, + // the JSON-string is considered invalid + if (skipWhitespaces(jsonString, pos)) + return CValue(); + + return value; + } + + CValueRef::CValueRef(const CValueRef& other) : IValue(other.m_internal) + { + } + + CValueRef::CValueRef(const CValue& value) : IValue(value.m_internal) + { + } + + CValueRef::~CValueRef() + { + } + + CValueRef& CValueRef::operator=(const CValueRef& other) + { + // not reassign the pointer, but copy its content! + *m_internal = *other.m_internal; + return *this; + } + + CValueRef& CValueRef::operator=(const CValue& value) + { + // not reassign the pointer, but copy its content! + *m_internal = *value.m_internal; + return *this; + } +} diff --git a/DesktopEditor/doctrenderer/json/json.h b/DesktopEditor/doctrenderer/json/json.h new file mode 100644 index 00000000000..429a3db0201 --- /dev/null +++ b/DesktopEditor/doctrenderer/json/json.h @@ -0,0 +1,365 @@ +#ifndef JSON_H_ +#define JSON_H_ + +#include <initializer_list> +#include <memory> +#include <string> +#include <vector> + +#ifndef JSON_DECL +#ifdef JSBASE_NO_USE_DYNAMIC_LIBRARY +#define JSON_DECL +#else +#include "../../common/base_export.h" +#ifdef JSBASE_USE_DYNAMIC_LIBRARY_BUILDING +#define JSON_DECL Q_DECL_EXPORT +#else +#define JSON_DECL Q_DECL_IMPORT +#endif +#endif +#endif + +// uncomment to enable exceptions throwing +// #define JSON_DEBUG + +#ifdef JSON_DEBUG +#include <stdexcept> +#endif + +namespace NSJSON +{ + typedef unsigned char BYTE; + + enum class ImageFormat + { + ifRGBA, + ifBGRA, + ifARGB, + ifInvalid + }; + + class CValue; + class CValueRef; + class CTypedValue; + // Main value interface. + // This class provide interface to work with each type of values. + class JSON_DECL IValue + { + protected: + IValue(); + IValue(const std::shared_ptr<CTypedValue>& internal); + ~IValue(); + + // Disable copy for this class (implemented in heirs) + IValue(const IValue& other) = delete; + IValue& operator=(const IValue& other) = delete; + + public: + // TYPE CHECKS + /** + * Returns true if the value is undefined. + */ + bool IsUndefined() const; + /** + * Returns true if the value is null. + */ + bool IsNull() const; + /** + * Returns true if the value is not undefined or null. + */ + bool IsInit() const; + /** + * Returns true if the value is a boolean value. + */ + bool IsBool() const; + /** + * Returns true if the value is an integer. + */ + bool IsInt() const; + /** + * Returns true if the value is a double value. + */ + bool IsDouble() const; + /** + * Returns true if the value is a string. + */ + bool IsString() const; + /** + * Returns true if the value is an array. + */ + bool IsArray() const; + /** + * Returns true if the value is a typed array. + */ + bool IsTypedArray() const; + /** + * Returns true if the value is an object. + */ + bool IsObject() const; + /** + * Returns true if the value is an image. + */ + bool IsImage() const; + + // FUNCTIONS FOR WORKING WITH PRIMITIVE VALUES + /** + * Converts this value to a boolean value. + * @returns Corresponding boolean value. If the value is not a boolean, returns false instead. + */ + bool ToBool() const; + /** + * Converts this value to an integer. + * @returns Corresponding integer value. If the value is not a number, returns 0 instead. + */ + int ToInt() const; + /** + * Converts this value to a double value. + * @returns Corresponding double value. If the value is not a number, returns 0.0 instead. + */ + double ToDouble() const; + /** + * Converts this value to a std::string. + * @returns Corresponding std::string. If the value is not a string, returns empty string instead. + */ + std::string ToStringA() const; + /** + * Converts this value to a wstring. + * @returns Corresponding std::wstring. If the value is not a string, returns empty string instead. + */ + std::wstring ToStringW() const; + + // Type cast operators work the same way as conversion functions + operator bool() const; + operator int() const; + operator double() const; + operator std::string() const; + operator std::wstring() const; + + public: + // JSON CONVERSION + /** + * Converts this value to a JSON-string. + * @return The JSON-string or empty string in case of errors. + */ + std::string ToJSON(); + + protected: + // Creates a value from primitive types + IValue(bool value); + IValue(int value); + IValue(double value); + IValue(const char* value); + IValue(const std::string& value); + IValue(const wchar_t* value); + IValue(const std::wstring& value); + + public: + // FUNCTIONS FOR WORKING WITH ARRAYS + /** + * Gets lengths of the array/typed array. + * @returns Returns the number of elements in the array or number of bytes in typed array. If current value is not an array/typed array, returns 0. + */ + int GetCount() const; + + /** + * Gets an array value by its index. + * @param index The index of the array value. + * @returns the value in the array. If current value is not an array, returns undefined value. + */ + const CValueRef Get(int index) const; + CValueRef Get(int index); + + // operators [] works the same way as Get(index) + const CValueRef operator[](int index) const; + CValueRef operator[](int index); + + protected: + // create array from initializer list + IValue(std::initializer_list<CValue> elements); + + public: + // FUNCTIONS FOR WORKING WITH TYPED ARRAYS + /** + * Gets data of typed array. + * @return the pointer to memory, allocated for this typed array. If current value is not a typed array, returns nullptr. + */ + const BYTE* GetData() const; + BYTE* GetData(); + + // FUNCTIONS FOR WORKING WITH OBJECTS + /** + * Gets a property of this object. + * @param name The name of the property. + * @returns the value of the object's property. If current value is not an object, returns undefined value. + */ + const CValueRef Get(const char* name) const; + CValueRef Get(const char* name); + + // operators [] works the same way as Get(name) + const CValueRef operator[](const char* name) const; + CValueRef operator[](const char* name); + + /** + * Retrieves all property names from current object. + * @returns a vector containing the names of the properties of this object as strings. If current value is not an object, returns an empty vector. + */ + std::vector<std::string> GetPropertyNames() const; + + // FUNCTIONS FOR WORKING WITH IMAGES + /** + * Gets bits of image. + * @return the pointer to memory, allocated for the image. If current value is not an image, returns nullptr. + */ + const BYTE* GetImageBits() const; + BYTE* GetImageBits(); + /** + * Gets width of the image. + * @returns Returns the width of the image. If current value is not an image, returns 0. + */ + int GetImageWidth() const; + /** + * Gets height of the image. + * @returns Returns the height of the image. If current value is not an image, returns 0. + */ + int GetImageHeight() const; + /** + * Gets format of the image. + * @returns Returns the image format. If current value is not an image, returns ImageFormat::ifInvalid. + */ + ImageFormat GetImageFormat() const; + + /** + * Make image bits external. + */ + void ImageExternalize(); + + /** + * Alloc image bits as internal. + */ + void ImageAlloc(const int& width, const int& height, const ImageFormat& format); + + protected: + std::shared_ptr<CTypedValue> m_internal; + }; + + // Main value implementation + class JSON_DECL CValue : public IValue + { + public: + CValue(); + CValue(const CValue& other); + CValue(const CValueRef& ref); + ~CValue(); + + CValue& operator=(const CValue& other); + CValue& operator=(const CValueRef& ref); + + // PRIMITIVES CONSTRUCTORS + CValue(bool value); + CValue(int value); + CValue(double value); + CValue(const char* value); + CValue(const std::string& value); + CValue(const wchar_t* value); + CValue(const std::wstring& value); + + // ARRAY CONSTRUCTORS + /** + * Creates an array with initializer list syntax (CValue arr = {1, 2, 3}). + * @param elements The elements of an array as an std::initializer_list. + */ + CValue(std::initializer_list<CValue> elements); + /** + * Creates and returns new array. + * @param count The number of elements reserved for the array. + */ + static CValue CreateArray(int count); + + // TYPED ARRAY + /** + * Creates and returns new typed array. + * @param data The pointer to binary data. The pointer should be acquired with AllocTypedArray()! + * @param count The length of an array in bytes. + * @param isExternalize If true the memory block will not be reclaimed when the created typed array is destroyed. + * If this parameter is false then the memory block will be released using FreeTypedArray() during the typed array destruction. + */ + static CValue CreateTypedArray(BYTE* data, int count, bool isExternalize = true); + /** + * Allocates the memory for a typed array by creating a buffer array of the specified size. + * @param size The buffer array size. + */ + static BYTE* AllocTypedArray(size_t size); + /** + * Frees the memory for a typed array. + * @param data The allocated memory to be released. + * @param size The buffer array size. + */ + static void FreeTypedArray(BYTE* data, size_t size); + + // IMAGE + /** + * Creates and returns new image object. + * @param bits The pointer to image data. The pointer should be acquired with AllocImageBits(). + * @param width The width of the image. + * @param height The height of the image. + * @param format The format of the image. + * @param isExternalize If true the memory will not be reclaimed when the created image is destroyed. + * If this parameter is false then the memory will be released using FreeImageBits() during the image object destruction. + */ + static CValue CreateImage(BYTE* bits, int width, int height, ImageFormat format = ImageFormat::ifBGRA, bool isExternalize = true); + static CValue CreateEmptyImage(ImageFormat format = ImageFormat::ifBGRA); + /** + * Allocates the memory for an image. + * @param width The width of the image. + * @param height The height of the image. + */ + static BYTE* AllocImageBits(int width, int height); + /** + * Frees the memory for a image bits. + * @param data The allocated memory to be released. + */ + static void FreeImageBits(BYTE* bits); + + // OBJECT CONSTRUCTOR + /** + * Creates and returns empty object. + */ + static CValue CreateObject(); + + // OTHER FUNCTIONS + /** + * Creates and returns undefined value (the same as CValue()). + */ + static CValue CreateUndefined(); + /** + * Creates and returns null value. + */ + static CValue CreateNull(); + + // JSON CONVERSION + /** + * Creates and returns new value from JSON-string. + * @param jsonString The JSON-string from which new value will be created. + * @returns created value. If JSON-string is invalid, value will be undefined. + */ + static CValue FromJSON(const std::string& jsonString); + + friend class CValueRef; + }; + + // Main value reference implementation + class JSON_DECL CValueRef : public IValue + { + public: + CValueRef(const CValueRef& other); + CValueRef(const CValue& value); + ~CValueRef(); + + CValueRef& operator=(const CValueRef& other); + CValueRef& operator=(const CValue& value); + + friend class CValue; + }; +} + +#endif // JSON_H_ diff --git a/DesktopEditor/doctrenderer/json/json_p.h b/DesktopEditor/doctrenderer/json/json_p.h new file mode 100644 index 00000000000..903dac78450 --- /dev/null +++ b/DesktopEditor/doctrenderer/json/json_p.h @@ -0,0 +1,38 @@ +#ifndef JSON_PRIVATE_H_ +#define JSON_PRIVATE_H_ + +#include <memory> + +namespace NSJSON +{ + class IBaseValue; + // Wrapper around IBaseValue with specific value type + class CTypedValue + { + public: + enum ValueType + { + vtUndefined, + vtNull, + vtPrimitive, + vtArray, + vtTypedArray, + vtObject, + vtImage + }; + + public: + CTypedValue(); + CTypedValue(IBaseValue* value, ValueType type); + ~CTypedValue(); + // default copy behaviour + CTypedValue(const CTypedValue& other) = default; + CTypedValue& operator=(const CTypedValue& other) = default; + + public: + std::shared_ptr<IBaseValue> m_value; + ValueType m_type; + }; +} + +#endif // JSON_PRIVATE_H_ diff --git a/DesktopEditor/doctrenderer/json/json_values.cpp b/DesktopEditor/doctrenderer/json/json_values.cpp new file mode 100644 index 00000000000..bddf10a6602 --- /dev/null +++ b/DesktopEditor/doctrenderer/json/json_values.cpp @@ -0,0 +1,266 @@ +#include "json_values.h" + +// for string <=> wstring conversion +#include "../../common/File.h" + +namespace NSJSON +{ + IBaseValue::IBaseValue() + { + } + + IBaseValue::~IBaseValue() + { + } + + CPrimitive::CPrimitive(bool value) : m_type(ptBoolean) + { + m_bool = value; + } + + CPrimitive::CPrimitive(int value) : m_type(ptInteger) + { + m_int = value; + } + + CPrimitive::CPrimitive(double value) : m_type(ptDouble) + { + m_double = value; + } + + CPrimitive::CPrimitive(const std::string& str) : m_type(ptStringA) + { + new (&m_string) std::string(str); + } + + CPrimitive::CPrimitive(const std::wstring& wstr) : m_type(ptStringW) + { + new (&m_wstring) std::wstring(wstr); + } + + CPrimitive::~CPrimitive() + { + switch (m_type) + { + case ptStringA: + m_string.~basic_string<char>(); + break; + case ptStringW: + m_wstring.~basic_string<wchar_t>(); + break; + default: + break; + } + } + + bool CPrimitive::isBool() const + { + return m_type == ptBoolean; + } + + bool CPrimitive::isInt() const + { + return m_type == ptInteger; + } + + bool CPrimitive::isDouble() const + { + return m_type == ptDouble || m_type == ptInteger; + } + + bool CPrimitive::isStringA() const + { + return m_type == ptStringA; + } + + bool CPrimitive::isStringW() const + { + return m_type == ptStringW; + } + + bool CPrimitive::toBool() const + { + if (m_type == ptBoolean) + return m_bool; +#ifdef JSON_DEBUG + throw std::bad_cast(); +#endif + return false; + } + + int CPrimitive::toInt() const + { + if (m_type == ptInteger) + return m_int; + if (m_type == ptDouble) + return (int)m_double; +#ifdef JSON_DEBUG + throw std::bad_cast(); +#endif + return 0; + } + + double CPrimitive::toDouble() const + { + if (m_type == ptDouble) + return m_double; + if (m_type == ptInteger) + return (double)m_int; +#ifdef JSON_DEBUG + throw std::bad_cast(); +#endif + return 0.0; + } + + std::string CPrimitive::toStringA() const + { + if (m_type == ptStringA) + return m_string; + + if (m_type == ptStringW) + { + return U_TO_UTF8(m_wstring); + } + +#ifdef JSON_DEBUG + throw std::bad_cast(); +#endif + return ""; + } + + std::wstring CPrimitive::toStringW() const + { + if (m_type == ptStringW) + return m_wstring; + + if (m_type == ptStringA) + { + return UTF8_TO_U(m_string); + } + +#ifdef JSON_DEBUG + throw std::bad_cast(); +#endif + return L""; + } + + CArray::CArray(int count) : m_values(count) + { + } + + CArray::CArray(std::initializer_list<CValue> elements) : m_values(elements) + { + } + + CArray::~CArray() + { + } + + int CArray::getCount() const + { + return (int)m_values.size(); + } + + CValue& CArray::get(int index) + { + return m_values[index]; + } + + CTypedArray::CTypedArray(BYTE* data, int len, bool isExternalize) : m_data(data), m_len(len), m_isExternalize(isExternalize) + { + } + + CTypedArray::~CTypedArray() + { + if (!m_isExternalize) + { + CValue::FreeTypedArray(m_data, m_len); + } + } + + BYTE* CTypedArray::getData() + { + return m_data; + } + + int CTypedArray::getCount() const + { + return m_len; + } + + CObject::CObject() + { + } + + CObject::~CObject() + { + } + + CValue& CObject::get(const std::string& name) + { + return m_values[name]; + } + + std::vector<std::string> CObject::getPropertyNames() + { + std::vector<std::string> ret; + for (const storage_t::value_type& entry : m_values) + { + if (!entry.second.IsUndefined()) + ret.push_back(entry.first); + } + return ret; + } + + CImage::CImage(BYTE* bits, const int& width, const int& height, const ImageFormat& format, const bool& isExternalize) : + m_bits(bits), m_width(width), m_height(height), m_format(format), m_isExternalize(isExternalize) + { + } + + CImage::~CImage() + { + if (!m_isExternalize) + { + CValue::FreeImageBits(m_bits); + } + } + + void CImage::alloc(const int& width, const int& height, const ImageFormat& format) + { + if (!m_isExternalize && m_bits) + { + CValue::FreeImageBits(m_bits); + } + + m_bits = CValue::AllocImageBits(width, height); + m_width = width; + m_height = height; + m_format = format; + m_isExternalize = false; + } + + BYTE* CImage::getBits() + { + return m_bits; + } + + int CImage::getWidth() + { + return m_width; + } + + int CImage::getHeight() + { + return m_height; + } + + ImageFormat CImage::getFormat() + { + return m_format; + } + + void CImage::externalize() + { + m_isExternalize = true; + } +} diff --git a/DesktopEditor/doctrenderer/json/json_values.h b/DesktopEditor/doctrenderer/json/json_values.h new file mode 100644 index 00000000000..af5693d57d3 --- /dev/null +++ b/DesktopEditor/doctrenderer/json/json_values.h @@ -0,0 +1,140 @@ +#ifndef JSON_VALUES_H_ +#define JSON_VALUES_H_ + +#include <string> +#include <unordered_map> +#include <vector> + +#include "json.h" + +namespace NSJSON +{ + class IBaseValue + { + public: + IBaseValue(); + virtual ~IBaseValue(); + }; + + class CPrimitive : public IBaseValue + { + private: + enum PrimitiveType + { + ptBoolean, + ptInteger, + ptDouble, + ptStringA, + ptStringW + }; + + public: + CPrimitive(bool value); + CPrimitive(int value); + CPrimitive(double value); + CPrimitive(const std::string& str); + CPrimitive(const std::wstring& wstr); + ~CPrimitive(); + + // disable copy + CPrimitive(const CPrimitive& other) = delete; + CPrimitive& operator=(const CPrimitive& other) = delete; + + // type check + bool isBool() const; + bool isInt() const; + bool isDouble() const; + bool isStringA() const; + bool isStringW() const; + + // getters + bool toBool() const; + int toInt() const; + double toDouble() const; + std::string toStringA() const; + std::wstring toStringW() const; + + private: + union + { + bool m_bool; + int m_int; + double m_double; + std::string m_string; + std::wstring m_wstring; + }; + PrimitiveType m_type; + }; + + class CArray : public IBaseValue + { + public: + CArray(int count); + CArray(std::initializer_list<CValue> elements); + ~CArray(); + + public: + int getCount() const; + CValue& get(int index); + + private: + std::vector<CValue> m_values; + }; + + class CTypedArray : public IBaseValue + { + public: + CTypedArray(BYTE* data, int len, bool isExternalize = true); + ~CTypedArray(); + + public: + BYTE* getData(); + int getCount() const; + + private: + BYTE* m_data; + int m_len; + bool m_isExternalize; + }; + + class CObject : public IBaseValue + { + private: + using storage_t = std::unordered_map<std::string, CValue>; + + public: + CObject(); + ~CObject(); + + public: + CValue& get(const std::string& name); + std::vector<std::string> getPropertyNames(); + + private: + storage_t m_values; + }; + + class CImage : public IBaseValue + { + public: + CImage(BYTE* bits, const int& width, const int& height, const ImageFormat& format, const bool& isExternalize = true); + ~CImage(); + + public: + BYTE* getBits(); + int getWidth(); + int getHeight(); + ImageFormat getFormat(); + void externalize(); + void alloc(const int& width, const int& height, const ImageFormat& format); + + private: + BYTE* m_bits; + int m_width; + int m_height; + ImageFormat m_format; + bool m_isExternalize; + }; +} // namespace + +#endif // JSON_VALUES_H_ diff --git a/DesktopEditor/doctrenderer/json/serialization.h b/DesktopEditor/doctrenderer/json/serialization.h new file mode 100644 index 00000000000..4f681c3503f --- /dev/null +++ b/DesktopEditor/doctrenderer/json/serialization.h @@ -0,0 +1,238 @@ +#ifndef SERIALIZATION_H_ +#define SERIALIZATION_H_ + +#include "json.h" +#include "../js_internal/js_base.h" +#include "../embed/GraphicsEmbed.h" + +#include <cmath> + +class CAppImageTo : public CGraphicsAppImage +{ +private: + NSJSON::CValueRef* m_image; + +public: + CAppImageTo(const NSJSON::CValue& image) : CGraphicsAppImage() + { + m_image = new NSJSON::CValueRef(image); + } + virtual ~CAppImageTo() + { + if (m_image) + delete m_image; + } + +public: + virtual unsigned char* GetBits(int& w, int& h) + { + unsigned char* bits = m_image->GetImageBits(); + if (NULL != bits) + { + w = m_image->GetImageWidth(); + h = m_image->GetImageHeight(); + } + return bits; + } + virtual unsigned char* AllocBits(const int& w, const int& h) + { + m_image->ImageAlloc(w, h, GetRgba() ? NSJSON::ImageFormat::ifRGBA : NSJSON::ImageFormat::ifBGRA); + return m_image->GetImageBits(); + } +}; + +class CAppImageFrom : public CGraphicsAppImage +{ +public: + unsigned char* m_pData; + int m_nW; + int m_nH; +public: + CAppImageFrom() : CGraphicsAppImage() + { + m_pData = NULL; + m_nW = 0; + m_nH = 0; + } + virtual ~CAppImageFrom() + { + } + +public: + virtual unsigned char* GetBits(int& w, int& h) + { + return m_pData; + } + virtual unsigned char* AllocBits(const int& w, const int& h) + { + m_nW = w; + m_nH = h; + m_pData = NSJSON::CValue::AllocImageBits(w, h); + return m_pData; + } +}; + +namespace NSJSON +{ + static JSSmart<NSJSBase::CJSValue> toJS(const CValue& value) + { + if (value.IsUndefined()) + return NSJSBase::CJSContext::createUndefined(); + if (value.IsNull()) + return NSJSBase::CJSContext::createNull(); + + JSSmart<NSJSBase::CJSValue> ret; + // handle primitive types first, as they are most commonly used + if (value.IsBool()) + { + ret = NSJSBase::CJSContext::createBool((bool)value); + } + else if (value.IsInt()) + { + ret = NSJSBase::CJSContext::createInt((int)value); + } + else if (value.IsDouble()) + { + ret = NSJSBase::CJSContext::createDouble((double)value); + } + else if (value.IsString()) + { + ret = NSJSBase::CJSContext::createString(value.ToStringA()); + } + // arrays + else if (value.IsArray()) + { + const int len = value.GetCount(); + JSSmart<NSJSBase::CJSArray> jsArr = NSJSBase::CJSContext::createArray(len); + for (int i = 0; i < len; i++) + { + jsArr->set(i, toJS(value[i])); + } + ret = jsArr->toValue(); + } + // typed arrays + else if (value.IsTypedArray()) + { + JSSmart<NSJSBase::CJSTypedArray> jsTypedArr = NSJSBase::CJSContext::createUint8Array(const_cast<BYTE*>(value.GetData()), value.GetCount()); + ret = jsTypedArr->toValue(); + } + else if (value.IsImage()) + { + JSSmart<CJSObject> wrap = CJSContext::createEmbedObject("CGraphicsEmbed"); + ((CGraphicsEmbed*)wrap->getNative())->SetAppImage(new CAppImageTo(value)); + ret = wrap->toValue(); + } + // objects (there is no need for IsObject()) + else + { + JSSmart<NSJSBase::CJSObject> jsObj = NSJSBase::CJSContext::createObject(); + std::vector<std::string> properties = value.GetPropertyNames(); + for (const std::string& name : properties) + { + JSSmart<NSJSBase::CJSValue> jsValue = toJS(value[name.c_str()]); + jsObj->set(name.c_str(), jsValue); + } + ret = jsObj->toValue(); + } + + return ret; + } + + static CValue fromJS(JSSmart<NSJSBase::CJSValue> jsValue) + { + if (!jsValue.is_init()) + return CValue::CreateUndefined(); + if (jsValue->isUndefined()) + return CValue::CreateUndefined(); + if (jsValue->isNull()) + return CValue::CreateNull(); + + CValue ret; + // handle primitive types first, as they are most commonly used + if (jsValue->isBool()) + { + ret = CValue(jsValue->toBool()); + } + else if (jsValue->isNumber()) + { + double number = jsValue->toDouble(); + if (std::isfinite(number)) + { + // check if number is an integer or double + double integral; // integral part + double fractional = std::modf(number, &integral); // fractional part + // TODO: this may not work for non-32 bit integers + if (fractional == 0.0 && integral >= INT_MIN && integral <= INT_MAX) + ret = (int)integral; + else + ret = number; + } + else + { + // handle NaN, inf, -inf + ret = number; + } + } + else if (jsValue->isString()) + { + // convert all strings to std::wstring, because in JS all strings are encoded in UTF-16 + ret = jsValue->toStringW(); + } + // arrays + else if (jsValue->isArray()) + { + JSSmart<NSJSBase::CJSArray> jsArr = jsValue->toArray(); + const int len = jsArr->getCount(); + ret = CValue::CreateArray(len); + for (int i = 0; i < len; i++) + { + JSSmart<NSJSBase::CJSValue> jsElement = jsArr->get(i); + ret[i] = fromJS(jsElement); + } + } + // typed arrays + else if (jsValue->isTypedArray()) + { + JSSmart<NSJSBase::CJSTypedArray> jsTypedArr = jsValue->toTypedArray(); + const int len = jsTypedArr->getCount(); + BYTE* data = jsTypedArr->getData().Data; + ret = CValue::CreateTypedArray(data, len); + } + // objects + else if (jsValue->isObject()) + { + JSSmart<NSJSBase::CJSObject> jsObj = jsValue->toObject(); + + CJSEmbedObject* pNative = jsObj->getNative(); + if (pNative != NULL) + { + CGraphicsEmbed* pGrEmbed = dynamic_cast<CGraphicsEmbed*>(pNative); + if (pGrEmbed) + { + CAppImageFrom* pAppImage = dynamic_cast<CAppImageFrom*>(pGrEmbed->GetAppImage()); + if (pAppImage) + { + return NSJSON::CValue::CreateImage(pAppImage->m_pData, + pAppImage->m_nW, + pAppImage->m_nH, + pAppImage->GetRgba() ? ImageFormat::ifRGBA : ImageFormat::ifBGRA, + false); + } + } + } + + std::vector<std::string> properties = jsObj->getPropertyNames(); + ret = CValue::CreateObject(); + for (const std::string& name : properties) + { + JSSmart<NSJSBase::CJSValue> jsPropertyValue = jsObj->get(name.c_str()); + ret[name.c_str()] = fromJS(jsPropertyValue); + } + } + // else the type is not supported and will be converted as undefined value + + return ret; + } +} + +#endif // SERIALIZATION_H_ diff --git a/DesktopEditor/doctrenderer/nativecontrol.cpp b/DesktopEditor/doctrenderer/nativecontrol.cpp index ac14488e95e..81b9a66ab7b 100644 --- a/DesktopEditor/doctrenderer/nativecontrol.cpp +++ b/DesktopEditor/doctrenderer/nativecontrol.cpp @@ -33,6 +33,7 @@ #include "../../DesktopEditor/raster/ImageFileFormatChecker.h" #include "../../DesktopEditor/raster/BgraFrame.h" #include "../../Common/Network/FileTransporter/include/FileTransporter.h" +#include "server.h" CImagesWorker::CImagesWorker(const std::wstring& sFolder) { @@ -42,6 +43,11 @@ CImagesWorker::CImagesWorker(const std::wstring& sFolder) } std::wstring CImagesWorker::GetImageLocal(const std::wstring& sUrl) { + if (CServerInstance::getInstance().IsEnable()) + { + if (!CServerInstance::getInstance().CheckTmpDirectory(sUrl)) + return L"error"; + } std::wstring sExt = NSFile::GetFileExtention(sUrl); std::wstring sRet = L"image" + std::to_wstring(m_nIndex++) + L"." + sExt; m_mapImages.insert(std::make_pair(sUrl, sRet)); diff --git a/DesktopEditor/doctrenderer/nativecontrol.h b/DesktopEditor/doctrenderer/nativecontrol.h index 34b1225a364..ba7ea430cf8 100644 --- a/DesktopEditor/doctrenderer/nativecontrol.h +++ b/DesktopEditor/doctrenderer/nativecontrol.h @@ -1039,108 +1039,6 @@ class CLoggerSpeed #endif ////////////////////////////////////////////////////////////////////////////// -#if 0 -class CSnapshotScript -{ -public: - bool m_bIsExist; - v8::StartupData m_oStartupData; - - CSnapshotScript(const std::wstring& sDir = L"") - { - m_bIsExist = false; - m_oStartupData.data = NULL; - m_oStartupData.raw_size = 0; - - std::wstring sFile = sDir + L"/heap_snapshot.bin"; - if (NSFile::CFileBinary::Exists(sFile)) - { - m_bIsExist = true; - - NSFile::CFileBinary oFile; - oFile.OpenFile(sFile); - m_oStartupData.raw_size = (int)oFile.GetFileSize(); - m_oStartupData.data = new char[m_oStartupData.raw_size]; - - DWORD dwRead = 0; - oFile.ReadFile((BYTE*)m_oStartupData.data, (DWORD)m_oStartupData.raw_size, dwRead); - oFile.CloseFile(); - } - } - - bool Generate(const std::string& sScript) - { - m_oStartupData = {NULL, 0}; - { - v8::SnapshotCreator snapshot_creator; - // Obtain an isolate provided by SnapshotCreator. - v8::Isolate* isolate = snapshot_creator.GetIsolate(); - { - v8::HandleScope scope(isolate); - // Create a new context and optionally run some script. - v8::Local<v8::Context> context = v8::Context::New(isolate); - //v8::Context::Scope context_scope(context); - - if (!RunExtraCode(isolate, context, sScript.c_str(), "<embedded>")) - return false; - - // Add the possibly customized context to the SnapshotCreator. - snapshot_creator.SetDefaultContext(context); - } - // Use the SnapshotCreator to create the snapshot blob. - m_oStartupData = snapshot_creator.CreateBlob(v8::SnapshotCreator::FunctionCodeHandling::kClear); - } - return true; - } - - void Save(const std::wstring& sDir) - { - if (m_oStartupData.data == NULL) - return; - - std::wstring sFile = sDir + L"/heap_snapshot.bin"; - NSFile::CFileBinary oFile; - oFile.CreateFile(sFile); - oFile.WriteFile((BYTE*)m_oStartupData.data, (DWORD)m_oStartupData.raw_size); - oFile.CloseFile(); - } - - bool RunExtraCode(v8::Isolate* isolate, v8::Local<v8::Context> context, const char* utf8_source, const char* name) - { - // Run custom script if provided. - v8::TryCatch try_catch(isolate); - - v8::Local<v8::String> source_string; - if (!v8::String::NewFromUtf8(isolate, utf8_source, v8::NewStringType::kNormal).ToLocal(&source_string)) - return false; - - v8::Local<v8::String> resource_name = v8::String::NewFromUtf8(isolate, name, v8::NewStringType::kNormal).ToLocalChecked(); - - v8::ScriptOrigin origin(resource_name); - v8::ScriptCompiler::Source source(source_string, origin); - v8::Local<v8::Script> script; - - bool bRet = v8::ScriptCompiler::Compile(context, &source).ToLocal(&script); - - if (try_catch.HasCaught()) - { - std::string strCode = to_cstringA(try_catch.Message()->GetSourceLine()); - std::string strException = to_cstringA(try_catch.Message()->Get()); - return false; - } - - script->Run(); - - if (try_catch.HasCaught()) - { - std::string strCode = to_cstringA(try_catch.Message()->GetSourceLine()); - std::string strException = to_cstringA(try_catch.Message()->Get()); - return false; - } - return true; - } -}; -#endif bool Doct_renderer_SaveFile_ForBuilder(int nFormat, const std::wstring& strDstFile, NSNativeControl::CNativeControl* pNative, diff --git a/DesktopEditor/doctrenderer/server.h b/DesktopEditor/doctrenderer/server.h new file mode 100644 index 00000000000..1599e41fd94 --- /dev/null +++ b/DesktopEditor/doctrenderer/server.h @@ -0,0 +1,98 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#ifndef SERVER_SETTINGS_H +#define SERVER_SETTINGS_H + +#include <string> +#include <map> +#include "../common/File.h" +#include "../common/StringBuilder.h" +#include <iostream> + +// class for server version (disable local files and etc) +class CServerInstance +{ +private: + bool m_bIsEnabled; + std::map<std::wstring, bool> m_arMapTmpFiles; + + CServerInstance() + { + m_bIsEnabled = false; + } + +public: + static CServerInstance& getInstance() + { + static CServerInstance server; + return server; + } + + void Enable(const bool& enabled) + { + m_bIsEnabled = enabled; + } + + bool IsEnable() + { + return m_bIsEnabled; + } + + void AddTmpFile(const std::wstring& sFolder) + { + std::wstring sDirectory = sFolder + L"/media"; + NSStringUtils::string_replace(sDirectory, L"\\", L"/"); + std::map<std::wstring, bool>::iterator findDir = m_arMapTmpFiles.find(sDirectory); + if (findDir == m_arMapTmpFiles.end()) + m_arMapTmpFiles.insert(std::make_pair(sDirectory, true)); + } + + void RemoveTmpFile(const std::wstring& sFolder) + { + std::wstring sDirectory = sFolder + L"/media"; + NSStringUtils::string_replace(sDirectory, L"\\", L"/"); + std::map<std::wstring, bool>::iterator findDir = m_arMapTmpFiles.find(sDirectory); + if (findDir != m_arMapTmpFiles.end()) + m_arMapTmpFiles.erase(findDir); + } + + bool CheckTmpDirectory(const std::wstring& sFile) + { + std::wstring sDirectory = NSFile::GetDirectoryName(sFile); + NSStringUtils::string_replace(sDirectory, L"\\", L"/"); + std::map<std::wstring, bool>::iterator findDir = m_arMapTmpFiles.find(sDirectory); + return (findDir != m_arMapTmpFiles.end()) ? true : false; + } +}; + + +#endif // SERVER_SETTINGS_H diff --git a/DesktopEditor/doctrenderer/test/internal/Embed.cpp b/DesktopEditor/doctrenderer/test/embed/external/Embed.cpp similarity index 100% rename from DesktopEditor/doctrenderer/test/internal/Embed.cpp rename to DesktopEditor/doctrenderer/test/embed/external/Embed.cpp diff --git a/DesktopEditor/doctrenderer/test/internal/Embed.h b/DesktopEditor/doctrenderer/test/embed/external/Embed.h similarity index 94% rename from DesktopEditor/doctrenderer/test/internal/Embed.h rename to DesktopEditor/doctrenderer/test/embed/external/Embed.h index 80f06776a7c..2d67bf898a3 100644 --- a/DesktopEditor/doctrenderer/test/internal/Embed.h +++ b/DesktopEditor/doctrenderer/test/embed/external/Embed.h @@ -1,7 +1,7 @@ #ifndef _BUILD_NATIVE_HASH_EMBED_H_ #define _BUILD_NATIVE_HASH_EMBED_H_ -#include "../../js_internal/js_base.h" +#include "js_internal/js_base.h" #define ENABLE_SUM_DEL #define ENABLE_GET diff --git a/DesktopEditor/doctrenderer/test/internal/jsc/jsc_Embed.mm b/DesktopEditor/doctrenderer/test/embed/external/jsc/jsc_Embed.mm similarity index 100% rename from DesktopEditor/doctrenderer/test/internal/jsc/jsc_Embed.mm rename to DesktopEditor/doctrenderer/test/embed/external/jsc/jsc_Embed.mm diff --git a/DesktopEditor/doctrenderer/test/internal/main.cpp b/DesktopEditor/doctrenderer/test/embed/external/main.cpp similarity index 100% rename from DesktopEditor/doctrenderer/test/internal/main.cpp rename to DesktopEditor/doctrenderer/test/embed/external/main.cpp diff --git a/DesktopEditor/doctrenderer/test/internal/test_internal.pro b/DesktopEditor/doctrenderer/test/embed/external/test.pro similarity index 86% rename from DesktopEditor/doctrenderer/test/internal/test_internal.pro rename to DesktopEditor/doctrenderer/test/embed/external/test.pro index aa25c41f1f2..6d2b027065d 100644 --- a/DesktopEditor/doctrenderer/test/internal/test_internal.pro +++ b/DesktopEditor/doctrenderer/test/embed/external/test.pro @@ -9,7 +9,7 @@ TEMPLATE = app CONFIG += core_static_link_libstd -CORE_ROOT_DIR = $$PWD/../../../../../core +CORE_ROOT_DIR = $$PWD/../../../../../../core PWD_ROOT_DIR = $$PWD include($$CORE_ROOT_DIR/Common/base.pri) @@ -18,7 +18,7 @@ include($$CORE_ROOT_DIR/DesktopEditor/doctrenderer/js_internal/js_base_embed.pri ############### destination path ############### DESTDIR = $$PWD/build ################################################ -INCLUDEPATH += ../.. +INCLUDEPATH += $$CORE_ROOT_DIR/DesktopEditor/doctrenderer DEFINES += CURR_DIR=\\\"$$PWD_ROOT_DIR\\\" diff --git a/DesktopEditor/doctrenderer/test/internal/v8/v8_Embed.cpp b/DesktopEditor/doctrenderer/test/embed/external/v8/v8_Embed.cpp similarity index 100% rename from DesktopEditor/doctrenderer/test/internal/v8/v8_Embed.cpp rename to DesktopEditor/doctrenderer/test/embed/external/v8/v8_Embed.cpp diff --git a/DesktopEditor/doctrenderer/test/embed/test.cpp b/DesktopEditor/doctrenderer/test/embed/internal/hash/main.cpp similarity index 100% rename from DesktopEditor/doctrenderer/test/embed/test.cpp rename to DesktopEditor/doctrenderer/test/embed/internal/hash/main.cpp diff --git a/DesktopEditor/doctrenderer/test/embed/test_embed.pro b/DesktopEditor/doctrenderer/test/embed/internal/hash/test.pro similarity index 76% rename from DesktopEditor/doctrenderer/test/embed/test_embed.pro rename to DesktopEditor/doctrenderer/test/embed/internal/hash/test.pro index b088bd08b73..9f1ad28169a 100644 --- a/DesktopEditor/doctrenderer/test/embed/test_embed.pro +++ b/DesktopEditor/doctrenderer/test/embed/internal/hash/test.pro @@ -1,32 +1,32 @@ -QT -= core -QT -= gui - -TARGET = test -CONFIG += console -CONFIG -= app_bundle - -TEMPLATE = app - -CONFIG += core_static_link_libstd - -CORE_ROOT_DIR = $$PWD/../../../../../core -CORE_3DPARTY_DIR = $$CORE_ROOT_DIR/Common/3dParty -PWD_ROOT_DIR = $$PWD - -include($$CORE_ROOT_DIR/Common/base.pri) -include($$CORE_3DPARTY_DIR/googletest/googletest.pri) - -DESTDIR = $$PWD/build - -INCLUDEPATH += ../.. - -ADD_DEPENDENCY(doctrenderer) - -core_linux { - LIBS += -Wl,-unresolved-symbols=ignore-in-shared-libs - LIBS += -ldl -} - -SOURCES += \ - test.cpp - +QT -= core +QT -= gui + +TARGET = test +CONFIG += console +CONFIG -= app_bundle + +TEMPLATE = app + +CONFIG += core_static_link_libstd + +CORE_ROOT_DIR = $$PWD/../../../../../../../core +CORE_3DPARTY_DIR = $$CORE_ROOT_DIR/Common/3dParty +PWD_ROOT_DIR = $$PWD + +include($$CORE_ROOT_DIR/Common/base.pri) +include($$CORE_3DPARTY_DIR/googletest/googletest.pri) + +DESTDIR = $$PWD/build + +INCLUDEPATH += $$CORE_ROOT_DIR/DesktopEditor/doctrenderer + +ADD_DEPENDENCY(doctrenderer) + +core_linux { + LIBS += -Wl,-unresolved-symbols=ignore-in-shared-libs + LIBS += -ldl +} + +SOURCES += \ + main.cpp + diff --git a/DesktopEditor/doctrenderer/test/js_internal/main.cpp b/DesktopEditor/doctrenderer/test/js_internal/main.cpp new file mode 100644 index 00000000000..606c6c991d4 --- /dev/null +++ b/DesktopEditor/doctrenderer/test/js_internal/main.cpp @@ -0,0 +1,316 @@ +#include "js_internal/js_base.h" + +#ifdef JS_INTERNAL_GOOGLE_TEST +#include "gtest/gtest.h" +#include <algorithm> +#else +#include <iostream> +#endif + +using namespace NSJSBase; + +#ifdef JS_INTERNAL_GOOGLE_TEST +// CJSObject::getPropertyNames() tests +// run with "--gtest_filter=CGetPropertyNamesTest.*" to run only this test suite +class CGetPropertyNamesTest : public testing::Test +{ +public: + void SetUp() override + { + // create and enter context + m_pContext = new CJSContext(); + m_pContext->Enter(); + } + + void TearDown() override + { + m_pContext->Exit(); + } + + std::vector<std::string> getObjectProperties(const std::string& objLiteral) + { + JSSmart<CJSObject> obj = m_pContext->runScript("(() => { return " + objLiteral + ";})();")->toObject(); + return obj->getPropertyNames(); + } + + // The order of properties of object in JS is not always the same as insertion order. + // So this function sorts and compares two vectors with property names. + bool compare(std::vector<std::string>& lhs, std::vector<std::string>& rhs) + { + std::sort(lhs.begin(), lhs.end()); + std::sort(rhs.begin(), rhs.end()); + return lhs == rhs; + } + + std::string printInfo(const std::string& info, const std::vector<std::string>& names) + { + std::string ret = info; + ret += '['; + const int lenResult = names.size(); + for (int i = 0; i < lenResult; i++) + { + ret += "\"" + names[i] + "\""; + if (i < lenResult - 1) + ret += ','; + } + ret += "]\n"; + return ret; + } + +public: + JSSmart<CJSContext> m_pContext; +}; + + +TEST_F(CGetPropertyNamesTest, normal_object) +{ + std::vector<std::string> result = getObjectProperties("{number: 42, name: 'foo', arr: [1, 'abc', 2, 3], func() { return 'bar'; }}"); + std::vector<std::string> expected = {"number", "name", "arr", "func"}; + EXPECT_TRUE(compare(result, expected)) << printInfo("Actual: ", result) << printInfo("Expected: ", expected); +} + +TEST_F(CGetPropertyNamesTest, empty_object) +{ + std::vector<std::string> result = getObjectProperties("{}"); + std::vector<std::string> expected = {}; + EXPECT_TRUE(compare(result, expected)) << printInfo("Actual: ", result) << printInfo("Expected: ", expected); +} + +TEST_F(CGetPropertyNamesTest, only_one_function_in_object) +{ + std::vector<std::string> result = getObjectProperties("{add(a, b) { return a + b; }}"); + std::vector<std::string> expected = {"add"}; + EXPECT_TRUE(compare(result, expected)) << printInfo("Actual: ", result) << printInfo("Expected: ", expected); +} + +TEST_F(CGetPropertyNamesTest, inner_object) +{ + std::vector<std::string> result = getObjectProperties("{inner: {number: 42, name: 'foo'}}"); + std::vector<std::string> expected = {"inner"}; + EXPECT_TRUE(compare(result, expected)) << printInfo("Actual: ", result) << printInfo("Expected: ", expected); +} + +TEST_F(CGetPropertyNamesTest, object_with_null_and_undefined_properties) +{ + std::vector<std::string> result = getObjectProperties("{number: null, name: undefined, func() { return 'bar'; }}"); + std::vector<std::string> expected = {"number", "func"}; + EXPECT_TRUE(compare(result, expected)) << printInfo("Actual: ", result) << printInfo("Expected: ", expected); +} + +TEST_F(CGetPropertyNamesTest, object_with_only_undefined_properties) +{ + std::vector<std::string> result = getObjectProperties("{foo: undefined, bar: undefined}"); + std::vector<std::string> expected = {}; + EXPECT_TRUE(compare(result, expected)) << printInfo("Actual: ", result) << printInfo("Expected: ", expected); +} + +TEST_F(CGetPropertyNamesTest, array_as_object) +{ + std::vector<std::string> result = getObjectProperties("{0: 4, 1: 2, 2: undefined, 3: 'foo', 42: 'bar'}"); + std::vector<std::string> expected = {"0", "1", "3", "42"}; + EXPECT_TRUE(compare(result, expected)) << printInfo("Actual: ", result) << printInfo("Expected: ", expected); +} + +TEST_F(CGetPropertyNamesTest, object_with_prototype) +{ + m_pContext->runScript( + "var personPrototype = { greet() { return 'Hello, world!'; } };" + "function Person(name) { this.name = name; }" + ); + + JSSmart<CJSObject> obj = m_pContext->runScript("new Person('Foo');")->toObject(); + std::vector<std::string> result1 = obj->getPropertyNames(); + std::vector<std::string> expected1 = {"name"}; + EXPECT_TRUE(compare(result1, expected1)) << printInfo("Actual: ", result1) << printInfo("Expected: ", expected1); + + m_pContext->runScript("Person.prototype.greet = personPrototype.greet;"); + std::vector<std::string> result2 = obj->getPropertyNames(); + std::vector<std::string> expected2 = {"name", "greet"}; + EXPECT_TRUE(compare(result2, expected2)) << printInfo("Actual: ", result2) << printInfo("Expected: ", expected2); +} + +// CJSContext::JSON_Stringify() tests +// run with "--gtest_filter=CJSONStringifyTest.*" to run only this test suite +class CJSONStringifyTest : public testing::Test +{ +public: + void SetUp() override + { + // create and enter context + m_pContext = new CJSContext(); + m_pContext->Enter(); + } + + void TearDown() override + { + m_pContext->Exit(); + } + + JSSmart<CJSObject> createObject(const std::string& objLiteral) + { + return m_pContext->runScript("(() => { return " + objLiteral + ";})();")->toObject(); + } + +public: + JSSmart<CJSContext> m_pContext; +}; + +TEST_F(CJSONStringifyTest, undefined) +{ + JSSmart<CJSValue> jsValue = CJSContext::createUndefined(); + std::string sRes = m_pContext->JSON_Stringify(jsValue); + EXPECT_EQ(sRes, ""); +} + +TEST_F(CJSONStringifyTest, null) +{ + JSSmart<CJSValue> jsValue = CJSContext::createNull(); + std::string sRes = m_pContext->JSON_Stringify(jsValue); + EXPECT_EQ(sRes, "null"); +} + +TEST_F(CJSONStringifyTest, numbers) +{ + JSSmart<CJSValue> jsValue = CJSContext::createInt(42); + std::string sRes = m_pContext->JSON_Stringify(jsValue); + EXPECT_EQ(sRes, "42"); + + jsValue = CJSContext::createUInt(7); + sRes = m_pContext->JSON_Stringify(jsValue); + EXPECT_EQ(sRes, "7"); + + jsValue = CJSContext::createDouble(3.1415926535); + sRes = m_pContext->JSON_Stringify(jsValue); + EXPECT_EQ(sRes, "3.1415926535"); +} + +TEST_F(CJSONStringifyTest, strings) +{ + JSSmart<CJSValue> jsValue = CJSContext::createString(""); + std::string sRes = m_pContext->JSON_Stringify(jsValue); + EXPECT_EQ(sRes, "\"\""); + + jsValue = CJSContext::createString("foo bar"); + sRes = m_pContext->JSON_Stringify(jsValue); + EXPECT_EQ(sRes, "\"foo bar\""); +} + +TEST_F(CJSONStringifyTest, arrays) +{ + JSSmart<CJSArray> jsArr = CJSContext::createArray(0); + std::string sRes = m_pContext->JSON_Stringify(jsArr->toValue()); + EXPECT_EQ(sRes, "[]"); + + jsArr = CJSContext::createArray(4); + jsArr->set(0, 42); + // inner array + JSSmart<CJSArray> jsArrInner = CJSContext::createArray(2); + jsArrInner->set(0, CJSContext::createString("foo")); + jsArrInner->set(1, CJSContext::createDouble(2.71828)); + jsArr->set(1, jsArrInner->toValue()); + + jsArr->set(2, CJSContext::createNull()); + jsArr->set(3, CJSContext::createUndefined()); + sRes = m_pContext->JSON_Stringify(jsArr->toValue()); + EXPECT_EQ(sRes, "[42,[\"foo\",2.71828],null,null]"); +} + +TEST_F(CJSONStringifyTest, typed_arrays) +{ + BYTE* data = NSAllocator::Alloc(4); + data[0] = 0x1A; + data[1] = 0x54; + data[2] = 0xFE; + data[3] = 0xFF; + JSSmart<CJSTypedArray> jsTypedArr = CJSContext::createUint8Array(data, 4, false); + + std::string sRes = m_pContext->JSON_Stringify(jsTypedArr->toValue()); + EXPECT_EQ(sRes, "{\"0\":26,\"1\":84,\"2\":254,\"3\":255}"); +} + +TEST_F(CJSONStringifyTest, empty_object) +{ + JSSmart<CJSObject> jsObj = CJSContext::createObject(); + std::string sRes = m_pContext->JSON_Stringify(jsObj->toValue()); + EXPECT_EQ(sRes, "{}"); + + jsObj->set("number", CJSContext::createInt(42)); + jsObj->set("name", CJSContext::createString("foo")); + sRes = m_pContext->JSON_Stringify(jsObj->toValue()); + EXPECT_EQ(sRes, "{\"number\":42,\"name\":\"foo\"}"); +} + +TEST_F(CJSONStringifyTest, normal_object) +{ + JSSmart<CJSObject> jsObj = createObject("{number: 42, name: 'foo', arr: [1, 'abc', 2, 3], func() { return 'bar'; }}"); + std::string sRes = m_pContext->JSON_Stringify(jsObj->toValue()); + EXPECT_EQ(sRes, "{\"number\":42,\"name\":\"foo\",\"arr\":[1,\"abc\",2,3]}"); +} + +TEST_F(CJSONStringifyTest, only_one_function_in_object) +{ + JSSmart<CJSObject> jsObj = createObject("{add(a, b) { return a + b; }}"); + std::string sRes = m_pContext->JSON_Stringify(jsObj->toValue()); + EXPECT_EQ(sRes, "{}"); +} + +TEST_F(CJSONStringifyTest, inner_object) +{ + JSSmart<CJSObject> jsObj = createObject("{inner: {number: 42, name: 'foo'}, own: 'bar'}"); + std::string sRes = m_pContext->JSON_Stringify(jsObj->toValue()); + EXPECT_EQ(sRes, "{\"inner\":{\"number\":42,\"name\":\"foo\"},\"own\":\"bar\"}"); +} + +TEST_F(CJSONStringifyTest, object_with_null_and_undefined_properties) +{ + JSSmart<CJSObject> jsObj = createObject("{number: null, name: undefined, func() { return 'bar'; }}"); + std::string sRes = m_pContext->JSON_Stringify(jsObj->toValue()); + EXPECT_EQ(sRes, "{\"number\":null}"); +} + +TEST_F(CJSONStringifyTest, object_with_only_undefined_properties) +{ + JSSmart<CJSObject> jsObj = createObject("{foo: undefined, bar: undefined}"); + std::string sRes = m_pContext->JSON_Stringify(jsObj->toValue()); + EXPECT_EQ(sRes, "{}"); +} + +TEST_F(CJSONStringifyTest, array_as_object) +{ + JSSmart<CJSObject> jsObj = createObject("{0: 4, 1: 2, 2: undefined, 3: 'foo', 42: 'bar'}"); + std::string sRes = m_pContext->JSON_Stringify(jsObj->toValue()); + EXPECT_EQ(sRes, "{\"0\":4,\"1\":2,\"3\":\"foo\",\"42\":\"bar\"}"); +} + +TEST_F(CJSONStringifyTest, object_with_prototype) +{ + m_pContext->runScript( + "var personPrototype = { age: 42, greet() { return 'Hello, world!'; } };" + "function Person(name) { this.name = name; }" + ); + + JSSmart<CJSObject> jsObj = m_pContext->runScript("new Person('Foo');")->toObject(); + std::string sRes = m_pContext->JSON_Stringify(jsObj->toValue()); + EXPECT_EQ(sRes, "{\"name\":\"Foo\"}"); + + m_pContext->runScript("Object.assign(Person.prototype, personPrototype);"); + sRes = m_pContext->JSON_Stringify(jsObj->toValue()); + // expect the same result, because JSON.stringify does not preserve any of the not-owned properties of the object + EXPECT_EQ(sRes, "{\"name\":\"Foo\"}"); +} + +#else +int main() +{ + JSSmart<CJSContext> pContext = new CJSContext(); + CJSContextScope scope(pContext); + + JSSmart<CJSObject> jsObj = CJSContext::createObject(); + jsObj->set("number", CJSContext::createInt(42)); + jsObj->set("name", CJSContext::createString("foo")); + + std::cout << pContext->JSON_Stringify(jsObj->toValue()) << std::endl; + + return 0; +} +#endif // JS_INTERNAL_GOOGLE_TEST diff --git a/DesktopEditor/doctrenderer/test/js_internal/test.pro b/DesktopEditor/doctrenderer/test/js_internal/test.pro new file mode 100644 index 00000000000..dabcdff535f --- /dev/null +++ b/DesktopEditor/doctrenderer/test/js_internal/test.pro @@ -0,0 +1,40 @@ +QT -= core +QT -= gui + +TARGET = test +CONFIG += console +CONFIG -= app_bundle + +TEMPLATE = app + +CONFIG += core_static_link_libstd + +CORE_ROOT_DIR = $$PWD/../../../../../core +CORE_3DPARTY_DIR = $$CORE_ROOT_DIR/Common/3dParty +PWD_ROOT_DIR = $$PWD + +#CONFIG += build_xp +include($$CORE_ROOT_DIR/Common/base.pri) + +# Comment to inspect custom main +# Uncomment to run google tests +CONFIG += js_internal_google_test + +js_internal_google_test { + include($$CORE_3DPARTY_DIR/googletest/googletest.pri) + DEFINES += JS_INTERNAL_GOOGLE_TEST +} + +DESTDIR = $$PWD/build + +INCLUDEPATH += ../.. + +ADD_DEPENDENCY(doctrenderer) + +core_linux { + LIBS += -Wl,-unresolved-symbols=ignore-in-shared-libs + LIBS += -ldl +} + +SOURCES += \ + main.cpp diff --git a/DesktopEditor/doctrenderer/test/json/main.cpp b/DesktopEditor/doctrenderer/test/json/main.cpp new file mode 100644 index 00000000000..e5c6a0e52d3 --- /dev/null +++ b/DesktopEditor/doctrenderer/test/json/main.cpp @@ -0,0 +1,2127 @@ +#include "json/serialization.h" + +#ifdef JSON_GOOGLE_TEST +#include "gtest/gtest.h" +#include <algorithm> +#include <limits> +#else +#include <iostream> +#endif + +using namespace NSJSBase; +using namespace NSJSON; + +#ifdef JSON_GOOGLE_TEST + +class CJSONTest : public testing::Test +{ +public: + void SetUp() override + { + // create and enter context + m_pContext = new CJSContext(); + m_pContext->Enter(); + } + + void TearDown() override + { + m_pContext->Exit(); + } + + bool compare(const CValue& value, JSSmart<CJSValue> jsValue, bool makeExpects = true) + { + if (value.IsUndefined()) + { + if (makeExpects) + EXPECT_TRUE(jsValue->isUndefined()); + return jsValue->isUndefined(); + } + if (value.IsNull()) + { + if (makeExpects) + EXPECT_TRUE(jsValue->isNull()); + return jsValue->isNull(); + } + + if (value.IsArray()) + { + if (makeExpects) + EXPECT_TRUE(jsValue->isArray()); + if (!jsValue->isArray()) + return false; + + JSSmart<CJSArray> jsArr = jsValue->toArray(); + const int len = value.GetCount(); + + if (makeExpects) + EXPECT_EQ(len, jsArr->getCount()); + if (len != jsArr->getCount()) + return false; + + for (int i = 0; i < len; i++) + { + if (!compare(value[i], jsArr->get(i), makeExpects)) + { + if (makeExpects) + ADD_FAILURE() << "Array values at index [" << i << "] are different!"; + return false; + } + } + } + else if (value.IsTypedArray()) + { + if (makeExpects) + EXPECT_TRUE(jsValue->isTypedArray()); + if (!jsValue->isTypedArray()) + return false; + + JSSmart<CJSTypedArray> jsTypedArr = jsValue->toTypedArray(); + + if (makeExpects) + EXPECT_EQ(value.GetCount(), jsTypedArr->getCount()); + if (value.GetCount() != jsTypedArr->getCount()) + return false; + + // compare pointers, not values + if (makeExpects) + EXPECT_EQ(value.GetData(), jsTypedArr->getData().Data); + if (value.GetData() != jsTypedArr->getData().Data) + return false; + } + else if (value.IsObject()) + { + if (makeExpects) + EXPECT_TRUE(jsValue->isObject()); + if (!jsValue->isObject()) + return false; + + JSSmart<CJSObject> jsObj = jsValue->toObject(); + std::vector<std::string> properties = value.GetPropertyNames(); + std::vector<std::string> jsProperties = jsObj->getPropertyNames(); + + const int len = properties.size(); + if (makeExpects) + EXPECT_EQ(len, jsProperties.size()); + if (len != jsProperties.size()) + return false; + + // sort both vectors since the order of properties may vary in them + std::sort(properties.begin(), properties.end()); + std::sort(jsProperties.begin(), jsProperties.end()); + + for (int i = 0; i < len; i++) + { + if (makeExpects) + EXPECT_EQ(properties[i], jsProperties[i]); + if (properties[i] != jsProperties[i]) + return false; + + const char* sProperty = properties[i].c_str(); + if (!compare(value[sProperty], jsObj->get(sProperty), makeExpects)) + { + if (makeExpects) + ADD_FAILURE() << "Object property values for property \"" << sProperty << "\" are different!"; + return false; + } + } + } + else + { + // primitive types + if (value.IsBool()) + { + if (makeExpects) + EXPECT_TRUE(jsValue->isBool()); + if (!jsValue->isBool()) + return false; + + bool val = (bool)value; + bool jsVal = jsValue->toBool(); + if (makeExpects) + EXPECT_EQ(val, jsVal); + if (val != jsVal) + return false; + } + else if (value.IsInt()) + { + if (makeExpects) + EXPECT_TRUE(jsValue->isNumber()); + if (!jsValue->isNumber()) + return false; + + int val = (int)value; + int jsVal = jsValue->toInt32(); + if (makeExpects) + EXPECT_EQ(val, jsVal); + if (val != jsVal) + return false; + } + else if (value.IsDouble()) + { + if (makeExpects) + EXPECT_TRUE(jsValue->isNumber()); + if (!jsValue->isNumber()) + return false; + + double val = (double)value; + double jsVal = jsValue->toDouble(); + if (!std::isnan(val)) + { + // strict check without tolerance + if (makeExpects) + EXPECT_EQ(val, jsVal); + if (val != jsVal) + return false; + } + else + { + if (makeExpects) + EXPECT_TRUE(std::isnan(jsVal)); + if (!std::isnan(jsVal)) + return false; + } + } + else + { + if (makeExpects) + { + EXPECT_TRUE(value.IsString()); + EXPECT_TRUE(jsValue->isString()); + } + if (!jsValue->isString()) + return false; + + std::string val = value.ToStringA(); + std::string jsVal = jsValue->toStringA(); + if (makeExpects) + EXPECT_EQ(val, jsVal); + if (val != jsVal) + return false; + } + } + + return true; + } + +public: + JSSmart<CJSContext> m_pContext; +}; + +// --------- CValue basic functinality tests ---------- + +TEST_F(CJSONTest, undefined_from_default_constructor) +{ + CValue val; + JSSmart<CJSValue> jsVal = CJSContext::createUndefined(); + EXPECT_TRUE(compare(val, jsVal)); + val = 0; + EXPECT_FALSE(compare(val, jsVal, false)); +} + +TEST_F(CJSONTest, undefined_from_static_method) +{ + CValue val = CValue::CreateUndefined(); + JSSmart<CJSValue> jsVal = CJSContext::createUndefined(); + EXPECT_TRUE(compare(val, jsVal)); + val = 5; + EXPECT_FALSE(compare(val, jsVal, false)); +} + +TEST_F(CJSONTest, null_) +{ + CValue val = CValue::CreateNull(); + JSSmart<CJSValue> jsVal = CJSContext::createNull(); + EXPECT_TRUE(compare(val, jsVal)); + val = CValue(); + EXPECT_FALSE(compare(val, jsVal, false)); +} + +TEST_F(CJSONTest, bool_) +{ + CValue val = true; + JSSmart<CJSValue> jsVal = CJSContext::createBool(true); + EXPECT_TRUE(compare(val, jsVal)); + val = false; + EXPECT_FALSE(compare(val, jsVal, false)); +} + +TEST_F(CJSONTest, int_) +{ + CValue val = 42; + EXPECT_TRUE(val.IsDouble()); + EXPECT_TRUE(val.IsInt()); + JSSmart<CJSValue> jsVal = CJSContext::createInt(42); + EXPECT_TRUE(compare(val, jsVal)); + val = 100; + EXPECT_FALSE(compare(val, jsVal, false)); + val = 3; + jsVal = CJSContext::createDouble(3.0); + EXPECT_TRUE(compare(val, jsVal)); +} + +TEST_F(CJSONTest, double_) +{ + CValue val = 3.141592; + EXPECT_FALSE(val.IsInt()); + JSSmart<CJSValue> jsVal = CJSContext::createDouble(3.141592); + EXPECT_TRUE(compare(val, jsVal)); + val = 2.81828; + jsVal = CJSContext::createDouble(3.0); + EXPECT_FALSE(compare(val, jsVal, false)); + val = 3.0; + jsVal = CJSContext::createInt(3); + EXPECT_TRUE(compare(val, jsVal)); +} + +TEST_F(CJSONTest, string_char_constructor) +{ + CValue val = "test"; + JSSmart<CJSValue> jsVal = CJSContext::createString("test"); + EXPECT_TRUE(compare(val, jsVal)); + jsVal = CJSContext::createString(L"test"); + EXPECT_TRUE(compare(val, jsVal)); + val = ""; + EXPECT_FALSE(compare(val, jsVal, false)); +} + +TEST_F(CJSONTest, string_string_constructor) +{ + CValue val = std::string("test"); + JSSmart<CJSValue> jsVal = CJSContext::createString("test"); + EXPECT_TRUE(compare(val, jsVal)); + jsVal = CJSContext::createString(L"test"); + EXPECT_TRUE(compare(val, jsVal)); + val = ""; + EXPECT_FALSE(compare(val, jsVal, false)); +} + +TEST_F(CJSONTest, wstring_wchar_constructor) +{ + CValue val = L"тест"; + JSSmart<CJSValue> jsVal = CJSContext::createString(L"тест"); + EXPECT_TRUE(compare(val, jsVal)); + val = "test"; + EXPECT_FALSE(compare(val, jsVal, false)); + jsVal = CJSContext::createString(L"test"); + EXPECT_TRUE(compare(val, jsVal)); +} + +TEST_F(CJSONTest, wstring_wstring_constructor) +{ + CValue val = std::wstring(L"тест"); + JSSmart<CJSValue> jsVal = CJSContext::createString(L"тест"); + EXPECT_TRUE(compare(val, jsVal)); + val = "test"; + EXPECT_FALSE(compare(val, jsVal, false)); + jsVal = CJSContext::createString(L"test"); + EXPECT_TRUE(compare(val, jsVal)); +} + +TEST_F(CJSONTest, array_from_static_method) +{ + CValue arr = CValue::CreateArray(4); + arr[0] = CValue::CreateNull(); + arr[1] = 42; + arr[2] = CValue::CreateArray(2); + arr[2][0] = true; + arr[2][1] = 2.5; + EXPECT_TRUE(arr[3].IsUndefined()); +#ifdef JSON_DEBUG + EXPECT_THROW(arr[100].IsUndefined(), std::out_of_range); + EXPECT_THROW(arr[-1].IsUndefined(), std::out_of_range); + EXPECT_THROW(arr[5] = 1, std::out_of_range); +#else + EXPECT_TRUE(arr[100].IsUndefined()); + EXPECT_TRUE(arr[-1].IsUndefined()); + arr[5] = 1; +#endif + EXPECT_EQ(arr.GetCount(), 4); + JSSmart<CJSArray> jsArr = CJSContext::createArray(4); + jsArr->set(0, CJSContext::createNull()); + jsArr->set(1, CJSContext::createInt(42)); + jsArr->set(2, CJSContext::createArray(2)); + jsArr->get(2)->toArray()->set(0, CJSContext::createBool(true)); + jsArr->get(2)->toArray()->set(1, CJSContext::createDouble(2.5)); + jsArr->set(3, CJSContext::createUndefined()); + EXPECT_TRUE(compare(arr, jsArr->toValue())); + arr[1] = 41; + EXPECT_FALSE(compare(arr, jsArr->toValue(), false)); +} + +TEST_F(CJSONTest, array_from_initializer_list) +{ + CValue arr = {CValue::CreateNull(), 42, {true, 2.5}, CValue::CreateUndefined()}; + EXPECT_TRUE(arr[3].IsUndefined()); +#ifdef JSON_DEBUG + EXPECT_THROW(arr[100].IsUndefined(), std::out_of_range); + EXPECT_THROW(arr[-1].IsUndefined(), std::out_of_range); + EXPECT_THROW(arr[5] = 1, std::out_of_range); +#else + EXPECT_TRUE(arr[100].IsUndefined()); + EXPECT_TRUE(arr[-1].IsUndefined()); + arr[5] = 1; +#endif + EXPECT_EQ(arr.GetCount(), 4); + JSSmart<CJSArray> jsArr = CJSContext::createArray(4); + jsArr->set(0, CJSContext::createNull()); + jsArr->set(1, CJSContext::createInt(42)); + jsArr->set(2, CJSContext::createArray(2)); + jsArr->get(2)->toArray()->set(0, CJSContext::createBool(true)); + jsArr->get(2)->toArray()->set(1, CJSContext::createDouble(2.5)); + jsArr->set(3, CJSContext::createUndefined()); + EXPECT_TRUE(compare(arr, jsArr->toValue())); + arr[1] = 41; + EXPECT_FALSE(compare(arr, jsArr->toValue(), false)); +} + +TEST_F(CJSONTest, array_empty) +{ + CValue arr = CValue::CreateArray(0); + EXPECT_TRUE(arr.IsArray()); + EXPECT_EQ(arr.GetCount(), 0); +#ifdef JSON_DEBUG + EXPECT_THROW(arr[0].IsUndefined(), std::out_of_range); +#else + EXPECT_TRUE(arr[0].IsUndefined()); +#endif +} + +TEST_F(CJSONTest, array_negative_size) +{ + CValue arr = CValue::CreateArray(-1); + EXPECT_TRUE(arr.IsUndefined()); +#ifdef JSON_DEBUG + EXPECT_THROW(arr[0].IsUndefined(), std::bad_cast); +#else + EXPECT_TRUE(arr[0].IsUndefined()); +#endif +} + +TEST_F(CJSONTest, typed_array_externalize) +{ + BYTE* data = CValue::AllocTypedArray(10); + CValue typedArr = CValue::CreateTypedArray(data, 10); + JSSmart<CJSTypedArray> jsTypedArr = CJSContext::createUint8Array(data, 10); + EXPECT_TRUE(compare(typedArr, jsTypedArr->toValue())); + typedArr = CValue::CreateTypedArray(data, 11); + EXPECT_FALSE(compare(typedArr, jsTypedArr->toValue(), false)); + BYTE* data2 = CValue::AllocTypedArray(10); + typedArr = CValue::CreateTypedArray(data2, 10); + EXPECT_FALSE(compare(typedArr, jsTypedArr->toValue(), false)); + + CValue::FreeTypedArray(data, 10); + CValue::FreeTypedArray(data2, 10); +} + +TEST_F(CJSONTest, typed_array_not_externalize) +{ + BYTE* data = CValue::AllocTypedArray(10); + CValue typedArr = CValue::CreateTypedArray(data, 10, false); + JSSmart<CJSTypedArray> jsTypedArr = CJSContext::createUint8Array(data, 10); + EXPECT_TRUE(compare(typedArr, jsTypedArr->toValue())); +} + +TEST_F(CJSONTest, typed_array_empty) +{ + BYTE* data = CValue::AllocTypedArray(0); + CValue typedArr = CValue::CreateTypedArray(data, 0, false); + EXPECT_TRUE(typedArr.IsUndefined()); +} + +TEST_F(CJSONTest, typed_array_negative_size) +{ + BYTE* data = CValue::AllocTypedArray(10); + CValue typedArr = CValue::CreateTypedArray(nullptr, -10); + EXPECT_TRUE(typedArr.IsUndefined()); + CValue::FreeTypedArray(data, 10); +} + +TEST_F(CJSONTest, typed_array_copy) +{ + BYTE* data = CValue::AllocTypedArray(10); + CValue typedArr = CValue::CreateTypedArray(data, 10, false); + { + CValue typedArr2 = typedArr; + typedArr2.GetData()[4] = 0x42; + } + EXPECT_EQ(typedArr.GetData()[4], 0x42); +} + +TEST_F(CJSONTest, object) +{ + CValue obj = CValue::CreateObject(); + JSSmart<CJSObject> jsObj = CJSContext::createObject(); + EXPECT_TRUE(compare(obj, jsObj->toValue())); + obj["name"] = "Foo"; + jsObj->set("name", CJSContext::createString("Foo")); + EXPECT_TRUE(compare(obj, jsObj->toValue())); + obj["name"] = "Bar"; + EXPECT_FALSE(compare(obj, jsObj->toValue(), false)); + obj["number"] = 42; + jsObj->set("name", CJSContext::createString("Bar")); + jsObj->set("number", CJSContext::createInt(42)); + EXPECT_TRUE(compare(obj, jsObj->toValue())); + obj["extra"] = CValue::CreateUndefined(); + EXPECT_TRUE(compare(obj, jsObj->toValue())); + obj["extra"] = CValue::CreateNull(); + EXPECT_FALSE(compare(obj, jsObj->toValue(), false)); +} + +TEST_F(CJSONTest, image_externalize) +{ + int width = 1080; + int height = 480; + BYTE* bits = CValue::AllocImageBits(width, height); + CValue img = CValue::CreateImage(bits, width, height, ifBGRA); + + EXPECT_TRUE(img.IsImage()); + EXPECT_EQ(img.GetImageBits(), bits); + EXPECT_EQ(img.GetImageWidth(), width); + EXPECT_EQ(img.GetImageHeight(), height); + EXPECT_EQ(img.GetImageFormat(), ifBGRA); + + CValue::FreeImageBits(bits); + + width = 50; + height = 100; + bits = CValue::AllocImageBits(width, height); + img = CValue::CreateImage(bits, width, height, ifRGBA); + + EXPECT_TRUE(img.IsImage()); + EXPECT_EQ(img.GetImageBits(), bits); + EXPECT_EQ(img.GetImageWidth(), width); + EXPECT_EQ(img.GetImageHeight(), height); + EXPECT_EQ(img.GetImageFormat(), ifRGBA); + + CValue::FreeImageBits(bits); +} + +TEST_F(CJSONTest, image_not_externalize) +{ + int width = 320; + int height = 480; + BYTE* bits = CValue::AllocImageBits(width, height); + CValue img = CValue::CreateImage(bits, width, height, ifARGB, false); + + EXPECT_TRUE(img.IsImage()); + EXPECT_EQ(img.GetImageBits(), bits); + EXPECT_EQ(img.GetImageWidth(), width); + EXPECT_EQ(img.GetImageHeight(), height); + EXPECT_EQ(img.GetImageFormat(), ifARGB); +} + +TEST_F(CJSONTest, image_wrong_size) +{ + BYTE* bits = CValue::AllocImageBits(100, 100); + CValue img = CValue::CreateImage(bits, 0, 100, ifARGB, false); + EXPECT_TRUE(img.IsUndefined()); + img = CValue::CreateImage(bits, -1, 100, ifARGB, false); + EXPECT_TRUE(img.IsUndefined()); + img = CValue::CreateImage(bits, 0, 0, ifARGB, false); + EXPECT_TRUE(img.IsUndefined()); + img = CValue::CreateImage(bits, -100, -100, ifARGB, false); + EXPECT_TRUE(img.IsUndefined()); +} + +TEST_F(CJSONTest, references) +{ + CValue val = 42; + CValueRef ref = val; + EXPECT_EQ((int)val, 42); + EXPECT_EQ((int)ref, 42); + ref = 10; + EXPECT_EQ((int)val, 10); + EXPECT_EQ((int)ref, 10); + // CValue from CValueRef + CValue val2 = ref; + val2 = 12; + EXPECT_EQ((int)val2, 12); + EXPECT_EQ((int)ref, 10); + EXPECT_EQ((int)val, 10); + // chaining CValueRef-s + CValueRef ref2 = ref; + val = "foo"; + EXPECT_EQ((std::string)ref, "foo"); + EXPECT_EQ((std::string)ref2, "foo"); + val = {1, 2, 3}; + EXPECT_EQ((int)ref[1], 2); + // CValue assignment to CValueRef + val2 = ref2; + EXPECT_EQ((int)val2[0], 1); + val2 = true; + EXPECT_EQ((bool)val2, true); + EXPECT_TRUE(ref.IsArray()); + EXPECT_TRUE(ref2.IsArray()); + // CValueRef from operator[] + CValueRef ref3 = val[2]; + ref3 = ref2[0]; + EXPECT_EQ((int)val[2], 1); +} + +TEST_F(CJSONTest, constants) +{ + const CValue val = 42; + // NOTE: you can't change constant value explicitly, but you can do it using references: + CValueRef ref = val; + ref = 10; + EXPECT_EQ((int)val, 10); + EXPECT_EQ((int)ref, 10); + // NOTE: const references saves its const properties + const CValueRef ref2 = ref; + // you can't do that: +// ref2 = 100; + EXPECT_EQ((int)ref2, 10); +} + +TEST_F(CJSONTest, wrong_usage) +{ + CValue val = 42; +#ifdef JSON_DEBUG + EXPECT_THROW(val["name"].IsUndefined(), std::bad_cast); + EXPECT_THROW(val[0].IsUndefined(), std::bad_cast); + EXPECT_THROW(val.GetPropertyNames(), std::bad_cast); + EXPECT_THROW(val.GetCount(), std::bad_cast); + EXPECT_THROW(val.GetData(), std::bad_cast); + EXPECT_THROW(val.GetImageBits(), std::bad_cast); + EXPECT_THROW(val.GetImageFormat(), std::bad_cast); + EXPECT_THROW(val.GetImageHeight(), std::bad_cast); + EXPECT_THROW(val.GetImageWidth(), std::bad_cast); +#else + EXPECT_TRUE(val["name"].IsUndefined()); + EXPECT_TRUE(val[0].IsUndefined()); + EXPECT_TRUE(val.GetPropertyNames().empty()); + EXPECT_EQ(val.GetCount(), 0); + EXPECT_EQ(val.GetData(), nullptr); + EXPECT_EQ(val.GetImageBits(), nullptr); + EXPECT_EQ(val.GetImageFormat(), ifInvalid); + EXPECT_EQ(val.GetImageHeight(), 0); + EXPECT_EQ(val.GetImageWidth(), 0); +#endif + EXPECT_DOUBLE_EQ(val.ToDouble(), 42.0); +#ifdef JSON_DEBUG + EXPECT_THROW((bool)val, std::bad_cast); + EXPECT_THROW((std::string)val, std::bad_cast); + EXPECT_THROW((std::wstring)val, std::bad_cast); +#else + EXPECT_EQ((bool)val, false); + EXPECT_EQ((std::string)val, ""); + EXPECT_EQ((std::wstring)val, L""); +#endif + + val = 3.1415926535; + EXPECT_EQ((int)val, 3); + + val = "test"; +#ifdef JSON_DEBUG + EXPECT_THROW((bool)val, std::bad_cast); + EXPECT_THROW((int)val, std::bad_cast); + EXPECT_THROW((double)val, std::bad_cast); +#else + EXPECT_EQ((bool)val, false); + EXPECT_EQ((int)val, 0); + EXPECT_EQ((double)val, 0.0); +#endif + EXPECT_EQ((std::wstring)val, L"test"); + + val = L"test"; +#ifdef JSON_DEBUG + EXPECT_THROW((bool)val, std::bad_cast); + EXPECT_THROW((int)val, std::bad_cast); + EXPECT_THROW((double)val, std::bad_cast); +#else + EXPECT_EQ((bool)val, false); + EXPECT_EQ((int)val, 0); + EXPECT_EQ((double)val, 0.0); +#endif + EXPECT_EQ((std::string)val, "test"); + + val = CValue::CreateObject(); +#ifdef JSON_DEBUG + EXPECT_THROW(val[0].IsUndefined(), std::bad_cast); + EXPECT_THROW((bool)val, std::bad_cast); + EXPECT_THROW((int)val, std::bad_cast); + EXPECT_THROW((double)val, std::bad_cast); + EXPECT_THROW((std::string)val, std::bad_cast); + EXPECT_THROW((std::wstring)val, std::bad_cast); +#else + EXPECT_TRUE(val[0].IsUndefined()); + EXPECT_EQ((bool)val, false); + EXPECT_EQ((int)val, 0); + EXPECT_EQ((double)val, 0.0); + EXPECT_EQ((std::string)val, ""); + EXPECT_EQ((std::wstring)val, L""); +#endif +} + +TEST_F(CJSONTest, is_init) +{ + CValue val; + EXPECT_FALSE(val.IsInit()); + val = CValue::CreateNull(); + EXPECT_FALSE(val.IsInit()); + val = 42; + EXPECT_TRUE(val.IsInit()); + CValue val2 = val; + val2 = CValue::CreateUndefined(); + EXPECT_TRUE(val.IsInit()); + EXPECT_FALSE(val2.IsInit()); + CValueRef ref = val; + ref = CValue::CreateUndefined(); + EXPECT_FALSE(val.IsInit()); + EXPECT_FALSE(ref.IsInit()); + ref = 3; + EXPECT_TRUE(val.IsInit()); + EXPECT_TRUE(ref.IsInit()); +} + +// ----------- toJS() tests ----------- + +TEST_F(CJSONTest, toJS_undefined) +{ + CValue val; + JSSmart<CJSValue> jsVal = toJS(val); + EXPECT_TRUE(compare(val, jsVal)); +} + +TEST_F(CJSONTest, toJS_null) +{ + CValue val = CValue::CreateNull(); + JSSmart<CJSValue> jsVal = toJS(val); + EXPECT_TRUE(compare(val, jsVal)); +} + +TEST_F(CJSONTest, toJS_typed_arrays) +{ + BYTE* data = CValue::AllocTypedArray(4); + data[0] = 0x1A; + data[1] = 0x54; + data[2] = 0xFE; + data[3] = 0xFF; + CValue typedArr = CValue::CreateTypedArray(data, 4, false); + JSSmart<CJSValue> jsTypedArr = toJS(typedArr); + // NOTE: BE CAREFUL WHEN CALLLING toJS() MULTIPLE TIMES WITH THE SAME TYPED ARRAY! + // second typed array will NOT be initialized properly, since there is another `CJSTypedArray` containing this memory! +// JSSmart<CJSValue> jsTypedArr2 = toJS(typedArr); + EXPECT_TRUE(compare(typedArr, jsTypedArr)); +} + +TEST_F(CJSONTest, toJS_arrays) +{ + BYTE* data = CValue::AllocTypedArray(4); + data[0] = 0x1A; + data[1] = 0x54; + data[2] = 0xFE; + data[3] = 0xFF; + CValue typedArr = CValue::CreateTypedArray(data, 4, false); + + // can't add typed array to this inner array (see test above), only to external array + CValue arrInner = {true, 42, L"тест функции toJS()", 2.71828, CValue(), "abc de f", L"test"}; + CValue arr = {0, arrInner, arrInner, CValue::CreateNull(), arrInner, CValue::CreateArray(4), typedArr}; + + JSSmart<CJSValue> jsArr = toJS(arr); + EXPECT_TRUE(compare(arr, jsArr)); +} + +TEST_F(CJSONTest, toJS_arrays_circular) +{ + // NOTE: BE CAREFULL WHEN CREATING CIRCULAR REFERENCE DEPENDENCY IN YOUR ARRAY OR OBJECT! + CValue arr = CValue::CreateArray(2); + CValueRef ref = arr; + arr[0] = 3; + arr[1] = ref; + // or simply: +// arr[1] = arr; + + EXPECT_EQ((int)arr[0], 3); + EXPECT_EQ((int)arr[1][0], 3); + EXPECT_EQ((int)arr[1][1][1][1][1][1][1][1][1][1][0], 3); + EXPECT_TRUE(arr[1][1][1][1].IsArray()); + // here you will get stack overflow, because each inner array reference will be transformed to a new copy of `CJSArray` +// JSSmart<CJSValue> jsArr = toJS(arr); + + // keep only 2 inner recursions + CValue arrRec = arr[1][1]; + arrRec[1] = 42; + EXPECT_TRUE(arr[1].IsInt()); + + JSSmart<CJSValue> jsArr = toJS(arr); + EXPECT_TRUE(compare(arr, jsArr)); +} + +TEST_F(CJSONTest, toJS_objects) +{ + CValue obj = CValue::CreateObject(); + obj["name"] = L"Foo"; + obj["parameters"] = CValue::CreateObject(); + CValueRef parameters = obj["parameters"]; + parameters["size"] = 42; + parameters["arr"] = {CValue::CreateNull(), CValue::CreateArray(0), {42, L"тест функции toJS()", 2.71828}, CValue::CreateObject(), CValue(), "abc de f", L"test"}; + parameters["0"] = 0; + + BYTE* data = CValue::AllocTypedArray(4); + data[0] = 0x1A; + data[1] = 0x54; + data[2] = 0xFE; + data[3] = 0xFF; + CValue typedArr = CValue::CreateTypedArray(data, 4, false); + obj["typed"] = typedArr; + // NOTE: you can create property even without a name (like in JS) + obj[""] = "Bar"; + + JSSmart<CJSValue> jsObj = toJS(obj); + EXPECT_TRUE(compare(obj, jsObj)); +} + +// ----------- fromJS() tests ----------- + +TEST_F(CJSONTest, fromJS_undefined) +{ + JSSmart<CJSValue> jsVal = CJSContext::createUndefined(); + CValue val = fromJS(jsVal); + EXPECT_TRUE(compare(val, jsVal)); +} + +TEST_F(CJSONTest, fromJS_null) +{ + JSSmart<CJSValue> jsVal = CJSContext::createNull(); + CValue val = fromJS(jsVal); + EXPECT_TRUE(compare(val, jsVal)); +} + +TEST_F(CJSONTest, fromJS_and_toJS_edge_numbers) +{ + JSSmart<CJSArray> jsVal = CJSContext::createArray(16); + jsVal->set(0, INT_MIN); + jsVal->set(1, INT_MAX); + jsVal->set(2, 0); + jsVal->set(3, 42); + jsVal->set(4, 0.0); + jsVal->set(5, 3.1415926535); + jsVal->set(6, 42.0); + jsVal->set(7, (double)INT_MIN); + jsVal->set(8, (double)INT_MAX); + jsVal->set(9, std::pow(2.0, 31) - 1); + jsVal->set(10, std::pow(2.0, 31)); + jsVal->set(11, -std::pow(2.0, 31)); + jsVal->set(12, -std::pow(2.0, 31) - 1); + jsVal->set(13, INFINITY); + jsVal->set(14, NAN); + jsVal->set(15, -INFINITY); + + CValue val = fromJS(jsVal->toValue()); + EXPECT_TRUE(compare(val, jsVal->toValue())); + EXPECT_TRUE(val[0].IsInt()); // INT_MIN + EXPECT_TRUE(val[1].IsInt()); // INT_MAX + EXPECT_TRUE(val[2].IsInt()); // 0 + EXPECT_TRUE(val[3].IsInt()); // 42 + EXPECT_TRUE(val[4].IsInt()); // 0.0 + EXPECT_TRUE(val[5].IsDouble()); // 3.1415926535 + EXPECT_TRUE(val[6].IsInt()); // 42.0 + EXPECT_TRUE(val[7].IsInt()); // (double)INT_MIN + EXPECT_TRUE(val[8].IsInt()); // (double)INT_MAX + EXPECT_TRUE(val[9].IsInt()); // 2^31 - 1 == INT_MAX + EXPECT_TRUE(val[10].IsDouble()); // 2^31 + EXPECT_TRUE(val[11].IsInt()); // -2^31 == INT_MIN + EXPECT_TRUE(val[12].IsDouble()); // -2^31 - 1 + EXPECT_TRUE(val[13].IsDouble()); // inf + EXPECT_TRUE(val[14].IsDouble()); // NaN + EXPECT_TRUE(val[15].IsDouble()); // -inf + + JSSmart<CJSValue> jsVal2 = toJS(val); + EXPECT_TRUE(compare(val, jsVal2)); +} + +TEST_F(CJSONTest, fromJS_typed_arrays) +{ + BYTE* data = NSAllocator::Alloc(4); + data[0] = 0x1A; + data[1] = 0x54; + data[2] = 0xFE; + data[3] = 0xFF; + JSSmart<CJSValue> jsTypedArr = CJSContext::createUint8Array(data, 4, false); + CValue typedArr = fromJS(jsTypedArr); + EXPECT_TRUE(compare(typedArr, jsTypedArr)); +} + +TEST_F(CJSONTest, fromJS_arrays) +{ + BYTE* data = NSAllocator::Alloc(4); + data[0] = 0x1A; + data[1] = 0x54; + data[2] = 0xFE; + data[3] = 0xFF; + JSSmart<CJSValue> jsTypedArr = CJSContext::createUint8Array(data, 4, false); + JSSmart<CJSArray> jsArrInner = CJSContext::createArray(0); + jsArrInner->add_bool(true); + jsArrInner->add_int(42); + jsArrInner->add_string(L"тест функции fromJS()"); + jsArrInner->add_double(2.71828); + jsArrInner->add_undefined(); + jsArrInner->add_stringa("abc de f"); + jsArrInner->add_string(L"test"); + JSSmart<CJSArray> jsArr = CJSContext::createArray(0); + jsArr->add_int(0); + jsArr->add(jsArrInner->toValue()); + jsArr->add(jsArrInner->toValue()); + jsArr->add_null(); + jsArr->add(jsArrInner->toValue()); + jsArr->add(CJSContext::createArray(4)); + jsArr->add(jsTypedArr); + + CValue arr = fromJS(jsArr->toValue()); + EXPECT_TRUE(compare(arr, jsArr->toValue())); +} + +TEST_F(CJSONTest, fromJS_objects) +{ + JSSmart<CJSObject> jsObj = CJSContext::createObject(); + jsObj->set("name", CJSContext::createString(L"Foo")); + + JSSmart<CJSObject> jsParam = CJSContext::createObject(); + jsParam->set("size", 42); + jsParam->set("arr", CJSContext::createArray(0)); + + JSSmart<CJSArray> jsArr = jsParam->get("arr")->toArray(); + jsArr->add_null(); + jsArr->add(CJSContext::createArray(0)); + jsArr->add(CJSContext::createArray(3)); + jsArr->get(2)->toArray()->set(0, 42); + jsArr->get(2)->toArray()->set(1, CJSContext::createString(L"тест функции fromJS()")); + jsArr->get(2)->toArray()->set(2, 2.71828); + jsArr->add(CJSContext::createObject()); + jsArr->add_undefined(); + jsArr->add_stringa("abc de f"); + jsArr->add_bool(true); + jsParam->set("0", 0); + + jsObj->set("parameters", jsParam); + + BYTE* data = NSAllocator::Alloc(4); + data[0] = 0x1A; + data[1] = 0x54; + data[2] = 0xFE; + data[3] = 0xFF; + JSSmart<CJSValue> jsTypedArr = CJSContext::createUint8Array(data, 4, false); + + jsObj->set("typed", jsTypedArr); + jsObj->set("", CJSContext::createString("Bar")); + + CValue obj = fromJS(jsObj->toValue()); + EXPECT_TRUE(compare(obj, jsObj->toValue())); +} + +TEST_F(CJSONTest, serialization_with_script) +{ + JSSmart<CJSValue> jsObj = m_pContext->runScript( + "(() => {" + " let obj = {};" + " obj['name'] = 'Foo';" + " obj['parameters'] = { size: 42, arr: [null, [], [42, 'test', 2.71828], {}, undefined, 'abc de f', ''], 0: 0, typedArr: { data: null, count: 0 } };" + " obj[''] = 'Bar';" + " return obj;" + "})();" + ); + + CValue obj = fromJS(jsObj); + + EXPECT_EQ(obj["name"].ToStringW(), L"Foo"); + EXPECT_EQ(obj[""].ToStringW(), L"Bar"); + EXPECT_EQ((double)obj["parameters"]["arr"][2][0], 42); + EXPECT_TRUE(obj["parameters"]["arr"][4].IsUndefined()); + EXPECT_EQ((int)obj["parameters"]["0"], 0); + EXPECT_TRUE(obj["parameters"]["typedArr"]["data"].IsNull()); + + EXPECT_TRUE(compare(obj, jsObj)); + + // function test() returns 0 if all checks have passed and number of failed check otherwise + m_pContext->runScript( + "function test(obj) {" + " if (obj['name'] !== 'Foo')" + " return 1;" + " if (obj[''] !== 'Bar')" + " return 2;" + " if (obj['parameters']['arr'][2][0] !== 42)" + " return 3;" + " if (obj['parameters']['arr'][4] !== undefined)" + " return 4;" + " if (obj['parameters']['0'] !== 0)" + " return 5;" + " if (obj['parameters']['typedArr']['data'] !== null)" + " return 6;" + " return 0;" + "}" + ); + + JSSmart<CJSObject> global = m_pContext->GetGlobal(); + JSSmart<CJSValue> args[1]; + args[0] = toJS(obj); + + JSSmart<CJSValue> jsCheckResult = global->call_func("test", 1, args); + + EXPECT_TRUE(jsCheckResult->isNumber()); + EXPECT_EQ(jsCheckResult->toInt32(), 0); + + EXPECT_TRUE(compare(obj, args[0])); +} + +// ----------- CValue::ToJSON() tests ----------- +namespace +{ + // helper function + std::string normalizeJSONObject(const std::string& str, int& pos) + { + // '{' was checked + pos++; + + std::vector<std::string> keyValuePairs; + std::string keyValue; + int nSquareBrackets = 0; + + for (; str[pos] != '}'; pos++) + { + if (str[pos] == '{') + { + keyValue += normalizeJSONObject(str, pos); + } + else if (str[pos] == ',' && nSquareBrackets == 0) + { + keyValuePairs.emplace_back(std::move(keyValue)); + keyValue = ""; + } + else + { + if (str[pos] == '[') + { + nSquareBrackets++; + } + else if (str[pos] == ']') + { + nSquareBrackets--; + } + keyValue += str[pos]; + } + } + + if (!keyValue.empty()) + keyValuePairs.emplace_back(std::move(keyValue)); + + std::sort(keyValuePairs.begin(), keyValuePairs.end()); + std::string result = "{"; + for (const std::string& keyValue : keyValuePairs) + { + result += keyValue; + result += ','; + } + // pop last ',' + if (result.back() == ',') + result.pop_back(); + result += '}'; + + return result; + } + + // test function that sorts key-value pairs for objects in JSON-strings + // works only with valid JSONs + std::string normalizeJSON(const std::string& str) + { + const int n = (int)str.size(); + + if (str[0] != '{' && str[0] != '[') + return str; + + std::string result; + for (int pos = 0; pos < n; pos++) + { + if (str[pos] == '{') + { + result += normalizeJSONObject(str, pos); + // decrement because it will be incremented again + } + else + { + result += str[pos]; + } + } + + return result; + } +} + +TEST_F(CJSONTest, ToJSON_undefined) +{ + CValue val = CValue::CreateUndefined(); + EXPECT_EQ(val.ToJSON(), ""); +} + +TEST_F(CJSONTest, ToJSON_null) +{ + CValue val = CValue::CreateNull(); + EXPECT_EQ(val.ToJSON(), "null"); +} + +TEST_F(CJSONTest, ToJSON_bool) +{ + CValue val(false); + EXPECT_EQ(val.ToJSON(), "false"); + val = true; + EXPECT_EQ(val.ToJSON(), "true"); +} + +TEST_F(CJSONTest, ToJSON_int) +{ + CValue val = 42; + EXPECT_EQ(val.ToJSON(), "42"); + val = 0; + EXPECT_EQ(val.ToJSON(), "0"); + val = -73; + EXPECT_EQ(val.ToJSON(), "-73"); + val = INT_MIN; + EXPECT_EQ(val.ToJSON(), "-2147483648"); + val = INT_MAX; + EXPECT_EQ(val.ToJSON(), "2147483647"); +} + +TEST_F(CJSONTest, ToJSON_double) +{ + CValue val = 4.2; + EXPECT_EQ(val.ToJSON(), "4.2"); + val = 42.0; + EXPECT_EQ(val.ToJSON(), "42"); + val = 0.0; + EXPECT_EQ(val.ToJSON(), "0"); + val = 3.1415926535; + EXPECT_EQ(val.ToJSON(), "3.1415926535"); + val = (double)INT_MIN; + EXPECT_EQ(val.ToJSON(), "-2147483648"); + val = (double)INT_MAX; + EXPECT_EQ(val.ToJSON(), "2147483647"); +} + +TEST_F(CJSONTest, ToJSON_double_critical_values) +{ + CValue val = 8e30; + EXPECT_EQ(val.ToJSON(), "8e+30"); + val = 8e-30; + EXPECT_EQ(val.ToJSON(), "8e-30"); + + val = INFINITY; + EXPECT_EQ(val.ToJSON(), "null"); + val = NAN; + EXPECT_EQ(val.ToJSON(), "null"); + val = -INFINITY; + EXPECT_EQ(val.ToJSON(), "null"); + + val = std::numeric_limits<double>::max(); + std::string strResult = val.ToJSON(); + // we cannot expect predefined specified result from this test case so just check if it is not empty + EXPECT_TRUE(!strResult.empty()); + EXPECT_TRUE(strResult != "null"); + + val = std::numeric_limits<double>::min(); + strResult = val.ToJSON(); + // we cannot expect predefined specified result from this test case so just check if it is not empty + EXPECT_TRUE(!strResult.empty()); + EXPECT_TRUE(strResult != "null"); +} + +TEST_F(CJSONTest, ToJSON_string) +{ + CValue val = " test "; + EXPECT_EQ(val.ToJSON(), "\" test \""); + val = ""; + EXPECT_EQ(val.ToJSON(), "\"\""); + val = L" test "; + EXPECT_EQ(val.ToJSON(), "\" test \""); + // test parsing of special symbols inside strings + val = "foo: {bar: 42}[} ,))"; + EXPECT_EQ(val.ToJSON(), "\"foo: {bar: 42}[} ,))\""); +} + +TEST_F(CJSONTest, ToJSON_string_escaped_characters) +{ + CValue val = "HEL\"LO"; + std::string strRes = val.ToJSON(); + EXPECT_EQ(strRes, "\"HEL\\\"LO\""); + + val = "HEL\\/LO"; + strRes = val.ToJSON(); + EXPECT_EQ(strRes, "\"HEL\\\\/LO\""); + + val = "\tH\bE\fL\nL\nO\r"; + strRes = val.ToJSON(); + EXPECT_EQ(strRes, "\"\\tH\\bE\\fL\\nL\\nO\\r\""); + + // other symbols + std::string spec = "/"; + for (char ch = 0; ch <= 0x21; ch++) + { + spec += ch; + } + spec += '/'; + + val = spec; + strRes = val.ToJSON(); + EXPECT_EQ(strRes, "\"/\\u0000\\u0001\\u0002\\u0003\\u0004\\u0005\\u0006\\u0007\\b\\t\\n\\u000b" + "\\f\\r\\u000e\\u000f\\u0010\\u0011\\u0012\\u0013\\u0014\\u0015\\u0016\\u0017" + "\\u0018\\u0019\\u001a\\u001b\\u001c\\u001d\\u001e\\u001f !/\""); +} + +TEST_F(CJSONTest, ToJSON_typed_arrays) +{ + BYTE* data = CValue::AllocTypedArray(4); + data[0] = 0x1A; + data[1] = 0x54; + data[2] = 0xFE; + data[3] = 0xFF; + CValue typedArr = CValue::CreateTypedArray(data, 4, false); + EXPECT_EQ(typedArr.ToJSON(), "{\"0\":26,\"1\":84,\"2\":254,\"3\":255}"); +} + +TEST_F(CJSONTest, ToJSON_arrays) +{ + CValue arr = CValue::CreateArray(0); + EXPECT_EQ(arr.ToJSON(), "[]"); + + arr = CValue::CreateArray(4); + arr[0] = 42; + arr[1] = "foo"; + arr[2] = 2.71828; + EXPECT_EQ(arr.ToJSON(), "[42,\"foo\",2.71828,null]"); + + CValue arrInner = {CValue::CreateNull(), 73.0}; + arr[3] = arrInner; + EXPECT_EQ(arr.ToJSON(), "[42,\"foo\",2.71828,[null,73]]"); +} + +TEST_F(CJSONTest, ToJSON_arrays_complex) +{ + BYTE* data = CValue::AllocTypedArray(5); + data[0] = 0x1A; + data[1] = 0x54; + data[2] = 0xFE; + data[3] = 0xFF; + data[4] = 0x00; + CValue typedArr = CValue::CreateTypedArray(data, 5, false); + + CValue arrInner = {true, 42, L"test function ToJSON()", 2.71828, CValue(), "abc de f", L"test"}; + CValue arr = {0, arrInner, arrInner, CValue::CreateNull(), arrInner, CValue::CreateArray(4), typedArr}; + + std::string strRes = arr.ToJSON(); + std::string strExpected = "[0," + "[true,42,\"test function ToJSON()\",2.71828,null,\"abc de f\",\"test\"]," + "[true,42,\"test function ToJSON()\",2.71828,null,\"abc de f\",\"test\"]," + "null," + "[true,42,\"test function ToJSON()\",2.71828,null,\"abc de f\",\"test\"]," + "[null,null,null,null]," + "{\"0\":26,\"1\":84,\"2\":254,\"3\":255,\"4\":0}]"; + + EXPECT_EQ(strRes, strExpected); +} + +TEST_F(CJSONTest, ToJSON_arrays_circular) +{ + // NOTE: BE CAREFULL WHEN CREATING CIRCULAR REFERENCE DEPENDENCY IN YOUR ARRAY OR OBJECT! + CValue arr = CValue::CreateArray(2); + CValue ref = arr; + arr[0] = 3; + arr[1] = ref; + + // here you will get stack overflow, because each inner array reference will be recursively converted to JSON-string + // arr.ToJSON(); + + // remove recursions + CValue arrRec = arr[1][1]; + arrRec[1] = 42; + + EXPECT_EQ(arr.ToJSON(), "[3,42]"); +} + +TEST_F(CJSONTest, ToJSON_objects) +{ + CValue obj = CValue::CreateObject(); + EXPECT_EQ(obj.ToJSON(), "{}"); + + obj["name"] = "Foo"; + obj["number"] = 42; + std::string strRes = normalizeJSON(obj.ToJSON()); + std::string strExpected = normalizeJSON("{\"name\":\"Foo\",\"number\":42}"); + EXPECT_EQ(strRes, strExpected); + + obj["undef"] = CValue::CreateUndefined(); + obj["null"] = CValue::CreateNull(); + strRes = normalizeJSON(obj.ToJSON()); + strExpected = normalizeJSON("{\"name\":\"Foo\",\"number\":42,\"null\":null}"); + EXPECT_EQ(strRes, strExpected); +} + +TEST_F(CJSONTest, ToJSON_objects_complex) +{ + CValue obj = CValue::CreateObject(); + + obj["name"] = L"Foo"; + obj["parameters"] = CValue::CreateObject(); + CValueRef parameters = obj["parameters"]; + parameters["0"] = 0; + parameters["size"] = 42; + parameters["arr"] = {CValue::CreateNull(), CValue::CreateArray(1), {42, L"test function ToJSON()", 2.71828}, CValue::CreateObject(), CValue(), "abc de f", L"test"}; + + BYTE* data = CValue::AllocTypedArray(4); + data[0] = 0x1A; + data[1] = 0x54; + data[2] = 0xFE; + data[3] = 0xFF; + CValue typedArr = CValue::CreateTypedArray(data, 4, false); + obj["typed"] = typedArr; + // property without a name + obj[""] = "Bar"; + + std::string strRes = normalizeJSON(obj.ToJSON()); + std::string strExpected = normalizeJSON( \ + "{" + "\"name\":\"Foo\"," + "\"parameters\":{\"arr\":[null,[null],[42,\"test function ToJSON()\",2.71828],{},null,\"abc de f\",\"test\"],\"size\":42,\"0\":0}," + "\"typed\":{\"0\":26,\"1\":84,\"2\":254,\"3\":255}," + "\"\":\"Bar\"" + "}"); + + EXPECT_EQ(strRes, strExpected); +} + +// ----------- CValue::FromJSON() tests ----------- +TEST_F(CJSONTest, FromJSON_null) +{ + std::string strJson = "null"; + CValue val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsNull()); +} + +TEST_F(CJSONTest, FromJSON_null_invalid) +{ + // empty json string is invalid + std::string strJson = ""; + CValue val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsUndefined()); + // there is no undefined in JSON standard + strJson = "undefined"; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsUndefined()); + + strJson = "nil"; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsUndefined()); + + strJson = "n"; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsUndefined()); + + strJson = "NULL"; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsUndefined()); + + strJson = "nullptr"; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsUndefined()); +} + +TEST_F(CJSONTest, FromJSON_bool) +{ + std::string strJson = "false"; + CValue val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsBool()); + EXPECT_EQ((bool)val, false); + + strJson = "true "; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsBool()); + EXPECT_EQ((bool)val, true); +} + +TEST_F(CJSONTest, FromJSON_bool_invalid) +{ + std::string strJson = "fals"; + CValue val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsUndefined()); + + strJson = "truE"; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsUndefined()); + + strJson = "f"; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsUndefined()); + + strJson = "t"; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsUndefined()); + + strJson = "True"; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsUndefined()); +} + +TEST_F(CJSONTest, FromJSON_int) +{ + std::string strJson = "42"; + CValue val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsInt()); + EXPECT_EQ((int)val, 42); + + strJson = "0"; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsInt()); + EXPECT_EQ((int)val, 0); + + strJson = "-73"; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsInt()); + EXPECT_EQ((int)val, -73); + + strJson = "-2147483648"; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsInt()); + EXPECT_EQ((int)val, std::numeric_limits<int>::min()); + + strJson = "2147483647"; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsInt()); + EXPECT_EQ((int)val, std::numeric_limits<int>::max()); + + strJson = "2147483648"; + val = CValue::FromJSON(strJson); + // this value does not fit into 32-bit integer limits + EXPECT_FALSE(val.IsInt()); + EXPECT_TRUE(val.IsDouble()); +} + +TEST_F(CJSONTest, FromJSON_double) +{ + std::string strJson = "4.2"; + CValue val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsDouble()); + EXPECT_DOUBLE_EQ((double)val, 4.2); + + strJson = "42.0"; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsInt()); + EXPECT_EQ((int)val, 42); + + strJson = "0.0"; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsInt()); + EXPECT_EQ((int)val, 0); + + strJson = "3.1415926535"; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsDouble()); + EXPECT_DOUBLE_EQ((double)val, 3.1415926535); + + strJson = "2147483648"; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsDouble()); + EXPECT_DOUBLE_EQ((double)val, 2147483648.0); +} + +TEST_F(CJSONTest, FromJSON_double_critical_values) +{ + std::string strJson = "-8e30"; + CValue val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsDouble()); + EXPECT_DOUBLE_EQ((double)val, -8e30); + + strJson = "8e+30"; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsDouble()); + EXPECT_DOUBLE_EQ((double)val, 8e30); + + strJson = "8e-30"; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsDouble()); + EXPECT_DOUBLE_EQ((double)val, 8e-30); + + // divide by 10 to prevent getting 'inf' when converting to string + CValue maxDouble = std::numeric_limits<double>::max() / 10; + strJson = maxDouble.ToJSON(); + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsDouble()); + EXPECT_NEAR((double)val, (double)maxDouble, 1e-15 * std::numeric_limits<double>::max()); + + // multiply by 10 to prevent getting '0' when converting to string + CValue minDouble = std::numeric_limits<double>::min() * 10; + strJson = minDouble.ToJSON(); + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsDouble()); + EXPECT_NEAR((double)val, (double)minDouble, 1e-15); + + // if value is outside of double range, it is expected to be inf + strJson = "10e+1000"; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsDouble()); + EXPECT_EQ((double)val, INFINITY); + + strJson = "-10e1000"; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsDouble()); + EXPECT_EQ((double)val, -INFINITY); + + // expected zero for too small values + strJson = "10e-1000"; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsDouble()); + EXPECT_EQ((double)val, 0.0); +} + +TEST_F(CJSONTest, FromJSON_numbers_invalid) +{ + // leading zeroes are invalid in JSON standard, but here it is considered valid + std::string strJson = "0123"; + CValue val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsInt()); + EXPECT_EQ((int)val, 123); + // multiple decimal points + strJson = "12.34.56"; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsUndefined()); + // trailing decimal point also considered invalid in JSON, but allowed here + strJson = "42."; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsDouble()); + EXPECT_EQ((int)val, 42); + // invalid exponent format + strJson = "1e"; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsUndefined()); + strJson = "1e+"; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsUndefined()); + strJson = "1e+a"; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsUndefined()); + strJson = "1e+-"; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsUndefined()); + // invalid characters + strJson = "123abc"; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsUndefined()); + strJson = "123\"abc\""; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsUndefined()); + strJson = "123-42"; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsUndefined()); + // sign without digits + strJson = "-"; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsUndefined()); + // sign without digits + strJson = "-"; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsUndefined()); + // whitespace in numbers + strJson = "1 234"; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsUndefined()); + strJson = "1 a"; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsUndefined()); +} + +TEST_F(CJSONTest, FromJSON_string) +{ + std::string strJson = "\" test \""; + CValue val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsString()); + EXPECT_EQ(val.ToStringA(), " test "); + + strJson = "\"\""; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsString()); + EXPECT_EQ(val.ToStringA(), ""); + + // test for parsing of special symbols inside strings + strJson = "\"foo: {bar: 42}[} ,))\""; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsString()); + EXPECT_EQ(val.ToStringA(), "foo: {bar: 42}[} ,))"); + + // test for using unicode codes instead of ASCII characters + strJson = "\"\\u0061\\u006E\\u0073\\u0077\\u0065\\u0072\\u0020\\u0069\\u0073\\u0020\\u0034\\u0032\\u0021\""; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsString()); + EXPECT_EQ(val.ToStringA(), "answer is 42!"); +} + +TEST_F(CJSONTest, FromJSON_string_escaped_characters) +{ + std::string strJson = "\"\\\\\""; + CValue val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsString()); + EXPECT_EQ(val.ToStringA(), "\\"); + + strJson = "\"HEL\\\"LO\""; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsString()); + EXPECT_EQ(val.ToStringA(), "HEL\"LO"); + + strJson = "\"HEL\\\\/LO\""; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsString()); + EXPECT_EQ(val.ToStringA(), "HEL\\/LO"); + + strJson = "\"\\tH\\bE\\fL\\nL\\nO\\r\""; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsString()); + EXPECT_EQ(val.ToStringA(), "\tH\bE\fL\nL\nO\r"); + + // characters from 0x00 to 0x21 (inclusive) + strJson = "\"/\\u0000\\u0001\\u0002\\u0003\\u0004\\u0005\\u0006\\u0007\\b\\t\\n\\u000b" + "\\f\\r\\u000e\\u000f\\u0010\\u0011\\u0012\\u0013\\u0014\\u0015\\u0016\\u0017" + "\\u0018\\u0019\\u001a\\u001b\\u001c\\u001d\\u001e\\u001f !\\/\""; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsString()); + + std::string spec = "/"; + for (char ch = 0; ch <= 0x21; ch++) + { + spec += ch; + } + spec += '/'; + + EXPECT_EQ(val.ToStringA(), spec); +} + +TEST_F(CJSONTest, FromJSON_string_invalid) +{ + // using unescaped control characters + std::string strJson = "\"this\nis a test"; + CValue val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsUndefined()); + + strJson = "\"\t\""; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsUndefined()); + // no closing quote + strJson = "\" test "; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsUndefined()); + // no symbol after backslash + strJson = "\"\\\""; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsUndefined()); + // wrong symbol after backslash + strJson = "\"\\x\""; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsUndefined()); + // invalid unicode sequence + strJson = "\"\\u\""; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsUndefined()); + strJson = "\"\\u00\""; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsUndefined()); + strJson = "\"\\u0100\""; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsUndefined()); + strJson = "\"\\u001\""; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsUndefined()); + strJson = "\"\\u00GH\""; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsUndefined()); + strJson = "\"\\u00fH\""; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsUndefined()); +} + +TEST_F(CJSONTest, FromJSON_whitespace_symbols) +{ + // allowed space symbols are: 0x09 (\t), 0x0A (\n), 0x0D (\r) and 0x20 (space) + std::string strJson = " null "; + CValue val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsNull()); + + strJson = "\t \n\n42\r"; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsInt()); + EXPECT_EQ((int)val, 42); + + strJson = "\n\t \" foo\\n \"\n \t\n"; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsString()); + EXPECT_EQ(val.ToStringA(), " foo\n "); + + strJson = " \t\v 42 \t"; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsUndefined()); + + strJson = " a 42 \t"; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsUndefined()); +} + +TEST_F(CJSONTest, FromJSON_arrays) +{ + std::string strJson = "[]"; + CValue val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsArray()); + EXPECT_EQ(val.GetCount(), 0); +#ifndef JSON_DEBUG + EXPECT_TRUE(val[0].IsUndefined()); +#else + EXPECT_THROW(val[0], std::out_of_range); +#endif + + strJson = "[1, 2, 3]"; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsArray()); + EXPECT_EQ(val.GetCount(), 3); + EXPECT_EQ((int)val[0], 1); + EXPECT_EQ((int)val[1], 2); + EXPECT_EQ((int)val[2], 3); + + strJson = " [ \"][\" ] "; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsArray()); + EXPECT_EQ(val.GetCount(), 1); + EXPECT_EQ(val[0].ToStringA(), "]["); + + strJson = " [ 73 , null\n\t,4.2]"; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsArray()); + EXPECT_EQ(val.GetCount(), 3); + EXPECT_EQ((int)val[0], 73); + EXPECT_TRUE(val[1].IsNull()); + EXPECT_DOUBLE_EQ((double)val[2], 4.2); + + strJson = "[1, \"two\", 3.14, true, null]"; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsArray()); + EXPECT_EQ(val.GetCount(), 5); + EXPECT_EQ(val[0].ToInt(), 1); + EXPECT_EQ(val[1].ToStringA(), "two"); + EXPECT_DOUBLE_EQ(val[2].ToDouble(), 3.14); + EXPECT_TRUE(val[3].ToBool()); + EXPECT_TRUE(val[4].IsNull()); +} + +TEST_F(CJSONTest, FromJSON_arrays_inner) +{ + std::string strJson = "[[1, 2, 3]]"; + CValue val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsArray()); + EXPECT_EQ(val.GetCount(), 1); + EXPECT_TRUE(val[0].IsArray()); + EXPECT_EQ(val[0].GetCount(), 3); + EXPECT_EQ((int)val[0][0], 1); + EXPECT_EQ((int)val[0][1], 2); + EXPECT_EQ((int)val[0][2], 3); + + strJson = "[1, [2, 3], [4, [5, 6]], 7]"; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsArray()); + EXPECT_EQ(val.GetCount(), 4); + EXPECT_EQ((int)val[0], 1); + EXPECT_TRUE(val[1].IsArray()); + EXPECT_EQ(val[1].GetCount(), 2); + EXPECT_EQ((int)val[1][0], 2); + EXPECT_EQ((int)val[1][1], 3); + EXPECT_TRUE(val[2].IsArray()); + EXPECT_EQ(val[2].GetCount(), 2); + EXPECT_EQ((int)val[2][0], 4); + EXPECT_TRUE(val[2][1].IsArray()); + EXPECT_EQ(val[2][1].GetCount(), 2); + EXPECT_EQ((int)val[2][1][0], 5); + EXPECT_EQ((int)val[2][1][1], 6); + EXPECT_EQ((int)val[3], 7); + + strJson = "[[],[[]],[[],[]]]"; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsArray()); + EXPECT_EQ(val.GetCount(), 3); + EXPECT_TRUE(val[0].IsArray()); + EXPECT_EQ(val[0].GetCount(), 0); + EXPECT_TRUE(val[1].IsArray()); + EXPECT_EQ(val[1].GetCount(), 1); + EXPECT_TRUE(val[1][0].IsArray()); + EXPECT_EQ(val[1][0].GetCount(), 0); + EXPECT_TRUE(val[2].IsArray()); + EXPECT_EQ(val[2].GetCount(), 2); + EXPECT_TRUE(val[2][0].IsArray()); + EXPECT_EQ(val[2][0].GetCount(), 0); + EXPECT_TRUE(val[2][1].IsArray()); + EXPECT_EQ(val[2][1].GetCount(), 0); +} + +TEST_F(CJSONTest, FromJSON_arrays_invalid) +{ + // no closing bracket + std::string strJson = "["; + CValue val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsUndefined()); + strJson = "[1,2,3"; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsUndefined()); + // trailing comma + strJson = "[1,2,]"; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsUndefined()); + // leading comma + strJson = "[,1]"; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsUndefined()); + // missing comma + strJson = "[1 2, 3]"; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsUndefined()); + // extra commas + strJson = "[1,,2,3]"; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsUndefined()); + strJson = "[,]"; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsUndefined()); + // invalid elements + strJson = "[1, 2, undefined, 4]"; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsUndefined()); + // non-JSON values as elements + strJson = "[1, 2, f(), 4]"; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsUndefined()); + // invalid syntax within elements + strJson = "[\"foo\", 123, [1, 2, }, 4]"; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsUndefined()); + // whitespace issues + strJson = "[1, 2 3, 4]"; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsUndefined()); + // empty array without brackets + strJson = "]"; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsUndefined()); + // extra brackets + strJson = "[[1, 2, 3]"; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsUndefined()); + strJson = "[1, 2, 3]]"; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsUndefined()); + // elements outside of the array + strJson = "[1, 2, 3], 5"; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsUndefined()); + strJson = "[1, 2, 3] 4"; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsUndefined()); +} + +TEST_F(CJSONTest, FromJSON_objects) +{ + std::string strJson = "{}"; + CValue val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsObject()); + EXPECT_EQ(val.GetPropertyNames().size(), 0); + + strJson = "{\"name\" : \"Foo\"}"; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsObject()); + EXPECT_EQ(val.GetPropertyNames().size(), 1); + EXPECT_EQ(val["name"].ToStringA(), "Foo"); + + strJson = "{\"name\":\"Bar\",\"value\":42}"; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsObject()); + EXPECT_EQ(val.GetPropertyNames().size(), 2); + EXPECT_EQ(val["name"].ToStringA(), "Bar"); + EXPECT_EQ((int)val["value"], 42); + + strJson = "{\"\\u0070\\u0069\":\n3.1415\t, \"\":null ,\"flag\":true,\"arr \":[4,2],\"str\":\"test\"}"; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsObject()); + EXPECT_EQ(val.GetPropertyNames().size(), 5); + EXPECT_DOUBLE_EQ((double)val["pi"], 3.1415); + EXPECT_TRUE(val[""].IsNull()); + EXPECT_EQ((bool)val["flag"], true); + EXPECT_TRUE(val["arr "].IsArray()); + EXPECT_EQ(val["arr "].GetCount(), 2); + EXPECT_EQ((int)val["arr "][0], 4); + EXPECT_EQ((int)val["arr "][1], 2); + EXPECT_EQ(val["str"].ToStringA(), "test"); +} + +TEST_F(CJSONTest, FromJSON_objects_as_typed_arrays) +{ + // typed arrays in JSON are represented as objects with properties "0", "1", ... and corresponding integer values + // if you still want to make typed array from such object, you need to do it manually + std::string strJson = "{\"0\":26,\"1\":179,\"2\":254,\"3\":255,\"4\":0}"; + CValue val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsObject()); + EXPECT_EQ((int)val["0"], 26); + EXPECT_EQ((int)val["1"], 179); + EXPECT_EQ((int)val["2"], 254); + EXPECT_EQ((int)val["3"], 255); + EXPECT_EQ((int)val["4"], 0); +} + +TEST_F(CJSONTest, FromJSON_objects_inner) +{ + std::string strJson = "{\"inner\":{}}"; + CValue val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsObject()); + EXPECT_EQ(val.GetPropertyNames().size(), 1); + EXPECT_TRUE(val["inner"].IsObject()); + EXPECT_TRUE(val["inner"].GetPropertyNames().empty()); +} + +TEST_F(CJSONTest, FromJSON_objects_and_arrays) +{ + // more complex example + std::string strJson = \ + "{\n" + " \"name\": \"Foo\",\n" + " \"parameters\": {\n" + " \"size\": 42,\n" + " \"arr\": [\n" + " null,\n" + " [],\n" + " [42, \"test\", 2.71828],\n" + " {\n" + " \"name\": \"Bar\",\n" + " \"good\": false\n" + " },\n" + " null,\n" + " \"abc de f\",\n" + " \"\"\n" + " ],\n" + " \"0\": 0,\n" + " \"data\": {\n" + " \"data\": null,\n" + " \"count\": 0\n" + " }\n" + " },\n" + " \"\": \"empty\"\n" + "}\n"; + + CValue val = CValue::FromJSON(strJson); + + // Check root-level object + EXPECT_TRUE(val.IsObject()); + EXPECT_EQ(val.GetPropertyNames().size(), 3); + // Check "name" property + EXPECT_EQ(val["name"].ToStringA(), "Foo"); + // Check "parameters" object + EXPECT_TRUE(val["parameters"].IsObject()); + EXPECT_EQ(val["parameters"].GetPropertyNames().size(), 4); + // Check "size" property + EXPECT_EQ((int)val["parameters"]["size"], 42); + // Check "arr" property (array) + EXPECT_TRUE(val["parameters"]["arr"].IsArray()); + EXPECT_EQ(val["parameters"]["arr"].GetCount(), 7); + // First element of "arr" (null) + EXPECT_TRUE(val["parameters"]["arr"][0].IsNull()); + // Second element of "arr" (empty array) + EXPECT_TRUE(val["parameters"]["arr"][1].IsArray()); + EXPECT_EQ(val["parameters"]["arr"][1].GetCount(), 0); + // Third element of "arr" (array with mixed types) + EXPECT_TRUE(val["parameters"]["arr"][2].IsArray()); + EXPECT_EQ(val["parameters"]["arr"][2].GetCount(), 3); + EXPECT_EQ((int)val["parameters"]["arr"][2][0], 42); + EXPECT_EQ(val["parameters"]["arr"][2][1].ToStringA(), "test"); + EXPECT_DOUBLE_EQ((double)val["parameters"]["arr"][2][2], 2.71828); + // Fourth element of "arr" (object) + EXPECT_TRUE(val["parameters"]["arr"][3].IsObject()); + EXPECT_EQ(val["parameters"]["arr"][3].GetPropertyNames().size(), 2); + EXPECT_EQ(val["parameters"]["arr"][3]["name"].ToStringA(), "Bar"); + EXPECT_TRUE(val["parameters"]["arr"][3]["good"].IsBool()); + EXPECT_FALSE(val["parameters"]["arr"][3]["good"]); + // Fifth element of "arr" (null) + EXPECT_TRUE(val["parameters"]["arr"][4].IsNull()); + // Sixth element of "arr" (string) + EXPECT_EQ(val["parameters"]["arr"][5].ToStringA(), "abc de f"); + // Seventh element of "arr" (empty string) + EXPECT_EQ(val["parameters"]["arr"][6].ToStringA(), ""); + // Check "0" property (numeric value) + EXPECT_EQ((int)val["parameters"]["0"], 0); + // Check "data" object inside "parameters" + EXPECT_TRUE(val["parameters"]["data"].IsObject()); + EXPECT_EQ(val["parameters"]["data"].GetPropertyNames().size(), 2); + // Check "data" property inside "data" (null) + EXPECT_TRUE(val["parameters"]["data"]["data"].IsNull()); + // Check "count" property inside "data" + EXPECT_EQ((int)val["parameters"]["data"]["count"], 0); +} + +TEST_F(CJSONTest, FromJSON_objects_invalid) +{ + // no closing bracket + std::string strJson = "{"; + CValue val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsUndefined()); + strJson = "{ \"key1\": \"value1\", \"key2\": 42"; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsUndefined()); + // trailing comma + strJson = "{ \"key1\": \"value1\", \"key2\": 42, }"; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsUndefined()); + // duplicating properties are technically allowed. Only the last value will apply. + strJson = "{ \"key\": \"value1\", \"key\": \"value2\" }"; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsObject()); + EXPECT_EQ(val.GetPropertyNames().size(), 1); + EXPECT_EQ(val["key"].ToStringA(), "value2"); + // keys are not enslosed in double quotes + strJson = "{ key1: \"value1\", \"key2\": 42 }"; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsUndefined()); + // missing colon between the key and the value + strJson = "{ \"key1\" \"value1\", \"key2\": 42 }"; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsUndefined()); + strJson = "{\"key\"}"; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsUndefined()); + strJson = "{key}"; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsUndefined()); + // wrong value formats + strJson = "{ \"key1\": undefined, \"key2\": 42 }"; ; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsUndefined()); + strJson = "{ \"key1\": 12.34.56, \"key2\": 42 }"; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsUndefined()); + strJson = "{ \"key1\": \"value1, \"key2\": 42 }"; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsUndefined()); + // non-string key + strJson = "{ 123: \"value\", \"key2\": 42 }"; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsUndefined()); + // missing coma + strJson = "{ \"key1\": \"value1\" \"key2\": 42 }"; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsUndefined()); + // some invalid inner object + strJson = "{ \"outerKey\": { \"innerKey\": \"value\", \"anotherInnerKey\": 42 }"; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsUndefined()); + strJson = "{ \"outerKey\": { innerKey: \"value\" } }"; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsUndefined()); + strJson = "{ \"outerKey\": { \"innerKey\" \"value\" } }"; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsUndefined()); + strJson = "{ \"outerKey\": { \"innerKey\": \"value\", }, \"key2\": 42 }"; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsUndefined()); + strJson = "{ \"outerKey\": { \"innerKey\": \"value\", \"anotherInnerKey\": 42, \"thirdKey\": { \"deepKey\": \"value\" } }"; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsUndefined()); + // no opening bracket + strJson = "}"; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsUndefined()); + strJson = "\"key1\": \"value1\", \"key2\": 42}"; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsUndefined()); + // extra brackets + strJson = "{{\"key1\": \"value1\", \"key2\": 42}}"; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsUndefined()); + strJson = "{{\"key1\": \"value1\", \"key2\": 42}"; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsUndefined()); + strJson = "{\"key1\": \"value1\", \"key2\": 42}}"; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsUndefined()); + // elements outside of the object + strJson = "{\"key1\": \"value1\", \"key2\": 42}, \"key3\": 3.14"; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsUndefined()); + strJson = "{\"key1\": \"value1\", \"key2\": 42} \"key3\": 3.14"; + val = CValue::FromJSON(strJson); + EXPECT_TRUE(val.IsUndefined()); +} + +#else +int main() +{ + JSSmart<CJSContext> pContext = new CJSContext(); + CJSContextScope scope(pContext); + + // top object with some text parameters + CValue textPr = CValue::CreateObject(); + + CValue colorRGB = CValue::CreateObject(); + colorRGB["r"] = 12; + colorRGB["g"] = 34; + colorRGB["b"] = 56; + + CValue colorRGBA = CValue::CreateObject(); + colorRGBA["rgb"] = colorRGB; + colorRGBA["alpha"] = 80; + + // CValueRef behaves as reference + CValueRef name = textPr["name"]; + // from now on, name - is a reference to the property "name" of textPr. Changing it will affect this object property: + name = "Foo"; + // Also you can chain references + CValueRef name3 = name; + name3 = "FooBar"; // this change applies to textPr["name"] + // The same but with CValue wouldnt' work: + CValue name2 = textPr["name"]; + name2 = "Bar"; // this change doesn't affect the property "name" of textPr + + textPr["size"] = 4.2; + textPr["color"] = colorRGBA; + textPr["font"] = CValue::CreateObject(); + textPr["font"]["fontName"] = L"Times New Roman"; + textPr["font"]["bold"] = true; + // undefined member: + textPr["font"]["italic"] = CValue::CreateUndefined(); + // or just +// textPr["font"]["italic"]; + // null member: + textPr["extras"] = CValue::CreateNull(); + // array + CValue numbers = {10000, 12, 42, 0, 147}; + // inner array + CValue innerArray = {true, "abc", 3.1415926535, L"ABC", 4}; + numbers[3] = innerArray; + textPr["numbers"] = numbers; + // create typed array + BYTE* pData = CValue::AllocTypedArray(4); + pData[0] = 11; + pData[1] = 23; + pData[2] = 58; + pData[3] = 13; + // add typed array + CValue typedArr = CValue::CreateTypedArray(pData, 4, false); + textPr["typedArr"] = typedArr; + + // convert to JS + JSSmart<CJSObject> jsObj = toJS(textPr)->toObject(); + JSSmart<CJSObject> global = pContext->GetGlobal(); + global->set("textPr", jsObj); + JSSmart<CJSValue> ret = pContext->runScript("(function () { return JSON.stringify(textPr, null, 4); })();"); + if (ret.IsInit()) + { + std::cout << ret->toStringA() << std::endl; + } + + // convert fromJS() the same object: + CValue textPr2 = fromJS(jsObj->toValue()); + // and then back toJS() to see if result is the same + JSSmart<CJSObject> jsObj2 = toJS(textPr2)->toObject(); + global->set("textPr2", jsObj2); + ret = pContext->runScript("(function () { return JSON.stringify(textPr2, null, 4); })();"); + if (ret.IsInit()) + { + std::cout << ret->toStringA() << std::endl; + } + + return 0; +} +#endif // JSON_GOOGLE_TEST diff --git a/DesktopEditor/doctrenderer/test/json/test.pro b/DesktopEditor/doctrenderer/test/json/test.pro new file mode 100644 index 00000000000..e6323902bf3 --- /dev/null +++ b/DesktopEditor/doctrenderer/test/json/test.pro @@ -0,0 +1,39 @@ +QT -= core +QT -= gui + +TARGET = test +CONFIG += console +CONFIG -= app_bundle + +TEMPLATE = app + +CONFIG += core_static_link_libstd + +CORE_ROOT_DIR = $$PWD/../../../../../core +CORE_3DPARTY_DIR = $$CORE_ROOT_DIR/Common/3dParty +PWD_ROOT_DIR = $$PWD + +include($$CORE_ROOT_DIR/Common/base.pri) + +# Comment to inspect simple usage example +# Uncomment to run google tests +CONFIG += json_google_test + +json_google_test { + include($$CORE_3DPARTY_DIR/googletest/googletest.pri) + DEFINES += JSON_GOOGLE_TEST +} + +DESTDIR = $$PWD/build + +INCLUDEPATH += ../.. + +ADD_DEPENDENCY(doctrenderer) + +core_linux { + LIBS += -Wl,-unresolved-symbols=ignore-in-shared-libs + LIBS += -ldl +} + +SOURCES += \ + main.cpp diff --git a/DesktopEditor/fontengine/ApplicationFonts.cpp b/DesktopEditor/fontengine/ApplicationFonts.cpp index 9df8716c58b..3b54c8365d2 100644 --- a/DesktopEditor/fontengine/ApplicationFonts.cpp +++ b/DesktopEditor/fontengine/ApplicationFonts.cpp @@ -1118,348 +1118,381 @@ std::vector<NSFonts::CFontInfo*> CFontList::GetAllByName(const std::wstring& str return aRes; } -void CFontList::LoadFromArrayFiles(std::vector<std::wstring>& oArray, int nFlag) +void CFontList::Add(FT_Library pLibrary, FT_Parameter* pParams, const std::wstring& sFontPath, CFontStream* pStream, int nFlag) { - size_t nCount = oArray.size(); - - FT_Library pLibrary = NULL; - if (FT_Init_FreeType(&pLibrary)) + if (!pLibrary || !pParams || !pStream) return; - FT_Parameter *pParams = (FT_Parameter *)::malloc( sizeof(FT_Parameter) * 4 ); - pParams[0].tag = FT_MAKE_TAG( 'i', 'g', 'p', 'f' ); - pParams[0].data = NULL; - pParams[1].tag = FT_MAKE_TAG( 'i', 'g', 'p', 's' ); - pParams[1].data = NULL; - pParams[2].tag = FT_PARAM_TAG_IGNORE_PREFERRED_FAMILY; - pParams[2].data = NULL; - pParams[3].tag = FT_PARAM_TAG_IGNORE_PREFERRED_SUBFAMILY; - pParams[3].data = NULL; + FT_Open_Args oOpenArgs; + oOpenArgs.flags = FT_OPEN_MEMORY | FT_OPEN_PARAMS; + oOpenArgs.memory_base = pStream->m_pData; + oOpenArgs.memory_size = pStream->m_lSize; - // определяем размер буфера, чтобы не выделять много кусков, а обойтись одним - int nMaxFontSize = 0; - for (size_t nIndex = 0; nIndex < nCount; ++nIndex) - { - NSFile::CFileBinary oFile; - if (oFile.OpenFile(oArray[nIndex])) - { - int nSizeTmp = (int)oFile.GetFileSize(); - if (nSizeTmp > 100000000) - { - // такие огромные шрифты не учитываем - oArray.erase(oArray.begin() + nIndex, oArray.begin() + nIndex + 1); - nIndex--; - nCount--; - } + oOpenArgs.num_params = 4; + oOpenArgs.params = pParams; - if (nMaxFontSize < nSizeTmp) - nMaxFontSize = nSizeTmp; - } + FT_Face pFace = NULL; + if (FT_Open_Face( pLibrary, &oOpenArgs, 0, &pFace )) + return; + + // TO DO: Шрифты, которые нельзя скейлить (т.е. изменять размер + // произвольно) мы не грузим. Возможно в будущем надо будет + // сделать, чтобы работал и такой вариант. (в Word такие шрифты + // не используются) + if ( !( pFace->face_flags & FT_FACE_FLAG_SCALABLE ) ) + { + FT_Done_Face( pFace ); + return; } - BYTE* pDataFontFile = new BYTE[nMaxFontSize]; + int nFacesCount = pFace->num_faces; + if ( FT_Done_Face( pFace ) ) + return; - for (size_t nIndex = 0; nIndex < nCount; ++nIndex) + for ( int nIndexFace = 0; nIndexFace < nFacesCount; nIndexFace++ ) { - if ((nFlag & 2) != 0) - { - std::wstring::size_type _pos_dfont = oArray[nIndex].find(L".dfont"); - if (_pos_dfont != std::wstring::npos && _pos_dfont == (oArray[nIndex].length() - 6)) - continue; - } - - // open file - CFontStream oStream; - if (!oStream.CreateFromFile(oArray[nIndex], pDataFontFile)) + if (FT_Open_Face( pLibrary, &oOpenArgs, nIndexFace, &pFace)) continue; - FT_Open_Args oOpenArgs; - oOpenArgs.flags = FT_OPEN_MEMORY | FT_OPEN_PARAMS; - oOpenArgs.memory_base = oStream.m_pData; - oOpenArgs.memory_size = oStream.m_lSize; + INT bBold = (pFace->style_flags & FT_STYLE_FLAG_BOLD ? 1 : 0); + INT bItalic = (pFace->style_flags & FT_STYLE_FLAG_ITALIC) ? 1 : 0; - oOpenArgs.num_params = 4; - oOpenArgs.params = pParams; + const char* pPostName = FT_Get_Postscript_Name(pFace); + std::string sPostscriptName = ""; + if (NULL != pPostName) + sPostscriptName = FT_Get_Postscript_Name(pFace); - FT_Face pFace = NULL; - if (FT_Open_Face( pLibrary, &oOpenArgs, 0, &pFace )) - continue; + INT bFixedWidth = FT_IS_FIXED_WIDTH( pFace ); - // TO DO: Шрифты, которые нельзя скейлить (т.е. изменять размер - // произвольно) мы не грузим. Возможно в будущем надо будет - // сделать, чтобы работал и такой вариант. (в Word такие шрифты - // не используются) - if ( !( pFace->face_flags & FT_FACE_FLAG_SCALABLE ) ) - { - FT_Done_Face( pFace ); - continue; - } + TT_OS2 *pOs2 = (TT_OS2 *)FT_Get_Sfnt_Table( pFace, ft_sfnt_os2 ); - int nFacesCount = pFace->num_faces; - if ( FT_Done_Face( pFace ) ) - continue; + BYTE* pPanose = NULL; + ULONG ulRange1 = 0, ulRange2 = 0, ulRange3 = 0, ulRange4 = 0, ulCodeRange1 = 0, ulCodeRange2 = 0; + USHORT usWidth = 0, usWeight = 0, usType = 0; + SHORT sFamilyClass = 0; - for ( int nIndexFace = 0; nIndexFace < nFacesCount; nIndexFace++ ) + SHORT shAvgCharWidth = 0, shAscent = 0, shDescent = 0, shLineGap = 0, shXHeight = 0, shCapHeight = 0; + if ( NULL != pOs2 ) { - if (FT_Open_Face( pLibrary, &oOpenArgs, nIndexFace, &pFace)) - continue; - - INT bBold = (pFace->style_flags & FT_STYLE_FLAG_BOLD ? 1 : 0); - INT bItalic = (pFace->style_flags & FT_STYLE_FLAG_ITALIC) ? 1 : 0; + pPanose = (BYTE *)pOs2->panose; - const char* pPostName = FT_Get_Postscript_Name(pFace); - std::string sPostscriptName = ""; - if (NULL != pPostName) - sPostscriptName = FT_Get_Postscript_Name(pFace); + ulRange1 = pOs2->ulUnicodeRange1; + ulRange2 = pOs2->ulUnicodeRange2; + ulRange3 = pOs2->ulUnicodeRange3; + ulRange4 = pOs2->ulUnicodeRange4; + ulCodeRange1 = pOs2->ulCodePageRange1; + ulCodeRange2 = pOs2->ulCodePageRange2; - INT bFixedWidth = FT_IS_FIXED_WIDTH( pFace ); + usWeight = pOs2->usWeightClass; + usWidth = pOs2->usWidthClass; - TT_OS2 *pOs2 = (TT_OS2 *)FT_Get_Sfnt_Table( pFace, ft_sfnt_os2 ); + sFamilyClass = pOs2->sFamilyClass; - BYTE* pPanose = NULL; - ULONG ulRange1 = 0, ulRange2 = 0, ulRange3 = 0, ulRange4 = 0, ulCodeRange1 = 0, ulCodeRange2 = 0; - USHORT usWidth = 0, usWeight = 0, usType = 0; - SHORT sFamilyClass = 0; + usType = pOs2->fsType; - SHORT shAvgCharWidth = 0, shAscent = 0, shDescent = 0, shLineGap = 0, shXHeight = 0, shCapHeight = 0; - if ( NULL != pOs2 ) + if ( 0 != pFace->units_per_EM ) { - pPanose = (BYTE *)pOs2->panose; - - ulRange1 = pOs2->ulUnicodeRange1; - ulRange2 = pOs2->ulUnicodeRange2; - ulRange3 = pOs2->ulUnicodeRange3; - ulRange4 = pOs2->ulUnicodeRange4; - ulCodeRange1 = pOs2->ulCodePageRange1; - ulCodeRange2 = pOs2->ulCodePageRange2; - - usWeight = pOs2->usWeightClass; - usWidth = pOs2->usWidthClass; - - sFamilyClass = pOs2->sFamilyClass; - - usType = pOs2->fsType; - - if ( 0 != pFace->units_per_EM ) - { - double dKoef = ( 1000 / (double)pFace->units_per_EM ); - shAvgCharWidth = (SHORT)(pOs2->xAvgCharWidth * dKoef); - shAscent = (SHORT)(pOs2->sTypoAscender * dKoef); - shDescent = (SHORT)(pOs2->sTypoDescender * dKoef); - shLineGap = (SHORT)(pOs2->sTypoLineGap * dKoef); - shXHeight = (SHORT)(pOs2->sxHeight * dKoef); - shCapHeight = (SHORT)(pOs2->sCapHeight * dKoef); - } - else - { - shAvgCharWidth = (SHORT)pOs2->xAvgCharWidth; - shAscent = (SHORT)pOs2->sTypoAscender; - shDescent = (SHORT)pOs2->sTypoDescender; - shLineGap = (SHORT)pOs2->sTypoLineGap; - shXHeight = (SHORT)pOs2->sxHeight; - shCapHeight = (SHORT)pOs2->sCapHeight; - } + double dKoef = ( 1000 / (double)pFace->units_per_EM ); + shAvgCharWidth = (SHORT)(pOs2->xAvgCharWidth * dKoef); + shAscent = (SHORT)(pOs2->sTypoAscender * dKoef); + shDescent = (SHORT)(pOs2->sTypoDescender * dKoef); + shLineGap = (SHORT)(pOs2->sTypoLineGap * dKoef); + shXHeight = (SHORT)(pOs2->sxHeight * dKoef); + shCapHeight = (SHORT)(pOs2->sCapHeight * dKoef); } + else + { + shAvgCharWidth = (SHORT)pOs2->xAvgCharWidth; + shAscent = (SHORT)pOs2->sTypoAscender; + shDescent = (SHORT)pOs2->sTypoDescender; + shLineGap = (SHORT)pOs2->sTypoLineGap; + shXHeight = (SHORT)pOs2->sxHeight; + shCapHeight = (SHORT)pOs2->sCapHeight; + } + } - if ( true ) + if ( true ) + { + // Специальная ветка для случаев, когда charset может быть задан не через значения + // ulCodePageRange, а непосредственно через тип Cmap. + + // Charset Name Charset Value(hex) Codepage number Platform_ID Encoding_ID Description + // ------------------------------------------------------------------------------------------------- + // + // SYMBOL_CHARSET 2 (x02) 3 0 Symbol + // SHIFTJIS_CHARSET 128 (x80) 932 3 2 ShiftJIS + // GB2313_CHARSET 134 (x86) 936 3 3 PRC + // CHINESEBIG5_CHARSET 136 (x88) 950 3 4 Big5 + // HANGEUL_CHARSET 129 (x81) 949 3 5 Wansung + // JOHAB_CHARSET 130 (x82) 1361 3 6 Johab + + for( int nIndex = 0; nIndex < pFace->num_charmaps; nIndex++ ) { - // Специальная ветка для случаев, когда charset может быть задан не через значения - // ulCodePageRange, а непосредственно через тип Cmap. - - // Charset Name Charset Value(hex) Codepage number Platform_ID Encoding_ID Description - // ------------------------------------------------------------------------------------------------- - // - // SYMBOL_CHARSET 2 (x02) 3 0 Symbol - // SHIFTJIS_CHARSET 128 (x80) 932 3 2 ShiftJIS - // GB2313_CHARSET 134 (x86) 936 3 3 PRC - // CHINESEBIG5_CHARSET 136 (x88) 950 3 4 Big5 - // HANGEUL_CHARSET 129 (x81) 949 3 5 Wansung - // JOHAB_CHARSET 130 (x82) 1361 3 6 Johab - - for( int nIndex = 0; nIndex < pFace->num_charmaps; nIndex++ ) - { - // Symbol - if ( !( ulCodeRange1 & 0x80000000 ) && 0 == pFace->charmaps[nIndex]->encoding_id && 3 == pFace->charmaps[nIndex]->platform_id ) - ulCodeRange1 |= 0x80000000; + // Symbol + if ( !( ulCodeRange1 & 0x80000000 ) && 0 == pFace->charmaps[nIndex]->encoding_id && 3 == pFace->charmaps[nIndex]->platform_id ) + ulCodeRange1 |= 0x80000000; - // ShiftJIS - if ( !( ulCodeRange1 & 0x00020000 ) && 2 == pFace->charmaps[nIndex]->encoding_id && 3 == pFace->charmaps[nIndex]->platform_id ) - ulCodeRange1 |= 0x00020000; + // ShiftJIS + if ( !( ulCodeRange1 & 0x00020000 ) && 2 == pFace->charmaps[nIndex]->encoding_id && 3 == pFace->charmaps[nIndex]->platform_id ) + ulCodeRange1 |= 0x00020000; - // PRC - if ( !( ulCodeRange1 & 0x00040000 ) && 3 == pFace->charmaps[nIndex]->encoding_id && 3 == pFace->charmaps[nIndex]->platform_id ) - ulCodeRange1 |= 0x00040000; + // PRC + if ( !( ulCodeRange1 & 0x00040000 ) && 3 == pFace->charmaps[nIndex]->encoding_id && 3 == pFace->charmaps[nIndex]->platform_id ) + ulCodeRange1 |= 0x00040000; - // Big5 - if ( !( ulCodeRange1 & 0x00100000 ) && 4 == pFace->charmaps[nIndex]->encoding_id && 3 == pFace->charmaps[nIndex]->platform_id ) - ulCodeRange1 |= 0x00100000; + // Big5 + if ( !( ulCodeRange1 & 0x00100000 ) && 4 == pFace->charmaps[nIndex]->encoding_id && 3 == pFace->charmaps[nIndex]->platform_id ) + ulCodeRange1 |= 0x00100000; - // Wansung - if ( !( ulCodeRange1 & 0x00080000 ) && 5 == pFace->charmaps[nIndex]->encoding_id && 3 == pFace->charmaps[nIndex]->platform_id ) - ulCodeRange1 |= 0x00080000; + // Wansung + if ( !( ulCodeRange1 & 0x00080000 ) && 5 == pFace->charmaps[nIndex]->encoding_id && 3 == pFace->charmaps[nIndex]->platform_id ) + ulCodeRange1 |= 0x00080000; - // Johab - if ( !( ulCodeRange1 & 0x00200000 ) && 6 == pFace->charmaps[nIndex]->encoding_id && 3 == pFace->charmaps[nIndex]->platform_id ) - ulCodeRange1 |= 0x00200000; - } + // Johab + if ( !( ulCodeRange1 & 0x00200000 ) && 6 == pFace->charmaps[nIndex]->encoding_id && 3 == pFace->charmaps[nIndex]->platform_id ) + ulCodeRange1 |= 0x00200000; } + } - NSFonts::EFontFormat eFormat = GetFontFormat( pFace ); + NSFonts::EFontFormat eFormat = GetFontFormat( pFace ); - bool bSupportFont = ((eFormat == NSFonts::fontTrueType) || ((nFlag & 1) && (eFormat == NSFonts::fontOpenType))); - if (!bSupportFont) - { - FT_Done_Face( pFace ); - continue; - } + bool bSupportFont = ((eFormat == NSFonts::fontTrueType) || ((nFlag & 1) && (eFormat == NSFonts::fontOpenType))); + if (!bSupportFont) + { + FT_Done_Face( pFace ); + continue; + } - std::wstring wsFamilyName = GetCorrectSfntName(pFace->family_name); - std::wstring wsStyleName = GetCorrectSfntName(pFace->style_name); + std::wstring wsFamilyName = GetCorrectSfntName(pFace->family_name); + std::wstring wsStyleName = GetCorrectSfntName(pFace->style_name); - bool isBadASCII = (std::wstring::npos != wsFamilyName.find('?')) ? true : false; + bool isBadASCII = (std::wstring::npos != wsFamilyName.find('?')) ? true : false; #ifdef _MAC - if (wsFamilyName.find(L".") == 0) - { - FT_Done_Face( pFace ); - continue; - } + if (wsFamilyName.find(L".") == 0) + { + FT_Done_Face( pFace ); + continue; + } #endif - NSFonts::CFontInfo* pFontInfo = new NSFonts::CFontInfo( wsFamilyName, - wsStyleName, - oArray[nIndex], - nIndexFace, - bBold, - bItalic, - bFixedWidth, - pPanose, - ulRange1, - ulRange2, - ulRange3, - ulRange4, - ulCodeRange1, - ulCodeRange2, - usWeight, - usWidth, - sFamilyClass, - eFormat, - shAvgCharWidth, - shAscent, - shDescent, - shLineGap, - shXHeight, - shCapHeight, - usType); - - if (pFace && FT_IS_SFNT(pFace)) - { - TT_Face pTTFace = (TT_Face)pFace; + NSFonts::CFontInfo* pFontInfo = new NSFonts::CFontInfo( wsFamilyName, + wsStyleName, + sFontPath, + nIndexFace, + bBold, + bItalic, + bFixedWidth, + pPanose, + ulRange1, + ulRange2, + ulRange3, + ulRange4, + ulCodeRange1, + ulCodeRange2, + usWeight, + usWidth, + sFamilyClass, + eFormat, + shAvgCharWidth, + shAscent, + shDescent, + shLineGap, + shXHeight, + shCapHeight, + usType); + + if (pFace && FT_IS_SFNT(pFace)) + { + TT_Face pTTFace = (TT_Face)pFace; - int nNamesCount = (int)pTTFace->num_names; - TT_NameRec* pNameRecs = pTTFace->name_table.names; + int nNamesCount = (int)pTTFace->num_names; + TT_NameRec* pNameRecs = pTTFace->name_table.names; - for (int nNameIndex = 0; nNameIndex < nNamesCount; ++nNameIndex) - { - TT_NameRec* rec = pNameRecs + nNameIndex; + for (int nNameIndex = 0; nNameIndex < nNamesCount; ++nNameIndex) + { + TT_NameRec* rec = pNameRecs + nNameIndex; - if (rec->nameID != TT_NAME_ID_FONT_FAMILY || rec->stringLength <= 0) - continue; + if (rec->nameID != TT_NAME_ID_FONT_FAMILY || rec->stringLength <= 0) + continue; - std::string sEncoding = ""; - switch (rec->platformID) - { - case TT_PLATFORM_APPLE_UNICODE: + std::string sEncoding = ""; + switch (rec->platformID) + { + case TT_PLATFORM_APPLE_UNICODE: + { + sEncoding = "UTF-16BE"; + break; + } + case TT_PLATFORM_MACINTOSH: + { + break; + } + case TT_PLATFORM_MICROSOFT: + { + switch (rec->encodingID) { + case TT_MS_ID_SYMBOL_CS: + case TT_MS_ID_UNICODE_CS: sEncoding = "UTF-16BE"; break; - } - case TT_PLATFORM_MACINTOSH: - { + case TT_MS_ID_UCS_4: + //sEncoding = "UCS4"; // см tt_ + sEncoding = "UTF-16BE"; break; - } - case TT_PLATFORM_MICROSOFT: - { - switch (rec->encodingID) - { - case TT_MS_ID_SYMBOL_CS: - case TT_MS_ID_UNICODE_CS: - sEncoding = "UTF-16BE"; - break; - case TT_MS_ID_UCS_4: - //sEncoding = "UCS4"; // см tt_ - sEncoding = "UTF-16BE"; - break; - //case TT_MS_ID_SJIS: - // sEncoding = "Shift-JIS"; - // break; - //case TT_MS_ID_GB2312: - // sEncoding = "GB2312"; - // break; - //case TT_MS_ID_BIG_5: - // sEncoding = "Big5"; - // break; - default: - break; - } - } + //case TT_MS_ID_SJIS: + // sEncoding = "Shift-JIS"; + // break; + //case TT_MS_ID_GB2312: + // sEncoding = "GB2312"; + // break; + //case TT_MS_ID_BIG_5: + // sEncoding = "Big5"; + // break; default: break; } + } + default: + break; + } - if (!sEncoding.empty()) + if (!sEncoding.empty()) + { + FT_Stream stream = pTTFace->name_table.stream; + FT_Memory memory = pFace->memory; + FT_Error error = 0; + + if ( FT_QNEW_ARRAY ( rec->string, rec->stringLength ) || + FT_STREAM_SEEK( rec->stringOffset ) || + FT_STREAM_READ( rec->string, rec->stringLength ) ) + { + FT_FREE( rec->string ); + rec->stringLength = 0; + } + else { - FT_Stream stream = pTTFace->name_table.stream; - FT_Memory memory = pFace->memory; - FT_Error error = 0; + NSUnicodeConverter::CUnicodeConverter oConverter; + std::wstring sNameW = oConverter.toUnicode((char*)rec->string, (unsigned int)rec->stringLength, sEncoding.c_str()); - if ( FT_QNEW_ARRAY ( rec->string, rec->stringLength ) || - FT_STREAM_SEEK( rec->stringOffset ) || - FT_STREAM_READ( rec->string, rec->stringLength ) ) + if (std::wstring::npos == sNameW.find(wsFamilyName) && std::wstring::npos == wsFamilyName.find(sNameW)) { - FT_FREE( rec->string ); - rec->stringLength = 0; - } - else - { - NSUnicodeConverter::CUnicodeConverter oConverter; - std::wstring sNameW = oConverter.toUnicode((char*)rec->string, (unsigned int)rec->stringLength, sEncoding.c_str()); + std::vector<std::wstring>::iterator iter = pFontInfo->names.begin(); + for (std::vector<std::wstring>::iterator iter = pFontInfo->names.begin(); iter != pFontInfo->names.end(); iter++) + { + if (*iter == sNameW) + break; + } - if (std::wstring::npos == sNameW.find(wsFamilyName) && std::wstring::npos == wsFamilyName.find(sNameW)) + if (isBadASCII && pFontInfo->names.empty()) { - std::vector<std::wstring>::iterator iter = pFontInfo->names.begin(); - for (std::vector<std::wstring>::iterator iter = pFontInfo->names.begin(); iter != pFontInfo->names.end(); iter++) - { - if (*iter == sNameW) - break; - } - - if (isBadASCII && pFontInfo->names.empty()) - { - wsFamilyName = sNameW; - pFontInfo->m_wsFontName = wsFamilyName; - isBadASCII = false; - } - else if (iter == pFontInfo->names.end()) - { - pFontInfo->names.push_back(sNameW); + wsFamilyName = sNameW; + pFontInfo->m_wsFontName = wsFamilyName; + isBadASCII = false; + } + else if (iter == pFontInfo->names.end()) + { + pFontInfo->names.push_back(sNameW); #if 0 - FILE* f = fopen("D:\\111.txt", "a+"); - fprintf(f, "%s: %s\n", U_TO_UTF8(wsFamilyName).c_str(), U_TO_UTF8(sNameW).c_str()); - fclose(f); + FILE* f = fopen("D:\\111.txt", "a+"); + fprintf(f, "%s: %s\n", U_TO_UTF8(wsFamilyName).c_str(), U_TO_UTF8(sNameW).c_str()); + fclose(f); #endif - } } } } } } + } - Add(pFontInfo); + Add(pFontInfo); - FT_Done_Face( pFace ); + FT_Done_Face( pFace ); + } +} + +void CFontList::Add(const std::wstring& sFontPath, NSFonts::IFontStream* pStream, int nFlag) +{ + if (!pStream) + return; + + FT_Library pLibrary = NULL; + if (FT_Init_FreeType(&pLibrary)) + return; + + FT_Parameter *pParams = (FT_Parameter *)::malloc( sizeof(FT_Parameter) * 4 ); + pParams[0].tag = FT_MAKE_TAG( 'i', 'g', 'p', 'f' ); + pParams[0].data = NULL; + pParams[1].tag = FT_MAKE_TAG( 'i', 'g', 'p', 's' ); + pParams[1].data = NULL; + pParams[2].tag = FT_PARAM_TAG_IGNORE_PREFERRED_FAMILY; + pParams[2].data = NULL; + pParams[3].tag = FT_PARAM_TAG_IGNORE_PREFERRED_SUBFAMILY; + pParams[3].data = NULL; + + Add(pLibrary, pParams, sFontPath, (CFontStream*)pStream, nFlag); + + ::free( pParams ); + FT_Done_FreeType(pLibrary); +} + +void CFontList::LoadFromArrayFiles(std::vector<std::wstring>& oArray, int nFlag) +{ + size_t nCount = oArray.size(); + + FT_Library pLibrary = NULL; + if (FT_Init_FreeType(&pLibrary)) + return; + + FT_Parameter *pParams = (FT_Parameter *)::malloc( sizeof(FT_Parameter) * 4 ); + pParams[0].tag = FT_MAKE_TAG( 'i', 'g', 'p', 'f' ); + pParams[0].data = NULL; + pParams[1].tag = FT_MAKE_TAG( 'i', 'g', 'p', 's' ); + pParams[1].data = NULL; + pParams[2].tag = FT_PARAM_TAG_IGNORE_PREFERRED_FAMILY; + pParams[2].data = NULL; + pParams[3].tag = FT_PARAM_TAG_IGNORE_PREFERRED_SUBFAMILY; + pParams[3].data = NULL; + + // определяем размер буфера, чтобы не выделять много кусков, а обойтись одним + int nMaxFontSize = 0; + for (size_t nIndex = 0; nIndex < nCount; ++nIndex) + { + NSFile::CFileBinary oFile; + if (oFile.OpenFile(oArray[nIndex])) + { + int nSizeTmp = (int)oFile.GetFileSize(); + if (nSizeTmp > 100000000) + { + // такие огромные шрифты не учитываем + oArray.erase(oArray.begin() + nIndex, oArray.begin() + nIndex + 1); + nIndex--; + nCount--; + } + + if (nMaxFontSize < nSizeTmp) + nMaxFontSize = nSizeTmp; + } + } + + BYTE* pDataFontFile = new BYTE[nMaxFontSize]; + + for (size_t nIndex = 0; nIndex < nCount; ++nIndex) + { + if ((nFlag & 2) != 0) + { + std::wstring::size_type _pos_dfont = oArray[nIndex].find(L".dfont"); + if (_pos_dfont != std::wstring::npos && _pos_dfont == (oArray[nIndex].length() - 6)) + continue; } + + // open file + CFontStream oStream; + if (!oStream.CreateFromFile(oArray[nIndex], pDataFontFile)) + continue; + + Add(pLibrary, pParams, oArray[nIndex], &oStream, nFlag); } RELEASEARRAYOBJECTS(pDataFontFile); @@ -1707,7 +1740,7 @@ static long GetNextNameValue(HKEY key, const std::wstring& sSubkey, std::wstring #endif -std::vector<std::wstring> CApplicationFonts::GetSetupFontFiles() +std::vector<std::wstring> CApplicationFonts::GetSetupFontFiles(const bool& bIsUseUserFonts) { #if defined(_WIN32) || defined (_WIN64) // Ищем директорию с фонтами (обычно это C:\Windows\Fonts) @@ -1778,13 +1811,16 @@ std::vector<std::wstring> CApplicationFonts::GetSetupFontFiles() { std::vector<std::wstring> oArray2 = NSDirectory::GetFiles(L"C:\\Windows\\Fonts", true); - wchar_t sUserName[1000]; - DWORD nUserNameLen = 1000 + 1; - GetUserNameW(sUserName, &nUserNameLen); - std::wstring strUserName(sUserName, nUserNameLen - 1); + if (bIsUseUserFonts) + { + wchar_t sUserName[1000]; + DWORD nUserNameLen = 1000 + 1; + GetUserNameW(sUserName, &nUserNameLen); + std::wstring strUserName(sUserName, nUserNameLen - 1); - NSDirectory::GetFiles2(L"C:\\Users\\" + strUserName + L"\\AppData\\Local\\Microsoft\\Windows\\Fonts", oArray2, false); - NSDirectory::GetFiles2(L"C:\\Users\\" + strUserName + L"\\AppData\\Local\\Microsoft\\FontCache\\4\\CloudFonts", oArray2, true); + NSDirectory::GetFiles2(L"C:\\Users\\" + strUserName + L"\\AppData\\Local\\Microsoft\\Windows\\Fonts", oArray2, false); + NSDirectory::GetFiles2(L"C:\\Users\\" + strUserName + L"\\AppData\\Local\\Microsoft\\FontCache\\4\\CloudFonts", oArray2, true); + } for (std::vector<std::wstring>::iterator i = oArray2.begin(); i != oArray2.end(); i++) { @@ -1800,9 +1836,11 @@ std::vector<std::wstring> CApplicationFonts::GetSetupFontFiles() std::vector<std::wstring> _array = NSDirectory::GetFiles(L"/usr/share/fonts", true); NSDirectory::GetFiles2(L"/usr/share/X11/fonts", _array, true); NSDirectory::GetFiles2(L"/usr/X11R6/lib/X11/fonts", _array, true); - NSDirectory::GetFiles2(L"/usr/local/share/fonts", _array, true); NSDirectory::GetFiles2(L"/run/host/fonts", _array, true); + if (bIsUseUserFonts) + NSDirectory::GetFiles2(L"/usr/local/share/fonts", _array, true); + #ifndef BUILDING_WASM_MODULE std::wstring custom_fonts_path = NSSystemUtils::GetEnvVariable(L"CUSTOM_FONTS_PATH"); if (!custom_fonts_path.empty()) diff --git a/DesktopEditor/fontengine/ApplicationFonts.h b/DesktopEditor/fontengine/ApplicationFonts.h index 742403cb0a2..2b2658451f7 100644 --- a/DesktopEditor/fontengine/ApplicationFonts.h +++ b/DesktopEditor/fontengine/ApplicationFonts.h @@ -306,6 +306,7 @@ class CFontList : public NSFonts::IFontList int GetXHeightPenalty(SHORT shCandXHeight, SHORT shReqXHeight); int GetCapHeightPenalty(SHORT shCandCapHeight, SHORT shReqCapHeight); bool CheckEmbeddingRights(const USHORT* ushRights, const USHORT& fsType); + void Add(FT_Library pLibrary, FT_Parameter* pParams, const std::wstring& sFontPath, CFontStream* pStream, int nFlag); public: static NSFonts::EFontFormat GetFontFormat(FT_Face pFace); @@ -316,6 +317,7 @@ class CFontList : public NSFonts::IFontList void LoadFromFolder (const std::wstring& strDirectory); bool CheckLoadFromFolderBin(const std::wstring& strDirectory); void CheckLoadFromSelectionBin(const std::wstring& strDirectory, BYTE* pData, DWORD len); + void Add (const std::wstring& sFontPath, NSFonts::IFontStream* pStream, int nFlag = 0); void Add (NSFonts::CFontInfo* pInfo); NSFonts::CFontInfo* GetByParams (NSFonts::CFontSelectFormat& oSelect, bool bIsDictionaryUse = true); std::vector<NSFonts::CFontInfo*> GetAllByName (const std::wstring& strFontName); @@ -345,7 +347,7 @@ class CApplicationFonts : public NSFonts::IApplicationFonts void InitializeFromBin(BYTE* pData, unsigned int nLen); void InitializeRanges(unsigned char* data); - std::vector<std::wstring> GetSetupFontFiles(); + std::vector<std::wstring> GetSetupFontFiles(const bool& bIsUseUserFonts = true); void InitializeFromArrayFiles(std::vector<std::wstring>& files, int nFlag = 0); #if defined(_WIN32) || defined (_WIN64) diff --git a/DesktopEditor/fontengine/ApplicationFontsWorker.cpp b/DesktopEditor/fontengine/ApplicationFontsWorker.cpp index 2894c39a760..7b20de85676 100644 --- a/DesktopEditor/fontengine/ApplicationFontsWorker.cpp +++ b/DesktopEditor/fontengine/ApplicationFontsWorker.cpp @@ -356,6 +356,8 @@ class CApplicationFontsWorker_private virtual void Check(const int& nCode, const unsigned int& nIndex) { + if (nCode > m_nMaxSymbols) + return; if (nCode > m_nMax) m_nMax = nCode; if (nCode < m_nMin) @@ -794,6 +796,8 @@ class CApplicationFontsWorker_private std::wstring sNameCorrect = pPair->second.m_sName; NSStringUtils::string_replace(sNameCorrect, L"\\", L"\\\\"); NSStringUtils::string_replace(sNameCorrect, L"\"", L"\\\""); + NSStringUtils::string_replace(sNameCorrect, L"\n", L""); + NSStringUtils::string_replace(sNameCorrect, L"\r", L""); oWriterJS += sNameCorrect; oWriterJS.AddSize(120); @@ -869,6 +873,12 @@ class CApplicationFontsWorker_private mapFontsPriorityStandard.insert(std::pair<std::wstring, int>(L"SimHei", 34)); mapFontsPriorityStandard.insert(std::pair<std::wstring, int>(L"Meiryo", 35)); +#ifdef _MAC + mapFontsPriorityStandard.insert(std::pair<std::wstring, int>(L"PingFang SC", 36)); + mapFontsPriorityStandard.insert(std::pair<std::wstring, int>(L"PingFang TC", 37)); + mapFontsPriorityStandard.insert(std::pair<std::wstring, int>(L"PingFang HK", 38)); +#endif + NSFonts::CApplicationFontsSymbols oApplicationChecker; // приоритеты шрифтов. по имени (все стили) @@ -1566,6 +1576,7 @@ class CApplicationFontsWorker_private CApplicationFontsWorker::CApplicationFontsWorker() { m_bIsUseSystemFonts = true; + m_bIsUseSystemUserFonts = true; m_bIsNeedThumbnails = true; m_bIsUseOpenType = true; m_bIsUseAllVersions = false; @@ -1658,7 +1669,7 @@ NSFonts::IApplicationFonts* CApplicationFontsWorker::Check() std::vector<std::wstring> strFontsW_Cur; if (m_bIsUseSystemFonts) - strFontsW_CurSrc = pApplicationF->GetSetupFontFiles(); + strFontsW_CurSrc = pApplicationF->GetSetupFontFiles(m_bIsUseSystemUserFonts); for (std::vector<std::wstring>::iterator i = m_arAdditionalFolders.begin(); i != m_arAdditionalFolders.end(); i++) { diff --git a/DesktopEditor/fontengine/ApplicationFontsWorker.h b/DesktopEditor/fontengine/ApplicationFontsWorker.h index 585718f76ae..ee12e5a4e29 100644 --- a/DesktopEditor/fontengine/ApplicationFontsWorker.h +++ b/DesktopEditor/fontengine/ApplicationFontsWorker.h @@ -36,7 +36,7 @@ #include <vector> #include "../graphics/pro/Fonts.h" -#define ONLYOFFICE_FONTS_VERSION 11 +#define ONLYOFFICE_FONTS_VERSION 12 #define ONLYOFFICE_ALL_FONTS_VERSION 2 class CApplicationFontsWorkerBreaker @@ -51,6 +51,8 @@ class GRAPHICS_DECL CApplicationFontsWorker public: // использовать ли системные шрифты bool m_bIsUseSystemFonts; + bool m_bIsUseSystemUserFonts; + // дополнительные папки с шрифтами std::vector<std::wstring> m_arAdditionalFolders; diff --git a/DesktopEditor/fontengine/FontFile.cpp b/DesktopEditor/fontengine/FontFile.cpp index 60539da69b5..f6075cfb798 100644 --- a/DesktopEditor/fontengine/FontFile.cpp +++ b/DesktopEditor/fontengine/FontFile.cpp @@ -104,9 +104,12 @@ FT_Error FT_Load_Glyph_Wrapper( FT_Face face, FT_Err_Invalid_CharMap_Handle = 0x26; FT_Err_Invalid_Cache_Handle = 0x27; FT_Err_Invalid_Stream_Handle = 0x28; + + FT_Err_Code_Overflow = 0x83; + FT_Err_Invalid_Reference = 0x86; */ - if ((bHintsSupport == TRUE) && (nErr > 0x10 && nErr < 0x28 || nErr == 131)) + if ((bHintsSupport == TRUE) && ((nErr > 0x10 && nErr < 0x28) || (nErr >= 0x83 && nErr <= 0x8D))) { int nErr2 = FT_Load_Glyph(face, glyph_index, 40970); diff --git a/DesktopEditor/fontengine/MemoryStream.h b/DesktopEditor/fontengine/MemoryStream.h index 00581913dfb..4abebc12907 100644 --- a/DesktopEditor/fontengine/MemoryStream.h +++ b/DesktopEditor/fontengine/MemoryStream.h @@ -1,4 +1,4 @@ -/* +/* * (c) Copyright Ascensio System SIA 2010-2023 * * This program is a free software product. You can redistribute it and/or @@ -38,22 +38,24 @@ #ifdef _DEBUG #define _LOGGING_NATIVE_ #else -//#define _LOGGING_NATIVE_ +// #define _LOGGING_NATIVE_ #endif #ifdef _LINUX #include <stdlib.h> #endif +#ifndef _ARM_ALIGN_ #define _ARM_ALIGN_ +#endif static void LOGGING(const std::string& strFile, const std::wstring& strMessage) { #ifdef _LOGGING_NATIVE_ FILE* f = fopen(strFile.c_str(), "a+"); - + BYTE* pData = NULL; - LONG lLen = 0; + LONG lLen = 0; NSFile::CUtf8Converter::GetUtf8StringFromUnicode(strMessage.c_str(), (LONG)strMessage.length(), pData, lLen); pData[lLen] = 0; @@ -79,10 +81,10 @@ namespace NSMemoryStream public: CMemoryStream() { - m_pBuffer = NULL; - m_pBufferMem = NULL; + m_pBuffer = NULL; + m_pBufferMem = NULL; - m_lSize = 0; + m_lSize = 0; } virtual ~CMemoryStream() { @@ -100,10 +102,10 @@ namespace NSMemoryStream inline void Clear() { - m_lSize = 0; + m_lSize = 0; - m_pBuffer = NULL; - m_pBufferMem = NULL; + m_pBuffer = NULL; + m_pBufferMem = NULL; } inline void ClearNoAttack() @@ -133,17 +135,17 @@ namespace NSMemoryStream BYTE* pNew = new BYTE[m_lSize]; memcpy(pNew, m_pBuffer, m_pBufferMem - m_pBuffer); - m_pBufferMem = pNew + (m_pBufferMem - m_pBuffer); + m_pBufferMem = pNew + (m_pBufferMem - m_pBuffer); RELEASEARRAYOBJECTS(m_pBuffer); - m_pBuffer = pNew; + m_pBuffer = pNew; } } else { - m_lSize = 1000; - m_pBuffer = new BYTE[m_lSize]; - m_pBufferMem = m_pBuffer; + m_lSize = 1000; + m_pBuffer = new BYTE[m_lSize]; + m_pBufferMem = m_pBuffer; CheckBufferSize(lPlus); } @@ -166,23 +168,34 @@ namespace NSMemoryStream } inline void WriteLONG(const LONG& lValue) { - CheckBufferSize(sizeof(INT)); + CheckBufferSize(sizeof(INT)); #ifdef _ARM_ALIGN_ - INT v = lValue; - memcpy(m_pBufferMem, &v, sizeof(INT)); + INT v = lValue; + memcpy(m_pBufferMem, &v, sizeof(INT)); #else - *((INT*)(m_pBufferMem)) = (INT)lValue; + *((INT*)(m_pBufferMem)) = (INT)lValue; #endif - m_pBufferMem += sizeof(INT); + m_pBufferMem += sizeof(INT); + } + inline void WriteUSHORT(const USHORT& lValue) + { + CheckBufferSize(sizeof(USHORT)); +#ifdef _ARM_ALIGN_ + USHORT v = lValue; + memcpy(m_pBufferMem, &v, sizeof(USHORT)); +#else + *((USHORT*)(m_pBufferMem)) = (USHORT)lValue; +#endif + m_pBufferMem += sizeof(USHORT); } inline void WriteDouble(const double& dValue) { CheckBufferSize(sizeof(double)); #ifdef _ARM_ALIGN_ - double v = dValue; - memcpy(m_pBufferMem, &v, sizeof(double)); + double v = dValue; + memcpy(m_pBufferMem, &v, sizeof(double)); #else - *((double*)(m_pBufferMem)) = dValue; + *((double*)(m_pBufferMem)) = dValue; #endif m_pBufferMem += sizeof(double); } @@ -202,112 +215,50 @@ namespace NSMemoryStream } inline void WriteStringA2(const char* pData, int nLen) { - CheckBufferSize(nLen + sizeof(INT)); + CheckBufferSize(nLen + sizeof(INT)); #ifdef __ANDROID__ memcpy(m_pBufferMem, &nLen, sizeof(INT)); #else *((INT*)(m_pBufferMem)) = (INT)nLen; #endif - m_pBufferMem += sizeof(INT); + m_pBufferMem += sizeof(INT); memcpy(m_pBufferMem, pData, nLen); m_pBufferMem += nLen; } - inline void WriteString(const wchar_t* pData, int nLen) + inline void WriteStringTruncate2(const wchar_t* pData, int nLenDouble) { -#ifdef _ARM_ALIGN_ - CheckBufferSize(nLen + sizeof(USHORT)); - USHORT v = (USHORT)(nLen); - memcpy(m_pBufferMem, &v, sizeof(USHORT)); - m_pBufferMem += sizeof(USHORT); - - int nLen2 = nLen << 1; + if (sizeof(wchar_t) == 2) + { + memcpy(m_pBufferMem, pData, nLenDouble); + } + else + { + int len = nLenDouble >> 1; + USHORT* mass = new USHORT[len]; + for (int i = 0; i < len; ++i) + mass[i] = (USHORT)pData[i]; + memcpy(m_pBufferMem, mass, nLenDouble); + RELEASEARRAYOBJECTS(mass); + } + m_pBufferMem += nLenDouble; + } - if (sizeof(wchar_t) == 2) - { - memcpy(m_pBufferMem, pData, nLen2); - } - else - { - int len = nLen >> 1; - USHORT* mass = new USHORT[len]; - for (int i = 0; i < len; ++i) - mass[i] = (USHORT)pData[i]; - memcpy(m_pBufferMem, mass, nLen2); - RELEASEARRAYOBJECTS(mass); - } - m_pBufferMem += nLen2; -#else - CheckBufferSize(nLen + sizeof(USHORT)); - *((USHORT*)(m_pBufferMem)) = (USHORT)nLen; - m_pBufferMem += sizeof(USHORT); - + inline void WriteString(const wchar_t* pData, int nLen) + { int nLen2 = nLen << 1; - - if (sizeof(wchar_t) == 2) - { - memcpy(m_pBufferMem, pData, nLen2); - } - else - { - int len = nLen >> 1; - USHORT* mass = new USHORT[len]; - for (int i = 0; i < len; ++i) - mass[i] = (USHORT)pData[i]; - memcpy(m_pBufferMem, mass, nLen2); - RELEASEARRAYOBJECTS(mass); - } - m_pBufferMem += nLen2; -#endif + CheckBufferSize(nLen2 + sizeof(USHORT)); + WriteUSHORT((USHORT)(nLen)); + WriteStringTruncate2(pData, nLen2); } inline void WriteString2(const wchar_t* pData, int nLen) { -#ifdef _ARM_ALIGN_ - int nLen2 = nLen << 1; - - CheckBufferSize(nLen2 + sizeof(INT)); - INT v = (INT)(nLen2); - memcpy(m_pBufferMem, &v, sizeof(INT)); - m_pBufferMem += sizeof(INT); - - if (sizeof(wchar_t) == 2) - { - memcpy(m_pBufferMem, pData, nLen2); - } - else - { - USHORT* mass = new USHORT[nLen]; - for (int i = 0; i < nLen; ++i) - mass[i] = (USHORT)pData[i]; - memcpy(m_pBufferMem, mass, nLen2); - RELEASEARRAYOBJECTS(mass); - } - - m_pBufferMem += nLen2; -#else int nLen2 = nLen << 1; - - CheckBufferSize(nLen2 + sizeof(INT)); - *((INT*)(m_pBufferMem)) = (INT)nLen2; - m_pBufferMem += sizeof(INT); - - if (sizeof(wchar_t) == 2) - { - memcpy(m_pBufferMem, pData, nLen2); - } - else - { - USHORT* mass = new USHORT[nLen]; - for (int i = 0; i < nLen; ++i) - mass[i] = (USHORT)pData[i]; - memcpy(m_pBufferMem, mass, nLen2); - RELEASEARRAYOBJECTS(mass); - } - - m_pBufferMem += nLen2; -#endif + CheckBufferSize(nLen2 + sizeof(INT)); + WriteLONG(nLen2); + WriteStringTruncate2(pData, nLen2); } inline void __WriteBYTE(const BYTE& lValue) @@ -326,20 +277,20 @@ namespace NSMemoryStream inline void __WriteLONG(const LONG& lValue) { #ifdef _ARM_ALIGN_ - INT v = (INT)lValue; - memcpy(m_pBufferMem, &v, sizeof(INT)); + INT v = (INT)lValue; + memcpy(m_pBufferMem, &v, sizeof(INT)); #else - *((INT*)(m_pBufferMem)) = (INT)lValue; + *((INT*)(m_pBufferMem)) = (INT)lValue; #endif - m_pBufferMem += sizeof(INT); + m_pBufferMem += sizeof(INT); } inline void __WriteDouble(const double& dValue) { #ifdef _ARM_ALIGN_ - double v = dValue; - memcpy(m_pBufferMem, &v, sizeof(double)); + double v = dValue; + memcpy(m_pBufferMem, &v, sizeof(double)); #else - *((double*)(m_pBufferMem)) = dValue; + *((double*)(m_pBufferMem)) = dValue; #endif m_pBufferMem += sizeof(double); } @@ -350,7 +301,7 @@ namespace NSMemoryStream memcpy(m_pBufferMem, pData, len); m_pBufferMem += len; } - }; -} + }; +} // namespace NSMemoryStream #endif // _BUILD_MEMORYSTREAM_H_ diff --git a/DesktopEditor/fontengine/TextShaper.cpp b/DesktopEditor/fontengine/TextShaper.cpp index 8b88c0ca4ea..4e509d5cc81 100644 --- a/DesktopEditor/fontengine/TextShaper.cpp +++ b/DesktopEditor/fontengine/TextShaper.cpp @@ -356,6 +356,12 @@ namespace NSShaper return ((FT_Face)face)->glyph->bitmap.buffer; } + int FT_Get_Glyph_Render_BufferSize(void* face) + { + FT_GlyphSlot slot = ((FT_Face)face)->glyph; + return slot->bitmap.pitch * slot->bitmap.rows; + } + bool FT_Get_Glyph_Render_Params(void* face, int render_mode, CExternalPointer* result) { FT_GlyphSlot slot = ((FT_Face)face)->glyph; diff --git a/DesktopEditor/fontengine/TextShaper.h b/DesktopEditor/fontengine/TextShaper.h index 7a862f283ba..286505700bf 100644 --- a/DesktopEditor/fontengine/TextShaper.h +++ b/DesktopEditor/fontengine/TextShaper.h @@ -70,6 +70,7 @@ namespace NSShaper GRAPHICS_DECL bool FT_Get_Glyph_Render_Params(void* face, int render_mode, CExternalPointer* result); GRAPHICS_DECL unsigned char* FT_Get_Glyph_Render_Buffer(void* face); + GRAPHICS_DECL int FT_Get_Glyph_Render_BufferSize(void* face); GRAPHICS_DECL void FT_Glyph_Get_CBox(void* glyph, unsigned int bbox_mode, CExternalPointer* result); diff --git a/DesktopEditor/fontengine/js/after.py b/DesktopEditor/fontengine/js/after.py index 970097a028b..58d95dd8036 100644 --- a/DesktopEditor/fontengine/js/after.py +++ b/DesktopEditor/fontengine/js/after.py @@ -8,8 +8,11 @@ base.configure_common_apps() base.replaceInFile("./deploy/fonts.js", "__ATPOSTRUN__=[];", "__ATPOSTRUN__=[function(){window[\"AscFonts\"].onLoadModule();}];") base.replaceInFile("./deploy/fonts.js", "__ATPOSTRUN__ = [];", "__ATPOSTRUN__=[function(){window[\"AscFonts\"].onLoadModule();}];") -base.replaceInFile("./deploy/fonts.js", "function getBinaryPromise()", "function getBinaryPromise2()") +base.replaceInFile("./deploy/fonts.js", "function getBinaryPromise(", "function getBinaryPromise2(") base.replaceInFile("./deploy/fonts_ie.js", "__ATPOSTRUN__=[];", "__ATPOSTRUN__=[function(){window[\"AscFonts\"].onLoadModule();}];") base.replaceInFile("./deploy/fonts_ie.js", "__ATPOSTRUN__ = [];", "__ATPOSTRUN__=[function(){window[\"AscFonts\"].onLoadModule();}];") -base.replaceInFile("./deploy/fonts_ie.js", "function getBinaryPromise()", "function getBinaryPromise2()") +base.replaceInFile("./deploy/fonts_ie.js", "function getBinaryPromise(", "function getBinaryPromise2(") + +base.cmd_in_dir("../../../Common/js", "python", ["./min.py", "./../../DesktopEditor/fontengine/js/deploy/fonts.js", "WHITESPACE_ONLY"]) +base.cmd_in_dir("../../../Common/js", "python", ["./min.py", "./../../DesktopEditor/fontengine/js/deploy/fonts_ie.js", "WHITESPACE_ONLY"]) diff --git a/DesktopEditor/fontengine/js/allfonts/after.py b/DesktopEditor/fontengine/js/allfonts/after.py new file mode 100644 index 00000000000..e74e8784b11 --- /dev/null +++ b/DesktopEditor/fontengine/js/allfonts/after.py @@ -0,0 +1,11 @@ +#!/usr/bin/env python + +import sys +sys.path.append("../../../../../build_tools/scripts") +import base +import os + +base.configure_common_apps() +base.copy_file("./index.html", "./deploy/index.html") + +#base.cmd_in_dir("../../../../Common/js", "python", ["./min.py", "./../../DesktopEditor/fontengine/js/allfonts/deploy/allfonts.js", "WHITESPACE_ONLY"]) diff --git a/DesktopEditor/fontengine/js/allfonts/before.py b/DesktopEditor/fontengine/js/allfonts/before.py new file mode 100644 index 00000000000..c83f64b4778 --- /dev/null +++ b/DesktopEditor/fontengine/js/allfonts/before.py @@ -0,0 +1,9 @@ +#!/usr/bin/env python + +import sys +import os +sys.path.append("../../../../../build_tools/scripts") +import base + +base.configure_common_apps() +print("before...") diff --git a/DesktopEditor/fontengine/js/allfonts/index.html b/DesktopEditor/fontengine/js/allfonts/index.html new file mode 100644 index 00000000000..f629e2c854b --- /dev/null +++ b/DesktopEditor/fontengine/js/allfonts/index.html @@ -0,0 +1,11 @@ +<!doctype html> +<html style="width:100%;height:100%;margin:0;padding:0;"> +<head> + <title>ONLYOFFICE Fonts + + + + + + + \ No newline at end of file diff --git a/DesktopEditor/fontengine/js/allfonts/liballfont.json b/DesktopEditor/fontengine/js/allfonts/liballfont.json new file mode 100644 index 00000000000..6e130163d3e --- /dev/null +++ b/DesktopEditor/fontengine/js/allfonts/liballfont.json @@ -0,0 +1,41 @@ +{ + "name": "allfonts", + "res_folder": "./deploy", + "wasm": true, + "asm": false, + "run_before": "before.py", + "run_after": "after.py", + "base_js_content": "./module.js", + + "compiler_flags": [ + "-O3", + "-fexceptions", + "-Wno-unused-command-line-argument", + "-s ALLOW_MEMORY_GROWTH=1", + "-s FILESYSTEM=0", + "-s ENVIRONMENT='web'", + "-s LLD_REPORT_UNDEFINED", + "-s ASYNCIFY" + ], + "exported_functions": [ + "_malloc", + "_free", + + "_parseSystemFonts", + "_createFontBinary", + "_deleteFontBinary" + ], + "include_path": [ + ], + "define": [ + "__linux__", "_LINUX", "UNIX", "_QT" + ], + "compile_files_array": [ + { + "folder": "./src", + "files": [ + "main.cpp" + ] + } + ] +} diff --git a/DesktopEditor/fontengine/js/allfonts/module.js b/DesktopEditor/fontengine/js/allfonts/module.js new file mode 100644 index 00000000000..1a6bc5c684b --- /dev/null +++ b/DesktopEditor/fontengine/js/allfonts/module.js @@ -0,0 +1,74 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2024 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ + +(function(window, undefined) { + +window['AscFonts'] = window['AscFonts'] || {}; +let AscFonts = window['AscFonts']; + +//string_utf8 + +//module + +AscFonts.checkSystemFonts = async function() +{ + self.queryLocalFonts() + .then(async function (fonts) { + AscFonts.systemFonts = fonts; + Module["_parseSystemFonts"](fonts.length); + }) + .catch(function (err) { + console.error(err.name, err.message); + }); +}; + +AscFonts.getSystemFont = async function(index) +{ + let buffer = await (await AscFonts.systemFonts[index].blob()).arrayBuffer(); + let array8 = new Uint8Array(buffer); + var pointer = Module["_malloc"](array8.length); + Module["HEAP8"].set(array8, pointer); + return Module["_createFontBinary"](index, pointer, array8.length); + + AscFonts.systemFonts[index].blob() + .then(async function (blob) { + let buffer = await blob.arrayBuffer(); + let array8 = new Uint8Array(buffer); + + var pointer = Module["_malloc"](array8.length); + Module["HEAP8"].set(array8, pointer); + + return Module["_createFontBinary"](index, pointer, array8.length); + }); +}; + +})(window, undefined); diff --git a/DesktopEditor/fontengine/js/allfonts/src/main.cpp b/DesktopEditor/fontengine/js/allfonts/src/main.cpp new file mode 100644 index 00000000000..7022a53a600 --- /dev/null +++ b/DesktopEditor/fontengine/js/allfonts/src/main.cpp @@ -0,0 +1,69 @@ +#include +#include + +#ifdef _WIN32 +#define WASM_EXPORT __declspec(dllexport) +#else +#define WASM_EXPORT __attribute__((visibility("default"))) +#endif + +class CFontBinary +{ +public: + unsigned char* Data = NULL; + int Size = 0; + int Index = 0; + +public: + CFontBinary() + { + } + ~CFontBinary() + { + if (NULL != Data) + delete [] Data; + } +}; + +#include "emscripten.h" +//EM_JS +EM_ASYNC_JS(CFontBinary*, js_get_system_font, (int index), { + return AscFonts.getSystemFont(index); +}); + +#ifdef __cplusplus +extern "C" { +#endif + +WASM_EXPORT CFontBinary* createFontBinary(int index, unsigned char* data, int size) +{ + CFontBinary* pFont = new CFontBinary(); + pFont->Index = index; + pFont->Data = data; + pFont->Size = size; + + return pFont; +} + +WASM_EXPORT void deleteFontBinary(CFontBinary* pFont) +{ + delete pFont; +} + +WASM_EXPORT void parseSystemFonts(int size) +{ + printf("[native] fonts: %d\n", size); + + for (int i = 0; i < size; ++i) + { + CFontBinary* pFont = js_get_system_font(i); + + printf("[native] %d, %d\n", pFont->Index, pFont->Size); + + delete pFont; + } +} + +#ifdef __cplusplus +} +#endif diff --git a/DesktopEditor/fontengine/js/cpp/text.cpp b/DesktopEditor/fontengine/js/cpp/text.cpp index 6679455e8e7..98572427384 100644 --- a/DesktopEditor/fontengine/js/cpp/text.cpp +++ b/DesktopEditor/fontengine/js/cpp/text.cpp @@ -1,5 +1,5 @@ /* - * (c) Copyright Ascensio System SIA 2010-2023 + * (c) Copyright Ascensio System SIA 2010-2024 * * This program is a free software product. You can redistribute it and/or * modify it under the terms of the GNU Affero General Public License (AGPL) diff --git a/DesktopEditor/fontengine/js/engine/module_js.js b/DesktopEditor/fontengine/js/engine/module_js.js index 1745f2118df..c3fca57a628 100644 --- a/DesktopEditor/fontengine/js/engine/module_js.js +++ b/DesktopEditor/fontengine/js/engine/module_js.js @@ -1,5 +1,5 @@ /* - * (c) Copyright Ascensio System SIA 2010-2023 + * (c) Copyright Ascensio System SIA 2010-2024 * * This program is a free software product. You can redistribute it and/or * modify it under the terms of the GNU Affero General Public License (AGPL) @@ -35,7 +35,20 @@ var AscFonts = window['AscFonts']; if (window["NATIVE_EDITOR_ENJINE"]) - window.setImmediate = function(fn) { fn(); }; +{ + var immediateArray = []; + window.setImmediate = function(fn) { + if (immediateArray) + immediateArray.push(fn); + else + fn(); + }; + window.immediateRun = function() { + for (var i = 0; i < immediateArray.length; i++) + immediateArray[i](); + immediateArray = undefined; + }; +} var setImmediate = window.setImmediate; @@ -518,6 +531,45 @@ ZLib.prototype.getImageAsSvg = function(path) return string; }; +/** + * Get image file raw data. this memory was copied and detach from archive. + * @returns {Uint8Array} + */ +ZLib.prototype.getImageBuffer = function(path) +{ + let result = { + type : 0, + data : null + }; + result.type = this.getImageType(path); + if (result.type === 0) + return null; + + let fileData = this.getFile(path); + result.data = new Uint8Array(fileData.length); + result.data.set(fileData); + + if (result.type != 10 && + result.type != 21) + { + return result; + } + + result.type = 24; + // Source was saved as result.data for using original image in native convertations. + // But for js we need svg for metafiles. + + let encodedData = Module["_Raster_Encode"](this.files[path].p + 4, fileData.length, 24); + let encodedSize = Module["_Raster_GetEncodedSize"](encodedData); + let encodedBuffer = Module["_Raster_GetEncodedBuffer"](encodedData); + + let fileDataEnc = new Uint8Array(Module["HEAP8"].buffer, encodedBuffer, encodedSize); + result.dataBlob = new Uint8Array(fileDataEnc.length); + result.dataBlob.set(fileDataEnc); + + Module["_Raster_DestroyEncodedData"](encodedData); + return result; +}; /** * Get image blob for browser * @returns {Blob} @@ -595,6 +647,8 @@ AscFonts.Hyphen_Word = function(lang, word) return hyphens; }; +if (window["NATIVE_EDITOR_ENJINE"]) + window.immediateRun(); AscFonts.onLoadModule(); })(window, undefined); diff --git a/DesktopEditor/fontengine/js/engine/module_native.js b/DesktopEditor/fontengine/js/engine/module_native.js index 6c28f43e003..933da591dee 100644 --- a/DesktopEditor/fontengine/js/engine/module_native.js +++ b/DesktopEditor/fontengine/js/engine/module_native.js @@ -1,5 +1,5 @@ /* - * (c) Copyright Ascensio System SIA 2010-2023 + * (c) Copyright Ascensio System SIA 2010-2024 * * This program is a free software product. You can redistribute it and/or * modify it under the terms of the GNU Affero General Public License (AGPL) @@ -35,7 +35,7 @@ window['AscFonts'] = window['AscFonts'] || {}; var AscFonts = window['AscFonts']; -var g_native_engine = CreateEmbedObject("CTextMeasurerEmbed"); +var g_native_engine = null; function CReturnObject() { @@ -236,4 +236,6 @@ AscFonts.Hyphen_Word = function(lang, word) AscFonts.onLoadModule(); AscFonts.onLoadModule(); +window["InitNativeTextMeasurer"] = function() { g_native_engine = CreateEmbedObject("CTextMeasurerEmbed"); }; + })(window, undefined); diff --git a/DesktopEditor/fontengine/js/libfont.json b/DesktopEditor/fontengine/js/libfont.json index 200fbfdd268..fe4cb2acc5d 100644 --- a/DesktopEditor/fontengine/js/libfont.json +++ b/DesktopEditor/fontengine/js/libfont.json @@ -100,6 +100,7 @@ "FT_CONFIG_OPTION_SYSTEM_ZLIB", "GRAPHICS_NO_USE_DYNAMIC_LIBRARY", "HYPHEN_ENGINE_DISABLE_FILESYSTEM", + "METAFILE_DISABLE_FILESYSTEM", "HAVE_UNISTD_H", "HAVE_FCNTL_H", "_ARM_ALIGN_", "METAFILE_SUPPORT_WMF_EMF", @@ -110,7 +111,9 @@ "_getcwd=getcwd", "NO_CONSOLE_IO", "BUILD_ZLIB_AS_SOURCES", - "IMAGE_CHECKER_DISABLE_XML" + "IMAGE_CHECKER_DISABLE_XML", + + "BUILDING_WASM_MODULE" ], "compile_files_array": [ { @@ -166,10 +169,13 @@ "hb-buffer-serialize.cc", "hb-buffer-verify.cc", "hb-buffer.cc", + "hb-cairo-utils.cc", + "hb-cairo.cc", "hb-common.cc", "hb-coretext.cc", "hb-directwrite.cc", "hb-draw.cc", + "hb-face-builder.cc", "hb-face.cc", "hb-fallback-shape.cc", "hb-font.cc", @@ -192,23 +198,26 @@ "hb-ot-meta.cc", "hb-ot-metrics.cc", "hb-ot-name.cc", - "hb-ot-shape-complex-arabic.cc", - "hb-ot-shape-complex-default.cc", - "hb-ot-shape-complex-hangul.cc", - "hb-ot-shape-complex-hebrew.cc", - "hb-ot-shape-complex-indic-table.cc", - "hb-ot-shape-complex-indic.cc", - "hb-ot-shape-complex-khmer.cc", - "hb-ot-shape-complex-myanmar.cc", - "hb-ot-shape-complex-syllabic.cc", - "hb-ot-shape-complex-thai.cc", - "hb-ot-shape-complex-use.cc", - "hb-ot-shape-complex-vowel-constraints.cc", "hb-ot-shape-fallback.cc", "hb-ot-shape-normalize.cc", "hb-ot-shape.cc", + "hb-ot-shaper-arabic.cc", + "hb-ot-shaper-default.cc", + "hb-ot-shaper-hangul.cc", + "hb-ot-shaper-hebrew.cc", + "hb-ot-shaper-indic-table.cc", + "hb-ot-shaper-indic.cc", + "hb-ot-shaper-khmer.cc", + "hb-ot-shaper-myanmar.cc", + "hb-ot-shaper-syllabic.cc", + "hb-ot-shaper-thai.cc", + "hb-ot-shaper-use.cc", + "hb-ot-shaper-vowel-constraints.cc", "hb-ot-tag.cc", "hb-ot-var.cc", + "hb-outline.cc", + "hb-paint-extents.cc", + "hb-paint.cc", "hb-set.cc", "hb-shape-plan.cc", "hb-shape.cc", @@ -219,11 +228,16 @@ "hb-subset-cff1.cc", "hb-subset-cff2.cc", "hb-subset-input.cc", + "hb-subset-instancer-solver.cc", "hb-subset-plan.cc", + "hb-subset-repacker.cc", "hb-subset.cc", "hb-ucd.cc", "hb-unicode.cc", - "hb-uniscribe.cc" + "hb-uniscribe.cc", + "hb-wasm-api.cc", + "hb-wasm-shape.cc", + "graph/gsubgpos-context.cc" ] }, { @@ -251,6 +265,10 @@ "folder": "../../", "files": ["graphics/Image.cpp", "raster/BgraFrame.cpp", "raster/ImageFileFormatChecker.cpp"] }, + { + "folder": "../../raster/", + "files": ["PICT/PICFile.cpp", "PICT/pic.cpp"] + }, { "folder": "../../graphics/pro/js/qt/raster", "files": ["pro_Fonts_empty.cpp", "pro_Graphics_empty.cpp", "raster.cpp"] diff --git a/DesktopEditor/fontengine/js/module.js b/DesktopEditor/fontengine/js/module.js index 48e231674b7..a71cee881c2 100644 --- a/DesktopEditor/fontengine/js/module.js +++ b/DesktopEditor/fontengine/js/module.js @@ -1,5 +1,5 @@ /* - * (c) Copyright Ascensio System SIA 2010-2023 + * (c) Copyright Ascensio System SIA 2010-2024 * * This program is a free software product. You can redistribute it and/or * modify it under the terms of the GNU Affero General Public License (AGPL) @@ -441,9 +441,9 @@ function onLoadFontsModule(window, undefined) this.codePoints = codePointsBuffer; this.codePointsCount = 0 } - CCodePointsCalculator.prototype.start = function() + CCodePointsCalculator.prototype.start = function(startCluster) { - this.currentCluster = 0; + this.currentCluster = startCluster; this.currentCodePoint = 0; this.codePointsCount = 0; } @@ -452,10 +452,14 @@ function onLoadFontsModule(window, undefined) this.currentCodePoint += this.codePointsCount; let nCodePointsCount = 0; - + if (cluster < this.currentCluster) { - // TODO: RTL + while (this.currentCluster > cluster) + { + this.currentCluster -= this.clusterBuffer[this.currentCodePoint + nCodePointsCount]; + ++nCodePointsCount; + } } else { @@ -562,9 +566,12 @@ function onLoadFontsModule(window, undefined) let retObj = AscFonts.HB_ShapeText(fontFile, STRING_POINTER, features, script, direction, language, READER); if (retObj["error"]) return; - - CODEPOINTS_CALCULATOR.start(); - let prevCluster = -1, type, flags, gid, cluster, x_advance, y_advance, x_offset, y_offset, codePoints; + + let isRtl = direction === AscFonts.HB_DIRECTION.HB_DIRECTION_RTL; + + CODEPOINTS_CALCULATOR.start(isRtl ? CLUSTER_MAX : 0); + let prevCluster = -1; + let type, flags, gid, cluster, x_advance, y_advance, x_offset, y_offset; let isLigature = false; let nWidth = 0; let reader = READER; @@ -579,10 +586,10 @@ function onLoadFontsModule(window, undefined) y_advance = reader.readInt(); x_offset = reader.readInt(); y_offset = reader.readInt(); - + if (cluster !== prevCluster && -1 !== prevCluster) { - CODEPOINTS_CALCULATOR.calculate(cluster); + CODEPOINTS_CALCULATOR.calculate(isRtl ? prevCluster : cluster); textShaper.FlushGrapheme(AscFonts.GetGrapheme(CODEPOINTS_CALCULATOR), nWidth, CODEPOINTS_CALCULATOR.getCount(), isLigature); nWidth = 0; } @@ -597,9 +604,10 @@ function onLoadFontsModule(window, undefined) AscFonts.AddGlyphToGrapheme(gid, x_advance, y_advance, x_offset, y_offset); nWidth += x_advance * COEF; } - CODEPOINTS_CALCULATOR.calculate(CLUSTER_MAX); + + CODEPOINTS_CALCULATOR.calculate(isRtl ? 0 : CLUSTER_MAX); textShaper.FlushGrapheme(AscFonts.GetGrapheme(CODEPOINTS_CALCULATOR), nWidth, CODEPOINTS_CALCULATOR.getCount(), isLigature); - + retObj["free"](); }; @@ -753,6 +761,14 @@ function onLoadFontsModule(window, undefined) { return this.engine["getImageBlob"](path); }; + /** + * Get image file raw data. this memory was copied and detach from archive. + * @returns {Uint8Array} + */ + ZLib.prototype.getImageBuffer = function(path) + { + return this.engine["getImageBuffer"](path); + }; /** * Get all file paths in archive * @returns {Array} @@ -764,10 +780,84 @@ function onLoadFontsModule(window, undefined) AscCommon.ZLib = ZLib; + function ZlibImageBlobs() + { + this.url2BlobUrl = {}; + this.blobUrl2Data = {}; + this.url2Base64 = {}; + + this.nativeBlobCounter = 1; + } + ZlibImageBlobs.prototype.getBlobUrl = function(path, zip) + { + if (this.url2BlobUrl[path]) + return this.url2BlobUrl[path]; + + let result = zip.getImageBuffer(path); + if (result == null) + return ""; + + let blobUrl = ""; + let blobType = AscCommon.openXml.GetMimeType((24 !== result["type"]) ? AscCommon.GetFileExtension(path) : "svg"); + + if (window["NATIVE_EDITOR_ENJINE"]) + { + blobUrl = "blob:internal-image" + this.nativeBlobCounter++; + } + else + { + try + { + let blob = new Blob([result["dataBlob"] ? result["dataBlob"] : result["data"]], {type: blobType}); + blobUrl = window.URL.createObjectURL(blob); + } + catch (e) + { + blobUrl = "error"; + AscCommon.consoleLog("ERROR: Image blob was not loaded"); + } + } + + this.blobUrl2Data[blobUrl] = result; + this.url2BlobUrl[path] = blobUrl; + return blobUrl; + }; + ZlibImageBlobs.prototype.getImageBase64 = function(url) + { + if (this.url2Base64[url]) + return this.url2Base64[url]; + + let obj = this.blobUrl2Data[url]; + if (!obj) + return url; + + let header = ""; + switch (obj.type) + { + case 3: + header = "data:image/jpeg;base64,"; + break; + case 24: + header = "data:image/svg+xml;base64,"; + break; + case 4: + default: + header = "data:image/png;base64,"; + } + + this.url2Base64[url] = header + AscCommon.Base64.encode(obj.data); + return this.url2Base64[url]; + }; + + window["AscCommon"].g_oDocumentBlobUrls = new ZlibImageBlobs(); + if (AscCommon["CZLibEngineJS"]) AscCommon["CZLibEngineJS"].prototype["isModuleInit"] = true; - window.nativeZlibEngine = new ZLib(); + if (window["NATIVE_EDITOR_ENJINE"]) + window["InitNativeZLib"] = function() { window.nativeZlibEngine = new ZLib(); }; + else + window.nativeZlibEngine = new ZLib(); function Hyphenation() { diff --git a/DesktopEditor/graphics/AlphaMask.cpp b/DesktopEditor/graphics/AlphaMask.cpp index 7cde5983a85..b0863980b8f 100644 --- a/DesktopEditor/graphics/AlphaMask.cpp +++ b/DesktopEditor/graphics/AlphaMask.cpp @@ -1,69 +1,88 @@ -#include "AlphaMask.h" -#include "AlphaMask_private.h" +#include "AlphaMask_p.h" namespace Aggplus { CAlphaMask::CAlphaMask() - : m_internal(new CAlphaMask_private()) + : m_pBuffer(NULL) + {} + + CAlphaMask::CAlphaMask(BYTE *pBuffer, EMaskDataType eDataType, bool bExternalBuffer) + : m_pBuffer(pBuffer), m_enDataType(eDataType), m_bExternalBuffer(bExternalBuffer) {} CAlphaMask::~CAlphaMask() { - RELEASEOBJECT(m_internal) + if (!m_bExternalBuffer) + RELEASEARRAYOBJECTS(m_pBuffer); } - void CAlphaMask::Clear() + BYTE *CAlphaMask::GetBuffer() { - m_internal->Clear(); + return m_pBuffer; } - StatusAlphaMask CAlphaMask::GetStatus() const - { - return m_internal->GetStatus(); - } - AMaskDataType CAlphaMask::GetDataType() const + EMaskDataType CAlphaMask::GetDataType() const { - return m_internal->GetDataType(); + return m_enDataType; } - Status CAlphaMask::CreateImageBuffer(UINT unWidth, UINT unHeight) + UINT CAlphaMask::GetStep() const { - return m_internal->Create(unWidth, unHeight, ImageBuffer); + switch(m_enDataType) + { + case EMaskDataType::ImageBuffer: return 4; + case EMaskDataType::AlphaBuffer: return 1; + } } - Status CAlphaMask::CreateAlphaBuffer(UINT unWidth, UINT unHeight) + Status CAlphaMask::Create(UINT unWidth, UINT unHeight, EMaskDataType eDataType) { - return m_internal->Create(unWidth, unHeight, AlphaBuffer); - } + if (0 == unWidth || 0 == unHeight) + return InvalidParameter; - Status CAlphaMask::LoadFromAlphaBuffer(BYTE *pBuffer, UINT unWidth, UINT unHeight, bool bExternalBuffer) - { - return m_internal->LoadFromBuffer(pBuffer, unWidth, unHeight, AlphaBuffer, bExternalBuffer); - } + m_enDataType = eDataType; + m_bExternalBuffer = false; - Status CAlphaMask::LoadFromImageBuffer(BYTE *pBuffer, UINT unWidth, UINT unHeight, bool bExternalBuffer) - { - return m_internal->LoadFromBuffer(pBuffer, unWidth, unHeight, ImageBuffer, bExternalBuffer); - } + UINT unSize = unWidth * unHeight * GetStep(); + + m_pBuffer = new BYTE[unSize]; - Status CAlphaMask::LoadFromFile(const std::wstring &wsFilePath) - { - return m_internal->LoadFromFile(wsFilePath); + if (NULL == m_pBuffer) + return OutOfMemory; + + memset(m_pBuffer, 0x00, unSize); + + return Ok; } - Status CAlphaMask::LoadFromImage(IGrObject *pGrObject, bool bCopy) + Status CAlphaMask::LoadFromBuffer(BYTE *pBuffer, EMaskDataType eDataType, bool bExternalBuffer) { - return m_internal->LoadFromImage(pGrObject, bCopy); + m_pBuffer = pBuffer; + m_enDataType = eDataType; + m_bExternalBuffer = bExternalBuffer; + return Ok; } - BYTE *CAlphaMask::GetMask() + CSoftMask::CSoftMask(BYTE* pBuffer, unsigned int unWidth, unsigned int unHeight, bool bFlip, bool bRGB, bool bAlpha) { - return m_internal->GetMask(); + if (bAlpha) + m_pInternal = new CSoftMaskAlpha(pBuffer, unWidth, unHeight, false, bFlip); + else + { + if (bRGB) + m_pInternal = new CSoftMaskBGRAgray(pBuffer, unWidth, unHeight, false, bFlip); + else + m_pInternal = new CSoftMaskRGBAgray(pBuffer, unWidth, unHeight, false, bFlip); + } } - - CAlphaMask &CAlphaMask::operator=(const CAlphaMask &oAlphaMask) + CSoftMask::~CSoftMask() { - *m_internal = *oAlphaMask.m_internal; - return *this; + RELEASEOBJECT(m_pInternal); } + + unsigned int CSoftMask::GetStep() const { return m_pInternal->GetStep(); } + unsigned int CSoftMask::GetWidth() const { return m_pInternal->GetWidth(); } + unsigned int CSoftMask::GetHeight() const { return m_pInternal->GetHeight(); } + BYTE* CSoftMask::GetBuffer() { return m_pInternal->GetBuffer(); } + ESoftMaskType CSoftMask::GetDataType() { return m_pInternal->GetDataType(); } } diff --git a/DesktopEditor/graphics/AlphaMask.h b/DesktopEditor/graphics/AlphaMask.h index a90eef39fc6..f47a14e96b8 100644 --- a/DesktopEditor/graphics/AlphaMask.h +++ b/DesktopEditor/graphics/AlphaMask.h @@ -1,52 +1,61 @@ #ifndef _BUILD_ALPHAMASK_H_ #define _BUILD_ALPHAMASK_H_ -#include #include "aggplustypes.h" #include "../common/IGrObject.h" #include "./config.h" namespace Aggplus { - enum StatusAlphaMask - { - EmptyAlphaMask, - GenerationAlphaMask, - ApplyingAlphaMask - }; - - enum AMaskDataType + enum class EMaskDataType { ImageBuffer, AlphaBuffer }; - class CAlphaMask_private; class GRAPHICS_DECL CAlphaMask : public IGrObject { public: CAlphaMask(); + CAlphaMask(BYTE* pBuffer, EMaskDataType eDataType, bool bExternalBuffer = true); virtual ~CAlphaMask(); - StatusAlphaMask GetStatus() const; - AMaskDataType GetDataType() const; + BYTE* GetBuffer(); + EMaskDataType GetDataType() const; + UINT GetStep() const; - void Clear(); + Status Create(UINT unWidth, UINT unHeight, EMaskDataType eDataType); + Status LoadFromBuffer(BYTE* pBuffer, EMaskDataType eDataType, bool bExternalBuffer = true); + private: + BYTE *m_pBuffer; + EMaskDataType m_enDataType; + bool m_bExternalBuffer; + }; - Status CreateImageBuffer(UINT unWidth, UINT unHeight); - Status CreateAlphaBuffer(UINT unWidth, UINT unHeight); + enum class ESoftMaskType + { + RGBGrayBuffer, + BGRGrayBuffer, + Alpha4Buffer + }; - Status LoadFromAlphaBuffer(BYTE* pBuffer, UINT unWidth, UINT unHeight, bool bExternalBuffer = true); - Status LoadFromImageBuffer(BYTE* pBuffer, UINT unWidth, UINT unHeight, bool bExternalBuffer = true); + class CSoftMask_private; + class GRAPHICS_DECL CSoftMask : public IGrObject + { + public: + CSoftMask(BYTE* pBuffer, unsigned int unWidth, unsigned int unHeight, bool bFlip, bool bRGB, bool bAlpha); + ~CSoftMask(); - Status LoadFromFile(const std::wstring& wsFilePath); - Status LoadFromImage(IGrObject* pGrObject, bool bCopy = true); + unsigned int GetStep() const; + unsigned int GetWidth() const; + unsigned int GetHeight() const; + BYTE* GetBuffer(); + ESoftMaskType GetDataType(); - BYTE* GetMask(); + private: + CSoftMask_private* m_pInternal; - CAlphaMask& operator=(const CAlphaMask& oAlphaMask); - public: - CAlphaMask_private *m_internal; + friend class CGraphics; }; } diff --git a/DesktopEditor/graphics/AlphaMask_p.h b/DesktopEditor/graphics/AlphaMask_p.h new file mode 100644 index 00000000000..42a59c71669 --- /dev/null +++ b/DesktopEditor/graphics/AlphaMask_p.h @@ -0,0 +1,96 @@ +#ifndef _BUILD_ALPHAMASK_P_H_ +#define _BUILD_ALPHAMASK_P_H_ + +#include "AlphaMask.h" +#include +#include + +#include "../agg-2.4/include/agg_rendering_buffer.h" +#include "../agg-2.4/include/agg_scanline_u.h" +#include "../agg-2.4/include/agg_alpha_mask_u8.h" + +namespace Aggplus +{ + class CSoftMask_private + { + public: + virtual ~CSoftMask_private() + { + BYTE* pBuffer = m_oRenderingBuffer.buf(); + if (NULL != pBuffer) + { + if (!m_bExternalBuffer) + RELEASEARRAYOBJECTS(pBuffer); + + m_oRenderingBuffer.attach(NULL, 0, 0, 0); + } + } + + unsigned int GetStep() const { return 4; } + unsigned int GetWidth() const { return m_unWidth; } + unsigned int GetHeight() const { return m_unHeight; } + BYTE* GetBuffer() { return m_oRenderingBuffer.buf(); } + + virtual ESoftMaskType GetDataType() const = 0; + virtual bool GetSwapRGB() const { return true; }; + + protected: + CSoftMask_private(BYTE* pBuffer, unsigned int unWidth, unsigned int unHeight, bool bExternalBuffer, bool bFlip) + { + m_bExternalBuffer = bExternalBuffer; + m_unWidth = unWidth; + m_unHeight = unHeight; + m_oRenderingBuffer.attach(pBuffer, unWidth, unHeight, (bFlip ? -1 : 1) * GetStep() * unWidth); + } + + agg::rendering_buffer m_oRenderingBuffer; + bool m_bExternalBuffer; + unsigned int m_unWidth; + unsigned int m_unHeight; + }; + + class CSoftMaskBGRAgray : public CSoftMask_private + { + public: + CSoftMaskBGRAgray(BYTE* pBuffer, unsigned int unWidth, unsigned int unHeight, bool bExternalBuffer, bool bFlip) + : CSoftMask_private(pBuffer, unWidth, unHeight, bExternalBuffer, bFlip), m_oAlphaMask(m_oRenderingBuffer), m_oScanLine(m_oAlphaMask) {} + + agg::scanline_u8_am& GetScanline() { return m_oScanLine; } + virtual ESoftMaskType GetDataType() const override { return ESoftMaskType::BGRGrayBuffer; } + + private: + agg::alpha_mask_bgra32gray m_oAlphaMask; + agg::scanline_u8_am m_oScanLine; + }; + + class CSoftMaskRGBAgray : public CSoftMask_private + { + public: + CSoftMaskRGBAgray(BYTE* pBuffer, unsigned int unWidth, unsigned int unHeight, bool bExternalBuffer, bool bFlip) + : CSoftMask_private(pBuffer, unWidth, unHeight, bExternalBuffer, bFlip), m_oAlphaMask(m_oRenderingBuffer), m_oScanLine(m_oAlphaMask) {} + + agg::scanline_u8_am& GetScanline() { return m_oScanLine; } + virtual bool GetSwapRGB() const override { return false; }; + virtual ESoftMaskType GetDataType() const override { return ESoftMaskType::RGBGrayBuffer; } + + private: + agg::alpha_mask_rgba32gray m_oAlphaMask; + agg::scanline_u8_am m_oScanLine; + }; + + class CSoftMaskAlpha : public CSoftMask_private + { + public: + CSoftMaskAlpha(BYTE* pBuffer, unsigned int unWidth, unsigned int unHeight, bool bExternalBuffer, bool bFlip) + : CSoftMask_private(pBuffer, unWidth, unHeight, bExternalBuffer, bFlip), m_oAlphaMask(m_oRenderingBuffer), m_oScanLine(m_oAlphaMask) {} + + agg::scanline_u8_am& GetScanline() { return m_oScanLine; } + virtual ESoftMaskType GetDataType() const override { return ESoftMaskType::Alpha4Buffer; } + + private: + agg::alpha_mask_rgba32a m_oAlphaMask; + agg::scanline_u8_am m_oScanLine; + }; +} + +#endif // _BUILD_ALPHAMASK_P_H_ diff --git a/DesktopEditor/graphics/AlphaMask_private.cpp b/DesktopEditor/graphics/AlphaMask_private.cpp deleted file mode 100644 index 5ba08ec6b10..00000000000 --- a/DesktopEditor/graphics/AlphaMask_private.cpp +++ /dev/null @@ -1,218 +0,0 @@ -#include "AlphaMask_private.h" -#include "../raster/BgraFrame.h" - -namespace Aggplus -{ - CAlphaMask_private::CAlphaMask_private() - : m_enStatus(EmptyAlphaMask), m_pImageData(NULL), m_pAlphaBufferData(NULL) - {} - - CAlphaMask_private::~CAlphaMask_private() - { - Clear(); - } - - StatusAlphaMask CAlphaMask_private::GetStatus() const - { - return m_enStatus; - } - - AMaskDataType CAlphaMask_private::GetDataType() const - { - return m_enDataType; - } - - void CAlphaMask_private::Clear() - { - BYTE *pBuffer = m_oRenderingBuffer.buf(); - if (NULL != pBuffer) - { - if (!m_bExternalBuffer) - RELEASEARRAYOBJECTS(pBuffer); - - m_oRenderingBuffer.attach(NULL, 0, 0, 0); - } - - RELEASEOBJECT(m_pImageData) - RELEASEOBJECT(m_pAlphaBufferData) - - m_enStatus = EmptyAlphaMask; - } - - Status CAlphaMask_private::Create(UINT unWidth, UINT unHeight, AMaskDataType enDataType) - { - if (0 == unWidth || 0 == unHeight) - return InvalidParameter; - - BYTE* pAlphaBufffer = new BYTE[unWidth * unHeight * ((enDataType == ImageBuffer) ? 4 : 1)]; - - if (NULL == pAlphaBufffer) - return OutOfMemory; - - Set(pAlphaBufffer, unWidth, unHeight, enDataType); - - if (enDataType == ImageBuffer) - m_pImageData->m_oRendererBase.clear(agg::rgba8(0, 0, 0)); - else if (enDataType == AlphaBuffer) - m_pAlphaBufferData->m_oRendererBase.clear(agg::gray8(0)); - - m_enStatus = GenerationAlphaMask; - m_bExternalBuffer = false; - - return Ok; - } - - Status CAlphaMask_private::LoadFromBuffer(BYTE *pBuffer, UINT unWidth, UINT unHeight, AMaskDataType enBufferType, bool bExternalBuffer) - { - if (NULL == pBuffer || 0 == unWidth || 0 == unHeight) - return InvalidParameter; - - Set(pBuffer, unWidth, unHeight, enBufferType); - - m_enStatus = ApplyingAlphaMask; - m_bExternalBuffer = bExternalBuffer; - - return Ok; - } - - Status CAlphaMask_private::LoadFromFile(const std::wstring &wsFilePath) - { - if (wsFilePath.empty()) - return InvalidParameter; - - CBgraFrame oFrame; - - if (!oFrame.OpenFile(wsFilePath)) - return GenericError; - - UINT unWidth = oFrame.get_Width(); - UINT unHeight = oFrame.get_Height(); - - Set(oFrame.get_Data(), unWidth, unHeight, ImageBuffer); - - oFrame.put_Data(NULL); - - m_enStatus = ApplyingAlphaMask; - m_bExternalBuffer = false; - - return Ok; - } - - Status CAlphaMask_private::LoadFromImage(IGrObject *pGrObject, bool bCopy) - { - if (NULL == pGrObject) - return InvalidParameter; - - CImage *pImage = (CImage*)pGrObject; - - if (Ok != pImage->GetLastStatus()) - return GenericError; - - UINT unWidth = pImage->GetWidth(); - UINT unHeight = pImage->GetHeight(); - - BYTE *pBuffer = NULL; - - if (bCopy) - { - const UINT unSize = 4 * unWidth * unWidth; - - pBuffer = new BYTE[unSize]; - memcpy(pBuffer, pImage->GetData(), unSize); - } - else - pBuffer = pImage->GetData(); - - Set(pBuffer, unWidth, unHeight, ImageBuffer); - - return Ok; - } - - RenBaseBGRA32 &CAlphaMask_private::GetRendererBaseImage() - { - return m_pImageData->m_oRendererBase; - } - - ScanlineBGRA32Gray &CAlphaMask_private::GetScanlineImage() - { - return m_pImageData->m_oScanLine; - } - - ScanlineGray8 &CAlphaMask_private::GetScanlineABuffer() - { - return m_pAlphaBufferData->m_oScanLine; - } - - BYTE *CAlphaMask_private::GetMask() - { - return m_oRenderingBuffer.buf(); - } - - void CAlphaMask_private::StartApplying() - { - m_enStatus = ApplyingAlphaMask; - } - - CAlphaMask_private &CAlphaMask_private::operator=(const CAlphaMask_private &oAlphaMask) - { - Clear(); - - m_enDataType = oAlphaMask.m_enDataType; - m_enStatus = oAlphaMask.m_enStatus; - m_bExternalBuffer = false; - - if (EmptyAlphaMask == m_enStatus) - return *this; - - const UINT unSize = oAlphaMask.m_oRenderingBuffer.width() * oAlphaMask.m_oRenderingBuffer.height() * ((m_enDataType == ImageBuffer) ? 4 : 1); - - BYTE* pBuffer = new BYTE[unSize]; - - memcpy(pBuffer, oAlphaMask.m_oRenderingBuffer.buf(), unSize); - - Set(pBuffer, oAlphaMask.m_oRenderingBuffer.width(), oAlphaMask.m_oRenderingBuffer.height(), m_enDataType); - - return *this; - } - - void CAlphaMask_private::Set(BYTE *pBuffer, UINT unWidth, UINT unHeight, AMaskDataType enDataType) - { - Clear(); - - m_enDataType = enDataType; - - switch (enDataType) - { - case ImageBuffer: - { - m_oRenderingBuffer.attach(pBuffer, unWidth, unHeight, 4 * unWidth); - - m_pImageData = new AMaskFromImage(m_oRenderingBuffer); - - m_pImageData->m_oPixfmt.attach(m_oRenderingBuffer); - m_pImageData->m_oRendererBase.attach(m_pImageData->m_oPixfmt); - m_pImageData->m_oAlphaMask.attach(m_oRenderingBuffer); - - break; - } - case AlphaBuffer: - { - m_oRenderingBuffer.attach(pBuffer, unWidth, unHeight, unWidth); - - m_pAlphaBufferData = new AMaskFromABuffer(m_oRenderingBuffer); - - m_pAlphaBufferData->m_oPixfmt.attach(m_oRenderingBuffer); - m_pAlphaBufferData->m_oRendererBase.attach(m_pAlphaBufferData->m_oPixfmt); - m_pAlphaBufferData->m_oAlphaMask.attach(m_oRenderingBuffer); - - break; - } - } - } - - agg::rendering_buffer &CAlphaMask_private::GetRenderingBuffer() - { - return m_oRenderingBuffer; - } -} - diff --git a/DesktopEditor/graphics/AlphaMask_private.h b/DesktopEditor/graphics/AlphaMask_private.h deleted file mode 100644 index 60eb6a1e34f..00000000000 --- a/DesktopEditor/graphics/AlphaMask_private.h +++ /dev/null @@ -1,78 +0,0 @@ -#ifndef _BUILD_ALPHAMASK_PRIVATE_H_ -#define _BUILD_ALPHAMASK_PRIVATE_H_ - -#include -#include "aggplustypes.h" -#include "./AlphaMask.h" - -#include "../agg-2.4/include/agg_alpha_mask_u8.h" -#include "../agg-2.4/include/agg_renderer_base.h" -#include "../agg-2.4/include/agg_pixfmt_gray.h" -#include "../agg-2.4/include/agg_pixfmt_rgba.h" -#include "../agg-2.4/include/agg_scanline_u.h" - -namespace Aggplus -{ - template - struct TAlphaMaskData - { - TAlphaMaskData(agg::rendering_buffer& oRenderingBuffer) - : m_oPixfmt(oRenderingBuffer), m_oScanLine(m_oAlphaMask) - {}; - - PixelFormat m_oPixfmt; - agg::renderer_base m_oRendererBase; - AlphaMask m_oAlphaMask; - agg::scanline_u8_am m_oScanLine; // Используется для применения альфа маски - }; - - typedef agg::renderer_base RenBaseBGRA32; - typedef agg::scanline_u8_am ScanlineBGRA32Gray; - typedef agg::scanline_u8_am ScanlineGray8; - - class CAlphaMask_private - { - public: - CAlphaMask_private(); - ~CAlphaMask_private(); - - StatusAlphaMask GetStatus() const; - AMaskDataType GetDataType() const; - - void Clear(); - - Status Create(UINT unWidth, UINT unHeight, AMaskDataType enDataType); - - Status LoadFromBuffer(BYTE* pBuffer, UINT unWidth, UINT unHeight, AMaskDataType enBufferType, bool bExternalBuffer = true); - - Status LoadFromFile(const std::wstring& wsFilePath); - Status LoadFromImage(IGrObject* pGrObject, bool bCopy = true); - - agg::rendering_buffer& GetRenderingBuffer(); - RenBaseBGRA32& GetRendererBaseImage(); - ScanlineBGRA32Gray& GetScanlineImage(); - ScanlineGray8& GetScanlineABuffer(); - - BYTE* GetMask(); - - void StartApplying(); - - CAlphaMask_private& operator=(const CAlphaMask_private& oAlphaMask); - private: - void Set(BYTE* pBuffer, UINT unWidth, UINT unHeight, AMaskDataType enDataType); - - agg::rendering_buffer m_oRenderingBuffer; - StatusAlphaMask m_enStatus; - AMaskDataType m_enDataType; - - bool m_bExternalBuffer; - public: - typedef TAlphaMaskData AMaskFromImage; - typedef TAlphaMaskData AMaskFromABuffer; - - AMaskFromImage *m_pImageData; - AMaskFromABuffer *m_pAlphaBufferData; - }; -} - -#endif // _BUILD_ALPHAMASK_PRIVATE_H_ diff --git a/DesktopEditor/graphics/BaseThread.cpp b/DesktopEditor/graphics/BaseThread.cpp index eeaf3b4d36a..7ef4d61f9ba 100644 --- a/DesktopEditor/graphics/BaseThread.cpp +++ b/DesktopEditor/graphics/BaseThread.cpp @@ -30,13 +30,13 @@ * */ -#if defined(__ANDROID__) && !defined (NOT_USE_PTHREAD_CANCEL) +#if defined(__ANDROID__) && !defined(NOT_USE_PTHREAD_CANCEL) #include #endif -#include "./BaseThread.h" +#include "./BaseThreadMonitor.h" -#if defined(_WIN32) || defined(_WIN64) ||defined(_WIN32_WCE) +#if defined(_WIN32) || defined(_WIN64) || defined(_WIN32_WCE) #include @@ -49,203 +49,230 @@ namespace NSThreads { - class CThreadDescriptor - { - public: - CThreadDescriptor() - { - } - virtual ~CThreadDescriptor() - { - } - }; - - ASC_THREAD_ID GetCurrentThreadId() - { -#if defined(_WIN32) || defined (_WIN64) - return ::GetCurrentThreadId(); + class CThreadDescriptor + { + public: + CThreadDescriptor() + { + } + virtual ~CThreadDescriptor() + { + } + }; + + ASC_THREAD_ID GetCurrentThreadId() + { +#if defined(_WIN32) || defined(_WIN64) + return ::GetCurrentThreadId(); #else - return pthread_self(); + return pthread_self(); #endif - } + } - void Sleep(int nMilliseconds) + void Sleep(int nMilliseconds) { #if defined(_WIN32) || defined(_WIN64) || defined(_WIN32_WCE) ::Sleep((DWORD)nMilliseconds); #else struct timespec tim, tim2; - tim.tv_sec = nMilliseconds / 1000; - tim.tv_nsec = (nMilliseconds % 1000) * 1000000; + tim.tv_sec = nMilliseconds / 1000; + tim.tv_nsec = (nMilliseconds % 1000) * 1000000; - ::nanosleep(&tim , &tim2); + ::nanosleep(&tim, &tim2); #endif } #if defined(_WIN32) || defined(_WIN64) || defined(_WIN32_WCE) - DWORD WINAPI CBaseThread::__ThreadProc(void* pv) - { - CBaseThread* pThis = (CBaseThread*)pv; - DWORD value = pThis->ThreadProc(); - if (pThis->m_bIsNeedDestroy) - delete pThis; - return value; - } - - class __native_thread : public CThreadDescriptor - { - friend class CBaseThread; - private: - HANDLE m_thread = nullptr; - - public: - __native_thread() : CThreadDescriptor() - { - } - virtual ~__native_thread() - { - if (m_thread) - { - CloseHandle(m_thread); - m_thread = NULL; - } - } - }; + DWORD WINAPI CBaseThread::__ThreadProc(void* pv) + { + CBaseThread* pThis = (CBaseThread*)pv; + + CBaseThreadMonitor::Get().Register(pThis); + DWORD value = pThis->ThreadProc(); + CBaseThreadMonitor::Get().Unregister(pThis); + + if (pThis->m_bIsNeedDestroy) + delete pThis; + return value; + } + + class __native_thread : public CThreadDescriptor + { + friend class CBaseThread; + + private: + HANDLE m_thread = nullptr; + + public: + __native_thread() : CThreadDescriptor() + { + } + virtual ~__native_thread() + { + if (m_thread) + { + CloseHandle(m_thread); + m_thread = NULL; + } + } + }; #else - void* CBaseThread::__ThreadProc(void* pv) - { + void* CBaseThread::__ThreadProc(void* pv) + { #ifndef NOT_USE_PTHREAD_CANCEL - int old_thread_type; - pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &old_thread_type); + int old_thread_type; + pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &old_thread_type); #endif - CBaseThread* pThis = (CBaseThread*)pv; - pThis->ThreadProc(); - - if (pThis->m_bIsNeedDestroy) - delete pThis; - - return NULL; - } - class __native_thread : public CThreadDescriptor - { - friend class CBaseThread; - private: - pthread_t m_thread; - - public: - __native_thread() : CThreadDescriptor() - { - m_thread = NULL; - } - virtual ~__native_thread() - { - } - }; + CBaseThread* pThis = (CBaseThread*)pv; + + CBaseThreadMonitor::Get().Register(pThis); + DWORD value = pThis->ThreadProc(); + CBaseThreadMonitor::Get().Unregister(pThis); + + if (pThis->m_bIsNeedDestroy) + delete pThis; + + return NULL; + } + class __native_thread : public CThreadDescriptor + { + friend class CBaseThread; + + private: + pthread_t m_thread; + + public: + __native_thread() : CThreadDescriptor() + { + m_thread = NULL; + } + virtual ~__native_thread() + { + } + }; #endif - CBaseThread::CBaseThread() - { - m_hThread = NULL; - m_bRunThread = FALSE; - m_bSuspend = FALSE; - - m_lError = 0; - m_lThreadPriority = 0; - - m_bIsNeedDestroy = false; - } - CBaseThread::~CBaseThread() - { - Stop(); - } - void CBaseThread::Start(int lPriority) - { - if (m_bRunThread) - return; - m_lError = 0; - m_bSuspend = FALSE; - - m_hThread = new __native_thread(); - - m_bRunThread = TRUE; - - m_bIsExit.store(false); + CBaseThread::CBaseThread() + { + m_hThread = NULL; + m_bRunThread = FALSE; + m_bSuspend = FALSE; + + m_lError = 0; + m_lThreadPriority = 0; + + m_bIsNeedDestroy = false; + } + CBaseThread::~CBaseThread() + { + Stop(); + } + void CBaseThread::Start(int lPriority) + { + if (m_bRunThread) + return; + m_lError = 0; + m_bSuspend = FALSE; + + m_hThread = new __native_thread(); + + m_bRunThread = TRUE; + + m_bIsExit.store(false); #if defined(_WIN32) || defined(_WIN64) || defined(_WIN32_WCE) - DWORD dwTemp; - ((__native_thread*)m_hThread)->m_thread = CreateThread(NULL, 0, &__ThreadProc, (void*)this, 0, &dwTemp); - SetThreadPriority(((__native_thread*)m_hThread)->m_thread, lPriority); + DWORD dwTemp; + ((__native_thread*)m_hThread)->m_thread = CreateThread(NULL, 0, &__ThreadProc, (void*)this, 0, &dwTemp); + SetThreadPriority(((__native_thread*)m_hThread)->m_thread, lPriority); #else - pthread_create(&((__native_thread*)m_hThread)->m_thread, 0, &__ThreadProc, (void*)this); + pthread_create(&((__native_thread*)m_hThread)->m_thread, 0, &__ThreadProc, (void*)this); #endif - m_lThreadPriority = lPriority; - } - void CBaseThread::Suspend() - { - m_bSuspend = TRUE; - } - void CBaseThread::Resume() - { - m_bSuspend = FALSE; - } - void CBaseThread::Stop() - { - if (!m_bRunThread) - return; - - m_bIsExit.store(true); - m_bRunThread = FALSE; - - Join(); - RELEASEOBJECT(m_hThread); - } - void CBaseThread::StopNoJoin() - { - m_bRunThread = FALSE; - m_bIsExit.store(true); - RELEASEOBJECT(m_hThread); - } - void CBaseThread::DestroyOnFinish() - { - m_bIsNeedDestroy = true; - } - - INT CBaseThread::IsSuspended() { return m_bSuspend; } - INT CBaseThread::IsRunned() { return m_bRunThread; } - int CBaseThread::GetError() { return m_lError; } - bool CBaseThread::isAborted() {return m_bIsExit && m_bIsExit.load();} - - CThreadDescriptor* CBaseThread::GetDescriptor() { return m_hThread; } - int CBaseThread::GetPriority() { return m_lThreadPriority; } - - void CBaseThread::CheckSuspend() - { - while (m_bSuspend && m_bRunThread) - NSThreads::Sleep(10); - } - - void CBaseThread::Join() - { - if (NULL == m_hThread) - return; + m_lThreadPriority = lPriority; + } + void CBaseThread::Suspend() + { + m_bSuspend = TRUE; + } + void CBaseThread::Resume() + { + m_bSuspend = FALSE; + } + void CBaseThread::Stop() + { + if (!m_bRunThread) + return; + + m_bIsExit.store(true); + m_bRunThread = FALSE; + + Join(); + RELEASEOBJECT(m_hThread); + } + void CBaseThread::StopNoJoin() + { + m_bRunThread = FALSE; + m_bIsExit.store(true); + RELEASEOBJECT(m_hThread); + } + void CBaseThread::DestroyOnFinish() + { + m_bIsNeedDestroy = true; + } + + INT CBaseThread::IsSuspended() + { + return m_bSuspend; + } + INT CBaseThread::IsRunned() + { + return m_bRunThread; + } + int CBaseThread::GetError() + { + return m_lError; + } + bool CBaseThread::isAborted() + { + return m_bIsExit && m_bIsExit.load(); + } + + CThreadDescriptor* CBaseThread::GetDescriptor() + { + return m_hThread; + } + int CBaseThread::GetPriority() + { + return m_lThreadPriority; + } + + void CBaseThread::CheckSuspend() + { + while (m_bSuspend && m_bRunThread) + NSThreads::Sleep(10); + } + + void CBaseThread::Join() + { + if (NULL == m_hThread) + return; #if defined(_WIN32) || defined(_WIN64) || defined(_WIN32_WCE) - WaitForSingleObject(((__native_thread*)m_hThread)->m_thread, INFINITE); + WaitForSingleObject(((__native_thread*)m_hThread)->m_thread, INFINITE); #else - pthread_join(((__native_thread*)m_hThread)->m_thread, 0); + pthread_join(((__native_thread*)m_hThread)->m_thread, 0); #endif - } + } - void CBaseThread::Cancel() - { - if (NULL == m_hThread) - return; + void CBaseThread::Cancel() + { + if (NULL == m_hThread) + return; - m_bIsExit.store(true); + m_bIsExit.store(true); - m_bRunThread = FALSE; + m_bRunThread = FALSE; - Join(); - RELEASEOBJECT(m_hThread); - } -} + Join(); + RELEASEOBJECT(m_hThread); + } +} // namespace NSThreads diff --git a/DesktopEditor/graphics/BaseThread.h b/DesktopEditor/graphics/BaseThread.h index 2a5fa9aec9d..93d04f8af75 100644 --- a/DesktopEditor/graphics/BaseThread.h +++ b/DesktopEditor/graphics/BaseThread.h @@ -41,7 +41,7 @@ #include #endif -#if defined(_WIN32) || defined (_WIN64) +#if defined(_WIN32) || defined(_WIN64) typedef DWORD ASC_THREAD_ID; #else typedef pthread_t ASC_THREAD_ID; @@ -51,56 +51,57 @@ typedef pthread_t ASC_THREAD_ID; namespace NSThreads { - KERNEL_DECL ASC_THREAD_ID GetCurrentThreadId(); + KERNEL_DECL ASC_THREAD_ID GetCurrentThreadId(); - KERNEL_DECL void Sleep(int nMilliseconds); + KERNEL_DECL void Sleep(int nMilliseconds); - class CThreadDescriptor; - class KERNEL_DECL CBaseThread + class CThreadDescriptor; + class KERNEL_DECL CBaseThread { protected: - CThreadDescriptor* m_hThread; - INT m_bRunThread; - INT m_bSuspend; + CThreadDescriptor* m_hThread; + INT m_bRunThread; + INT m_bSuspend; - int m_lError; - int m_lThreadPriority; + int m_lError; + int m_lThreadPriority; - bool m_bIsNeedDestroy; - std::atomic m_bIsExit{false}; + bool m_bIsNeedDestroy; + std::atomic m_bIsExit{false}; public: - CBaseThread(); - virtual ~CBaseThread(); + CBaseThread(); + virtual ~CBaseThread(); + public: - virtual void Start(int lPriority); - virtual void Suspend(); - virtual void Resume(); - virtual void Stop(); - virtual void StopNoJoin(); - virtual void DestroyOnFinish(); - virtual void Cancel(); - - INT IsSuspended(); - INT IsRunned(); - bool isAborted(); - int GetError(); - - CThreadDescriptor* GetDescriptor(); - int GetPriority(); - - virtual void CheckSuspend(); + virtual void Start(int lPriority); + virtual void Suspend(); + virtual void Resume(); + virtual void Stop(); + virtual void StopNoJoin(); + virtual void DestroyOnFinish(); + virtual void Cancel(); + + INT IsSuspended(); + INT IsRunned(); + bool isAborted(); + int GetError(); + + CThreadDescriptor* GetDescriptor(); + int GetPriority(); + + virtual void CheckSuspend(); protected: - virtual void Join(); + virtual void Join(); virtual DWORD ThreadProc() = 0; #if defined(_WIN32) || defined(_WIN64) || defined(_WIN32_WCE) - static DWORD WINAPI __ThreadProc(void* pv); + static DWORD WINAPI __ThreadProc(void* pv); #else - static void* __ThreadProc(void* pv); + static void* __ThreadProc(void* pv); #endif - }; + }; } #endif // _BUILD_BASETHREAD_H_ diff --git a/DesktopEditor/graphics/BaseThreadMonitor.cpp b/DesktopEditor/graphics/BaseThreadMonitor.cpp new file mode 100644 index 00000000000..b84268b76dd --- /dev/null +++ b/DesktopEditor/graphics/BaseThreadMonitor.cpp @@ -0,0 +1,155 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ + +#include "./BaseThreadMonitor.h" + +namespace NSThreads +{ + CBaseThreadMonitor::CBaseThreadMonitor() + { + m_bIsInit = false; + m_pReceiver = NULL; + m_funcRelease = nullptr; + + m_oCS.InitializeCriticalSection(); + } + + CBaseThreadMonitor::~CBaseThreadMonitor() + { + m_oCS.DeleteCriticalSection(); + } + + CBaseThreadMonitor& CBaseThreadMonitor::Get() + { + static CBaseThreadMonitor instance; + return instance; + } + + bool CBaseThreadMonitor::Init(void* receiver) + { + CTemporaryCS oCS(&m_oCS); + + if (m_bIsInit) + return false; + + m_bIsInit = true; + m_pReceiver = receiver; + return true; + } + + bool CBaseThreadMonitor::Destroy() + { + CTemporaryCS oCS(&m_oCS); + + if (!m_bIsInit) + return false; + + m_bIsInit = false; + m_pReceiver = NULL; + m_listThreads.clear(); + return true; + } + + bool CBaseThreadMonitor::IsInit() + { + CTemporaryCS oCS(&m_oCS); + return m_bIsInit; + } + + NSCriticalSection::CRITICAL_SECTION* CBaseThreadMonitor::GetCS() + { + return &m_oCS; + } + + CBaseThread* CBaseThreadMonitor::GetBaseThread(const ASC_THREAD_ID& nThreadId) + { + // лист - потому что будет всегда мало записей - и то будет быстрее мапа. двигаем всегда текущий на первое место + + if (m_listThreads.size() == 0) + return NULL; + + std::list::iterator i = m_listThreads.begin(); + + if (i->ID == nThreadId) + return i->Instance; + + i++; + while (i != m_listThreads.end()) + { + if (i->ID == nThreadId) + { + CBaseThreadInfo last; + last.ID = i->ID; + last.Instance = i->Instance; + + m_listThreads.erase(i); + m_listThreads.insert(m_listThreads.begin(), last); + + return last.Instance; + } + i++; + } + + return NULL; + } + + void CBaseThreadMonitor::SetReleaseHandler(std::function func) + { + CTemporaryCS oCS(&m_oCS); + m_funcRelease = func; + } + + void CBaseThreadMonitor::Register(CBaseThread* pInstance) + { + CTemporaryCS oCS(&m_oCS); + if (!m_bIsInit) + return; + m_listThreads.push_back({NSThreads::GetCurrentThreadId(), pInstance}); + } + + void CBaseThreadMonitor::Unregister(CBaseThread* pInstance) + { + CTemporaryCS oCS(&m_oCS); + if (!m_bIsInit) + return; + for (std::list::iterator i = m_listThreads.begin(); i != m_listThreads.end(); i++) + { + if (i->Instance == pInstance) + { + m_listThreads.erase(i); + if (m_funcRelease) + m_funcRelease(m_pReceiver, pInstance); + return; + } + } + } +} diff --git a/DesktopEditor/graphics/BaseThreadMonitor.h b/DesktopEditor/graphics/BaseThreadMonitor.h new file mode 100644 index 00000000000..e522aaab483 --- /dev/null +++ b/DesktopEditor/graphics/BaseThreadMonitor.h @@ -0,0 +1,87 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#ifndef _BUILD_BASETHREAD_MONITOR_H_ +#define _BUILD_BASETHREAD_MONITOR_H_ + +#include "BaseThread.h" +#include "TemporaryCS.h" +#include +#include + +namespace NSThreads +{ + class CBaseThreadInfo + { + public: + ASC_THREAD_ID ID; + CBaseThread* Instance; + }; + + class KERNEL_DECL CBaseThreadMonitor + { + private: + NSCriticalSection::CRITICAL_SECTION m_oCS; + + bool m_bIsInit; + + void* m_pReceiver; + std::function m_funcRelease; + + std::list m_listThreads; + + private: + CBaseThreadMonitor(); + + public: + static CBaseThreadMonitor& Get(); + ~CBaseThreadMonitor(); + + public: + bool IsInit(); + + bool Init(void* receiver); + bool Destroy(); + + CBaseThread* GetBaseThread(const ASC_THREAD_ID& nThreadId); + void SetReleaseHandler(std::function func); + + NSCriticalSection::CRITICAL_SECTION* GetCS(); + + private: + void Register(CBaseThread* pInstance); + void Unregister(CBaseThread* pInstance); + + friend class CBaseThread; + }; +} + +#endif // _BUILD_BASETHREAD_MONITOR_H_ diff --git a/DesktopEditor/graphics/BooleanOperations.cpp b/DesktopEditor/graphics/BooleanOperations.cpp new file mode 100644 index 00000000000..05d7a991d3a --- /dev/null +++ b/DesktopEditor/graphics/BooleanOperations.cpp @@ -0,0 +1,1945 @@ +#include "BooleanOperations.h" +#include "boolean_operations_math.h" +#include +#include + +namespace Aggplus { +Segment::Segment() noexcept +{ +} + +Segment::Segment(const std::vector& points, const bool& isCurve, + const int& index, const int& id, const bool& polyClosed) noexcept : + IsCurve(isCurve), + PolyClosed(polyClosed), + Index(index), + Id(id) +{ + if (IsCurve) + { + P = points[2]; + HI = PointD(points[0].X - P.X, points[0].Y - P.Y); + HO = PointD(points[1].X - P.X, points[1].Y - P.Y); + } + else + P = points[0]; +} + +Segment::Segment(const PointD& point, const bool& isCurve, const int& index, + const int& id, const bool& polyClosed) noexcept : + P(point), + IsCurve(isCurve), + PolyClosed(polyClosed), + Index(index), + Id(id) +{ +} + +Segment::Segment(const PointD& p) noexcept : + P(p) +{ +} + +Segment::Segment(const PointD& p, const PointD& hi, const PointD& ho) noexcept : + P(p), + HI(hi), + HO(ho) +{ + if (!hi.IsZero() || !ho.IsZero()) + IsCurve = true; +} + +void Segment::SetHandles(const PointD &hi, const PointD &ho) noexcept +{ + IsCurve = true; + HI = PointD(hi.X - P.X, hi.Y - P.Y); + HO = PointD(ho.X - P.X, ho.Y - P.Y); +} + +void Segment::UpdateHandles(const PointD &hi, const PointD &ho) noexcept +{ + HI = hi; + HO = ho; +} + +bool Segment::IsValid(const BooleanOpType& op) const noexcept +{ + if (Visited) + return false; + if (Inters) + return true; + if (op == Subtraction) + { + if (Id == 1 && Winding == 0) + return true; + else if (Id == 2 && Winding == 1) + return true; + } + else if (Winding == op) + return true; + return false; +} + +bool Segment::IsEmpty() const noexcept +{ + return Id == 0 && Index == -1 && P.IsZero() && HI.IsZero() && HO.IsZero(); +} + +bool Segment::operator==(const Segment& other) const noexcept +{ + return (Index == other.Index) && (Id == other.Id); +} + +bool Segment::operator!=(const Segment& other) const noexcept +{ + return !operator==(other); +} + +Curve::Curve() noexcept +{ +} + +Curve::Curve(const Segment& segment1, const Segment& segment2) noexcept : + Segment1(segment1), + Segment2(segment2) +{ +} + +Curve::Curve(const std::vector& values) noexcept +{ + if (values.size() == 4) + { + Segment1 = Segment(PointD(values[0], values[1])); + Segment2 = Segment(PointD(values[2], values[3])); + } + else if (values.size() == 8) + { + Segment1 = Segment(PointD(values[0], values[1])); + Segment2 = Segment(PointD(values[6], values[7]), + PointD(values[2] - values[6], + values[3] - values[7]), + PointD(values[4] - values[6], + values[5] - values[7])); + } +} + +Curve::Curve(const double& x0, const double& y0, const double& x1, const double& y1, + const double& x2, const double& y2, const double& x3, const double& y3) noexcept : + Segment1(Segment(PointD(x0, y0))), + Segment2(Segment(PointD(x3, y3), PointD(x1, y1), PointD(x2, y2))) +{ +} + +std::vector Curve::GetXValues() const noexcept +{ + if (IsStraight()) return {Segment1.P.X, Segment1.P.X, Segment2.P.X, Segment2.P.X}; + return {Segment1.P.X, Segment2.P.X + Segment2.HI.X, Segment2.P.X + Segment2.HO.X, Segment2.P.X}; +} + +std::vector Curve::GetYValues() const noexcept +{ + if (IsStraight()) return {Segment1.P.Y, Segment1.P.Y, Segment2.P.Y, Segment2.P.Y}; + return {Segment1.P.Y, Segment2.P.Y + Segment2.HI.Y, Segment2.P.Y + Segment2.HO.Y, Segment2.P.Y}; +} + +std::vector Curve::GetBound() const noexcept +{ + return {min(Segment1.P.X, Segment2.P.X + Segment2.HI.X, Segment2.P.X + Segment2.HO.X, Segment2.P.X), + min(Segment1.P.Y, Segment2.P.Y + Segment2.HI.Y, Segment2.P.Y + Segment2.HO.Y, Segment2.P.Y), + max(Segment1.P.X, Segment2.P.X + Segment2.HI.X, Segment2.P.X + Segment2.HO.X, Segment2.P.X), + max(Segment1.P.Y, Segment2.P.Y + Segment2.HI.Y, Segment2.P.Y + Segment2.HO.Y, Segment2.P.Y)}; +} + +std::vector Curve::GetPeeks() const +{ + std::vector x = GetXValues(), + y = GetYValues(), + roots; + + double ax = -x[0] + 3 * x[1] - 3 * x[2] + x[3], + bx = 3 * x[0] - 6 * x[1] + 3 * x[2], + cx = -3 * x[0] + 3 * x[1], + ay = -y[0] + 3 * y[1] - 3 * y[2] + y[3], + by = 3 * y[0] - 6 * y[1] + 3 * y[2], + cy = -3 * y[0] + 3 * y[1], + tMin = CURVETIME_EPSILON, + tMax = 1 - tMin; + + SolveCubic(9 * (ax * ax + ay * ay), + 9 * (ax * bx + by * ay), + 2 * (bx * bx + by * by) + 3 * (cx * ax + cy * ay), + (cx * bx + by * cy), + roots, tMin, tMax); + + std::sort(roots.begin(), roots.end()); + + return roots; +} + +double Curve::GetLength(double a, double b) const +{ + if(IsStraight()) + { + Curve c; + double dx, dy; + if (b < 1) + { + c = Subdivide(b)[0]; + dx = c.Segment2.P.X - c.Segment1.P.X; + dy = c.Segment2.P.Y - c.Segment1.P.Y; + } + else if (a > 0) + { + c = Subdivide(a)[1]; + dx = c.Segment2.P.X - c.Segment1.P.X; + dy = c.Segment2.P.Y - c.Segment1.P.Y; + } + else + { + dx = Segment2.P.X - Segment1.P.X; + dy = Segment2.P.Y - Segment1.P.Y; + } + return sqrt(dx * dx + dy * dy); + } + + std::vector x = GetXValues(), + y = GetYValues(); + + double ax = 9 * (x[1] - x[2]) + 3 * (x[3] - x[0]), + bx = 6 * (x[0] + x[2]) - 12 * x[1], + cx = 3 * (x[1] - x[0]), + ay = 9 * (y[1] - y[2]) + 3 * (y[3] - y[0]), + by = 6 * (y[0] + y[2]) - 12 * y[1], + cy = 3 * (y[1] - y[0]); + + return integrate(ax, bx, cx, ay, by, cy, a, b); +} + +double Curve::GetSquaredLineLength() const noexcept +{ + return (Segment2.P.X - Segment1.P.X) * (Segment2.P.X - Segment1.P.X) + + (Segment2.P.Y - Segment1.P.Y) * (Segment2.P.Y - Segment1.P.Y); +} + +double Curve::GetTimeOf(const PointD& point) const noexcept +{ + double d0 = getDistance(point.X, point.Y, Segment1.P.X, Segment1.P.Y), + d3 = getDistance(point.X, point.Y, Segment2.P.X, Segment2.P.Y); + + if (d0 > EPSILON && d3 > EPSILON) + { + std::vector roots; + for (int c = 0; c < 2; c++) + { + int count = SolveCubic(c, c == 0 ? point.X : point.Y, roots, 0.0, 1.0); + for (int i = 0; i < count; i++) + { + double u = roots[i]; + if (u > 1.0 || u < 0.0) + return - 1.0; + if (getDistance(point, GetPoint(u)) <= GEOMETRIC_EPSILON) + return u; + } + roots.clear(); + } + } + bool firstDist = d0 <= GEOMETRIC_EPSILON, + secondDist = d3 <= GEOMETRIC_EPSILON; + return firstDist ? 0.0 : secondDist ? 1.0 : - 1.0; +} + +double Curve::GetTimeAt(const double& offset) const noexcept +{ + bool forward = offset > 0; + double start = !forward ? 1 : 0; + if (offset == 0) + return start; + + double a = forward ? start : 0, + b = forward ? 1 : start, + rangeLength = GetLength(a, b), + diff = fabs(offset) - rangeLength; + + if (fabs(diff) < EPSILON) + return forward ? b : a; + else if (diff > EPSILON) + return MIN; + + double guess = offset / rangeLength, + length = 0.0; + + std::vector x = GetXValues(), + y = GetYValues(); + + double ax = 9 * (x[1] - x[2]) + 3 * (x[3] - x[0]), + bx = 6 * (x[0] + x[2]) - 12 * x[1], + cx = 3 * (x[1] - x[0]), + ay = 9 * (y[1] - y[2]) + 3 * (y[3] - y[0]), + by = 6 * (y[0] + y[2]) - 12 * y[1], + cy = 3 * (y[1] - y[0]); + + double vx = start + guess; + for (size_t i = 0; i < 32; i++) + { + length += integrate(ax, bx, cx, ay, by, cy, start, vx, getIterations(start, vx)); + start = vx; + + double dx = vx - (length - offset) / CurveLength(vx, ax, bx, cx, ay, by, cy); + if (fabs(vx - dx) < EPSILON) + { + vx = dx; + break; + } + + if (length - offset > 0) + { + b = vx; + vx = dx <= a ? (a + b) * 0.5 : dx; + } + else{ + a = vx; + vx = dx >= b ? (a + b) * 0.5 : dx; + } + } + + return clamp(vx, a, b); +} + +PointD Curve::Get(const double& t, const int& type) const noexcept +{ + std::vector x = GetXValues(), + y = GetYValues(); + + if (isZero(x[1] - x[0]) && isZero(y[1] - y[0])) + { + x[1] = x[0]; + y[1] = y[0]; + } + if (isZero(x[2] - x[3]) && isZero(y[2] - y[3])) + { + x[2] = x[3]; + y[2] = y[3]; + } + + double cx = 3 * (x[1] - x[0]), + bx = 3 * (x[2] - x[1]) - cx, + ax = x[3] - x[0] - cx - bx, + cy = 3 * (y[1] - y[0]), + by = 3 * (y[2] - y[1]) - cy, + ay = y[3] - y[0] - cy - by, + xv = ((ax * t + bx) * t + cx) * t + x[0], + yv = ((ay * t + by) * t + cy) * t + y[0], + x0 = t == 0 ? x[0] : t == 1 ? x[3] : xv, + y0 = t == 0 ? y[0] : t == 1 ? y[3] : yv; + + if (type == 1) + { + double tMin = CURVETIME_EPSILON, + tMax = 1 - tMin; + + if (t < tMin) + { + x0 = cx; + y0 = cy; + } + else if (t > tMax) + { + x0 = 3 * (x[3] - x[2]); + y0 = 3 * (y[3] - y[2]); + } + else + { + x0 = (3 * ax * t + 2 * bx) * t + cx; + y0 = (3 * ay * t + 2 * by) * t + cy; + } + + if (x0 == 0.0 && y0 == 0.0 && (t < tMin || t > tMax)) + { + x0 = x[2] - x[1]; + y0 = y[2] - y[1]; + } + + double len = sqrt(x0 * x0 + y0 * y0); + if (len != 0.0) + { + x0 /= len; + y0 /= len; + } + } + + return PointD(x0, y0); +} + +PointD Curve::GetPoint(const double& t) const noexcept +{ + return Get(t, 0); +} + +PointD Curve::GetTangent(const double& t) const noexcept +{ + return Get(t, 1); +} + +PointD Curve::GetTangent(const double& t, const double& offset, + const bool& inside, const PointD& p) const noexcept +{ + if (inside) return GetTangent(t); + return GetPoint(GetTimeAt(offset)) - p; +} + +Curve Curve::GetPart(double from, double to) const noexcept +{ + Curve result = *this; + if (from > to) + std::swap(from, to); + + if (from > 0) + { + result = Subdivide(from)[1]; + result.Segment2.HI.X -= result.Segment2.P.X; + result.Segment2.HI.Y -= result.Segment2.P.Y; + result.Segment2.HO.X -= result.Segment2.P.X; + result.Segment2.HO.Y -= result.Segment2.P.Y; + } + if (to < 1) + { + result = result.Subdivide((to - from) / (1 - from))[0]; + result.Segment2.HI.X -= result.Segment2.P.X; + result.Segment2.HI.Y -= result.Segment2.P.Y; + result.Segment2.HO.X -= result.Segment2.P.X; + result.Segment2.HO.Y -= result.Segment2.P.Y; + } + + if (from > to) + result.Flip(); + + return result; +} + +std::vector> Curve::GetOverlaps(const Curve& curve) const noexcept +{ + bool swap = GetSquaredLineLength() < curve.GetSquaredLineLength(), + straight1 = IsStraight(), + straight2 = curve.IsStraight(), + straightBoth = straight1 && straight2; + + std::vector x1 = GetXValues(), + y1 = GetYValues(), + x2 = curve.GetXValues(), + y2 = curve.GetYValues(); + + double px = swap ? x2[0] : x1[0], + py = swap ? y2[0] : y1[0], + vx = swap ? x2[3] - px : x1[3] - px, + vy = swap ? y2[3] - py : y1[3] - py; + + if (swap) + { + std::swap(x1, x2); + std::swap(y1, y2); + } + + double d20 = fabs(getSignedDistance(px, py, vx, vy, x2[0], y2[0], true)), + d23 = fabs(getSignedDistance(px, py, vx, vy, x2[3], y2[3], true)); + + if (d20 < GEOMETRIC_EPSILON && d23 < GEOMETRIC_EPSILON) + { + double d11 = fabs(getSignedDistance(px, py, vx, vy, x1[1], y1[1], true)), + d12 = fabs(getSignedDistance(px, py, vx, vy, x1[2], y1[2], true)), + d21 = fabs(getSignedDistance(px, py, vx, vy, x2[1], y2[1], true)), + d22 = fabs(getSignedDistance(px, py, vx, vy, x2[2], y2[2], true)); + + if (!straightBoth && + d11 < GEOMETRIC_EPSILON && + d12 < GEOMETRIC_EPSILON && + d21 < GEOMETRIC_EPSILON && + d22 < GEOMETRIC_EPSILON) + { + straight1 = straight2 = straightBoth = true; + } + } + else if (straightBoth) + { + return std::vector>(); + } + if (straight1 ^ straight2) + { + return std::vector>(); + } + + std::vector> pairs; + for (int i = 0; i < 4 && pairs.size() < 2; i++) + { + int i1 = i & 1, + t1 = i >> 1; + double t2 = i1 == 0 ? GetTimeOf(t1 == 1 ? curve.Segment2.P : curve.Segment1.P) + : curve.GetTimeOf(t1 == 1 ? Segment2.P : Segment1.P); + if (t2 != -1) + { + std::pair pair = i1 == 1 ? std::pair(t1, t2) + : std::pair(t2, t1); + if (pairs.empty()) + pairs.push_back(pair); + else if (fabs(pair.first - pairs[0].first) > TIME_EPSILON && + fabs(pair.second - pairs[0].second) > TIME_EPSILON) + pairs.push_back(pair); + } + + if (i > 2 && pairs.empty()) + break; + } + + if (pairs.size() != 2) + pairs.clear(); + else if (!straightBoth) + { + Curve o1 = GetPart(pairs[0].first, pairs[1].first), + o2 = curve.GetPart(pairs[0].second, pairs[1].second); + + double dox = fabs(o2.Segment2.HO.X - o1.Segment2.HO.X), + doy = fabs(o2.Segment2.HO.Y - o1.Segment2.HO.Y), + dix = fabs(o2.Segment2.HI.X - o1.Segment2.HI.X), + diy = fabs(o2.Segment2.HI.Y - o1.Segment2.HI.Y); + + if (dox > GEOMETRIC_EPSILON || + doy > GEOMETRIC_EPSILON || + dix > GEOMETRIC_EPSILON || + diy > GEOMETRIC_EPSILON) + pairs.clear(); + } + + return pairs; +} + +std::vector Curve::GetCurveLineIntersection(const double& px, const double& py, + const double& vx, const double& vy) const noexcept +{ + if (isZero(vx) && isZero(vy)) + { + double t = GetTimeOf(PointD(px, py)); + return t == -1 ? std::vector() : std::vector({t}); + } + + double angle = std::atan2(-vy, vx), + sin = std::sin(angle), + cos = std::cos(angle); + + std::vector x = GetXValues(), + y = GetYValues(), + rv, roots; + + for (int i = 0; i < 4; i++) + { + double cx = x[i] - px, + cy = y[i] - py; + + rv.push_back(cx * cos - cy * sin); + rv.push_back(cx * sin + cy * cos); + } + + Curve c(rv); + c.SolveCubic(1, 0, roots, 0, 1); + + return roots; +} + +std::vector Curve::Subdivide(const double& t) const noexcept +{ + std::vector x = GetXValues(), + y = GetYValues(); + double x2[6], y2[6], u = 1 - t; + + x2[0] = u * x[0] + t * x[1], y2[0] = u * y[0] + t * y[1], + x2[1] = u * x[1] + t * x[2], y2[1] = u * y[1] + t * y[2], + x2[2] = u * x[2] + t * x[3], y2[2] = u * y[2] + t * y[3], + x2[3] = u * x2[0] + t * x2[1], y2[3] = u * y2[0] + t * y2[1], + x2[4] = u * x2[1] + t * x2[2], y2[4] = u * y2[1] + t * y2[2], + x2[5] = u * x2[3] + t * x2[4], y2[5] = u * y2[3] + t * y2[4]; + + return {Curve(x[0], y[0], x2[0], y2[0], x2[3], y2[3], x2[5], y2[5]), + Curve(x2[5], y2[5], x2[4], y2[4], x2[2], y2[2], x[3], y[3])}; +} + +Curve Curve::DivideAtTime(const double& time) noexcept +{ + double tMin = CURVETIME_EPSILON, + tMax = 1 - tMin; + + if (time >= tMin && time <= tMax) + { + std::vector parts = Subdivide(time); + Segment segment(parts[0].Segment2.P, + false, + Segment1.Index + 1, + Segment1.Id, + Segment1.PolyClosed); + + if (!IsStraight()) + { + segment.SetHandles(parts[0].Segment2.HI, parts[0].Segment2.HO); + Segment2.SetHandles(parts[1].Segment2.HI, parts[1].Segment2.HO); + } + + return Curve(segment, Segment2); + } + + return Curve(); +} + +int Curve::SolveCubic(const int& coord, const double& value, std::vector& roots, + const double& mn, const double& mx) const noexcept +{ + int count = 0; + std::vector v = coord == 0 ? GetXValues() : GetYValues(); + double a, b, c, d; + + if (!((v[0] < value && v[3] < value && v[1] < value && v[2] < value) || + (v[0] > value && v[3] > value && v[1] > value && v[2] > value))) + { + c = 3 * (v[1] - v[0]); + b = 3 * (v[2] - v[1]) - c; + a = v[3] - v[0] - c - b; + d = v[0] - value; + count = SolveCubic(a, b, c, d, roots, mn, mx); + } + + return count; +} + +int Curve::SolveCubic(double a, double b, double c, double d, + std::vector& roots, const double& mn, const double& mx) const noexcept +{ + int count = 0; + double f = max(fabs(a), fabs(b), fabs(c), fabs(d)); + double x, b1, c2, qd, q; + if (f != 0 && (f < 1e-8 || f > 1e8)) + { + f = pow(2, -round(log2(f))); + a *= f; + b *= f; + c *= f; + d *= f; + } + + if (fabs(a) < EPSILON) + { + a = b; + b1 = c; + c2 = d; + x = MAX; + } + else if (fabs(d) 0 ? 1.324717957244746 * std::max(r, std::sqrt(td)) : r, + x0 = x - s * rd; + + if (x0 != x) + { + do + { + x = x0; + b1 = a * x + b; + c2 = b1 * x + c; + qd = (a * x + b1) * x + c2; + q = c2 * x + d; + x0 = qd == 0 ? x : x - q / qd / (1 + MACHINE_EPSILON); + } while (s * x0 > s * x); + + if (fabs(a) * x * x > fabs(d / x)) + { + c2 = -d / x; + b1 = (c2 - c) / x; + } + } + } + + count = solveQuadratic(a, b1, c2, roots, mn, mx); + + bool xInRoots1 = count > 0 && x != roots[0], + xInRoots2 = count > 1 && x != roots[1], + xInEps = x > mn - EPSILON && x < mx + EPSILON; + if (x != MAX && (count == 0 || xInRoots1 || xInRoots2) && (xInEps)) + { + roots.push_back(clamp(x, mn, mx)); + count++; + } + + return count; +} + +void Curve::Flip() noexcept +{ + PointD tmpHI = Segment2.P + Segment2.HI; + PointD tmpHO = Segment2.P + Segment2.HO; + std::swap(Segment1.P, Segment2.P); + Segment2.HI = tmpHI - Segment2.P; + Segment2.HO = tmpHO - Segment2.P; +} + +bool Curve::IsStraight() const noexcept +{ + return !Segment2.IsCurve; +} + +bool Curve::operator==(const Curve& other) const noexcept +{ + return Segment1 == other.Segment1 && + Segment2 == other.Segment2; +} + +bool Curve::operator!=(const Curve& other) const noexcept +{ + return !operator ==(other); +} + +Location::Location() noexcept +{ +} + +Location::Location(const Curve& curve, const double& time, const bool& overlap, const bool& ends) noexcept : + C(curve), + Time(time), + Overlap(overlap), + Ends(ends) +{ +} + +bool Location::IsTouching() noexcept +{ + if (!Inters) + return false; + if (!isCollinear(C.GetTangent(Time), Inters->C.GetTangent(Inters->Time))) + return false; + + PointD pt; + bool straight = C.IsStraight() && Inters->C.IsStraight(); + + return !straight || !intersect({C.Segment1.P.X, + C.Segment1.P.Y, + C.Segment2.P.X, + C.Segment2.P.Y, + Inters->C.Segment1.P.X, + Inters->C.Segment1.P.Y, + Inters->C.Segment2.P.X, + Inters->C.Segment2.P.Y}, pt); +} + +CBooleanOperations::CBooleanOperations(const CGraphicsPath& path1, + const CGraphicsPath& path2, + BooleanOpType op, + long fillType) : + Op(op), + Close1(path1.Is_poly_closed()), + Close2(path2.Is_poly_closed()), + FillType(fillType), + Path1(path1), + Path2(path2) +{ + TraceBoolean(); +} + +CBooleanOperations::~CBooleanOperations() +{ +} + +CGraphicsPath&& CBooleanOperations::GetResult() +{ + return std::move(Result); +} + +void CBooleanOperations::TraceBoolean() +{ + bool reverse = false; + if ((Op == Subtraction || Op == Exclusion) ^ + Path1.IsClockwise() ^ + Path2.IsClockwise()) + reverse = true; + + PreparePath(Path1, 1, Segments1, Curves1); + PreparePath(Path2, 2, Segments2, Curves2, reverse); + + OriginCurves1 = Curves1; + OriginCurves2 = Curves2; + + GetIntersection(); + + if (!Locations.empty()) + { + int length = static_cast(Locations.size()); + for (int i = 0; i < length; i++) + { + int before = static_cast(Locations.size()); + InsertLocation(Locations[i]->Inters, Locations[i]->Inters->Overlap); + if (before == Locations.size()) + { + Locations.erase(Locations.begin() + i); + length--; + i--; + } + } + + DivideLocations(); + + if (Locations.size() == 2 && Locations[0]->Ends) + { + SetWinding(); + TraceOneInters(); + return; + } + if (AllOverlap()) + { + TraceAllOverlap(); + return; + } + } + + SetWinding(); + TracePaths(); +} + +void CBooleanOperations::TraceOneInters() +{ + Segment s1, s2; + + for (const auto& s : Segments1) + if (!s.Inters) + s1 = s; + + for (const auto& s : Segments2) + if (!s.Inters) + s2 = s; + + if (Op == Intersection) + { + if (s1.Winding == 1) + Result = std::move(Path1); + else if (s2.Winding == 1) + Result = std::move(Path2); + else + { + Result.StartFigure(); + Result.MoveTo(Locations[0]->S.P.X, Locations[0]->S.P.Y); + Result.CloseFigure(); + } + } + else + { + if (Op == Union && s1.Winding == 1) + Result = std::move(Path2); + else if (Op == Union && s2.Winding == 1) + Result = std::move(Path1); + else if (s1.Winding == 0 && s2.Winding == 0 && Op == Subtraction) + Result = std::move(Path1); + else + { + bool start = true; + for (const auto& s : (Op == Union || s2.Winding == 1) ? Segments1 : Segments2) + { + if (!s.P.Equals(Locations[(Op == Union || s2.Winding == 1) ? 0 : 1]->S.P)) + { + if (start) + { + Result.StartFigure(); + Result.MoveTo(s.P.X, s.P.Y); + start = false; + } + else if (s.IsCurve) + Result.CurveTo(s.HI.X + s.P.X, s.HI.Y + s.P.Y, + s.HO.X + s.P.X, s.HO.Y + s.P.Y, + s.P.X, s.P.Y); + else + Result.LineTo(s.P.X, s.P.Y); + } + else + { + if (s.IsCurve) + Result.CurveTo(s.HI.X + s.P.X, s.HI.Y + s.P.Y, + s.HO.X + s.P.X, s.HO.Y + s.P.Y, + s.P.X, s.P.Y); + else + Result.LineTo(s.P.X, s.P.Y); + + Segment seg = GetNextSegment(Locations[1]->S); + while (!seg.IsEmpty() && seg != Locations[(Op == Union || s2.Winding == 1) ? 1 : 0]->S) + { + if (seg.IsCurve) + Result.CurveTo(seg.HI.X + seg.P.X, seg.HI.Y + seg.P.Y, + seg.HO.X + seg.P.X, seg.HO.Y + seg.P.Y, + seg.P.X, seg.P.Y); + else + Result.LineTo(seg.P.X, seg.P.Y); + seg = GetNextSegment(seg); + } + + if (seg.IsCurve) + Result.CurveTo(seg.HI.X + seg.P.X, seg.HI.Y + seg.P.Y, + seg.HO.X + seg.P.X, seg.HO.Y + seg.P.Y, + seg.P.X, seg.P.Y); + else + Result.LineTo(seg.P.X, seg.P.Y); + } + } + + if (Close1 && Close2) + { + Segment firstS = (Op == Union || s2.Winding == 1) ? Segments1[0] : Segments2[0]; + + if (firstS.IsCurve) + Result.CurveTo(firstS.HI.X + firstS.P.X, firstS.HI.Y + firstS.P.Y, + firstS.HO.X + firstS.P.X, firstS.HO.Y + firstS.P.Y, + firstS.P.X, firstS.P.Y); + else + Result.LineTo(firstS.P.X, firstS.P.Y); + + Result.CloseFigure(); + } + } + } +} + +void CBooleanOperations::TraceAllOverlap() +{ + if (AllInters(Segments1) && AllInters(Segments2)) + { + if (Op != Subtraction) + Result = std::move(Path1); + } + else if (AllInters(Segments1)) + { + if (Op == Intersection) + Result = std::move(Path1); + else if (Op == Union) + Result = std::move(Path2); + } + else if (AllInters(Segments2)) + { + if (Op == Intersection) + Result = std::move(Path2); + else if (Op == Union) + Result = std::move(Path1); + } + else + { + int count1 = 0, count2 = 0; + for (const auto& s : Segments1) + { + if (!s.Inters) + { + int touchCount = 0; + for (const auto& c : OriginCurves2) + count1 += CheckInters(MIN_POINT, s, c, touchCount); + break; + } + } + + for (const auto& s : Segments2) + { + if (!s.Inters) + { + int touchCount = 0; + for (const auto& c : OriginCurves1) + count2 += CheckInters(MIN_POINT, s, c, touchCount); + break; + } + } + + if (Op == Intersection) + { + SetWinding(); + TracePaths(); + } + else if (Op == Union) + { + if (count1 % 2 == 0 && count2 % 2 == 0) + TracePaths(); + else if (count1 % 2 == 0) + Result = std::move(Path1); + else + Result = std::move(Path2); + } + else if (count1 % 2 == 0 && count2 % 2 == 0) + Result = std::move(Path1); + else + { + Result.StartFigure(); + for (const auto& seg : count1 % 2 == 0 ? Segments1 : Segments2) + { + if (!seg.Inters && !seg.Visited) + { + Result.MoveTo(seg.P.X, seg.P.Y); + SetVisited(seg); + + Segment s = GetNextSegment(seg); + while (!s.IsEmpty() && s != seg) + { + if (s.IsCurve) + Result.CurveTo(s.HI.X + s.P.X, s.HI.Y + s.P.Y, + s.HO.X + s.P.X, s.HO.Y + s.P.Y, + s.P.X, s.P.Y); + else + Result.LineTo(s.P.X, s.P.Y); + + SetVisited(s); + + if (s.Inters) + s = GetNextSegment(s.Inters->S); + else + s = GetNextSegment(s); + } + + if (s.IsCurve) + Result.CurveTo(s.HI.X + s.P.X, s.HI.Y + s.P.Y, + s.HO.X + s.P.X, s.HO.Y + s.P.Y, + s.P.X, s.P.Y); + else + Result.LineTo(s.P.X, s.P.Y); + } + } + if (Close1 && Close2) Result.CloseFigure(); + } + } +} + +void CBooleanOperations::TracePaths() +{ + size_t length = Segments1.size(); + Result.StartFigure(); + for (size_t i = 0; i < length + Segments2.size(); i++) + { + Segment s = i >= length ? Segments2[i - length] : Segments1[i]; + bool valid = s.IsValid(Op), + start = true; + while (valid) + { + if (!start || (Op == Intersection && s.Inters && !GetNextSegment(s).Inters)) + SetVisited(s); + + if (start) + Result.MoveTo(s.P.X, s.P.Y); + else if (s.IsCurve) + Result.CurveTo(s.HI.X + s.P.X, s.HI.Y + s.P.Y, + s.HO.X + s.P.X, s.HO.Y + s.P.Y, + s.P.X, s.P.Y); + else + Result.LineTo(s.P.X, s.P.Y); + + if (!start && valid && s.Inters) + SetVisited(s.Inters->S); + + Segment prev = s; + s = GetNextSegment(s); + if (s.IsEmpty()) break; + valid = s.IsValid(Op); + + if (s.Inters && prev.Inters && (s.Inters->S.Index - prev.Inters->S.Index) != 0) + { + Segment tmp = GetNextSegment(prev.Inters->S); + if (tmp.IsEmpty()) break; + if (tmp.IsValid(Op)) + s = tmp; + } + + if (!valid && prev.Inters) + { + s = GetNextSegment(prev.Inters->S); + if (!start || Op != Intersection) + SetVisited(prev.Inters->S); + valid = s.IsValid(Op); + } + + if (start) + start = false; + } + + if (!start && AllOverlap()) break; + } + + if (Close1 && Close2) Result.CloseFigure(); +} + +void CBooleanOperations::PreparePath(const CGraphicsPath& path, int id, + std::vector& segments, + std::vector& curves, + bool reverse) +{ + bool isPolyClosed = path.Is_poly_closed(); + int length = path.GetPointCount(); + int idx = 0; + if (reverse) + { + bool isCurve = false; + for (int i = length - 1; i >= 0; i--) + { + std::vector points = path.GetPoints(isCurve ? i - 2 : i, isCurve ? 3 : 1); + if (isCurve) std::reverse(points.begin(), points.end()); + if (segments.empty() || getDistance(segments[segments.size() - 1].P, isCurve ? points[2] : points[0]) > POINT_EPSILON) + { + if (!segments.empty() && getDistance(segments[0].P, isCurve ? points[2] : points[0]) <= POINT_EPSILON) + { + if (isCurve && segments[0].HI.IsZero() && segments[0].HO.IsZero()) + segments[0].SetHandles(points[0], points[1]); + } + else + segments.push_back(Segment(points, isCurve, idx++, id, isPolyClosed)); + } + + if (isCurve) i -= 2; + isCurve = path.IsCurvePoint(i); + } + } + else + { + for (int i = 0; i < length; i++) + { + bool isCurve = path.IsCurvePoint(i); + std::vector points = path.GetPoints(i, isCurve ? 3 : 1); + if (segments.empty() || getDistance(segments[segments.size() - 1].P, isCurve ? points[2] : points[0]) > POINT_EPSILON) + { + if (!segments.empty() && getDistance(segments[0].P, isCurve ? points[2] : points[0]) <= POINT_EPSILON) + { + if (isCurve && segments[0].HI.IsZero() && segments[0].HO.IsZero()) + segments[0].SetHandles(points[0], points[1]); + } + else + segments.push_back(Segment(points, isCurve, idx++, id, isPolyClosed)); + } + + if (isCurve) i += 2; + } + } + + length = isPolyClosed ? static_cast(segments.size()) : static_cast(segments.size()) - 1; + + for (int i = 0; i < length; i++) + curves.push_back(Curve(segments[i], isPolyClosed && (i == (length - 1)) ? segments[0] : segments[i + 1])); +} + +void CBooleanOperations::InsertSegment(Segment& segment, const Segment& handles, bool updateHandles) +{ + if (segment.Id == 1) + { + int length = static_cast(Segments1.size()), + index = segment.Index == length ? 0 : segment.Index; + if (getDistance(segment.P, Segments1[index].P) <= GEOMETRIC_EPSILON) + { + segment.Index = index; + Segments1[index] = segment; + return; + } + Segments1.insert(Segments1.begin() + segment.Index, segment); + + for (int i = segment.Index + 1; i < length + 1; i++) + Segments1[i].Index++; + + if (updateHandles) + Segments1[segment.Index == length ? 0 : segment.Index + 1].UpdateHandles(handles.HI, handles.HO); + + Curves1.clear(); + for (int i = 0; i < length + 1; i++) + Curves1.push_back(Curve(Segments1[i], i == (Segments1.size() - 1) ? + Segments1[0] : + Segments1[i + 1])); + } + else + { + int length = static_cast(Segments2.size()), + index = segment.Index == length ? 0 : segment.Index; + if (getDistance(segment.P, Segments2[index].P) <= GEOMETRIC_EPSILON) + { + segment.Index = index; + Segments2[index] = segment; + return; + } + Segments2.insert(Segments2.begin() + segment.Index, segment); + + for (int i = segment.Index + 1; i < length + 1; i++) + Segments2[i].Index++; + + if (updateHandles) + Segments2[segment.Index == length ? 0 : segment.Index + 1].UpdateHandles(handles.HI, handles.HO); + + Curves2.clear(); + for (int i = 0; i < length + 1; i++) + Curves2.push_back(Curve(Segments2[i], i == (Segments2.size() - 1) ? + Segments2[0] : + Segments2[i + 1])); + } + + for (auto& l : Locations) + if (l->S.Index >= segment.Index && l->S.Id == segment.Id) + l->S.Index++; +} + +Curve CBooleanOperations::GetCurve(const Segment& segment) const noexcept +{ + return segment.Id == 1 ? Curves1[segment.Index] : Curves2[segment.Index]; +} + +Curve CBooleanOperations::GetPreviousCurve(const Curve& curve) const noexcept +{ + bool path1 = curve.Segment1.Id == 1; + size_t last = path1 ? Curves1.size() - 1 + : Curves2.size() - 1; + + if (curve.Segment1.Index == 0) + { + if (curve.Segment1.PolyClosed) + return path1 ? Curves1[last] : Curves2[last]; + else + return Curve(); + } + + return path1 ? Curves1[curve.Segment1.Index - 1] + : Curves2[curve.Segment1.Index - 1]; +} + +Curve CBooleanOperations::GetNextCurve(const Curve& curve) const noexcept +{ + bool path1 = curve.Segment1.Id == 1; + int last = path1 ? static_cast(Curves1.size()) - 1 + : static_cast(Curves2.size()) - 1; + + if (curve.Segment1.Index == last) + { + if (curve.Segment1.PolyClosed) + return path1 ? Curves1[0] : Curves2[0]; + else + return Curve(); + } + + return path1 ? Curves1[curve.Segment1.Index + 1] + : Curves2[curve.Segment1.Index + 1]; +} + +Segment CBooleanOperations::GetNextSegment(const Segment& segment) const noexcept +{ + bool path1 = segment.Id == 1; + int last = path1 ? static_cast(Segments1.size()) - 1 + : static_cast(Segments2.size()) - 1; + + if (segment.Index == last) + { + if (segment.PolyClosed) + return path1 ? Segments1[0] : Segments2[0]; + else + return Segment(); + } + + return path1 ? Segments1[segment.Index + 1] + : Segments2[segment.Index + 1]; +} + +void CBooleanOperations::SetVisited(const Segment& segment) +{ + if (segment.Id == 1) + Segments1[segment.Index].Visited = true; + else + Segments2[segment.Index].Visited = true; +} + +std::vector> CBooleanOperations::FindBoundsCollisions() +{ + std::vector> allBounds, bounds2; + for (const auto& c : Curves1) + allBounds.push_back(c.GetBound()); + for (const auto& c : Curves2) + bounds2.push_back(c.GetBound()); + + bool self = allBounds == bounds2; + + if (!self) + for (auto it = bounds2.begin(); it != bounds2.end(); ++it) + allBounds.push_back(*it); + + int allLength = static_cast(allBounds.size()), + length1 = static_cast(Curves1.size()); + + std::vector allIdicesByPri1(allLength); + for (int i = 0; i < allLength; i++) + allIdicesByPri1[i] = i; + + std::sort(allIdicesByPri1.begin(), + allIdicesByPri1.end(), + [&allBounds](int i1, int i2){ + return allBounds[i1][0] < allBounds[i2][0]; + }); + + std::vector activeIndicesByPri2; + std::vector> allCollisions(length1); + for (int i = 0; i < allLength; i++) + { + std::vector curCollisions; + bool isCurrent1 = allIdicesByPri1[i] < length1, + isCurrent2 = self || !isCurrent1; + int origIndex = self ? allIdicesByPri1[i] : allIdicesByPri1[i] - length1; + + if (!activeIndicesByPri2.empty()) + { + int pruneCount = binarySearch(allBounds, activeIndicesByPri2, 2, + allBounds[allIdicesByPri1[i]][0] - GEOMETRIC_EPSILON) + 1; + + activeIndicesByPri2.erase(activeIndicesByPri2.begin(), + activeIndicesByPri2.begin() + pruneCount); + for (int j = 0; j < static_cast(activeIndicesByPri2.size()); j++) + { + bool isActive1 = activeIndicesByPri2[j] < length1, + isActive2 = self || !isActive1, + isActive1Or2 = (isCurrent1 && isActive2) || (isCurrent2 && isActive1), + inRange1 = allBounds[allIdicesByPri1[i]][1] <= allBounds[activeIndicesByPri2[j]][3] + GEOMETRIC_EPSILON, + inRange2 = allBounds[allIdicesByPri1[i]][3] >= allBounds[activeIndicesByPri2[j]][1] - GEOMETRIC_EPSILON; + + if (isActive1Or2 && (inRange2 && inRange1)) + { + if (isCurrent1 && isActive2) + curCollisions.push_back(self ? activeIndicesByPri2[j] : activeIndicesByPri2[j] - length1); + if (isCurrent2 && isActive1) + allCollisions[activeIndicesByPri2[j]].push_back(origIndex); + } + } + } + if (isCurrent1) + { + if (self) curCollisions.push_back(allIdicesByPri1[i]); + allCollisions[allIdicesByPri1[i]] = curCollisions; + } + if (activeIndicesByPri2.size() > 0) + { + int index = 1 + binarySearch(allBounds, activeIndicesByPri2, 2, allBounds[allIdicesByPri1[i]][2]); + activeIndicesByPri2.insert(activeIndicesByPri2.begin() + index, allIdicesByPri1[i]); + } + else + activeIndicesByPri2.push_back(allIdicesByPri1[i]); + } + + for (auto& c : allCollisions) + std::sort(c.begin(), c.end()); + + return allCollisions; +} + +bool CBooleanOperations::IsCrossing(std::shared_ptr loc) noexcept +{ + if(!loc->Inters) + return false; + + double t1 = loc->Time, + t2 = loc->Inters->Time, + tMin = CURVETIME_EPSILON, + tMax = 1 - tMin; + + bool t1Inside = t1 >= tMin && t1 <= tMax, + t2Inside = t2 >= tMin && t2 <= tMax; + + if (t1Inside && t2Inside) + return !loc->IsTouching(); + + Curve c2 = loc->C, + c1 = t1 < tMin ? GetPreviousCurve(c2) : c2, + c4 = loc->Inters->C, + c3 = t2 < tMin ? GetPreviousCurve(c4) : c4; + + if (t1 > tMax) c2 = GetNextCurve(c2); + if (t2 > tMax) c4 = GetNextCurve(c4); + + std::vector offsets; + + if (!t1Inside) + { + AddOffsets(offsets, c1, true); + AddOffsets(offsets, c2, false); + } + + if (!t2Inside) + { + AddOffsets(offsets, c3, true); + AddOffsets(offsets, c4, false); + } + + PointD pt = loc->C.GetPoint(loc->Time); + double offset = MAX; + for (const auto& o : offsets) + if (o < offset) + offset = o; + + PointD v2 = c2.GetTangent(t1, offset, t1Inside, pt), + v1 = t1Inside ? PointD(-v2.X, -v2.Y) : c1.GetTangent(t1, -offset, false, pt), + v4 = c4.GetTangent(t2, offset, t2Inside, pt), + v3 = t2Inside ? PointD(-v4.X, -v4.Y) : c3.GetTangent(t2, -offset, false, pt); + + double a1 = v1.Equals(PointD()) ? 0.0 : atan2(v1.Y, v1.X) * 180 / M_PI, + a2 = v2.Equals(PointD()) ? 0.0 : atan2(v2.Y, v2.X) * 180 / M_PI, + a3 = v3.Equals(PointD()) ? 0.0 : atan2(v3.Y, v3.X) * 180 / M_PI, + a4 = v4.Equals(PointD()) ? 0.0 : atan2(v4.Y, v4.X) * 180 / M_PI; + + bool inRange34 = isInRange(a1, a3, a4) ^ isInRange(a2, a3, a4), + inRange43 = isInRange(a1, a4, a3) ^ isInRange(a2, a4, a3), + inRange1 = inRange34 && inRange43, + inRange12 = isInRange(a3, a1, a2) ^ isInRange(a4, a1, a2), + inRange21 = isInRange(a3, a2, a1) ^ isInRange(a4, a2, a1), + inRange2 = inRange21 && inRange12; + + return t1Inside ? inRange1 : inRange2; +} + +bool CBooleanOperations::IntersectsBounds() noexcept +{ + RectF_T rect1, rect2; + Path1.GetBounds(rect1.X, rect1.Y, rect1.Width, rect1.Height); + Path2.GetBounds(rect2.X, rect2.Y, rect2.Width, rect2.Height); + + return (rect2.X + rect2.Width > rect1.X - EPSILON) && + (rect2.Y + rect2.Height > rect1.Y - EPSILON) && + (rect2.X < rect1.X + rect1.Width + EPSILON) && + (rect2.Y < rect1.Y + rect1.Height + EPSILON); +} + +void CBooleanOperations::GetIntersection() +{ + if (!IntersectsBounds()) return; + + std::vector> boundsCollisions = FindBoundsCollisions(); + for (int index1 = 0; index1 < Curves1.size(); index1++) + for (int j = 0; j < boundsCollisions[index1].size(); j++) + GetCurveIntersection(Curves1[index1], Curves2[boundsCollisions[index1][j]]); +} + +void CBooleanOperations::GetCurveIntersection(const Curve& curve1, const Curve& curve2) +{ + std::vector x1 = curve1.GetXValues(), + y1 = curve1.GetYValues(), + x2 = curve2.GetXValues(), + y2 = curve2.GetYValues(); + + double minX1 = min(x1[0], x1[1], x1[2], x1[3]), + maxX1 = max(x1[0], x1[1], x1[2], x1[3]), + minY1 = min(y1[0], y1[1], y1[2], y1[3]), + maxY1 = max(y1[0], y1[1], y1[2], y1[3]), + minX2 = min(x2[0], x2[1], x2[2], x2[3]), + maxX2 = max(x2[0], x2[1], x2[2], x2[3]), + minY2 = min(y2[0], y2[1], y2[2], y2[3]), + maxY2 = max(y2[0], y2[1], y2[2], y2[3]); + + if (maxX1 + GEOMETRIC_EPSILON > minX2 && minX1 - GEOMETRIC_EPSILON < maxX2 && + maxY1 + GEOMETRIC_EPSILON > minY2 && minY1 - GEOMETRIC_EPSILON < maxY2) + { + std::vector> overlaps = curve1.GetOverlaps(curve2); + if (!overlaps.empty()) + for (int i = 0; i < 2; i++) + AddLocation(curve1, curve2, overlaps[i].first, overlaps[i].second, true); + else + { + bool straight1 = curve1.IsStraight(), + straight2 = curve2.IsStraight(), + straight = straight1 && straight2, + flip = straight1 && !straight2; + size_t before = Locations.size(); + if (straight) + AddLineIntersection(flip ? curve2 : curve1, flip ? curve1 : curve2); + else if (straight1 || straight2) + AddCurveLineIntersection(flip ? curve2 : curve1, flip ? curve1 : curve2, flip); + else + AddCurveIntersection(flip ? curve2 : curve1, flip ? curve1 : curve2, + flip ? curve2 : curve1, flip ? curve1 : curve2, flip); + + if (Locations.size() == before && (!straight || Locations.empty())) + { + double t = curve2.GetTimeOf(curve1.Segment1.P); + if (t != -1.0) + AddLocation(curve1, curve2, 0.0, t, Locations.empty(), false, true); + t = curve2.GetTimeOf(curve1.Segment2.P); + if (t != -1.0) + AddLocation(curve1, curve2, 1.0, t, Locations.empty(), false, true); + t = curve1.GetTimeOf(curve2.Segment1.P); + if (t != -1.0) + AddLocation(curve1, curve2, t, 0.0, Locations.empty(), false, true); + t = curve1.GetTimeOf(curve2.Segment2.P); + if (t != -1.0) + AddLocation(curve1, curve2, t, 1.0, Locations.empty(), false, true); + } + } + } +} + +void CBooleanOperations::LinkIntersection(std::shared_ptr from, + std::shared_ptr to) +{ + std::shared_ptr prev = from; + while (prev) + { + if (prev == to) + return; + prev = prev->Prev; + } + + while (from->Next && from->Next != to) + from = from->Next; + + if (!from->Next) + { + while (to->Prev) + to = to->Prev; + from->Next = to; + to->Prev = from; + } +} + +void CBooleanOperations::AddLineIntersection(const Curve& curve1, const Curve& curve2) +{ + PointD pt; + if (intersect({curve1.Segment1.P.X, curve1.Segment1.P.Y, curve1.Segment2.P.X, curve1.Segment2.P.Y, + curve2.Segment1.P.X, curve2.Segment1.P.Y, curve2.Segment2.P.X, curve2.Segment2.P.Y}, pt)) + AddLocation(curve1, curve2, curve1.GetTimeOf(pt), curve2.GetTimeOf(pt)); +} + +void CBooleanOperations::AddCurveLineIntersection(const Curve& curve1, const Curve& curve2, bool flip) +{ + std::vector x2 = curve2.GetXValues(), + y2 = curve2.GetYValues(), + roots = curve1.GetCurveLineIntersection(x2[0], y2[0], x2[3] - x2[0], y2[3] - y2[0]); + for (const auto& r : roots) + { + double t1 = r; + PointD p1 = curve1.GetPoint(t1); + double t2 = curve2.GetTimeOf(p1); + + if (flip) std::swap(t1, t2); + if (t2 != -1) + AddLocation(flip ? curve2 :curve1, flip ? curve1 : curve2, t1, t2); + } +} + +int CBooleanOperations::AddCurveIntersection(const Curve& curve1, const Curve& curve2, const Curve& startCurve1, + const Curve& startCurve2, bool flip, + int recursion, int calls, double tMin, + double tMax, double uMin, double uMax) +{ + if (++calls >= 4096 || ++recursion >= 40) + return calls; + + std::vector x1 = curve1.GetXValues(), + y1 = curve1.GetYValues(), + x2 = curve2.GetXValues(), + y2 = curve2.GetYValues(); + + double d1 = getSignedDistance(x2[0], y2[0], x2[3], y2[3], x2[1], y2[1], false), + d2 = getSignedDistance(x2[0], y2[0], x2[3], y2[3], x2[2], y2[2], false), + factor = (d1 * d2) > 0 ? 3.0 / 4.0 : 4.0 / 9.0, + dMin = factor * min(0, d1, d2), + dMax = factor * max(0, d1, d2), + dp0 = getSignedDistance(x2[0], y2[0], x2[3], y2[3], x1[0], y1[0], false), + dp1 = getSignedDistance(x2[0], y2[0], x2[3], y2[3], x1[1], y1[1], false), + dp2 = getSignedDistance(x2[0], y2[0], x2[3], y2[3], x1[2], y1[2], false), + dp3 = getSignedDistance(x2[0], y2[0], x2[3], y2[3], x1[3], y1[3], false); + + std::vector top; + std::vector bottom; + getConvexHull(dp0, dp1, dp2, dp3, top, bottom); + + double tMinClip = clipConvexHull(top, bottom, dMin, dMax); + + std::reverse(top.begin(), top.end()); + std::reverse(bottom.begin(), bottom.end()); + + double tMaxClip = clipConvexHull(top, bottom, dMin, dMax); + + if ((d1 == 0 && d2 == 0 && dp0 == 0 && dp1 == 0 && dp2 == 0 && dp3 == 0) + || tMinClip == MIN || tMaxClip == MIN) + return calls; + + double tMinNew = tMin + (tMax - tMin) * tMinClip, + tMaxNew = tMin + (tMax - tMin) * tMaxClip; + + if (std::max(uMax - uMin, tMaxNew - tMinNew) < LINE_EPSILON) + { + double t = (tMinNew + tMaxNew) / 2, + u = (uMin + uMax) / 2; + + Curve c1 = flip ? startCurve2 : startCurve1, + c2 = flip ? startCurve1 : startCurve2; + + double t1 = flip ? u : t, + t2 = flip ? t : u; + + AddLocation(c1, c2, t1, t2); + } + else + { + Curve newCurve1 = curve1.GetPart(tMinClip, tMaxClip); + double uDiff = uMax - uMin; + + if (tMaxClip - tMinClip > 0.8) + { + if (tMaxNew - tMinNew > uDiff) + { + std::vector parts = newCurve1.Subdivide(0.5); + double t = (tMinNew + tMaxNew) / 2; + + parts[0].Segment2.SetHandles(parts[0].Segment2.HI, parts[0].Segment2.HO); + parts[1].Segment2.SetHandles(parts[1].Segment2.HI, parts[1].Segment2.HO); + + calls = AddCurveIntersection(curve2, parts[0], startCurve2, startCurve1, + !flip, recursion, calls, uMin, uMax, tMinNew, t); + calls = AddCurveIntersection(curve2, parts[1], startCurve2, startCurve1, + !flip, recursion, calls, uMin, uMax, t, tMaxNew); + } + else + { + std::vector parts = curve2.Subdivide(0.5); + double u = (uMin + uMax) / 2; + + parts[0].Segment2.SetHandles(parts[0].Segment2.HI, parts[0].Segment2.HO); + parts[1].Segment2.SetHandles(parts[1].Segment2.HI, parts[1].Segment2.HO); + + calls = AddCurveIntersection(parts[0], newCurve1, startCurve2, startCurve1, + !flip, recursion, calls, uMin, u, tMinNew, tMaxNew); + calls = AddCurveIntersection(parts[1], newCurve1, startCurve2, startCurve1, + !flip, recursion, calls, u, uMax, tMinNew, tMaxNew); + } + } + else + { + if (uDiff == 0 || uDiff >= LINE_EPSILON) + calls = AddCurveIntersection(curve2, newCurve1, startCurve2, startCurve1, + !flip, recursion, calls, uMin, uMax, tMinNew, tMaxNew); + else + calls = AddCurveIntersection(newCurve1, curve2, startCurve1, startCurve2, + flip, recursion, calls, tMinNew, tMaxNew, uMin, uMax); + } + } + + return calls; +} + +int CBooleanOperations::CheckInters(const PointD& point, const Segment& segment, const Curve& curve, int& touchCount) const +{ + PointD pt{}; + if (intersect({point.X, point.Y, segment.P.X, segment.P.Y, curve.Segment1.P.X, curve.Segment1.P.Y, curve.Segment2.P.X, curve.Segment2.P.Y}, pt)) + { + if (getDistance(segment.P, pt) <= GEOMETRIC_EPSILON) return (touchCount + 1) % 2; + if (getDistance(curve.Segment1.P, pt) <= GEOMETRIC_EPSILON || getDistance(curve.Segment2.P, pt) <= GEOMETRIC_EPSILON) + return ++touchCount % 2; + else if (curve.IsStraight()) + { + touchCount++; + return 1; + } + } + if (!curve.IsStraight()) + { + std::vector roots = curve.GetCurveLineIntersection(segment.P.X,segment.P.Y, point.X - segment.P.X, point.Y - segment.P.Y); + Curve line(segment, Segment(point)); + + int count = 0; + for (const auto& r : roots) + if (line.GetTimeOf(curve.GetPoint(r)) != -1) + count++; + + return count; + } + return 0; +} + +void CBooleanOperations::SetWinding() +{ + if (Locations.empty() || (Locations.size() == 2 && Locations[0]->Ends)) + { + Segment s1, s2; + + for (const auto& s : Segments1) + if (!s.Inters) + s1 = s; + + for (const auto& s : Segments2) + if (!s.Inters) + s2 = s; + + int count = 0, + touchCount = 0; + for (const auto& c : OriginCurves2) + count += CheckInters(MIN_POINT, s1, c, touchCount); + + for (auto& s : Segments1) + s.Winding = count % 2; + + count = 0; + touchCount = 0; + for (const auto& c : OriginCurves1) + count += CheckInters(MIN_POINT, s2, c, touchCount); + + for (auto& s : Segments2) + s.Winding = count % 2; + } + else + { + for (const auto& l : Locations) + { + Segment start = l->S, + s = GetNextSegment(l->S); + + if (s.IsEmpty() || s.Inters || s == start) + continue; + + int count = 0, + touchCount = 0; + for (const auto& c : (s.Id == 1 ? OriginCurves2 : OriginCurves1)) + count += CheckInters(MIN_POINT, s, c, touchCount); + + do + { + if (s.Id == 1 ) + Segments1[s.Index].Winding = count % 2; + else + Segments2[s.Index].Winding = count % 2; + s = GetNextSegment(s); + } while (!s.IsEmpty() && !s.Inters && s != start); + } + } + + if (FillType & c_nStroke) + for (auto& s : Segments2) + s.Winding = 0; +} + +void CBooleanOperations::DivideLocations() +{ + double tMin = CURVETIME_EPSILON, + tMax = 1 - tMin, + prevTime = -1.0; + + Curve prevCurve; + + for (int i = static_cast(Locations.size()) - 1; i >= 0; i--) + { + double origTime = Locations[i]->Time, + time = origTime; + + Segment segment; + Curve curve = GetCurve(Locations[i]->C.Segment1), + newCurve; + + bool updateHandles = false; + + if (Locations[i]->C != prevCurve) + prevCurve = Locations[i]->C; + else if (prevTime >= tMin) + time /= prevTime; + + prevTime = origTime; + + if (time < tMin) + { + segment = curve.Segment1; + } + else if (time > tMax) + { + segment = curve.Segment2; + } + else + { + if (curve.IsStraight()) + segment = Segment(Locations[i]->C.GetPoint(origTime), + false, + curve.Segment1.Index + 1, + curve.Segment1.Id, + curve.Segment1.PolyClosed); + else + { + newCurve = curve.Segment1.Id == 1 ? curve.DivideAtTime(time) + : curve.DivideAtTime(time); + segment = newCurve.Segment1; + updateHandles = true; + } + } + std::shared_ptr inter = segment.Inters, + dest = Locations[i]->Inters; + if (inter) + { + LinkIntersection(inter, dest); + + std::shared_ptr other = inter; + while (other) + { + LinkIntersection(other->Inters, inter); + other = other->Next; + } + } + else + segment.Inters = dest; + + InsertSegment(segment, newCurve.Segment2, updateHandles); + Locations[i]->S = segment; + } +} + +void CBooleanOperations::InsertLocation(std::shared_ptr loc, bool overlap) +{ + if (Locations.empty()) + { + Locations.push_back(loc); + return; + } + + int length = static_cast(Locations.size()), + l = 0, + r = length - 1; + while (l <= r) + { + int mid = (l + r) >> 1; + + if (getDistance(loc->C.GetPoint(loc->Time), Locations[mid]->C.GetPoint(Locations[mid]->Time)) <= LOCATION_EPSILON + && loc->C.Segment1.Id == Locations[mid]->C.Segment1.Id) + return; + + if (overlap) + { + if (getDistance(loc->C.GetPoint(loc->Time), loc->Inters->C.GetPoint(loc->Inters->Time)) > LOCATION_EPSILON) + return; + + for (int i = mid - 1; i >= -1; i--) + { + size_t idx = ((i % length) + length) % length; + if (getDistance(loc->C.GetPoint(loc->Time), Locations[idx]->C.GetPoint(Locations[idx]->Time)) > LOCATION_EPSILON) + break; + if (getDistance(loc->C.GetPoint(loc->Time), Locations[idx]->C.GetPoint(Locations[idx]->Time)) <= LOCATION_EPSILON && + loc->C.Segment1.Id == Locations[idx]->C.Segment1.Id) + return; + } + for (int i = mid + 1; i <= length; i++) + { + size_t idx = ((i % length) + length) % length; + if (getDistance(loc->C.GetPoint(loc->Time), Locations[idx]->C.GetPoint(Locations[idx]->Time)) > LOCATION_EPSILON) + break; + if (getDistance(loc->C.GetPoint(loc->Time), Locations[idx]->C.GetPoint(Locations[idx]->Time)) <= LOCATION_EPSILON && + loc->C.Segment1.Id == Locations[idx]->C.Segment1.Id) + return; + } + } + + double diffId = loc->C.Segment1.Id - Locations[mid]->C.Segment1.Id, + diffT = (loc->C.Segment1.Index + loc->Time) - (Locations[mid]->C.Segment1.Index + Locations[mid]->Time); + bool self = loc->C.Segment1.Id == Locations[mid]->C.Segment1.Id; + double diff = self ? (diffT) : (diffId); + if (diff < 0) + r = mid - 1; + else + l = mid + 1; + } + Locations.insert(Locations.begin() + l, loc); +} + +bool CBooleanOperations::AllOverlap() const noexcept +{ + if (Locations.empty()) return false; + + for (const auto& l : Locations) + if (!l->Overlap) + return false; + + return true; +} + +bool CBooleanOperations::AllInters(const std::vector& segments) const noexcept +{ + for (const auto& s : segments) + if (!s.Inters) + return false; + + return true; +} + +void CBooleanOperations::AddLocation(Curve curve1, Curve curve2, double t1, + double t2, bool overlap, bool filter, bool ends) +{ + bool excludeStart = !overlap && GetPreviousCurve(curve1) == curve2, + excludeEnd = !overlap && curve1 != curve2 && GetNextCurve(curve1) == curve2; + double tMin = CURVETIME_EPSILON, + tMax = 1 - tMin; + + if (t1 >= (excludeStart ? tMin : 0) && + t1 <= (excludeEnd ? tMax : 1)) + { + if (t2 >= (excludeEnd ? tMin : 0) && + t2 <= (excludeStart ? tMax : 1)) + { + std::shared_ptr loc1(new Location(curve1, t1, overlap, ends)), + loc2(new Location(curve2, t2, overlap, ends)); + + loc1->Inters = loc2; + loc2->Inters = loc1; + + if (!filter || loc1->Overlap || IsCrossing(loc1)) + InsertLocation(loc1, overlap); + } + } +} + +void CBooleanOperations::AddOffsets(std::vector& offsets, + const Curve& curve, bool end) +{ + std::vector roots = curve.GetPeeks(); + + size_t count = roots.size(); + bool first = end && count != 0, + second = !end && count != 0; + + double offset = curve.GetLength(first ? roots[count - 1] : 0, + second ? roots[0] : 1); + offsets.push_back(count != 0 ? offset : offset / 32); +} + +CGraphicsPath CalcBooleanOperation(const CGraphicsPath& path1, + const CGraphicsPath& path2, + BooleanOpType op, + long fillType) +{ + std::vector paths1 = path1.GetSubPaths(), + paths2 = path2.GetSubPaths(), + paths; + + for (const auto& p1 : paths1) + { + for (const auto& p2 : paths2) + { + CBooleanOperations operation(p1, p2, op, fillType); + paths.push_back(operation.GetResult()); + } + } + + return CGraphicsPath(paths); +} + +//For unit-tests +bool CGraphicsPath::operator==(const CGraphicsPath& other) noexcept +{ + unsigned pointsCount = GetPointCount(), + otherPointsCount = other.GetPointCount(); + + if (pointsCount != otherPointsCount) + return false; + + std::vector points = GetPoints(0, pointsCount), + otherPoints = other.GetPoints(0, otherPointsCount); + + for (unsigned i = 0; i < pointsCount; i++) + if (getDistance(points[i], otherPoints[i]) > POINT_EPSILON) + return false; + + return true; +} +} diff --git a/DesktopEditor/graphics/BooleanOperations.h b/DesktopEditor/graphics/BooleanOperations.h new file mode 100644 index 00000000000..499c5f1a8fa --- /dev/null +++ b/DesktopEditor/graphics/BooleanOperations.h @@ -0,0 +1,179 @@ +#ifndef BOOLEANOPERATIONS_H +#define BOOLEANOPERATIONS_H + +#include "GraphicsPath.h" +#include + +namespace Aggplus +{ + struct Location; + + struct Segment + { + PointD P{}; + PointD HI{}; + PointD HO{}; + + bool IsCurve = false; + bool Visited = false; + bool PolyClosed = false; + + int Index = -1; + int Id = 0; + int Winding = 0; + + std::shared_ptr Inters{nullptr}; + + Segment() noexcept; + Segment(const std::vector& points, const bool& isCurve, + const int& index, const int& id, const bool& polyClosed) noexcept; + Segment(const PointD& point, const bool& isCurve, const int& index, + const int& id, const bool& polyClosed) noexcept; + Segment(const PointD& p) noexcept; + Segment(const PointD& p, const PointD& hi, const PointD& ho) noexcept; + + void SetHandles(const PointD& hi, const PointD& ho) noexcept; + void UpdateHandles(const PointD& hi, const PointD& ho) noexcept; + + bool IsValid(const BooleanOpType& op) const noexcept; + bool IsEmpty() const noexcept; + bool operator==(const Segment& other) const noexcept; + bool operator!=(const Segment& other) const noexcept; + }; + + struct Curve + { + Segment Segment1{}; + Segment Segment2{}; + + Curve() noexcept; + Curve(const Segment& segment1, const Segment& segment2) noexcept; + Curve(const std::vector& values) noexcept; + Curve(const double& x0, const double& y0, const double& x1, const double& y1, + const double& x2, const double& y2, const double& x3, const double& y3) noexcept; + + std::vector GetXValues() const noexcept; + std::vector GetYValues() const noexcept; + std::vector GetBound() const noexcept; + std::vector GetPeeks() const; + double GetLength(double a = 0, double b = 1) const; + double GetSquaredLineLength() const noexcept; + double GetTimeOf(const PointD& point) const noexcept; + double GetTimeAt(const double& offset) const noexcept; + PointD Get(const double& t, const int& type) const noexcept; + PointD GetPoint(const double& t) const noexcept; + PointD GetTangent(const double& t) const noexcept; + PointD GetTangent(const double& t, const double& offset, + const bool& inside, const PointD& p) const noexcept; + Curve GetPart(double from, double to) const noexcept; + std::vector GetMonoCurves(const bool& dir) const noexcept; + std::vector GetCurveLineIntersection(const double& px, const double& py, + const double& vx, const double& vy) const noexcept; + std::vector> GetOverlaps(const Curve& curve) const noexcept; + + std::vector Subdivide(const double& t) const noexcept; + Curve DivideAtTime(const double& time) noexcept; + + int SolveCubic(const int& coord, const double& value, std::vector& roots, + const double& mn, const double& mx) const noexcept; + int SolveCubic(double a, double b, double c, double d, std::vector& roots, + const double& mn, const double& mx) const noexcept; + + void Flip() noexcept; + + bool IsStraight() const noexcept; + bool operator==(const Curve& other) const noexcept; + bool operator!=(const Curve& other) const noexcept; + }; + + struct Location + { + Curve C{}; + Segment S{}; + double Time = -1.0; + bool Overlap = false; + bool Ends = false; + + std::shared_ptr Inters{nullptr}; + std::shared_ptr Next{nullptr}; + std::shared_ptr Prev{nullptr}; + + Location() noexcept; + Location(const Curve& curve, const double& time, const bool& overlap, const bool& ends) noexcept; + + bool IsTouching() noexcept; + }; + + class CBooleanOperations + { + public: + CBooleanOperations(const CGraphicsPath& path1, const CGraphicsPath& path2, BooleanOpType op, long fillType = c_nWindingFillMode); + ~CBooleanOperations(); + CGraphicsPath&& GetResult(); + + // BooleanOp + void TraceBoolean(); + void TraceOneInters(); + void TraceAllOverlap(); + void TracePaths(); + + // Path + void PreparePath(const CGraphicsPath& path, int id, std::vector& segments, + std::vector& curves, bool reverse = false); + void InsertSegment(Segment& segment, const Segment& handles, bool updateHandles); + Curve GetCurve(const Segment& segment) const noexcept; + Curve GetPreviousCurve(const Curve& curve) const noexcept; + Curve GetNextCurve(const Curve& curve) const noexcept; + Segment GetNextSegment(const Segment& segment) const noexcept; + void SetVisited(const Segment& segment); + + // Bounds + std::vector> FindBoundsCollisions(); + + // Intersection + bool IsCrossing(std::shared_ptr loc) noexcept; + bool IntersectsBounds() noexcept; + void GetIntersection(); + void GetCurveIntersection(const Curve& curve1, const Curve& curve2); + void LinkIntersection(std::shared_ptr form, std::shared_ptr to); + void AddLineIntersection(const Curve& curve1, const Curve& curve2); + void AddCurveLineIntersection(const Curve& curve1, const Curve& curve2, bool flip); + int AddCurveIntersection(const Curve& curve1, const Curve& curve2, const Curve& startCurve1, const Curve& startCurve2, bool flip, + int recursion = 0, int calls = 0, double tMin = 0.0, double tMax = 1.0, double uMin = 0.0, double uMax = 1.0); + int CheckInters(const PointD& point, const Segment& segment, const Curve& curve, int& touchCount) const; + void SetWinding(); + + // Location + void DivideLocations(); + void AddLocation(Curve curve1, Curve curve2, double t1, double t2, bool overlap = false, bool filter = true, bool bothEnds = false); + void InsertLocation(std::shared_ptr loc, bool overlap); + bool AllOverlap() const noexcept; + bool AllInters(const std::vector& segments) const noexcept; + void AddOffsets(std::vector& offsets, const Curve& curve, bool end); + + private: + BooleanOpType Op = Intersection; + + bool Close1 = true; + bool Close2 = true; + + // c_nStroke, c_nWindingFillMode, c_nEvenOddFillMode + long FillType = c_nWindingFillMode; + + CGraphicsPath Path1; + CGraphicsPath Path2; + CGraphicsPath Result; + + std::vector Segments1; + std::vector Segments2; + + std::vector OriginCurves1; + std::vector OriginCurves2; + std::vector Curves1; + std::vector Curves2; + + std::vector> Locations; + }; +} // namespace Aggplus + +#endif // BOOLEANOPERATIONS_H diff --git a/DesktopEditor/graphics/Clip.cpp b/DesktopEditor/graphics/Clip.cpp index 4c4e51e95a5..b755d3c49e2 100644 --- a/DesktopEditor/graphics/Clip.cpp +++ b/DesktopEditor/graphics/Clip.cpp @@ -191,6 +191,16 @@ namespace Aggplus { } + CClipMulti::clip_rasterizer* CClipMulti::GetRasterizer() + { + if (!m_bIsClip) + { + m_rasterizer.reset(); + return &m_rasterizer; + } + return NULL; + } + void CClipMulti::Create(LONG width, LONG height) { m_lWidth = width; @@ -212,62 +222,52 @@ namespace Aggplus typedef agg::conv_curve conv_crv_type; conv_crv_type c_c_path(trans); - + m_rasterizer.add_path(c_c_path); - m_rasterizer.filling_rule(pPath->m_internal->m_bEvenOdd ? agg::fill_even_odd : agg::fill_non_zero); + + GenerateClip2(pPath->m_internal->m_bEvenOdd); + } + + void CClipMulti::GenerateClip2(bool bEvenOdd) + { + m_rasterizer.filling_rule(bEvenOdd ? agg::fill_even_odd : agg::fill_non_zero); m_bIsClip = true; m_bIsClip2 = false; } - void CClipMulti::Combine(CGraphicsPath* pPath, CMatrix* pMatrix, agg::sbool_op_e op) + void CClipMulti::Combine(bool bEvenOdd, agg::sbool_op_e op, clip_rasterizer* pRasterizer) { + if (!pRasterizer) + return; + if (!m_bIsClip) - return GenerateClip(pPath, pMatrix); + return GenerateClip2(bEvenOdd); if (!m_bIsClip2) { // смешивать надо с растерайзером - agg::rasterizer_scanline_aa rasterizer; - rasterizer.clip_box(0, 0, m_lWidth, m_lHeight); - - typedef agg::conv_transform trans_type; - trans_type trans(pPath->m_internal->m_agg_ps, pMatrix->m_internal->m_agg_mtx); - - typedef agg::conv_curve conv_crv_type; - conv_crv_type c_c_path(trans); - - rasterizer.add_path(c_c_path); - rasterizer.filling_rule(pPath->m_internal->m_bEvenOdd ? agg::fill_even_odd : agg::fill_non_zero); + pRasterizer->filling_rule(bEvenOdd ? agg::fill_even_odd : agg::fill_non_zero); scanline_type sl1; scanline_type sl2; scanline_type sl; - agg::sbool_combine_shapes_aa(op, m_rasterizer, rasterizer, sl1, sl2, sl, m_storage1); + agg::sbool_combine_shapes_aa(op, m_rasterizer, *pRasterizer, sl1, sl2, sl, m_storage1); m_lCurStorage = 1; } else { // надо смешивать со стораджем - agg::rasterizer_scanline_aa rasterizer; - rasterizer.clip_box(0, 0, m_lWidth, m_lHeight); - - typedef agg::conv_transform trans_type; - trans_type trans(pPath->m_internal->m_agg_ps, pMatrix->m_internal->m_agg_mtx); - typedef agg::conv_curve conv_crv_type; - conv_crv_type c_c_path(trans); - - rasterizer.add_path(c_c_path); - rasterizer.filling_rule(pPath->m_internal->m_bEvenOdd ? agg::fill_even_odd : agg::fill_non_zero); + pRasterizer->filling_rule(op ? agg::fill_even_odd : agg::fill_non_zero); scanline_type sl1; scanline_type sl2; scanline_type sl; - agg::sbool_combine_shapes_aa(op, rasterizer, (m_lCurStorage == 1) ? m_storage1 : m_storage2, sl1, sl2, sl, + agg::sbool_combine_shapes_aa(op, *pRasterizer, (m_lCurStorage == 1) ? m_storage1 : m_storage2, sl1, sl2, sl, (m_lCurStorage == 1) ? m_storage2 : m_storage1); if (1 == m_lCurStorage) diff --git a/DesktopEditor/graphics/Clip.h b/DesktopEditor/graphics/Clip.h index 034fe01c67d..d5c4d4be0b3 100644 --- a/DesktopEditor/graphics/Clip.h +++ b/DesktopEditor/graphics/Clip.h @@ -138,10 +138,11 @@ class CClip class CClipMulti { +public: typedef agg::scanline_p8 scanline_type; + typedef agg::rasterizer_scanline_aa clip_rasterizer; -public: - agg::rasterizer_scanline_aa m_rasterizer; + clip_rasterizer m_rasterizer; agg::scanline_storage_aa8 m_storage1; agg::scanline_storage_aa8 m_storage2; @@ -158,10 +159,13 @@ class CClipMulti CClipMulti(); ~CClipMulti(); + clip_rasterizer* GetRasterizer(); + void Create(LONG width, LONG height); void GenerateClip(CGraphicsPath* pPath, CMatrix* pMatrix); + void GenerateClip2(bool bEvenOdd); - void Combine(CGraphicsPath* pPath, CMatrix* pMatrix, agg::sbool_op_e op); + void Combine(bool bEvenOdd, agg::sbool_op_e op, clip_rasterizer* pRasterizer); bool IsClip(); bool IsClip2(); diff --git a/DesktopEditor/graphics/Graphics.cpp b/DesktopEditor/graphics/Graphics.cpp index 769310a6d6a..2ffd835aff7 100644 --- a/DesktopEditor/graphics/Graphics.cpp +++ b/DesktopEditor/graphics/Graphics.cpp @@ -32,7 +32,6 @@ #include "Graphics.h" #include #include "../fontengine/FontFile.h" -#include "AlphaMask_private.h" namespace Aggplus { @@ -69,6 +68,7 @@ namespace Aggplus m_dDpiTile = -1; m_pAlphaMask = NULL; + m_pSoftMask = NULL; m_nTextRenderMode = FT_RENDER_MODE_NORMAL; m_nBlendMode = agg::comp_op_src_over; @@ -105,7 +105,10 @@ namespace Aggplus #endif m_dDpiTile = -1; - + + m_pAlphaMask = NULL; + m_pSoftMask = NULL; + m_nTextRenderMode = FT_RENDER_MODE_NORMAL; m_nBlendMode = agg::comp_op_src_over; @@ -146,7 +149,10 @@ namespace Aggplus #endif m_dDpiTile = -1; - + + m_pAlphaMask = NULL; + m_pSoftMask = NULL; + m_nTextRenderMode = FT_RENDER_MODE_NORMAL; m_nBlendMode = agg::comp_op_src_over; @@ -161,6 +167,13 @@ namespace Aggplus #endif RELEASEINTERFACE(m_pAlphaMask); + RELEASEINTERFACE(m_pSoftMask); + + while (!m_arLayers.empty()) + { + RELEASEINTERFACE(m_arLayers.top()); + m_arLayers.pop(); + } } INT CGraphics::IsDib() @@ -453,7 +466,7 @@ namespace Aggplus m_rasterizer.get_rasterizer().reset_clipping(); m_rasterizer.get_rasterizer().clip_box(m_dClipLeft, m_dClipTop, m_dClipWidth + m_dClipLeft, m_dClipHeight + m_dClipTop); - GetRendererBase().clip_box((int)m_dClipLeft, (int)m_dClipTop, (int)(m_dClipWidth + m_dClipLeft), (int)(m_dClipHeight + m_dClipTop)); + m_frame_buffer.ren_base().clip_box((int)m_dClipLeft, (int)m_dClipTop, (int)(m_dClipWidth + m_dClipLeft), (int)(m_dClipHeight + m_dClipTop)); m_oClip.Reset(); @@ -489,18 +502,41 @@ namespace Aggplus return Ok; } - Status CGraphics::CombineClip(CGraphicsPath* pPath, agg::sbool_op_e op) + Status CGraphics::CombineClip(CGraphicsPath* pPath, agg::sbool_op_e op, NSStructures::CPen* pPen) { Aggplus::CMatrix m; - return InternalClip(pPath, (m_bIntegerGrid || pPath->m_internal->m_pTransform != NULL) ? &m : &m_oFullTransform, op); + return InternalClip(pPath, (m_bIntegerGrid || pPath->m_internal->m_pTransform != NULL) ? &m : &m_oFullTransform, op, pPen); } - Status CGraphics::InternalClip(CGraphicsPath* pPath, CMatrix* pTransform, agg::sbool_op_e op) + Status CGraphics::InternalClip(CGraphicsPath* pPath, CMatrix* pTransform, agg::sbool_op_e op, NSStructures::CPen* pPen) { if (NULL == pPath) return InvalidParameter; - m_oClip.Combine(pPath, pTransform, op); + bool bTempRasterizer = false; + CClipMulti::clip_rasterizer* pRasterizer = m_oClip.GetRasterizer(); + if (!pRasterizer) + { + pRasterizer = new CClipMulti::clip_rasterizer(); + pRasterizer->clip_box(0, 0, m_oClip.m_lWidth, m_oClip.m_lHeight); + bTempRasterizer = true; + } + + agg::trans_affine* pAffine = NULL; + if (pPen) + pAffine = DoStrokePath(pPen, pPath, pRasterizer); + else + { + typedef agg::conv_transform trans_type; + trans_type trans(pPath->m_internal->m_agg_ps, pTransform->m_internal->m_agg_mtx); + + typedef agg::conv_curve conv_crv_type; + conv_crv_type c_c_path(trans); + + pRasterizer->add_path(c_c_path); + } + + m_oClip.Combine(pPath->m_internal->m_bEvenOdd, op, pRasterizer); // write to clips history CGraphics_ClipStateRecord* pRecord = new CGraphics_ClipStateRecord(); @@ -509,6 +545,11 @@ namespace Aggplus pRecord->Operation = op; m_oClipState.AddRecord(pRecord); + if (pAffine) + delete pAffine; + if (bTempRasterizer) + delete pRasterizer; + return Ok; } @@ -597,173 +638,7 @@ namespace Aggplus m_rasterizer.get_rasterizer().reset(); - agg::line_join_e LineJoin = agg::round_join; - switch(pPen->LineJoin) - { - case LineJoinMiter : LineJoin = agg::miter_join_revert; break; - case LineJoinBevel : LineJoin = agg::bevel_join; break; - case LineJoinRound : LineJoin = agg::round_join; break; - case LineJoinMiterClipped : LineJoin = agg::miter_join_revert; break; - default: break; - } - agg::line_cap_e LineCap = agg::round_cap; - switch(pPen->LineStartCap) - { - case LineCapFlat : LineCap = agg::butt_cap; break; - case LineCapRound : LineCap = agg::round_cap; break; - case LineCapSquare : LineCap = agg::square_cap; break; - default: break; - } - - double dWidth = pPen->Size; - double dWidthMinSize = 1.0 / sqrt(m_oCoordTransform.m_internal->m_agg_mtx.determinant()); - - if ((0 == dWidth && !m_bIntegerGrid) || dWidth < dWidthMinSize) - { - if (m_bIs0PenWidthAs1px) - dWidth = dWidthMinSize; - } - - double dblMiterLimit = pPen->MiterLimit; - - agg::path_storage path_copy(pPath->m_internal->m_agg_ps); - bool bIsUseIdentity = m_bIntegerGrid; - if (!bIsUseIdentity) - { - agg::trans_affine* full_trans = &m_oFullTransform.m_internal->m_agg_mtx; - double dDet = full_trans->determinant(); - - if (fabs(dDet) < 0.0001) - { - path_copy.transform_all_paths(m_oFullTransform.m_internal->m_agg_mtx); - dWidth *= sqrt(dDet); - - bIsUseIdentity = true; - } - } - - typedef agg::conv_curve conv_crv_type; - - conv_crv_type c_c_path(path_copy); - c_c_path.approximation_scale(25.0); - c_c_path.approximation_method(agg::curve_inc); - DashStyle eStyle = (DashStyle)pPen->DashStyle; - - if (DashStyleCustom == eStyle) - { - if (0 == pPen->Count || NULL == pPen->DashPattern) - { - eStyle = DashStyleSolid; - } - else - { - bool bFoundNormal = false; - for (int i = 0; i < pPen->Count; i++) - { - if (fabs(pPen->DashPattern[i]) > 0.0001) - { - bFoundNormal = true; - break; - } - } - if (!bFoundNormal) - eStyle = DashStyleSolid; - } - } - - agg::trans_affine* pAffine = &m_oFullTransform.m_internal->m_agg_mtx; - if (bIsUseIdentity) - pAffine = new agg::trans_affine(); - - if (DashStyleSolid == eStyle) - { - typedef agg::conv_stroke Path_Conv_StrokeN; - Path_Conv_StrokeN pgN(c_c_path); - - //pgN.line_join(agg::miter_join_revert); - - pgN.line_cap(LineCap); - - pgN.line_join(LineJoin); - pgN.inner_join(agg::inner_round); - - pgN.miter_limit(dblMiterLimit); - pgN.width(dWidth); - - pgN.approximation_scale(25.0); - - typedef agg::conv_transform transStroke; - - transStroke trans(pgN, *pAffine); - m_rasterizer.get_rasterizer().add_path(trans); - } - else - { - typedef agg::conv_dash Path_Conv_Dash; - Path_Conv_Dash poly2_dash(c_c_path); - - typedef agg::conv_stroke Path_Conv_StrokeD; - Path_Conv_StrokeD pgD(poly2_dash); - - switch (eStyle) - { - case DashStyleDash: - poly2_dash.add_dash(3.00*dWidth, dWidth); - break; - case DashStyleDot: - poly2_dash.add_dash(dWidth, dWidth); - break; - case DashStyleDashDot: - poly2_dash.add_dash(3.00*dWidth, dWidth); - poly2_dash.add_dash(dWidth, dWidth); - break; - case DashStyleDashDotDot: - poly2_dash.add_dash(3.00*dWidth, dWidth); - poly2_dash.add_dash(dWidth, dWidth); - poly2_dash.add_dash(dWidth, dWidth); - break; - default: - case DashStyleCustom: - { - double offset = pPen->DashOffset; - double* params = pPen->DashPattern; - LONG lCount = pPen->Count; - LONG lCount2 = lCount / 2; - - double dKoef = 1.0; - - for (LONG i = 0; i < lCount2; ++i) - { - if (0 == i) - { - poly2_dash.add_dash((params[i * 2]) * dKoef, params[i * 2 + 1] * dKoef); - } - else - { - poly2_dash.add_dash(params[i * 2] * dKoef, params[i * 2 + 1] * dKoef); - } - } - if (1 == (lCount % 2)) - { - poly2_dash.add_dash(params[lCount - 1] * dKoef, 0); - } - poly2_dash.dash_start(offset * dKoef); - - break; - } - } - - if ((0 == dWidth && !m_bIntegerGrid) || dWidth < dWidthMinSize) - dWidth = dWidthMinSize; - - pgD.line_cap(LineCap); - pgD.line_join(LineJoin); - pgD.miter_limit(dblMiterLimit); - pgD.width(dWidth); - - agg::conv_transform trans(pgD, *pAffine); - m_rasterizer.get_rasterizer().add_path(trans); - } + agg::trans_affine* pAffine = DoStrokePath(pPen, pPath, &m_rasterizer.get_rasterizer()); CColor oColor((BYTE)(pPen->Alpha * m_dGlobalAlpha), pPen->Color, m_bSwapRGB); CBrushSolid oBrush(oColor); @@ -778,8 +653,7 @@ namespace Aggplus if (gamma >= 0) m_rasterizer.gamma(1.0); - if (bIsUseIdentity) - RELEASEOBJECT(pAffine); + RELEASEOBJECT(pAffine); return Ok; } @@ -996,7 +870,7 @@ namespace Aggplus if(width == 0.00 || height == 0.00) return InvalidParameter; - + CGraphicsPath oPath; oPath.MoveTo(x, y); oPath.LineTo(x+width, y); @@ -1212,108 +1086,298 @@ namespace Aggplus return TRUE; } - Status CGraphics::SetAlphaMask(CAlphaMask* pAlphaMask) + Status CGraphics::SetAlphaMask(CAlphaMask *pAlphaMask) { RELEASEINTERFACE(m_pAlphaMask); m_pAlphaMask = pAlphaMask; + if (m_pAlphaMask) - { m_pAlphaMask->AddRef(); - m_pAlphaMask->m_internal->StartApplying(); - } - return Ok; + + return CreateLayer(); } - Status CGraphics::CreateAlphaMask() + Status CGraphics::StartCreatingAlphaMask() { + return CreateLayer(); + } + + Status CGraphics::EndCreatingAlphaMask() + { + if (m_arLayers.empty()) + return WrongState; + + CGraphicsLayer *pCurrentGraphicsLayer = m_arLayers.top(); + m_arLayers.pop(); + + if (pCurrentGraphicsLayer->Empty()) + return GenericError; + + BYTE* pBuffer = pCurrentGraphicsLayer->GetBuffer(); + + pCurrentGraphicsLayer->ClearBuffer(false); + + RELEASEINTERFACE(pCurrentGraphicsLayer); RELEASEINTERFACE(m_pAlphaMask); - m_pAlphaMask = new CAlphaMask(); - return m_pAlphaMask->CreateImageBuffer(m_frame_buffer.width(), m_frame_buffer.height()); + + m_pAlphaMask = new CAlphaMask(pBuffer, EMaskDataType::ImageBuffer, false); + return CreateLayer(); } Status CGraphics::ResetAlphaMask() { + BlendLayer(); RELEASEINTERFACE(m_pAlphaMask); return Ok; } - Status CGraphics::StartApplyingAlphaMask() + CSoftMask* CGraphics::CreateSoftMask(bool bAlpha) { - m_pAlphaMask->m_internal->StartApplying(); + if (m_arLayers.empty()) + return NULL; + + CGraphicsLayer *pCurrentGraphicsLayer = m_arLayers.top(); + m_arLayers.pop(); + + if (pCurrentGraphicsLayer->Empty()) + { + RELEASEINTERFACE(pCurrentGraphicsLayer); + return NULL; + } + + BYTE* pBuffer = pCurrentGraphicsLayer->GetBuffer(); + pCurrentGraphicsLayer->ClearBuffer(false); + + RELEASEINTERFACE(pCurrentGraphicsLayer); + RELEASEINTERFACE(m_pSoftMask); + + unsigned int unWidth = m_frame_buffer.ren_buf().width(), unHeight = m_frame_buffer.ren_buf().height(); + bool bFlip = m_frame_buffer.ren_buf().stride() < 0; + m_pSoftMask = new CSoftMask(pBuffer, unWidth, unHeight, bFlip, m_bSwapRGB, bAlpha); + + pBuffer = m_arLayers.empty() ? m_pPixels : m_arLayers.top()->GetBuffer(); + if (!pBuffer) + { + RELEASEINTERFACE(pCurrentGraphicsLayer); + return NULL; + } + + m_frame_buffer.ren_buf().attach(pBuffer, unWidth, unHeight, m_frame_buffer.ren_buf().stride()); + + return m_pSoftMask; + } + + Status CGraphics::SetSoftMask(CSoftMask* pSoftMask) + { + if (m_pSoftMask == pSoftMask) + return Ok; + + RELEASEINTERFACE(m_pSoftMask); + m_pSoftMask = pSoftMask; + + if (m_pSoftMask) + m_pSoftMask->AddRef(); + return Ok; } - void CGraphics::CalculateFullTransform() + Status CGraphics::AddLayer(CGraphicsLayer *pGraphicsLayer) { - m_oFullTransform = m_oCoordTransform; - m_oFullTransform.Multiply(&m_oBaseTransform, MatrixOrderAppend); - m_oFullTransform.Multiply(&m_oTransform, MatrixOrderPrepend); + if (NULL == pGraphicsLayer || pGraphicsLayer->Empty()) + return InvalidParameter; + + m_arLayers.push(pGraphicsLayer); + pGraphicsLayer->AddRef(); + + int nStride = m_frame_buffer.ren_buf().stride(); + const unsigned int unWidth = m_frame_buffer.ren_buf().width(); + const unsigned int unHeight = m_frame_buffer.ren_buf().height(); + + m_frame_buffer.create(unWidth, unHeight, nStride < 0, nStride, pGraphicsLayer->GetBuffer()); + + return Ok; } - bool CGraphics::IsClip() + + Status CGraphics::CreateLayer() { - return m_oClip.IsClip(); + int nStride = m_frame_buffer.ren_buf().stride(); + const unsigned int unWidth = m_frame_buffer.ren_buf().width(); + const unsigned int unHeight = m_frame_buffer.ren_buf().height(); + + UINT unSize = unWidth * unHeight * m_frame_buffer.pix_size; + + BYTE *pBuffer = new BYTE[unSize]; + + memset(pBuffer, 0x00, unSize); + + m_frame_buffer.create(unWidth, unHeight, nStride < 0, nStride, pBuffer); + + m_arLayers.push(new CGraphicsLayer(pBuffer, false)); + return Ok; } - agg::rendering_buffer& CGraphics::GetRenderingBuffer() + Status CGraphics::BlendLayer() { - if (m_pAlphaMask && GenerationAlphaMask == m_pAlphaMask->m_internal->GetStatus()) - return m_pAlphaMask->m_internal->GetRenderingBuffer(); + if (m_arLayers.empty()) + return WrongState; + + CGraphicsLayer *pCurrentGraphicsLayer = m_arLayers.top(); + m_arLayers.pop(); - return m_frame_buffer.ren_buf(); + BYTE* pBuffer = NULL; + + if (!m_arLayers.empty()) + pBuffer = m_arLayers.top()->GetBuffer(); + else + pBuffer = m_pPixels; + + if (NULL == pBuffer) + { + RELEASEINTERFACE(pCurrentGraphicsLayer); + return WrongState; + } + + m_frame_buffer.ren_buf().attach(pBuffer, m_frame_buffer.ren_buf().width(), m_frame_buffer.ren_buf().height(), m_frame_buffer.ren_buf().stride()); + + if (m_pAlphaMask) + { + switch(m_pAlphaMask->GetDataType()) + { + case EMaskDataType::ImageBuffer: + { + Aggplus::BlendTo>(pCurrentGraphicsLayer, m_frame_buffer.pixfmt(), m_pAlphaMask->GetBuffer(), m_pAlphaMask->GetStep()); + break; + } + case EMaskDataType::AlphaBuffer: + { + Aggplus::BlendTo(pCurrentGraphicsLayer, m_frame_buffer.pixfmt(), m_pAlphaMask->GetBuffer(), m_pAlphaMask->GetStep()); + break; + } + } + } + else if (m_pSoftMask) + { + ESoftMaskType nType = m_pSoftMask->GetDataType(); + if (nType == ESoftMaskType::RGBGrayBuffer) + Aggplus::BlendTo>(pCurrentGraphicsLayer, m_frame_buffer.pixfmt(), m_pSoftMask->GetBuffer(), m_pSoftMask->GetStep()); + else if (nType == ESoftMaskType::BGRGrayBuffer) + Aggplus::BlendTo>(pCurrentGraphicsLayer, m_frame_buffer.pixfmt(), m_pSoftMask->GetBuffer(), m_pSoftMask->GetStep()); + else if (nType == ESoftMaskType::Alpha4Buffer) + Aggplus::BlendTo(pCurrentGraphicsLayer, m_frame_buffer.pixfmt(), m_pSoftMask->GetBuffer() + 3, m_pSoftMask->GetStep()); + } + else + { + if (m_nBlendMode != agg::comp_op_src_over) + { + pixfmt_type_comp pixfmt(m_frame_buffer.ren_buf(), m_nBlendMode); + Aggplus::BlendTo(pCurrentGraphicsLayer, pixfmt, m_nBlendMode); + } + else + Aggplus::BlendTo(pCurrentGraphicsLayer, m_frame_buffer.pixfmt()); + } + + RELEASEINTERFACE(pCurrentGraphicsLayer); + return Ok; } + + Status CGraphics::RemoveLayer() + { + if (m_arLayers.empty()) + return WrongState; + + CGraphicsLayer *pCurrentGraphicsLayer = m_arLayers.top(); + m_arLayers.pop(); + + BYTE* pBuffer = NULL; + + if (!m_arLayers.empty()) + pBuffer = m_arLayers.top()->GetBuffer(); + else + pBuffer = m_pPixels; + + if (NULL == pBuffer) + { + RELEASEINTERFACE(pCurrentGraphicsLayer); + return WrongState; + } - base_renderer_type& CGraphics::GetRendererBase() + m_frame_buffer.ren_buf().attach(pBuffer, m_frame_buffer.ren_buf().width(), m_frame_buffer.ren_buf().height(), m_frame_buffer.ren_buf().stride()); + + RELEASEINTERFACE(pCurrentGraphicsLayer); + return Ok; + } + + Status CGraphics::SetLayerSettings(const TGraphicsLayerSettings &oSettings) { - if (m_pAlphaMask && GenerationAlphaMask == m_pAlphaMask->GetStatus() && ImageBuffer == m_pAlphaMask->GetDataType()) - return (base_renderer_type&)m_pAlphaMask->m_internal->GetRendererBaseImage(); + if (m_arLayers.empty()) + return WrongState; - return m_frame_buffer.ren_base(); + m_arLayers.top()->SetSettings(oSettings); + + return Ok; } - template - void CGraphics::render_scanlines(Renderer& ren) + Status CGraphics::SetLayerOpacity(double dOpacity) + { + if (dOpacity < 0. || dOpacity > 1.) + return InvalidParameter; + + if (m_arLayers.empty()) + return WrongState; + + m_arLayers.top()->SetOpacity(dOpacity); + + return Ok; + } + + void CGraphics::CalculateFullTransform() + { + m_oFullTransform = m_oCoordTransform; + m_oFullTransform.Multiply(&m_oBaseTransform, MatrixOrderAppend); + m_oFullTransform.Multiply(&m_oTransform, MatrixOrderPrepend); + } + bool CGraphics::IsClip() + { + return m_oClip.IsClip(); + } + + template + void CGraphics::render_scanlines_3(Rasterizer& ras, Renderer& ren, Scanline& sl) { if (!m_oClip.IsClip()) { - if (m_pAlphaMask && ApplyingAlphaMask == m_pAlphaMask->GetStatus()) - { - if (ImageBuffer == m_pAlphaMask->GetDataType()) - return agg::render_scanlines(m_rasterizer.get_rasterizer(), m_pAlphaMask->m_internal->GetScanlineImage(), ren); - else if (AlphaBuffer == m_pAlphaMask->GetDataType()) - return agg::render_scanlines(m_rasterizer.get_rasterizer(), m_pAlphaMask->m_internal->GetScanlineABuffer(), ren); - } - - return agg::render_scanlines(m_rasterizer.get_rasterizer(), m_rasterizer.get_scanline(), ren); + agg::render_scanlines(ras, sl, ren); } else { if (!m_oClip.IsClip2()) { - typedef agg::scanline_p8 sbool_scanline_type; + typedef agg::scanline_p8 sbool_scanline_type; - sbool_scanline_type sl_result; sbool_scanline_type sl1; sbool_scanline_type sl2; - agg::sbool_combine_shapes_aa(agg::sbool_and, m_rasterizer.get_rasterizer(), m_oClip.m_rasterizer, - sl1, sl2, sl_result, ren); + agg::sbool_combine_shapes_aa(agg::sbool_and, ras, m_oClip.m_rasterizer, sl1, sl2, sl, ren); } else { - typedef agg::scanline_p8 sbool_scanline_type; - sbool_scanline_type sl_result; + typedef agg::scanline_p8 sbool_scanline_type; + sbool_scanline_type sl1; sbool_scanline_type sl2; - sbool_scanline_type sl; - - agg::sbool_combine_shapes_aa(agg::sbool_and, m_rasterizer.get_rasterizer(), - (1 == m_oClip.m_lCurStorage) ? m_oClip.m_storage1 : m_oClip.m_storage2, sl1, sl2, sl_result, ren); + agg::sbool_combine_shapes_aa(agg::sbool_and, ras, (1 == m_oClip.m_lCurStorage) ? m_oClip.m_storage1 : m_oClip.m_storage2, sl1, sl2, sl, ren); } } } + template + void CGraphics::render_scanlines(Renderer& ren) + { + render_scanlines_2(m_rasterizer.get_rasterizer(), ren); + } + template void CGraphics::render_scanlines_alpha(Renderer& ren, BYTE Alpha) { @@ -1331,47 +1395,19 @@ namespace Aggplus } template - void CGraphics::render_scanlines(Rasterizer& ras, Renderer& ren) + void CGraphics::render_scanlines_2(Rasterizer& ras, Renderer& ren) { - if (!m_oClip.IsClip()) + if (m_pSoftMask) { - if (m_pAlphaMask && ApplyingAlphaMask == m_pAlphaMask->GetStatus()) - { - if (ImageBuffer == m_pAlphaMask->GetDataType()) - return agg::render_scanlines(ras, m_pAlphaMask->m_internal->GetScanlineImage(), ren); - else if (AlphaBuffer == m_pAlphaMask->GetDataType()) - return agg::render_scanlines(ras, m_pAlphaMask->m_internal->GetScanlineABuffer(), ren); - } - - return agg::render_scanlines(ras, m_rasterizer.get_scanline(), ren); - } - else - { - if (!m_oClip.IsClip2()) - { - typedef agg::scanline_p8 sbool_scanline_type; - - sbool_scanline_type sl_result; - sbool_scanline_type sl1; - sbool_scanline_type sl2; - - agg::sbool_combine_shapes_aa(agg::sbool_and, ras, m_oClip.m_rasterizer, - sl1, sl2, sl_result, ren); - } - else - { - typedef agg::scanline_p8 sbool_scanline_type; - - sbool_scanline_type sl_result; - sbool_scanline_type sl1; - sbool_scanline_type sl2; - - sbool_scanline_type sl; - - agg::sbool_combine_shapes_aa(agg::sbool_and, ras, - (1 == m_oClip.m_lCurStorage) ? m_oClip.m_storage1 : m_oClip.m_storage2, sl1, sl2, sl_result, ren); - } + ESoftMaskType nType = m_pSoftMask->GetDataType(); + if (nType == ESoftMaskType::RGBGrayBuffer) + return render_scanlines_3(ras, ren, ((CSoftMaskRGBAgray*)m_pSoftMask->m_pInternal)->GetScanline()); + if (nType == ESoftMaskType::BGRGrayBuffer) + return render_scanlines_3(ras, ren, ((CSoftMaskBGRAgray*)m_pSoftMask->m_pInternal)->GetScanline()); + if (nType == ESoftMaskType::Alpha4Buffer) + return render_scanlines_3(ras, ren, ((CSoftMaskAlpha*)m_pSoftMask->m_pInternal)->GetScanline()); } + render_scanlines_3(ras, ren, m_rasterizer.get_scanline()); } void CGraphics::DoFillPathSolid(CColor dwColor) @@ -1381,10 +1417,8 @@ namespace Aggplus typedef agg::renderer_scanline_aa_solid solid_comp_renderer_type; solid_comp_renderer_type ren_solid; comp_renderer_type ren_base; - pixfmt_type_comp pixfmt; + pixfmt_type_comp pixfmt(m_frame_buffer.ren_buf(), m_nBlendMode); - pixfmt.attach(GetRenderingBuffer()); - pixfmt.comp_op(m_nBlendMode); ren_base.attach(pixfmt); ren_solid.attach(ren_base); @@ -1394,7 +1428,7 @@ namespace Aggplus else { typedef agg::renderer_scanline_aa_solid solid_renderer_type; - solid_renderer_type ren_fine(GetRendererBase()); + solid_renderer_type ren_fine(m_frame_buffer.ren_base()); ren_fine.color(dwColor.GetAggColor()); render_scanlines(ren_fine); @@ -1465,7 +1499,7 @@ namespace Aggplus gradient_span_alloc span_alloc; typedef agg::renderer_scanline_aa renderer_gradient_type; - renderer_gradient_type ren_gradient( GetRendererBase(), span_alloc, span_gen ); + renderer_gradient_type ren_gradient( m_frame_buffer.ren_base(), span_alloc, span_gen ); if (fabs(m_dGlobalAlpha - 1.0) < FLT_EPSILON) { @@ -1546,7 +1580,7 @@ namespace Aggplus gradient_span_alloc span_alloc; typedef agg::renderer_scanline_aa renderer_gradient_type; - renderer_gradient_type ren_gradient( GetRendererBase(), span_alloc, span_gen ); + renderer_gradient_type ren_gradient( m_frame_buffer.ren_base(), span_alloc, span_gen ); if (fabs(m_dGlobalAlpha - 1.0) < FLT_EPSILON) { @@ -1605,7 +1639,7 @@ namespace Aggplus hatch_span_alloc span_alloc; typedef agg::renderer_scanline_aa renderer_hatch_type; - renderer_hatch_type ren_hatch( GetRendererBase(), span_alloc, span_gen ); + renderer_hatch_type ren_hatch( m_frame_buffer.ren_base(), span_alloc, span_gen ); if (fabs(m_dGlobalAlpha - 1.0) < FLT_EPSILON) { @@ -1647,7 +1681,7 @@ namespace Aggplus pixfmt img_pixf(PatRendBuff); img_source_type img_src(img_pixf); span_gen_type sg(img_src, interpolator); - renderer_type ri(GetRendererBase(), span_allocator, sg); + renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg); if (fabs(m_dGlobalAlpha - 1.0) < FLT_EPSILON) { @@ -1685,7 +1719,7 @@ namespace Aggplus pixfmt img_pixf(PatRendBuff); img_source_type img_src(img_pixf, agg::rgba(0, 0, 0, 0)); span_gen_type sg(img_src, interpolator); - renderer_type ri(GetRendererBase(), span_allocator, sg); + renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg); //agg::render_scanlines(m_rasterizer.get_rasterizer(), m_rasterizer.get_scanline(), ri); render_scanlines(ri); } @@ -1717,7 +1751,7 @@ namespace Aggplus typedef agg::span_image_filter_rgba_nn span_gen_type; typedef agg::renderer_scanline_aa renderer_type; span_gen_type sg(img_src, interpolator); - renderer_type ri(GetRendererBase(), span_allocator, sg); + renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg); render_scanlines_alpha(ri, Alpha); break; } @@ -1726,7 +1760,7 @@ namespace Aggplus typedef agg::span_image_filter_rgba_bilinear span_gen_type; typedef agg::renderer_scanline_aa renderer_type; span_gen_type sg(img_src, interpolator); - renderer_type ri(GetRendererBase(), span_allocator, sg); + renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg); render_scanlines_alpha(ri, Alpha); break; } @@ -1737,7 +1771,7 @@ namespace Aggplus agg::image_filter_lut filter; filter.calculate(agg::image_filter_bicubic(), false); span_gen_type sg(img_src, interpolator, filter); - renderer_type ri(GetRendererBase(), span_allocator, sg); + renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg); render_scanlines_alpha(ri, Alpha); break; } @@ -1748,7 +1782,7 @@ namespace Aggplus agg::image_filter_lut filter; filter.calculate(agg::image_filter_spline16(), false); span_gen_type sg(img_src, interpolator, filter); - renderer_type ri(GetRendererBase(), span_allocator, sg); + renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg); render_scanlines_alpha(ri, Alpha); break; } @@ -1759,7 +1793,7 @@ namespace Aggplus agg::image_filter_lut filter; filter.calculate(agg::image_filter_blackman256(), false); span_gen_type sg(img_src, interpolator, filter); - renderer_type ri(GetRendererBase(), span_allocator, sg); + renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg); render_scanlines_alpha(ri, Alpha); break; } @@ -1770,7 +1804,7 @@ namespace Aggplus agg::image_filter_lut filter; filter.calculate(agg::image_filter_bilinear(), false); span_gen_type sg(img_src, interpolator, filter); - renderer_type ri(GetRendererBase(), span_allocator, sg); + renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg); render_scanlines_alpha(ri, Alpha); break; } @@ -1793,7 +1827,7 @@ namespace Aggplus typedef agg::span_image_filter_rgba_nn span_gen_type; typedef agg::renderer_scanline_aa renderer_type; span_gen_type sg(img_src, interpolator); - renderer_type ri(GetRendererBase(), span_allocator, sg); + renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg); render_scanlines_alpha(ri, Alpha); break; } @@ -1802,7 +1836,7 @@ namespace Aggplus typedef agg::span_image_filter_rgba_bilinear span_gen_type; typedef agg::renderer_scanline_aa renderer_type; span_gen_type sg(img_src, interpolator); - renderer_type ri(GetRendererBase(), span_allocator, sg); + renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg); render_scanlines_alpha(ri, Alpha); break; } @@ -1813,7 +1847,7 @@ namespace Aggplus agg::image_filter_lut filter; filter.calculate(agg::image_filter_bicubic(), false); span_gen_type sg(img_src, interpolator, filter); - renderer_type ri(GetRendererBase(), span_allocator, sg); + renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg); render_scanlines_alpha(ri, Alpha); break; } @@ -1824,7 +1858,7 @@ namespace Aggplus agg::image_filter_lut filter; filter.calculate(agg::image_filter_spline16(), false); span_gen_type sg(img_src, interpolator, filter); - renderer_type ri(GetRendererBase(), span_allocator, sg); + renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg); render_scanlines_alpha(ri, Alpha); break; } @@ -1835,7 +1869,7 @@ namespace Aggplus agg::image_filter_lut filter; filter.calculate(agg::image_filter_blackman256(), false); span_gen_type sg(img_src, interpolator, filter); - renderer_type ri(GetRendererBase(), span_allocator, sg); + renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg); render_scanlines_alpha(ri, Alpha); break; } @@ -1846,7 +1880,7 @@ namespace Aggplus agg::image_filter_lut filter; filter.calculate(agg::image_filter_bilinear(), false); span_gen_type sg(img_src, interpolator, filter); - renderer_type ri(GetRendererBase(), span_allocator, sg); + renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg); render_scanlines_alpha(ri, Alpha); break; } @@ -1888,7 +1922,7 @@ namespace Aggplus pixfmt img_pixf(PatRendBuff); img_source_type img_src(img_pixf); span_gen_type sg(img_src, interpolator); - renderer_type ri(GetRendererBase(), span_allocator, sg); + renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg); double dAlpha = m_dGlobalAlpha * Alpha / 255.0; if (fabs(dAlpha - 1.0) < FLT_EPSILON) @@ -1914,7 +1948,7 @@ namespace Aggplus pixfmt img_pixf(PatRendBuff); img_source_type img_src(img_pixf); span_gen_type sg(img_src, interpolator); - renderer_type ri(GetRendererBase(), span_allocator, sg); + renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg); double dAlpha = m_dGlobalAlpha * Alpha / 255.0; if (fabs(dAlpha - 1.0) < FLT_EPSILON) @@ -1940,7 +1974,7 @@ namespace Aggplus pixfmt img_pixf(PatRendBuff); img_source_type img_src(img_pixf); span_gen_type sg(img_src, interpolator); - renderer_type ri(GetRendererBase(), span_allocator, sg); + renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg); double dAlpha = m_dGlobalAlpha * Alpha / 255.0; if (fabs(dAlpha - 1.0) < FLT_EPSILON) @@ -1966,7 +2000,7 @@ namespace Aggplus pixfmt img_pixf(PatRendBuff); img_source_type img_src(img_pixf); span_gen_type sg(img_src, interpolator); - renderer_type ri(GetRendererBase(), span_allocator, sg); + renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg); double dAlpha = m_dGlobalAlpha * Alpha / 255.0; if (fabs(dAlpha - 1.0) < FLT_EPSILON) @@ -2063,6 +2097,186 @@ namespace Aggplus break; } } + template + agg::trans_affine* CGraphics::DoStrokePath(NSStructures::CPen* pPen, CGraphicsPath* pPath, Rasterizer* pRasterizer) + { + agg::line_join_e LineJoin = agg::round_join; + switch(pPen->LineJoin) + { + case LineJoinMiter : LineJoin = agg::miter_join_revert; break; + case LineJoinBevel : LineJoin = agg::bevel_join; break; + case LineJoinRound : LineJoin = agg::round_join; break; + case LineJoinMiterClipped : LineJoin = agg::miter_join_revert; break; + default: break; + } + agg::line_cap_e LineCap = agg::round_cap; + switch(pPen->LineStartCap) + { + case LineCapFlat : LineCap = agg::butt_cap; break; + case LineCapRound : LineCap = agg::round_cap; break; + case LineCapSquare : LineCap = agg::square_cap; break; + default: break; + } + + double dWidth = pPen->Size; + if (!m_bIntegerGrid && m_bIs0PenWidthAs1px) + { + double dWidthMinSize, dSqrtDet = sqrt(abs(m_oFullTransform.m_internal->m_agg_mtx.determinant())); + if (0 == dWidth) + { + double dX = 0.72, dY = 0.72; + agg::trans_affine invert = ~m_oFullTransform.m_internal->m_agg_mtx; + invert.transform_2x2(&dX, &dY); + dWidth = std::min(abs(dX), abs(dY)); + } + else if (0 != dSqrtDet && dWidth < (dWidthMinSize = 1.0 / dSqrtDet)) + dWidth = dWidthMinSize; + } + + double dblMiterLimit = pPen->MiterLimit; + + agg::path_storage path_copy(pPath->m_internal->m_agg_ps); + bool bIsUseIdentity = m_bIntegerGrid; + if (!bIsUseIdentity) + { + agg::trans_affine* full_trans = &m_oFullTransform.m_internal->m_agg_mtx; + double dDet = full_trans->determinant(); + + if (fabs(dDet) < 0.0001) + { + path_copy.transform_all_paths(m_oFullTransform.m_internal->m_agg_mtx); + dWidth *= sqrt(fabs(dDet)); + + bIsUseIdentity = true; + } + } + + typedef agg::conv_curve conv_crv_type; + + conv_crv_type c_c_path(path_copy); + c_c_path.approximation_scale(25.0); + c_c_path.approximation_method(agg::curve_inc); + DashStyle eStyle = (DashStyle)pPen->DashStyle; + + if (DashStyleCustom == eStyle) + { + if (0 == pPen->Count || NULL == pPen->DashPattern) + { + eStyle = DashStyleSolid; + } + else + { + bool bFoundNormal = false; + for (int i = 0; i < pPen->Count; i++) + { + if (fabs(pPen->DashPattern[i]) > 0.0001) + { + bFoundNormal = true; + break; + } + } + if (!bFoundNormal) + eStyle = DashStyleSolid; + } + } + + agg::trans_affine* pAffine = &m_oFullTransform.m_internal->m_agg_mtx; + if (bIsUseIdentity) + pAffine = new agg::trans_affine(); + + if (DashStyleSolid == eStyle) + { + typedef agg::conv_stroke Path_Conv_StrokeN; + Path_Conv_StrokeN pgN(c_c_path); + + //pgN.line_join(agg::miter_join_revert); + + pgN.line_cap(LineCap); + + pgN.line_join(LineJoin); + pgN.inner_join(agg::inner_round); + + pgN.miter_limit(dblMiterLimit); + pgN.width(dWidth); + + pgN.approximation_scale(25.0); + + typedef agg::conv_transform transStroke; + + transStroke trans(pgN, *pAffine); + pRasterizer->add_path(trans); + } + else + { + typedef agg::conv_dash Path_Conv_Dash; + Path_Conv_Dash poly2_dash(c_c_path); + + typedef agg::conv_stroke Path_Conv_StrokeD; + Path_Conv_StrokeD pgD(poly2_dash); + + switch (eStyle) + { + case DashStyleDash: + poly2_dash.add_dash(3.00*dWidth, dWidth); + break; + case DashStyleDot: + poly2_dash.add_dash(dWidth, dWidth); + break; + case DashStyleDashDot: + poly2_dash.add_dash(3.00*dWidth, dWidth); + poly2_dash.add_dash(dWidth, dWidth); + break; + case DashStyleDashDotDot: + poly2_dash.add_dash(3.00*dWidth, dWidth); + poly2_dash.add_dash(dWidth, dWidth); + poly2_dash.add_dash(dWidth, dWidth); + break; + default: + case DashStyleCustom: + { + double offset = pPen->DashOffset; + double* params = pPen->DashPattern; + LONG lCount = pPen->Count; + LONG lCount2 = lCount / 2; + + double dKoef = 1.0; + + for (LONG i = 0; i < lCount2; ++i) + { + if (0 == i) + { + poly2_dash.add_dash((params[i * 2]) * dKoef, params[i * 2 + 1] * dKoef); + } + else + { + poly2_dash.add_dash(params[i * 2] * dKoef, params[i * 2 + 1] * dKoef); + } + } + if (1 == (lCount % 2)) + { + poly2_dash.add_dash(params[lCount - 1] * dKoef, 0); + } + poly2_dash.dash_start(offset * dKoef); + + break; + } + } + + double dWidthMinSize = 1.0 / sqrt(abs(m_oCoordTransform.m_internal->m_agg_mtx.determinant())); + if ((0 == dWidth && !m_bIntegerGrid) || dWidth < dWidthMinSize) + dWidth = dWidthMinSize; + + pgD.line_cap(LineCap); + pgD.line_join(LineJoin); + pgD.miter_limit(dblMiterLimit); + pgD.width(dWidth); + + agg::conv_transform trans(pgD, *pAffine); + pRasterizer->add_path(trans); + } + + return bIsUseIdentity ? pAffine : NULL; + } // text methods int CGraphics::FillGlyph2(int nX, int nY, TGlyph* pGlyph, Aggplus::CBrush* pBrush) { @@ -2107,11 +2321,11 @@ namespace Aggplus ((CBrushSolid*)pBrush)->GetColor(&clr); typedef agg::renderer_scanline_aa_solid solid_renderer_type; - solid_renderer_type ren_fine(GetRendererBase()); + solid_renderer_type ren_fine(m_frame_buffer.ren_base()); ren_fine.color(clr.GetAggColor()); //agg::render_scanlines(storage, m_rasterizer.get_scanline(), ren_fine); - render_scanlines(storage, ren_fine); + render_scanlines_2(storage, ren_fine); } return 0; @@ -2122,7 +2336,7 @@ namespace Aggplus ((CBrushSolid*)pBrush)->GetColor(&clr); typedef agg::renderer_scanline_aa_solid solid_renderer_type; - solid_renderer_type ren_fine(GetRendererBase()); + solid_renderer_type ren_fine(m_frame_buffer.ren_base()); ren_fine.color(clr.GetAggColor()); if (m_nTextRenderMode == FT_RENDER_MODE_LCD) @@ -2255,7 +2469,7 @@ namespace Aggplus gradient_span_alloc span_alloc; typedef agg::renderer_scanline_aa renderer_gradient_type; - renderer_gradient_type ren_gradient( GetRendererBase(), span_alloc, span_gen ); + renderer_gradient_type ren_gradient( m_frame_buffer.ren_base(), span_alloc, span_gen ); if (fabs(m_dGlobalAlpha - 1.0) < FLT_EPSILON) { diff --git a/DesktopEditor/graphics/Graphics.h b/DesktopEditor/graphics/Graphics.h index 8895dbfa2ac..5bb709688d7 100644 --- a/DesktopEditor/graphics/Graphics.h +++ b/DesktopEditor/graphics/Graphics.h @@ -64,13 +64,15 @@ #include "Color.h" #include "Matrix.h" +#include "GraphicsLayerBlend.h" #include "GraphicsPath.h" -#include "AlphaMask.h" +#include "AlphaMask_p.h" #include "Clip.h" #include "Brush.h" #include "Image.h" #include "../fontengine/FontManager.h" +#include #include #if defined(_WIN32) || defined (_WIN64) @@ -280,6 +282,9 @@ class CGraphics CClipMulti m_oClip; CAlphaMask* m_pAlphaMask; + CSoftMask* m_pSoftMask; + + std::stack m_arLayers; agg::svg::frame_buffer_rgba m_frame_buffer; agg::svg::rasterizer m_rasterizer; @@ -355,8 +360,8 @@ class CGraphics Status SetClip(CGraphicsPath* pPath); Status ResetClip(); Status ExclugeClip(CGraphicsPath* pPath); - Status CombineClip(CGraphicsPath* pPath, agg::sbool_op_e op); - Status InternalClip(CGraphicsPath* pPath, CMatrix* pTransform, agg::sbool_op_e op); + Status CombineClip(CGraphicsPath* pPath, agg::sbool_op_e op, NSStructures::CPen* pPen = NULL); + Status InternalClip(CGraphicsPath* pPath, CMatrix* pTransform, agg::sbool_op_e op, NSStructures::CPen* pPen = NULL); // измерение текста INT MeasureString(const std::wstring& strText, CFontManager* pManager, double* lWidth, double* lHeight); @@ -398,9 +403,21 @@ class CGraphics //Работа с альфа-маской Status SetAlphaMask(CAlphaMask* pAlphaMask); - Status CreateAlphaMask(); + Status StartCreatingAlphaMask(); + Status EndCreatingAlphaMask(); Status ResetAlphaMask(); - Status StartApplyingAlphaMask(); + + CSoftMask* CreateSoftMask(bool bAlpha); + Status SetSoftMask(CSoftMask* pSoftMask); + + //Работа со слоями + Status AddLayer(CGraphicsLayer* pGraphicsLayer); + Status CreateLayer(); + Status BlendLayer(); + Status RemoveLayer(); + + Status SetLayerSettings(const TGraphicsLayerSettings& oSettings); + Status SetLayerOpacity(double dOpacity); void CalculateFullTransform(); bool IsClip(); @@ -416,12 +433,11 @@ class CGraphics template void render_scanlines(Renderer& ren); template - void render_scanlines(Rasterizer& ras, Renderer& ren); + void render_scanlines_2(Rasterizer& ras, Renderer& ren); template void render_scanlines_alpha(Renderer& ren, BYTE Alpha); - - agg::rendering_buffer& GetRenderingBuffer(); - base_renderer_type& GetRendererBase(); + template + void render_scanlines_3(Rasterizer& ras, Renderer& ren, Scanline& sl); void DoFillPathSolid(CColor dwColor); void DoFillPathGradient(CBrushLinearGradient *pBrush); @@ -437,6 +453,8 @@ class CGraphics void DoFillPathTextureClampSz3(const CMatrix &mImgMtx, const void *pImgBuff, DWORD dwImgWidth, DWORD dwImgHeight, int nImgStride, Aggplus::WrapMode wrapmode, BYTE Alpha = 255); void DoFillPath(const CBrush* Brush); + template + agg::trans_affine* DoStrokePath(NSStructures::CPen* pPen, CGraphicsPath* pPath, Rasterizer* ras); // text methods int FillGlyph2(int nX, int nY, TGlyph* pGlyph, Aggplus::CBrush* pBrush); diff --git a/DesktopEditor/graphics/GraphicsLayer.cpp b/DesktopEditor/graphics/GraphicsLayer.cpp new file mode 100644 index 00000000000..16dd456ccf3 --- /dev/null +++ b/DesktopEditor/graphics/GraphicsLayer.cpp @@ -0,0 +1,65 @@ +#include "GraphicsLayer.h" +#include + +namespace Aggplus +{ + CGraphicsLayer::CGraphicsLayer(BYTE *pBuffer, bool bExternalBuffer) + : m_pBuffer(pBuffer), m_bExternalBuffer(NULL != pBuffer && bExternalBuffer) + { + SetDefaultSettings(); + } + + CGraphicsLayer::~CGraphicsLayer() + { + ClearBuffer(); + } + + bool CGraphicsLayer::Empty() const + { + return NULL == m_pBuffer; + } + + BYTE *CGraphicsLayer::GetBuffer() + { + return m_pBuffer; + } + + void CGraphicsLayer::SetDefaultSettings() + { + m_oSettings.m_uchOpacity = 255; + } + + void CGraphicsLayer::ClearBuffer(bool bDeleteData) + { + if (bDeleteData && !m_bExternalBuffer) + RELEASEARRAYOBJECTS(m_pBuffer); + + m_pBuffer = NULL; + } + + void CGraphicsLayer::SetSettings(const TGraphicsLayerSettings &oSettings) + { + m_oSettings = oSettings; + } + + const TGraphicsLayerSettings &CGraphicsLayer::GetSettings() const + { + return m_oSettings; + } + + void CGraphicsLayer::SetOpacity(double dOpacity) + { + if (dOpacity > 1. || dOpacity < 0.) + m_oSettings.m_uchOpacity = 255; + else + { + m_oSettings.m_uchOpacity = ceil(255 * dOpacity); + } + } + + void CGraphicsLayer::SetOpacity(BYTE uchOpacity) + { + m_oSettings.m_uchOpacity = uchOpacity; + } +} + diff --git a/DesktopEditor/graphics/GraphicsLayer.h b/DesktopEditor/graphics/GraphicsLayer.h new file mode 100644 index 00000000000..8b4914291e3 --- /dev/null +++ b/DesktopEditor/graphics/GraphicsLayer.h @@ -0,0 +1,44 @@ +#ifndef CGRAPHICSLAYER_H +#define CGRAPHICSLAYER_H + +#include "Defines.h" +#include "./config.h" +#include "../common/IGrObject.h" + +#include + +namespace Aggplus +{ + struct TGraphicsLayerSettings + { + BYTE m_uchOpacity; + }; + + class GRAPHICS_DECL CGraphicsLayer : public IGrObject + { + public: + CGraphicsLayer(BYTE* pBuffer, bool bExternalBuffer = true); + ~CGraphicsLayer(); + + bool Empty() const; + BYTE* GetBuffer(); + + void SetDefaultSettings(); + void ClearBuffer(bool bDeleteData = true); + + void SetSettings(const TGraphicsLayerSettings& oSettings); + const TGraphicsLayerSettings& GetSettings() const; + + void SetOpacity(double dOpacity); + void SetOpacity(BYTE uchOpacity); + + private: + BYTE* m_pBuffer; + bool m_bExternalBuffer; + + TGraphicsLayerSettings m_oSettings; + }; + +} + +#endif // CGRAPHICSLAYER_H diff --git a/DesktopEditor/graphics/GraphicsLayerBlend.h b/DesktopEditor/graphics/GraphicsLayerBlend.h new file mode 100644 index 00000000000..65a8dfdea22 --- /dev/null +++ b/DesktopEditor/graphics/GraphicsLayerBlend.h @@ -0,0 +1,140 @@ +#ifndef CGRAPHICSLAYER_BLEND_H +#define CGRAPHICSLAYER_BLEND_H + +#include "GraphicsLayer.h" + +namespace Aggplus +{ + template + void BlendTo(CGraphicsLayer* pLayer, SrcPixelFormatRenderer& oSrc) + { + if (NULL == pLayer->GetBuffer() || 0 == oSrc.width() || 0 == oSrc.height()) + return; + + typedef typename SrcPixelFormatRenderer::order_type order_type; + typedef typename SrcPixelFormatRenderer::value_type value_type; + + int nStep = 4; + BYTE* pSrcBuffer = pLayer->GetBuffer(); + value_type* pDstBuffer = NULL; + BYTE uchAlpha; + + unsigned int unSrcW = oSrc.width(); + unsigned int unSrcH = oSrc.height(); + + BYTE nOpacity = pLayer->GetSettings().m_uchOpacity; + bool bFlip = oSrc.stride() < 0; + + for (unsigned int unY = 0; unY < unSrcH; ++unY) + { + pDstBuffer = oSrc.row_ptr(bFlip ? unSrcH - 1 - unY : unY); + for (unsigned int unX = 0; unX < unSrcW; ++unX) + { + uchAlpha = (SrcPixelFormatRenderer::base_mask + nOpacity * pSrcBuffer[order_type::A]) >> 8; + if (uchAlpha) + { + if(uchAlpha == SrcPixelFormatRenderer::base_mask) + { + pDstBuffer[order_type::R] = pSrcBuffer[order_type::R]; + pDstBuffer[order_type::G] = pSrcBuffer[order_type::G]; + pDstBuffer[order_type::B] = pSrcBuffer[order_type::B]; + pDstBuffer[order_type::A] = SrcPixelFormatRenderer::base_mask; + } + else + { + SrcPixelFormatRenderer::blender_type::blend_pix(pDstBuffer, pSrcBuffer[order_type::R], pSrcBuffer[order_type::G], pSrcBuffer[order_type::B], uchAlpha); + } + } + + pSrcBuffer += nStep; + pDstBuffer += nStep; + } + } + } + + template + void BlendTo(CGraphicsLayer* pLayer, SrcPixelFormatRenderer& oSrc, int nBlendMode) + { + if (NULL == pLayer->GetBuffer() || 0 == oSrc.width() || 0 == oSrc.height()) + return; + + typedef typename SrcPixelFormatRenderer::order_type order_type; + typedef typename SrcPixelFormatRenderer::value_type value_type; + + int nStep = 4; + BYTE* pSrcBuffer = pLayer->GetBuffer(); + value_type* pDstBuffer = NULL; + BYTE uchAlpha; + + unsigned int unSrcW = oSrc.width(); + unsigned int unSrcH = oSrc.height(); + + BYTE nOpacity = pLayer->GetSettings().m_uchOpacity; + bool bFlip = oSrc.stride() < 0; + + for (unsigned int unY = 0; unY < unSrcH; ++unY) + { + pDstBuffer = oSrc.row_ptr(bFlip ? unSrcH - 1 - unY : unY); + for (unsigned int unX = 0; unX < unSrcW; ++unX) + { + uchAlpha = (SrcPixelFormatRenderer::base_mask + nOpacity * pSrcBuffer[order_type::A]) >> 8; + if (uchAlpha) + { + SrcPixelFormatRenderer::blender_type::blend_pix(nBlendMode, pDstBuffer, pSrcBuffer[order_type::R], pSrcBuffer[order_type::G], pSrcBuffer[order_type::B], uchAlpha, 255); + } + + pSrcBuffer += nStep; + pDstBuffer += nStep; + } + } + } + + template + void BlendTo(CGraphicsLayer* pLayer, SrcPixelFormatRenderer& oSrc, BYTE* pAlphaMaskBuffer, UINT unAlphaMaskStep) + { + if (NULL == pLayer->GetBuffer() || 0 == oSrc.width() || 0 == oSrc.height()) + return; + + typedef typename SrcPixelFormatRenderer::order_type order_type; + typedef typename SrcPixelFormatRenderer::value_type value_type; + + int nStep = 4; + BYTE* pSrcBuffer = pLayer->GetBuffer(); + value_type* pDstBuffer = NULL; + BYTE* pSrcAlphaMaskBuffer = pAlphaMaskBuffer; + BYTE uchAlpha; + + unsigned int unSrcW = oSrc.width(); + unsigned int unSrcH = oSrc.height(); + + BYTE nOpacity = pLayer->GetSettings().m_uchOpacity; + bool bFlip = oSrc.stride() < 0; + + for (unsigned int unY = 0; unY < unSrcH; ++unY) + { + pDstBuffer = oSrc.row_ptr(bFlip ? unSrcH - 1 - unY : unY); + for (unsigned int unX = 0; unX < unSrcW; ++unX) + { + uchAlpha = ((SrcPixelFormatRenderer::base_mask + nOpacity * pSrcBuffer[order_type::A] * AlphaMaskFunction::calculate(pSrcAlphaMaskBuffer)) >> 16); + + if(uchAlpha == SrcPixelFormatRenderer::base_mask) + { + pDstBuffer[order_type::R] = pSrcBuffer[order_type::R]; + pDstBuffer[order_type::G] = pSrcBuffer[order_type::G]; + pDstBuffer[order_type::B] = pSrcBuffer[order_type::B]; + pDstBuffer[order_type::A] = SrcPixelFormatRenderer::base_mask; + } + else + { + SrcPixelFormatRenderer::blender_type::blend_pix(pDstBuffer, pSrcBuffer[order_type::R], pSrcBuffer[order_type::G], pSrcBuffer[order_type::B], uchAlpha); + } + + pSrcBuffer += nStep; + pDstBuffer += nStep; + pSrcAlphaMaskBuffer += unAlphaMaskStep; + } + } + } +} + +#endif // CGRAPHICSLAYER_BLEND_H diff --git a/DesktopEditor/graphics/GraphicsPath.cpp b/DesktopEditor/graphics/GraphicsPath.cpp index 87e8932d18d..ec259ff4525 100644 --- a/DesktopEditor/graphics/GraphicsPath.cpp +++ b/DesktopEditor/graphics/GraphicsPath.cpp @@ -30,6 +30,7 @@ * */ #include "GraphicsPath_private.h" +#include "agg_bounding_rect.h" #include namespace Aggplus @@ -37,56 +38,96 @@ namespace Aggplus // GraphicsPath CGraphicsPath::CGraphicsPath() : ISimpleGraphicsPath() { - m_internal = new CGraphicsPath_private(); + m_internal = new CGraphicsPath_private(); + } + + CGraphicsPath::CGraphicsPath(const CGraphicsPath& other) noexcept + { + *this = other; + } + + CGraphicsPath::CGraphicsPath(CGraphicsPath&& other) noexcept + { + *this = other; + } + + CGraphicsPath::CGraphicsPath(const std::vector& paths) noexcept : CGraphicsPath() + { + if (paths.size() == 1) + *this = paths[0]; + else + { + StartFigure(); + for (const auto& p : paths) + { + unsigned length = p.GetPointCount(); + std::vector points = p.GetPoints(0, length); + for (unsigned j = 0; j < length; j++) + { + if (p.IsMovePoint(j)) + MoveTo(points[j].X, points[j].Y); + else if (p.IsLinePoint(j)) + LineTo(points[j].X, points[j].Y); + else if (p.IsCurvePoint(j)) + { + CurveTo(points[j].X, points[j].Y, + points[j + 1].X, points[j + 1].Y, + points[j + 2].X, points[j + 2].Y); + j += 2; + } + } + if (p.Is_poly_closed()) CloseFigure(); + } + } } CGraphicsPath::~CGraphicsPath() { - RELEASEOBJECT(m_internal); + RELEASEOBJECT(m_internal); } CGraphicsPath* CGraphicsPath::Clone() { CGraphicsPath* pNew = new CGraphicsPath(); - pNew->m_internal->m_agg_ps = m_internal->m_agg_ps; - pNew->m_internal->m_bEvenOdd = m_internal->m_bEvenOdd; - pNew->m_internal->m_bIsMoveTo = m_internal->m_bIsMoveTo; + pNew->m_internal->m_agg_ps = m_internal->m_agg_ps; + pNew->m_internal->m_bEvenOdd = m_internal->m_bEvenOdd; + pNew->m_internal->m_bIsMoveTo = m_internal->m_bIsMoveTo; return pNew; } Status CGraphicsPath::Reset() { - m_internal->m_agg_ps.remove_all(); - m_internal->m_bIsMoveTo = false; + m_internal->m_agg_ps.remove_all(); + m_internal->m_bIsMoveTo = false; return Ok; } void CGraphicsPath::SetRuler(bool bEvenOdd) { - m_internal->m_bEvenOdd = bEvenOdd; + m_internal->m_bEvenOdd = bEvenOdd; } - Status CGraphicsPath::StartFigure() - { - m_internal->m_agg_ps.start_new_path(); - return Ok; + Status CGraphicsPath::StartFigure() + { + m_internal->m_agg_ps.start_new_path(); + return Ok; } - Status CGraphicsPath::CloseFigure() - { - m_internal->m_agg_ps.close_polygon(); - return Ok; + Status CGraphicsPath::CloseFigure() + { + m_internal->m_agg_ps.close_polygon(); + return Ok; } - bool CGraphicsPath::Is_poly_closed() + bool CGraphicsPath::Is_poly_closed() const { - if (!m_internal->m_agg_ps.total_vertices()) + if (!m_internal->m_agg_ps.total_vertices()) return true; double x, y; - unsigned int nTip = m_internal->m_agg_ps.last_vertex(&x, &y); - - if (nTip & agg::path_flags_close) + unsigned int nTip = m_internal->m_agg_ps.last_vertex(&x, &y); + + if (nTip & agg::path_flags_close) return true; return false; @@ -94,33 +135,33 @@ namespace Aggplus Status CGraphicsPath::MoveTo(double x, double y) { - m_internal->m_bIsMoveTo = true; - m_internal->m_agg_ps.move_to(x, y); + m_internal->m_bIsMoveTo = true; + m_internal->m_agg_ps.move_to(x, y); return Ok; } Status CGraphicsPath::LineTo(double x, double y) { - m_internal->m_agg_ps.line_to(x, y); + m_internal->m_agg_ps.line_to(x, y); return Ok; } Status CGraphicsPath::CurveTo(double x1, double y1, double x2, double y2, double x3, double y3) { - m_internal->m_agg_ps.curve4(x1, y1, x2, y2, x3, y3); + m_internal->m_agg_ps.curve4(x1, y1, x2, y2, x3, y3); return Ok; } Status CGraphicsPath::AddLine(double x1, double y1, double x2, double y2) { - if (Is_poly_closed()) + if (Is_poly_closed()) { - m_internal->m_agg_ps.move_to(x1, y1); + m_internal->m_agg_ps.move_to(x1, y1); } else { - m_internal->m_agg_ps.line_to(x1, y1); + m_internal->m_agg_ps.line_to(x1, y1); } - m_internal->m_agg_ps.line_to(x2, y2); + m_internal->m_agg_ps.line_to(x2, y2); return Ok; } @@ -132,7 +173,7 @@ namespace Aggplus } int nRet = 0; - if (!m_internal->m_bIsMoveTo) + if (!m_internal->m_bIsMoveTo) { MoveTo(pPoints[0], pPoints[1]); } @@ -151,19 +192,19 @@ namespace Aggplus for (int i = 1; i <= n; ++i) { const double* points = &pPoints[i * 2]; - m_internal->m_agg_ps.line_to(points[0], points[1]); + m_internal->m_agg_ps.line_to(points[0], points[1]); } return Ok; } Status CGraphicsPath::AddBezier(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4) { - if (Is_poly_closed()) - m_internal->m_agg_ps.move_to(x1, y1); - else - m_internal->m_agg_ps.line_to(x1, y1); + if (Is_poly_closed()) + m_internal->m_agg_ps.move_to(x1, y1); + else + m_internal->m_agg_ps.line_to(x1, y1); - m_internal->m_agg_ps.curve4(x2, y2, x3, y3, x4, y4); + m_internal->m_agg_ps.curve4(x2, y2, x3, y3, x4, y4); return Ok; } Status CGraphicsPath::AddBeziers(double* pPoints, int nCount) @@ -171,7 +212,7 @@ namespace Aggplus if (8 > nCount) return InvalidParameter; - if (!m_internal->m_bIsMoveTo) + if (!m_internal->m_bIsMoveTo) { MoveTo(pPoints[0], pPoints[1]); } @@ -183,13 +224,13 @@ namespace Aggplus curve.approximation_scale(25.0); curve.init(points[0], points[1], points[2], points[3], points[4], points[5], points[6], points[7]); - if (Is_poly_closed()) + if (Is_poly_closed()) { - m_internal->m_agg_ps.concat_path(curve, 0); + m_internal->m_agg_ps.concat_path(curve, 0); } else { - m_internal->m_agg_ps.join_path(curve, 0); + m_internal->m_agg_ps.join_path(curve, 0); } int nCountTo = (nCount - 8) / 6; @@ -212,16 +253,16 @@ namespace Aggplus { agg::bezier_arc arc(x+width/2.0, y+height/2.0, width/2.0, height/2.0, 0.0, agg::pi2); //2.3 m_agg_ps.add_path(arc, 0, true); - m_internal->m_agg_ps.join_path(arc, 0); + m_internal->m_agg_ps.join_path(arc, 0); return Ok; } Status CGraphicsPath::AddRectangle(double x, double y, double width, double height) { - m_internal->m_agg_ps.move_to(x, y); - m_internal->m_agg_ps.line_to(x + width, y); - m_internal->m_agg_ps.line_to(x + width, y + height); - m_internal->m_agg_ps.line_to(x, y + height); - m_internal->m_agg_ps.close_polygon(); + m_internal->m_agg_ps.move_to(x, y); + m_internal->m_agg_ps.line_to(x + width, y); + m_internal->m_agg_ps.line_to(x + width, y + height); + m_internal->m_agg_ps.line_to(x, y + height); + m_internal->m_agg_ps.close_polygon(); return Ok; } Status CGraphicsPath::AddPolygon(double* pPoints, int nCount) @@ -232,13 +273,13 @@ namespace Aggplus } int nRet = 0; - if (Is_poly_closed()) + if (Is_poly_closed()) { - m_internal->m_agg_ps.move_to(pPoints[0], pPoints[1]); + m_internal->m_agg_ps.move_to(pPoints[0], pPoints[1]); } else { - m_internal->m_agg_ps.line_to(pPoints[0], pPoints[1]); + m_internal->m_agg_ps.line_to(pPoints[0], pPoints[1]); } int n = (nCount / 2) - 1; @@ -246,20 +287,20 @@ namespace Aggplus for (int i = 1; i < n; ++i) { double* points = &pPoints[i * 2]; - m_internal->m_agg_ps.line_to(points[0], points[1]); + m_internal->m_agg_ps.line_to(points[0], points[1]); } - m_internal->m_agg_ps.close_polygon(); + m_internal->m_agg_ps.close_polygon(); return Ok; } Status CGraphicsPath::AddPath(const CGraphicsPath& oPath) { typedef agg::conv_curve conv_crv_type; - agg::path_storage p_copy(oPath.m_internal->m_agg_ps); + agg::path_storage p_copy(oPath.m_internal->m_agg_ps); conv_crv_type p3(p_copy); - m_internal->m_agg_ps.join_path(p3, 0); + m_internal->m_agg_ps.join_path(p3, 0); return Ok; } Status CGraphicsPath::AddArc(double x, double y, double width, double height, double startAngle, double sweepAngle) @@ -275,11 +316,11 @@ namespace Aggplus if (Is_poly_closed()) { - m_internal->m_agg_ps.concat_path(arc, 0); + m_internal->m_agg_ps.concat_path(arc, 0); } else { - m_internal->m_agg_ps.join_path(arc, 0); + m_internal->m_agg_ps.join_path(arc, 0); } return Ok; @@ -288,13 +329,13 @@ namespace Aggplus ULONG CGraphicsPath::GetPointCount() const { ULONG nPointCount=0; - ULONG nTotal = m_internal->m_agg_ps.total_vertices(); + ULONG nTotal = m_internal->m_agg_ps.total_vertices(); double x, y; for(ULONG i = 0; i < nTotal; ++i) { - ULONG nTip = m_internal->m_agg_ps.vertex(i, &x, &y); + ULONG nTip = m_internal->m_agg_ps.vertex(i, &x, &y); if(nTip) { if (!(nTip & agg::path_flags_close)) @@ -308,13 +349,13 @@ namespace Aggplus Status CGraphicsPath::GetPathPoints(PointF* points, int count) const { - int nTotal = m_internal->m_agg_ps.total_vertices(); + int nTotal = m_internal->m_agg_ps.total_vertices(); double x, y; int i = 0, k = 0; while (k < count && i < nTotal) { - unsigned int nTip = m_internal->m_agg_ps.vertex(i, &x, &y); + unsigned int nTip = m_internal->m_agg_ps.vertex(i, &x, &y); if (nTip) { if(!(nTip & agg::path_flags_close)) @@ -332,19 +373,19 @@ namespace Aggplus Status CGraphicsPath::GetLastPoint(double& x, double& y) { - m_internal->m_agg_ps.last_vertex(&x, &y); + m_internal->m_agg_ps.last_vertex(&x, &y); return Ok; } Status CGraphicsPath::GetPathPoints(double* points, int count) const { - int nTotal = m_internal->m_agg_ps.total_vertices(); + int nTotal = m_internal->m_agg_ps.total_vertices(); double x, y; int i = 0, k = 0; while (k < count && i < nTotal) { - unsigned int nTip = m_internal->m_agg_ps.vertex(i, &x, &y); + unsigned int nTip = m_internal->m_agg_ps.vertex(i, &x, &y); if (nTip) { if(!(nTip & agg::path_flags_close)) @@ -360,16 +401,16 @@ namespace Aggplus return Ok; } - void CGraphicsPath::GetBounds(double& left, double& top, double& width, double& height) + void CGraphicsPath::GetBounds(double& left, double& top, double& width, double& height) const { - unsigned int nTotal = m_internal->m_agg_ps.total_vertices(); + unsigned int nTotal = m_internal->m_agg_ps.total_vertices(); if (nTotal) { agg::rect_d bounds(1e100, 1e100, -1e100, -1e100); double x, y; for(unsigned int i = 0; i < nTotal; i++) { - unsigned int nTip = m_internal->m_agg_ps.vertex(i, &x, &y); + unsigned int nTip = m_internal->m_agg_ps.vertex(i, &x, &y); if(agg::is_vertex(nTip)) { if(x < bounds.x1) bounds.x1 = x; @@ -393,42 +434,57 @@ namespace Aggplus } } + void CGraphicsPath::GetBoundsAccurate(double& left, double& top, double& width, double& height) const + { + agg::conv_curve storage(m_internal->m_agg_ps); + storage.approximation_scale(25.0); + storage.approximation_method(agg::curve_inc); + + double r = 0, b = 0; + agg::bounding_rect_single(storage, 0, + &left, &top, + &r, &b); + + width = r - left; + height = b - top; + } + Status CGraphicsPath::Transform(const CMatrix* matrix) { if (NULL != matrix) { - agg::path_storage p2(m_internal->m_agg_ps); - agg::conv_transform trans(p2, matrix->m_internal->m_agg_mtx); - m_internal->m_agg_ps.remove_all(); + agg::path_storage p2(m_internal->m_agg_ps); + agg::conv_transform trans(p2, matrix->m_internal->m_agg_mtx); + m_internal->m_agg_ps.remove_all(); //2.3 m_agg_ps.add_path(trans, 0, false); - m_internal->m_agg_ps.concat_path(trans, 0); + m_internal->m_agg_ps.concat_path(trans, 0); } return Ok; } bool CGraphicsPath::_MoveTo(double x, double y) { - if (NULL != m_internal->m_pTransform) + if (NULL != m_internal->m_pTransform) { - m_internal->m_pTransform->TransformPoint(x, y); + m_internal->m_pTransform->TransformPoint(x, y); } return (Ok == MoveTo(x, y)); } bool CGraphicsPath::_LineTo(double x, double y) { - if (NULL != m_internal->m_pTransform) + if (NULL != m_internal->m_pTransform) { - m_internal->m_pTransform->TransformPoint(x, y); + m_internal->m_pTransform->TransformPoint(x, y); } return (Ok == LineTo(x, y)); } bool CGraphicsPath::_CurveTo(double x1, double y1, double x2, double y2, double x3, double y3) { - if (NULL != m_internal->m_pTransform) + if (NULL != m_internal->m_pTransform) { - m_internal->m_pTransform->TransformPoint(x1, y1); - m_internal->m_pTransform->TransformPoint(x2, y2); - m_internal->m_pTransform->TransformPoint(x3, y3); + m_internal->m_pTransform->TransformPoint(x1, y1); + m_internal->m_pTransform->TransformPoint(x2, y2); + m_internal->m_pTransform->TransformPoint(x3, y3); } return (Ok == CurveTo(x1, y1, x2, y2, x3, y3)); } @@ -437,26 +493,26 @@ namespace Aggplus return (Ok == CloseFigure()); } - Status CGraphicsPath::AddString(const std::wstring& strText, NSFonts::IFontManager* pFont, double x, double y) + Status CGraphicsPath::AddString(const std::wstring& strText, NSFonts::IFontManager* pFont, double x, double y) { if (NULL == pFont) return InvalidParameter; - + pFont->SetTextMatrix(1, 0, 0, 1, 0, 0); pFont->LoadString1(strText, (float)x, (float)y); return (TRUE == pFont->GetStringPath(this)) ? Ok : InvalidParameter; } - Status CGraphicsPath::AddString(const unsigned int* pGids, const unsigned int nGidsCount, NSFonts::IFontManager* pFont, double x, double y) - { - if (NULL == pFont) - return InvalidParameter; + Status CGraphicsPath::AddString(const unsigned int* pGids, const unsigned int nGidsCount, NSFonts::IFontManager* pFont, double x, double y) + { + if (NULL == pFont) + return InvalidParameter; pFont->SetTextMatrix(1, 0, 0, 1, 0, 0); - pFont->LoadString1(pGids, nGidsCount, (float)x, (float)y); - return (TRUE == pFont->GetStringPath(this)) ? Ok : InvalidParameter; - } + pFont->LoadString1(pGids, nGidsCount, (float)x, (float)y); + return (TRUE == pFont->GetStringPath(this)) ? Ok : InvalidParameter; + } - Status CGraphicsPath::AddStringC(const LONG& lText, NSFonts::IFontManager* pFont, double x, double y) + Status CGraphicsPath::AddStringC(const LONG& lText, NSFonts::IFontManager* pFont, double x, double y) { if (NULL == pFont) return InvalidParameter; @@ -467,45 +523,45 @@ namespace Aggplus return (TRUE == pFont->GetStringPath(this)) ? Ok : InvalidParameter; } - void CGraphicsPath::z_Stroke(const double& size) + void CGraphicsPath::z_Stroke(const double& size) { typedef agg::conv_stroke Path_Conv_Stroke; - Path_Conv_Stroke pg(m_internal->m_agg_ps); + Path_Conv_Stroke pg(m_internal->m_agg_ps); pg.line_join(agg::round_join); pg.line_cap(agg::round_cap); pg.approximation_scale(25.00); //pg.miter_limit(0.50); - pg.width(size); + pg.width(size); //pg.auto_detect_orientation(true); agg::path_storage psNew; //2.3 psNew.add_path(pg, 0, false); psNew.concat_path(pg, 0); - m_internal->m_agg_ps = psNew; + m_internal->m_agg_ps = psNew; } - void CGraphicsPath::Widen(const double& size, const Aggplus::LineJoin& join, const CMatrix* matrix, float flatness) + void CGraphicsPath::Widen(const double& size, const Aggplus::LineJoin& join, const CMatrix* matrix, float flatness) { - if (NULL == matrix || 0.0f == flatness) + if (NULL == matrix || 0.0f == flatness) return; typedef agg::conv_curve conv_crv_type; typedef agg::conv_contour Path_Conv_Contour; - conv_crv_type crv(m_internal->m_agg_ps); + conv_crv_type crv(m_internal->m_agg_ps); Path_Conv_Contour pg(crv); pg.miter_limit(0.50); //pg.miter_limit_theta(0.05); //pg.approximation_scale(2.00); - pg.width(size); + pg.width(size); agg::line_join_e LineJoin; - switch (join) + switch (join) { case LineJoinMiter : LineJoin=agg::miter_join; break; case LineJoinBevel : LineJoin=agg::bevel_join; break; @@ -520,8 +576,8 @@ namespace Aggplus agg::path_storage psNew; //2.3 psNew.add_path(pg, 0, false); //m_agg_ps.concat_path(pg, 0); - m_internal->m_agg_ps.concat_path(pg, 0); - m_internal->m_agg_ps = psNew; + m_internal->m_agg_ps.concat_path(pg, 0); + m_internal->m_agg_ps = psNew; } int CGraphicsPath::EllipseArc(double fX, double fY, double fXRad, double fYRad, double fAngle1, double fAngle2, INT bClockDirection) @@ -582,8 +638,8 @@ namespace Aggplus // Выясним в каких четвертях находятся начальная и конечная точки unsigned int nFirstPointQuard = int(fAngle1) / 90 + 1; unsigned int nSecondPointQuard = int(fAngle2) / 90 + 1; - nSecondPointQuard = std::min( 4, std::max( 1, (int)nSecondPointQuard ) ); - nFirstPointQuard = std::min( 4, std::max( 1, (int)nFirstPointQuard ) ); + nSecondPointQuard = std::min( 4, std::max( 1, (int)nSecondPointQuard ) ); + nFirstPointQuard = std::min( 4, std::max( 1, (int)nFirstPointQuard ) ); // Проведем линию в начальную точку дуги double fStartX = 0.0, fStartY = 0.0, fEndX = 0.0, fEndY = 0.0; @@ -719,15 +775,216 @@ namespace Aggplus return Ok; } - bool CGraphicsPath::IsPointInPath(const double& x, const double& y) - { - agg::rasterizer_scanline_aa rasterizer; - agg::conv_curve c_c_path(m_internal->m_agg_ps); - rasterizer.add_path(c_c_path); + bool CGraphicsPath::IsPointInPath(const double& x, const double& y) + { + agg::rasterizer_scanline_aa rasterizer; + agg::conv_curve c_c_path(m_internal->m_agg_ps); + rasterizer.add_path(c_c_path); + + return rasterizer.hit_test((int)x, (int)y); + } + + unsigned CGraphicsPath::GetCloseCount() const noexcept + { + unsigned countClose = 0; + for (unsigned i = 0; i < m_internal->m_agg_ps.total_vertices(); i++) + if (IsClosePoint(i)) + countClose++; + + return countClose; + } + + unsigned CGraphicsPath::GetMoveCount() const noexcept + { + unsigned countMove = 0; + for (unsigned i = 0; i < m_internal->m_agg_ps.total_vertices(); i++) + if (IsMovePoint(i)) + countMove++; + + return countMove; + } + + bool CGraphicsPath::IsClockwise() const noexcept + { + return GetArea() >= 0; + } + + bool CGraphicsPath::IsMovePoint(unsigned idx) const noexcept + { + if (idx >= m_internal->m_agg_ps.total_vertices()) return false; + return this->m_internal->m_agg_ps.command(idx) == agg::path_cmd_move_to; + } + + bool CGraphicsPath::IsCurvePoint(unsigned idx) const noexcept + { + if (idx >= m_internal->m_agg_ps.total_vertices()) return false; + return this->m_internal->m_agg_ps.command(idx) == agg::path_cmd_curve4; + } + + bool CGraphicsPath::IsLinePoint(unsigned idx) const noexcept + { + if (idx >= m_internal->m_agg_ps.total_vertices()) return false; + return this->m_internal->m_agg_ps.command(idx) == agg::path_cmd_line_to; + } + + bool CGraphicsPath::IsClosePoint(unsigned idx) const noexcept + { + if (idx >= m_internal->m_agg_ps.total_vertices()) return false; + return this->m_internal->m_agg_ps.command(idx) == (agg::path_cmd_end_poly | agg::path_flags_close); + } + + std::vector CGraphicsPath::GetPoints(unsigned idx, unsigned count) const noexcept + { + std::vector points; + unsigned length = m_internal->m_agg_ps.total_vertices(); + for (unsigned i = 0; i < count; i++) + { + double x,y; + if (idx + i > length) break; + this->m_internal->m_agg_ps.vertex(idx + i, &x, &y); + points.push_back(PointD(x, y)); + } + + return points; + } + + double CGraphicsPath::GetArea() const noexcept + { + double area = 0.0; + unsigned length = GetPointCount() - 1; + for (unsigned i = 0; i < length; i++) + { + area += GetArea(i, IsCurvePoint(i + 1)); + if (IsCurvePoint(i + 1)) i += 2; + } + + return area; + } + + double CGraphicsPath::GetArea(unsigned idx, bool isCurve) const noexcept + { + float area; + if (isCurve) + { + std::vector points = GetPoints(idx, 4); + area = 3 * ((points[3].Y - points[0].Y) * (points[1].X + points[2].X) + - (points[3].X - points[0].X) * (points[1].Y * points[2].Y) + + points[1].Y * (points[0].X - points[2].X) + - points[1].X * (points[0].Y - points[2].Y) + + points[3].Y * (points[2].X + points[0].X / 3) + - points[3].X * (points[2].Y - points[0].Y / 3)) / 20; + } + + std::vector points = GetPoints(idx, 2); + area = (points[1].Y * points[0].X - points[1].X * points[0].Y) / 20; + + return area; + } + + std::vector CGraphicsPath::GetSubPaths() const + { + std::vector result; - return rasterizer.hit_test((int)x, (int)y); - } + CGraphicsPath subPath; + bool close = true; + for (unsigned i = 0; i < m_internal->m_agg_ps.total_vertices(); i++) + { + if (IsMovePoint(i)) + { + if (!close) + { + PointD firstPoint = subPath.GetPoints(0, 1)[0]; + double x, y; + subPath.GetLastPoint(x, y); + if ((abs(firstPoint.X - x) <= 1e-2 && abs(firstPoint.Y - y) <= 1e-2) || + subPath.GetPointCount() == 1) + { + if (!firstPoint.Equals(PointD(x, y)) || subPath.GetPointCount() == 1) + subPath.LineTo(firstPoint.X, firstPoint.Y); + subPath.CloseFigure(); + } + + result.push_back(subPath); + subPath.Reset(); + } + subPath.StartFigure(); + PointD point = GetPoints(i, 1)[0]; + subPath.MoveTo(point.X, point.Y); + close = false; + } + else if (IsCurvePoint(i)) + { + std::vector points = GetPoints(i, 3); + subPath.CurveTo(points[0].X, points[0].Y, + points[1].X, points[1].Y, + points[2].X, points[2].Y); + i += 2; + } + else if (IsLinePoint(i)) + { + PointD point = GetPoints(i, 1)[0]; + subPath.LineTo(point.X, point.Y); + } + else if (IsClosePoint(i)) + { + PointD firstPoint = subPath.GetPoints(0, 1)[0]; + double x, y; + subPath.GetLastPoint(x, y); + + if (!firstPoint.Equals(PointD(x, y)) || subPath.GetPointCount() == 1) + subPath.LineTo(firstPoint.X, firstPoint.Y); + subPath.CloseFigure(); + result.push_back(subPath); + subPath.Reset(); + close = true; + } + } + + if (!close) + { + PointD firstPoint = subPath.GetPoints(0, 1)[0]; + double x, y; + subPath.GetLastPoint(x, y); + + if ((abs(firstPoint.X - x) <= 1e-2 && abs(firstPoint.Y - y) <= 1e-2) || + subPath.GetPointCount() == 1) + { + if (!firstPoint.Equals(PointD(x, y)) || + subPath.GetPointCount() == 1) + subPath.LineTo(firstPoint.X, firstPoint.Y); + subPath.CloseFigure(); + } + + result.push_back(subPath); + } + + return result; + } + + CGraphicsPath& CGraphicsPath::operator=(const CGraphicsPath& other) noexcept + { + if (&other == this) + return *this; + + m_internal = new CGraphicsPath_private; + m_internal->m_agg_ps = other.m_internal->m_agg_ps; + m_internal->m_bEvenOdd = other.m_internal->m_bEvenOdd; + m_internal->m_bIsMoveTo = other.m_internal->m_bIsMoveTo; + + return *this; + } + + CGraphicsPath& CGraphicsPath::operator=(CGraphicsPath&& other) noexcept + { + if (&other == this) + return *this; + + m_internal = other.m_internal; + other.m_internal = nullptr; + + return *this; + } } namespace Aggplus @@ -736,13 +993,13 @@ namespace Aggplus CGraphicsPathSimpleConverter::CGraphicsPathSimpleConverter() { m_pRenderer = NULL; - m_internal = new CGraphicsPathSimpleConverter_private(); + m_internal = new CGraphicsPathSimpleConverter_private(); } CGraphicsPathSimpleConverter::~CGraphicsPathSimpleConverter() { RELEASEINTERFACE(m_pRenderer); - RELEASEOBJECT(m_internal); + RELEASEOBJECT(m_internal); } void CGraphicsPathSimpleConverter::SetRenderer(IRenderer* pRenderer) @@ -788,7 +1045,7 @@ namespace Aggplus int nRet = 0; - if (!m_internal->m_bIsMoveTo) + if (!m_internal->m_bIsMoveTo) { _MoveTo(pData[0], pData[1]); } @@ -816,7 +1073,7 @@ namespace Aggplus if (8 > lCount) return false; - if (!m_internal->m_bIsMoveTo) + if (!m_internal->m_bIsMoveTo) { _MoveTo(pData[0], pData[1]); @@ -861,14 +1118,14 @@ namespace Aggplus } bool CGraphicsPathSimpleConverter::PathCommandGetCurrentPoint(double* fX, double* fY) { - m_internal->m_agg_ps.last_vertex(fX, fY); + m_internal->m_agg_ps.last_vertex(fX, fY); return true; } - bool CGraphicsPathSimpleConverter::PathCommandText(const std::wstring& bsText, NSFonts::IFontManager* pManager, double fX, double fY, double fWidth, double fHeight, double fBaseLineOffset) + bool CGraphicsPathSimpleConverter::PathCommandText(const std::wstring& bsText, NSFonts::IFontManager* pManager, double fX, double fY, double fWidth, double fHeight, double fBaseLineOffset) { return AddString(bsText, pManager, fX, fY + fBaseLineOffset); } - bool CGraphicsPathSimpleConverter::PathCommandTextEx(std::wstring& bsText, std::wstring& bsGidText, NSFonts::IFontManager* pManager, double fX, double fY, double fWidth, double fHeight, double fBaseLineOffset, DWORD lFlags) + bool CGraphicsPathSimpleConverter::PathCommandTextEx(std::wstring& bsText, std::wstring& bsGidText, NSFonts::IFontManager* pManager, double fX, double fY, double fWidth, double fHeight, double fBaseLineOffset, DWORD lFlags) { if (!bsGidText.empty()) { @@ -878,49 +1135,49 @@ namespace Aggplus return PathCommandText(bsText, pManager, fX, fY, fWidth, fHeight, fBaseLineOffset); } - bool CGraphicsPathSimpleConverter::PathCommandText2(const int* pUnicodes, const int* pGids, const int& nCount, NSFonts::IFontManager* pManager, - const double& x, const double& y, const double& w, const double& h) - { - if (NULL == pGids) - { - pManager->SetStringGID(FALSE); - pManager->LoadString1((const unsigned int*)pUnicodes, (unsigned int)nCount, (float)x, (float)y); - return (TRUE == pManager->GetStringPath(this)) ? true : false; - } - else - { - pManager->SetStringGID(TRUE); - pManager->LoadString1((const unsigned int*)pGids, (unsigned int)nCount, (float)x, (float)y); - return (TRUE == pManager->GetStringPath(this)) ? true : false; - } - } - bool CGraphicsPathSimpleConverter::PathCommandText2(const std::wstring& sUnicodes, const int* pGids, const int& nCount, NSFonts::IFontManager* pManager, - const double& x, const double& y, const double& w, const double& h) - { - if (NULL == pGids) - { - pManager->SetStringGID(FALSE); - pManager->LoadString1(sUnicodes, (float)x, (float)y); - return (TRUE == pManager->GetStringPath(this)) ? true : false; - } - else - { - pManager->SetStringGID(TRUE); - pManager->LoadString1((const unsigned int*)pGids, (unsigned int)nCount, (float)x, (float)y); - return (TRUE == pManager->GetStringPath(this)) ? true : false; - } - } + bool CGraphicsPathSimpleConverter::PathCommandText2(const int* pUnicodes, const int* pGids, const int& nCount, NSFonts::IFontManager* pManager, + const double& x, const double& y, const double& w, const double& h) + { + if (NULL == pGids) + { + pManager->SetStringGID(FALSE); + pManager->LoadString1((const unsigned int*)pUnicodes, (unsigned int)nCount, (float)x, (float)y); + return (TRUE == pManager->GetStringPath(this)) ? true : false; + } + else + { + pManager->SetStringGID(TRUE); + pManager->LoadString1((const unsigned int*)pGids, (unsigned int)nCount, (float)x, (float)y); + return (TRUE == pManager->GetStringPath(this)) ? true : false; + } + } + bool CGraphicsPathSimpleConverter::PathCommandText2(const std::wstring& sUnicodes, const int* pGids, const int& nCount, NSFonts::IFontManager* pManager, + const double& x, const double& y, const double& w, const double& h) + { + if (NULL == pGids) + { + pManager->SetStringGID(FALSE); + pManager->LoadString1(sUnicodes, (float)x, (float)y); + return (TRUE == pManager->GetStringPath(this)) ? true : false; + } + else + { + pManager->SetStringGID(TRUE); + pManager->LoadString1((const unsigned int*)pGids, (unsigned int)nCount, (float)x, (float)y); + return (TRUE == pManager->GetStringPath(this)) ? true : false; + } + } bool CGraphicsPathSimpleConverter::PathCommandGetBounds(double& left, double& top, double& width, double &height) { - unsigned int nTotal = m_internal->m_agg_ps.total_vertices(); + unsigned int nTotal = m_internal->m_agg_ps.total_vertices(); if (nTotal) { agg::rect_d bounds(1e100, 1e100, -1e100, -1e100); double x, y; for(unsigned int i = 0; i < nTotal; i++) { - unsigned int nTip = m_internal->m_agg_ps.vertex(i, &x, &y); + unsigned int nTip = m_internal->m_agg_ps.vertex(i, &x, &y); if(agg::is_vertex(nTip)) { if(x < bounds.x1) bounds.x1 = x; @@ -947,8 +1204,8 @@ namespace Aggplus bool CGraphicsPathSimpleConverter::_MoveTo(double x, double y) { - m_internal->m_bIsMoveTo = true; - m_internal->m_agg_ps.move_to(x, y); + m_internal->m_bIsMoveTo = true; + m_internal->m_agg_ps.move_to(x, y); if (NULL != m_pRenderer) { @@ -960,12 +1217,12 @@ namespace Aggplus } bool CGraphicsPathSimpleConverter::_LineTo(double x, double y) { - if (!m_internal->m_bIsMoveTo) + if (!m_internal->m_bIsMoveTo) { _MoveTo(x, y); - } + } - m_internal->m_agg_ps.line_to(x, y); + m_internal->m_agg_ps.line_to(x, y); if (NULL != m_pRenderer) { @@ -978,12 +1235,12 @@ namespace Aggplus } bool CGraphicsPathSimpleConverter::_CurveTo(double x1, double y1, double x2, double y2, double x3, double y3) { - if (!m_internal->m_bIsMoveTo) + if (!m_internal->m_bIsMoveTo) { _MoveTo(x1, y1); } - m_internal->m_agg_ps.curve4(x1, y1, x2, y2, x3, y3); + m_internal->m_agg_ps.curve4(x1, y1, x2, y2, x3, y3); if (NULL != m_pRenderer) { @@ -996,8 +1253,8 @@ namespace Aggplus } bool CGraphicsPathSimpleConverter::_Close() { - m_internal->m_bIsClosed = true; - m_internal->m_agg_ps.close_polygon(); + m_internal->m_bIsClosed = true; + m_internal->m_agg_ps.close_polygon(); if (NULL != m_pRenderer) { @@ -1009,11 +1266,11 @@ namespace Aggplus } bool CGraphicsPathSimpleConverter::_Reset() { - m_internal->m_bEvenOdd = false; - m_internal->m_bIsMoveTo = false; - m_internal->m_bIsClosed = false; + m_internal->m_bEvenOdd = false; + m_internal->m_bIsMoveTo = false; + m_internal->m_bIsClosed = false; - m_internal->m_agg_ps.remove_all(); + m_internal->m_agg_ps.remove_all(); if (NULL != m_pRenderer) { @@ -1026,7 +1283,7 @@ namespace Aggplus } bool CGraphicsPathSimpleConverter::_Start() { - m_internal->m_agg_ps.start_new_path(); + m_internal->m_agg_ps.start_new_path(); if (NULL != m_pRenderer) { @@ -1038,7 +1295,7 @@ namespace Aggplus return true; } - bool CGraphicsPathSimpleConverter::AddString(const std::wstring& bstrText, NSFonts::IFontManager* pFont, double x, double y) + bool CGraphicsPathSimpleConverter::AddString(const std::wstring& bstrText, NSFonts::IFontManager* pFont, double x, double y) { if (NULL == pFont) return false; @@ -1105,8 +1362,8 @@ namespace Aggplus // Выясним в каких четвертях находятся начальная и конечная точки unsigned int nFirstPointQuard = int(fAngle1) / 90 + 1; unsigned int nSecondPointQuard = int(fAngle2) / 90 + 1; - nSecondPointQuard = std::min( 4, std::max( 1, (int)nSecondPointQuard ) ); - nFirstPointQuard = std::min( 4, std::max( 1, (int)nFirstPointQuard ) ); + nSecondPointQuard = std::min( 4, std::max( 1, (int)nSecondPointQuard ) ); + nFirstPointQuard = std::min( 4, std::max( 1, (int)nFirstPointQuard ) ); // Проведем линию в начальную точку дуги double fStartX = 0.0, fStartY = 0.0, fEndX = 0.0, fEndY = 0.0; @@ -1244,11 +1501,11 @@ namespace Aggplus bool CGraphicsPathSimpleConverter::Is_poly_closed() { - if (!m_internal->m_agg_ps.total_vertices()) + if (!m_internal->m_agg_ps.total_vertices()) return true; double x, y; - unsigned int nTip = m_internal->m_agg_ps.last_vertex(&x, &y); + unsigned int nTip = m_internal->m_agg_ps.last_vertex(&x, &y); if (nTip & agg::path_flags_close) return true; diff --git a/DesktopEditor/graphics/GraphicsPath.h b/DesktopEditor/graphics/GraphicsPath.h index 1160dc9da23..1e44a29e756 100644 --- a/DesktopEditor/graphics/GraphicsPath.h +++ b/DesktopEditor/graphics/GraphicsPath.h @@ -42,125 +42,155 @@ namespace Aggplus { - class CGraphicsPath_private; - class GRAPHICS_DECL CGraphicsPath : public NSFonts::ISimpleGraphicsPath - { - public: - CGraphicsPath(); - ~CGraphicsPath(); - - CGraphicsPath* Clone(); - - Status Reset(); - void SetRuler(bool bEvenOdd); - - Status StartFigure(); - Status CloseFigure(); - bool Is_poly_closed(); - Status MoveTo(double x, double y); - Status LineTo(double x, double y); - Status CurveTo(double x1, double y1, double x2, double y2, double x3, double y3); - - // методы, которые просто будем сводить к трем основным - Status AddLine(double x1, double y1, double x2, double y2); - Status AddLines(double* pPoints, int nCount); - Status AddBezier(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4); - Status AddBeziers(double* pPoints, int nCount); - Status AddCurve(double* pPoints, int nCount); - Status AddEllipse(double x, double y, double width, double height); - Status AddRectangle(double x, double y, double width, double height); - Status AddPolygon(double* pPoints, int nCount); - Status AddPath(const CGraphicsPath& oPath); - Status AddArc(double x, double y, double width, double height, double startAngle, double sweepAngle); - - ULONG GetPointCount() const; - Status GetPathPoints(PointF* points, int count) const; - Status GetLastPoint(double& x, double& y); - Status GetPathPoints(double* points, int count) const; - void GetBounds(double& left, double& top, double& width, double& height); - - Status Transform(const CMatrix* matrix); - virtual bool _MoveTo(double x, double y); - virtual bool _LineTo(double x, double y); - virtual bool _CurveTo(double x1, double y1, double x2, double y2, double x3, double y3); - virtual bool _Close(); - - Status AddString(const std::wstring& strText, NSFonts::IFontManager* pFont, double x, double y); - Status AddString(const unsigned int* pGids, const unsigned int nGidsCount, NSFonts::IFontManager* pFont, double x, double y); - Status AddStringC(const LONG& lText, NSFonts::IFontManager* pFont, double x, double y); - void z_Stroke(const double& size); - void Widen(const double& size, const Aggplus::LineJoin& join, const CMatrix* matrix, float flatness); - - int EllipseArc(double fX, double fY, double fXRad, double fYRad, double fAngle1, double fAngle2, INT bClockDirection); - double AngToEllPrm(double fAngle, double fXRad, double fYRad); - int EllipseArc2(double fX, double fY, double fXRad, double fYRad, double fAngle1, double fAngle2, INT bClockDirection); - int EllipseArc3(double fX, double fY, double fXRad, double fYRad, double dAngle1, double dAngle2, double *pfXCur, double *pfYCur, INT bClockDirection = FALSE); - int Ellipse(double fX, double fY, double fXRad, double fYRad); - Status AddArc2(double fX, double fY, double fWidth, double fHeight, double fStartAngle, double fSweepAngle); - bool IsPointInPath(const double& x, const double& y); - - public: - CGraphicsPath_private* m_internal; - }; - - class CGraphicsPathSimpleConverter_private; - class GRAPHICS_DECL CGraphicsPathSimpleConverter : public NSFonts::ISimpleGraphicsPath - { - private: - IRenderer* m_pRenderer; - CGraphicsPathSimpleConverter_private* m_internal; - - public: - CGraphicsPathSimpleConverter(); - ~CGraphicsPathSimpleConverter(); - - public: - void SetRenderer(IRenderer* pRenderer); - IRenderer* GetRenderer(INT bIsAddref = FALSE); - - public: - bool PathCommandMoveTo(double fX, double fY); - bool PathCommandLineTo(double fX, double fY); - bool PathCommandLinesTo(double* pPoints, LONG lCount); - bool PathCommandCurveTo(double fX1, double fY1, double fX2, double fY2, double fX3, double fY3); - bool PathCommandCurvesTo(double* pData, LONG lCount); - bool PathCommandArcTo(double fX, double fY, double fWidth, double fHeight, double fStartAngle, double fSweepAngle); - bool PathCommandClose(); - bool PathCommandEnd(); - bool PathCommandStart(); - bool PathCommandGetCurrentPoint(double* fX, double* fY); - bool PathCommandText(const std::wstring& bsText, NSFonts::IFontManager* pManager, double fX, double fY, double fWidth, double fHeight, double fBaseLineOffset); - bool PathCommandTextEx(std::wstring& bsText, std::wstring& bsGidText, NSFonts::IFontManager* pManager, double fX, double fY, double fWidth, double fHeight, double fBaseLineOffset, DWORD lFlags); - - bool PathCommandText2(const int* pUnicodes, const int* pGids, const int& nCount, NSFonts::IFontManager* pManager, - const double& x, const double& y, const double& w, const double& h); - bool PathCommandText2(const std::wstring& sUnicodes, const int* pGids, const int& nCount, NSFonts::IFontManager* pManager, - const double& x, const double& y, const double& w, const double& h); - - bool PathCommandGetBounds(double& left, double& top, double& width, double &height); - - public: - - virtual bool _MoveTo(double x, double y); - virtual bool _LineTo(double x, double y); - virtual bool _CurveTo(double x1, double y1, double x2, double y2, double x3, double y3); - virtual bool _Close(); - bool _Reset(); - bool _Start(); - - protected: - bool AddString(const std::wstring& bstrText, NSFonts::IFontManager* pFont, double x, double y); - - int EllipseArc(double fX, double fY, double fXRad, double fYRad, double fAngle1, double fAngle2, INT bClockDirection); - double AngToEllPrm(double fAngle, double fXRad, double fYRad); - int EllipseArc2(double fX, double fY, double fXRad, double fYRad, double fAngle1, double fAngle2, INT bClockDirection); - int EllipseArc3(double fX, double fY, double fXRad, double fYRad, double dAngle1, double dAngle2, double *pfXCur, double *pfYCur, INT bClockDirection = FALSE); - int Ellipse(double fX, double fY, double fXRad, double fYRad); - - bool AddArc(double fX, double fY, double fWidth, double fHeight, double fStartAngle, double fSweepAngle); - - bool Is_poly_closed(); - }; -} + class CGraphicsPath_private; + class GRAPHICS_DECL CGraphicsPath : public NSFonts::ISimpleGraphicsPath + { + public: + CGraphicsPath(); + CGraphicsPath(const CGraphicsPath& other) noexcept; + CGraphicsPath(CGraphicsPath&& other) noexcept; + CGraphicsPath(const std::vector& paths) noexcept; + virtual ~CGraphicsPath(); + + CGraphicsPath* Clone(); + + Status Reset(); + void SetRuler(bool bEvenOdd); + + Status StartFigure(); + Status CloseFigure(); + bool Is_poly_closed() const; + Status MoveTo(double x, double y); + Status LineTo(double x, double y); + Status CurveTo(double x1, double y1, double x2, double y2, double x3, double y3); + + // методы, которые просто будем сводить к трем основным + Status AddLine(double x1, double y1, double x2, double y2); + Status AddLines(double* pPoints, int nCount); + Status AddBezier(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4); + Status AddBeziers(double* pPoints, int nCount); + Status AddCurve(double* pPoints, int nCount); + Status AddEllipse(double x, double y, double width, double height); + Status AddRectangle(double x, double y, double width, double height); + Status AddPolygon(double* pPoints, int nCount); + Status AddPath(const CGraphicsPath& oPath); + Status AddArc(double x, double y, double width, double height, double startAngle, double sweepAngle); + + ULONG GetPointCount() const; + Status GetPathPoints(PointF* points, int count) const; + Status GetLastPoint(double& x, double& y); + Status GetPathPoints(double* points, int count) const; + void GetBounds(double& left, double& top, double& width, double& height) const; + void GetBoundsAccurate(double& left, double& top, double& width, double& height) const; + + Status Transform(const CMatrix* matrix); + virtual bool _MoveTo(double x, double y); + virtual bool _LineTo(double x, double y); + virtual bool _CurveTo(double x1, double y1, double x2, double y2, double x3, double y3); + virtual bool _Close(); + + Status AddString(const std::wstring& strText, NSFonts::IFontManager* pFont, double x, double y); + Status AddString(const unsigned int* pGids, const unsigned int nGidsCount, NSFonts::IFontManager* pFont, double x, double y); + Status AddStringC(const LONG& lText, NSFonts::IFontManager* pFont, double x, double y); + void z_Stroke(const double& size); + void Widen(const double& size, const Aggplus::LineJoin& join, const CMatrix* matrix, float flatness); + + int EllipseArc(double fX, double fY, double fXRad, double fYRad, double fAngle1, double fAngle2, INT bClockDirection); + double AngToEllPrm(double fAngle, double fXRad, double fYRad); + int EllipseArc2(double fX, double fY, double fXRad, double fYRad, double fAngle1, double fAngle2, INT bClockDirection); + int EllipseArc3(double fX, double fY, double fXRad, double fYRad, double dAngle1, double dAngle2, double* pfXCur, double* pfYCur, INT bClockDirection = FALSE); + int Ellipse(double fX, double fY, double fXRad, double fYRad); + Status AddArc2(double fX, double fY, double fWidth, double fHeight, double fStartAngle, double fSweepAngle); + bool IsPointInPath(const double& x, const double& y); + + // Methods for Path Clip + unsigned GetCloseCount() const noexcept; + unsigned GetMoveCount() const noexcept; + bool IsClockwise() const noexcept; + bool IsMovePoint(unsigned idx) const noexcept; + bool IsCurvePoint(unsigned idx) const noexcept; + bool IsLinePoint(unsigned idx) const noexcept; + bool IsClosePoint(unsigned idx) const noexcept; + double GetArea() const noexcept; + double GetArea(unsigned idx, bool isCurve) const noexcept; + std::vector GetPoints(unsigned idx, unsigned count) const noexcept; + std::vector GetSubPaths() const; + + CGraphicsPath& operator=(const CGraphicsPath& other) noexcept; + CGraphicsPath& operator=(CGraphicsPath&& other) noexcept; + bool operator==(const CGraphicsPath& other) noexcept; + + public: + CGraphicsPath_private* m_internal; + }; + + class CGraphicsPathSimpleConverter_private; + class GRAPHICS_DECL CGraphicsPathSimpleConverter : public NSFonts::ISimpleGraphicsPath + { + private: + IRenderer* m_pRenderer; + CGraphicsPathSimpleConverter_private* m_internal; + + public: + CGraphicsPathSimpleConverter(); + ~CGraphicsPathSimpleConverter(); + + public: + void SetRenderer(IRenderer* pRenderer); + IRenderer* GetRenderer(INT bIsAddref = FALSE); + + public: + bool PathCommandMoveTo(double fX, double fY); + bool PathCommandLineTo(double fX, double fY); + bool PathCommandLinesTo(double* pPoints, LONG lCount); + bool PathCommandCurveTo(double fX1, double fY1, double fX2, double fY2, double fX3, double fY3); + bool PathCommandCurvesTo(double* pData, LONG lCount); + bool PathCommandArcTo(double fX, double fY, double fWidth, double fHeight, double fStartAngle, double fSweepAngle); + bool PathCommandClose(); + bool PathCommandEnd(); + bool PathCommandStart(); + bool PathCommandGetCurrentPoint(double* fX, double* fY); + bool PathCommandText(const std::wstring& bsText, NSFonts::IFontManager* pManager, double fX, double fY, double fWidth, double fHeight, double fBaseLineOffset); + bool + PathCommandTextEx(std::wstring& bsText, std::wstring& bsGidText, NSFonts::IFontManager* pManager, double fX, double fY, double fWidth, double fHeight, double fBaseLineOffset, DWORD lFlags); + + bool PathCommandText2(const int* pUnicodes, const int* pGids, const int& nCount, NSFonts::IFontManager* pManager, const double& x, const double& y, const double& w, const double& h); + bool PathCommandText2(const std::wstring& sUnicodes, const int* pGids, const int& nCount, NSFonts::IFontManager* pManager, const double& x, const double& y, const double& w, const double& h); + + bool PathCommandGetBounds(double& left, double& top, double& width, double& height); + + public: + virtual bool _MoveTo(double x, double y); + virtual bool _LineTo(double x, double y); + virtual bool _CurveTo(double x1, double y1, double x2, double y2, double x3, double y3); + virtual bool _Close(); + bool _Reset(); + bool _Start(); + + protected: + bool AddString(const std::wstring& bstrText, NSFonts::IFontManager* pFont, double x, double y); + + int EllipseArc(double fX, double fY, double fXRad, double fYRad, double fAngle1, double fAngle2, INT bClockDirection); + double AngToEllPrm(double fAngle, double fXRad, double fYRad); + int EllipseArc2(double fX, double fY, double fXRad, double fYRad, double fAngle1, double fAngle2, INT bClockDirection); + int EllipseArc3(double fX, double fY, double fXRad, double fYRad, double dAngle1, double dAngle2, double* pfXCur, double* pfYCur, INT bClockDirection = FALSE); + int Ellipse(double fX, double fY, double fXRad, double fYRad); + + bool AddArc(double fX, double fY, double fWidth, double fHeight, double fStartAngle, double fSweepAngle); + + bool Is_poly_closed(); + }; + + enum BooleanOpType + { + Intersection = 1, + Union = 0, + Subtraction = 2, + Exclusion = 3 + }; + + GRAPHICS_DECL CGraphicsPath CalcBooleanOperation(const CGraphicsPath& path1, const CGraphicsPath& path2, BooleanOpType op, long fillType = c_nWindingFillMode); + +} // namespace Aggplus #endif // _BUILD_GRAPHICSPATH_H_ diff --git a/DesktopEditor/graphics/GraphicsRenderer.cpp b/DesktopEditor/graphics/GraphicsRenderer.cpp index 7304897791c..9b0c684e558 100644 --- a/DesktopEditor/graphics/GraphicsRenderer.cpp +++ b/DesktopEditor/graphics/GraphicsRenderer.cpp @@ -563,11 +563,11 @@ HRESULT CGraphicsRenderer::get_BrushTextureImage(Aggplus::CImage** pImage) } HRESULT CGraphicsRenderer::put_BrushTextureImage(Aggplus::CImage *pImage) { - if (NULL == pImage) - return S_FALSE; - RELEASEINTERFACE(m_oBrush.Image); + if (NULL == pImage) + return S_OK; + m_oBrush.Image = pImage; m_oBrush.Image->AddRef(); @@ -796,7 +796,12 @@ HRESULT CGraphicsRenderer::BeginCommand(const DWORD& lType) } case c_nMaskType: { - m_pRenderer->CreateAlphaMask(); + m_pRenderer->StartCreatingAlphaMask(); + break; + } + case c_nLayerType: + { + m_pRenderer->CreateLayer(); break; } default: @@ -817,7 +822,8 @@ HRESULT CGraphicsRenderer::EndCommand(const DWORD& lType) m_pPath->SetRuler(bIsIn ? false : true); INT bIsIntersect = (c_nClipRegionIntersect == (0x0100 & m_lCurrentClipMode)); - m_pRenderer->CombineClip(m_pPath, bIsIntersect ? agg::sbool_and : agg::sbool_or); + INT bIsStrokePath = (c_nClipToStrokePath == (0x0010 & m_lCurrentClipMode)); + m_pRenderer->CombineClip(m_pPath, bIsIntersect ? agg::sbool_and : agg::sbool_or, bIsStrokePath ? &m_oPen : NULL); //m_pRenderer->SetClip(m_pPath); break; @@ -830,7 +836,7 @@ HRESULT CGraphicsRenderer::EndCommand(const DWORD& lType) } case c_nMaskType: { - m_pRenderer->StartApplyingAlphaMask(); + m_pRenderer->EndCreatingAlphaMask(); break; } case c_nResetMaskType: @@ -838,6 +844,11 @@ HRESULT CGraphicsRenderer::EndCommand(const DWORD& lType) m_pRenderer->ResetAlphaMask(); break; } + case c_nLayerType: + { + m_pRenderer->BlendLayer(); + break; + } default: break; }; @@ -945,61 +956,62 @@ HRESULT CGraphicsRenderer::DrawPath(const LONG& nType) } Aggplus::CBrushTexture* pTextureBrush = NULL; - - if (NULL != m_pCache) - { - pCacheImage = (CCacheImage*)m_pCache->Lock(m_oBrush.TexturePath); - pTextureBrush = new Aggplus::CBrushTexture(pCacheImage->GetImage(), oMode); + if (NULL != m_oBrush.Image) + { + pTextureBrush = new Aggplus::CBrushTexture(m_oBrush.Image, oMode); } - else + else if (m_oBrush.TexturePath.find(L"data:") == 0) { - #ifdef BUILDING_WASM_MODULE - if (NULL != m_oBrush.Image) - pTextureBrush = new Aggplus::CBrushTexture(m_oBrush.Image, oMode); - else if (m_oBrush.TexturePath.find(L"data:") == 0) + bool bIsOnlyOfficeHatch = false; + if (m_oBrush.TexturePath.find(L"onlyoffice_hatch") != std::wstring::npos) + bIsOnlyOfficeHatch = true; + + int countErase = (int)(m_oBrush.TexturePath.find(',') + 1); + int nInputSize = (int)(m_oBrush.TexturePath.length() - countErase); + const wchar_t* pInputSrc = m_oBrush.TexturePath.c_str() + countErase; + + int nDecodeLen = NSBase64::Base64DecodeGetRequiredLength(nInputSize); + BYTE* pImageData = new BYTE[nDecodeLen]; + if (TRUE == NSBase64::Base64Decode(pInputSrc, nInputSize, pImageData, &nDecodeLen)) { - bool bIsOnlyOfficeHatch = false; - if (m_oBrush.TexturePath.find(L"onlyoffice_hatch") != std::wstring::npos) - bIsOnlyOfficeHatch = true; - std::string sBase64MultyByte(m_oBrush.TexturePath.begin(), m_oBrush.TexturePath.end()); - sBase64MultyByte.erase(0, sBase64MultyByte.find(',') + 1); - int nDecodeLen = NSBase64::Base64DecodeGetRequiredLength(sBase64MultyByte.length()); - BYTE* pImageData = new BYTE[nDecodeLen + 64]; - if (TRUE == NSBase64::Base64Decode(sBase64MultyByte.c_str(), sBase64MultyByte.length(), pImageData, &nDecodeLen)) + CBgraFrame oFrame; + if (bIsOnlyOfficeHatch) { - CBgraFrame oFrame; - if (bIsOnlyOfficeHatch) - { - int nSize = (int)sqrt(nDecodeLen >> 2); - oFrame.put_IsRGBA(true); - oFrame.put_Data(pImageData); - oFrame.put_Width(nSize); - oFrame.put_Height(nSize); - oFrame.put_Stride(4 * nSize); - } - else - { - oFrame.put_IsRGBA(false); - oFrame.Decode(pImageData, nDecodeLen); - RELEASEARRAYOBJECTS(pImageData); - } - // pImage отдается pTextureBrush и освобождается вместе с pBrush - Aggplus::CImage* pImage = new Aggplus::CImage(); - pImage->Create(oFrame.get_Data(), oFrame.get_Width(), oFrame.get_Height(), oFrame.get_Stride()); - oFrame.ClearNoAttack(); - pTextureBrush = new Aggplus::CBrushTexture(pImage, oMode); - pTextureBrush->m_bReleaseImage = TRUE; + int nSize = (int)sqrt(nDecodeLen >> 2); + oFrame.put_IsRGBA(true); + oFrame.put_Data(pImageData); + oFrame.put_Width(nSize); + oFrame.put_Height(nSize); + oFrame.put_Stride(4 * nSize); } else + { + oFrame.put_IsRGBA(false); + oFrame.Decode(pImageData, nDecodeLen); RELEASEARRAYOBJECTS(pImageData); + } + // pImage отдается pTextureBrush и освобождается вместе с pBrush + Aggplus::CImage* pImage = new Aggplus::CImage(); + pImage->Create(oFrame.get_Data(), oFrame.get_Width(), oFrame.get_Height(), oFrame.get_Stride()); + oFrame.ClearNoAttack(); + pTextureBrush = new Aggplus::CBrushTexture(pImage, oMode); + pTextureBrush->m_bReleaseImage = TRUE; } - #else - if (NULL != m_oBrush.Image) - pTextureBrush = new Aggplus::CBrushTexture(m_oBrush.Image, oMode); else + RELEASEARRAYOBJECTS(pImageData); + } + else + { + if (NULL != m_pCache) + { + pCacheImage = (CCacheImage*)m_pCache->Lock(m_oBrush.TexturePath); + pTextureBrush = new Aggplus::CBrushTexture(pCacheImage->GetImage(), oMode); + } + else + { pTextureBrush = new Aggplus::CBrushTexture(m_oBrush.TexturePath, oMode); - #endif + } } if( pTextureBrush ) @@ -1401,11 +1413,26 @@ void CGraphicsRenderer::CreateFlip(BYTE* pPixels, const Aggplus::CDoubleRect& oR m_pRenderer->SetPageUnit(Aggplus::UnitMillimeter); } -void CGraphicsRenderer::SetAlphaMask(Aggplus::CAlphaMask* pAlphaMask) +void CGraphicsRenderer::SetAlphaMask(Aggplus::CAlphaMask *pAlphaMask) { m_pRenderer->SetAlphaMask(pAlphaMask); } +Aggplus::CSoftMask* CGraphicsRenderer::CreateSoftMask(bool bAlpha) +{ + return m_pRenderer->CreateSoftMask(bAlpha); +} + +void CGraphicsRenderer::SetSoftMask(Aggplus::CSoftMask* pSoftMask) +{ + m_pRenderer->SetSoftMask(pSoftMask); +} + +HRESULT CGraphicsRenderer::put_LayerOpacity(double dValue) +{ + return m_pRenderer->SetLayerOpacity(dValue); +} + void CGraphicsRenderer::put_GlobalAlphaEnabled(const bool& bEnabled, const double& dVal) { m_bGlobalAlphaEnabled = bEnabled; @@ -1458,6 +1485,7 @@ class CGraphicsRenderer_State : public IGraphicsRenderer_State double m_dGlobalAlpha; bool m_bGlobalAlphaEnabled; bool m_bIntegerGrid; + unsigned int m_nBlendMode; Aggplus::CGraphics_ClipState m_oClipState; }; @@ -1478,6 +1506,7 @@ void CGraphicsRenderer::Save() pState->m_bGlobalAlphaEnabled = m_bGlobalAlphaEnabled; pState->m_bIntegerGrid = m_pRenderer->m_bIntegerGrid; + pState->m_nBlendMode = m_pRenderer->m_nBlendMode; m_arStates.push_back(pState); } @@ -1499,6 +1528,7 @@ void CGraphicsRenderer::Restore() ApplyTransform(&pState->m_oTransform); this->put_IntegerGrid(pState->m_bIntegerGrid); this->put_GlobalAlphaEnabled(pState->m_bGlobalAlphaEnabled, pState->m_dGlobalAlpha); + this->put_BlendMode(pState->m_nBlendMode); m_pRenderer->ResetClip(); for (std::vector::iterator i = pState->m_oClipState.Records.begin(); i != pState->m_oClipState.Records.end(); i++) @@ -1509,7 +1539,7 @@ void CGraphicsRenderer::Restore() RELEASEOBJECT(pState); } -void CGraphicsRenderer::put_BlendMode(const unsigned int nBlendMode) +void CGraphicsRenderer::put_BlendMode(const unsigned int& nBlendMode) { if (NULL != m_pRenderer) { diff --git a/DesktopEditor/graphics/GraphicsRenderer.h b/DesktopEditor/graphics/GraphicsRenderer.h index e0d67d8628e..d5cd633616f 100644 --- a/DesktopEditor/graphics/GraphicsRenderer.h +++ b/DesktopEditor/graphics/GraphicsRenderer.h @@ -124,8 +124,8 @@ class CGraphicsRenderer : public NSGraphics::IGraphicsRenderer virtual void SetSwapRGB(bool bValue){ if (m_pRenderer) m_pRenderer->m_bSwapRGB = bValue; } virtual void SetTileImageDpi(const double& dDpi) { if (m_pRenderer) m_pRenderer->m_dDpiTile = dDpi; } - void Save(); - void Restore(); + virtual void Save(); + virtual void Restore(); public: // тип рендерера----------------------------------------------------------------------------- @@ -163,9 +163,9 @@ class CGraphicsRenderer : public NSGraphics::IGraphicsRenderer virtual HRESULT PenDashPattern(double* pPattern, LONG lCount); // brush ------------------------------------------------------------------------------------ - virtual void put_BrushGradInfo(const NSStructures::GradientInfo &_ginfo) override { - m_oBrush.m_oGradientInfo = _ginfo; - } + virtual void put_BrushGradInfo(void* pGradInfo) override { + m_oBrush.m_oGradientInfo = *((NSStructures::GradientInfo*)pGradInfo); + } virtual HRESULT get_BrushType(LONG* lType); virtual HRESULT put_BrushType(const LONG& lType); @@ -278,7 +278,7 @@ class CGraphicsRenderer : public NSGraphics::IGraphicsRenderer { _SetFont(); } - virtual void put_BlendMode(const unsigned int nBlendMode) override; + virtual void put_BlendMode(const unsigned int& nBlendMode) override; public: virtual void CloseFont() @@ -351,6 +351,11 @@ class CGraphicsRenderer : public NSGraphics::IGraphicsRenderer // alpha mask methods void SetAlphaMask(Aggplus::CAlphaMask* pAlphaMask); + virtual Aggplus::CSoftMask* CreateSoftMask(bool bAlpha) override; + virtual void SetSoftMask(Aggplus::CSoftMask* pSoftMask) override; + + // layer methods + virtual HRESULT put_LayerOpacity(double dValue) override; // smart methods void drawHorLine(BYTE align, double y, double x, double r, double penW) diff --git a/DesktopEditor/graphics/IRenderer.h b/DesktopEditor/graphics/IRenderer.h index 6ee8c92f45e..0f46a733e73 100644 --- a/DesktopEditor/graphics/IRenderer.h +++ b/DesktopEditor/graphics/IRenderer.h @@ -67,6 +67,8 @@ const long c_nTableCell = 0x2000; const long c_nMaskType = 0x3000; const long c_nResetMaskType = 0x4000; +const long c_nLayerType = 0x5000; + const long c_nPDFTilingFill = 0x2001; const long c_nPDFTilingFillIteration = 0x2002; @@ -94,6 +96,9 @@ const long c_nBaselineShift = 0xa041; // типы клипа const long c_nClipRegionTypeWinding = 0x0000; const long c_nClipRegionTypeEvenOdd = 0x0001; +// тип преобразования пути для клипов +const long c_nClipToPath = 0x0000; +const long c_nClipToStrokePath = 0x0010; // тип объединения клипов const long c_nClipRegionIntersect = 0x0000; const long c_nClipRegionUnion = 0x0100; @@ -111,6 +116,7 @@ const long c_nFlipNextRotate = 0x0004; const long c_nDarkMode = 0x0008; const long c_nUseDictionaryFonts = 0x0010; const long c_nPenWidth0As1px = 0x0020; +const long c_nSupportPathTextAsText = 0x0040; // типы рендерера const long c_nUnknownRenderer = 0x0000; @@ -144,6 +150,12 @@ class IAdvancedCommand FormField = 3, // Обратная совместимость для docxf Annotaion = 4, DeleteAnnot = 5, + WidgetsInfo = 6, + ShapeStart = 7, + ShapeEnd = 8, + PageClear = 9, + PageRotate = 10, + Headings = 11, Undefined = 255 }; @@ -161,13 +173,13 @@ namespace Aggplus { class CImage; } class IRenderer : public IGrObject { public: - bool m_bUseTransformCoordsToIdentity; + bool m_bUseTransformCoordsToIdentity; public: - IRenderer() - { - m_bUseTransformCoordsToIdentity = false; - } + IRenderer() + { + m_bUseTransformCoordsToIdentity = false; + } public: // тип рендерера----------------------------------------------------------------------------- @@ -258,6 +270,7 @@ class IRenderer : public IGrObject virtual HRESULT CommandDrawTextCHAR2(unsigned int* codepoints, const unsigned int& codepointscount, const unsigned int& gid, const double& x, const double& y, const double& w, const double& h) { + UNUSED_VARIABLE(codepointscount); LONG c = (NULL == codepoints) ? 32 : codepoints[0]; return CommandDrawTextExCHAR(c, (LONG)gid, x, y, w, h); } @@ -292,6 +305,12 @@ class IRenderer : public IGrObject // transform -------------------------------------------------------------------------------- virtual HRESULT GetCommandParams(double* dAngle, double* dLeft, double* dTop, double* dWidth, double* dHeight, DWORD* lFlags) { + UNUSED_VARIABLE(dAngle); + UNUSED_VARIABLE(dLeft); + UNUSED_VARIABLE(dTop); + UNUSED_VARIABLE(dWidth); + UNUSED_VARIABLE(dHeight); + UNUSED_VARIABLE(lFlags); return S_OK; } virtual HRESULT SetCommandParams(double dAngle, double dLeft, double dTop, double dWidth, double dHeight, DWORD lFlags) @@ -324,7 +343,16 @@ class IRenderer : public IGrObject SetTransform(mass[0], mass[1], mass[2], mass[3], mass[4], mass[5]); return S_OK; } - virtual HRESULT SetBaseTransform(const double& m1, const double& m2, const double& m3, const double& m4, const double& m5, const double& m6) { return S_OK; }; + virtual HRESULT SetBaseTransform(const double& m1, const double& m2, const double& m3, const double& m4, const double& m5, const double& m6) + { + UNUSED_VARIABLE(m1); + UNUSED_VARIABLE(m2); + UNUSED_VARIABLE(m3); + UNUSED_VARIABLE(m4); + UNUSED_VARIABLE(m5); + UNUSED_VARIABLE(m6); + return S_OK; + }; virtual HRESULT SetTransform(const double& m1, const double& m2, const double& m3, const double& m4, const double& m5, const double& m6) = 0; virtual HRESULT GetTransform(double *pdA, double *pdB, double *pdC, double *pdD, double *pdE, double *pdF) = 0; virtual HRESULT ResetTransform() = 0; @@ -349,26 +377,59 @@ class IRenderer : public IGrObject return S_OK; } - virtual HRESULT IsExistAdditionalParam(const int& type) {return S_FALSE;} - virtual HRESULT GetAdditionalParam(const int& type, std::string& result) {return S_FALSE;} + virtual HRESULT IsExistAdditionalParam(const int& type) + { + UNUSED_VARIABLE(type); + return S_FALSE; + } + virtual HRESULT GetAdditionalParam(const int& type, std::string& result) + { + UNUSED_VARIABLE(type); + UNUSED_VARIABLE(result); + return S_FALSE; + } + + virtual HRESULT IsSupportAdvancedCommand(const IAdvancedCommand::AdvancedCommandType& type) + { + UNUSED_VARIABLE(type); + return S_FALSE; + } + virtual HRESULT AdvancedCommand(IAdvancedCommand* command) + { + UNUSED_VARIABLE(command); + return S_FALSE; + } + + // graphics layer settings + virtual HRESULT put_LayerOpacity(double dValue) + { + UNUSED_VARIABLE(dValue); + return S_FALSE; + } - virtual HRESULT IsSupportAdvancedCommand(const IAdvancedCommand::AdvancedCommandType& type) { return S_FALSE; } - virtual HRESULT AdvancedCommand(IAdvancedCommand* command) { return S_FALSE; } + virtual void put_BrushGradInfo(void* pGradInfo) + { + UNUSED_VARIABLE(pGradInfo); + } + virtual void put_BlendMode(const unsigned int& nBlendMode) + { + UNUSED_VARIABLE(nBlendMode); + } }; #define PROPERTY_RENDERER(NameBase, Name, Type) \ - STDMETHOD(get_##NameBase##Name)(Type* pVal) \ - { \ - if (NULL == pVal) \ - return S_FALSE; \ - *pVal = m_o##NameBase.##Name; \ - return S_OK; \ - } \ - STDMETHOD(put_##NameBase##Name)(Type Val) \ - { \ - m_o##NameBase.##Name = Val; \ - return S_OK; \ - } + STDMETHOD(get_##NameBase##Name)(Type* pVal) \ + { \ + if (NULL == pVal) \ + return S_FALSE; \ + *pVal = m_o##NameBase.##Name; \ + return S_OK; \ + } \ + STDMETHOD(put_##NameBase##Name)(Type Val) \ + { \ + m_o##NameBase.##Name = Val; \ + return S_OK; \ + } // exapmle: // PROPERTY_RENDERER(Pen, Color, LONG) diff --git a/DesktopEditor/graphics/ImageFilesCache.h b/DesktopEditor/graphics/ImageFilesCache.h index 5f0feee20ba..70118e0349f 100644 --- a/DesktopEditor/graphics/ImageFilesCache.h +++ b/DesktopEditor/graphics/ImageFilesCache.h @@ -38,7 +38,7 @@ #include "../common/File.h" #ifndef GRAPHICS_DISABLE_METAFILE -#include "../raster/Metafile/MetaFile.h" +#include "../raster/Metafile/MetaFileCommon.h" #endif #if defined (GetTempPath) @@ -77,9 +77,11 @@ class CCacheImage : public NSImages::ICacheImage else { std::wstring sTempFile = NSFile::CFileBinary::CreateTempFileWithUniqueName(NSFile::CFileBinary::GetTempPath(), L"AscMetafile_"); - pMetafile->ConvertToRaster(sTempFile.c_str(), 4, 1000, -1); - m_oImage.Create(sTempFile); + //pMetafile->ConvertToRaster(sTempFile.c_str(), 4, 1000, -1); + MetaFile::ConvertToRasterMaxSize(pMetafile, sTempFile.c_str(), 4, 1000); + + m_oImage.Create(sTempFile); NSFile::CFileBinary::Remove(sTempFile); } RELEASEINTERFACE(pMetafile); diff --git a/DesktopEditor/graphics/Matrix.cpp b/DesktopEditor/graphics/Matrix.cpp index c8e1043d8d8..540e9fe2631 100644 --- a/DesktopEditor/graphics/Matrix.cpp +++ b/DesktopEditor/graphics/Matrix.cpp @@ -96,7 +96,7 @@ namespace Aggplus } } - void CMatrix::TransformVectors(PointF* pts, int count) + void CMatrix::TransformVectors(PointF* pts, int count) const { // Store matrix to an array [6] of double double M[6]; m_internal->m_agg_mtx.store_to(M); @@ -111,7 +111,7 @@ namespace Aggplus } } - void CMatrix::TransformPoints(PointF* pts, int count) + void CMatrix::TransformPoints(PointF* pts, int count) const { for (int i = 0; i < count; ++i) { @@ -123,7 +123,7 @@ namespace Aggplus } } - void CMatrix::TransformPoint(double& x, double& y) + void CMatrix::TransformPoint(double& x, double& y) const { m_internal->m_agg_mtx.transform(&x, &y); } @@ -281,7 +281,7 @@ namespace Aggplus return agg::rad2deg(m_internal->m_agg_mtx.rotation()); } - void CMatrix::TransformPoints( PointF* dst, const PointF* src, int count ) + void CMatrix::TransformPoints( PointF* dst, const PointF* src, int count ) const { agg::trans_affine& m = m_internal->m_agg_mtx; for(int i = 0; i < count; ++i) @@ -312,14 +312,14 @@ namespace Aggplus agg::trans_affine& m1 = mm1->m_internal->m_agg_mtx; agg::trans_affine& m2 = mm2->m_internal->m_agg_mtx; - bool bMain = (fabs(m1.sx - m2.sx) < eps && - fabs(m1.sy - m2.sy) < eps && - fabs(m1.shx - m2.shx) < eps && - fabs(m1.shy - m2.shy) < eps) ? true : false; + bool bMain = fabs(m1.sx - m2.sx) < eps && + fabs(m1.sy - m2.sy) < eps && + fabs(m1.shx - m2.shx) < eps && + fabs(m1.shy - m2.shy) < eps; if (!bMain || bIsOnlyMain) return bMain; - return (fabs(m1.tx - m2.tx) < eps && fabs(m1.ty - m2.ty) < eps) ? true : false; + return fabs(m1.tx - m2.tx) < eps && fabs(m1.ty - m2.ty) < eps; } } diff --git a/DesktopEditor/graphics/Matrix.h b/DesktopEditor/graphics/Matrix.h index be917d7db54..bcb4ebc9781 100644 --- a/DesktopEditor/graphics/Matrix.h +++ b/DesktopEditor/graphics/Matrix.h @@ -52,10 +52,10 @@ namespace Aggplus void Shear(double shearX, double shearY, MatrixOrder order = MatrixOrderPrepend); double Determinant() const; - void TransformVectors(PointF* pts, int count); - void TransformPoints(PointF* pts, int count); - void TransformPoint(double& x, double& y); - void TransformPoints(PointF* dst, const PointF* src, int count); + void TransformVectors(PointF* pts, int count) const; + void TransformPoints(PointF* pts, int count) const; + void TransformPoint(double& x, double& y) const; + void TransformPoints(PointF* dst, const PointF* src, int count) const; void Rotate(double angle, MatrixOrder order = MatrixOrderPrepend); void RotateAt(double angle, const PointF ¢er, MatrixOrder order = MatrixOrderPrepend); diff --git a/DesktopEditor/graphics/MetafileToRenderer.cpp b/DesktopEditor/graphics/MetafileToRenderer.cpp index 25b2c7a8aef..4dd5557a2e7 100644 --- a/DesktopEditor/graphics/MetafileToRenderer.cpp +++ b/DesktopEditor/graphics/MetafileToRenderer.cpp @@ -153,13 +153,6 @@ IMetafileToRenderter::IMetafileToRenderter(IRenderer* pRenderer) } IMetafileToRenderter::~IMetafileToRenderter() { - for (std::vector::iterator i = m_arTempFiles.begin(); i != m_arTempFiles.end(); i++) - { - std::wstring sPath = *i; - if (NSFile::CFileBinary::Exists(sPath)) - NSFile::CFileBinary::Remove(sPath); - } - if (m_pPicker) { CMetafileFontPicker* pPicker = (CMetafileFontPicker*)m_pPicker; @@ -234,8 +227,6 @@ std::wstring IMetafileToRenderter::GetImagePath(const std::wstring& sPath) oFrame.put_Data(NULL); sImagePath = sTempFile; } - - m_arTempFiles.push_back(sTempFile); } RELEASEARRAYOBJECTS(pImageBuffer); @@ -924,6 +915,12 @@ namespace NSOnlineOfficeBinToPdf case ctFormField: case ctAnnotField: case ctAnnotFieldDelete: + case ctWidgetsInfo: + case ctShapeStart: + case ctShapeEnd: + case ctPageClear: + case ctPageRotate: + case ctHeadings: { IAdvancedCommand::AdvancedCommandType eAdvancedCommandType = IAdvancedCommand::AdvancedCommandType::Undefined; switch (eCommand) @@ -931,6 +928,12 @@ namespace NSOnlineOfficeBinToPdf case ctFormField: eAdvancedCommandType = IAdvancedCommand::AdvancedCommandType::FormField; break; case ctAnnotField: eAdvancedCommandType = IAdvancedCommand::AdvancedCommandType::Annotaion; break; case ctAnnotFieldDelete: eAdvancedCommandType = IAdvancedCommand::AdvancedCommandType::DeleteAnnot; break; + case ctWidgetsInfo: eAdvancedCommandType = IAdvancedCommand::AdvancedCommandType::WidgetsInfo; break; + case ctShapeStart: eAdvancedCommandType = IAdvancedCommand::AdvancedCommandType::ShapeStart; break; + case ctShapeEnd: eAdvancedCommandType = IAdvancedCommand::AdvancedCommandType::ShapeEnd; break; + case ctPageClear: eAdvancedCommandType = IAdvancedCommand::AdvancedCommandType::PageClear; break; + case ctPageRotate: eAdvancedCommandType = IAdvancedCommand::AdvancedCommandType::PageRotate; break; + case ctHeadings: eAdvancedCommandType = IAdvancedCommand::AdvancedCommandType::Headings; break; default: break; } @@ -1250,6 +1253,11 @@ namespace NSOnlineOfficeBinToPdf case ctFormField: case ctAnnotField: case ctAnnotFieldDelete: + case ctWidgetsInfo: + case ctShapeStart: + case ctShapeEnd: + case ctPageRotate: + case ctHeadings: default: { BYTE* cur = oReader.GetCurrentBuffer(); diff --git a/DesktopEditor/graphics/MetafileToRenderer.h b/DesktopEditor/graphics/MetafileToRenderer.h index ebabee84007..cde5dbd5041 100644 --- a/DesktopEditor/graphics/MetafileToRenderer.h +++ b/DesktopEditor/graphics/MetafileToRenderer.h @@ -49,7 +49,6 @@ class GRAPHICS_DECL IMetafileToRenderter protected: std::wstring m_sTempDir; - std::vector m_arTempFiles; std::wstring m_sThemesDir; std::wstring m_sMediaDir; @@ -182,6 +181,10 @@ namespace NSOnlineOfficeBinToPdf ctDocInfo = 163, ctAnnotField = 164, ctAnnotFieldDelete = 165, + ctWidgetsInfo = 166, + ctShapeStart = 167, + ctShapeEnd = 168, + ctHeadings = 169, ctPageWidth = 200, ctPageHeight = 201, @@ -189,6 +192,9 @@ namespace NSOnlineOfficeBinToPdf ctPageStart = 202, ctPageEnd = 203, + ctPageClear = 207, + ctPageRotate = 208, + // gradients ctGradientFill = 220, diff --git a/DesktopEditor/graphics/MetafileToRendererReader.cpp b/DesktopEditor/graphics/MetafileToRendererReader.cpp index e3532e41353..5ee42acca64 100644 --- a/DesktopEditor/graphics/MetafileToRendererReader.cpp +++ b/DesktopEditor/graphics/MetafileToRendererReader.cpp @@ -57,6 +57,12 @@ namespace NSOnlineOfficeBinToPdf case ctAnnotField: return Read_Command (this, pCorrector); case ctFormField: return Read_Command (this, pCorrector); case ctAnnotFieldDelete: return Read_Command(this, pCorrector); + case ctWidgetsInfo: return Read_Command (this, pCorrector); + case ctShapeStart: return Read_Command (this, pCorrector); + case ctShapeEnd: return new CEmptyComand(IAdvancedCommand::AdvancedCommandType::ShapeEnd); + case ctPageClear: return new CEmptyComand(IAdvancedCommand::AdvancedCommandType::PageClear); + case ctPageRotate: return Read_Command (this, pCorrector); + case ctHeadings: return Read_Command (this, pCorrector); default: break; } diff --git a/DesktopEditor/graphics/MetafileToRendererReader.h b/DesktopEditor/graphics/MetafileToRendererReader.h index 4584dc03efe..8e20572605a 100644 --- a/DesktopEditor/graphics/MetafileToRendererReader.h +++ b/DesktopEditor/graphics/MetafileToRendererReader.h @@ -174,6 +174,13 @@ namespace NSOnlineOfficeBinToPdf int len = 2 * ReadUShort(); return ReadString16(len); } + inline std::string ReadStringA() + { + int len = ReadInt(); + std::string sRes = std::string((char*)m_cur, len); + m_cur += len; + return sRes; + } inline void SkipString16(int len) { Skip(len); diff --git a/DesktopEditor/graphics/Timer.cpp b/DesktopEditor/graphics/Timer.cpp index 832c5910098..a81bbdad8c8 100644 --- a/DesktopEditor/graphics/Timer.cpp +++ b/DesktopEditor/graphics/Timer.cpp @@ -39,8 +39,8 @@ namespace NSTimers { - // CLOCK_MONOTONIC defined ONLY since macOS 10.12!!! (crash on earlier version) - DWORD GetTickCount() + // CLOCK_MONOTONIC defined ONLY since macOS 10.12!!! (crash on earlier version) + DWORD GetTickCount() { #if defined(_WIN32) || defined(_WIN64) || defined(_WIN32_WCE) return ::GetTickCount(); @@ -49,55 +49,55 @@ namespace NSTimers struct timespec ts; clock_gettime(CLOCK_MONOTONIC, &ts); - return (ts.tv_sec * 1000 + (DWORD)(ts.tv_nsec / 1000000)); + return (ts.tv_sec * 1000 + (DWORD)(ts.tv_nsec / 1000000)); #else - //uint64_t nano = mach_absolute_time(); - //return nano / 1000000; - return getUptimeInMilliseconds(); + //uint64_t nano = mach_absolute_time(); + //return nano / 1000000; + return getUptimeInMilliseconds(); #endif #endif } - CTimer::CTimer() : NSThreads::CBaseThread() - { - m_dwInterval = 40; - m_bIsCOMNeed = FALSE; - } - CTimer::~CTimer() - { - } + CTimer::CTimer() : NSThreads::CBaseThread() + { + m_dwInterval = 40; + m_bIsCOMNeed = FALSE; + } + CTimer::~CTimer() + { + } - void CTimer::SetInterval(const DWORD& dwInterval) { m_dwInterval = dwInterval; } - void CTimer::SetCOMNeed(const INT& bIsCOM) { m_bIsCOMNeed = bIsCOM; } + void CTimer::SetInterval(const DWORD& dwInterval) { m_dwInterval = dwInterval; } + void CTimer::SetCOMNeed(const INT& bIsCOM) { m_bIsCOMNeed = bIsCOM; } - DWORD CTimer::ThreadProc() - { + DWORD CTimer::ThreadProc() + { #ifdef _CAN_USE_COM_THREADS - if (m_bIsCOMNeed) - CoInitialize(NULL); + if (m_bIsCOMNeed) + CoInitialize(NULL); #endif - DWORD m_startTime, m_curTime; - m_startTime = NSTimers::GetTickCount(); + DWORD m_startTime, m_curTime; + m_startTime = NSTimers::GetTickCount(); - while (m_bRunThread) - { - m_curTime = NSTimers::GetTickCount(); - while (m_curTime - m_startTime < m_dwInterval) - { - NSThreads::Sleep(10); - if (!m_bRunThread) - break; - m_curTime = NSTimers::GetTickCount(); - } + while (m_bRunThread) + { + m_curTime = NSTimers::GetTickCount(); + while (m_curTime - m_startTime < m_dwInterval) + { + NSThreads::Sleep(10); + if (!m_bRunThread) + break; + m_curTime = NSTimers::GetTickCount(); + } - m_startTime = NSTimers::GetTickCount(); - OnTimer(); - } + m_startTime = NSTimers::GetTickCount(); + OnTimer(); + } #ifdef _CAN_USE_COM_THREADS - if (m_bIsCOMNeed) - CoUninitialize(); + if (m_bIsCOMNeed) + CoUninitialize(); #endif - return 0; - } + return 0; + } } diff --git a/DesktopEditor/graphics/Timer.h b/DesktopEditor/graphics/Timer.h index 5e21823599f..62ef2ba626c 100644 --- a/DesktopEditor/graphics/Timer.h +++ b/DesktopEditor/graphics/Timer.h @@ -41,51 +41,51 @@ namespace NSTimers { - KERNEL_DECL DWORD GetTickCount(); + KERNEL_DECL DWORD GetTickCount(); - class KERNEL_DECL CTimer : public NSThreads::CBaseThread + class KERNEL_DECL CTimer : public NSThreads::CBaseThread { private: DWORD m_dwInterval; - INT m_bIsCOMNeed; + INT m_bIsCOMNeed; public: - CTimer(); - virtual ~CTimer(); + CTimer(); + virtual ~CTimer(); - void SetInterval(const DWORD& dwInterval); - void SetCOMNeed(const INT& bIsCOM); + void SetInterval(const DWORD& dwInterval); + void SetCOMNeed(const INT& bIsCOM); protected: - virtual DWORD ThreadProc(); + virtual DWORD ThreadProc(); virtual void OnTimer() = 0; }; - - inline static unsigned long getUptimeInMilliseconds() - { + + inline static unsigned long getUptimeInMilliseconds() + { #if defined(_IOS) || defined(_MAC) - const int64_t kOneMillion = 1000 * 1000; - static mach_timebase_info_data_t s_timebase_info; - - if (s_timebase_info.denom == 0) { - (void) mach_timebase_info(&s_timebase_info); - } - - // mach_absolute_time() returns billionth of seconds, - // so divide by one million to get milliseconds - return (unsigned long)((mach_absolute_time() * s_timebase_info.numer) / (kOneMillion * s_timebase_info.denom)); + const int64_t kOneMillion = 1000 * 1000; + static mach_timebase_info_data_t s_timebase_info; + + if (s_timebase_info.denom == 0) { + (void) mach_timebase_info(&s_timebase_info); + } + + // mach_absolute_time() returns billionth of seconds, + // so divide by one million to get milliseconds + return (unsigned long)((mach_absolute_time() * s_timebase_info.numer) / (kOneMillion * s_timebase_info.denom)); #endif - + #ifdef __ANDROID__ - struct timespec ts; - clock_gettime(CLOCK_MONOTONIC, &ts); - - return (ts.tv_sec * 1000 + (DWORD)(ts.tv_nsec / 1000000)); + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + + return (ts.tv_sec * 1000 + (DWORD)(ts.tv_nsec / 1000000)); #endif - - return 0; - } + + return 0; + } } #endif diff --git a/DesktopEditor/graphics/aggplustypes.h b/DesktopEditor/graphics/aggplustypes.h index a54310a850d..74b6f83e098 100644 --- a/DesktopEditor/graphics/aggplustypes.h +++ b/DesktopEditor/graphics/aggplustypes.h @@ -123,8 +123,10 @@ class PointF_T PointF_T(T x, T y) : X(x), Y(y) { } //~PointF() { } INT Equals(const PointF_T& point) const { return(X==point.X && Y==point.Y); } + bool IsZero() const noexcept { return X == 0.0 && Y == 0.0; } PointF_T operator+(const PointF_T& point) const { return PointF_T(X + point.X, Y + point.Y); } PointF_T operator-(const PointF_T& point) const { return PointF_T(X - point.X, Y - point.Y); } + PointF_T& operator=(const PointF_T& other) noexcept {X = other.X; Y = other.Y; return *this;} public: T X, Y; }; diff --git a/DesktopEditor/graphics/boolean_operations_math.h b/DesktopEditor/graphics/boolean_operations_math.h new file mode 100644 index 00000000000..ca6297c3e68 --- /dev/null +++ b/DesktopEditor/graphics/boolean_operations_math.h @@ -0,0 +1,435 @@ +#ifndef CLIPMATH_H +#define CLIPMATH_H + +#include "aggplustypes.h" + +#include +#include +#include + +constexpr double EPSILON = 1e-12; +constexpr double POINT_EPSILON = 1e-2; +constexpr double GEOMETRIC_EPSILON = 1e-7; +constexpr double LOCATION_EPSILON = 1e-7; +constexpr double TIME_EPSILON = 1e-8; +constexpr double MACHINE_EPSILON = 1.12e-16; +constexpr double TRIGANOMETRIC_EPSILON = 1e-8; +constexpr double CURVETIME_EPSILON = 1e-8; +constexpr double LINE_EPSILON = 1e-9; +constexpr double MIN = std::numeric_limits::min(); +constexpr double MAX = std::numeric_limits::max(); +const Aggplus::PointD MIN_POINT = Aggplus::PointD(-100000.0, -100000.0); + +const std::vector ABSCISSAS[16] = { + {0.5773502691896257645091488}, + {0,0.7745966692414833770358531}, + {0.3399810435848562648026658,0.8611363115940525752239465}, + {0,0.5384693101056830910363144,0.9061798459386639927976269}, + {0.2386191860831969086305017,0.6612093864662645136613996,0.9324695142031520278123016}, + {0,0.4058451513773971669066064,0.7415311855993944398638648,0.9491079123427585245261897}, + {0.1834346424956498049394761,0.5255324099163289858177390,0.7966664774136267395915539, + 0.9602898564975362316835609}, + {0,0.3242534234038089290385380,0.6133714327005903973087020,0.8360311073266357942994298, + 0.9681602395076260898355762}, + {0.1488743389816312108848260,0.4333953941292471907992659,0.6794095682990244062343274, + 0.8650633666889845107320967,0.9739065285171717200779640}, + {0,0.2695431559523449723315320,0.5190961292068118159257257,0.7301520055740493240934163, + 0.8870625997680952990751578,0.9782286581460569928039380}, + {0.1252334085114689154724414,0.3678314989981801937526915,0.5873179542866174472967024, + 0.7699026741943046870368938,0.9041172563704748566784659,0.9815606342467192506905491}, + {0,0.2304583159551347940655281,0.4484927510364468528779129,0.6423493394403402206439846, + 0.8015780907333099127942065,0.9175983992229779652065478,0.9841830547185881494728294}, + {0.1080549487073436620662447,0.3191123689278897604356718,0.5152486363581540919652907, + 0.6872929048116854701480198,0.8272013150697649931897947,0.9284348836635735173363911, + 0.9862838086968123388415973}, + {0,0.2011940939974345223006283,0.3941513470775633698972074,0.5709721726085388475372267, + 0.7244177313601700474161861,0.8482065834104272162006483,0.9372733924007059043077589, + 0.9879925180204854284895657}, + {0.0950125098376374401853193,0.2816035507792589132304605,0.4580167776572273863424194, + 0.6178762444026437484466718,0.7554044083550030338951012,0.8656312023878317438804679, + 0.9445750230732325760779884,0.9894009349916499325961542} +}; + +const std::vector WEIGHT[16] { + {1}, + {0.8888888888888888888888889,0.5555555555555555555555556}, + {0.6521451548625461426269361,0.3478548451374538573730639}, + {0.5688888888888888888888889,0.4786286704993664680412915,0.2369268850561890875142640}, + {0.4679139345726910473898703,0.3607615730481386075698335,0.1713244923791703450402961}, + {0.4179591836734693877551020,0.3818300505051189449503698,0.2797053914892766679014678, + 0.1294849661688696932706114}, + {0.3626837833783619829651504,0.3137066458778872873379622,0.2223810344533744705443560, + 0.1012285362903762591525314}, + {0.3302393550012597631645251,0.3123470770400028400686304,0.2606106964029354623187429, + 0.1806481606948574040584720,0.0812743883615744119718922}, + {0.2955242247147528701738930,0.2692667193099963550912269,0.2190863625159820439955349, + 0.1494513491505805931457763,0.0666713443086881375935688}, + {0.2729250867779006307144835,0.2628045445102466621806889,0.2331937645919904799185237, + 0.1862902109277342514260976,0.1255803694649046246346943,0.0556685671161736664827537}, + {0.2491470458134027850005624,0.2334925365383548087608499,0.2031674267230659217490645, + 0.1600783285433462263346525,0.1069393259953184309602547,0.0471753363865118271946160}, + {0.2325515532308739101945895,0.2262831802628972384120902,0.2078160475368885023125232, + 0.1781459807619457382800467,0.1388735102197872384636018,0.0921214998377284479144218, + 0.0404840047653158795200216}, + {0.2152638534631577901958764,0.2051984637212956039659241,0.1855383974779378137417166, + 0.1572031671581935345696019,0.1215185706879031846894148,0.0801580871597602098056333, + 0.0351194603317518630318329}, + {0.2025782419255612728806202,0.1984314853271115764561183,0.1861610000155622110268006, + 0.1662692058169939335532009,0.1395706779261543144478048,0.1071592204671719350118695, + 0.0703660474881081247092674,0.0307532419961172683546284}, + {0.1894506104550684962853967,0.1826034150449235888667637,0.1691565193950025381893121, + 0.1495959888165767320815017,0.1246289712555338720524763,0.0951585116824927848099251, + 0.0622535239386478928628438,0.0271524594117540948517806} +}; + +inline double max(const double& v1, const double& v2, const double& v3, const double& v4) +{ + return std::max(std::max(v1, v2), std::max(v3, v4)); +} + +inline double max(const double& v1, const double& v2, const double& v3) +{ + return std::max(std::max(v1, v2), v3); +} + +inline double min(const double& v1, const double& v2, const double& v3, const double& v4) +{ + return std::min(std::min(v1, v2), std::min(v3, v4)); +} + +inline double min(const double& v1, const double& v2, const double& v3) +{ + return std::min(std::min(v1, v2), v3); +} + +inline bool isZero(const double& value) +{ + return value >= -EPSILON && value <= EPSILON; +} + +inline bool isMachineZero(const double& value) +{ + return value >= -MACHINE_EPSILON && value <= MACHINE_EPSILON; +} + +inline bool isInRange(const double& angle, const double& mn, const double& mx) +{ + return (mn < mx) ? (angle > mn && angle < mx) : (angle > mn || angle < mx); +} + +inline double clamp(const double& value, const double& mn, const double& mx) +{ + return value < mn ? mn : value > mx ? mx : value; +} + +inline bool isCollinear(const Aggplus::PointD& p1, const Aggplus::PointD& p2) +{ + return fabs(p1.X * p2.X + p1.Y * p2.Y) <= sqrt((p1.X * p1.X + p1.Y * p1.Y) * (p2.X * p2.X + p2.Y * p2.Y)) * TRIGANOMETRIC_EPSILON; +} + +inline int getIterations(const double& a, const double& b) +{ + return std::max(2, std::min(16, static_cast(ceil(fabs(b - a) * 32)))); +} + +inline double CurveLength(const double& t, const double& ax, const double& bx, const double& cx, + const double& ay, const double& by, const double& cy) +{ + return sqrt((((ax * t) + bx) * t + cx) * (((ax * t) + bx) * t + cx) + (((ay * t) + by) * t + cy) * (((ay * t) + by) * t + cy)); +} + +inline double integrate(const double& ax, const double& bx, const double& cx, const double& ay, + const double& by, const double& cy, const double& a, const double& b, size_t n = 16) +{ + double A = (b - a) * 0.5; + double sum = n & 1 ? CurveLength(A + a, ax, bx, cx, ay, by, cy) : 0.0; + + for (size_t i = 0; i < (n + 1) >> 1; i++) + sum += WEIGHT[n - 2][i] * (CurveLength(A + a + A * ABSCISSAS[n - 2][i], ax, bx, cx, ay, by, cy) + + CurveLength(A + a - A * ABSCISSAS[n - 2][i], ax, bx, cx, ay, by, cy)); + + return A * sum; +} + +inline bool intersect(std::vector v, Aggplus::PointD& res) +{ + v[2] -= v[0]; + v[3] -= v[1]; + v[6] -= v[4]; + v[7] -= v[5]; + + double cross = v[2] * v[7] - v[3] * v[6]; + if (!isMachineZero(cross)) + { + double dx = v[0] - v[4], + dy = v[1] - v[5], + u1 = (v[6] * dy - v[7] * dx) / cross, + u2 = (v[2] * dy - v[3] * dx) / cross, + uMin = -EPSILON, + uMax = 1 + EPSILON; + + if (uMin < u1 && u1 < uMax && uMin < u2 && u2 < uMax) + { + u1 = u1 <= 0 ? 0 : u1 >= 1 ? 1 : u1; + res = Aggplus::PointD(v[0] + u1 * v[2], v[1] + u1 * v[3]); + + return true; + } + } + + return false; +} + +inline void getConvexHull(const double& dq0, const double& dq1, + const double& dq2, const double& dq3, + std::vector& top, + std::vector& bottom) +{ + Aggplus::PointD p0 = Aggplus::PointD(0.0, dq0), + p1 = Aggplus::PointD(1.0 / 3.0, dq1), + p2 = Aggplus::PointD(2.0 / 3.0, dq2), + p3 = Aggplus::PointD(1.0, dq3); + + double dist1 = dq1 - (2.0 * dq0 + dq3) / 3.0, + dist2 = dq2 - (dq0 + 2.0 * dq3) / 3.0; + + if (dist1 * dist2 < 0.0) + { + top.reserve(3); + top.push_back(p0); + top.push_back(p1); + top.push_back(p3); + + bottom.reserve(3); + bottom.push_back(p0); + bottom.push_back(p2); + bottom.push_back(p3); + } + else + { + double distRatio = dist1 / dist2; + if (distRatio >= 2.0) + { + top.reserve(3); + top.push_back(p0); + top.push_back(p1); + top.push_back(p3); + + bottom.reserve(2); + bottom.push_back(p0); + bottom.push_back(p3); + } + else if (distRatio <= 0.5) + { + top.reserve(3); + top.push_back(p0); + top.push_back(p2); + top.push_back(p3); + + bottom.reserve(2); + bottom.push_back(p0); + bottom.push_back(p3); + } + else + { + top.reserve(4); + top.push_back(p0); + top.push_back(p1); + top.push_back(p2); + top.push_back(p3); + + bottom.reserve(2); + bottom.push_back(p0); + bottom.push_back(p3); + } + } + + if (dist1 < 0.0 || dist2 < 0.0) + std::swap(top, bottom); +} + +inline double clipConvexHullPart(const std::vector& part, const bool& top, + const double& threshold) +{ + double px = part[0].X, + py = part[0].Y; + for (size_t i = 1; i < part.size(); i++) + { + double qx = part[i].X, + qy = part[i].Y; + + if (top ? qy >= threshold : qy <= threshold) + return qy == threshold ? qx : px + (threshold - py) * (qx - px) / (qy - py); + + px = qx; + py = qy; + } + + return MIN; +} + +inline double clipConvexHull(const std::vector& top, + const std::vector& bottom, + const double& dMin, const double& dMax) +{ + if (top[0].Y < dMin) + return clipConvexHullPart(top, true, dMin); + else if (bottom[0].Y > dMax) + return clipConvexHullPart(bottom, false, dMax); + else + return top[0].X; +} + +inline int binarySearch(const std::vector>& allBounds, + const std::vector& indices, const size_t& coord, const double& value) +{ + int lo = 0, + hi = static_cast(indices.size()); + + while(lo < hi) + { + int mid = (hi + lo) >> 1; + if (allBounds[indices[mid]][coord] < value) + lo = mid + 1; + else + hi = mid; + } + + return lo - 1; +} + +inline double getSignedDistance(const double& px, const double& py, double vx, double vy, + const double& x, const double& y, const bool& asVector) +{ + if (!asVector) + { + vx -= px; + vy -= py; + } + + bool vx0 = vx == 0.0, + vyG = vy > 0.0, + vxL = vx < 0.0, + vy0 = vy == 0.0, + vyGvx = vy > vx; + + double distX = vyG ? x - px : px - x, + distY = vxL ? y - py : py - y, + distGY = vy * sqrt(1.0 + (vx * vx) / (vy * vy)), + distGX = vx * sqrt(1.0 + (vy * vy) / (vx * vx)), + distXY = ((x - px) * vy - (y - py) * vx) / (vyGvx ? distGY : distGX); + + return vx0 ? distX : vy0 ? distY : distXY; +} + +inline double getDistance(const double& x1, const double& y1, const double& x2, const double& y2) +{ + return sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1)); +} + +inline double getDistance(const Aggplus::PointD& point1, const Aggplus::PointD& point2) +{ + return getDistance(point1.X, point1.Y, point2.X, point2.Y); +} + +inline std::pair split(const double& v) +{ + double x = v * 134217729.0, + y = v - x, + hi = y + x, + lo = v - hi; + + return std::pair(hi, lo); +} + +inline double getDiscriminant(const double& a, const double& b, const double& c) +{ + double D = b * b - a * c, + E = b * b + a * c; + + if (fabs(D) * 3 < E) + { + std::pair ad = split(a), + bd = split(b), + cd = split(c); + + double p = b * b, + dp = (bd.first * bd.first - + p + 2 * bd.first * bd.second) + + bd.second * bd.second, + q = a * c, + dq = (ad.first * cd.first - + q + ad.first * cd.second + + ad.second * cd.first) + + ad.second * cd.second; + + D = (p - q) + (dp - dq); + } + + return D; +} + +inline int solveQuadratic(double a, double b, double c, std::vector& roots, + const double& mn, const double& mx) +{ + double x1 = MAX, x2 = MAX; + if (fabs(a) < EPSILON) + { + if (fabs(b) < EPSILON) + return fabs(c) < EPSILON ? -1 : 0; + x1 = -c / b; + } + else + { + b *= -0.5; + + double D = getDiscriminant(a, b, c); + if (D != 0 && fabs(D) < MACHINE_EPSILON) + { + double f = max(fabs(a), fabs(b), fabs(c)); + if ((f != 0) && (f < 1e-8 || f < 1e8)) + { + f = pow(2, -round(log2(f))); + a *= f; + b *= f; + c *= f; + D = getDiscriminant(a, b, c); + } + } + + if (D >= -MACHINE_EPSILON) + { + double Q = D < 0 ? 0 : sqrt(D), + R = b + (b < 0 ? -Q : Q); + if (R == 0) + { + x1 = c / a; + x2 = -x1; + } + else + { + x1 = R / a; + x2 = c / R; + } + } + } + + int count = 0; + double minB = mn - EPSILON, + maxB = mx + EPSILON; + if (x1 != MAX && x1 > minB && x1 < maxB) + { + roots.push_back(clamp(x1, mn, mx)); + count++; + } + + if (x2 != x1 && x2 != MAX && x2 > minB && x2 < maxB) + { + roots.push_back(clamp(x2, mn, mx)); + count++; + } + + return count; +} + +#endif //CLIPMATH_H diff --git a/DesktopEditor/graphics/commands/AnnotField.cpp b/DesktopEditor/graphics/commands/AnnotField.cpp index 718353fe13e..7569ec5dce7 100644 --- a/DesktopEditor/graphics/commands/AnnotField.cpp +++ b/DesktopEditor/graphics/commands/AnnotField.cpp @@ -32,10 +32,23 @@ #include "./AnnotField.h" #include "../MetafileToRenderer.h" +#include "../../common/File.h" + +// void Set(const BYTE& n) { m_n = n; } +// BYTE Get() const { return m_n; } + +// void Set(const int& n) { m_n = n; } +// int Get() const { return m_n; } + +// void Set(const double& d) { m_d = d; } +// double Get() const { return m_d; } + +// void Set(const std::wstring& ws) { m_ws = ws; } +// const std::wstring& Get() { return m_ws; } CAnnotFieldInfo::CAnnotFieldInfo() : IAdvancedCommand(AdvancedCommandType::Annotaion) { - m_nType = 0; + m_nType = -1; m_nFlag = 0; m_nID = 0; @@ -46,13 +59,11 @@ CAnnotFieldInfo::CAnnotFieldInfo() : IAdvancedCommand(AdvancedCommandType::Annot m_dY1 = 0.0; m_dX2 = 0.0; m_dY2 = 0.0; - m_pBE.first = 0.0; + m_pBE.first = 0; m_pBE.second = 0.0; - m_oBorder.nType = 0; - m_oBorder.dWidth = 0.0; - m_oBorder.dDashesAlternating = 0.0; - m_oBorder.dGaps = 0.0; + m_oBorder.nType = 0; + m_oBorder.dWidth = 0.0; m_pMarkupPr = NULL; m_pTextPr = NULL; @@ -64,6 +75,7 @@ CAnnotFieldInfo::CAnnotFieldInfo() : IAdvancedCommand(AdvancedCommandType::Annot m_pPopupPr = NULL; m_pFreeTextPr = NULL; m_pCaretPr = NULL; + m_pStampPr = NULL; m_pWidgetPr = NULL; } CAnnotFieldInfo::~CAnnotFieldInfo() @@ -78,17 +90,17 @@ CAnnotFieldInfo::~CAnnotFieldInfo() RELEASEOBJECT(m_pPopupPr); RELEASEOBJECT(m_pFreeTextPr); RELEASEOBJECT(m_pCaretPr); + RELEASEOBJECT(m_pStampPr); RELEASEOBJECT(m_pWidgetPr); } void CAnnotFieldInfo::SetType(int nType) { + m_nType = nType; switch (nType) { case 0: { - m_nType = 15; - RELEASEOBJECT(m_pMarkupPr); m_pMarkupPr = new CAnnotFieldInfo::CMarkupAnnotPr(); @@ -98,8 +110,6 @@ void CAnnotFieldInfo::SetType(int nType) } case 2: { - m_nType = 13; - RELEASEOBJECT(m_pMarkupPr); m_pMarkupPr = new CAnnotFieldInfo::CMarkupAnnotPr(); @@ -109,8 +119,6 @@ void CAnnotFieldInfo::SetType(int nType) } case 3: { - m_nType = 9; - RELEASEOBJECT(m_pMarkupPr); m_pMarkupPr = new CAnnotFieldInfo::CMarkupAnnotPr(); @@ -121,8 +129,6 @@ void CAnnotFieldInfo::SetType(int nType) case 4: case 5: { - m_nType = 11; - RELEASEOBJECT(m_pMarkupPr); m_pMarkupPr = new CAnnotFieldInfo::CMarkupAnnotPr(); @@ -133,8 +139,6 @@ void CAnnotFieldInfo::SetType(int nType) case 6: case 7: { - m_nType = 12; - RELEASEOBJECT(m_pMarkupPr); m_pMarkupPr = new CAnnotFieldInfo::CMarkupAnnotPr(); @@ -147,8 +151,6 @@ void CAnnotFieldInfo::SetType(int nType) case 10: case 11: { - m_nType = 10; - RELEASEOBJECT(m_pMarkupPr); m_pMarkupPr = new CAnnotFieldInfo::CMarkupAnnotPr(); @@ -156,10 +158,17 @@ void CAnnotFieldInfo::SetType(int nType) m_pTextMarkupPr = new CAnnotFieldInfo::CTextMarkupAnnotPr(); break; } - case 13: + case 12: { - m_nType = 14; + RELEASEOBJECT(m_pMarkupPr); + m_pMarkupPr = new CAnnotFieldInfo::CMarkupAnnotPr(); + RELEASEOBJECT(m_pStampPr); + m_pStampPr = new CAnnotFieldInfo::CStampAnnotPr(); + break; + } + case 13: + { RELEASEOBJECT(m_pMarkupPr); m_pMarkupPr = new CAnnotFieldInfo::CMarkupAnnotPr(); @@ -169,8 +178,6 @@ void CAnnotFieldInfo::SetType(int nType) } case 14: { - m_nType = 8; - RELEASEOBJECT(m_pMarkupPr); m_pMarkupPr = new CAnnotFieldInfo::CMarkupAnnotPr(); @@ -180,8 +187,6 @@ void CAnnotFieldInfo::SetType(int nType) } case 15: { - m_nType = 24; - RELEASEOBJECT(m_pPopupPr); m_pPopupPr = new CAnnotFieldInfo::CPopupAnnotPr(); break; @@ -195,110 +200,499 @@ void CAnnotFieldInfo::SetType(int nType) case 32: case 33: { - m_nType = nType - 26; - RELEASEOBJECT(m_pWidgetPr); m_pWidgetPr = new CAnnotFieldInfo::CWidgetAnnotPr(nType); break; } } } -bool CAnnotFieldInfo::IsValid() const -{ - return (m_nType != 0); -} -void CAnnotFieldInfo::SetBounds(const double& dX1, const double& dY1, const double& dX2, const double& dY2) -{ - m_dX1 = dX1; - m_dY1 = dY1; - m_dX2 = dX2; - m_dY2 = dY2; -} -void CAnnotFieldInfo::GetBounds(double& dX1, double& dY1, double& dX2, double& dY2) const +void CAnnotFieldInfo::GetBounds(double& dX1, double& dY1, double& dX2, double& dY2) { dX1 = m_dX1; dY1 = m_dY1; dX2 = m_dX2; dY2 = m_dY2; } -void CAnnotFieldInfo::SetBorder(BYTE nType, double dWidth, double dDashesAlternating, double dGaps) -{ - m_oBorder.nType = nType; - m_oBorder.dWidth = dWidth; - m_oBorder.dDashesAlternating = dDashesAlternating; - m_oBorder.dGaps = dGaps; -} -void CAnnotFieldInfo::GetBorder(BYTE& nType, double& dWidth, double& dDashesAlternating, double& dGaps) +void CAnnotFieldInfo::GetBorder(BYTE& nType, double& dWidth, std::vector& arrDash) { nType = m_oBorder.nType; dWidth = m_oBorder.dWidth; - dDashesAlternating = m_oBorder.dDashesAlternating; - dGaps = m_oBorder.dGaps; + arrDash = m_oBorder.arrDash; +} +int CAnnotFieldInfo::GetFlag() const { return m_nFlag; } +int CAnnotFieldInfo::GetID() const { return m_nID; } +int CAnnotFieldInfo::GetAnnotFlag() const { return m_nAnnotFlag; } +int CAnnotFieldInfo::GetPage() const { return m_nPage; } +void CAnnotFieldInfo::GetBE(BYTE& nS, double& dI) { nS = m_pBE.first; dI = m_pBE.second; } +BYTE* CAnnotFieldInfo::GetRender(LONG& nLen) +{ + nLen = m_nRenderLen; + return m_pRender; } +const std::wstring& CAnnotFieldInfo::GetNM() { return m_wsNM; } +const std::wstring& CAnnotFieldInfo::GetLM() { return m_wsLM; } +const std::wstring& CAnnotFieldInfo::GetOUserID() { return m_wsOUserID; } +const std::wstring& CAnnotFieldInfo::GetContents() { return m_wsContents; } +const std::vector& CAnnotFieldInfo::GetC() { return m_arrC; } -// Common bool CAnnotFieldInfo::IsWidget() const { - return (m_nType < 8); + return (m_nType >= 26); } bool CAnnotFieldInfo::IsButtonWidget() const { - return (m_nType == 1 || m_nType == 2 || m_nType == 3); + return (m_nType == 27 || m_nType == 28 || m_nType == 29); } bool CAnnotFieldInfo::IsTextWidget() const { - return (m_nType == 4); + return (m_nType == 30); } bool CAnnotFieldInfo::IsChoiceWidget() const { - return (m_nType == 5 || m_nType == 6); + return (m_nType == 31 || m_nType == 32); } bool CAnnotFieldInfo::IsSignatureWidget() const { - return (m_nType == 7); + return (m_nType == 33); } bool CAnnotFieldInfo::IsMarkup() const { - return (m_nType > 6 && m_nType < 24); + return ((m_nType >= 0 && m_nType <= 17 && m_nType != 1 && m_nType != 15) || m_nType == 25); } bool CAnnotFieldInfo::IsText() const { - return (m_nType == 15); + return (m_nType == 0); } bool CAnnotFieldInfo::IsInk() const { - return (m_nType == 8); + return (m_nType == 14); } bool CAnnotFieldInfo::IsLine() const { - return (m_nType == 9); + return (m_nType == 3); } bool CAnnotFieldInfo::IsTextMarkup() const { - return (m_nType == 10); + return (m_nType >= 8 && m_nType <= 11); } bool CAnnotFieldInfo::IsSquareCircle() const { - return (m_nType == 11); + return (m_nType == 4 || m_nType == 5); } bool CAnnotFieldInfo::IsPolygonLine() const { - return (m_nType == 12); + return (m_nType == 6 || m_nType == 7); } bool CAnnotFieldInfo::IsPopup() const { - return (m_nType == 24); + return (m_nType == 15); } bool CAnnotFieldInfo::IsFreeText() const { - return (m_nType == 13); + return (m_nType == 2); } bool CAnnotFieldInfo::IsCaret() const { - return (m_nType == 14); + return (m_nType == 13); +} +bool CAnnotFieldInfo::IsStamp() const +{ + return (m_nType == 12); +} + +CAnnotFieldInfo::CMarkupAnnotPr* CAnnotFieldInfo::GetMarkupAnnotPr() { return m_pMarkupPr; } +CAnnotFieldInfo::CTextAnnotPr* CAnnotFieldInfo::GetTextAnnotPr() { return m_pTextPr; } +CAnnotFieldInfo::CInkAnnotPr* CAnnotFieldInfo::GetInkAnnotPr() { return m_pInkPr; } +CAnnotFieldInfo::CLineAnnotPr* CAnnotFieldInfo::GetLineAnnotPr() { return m_pLinePr; } +CAnnotFieldInfo::CTextMarkupAnnotPr* CAnnotFieldInfo::GetTextMarkupAnnotPr() { return m_pTextMarkupPr; } +CAnnotFieldInfo::CSquareCircleAnnotPr* CAnnotFieldInfo::GetSquareCircleAnnotPr() { return m_pSquareCirclePr; } +CAnnotFieldInfo::CPolygonLineAnnotPr* CAnnotFieldInfo::GetPolygonLineAnnotPr() { return m_pPolygonLinePr; } +CAnnotFieldInfo::CPopupAnnotPr* CAnnotFieldInfo::GetPopupAnnotPr() { return m_pPopupPr; } +CAnnotFieldInfo::CFreeTextAnnotPr* CAnnotFieldInfo::GetFreeTextAnnotPr() { return m_pFreeTextPr; } +CAnnotFieldInfo::CCaretAnnotPr* CAnnotFieldInfo::GetCaretAnnotPr() { return m_pCaretPr; } +CAnnotFieldInfo::CStampAnnotPr* CAnnotFieldInfo::GetStampAnnotPr() { return m_pStampPr; } +CAnnotFieldInfo::CWidgetAnnotPr* CAnnotFieldInfo::GetWidgetAnnotPr() { return m_pWidgetPr; } + +bool CAnnotFieldInfo::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetafileToRenderter* pCorrector) +{ + BYTE nType = pReader->ReadByte(); + SetType(nType); + + m_nID = pReader->ReadInt(); + m_nAnnotFlag = pReader->ReadInt(); + m_nPage = pReader->ReadInt(); + + m_dX1 = pReader->ReadDouble(); + m_dY1 = pReader->ReadDouble(); + m_dX2 = pReader->ReadDouble(); + m_dY2 = pReader->ReadDouble(); + + int nFlags = pReader->ReadInt(); + m_nFlag = nFlags; + + if (nFlags & (1 << 0)) + m_wsNM = pReader->ReadString(); + if (nFlags & (1 << 1)) + m_wsContents = pReader->ReadString(); + if (nFlags & (1 << 2)) + { + m_pBE.first = pReader->ReadByte(); + m_pBE.second = pReader->ReadDouble(); + } + if (nFlags & (1 << 3)) + { + int n = pReader->ReadInt(); + for (int i = 0; i < n; ++i) + m_arrC.push_back(pReader->ReadDouble()); + } + if (nFlags & (1 << 4)) + { + m_oBorder.nType = pReader->ReadByte(); + m_oBorder.dWidth = pReader->ReadDouble(); + if (m_oBorder.nType == 2) + { + int n = pReader->ReadInt(); + for (int i = 0; i < n; ++i) + m_oBorder.arrDash.push_back(pReader->ReadDouble()); + } + } + if (nFlags & (1 << 5)) + m_wsLM = pReader->ReadString(); + if (nFlags & (1 << 6)) + { + m_nRenderLen = pReader->ReadInt() - 4; + m_pRender = pReader->GetCurrentBuffer(); + pReader->Skip(m_nRenderLen); + } + if (nFlags & (1 << 7)) + m_wsOUserID = pReader->ReadString(); + + if (IsMarkup()) + { + CAnnotFieldInfo::CMarkupAnnotPr* pPr = GetMarkupAnnotPr(); + + nFlags = pReader->ReadInt(); + pPr->Read(pReader, nFlags); + + if (IsText()) + m_pTextPr->Read(pReader, nFlags); + else if (IsInk()) + m_pInkPr->Read(pReader); + else if (IsLine()) + m_pLinePr->Read(pReader, nFlags); + else if (IsTextMarkup()) + m_pTextMarkupPr->Read(pReader, nType); + else if (IsSquareCircle()) + m_pSquareCirclePr->Read(pReader, nType, nFlags); + else if (IsPolygonLine()) + m_pPolygonLinePr->Read(pReader, nType, nFlags); + else if (IsFreeText()) + m_pFreeTextPr->Read(pReader, nFlags); + else if (IsCaret()) + m_pCaretPr->Read(pReader, nFlags); + else if (IsStamp()) + m_pStampPr->Read(pReader, nFlags); + } + else if (IsPopup()) + m_pPopupPr->Read(pReader); + else if (IsWidget()) + m_pWidgetPr->Read(pReader, nType); + + return m_nType != -1; +} + +CAnnotFieldInfo::CMarkupAnnotPr::~CMarkupAnnotPr() +{ + for (int i = 0; i < m_arrRC.size(); ++i) + RELEASEOBJECT(m_arrRC[i]); +} +BYTE CAnnotFieldInfo::CMarkupAnnotPr::GetRT() const { return m_nRT; } +int CAnnotFieldInfo::CMarkupAnnotPr::GetFlag() const { return m_nFlag; } +int CAnnotFieldInfo::CMarkupAnnotPr::GetPopupID() const { return m_nPopupID; } +int CAnnotFieldInfo::CMarkupAnnotPr::GetIRTID() const { return m_nIRTID; } +double CAnnotFieldInfo::CMarkupAnnotPr::GetCA() const { return m_dCA; } +const std::wstring& CAnnotFieldInfo::CMarkupAnnotPr::GetT() { return m_wsT; } +const std::wstring& CAnnotFieldInfo::CMarkupAnnotPr::GetCD() { return m_wsCD; } +const std::wstring& CAnnotFieldInfo::CMarkupAnnotPr::GetSubj() { return m_wsSubj; } +const std::vector& CAnnotFieldInfo::CMarkupAnnotPr::GetRC() { return m_arrRC; } +void CAnnotFieldInfo::CMarkupAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, int nFlags) +{ + m_nFlag = nFlags; + if (nFlags & (1 << 0)) + m_nPopupID = pReader->ReadInt(); + if (nFlags & (1 << 1)) + m_wsT = pReader->ReadString(); + if (nFlags & (1 << 2)) + m_dCA = pReader->ReadDouble(); + if (nFlags & (1 << 3)) + { + int nFont = pReader->ReadInt(); + for (int i = 0; i < nFont; ++i) + { + CFontData* pFont = new CFontData(); + pFont->nAlignment = pReader->ReadByte(); + pFont->nFontFlag = pReader->ReadInt(); + if (pFont->nFontFlag & (1 << 5)) + pFont->dVAlign = pReader->ReadDouble(); + if (pFont->nFontFlag & (1 << 6)) + pFont->sActualFont = pReader->ReadString(); + pFont->dFontSise = pReader->ReadDouble(); + pFont->dColor[0] = pReader->ReadDouble(); + pFont->dColor[1] = pReader->ReadDouble(); + pFont->dColor[2] = pReader->ReadDouble(); + pFont->sFontFamily = pReader->ReadString(); + pFont->sText = pReader->ReadString(); + m_arrRC.push_back(pFont); + } + } + if (nFlags & (1 << 4)) + m_wsCD = pReader->ReadString(); + if (nFlags & (1 << 5)) + m_nIRTID = pReader->ReadInt(); + if (nFlags & (1 << 6)) + m_nRT = pReader->ReadByte(); + if (nFlags & (1 << 7)) + m_wsSubj = pReader->ReadString(); +} + +CAnnotFieldInfo::CTextAnnotPr::CTextAnnotPr() : m_bOpen(false), m_nName(2), m_nState(7), m_nStateModel(2) {} +bool CAnnotFieldInfo::CTextAnnotPr::IsOpen() const { return m_bOpen; } +BYTE CAnnotFieldInfo::CTextAnnotPr::GetName() const { return m_nName; } +BYTE CAnnotFieldInfo::CTextAnnotPr::GetState() const { return m_nState; } +BYTE CAnnotFieldInfo::CTextAnnotPr::GetStateModel() const { return m_nStateModel; } +void CAnnotFieldInfo::CTextAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, int nFlags) +{ + m_bOpen = nFlags & (1 << 15); + if (nFlags & (1 << 16)) + m_nName = pReader->ReadByte(); + if (nFlags & (1 << 17)) + m_nStateModel = pReader->ReadByte(); + if (nFlags & (1 << 18)) + m_nState = pReader->ReadByte(); +} + +const std::vector< std::vector >& CAnnotFieldInfo::CInkAnnotPr::GetInkList() { return m_arrInkList; } +void CAnnotFieldInfo::CInkAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader) +{ + int n = pReader->ReadInt(); + for (int i = 0; i < n; ++i) + { + std::vector arrLine; + int m = pReader->ReadInt(); + for (int j = 0; j < m; ++j) + arrLine.push_back(pReader->ReadDouble()); + if (!arrLine.empty()) + m_arrInkList.push_back(arrLine); + } +} + +bool CAnnotFieldInfo::CLineAnnotPr::IsCap() const { return m_bCap; } +BYTE CAnnotFieldInfo::CLineAnnotPr::GetIT() const { return m_nIT; } +BYTE CAnnotFieldInfo::CLineAnnotPr::GetCP() const { return m_nCP; } +double CAnnotFieldInfo::CLineAnnotPr::GetLL() const { return m_dLL; } +double CAnnotFieldInfo::CLineAnnotPr::GetLLE() const { return m_dLLE; } +double CAnnotFieldInfo::CLineAnnotPr::GetLLO() const { return m_dLLO; } +void CAnnotFieldInfo::CLineAnnotPr::GetLE(BYTE& nLE1, BYTE& nLE2) { nLE1 = m_nLE[0]; nLE2 = m_nLE[1]; } +void CAnnotFieldInfo::CLineAnnotPr::GetL(double& dL1, double& dL2, double& dL3, double& dL4) { dL1 = m_dL[0]; dL2 = m_dL[1]; dL3 = m_dL[2]; dL4 = m_dL[3]; } +void CAnnotFieldInfo::CLineAnnotPr::GetCO(double& dCO1, double& dCO2) { dCO1 = m_dCO[0]; dCO2 = m_dCO[1]; } +const std::vector& CAnnotFieldInfo::CLineAnnotPr::GetIC() { return m_arrIC; } +void CAnnotFieldInfo::CLineAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, int nFlags) +{ + m_dL[0] = pReader->ReadDouble(); + m_dL[1] = pReader->ReadDouble(); + m_dL[2] = pReader->ReadDouble(); + m_dL[3] = pReader->ReadDouble(); + + if (nFlags & (1 << 15)) + { + m_nLE[0] = pReader->ReadByte(); + m_nLE[1] = pReader->ReadByte(); + } + if (nFlags & (1 << 16)) + { + int n = pReader->ReadInt(); + for (int i = 0; i < n; ++i) + m_arrIC.push_back(pReader->ReadDouble()); + } + if (nFlags & (1 << 17)) + m_dLL = pReader->ReadDouble(); + if (nFlags & (1 << 18)) + m_dLLE = pReader->ReadDouble(); + m_bCap = nFlags & (1 << 19); + if (nFlags & (1 << 20)) + m_nIT = pReader->ReadByte(); + if (nFlags & (1 << 21)) + m_dLLO = pReader->ReadDouble(); + if (nFlags & (1 << 22)) + m_nCP = pReader->ReadByte(); + if (nFlags & (1 << 23)) + { + m_dCO[0] = pReader->ReadDouble(); + m_dCO[1] = pReader->ReadDouble(); + } +} + +BYTE CAnnotFieldInfo::CTextMarkupAnnotPr::GetSubtype() const { return m_nSubtype; } +const std::vector& CAnnotFieldInfo::CTextMarkupAnnotPr::GetQuadPoints() { return m_arrQuadPoints; } +void CAnnotFieldInfo::CTextMarkupAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, BYTE nType) +{ + m_nSubtype = nType; + int n = pReader->ReadInt(); + for (int i = 0; i < n; ++i) + m_arrQuadPoints.push_back(pReader->ReadDouble()); +} + +BYTE CAnnotFieldInfo::CSquareCircleAnnotPr::GetSubtype() const { return m_nSubtype; } +void CAnnotFieldInfo::CSquareCircleAnnotPr::GetRD(double& dRD1, double& dRD2, double& dRD3, double& dRD4) { dRD1 = m_dRD[0]; dRD2 = m_dRD[1]; dRD3 = m_dRD[2]; dRD4 = m_dRD[3]; } +const std::vector& CAnnotFieldInfo::CSquareCircleAnnotPr::GetIC() { return m_arrIC; } +void CAnnotFieldInfo::CSquareCircleAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, BYTE nType, int nFlags) +{ + m_nSubtype = nType; + if (nFlags & (1 << 15)) + { + m_dRD[0] = pReader->ReadDouble(); + m_dRD[1] = pReader->ReadDouble(); + m_dRD[2] = pReader->ReadDouble(); + m_dRD[3] = pReader->ReadDouble(); + } + if (nFlags & (1 << 16)) + { + int n = pReader->ReadInt(); + for (int i = 0; i < n; ++i) + m_arrIC.push_back(pReader->ReadDouble()); + } +} + +BYTE CAnnotFieldInfo::CPolygonLineAnnotPr::GetIT() const { return m_nIT; } +BYTE CAnnotFieldInfo::CPolygonLineAnnotPr::GetSubtype() const { return m_nSubtype; } +void CAnnotFieldInfo::CPolygonLineAnnotPr::GetLE(BYTE& nLE1, BYTE& nLE2) { nLE1 = m_nLE[0]; nLE2 = m_nLE[1]; } +const std::vector& CAnnotFieldInfo::CPolygonLineAnnotPr::GetIC() { return m_arrIC; } +const std::vector& CAnnotFieldInfo::CPolygonLineAnnotPr::GetVertices() { return m_arrVertices; } +void CAnnotFieldInfo::CPolygonLineAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, BYTE nType, int nFlags) +{ + int n = pReader->ReadInt(); + for (int i = 0; i < n; ++i) + m_arrVertices.push_back(pReader->ReadDouble()); + + m_nSubtype = nType; + if (nFlags & (1 << 15)) + { + m_nLE[0] = pReader->ReadByte(); + m_nLE[1] = pReader->ReadByte(); + } + if (nFlags & (1 << 16)) + { + int n = pReader->ReadInt(); + for (int i = 0; i < n; ++i) + m_arrIC.push_back(pReader->ReadDouble()); + } + if (nFlags & (1 << 20)) + m_nIT = pReader->ReadByte(); +} + +BYTE CAnnotFieldInfo::CFreeTextAnnotPr::GetQ() const { return m_nQ; } +BYTE CAnnotFieldInfo::CFreeTextAnnotPr::GetIT() const { return m_nIT; } +BYTE CAnnotFieldInfo::CFreeTextAnnotPr::GetLE() const { return m_nLE; } +int CAnnotFieldInfo::CFreeTextAnnotPr::GetRotate() { return m_nRotate; } +const std::wstring& CAnnotFieldInfo::CFreeTextAnnotPr::GetDS() { return m_wsDS; } +void CAnnotFieldInfo::CFreeTextAnnotPr::GetRD(double& dRD1, double& dRD2, double& dRD3, double& dRD4) { dRD1 = m_dRD[0]; dRD2 = m_dRD[1]; dRD3 = m_dRD[2]; dRD4 = m_dRD[3]; } +const std::vector& CAnnotFieldInfo::CFreeTextAnnotPr::GetCL() { return m_arrCL; } +const std::vector& CAnnotFieldInfo::CFreeTextAnnotPr::GetIC() { return m_arrIC; } +void CAnnotFieldInfo::CFreeTextAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, int nFlags) +{ + m_nQ = pReader->ReadByte(); + m_nRotate = pReader->ReadInt(); + if (nFlags & (1 << 15)) + { + m_dRD[0] = pReader->ReadDouble(); + m_dRD[1] = pReader->ReadDouble(); + m_dRD[2] = pReader->ReadDouble(); + m_dRD[3] = pReader->ReadDouble(); + } + if (nFlags & (1 << 16)) + { + int n = pReader->ReadInt(); + for (int i = 0; i < n; ++i) + m_arrCL.push_back(pReader->ReadDouble()); + } + if (nFlags & (1 << 17)) + m_wsDS = pReader->ReadString(); + if (nFlags & (1 << 18)) + m_nLE = pReader->ReadByte(); + if (nFlags & (1 << 20)) + m_nIT = pReader->ReadByte(); + if (nFlags & (1 << 21)) + { + int n = pReader->ReadInt(); + for (int i = 0; i < n; ++i) + m_arrIC.push_back(pReader->ReadDouble()); + } } +BYTE CAnnotFieldInfo::CCaretAnnotPr::GetSy() const { return m_nSy; } +void CAnnotFieldInfo::CCaretAnnotPr::GetRD(double& dRD1, double& dRD2, double& dRD3, double& dRD4) { dRD1 = m_dRD[0]; dRD2 = m_dRD[1]; dRD3 = m_dRD[2]; dRD4 = m_dRD[3]; } +void CAnnotFieldInfo::CCaretAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, int nFlags) +{ + if (nFlags & (1 << 15)) + { + m_dRD[0] = pReader->ReadDouble(); + m_dRD[1] = pReader->ReadDouble(); + m_dRD[2] = pReader->ReadDouble(); + m_dRD[3] = pReader->ReadDouble(); + } + if (nFlags & (1 << 16)) + m_nSy = pReader->ReadByte(); +} + +double CAnnotFieldInfo::CStampAnnotPr::GetRotate() { return m_nRotate; } +const std::wstring& CAnnotFieldInfo::CStampAnnotPr::GetName() { return m_wsName; } +void CAnnotFieldInfo::CStampAnnotPr::GetInRect(double& dRD1, double& dRD2, double& dRD3, double& dRD4) { dRD1 = m_dInRect[0]; dRD2 = m_dInRect[1]; dRD3 = m_dInRect[2]; dRD4 = m_dInRect[3]; } +void CAnnotFieldInfo::CStampAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, int nFlags) +{ + m_wsName = pReader->ReadString(); + m_nRotate = pReader->ReadDouble(); + m_dInRect[0] = pReader->ReadDouble(); + m_dInRect[1] = pReader->ReadDouble(); + m_dInRect[2] = pReader->ReadDouble(); + m_dInRect[3] = pReader->ReadDouble(); +} + +bool CAnnotFieldInfo::CPopupAnnotPr::IsOpen() const { return m_bOpen; } +int CAnnotFieldInfo::CPopupAnnotPr::GetFlag() const { return m_nFlag; } +int CAnnotFieldInfo::CPopupAnnotPr::GetParentID() const { return m_nParentID; } +void CAnnotFieldInfo::CPopupAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader) +{ + m_nFlag = pReader->ReadInt(); + m_bOpen = m_nFlag & (1 << 0); + if (m_nFlag & (1 << 1)) + m_nParentID = pReader->ReadInt(); +} + +BYTE CAnnotFieldInfo::CWidgetAnnotPr::GetQ() const { return m_nQ; } +BYTE CAnnotFieldInfo::CWidgetAnnotPr::GetH() const { return m_nH; } +BYTE CAnnotFieldInfo::CWidgetAnnotPr::GetType() const { return m_nType; } +int CAnnotFieldInfo::CWidgetAnnotPr::GetR() const { return m_nR; } +int CAnnotFieldInfo::CWidgetAnnotPr::GetFlag() const { return m_nFlag; } +int CAnnotFieldInfo::CWidgetAnnotPr::GetFlags() const { return m_nFlags; } +int CAnnotFieldInfo::CWidgetAnnotPr::GetParentID() const { return m_nParentID; } +int CAnnotFieldInfo::CWidgetAnnotPr::GetFontStyle() const { return m_nFontStyle; } +double CAnnotFieldInfo::CWidgetAnnotPr::GetFontSize() const { return m_dFS; } +double CAnnotFieldInfo::CWidgetAnnotPr::GetFontSizeAP() const { return m_dFSAP; } +const std::wstring& CAnnotFieldInfo::CWidgetAnnotPr::GetTU() { return m_wsTU; } +const std::wstring& CAnnotFieldInfo::CWidgetAnnotPr::GetDS() { return m_wsDS; } +const std::wstring& CAnnotFieldInfo::CWidgetAnnotPr::GetDV() { return m_wsDV; } +const std::wstring& CAnnotFieldInfo::CWidgetAnnotPr::GetT() { return m_wsT; } +const std::wstring& CAnnotFieldInfo::CWidgetAnnotPr::GetFontName() { return m_wsFN; } +const std::wstring& CAnnotFieldInfo::CWidgetAnnotPr::GetFontKey() { return m_wsFK; } +const std::vector& CAnnotFieldInfo::CWidgetAnnotPr::GetTC() { return m_arrTC; } +const std::vector& CAnnotFieldInfo::CWidgetAnnotPr::GetBC() { return m_arrBC; } +const std::vector& CAnnotFieldInfo::CWidgetAnnotPr::GetBG() { return m_arrBG; } +const std::vector& CAnnotFieldInfo::CWidgetAnnotPr::GetActions() { return m_arrAction; } +CAnnotFieldInfo::CWidgetAnnotPr::CButtonWidgetPr* CAnnotFieldInfo::CWidgetAnnotPr::GetButtonWidgetPr() { return m_pButtonPr; } +CAnnotFieldInfo::CWidgetAnnotPr::CTextWidgetPr* CAnnotFieldInfo::CWidgetAnnotPr::GetTextWidgetPr() { return m_pTextPr; } +CAnnotFieldInfo::CWidgetAnnotPr::CChoiceWidgetPr* CAnnotFieldInfo::CWidgetAnnotPr::GetChoiceWidgetPr() { return m_pChoicePr; } +CAnnotFieldInfo::CWidgetAnnotPr::CSignatureWidgetPr* CAnnotFieldInfo::CWidgetAnnotPr::GetSignatureWidgetPr() { return m_pSignaturePr; } CAnnotFieldInfo::CWidgetAnnotPr::CWidgetAnnotPr(BYTE nType) { m_pButtonPr = NULL; @@ -354,6 +748,8 @@ CAnnotFieldInfo::CWidgetAnnotPr::~CWidgetAnnotPr() RELEASEOBJECT(m_arrAction[i]); } +CAnnotFieldInfo::CWidgetAnnotPr::CActionWidget::CActionWidget() : pNext(NULL) {} +CAnnotFieldInfo::CWidgetAnnotPr::CActionWidget::~CActionWidget() { RELEASEOBJECT(pNext); } CAnnotFieldInfo::CWidgetAnnotPr::CActionWidget* ReadAction(NSOnlineOfficeBinToPdf::CBufferReader* pReader) { CAnnotFieldInfo::CWidgetAnnotPr::CActionWidget* pRes = new CAnnotFieldInfo::CWidgetAnnotPr::CActionWidget(); @@ -416,7 +812,7 @@ CAnnotFieldInfo::CWidgetAnnotPr::CActionWidget* ReadAction(NSOnlineOfficeBinToPd } case 9: // Hide { - pRes->nInt1 = pReader->ReadInt(); + pRes->nKind = pReader->ReadByte(); int n = pReader->ReadInt(); for (int i = 0; i < n; ++i) pRes->arrStr.push_back(pReader->ReadString()); @@ -437,407 +833,270 @@ CAnnotFieldInfo::CWidgetAnnotPr::CActionWidget* ReadAction(NSOnlineOfficeBinToPd return pRes; } - -bool CAnnotFieldInfo::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetafileToRenderter* pCorrector) +void CAnnotFieldInfo::CWidgetAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, BYTE nType) { - BYTE nType = pReader->ReadByte(); - SetType(nType); - SetID(pReader->ReadInt()); - SetAnnotFlag(pReader->ReadInt()); - SetPage(pReader->ReadInt()); + m_wsFN = pReader->ReadString(); + m_dFS = pReader->ReadDouble(); + m_dFSAP = pReader->ReadDouble(); + m_nFontStyle = pReader->ReadInt(); - double dX1 = pReader->ReadDouble(); - double dY1 = pReader->ReadDouble(); - double dX2 = pReader->ReadDouble(); - double dY2 = pReader->ReadDouble(); + int n = pReader->ReadInt(); + for (int i = 0; i < n; ++i) + m_arrTC.push_back(pReader->ReadDouble()); - SetBounds(dX1, dY1, dX2, dY2); + m_nQ = 0; + if (nType != 29 && nType != 28 && nType != 27) + m_nQ = pReader->ReadByte(); + int nWidgetFlag = pReader->ReadInt(); + m_nFlag = nWidgetFlag; int nFlags = pReader->ReadInt(); - SetFlag(nFlags); - + m_nFlags = nFlags; if (nFlags & (1 << 0)) - SetNM(pReader->ReadString()); + m_wsTU = pReader->ReadString(); if (nFlags & (1 << 1)) - SetContents(pReader->ReadString()); + m_wsDS = pReader->ReadString(); if (nFlags & (1 << 2)) + m_wsFK = pReader->ReadString(); + if (nFlags & (1 << 3)) + m_nH = pReader->ReadByte(); + if (nFlags & (1 << 5)) { - BYTE nS = pReader->ReadByte(); - double dI = pReader->ReadDouble(); - SetBE(nS, dI); + int n = pReader->ReadInt(); + for (int i = 0; i < n; ++i) + m_arrBC.push_back(pReader->ReadDouble()); } - if (nFlags & (1 << 3)) + if (nFlags & (1 << 6)) + m_nR = pReader->ReadInt(); + if (nFlags & (1 << 7)) { int n = pReader->ReadInt(); - std::vector arrC; for (int i = 0; i < n; ++i) - arrC.push_back(pReader->ReadDouble()); - SetC(arrC); + m_arrBG.push_back(pReader->ReadDouble()); } - if (nFlags & (1 << 4)) + if (nFlags & (1 << 8)) + m_wsDV = pReader->ReadString(); + if (nFlags & (1 << 17)) + m_nParentID = pReader->ReadInt(); + if (nFlags & (1 << 18)) + m_wsT = pReader->ReadString(); + + // Action + int nAction = pReader->ReadInt(); + for (int i = 0; i < nAction; ++i) { - BYTE nType = pReader->ReadByte(); - double dWidth = pReader->ReadDouble(); - double d1 = 0.0, d2 = 0.0; - if (nType == 2) + std::wstring wsType = pReader->ReadString(); + CAnnotFieldInfo::CWidgetAnnotPr::CActionWidget* pA = ReadAction(pReader); + if (pA) { - d1 = pReader->ReadDouble(); - d2 = pReader->ReadDouble(); + pA->wsType = wsType; + m_arrAction.push_back(pA); } - SetBorder(nType, dWidth, d1, d2); } - if (nFlags & (1 << 5)) - SetLM(pReader->ReadString()); - if (IsMarkup()) + if (nType == 29 || nType == 28 || nType == 27) + m_pButtonPr->Read(pReader, nType, nFlags); + else if (nType == 30) + m_pTextPr->Read(pReader, nFlags, nWidgetFlag); + else if (nType == 31 || nType == 32) + m_pChoicePr->Read(pReader, nFlags); +} + +BYTE CAnnotFieldInfo::CWidgetAnnotPr::CButtonWidgetPr::GetS() const { return m_nS; } +BYTE CAnnotFieldInfo::CWidgetAnnotPr::CButtonWidgetPr::GetTP() const { return m_nTP; } +BYTE CAnnotFieldInfo::CWidgetAnnotPr::CButtonWidgetPr::GetSW() const { return m_nSW; } +BYTE CAnnotFieldInfo::CWidgetAnnotPr::CButtonWidgetPr::GetStyle() const { return m_nStyle; } +int CAnnotFieldInfo::CWidgetAnnotPr::CButtonWidgetPr::GetIFFlag() const { return m_nIFFlag; } +int CAnnotFieldInfo::CWidgetAnnotPr::CButtonWidgetPr::GetI() const { return m_nI; } +int CAnnotFieldInfo::CWidgetAnnotPr::CButtonWidgetPr::GetRI() const { return m_nRI; } +int CAnnotFieldInfo::CWidgetAnnotPr::CButtonWidgetPr::GetIX() const { return m_nIX; } +void CAnnotFieldInfo::CWidgetAnnotPr::CButtonWidgetPr::GetA(double& dA1, double& dA2) { dA1 = m_dA1; dA2 = m_dA2; } +const std::wstring& CAnnotFieldInfo::CWidgetAnnotPr::CButtonWidgetPr::GetV() { return m_wsV; } +const std::wstring& CAnnotFieldInfo::CWidgetAnnotPr::CButtonWidgetPr::GetCA() { return m_wsCA; } +const std::wstring& CAnnotFieldInfo::CWidgetAnnotPr::CButtonWidgetPr::GetRC() { return m_wsRC; } +const std::wstring& CAnnotFieldInfo::CWidgetAnnotPr::CButtonWidgetPr::GetAC() { return m_wsAC; } +const std::wstring& CAnnotFieldInfo::CWidgetAnnotPr::CButtonWidgetPr::GetAP_N_Yes() { return m_wsAP_N_Yes; } +void CAnnotFieldInfo::CWidgetAnnotPr::CButtonWidgetPr::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, BYTE nType, int nFlags) +{ + if (nType == 27) { - CAnnotFieldInfo::CMarkupAnnotPr* pPr = GetMarkupAnnotPr(); + m_nIFFlag = pReader->ReadInt(); + + if (nFlags & (1 << 10)) + m_wsCA = pReader->ReadString(); + if (nFlags & (1 << 11)) + m_wsRC = pReader->ReadString(); + if (nFlags & (1 << 12)) + m_wsAC = pReader->ReadString(); + if (nFlags & (1 << 13)) + m_nTP = pReader->ReadByte(); + + if (m_nIFFlag & (1 << 0)) + { + if (m_nIFFlag & (1 << 1)) + m_nSW = pReader->ReadByte(); + if (m_nIFFlag & (1 << 2)) + m_nS = pReader->ReadByte(); + if (m_nIFFlag & (1 << 3)) + { + m_dA1 = pReader->ReadDouble(); + m_dA2 = pReader->ReadDouble(); + } + } - nFlags = pReader->ReadInt(); - pPr->SetFlag(nFlags); - if (nFlags & (1 << 0)) - pPr->SetPopupID(pReader->ReadInt()); - if (nFlags & (1 << 1)) - pPr->SetT(pReader->ReadString()); - if (nFlags & (1 << 2)) - pPr->SetCA(pReader->ReadDouble()); - if (nFlags & (1 << 3)) - pPr->SetRC(pReader->ReadString()); - if (nFlags & (1 << 4)) - pPr->SetCD(pReader->ReadString()); - if (nFlags & (1 << 5)) - pPr->SetIRTID(pReader->ReadInt()); - if (nFlags & (1 << 6)) - pPr->SetRT(pReader->ReadByte()); - if (nFlags & (1 << 7)) - pPr->SetSubj(pReader->ReadString()); + if (m_nIFFlag & (1 << 5)) + m_nI = pReader->ReadInt(); + if (m_nIFFlag & (1 << 6)) + m_nRI = pReader->ReadInt(); + if (m_nIFFlag & (1 << 7)) + m_nIX = pReader->ReadInt(); } - - if (IsText()) + else { - CAnnotFieldInfo::CTextAnnotPr* pPr = GetTextAnnotPr(); - - pPr->SetOpen(nFlags & (1 << 15)); - if (nFlags & (1 << 16)) - pPr->SetName(pReader->ReadByte()); - if (nFlags & (1 << 17)) - pPr->SetStateModel(pReader->ReadByte()); - if (nFlags & (1 << 18)) - pPr->SetState(pReader->ReadByte()); + if (nFlags & (1 << 9)) + m_wsV = pReader->ReadString(); + m_nStyle = pReader->ReadByte(); + if (nFlags & (1 << 14)) + m_wsAP_N_Yes = pReader->ReadString(); } - else if (IsInk()) +} + +int CAnnotFieldInfo::CWidgetAnnotPr::CTextWidgetPr::GetMaxLen() const { return m_nMaxLen; } +const std::wstring& CAnnotFieldInfo::CWidgetAnnotPr::CTextWidgetPr::GetV() { return m_wsV; } +const std::wstring& CAnnotFieldInfo::CWidgetAnnotPr::CTextWidgetPr::GetRV() { return m_wsRV; } +const std::wstring& CAnnotFieldInfo::CWidgetAnnotPr::CTextWidgetPr::GetAPV() { return m_wsAPV; } +BYTE* CAnnotFieldInfo::CWidgetAnnotPr::CTextWidgetPr::GetRender(LONG& nLen) +{ + nLen = m_nRenderLen; + return m_pRender; +} +void CAnnotFieldInfo::CWidgetAnnotPr::CTextWidgetPr::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, int nFlags, int nWidgetFlag) +{ + if (nFlags & (1 << 9)) + m_wsV = pReader->ReadString(); + if (nFlags & (1 << 10)) + m_nMaxLen = pReader->ReadInt(); + if (nWidgetFlag & (1 << 25)) + m_wsRV = pReader->ReadString(); + if (nFlags & (1 << 12)) + m_wsAPV = pReader->ReadString(); + if (nFlags & (1 << 13)) { - CAnnotFieldInfo::CInkAnnotPr* pPr = GetInkAnnotPr(); + m_nRenderLen = pReader->ReadInt() - 4; + m_pRender = pReader->GetCurrentBuffer(); + pReader->Skip(m_nRenderLen); + } +} +int CAnnotFieldInfo::CWidgetAnnotPr::CChoiceWidgetPr::GetTI() const { return m_nTI; } +const std::wstring& CAnnotFieldInfo::CWidgetAnnotPr::CChoiceWidgetPr::GetV() { return m_wsV; } +const std::wstring& CAnnotFieldInfo::CWidgetAnnotPr::CChoiceWidgetPr::GetAPV() { return m_wsAPV; } +const std::vector& CAnnotFieldInfo::CWidgetAnnotPr::CChoiceWidgetPr::GetI() { return m_arrI; } +const std::vector& CAnnotFieldInfo::CWidgetAnnotPr::CChoiceWidgetPr::GetArrV() { return m_arrV; } +const std::vector< std::pair >& CAnnotFieldInfo::CWidgetAnnotPr::CChoiceWidgetPr::GetOpt() { return m_arrOpt; } +BYTE* CAnnotFieldInfo::CWidgetAnnotPr::CChoiceWidgetPr::GetRender(LONG& nLen) +{ + nLen = m_nRenderLen; + return m_pRender; +} +void CAnnotFieldInfo::CWidgetAnnotPr::CChoiceWidgetPr::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, int nFlags) +{ + if (nFlags & (1 << 9)) + m_wsV = pReader->ReadString(); + if (nFlags & (1 << 10)) + { int n = pReader->ReadInt(); - std::vector< std::vector > arrInkList; for (int i = 0; i < n; ++i) { - std::vector arrLine; - int m = pReader->ReadInt(); - for (int j = 0; j < m; ++j) - arrLine.push_back(pReader->ReadDouble()); - if (!arrLine.empty()) - arrInkList.push_back(arrLine); + std::wstring s1 = pReader->ReadString(); + std::wstring s2 = pReader->ReadString(); + m_arrOpt.push_back(std::make_pair(s1, s2)); } - pPr->SetInkList(arrInkList); } - else if (IsLine()) + if (nFlags & (1 << 11)) + m_nTI = pReader->ReadInt(); + if (nFlags & (1 << 12)) + m_wsAPV = pReader->ReadString(); + if (nFlags & (1 << 13)) { - CAnnotFieldInfo::CLineAnnotPr* pPr = GetLineAnnotPr(); - - double dLX1 = pReader->ReadDouble(); - double dLY1 = pReader->ReadDouble(); - double dLX2 = pReader->ReadDouble(); - double dLY2 = pReader->ReadDouble(); - pPr->SetL(dLX1, dLY1, dLX2, dLY2); - - if (nFlags & (1 << 15)) - { - BYTE nLE1 = pReader->ReadByte(); - BYTE nLE2 = pReader->ReadByte(); - pPr->SetLE(nLE1, nLE2); - } - if (nFlags & (1 << 16)) - { - int n = pReader->ReadInt(); - std::vector arrIC; - for (int i = 0; i < n; ++i) - arrIC.push_back(pReader->ReadDouble()); - pPr->SetIC(arrIC); - } - if (nFlags & (1 << 17)) - pPr->SetLL(pReader->ReadDouble()); - if (nFlags & (1 << 18)) - pPr->SetLLE(pReader->ReadDouble()); - pPr->SetCap(nFlags & (1 << 19)); - if (nFlags & (1 << 20)) - pPr->SetIT(pReader->ReadByte()); - if (nFlags & (1 << 21)) - pPr->SetLLO(pReader->ReadDouble()); - if (nFlags & (1 << 22)) - pPr->SetCP(pReader->ReadByte()); - if (nFlags & (1 << 23)) - { - double dCO1 = pReader->ReadDouble(); - double dCO2 = pReader->ReadDouble(); - pPr->SetCO(dCO1, dCO2); - } - } - else if (IsTextMarkup()) - { - CAnnotFieldInfo::CTextMarkupAnnotPr* pPr = GetTextMarkupAnnotPr(); - - pPr->SetSubtype(nType); - std::vector arrQuadPoints; int n = pReader->ReadInt(); for (int i = 0; i < n; ++i) - arrQuadPoints.push_back(pReader->ReadDouble()); - pPr->SetQuadPoints(arrQuadPoints); + m_arrV.push_back(pReader->ReadString()); } - else if (IsSquareCircle()) + if (nFlags & (1 << 14)) { - CAnnotFieldInfo::CSquareCircleAnnotPr* pPr = GetSquareCircleAnnotPr(); - - pPr->SetSubtype(nType); - if (nFlags & (1 << 15)) - { - double dRD1 = pReader->ReadDouble(); - double dRD2 = pReader->ReadDouble(); - double dRD3 = pReader->ReadDouble(); - double dRD4 = pReader->ReadDouble(); - pPr->SetRD(dRD1, dRD2, dRD3, dRD4); - } - if (nFlags & (1 << 16)) - { - int n = pReader->ReadInt(); - std::vector arrIC; - for (int i = 0; i < n; ++i) - arrIC.push_back(pReader->ReadDouble()); - pPr->SetIC(arrIC); - } - } - else if (IsPolygonLine()) - { - CAnnotFieldInfo::CPolygonLineAnnotPr* pPr = GetPolygonLineAnnotPr(); - int n = pReader->ReadInt(); - std::vector arrVertices; for (int i = 0; i < n; ++i) - arrVertices.push_back(pReader->ReadDouble()); - pPr->SetVertices(arrVertices); - - pPr->SetSubtype(nType); - if (nFlags & (1 << 15)) - { - BYTE nLE1 = pReader->ReadByte(); - BYTE nLE2 = pReader->ReadByte(); - pPr->SetLE(nLE1, nLE2); - } - if (nFlags & (1 << 16)) - { - int n = pReader->ReadInt(); - std::vector arrIC; - for (int i = 0; i < n; ++i) - arrIC.push_back(pReader->ReadDouble()); - pPr->SetIC(arrIC); - } - if (nFlags & (1 << 20)) - pPr->SetIT(pReader->ReadByte()); + m_arrI.push_back(pReader->ReadInt()); } - else if (IsPopup()) + if (nFlags & (1 << 15)) { - CAnnotFieldInfo::CPopupAnnotPr* pPr = GetPopupAnnotPr(); - - nFlags = pReader->ReadInt(); - pPr->SetFlag(nFlags); - pPr->SetOpen(nFlags & (1 << 0)); - if (nFlags & (1 << 1)) - pPr->SetParentID(pReader->ReadInt()); + m_nRenderLen = pReader->ReadInt() - 4; + m_pRender = pReader->GetCurrentBuffer(); + pReader->Skip(m_nRenderLen); } - else if (IsFreeText()) - { - CAnnotFieldInfo::CFreeTextAnnotPr* pPr = GetFreeTextAnnotPr(); +} - pPr->SetQ(pReader->ReadByte()); - if (nFlags & (1 << 15)) - { - double dRD1 = pReader->ReadDouble(); - double dRD2 = pReader->ReadDouble(); - double dRD3 = pReader->ReadDouble(); - double dRD4 = pReader->ReadDouble(); - pPr->SetRD(dRD1, dRD2, dRD3, dRD4); - } - if (nFlags & (1 << 16)) - { - int n = pReader->ReadInt(); - std::vector arrCL; - for (int i = 0; i < n; ++i) - arrCL.push_back(pReader->ReadDouble()); - pPr->SetCL(arrCL); - } - if (nFlags & (1 << 17)) - pPr->SetDS(pReader->ReadString()); - if (nFlags & (1 << 18)) - pPr->SetLE(pReader->ReadByte()); - if (nFlags & (1 << 20)) - pPr->SetIT(pReader->ReadByte()); - } - else if (IsCaret()) - { - CAnnotFieldInfo::CCaretAnnotPr* pPr = GetCaretAnnotPr(); +CAnnotFieldDelete::CAnnotFieldDelete() : IAdvancedCommand(AdvancedCommandType::DeleteAnnot) {} +CAnnotFieldDelete::~CAnnotFieldDelete() {} +int CAnnotFieldDelete::GetID() { return m_nID; } +bool CAnnotFieldDelete::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetafileToRenderter* pCorrector) +{ + m_nID = pReader->ReadInt(); + return true; +} - if (nFlags & (1 << 15)) - { - double dRD1 = pReader->ReadDouble(); - double dRD2 = pReader->ReadDouble(); - double dRD3 = pReader->ReadDouble(); - double dRD4 = pReader->ReadDouble(); - pPr->SetRD(dRD1, dRD2, dRD3, dRD4); - } - if (nFlags & (1 << 16)) - pPr->SetSy(pReader->ReadByte()); - } +CWidgetsInfo::CWidgetsInfo() : IAdvancedCommand(AdvancedCommandType::WidgetsInfo) {} +CWidgetsInfo::~CWidgetsInfo() +{ + for (int i = 0; i < m_arrParents.size(); ++i) + RELEASEOBJECT(m_arrParents[i]); +} +const std::vector& CWidgetsInfo::GetCO() { return m_arrCO; } +const std::vector& CWidgetsInfo::GetButtonImg() { return m_arrButtonImg; } +const std::vector& CWidgetsInfo::GetParents() { return m_arrParents; } +bool CWidgetsInfo::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetafileToRenderter* pCorrector) +{ + int n = pReader->ReadInt(); + for (int i = 0; i < n; ++i) + m_arrCO.push_back(pReader->ReadInt()); - if (IsWidget()) + n = pReader->ReadInt(); + for (int i = 0; i < n; ++i) { - CAnnotFieldInfo::CWidgetAnnotPr* pPr = GetWidgetAnnotPr(); - - int n = pReader->ReadInt(); - std::vector arrTC; - for (int i = 0; i < n; ++i) - arrTC.push_back(pReader->ReadDouble()); - pPr->SetTC(arrTC); - - pPr->SetQ(pReader->ReadByte()); - int nWidgetFlag = pReader->ReadInt(); - pPr->SetFlag(nWidgetFlag); - - int nFlags = pReader->ReadInt(); - pPr->SetFlags(nFlags); + CParent* pParent = new CParent(); + pParent->nID = pReader->ReadInt(); + int nFlags = pReader->ReadInt(); + pParent->nFlags = nFlags; if (nFlags & (1 << 0)) - pPr->SetTU(pReader->ReadString()); + pParent->sName = pReader->ReadString(); if (nFlags & (1 << 1)) - pPr->SetDS(pReader->ReadString()); + pParent->sV = pReader->ReadString(); + if (nFlags & (1 << 2)) + pParent->sDV = pReader->ReadString(); if (nFlags & (1 << 3)) - pPr->SetH(pReader->ReadByte()); - if (nFlags & (1 << 5)) { int n = pReader->ReadInt(); - std::vector arrBC; for (int i = 0; i < n; ++i) - arrBC.push_back(pReader->ReadDouble()); - pPr->SetBC(arrBC); + pParent->arrI.push_back(pReader->ReadInt()); } - if (nFlags & (1 << 6)) - pPr->SetR(pReader->ReadInt()); - if (nFlags & (1 << 7)) + if (nFlags & (1 << 4)) + pParent->nParentID = pReader->ReadInt(); + if (nFlags & (1 << 5)) { int n = pReader->ReadInt(); - std::vector arrBG; for (int i = 0; i < n; ++i) - arrBG.push_back(pReader->ReadDouble()); - pPr->SetBG(arrBG); - } - if (nFlags & (1 << 8)) - pPr->SetDV(pReader->ReadString()); - if (nFlags & (1 << 17)) - pPr->SetParentID(pReader->ReadInt()); - if (nFlags & (1 << 18)) - pPr->SetT(pReader->ReadString()); - - // Action - int nAction = pReader->ReadInt(); - for (int i = 0; i < nAction; ++i) - { - std::wstring wsType = pReader->ReadString(); - CAnnotFieldInfo::CWidgetAnnotPr::CActionWidget* pA = ReadAction(pReader); - if (pA) - { - pA->wsType = wsType; - pPr->AddAction(pA); - } - } - - if (nType == 29 || nType == 28 || nType == 27) - { - CAnnotFieldInfo::CWidgetAnnotPr::CButtonWidgetPr* pPr1 = pPr->GetButtonWidgetPr(); - - int nIFFlags = pReader->ReadInt(); - pPr1->SetIFFlag(nIFFlags); - if (nType == 27) - { - if (nFlags & (1 << 10)) - pPr1->SetCA(pReader->ReadString()); - if (nFlags & (1 << 11)) - pPr1->SetRC(pReader->ReadString()); - if (nFlags & (1 << 12)) - pPr1->SetAC(pReader->ReadString()); - } - else - pPr1->SetS(pReader->ReadByte()); - - if (nFlags & (1 << 13)) - pPr1->SetTP(pReader->ReadByte()); - if (nIFFlags & (1 << 0)) - { - if (nIFFlags & (1 << 1)) - pPr1->SetSW(pReader->ReadByte()); - if (nIFFlags & (1 << 2)) - pPr1->SetS(pReader->ReadByte()); - if (nIFFlags & (1 << 3)) - { - double d1 = pReader->ReadDouble(); - double d2 = pReader->ReadDouble(); - pPr1->SetA(d1, d2); - } - } - if (nFlags & (1 << 14)) - pPr1->SetAP_N_Yes(pReader->ReadString()); - - } - else if (nType == 30) - { - CAnnotFieldInfo::CWidgetAnnotPr::CTextWidgetPr* pPr1 = pPr->GetTextWidgetPr(); - - if (nFlags & (1 << 9)) - pPr1->SetV(pReader->ReadString()); - if (nFlags & (1 << 10)) - pPr1->SetMaxLen(pReader->ReadInt()); - if (nWidgetFlag & (1 << 25)) - pPr1->SetRV(pReader->ReadString()); - } - else if (nType == 31 || nType == 32) - { - CAnnotFieldInfo::CWidgetAnnotPr::CChoiceWidgetPr* pPr1 = pPr->GetChoiceWidgetPr(); - - if (nFlags & (1 << 9)) - pPr1->SetV(pReader->ReadString()); - if (nFlags & (1 << 10)) - { - int n = pReader->ReadInt(); - std::vector< std::pair > arrOpt; - for (int i = 0; i < n; ++i) - { - std::wstring s1 = pReader->ReadString(); - std::wstring s2 = pReader->ReadString(); - arrOpt.push_back(std::make_pair(s2, s1)); - } - pPr1->SetOpt(arrOpt); - } - if (nFlags & (1 << 11)) - pPr1->SetTI(pReader->ReadInt()); + pParent->arrV.push_back(pReader->ReadString()); } + m_arrParents.push_back(pParent); } - return IsValid(); -} - -CAnnotFieldDelete::CAnnotFieldDelete() : IAdvancedCommand(AdvancedCommandType::DeleteAnnot) {} - -bool CAnnotFieldDelete::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetafileToRenderter* pCorrector) -{ - m_nID = pReader->ReadInt(); + n = pReader->ReadInt(); + for (int i = 0; i < n; ++i) + { + std::string sImagePath = pReader->ReadStringA(); + m_arrButtonImg.push_back(pCorrector->GetImagePath(UTF8_TO_U(sImagePath))); + } return true; } diff --git a/DesktopEditor/graphics/commands/AnnotField.h b/DesktopEditor/graphics/commands/AnnotField.h index 8e3a22370f1..49f6bc30750 100644 --- a/DesktopEditor/graphics/commands/AnnotField.h +++ b/DesktopEditor/graphics/commands/AnnotField.h @@ -36,48 +36,31 @@ #include "../MetafileToRendererReader.h" class IMetafileToRenderter; -// void Set(const BYTE& n) { m_n = n; } -// BYTE Get() const { return m_n; } - -// void Set(const int& n) { m_n = n; } -// int Get() const { return m_n; } - -// void Set(const double& d) { m_d = d; } -// double Get() const { return m_d; } - -// void Set(const std::wstring& ws) { m_ws = ws; } -// const std::wstring& Get() const { return m_ws; } - class GRAPHICS_DECL CAnnotFieldInfo : public IAdvancedCommand { public: - class CWidgetAnnotPr + class GRAPHICS_DECL CWidgetAnnotPr { public: - class CButtonWidgetPr + class GRAPHICS_DECL CButtonWidgetPr { public: - void SetS (const BYTE& nS) { m_nS = nS; } - void SetTP(const BYTE& nTP) { m_nTP = nTP; } - void SetSW(const BYTE& nSW) { m_nSW = nSW; } - void SetStyle(const BYTE& nStyle) { m_nStyle = nStyle; } - void SetIFFlag(const int& nIFFlag) { m_nIFFlag = nIFFlag; } - void SetA(const double& dA1, const double& dA2) { m_dA1 = dA1; m_dA2 = dA2; } - void SetCA(const std::wstring& wsCA) { m_wsCA = wsCA; } - void SetRC(const std::wstring& wsRC) { m_wsRC = wsRC; } - void SetAC(const std::wstring& wsAC) { m_wsAC = wsAC; } - void SetAP_N_Yes(const std::wstring& wsAP_N_Yes) { m_wsAP_N_Yes = wsAP_N_Yes; } - - BYTE GetS() const { return m_nS; } - BYTE GetTP() const { return m_nTP; } - BYTE GetSW() const { return m_nSW; } - BYTE GetStyle() const { return m_nStyle; } - int GetIFFlag() const { return m_nIFFlag; } - void GetA(double& dA1, double& dA2) const { dA1 = m_dA1; dA2 = m_dA2; } - const std::wstring& GetCA() const { return m_wsCA; } - const std::wstring& GetRC() const { return m_wsRC; } - const std::wstring& GetAC() const { return m_wsAC; } - const std::wstring& GetAP_N_Yes() const { return m_wsAP_N_Yes; } + BYTE GetS() const; + BYTE GetTP() const; + BYTE GetSW() const; + BYTE GetStyle() const; + int GetIFFlag() const; + int GetI() const; + int GetRI() const; + int GetIX() const; + void GetA(double& dA1, double& dA2); + const std::wstring& GetV(); + const std::wstring& GetCA(); + const std::wstring& GetRC(); + const std::wstring& GetAC(); + const std::wstring& GetAP_N_Yes(); + + void Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, BYTE nType, int nFlags); private: BYTE m_nS; @@ -85,107 +68,113 @@ class GRAPHICS_DECL CAnnotFieldInfo : public IAdvancedCommand BYTE m_nSW; BYTE m_nStyle; int m_nIFFlag; + int m_nI; + int m_nRI; + int m_nIX; double m_dA1, m_dA2; + std::wstring m_wsV; std::wstring m_wsCA; std::wstring m_wsRC; std::wstring m_wsAC; std::wstring m_wsAP_N_Yes; }; - class CTextWidgetPr + class GRAPHICS_DECL CTextWidgetPr { public: - void SetMaxLen(const int& nMaxLen) { m_nMaxLen = nMaxLen; } - void SetV (const std::wstring& wsV) { m_wsV = wsV; } - void SetRV(const std::wstring& wsRV) { m_wsRV = wsRV; } + int GetMaxLen() const; + const std::wstring& GetV(); + const std::wstring& GetRV(); + const std::wstring& GetAPV(); + BYTE* GetRender(LONG& nLen); - int GetMaxLen() const { return m_nMaxLen; } - const std::wstring& GetV() const { return m_wsV; } - const std::wstring& GetRV() const { return m_wsRV; } + void Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, int nFlags, int nWidgetFlag); private: int m_nMaxLen; std::wstring m_wsV; std::wstring m_wsRV; + std::wstring m_wsAPV; + LONG m_nRenderLen; + BYTE* m_pRender; }; - class CChoiceWidgetPr + class GRAPHICS_DECL CChoiceWidgetPr { public: - void SetTI(const int& nTI) { m_nTI = nTI; } - void SetV(const std::wstring& wsV) { m_wsV = wsV; } - void SetOpt(const std::vector< std::pair >& arrOpt) { m_arrOpt = arrOpt; } + int GetTI() const; + const std::wstring& GetV(); + const std::wstring& GetAPV(); + const std::vector& GetI(); + const std::vector& GetArrV(); + const std::vector< std::pair >& GetOpt(); + BYTE* GetRender(LONG& nLen); - int GetTI() const { return m_nTI; } - const std::wstring& GetV() const { return m_wsV; } - const std::vector< std::pair >& GetOpt() const { return m_arrOpt; } + void Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, int nFlags); private: int m_nTI; std::wstring m_wsV; + std::wstring m_wsAPV; + std::vector m_arrI; + std::vector m_arrV; std::vector< std::pair > m_arrOpt; + LONG m_nRenderLen; + BYTE* m_pRender; }; - class CSignatureWidgetPr + class GRAPHICS_DECL CSignatureWidgetPr { }; - class CActionWidget + class GRAPHICS_DECL CActionWidget { public: - CActionWidget() : pNext(NULL) {} - ~CActionWidget() { RELEASEOBJECT(pNext); } + CActionWidget(); + ~CActionWidget(); BYTE nKind; BYTE nFlags; BYTE nActionType; int nInt1; - double dD[4]; + double dD[4]{}; std::wstring wsType; std::wstring wsStr1; std::vector arrStr; CActionWidget* pNext; }; - public: CWidgetAnnotPr(BYTE nType); ~CWidgetAnnotPr(); - void SetQ(const BYTE& nQ) { m_nQ = nQ; } - void SetH(const BYTE& nH) { m_nH = nH; } - void SetR(const int& nR) { m_nR = nR; } - void SetFlag (const int& nFlag) { m_nFlag = nFlag; } - void SetFlags (const int& nFlags) { m_nFlags = nFlags; } - void SetParentID(const int& nParentID) { m_nParentID = nParentID; } - void SetTU(const std::wstring& wsTU) { m_wsTU = wsTU; } - void SetDS(const std::wstring& wsDS) { m_wsDS = wsDS; } - void SetDV(const std::wstring& wsDV) { m_wsDV = wsDV; } - void SetT (const std::wstring& wsT) { m_wsT = wsT; } - void SetTC(const std::vector& arrTC) { m_arrTC = arrTC; } - void SetBC(const std::vector& arrBC) { m_arrBC = arrBC; } - void SetBG(const std::vector& arrBG) { m_arrBG = arrBG; } - void AddAction(CActionWidget* pA) { m_arrAction.push_back(pA); } - - BYTE GetQ() const { return m_nQ; } - BYTE GetH() const { return m_nH; } - BYTE GetType() const { return m_nType; } - int GetR() const { return m_nR; } - int GetFlag() const { return m_nFlag; } - int GetFlags() const { return m_nFlags; } - int GetParentID() const { return m_nParentID; } - const std::wstring& GetTU() const { return m_wsTU; } - const std::wstring& GetDS() const { return m_wsDS; } - const std::wstring& GetDV() const { return m_wsDV; } - const std::wstring& GetT() const { return m_wsT; } - const std::vector& GetTC() const { return m_arrTC; } - const std::vector& GetBC() const { return m_arrBC; } - const std::vector& GetBG() const { return m_arrBG; } - - CButtonWidgetPr* GetButtonWidgetPr() { return m_pButtonPr; } - CTextWidgetPr* GetTextWidgetPr() { return m_pTextPr; } - CChoiceWidgetPr* GetChoiceWidgetPr() { return m_pChoicePr; } - CSignatureWidgetPr* GetSignatureWidgetPr() { return m_pSignaturePr; } + BYTE GetQ() const; + BYTE GetH() const; + BYTE GetType() const; + int GetR() const; + int GetFlag() const; + int GetFlags() const; + int GetParentID() const; + int GetFontStyle() const; + double GetFontSize() const; + double GetFontSizeAP() const; + const std::wstring& GetTU(); + const std::wstring& GetDS(); + const std::wstring& GetDV(); + const std::wstring& GetT(); + const std::wstring& GetFontName(); + const std::wstring& GetFontKey(); + const std::vector& GetTC(); + const std::vector& GetBC(); + const std::vector& GetBG(); + const std::vector& GetActions(); + + CButtonWidgetPr* GetButtonWidgetPr(); + CTextWidgetPr* GetTextWidgetPr(); + CChoiceWidgetPr* GetChoiceWidgetPr(); + CSignatureWidgetPr* GetSignatureWidgetPr(); + + void Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, BYTE nType); private: BYTE m_nQ; @@ -195,10 +184,15 @@ class GRAPHICS_DECL CAnnotFieldInfo : public IAdvancedCommand int m_nFlag; int m_nFlags; int m_nParentID; + int m_nFontStyle; + double m_dFS; + double m_dFSAP; std::wstring m_wsTU; std::wstring m_wsDS; std::wstring m_wsDV; std::wstring m_wsT; + std::wstring m_wsFN; + std::wstring m_wsFK; std::vector m_arrTC; std::vector m_arrBC; std::vector m_arrBG; @@ -210,28 +204,34 @@ class GRAPHICS_DECL CAnnotFieldInfo : public IAdvancedCommand CSignatureWidgetPr* m_pSignaturePr; }; - class CMarkupAnnotPr + class GRAPHICS_DECL CMarkupAnnotPr { public: - void SetRT(const BYTE& nRT) { m_nRT = nRT; } - void SetFlag(const int& nFlag) { m_nFlag = nFlag; } - void SetPopupID(const int& nPopupID) { m_nPopupID = nPopupID; } - void SetIRTID(const int& nIRTID) { m_nIRTID = nIRTID; } - void SetCA(const double& dCA) { m_dCA = dCA; } - void SetT(const std::wstring& wsT) { m_wsT = wsT; } - void SetRC(const std::wstring& wsRC) { m_wsRC = wsRC; } - void SetCD(const std::wstring& wsCD) { m_wsCD = wsCD; } - void SetSubj(const std::wstring& wsSubj) { m_wsSubj = wsSubj; } - - BYTE GetRT() const { return m_nRT; } - int GetFlag() const { return m_nFlag; } - int GetPopupID() const { return m_nPopupID; } - int GetIRTID() const { return m_nIRTID; } - double GetCA() const { return m_dCA; } - const std::wstring& GetT() const { return m_wsT; } - const std::wstring& GetRC() const { return m_wsRC; } - const std::wstring& GetCD() const { return m_wsCD; } - const std::wstring& GetSubj() const { return m_wsSubj; } + struct GRAPHICS_DECL CFontData + { + BYTE nAlignment; + int nFontFlag; + double dFontSise; + double dVAlign; + double dColor[3]; + std::wstring sFontFamily; + std::wstring sActualFont; + std::wstring sText; + }; + + virtual ~CMarkupAnnotPr(); + + BYTE GetRT() const; + int GetFlag() const; + int GetPopupID() const; + int GetIRTID() const; + double GetCA() const; + const std::wstring& GetT(); + const std::wstring& GetCD(); + const std::wstring& GetSubj(); + const std::vector& GetRC(); + + void Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, int nFlags); private: BYTE m_nRT; @@ -243,22 +243,20 @@ class GRAPHICS_DECL CAnnotFieldInfo : public IAdvancedCommand std::wstring m_wsRC; std::wstring m_wsCD; std::wstring m_wsSubj; + std::vector m_arrRC; }; - class CTextAnnotPr + class GRAPHICS_DECL CTextAnnotPr { public: - CTextAnnotPr() : m_bOpen(false), m_nName(2), m_nState(7), m_nStateModel(2) {} + CTextAnnotPr(); - void SetOpen(bool bOpen) { m_bOpen = bOpen; } - void SetName(BYTE nName) { m_nName = nName; } - void SetState(BYTE nState) { m_nState = nState; } - void SetStateModel(BYTE nStateModel) { m_nStateModel = nStateModel; } + bool IsOpen() const; + BYTE GetName() const; + BYTE GetState() const; + BYTE GetStateModel() const; - bool IsOpen() const { return m_bOpen; } - BYTE GetName() const { return m_nName; } - BYTE GetState() const { return m_nState; } - BYTE GetStateModel() const { return m_nStateModel; } + void Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, int nFlags); private: bool m_bOpen; @@ -267,42 +265,32 @@ class GRAPHICS_DECL CAnnotFieldInfo : public IAdvancedCommand BYTE m_nStateModel; }; - class CInkAnnotPr + class GRAPHICS_DECL CInkAnnotPr { public: - void SetInkList(const std::vector< std::vector >& arrInkList) { m_arrInkList = arrInkList; } + const std::vector< std::vector >& GetInkList(); - const std::vector< std::vector >& GetInkList() const { return m_arrInkList; } + void Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader); private: std::vector< std::vector > m_arrInkList; }; - class CLineAnnotPr + class GRAPHICS_DECL CLineAnnotPr { public: - void SetCap(bool bCap) { m_bCap = bCap; } - void SetIT(const BYTE& nIT) { m_nIT = nIT; } - void SetCP(const BYTE& nCP) { m_nCP = nCP; } - void SetLL(const double& dLL) { m_dLL = dLL; } - void SetLLE(const double& dLLE) { m_dLLE = dLLE; } - void SetLLO(const double& dLLO) { m_dLLO = dLLO; } - void SetLE(const BYTE& nLE1, const BYTE& nLE2) { m_nLE[0] = nLE1; m_nLE[1] = nLE2; } - void SetL(const double& dL1, const double& dL2, const double& dL3, const double& dL4) - { m_dL[0] = dL1; m_dL[1] = dL2; m_dL[2] = dL3; m_dL[3] = dL4; } - void SetCO(const double& dCO1, const double& dCO2) { m_dCO[0] = dCO1; m_dCO[1] = dCO2; } - void SetIC(const std::vector& arrIC) { m_arrIC = arrIC; } - - bool IsCap() const { return m_bCap; } - BYTE GetIT() const { return m_nIT; } - BYTE GetCP() const { return m_nCP; } - double GetLL() const { return m_dLL; } - double GetLLE() const { return m_dLLE; } - double GetLLO() const { return m_dLLO; } - void GetLE(BYTE& nLE1, BYTE& nLE2) const { nLE1 = m_nLE[0]; nLE2 = m_nLE[1]; } - void GetL(double& dL1, double& dL2, double& dL3, double& dL4) const { dL1 = m_dL[0]; dL2 = m_dL[1]; dL3 = m_dL[2]; dL4 = m_dL[3]; } - void GetCO(double& dCO1, double& dCO2) const { dCO1 = m_dCO[0]; dCO2 = m_dCO[1]; } - const std::vector& GetIC() const { return m_arrIC; } + bool IsCap() const; + BYTE GetIT() const; + BYTE GetCP() const; + double GetLL() const; + double GetLLE() const; + double GetLLO() const; + void GetLE(BYTE& nLE1, BYTE& nLE2); + void GetL(double& dL1, double& dL2, double& dL3, double& dL4); + void GetCO(double& dCO1, double& dCO2); + const std::vector& GetIC(); + + void Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, int nFlags); private: bool m_bCap; @@ -311,77 +299,67 @@ class GRAPHICS_DECL CAnnotFieldInfo : public IAdvancedCommand double m_dLL; double m_dLLE; double m_dLLO; - BYTE m_nLE[2]; - double m_dL[4]; - double m_dCO[2]; + BYTE m_nLE[2]{}; + double m_dL[4]{}; + double m_dCO[2]{}; std::vector m_arrIC; }; - class CTextMarkupAnnotPr + class GRAPHICS_DECL CTextMarkupAnnotPr { public: - void SetSubtype(const BYTE& nSubtype) { m_nSubtype = nSubtype; } - void SetQuadPoints(const std::vector& arrQuadPoints) { m_arrQuadPoints = arrQuadPoints; } + BYTE GetSubtype() const; + const std::vector& GetQuadPoints(); - BYTE GetSubtype() const { return m_nSubtype; } - const std::vector& GetQuadPoints() const { return m_arrQuadPoints; } + void Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, BYTE nType); private: BYTE m_nSubtype; std::vector m_arrQuadPoints; }; - class CSquareCircleAnnotPr + class GRAPHICS_DECL CSquareCircleAnnotPr { public: - void SetSubtype(const BYTE& nSubtype) { m_nSubtype = nSubtype; } - void SetRD(const double& dRD1, const double& dRD2, const double& dRD3, const double& dRD4) - { m_dRD[0] = dRD1; m_dRD[1] = dRD2; m_dRD[2] = dRD3; m_dRD[3] = dRD4; } - void SetIC(const std::vector& arrIC) { m_arrIC = arrIC; } + BYTE GetSubtype() const; + void GetRD(double& dRD1, double& dRD2, double& dRD3, double& dRD4); + const std::vector& GetIC(); - BYTE GetSubtype() const { return m_nSubtype; } - void GetRD(double& dRD1, double& dRD2, double& dRD3, double& dRD4) const { dRD1 = m_dRD[0]; dRD2 = m_dRD[1]; dRD3 = m_dRD[2]; dRD4 = m_dRD[3]; } - const std::vector& GetIC() const { return m_arrIC; } + void Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, BYTE nType, int nFlags); private: BYTE m_nSubtype; - double m_dRD[4]; + double m_dRD[4]{}; std::vector m_arrIC; }; - class CPolygonLineAnnotPr + class GRAPHICS_DECL CPolygonLineAnnotPr { public: - void SetIT(const BYTE& nIT) { m_nIT = nIT; } - void SetSubtype(const BYTE& nSubtype) { m_nSubtype = nSubtype; } - void SetLE(const BYTE& nLE1, const BYTE& nLE2) { m_nLE[0] = nLE1; m_nLE[1] = nLE2; } - void SetIC(const std::vector& arrIC) { m_arrIC = arrIC; } - void SetVertices(const std::vector& arrVertices) { m_arrVertices = arrVertices; } - - BYTE GetIT() const { return m_nIT; } - BYTE GetSubtype() const { return m_nSubtype; } - void GetLE(BYTE& nLE1, BYTE& nLE2) const { nLE1 = m_nLE[0]; nLE2 = m_nLE[1]; } - const std::vector& GetIC() const { return m_arrIC; } - const std::vector& GetVertices() const { return m_arrVertices; } + BYTE GetIT() const; + BYTE GetSubtype() const; + void GetLE(BYTE& nLE1, BYTE& nLE2); + const std::vector& GetIC(); + const std::vector& GetVertices(); + + void Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, BYTE nType, int nFlags); private: BYTE m_nIT; BYTE m_nSubtype; - BYTE m_nLE[2]; + BYTE m_nLE[2]{}; std::vector m_arrIC; std::vector m_arrVertices; }; - class CPopupAnnotPr + class GRAPHICS_DECL CPopupAnnotPr { public: - void SetOpen(bool bOpen) { m_bOpen = bOpen; } - void SetFlag(const int& nFlag) { m_nFlag = nFlag; } - void SetParentID(const int& nParentID) { m_nParentID = nParentID; } + bool IsOpen() const; + int GetFlag() const; + int GetParentID() const; - bool IsOpen() const { return m_bOpen; } - int GetFlag() const { return m_nFlag; } - int GetParentID() const { return m_nParentID; } + void Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader); private: bool m_bOpen; @@ -389,87 +367,77 @@ class GRAPHICS_DECL CAnnotFieldInfo : public IAdvancedCommand int m_nParentID; }; - class CFreeTextAnnotPr + class GRAPHICS_DECL CFreeTextAnnotPr { public: - void SetQ(const BYTE& nQ) { m_nQ = nQ; } - void SetIT(const BYTE& nIT) { m_nIT = nIT; } - void SetLE(const BYTE& nLE) { m_nLE = nLE; } - void SetDS(const std::wstring& wsDS) { m_wsDS = wsDS; } - void SetRD(const double& dRD1, const double& dRD2, const double& dRD3, const double& dRD4) - { m_dRD[0] = dRD1; m_dRD[1] = dRD2; m_dRD[2] = dRD3; m_dRD[3] = dRD4; } - void SetCL(const std::vector& arrCL) { m_arrCL = arrCL; } - - BYTE GetQ() const { return m_nQ; } - BYTE GetIT() const { return m_nIT; } - BYTE GetLE() const { return m_nLE; } - const std::wstring& GetDS() const { return m_wsDS; } - void GetRD(double& dRD1, double& dRD2, double& dRD3, double& dRD4) const { dRD1 = m_dRD[0]; dRD2 = m_dRD[1]; dRD3 = m_dRD[2]; dRD4 = m_dRD[3]; } - const std::vector& GetCL() const { return m_arrCL; } + BYTE GetQ() const; + BYTE GetIT() const; + BYTE GetLE() const; + int GetRotate(); + const std::wstring& GetDS(); + void GetRD(double& dRD1, double& dRD2, double& dRD3, double& dRD4); + const std::vector& GetCL(); + const std::vector& GetIC(); + + void Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, int nFlags); private: BYTE m_nQ; BYTE m_nIT; BYTE m_nLE; + int m_nRotate; std::wstring m_wsDS; double m_dRD[4]{}; std::vector m_arrCL; + std::vector m_arrIC; }; - class CCaretAnnotPr + class GRAPHICS_DECL CCaretAnnotPr { public: - void SetSy(const BYTE& nSy) { m_nSy = nSy; } - void SetRD(const double& dRD1, const double& dRD2, const double& dRD3, const double& dRD4) - { m_dRD[0] = dRD1; m_dRD[1] = dRD2; m_dRD[2] = dRD3; m_dRD[3] = dRD4; } + BYTE GetSy() const; + void GetRD(double& dRD1, double& dRD2, double& dRD3, double& dRD4); - BYTE GetSy() const { return m_nSy; } - void GetRD(double& dRD1, double& dRD2, double& dRD3, double& dRD4) const { dRD1 = m_dRD[0]; dRD2 = m_dRD[1]; dRD3 = m_dRD[2]; dRD4 = m_dRD[3]; } + void Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, int nFlags); private: BYTE m_nSy; double m_dRD[4]{}; }; -private: - struct CBorder + class GRAPHICS_DECL CStampAnnotPr { - BYTE nType; - double dWidth; - double dDashesAlternating; - double dGaps; + public: + double GetRotate(); + const std::wstring& GetName(); + void GetInRect(double& dRD1, double& dRD2, double& dRD3, double& dRD4); + + void Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, int nFlags); + + private: + double m_nRotate; + std::wstring m_wsName; + double m_dInRect[4]{}; }; -public: CAnnotFieldInfo(); virtual ~CAnnotFieldInfo(); void SetType(int nType); - bool IsValid() const; - - void SetBounds(const double& dX1, const double& dY1, const double& dX2, const double& dY2); - void SetBorder(BYTE nType, double dWidth, double dDashesAlternating, double dGaps); - void SetFlag(const int& nFlag) { m_nFlag = nFlag; } - void SetID(const int& nID) { m_nID = nID; } - void SetAnnotFlag(const int& nAnnotFlag) { m_nAnnotFlag = nAnnotFlag; } - void SetPage(const int& nPage) { m_nPage = nPage; } - void SetBE(BYTE nS, const double& dI) { m_pBE.first = nS; m_pBE.second = dI; } - void SetNM(const std::wstring& wsNM) { m_wsNM = wsNM; } - void SetLM(const std::wstring& wsLM) { m_wsLM = wsLM; } - void SetContents(const std::wstring& wsContents) { m_wsContents = wsContents; } - void SetC(const std::vector& arrC) { m_arrC = arrC; } - - void GetBounds(double& dX1, double& dY1, double& dX2, double& dY2) const; - void GetBorder(BYTE& nType, double& dWidth, double& dDashesAlternating, double& dGaps); - int GetFlag() const { return m_nFlag; } - int GetID() const { return m_nID; } - int GetAnnotFlag() const { return m_nAnnotFlag; } - int GetPage() const { return m_nPage; } - void GetBE(BYTE& nS, double& dI) { nS = m_pBE.first; dI = m_pBE.second; } - const std::wstring& GetNM() const { return m_wsNM; } - const std::wstring& GetLM() const { return m_wsLM; } - const std::wstring& GetContents() const { return m_wsContents; } - const std::vector& GetC() const { return m_arrC; } + + void GetBounds(double& dX1, double& dY1, double& dX2, double& dY2); + void GetBorder(BYTE& nType, double& dWidth, std::vector& arrDash); + int GetFlag() const; + int GetID() const; + int GetAnnotFlag() const; + int GetPage() const; + void GetBE(BYTE& nS, double& dI); + BYTE* GetRender(LONG& nLen); + const std::wstring& GetNM(); + const std::wstring& GetLM(); + const std::wstring& GetOUserID(); + const std::wstring& GetContents(); + const std::vector& GetC(); bool IsWidget() const; bool IsButtonWidget() const; @@ -486,22 +454,31 @@ class GRAPHICS_DECL CAnnotFieldInfo : public IAdvancedCommand bool IsPopup() const; bool IsFreeText() const; bool IsCaret() const; - - CMarkupAnnotPr* GetMarkupAnnotPr() { return m_pMarkupPr; } - CTextAnnotPr* GetTextAnnotPr() { return m_pTextPr; } - CInkAnnotPr* GetInkAnnotPr() { return m_pInkPr; } - CLineAnnotPr* GetLineAnnotPr() { return m_pLinePr; } - CTextMarkupAnnotPr* GetTextMarkupAnnotPr() { return m_pTextMarkupPr; } - CSquareCircleAnnotPr* GetSquareCircleAnnotPr() { return m_pSquareCirclePr; } - CPolygonLineAnnotPr* GetPolygonLineAnnotPr() { return m_pPolygonLinePr; } - CPopupAnnotPr* GetPopupAnnotPr() { return m_pPopupPr; } - CFreeTextAnnotPr* GetFreeTextAnnotPr() { return m_pFreeTextPr; } - CCaretAnnotPr* GetCaretAnnotPr() { return m_pCaretPr; } - CWidgetAnnotPr* GetWidgetAnnotPr() { return m_pWidgetPr; } + bool IsStamp() const; + + CMarkupAnnotPr* GetMarkupAnnotPr(); + CTextAnnotPr* GetTextAnnotPr(); + CInkAnnotPr* GetInkAnnotPr(); + CLineAnnotPr* GetLineAnnotPr(); + CTextMarkupAnnotPr* GetTextMarkupAnnotPr(); + CSquareCircleAnnotPr* GetSquareCircleAnnotPr(); + CPolygonLineAnnotPr* GetPolygonLineAnnotPr(); + CPopupAnnotPr* GetPopupAnnotPr(); + CFreeTextAnnotPr* GetFreeTextAnnotPr(); + CCaretAnnotPr* GetCaretAnnotPr(); + CStampAnnotPr* GetStampAnnotPr(); + CWidgetAnnotPr* GetWidgetAnnotPr(); bool Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetafileToRenderter* pCorrector); private: + struct CBorder + { + BYTE nType; + double dWidth; + std::vector arrDash; + }; + int m_nType; double m_dX1; double m_dY1; @@ -513,10 +490,13 @@ class GRAPHICS_DECL CAnnotFieldInfo : public IAdvancedCommand int m_nPage; std::wstring m_wsNM; std::wstring m_wsLM; + std::wstring m_wsOUserID; std::wstring m_wsContents; std::pair m_pBE; std::vector m_arrC; CBorder m_oBorder; + LONG m_nRenderLen; + BYTE* m_pRender; CMarkupAnnotPr* m_pMarkupPr; CTextAnnotPr* m_pTextPr; @@ -528,6 +508,7 @@ class GRAPHICS_DECL CAnnotFieldInfo : public IAdvancedCommand CPopupAnnotPr* m_pPopupPr; CFreeTextAnnotPr* m_pFreeTextPr; CCaretAnnotPr* m_pCaretPr; + CStampAnnotPr* m_pStampPr; CWidgetAnnotPr* m_pWidgetPr; }; @@ -535,9 +516,9 @@ class GRAPHICS_DECL CAnnotFieldDelete : public IAdvancedCommand { public: CAnnotFieldDelete(); - virtual ~CAnnotFieldDelete() {} + virtual ~CAnnotFieldDelete(); - int GetID() { return m_nID; } + int GetID(); bool Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetafileToRenderter* pCorrector); @@ -545,4 +526,34 @@ class GRAPHICS_DECL CAnnotFieldDelete : public IAdvancedCommand int m_nID; }; +class GRAPHICS_DECL CWidgetsInfo : public IAdvancedCommand +{ +public: + struct CParent + { + int nID; + int nFlags; + int nParentID; + std::wstring sName; + std::wstring sV; + std::wstring sDV; + std::vector arrI; + std::vector arrV; + }; + + CWidgetsInfo(); + virtual ~CWidgetsInfo(); + + const std::vector& GetCO(); + const std::vector& GetButtonImg(); + const std::vector& GetParents(); + + bool Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetafileToRenderter* pCorrector); + +private: + std::vector m_arrCO; + std::vector m_arrButtonImg; + std::vector m_arrParents; +}; + #endif // _BUILD_ANNOTFIELD_H_ diff --git a/DesktopEditor/graphics/commands/DocInfo.cpp b/DesktopEditor/graphics/commands/DocInfo.cpp index 723f50c37b1..d36f2c1a6d6 100644 --- a/DesktopEditor/graphics/commands/DocInfo.cpp +++ b/DesktopEditor/graphics/commands/DocInfo.cpp @@ -128,3 +128,93 @@ bool CDocInfoCommand::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMeta m_sKeywords = pReader->ReadString(); return true; } + +CShapeStart::CShapeStart() : IAdvancedCommand(AdvancedCommandType::ShapeStart) +{ + m_pImage = NULL; +} +CShapeStart::~CShapeStart() +{ + RELEASEINTERFACE(m_pImage); +} +void CShapeStart::SetShapeXML(const std::string& sShapeXML) { m_sShapeXML = sShapeXML; } +void CShapeStart::SetShapeImage(BYTE* pImgData, int nWidth, int nHeight) +{ + if (pImgData) + { + m_pImage = new Aggplus::CImage(); + m_pImage->Create(pImgData, nWidth, nHeight, -4 * nWidth); + } +} +std::string& CShapeStart::GetShapeXML() { return m_sShapeXML; } +Aggplus::CImage* CShapeStart::GetShapeImage() { return m_pImage; } +bool CShapeStart::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetafileToRenderter* pCorrector) +{ + m_sShapeXML = pReader->ReadStringA(); + return true; +} + +CEmptyComand::CEmptyComand(AdvancedCommandType nType) : IAdvancedCommand(nType) {} + +CPageRotate::CPageRotate() : IAdvancedCommand(AdvancedCommandType::PageRotate) {} +int CPageRotate::GetPageRotate() { return m_nPageRotate; } +bool CPageRotate::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetafileToRenderter* pCorrector) +{ + m_nPageRotate = pReader->ReadInt(); + return true; +} + +CHeadings::CHeading::CHeading() +{ + nPage = 0; + dX = 0.0; + dY = 0.0; + pParent = NULL; +} +CHeadings::CHeading::~CHeading() +{ + for (int i = 0; i < arrHeading.size(); ++i) + RELEASEOBJECT(arrHeading[i]); +} + +CHeadings::CHeadings() : IAdvancedCommand(AdvancedCommandType::Headings) {} +CHeadings::~CHeadings() +{ + for (int i = 0; i < m_arrHeading.size(); ++i) + RELEASEOBJECT(m_arrHeading[i]); +} +const std::vector& CHeadings::GetHeading() { return m_arrHeading; } +bool CHeadings::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetafileToRenderter* pCorrector) +{ + int nPredLevel = 0, nHeaderLevel = 0; + std::vector* arrHeading = &m_arrHeading; + CHeading* pParent = NULL; + int nHeadings = pReader->ReadInt(); + for (int i = 0; i < nHeadings; ++i) + { + int nLevel = pReader->ReadInt(); + if (nLevel > nPredLevel && i > 0) + { + nHeaderLevel = nPredLevel; + pParent = arrHeading->back(); + arrHeading = &pParent->arrHeading; + } + else if (nLevel < nPredLevel && nLevel <= nHeaderLevel) + { + nHeaderLevel = nLevel; + pParent = pParent ? pParent->pParent : NULL; + arrHeading = pParent ? &pParent->arrHeading : &m_arrHeading; + } + nPredLevel = nLevel; + + CHeading* pHeading = new CHeading(); + pHeading->nPage = pReader->ReadInt(); + pHeading->dX = pReader->ReadDouble(); + pHeading->dY = pReader->ReadDouble(); + pHeading->wsTitle = pReader->ReadString(); + pHeading->pParent = pParent; + + arrHeading->push_back(pHeading); + } + return true; +} diff --git a/DesktopEditor/graphics/commands/DocInfo.h b/DesktopEditor/graphics/commands/DocInfo.h index a9df8a230fc..e0850188ff8 100644 --- a/DesktopEditor/graphics/commands/DocInfo.h +++ b/DesktopEditor/graphics/commands/DocInfo.h @@ -132,4 +132,70 @@ class GRAPHICS_DECL CDocInfoCommand : public IAdvancedCommand bool Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetafileToRenderter* pCorrector); }; +class GRAPHICS_DECL CShapeStart : public IAdvancedCommand +{ +public: + CShapeStart(); + ~CShapeStart(); + + std::string& GetShapeXML(); + Aggplus::CImage* GetShapeImage(); + + void SetShapeXML(const std::string& sShapeXML); + void SetShapeImage(BYTE* pImgData, int nWidth, int nHeight); + + bool Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetafileToRenderter* pCorrector); + +private: + std::string m_sShapeXML; + Aggplus::CImage* m_pImage; +}; + +class GRAPHICS_DECL CEmptyComand : public IAdvancedCommand +{ +public: + CEmptyComand(AdvancedCommandType nType); +}; + +class GRAPHICS_DECL CPageRotate : public IAdvancedCommand +{ +public: + CPageRotate(); + + int GetPageRotate(); + + bool Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetafileToRenderter* pCorrector); + +private: + int m_nPageRotate; +}; + +class GRAPHICS_DECL CHeadings : public IAdvancedCommand +{ +public: + struct CHeading + { + std::wstring wsTitle; + int nPage; + double dX; + double dY; + CHeading* pParent; + std::vector arrHeading; + + CHeading(); + ~CHeading(); + }; + + CHeadings(); + ~CHeadings(); + + bool Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetafileToRenderter* pCorrector); + + const std::vector& GetHeading(); + +private: + std::vector m_arrHeading; +}; + + #endif // _BUILD_DOCINFO_H_ diff --git a/DesktopEditor/graphics/commands/FormField.cpp b/DesktopEditor/graphics/commands/FormField.cpp index 81faf97f12f..ea876d48901 100644 --- a/DesktopEditor/graphics/commands/FormField.cpp +++ b/DesktopEditor/graphics/commands/FormField.cpp @@ -329,60 +329,6 @@ const std::wstring& CFormFieldInfo::CPictureFormPr::GetPicturePath() const return m_wsPicturePath; } -// -CFormFieldInfo::CSignatureFormPr::CSignatureFormPr() -{ -} -void CFormFieldInfo::CSignatureFormPr::SetName(const std::wstring& wsValue) -{ - m_wsName = wsValue; -} -void CFormFieldInfo::CSignatureFormPr::SetContact(const std::wstring& wsValue) -{ - m_wsContact = wsValue; -} -void CFormFieldInfo::CSignatureFormPr::SetReason(const std::wstring& wsValue) -{ - m_wsReason = wsValue; -} -void CFormFieldInfo::CSignatureFormPr::SetPicturePath(const std::wstring& wsPath) -{ - m_wsPicturePath = wsPath; -} -void CFormFieldInfo::CSignatureFormPr::SetCert(const std::wstring& wsValue) -{ - m_wsCert = wsValue; -} -void CFormFieldInfo::CSignatureFormPr::SetDate(const bool& bDate) -{ - m_bDate = bDate; -} - -const std::wstring& CFormFieldInfo::CSignatureFormPr::GetName() const -{ - return m_wsName; -} -const std::wstring& CFormFieldInfo::CSignatureFormPr::GetContact() const -{ - return m_wsContact; -} -const std::wstring& CFormFieldInfo::CSignatureFormPr::GetReason() const -{ - return m_wsReason; -} -const std::wstring& CFormFieldInfo::CSignatureFormPr::GetPicturePath() const -{ - return m_wsPicturePath; -} -const std::wstring& CFormFieldInfo::CSignatureFormPr::GetCert() const -{ - return m_wsCert; -} -bool CFormFieldInfo::CSignatureFormPr::GetDate() const -{ - return m_bDate; -} - // CFormFieldInfo::CDateTimeFormPr::CDateTimeFormPr() { @@ -565,10 +511,6 @@ bool CFormFieldInfo::IsPicture() const { return (m_nType == 4); } -bool CFormFieldInfo::IsSignature() const -{ - return (m_nType == 5); -} bool CFormFieldInfo::IsDateTime() const { return (m_nType == 6); @@ -605,14 +547,6 @@ const CFormFieldInfo::CPictureFormPr* CFormFieldInfo::GetPicturePr() const { return &m_oPicturePr; } -CFormFieldInfo::CSignatureFormPr* CFormFieldInfo::GetSignatureFormPr() -{ - return &m_oSignaturePr; -} -const CFormFieldInfo::CSignatureFormPr* CFormFieldInfo::GetSignaturePr() const -{ - return &m_oSignaturePr; -} CFormFieldInfo::CDateTimeFormPr* CFormFieldInfo::GetDateTimeFormPr() { return &m_oDateTimePr; @@ -747,40 +681,6 @@ bool CFormFieldInfo::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetaf if (nFlags & (1 << 22)) pPr->SetPicturePath(pCorrector->GetImagePath(pReader->ReadString())); } - else if (IsSignature()) - { - CFormFieldInfo::CSignatureFormPr* pPr = GetSignatureFormPr(); - - // Поля Настройки подписи - // Сведения о подписывающем - - // Имя - if (nFlags & (1 << 20)) - pPr->SetName(pReader->ReadString()); - - // Должность Игнорируется - - // Адрес электронной почты - if (nFlags & (1 << 21)) - pPr->SetContact(pReader->ReadString()); - - // Инструкция для подписывающего Игнорируется - - // Показывать дату подписи в строке подписи - pPr->SetDate(nFlags & (1 << 22)); - - // Цель подписания документа (причина) - if (nFlags & (1 << 23)) - pPr->SetReason(pReader->ReadString()); - - // Картинка - if (nFlags & (1 << 24)) - pPr->SetPicturePath(pCorrector->GetImagePath(pReader->ReadString())); - - // Необходимо передать сертификат, пароль, ключ, пароль ключа - if (nFlags & (1 << 25)) - pPr->SetCert(pReader->ReadString()); - } else if (IsDateTime()) { CFormFieldInfo::CDateTimeFormPr* pPr = GetDateTimeFormPr(); diff --git a/DesktopEditor/graphics/commands/FormField.h b/DesktopEditor/graphics/commands/FormField.h index 664b4082f5b..565827ce1d4 100644 --- a/DesktopEditor/graphics/commands/FormField.h +++ b/DesktopEditor/graphics/commands/FormField.h @@ -213,34 +213,6 @@ class GRAPHICS_DECL CFormFieldInfo : public IAdvancedCommand LONG m_lShiftY; std::wstring m_wsPicturePath; }; - - class GRAPHICS_DECL CSignatureFormPr - { - public: - CSignatureFormPr(); - - void SetName(const std::wstring& wsValue); - void SetContact(const std::wstring& wsValue); - void SetReason(const std::wstring& wsValue); - void SetPicturePath(const std::wstring& wsPath); - void SetCert(const std::wstring& wsValue); - void SetDate(const bool& bDate); - - const std::wstring& GetName() const; - const std::wstring& GetContact() const; - const std::wstring& GetReason() const; - const std::wstring& GetPicturePath() const; - const std::wstring& GetCert() const; - bool GetDate() const; - - private: - std::wstring m_wsName; - std::wstring m_wsContact; - std::wstring m_wsReason; - std::wstring m_wsPicturePath; - std::wstring m_wsCert; - bool m_bDate; - }; class GRAPHICS_DECL CDateTimeFormPr { @@ -304,7 +276,6 @@ class GRAPHICS_DECL CFormFieldInfo : public IAdvancedCommand bool IsDropDownList() const; bool IsCheckBox() const; bool IsPicture() const; - bool IsSignature() const; bool IsDateTime() const; CTextFormPr* GetTextFormPr(); @@ -318,9 +289,6 @@ class GRAPHICS_DECL CFormFieldInfo : public IAdvancedCommand CPictureFormPr* GetPictureFormPr(); const CPictureFormPr* GetPicturePr() const; - - CSignatureFormPr* GetSignatureFormPr(); - const CSignatureFormPr* GetSignaturePr() const; CDateTimeFormPr* GetDateTimeFormPr(); const CDateTimeFormPr* GetDateTimePr() const; @@ -349,7 +317,6 @@ class GRAPHICS_DECL CFormFieldInfo : public IAdvancedCommand CDropDownFormPr m_oDropDownPr; CCheckBoxFormPr m_oCheckBoxPr; CPictureFormPr m_oPicturePr; - CSignatureFormPr m_oSignaturePr; CDateTimeFormPr m_oDateTimePr; }; diff --git a/DesktopEditor/graphics/pro/Fonts.h b/DesktopEditor/graphics/pro/Fonts.h index 4b0599eedc0..d41a82ee79c 100644 --- a/DesktopEditor/graphics/pro/Fonts.h +++ b/DesktopEditor/graphics/pro/Fonts.h @@ -766,6 +766,7 @@ namespace NSFonts virtual std::vector* GetFonts() = 0; virtual CFontInfo* GetByParams(CFontSelectFormat& oSelect, bool bIsDictionaryUse = true) = 0; virtual void ToBuffer(BYTE** pDstData, LONG* pLen, CFontListToBufferSerializer& oSerializer) = 0; + virtual void Add(const std::wstring& sFontPath, IFontStream* pStream, int nFlag = 0) = 0; }; class GRAPHICS_DECL IApplicationFonts : public NSBase::CBaseRefCounter @@ -784,7 +785,7 @@ namespace NSFonts virtual void InitializeFromBin(BYTE* pData, unsigned int nLen) = 0; virtual void InitializeRanges(unsigned char* data) = 0; - virtual std::vector GetSetupFontFiles() = 0; + virtual std::vector GetSetupFontFiles(const bool& bIsUseUserFonts = true) = 0; virtual void InitializeFromArrayFiles(std::vector& files, int nFlag = 0) = 0; #if defined(_WIN32) || defined(_WIN64) diff --git a/DesktopEditor/graphics/pro/Graphics.h b/DesktopEditor/graphics/pro/Graphics.h index 508b1dca982..efc49eddd35 100644 --- a/DesktopEditor/graphics/pro/Graphics.h +++ b/DesktopEditor/graphics/pro/Graphics.h @@ -88,6 +88,8 @@ namespace NSGraphics virtual void SetSwapRGB(bool bValue) = 0; virtual void SetTileImageDpi(const double& dDpi) = 0; + virtual void Save() = 0; + virtual void Restore() = 0; public: virtual void CreateFromBgraFrame(CBgraFrame* pFrame) = 0; @@ -120,6 +122,8 @@ namespace NSGraphics //alpha mask methods virtual void SetAlphaMask(Aggplus::CAlphaMask* pAlphaMask) = 0; + virtual Aggplus::CSoftMask* CreateSoftMask(bool bAlpha) = 0; + virtual void SetSoftMask(Aggplus::CSoftMask* pSoftMask) = 0; // smart methods virtual void drawHorLine(BYTE align, double y, double x, double r, double penW) = 0; @@ -127,11 +131,6 @@ namespace NSGraphics virtual void drawVerLine(BYTE align, double x, double y, double b, double penW) = 0; virtual void drawHorLineExt(BYTE align, double y, double x, double r, double penW, double leftMW, double rightMW) = 0; - - // test - - virtual void put_BrushGradInfo(const NSStructures::GradientInfo &_ginfo) = 0; - virtual void put_BlendMode(const unsigned int nBlendMode) = 0; }; GRAPHICS_DECL IGraphicsRenderer* Create(); diff --git a/DesktopEditor/graphics/pro/Image.h b/DesktopEditor/graphics/pro/Image.h index 9bb1f8d7764..313ee4f51ee 100644 --- a/DesktopEditor/graphics/pro/Image.h +++ b/DesktopEditor/graphics/pro/Image.h @@ -123,6 +123,7 @@ namespace MetaFile virtual bool LoadFromFile(const wchar_t* wsFilePath) = 0; virtual bool LoadFromBuffer(BYTE* pBuffer, unsigned int unSize) = 0; + virtual bool LoadFromString(const std::wstring& data) = 0; virtual bool DrawOnRenderer(IRenderer* pRenderer, double dX, double dY, double dWidth, double dHeight) = 0; virtual void Close() = 0; virtual void GetBounds(double* pdX, double* pdY, double* pdW, double* pdH) = 0; @@ -131,6 +132,7 @@ namespace MetaFile virtual NSFonts::IFontManager* get_FontManager() = 0; virtual std::wstring ConvertToSvg(unsigned int unWidth = 0, unsigned int unHeight = 0) = 0; + virtual void SetTempDirectory(const std::wstring& dir) = 0; //Для тестов #ifdef METAFILE_SUPPORT_WMF_EMF diff --git a/DesktopEditor/graphics/pro/fontengine.pri b/DesktopEditor/graphics/pro/fontengine.pri index 5989e225508..9e84f6130c4 100644 --- a/DesktopEditor/graphics/pro/fontengine.pri +++ b/DesktopEditor/graphics/pro/fontengine.pri @@ -3,7 +3,7 @@ include(freetype.pri) FONT_ENGINE_PATH = $$PWD/../../fontengine HEADERS += \ - $$PWD/Fonts.h \ + $$PWD/Fonts.h \ $$FONT_ENGINE_PATH/ApplicationFonts.h \ $$FONT_ENGINE_PATH/FontFile.h \ $$FONT_ENGINE_PATH/FontPath.h \ @@ -12,7 +12,7 @@ HEADERS += \ $$FONT_ENGINE_PATH/FontConverter.h SOURCES += \ - $$FONT_ENGINE_PATH/ApplicationFonts.cpp \ + $$FONT_ENGINE_PATH/ApplicationFonts.cpp \ $$FONT_ENGINE_PATH/FontFile.cpp \ $$FONT_ENGINE_PATH/FontManager.cpp \ $$FONT_ENGINE_PATH/FontPath.cpp \ @@ -34,7 +34,7 @@ SOURCES += $$FONT_ENGINE_PATH/TextShaper.cpp include($$PWD/textshaper.pri) enable_support_shaper { - include($$PWD/../../../Common/3dParty/harfbuzz/harfbuzz.pri) + include($$PWD/../../../Common/3dParty/harfbuzz/harfbuzz.pri) } # ------------------------------------------------- @@ -46,14 +46,14 @@ SOURCES += $$FONT_ENGINE_PATH/TextHyphen.cpp # ------------------------------------------------- core_ios { - LIBS += -framework Foundation + LIBS += -framework Foundation } SOURCES += $$PWD/pro_Fonts.cpp support_font_converter { SOURCES += \ - $$FONT_ENGINE_PATH/fontconverter/StringExt.cpp \ + $$FONT_ENGINE_PATH/fontconverter/StringExt.cpp \ $$FONT_ENGINE_PATH/fontconverter/Hash.cpp \ $$FONT_ENGINE_PATH/fontconverter/FontConverter.cpp \ $$FONT_ENGINE_PATH/fontconverter/FontFileEncodings.cpp \ diff --git a/DesktopEditor/graphics/pro/graphics.pro b/DesktopEditor/graphics/pro/graphics.pro index ce20b972e5f..212cbc268d1 100644 --- a/DesktopEditor/graphics/pro/graphics.pro +++ b/DesktopEditor/graphics/pro/graphics.pro @@ -1,4 +1,4 @@ -QT -= core gui +QT -= core gui TARGET = graphics TEMPLATE = lib @@ -7,12 +7,12 @@ CONFIG += graphics_dynamic_library DEFINES += _QT graphics_dynamic_library { - CONFIG += shared + CONFIG += shared CONFIG += plugin - DEFINES += GRAPHICS_USE_DYNAMIC_LIBRARY_BUILDING + DEFINES += GRAPHICS_USE_DYNAMIC_LIBRARY_BUILDING } else { - DEFINES += GRAPHICS_NO_USE_DYNAMIC_LIBRARY + DEFINES += GRAPHICS_NO_USE_DYNAMIC_LIBRARY CONFIG += static } @@ -23,7 +23,7 @@ include(../../../Common/base.pri) ADD_DEPENDENCY(UnicodeConverter, kernel) core_windows { - LIBS += -lAdvapi32 + LIBS += -lAdvapi32 LIBS += -lShell32 } @@ -32,39 +32,49 @@ HEADERS += ./../config.h GRAPHICS_AGG_PATH = $$PWD/../../agg-2.4 INCLUDEPATH += \ - $$GRAPHICS_AGG_PATH/include + $$GRAPHICS_AGG_PATH/include # matrix HEADERS += \ - $$GRAPHICS_AGG_PATH/include/test_grads/custom_gradients.h \ - ./../Matrix_private.h \ + $$GRAPHICS_AGG_PATH/include/test_grads/custom_gradients.h \ + ./../Matrix_private.h \ ./../Matrix.h SOURCES += \ - ./../Matrix.cpp + ./../Matrix.cpp SOURCES += \ - $$GRAPHICS_AGG_PATH/src/agg_trans_affine.cpp + $$GRAPHICS_AGG_PATH/src/agg_trans_affine.cpp # paths HEADERS += \ - ./../GraphicsPath_private.h \ - ./../GraphicsPath.h + ./../GraphicsPath_private.h \ + ./../GraphicsPath.h \ + ./../BooleanOperations.h \ + ./../boolean_operations_math.h SOURCES += \ - ./../GraphicsPath.cpp + ./../GraphicsPath.cpp \ + ./../BooleanOperations.cpp # alpha mask HEADERS += \ - ./../AlphaMask_private.h \ - ./../AlphaMask.h + ./../AlphaMask.h \ + ./../AlphaMask_p.h SOURCES += \ - ./../AlphaMask_private.cpp \ ./../AlphaMask.cpp +# grapgics layer +HEADERS += \ + ./../GraphicsLayer.h \ + ./../GraphicsLayerBlend.h + +SOURCES += \ + ./../GraphicsLayer.cpp + SOURCES += \ - $$GRAPHICS_AGG_PATH/src/agg_arc.cpp \ + $$GRAPHICS_AGG_PATH/src/agg_arc.cpp \ $$GRAPHICS_AGG_PATH/src/agg_bezier_arc.cpp \ $$GRAPHICS_AGG_PATH/src/agg_curves.cpp \ $$GRAPHICS_AGG_PATH/src/agg_bspline.cpp \ @@ -76,9 +86,9 @@ include(raster.pri) #CONFIG += graphics_disable_metafile graphics_disable_metafile { - DEFINES += GRAPHICS_DISABLE_METAFILE + DEFINES += GRAPHICS_DISABLE_METAFILE } else { - include(metafile.pri) + include(metafile.pri) } CONFIG += support_font_converter @@ -90,7 +100,7 @@ SOURCES += ./officedrawingfile.cpp # graphics SOURCES += \ - $$GRAPHICS_AGG_PATH/src/agg_arrowhead.cpp \ + $$GRAPHICS_AGG_PATH/src/agg_arrowhead.cpp \ $$GRAPHICS_AGG_PATH/src/agg_image_filters.cpp \ $$GRAPHICS_AGG_PATH/src/agg_line_aa_basics.cpp \ $$GRAPHICS_AGG_PATH/src/agg_line_profile_aa.cpp \ @@ -99,7 +109,7 @@ SOURCES += \ $$GRAPHICS_AGG_PATH/src/agg_vcgen_smooth_poly1.cpp HEADERS += \ - ./../ArrowHead.h \ + ./../ArrowHead.h \ ./../Brush.h \ ./../Clip.h \ ./../Color.h \ @@ -115,7 +125,7 @@ HEADERS += \ ./Image.h SOURCES += \ - ./../ArrowHead.cpp \ + ./../ArrowHead.cpp \ ./../Brush.cpp \ ./../Clip.cpp \ ./../Graphics.cpp \ diff --git a/DesktopEditor/graphics/pro/js/after.py b/DesktopEditor/graphics/pro/js/after.py index 9e9c176cba7..b11b83257d1 100644 --- a/DesktopEditor/graphics/pro/js/after.py +++ b/DesktopEditor/graphics/pro/js/after.py @@ -5,23 +5,37 @@ base.configure_common_apps() base.replaceInFile("../../../../Common/3dParty/icu/icu/source/common/udata.cpp", "\n{\n#ifdef BUILDING_WASM_MODULE\nreturn NULL;\n#endif\n UDataMemory tData;", "\n{\n UDataMemory tData;") +base.replaceInFile("../../../../DesktopEditor/cximage/png/pnglibconf.h", "//#define PNG_CONSOLE_IO_SUPPORTED", "#define PNG_CONSOLE_IO_SUPPORTED") + +base.replaceInFile("../../../../Common/3dParty/openssl/openssl/crypto/sha/sha512.c", "const SHA_LONG64 *W = (const SHA_LONG64*)in;", "const SHA_LONG64 *W = in;") # finalize -base.replaceInFile("./deploy/drawingfile.js", "function getBinaryPromise()", "function getBinaryPromise2()") +base.replaceInFile("./deploy/drawingfile.js", "function getBinaryPromise(", "function getBinaryPromise2(") base.replaceInFile("./deploy/drawingfile.js", "__ATPOSTRUN__=[];", "__ATPOSTRUN__=[function(){window[\"AscViewer\"] && window[\"AscViewer\"][\"onLoadModule\"] && window[\"AscViewer\"][\"onLoadModule\"]();}];") base.replaceInFile("./deploy/drawingfile.js", "__ATPOSTRUN__ = [];", "__ATPOSTRUN__=[function(){window[\"AscViewer\"] && window[\"AscViewer\"][\"onLoadModule\"] && window[\"AscViewer\"][\"onLoadModule\"]();}];") base.replaceInFile("./deploy/drawingfile.js", "\"drawingfile.js.mem\"", "getMemoryPathIE(\"drawingfile.js.mem\")") -base.replaceInFile("./deploy/drawingfile_ie.js", "function getBinaryPromise()", "function getBinaryPromise2()") +base.replaceInFile("./deploy/drawingfile_ie.js", "function getBinaryPromise(", "function getBinaryPromise2(") base.replaceInFile("./deploy/drawingfile_ie.js", "__ATPOSTRUN__=[];", "__ATPOSTRUN__=[function(){window[\"AscViewer\"] && window[\"AscViewer\"][\"onLoadModule\"] && window[\"AscViewer\"][\"onLoadModule\"]();}];") base.replaceInFile("./deploy/drawingfile_ie.js", "__ATPOSTRUN__ = [];", "__ATPOSTRUN__=[function(){window[\"AscViewer\"] && window[\"AscViewer\"][\"onLoadModule\"] && window[\"AscViewer\"][\"onLoadModule\"]();}];") base.replaceInFile("./deploy/drawingfile_ie.js", "\"drawingfile.js.mem\"", "getMemoryPathIE(\"drawingfile.js.mem\")") -base.replaceInFile("./deploy/drawingfile.js", "{credentials:\"same-origin\"}", "{credentials:\"same-origin\",mode:\"no-cors\"}") -base.replaceInFile("./deploy/drawingfile_ie.js", "{credentials:\"same-origin\"}", "{credentials:\"same-origin\",mode:\"no-cors\"}") - base.cmd_in_dir("../../../../Common/js", "python", ["./min.py", "./../../DesktopEditor/graphics/pro/js/deploy/drawingfile.js", "WHITESPACE_ONLY"]) base.cmd_in_dir("../../../../Common/js", "python", ["./min.py", "./../../DesktopEditor/graphics/pro/js/deploy/drawingfile_ie.js", "WHITESPACE_ONLY"]) +content_native_files = [ + "./wasm/js/stream.js", + "./wasm/js/drawingfile.js" +] + +content_native = "(function(window, undefined) {\n" +for item in content_native_files: + content_native += base.readFile(item) +content_native += "\n})(window, undefined);" +content_native = content_native.replace("//file_internal", base.readFile("./wasm/js/drawingfile_native.js")) +content_native = content_native.replace("//string_utf8", base.readFile("./../../../../Common/js/string_utf8.js")) +base.writeFile("./deploy/drawingfile_native.js", content_native) +base.cmd_in_dir("../../../../Common/js", "python", ["./min.py", "./../../DesktopEditor/graphics/pro/js/deploy/drawingfile_native.js", "WHITESPACE_ONLY"]) + # base.delete_dir("./xml") # base.delete_dir("./freetype-2.10.4") diff --git a/DesktopEditor/graphics/pro/js/before.py b/DesktopEditor/graphics/pro/js/before.py index b77a61c3576..8f75cc7f3bc 100644 --- a/DesktopEditor/graphics/pro/js/before.py +++ b/DesktopEditor/graphics/pro/js/before.py @@ -13,6 +13,8 @@ base.replaceInFile("./xml/src/xmllight_private.h", "#include \"../../common/", "#include \"../../../../../common/") base.replaceInFile("./xml/src/xmllight_private.h", "#include \"../../../UnicodeConverter/", "#include \"../../../../../../UnicodeConverter/") base.replaceInFile("./xml/include/xmlutils.h", "#include \"../../common/", "#include \"../../../../../common/") + base.replaceInFile("./xml/libxml2/globals.c", "int xmlGetWarningsDefaultValue = 1;", "int xmlGetWarningsDefaultValue = 0;") + base.replaceInFile("./xml/libxml2/globals.c", "static int xmlGetWarningsDefaultValueThrDef = 1;", "static int xmlGetWarningsDefaultValueThrDef = 0;") if not base.is_dir("freetype-2.10.4"): base.copy_dir("../../../freetype-2.10.4", "./freetype-2.10.4") @@ -34,3 +36,6 @@ common.apply_patch("./freetype-2.10.4/builds/unix/ftsystem.c", "./wasm/patches/ftsystem.patch") base.replaceInFile("../../../../Common/3dParty/icu/icu/source/common/udata.cpp", "\n{\n UDataMemory tData;", "\n{\n#ifdef BUILDING_WASM_MODULE\nreturn NULL;\n#endif\n UDataMemory tData;") +base.replaceInFile("../../../../DesktopEditor/cximage/png/pnglibconf.h", "#define PNG_CONSOLE_IO_SUPPORTED", "//#define PNG_CONSOLE_IO_SUPPORTED") + +base.replaceInFile("../../../../Common/3dParty/openssl/openssl/crypto/sha/sha512.c", "const SHA_LONG64 *W = in;", "const SHA_LONG64 *W = (const SHA_LONG64*)in;") diff --git a/DesktopEditor/graphics/pro/js/deploy.py b/DesktopEditor/graphics/pro/js/deploy.py index c92c30bb34e..6a115232ea3 100644 --- a/DesktopEditor/graphics/pro/js/deploy.py +++ b/DesktopEditor/graphics/pro/js/deploy.py @@ -19,3 +19,4 @@ base.copy_file(src_dir + "drawingfile.js", dst_dir + "drawingfile.js") base.copy_file(src_dir + "drawingfile.wasm", dst_dir + "drawingfile.wasm") base.copy_file(src_dir + "drawingfile_ie.js", dst_dir + "drawingfile_ie.js") +base.copy_file(src_dir + "drawingfile_native.js", dst_dir + "drawingfile_native.js") diff --git a/DesktopEditor/graphics/pro/js/drawingfile.json b/DesktopEditor/graphics/pro/js/drawingfile.json index b8521a7c212..681f8f2b6b5 100644 --- a/DesktopEditor/graphics/pro/js/drawingfile.json +++ b/DesktopEditor/graphics/pro/js/drawingfile.json @@ -7,6 +7,11 @@ "run_before": "before.py", "run_after": "after.py", "base_js_content": "./wasm/js/drawingfile_base.js", + "replaces" : { + "stream" : "./wasm/js/stream.js", + "file" : "./wasm/js/drawingfile.js", + "file_internal" : "./wasm/js/drawingfile_wasm.js" + }, "compiler_flags": [ "-O3", @@ -31,6 +36,7 @@ "_GetLinks", "_GetStructure", "_GetInteractiveFormsInfo", + "_GetInteractiveFormsFonts", "_GetInteractiveFormsAP", "_GetButtonIcons", "_GetAnnotationsInfo", @@ -39,13 +45,29 @@ "_InitializeFontsBase64", "_InitializeFontsRanges", "_SetFontBinary", + "_GetFontBinary", "_IsFontBinaryExist", "_DestroyTextInfo", "_IsNeedCMap", - "_SetCMapData" + "_SetCMapData", + "_ScanPage", + "_GetImageBase64", + "_GetImageBase64Len", + "_GetImageBase64Ptr", + "_GetImageBase64Free" ], "include_path": [ - "wasm/src/lib", "../../../agg-2.4/include", "../../../cximage/jasper/include", "../../../cximage/jpeg", "../../../cximage/png", "freetype-2.10.4/include", "freetype-2.10.4/include/freetype", "../../../../OfficeUtils/src/zlib-1.2.11", "../../../../OfficeUtils/src", "../../../../Common/3dParty/icu/icu/source/common", "../../../xml/libxml2/include", "../../../xml/build/qt", "../../../../OfficeUtils/src/zlib-1.2.11/contrib/minizip", "../../../../PdfFile/lib/goo", "../../../../PdfFile/lib/fofi", "../../../../PdfFile/lib/splash", "../../../../PdfFile/lib", "../../../raster/Jp2/openjpeg", "../../../raster/Jp2/openjpeg/openjpeg-2.4.0/src/lib/openjp2" + "wasm/src/lib", + "../../../agg-2.4/include", + "../../../cximage/jasper/include", "../../../cximage/jpeg", "../../../cximage/png", + "freetype-2.10.4/include", "freetype-2.10.4/include/freetype", + "../../../../OfficeUtils/src/zlib-1.2.11", "../../../../OfficeUtils/src/zlib-1.2.11/contrib/minizip", "../../../../OfficeUtils/src", + "../../../../Common/3dParty/icu/icu/source/common", + "../../../xml/libxml2/include", "../../../xml/build/qt", + "../../../../PdfFile/lib/goo", "../../../../PdfFile/lib/fofi", "../../../../PdfFile/lib/splash", "../../../../PdfFile/lib", + "../../../raster/Jp2/openjpeg", "../../../raster/Jp2/openjpeg/openjpeg-2.4.0/src/lib/openjp2", + "../../../../Common/3dParty/openssl/openssl/include", + "../../../../DocxRenderer" ], "define": [ "__linux__", "_LINUX", "UNIX", @@ -58,20 +80,22 @@ "LIBXML_READER_ENABLED", "LIBXML_PUSH_ENABLED", "LIBXML_HTML_ENABLED", "LIBXML_XPATH_ENABLED", "LIBXML_OUTPUT_ENABLED", "LIBXML_C14N_ENABLED", "LIBXML_SAX1_ENABLED", "LIBXML_TREE_ENABLED", "LIBXML_XPTR_ENABLED", - "IN_LIBXML", "LIBXML_STATIC", "BUILD_ZLIB_AS_SOURCES", + "XML_ERROR_DISABLE_MODE", "IN_LIBXML", "LIBXML_STATIC", "BUILD_ZLIB_AS_SOURCES", "_ARM_ALIGN_", "_tcsnicmp=strncmp", "_lseek=lseek", "_getcwd=getcwd", "NO_CONSOLE_IO", "USE_EXTERNAL_JPEG2000", "USE_JPIP", "OPJ_STATIC", "FONT_ENGINE_DISABLE_FILESYSTEM", - "IMAGE_CHECKER_DISABLE_XML" + "IMAGE_CHECKER_DISABLE_XML", + "USE_OPENSSL_HASH", + "DISABLE_FULL_DOCUMENT_CREATION", "DISABLE_FILESYSTEM" ], "compile_files_array": [ { "folder": "../../../raster/", - "files": ["BgraFrame.cpp", "ImageFileFormatChecker.cpp"] + "files": ["BgraFrame.cpp", "ImageFileFormatChecker.cpp", "PICT/PICFile.cpp", "PICT/pic.cpp"] }, { "folder": "../../../cximage/CxImage/", - "files": ["ximaenc.cpp", "ximaexif.cpp", "ximage.cpp", "ximainfo.cpp", "ximajpg.cpp", "ximalpha.cpp", "ximapal.cpp", "ximasel.cpp", "xmemfile.cpp", "ximapng.cpp", "ximabmp.cpp", "ximatran.cpp", "ximatif.cpp", "tif_xfile.cpp", "ximajas.cpp", "ximagif.cpp", "ximaico.cpp", "ximatga.cpp", "ximapcx.cpp", "ximawbmp.cpp", "ximamng.cpp", "ximapsd.cpp", "ximaska.cpp", "ximaraw.cpp"] + "files": ["ximaenc.cpp", "ximaexif.cpp", "ximage.cpp", "ximainfo.cpp", "ximajpg.cpp", "ximalpha.cpp", "ximapal.cpp", "ximasel.cpp", "xmemfile.cpp", "ximapng.cpp", "ximabmp.cpp", "ximatran.cpp", "ximatif.cpp", "tif_xfile.cpp", "ximajas.cpp", "ximagif.cpp", "ximaico.cpp", "ximatga.cpp", "ximapcx.cpp", "ximawbmp.cpp", "ximamng.cpp", "ximapsd.cpp", "ximaska.cpp", "ximaraw.cpp", "ximaint.cpp"] }, { "folder": "../../../cximage/jpeg/", @@ -111,7 +135,7 @@ }, { "folder": "./wasm/src/", - "files": ["lib/wasm_jmp.cpp", "drawingfile.cpp", "metafile.cpp"] + "files": ["lib/wasm_jmp.cpp", "drawingfile.cpp", "metafile.cpp", "pdfwriter.cpp", "HTMLRendererText.cpp"] }, { "folder": "freetype-2.10.4/src/", @@ -119,7 +143,7 @@ }, { "folder": "../../", - "files": ["GraphicsRenderer.cpp", "pro/pro_Graphics.cpp", "pro/pro_Fonts.cpp", "pro/pro_Image.cpp", "Graphics.cpp", "Brush.cpp", "BaseThread.cpp", "GraphicsPath.cpp", "Image.cpp", "Matrix.cpp", "Clip.cpp", "TemporaryCS.cpp", "AlphaMask.cpp", "AlphaMask_private.cpp", "commands/DocInfo.cpp", "commands/AnnotField.cpp", "commands/FormField.cpp"] + "files": ["GraphicsRenderer.cpp", "pro/pro_Graphics.cpp", "pro/pro_Fonts.cpp", "pro/pro_Image.cpp", "Graphics.cpp", "Brush.cpp", "BaseThread.cpp", "GraphicsPath.cpp", "BooleanOperations.cpp", "Image.cpp", "Matrix.cpp", "Clip.cpp", "TemporaryCS.cpp", "AlphaMask.cpp", "GraphicsLayer.cpp", "commands/DocInfo.cpp", "commands/AnnotField.cpp", "commands/FormField.cpp"] }, { "folder": "../../../fontengine/", @@ -155,7 +179,7 @@ }, { "folder": "../../../../PdfFile/", - "files": ["SrcReader/Adaptors.cpp", "SrcReader/GfxClip.cpp", "SrcReader/RendererOutputDev.cpp", "SrcReader/JPXStream2.cpp", "SrcReader/PdfAnnot.cpp", "Resources/BaseFonts.cpp", "Resources/CMapMemory/cmap_memory.cpp", "lib/fofi/FofiBase.cc", "lib/fofi/FofiEncodings.cc", "lib/fofi/FofiIdentifier.cc", "lib/fofi/FofiTrueType.cc", "lib/fofi/FofiType1.cc", "lib/fofi/FofiType1C.cc", "lib/goo/FixedPoint.cc", "lib/goo/gfile.cc", "lib/goo/GHash.cc", "lib/goo/GList.cc", "lib/goo/gmem.cc", "lib/goo/gmempp.cc", "lib/goo/GString.cc", "lib/goo/parseargs.c", "lib/goo/Trace.cc", "lib/splash/Splash.cc", "lib/splash/SplashBitmap.cc", "lib/splash/SplashClip.cc", "lib/splash/SplashFont.cc", "lib/splash/SplashFontEngine.cc", "lib/splash/SplashFontFile.cc", "lib/splash/SplashFontFileID.cc", "lib/splash/SplashFTFont.cc", "lib/splash/SplashFTFontEngine.cc", "lib/splash/SplashFTFontFile.cc", "lib/splash/SplashPath.cc", "lib/splash/SplashPattern.cc", "lib/splash/SplashScreen.cc", "lib/splash/SplashState.cc", "lib/splash/SplashXPath.cc", "lib/splash/SplashXPathScanner.cc", "lib/xpdf/AcroForm.cc", "lib/xpdf/Annot.cc", "lib/xpdf/Array.cc", "lib/xpdf/BuiltinFont.cc", "lib/xpdf/BuiltinFontTables.cc", "lib/xpdf/Catalog.cc", "lib/xpdf/CharCodeToUnicode.cc", "lib/xpdf/CMap.cc", "lib/xpdf/Decrypt.cc", "lib/xpdf/Dict.cc", "lib/xpdf/DisplayState.cc", "lib/xpdf/Error.cc", "lib/xpdf/FontEncodingTables.cc", "lib/xpdf/Function.cc", "lib/xpdf/Gfx.cc", "lib/xpdf/GfxFont.cc", "lib/xpdf/GfxState.cc", "lib/xpdf/GlobalParams.cc", "lib/xpdf/ImageOutputDev.cc", "lib/xpdf/JArithmeticDecoder.cc", "lib/xpdf/JBIG2Stream.cc", "lib/xpdf/JPXStream.cc", "lib/xpdf/Lexer.cc", "lib/xpdf/Link.cc", "lib/xpdf/NameToCharCode.cc", "lib/xpdf/Object.cc", "lib/xpdf/OptionalContent.cc", "lib/xpdf/Outline.cc", "lib/xpdf/OutputDev.cc", "lib/xpdf/Page.cc", "lib/xpdf/Parser.cc", "lib/xpdf/PDF417Barcode.cc", "lib/xpdf/PDFCore.cc", "lib/xpdf/PDFDoc.cc", "lib/xpdf/PDFDocEncoding.cc", "lib/xpdf/PreScanOutputDev.cc", "lib/xpdf/PSOutputDev.cc", "lib/xpdf/PSTokenizer.cc", "lib/xpdf/SecurityHandler.cc", "lib/xpdf/ShadingImage.cc", "lib/xpdf/SplashOutputDev.cc", "lib/xpdf/Stream.cc", "lib/xpdf/TextOutputDev.cc", "lib/xpdf/TextString.cc", "lib/xpdf/TileCache.cc", "lib/xpdf/TileCompositor.cc", "lib/xpdf/TileMap.cc", "lib/xpdf/UnicodeMap.cc", "lib/xpdf/UnicodeRemapping.cc", "lib/xpdf/UnicodeTypeTable.cc", "lib/xpdf/UTF8.cc", "lib/xpdf/WebFont.cc", "lib/xpdf/XFAScanner.cc", "lib/xpdf/XRef.cc", "lib/xpdf/Zoox.cc", "PdfFile.cpp", "PdfReader.cpp", "PdfWriter_empty.cpp"] + "files": ["SrcReader/Adaptors.cpp", "SrcReader/GfxClip.cpp", "SrcReader/RendererOutputDev.cpp", "SrcReader/JPXStream2.cpp", "SrcReader/PdfAnnot.cpp", "Resources/BaseFonts.cpp", "Resources/CMapMemory/cmap_memory.cpp", "lib/fofi/FofiBase.cc", "lib/fofi/FofiEncodings.cc", "lib/fofi/FofiIdentifier.cc", "lib/fofi/FofiTrueType.cc", "lib/fofi/FofiType1.cc", "lib/fofi/FofiType1C.cc", "lib/goo/FixedPoint.cc", "lib/goo/gfile.cc", "lib/goo/GHash.cc", "lib/goo/GList.cc", "lib/goo/gmem.cc", "lib/goo/gmempp.cc", "lib/goo/GString.cc", "lib/goo/parseargs.c", "lib/goo/Trace.cc", "lib/splash/Splash.cc", "lib/splash/SplashBitmap.cc", "lib/splash/SplashClip.cc", "lib/splash/SplashFont.cc", "lib/splash/SplashFontEngine.cc", "lib/splash/SplashFontFile.cc", "lib/splash/SplashFontFileID.cc", "lib/splash/SplashFTFont.cc", "lib/splash/SplashFTFontEngine.cc", "lib/splash/SplashFTFontFile.cc", "lib/splash/SplashPath.cc", "lib/splash/SplashPattern.cc", "lib/splash/SplashScreen.cc", "lib/splash/SplashState.cc", "lib/splash/SplashXPath.cc", "lib/splash/SplashXPathScanner.cc", "lib/xpdf/AcroForm.cc", "lib/xpdf/Annot.cc", "lib/xpdf/Array.cc", "lib/xpdf/BuiltinFont.cc", "lib/xpdf/BuiltinFontTables.cc", "lib/xpdf/Catalog.cc", "lib/xpdf/CharCodeToUnicode.cc", "lib/xpdf/CMap.cc", "lib/xpdf/Decrypt.cc", "lib/xpdf/Dict.cc", "lib/xpdf/DisplayState.cc", "lib/xpdf/Error.cc", "lib/xpdf/FontEncodingTables.cc", "lib/xpdf/Function.cc", "lib/xpdf/Gfx.cc", "lib/xpdf/GfxFont.cc", "lib/xpdf/GfxState.cc", "lib/xpdf/GlobalParams.cc", "lib/xpdf/ImageOutputDev.cc", "lib/xpdf/JArithmeticDecoder.cc", "lib/xpdf/JBIG2Stream.cc", "lib/xpdf/JPXStream.cc", "lib/xpdf/Lexer.cc", "lib/xpdf/Link.cc", "lib/xpdf/NameToCharCode.cc", "lib/xpdf/Object.cc", "lib/xpdf/OptionalContent.cc", "lib/xpdf/Outline.cc", "lib/xpdf/OutputDev.cc", "lib/xpdf/Page.cc", "lib/xpdf/Parser.cc", "lib/xpdf/PDF417Barcode.cc", "lib/xpdf/PDFCore.cc", "lib/xpdf/PDFDoc.cc", "lib/xpdf/PDFDocEncoding.cc", "lib/xpdf/PreScanOutputDev.cc", "lib/xpdf/PSOutputDev.cc", "lib/xpdf/PSTokenizer.cc", "lib/xpdf/SecurityHandler.cc", "lib/xpdf/ShadingImage.cc", "lib/xpdf/SplashOutputDev.cc", "lib/xpdf/Stream.cc", "lib/xpdf/TextOutputDev.cc", "lib/xpdf/TextString.cc", "lib/xpdf/TileCache.cc", "lib/xpdf/TileCompositor.cc", "lib/xpdf/TileMap.cc", "lib/xpdf/UnicodeMap.cc", "lib/xpdf/UnicodeRemapping.cc", "lib/xpdf/UnicodeTypeTable.cc", "lib/xpdf/UTF8.cc", "lib/xpdf/WebFont.cc", "lib/xpdf/XFAScanner.cc", "lib/xpdf/XRef.cc", "lib/xpdf/Zoox.cc", "PdfFile.cpp", "PdfReader.cpp"] }, { "folder": "../../../raster/Jp2/openjpeg/openjpeg-2.4.0/src/lib/openjp2/", @@ -177,13 +201,33 @@ "folder": "../", "files": ["officedrawingfile.cpp"] }, - { - "folder": "../../../../HtmlRenderer/src/", - "files": ["HTMLRendererText.cpp"] - }, { "folder": "../../../../UnicodeConverter/", "files": ["UnicodeConverter.cpp"] + }, + { + "folder": "../../../../DocxRenderer/", + "files": ["DocxRenderer.cpp"] + }, + { + "folder": "../../../../DocxRenderer/src/resources", + "files": ["VectorGraphics.cpp"] + }, + { + "folder": "../../../../DocxRenderer/src/logic", + "files": ["styles/FontStyle.cpp", "styles/ParagraphStyle.cpp", "Page.cpp", "Document.cpp"] + }, + { + "folder": "../../../../DocxRenderer/src/logic/managers", + "files": ["FontManager.cpp", "FontStyleManager.cpp", "ImageManager.cpp", "ParagraphStyleManager.cpp"] + }, + { + "folder": "../../../../DocxRenderer/src/logic/elements", + "files": ["BaseItem.cpp", "ContText.cpp", "Paragraph.cpp", "Shape.cpp", "TextLine.cpp", "Table.cpp"] + }, + { + "folder": "../../../common", + "files": ["StringUTF32.cpp", "StringBuilder.cpp"] } ] } diff --git a/DesktopEditor/graphics/pro/js/qt/nativegraphics.pro b/DesktopEditor/graphics/pro/js/qt/nativegraphics.pro index bf3f3877b5d..3b3710f95f0 100644 --- a/DesktopEditor/graphics/pro/js/qt/nativegraphics.pro +++ b/DesktopEditor/graphics/pro/js/qt/nativegraphics.pro @@ -19,7 +19,7 @@ include($$CORE_ROOT_DIR/Common/base.pri) include($$CORE_ROOT_DIR/Common/3dParty/icu/icu.pri) include(../../freetype.pri) -ADD_DEPENDENCY(UnicodeConverter, kernel, HtmlRenderer) +ADD_DEPENDENCY(UnicodeConverter, kernel) INCLUDEPATH += \ $$CORE_ROOT_DIR/DesktopEditor/agg-2.4/include \ @@ -27,7 +27,8 @@ INCLUDEPATH += \ $$CORE_ROOT_DIR/DesktopEditor/cximage/jpeg \ $$CORE_ROOT_DIR/DesktopEditor/cximage/png \ $$CORE_ROOT_DIR/DesktopEditor/freetype-2.10.4/include \ - $$CORE_ROOT_DIR/DesktopEditor/freetype-2.10.4/include/freetype + $$CORE_ROOT_DIR/DesktopEditor/freetype-2.10.4/include/freetype \ + $$CORE_ROOT_DIR/Common/3dParty/openssl/openssl/include win32 { DEFINES += \ @@ -52,8 +53,9 @@ HEADERS += \ ../../../Matrix.h \ ../../../Matrix_private.h \ ../../../GraphicsPath.h \ + ../../../BooleanOperations.h \ + ../../../boolean_operations_math.h \ ../../../GraphicsPath_private.h \ - ../../../AlphaMask_private.h \ ../../../AlphaMask.h \ \ ../../../../raster/BgraFrame.h \ @@ -66,6 +68,7 @@ HEADERS += \ ../../../../raster/Metafile/Common/MetaFileObjects.h \ ../../../../raster/Metafile/Common/MetaFileRenderer.h \ ../../../../raster/Metafile/Common/MetaFileUtils.h \ + ../../../../raster/PICT/PICTFile.h \ \ ../../../ArrowHead.h \ ../../../Brush.h \ @@ -78,6 +81,7 @@ HEADERS += \ ../../../structures.h \ ../../../shading_info.h \ ../../../GraphicsRenderer.h \ + ../../../GraphicsLayer.h \ \ ../../../../fontengine/ApplicationFonts.h \ ../../../../fontengine/FontFile.h \ @@ -103,11 +107,13 @@ HEADERS += \ SOURCES += \ ../../../Matrix.cpp \ ../../../GraphicsPath.cpp \ - ../../../AlphaMask_private.cpp \ + ../../../BooleanOperations.cpp \ ../../../AlphaMask.cpp \ ../../../../raster/BgraFrame.cpp \ ../../../../raster/ImageFileFormatChecker.cpp \ ../../../../raster/Metafile/MetaFile.cpp \ + ../../../../raster/PICT/PICFile.cpp \ + ../../../../raster/PICT/pic.cpp \ \ ../../../ArrowHead.cpp \ ../../../Brush.cpp \ @@ -115,6 +121,7 @@ SOURCES += \ ../../../Graphics.cpp \ ../../../GraphicsRenderer.cpp \ ../../../Image.cpp \ + ../../../GraphicsLayer.cpp \ \ ../../../../fontengine/ApplicationFonts.cpp \ ../../../../fontengine/FontFile.cpp \ @@ -454,7 +461,7 @@ SOURCES += \ # XpsFile -XPS_ROOT_DIR = $$PWD/../../../../../XpsFile +XPS_ROOT_DIR = $$CORE_ROOT_DIR/XpsFile HEADERS += \ $$XPS_ROOT_DIR/XpsFile.h \ @@ -481,8 +488,8 @@ DEFINES += \ THREADMODEL=0 \ DEBUGLVL=0 -DJVU_ROOT_DIR = $$PWD/../../../../../DjVuFile -DJVU_WRAPPER = $$PWD/../../../../../DjVuFile/wasm/libdjvu +DJVU_ROOT_DIR = $$CORE_ROOT_DIR/DjVuFile +DJVU_WRAPPER = $$CORE_ROOT_DIR/DjVuFile/wasm/libdjvu HEADERS += \ $$DJVU_ROOT_DIR/DjVu.h \ @@ -604,7 +611,7 @@ SOURCES += \ $$DJVU_WRAPPER/GURL.cpp # PdfReader -PDF_ROOT_DIR = $$PWD/../../../../../PdfFile +PDF_ROOT_DIR = $$CORE_ROOT_DIR/PdfFile INCLUDEPATH += \ $$PDF_ROOT_DIR/lib/goo \ @@ -639,7 +646,6 @@ SOURCES += \ $$PDF_ROOT_DIR/Resources/BaseFonts.cpp \ $$PDF_ROOT_DIR/Resources/CMapMemory/cmap_memory.cpp \ $$PDF_ROOT_DIR/PdfReader.cpp \ - $$PDF_ROOT_DIR/PdfWriter_empty.cpp \ $$PDF_ROOT_DIR/PdfFile.cpp HEADERS +=\ @@ -668,11 +674,60 @@ HEADERS +=\ $$PDF_ROOT_DIR/PdfReader.h \ $$PDF_ROOT_DIR/PdfFile.h -HEADERS += $$CORE_ROOT_DIR/HtmlRenderer/include/HTMLRendererText.h -SOURCES += $$CORE_ROOT_DIR/HtmlRenderer/src/HTMLRendererText.cpp +# DocxRenderer +DOCX_RENDERER_ROOT_DIR = $$CORE_ROOT_DIR/DocxRenderer +HEADERS += \ + $$DOCX_RENDERER_ROOT_DIR/src/logic/elements/BaseItem.h \ + $$DOCX_RENDERER_ROOT_DIR/src/logic/elements/ContText.h \ + $$DOCX_RENDERER_ROOT_DIR/src/logic/elements/DropCap.h \ + $$DOCX_RENDERER_ROOT_DIR/src/logic/elements/Paragraph.h \ + $$DOCX_RENDERER_ROOT_DIR/src/logic/elements/Shape.h \ + $$DOCX_RENDERER_ROOT_DIR/src/logic/elements/TextLine.h \ + $$DOCX_RENDERER_ROOT_DIR/src/logic/managers/ExternalImageStorage.h \ + $$DOCX_RENDERER_ROOT_DIR/src/logic/managers/FontStyleManager.h \ + $$DOCX_RENDERER_ROOT_DIR/src/logic/managers/ImageManager.h \ + $$DOCX_RENDERER_ROOT_DIR/src/logic/managers/FontManager.h \ + $$DOCX_RENDERER_ROOT_DIR/src/logic/managers/ParagraphStyleManager.h \ + $$DOCX_RENDERER_ROOT_DIR/src/logic/styles/FontStyle.h \ + $$DOCX_RENDERER_ROOT_DIR/src/logic/styles/ParagraphStyle.h \ + $$DOCX_RENDERER_ROOT_DIR/src/resources/ColorTable.h \ + $$DOCX_RENDERER_ROOT_DIR/src/resources/Constants.h \ + $$DOCX_RENDERER_ROOT_DIR/src/resources/ImageInfo.h \ + $$DOCX_RENDERER_ROOT_DIR/src/resources/LinesTable.h \ + $$DOCX_RENDERER_ROOT_DIR/src/resources/VectorGraphics.h \ + $$DOCX_RENDERER_ROOT_DIR/src/resources/resources.h \ + $$DOCX_RENDERER_ROOT_DIR/src/resources/utils.h \ + $$DOCX_RENDERER_ROOT_DIR/src/logic/Page.h \ + $$DOCX_RENDERER_ROOT_DIR/src/logic/Document.h \ + $$DOCX_RENDERER_ROOT_DIR/DocxRenderer.h + +SOURCES += \ + $$DOCX_RENDERER_ROOT_DIR/src/logic/elements/BaseItem.cpp \ + $$DOCX_RENDERER_ROOT_DIR/src/logic/elements/ContText.cpp \ + $$DOCX_RENDERER_ROOT_DIR/src/logic/elements/Paragraph.cpp \ + $$DOCX_RENDERER_ROOT_DIR/src/logic/elements/Shape.cpp \ + $$DOCX_RENDERER_ROOT_DIR/src/logic/elements/TextLine.cpp \ + $$DOCX_RENDERER_ROOT_DIR/src/logic/managers/FontManager.cpp \ + $$DOCX_RENDERER_ROOT_DIR/src/logic/managers/FontStyleManager.cpp \ + $$DOCX_RENDERER_ROOT_DIR/src/logic/managers/ImageManager.cpp \ + $$DOCX_RENDERER_ROOT_DIR/src/logic/managers/ParagraphStyleManager.cpp \ + $$DOCX_RENDERER_ROOT_DIR/src/logic/styles/FontStyle.cpp \ + $$DOCX_RENDERER_ROOT_DIR/src/logic/Page.cpp \ + $$DOCX_RENDERER_ROOT_DIR/src/logic/Document.cpp \ + $$DOCX_RENDERER_ROOT_DIR/src/logic/styles/ParagraphStyle.cpp \ + $$DOCX_RENDERER_ROOT_DIR/src/resources/VectorGraphics.cpp \ + $$DOCX_RENDERER_ROOT_DIR/DocxRenderer.cpp \ + $$DOCX_RENDERER_ROOT_DIR/src/resources/resources.cpp + +HEADERS += $$CORE_ROOT_DIR/DesktopEditor/doctrenderer/drawingfile.h HEADERS += \ - ../wasm/src/drawingfile.h \ - ../wasm/src/serialize.h + ../wasm/src/serialize.h \ + ../wasm/src/HTMLRendererText.h \ + ../wasm/src/Text.h -SOURCES += ../wasm/src/drawingfile_test.cpp +SOURCES += \ + ../wasm/src/pdfwriter.cpp \ + ../wasm/src/HTMLRendererText.cpp \ + ../wasm/src/drawingfile.cpp \ + ../wasm/src/drawingfile_test.cpp diff --git a/DesktopEditor/graphics/pro/js/qt/raster/pro_Fonts_empty.cpp b/DesktopEditor/graphics/pro/js/qt/raster/pro_Fonts_empty.cpp index 5f066950235..1cb3a84884b 100644 --- a/DesktopEditor/graphics/pro/js/qt/raster/pro_Fonts_empty.cpp +++ b/DesktopEditor/graphics/pro/js/qt/raster/pro_Fonts_empty.cpp @@ -1,5 +1,5 @@ /* - * (c) Copyright Ascensio System SIA 2010-2023 + * (c) Copyright Ascensio System SIA 2010-2024 * * This program is a free software product. You can redistribute it and/or * modify it under the terms of the GNU Affero General Public License (AGPL) diff --git a/DesktopEditor/graphics/pro/js/qt/raster/pro_Graphics_empty.cpp b/DesktopEditor/graphics/pro/js/qt/raster/pro_Graphics_empty.cpp index aeae76a4cc1..12c2f84ffdf 100644 --- a/DesktopEditor/graphics/pro/js/qt/raster/pro_Graphics_empty.cpp +++ b/DesktopEditor/graphics/pro/js/qt/raster/pro_Graphics_empty.cpp @@ -1,5 +1,5 @@ /* - * (c) Copyright Ascensio System SIA 2010-2023 + * (c) Copyright Ascensio System SIA 2010-2024 * * This program is a free software product. You can redistribute it and/or * modify it under the terms of the GNU Affero General Public License (AGPL) diff --git a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js new file mode 100644 index 00000000000..c75590e0e7b --- /dev/null +++ b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js @@ -0,0 +1,1505 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ + +var UpdateFontsSource = { + Undefined : 0, + Page : 1, + Annotation : 2, + Forms : 4 +}; + +function CFile() +{ + this.nativeFile = 0; + this.stream = -1; + this.stream_size = 0; + this.type = -1; + this.pages = []; + this.info = null; + this._isNeedPassword = false; + + // for async fonts loader + this.fontPageIndex = -1; + this.fontPageUpdateType = UpdateFontsSource.Undefined; + this.fontStreams = {}; + + this.scannedImages = {}; +} + +//file_internal + +CFile.prototype.lockPageNumForFontsLoader = function(pageIndex, type) +{ + this.fontPageIndex = pageIndex; + this.fontPageUpdateType = type; +}; +CFile.prototype.unlockPageNumForFontsLoader = function() +{ + this.fontPageIndex = -1; + drawingFile.fontPageUpdateType = UpdateFontsSource.Undefined; +}; + +CFile.prototype["getPages"] = function() +{ + return this.pages; +}; + +CFile.prototype["openForms"] = function() +{ +}; + +CFile.prototype["getDocumentInfo"] = function() +{ + return this.info; +}; + +CFile.prototype["getStartID"] = function() +{ + return this.StartID; +}; + +// FILE +CFile.prototype["loadFromData"] = function(arrayBuffer) +{ + let isSuccess = this._openFile(arrayBuffer); + let error = this._getError(); // 0 - ok, 4 - password, else: error + this.type = this._getType(); + + self.drawingFile = this; + if (!error) + this.getInfo(); + this._isNeedPassword = (4 === error) ? true : false; + return error; +}; +CFile.prototype["loadFromDataWithPassword"] = function(password) +{ + if (0 != this.nativeFile) + this._closeFile(); + + let isSuccess = this._openFile(undefined, password); + let error = this._getError(); // 0 - ok, 4 - password, else: error + this.type = this._getType(); + + self.drawingFile = this; + if (!error) + this.getInfo(); + this._isNeedPassword = (4 === error) ? true : false; + return error; +}; + +CFile.prototype["getType"] = function() +{ + return this.type; +}; + +CFile.prototype["close"] = function() +{ + this._closeFile(); + this.nativeFile = 0; + this.pages = []; + this.info = null; + this.StartID = null; + if (this.stream > 0) + this._free(this.stream); + this.stream = -1; + self.drawingFile = null; +}; + +CFile.prototype["getFileBinary"] = function() +{ + if (0 >= this.stream) + return ""; + return new Uint8Array(Module["HEAP8"].buffer, this.stream, this.stream_size); +}; + +CFile.prototype["isNeedPassword"] = function() +{ + return this._isNeedPassword; +}; + +// INFO DOCUMENT +CFile.prototype.getInfo = function() +{ + if (!this.nativeFile) + return false; + + let ptr = this._getInfo(); + let reader = ptr.getReader(); + if (!reader) return false; + + this.StartID = reader.readInt(); + + let _pages = reader.readInt(); + for (let i = 0; i < _pages; i++) + { + let rec = {}; + rec["W"] = reader.readInt(); + rec["H"] = reader.readInt(); + rec["Dpi"] = reader.readInt(); + rec["Rotate"] = reader.readInt(); + rec["originIndex"] = i; + rec.fonts = []; + rec.fontsUpdateType = UpdateFontsSource.Undefined; + rec.text = null; + this.pages.push(rec); + } + let json_info = reader.readString(); + try + { + this.info = JSON.parse(json_info); + } catch(err) {} + + ptr.free(); + return this.pages.length > 0; +}; + +CFile.prototype["getStructure"] = function() +{ + let ptr = this._getStructure(); + let reader = ptr.getReader(); + + if (!reader) return []; + + let res = []; + while (reader.isValid()) + { + let rec = {}; + rec["page"] = reader.readInt(); + rec["level"] = reader.readInt(); + rec["y"] = reader.readDouble(); + rec["description"] = reader.readString(); + res.push(rec); + } + + ptr.free(); + return res; +}; + +CFile.prototype["getLinks"] = function(pageIndex) +{ + let ptr = this._getLinks(pageIndex); + let reader = ptr.getReader(); + + if (!reader) return []; + + let res = []; + while (reader.isValid()) + { + let rec = {}; + rec["link"] = reader.readString(); + rec["dest"] = reader.readDouble(); + rec["x"] = reader.readDouble(); + rec["y"] = reader.readDouble(); + rec["w"] = reader.readDouble(); + rec["h"] = reader.readDouble(); + res.push(rec); + } + + ptr.free(); + return res; +}; + +// TEXT +CFile.prototype["getGlyphs"] = function(pageIndex) +{ + let page = this.pages[pageIndex]; + if (page.originIndex == undefined) + return []; + if (page.fonts.length > 0) + { + // waiting fonts + return null; + } + + this.lockPageNumForFontsLoader(pageIndex, UpdateFontsSource.Page); + let res = this._getGlyphs(page.originIndex); + // there is no need to delete the result; this buffer is used as a text buffer + // for text commands on other pages. After receiving ALL text pages, + // you need to call destroyTextInfo() + this.unlockPageNumForFontsLoader(); + + if (page.fonts.length > 0) + { + // waiting fonts + res = null; + return null; + } + + if (res && this.onUpdateStatistics) + this.onUpdateStatistics(res.info[0], res.info[1], res.info[2], res.info[3]); + + return res.result || null; +}; +CFile.prototype["destroyTextInfo"] = function() +{ + this._destroyTextInfo(); +}; + +// FONTS +CFile.prototype.getWidgetFonts = function(type) +{ + let ptr = this._getInteractiveFormsFonts(type); + let reader = ptr.getReader(); + if (!reader) return []; + + let res = []; + while (reader.isValid()) + { + let n = reader.readInt(); + for (let i = 0; i < n; ++i) + res.push(reader.readString()); + } + + ptr.free(); + return res; +}; + +CFile.prototype["getInteractiveFormsEmbeddedFonts"] = function() +{ + return this.getWidgetFonts(1); +}; + +CFile.prototype["getInteractiveFormsStandardFonts"] = function() +{ + return this.getWidgetFonts(2); +}; + +CFile.prototype["getFontByID"] = function(ID) +{ + return this._getFontByID(ID); +}; + +CFile.prototype["setCMap"] = function(memoryBuffer) +{ + if (!this.nativeFile) + return; + + this._setCMap(memoryBuffer); +}; + +CFile.prototype["isNeedCMap"] = function() +{ + return this._isNeedCMap(); +}; + +// WIDGETS & ANNOTATIONS +function readAction(reader, rec) +{ + let SType = reader.readByte(); + // 0 - Unknown, 1 - GoTo, 2 - GoToR, 3 - GoToE, 4 - Launch + // 5 - Thread, 6 - URI, 7 - Sound, 8 - Movie, 9 - Hide + // 10 - Named, 11 - SubmitForm, 12 - ResetForm, 13 - ImportData + // 14 - JavaScript, 15 - SetOCGState, 16 - Rendition + // 17 - Trans, 18 - GoTo3DView + rec["S"] = SType; + if (SType == 14) + { + rec["JS"] = reader.readString(); + } + else if (SType == 1) + { + rec["page"] = reader.readInt(); + rec["kind"] = reader.readByte(); + // 0 - XYZ + // 1 - Fit + // 2 - FitH + // 3 - FitV + // 4 - FitR + // 5 - FitB + // 6 - FitBH + // 7 - FitBV + switch (rec["kind"]) + { + case 0: + case 2: + case 3: + case 6: + case 7: + { + let nFlag = reader.readByte(); + if (nFlag & (1 << 0)) + rec["left"] = reader.readDouble(); + if (nFlag & (1 << 1)) + rec["top"] = reader.readDouble(); + if (nFlag & (1 << 2)) + rec["zoom"] = reader.readDouble(); + break; + } + case 4: + { + rec["left"] = reader.readDouble(); + rec["bottom"] = reader.readDouble(); + rec["right"] = reader.readDouble(); + rec["top"] = reader.readDouble(); + break; + } + case 1: + case 5: + default: + break; + } + } + else if (SType == 10) + { + rec["N"] = reader.readString(); + } + else if (SType == 6) + { + rec["URI"] = reader.readString(); + } + else if (SType == 9) + { + rec["H"] = reader.readByte(); + let m = reader.readInt(); + rec["T"] = []; + // array of annotation names - rec["name"] + for (let j = 0; j < m; ++j) + rec["T"].push(reader.readString()); + } + else if (SType == 12) + { + rec["Flags"] = reader.readInt(); + let m = reader.readInt(); + rec["Fields"] = []; + // array of annotation names - rec["name"] + for (let j = 0; j < m; ++j) + rec["Fields"].push(reader.readString()); + } + let NextAction = reader.readByte(); + if (NextAction) + { + rec["Next"] = {}; + readAction(reader, rec["Next"]); + } +} +function readAnnot(reader, rec) +{ + rec["AP"] = {}; + // Annot + // number for relations with AP + rec["AP"]["i"] = reader.readInt(); + rec["annotflag"] = reader.readInt(); + // 12.5.3 + let bHidden = (rec["annotflag"] >> 1) & 1; // Hidden + let bPrint = (rec["annotflag"] >> 2) & 1; // Print + rec["noZoom"] = (rec["annotflag"] >> 3) & 1; // NoZoom + rec["noRotate"] = (rec["annotflag"] >> 4) & 1; // NoRotate + let bNoView = (rec["annotflag"] >> 5) & 1; // NoView + rec["locked"] = (rec["annotflag"] >> 7) & 1; // Locked + rec["ToggleNoView"] = (rec["annotflag"] >> 8) & 1; // ToggleNoView + rec["lockedC"] = (rec["annotflag"] >> 9) & 1; // LockedContents + // 0 - visible, 1 - hidden, 2 - noPrint, 3 - noView + rec["display"] = 0; + if (bHidden) + rec["display"] = 1; + else + { + if (bPrint) + { + if (bNoView) + rec["display"] = 3; + else + rec["display"] = 0; + } + else + { + if (bNoView) + rec["display"] = 0; // ??? no hidden, but noView and no print + else + rec["display"] = 2; + } + } + rec["page"] = reader.readInt(); + // offsets like getStructure and viewer.navigate + rec["rect"] = {}; + rec["rect"]["x1"] = reader.readDouble2(); + rec["rect"]["y1"] = reader.readDouble2(); + rec["rect"]["x2"] = reader.readDouble2(); + rec["rect"]["y2"] = reader.readDouble2(); + let flags = reader.readInt(); + // Unique name - NM + if (flags & (1 << 0)) + rec["UniqueName"] = reader.readString(); + // Alternate annotation text - Contents + if (flags & (1 << 1)) + rec["Contents"] = reader.readString(); + // Border effect - BE + if (flags & (1 << 2)) + { + rec["BE"] = {}; + rec["BE"]["S"] = reader.readByte(); + rec["BE"]["I"] = reader.readDouble(); + } + // Special annotation color - С + if (flags & (1 << 3)) + { + let n = reader.readInt(); + rec["C"] = []; + for (let i = 0; i < n; ++i) + rec["C"].push(reader.readDouble2()); + } + // Border/BS + if (flags & (1 << 4)) + { + // 0 - solid, 1 - beveled, 2 - dashed, 3 - inset, 4 - underline + rec["border"] = reader.readByte(); + rec["borderWidth"] = reader.readDouble(); + // Border Dash Pattern + if (rec["border"] == 2) + { + let n = reader.readInt(); + rec["dashed"] = []; + for (let i = 0; i < n; ++i) + rec["dashed"].push(reader.readDouble()); + } + } + // Date of last change - M + if (flags & (1 << 5)) + rec["LastModified"] = reader.readString(); + // AP + rec["AP"]["have"] = (flags >> 6) & 1; + // User ID + if (flags & (1 << 7)) + rec["OUserID"] = reader.readString(); +} +function readAnnotAP(reader, AP) +{ + // number for relations with AP + AP["i"] = reader.readInt(); + AP["x"] = reader.readDouble(); + AP["y"] = reader.readDouble(); + AP["w"] = reader.readInt(); + AP["h"] = reader.readInt(); + let n = reader.readInt(); + for (let i = 0; i < n; ++i) + { + let APType = reader.readString(); + if (!AP[APType]) + AP[APType] = {}; + let APi = AP[APType]; + let ASType = reader.readString(); + if (ASType) + { + AP[APType][ASType] = {}; + APi = AP[APType][ASType]; + } + let np1 = reader.readInt(); + let np2 = reader.readInt(); + // this memory needs to be deleted + APi["retValue"] = np2 << 32 | np1; + // 0 - Normal, 1 - Multiply, 2 - Screen, 3 - Overlay, 4 - Darken, 5 - Lighten, 6 - ColorDodge, 7 - ColorBurn, 8 - HardLight, + // 9 - SoftLight, 10 - Difference, 11 - Exclusion, 12 - Hue, 13 - Saturation, 14 - Color, 15 - Luminosity + APi["BlendMode"] = reader.readByte(); + } +} + +CFile.prototype["getInteractiveFormsInfo"] = function() +{ + let ptr = this._getInteractiveFormsInfo(); + let reader = ptr.getReader(); + if (!reader) return {}; + + let res = {}; + let k = reader.readInt(); + if (k > 0) + res["CO"] = []; + for (let i = 0; i < k; ++i) + res["CO"].push(reader.readInt()); + + k = reader.readInt(); + if (k > 0) + res["Parents"] = []; + for (let i = 0; i < k; ++i) + { + let rec = {}; + rec["i"] = reader.readInt(); + let flags = reader.readInt(); + if (flags & (1 << 0)) + rec["name"] = reader.readString(); + if (flags & (1 << 1)) + rec["value"] = reader.readString(); + if (flags & (1 << 2)) + rec["defaultValue"] = reader.readString(); + if (flags & (1 << 3)) + { + let n = reader.readInt(); + rec["curIdxs"] = []; + for (let i = 0; i < n; ++i) + rec["curIdxs"].push(reader.readInt()); + } + if (flags & (1 << 4)) + rec["Parent"] = reader.readInt(); + if (flags & (1 << 5)) + { + let n = reader.readInt(); + rec["value"] = []; + for (let i = 0; i < n; ++i) + rec["value"].push(reader.readString()); + } + if (flags & (1 << 6)) + { + let n = reader.readInt(); + rec["Opt"] = []; + for (let i = 0; i < n; ++i) + rec["Opt"].push(reader.readString()); + } + res["Parents"].push(rec); + } + + res["Fields"] = []; + k = reader.readInt(); + for (let q = 0; reader.isValid() && q < k; ++q) + { + let rec = {}; + // Widget type - FT + // 26 - Unknown, 27 - button, 28 - radiobutton, 29 - checkbox, 30 - text, 31 - combobox, 32 - listbox, 33 - signature + rec["type"] = reader.readByte(); + // Annot + readAnnot(reader, rec); + // Widget + rec["font"] = {}; + rec["font"]["name"] = reader.readString(); + rec["font"]["size"] = reader.readDouble(); + rec["font"]["style"] = reader.readInt(); + let tc = reader.readInt(); + if (tc) + { + rec["font"]["color"] = []; + for (let i = 0; i < tc; ++i) + rec["font"]["color"].push(reader.readDouble2()); + } + // 0 - left-justified, 1 - centered, 2 - right-justified + rec["alignment"] = reader.readByte(); + rec["flag"] = reader.readInt(); + // 12.7.3.1 + rec["readOnly"] = (rec["flag"] >> 0) & 1; // ReadOnly + rec["required"] = (rec["flag"] >> 1) & 1; // Required + rec["noexport"] = (rec["flag"] >> 2) & 1; // NoExport + let flags = reader.readInt(); + // Alternative field name, used in tooltip and error messages - TU + if (flags & (1 << 0)) + rec["userName"] = reader.readString(); + // Default style string (CSS2 format) - DS + if (flags & (1 << 1)) + rec["defaultStyle"] = reader.readString(); + // Actual font + if (flags & (1 << 2)) + rec["font"]["actual"] = reader.readString(); + // Selection mode - H + // 0 - none, 1 - invert, 2 - push, 3 - outline + if (flags & (1 << 3)) + rec["highlight"] = reader.readByte(); + // Font key + if (flags & (1 << 4)) + rec["font"]["key"] = reader.readString(); + // Border color - BC. Even if the border is not specified by BS/Border, + // then if BC is present, a default border is provided (solid, thickness 1). + // If the text annotation has MaxLen, borders appear for each character + if (flags & (1 << 5)) + { + let n = reader.readInt(); + rec["BC"] = []; + for (let i = 0; i < n; ++i) + rec["BC"].push(reader.readDouble2()); + } + // Rotate an annotation relative to the page - R + if (flags & (1 << 6)) + rec["rotate"] = reader.readInt(); + // Annotation background color - BG + if (flags & (1 << 7)) + { + let n = reader.readInt(); + rec["BG"] = []; + for (let i = 0; i < n; ++i) + rec["BG"].push(reader.readDouble2()); + } + // Default value - DV + if (flags & (1 << 8)) + rec["defaultValue"] = reader.readString(); + if (flags & (1 << 17)) + rec["Parent"] = reader.readInt(); + if (flags & (1 << 18)) + rec["name"] = reader.readString(); + if (flags & (1 << 19)) + rec["font"]["AP"] = reader.readString(); + // Action + let nAction = reader.readInt(); + if (nAction > 0) + rec["AA"] = {}; + for (let i = 0; i < nAction; ++i) + { + let AAType = reader.readString(); + rec["AA"][AAType] = {}; + readAction(reader, rec["AA"][AAType]); + } + // Widget types + if (rec["type"] == 27) + { + if (flags & (1 << 9)) + rec["value"] = reader.readString(); + let IFflags = reader.readInt(); + // Header - СA + if (flags & (1 << 10)) + rec["caption"] = reader.readString(); + // Rollover header - RC + if (flags & (1 << 11)) + rec["rolloverCaption"] = reader.readString(); + // Alternate header - AC + if (flags & (1 << 12)) + rec["alternateCaption"] = reader.readString(); + // Header position - TP + if (flags & (1 << 13)) + // 0 - textOnly, 1 - iconOnly, 2 - iconTextV, 3 - textIconV, 4 - iconTextH, 5 - textIconH, 6 - overlay + rec["position"] = reader.readByte(); + // Icons - IF + if (IFflags & (1 << 0)) + { + rec["IF"] = {}; + // Scaling IF.SW + // 0 - Always, 1 - Never, 2 - too big, 3 - too small + if (IFflags & (1 << 1)) + rec["IF"]["SW"] = reader.readByte(); + // Scaling type - IF.S + // 0 - Proportional, 1 - Anamorphic + if (IFflags & (1 << 2)) + rec["IF"]["S"] = reader.readByte(); + if (IFflags & (1 << 3)) + { + rec["IF"]["A"] = []; + rec["IF"]["A"].push(reader.readDouble()); + rec["IF"]["A"].push(reader.readDouble()); + } + rec["IF"]["FB"] = (IFflags >> 4) & 1; + } + } + else if (rec["type"] == 29 || rec["type"] == 28) + { + if (flags & (1 << 9)) + rec["value"] = reader.readString(); + // 0 - check, 1 - cross, 2 - diamond, 3 - circle, 4 - star, 5 - square + rec["style"] = reader.readByte(); + if (flags & (1 << 14)) + rec["ExportValue"] = reader.readString(); + // 12.7.4.2.1 + rec["NoToggleToOff"] = (rec["flag"] >> 14) & 1; // NoToggleToOff + rec["radiosInUnison"] = (rec["flag"] >> 25) & 1; // RadiosInUnison + } + else if (rec["type"] == 30) + { + if (flags & (1 << 9)) + rec["value"] = reader.readString(); + if (flags & (1 << 10)) + rec["maxLen"] = reader.readInt(); + if (rec["flag"] & (1 << 25)) + rec["richValue"] = reader.readString(); + // 12.7.4.3 + rec["multiline"] = (rec["flag"] >> 12) & 1; // Multiline + rec["password"] = (rec["flag"] >> 13) & 1; // Password + rec["fileSelect"] = (rec["flag"] >> 20) & 1; // FileSelect + rec["doNotSpellCheck"] = (rec["flag"] >> 22) & 1; // DoNotSpellCheck + rec["doNotScroll"] = (rec["flag"] >> 23) & 1; // DoNotScroll + rec["comb"] = (rec["flag"] >> 24) & 1; // Comb + rec["richText"] = (rec["flag"] >> 25) & 1; // RichText + } + else if (rec["type"] == 31 || rec["type"] == 32) + { + if (flags & (1 << 9)) + rec["value"] = reader.readString(); + if (flags & (1 << 10)) + { + let n = reader.readInt(); + rec["opt"] = []; + for (let i = 0; i < n; ++i) + { + let opt1 = reader.readString(); + let opt2 = reader.readString(); + if (opt1 == "") + rec["opt"].push(opt2); + else + rec["opt"].push([opt2, opt1]); + } + } + if (flags & (1 << 11)) + rec["TI"] = reader.readInt(); + if (flags & (1 << 12)) + { + let n = reader.readInt(); + rec["curIdxs"] = []; + for (let i = 0; i < n; ++i) + rec["curIdxs"].push(reader.readInt()); + } + if (flags & (1 << 13)) + { + let n = reader.readInt(); + rec["value"] = []; + for (let i = 0; i < n; ++i) + rec["value"].push(reader.readString()); + } + // 12.7.4.4 + rec["editable"] = (rec["flag"] >> 18) & 1; // Edit + rec["multipleSelection"] = (rec["flag"] >> 21) & 1; // MultiSelect + rec["doNotSpellCheck"] = (rec["flag"] >> 22) & 1; // DoNotSpellCheck + rec["commitOnSelChange"] = (rec["flag"] >> 26) & 1; // CommitOnSelChange + } + else if (rec["type"] == 33) + { + rec["Sig"] = (flags >> 9) & 1; + } + + res["Fields"].push(rec); + } + + ptr.free(); + return res; +}; + +// optional nWidget - rec["AP"]["i"] +// optional sView - N/D/R +// optional sButtonView - state pushbutton-annotation - Off/Yes(or rec["ExportValue"]) +CFile.prototype["getInteractiveFormsAP"] = function(pageIndex, width, height, backgroundColor, nWidget, sView, sButtonView) +{ + let nView = -1; + if (sView) + { + if (sView == "N") + nView = 0; + else if (sView == "D") + nView = 1; + else if (sView == "R") + nView = 2; + } + let nButtonView = -1; + if (sButtonView) + nButtonView = (sButtonView == "Off" ? 0 : 1); + + this.lockPageNumForFontsLoader(pageIndex, UpdateFontsSource.Forms); + let ptr = this._getInteractiveFormsAP(width, height, backgroundColor, pageIndex, nWidget, nView, nButtonView); + let reader = ptr.getReader(); + this.unlockPageNumForFontsLoader(); + + if (!reader) + return []; + + let res = []; + + while (reader.isValid()) + { + // Annotation view + let AP = {}; + readAnnotAP(reader, AP); + res.push(AP); + } + + ptr.free(); + return res; +}; +// optional bBase64 - true/false base64 result +// optional nWidget ... +// optional sIconView - icon - I/RI/IX +CFile.prototype["getButtonIcons"] = function(pageIndex, width, height, backgroundColor, bBase64, nWidget, sIconView) +{ + let nView = -1; + if (sIconView) + { + if (sIconView == "I") + nView = 0; + else if (sIconView == "RI") + nView = 1; + else if (sIconView == "IX") + nView = 2; + } + + let ptr = this._getButtonIcons(backgroundColor, pageIndex, bBase64, nWidget, nView); + let reader = ptr.getReader(); + + if (!reader) return {}; + + let res = {}; + + res["MK"] = []; + res["View"] = []; + + while (reader.isValid()) + { + // View pushbutton annotation + let MK = {}; + // Relation with AP + MK["i"] = reader.readInt(); + let n = reader.readInt(); + for (let i = 0; i < n; ++i) + { + let MKType = reader.readString(); + MK[MKType] = reader.readInt(); + let unique = reader.readByte(); + if (unique) + { + let ViewMK = {}; + ViewMK["j"] = MK[MKType]; + ViewMK["w"] = reader.readInt(); + ViewMK["h"] = reader.readInt(); + if (bBase64) + { + // base64 string with image + ViewMK["retValue"] = reader.readString(); + } + else + { + let np1 = reader.readInt(); + let np2 = reader.readInt(); + // this memory needs to be deleted + ViewMK["retValue"] = np2 << 32 | np1; + } + res["View"].push(ViewMK); + } + } + res["MK"].push(MK); + } + + ptr.free(); + return res; +}; +// optional pageIndex - get annotations from specific page +CFile.prototype["getAnnotationsInfo"] = function(pageIndex) +{ + if (!this.nativeFile) + return []; + + let ptr = this._getAnnotationsInfo(pageIndex); + let reader = ptr.getReader(); + + if (!reader) return []; + + let res = []; + while (reader.isValid()) + { + let rec = {}; + // Annotation type + // 0 - Text, 1 - Link, 2 - FreeText, 3 - Line, 4 - Square, 5 - Circle, + // 6 - Polygon, 7 - PolyLine, 8 - Highlight, 9 - Underline, 10 - Squiggly, + // 11 - Strikeout, 12 - Stamp, 13 - Caret, 14 - Ink, 15 - Popup, 16 - FileAttachment, + // 17 - Sound, 18 - Movie, 19 - Widget, 20 - Screen, 21 - PrinterMark, + // 22 - TrapNet, 23 - Watermark, 24 - 3D, 25 - Redact + rec["Type"] = reader.readByte(); + // Annot + readAnnot(reader, rec); + // Markup + let flags = 0; + if ((rec["Type"] < 18 && rec["Type"] != 1 && rec["Type"] != 15) || rec["Type"] == 25) + { + flags = reader.readInt(); + if (flags & (1 << 0)) + rec["Popup"] = reader.readInt(); + // T + if (flags & (1 << 1)) + rec["User"] = reader.readString(); + // CA + if (flags & (1 << 2)) + rec["CA"] = reader.readDouble(); + // RC + if (flags & (1 << 3)) + { + let n = reader.readInt(); + rec["RC"] = []; + for (let i = 0; i < n; ++i) + { + let oFont = {}; + // 0 - left, 1 - centered, 2 - right, 3 - justify + oFont["alignment"] = reader.readByte(); + let nFontFlag = reader.readInt(); + oFont["bold"] = (nFontFlag >> 0) & 1; + oFont["italic"] = (nFontFlag >> 1) & 1; + oFont["strikethrough"] = (nFontFlag >> 3) & 1; + oFont["underlined"] = (nFontFlag >> 4) & 1; + if (nFontFlag & (1 << 5)) + oFont["vertical"] = reader.readDouble(); + if (nFontFlag & (1 << 6)) + oFont["actual"] = reader.readString(); + oFont["size"] = reader.readDouble(); + oFont["color"] = []; + oFont["color"].push(reader.readDouble2()); + oFont["color"].push(reader.readDouble2()); + oFont["color"].push(reader.readDouble2()); + oFont["name"] = reader.readString(); + oFont["text"] = reader.readString(); + rec["RC"].push(oFont); + } + } + // CreationDate + if (flags & (1 << 4)) + rec["CreationDate"] = reader.readString(); + // IRT + if (flags & (1 << 5)) + rec["RefTo"] = reader.readInt(); + // RT + // 0 - R, 1 - Group + if (flags & (1 << 6)) + rec["RefToReason"] = reader.readByte(); + // Subj + if (flags & (1 << 7)) + rec["Subj"] = reader.readString(); + } + // Text + if (rec["Type"] == 0) + { + // Bachground color - C->IC + if (rec["C"]) + { + rec["IC"] = rec["C"]; + delete rec["C"]; + } + rec["Open"] = (flags >> 15) & 1; + // icon - Name + // 0 - Check, 1 - Checkmark, 2 - Circle, 3 - Comment, 4 - Cross, 5 - CrossHairs, 6 - Help, 7 - Insert, 8 - Key, 9 - NewParagraph, 10 - Note, 11 - Paragraph, 12 - RightArrow, 13 - RightPointer, 14 - Star, 15 - UpArrow, 16 - UpLeftArrow + if (flags & (1 << 16)) + rec["Icon"] = reader.readByte(); + // StateModel + // 0 - Marked, 1 - Review + if (flags & (1 << 17)) + rec["StateModel"] = reader.readByte(); + // State + // 0 - Marked, 1 - Unmarked, 2 - Accepted, 3 - Rejected, 4 - Cancelled, 5 - Completed, 6 - None + if (flags & (1 << 18)) + rec["State"] = reader.readByte(); + + } + // Line + else if (rec["Type"] == 3) + { + // L + rec["L"] = []; + for (let i = 0; i < 4; ++i) + rec["L"].push(reader.readDouble()); + // LE + // 0 - Square, 1 - Circle, 2 - Diamond, 3 - OpenArrow, 4 - ClosedArrow, 5 - None, 6 - Butt, 7 - ROpenArrow, 8 - RClosedArrow, 9 - Slash + if (flags & (1 << 15)) + { + rec["LE"] = []; + rec["LE"].push(reader.readByte()); + rec["LE"].push(reader.readByte()); + } + // IC + if (flags & (1 << 16)) + { + let n = reader.readInt(); + rec["IC"] = []; + for (let i = 0; i < n; ++i) + rec["IC"].push(reader.readDouble2()); + } + // LL + if (flags & (1 << 17)) + rec["LL"] = reader.readDouble(); + // LLE + if (flags & (1 << 18)) + rec["LLE"] = reader.readDouble(); + // Cap + rec["Cap"] = (flags >> 19) & 1; + // IT + // 0 - LineDimension, 1 - LineArrow + if (flags & (1 << 20)) + rec["IT"] = reader.readByte(); + // LLO + if (flags & (1 << 21)) + rec["LLO"] = reader.readDouble(); + // CP + // 0 - Inline, 1 - Top + if (flags & (1 << 22)) + rec["CP"] = reader.readByte(); + // CO + if (flags & (1 << 23)) + { + rec["CO"] = []; + rec["CO"].push(reader.readDouble()); + rec["CO"].push(reader.readDouble()); + } + } + // Ink + else if (rec["Type"] == 14) + { + // offsets like getStructure and viewer.navigate + let n = reader.readInt(); + rec["InkList"] = []; + for (let i = 0; i < n; ++i) + { + rec["InkList"][i] = []; + let m = reader.readInt(); + for (let j = 0; j < m; ++j) + rec["InkList"][i].push(reader.readDouble()); + } + } + // Highlight, Underline, Squiggly, Strikeout + else if (rec["Type"] > 7 && rec["Type"] < 12) + { + // QuadPoints + let n = reader.readInt(); + rec["QuadPoints"] = []; + for (let i = 0; i < n; ++i) + rec["QuadPoints"].push(reader.readDouble()); + } + // Square, Circle + else if (rec["Type"] == 4 || rec["Type"] == 5) + { + // Rect and RD differences + if (flags & (1 << 15)) + { + rec["RD"] = []; + for (let i = 0; i < 4; ++i) + rec["RD"].push(reader.readDouble()); + } + // IC + if (flags & (1 << 16)) + { + let n = reader.readInt(); + rec["IC"] = []; + for (let i = 0; i < n; ++i) + rec["IC"].push(reader.readDouble2()); + } + } + // Polygon, PolyLine + else if (rec["Type"] == 6 || rec["Type"] == 7) + { + let nVertices = reader.readInt(); + rec["Vertices"] = []; + for (let i = 0; i < nVertices; ++i) + rec["Vertices"].push(reader.readDouble()); + // LE + // 0 - Square, 1 - Circle, 2 - Diamond, 3 - OpenArrow, 4 - ClosedArrow, 5 - None, 6 - Butt, 7 - ROpenArrow, 8 - RClosedArrow, 9 - Slash + if (flags & (1 << 15)) + { + rec["LE"] = []; + rec["LE"].push(reader.readByte()); + rec["LE"].push(reader.readByte()); + } + // IC + if (flags & (1 << 16)) + { + let n = reader.readInt(); + rec["IC"] = []; + for (let i = 0; i < n; ++i) + rec["IC"].push(reader.readDouble2()); + } + // IT + // 0 - PolygonCloud, 1 - PolyLineDimension, 2 - PolygonDimension + if (flags & (1 << 20)) + rec["IT"] = reader.readByte(); + } + // Popup + /* + else if (rec["Type"] == 15) + { + flags = reader.readInt(); + rec["Open"] = (flags >> 0) & 1; + // Link to parent-annotation + if (flags & (1 << 1)) + rec["PopupParent"] = reader.readInt(); + } + */ + // FreeText + else if (rec["Type"] == 2) + { + // Background color - C->IC + if (rec["C"]) + { + rec["IC"] = rec["C"]; + delete rec["C"]; + } + // 0 - left-justified, 1 - centered, 2 - right-justified + rec["alignment"] = reader.readByte(); + rec["Rotate"] = reader.readInt(); + // Rect and RD differences + if (flags & (1 << 15)) + { + rec["RD"] = []; + for (let i = 0; i < 4; ++i) + rec["RD"].push(reader.readDouble()); + } + // CL + if (flags & (1 << 16)) + { + let n = reader.readInt(); + rec["CL"] = []; + for (let i = 0; i < n; ++i) + rec["CL"].push(reader.readDouble()); + } + // Default style (CSS2 format) - DS + if (flags & (1 << 17)) + rec["defaultStyle"] = reader.readString(); + // LE + // 0 - Square, 1 - Circle, 2 - Diamond, 3 - OpenArrow, 4 - ClosedArrow, 5 - None, 6 - Butt, 7 - ROpenArrow, 8 - RClosedArrow, 9 - Slash + if (flags & (1 << 18)) + rec["LE"] = reader.readByte(); + // IT + // 0 - FreeText, 1 - FreeTextCallout, 2 - FreeTextTypeWriter + if (flags & (1 << 20)) + rec["IT"] = reader.readByte(); + // Border color - from DA (write to C) + if (flags & (1 << 21)) + { + let n = reader.readInt(); + rec["C"] = []; + for (let i = 0; i < n; ++i) + rec["C"].push(reader.readDouble2()); + } + } + // Caret + else if (rec["Type"] == 13) + { + // Rect and RD differenses + if (flags & (1 << 15)) + { + rec["RD"] = []; + for (let i = 0; i < 4; ++i) + rec["RD"].push(reader.readDouble()); + } + // Sy + // 0 - None, 1 - P, 2 - S + if (flags & (1 << 16)) + rec["Sy"] = reader.readByte(); + } + // FileAttachment + else if (rec["Type"] == 16) + { + if (flags & (1 << 15)) + rec["Icon"] = reader.readString(); + if (flags & (1 << 16)) + rec["FS"] = reader.readString(); + if (flags & (1 << 17)) + { + rec["F"] = {}; + rec["F"]["FileName"] = reader.readString(); + } + if (flags & (1 << 18)) + { + rec["UF"] = {}; + rec["UF"]["FileName"] = reader.readString(); + } + if (flags & (1 << 19)) + { + rec["DOS"] = {}; + rec["DOS"]["FileName"] = reader.readString(); + } + if (flags & (1 << 20)) + { + rec["Mac"] = {}; + rec["Mac"]["FileName"] = reader.readString(); + } + if (flags & (1 << 21)) + { + rec["Unix"] = {}; + rec["Unix"]["FileName"] = reader.readString(); + } + if (flags & (1 << 22)) + { + rec["ID"] = []; + rec["ID"].push(reader.readString()); + rec["ID"].push(reader.readString()); + } + rec["V"] = flags & (1 << 23); + if (flags & (1 << 24)) + { + let flag = reader.readInt(); + if (flag & (1 << 0)) + { + let n = reader.readInt(); + let np1 = reader.readInt(); + let np2 = reader.readInt(); + let pPoint = np2 << 32 | np1; + rec["F"]["File"] = new Uint8Array(Module["HEAP8"].buffer, pPoint, n); + Module["_free"](pPoint); + } + if (flag & (1 << 1)) + { + let n = reader.readInt(); + let np1 = reader.readInt(); + let np2 = reader.readInt(); + let pPoint = np2 << 32 | np1; + rec["UF"]["File"] = new Uint8Array(Module["HEAP8"].buffer, pPoint, n); + Module["_free"](pPoint); + } + if (flag & (1 << 2)) + { + let n = reader.readInt(); + let np1 = reader.readInt(); + let np2 = reader.readInt(); + let pPoint = np2 << 32 | np1; + rec["DOS"]["File"] = new Uint8Array(Module["HEAP8"].buffer, pPoint, n); + Module["_free"](pPoint); + } + if (flag & (1 << 3)) + { + let n = reader.readInt(); + let np1 = reader.readInt(); + let np2 = reader.readInt(); + let pPoint = np2 << 32 | np1; + rec["Mac"]["File"] = new Uint8Array(Module["HEAP8"].buffer, pPoint, n); + Module["_free"](pPoint); + } + if (flag & (1 << 4)) + { + let n = reader.readInt(); + let np1 = reader.readInt(); + let np2 = reader.readInt(); + let pPoint = np2 << 32 | np1; + rec["Unix"]["File"] = new Uint8Array(Module["HEAP8"].buffer, pPoint, n); + Module["_free"](pPoint); + } + } + if (flags & (1 << 26)) + rec["Desc"] = reader.readString(); + } + // Stamp + else if (rec["Type"] == 12) + { + rec["Icon"] = reader.readString(); + rec["Rotate"] = reader.readDouble2(); + rec["InRect"] = []; + for (let i = 0; i < 8; ++i) + rec["InRect"].push(reader.readDouble2()); + } + res.push(rec); + } + + ptr.free(); + return res; +}; +// optional nAnnot ... +// optional sView ... +CFile.prototype["getAnnotationsAP"] = function(pageIndex, width, height, backgroundColor, nAnnot, sView) +{ + let nView = -1; + if (sView) + { + if (sView == "N") + nView = 0; + else if (sView == "D") + nView = 1; + else if (sView == "R") + nView = 2; + } + + this.lockPageNumForFontsLoader(pageIndex, UpdateFontsSource.Annotation); + let ptr = this._getAnnotationsAP(width, height, backgroundColor, pageIndex, nAnnot, nView); + let reader = ptr.getReader(); + this.unlockPageNumForFontsLoader(); + + if (!reader) + return []; + + let res = []; + while (reader.isValid()) + { + // Annotation view + let AP = {}; + readAnnotAP(reader, AP); + res.push(AP); + } + + ptr.free(); + return res; +}; + +// SCAN PAGES +CFile.prototype["scanPage"] = function(page, mode) +{ + let ptr = this._scanPage(page, mode); + let reader = ptr.getReader(); + + if (!reader) return []; + + let shapesCount = reader.readInt(); + let shapes = new Array(shapesCount); + + for (let i = 0; i < shapesCount; i++) + shapes[i] = reader.readString(); + + ptr.free(); + return shapes; +}; + +CFile.prototype["getImageBase64"] = function(rId) +{ + let strId = "" + rId; + if (this.scannedImages[strId]) + return this.scannedImages[strId]; + + this.scannedImages[strId] = this._getImageBase64(rId); + return this.scannedImages[strId]; +}; + +CFile.prototype["changeImageUrl"] = function(baseUrl, resultUrl) +{ + for (let i in this.scannedImages) + { + if (this.scannedImages[i] == baseUrl) + this.scannedImages[i] = resultUrl; + } +}; + +// MEMORY +CFile.prototype["getUint8Array"] = function(ptr, len) +{ + return this._getUint8Array(ptr, len); +}; +CFile.prototype["getUint8ClampedArray"] = function(ptr, len) +{ + return this._getUint8ClampedArray(ptr, len); +}; +CFile.prototype["free"] = function(pointer) +{ + this._free(pointer); +}; + +// PIXMAP +CFile.prototype["getPagePixmap"] = function(pageIndex, width, height, backgroundColor) +{ + let page = this.pages[pageIndex]; + if (page.originIndex == undefined) + return null; + if (page.fonts.length > 0) + { + // waiting fonts + return null; + } + + this.lockPageNumForFontsLoader(pageIndex, UpdateFontsSource.Page); + let ptr = this._getPixmap(page.originIndex, width, height, backgroundColor); + this.unlockPageNumForFontsLoader(); + + if (page.fonts.length > 0) + { + // waiting fonts + this._free(ptr); + ptr = null; + } + return ptr; +}; + +// CLOUD FONTS +function addToArrayAsDictionary(arr, value) +{ + let isFound = false; + for (let i = 0, len = arr.length; i < len; i++) + { + if (arr[i] == value) + { + isFound = true; + break; + } + } + if (!isFound) + arr.push(value); + return isFound; +} + +function fontToMemory(file, isCheck) +{ + let idBuffer = file.GetID().toUtf8(); + let idPointer = Module["_malloc"](idBuffer.length); + Module["HEAP8"].set(idBuffer, idPointer); + + if (isCheck) + { + let nExist = Module["_IsFontBinaryExist"](idPointer); + if (nExist != 0) + { + Module["_free"](idPointer); + return; + } + } + + let stream_index = file.GetStreamIndex(); + + let stream = AscFonts.getFontStream(stream_index); + let streamPointer = Module["_malloc"](stream.size); + Module["HEAP8"].set(stream.data, streamPointer); + + Module["_SetFontBinary"](idPointer, streamPointer, stream.size); + + Module["_free"](streamPointer); + Module["_free"](idPointer); +} + +// FONTS +CFile.prototype["addPage"] = function(pageIndex, pageObj) +{ + this.pages.splice(pageIndex, 0, pageObj); + if (this.fontStreams) + { + for (let i in this.fontStreams) + { + let pages = this.fontStreams[i].pages; + for (let j = 0; j < pages.length; j++) + { + if (pages[j] >= pageIndex) + pages[j] += 1; + } + } + } +}; +CFile.prototype["removePage"] = function(pageIndex) +{ + let result = this.pages.splice(pageIndex, 1); + if (this.fontStreams) + { + for (let i in this.fontStreams) + { + let pages = this.fontStreams[i].pages; + for (let j = 0; j < pages.length; j++) + { + if (pages[j] > pageIndex) + pages[j] -= 1; + else if (pages[j] == pageIndex) + pages.splice(j, 1); + } + } + } + return result; +}; + +// ONLY WEB +self["AscViewer"]["Free"] = function(pointer) +{ + CFile.prototype._free(pointer); +}; +self["AscViewer"]["InitializeFonts"] = function(basePath) +{ + return CFile.prototype._InitializeFonts(basePath); +}; + +self["AscViewer"]["CheckStreamId"] = function(data, status) +{ + return CFile.prototype._CheckStreamId(data, status); +}; + +// export +self["AscViewer"]["CDrawingFile"] = CFile; + +self.drawingFile = null; \ No newline at end of file diff --git a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_base.js b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_base.js index 4805bb11a12..38c638c5a31 100644 --- a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_base.js +++ b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_base.js @@ -51,1455 +51,7 @@ //module - self.drawingFileCurrentPageIndex = -1; - self.fontStreams = {}; - self.drawingFile = null; + //stream - function CBinaryReader(data, start, size) - { - this.data = data; - this.pos = start; - this.limit = start + size; - } - CBinaryReader.prototype.readByte = function() - { - let val = this.data[this.pos]; - this.pos += 1; - return val; - }; - CBinaryReader.prototype.readInt = function() - { - let val = this.data[this.pos] | this.data[this.pos + 1] << 8 | this.data[this.pos + 2] << 16 | this.data[this.pos + 3] << 24; - this.pos += 4; - return val; - }; - CBinaryReader.prototype.readDouble = function() - { - return this.readInt() / 100; - }; - CBinaryReader.prototype.readDouble2 = function() - { - return this.readInt() / 10000; - }; - CBinaryReader.prototype.readString = function() - { - let len = this.readInt(); - let val = String.prototype.fromUtf8(this.data, this.pos, len); - this.pos += len; - return val; - }; - CBinaryReader.prototype.readData = function() - { - let len = this.readInt(); - let val = this.data.slice(this.pos, this.pos + len); - this.pos += len; - return val; - }; - CBinaryReader.prototype.isValid = function() - { - return (this.pos < this.limit) ? true : false; - }; - CBinaryReader.prototype.Skip = function(nPos) - { - this.pos += nPos; - }; - - function CBinaryWriter() - { - this.size = 100000; - this.dataSize = 0; - this.buffer = new Uint8Array(this.size); - } - CBinaryWriter.prototype.checkAlloc = function(addition) - { - if ((this.dataSize + addition) <= this.size) - return; - - let newSize = Math.max(this.size * 2, this.size + addition); - let newBuffer = new Uint8Array(newSize); - newBuffer.set(this.buffer, 0); - - this.size = newSize; - this.buffer = newBuffer; - }; - CBinaryWriter.prototype.writeUint = function(value) - { - this.checkAlloc(4); - let val = (value>2147483647)?value-4294967296:value; - this.buffer[this.dataSize++] = (val) & 0xFF; - this.buffer[this.dataSize++] = (val >>> 8) & 0xFF; - this.buffer[this.dataSize++] = (val >>> 16) & 0xFF; - this.buffer[this.dataSize++] = (val >>> 24) & 0xFF; - }; - CBinaryWriter.prototype.writeString = function(value) - { - let valueUtf8 = value.toUtf8(); - this.checkAlloc(valueUtf8.length); - this.buffer.set(valueUtf8, this.dataSize); - this.dataSize += valueUtf8.length; - }; - - function CFile() - { - this.nativeFile = 0; - this.stream = -1; - this.stream_size = 0; - this.type = -1; - this.pages = []; - this.info = null; - this._isNeedPassword = false; - } - - CFile.prototype["loadFromData"] = function(arrayBuffer) - { - let data = new Uint8Array(arrayBuffer); - let _stream = Module["_malloc"](data.length); - Module["HEAP8"].set(data, _stream); - this.nativeFile = Module["_Open"](_stream, data.length, 0); - let error = Module["_GetErrorCode"](this.nativeFile); - this.stream = _stream; - this.stream_size = data.length; - this.type = Module["_GetType"](_stream, data.length); - self.drawingFile = this; - if (!error) - this.getInfo(); - this._isNeedPassword = (4 === error) ? true : false; - - // 0 - ok - // 4 - password - // else - error - return error; - }; - CFile.prototype["loadFromDataWithPassword"] = function(password) - { - if (0 != this.nativeFile) - Module["_Close"](this.nativeFile); - - let passBuffer = password.toUtf8(); - let passPointer = Module["_malloc"](passBuffer.length); - Module["HEAP8"].set(passBuffer, passPointer); - this.nativeFile = Module["_Open"](this.stream, this.stream_size, passPointer); - Module["_free"](passPointer); - let error = Module["_GetErrorCode"](this.nativeFile); - this.type = Module["_GetType"](this.stream, this.stream_size); - self.drawingFile = this; - if (!error) - this.getInfo(); - this._isNeedPassword = (4 === error) ? true : false; - - // 0 - ok - // 4 - password - // else - error - return error; - }; - CFile.prototype["getFileAsBase64"] = function() - { - if (0 >= this.stream) - return ""; - - return new Uint8Array(Module["HEAP8"].buffer, this.stream, this.stream_size); - }; - CFile.prototype["isNeedPassword"] = function() - { - return this._isNeedPassword; - }; - CFile.prototype["isNeedCMap"] = function() - { - if (!this.nativeFile) - return false; - - let isNeed = Module["_IsNeedCMap"](this.nativeFile); - return (isNeed === 1) ? true : false; - }; - CFile.prototype["setCMap"] = function(memoryBuffer) - { - if (!this.nativeFile) - return; - - let pointer = Module["_malloc"](memoryBuffer.length); - Module.HEAP8.set(memoryBuffer, pointer); - Module["_SetCMapData"](this.nativeFile, pointer, memoryBuffer.length); - }; - CFile.prototype["getInfo"] = function() - { - if (!this.nativeFile) - return false; - - let _info = Module["_GetInfo"](this.nativeFile); - if (_info == 0) - return false; - - let lenArray = new Int32Array(Module["HEAP8"].buffer, _info, 4); - if (lenArray == null) - return false; - - let len = lenArray[0]; - len -= 4; - if (len <= 0) - return false; - - let buffer = new Uint8Array(Module["HEAP8"].buffer, _info + 4, len); - let reader = new CBinaryReader(buffer, 0, len); - - this.StartID = reader.readInt(); - - let _pages = reader.readInt(); - for (let i = 0; i < _pages; i++) - { - let rec = {}; - rec["W"] = reader.readInt(); - rec["H"] = reader.readInt(); - rec["Dpi"] = reader.readInt(); - rec["Rotate"] = reader.readInt(); - rec.fonts = []; - rec.text = null; - this.pages.push(rec); - } - let json_info = reader.readString(); - try - { - this.info = JSON.parse(json_info); - } catch(err) {} - - Module["_free"](_info); - return this.pages.length > 0; - }; - CFile.prototype["close"] = function() - { - Module["_Close"](this.nativeFile); - this.nativeFile = 0; - this.pages = []; - this.info = null; - this.StartID = null; - if (this.stream > 0) - Module["_free"](this.stream); - this.stream = -1; - self.drawingFile = null; - }; - - CFile.prototype["getPages"] = function() - { - return this.pages; - }; - - CFile.prototype["openForms"] = function() - { - - }; - - CFile.prototype["getDocumentInfo"] = function() - { - return this.info; - }; - - CFile.prototype["getStartID"] = function() - { - return this.StartID; - }; - - CFile.prototype["getPagePixmap"] = function(pageIndex, width, height, backgroundColor) - { - if (this.pages[pageIndex].fonts.length > 0) - { - // waiting fonts - return null; - } - - self.drawingFileCurrentPageIndex = pageIndex; - let retValue = Module["_GetPixmap"](this.nativeFile, pageIndex, width, height, backgroundColor === undefined ? 0xFFFFFF : backgroundColor); - self.drawingFileCurrentPageIndex = -1; - - if (this.pages[pageIndex].fonts.length > 0) - { - // waiting fonts - Module["_free"](retValue); - retValue = null; - } - return retValue; - }; - CFile.prototype["getGlyphs"] = function(pageIndex) - { - if (this.pages[pageIndex].fonts.length > 0) - { - // waiting fonts - return null; - } - - self.drawingFileCurrentPageIndex = pageIndex; - let retValue = Module["_GetGlyphs"](this.nativeFile, pageIndex); - // there is no need to delete the result; this buffer is used as a text buffer - // for text commands on other pages. After receiving ALL text pages, - // you need to call destroyTextInfo() - self.drawingFileCurrentPageIndex = -1; - - if (this.pages[pageIndex].fonts.length > 0) - { - // waiting fonts - retValue = null; - } - - if (null == retValue) - return null; - - let lenArray = new Int32Array(Module["HEAP8"].buffer, retValue, 5); - let len = lenArray[0]; - len -= 20; - - if (self.drawingFile.onUpdateStatistics) - self.drawingFile.onUpdateStatistics(lenArray[1], lenArray[2], lenArray[3], lenArray[4]); - - if (len <= 0) - { - return []; - } - - let textCommandsSrc = new Uint8Array(Module["HEAP8"].buffer, retValue + 20, len); - let textCommands = new Uint8Array(len); - textCommands.set(textCommandsSrc); - - textCommandsSrc = null; - return textCommands; - }; - CFile.prototype["destroyTextInfo"] = function() - { - Module["_DestroyTextInfo"](); - }; - CFile.prototype["getLinks"] = function(pageIndex) - { - let res = []; - let ext = Module["_GetLinks"](this.nativeFile, pageIndex); - if (ext == 0) - return res; - - let lenArray = new Int32Array(Module["HEAP8"].buffer, ext, 4); - if (lenArray == null) - return res; - - let len = lenArray[0]; - len -= 4; - if (len <= 0) - return res; - - let buffer = new Uint8Array(Module["HEAP8"].buffer, ext + 4, len); - let reader = new CBinaryReader(buffer, 0, len); - - while (reader.isValid()) - { - let rec = {}; - rec["link"] = reader.readString(); - rec["dest"] = reader.readDouble(); - rec["x"] = reader.readDouble(); - rec["y"] = reader.readDouble(); - rec["w"] = reader.readDouble(); - rec["h"] = reader.readDouble(); - res.push(rec); - } - - Module["_free"](ext); - return res; - }; - - function readAction(reader, rec) - { - let SType = reader.readByte(); - // 0 - Unknown, 1 - GoTo, 2 - GoToR, 3 - GoToE, 4 - Launch - // 5 - Thread, 6 - URI, 7 - Sound, 8 - Movie, 9 - Hide - // 10 - Named, 11 - SubmitForm, 12 - ResetForm, 13 - ImportData - // 14 - JavaScript, 15 - SetOCGState, 16 - Rendition - // 17 - Trans, 18 - GoTo3DView - rec["S"] = SType; - if (SType == 14) - { - rec["JS"] = reader.readString(); - } - else if (SType == 1) - { - rec["page"] = reader.readInt(); - rec["kind"] = reader.readByte(); - // 0 - XYZ - // 1 - Fit - // 2 - FitH - // 3 - FitV - // 4 - FitR - // 5 - FitB - // 6 - FitBH - // 7 - FitBV - switch (rec["kind"]) - { - case 0: - case 2: - case 3: - case 6: - case 7: - { - let nFlag = reader.readByte(); - if (nFlag & (1 << 0)) - rec["left"] = reader.readDouble(); - if (nFlag & (1 << 1)) - rec["top"] = reader.readDouble(); - if (nFlag & (1 << 2)) - rec["zoom"] = reader.readDouble(); - break; - } - case 4: - { - rec["left"] = reader.readDouble(); - rec["bottom"] = reader.readDouble(); - rec["right"] = reader.readDouble(); - rec["top"] = reader.readDouble(); - break; - } - case 1: - case 5: - default: - break; - } - } - else if (SType == 10) - { - rec["N"] = reader.readString(); - } - else if (SType == 6) - { - rec["URI"] = reader.readString(); - } - else if (SType == 9) - { - rec["H"] = reader.readInt(); - let m = reader.readInt(); - rec["T"] = []; - // array of annotation names - rec["name"] - for (let j = 0; j < m; ++j) - rec["T"].push(reader.readString()); - } - else if (SType == 12) - { - rec["Flags"] = reader.readInt(); - let m = reader.readInt(); - rec["Fields"] = []; - // array of annotation names - rec["name"] - for (let j = 0; j < m; ++j) - rec["Fields"].push(reader.readString()); - } - let NextAction = reader.readByte(); - if (NextAction) - { - rec["Next"] = {}; - readAction(reader, rec["Next"]); - } - } - function readAnnot(reader, rec) - { - rec["AP"] = {}; - // Annot - // number for relations with AP - rec["AP"]["i"] = reader.readInt(); - rec["annotflag"] = reader.readInt(); - // 12.5.3 - let bHidden = (rec["annotflag"] >> 1) & 1; // Hidden - let bPrint = (rec["annotflag"] >> 2) & 1; // Print - rec["noZoom"] = (rec["annotflag"] >> 3) & 1; // NoZoom - rec["noRotate"] = (rec["annotflag"] >> 4) & 1; // NoRotate - let bNoView = (rec["annotflag"] >> 5) & 1; // NoView - rec["locked"] = (rec["annotflag"] >> 7) & 1; // Locked - rec["ToggleNoView"] = (rec["annotflag"] >> 8) & 1; // ToggleNoView - rec["lockedC"] = (rec["annotflag"] >> 9) & 1; // LockedContents - // 0 - visible, 1 - hidden, 2 - noPrint, 3 - noView - rec["display"] = 0; - if (bHidden) - rec["display"] = 1; - else - { - if (bPrint) - { - if (bNoView) - rec["display"] = 3; - else - rec["display"] = 0; - } - else - { - if (bNoView) - rec["display"] = 0; // ??? no hidden, but noView and no print - else - rec["display"] = 2; - } - } - rec["page"] = reader.readInt(); - // offsets like getStructure and viewer.navigate - rec["rect"] = {}; - rec["rect"]["x1"] = reader.readDouble2(); - rec["rect"]["y1"] = reader.readDouble2(); - rec["rect"]["x2"] = reader.readDouble2(); - rec["rect"]["y2"] = reader.readDouble2(); - let flags = reader.readInt(); - // Unique name - NM - if (flags & (1 << 0)) - rec["UniqueName"] = reader.readString(); - // Alternate annotation text - Contents - if (flags & (1 << 1)) - rec["Contents"] = reader.readString(); - // Border effect - BE - if (flags & (1 << 2)) - { - rec["BE"] = {}; - rec["BE"]["S"] = reader.readByte(); - rec["BE"]["I"] = reader.readDouble(); - } - // Special annotation color - С - if (flags & (1 << 3)) - { - let n = reader.readInt(); - rec["C"] = []; - for (let i = 0; i < n; ++i) - rec["C"].push(reader.readDouble()); - } - // Border/BS - if (flags & (1 << 4)) - { - // 0 - solid, 1 - beveled, 2 - dashed, 3 - inset, 4 - underline - rec["border"] = reader.readByte(); - rec["borderWidth"] = reader.readDouble(); - // Border Dash Pattern - if (rec["border"] == 2) - { - rec["dashed"] = []; - rec["dashed"].push(reader.readDouble()); - rec["dashed"].push(reader.readDouble()); - } - } - // Date of last change - M - if (flags & (1 << 5)) - rec["LastModified"] = reader.readString(); - rec["AP"]["have"] = (flags >> 6) & 1; - } - function readAnnotAP(reader, AP) - { - // number for relations with AP - AP["i"] = reader.readInt(); - AP["x"] = reader.readInt(); - AP["y"] = reader.readInt(); - AP["w"] = reader.readInt(); - AP["h"] = reader.readInt(); - let n = reader.readInt(); - for (let i = 0; i < n; ++i) - { - let APType = reader.readString(); - if (!AP[APType]) - AP[APType] = {}; - let APi = AP[APType]; - let ASType = reader.readString(); - if (ASType) - { - AP[APType][ASType] = {}; - APi = AP[APType][ASType]; - } - let np1 = reader.readInt(); - let np2 = reader.readInt(); - // this memory needs to be deleted - APi["retValue"] = np2 << 32 | np1; - let k = reader.readInt(); - if (k != 0) - APi["fontInfo"] = []; - for (let j = 0; j < k; ++j) - { - let fontInfo = {}; - fontInfo["text"] = reader.readString(); - fontInfo["fontName"] = reader.readString(); - fontInfo["fontSize"] = reader.readDouble(); - APi["fontInfo"].push(fontInfo); - } - } - } - - CFile.prototype["getInteractiveFormsInfo"] = function() - { - let res = {}; - let ext = Module["_GetInteractiveFormsInfo"](this.nativeFile); - if (ext == 0) - return res; - - let lenArray = new Int32Array(Module["HEAP8"].buffer, ext, 4); - if (lenArray == null) - { - Module["_free"](ext); - return res; - } - - let len = lenArray[0]; - len -= 4; - if (len <= 0) - { - Module["_free"](ext); - return res; - } - - let buffer = new Uint8Array(Module["HEAP8"].buffer, ext + 4, len); - let reader = new CBinaryReader(buffer, 0, len); - - if (!reader.isValid()) - { - Module["_free"](ext); - return res; - } - - let k = reader.readInt(); - if (k > 0) - res["CO"] = []; - for (let i = 0; i < k; ++i) - // array of annotation names - rec["name"] - res["CO"].push(reader.readString()); - - k = reader.readInt(); - if (k > 0) - res["Parents"] = []; - for (let i = 0; i < k; ++i) - { - let rec = {}; - rec["i"] = reader.readInt(); - let flags = reader.readInt(); - if (flags & (1 << 0)) - rec["name"] = reader.readString(); - if (flags & (1 << 1)) - rec["value"] = reader.readString(); - if (flags & (1 << 2)) - rec["defaultValue"] = reader.readString(); - if (flags & (1 << 3)) - rec["Parent"] = reader.readInt(); - res["Parents"].push(rec); - } - - res["Fields"] = []; - k = reader.readInt(); - for (let q = 0; reader.isValid() && q < k; ++q) - { - let rec = {}; - // Widget type - FT - // 26 - Unknown, 27 - button, 28 - radiobutton, 29 - checkbox, 30 - text, 31 - combobox, 32 - listbox, 33 - signature - rec["type"] = reader.readByte(); - // Annot - readAnnot(reader, rec); - // Widget - let tc = reader.readInt(); - if (tc) - { - rec["textColor"] = []; - for (let i = 0; i < tc; ++i) - rec["textColor"].push(reader.readDouble()); - } - // 0 - left-justified, 1 - centered, 2 - right-justified - rec["alignment"] = reader.readByte(); - rec["flag"] = reader.readInt(); - // 12.7.3.1 - rec["readOnly"] = (rec["flag"] >> 0) & 1; // ReadOnly - rec["required"] = (rec["flag"] >> 1) & 1; // Required - rec["noexport"] = (rec["flag"] >> 2) & 1; // NoExport - let flags = reader.readInt(); - // Alternative field name, used in tooltip and error messages - TU - if (flags & (1 << 0)) - rec["userName"] = reader.readString(); - // Default style string (CSS2 format) - DS - if (flags & (1 << 1)) - rec["defaultStyle"] = reader.readString(); - // Selection mode - H - // 0 - none, 1 - invert, 2 - push, 3 - outline - if (flags & (1 << 3)) - rec["highlight"] = reader.readByte(); - // Border color - BC. Even if the border is not specified by BS/Border, - // then if BC is present, a default border is provided (solid, thickness 1). - // If the text annotation has MaxLen, borders appear for each character - if (flags & (1 << 5)) - { - let n = reader.readInt(); - rec["BC"] = []; - for (let i = 0; i < n; ++i) - rec["BC"].push(reader.readDouble()); - } - // Rotate an annotation relative to the page - R - if (flags & (1 << 6)) - rec["rotate"] = reader.readInt(); - // Annotation background color - BG - if (flags & (1 << 7)) - { - let n = reader.readInt(); - rec["BG"] = []; - for (let i = 0; i < n; ++i) - rec["BG"].push(reader.readDouble()); - } - // Default value - DV - if (flags & (1 << 8)) - rec["defaultValue"] = reader.readString(); - if (flags & (1 << 17)) - rec["Parent"] = reader.readInt(); - if (flags & (1 << 18)) - rec["name"] = reader.readString(); - // Action - let nAction = reader.readInt(); - if (nAction > 0) - rec["AA"] = {}; - for (let i = 0; i < nAction; ++i) - { - let AAType = reader.readString(); - rec["AA"][AAType] = {}; - readAction(reader, rec["AA"][AAType]); - } - // Widget types - if (rec["type"] == 29 || rec["type"] == 28 || rec["type"] == 27) - { - rec["value"] = (flags & (1 << 9)) ? "Yes" : "Off"; - let IFflags = reader.readInt(); - // MK - if (rec["type"] == 27) - { - // Header - СA - if (flags & (1 << 10)) - rec["caption"] = reader.readString(); - // Rollover header - RC - if (flags & (1 << 11)) - rec["rolloverCaption"] = reader.readString(); - // Alternate header - AC - if (flags & (1 << 12)) - rec["alternateCaption"] = reader.readString(); - } - else - // 0 - check, 1 - cross, 2 - diamond, 3 - circle, 4 - star, 5 - square - rec["style"] = reader.readByte(); - // Header position - TP - if (flags & (1 << 13)) - // 0 - textOnly, 1 - iconOnly, 2 - iconTextV, 3 - textIconV, 4 - iconTextH, 5 - textIconH, 6 - overlay - rec["position"] = reader.readByte(); - // Icons - IF - if (IFflags & (1 << 0)) - { - rec["IF"] = {}; - // Scaling IF.SW - // 0 - Always, 1 - Never, 2 - too big, 3 - too small - if (IFflags & (1 << 1)) - rec["IF"]["SW"] = reader.readByte(); - // Scaling type - IF.S - // 0 - Proportional, 1 - Anamorphic - if (IFflags & (1 << 2)) - rec["IF"]["S"] = reader.readByte(); - if (IFflags & (1 << 3)) - { - rec["IF"]["A"] = []; - rec["IF"]["A"].push(reader.readDouble()); - rec["IF"]["A"].push(reader.readDouble()); - } - rec["IF"]["FB"] = (IFflags >> 4) & 1; - } - if (flags & (1 << 14)) - { - rec["NameOfYes"] = reader.readString(); - if (flags & (1 << 9)) - rec["value"] = rec["NameOfYes"]; - } - // 12.7.4.2.1 - rec["NoToggleToOff"] = (rec["flag"] >> 14) & 1; // NoToggleToOff - rec["radiosInUnison"] = (rec["flag"] >> 25) & 1; // RadiosInUnison - } - else if (rec["type"] == 30) - { - if (flags & (1 << 9)) - rec["value"] = reader.readString(); - if (flags & (1 << 10)) - rec["maxLen"] = reader.readInt(); - if (rec["flag"] & (1 << 25)) - rec["richValue"] = reader.readString(); - // 12.7.4.3 - rec["multiline"] = (rec["flag"] >> 12) & 1; // Multiline - rec["password"] = (rec["flag"] >> 13) & 1; // Password - rec["fileSelect"] = (rec["flag"] >> 20) & 1; // FileSelect - rec["doNotSpellCheck"] = (rec["flag"] >> 22) & 1; // DoNotSpellCheck - rec["doNotScroll"] = (rec["flag"] >> 23) & 1; // DoNotScroll - rec["comb"] = (rec["flag"] >> 24) & 1; // Comb - rec["richText"] = (rec["flag"] >> 25) & 1; // RichText - } - else if (rec["type"] == 31 || rec["type"] == 32) - { - if (flags & (1 << 9)) - rec["value"] = reader.readString(); - if (flags & (1 << 10)) - { - let n = reader.readInt(); - rec["opt"] = []; - for (let i = 0; i < n; ++i) - { - let opt1 = reader.readString(); - let opt2 = reader.readString(); - if (opt1 == "") - rec["opt"].push(opt2); - else - rec["opt"].push([opt2, opt1]); - } - } - if (flags & (1 << 11)) - rec["TI"] = reader.readInt(); - // 12.7.4.4 - rec["editable"] = (rec["flag"] >> 18) & 1; // Edit - rec["multipleSelection"] = (rec["flag"] >> 21) & 1; // MultiSelect - rec["doNotSpellCheck"] = (rec["flag"] >> 22) & 1; // DoNotSpellCheck - rec["commitOnSelChange"] = (rec["flag"] >> 26) & 1; // CommitOnSelChange - } - else if (rec["type"] == 33) - { - rec["Sig"] = (flags >> 9) & 1; - } - - res["Fields"].push(rec); - } - - Module["_free"](ext); - return res; - }; - // optional nWidget - rec["AP"]["i"] - // optional sView - N/D/R - // optional sButtonView - state pushbutton-annotation - Off/Yes(or rec["NameOfYes"]) - CFile.prototype["getInteractiveFormsAP"] = function(pageIndex, width, height, backgroundColor, nWidget, sView, sButtonView) - { - let nView = -1; - if (sView) - { - if (sView == "N") - nView = 0; - else if (sView == "D") - nView = 1; - else if (sView == "R") - nView = 2; - } - let nButtonView = -1; - if (sButtonView) - nButtonView = (sButtonView == "Off" ? 0 : 1); - - let res = []; - self.drawingFileCurrentPageIndex = pageIndex; - let ext = Module["_GetInteractiveFormsAP"](this.nativeFile, width, height, backgroundColor === undefined ? 0xFFFFFF : backgroundColor, pageIndex, nWidget === undefined ? -1 : nWidget, nView, nButtonView); - self.drawingFileCurrentPageIndex = -1; - if (ext == 0) - return res; - - let lenArray = new Int32Array(Module["HEAP8"].buffer, ext, 4); - if (lenArray == null) - return res; - - let len = lenArray[0]; - len -= 4; - if (len <= 0) - return res; - - let buffer = new Uint8Array(Module["HEAP8"].buffer, ext + 4, len); - let reader = new CBinaryReader(buffer, 0, len); - - while (reader.isValid()) - { - // Annotation view - let AP = {}; - readAnnotAP(reader, AP); - res.push(AP); - } - - Module["_free"](ext); - return res; - }; - // optional bBase64 - true/false base64 result - // optional nWidget ... - // optional sIconView - icon - I/RI/IX - CFile.prototype["getButtonIcons"] = function(pageIndex, width, height, backgroundColor, bBase64, nWidget, sIconView) - { - let nView = -1; - if (sIconView) - { - if (sIconView == "I") - nView = 0; - else if (sIconView == "RI") - nView = 1; - else if (sIconView == "IX") - nView = 2; - } - - let res = {}; - self.drawingFileCurrentPageIndex = pageIndex; - let ext = Module["_GetButtonIcons"](this.nativeFile, width, height, backgroundColor === undefined ? 0xFFFFFF : backgroundColor, pageIndex, bBase64 ? 1 : 0, nWidget === undefined ? -1 : nWidget, nView); - self.drawingFileCurrentPageIndex = -1; - if (ext == 0) - return res; - - let lenArray = new Int32Array(Module["HEAP8"].buffer, ext, 4); - if (lenArray == null) - return res; - - let len = lenArray[0]; - len -= 4; - if (len <= 0) - return res; - - let buffer = new Uint8Array(Module["HEAP8"].buffer, ext + 4, len); - let reader = new CBinaryReader(buffer, 0, len); - - res["MK"] = []; - res["View"] = []; - - while (reader.isValid()) - { - // View pushbutton annotation - let MK = {}; - // Relation with AP - MK["i"] = reader.readInt(); - let n = reader.readInt(); - for (let i = 0; i < n; ++i) - { - let MKType = reader.readString(); - MK[MKType] = reader.readInt(); - let unique = reader.readByte(); - if (unique) - { - let ViewMK = {}; - ViewMK["j"] = MK[MKType]; - ViewMK["w"] = reader.readInt(); - ViewMK["h"] = reader.readInt(); - if (bBase64) - { - // base64 string with image - ViewMK["retValue"] = reader.readString(); - } - else - { - let np1 = reader.readInt(); - let np2 = reader.readInt(); - // this memory needs to be deleted - ViewMK["retValue"] = np2 << 32 | np1; - } - res["View"].push(ViewMK); - } - } - res["MK"].push(MK); - } - - Module["_free"](ext); - return res; - }; - // optional pageIndex - get annotations from specific page - CFile.prototype["getAnnotationsInfo"] = function(pageIndex) - { - let res = []; - let ext = Module["_GetAnnotationsInfo"](this.nativeFile, pageIndex === undefined ? -1 : pageIndex); - if (ext == 0) - return res; - - let lenArray = new Int32Array(Module["HEAP8"].buffer, ext, 4); - if (lenArray == null) - { - Module["_free"](ext); - return res; - } - - let len = lenArray[0]; - len -= 4; - if (len <= 0) - { - Module["_free"](ext); - return res; - } - - let buffer = new Uint8Array(Module["HEAP8"].buffer, ext + 4, len); - let reader = new CBinaryReader(buffer, 0, len); - - if (!reader.isValid()) - { - Module["_free"](ext); - return res; - } - - while (reader.isValid()) - { - let rec = {}; - // Annotation type - // 0 - Text, 1 - Link, 2 - FreeText, 3 - Line, 4 - Square, 5 - Circle, - // 6 - Polygon, 7 - PolyLine, 8 - Highlight, 9 - Underline, 10 - Squiggly, - // 11 - Strikeout, 12 - Stamp, 13 - Caret, 14 - Ink, 15 - Popup, 16 - FileAttachment, - // 17 - Sound, 18 - Movie, 19 - Widget, 20 - Screen, 21 - PrinterMark, - // 22 - TrapNet, 23 - Watermark, 24 - 3D, 25 - Redact - rec["Type"] = reader.readByte(); - // Annot - readAnnot(reader, rec); - // Markup - let flags = 0; - if ((rec["Type"] < 18 && rec["Type"] != 1 && rec["Type"] != 15) || rec["Type"] == 25) - { - flags = reader.readInt(); - if (flags & (1 << 0)) - rec["Popup"] = reader.readInt(); - // T - if (flags & (1 << 1)) - rec["User"] = reader.readString(); - // CA - if (flags & (1 << 2)) - rec["CA"] = reader.readDouble(); - // RC - if (flags & (1 << 3)) - rec["RC"] = reader.readString(); - // CreationDate - if (flags & (1 << 4)) - rec["CreationDate"] = reader.readString(); - // IRT - if (flags & (1 << 5)) - rec["RefTo"] = reader.readInt(); - // RT - // 0 - R, 1 - Group - if (flags & (1 << 6)) - rec["RefToReason"] = reader.readByte(); - // Subj - if (flags & (1 << 7)) - rec["Subj"] = reader.readString(); - } - // Text - if (rec["Type"] == 0) - { - rec["Open"] = (flags >> 15) & 1; - // icon - Name - // 0 - Check, 1 - Checkmark, 2 - Circle, 3 - Comment, 4 - Cross, 5 - CrossHairs, 6 - Help, 7 - Insert, 8 - Key, 9 - NewParagraph, 10 - Note, 11 - Paragraph, 12 - RightArrow, 13 - RightPointer, 14 - Star, 15 - UpArrow, 16 - UpLeftArrow - if (flags & (1 << 16)) - rec["Icon"] = reader.readByte(); - // StateModel - // 0 - Marked, 1 - Review - if (flags & (1 << 17)) - rec["StateModel"] = reader.readByte(); - // State - // 0 - Marked, 1 - Unmarked, 2 - Accepted, 3 - Rejected, 4 - Cancelled, 5 - Completed, 6 - None - if (flags & (1 << 18)) - rec["State"] = reader.readByte(); - - } - // Line - else if (rec["Type"] == 3) - { - // L - rec["L"] = []; - for (let i = 0; i < 4; ++i) - rec["L"].push(reader.readDouble()); - // LE - // 0 - Square, 1 - Circle, 2 - Diamond, 3 - OpenArrow, 4 - ClosedArrow, 5 - None, 6 - Butt, 7 - ROpenArrow, 8 - RClosedArrow, 9 - Slash - if (flags & (1 << 15)) - { - rec["LE"] = []; - rec["LE"].push(reader.readByte()); - rec["LE"].push(reader.readByte()); - } - // IC - if (flags & (1 << 16)) - { - let n = reader.readInt(); - rec["IC"] = []; - for (let i = 0; i < n; ++i) - rec["IC"].push(reader.readDouble()); - } - // LL - if (flags & (1 << 17)) - rec["LL"] = reader.readDouble(); - // LLE - if (flags & (1 << 18)) - rec["LLE"] = reader.readDouble(); - // Cap - rec["Cap"] = (flags >> 19) & 1; - // IT - // 0 - LineDimension, 1 - LineArrow - if (flags & (1 << 20)) - rec["IT"] = reader.readByte(); - // LLO - if (flags & (1 << 21)) - rec["LLO"] = reader.readDouble(); - // CP - // 0 - Inline, 1 - Top - if (flags & (1 << 22)) - rec["CP"] = reader.readByte(); - // CO - if (flags & (1 << 23)) - { - rec["CO"] = []; - rec["CO"].push(reader.readDouble()); - rec["CO"].push(reader.readDouble()); - } - } - // Ink - else if (rec["Type"] == 14) - { - // offsets like getStructure and viewer.navigate - let n = reader.readInt(); - rec["InkList"] = []; - for (let i = 0; i < n; ++i) - { - rec["InkList"][i] = []; - let m = reader.readInt(); - for (let j = 0; j < m; ++j) - rec["InkList"][i].push(reader.readDouble()); - } - } - // Highlight, Underline, Squiggly, Strikeout - else if (rec["Type"] > 7 && rec["Type"] < 12) - { - // QuadPoints - let n = reader.readInt(); - rec["QuadPoints"] = []; - for (let i = 0; i < n; ++i) - rec["QuadPoints"].push(reader.readDouble()); - } - // Square, Circle - else if (rec["Type"] == 4 || rec["Type"] == 5) - { - // Rect and RD differences - if (flags & (1 << 15)) - { - rec["RD"] = []; - for (let i = 0; i < 4; ++i) - rec["RD"].push(reader.readDouble()); - } - // IC - if (flags & (1 << 16)) - { - let n = reader.readInt(); - rec["IC"] = []; - for (let i = 0; i < n; ++i) - rec["IC"].push(reader.readDouble()); - } - } - // Polygon, PolyLine - else if (rec["Type"] == 6 || rec["Type"] == 7) - { - let nVertices = reader.readInt(); - rec["Vertices"] = []; - for (let i = 0; i < nVertices; ++i) - rec["Vertices"].push(reader.readDouble()); - // LE - // 0 - Square, 1 - Circle, 2 - Diamond, 3 - OpenArrow, 4 - ClosedArrow, 5 - None, 6 - Butt, 7 - ROpenArrow, 8 - RClosedArrow, 9 - Slash - if (flags & (1 << 15)) - { - rec["LE"] = []; - rec["LE"].push(reader.readByte()); - rec["LE"].push(reader.readByte()); - } - // IC - if (flags & (1 << 16)) - { - let n = reader.readInt(); - rec["IC"] = []; - for (let i = 0; i < n; ++i) - rec["IC"].push(reader.readDouble()); - } - // IT - // 0 - PolygonCloud, 1 - PolyLineDimension, 2 - PolygonDimension - if (flags & (1 << 20)) - rec["IT"] = reader.readByte(); - } - // Popup - /* - else if (rec["Type"] == 15) - { - flags = reader.readInt(); - rec["Open"] = (flags >> 0) & 1; - // Link to parent-annotation - if (flags & (1 << 1)) - rec["PopupParent"] = reader.readInt(); - } - */ - // FreeText - else if (rec["Type"] == 2) - { - // 0 - left-justified, 1 - centered, 2 - right-justified - rec["alignment"] = reader.readByte(); - // Rect and RD differences - if (flags & (1 << 15)) - { - rec["RD"] = []; - for (let i = 0; i < 4; ++i) - rec["RD"].push(reader.readDouble()); - } - // CL - if (flags & (1 << 16)) - { - let n = reader.readInt(); - rec["CL"] = []; - for (let i = 0; i < n; ++i) - rec["CL"].push(reader.readDouble()); - } - // Default style (CSS2 format) - DS - if (flags & (1 << 17)) - rec["defaultStyle"] = reader.readString(); - // LE - // 0 - Square, 1 - Circle, 2 - Diamond, 3 - OpenArrow, 4 - ClosedArrow, 5 - None, 6 - Butt, 7 - ROpenArrow, 8 - RClosedArrow, 9 - Slash - if (flags & (1 << 18)) - rec["LE"] = reader.readByte(); - // IT - // 0 - FreeText, 1 - FreeTextCallout, 2 - FreeTextTypeWriter - if (flags & (1 << 20)) - rec["IT"] = reader.readByte(); - } - // Caret - else if (rec["Type"] == 13) - { - // Rect and RD differenses - if (flags & (1 << 15)) - { - rec["RD"] = []; - for (let i = 0; i < 4; ++i) - rec["RD"].push(reader.readDouble()); - } - // Sy - // 0 - None, 1 - P, 2 - S - if (flags & (1 << 16)) - rec["Sy"] = reader.readByte(); - } - res.push(rec); - } - - Module["_free"](ext); - return res; - }; - // optional nAnnot ... - // optional sView ... - CFile.prototype["getAnnotationsAP"] = function(pageIndex, width, height, backgroundColor, nAnnot, sView) - { - let nView = -1; - if (sView) - { - if (sView == "N") - nView = 0; - else if (sView == "D") - nView = 1; - else if (sView == "R") - nView = 2; - } - - let res = []; - self.drawingFileCurrentPageIndex = pageIndex; - let ext = Module["_GetAnnotationsAP"](this.nativeFile, width, height, backgroundColor === undefined ? 0xFFFFFF : backgroundColor, pageIndex, nAnnot === undefined ? -1 : nAnnot, nView); - self.drawingFileCurrentPageIndex = -1; - if (ext == 0) - return res; - - let lenArray = new Int32Array(Module["HEAP8"].buffer, ext, 4); - if (lenArray == null) - return res; - - let len = lenArray[0]; - len -= 4; - if (len <= 0) - return res; - - let buffer = new Uint8Array(Module["HEAP8"].buffer, ext + 4, len); - let reader = new CBinaryReader(buffer, 0, len); - - while (reader.isValid()) - { - // Annotation view - let AP = {}; - readAnnotAP(reader, AP); - res.push(AP); - } - - Module["_free"](ext); - return res; - }; - CFile.prototype["getStructure"] = function() - { - let res = []; - let str = Module["_GetStructure"](this.nativeFile); - if (str == 0) - return res; - let lenArray = new Int32Array(Module["HEAP8"].buffer, str, 4); - if (lenArray == null) - return res; - let len = lenArray[0]; - len -= 4; - if (len <= 0) - return res; - - let buffer = new Uint8Array(Module["HEAP8"].buffer, str + 4, len); - let reader = new CBinaryReader(buffer, 0, len); - - while (reader.isValid()) - { - let rec = {}; - rec["page"] = reader.readInt(); - rec["level"] = reader.readInt(); - rec["y"] = reader.readDouble(); - rec["description"] = reader.readString(); - res.push(rec); - } - - Module["_free"](str); - return res; - }; - - CFile.prototype.memory = function() - { - return Module["HEAP8"]; - }; - CFile.prototype.free = function(pointer) - { - Module["_free"](pointer); - }; - - self["AscViewer"]["CDrawingFile"] = CFile; - self["AscViewer"]["InitializeFonts"] = function(basePath) { - if (undefined !== basePath && "" !== basePath) - baseFontsPath = basePath; - if (!window["g_fonts_selection_bin"]) - return; - let memoryBuffer = window["g_fonts_selection_bin"].toUtf8(); - let pointer = Module["_malloc"](memoryBuffer.length); - Module.HEAP8.set(memoryBuffer, pointer); - Module["_InitializeFontsBase64"](pointer, memoryBuffer.length); - Module["_free"](pointer); - delete window["g_fonts_selection_bin"]; - - // ranges - let rangesBuffer = new CBinaryWriter(); - let ranges = AscFonts.getSymbolRanges(); - - let rangesCount = ranges.length; - rangesBuffer.writeUint(rangesCount); - for (let i = 0; i < rangesCount; i++) - { - rangesBuffer.writeString(ranges[i].getName()); - rangesBuffer.writeUint(ranges[i].getStart()); - rangesBuffer.writeUint(ranges[i].getEnd()); - } - - let rangesFinalLen = rangesBuffer.dataSize; - let rangesFinal = new Uint8Array(rangesBuffer.buffer.buffer, 0, rangesFinalLen); - pointer = Module["_malloc"](rangesFinalLen); - Module.HEAP8.set(rangesFinal, pointer); - Module["_InitializeFontsRanges"](pointer, rangesFinalLen); - Module["_free"](pointer); - }; - self["AscViewer"]["Free"] = function(pointer) { - Module["_free"](pointer); - }; - - function addToArrayAsDictionary(arr, value) - { - let isFound = false; - for (let i = 0, len = arr.length; i < len; i++) - { - if (arr[i] == value) - { - isFound = true; - break; - } - } - if (!isFound) - arr.push(value); - return isFound; - } - - self["AscViewer"]["CheckStreamId"] = function(data, status) { - let lenArray = new Int32Array(Module["HEAP8"].buffer, data, 4); - let len = lenArray[0]; - len -= 4; - - let buffer = new Uint8Array(Module["HEAP8"].buffer, data + 4, len); - let reader = new CBinaryReader(buffer, 0, len); - - let name = reader.readString(); - let style = 0; - if (reader.readInt() != 0) - style |= 1;//AscFonts.FontStyle.FontStyleBold; - if (reader.readInt() != 0) - style |= 2;//AscFonts.FontStyle.FontStyleItalic; - - let file = AscFonts.pickFont(name, style); - let fileId = file.GetID(); - let fileStatus = file.GetStatus(); - - if (fileStatus === 0) - { - // font was loaded - fontToMemory(file, true); - } - else - { - self.fontStreams[fileId] = self.fontStreams[fileId] || {}; - self.fontStreams[fileId].pages = self.fontStreams[fileId].pages || []; - addToArrayAsDictionary(self.fontStreams[fileId].pages, self.drawingFileCurrentPageIndex); - - if (self.drawingFile) - { - addToArrayAsDictionary(self.drawingFile.pages[self.drawingFileCurrentPageIndex].fonts, fileId); - } - - // font can be loading in editor - if (undefined === file.externalCallback) - { - let _t = file; - file.externalCallback = function() { - fontToMemory(_t, true); - - let pages = self.fontStreams[fileId].pages; - delete self.fontStreams[fileId]; - let pagesRepaint = []; - for (let i = 0, len = pages.length; i < len; i++) - { - let pageObj = self.drawingFile.pages[pages[i]]; - let fonts = pageObj.fonts; - - for (let j = 0, len_fonts = fonts.length; j < len_fonts; j++) - { - if (fonts[j] == fileId) - { - fonts.splice(j, 1); - break; - } - } - if (0 == fonts.length) - pagesRepaint.push(pages[i]); - } - - if (pagesRepaint.length > 0) - { - if (self.drawingFile.onRepaintPages) - self.drawingFile.onRepaintPages(pagesRepaint); - } - - delete _t.externalCallback; - }; - - if (2 !== file.LoadFontAsync) - file.LoadFontAsync(baseFontsPath, null); - } - } - - let memoryBuffer = fileId.toUtf8(); - let pointer = Module["_malloc"](memoryBuffer.length); - Module.HEAP8.set(memoryBuffer, pointer); - Module["HEAP8"][status] = (fileStatus == 0) ? 1 : 0; - return pointer; - }; - - function fontToMemory(file, isCheck) - { - let idBuffer = file.GetID().toUtf8(); - let idPointer = Module["_malloc"](idBuffer.length); - Module["HEAP8"].set(idBuffer, idPointer); - - if (isCheck) - { - let nExist = Module["_IsFontBinaryExist"](idPointer); - if (nExist != 0) - { - Module["_free"](idPointer); - return; - } - } - - let stream_index = file.GetStreamIndex(); - - let stream = AscFonts.getFontStream(stream_index); - let streamPointer = Module["_malloc"](stream.size); - Module["HEAP8"].set(stream.data, streamPointer); - - Module["_SetFontBinary"](idPointer, streamPointer, stream.size); - - Module["_free"](streamPointer); - Module["_free"](idPointer); - } + //file })(window, undefined); diff --git a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_native.js b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_native.js new file mode 100644 index 00000000000..d43e81dd80b --- /dev/null +++ b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_native.js @@ -0,0 +1,227 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ + +//string_utf8 + +function CNativePointer() +{ + this.ptr = null; +} +CNativePointer.prototype.free = function() +{ + if (this.ptr) + g_native_drawing_file["FreeWasmData"](this.ptr); + this.ptr = null; +}; +CNativePointer.prototype.getReader = function() +{ + if (!this.ptr) + return null; + + return new CBinaryReader(this.ptr, 0, this.ptr.length); +}; + +var g_module_pointer = new CNativePointer(); + +// js interface +CFile.prototype._free = function(ptr) +{ + // TODO: +}; +CFile.prototype._getUint8Array = function(ptr, len) +{ + // TODO: +}; +CFile.prototype._getUint8ClampedArray = function(ptr, len) +{ + // TODO: +}; + +// FILE +CFile.prototype._openFile = function(buffer, password) +{ + let res = false; + if (!buffer) + res = -1 !== g_native_drawing_file["GetType"](); + + if (res) + this.nativeFile = 1; + return res; +}; + +CFile.prototype._closeFile = function() +{ + g_native_drawing_file["CloseFile"](); + this.nativeFile = 0; +}; + +CFile.prototype._getType = function() +{ + return g_native_drawing_file["GetType"](); +}; + +CFile.prototype._getError = function() +{ + return g_native_drawing_file["GetErrorCode"](); +}; + +// FONTS +CFile.prototype._isNeedCMap = function() +{ + return g_native_drawing_file["IsNeedCMap"](); +}; + +CFile.prototype._setCMap = function(memoryBuffer) +{ + // none +}; + +CFile.prototype._getFontByID = function(ID) +{ + return g_native_drawing_file["GetFontBinary"](ID); +}; + +CFile.prototype._getInteractiveFormsFonts = function(type) +{ + g_module_pointer.ptr = g_native_drawing_file["GetInteractiveFormsFonts"](type); + return g_module_pointer; +}; + +// INFO DOCUMENT +CFile.prototype._getInfo = function() +{ + g_module_pointer.ptr = g_native_drawing_file["GetInfo"](); + return g_module_pointer; +}; + +CFile.prototype._getStructure = function() +{ + g_module_pointer.ptr = g_native_drawing_file["GetStructure"](); + return g_module_pointer; +}; + +CFile.prototype._getLinks = function(pageIndex) +{ + g_module_pointer.ptr = g_native_drawing_file["GetLinks"](pageIndex); + return g_module_pointer; +}; + +// WIDGETS & ANNOTATIONS +CFile.prototype._getInteractiveFormsInfo = function() +{ + g_module_pointer.ptr = g_native_drawing_file["GetInteractiveFormsInfo"](); + return g_module_pointer; +}; + +CFile.prototype._getAnnotationsInfo = function(pageIndex) +{ + g_module_pointer.ptr = g_native_drawing_file["GetAnnotationsInfo"](pageIndex === undefined ? -1 : pageIndex); + return g_module_pointer; +}; + +CFile.prototype._getButtonIcons = function(backgroundColor, pageIndex, isBase64, nWidget, nView) +{ + g_module_pointer.ptr = g_native_drawing_file["GetButtonIcons"]( + backgroundColor === undefined ? 0xFFFFFF : backgroundColor, + pageIndex, + isBase64 ? 1 : 0, + nWidget === undefined ? -1 : nWidget, + nView); + return g_module_pointer; +}; + +CFile.prototype._getAnnotationsAP = function(width, height, backgroundColor, pageIndex, nAnnot, nView) +{ + g_module_pointer.ptr = g_native_drawing_file["GetAnnotationsAP"]( + width, + height, + backgroundColor === undefined ? 0xFFFFFF : backgroundColor, + pageIndex, + nAnnot === undefined ? -1 : nAnnot, + nView); + return g_module_pointer; +}; + +CFile.prototype._getInteractiveFormsAP = function(width, height, backgroundColor, pageIndex, nWidget, nView, nButtonView) +{ + g_module_pointer.ptr = g_native_drawing_file["GetInteractiveFormsAP"]( + width, + height, + backgroundColor === undefined ? 0xFFFFFF : backgroundColor, + pageIndex, + nWidget === undefined ? -1 : nWidget, + nView, nButtonView); + return g_module_pointer; +}; + +// SCAN PAGES +CFile.prototype._scanPage = function(page, mode) +{ + g_module_pointer.ptr = g_native_drawing_file["ScanPage"](page, (mode === undefined) ? 0 : mode); + return g_module_pointer; +}; + +CFile.prototype._getImageBase64 = function(rId) +{ + return g_native_drawing_file["GetImageBase64"](rId); +}; + +// TEXT +CFile.prototype._getGlyphs = function(pageIndex) +{ + let res = {}; + res.info = [0, 0, 0, 0]; + res.result = []; + return res; +}; + +CFile.prototype._destroyTextInfo = function() +{ + g_native_drawing_file["DestroyTextInfo"](rId); +}; + +// RASTER +CFile.prototype._getPixmap = function(pageIndex, width, height, backgroundColor) +{ + return null; +}; + +// STATIC FUNCTIONS +CFile.prototype._InitializeFonts = function(basePath) +{ + // none +}; + +CFile.prototype._CheckStreamId = function(data, status) +{ + // none +}; diff --git a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_wasm.js b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_wasm.js new file mode 100644 index 00000000000..f2e81f7cb00 --- /dev/null +++ b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_wasm.js @@ -0,0 +1,432 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ + +function CWasmPointer() +{ + this.ptr = 0; +} +CWasmPointer.prototype.free = function() +{ + Module["_free"](this.ptr); + this.ptr = 0; +}; +CWasmPointer.prototype.getReader = function() +{ + if (!this.ptr) + return null; + + let lenArr = new Int32Array(Module["HEAP8"].buffer, this.ptr, 1); + if (!lenArr) + { + this.free(); + return null; + } + + let len = lenArr[0]; + if (len <= 4) + { + this.free(); + return null; + } + + len -= 4; + let buffer = new Uint8Array(Module["HEAP8"].buffer, this.ptr + 4, len); + return new CBinaryReader(buffer, 0, len); +}; + +var g_module_pointer = new CWasmPointer(); + +// js interface +CFile.prototype._free = function(ptr) +{ + Module["_free"](ptr); +}; +CFile.prototype._getUint8Array = function(ptr, len) +{ + return new Uint8Array(Module["HEAP8"].buffer, ptr, len); +}; +CFile.prototype._getUint8ClampedArray = function(ptr, len) +{ + return new Uint8ClampedArray(Module["HEAP8"].buffer, ptr, len); +}; + +// FILE +CFile.prototype._openFile = function(buffer, password) +{ + if (buffer) + { + let data = new Uint8Array(buffer); + this.stream_size = data.length; + this.stream = Module["_malloc"](this.stream_size); + Module["HEAP8"].set(data, this.stream); + } + + let passwordPtr = 0; + if (password) + { + let passwordBuf = password.toUtf8(); + passwordPtr = Module["_malloc"](passwordBuf.length); + Module["HEAP8"].set(passwordBuf, passwordPtr); + } + + this.nativeFile = Module["_Open"](this.stream, this.stream_size, passwordPtr); + + if (passwordPtr) + Module["_free"](passwordPtr); + return this.nativeFile > 0 ? true : false; +}; + +CFile.prototype._closeFile = function() +{ + Module["_Close"](this.nativeFile); +}; + +CFile.prototype._getType = function() +{ + return Module["_GetType"](this.stream, this.stream_size); +}; + +CFile.prototype._getError = function() +{ + return Module["_GetErrorCode"](this.nativeFile); +}; + +// FONTS +CFile.prototype._isNeedCMap = function() +{ + let isNeed = Module["_IsNeedCMap"](this.nativeFile); + return (isNeed === 1) ? true : false; +}; + +CFile.prototype._setCMap = function(memoryBuffer) +{ + let pointer = Module["_malloc"](memoryBuffer.length); + Module.HEAP8.set(memoryBuffer, pointer); + Module["_SetCMapData"](this.nativeFile, pointer, memoryBuffer.length); +}; + +CFile.prototype._getFontByID = function(ID) +{ + if (ID === undefined) + return null; + + let idBuffer = ID.toUtf8(); + let idPointer = Module["_malloc"](idBuffer.length); + Module["HEAP8"].set(idBuffer, idPointer); + g_module_pointer.ptr = Module["_GetFontBinary"](this.nativeFile, idPointer); + Module["_free"](idPointer); + + let reader = g_module_pointer.getReader(); + if (!reader) + return null; + + let nFontLength = reader.readInt(); + let np1 = reader.readInt(); + let np2 = reader.readInt(); + let pFontPointer = np2 << 32 | np1; + + let res = new Uint8Array(Module["HEAP8"].buffer, pFontPointer, nFontLength); + g_module_pointer.free(); + return res; +}; + +CFile.prototype._getInteractiveFormsFonts = function(type) +{ + g_module_pointer.ptr = Module["_GetInteractiveFormsFonts"](this.nativeFile, type); + return g_module_pointer; +}; + +// INFO DOCUMENT +CFile.prototype._getInfo = function() +{ + g_module_pointer.ptr = Module["_GetInfo"](this.nativeFile); + return g_module_pointer; +}; + +CFile.prototype._getStructure = function() +{ + g_module_pointer.ptr = Module["_GetStructure"](this.nativeFile); + return g_module_pointer; +}; + +CFile.prototype._getLinks = function(pageIndex) +{ + g_module_pointer.ptr = Module["_GetLinks"](this.nativeFile, pageIndex); + return g_module_pointer; +}; + +// WIDGETS & ANNOTATIONS +CFile.prototype._getInteractiveFormsInfo = function() +{ + g_module_pointer.ptr = Module["_GetInteractiveFormsInfo"](this.nativeFile); + return g_module_pointer; +}; + +CFile.prototype._getAnnotationsInfo = function(pageIndex) +{ + g_module_pointer.ptr = Module["_GetAnnotationsInfo"](this.nativeFile, pageIndex === undefined ? -1 : pageIndex); + return g_module_pointer; +}; + +CFile.prototype._getButtonIcons = function(backgroundColor, pageIndex, isBase64, nWidget, nView) +{ + g_module_pointer.ptr = Module["_GetButtonIcons"](this.nativeFile, + backgroundColor === undefined ? 0xFFFFFF : backgroundColor, + pageIndex, + isBase64 ? 1 : 0, + nWidget === undefined ? -1 : nWidget, + nView); + return g_module_pointer; +}; + +CFile.prototype._getAnnotationsAP = function(width, height, backgroundColor, pageIndex, nAnnot, nView) +{ + g_module_pointer.ptr = Module["_GetAnnotationsAP"](this.nativeFile, + width, + height, + backgroundColor === undefined ? 0xFFFFFF : backgroundColor, + pageIndex, + nAnnot === undefined ? -1 : nAnnot, + nView); + return g_module_pointer; +}; + +CFile.prototype._getInteractiveFormsAP = function(width, height, backgroundColor, pageIndex, nWidget, nView, nButtonView) +{ + g_module_pointer.ptr = Module["_GetInteractiveFormsAP"](this.nativeFile, + width, + height, + backgroundColor === undefined ? 0xFFFFFF : backgroundColor, + pageIndex, + nWidget === undefined ? -1 : nWidget, + nView, nButtonView); + return g_module_pointer; +}; + +// SCAN PAGES +CFile.prototype._scanPage = function(page, mode) +{ + g_module_pointer.ptr = Module["_ScanPage"](this.nativeFile, page, (mode === undefined) ? 0 : mode); + return g_module_pointer; +}; + +CFile.prototype._getImageBase64 = function(rId) +{ + let strPtr = Module["_GetImageBase64"](this.nativeFile, rId); + if (0 == strPtr) + return "error"; + let len = Module["_GetImageBase64Len"](strPtr); + let ptr = Module["_GetImageBase64Ptr"](strPtr); + + var buffer = new Uint8Array(Module["HEAP8"].buffer, ptr, len); + let result = String.prototype.fromUtf8(buffer, 0, len); + Module["_GetImageBase64Free"](strPtr); + return result; +}; + +// TEXT +CFile.prototype._getGlyphs = function(pageIndex) +{ + let ptr = Module["_GetGlyphs"](this.nativeFile, pageIndex); + if (!ptr) + return null; + + let ptrArray = new Int32Array(Module["HEAP8"].buffer, ptr, 5); + let len = ptrArray[0]; + len -= 20; + + let res = {}; + res.info = [ptrArray[1], ptrArray[2], ptrArray[3], ptrArray[4]]; + + if (len > 0) + { + let textCommandsSrc = new Uint8Array(Module["HEAP8"].buffer, ptr + 20, len); + res.result = new Uint8Array(len); + res.result.set(textCommandsSrc); + } + else + res.result = []; + + return res; +}; + +CFile.prototype._destroyTextInfo = function() +{ + Module["_DestroyTextInfo"](); +}; + +// RASTER +CFile.prototype._getPixmap = function(pageIndex, width, height, backgroundColor) +{ + return Module["_GetPixmap"](this.nativeFile, pageIndex, width, height, backgroundColor === undefined ? 0xFFFFFF : backgroundColor); +}; + +// STATIC FUNCTIONS +CFile.prototype._InitializeFonts = function(basePath) +{ + if (undefined !== basePath && "" !== basePath) + baseFontsPath = basePath; + if (!window["g_fonts_selection_bin"]) + return; + let memoryBuffer = window["g_fonts_selection_bin"].toUtf8(); + let pointer = Module["_malloc"](memoryBuffer.length); + Module.HEAP8.set(memoryBuffer, pointer); + Module["_InitializeFontsBase64"](pointer, memoryBuffer.length); + Module["_free"](pointer); + delete window["g_fonts_selection_bin"]; + + // ranges + let rangesBuffer = new CBinaryWriter(); + let ranges = AscFonts.getSymbolRanges(); + + let rangesCount = ranges.length; + rangesBuffer.writeUint(rangesCount); + for (let i = 0; i < rangesCount; i++) + { + rangesBuffer.writeString(ranges[i].getName()); + rangesBuffer.writeUint(ranges[i].getStart()); + rangesBuffer.writeUint(ranges[i].getEnd()); + } + + let rangesFinalLen = rangesBuffer.dataSize; + let rangesFinal = new Uint8Array(rangesBuffer.buffer.buffer, 0, rangesFinalLen); + pointer = Module["_malloc"](rangesFinalLen); + Module.HEAP8.set(rangesFinal, pointer); + Module["_InitializeFontsRanges"](pointer, rangesFinalLen); + Module["_free"](pointer); +}; + +CFile.prototype._CheckStreamId = function(data, status) +{ + let drawingFile = self.drawingFile; + if (!drawingFile) + return; + + let lenArray = new Int32Array(Module["HEAP8"].buffer, data, 4); + let len = lenArray[0]; + len -= 4; + + let buffer = new Uint8Array(Module["HEAP8"].buffer, data + 4, len); + let reader = new CBinaryReader(buffer, 0, len); + + let name = reader.readString(); + let style = 0; + if (reader.readInt() != 0) + style |= 1;//AscFonts.FontStyle.FontStyleBold; + if (reader.readInt() != 0) + style |= 2;//AscFonts.FontStyle.FontStyleItalic; + + let file = AscFonts.pickFont(name, style); + let fileId = file.GetID(); + let fileStatus = file.GetStatus(); + + if (fileStatus === 0) + { + // font was loaded + fontToMemory(file, true); + } + else + { + drawingFile.fontStreams[fileId] = drawingFile.fontStreams[fileId] || {}; + drawingFile.fontStreams[fileId].pages = drawingFile.fontStreams[fileId].pages || []; + addToArrayAsDictionary(drawingFile.fontStreams[fileId].pages, drawingFile.fontPageIndex); + addToArrayAsDictionary(drawingFile.pages[drawingFile.fontPageIndex].fonts, fileId); + + drawingFile.pages[drawingFile.fontPageIndex].fontsUpdateType |= drawingFile.fontPageUpdateType; + + // font can be loading in editor + if (undefined === file.externalCallback) + { + let _t = file; + file.externalCallback = function() { + fontToMemory(_t, true); + + let pages = drawingFile.fontStreams[fileId].pages; + delete drawingFile.fontStreams[fileId]; + + let pagesRepaint_Page = []; + let pagesRepaint_Annotation = []; + let pagesRepaint_Forms = []; + + for (let i = 0, len = pages.length; i < len; i++) + { + let pageNum = pages[i]; + let pageObj = drawingFile.pages[pageNum]; + let fonts = pageObj.fonts; + + for (let j = 0, len_fonts = fonts.length; j < len_fonts; j++) + { + if (fonts[j] == fileId) + { + fonts.splice(j, 1); + break; + } + } + + if (0 == fonts.length) + { + if (pageObj.fontsUpdateType & UpdateFontsSource.Page) + pagesRepaint_Page.push(pageNum); + + if (pageObj.fontsUpdateType & UpdateFontsSource.Annotation) + pagesRepaint_Annotation.push(pageNum); + + if (pageObj.fontsUpdateType & UpdateFontsSource.Forms) + pagesRepaint_Forms.push(pageNum); + + pageObj.fontsUpdateType = UpdateFontsSource.Undefined; + } + } + + if (pagesRepaint_Page.length > 0 && drawingFile.onRepaintPages) + drawingFile.onRepaintPages(pagesRepaint_Page); + + if (pagesRepaint_Annotation.length > 0 && drawingFile.onRepaintAnnotations) + drawingFile.onRepaintAnnotations(pagesRepaint_Annotation); + + if (pagesRepaint_Forms.length > 0 && drawingFile.onRepaintForms) + drawingFile.onRepaintForms(pagesRepaint_Forms); + + delete _t.externalCallback; + }; + + if (2 !== file.LoadFontAsync) + file.LoadFontAsync(baseFontsPath, null); + } + } + + let memoryBuffer = fileId.toUtf8(); + let pointer = Module["_malloc"](memoryBuffer.length); + Module.HEAP8.set(memoryBuffer, pointer); + Module["HEAP8"][status] = (fileStatus == 0) ? 1 : 0; + return pointer; +}; diff --git a/DesktopEditor/graphics/pro/js/wasm/js/stream.js b/DesktopEditor/graphics/pro/js/wasm/js/stream.js new file mode 100644 index 00000000000..2345ff97ff8 --- /dev/null +++ b/DesktopEditor/graphics/pro/js/wasm/js/stream.js @@ -0,0 +1,115 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ + +function CBinaryReader(data, start, size) +{ + this.data = data; + this.pos = start; + this.limit = start + size; +} +CBinaryReader.prototype.readByte = function() +{ + let val = this.data[this.pos]; + this.pos += 1; + return val; +}; +CBinaryReader.prototype.readInt = function() +{ + let val = this.data[this.pos] | this.data[this.pos + 1] << 8 | this.data[this.pos + 2] << 16 | this.data[this.pos + 3] << 24; + this.pos += 4; + return val; +}; +CBinaryReader.prototype.readDouble = function() +{ + return this.readInt() / 100; +}; +CBinaryReader.prototype.readDouble2 = function() +{ + return this.readInt() / 10000; +}; +CBinaryReader.prototype.readString = function() +{ + let len = this.readInt(); + let val = String.prototype.fromUtf8(this.data, this.pos, len); + this.pos += len; + return val; +}; +CBinaryReader.prototype.readData = function() +{ + let len = this.readInt(); + let val = this.data.slice(this.pos, this.pos + len); + this.pos += len; + return val; +}; +CBinaryReader.prototype.isValid = function() +{ + return (this.pos < this.limit) ? true : false; +}; +CBinaryReader.prototype.Skip = function(nPos) +{ + this.pos += nPos; +}; + +function CBinaryWriter() +{ + this.size = 100000; + this.dataSize = 0; + this.buffer = new Uint8Array(this.size); +} +CBinaryWriter.prototype.checkAlloc = function(addition) +{ + if ((this.dataSize + addition) <= this.size) + return; + + let newSize = Math.max(this.size * 2, this.size + addition); + let newBuffer = new Uint8Array(newSize); + newBuffer.set(this.buffer, 0); + + this.size = newSize; + this.buffer = newBuffer; +}; +CBinaryWriter.prototype.writeUint = function(value) +{ + this.checkAlloc(4); + let val = (value>2147483647)?value-4294967296:value; + this.buffer[this.dataSize++] = (val) & 0xFF; + this.buffer[this.dataSize++] = (val >>> 8) & 0xFF; + this.buffer[this.dataSize++] = (val >>> 16) & 0xFF; + this.buffer[this.dataSize++] = (val >>> 24) & 0xFF; +}; +CBinaryWriter.prototype.writeString = function(value) +{ + let valueUtf8 = value.toUtf8(); + this.checkAlloc(valueUtf8.length); + this.buffer.set(valueUtf8, this.dataSize); + this.dataSize += valueUtf8.length; +}; diff --git a/HtmlRenderer/src/HTMLRendererText.cpp b/DesktopEditor/graphics/pro/js/wasm/src/HTMLRendererText.cpp similarity index 74% rename from HtmlRenderer/src/HTMLRendererText.cpp rename to DesktopEditor/graphics/pro/js/wasm/src/HTMLRendererText.cpp index 52e8442b3af..4177ee8ce32 100644 --- a/HtmlRenderer/src/HTMLRendererText.cpp +++ b/DesktopEditor/graphics/pro/js/wasm/src/HTMLRendererText.cpp @@ -29,8 +29,8 @@ * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode * */ -#include "../include/HTMLRendererText.h" -#include "./Text.h" +#include "HTMLRendererText.h" +#include "Text.h" namespace NSHtmlRenderer { @@ -40,52 +40,35 @@ namespace NSHtmlRenderer double m_dWidth; double m_dHeght; - NSStructures::CBrush m_oBrush; - NSStructures::CBrush m_oLastBrush; - NSStructures::CFont m_oFont; - NSStructures::CFont* m_pFont; NSStructures::CFont m_oInstalledFont; - LONG m_lCurrentFont; - double m_dCurrentFontSize; Aggplus::CMatrix m_oTransform; Aggplus::CMatrix m_oLastTransform; - bool m_bIsChangedFontParamBetweenDrawText; - LONG m_lCurrentCommandType; - LONG m_lSrcFileType; - CHText m_oSmartText; - CMetafile m_oPage; + NSWasm::CData m_oPage; - int* m_pTempUnicodes; - int m_nTempUnicodesAlloc; - int m_nTempUnicodesLen; + int* m_pTempUnicodes; // массив юникодов + int m_nTempUnicodesAlloc; // размер выделенной памяти + int m_nTempUnicodesLen; // размер используемой памяти bool m_bIsFontsInit; public: CHTMLRendererText_Private() { - m_bIsChangedFontParamBetweenDrawText = true; - m_lSrcFileType = 0; m_pTempUnicodes = NULL; m_nTempUnicodesLen = 0; m_nTempUnicodesAlloc = 0; m_bIsFontsInit = false; - - m_lCurrentFont = 0; - m_dCurrentFontSize = 0; - m_pFont = &m_oFont; } ~CHTMLRendererText_Private() { RELEASEARRAYOBJECTS(m_pTempUnicodes); } - public: void GetUnicodes(const std::wstring& sText) { int nLen = (int)sText.length(); @@ -101,7 +84,7 @@ namespace NSHtmlRenderer if (sizeof(wchar_t) == 2) { - for (int nIndex = 0, nGlyphIndex = 0; nIndex < nLen; ++nIndex, ++nGlyphIndex) + for (int nIndex = 0; nIndex < nLen; ++nIndex) { int code = (int)pWchars[nIndex]; if (code >= 0xD800 && code <= 0xDFFF && (nIndex + 1) < nLen) @@ -109,32 +92,25 @@ namespace NSHtmlRenderer ++nIndex; code = 0x10000 + (((code & 0x3FF) << 10) | (0x03FF & pWchars[nIndex])); } - m_pTempUnicodes[m_nTempUnicodesLen++] = code; } } else { - for ( int nIndex = 0; nIndex < nLen; ++nIndex ) - { + for (int nIndex = 0; nIndex < nLen; ++nIndex) m_pTempUnicodes[m_nTempUnicodesLen++] = (int)pWchars[nIndex]; - } } } - - void WriteText(const int* pUnicodes, const int* pGids, const int& nCount, const double& x, const double& y, - const double& width, const double& height, const bool& bIsChangedFontParamBetweenDrawText) + void WriteText(const int* pUnicodes, const int* pGids, const int& nCount, const double& x, const double& y) { bool bIsDumpFont = false; if (!m_oInstalledFont.IsEqual(&m_oFont)) { m_oInstalledFont = m_oFont; bIsDumpFont = true; - - m_dCurrentFontSize = m_oInstalledFont.Size; } - m_oSmartText.CommandText(pUnicodes, pGids, nCount, x, y, width, height, bIsDumpFont, this); + m_oSmartText.CommandText(pUnicodes, pGids, nCount, x, y, bIsDumpFont); } }; @@ -149,9 +125,6 @@ namespace NSHtmlRenderer void CHTMLRendererText::Init(IOfficeDrawingFile* pFile, int nCacheSize) { - m_pInternal->m_oBrush.SetDefaultParams(); - m_pInternal->m_oLastBrush.SetDefaultParams(); - m_pInternal->m_oFont.SetDefaultParams(); m_pInternal->m_oInstalledFont.SetDefaultParams(); m_pInternal->m_oInstalledFont.Name = L""; @@ -159,87 +132,38 @@ namespace NSHtmlRenderer m_pInternal->m_oTransform.Reset(); m_pInternal->m_oLastTransform.Reset(); - m_pInternal->m_oLastBrush.Color1 = -1; - m_pInternal->m_dCurrentFontSize = 0.0; - - m_pInternal->m_bIsChangedFontParamBetweenDrawText = false; - m_pInternal->m_lCurrentCommandType = -1; - - m_pInternal->m_oSmartText.NewPage(); - if (!m_pInternal->m_bIsFontsInit) { m_pInternal->m_oSmartText.m_oFontManager.m_pFont = &m_pInternal->m_oFont; - - m_pInternal->m_oSmartText.m_pLastBrush = &m_pInternal->m_oLastBrush; - m_pInternal->m_oSmartText.m_pBrush = &m_pInternal->m_oBrush; - - m_pInternal->m_oSmartText.m_pFont = &m_pInternal->m_oFont; - + m_pInternal->m_oSmartText.m_oFontManager.Init(pFile->GetFonts(), nCacheSize); m_pInternal->m_oSmartText.m_pTransform = &m_pInternal->m_oTransform; m_pInternal->m_oSmartText.m_pLastTransform = &m_pInternal->m_oLastTransform; - m_pInternal->m_oSmartText.m_pPageMeta = &m_pInternal->m_oPage; - - OfficeDrawingFileType eType = pFile->GetType(); - switch (eType) - { - case odftPDF: - { - m_pInternal->m_lSrcFileType = AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_PDF; - m_pInternal->m_oSmartText.m_dTextSpaceEps = 0.1; - break; - } - case odftDJVU: - { - m_pInternal->m_lSrcFileType = AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_DJVU; - m_pInternal->m_oSmartText.m_dTextSpaceEps = 0.1; - break; - } - case odftXPS: - { - m_pInternal->m_lSrcFileType = AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_XPS; - m_pInternal->m_oSmartText.m_dTextSpaceEps = 0.1; - break; - } - default: - break; - } - m_pInternal->m_bIsFontsInit = true; - m_pInternal->m_oSmartText.Init(pFile->GetFonts(), nCacheSize); } m_pInternal->m_oPage.ClearNoAttack(); - m_pInternal->m_oPage.WriteLONG(0); - + m_pInternal->m_oPage.SkipLen(); // статистика - m_pInternal->m_oPage.WriteLONG(0); - m_pInternal->m_oPage.WriteLONG(0); - m_pInternal->m_oPage.WriteLONG(0); - m_pInternal->m_oPage.WriteLONG(0); - + m_pInternal->m_oPage.AddInt(0); + m_pInternal->m_oPage.AddInt(0); + m_pInternal->m_oPage.AddInt(0); + m_pInternal->m_oPage.AddInt(0); } - BYTE* CHTMLRendererText::GetBuffer() { m_pInternal->m_oSmartText.ClosePage(); - LONG lPos = m_pInternal->m_oPage.GetPosition(); - m_pInternal->m_oPage.Seek(0); - // len - m_pInternal->m_oPage.WriteLONG(lPos); - // stat - m_pInternal->m_oPage.WriteLONG(m_pInternal->m_oSmartText.m_lCountParagraphs); - m_pInternal->m_oPage.WriteLONG(m_pInternal->m_oSmartText.m_lCountWords); - m_pInternal->m_oPage.WriteLONG(m_pInternal->m_oSmartText.m_lCountSymbols); - m_pInternal->m_oPage.WriteLONG(m_pInternal->m_oSmartText.m_lCountSpaces); - // seek to end - m_pInternal->m_oPage.Seek(lPos); + + m_pInternal->m_oPage.WriteLen(); + // статистика + m_pInternal->m_oPage.AddInt(m_pInternal->m_oSmartText.m_nCountParagraphs, 4); + m_pInternal->m_oPage.AddInt(m_pInternal->m_oSmartText.m_nCountWords, 8); + m_pInternal->m_oPage.AddInt(m_pInternal->m_oSmartText.m_nCountSymbols, 12); + m_pInternal->m_oPage.AddInt(m_pInternal->m_oSmartText.m_nCountSpaces, 16); m_pInternal->m_oSmartText.ClearStatistics(); - return m_pInternal->m_oPage.GetData(); + return m_pInternal->m_oPage.GetBuffer(); } - HRESULT CHTMLRendererText::get_Type(LONG* lType) { *lType = c_nHtmlRendrererText; @@ -247,10 +171,7 @@ namespace NSHtmlRenderer } //-------- Функции для работы со страницей -------------------------------------------------- - HRESULT CHTMLRendererText::NewPage() - { - return S_OK; - } + HRESULT CHTMLRendererText::NewPage() { return S_OK; } HRESULT CHTMLRendererText::get_Height(double* dHeight) { *dHeight = m_pInternal->m_dHeght; @@ -311,36 +232,12 @@ namespace NSHtmlRenderer HRESULT CHTMLRendererText::put_BrushTransform(const Aggplus::CMatrix& oMatrix) { return S_OK; } // brush ------------------------------------------------------------------------------------ - HRESULT CHTMLRendererText::get_BrushType(LONG* lType) - { - *lType = m_pInternal->m_oBrush.Type; - return S_OK; - } - HRESULT CHTMLRendererText::put_BrushType(const LONG& lType) - { - m_pInternal->m_oBrush.Type = lType; - return S_OK; - } - HRESULT CHTMLRendererText::get_BrushColor1(LONG* lColor) - { - *lColor = m_pInternal->m_oBrush.Color1; - return S_OK; - } - HRESULT CHTMLRendererText::put_BrushColor1(const LONG& lColor) - { - m_pInternal->m_oBrush.Color1 = lColor; - return S_OK; - } - HRESULT CHTMLRendererText::get_BrushAlpha1(LONG* lAlpha) - { - *lAlpha = m_pInternal->m_oBrush.Alpha1; - return S_OK; - } - HRESULT CHTMLRendererText::put_BrushAlpha1(const LONG& lAlpha) - { - m_pInternal->m_oBrush.Alpha1 = lAlpha; - return S_OK; - } + HRESULT CHTMLRendererText::get_BrushType(LONG* lType) { return S_OK; } + HRESULT CHTMLRendererText::put_BrushType(const LONG& lType) { return S_OK; } + HRESULT CHTMLRendererText::get_BrushColor1(LONG* lColor) { return S_OK; } + HRESULT CHTMLRendererText::put_BrushColor1(const LONG& lColor) { return S_OK; } + HRESULT CHTMLRendererText::get_BrushAlpha1(LONG* lAlpha) { return S_OK; } + HRESULT CHTMLRendererText::put_BrushAlpha1(const LONG& lAlpha) { return S_OK; } HRESULT CHTMLRendererText::get_BrushColor2(LONG* lColor) { return S_OK; } HRESULT CHTMLRendererText::put_BrushColor2(const LONG& lColor) { return S_OK; } HRESULT CHTMLRendererText::get_BrushAlpha2(LONG* lAlpha) { return S_OK; } @@ -366,7 +263,6 @@ namespace NSHtmlRenderer HRESULT CHTMLRendererText::put_FontName(const std::wstring& bsName) { m_pInternal->m_oFont.Name = bsName; - m_pInternal->m_bIsChangedFontParamBetweenDrawText = true; return S_OK; } HRESULT CHTMLRendererText::get_FontPath(std::wstring* bsName) @@ -377,7 +273,6 @@ namespace NSHtmlRenderer HRESULT CHTMLRendererText::put_FontPath(const std::wstring& bsName) { m_pInternal->m_oFont.Path = bsName; - m_pInternal->m_bIsChangedFontParamBetweenDrawText = true; return S_OK; } HRESULT CHTMLRendererText::get_FontSize(double* dSize) @@ -387,11 +282,7 @@ namespace NSHtmlRenderer } HRESULT CHTMLRendererText::put_FontSize(const double& dSize) { - if (m_pInternal->m_oFont.Size != dSize) - { - m_pInternal->m_oFont.Size = dSize; - m_pInternal->m_bIsChangedFontParamBetweenDrawText = true; - } + m_pInternal->m_oFont.Size = dSize; return S_OK; } HRESULT CHTMLRendererText::get_FontStyle(LONG* lStyle) @@ -401,12 +292,7 @@ namespace NSHtmlRenderer } HRESULT CHTMLRendererText::put_FontStyle(const LONG& lStyle) { - LONG lOld = m_pInternal->m_oFont.GetStyle(); - if (lOld != lStyle) - { - m_pInternal->m_oFont.SetStyle(lStyle); - m_pInternal->m_bIsChangedFontParamBetweenDrawText = true; - } + m_pInternal->m_oFont.SetStyle(lStyle); return S_OK; } HRESULT CHTMLRendererText::get_FontStringGID(INT* bGID) @@ -443,58 +329,34 @@ namespace NSHtmlRenderer //-------- Функции для вывода текста -------------------------------------------------------- HRESULT CHTMLRendererText::CommandDrawTextCHAR(const LONG& c, const double& x, const double& y, const double& w, const double& h) { - if (c_nHyperlinkType == m_pInternal->m_lCurrentCommandType) - return S_OK; - int _c = (int)c; - m_pInternal->WriteText(&_c, NULL, 1, x, y, w, h, m_pInternal->m_bIsChangedFontParamBetweenDrawText); - m_pInternal->m_bIsChangedFontParamBetweenDrawText = false; + m_pInternal->WriteText(&_c, NULL, 1, x, y); return S_OK; } HRESULT CHTMLRendererText::CommandDrawText(const std::wstring& bsText, const double& x, const double& y, const double& w, const double& h) { - if (c_nHyperlinkType == m_pInternal->m_lCurrentCommandType) - return S_OK; - m_pInternal->GetUnicodes(bsText); - m_pInternal->WriteText(m_pInternal->m_pTempUnicodes, NULL, m_pInternal->m_nTempUnicodesLen, x, y, w, h, m_pInternal->m_bIsChangedFontParamBetweenDrawText); - m_pInternal->m_bIsChangedFontParamBetweenDrawText = false; + m_pInternal->WriteText(m_pInternal->m_pTempUnicodes, NULL, m_pInternal->m_nTempUnicodesLen, x, y); return S_OK; } HRESULT CHTMLRendererText::CommandDrawTextExCHAR(const LONG& c, const LONG& gid, const double& x, const double& y, const double& w, const double& h) { - if (c_nHyperlinkType == m_pInternal->m_lCurrentCommandType) - return S_OK; - int _c = (int)c; int _g = (int)gid; - m_pInternal->WriteText(&_c, &_g, 1, x, y, w, h, m_pInternal->m_bIsChangedFontParamBetweenDrawText); - m_pInternal->m_bIsChangedFontParamBetweenDrawText = false; + m_pInternal->WriteText(&_c, &_g, 1, x, y); return S_OK; } HRESULT CHTMLRendererText::CommandDrawTextEx(const std::wstring& bsUnicodeText, const unsigned int* pGids, const unsigned int nGidsCount, const double& x, const double& y, const double& w, const double& h) { - if (c_nHyperlinkType == m_pInternal->m_lCurrentCommandType) - return S_OK; - m_pInternal->GetUnicodes(bsUnicodeText); - m_pInternal->WriteText(m_pInternal->m_pTempUnicodes, (const int*)pGids, m_pInternal->m_nTempUnicodesLen, x, y, w, h, m_pInternal->m_bIsChangedFontParamBetweenDrawText); - m_pInternal->m_bIsChangedFontParamBetweenDrawText = false; + m_pInternal->WriteText(m_pInternal->m_pTempUnicodes, (const int*)pGids, m_pInternal->m_nTempUnicodesLen, x, y); return S_OK; } //-------- Маркеры для команд --------------------------------------------------------------- - HRESULT CHTMLRendererText::BeginCommand(const DWORD& lType) - { - m_pInternal->m_lCurrentCommandType = lType; - return S_OK; - } - HRESULT CHTMLRendererText::EndCommand(const DWORD& lType) - { - m_pInternal->m_lCurrentCommandType = -1; - return S_OK; - } + HRESULT CHTMLRendererText::BeginCommand(const DWORD& lType) { return S_OK; } + HRESULT CHTMLRendererText::EndCommand(const DWORD& lType) { return S_OK; } //-------- Функции для работы с Graphics Path ----------------------------------------------- HRESULT CHTMLRendererText::PathCommandMoveTo(const double& x, const double& y) { return S_OK; } diff --git a/HtmlRenderer/include/HTMLRendererText.h b/DesktopEditor/graphics/pro/js/wasm/src/HTMLRendererText.h similarity index 97% rename from HtmlRenderer/include/HTMLRendererText.h rename to DesktopEditor/graphics/pro/js/wasm/src/HTMLRendererText.h index 68b51c740e7..79a4d144f90 100644 --- a/HtmlRenderer/include/HTMLRendererText.h +++ b/DesktopEditor/graphics/pro/js/wasm/src/HTMLRendererText.h @@ -29,11 +29,11 @@ * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode * */ -#ifndef _ASC_HTMLRENDERER3_H_ -#define _ASC_HTMLRENDERER3_H_ +#ifndef _ASC_HTMLRENDERER3_TEXT_H_ +#define _ASC_HTMLRENDERER3_TEXT_H_ -#include "../../DesktopEditor/graphics/IRenderer.h" -#include "../../DesktopEditor/graphics/pro/officedrawingfile.h" +#include "../../../../IRenderer.h" +#include "../../../officedrawingfile.h" #ifndef HTMLRENDERER_USE_DYNAMIC_LIBRARY #define HTMLRENDERER_DECL_EXPORT @@ -187,4 +187,4 @@ namespace NSHtmlRenderer }; } -#endif // _ASC_HTMLRENDERER3_H_ +#endif // _ASC_HTMLRENDERER3_TEXT_H_ diff --git a/DesktopEditor/graphics/pro/js/wasm/src/Text.h b/DesktopEditor/graphics/pro/js/wasm/src/Text.h new file mode 100644 index 00000000000..2f4ef404cfc --- /dev/null +++ b/DesktopEditor/graphics/pro/js/wasm/src/Text.h @@ -0,0 +1,409 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#ifndef _ASC_HTMLRENDERER_TEXT_H_ +#define _ASC_HTMLRENDERER_TEXT_H_ + +#include + +#include "serialize.h" +#include "../../../../structures.h" +#include "../../../Fonts.h" + +namespace NSHtmlRenderer +{ + struct CHFontInfo + { + int m_lAscent; + int m_lDescent; + int m_lUnitsPerEm; + + CHFontInfo() : m_lAscent(0), m_lDescent(0), m_lUnitsPerEm(0) {} + CHFontInfo(const CHFontInfo& oSrc) : m_lAscent(oSrc.m_lAscent), m_lDescent(oSrc.m_lDescent), m_lUnitsPerEm(oSrc.m_lUnitsPerEm) {} + CHFontInfo& operator=(const CHFontInfo& oSrc) + { + m_lAscent = oSrc.m_lAscent; + m_lDescent = oSrc.m_lDescent; + m_lUnitsPerEm = oSrc.m_lUnitsPerEm; + return *this; + } + }; + + class CFontManagerWrapper + { + private: + NSFonts::IFontManager* m_pManager; + public: + NSStructures::CFont* m_pFont; + CHFontInfo m_oCurrentInfo; + + public: + CFontManagerWrapper() : m_pManager(NULL) {} + virtual ~CFontManagerWrapper() + { + RELEASEOBJECT(m_pManager); + } + + void Init(NSFonts::IApplicationFonts* pApplicationFonts, int nCacheSize = 0) + { + RELEASEOBJECT(m_pManager); + m_pManager = pApplicationFonts->GenerateFontManager(); + if (nCacheSize) + { + NSFonts::IFontsCache* pFontCache = NSFonts::NSFontCache::Create(); + pFontCache->SetStreams(pApplicationFonts->GetStreams()); + pFontCache->SetCacheSize(nCacheSize); + m_pManager->SetOwnerCache(pFontCache); + } + } + void SetStringGID(INT bGid) + { + m_pManager->SetStringGID(bGid); + } + void LoadCurrentFont() + { + if (m_pFont->Path.empty()) + LoadFontByName(m_pFont->Name, m_pFont->Size, m_pFont->GetStyle()); + else + LoadFontByFile(m_pFont->Path, m_pFont->Size); + } + double MeasureString(const unsigned int* symbols, const int& count, double x, double y) + { + if (!m_pManager) + return 0; + + m_pManager->LoadString1(symbols, count, (float)x, (float)y); + TBBox _box = m_pManager->MeasureString2(); + + return abs((_box.fMaxX - _box.fMinX) * 25.4 / 72.0); + } + + private: + inline void LoadFontByName(const std::wstring& strName, const double& dSize, const LONG& lStyle) + { + m_pManager->LoadFontByName(strName, dSize, lStyle, 72.0, 72.0); + LoadFontMetrics(); + } + inline void LoadFontByFile(const std::wstring& strPath, const double& dSize) + { + m_pManager->LoadFontFromFile(strPath, 0, dSize, 72.0, 72.0); + LoadFontMetrics(); + } + void LoadFontMetrics() + { + m_pManager->AfterLoad(); + m_oCurrentInfo.m_lAscent = abs(m_pManager->GetAscender()); + m_oCurrentInfo.m_lDescent = abs(m_pManager->GetDescender()); + m_oCurrentInfo.m_lUnitsPerEm = abs(m_pManager->GetUnitsPerEm()); + } + }; + + struct CHText + { + CFontManagerWrapper m_oFontManager; + Aggplus::CMatrix* m_pTransform; + Aggplus::CMatrix* m_pLastTransform; + + NSWasm::CHLine m_oLine; + NSWasm::CData* m_pPageMeta; + + LONG m_nCountParagraphs; + LONG m_nCountWords; + LONG m_nCountSymbols; + LONG m_nCountSpaces; + + CHText() : m_oFontManager(), m_oLine() + { + m_nCountParagraphs = 0; + m_nCountWords = 0; + m_nCountSymbols = 0; + m_nCountSpaces = 0; + } + + void ClearStatistics() + { + m_nCountParagraphs = 0; + m_nCountWords = 0; + m_nCountSymbols = 0; + m_nCountSpaces = 0; + } + void ClosePage() + { + if (m_oLine.GetCountChars()) + DumpLine(); + } + void CommandText(const int* pUnicodes, const int* pGids, const int& nCount, const double& x, const double& y, bool bIsDumpFont) + { + // 1) сначала определяем точку отсчета и направление baseline + double _x1 = x; + double _y1 = y; + double _x2 = x + 1; + double _y2 = y; + m_pTransform->TransformPoint(_x1, _y1); + m_pTransform->TransformPoint(_x2, _y2); + + double _k = 0; + double _b = 0; + bool _isConstX = false; + if (fabs(_x1 - _x2) < 0.001) + { + _isConstX = true; + _b = _x1; + } + else + { + _k = (_y1 - _y2) / (_x1 - _x2); + _b = _y1 - _k * _x1; + } + + double dAbsVec = sqrt((_x1 - _x2) * (_x1 - _x2) + (_y1 - _y2) * (_y1 - _y2)); + if (dAbsVec == 0) + dAbsVec = 1; + + bool bIsNewLine = true; + if (m_oLine.GetCountChars()) + { + if (_isConstX && m_oLine.m_bIsConstX && fabs(_b - m_oLine.m_dB) < 0.001) + bIsNewLine = false; + else if (!_isConstX && !m_oLine.m_bIsConstX && fabs(_k - m_oLine.m_dK) < 0.001 && fabs(_b - m_oLine.m_dB) < 0.001) + bIsNewLine = false; + + if (bIsNewLine) // не совпала baseline. поэтому просто скидываем линию в поток + DumpLine(); + } + + // теперь нужно определить сдвиг по baseline относительно destination точки + double dOffsetX = 0; + LONG nCountChars = m_oLine.GetCountChars(); + if (0 == nCountChars) + { + m_oLine.m_bIsConstX = _isConstX; + m_oLine.m_dK = _k; + m_oLine.m_dB = _b; + + m_oLine.m_dX = _x1; + m_oLine.m_dY = _y1; + + m_oLine.m_ex = (_x2 - _x1) / dAbsVec; + m_oLine.m_ey = (_y2 - _y1) / dAbsVec; + + m_oLine.m_dEndX = _x1; + m_oLine.m_dEndY = _y1; + } + else + { + double sx = _x1 - m_oLine.m_dEndX; + double sy = _y1 - m_oLine.m_dEndY; + double len = sqrt(sx*sx + sy*sy); + + if (sx * m_oLine.m_ex >= 0 && sy * m_oLine.m_ey >= 0) + { + // продолжаем линию + dOffsetX = len; + + // теперь посмотрим, может быть нужно вставить пробел?? + NSWasm::CHChar* pLastChar = m_oLine.GetTail(); + if (dOffsetX > (pLastChar->width + 0.5)) + { + // вставляем пробел. Пробел у нас будет не совсем пробел. А специфический + NSWasm::CHChar* pSpaceChar = m_oLine.AddTail(); + pLastChar = &m_oLine.m_pChars[m_oLine.m_lCharsTail - 2]; + pSpaceChar->x = pLastChar->width; + pSpaceChar->width = dOffsetX - pLastChar->width; + pSpaceChar->unicode = 0xFFFF; + dOffsetX -= pLastChar->width; + } + } + else + { + // буква сдвинута влево относительно предыдущей буквы + // на такую ситуацию реагируем просто - просто начинаем новую линию, + // предварительно сбросив старую + DumpLine(); + + m_oLine.m_bIsConstX = _isConstX; + + m_oLine.m_dX = _x1; + m_oLine.m_dY = _y1; + + m_oLine.m_dK = _k; + m_oLine.m_dB = _b; + + m_oLine.m_ex = (_x2 - _x1) / dAbsVec; + m_oLine.m_ey = (_y2 - _y1) / dAbsVec; + } + + m_oLine.m_dEndX = _x1; + m_oLine.m_dEndY = _y1; + } + + if (!Aggplus::CMatrix::IsEqual(m_pLastTransform, m_pTransform, 0.001, true)) + { // смотрим, совпадает ли главная часть матрицы + bIsDumpFont = true; + *m_pLastTransform = *m_pTransform; + m_oLine.m_bIsSetUpTransform = true; + m_oLine.m_sx = m_pTransform->sx(); + m_oLine.m_shx = m_pTransform->shx(); + m_oLine.m_shy = m_pTransform->shy(); + m_oLine.m_sy = m_pTransform->sy(); + } + + // все, baseline установлен. теперь просто продолжаем линию + if (bIsDumpFont) + m_oFontManager.LoadCurrentFont(); + + double dKoef = m_oFontManager.m_pFont->Size * 25.4 / (72 * m_oFontManager.m_oCurrentInfo.m_lUnitsPerEm); + double dAscender = m_oFontManager.m_oCurrentInfo.m_lAscent * dKoef * dAbsVec; + double dDescender = m_oFontManager.m_oCurrentInfo.m_lDescent * dKoef * dAbsVec; + + if (m_oLine.m_dAscent < dAscender) + m_oLine.m_dAscent = dAscender; + if (m_oLine.m_dDescent < dDescender) + m_oLine.m_dDescent = dDescender; + + const int* input = NULL; + if (NULL != pGids) + { + input = pGids; + m_oFontManager.SetStringGID(TRUE); + } + else + { + input = pUnicodes; + m_oFontManager.SetStringGID(FALSE); + } + + double dPlusOffset = 0; + double dPrevW = dOffsetX; + for (int i = 0; i < nCount; ++i) + { + double dW = m_oFontManager.MeasureString((const unsigned int*)(input + i), 1, 0, 0); + + NSWasm::CHChar* pChar = m_oLine.AddTail(); + pChar->unicode = pUnicodes[i]; + + pChar->x = dPrevW; + if (i) + dPlusOffset += dPrevW; + dPrevW = dW; + pChar->width = dW * dAbsVec; + + if (i == nCount - 1) + { + m_oLine.m_dEndX += dPlusOffset * m_oLine.m_ex; + m_oLine.m_dEndY += dPlusOffset * m_oLine.m_ey; + } + } + } + void DumpLine() + { + LONG nCount = m_oLine.GetCountChars(); + if (!nCount) + { + m_oLine.Clear(); + return; + } + + if (m_oLine.m_bIsSetUpTransform) + { + // выставится трансформ!!! + // cравнивать нужно с ним!!! + m_pLastTransform->SetElements(m_oLine.m_sx, m_oLine.m_shy, m_oLine.m_shx, m_oLine.m_sy); + } + + // скидываем линию в поток pMeta + m_pPageMeta->WriteDouble(m_oLine.m_dX); + m_pPageMeta->WriteDouble(m_oLine.m_dY); + + bool bHorizontal = false; + if (fabs(m_oLine.m_ex - 1.0) < 0.001 && fabs(m_oLine.m_ey) < 0.001) + bHorizontal = true; + m_pPageMeta->WriteBYTE(!bHorizontal ? 1 : 0); + if (!bHorizontal) + { + m_pPageMeta->WriteDouble(m_oLine.m_ex); + m_pPageMeta->WriteDouble(m_oLine.m_ey); + } + + m_pPageMeta->WriteDouble(m_oLine.m_dAscent); + m_pPageMeta->WriteDouble(m_oLine.m_dDescent); + + m_nCountParagraphs++; + + // width + LONG _position = m_pPageMeta->GetSize(); + m_pPageMeta->AddInt(0); + + double dWidthLine = 0; + double dCurrentGlyphLineOffset = 0; + m_pPageMeta->AddInt(nCount); + NSWasm::CHChar* pChar = NULL; + bool bIsLastSymbol = false; + for (LONG lIndexChar = 0; lIndexChar < nCount; ++lIndexChar) + { + pChar = &m_oLine.m_pChars[lIndexChar]; + + if (lIndexChar) + { + m_pPageMeta->WriteDouble(pChar->x); + dCurrentGlyphLineOffset += pChar->x; + } + + if (pChar->unicode == 0xFFFF || pChar->unicode == 32 || pChar->unicode == 9) + { + m_nCountSpaces++; + if (bIsLastSymbol) + { + bIsLastSymbol = false; + m_nCountWords++; + } + } + else + { + m_nCountSymbols++; + bIsLastSymbol = true; + } + + m_pPageMeta->AddInt(pChar->unicode); // юникодное значение + m_pPageMeta->WriteDouble(pChar->width); // ширина буквы + } + if (bIsLastSymbol) + m_nCountWords++; + + if (pChar) + dWidthLine = dCurrentGlyphLineOffset + pChar->width; + m_pPageMeta->AddInt((int)(dWidthLine * 10000.0), _position); + m_oLine.Clear(); + } + }; +} + +#endif // _ASC_HTMLRENDERER_TEXT_H_ diff --git a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp index 0f080a19b4c..19bb4b4e3fa 100644 --- a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp +++ b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp @@ -1,11 +1,7 @@ #include -#include -#include "../../../../pro/Graphics.h" #include "../../../../../common/Base64.h" -#include "../../../../../common/File.h" -#include "drawingfile.h" -#include "serialize.h" +#include "../../../../../doctrenderer/drawingfile.h" #ifdef _WIN32 #define WASM_EXPORT __declspec(dllexport) @@ -52,7 +48,7 @@ WASM_EXPORT void InitializeFontsRanges(BYTE* pDataSrc) } WASM_EXPORT void SetFontBinary(char* path, BYTE* data, int size) { - NSFonts::IFontsMemoryStorage* pStorage = NSFonts::NSApplicationFontStream::GetGlobalMemoryStorage(); + NSFonts::IFontsMemoryStorage* pStorage = CDrawingFile::GetFontsStorage(); if (pStorage) { std::string sPathA(path); @@ -61,7 +57,7 @@ WASM_EXPORT void SetFontBinary(char* path, BYTE* data, int size) } WASM_EXPORT int IsFontBinaryExist(char* path) { - NSFonts::IFontsMemoryStorage* pStorage = NSFonts::NSApplicationFontStream::GetGlobalMemoryStorage(); + NSFonts::IFontsMemoryStorage* pStorage = CDrawingFile::GetFontsStorage(); if (pStorage) { std::string sPathA(path); @@ -77,144 +73,126 @@ WASM_EXPORT int GetType(BYTE* data, LONG size) // 0 - PDF // 1 - DJVU // 2 - XPS - char* pFirst = strstr((char*)data, "%PDF-" ); - if (pFirst) - return 0; + LONG nHeaderSearchSize = 1024; + LONG nSize = size < nHeaderSearchSize ? size : nHeaderSearchSize; + char* pData = (char*)data; + for (int i = 0; i < nSize - 5; ++i) + { + int nPDF = strncmp(&pData[i], "%PDF-", 5); + if (!nPDF) + return 0; + } if ( (8 <= size) && (0x41 == data[0] && 0x54 == data[1] && 0x26 == data[2] && 0x54 == data[3] && 0x46 == data[4] && 0x4f == data[5] && 0x52 == data[6] && 0x4d == data[7])) return 1; return 2; } -WASM_EXPORT CGraphicsFileDrawing* Open(BYTE* data, LONG size, const char* password) +WASM_EXPORT CDrawingFile* Open(BYTE* data, LONG size, const char* password) { if (!g_applicationFonts) g_applicationFonts = NSFonts::NSApplication::Create(); // всегда пересоздаем сторадж - NSFonts::NSApplicationFontStream::SetGlobalMemoryStorage(NSFonts::NSApplicationFontStream::CreateDefaultGlobalMemoryStorage()); + CDrawingFile::InitFontsGlobalStorage(); - CGraphicsFileDrawing* pGraphics = new CGraphicsFileDrawing(g_applicationFonts); - pGraphics->Open(data, size, GetType(data, size), password); - return pGraphics; + CDrawingFile* pFile = new CDrawingFile(g_applicationFonts); + std::wstring sPassword = L""; + if (NULL != password) + sPassword = NSFile::CUtf8Converter::GetUnicodeStringFromUTF8((BYTE*)password, strlen(password)); + pFile->OpenFile(data, size, sPassword); + return pFile; } -WASM_EXPORT int GetErrorCode(CGraphicsFileDrawing* pGraphics) +WASM_EXPORT int GetErrorCode(CDrawingFile* pFile) { - if (!pGraphics) + if (!pFile) return -1; - return pGraphics->GetErrorCode(); + return pFile->GetErrorCode(); } -WASM_EXPORT void Close (CGraphicsFileDrawing* pGraphics) +WASM_EXPORT void Close(CDrawingFile* pFile) { - delete pGraphics; + delete pFile; NSFonts::NSApplicationFontStream::SetGlobalMemoryStorage(NULL); } -WASM_EXPORT BYTE* GetInfo (CGraphicsFileDrawing* pGraphics) +WASM_EXPORT BYTE* GetInfo(CDrawingFile* pFile) { - NSWasm::CData oRes; - oRes.SkipLen(); - - oRes.AddInt(pGraphics->GetMaxRefID()); - - int pages_count = pGraphics->GetPagesCount(); - oRes.AddInt(pages_count); - for (int page = 0; page < pages_count; ++page) - { - int nW = 0; - int nH = 0; - int nDpi = 0; - int nRotate = 0; - pGraphics->GetPageInfo(page, nW, nH, nDpi, nRotate); - oRes.AddInt(nW); - oRes.AddInt(nH); - oRes.AddInt(nDpi); - oRes.AddInt(nRotate); - } - std::wstring wsInfo = pGraphics->GetInfo(); - std::string sInfo = U_TO_UTF8(wsInfo); - oRes.WriteString((BYTE*)sInfo.c_str(), sInfo.length()); - - oRes.WriteLen(); - BYTE* bRes = oRes.GetBuffer(); - oRes.ClearWithoutAttack(); - return bRes; + return pFile->GetInfo(); } -WASM_EXPORT BYTE* GetPixmap (CGraphicsFileDrawing* pGraphics, int nPageIndex, int nRasterW, int nRasterH, int nBackgroundColor) +WASM_EXPORT BYTE* GetPixmap(CDrawingFile* pFile, int nPageIndex, int nRasterW, int nRasterH, int nBackgroundColor) { - return pGraphics->GetPage(nPageIndex, nRasterW, nRasterH, nBackgroundColor); + return pFile->GetPixmap(nPageIndex, nRasterW, nRasterH, nBackgroundColor); } -WASM_EXPORT BYTE* GetGlyphs (CGraphicsFileDrawing* pGraphics, int nPageIndex) +WASM_EXPORT BYTE* GetGlyphs(CDrawingFile* pFile, int nPageIndex) { - return pGraphics->GetGlyphs(nPageIndex); + return pFile->GetGlyphs(nPageIndex); } -WASM_EXPORT BYTE* GetLinks (CGraphicsFileDrawing* pGraphics, int nPageIndex) +WASM_EXPORT BYTE* GetLinks (CDrawingFile* pFile, int nPageIndex) { - return pGraphics->GetLinks(nPageIndex); + return pFile->GetLinks(nPageIndex); } -WASM_EXPORT BYTE* GetStructure(CGraphicsFileDrawing* pGraphics) +WASM_EXPORT BYTE* GetStructure(CDrawingFile* pFile) { - return pGraphics->GetStructure(); + return pFile->GetStructure(); } -WASM_EXPORT BYTE* GetInteractiveFormsInfo(CGraphicsFileDrawing* pGraphics) +WASM_EXPORT BYTE* GetInteractiveFormsInfo(CDrawingFile* pFile) { - return pGraphics->GetInteractiveFormsInfo(); + return pFile->GetInteractiveFormsInfo(); } -WASM_EXPORT BYTE* GetInteractiveFormsAP(CGraphicsFileDrawing* pGraphics, int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex, int nWidget, int nView, int nButtonView) +WASM_EXPORT BYTE* GetInteractiveFormsFonts(CDrawingFile* pFile, int nType) { - const char* sView = NULL; - if (nView == 0) - sView = "N"; - else if (nView == 1) - sView = "D"; - else if (nView == 2) - sView = "R"; - - const char* sButtonView = NULL; - if (nButtonView == 0) - sButtonView = "Off"; - else if (nButtonView == 1) - sButtonView = "Yes"; - - return pGraphics->GetAPWidget(nRasterW, nRasterH, nBackgroundColor, nPageIndex, nWidget, sView, sButtonView); + return pFile->GetInteractiveFormsFonts(nType); } -WASM_EXPORT BYTE* GetButtonIcons(CGraphicsFileDrawing* pGraphics, int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex, int bBase64, int nButtonWidget, int nIconView) +WASM_EXPORT BYTE* GetInteractiveFormsAP(CDrawingFile* pFile, int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex, int nWidget, int nView, int nButtonView) { - const char* sIconView = NULL; - if (nIconView == 0) - sIconView = "I"; - else if (nIconView == 1) - sIconView = "RI"; - else if (nIconView == 2) - sIconView = "IX"; - - return pGraphics->GetButtonIcon(nRasterW, nRasterH, nBackgroundColor, nPageIndex, bBase64 ? true : false, nButtonWidget, sIconView); + return pFile->GetInteractiveFormsAP(nRasterW, nRasterH, nBackgroundColor, nPageIndex, nWidget, nView, nButtonView); +} +WASM_EXPORT BYTE* GetButtonIcons(CDrawingFile* pFile, int nBackgroundColor, int nPageIndex, int bBase64, int nButtonWidget, int nIconView) +{ + return pFile->GetButtonIcons(nBackgroundColor, nPageIndex, bBase64 ? true : false, nButtonWidget, nIconView); } -WASM_EXPORT BYTE* GetAnnotationsInfo(CGraphicsFileDrawing* pGraphics, int nPageIndex) +WASM_EXPORT BYTE* GetAnnotationsInfo(CDrawingFile* pFile, int nPageIndex) { - return pGraphics->GetAnnots(nPageIndex); + return pFile->GetAnnotationsInfo(nPageIndex); } -WASM_EXPORT BYTE* GetAnnotationsAP(CGraphicsFileDrawing* pGraphics, int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex, int nAnnot, int nView) +WASM_EXPORT BYTE* GetAnnotationsAP(CDrawingFile* pFile, int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex, int nAnnot, int nView) { - const char* sView = NULL; - if (nView == 0) - sView = "N"; - else if (nView == 1) - sView = "D"; - else if (nView == 2) - sView = "R"; + return pFile->GetAnnotationsAP(nRasterW, nRasterH, nBackgroundColor, nPageIndex, nAnnot, nView); +} +WASM_EXPORT BYTE* GetFontBinary(CDrawingFile* pFile, char* path) +{ + return pFile->GetFontBinary(std::string(path)); +} +WASM_EXPORT void DestroyTextInfo(CDrawingFile* pFile) +{ + return pFile->DestroyTextInfo(); +} +WASM_EXPORT int IsNeedCMap(CDrawingFile* pFile) +{ + return pFile->IsNeedCMap() ? 1 : 0; +} +WASM_EXPORT void SetCMapData(CDrawingFile* pFile, BYTE* data, int size) +{ + pFile->SetCMapData(data, size); +} +WASM_EXPORT BYTE* ScanPage(CDrawingFile* pFile, int nPageIndex, int mode) +{ + return pFile->ScanPage(nPageIndex, mode); +} - return pGraphics->GetAPAnnots(nRasterW, nRasterH, nBackgroundColor, nPageIndex, nAnnot, sView); +WASM_EXPORT void* GetImageBase64(CDrawingFile* pFile, int rId) +{ + return pFile->GetImageBase64(rId); } -WASM_EXPORT void DestroyTextInfo(CGraphicsFileDrawing* pGraphics) +WASM_EXPORT int GetImageBase64Len(std::string* p) { - return pGraphics->DestroyText(); + return (int)p->length(); } -WASM_EXPORT int IsNeedCMap(CGraphicsFileDrawing* pGraphics) +WASM_EXPORT char* GetImageBase64Ptr(std::string* p) { - return pGraphics->IsNeedCMap() ? 1 : 0; + return (char*)p->c_str(); } -WASM_EXPORT void SetCMapData(CGraphicsFileDrawing* pGraphics, BYTE* data, int size) +WASM_EXPORT void GetImageBase64Free(std::string* p) { - pGraphics->SetCMapData(data, size); + *p = ""; } #ifdef __cplusplus diff --git a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.h b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.h deleted file mode 100644 index 86053b310fa..00000000000 --- a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.h +++ /dev/null @@ -1,172 +0,0 @@ -#ifndef _WASM_GRAPHICS_ -#define _WASM_GRAPHICS_ - -#include "../../../../GraphicsRenderer.h" -#include "../../../../pro/Graphics.h" -#include "../../../../pro/officedrawingfile.h" -#include "../../../../../../XpsFile/XpsFile.h" -#include "../../../../../../DjVuFile/DjVu.h" -#include "../../../../../../PdfFile/PdfFile.h" -#include "../../../../../../HtmlRenderer/include/HTMLRendererText.h" - -class CGraphicsFileDrawing -{ -private: - IOfficeDrawingFile* pReader; - NSFonts::IApplicationFonts* pApplicationFonts; - NSFonts::IFontManager* pFontManager; - NSHtmlRenderer::CHTMLRendererText* pTextRenderer; - int nType; -public: - CGraphicsFileDrawing(NSFonts::IApplicationFonts* pFonts) - { - pReader = NULL; - pTextRenderer = NULL; - pApplicationFonts = pFonts; - pApplicationFonts->AddRef(); - - pFontManager = pApplicationFonts->GenerateFontManager(); - NSFonts::IFontsCache* pFontCache = NSFonts::NSFontCache::Create(); - pFontCache->SetStreams(pApplicationFonts->GetStreams()); - pFontCache->SetCacheSize(8); - pFontManager->SetOwnerCache(pFontCache); - - nType = -1; - } - ~CGraphicsFileDrawing() - { - RELEASEOBJECT(pReader); - RELEASEOBJECT(pTextRenderer); - RELEASEOBJECT(pFontManager); - RELEASEINTERFACE(pApplicationFonts); - nType = -1; - } - bool Open(BYTE* data, DWORD length, int _nType, const char* password) - { - nType = _nType; - if (nType == 0) - pReader = new CPdfFile(pApplicationFonts); - else if (nType == 1) - pReader = new CDjVuFile(pApplicationFonts); - else if (nType == 2) - pReader = new CXpsFile(pApplicationFonts); - if (!pReader) - return false; - std::wstring sPassword = L""; - if (password) - { - std::string sPass(password); - sPassword = UTF8_TO_U(sPass); - } - return pReader->LoadFromMemory(data, length, L"", sPassword, sPassword); - } - int GetErrorCode() - { - if (!pReader) - return -1; - if (nType == 0) - // диапозон ошибки от 0 до 10 - return ((CPdfFile*)pReader)->GetError(); - return 0; // errNone - } - int GetPagesCount() - { - return pReader->GetPagesCount(); - } - int GetMaxRefID() - { - if (nType == 0) - return ((CPdfFile*)pReader)->GetMaxRefID(); - return 0; - } - void GetPageInfo(int nPageIndex, int& nWidth, int& nHeight, int& nPageDpiX, int& nRotate) - { - double dPageDpiX, dPageDpiY; - double dWidth, dHeight; - pReader->GetPageInfo(nPageIndex, &dWidth, &dHeight, &dPageDpiX, &dPageDpiY); - if (nType == 2) - { - dWidth = dWidth / 25.4 * 96.0; - dHeight = dHeight / 25.4 * 96.0; - dPageDpiX = dPageDpiX / 25.4 * 96.0; - } - if (nType == 0) - nRotate = ((CPdfFile*)pReader)->GetRotate(nPageIndex); - nWidth = dWidth; - nHeight = dHeight; - nPageDpiX = dPageDpiX; - } - BYTE* GetPage(int nPageIndex, int nRasterW, int nRasterH, int nBackgroundColor) - { - return pReader->ConvertToPixels(nPageIndex, nRasterW, nRasterH, true, pFontManager, nBackgroundColor, (nBackgroundColor == 0xFFFFFF) ? false : true); - } - BYTE* GetGlyphs(int nPageIndex) - { - if (NULL == pTextRenderer) - pTextRenderer = new NSHtmlRenderer::CHTMLRendererText(); - - pTextRenderer->Init(pReader, 8); - pReader->DrawPageOnRenderer(pTextRenderer, nPageIndex, NULL); - - return pTextRenderer->GetBuffer(); - } - BYTE* GetLinks(int nPageIndex) - { - return pReader->GetLinks(nPageIndex); - } - BYTE* GetStructure() - { - return pReader->GetStructure(); - } - BYTE* GetInteractiveFormsInfo() - { - if (nType == 0) - return ((CPdfFile*)pReader)->GetWidgets(); - return NULL; - } - BYTE* GetAnnots(int nPageIndex = -1) - { - if (nType == 0) - return ((CPdfFile*)pReader)->GetAnnots(nPageIndex); - return NULL; - } - BYTE* GetAPWidget(int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex, int nWidget = -1, const char* sView = NULL, const char* sButtonView = NULL) - { - if (nType == 0) - return ((CPdfFile*)pReader)->GetAPWidget(nRasterW, nRasterH, nBackgroundColor, nPageIndex, nWidget, sView, sButtonView); - return NULL; - } - BYTE* GetButtonIcon(int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex, bool bBase64 = false, int nButtonWidget = -1, const char* sIconView = NULL) - { - if (nType == 0) - return ((CPdfFile*)pReader)->GetButtonIcon(nRasterW, nRasterH, nBackgroundColor, nPageIndex, bBase64, nButtonWidget, sIconView); - return NULL; - } - BYTE* GetAPAnnots(int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex, int nAnnot = -1, const char* sView = NULL) - { - if (nType == 0) - return ((CPdfFile*)pReader)->GetAPAnnots(nRasterW, nRasterH, nBackgroundColor, nPageIndex, nAnnot, sView); - return NULL; - } - std::wstring GetInfo() - { - return pReader->GetInfo(); - } - bool IsNeedCMap() - { - if (nType == 0) - return ((CPdfFile*)pReader)->IsNeedCMap(); - return false; - } - void SetCMapData(BYTE* pData, DWORD nSizeData) - { - if (nType == 0) - ((CPdfFile*)pReader)->SetCMapMemory(pData, nSizeData); - } - void DestroyText() - { - RELEASEOBJECT(pTextRenderer); - } -}; - -#endif // _WASM_GRAPHICS_ diff --git a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp index fdf70ffc359..e36f48cd533 100644 --- a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp +++ b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp @@ -1,9 +1,19 @@ +#include + +#include "../../../../raster/BgraFrame.h" +#include "../../../../raster/ImageFileFormatChecker.h" +#include "../../../../../common/File.h" +#include "../../../../../common/StringBuilder.h" #include "drawingfile.cpp" unsigned char READ_BYTE(BYTE* x) { return x ? x[0] : 1; } +unsigned short READ_SHORT(BYTE* x) +{ + return x ? (x[0] | x[1] << 8) : 2; +} unsigned int READ_INT(BYTE* x) { return x ? (x[0] | x[1] << 8 | x[2] << 16 | x[3] << 24) : 4; @@ -220,7 +230,7 @@ void ReadAnnot(BYTE* pWidgets, int& i) { nPathLength = READ_INT(pWidgets + i); i += 4; - std::cout << (double)nPathLength / 100.0 << " "; + std::cout << (double)nPathLength / 10000.0 << " "; } std::cout << ", "; } @@ -237,13 +247,17 @@ void ReadAnnot(BYTE* pWidgets, int& i) if (nBorderType == 2) { - nPathLength = READ_INT(pWidgets + i); + int nDash = READ_INT(pWidgets + i); i += 4; - std::cout << "Dash Pattern " << (double)nPathLength / 100.0 << " "; + std::cout << "Dash Pattern"; - nPathLength = READ_INT(pWidgets + i); - i += 4; - std::cout << (double)nPathLength / 100.0 << ", "; + for (int j = 0; j < nDash; ++j) + { + nPathLength = READ_INT(pWidgets + i); + i += 4; + std::cout << " " << (double)nPathLength / 100.0; + } + std::cout << ", "; } } if (nFlags & (1 << 5)) @@ -257,6 +271,13 @@ void ReadAnnot(BYTE* pWidgets, int& i) std::cout << "YES AP, "; else std::cout << "NO AP, "; + if (nFlags & (1 << 7)) + { + nPathLength = READ_INT(pWidgets + i); + i += 4; + std::cout << "User ID " << std::string((char*)(pWidgets + i), nPathLength) << ", "; + i += nPathLength; + } } void ReadInteractiveForms(BYTE* pWidgets, int& i) @@ -265,17 +286,16 @@ void ReadInteractiveForms(BYTE* pWidgets, int& i) i += 4; if (nCOLength > 0) std::cout << "CO "; - for (DWORD j = 0; j < nCOLength; ++j) + for (int j = 0; j < nCOLength; ++j) { int nPathLength = READ_INT(pWidgets + i); i += 4; - std::cout << std::string((char*)(pWidgets + i), nPathLength) << ", "; - i += nPathLength; + std::cout << nPathLength << ", "; } if (nCOLength > 0) std::cout << std::endl; - // Parents + // Parents int nParentsLength = READ_INT(pWidgets + i); i += 4; @@ -314,11 +334,55 @@ void ReadInteractiveForms(BYTE* pWidgets, int& i) i += nPathLength; } if (nFlags & (1 << 3)) + { + int nILength = READ_INT(pWidgets + i); + i += 4; + std::cout << "I"; + + for (int j = 0; j < nILength; ++j) + { + nPathLength = READ_INT(pWidgets + i); + i += 4; + std::cout << " " << nPathLength; + } + std::cout << ", "; + } + if (nFlags & (1 << 4)) { nPathLength = READ_INT(pWidgets + i); i += 4; std::cout << "Parent " << nPathLength; } + if (nFlags & (1 << 5)) + { + int nILength = READ_INT(pWidgets + i); + i += 4; + std::cout << "V"; + + for (int j = 0; j < nILength; ++j) + { + nPathLength = READ_INT(pWidgets + i); + i += 4; + std::cout << " " << std::string((char*)(pWidgets + i), nPathLength); + i += nPathLength; + } + std::cout << ", "; + } + if (nFlags & (1 << 6)) + { + int nILength = READ_INT(pWidgets + i); + i += 4; + std::cout << "Opt ["; + + for (int j = 0; j < nILength; ++j) + { + nPathLength = READ_INT(pWidgets + i); + i += 4; + std::cout << " " << std::string((char*)(pWidgets + i), nPathLength); + i += nPathLength; + } + std::cout << " ], "; + } std::cout << std::endl; } @@ -335,24 +399,38 @@ void ReadInteractiveForms(BYTE* pWidgets, int& i) std::string sType = arrAnnots[nPathLength]; std::cout << "Widget type " << sType << ", "; - // Annot + // Annot ReadAnnot(pWidgets, i); - // Widget + // Widget + + nPathLength = READ_INT(pWidgets + i); + i += 4; + std::cout << "Font: name " << std::string((char*)(pWidgets + i), nPathLength) << ", "; + i += nPathLength; + + nPathLength = READ_INT(pWidgets + i); + i += 4; + std::cout << "size " << (double)nPathLength / 100.0 << ", "; + + nPathLength = READ_INT(pWidgets + i); + i += 4; + std::cout << "style " << nPathLength << ", "; int nTCLength = READ_INT(pWidgets + i); i += 4; if (nTCLength) - std::cout << "Text Color: "; - for (int j = 0; j < nTCLength; ++j) { - nPathLength = READ_INT(pWidgets + i); - i += 4; - std::cout << (double)nPathLength / 100.0 << " "; - } - if (nTCLength) + std::cout << "color"; + for (int j = 0; j < nTCLength; ++j) + { + nPathLength = READ_INT(pWidgets + i); + i += 4; + std::cout << " " << (double)nPathLength / 10000.0; + } std::cout << ", "; + } std::string arrQ[] = {"left-justified", "centered", "right-justified"}; nPathLength = READ_BYTE(pWidgets + i); @@ -382,6 +460,13 @@ void ReadInteractiveForms(BYTE* pWidgets, int& i) std::cout << "DS " << std::string((char*)(pWidgets + i), nPathLength) << ", "; i += nPathLength; } + if (nFlags & (1 << 2)) + { + nPathLength = READ_INT(pWidgets + i); + i += 4; + std::cout << "Actual font " << std::string((char*)(pWidgets + i), nPathLength) << ", "; + i += nPathLength; + } if (nFlags & (1 << 3)) { std::string arrHighlighting[] = {"none", "invert", "push", "outline"}; @@ -389,6 +474,13 @@ void ReadInteractiveForms(BYTE* pWidgets, int& i) i += 1; std::cout << "Highlight " << arrHighlighting[nPathLength] << ", "; } + if (nFlags & (1 << 4)) + { + nPathLength = READ_INT(pWidgets + i); + i += 4; + std::cout << "Font key " << std::string((char*)(pWidgets + i), nPathLength) << ", "; + i += nPathLength; + } if (nFlags & (1 << 5)) { int nBCLength = READ_INT(pWidgets + i); @@ -399,7 +491,7 @@ void ReadInteractiveForms(BYTE* pWidgets, int& i) { nPathLength = READ_INT(pWidgets + i); i += 4; - std::cout << (double)nPathLength / 100.0 << " "; + std::cout << (double)nPathLength / 10000.0 << " "; } std::cout << ", "; } @@ -419,7 +511,7 @@ void ReadInteractiveForms(BYTE* pWidgets, int& i) { nPathLength = READ_INT(pWidgets + i); i += 4; - std::cout << (double)nPathLength / 100.0 << " "; + std::cout << (double)nPathLength / 10000.0 << " "; } std::cout << ", "; } @@ -443,8 +535,15 @@ void ReadInteractiveForms(BYTE* pWidgets, int& i) std::cout << "Name " << std::string((char*)(pWidgets + i), nPathLength) << ", "; i += nPathLength; } + if (nFlags & (1 << 19)) + { + nPathLength = READ_INT(pWidgets + i); + i += 4; + std::cout << "Font button " << std::string((char*)(pWidgets + i), nPathLength) << ", "; + i += nPathLength; + } - //Action + //Action int nActLength = READ_INT(pWidgets + i); i += 4; @@ -460,45 +559,41 @@ void ReadInteractiveForms(BYTE* pWidgets, int& i) } std::cout << std::endl; - // Widget types + // Widget types - if (sType == "checkbox" || sType == "radiobutton" || sType == "button") + if (sType == "button") { - std::cout << (nFlags & (1 << 9) ? "Yes" : "Off") << ", "; + if (nFlags & (1 << 9)) + { + nPathLength = READ_INT(pWidgets + i); + i += 4; + std::cout << "Value " << std::string((char*)(pWidgets + i), nPathLength) << ", "; + i += nPathLength; + } int nIFFlag = READ_INT(pWidgets + i); i += 4; - if (sType == "button") + if (nFlags & (1 << 10)) { - if (nFlags & (1 << 10)) - { - nPathLength = READ_INT(pWidgets + i); - i += 4; - std::cout << "CA " << std::string((char*)(pWidgets + i), nPathLength) << ", "; - i += nPathLength; - } - if (nFlags & (1 << 11)) - { - nPathLength = READ_INT(pWidgets + i); - i += 4; - std::cout << "RC " << std::string((char*)(pWidgets + i), nPathLength) << ", "; - i += nPathLength; - } - if (nFlags & (1 << 12)) - { - nPathLength = READ_INT(pWidgets + i); - i += 4; - std::cout << "AC " << std::string((char*)(pWidgets + i), nPathLength) << ", "; - i += nPathLength; - } + nPathLength = READ_INT(pWidgets + i); + i += 4; + std::cout << "CA " << std::string((char*)(pWidgets + i), nPathLength) << ", "; + i += nPathLength; } - else + if (nFlags & (1 << 11)) { - std::string arrStyle[] = {"check", "cross", "diamond", "circle", "star", "square"}; - nPathLength = READ_BYTE(pWidgets + i); - i += 1; - std::cout << "Style " << arrStyle[nPathLength] << ", "; + nPathLength = READ_INT(pWidgets + i); + i += 4; + std::cout << "RC " << std::string((char*)(pWidgets + i), nPathLength) << ", "; + i += nPathLength; + } + if (nFlags & (1 << 12)) + { + nPathLength = READ_INT(pWidgets + i); + i += 4; + std::cout << "AC " << std::string((char*)(pWidgets + i), nPathLength) << ", "; + i += nPathLength; } if (nFlags & (1 << 13)) { @@ -535,6 +630,22 @@ void ReadInteractiveForms(BYTE* pWidgets, int& i) } std::cout << "FB " << (nIFFlag & (1 << 4)) << ", "; } + } + else if (sType == "checkbox" || sType == "radiobutton") + { + if (nFlags & (1 << 9)) + { + nPathLength = READ_INT(pWidgets + i); + i += 4; + std::cout << "Value " << std::string((char*)(pWidgets + i), nPathLength) << ", "; + i += nPathLength; + } + + std::string arrStyle[] = {"check", "cross", "diamond", "circle", "star", "square"}; + nPathLength = READ_BYTE(pWidgets + i); + i += 1; + std::cout << "Style " << arrStyle[nPathLength] << ", "; + if (nFlags & (1 << 14)) { nPathLength = READ_INT(pWidgets + i); @@ -598,13 +709,40 @@ void ReadInteractiveForms(BYTE* pWidgets, int& i) i += 4; std::cout << "TI " << nPathLength << ", "; } + if (nFlags & (1 << 12)) + { + int nILength = READ_INT(pWidgets + i); + i += 4; + std::cout << "I"; + for (int j = 0; j < nILength; ++j) + { + nPathLength = READ_INT(pWidgets + i); + i += 4; + std::cout << " " << nPathLength; + } + std::cout << ", "; + } + if (nFlags & (1 << 13)) + { + int nILength = READ_INT(pWidgets + i); + i += 4; + std::cout << "Value"; + for (int j = 0; j < nILength; ++j) + { + nPathLength = READ_INT(pWidgets + i); + i += 4; + std::cout << " " << std::string((char*)(pWidgets + i), nPathLength); + i += nPathLength; + } + std::cout << ", "; + } } else if (sType == "signature") { if (nFlags & (1 << 9)) std::cout << "SIG, "; } - std::cout << std::endl; + std::cout << std::endl << std::endl; } } @@ -616,11 +754,11 @@ void ReadAnnotAP(BYTE* pWidgetsAP, int& i) int nPathLength = READ_INT(pWidgetsAP + i); i += 4; - std::cout << "X " << nPathLength << ", "; + std::cout << "X " << (double)nPathLength / 100.0 << ", "; nPathLength = READ_INT(pWidgetsAP + i); i += 4; - std::cout << "Y " << nPathLength << ", "; + std::cout << "Y " << (double)nPathLength / 100.0 << ", "; int nWidgetWidth = READ_INT(pWidgetsAP + i); i += 4; @@ -632,10 +770,11 @@ void ReadAnnotAP(BYTE* pWidgetsAP, int& i) int nAPLength = READ_INT(pWidgetsAP + i); i += 4; + if (nAPLength > 0) + std::cout << "APName "; for (int j = 0; j < nAPLength; ++j) { - std::cout << std::endl; nPathLength = READ_INT(pWidgetsAP + i); i += 4; std::string sAPName = std::string((char*)(pWidgetsAP + i), nPathLength); @@ -646,7 +785,7 @@ void ReadAnnotAP(BYTE* pWidgetsAP, int& i) sAPName += nPathLength ? ("." + std::string((char*)(pWidgetsAP + i), nPathLength)) : ""; i += nPathLength; - std::cout << "APName " << sAPName << ", "; + std::cout << sAPName << ", "; unsigned long long npBgraData1 = READ_INT(pWidgetsAP + i); i += 4; unsigned long long npBgraData2 = READ_INT(pWidgetsAP + i); @@ -663,26 +802,92 @@ void ReadAnnotAP(BYTE* pWidgetsAP, int& i) oFrame.ClearNoAttack(); RELEASEARRAYOBJECTS(res); - int nTextSize = READ_INT(pWidgetsAP + i); + nPathLength = READ_BYTE(pWidgetsAP + i); + i += 1; + std::string arrBlendMode[] = { "Normal", "Multiply", "Screen", "Overlay", "Darken", "Lighten", "ColorDodge", "ColorBurn", "HardLight", + "SoftLight", "Difference", "Exclusion", "Hue", "Saturation", "Color", "Luminosity" }; + std::cout << "Type " << arrBlendMode[nPathLength] << ", "; + } + std::cout << std::endl; +} + +void ReadFileAttachment(BYTE* pAnnots, int& i, int n) +{ + std::cout << "EF FileAttachment" << n << ".txt, "; + int nFileLength = READ_INT(pAnnots + i); + i += 4; + + unsigned long long npFile1 = READ_INT(pAnnots + i); + i += 4; + unsigned long long npFile2 = READ_INT(pAnnots + i); + i += 4; + + BYTE* res = (BYTE*)(npFile2 << 32 | npFile1); + + NSFile::CFileBinary oFile; + if (oFile.CreateFileW(NSFile::GetProcessDirectory() + L"/FileAttachment" + std::to_wstring(n) + L".txt")) + oFile.WriteFile(res, nFileLength); + oFile.CloseFile(); + + RELEASEARRAYOBJECTS(res); +} + +void ReadInteractiveFormsFonts(CDrawingFile* pGrFile, int nType) +{ + BYTE* pFonts = GetInteractiveFormsFonts(pGrFile, nType); + int nLength = READ_INT(pFonts); + int i = 4; + nLength -= 4; + + while (i < nLength) + { + int nFontsLength = READ_INT(pFonts + i); i += 4; - for (int k = 0; k < nTextSize; ++k) + std::cout << "Fonts"; + + for (int j = 0; j < nFontsLength; ++j) { - nPathLength = READ_INT(pWidgetsAP + i); - i += 4; - std::cout << k << " Text " << std::string((char*)(pWidgetsAP + i), nPathLength) << ", "; - i += nPathLength; + std::cout << std::endl; - nPathLength = READ_INT(pWidgetsAP + i); + int nPathLength = READ_INT(pFonts + i); i += 4; - std::cout << "Font " << std::string((char*)(pWidgetsAP + i), nPathLength) << ", "; + std::string sFontName = std::string((char*)(pFonts + i), nPathLength); + std::cout << " " << sFontName << " "; i += nPathLength; - nPathLength = READ_INT(pWidgetsAP + i); - i += 4; - std::cout << "Size " << (double)nPathLength / 100.0 << ", "; + BYTE* pFont = GetFontBinary(pGrFile, (char*)sFontName.c_str()); + int nLength2 = READ_INT(pFont); + int i2 = 4; + nLength2 -= 4; + + while (i2 < nLength2) + { + int nFontLength = READ_INT(pFont + i2); + i2 += 4; + + unsigned long long npFont1 = READ_INT(pFont + i2); + i2 += 4; + unsigned long long npFont2 = READ_INT(pFont + i2); + i2 += 4; + + BYTE* res = (BYTE*)(npFont2 << 32 | npFont1); + + NSFile::CFileBinary oFile; + if (oFile.CreateFileW(NSFile::GetProcessDirectory() + L"/font" + std::to_wstring(j) + L".txt")) + oFile.WriteFile(res, nFontLength); + oFile.CloseFile(); + + std::cout << "font" << j << ".txt"; + } + + if (pFont) + free(pFont); } + std::cout << std::endl; } - std::cout << std::endl; + + if (pFonts) + free(pFonts); } #include "../../../../../fontengine/ApplicationFontsWorker.h" @@ -690,8 +895,7 @@ void ReadAnnotAP(BYTE* pWidgetsAP, int& i) int main(int argc, char* argv[]) { - - // CHECK SYSTEM FONTS + // CHECK SYSTEM FONTS CApplicationFontsWorker oWorker; oWorker.m_sDirectory = NSFile::GetProcessDirectory() + L"/fonts_cache"; //oWorker.m_arAdditionalFolders.push_back(L"D:\\GIT\\core-fonts"); @@ -704,7 +908,7 @@ int main(int argc, char* argv[]) RELEASEINTERFACE(pFonts); } - // INITIALIZE FONTS + // INITIALIZE FONTS if (true) { BYTE* pFontSelection = NULL; @@ -722,7 +926,7 @@ int main(int argc, char* argv[]) RELEASEARRAYOBJECTS(pFontSelection); } - // OPEN FILE + // OPEN FILE std::wstring sFilePath = NSFile::GetProcessDirectory() + L"/test.pdf"; BYTE* pFileData = NULL; @@ -730,7 +934,7 @@ int main(int argc, char* argv[]) if (!NSFile::CFileBinary::ReadAllBytes(sFilePath, &pFileData, nFileDataLen)) return 1; - CGraphicsFileDrawing* pGrFile = Open(pFileData, (LONG)nFileDataLen, ""); + CDrawingFile* pGrFile = Open(pFileData, (LONG)nFileDataLen, ""); int nError = GetErrorCode(pGrFile); if (nError != 0) @@ -748,7 +952,7 @@ int main(int argc, char* argv[]) } } - // INFO + // INFO BYTE* pInfo = GetInfo(pGrFile); int nLength = READ_INT(pInfo); nLength -= 4; @@ -774,13 +978,11 @@ int main(int argc, char* argv[]) std::cout << " Page " << nTestPage << " width " << nWidth << " height " << nHeight << " dpi " << dpi << " rotate " << rotate << std::endl; nLength = READ_INT(pInfo + nPagesCount * 16 + 12); - std::cout << "json "<< std::string((char*)(pInfo + nPagesCount * 16 + 16), nLength) << std::endl;; + std::cout << "json "<< std::string((char*)(pInfo + nPagesCount * 16 + 16), nLength) << std::endl << std::endl; } } - free(pInfo); - - // CMAP + // CMAP BYTE* pCMapData = NULL; if (IsNeedCMap(pGrFile)) { @@ -791,25 +993,37 @@ int main(int argc, char* argv[]) } } - // RASTER - if (true && nPagesCount > 0) + int i = nTestPage; + //for (int i = 0; i < nPagesCount; ++i) { - BYTE* res = NULL; - res = GetPixmap(pGrFile, nTestPage, nWidth, nHeight, 0xFFFFFF); + // RASTER + if (true) + { + nWidth = READ_INT(pInfo + i * 16 + 12); + nHeight = READ_INT(pInfo + i * 16 + 16); - CBgraFrame oFrame; - oFrame.put_Data(res); - oFrame.put_Width(nWidth); - oFrame.put_Height(nHeight); - oFrame.put_Stride(4 * nWidth); - oFrame.put_IsRGBA(true); - oFrame.SaveFile(NSFile::GetProcessDirectory() + L"/res.png", _CXIMAGE_FORMAT_PNG); - oFrame.ClearNoAttack(); + //nWidth *= 3; + //nHeight *= 3; - RELEASEARRAYOBJECTS(res); + BYTE* res = NULL; + res = GetPixmap(pGrFile, i, nWidth, nHeight, 0xFFFFFF); + + CBgraFrame oFrame; + oFrame.put_Data(res); + oFrame.put_Width(nWidth); + oFrame.put_Height(nHeight); + oFrame.put_Stride(4 * nWidth); + oFrame.put_IsRGBA(true); + oFrame.SaveFile(NSFile::GetProcessDirectory() + L"/res/res" + std::to_wstring(i) + L".png", _CXIMAGE_FORMAT_PNG); + oFrame.ClearNoAttack(); + + RELEASEARRAYOBJECTS(res); + } } - // LINKS + free(pInfo); + + // LINKS if (false && nPagesCount > 0) { BYTE* pLinks = GetLinks(pGrFile, nTestPage); @@ -845,7 +1059,7 @@ int main(int argc, char* argv[]) free(pLinks); } - // STRUCTURE + // STRUCTURE if (false) { BYTE* pStructure = GetStructure(pGrFile); @@ -875,17 +1089,88 @@ int main(int argc, char* argv[]) free(pStructure); } - // GLYPHS - if (false && nPagesCount > 0) + // GLYPHS + if (true && nPagesCount > 0) { - // TODO: BYTE* pGlyphs = GetGlyphs(pGrFile, nTestPage); + nLength = READ_INT(pGlyphs); + int i = 4; + nLength -= 20; + + int nPathLength = READ_INT(pGlyphs + i); + i += 4; + std::cout << "Stats Paragraphs " << nPathLength; + nPathLength = READ_INT(pGlyphs + i); + i += 4; + std::cout << " Words " << nPathLength; + nPathLength = READ_INT(pGlyphs + i); + i += 4; + std::cout << " Symbols " << nPathLength; + nPathLength = READ_INT(pGlyphs + i); + i += 4; + std::cout << " Spaces " << nPathLength << std::endl; + + while (i < nLength) + { + int nPathLength = READ_INT(pGlyphs + i); + i += 4; + std::cout << "Line X " << (double)nPathLength / 10000.0; + nPathLength = READ_INT(pGlyphs + i); + i += 4; + std::cout << " Y " << (double)nPathLength / 10000.0; + nPathLength = READ_BYTE(pGlyphs + i); + i += 1; + if (nPathLength) + { + nPathLength = READ_INT(pGlyphs + i); + i += 4; + std::cout << " Ex " << (double)nPathLength / 10000.0; + nPathLength = READ_INT(pGlyphs + i); + i += 4; + std::cout << " Ey " << (double)nPathLength / 10000.0; + } + nPathLength = READ_INT(pGlyphs + i); + i += 4; + std::cout << " Ascent " << (double)nPathLength / 10000.0; + nPathLength = READ_INT(pGlyphs + i); + i += 4; + std::cout << " Descent " << (double)nPathLength / 10000.0; + nPathLength = READ_INT(pGlyphs + i); + i += 4; + std::cout << " LineWidth " << (double)nPathLength / 10000.0; + int nCharLength = READ_INT(pGlyphs + i); + i += 4; + std::cout << " Chars:" << std::endl; + for (int j = 0; j < nCharLength; ++j) + { + int nCharX = 0; + if (j) + { + nCharX = READ_INT(pGlyphs + i); + i += 4; + } + nPathLength = READ_INT(pGlyphs + i); + i += 4; + std::cout << " Unicode " << nPathLength; + nPathLength = READ_INT(pGlyphs + i); + i += 4; + std::cout << " width " << (double)nPathLength / 10000.0; + if (nCharX) + std::cout << " charX " << (double)nCharX / 10000.0; + std::cout << std::endl; + } + } + DestroyTextInfo(pGrFile); } - // INTERACTIVE FORMS - if (true) + // INTERACTIVE FORMS + if (false) { + ReadInteractiveFormsFonts(pGrFile, 1); + ReadInteractiveFormsFonts(pGrFile, 2); + std::cout << std::endl; + BYTE* pWidgets = GetInteractiveFormsInfo(pGrFile); nLength = READ_INT(pWidgets); int i = 4; @@ -911,7 +1196,7 @@ int main(int argc, char* argv[]) free(pWidgetsAP); int bBase64 = 1; - BYTE* pWidgetsMK = GetButtonIcons(pGrFile, nWidth, nHeight, 0xFFFFFF, nTestPage, bBase64, -1, -1); + BYTE* pWidgetsMK = GetButtonIcons(pGrFile, 0xFFFFFF, nTestPage, bBase64, -1, -1); nLength = READ_INT(pWidgetsMK); i = 4; nLength -= 4; @@ -946,6 +1231,7 @@ int main(int argc, char* argv[]) int nWidgetHeight = READ_INT(pWidgetsMK + i); i += 4; std::cout << "H " << nWidgetHeight << ", "; + if (bBase64) { nPathLength = READ_INT(pWidgetsMK + i); @@ -993,7 +1279,7 @@ int main(int argc, char* argv[]) free(pWidgetsMK); } - // ANNOTS + // ANNOTS if (true) { BYTE* pAnnots = GetAnnotationsInfo(pGrFile, -1); @@ -1012,7 +1298,7 @@ int main(int argc, char* argv[]) ReadAnnot(pAnnots, i); - // Markup + // Markup DWORD nFlags = 0; if ((nPathLength < 18 && nPathLength != 1 && nPathLength != 15) || nPathLength == 25) @@ -1040,11 +1326,84 @@ int main(int argc, char* argv[]) std::cout << "CA " << (double)nPathLength / 100.0 << ", "; } if (nFlags & (1 << 3)) - { - nPathLength = READ_INT(pAnnots + i); + { + std::cout << "RC {"; + + int nFontLength = READ_INT(pAnnots + i); i += 4; - std::cout << "RC " << std::string((char*)(pAnnots + i), nPathLength) << ", "; - i += nPathLength; + for (int j = 0; j < nFontLength; ++j) + { + std::cout << std::endl << "span" << j << " { "; + + nPathLength = READ_BYTE(pAnnots + i); + i += 1; + std::string arrTextAlign[] = {"Left", "Center", "Right", "Justify"}; + std::cout << "text-align: " << arrTextAlign[nPathLength]; + + std::cout << "; font-style:"; + int nFontFlag = READ_INT(pAnnots + i); + i += 4; + if (nFontFlag & (1 << 0)) + std::cout << "Bold "; + if (nFontFlag & (1 << 1)) + std::cout << "Italic "; + if (nFontFlag & (1 << 3)) + std::cout << "Strike "; + if (nFontFlag & (1 << 4)) + std::cout << "Underline "; + if (nFontFlag & (1 << 5)) + { + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::cout << "; vertical-align:" << (double)nPathLength / 100.0; + } + if (nFontFlag & (1 << 6)) + { + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::cout << "; font-actual:" << std::string((char*)(pAnnots + i), nPathLength) << "; "; + i += nPathLength; + } + + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::cout << "; font-size:" << (double)nPathLength / 100.0; + + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::cout << "; font-color:" << (double)nPathLength / 10000.0 << " "; + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::cout << (double)nPathLength / 10000.0 << " "; + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::cout << (double)nPathLength / 10000.0 << "; "; + + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::string sFontName((char*)(pAnnots + i), nPathLength); + std::cout << "font-family:" << sFontName << "; "; + i += nPathLength; + + BYTE* pFont = GetFontBinary(pGrFile, (char*)sFontName.c_str()); + if (pFont) + { + std::cout << "FIND; "; + free(pFont); + } + else + std::cout << "NO; "; + + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::string sText = std::string((char*)(pAnnots + i), nPathLength); + NSStringUtils::string_replaceA(sText, "\r", "\n"); + std::cout << "text:" << sText << " "; + i += nPathLength; + + std::cout << "} "; + } + std::cout << "}, " << std::endl; } if (nFlags & (1 << 4)) { @@ -1134,7 +1493,7 @@ int main(int argc, char* argv[]) { nPathLength = READ_INT(pAnnots + i); i += 4; - std::cout << " " << (double)nPathLength / 100.0; + std::cout << " " << (double)nPathLength / 10000.0; } std::cout << ", "; } @@ -1249,7 +1608,7 @@ int main(int argc, char* argv[]) { nPathLength = READ_INT(pAnnots + i); i += 4; - std::cout << (double)nPathLength / 100.0 << " "; + std::cout << (double)nPathLength / 10000.0 << " "; } std::cout << ", "; } @@ -1291,7 +1650,7 @@ int main(int argc, char* argv[]) { nPathLength = READ_INT(pAnnots + i); i += 4; - std::cout << " " << (double)nPathLength / 100.0; + std::cout << " " << (double)nPathLength / 10000.0; } std::cout << ", "; } @@ -1325,6 +1684,10 @@ int main(int argc, char* argv[]) i += 1; std::cout << "Q " << arrQ[nPathLength] << ", "; + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::cout << "Rotate " << nPathLength << ", "; + if (nFlags & (1 << 15)) { std::cout << "RD"; @@ -1371,6 +1734,20 @@ int main(int argc, char* argv[]) std::string arrIT[] = {"FreeText", "FreeTextCallout", "FreeTextTypeWriter"}; std::cout << "IT " << arrIT[nPathLength] << ", "; } + if (nFlags & (1 << 21)) + { + int nCLLength = READ_INT(pAnnots + i); + i += 4; + std::cout << "C from DA:"; + + for (int j = 0; j < nCLLength; ++j) + { + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::cout << " " << (double)nPathLength / 10000.0; + } + std::cout << ", "; + } } else if (sType == "Caret") { @@ -1393,8 +1770,142 @@ int main(int argc, char* argv[]) std::cout << "Sy " << arrSy[nPathLength] << ", "; } } + else if (sType == "FileAttachment") + { + if (nFlags & (1 << 15)) + { + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::cout << "Name " << std::string((char*)(pAnnots + i), nPathLength) << ", "; + i += nPathLength; + } + if (nFlags & (1 << 16)) + { + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::cout << "FS " << std::string((char*)(pAnnots + i), nPathLength) << ", "; + i += nPathLength; + } + if (nFlags & (1 << 17)) + { + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::cout << "F " << std::string((char*)(pAnnots + i), nPathLength) << ", "; + i += nPathLength; + } + if (nFlags & (1 << 18)) + { + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::cout << "UF " << std::string((char*)(pAnnots + i), nPathLength) << ", "; + i += nPathLength; + } + if (nFlags & (1 << 19)) + { + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::cout << "DOS " << std::string((char*)(pAnnots + i), nPathLength) << ", "; + i += nPathLength; + } + if (nFlags & (1 << 20)) + { + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::cout << "Mac " << std::string((char*)(pAnnots + i), nPathLength) << ", "; + i += nPathLength; + } + if (nFlags & (1 << 21)) + { + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::cout << "Unix " << std::string((char*)(pAnnots + i), nPathLength) << ", "; + i += nPathLength; + } + if (nFlags & (1 << 22)) + { + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::cout << "ID " << std::string((char*)(pAnnots + i), nPathLength); + i += nPathLength; - std::cout << std::endl; + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::cout << " " << std::string((char*)(pAnnots + i), nPathLength) << ", "; + i += nPathLength; + } + if (nFlags & (1 << 23)) + std::cout << "V true, "; + else + std::cout << "V false, "; + if (nFlags & (1 << 24)) + { + int nFlag = READ_INT(pAnnots + i); + i += 4; + + if (nFlag & (1 << 0)) + ReadFileAttachment(pAnnots, i, 0); + if (nFlag & (1 << 1)) + ReadFileAttachment(pAnnots, i, 1); + if (nFlag & (1 << 2)) + ReadFileAttachment(pAnnots, i, 2); + if (nFlag & (1 << 3)) + ReadFileAttachment(pAnnots, i, 3); + if (nFlag & (1 << 4)) + ReadFileAttachment(pAnnots, i, 4); + } + if (nFlags & (1 << 26)) + { + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::cout << "Desc " << std::string((char*)(pAnnots + i), nPathLength) << ", "; + i += nPathLength; + } + } + else if (sType == "Stamp") + { + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::cout << "Icon " << std::string((char*)(pAnnots + i), nPathLength) << ", "; + i += nPathLength; + + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::cout << "Rotate " << nPathLength / 10000.0 << ", "; + + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::cout << "X1 " << (double)nPathLength / 10000.0 << ", "; + + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::cout << "Y1 " << (double)nPathLength / 10000.0 << ", "; + + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::cout << "X2 " << (double)nPathLength / 10000.0 << ", "; + + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::cout << "Y2 " << (double)nPathLength / 10000.0 << ", "; + + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::cout << "X3 " << (double)nPathLength / 10000.0 << ", "; + + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::cout << "Y3 " << (double)nPathLength / 10000.0 << ", "; + + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::cout << "X4 " << (double)nPathLength / 10000.0 << ", "; + + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::cout << "Y4 " << (double)nPathLength / 10000.0 << ", "; + } + + std::cout << std::endl << std::endl; } if (pAnnots) @@ -1414,7 +1925,16 @@ int main(int argc, char* argv[]) free(pAnnotAP); } + // SCAN PAGE + if (false) + { + BYTE* pScan = ScanPage(pGrFile, nTestPage, 1); + if (pScan) + free(pScan); + } + Close(pGrFile); + RELEASEARRAYOBJECTS(pFileData); RELEASEARRAYOBJECTS(pCMapData); return 0; diff --git a/DesktopEditor/graphics/pro/js/wasm/src/metafile.cpp b/DesktopEditor/graphics/pro/js/wasm/src/metafile.cpp index 2379a2b3e75..e47a686cef3 100644 --- a/DesktopEditor/graphics/pro/js/wasm/src/metafile.cpp +++ b/DesktopEditor/graphics/pro/js/wasm/src/metafile.cpp @@ -39,8 +39,10 @@ namespace MetaFile CMetaFile(NSFonts::IApplicationFonts *pAppFonts) : IMetaFile(pAppFonts) {} virtual ~CMetaFile() {} + virtual void SetImageSize(int nWidth, int nHeight) {} virtual bool LoadFromFile(const wchar_t* wsFilePath) { return false; } virtual bool LoadFromBuffer(BYTE* pBuffer, unsigned int unSize) { return false; } + virtual bool LoadFromString(const std::wstring& data) { return false; } virtual bool DrawOnRenderer(IRenderer* pRenderer, double dX, double dY, double dWidth, double dHeight) { return false; } virtual void Close() {} virtual void GetBounds(double* pdX, double* pdY, double* pdW, double* pdH) {} @@ -49,6 +51,7 @@ namespace MetaFile virtual NSFonts::IFontManager* get_FontManager() { return NULL; } virtual std::wstring ConvertToSvg(unsigned int unWidth = 0, unsigned int unHeight = 0) { return L""; } + virtual void SetTempDirectory(const std::wstring& dir) {} virtual void ConvertToXml(const wchar_t* wsFilePath) {} virtual void ConvertToXmlAndRaster(const wchar_t *wsXmlFilePath, const wchar_t* wsOutFilePath, unsigned int unFileType, int nWidth, int nHeight = -1) {} diff --git a/PdfFile/PdfWriter_empty.cpp b/DesktopEditor/graphics/pro/js/wasm/src/pdfwriter.cpp similarity index 91% rename from PdfFile/PdfWriter_empty.cpp rename to DesktopEditor/graphics/pro/js/wasm/src/pdfwriter.cpp index 0b85e4e82de..22692d4e898 100644 --- a/PdfFile/PdfWriter_empty.cpp +++ b/DesktopEditor/graphics/pro/js/wasm/src/pdfwriter.cpp @@ -29,10 +29,10 @@ * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode * */ -#include "PdfWriter.h" +#include "../../../../../../PdfFile/PdfWriter.h" #ifdef BUILDING_WASM_MODULE -CPdfWriter::CPdfWriter(NSFonts::IApplicationFonts* pAppFonts, bool isPDFA, IRenderer* pRenderer) : m_oCommandManager(this) {} +CPdfWriter::CPdfWriter(NSFonts::IApplicationFonts* pAppFonts, bool isPDFA, IRenderer* pRenderer, bool bCreate) : m_oCommandManager(this) {} CPdfWriter::~CPdfWriter() {} int CPdfWriter::SaveToFile(const std::wstring& wsPath) { return 0; } void CPdfWriter::SetPassword(const std::wstring& wsPassword) {} @@ -107,7 +107,7 @@ HRESULT CPdfWriter::CommandDrawTextExCHAR(const LONG& lUnicode, const LONG& lGid HRESULT CPdfWriter::CommandDrawText (const std::wstring& wsUnicodeText, const double& dX, const double& dY, const double& dW, const double& dH) { return 0; } HRESULT CPdfWriter::CommandDrawTextEx (const std::wstring& wsUnicodeText, const unsigned int* pGids, const unsigned int nGidsCount, const double& dX, const double& dY, const double& dW, const double& dH) { return 0; } HRESULT CPdfWriter::CommandDrawTextCHAR2 (unsigned int* unUnicode, const unsigned int& unUnicodeCount, const unsigned int& unGid, const double& dX, const double& dY, const double& dW, const double& dH) { return 0; } -HRESULT CPdfWriter::EndCommand(const DWORD& lType, const LONG& lClipMode) { return 0; } +HRESULT CPdfWriter::EndCommand(const DWORD& lType) { return 0; } HRESULT CPdfWriter::PathCommandMoveTo(const double& dX, const double& dY) { return 0; } HRESULT CPdfWriter::PathCommandLineTo(const double& dX, const double& dY) { return 0; } HRESULT CPdfWriter::PathCommandLinesTo(double* pPoints, const int& nCount) { return 0; } @@ -128,10 +128,13 @@ HRESULT CPdfWriter::DrawImageFromFile(NSFonts::IApplicationFonts* pAppFonts, con HRESULT CPdfWriter::SetTransform(const double& dM11, const double& dM12, const double& dM21, const double& dM22, const double& dX, const double& dY) { return 0; } HRESULT CPdfWriter::GetTransform(double* dM11, double* dM12, double* dM21, double* dM22, double* dX, double* dY) { return 0; } HRESULT CPdfWriter::ResetTransform() { return 0; } +HRESULT CPdfWriter::get_ClipMode(LONG* lMode) { return 0; } +HRESULT CPdfWriter::put_ClipMode(const LONG& lMode) { return 0; } HRESULT CPdfWriter::AddHyperlink(const double& dX, const double& dY, const double& dW, const double& dH, const std::wstring& wsUrl, const std::wstring& wsTooltip) { return 0; } HRESULT CPdfWriter::AddLink(const double& dX, const double& dY, const double& dW, const double& dH, const double& dDestX, const double& dDestY, const int& nPage) { return 0; } -HRESULT CPdfWriter::AddFormField(NSFonts::IApplicationFonts* pAppFonts, CFormFieldInfo* pInfo) { return 0; } +HRESULT CPdfWriter::AddFormField(NSFonts::IApplicationFonts* pAppFonts, CFormFieldInfo* pInfo, const std::wstring& wsTempDirectory) { return 0; } HRESULT CPdfWriter::AddAnnotField(NSFonts::IApplicationFonts* pAppFonts, CAnnotFieldInfo* pFieldInfo) { return 0; } +HRESULT CPdfWriter::AddMetaData(const std::wstring& sMetaName, BYTE* pMetaData, DWORD nMetaLength) { return 0; } HRESULT CPdfWriter::DrawImage1bpp(NSImages::CPixJbig2* pImageBuffer, const unsigned int& unWidth, const unsigned int& unHeight, const double& dX, const double& dY, const double& dW, const double& dH) { return 0; } HRESULT CPdfWriter::EnableBrushRect(const LONG& lEnable) { return 0; } HRESULT CPdfWriter::SetLinearGradient(const double& dX1, const double& dY1, const double& dX2, const double& dY2) { return 0; } @@ -142,9 +145,14 @@ bool CPdfWriter::AddPage(int nPageIndex) { return false; } bool CPdfWriter::EditClose() { return false; } void CPdfWriter::PageRotate(int nRotate) {} void CPdfWriter::Sign(const double& dX, const double& dY, const double& dW, const double& dH, const std::wstring& wsPicturePath, ICertificate* pCertificate) {} -PdfWriter::CImageDict* CPdfWriter::LoadImage(Aggplus::CImage* pImage, const BYTE& nAlpha) { return NULL; } -bool CPdfWriter::DrawImage(Aggplus::CImage* pImage, const double& dX, const double& dY, const double& dW, const double& dH, const BYTE& nAlpha) { return false; } -bool CPdfWriter::DrawText(unsigned char* pCodes, const unsigned int& unLen, const double& dX, const double& dY) { return false; } +HRESULT CPdfWriter::EditWidgetParents(NSFonts::IApplicationFonts* pAppFonts, CWidgetsInfo* pFieldInfo, const std::wstring& wsTempDirectory) { return 0; } +PdfWriter::CDocument* CPdfWriter::GetDocument() { return NULL; } +PdfWriter::CPage* CPdfWriter::GetPage() { return NULL; } +void CPdfWriter::AddFont(const std::wstring& wsFontName, const bool& bBold, const bool& bItalic, const std::wstring& wsFontPath, const LONG& lFaceIndex) {} +void CPdfWriter::SetHeadings(CHeadings* pCommand) {} +PdfWriter::CImageDict* CPdfWriter::LoadImage(Aggplus::CImage* pImage, BYTE nAlpha) { return NULL; } +PdfWriter::CImageDict* CPdfWriter::DrawImage(Aggplus::CImage* pImage, const double& dX, const double& dY, const double& dW, const double& dH, const BYTE& nAlpha) { return NULL; } +bool CPdfWriter::DrawText(unsigned char* pCodes, const unsigned int& unLen, const double& dX, const double& dY, const std::string& sPUA) { return false; } bool CPdfWriter::DrawTextToRenderer(const unsigned int* unGid, const unsigned int& unLen, const double& dX, const double& dY) { return false; } bool CPdfWriter::PathCommandDrawText(unsigned int* pUnicodes, unsigned int unLen, const double& dX, const double& dY, const unsigned int* pGids) { return false; } bool CPdfWriter::UpdateFont() { return false; } diff --git a/DesktopEditor/graphics/pro/js/wasm/src/serialize.h b/DesktopEditor/graphics/pro/js/wasm/src/serialize.h index 72f151d2539..9b2d6962c1f 100644 --- a/DesktopEditor/graphics/pro/js/wasm/src/serialize.h +++ b/DesktopEditor/graphics/pro/js/wasm/src/serialize.h @@ -1,439 +1,425 @@ #ifndef _WASM_SERIALIZE_H #define _WASM_SERIALIZE_H -#include "../../../../../graphics/IRenderer.h" -#include "../../../../../common/StringExt.h" -#include "../../../../../common/StringUTF32.h" -#include "../../../../../graphics/pro/Fonts.h" +#include +#include "../../../../../common/File.h" namespace NSWasm { - class CData - { - protected: - BYTE* m_pData; - size_t m_lSize; - - BYTE* m_pDataCur; - size_t m_lSizeCur; - - public: - CData() - { - m_pData = NULL; - m_lSize = 0; - - m_pDataCur = m_pData; - m_lSizeCur = m_lSize; - } - virtual ~CData() - { - Clear(); - } - - inline void AddSize(size_t nSize) - { - if (NULL == m_pData) - { - m_lSize = 1000; - if (nSize > m_lSize) - m_lSize = nSize; - - m_pData = (BYTE*)malloc(m_lSize * sizeof(BYTE)); - - m_lSizeCur = 0; - m_pDataCur = m_pData; - return; - } - - if ((m_lSizeCur + nSize) > m_lSize) - { - while ((m_lSizeCur + nSize) > m_lSize) - m_lSize *= 2; - - BYTE* pRealloc = (BYTE*)realloc(m_pData, m_lSize * sizeof(BYTE)); - if (NULL != pRealloc) - { - m_pData = pRealloc; - m_pDataCur = m_pData + m_lSizeCur; - } - else - { - BYTE* pMalloc = (BYTE*)malloc(m_lSize * sizeof(BYTE)); - memcpy(pMalloc, m_pData, m_lSizeCur * sizeof(BYTE)); - - free(m_pData); - m_pData = pMalloc; - m_pDataCur = m_pData + m_lSizeCur; - } - } - } - - public: - void AddInt(unsigned int value) - { - AddSize(4); - memcpy(m_pDataCur, &value, sizeof(unsigned int)); - m_pDataCur += 4; - m_lSizeCur += 4; - } - void AddInt(unsigned int value, size_t pos) - { - if (pos < m_lSizeCur) - memcpy(m_pData + pos, &value, sizeof(unsigned int)); - } - void AddDouble(double value) - { - // такой точности хватит - int nV = value * 100; - AddInt(nV); - } - void WriteBYTE(BYTE value) - { - AddSize(sizeof(BYTE)); - memcpy(m_pDataCur, &value, sizeof(BYTE)); - m_pDataCur += sizeof(BYTE); - m_lSizeCur += sizeof(BYTE); - } - void WriteDouble(double value) - { - int nV = value * 10000; - AddInt(nV); - } - void WriteDouble2(double value) - { - SHORT lValue = (SHORT)(value * 100); - AddSize(sizeof(SHORT)); - memcpy(m_pDataCur, &lValue, sizeof(SHORT)); - m_pDataCur += sizeof(SHORT); - m_lSizeCur += sizeof(SHORT); - } - void WriteWCHAR(int value) - { - if (value < 0x10000) - WriteUSHORT(value); - else - { - AddSize(4); - int code = value - 0x10000; - USHORT c1 = 0xD800 | ((code >> 10) & 0x03FF); - USHORT c2 = 0xDC00 | (code & 0x03FF); - memcpy(m_pDataCur, &c1, sizeof(USHORT)); - memcpy(m_pDataCur + 2, &c2, sizeof(USHORT)); - m_pDataCur += 4; - m_lSizeCur += 4; - } - } - void WriteUSHORT(USHORT value) - { - AddSize(sizeof(USHORT)); - memcpy(m_pDataCur, &value, sizeof(USHORT)); - m_pDataCur += sizeof(USHORT); - m_lSizeCur += sizeof(USHORT); - } - void WriteString(BYTE* value, unsigned int len) - { - AddSize(len + 4); - memcpy(m_pDataCur, &len, sizeof(unsigned int)); - m_pDataCur += 4; - m_lSizeCur += 4; - memcpy(m_pDataCur, value, len); - m_pDataCur += len; - m_lSizeCur += len; - } - void WriteString(const std::string& sStr) - { - WriteString((BYTE*)sStr.c_str(), (unsigned int)sStr.length()); - } - void Write(BYTE* value, unsigned int len) - { - if (!value || len == 0) - return; - AddSize(len); - memcpy(m_pDataCur, value, len); - m_pDataCur += len; - m_lSizeCur += len; - } - BYTE* GetBuffer() - { - return m_pData; - } - - void Clear() - { - if (m_pData) free(m_pData); - - m_pData = NULL; - m_lSize = 0; - - m_pDataCur = m_pData; - m_lSizeCur = 0; - } - void ClearWithoutAttack() - { - m_pData = NULL; - m_lSize = 0; - - m_pDataCur = m_pData; - m_lSizeCur = 0; - } - void ClearNoAttack() - { - m_pDataCur = m_pData; - m_lSizeCur = 0; - } - unsigned int GetSize() - { - return (unsigned int)m_lSizeCur; - } - - void SkipLen() - { - AddInt(0); - } - void WriteLen() - { - unsigned int len = (unsigned int)m_lSizeCur; - memcpy(m_pData, &len, sizeof(unsigned int)); - } - }; - - class CHChar - { - public: - int unicode; // юникодное значение - int gid; // индекс глифа в файле - double x; // сдвиг по baseline - double width; // ширина символа (сдвиг до след буквы) - double* matrix; // матрица преобразования (!!! без сдвига) - - public: - CHChar() - { - unicode = 0; - gid = 0; - width = 0; - matrix = NULL; - } - CHChar(const CHChar& oSrc) - { - *this = oSrc; - } - CHChar& operator=(const CHChar& oSrc) - { - unicode = oSrc.unicode; - gid = oSrc.gid; - width = oSrc.width; - matrix = NULL; - if (NULL != oSrc.matrix) - { - matrix = new double[4]; - memcpy(matrix, oSrc.matrix, 4 * sizeof(double)); - } - return *this; - } - ~CHChar() - { - RELEASEARRAYOBJECTS(matrix); - } - - inline void Clear() - { - unicode = 0; - gid = 0; - width = 0; - - RELEASEARRAYOBJECTS(matrix); - } - }; - - class CHLine - { - public: - double m_dAscent; - double m_dDescent; - double m_dX; - double m_dY; - - double m_dEndX; - double m_dEndY; - - // baseline ruler: y = k*x + b - double m_dK; - double m_dB; - double m_ex; - double m_ey; - bool m_bIsConstX; - - // symbols - // не менять на списки. постоянное создание объектов и их удаление - - // плохо влияет на скорость - CHChar* m_pChars; - LONG m_lSizeChars; - LONG m_lCharsTail; - - bool m_bIsSetUpTransform; - double m_sx; - double m_sy; - double m_shx; - double m_shy; - - public: - CHLine() - { - m_dAscent = 0; - m_dDescent = 0; - m_dX = 0; - m_dY = 0; - - m_dK = 0; - m_dB = 0; - m_bIsConstX = false; - - m_ex = 0; - m_ey = 0; - - m_lSizeChars = 1000; - m_lCharsTail = 0; - m_pChars = new CHChar[m_lSizeChars]; - - m_bIsSetUpTransform = false; - m_sx = 1; - m_sy = 1; - m_shx = 0; - m_shy = 0; - } - CHLine& operator=(const CHLine& oLine) - { - m_dAscent = oLine.m_dAscent; - m_dDescent = oLine.m_dDescent; - m_dX = oLine.m_dX; - m_dY = oLine.m_dY; - - m_dK = oLine.m_dK; - m_dB = oLine.m_dB; - - m_lSizeChars = oLine.m_lSizeChars; - m_lCharsTail = oLine.m_lCharsTail; - - RELEASEARRAYOBJECTS(m_pChars); - m_pChars = new CHChar[m_lSizeChars]; - - for (LONG i = 0; i < m_lSizeChars; ++i) - m_pChars[i] = oLine.m_pChars[i]; - - m_bIsSetUpTransform = oLine.m_bIsSetUpTransform; - m_sx = oLine.m_sx; - m_sy = oLine.m_sy; - m_shx = oLine.m_shx; - m_shy = oLine.m_shy; - - return *this; - } - ~CHLine() - { - RELEASEARRAYOBJECTS(m_pChars); - } - - inline void Clear() - { - m_dAscent = 0; - m_dDescent = 0; - m_dX = 0; - m_dY = 0; - - m_dK = 0; - m_dB = 0; - m_bIsConstX = false; - - m_ex = 0; - m_ey = 0; - - m_lCharsTail = 0; - - m_bIsSetUpTransform = false; - m_sx = 1; - m_sy = 1; - m_shx = 0; - m_shy = 0; - } - - inline CHChar* AddTail() - { - if (m_lCharsTail >= m_lSizeChars) - { - CHChar* pNews = new CHChar[2 * m_lSizeChars]; - for (LONG i = 0; i < m_lSizeChars; ++i) - { - pNews[i] = m_pChars[i]; - } - - RELEASEARRAYOBJECTS(m_pChars); - m_pChars = pNews; - m_lSizeChars *= 2; - } - - CHChar* pChar = &m_pChars[m_lCharsTail]; - ++m_lCharsTail; - pChar->Clear(); - - return pChar; - } - - inline CHChar* GetTail() - { - if (0 == m_lCharsTail) - return NULL; - - return &m_pChars[m_lCharsTail - 1]; - } - - inline LONG GetCountChars() - { - return m_lCharsTail; - } - }; -} + class CData + { + protected: + BYTE* m_pData; + size_t m_lSize; + + BYTE* m_pDataCur; + size_t m_lSizeCur; + + public: + CData() + { + m_pData = NULL; + m_lSize = 0; + + m_pDataCur = m_pData; + m_lSizeCur = m_lSize; + } + virtual ~CData() + { + Clear(); + } + + inline void AddSize(size_t nSize) + { + if (NULL == m_pData) + { + m_lSize = 1000; + if (nSize > m_lSize) + m_lSize = nSize; + + m_pData = (BYTE*)malloc(m_lSize * sizeof(BYTE)); + + m_lSizeCur = 0; + m_pDataCur = m_pData; + return; + } + + if ((m_lSizeCur + nSize) > m_lSize) + { + while ((m_lSizeCur + nSize) > m_lSize) + m_lSize *= 2; + + BYTE* pRealloc = (BYTE*)realloc(m_pData, m_lSize * sizeof(BYTE)); + if (NULL != pRealloc) + { + m_pData = pRealloc; + m_pDataCur = m_pData + m_lSizeCur; + } + else + { + BYTE* pMalloc = (BYTE*)malloc(m_lSize * sizeof(BYTE)); + memcpy(pMalloc, m_pData, m_lSizeCur * sizeof(BYTE)); + + free(m_pData); + m_pData = pMalloc; + m_pDataCur = m_pData + m_lSizeCur; + } + } + } + + public: + void AddInt(unsigned int value) + { + AddSize(4); + memcpy(m_pDataCur, &value, sizeof(unsigned int)); + m_pDataCur += 4; + m_lSizeCur += 4; + } + void AddInt(unsigned int value, size_t pos) + { + if (pos < m_lSizeCur) + memcpy(m_pData + pos, &value, sizeof(unsigned int)); + } + void AddDouble(double value) + { + // такой точности хватит + int nV = value * 100; + AddInt(nV); + } + void WriteBYTE(BYTE value) + { + AddSize(sizeof(BYTE)); + memcpy(m_pDataCur, &value, sizeof(BYTE)); + m_pDataCur += sizeof(BYTE); + m_lSizeCur += sizeof(BYTE); + } + void WriteDouble(double value) + { + int nV = value * 10000; + AddInt(nV); + } + void WriteDouble2(double value) + { + SHORT lValue = (SHORT)(value * 100); + AddSize(sizeof(SHORT)); + memcpy(m_pDataCur, &lValue, sizeof(SHORT)); + m_pDataCur += sizeof(SHORT); + m_lSizeCur += sizeof(SHORT); + } + void WriteWCHAR(int value) + { + if (value < 0x10000) + WriteUSHORT(value); + else + { + AddSize(4); + int code = value - 0x10000; + USHORT c1 = 0xD800 | ((code >> 10) & 0x03FF); + USHORT c2 = 0xDC00 | (code & 0x03FF); + memcpy(m_pDataCur, &c1, sizeof(USHORT)); + memcpy(m_pDataCur + 2, &c2, sizeof(USHORT)); + m_pDataCur += 4; + m_lSizeCur += 4; + } + } + void WriteUSHORT(USHORT value) + { + AddSize(sizeof(USHORT)); + memcpy(m_pDataCur, &value, sizeof(USHORT)); + m_pDataCur += sizeof(USHORT); + m_lSizeCur += sizeof(USHORT); + } + void WriteString(BYTE* value, unsigned int len) + { + AddSize(len + 4); + memcpy(m_pDataCur, &len, sizeof(unsigned int)); + m_pDataCur += 4; + m_lSizeCur += 4; + memcpy(m_pDataCur, value, len); + m_pDataCur += len; + m_lSizeCur += len; + } + void WriteString(const std::string& sStr) + { + WriteString((BYTE*)sStr.c_str(), (unsigned int)sStr.length()); + } + void WriteString(const std::wstring& sStr) + { + BYTE* pDataUtf8 = NULL; + LONG lDataUtf8 = 0; + NSFile::CUtf8Converter::GetUtf8StringFromUnicode(sStr.c_str(), (LONG)sStr.length(), pDataUtf8, lDataUtf8); + WriteString(pDataUtf8, (unsigned int)lDataUtf8); + RELEASEARRAYOBJECTS(pDataUtf8); + } + void Write(BYTE* value, unsigned int len) + { + if (!value || len == 0) + return; + AddSize(len); + memcpy(m_pDataCur, value, len); + m_pDataCur += len; + m_lSizeCur += len; + } + BYTE* GetBuffer() + { + return m_pData; + } + + void Clear() + { + if (m_pData) + free(m_pData); + + m_pData = NULL; + m_lSize = 0; + + m_pDataCur = m_pData; + m_lSizeCur = 0; + } + void ClearWithoutAttack() + { + m_pData = NULL; + m_lSize = 0; + + m_pDataCur = m_pData; + m_lSizeCur = 0; + } + void ClearNoAttack() + { + m_pDataCur = m_pData; + m_lSizeCur = 0; + } + unsigned int GetSize() + { + return (unsigned int)m_lSizeCur; + } + + void SkipLen() + { + AddInt(0); + } + void WriteLen() + { + unsigned int len = (unsigned int)m_lSizeCur; + memcpy(m_pData, &len, sizeof(unsigned int)); + } + }; + + struct CHChar + { + int unicode; // юникодное значение + double x; // сдвиг по baseline + double width; // ширина символа (сдвиг до след буквы) + + CHChar() : unicode(0), x(0), width(0) {} + CHChar(const CHChar& oSrc) { *this = oSrc; } + CHChar& operator=(const CHChar& oSrc) + { + unicode = oSrc.unicode; + x = oSrc.x; + width = oSrc.width; + return *this; + } + + inline void Clear() + { + unicode = 0; + x = 0; + width = 0; + } + }; + + struct CHLine + { + double m_dAscent; + double m_dDescent; + double m_dX; + double m_dY; + + double m_dEndX; + double m_dEndY; + + // baseline ruler: y = k*x + b + double m_dK; + double m_dB; + double m_ex; + double m_ey; + bool m_bIsConstX; + + // symbols + // не менять на списки. постоянное создание объектов и их удаление - + // плохо влияет на скорость + CHChar* m_pChars; + LONG m_lSizeChars; + LONG m_lCharsTail; + + bool m_bIsSetUpTransform; + double m_sx; + double m_sy; + double m_shx; + double m_shy; + + CHLine() + { + m_dAscent = 0; + m_dDescent = 0; + m_dX = 0; + m_dY = 0; + + m_dK = 0; + m_dB = 0; + m_bIsConstX = false; + + m_ex = 0; + m_ey = 0; + + m_lSizeChars = 1000; + m_lCharsTail = 0; + m_pChars = new CHChar[m_lSizeChars]; + + m_bIsSetUpTransform = false; + m_sx = 1; + m_sy = 1; + m_shx = 0; + m_shy = 0; + } + CHLine& operator=(const CHLine& oLine) + { + m_dAscent = oLine.m_dAscent; + m_dDescent = oLine.m_dDescent; + m_dX = oLine.m_dX; + m_dY = oLine.m_dY; + + m_dK = oLine.m_dK; + m_dB = oLine.m_dB; + + m_lSizeChars = oLine.m_lSizeChars; + m_lCharsTail = oLine.m_lCharsTail; + + RELEASEARRAYOBJECTS(m_pChars); + m_pChars = new CHChar[m_lSizeChars]; + + for (LONG i = 0; i < m_lSizeChars; ++i) + m_pChars[i] = oLine.m_pChars[i]; + + m_bIsSetUpTransform = oLine.m_bIsSetUpTransform; + m_sx = oLine.m_sx; + m_sy = oLine.m_sy; + m_shx = oLine.m_shx; + m_shy = oLine.m_shy; + + return *this; + } + ~CHLine() + { + RELEASEARRAYOBJECTS(m_pChars); + } + + inline void Clear() + { + m_dAscent = 0; + m_dDescent = 0; + m_dX = 0; + m_dY = 0; + + m_dK = 0; + m_dB = 0; + m_bIsConstX = false; + + m_ex = 0; + m_ey = 0; + + m_lCharsTail = 0; + + m_bIsSetUpTransform = false; + m_sx = 1; + m_sy = 1; + m_shx = 0; + m_shy = 0; + } + + inline CHChar* AddTail() + { + if (m_lCharsTail >= m_lSizeChars) + { + CHChar* pNews = new CHChar[2 * m_lSizeChars]; + for (LONG i = 0; i < m_lSizeChars; ++i) + pNews[i] = m_pChars[i]; + + RELEASEARRAYOBJECTS(m_pChars); + m_pChars = pNews; + m_lSizeChars *= 2; + } + + CHChar* pChar = &m_pChars[m_lCharsTail]; + ++m_lCharsTail; + pChar->Clear(); + + return pChar; + } + + inline CHChar* GetTail() + { + if (m_lCharsTail >= m_lSizeChars) + { + CHChar* pNews = new CHChar[2 * m_lSizeChars]; + for (LONG i = 0; i < m_lSizeChars; ++i) + pNews[i] = m_pChars[i]; + + RELEASEARRAYOBJECTS(m_pChars); + m_pChars = pNews; + m_lSizeChars *= 2; + } + + return m_lCharsTail ? &m_pChars[m_lCharsTail - 1] : NULL; + } + + inline LONG GetCountChars() + { + return m_lCharsTail; + } + }; +} // namespace NSWasm namespace NSWasm { - struct CPageLinkItem - { - std::string Link; - double Dest; - - double X; - double Y; - double W; - double H; - }; - - class CPageLink - { - public: - std::vector m_arLinks; - - public: - BYTE* Serialize() - { - NSWasm::CData oRes; - oRes.SkipLen(); - for (const CPageLinkItem& link : m_arLinks) - { - oRes.WriteString((BYTE*)link.Link.c_str(), link.Link.length()); - oRes.AddDouble(link.Dest); - oRes.AddDouble(link.X); - oRes.AddDouble(link.Y); - oRes.AddDouble(link.W); - oRes.AddDouble(link.H); - } - oRes.WriteLen(); - - BYTE* res = oRes.GetBuffer(); - oRes.ClearWithoutAttack(); - return res; - } - }; -} + struct CPageLinkItem + { + std::string Link; + double Dest; + + double X; + double Y; + double W; + double H; + }; + + class CPageLink + { + public: + std::vector m_arLinks; + + public: + BYTE* Serialize() + { + NSWasm::CData oRes; + oRes.SkipLen(); + for (const CPageLinkItem& link : m_arLinks) + { + oRes.WriteString((BYTE*)link.Link.c_str(), link.Link.length()); + oRes.AddDouble(link.Dest); + oRes.AddDouble(link.X); + oRes.AddDouble(link.Y); + oRes.AddDouble(link.W); + oRes.AddDouble(link.H); + } + oRes.WriteLen(); + + BYTE* res = oRes.GetBuffer(); + oRes.ClearWithoutAttack(); + return res; + } + }; +} // namespace NSWasm #endif // _WASM_SERIALIZE_H diff --git a/DesktopEditor/graphics/pro/metafile.pri b/DesktopEditor/graphics/pro/metafile.pri index 176a1f8e4a4..6baa7c4f23f 100644 --- a/DesktopEditor/graphics/pro/metafile.pri +++ b/DesktopEditor/graphics/pro/metafile.pri @@ -19,6 +19,7 @@ METAFILE_PATH = $$PWD/../../raster/Metafile \ $$METAFILE_PATH/Emf/EmfTypes.h \ $$METAFILE_PATH/Emf/EmfObjects.h \ + $$METAFILE_PATH/Emf/EmfPlusObjects.h \ $$METAFILE_PATH/Emf/EmfPlayer.h \ $$METAFILE_PATH/Emf/EmfFile.h \ $$METAFILE_PATH/Wmf/WmfObjects.h \ @@ -106,6 +107,7 @@ METAFILE_PATH = $$PWD/../../raster/Metafile $$METAFILE_PATH/svg/SvgObjects/CMask.h \ $$METAFILE_PATH/svg/SvgObjects/CPattern.h \ $$METAFILE_PATH/svg/SvgObjects/CSymbol.h \ + $$METAFILE_PATH/svg/SvgObjects/CSwitch.h \ $$METAFILE_PATH/svg/SvgObjects/CMarker.h \ $$METAFILE_PATH/svg/SvgObjects/CImage.h \ $$METAFILE_PATH/svg/SvgObjects/CLine.h \ @@ -116,6 +118,7 @@ METAFILE_PATH = $$PWD/../../raster/Metafile $$METAFILE_PATH/svg/SvgObjects/CText.h \ $$METAFILE_PATH/svg/SvgObjects/CUse.h \ $$METAFILE_PATH/svg/SvgObjects/CPolyline.h \ + $$METAFILE_PATH/svg/SvgObjects/CFont.h \ $$METAFILE_PATH/svg/SvgObjects/CStyle.h \ $$METAFILE_PATH/svg/SvgObjects/CObjectBase.h \ $$METAFILE_PATH/svg/SvgUtils.h @@ -130,6 +133,7 @@ METAFILE_PATH = $$PWD/../../raster/Metafile $$METAFILE_PATH/svg/SvgObjects/CMarker.cpp \ $$METAFILE_PATH/svg/SvgObjects/CPattern.cpp \ $$METAFILE_PATH/svg/SvgObjects/CSymbol.cpp \ + $$METAFILE_PATH/svg/SvgObjects/CSwitch.cpp \ $$METAFILE_PATH/svg/SvgObjects/CImage.cpp \ $$METAFILE_PATH/svg/SvgObjects/CLine.cpp \ $$METAFILE_PATH/svg/SvgObjects/CRect.cpp \ @@ -139,6 +143,7 @@ METAFILE_PATH = $$PWD/../../raster/Metafile $$METAFILE_PATH/svg/SvgObjects/CText.cpp \ $$METAFILE_PATH/svg/SvgObjects/CUse.cpp \ $$METAFILE_PATH/svg/SvgObjects/CPolyline.cpp \ + $$METAFILE_PATH/svg/SvgObjects/CFont.cpp \ $$METAFILE_PATH/svg/SvgObjects/CObjectBase.cpp \ $$METAFILE_PATH/svg/SvgObjects/CStyle.cpp diff --git a/DesktopEditor/graphics/pro/officedrawingfile.cpp b/DesktopEditor/graphics/pro/officedrawingfile.cpp index 5477790831c..cd066c7a778 100644 --- a/DesktopEditor/graphics/pro/officedrawingfile.cpp +++ b/DesktopEditor/graphics/pro/officedrawingfile.cpp @@ -64,7 +64,7 @@ CBgraFrame* GetFrame(IOfficeDrawingFile* pFile, int nPageIndex, int nRasterW, in int nWidth = (nRasterW > 0) ? nRasterW : ((int)dWidth * 96 / dPageDpiX); int nHeight = (nRasterH > 0) ? nRasterH : ((int)dHeight * 96 / dPageDpiY); - BYTE* pBgraData = new BYTE[nWidth * nHeight * 4]; + BYTE* pBgraData = new(std::nothrow) BYTE[nWidth * nHeight * 4]; if (!pBgraData) { RELEASEINTERFACE(pFontManager); diff --git a/DesktopEditor/graphics/pro/officedrawingfile.h b/DesktopEditor/graphics/pro/officedrawingfile.h index 9747138e819..7681650e93b 100644 --- a/DesktopEditor/graphics/pro/officedrawingfile.h +++ b/DesktopEditor/graphics/pro/officedrawingfile.h @@ -43,6 +43,18 @@ enum OfficeDrawingFileType odftUndefined = 255 }; +struct COfficeDrawingPageParams +{ + bool m_bNeedDrawAnnotation; + + COfficeDrawingPageParams() : m_bNeedDrawAnnotation(true){} + + void SetDrawAnnotation(bool bDraw) + { + m_bNeedDrawAnnotation = bDraw; + } +}; + class GRAPHICS_DECL IOfficeDrawingFile { public: @@ -70,7 +82,7 @@ class GRAPHICS_DECL IOfficeDrawingFile // Pages info/draw virtual int GetPagesCount() = 0; virtual void GetPageInfo(int nPageIndex, double* pdWidth, double* pdHeight, double* pdDpiX, double* pdDpiY) = 0; - virtual void DrawPageOnRenderer(IRenderer* pRenderer, int nPageIndex, bool* pBreak) = 0; + virtual void DrawPageOnRenderer(IRenderer* pRenderer, int nPageIndex, bool* pBreak, COfficeDrawingPageParams* pParams = NULL) = 0; // Common methods/wrappers on GetPageInfo + DrawPageOnRenderer virtual unsigned char* ConvertToPixels(int nPageIndex, int nRasterW, int nRasterH, diff --git a/DesktopEditor/graphics/pro/raster.pri b/DesktopEditor/graphics/pro/raster.pri index 394eb886886..f5e54810fc6 100644 --- a/DesktopEditor/graphics/pro/raster.pri +++ b/DesktopEditor/graphics/pro/raster.pri @@ -5,234 +5,238 @@ DEFINES -= _UNICODE DEFINES += DISABLE_IMAGE_EXCEPTIONS DEFINES += \ - _QT \ - EXCLUDE_JPG_SUPPORT \ - MNG_SUPPORT_DISPLAY \ - MNG_SUPPORT_READ \ - MNG_SUPPORT_WRITE \ - MNG_ACCESS_CHUNKS \ - MNG_STORE_CHUNKS\ - MNG_ERROR_TELLTALE + _QT \ + EXCLUDE_JPG_SUPPORT \ + MNG_SUPPORT_DISPLAY \ + MNG_SUPPORT_READ \ + MNG_SUPPORT_WRITE \ + MNG_ACCESS_CHUNKS \ + MNG_STORE_CHUNKS\ + MNG_ERROR_TELLTALE core_linux { - DEFINES += HAVE_UNISTD_H HAVE_FCNTL_H + DEFINES += HAVE_UNISTD_H HAVE_FCNTL_H QMAKE_CXXFLAGS += -Wno-narrowing } core_mac { - DEFINES += HAVE_UNISTD_H HAVE_FCNTL_H + DEFINES += HAVE_UNISTD_H HAVE_FCNTL_H } core_windows { - DEFINES += JAS_WIN_MSVC_BUILD NOMINMAX + DEFINES += JAS_WIN_MSVC_BUILD NOMINMAX LIBS += -lUser32 } +core_android { + QMAKE_CFLAGS += -Wno-incompatible-function-pointer-types +} + INCLUDEPATH += \ - $$LIB_GRAPHICS_PRI_PATH/cximage/jasper/include \ + $$LIB_GRAPHICS_PRI_PATH/cximage/jasper/include \ $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg \ $$LIB_GRAPHICS_PRI_PATH/cximage/png HEADERS += \ - $$PWD/../../graphics/Image.h \ + $$PWD/../../graphics/Image.h \ $$PWD/../../raster/BgraFrame.h \ $$PWD/../../raster/ImageFileFormatChecker.h SOURCES += \ - $$PWD/../../graphics/Image.cpp \ - $$PWD/../../raster/BgraFrame.cpp \ - $$PWD/../../raster/ImageFileFormatChecker.cpp + $$PWD/../../graphics/Image.cpp \ + $$PWD/../../raster/BgraFrame.cpp \ + $$PWD/../../raster/ImageFileFormatChecker.cpp SOURCES += \ - $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/wrtarga.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/wrrle.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/wrppm.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/wrjpgcom.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/wrgif.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/wrbmp.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/transupp.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/rdtarga.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/rdswitch.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/rdrle.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/rdppm.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/rdjpgcom.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/rdgif.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/rdcolmap.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/rdbmp.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jutils.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jpegtran.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jquant1.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jquant2.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jdpostct.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jdsample.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jdtrans.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jerror.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jfdctflt.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jfdctfst.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jfdctint.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jidctflt.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jidctfst.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jidctint.c \ - #$$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jmemansi.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jmemmgr.c \ - #$$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jmemname.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jmemnobs.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jaricom.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jcapimin.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jcapistd.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jcarith.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jccoefct.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jccolor.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jcdctmgr.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jchuff.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jcinit.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jcmainct.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jcmarker.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jcmaster.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jcomapi.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jcparam.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jcprepct.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jcsample.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jctrans.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jdapimin.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jdapistd.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jdarith.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jdatadst.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jdatasrc.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jdcoefct.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jdcolor.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jddctmgr.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jdhuff.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jdinput.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jdmainct.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jdmarker.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jdmaster.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jdmerge.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/cdjpeg.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/cjpeg.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/ckconfig.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/djpeg.c + $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/wrtarga.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/wrrle.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/wrppm.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/wrjpgcom.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/wrgif.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/wrbmp.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/transupp.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/rdtarga.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/rdswitch.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/rdrle.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/rdppm.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/rdjpgcom.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/rdgif.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/rdcolmap.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/rdbmp.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jutils.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jpegtran.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jquant1.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jquant2.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jdpostct.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jdsample.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jdtrans.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jerror.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jfdctflt.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jfdctfst.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jfdctint.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jidctflt.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jidctfst.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jidctint.c \ + #$$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jmemansi.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jmemmgr.c \ + #$$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jmemname.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jmemnobs.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jaricom.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jcapimin.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jcapistd.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jcarith.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jccoefct.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jccolor.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jcdctmgr.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jchuff.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jcinit.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jcmainct.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jcmarker.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jcmaster.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jcomapi.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jcparam.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jcprepct.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jcsample.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jctrans.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jdapimin.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jdapistd.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jdarith.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jdatadst.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jdatasrc.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jdcoefct.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jdcolor.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jddctmgr.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jdhuff.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jdinput.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jdmainct.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jdmarker.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jdmaster.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/jdmerge.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/cdjpeg.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/cjpeg.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/ckconfig.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg/djpeg.c !disable_cximage_mng { SOURCES += \ - $$LIB_GRAPHICS_PRI_PATH/cximage/mng/libmng_callback_xs.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/mng/libmng_chunk_descr.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/mng/libmng_chunk_io.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/mng/libmng_chunk_prc.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/mng/libmng_chunk_xs.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/mng/libmng_cms.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/mng/libmng_display.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/mng/libmng_dither.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/mng/libmng_error.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/mng/libmng_filter.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/mng/libmng_hlapi.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/mng/libmng_jpeg.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/mng/libmng_object_prc.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/mng/libmng_pixels.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/mng/libmng_prop_xs.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/mng/libmng_read.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/mng/libmng_trace.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/mng/libmng_write.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/mng/libmng_callback_xs.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/mng/libmng_chunk_descr.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/mng/libmng_chunk_io.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/mng/libmng_chunk_prc.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/mng/libmng_chunk_xs.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/mng/libmng_cms.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/mng/libmng_display.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/mng/libmng_dither.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/mng/libmng_error.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/mng/libmng_filter.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/mng/libmng_hlapi.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/mng/libmng_jpeg.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/mng/libmng_object_prc.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/mng/libmng_pixels.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/mng/libmng_prop_xs.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/mng/libmng_read.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/mng/libmng_trace.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/mng/libmng_write.c \ $$LIB_GRAPHICS_PRI_PATH/cximage/mng/libmng_zlib.c } SOURCES += \ - $$LIB_GRAPHICS_PRI_PATH/cximage/png/png.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/png/pngerror.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/png/pngget.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/png/pngmem.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/png/pngpread.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/png/pngread.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/png/pngrio.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/png/pngrtran.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/png/pngrutil.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/png/pngset.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/png/pngtrans.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/png/pngwio.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/png/pngwrite.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/png/pngwtran.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/png/pngwutil.c \ - \ + $$LIB_GRAPHICS_PRI_PATH/cximage/png/png.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/png/pngerror.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/png/pngget.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/png/pngmem.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/png/pngpread.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/png/pngread.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/png/pngrio.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/png/pngrtran.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/png/pngrutil.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/png/pngset.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/png/pngtrans.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/png/pngwio.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/png/pngwrite.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/png/pngwtran.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/png/pngwutil.c \ + \ $$LIB_GRAPHICS_PRI_PATH/cximage/tiff/tif_stream.cxx \ - $$LIB_GRAPHICS_PRI_PATH/cximage/tiff/tif_aux.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/tiff/tif_close.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/tiff/tif_codec.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/tiff/tif_color.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/tiff/tif_compress.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/tiff/tif_dir.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/tiff/tif_dirinfo.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/tiff/tif_dirread.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/tiff/tif_dirwrite.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/tiff/tif_dumpmode.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/tiff/tif_error.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/tiff/tif_extension.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/tiff/tif_fax3.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/tiff/tif_fax3sm.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/tiff/tif_flush.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/tiff/tif_getimage.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/tiff/tif_jbig.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/tiff/tif_jpeg.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/tiff/tif_luv.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/tiff/tif_lzw.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/tiff/tif_next.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/tiff/tif_ojpeg.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/tiff/tif_open.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/tiff/tif_packbits.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/tiff/tif_pixarlog.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/tiff/tif_predict.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/tiff/tif_print.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/tiff/tif_read.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/tiff/tif_strip.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/tiff/tif_swab.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/tiff/tif_thunder.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/tiff/tif_tile.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/tiff/tif_unix.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/tiff/tif_version.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/tiff/tif_warning.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/tiff/tif_write.c \ - $$LIB_GRAPHICS_PRI_PATH/cximage/tiff/tif_zip.c \ - \ - $$LIB_GRAPHICS_PRI_PATH/cximage/CxImage/tif_xfile.cpp \ - $$LIB_GRAPHICS_PRI_PATH/cximage/CxImage/ximabmp.cpp \ - $$LIB_GRAPHICS_PRI_PATH/cximage/CxImage/ximadsp.cpp \ - $$LIB_GRAPHICS_PRI_PATH/cximage/CxImage/ximaenc.cpp \ - $$LIB_GRAPHICS_PRI_PATH/cximage/CxImage/ximaexif.cpp \ - $$LIB_GRAPHICS_PRI_PATH/cximage/CxImage/ximage.cpp \ - $$LIB_GRAPHICS_PRI_PATH/cximage/CxImage/ximagif.cpp \ - $$LIB_GRAPHICS_PRI_PATH/cximage/CxImage/ximahist.cpp \ - $$LIB_GRAPHICS_PRI_PATH/cximage/CxImage/ximaico.cpp \ - $$LIB_GRAPHICS_PRI_PATH/cximage/CxImage/ximainfo.cpp \ - $$LIB_GRAPHICS_PRI_PATH/cximage/CxImage/ximaint.cpp \ - $$LIB_GRAPHICS_PRI_PATH/cximage/CxImage/ximajas.cpp \ - $$LIB_GRAPHICS_PRI_PATH/cximage/CxImage/ximajbg.cpp \ - $$LIB_GRAPHICS_PRI_PATH/cximage/CxImage/ximajpg.cpp \ - $$LIB_GRAPHICS_PRI_PATH/cximage/CxImage/ximalpha.cpp \ - $$LIB_GRAPHICS_PRI_PATH/cximage/CxImage/ximalyr.cpp \ - $$LIB_GRAPHICS_PRI_PATH/cximage/CxImage/ximamng.cpp \ - $$LIB_GRAPHICS_PRI_PATH/cximage/CxImage/ximapal.cpp \ - $$LIB_GRAPHICS_PRI_PATH/cximage/CxImage/ximapcx.cpp \ - $$LIB_GRAPHICS_PRI_PATH/cximage/CxImage/ximapng.cpp \ - $$LIB_GRAPHICS_PRI_PATH/cximage/CxImage/ximapsd.cpp \ - $$LIB_GRAPHICS_PRI_PATH/cximage/CxImage/ximaraw.cpp \ - $$LIB_GRAPHICS_PRI_PATH/cximage/CxImage/ximasel.cpp \ - $$LIB_GRAPHICS_PRI_PATH/cximage/CxImage/ximaska.cpp \ - $$LIB_GRAPHICS_PRI_PATH/cximage/CxImage/ximatga.cpp \ - $$LIB_GRAPHICS_PRI_PATH/cximage/CxImage/ximath.cpp \ - $$LIB_GRAPHICS_PRI_PATH/cximage/CxImage/ximatif.cpp \ - $$LIB_GRAPHICS_PRI_PATH/cximage/CxImage/ximatran.cpp \ - $$LIB_GRAPHICS_PRI_PATH/cximage/CxImage/ximawbmp.cpp \ - $$LIB_GRAPHICS_PRI_PATH/cximage/CxImage/ximawmf.cpp \ - $$LIB_GRAPHICS_PRI_PATH/cximage/CxImage/ximawnd.cpp \ - $$LIB_GRAPHICS_PRI_PATH/cximage/CxImage/xmemfile.cpp + $$LIB_GRAPHICS_PRI_PATH/cximage/tiff/tif_aux.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/tiff/tif_close.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/tiff/tif_codec.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/tiff/tif_color.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/tiff/tif_compress.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/tiff/tif_dir.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/tiff/tif_dirinfo.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/tiff/tif_dirread.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/tiff/tif_dirwrite.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/tiff/tif_dumpmode.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/tiff/tif_error.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/tiff/tif_extension.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/tiff/tif_fax3.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/tiff/tif_fax3sm.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/tiff/tif_flush.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/tiff/tif_getimage.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/tiff/tif_jbig.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/tiff/tif_jpeg.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/tiff/tif_luv.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/tiff/tif_lzw.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/tiff/tif_next.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/tiff/tif_ojpeg.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/tiff/tif_open.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/tiff/tif_packbits.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/tiff/tif_pixarlog.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/tiff/tif_predict.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/tiff/tif_print.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/tiff/tif_read.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/tiff/tif_strip.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/tiff/tif_swab.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/tiff/tif_thunder.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/tiff/tif_tile.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/tiff/tif_unix.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/tiff/tif_version.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/tiff/tif_warning.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/tiff/tif_write.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/tiff/tif_zip.c \ + \ + $$LIB_GRAPHICS_PRI_PATH/cximage/CxImage/tif_xfile.cpp \ + $$LIB_GRAPHICS_PRI_PATH/cximage/CxImage/ximabmp.cpp \ + $$LIB_GRAPHICS_PRI_PATH/cximage/CxImage/ximadsp.cpp \ + $$LIB_GRAPHICS_PRI_PATH/cximage/CxImage/ximaenc.cpp \ + $$LIB_GRAPHICS_PRI_PATH/cximage/CxImage/ximaexif.cpp \ + $$LIB_GRAPHICS_PRI_PATH/cximage/CxImage/ximage.cpp \ + $$LIB_GRAPHICS_PRI_PATH/cximage/CxImage/ximagif.cpp \ + $$LIB_GRAPHICS_PRI_PATH/cximage/CxImage/ximahist.cpp \ + $$LIB_GRAPHICS_PRI_PATH/cximage/CxImage/ximaico.cpp \ + $$LIB_GRAPHICS_PRI_PATH/cximage/CxImage/ximainfo.cpp \ + $$LIB_GRAPHICS_PRI_PATH/cximage/CxImage/ximaint.cpp \ + $$LIB_GRAPHICS_PRI_PATH/cximage/CxImage/ximajas.cpp \ + $$LIB_GRAPHICS_PRI_PATH/cximage/CxImage/ximajbg.cpp \ + $$LIB_GRAPHICS_PRI_PATH/cximage/CxImage/ximajpg.cpp \ + $$LIB_GRAPHICS_PRI_PATH/cximage/CxImage/ximalpha.cpp \ + $$LIB_GRAPHICS_PRI_PATH/cximage/CxImage/ximalyr.cpp \ + $$LIB_GRAPHICS_PRI_PATH/cximage/CxImage/ximamng.cpp \ + $$LIB_GRAPHICS_PRI_PATH/cximage/CxImage/ximapal.cpp \ + $$LIB_GRAPHICS_PRI_PATH/cximage/CxImage/ximapcx.cpp \ + $$LIB_GRAPHICS_PRI_PATH/cximage/CxImage/ximapng.cpp \ + $$LIB_GRAPHICS_PRI_PATH/cximage/CxImage/ximapsd.cpp \ + $$LIB_GRAPHICS_PRI_PATH/cximage/CxImage/ximaraw.cpp \ + $$LIB_GRAPHICS_PRI_PATH/cximage/CxImage/ximasel.cpp \ + $$LIB_GRAPHICS_PRI_PATH/cximage/CxImage/ximaska.cpp \ + $$LIB_GRAPHICS_PRI_PATH/cximage/CxImage/ximatga.cpp \ + $$LIB_GRAPHICS_PRI_PATH/cximage/CxImage/ximath.cpp \ + $$LIB_GRAPHICS_PRI_PATH/cximage/CxImage/ximatif.cpp \ + $$LIB_GRAPHICS_PRI_PATH/cximage/CxImage/ximatran.cpp \ + $$LIB_GRAPHICS_PRI_PATH/cximage/CxImage/ximawbmp.cpp \ + $$LIB_GRAPHICS_PRI_PATH/cximage/CxImage/ximawmf.cpp \ + $$LIB_GRAPHICS_PRI_PATH/cximage/CxImage/ximawnd.cpp \ + $$LIB_GRAPHICS_PRI_PATH/cximage/CxImage/xmemfile.cpp !disable_cximage_all { SOURCES += \ - $$LIB_GRAPHICS_PRI_PATH/raster/JBig2/source/Encoder/jbig2arith.cpp \ - $$LIB_GRAPHICS_PRI_PATH/raster/JBig2/source/Encoder/jbig2enc.cpp \ - $$LIB_GRAPHICS_PRI_PATH/raster/JBig2/source/Encoder/jbig2sym.cpp + $$LIB_GRAPHICS_PRI_PATH/raster/JBig2/source/Encoder/jbig2arith.cpp \ + $$LIB_GRAPHICS_PRI_PATH/raster/JBig2/source/Encoder/jbig2enc.cpp \ + $$LIB_GRAPHICS_PRI_PATH/raster/JBig2/source/Encoder/jbig2sym.cpp SOURCES += \ - $$LIB_GRAPHICS_PRI_PATH/cximage/jbig/jbig.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/jbig/jbig.c \ $$LIB_GRAPHICS_PRI_PATH/cximage/jbig/jbig_tab.c SOURCES += $$PWD/libpsd_pri.c @@ -244,37 +248,41 @@ SOURCES += $$PWD/lepton_lib_all.cpp SOURCES += $$LIB_GRAPHICS_PRI_PATH/cximage/raw/libdcr.c SOURCES += \ - $$LIB_GRAPHICS_PRI_PATH/raster/JBig2/source/LeptonLib/boxbasic.cpp \ - $$LIB_GRAPHICS_PRI_PATH/raster/JBig2/source/LeptonLib/ccbord.cpp \ - $$LIB_GRAPHICS_PRI_PATH/raster/JBig2/source/LeptonLib/dwacomb.2.cpp \ - $$LIB_GRAPHICS_PRI_PATH/raster/JBig2/source/LeptonLib/dwacomblow.2.cpp \ - $$LIB_GRAPHICS_PRI_PATH/raster/JBig2/source/LeptonLib/fhmtgen.1.cpp \ - $$LIB_GRAPHICS_PRI_PATH/raster/JBig2/source/LeptonLib/fliphmtgen.cpp \ - $$LIB_GRAPHICS_PRI_PATH/raster/JBig2/source/LeptonLib/fmorphauto.cpp \ - $$LIB_GRAPHICS_PRI_PATH/raster/JBig2/source/LeptonLib/fmorphgen.1.cpp \ - $$LIB_GRAPHICS_PRI_PATH/raster/JBig2/source/LeptonLib/numabasic.cpp \ - $$LIB_GRAPHICS_PRI_PATH/raster/JBig2/source/LeptonLib/pix5.cpp \ - $$LIB_GRAPHICS_PRI_PATH/raster/JBig2/source/LeptonLib/pixabasic.cpp \ - $$LIB_GRAPHICS_PRI_PATH/raster/JBig2/source/LeptonLib/pixafunc1.cpp \ - $$LIB_GRAPHICS_PRI_PATH/raster/JBig2/source/LeptonLib/pixcomp.cpp \ - $$LIB_GRAPHICS_PRI_PATH/raster/JBig2/source/LeptonLib/ptabasic.cpp \ - $$LIB_GRAPHICS_PRI_PATH/raster/JBig2/source/LeptonLib/ptra.cpp \ - $$LIB_GRAPHICS_PRI_PATH/raster/JBig2/source/LeptonLib/ropiplow.cpp \ - $$LIB_GRAPHICS_PRI_PATH/raster/JBig2/source/LeptonLib/roplow.cpp \ - $$LIB_GRAPHICS_PRI_PATH/raster/JBig2/source/LeptonLib/rotateam.cpp \ - $$LIB_GRAPHICS_PRI_PATH/raster/JBig2/source/LeptonLib/rotateshear.cpp \ - $$LIB_GRAPHICS_PRI_PATH/raster/JBig2/source/LeptonLib/sarray.cpp \ - $$LIB_GRAPHICS_PRI_PATH/raster/JBig2/source/LeptonLib/sel1.cpp \ - $$LIB_GRAPHICS_PRI_PATH/raster/JBig2/source/LeptonLib/sel2.cpp \ - $$LIB_GRAPHICS_PRI_PATH/raster/JBig2/source/LeptonLib/skew.cpp + $$LIB_GRAPHICS_PRI_PATH/raster/JBig2/source/LeptonLib/boxbasic.cpp \ + $$LIB_GRAPHICS_PRI_PATH/raster/JBig2/source/LeptonLib/ccbord.cpp \ + $$LIB_GRAPHICS_PRI_PATH/raster/JBig2/source/LeptonLib/dwacomb.2.cpp \ + $$LIB_GRAPHICS_PRI_PATH/raster/JBig2/source/LeptonLib/dwacomblow.2.cpp \ + $$LIB_GRAPHICS_PRI_PATH/raster/JBig2/source/LeptonLib/fhmtgen.1.cpp \ + $$LIB_GRAPHICS_PRI_PATH/raster/JBig2/source/LeptonLib/fliphmtgen.cpp \ + $$LIB_GRAPHICS_PRI_PATH/raster/JBig2/source/LeptonLib/fmorphauto.cpp \ + $$LIB_GRAPHICS_PRI_PATH/raster/JBig2/source/LeptonLib/fmorphgen.1.cpp \ + $$LIB_GRAPHICS_PRI_PATH/raster/JBig2/source/LeptonLib/numabasic.cpp \ + $$LIB_GRAPHICS_PRI_PATH/raster/JBig2/source/LeptonLib/pix5.cpp \ + $$LIB_GRAPHICS_PRI_PATH/raster/JBig2/source/LeptonLib/pixabasic.cpp \ + $$LIB_GRAPHICS_PRI_PATH/raster/JBig2/source/LeptonLib/pixafunc1.cpp \ + $$LIB_GRAPHICS_PRI_PATH/raster/JBig2/source/LeptonLib/pixcomp.cpp \ + $$LIB_GRAPHICS_PRI_PATH/raster/JBig2/source/LeptonLib/ptabasic.cpp \ + $$LIB_GRAPHICS_PRI_PATH/raster/JBig2/source/LeptonLib/ptra.cpp \ + $$LIB_GRAPHICS_PRI_PATH/raster/JBig2/source/LeptonLib/ropiplow.cpp \ + $$LIB_GRAPHICS_PRI_PATH/raster/JBig2/source/LeptonLib/roplow.cpp \ + $$LIB_GRAPHICS_PRI_PATH/raster/JBig2/source/LeptonLib/rotateam.cpp \ + $$LIB_GRAPHICS_PRI_PATH/raster/JBig2/source/LeptonLib/rotateshear.cpp \ + $$LIB_GRAPHICS_PRI_PATH/raster/JBig2/source/LeptonLib/sarray.cpp \ + $$LIB_GRAPHICS_PRI_PATH/raster/JBig2/source/LeptonLib/sel1.cpp \ + $$LIB_GRAPHICS_PRI_PATH/raster/JBig2/source/LeptonLib/sel2.cpp \ + $$LIB_GRAPHICS_PRI_PATH/raster/JBig2/source/LeptonLib/skew.cpp + +SOURCES += \ + $$LIB_GRAPHICS_PRI_PATH/raster/Jp2/J2kFile.cpp \ + $$LIB_GRAPHICS_PRI_PATH/raster/Jp2/Reader.cpp \ + $$LIB_GRAPHICS_PRI_PATH/raster/JBig2/source/JBig2File.cpp SOURCES += \ - $$LIB_GRAPHICS_PRI_PATH/raster/Jp2/J2kFile.cpp \ - $$LIB_GRAPHICS_PRI_PATH/raster/Jp2/Reader.cpp \ - $$LIB_GRAPHICS_PRI_PATH/raster/JBig2/source/JBig2File.cpp + $$LIB_GRAPHICS_PRI_PATH/raster/PICT/PICFile.cpp \ + $$LIB_GRAPHICS_PRI_PATH/raster/PICT/pic.cpp SOURCES += \ - $$LIB_GRAPHICS_PRI_PATH/cximage/jasper/base/jas_cm.c \ + $$LIB_GRAPHICS_PRI_PATH/cximage/jasper/base/jas_cm.c \ $$LIB_GRAPHICS_PRI_PATH/cximage/jasper/base/jas_debug.c \ $$LIB_GRAPHICS_PRI_PATH/cximage/jasper/base/jas_getopt.c \ $$LIB_GRAPHICS_PRI_PATH/cximage/jasper/base/jas_icc.c \ @@ -331,13 +339,13 @@ disable_cximage_mng:DEFINES += CXIMAGE_DISABLE_SUPPORT_MNG disable_cximage_all:DEFINES += CXIMAGE_DISABLE_SUPPORT_ADDITIONS !config_zlip_image { - OFFICEUTILS_PATH = $$PWD/../../../OfficeUtils + OFFICEUTILS_PATH = $$PWD/../../../OfficeUtils INCLUDEPATH += \ - $$OFFICEUTILS_PATH/src/zlib-1.2.11 \ + $$OFFICEUTILS_PATH/src/zlib-1.2.11 \ $$OFFICEUTILS_PATH/src - SOURCES += \ - $$OFFICEUTILS_PATH/src/zlib-1.2.11/crc32.c \ + SOURCES += \ + $$OFFICEUTILS_PATH/src/zlib-1.2.11/crc32.c \ $$OFFICEUTILS_PATH/src/zlib-1.2.11/adler32.c \ $$OFFICEUTILS_PATH/src/zlib-1.2.11/deflate.c \ $$OFFICEUTILS_PATH/src/zlib-1.2.11/inffast.c \ @@ -349,5 +357,5 @@ disable_cximage_all:DEFINES += CXIMAGE_DISABLE_SUPPORT_ADDITIONS $$OFFICEUTILS_PATH/src/zlib-1.2.11/compress.c \ $$OFFICEUTILS_PATH/src/zlib_addon.c - CONFIG += config_zlip_image + CONFIG += config_zlip_image } diff --git a/DesktopEditor/graphics/shading_info.h b/DesktopEditor/graphics/shading_info.h index 4ea5cc9b237..6ab27759f13 100644 --- a/DesktopEditor/graphics/shading_info.h +++ b/DesktopEditor/graphics/shading_info.h @@ -35,6 +35,7 @@ #include "../agg-2.4/include/agg_color_rgba.h" #include "../graphics/aggplustypes.h" +#include "../graphics/Matrix.h" #ifndef M_PI #define M_PI 3.14159265358979323846 @@ -102,6 +103,23 @@ namespace NSStructures } } + void set_x_min(float x_min) + { + x_domain_min = x_min; + } + void set_x_max(float x_max) + { + x_domain_max = x_max; + } + void set_y_min(float y_min) + { + y_domain_min = y_min; + } + void set_y_max(float y_max) + { + y_domain_max = y_max; + } + float get_x_min() { return x_domain_min; @@ -386,6 +404,89 @@ namespace NSStructures { discrete_step = 1.0f / n; } + void transform(const Aggplus::CMatrix& matrix) + { + // shading transform + auto& point1 = shading.point1; + auto& point2 = shading.point2; + + double point1_x = static_cast(point1.x); + double point1_y = static_cast(point1.y); + double point2_x = static_cast(point2.x); + double point2_y = static_cast(point2.y); + + matrix.TransformPoint(point1_x, point1_y); + matrix.TransformPoint(point2_x, point2_y); + + point1.x = static_cast(point1_x); + point1.y = static_cast(point1_y); + point2.x = static_cast(point2_x); + point2.y = static_cast(point2_y); + + // triangle transform + for (auto& p : shading.triangle) + { + double triangle_x = static_cast(p.x); + double triangle_y = static_cast(p.y); + + matrix.TransformPoint(triangle_x, triangle_y); + + p.x = static_cast(triangle_x); + p.y = static_cast(triangle_y); + } + + // domains transform + double x_domain_min = static_cast(shading.function.get_x_min()); + double y_domain_min = static_cast(shading.function.get_y_min()); + double x_domain_max = static_cast(shading.function.get_x_max()); + double y_domain_max = static_cast(shading.function.get_y_max()); + + matrix.TransformPoint(x_domain_min, y_domain_min); + matrix.TransformPoint(x_domain_max, y_domain_max); + + shading.function.set_x_min(static_cast(x_domain_min)); + shading.function.set_y_min(static_cast(y_domain_min)); + shading.function.set_x_max(static_cast(x_domain_max)); + shading.function.set_y_max(static_cast(y_domain_max)); + + // center transform + double center_x = static_cast(centerX); + double center_y = static_cast(centerY); + + matrix.TransformPoint(center_x, center_y); + + double p0_x = static_cast(p0.x); + double p0_y = static_cast(p0.y); + double p1_x = static_cast(p1.x); + double p1_y = static_cast(p1.y); + + matrix.TransformPoint(p0_x, p0_y); + matrix.TransformPoint(p1_x, p1_y); + + p0.x = static_cast(p0_x); + p0.y = static_cast(p0_y); + p1.x = static_cast(p1_x); + p1.y = static_cast(p1_y); + + for (size_t i = 0; i < shading.patch.size(); ++i) + { + for (size_t j = 0; j < shading.patch[i].size(); ++j) + { + double patch_x = static_cast(shading.patch[i][j].x); + double patch_y = static_cast(shading.patch[i][j].y); + + matrix.TransformPoint(patch_x, patch_y); + + shading.patch[i][j].x = static_cast(patch_x); + shading.patch[i][j].y = static_cast(patch_y); + } + } + + // sizes scale + double sqrt_det = sqrt(fabs(matrix.Determinant())); + r0 *= sqrt_det; + r1 *= sqrt_det; + } Point p0, p1; float r0, r1; @@ -468,14 +569,14 @@ namespace NSStructures { GradientInfo ginfo; ginfo.shading.triangle = points; + ginfo.shading.shading_type = ShadingInfo::Parametric; + ginfo.shading.function = ColorFunction(256, t0, t1); + ginfo.continue_shading_f = false; + ginfo.continue_shading_b = false; if (parametric) { ginfo.shading.triangle_parameters = params; - ginfo.shading.f_type = ShadingInfo::UseNew; - ginfo.shading.function = ColorFunction(256, t0, t1); ginfo.shading.shading_type = ShadingInfo::Parametric; - ginfo.continue_shading_f = false; - ginfo.continue_shading_b = false; } else { @@ -513,7 +614,10 @@ namespace NSStructures ginfo.shading.patch[2][0] = curve_points[10]; ginfo.shading.patch[1][0] = curve_points[11]; - + ginfo.shading.f_type = ShadingInfo::UseNew; + ginfo.shading.function = ColorFunction(256, t0, t1); + ginfo.continue_shading_f = false; + ginfo.continue_shading_b = false; if (parametric) { @@ -522,11 +626,7 @@ namespace NSStructures ginfo.shading.patch_parameters[0][1] = curve_parametrs[1]; ginfo.shading.patch_parameters[1][0] = curve_parametrs[3]; ginfo.shading.patch_parameters[1][1] = curve_parametrs[2]; - ginfo.shading.f_type = ShadingInfo::UseNew; - ginfo.shading.function = ColorFunction(256, t0, t1); ginfo.shading.shading_type = ShadingInfo::Parametric; - ginfo.continue_shading_f = false; - ginfo.continue_shading_b = false; } else { @@ -549,14 +649,15 @@ namespace NSStructures ginfo.shading.patch = curve_poits; + ginfo.shading.f_type = ShadingInfo::UseNew; + ginfo.shading.function = ColorFunction(256, t0, t1); + ginfo.continue_shading_f = false; + ginfo.continue_shading_b = false; + if (parametric) { ginfo.shading.patch_parameters = curve_parametrs; - ginfo.shading.f_type = ShadingInfo::UseNew; - ginfo.shading.function = ColorFunction(256, t0, t1); ginfo.shading.shading_type = ShadingInfo::Parametric; - ginfo.continue_shading_f = false; - ginfo.continue_shading_b = false; } else { diff --git a/DesktopEditor/graphics/structures.h b/DesktopEditor/graphics/structures.h index c32a946028c..532c27e193a 100644 --- a/DesktopEditor/graphics/structures.h +++ b/DesktopEditor/graphics/structures.h @@ -442,6 +442,8 @@ namespace NSStructures Alpha2 = other.Alpha2; Image = other.Image; + if (Image) + ((IGrObject*)Image)->AddRef(); Transform = other.Transform; TexturePath = other.TexturePath; diff --git a/DesktopEditor/graphics/tests/BooleanOperations_Unit-tests/BooleanOperations_Unit-tests.pro b/DesktopEditor/graphics/tests/BooleanOperations_Unit-tests/BooleanOperations_Unit-tests.pro new file mode 100644 index 00000000000..b737cb0063d --- /dev/null +++ b/DesktopEditor/graphics/tests/BooleanOperations_Unit-tests/BooleanOperations_Unit-tests.pro @@ -0,0 +1,17 @@ +include(../../../../Common/3dParty/googletest/googletest.pri) + +TEMPLATE = app +CONFIG += console c++14 +CONFIG -= app_bundle +CONFIG += thread +CONFIG -= qt + +SOURCES += \ + tst_booleanoperations.cpp + +PWD_ROOT_DIR = $$PWD +CORE_ROOT_DIR = $$PWD/../../../../../core +include($$CORE_ROOT_DIR/Common/base.pri) + +ADD_DEPENDENCY(kernel, graphics, UnicodeConverter) +include($$CORE_ROOT_DIR/Common/3dParty/icu/icu.pri) diff --git a/DesktopEditor/graphics/tests/BooleanOperations_Unit-tests/gtest_dependency.pri b/DesktopEditor/graphics/tests/BooleanOperations_Unit-tests/gtest_dependency.pri new file mode 100644 index 00000000000..cfd67da53ac --- /dev/null +++ b/DesktopEditor/graphics/tests/BooleanOperations_Unit-tests/gtest_dependency.pri @@ -0,0 +1,17 @@ +isEmpty(GOOGLETEST_DIR):GOOGLETEST_DIR=$$(GOOGLETEST_DIR) + +isEmpty(GOOGLETEST_DIR) { + GOOGLETEST_DIR = "" + !isEmpty(GOOGLETEST_DIR) { + warning("Using googletest src dir specified at Qt Creator wizard") + message("set GOOGLETEST_DIR as environment variable or qmake variable to get rid of this message") + } +} + +!isEmpty(GOOGLETEST_DIR): { + INCLUDEPATH *= "$$GOOGLETEST_DIR/include" + + LIBS *= -L"$$GOOGLETEST_DIR/lib" -lgtest -lgmock +} else { + LIBS *= -lgtest -lgmock +} diff --git a/DesktopEditor/graphics/tests/BooleanOperations_Unit-tests/tst_booleanoperations.cpp b/DesktopEditor/graphics/tests/BooleanOperations_Unit-tests/tst_booleanoperations.cpp new file mode 100644 index 00000000000..2cdb0f06b64 --- /dev/null +++ b/DesktopEditor/graphics/tests/BooleanOperations_Unit-tests/tst_booleanoperations.cpp @@ -0,0 +1,459 @@ + +//#include +#include +#include "../../GraphicsPath.h" + +using namespace testing; + +TEST(BooleanOperations, NoIntersOutside) +{ + Aggplus::CGraphicsPath path1, path2, resultIntersect, resultUnite, resultSubtract; + + path1.StartFigure(); + path1.MoveTo(100.0, 100.0); + path1.LineTo(100.0, 200.0); + path1.LineTo(200.0, 200.0); + path1.LineTo(200.0, 100.0); + path1.LineTo(100.0, 100.0); + path1.CloseFigure(); + + path2.StartFigure(); + path2.MoveTo(300.0, 300.0); + path2.LineTo(300.0, 400.0); + path2.LineTo(400.0, 400.0); + path2.LineTo(400.0, 300.0); + path2.LineTo(300.0, 300.0); + path2.CloseFigure(); + + resultIntersect.StartFigure(); + resultIntersect.CloseFigure(); + + resultUnite.StartFigure(); + resultUnite.MoveTo(100.0, 100.0); + resultUnite.LineTo(100.0, 200.0); + resultUnite.LineTo(200.0, 200.0); + resultUnite.LineTo(200.0, 100.0); + resultUnite.LineTo(100.0, 100.0); + resultUnite.MoveTo(300.0, 300.0); + resultUnite.LineTo(300.0, 400.0); + resultUnite.LineTo(400.0, 400.0); + resultUnite.LineTo(400.0, 300.0); + resultUnite.LineTo(300.0, 300.0); + resultUnite.CloseFigure(); + + resultSubtract.StartFigure(); + resultSubtract.MoveTo(100.0, 100.0); + resultSubtract.LineTo(100.0, 200.0); + resultSubtract.LineTo(200.0, 200.0); + resultSubtract.LineTo(200.0, 100.0); + resultSubtract.LineTo(100.0, 100.0); + resultSubtract.CloseFigure(); + + + EXPECT_TRUE(Aggplus::CalcBooleanOperation(path1, path2, Aggplus::Intersection) == resultIntersect); + EXPECT_TRUE(Aggplus::CalcBooleanOperation(path1, path2, Aggplus::Union) == resultUnite); + EXPECT_TRUE(Aggplus::CalcBooleanOperation(path1, path2, Aggplus::Subtraction) == resultSubtract); +} + +TEST(BooleanOperations, NoIntersInside) +{ + Aggplus::CGraphicsPath path1, path2, resultIntersect, resultUnite, resultSubtract; + + path1.StartFigure(); + path1.MoveTo(100.0, 100.0); + path1.LineTo(100.0, 400.0); + path1.LineTo(400.0, 400.0); + path1.LineTo(400.0, 100.0); + path1.LineTo(100.0, 100.0); + path1.CloseFigure(); + + path2.StartFigure(); + path2.MoveTo(300.0, 300.0); + path2.LineTo(300.0, 200.0); + path2.LineTo(200.0, 200.0); + path2.LineTo(200.0, 300.0); + path2.LineTo(300.0, 300.0); + path2.CloseFigure(); + + resultIntersect.StartFigure(); + resultIntersect.MoveTo(300.0, 300.0); + resultIntersect.LineTo(300.0, 200.0); + resultIntersect.LineTo(200.0, 200.0); + resultIntersect.LineTo(200.0, 300.0); + resultIntersect.LineTo(300.0, 300.0); + resultIntersect.CloseFigure(); + + resultUnite.StartFigure(); + resultUnite.MoveTo(100.0, 100.0); + resultUnite.LineTo(100.0, 400.0); + resultUnite.LineTo(400.0, 400.0); + resultUnite.LineTo(400.0, 100.0); + resultUnite.LineTo(100.0, 100.0); + resultUnite.CloseFigure(); + + resultSubtract.StartFigure(); + resultSubtract.MoveTo(100.0, 100.0); + resultSubtract.LineTo(100.0, 400.0); + resultSubtract.LineTo(400.0, 400.0); + resultSubtract.LineTo(400.0, 100.0); + resultSubtract.LineTo(100.0, 100.0); + resultSubtract.MoveTo(300.0, 300.0); + resultSubtract.LineTo(200.0, 300.0); + resultSubtract.LineTo(200.0, 200.0); + resultSubtract.LineTo(300.0, 200.0); + resultSubtract.LineTo(300.0, 300.0); + resultSubtract.CloseFigure(); + + + EXPECT_TRUE(Aggplus::CalcBooleanOperation(path1, path2, Aggplus::Intersection) == resultIntersect); + EXPECT_TRUE(Aggplus::CalcBooleanOperation(path1, path2, Aggplus::Union) == resultUnite); + EXPECT_TRUE(Aggplus::CalcBooleanOperation(path1, path2, Aggplus::Subtraction) == resultSubtract); +} + +TEST(BooleanOperations, OneIntersOutside) +{ + Aggplus::CGraphicsPath path1, path2, resultIntersect, resultUnite, resultSubtract; + + path1.StartFigure(); + path1.MoveTo(100.0, 100.0); + path1.LineTo(100.0, 200.0); + path1.LineTo(200.0, 200.0); + path1.LineTo(200.0, 100.0); + path1.LineTo(100.0, 100.0); + path1.CloseFigure(); + + path2.StartFigure(); + path2.MoveTo(200.0, 150.0); + path2.LineTo(300.0, 150.0); + path2.LineTo(250.0, 200.0); + path2.LineTo(200.0, 150.0); + path2.CloseFigure(); + + resultIntersect.StartFigure(); + resultIntersect.MoveTo(200.0, 150.0); + resultIntersect.CloseFigure(); + + resultUnite.StartFigure(); + resultUnite.MoveTo(100.0, 100.0); + resultUnite.LineTo(100.0, 200.0); + resultUnite.LineTo(200.0, 200.0); + resultUnite.LineTo(200.0, 150.0); + resultUnite.LineTo(250.0, 200.0); + resultUnite.LineTo(300.0, 150.0); + resultUnite.LineTo(200.0, 150.0); + resultUnite.LineTo(200.0, 100.0); + resultUnite.LineTo(100.0, 100.0); + resultUnite.CloseFigure(); + + resultSubtract.StartFigure(); + resultSubtract.MoveTo(100.0, 100.0); + resultSubtract.LineTo(100.0, 200.0); + resultSubtract.LineTo(200.0, 200.0); + resultSubtract.LineTo(200.0, 100.0); + resultSubtract.LineTo(100.0, 100.0); + resultSubtract.CloseFigure(); + + + EXPECT_TRUE(Aggplus::CalcBooleanOperation(path1, path2, Aggplus::Intersection) == resultIntersect); + EXPECT_TRUE(Aggplus::CalcBooleanOperation(path1, path2, Aggplus::Union) == resultUnite); + EXPECT_TRUE(Aggplus::CalcBooleanOperation(path1, path2, Aggplus::Subtraction) == resultSubtract); +} + +TEST(BooleanOperations, OneIntersInside) +{ + Aggplus::CGraphicsPath path1, path2, resultIntersect, resultUnite, resultSubtract; + + path1.StartFigure(); + path1.MoveTo(100.0, 100.0); + path1.LineTo(100.0, 200.0); + path1.LineTo(200.0, 200.0); + path1.LineTo(200.0, 100.0); + path1.LineTo(100.0, 100.0); + path1.CloseFigure(); + + path2.StartFigure(); + path2.MoveTo(200.0, 150.0); + path2.LineTo(150.0, 150.0); + path2.LineTo(175.0, 175.0); + path2.LineTo(200.0, 150.0); + path2.CloseFigure(); + + resultIntersect.StartFigure(); + resultIntersect.MoveTo(200.0, 150.0); + resultIntersect.LineTo(150.0, 150.0); + resultIntersect.LineTo(175.0, 175.0); + resultIntersect.LineTo(200.0, 150.0); + resultIntersect.CloseFigure(); + + resultUnite.StartFigure(); + resultUnite.MoveTo(100.0, 100.0); + resultUnite.LineTo(100.0, 200.0); + resultUnite.LineTo(200.0, 200.0); + resultUnite.LineTo(200.0, 100.0); + resultUnite.LineTo(100.0, 100.0); + resultUnite.CloseFigure(); + + resultSubtract.StartFigure(); + resultSubtract.MoveTo(100.0, 100.0); + resultSubtract.LineTo(100.0, 200.0); + resultSubtract.LineTo(200.0, 200.0); + resultSubtract.LineTo(200.0, 150.0); + resultSubtract.LineTo(175.0, 175.0); + resultSubtract.LineTo(150.0, 150.0); + resultSubtract.LineTo(200.0, 150.0); + resultSubtract.LineTo(200.0, 100.0); + resultSubtract.LineTo(100.0, 100.0); + resultSubtract.CloseFigure(); + + + EXPECT_TRUE(Aggplus::CalcBooleanOperation(path1, path2, Aggplus::Intersection) == resultIntersect); + EXPECT_TRUE(Aggplus::CalcBooleanOperation(path1, path2, Aggplus::Union) == resultUnite); + EXPECT_TRUE(Aggplus::CalcBooleanOperation(path1, path2, Aggplus::Subtraction) == resultSubtract); +} + +TEST(BooleanOperations, OverlapOutside) +{ + Aggplus::CGraphicsPath path1, path2, resultIntersect, resultUnite, resultSubtract; + + path1.StartFigure(); + path1.MoveTo(100.0, 100.0); + path1.LineTo(100.0, 300.0); + path1.LineTo(300.0, 300.0); + path1.LineTo(300.0, 100.0); + path1.LineTo(100.0, 100.0); + path1.CloseFigure(); + + path2.StartFigure(); + path2.MoveTo(300.0, 200.0); + path2.LineTo(300.0, 400.0); + path2.LineTo(400.0, 400.0); + path2.LineTo(400.0, 200.0); + path2.LineTo(300.0, 200.0); + path2.CloseFigure(); + + resultIntersect.StartFigure(); + resultIntersect.MoveTo(300.0, 300.0); + resultIntersect.LineTo(300.0, 200.0); + resultIntersect.LineTo(300.0, 300.0); + resultIntersect.CloseFigure(); + + resultUnite.StartFigure(); + resultUnite.MoveTo(100.0, 100.0); + resultUnite.LineTo(100.0, 300.0); + resultUnite.LineTo(300.0, 300.0); + resultUnite.LineTo(300.0, 400.0); + resultUnite.LineTo(400.0, 400.0); + resultUnite.LineTo(400.0, 200.0); + resultUnite.LineTo(300.0, 200.0); + resultUnite.LineTo(300.0, 100.0); + resultUnite.LineTo(100.0, 100.0); + resultUnite.CloseFigure(); + + resultSubtract.StartFigure(); + resultSubtract.MoveTo(100.0, 100.0); + resultSubtract.LineTo(100.0, 300.0); + resultSubtract.LineTo(300.0, 300.0); + resultSubtract.LineTo(300.0, 100.0); + resultSubtract.LineTo(100.0, 100.0); + resultSubtract.CloseFigure(); + + + EXPECT_TRUE(Aggplus::CalcBooleanOperation(path1, path2, Aggplus::Intersection) == resultIntersect); + EXPECT_TRUE(Aggplus::CalcBooleanOperation(path1, path2, Aggplus::Union) == resultUnite); + EXPECT_TRUE(Aggplus::CalcBooleanOperation(path1, path2, Aggplus::Subtraction) == resultSubtract); +} + +TEST(BooleanOperations, OverlapInside) +{ + Aggplus::CGraphicsPath path1, path2, resultIntersect, resultUnite, resultSubtract; + + path1.StartFigure(); + path1.MoveTo(100.0, 100.0); + path1.LineTo(100.0, 400.0); + path1.LineTo(400.0, 400.0); + path1.LineTo(400.0, 100.0); + path1.LineTo(100.0, 100.0); + path1.CloseFigure(); + + path2.StartFigure(); + path2.MoveTo(200.0, 200.0); + path2.LineTo(400.0, 200.0); + path2.LineTo(400.0, 300.0); + path2.LineTo(200.0, 300.0); + path2.LineTo(200.0, 200.0); + path2.CloseFigure(); + + resultIntersect.StartFigure(); + resultIntersect.MoveTo(400.0, 300.0); + resultIntersect.LineTo(400.0, 200.0); + resultIntersect.LineTo(200.0, 200.0); + resultIntersect.LineTo(200.0, 300.0); + resultIntersect.LineTo(400.0, 300.0); + resultIntersect.CloseFigure(); + + resultUnite.StartFigure(); + resultUnite.MoveTo(100.0, 100.0); + resultUnite.LineTo(100.0, 400.0); + resultUnite.LineTo(400.0, 400.0); + resultUnite.LineTo(400.0, 100.0); + resultUnite.LineTo(100.0, 100.0); + resultUnite.CloseFigure(); + + resultSubtract.StartFigure(); + resultSubtract.MoveTo(100.0, 100.0); + resultSubtract.LineTo(100.0, 400.0); + resultSubtract.LineTo(400.0, 400.0); + resultSubtract.LineTo(400.0, 300.0); + resultSubtract.LineTo(200.0, 300.0); + resultSubtract.LineTo(200.0, 200.0); + resultSubtract.LineTo(400.0, 200.0); + resultSubtract.LineTo(400.0, 100.0); + resultSubtract.LineTo(100.0, 100.0); + resultSubtract.CloseFigure(); + + + EXPECT_TRUE(Aggplus::CalcBooleanOperation(path1, path2, Aggplus::Intersection) == resultIntersect); + EXPECT_TRUE(Aggplus::CalcBooleanOperation(path1, path2, Aggplus::Union) == resultUnite); + EXPECT_TRUE(Aggplus::CalcBooleanOperation(path1, path2, Aggplus::Subtraction) == resultSubtract); +} + +TEST(BooleanOperations, LineIntersLine) +{ + Aggplus::CGraphicsPath path1, path2, resultIntersect, resultUnite, resultSubtract; + + path1.StartFigure(); + path1.MoveTo(100.0, 100.0); + path1.LineTo(100.0, 300.0); + path1.LineTo(300.0, 300.0); + path1.LineTo(300.0, 100.0); + path1.LineTo(100.0, 100.0); + path1.CloseFigure(); + + path2.StartFigure(); + path2.MoveTo(200.0, 200.0); + path2.LineTo(400.0, 200.0); + path2.LineTo(400.0, 400.0); + path2.LineTo(200.0, 400.0); + path2.LineTo(200.0, 200.0); + path2.CloseFigure(); + + resultIntersect.StartFigure(); + resultIntersect.MoveTo(200.0, 300.0); + resultIntersect.LineTo(300.0, 300.0); + resultIntersect.LineTo(300.0, 200.0); + resultIntersect.LineTo(200.0, 200.0); + resultIntersect.LineTo(200.0, 300.0); + resultIntersect.CloseFigure(); + + resultUnite.StartFigure(); + resultUnite.MoveTo(100.0, 100.0); + resultUnite.LineTo(100.0, 300.0); + resultUnite.LineTo(200.0, 300.0); + resultUnite.LineTo(200.0, 400.0); + resultUnite.LineTo(400.0, 400.0); + resultUnite.LineTo(400.0, 200.0); + resultUnite.LineTo(300.0, 200.0); + resultUnite.LineTo(300.0, 100.0); + resultUnite.LineTo(100.0, 100.0); + resultUnite.CloseFigure(); + + resultSubtract.StartFigure(); + resultSubtract.MoveTo(100.0, 100.0); + resultSubtract.LineTo(100.0, 300.0); + resultSubtract.LineTo(200.0, 300.0); + resultSubtract.LineTo(200.0, 200.0); + resultSubtract.LineTo(300.0, 200.0); + resultSubtract.LineTo(300.0, 100.0); + resultSubtract.LineTo(100.0, 100.0); + resultSubtract.CloseFigure(); + + + EXPECT_TRUE(Aggplus::CalcBooleanOperation(path1, path2, Aggplus::Intersection) == resultIntersect); + EXPECT_TRUE(Aggplus::CalcBooleanOperation(path1, path2, Aggplus::Union) == resultUnite); + EXPECT_TRUE(Aggplus::CalcBooleanOperation(path1, path2, Aggplus::Subtraction) == resultSubtract); +} + +TEST(BooleanOperations, CurveIntersLine) +{ + Aggplus::CGraphicsPath path1, path2, resultIntersect, resultUnite, resultSubtract; + + path1.AddEllipse(-300.0, -300.0, 200.0, 200.0); + + path2.StartFigure(); + path2.MoveTo(-200.0, -200.0); + path2.LineTo(0.0, -200.0); + path2.LineTo(0.0, 0.0); + path2.LineTo(-200.0, 0.0); + path2.LineTo(-200.0, -200.0); + path2.CloseFigure(); + + resultIntersect.StartFigure(); + resultIntersect.MoveTo(-100.0, -200.0); + resultIntersect.CurveTo(-100.0, -144.772, -144.772, -100.0, -200.0, -100.0); + resultIntersect.LineTo(-200.0, -200.0); + resultIntersect.LineTo(-100.0, -200.0); + resultIntersect.CloseFigure(); + + resultUnite.StartFigure(); + resultUnite.MoveTo(-100.0, -200.0); + resultUnite.LineTo(0.0, -200.0); + resultUnite.LineTo(0.0, 0.0); + resultUnite.LineTo(-200.0, 0.0); + resultUnite.LineTo(-200.0, -100.0); + resultUnite.CurveTo(-255.228, -100.0, -300.0, -144.772, -300.0, -200.0); + resultUnite.CurveTo(-300.0, -255.228, -255.228, -300.0, -200.0, -300.0); + resultUnite.CurveTo(-144.772, -300.0, -100.0, -255.228, -100.0, -200.0); + resultUnite.CloseFigure(); + + resultSubtract.StartFigure(); + resultSubtract.MoveTo(-100.0, -200.0); + resultSubtract.LineTo(-200.0, -200.0); + resultSubtract.LineTo(-200.0, -100.0); + resultSubtract.CurveTo(-255.228, -100.0, -300.0, -144.772, -300.0, -200.0); + resultSubtract.CurveTo(-300.0, -255.228, -255.228, -300.0, -200.0, -300.0); + resultSubtract.CurveTo(-144.772, -300.0, -100.0, -255.228, -100.0, -200.0); + resultSubtract.CloseFigure(); + + + EXPECT_TRUE(Aggplus::CalcBooleanOperation(path1, path2, Aggplus::Intersection) == resultIntersect); + EXPECT_TRUE(Aggplus::CalcBooleanOperation(path1, path2, Aggplus::Union) == resultUnite); + EXPECT_TRUE(Aggplus::CalcBooleanOperation(path1, path2, Aggplus::Subtraction) == resultSubtract); +} + +TEST(BooleanOperations, CurveIntersCurve) +{ + Aggplus::CGraphicsPath path1, path2, resultIntersect, resultUnite, resultSubtract; + + path1.AddEllipse(-300.0, -300.0, 200.0, 200.0); + + path2.AddEllipse(-200.0, -200.0, 200.0, 200.0); + + resultIntersect.StartFigure(); + resultIntersect.MoveTo(-100.0, -200.0); + resultIntersect.CurveTo(-100.0, -144.772, -144.772, -100.0, -200.0, -100.0); + resultIntersect.CurveTo(-200.0, -155.228, -155.228, -200.0, -100.0, -200.0); + resultIntersect.CloseFigure(); + + resultUnite.StartFigure(); + resultUnite.MoveTo(-100.0, -200.0); + resultUnite.CurveTo(-44.772, -200.0, 0.0, -155.228, 0.0, -100.0); + resultUnite.CurveTo(0.0, -44.772, -44.772, 0.0, -100.0, 0.0); + resultUnite.CurveTo(-155.228, 0.0, -200.0, -44.772, -200.0, -100.0); + resultUnite.CurveTo(-255.228, -100.0, -300.0, -144.772, -300.0, -200.0); + resultUnite.CurveTo(-300.0, -255.228, -255.228, -300.0, -200.0, -300.0); + resultUnite.CurveTo(-144.772, -300.0, -100.0, -255.228, -100.0, -200.0); + resultUnite.CloseFigure(); + + resultSubtract.StartFigure(); + resultSubtract.MoveTo(-100.0, -200.0); + resultSubtract.CurveTo(-155.228, -200.0, -200.0, -155.228, -200.0, -100.0); + resultSubtract.CurveTo(-255.228, -100.0, -300.0, -144.772, -300.0, -200.0); + resultSubtract.CurveTo(-300.0, -255.228, -255.228, -300.0, -200.0, -300.0); + resultSubtract.CurveTo(-144.772, -300.0, -100.0, -255.228, -100.0, -200.0); + resultSubtract.CloseFigure(); + + + EXPECT_TRUE(Aggplus::CalcBooleanOperation(path1, path2, Aggplus::Intersection) == resultIntersect); + EXPECT_TRUE(Aggplus::CalcBooleanOperation(path1, path2, Aggplus::Union) == resultUnite); + EXPECT_TRUE(Aggplus::CalcBooleanOperation(path1, path2, Aggplus::Subtraction) == resultSubtract); +} diff --git a/DesktopEditor/graphics/tests/TestPICT/TestPICT.pro b/DesktopEditor/graphics/tests/TestPICT/TestPICT.pro new file mode 100644 index 00000000000..2787314412d --- /dev/null +++ b/DesktopEditor/graphics/tests/TestPICT/TestPICT.pro @@ -0,0 +1,26 @@ +#CONFIG += c++11 cmdline + +#SOURCES += \ +QT -= core + +QT -= gui + +TARGET = test +CONFIG += console +TEMPLATE = app + +CORE_ROOT_DIR = $$PWD/../../../.. +PWD_ROOT_DIR = $$PWD +include($$CORE_ROOT_DIR/Common/base.pri) +include($$CORE_ROOT_DIR/Common/3dParty/icu/icu.pri) + +ADD_DEPENDENCY(kernel, graphics, UnicodeConverter) + +GRAPHICS_AGG_PATH = $$PWD/../../../agg-2.4 + +INCLUDEPATH += \ + $$GRAPHICS_AGG_PATH/include + +SOURCES += main.cpp + +DESTDIR = $$PWD_ROOT_DIR/build/$$CORE_BUILDS_PLATFORM_PREFIX/$$CORE_BUILDS_CONFIGURATION_PREFIX diff --git a/DesktopEditor/graphics/tests/TestPICT/main.cpp b/DesktopEditor/graphics/tests/TestPICT/main.cpp new file mode 100644 index 00000000000..b0848dc9cbc --- /dev/null +++ b/DesktopEditor/graphics/tests/TestPICT/main.cpp @@ -0,0 +1,11 @@ +#include + +#include "../../pro/Graphics.h" + +int main(int argc, char *argv[]) +{ + Aggplus::CImage Cimg(std::wstring_convert>().from_bytes(argv[1])); + Cimg.SaveFile(std::wstring_convert>().from_bytes(argv[2]), 1); + + return 0; +} diff --git a/DesktopEditor/graphics/tests/alphaMask/main.cpp b/DesktopEditor/graphics/tests/alphaMask/main.cpp index fe424b0896d..fc3d30abb3c 100644 --- a/DesktopEditor/graphics/tests/alphaMask/main.cpp +++ b/DesktopEditor/graphics/tests/alphaMask/main.cpp @@ -71,7 +71,9 @@ int main(int argc, char *argv[]) { Aggplus::CAlphaMask* pAlphaMask = new Aggplus::CAlphaMask(); - BYTE* pAlphaBuffer = new BYTE[unWidth * unHeight]; + pAlphaMask->Create(unWidth, unHeight, Aggplus::EMaskDataType::AlphaBuffer); + + BYTE* pAlphaBuffer = pAlphaMask->GetBuffer(); BYTE uchAlphaValue = 0; @@ -84,8 +86,6 @@ int main(int argc, char *argv[]) uchAlphaValue += 25; } - pAlphaMask->LoadFromAlphaBuffer(pAlphaBuffer, unWidth, unHeight, false); - pRasterRenderer->SetAlphaMask(pAlphaMask); pAlphaMask->Release(); diff --git a/X2tConverter/test/batch_convert/x2t_test/main.cpp b/DesktopEditor/graphics/tests/booleanPaths/main.cpp similarity index 50% rename from X2tConverter/test/batch_convert/x2t_test/main.cpp rename to DesktopEditor/graphics/tests/booleanPaths/main.cpp index b48f94ec827..1cd93da318b 100644 --- a/X2tConverter/test/batch_convert/x2t_test/main.cpp +++ b/DesktopEditor/graphics/tests/booleanPaths/main.cpp @@ -1,11 +1,11 @@ #include "mainwindow.h" + #include int main(int argc, char *argv[]) { - QApplication a(argc, argv); - MainWindow w; - w.show(); - - return a.exec(); + QApplication a(argc, argv); + MainWindow w; + w.show(); + return a.exec(); } diff --git a/DesktopEditor/graphics/tests/booleanPaths/mainwindow.cpp b/DesktopEditor/graphics/tests/booleanPaths/mainwindow.cpp new file mode 100644 index 00000000000..7f1fb3f591e --- /dev/null +++ b/DesktopEditor/graphics/tests/booleanPaths/mainwindow.cpp @@ -0,0 +1,396 @@ +#include "mainwindow.h" +#include "ui_mainwindow.h" +#include + +CustomLabel::CustomLabel(QWidget *parent) : QLabel(parent) +{ + setMouseTracking(true); +} + +QPointF CustomLabel::GetStartPoint() const noexcept +{ + return StartP; +} + +double CustomLabel::GetDifferenceX() const noexcept +{ + return CurrP.x() - StartP.x(); +} + +double CustomLabel::GetDifferenceY() const noexcept +{ + return CurrP.y() - StartP.y(); +} + +bool CustomLabel::GetMovable() const noexcept +{ + return Movable; +} + +void CustomLabel::mousePressEvent(QMouseEvent *event) +{ + StartP = event->pos(); + Movable = true; + emit mousePress(); +} + +void CustomLabel::mouseReleaseEvent(QMouseEvent *event) +{ + CurrP = event->pos(); + Movable = false; + emit mousePress(); +} + +void CustomLabel::mouseMoveEvent(QMouseEvent *event) +{ + CurrP = event->pos(); + emit mouseMove(); +} + +CustomButton::CustomButton(QWidget *parent) : QPushButton(parent) +{ +} + +BooleanButton::BooleanButton(QWidget *parent) : QPushButton(parent) +{ +} + +std::vector GetChildsByClassName(QObject* parent, const QString& name) +{ + std::vector res; + foreach (QObject* child, parent->children()) + { + if (QString(child->metaObject()->className()) == name) + res.push_back(child); + else + { + if (!child->children().empty()) + { + std::vector resChilds = GetChildsByClassName(child, name); + res.insert(res.end(), resChilds.begin(), resChilds.end()); + } + } + } + return res; +} + +MainWindow::MainWindow(QWidget *parent) + : QMainWindow(parent) + , ui(new Ui::MainWindow) +{ + ui->setupUi(this); + + Figure1 = ""; + Figure2 = ""; + Op = Aggplus::Intersection; + + std::vector arrPathButtons = GetChildsByClassName(this, "CustomButton"); + std::vector arrBooleanButtons = GetChildsByClassName(this, "BooleanButton"); + + for (std::vector::iterator i = arrPathButtons.begin(); i != arrPathButtons.end(); i++) + connect((QPushButton*)(*i), &QPushButton::clicked, this, &MainWindow::SetFigure); + + for (std::vector::iterator i = arrBooleanButtons.begin(); i != arrBooleanButtons.end(); i++) + connect((QPushButton*)(*i), &QPushButton::clicked, this, &MainWindow::SetCommand); + + Path1.StartFigure(); + Path1.MoveTo(100.0, 100.0); + Path1.LineTo(150.0, 150.0); + Path1.LineTo(200.0, 150.0); + Path1.LineTo(100.0, 100.0); + Path1.CloseFigure(); + Path1.MoveTo(300.0, 300.0); + Path1.LineTo(400.0, 300.0); + Path1.LineTo(400.0, 400.0); + Path1.LineTo(300.0, 400.0); + Path1.LineTo(300.0, 300.0); + Path1.CloseFigure(); + + Path2.StartFigure(); + Path2.MoveTo(100.0, 125.0); + Path2.LineTo(100.0, 350.0); + Path2.LineTo(350.0, 350.0); + Path2.LineTo(350.0, 125.0); + Path2.LineTo(100.0, 125.0); + Path2.CloseFigure(); + + Result = Aggplus::CalcBooleanOperation(Path1, Path2, Aggplus::Intersection); + Draw(true); +} + +void MainWindow::SetFigure() +{ + QPushButton* sender = (QPushButton*)this->sender(); + + if (((QGroupBox*)sender->parentWidget())->title() == "Path1") + { + Figure1 = sender->text(); + DrawPath1(); + } + + if (((QGroupBox*)sender->parentWidget())->title() == "Path2") + { + Figure2 = sender->text(); + DrawPath2(); + } +} + +void MainWindow::SetCommand() +{ + QString text = ((QPushButton*)sender())->text(); + if (text == "Unite") + Op = Aggplus::Union; + else if (text == "Intersect") + Op = Aggplus::Intersection; + else + Op = Aggplus::Subtraction; + + BooleanOp(); +} + +MainWindow::~MainWindow() +{ + delete ui; +} + +Aggplus::CGraphicsPath MainWindow::SetPath(double scale, double offsetX, double offsetY, QString Figure) +{ + Aggplus::CGraphicsPath path; + + path.StartFigure(); + if (Figure == "Rectangle") + { + path.MoveTo(RECTANGLE[0] + offsetX, + RECTANGLE[1] + offsetY); + path.LineTo(RECTANGLE[0] + scale * RECTANGLE[2] + offsetX, + RECTANGLE[1] + offsetY); + path.LineTo(RECTANGLE[0] + scale * RECTANGLE[2] + offsetX, + RECTANGLE[1] + scale * RECTANGLE[3] + offsetY); + path.LineTo(RECTANGLE[0] + offsetX, + RECTANGLE[1] + scale * RECTANGLE[3] + offsetY); + path.LineTo(RECTANGLE[0] + offsetX, + RECTANGLE[1] + offsetY); + } + else if (Figure == "Ellipse") + { + path.AddEllipse(RECTANGLE[0] + offsetX, + RECTANGLE[1] + offsetY, + scale * RECTANGLE[2], + scale * RECTANGLE[3]); + } + else if (Figure == "Triangle") + { + path.MoveTo(TRIANGLE[0] + offsetX, + TRIANGLE[1] + offsetY); + for (size_t i = 2; i < std::size(TRIANGLE); i += 2) + path.LineTo(TRIANGLE[0] + scale * TRIANGLE[i] + offsetX, + TRIANGLE[1] + scale * TRIANGLE[i + 1] + offsetY); + path.LineTo(TRIANGLE[0] + offsetX, + TRIANGLE[1] + offsetY); + } + else if (Figure == "Cross") + { + path.MoveTo(CROSS[0] + offsetX, + CROSS[1] + offsetY); + for (size_t i = 2; i < std::size(CROSS); i += 2) + path.LineTo(CROSS[0] + scale * CROSS[i] + offsetX, + CROSS[1] + scale * CROSS[i + 1] + offsetY); + path.LineTo(CROSS[0] + offsetX, + CROSS[1] + offsetY); + } + path.CloseFigure(); + + return path; +} + +void MainWindow::AddPath(NSGraphics::IGraphicsRenderer* pathRenderer, const Aggplus::CGraphicsPath& path, bool isResult) +{ + if (path.GetPointCount() == 0) + return; + + pathRenderer->PathCommandStart(); + pathRenderer->BeginCommand(c_nPathType); + + size_t length = path.GetPointCount(), + compound = path.GetCloseCount(); + std::vector points = path.GetPoints(0, length + compound); + + for (size_t i = 0; i < length + compound; i++) + { + if (path.IsCurvePoint(i)) + { + pathRenderer->PathCommandCurveTo(points[i].X + NEGATIVE_OFFSET, points[i].Y + NEGATIVE_OFFSET, + points[i + 1].X + NEGATIVE_OFFSET, points[i + 1].Y + NEGATIVE_OFFSET, + points[i + 2].X + NEGATIVE_OFFSET, points[i + 2].Y + NEGATIVE_OFFSET); + i += 2; + } + else if (path.IsMovePoint(i)) + pathRenderer->PathCommandMoveTo(points[i].X + NEGATIVE_OFFSET, points[i].Y + NEGATIVE_OFFSET); + else if (path.IsLinePoint(i)) + pathRenderer->PathCommandLineTo(points[i].X + NEGATIVE_OFFSET, points[i].Y + NEGATIVE_OFFSET); + } + + if (isResult) + { + pathRenderer->put_BrushColor1(0xFF0000); + pathRenderer->Fill(); + } + + pathRenderer->put_PenColor(!isResult ? 0x000000 : 0x0000FF); + pathRenderer->DrawPath(c_nStroke); + + pathRenderer->EndCommand(c_nPathType); + pathRenderer->PathCommandEnd(); +} + +void MainWindow::Draw(bool drawResult) +{ + ui->label->clear(); + + NSGraphics::IGraphicsRenderer* pathRenderer = NSGraphics::Create(); + NSFonts::IFontManager* fmp = NSFonts::NSFontManager::Create(); + pathRenderer->SetFontManager(fmp); + + int nW = ui->label->width(); + int nH = ui->label->height(); + + BYTE* pData = new BYTE[4 * nW * nH]; + + CBgraFrame oFrame; + oFrame.put_Data(pData); + oFrame.put_Width(nW); + oFrame.put_Height(nH); + oFrame.put_Stride(4 * nW); + + pathRenderer->CreateFromBgraFrame(&oFrame); + pathRenderer->SetSwapRGB(true); + + pathRenderer->put_Width(nW); + pathRenderer->put_Height(nH); + + AddPath(pathRenderer, Path1); + AddPath(pathRenderer, Path2); + + if (drawResult) + { + AddPath(pathRenderer, Result, true); + } + + QImage img = QImage(pData, nW, nH, QImage::Format_RGBA8888, [](void *data){ + delete [] (BYTE*)data; + }); + ui->label->setPixmap(QPixmap::fromImage(img)); +} + +void MainWindow::SetCoords(QLabel *label, const Aggplus::CGraphicsPath& path) +{ + size_t length = path.GetPointCount(); + std::vector points = path.GetPoints(0, length); + QString text = ""; + + for (size_t i = 0; i < length; i++) + text += "(" + QString::number(points[i].X) + + "; " + QString::number(points[i].Y) + "); "; + + label->setText(text); +} + +void MainWindow::DrawPath1() +{ + if (Path1.GetPointCount() > 0) Path1.Reset(); + Path1 = SetPath(Scale[0], Offsets[0], Offsets[1], Figure1); + Draw(); + SetCoords(ui->label_4, Path1); +} + +void MainWindow::DrawPath2() +{ + if (Path2.GetPointCount() > 0) Path2.Reset(); + Path2 = SetPath(Scale[1], Offsets[2], Offsets[3], Figure2); + Draw(); + SetCoords(ui->label_5, Path2); +} + +void MainWindow::BooleanOp() +{ + if (Path1.GetPointCount() == 0 || Path2.GetPointCount() == 0) + return; + + Result = Aggplus::CalcBooleanOperation(Path1, Path2, Op); + Draw(true); + SetCoords(ui->label_7, Result); +} + +void MainWindow::CheckMousePress() +{ + if (!ui->label->GetMovable()) + { + Move1 = false; + Move2 = false; + disconnect(ui->label, SIGNAL(mouseMove()), this, SLOT(Move())); + return; + } + + QRectF rect1(RECTANGLE[0] + NEGATIVE_OFFSET + Offsets[0], + RECTANGLE[1] + NEGATIVE_OFFSET + Offsets[1], + Scale[0] * RECTANGLE[2], + Scale[0] * RECTANGLE[3]), + rect2(RECTANGLE[0] + NEGATIVE_OFFSET + Offsets[2], + RECTANGLE[1] + NEGATIVE_OFFSET + Offsets[3], + Scale[1] * RECTANGLE[2], + Scale[1] * RECTANGLE[3]); + + Move1 = rect1.contains(ui->label->GetStartPoint()) && Path1.GetPointCount() != 0; + Move2 = rect2.contains(ui->label->GetStartPoint()) && Path2.GetPointCount() != 0; + if (Move2) + Move1 = false; + if (Move1 || Move2) + { + for (size_t i = 0; i < 4; i++) + OldOffsets[i] = Offsets[i]; + connect(ui->label, SIGNAL(mouseMove()), this, SLOT(Move())); + } +} + +inline double CheckOffset(double offset, double min, double max) +{ + return std::max(min, std::min(max, offset)); +} + +void MainWindow::Move() +{ + if (Move1) + { + Offsets[0] = CheckOffset(OldOffsets[0] + ui->label->GetDifferenceX(), + static_cast(ui->label->x()), + static_cast(ui->label->width())); + Offsets[1] = CheckOffset(OldOffsets[1] + ui->label->GetDifferenceY(), + static_cast(ui->label->y()), + static_cast(ui->label->height())); + DrawPath1(); + } + if (Move2) + { + Offsets[2] = CheckOffset(OldOffsets[2] + ui->label->GetDifferenceX(), + static_cast(ui->label->x()), + static_cast(ui->label->width())); + Offsets[3] = CheckOffset(OldOffsets[3] + ui->label->GetDifferenceY(), + static_cast(ui->label->y()), + static_cast(ui->label->height())); + DrawPath2(); + } +} + +void MainWindow::on_horizontalSlider_sliderMoved(int position) +{ + Scale[0] = position / 100.0; + DrawPath1(); +} + + +void MainWindow::on_horizontalSlider_2_sliderMoved(int position) +{ + Scale[1] = position / 100.0; + DrawPath2(); +} + diff --git a/DesktopEditor/graphics/tests/booleanPaths/mainwindow.h b/DesktopEditor/graphics/tests/booleanPaths/mainwindow.h new file mode 100644 index 00000000000..6c1c90e1099 --- /dev/null +++ b/DesktopEditor/graphics/tests/booleanPaths/mainwindow.h @@ -0,0 +1,111 @@ +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include +#include +#include +#include +#include +#include "../../pro/Graphics.h" + +QT_BEGIN_NAMESPACE +namespace Ui { +class MainWindow; +} +QT_END_NAMESPACE + +const double NEGATIVE_OFFSET= 400.0; +const double RECTANGLE[4] = {-400.0, -400.0, 200.0, 200.0}; +const double TRIANGLE[6] = {-300.0, -400.0, 100.0, 200.0, -100.0, 100.0}; +const double CROSS[24] = {-375.0, -325.0, 50.0, 0.0, 50.0, -50.0, + 100.0, -50.0, 100.0, 0.0, 150.0, 0.0, + 150.0, 50.0, 100.0, 50.0, 100.0, 100.0, + 50.0, 100.0, 50.0, 50.0, 0.0, 50.0}; + +class CustomLabel : public QLabel +{ + Q_OBJECT + +public: + CustomLabel(QWidget *parent = nullptr); + + QPointF GetStartPoint() const noexcept; + double GetDifferenceX() const noexcept; + double GetDifferenceY() const noexcept; + bool GetMovable() const noexcept; + +signals: + void mousePress(); + void mouseMove(); + +protected: + void mousePressEvent(QMouseEvent *event) override; + void mouseMoveEvent(QMouseEvent *event) override; + void mouseReleaseEvent(QMouseEvent *event) override; + +private: + bool Movable = false; + QPointF StartP = {0.0, 0.0}; + QPointF CurrP = {0.0, 0.0}; +}; + +class CustomButton : public QPushButton +{ + Q_OBJECT + +public: + CustomButton(QWidget *parent = nullptr); +}; + +class BooleanButton : public QPushButton +{ + Q_OBJECT + +public: + BooleanButton(QWidget *parent = nullptr); +}; + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + MainWindow(QWidget *parent = nullptr); + ~MainWindow(); + + Aggplus::CGraphicsPath SetPath(double scale, double offsetX, double offsetY, QString Figure); + void AddPath(NSGraphics::IGraphicsRenderer* pathRenderer, const Aggplus::CGraphicsPath& path, bool isResult = false); + void Draw(bool drawResult = false); + void SetCoords(QLabel* label, const Aggplus::CGraphicsPath& path); + + void DrawPath1(); + void DrawPath2(); + void BooleanOp(); + +private slots: + void CheckMousePress(); + void Move(); + void SetCommand(); + void SetFigure(); + void on_horizontalSlider_sliderMoved(int position); + void on_horizontalSlider_2_sliderMoved(int position); + +public: + QString Figure1; + QString Figure2; + Aggplus::BooleanOpType Op; + + double Scale[2] = {1.0, 1.0}; + double Offsets[4] = {100.0, 100.0, 200.0, 200.0}; + double OldOffsets[4]; + + bool Move1 = false; + bool Move2 = false; + + Aggplus::CGraphicsPath Path1; + Aggplus::CGraphicsPath Path2; + Aggplus::CGraphicsPath Result; + + Ui::MainWindow *ui; +}; +#endif // MAINWINDOW_H diff --git a/DesktopEditor/graphics/tests/booleanPaths/mainwindow.ui b/DesktopEditor/graphics/tests/booleanPaths/mainwindow.ui new file mode 100644 index 00000000000..f79a81a996c --- /dev/null +++ b/DesktopEditor/graphics/tests/booleanPaths/mainwindow.ui @@ -0,0 +1,437 @@ + + + MainWindow + + + + 0 + 0 + 1441 + 859 + + + + MainWindow + + + + + + 0 + 0 + 800 + 800 + + + + + + + + + + 810 + 0 + 610 + 500 + + + + + + + + + 10 + 10 + 191 + 480 + + + + Path1 + + + + + 20 + 40 + 83 + 29 + + + + Rectangle + + + + + + 20 + 80 + 83 + 29 + + + + Ellipse + + + + + + 20 + 120 + 83 + 29 + + + + Triangle + + + + + + 10 + 250 + 63 + 20 + + + + Coords: + + + + + + 10 + 270 + 170 + 200 + + + + + + + true + + + + + + 10 + 230 + 160 + 16 + + + + 1 + + + 200 + + + 100 + + + Qt::Horizontal + + + + + + 10 + 210 + 63 + 20 + + + + Scale: + + + + + + 20 + 160 + 83 + 29 + + + + Cross + + + + + + + 210 + 10 + 191 + 480 + + + + Path2 + + + + + 20 + 40 + 83 + 29 + + + + Rectangle + + + + + + 20 + 80 + 83 + 29 + + + + Ellipse + + + + + + 20 + 120 + 83 + 29 + + + + Triangle + + + + + + 10 + 250 + 63 + 20 + + + + Coords: + + + + + + 10 + 270 + 170 + 200 + + + + + + + true + + + + + + 10 + 230 + 160 + 16 + + + + 1 + + + 200 + + + 100 + + + Qt::Horizontal + + + + + + 10 + 210 + 63 + 20 + + + + Scale: + + + + + + 20 + 160 + 83 + 29 + + + + Cross + + + + + + + 410 + 10 + 191 + 480 + + + + Result + + + + + 10 + 250 + 63 + 20 + + + + Coords: + + + + + + 10 + 270 + 170 + 200 + + + + + + + true + + + + + + 20 + 120 + 83 + 29 + + + + Subtract + + + + + + 20 + 80 + 83 + 29 + + + + Intersect + + + + + + 20 + 40 + 83 + 29 + + + + Unite + + + + + + + + + 0 + 0 + 1441 + 21 + + + + + + + + CustomButton + QPushButton +
mainwindow.h
+
+ + BooleanButton + QPushButton +
mainwindow.h
+
+ + CustomLabel + QLabel +
mainwindow.h
+ + mousePress() + +
+
+ + + + label + mousePress() + MainWindow + CheckMousePress() + + + 249 + 274 + + + 561 + 276 + + + + + + CheckMousePress() + +
diff --git a/DesktopEditor/graphics/tests/booleanPaths/test.pro b/DesktopEditor/graphics/tests/booleanPaths/test.pro new file mode 100644 index 00000000000..e9247ea3cae --- /dev/null +++ b/DesktopEditor/graphics/tests/booleanPaths/test.pro @@ -0,0 +1,20 @@ +QT += core gui widgets + +QMAKE_CXXFLAGS += /permissive- + +SOURCES += \ + main.cpp \ + mainwindow.cpp + +HEADERS += \ + mainwindow.h + +FORMS += \ + mainwindow.ui + +PWD_ROOT_DIR = $$PWD +CORE_ROOT_DIR = $$PWD/../../../../../core +include($$CORE_ROOT_DIR/Common/base.pri) + +ADD_DEPENDENCY(kernel, graphics, UnicodeConverter) +include($$CORE_ROOT_DIR/Common/3dParty/icu/icu.pri) diff --git a/DesktopEditor/graphics/tests/graphicsLayers/graphicsLayers.pro b/DesktopEditor/graphics/tests/graphicsLayers/graphicsLayers.pro new file mode 100644 index 00000000000..2787314412d --- /dev/null +++ b/DesktopEditor/graphics/tests/graphicsLayers/graphicsLayers.pro @@ -0,0 +1,26 @@ +#CONFIG += c++11 cmdline + +#SOURCES += \ +QT -= core + +QT -= gui + +TARGET = test +CONFIG += console +TEMPLATE = app + +CORE_ROOT_DIR = $$PWD/../../../.. +PWD_ROOT_DIR = $$PWD +include($$CORE_ROOT_DIR/Common/base.pri) +include($$CORE_ROOT_DIR/Common/3dParty/icu/icu.pri) + +ADD_DEPENDENCY(kernel, graphics, UnicodeConverter) + +GRAPHICS_AGG_PATH = $$PWD/../../../agg-2.4 + +INCLUDEPATH += \ + $$GRAPHICS_AGG_PATH/include + +SOURCES += main.cpp + +DESTDIR = $$PWD_ROOT_DIR/build/$$CORE_BUILDS_PLATFORM_PREFIX/$$CORE_BUILDS_CONFIGURATION_PREFIX diff --git a/DesktopEditor/graphics/tests/graphicsLayers/main.cpp b/DesktopEditor/graphics/tests/graphicsLayers/main.cpp new file mode 100644 index 00000000000..34d875eae63 --- /dev/null +++ b/DesktopEditor/graphics/tests/graphicsLayers/main.cpp @@ -0,0 +1,108 @@ +#include "../../pro/Graphics.h" +#include "../../../raster/BgraFrame.h" +#include "../../../common/Directory.h" + +#define RGB_TO_INT(r, g, b) ((unsigned int)( ( (unsigned char)(r) )| ( ( (unsigned char)(g) ) << 8 ) | ( ( (unsigned char)(b) ) << 16 ) | ( (unsigned char)(0) << 24 ) ) ) + +int main(int argc, char *argv[]) +{ + NSGraphics::IGraphicsRenderer* pRasterRenderer = NSGraphics::Create(); + + const unsigned int unWidth = 1000; + const unsigned int unHeight = 1000; + + // Создание основной картинки + BYTE* pData = new BYTE[4 * unWidth * unHeight]; + + for (unsigned long unIndex = 0; unIndex < unWidth * unHeight; ++unIndex) + ((unsigned int*)pData)[unIndex] = 0xffffff; + + CBgraFrame oFrame; + oFrame.put_Data(pData); + oFrame.put_Width(unWidth); + oFrame.put_Height(unHeight); + oFrame.put_Stride(4 * unWidth); + + pRasterRenderer->CreateFromBgraFrame(&oFrame); + pRasterRenderer->SetSwapRGB(false); + + double dW_MM = unWidth; + double dH_MM = unHeight; + + pRasterRenderer->put_Width(dW_MM); + pRasterRenderer->put_Height(dH_MM); + + pRasterRenderer->BeginCommand(c_nPathType); + pRasterRenderer->PathCommandStart(); + + // Отрисовываем основной слой + pRasterRenderer->PathCommandRect(50, 200, 600, 300); + + pRasterRenderer->put_BrushAlpha1(255); + pRasterRenderer->put_BrushColor1(RGB_TO_INT(255, 0, 0)); // красный + + pRasterRenderer->put_PenAlpha(255); + pRasterRenderer->put_PenColor(RGB_TO_INT(255, 0, 255)); + pRasterRenderer->put_PenSize(40); + + pRasterRenderer->DrawPath(c_nWindingFillMode | c_nStroke); + + pRasterRenderer->PathCommandEnd(); + pRasterRenderer->EndCommand(c_nPathType); + + // Отрисовываем второй слой + pRasterRenderer->BeginCommand(c_nLayerType); + + pRasterRenderer->BeginCommand(c_nPathType); + pRasterRenderer->PathCommandStart(); + + pRasterRenderer->PathCommandRect(300, 300, 300, 300); + + pRasterRenderer->put_BrushAlpha1(255); + pRasterRenderer->put_BrushColor1(RGB_TO_INT(0, 255, 0)); // зеленый + + pRasterRenderer->put_PenAlpha(150); + pRasterRenderer->put_PenColor(RGB_TO_INT(0, 0, 255)); + pRasterRenderer->put_PenSize(40); + + pRasterRenderer->put_LayerOpacity(0.5); + + pRasterRenderer->DrawPath(c_nWindingFillMode | c_nStroke); + + pRasterRenderer->PathCommandEnd(); + pRasterRenderer->EndCommand(c_nPathType); + + //Отрисовываем третий слой + pRasterRenderer->BeginCommand(c_nLayerType); + + pRasterRenderer->BeginCommand(c_nPathType); + pRasterRenderer->PathCommandStart(); + + pRasterRenderer->PathCommandRect(500, 400, 300, 300); + + pRasterRenderer->put_BrushAlpha1(150); + pRasterRenderer->put_BrushColor1(RGB_TO_INT(0, 0, 255)); // синий + + pRasterRenderer->put_PenAlpha(255); + pRasterRenderer->put_PenColor(RGB_TO_INT(255, 0, 0)); + pRasterRenderer->put_PenSize(40); + + pRasterRenderer->put_LayerOpacity(1); + + pRasterRenderer->DrawPath(c_nWindingFillMode | c_nStroke); + + pRasterRenderer->PathCommandEnd(); + pRasterRenderer->EndCommand(c_nPathType); + + // блитируем трутий слой на второй + pRasterRenderer->EndCommand(c_nLayerType); + + // блитируем второй слой на основной + pRasterRenderer->EndCommand(c_nLayerType); + + oFrame.SaveFile(L"testGraphicsLayers.png", 4); + + RELEASEINTERFACE(pRasterRenderer); + + return 0; +} diff --git a/DesktopEditor/raster/BgraFrame.cpp b/DesktopEditor/raster/BgraFrame.cpp index 1b32860e9c8..d39f05fdddb 100644 --- a/DesktopEditor/raster/BgraFrame.cpp +++ b/DesktopEditor/raster/BgraFrame.cpp @@ -40,6 +40,10 @@ #include "JBig2/source/JBig2File.h" #endif +#if CXIMAGE_SUPPORT_PIC +#include "PICT/PICFile.h" +#endif + #include #define BGRA_FRAME_CXIMAGE_MAX_MEMORY 67108864 // 256Mb (*4 channel) @@ -439,6 +443,14 @@ bool CBgraFrame::OpenFile(const std::wstring& strFileName, unsigned int nFileTyp } #endif +#if CXIMAGE_SUPPORT_PIC + if (CXIMAGE_FORMAR_PIC == m_nFileType) + { + PICT::CPictFile PIC; + return PIC.Open(this, strFileName, !m_bIsRGBA); + } +#endif + NSFile::CFileBinary oFile; if (!oFile.OpenFile(strFileName)) return false; @@ -514,6 +526,14 @@ bool CBgraFrame::Decode(BYTE* pBuffer, int nSize, unsigned int nFileType) } #endif +#if CXIMAGE_SUPPORT_PIC + if (CXIMAGE_FORMAR_PIC == m_nFileType) + { + PICT::CPictFile PIC; + return PIC.Open(this, pBuffer, nSize, !m_bIsRGBA); + } +#endif + CxImage img; if (!img.Decode(pBuffer, nSize, m_nFileType)) @@ -569,7 +589,7 @@ bool CBgraFrame::SaveFile(const std::wstring& strFileName, unsigned int nFileTyp bool CBgraFrame::Encode(BYTE*& pBuffer, int& nSize, unsigned int nFileType) { CxImage oCxImage; - if (!oCxImage.CreateFromArray(m_pData, m_lWidth, m_lHeight, 32, 4 * m_lWidth, (m_lStride >= 0) ? true : false)) + if (!oCxImage.CreateFromArray(m_pData, m_lWidth, m_lHeight, 32, 4 * m_lWidth, (m_lStride >= 0) ? true : false, !m_bIsRGBA)) return false; if (CXIMAGE_FORMAT_JPG == nFileType && -1 != m_dJpegSaveQuality) diff --git a/DesktopEditor/raster/ImageFileFormatChecker.cpp b/DesktopEditor/raster/ImageFileFormatChecker.cpp index 91e252c4b51..467ee197514 100644 --- a/DesktopEditor/raster/ImageFileFormatChecker.cpp +++ b/DesktopEditor/raster/ImageFileFormatChecker.cpp @@ -412,6 +412,26 @@ bool CImageFileFormatChecker::isIpodFile(BYTE* pBuffer,DWORD dwBytes) return false; } + +bool CImageFileFormatChecker::isPicFile(BYTE *pBuffer, DWORD dwBytes) +{ + if (dwBytes < 12) + return false; + + if (memcmp(pBuffer, "PICT", 4) == 0) + return true; + + if (memcmp(pBuffer + 10, "\000\021\002\377\014\000", 6) == 0) + return true; + + if (dwBytes < 528) + return false; + + if (memcmp(pBuffer + 522, "\000\021\002\377\014\000", 6) == 0) + return true; + + return false; +} ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool CImageFileFormatChecker::isImageFile(std::wstring& fileName) { @@ -530,6 +550,10 @@ bool CImageFileFormatChecker::isImageFile(std::wstring& fileName) { eFileType = _CXIMAGE_FORMAT_UNKNOWN; } + else if (isPicFile(buffer, sizeRead)) + { + eFileType = _CXIMAGE_FORMAT_PIC; + } /////////////////////////////////////////////////////////////////////// delete [] buffer; @@ -641,7 +665,11 @@ bool CImageFileFormatChecker::isImageFile(BYTE* buffer, DWORD sizeRead) { eFileType = _CXIMAGE_FORMAT_UNKNOWN; } - /////////////////////////////////////////////////////////////////////// + if (isPicFile(buffer, sizeRead)) + { + eFileType = _CXIMAGE_FORMAT_PIC; + } + /////////////////////////////////////////////////////////////////////// if (eFileType) return true; return false; } diff --git a/DesktopEditor/raster/ImageFileFormatChecker.h b/DesktopEditor/raster/ImageFileFormatChecker.h index c18669c9e2f..a3640274eaf 100644 --- a/DesktopEditor/raster/ImageFileFormatChecker.h +++ b/DesktopEditor/raster/ImageFileFormatChecker.h @@ -62,6 +62,7 @@ enum __ENUM_CXIMAGE_FORMATS _CXIMAGE_FORMAT_WB = 22, _CXIMAGE_FORMAT_SVM = 23, _CXIMAGE_FORMAT_SVG = 24, + _CXIMAGE_FORMAT_PIC = 25, }; class GRAPHICS_DECL CImageFileFormatChecker @@ -109,6 +110,7 @@ class GRAPHICS_DECL CImageFileFormatChecker bool isPgxFile(BYTE* pBuffer,DWORD dwBytes); bool isSvgFile(BYTE* pBuffer,DWORD dwBytes); bool isRawFile(BYTE* pBuffer,DWORD dwBytes); + bool isPicFile(BYTE* pBuffer,DWORD dwBytes); std::wstring DetectFormatByData(BYTE *Data, int DataSize); diff --git a/DesktopEditor/raster/JBig2/source/LeptonLib/ccbord.cpp b/DesktopEditor/raster/JBig2/source/LeptonLib/ccbord.cpp index 7d82b96356e..d906c6c8715 100644 --- a/DesktopEditor/raster/JBig2/source/LeptonLib/ccbord.cpp +++ b/DesktopEditor/raster/JBig2/source/LeptonLib/ccbord.cpp @@ -1028,6 +1028,8 @@ l_uint32 *line; pos = (qpos + i) % 8; npx = px + xpostab[pos]; npy = py + ypostab[pos]; + if (npx < 0 || npx >= w || npy < 0 || npy >= h) + continue; line = data + npy * wpl; val = GET_DATA_BIT(line, npx); if (val) { diff --git a/DesktopEditor/raster/JBig2/source/LeptonLib/colorquant1.cpp b/DesktopEditor/raster/JBig2/source/LeptonLib/colorquant1.cpp index bca4619f1a7..bdeac0c23b0 100644 --- a/DesktopEditor/raster/JBig2/source/LeptonLib/colorquant1.cpp +++ b/DesktopEditor/raster/JBig2/source/LeptonLib/colorquant1.cpp @@ -3228,7 +3228,7 @@ l_int32 i, j, w, h, wplc, wplm, wpld, ncolors, index; l_int32 rval, gval, bval, val, minval, maxval; l_int32 *lut; l_uint32 *datac, *datam, *datad, *linec, *linem, *lined; -PIX *pixc, *pixm, *pixg, *pixd; +PIX *pix1, *pixc, *pixm, *pixg, *pixd; PIXCMAP *cmap, *cmapd; PROCNAME("pixFewColorsOctcubeQuantMixed"); @@ -3245,8 +3245,10 @@ PIXCMAP *cmap, *cmapd; if (maxspan <= 2) maxspan = 15; /* Start with a simple fixed octcube quantizer. */ - if ((pixc = pixFewColorsOctcubeQuant1(pixs, level)) == NULL) + if ((pix1 = pixFewColorsOctcubeQuant1(pixs, level)) == NULL) return (PIX *)ERROR_PTR("too many colors", procName, NULL); + pixc = pixConvertTo8(pix1, 1); /* must be 8 bpp */ + pixDestroy(&pix1); /* Identify and save color entries in the colormap. Set up a LUT * that returns -1 for any gray pixel. */ diff --git a/DesktopEditor/raster/Metafile/Common/CClip.cpp b/DesktopEditor/raster/Metafile/Common/CClip.cpp index 20bba192985..5797ca807b7 100644 --- a/DesktopEditor/raster/Metafile/Common/CClip.cpp +++ b/DesktopEditor/raster/Metafile/Common/CClip.cpp @@ -107,8 +107,8 @@ namespace MetaFile void CClip::Copy(const CClip &oClip) { Clear(); - - for (const CClipCommandBase* pCommand : m_arCommands) + + for (const CClipCommandBase* pCommand : oClip.m_arCommands) { switch(pCommand->GetType()) { diff --git a/DesktopEditor/raster/Metafile/Common/CPath.cpp b/DesktopEditor/raster/Metafile/Common/CPath.cpp index cb41d28e43e..12850e72360 100644 --- a/DesktopEditor/raster/Metafile/Common/CPath.cpp +++ b/DesktopEditor/raster/Metafile/Common/CPath.cpp @@ -327,6 +327,13 @@ namespace MetaFile if (NULL == pCommand) return false; + if (PATH_COMMAND_MOVETO == pCommand->GetType() && !m_arCommands.empty() && PATH_COMMAND_MOVETO == m_arCommands.back()->GetType()) + { + CPathCommandBase* pLastCommand = m_arCommands.back(); + m_arCommands.pop_back(); + delete pLastCommand; + } + m_arCommands.push_back(pCommand); return true; } diff --git a/DesktopEditor/raster/Metafile/Common/CPathConverter.cpp b/DesktopEditor/raster/Metafile/Common/CPathConverter.cpp index 5fa2370d86a..06f8d02135d 100644 --- a/DesktopEditor/raster/Metafile/Common/CPathConverter.cpp +++ b/DesktopEditor/raster/Metafile/Common/CPathConverter.cpp @@ -59,7 +59,7 @@ namespace MetaFile { CPathCommandArcTo *pCommandArcTo = (CPathCommandArcTo*)pCommand; - oNewPath.ArcTo(pCommandArcTo->GetLeft(), pCommandArcTo->GetTop(), + oNewPath.ArcTo(pCommandArcTo->GetLeft(), pCommandArcTo->GetTop(), pCommandArcTo->GetRight(), pCommandArcTo->GetBottom(), pCommandArcTo->GetStartAngle(), pCommandArcTo->GetSweepAngle()); diff --git a/DesktopEditor/raster/Metafile/Common/MetaFile.h b/DesktopEditor/raster/Metafile/Common/MetaFile.h index d2ed5edc43c..4e0d19f671e 100644 --- a/DesktopEditor/raster/Metafile/Common/MetaFile.h +++ b/DesktopEditor/raster/Metafile/Common/MetaFile.h @@ -45,11 +45,8 @@ namespace MetaFile { public: IMetaFileBase() + : m_pOutput(NULL), m_pParent(NULL), m_pBufferData(NULL), m_bIsExternalBuffer(false), m_bError(false) { - m_pBufferData = NULL; - m_bIsExternalBuffer = false; - m_bError = false; - m_pOutput = NULL; m_oStream.SetStream(NULL, 0); } virtual ~IMetaFileBase() @@ -57,33 +54,46 @@ namespace MetaFile this->Close(); } - virtual void PlayMetaFile() = 0; - virtual void ClearFile() {/*Нельзя делать чисто виртуальной, потому что вызывается в деструкторе*/} - virtual TRectL* GetDCBounds() = 0; - virtual CClip* GetClip() = 0; - virtual double GetPixelHeight() = 0; - virtual double GetPixelWidth() = 0; - virtual int GetTextColor() = 0; - virtual IFont* GetFont() = 0; - virtual IBrush* GetBrush() = 0; - virtual IPen* GetPen() = 0; - virtual unsigned int GetTextAlign() = 0; - virtual unsigned int GetTextBgMode() = 0; - virtual int GetTextBgColor() = 0; - virtual unsigned int GetFillMode() = 0; - virtual TPointD GetCurPos() = 0; - virtual TXForm* GetInverseTransform() = 0; - virtual TXForm* GetTransform(int iGraphicsMode = GM_ADVANCED) = 0; - virtual unsigned int GetMiterLimit() = 0; - virtual unsigned int GetRop2Mode() = 0; - virtual int GetCharSpace() = 0; - virtual bool IsWindowFlippedY() = 0; - virtual bool IsWindowFlippedX() = 0; - virtual unsigned int GetMapMode() = 0; - virtual double GetDpi() = 0; - virtual IRegion* GetRegion() = 0; - virtual unsigned int GetArcDirection() = 0; - virtual CPath* GetPath() = 0; + virtual void PlayMetaFile() = 0; + virtual void ClearFile() {/*Нельзя делать чисто виртуальной, потому что вызывается в деструкторе*/} + virtual const TRectL& GetDCBounds() const = 0; + virtual const CClip* GetClip() const = 0; + virtual double GetPixelHeight() const = 0; + virtual double GetPixelWidth() const = 0; + virtual int GetTextColor() const = 0; + virtual const IFont* GetFont() const = 0; + virtual const IBrush* GetBrush() const = 0; + virtual const IPen* GetPen() const = 0; + virtual unsigned int GetTextAlign() const = 0; + virtual unsigned int GetTextBgMode() const = 0; + virtual int GetTextBgColor() const = 0; + virtual unsigned int GetFillMode() const = 0; + virtual TPointD GetCurPos() const = 0; + virtual const TXForm& GetInverseTransform() const = 0; + virtual const TXForm& GetTransform(int iGraphicsMode = GM_ADVANCED) = 0; + virtual unsigned int GetMiterLimit() const = 0; + virtual unsigned int GetRop2Mode() const = 0; + virtual int GetCharSpace() const = 0; + virtual bool IsWindowFlippedY() const = 0; + virtual bool IsWindowFlippedX() const = 0; + virtual unsigned int GetMapMode() const = 0; + virtual USHORT GetDpi() const = 0; + virtual const IRegion* GetRegion() const = 0; + virtual unsigned int GetArcDirection() const = 0; + virtual const CPath* GetPath() const = 0; + + virtual TXForm CalculateCurrentTransform() const + { + return TXForm{}; + } + + virtual const TRectL& GetOriginalDCBounds() const + { + if (NULL != m_pParent) + return m_pParent->GetOriginalDCBounds(); + + return GetDCBounds(); + } bool ReadFromBuffer(BYTE* pBuffer, unsigned int unSize, const bool& bIsExternal = true) { @@ -141,7 +151,7 @@ namespace MetaFile this->ClearFile(); } - NSFonts::IFontManager* GetFontManager() + NSFonts::IFontManager* GetFontManager() const { return m_pFontManager; } @@ -157,16 +167,21 @@ namespace MetaFile { m_bError = true; } - bool CheckError() + bool CheckError() const { return m_bError; } + void SetParent(const IMetaFileBase* pParent) + { + m_pParent = pParent; + } protected: CDataStream m_oStream; IOutputDevice* m_pOutput; + const IMetaFileBase* m_pParent; private: NSFonts::IFontManager* m_pFontManager; diff --git a/DesktopEditor/raster/Metafile/Common/MetaFileObjects.h b/DesktopEditor/raster/Metafile/Common/MetaFileObjects.h index 76d61ad9b71..58b9c94e7a2 100644 --- a/DesktopEditor/raster/Metafile/Common/MetaFileObjects.h +++ b/DesktopEditor/raster/Metafile/Common/MetaFileObjects.h @@ -33,8 +33,7 @@ #define _METAFILE_COMMON_METAFILEOBJECTS_H #include - -#include "IOutputDevice.h" +#include namespace MetaFile { @@ -44,15 +43,15 @@ namespace MetaFile IFont(){} virtual ~IFont(){} - virtual double GetHeight() = 0; - virtual std::wstring GetFaceName() = 0; - virtual int GetWeight() = 0; - virtual bool IsItalic() = 0; - virtual bool IsStrikeOut() = 0; - virtual bool IsUnderline() = 0; - virtual int GetEscapement() = 0; - virtual int GetCharSet() = 0; - virtual int GetOrientation() = 0; + virtual double GetHeight() const = 0; + virtual std::wstring GetFaceName() const = 0; + virtual int GetWeight() const = 0; + virtual bool IsItalic() const = 0; + virtual bool IsStrikeOut() const = 0; + virtual bool IsUnderline() const = 0; + virtual int GetEscapement() const = 0; + virtual int GetCharSet() const = 0; + virtual int GetOrientation() const = 0; }; class IBrush @@ -61,32 +60,44 @@ namespace MetaFile IBrush(){} virtual ~IBrush(){} - virtual int GetColor() = 0; - virtual int GetColor2() = 0; - virtual unsigned int GetStyle() = 0; - virtual unsigned int GetStyleEx() = 0; - virtual unsigned int GetHatch() = 0; - virtual unsigned int GetAlpha() = 0; - virtual unsigned int GetAlpha2() = 0; - virtual std::wstring GetDibPatterPath() = 0; - virtual void GetBounds(double& left, double& top, double& width, double& height) = 0; - virtual void GetCenterPoint(double& dX, double& dY) = 0; + virtual int GetColor() const = 0; + virtual int GetColor2() const = 0; + virtual unsigned int GetStyle() const = 0; + virtual unsigned int GetStyleEx() const = 0; + virtual unsigned int GetHatch() const = 0; + virtual unsigned int GetAlpha() const = 0; + virtual unsigned int GetAlpha2() const = 0; + virtual std::wstring GetDibPatterPath() const = 0; + virtual void GetBounds(double& left, double& top, double& width, double& height) const = 0; + virtual void GetCenterPoint(double& dX, double& dY) const = 0; + + virtual void GetGradientColors(std::vector& arColors, std::vector& arPositions) const = 0; - virtual void GetDibPattern(unsigned char** pBuffer, unsigned int &unWidth, unsigned int &unHeight) = 0; + virtual void GetDibPattern(unsigned char** pBuffer, unsigned int &unWidth, unsigned int &unHeight) const = 0; }; + + class ILineCap + { + public: + ILineCap(){} + virtual ~ILineCap(){} + }; + class IPen { public: IPen(){} virtual ~IPen(){} - virtual int GetColor() = 0; - virtual unsigned int GetStyle() = 0; - virtual double GetWidth() = 0; - virtual unsigned int GetAlpha() = 0; - virtual double GetMiterLimit() = 0; - virtual double GetDashOffset() = 0; - virtual void GetDashData(double*&, unsigned int&) = 0; + virtual int GetColor() const = 0; + virtual unsigned int GetStyle() const = 0; + virtual double GetWidth() const = 0; + virtual unsigned int GetAlpha() const = 0; + virtual double GetMiterLimit() const = 0; + virtual double GetDashOffset() const = 0; + virtual void GetDashData(double*&, unsigned int&) const = 0; + virtual const ILineCap* GetStartLineCap() const = 0; + virtual const ILineCap* GetEndLineCap() const = 0; }; class IRegion diff --git a/DesktopEditor/raster/Metafile/Common/MetaFileRenderer.h b/DesktopEditor/raster/Metafile/Common/MetaFileRenderer.h index 50d9192326f..507ee0082fc 100644 --- a/DesktopEditor/raster/Metafile/Common/MetaFileRenderer.h +++ b/DesktopEditor/raster/Metafile/Common/MetaFileRenderer.h @@ -100,6 +100,8 @@ namespace MetaFile m_bStartedPath = false; m_bUpdatedClip = true; + m_pRenderer->CommandLong(c_nPenWidth0As1px, 1); + //int alpha = 0xff; //m_pRenderer->put_BrushAlpha1(alpha); //m_pRenderer->put_BrushType(c_BrushTypeSolid); @@ -197,14 +199,29 @@ namespace MetaFile if (NULL == m_pFile) return; - TRectL* pBounds = m_pFile->GetDCBounds(); - int nL = pBounds->Left; - int nR = pBounds->Right; - int nT = pBounds->Top; - int nB = pBounds->Bottom; + const TRectL& oBounds{m_pFile->GetDCBounds()}; + m_dScaleX = m_dW / std::fabs((double)(oBounds.Right - oBounds.Left)); + m_dScaleY = m_dH / std::fabs((double)(oBounds.Bottom - oBounds.Top)); + } + + double GetHeight() const + { + return m_dH; + } + + double GetWidth() const + { + return m_dW; + } - m_dScaleX = m_dW / std::fabs((double)(nR - nL)); - m_dScaleY = m_dH / std::fabs((double)(nB - nT)); + double GetScaleX() const + { + return m_dScaleX; + } + + double GetScaleY() const + { + return m_dScaleY; } void Begin() @@ -273,7 +290,7 @@ namespace MetaFile } void DrawDriverString(const std::wstring& wsString, const std::vector& arPoints) { - IFont *pFont = m_pFile->GetFont(); + const IFont *pFont = m_pFile->GetFont(); if (NULL == pFont) return; @@ -336,7 +353,7 @@ namespace MetaFile void DrawString(std::wstring& wsText, unsigned int unCharsCount, double _dX, double _dY, double* pDx, int iGraphicsMode, double dXScale, double dYScale) { CheckEndPath(); - IFont* pFont = m_pFile->GetFont(); + const IFont* pFont = m_pFile->GetFont(); if (!pFont) return; @@ -434,7 +451,12 @@ namespace MetaFile } else { - pFontManager->LoadFontByName(wsFaceName, dFontHeight, lStyle, 72, 72); + double dRendererDpiX, dRendererDpiY; + + m_pRenderer->get_DpiX(&dRendererDpiX); + m_pRenderer->get_DpiY(&dRendererDpiY); + + pFontManager->LoadFontByName(wsFaceName, dFontHeight, lStyle, dRendererDpiX, dRendererDpiY); pFontManager->SetCharSpacing(dFontCharSpace * 72 / 25.4); double dMmToPt = 25.4 / 72; @@ -966,7 +988,7 @@ namespace MetaFile } bool UpdateBrush() { - IBrush* pBrush = m_pFile->GetBrush(); + const IBrush* pBrush = m_pFile->GetBrush(); if (!pBrush) return false; @@ -1087,12 +1109,11 @@ namespace MetaFile m_pRenderer->put_BrushLinearAngle(pBrush->GetStyleEx()); - long Colors[2]; - Colors[0] = pBrush->GetColor() + (pBrush->GetAlpha() << 24); - Colors[1] = pBrush->GetColor2() + (pBrush->GetAlpha2() << 24); - double Position[2] = {0, 1}; + std::vector arColors; + std::vector arPositions; - m_pRenderer->put_BrushGradientColors(Colors,Position,2); + pBrush->GetGradientColors(arColors, arPositions); + m_pRenderer->put_BrushGradientColors(arColors.data(), arPositions.data(), arColors.size()); } else if ( BS_RADIALGRADIENT == unBrushStyle || @@ -1127,7 +1148,7 @@ namespace MetaFile if (m_bUpdatedClip) return; - CClip *pClip = m_pFile->GetClip(); + const CClip *pClip = m_pFile->GetClip(); if (NULL == pClip) return; @@ -1155,12 +1176,11 @@ namespace MetaFile } bool UpdatePen() { - IPen* pPen = m_pFile->GetPen(); + const IPen* pPen = m_pFile->GetPen(); if (!pPen) return false; unsigned int unMetaPenStyle = pPen->GetStyle(); - unsigned int ulPenStyle = unMetaPenStyle & PS_STYLE_MASK; if (PS_NULL == ulPenStyle) @@ -1198,25 +1218,8 @@ namespace MetaFile else if (PS_JOIN_MITER == ulPenJoin) nJoinStyle = Aggplus::LineJoinMiter; - double dWidth = pPen->GetWidth(); - - if (0 == dWidth || (1 == dWidth && PS_COSMETIC == ulPenType)) - { - double dRendererDpiX; - m_pRenderer->get_DpiX(&dRendererDpiX); - - dWidth = 25.4 / dRendererDpiX; - - if (PS_COSMETIC == ulPenType) - dWidth /= m_pFile->GetTransform()->M11 / (m_pFile->GetDpi() / 96.); - - nStartCapStyle = nEndCapStyle = Aggplus::LineCapFlat; - nJoinStyle = Aggplus::LineJoinMiter; - } - else - dWidth *= m_dScaleX; - - double dMiterLimit = (0 != pPen->GetMiterLimit()) ? pPen->GetMiterLimit() : m_pFile->GetMiterLimit() * m_dScaleX; + const double dWidth = pPen->GetWidth() * m_dScaleX; + const double dMiterLimit = (0 != pPen->GetMiterLimit()) ? pPen->GetMiterLimit() : m_pFile->GetMiterLimit() * m_dScaleX; BYTE nDashStyle = Aggplus::DashStyleSolid; @@ -1229,10 +1232,16 @@ namespace MetaFile { m_pRenderer->put_PenDashOffset(pPen->GetDashOffset()); + double dM11, dTemp; + m_pRenderer->GetTransform(&dM11, &dTemp, &dTemp, &dTemp, &dTemp, &dTemp); + double dDpi; + m_pRenderer->get_DpiX(&dDpi); + const double dNewWidth{dWidth * dM11 * dDpi / 25.4}; + std::vector arDashes(unSizeDash); for (unsigned int unIndex = 0; unIndex < unSizeDash; ++unIndex) - arDashes[unIndex] = pDataDash[unIndex] * dWidth; + arDashes[unIndex] = pDataDash[unIndex] * dNewWidth; m_pRenderer->PenDashPattern(arDashes.data(), unSizeDash); @@ -1242,53 +1251,45 @@ namespace MetaFile { std::vector arDashPattern; - double dPixWidth = 0; - - if (0 == pPen->GetWidth() || (1 == pPen->GetWidth() && PS_COSMETIC == ulPenType)) - { - dPixWidth = dWidth; - } - else - { - dPixWidth = dWidth * 25.4 / 72.; - - if (1 == pPen->GetWidth() && PS_COSMETIC == ulPenType) - dPixWidth /= m_pFile->GetTransform()->M11 / (m_pFile->GetDpi() / 96.); - } + double dM11, dTemp; + m_pRenderer->GetTransform(&dM11, &dTemp, &dTemp, &dTemp, &dTemp, &dTemp); + double dDpi; + m_pRenderer->get_DpiX(&dDpi); + const double dNewWidth{dWidth * dM11 * dDpi / 25.4}; switch (ulPenStyle) { case PS_DASH: { - arDashPattern.push_back(9 * dPixWidth); - arDashPattern.push_back(3 * dPixWidth); + arDashPattern.push_back(9 * dNewWidth); + arDashPattern.push_back(3 * dNewWidth); break; } case PS_DOT: { - arDashPattern.push_back(3 * dPixWidth); - arDashPattern.push_back(3 * dPixWidth); + arDashPattern.push_back(3 * dNewWidth); + arDashPattern.push_back(3 * dNewWidth); break; } case PS_DASHDOT: { - arDashPattern.push_back(9 * dPixWidth); - arDashPattern.push_back(3 * dPixWidth); - arDashPattern.push_back(3 * dPixWidth); - arDashPattern.push_back(3 * dPixWidth); + arDashPattern.push_back(9 * dNewWidth); + arDashPattern.push_back(3 * dNewWidth); + arDashPattern.push_back(3 * dNewWidth); + arDashPattern.push_back(3 * dNewWidth); break; } case PS_DASHDOTDOT: { - arDashPattern.push_back(9 * dPixWidth); - arDashPattern.push_back(3 * dPixWidth); - arDashPattern.push_back(3 * dPixWidth); - arDashPattern.push_back(3 * dPixWidth); - arDashPattern.push_back(3 * dPixWidth); - arDashPattern.push_back(3 * dPixWidth); + arDashPattern.push_back(9 * dNewWidth); + arDashPattern.push_back(3 * dNewWidth); + arDashPattern.push_back(3 * dNewWidth); + arDashPattern.push_back(3 * dNewWidth); + arDashPattern.push_back(3 * dNewWidth); + arDashPattern.push_back(3 * dNewWidth); break; } diff --git a/DesktopEditor/raster/Metafile/Common/MetaFileTypes.cpp b/DesktopEditor/raster/Metafile/Common/MetaFileTypes.cpp index f92981df8d8..b6293a91ce6 100644 --- a/DesktopEditor/raster/Metafile/Common/MetaFileTypes.cpp +++ b/DesktopEditor/raster/Metafile/Common/MetaFileTypes.cpp @@ -62,7 +62,7 @@ namespace MetaFile a = oRGBA.a; } - int TRGBA::ToInt() + int TRGBA::ToInt() const { return METAFILE_RGBA(r, g, b, a); } @@ -74,6 +74,26 @@ namespace MetaFile b = t; } + unsigned char TRGBA::GetRed() const + { + return r; + } + + unsigned char TRGBA::GetGreen() const + { + return g; + } + + unsigned char TRGBA::GetBlue() const + { + return b; + } + + unsigned char TRGBA::GetAlpha() const + { + return a; + } + TXForm::TXForm() : M11(1), M12(0), M21(0), M22(1), Dx(0), Dy(0) {} @@ -101,14 +121,24 @@ namespace MetaFile return; M11 = pOther->M11; - M12 = pOther->M12; - M21 = pOther->M21; - M22 = pOther->M22; - Dx = pOther->Dx; - Dy = pOther->Dy; + M12 = pOther->M12; + M21 = pOther->M21; + M22 = pOther->M22; + Dx = pOther->Dx; + Dy = pOther->Dy; } - void TXForm::Multiply(TXForm &oOther, unsigned int ulMode) + void TXForm::Copy(const TXForm& oOther) + { + M11 = oOther.M11; + M12 = oOther.M12; + M21 = oOther.M21; + M22 = oOther.M22; + Dx = oOther.Dx; + Dy = oOther.Dy; + } + + void TXForm::Multiply(const TXForm &oOther, unsigned int ulMode) { if (MWT_IDENTITY == ulMode) Init(); @@ -154,7 +184,7 @@ namespace MetaFile } } - void TXForm::Apply(double &dX, double &dY) + void TXForm::Apply(double &dX, double &dY) const { double _dX = dX; double _dY = dY; @@ -162,4 +192,34 @@ namespace MetaFile dX = _dX * M11 + _dY * M21 + Dx; dY = _dX * M12 + _dY * M22 + Dy; } + + template<> + bool TPoint::operator==(const TPoint& oPoint) const + { + return std::abs(X - oPoint.X) <= DBL_EPSILON && std::abs(Y - oPoint.Y) <= DBL_EPSILON; + } + + template<> + bool TPoint::operator!=(const TPoint& oPoint) const + { + return std::abs(X - oPoint.X) > DBL_EPSILON || std::abs(Y - oPoint.Y) > DBL_EPSILON; + } + + template<> + bool TRect::operator==(const TRect& oRect) const + { + return std::abs(Left - oRect.Right) <= DBL_EPSILON && + std::abs(Top - oRect.Top) <= DBL_EPSILON && + std::abs(Right - oRect.Right) <= DBL_EPSILON && + std::abs(Bottom - oRect.Bottom) <= DBL_EPSILON; + } + + template<> + bool TRect::operator!=(const TRect& oRect) const + { + return std::abs(Left - oRect.Right) > DBL_EPSILON || + std::abs(Top - oRect.Top) > DBL_EPSILON || + std::abs(Right - oRect.Right) > DBL_EPSILON || + std::abs(Bottom - oRect.Bottom) > DBL_EPSILON; + } } diff --git a/DesktopEditor/raster/Metafile/Common/MetaFileTypes.h b/DesktopEditor/raster/Metafile/Common/MetaFileTypes.h index f458d14012e..4bd9ff3da7b 100644 --- a/DesktopEditor/raster/Metafile/Common/MetaFileTypes.h +++ b/DesktopEditor/raster/Metafile/Common/MetaFileTypes.h @@ -33,6 +33,7 @@ #define _METAFILE_COMMON_METAFILETYPES_H #include +#include #include "../../../common/StringExt.h" #ifndef BYTE @@ -348,6 +349,8 @@ typedef unsigned char BYTE; namespace MetaFile { + #define DEFAULT_FONT_SIZE 14 + enum InterpretatorType { Emf, @@ -396,18 +399,24 @@ namespace MetaFile X *= scale; Y *= scale; } - - friend bool operator!=(const TPoint& oLeftRect, const TPoint& oRightValue) + + bool operator==(const TPoint& oPoint) const { - return oLeftRect.X != oRightValue.X || oLeftRect.Y != oRightValue.Y; + return X == oPoint.X && Y == oPoint.Y; } - friend bool operator==(const TPoint& oLeftRect, const TPoint& oRightValue) + bool operator!=(const TPoint& oPoint) const { - return oLeftRect.X == oRightValue.X && oLeftRect.Y == oRightValue.Y; + return X != oPoint.X || Y != oPoint.Y; } }; + template<> + bool TPoint::operator==(const TPoint& oPoint) const; + + template<> + bool TPoint::operator!=(const TPoint& oPoint) const; + typedef TPoint TPointL; typedef TPoint TPointS; typedef TPoint TPointD; @@ -467,19 +476,8 @@ namespace MetaFile Top *= scale; Right *= scale; Bottom *= scale; - - return *this; - } - friend bool operator!=(const TRect& oLeftRect, const TRect& oRightValue) - { - return oLeftRect.Left != oRightValue.Left || oLeftRect.Top != oRightValue.Top || - oLeftRect.Right != oRightValue.Right || oLeftRect.Bottom != oRightValue.Bottom; - } - friend bool operator==(const TRect& oLeftRect, const TRect& oRightValue) - { - return oLeftRect.Left == oRightValue.Left && oLeftRect.Top == oRightValue.Top && - oLeftRect.Right == oRightValue.Right && oLeftRect.Bottom == oRightValue.Bottom; + return *this; } bool Empty() const @@ -514,8 +512,26 @@ namespace MetaFile Right = pOther->Right; Bottom = pOther->Bottom; } + + bool operator==(const TRect& oRect) const + { + return Left == oRect.Left && Top == oRect.Top && + Right == oRect.Right && Bottom == oRect.Bottom; + } + + bool operator!=(const TRect& oRect) const + { + return Left != oRect.Left || Top != oRect.Top || + Right != oRect.Right || Bottom != oRect.Bottom; + } }; + template<> + bool TRect::operator==(const TRect& oRect) const; + + template<> + bool TRect::operator!=(const TRect& oRect) const; + typedef TRect TRectL; typedef TRect TRectS; typedef TRect TRectD; @@ -535,8 +551,13 @@ namespace MetaFile void Set(unsigned char _r, unsigned char _g, unsigned char _b, unsigned char _a = 0); void Copy(const TRGBA &oRGBA); - int ToInt(); + int ToInt() const; void SwapToBGR(); + + unsigned char GetRed() const; + unsigned char GetGreen() const; + unsigned char GetBlue() const; + unsigned char GetAlpha() const; }; struct TXForm @@ -551,11 +572,12 @@ namespace MetaFile TXForm(); TXForm(const TXForm& oXForm); TXForm(double m11, double m12, double m21, double m22, double dx, double dy); - + void Init(); void Copy(const TXForm* pOther); - void Multiply(TXForm &oOther, unsigned int ulMode); - void Apply(double& dX, double& dY); + void Copy(const TXForm& oOther); + void Multiply(const TXForm& oOther, unsigned int ulMode); + void Apply(double& dX, double& dY) const; }; } diff --git a/DesktopEditor/raster/Metafile/Common/MetaFileUtils.cpp b/DesktopEditor/raster/Metafile/Common/MetaFileUtils.cpp index 51811140074..29ab635fda1 100644 --- a/DesktopEditor/raster/Metafile/Common/MetaFileUtils.cpp +++ b/DesktopEditor/raster/Metafile/Common/MetaFileUtils.cpp @@ -44,11 +44,16 @@ #define DIB_RGB_COLORS 0x00 #endif -#define MINACCURACY 2 +#define MINACCURACY 5 #define MAXACCURACY 10 namespace MetaFile { + bool Equals(double dFirst, double dSecond, double dEpsilon) + { + return std::abs(dFirst - dSecond) <= dEpsilon; + } + unsigned char GetLowestBit(unsigned int ulValue) { if (0 == ulValue) @@ -142,6 +147,10 @@ namespace MetaFile if (BI_JPEG != unCompression || BI_PNG != unCompression) return false; +#ifdef METAFILE_DISABLE_FILESYSTEM + return false; +#endif + std::wstring wsTempFileName = GetTempFilename(); if (wsTempFileName.empty()) return false; @@ -1061,54 +1070,105 @@ namespace MetaFile #endif } - static int GetMinAccuracy(double dValue) + std::wstring ConvertToWString(double dValue, int nAccuracy) { - if (dValue == (int)dValue) - return 0; + const double dAbsValue {std::abs(dValue)}; + const double dRemainder{dAbsValue - std::floor(dAbsValue)}; - if (dValue < 0.) - dValue = -dValue; + if (Equals(0., dRemainder)) + return std::to_wstring(static_cast(dValue)); - if (dValue > 1.) - return MINACCURACY; + if (nAccuracy < 0) + { + if (dAbsValue < 1.) + nAccuracy = MAXACCURACY; + else + nAccuracy = MINACCURACY; + } - unsigned int unAccuracy = 0; + std::wstringstream owsStream; + owsStream << std::fixed << std::setprecision(nAccuracy) << dValue; - while (unAccuracy < MAXACCURACY) - { - dValue *= 10; + std::wstring wsValue{owsStream.str()}; - if (dValue >= 1.) - break; + const size_t unDotPosition{wsValue.find_first_of(L'.')}; - ++unAccuracy; - } + if (std::wstring::npos == unDotPosition) + return wsValue; - if (MAXACCURACY == unAccuracy) - return 0; - else - return unAccuracy + 3; - } + const size_t unFirstPosition{wsValue.find_first_not_of(L'0', unDotPosition + 1)}; - std::wstring ConvertToWString(double dValue, int nAccuracy) - { - int nNewAccuracy = (-1 != nAccuracy) ? nAccuracy : GetMinAccuracy(dValue); + if (std::wstring::npos == unFirstPosition) + return wsValue.substr(0, unDotPosition); - std::wstringstream owsStream; - owsStream << std::fixed << std::setprecision(nNewAccuracy) << dValue; + const size_t unLastPosition = wsValue.find_last_not_of(L'0', unFirstPosition + MINACCURACY - 1); - return owsStream.str(); + return wsValue.substr(0, unLastPosition + 1); } std::wstring ConvertToWString(const std::vector& arValues, int nAccuracy) { - std::wstringstream owsStream; + std::wstring wsValue; for (double dValue : arValues) - owsStream << std::fixed << std::setprecision((-1 != nAccuracy) ? nAccuracy : GetMinAccuracy(dValue)) << dValue << L" "; + wsValue += ConvertToWString(dValue, nAccuracy) + L' '; - owsStream.seekp(-1, std::ios_base::end); + wsValue.pop_back(); - return owsStream.str(); + return wsValue; } + + std::wstring ConvertToUnicode(const unsigned char* pText, unsigned long unLength, unsigned short uchCharSet) + { + NSStringExt::CConverter::ESingleByteEncoding eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_DEFAULT;; + + // Соответствие Charset -> Codepage: http://support.microsoft.com/kb/165478 + // http://msdn.microsoft.com/en-us/library/cc194829.aspx + // Charset Name Charset Value(hex) Codepage number + // ------------------------------------------------------ + // + // DEFAULT_CHARSET 1 (x01) + // SYMBOL_CHARSET 2 (x02) + // OEM_CHARSET 255 (xFF) + // ANSI_CHARSET 0 (x00) 1252 + // RUSSIAN_CHARSET 204 (xCC) 1251 + // EASTEUROPE_CHARSET 238 (xEE) 1250 + // GREEK_CHARSET 161 (xA1) 1253 + // TURKISH_CHARSET 162 (xA2) 1254 + // BALTIC_CHARSET 186 (xBA) 1257 + // HEBREW_CHARSET 177 (xB1) 1255 + // ARABIC _CHARSET 178 (xB2) 1256 + // SHIFTJIS_CHARSET 128 (x80) 932 + // HANGEUL_CHARSET 129 (x81) 949 + // GB2313_CHARSET 134 (x86) 936 + // CHINESEBIG5_CHARSET 136 (x88) 950 + // THAI_CHARSET 222 (xDE) 874 + // JOHAB_CHARSET 130 (x82) 1361 + // VIETNAMESE_CHARSET 163 (xA3) 1258 + + switch (uchCharSet) + { + default: + case DEFAULT_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_DEFAULT; break; + case SYMBOL_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_DEFAULT; break; + case ANSI_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1252; break; + case RUSSIAN_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1251; break; + case EASTEUROPE_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1250; break; + case GREEK_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1253; break; + case TURKISH_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1254; break; + case BALTIC_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1257; break; + case HEBREW_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1255; break; + case ARABIC_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1256; break; + case SHIFTJIS_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP932; break; + case HANGEUL_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP949; break; + case 134/*GB2313_CHARSET*/: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP936; break; + case CHINESEBIG5_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP950; break; + case THAI_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP874; break; + case JOHAB_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1361; break; + case VIETNAMESE_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1258; break; + } + + return NSStringExt::CConverter::GetUnicodeFromSingleByteString(pText, unLength, eCharSet); + } + } diff --git a/DesktopEditor/raster/Metafile/Common/MetaFileUtils.h b/DesktopEditor/raster/Metafile/Common/MetaFileUtils.h index 92222e865b2..3edb5123455 100644 --- a/DesktopEditor/raster/Metafile/Common/MetaFileUtils.h +++ b/DesktopEditor/raster/Metafile/Common/MetaFileUtils.h @@ -46,6 +46,11 @@ namespace MetaFile { + bool Equals(double dFirst, double dSecond, double dEpsilon = DBL_EPSILON); + std::wstring ConvertToUnicode(const unsigned char* pText, unsigned long unLength, unsigned short uchCharSet); + std::wstring ConvertToWString(double dValue, int nAccuracy = -1); + std::wstring ConvertToWString(const std::vector& arValues, int nAccuracy = -1); + struct TRgbQuad { unsigned char r; @@ -66,32 +71,53 @@ namespace MetaFile double dRight; double dBottom; - TSvgViewport() : dLeft(DBL_MAX), dTop(DBL_MAX), dRight(DBL_MIN), dBottom(DBL_MIN) {} + TSvgViewport() : dLeft(DBL_MAX), dTop(DBL_MAX), dRight(-DBL_MAX), dBottom(-DBL_MAX) {} bool Empty() const { - return DBL_MAX == dLeft || DBL_MAX == dTop || DBL_MIN == dRight || DBL_MIN == dBottom || dRight == dLeft || dBottom == dTop; + return Equals(DBL_MAX, dLeft) || Equals(DBL_MAX, dTop) || Equals(-DBL_MAX, dRight) || Equals(-DBL_MAX, dBottom) || Equals(dRight, dLeft) || Equals(dBottom, dTop); } double GetWidth() const { - return (DBL_MAX == dLeft || DBL_MIN == dRight) ? 0 : dRight - dLeft; + return (Equals(DBL_MAX, dLeft) || Equals(-DBL_MAX, dRight)) ? 0 : dRight - dLeft; } double GetHeight() const { - return (DBL_MAX == dTop || DBL_MIN == dBottom) ? 0 : dBottom - dTop; + return (Equals(DBL_MAX, dTop) || Equals(-DBL_MAX, dBottom)) ? 0 : dBottom - dTop; } }; typedef std::pair NodeAttribute; - typedef std::vector NodeAttributes; + // typedef std::vector NodeAttributes; + + class NodeAttributes : public std::vector + { + public: + using std::vector::vector; + + void Add(const std::wstring& wsNameArgument, const std::wstring& wsValueArgument) + { + emplace_back(NodeAttribute{wsNameArgument, wsValueArgument}); + } + + void Add(const std::wstring& wsNameArgument, const double& dValueArgument, int nAccuracy = -1) + { + emplace_back(NodeAttribute{wsNameArgument, ConvertToWString(dValueArgument, nAccuracy)}); + } + + void Add(const std::wstring& wsNameArgument, const int& nValueArgument) + { + emplace_back(NodeAttribute{wsNameArgument, std::to_wstring(nValueArgument)}); + } + }; class CDataStream { public: - CDataStream() : pBuffer(NULL) + CDataStream() : pBuffer(NULL), pBufferEnd(NULL), pCur(NULL), pEnd(NULL) { } @@ -101,10 +127,25 @@ namespace MetaFile void SetStream(BYTE* pBuf, unsigned int unSize) { - pBuffer = pBuf; - pCur = pBuf; - pEnd = pBuf + unSize; - }; + pBuffer = pBuf; + pCur = pBuf; + pBufferEnd = pBuf + unSize; + pEnd = pBufferEnd; + } + + void SetCurrentBlockSize(unsigned int unSize) + { + if (pCur + unSize >= pBufferEnd) + pEnd = pBufferEnd; + else + pEnd = pCur + unSize; + } + + void ClearCurrentBlockSize() + { + pEnd = pBufferEnd; + } + BYTE* GetCurPtr() { return pCur; @@ -118,7 +159,7 @@ namespace MetaFile unsigned char unResult = pCur[0]; pCur++; return unResult; - }; + } unsigned short ReadUShort() { if (pCur + 1 >= pEnd) @@ -127,7 +168,7 @@ namespace MetaFile unsigned short ushResult = (pCur[0]) | ((pCur[1]) << 8); pCur += 2; return ushResult; - }; + } unsigned int ReadULong() { if (pCur + 3 >= pEnd) @@ -136,7 +177,7 @@ namespace MetaFile unsigned int unResult = (unsigned int)((pCur[0] << 0) | ((pCur[1]) << 8) | ((pCur[2]) << 16) | ((pCur[3]) << 24)); pCur += 4; return unResult; - }; + } double ReadDouble() { if (pCur + 3 >= pEnd) @@ -157,19 +198,19 @@ namespace MetaFile int lFracValue = (int)(pCur[3]); pCur += 4; return (double)(lIntValue + (lFracValue / 16.0)); - }; + } char ReadChar() { return (char)ReadUChar(); - }; + } short ReadShort() { return (short)ReadUShort(); - }; + } int ReadLong() { return (int)ReadULong(); - }; + } void ReadBytes(unsigned char* pBuffer, unsigned int ulSize) { size_t ulRemainSize = (pEnd - pCur); @@ -179,7 +220,7 @@ namespace MetaFile { pBuffer[ulIndex] = ReadChar(); } - }; + } void ReadBytes(unsigned short* pBuffer, unsigned int ulSize) { size_t ulRemainSize = (pEnd - pCur) / 2; @@ -1045,20 +1086,23 @@ namespace MetaFile bool IsEof() const { - if (pCur >= pEnd) + if (pCur >= pBufferEnd) return true; return false; } - unsigned int Tell() + unsigned int Tell() const { return (unsigned int)(pCur - pBuffer); } void Skip(unsigned int ulSkip) { - pCur += ulSkip; + if (pCur + ulSkip >= pEnd) + pCur = pEnd; + else + pCur += ulSkip; } void SeekBack(unsigned int ulSkipBack) @@ -1069,9 +1113,10 @@ namespace MetaFile void SeekToStart() { pCur = pBuffer; + ClearCurrentBlockSize(); } - unsigned int CanRead() + unsigned int CanRead() const { return (unsigned int)(pEnd - pCur); } @@ -1083,21 +1128,31 @@ namespace MetaFile *this >> oText; // Читаем OutputString - const unsigned int unCharsCount = oText.unChars; - int nSkip = oText.unOffString - (unOffset + 40); // 40 - размер структуры TEmfEmrText - Skip(nSkip); - T* pString = new T[unCharsCount + 1]; + oText.unChars = std::min(oText.unChars, (UINT)(CanRead() / sizeof(T))); + + if (0 == oText.unChars) + return; + + if (oText.unOffString - 40 > unOffset) + Skip(oText.unOffString - (unOffset + 40)); // 40 - размер структуры TEmfEmrText + + T* pString = new T[oText.unChars + 1]; if (pString) { - pString[unCharsCount] = 0x00; - ReadBytes(pString, unCharsCount); + pString[oText.unChars] = 0x00; + ReadBytes(pString, oText.unChars); oText.pOutputString = pString; } // Читаем OutputDx - nSkip = oText.unOffDx - oText.unOffString - 2 * unCharsCount; - Skip(nSkip); - const unsigned int unDxCount = oText.unOptions & ETO_PDY ? 2 * unCharsCount : unCharsCount; + if (oText.unChars < (UINT32_MAX / 2) && (oText.unOffDx > oText.unOffString) && (oText.unOffDx - oText.unOffString > 2 * oText.unChars)) + Skip(oText.unOffDx - oText.unOffString - 2 * oText.unChars); + + const unsigned int unDxCount = (oText.unOptions & ETO_PDY ? 2 * oText.unChars : oText.unChars); + + if ((CanRead() / 4) < unDxCount || 0 == unDxCount) + return; + unsigned int* pDx = new unsigned int[unDxCount]; if (pDx) { @@ -1114,6 +1169,7 @@ namespace MetaFile private: BYTE *pBuffer; + BYTE *pBufferEnd; BYTE *pCur; BYTE *pEnd; }; @@ -1126,8 +1182,5 @@ namespace MetaFile std::wstring StringNormalization(const std::wstring& wsString); bool StringEquals(const std::wstring& wsFirstString, const std::wstring& wsSecondString); - - std::wstring ConvertToWString(double dValue, int nAccuracy = -1); - std::wstring ConvertToWString(const std::vector& arValues, int nAccuracy = -1); }; #endif // _METAFILE_COMMON_METAFILEUTILS_H diff --git a/DesktopEditor/raster/Metafile/Emf/EmfFile.h b/DesktopEditor/raster/Metafile/Emf/EmfFile.h index d296724fd1f..8d40755bd0e 100644 --- a/DesktopEditor/raster/Metafile/Emf/EmfFile.h +++ b/DesktopEditor/raster/Metafile/Emf/EmfFile.h @@ -117,7 +117,7 @@ namespace MetaFile m_pParser->SetFontManager(pFontManager); } - bool CheckError() + bool CheckError() const { return m_pParser->CheckError(); } @@ -142,7 +142,7 @@ namespace MetaFile m_pParser->SetInterpretator(oInterpretatorType, unWidth, unHeight); } - TRectL* GetBounds() + const TRectL& GetBounds() const { return m_pParser->GetBounds(); } diff --git a/DesktopEditor/raster/Metafile/Emf/EmfInterpretator/CEmfInterpretatorRender.cpp b/DesktopEditor/raster/Metafile/Emf/EmfInterpretator/CEmfInterpretatorRender.cpp index 03126f73276..803ecee518b 100644 --- a/DesktopEditor/raster/Metafile/Emf/EmfInterpretator/CEmfInterpretatorRender.cpp +++ b/DesktopEditor/raster/Metafile/Emf/EmfInterpretator/CEmfInterpretatorRender.cpp @@ -41,7 +41,7 @@ namespace MetaFile } void CEmfInterpretatorRender::DrawString(std::wstring &wsText, unsigned int unCharsCount, double dX, double dY, double *pDx, - int iGraphicsMode, double dXScale, double dYScale) + int iGraphicsMode, double dXScale, double dYScale) { if (NULL != m_pMetaFileRenderer) m_pMetaFileRenderer->DrawString(wsText, unCharsCount, dX, dY, pDx, iGraphicsMode, dXScale, dYScale); @@ -160,6 +160,22 @@ namespace MetaFile return m_pMetaFileRenderer; } + double CEmfInterpretatorRender::GetScaleX() const + { + if (NULL == m_pMetaFileRenderer) + return 1.; + + return m_pMetaFileRenderer->GetScaleX(); + } + + double CEmfInterpretatorRender::GetScaleY() const + { + if (NULL == m_pMetaFileRenderer) + return 1.; + + return m_pMetaFileRenderer->GetScaleY(); + } + void CEmfInterpretatorRender::HANDLE_EMR_RESTOREDC(const int &nIndexDC) { if (NULL != m_pMetaFileRenderer) diff --git a/DesktopEditor/raster/Metafile/Emf/EmfInterpretator/CEmfInterpretatorRender.h b/DesktopEditor/raster/Metafile/Emf/EmfInterpretator/CEmfInterpretatorRender.h index fc7f660df2d..d1a309d7f28 100644 --- a/DesktopEditor/raster/Metafile/Emf/EmfInterpretator/CEmfInterpretatorRender.h +++ b/DesktopEditor/raster/Metafile/Emf/EmfInterpretator/CEmfInterpretatorRender.h @@ -48,6 +48,8 @@ namespace MetaFile CMetaFileRenderer* GetRenderer() const; + double GetScaleX() const; + double GetScaleY() const; private: CMetaFileRenderer *m_pMetaFileRenderer; diff --git a/DesktopEditor/raster/Metafile/Emf/EmfInterpretator/CEmfInterpretatorSvg.cpp b/DesktopEditor/raster/Metafile/Emf/EmfInterpretator/CEmfInterpretatorSvg.cpp index 83dfeb4bce1..8f83a4e6ed9 100644 --- a/DesktopEditor/raster/Metafile/Emf/EmfInterpretator/CEmfInterpretatorSvg.cpp +++ b/DesktopEditor/raster/Metafile/Emf/EmfInterpretator/CEmfInterpretatorSvg.cpp @@ -20,9 +20,7 @@ namespace MetaFile {} CEmfInterpretatorSvg::~CEmfInterpretatorSvg() - { - - } + {} void CEmfInterpretatorSvg::CreateConditional(IMetaFileBase *pParser) { @@ -35,7 +33,8 @@ namespace MetaFile return; std::swap(m_pParser, m_oSecondConditional.m_pParser); - std::swap(m_oClip, m_oSecondConditional.m_oClip); + + SwapClips(m_oClip, m_oSecondConditional.m_oClip); } InterpretatorType CEmfInterpretatorSvg::GetType() const @@ -45,10 +44,10 @@ namespace MetaFile void CEmfInterpretatorSvg::HANDLE_EMR_HEADER(const TEmfHeader &oTEmfHeader) { - m_oViewport.dLeft = oTEmfHeader.oFramePx.Left; - m_oViewport.dTop = oTEmfHeader.oFramePx.Top; - m_oViewport.dRight = oTEmfHeader.oFramePx.Right; - m_oViewport.dBottom = oTEmfHeader.oFramePx.Bottom; + m_oViewport.dLeft = std::min(oTEmfHeader.oFramePx.Left, oTEmfHeader.oFramePx.Right ); + m_oViewport.dTop = std::min(oTEmfHeader.oFramePx.Top, oTEmfHeader.oFramePx.Bottom); + m_oViewport.dRight = std::max(oTEmfHeader.oFramePx.Left, oTEmfHeader.oFramePx.Right ); + m_oViewport.dBottom = std::max(oTEmfHeader.oFramePx.Top, oTEmfHeader.oFramePx.Bottom); m_pXmlWriter->WriteNodeBegin(L"svg", true); m_pXmlWriter->WriteAttribute(L"xmlns", L"http://www.w3.org/2000/svg"); @@ -56,43 +55,42 @@ namespace MetaFile UpdateSize(); - if (m_oViewport.GetWidth() != 0) - m_pXmlWriter->WriteAttribute(L"width", ConvertToWString(m_oViewport.GetWidth())); - - if (m_oViewport.GetHeight() != 0) - m_pXmlWriter->WriteAttribute(L"height", ConvertToWString(m_oViewport.GetHeight())); - - double dXScale = 1, dYScale = 1, dXTranslate = 0, dYTranslate = 0; + double dXScale = 1., dYScale = 1.; if (0 != m_oSizeWindow.X) - { dXScale = m_oSizeWindow.X / m_oViewport.GetWidth(); - dXTranslate = m_oViewport.GetWidth() / 2 * std::abs(dXScale - 1); - - if (dXScale < 1) - dXTranslate = -dXTranslate; - } if (0 != m_oSizeWindow.Y) - { dYScale = m_oSizeWindow.Y / m_oViewport.GetHeight(); - dYTranslate = m_oViewport.GetHeight() / 2 * std::abs(dYScale - 1); - if (dYScale < 1) - dYTranslate = -dYTranslate; - } + if (m_oViewport.GetWidth() != 0) + m_pXmlWriter->WriteAttribute(L"width", ConvertToWString(m_oViewport.GetWidth() * dXScale)); - if (1 != dXScale || 1 != dYScale) - m_pXmlWriter->WriteAttribute(L"transform", L"matrix(" + std::to_wstring(dXScale) + L",0,0," + std::to_wstring(dYScale) + L',' + ConvertToWString(dXTranslate) + L',' + ConvertToWString(dYTranslate) + L')'); + if (m_oViewport.GetHeight() != 0) + m_pXmlWriter->WriteAttribute(L"height", ConvertToWString(m_oViewport.GetHeight() * dYScale)); m_pXmlWriter->WriteNodeEnd(L"svg", true, false); + + if (!Equals(1., dXScale) || !Equals(1., dYScale)) + { + m_pXmlWriter->WriteNodeBegin(L"g", true); + + m_pXmlWriter->WriteAttribute(L"transform", L"scale(" + ConvertToWString(dXScale) + L',' + ConvertToWString(dYScale) + L')'); + + m_pXmlWriter->WriteNodeEnd(L"g", true, false); + } } void CEmfInterpretatorSvg::HANDLE_EMR_EOF() { CloseClip(); + if (!m_wsDefs.empty()) m_pXmlWriter->WriteString(L"" + m_wsDefs + L""); + + if (!Equals(m_oSizeWindow.X, m_oViewport.GetWidth()) || !Equals(m_oSizeWindow.Y, m_oViewport.GetHeight())) + m_pXmlWriter->WriteNodeEnd(L"g", false, false); + m_pXmlWriter->WriteNodeEnd(L"svg", false, false); } @@ -110,7 +108,7 @@ namespace MetaFile if (NULL == pPath) return; - + const std::wstring wsValue = CreatePath(*pPath); if (wsValue.empty()) @@ -120,6 +118,7 @@ namespace MetaFile AddClip(); AddFill(arAttributes); + AddShapeRendering(arAttributes); AddTransform(arAttributes); WriteNode(L"path" , arAttributes); @@ -178,6 +177,7 @@ namespace MetaFile AddStroke(arAttributes); AddNoneFill(arAttributes); + AddShapeRendering(arAttributes); if (AD_COUNTERCLOCKWISE == m_pParser->GetArcDirection()) { @@ -203,7 +203,7 @@ namespace MetaFile double dStartAngle = GetEllipseAngle(oBox.Left, oBox.Top, oBox.Right, oBox.Bottom, oStart.X, oStart.Y); double dSweepAngle = GetEllipseAngle(oBox.Left, oBox.Top, oBox.Right, oBox.Bottom, oEnd.X, oEnd.Y); - if (NULL != m_pParser && m_pParser->GetTransform()->M22 < 0) + if (NULL != m_pParser && m_pParser->GetTransform().M22 < 0) { dStartAngle *= -1; dSweepAngle *= -1; @@ -241,6 +241,7 @@ namespace MetaFile AddStroke(arAttributes); AddNoneFill(arAttributes); + AddShapeRendering(arAttributes); if (AD_COUNTERCLOCKWISE == m_pParser->GetArcDirection()) { @@ -266,7 +267,7 @@ namespace MetaFile double dStartAngle = GetEllipseAngle(oBox.Left, oBox.Top, oBox.Right, oBox.Bottom, oStart.X, oStart.Y); double dSweepAngle = GetEllipseAngle(oBox.Left, oBox.Top, oBox.Right, oBox.Bottom, oEnd.X, oEnd.Y); - if (NULL != m_pParser && m_pParser->GetTransform()->M22 < 0) + if (NULL != m_pParser && m_pParser->GetTransform().M22 < 0) { dStartAngle *= -1; dSweepAngle *= -1; @@ -295,6 +296,7 @@ namespace MetaFile AddStroke(arAttributes); AddNoneFill(arAttributes); + AddShapeRendering(arAttributes); if (AD_COUNTERCLOCKWISE == m_pParser->GetArcDirection()) { @@ -328,6 +330,7 @@ namespace MetaFile {L"ry", ConvertToWString((oNewRect.Bottom - oNewRect.Top) / 2)}}; AddStroke(arAttributes); AddFill(arAttributes); + AddShapeRendering(arAttributes); AddTransform(arAttributes); AddClip(); @@ -368,6 +371,7 @@ namespace MetaFile {L"y2", ConvertToWString(oPoint.Y)}}; AddStroke(arAttributes); + AddShapeRendering(arAttributes); AddTransform(arAttributes); AddClip(); @@ -376,21 +380,29 @@ namespace MetaFile void CEmfInterpretatorSvg::HANDLE_EMR_PIE(const TRectL &oBox, const TPointL &oStart, const TPointL &oEnd) { - short shCenterX = (oBox.Left + oBox.Right) / 2; - short shCenterY = (oBox.Top + oBox.Bottom) / 2; + int nCenterX = (oBox.Left + oBox.Right) / 2; + int nCenterY = (oBox.Top + oBox.Bottom) / 2; short shRadiusX = std::abs(oBox.Right - oBox.Left) / 2; short shRadiusY = std::abs(oBox.Bottom - oBox.Top) / 2; - std::wstring wsPath = L'M' + ConvertToWString(shCenterX) + L' ' + ConvertToWString(shCenterY) + L' ' + + double dStartAngle = std::atan2(oStart.Y - nCenterY, oStart.X - nCenterX); + double dEndAngle = std::atan2(oEnd.Y - nCenterY, oEnd.X - nCenterX); + + if (dEndAngle > dStartAngle) + dEndAngle -= 2 * M_PI; + + std::wstring wsPath = L'M' + ConvertToWString(nCenterX) + L' ' + ConvertToWString(nCenterY) + L' ' + L'L' + ConvertToWString(oStart.X)+ L' ' + ConvertToWString(oStart.Y)+ L' ' + - L'A' + ConvertToWString(shRadiusX) + L' ' + ConvertToWString(shRadiusY) + L" 0, 0, 0, " + ConvertToWString(oEnd.X) + L' ' + ConvertToWString(oEnd.Y) + L' ' + - L'L' + ConvertToWString(shCenterX) + L' ' + ConvertToWString(shCenterY) + L" Z"; + L'A' + ConvertToWString(shRadiusX) + L' ' + ConvertToWString(shRadiusY) + L" 0 " + + ((std::abs(dEndAngle - dStartAngle) > M_PI) ? L'1' : L'0') + L" 0 " + ConvertToWString(oEnd.X) + L' ' + ConvertToWString(oEnd.Y) + L' ' + + L'L' + ConvertToWString(nCenterX) + L' ' + ConvertToWString(nCenterY) + L" Z"; NodeAttributes arAttributes = {{L"d", wsPath}}; AddStroke(arAttributes); AddFill(arAttributes); + AddShapeRendering(arAttributes); AddTransform(arAttributes); AddClip(); @@ -405,14 +417,15 @@ namespace MetaFile std::wstring wsValue = L"M " + ConvertToWString(arPoints[0].X) + L' ' + ConvertToWString(arPoints[0].Y) + L" C "; for (unsigned int unIndex = 1; unIndex + 2 < arPoints.size(); unIndex += 3) - wsValue += ConvertToWString(arPoints[unIndex].X) + L' ' + ConvertToWString(arPoints[unIndex].Y) + L' ' + - ConvertToWString(arPoints[unIndex + 1].X) + L' ' + ConvertToWString(arPoints[unIndex + 1].Y) + L' ' + - ConvertToWString(arPoints[unIndex + 2].X) + L' ' + ConvertToWString(arPoints[unIndex + 2].Y) + L' '; + wsValue += ConvertToWString(arPoints[unIndex].X) + L' ' + ConvertToWString(arPoints[unIndex].Y) + L' ' + + ConvertToWString(arPoints[unIndex + 1].X) + L' ' + ConvertToWString(arPoints[unIndex + 1].Y) + L' ' + + ConvertToWString(arPoints[unIndex + 2].X) + L' ' + ConvertToWString(arPoints[unIndex + 2].Y) + L' '; NodeAttributes arAttributes = {{L"d", wsValue}}; AddStroke(arAttributes); AddNoneFill(arAttributes); + AddShapeRendering(arAttributes); AddTransform(arAttributes); AddClip(); @@ -427,14 +440,15 @@ namespace MetaFile std::wstring wsValue = L"M " + ConvertToWString(arPoints[0].X) + L' ' + ConvertToWString(arPoints[0].Y) + L" C "; for (unsigned int unIndex = 1; unIndex + 2 < arPoints.size(); unIndex += 3) - wsValue += ConvertToWString(arPoints[unIndex].X) + L' ' + ConvertToWString(arPoints[unIndex].Y) + L' ' + - ConvertToWString(arPoints[unIndex + 1].X) + L' ' + ConvertToWString(arPoints[unIndex + 1].Y) + L' ' + - ConvertToWString(arPoints[unIndex + 2].X) + L' ' + ConvertToWString(arPoints[unIndex + 2].Y) + L' '; + wsValue += ConvertToWString(arPoints[unIndex].X) + L' ' + ConvertToWString(arPoints[unIndex].Y) + L' ' + + ConvertToWString(arPoints[unIndex + 1].X) + L' ' + ConvertToWString(arPoints[unIndex + 1].Y) + L' ' + + ConvertToWString(arPoints[unIndex + 2].X) + L' ' + ConvertToWString(arPoints[unIndex + 2].Y) + L' '; NodeAttributes arAttributes = {{L"d", wsValue}}; AddStroke(arAttributes); AddNoneFill(arAttributes); + AddShapeRendering(arAttributes); AddTransform(arAttributes); AddClip(); @@ -449,14 +463,15 @@ namespace MetaFile std::wstring wsValue = L"M " + ConvertToWString(arPoints[0].X) + L' ' + ConvertToWString(arPoints[0].Y) + L" C "; for (unsigned int unIndex = 1; unIndex + 2 < arPoints.size(); unIndex += 3) - wsValue += ConvertToWString(arPoints[unIndex].X) + L' ' + ConvertToWString(arPoints[unIndex].Y) + L' ' + - ConvertToWString(arPoints[unIndex + 1].X) + L' ' + ConvertToWString(arPoints[unIndex + 1].Y) + L' ' + - ConvertToWString(arPoints[unIndex + 2].X) + L' ' + ConvertToWString(arPoints[unIndex + 2].Y) + L' '; + wsValue += ConvertToWString(arPoints[unIndex].X) + L' ' + ConvertToWString(arPoints[unIndex].Y) + L' ' + + ConvertToWString(arPoints[unIndex + 1].X) + L' ' + ConvertToWString(arPoints[unIndex + 1].Y) + L' ' + + ConvertToWString(arPoints[unIndex + 2].X) + L' ' + ConvertToWString(arPoints[unIndex + 2].Y) + L' '; NodeAttributes arAttributes = {{L"d", wsValue}}; AddStroke(arAttributes); AddNoneFill(arAttributes); + AddShapeRendering(arAttributes); AddTransform(arAttributes); AddClip(); @@ -471,14 +486,15 @@ namespace MetaFile std::wstring wsValue = L"M " + ConvertToWString(arPoints[0].X) + L' ' + ConvertToWString(arPoints[0].Y) + L" C "; for (unsigned int unIndex = 1; unIndex + 2 < arPoints.size(); unIndex += 3) - wsValue += ConvertToWString(arPoints[unIndex].X) + L' ' + ConvertToWString(arPoints[unIndex].Y) + L' ' + - ConvertToWString(arPoints[unIndex + 1].X) + L' ' + ConvertToWString(arPoints[unIndex + 1].Y) + L' ' + - ConvertToWString(arPoints[unIndex + 2].X) + L' ' + ConvertToWString(arPoints[unIndex + 2].Y) + L' '; + wsValue += ConvertToWString(arPoints[unIndex].X) + L' ' + ConvertToWString(arPoints[unIndex].Y) + L' ' + + ConvertToWString(arPoints[unIndex + 1].X) + L' ' + ConvertToWString(arPoints[unIndex + 1].Y) + L' ' + + ConvertToWString(arPoints[unIndex + 2].X) + L' ' + ConvertToWString(arPoints[unIndex + 2].Y) + L' '; NodeAttributes arAttributes = {{L"d", wsValue}}; AddStroke(arAttributes); AddNoneFill(arAttributes); + AddShapeRendering(arAttributes); AddTransform(arAttributes); AddClip(); @@ -512,9 +528,9 @@ namespace MetaFile wsValue += L" C "; oLastType = 0x04; } - wsValue += ConvertToWString(arPoints[unIndex].X) + L',' + ConvertToWString(arPoints[unIndex].Y) + L' ' + - ConvertToWString(arPoints[unIndex + 1].X) + L',' + ConvertToWString(arPoints[unIndex + 1].Y) + L' ' + - ConvertToWString(arPoints[unIndex + 2].X) + L',' + ConvertToWString(arPoints[unIndex + 2].Y) + L' '; + wsValue += ConvertToWString(arPoints[unIndex].X) + L',' + ConvertToWString(arPoints[unIndex].Y) + L' ' + + ConvertToWString(arPoints[unIndex + 1].X) + L',' + ConvertToWString(arPoints[unIndex + 1].Y) + L' ' + + ConvertToWString(arPoints[unIndex + 2].X) + L',' + ConvertToWString(arPoints[unIndex + 2].Y) + L' '; unIndex += 3; } @@ -529,6 +545,7 @@ namespace MetaFile AddStroke(arAttributes); AddNoneFill(arAttributes); + AddShapeRendering(arAttributes); AddTransform(arAttributes); AddClip(); @@ -562,9 +579,9 @@ namespace MetaFile wsValue += L" C "; oLastType = 0x04; } - wsValue += ConvertToWString(arPoints[unIndex].X) + L',' + ConvertToWString(arPoints[unIndex].Y) + L' ' + - ConvertToWString(arPoints[unIndex + 1].X) + L',' + ConvertToWString(arPoints[unIndex + 1].Y) + L' ' + - ConvertToWString(arPoints[unIndex + 2].X) + L',' + ConvertToWString(arPoints[unIndex + 2].Y) + L' '; + wsValue += ConvertToWString(arPoints[unIndex].X) + L',' + ConvertToWString(arPoints[unIndex].Y) + L' ' + + ConvertToWString(arPoints[unIndex + 1].X) + L',' + ConvertToWString(arPoints[unIndex + 1].Y) + L' ' + + ConvertToWString(arPoints[unIndex + 2].X) + L',' + ConvertToWString(arPoints[unIndex + 2].Y) + L' '; unIndex += 3; } @@ -579,6 +596,7 @@ namespace MetaFile AddStroke(arAttributes); AddNoneFill(arAttributes); + AddShapeRendering(arAttributes); AddTransform(arAttributes); AddClip(); @@ -599,6 +617,7 @@ namespace MetaFile AddStroke(arAttributes); AddFill(arAttributes); + AddShapeRendering(arAttributes); AddTransform(arAttributes); AddClip(); @@ -619,6 +638,7 @@ namespace MetaFile AddStroke(arAttributes); AddFill(arAttributes); + AddShapeRendering(arAttributes); AddTransform(arAttributes); AddClip(); @@ -639,6 +659,7 @@ namespace MetaFile AddStroke(arAttributes); AddNoneFill(arAttributes); + AddShapeRendering(arAttributes); AddTransform(arAttributes); AddClip(); @@ -661,6 +682,7 @@ namespace MetaFile AddStroke(arAttributes); AddNoneFill(arAttributes); + AddShapeRendering(arAttributes); AddTransform(arAttributes); AddClip(); @@ -683,6 +705,7 @@ namespace MetaFile AddStroke(arAttributes); AddNoneFill(arAttributes); + AddShapeRendering(arAttributes); AddTransform(arAttributes); AddClip(); @@ -705,6 +728,7 @@ namespace MetaFile AddStroke(arAttributes); AddNoneFill(arAttributes); + AddShapeRendering(arAttributes); AddTransform(arAttributes); AddClip(); @@ -732,10 +756,11 @@ namespace MetaFile AddStroke(arAttributes); AddFill(arAttributes); + AddShapeRendering(arAttributes); AddTransform(arAttributes); AddClip(); - arAttributes.push_back({L"fill-rule", L"evenodd"}); + arAttributes.Add(L"fill-rule", L"evenodd"); WriteNode(L"path", arAttributes); } @@ -761,10 +786,11 @@ namespace MetaFile AddStroke(arAttributes); AddFill(arAttributes); + AddShapeRendering(arAttributes); AddTransform(arAttributes); AddClip(); - arAttributes.push_back({L"fill-rule", L"evenodd"}); + arAttributes.Add(L"fill-rule", L"evenodd"); WriteNode(L"path", arAttributes); } @@ -790,10 +816,11 @@ namespace MetaFile AddStroke(arAttributes); AddFill(arAttributes); + AddShapeRendering(arAttributes); AddTransform(arAttributes); AddClip(); - arAttributes.push_back({L"fill-rule", L"evenodd"}); + arAttributes.Add(L"fill-rule", L"evenodd"); WriteNode(L"path", arAttributes); } @@ -819,10 +846,11 @@ namespace MetaFile AddStroke(arAttributes); AddFill(arAttributes); + AddShapeRendering(arAttributes); AddTransform(arAttributes); AddClip(); - arAttributes.push_back({L"fill-rule", L"evenodd"}); + arAttributes.Add(L"fill-rule", L"evenodd"); WriteNode(L"path", arAttributes); } @@ -831,13 +859,14 @@ namespace MetaFile { TRectD oNewRect = TranslateRect(oBox); - NodeAttributes arAttributes = {{L"x", ConvertToWString(oNewRect.Left)}, - {L"y", ConvertToWString(oNewRect.Top)}, - {L"width", ConvertToWString(oNewRect.Right - oNewRect.Left)}, - {L"height", ConvertToWString(oNewRect.Bottom - oNewRect.Top)}}; + NodeAttributes arAttributes = {{L"x", ConvertToWString(oNewRect.Left)}, + {L"y", ConvertToWString(oNewRect.Top)}, + {L"width", ConvertToWString(oNewRect.Right - oNewRect.Left)}, + {L"height", ConvertToWString(oNewRect.Bottom - oNewRect.Top)}}; AddStroke(arAttributes); AddFill(arAttributes, oNewRect.Right - oNewRect.Left, oNewRect.Bottom - oNewRect.Top); + AddShapeRendering(arAttributes); AddTransform(arAttributes); AddClip(); @@ -848,15 +877,16 @@ namespace MetaFile { TRectD oNewRect = TranslateRect(oBox); - NodeAttributes arAttributes = {{L"x", ConvertToWString(oNewRect.Left)}, - {L"y", ConvertToWString(oNewRect.Top)}, - {L"width", ConvertToWString(oNewRect.Right - oNewRect.Left)}, - {L"height", ConvertToWString(oNewRect.Bottom - oNewRect.Top)}, - {L"rx", ConvertToWString((double)oCorner.X / 2.)}, - {L"ry", ConvertToWString((double)oCorner.Y / 2.)}}; + NodeAttributes arAttributes = {{L"x", ConvertToWString(oNewRect.Left)}, + {L"y", ConvertToWString(oNewRect.Top)}, + {L"width", ConvertToWString(oNewRect.Right - oNewRect.Left)}, + {L"height", ConvertToWString(oNewRect.Bottom - oNewRect.Top)}, + {L"rx", ConvertToWString((double)oCorner.X / 2.)}, + {L"ry", ConvertToWString((double)oCorner.Y / 2.)}}; AddStroke(arAttributes); AddFill(arAttributes); + AddShapeRendering(arAttributes); AddTransform(arAttributes); AddClip(); @@ -892,6 +922,7 @@ namespace MetaFile AddStroke(arAttributes); AddFill(arAttributes, std::fabs(oBounds.Right - oBounds.Left), std::fabs(oBounds.Bottom - oBounds.Top)); + AddShapeRendering(arAttributes); AddTransform(arAttributes); AddClip(); @@ -917,6 +948,7 @@ namespace MetaFile AddStroke(arAttributes); AddNoneFill(arAttributes); + AddShapeRendering(arAttributes); AddTransform(arAttributes); AddClip(); @@ -931,15 +963,16 @@ namespace MetaFile NodeAttributes arAttributes; AddFill(arAttributes); + AddShapeRendering(arAttributes); AddTransform(arAttributes); AddClip(); if (4 == arVertex.size()) { - arAttributes.push_back({L"x", std::to_wstring(std::min(arVertex[0].nX, arVertex[1].nX))}); - arAttributes.push_back({L"y", std::to_wstring(std::min(arVertex[0].nY, arVertex[2].nY))}); - arAttributes.push_back({L"width", std::to_wstring(std::abs(arVertex[1].nX - arVertex[0].nX))}); - arAttributes.push_back({L"height", std::to_wstring(std::abs(arVertex[2].nY - arVertex[0].nY))}); + arAttributes.Add(L"x", std::min(arVertex[0].nX, arVertex[1].nX)); + arAttributes.Add(L"y", std::min(arVertex[0].nY, arVertex[2].nY)); + arAttributes.Add(L"width", std::abs(arVertex[1].nX - arVertex[0].nX)); + arAttributes.Add(L"height", std::abs(arVertex[2].nY - arVertex[0].nY)); WriteNode(L"rect" , arAttributes); } else if (3 == arVertex.size()) @@ -953,7 +986,7 @@ namespace MetaFile std::wstring wsValue = CreatePath(oPath); if (!wsValue.empty()) - arAttributes.push_back({L"d", wsValue}); + arAttributes.Add(L"d", wsValue); WriteNode(L"path" , arAttributes); } @@ -972,16 +1005,17 @@ namespace MetaFile { oTempRect = TranslateRect(oRect); - wsValue += L"M " + ConvertToWString(oTempRect.Left) + L',' + ConvertToWString(oTempRect.Top) + L' ' + - L"L " + ConvertToWString(oTempRect.Right) + L',' + ConvertToWString(oTempRect.Top) + L' ' + - ConvertToWString(oTempRect.Right) + L',' + ConvertToWString(oTempRect.Bottom) + L' ' + - ConvertToWString(oTempRect.Left) + L',' + ConvertToWString(oTempRect.Bottom) + L' ' + - ConvertToWString(oTempRect.Left) + L',' + ConvertToWString(oTempRect.Top) + L' '; + wsValue += L"M " + ConvertToWString(oTempRect.Left) + L',' + ConvertToWString(oTempRect.Top) + L' ' + + L"L " + ConvertToWString(oTempRect.Right) + L',' + ConvertToWString(oTempRect.Top) + L' ' + + ConvertToWString(oTempRect.Right) + L',' + ConvertToWString(oTempRect.Bottom) + L' ' + + ConvertToWString(oTempRect.Left) + L',' + ConvertToWString(oTempRect.Bottom) + L' ' + + ConvertToWString(oTempRect.Left) + L',' + ConvertToWString(oTempRect.Top) + L' '; } NodeAttributes arAttributes = {{L"d", wsValue}}; AddFill(arAttributes); + AddShapeRendering(arAttributes); AddTransform(arAttributes); AddClip(); @@ -1001,16 +1035,17 @@ namespace MetaFile { oTempRect = TranslateRect(oRect); - wsValue += L"M " + ConvertToWString(oTempRect.Left) + L',' + ConvertToWString(oTempRect.Top) + L' ' + - L"L " + ConvertToWString(oTempRect.Right) + L',' + ConvertToWString(oTempRect.Top) + L' ' + - ConvertToWString(oTempRect.Right) + L',' + ConvertToWString(oTempRect.Bottom) + L' ' + - ConvertToWString(oTempRect.Left) + L',' + ConvertToWString(oTempRect.Bottom) + L' ' + - ConvertToWString(oTempRect.Left) + L',' + ConvertToWString(oTempRect.Top) + L' '; + wsValue += L"M " + ConvertToWString(oTempRect.Left) + L',' + ConvertToWString(oTempRect.Top) + L' ' + + L"L " + ConvertToWString(oTempRect.Right) + L',' + ConvertToWString(oTempRect.Top) + L' ' + + ConvertToWString(oTempRect.Right) + L',' + ConvertToWString(oTempRect.Bottom) + L' ' + + ConvertToWString(oTempRect.Left) + L',' + ConvertToWString(oTempRect.Bottom) + L' ' + + ConvertToWString(oTempRect.Left) + L',' + ConvertToWString(oTempRect.Top) + L' '; } NodeAttributes arAttributes = {{L"d", wsValue}}; AddFill(arAttributes); + AddShapeRendering(arAttributes); AddTransform(arAttributes); AddClip(); @@ -1019,6 +1054,7 @@ namespace MetaFile void CEmfInterpretatorSvg::HANDLE_EMR_FRAMERGN(const TRectL &oBounds, unsigned int unIhBrush, int nWidth, int nHeight, const TRegionDataHeader &oRegionDataHeader, const std::vector &arRects) { + m_bUpdatedClip = false; } void CEmfInterpretatorSvg::HANDLE_EMFPLUS_OFFSETCLIP(double dX, double dY) @@ -1065,7 +1101,7 @@ namespace MetaFile { TRectD oNewRect = oRect.ToRectD(); - if (NULL != m_pParser && m_pParser->GetTransform()->M22 < 0) + if (NULL != m_pParser && m_pParser->GetTransform().M22 < 0) { dStartAngle *= -1; dSweepAngle *= -1; @@ -1088,6 +1124,7 @@ namespace MetaFile AddStroke(arAttributes); AddNoneFill(arAttributes); + AddShapeRendering(arAttributes); if (AD_COUNTERCLOCKWISE == m_pParser->GetArcDirection()) { @@ -1114,14 +1151,15 @@ namespace MetaFile std::wstring wsValue = L"M " + ConvertToWString(arPoints[0].X) + L' ' + ConvertToWString(arPoints[0].Y) + L" C "; for (unsigned int unIndex = 1; unIndex + 2 < arPoints.size(); unIndex += 3) - wsValue += ConvertToWString(arPoints[unIndex].X) + L' ' + ConvertToWString(arPoints[unIndex].Y) + L' ' + - ConvertToWString(arPoints[unIndex + 1].X) + L' ' + ConvertToWString(arPoints[unIndex + 1].Y) + L' ' + - ConvertToWString(arPoints[unIndex + 2].X) + L' ' + ConvertToWString(arPoints[unIndex + 2].Y) + L' '; + wsValue += ConvertToWString(arPoints[unIndex].X) + L' ' + ConvertToWString(arPoints[unIndex].Y) + L' ' + + ConvertToWString(arPoints[unIndex + 1].X) + L' ' + ConvertToWString(arPoints[unIndex + 1].Y) + L' ' + + ConvertToWString(arPoints[unIndex + 2].X) + L' ' + ConvertToWString(arPoints[unIndex + 2].Y) + L' '; NodeAttributes arAttributes = {{L"d", wsValue}}; AddStroke(arAttributes); AddNoneFill(arAttributes); + AddShapeRendering(arAttributes); AddTransform(arAttributes); AddClip(); @@ -1143,7 +1181,7 @@ namespace MetaFile if (NULL == m_pParser || wsString.size() != arGlyphPos.size()) return; - IFont *pFont = m_pParser->GetFont(); + const IFont *pFont = m_pParser->GetFont(); if (NULL == pFont) return; @@ -1161,43 +1199,51 @@ namespace MetaFile int nColor = m_pParser->GetTextColor(); if (0 != nColor) - arNodeAttributes.push_back({L"fill", L"rgb(" + INTCOLOR_TO_RGB(nColor) + L')'}); + arNodeAttributes.Add(L"fill", CalculateColor(nColor, 255)); double dFontHeight = std::fabs(pFont->GetHeight()); if (dFontHeight < 0.01) dFontHeight = 18; - arNodeAttributes.push_back({L"font-size", ConvertToWString(dFontHeight)}); + arNodeAttributes.Add(L"font-size", dFontHeight); - std::wstring wsFontName = pFont->GetFaceName(); + NSStringUtils::CStringBuilder oFontName; + oFontName.WriteEncodeXmlString(pFont->GetFaceName()); - if (!wsFontName.empty()) + if (0 != oFontName.GetSize()) { + #ifndef BUILDING_WASM_MODULE NSFonts::CFontSelectFormat oFormat; oFormat.wsName = new std::wstring(pFont->GetFaceName()); NSFonts::CFontInfo *pFontInfo = m_pParser->GetFontManager()->GetFontInfoByParams(oFormat); - if (NULL != pFontInfo && !StringEquals(wsFontName, pFontInfo->m_wsFontName)) - wsFontName = L"'" + wsFontName + L"', '" + pFontInfo->m_wsFontName + L"'"; + if (NULL != pFontInfo && !StringEquals(*oFormat.wsName, pFontInfo->m_wsFontName)) + { + oFontName.Clear(); + oFontName.WriteEncodeXmlString(L"\'"); + oFontName.WriteEncodeXmlString(*oFormat.wsName); + oFontName.WriteEncodeXmlString(L"\',\'"); + oFontName.WriteEncodeXmlString(pFontInfo->m_wsFontName); + oFontName.WriteEncodeXmlString(L"\'"); + } + #endif + arNodeAttributes.Add(L"font-family", oFontName.GetData()); } - if (!wsFontName.empty()) - arNodeAttributes.push_back({L"font-family", wsFontName}); - if (pFont->GetWeight() > 550) - arNodeAttributes.push_back({L"font-weight", L"bold"}); + arNodeAttributes.Add(L"font-weight", L"bold"); if (pFont->IsItalic()) - arNodeAttributes.push_back({L"font-style", L"italic"}); + arNodeAttributes.Add(L"font-style", L"italic"); if (pFont->IsUnderline() && pFont->IsStrikeOut()) - arNodeAttributes.push_back({L"text-decoration", L"underline line-through"}); + arNodeAttributes.Add(L"text-decoration", L"underline line-through"); else if (pFont->IsUnderline()) - arNodeAttributes.push_back({L"text-decoration", L"underline"}); + arNodeAttributes.Add(L"text-decoration", L"underline"); else if (pFont->IsStrikeOut()) - arNodeAttributes.push_back({L"text-decoration", L"line-through"}); + arNodeAttributes.Add(L"text-decoration", L"line-through"); AddTransform(arNodeAttributes); AddClip(); @@ -1213,8 +1259,8 @@ namespace MetaFile wsX.pop_back(); wsY.pop_back(); - arNodeAttributes.push_back({L"x", wsX}); - arNodeAttributes.push_back({L"y", wsY}); + arNodeAttributes.Add(L"x", wsX); + arNodeAttributes.Add(L"y", wsY); WriteNode(L"text", arNodeAttributes, wsText); } @@ -1228,7 +1274,8 @@ namespace MetaFile {L"rx", ConvertToWString((oNewRect.Right - oNewRect.Left) / 2)}, {L"ry", ConvertToWString((oNewRect.Bottom - oNewRect.Top) / 2)}}; AddStroke(arAttributes); - AddFill(arAttributes); + AddNoneFill(arAttributes); + AddShapeRendering(arAttributes); AddTransform(arAttributes); AddClip(); @@ -1249,6 +1296,7 @@ namespace MetaFile AddStroke(arAttributes); AddNoneFill(arAttributes); + AddShapeRendering(arAttributes); AddTransform(arAttributes); AddClip(); @@ -1268,7 +1316,9 @@ namespace MetaFile NodeAttributes arAttributes = {{L"d", wsValue}}; AddStroke(arAttributes); + AddLineCaps(arAttributes, pPath); AddNoneFill(arAttributes); + AddShapeRendering(arAttributes); AddTransform(arAttributes); AddClip(); @@ -1290,17 +1340,18 @@ namespace MetaFile { oTempRect = oRect.ToRectD(); - wsValue += L"M " + ConvertToWString(oTempRect.Left) + L',' + ConvertToWString(oTempRect.Top) + - L" L " + ConvertToWString(oTempRect.Right) + L',' + ConvertToWString(oTempRect.Top) + L' ' + - ConvertToWString(oTempRect.Right) + L',' + ConvertToWString(oTempRect.Bottom) + L' ' + - ConvertToWString(oTempRect.Left) + L',' + ConvertToWString(oTempRect.Bottom) + L' ' + - ConvertToWString(oTempRect.Left) + L',' + ConvertToWString(oTempRect.Top) + L' '; + wsValue += L"M " + ConvertToWString(oTempRect.Left) + L',' + ConvertToWString(oTempRect.Top) + + L" L " + ConvertToWString(oTempRect.Right) + L',' + ConvertToWString(oTempRect.Top) + L' ' + + ConvertToWString(oTempRect.Right) + L',' + ConvertToWString(oTempRect.Bottom) + L' ' + + ConvertToWString(oTempRect.Left) + L',' + ConvertToWString(oTempRect.Bottom) + L' ' + + ConvertToWString(oTempRect.Left) + L',' + ConvertToWString(oTempRect.Top) + L' '; } NodeAttributes arAttributes = {{L"d", wsValue}}; AddStroke(arAttributes); AddNoneFill(arAttributes); + AddShapeRendering(arAttributes); AddTransform(arAttributes); AddClip(); @@ -1309,7 +1360,7 @@ namespace MetaFile void CEmfInterpretatorSvg::HANDLE_EMFPLUS_DRAWSTRING(short shOgjectIndex, unsigned int unBrushId, unsigned int unFormatID, const std::wstring &wsString, const TEmfPlusRectF &oRect) { - WriteText(wsString, TPointD(oRect.dX, oRect.dY), oRect.ToRectL(), TPointD(m_pParser->GetTransform()->M11, m_pParser->GetTransform()->M22)); + WriteText(wsString, TPointD(oRect.dX, oRect.dY), oRect.ToRectL(), TPointD(m_pParser->GetTransform().M11, m_pParser->GetTransform().M22)); } void CEmfInterpretatorSvg::HANDLE_EMFPLUS_FILLCLOSEDCURVE(unsigned int unBrushId, double dTension, const std::vector &arPoints) @@ -1327,6 +1378,7 @@ namespace MetaFile {L"ry", ConvertToWString((oNewRect.Bottom - oNewRect.Top) / 2)}}; AddFill(arAttributes); + AddShapeRendering(arAttributes); AddTransform(arAttributes); AddClip(); @@ -1348,6 +1400,7 @@ namespace MetaFile TRectD oPathRect = pPath->GetBounds(); AddFill(arAttributes, std::fabs(oPathRect.Right - oPathRect.Left), std::fabs(oPathRect.Bottom - oPathRect.Top)); + AddShapeRendering(arAttributes); AddTransform(arAttributes); AddClip(); @@ -1372,6 +1425,7 @@ namespace MetaFile NodeAttributes arAttributes = {{L"points", wsValue}}; AddFill(arAttributes); + AddShapeRendering(arAttributes); AddTransform(arAttributes); NodeAttributes arGAttributes; @@ -1382,27 +1436,32 @@ namespace MetaFile void CEmfInterpretatorSvg::HANDLE_EMFPLUS_FILLRECTS(unsigned int unBrushId, const std::vector &arRects) { + if (arRects.empty()) + return; + std::wstring wsValue; TRectD oTempRect; + TXForm oFileTransform(m_pParser->GetTransform()); for (const TEmfPlusRectF& oRect : arRects) { oTempRect = oRect.ToRectD(); - m_pParser->GetTransform()->Apply(oTempRect.Left, oTempRect.Top); - m_pParser->GetTransform()->Apply(oTempRect.Right, oTempRect.Bottom); - - wsValue += L"M " + ConvertToWString(oTempRect.Left) + L',' + ConvertToWString(oTempRect.Top) + - L" L " + ConvertToWString(oTempRect.Right) + L',' + ConvertToWString(oTempRect.Top) + L' ' + - ConvertToWString(oTempRect.Right) + L',' + ConvertToWString(oTempRect.Bottom) + L' ' + - ConvertToWString(oTempRect.Left) + L',' + ConvertToWString(oTempRect.Bottom) + L' ' + - ConvertToWString(oTempRect.Left) + L',' + ConvertToWString(oTempRect.Top) + L' '; + wsValue += L"M " + ConvertToWString(oTempRect.Left) + L',' + ConvertToWString(oTempRect.Top) + + L" L " + ConvertToWString(oTempRect.Right) + L',' + ConvertToWString(oTempRect.Top) + L' ' + + ConvertToWString(oTempRect.Right) + L',' + ConvertToWString(oTempRect.Bottom) + L' ' + + ConvertToWString(oTempRect.Left) + L',' + ConvertToWString(oTempRect.Bottom) + L' ' + + ConvertToWString(oTempRect.Left) + L',' + ConvertToWString(oTempRect.Top) + L' '; } + wsValue.pop_back(); + NodeAttributes arAttributes = {{L"d", wsValue}}; + AddTransform(arAttributes); AddFill(arAttributes); + AddShapeRendering(arAttributes); AddClip(); WriteNode(L"path", arAttributes); @@ -1412,73 +1471,17 @@ namespace MetaFile { } - + void CEmfInterpretatorSvg::HANDLE_EMFPLUS_RESTORE(unsigned int) { m_bUpdatedClip = false; } - void CEmfInterpretatorSvg::DrawBitmap(double dX, double dY, double dW, double dH, BYTE* pBuffer, unsigned int unWidth, unsigned int unHeight) + void CEmfInterpretatorSvg::DrawBitmap(double dX, double dY, double dW, double dH, BYTE *pBuffer, unsigned int unWidth, unsigned int unHeight) { - if (NULL == pBuffer || 0 == dW || 0 == dH || 0 == unWidth || 0 == unHeight) - return; - - if (1 == unWidth && 1 == unHeight) - { - NodeAttributes arAttributes = {{L"x", ConvertToWString(dX)}, - {L"y", ConvertToWString(dY)}, - {L"width", ConvertToWString(dW)}, - {L"height", ConvertToWString(dH)}, - {L"fill", L"rgb(" + std::to_wstring(pBuffer[2]) + L',' + std::to_wstring(pBuffer[1]) + L',' + std::to_wstring(pBuffer[0]) + L',' + std::to_wstring(pBuffer[3]) + L')'}}; - - AddTransform(arAttributes); - - WriteNode(L"rect", arAttributes); - - return; - } - - CBgraFrame oFrame; - - oFrame.put_Data(pBuffer); - oFrame.put_Width(unWidth); - oFrame.put_Height(unHeight); - - BYTE* pNewBuffer = NULL; - int nNewSize = 0; - - oFrame.Encode(pNewBuffer, nNewSize, 4); - oFrame.put_Data(NULL); - - if (0 < nNewSize) - { - int nImageSize = NSBase64::Base64EncodeGetRequiredLength(nNewSize); - unsigned char* ucValue = new unsigned char[nImageSize]; - - if (NULL == ucValue) - return; - - NSBase64::Base64Encode(pNewBuffer, nNewSize, ucValue, &nImageSize); - std::wstring wsValue(ucValue, ucValue + nImageSize); - - RELEASEARRAYOBJECTS(ucValue); - - NodeAttributes arAttributes = {{L"x", ConvertToWString(dX)}, - {L"y", ConvertToWString(dY)}, - {L"width", ConvertToWString(dW)}, - {L"height", ConvertToWString(dH)}, - {L"xlink:href", L"data:image/png;base64," + wsValue}}; - - AddTransform(arAttributes); - AddClip(); - - WriteNode(L"image", arAttributes); - } - - if (NULL != pNewBuffer) - delete [] pNewBuffer; + CInterpretatorSvgBase::DrawBitmap(dX, dY, dW, dH, pBuffer, unWidth, unHeight); } - + void CEmfInterpretatorSvg::ResetClip() { CInterpretatorSvgBase::ResetClip(); @@ -1499,25 +1502,15 @@ namespace MetaFile CInterpretatorSvgBase::PathClip(oPath, nClipMode, pTransform); } - TRectD CEmfInterpretatorSvg::TranslateRect(const TRectL &oRect) const + void CEmfInterpretatorSvg::SwapClips(CSvgClip& oFirstClip, CSvgClip& oSecondClip) { - TRectD oNewRect(oRect.Left, oRect.Top, oRect.Right, oRect.Bottom); + if (oFirstClip.StartedClip()) + WriteNodeEnd(L"g"); - if (oNewRect.Right < oNewRect.Left) - { - double dTempValue = oNewRect.Left; - oNewRect.Left = oNewRect.Right; - oNewRect.Right = dTempValue; - } - - if (oNewRect.Bottom < oNewRect.Top) - { - double dTempValue = oNewRect.Top; - oNewRect.Top = oNewRect.Bottom; - oNewRect.Bottom = dTempValue; - } + if (oSecondClip.StartedClip()) + WriteNodeBegin(L"g", {{L"clip-path", L"url(#" + oSecondClip.GetClipId() + L')'}}); - return oNewRect; + std::swap(oFirstClip, oSecondClip); } } diff --git a/DesktopEditor/raster/Metafile/Emf/EmfInterpretator/CEmfInterpretatorSvg.h b/DesktopEditor/raster/Metafile/Emf/EmfInterpretator/CEmfInterpretatorSvg.h index 1503e59034f..0c1a40361de 100644 --- a/DesktopEditor/raster/Metafile/Emf/EmfInterpretator/CEmfInterpretatorSvg.h +++ b/DesktopEditor/raster/Metafile/Emf/EmfInterpretator/CEmfInterpretatorSvg.h @@ -226,7 +226,7 @@ namespace MetaFile void SetTransform(double& dM11, double& dM12, double& dM21, double& dM22, double& dX, double& dY) override {}; void GetTransform(double* pdM11, double* pdM12, double* pdM21, double* pdM22, double* pdX, double* pdY) override {}; - TRectD TranslateRect(const TRectL &oRect) const; + void SwapClips(CSvgClip& oFirstClip, CSvgClip& oSecondClip); }; } diff --git a/DesktopEditor/raster/Metafile/Emf/EmfObjects.cpp b/DesktopEditor/raster/Metafile/Emf/EmfObjects.cpp index 034cedecf05..09f8874cedd 100644 --- a/DesktopEditor/raster/Metafile/Emf/EmfObjects.cpp +++ b/DesktopEditor/raster/Metafile/Emf/EmfObjects.cpp @@ -46,7 +46,7 @@ namespace MetaFile CEmfObjectBase::~CEmfObjectBase() {} - EEmfObjectType CEmfObjectBase::GetType() + EEmfObjectType CEmfObjectBase::GetType() const { return EMF_OBJECT_UNKNOWN; } @@ -63,7 +63,7 @@ namespace MetaFile RELEASEOBJECT(pDibBuffer); } - EEmfObjectType CEmfLogBrushEx::GetType() + EEmfObjectType CEmfLogBrushEx::GetType() const { return EMF_OBJECT_BRUSH; } @@ -102,62 +102,91 @@ namespace MetaFile #endif } - int CEmfLogBrushEx::GetColor() + int CEmfLogBrushEx::GetColor() const { return METAFILE_RGBA(oColor.r, oColor.g, oColor.b, 0); } - int CEmfLogBrushEx::GetColor2() + int CEmfLogBrushEx::GetColor2() const { return 0; } - unsigned int CEmfLogBrushEx::GetStyle() + unsigned int CEmfLogBrushEx::GetStyle() const { return unBrushStyle; } - unsigned int CEmfLogBrushEx::GetStyleEx() + unsigned int CEmfLogBrushEx::GetStyleEx() const { return 0; } - unsigned int CEmfLogBrushEx::GetHatch() + unsigned int CEmfLogBrushEx::GetHatch() const { return unBrushHatch; } - unsigned int CEmfLogBrushEx::GetAlpha() + unsigned int CEmfLogBrushEx::GetAlpha() const { return 0xff; } - unsigned int CEmfLogBrushEx::GetAlpha2() + unsigned int CEmfLogBrushEx::GetAlpha2() const { return 0xff; } - std::wstring CEmfLogBrushEx::GetDibPatterPath() + std::wstring CEmfLogBrushEx::GetDibPatterPath() const { return wsDibPatternPath; } - void CEmfLogBrushEx::GetBounds(double &left, double &top, double &width, double &height) + void CEmfLogBrushEx::GetBounds(double &left, double &top, double &width, double &height) const {} - void CEmfLogBrushEx::GetCenterPoint(double &dX, double &dY) + void CEmfLogBrushEx::GetCenterPoint(double &dX, double &dY) const {} - void CEmfLogBrushEx::GetDibPattern(unsigned char **pBuffer, unsigned int &unWidth, unsigned int &unHeight) + void CEmfLogBrushEx::GetDibPattern(unsigned char **pBuffer, unsigned int &unWidth, unsigned int &unHeight) const { - *pBuffer = pDibBuffer; - unWidth = unDibWidth; - unHeight = unDibHeigth; + *pBuffer = pDibBuffer; + unWidth = unDibWidth; + unHeight = unDibHeigth; } - CEmfLogFont::CEmfLogFont(bool bFixedLength) : m_bFixedLength(bFixedLength) + void CEmfLogBrushEx::GetGradientColors(std::vector& arColors, std::vector& arPositions) const + { + arColors = {(long)(GetColor() + (GetAlpha() << 24)), (long)(GetColor2() + (GetAlpha2() << 24))}; + arPositions = {0., 1.}; + } + + CEmfLogFont::CEmfLogFont(bool bFixedLength) + : m_bFixedLength(bFixedLength) { oDesignVector.pValues = NULL; + + oLogFontEx.oLogFont.nHeight = DEFAULT_FONT_SIZE; + oLogFontEx.oLogFont.nWidth = 0; + oLogFontEx.oLogFont.nEscapement = 0; + oLogFontEx.oLogFont.nOrientation = 0; + oLogFontEx.oLogFont.nWeight = 400; + oLogFontEx.oLogFont.uchItalic = 0x00; + oLogFontEx.oLogFont.uchUnderline = 0x00; + oLogFontEx.oLogFont.uchStrikeOut = 0x00; + oLogFontEx.oLogFont.uchCharSet = 0x01; + oLogFontEx.oLogFont.uchOutPrecision = 0x00; + oLogFontEx.oLogFont.uchClipPrecision = 0x00; + oLogFontEx.oLogFont.uchQuality = 0x00; + oLogFontEx.oLogFont.uchPitchAndFamily = 0x00; + + memset(oLogFontEx.oLogFont.ushFaceName, 0x00, 32); + + oLogFontEx.oLogFont.ushFaceName[0] = 'A'; + oLogFontEx.oLogFont.ushFaceName[1] = 'r'; + oLogFontEx.oLogFont.ushFaceName[2] = 'i'; + oLogFontEx.oLogFont.ushFaceName[3] = 'a'; + oLogFontEx.oLogFont.ushFaceName[4] = 'l'; } CEmfLogFont::~CEmfLogFont() @@ -165,63 +194,64 @@ namespace MetaFile RELEASEOBJECT(oDesignVector.pValues); } - EEmfObjectType CEmfLogFont::GetType() + EEmfObjectType CEmfLogFont::GetType() const { return EMF_OBJECT_FONT; } - double CEmfLogFont::GetHeight() + double CEmfLogFont::GetHeight() const { return (double)oLogFontEx.oLogFont.nHeight; } - std::wstring CEmfLogFont::GetFaceName() + std::wstring CEmfLogFont::GetFaceName() const { - return std::wstring(NSFile::CUtf8Converter::GetWStringFromUTF16(oLogFontEx.oLogFont.ushFaceName, 32).c_str()); + const std::wstring wsFaceName{NSFile::CUtf8Converter::GetWStringFromUTF16(oLogFontEx.oLogFont.ushFaceName, 32)}; + return wsFaceName.substr(0, wsFaceName.find(L'\0')); } - int CEmfLogFont::GetWeight() + int CEmfLogFont::GetWeight() const { return oLogFontEx.oLogFont.nWeight; } - bool CEmfLogFont::IsItalic() + bool CEmfLogFont::IsItalic() const { - return (0x01 == oLogFontEx.oLogFont.uchItalic ? true : false); + return 0x01 == oLogFontEx.oLogFont.uchItalic; } - bool CEmfLogFont::IsStrikeOut() + bool CEmfLogFont::IsStrikeOut() const { - return (0x01 == oLogFontEx.oLogFont.uchStrikeOut ? true : false); + return 0x01 == oLogFontEx.oLogFont.uchStrikeOut; } - bool CEmfLogFont::IsUnderline() + bool CEmfLogFont::IsUnderline() const { - return (0x01 == oLogFontEx.oLogFont.uchUnderline ? true : false); + return 0x01 == oLogFontEx.oLogFont.uchUnderline ; } - int CEmfLogFont::GetEscapement() + int CEmfLogFont::GetEscapement() const { return oLogFontEx.oLogFont.nEscapement; } - int CEmfLogFont::GetCharSet() + int CEmfLogFont::GetCharSet() const { return oLogFontEx.oLogFont.uchCharSet; } - bool CEmfLogFont::IsFixedLength() + bool CEmfLogFont::IsFixedLength() const { return m_bFixedLength; } - int CEmfLogFont::GetOrientation() + int CEmfLogFont::GetOrientation() const { return oLogFontEx.oLogFont.nOrientation; } CEmfLogPen::CEmfLogPen() - : unPenStyle(PS_SOLID), unWidth(1), oColor(0, 0, 0), pStyleEntry(NULL) + : unPenStyle(PS_SOLID), unWidth(1), oColor(0, 0, 0), unNumStyleEntries(0), pStyleEntry(NULL) {} CEmfLogPen::~CEmfLogPen() @@ -229,47 +259,57 @@ namespace MetaFile RELEASEOBJECT(pStyleEntry); } - EEmfObjectType CEmfLogPen::GetType() + EEmfObjectType CEmfLogPen::GetType() const { return EMF_OBJECT_PEN; } - int CEmfLogPen::GetColor() + int CEmfLogPen::GetColor() const { return METAFILE_RGBA(oColor.r, oColor.g, oColor.b, oColor.a); } - unsigned int CEmfLogPen::GetStyle() + unsigned int CEmfLogPen::GetStyle() const { return unPenStyle; } - double CEmfLogPen::GetWidth() + double CEmfLogPen::GetWidth() const { return (double)unWidth; } - unsigned int CEmfLogPen::GetAlpha() + unsigned int CEmfLogPen::GetAlpha() const { return 0xff; } - double CEmfLogPen::GetMiterLimit() + double CEmfLogPen::GetMiterLimit() const { return 0; } - double CEmfLogPen::GetDashOffset() + double CEmfLogPen::GetDashOffset() const { return 0; } - void CEmfLogPen::GetDashData(double *&arDatas, unsigned int &unSize) + void CEmfLogPen::GetDashData(double *&arDatas, unsigned int &unSize) const { arDatas = NULL; unSize = 0; } + const ILineCap* CEmfLogPen::GetStartLineCap() const + { + return NULL; + } + + const ILineCap* CEmfLogPen::GetEndLineCap() const + { + return NULL; + } + CEmfLogPalette::CEmfLogPalette() : ushNumberOfEntries(0), pPaletteEntries(NULL) {} @@ -278,7 +318,7 @@ namespace MetaFile RELEASEOBJECT(pPaletteEntries); } - EEmfObjectType CEmfLogPalette::GetType() + EEmfObjectType CEmfLogPalette::GetType() const { return EMF_OBJECT_PALETTE; } diff --git a/DesktopEditor/raster/Metafile/Emf/EmfObjects.h b/DesktopEditor/raster/Metafile/Emf/EmfObjects.h index d75fa92f16c..e077f2c8fe9 100644 --- a/DesktopEditor/raster/Metafile/Emf/EmfObjects.h +++ b/DesktopEditor/raster/Metafile/Emf/EmfObjects.h @@ -53,7 +53,7 @@ namespace MetaFile public: CEmfObjectBase(); virtual ~CEmfObjectBase(); - virtual EEmfObjectType GetType(); + virtual EEmfObjectType GetType() const; }; class CEmfLogBrushEx : public CEmfObjectBase, public IBrush @@ -61,22 +61,24 @@ namespace MetaFile public: CEmfLogBrushEx(); virtual ~CEmfLogBrushEx(); - virtual EEmfObjectType GetType(); + virtual EEmfObjectType GetType() const override; void SetDibPattern(unsigned char* pBuffer, unsigned int ulWidth, unsigned int ulHeight); // IBrush - int GetColor(); - int GetColor2(); - unsigned int GetStyle(); - unsigned int GetStyleEx(); - unsigned int GetHatch(); - unsigned int GetAlpha(); - unsigned int GetAlpha2(); - std::wstring GetDibPatterPath(); - void GetBounds(double& left, double& top, double& width, double& height); - void GetCenterPoint(double& dX, double& dY); - void GetDibPattern(unsigned char** pBuffer, unsigned int &unWidth, unsigned int &unHeight); + int GetColor() const override; + int GetColor2() const override; + unsigned int GetStyle() const override; + unsigned int GetStyleEx() const override; + unsigned int GetHatch() const override; + unsigned int GetAlpha() const override; + unsigned int GetAlpha2() const override; + std::wstring GetDibPatterPath() const override; + void GetBounds(double& left, double& top, double& width, double& height) const override; + void GetCenterPoint(double& dX, double& dY) const override; + void GetDibPattern(unsigned char** pBuffer, unsigned int &unWidth, unsigned int &unHeight) const override; + + void GetGradientColors(std::vector& arColors, std::vector& arPositions) const override; public: unsigned int unBrushStyle; TRGBA oColor; @@ -92,19 +94,20 @@ namespace MetaFile public: CEmfLogFont(bool bFixedLength = false); virtual ~CEmfLogFont(); - virtual EEmfObjectType GetType(); + virtual EEmfObjectType GetType() const override; + + bool IsFixedLength() const; // IFont - double GetHeight(); - std::wstring GetFaceName(); - int GetWeight(); - bool IsItalic(); - bool IsStrikeOut(); - bool IsUnderline(); - int GetEscapement(); - int GetCharSet(); - bool IsFixedLength(); - int GetOrientation(); + double GetHeight() const override; + int GetWeight() const override; + bool IsItalic() const override; + bool IsStrikeOut() const override; + bool IsUnderline() const override; + int GetEscapement() const override; + int GetCharSet() const override; + int GetOrientation() const override; + std::wstring GetFaceName() const override; public: TEmfLogFontEx oLogFontEx; TEmfDesignVector oDesignVector; @@ -118,16 +121,18 @@ namespace MetaFile public: CEmfLogPen(); virtual ~CEmfLogPen(); - virtual EEmfObjectType GetType(); + virtual EEmfObjectType GetType() const override; // IPen - int GetColor(); - unsigned int GetStyle(); - double GetWidth(); - unsigned int GetAlpha(); - double GetMiterLimit(); - double GetDashOffset(); - void GetDashData(double*& arDatas, unsigned int& unSize); + int GetColor() const override; + unsigned int GetStyle() const override; + double GetWidth() const override; + unsigned int GetAlpha() const override; + double GetMiterLimit() const override; + double GetDashOffset() const override; + void GetDashData(double*& arDatas, unsigned int& unSize) const override; + const ILineCap* GetStartLineCap() const override; + const ILineCap* GetEndLineCap() const override; public: unsigned int unPenStyle; unsigned int unWidth; @@ -141,7 +146,7 @@ namespace MetaFile public: CEmfLogPalette(); virtual ~CEmfLogPalette(); - virtual EEmfObjectType GetType(); + virtual EEmfObjectType GetType() const override; public: unsigned short ushNumberOfEntries; TEmfLogPaletteEntry* pPaletteEntries; diff --git a/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfParser.cpp b/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfParser.cpp index 0cedd55c13b..6f4bdc8e007 100644 --- a/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfParser.cpp +++ b/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfParser.cpp @@ -14,9 +14,157 @@ #include "../../Wmf/WmfParser/CWmfParser.h" +#define PRINT_EMF_RECORD(type) do {} while(false) + +#ifdef _DEBUG + #ifdef LOG_EMF_RECORDS + #if 1 == LOG_EMF_RECORDS + #ifdef PRINTING_EMF_RECORDS + #if 1 == PRINTING_EMF_RECORDS + static const struct ActionNamesEmf + { + int actionNumber; + std::wstring actionName; + } actionNamesEmf[] = + { + { 0, L"Unknown"}, + { EMR_HEADER, L"EMR_HEADER"}, + { EMR_POLYBEZIER, L"EMR_POLYBEZIER"}, + { EMR_POLYGON, L"EMR_POLYGON"}, + { EMR_POLYLINE, L"EMR_POLYLINE"}, + { EMR_POLYBEZIERTO, L"EMR_POLYBEZIERTO"}, + { EMR_POLYLINETO, L"EMR_POLYLINETO"}, + { EMR_POLYPOLYLINE, L"EMR_POLYPOLYLINE"}, + { EMR_POLYPOLYGON, L"EMR_POLYPOLYGON"}, + { EMR_SETWINDOWEXTEX, L"EMR_SETWINDOWEXTEX"}, + { EMR_SETWINDOWORGEX, L"EMR_SETWINDOWORGEX"}, + { EMR_SETVIEWPORTEXTEX, L"EMR_SETVIEWPORTEXTEX"}, + { EMR_SETVIEWPORTORGEX, L"EMR_SETVIEWPORTORGEX"}, + { EMR_SETBRUSHORGEX, L"EMR_SETBRUSHORGEX"}, + { EMR_EOF, L"EMR_EOF"}, + { EMR_SETPIXELV, L"EMR_SETPIXELV"}, + { EMR_SETMAPPERFLAGS, L"EMR_SETMAPPERFLAGS"}, + { EMR_SETMAPMODE, L"EMR_SETMAPMODE"}, + { EMR_SETBKMODE, L"EMR_SETBKMODE"}, + { EMR_SETPOLYFILLMODE, L"EMR_SETPOLYFILLMODE"}, + { EMR_SETROP2, L"EMR_SETROP2"}, + { EMR_SETSTRETCHBLTMODE, L"EMR_SETSTRETCHBLTMODE"}, + { EMR_SETTEXTALIGN, L"EMR_SETTEXTALIGN"}, + { EMR_SETCOLORADJUSTMENT, L"EMR_SETCOLORADJUSTMENT"}, + { EMR_SETTEXTCOLOR, L"EMR_SETTEXTCOLOR"}, + { EMR_SETBKCOLOR, L"EMR_SETBKCOLOR"}, + { EMR_OFFSETCLIPRGN, L"EMR_OFFSETCLIPRGN"}, + { EMR_MOVETOEX, L"EMR_MOVETOEX"}, + { EMR_SETMETARGN, L"EMR_SETMETARGN"}, + { EMR_EXCLUDECLIPRECT, L"EMR_EXCLUDECLIPRECT"}, + { EMR_INTERSECTCLIPRECT, L"EMR_INTERSECTCLIPRECT"}, + { EMR_SCALEVIEWPORTEXTEX, L"EMR_SCALEVIEWPORTEXTEX"}, + { EMR_SCALEWINDOWEXTEX, L"EMR_SCALEWINDOWEXTEX"}, + { EMR_SAVEDC, L"EMR_SAVEDC"}, + { EMR_RESTOREDC, L"EMR_RESTOREDC"}, + { EMR_SETWORLDTRANSFORM, L"EMR_SETWORLDTRANSFORM"}, + { EMR_MODIFYWORLDTRANSFORM, L"EMR_MODIFYWORLDTRANSFORM"}, + { EMR_SELECTOBJECT, L"EMR_SELECTOBJECT"}, + { EMR_CREATEPEN, L"EMR_CREATEPEN"}, + { EMR_CREATEBRUSHINDIRECT, L"EMR_CREATEBRUSHINDIRECT"}, + { EMR_DELETEOBJECT, L"EMR_DELETEOBJECT"}, + { EMR_ANGLEARC, L"EMR_ANGLEARC"}, + { EMR_ELLIPSE, L"EMR_ELLIPSE"}, + { EMR_RECTANGLE, L"EMR_RECTANGLE"}, + { EMR_ROUNDRECT, L"EMR_ROUNDRECT"}, + { EMR_ARC, L"EMR_ARC"}, + { EMR_CHORD, L"EMR_CHORD"}, + { EMR_PIE, L"EMR_PIE"}, + { EMR_SELECTPALETTE, L"EMR_SELECTPALETTE"}, + { EMR_CREATEPALETTE, L"EMR_CREATEPALETTE"}, + { EMR_SETPALETTEENTRIES, L"EMR_SETPALETTEENTRIES"}, + { EMR_RESIZEPALETTE, L"EMR_RESIZEPALETTE"}, + { EMR_REALIZEPALETTE, L"EMR_REALIZEPALETTE"}, + { EMR_EXTFLOODFILL, L"EMR_EXTFLOODFILL"}, + { EMR_LINETO, L"EMR_LINETO"}, + { EMR_ARCTO, L"EMR_ARCTO"}, + { EMR_POLYDRAW, L"EMR_POLYDRAW"}, + { EMR_SETARCDIRECTION, L"EMR_SETARCDIRECTION"}, + { EMR_SETMITERLIMIT, L"EMR_SETMITERLIMIT"}, + { EMR_BEGINPATH, L"EMR_BEGINPATH"}, + { EMR_ENDPATH, L"EMR_ENDPATH"}, + { EMR_CLOSEFIGURE, L"EMR_CLOSEFIGURE"}, + { EMR_FILLPATH, L"EMR_FILLPATH"}, + { EMR_STROKEANDFILLPATH, L"EMR_STROKEANDFILLPATH"}, + { EMR_STROKEPATH, L"EMR_STROKEPATH"}, + { EMR_FLATTENPATH, L"EMR_FLATTENPATH"}, + { EMR_WIDENPATH, L"EMR_WIDENPATH"}, + { EMR_SELECTCLIPPATH, L"EMR_SELECTCLIPPATH"}, + { EMR_ABORTPATH, L"EMR_ABORTPATH"}, + { 69, L"Unknown"}, + { EMR_GDICOMMENT, L"EMR_GDICOMMENT"}, + { EMR_FILLRGN, L"EMR_FILLRGN"}, + { EMR_FRAMERGN, L"EMR_FRAMERGN"}, + { EMR_INVERTRGN, L"EMR_INVERTRGN"}, + { EMR_PAINTRGN, L"EMR_PAINTRGN"}, + { EMR_EXTSELECTCLIPRGN, L"EMR_EXTSELECTCLIPRGN"}, + { EMR_BITBLT, L"EMR_BITBLT"}, + { EMR_STRETCHBLT, L"EMR_STRETCHBLT"}, + { EMR_MASKBLT, L"EMR_MASKBLT"}, + { EMR_PLGBLT, L"EMR_PLGBLT"}, + { EMR_SETDIBITSTODEVICE, L"EMR_SETDIBITSTODEVICE"}, + { EMR_STRETCHDIBITS, L"EMR_STRETCHDIBITS"}, + { EMR_EXTCREATEFONTINDIRECTW, L"EMR_EXTCREATEFONTINDIRECTW"}, + { EMR_EXTTEXTOUTA, L"EMR_EXTTEXTOUTA"}, + { EMR_EXTTEXTOUTW, L"EMR_EXTTEXTOUTW"}, + { EMR_POLYBEZIER16, L"EMR_POLYBEZIER16"}, + { EMR_POLYGON16, L"EMR_POLYGON16"}, + { EMR_POLYLINE16, L"EMR_POLYLINE16"}, + { EMR_POLYBEZIERTO16, L"EMR_POLYBEZIERTO16"}, + { EMR_POLYLINETO16, L"EMR_POLYLINETO16"}, + { EMR_POLYPOLYLINE16, L"EMR_POLYPOLYLINE16"}, + { EMR_POLYPOLYGON16, L"EMR_POLYPOLYGON16"}, + { EMR_POLYDRAW16, L"EMR_POLYDRAW16"}, + { EMR_CREATEMONOBRUSH, L"EMR_CREATEMONOBRUSH"}, + { EMR_CREATEDIBPATTERNBRUSHPT, L"EMR_CREATEDIBPATTERNBRUSHPT"}, + { EMR_EXTCREATEPEN, L"EMR_EXTCREATEPEN"}, + { EMR_POLYTEXTOUTA, L"EMR_POLYTEXTOUTA"}, + { EMR_POLYTEXTOUTW, L"EMR_POLYTEXTOUTW"}, + { EMR_SETICMMODE, L"EMR_SETICMMODE"}, + { EMR_CREATECOLORSPACE, L"EMR_CREATECOLORSPACE"}, + { EMR_SETCOLORSPACE, L"EMR_SETCOLORSPACE"}, + { EMR_DELETECOLORSPACE, L"EMR_DELETECOLORSPACE"}, + { EMR_GLSRECORD, L"EMR_GLSRECORD"}, + { EMR_GLSBOUNDEDRECORD, L"EMR_GLSBOUNDEDRECORD"}, + { EMR_PIXELFORMAT, L"EMR_PIXELFORMAT"}, + { EMR_RESERVED_105, L"EMR_RESERVED_105"}, + { EMR_RESERVED_106, L"EMR_RESERVED_106"}, + { EMR_RESERVED_107, L"EMR_RESERVED_107"}, + { EMR_RESERVED_108, L"EMR_RESERVED_108"}, + { EMR_RESERVED_109, L"EMR_RESERVED_109"}, + { EMR_RESERVED_110, L"EMR_RESERVED_110"}, + { EMR_COLORCORRECTPALETTE, L"EMR_COLORCORRECTPALETTE"}, + { EMR_SETICMPROFILEA, L"EMR_SETICMPROFILEA"}, + { EMR_SETICMPROFILEW, L"EMR_SETICMPROFILEW"}, + { EMR_ALPHABLEND, L"EMR_ALPHABLEND"}, + { EMR_SETLAYOUT, L"EMR_SETLAYOUT"}, + { EMR_TRANSPARENTBLT, L"EMR_TRANSPARENTBLT"}, + { EMR_RESERVED_117, L"EMR_RESERVED_117"}, + { EMR_GRADIENTFILL, L"EMR_GRADIENTFILL"}, + { EMR_RESERVED_119, L"EMR_RESERVED_119"}, + { EMR_RESERVED_120, L"EMR_RESERVED_120"}, + { EMR_COLORMATCHTOTARGETW, L"EMR_COLORMATCHTOTARGETW"}, + { EMR_CREATECOLORSPACEW, L"EMR_CREATECOLORSPACEW"} + }; + + #define PRINT_EMF_RECORD(type) \ + if (0 <= type && type <= EMR_CREATECOLORSPACEW) \ + std::wcout << L"LEVEL [" << unFileLevel << L"] EMF Record: " << actionNamesEmf[type].actionName << std::endl + #endif + #endif + #endif + #endif +#endif + namespace MetaFile { - CEmfParser::CEmfParser() : m_pEmfPlusParser(NULL){} + CEmfParser::CEmfParser() + : m_pEmfPlusParser(NULL) {} CEmfParser::~CEmfParser() { @@ -38,6 +186,9 @@ namespace MetaFile if (!m_oStream.IsValid()) SetError(); + if (NULL != m_pInterpretator) + GO_UP_LEVEL; + unsigned int ulSize, ulType; unsigned int ulRecordIndex = 0; @@ -63,6 +214,8 @@ namespace MetaFile m_ulRecordPos = m_oStream.Tell(); m_ulRecordSize = ulSize - 8; + m_oStream.SetCurrentBlockSize(m_ulRecordSize); + if (ulType < EMR_MIN || ulType > EMR_MAX) { if (ENHMETA_SIGNATURE != m_oHeader.ulSignature || 0x00010000 != m_oHeader.ulVersion) @@ -74,6 +227,9 @@ namespace MetaFile if (0 == ulRecordIndex && EMR_HEADER != ulType) return SetError(); + if (NULL != m_pInterpretator && (!BanEMFProcesses()|| ulType == EMR_HEADER || ulType == EMR_EOF || ulType == EMR_GDICOMMENT)) + PRINT_EMF_RECORD(ulType); + switch (ulType) { //----------------------------------------------------------- @@ -211,8 +367,13 @@ namespace MetaFile int need_skip = m_ulRecordSize - (m_oStream.Tell() - m_ulRecordPos); m_oStream.Skip(need_skip); + + if (0 != need_skip && NULL != m_pInterpretator) + PRINT_LOG(L"SKIP BYTES: " << need_skip); + ulRecordIndex++; + m_oStream.ClearCurrentBlockSize(); } while (!CheckError()); if (!CheckError()) @@ -221,6 +382,9 @@ namespace MetaFile if (!m_bEof) HANDLE_EMR_EOF(); + if (NULL != m_pInterpretator) + GO_DOWN_LEVEL_BELOW; + ClearFile(); } @@ -239,7 +403,7 @@ namespace MetaFile CEmfParserBase::ClearFile(); } - EmfParserType CEmfParser::GetType() + EmfParserType CEmfParser::GetType() const { return EmfParserType::EmfParser; } @@ -249,11 +413,9 @@ namespace MetaFile m_oStream.SetStream(pBuf, unSize); } - void CEmfParser::SetInterpretator(IOutputDevice* pOutput) + bool CEmfParser::BanEMFProcesses() const { - CEmfParserBase::SetInterpretator(pOutput); - if (m_pEmfPlusParser) - RELEASEOBJECT(m_pEmfPlusParser); + return NULL != m_pEmfPlusParser && m_pEmfPlusParser->GetBanEMFProcesses(); } bool CEmfParser::ReadImage(unsigned int offBmi, unsigned int cbBmi, unsigned int offBits, unsigned int cbBits, unsigned int ulSkip, BYTE **ppBgraBuffer, unsigned int *pulWidth, unsigned int *pulHeight) @@ -318,7 +480,7 @@ namespace MetaFile m_oStream >> oBitmap; - if (NULL == m_pEmfPlusParser || !m_pEmfPlusParser->GetBanEMFProcesses()) + if (!BanEMFProcesses()) HANDLE_EMR_ALPHABLEND(oBitmap); } @@ -328,7 +490,7 @@ namespace MetaFile m_oStream >> oBitmap; - if (NULL == m_pEmfPlusParser || !m_pEmfPlusParser->GetBanEMFProcesses()) + if (!BanEMFProcesses()) HANDLE_EMR_STRETCHDIBITS(oBitmap); } @@ -338,7 +500,7 @@ namespace MetaFile m_oStream >> oBitmap; - if (NULL == m_pEmfPlusParser || !m_pEmfPlusParser->GetBanEMFProcesses()) + if (!BanEMFProcesses()) HANDLE_EMR_BITBLT(oBitmap); } @@ -348,7 +510,7 @@ namespace MetaFile m_oStream >> oBitmap; - if (NULL == m_pEmfPlusParser || !m_pEmfPlusParser->GetBanEMFProcesses()) + if (!BanEMFProcesses()) HANDLE_EMR_SETDIBITSTODEVICE(oBitmap); } @@ -358,7 +520,7 @@ namespace MetaFile m_oStream >> oBitmap; - if (NULL == m_pEmfPlusParser || !m_pEmfPlusParser->GetBanEMFProcesses()) + if (!BanEMFProcesses()) HANDLE_EMR_STRETCHBLT(oBitmap); } @@ -383,7 +545,7 @@ namespace MetaFile void CEmfParser::Read_EMR_SAVEDC() { - if (NULL == m_pEmfPlusParser || !m_pEmfPlusParser->GetBanEMFProcesses()) + if (!BanEMFProcesses()) HANDLE_EMR_SAVEDC(); } @@ -393,7 +555,7 @@ namespace MetaFile m_oStream >> lSavedDC; - if (NULL == m_pEmfPlusParser || !m_pEmfPlusParser->GetBanEMFProcesses()) + if (!BanEMFProcesses()) HANDLE_EMR_RESTOREDC(lSavedDC); } @@ -405,7 +567,7 @@ namespace MetaFile m_oStream >> oXForm; m_oStream >> ulMode; - if (NULL == m_pEmfPlusParser || !m_pEmfPlusParser->GetBanEMFProcesses()) + if (!BanEMFProcesses()) HANDLE_EMR_MODIFYWORLDTRANSFORM(oXForm, ulMode); } @@ -415,7 +577,7 @@ namespace MetaFile m_oStream >> oXForm; - if (NULL == m_pEmfPlusParser || !m_pEmfPlusParser->GetBanEMFProcesses()) + if (!BanEMFProcesses()) HANDLE_EMR_SETWORLDTRANSFORM(oXForm); } @@ -429,7 +591,7 @@ namespace MetaFile m_oStream >> ulBrushIndex; m_oStream >> *pBrush; - if (NULL == m_pEmfPlusParser || !m_pEmfPlusParser->GetBanEMFProcesses()) + if (!BanEMFProcesses()) HANDLE_EMR_CREATEBRUSHINDIRECT(ulBrushIndex, pBrush); } @@ -439,7 +601,7 @@ namespace MetaFile m_oStream >> oColor; - if (NULL == m_pEmfPlusParser || !m_pEmfPlusParser->GetBanEMFProcesses()) + if (!BanEMFProcesses()) HANDLE_EMR_SETTEXTCOLOR(oColor); } @@ -449,7 +611,7 @@ namespace MetaFile m_oStream >> ulObjectIndex; - if (NULL == m_pEmfPlusParser || !m_pEmfPlusParser->GetBanEMFProcesses()) + if (!BanEMFProcesses()) HANDLE_EMR_SELECTOBJECT(ulObjectIndex); } @@ -466,7 +628,7 @@ namespace MetaFile m_oStream >> ulIndex; m_oStream >> *pFont; - if (NULL == m_pEmfPlusParser || !m_pEmfPlusParser->GetBanEMFProcesses()) + if (!BanEMFProcesses()) HANDLE_EMR_EXTCREATEFONTINDIRECTW(ulIndex, pFont); } @@ -476,7 +638,7 @@ namespace MetaFile m_oStream >> ulAlign; - if (NULL == m_pEmfPlusParser || !m_pEmfPlusParser->GetBanEMFProcesses()) + if (!BanEMFProcesses()) HANDLE_EMR_SETTEXTALIGN(ulAlign); } @@ -486,7 +648,7 @@ namespace MetaFile m_oStream >> ulBgMode; - if (NULL == m_pEmfPlusParser || !m_pEmfPlusParser->GetBanEMFProcesses()) + if (!BanEMFProcesses()) HANDLE_EMR_SETBKMODE(ulBgMode); } @@ -496,7 +658,7 @@ namespace MetaFile m_oStream >> ulIndex; - if (NULL == m_pEmfPlusParser || !m_pEmfPlusParser->GetBanEMFProcesses()) + if (!BanEMFProcesses()) HANDLE_EMR_DELETEOBJECT(ulIndex); } @@ -506,7 +668,7 @@ namespace MetaFile m_oStream >> ulMiterLimit; - if (NULL == m_pEmfPlusParser || !m_pEmfPlusParser->GetBanEMFProcesses()) + if (!BanEMFProcesses()) HANDLE_EMR_SETMITERLIMIT(ulMiterLimit); } @@ -558,7 +720,7 @@ namespace MetaFile // Пропускаем часть с картинкой, если она была m_oStream.Skip(current_size); - if (NULL == m_pEmfPlusParser || !m_pEmfPlusParser->GetBanEMFProcesses()) + if (!BanEMFProcesses()) HANDLE_EMR_EXTCREATEPEN(ulPenIndex, pPen, arUnused); } @@ -580,7 +742,7 @@ namespace MetaFile m_oStream >> widthY; m_oStream >> pPen->oColor; - if (NULL == m_pEmfPlusParser || !m_pEmfPlusParser->GetBanEMFProcesses()) + if (!BanEMFProcesses()) HANDLE_EMR_CREATEPEN(ulPenIndex, widthX, pPen); } @@ -590,43 +752,43 @@ namespace MetaFile m_oStream >> ulFillMode; - if (NULL == m_pEmfPlusParser || !m_pEmfPlusParser->GetBanEMFProcesses()) + if (!BanEMFProcesses()) HANDLE_EMR_SETPOLYFILLMODE(ulFillMode); } void CEmfParser::Read_EMR_BEGINPATH() { - if (NULL == m_pEmfPlusParser || !m_pEmfPlusParser->GetBanEMFProcesses()) + if (!BanEMFProcesses()) HANDLE_EMR_BEGINPATH(); } void CEmfParser::Read_EMR_ENDPATH() { - if (NULL == m_pEmfPlusParser || !m_pEmfPlusParser->GetBanEMFProcesses()) + if (!BanEMFProcesses()) HANDLE_EMR_ENDPATH(); } void CEmfParser::Read_EMR_CLOSEFIGURE() { - if (NULL == m_pEmfPlusParser || !m_pEmfPlusParser->GetBanEMFProcesses()) + if (!BanEMFProcesses()) HANDLE_EMR_CLOSEFIGURE(); } void CEmfParser::Read_EMR_FLATTENPATH() { - if (NULL == m_pEmfPlusParser || !m_pEmfPlusParser->GetBanEMFProcesses()) + if (!BanEMFProcesses()) HANDLE_EMR_FLATTENPATH(); } void CEmfParser::Read_EMR_WIDENPATH() { - if (NULL == m_pEmfPlusParser || !m_pEmfPlusParser->GetBanEMFProcesses()) + if (!BanEMFProcesses()) HANDLE_EMR_WIDENPATH(); } void CEmfParser::Read_EMR_ABORTPATH() { - if (NULL == m_pEmfPlusParser || !m_pEmfPlusParser->GetBanEMFProcesses()) + if (!BanEMFProcesses()) HANDLE_EMR_ABORTPATH(); } @@ -636,7 +798,7 @@ namespace MetaFile m_oStream >> oPoint; - if (NULL == m_pEmfPlusParser || !m_pEmfPlusParser->GetBanEMFProcesses()) + if (!BanEMFProcesses()) HANDLE_EMR_MOVETOEX(oPoint); } @@ -646,7 +808,7 @@ namespace MetaFile m_oStream >> unDirection; - if (NULL == m_pEmfPlusParser || !m_pEmfPlusParser->GetBanEMFProcesses()) + if (!BanEMFProcesses()) HANDLE_EMR_SETARCDIRECTION(unDirection); } @@ -656,7 +818,7 @@ namespace MetaFile m_oStream >> oBounds; - if (NULL == m_pEmfPlusParser || !m_pEmfPlusParser->GetBanEMFProcesses()) + if (!BanEMFProcesses()) HANDLE_EMR_FILLPATH(oBounds); } @@ -666,7 +828,7 @@ namespace MetaFile m_oStream >> ulMapMode; - if (NULL == m_pEmfPlusParser || !m_pEmfPlusParser->GetBanEMFProcesses()) + if (!BanEMFProcesses()) HANDLE_EMR_SETMAPMODE(ulMapMode); } @@ -676,7 +838,7 @@ namespace MetaFile m_oStream >> oOrigin; - if (NULL == m_pEmfPlusParser || !m_pEmfPlusParser->GetBanEMFProcesses()) + if (!BanEMFProcesses()) HANDLE_EMR_SETWINDOWORGEX(oOrigin); } @@ -686,7 +848,7 @@ namespace MetaFile m_oStream >> oExtent; - if (NULL == m_pEmfPlusParser || !m_pEmfPlusParser->GetBanEMFProcesses()) + if (!BanEMFProcesses()) HANDLE_EMR_SETWINDOWEXTEX(oExtent); } @@ -699,7 +861,7 @@ namespace MetaFile m_oStream >> nYNum; m_oStream >> nYDenom; - if (NULL == m_pEmfPlusParser || !m_pEmfPlusParser->GetBanEMFProcesses()) + if (!BanEMFProcesses()) HANDLE_EMR_SCALEWINDOWEXTEX(nXNum, nXDenom, nYNum, nYDenom); } @@ -709,7 +871,7 @@ namespace MetaFile m_oStream >> oOrigin; - if (NULL == m_pEmfPlusParser || !m_pEmfPlusParser->GetBanEMFProcesses()) + if (!BanEMFProcesses()) HANDLE_EMR_SETVIEWPORTORGEX(oOrigin); } @@ -719,7 +881,7 @@ namespace MetaFile m_oStream >> oExtent; - if (NULL == m_pEmfPlusParser || !m_pEmfPlusParser->GetBanEMFProcesses()) + if (!BanEMFProcesses()) HANDLE_EMR_SETVIEWPORTEXTEX(oExtent); } @@ -732,7 +894,7 @@ namespace MetaFile m_oStream >> nYNum; m_oStream >> nYDenom; - if (NULL == m_pEmfPlusParser || !m_pEmfPlusParser->GetBanEMFProcesses()) + if (!BanEMFProcesses()) HANDLE_EMR_SCALEVIEWPORTEXTEX(nXNum, nXDenom, nYNum, nYDenom); } @@ -742,7 +904,7 @@ namespace MetaFile m_oStream >> ulStretchMode; - if (NULL == m_pEmfPlusParser || !m_pEmfPlusParser->GetBanEMFProcesses()) + if (!BanEMFProcesses()) HANDLE_EMR_SETSTRETCHBLTMODE(ulStretchMode); } @@ -752,7 +914,7 @@ namespace MetaFile m_oStream >> ulICMMode; - if (NULL == m_pEmfPlusParser || !m_pEmfPlusParser->GetBanEMFProcesses()) + if (!BanEMFProcesses()) HANDLE_EMR_SETICMMODE(ulICMMode); } @@ -764,7 +926,7 @@ namespace MetaFile m_oStream >> ulBrushIndex; m_oStream >> oDibBrush; - if (NULL == m_pEmfPlusParser || !m_pEmfPlusParser->GetBanEMFProcesses()) + if (!BanEMFProcesses()) HANDLE_EMR_CREATEDIBPATTERNBRUSHPT(ulBrushIndex, oDibBrush); } @@ -776,7 +938,7 @@ namespace MetaFile m_oStream >> ulBrushIndex; m_oStream >> oDibBrush; - if (NULL == m_pEmfPlusParser || !m_pEmfPlusParser->GetBanEMFProcesses()) + if (!BanEMFProcesses()) HANDLE_EMR_CREATEMONOBRUSH(ulBrushIndex, oDibBrush); } @@ -786,7 +948,7 @@ namespace MetaFile m_oStream >> unRegionMode; - if (NULL == m_pEmfPlusParser || !m_pEmfPlusParser->GetBanEMFProcesses()) + if (!BanEMFProcesses()) HANDLE_EMR_SELECTCLIPPATH(unRegionMode); } @@ -796,7 +958,7 @@ namespace MetaFile m_oStream >> oColor; - if (NULL == m_pEmfPlusParser || !m_pEmfPlusParser->GetBanEMFProcesses()) + if (!BanEMFProcesses()) HANDLE_EMR_SETBKCOLOR(oColor); } @@ -807,7 +969,7 @@ namespace MetaFile m_oStream >> oClip; - if (NULL == m_pEmfPlusParser || !m_pEmfPlusParser->GetBanEMFProcesses()) + if (!BanEMFProcesses()) HANDLE_EMR_EXCLUDECLIPRECT(oClip); } @@ -818,7 +980,7 @@ namespace MetaFile m_oStream >> ulRgnDataSize; m_oStream >> ulRegionMode; - if (NULL == m_pEmfPlusParser || !m_pEmfPlusParser->GetBanEMFProcesses()) + if (!BanEMFProcesses()) HANDLE_EMR_EXTSELECTCLIPRGN(ulRgnDataSize, ulRegionMode); } @@ -833,7 +995,7 @@ namespace MetaFile m_oStream >> ulRop2Mode; - if (NULL == m_pEmfPlusParser || !m_pEmfPlusParser->GetBanEMFProcesses()) + if (!BanEMFProcesses()) HANDLE_EMR_SETROP2(ulRop2Mode); } @@ -847,7 +1009,7 @@ namespace MetaFile m_oStream >> ulPaletteIndex; m_oStream >> *pPalette; - if (NULL == m_pEmfPlusParser || !m_pEmfPlusParser->GetBanEMFProcesses()) + if (!BanEMFProcesses()) HANDLE_EMR_CREATEPALETTE(ulPaletteIndex, pPalette); } @@ -857,13 +1019,13 @@ namespace MetaFile m_oStream >> ulIndex; - if (NULL == m_pEmfPlusParser || !m_pEmfPlusParser->GetBanEMFProcesses()) + if (!BanEMFProcesses()) HANDLE_EMR_SELECTPALETTE(ulIndex); } void CEmfParser::Read_EMR_REALIZEPALETTE() { - if (NULL == m_pEmfPlusParser || !m_pEmfPlusParser->GetBanEMFProcesses()) + if (!BanEMFProcesses()) HANDLE_EMR_REALIZEPALETTE(); } @@ -873,7 +1035,7 @@ namespace MetaFile m_oStream >> oClip; - if (NULL == m_pEmfPlusParser || !m_pEmfPlusParser->GetBanEMFProcesses()) + if (!BanEMFProcesses()) HANDLE_EMR_INTERSECTCLIPRECT(oClip); } @@ -883,7 +1045,7 @@ namespace MetaFile m_oStream >> ulLayoutMode; - if (NULL == m_pEmfPlusParser || !m_pEmfPlusParser->GetBanEMFProcesses()) + if (!BanEMFProcesses()) HANDLE_EMR_SETLAYOUT(ulLayoutMode); } @@ -893,7 +1055,7 @@ namespace MetaFile m_oStream >> oOrigin; - if (NULL == m_pEmfPlusParser || !m_pEmfPlusParser->GetBanEMFProcesses()) + if (!BanEMFProcesses()) HANDLE_EMR_SETBRUSHORGEX(oOrigin); } @@ -910,7 +1072,7 @@ namespace MetaFile m_oStream >> dStartAngle; m_oStream >> dSweepAngle; - if (NULL == m_pEmfPlusParser || !m_pEmfPlusParser->GetBanEMFProcesses()) + if (!BanEMFProcesses()) HANDLE_EMR_ANGLEARC(oCenter, unRadius, dStartAngle, dSweepAngle); } @@ -942,7 +1104,7 @@ namespace MetaFile Read_EMR_ARC_BASE(oBox, oStart, oEnd, dStartAngle, dSweep); - if (NULL == m_pEmfPlusParser || !m_pEmfPlusParser->GetBanEMFProcesses()) + if (!BanEMFProcesses()) HANDLE_EMR_ARC(oBox, oStart, oEnd); } @@ -955,7 +1117,7 @@ namespace MetaFile Read_EMR_ARC_BASE(oBox, oStart, oEnd, dStartAngle, dSweep); - if (NULL == m_pEmfPlusParser || !m_pEmfPlusParser->GetBanEMFProcesses()) + if (!BanEMFProcesses()) HANDLE_EMR_ARCTO(oBox, oStart, oEnd); } @@ -968,7 +1130,7 @@ namespace MetaFile Read_EMR_ARC_BASE(oBox, oStart, oEnd, dStartAngle, dSweep); - if (NULL == m_pEmfPlusParser || !m_pEmfPlusParser->GetBanEMFProcesses()) + if (!BanEMFProcesses()) HANDLE_EMR_CHORD(oBox, oStart, oEnd); } @@ -978,7 +1140,7 @@ namespace MetaFile m_oStream >> oBox; - if (NULL == m_pEmfPlusParser || !m_pEmfPlusParser->GetBanEMFProcesses()) + if (!BanEMFProcesses()) HANDLE_EMR_ELLIPSE(oBox); } @@ -989,7 +1151,7 @@ namespace MetaFile m_oStream >> oText; - if (NULL == m_pEmfPlusParser || !m_pEmfPlusParser->GetBanEMFProcesses()) + if (!BanEMFProcesses()) HANDLE_EMR_EXTTEXTOUTA(oText); } @@ -999,7 +1161,7 @@ namespace MetaFile m_oStream >> oText; - if (NULL == m_pEmfPlusParser || !m_pEmfPlusParser->GetBanEMFProcesses()) + if (!BanEMFProcesses()) HANDLE_EMR_EXTTEXTOUTW(oText); } @@ -1009,7 +1171,7 @@ namespace MetaFile m_oStream >> oPoint; - if (NULL == m_pEmfPlusParser || !m_pEmfPlusParser->GetBanEMFProcesses()) + if (!BanEMFProcesses()) HANDLE_EMR_LINETO(oPoint); } @@ -1022,7 +1184,7 @@ namespace MetaFile Read_EMR_ARC_BASE(oBox, oStart, oEnd, dStartAngle, dSweep); - if (NULL == m_pEmfPlusParser || !m_pEmfPlusParser->GetBanEMFProcesses()) + if (!BanEMFProcesses()) HANDLE_EMR_PIE(oBox, oStart, oEnd); } @@ -1058,7 +1220,7 @@ namespace MetaFile m_oStream >> arPoints[ulIndex + 2]; } - if (NULL == m_pEmfPlusParser || !m_pEmfPlusParser->GetBanEMFProcesses()) + if (!BanEMFProcesses()) HANDLE_EMR_POLYBEZIER(oBounds, arPoints); } @@ -1092,7 +1254,7 @@ namespace MetaFile m_oStream >> arPoints[ulIndex + 2]; } - if (NULL == m_pEmfPlusParser || !m_pEmfPlusParser->GetBanEMFProcesses()) + if (!BanEMFProcesses()) HANDLE_EMR_POLYBEZIERTO_BASE(oBounds, arPoints); } @@ -1137,7 +1299,7 @@ namespace MetaFile for (unsigned int unIndex = 0; unIndex < unCount; unIndex++) m_oStream >> pAbTypes[unIndex]; - if (NULL == m_pEmfPlusParser || !m_pEmfPlusParser->GetBanEMFProcesses()) + if (!BanEMFProcesses()) HANDLE_EMR_POLYDRAW_BASE(oBounds, pPoints, unCount, pAbTypes); delete[] pPoints; @@ -1170,7 +1332,7 @@ namespace MetaFile for (unsigned int ulIndex = 0; ulIndex < ulCount; ulIndex++) m_oStream >> arPoints[ulIndex]; - if (NULL == m_pEmfPlusParser || !m_pEmfPlusParser->GetBanEMFProcesses()) + if (!BanEMFProcesses()) HANDLE_EMR_POLYGON_BASE(oBounds, arPoints); } @@ -1200,7 +1362,7 @@ namespace MetaFile for (unsigned int ulIndex = 0; ulIndex < ulCount; ulIndex++) m_oStream >> arPoints[ulIndex]; - if (NULL == m_pEmfPlusParser || !m_pEmfPlusParser->GetBanEMFProcesses()) + if (!BanEMFProcesses()) HANDLE_EMR_POLYLINE_BASE(oBounds, arPoints); } @@ -1227,7 +1389,7 @@ namespace MetaFile for (unsigned int ulIndex = 0; ulIndex < ulCount; ulIndex++) m_oStream >> arPoints[ulIndex]; - if (NULL == m_pEmfPlusParser || !m_pEmfPlusParser->GetBanEMFProcesses()) + if (!BanEMFProcesses()) HANDLE_EMR_POLYLINETO_BASE(oBounds, arPoints); } @@ -1269,7 +1431,7 @@ namespace MetaFile for (unsigned int unPointIndex = 0; unPointIndex < arPoints[unPolygonIndex].size(); ++unPointIndex) m_oStream >> arPoints[unPolygonIndex][unPointIndex]; - if (NULL == m_pEmfPlusParser || !m_pEmfPlusParser->GetBanEMFProcesses()) + if (!BanEMFProcesses()) HANDLE_EMR_POLYPOLYGON(oBounds, arPoints); delete[] pPolygonPointCount; @@ -1317,7 +1479,7 @@ namespace MetaFile for (unsigned int unPointIndex = 0; unPointIndex < arPoints[unPolylineIndex].size(); ++unPointIndex) m_oStream >> arPoints[unPolylineIndex][unPointIndex]; - if (NULL == m_pEmfPlusParser || !m_pEmfPlusParser->GetBanEMFProcesses()) + if (!BanEMFProcesses()) HANDLE_EMR_POLYPOLYLINE(oBounds, arPoints); delete[] pPolylinePointCount; @@ -1338,7 +1500,7 @@ namespace MetaFile if (!oText.arEmrText) return SetError(); - if (NULL == m_pEmfPlusParser || !m_pEmfPlusParser->GetBanEMFProcesses()) + if (!BanEMFProcesses()) { for (unsigned int unIndex = 0; unIndex < oText.unCStrings; unIndex++) { @@ -1361,7 +1523,7 @@ namespace MetaFile if (!oText.arEmrText) return SetError(); - if (NULL == m_pEmfPlusParser || !m_pEmfPlusParser->GetBanEMFProcesses()) + if (!BanEMFProcesses()) { for (unsigned int unIndex = 0; unIndex < oText.unCStrings; unIndex++) { @@ -1376,7 +1538,7 @@ namespace MetaFile m_oStream >> oBox; - if (NULL == m_pEmfPlusParser || !m_pEmfPlusParser->GetBanEMFProcesses()) + if (!BanEMFProcesses()) HANDLE_EMR_RECTANGLE(oBox); } @@ -1388,7 +1550,7 @@ namespace MetaFile m_oStream >> oBox; m_oStream >> oCorner; - if (NULL == m_pEmfPlusParser || !m_pEmfPlusParser->GetBanEMFProcesses()) + if (!BanEMFProcesses()) HANDLE_EMR_ROUNDRECT(oBox, oCorner); } @@ -1400,7 +1562,7 @@ namespace MetaFile m_oStream >> oPoint; m_oStream >> oColor; - if (NULL == m_pEmfPlusParser || !m_pEmfPlusParser->GetBanEMFProcesses()) + if (!BanEMFProcesses()) HANDLE_EMR_SETPIXELV(oPoint, oColor); } @@ -1410,7 +1572,7 @@ namespace MetaFile m_oStream >> oText; - if (NULL == m_pEmfPlusParser || !m_pEmfPlusParser->GetBanEMFProcesses()) + if (!BanEMFProcesses()) HANDLE_EMR_SMALLTEXTOUT(oText); } @@ -1420,7 +1582,7 @@ namespace MetaFile m_oStream >> oBounds; - if (NULL == m_pEmfPlusParser || !m_pEmfPlusParser->GetBanEMFProcesses()) + if (!BanEMFProcesses()) HANDLE_EMR_STROKEANDFILLPATH(oBounds); } @@ -1430,7 +1592,7 @@ namespace MetaFile m_oStream >> oBounds; - if (NULL == m_pEmfPlusParser || !m_pEmfPlusParser->GetBanEMFProcesses()) + if (!BanEMFProcesses()) HANDLE_EMR_STROKEPATH(oBounds); } @@ -1463,7 +1625,7 @@ namespace MetaFile if (4 == unVer) m_oStream.Skip(unTri * 4); - if (NULL == m_pEmfPlusParser || !m_pEmfPlusParser->GetBanEMFProcesses()) + if (!BanEMFProcesses()) HANDLE_EMR_GRADIENTFILL(arVertex, arVertexIndexes, unMode); } @@ -1476,10 +1638,13 @@ namespace MetaFile if (sType == "EMF+" && NULL != m_pInterpretator) { + SaveDC(); + if (NULL == m_pEmfPlusParser) { m_pEmfPlusParser = new CEmfPlusParser(m_pInterpretator, m_oHeader); m_pEmfPlusParser->SetFontManager(GetFontManager()); + m_pEmfPlusParser->SetParent(this); } m_pEmfPlusParser->SetStream(m_oStream.GetCurPtr(), m_ulRecordSize - 8); @@ -1491,14 +1656,18 @@ namespace MetaFile m_pInterpretator->ChangeConditional(); m_oStream.Skip(m_ulRecordSize - 8); + + RestoreDC(-1); } - else if (sType == "GDIC") + else if (sType == "GDIC" && NULL != m_pInterpretator) { unsigned int unPublicCommentIdentifier; m_oStream >> unPublicCommentIdentifier; - if (EMR_COMMENT_WINDOWS_METAFILE == unPublicCommentIdentifier) + // At the moment, we are disabling support for embedded MWF files (in bug #71100 - The plus-minus symbol is not displayed correctly) + // From the tests, it became clear that the embedded WMF files are ignored + if (EMR_COMMENT_WINDOWS_METAFILE == unPublicCommentIdentifier && false) { m_oStream.Skip(12); // Version, Reserved, Checksum, Flags @@ -1513,6 +1682,7 @@ namespace MetaFile oWmfParser.SetFontManager(GetFontManager()); oWmfParser.SetStream(m_oStream.GetCurPtr(), unWinMetafileSize); + oWmfParser.SetParent(this); oWmfParser.Scan(); if (oWmfParser.CheckError()) @@ -1522,38 +1692,40 @@ namespace MetaFile HANDLE_EMR_EOF(); else if (InterpretatorType::Render == m_pInterpretator->GetType()) { - CMetaFileRenderer oWmfOut(&oWmfParser, ((CEmfInterpretatorRender*)m_pInterpretator)->GetRenderer()); - oWmfParser.SetInterpretator(&oWmfOut); + CMetaFileRenderer oWmfOut(&oWmfParser, ((CEmfInterpretatorRender*)m_pInterpretator)->GetRenderer()); + oWmfParser.SetInterpretator(&oWmfOut); - oWmfParser.PlayFile(); + oWmfParser.PlayFile(); - HANDLE_EMR_EOF(); + HANDLE_EMR_EOF(); } else if (NULL != m_pInterpretator && InterpretatorType::Svg == m_pInterpretator->GetType()) { - double dWidth, dHeight; - - ((CEmfInterpretatorSvg*)m_pInterpretator)->GetSize(dWidth, dHeight); - - ((CWmfParserBase*)&oWmfParser)->SetInterpretator(InterpretatorType::Svg, dWidth, dHeight); + ((CWmfParserBase*)&oWmfParser)->SetInterpretator(InterpretatorType::Svg); XmlUtils::CXmlWriter *pXmlWriter = ((CEmfInterpretatorSvg*)m_pInterpretator)->GetXmlWriter(); - TRectD oWmfRect = oWmfParser.GetBounds(); - TRectL *pCuurentRect = GetBounds(); + const TRectL& oWmfRect{oWmfParser.GetDCBounds()}; + const TRectL& oCurentRect{GetDCBounds()}; + + const double dScaleX = std::abs((double)(oCurentRect.Right - oCurentRect.Left) / (double)(oWmfRect.Right - oWmfRect.Left)); + const double dScaleY = std::abs((double)(oCurentRect.Bottom - oCurentRect.Top) / (double)(oWmfRect.Bottom - oWmfRect.Top)); - double dScaleX = std::abs((pCuurentRect->Right - pCuurentRect->Left) / (oWmfRect.Right - oWmfRect.Left)); - double dScaleY = std::abs((pCuurentRect->Bottom - pCuurentRect->Top) / (oWmfRect.Bottom - oWmfRect.Top)); + const bool bAddGElement = !Equals(1., dScaleX) || !Equals(1., dScaleY); - pXmlWriter->WriteNodeBegin(L"g", true); - pXmlWriter->WriteAttribute(L"transform", L"scale(" + std::to_wstring(dScaleX) + L',' + std::to_wstring(dScaleY) + L')'); - pXmlWriter->WriteNodeEnd(L"g", true, false); + if (bAddGElement) + { + pXmlWriter->WriteNodeBegin(L"g", true); + pXmlWriter->WriteAttribute(L"transform", L"scale(" + ConvertToWString(dScaleX) + L',' + ConvertToWString(dScaleY) + L')'); + pXmlWriter->WriteNodeEnd(L"g", true, false); + } ((CWmfInterpretatorSvg*)oWmfParser.GetInterpretator())->SetXmlWriter(pXmlWriter); oWmfParser.PlayFile(); - pXmlWriter->WriteNodeEnd(L"g", false, false); + if (bAddGElement) + pXmlWriter->WriteNodeEnd(L"g", false, false); HANDLE_EMR_EOF(); } @@ -1587,7 +1759,7 @@ namespace MetaFile for (TRectL &oRect : arRects) m_oStream >> oRect; - if (NULL == m_pEmfPlusParser || !m_pEmfPlusParser->GetBanEMFProcesses()) + if (!BanEMFProcesses()) HANDLE_EMR_FILLRGN(oBounds, unIhBrush, oRegionDataHeader, arRects); } @@ -1614,7 +1786,7 @@ namespace MetaFile for (TRectL &oRect : arRects) m_oStream >> oRect; - if (NULL == m_pEmfPlusParser || !m_pEmfPlusParser->GetBanEMFProcesses()) + if (!BanEMFProcesses()) HANDLE_EMR_PAINTRGN(oBounds, oRegionDataHeader, arRects); } @@ -1646,7 +1818,7 @@ namespace MetaFile for (TRectL &oRect : arRects) m_oStream >> oRect; - if (NULL == m_pEmfPlusParser || !m_pEmfPlusParser->GetBanEMFProcesses()) + if (!BanEMFProcesses()) HANDLE_EMR_FRAMERGN(oBounds, unIhBrush, nWidth, nHeight, oRegionDataHeader, arRects); } } diff --git a/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfParser.h b/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfParser.h index f24b0e91a7b..f2870789b7c 100644 --- a/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfParser.h +++ b/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfParser.h @@ -20,15 +20,13 @@ namespace MetaFile void ClearFile() override; - EmfParserType GetType() override; + EmfParserType GetType() const override; void SetStream(BYTE* pBuf, unsigned int unSize); - - public: - virtual void SetInterpretator(IOutputDevice* pOutput) override; - private: CEmfPlusParser *m_pEmfPlusParser; + bool BanEMFProcesses() const; + bool ReadImage(unsigned int offBmi, unsigned int cbBmi, unsigned int offBits, unsigned int cbBits, unsigned int ulSkip, BYTE **ppBgraBuffer, unsigned int *pulWidth, unsigned int *pulHeight) override; void Read_EMR_HEADER(); void Read_EMR_ALPHABLEND(); diff --git a/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfParserBase.cpp b/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfParserBase.cpp index ff46f0c4746..cffcbabb829 100644 --- a/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfParserBase.cpp +++ b/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfParserBase.cpp @@ -16,6 +16,14 @@ #define GRADIENT_FILL_OP_FLAG 0x000000ff #endif +#ifdef _DEBUG +#ifdef LOG_EMF_RECORDS + #if 1 == LOG_EMF_RECORDS + unsigned int unFileLevel = 0; +#endif +#endif +#endif + namespace MetaFile { void CEmfParserBase::ImageProcessing(const TEmfAlphaBlend &oTEmfAlphaBlend) @@ -70,8 +78,8 @@ namespace MetaFile unsigned int ulWidth, ulHeight; if (ReadImage(oTEmfStretchDIBITS.unOffBmiSrc, oTEmfStretchDIBITS.unCbBmiSrc, - oTEmfStretchDIBITS.unOffBitsSrc, oTEmfStretchDIBITS.unCbBitsSrc, - sizeof(TEmfStretchDIBITS) + 8, &pBgraBuffer, &ulWidth, &ulHeight)) + oTEmfStretchDIBITS.unOffBitsSrc, oTEmfStretchDIBITS.unCbBitsSrc, + sizeof(TEmfStretchDIBITS) + 8, &pBgraBuffer, &ulWidth, &ulHeight)) { if (m_pInterpretator) { @@ -102,8 +110,7 @@ namespace MetaFile oTEmfBitBlt.nCxDest, oTEmfBitBlt.nCyDest, pBgraBuffer, ulWidth, ulHeight); } - - if (m_pInterpretator) + else { if (0x00000042 == oTEmfBitBlt.unBitBltRasterOperation) // BLACKNESS { @@ -129,54 +136,24 @@ namespace MetaFile ulWidth = 1; ulHeight = 1; } - else if (0x00f00021 == oTEmfBitBlt.unBitBltRasterOperation) // PATCOPY + else if (0x00f00021 == oTEmfBitBlt.unBitBltRasterOperation || // PATCOPY + 0x005a0049 == oTEmfBitBlt.unBitBltRasterOperation || // PATINVERT + 0x00A000C9 == oTEmfBitBlt.unBitBltRasterOperation) // DPA { CEmfLogBrushEx* pBrush = (CEmfLogBrushEx*)m_pDC->GetBrush(); if (pBrush) { // Делаем цветом кисти pBgraBuffer = new BYTE[4]; - pBgraBuffer[0] = pBrush->oColor.b; - pBgraBuffer[1] = pBrush->oColor.g; - pBgraBuffer[2] = pBrush->oColor.r; + pBgraBuffer[0] = pBrush->oColor.b; + pBgraBuffer[1] = pBrush->oColor.g; + pBgraBuffer[2] = pBrush->oColor.r; pBgraBuffer[3] = 0xff; ulWidth = 1; ulHeight = 1; } } - else if (0x005a0049 == oTEmfBitBlt.unBitBltRasterOperation) // PATINVERT - { - CEmfLogBrushEx* pBrush = (CEmfLogBrushEx*)m_pDC->GetBrush(); - if (pBrush) - { - // Делаем цветом кисти - pBgraBuffer = new BYTE[4]; - pBgraBuffer[0] = pBrush->oColor.b; - pBgraBuffer[1] = pBrush->oColor.g; - pBgraBuffer[2] = pBrush->oColor.r; - pBgraBuffer[3] = 30; - - ulWidth = 1; - ulHeight = 1; - } - } - else if (0x00A000C9 == oTEmfBitBlt.unBitBltRasterOperation) // PATINVERT - { - CEmfLogBrushEx* pBrush = (CEmfLogBrushEx*)m_pDC->GetBrush(); - if (pBrush) - { - // Делаем цветом кисти - pBgraBuffer = new BYTE[4]; - pBgraBuffer[0] = pBrush->oColor.b; - pBgraBuffer[1] = pBrush->oColor.g; - pBgraBuffer[2] = pBrush->oColor.r; - pBgraBuffer[3] = 30; - - ulWidth = 1; - ulHeight = 1; - } - } if (pBgraBuffer) DrawImage(oTEmfBitBlt.nXDest, oTEmfBitBlt.nYDest, @@ -259,12 +236,12 @@ namespace MetaFile } } - void CEmfParserBase::TranslatePoint(TPointL &oPoint, double &dX, double &dY) + void CEmfParserBase::TranslatePoint(TPointL &oPoint, double &dX, double &dY) const { TranslatePoint(oPoint.X, oPoint.Y, dX, dY); } - void CEmfParserBase::TranslatePoint(int nX, int nY, double &dX, double &dY) + void CEmfParserBase::TranslatePoint(int nX, int nY, double &dX, double &dY) const { dX = (double)nX; dY = (double)nY; @@ -476,61 +453,11 @@ namespace MetaFile if (!oText.pOutputString) return SetError(); - IFont* pFont = GetFont(); - NSStringExt::CConverter::ESingleByteEncoding eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_DEFAULT; - if (pFont) - { - // Соответствие Charset -> Codepage: http://support.microsoft.com/kb/165478 - // http://msdn.microsoft.com/en-us/library/cc194829.aspx - // Charset Name Charset Value(hex) Codepage number - // ------------------------------------------------------ - // - // DEFAULT_CHARSET 1 (x01) - // SYMBOL_CHARSET 2 (x02) - // OEM_CHARSET 255 (xFF) - // ANSI_CHARSET 0 (x00) 1252 - // RUSSIAN_CHARSET 204 (xCC) 1251 - // EASTEUROPE_CHARSET 238 (xEE) 1250 - // GREEK_CHARSET 161 (xA1) 1253 - // TURKISH_CHARSET 162 (xA2) 1254 - // BALTIC_CHARSET 186 (xBA) 1257 - // HEBREW_CHARSET 177 (xB1) 1255 - // ARABIC _CHARSET 178 (xB2) 1256 - // SHIFTJIS_CHARSET 128 (x80) 932 - // HANGEUL_CHARSET 129 (x81) 949 - // GB2313_CHARSET 134 (x86) 936 - // CHINESEBIG5_CHARSET 136 (x88) 950 - // THAI_CHARSET 222 (xDE) 874 - // JOHAB_CHARSET 130 (x82) 1361 - // VIETNAMESE_CHARSET 163 (xA3) 1258 - - switch (pFont->GetCharSet()) - { - default: - case DEFAULT_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_DEFAULT; break; - case SYMBOL_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_DEFAULT; break; - case ANSI_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1252; break; - case RUSSIAN_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1251; break; - case EASTEUROPE_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1250; break; - case GREEK_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1253; break; - case TURKISH_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1254; break; - case BALTIC_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1257; break; - case HEBREW_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1255; break; - case ARABIC_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1256; break; - case SHIFTJIS_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP932; break; - case HANGEUL_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP949; break; - case 134/*GB2313_CHARSET*/: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP936; break; - case CHINESEBIG5_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP950; break; - case THAI_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP874; break; - case JOHAB_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1361; break; - case VIETNAMESE_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1258; break; - } - } - - std::wstring wsText = NSStringExt::CConverter::GetUnicodeFromSingleByteString((unsigned char*)oText.pOutputString, oText.unChars, eCharSet); + const IFont* pFont = GetFont(); + std::wstring wsText = ConvertToUnicode(oText.pOutputString, oText.unChars, (NULL != pFont) ? pFont->GetCharSet() : DEFAULT_CHARSET); int* pDx = NULL; - if (oText.pOutputDx) + if (oText.pOutputDx && oText.unChars == wsText.length()) { pDx = new int[oText.unChars]; if (pDx) @@ -561,7 +488,7 @@ namespace MetaFile unsigned int unLen = 0; int* pDx = NULL; - if (oText.pOutputDx && oText.unChars) + if (oText.pOutputDx && oText.unChars && oText.unChars == wsText.length()) { // Здесь мы эмулируем конвертацию Utf16 в Utf32, чтобы правильно получить массив pDx pDx = new int[oText.unChars]; @@ -628,12 +555,9 @@ namespace MetaFile } CEmfParserBase::CEmfParserBase() - : m_oPlayer(this) + : m_oPlayer(this), m_pPath(NULL), m_pInterpretator(NULL), m_bEof(false) { - m_pPath = NULL; - m_pDC = m_oPlayer.GetDC(); - m_pInterpretator = NULL; - m_bEof = false; + m_pDC = m_oPlayer.GetDC(); } CEmfParserBase::~CEmfParserBase(){} @@ -648,35 +572,34 @@ namespace MetaFile m_bEof = false; } - TRectL *CEmfParserBase::GetDCBounds() + const TRectL& CEmfParserBase::GetDCBounds() const { - return &m_oHeader.oFrameToBounds; + return m_oHeader.oFrameToBounds; } - - CClip *CEmfParserBase::GetClip() + + const CClip *CEmfParserBase::GetClip() const { return m_pDC->GetClip(); } - double CEmfParserBase::GetPixelHeight() + double CEmfParserBase::GetPixelHeight() const { return m_pDC->GetPixelHeight(); } - double CEmfParserBase::GetPixelWidth() + double CEmfParserBase::GetPixelWidth() const { return m_pDC->GetPixelWidth(); } - int CEmfParserBase::GetTextColor() + int CEmfParserBase::GetTextColor() const { - TRGBA& oColor = m_pDC->GetTextColor(); - return METAFILE_RGBA(oColor.r, oColor.g, oColor.b, 0); + return m_pDC->GetTextColor().ToInt(); } - IFont *CEmfParserBase::GetFont() + const IFont *CEmfParserBase::GetFont() const { - IFont* pFont = m_pDC->GetFont(); + const IFont* pFont = m_pDC->GetFont(); if (!pFont) return NULL; @@ -684,46 +607,37 @@ namespace MetaFile return pFont; } - IBrush *CEmfParserBase::GetBrush() + const IBrush *CEmfParserBase::GetBrush() const { - IBrush* pBrush = m_pDC->GetBrush(); - if (!pBrush) - return NULL; - - return pBrush; + return m_pDC->GetBrush(); } - IPen *CEmfParserBase::GetPen() + const IPen *CEmfParserBase::GetPen() const { - IPen* pPen = m_pDC->GetPen(); - if (!pPen) - return NULL; - - return pPen; + return m_pDC->GetPen(); } - unsigned int CEmfParserBase::GetTextAlign() + unsigned int CEmfParserBase::GetTextAlign() const { return m_pDC->GetTextAlign(); } - unsigned int CEmfParserBase::GetTextBgMode() + unsigned int CEmfParserBase::GetTextBgMode() const { return m_pDC->GetBgMode(); } - int CEmfParserBase::GetTextBgColor() + int CEmfParserBase::GetTextBgColor() const { - TRGBA& oColor = m_pDC->GetBgColor(); - return METAFILE_RGBA(oColor.r, oColor.g, oColor.b, 0); + return m_pDC->GetBgColor()->ToInt(); } - unsigned int CEmfParserBase::GetFillMode() + unsigned int CEmfParserBase::GetFillMode() const { return m_pDC->GetFillMode(); } - TPointD CEmfParserBase::GetCurPos() + TPointD CEmfParserBase::GetCurPos() const { TPointL oPoint = m_pDC->GetCurPos(); TPointD oRes; @@ -731,85 +645,80 @@ namespace MetaFile return oRes; } - TXForm *CEmfParserBase::GetInverseTransform() + const TXForm& CEmfParserBase::GetInverseTransform() const { return m_pDC->GetInverseTransform(); } - TXForm *CEmfParserBase::GetTransform(int iGraphicsMode) + const TXForm& CEmfParserBase::GetTransform(int iGraphicsMode) { - TRectL* pBounds = GetDCBounds(); - double dT = pBounds->Top; - double dL = pBounds->Left; + double dT = GetDCBounds().Top; + double dL = GetDCBounds().Left; TXForm oShiftXForm(1, 0, 0, 1, -dL, -dT); - m_oTransform.Copy(m_pDC->GetFinalTransform(iGraphicsMode)); + m_oTransform.Copy(&m_pDC->GetFinalTransform(iGraphicsMode)); m_oTransform.Multiply(oShiftXForm, MWT_RIGHTMULTIPLY); - return &m_oTransform; + return m_oTransform; } - unsigned int CEmfParserBase::GetMiterLimit() + unsigned int CEmfParserBase::GetMiterLimit() const { return m_pDC->GetMiterLimit(); } - unsigned int CEmfParserBase::GetRop2Mode() + unsigned int CEmfParserBase::GetRop2Mode() const { return m_pDC->GetRop2Mode(); } - int CEmfParserBase::GetCharSpace() + int CEmfParserBase::GetCharSpace() const { return 0; } - bool CEmfParserBase::IsWindowFlippedY() + bool CEmfParserBase::IsWindowFlippedY() const { - TEmfWindow* pWindow = m_pDC->GetWindow(); - return (pWindow->ulH < 0); + return m_pDC->GetWindow().ulH < 0; } - bool CEmfParserBase::IsWindowFlippedX() + bool CEmfParserBase::IsWindowFlippedX() const { - TEmfWindow* pWindow = m_pDC->GetWindow(); - return (pWindow->ulW < 0); + return m_pDC->GetWindow().ulW < 0; } - unsigned int CEmfParserBase::GetMapMode() + unsigned int CEmfParserBase::GetMapMode() const { return m_pDC->GetMapMode(); } - double CEmfParserBase::GetDpi() + USHORT CEmfParserBase::GetDpi() const { - return 96.; + return 96; } - IRegion *CEmfParserBase::GetRegion() + const IRegion *CEmfParserBase::GetRegion() const { return NULL; } - unsigned int CEmfParserBase::GetArcDirection() + unsigned int CEmfParserBase::GetArcDirection() const { return m_pDC->GetArcDirection(); } - CPath *CEmfParserBase::GetPath() + const CPath *CEmfParserBase::GetPath() const { return m_pPath; } - bool CEmfParserBase::IsViewportFlippedY() + bool CEmfParserBase::IsViewportFlippedY() const { - TEmfWindow* pViewport = m_pDC->GetViewport(); - return (pViewport->ulH < 0); + return m_pDC->GetViewport().ulH < 0; } - bool CEmfParserBase::IsViewportFlippedX() + bool CEmfParserBase::IsViewportFlippedX() const { - TEmfWindow* pViewport = m_pDC->GetViewport(); - return (pViewport->ulW < 0); + return m_pDC->GetViewport().ulW < 0; } void CEmfParserBase::SetInterpretator(IOutputDevice *pOutput) @@ -852,7 +761,11 @@ namespace MetaFile RELEASEOBJECT(m_pInterpretator); if (InterpretatorType::Svg == oInterpretatorType) - m_pInterpretator = new CEmfInterpretatorSvg(this, dWidth, dHeight); + { + CEmfInterpretatorSvg *pEmfInterpretatorSvg = new CEmfInterpretatorSvg(this, dWidth, dHeight); + pEmfInterpretatorSvg->SetShapeRendering(EShapeRendering::CrispEdges); + m_pInterpretator = pEmfInterpretatorSvg; + } } CEmfInterpretatorBase* CEmfParserBase::GetInterpretator() @@ -860,17 +773,28 @@ namespace MetaFile return m_pInterpretator; } - TRectL* CEmfParserBase::GetBounds() + TXForm CEmfParserBase::CalculateCurrentTransform() const { - return &m_oHeader.oFramePx; + if (NULL == m_pParent) + return m_pDC->GetTransform(); + + TXForm oTransform{m_pParent->CalculateCurrentTransform()}; + oTransform.Multiply(m_pDC->GetTransform(), MWT_RIGHTMULTIPLY); + + return oTransform; } - CPath *CEmfParserBase::GetPath() const + const TRectL& CEmfParserBase::GetBounds() const + { + return m_oHeader.oFramePx; + } + + CPath *CEmfParserBase::GetPath() { return m_pPath; } - TPointL CEmfParserBase::GetStartPointForArc(const TRectL &oBox, double dStartAngle) + TPointL CEmfParserBase::GetStartPointForArc(const TRectL &oBox, double dStartAngle) const { TPointL oStartPoint; @@ -887,6 +811,25 @@ namespace MetaFile return oStartPoint; } + void CEmfParserBase::SaveDC() + { + m_oPlayer.SaveDC(); + UpdateOutputDC(); + } + + void CEmfParserBase::RestoreDC(int nIndex) + { + if (nIndex >= 0) + { + SetError(); + return; + } + + m_oPlayer.RestoreDC(nIndex); + m_pDC = m_oPlayer.GetDC(); + UpdateOutputDC(); + } + void CEmfParserBase::HANDLE_EMR_HEADER(TEmfHeader &oTEmfHeader) { if (ENHMETA_SIGNATURE != m_oHeader.ulSignature || 0x00010000 != m_oHeader.ulVersion) @@ -983,8 +926,7 @@ namespace MetaFile if (NULL != m_pInterpretator) m_pInterpretator->HANDLE_EMR_SAVEDC(); - m_oPlayer.SaveDC(); - UpdateOutputDC(); + SaveDC(); } void CEmfParserBase::HANDLE_EMR_RESTOREDC(int &nIndexDC) @@ -992,15 +934,7 @@ namespace MetaFile if (NULL != m_pInterpretator) m_pInterpretator->HANDLE_EMR_RESTOREDC(nIndexDC); - if (nIndexDC >= 0) - { - SetError(); - return; - } - - m_oPlayer.RestoreDC(nIndexDC); - m_pDC = m_oPlayer.GetDC(); - UpdateOutputDC(); + RestoreDC(nIndexDC); } void CEmfParserBase::HANDLE_EMR_MODIFYWORLDTRANSFORM(TXForm &oXForm, unsigned int &unMode) @@ -1323,7 +1257,7 @@ namespace MetaFile if (NULL != m_pPath) { - m_pDC->GetClip()->SetPath(*m_pPath, unRegionMode, *GetDC()->GetFinalTransform(GM_ADVANCED)); + m_pDC->GetClip()->SetPath(*m_pPath, unRegionMode, m_pDC->GetFinalTransform(GM_ADVANCED)); RELEASEOBJECT(m_pPath); UpdateOutputDC(); } @@ -1369,9 +1303,9 @@ namespace MetaFile TranslatePoint(oClip.Left, oClip.Top, oClipRect.Left, oClipRect.Top); TranslatePoint(oClip.Right, oClip.Bottom, oClipRect.Right, oClipRect.Bottom); - TRectL* pRect = GetDCBounds(); - TranslatePoint(pRect->Left, pRect->Top, oBB.Left, oBB.Top); - TranslatePoint(pRect->Right, pRect->Bottom, oBB.Right, oBB.Bottom); + const TRectL& oRect{GetDCBounds()}; + TranslatePoint(oRect.Left, oRect.Top, oBB.Left, oBB.Top); + TranslatePoint(oRect.Right, oRect.Bottom, oBB.Right, oBB.Bottom); m_pDC->GetClip()->Exclude(oClipRect, oBB); UpdateOutputDC(); @@ -1439,9 +1373,9 @@ namespace MetaFile TRectD oClipRect; TranslatePoint(oClip.Left, oClip.Top, oClipRect.Left, oClipRect.Top); TranslatePoint(oClip.Right, oClip.Bottom, oClipRect.Right, oClipRect.Bottom); - + m_pDC->GetClip()->Intersect(oClipRect); - + if (NULL != m_pInterpretator) m_pInterpretator->HANDLE_EMR_INTERSECTCLIPRECT(oClip); } @@ -1575,11 +1509,19 @@ namespace MetaFile if (NULL != m_pInterpretator && (NULL == m_pPath || Svg != m_pInterpretator->GetType())) m_pInterpretator->HANDLE_EMR_PIE(oBox, oStart, oEnd); - double dStartAngle = GetEllipseAngle(oBox.Left, oBox.Top, oBox.Right, oBox.Bottom, oStart.X, oStart.Y); - double dSweepAngle = GetEllipseAngle(oBox.Left, oBox.Top, oBox.Right, oBox.Bottom, oEnd.X, oEnd.Y) - dStartAngle; + const int nCenterX = (oBox.Left + oBox.Right) / 2; + const int nCenterY = (oBox.Top + oBox.Bottom) / 2; - ArcTo(oBox.Left, oBox.Top, oBox.Right, oBox.Bottom, dStartAngle, dSweepAngle); - LineTo((oBox.Left + oBox.Right) / 2, (oBox.Top + oBox.Bottom) / 2); + double dStartAngle = std::atan2(oStart.Y - nCenterY, oStart.X - nCenterX); + double dEndAngle = std::atan2(oEnd.Y - nCenterY, oEnd.X - nCenterX); + + if (dEndAngle > dStartAngle) + dEndAngle -= 2 * M_PI; + + MoveTo(nCenterX, nCenterY); + LineTo(oStart.X, oStart.Y); + ArcTo(oBox.Left, oBox.Top, oBox.Right, oBox.Bottom, dStartAngle * 180. / M_PI, (dEndAngle - dStartAngle) * 180. / M_PI); + LineTo(nCenterX, nCenterY); ClosePath(); DrawPath(true, true); } @@ -1726,12 +1668,12 @@ namespace MetaFile return; CEmfPlusBrush oBrush; - oBrush.unStyle = BS_LINEARGRADIENT; + oBrush.unStyle = BS_LINEARGRADIENT; - oBrush.oColor.chRed = arVertex[0].ushRed / 255.; - oBrush.oColor.chGreen = arVertex[0].ushGreen / 255.; - oBrush.oColor.chBlue = arVertex[0].ushBlue / 255.; - oBrush.oColor.chAlpha = 255; + oBrush.oColor.chRed = arVertex[0].ushRed / 255.; + oBrush.oColor.chGreen = arVertex[0].ushGreen / 255.; + oBrush.oColor.chBlue = arVertex[0].ushBlue / 255.; + oBrush.oColor.chAlpha = 255; if (GRADIENT_FILL_RECT_H == unFillMode || GRADIENT_FILL_TRIANGLE == unFillMode) { @@ -1757,7 +1699,7 @@ namespace MetaFile } oBrush.oColorBack.chAlpha = 255; - IBrush* pBrush = m_pDC->GetBrush(); + const IBrush* pBrush = m_pDC->GetBrush(); m_pDC->SetBrush(&oBrush); MoveTo(arVertex[0].nX, arVertex[0].nY); @@ -1773,7 +1715,7 @@ namespace MetaFile m_pInterpretator->HANDLE_EMR_GRADIENTFILL(arVertex, arIndexes, unFillMode); m_pDC->RemoveBrush(&oBrush); - m_pDC->SetBrush(pBrush); + m_pDC->SetBrush((IBrush*)pBrush); } void CEmfParserBase::HANDLE_EMR_UNKNOWN(const unsigned int& unRecordSize) diff --git a/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfParserBase.h b/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfParserBase.h index 5984f1ac29c..20a460aa489 100644 --- a/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfParserBase.h +++ b/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfParserBase.h @@ -11,14 +11,39 @@ #include "../EmfInterpretator/CEmfInterpretatorBase.h" + +#if defined(DrawText) +#undef DrawText +#endif + +#define PRINT_LOG(text) do {} while(false) +#define GO_DOWN_LEVEL_BELOW do {} while (false) +#define GO_UP_LEVEL do {} while (false) + #ifdef _DEBUG #include #include #include -#endif -#if defined(DrawText) -#undef DrawText +#define LOG_EMF_RECORDS 1 + +#ifdef LOG_EMF_RECORDS + #if 1 == LOG_EMF_RECORDS + #define PRINTING_EMF_RECORDS 1 + #define PRINTING_EMF_PLUS_RECORDS 1 + + extern unsigned int unFileLevel; + + #define GO_DOWN_LEVEL_BELOW \ + std::wcout << L"LEVEL [" << unFileLevel << L"] -> [" << --::unFileLevel << L"]" << std::endl + + #define GO_UP_LEVEL \ + std::wcout << L"LEVEL [" << unFileLevel << L"] -> [" << ++::unFileLevel << L"]" << std::endl + + #define PRINT_LOG(text) \ + std::wcout << L"LEVEL [" << unFileLevel << L"] [LOG] " << text << std::endl + #endif +#endif #endif namespace MetaFile @@ -54,48 +79,51 @@ namespace MetaFile virtual void PlayFile() = 0; virtual void Scan() = 0; - virtual EmfParserType GetType() = 0; - - void PlayMetaFile() override; - void ClearFile() override; - TRectL* GetDCBounds() override; - CClip* GetClip() override; - double GetPixelHeight() override; - double GetPixelWidth() override; - int GetTextColor() override; - IFont* GetFont() override; - IBrush* GetBrush() override; - IPen* GetPen() override; - unsigned int GetTextAlign() override; - unsigned int GetTextBgMode() override; - int GetTextBgColor() override; - unsigned int GetFillMode() override; - TPointD GetCurPos() override; - TXForm* GetInverseTransform() override; - TXForm* GetTransform(int = GM_ADVANCED) override; - unsigned int GetMiterLimit() override; - unsigned int GetRop2Mode() override; - int GetCharSpace() override; - bool IsWindowFlippedY() override; - bool IsWindowFlippedX() override; - unsigned int GetMapMode() override; - double GetDpi() override; - IRegion* GetRegion() override; - unsigned int GetArcDirection() override; - CPath* GetPath() override; - bool IsViewportFlippedY(); - bool IsViewportFlippedX(); - - virtual void SetInterpretator(IOutputDevice* pOutput); + virtual EmfParserType GetType() const = 0; + + void PlayMetaFile() override; + void ClearFile() override; + const TRectL& GetDCBounds() const override; + const CClip* GetClip() const override; + double GetPixelHeight() const override; + double GetPixelWidth() const override; + int GetTextColor() const override; + const IFont* GetFont() const override; + const IBrush* GetBrush() const override; + const IPen* GetPen() const override; + unsigned int GetTextAlign() const override; + unsigned int GetTextBgMode() const override; + int GetTextBgColor() const override; + unsigned int GetFillMode() const override; + TPointD GetCurPos() const override; + const TXForm& GetInverseTransform() const override; + const TXForm& GetTransform(int = GM_ADVANCED) override; + unsigned int GetMiterLimit() const override; + unsigned int GetRop2Mode() const override; + int GetCharSpace() const override; + bool IsWindowFlippedY() const override; + bool IsWindowFlippedX() const override; + unsigned int GetMapMode() const override; + USHORT GetDpi() const override; + const IRegion* GetRegion() const override; + unsigned int GetArcDirection() const override; + const CPath* GetPath() const override; + + bool IsViewportFlippedY() const; + bool IsViewportFlippedX() const; + + void SetInterpretator(IOutputDevice* pOutput); void SetInterpretator(const wchar_t *wsFilePath, InterpretatorType oInterpretatorType, unsigned int unWidth = 0, unsigned int unHeight = 0); void SetInterpretator(IOutputDevice* pOutput, const wchar_t *wsFilePath); void SetInterpretator(InterpretatorType oInterpretatorType, double dWidth = 0, double dHeight = 0); CEmfInterpretatorBase* GetInterpretator(); - CEmfDC* GetDC(); - TRectL* GetBounds(); - CPath* GetPath() const; + TXForm CalculateCurrentTransform() const override; + + CEmfDC* GetDC(); + const TRectL& GetBounds() const; + CPath* GetPath(); private: //Работа с изображениями void ImageProcessing(const TEmfAlphaBlend &oTEmfAlphaBlend); @@ -107,8 +135,8 @@ namespace MetaFile void DrawImage(int nX, int nY, int nW, int nH, BYTE *pImageBuffer, unsigned int unImageW, unsigned int unImageH); //---------------------- - void TranslatePoint(TPointL &oPoint, double &dX, double &dY); - void TranslatePoint(int nX, int nY, double &dX, double &dY); + void TranslatePoint(TPointL &oPoint, double &dX, double &dY) const; + void TranslatePoint(int nX, int nY, double &dX, double &dY) const; void UpdateOutputDC(); void ClosePath(); @@ -151,13 +179,16 @@ namespace MetaFile CPath* m_pPath; TEmfXForm m_oTransform; - CEmfInterpretatorBase *m_pInterpretator; + CEmfInterpretatorBase* m_pInterpretator; bool m_bEof; private: virtual bool ReadImage(unsigned int offBmi, unsigned int cbBmi, unsigned int offBits, unsigned int cbBits, unsigned int ulSkip, BYTE **ppBgraBuffer, unsigned int *pulWidth, unsigned int *pulHeight) = 0; - TPointL GetStartPointForArc(const TRectL &oBox, double dStartAngle); + TPointL GetStartPointForArc(const TRectL &oBox, double dStartAngle) const; + + void SaveDC(); + void RestoreDC(int nIndex); void HANDLE_EMR_HEADER(TEmfHeader& oTEmfHeader); void HANDLE_EMR_ALPHABLEND(TEmfAlphaBlend& oTEmfAlphaBlend); @@ -397,6 +428,5 @@ namespace MetaFile void HANDLE_EMR_FRAMERGN(const TRectL& oBounds, unsigned int unIhBrush, int nWidth, int nHeight, const TRegionDataHeader& oRegionDataHeader, const std::vector& arRects); }; - } #endif // CEMFPARSERBASE_H diff --git a/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfPlusParser.cpp b/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfPlusParser.cpp index 899811be142..713cb4c95dc 100644 --- a/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfPlusParser.cpp +++ b/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfPlusParser.cpp @@ -86,79 +86,99 @@ #include "../../../BgraFrame.h" +#define MAX_PICTURE_SIZE 2000. + +#define PRINT_EMF_PLUS_RECORD(type, size) do {} while(false) + +#ifdef _DEBUG + #ifdef LOG_EMF_RECORDS + #if 1 == LOG_EMF_RECORDS + #ifdef PRINTING_EMF_PLUS_RECORDS + #if 1 == PRINTING_EMF_PLUS_RECORDS + #include + + static std::map mActionNamesEmfPlus = + { + {0x4035, L"EMRPLUS_OFFSETCLIP"}, + {0x4031, L"EMRPLUS_RESETCLIP"}, + {0x4033, L"EMFPLUS_SETCLIPPATH"}, + {0x4032, L"EMFPLUS_SETCLIPRECT"}, + {0x4034, L"EMFPLUS_SETCLIPREGION"}, + + {0x4003, L"EMFPLUS_COMMENT"}, + + {0x4002, L"EMFPLUS_ENDOFFILE"}, + {0x4004, L"EMFPLUS_GETDC"}, + {0x4001, L"EMFPLUS_HEADER"}, + + {0x4009, L"EMFPLUS_CLEAR"}, + {0x4012, L"EMFPLUS_DRAWARC"}, + {0x4019, L"EMFPLUS_DRAWBEZIERS"}, + {0x4017, L"EMFPLUS_DRAWCLOSEDCURVE"}, + {0x4018, L"EMFPLUS_DRAWCURVE"}, + {0x4036, L"EMFPLUS_DRAWDRIVERSTRING"}, + {0x400F, L"EMFPLUS_DRAWELLIPSE"}, + {0x401A, L"EMFPLUS_DRAWIMAGE"}, + {0x401B, L"EMFPLUS_DRAWIMAGEPOINTS"}, + {0x400D, L"EMFPLUS_DRAWLINES"}, + {0x4015, L"EMFPLUS_DRAWPATH"}, + {0x4011, L"EMFPLUS_DRAWPIE"}, + {0x400B, L"EMFPLUS_DRAWRECTS"}, + {0x401C, L"EMFPLUS_DRAWSTRING"}, + {0x4016, L"EMFPLUS_FILLCLOSEDCURVE"}, + {0x400E, L"EMFPLUS_FILLELLIPSE"}, + {0x4014, L"EMFPLUS_FILLPATH"}, + {0x4010, L"EMFPLUS_FILLPIE"}, + {0x400C, L"EMFPLUS_FILLPOLYGON"}, + {0x400A, L"EMFPLUS_FILLRECTS"}, + {0x4013, L"EMFPLUS_FILLREGION"}, + + {0x4008, L"EMFPLUS_OBJECT"}, + {0x4038, L"EMFPLUS_SERIALIZABLEOBJECT"}, + + {0x401E, L"EMFPLUS_SETANTIALIASMODE"}, + {0x4023, L"EMFPLUS_SETCOMPOSITINGMODE"}, + {0x4024, L"EMFPLUS_SETCOMPOSITINGQUALITY"}, + {0x4021, L"EMFPLUS_SETINTERPOLATIONMODE"}, + {0x4022, L"EMFPLUS_SETPIXELOFFSETMODE"}, + {0x401D, L"EMFPLUS_SETRENDERINGORIGIN"}, + {0x4020, L"EMFPLUS_SETTEXTCONTRAST"}, + {0x401F, L"EMFPLUS_SETTEXTRENDERINGHINT"}, + + {0x4027, L"EMFPLUS_BEGINCONTAINER"}, + {0x4028, L"EMFPLUS_BEGINCONTAINERNOPARAMS"}, + {0x4029, L"EMFPLUS_ENDCONTAINER"}, + {0x4026, L"EMFPLUS_RESTORE"}, + {0x4025, L"EMFPLUS_SAVE"}, + + {0x403A, L"EMFPLUS_SETTSCLIP"}, + {0x4039, L"EMFPLUS_SETTSGRAPHICS"}, + + {0x402C, L"EMFPLUS_MULTIPLYWORLDTRANSFORM"}, + {0x402B, L"EMFPLUS_RESETWORLDTRANSFORM"}, + {0x402F, L"EMFPLUS_ROTATEWORLDTRANSFORM"}, + {0x402E, L"EMFPLUS_SCALEWORLDTRANSFORM"}, + {0x4030, L"EMFPLUS_SETPAGETRANSFORM"}, + {0x402A, L"EMFPLUS_SETWORLDTRANSFORM"}, + {0x402D, L"EMFPLUS_TRANSLATEWORLDTRANSFORM"} + }; + + #define PRINT_EMF_PLUS_RECORD(type, size) \ + std::wcout << L"LEVEL [" << unFileLevel << L"] EMF_PLUS_RECORD: " << mActionNamesEmfPlus[unShType] << L" {DataSize = " << size << L"}" << std::endl + #endif + #endif + #endif + #endif +#endif + namespace MetaFile { - static std::map ActionNamesEmfPlus = - { - {0x4035, L"EMRPLUS_OFFSETCLIP"}, - {0x4031, L"EMRPLUS_RESETCLIP"}, - {0x4033, L"EMFPLUS_SETCLIPPATH"}, - {0x4032, L"EMFPLUS_SETCLIPRECT"}, - {0x4034, L"EMFPLUS_SETCLIPREGION"}, - - {0x4003, L"EMFPLUS_COMMENT"}, - - {0x4002, L"EMFPLUS_ENDOFFILE"}, - {0x4004, L"EMFPLUS_GETDC"}, - {0x4001, L"EMFPLUS_HEADER"}, - - {0x4009, L"EMFPLUS_CLEAR"}, - {0x4012, L"EMFPLUS_DRAWARC"}, - {0x4019, L"EMFPLUS_DRAWBEZIERS"}, - {0x4017, L"EMFPLUS_DRAWCLOSEDCURVE"}, - {0x4018, L"EMFPLUS_DRAWCURVE"}, - {0x4036, L"EMFPLUS_DRAWDRIVERSTRING"}, - {0x400F, L"EMFPLUS_DRAWELLIPSE"}, - {0x401A, L"EMFPLUS_DRAWIMAGE"}, - {0x401B, L"EMFPLUS_DRAWIMAGEPOINTS"}, - {0x400D, L"EMFPLUS_DRAWLINES"}, - {0x4015, L"EMFPLUS_DRAWPATH"}, - {0x4011, L"EMFPLUS_DRAWPIE"}, - {0x400B, L"EMFPLUS_DRAWRECTS"}, - {0x401C, L"EMFPLUS_DRAWSTRING"}, - {0x4016, L"EMFPLUS_FILLCLOSEDCURVE"}, - {0x400E, L"EMFPLUS_FILLELLIPSE"}, - {0x4014, L"EMFPLUS_FILLPATH"}, - {0x4010, L"EMFPLUS_FILLPIE"}, - {0x400C, L"EMFPLUS_FILLPOLYGON"}, - {0x400A, L"EMFPLUS_FILLRECTS"}, - {0x4013, L"EMFPLUS_FILLREGION"}, - - {0x4008, L"EMFPLUS_OBJECT"}, - {0x4038, L"EMFPLUS_SERIALIZABLEOBJECT"}, - - {0x401E, L"EMFPLUS_SETANTIALIASMODE"}, - {0x4023, L"EMFPLUS_SETCOMPOSITINGMODE"}, - {0x4024, L"EMFPLUS_SETCOMPOSITINGQUALITY"}, - {0x4021, L"EMFPLUS_SETINTERPOLATIONMODE"}, - {0x4022, L"EMFPLUS_SETPIXELOFFSETMODE"}, - {0x401D, L"EMFPLUS_SETRENDERINGORIGIN"}, - {0x4020, L"EMFPLUS_SETTEXTCONTRAST"}, - {0x401F, L"EMFPLUS_SETTEXTRENDERINGHINT"}, - - {0x4027, L"EMFPLUS_BEGINCONTAINER"}, - {0x4028, L"EMFPLUS_BEGINCONTAINERNOPARAMS"}, - {0x4029, L"EMFPLUS_ENDCONTAINER"}, - {0x4026, L"EMFPLUS_RESTORE"}, - {0x4025, L"EMFPLUS_SAVE"}, - - {0x403A, L"EMFPLUS_SETTSCLIP"}, - {0x4039, L"EMFPLUS_SETTSGRAPHICS"}, - - {0x402C, L"EMFPLUS_MULTIPLYWORLDTRANSFORM"}, - {0x402B, L"EMFPLUS_RESETWORLDTRANSFORM"}, - {0x402F, L"EMFPLUS_ROTATEWORLDTRANSFORM"}, - {0x402E, L"EMFPLUS_SCALEWORLDTRANSFORM"}, - {0x4030, L"EMFPLUS_SETPAGETRANSFORM"}, - {0x402A, L"EMFPLUS_SETWORLDTRANSFORM"}, - {0x402D, L"EMFPLUS_TRANSLATEWORLDTRANSFORM"} - }; - CEmfPlusParser::CEmfPlusParser(CEmfInterpretatorBase *pEmfInterpretator, const TEmfHeader& oHeader) - : m_bBanEmfProcessing(false), + : m_bBanEmfProcessing(true), m_unLogicalDpiX(96), m_unLogicalDpiY(96), - m_dUnitKoef(1) + m_dPageTransformX(1.), + m_dPageTransformY(1.) { m_oHeader = oHeader; @@ -219,6 +239,9 @@ namespace MetaFile unsigned short unShType, unShFlags; unsigned int unSize; + if (NULL != m_pInterpretator) + GO_UP_LEVEL; + do { if (m_bEof) @@ -233,9 +256,17 @@ namespace MetaFile m_oStream >> unSize; m_oStream >> m_ulRecordSize; + if (unSize < 12 || m_ulRecordSize > m_oStream.CanRead() || m_ulRecordSize > (unSize - 12)) + break; + + m_oStream.SetCurrentBlockSize(m_ulRecordSize); + unsigned int unRecordPos = m_oStream.Tell(); - LOGGING(ActionNamesEmfPlus[unShType] << L" DataSize = " << m_ulRecordSize) + if (NULL != m_pInterpretator) + PRINT_EMF_PLUS_RECORD(unShType, m_ulRecordSize); + + m_bBanEmfProcessing = true; switch (unShType) { @@ -315,15 +346,18 @@ namespace MetaFile int nNeedSkip = (unRecordPos + m_ulRecordSize) - m_oStream.Tell(); m_oStream.Skip(nNeedSkip); - LOGGING(L"Skip: " << nNeedSkip) + if (0 != nNeedSkip && NULL != m_pInterpretator) + PRINT_LOG(L"SKIP BYTES: " << nNeedSkip); + m_oStream.ClearCurrentBlockSize(); m_ulRecordSize = 0; }while(m_oStream.CanRead() >= 12 && !m_bEof); if (!CheckError()) m_oStream.SeekToStart(); - LOGGING(L"_____________________________________________________") + if (NULL != m_pInterpretator) + GO_DOWN_LEVEL_BELOW; } void CEmfPlusParser::Scan() @@ -335,12 +369,12 @@ namespace MetaFile this->ClearFile(); } - double CEmfPlusParser::GetDpi() + USHORT CEmfPlusParser::GetDpi() const { - return (double)m_unLogicalDpiX; + return m_unLogicalDpiX; } - EmfParserType CEmfPlusParser::GetType() + EmfParserType CEmfPlusParser::GetType() const { return EmfParserType::EmfPlusParser; } @@ -621,20 +655,18 @@ namespace MetaFile m_oStream >> unPositionCount; - std::vector arBlendPositions(unPositionCount); - - for (unsigned int unIndex = 0; unIndex < unPositionCount; ++unIndex) - m_oStream >> arBlendPositions[unIndex]; + if (unPositionCount > 1) + { + pEmfPlusBrush->arGradientColors.resize(unPositionCount); - std::vector arBlendColors(unPositionCount); + for (unsigned int unIndex = 0; unIndex < unPositionCount; ++unIndex) + m_oStream >> pEmfPlusBrush->arGradientColors[unIndex].second; - for (unsigned int unIndex = 0; unIndex < unPositionCount; ++unIndex) - m_oStream >> arBlendColors[unIndex]; + for (unsigned int unIndex = 0; unIndex < unPositionCount; ++unIndex) + m_oStream >> pEmfPlusBrush->arGradientColors[unIndex].first; - if (1 < unPositionCount) - { - pEmfPlusBrush->oColorBack = arBlendColors[0]; - pEmfPlusBrush->oColor = arBlendColors.back(); + pEmfPlusBrush->oColor = pEmfPlusBrush->arGradientColors[unPositionCount - 1].first; + pEmfPlusBrush->oColorBack = pEmfPlusBrush->arGradientColors[0].first; } } @@ -645,13 +677,40 @@ namespace MetaFile //TODO: реализовать pEmfPlusBrush->unStyle = BS_LINEARGRADIENT; - m_oStream.Skip(8); // BrushDataFlags, WrapMode + int nBrushDataFlags; + m_oStream >> nBrushDataFlags; + + m_oStream.Skip(4); // WrapMode // m_oStream >> pEmfPlusBrush->RectF; m_oStream.Skip(16); m_oStream >> pEmfPlusBrush->oColor; m_oStream >> pEmfPlusBrush->oColorBack; + m_oStream.Skip(8); // Reserved1, Reserved2 + + if (BrushDataTransform & nBrushDataFlags) + { + m_oStream.Skip(24); + } + + if (BrushDataPresetColors & nBrushDataFlags) + { + int nPositionCount; + m_oStream >> nPositionCount; + + if (nPositionCount > 1) + { + pEmfPlusBrush->arGradientColors.resize(nPositionCount); + + for (unsigned int unIndex = 0; unIndex < nPositionCount; ++unIndex) + m_oStream >> pEmfPlusBrush->arGradientColors[unIndex].second; + + for (unsigned int unIndex = 0; unIndex < nPositionCount; ++unIndex) + m_oStream >> pEmfPlusBrush->arGradientColors[unIndex].first; + } + } + break; } default: @@ -703,7 +762,7 @@ namespace MetaFile switch (nStartCap) { - case 0: pEmfPlusPen->unStyle |= PS_STARTCAP_MASK & PS_STARTCAP_FLAT; break; + case 0: pEmfPlusPen->unStyle |= PS_STARTCAP_MASK & PS_STARTCAP_FLAT; break; case 1: pEmfPlusPen->unStyle |= PS_STARTCAP_MASK & PS_STARTCAP_SQUARE; break; case 2: pEmfPlusPen->unStyle |= PS_STARTCAP_MASK & PS_STARTCAP_ROUND; break; } @@ -918,6 +977,9 @@ namespace MetaFile m_oStream >> unLength; + if (unLength > 15) // 30 байта / 2 (размер ushort) = 15 символов максимальная длина имени Unicode шрифта + unLength = 15; + unsigned short* pString = new unsigned short[unLength + 1]; if (pString) { @@ -998,7 +1060,7 @@ namespace MetaFile else { std::vector arPoints = ReadPoints(unPathPointCount); - std::vector arPointTypes = ReadPointTypes(unPathPointCount); + std::vector arPointTypes = ReadPointTypes(unPathPointCount); pPath->MoveTo(arPoints[0].X, arPoints[0].Y); @@ -1329,19 +1391,24 @@ namespace MetaFile oPath.LineTo(oClip.Left, oClip.Bottom); oPath.Close(); - m_pDC->GetClip()->SetPath(oPath, nMode, *GetTransform()); + m_pDC->GetClip()->SetPath(oPath, nMode, GetTransform()); UpdateOutputDC(); } - void CEmfPlusParser::UpdateMatrix(TEmfPlusXForm &oMatrix) + double CEmfPlusParser::GetUnitToPixel(const double& dDpi, EEmfPlusUnitType eUnitType) const { - oMatrix.M11 *= m_dUnitKoef; - oMatrix.M12 *= m_dUnitKoef; - oMatrix.M21 *= m_dUnitKoef; - oMatrix.M22 *= m_dUnitKoef; - oMatrix.Dx *= m_dUnitKoef; - oMatrix.Dy *= m_dUnitKoef; + switch (eUnitType) + { + case UnitTypePixel: + case UnitTypeWorld: + case UnitTypeDisplay: + default: return 1.; + case UnitTypePoint: return dDpi / 72.; + case UnitTypeInch: return dDpi; + case UnitTypeDocument: return dDpi / 300.; + case UnitTypeMillimeter: return dDpi / 25.4; + } } bool CEmfPlusParser::SaveImage(const CEmfPlusImage &oEmfPlusImage, std::wstring &wsPathToImage) @@ -1374,48 +1441,50 @@ namespace MetaFile return true; } - BYTE* GetClipedImage(const BYTE* pBuffer, LONG lWidth, LONG lHeight, TRectL& oNewRect) + BYTE* GetClipedImage(const BYTE* pBuffer, LONG lWidth, LONG lHeight, const TRectL& oNewRect, unsigned int& nWidth, unsigned int& nHeight) { - if (NULL == pBuffer || - oNewRect.Left < 0 || oNewRect.Right < 0 || - oNewRect.Top < 0 || oNewRect.Bottom < 0) + if (NULL == pBuffer) return NULL; - if (lHeight < (oNewRect.Bottom - oNewRect.Top)) - oNewRect.Bottom = oNewRect.Top + lHeight; + int nBeginX = (std::min)(oNewRect.Left, oNewRect.Right); + int nBeginY = (std::min)(oNewRect.Top, oNewRect.Bottom); - if (lWidth < (oNewRect.Right - oNewRect.Left)) - oNewRect.Right = oNewRect.Left + lWidth; + int nEndX = (std::max)(oNewRect.Left, oNewRect.Right); + int nEndY = (std::max)(oNewRect.Top, oNewRect.Bottom); - if (lHeight == (oNewRect.Bottom - oNewRect.Top) && - lWidth == (oNewRect.Right - oNewRect.Left)) + if (nBeginX >= lWidth || nEndX <= 0) + return NULL; + if (nBeginY >= lHeight || nEndY <= 0) return NULL; - int nBeginX, nBeginY, nEndX, nEndY; + if (nBeginX <= 0 && nEndX >= lWidth && + nBeginY <= 0 && nEndY >= lHeight) + return NULL; - nBeginX = (std::min)(oNewRect.Left, oNewRect.Right); - nBeginY = (std::min)(oNewRect.Top, oNewRect.Bottom); + if (nBeginX < 0) + nBeginX = 0; + if (nBeginY < 0) + nBeginY = 0; - nEndX = (std::max)(oNewRect.Left, oNewRect.Right); - nEndY = (std::max)(oNewRect.Top, oNewRect.Bottom); + if (nEndX > lWidth) + nEndX = lWidth; + if (nEndY > lHeight) + nEndY = lHeight; - int nWidth = nEndX - nBeginX; - int nHeight = nEndY - nBeginY; + if (nEndX <= nBeginX || nEndY <= nBeginY) + return NULL; - BYTE* pNewBuffer = new BYTE[nWidth * nHeight * 4]; + nWidth = nEndX - nBeginX; + nHeight = nEndY - nBeginY; - ULONG ulPos = 0; + BYTE* pNewBuffer = new BYTE[nWidth * nHeight * 4]; + BYTE* pCurrentLine = pNewBuffer; - for (ULONG ulPosY = nBeginY * 4; ulPosY < nEndY * 4; ulPosY += 4) + int ulStride = 4 * nWidth; + for (int nPosY = nBeginY; nPosY < nEndY; ++nPosY) { - for (ULONG ulPosX = nBeginX * 4; ulPosX < nEndX * 4; ulPosX += 4) - { - pNewBuffer[ulPos + 0] = (BYTE)pBuffer[ulPosY * lWidth + ulPosX + 0]; - pNewBuffer[ulPos + 1] = (BYTE)pBuffer[ulPosY * lWidth + ulPosX + 1]; - pNewBuffer[ulPos + 2] = (BYTE)pBuffer[ulPosY * lWidth + ulPosX + 2]; - pNewBuffer[ulPos + 3] = (BYTE)pBuffer[ulPosY * lWidth + ulPosX + 3]; - ulPos += 4; - } + memcpy(pCurrentLine, pBuffer + lWidth * 4 * nPosY + 4 * nBeginX, ulStride); + pCurrentLine += ulStride; } return pNewBuffer; @@ -1426,29 +1495,18 @@ namespace MetaFile if (NULL == pImageBuffer || lWidth == 0 || lHeight == 0) return S_FALSE; - BYTE oBuffer[4] = {0, 0, 0, 0}; + BYTE* pTempLine = (BYTE*)malloc(lWidth * 4); + const ULONG ulStride = 4 * lWidth; - for (ULONG ulPosY = 0; ulPosY < lHeight / 2 * 4; ulPosY += 4) + for (UINT nPosY = 0; nPosY < lHeight / 2; ++nPosY) { - for (ULONG ulPosX = 0; ulPosX < lWidth * 4; ulPosX += 4) - { - oBuffer[0] = pImageBuffer[ulPosY * lWidth + ulPosX + 0]; - oBuffer[1] = pImageBuffer[ulPosY * lWidth + ulPosX + 1]; - oBuffer[2] = pImageBuffer[ulPosY * lWidth + ulPosX + 2]; - oBuffer[3] = pImageBuffer[ulPosY * lWidth + ulPosX + 3]; - - pImageBuffer[ulPosY * lWidth + ulPosX + 0] = pImageBuffer[((lHeight - 1) * 4 - ulPosY) * lWidth + ulPosX + 0]; - pImageBuffer[ulPosY * lWidth + ulPosX + 1] = pImageBuffer[((lHeight - 1) * 4 - ulPosY) * lWidth + ulPosX + 1]; - pImageBuffer[ulPosY * lWidth + ulPosX + 2] = pImageBuffer[((lHeight - 1) * 4 - ulPosY) * lWidth + ulPosX + 2]; - pImageBuffer[ulPosY * lWidth + ulPosX + 3] = pImageBuffer[((lHeight - 1) * 4 - ulPosY) * lWidth + ulPosX + 3]; - - pImageBuffer[((lHeight - 1) * 4 - ulPosY) * lWidth + ulPosX + 0] = oBuffer[0]; - pImageBuffer[((lHeight - 1) * 4 - ulPosY) * lWidth + ulPosX + 1] = oBuffer[1]; - pImageBuffer[((lHeight - 1) * 4 - ulPosY) * lWidth + ulPosX + 2] = oBuffer[2]; - pImageBuffer[((lHeight - 1) * 4 - ulPosY) * lWidth + ulPosX + 3] = oBuffer[3]; - } + memcpy(pTempLine, pImageBuffer + nPosY * ulStride, ulStride); + memcpy(pImageBuffer + nPosY * ulStride, pImageBuffer + (lHeight - nPosY - 1) * ulStride, ulStride); + memcpy(pImageBuffer + (lHeight - nPosY - 1) * ulStride, pTempLine, ulStride); } + free(pTempLine); + return S_OK; } @@ -1471,7 +1529,7 @@ namespace MetaFile if (NULL == pBuffer || unSizeBuffer == 0 || arPoints.size() != 3) return; - if (ImageDataTypeBitmap == pImage->GetImageDataType()) + if (ImageDataTypeBitmap == pImage->GetImageDataType()) { unsigned int unWidth, unHeigth; @@ -1481,245 +1539,167 @@ namespace MetaFile } else if (ImageDataTypeMetafile == pImage->GetImageDataType()) { - DrawMetafile(pBuffer, unSizeBuffer, oSrcRect, arPoints, pImage->GetMetafileType(), unImageAttributeIndex); - } -} - - void CEmfPlusParser::DrawMetafile(BYTE *pBuffer, unsigned int unSize, const TEmfPlusRectF& oSrcRect, const std::vector& arPoints, EEmfPlusMetafileDataType eMetafileType, unsigned int unImageAttributeIndex) - { - if (NULL == pBuffer || 0 == unSize || MetafileDataTypeUnknown == eMetafileType) - return; - - if (MetafileDataTypeEmf == eMetafileType || - MetafileDataTypeEmfPlusOnly == eMetafileType || - MetafileDataTypeEmfPlusDual == eMetafileType) - { - CEmfParser oEmfParser; - oEmfParser.SetStream(pBuffer, unSize); - oEmfParser.SetFontManager(GetFontManager()); - oEmfParser.Scan(); - - if (!oEmfParser.CheckError() && InterpretatorType::Render == m_pInterpretator->GetType()) + switch ((int)pImage->GetMetafileType()) { - NSGraphics::IGraphicsRenderer* pGrRenderer = NSGraphics::Create(); - - pGrRenderer->SetFontManager(GetFontManager()); - - TRectL *pEmfBounds = oEmfParser.GetBounds(); - - int nWidth = fabs(pEmfBounds->Right - pEmfBounds->Left); - int nHeight = fabs(pEmfBounds->Bottom - pEmfBounds->Top); - - double dWidth = 25.4 * nWidth / 72; - double dHeight = 25.4 * nHeight / 72; - - BYTE* pBgraData = new BYTE[nWidth * nHeight * 4]; - - if (!pBgraData) - return; - - unsigned int alfa = 0xffffff; - //дефолтный тон должен быть прозрачным, а не белым - //memset(pBgraData, 0xff, nWidth * nHeight * 4); - for (int i = 0; i < nWidth * nHeight; i++) + case MetafileDataTypeEmf: + case MetafileDataTypeEmfPlusOnly: + case MetafileDataTypeEmfPlusDual: { - ((unsigned int*)pBgraData)[i] = alfa; + return DrawMetafile(pBuffer, unSizeBuffer, oSrcRect, arPoints); + } + case MetafileDataTypeWmf: + case MetafileDataTypeWmfPlaceable: + { + return DrawMetafile(pBuffer, unSizeBuffer, oSrcRect, arPoints); } - - CBgraFrame oFrame; - oFrame.put_Data(pBgraData); - oFrame.put_Width(nWidth); - oFrame.put_Height(nHeight); - oFrame.put_Stride(-4 * nWidth); - - pGrRenderer->CreateFromBgraFrame(&oFrame); - pGrRenderer->SetSwapRGB(false); - pGrRenderer->put_Width(dWidth); - pGrRenderer->put_Height(dHeight); - - pGrRenderer->BeginCommand(c_nImageType); - - CMetaFileRenderer oEmfOut(&oEmfParser, pGrRenderer, 0, 0, dWidth, dHeight); - oEmfParser.SetInterpretator(&oEmfOut); - - oEmfParser.PlayFile(); - - pGrRenderer->EndCommand(c_nImageType); - - LONG lWidth = nWidth, lHeight = nHeight; - - BYTE* pPixels = oFrame.get_Data(); - - FlipYImage(pPixels, lWidth, lHeight); //Проверить на примерах, где WrapMode != WrapModeTileFlipXY - - TRectL oClipRect; - - oClipRect.Left = oSrcRect.dX; - oClipRect.Top = oSrcRect.dY; - oClipRect.Right = oSrcRect.dX + oSrcRect.dWidth; - oClipRect.Bottom = oSrcRect.dY + oSrcRect.dHeight; - - BYTE* pNewBuffer = GetClipedImage(pPixels, lWidth, lHeight, oClipRect); - - unsigned int unWidth = std::min(((unsigned int)fabs(oClipRect.Right - oClipRect.Left)), ((unsigned int)lWidth )); - unsigned int unHeight = std::min(((unsigned int)fabs(oClipRect.Bottom - oClipRect.Top)), ((unsigned int)lHeight)); - - m_pInterpretator->DrawBitmap(arPoints[0].X, arPoints[0].Y, arPoints[1].X - arPoints[0].X - m_pDC->GetPixelWidth(), arPoints[2].Y - arPoints[0].Y - m_pDC->GetPixelHeight(), - (NULL != pNewBuffer) ? pNewBuffer : pPixels, unWidth, unHeight); - - RELEASEINTERFACE(pGrRenderer); - RELEASEARRAYOBJECTS(pNewBuffer); } - else if (!oEmfParser.CheckError() && InterpretatorType::Svg == m_pInterpretator->GetType()) - { - ((CEmfParserBase*)&oEmfParser)->SetInterpretator(InterpretatorType::Svg); + } + } - oEmfParser.PlayFile(); + template + void CEmfPlusParser::DrawMetafile(BYTE *pBuffer, unsigned int unSize, const TEmfPlusRectF &oSrcRect, const std::vector &arPoints) + { + if (NULL == pBuffer || 0 == unSize || 3 != arPoints.size()) + return; - TXForm *pXForm = m_pDC->GetTransform(); + const TRectL& oOriginalBounds{GetOriginalDCBounds()}; + const TXForm oCurrentTransform{CalculateCurrentTransform()}; - TRectD oRect; + bool bIsWokspace{false}; - oRect.Left = arPoints[0].X; - oRect.Top = arPoints[0].Y; - oRect.Right = arPoints[1].X - m_pDC->GetPixelWidth(); - oRect.Bottom = arPoints[2].Y - m_pDC->GetPixelHeight(); + for (TEmfPlusPointF oPoint : arPoints) + { + oCurrentTransform.Apply(oPoint.X, oPoint.Y); - TRectD oTempSrcRect; + if (oPoint.X > oOriginalBounds.Left && oPoint.X < oOriginalBounds.Right && + oPoint.Y > oOriginalBounds.Top && oPoint.Y < oOriginalBounds.Bottom) + { + bIsWokspace = true; + break; + } + } - TRectL *pEmfBounds = oEmfParser.GetBounds(); + if (!bIsWokspace) + return; - oTempSrcRect = oSrcRect.ToRectD(); - oTempSrcRect.Left -= pEmfBounds->Left; - oTempSrcRect.Right -= pEmfBounds->Left + GetPixelWidth(); - oTempSrcRect.Top -= pEmfBounds->Top; - oTempSrcRect.Bottom -= pEmfBounds->Top + GetPixelHeight(); + MetafileType oParser; - TXForm oTransform; + oParser.SetStream(pBuffer, unSize); + oParser.SetFontManager(GetFontManager()); + oParser.SetParent(this); + oParser.Scan(); - oTransform.Copy(pXForm); + if (oParser.CheckError()) + return; - oTransform.Dx -= m_oHeader.oFramePx.Left; - oTransform.Dy -= m_oHeader.oFramePx.Top; + const TRectL& oFileBounds{oParser.GetDCBounds()}; + const double dFileWidth = std::abs(oFileBounds.Right - oFileBounds.Left); + const double dFileHeight = std::abs(oFileBounds.Bottom - oFileBounds.Top); - ((CEmfInterpretatorSvg*)m_pInterpretator)->IncludeSvg(((CEmfInterpretatorSvg*)oEmfParser.GetInterpretator())->GetFile(), oRect, oTempSrcRect, &oTransform); - } + const TRectL& oParentBounds{GetDCBounds()}; + const double dParentWidth = std::abs(oParentBounds.Right - oParentBounds.Left); + const double dParentHeight = std::abs(oParentBounds.Bottom - oParentBounds.Top); - } - else if (MetafileDataTypeWmf == eMetafileType || - MetafileDataTypeWmfPlaceable == eMetafileType) + if (InterpretatorType::Render == m_pInterpretator->GetType()) { - CWmfParser oWmfParser; - oWmfParser.SetStream(pBuffer, unSize); - oWmfParser.SetFontManager(GetFontManager()); - oWmfParser.Scan(); + NSGraphics::IGraphicsRenderer* pGrRenderer = NSGraphics::Create(); - if (!oWmfParser.CheckError() && InterpretatorType::Render == m_pInterpretator->GetType()) - { - NSGraphics::IGraphicsRenderer* pGrRenderer = NSGraphics::Create(); - pGrRenderer->SetFontManager(GetFontManager()); + pGrRenderer->SetFontManager(GetFontManager()); - TRectD oWmfBounds = oWmfParser.GetBounds(); + double dScale = ((CEmfInterpretatorRender*)m_pInterpretator)->GetRenderer()->GetWidth() * 96. / 25.4 / dParentWidth; - int nWidth = fabs(oWmfBounds.Right - oWmfBounds.Left); - int nHeight = fabs(oWmfBounds.Bottom - oWmfBounds.Top); + const double dMaxWidth = std::max(MAX_PICTURE_SIZE, dParentWidth); + const double dMaxHeight = std::max(MAX_PICTURE_SIZE, dParentHeight); - double dWidth = 25.4 * nWidth / 72; - double dHeight = 25.4 * nHeight / 72; + dScale *= std::min(dMaxWidth / dFileWidth, dMaxHeight / dFileHeight); - BYTE* pBgraData = new BYTE[nWidth * nHeight * 4]; + const int nWidth = dFileWidth * dScale; + const int nHeight = dFileHeight * dScale; - if (!pBgraData) - return; - - unsigned int alfa = 0xffffff; - //дефолтный тон должен быть прозрачным, а не белым - //memset(pBgraData, 0xff, nWidth * nHeight * 4); - for (int i = 0; i < nWidth * nHeight; i++) - { - ((unsigned int*)pBgraData)[i] = alfa; - } + BYTE* pBgraData = new(std::nothrow) BYTE[nWidth * nHeight * 4]; - CBgraFrame oFrame; - oFrame.put_Data(pBgraData); - oFrame.put_Width(nWidth); - oFrame.put_Height(nHeight); - oFrame.put_Stride(-4 * nWidth); + if (!pBgraData) + return; - pGrRenderer->CreateFromBgraFrame(&oFrame); - pGrRenderer->SetSwapRGB(false); - pGrRenderer->put_Width(dWidth); - pGrRenderer->put_Height(dHeight); + unsigned int alfa = 0xffffff; + //дефолтный тон должен быть прозрачным, а не белым + //memset(pBgraData, 0x00, nWidth * nHeight * 4); + for (int i = 0; i < nWidth * nHeight; i++) + ((unsigned int*)pBgraData)[i] = alfa; - pGrRenderer->BeginCommand(c_nImageType); + const double dWidth = nWidth * 25.4 / 96; + const double dHeight = nHeight * 25.4 / 96; - CMetaFileRenderer oWmfOut(&oWmfParser, pGrRenderer, 0, 0, dWidth, dHeight); - oWmfParser.SetInterpretator(&oWmfOut); - oWmfParser.PlayFile(); + CBgraFrame oFrame; + oFrame.put_Data(pBgraData); + oFrame.put_Width(nWidth); + oFrame.put_Height(nHeight); + oFrame.put_Stride(4 * nWidth); - pGrRenderer->EndCommand(c_nImageType); + pGrRenderer->CreateFromBgraFrame(&oFrame); + pGrRenderer->SetSwapRGB(false); + pGrRenderer->put_Width(dWidth); + pGrRenderer->put_Height(dHeight); - LONG lWidth = nWidth, lHeight = nHeight; + pGrRenderer->BeginCommand(c_nImageType); - BYTE* pPixels = oFrame.get_Data(); + CMetaFileRenderer oEmfOut(&oParser, pGrRenderer, 0, 0, dWidth, dHeight); + oParser.SetInterpretator(&oEmfOut); - FlipYImage(pPixels, lWidth, lHeight); //Проверить на примерах, где WrapMode != WrapModeTileFlipXY + oParser.PlayFile(); - TRectL oClipRect; + pGrRenderer->EndCommand(c_nImageType); - oClipRect.Left = oSrcRect.dX; - oClipRect.Top = oSrcRect.dY; - oClipRect.Right = oSrcRect.dX + oSrcRect.dWidth; - oClipRect.Bottom = oSrcRect.dY + oSrcRect.dHeight; + BYTE* pPixels = oFrame.get_Data(); - BYTE* pNewBuffer = GetClipedImage(pPixels, lWidth, lHeight, oClipRect); + TRectL oClipRect; - unsigned int unWidth = std::min(((unsigned int)fabs(oClipRect.Right - oClipRect.Left)), ((unsigned int)lWidth )); - unsigned int unHeight = std::min(((unsigned int)fabs(oClipRect.Bottom - oClipRect.Top)), ((unsigned int)lHeight)); + oClipRect.Left = std::floor((oSrcRect.dX - oFileBounds.Left) * dScale); + oClipRect.Top = std::floor((oSrcRect.dY - oFileBounds.Top) * dScale); + oClipRect.Right = std::floor((oSrcRect.dX + oSrcRect.dWidth - oFileBounds.Left) * dScale); + oClipRect.Bottom = std::floor((oSrcRect.dY + oSrcRect.dHeight - oFileBounds.Top) * dScale); - m_pInterpretator->DrawBitmap(arPoints[0].X, arPoints[0].Y, arPoints[1].X - arPoints[0].X - m_pDC->GetPixelWidth(), arPoints[2].Y - arPoints[0].Y - m_pDC->GetPixelHeight(), - (NULL != pNewBuffer) ? pNewBuffer : pPixels, unWidth, unHeight); + unsigned int nW = (unsigned int)nWidth; + unsigned int nH = (unsigned int)nHeight; + BYTE* pNewBuffer = GetClipedImage(pPixels, nWidth, nHeight, oClipRect, nW, nH); - RELEASEINTERFACE(pGrRenderer); - RELEASEARRAYOBJECTS(pNewBuffer); - } - else if (!oWmfParser.CheckError() && InterpretatorType::Svg == m_pInterpretator->GetType()) - { - ((CWmfParserBase*)&oWmfParser)->SetInterpretator(InterpretatorType::Svg); + m_pInterpretator->DrawBitmap(arPoints[0].X, arPoints[0].Y, arPoints[1].X - arPoints[0].X - m_pDC->GetPixelWidth(), arPoints[2].Y - arPoints[0].Y - m_pDC->GetPixelHeight(), + (NULL != pNewBuffer) ? pNewBuffer : pPixels, nW, nH); - oWmfParser.PlayFile(); + RELEASEINTERFACE(pGrRenderer); + RELEASEARRAYOBJECTS(pNewBuffer); + } + else if (InterpretatorType::Svg == m_pInterpretator->GetType()) + { + ((MetafileType*)&oParser)->SetInterpretator(InterpretatorType::Svg); - TXForm *pXForm = m_pDC->GetFinalTransform(GM_ADVANCED); + oParser.PlayFile(); - TRectD oRect; + TRectD oRect; - oRect.Left = arPoints[0].X; - oRect.Top = arPoints[0].Y; - oRect.Right = arPoints[1].X - m_pDC->GetPixelWidth(); - oRect.Bottom = arPoints[2].Y - m_pDC->GetPixelHeight(); + oRect.Left = arPoints[0].X; + oRect.Top = arPoints[0].Y; + oRect.Right = arPoints[1].X - m_pDC->GetPixelWidth(); + oRect.Bottom = arPoints[2].Y - m_pDC->GetPixelHeight(); - TRectD oTempSrcRect = oSrcRect.ToRectD(); + TRectD oTempSrcRect; - CEmfPlusImageAttributes *pImageAttributes = GetImageAttributes(unImageAttributeIndex); + oTempSrcRect.Left = oSrcRect.dX - oFileBounds.Left; + oTempSrcRect.Top = oSrcRect.dY - oFileBounds.Top; + oTempSrcRect.Right = oTempSrcRect.Left + ((dFileWidth > oSrcRect.dWidth) ? oSrcRect.dWidth - GetPixelWidth() : dFileWidth); + oTempSrcRect.Bottom = oTempSrcRect.Top + ((dFileHeight > oSrcRect.dHeight) ? oSrcRect.dHeight - GetPixelHeight() : dFileHeight); - if (NULL != pImageAttributes && WrapModeTileFlipY != pImageAttributes->eWrapMode && WrapModeTileFlipXY != pImageAttributes->eWrapMode) - { - double dTempValue = oTempSrcRect.Bottom; - oTempSrcRect.Bottom = oTempSrcRect.Top; - oTempSrcRect.Top = dTempValue; - } + TXForm oTransform(m_pDC->GetTransform()); - TXForm oTransform; + oTransform.Dx -= m_oHeader.oFramePx.Left; + oTransform.Dy -= m_oHeader.oFramePx.Top; - oTransform.Copy(pXForm); + CInterpretatorSvgBase* pParserSvgInterpretator = dynamic_cast(oParser.GetInterpretator()); + CInterpretatorSvgBase *pSvgInterpretator = dynamic_cast(m_pInterpretator); - oTransform.Dx -= m_oHeader.oFramePx.Left; - oTransform.Dy -= m_oHeader.oFramePx.Top; - - ((CWmfInterpretatorSvg*)m_pInterpretator)->IncludeSvg(((CWmfInterpretatorSvg*)oWmfParser.GetInterpretator())->GetFile(), oRect, oTempSrcRect, &oTransform); - } + if (NULL != pParserSvgInterpretator && NULL != pSvgInterpretator) + pSvgInterpretator->IncludeSvg(pParserSvgInterpretator->GetFile(), oRect, oTempSrcRect, &oTransform); } - //TODO: общую часть в идеале нужно вынести } void CEmfPlusParser::DrawBitmap(BYTE *pBuffer, unsigned int unSize, unsigned int unWidth, unsigned int unHeight, const TEmfPlusRectF& oSrcRect, const std::vector& arPoints) @@ -1753,15 +1733,17 @@ namespace MetaFile TRectL oClipRect; - oClipRect.Left = oSrcRect.dX; - oClipRect.Top = oSrcRect.dY; - oClipRect.Right = (oSrcRect.dX + oSrcRect.dWidth); - oClipRect.Bottom = (oSrcRect.dY + oSrcRect.dHeight); + oClipRect.Left = std::floor(oSrcRect.dX); + oClipRect.Top = std::floor(oSrcRect.dY); + oClipRect.Right = std::floor((oSrcRect.dX + oSrcRect.dWidth)); + oClipRect.Bottom = std::floor((oSrcRect.dY + oSrcRect.dHeight)); - BYTE* pNewBuffer = GetClipedImage(pBytes, unWidth, unHeight, oClipRect); + unsigned int nW = (unsigned int)unWidth; + unsigned int nH = (unsigned int)unHeight; + BYTE* pNewBuffer = GetClipedImage(pBytes, unWidth, unHeight, oClipRect, nW, nH); m_pInterpretator->DrawBitmap(arPoints[0].X, arPoints[0].Y, arPoints[1].X - arPoints[0].X, arPoints[2].Y - arPoints[0].Y, - (NULL != pNewBuffer) ? pNewBuffer : pBytes, fabs(oClipRect.Right - oClipRect.Left), fabs(oClipRect.Bottom - oClipRect.Top)); + (NULL != pNewBuffer) ? pNewBuffer : pBytes, nW, nH); if (!bExternalBuffer) RELEASEARRAYOBJECTS(pBytes); @@ -1771,7 +1753,7 @@ namespace MetaFile void CEmfPlusParser::Read_EMFPLUS_HEADER(unsigned short unShFlags) { - m_oStream.Skip(4); //Version + m_oStream.Skip(4); //Data size unsigned int unEmfPlusFlags; @@ -1779,8 +1761,6 @@ namespace MetaFile m_oStream >> m_unLogicalDpiX; m_oStream >> m_unLogicalDpiY; - m_bBanEmfProcessing = true; - if (NULL != m_pInterpretator) { m_pInterpretator->Begin(); @@ -1797,8 +1777,6 @@ namespace MetaFile if (NULL != m_pInterpretator) m_pInterpretator->HANDLE_EMFPLUS_CLEAR(oARGB); - - m_bBanEmfProcessing = true; } void CEmfPlusParser::Read_EMFPLUS_DRAWARC(unsigned short unShFlags) @@ -1807,8 +1785,6 @@ namespace MetaFile Read_EMFPLUS_DRAWARC_BASE(unShFlags); else Read_EMFPLUS_DRAWARC_BASE(unShFlags); - - m_bBanEmfProcessing = true; } template @@ -1867,8 +1843,6 @@ namespace MetaFile //Оба флага не определены Read_EMFPLUS_DRAWBEZIERS_BASE(unShFlags); // абсолютное расположение } - - m_bBanEmfProcessing = true; } template @@ -1928,8 +1902,6 @@ namespace MetaFile //Оба флага не определены Read_EMFPLUS_DRAWCLOSEDCURVE_BASE(unShFlags); // абсолютное расположение с 32-разрядными координатами. } - - m_bBanEmfProcessing = true; } template @@ -1982,8 +1954,6 @@ namespace MetaFile Read_EMFPLUS_DRAWCURVE_BASE(unShFlags); else Read_EMFPLUS_DRAWCURVE_BASE(unShFlags); - - m_bBanEmfProcessing = true; } template @@ -2060,8 +2030,6 @@ namespace MetaFile TEmfPlusXForm oMatrix; m_oStream >> oMatrix; - - m_bBanEmfProcessing = true; } //---------- if (NULL == m_pInterpretator || wsString.length() != arGlyphPos.size()) @@ -2090,7 +2058,7 @@ namespace MetaFile oColor.r = (unBrushId >> 16) & 0xFF; oColor.a = (unBrushId >> 24) & 0xFF; - TRGBA oTextColor = m_pDC->GetTextColor(); + const TRGBA oTextColor{m_pDC->GetTextColor()}; m_pDC->SetTextColor(oColor); @@ -2112,7 +2080,7 @@ namespace MetaFile oColor.r = pBrush->oColor.chRed; oColor.a = pBrush->oColor.chAlpha; - TRGBA oTextColor = m_pDC->GetTextColor(); + const TRGBA oTextColor{m_pDC->GetTextColor()}; m_pDC->SetTextColor(oColor); @@ -2125,8 +2093,6 @@ namespace MetaFile } m_pDC->RemoveFont(pFont); - - m_bBanEmfProcessing = true; } void CEmfPlusParser::Read_EMFPLUS_DRAWELLIPSE(unsigned short unShFlags) @@ -2135,8 +2101,6 @@ namespace MetaFile Read_EMFPLUS_DRAWELLIPSE_BASE(unShFlags); else Read_EMFPLUS_DRAWELLIPSE_BASE(unShFlags); - - m_bBanEmfProcessing = true; } template @@ -2180,8 +2144,6 @@ namespace MetaFile Read_EMFPLUS_DRAWIMAGE_BASE(unShFlags); else Read_EMFPLUS_DRAWIMAGE_BASE(unShFlags); - - m_bBanEmfProcessing = true; } template @@ -2228,8 +2190,6 @@ namespace MetaFile //Оба флага не определены Read_EMFPLUS_DRAWIMAGEPOINTS_BASE(unShFlags); // абсолютное расположение с 32-разрядными координатами с плавующей запятой } - - m_bBanEmfProcessing = true; } template @@ -2245,7 +2205,7 @@ namespace MetaFile m_oStream >> oSrcRect; m_oStream >> unCount; - if (nSrcUnit != UnitTypePixel && unCount != 3) + if (nSrcUnit != UnitTypePixel || unCount != 3) return; std::vector arPoints(unCount); @@ -2273,8 +2233,6 @@ namespace MetaFile //Оба флага не определены Read_EMFPLUS_DRAWLINES_BASE(unShFlags); // абсолютное расположение с 32-разрядными координатами с плавующей запятой } - - m_bBanEmfProcessing = true; } template @@ -2311,8 +2269,6 @@ namespace MetaFile m_pDC->RemoveBrush(pEmfPlusPen->pBrush); m_pDC->RemovePen(pEmfPlusPen); - - m_bBanEmfProcessing = true; } void CEmfPlusParser::Read_EMFPLUS_DRAWPATH(unsigned short unShFlags) @@ -2335,24 +2291,27 @@ namespace MetaFile if (NULL != pEmfPlusPen->pBrush) m_pDC->SetBrush(pEmfPlusPen->pBrush); - CPathConverter oPathConverter; - CPath oNewPath, oLineCapPath; - - oPathConverter.GetUpdatedPath(oNewPath, oLineCapPath, *pPath, *pEmfPlusPen); + if (NULL != m_pInterpretator) + { + CPathConverter oPathConverter; + CPath oNewPath, oLineCapPath; - oNewPath.DrawOn(m_pInterpretator, true, false); - oLineCapPath.DrawOn(m_pInterpretator, false, true); + oPathConverter.GetUpdatedPath(oNewPath, oLineCapPath, *pPath, *pEmfPlusPen); - if (NULL != m_pInterpretator) - m_pInterpretator->HANDLE_EMFPLUS_DRAWPATH(shOgjectIndex, unPenId, &oNewPath); + if (InterpretatorType::Render == m_pInterpretator->GetType()) + { + oNewPath.DrawOn(m_pInterpretator, true, false); + oLineCapPath.DrawOn(m_pInterpretator, false, true); + } + else + m_pInterpretator->HANDLE_EMFPLUS_DRAWPATH(shOgjectIndex, unPenId, pPath); + } if (NULL != pEmfPlusPen->pBrush) m_pDC->RemoveBrush(pEmfPlusPen->pBrush); m_pDC->RemovePen(pEmfPlusPen); } - - m_bBanEmfProcessing = true; } void CEmfPlusParser::Read_EMFPLUS_DRAWPIE(unsigned short unShFlags) @@ -2361,8 +2320,6 @@ namespace MetaFile Read_EMFPLUS_DRAWPIE_BASE(unShFlags); else Read_EMFPLUS_DRAWPIE_BASE(unShFlags); - - m_bBanEmfProcessing = true; } template @@ -2388,8 +2345,6 @@ namespace MetaFile Read_EMFPLUS_DRAWRECTS_BASE(unShFlags); else Read_EMFPLUS_DRAWRECTS_BASE(unShFlags); - - m_bBanEmfProcessing = true; } template @@ -2444,6 +2399,9 @@ namespace MetaFile if (0 == unLength) return; + if (2 * unLength > m_ulRecordSize - 28) // 28 = 4*3 + 4*4 + unLength = m_ulRecordSize - 28; + m_oStream >> oRect; unsigned short* pString = new unsigned short[unLength + 1]; @@ -2550,8 +2508,6 @@ namespace MetaFile m_pDC->SetTextAlign(unOldTextAlign); m_pDC->RemoveFont(pFont); - - m_bBanEmfProcessing = true; } void CEmfPlusParser::Read_EMFPLUS_FILLCLOSEDCURVE(unsigned short unShFlags) @@ -2571,8 +2527,6 @@ namespace MetaFile //Оба флага не определены Read_EMFPLUS_FILLCLOSEDCURVE_BASE(unShFlags); // абсолютное расположение с 32-разрядными координатами с плавующей запятой } - - m_bBanEmfProcessing = true; } template @@ -2601,8 +2555,6 @@ namespace MetaFile Read_EMFPLUS_FILLELLIPSE_BASE(unShFlags); else Read_EMFPLUS_FILLELLIPSE_BASE(unShFlags); - - m_bBanEmfProcessing = true; } template @@ -2705,8 +2657,6 @@ namespace MetaFile m_pDC->RemoveBrush(pBrush); } - - m_bBanEmfProcessing = true; } void CEmfPlusParser::Read_EMFPLUS_FILLPIE(unsigned short unShFlags) @@ -2715,8 +2665,6 @@ namespace MetaFile Read_EMFPLUS_FILLPIE_BASE(unShFlags); else Read_EMFPLUS_FILLPIE_BASE(unShFlags); - - m_bBanEmfProcessing = true; } template @@ -2754,8 +2702,6 @@ namespace MetaFile //Оба флага не определены Read_EMFPLUS_FILLPOLYGON_BASE(unShFlags); // абсолютное расположение с 32-разрядными координатами с плавующей запятой } - - m_bBanEmfProcessing = true; } template @@ -2829,8 +2775,6 @@ namespace MetaFile Read_EMFPLUS_FILLRECTS_BASE(unShFlags); else Read_EMFPLUS_FILLRECTS_BASE(unShFlags); - - m_bBanEmfProcessing = true; } template @@ -2898,7 +2842,6 @@ namespace MetaFile m_oStream >> unBrushId; //TODO: реализовать - m_bBanEmfProcessing = true; } void CEmfPlusParser::Read_EMFPLUS_OBJECT(unsigned short unShFlags) @@ -2911,7 +2854,7 @@ namespace MetaFile case ObjectTypeInvalid: return; case ObjectTypeBrush: { - LOGGING(L"Object Brush with index: " << shObjectIndex) + PRINT_LOG(L"Object Brush with index: " << shObjectIndex); CEmfPlusBrush *pEmfPlusBrush = ReadBrush(); @@ -2921,7 +2864,7 @@ namespace MetaFile } case ObjectTypePen: { - LOGGING(L"Object Pen with index: " << shObjectIndex) + PRINT_LOG(L"Object Pen with index: " << shObjectIndex); CEmfPlusPen *pEmfPlusPen = ReadPen(); @@ -2931,7 +2874,7 @@ namespace MetaFile } case ObjectTypePath: { - LOGGING(L"Object Path with index: " << shObjectIndex) + PRINT_LOG(L"Object Path with index: " << shObjectIndex); if ((unShFlags >>(15)) & 1) { @@ -2974,7 +2917,7 @@ namespace MetaFile } case ObjectTypeRegion: { - LOGGING(L"Object Region") + PRINT_LOG(L"Object Region"); CEmfPlusRegion *pEmfPlusRegion = ReadRegion(); @@ -2984,13 +2927,14 @@ namespace MetaFile } case ObjectTypeImage: { - LOGGING(L"Object Image") + PRINT_LOG(L"Object Image"); + ReadImage(shObjectIndex, ((unShFlags >>(15)) & 1)); break; } case ObjectTypeFont: { - LOGGING(L"Object Font with index: " << shObjectIndex) + PRINT_LOG(L"Object Font with index: " << shObjectIndex); CEmfPlusFont *pFont = ReadFont(); @@ -3000,7 +2944,7 @@ namespace MetaFile } case ObjectTypeStringFormat: { - LOGGING(L"Object String Format") + PRINT_LOG(L"Object String Format"); CEmfPlusStringFormat *pStringFormat = new CEmfPlusStringFormat; @@ -3012,7 +2956,7 @@ namespace MetaFile } case ObjectTypeImageAttributes: { - LOGGING(L"Object Image Attributes") + PRINT_LOG(L"Object Image Attributes"); CEmfPlusImageAttributes *pImageAttributes = new CEmfPlusImageAttributes(); @@ -3026,10 +2970,14 @@ namespace MetaFile } case ObjectTypeCustomLineCap: { - LOGGING(L"Object Custom Line Cap") + PRINT_LOG(L"Object Custom Line Cap"); break; } - default: return; + default: + { + PRINT_LOG(L"Unknown object type"); + return; + } } //TODO: реализовать } @@ -3201,26 +3149,26 @@ namespace MetaFile void CEmfPlusParser::Read_EMFPLUS_MULTIPLYWORLDTRANSFORM(unsigned short unShFlags) { + m_bBanEmfProcessing = true; + TEmfPlusXForm oMatrix; m_oStream >> oMatrix; m_pDC->MultiplyTransform(oMatrix, (unShFlags & 0x2000) ? MWT_RIGHTMULTIPLY : MWT_LEFTMULTIPLY); - UpdateOutputDC(); - - m_bBanEmfProcessing = true; } void CEmfPlusParser::Read_EMFPLUS_RESETWORLDTRANSFORM() { - m_pDC->ResetTransform(); - UpdateOutputDC(); - m_bBanEmfProcessing = true; + + m_pDC->ResetTransform(); } void CEmfPlusParser::Read_EMFPLUS_ROTATEWORLDTRANSFORM(unsigned short unShFlags) { + m_bBanEmfProcessing = true; + double dAngle; m_oStream >> dAngle; @@ -3233,13 +3181,12 @@ namespace MetaFile TEmfPlusXForm oMatrix(dCosTheta, dSinTheta, -dSinTheta, dCosTheta, 0, 0); m_pDC->MultiplyTransform(oMatrix, (unShFlags & 0x2000) ? MWT_RIGHTMULTIPLY : MWT_LEFTMULTIPLY); - UpdateOutputDC(); - - m_bBanEmfProcessing = true; } void CEmfPlusParser::Read_EMFPLUS_SCALEWORLDTRANSFORM(unsigned short unShFlags) { + m_bBanEmfProcessing = true; + double dSx, dSy; m_oStream >> dSx; @@ -3248,35 +3195,22 @@ namespace MetaFile TEmfPlusXForm oMatrix(dSx, 0, 0, dSy, 0, 0); m_pDC->MultiplyTransform(oMatrix, (unShFlags & 0x2000) ? MWT_RIGHTMULTIPLY : MWT_LEFTMULTIPLY); - UpdateOutputDC(); - - m_bBanEmfProcessing = true; } void CEmfPlusParser::Read_EMFPLUS_SETPAGETRANSFORM(unsigned short unShFlags) { - short shPageUnit = ExpressValue(unShFlags, 0, 7); - - m_oStream >> m_dUnitKoef; + m_bBanEmfProcessing = true; - switch (shPageUnit) - { - case UnitTypePixel: - case UnitTypeWorld: - case UnitTypeDisplay: - default: break; - case UnitTypePoint: m_dUnitKoef *= m_unLogicalDpiX * 72.f; break; - case UnitTypeInch: m_dUnitKoef *= m_unLogicalDpiX; break; - case UnitTypeDocument: m_dUnitKoef *= m_unLogicalDpiX / 300.f; break; - case UnitTypeMillimeter: m_dUnitKoef *= m_unLogicalDpiX / 25.4f; break; - } + short shPageUnit = ExpressValue(unShFlags, 0, 7); + double dUnitKoef; - TXForm oMatrix(m_dUnitKoef, 0, 0, m_dUnitKoef, 0, 0); + m_oStream >> dUnitKoef; - m_pDC->MultiplyTransform(oMatrix, MWT_LEFTMULTIPLY); - UpdateOutputDC(); + m_dPageTransformX = dUnitKoef * GetUnitToPixel(m_unLogicalDpiX, static_cast(shPageUnit)); + m_dPageTransformY = dUnitKoef * GetUnitToPixel(m_unLogicalDpiY, static_cast(shPageUnit)); - m_bBanEmfProcessing = true; + TEmfPlusXForm oUnitKoefMatrix(m_dPageTransformX, 0, 0, m_dPageTransformY, 0, 0); + m_pDC->MultiplyTransform(oUnitKoefMatrix, MWT_LEFTMULTIPLY); } void CEmfPlusParser::Read_EMFPLUS_SETWORLDTRANSFORM() @@ -3285,12 +3219,9 @@ namespace MetaFile m_oStream >> oMatrix; - UpdateMatrix(oMatrix); - m_pDC->MultiplyTransform(oMatrix, MWT_SET); - UpdateOutputDC(); - - m_bBanEmfProcessing = true; + TEmfPlusXForm oUnitKoefMatrix(m_dPageTransformX, 0, 0, m_dPageTransformY, 0, 0); + m_pDC->MultiplyTransform(oUnitKoefMatrix, MWT_LEFTMULTIPLY); } void CEmfPlusParser::Read_EMFPLUS_TRANSLATEWORLDTRANSFORM(unsigned short unShFlags) @@ -3303,9 +3234,6 @@ namespace MetaFile TEmfPlusXForm oMatrix(1, 0, 0, 1, dX, dY); m_pDC->MultiplyTransform(oMatrix, (unShFlags & 0x2000) ? MWT_RIGHTMULTIPLY : MWT_LEFTMULTIPLY); - UpdateOutputDC(); - - m_bBanEmfProcessing = true; } void CEmfPlusParser::Read_EMFPLUS_ENDOFFILE() @@ -3314,7 +3242,6 @@ namespace MetaFile m_pInterpretator->End(); m_bEof = true; - m_bBanEmfProcessing = false; if (NULL != m_pInterpretator) m_pInterpretator->HANDLE_EMFPLUS_ENDOFFILE(); @@ -3330,8 +3257,6 @@ namespace MetaFile void CEmfPlusParser::Read_EMRPLUS_OFFSETCLIP() { - m_bBanEmfProcessing = true; - double dX, dY; m_oStream >> dX; @@ -3345,8 +3270,6 @@ namespace MetaFile void CEmfPlusParser::Read_EMRPLUS_RESETCLIP() { - m_bBanEmfProcessing = true; - m_pDC->GetClip()->Reset(); UpdateOutputDC(); @@ -3356,8 +3279,6 @@ namespace MetaFile void CEmfPlusParser::Read_EMFPLUS_SETCLIPPATH(unsigned short unShFlags) { - m_bBanEmfProcessing = true; - BYTE uchObjectId = ExpressValue(unShFlags, 0, 7); CEmfPlusPath* pPath = GetPath(uchObjectId); @@ -3367,7 +3288,7 @@ namespace MetaFile BYTE uchCM = ExpressValue(unShFlags, 8, 11); m_pDC->GetClip()->Reset(); - m_pDC->GetClip()->SetPath(*pPath, uchCM, *GetTransform()); + m_pDC->GetClip()->SetPath(*pPath, uchCM, GetTransform()); UpdateOutputDC(); if (NULL != m_pInterpretator) @@ -3376,8 +3297,6 @@ namespace MetaFile void CEmfPlusParser::Read_EMFPLUS_SETCLIPRECT(unsigned short unShFlags) { - m_bBanEmfProcessing = true; - short shCM = ExpressValue(unShFlags, 8, 11); TEmfPlusRectF oRect; @@ -3393,8 +3312,6 @@ namespace MetaFile void CEmfPlusParser::Read_EMFPLUS_SETCLIPREGION(unsigned short unShFlags) { - m_bBanEmfProcessing = true; - short shObjectIndex = ExpressValue(unShFlags, 0, 7); short shCM = ExpressValue(unShFlags, 8, 11); @@ -3417,7 +3334,7 @@ namespace MetaFile CEmfPlusRegionNodePath* pNodeRegionPath = (CEmfPlusRegionNodePath*)pNode; if (!pNodeRegionPath->Empty()) - m_pDC->GetClip()->SetPath(*pNodeRegionPath->GetPath(), shCM, *GetTransform()); + m_pDC->GetClip()->SetPath(*pNodeRegionPath->GetPath(), shCM, GetTransform()); break; } @@ -3434,7 +3351,7 @@ namespace MetaFile { CEmfPlusRegionNodeChild* pNodeRegionChild = (CEmfPlusRegionNodeChild*)pNode; - pNodeRegionChild->DrawOnClip(*m_pDC->GetClip(), *GetTransform(), GetDCBounds()); + pNodeRegionChild->DrawOnClip(*m_pDC->GetClip(), GetTransform(), &GetDCBounds()); break; } diff --git a/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfPlusParser.h b/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfPlusParser.h index 26c5eb0fe3d..d78d497131a 100644 --- a/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfPlusParser.h +++ b/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfPlusParser.h @@ -21,13 +21,12 @@ namespace MetaFile void PlayFile() override; void Scan() override; - double GetDpi() override; + USHORT GetDpi() const override; - EmfParserType GetType() override; + EmfParserType GetType() const override; void SetStream(BYTE *pBytes, unsigned int unSize); bool GetBanEMFProcesses(); - private: void RegisterObject(CEmfPlusObject* pObject, unsigned int unIndex); @@ -77,7 +76,8 @@ namespace MetaFile void DrawLines(std::vector arPoints, bool bCloseFigure); void DrawImagePoints(unsigned int unImageIndex, unsigned int unImageAttributeIndex, const TEmfPlusRectF& oSrcRect, const std::vector& arPoints); - void DrawMetafile(BYTE* pBuffer, unsigned int unSize, const TEmfPlusRectF& oSrcRect, const std::vector& arPoints, EEmfPlusMetafileDataType eMetafileType, unsigned int unImageAttributeIndex); + template + void DrawMetafile(BYTE* pBuffer, unsigned int unSize, const TEmfPlusRectF& oSrcRect, const std::vector& arPoints); void DrawBitmap(BYTE* pBuffer, unsigned int unSize, unsigned int unWidth, unsigned int unHeight, const TEmfPlusRectF& oSrcRect, const std::vector& arPoints); TEmfPlusARGB ApplyImageAttributes(TEmfPlusRectF& oRectangle, const CEmfPlusImageAttributes& oImageAttributes); @@ -86,7 +86,7 @@ namespace MetaFile template std::vector GetConvertedPoints(std::vectorarPoints); template TEmfPlusRectF GetConvertedRectangle(T oRectangle); - void UpdateMatrix(TEmfPlusXForm& oMatrix); + double GetUnitToPixel(const double& dDpi, EEmfPlusUnitType eUnitType) const; bool SaveImage(const CEmfPlusImage& oImage, std::wstring& wsPathToImage); @@ -175,7 +175,8 @@ namespace MetaFile unsigned int m_unLogicalDpiX; unsigned int m_unLogicalDpiY; - double m_dUnitKoef; + double m_dPageTransformX; + double m_dPageTransformY; typedef std::map EmfPlusObjects; diff --git a/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfxParser.cpp b/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfxParser.cpp index c15cd619005..cb392e3c685 100644 --- a/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfxParser.cpp +++ b/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfxParser.cpp @@ -301,7 +301,7 @@ namespace MetaFile m_pOutput->MoveToStart(); } - EmfParserType CEmfxParser::GetType() + EmfParserType CEmfxParser::GetType() const { return EmfParserType::EmfxParser; } diff --git a/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfxParser.h b/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfxParser.h index 36cda4ebde4..d67b7219c38 100644 --- a/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfxParser.h +++ b/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfxParser.h @@ -18,7 +18,7 @@ namespace MetaFile void PlayFile() override; void Scan() override; - EmfParserType GetType() override; + EmfParserType GetType() const override; private: bool ReadImage(unsigned int offBmi, unsigned int cbBmi, unsigned int offBits, unsigned int cbBits, unsigned int ulSkip, BYTE **ppBgraBuffer, unsigned int *pulWidth, unsigned int *pulHeight) override; diff --git a/DesktopEditor/raster/Metafile/Emf/EmfPlayer.cpp b/DesktopEditor/raster/Metafile/Emf/EmfPlayer.cpp index 291acd40b46..881e4242cf4 100644 --- a/DesktopEditor/raster/Metafile/Emf/EmfPlayer.cpp +++ b/DesktopEditor/raster/Metafile/Emf/EmfPlayer.cpp @@ -191,6 +191,7 @@ namespace MetaFile case EMF_OBJECT_BRUSH: m_pDC->SetBrush((CEmfLogBrushEx*)pObject); break; case EMF_OBJECT_FONT: m_pDC->SetFont((CEmfLogFont*)pObject); break; case EMF_OBJECT_PEN: m_pDC->SetPen((CEmfLogPen*)pObject); break; + default: break; } } } @@ -222,6 +223,7 @@ namespace MetaFile case EMF_OBJECT_BRUSH: m_pDC->RemoveBrush((CEmfLogBrushEx*)pObject); break; case EMF_OBJECT_FONT: m_pDC->RemoveFont((CEmfLogFont*)pObject); break; case EMF_OBJECT_PEN: m_pDC->RemovePen((CEmfLogPen*)pObject); break; + default: break; } for (std::pair oElement : m_mDCs) @@ -233,6 +235,7 @@ namespace MetaFile case EMF_OBJECT_BRUSH: pDC->RemoveBrush((CEmfLogBrushEx*)pObject); break; case EMF_OBJECT_FONT: pDC->RemoveFont((CEmfLogFont*)pObject); break; case EMF_OBJECT_PEN: pDC->RemovePen((CEmfLogPen*)pObject); break; + default: break; } } @@ -435,7 +438,7 @@ namespace MetaFile UpdateFinalTransform(); } - unsigned int CEmfDC::GetMapMode() + unsigned int CEmfDC::GetMapMode() const { return m_ulMapMode; } @@ -445,20 +448,20 @@ namespace MetaFile m_oTransform.Init(); UpdateFinalTransform(); } - TEmfXForm* CEmfDC::GetTransform() + const TEmfXForm& CEmfDC::GetTransform() const { - return &m_oTransform; + return m_oTransform; } - TEmfXForm* CEmfDC::GetInverseTransform() + const TEmfXForm& CEmfDC::GetInverseTransform() const { - return &m_oInverseTransform; + return m_oInverseTransform; } - TEmfXForm* CEmfDC::GetFinalTransform(int iGraphicsMode) + const TEmfXForm& CEmfDC::GetFinalTransform(int iGraphicsMode) const { if (GM_COMPATIBLE == iGraphicsMode) - return &m_oFinalTransform2; + return m_oFinalTransform2; - return &m_oFinalTransform; + return m_oFinalTransform; } void CEmfDC::MultiplyTransform(TEmfXForm& oForm, unsigned int ulMode) { @@ -466,8 +469,8 @@ namespace MetaFile // Обновляем обратную матрицу TEmfXForm* pT = &m_oTransform; - double dDet = pT->M11 * pT->M22 - pT->M12 * pT->M21; - if (dDet < 0.0001 && dDet > 0.0001) + const double dDet = pT->M11 * pT->M22 - pT->M12 * pT->M21; + if (Equals(0., dDet, 0.0001)) { m_oInverseTransform.M11 = 1; m_oInverseTransform.M12 = 0; @@ -476,21 +479,23 @@ namespace MetaFile m_oInverseTransform.Dx = 0; m_oInverseTransform.Dy = 0; } - - m_oInverseTransform.M11 = pT->M22 / dDet; - m_oInverseTransform.M12 = -pT->M12 / dDet; - m_oInverseTransform.M21 = -pT->M21 / dDet; - m_oInverseTransform.M22 = pT->M22 / dDet; - m_oInverseTransform.Dx = pT->Dy * pT->M21 / dDet - pT->Dx * pT->M22 / dDet; - m_oInverseTransform.Dy = pT->Dx * pT->M12 / dDet - pT->Dy * pT->M11 / dDet; + else + { + m_oInverseTransform.M11 = pT->M22 / dDet; + m_oInverseTransform.M12 = -pT->M12 / dDet; + m_oInverseTransform.M21 = -pT->M21 / dDet; + m_oInverseTransform.M22 = pT->M22 / dDet; + m_oInverseTransform.Dx = pT->Dy * pT->M21 / dDet - pT->Dx * pT->M22 / dDet; + m_oInverseTransform.Dy = pT->Dx * pT->M12 / dDet - pT->Dy * pT->M11 / dDet; + } UpdateFinalTransform(); } - void CEmfDC::SetTextColor(TRGBA& oColor) + void CEmfDC::SetTextColor(const TRGBA& oColor) { m_oTextColor.Copy(oColor); } - TRGBA& CEmfDC::GetTextColor() + const TRGBA& CEmfDC::GetTextColor() const { return m_oTextColor; } @@ -503,7 +508,7 @@ namespace MetaFile if (pBrush == m_pBrush) m_pBrush = NULL; } - IBrush* CEmfDC::GetBrush() + const IBrush* CEmfDC::GetBrush() const { return m_pBrush; } @@ -516,7 +521,7 @@ namespace MetaFile if (pFont == m_pFont) m_pFont = NULL; } - IFont* CEmfDC::GetFont() + const IFont* CEmfDC::GetFont() const { return (NULL != m_pFont) ? m_pFont : &m_oDefaultFont; } @@ -524,7 +529,7 @@ namespace MetaFile { m_ulTextAlign = ulAlign; } - unsigned int CEmfDC::GetTextAlign() + unsigned int CEmfDC::GetTextAlign() const { return m_ulTextAlign; } @@ -532,7 +537,7 @@ namespace MetaFile { m_ulBgMode = ulBgMode; } - unsigned int CEmfDC::GetBgMode() + unsigned int CEmfDC::GetBgMode() const { return m_ulBgMode; } @@ -540,15 +545,15 @@ namespace MetaFile { m_oBgColor.Copy(oColor); } - TRGBA& CEmfDC::GetBgColor() + const TRGBA* CEmfDC::GetBgColor() const { - return m_oBgColor; + return &m_oBgColor; } void CEmfDC::SetMiterLimit(unsigned int ulMiter) { m_ulMiterLimit = ulMiter; } - unsigned int CEmfDC::GetMiterLimit() + unsigned int CEmfDC::GetMiterLimit() const { return m_ulMiterLimit; } @@ -556,7 +561,7 @@ namespace MetaFile { m_ulFillMode = ulFillMode; } - unsigned int CEmfDC::GetFillMode() + unsigned int CEmfDC::GetFillMode() const { return m_ulFillMode; } @@ -569,7 +574,7 @@ namespace MetaFile if (pPen == m_pPen) m_pPen = NULL; } - IPen* CEmfDC::GetPen() + const IPen* CEmfDC::GetPen() const { return m_pPen; } @@ -577,15 +582,15 @@ namespace MetaFile { m_ulStretchMode = oMode; } - unsigned int CEmfDC::GetStretchMode() + unsigned int CEmfDC::GetStretchMode() const { return m_ulStretchMode; } - double CEmfDC::GetPixelWidth() + double CEmfDC::GetPixelWidth() const { return m_dPixelWidth; } - double CEmfDC::GetPixelHeight() + double CEmfDC::GetPixelHeight() const { return m_dPixelHeight; } @@ -597,14 +602,14 @@ namespace MetaFile { m_dPixelHeight = dPixelH; } - void CEmfDC::SetWindowOrigin(TPointL& oPoint) + void CEmfDC::SetWindowOrigin(const TPointL& oPoint) { m_oWindow.lX = oPoint.X; m_oWindow.lY = oPoint.Y; UpdatePixelMetrics(); UpdateFinalTransform(); } - void CEmfDC::SetWindowExtents(TSizeL& oPoint) + void CEmfDC::SetWindowExtents(const TSizeL& oPoint) { m_oWindow.ulW = oPoint.X; m_oWindow.ulH = oPoint.Y; @@ -622,7 +627,7 @@ namespace MetaFile UpdateFinalTransform(); } - void CEmfDC::ScaleWindow(double dXScale, double dYScale) + void CEmfDC::ScaleWindow(const double& dXScale, const double& dYScale) { m_oWindow.ulW = (int)(m_oWindow.ulW * dXScale); m_oWindow.ulH = (int)(m_oWindow.ulH * dYScale); @@ -634,18 +639,18 @@ namespace MetaFile UpdateFinalTransform(); } - TEmfWindow* CEmfDC::GetWindow() + const TEmfWindow& CEmfDC::GetWindow() const { - return &m_oWindow; + return m_oWindow; } - void CEmfDC::SetViewportOrigin(TPointL& oPoint) + void CEmfDC::SetViewportOrigin(const TPointL& oPoint) { m_oViewport.lX = oPoint.X; m_oViewport.lY = oPoint.Y; UpdatePixelMetrics(); UpdateFinalTransform(); } - void CEmfDC::SetViewportExtents(TSizeL& oPoint) + void CEmfDC::SetViewportExtents(const TSizeL& oPoint) { m_oViewport.ulW = oPoint.X; m_oViewport.ulH = oPoint.Y; @@ -663,7 +668,7 @@ namespace MetaFile UpdateFinalTransform(); } - void CEmfDC::ScaleViewport(double dXScale, double dYScale) + void CEmfDC::ScaleViewport(const double& dXScale, const double& dYScale) { m_oViewport.ulW = (int)(m_oViewport.ulW * dXScale); m_oViewport.ulH = (int)(m_oViewport.ulH * dYScale); @@ -675,9 +680,9 @@ namespace MetaFile UpdateFinalTransform(); } - TEmfWindow* CEmfDC::GetViewport() + const TEmfWindow& CEmfDC::GetViewport() const { - return &m_oViewport; + return m_oViewport; } bool CEmfDC::UpdatePixelMetrics() { @@ -708,23 +713,23 @@ namespace MetaFile } void CEmfDC::UpdateFinalTransform() { - TEmfWindow* pWindow = GetWindow(); - TEmfWindow* pViewPort = GetViewport(); + const TEmfWindow& oWindow{GetWindow()}; + const TEmfWindow& oViewPort{GetViewport()}; - double dM11 = (pViewPort->ulW >= 0) ? 1 : -1; - double dM22 = (pViewPort->ulH >= 0) ? 1 : -1; + double dM11 = ((oViewPort.ulW >= 0) ? 1. : -1.) * GetPixelWidth(); + double dM22 = ((oViewPort.ulH >= 0) ? 1. : -1.) * GetPixelHeight(); - TEmfXForm oWindowXForm(1, 0, 0, 1, -(pWindow->lX * GetPixelWidth() * dM11), -(pWindow->lY * GetPixelHeight() * dM22)); - TEmfXForm oViewportXForm(GetPixelWidth() * dM11, 0, 0, GetPixelHeight() * dM22, pViewPort->lX, pViewPort->lY); + TEmfXForm oWindowXForm(1, 0, 0, 1, -(oWindow.lX * dM11), -(oWindow.lY * dM22)); + TEmfXForm oViewportXForm(dM11, 0, 0, dM22, oViewPort.lX, oViewPort.lY); m_oFinalTransform.Init(); - m_oFinalTransform.Multiply(oViewportXForm, MWT_RIGHTMULTIPLY); m_oFinalTransform.Multiply(m_oTransform, MWT_RIGHTMULTIPLY); + m_oFinalTransform.Multiply(oViewportXForm, MWT_RIGHTMULTIPLY); m_oFinalTransform.Multiply(oWindowXForm, MWT_RIGHTMULTIPLY); m_oFinalTransform2.Init(); + // m_oFinalTransform2.Multiply(m_oTransform, MWT_RIGHTMULTIPLY); m_oFinalTransform2.Multiply(oViewportXForm, MWT_RIGHTMULTIPLY); - m_oFinalTransform2.Multiply(m_oTransform, MWT_RIGHTMULTIPLY); m_oFinalTransform2.Multiply(oWindowXForm, MWT_RIGHTMULTIPLY); } @@ -746,11 +751,11 @@ namespace MetaFile if (!m_oViewport.ulH) m_oViewport.ulH = nMinCy; } } - void CEmfDC::SetRop2Mode(unsigned int& nMode) + void CEmfDC::SetRop2Mode(unsigned int nMode) { m_ulRop2Mode = nMode; } - unsigned int CEmfDC::GetRop2Mode() + unsigned int CEmfDC::GetRop2Mode() const { return m_ulRop2Mode; } @@ -763,11 +768,11 @@ namespace MetaFile if (m_pPalette == pPalette) m_pPalette = NULL; } - CEmfLogPalette* CEmfDC::GetPalette() + const CEmfLogPalette* CEmfDC::GetPalette() const { return m_pPalette; } - void CEmfDC::SetCurPos(TPointL& oPoint) + void CEmfDC::SetCurPos(const TPointL& oPoint) { SetCurPos(oPoint.X, oPoint.Y); } @@ -776,7 +781,7 @@ namespace MetaFile m_oCurPos.X = lX; m_oCurPos.Y = lY; } - TPointL& CEmfDC::GetCurPos() + const TPointL& CEmfDC::GetCurPos() const { return m_oCurPos; } @@ -784,7 +789,7 @@ namespace MetaFile { m_unArcDirection = unDirection; } - unsigned int CEmfDC::GetArcDirection() + unsigned int CEmfDC::GetArcDirection() const { return m_unArcDirection; } diff --git a/DesktopEditor/raster/Metafile/Emf/EmfPlayer.h b/DesktopEditor/raster/Metafile/Emf/EmfPlayer.h index 1159d4deaaa..081ee385ee8 100644 --- a/DesktopEditor/raster/Metafile/Emf/EmfPlayer.h +++ b/DesktopEditor/raster/Metafile/Emf/EmfPlayer.h @@ -89,56 +89,56 @@ namespace MetaFile CClip* GetClip(); - void SetMapMode(unsigned int ulMapMode); - unsigned int GetMapMode(); - void ResetTransform(); - TEmfXForm* GetTransform(); - TEmfXForm* GetInverseTransform(); - TEmfXForm* GetFinalTransform(int iGraphicsMode); - void MultiplyTransform(TEmfXForm& oForm, unsigned int ulMode); - void SetTextColor(TRGBA& oColor); - TRGBA& GetTextColor(); - void SetBrush(IBrush* pBrush); - void RemoveBrush(IBrush* pBrush); - IBrush* GetBrush(); - void SetFont(IFont* pFont); - void RemoveFont(IFont* pFont); - IFont* GetFont(); - void SetTextAlign(unsigned int ulAlign); - unsigned int GetTextAlign(); - void SetBgMode(unsigned int ulBgMode); - unsigned int GetBgMode(); - void SetBgColor(TRGBA& oColor); - TRGBA& GetBgColor(); - void SetMiterLimit(unsigned int ulMiter); - unsigned int GetMiterLimit(); - void SetFillMode(unsigned int ulFillMode); - unsigned int GetFillMode(); - void SetPen(IPen* pPen); - void RemovePen(IPen* pPen); - IPen* GetPen(); - void SetStretchMode(unsigned int& oMode); - unsigned int GetStretchMode(); - double GetPixelWidth(); - double GetPixelHeight(); - void SetWindowOrigin(TPointL& oPoint); - void SetWindowExtents(TSizeL& oPoint); - void ScaleWindow(double dXScale, double dYScale); - TEmfWindow* GetWindow(); - void SetViewportOrigin(TPointL& oPoint); - void SetViewportExtents(TSizeL& oPoint); - void ScaleViewport(double dXScale, double dYScale); - TEmfWindow* GetViewport(); - void SetRop2Mode(unsigned int& nMode); - unsigned int GetRop2Mode(); - void SetPalette(CEmfLogPalette* pPalette); - void RemovePalette(CEmfLogPalette* pPalette); - CEmfLogPalette* GetPalette(); - void SetCurPos(TPointL& oPoint); - void SetCurPos(int lX, int lY); - TPointL& GetCurPos(); - void SetArcDirection(unsigned int unDirection); - unsigned int GetArcDirection(); + void SetMapMode(unsigned int ulMapMode); + unsigned int GetMapMode() const; + void ResetTransform(); + const TEmfXForm& GetTransform() const; + const TEmfXForm& GetInverseTransform() const ; + const TEmfXForm& GetFinalTransform(int iGraphicsMode) const; + void MultiplyTransform(TEmfXForm& oForm, unsigned int ulMode); + void SetTextColor(const TRGBA& oColor); + const TRGBA& GetTextColor() const; + void SetBrush(IBrush* pBrush); + void RemoveBrush(IBrush* pBrush); + const IBrush* GetBrush() const; + void SetFont(IFont* pFont); + void RemoveFont(IFont* pFont); + const IFont* GetFont() const; + void SetTextAlign(unsigned int ulAlign); + unsigned int GetTextAlign() const; + void SetBgMode(unsigned int ulBgMode); + unsigned int GetBgMode() const; + void SetBgColor(TRGBA& oColor); + const TRGBA* GetBgColor() const; + void SetMiterLimit(unsigned int ulMiter); + unsigned int GetMiterLimit() const; + void SetFillMode(unsigned int ulFillMode); + unsigned int GetFillMode() const; + void SetPen(IPen* pPen); + void RemovePen(IPen* pPen); + const IPen* GetPen() const; + void SetStretchMode(unsigned int& oMode); + unsigned int GetStretchMode() const; + double GetPixelWidth() const; + double GetPixelHeight() const; + void SetWindowOrigin(const TPointL& oPoint); + void SetWindowExtents(const TSizeL& oPoint); + void ScaleWindow(const double& dXScale, const double& dYScale); + const TEmfWindow& GetWindow() const; + void SetViewportOrigin(const TPointL& oPoint); + void SetViewportExtents(const TSizeL& oPoint); + void ScaleViewport(const double& dXScale, const double& dYScale); + const TEmfWindow& GetViewport() const; + void SetRop2Mode(unsigned int nMode); + unsigned int GetRop2Mode() const; + void SetPalette(CEmfLogPalette* pPalette); + void RemovePalette(CEmfLogPalette* pPalette); + const CEmfLogPalette* GetPalette() const; + void SetCurPos(const TPointL& oPoint); + void SetCurPos(int lX, int lY); + const TPointL& GetCurPos() const; + void SetArcDirection(unsigned int unDirection); + unsigned int GetArcDirection() const; private: diff --git a/DesktopEditor/raster/Metafile/Emf/EmfPlusObjects.cpp b/DesktopEditor/raster/Metafile/Emf/EmfPlusObjects.cpp index 5f55b3b72d2..13b17d54ffb 100644 --- a/DesktopEditor/raster/Metafile/Emf/EmfPlusObjects.cpp +++ b/DesktopEditor/raster/Metafile/Emf/EmfPlusObjects.cpp @@ -12,66 +12,66 @@ namespace MetaFile NSFile::CFileBinary::Remove(wsDibPatternPath); } - EEmfObjectType CEmfPlusBrush::GetType() + EEmfObjectType CEmfPlusBrush::GetType() const { return EMF_OBJECT_BRUSH; } - EEmfPlusObjectType CEmfPlusBrush::GetObjectType() + EEmfPlusObjectType CEmfPlusBrush::GetObjectType() const { return ObjectTypeBrush; } - int CEmfPlusBrush::GetColor() + int CEmfPlusBrush::GetColor() const { return METAFILE_RGBA(oColor.chRed, oColor.chGreen, oColor.chBlue, 0); } - int CEmfPlusBrush::GetColor2() + int CEmfPlusBrush::GetColor2() const { return METAFILE_RGBA(oColorBack.chRed, oColorBack.chGreen, oColorBack.chBlue, 0); } - unsigned int CEmfPlusBrush::GetStyle() + unsigned int CEmfPlusBrush::GetStyle() const { return unStyle; } - unsigned int CEmfPlusBrush::GetStyleEx() + unsigned int CEmfPlusBrush::GetStyleEx() const { return unAngle; } - unsigned int CEmfPlusBrush::GetHatch() + unsigned int CEmfPlusBrush::GetHatch() const { return unHatch; } - unsigned int CEmfPlusBrush::GetAlpha() + unsigned int CEmfPlusBrush::GetAlpha() const { return oColor.chAlpha; } - unsigned int CEmfPlusBrush::GetAlpha2() + unsigned int CEmfPlusBrush::GetAlpha2() const { return oColorBack.chAlpha; } - std::wstring CEmfPlusBrush::GetDibPatterPath() + std::wstring CEmfPlusBrush::GetDibPatterPath() const { return wsDibPatternPath; } - void CEmfPlusBrush::GetDibPattern(unsigned char **pBuffer, unsigned int &unWidth, unsigned int &unHeight) + void CEmfPlusBrush::GetDibPattern(unsigned char **pBuffer, unsigned int &unWidth, unsigned int &unHeight) const {} - void CEmfPlusBrush::GetCenterPoint(double &dX, double &dY) + void CEmfPlusBrush::GetCenterPoint(double &dX, double &dY) const { dX = oCenterPoint.X; dY = oCenterPoint.Y; } - void CEmfPlusBrush::GetBounds(double &left, double &top, double &width, double &height) + void CEmfPlusBrush::GetBounds(double &left, double &top, double &width, double &height) const { left = oRectF.dX; top = oRectF.dY; @@ -79,8 +79,28 @@ namespace MetaFile height = oRectF.dHeight; } + void CEmfPlusBrush::GetGradientColors(std::vector& arColors, std::vector& arPositions) const + { + if (arGradientColors.empty()) + { + arColors = {(long)(GetColor() + (GetAlpha() << 24)), (long)(GetColor2() + (GetAlpha2() << 24))}; + arPositions = {0., 1.}; + + return; + } + + arColors.resize(arGradientColors.size()); + arPositions.resize(arGradientColors.size()); + + for (unsigned int unIndex = 0; unIndex < arGradientColors.size(); ++unIndex) + { + arColors[unIndex] = METAFILE_RGBA(arGradientColors[unIndex].first.chRed, arGradientColors[unIndex].first.chGreen, arGradientColors[unIndex].first.chBlue, arGradientColors[unIndex].first.chAlpha); + arPositions[unIndex] = arGradientColors[unIndex].second; + } + } + CEmfPlusPen::CEmfPlusPen() - : unStyle(PS_SOLID), dWidth(1), oColor(0, 0, 0), + : unStyle(PS_SOLID | PS_GEOMETRIC | PS_STARTCAP_FLAT | PS_ENDCAP_FLAT | PS_JOIN_MITER), dWidth(1), oColor(0, 0, 0), pBrush(NULL), dMiterLimit(0), dDashOffset(0), pDataDash(NULL), unSizeDash(0), pLineStartCapData(NULL), pLineEndCapData(NULL) {} @@ -90,20 +110,20 @@ namespace MetaFile RELEASEOBJECT(pBrush) RELEASEARRAYOBJECTS(pDataDash) RELEASEOBJECT(pLineStartCapData) - RELEASEOBJECT(pLineEndCapData) + RELEASEOBJECT(pLineEndCapData) } - EEmfObjectType CEmfPlusPen::GetType() + EEmfObjectType CEmfPlusPen::GetType() const { return EMF_OBJECT_PEN; } - EEmfPlusObjectType CEmfPlusPen::GetObjectType() + EEmfPlusObjectType CEmfPlusPen::GetObjectType() const { return ObjectTypePen; } - int CEmfPlusPen::GetColor() + int CEmfPlusPen::GetColor() const { if (NULL != pBrush) return pBrush->GetColor(); @@ -111,12 +131,12 @@ namespace MetaFile return METAFILE_RGBA(oColor.chRed, oColor.chGreen, oColor.chBlue, 0); } - unsigned int CEmfPlusPen::GetStyle() + unsigned int CEmfPlusPen::GetStyle() const { return unStyle; } - double CEmfPlusPen::GetWidth() + double CEmfPlusPen::GetWidth() const { // if (dWidth < 0) // return 1; @@ -124,7 +144,7 @@ namespace MetaFile return dWidth; } - unsigned int CEmfPlusPen::GetAlpha() + unsigned int CEmfPlusPen::GetAlpha() const { if (NULL != pBrush) return pBrush->oColor.chAlpha; @@ -132,22 +152,32 @@ namespace MetaFile return 0xff; } - double CEmfPlusPen::GetMiterLimit() + double CEmfPlusPen::GetMiterLimit() const { return dMiterLimit; } - double CEmfPlusPen::GetDashOffset() + double CEmfPlusPen::GetDashOffset() const { return dDashOffset; } - void CEmfPlusPen::GetDashData(double *&arDatas, unsigned int &unSize) + void CEmfPlusPen::GetDashData(double *&arDatas, unsigned int &unSize) const { arDatas = pDataDash; unSize = unSizeDash; } + const ILineCap* CEmfPlusPen::GetStartLineCap() const + { + return pLineStartCapData; + } + + const ILineCap* CEmfPlusPen::GetEndLineCap() const + { + return pLineEndCapData; + } + CEmfPlusFont::CEmfPlusFont() : m_dEmSize(18), m_unSizeUnit(0), m_bBold(false), m_bItalic(false), m_bUnderline(false), m_bStrikeout(false), @@ -157,57 +187,57 @@ namespace MetaFile CEmfPlusFont::~CEmfPlusFont() {} - EEmfObjectType CEmfPlusFont::GetType() + EEmfObjectType CEmfPlusFont::GetType() const { return EMF_OBJECT_FONT; } - EEmfPlusObjectType CEmfPlusFont::GetObjectType() + EEmfPlusObjectType CEmfPlusFont::GetObjectType() const { return ObjectTypeFont; } - double CEmfPlusFont::GetHeight() + double CEmfPlusFont::GetHeight() const { return m_dEmSize; } - std::wstring CEmfPlusFont::GetFaceName() + std::wstring CEmfPlusFont::GetFaceName() const { return m_wsFamilyName; } - int CEmfPlusFont::GetWeight() + int CEmfPlusFont::GetWeight() const { return (m_bBold) ? 700 : 400; } - bool CEmfPlusFont::IsItalic() + bool CEmfPlusFont::IsItalic() const { return m_bItalic; } - bool CEmfPlusFont::IsStrikeOut() + bool CEmfPlusFont::IsStrikeOut() const { return m_bStrikeout; } - bool CEmfPlusFont::IsUnderline() + bool CEmfPlusFont::IsUnderline() const { return m_bUnderline; } - int CEmfPlusFont::GetEscapement() + int CEmfPlusFont::GetEscapement() const { return 0; } - int CEmfPlusFont::GetCharSet() + int CEmfPlusFont::GetCharSet() const { return 0; } - int CEmfPlusFont::GetOrientation() + int CEmfPlusFont::GetOrientation() const { return 0; } @@ -221,7 +251,7 @@ namespace MetaFile RELEASEOBJECT(m_pBuffer) } - EEmfPlusObjectType CEmfPlusBuffer::GetObjectType() + EEmfPlusObjectType CEmfPlusBuffer::GetObjectType() const { return ObjectTypeBuffer; } @@ -271,7 +301,12 @@ namespace MetaFile CEmfPlusPath::CEmfPlusPath(CEmfPlusPath *pPath) : CEmfPlusObject(), CPath(*pPath) {} - EEmfPlusObjectType CEmfPlusPath::GetObjectType() + CEmfPlusPath::~CEmfPlusPath() + { + Clear(); + } + + EEmfPlusObjectType CEmfPlusPath::GetObjectType() const { return ObjectTypePath; } @@ -323,7 +358,7 @@ namespace MetaFile CEmfPlusImageAttributes::CEmfPlusImageAttributes() : CEmfPlusObject() {} - EEmfPlusObjectType CEmfPlusImageAttributes::GetObjectType() + EEmfPlusObjectType CEmfPlusImageAttributes::GetObjectType() const { return ObjectTypeImageAttributes; } @@ -334,7 +369,7 @@ namespace MetaFile m_unWidth(0), m_unHeight(0) {} - EEmfPlusObjectType CEmfPlusImage::GetObjectType() + EEmfPlusObjectType CEmfPlusImage::GetObjectType() const { return ObjectTypeImage; } @@ -406,7 +441,7 @@ namespace MetaFile RELEASEOBJECT(pPath); } - EEmfPLusRegionNodeType CEmfPlusRegionNodePath::GetNodeType() + EEmfPLusRegionNodeType CEmfPlusRegionNodePath::GetNodeType() const { return EmfPLusRegionNodeTypePath; } @@ -429,7 +464,7 @@ namespace MetaFile RELEASEOBJECT(pRect); } - EEmfPLusRegionNodeType CEmfPlusRegionNodeRectF::GetNodeType() + EEmfPLusRegionNodeType CEmfPlusRegionNodeRectF::GetNodeType() const { return EmfPLusRegionNodeTypeRectF; } @@ -453,12 +488,12 @@ namespace MetaFile RELEASEOBJECT(pRigth); } - EEmfPLusRegionNodeType CEmfPlusRegionNodeChild::GetNodeType() + EEmfPLusRegionNodeType CEmfPlusRegionNodeChild::GetNodeType() const { return EmfPLusRegionNodeTypeChild; } - void CEmfPlusRegionNodeChild::DrawOnClip(CClip &oClip, const TXForm &oTransform, TRectL *pOutRect) + void CEmfPlusRegionNodeChild::DrawOnClip(CClip &oClip, const TXForm &oTransform, const TRectL *pOutRect) { unsigned int unType; @@ -545,7 +580,7 @@ namespace MetaFile arNodes.clear(); } - EEmfPlusObjectType CEmfPlusRegion::GetObjectType() + EEmfPlusObjectType CEmfPlusRegion::GetObjectType() const { return ObjectTypeRegion; } @@ -553,8 +588,16 @@ namespace MetaFile CEmfPlusStringFormat::CEmfPlusStringFormat() : CEmfPlusObject() {} - EEmfPlusObjectType CEmfPlusStringFormat::GetObjectType() + EEmfPlusObjectType CEmfPlusStringFormat::GetObjectType() const { return ObjectTypeStringFormat; } } + +namespace MetaFile +{ + TEmfPlusCustomLineCapData::~TEmfPlusCustomLineCapData() + { + RELEASEOBJECT(pPath); + } +} diff --git a/DesktopEditor/raster/Metafile/Emf/EmfPlusObjects.h b/DesktopEditor/raster/Metafile/Emf/EmfPlusObjects.h index 6f1068dce5b..3b61cd0f4bf 100644 --- a/DesktopEditor/raster/Metafile/Emf/EmfPlusObjects.h +++ b/DesktopEditor/raster/Metafile/Emf/EmfPlusObjects.h @@ -93,7 +93,7 @@ namespace MetaFile CEmfPlusObject(){}; virtual ~CEmfPlusObject(){}; - virtual EEmfPlusObjectType GetObjectType() + virtual EEmfPlusObjectType GetObjectType() const { return ObjectTypeInvalid; } @@ -173,22 +173,23 @@ namespace MetaFile public: CEmfPlusBrush(); virtual ~CEmfPlusBrush(); - virtual EEmfObjectType GetType(); - virtual EEmfPlusObjectType GetObjectType(); + virtual EEmfObjectType GetType() const override; + virtual EEmfPlusObjectType GetObjectType() const override; // IBrush - int GetColor(); - int GetColor2(); - unsigned int GetStyle(); - unsigned int GetStyleEx(); - unsigned int GetHatch(); - unsigned int GetAlpha(); - unsigned int GetAlpha2(); - std::wstring GetDibPatterPath(); - void GetDibPattern(unsigned char** pBuffer, unsigned int &unWidth, unsigned int &unHeight); - void GetCenterPoint(double& dX, double& dY); - void GetBounds(double& left, double& top, double& width, double& height); - + int GetColor() const override; + int GetColor2() const override; + unsigned int GetStyle() const override; + unsigned int GetStyleEx() const override; + unsigned int GetHatch() const override; + unsigned int GetAlpha() const override; + unsigned int GetAlpha2() const override; + std::wstring GetDibPatterPath() const override; + void GetDibPattern(unsigned char** pBuffer, unsigned int &unWidth, unsigned int &unHeight) const override; + void GetCenterPoint(double& dX, double& dY) const override; + void GetBounds(double& left, double& top, double& width, double& height) const override; + + void GetGradientColors(std::vector& arColors, std::vector& arPositions) const override; public: TEmfPlusARGB oColor; TEmfPlusARGB oColorBack; @@ -198,6 +199,8 @@ namespace MetaFile TEmfPlusPointF oCenterPoint; unsigned int unAngle; std::wstring wsDibPatternPath; + + std::vector> arGradientColors; }; class CEmfPlusPen: public CEmfPlusObject, public IPen @@ -205,18 +208,19 @@ namespace MetaFile public: CEmfPlusPen(); virtual ~CEmfPlusPen(); - virtual EEmfObjectType GetType(); - virtual EEmfPlusObjectType GetObjectType(); + virtual EEmfObjectType GetType() const override; + virtual EEmfPlusObjectType GetObjectType() const override; // IPen - int GetColor(); - unsigned int GetStyle(); - double GetWidth(); - unsigned int GetAlpha(); - double GetMiterLimit(); - double GetDashOffset(); - void GetDashData(double*& arDatas, unsigned int& unSize); - + int GetColor() const override; + unsigned int GetStyle() const override; + double GetWidth() const override; + unsigned int GetAlpha() const override; + double GetMiterLimit() const override; + double GetDashOffset() const override; + void GetDashData(double*& arDatas, unsigned int& unSize) const override; + const ILineCap* GetStartLineCap() const override; + const ILineCap* GetEndLineCap() const override; public: unsigned int unStyle; double dWidth; @@ -236,19 +240,19 @@ namespace MetaFile public: CEmfPlusFont(); virtual ~CEmfPlusFont(); - virtual EEmfObjectType GetType(); - virtual EEmfPlusObjectType GetObjectType(); + virtual EEmfObjectType GetType() const override; + virtual EEmfPlusObjectType GetObjectType() const override; // IFont - double GetHeight(); - std::wstring GetFaceName(); - int GetWeight(); - bool IsItalic(); - bool IsStrikeOut(); - bool IsUnderline(); - int GetEscapement(); - int GetCharSet(); - int GetOrientation(); + double GetHeight() const override; + std::wstring GetFaceName() const override; + int GetWeight() const override; + bool IsItalic() const override; + bool IsStrikeOut() const override; + bool IsUnderline() const override; + int GetEscapement() const override; + int GetCharSet() const override; + int GetOrientation() const override; public: double m_dEmSize; @@ -272,7 +276,7 @@ namespace MetaFile public: CEmfPlusBuffer(); virtual ~CEmfPlusBuffer(); - virtual EEmfPlusObjectType GetObjectType(); + virtual EEmfPlusObjectType GetObjectType() const override; void SetSize(unsigned int unSize); unsigned int GetSize() const; @@ -292,7 +296,8 @@ namespace MetaFile public: CEmfPlusPath(); CEmfPlusPath(CEmfPlusPath* pPath); - virtual EEmfPlusObjectType GetObjectType() override; + virtual ~CEmfPlusPath(); + virtual EEmfPlusObjectType GetObjectType() const override; TRectD GetBounds() const; }; @@ -310,7 +315,7 @@ namespace MetaFile { public: CEmfPlusImageAttributes(); - virtual EEmfPlusObjectType GetObjectType() override; + virtual EEmfPlusObjectType GetObjectType() const override; public: EEmfPlusWrapMode eWrapMode; @@ -328,7 +333,7 @@ namespace MetaFile { public: CEmfPlusImage(); - virtual EEmfPlusObjectType GetObjectType() override; + virtual EEmfPlusObjectType GetObjectType() const override; void SetImageDataType(unsigned int unImageDataType); EEmfPlusImageDataType GetImageDataType() const; @@ -373,8 +378,8 @@ namespace MetaFile CEmfPlusRegionNode(); virtual ~CEmfPlusRegionNode(); - EEmfPlusRegionNodeDataType GetType() const; - EEmfPLusRegionNodeType GetNodeType() const; + virtual EEmfPlusRegionNodeDataType GetType() const; + virtual EEmfPLusRegionNodeType GetNodeType() const; public: EEmfPlusRegionNodeDataType eType; @@ -386,7 +391,7 @@ namespace MetaFile CEmfPlusRegionNodePath(); virtual ~CEmfPlusRegionNodePath(); - EEmfPLusRegionNodeType GetNodeType(); + EEmfPLusRegionNodeType GetNodeType() const override; bool Empty() const; CEmfPlusPath* GetPath() const; @@ -401,9 +406,9 @@ namespace MetaFile CEmfPlusRegionNodeRectF(); virtual ~CEmfPlusRegionNodeRectF(); - EEmfPLusRegionNodeType GetNodeType(); + EEmfPLusRegionNodeType GetNodeType() const override; - bool Empty() const; + bool Empty() const; TEmfPlusRectF* GetRect() const; public: @@ -416,9 +421,9 @@ namespace MetaFile CEmfPlusRegionNodeChild(); virtual ~CEmfPlusRegionNodeChild(); - EEmfPLusRegionNodeType GetNodeType(); + EEmfPLusRegionNodeType GetNodeType() const override; - void DrawOnClip(CClip& oClip, const TXForm& oTransform, TRectL *pOutRect = NULL); + void DrawOnClip(CClip& oClip, const TXForm& oTransform, const TRectL* pOutRect = NULL); public: CEmfPlusRegionNode *pLeft, *pRigth; }; @@ -429,7 +434,7 @@ namespace MetaFile CEmfPlusRegion(); virtual ~CEmfPlusRegion(); - virtual EEmfPlusObjectType GetObjectType() override; + virtual EEmfPlusObjectType GetObjectType() const override; public: std::vector arNodes; @@ -464,7 +469,7 @@ namespace MetaFile { public: CEmfPlusStringFormat(); - virtual EEmfPlusObjectType GetObjectType() override; + virtual EEmfPlusObjectType GetObjectType() const override; unsigned int unStringFormatFlags; unsigned int unStringAlignment; diff --git a/DesktopEditor/raster/Metafile/Emf/EmfPlusTypes.h b/DesktopEditor/raster/Metafile/Emf/EmfPlusTypes.h index b79f2942bf0..0e49ce3500e 100644 --- a/DesktopEditor/raster/Metafile/Emf/EmfPlusTypes.h +++ b/DesktopEditor/raster/Metafile/Emf/EmfPlusTypes.h @@ -2,6 +2,7 @@ #define EMFPLUSTYPES_H #include "EmfTypes.h" +#include "../Common/MetaFileObjects.h" namespace MetaFile { @@ -243,7 +244,7 @@ namespace MetaFile CustomLineCapDataLinePath = 0x00000002 } CustomLineCapDataFlags; - class CLineCapData + class CLineCapData : public ILineCap { public: CLineCapData() {}; @@ -291,7 +292,7 @@ namespace MetaFile CEmfPlusPath* pPath; TEmfPlusCustomLineCapData() : pPath(NULL) {}; - virtual ~TEmfPlusCustomLineCapData() { RELEASEOBJECT(pPath) }; + virtual ~TEmfPlusCustomLineCapData(); CustomLineCapDataType GetType() const override { diff --git a/DesktopEditor/raster/Metafile/MetaFile.cpp b/DesktopEditor/raster/Metafile/MetaFile.cpp index 66372cc98cb..d154f4cb230 100644 --- a/DesktopEditor/raster/Metafile/MetaFile.cpp +++ b/DesktopEditor/raster/Metafile/MetaFile.cpp @@ -145,7 +145,7 @@ namespace MetaFile double dWidth = 25.4 * nWidth / 96; double dHeight = 25.4 * nHeight / 96; - BYTE* pBgraData = new BYTE[nWidth * nHeight * 4]; + BYTE* pBgraData = new(std::nothrow) BYTE[nWidth * nHeight * 4]; if (!pBgraData) return; @@ -448,6 +448,37 @@ namespace MetaFile return false; } + bool CMetaFile::LoadFromString(const std::wstring& data) + { +#ifdef METAFILE_SUPPORT_SVG + RELEASEINTERFACE(m_pFontManager); + + if (m_pAppFonts) + { + m_pFontManager = m_pAppFonts->GenerateFontManager(); + NSFonts::IFontsCache* pMeasurerCache = NSFonts::NSFontCache::Create(); + pMeasurerCache->SetStreams(m_pAppFonts->GetStreams()); + m_pFontManager->SetOwnerCache(pMeasurerCache); + } + + m_oSvgFile.SetFontManager(m_pFontManager); + + if (m_oSvgFile.ReadFromWString(data) == true) + { + m_lType = c_lMetaSvg; + return true; + } +#endif + return false; + } + + void CMetaFile::SetTempDirectory(const std::wstring& dir) + { +#ifdef METAFILE_SUPPORT_SVG + m_oSvgFile.SetWorkingDirectory(dir); +#endif + } + bool CMetaFile::DrawOnRenderer(IRenderer* pRenderer, double dX, double dY, double dWidth, double dHeight) { if (NULL == pRenderer) @@ -508,10 +539,6 @@ namespace MetaFile m_oSvmFile.Close(); #endif - #ifdef METAFILE_SUPPORT_SVG - m_oSvgFile.Close(); - #endif - m_lType = 0; } @@ -527,31 +554,31 @@ namespace MetaFile #ifdef METAFILE_SUPPORT_WMF_EMF case c_lMetaWmf: { - const TRectD& oRect = m_oWmfFile.GetBounds(); + const TRectL& oRect{m_oWmfFile.GetBounds()}; *pdX = oRect.Left; *pdY = oRect.Top; - *pdW = oRect.Right - oRect.Left; + *pdW = oRect.Right - oRect.Left; *pdH = oRect.Bottom - oRect.Top; break; } case c_lMetaEmf: { - TRectL* pRect = m_oEmfFile.GetBounds(); - *pdX = pRect->Left; - *pdY = pRect->Top; - *pdW = pRect->Right - pRect->Left; - *pdH = pRect->Bottom - pRect->Top; + const TRectL& oRect{m_oEmfFile.GetBounds()}; + *pdX = oRect.Left; + *pdY = oRect.Top; + *pdW = oRect.Right - oRect.Left; + *pdH = oRect.Bottom - oRect.Top; break; } #endif #ifdef METAFILE_SUPPORT_SVM case c_lMetaSvm: { - TRectL* pRect = m_oSvmFile.GetBounds(); - *pdX = pRect->Left; - *pdY = pRect->Top; - *pdW = pRect->Right - pRect->Left; - *pdH = pRect->Bottom - pRect->Top; + const TRectL& oRect{m_oSvmFile.GetBounds()}; + *pdX = oRect.Left; + *pdY = oRect.Top; + *pdW = oRect.Right - oRect.Left; + *pdH = oRect.Bottom - oRect.Top; if (*pdW > 10000 || *pdH > 10000) { diff --git a/DesktopEditor/raster/Metafile/MetaFile.h b/DesktopEditor/raster/Metafile/MetaFile.h index 74738c1251f..018e0d1f199 100644 --- a/DesktopEditor/raster/Metafile/MetaFile.h +++ b/DesktopEditor/raster/Metafile/MetaFile.h @@ -64,6 +64,7 @@ namespace MetaFile bool LoadFromFile(const wchar_t* wsFilePath); bool LoadFromBuffer(BYTE* pBuffer, unsigned int unSize); + bool LoadFromString(const std::wstring& data); bool DrawOnRenderer(IRenderer* pRenderer, double dX, double dY, double dWidth, double dHeight); void Close(); void GetBounds(double* pdX, double* pdY, double* pdW, double* pdH); @@ -75,6 +76,8 @@ namespace MetaFile //конвертация в Svg std::wstring ConvertToSvg(unsigned int unWidth = 0, unsigned int unHeight = 0); + void SetTempDirectory(const std::wstring& dir); + //Для тестов #ifdef METAFILE_SUPPORT_WMF_EMF void ConvertToXml(const wchar_t *wsFilePath); diff --git a/DesktopEditor/raster/Metafile/MetaFileCommon.h b/DesktopEditor/raster/Metafile/MetaFileCommon.h new file mode 100644 index 00000000000..c5ac40e1dc2 --- /dev/null +++ b/DesktopEditor/raster/Metafile/MetaFileCommon.h @@ -0,0 +1,64 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#ifndef _METAFILE_COMMON_H +#define _METAFILE_COMMON_H + +#include "./MetaFile.h" + +namespace MetaFile +{ + static void ConvertToRasterMaxSize(MetaFile::IMetaFile* pMetafile, const wchar_t* wsOutFilePath, unsigned int unFileType, int nOneMaxSize) + { + double dX, dY, dW, dH; + pMetafile->GetBounds(&dX, &dY, &dW, &dH); + + if (dW < 0) dW = -dW; + if (dH < 0) dH = -dH; + + double dOneMaxSize = (double)nOneMaxSize; + + if (dW > dH) + { + dH *= (dOneMaxSize / dW); + dW = dOneMaxSize; + } + else + { + dW *= (dOneMaxSize / dH); + dH = dOneMaxSize; + } + + pMetafile->ConvertToRaster(wsOutFilePath, unFileType, (int)dW, (int)dH); + } +} + +#endif //_METAFILE_COMMON_H diff --git a/DesktopEditor/raster/Metafile/StarView/SvmFile.cpp b/DesktopEditor/raster/Metafile/StarView/SvmFile.cpp index dc8e978abf5..1a954774270 100644 --- a/DesktopEditor/raster/Metafile/StarView/SvmFile.cpp +++ b/DesktopEditor/raster/Metafile/StarView/SvmFile.cpp @@ -1070,7 +1070,7 @@ void CSvmFile::Read_META_BMP(TSvmBitmap & bitmap_info, BYTE** ppDstBuffer, unsig MetaFile::ReadImage((BYTE*)&bitmap_info, bitmap_info.nSize, destBuf, destSize, ppDstBuffer, pulWidth, pulHeight); delete []destBuf; } - else + else if (nHeaderSize >= bitmap_info.nSize) { BYTE *Header = new BYTE [ nHeaderSize]; memcpy(Header, &bitmap_info, bitmap_info.nSize); diff --git a/DesktopEditor/raster/Metafile/StarView/SvmFile.h b/DesktopEditor/raster/Metafile/StarView/SvmFile.h index a8e5ea9c0e1..5a7bedfecab 100644 --- a/DesktopEditor/raster/Metafile/StarView/SvmFile.h +++ b/DesktopEditor/raster/Metafile/StarView/SvmFile.h @@ -82,142 +82,122 @@ class CSvmFile : virtual public IMetaFileBase m_currentCharset = 0; m_currentLanguage = 0; } - TRectL* GetBounds() + const TRectL& GetBounds() { - return &m_oBoundingBox; + return m_oBoundingBox; } - TRectL* GetDCBounds() + const TRectL& GetDCBounds() const override { - //if (m_oHeader.mapMode.isSimple) if (m_pDC->m_oMapMode.isSimple) { - m_oDCRect = m_oBoundingBox; - return &m_oDCRect; + return m_oBoundingBox; } else { - return &m_oHeader.boundRect; + return m_oHeader.boundRect; } } - double GetPixelHeight() + double GetPixelHeight() const override { return m_pDC->m_dPixelHeight; } - double GetPixelWidth() + double GetPixelWidth() const override { return m_pDC->m_dPixelWidth; } - int GetTextColor() + int GetTextColor() const override { - TSvmColor& oColor = m_pDC->GetTextColor(); - return METAFILE_RGBA(oColor.r, oColor.g, oColor.b, 0); + return m_pDC->GetTextColor().ToInt(); } - IFont* GetFont() + const IFont* GetFont() const override { - CSvmFont* pFont = m_pDC->GetFont(); - if (!pFont) - return NULL; - - return (IFont*)pFont; + return m_pDC->GetFont(); } - IBrush* GetBrush() + const IBrush* GetBrush() const override { - CSvmBrush* pBrush = m_pDC->GetBrush(); - if (!pBrush) - return NULL; - - return (IBrush*)pBrush; + return m_pDC->GetBrush(); } - IPen* GetPen() + const IPen* GetPen() const override { - CSvmPen* pPen = m_pDC->GetPen(); - if (!pPen) - return NULL; - - return (IPen*)pPen; + return m_pDC->GetPen(); } - unsigned int GetTextAlign() + unsigned int GetTextAlign() const override { return m_pDC->GetTextAlign(); } - unsigned int GetTextBgMode() + unsigned int GetTextBgMode() const override { return m_pDC->GetBgMode(); } - int GetTextBgColor() + int GetTextBgColor() const override { - TSvmColor& oColor = m_pDC->GetTextBgColor(); - return METAFILE_RGBA(oColor.r, oColor.g, oColor.b, 0); + return m_pDC->GetTextBgColor().ToInt(); } - unsigned int GetFillMode() + unsigned int GetFillMode() const override { return m_pDC->GetFillMode(); } - TPointD GetCurPos() + TPointD GetCurPos() const override { TSvmPoint oPoint = m_pDC->GetCurPos(); TPointD oRes( oPoint.x, oPoint.y); TranslatePoint(oPoint.x, oPoint.y, oRes.X, oRes.Y); return oRes; } - TXForm* GetInverseTransform() + const TXForm& GetInverseTransform() const override { return m_pDC->GetInverseTransform(); } - TXForm* GetTransform(int iGraphicsMode = GM_ADVANCED) + const TXForm& GetTransform(int iGraphicsMode = GM_ADVANCED) override { return m_pDC->GetTransform(); } - unsigned int GetMiterLimit() + unsigned int GetMiterLimit() const override { return m_pDC->GetMiterLimit(); } - unsigned int GetRop2Mode() + unsigned int GetRop2Mode() const override { return m_pDC->GetRop2Mode(); } - CClip* GetClip() + const CClip* GetClip() const override { - CClip* pClip = m_pDC->GetClip(); - if (!pClip) - return NULL; - - return pClip; + return m_pDC->GetClip(); } - int GetCharSpace() + int GetCharSpace() const override { return 0; } - bool IsWindowFlippedY() + bool IsWindowFlippedY() const override { return false; } - bool IsWindowFlippedX() + bool IsWindowFlippedX() const override { return false; } - unsigned int GetMapMode() + unsigned int GetMapMode() const override { return MM_ANISOTROPIC; } - double GetDpi() + USHORT GetDpi() const override { - return 96.; + return 96; } - IRegion* GetRegion() + const IRegion* GetRegion() const override { return NULL; } - unsigned int GetArcDirection() + unsigned int GetArcDirection() const override { return AD_CLOCKWISE; } - CPath* GetPath() + const CPath* GetPath() const override { return NULL; } @@ -240,8 +220,6 @@ class CSvmFile : virtual public IMetaFileBase bool m_bFirstPoint; TRectL m_oBoundingBox; - //TRect m_oRect; - TRectL m_oDCRect; friend class CSvmPlayer; @@ -286,11 +264,11 @@ class CSvmFile : virtual public IMetaFileBase //------------------------------------------------------------------------------------------------------- - void TranslatePoint(TSvmPoint& oPoint, double& dX, double& dY) + void TranslatePoint(TSvmPoint& oPoint, double& dX, double& dY) const { TranslatePoint(oPoint.x, oPoint.y, dX, dY); } - void TranslatePoint(int nX, int nY, double& dX, double &dY) + void TranslatePoint(int nX, int nY, double& dX, double &dY) const { dX = (double)nX; dY = (double)nY; diff --git a/DesktopEditor/raster/Metafile/StarView/SvmObjects.cpp b/DesktopEditor/raster/Metafile/StarView/SvmObjects.cpp index bbe4c96e325..2c774bcbf99 100644 --- a/DesktopEditor/raster/Metafile/StarView/SvmObjects.cpp +++ b/DesktopEditor/raster/Metafile/StarView/SvmObjects.cpp @@ -319,35 +319,35 @@ CSvmBrush::CSvmBrush(CSvmBrush& oBrush) BrushBounds = oBrush.BrushBounds; } -int CSvmBrush::GetColor() +int CSvmBrush::GetColor() const { - return METAFILE_RGBA(Color.r, Color.g, Color.b, 0); + return Color.ToInt(); } -int CSvmBrush::GetColor2() +int CSvmBrush::GetColor2() const { - return METAFILE_RGBA(Color2.r, Color2.g, Color2.b, 0); + return Color2.ToInt(); } -unsigned int CSvmBrush::GetStyleEx() +unsigned int CSvmBrush::GetStyleEx() const { return BrushStyleEx; } -unsigned int CSvmBrush::GetStyle() +unsigned int CSvmBrush::GetStyle() const { return BrushStyle; } -unsigned int CSvmBrush::GetHatch() +unsigned int CSvmBrush::GetHatch() const { return BrushHatch; } -unsigned int CSvmBrush::GetAlpha() +unsigned int CSvmBrush::GetAlpha() const { return 0xff-Color.a; } -unsigned int CSvmBrush::GetAlpha2() +unsigned int CSvmBrush::GetAlpha2() const { return 0xff-Color2.a; } -void CSvmBrush::GetBounds(double& left, double& top, double& width, double& height) +void CSvmBrush::GetBounds(double& left, double& top, double& width, double& height) const { left = BrushBounds.l; top = BrushBounds.t; @@ -355,10 +355,16 @@ void CSvmBrush::GetBounds(double& left, double& top, double& width, double& heig height = BrushBounds.b - BrushBounds.t; } -void CSvmBrush::GetDibPattern(unsigned char **pBuffer, unsigned int &unWidth, unsigned int &unHeight) +void CSvmBrush::GetDibPattern(unsigned char **pBuffer, unsigned int &unWidth, unsigned int &unHeight) const {} -int CSvmPen::GetColor() +void CSvmBrush::GetGradientColors(std::vector& arColors, std::vector& arPositions) const +{ + arColors = {(long)(GetColor() + (GetAlpha() << 24)), (long)(GetColor2() + (GetAlpha2() << 24))}; + arPositions = {0., 1.}; +} + +int CSvmPen::GetColor() const { return METAFILE_RGBA(Color.r, Color.g, Color.b, 0); } diff --git a/DesktopEditor/raster/Metafile/StarView/SvmObjects.h b/DesktopEditor/raster/Metafile/StarView/SvmObjects.h index 8a512f78ba7..c2aefa243ef 100644 --- a/DesktopEditor/raster/Metafile/StarView/SvmObjects.h +++ b/DesktopEditor/raster/Metafile/StarView/SvmObjects.h @@ -53,7 +53,7 @@ namespace MetaFile public: CSvmObjectBase(){} virtual ~CSvmObjectBase(){} - virtual ESvmObjectType GetType() + virtual ESvmObjectType GetType() const { return SVM_OBJECT_UNKNOWN; } @@ -241,6 +241,10 @@ struct TSvmColor r = oColor.r; g = oColor.g; b = oColor.b; a = oColor.a; color = oColor.color; return *this; } + int ToInt() const + { + return METAFILE_RGBA(r, g, b, 0); + } }; struct TSvmLineInfo @@ -279,23 +283,24 @@ class CSvmBrush : public CSvmObjectBase, public IBrush CSvmBrush(); CSvmBrush(CSvmBrush& oBrush); virtual ~CSvmBrush(){} - virtual ESvmObjectType GetType() + virtual ESvmObjectType GetType() const override { return SVM_OBJECT_BRUSH; } // IBrush - int GetColor(); - int GetColor2(); - unsigned int GetStyleEx(); - unsigned int GetStyle(); - unsigned int GetHatch(); - unsigned int GetAlpha(); - unsigned int GetAlpha2(); - std::wstring GetDibPatterPath(){ return L""; } - void GetCenterPoint(double& dX, double& dY){} - void GetBounds(double& left, double& top, double& width, double& height); - void GetDibPattern(unsigned char** pBuffer, unsigned int &unWidth, unsigned int &unHeight); - + int GetColor() const override; + int GetColor2() const override; + unsigned int GetStyleEx() const override; + unsigned int GetStyle() const override; + unsigned int GetHatch() const override; + unsigned int GetAlpha() const override; + unsigned int GetAlpha2() const override; + std::wstring GetDibPatterPath() const override { return L""; } + void GetCenterPoint(double& dX, double& dY) const override {} + void GetBounds(double& left, double& top, double& width, double& height) const override; + void GetDibPattern(unsigned char** pBuffer, unsigned int &unWidth, unsigned int &unHeight) const override; + + void GetGradientColors(std::vector& arColors, std::vector& arPositions) const override; public: unsigned short BrushStyleEx; //angle, or .... unsigned short BrushStyle; @@ -331,45 +336,45 @@ class CSvmFont : public CSvmObjectBase, public IFont { } - virtual ESvmObjectType GetType() + virtual ESvmObjectType GetType() const override { return SVM_OBJECT_FONT; } // IFont - double GetHeight() + double GetHeight() const override { return (double)SizeHeight; } - std::wstring GetFaceName() + std::wstring GetFaceName() const override { return sFamilyName; } - int GetWeight() + int GetWeight() const override { return (int)Weight; } - bool IsItalic() + bool IsItalic() const override { return (0x01 == Italic ? true : false); } - bool IsStrikeOut() + bool IsStrikeOut() const override { return (0x01 == StrikeOut ? true : false); } - bool IsUnderline() + bool IsUnderline() const override { return (0x01 == Underline ? true : false); } - int GetEscapement() + int GetEscapement() const override { return 0;//(int)Escapement; } - int GetCharSet() + int GetCharSet() const override { return (int)CharSet; } - int GetOrientation() + int GetOrientation() const override { return (int)Orientation; } @@ -412,38 +417,46 @@ class CSvmPen : public CSvmObjectBase, public IPen { } - virtual ESvmObjectType GetType() + virtual ESvmObjectType GetType() const override { return SVM_OBJECT_PEN; } // IPen - int GetColor(); - unsigned int GetStyle() + int GetColor() const override; + unsigned int GetStyle() const override { return (unsigned int)PenStyle; } - double GetWidth() + double GetWidth() const override { return (double)Width; } - unsigned int GetAlpha() + unsigned int GetAlpha() const override { return 255; } - double GetMiterLimit() + double GetMiterLimit() const override { return 0; } - double GetDashOffset() + double GetDashOffset() const override { return 0; } - void GetDashData(double*& arDatas, unsigned int& unSize) + void GetDashData(double*& arDatas, unsigned int& unSize) const override { arDatas = NULL; unSize = 0; } + const ILineCap* GetStartLineCap() const override + { + return NULL; + } + const ILineCap* GetEndLineCap() const override + { + return NULL; + } public: unsigned short PenStyle; int Width; diff --git a/DesktopEditor/raster/Metafile/StarView/SvmPlayer.cpp b/DesktopEditor/raster/Metafile/StarView/SvmPlayer.cpp index d4e20ad4172..6a9c1f34810 100644 --- a/DesktopEditor/raster/Metafile/StarView/SvmPlayer.cpp +++ b/DesktopEditor/raster/Metafile/StarView/SvmPlayer.cpp @@ -447,7 +447,7 @@ CSvmDC::CSvmDC() CSvmDC::~CSvmDC() { } -CSvmDC* CSvmDC::Copy() +CSvmDC* CSvmDC::Copy() const { CSvmDC* pNewDC = new CSvmDC(); if (!pNewDC) @@ -482,7 +482,7 @@ CSvmDC* CSvmDC::Copy() return pNewDC; } -ESvmMapUnit CSvmDC::GetMapModeUnit() +ESvmMapUnit CSvmDC::GetMapModeUnit() const { return (ESvmMapUnit)m_oMapMode.unit; } @@ -576,14 +576,14 @@ void CSvmDC::SetMapMode(TSvmMapMode & mapMode, bool prefered ) } } -TXForm* CSvmDC::GetTransform() +const TXForm& CSvmDC::GetTransform() const { - return &m_oTransform; + return m_oTransform; } -TXForm* CSvmDC::GetInverseTransform() +const TXForm& CSvmDC::GetInverseTransform() const { - return &m_oTransform; + return m_oTransform; } void CSvmDC::SetTextColor(TSvmColor& oColor) @@ -591,7 +591,7 @@ void CSvmDC::SetTextColor(TSvmColor& oColor) m_oTextColor.Copy(oColor); } -TSvmColor& CSvmDC::GetTextColor() +const TSvmColor& CSvmDC::GetTextColor() const { return m_oTextColor; } @@ -604,7 +604,7 @@ void CSvmDC::RemoveBrush(CSvmBrush* pBrush) if (pBrush == m_pBrush) m_pBrush = NULL; } -CSvmBrush* CSvmDC::GetBrush() +const CSvmBrush* CSvmDC::GetBrush() const { return m_pBrush; } @@ -617,7 +617,7 @@ void CSvmDC::RemoveFont(CSvmFont* pFont) if (pFont == m_pFont) m_pFont = NULL; } -CSvmFont* CSvmDC::GetFont() +const CSvmFont* CSvmDC::GetFont() const { return m_pFont; } @@ -625,7 +625,7 @@ void CSvmDC::SetTextAlign(unsigned int ulAlign) { m_ulTextAlign = ulAlign; } -unsigned int CSvmDC::GetTextAlign() +unsigned int CSvmDC::GetTextAlign() const { return m_ulTextAlign; } @@ -633,7 +633,7 @@ void CSvmDC::SetBgMode(unsigned int ulBgMode) { m_ulBgMode = ulBgMode; } -unsigned int CSvmDC::GetBgMode() +unsigned int CSvmDC::GetBgMode() const { return m_ulBgMode; } @@ -645,7 +645,7 @@ void CSvmDC::SetTextBgColor(TSvmColor* oColor) { m_oTextBgColor.Copy(*oColor); } -TSvmColor& CSvmDC::GetTextBgColor() +const TSvmColor& CSvmDC::GetTextBgColor() const { return m_oTextBgColor; } @@ -653,7 +653,7 @@ void CSvmDC::SetMiterLimit(unsigned int ulMiter) { m_ulMiterLimit = ulMiter; } -unsigned int CSvmDC::GetMiterLimit() +unsigned int CSvmDC::GetMiterLimit() const { return m_ulMiterLimit; } @@ -661,7 +661,7 @@ void CSvmDC::SetFillMode(unsigned int ulFillMode) { m_ulFillMode = ulFillMode; } -unsigned int CSvmDC::GetFillMode() +unsigned int CSvmDC::GetFillMode() const { return m_ulFillMode; } @@ -674,11 +674,11 @@ void CSvmDC::RemovePen(CSvmPen* pPen) if (pPen == m_pPen) m_pPen = NULL; } -CSvmPen* CSvmDC::GetPen() +const CSvmPen* CSvmDC::GetPen() const { return m_pPen; } -CClip* CSvmDC::GetClip() +const CClip* CSvmDC::GetClip() const { return NULL;; //return &m_oClip; @@ -687,7 +687,7 @@ void CSvmDC::SetStretchMode(unsigned int& oMode) { m_ulStretchMode = oMode; } -unsigned int CSvmDC::GetStretchMode() +unsigned int CSvmDC::GetStretchMode() const { return m_ulStretchMode; } @@ -705,7 +705,7 @@ void CSvmDC::SetRop2Mode(unsigned int& nMode) { m_ulRop2Mode = nMode; } -unsigned int CSvmDC::GetRop2Mode() +unsigned int CSvmDC::GetRop2Mode() const { return m_ulRop2Mode; } @@ -731,7 +731,7 @@ void CSvmDC::SetCurPos(int lX, int lY) m_oCurPos.x = lX; m_oCurPos.y = lY; } -TSvmPoint & CSvmDC::GetCurPos() +const TSvmPoint & CSvmDC::GetCurPos() const { return m_oCurPos; } @@ -743,7 +743,7 @@ void CSvmDC::SetArcDirection(unsigned int unDirection) { m_unArcDirection = unDirection; } -unsigned int CSvmDC::GetArcDirection() +unsigned int CSvmDC::GetArcDirection() const { return m_unArcDirection; } diff --git a/DesktopEditor/raster/Metafile/StarView/SvmPlayer.h b/DesktopEditor/raster/Metafile/StarView/SvmPlayer.h index f8ecddd6799..be9b9568fab 100644 --- a/DesktopEditor/raster/Metafile/StarView/SvmPlayer.h +++ b/DesktopEditor/raster/Metafile/StarView/SvmPlayer.h @@ -89,51 +89,51 @@ class CSvmDC CSvmDC(); ~CSvmDC(); - CSvmDC* Copy(); - - ESvmMapUnit GetMapModeUnit(); - void SetMapMode(TSvmMapMode &mapMode, bool prefered = false); - TXForm* GetTransform(); - TXForm* GetInverseTransform(); - void MultiplyTransform(TXForm& oForm, unsigned int ulMode); - void SetTextColor(TSvmColor& oColor); - TSvmColor& GetTextColor(); - void SetBrush(CSvmBrush* pBrush); - void RemoveBrush(CSvmBrush *pBrush); - CSvmBrush* GetBrush(); - void SetFont(CSvmFont* pFont); - void RemoveFont(CSvmFont* pFont); - CSvmFont* GetFont(); - void SetTextAlign(unsigned int ulAlign); - unsigned int GetTextAlign(); - void SetBgMode(unsigned int ulBgMode); - unsigned int GetBgMode(); + CSvmDC* Copy() const; + + ESvmMapUnit GetMapModeUnit() const; + void SetMapMode(TSvmMapMode &mapMode, bool prefered = false); + const TXForm& GetTransform() const; + const TXForm& GetInverseTransform() const; + void MultiplyTransform(TXForm& oForm, unsigned int ulMode); + void SetTextColor(TSvmColor& oColor); + const TSvmColor& GetTextColor() const; + void SetBrush(CSvmBrush* pBrush); + void RemoveBrush(CSvmBrush *pBrush); + const CSvmBrush* GetBrush() const; + void SetFont(CSvmFont* pFont); + void RemoveFont(CSvmFont* pFont); + const CSvmFont* GetFont() const; + void SetTextAlign(unsigned int ulAlign); + unsigned int GetTextAlign() const; + void SetBgMode(unsigned int ulBgMode); + unsigned int GetBgMode() const; - void SetTextBgColor(TSvmColor& oColor); - void SetTextBgColor(TSvmColor* oColor); - TSvmColor& GetTextBgColor(); + void SetTextBgColor(TSvmColor& oColor); + void SetTextBgColor(TSvmColor* oColor); + const TSvmColor& GetTextBgColor() const; - void SetMiterLimit(unsigned int ulMiter); - unsigned int GetMiterLimit(); - void SetFillMode(unsigned int ulFillMode); - unsigned int GetFillMode(); - void SetPen(CSvmPen* pPen); - void RemovePen(CSvmPen* pPen); - CSvmPen* GetPen(); - void SetStretchMode(unsigned int& oMode); - unsigned int GetStretchMode(); - void SetRop2Mode(unsigned int& nMode); - unsigned int GetRop2Mode(); + void SetMiterLimit(unsigned int ulMiter); + unsigned int GetMiterLimit() const; + void SetFillMode(unsigned int ulFillMode); + unsigned int GetFillMode() const; + void SetPen(CSvmPen* pPen); + void RemovePen(CSvmPen* pPen); + const CSvmPen* GetPen() const; + void SetStretchMode(unsigned int& oMode); + unsigned int GetStretchMode() const; + void SetRop2Mode(unsigned int& nMode); + unsigned int GetRop2Mode() const; //void SetPalette(CSvmLogPalette* pPalette); //void RemovePalette(CSvmLogPalette* pPalette); //CSvmLogPalette* GetPalette(); - void SetCurPos(TSvmPoint& oPoint); - void SetCurPos(int lX, int lY); - TSvmPoint& GetCurPos(); - CClip* GetClip(); + void SetCurPos(TSvmPoint& oPoint); + void SetCurPos(int lX, int lY); + const TSvmPoint& GetCurPos() const; + const CClip* GetClip() const; //void ClipToPath(CSvmPath* pPath, unsigned int unMode); - void SetArcDirection(unsigned int unDirection); - unsigned int GetArcDirection(); + void SetArcDirection(unsigned int unDirection); + unsigned int GetArcDirection() const; double m_dPixelWidth; double m_dPixelHeight; diff --git a/DesktopEditor/raster/Metafile/TestMain.cpp b/DesktopEditor/raster/Metafile/TestMain.cpp index 9eca82560bc..3b96e3e2be5 100644 --- a/DesktopEditor/raster/Metafile/TestMain.cpp +++ b/DesktopEditor/raster/Metafile/TestMain.cpp @@ -36,7 +36,6 @@ #include "../../common/Directory.h" #include "../../fontengine/ApplicationFonts.h" -#include "../../../HtmlRenderer/include/ASCSVGWriter.h" #include "MetaFile.h" #if defined(_WIN64) diff --git a/DesktopEditor/raster/Metafile/Wmf/WmfFile.h b/DesktopEditor/raster/Metafile/Wmf/WmfFile.h index e8197568e05..5c0734575b2 100644 --- a/DesktopEditor/raster/Metafile/Wmf/WmfFile.h +++ b/DesktopEditor/raster/Metafile/Wmf/WmfFile.h @@ -51,7 +51,7 @@ namespace MetaFile { public: CWmfFile() : m_pParser(new CWmfParser) - {} + {} ~CWmfFile() { @@ -71,7 +71,7 @@ namespace MetaFile { if (NULL != m_pParser) { - NSFonts::IFontManager* pFont = m_pParser->GetFontManager(); + NSFonts::IFontManager* pFont = m_pParser->GetFontManager(); delete m_pParser; m_pParser = new CWmfParser(); @@ -102,7 +102,7 @@ namespace MetaFile m_pParser->Close(); } - void SetFontManager(NSFonts::IFontManager* pFontManager) + void SetFontManager(NSFonts::IFontManager* pFontManager) { m_pParser->SetFontManager(pFontManager); } @@ -131,9 +131,9 @@ namespace MetaFile m_pParser->SetInterpretator(pOutput, wsFilePath); } - TRectD GetBounds() + const TRectL& GetBounds() const { - return m_pParser->GetBounds(); + return m_pParser->GetDCBounds(); } private: diff --git a/DesktopEditor/raster/Metafile/Wmf/WmfInterpretator/CInterpretatorSvgBase.cpp b/DesktopEditor/raster/Metafile/Wmf/WmfInterpretator/CInterpretatorSvgBase.cpp index 85cab75fcf0..aa04e4ce569 100644 --- a/DesktopEditor/raster/Metafile/Wmf/WmfInterpretator/CInterpretatorSvgBase.cpp +++ b/DesktopEditor/raster/Metafile/Wmf/WmfInterpretator/CInterpretatorSvgBase.cpp @@ -19,7 +19,7 @@ namespace MetaFile const std::map mHatchStyles = { - { HS_HORIZONTAL, L"HORIZONTAL"}, + { HS_HORIZONTAL, L"HORIZONTAL"}, { HS_VERTICAL, L"VERTICAL"}, { HS_FDIAGONAL, L"FDIAGONAL"}, { HS_BDIAGONAL, L"BDIAGONAL"}, @@ -75,7 +75,8 @@ namespace MetaFile }; CInterpretatorSvgBase::CInterpretatorSvgBase(IMetaFileBase *pParser, double dWidth, double dHeight) - : m_oSizeWindow(dWidth, dHeight), m_unNumberDefs(0), m_pParser(pParser), m_pXmlWriter(new XmlUtils::CXmlWriter()), m_bExternXmlWriter(false), m_bUpdatedClip(true) + : m_oSizeWindow(dWidth, dHeight), m_unNumberDefs(0), m_pParser(pParser), m_pXmlWriter(new XmlUtils::CXmlWriter()), + m_bExternXmlWriter(false), m_bUpdatedClip(true), m_eShapeRendering(EShapeRendering::Auto) {} CInterpretatorSvgBase::~CInterpretatorSvgBase() @@ -98,6 +99,12 @@ namespace MetaFile void CInterpretatorSvgBase::UpdateSize() { + if (Equals(0., m_oSizeWindow.X) && !Equals(0., m_oViewport.GetWidth())) + m_oSizeWindow.X = m_oViewport.GetWidth(); + + if (Equals(0., m_oSizeWindow.Y) && !Equals(0., m_oViewport.GetHeight())) + m_oSizeWindow.Y = m_oViewport.GetHeight(); + if (0 != m_oSizeWindow.X && 0 == m_oSizeWindow.Y) m_oSizeWindow.Y = m_oSizeWindow.X * (m_oViewport.GetHeight() / m_oViewport.GetWidth()); else if (0 == m_oSizeWindow.X && 0 != m_oSizeWindow.Y) @@ -121,6 +128,11 @@ namespace MetaFile return m_pXmlWriter; } + void CInterpretatorSvgBase::SetShapeRendering(EShapeRendering eShapeRenderingType) + { + m_eShapeRendering = eShapeRenderingType; + } + std::wstring CInterpretatorSvgBase::GetFile() { return m_pXmlWriter->GetXmlString(); @@ -147,12 +159,6 @@ namespace MetaFile if (oNewClipRect.Top > oNewClipRect.Bottom) std::swap(oNewClipRect.Top, oNewClipRect.Bottom); - NodeAttributes arNodeAttributes; - - AddTransform(arNodeAttributes, pTransform); - - WriteNodeBegin(L"g", arNodeAttributes); - wsNewSvg.erase(unFirstPos, unSecondPos - unFirstPos); std::wstring wsClip = L"x=\"" + ConvertToWString(oRect.Left) + L"\" y=\"" + ConvertToWString(oRect.Top) + L"\" " + @@ -161,9 +167,17 @@ namespace MetaFile wsNewSvg.insert(unFirstPos, wsClip); + NodeAttributes arNodeAttributes; + + AddTransform(arNodeAttributes, pTransform); + + if (!arNodeAttributes.empty()) + WriteNodeBegin(L"g", arNodeAttributes); + m_pXmlWriter->WriteString(wsNewSvg); - WriteNodeEnd(L"g"); + if (!arNodeAttributes.empty()) + WriteNodeEnd(L"g"); } void CInterpretatorSvgBase::WriteNode(const std::wstring &wsNodeName, const NodeAttributes &arAttributes, const std::wstring &wsValueNode) @@ -203,16 +217,6 @@ namespace MetaFile m_pXmlWriter->WriteNodeEnd(wsNodeName, false, false); } - static void EraseWords(std::wstring& wsString, const std::vector& arWords) - { - size_t unBegin = 0; - for (const std::wstring& wsWord : arWords) - { - while (std::wstring::npos != (unBegin = wsString.find(wsWord))) - wsString.erase(unBegin, wsWord.length()); - } - } - void CInterpretatorSvgBase::WriteText(const std::wstring &wsText, const TPointD &oCoord, const TRectL &oBounds, const TPointD &oScale, const std::vector& arDx) { if (NULL == m_pParser || NULL == m_pParser->GetFont()) @@ -243,64 +247,73 @@ namespace MetaFile if (OPAQUE == m_pParser->GetTextBgMode()) { - std::wstring wsFillRect = L"rgb(" + INTCOLOR_TO_RGB(m_pParser->GetTextBgColor()) + L')'; + std::wstring wsFillRect = CalculateColor(m_pParser->GetTextBgColor(), 255); WriteNodeBegin(L"g", {}); bWriteG = true; - WriteNode(L"rect", {{L"x", ConvertToWString(oBounds.Left)}, - {L"y", ConvertToWString(oBounds.Top)}, - {L"width", ConvertToWString(oBounds.Right - oBounds.Left)}, - {L"height", ConvertToWString(oBounds.Bottom - oBounds.Top)}, - {L"fill", wsFillRect}, - {L"stroke", L"none"}}); + NodeAttributes arRectAttributes{{L"x", ConvertToWString(oBounds.Left)}, + {L"y", ConvertToWString(oBounds.Top)}, + {L"width", ConvertToWString(oBounds.Right - oBounds.Left)}, + {L"height", ConvertToWString(oBounds.Bottom - oBounds.Top)}, + {L"fill", wsFillRect}, + {L"stroke", L"none"}}; + + AddShapeRendering(arRectAttributes); + + WriteNode(L"rect", arNodeAttributes); } int nColor = m_pParser->GetTextColor(); if (0 != nColor) - arNodeAttributes.push_back({L"fill", L"rgb(" + INTCOLOR_TO_RGB(nColor) + L')'}); + arNodeAttributes.Add(L"fill", CalculateColor(nColor, 255)); - IFont *pFont = m_pParser->GetFont(); - - if (NULL == pFont) - return; + const IFont *pFont = m_pParser->GetFont(); double dFontHeight = std::fabs(pFont->GetHeight()); if (dFontHeight < 0.01) - dFontHeight = 18; + dFontHeight = DEFAULT_FONT_SIZE; - arNodeAttributes.push_back({L"font-size", ConvertToWString(dFontHeight)}); + arNodeAttributes.Add(L"font-size", dFontHeight); - std::wstring wsFontName = pFont->GetFaceName(); + NSStringUtils::CStringBuilder oFontName; + oFontName.WriteEncodeXmlString(pFont->GetFaceName()); - if (!wsFontName.empty()) + if (0 != oFontName.GetSize()) { + #ifndef BUILDING_WASM_MODULE NSFonts::CFontSelectFormat oFormat; oFormat.wsName = new std::wstring(pFont->GetFaceName()); NSFonts::CFontInfo *pFontInfo = m_pParser->GetFontManager()->GetFontInfoByParams(oFormat); - if (NULL != pFontInfo && !StringEquals(wsFontName, pFontInfo->m_wsFontName)) - wsFontName = L"'" + wsFontName + L"', '" + pFontInfo->m_wsFontName + L"'"; + if (NULL != pFontInfo && !StringEquals(*oFormat.wsName, pFontInfo->m_wsFontName)) + { + oFontName.Clear(); + oFontName.WriteEncodeXmlString(L"\'"); + oFontName.WriteEncodeXmlString(*oFormat.wsName); + oFontName.WriteEncodeXmlString(L"\',\'"); + oFontName.WriteEncodeXmlString(pFontInfo->m_wsFontName); + oFontName.WriteEncodeXmlString(L"\'"); + } + #endif + arNodeAttributes.Add(L"font-family", oFontName.GetData()); } - if (!wsFontName.empty()) - arNodeAttributes.push_back({L"font-family", wsFontName}); - if (pFont->GetWeight() > 550) - arNodeAttributes.push_back({L"font-weight", L"bold"}); + arNodeAttributes.Add(L"font-weight", L"bold"); if (pFont->IsItalic()) - arNodeAttributes.push_back({L"font-style", L"italic"}); + arNodeAttributes.Add(L"font-style", L"italic"); if (pFont->IsUnderline() && pFont->IsStrikeOut()) - arNodeAttributes.push_back({L"text-decoration", L"underline line-through"}); + arNodeAttributes.Add(L"text-decoration", L"underline line-through"); else if (pFont->IsUnderline()) - arNodeAttributes.push_back({L"text-decoration", L"underline"}); + arNodeAttributes.Add(L"text-decoration", L"underline"); else if (pFont->IsStrikeOut()) - arNodeAttributes.push_back({L"text-decoration", L"line-through"}); + arNodeAttributes.Add(L"text-decoration", L"line-through"); //TODO:: разобраться для корректной работы // double dFontCharSpace = pFont->GetCharSet(); @@ -322,14 +335,14 @@ namespace MetaFile } else if (ulTextAlign & TA_BOTTOM || ulVTextAlign == VTA_BOTTOM) { - arNodeAttributes.push_back({L"dominant-baseline", L"auto"}); + arNodeAttributes.Add(L"dominant-baseline", L"auto"); if (ulVTextAlign != VTA_BOTTOM) ulTextAlign -= TA_BOTTOM; } else if (ulVTextAlign == VTA_CENTER) { - arNodeAttributes.push_back({L"dominant-baseline", L"middle"}); + arNodeAttributes.Add(L"dominant-baseline", L"middle"); } else // if (ulTextAlign & TA_TOP) { @@ -339,14 +352,14 @@ namespace MetaFile if (ulTextAlign == TA_RIGHT) { if (arDx.empty()) - arNodeAttributes.push_back({L"text-anchor", L"end"}); + arNodeAttributes.Add(L"text-anchor", L"end"); else dXCoord -= std::accumulate(arDx.begin(), arDx.end(), 0.0); } else if (ulTextAlign == TA_CENTER) { if (arDx.empty()) - arNodeAttributes.push_back({L"text-anchor", L"middle"}); + arNodeAttributes.Add(L"text-anchor", L"middle"); else dXCoord -= std::accumulate(arDx.begin(), arDx.end(), 0.0) / 2; } @@ -368,7 +381,7 @@ namespace MetaFile { double dEscapement = pFont->GetEscapement() / -10; - if (m_pParser->GetTransform()->M22 < 0) + if (m_pParser->GetTransform().M22 < 0) dEscapement = -dEscapement; double dSin = std::sin(dEscapement * M_PI / 180.); @@ -378,7 +391,7 @@ namespace MetaFile if (oScale.Y < -0.00001) dXCoord -= dFontHeight * dSin; - arNodeAttributes.push_back({L"transform", L"rotate(" + ConvertToWString(dEscapement) + L' ' + ConvertToWString(dXCoord) + L' ' + ConvertToWString(dYCoord) + L')'}); + arNodeAttributes.Add(L"transform", L"rotate(" + ConvertToWString(dEscapement) + L' ' + ConvertToWString(dXCoord) + L' ' + ConvertToWString(dYCoord) + L')'); if (oScale.Y > 0.00001) dXCoord -= dFontHeight * dSin; @@ -386,7 +399,7 @@ namespace MetaFile AddTransform(arNodeAttributes, &oTransform); - arNodeAttributes.push_back({L"xml:space", L"preserve"}); + arNodeAttributes.Add(L"xml:space", L"preserve"); size_t unPosLineBreak = wsNormalizedText.find(L"\n"); @@ -408,8 +421,8 @@ namespace MetaFile if (std::wstring::npos == unPosLineBreak) { - arNodeAttributes.push_back({L"x", wsXCoord}); - arNodeAttributes.push_back({L"y", ConvertToWString(dYCoord)}); + arNodeAttributes.Add(L"x", wsXCoord); + arNodeAttributes.Add(L"y", dYCoord); WriteNode(L"text", arNodeAttributes, wsNormalizedText); } @@ -423,7 +436,7 @@ namespace MetaFile do { WriteNode(L"tspan", {{L"x", wsXCoord}, - {L"y", ConvertToWString(dYNewCoord)}}, wsNormalizedText.substr(unStart, unPosLineBreak - unStart)); + {L"y", ConvertToWString(dYNewCoord)}}, wsNormalizedText.substr(unStart, unPosLineBreak - unStart)); dYNewCoord += dFontHeight * 1.6; unStart = wsNormalizedText.find_first_not_of(L"\n", unPosLineBreak); @@ -438,54 +451,152 @@ namespace MetaFile m_pXmlWriter->WriteNodeEnd(L"g"); } + void CInterpretatorSvgBase::DrawBitmap(double dX, double dY, double dW, double dH, BYTE *pBuffer, unsigned int unWidth, unsigned int unHeight) + { + if (NULL == pBuffer || Equals(0., dW) || Equals(0., dH) || 0 == unWidth || 0 == unHeight) + return; + + TXForm oTransform; + oTransform.Copy(m_pParser->GetTransform()); + + if (dW < 0 || dH < 0) + { + double dKx = 1, dKy = 1, dShiftKoefX = 0, dShiftKoefY = 0; + if (dW < 0) + { + dKx = -1; + dShiftKoefX = 2 * dX + dW; + + dW = -dW; + dX -= dW; + } + + if (dH < 0) + { + dKy = -1; + dShiftKoefY = 2 * dY + dH; + + dH = -dH; + dY -= dH; + } + + oTransform.Dx += dShiftKoefX * oTransform.M11 + dShiftKoefY * oTransform.M21; + oTransform.Dy += dShiftKoefX * oTransform.M12 + dShiftKoefY * oTransform.M22; + oTransform.M11 *= dKx; + oTransform.M12 *= dKx; + oTransform.M21 *= dKy; + oTransform.M22 *= dKy; + } + + if (1 == unWidth && 1 == unHeight) + { + NodeAttributes arAttributes = {{L"x", ConvertToWString(dX)}, + {L"y", ConvertToWString(dY)}, + {L"width", ConvertToWString(dW)}, + {L"height", ConvertToWString(dH)}, + {L"fill", CalculateColor(pBuffer[2], pBuffer[1], pBuffer[0], 255)}}; + + AddShapeRendering(arAttributes); + AddTransform(arAttributes, &oTransform); + AddClip(); + + WriteNode(L"rect", arAttributes); + + return; + } + + CBgraFrame oFrame; + + oFrame.put_Data(pBuffer); + oFrame.put_Width(unWidth); + oFrame.put_Height(unHeight); + + BYTE* pNewBuffer = NULL; + int nNewSize = 0; + + if (!oFrame.Encode(pNewBuffer, nNewSize, 4)) + { + oFrame.put_Data(NULL); + return; + } + + oFrame.put_Data(NULL); + + if (0 < nNewSize) + { + int nImageSize = NSBase64::Base64EncodeGetRequiredLength(nNewSize); + unsigned char* ucValue = new unsigned char[nImageSize]; + + if (NULL == ucValue) + return; + + NSBase64::Base64Encode(pNewBuffer, nNewSize, ucValue, &nImageSize); + std::wstring wsValue(ucValue, ucValue + nImageSize); + + RELEASEARRAYOBJECTS(ucValue); + + NodeAttributes arAttributes = {{L"x", ConvertToWString(dX)}, + {L"y", ConvertToWString(dY)}, + {L"width", ConvertToWString(dW)}, + {L"height", ConvertToWString(dH)}, + {L"xlink:href", L"data:image/png;base64," + wsValue}}; + + AddTransform(arAttributes, &oTransform); + AddClip(); + + WriteNode(L"image", arAttributes); + } + + if (NULL != pNewBuffer) + delete [] pNewBuffer; + } + void CInterpretatorSvgBase::ResetClip() { + CloseClip(); m_oClip.Reset(); + m_bUpdatedClip = false; } void CInterpretatorSvgBase::IntersectClip(const TRectD &oClip) { - TXForm *pTransform = m_pParser->GetTransform(); - - double dLeft = oClip.Left; - double dTop = oClip.Top; - double dRight = oClip.Right; - double dBottom = oClip.Bottom; + TRectD oUpdatedClip{oClip}; + + NormalizeRect(oUpdatedClip); + + m_pParser->GetTransform().Apply(oUpdatedClip.Left, oUpdatedClip.Top); + m_pParser->GetTransform().Apply(oUpdatedClip.Right, oUpdatedClip.Bottom); - pTransform->Apply(dLeft, dTop); - pTransform->Apply(dRight, dBottom); - const std::wstring wsId = L"INTERSECTCLIP_" + ConvertToWString(++m_unNumberDefs, 0); - const std::wstring wsValue = L""; + const std::wstring wsValue = L""; m_oClip.AddClipValue(wsId, wsValue); } void CInterpretatorSvgBase::ExcludeClip(const TRectD &oClip, const TRectD &oBB) { - TXForm *pTransform = m_pParser->GetTransform(); - - double dClipLeft = oClip.Left; - double dClipTop = oClip.Top; - double dClipRight = oClip.Right; - double dClipBottom = oClip.Bottom; + const TXForm &oTransform{m_pParser->GetTransform()}; - pTransform->Apply(dClipLeft, dClipTop); - pTransform->Apply(dClipRight, dClipBottom); - - double dBBLeft = oBB.Left; - double dBBTop = oBB.Top; - double dBBRight = oBB.Right; - double dBBBottom = oBB.Bottom; + TRectD oUpdatedClip{oClip}; + NormalizeRect(oUpdatedClip); + + oTransform.Apply(oUpdatedClip.Left, oUpdatedClip.Top); + oTransform.Apply(oUpdatedClip.Right, oUpdatedClip.Bottom); + + TRectD oBBRect{oBB}; + NormalizeRect(oBBRect); - pTransform->Apply(dBBLeft, dBBTop); - pTransform->Apply(dBBRight, dBBBottom); + oTransform.Apply(oBBRect.Left, oBBRect.Top); + oTransform.Apply(oBBRect.Right, oBBRect.Bottom); const std::wstring wsId = L"EXCLUDECLIP_" + ConvertToWString(++m_unNumberDefs, 0); - const std::wstring wsValue = L""; + const std::wstring wsValue = L""; m_oClip.AddClipValue(wsId, wsValue); } @@ -508,38 +619,19 @@ namespace MetaFile if (NULL == m_pParser) return; - IPen *pPen = m_pParser->GetPen(); + const IPen *pPen = m_pParser->GetPen(); if (NULL == pPen || PS_NULL == pPen->GetStyle()) return; switch (m_pParser->GetRop2Mode()) { - case R2_BLACK: arAttributes.push_back({L"stroke", L"rgb(0, 0, 0)"}); break; + case R2_BLACK: arAttributes.Add(L"stroke", L"rgb(0, 0, 0)"); break; case R2_NOP: return; - case R2_WHITE: arAttributes.push_back({L"stroke", L"rgb(255, 255, 255)"}); break; - default: arAttributes.push_back({L"stroke", L"rgb(" + INTCOLOR_TO_RGB(pPen->GetColor()) + L')'}); break; + case R2_WHITE: arAttributes.Add(L"stroke", L"rgb(255, 255, 255)"); break; + default: arAttributes.Add(L"stroke", CalculateColor(pPen->GetColor(), pPen->GetAlpha())); break; } - double dStrokeWidth = std::fabs(pPen->GetWidth()); - - if (0 == dStrokeWidth || (1.0 == dStrokeWidth && PS_COSMETIC == (pPen->GetStyle() & PS_TYPE_MASK))) - { - double dScale = m_pParser->GetDpi() / 96.; - - if (0 != m_oViewport.GetWidth() && 0 != m_oSizeWindow.X) - dScale *= m_oViewport.GetWidth() / m_oSizeWindow.X; - - dStrokeWidth = dScale / std::fabs(m_pParser->GetTransform()->M11); - } - - arAttributes.push_back({L"stroke-width", ConvertToWString(dStrokeWidth)}); - - if (pPen->GetAlpha() != 255) - arAttributes.push_back({L"stroke-opacity" , ConvertToWString(pPen->GetAlpha() / 255., 3)}); - - arAttributes.push_back({L"stroke-miterlimit", ConvertToWString(pPen->GetMiterLimit())}); - unsigned int unMetaPenStyle = pPen->GetStyle(); unsigned int ulPenStyle = unMetaPenStyle & PS_STYLE_MASK; unsigned int ulPenStartCap = unMetaPenStyle & PS_STARTCAP_MASK; @@ -547,7 +639,7 @@ namespace MetaFile unsigned int ulPenJoin = unMetaPenStyle & PS_JOIN_MASK; // svg не поддерживает разные стили для разных сторон линии - std::wstring wsLineCap; + std::wstring wsLineCap, wsLineJoin; if (PS_ENDCAP_ROUND == ulPenEndCap) wsLineCap = L"round"; @@ -562,15 +654,26 @@ namespace MetaFile wsLineCap = L"square"; else if (PS_STARTCAP_ROUND == ulPenStartCap) wsLineCap = L"round"; - - arAttributes.push_back({L"stroke-linecap", wsLineCap}); - + if (PS_JOIN_MITER == ulPenJoin) - arAttributes.push_back({L"stroke-linejoin", L"miter"}); + wsLineJoin = L"miter"; else if (PS_JOIN_BEVEL == ulPenJoin) - arAttributes.push_back({L"stroke-linejoin", L"bevel"}); + wsLineJoin = L"bevel"; else if (PS_JOIN_ROUND == ulPenJoin) - arAttributes.push_back({L"stroke-linejoin", L"round"}); + wsLineJoin = L"round"; + + double dStrokeWidth = std::fabs(m_pParser->GetPen()->GetWidth()); + + if (Equals(0., dStrokeWidth)) + { + dStrokeWidth = 1.; + arAttributes.Add(L"vector-effect", L"non-scaling-stroke"); + } + + arAttributes.Add(L"stroke-width", dStrokeWidth); + arAttributes.Add(L"stroke-miterlimit", pPen->GetMiterLimit()); + arAttributes.Add(L"stroke-linecap", wsLineCap); + arAttributes.Add(L"stroke-linejoin", wsLineJoin); double* arDatas = NULL; unsigned int unDataSize = 0; @@ -590,31 +693,31 @@ namespace MetaFile } wsDashArray.pop_back(); - arAttributes.push_back({L"stroke-dasharray", wsDashArray}); + arAttributes.Add(L"stroke-dasharray", wsDashArray); } else if (PS_DASH == ulPenStyle) - arAttributes.push_back({L"stroke-dasharray", ConvertToWString(dStrokeWidth * 4) + L' ' + ConvertToWString(dStrokeWidth * 2)}); + arAttributes.Add(L"stroke-dasharray", ConvertToWString(dStrokeWidth * 4) + L' ' + ConvertToWString(dStrokeWidth * 2)); else if (PS_DOT == ulPenStyle) - arAttributes.push_back({L"stroke-dasharray", ConvertToWString(dStrokeWidth) + L' ' + ConvertToWString(dStrokeWidth)}); + arAttributes.Add(L"stroke-dasharray", ConvertToWString(dStrokeWidth) + L' ' + ConvertToWString(dStrokeWidth)); else if (PS_DASHDOT == ulPenStyle) - arAttributes.push_back({L"stroke-dasharray", ConvertToWString(dStrokeWidth * 4) + L' ' + ConvertToWString(dStrokeWidth * 2) + L' ' + ConvertToWString(dStrokeWidth) + L' ' + ConvertToWString(dStrokeWidth * 2)}); + arAttributes.Add(L"stroke-dasharray", ConvertToWString(dStrokeWidth * 4) + L' ' + ConvertToWString(dStrokeWidth * 2) + L' ' + ConvertToWString(dStrokeWidth) + L' ' + ConvertToWString(dStrokeWidth * 2)); else if (PS_DASHDOTDOT == ulPenStyle) - arAttributes.push_back({L"stroke-dasharray", ConvertToWString(dStrokeWidth * 4) + L' ' + ConvertToWString(dStrokeWidth * 2) + L' ' + ConvertToWString(dStrokeWidth) + L' ' + ConvertToWString(dStrokeWidth * 2) + L' ' + ConvertToWString(dStrokeWidth) + L' ' + ConvertToWString(dStrokeWidth * 2)}); + arAttributes.Add(L"stroke-dasharray", ConvertToWString(dStrokeWidth * 4) + L' ' + ConvertToWString(dStrokeWidth * 2) + L' ' + ConvertToWString(dStrokeWidth) + L' ' + ConvertToWString(dStrokeWidth * 2) + L' ' + ConvertToWString(dStrokeWidth) + L' ' + ConvertToWString(dStrokeWidth * 2)); } void CInterpretatorSvgBase::AddFill(NodeAttributes &arAttributes, double dWidth, double dHeight) { if (NULL == m_pParser) { - arAttributes.push_back({L"fill", L"none"}); + arAttributes.Add(L"fill", L"none"); return; } - IBrush *pBrush = NULL; + const IBrush *pBrush = NULL; if (NULL != m_pParser->GetPen()) { - CEmfPlusPen *pPen = dynamic_cast(m_pParser->GetPen()); + const CEmfPlusPen *pPen = dynamic_cast(m_pParser->GetPen()); if (NULL != pPen) pBrush = pPen->pBrush; @@ -623,23 +726,17 @@ namespace MetaFile if (NULL == pBrush) pBrush = m_pParser->GetBrush(); - unsigned int unBrushStyle = pBrush->GetStyle(); - - if (NULL == pBrush || BS_NULL == unBrushStyle) + if (NULL == pBrush || BS_NULL == pBrush->GetStyle()) { - arAttributes.push_back({L"fill", L"none"}); + arAttributes.Add(L"fill", L"none"); return; } - switch (unBrushStyle) + switch (pBrush->GetStyle()) { case BS_SOLID: { - arAttributes.push_back({L"fill", L"rgb(" + INTCOLOR_TO_RGB(pBrush->GetColor()) + L")"}); - - if (pBrush->GetAlpha() != 255) - arAttributes.push_back({L"fill-opacity" , ConvertToWString(pBrush->GetAlpha() / 255., 3)}); - + arAttributes.Add(L"fill", CalculateColor(pBrush->GetColor(), pBrush->GetAlpha())); return; } case BS_HATCHED: @@ -648,7 +745,7 @@ namespace MetaFile if (!wsStyleId.empty()) { - arAttributes.push_back({L"fill", L"url(#" + wsStyleId + L")"}); + arAttributes.Add(L"fill", L"url(#" + wsStyleId + L")"); return; } @@ -660,7 +757,7 @@ namespace MetaFile if (!wsStyleId.empty()) { - arAttributes.push_back({L"fill", L"url(#" + wsStyleId + L")"}); + arAttributes.Add(L"fill", L"url(#" + wsStyleId + L")"); return; } } @@ -670,7 +767,7 @@ namespace MetaFile if (!wsStyleId.empty()) { - arAttributes.push_back({L"fill", L"url(#" + wsStyleId + L")"}); + arAttributes.Add(L"fill", L"url(#" + wsStyleId + L")"); return; } } @@ -684,12 +781,12 @@ namespace MetaFile if (!wsStyleId.empty()) { - arAttributes.push_back({L"fill", L"url(#" + wsStyleId + L")"}); + arAttributes.Add(L"fill", L"url(#" + wsStyleId + L")"); return; } } default: - arAttributes.push_back({L"fill", L"none"}); + arAttributes.Add(L"fill", L"none"); } } @@ -705,12 +802,6 @@ namespace MetaFile else oOldTransform.Copy(m_pParser->GetTransform()); -// if (std::fabs(oOldTransform.M11) > MAXTRANSFORMSCALE || std::fabs(oOldTransform.M22) > MAXTRANSFORMSCALE) -// { -// oOldTransform.M11 /= std::fabs(oOldTransform.M11); -// oOldTransform.M22 /= std::fabs(oOldTransform.M22); -// } - bool bScale = false, bTranslate = false; if (oOldTransform.M11 != 1 || oOldTransform.M22 != 1) @@ -734,7 +825,7 @@ namespace MetaFile if (bScale && !bTranslate) { - wsValue = L"scale(" + ConvertToWString(oOldTransform.M11) + L',' + ConvertToWString(oOldTransform.M22) + L')'; + wsValue = L"scale(" + ConvertToWString(oOldTransform.M11) + L',' + ConvertToWString(oOldTransform.M22) + L')'; } else if (bTranslate && !bScale) { @@ -742,18 +833,18 @@ namespace MetaFile } else if (bScale && bTranslate) { - wsValue = L"matrix(" + ConvertToWString(oOldTransform.M11) + L',' + - ConvertToWString(oOldTransform.M12) + L',' + - ConvertToWString(oOldTransform.M21) + L',' + - ConvertToWString(oOldTransform.M22) + L',' + - ConvertToWString(oOldTransform.Dx) + L',' + ConvertToWString(oOldTransform.Dy) + L')'; + wsValue = L"matrix(" + ConvertToWString(oOldTransform.M11) + L',' + + ConvertToWString(oOldTransform.M12) + L',' + + ConvertToWString(oOldTransform.M21) + L',' + + ConvertToWString(oOldTransform.M22) + L',' + + ConvertToWString(oOldTransform.Dx) + L',' + ConvertToWString(oOldTransform.Dy) + L')'; } else return; if (NULL != pFoundTransform) pFoundTransform->second.insert(0, wsValue + L' '); else - arAttributes.push_back({L"transform", wsValue}); + arAttributes.Add(L"transform", wsValue); } void CInterpretatorSvgBase::AddClip() @@ -763,13 +854,13 @@ namespace MetaFile m_bUpdatedClip = true; } - + bool CInterpretatorSvgBase::OpenClip() { CloseClip(); - CClip *pClip = m_pParser->GetClip(); - + const CClip *pClip = m_pParser->GetClip(); + if (NULL == pClip || pClip->Empty()) return false; @@ -777,7 +868,7 @@ namespace MetaFile WriteNodeBegin(L"g", {{L"clip-path", L"url(#" + m_oClip.GetClipId() + L')'}}); m_oClip.BeginClip(); - + return true; } @@ -793,7 +884,101 @@ namespace MetaFile void CInterpretatorSvgBase::AddNoneFill(NodeAttributes &arAttributes) const { - arAttributes.push_back({L"fill", L"none"}); + arAttributes.Add(L"fill", L"none"); + } + + void CInterpretatorSvgBase::AddShapeRendering(NodeAttributes& arAttributes) const + { + switch (m_eShapeRendering) + { + case EShapeRendering::OptimizeSpeed: + { + arAttributes.Add(L"shape-rendering", L"optimizeSpeed"); + break; + } + case EShapeRendering::CrispEdges: + { + arAttributes.Add(L"shape-rendering", L"crispEdges"); + break; + } + case EShapeRendering::GeometricPrecision: + { + arAttributes.Add(L"shape-rendering", L"geometricPrecision"); + break; + } + default: + break; + } + } + + TPointD GetFirstPoint(const CPathCommandBase* pPathCommand) + { + if (NULL == pPathCommand) + return {0., 0.}; + + switch (pPathCommand->GetType()) + { + case EPathCommandType::PATH_COMMAND_MOVETO: + { + CPathCommandMoveTo* pMoveTo{(CPathCommandMoveTo*)pPathCommand}; + return {pMoveTo->GetX(), pMoveTo->GetY()}; + } + case EPathCommandType::PATH_COMMAND_LINETO: + { + CPathCommandLineTo* pLineTo{(CPathCommandLineTo*)pPathCommand}; + return {pLineTo->GetX(), pLineTo->GetY()}; + } + default: + return {0., 0.}; + } + } + + void CInterpretatorSvgBase::AddLineCaps(NodeAttributes& arAttributes, const CPath* pMainPath) + { + if (NULL == m_pParser || NULL == m_pParser->GetPen() || NULL == pMainPath) + return; + + const IPen *pPen = m_pParser->GetPen(); + const std::vector arCommands{pMainPath->GetCommands()}; + const CLineCapData* pStartLineCap = dynamic_cast(pPen->GetStartLineCap()); + + if (NULL != pStartLineCap) + { + double dAngle = 0.; + + if (arCommands.size() > 1) + { + const TPointD oFirstPoint {GetFirstPoint(arCommands[0])}; + const TPointD oSecondPoint{GetFirstPoint(arCommands[1])}; + + dAngle = (atan2((oSecondPoint.Y - oFirstPoint.Y), (oSecondPoint.X - oFirstPoint.X))) / M_PI * 180. + 90.; + } + + const std::wstring wsStartLineCapId{CreateLineCap(pStartLineCap, dAngle)}; + + if (!wsStartLineCapId.empty()) + arAttributes.Add(L"marker-start", L"url(#" + wsStartLineCapId + L')'); + } + + const CLineCapData* pEndLineCap = dynamic_cast(pPen->GetEndLineCap()); + + if (NULL != pEndLineCap) + { + double dAngle = 0.; + + if (arCommands.size() > 1) + { + const TPointD oFirstPoint {GetFirstPoint(arCommands[arCommands.size() - 1])}; + const TPointD oSecondPoint{GetFirstPoint(arCommands[arCommands.size() - 2])}; + + dAngle = (atan2((oSecondPoint.Y - oFirstPoint.Y), (oSecondPoint.X - oFirstPoint.X))) / M_PI * 180. + 90.; + } + + const std::wstring wsEndLineCapId{CreateLineCap(pEndLineCap, dAngle)}; + + if (!wsEndLineCapId.empty()) + arAttributes.Add(L"marker-end", L"url(#" + wsEndLineCapId + L')'); + } } TPointD CInterpretatorSvgBase::GetCutPos() const @@ -804,7 +989,7 @@ namespace MetaFile return TPointD(m_oViewport.dLeft, m_oViewport.dRight); } - std::wstring CInterpretatorSvgBase::CreatePath(const CPath& oPath, const TXForm *pTransform) + std::wstring CInterpretatorSvgBase::CreatePath(const CPath& oPath, const TXForm *pTransform) const { if (NULL == m_pParser || oPath.Empty()) return std::wstring(); @@ -871,9 +1056,9 @@ namespace MetaFile oTransform.Apply(oPoint2.X, oPoint2.Y); oTransform.Apply(oPointE.X, oPointE.Y); - wsValue += ConvertToWString(oPoint1.X) + L',' + ConvertToWString(oPoint1.Y) + L' ' + - ConvertToWString(oPoint2.X) + L',' + ConvertToWString(oPoint2.Y) + L' ' + - ConvertToWString(oPointE.X) + L',' + ConvertToWString(oPointE.Y) + L' '; + wsValue += ConvertToWString(oPoint1.X) + L',' + ConvertToWString(oPoint1.Y) + L' ' + + ConvertToWString(oPoint2.X) + L',' + ConvertToWString(oPoint2.Y) + L' ' + + ConvertToWString(oPointE.X) + L',' + ConvertToWString(oPointE.Y) + L' '; break; } @@ -924,24 +1109,17 @@ namespace MetaFile if (NULL == m_pParser || NULL == m_pParser->GetBrush()) return std::wstring(); - double dStrokeWidth = 1. / m_pParser->GetTransform()->M11; + double dStrokeWidth = 1. / m_pParser->GetTransform().M11; if (NULL != m_pParser->GetPen()) { dStrokeWidth = std::fabs(m_pParser->GetPen()->GetWidth()); - - if (0.0 == dStrokeWidth || (1.0 == dStrokeWidth && PS_COSMETIC == (m_pParser->GetPen()->GetStyle() & PS_TYPE_MASK))) - dStrokeWidth = 1. / m_pParser->GetTransform()->M11; + + if (Equals(0, dStrokeWidth) || PS_COSMETIC == (m_pParser->GetPen()->GetStyle() & PS_TYPE_MASK)) + dStrokeWidth = 1; } - if (0 != m_oViewport.GetWidth() && 0 != m_oSizeWindow.X) - dStrokeWidth *= m_oViewport.GetWidth() / m_oSizeWindow.X; - - std::wstring wsStrokeColor = L"rgba(" + INTCOLOR_TO_RGB(m_pParser->GetBrush()->GetColor()) + L"," + ConvertToWString(m_pParser->GetBrush()->GetAlpha(), 0) + L")"; - std::wstring wsBgColor; - - if (TRANSPARENT != m_pParser->GetTextBgMode()) - wsBgColor += L"rgb(" + INTCOLOR_TO_RGB(m_pParser->GetTextBgColor())+ L")"; + std::wstring wsStrokeColor = CalculateColor(m_pParser->GetBrush()->GetColor(), m_pParser->GetBrush()->GetAlpha()); CHatchGenerator oHatchGenerator; @@ -950,7 +1128,7 @@ namespace MetaFile oHatchGenerator.SetStroke(dStrokeWidth, m_pParser->GetBrush()->GetColor(), m_pParser->GetBrush()->GetAlpha()); if (TRANSPARENT != m_pParser->GetTextBgMode()) - oHatchGenerator.SetBKColor(m_pParser->GetTextBgColor()); + oHatchGenerator.SetBackground(m_pParser->GetTextBgColor()); if (oHatchGenerator.GenerateHatch()) { @@ -963,7 +1141,7 @@ namespace MetaFile return std::wstring(); } - std::wstring CInterpretatorSvgBase::CreateDibPatternStyle(IBrush *pBrush) + std::wstring CInterpretatorSvgBase::CreateDibPatternStyle(const IBrush *pBrush) { if (NULL == m_pParser || NULL == pBrush) return std::wstring(); @@ -1016,19 +1194,16 @@ namespace MetaFile std::wstring wsImageDataW = NSFile::CUtf8Converter::GetUnicodeFromCharPtr(pImageData, (LONG)nImageSize); - double dStrokeWidth = 1. / m_pParser->GetTransform()->M11; + double dStrokeWidth = 1. / m_pParser->GetTransform().M11; if (NULL != m_pParser->GetPen()) { dStrokeWidth = std::fabs(m_pParser->GetPen()->GetWidth()); - - if (0.0 == dStrokeWidth || (1.0 == dStrokeWidth && PS_COSMETIC == (m_pParser->GetPen()->GetStyle() & PS_TYPE_MASK))) - dStrokeWidth = 1. / m_pParser->GetTransform()->M11; + + if (Equals(0, dStrokeWidth) || PS_COSMETIC == (m_pParser->GetPen()->GetStyle() & PS_TYPE_MASK)) + dStrokeWidth = 1; } - if (0 != m_oViewport.GetWidth() && 0 != m_oSizeWindow.X) - dStrokeWidth *= m_oViewport.GetWidth() / m_oSizeWindow.X; - std::wstring wsWidth = ConvertToWString(dStrokeWidth * unWidth); std::wstring wsHeight = ConvertToWString(dStrokeWidth * unHeight); @@ -1042,7 +1217,7 @@ namespace MetaFile return wsStyleId; } - std::wstring CInterpretatorSvgBase::CreatePatternStyle(IBrush *pBrush) + std::wstring CInterpretatorSvgBase::CreatePatternStyle(const IBrush *pBrush) { if (NULL == m_pParser || NULL == pBrush) return std::wstring(); @@ -1092,23 +1267,30 @@ namespace MetaFile return wsStyleId; } - std::wstring CInterpretatorSvgBase::CreateGradient(IBrush *pBrush) + std::wstring CInterpretatorSvgBase::CreateGradient(const IBrush* pBrush) { if (pBrush == NULL) return std::wstring(); std::wstring wsStyleId; - if (BS_LINEARGRADIENT == pBrush->GetStyle() || - BS_RECTGRADIENT == pBrush->GetStyle() || - BS_PATHGRADIENT == pBrush->GetStyle()) + if (BS_LINEARGRADIENT == pBrush->GetStyle() || + BS_RECTGRADIENT == pBrush->GetStyle() || + BS_PATHGRADIENT == pBrush->GetStyle()) { wsStyleId = L"LINEARGRADIENT_" + ConvertToWString(++m_unNumberDefs, 0); - m_wsDefs += L"" + - L"GetColor()) + L")\"/>" + - L"GetColor2()) + L")\"/>" + - L""; + m_wsDefs += L""; + + std::vector arColors; + std::vector arPositions; + pBrush->GetGradientColors(arColors, arPositions); + + for (unsigned int unIndex = 0; unIndex < arColors.size(); ++unIndex) + m_wsDefs += L""; + + m_wsDefs += L""; return wsStyleId; } @@ -1139,8 +1321,8 @@ namespace MetaFile } m_wsDefs += L"" + - L"GetColor()) + L")\"/>" + - L"GetColor2()) + L")\"/>" + + L"GetColor(), pBrush->GetAlpha() ) + L"\"/>" + + L"GetColor2(), pBrush->GetAlpha2()) + L"\"/>" + L""; return wsStyleId; @@ -1149,11 +1331,50 @@ namespace MetaFile return std::wstring(); } - CHatchGenerator::CHatchGenerator() - : m_nHatchStyle(-1), m_unNumber(0), m_nBKColor(-1) + std::wstring CInterpretatorSvgBase::CreateLineCap(const CLineCapData* pLineCap, const double& dAngle) { + if (NULL == pLineCap) + return std::wstring(); + + CustomLineCapDataType enLineCapDataType = pLineCap->GetType(); + + if (CustomLineCapDataType::CustomLineCapDataTypeDefault == enLineCapDataType) + { + const TEmfPlusCustomLineCapData* pCustomLineCap = dynamic_cast(pLineCap); + + if (NULL == pCustomLineCap) + return std::wstring(); + + const std::wstring wsPath = CreatePath(*pCustomLineCap->pPath); + + if (wsPath.empty()) + return std::wstring(); + + const std::wstring wsMarkerId {L"CUSTOM_MARKER_" + std::to_wstring(++m_unNumberDefs)}; + const TRectD oPathBounds{pCustomLineCap->pPath->GetBounds()}; + const double dWidth {std::abs(oPathBounds.Right - oPathBounds.Left)}; + const double dHeight {std::abs(oPathBounds.Bottom - oPathBounds.Top)}; + const std::wstring wsWidth {ConvertToWString(dWidth)}; + const std::wstring wsHeight {ConvertToWString(dHeight)}; + const std::wstring wsViewBox {L"viewBox=\"" + ConvertToWString(oPathBounds.Left) + L' ' + ConvertToWString(oPathBounds.Top) + + L' ' + wsWidth + L' ' + wsHeight + L'\"'}; + + const double dRefY = -dHeight * (std::min)(3. / dWidth, 3. / dHeight); + + m_wsDefs += L""; + + return wsMarkerId; + } + + return std::wstring(); } + CHatchGenerator::CHatchGenerator() + : m_nHatchStyle(-1), m_unNumber(0), m_chStrokeAlpha(255), m_nBackgroundColor(-1), m_chBackgroundAlpha(255) + {} + void CHatchGenerator::SetSize(double dWidth, double dHeight) { m_dWidth = dWidth; @@ -1168,14 +1389,15 @@ namespace MetaFile void CHatchGenerator::SetStroke(double dWidth, int nColor, unsigned char chAlpha) { - m_dStrokeWidth = dWidth; - m_nStrokeColor = nColor; - m_chAlpha = chAlpha; + m_dStrokeWidth = dWidth; + m_nStrokeColor = nColor; + m_chStrokeAlpha = chAlpha; } - void CHatchGenerator::SetBKColor(int nColor) + void CHatchGenerator::SetBackground(int nColor, unsigned char chAlpha) { - m_nBKColor = nColor; + m_nBackgroundColor = nColor; + m_chBackgroundAlpha = chAlpha; } bool CHatchGenerator::GenerateHatch() @@ -1186,7 +1408,7 @@ namespace MetaFile if (!GenerateStartPattern()) return false; - GenerateBK(); + GenerateBackground(); switch(m_nHatchStyle) { @@ -1637,7 +1859,7 @@ namespace MetaFile return true; } - std::wstring CHatchGenerator::GetPatternId() + std::wstring CHatchGenerator::GetPatternId() const { if (mHatchStyles.end() == mHatchStyles.find(m_nHatchStyle)) return L""; @@ -1652,12 +1874,15 @@ namespace MetaFile void CHatchGenerator::AddLine(const TPointD& oPoint1, const TPointD& oPoint2) { + if (0 == m_chStrokeAlpha) + return; + m_oStringBuilder.WriteNodeBegin(L"line", true); m_oStringBuilder.WriteAttribute(L"x1", ConvertToWString(m_dStrokeWidth * oPoint1.X)); m_oStringBuilder.WriteAttribute(L"y1", ConvertToWString(m_dStrokeWidth * oPoint1.Y)); m_oStringBuilder.WriteAttribute(L"x2", ConvertToWString(m_dStrokeWidth * oPoint2.X)); m_oStringBuilder.WriteAttribute(L"y2", ConvertToWString(m_dStrokeWidth * oPoint2.Y)); - m_oStringBuilder.WriteAttribute(L"stroke", L"rgb(" + INTCOLOR_TO_RGB(m_nStrokeColor) + L')'); + m_oStringBuilder.WriteAttribute(L"stroke", CalculateColor(m_nStrokeColor, m_chStrokeAlpha)); m_oStringBuilder.WriteAttribute(L"stroke-width", ConvertToWString(m_dStrokeWidth)); m_oStringBuilder.WriteNodeEnd(L"line", true, true); } @@ -1670,12 +1895,15 @@ namespace MetaFile void CHatchGenerator::AddPoint(const TPointD& oPoint) { + if (0 == m_chStrokeAlpha) + return; + m_oStringBuilder.WriteNodeBegin(L"line", true); m_oStringBuilder.WriteAttribute(L"x1", ConvertToWString(m_dStrokeWidth * oPoint.X)); m_oStringBuilder.WriteAttribute(L"y1", ConvertToWString(m_dStrokeWidth * oPoint.Y)); m_oStringBuilder.WriteAttribute(L"x2", ConvertToWString(m_dStrokeWidth * (oPoint.X + 1))); m_oStringBuilder.WriteAttribute(L"y2", ConvertToWString(m_dStrokeWidth * oPoint.Y)); - m_oStringBuilder.WriteAttribute(L"stroke", L"rgb(" + INTCOLOR_TO_RGB(m_nStrokeColor) + L')'); + m_oStringBuilder.WriteAttribute(L"stroke", CalculateColor(m_nStrokeColor, m_chStrokeAlpha)); m_oStringBuilder.WriteAttribute(L"stroke-width", ConvertToWString(m_dStrokeWidth)); m_oStringBuilder.WriteNodeEnd(L"line", true, true); } @@ -1704,9 +1932,9 @@ namespace MetaFile return true; } - void CHatchGenerator::GenerateBK() + void CHatchGenerator::GenerateBackground() { - if (0 > m_nBKColor) + if (0 > m_nBackgroundColor || 0 == m_chBackgroundAlpha) return; m_oStringBuilder.WriteNodeBegin(L"rect", true); @@ -1714,7 +1942,7 @@ namespace MetaFile m_oStringBuilder.WriteAttribute(L"y", L"0"); m_oStringBuilder.WriteAttribute(L"width", ConvertToWString(m_dStrokeWidth * 8)); m_oStringBuilder.WriteAttribute(L"height", ConvertToWString(m_dStrokeWidth * 8)); - m_oStringBuilder.WriteAttribute(L"fill", L"rgb(" + INTCOLOR_TO_RGB(m_nBKColor) + L')'); + m_oStringBuilder.WriteAttribute(L"fill", CalculateColor(m_nBackgroundColor, m_chBackgroundAlpha)); m_oStringBuilder.WriteNodeEnd(L"rect", true, true); } @@ -1821,4 +2049,50 @@ namespace MetaFile return m_arValues.front().m_wsId; } + std::wstring CalculateColor(unsigned int unColor, BYTE uchAlpha) + { + if (0 == uchAlpha) + return L"none"; + + if (255 == uchAlpha) + return L"rgb(" + INTCOLOR_TO_RGB(unColor) + L')'; + + return L"rgba(" + INTCOLOR_TO_RGB(unColor) + L", " + ConvertToWString((double)uchAlpha / 255., 3) + L')'; + } + + std::wstring CalculateColor(BYTE uchRed, BYTE uchGreen, BYTE uchBlue, BYTE uchAlpha) + { + if (0 == uchAlpha) + return L"none"; + + if (255 == uchAlpha) + return L"rgb(" + std::to_wstring(uchRed) + L", " + std::to_wstring(uchGreen) + L", " + std::to_wstring(uchBlue) + L')'; + + return L"rgba(" + std::to_wstring(uchRed) + L", " + std::to_wstring(uchGreen) + L", " + std::to_wstring(uchBlue) + L", " + ConvertToWString((double)uchAlpha / 255., 3) + L')'; + } + + std::wstring CalculateColor(unsigned int unColor) + { + BYTE chAlpha = unColor >> 24; + + return CalculateColor(unColor, chAlpha); + } + + void NormalizeRect(TRectD& oRect) + { + if (oRect.Right < oRect.Left) + std::swap(oRect.Right, oRect.Left); + + if (oRect.Bottom < oRect.Top) + std::swap(oRect.Bottom, oRect.Top); + } + + TRectD TranslateRect(const TRectL& oRect) + { + TRectD oNewRect(oRect.Left, oRect.Top, oRect.Right, oRect.Bottom); + + NormalizeRect(oNewRect); + + return oNewRect; + } } diff --git a/DesktopEditor/raster/Metafile/Wmf/WmfInterpretator/CInterpretatorSvgBase.h b/DesktopEditor/raster/Metafile/Wmf/WmfInterpretator/CInterpretatorSvgBase.h index e84b4cd5218..6061823c317 100644 --- a/DesktopEditor/raster/Metafile/Wmf/WmfInterpretator/CInterpretatorSvgBase.h +++ b/DesktopEditor/raster/Metafile/Wmf/WmfInterpretator/CInterpretatorSvgBase.h @@ -15,11 +15,11 @@ namespace MetaFile void SetSize(double dWidth, double dHeight); void SetStyleId(unsigned int unStyleId, unsigned int unNumber); void SetStroke(double dWidth, int nColor, unsigned char chAlpha = 255); - void SetBKColor(int nColor); + void SetBackground(int nColor, unsigned char chAlpha = 255); bool GenerateHatch(); - std::wstring GetPatternId(); + std::wstring GetPatternId() const; std::wstring GetPattern(); private: void AddLine(const TPointD& oPoint1, const TPointD& oPoint2); @@ -28,20 +28,21 @@ namespace MetaFile void AddPoints(const std::vector& arPoints); bool GenerateStartPattern(); - void GenerateBK(); + void GenerateBackground(); void GenerateEndPattern(); int m_nHatchStyle; unsigned int m_unNumber; - double m_dStrokeWidth; - int m_nStrokeColor; - unsigned char m_chAlpha; + double m_dStrokeWidth; + int m_nStrokeColor; + unsigned char m_chStrokeAlpha; double m_dWidth; double m_dHeight; - int m_nBKColor; + int m_nBackgroundColor; + unsigned char m_chBackgroundAlpha; NSStringUtils::CStringBuilder m_oStringBuilder; }; @@ -61,8 +62,8 @@ namespace MetaFile void AddClipValue(const std::wstring& wsId, const std::wstring& wsValue, int nClipMode = RGN_AND); - inline std::wstring GetClip() const; - inline std::wstring GetClipId() const; + std::wstring GetClip() const; + std::wstring GetClipId() const; private: struct TClipValue { @@ -76,6 +77,14 @@ namespace MetaFile bool m_bStartClip; }; + enum class EShapeRendering + { + Auto, + OptimizeSpeed, + CrispEdges, + GeometricPrecision + }; + class CInterpretatorSvgBase : public IOutputDevice { public: @@ -89,6 +98,8 @@ namespace MetaFile void SetXmlWriter(XmlUtils::CXmlWriter* pXmlWriter); XmlUtils::CXmlWriter* GetXmlWriter(); + void SetShapeRendering(EShapeRendering eShapeRenderingType); + std::wstring GetFile(); void IncludeSvg(const std::wstring& wsSvg, const TRectD& oRect, const TRectD& oClipRect, TXForm *pTransform); private: @@ -97,6 +108,8 @@ namespace MetaFile void WriteNodeEnd(const std::wstring& wsNodeName); void WriteText(const std::wstring& wsText, const TPointD& oCoord, const TRectL& oBounds = TRectL(), const TPointD& oScale = TPointD(1, 1), const std::vector& arDx = {}); + void DrawBitmap(double dX, double dY, double dW, double dH, BYTE* pBuffer, unsigned int unWidth, unsigned int unHeight) override; + void ResetClip() override; void IntersectClip(const TRectD& oClip) override; void ExcludeClip(const TRectD& oClip, const TRectD& oBB) override; @@ -112,15 +125,18 @@ namespace MetaFile void CloseClip(); void AddNoneFill(NodeAttributes &arAttributes) const; + void AddShapeRendering(NodeAttributes &arAttributes) const; + + void AddLineCaps(NodeAttributes &arAttributes, const CPath* pMainPath); TPointD GetCutPos() const; - std::wstring CreatePath(const CPath& oPath, const TXForm* pTransform = NULL); + std::wstring CreatePath(const CPath& oPath, const TXForm* pTransform = NULL) const; std::wstring CreateHatchStyle(unsigned int unHatchStyle, double dWidth, double dHeight); - std::wstring CreateDibPatternStyle(IBrush *pBrush); - std::wstring CreatePatternStyle(IBrush *pBrush); - std::wstring CreateGradient(IBrush *pBrush); - + std::wstring CreateDibPatternStyle(const IBrush* pBrush); + std::wstring CreatePatternStyle(const IBrush* pBrush); + std::wstring CreateGradient(const IBrush *pBrush); + std::wstring CreateLineCap(const CLineCapData* pLineCap, const double& dAngle); private: TSvgViewport m_oViewport; TPointD m_oSizeWindow; @@ -136,9 +152,17 @@ namespace MetaFile bool m_bUpdatedClip; CSvgClip m_oClip; + EShapeRendering m_eShapeRendering; + friend class CEmfInterpretatorSvg; friend class CWmfInterpretatorSvg; }; + + std::wstring CalculateColor(unsigned int unColor); + std::wstring CalculateColor(unsigned int unColor, BYTE uchAlpha); + std::wstring CalculateColor(BYTE uchRed, BYTE uchGreen, BYTE uchBlue, BYTE uchAlpha); + void NormalizeRect(TRectD& oRect); + TRectD TranslateRect(const TRectL &oRect); } #endif // CINTERPRETATORSVGBASE_H diff --git a/DesktopEditor/raster/Metafile/Wmf/WmfInterpretator/CWmfInterpretatorRender.cpp b/DesktopEditor/raster/Metafile/Wmf/WmfInterpretator/CWmfInterpretatorRender.cpp index 3de54d43779..ac5d84cddd6 100644 --- a/DesktopEditor/raster/Metafile/Wmf/WmfInterpretator/CWmfInterpretatorRender.cpp +++ b/DesktopEditor/raster/Metafile/Wmf/WmfInterpretator/CWmfInterpretatorRender.cpp @@ -29,7 +29,7 @@ namespace MetaFile } void CWmfInterpretatorRender::DrawString(std::wstring &wsText, unsigned int unCharsCount, double dX, double dY, double *pDx, - int iGraphicsMode, double dXScale, double dYScale) + int iGraphicsMode, double dXScale, double dYScale) { if (NULL != m_pMetaFileRenderer) m_pMetaFileRenderer->DrawString(wsText, unCharsCount, dX, dY, pDx, iGraphicsMode, dXScale, dYScale); @@ -147,4 +147,28 @@ namespace MetaFile { return m_pMetaFileRenderer; } + + void CWmfInterpretatorRender::HANDLE_META_EXCLUDECLIPRECT(short shLeft, short shTop, short shRight, short shBottom) + { + if (NULL != m_pMetaFileRenderer) + m_pMetaFileRenderer->NeedUpdateClip(); + } + + void CWmfInterpretatorRender::HANDLE_META_INTERSECTCLIPRECT(short shLeft, short shTop, short shRight, short shBottom) + { + if (NULL != m_pMetaFileRenderer) + m_pMetaFileRenderer->NeedUpdateClip(); + } + + void CWmfInterpretatorRender::HANDLE_META_OFFSETCLIPRGN(short shOffsetX, short shOffsetY) + { + if (NULL != m_pMetaFileRenderer) + m_pMetaFileRenderer->NeedUpdateClip(); + } + + void CWmfInterpretatorRender::HANDLE_META_RESTOREDC() + { + if (NULL != m_pMetaFileRenderer) + m_pMetaFileRenderer->NeedUpdateClip(); + } } diff --git a/DesktopEditor/raster/Metafile/Wmf/WmfInterpretator/CWmfInterpretatorRender.h b/DesktopEditor/raster/Metafile/Wmf/WmfInterpretator/CWmfInterpretatorRender.h index df27c44a5c3..5768557914d 100644 --- a/DesktopEditor/raster/Metafile/Wmf/WmfInterpretator/CWmfInterpretatorRender.h +++ b/DesktopEditor/raster/Metafile/Wmf/WmfInterpretator/CWmfInterpretatorRender.h @@ -19,7 +19,7 @@ namespace MetaFile void DrawBitmap(double dX, double dY, double dW, double dH, BYTE* pBuffer, unsigned int unWidth, unsigned int unHeight) override; void DrawString(std::wstring& wsText, unsigned int unCharsCount, double dX, double dY, double* pDx, - int iGraphicsMode = 1, double dXScale = 1, double dYScale = 1) override; + int iGraphicsMode = 1, double dXScale = 1, double dYScale = 1) override; void DrawDriverString(const std::wstring& wsString, const std::vector& arPoints) override; @@ -101,13 +101,13 @@ namespace MetaFile //----------------------------------------------------------- // 2.3.5 State records //----------------------------------------------------------- - void HANDLE_META_EXCLUDECLIPRECT(short shLeft, short shTop, short shRight, short shBottom) override {}; - void HANDLE_META_INTERSECTCLIPRECT(short shLeft, short shTop, short shRight, short shBottom) override {}; + void HANDLE_META_EXCLUDECLIPRECT(short shLeft, short shTop, short shRight, short shBottom) override; + void HANDLE_META_INTERSECTCLIPRECT(short shLeft, short shTop, short shRight, short shBottom) override; void HANDLE_META_MOVETO(short shX, short shY) override {}; - void HANDLE_META_OFFSETCLIPRGN(short shOffsetX, short shOffsetY) override {}; + void HANDLE_META_OFFSETCLIPRGN(short shOffsetX, short shOffsetY) override; void HANDLE_META_OFFSETVIEWPORTORG(short shXOffset, short shYOffset) override {}; void HANDLE_META_OFFSETWINDOWORG(short shXOffset, short shYOffset) override {}; - void HANDLE_META_RESTOREDC() override {}; + void HANDLE_META_RESTOREDC() override; void HANDLE_META_SAVEDC() override {}; void HANDLE_META_SCALEVIEWPORTEXT(short yDenom, short yNum, short xDenom, short xNum) override {}; void HANDLE_META_SCALEWINDOWEXT(short yDenom, short yNum, short xDenom, short xNum) override {}; diff --git a/DesktopEditor/raster/Metafile/Wmf/WmfInterpretator/CWmfInterpretatorSvg.cpp b/DesktopEditor/raster/Metafile/Wmf/WmfInterpretator/CWmfInterpretatorSvg.cpp index 34913956a51..0201d9d9dd0 100644 --- a/DesktopEditor/raster/Metafile/Wmf/WmfInterpretator/CWmfInterpretatorSvg.cpp +++ b/DesktopEditor/raster/Metafile/Wmf/WmfInterpretator/CWmfInterpretatorSvg.cpp @@ -28,52 +28,51 @@ namespace MetaFile m_pXmlWriter->WriteAttribute(L"xmlns", L"http://www.w3.org/2000/svg"); m_pXmlWriter->WriteAttribute(L"xmlns:xlink", L"http://www.w3.org/1999/xlink"); - TRectL *pBounds = m_pParser->GetDCBounds(); + const TRectL& oBounds{m_pParser->GetDCBounds()}; - m_oViewport.dLeft = pBounds->Left; - m_oViewport.dTop = pBounds->Top; - m_oViewport.dRight = pBounds->Right; - m_oViewport.dBottom = pBounds->Bottom; + m_oViewport.dLeft = std::min(oBounds.Left, oBounds.Right ); + m_oViewport.dTop = std::min(oBounds.Top, oBounds.Bottom); + m_oViewport.dRight = std::max(oBounds.Left, oBounds.Right ); + m_oViewport.dBottom = std::max(oBounds.Top, oBounds.Bottom); UpdateSize(); - if (m_oViewport.GetWidth() != 0) - m_pXmlWriter->WriteAttribute(L"width", ConvertToWString(m_oViewport.GetWidth())); - - if (m_oViewport.GetHeight() != 0) - m_pXmlWriter->WriteAttribute(L"height", ConvertToWString(m_oViewport.GetHeight())); - - double dXScale = 1, dYScale = 1, dXTranslate = 0, dYTranslate = 0; + double dXScale = 1., dYScale = 1.; if (0 != m_oSizeWindow.X) - { dXScale = m_oSizeWindow.X / m_oViewport.GetWidth(); - dXTranslate = (m_oViewport.GetWidth()) / 2 * std::abs(dXScale - 1); - - if (dXScale < 1) - dXTranslate = -dXTranslate; - } if (0 != m_oSizeWindow.Y) - { dYScale = m_oSizeWindow.Y / m_oViewport.GetHeight(); - dYTranslate = (m_oViewport.GetHeight()) / 2 * std::abs(dYScale - 1); - if (dYScale < 1) - dYTranslate = -dYTranslate; - } + if (m_oViewport.GetWidth() != 0) + m_pXmlWriter->WriteAttribute(L"width", ConvertToWString(m_oViewport.GetWidth() * dXScale)); - if (1 != dXScale || 1 != dYScale) - m_pXmlWriter->WriteAttribute(L"transform", L"matrix(" + std::to_wstring(dXScale) + L",0,0," + std::to_wstring(dYScale) + L',' + ConvertToWString(dXTranslate) + L',' + ConvertToWString(dYTranslate) + L')'); + if (m_oViewport.GetHeight() != 0) + m_pXmlWriter->WriteAttribute(L"height", ConvertToWString(m_oViewport.GetHeight() * dYScale)); m_pXmlWriter->WriteNodeEnd(L"svg", true, false); + + if (!Equals(1., dXScale) || !Equals(1., dYScale)) + { + m_pXmlWriter->WriteNodeBegin(L"g", true); + + m_pXmlWriter->WriteAttribute(L"transform", L"scale(" + ConvertToWString(dXScale) + L',' + ConvertToWString(dYScale) + L')'); + + m_pXmlWriter->WriteNodeEnd(L"g", true, false); + } } void CWmfInterpretatorSvg::HANDLE_META_EOF() { CloseClip(); + if (!m_wsDefs.empty()) m_pXmlWriter->WriteString(L"" + m_wsDefs + L""); + + if (!Equals(m_oSizeWindow.X, m_oViewport.GetWidth()) || !Equals(m_oSizeWindow.Y, m_oViewport.GetHeight())) + m_pXmlWriter->WriteNodeEnd(L"g", false, false); + m_pXmlWriter->WriteNodeEnd(L"svg", false, false); } @@ -111,6 +110,7 @@ namespace MetaFile AddStroke(arAttributes); AddNoneFill(arAttributes); + AddShapeRendering(arAttributes); AddTransform(arAttributes); AddClip(); @@ -137,6 +137,7 @@ namespace MetaFile {L"ry", ConvertToWString((oNewRect.Bottom - oNewRect.Top) / 2)}}; AddStroke(arAttributes); AddFill(arAttributes); + AddShapeRendering(arAttributes); AddTransform(arAttributes); AddClip(); @@ -145,68 +146,18 @@ namespace MetaFile void CWmfInterpretatorSvg::HANDLE_META_EXTTEXTOUT(short shY, short shX, short shStringLength, unsigned short ushFwOptions, const TRectL &oRectangle, unsigned char *pString, short *pDx) { - IFont* pFont = NULL; + const IFont* pFont = NULL; if (NULL != m_pParser) pFont = m_pParser->GetFont(); - NSStringExt::CConverter::ESingleByteEncoding eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_DEFAULT;; - if (pFont) - { - // Соответствие Charset -> Codepage: http://support.microsoft.com/kb/165478 - // http://msdn.microsoft.com/en-us/library/cc194829.aspx - // Charset Name Charset Value(hex) Codepage number - // ------------------------------------------------------ - // - // DEFAULT_CHARSET 1 (x01) - // SYMBOL_CHARSET 2 (x02) - // OEM_CHARSET 255 (xFF) - // ANSI_CHARSET 0 (x00) 1252 - // RUSSIAN_CHARSET 204 (xCC) 1251 - // EASTEUROPE_CHARSET 238 (xEE) 1250 - // GREEK_CHARSET 161 (xA1) 1253 - // TURKISH_CHARSET 162 (xA2) 1254 - // BALTIC_CHARSET 186 (xBA) 1257 - // HEBREW_CHARSET 177 (xB1) 1255 - // ARABIC _CHARSET 178 (xB2) 1256 - // SHIFTJIS_CHARSET 128 (x80) 932 - // HANGEUL_CHARSET 129 (x81) 949 - // GB2313_CHARSET 134 (x86) 936 - // CHINESEBIG5_CHARSET 136 (x88) 950 - // THAI_CHARSET 222 (xDE) 874 - // JOHAB_CHARSET 130 (x82) 1361 - // VIETNAMESE_CHARSET 163 (xA3) 1258 - - switch (pFont->GetCharSet()) - { - default: - case DEFAULT_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_DEFAULT; break; - case SYMBOL_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_DEFAULT; break; - case ANSI_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1252; break; - case RUSSIAN_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1251; break; - case EASTEUROPE_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1250; break; - case GREEK_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1253; break; - case TURKISH_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1254; break; - case BALTIC_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1257; break; - case HEBREW_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1255; break; - case ARABIC_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1256; break; - case SHIFTJIS_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP932; break; - case HANGEUL_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP949; break; - case 134/*GB2313_CHARSET*/: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP936; break; - case CHINESEBIG5_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP950; break; - case THAI_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP874; break; - case JOHAB_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1361; break; - case VIETNAMESE_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1258; break; - } - } - - std::wstring wsText = NSStringExt::CConverter::GetUnicodeFromSingleByteString((const unsigned char*)pString, (long)shStringLength, eCharSet); + const std::wstring wsText{ConvertToUnicode(pString, (long)shStringLength, (NULL != pFont) ? pFont->GetCharSet() : DEFAULT_CHARSET)}; TPointD oScale((m_pParser->IsWindowFlippedX()) ? -1 : 1, (m_pParser->IsWindowFlippedY()) ? -1 : 1); std::vector arDx(0); - if (NULL != pDx) + if (NULL != pDx && shStringLength == wsText.length()) arDx = std::vector(pDx, pDx + wsText.length()); WriteText(wsText, TPointD(shX, shY), oRectangle, oScale, arDx); @@ -214,7 +165,7 @@ namespace MetaFile void CWmfInterpretatorSvg::HANDLE_META_FILLREGION(unsigned short ushRegionIndex, unsigned short ushBrushIndex) { - CWmfRegion *pRegion = dynamic_cast(m_pParser->GetRegion()); + const CWmfRegion *pRegion = dynamic_cast(m_pParser->GetRegion()); if (NULL == pRegion) return; @@ -240,6 +191,7 @@ namespace MetaFile NodeAttributes arAttributes = {{L"d", wsValue}}; AddFill(arAttributes); + AddShapeRendering(arAttributes); AddTransform(arAttributes); AddClip(); @@ -266,6 +218,7 @@ namespace MetaFile {L"y2", ConvertToWString(shY)}}; AddStroke(arAttributes); + AddShapeRendering(arAttributes); AddTransform(arAttributes); AddClip(); @@ -281,12 +234,13 @@ namespace MetaFile { TRectD oNewRect; - NodeAttributes arAttributes = {{L"x", ConvertToWString(shX)}, - {L"y", ConvertToWString(shY)}, - {L"width", ConvertToWString(shW)}, - {L"height", ConvertToWString(shH)}}; + NodeAttributes arAttributes = {{L"x", ConvertToWString(shX)}, + {L"y", ConvertToWString(shY)}, + {L"width", ConvertToWString(shW)}, + {L"height", ConvertToWString(shH)}}; AddFill(arAttributes); + AddShapeRendering(arAttributes); AddTransform(arAttributes); AddClip(); @@ -311,6 +265,7 @@ namespace MetaFile AddStroke(arAttributes); AddFill(arAttributes); + AddShapeRendering(arAttributes); AddTransform(arAttributes); AddClip(); @@ -331,6 +286,7 @@ namespace MetaFile AddStroke(arAttributes); AddNoneFill(arAttributes); + AddShapeRendering(arAttributes); AddTransform(arAttributes); AddClip(); @@ -351,6 +307,7 @@ namespace MetaFile AddStroke(arAttributes); AddFill(arAttributes); + AddShapeRendering(arAttributes); AddTransform(arAttributes); AddClip(); @@ -378,30 +335,27 @@ namespace MetaFile AddStroke(arAttributes); AddFill(arAttributes); + AddShapeRendering(arAttributes); AddTransform(arAttributes); AddClip(); - arAttributes.push_back({L"fill-rule", L"evenodd"}); + arAttributes.Add(L"fill-rule", L"evenodd"); WriteNode(L"path", arAttributes); } void CWmfInterpretatorSvg::HANDLE_META_RECTANGLE(short shB, short shR, short shT, short shL) { - TRectD oNewRect; - - oNewRect.Left = shL; - oNewRect.Top = shT; - oNewRect.Right = shR; - oNewRect.Bottom = shB; + TRectD oNewRect = TranslateRect({shL, shT, shR, shB}); - NodeAttributes arAttributes = {{L"x", ConvertToWString(oNewRect.Left)}, - {L"y", ConvertToWString(oNewRect.Top)}, - {L"width", ConvertToWString(oNewRect.Right - oNewRect.Left)}, - {L"height", ConvertToWString(oNewRect.Bottom - oNewRect.Top)}}; + NodeAttributes arAttributes = {{L"x", ConvertToWString(oNewRect.Left)}, + {L"y", ConvertToWString(oNewRect.Top)}, + {L"width", ConvertToWString(oNewRect.Right - oNewRect.Left)}, + {L"height", ConvertToWString(oNewRect.Bottom - oNewRect.Top)}}; AddStroke(arAttributes); AddFill(arAttributes); + AddShapeRendering(arAttributes); AddTransform(arAttributes); AddClip(); @@ -410,22 +364,18 @@ namespace MetaFile void CWmfInterpretatorSvg::HANDLE_META_ROUNDRECT(short shH, short shW, short shB, short shR, short shT, short shL) { - TRectD oNewRect; - - oNewRect.Left = shL; - oNewRect.Top = shT; - oNewRect.Right = shR; - oNewRect.Bottom = shB; + TRectD oNewRect = TranslateRect({shL, shT, shR, shB}); - NodeAttributes arAttributes = {{L"x", ConvertToWString(oNewRect.Left)}, - {L"y", ConvertToWString(oNewRect.Top)}, - {L"width", ConvertToWString(oNewRect.Right - oNewRect.Left)}, - {L"height", ConvertToWString(oNewRect.Bottom - oNewRect.Top)}, - {L"rx", ConvertToWString((double)shW / 2.)}, - {L"ry", ConvertToWString((double)shH / 2.)}}; + NodeAttributes arAttributes = {{L"x", ConvertToWString(oNewRect.Left)}, + {L"y", ConvertToWString(oNewRect.Top)}, + {L"width", ConvertToWString(oNewRect.Right - oNewRect.Left)}, + {L"height", ConvertToWString(oNewRect.Bottom - oNewRect.Top)}, + {L"rx", ConvertToWString((double)shW / 2.)}, + {L"ry", ConvertToWString((double)shH / 2.)}}; AddStroke(arAttributes); AddFill(arAttributes); + AddShapeRendering(arAttributes); AddTransform(arAttributes); AddClip(); @@ -439,7 +389,7 @@ namespace MetaFile void CWmfInterpretatorSvg::HANDLE_META_TEXTOUT(short shStringLength, unsigned char *pString, short shX, short shY) { - IFont* pFont = NULL; + const IFont* pFont = NULL; if (NULL != m_pParser) pFont = m_pParser->GetFont(); @@ -514,66 +464,9 @@ namespace MetaFile m_bUpdatedClip = false; } - void CWmfInterpretatorSvg::DrawBitmap(double dX, double dY, double dW, double dH, BYTE* pBuffer, unsigned int unWidth, unsigned int unHeight) + void CWmfInterpretatorSvg::DrawBitmap(double dX, double dY, double dW, double dH, BYTE *pBuffer, unsigned int unWidth, unsigned int unHeight) { - if (NULL == pBuffer || 0 == dW || 0 == dH || 0 == unWidth || 0 == unHeight) - return; - - if (1 == unWidth && 1 == unHeight) - { - NodeAttributes arAttributes = {{L"x", ConvertToWString(dX)}, - {L"y", ConvertToWString(dY)}, - {L"width", ConvertToWString(dW)}, - {L"height", ConvertToWString(dH)}, - {L"fill", L"rgb(" + std::to_wstring(pBuffer[2]) + L',' + std::to_wstring(pBuffer[1]) + L',' + std::to_wstring(pBuffer[0]) + L',' + std::to_wstring(pBuffer[3]) + L')'}}; - - AddTransform(arAttributes); - - WriteNode(L"rect", arAttributes); - - return; - } - - CBgraFrame oFrame; - - oFrame.put_Data(pBuffer); - oFrame.put_Width(unWidth); - oFrame.put_Height(unHeight); - - BYTE* pNewBuffer = NULL; - int nNewSize = 0; - - oFrame.Encode(pNewBuffer, nNewSize, 4); - oFrame.put_Data(NULL); - - if (0 < nNewSize) - { - int nImageSize = NSBase64::Base64EncodeGetRequiredLength(nNewSize); - unsigned char* ucValue = new unsigned char[nImageSize]; - - if (NULL == ucValue) - return; - - NSBase64::Base64Encode(pNewBuffer, nNewSize, ucValue, &nImageSize); - std::wstring wsValue(ucValue, ucValue + nImageSize); - - RELEASEARRAYOBJECTS(ucValue); - - NodeAttributes arAttributes = {{L"x", ConvertToWString(dX)}, - {L"y", ConvertToWString(dY)}, - {L"width", ConvertToWString(dW)}, - {L"height", ConvertToWString(dH)}, - {L"preserveAspectRatio", L"xMinYMin slice"}, - {L"xlink:href", L"data:image/png;base64," + wsValue}}; - - AddTransform(arAttributes); - AddClip(); - - WriteNode(L"image", arAttributes); - } - - if (NULL != pNewBuffer) - delete [] pNewBuffer; + CInterpretatorSvgBase::DrawBitmap(dX, dY, dW, dH, pBuffer, unWidth, unHeight); } void CWmfInterpretatorSvg::ResetClip() diff --git a/DesktopEditor/raster/Metafile/Wmf/WmfObjects.cpp b/DesktopEditor/raster/Metafile/Wmf/WmfObjects.cpp index a1842f7d2ec..b697d0843a2 100644 --- a/DesktopEditor/raster/Metafile/Wmf/WmfObjects.cpp +++ b/DesktopEditor/raster/Metafile/Wmf/WmfObjects.cpp @@ -46,7 +46,7 @@ namespace MetaFile CWmfObjectBase::~CWmfObjectBase() {} - EWmfObjectType CWmfObjectBase::GetType() + EWmfObjectType CWmfObjectBase::GetType() const { return WMF_OBJECT_UNKNOWN; } @@ -67,7 +67,7 @@ namespace MetaFile RELEASEOBJECT(pDibBuffer); } - EWmfObjectType CWmfBrush::GetType() + EWmfObjectType CWmfBrush::GetType() const { return WMF_OBJECT_BRUSH; } @@ -109,117 +109,129 @@ namespace MetaFile #endif } - int CWmfBrush::GetColor() + int CWmfBrush::GetColor() const { return METAFILE_RGBA(oColor.r, oColor.g, oColor.b, oColor.a); } - int CWmfBrush::GetColor2() + int CWmfBrush::GetColor2() const { return 0; } - unsigned int CWmfBrush::GetStyle() + unsigned int CWmfBrush::GetStyle() const { return ushBrushStyle; } - unsigned int CWmfBrush::GetStyleEx() + unsigned int CWmfBrush::GetStyleEx() const { return 0; } - unsigned int CWmfBrush::GetHatch() + unsigned int CWmfBrush::GetHatch() const { return ushBrushHatch; } - unsigned int CWmfBrush::GetAlpha() + unsigned int CWmfBrush::GetAlpha() const { - return 255; + return 0xff; } - unsigned int CWmfBrush::GetAlpha2() + unsigned int CWmfBrush::GetAlpha2() const { return 0xff; } - std::wstring CWmfBrush::GetDibPatterPath() + std::wstring CWmfBrush::GetDibPatterPath() const { return wsDibPatternPath; } - void CWmfBrush::GetBounds(double &left, double &top, double &width, double &height) - { - - } + void CWmfBrush::GetBounds(double &left, double &top, double &width, double &height) const + {} - void CWmfBrush::GetCenterPoint(double &dX, double &dY) + void CWmfBrush::GetCenterPoint(double &dX, double &dY) const + {} + + void CWmfBrush::GetDibPattern(unsigned char **pBuffer, unsigned int &unWidth, unsigned int &unHeight) const { - + *pBuffer = pDibBuffer; + unWidth = unDibWidth; + unHeight = unDibHeigth; } - void CWmfBrush::GetDibPattern(unsigned char **pBuffer, unsigned int &unWidth, unsigned int &unHeight) + void CWmfBrush::GetGradientColors(std::vector& arColors, std::vector& arPositions) const { - *pBuffer = pDibBuffer; - unWidth = unDibWidth; - unHeight = unDibHeigth; + arColors = {(long)(GetColor() + (GetAlpha() << 24)), (long)(GetColor2() + (GetAlpha2() << 24))}; + arPositions = {0., 1.}; } CWmfFont::CWmfFont() + : shHeight(DEFAULT_FONT_SIZE), shWidth(0), shEscapement(0), shOrientation(0), shWeight(400), + uchItalic(0x00), uchUnderline(0x00), uchStrikeOut(0x00), uchCharSet(0x01), uchOutPrecision(0x00), + uchClipPrecision(0x00), uchQuality(0x00), uchPitchAndFamily(0x00) { memset(uchFacename, 0x00, 32); + + uchFacename[0] = 'A'; + uchFacename[1] = 'r'; + uchFacename[2] = 'i'; + uchFacename[3] = 'a'; + uchFacename[4] = 'l'; } CWmfFont::~CWmfFont() {} - EWmfObjectType CWmfFont::GetType() + EWmfObjectType CWmfFont::GetType() const { return WMF_OBJECT_FONT; } - double CWmfFont::GetHeight() + double CWmfFont::GetHeight() const { return (double)shHeight; } - std::wstring CWmfFont::GetFaceName() + std::wstring CWmfFont::GetFaceName() const { - return std::wstring(NSStringExt::CConverter::GetUnicodeFromSingleByteString((const unsigned char*)uchFacename, 32).c_str()); + const std::wstring wsFontName(ConvertToUnicode((const unsigned char*)uchFacename, 32, uchCharSet)); + return wsFontName.substr(0, wsFontName.find(L'\0')); } - int CWmfFont::GetWeight() + int CWmfFont::GetWeight() const { return (int)shWidth; } - bool CWmfFont::IsItalic() + bool CWmfFont::IsItalic() const { - return (0x01 == uchItalic ? true : false); + return 0x01 == uchItalic; } - bool CWmfFont::IsStrikeOut() + bool CWmfFont::IsStrikeOut() const { - return (0x01 == uchStrikeOut ? true : false); + return 0x01 == uchStrikeOut; } - bool CWmfFont::IsUnderline() + bool CWmfFont::IsUnderline() const { - return (0x01 == uchUnderline ? true : false); + return 0x01 == uchUnderline; } - int CWmfFont::GetEscapement() + int CWmfFont::GetEscapement() const { return (int)shEscapement; } - int CWmfFont::GetCharSet() + int CWmfFont::GetCharSet() const { return (int)uchCharSet; } - int CWmfFont::GetOrientation() + int CWmfFont::GetOrientation() const { return (int)shOrientation; } @@ -232,7 +244,7 @@ namespace MetaFile RELEASEOBJECT(pPaletteEntries); } - EWmfObjectType CWmfPalette::GetType() + EWmfObjectType CWmfPalette::GetType() const { return WMF_OBJECT_PALETTE; } @@ -243,47 +255,57 @@ namespace MetaFile CWmfPen::~CWmfPen() {} - EWmfObjectType CWmfPen::GetType() + EWmfObjectType CWmfPen::GetType() const { return WMF_OBJECT_PEN; } - int CWmfPen::GetColor() + int CWmfPen::GetColor() const { return METAFILE_RGBA(oColor.r, oColor.g, oColor.b, oColor.a); } - unsigned int CWmfPen::GetStyle() + unsigned int CWmfPen::GetStyle() const { return (unsigned int)ushPenStyle; } - double CWmfPen::GetWidth() + double CWmfPen::GetWidth() const { return (double)oWidth.X; } - unsigned int CWmfPen::GetAlpha() + unsigned int CWmfPen::GetAlpha() const { return 0xff; } - double CWmfPen::GetMiterLimit() + double CWmfPen::GetMiterLimit() const { return 0; } - double CWmfPen::GetDashOffset() + double CWmfPen::GetDashOffset() const { return 0; } - void CWmfPen::GetDashData(double *&arDatas, unsigned int &unSize) + void CWmfPen::GetDashData(double *&arDatas, unsigned int &unSize) const { arDatas = NULL; unSize = 0; } + const ILineCap* CWmfPen::GetStartLineCap() const + { + return NULL; + } + + const ILineCap* CWmfPen::GetEndLineCap() const + { + return NULL; + } + CWmfRegion::CWmfRegion() : pScans(NULL) {} @@ -292,7 +314,7 @@ namespace MetaFile RELEASEOBJECT(pScans); } - EWmfObjectType CWmfRegion::GetType() + EWmfObjectType CWmfRegion::GetType() const { return WMF_OBJECT_REGION; } diff --git a/DesktopEditor/raster/Metafile/Wmf/WmfObjects.h b/DesktopEditor/raster/Metafile/Wmf/WmfObjects.h index fd020a3f4a9..a3a31b3d1a0 100644 --- a/DesktopEditor/raster/Metafile/Wmf/WmfObjects.h +++ b/DesktopEditor/raster/Metafile/Wmf/WmfObjects.h @@ -57,7 +57,7 @@ namespace MetaFile public: CWmfObjectBase(); virtual ~CWmfObjectBase(); - virtual EWmfObjectType GetType(); + virtual EWmfObjectType GetType() const; }; class CWmfBrush : public CWmfObjectBase, public IBrush @@ -66,22 +66,24 @@ namespace MetaFile CWmfBrush(); CWmfBrush(const TWmfLogBrush &oBrush); virtual ~CWmfBrush(); - virtual EWmfObjectType GetType(); + virtual EWmfObjectType GetType() const override; void SetDibPattern(unsigned char* pBuffer, unsigned int unWidth, unsigned int unHeight); // IBrush - int GetColor(); - int GetColor2(); - unsigned int GetStyle(); - unsigned int GetStyleEx(); - unsigned int GetHatch(); - unsigned int GetAlpha(); - unsigned int GetAlpha2(); - std::wstring GetDibPatterPath(); - void GetBounds(double& left, double& top, double& width, double& height); - void GetCenterPoint(double& dX, double& dY); - void GetDibPattern(unsigned char** pBuffer, unsigned int &unWidth, unsigned int &unHeight); + int GetColor() const override; + int GetColor2() const override; + unsigned int GetStyle() const override; + unsigned int GetStyleEx() const override; + unsigned int GetHatch() const override; + unsigned int GetAlpha() const override; + unsigned int GetAlpha2() const override; + std::wstring GetDibPatterPath() const override; + void GetBounds(double& left, double& top, double& width, double& height) const override; + void GetCenterPoint(double& dX, double& dY) const override; + void GetDibPattern(unsigned char** pBuffer, unsigned int &unWidth, unsigned int &unHeight) const override; + + void GetGradientColors(std::vector& arColors, std::vector& arPositions) const override; public: unsigned short ushBrushStyle; @@ -98,18 +100,18 @@ namespace MetaFile CWmfFont(); virtual ~CWmfFont(); - virtual EWmfObjectType GetType(); + virtual EWmfObjectType GetType() const override; // IFont - double GetHeight(); - std::wstring GetFaceName(); - int GetWeight(); - bool IsItalic(); - bool IsStrikeOut(); - bool IsUnderline(); - int GetEscapement(); - int GetCharSet(); - int GetOrientation(); + double GetHeight() const override; + std::wstring GetFaceName() const override; + int GetWeight() const override; + bool IsItalic() const override; + bool IsStrikeOut() const override; + bool IsUnderline() const override; + int GetEscapement() const override; + int GetCharSet() const override; + int GetOrientation() const override; public: short shHeight; @@ -132,7 +134,7 @@ namespace MetaFile public: CWmfPalette(); virtual ~CWmfPalette(); - virtual EWmfObjectType GetType(); + virtual EWmfObjectType GetType() const override; public: unsigned short ushStart; unsigned short ushNumberOfEntries; @@ -143,16 +145,18 @@ namespace MetaFile public: CWmfPen(); virtual ~CWmfPen(); - virtual EWmfObjectType GetType(); + virtual EWmfObjectType GetType() const override; // IPen - int GetColor(); - unsigned int GetStyle(); - double GetWidth(); - unsigned int GetAlpha(); - double GetMiterLimit(); - double GetDashOffset(); - void GetDashData(double*& arDatas, unsigned int& unSize); + int GetColor() const override; + unsigned int GetStyle() const override; + double GetWidth() const override; + unsigned int GetAlpha() const override; + double GetMiterLimit() const override; + double GetDashOffset() const override; + void GetDashData(double*& arDatas, unsigned int& unSize) const override; + const ILineCap* GetStartLineCap() const override; + const ILineCap* GetEndLineCap() const override; public: unsigned short ushPenStyle; TPointS oWidth; @@ -163,7 +167,7 @@ namespace MetaFile public: CWmfRegion(); virtual ~CWmfRegion(); - virtual EWmfObjectType GetType(); + virtual EWmfObjectType GetType() const override; public: short shNextInChain; // не используется short shObjectType; // не используется diff --git a/DesktopEditor/raster/Metafile/Wmf/WmfParser/CWmfParser.cpp b/DesktopEditor/raster/Metafile/Wmf/WmfParser/CWmfParser.cpp index 33803d513a6..214b314d836 100644 --- a/DesktopEditor/raster/Metafile/Wmf/WmfParser/CWmfParser.cpp +++ b/DesktopEditor/raster/Metafile/Wmf/WmfParser/CWmfParser.cpp @@ -27,15 +27,12 @@ namespace MetaFile unsigned int unSize; unsigned short ushType; - unsigned int ulNumber = 0; if (NULL != m_pInterpretator) m_pInterpretator->Begin(); Read_META_HEADER(); - unsigned int unRecordIndex = 1; - while (!CheckError()) { if (m_oStream.CanRead() < 6) @@ -52,6 +49,11 @@ namespace MetaFile m_unRecordSize = unSize * 2; // Размер указан в WORD + m_oStream.SetCurrentBlockSize(m_unRecordSize); + + if (NULL != m_pInterpretator) + PRINT_WMF_RECORD(ushType); + switch (ushType) { //----------------------------------------------------------- @@ -147,20 +149,18 @@ namespace MetaFile //----------------------------------------------------------- default: { - //std::cout << ushType << " "; Read_META_UNKNOWN(); break; } } - unRecordIndex++; - if (m_bEof) break; // Пропускаем лишние байты, которые могли быть в записи int need_skip = m_unRecordSize - (m_oStream.Tell() - m_unRecordPos); m_oStream.Skip(need_skip); + m_oStream.ClearCurrentBlockSize(); }; if (!m_bEof) @@ -180,11 +180,12 @@ namespace MetaFile CWmfInterpretatorBase *pInterpretator = m_pInterpretator; m_pInterpretator = NULL; PlayFile(); + UpdateDCRect(); m_pInterpretator = pInterpretator; this->ClearFile(); } - WmfParserType CWmfParser::GetType() + WmfParserType CWmfParser::GetType() const { return WmfParserType::WmfParser; } diff --git a/DesktopEditor/raster/Metafile/Wmf/WmfParser/CWmfParser.h b/DesktopEditor/raster/Metafile/Wmf/WmfParser/CWmfParser.h index f60df82b861..f8d727788af 100644 --- a/DesktopEditor/raster/Metafile/Wmf/WmfParser/CWmfParser.h +++ b/DesktopEditor/raster/Metafile/Wmf/WmfParser/CWmfParser.h @@ -17,7 +17,7 @@ namespace MetaFile void PlayFile() override; void Scan() override; - WmfParserType GetType() override; + WmfParserType GetType() const override; void SetStream(BYTE* pBuf, unsigned int unSize); private: diff --git a/DesktopEditor/raster/Metafile/Wmf/WmfParser/CWmfParserBase.cpp b/DesktopEditor/raster/Metafile/Wmf/WmfParser/CWmfParserBase.cpp index 2e0eba976b4..b8d03f538e1 100644 --- a/DesktopEditor/raster/Metafile/Wmf/WmfParser/CWmfParserBase.cpp +++ b/DesktopEditor/raster/Metafile/Wmf/WmfParser/CWmfParserBase.cpp @@ -29,82 +29,67 @@ namespace MetaFile m_bEof = false; } - TRectL *CWmfParserBase::GetDCBounds() + const TRectL& CWmfParserBase::GetDCBounds() const { - m_oDCRect = GetBoundingBox(); - return &m_oDCRect; + return m_oDCRect; } - CClip *CWmfParserBase::GetClip() + const CClip *CWmfParserBase::GetClip() const { return m_pDC->GetClip(); } - double CWmfParserBase::GetPixelHeight() + double CWmfParserBase::GetPixelHeight() const { return m_pDC->GetPixelHeight(); } - double CWmfParserBase::GetPixelWidth() + double CWmfParserBase::GetPixelWidth() const { return m_pDC->GetPixelWidth(); } - int CWmfParserBase::GetTextColor() + int CWmfParserBase::GetTextColor() const { - TRGBA& oColor = m_pDC->GetTextColor(); - return METAFILE_RGBA(oColor.r, oColor.g, oColor.b, 0); + return m_pDC->GetTextColor().ToInt(); } - IFont *CWmfParserBase::GetFont() + const IFont *CWmfParserBase::GetFont() const { - CWmfFont* pFont = m_pDC->GetFont(); - if (!pFont) - return NULL; - - return (IFont*)pFont; + return m_pDC->GetFont(); } - IBrush *CWmfParserBase::GetBrush() + const IBrush *CWmfParserBase::GetBrush() const { - CWmfBrush* pBrush = m_pDC->GetBrush(); - if (!pBrush) - return NULL; - - return (IBrush*)pBrush; + return m_pDC->GetBrush(); } - IPen *CWmfParserBase::GetPen() + const IPen *CWmfParserBase::GetPen() const { - CWmfPen* pPen = m_pDC->GetPen(); - if (!pPen) - return NULL; - - return (IPen*)pPen; + return m_pDC->GetPen(); } - unsigned int CWmfParserBase::GetTextAlign() + unsigned int CWmfParserBase::GetTextAlign() const { return (unsigned int)m_pDC->GetTextAlign(); } - unsigned int CWmfParserBase::GetTextBgMode() + unsigned int CWmfParserBase::GetTextBgMode() const { return (unsigned int)m_pDC->GetTextBgMode(); } - int CWmfParserBase::GetTextBgColor() + int CWmfParserBase::GetTextBgColor() const { - TRGBA& oColor = m_pDC->GetTextBgColor(); - return METAFILE_RGBA(oColor.r, oColor.g, oColor.b, 0); + return m_pDC->GetTextBgColor().ToInt(); } - unsigned int CWmfParserBase::GetFillMode() + unsigned int CWmfParserBase::GetFillMode() const { return (unsigned int)m_pDC->GetPolyFillMode(); } - TPointD CWmfParserBase::GetCurPos() + TPointD CWmfParserBase::GetCurPos() const { TPointL oPoint = m_pDC->GetCurPos(); double dX, dY; @@ -112,71 +97,69 @@ namespace MetaFile return TPointD(dX, dY); } - TXForm *CWmfParserBase::GetInverseTransform() + const TXForm& CWmfParserBase::GetInverseTransform() const { return m_pDC->GetInverseTransform(); } - TXForm *CWmfParserBase::GetTransform(int iGraphicsMode) + const TXForm& CWmfParserBase::GetTransform(int iGraphicsMode) { - TRectL* pBounds = GetDCBounds(); - double dT = pBounds->Top; - double dL = pBounds->Left; + const TRectL& oBounds{GetDCBounds()}; + double dT = oBounds.Top; + double dL = oBounds.Left; TXForm oShiftXForm(1, 0, 0, 1, -dL, -dT); m_oTransform.Copy(m_pDC->GetFinalTransform(iGraphicsMode)); m_oTransform.Multiply(oShiftXForm, MWT_RIGHTMULTIPLY); - return &m_oTransform; + return m_oTransform; } - unsigned int CWmfParserBase::GetMiterLimit() + unsigned int CWmfParserBase::GetMiterLimit() const { return m_pDC->GetMiterLimit(); } - unsigned int CWmfParserBase::GetRop2Mode() + unsigned int CWmfParserBase::GetRop2Mode() const { return (unsigned int)m_pDC->GetRop2Mode(); } - int CWmfParserBase::GetCharSpace() + int CWmfParserBase::GetCharSpace() const { return m_pDC->GetCharSpacing(); } - bool CWmfParserBase::IsWindowFlippedY() + bool CWmfParserBase::IsWindowFlippedY() const { - TWmfWindow* pWindow = m_pDC->GetWindow(); - return (pWindow->h < 0); + return m_pDC->GetWindow().h < 0; } - bool CWmfParserBase::IsWindowFlippedX() + bool CWmfParserBase::IsWindowFlippedX() const { - TWmfWindow* pWindow = m_pDC->GetWindow(); - return (pWindow->w < 0); + return m_pDC->GetWindow().w < 0; } - unsigned int CWmfParserBase::GetMapMode() + unsigned int CWmfParserBase::GetMapMode() const { return m_pDC->GetMapMode(); } - double CWmfParserBase::GetDpi() + USHORT CWmfParserBase::GetDpi() const { - return (0 != m_oPlaceable.ushInch) ? m_oPlaceable.ushInch : 96.; + return (0 != m_oPlaceable.ushInch) ? m_oPlaceable.ushInch : 96; } - IRegion *CWmfParserBase::GetRegion() + const IRegion *CWmfParserBase::GetRegion() const { return m_pDC->GetRegion(); } - unsigned int CWmfParserBase::GetArcDirection() + unsigned int CWmfParserBase::GetArcDirection() const { return AD_CLOCKWISE; } - CPath *CWmfParserBase::GetPath() + const CPath *CWmfParserBase::GetPath() const { return NULL; } @@ -211,19 +194,21 @@ namespace MetaFile RELEASEOBJECT(m_pInterpretator); if (InterpretatorType::Svg == oInterpretatorType) - m_pInterpretator = new CWmfInterpretatorSvg(this, unWidth, unHeight); + { + CWmfInterpretatorSvg *pWmfInterpretatorSvg = new CWmfInterpretatorSvg(this, unWidth, unHeight); + pWmfInterpretatorSvg->SetShapeRendering(EShapeRendering::CrispEdges); + m_pInterpretator = pWmfInterpretatorSvg; + } } void CWmfParserBase::SetInterpretator(IOutputDevice *pOutput, const wchar_t *wsFilePath) { RELEASEOBJECT(m_pInterpretator); - } TRectD CWmfParserBase::GetBounds() { - TRectL oBoundsBox = GetBoundingBox(); - TRectD oBounds(oBoundsBox); + TRectD oBounds(m_oDCRect); return oBounds; } @@ -236,50 +221,57 @@ namespace MetaFile m_oStream.SeekBack(1); } - void CWmfParserBase::TranslatePoint(short shX, short shY, double &dX, double &dY) + void CWmfParserBase::TranslatePoint(short shX, short shY, double &dX, double &dY) const { dX = (double)shX; dY = (double)shY; } - TRectL CWmfParserBase::GetBoundingBox() + void CWmfParserBase::UpdateDCRect() { - if (IsPlaceable()) + if (!IsPlaceable()) { - TRectL oBB; + m_oDCRect = m_oBoundingBox; + return; + } - oBB = m_oPlaceable.oBoundingBox; + m_oDCRect = m_oPlaceable.oBoundingBox; - // Иногда m_oPlaceable.BoundingBox задается нулевой ширины и высоты - if (abs(oBB.Right - oBB.Left) <= 1) - { - oBB.Right = m_oBoundingBox.Right; - oBB.Left = m_oBoundingBox.Left; - } - if (abs(oBB.Bottom - oBB.Top) <= 1) - { - oBB.Top = m_oBoundingBox.Top; - oBB.Bottom = m_oBoundingBox.Bottom; - } + if (96 != m_oPlaceable.ushInch) + { + const double dKoef = 96. / (double)m_oPlaceable.ushInch; - return oBB; + m_oDCRect.Left = std::round(m_oDCRect.Left * dKoef); + m_oDCRect.Top = std::round(m_oDCRect.Top * dKoef); + m_oDCRect.Right = std::round(m_oDCRect.Right * dKoef); + m_oDCRect.Bottom = std::round(m_oDCRect.Bottom * dKoef); + } + + // Иногда m_oPlaceable.BoundingBox задается нулевой ширины и высоты + if (abs(m_oDCRect.Right - m_oDCRect.Left) <= 1) + { + m_oDCRect.Right = m_oBoundingBox.Right; + m_oDCRect.Left = m_oBoundingBox.Left; + } + if (abs(m_oDCRect.Bottom - m_oDCRect.Top) <= 1) + { + m_oDCRect.Top = m_oBoundingBox.Top; + m_oDCRect.Bottom = m_oBoundingBox.Bottom; } - else - return m_oBoundingBox; } - bool CWmfParserBase::IsPlaceable() + bool CWmfParserBase::IsPlaceable() const { return (0x9AC6CDD7 == m_oPlaceable.unKey); } - int CWmfParserBase::GetRecordRemainingBytesCount() + int CWmfParserBase::GetRecordRemainingBytesCount() const { - unsigned int unReadedSize = m_oStream.Tell() - m_unRecordPos; + const unsigned int unReadedSize = m_oStream.Tell() - m_unRecordPos; return (m_unRecordSize - unReadedSize); } - double CWmfParserBase::GetSweepAngle(const double &dStartAngle, const double &dEndAngle) + double CWmfParserBase::GetSweepAngle(const double &dStartAngle, const double &dEndAngle) const { return (dEndAngle - dStartAngle); } @@ -361,58 +353,8 @@ namespace MetaFile nY = m_pDC->GetCurPos().Y; } - IFont* pFont = GetFont(); - NSStringExt::CConverter::ESingleByteEncoding eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_DEFAULT;; - if (pFont) - { - // Соответствие Charset -> Codepage: http://support.microsoft.com/kb/165478 - // http://msdn.microsoft.com/en-us/library/cc194829.aspx - // Charset Name Charset Value(hex) Codepage number - // ------------------------------------------------------ - // - // DEFAULT_CHARSET 1 (x01) - // SYMBOL_CHARSET 2 (x02) - // OEM_CHARSET 255 (xFF) - // ANSI_CHARSET 0 (x00) 1252 - // RUSSIAN_CHARSET 204 (xCC) 1251 - // EASTEUROPE_CHARSET 238 (xEE) 1250 - // GREEK_CHARSET 161 (xA1) 1253 - // TURKISH_CHARSET 162 (xA2) 1254 - // BALTIC_CHARSET 186 (xBA) 1257 - // HEBREW_CHARSET 177 (xB1) 1255 - // ARABIC _CHARSET 178 (xB2) 1256 - // SHIFTJIS_CHARSET 128 (x80) 932 - // HANGEUL_CHARSET 129 (x81) 949 - // GB2313_CHARSET 134 (x86) 936 - // CHINESEBIG5_CHARSET 136 (x88) 950 - // THAI_CHARSET 222 (xDE) 874 - // JOHAB_CHARSET 130 (x82) 1361 - // VIETNAMESE_CHARSET 163 (xA3) 1258 - - switch (pFont->GetCharSet()) - { - default: - case DEFAULT_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_DEFAULT; break; - case SYMBOL_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_DEFAULT; break; - case ANSI_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1252; break; - case RUSSIAN_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1251; break; - case EASTEUROPE_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1250; break; - case GREEK_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1253; break; - case TURKISH_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1254; break; - case BALTIC_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1257; break; - case HEBREW_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1255; break; - case ARABIC_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1256; break; - case SHIFTJIS_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP932; break; - case HANGEUL_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP949; break; - case 134/*GB2313_CHARSET*/: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP936; break; - case CHINESEBIG5_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP950; break; - case THAI_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP874; break; - case JOHAB_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1361; break; - case VIETNAMESE_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1258; break; - } - } - - std::wstring wsText = NSStringExt::CConverter::GetUnicodeFromSingleByteString((const unsigned char*)pString, (long)unCharsCount, eCharSet); + const IFont* pFont = GetFont(); + std::wstring wsText = ConvertToUnicode(pString, (long)unCharsCount, (NULL != pFont) ? pFont->GetCharSet() : DEFAULT_CHARSET); if (NULL != m_pInterpretator) { @@ -420,7 +362,7 @@ namespace MetaFile TranslatePoint(nX, nY, dX, dY); double* pdDx = NULL; - if (NULL != pDx) + if (NULL != pDx && unCharsCount == wsText.length()) { pdDx = new double[unCharsCount]; if (pdDx) @@ -441,7 +383,7 @@ namespace MetaFile } } - m_pInterpretator->DrawString(wsText, unCharsCount, dX, dY, pdDx, 1, GetTransform()->M11, GetTransform()->M22); + m_pInterpretator->DrawString(wsText, unCharsCount, dX, dY, pdDx, 1, GetTransform().M11, GetTransform().M22); RELEASEARRAYOBJECTS(pdDx); } @@ -743,18 +685,22 @@ namespace MetaFile if (oDestRect != oSrcRect) { TRectL oClip = oSrcRect; + + oClip.Right = oClip.Left + (std::min)(oClip.Right - oClip.Left, (int)unWidth ); + oClip.Bottom = oClip.Top + (std::min)(oClip.Bottom - oClip.Top, (int)unHeight); + BYTE* pNewBuffer = ClipBuffer(pBgra, unWidth, unHeight, oClip); if (NULL != pNewBuffer) { - m_pInterpretator->DrawBitmap(dX, dY, fabs(dX1 - dX), fabs(dY1 - dY), pNewBuffer, std::abs(oClip.Right - oClip.Left), std::abs(oClip.Bottom - oClip.Top)); + m_pInterpretator->DrawBitmap(dX, dY, dX1 - dX, dY1 - dY, pNewBuffer, std::abs(oClip.Right - oClip.Left), std::abs(oClip.Bottom - oClip.Top)); delete[] pNewBuffer; } else - m_pInterpretator->DrawBitmap(dX, dY, fabs(dX1 - dX), fabs(dY1 - dY), pBgra, unWidth, unHeight); + m_pInterpretator->DrawBitmap(dX, dY, dX1 - dX, dY1 - dY, pBgra, unWidth, unHeight); } else - m_pInterpretator->DrawBitmap(dX, dY, fabs(dX1 - dX), fabs(dY1 - dY), pBgra, unWidth, unHeight); + m_pInterpretator->DrawBitmap(dX, dY, dX1 - dX, dY1 - dY, pBgra, unWidth, unHeight); } if (pBgra) @@ -842,14 +788,14 @@ namespace MetaFile if (NULL != m_pInterpretator) { - m_oRect = GetBoundingBox(); + UpdateDCRect(); - m_pDC->SetWindowOrg(m_oRect.Left, m_oRect.Top); - m_pDC->SetWindowExt(m_oRect.Right - m_oRect.Left, m_oRect.Bottom - m_oRect.Top); - m_pDC->SetViewportOrg(m_oRect.Left, m_oRect.Top); - m_pDC->SetViewportExt(m_oRect.Right - m_oRect.Left, m_oRect.Bottom - m_oRect.Top); + m_pDC->SetWindowOrg(m_oDCRect.Left, m_oDCRect.Top); + m_pDC->SetWindowExt(m_oDCRect.Right - m_oDCRect.Left, m_oDCRect.Bottom - m_oDCRect.Top); + m_pDC->SetViewportOrg(m_oDCRect.Left, m_oDCRect.Top); + m_pDC->SetViewportExt(m_oDCRect.Right - m_oDCRect.Left, m_oDCRect.Bottom - m_oDCRect.Top); - if (0 != m_oPlaceable.ushInch) + if (IsPlaceable() && 0 != m_oPlaceable.ushInch) { double dScale = 1440. / m_oPlaceable.ushInch; m_pDC->SetWindowScale(dScale, dScale); @@ -1024,7 +970,7 @@ namespace MetaFile if (NULL != m_pInterpretator) m_pInterpretator->HANDLE_META_FILLREGION(ushRegionIndex, ushBrushIndex); - CWmfRegion *pRegion = m_pDC->GetRegion(); + const CWmfRegion *pRegion = m_pDC->GetRegion(); if (NULL != pRegion) { @@ -1054,7 +1000,7 @@ namespace MetaFile m_oPlayer.SelectObject(ushRegionIndex); - CWmfRegion *pRegion = m_pDC->GetRegion(); + const CWmfRegion *pRegion = m_pDC->GetRegion(); if (NULL != pRegion) { @@ -1101,7 +1047,7 @@ namespace MetaFile m_oPlayer.SelectObject(ushRegionIndex); - CWmfRegion *pRegion = m_pDC->GetRegion(); + const CWmfRegion *pRegion = m_pDC->GetRegion(); if (NULL != pRegion) { @@ -1424,11 +1370,11 @@ namespace MetaFile TranslatePoint(shLeft, shTop, oClip.Left, oClip.Top); TranslatePoint(shRight, shBottom, oClip.Right, oClip.Bottom); - TWmfWindow* pWindow = m_pDC->GetWindow(); + const TWmfWindow& oWindow{m_pDC->GetWindow()}; TRectD oBB; - TranslatePoint(pWindow->x, pWindow->y, oBB.Left, oBB.Top); - TranslatePoint(pWindow->x + pWindow->w, pWindow->y + pWindow->h, oBB.Right, oBB.Bottom); + TranslatePoint(oWindow.x, oWindow.y, oBB.Left, oBB.Top); + TranslatePoint(oWindow.x + oWindow.w, oWindow.y + oWindow.h, oBB.Right, oBB.Bottom); m_pDC->GetClip()->Exclude(oClip, oBB); UpdateOutputDC(); @@ -1487,6 +1433,13 @@ namespace MetaFile m_pDC->SetWindowOff(shXOffset, shYOffset); UpdateOutputDC(); + + if (NULL == m_pInterpretator) + { + const TWmfWindow& oWindow{m_pDC->GetWindow()}; + RegisterPoint(oWindow.x , oWindow.y ); + RegisterPoint(oWindow.x + oWindow.w, oWindow.y + oWindow.h); + } } void CWmfParserBase::HANDLE_META_RESTOREDC() @@ -1661,6 +1614,12 @@ namespace MetaFile m_pDC->SetWindowExt(shX, shY); UpdateOutputDC(); + + if (NULL == m_pInterpretator) + { + const TWmfWindow& oWindow{m_pDC->GetWindow()}; + RegisterPoint(oWindow.x + oWindow.w, oWindow.y + oWindow.h); + } } void CWmfParserBase::HANDLE_META_SETWINDOWORG(short shX, short shY) @@ -1670,12 +1629,22 @@ namespace MetaFile m_pDC->SetWindowOrg(shX, shY); UpdateOutputDC(); + + if (NULL == m_pInterpretator) + { + const TWmfWindow& oWindow{m_pDC->GetWindow()}; + RegisterPoint(oWindow.x , oWindow.y ); + RegisterPoint(oWindow.x + oWindow.w, oWindow.y + oWindow.h); + } } void CWmfParserBase::HANDLE_META_ESCAPE(unsigned short ushEscapeFunction, unsigned short ushByteCount) { if (NULL != m_pInterpretator) + { m_pInterpretator->HANDLE_META_ESCAPE(ushEscapeFunction, ushByteCount); + PRINT_WMF_LOG("Escape function type: " << ushEscapeFunction << " size: " << ushByteCount); + } if (WMF_META_ESCAPE_ENHANCED_METAFILE == ushEscapeFunction) { @@ -1730,13 +1699,13 @@ namespace MetaFile m_oEscapeBuffer.Clear(); return; } - - m_oBoundingBox = *oEmfParser.GetBounds(); if (NULL == m_pInterpretator) { - m_oEscapeBuffer.Clear(); - return HANDLE_META_EOF(); + if (!IsPlaceable()) + m_oBoundingBox = oEmfParser.GetDCBounds(); + + HANDLE_META_EOF(); } else if (InterpretatorType::Render == m_pInterpretator->GetType()) { @@ -1749,31 +1718,31 @@ namespace MetaFile } else if (InterpretatorType::Svg == m_pInterpretator->GetType()) { - double dWidth, dHeight; - - ((CWmfInterpretatorSvg*)m_pInterpretator)->GetSize(dWidth, dHeight); - - ((CEmfParserBase*)&oEmfParser)->SetInterpretator(InterpretatorType::Svg, dWidth, dHeight); + ((CEmfParserBase*)&oEmfParser)->SetInterpretator(InterpretatorType::Svg); XmlUtils::CXmlWriter *pXmlWriter = ((CWmfInterpretatorSvg*)GetInterpretator())->GetXmlWriter(); - TRectD oCurrentRect = GetBounds(); + const TRectL& oEmfRect{oEmfParser.GetDCBounds()}; + const TRectL& oCurentRect{GetDCBounds()}; - double dScaleX = std::abs((oCurrentRect.Right - oCurrentRect.Left) / (m_oBoundingBox.Right - m_oBoundingBox.Left)); - double dScaleY = std::abs((oCurrentRect.Bottom - oCurrentRect.Top) / (m_oBoundingBox.Bottom - m_oBoundingBox.Top)); + const double dScaleX = std::abs((oCurentRect.Right - oCurentRect.Left) / (oEmfRect.Right - oEmfRect.Left)); + const double dScaleY = std::abs((oCurentRect.Bottom - oCurentRect.Top) / (oEmfRect.Bottom - oEmfRect.Top)); - pXmlWriter->WriteNodeBegin(L"g", true); + const bool bAddGElement = !Equals(1., dScaleX) || !Equals(1., dScaleY); - if (0 != dScaleX || 0 != dScaleY) - pXmlWriter->WriteAttribute(L"transform", L"scale(" + std::to_wstring(dScaleX) + L',' + std::to_wstring(dScaleY) + L')'); - - pXmlWriter->WriteNodeEnd(L"g", true, false); + if (bAddGElement) + { + pXmlWriter->WriteNodeBegin(L"g", true); + pXmlWriter->WriteAttribute(L"transform", L"scale(" + ConvertToWString(dScaleX) + L',' + ConvertToWString(dScaleY) + L')'); + pXmlWriter->WriteNodeEnd(L"g", true, false); + } ((CEmfInterpretatorSvg*)oEmfParser.GetInterpretator())->SetXmlWriter(pXmlWriter); oEmfParser.PlayFile(); - pXmlWriter->WriteNodeEnd(L"g", false, false); + if (bAddGElement) + pXmlWriter->WriteNodeEnd(L"g", false, false); HANDLE_META_EOF(); } diff --git a/DesktopEditor/raster/Metafile/Wmf/WmfParser/CWmfParserBase.h b/DesktopEditor/raster/Metafile/Wmf/WmfParser/CWmfParserBase.h index 61c79d446e3..5716462b351 100644 --- a/DesktopEditor/raster/Metafile/Wmf/WmfParser/CWmfParserBase.h +++ b/DesktopEditor/raster/Metafile/Wmf/WmfParser/CWmfParserBase.h @@ -11,6 +11,113 @@ #undef DrawText #endif +#define PRINT_WMF_RECORD(type) do {} while(false) +#define PRINT_WMF_LOG(text) do {} while(false) + +#ifdef _DEBUG +#define LOG_WMF_RECORDS 1 + +#ifdef LOG_WMF_RECORDS + #if 1 == LOG_WMF_RECORDS + #include + + #define PRINTING_WMF_RECORDS 1 + + #define PRINT_WMF_LOG(text) \ + std::cout << "[LOG] " << text << std::endl + + #ifdef PRINTING_WMF_RECORDS + #if 1 == PRINTING_WMF_RECORDS + #define AddRecord(name) {name, #name} + + static const std::map mWmfRecords = + { + AddRecord(META_EOF), + AddRecord(META_SETBKCOLOR), + AddRecord(META_SETBKMODE), + AddRecord(META_SETMAPMODE), + AddRecord(META_SETROP2), + AddRecord(META_SETRELABS), + AddRecord(META_SETPOLYFILLMODE), + AddRecord(META_SETSTRETCHBLTMODE), + AddRecord(META_SETTEXTCHAREXTRA), + AddRecord(META_SETTEXTCOLOR), + AddRecord(META_SETTEXTJUSTIFICATION), + AddRecord(META_SETWINDOWORG), + AddRecord(META_SETWINDOWEXT), + AddRecord(META_SETVIEWPORTORG), + AddRecord(META_SETVIEWPORTEXT), + AddRecord(META_OFFSETWINDOWORG), + AddRecord(META_SCALEWINDOWEXT), + AddRecord(META_OFFSETVIEWPORTORG), + AddRecord(META_SCALEVIEWPORTEXT), + AddRecord(META_LINETO), + AddRecord(META_MOVETO), + AddRecord(META_EXCLUDECLIPRECT), + AddRecord(META_INTERSECTCLIPRECT), + AddRecord(META_ARC), + AddRecord(META_ELLIPSE), + AddRecord(META_FLOODFILL), + AddRecord(META_PIE), + AddRecord(META_RECTANGLE), + AddRecord(META_ROUNDRECT), + AddRecord(META_PATBLT), + AddRecord(META_SAVEDC), + AddRecord(META_SETPIXEL), + AddRecord(META_OFFSETCLIPRGN), + AddRecord(META_TEXTOUT), + AddRecord(META_BITBLT), + AddRecord(META_STRETCHBLT), + AddRecord(META_POLYGON), + AddRecord(META_POLYLINE), + AddRecord(META_ESCAPE), + AddRecord(META_RESTOREDC), + AddRecord(META_FILLREGION), + AddRecord(META_FRAMEREGION), + AddRecord(META_INVERTREGION), + AddRecord(META_PAINTREGION), + AddRecord(META_SELECTCLIPREGION), + AddRecord(META_SELECTOBJECT), + AddRecord(META_SETTEXTALIGN), + AddRecord(META_CHORD), + AddRecord(META_SETMAPPERFLAGS), + AddRecord(META_EXTTEXTOUT), + AddRecord(META_SETDIBTODEV), + AddRecord(META_SELECTPALETTE), + AddRecord(META_REALIZEPALETTE), + AddRecord(META_ANIMATEPALETTE), + AddRecord(META_SETPALENTRIES), + AddRecord(META_POLYPOLYGON), + AddRecord(META_RESIZEPALETTE), + AddRecord(META_DIBBITBLT), + AddRecord(META_DIBSTRETCHBLT), + AddRecord(META_DIBCREATEPATTERNBRUSH), + AddRecord(META_STRETCHDIB), + AddRecord(META_EXTFLOODFILL), + AddRecord(META_SETLAYOUT), + AddRecord(META_DELETEOBJECT), + AddRecord(META_CREATEPALETTE), + AddRecord(META_CREATEPATTERNBRUSH), + AddRecord(META_CREATEPENINDIRECT), + AddRecord(META_CREATEFONTINDIRECT), + AddRecord(META_CREATEBRUSHINDIRECT), + AddRecord(META_CREATEREGION) + }; + + #define PRINT_WMF_RECORD(type) \ + do {\ + std::map::const_iterator itFound = mWmfRecords.find(type); \ + if (mWmfRecords.cend() != itFound) \ + std::cout << itFound->second << std::endl; \ + else \ + std::cout << "Unknown record: " << type << std::endl; \ + } while(false) + #endif + #endif + #endif +#endif +#endif + namespace MetaFile { enum WmfParserType @@ -32,35 +139,35 @@ namespace MetaFile virtual void PlayFile() = 0; virtual void Scan() = 0; - virtual WmfParserType GetType() = 0; - - void PlayMetaFile() override; - void ClearFile() override; - TRectL* GetDCBounds() override; - CClip* GetClip() override; - double GetPixelHeight() override; - double GetPixelWidth() override; - int GetTextColor() override; - IFont* GetFont() override; - IBrush* GetBrush() override; - IPen* GetPen() override; - unsigned int GetTextAlign() override; - unsigned int GetTextBgMode() override; - int GetTextBgColor() override; - unsigned int GetFillMode() override; - TPointD GetCurPos() override; - TXForm* GetInverseTransform() override; - TXForm* GetTransform(int = GM_ADVANCED) override; - unsigned int GetMiterLimit() override; - unsigned int GetRop2Mode() override; - int GetCharSpace() override; - bool IsWindowFlippedY() override; - bool IsWindowFlippedX() override; - unsigned int GetMapMode() override; - double GetDpi() override; - IRegion* GetRegion() override; - unsigned int GetArcDirection() override; - CPath* GetPath() override; + virtual WmfParserType GetType() const = 0; + + void PlayMetaFile() override; + void ClearFile() override; + const TRectL& GetDCBounds() const override; + const CClip* GetClip() const override; + double GetPixelHeight() const override; + double GetPixelWidth() const override; + int GetTextColor() const override; + const IFont* GetFont() const override; + const IBrush* GetBrush() const override; + const IPen* GetPen() const override; + unsigned int GetTextAlign() const override; + unsigned int GetTextBgMode() const override; + int GetTextBgColor() const override; + unsigned int GetFillMode() const override; + TPointD GetCurPos() const override; + const TXForm& GetInverseTransform() const override; + const TXForm& GetTransform(int = GM_ADVANCED) override; + unsigned int GetMiterLimit() const override; + unsigned int GetRop2Mode() const override; + int GetCharSpace() const override; + bool IsWindowFlippedY() const override; + bool IsWindowFlippedX() const override; + unsigned int GetMapMode() const override; + USHORT GetDpi() const override; + const IRegion* GetRegion() const override; + unsigned int GetArcDirection() const override; + const CPath* GetPath() const override; void SetInterpretator(IOutputDevice* pOutput); void SetInterpretator(const wchar_t *wsFilePath, InterpretatorType oInterpretatorType, unsigned int unWidth = 0, unsigned int unHeight = 0); @@ -74,11 +181,11 @@ namespace MetaFile private: void SkipVoid(); - void TranslatePoint(short shX, short shY, double& dX, double &dY); - TRectL GetBoundingBox(); - bool IsPlaceable(); - int GetRecordRemainingBytesCount(); - inline double GetSweepAngle(const double& dStartAngle, const double& dEndAngle); + void TranslatePoint(short shX, short shY, double& dX, double &dY) const; + void UpdateDCRect(); + bool IsPlaceable() const; + int GetRecordRemainingBytesCount() const; + inline double GetSweepAngle(const double& dStartAngle, const double& dEndAngle) const; void MoveTo(short shX, short shY); void LineTo(short shX, short shY); @@ -105,7 +212,6 @@ namespace MetaFile TWmfPlaceable m_oPlaceable; TWmfHeader m_oHeader; - TRectL m_oRect; TRectL m_oDCRect; CWmfPlayer m_oPlayer; diff --git a/DesktopEditor/raster/Metafile/Wmf/WmfPlayer.cpp b/DesktopEditor/raster/Metafile/Wmf/WmfPlayer.cpp index 2511c361d9e..190125b826d 100644 --- a/DesktopEditor/raster/Metafile/Wmf/WmfPlayer.cpp +++ b/DesktopEditor/raster/Metafile/Wmf/WmfPlayer.cpp @@ -236,8 +236,8 @@ namespace MetaFile { m_pBrush = &m_oDefaultBrush; m_pPen = &m_oDefaultPen; + m_pFont = &m_oDefaultFont; m_pPalette = NULL; - m_pFont = NULL; m_pRegion = NULL; m_ushMapMode = MM_TEXT; m_dPixelWidth = 1; @@ -262,7 +262,7 @@ namespace MetaFile { } - CWmfDC* CWmfDC::Copy() + CWmfDC* CWmfDC::Copy() const { CWmfDC* pNewDC = new CWmfDC(); if (!pNewDC) @@ -296,7 +296,7 @@ namespace MetaFile return pNewDC; } - CClip *CWmfDC::GetClip() + CClip* CWmfDC::GetClip() { return &m_oClip; } @@ -309,7 +309,7 @@ namespace MetaFile if (pBrush == m_pBrush) m_pBrush = NULL; } - CWmfBrush* CWmfDC::GetBrush() + const CWmfBrush* CWmfDC::GetBrush() const { return m_pBrush; } @@ -322,7 +322,7 @@ namespace MetaFile if (m_pPen == pPen) m_pPen = NULL; } - CWmfPen* CWmfDC::GetPen() + const CWmfPen* CWmfDC::GetPen() const { return m_pPen; } @@ -335,7 +335,7 @@ namespace MetaFile if (m_pPalette == pPalette) m_pPalette = NULL; } - CWmfPalette* CWmfDC::GetPalette() + const CWmfPalette* CWmfDC::GetPalette() const { return m_pPalette; } @@ -348,9 +348,9 @@ namespace MetaFile if (m_pFont == pFont) m_pFont = NULL; } - CWmfFont* CWmfDC::GetFont() + const CWmfFont* CWmfDC::GetFont() const { - return m_pFont; + return (NULL != m_pFont) ? m_pFont : &m_oDefaultFont; } void CWmfDC::SetRegion(CWmfRegion* pRegion) { @@ -361,7 +361,7 @@ namespace MetaFile if (m_pRegion == pRegion) m_pRegion = NULL; } - CWmfRegion* CWmfDC::GetRegion() + const CWmfRegion* CWmfDC::GetRegion() const { return m_pRegion; } @@ -421,15 +421,15 @@ namespace MetaFile UpdateFinalTransform(); } - unsigned int CWmfDC::GetMapMode() + unsigned int CWmfDC::GetMapMode() const { return m_ushMapMode; } - double CWmfDC::GetPixelWidth() + double CWmfDC::GetPixelWidth() const { return m_dPixelWidth; } - double CWmfDC::GetPixelHeight() + double CWmfDC::GetPixelHeight() const { return m_dPixelHeight; } @@ -441,9 +441,9 @@ namespace MetaFile { m_dPixelHeight = dH; } - TWmfWindow* CWmfDC::GetWindow() + const TWmfWindow& CWmfDC::GetWindow() const { - return &m_oWindow; + return m_oWindow; } void CWmfDC::SetWindowOrg(short shX, short shY) { @@ -457,7 +457,6 @@ namespace MetaFile m_oViewport.y = shY; } - UpdatePixelMetrics(); UpdateFinalTransform(); } void CWmfDC::SetWindowExt(short shW, short shH) @@ -482,7 +481,6 @@ namespace MetaFile { m_oWindow.x += shX; m_oWindow.y += shY; - UpdatePixelMetrics(); UpdateFinalTransform(); } void CWmfDC::SetWindowScale(double dX, double dY) @@ -492,9 +490,9 @@ namespace MetaFile UpdatePixelMetrics(); UpdateFinalTransform(); } - TWmfWindow* CWmfDC::GetViewport() + const TWmfWindow& CWmfDC::GetViewport() const { - return &m_oViewport; + return m_oViewport; } void CWmfDC::SetViewportOrg(short shX, short shY) { @@ -508,7 +506,6 @@ namespace MetaFile m_oWindow.y = shY; } - UpdatePixelMetrics(); UpdateFinalTransform(); } void CWmfDC::SetViewportExt(short shW, short shH) @@ -533,7 +530,7 @@ namespace MetaFile { m_oViewport.x += shX; m_oViewport.y += shY; - UpdatePixelMetrics(); +// UpdatePixelMetrics(); UpdateFinalTransform(); } void CWmfDC::SetViewportScale(double dX, double dY) @@ -545,7 +542,7 @@ namespace MetaFile } bool CWmfDC::UpdatePixelMetrics() { - if (1 >= m_oWindow.w || 1 >= m_oViewport.w) + if (1 >= std::abs(m_oWindow.w) || 1 >= std::abs(m_oViewport.w)) return false; unsigned short ushMapMode = m_ushMapMode; @@ -571,28 +568,31 @@ namespace MetaFile } void CWmfDC::UpdateFinalTransform() { - TWmfWindow* pWindow = GetWindow(); - TWmfWindow* pViewPort = GetViewport(); + const TWmfWindow& oWindow{GetWindow()}; + const TWmfWindow& oViewPort{GetViewport()}; - double dM11 = (pViewPort->w >= 0) ? 1 : -1; - double dM22 = (pViewPort->h >= 0) ? 1 : -1; + double dM11 = ((oViewPort.w >= 0) ? 1. : -1.) * GetPixelWidth(); + double dM22 = ((oViewPort.h >= 0) ? 1. : -1.) * GetPixelHeight(); - TEmfXForm oWindowXForm(1, 0, 0, 1, -(pWindow->x * GetPixelWidth() * dM11), -(pWindow->y * GetPixelHeight() * dM22)); - TEmfXForm oViewportXForm(GetPixelWidth() * dM11, 0, 0, GetPixelHeight() * dM22, pViewPort->x, pViewPort->y); + TEmfXForm oWindowXForm(1, 0, 0, 1, -(oWindow.x * dM11), -(oWindow.y * dM22)); + TEmfXForm oViewportXForm(dM11, 0, 0, dM22, oViewPort.x, oViewPort.y); m_oFinalTransform.Init(); - m_oFinalTransform.Multiply(oViewportXForm, MWT_RIGHTMULTIPLY); m_oFinalTransform.Multiply(m_oTransform, MWT_RIGHTMULTIPLY); + m_oFinalTransform.Multiply(oViewportXForm, MWT_RIGHTMULTIPLY); m_oFinalTransform.Multiply(oWindowXForm, MWT_RIGHTMULTIPLY); m_oFinalTransform2.Init(); + m_oFinalTransform2.Multiply(m_oTransform, MWT_RIGHTMULTIPLY); m_oFinalTransform2.Multiply(oViewportXForm, MWT_RIGHTMULTIPLY); -// m_oFinalTransform2.Multiply(m_oTransform, MWT_RIGHTMULTIPLY); m_oFinalTransform2.Multiply(oWindowXForm, MWT_RIGHTMULTIPLY); } void CWmfDC::FixIsotropic() { + if (m_oViewport.w == m_oWindow.w && m_oViewport.h == m_oWindow.h) + return; + double dXDim = std::fabs((double)m_oViewport.w / m_oWindow.w); double dYDim = std::fabs((double)m_oViewport.h / m_oWindow.h); @@ -609,11 +609,12 @@ namespace MetaFile if (!m_oViewport.h) m_oViewport.h = nMinCy; } } + void CWmfDC::SetTextColor(TRGBA& oColor) { m_oTextColor = oColor; } - TRGBA& CWmfDC::GetTextColor() + const TRGBA& CWmfDC::GetTextColor() const { return m_oTextColor; } @@ -621,11 +622,11 @@ namespace MetaFile { m_oTextBgColor = oColor; } - TRGBA& CWmfDC::GetTextBgColor() + const TRGBA& CWmfDC::GetTextBgColor() const { return m_oTextBgColor; } - TPointS &CWmfDC::GetCurPos() + const TPointS& CWmfDC::GetCurPos() const { return m_oCurPos; } @@ -642,7 +643,7 @@ namespace MetaFile { m_ushTextBgMode = ushMode; } - unsigned short CWmfDC::GetTextBgMode() + unsigned short CWmfDC::GetTextBgMode() const { return m_ushTextBgMode; } @@ -650,7 +651,7 @@ namespace MetaFile { m_ushLayout = ushLayout; } - unsigned short CWmfDC::GetLayout() + unsigned short CWmfDC::GetLayout() const { return m_ushLayout; } @@ -658,7 +659,7 @@ namespace MetaFile { m_ushPolyFillMode = ushMode; } - unsigned short CWmfDC::GetPolyFillMode() + unsigned short CWmfDC::GetPolyFillMode() const { return m_ushPolyFillMode; } @@ -666,7 +667,7 @@ namespace MetaFile { m_ushRop2Mode = ushMode; } - unsigned short CWmfDC::GetRop2Mode() + unsigned short CWmfDC::GetRop2Mode() const { return m_ushRop2Mode; } @@ -674,7 +675,7 @@ namespace MetaFile { m_ushStretchBltMode = ushMode; } - unsigned short CWmfDC::GetStretchBltMode() + unsigned short CWmfDC::GetStretchBltMode() const { return m_ushStretchBltMode; } @@ -682,7 +683,7 @@ namespace MetaFile { m_ushTextAlign = ushTextAlign; } - unsigned short CWmfDC::GetTextAlign() + unsigned short CWmfDC::GetTextAlign() const { return m_ushTextAlign; } @@ -690,26 +691,26 @@ namespace MetaFile { m_ushCharSpacing = ushCharSpacing; } - unsigned short CWmfDC::GetCharSpacing() + unsigned short CWmfDC::GetCharSpacing() const { return m_ushCharSpacing; } - TXForm* CWmfDC::GetTransform() + const TXForm& CWmfDC::GetTransform() const { - return &m_oTransform; + return m_oTransform; } - TXForm* CWmfDC::GetInverseTransform() + const TXForm& CWmfDC::GetInverseTransform() const { - return &m_oTransform; + return m_oTransform; } - TXForm* CWmfDC::GetFinalTransform(int iGraphicsMode) + const TXForm& CWmfDC::GetFinalTransform(int iGraphicsMode) const { if (GM_COMPATIBLE == iGraphicsMode) - return &m_oFinalTransform2; + return m_oFinalTransform2; - return &m_oFinalTransform; + return m_oFinalTransform; } - unsigned int CWmfDC::GetMiterLimit() + unsigned int CWmfDC::GetMiterLimit() const { return 0; } diff --git a/DesktopEditor/raster/Metafile/Wmf/WmfPlayer.h b/DesktopEditor/raster/Metafile/Wmf/WmfPlayer.h index 40a3e8263f5..e35ff4faebf 100644 --- a/DesktopEditor/raster/Metafile/Wmf/WmfPlayer.h +++ b/DesktopEditor/raster/Metafile/Wmf/WmfPlayer.h @@ -78,62 +78,62 @@ namespace MetaFile public: CWmfDC(); ~CWmfDC(); - CWmfDC* Copy(); - CClip* GetClip(); - void SetBrush(CWmfBrush* pBrush); - void RemoveBrush(CWmfBrush* pBrush); - CWmfBrush* GetBrush(); - void SetPen(CWmfPen* pPen); - void RemovePen(CWmfPen* pPen); - CWmfPen* GetPen(); - void SetPalette(CWmfPalette* pPalette); - void RemovePalette(CWmfPalette* pPalette); - CWmfPalette* GetPalette(); - void SetFont(CWmfFont* pFont); - void RemoveFont(CWmfFont* pFont); - CWmfFont* GetFont(); - void SetRegion(CWmfRegion* pRegion); - void RemoveRegion(CWmfRegion* pRegion); - CWmfRegion* GetRegion(); - void SetMapMode(unsigned short ushMapMode); - unsigned int GetMapMode(); - double GetPixelWidth(); - double GetPixelHeight(); - TWmfWindow* GetWindow(); - void SetWindowOrg(short shX, short shY); - void SetWindowExt(short shW, short shH); - void SetWindowOff(short shX, short shY); - void SetWindowScale(double dX, double dY); - TWmfWindow* GetViewport(); - void SetViewportOrg(short shX, short shY); - void SetViewportExt(short shW, short shH); - void SetViewportOff(short shX, short shY); - void SetViewportScale(double dX, double dY); - void SetTextColor(TRGBA& oColor); - TRGBA& GetTextColor(); - void SetTextBgColor(TRGBA& oColor); - TRGBA& GetTextBgColor(); - TPointS& GetCurPos(); - void SetCurPos(TPointS& oPoint); - void SetCurPos(short shX, short shY); - void SetTextBgMode(unsigned short ushMode); - unsigned short GetTextBgMode(); - void SetLayout(unsigned short ushLayout); - unsigned short GetLayout(); - void SetPolyFillMode(unsigned short ushMode); - unsigned short GetPolyFillMode(); - void SetRop2Mode(unsigned short ushMode); - unsigned short GetRop2Mode(); - void SetStretchBltMode(unsigned short ushMode); - unsigned short GetStretchBltMode(); - void SetTextAlign(unsigned short ushTextAlign); - unsigned short GetTextAlign(); - void SetCharSpacing(unsigned short ushCharSpacing); - unsigned short GetCharSpacing(); - TXForm* GetTransform(); - TXForm* GetInverseTransform(); - TXForm* GetFinalTransform(int iGraphicsMode); - unsigned int GetMiterLimit(); + CWmfDC* Copy() const; + CClip* GetClip(); + void SetBrush(CWmfBrush* pBrush); + void RemoveBrush(CWmfBrush* pBrush); + const CWmfBrush* GetBrush() const; + void SetPen(CWmfPen* pPen); + void RemovePen(CWmfPen* pPen); + const CWmfPen* GetPen() const; + void SetPalette(CWmfPalette* pPalette); + void RemovePalette(CWmfPalette* pPalette); + const CWmfPalette* GetPalette() const; + void SetFont(CWmfFont* pFont); + void RemoveFont(CWmfFont* pFont); + const CWmfFont* GetFont() const; + void SetRegion(CWmfRegion* pRegion); + void RemoveRegion(CWmfRegion* pRegion); + const CWmfRegion* GetRegion() const; + void SetMapMode(unsigned short ushMapMode); + unsigned int GetMapMode() const; + double GetPixelWidth() const; + double GetPixelHeight() const; + const TWmfWindow& GetWindow() const; + void SetWindowOrg(short shX, short shY); + void SetWindowExt(short shW, short shH); + void SetWindowOff(short shX, short shY); + void SetWindowScale(double dX, double dY); + const TWmfWindow& GetViewport() const; + void SetViewportOrg(short shX, short shY); + void SetViewportExt(short shW, short shH); + void SetViewportOff(short shX, short shY); + void SetViewportScale(double dX, double dY); + void SetTextColor(TRGBA& oColor); + const TRGBA& GetTextColor() const; + void SetTextBgColor(TRGBA& oColor); + const TRGBA& GetTextBgColor() const; + const TPointS& GetCurPos() const; + void SetCurPos(TPointS& oPoint); + void SetCurPos(short shX, short shY); + void SetTextBgMode(unsigned short ushMode); + unsigned short GetTextBgMode() const; + void SetLayout(unsigned short ushLayout); + unsigned short GetLayout() const; + void SetPolyFillMode(unsigned short ushMode); + unsigned short GetPolyFillMode() const; + void SetRop2Mode(unsigned short ushMode); + unsigned short GetRop2Mode() const; + void SetStretchBltMode(unsigned short ushMode); + unsigned short GetStretchBltMode() const; + void SetTextAlign(unsigned short ushTextAlign); + unsigned short GetTextAlign() const; + void SetCharSpacing(unsigned short ushCharSpacing); + unsigned short GetCharSpacing() const; + const TXForm& GetTransform() const; + const TXForm& GetInverseTransform() const; + const TXForm& GetFinalTransform(int iGraphicsMode) const; + unsigned int GetMiterLimit() const; private: @@ -147,6 +147,7 @@ namespace MetaFile CClip m_oClip; CWmfBrush m_oDefaultBrush; + CWmfFont m_oDefaultFont; CWmfPen m_oDefaultPen; CWmfBrush* m_pBrush; CWmfPen* m_pPen; diff --git a/DesktopEditor/raster/Metafile/Wmf/WmfTypes.h b/DesktopEditor/raster/Metafile/Wmf/WmfTypes.h index f5d4870f13e..7c45973a393 100644 --- a/DesktopEditor/raster/Metafile/Wmf/WmfTypes.h +++ b/DesktopEditor/raster/Metafile/Wmf/WmfTypes.h @@ -230,7 +230,7 @@ namespace MetaFile h = 1; } - void Copy(TWmfWindow& oOther) + void Copy(const TWmfWindow& oOther) { x = oOther.x; y = oOther.y; diff --git a/DesktopEditor/raster/Metafile/svg/CSvgFile.cpp b/DesktopEditor/raster/Metafile/svg/CSvgFile.cpp index d6b0478750e..f6df395d0f9 100644 --- a/DesktopEditor/raster/Metafile/svg/CSvgFile.cpp +++ b/DesktopEditor/raster/Metafile/svg/CSvgFile.cpp @@ -1,34 +1,39 @@ #include "CSvgFile.h" #include "SvgObjects/CContainer.h" +#include "SvgObjects/CFont.h" + +#define SVG_FILE_WIDTH 300 +#define SVG_FILE_HEIGHT 150 CSvgFile::CSvgFile() : m_oContainer(L"svg") {} CSvgFile::~CSvgFile() -{} +{ + Clear(); +} bool CSvgFile::ReadFromBuffer(BYTE *pBuffer, unsigned int unSize) { + Clear(); return false; } -bool CSvgFile::OpenFromFile(const std::wstring &wsFile) +bool CSvgFile::ReadFromWString(const std::wstring &wsContext) { Clear(); - - return m_oParser.LoadFromFile(wsFile, &m_oContainer, this); + return m_oParser.LoadFromString(wsContext, &m_oContainer, this); } -bool CSvgFile::Load(const std::wstring &wsContent) +bool CSvgFile::OpenFromFile(const std::wstring &wsFile) { - return false; -} + Clear(); -void CSvgFile::Close() -{ + m_wsWorkingDirectory = NSFile::GetDirectoryName(wsFile); + return m_oParser.LoadFromFile(wsFile, &m_oContainer, this); } bool CSvgFile::GetBounds(double &dX, double &dY, double &dWidth, double &dHeight) const @@ -38,15 +43,46 @@ bool CSvgFile::GetBounds(double &dX, double &dY, double &dWidth, double &dHeight SVG::TRect oWindow = m_oContainer.GetWindow(); - dX = oWindow.m_oX .ToDouble(NSCSS::Pixel); - dY = oWindow.m_oY .ToDouble(NSCSS::Pixel); - dWidth = oWindow.m_oWidth .ToDouble(NSCSS::Pixel); - dHeight = oWindow.m_oHeight.ToDouble(NSCSS::Pixel); + dX = oWindow.m_oX.ToDouble(NSCSS::Pixel, SVG_FILE_WIDTH); + dY = oWindow.m_oY.ToDouble(NSCSS::Pixel, SVG_FILE_HEIGHT); - if (SVG::Equals(0., dWidth)) - dWidth = (!m_oContainer.GetViewBox().m_oWidth.Empty()) ? m_oContainer.GetViewBox().m_oWidth.ToDouble(NSCSS::Pixel) : 300; - if (SVG::Equals(0., dHeight)) - dHeight = (!m_oContainer.GetViewBox().m_oHeight.Empty()) ? m_oContainer.GetViewBox().m_oHeight.ToDouble(NSCSS::Pixel) : 150; + dWidth = 0.; + dHeight = 0.; + + if (!oWindow.m_oWidth.Empty() && !oWindow.m_oWidth.Zero()) + { + if (NSCSS::Percent == oWindow.m_oWidth.GetUnitMeasure()) + { + if (!m_oContainer.GetViewBox().m_oWidth.Empty() && !m_oContainer.GetViewBox().m_oWidth.Zero()) + dWidth = oWindow.m_oWidth.ToDouble(NSCSS::Pixel, m_oContainer.GetViewBox().m_oWidth.ToDouble(NSCSS::Pixel)); + else + dWidth = oWindow.m_oWidth.ToDouble(NSCSS::Pixel, SVG_FILE_WIDTH); + } + else + dWidth = oWindow.m_oWidth.ToDouble(NSCSS::Pixel); + } + else + dWidth = m_oContainer.GetViewBox().m_oWidth.ToDouble(NSCSS::Pixel); + + if (!oWindow.m_oHeight.Empty() && !oWindow.m_oHeight.Zero()) + { + if (NSCSS::Percent == oWindow.m_oHeight.GetUnitMeasure()) + { + if (!m_oContainer.GetViewBox().m_oHeight.Empty() && !m_oContainer.GetViewBox().m_oHeight.Zero()) + dHeight = oWindow.m_oHeight.ToDouble(NSCSS::Pixel, m_oContainer.GetViewBox().m_oHeight.ToDouble(NSCSS::Pixel)); + else + dHeight = oWindow.m_oHeight.ToDouble(NSCSS::Pixel, SVG_FILE_WIDTH); + } + else + dHeight = oWindow.m_oHeight.ToDouble(NSCSS::Pixel); + } + else + dHeight = m_oContainer.GetViewBox().m_oHeight.ToDouble(NSCSS::Pixel); + + if (0. == dWidth) + dWidth = SVG_FILE_WIDTH; + if (0. == dHeight) + dHeight = SVG_FILE_HEIGHT; return true; } @@ -61,11 +97,17 @@ void CSvgFile::SetFontManager(NSFonts::IFontManager *pFontManager) m_oParser.SetFontManager(pFontManager); } +void CSvgFile::SetWorkingDirectory(const std::wstring &wsWorkingDirectory) +{ + m_wsWorkingDirectory = wsWorkingDirectory; +} + bool CSvgFile::MarkObject(SVG::CObject *pObject) { if (NULL == pObject || pObject->GetId().empty()) return false; + pObject->AddRef(); m_mMarkedObjects[pObject->GetId()] = pObject; return true; @@ -91,11 +133,31 @@ SVG::CObject *CSvgFile::GetMarkedObject(const std::wstring &wsId) const return NULL; } +SVG::CFont *CSvgFile::GetFont(const std::wstring &wsFontFamily) const +{ + FontsFaceMap::const_iterator itFound = std::find_if(m_mFontsFace.cbegin(), m_mFontsFace.cend(), [&wsFontFamily](const std::pair& oValue){ return wsFontFamily == oValue.first; }); + + if (m_mFontsFace.cend() == itFound) + return NULL; + + return dynamic_cast(GetMarkedObject(itFound->second)); +} + +std::wstring CSvgFile::GetWorkingDirectory() const +{ + return m_wsWorkingDirectory; +} + void CSvgFile::AddStyles(const std::wstring &wsStyles) { m_oSvgCalculator.AddStyles(wsStyles); } +void CSvgFile::AddFontFace(const SVG::TFontArguments& oArguments, const std::wstring &wsId) +{ + m_mFontsFace.insert(std::make_pair(oArguments.m_wsFontFamily, wsId)); +} + bool CSvgFile::Draw(IRenderer *pRenderer, double dX, double dY, double dWidth, double dHeight) { if (NULL == pRenderer || m_oContainer.Empty()) @@ -107,7 +169,7 @@ bool CSvgFile::Draw(IRenderer *pRenderer, double dX, double dY, double dWidth, d if (oWindow.m_oWidth.Empty() || oWindow.m_oWidth.Zero()) { if (oViewBox.m_oWidth.Empty() || oViewBox.m_oWidth.Zero()) - oWindow.m_oWidth = 300; + oWindow.m_oWidth = SVG_FILE_WIDTH; else { oWindow.m_oWidth = oViewBox.m_oWidth; @@ -118,7 +180,7 @@ bool CSvgFile::Draw(IRenderer *pRenderer, double dX, double dY, double dWidth, d if (oWindow.m_oHeight.Empty() || oWindow.m_oHeight.Zero()) { if (oViewBox.m_oHeight.Empty() || oViewBox.m_oHeight.Zero()) - oWindow.m_oHeight = 150; + oWindow.m_oHeight = SVG_FILE_HEIGHT; else { oWindow.m_oHeight = oViewBox.m_oHeight; @@ -126,9 +188,9 @@ bool CSvgFile::Draw(IRenderer *pRenderer, double dX, double dY, double dWidth, d } } - double dViewBoxWidth = oViewBox.m_oWidth.ToDouble(NSCSS::Pixel); - double dViewBoxHeight = oViewBox.m_oHeight.ToDouble(NSCSS::Pixel); - + double dViewBoxWidth = oViewBox.m_oWidth.ToDouble(NSCSS::Pixel, SVG_FILE_WIDTH); + double dViewBoxHeight = oViewBox.m_oHeight.ToDouble(NSCSS::Pixel, SVG_FILE_HEIGHT); + double dWindowWidth = oWindow.m_oWidth.ToDouble(NSCSS::Pixel, dViewBoxWidth); double dWindowHeight = oWindow.m_oHeight.ToDouble(NSCSS::Pixel, dViewBoxHeight); @@ -142,21 +204,15 @@ bool CSvgFile::Draw(IRenderer *pRenderer, double dX, double dY, double dWidth, d pRenderer->GetTransform(&oldTransform[0], &oldTransform[1], &oldTransform[2], &oldTransform[3], &oldTransform[4], &oldTransform[5]); pRenderer->ResetTransform(); - double dM11 = 1; - double dM22 = 1; - - if (!oWindow.m_oWidth.Empty() && !oWindow.m_oWidth.Zero()) - dM11 = dWidth / dWindowWidth; - - if (!oWindow.m_oHeight.Empty() && !oWindow.m_oHeight.Zero()) - dM22 = dHeight / dWindowHeight; + double dM11 = dWidth / dWindowWidth; + double dM22 = dHeight / dWindowHeight; double dScaleX = 1, dScaleY = 1; - if (!oWindow.m_oWidth.Empty() && !oWindow.m_oWidth.Zero() && !oViewBox.m_oWidth.Empty() && !oViewBox.m_oWidth.Zero()) + if (!SVG::Equals(0., dViewBoxWidth)) dScaleX = dWindowWidth / dViewBoxWidth; - if (!oWindow.m_oHeight.Empty() && !oWindow.m_oHeight.Zero() && !oViewBox.m_oHeight.Empty() && !oViewBox.m_oHeight.Zero()) + if (!SVG::Equals(0., dViewBoxHeight)) dScaleY = dWindowHeight / dViewBoxHeight; double dMinScale = std::min(dScaleX, dScaleY); @@ -178,11 +234,9 @@ void CSvgFile::Clear() m_oContainer.Clear(); m_oSvgCalculator.Clear(); - for (MarkedMap::iterator oIter = m_mMarkedObjects.begin(); oIter != m_mMarkedObjects.end(); ++oIter) - { - if (SVG::AppliedObject == oIter->second->GetType()) - delete oIter->second; - } + for (MarkedMap::reference oIter : m_mMarkedObjects) + RELEASEINTERFACE(oIter.second); m_mMarkedObjects.clear(); + m_wsWorkingDirectory.clear(); } diff --git a/DesktopEditor/raster/Metafile/svg/CSvgFile.h b/DesktopEditor/raster/Metafile/svg/CSvgFile.h index 4ae2d375764..8266c231728 100644 --- a/DesktopEditor/raster/Metafile/svg/CSvgFile.h +++ b/DesktopEditor/raster/Metafile/svg/CSvgFile.h @@ -7,6 +7,12 @@ #include "CSvgParser.h" #include "SvgObjects/CStyle.h" +namespace SVG +{ + struct TFontArguments; + class CFont; +} + class CSvgFile { public: @@ -14,20 +20,24 @@ class CSvgFile ~CSvgFile(); bool ReadFromBuffer(BYTE* pBuffer, unsigned int unSize); + bool ReadFromWString(const std::wstring& wsContext); bool OpenFromFile(const std::wstring& wsFile); - bool Load(const std::wstring& wsContent); - - void Close(); bool GetBounds(double& dX, double& dY, double& dWidth, double& dHeight) const; const SVG::CSvgCalculator* GetSvgCalculator() const; void SetFontManager(NSFonts::IFontManager* pFontManager); + void SetWorkingDirectory(const std::wstring& wsWorkingDirectory); bool MarkObject(SVG::CObject* pObject); SVG::CObject* GetMarkedObject(const std::wstring& wsId) const; + SVG::CFont* GetFont(const std::wstring& wsFontFamily) const; + + std::wstring GetWorkingDirectory() const; + void AddStyles(const std::wstring& wsStyles); + void AddFontFace(const SVG::TFontArguments& oArguments, const std::wstring& wsId); bool Draw(IRenderer* pRenderer, double dX, double dY, double dWidth, double dHeight); private: @@ -39,7 +49,11 @@ class CSvgFile typedef std::map MarkedMap; - MarkedMap m_mMarkedObjects; + MarkedMap m_mMarkedObjects; + std::wstring m_wsWorkingDirectory; + + typedef std::map FontsFaceMap; + FontsFaceMap m_mFontsFace; }; #endif // CSVGFILE_H diff --git a/DesktopEditor/raster/Metafile/svg/CSvgParser.cpp b/DesktopEditor/raster/Metafile/svg/CSvgParser.cpp index d1044cd6b43..6dfb5191450 100644 --- a/DesktopEditor/raster/Metafile/svg/CSvgParser.cpp +++ b/DesktopEditor/raster/Metafile/svg/CSvgParser.cpp @@ -1,18 +1,17 @@ #include "CSvgParser.h" -#include "SvgUtils.h" - -#include +#include +#include #include "CSvgFile.h" -#include "SvgObjects/CContainer.h" #include "SvgObjects/CPolyline.h" #include "SvgObjects/CGradient.h" #include "SvgObjects/CClipPath.h" #include "SvgObjects/CPattern.h" #include "SvgObjects/CEllipse.h" #include "SvgObjects/CSymbol.h" +#include "SvgObjects/CSwitch.h" #include "SvgObjects/CMarker.h" #include "SvgObjects/CCircle.h" #include "SvgObjects/CStyle.h" @@ -20,6 +19,7 @@ #include "SvgObjects/CRect.h" #include "SvgObjects/CLine.h" #include "SvgObjects/CPath.h" +#include "SvgObjects/CFont.h" #include "SvgObjects/CText.h" #include "SvgObjects/CMask.h" #include "SvgObjects/CUse.h" @@ -40,28 +40,82 @@ namespace SVG m_pFontManager = pFontManager; } + std::string FindEncoding(const std::string& wsContent) + { + size_t unEncodingBegin = wsContent.find("encoding"); + + if (std::string::npos == unEncodingBegin) + return std::string(); + + unEncodingBegin += 8; + + while (unEncodingBegin < wsContent.length() && std::isspace(wsContent[unEncodingBegin])) + ++unEncodingBegin; + + if (unEncodingBegin >= wsContent.length() || '=' != wsContent[unEncodingBegin++]) + return std::string(); + + while (unEncodingBegin < wsContent.length() && std::isspace(wsContent[unEncodingBegin])) + ++unEncodingBegin; + + if (unEncodingBegin >= wsContent.length() || ('\'' != wsContent[unEncodingBegin] && '"' != wsContent[unEncodingBegin])) + return std::string(); + + std::string::const_iterator itEncodingValueBegin = std::find_if(wsContent.cbegin() + unEncodingBegin + 1, wsContent.cend(), [](char chElement){ return !isspace(chElement);}); + + if (wsContent.cend() == itEncodingValueBegin) + return std::string(); + + std::string::const_iterator itEncodingValueEnd = std::find_if(itEncodingValueBegin, wsContent.cend(), [](char chElement){ return isspace(chElement) || '\'' == chElement || '\"' == chElement;}); + + if (wsContent.cend() == itEncodingValueEnd) + return std::string(); + + return std::string(itEncodingValueBegin, itEncodingValueEnd); + } + bool CSvgParser::LoadFromFile(const std::wstring &wsFile, CGraphicsContainer* pContainer, CSvgFile* pFile) const { if (wsFile.empty() || NULL == pFile) return false; - std::wstring wsXml; - NSFile::CFileBinary::ReadAllTextUtf8(wsFile, wsXml); + std::string sXml; + if (!NSFile::CFileBinary::ReadAllTextUtf8A(wsFile, sXml)) + return false; + + size_t unFoundBegin = sXml.find("AddStyles(oElement.GetText()); + ParseStyles(oElement.GetText(), pFile); return true; } @@ -115,6 +169,61 @@ namespace SVG return bScanResult; } + + void CSvgParser::ParseStyles(const std::wstring &wsStyles, CSvgFile *pFile) const + { + if (NULL == pFile) + return; + + pFile->AddStyles(wsStyles); + + std::wregex oRegex(L"@font-face\\s*(\\{[^}]*\\})"); + std::wsmatch oMatch; + std::wstring::const_iterator oSearchStart(wsStyles.cbegin()); + + while (std::regex_search(oSearchStart, wsStyles.cend(), oMatch, oRegex)) + { + if (oMatch[1].str().empty()) + continue; + + std::wstring wsValue{oMatch[1].str()}; + + std::wstring::const_iterator itStart = std::find_if(wsValue.cbegin(), wsValue.cend(), [](const wchar_t& wChar) { return !std::iswspace(wChar) && L'{' != wChar; }); + std::wstring::const_reverse_iterator itEnd = std::find_if(wsValue.crbegin(), wsValue.crend(), [](const wchar_t& wChar) { return !std::iswspace(wChar) && L'}' != wChar; }); + + if (wsValue.cend() != itStart && wsValue.crend() != itEnd) + wsValue = std::wstring(itStart, itEnd.base()); + + const std::vector arWords{NSCSS::NS_STATIC_FUNCTIONS::GetWordsW(wsValue, true, L":;")}; + + SvgURL oURL; + TFontArguments m_oArguments; + + for (unsigned int unIndex = 0; unIndex < arWords.size(); ++unIndex) + { + if (arWords[unIndex].length() > 3 && L"src" == arWords[unIndex].substr(0, 3) && L':' == arWords[unIndex].back() && + unIndex + 1 < arWords.size() && oURL.SetValue(arWords[++unIndex])) + { + continue; + } + else if (arWords[unIndex].length() > 11 && L"font-family" == arWords[unIndex].substr(0, 11) && L':' == arWords[unIndex].back() && + unIndex + 1 < arWords.size()) + { + const std::vector arFontFamily{NSCSS::NS_STATIC_FUNCTIONS::GetWordsW(arWords[++unIndex], false, L"\"\',;")}; + + if (arFontFamily.empty()) + continue; + + m_oArguments.m_wsFontFamily = arFontFamily.back(); + } + } + + if (!oURL.Empty() && !m_oArguments.m_wsFontFamily.empty()) + pFile->AddFontFace(m_oArguments, oURL.GetValue()); + + oSearchStart = oMatch.suffix().first; + } + } template bool CSvgParser::ReadObject(XmlUtils::CXmlNode &oElement, CContainer *pContainer, CSvgFile *pFile, CRenderedObject *pParent) const @@ -152,7 +261,7 @@ namespace SVG else if (L"image" == wsElementName) pObject = new CImage(oElement, pParent); else if (L"use" == wsElementName) - pObject = new CUse(oElement, pParent, pFile); + pObject = new CUse(oElement, pParent); else if (L"text" == wsElementName) { pObject = CText::Create(oElement, pParent, m_pFontManager); @@ -168,6 +277,11 @@ namespace SVG pObject = CTextPath::Create(oElement, pParent, m_pFontManager, pFile); ReadChildrens(oElement, (CTextPath*)pObject, pFile); } + else if (L"switch" == wsElementName) + { + pObject = new CSwitch(oElement, pParent); + ReadChildrens(oElement, (CSwitch*)pObject, pFile); + } //defs else if (L"defs" == wsElementName) return ReadChildrens(oElement, NULL, pFile); @@ -223,6 +337,10 @@ namespace SVG else RELEASEOBJECT(pObject); } + else if (L"font" == wsElementName) + { + pObject = new CFont(oElement); + } if (NULL != pObject) { diff --git a/DesktopEditor/raster/Metafile/svg/CSvgParser.h b/DesktopEditor/raster/Metafile/svg/CSvgParser.h index 61ba7b72b98..b0b298c3d6d 100644 --- a/DesktopEditor/raster/Metafile/svg/CSvgParser.h +++ b/DesktopEditor/raster/Metafile/svg/CSvgParser.h @@ -1,8 +1,8 @@ #ifndef CSVGPARSER_H #define CSVGPARSER_H -#include "../../graphics/pro/Fonts.h" #include "../../../common/Directory.h" +#include "../../../graphics/pro/Fonts.h" #include "../../../xml/include/xmlutils.h" #include "SvgObjects/CContainer.h" @@ -20,7 +20,7 @@ namespace SVG void SetFontManager(NSFonts::IFontManager* pFontManager); bool LoadFromFile(const std::wstring& wsFile, CGraphicsContainer* pContainer, CSvgFile* pFile) const; - bool LoadFromString(const std::wstring& wsContente, CGraphicsContainer* pContainer, CSvgFile* pFile) const; + bool LoadFromString(const std::wstring& wsContentent, CGraphicsContainer* pContainer, CSvgFile* pFile) const; bool LoadFromXmlNode(XmlUtils::CXmlNode& oElement, CGraphicsContainer* pContainer, CSvgFile* pFile) const; template @@ -30,6 +30,7 @@ namespace SVG bool ReadChildrens(XmlUtils::CXmlNode& oElement, CContainer* pContainer, CSvgFile* pFile, CRenderedObject* pParent = NULL) const; bool ScanStyles(XmlUtils::CXmlNode& oElement, CSvgFile* pFile) const; + void ParseStyles(const std::wstring& wsStyles, CSvgFile *pFile) const; void UpdateStyles(CObject* pObject, CSvgFile* pFile) const; bool MarkObject(CObject* pObject, CSvgFile* pFile) const; diff --git a/DesktopEditor/raster/Metafile/svg/SvgObjects/CCircle.cpp b/DesktopEditor/raster/Metafile/svg/SvgObjects/CCircle.cpp index 97d51fff376..fdc7f15b453 100644 --- a/DesktopEditor/raster/Metafile/svg/SvgObjects/CCircle.cpp +++ b/DesktopEditor/raster/Metafile/svg/SvgObjects/CCircle.cpp @@ -21,7 +21,7 @@ namespace SVG SetFill(mAttributes, ushLevel, bHardMode); } - bool CCircle::Draw(IRenderer *pRenderer, const CSvgFile *pFile, CommandeMode oMode, const TSvgStyles *pOtherStyles) const + bool CCircle::Draw(IRenderer *pRenderer, const CSvgFile *pFile, CommandeMode oMode, const TSvgStyles *pOtherStyles, const CRenderedObject* pContexObject) const { Aggplus::CMatrix oOldTransform; @@ -37,17 +37,17 @@ namespace SVG pRenderer->PathCommandMoveTo(dX + dR, dY); pRenderer->PathCommandArcTo(dX - dR, dY - dR, dR * 2.0, dR * 2.0, 0, 360); - EndPath(pRenderer, pFile, oOldTransform, oMode, pOtherStyles); + EndPath(pRenderer, pFile, oOldTransform, oMode, pOtherStyles, pContexObject); return true; } - void CCircle::ApplyStyle(IRenderer *pRenderer, const TSvgStyles *pStyles, const CSvgFile *pFile, int &nTypePath) const + void CCircle::ApplyStyle(IRenderer *pRenderer, const TSvgStyles *pStyles, const CSvgFile *pFile, int &nTypePath, const CRenderedObject* pContexObject) const { - if (ApplyStroke(pRenderer, &pStyles->m_oStroke)) + if (ApplyStroke(pRenderer, &pStyles->m_oStroke, false, pContexObject)) nTypePath += c_nStroke; - if (ApplyFill(pRenderer, &pStyles->m_oFill, pFile, true)) + if (ApplyFill(pRenderer, &pStyles->m_oFill, pFile, true, pContexObject)) nTypePath += c_nWindingFillMode; } diff --git a/DesktopEditor/raster/Metafile/svg/SvgObjects/CCircle.h b/DesktopEditor/raster/Metafile/svg/SvgObjects/CCircle.h index 5f4c2f85186..68fc95b9a44 100644 --- a/DesktopEditor/raster/Metafile/svg/SvgObjects/CCircle.h +++ b/DesktopEditor/raster/Metafile/svg/SvgObjects/CCircle.h @@ -12,9 +12,9 @@ namespace SVG void SetData(const std::map& mAttributes, unsigned short ushLevel, bool bHardMode = false) override; - bool Draw(IRenderer* pRenderer, const CSvgFile *pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pOtherStyles = NULL) const override; + bool Draw(IRenderer* pRenderer, const CSvgFile *pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pOtherStyles = NULL, const CRenderedObject* pContexObject = NULL) const override; private: - void ApplyStyle(IRenderer* pRenderer, const TSvgStyles* pStyles, const CSvgFile *pFile, int& nTypePath) const override; + void ApplyStyle(IRenderer* pRenderer, const TSvgStyles* pStyles, const CSvgFile *pFile, int& nTypePath, const CRenderedObject* pContexObject = NULL) const override; TBounds GetBounds() const override; diff --git a/DesktopEditor/raster/Metafile/svg/SvgObjects/CClipPath.cpp b/DesktopEditor/raster/Metafile/svg/SvgObjects/CClipPath.cpp index 1e3999f931a..6e26551035a 100644 --- a/DesktopEditor/raster/Metafile/svg/SvgObjects/CClipPath.cpp +++ b/DesktopEditor/raster/Metafile/svg/SvgObjects/CClipPath.cpp @@ -23,8 +23,8 @@ namespace SVG if (NULL == pRenderer || NULL == pFile) return false; - ApplyClip(pRenderer, &m_oTransformtaion.m_oClip, pFile, oObjectBounds); - + ApplyClip(pRenderer, &m_oTransformation.m_oClip, pFile, oObjectBounds); + for (const CRenderedObject* pObject : m_oContainer.m_arObjects) pObject->Draw(pRenderer, pFile, CommandeModeClip); diff --git a/DesktopEditor/raster/Metafile/svg/SvgObjects/CContainer.cpp b/DesktopEditor/raster/Metafile/svg/SvgObjects/CContainer.cpp index c33e980a0d1..f6126cd9c07 100644 --- a/DesktopEditor/raster/Metafile/svg/SvgObjects/CContainer.cpp +++ b/DesktopEditor/raster/Metafile/svg/SvgObjects/CContainer.cpp @@ -9,12 +9,20 @@ namespace SVG : CRenderedObject(NSCSS::CNode(wsName, L"", L"")) {} + CGraphicsContainer::~CGraphicsContainer() + { + for (CRenderedObject* pObject : m_arObjects) + pObject->m_pParent = NULL; + } + void CGraphicsContainer::SetData(XmlUtils::CXmlNode &oNode) { + SetNodeData(oNode); + m_oWindow.m_oX .SetValue(oNode.GetAttribute(L"x")); m_oWindow.m_oY .SetValue(oNode.GetAttribute(L"y")); - m_oWindow.m_oWidth .SetValue(oNode.GetAttribute(L"width")); - m_oWindow.m_oHeight.SetValue(oNode.GetAttribute(L"height")); + m_oWindow.m_oWidth .SetValue(oNode.GetAttribute(L"width"), 0, true); + m_oWindow.m_oHeight.SetValue(oNode.GetAttribute(L"height"), 0, true); const std::wstring wsViewBox = oNode.GetAttribute(L"viewBox"); @@ -29,6 +37,8 @@ namespace SVG m_oViewBox.m_oHeight = arValues[3]; } } + else + m_oViewBox = m_oWindow; } CGraphicsContainer::CGraphicsContainer(XmlUtils::CXmlNode& oNode, CRenderedObject *pParent) @@ -41,17 +51,17 @@ namespace SVG : CRenderedObject(oNode, pParent), m_oWindow{0, 0, dWidth, dHeight} {} - bool CGraphicsContainer::Draw(IRenderer *pRenderer, const CSvgFile *pFile, CommandeMode oMode, const TSvgStyles *pOtherStyles) const + bool CGraphicsContainer::Draw(IRenderer *pRenderer, const CSvgFile *pFile, CommandeMode oMode, const TSvgStyles *pOtherStyles, const CRenderedObject* pContexObject) const { Aggplus::CMatrix oOldTransform; - if (!StartPath(pRenderer, pFile, oOldTransform, oMode)) + if (!StartPath(pRenderer, pFile, oOldTransform, CommandeModeDraw)) return false; for (const CRenderedObject* pObject : m_arObjects) - pObject->Draw(pRenderer, pFile, oMode, pOtherStyles); + pObject->Draw(pRenderer, pFile, oMode, pOtherStyles, pContexObject); - EndPath(pRenderer, pFile, oOldTransform, oMode, pOtherStyles); + EndPath(pRenderer, pFile, oOldTransform, CommandeModeDraw, pOtherStyles, pContexObject); return true; } diff --git a/DesktopEditor/raster/Metafile/svg/SvgObjects/CContainer.h b/DesktopEditor/raster/Metafile/svg/SvgObjects/CContainer.h index bc12b5bf795..b1aed738104 100644 --- a/DesktopEditor/raster/Metafile/svg/SvgObjects/CContainer.h +++ b/DesktopEditor/raster/Metafile/svg/SvgObjects/CContainer.h @@ -3,8 +3,6 @@ #include "CObjectBase.h" -#include "../../../graphics/pro/Fonts.h" - class CSvgFile; namespace SVG @@ -16,20 +14,22 @@ namespace SVG { public: CContainer(){} - ~CContainer() + virtual ~CContainer() { Clear(); } - void Clear() + virtual void Clear() { for (TypeObject* pObject : m_arObjects) - delete pObject; + RELEASEINTERFACE(pObject); + + m_arObjects.clear(); } bool Empty() const { - return m_arObjects.empty(); + return m_arObjects.empty(); } virtual bool AddObject(TypeObject* pObject) @@ -68,6 +68,7 @@ namespace SVG friend class CMask; friend class CTSpan; friend class CMarker; + friend class CSwitch; friend class CPattern; friend class CGradient; friend class CClipPath; @@ -82,11 +83,12 @@ namespace SVG CGraphicsContainer(const std::wstring& wsName = L"GraphicsContainer"); CGraphicsContainer(XmlUtils::CXmlNode& oNode, CRenderedObject* pParent = NULL); CGraphicsContainer(double dWidth, double dHeight, XmlUtils::CXmlNode& oNode, CRenderedObject* pParent = NULL); - CGraphicsContainer(const CGraphicsContainer& oGraphicsContainer); + + virtual ~CGraphicsContainer(); void SetData(XmlUtils::CXmlNode& oNode); - bool Draw(IRenderer* pRenderer, const CSvgFile *pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pOtherStyles = NULL) const override; + bool Draw(IRenderer* pRenderer, const CSvgFile *pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pOtherStyles = NULL, const CRenderedObject* pContexObject = NULL) const override; TRect GetWindow() const; TRect GetViewBox() const; diff --git a/DesktopEditor/raster/Metafile/svg/SvgObjects/CEllipse.cpp b/DesktopEditor/raster/Metafile/svg/SvgObjects/CEllipse.cpp index b90619d0b2d..ec40479098c 100644 --- a/DesktopEditor/raster/Metafile/svg/SvgObjects/CEllipse.cpp +++ b/DesktopEditor/raster/Metafile/svg/SvgObjects/CEllipse.cpp @@ -22,7 +22,7 @@ namespace SVG SetFill(mAttributes, ushLevel, bHardMode); } - bool CEllipse::Draw(IRenderer *pRenderer, const CSvgFile *pFile, CommandeMode oMode, const TSvgStyles *pOtherStyles) const + bool CEllipse::Draw(IRenderer *pRenderer, const CSvgFile *pFile, CommandeMode oMode, const TSvgStyles *pOtherStyles, const CRenderedObject* pContexObject) const { Aggplus::CMatrix oOldTransform; @@ -42,17 +42,17 @@ namespace SVG pRenderer->PathCommandMoveTo(dX + dRx, dY); pRenderer->PathCommandArcTo(dX - dRx, dY - dRy, dRx * 2.0, dRy * 2.0, 0, 360); - EndPath(pRenderer, pFile, oOldTransform, oMode, pOtherStyles); + EndPath(pRenderer, pFile, oOldTransform, oMode, pOtherStyles, pContexObject); return true; } - void CEllipse::ApplyStyle(IRenderer *pRenderer, const TSvgStyles *pStyles, const CSvgFile *pFile, int &nTypePath) const + void CEllipse::ApplyStyle(IRenderer *pRenderer, const TSvgStyles *pStyles, const CSvgFile *pFile, int &nTypePath, const CRenderedObject* pContexObject) const { - if (ApplyStroke(pRenderer, &pStyles->m_oStroke)) + if (ApplyStroke(pRenderer, &pStyles->m_oStroke, false, pContexObject)) nTypePath += c_nStroke; - if (ApplyFill(pRenderer, &pStyles->m_oFill, pFile, true)) + if (ApplyFill(pRenderer, &pStyles->m_oFill, pFile, true, pContexObject)) nTypePath += c_nWindingFillMode; } diff --git a/DesktopEditor/raster/Metafile/svg/SvgObjects/CEllipse.h b/DesktopEditor/raster/Metafile/svg/SvgObjects/CEllipse.h index 86f543fee80..a6f01a97cdc 100644 --- a/DesktopEditor/raster/Metafile/svg/SvgObjects/CEllipse.h +++ b/DesktopEditor/raster/Metafile/svg/SvgObjects/CEllipse.h @@ -13,9 +13,9 @@ namespace SVG void SetData(const std::map& mAttributes, unsigned short ushLevel, bool bHardMode = false) override; - bool Draw(IRenderer* pRenderer, const CSvgFile *pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pOtherStyles = NULL) const override; + bool Draw(IRenderer* pRenderer, const CSvgFile *pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pOtherStyles = NULL, const CRenderedObject* pContexObject = NULL) const override; private: - void ApplyStyle(IRenderer* pRenderer, const TSvgStyles* pStyles, const CSvgFile *pFile, int& nTypePath) const override; + void ApplyStyle(IRenderer* pRenderer, const TSvgStyles* pStyles, const CSvgFile *pFile, int& nTypePath, const CRenderedObject* pContexObject = NULL) const override; TBounds GetBounds() const override; diff --git a/DesktopEditor/raster/Metafile/svg/SvgObjects/CFont.cpp b/DesktopEditor/raster/Metafile/svg/SvgObjects/CFont.cpp new file mode 100644 index 00000000000..0aba76424cd --- /dev/null +++ b/DesktopEditor/raster/Metafile/svg/SvgObjects/CFont.cpp @@ -0,0 +1,157 @@ +#include "CFont.h" + +namespace SVG +{ + CGlyph::CGlyph(XmlUtils::CXmlNode &oNode) + : CPath(oNode) + { + std::wstring wsUnicode(oNode.GetAttribute(L"unicode")); + + if (!wsUnicode.empty()) + m_wchUnicode = wsUnicode[0]; + + m_oHorizAdvX.SetValue(oNode.GetAttributeOrValue(L"horiz-adv-x")); + } + + wchar_t CGlyph::GetUnicode() const + { + return m_wchUnicode; + } + + CFontFace::CFontFace(XmlUtils::CXmlNode &oNode) + { + + } + + CFont::CFont(XmlUtils::CXmlNode &oNode) + : CAppliedObject(oNode), m_pMissingGlyph(NULL) + { + ParseGlyphs(oNode); + + m_oArguments.m_wsFontVariant = oNode.GetAttribute(L"font-variant"); + m_oArguments.m_wsFontStyle = oNode.GetAttribute(L"font-style"); + m_oArguments.m_wsFontWidght = oNode.GetAttribute(L"font-weight"); + + m_oHorizAdvX.SetValue(oNode.GetAttributeOrValue(L"horiz-adv-x")); + } + + CFont::~CFont() + { + for (std::pair oElement : m_mGlyphs) + RELEASEOBJECT(oElement.second); + + RELEASEOBJECT(m_pMissingGlyph); + } + + void CFont::SetData(const std::map &mAttributes, unsigned short ushLevel, bool bHardMode) + { + } + + bool CFont::Apply(IRenderer *pRenderer, const CSvgFile *pFile, const TBounds &oObjectBounds) + { + return false; + } + + bool CFont::Draw(const std::wstring &wsText, const double& dX, const double& dY, const double& dFontHeight, IRenderer *pRenderer, const CSvgFile *pFile, CommandeMode oMode, const TSvgStyles *pStyles, const CRenderedObject* pContexObject) const + { + if (NULL == pRenderer || wsText.empty()) + return false; + + double dM11, dM12, dM21, dM22, dRx, dRy; + + pRenderer->GetTransform(&dM11, &dM12, &dM21, &dM22, &dRx, &dRy); + + Aggplus::CMatrix oMatrix(dM11, dM12, dM21, dM22, dRx, dRy); + oMatrix.Translate(dX, dY); + + MGlyphsMap::const_iterator itFound; + double dGlyphScale = 1.; + + #define DrawGlyph(glyphPtr, function) \ + const TBounds oGlyphBound{glyphPtr->GetBounds()};\ + if (Equals(0., dFontHeight) || Equals(oGlyphBound.m_dBottom, oGlyphBound.m_dTop) || Equals(oGlyphBound.m_dRight, oGlyphBound.m_dLeft)) \ + continue; \ + dGlyphScale = dFontHeight / 1000.; \ + if (!Equals(1., dGlyphScale)) \ + { \ + oMatrix.Scale(dGlyphScale, -dGlyphScale); \ + pRenderer->SetTransform(oMatrix.sx(), oMatrix.shy(), oMatrix.shx(), oMatrix.sy(), oMatrix.tx(), oMatrix.ty()); \ + } \ + function; \ + if (!Equals(1., dGlyphScale)) \ + { \ + oMatrix.Scale(1. / dGlyphScale, -1. / dGlyphScale); \ + pRenderer->SetTransform(oMatrix.sx(), oMatrix.shy(), oMatrix.shx(), oMatrix.sy(), oMatrix.tx(), oMatrix.ty()); \ + } \ + + for (wchar_t wchGlyph : wsText) + { + itFound = m_mGlyphs.find(wchGlyph); + + if (m_mGlyphs.cend() == itFound) + { + if (NULL == m_pMissingGlyph) + continue; + + DrawGlyph(m_pMissingGlyph, m_pMissingGlyph->Draw(pRenderer, pFile, oMode, pStyles, pContexObject)) + + oMatrix.Translate(m_oHorizAdvX.ToDouble(NSCSS::Pixel), 0); + } + else + { + DrawGlyph(itFound->second, itFound->second->Draw(pRenderer, pFile, oMode, pStyles, pContexObject)) + + if (!itFound->second->m_oHorizAdvX.Empty()) + oMatrix.Translate(itFound->second->m_oHorizAdvX.ToDouble(NSCSS::Pixel), 0); + else + oMatrix.Translate(m_oHorizAdvX.ToDouble(NSCSS::Pixel), 0); + } + + pRenderer->SetTransform(oMatrix.sx(), oMatrix.shy(), oMatrix.shx(), -oMatrix.sy(), oMatrix.tx(), oMatrix.ty()); + } + + pRenderer->SetTransform(dM11, dM12, dM21, dM22, dRx, dRy); + + return true; + } + + void CFont::ParseGlyphs(XmlUtils::CXmlNode &oNode) + { + std::vector arChilds; + + if (!oNode.GetChilds(arChilds) || arChilds.empty()) + return; + + for (XmlUtils::CXmlNode& oChild : arChilds) + { + if (L"glyph" == oChild.GetName()) + { + CGlyph *pGlyph = new CGlyph(oChild); + + if (NULL == pGlyph) + continue; + + if (m_mGlyphs.end() == m_mGlyphs.find(pGlyph->GetUnicode())) + m_mGlyphs.insert(std::make_pair(pGlyph->GetUnicode(), pGlyph)); + else + delete pGlyph; + } + else if (L"missing-glyph" == oChild.GetName()) + { + std::vector arMissingGlyphChilds; + if (!oChild.GetChilds(arMissingGlyphChilds) || arMissingGlyphChilds.empty()) + continue; + + for (XmlUtils::CXmlNode& oChildMissingGlyph : arMissingGlyphChilds) + { + if (L"path" == oChildMissingGlyph.GetName()) + { + m_pMissingGlyph = new CPath(oChildMissingGlyph); + if (NULL != m_pMissingGlyph) + break; + } + } + } + } + } +} diff --git a/DesktopEditor/raster/Metafile/svg/SvgObjects/CFont.h b/DesktopEditor/raster/Metafile/svg/SvgObjects/CFont.h new file mode 100644 index 00000000000..bf32786bbe0 --- /dev/null +++ b/DesktopEditor/raster/Metafile/svg/SvgObjects/CFont.h @@ -0,0 +1,61 @@ +#ifndef CFONT_H +#define CFONT_H + +#include "CPath.h" + +namespace SVG +{ + class CGlyph : public CPath + { + public: + CGlyph(XmlUtils::CXmlNode& oNode); + + wchar_t GetUnicode() const; + private: + wchar_t m_wchUnicode; + SvgDigit m_oHorizAdvX; + + friend class CFont; + }; + + class CFontFace + { + public: + CFontFace(XmlUtils::CXmlNode& oNode); + private: + std::wstring m_wsSrcFaceName; + }; + + struct TFontArguments + { + std::wstring m_wsFontFamily; + std::wstring m_wsFontVariant; + std::wstring m_wsFontStyle; + std::wstring m_wsFontWidght; + }; + + class CFont : public CAppliedObject + { + public: + CFont(XmlUtils::CXmlNode& oNode); + ~CFont(); + + void SetData(const std::map &mAttributes, unsigned short ushLevel, bool bHardMode) override; + + bool Apply(IRenderer* pRenderer, const CSvgFile *pFile, const TBounds &oObjectBounds) override; + bool Draw(const std::wstring& wsText, const double& dX, const double& dY, const double& dFontHeight, IRenderer* pRenderer, const CSvgFile *pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pStyles = NULL, const CRenderedObject* pContexObject = NULL) const; + private: + void ParseGlyphs(XmlUtils::CXmlNode& oNode); + + TFontArguments m_oArguments; + + typedef std::map MGlyphsMap; + + MGlyphsMap m_mGlyphs; + CPath *m_pMissingGlyph; + + SvgDigit m_oHorizAdvX; + }; +} + +#endif // CFONT_H diff --git a/DesktopEditor/raster/Metafile/svg/SvgObjects/CGradient.cpp b/DesktopEditor/raster/Metafile/svg/SvgObjects/CGradient.cpp index 0e3aa5335bf..d20b26f5cc0 100644 --- a/DesktopEditor/raster/Metafile/svg/SvgObjects/CGradient.cpp +++ b/DesktopEditor/raster/Metafile/svg/SvgObjects/CGradient.cpp @@ -52,37 +52,21 @@ namespace SVG bool CGradient::Apply(IRenderer *pRenderer, const CSvgFile *pFile, const TBounds &oObjectBounds) { - if (NULL == pRenderer) + if (NULL == pRenderer || m_arObjects.empty()) return false; - if (m_arObjects.empty()) - { - if (m_wsXlinkHref.empty() || NULL == pFile) - return false; - - CGradient *pGradiend = dynamic_cast(pFile->GetMarkedObject(m_wsXlinkHref)); + std::vector arColors; + std::vector arPositions; - if (NULL == pGradiend) - return false; - - pGradiend->Apply(pRenderer, pFile, oObjectBounds); - } - else + for (const CStopElement* pStopElement : m_arObjects) { - std::vector arColors; - std::vector arPositions; - - for (const CStopElement* pStopElement : m_arObjects) - { - arColors.push_back(((unsigned int)(pStopElement->GetColor().ToInt() | ((unsigned char)(255. * pStopElement->GetColor().GetOpacity()) << 24)))); - arPositions.push_back(pStopElement->GetOffset().ToDouble()); - } - - pRenderer->put_BrushGradientColors(arColors.data(), arPositions.data(), arColors.size()); + arColors.push_back(((unsigned int)(pStopElement->GetColor().ToInt() | ((unsigned char)(255. * pStopElement->GetColor().GetOpacity()) << 24)))); + arPositions.push_back(pStopElement->GetOffset().ToDouble()); } - + + pRenderer->put_BrushGradientColors(arColors.data(), arPositions.data(), arColors.size()); pRenderer->put_BrushTransform(m_oTransform.GetMatrix().GetFinalValue()); - + return true; } @@ -108,6 +92,31 @@ namespace SVG pRenderer->BrushBounds(oNewBounds.m_dLeft, oNewBounds.m_dTop, oNewBounds.m_dRight - oNewBounds.m_dLeft, oNewBounds.m_dBottom - oNewBounds.m_dTop); } + CGradient *CGradient::GetRefGradient(const CSvgFile *pFile) const + { + if (m_wsXlinkHref.empty() || NULL == pFile) + return NULL; + + CGradient *pGradiend = dynamic_cast(pFile->GetMarkedObject(m_wsXlinkHref)); + + if (NULL == pGradiend) + return NULL; + + CGradient *pRefGradient = pGradiend->GetRefGradient(pFile); + + return (NULL != pRefGradient) ? pRefGradient : pGradiend; + } + + bool CGradient::ApplyRefGradient(IRenderer *pRenderer, const CSvgFile *pFile, const TBounds &oObjectBounds) const + { + CGradient *pRefGradient = GetRefGradient(pFile); + + if (NULL == pRefGradient) + return false; + + return pRefGradient->Apply(pRenderer, pFile, oObjectBounds); + } + CLinearGradient::CLinearGradient(XmlUtils::CXmlNode& oNode) : CGradient(oNode) { @@ -120,10 +129,8 @@ namespace SVG bool CLinearGradient::Apply(IRenderer *pRenderer, const CSvgFile *pFile, const TBounds &oObjectBounds) { if (!CGradient::Apply(pRenderer, pFile, oObjectBounds)) - return false; + return ApplyRefGradient(pRenderer, pFile, oObjectBounds); - pRenderer->put_BrushType(c_BrushTypePathGradient1); - if (m_oX1 == m_oX2 && m_oY1 == m_oY2) { pRenderer->put_BrushType(c_BrushTypeSolid); @@ -132,6 +139,8 @@ namespace SVG return true; } + pRenderer->put_BrushType(c_BrushTypePathGradient1); + double dAngle = 0.; TBounds oNewBounds(oObjectBounds); @@ -171,8 +180,8 @@ namespace SVG bool CRadialGradient::Apply(IRenderer *pRenderer, const CSvgFile *pFile, const TBounds &oObjectBounds) { if (!CGradient::Apply(pRenderer, pFile, oObjectBounds) || m_oR.Zero()) - return false; - + return ApplyRefGradient(pRenderer, pFile, oObjectBounds); + double dCX = (oObjectBounds.m_dRight + oObjectBounds.m_dLeft) / 2.; double dCY = (oObjectBounds.m_dBottom + oObjectBounds.m_dTop) / 2.; double dR = oObjectBounds.m_dBottom - oObjectBounds.m_dTop; diff --git a/DesktopEditor/raster/Metafile/svg/SvgObjects/CGradient.h b/DesktopEditor/raster/Metafile/svg/SvgObjects/CGradient.h index 0c73ada939e..c5b0b6f4438 100644 --- a/DesktopEditor/raster/Metafile/svg/SvgObjects/CGradient.h +++ b/DesktopEditor/raster/Metafile/svg/SvgObjects/CGradient.h @@ -47,6 +47,9 @@ namespace SVG bool Apply(IRenderer* pRenderer, const CSvgFile *pFile, const TBounds &oObjectBounds) override; void ApplyTransform(IRenderer *pRenderer, const TBounds& oBounds, double& dAngle) const; private: + CGradient* GetRefGradient(const CSvgFile *pFile) const; + bool ApplyRefGradient(IRenderer *pRenderer, const CSvgFile *pFile, const TBounds &oObjectBounds) const; + std::wstring m_wsXlinkHref; GradientUnits m_enGradientUnits; SpreadMethod m_enSpreadMethod; diff --git a/DesktopEditor/raster/Metafile/svg/SvgObjects/CImage.cpp b/DesktopEditor/raster/Metafile/svg/SvgObjects/CImage.cpp index 79dfb743f0e..3c9908fc8f0 100644 --- a/DesktopEditor/raster/Metafile/svg/SvgObjects/CImage.cpp +++ b/DesktopEditor/raster/Metafile/svg/SvgObjects/CImage.cpp @@ -1,9 +1,10 @@ #include "CImage.h" -#include "CStyle.h" -#include "CContainer.h" +#include "../CSvgFile.h" #include "../../graphics/Image.h" #include "../../../BgraFrame.h" +#include "../../../../common/Path.h" +#include "../../../../common/ProcessEnv.h" namespace SVG { @@ -18,28 +19,13 @@ namespace SVG m_wsHref = oNode.GetAttribute(L"href", oNode.GetAttribute(L"xlink:href")); // TODO:: В дальнейшем возможно стоит реализовать отдельный класс CHref для всех типов ссылок } - bool CImage::Draw(IRenderer *pRenderer, const CSvgFile *pFile, CommandeMode oMode, const TSvgStyles *pOtherStyles) const + bool CImage::Draw(IRenderer *pRenderer, const CSvgFile *pFile, CommandeMode oMode, const TSvgStyles *pOtherStyles, const CRenderedObject* pContexObject) const { Aggplus::CMatrix oOldTransform; if (m_wsHref.empty() || !StartPath(pRenderer, pFile, oOldTransform, oMode)) return false; - size_t unStart = m_wsHref.find(L"data:image"); - - if (std::wstring::npos == unStart) - return false; - - size_t unType = m_wsHref.find(L";base64", unStart); - - if (std::wstring::npos == unType) - return false; - - const std::wstring wsImageType = m_wsHref.substr(unStart + 11, unType - unStart - 11); - - if (L"png" != wsImageType && L"jpeg" != wsImageType) - return false; - TBounds oBounds = (NULL != m_pParent) ? m_pParent->GetBounds() : TBounds{0., 0., 0., 0.}; double dParentWidth = oBounds.m_dRight - oBounds.m_dLeft; @@ -50,19 +36,53 @@ namespace SVG double dWidth = m_oRect.m_oWidth .ToDouble(NSCSS::Pixel, dParentWidth); double dHeight = m_oRect.m_oHeight.ToDouble(NSCSS::Pixel, dParentHeight); - std::wstring wsImageData = m_wsHref.substr(unType + 8, m_wsHref.length() - unType - 8); - BYTE* pBuffer; - int unSize = NSBase64::Base64DecodeGetRequiredLength(wsImageData.length()); + BYTE* pBuffer = NULL; + DWORD ulSize = 0; + size_t unStart = m_wsHref.find(L"data:image"); + + if (std::wstring::npos != unStart) + { + size_t unType = m_wsHref.find(L";base64", unStart); + + if (std::wstring::npos == unType) + return false; - pBuffer = new BYTE[unSize]; + const std::wstring wsImageType = m_wsHref.substr(unStart + 11, unType - unStart - 11); + + if (L"png" != wsImageType && L"jpeg" != wsImageType) + return false; + + std::wstring wsImageData = m_wsHref.substr(unType + 8, m_wsHref.length() - unType - 8); + ulSize = NSBase64::Base64DecodeGetRequiredLength(wsImageData.length()); + + pBuffer = new BYTE[ulSize]; + + NSBase64::Base64Decode(wsImageData.c_str(), wsImageData.length(), pBuffer, &(int&)ulSize); + } + #ifndef METAFILE_DISABLE_FILESYSTEM + else + { + std::wstring wsFilePath = NSSystemPath::ShortenPath(m_wsHref); + + bool bIsAllowExternalLocalFiles = true; + if (NSProcessEnv::IsPresent(NSProcessEnv::Converter::gc_allowPrivateIP)) + bIsAllowExternalLocalFiles = NSProcessEnv::GetBoolValue(NSProcessEnv::Converter::gc_allowPrivateIP); + + if (!bIsAllowExternalLocalFiles && wsFilePath.length() >= 3 && L"../" == wsFilePath.substr(0, 3)) + return false; + + wsFilePath = pFile->GetWorkingDirectory() + L'/' + wsFilePath; + + if (!NSFile::CFileBinary::Exists(wsFilePath) || !NSFile::CFileBinary::ReadAllBytes(wsFilePath, &pBuffer, ulSize)) + return false; + } + #endif if (NULL == pBuffer) return false; - NSBase64::Base64Decode(wsImageData.c_str(), wsImageData.length(), pBuffer, &unSize); - CBgraFrame oBgraFrame; - oBgraFrame.Decode(pBuffer, unSize); + oBgraFrame.Decode(pBuffer, ulSize); double dImageW = oBgraFrame.get_Width(); double dImageH = oBgraFrame.get_Height(); @@ -94,7 +114,7 @@ namespace SVG pRenderer->PathCommandClose(); } - EndPath(pRenderer, pFile, oOldTransform, oMode, pOtherStyles); + EndPath(pRenderer, pFile, oOldTransform, oMode, pOtherStyles, pContexObject); delete[] pBuffer; diff --git a/DesktopEditor/raster/Metafile/svg/SvgObjects/CImage.h b/DesktopEditor/raster/Metafile/svg/SvgObjects/CImage.h index ab37eef19f2..389ee46d0fb 100644 --- a/DesktopEditor/raster/Metafile/svg/SvgObjects/CImage.h +++ b/DesktopEditor/raster/Metafile/svg/SvgObjects/CImage.h @@ -10,7 +10,7 @@ namespace SVG public: CImage(XmlUtils::CXmlNode& oNode, CRenderedObject* pParent = NULL); - bool Draw(IRenderer* pRenderer, const CSvgFile *pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pOtherStyles = NULL) const override; + bool Draw(IRenderer* pRenderer, const CSvgFile *pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pOtherStyles = NULL, const CRenderedObject* pContexObject = NULL) const override; private: TBounds GetBounds() const override; diff --git a/DesktopEditor/raster/Metafile/svg/SvgObjects/CLine.cpp b/DesktopEditor/raster/Metafile/svg/SvgObjects/CLine.cpp index e75d1d13960..c25329ede42 100644 --- a/DesktopEditor/raster/Metafile/svg/SvgObjects/CLine.cpp +++ b/DesktopEditor/raster/Metafile/svg/SvgObjects/CLine.cpp @@ -27,9 +27,9 @@ namespace SVG SetMarker(mAttributes, ushLevel, bHardMode); } - void CLine::ApplyStyle(IRenderer *pRenderer, const TSvgStyles *pStyles, const CSvgFile *pFile, int &nTypePath) const + void CLine::ApplyStyle(IRenderer *pRenderer, const TSvgStyles *pStyles, const CSvgFile *pFile, int &nTypePath, const CRenderedObject* pContexObject) const { - if (ApplyStroke(pRenderer, &pStyles->m_oStroke, true)) + if (ApplyStroke(pRenderer, &pStyles->m_oStroke, true, pContexObject)) nTypePath += c_nStroke; } } diff --git a/DesktopEditor/raster/Metafile/svg/SvgObjects/CLine.h b/DesktopEditor/raster/Metafile/svg/SvgObjects/CLine.h index eb511e771ef..a7b6678cd7f 100644 --- a/DesktopEditor/raster/Metafile/svg/SvgObjects/CLine.h +++ b/DesktopEditor/raster/Metafile/svg/SvgObjects/CLine.h @@ -12,7 +12,7 @@ namespace SVG void SetData(const std::map& mAttributes, unsigned short ushLevel, bool bHardMode = false) override; private: - void ApplyStyle(IRenderer* pRenderer, const TSvgStyles* pStyles, const CSvgFile *pFile, int& nTypePath) const override; + void ApplyStyle(IRenderer* pRenderer, const TSvgStyles* pStyles, const CSvgFile *pFile, int& nTypePath, const CRenderedObject* pContexObject = NULL) const override; }; } diff --git a/DesktopEditor/raster/Metafile/svg/SvgObjects/CMarker.cpp b/DesktopEditor/raster/Metafile/svg/SvgObjects/CMarker.cpp index 97433acbde6..f48a55f9e68 100644 --- a/DesktopEditor/raster/Metafile/svg/SvgObjects/CMarker.cpp +++ b/DesktopEditor/raster/Metafile/svg/SvgObjects/CMarker.cpp @@ -6,7 +6,7 @@ namespace SVG { CMarker::CMarker(XmlUtils::CXmlNode &oNode) - : CObject(oNode), m_pImage(NULL) + : CObject(oNode), m_dAngle(0.), m_oBounds{0., 0., 0., 0.} { m_oWindow.m_oX .SetValue(oNode.GetAttribute(L"refX")); m_oWindow.m_oY .SetValue(oNode.GetAttribute(L"refY")); @@ -14,6 +14,8 @@ namespace SVG m_oWindow.m_oWidth .SetValue(oNode.GetAttribute(L"markerWidth", L"3")); m_oWindow.m_oHeight.SetValue(oNode.GetAttribute(L"markerHeight", L"3")); + m_oViewBox = m_oWindow; + const std::wstring wsViewBox = oNode.GetAttribute(L"viewBox"); if (!wsViewBox.empty()) @@ -28,28 +30,29 @@ namespace SVG } } -// if (m_oWindow.m_oWidth.Empty() && !m_oViewBox.m_oWidth.Empty()) -// m_oWindow.m_oWidth = m_oViewBox.m_oWidth; -// else if (!m_oWindow.m_oWidth.Empty() && m_oViewBox.m_oWidth.Empty()) -// m_oViewBox.m_oWidth = m_oWindow.m_oWidth; - -// if (m_oWindow.m_oHeight.Empty() && !m_oViewBox.m_oHeight.Empty()) -// m_oWindow.m_oHeight = m_oViewBox.m_oHeight; -// else if (!m_oWindow.m_oHeight.Empty() && m_oViewBox.m_oHeight.Empty()) -// m_oViewBox.m_oHeight = m_oWindow.m_oHeight; - const std::wstring& wsUnits = oNode.GetAttribute(L"markerUnits"); if (L"userSpaceOnUse" == wsUnits) - m_enUnits = Marker_UserSpaceOnUse; + m_enUnits = EMarkerUnits::UserSpaceOnUse; + else + m_enUnits = EMarkerUnits::StrokeWidth; + + const std::wstring& wsOrient = oNode.GetAttribute(L"orient"); + + if (L"auto" == wsOrient) + m_enOrient = EMarkerOrient::Auto; + else if (L"auto-start-reverse" == wsOrient) + m_enOrient = EMarkerOrient::Auto_start_reverse; else - m_enUnits = Marker_StrokeWidth; + { + m_enOrient = EMarkerOrient::Angle; + if (!StrUtils::ReadAngle(wsOrient, m_dAngle)) + StrUtils::ReadDoubleValue(wsOrient, m_dAngle); + } } CMarker::~CMarker() { - if (NULL != m_pImage) - delete m_pImage; } ObjectType CMarker::GetType() const @@ -60,91 +63,48 @@ namespace SVG void CMarker::SetData(const std::map &mAttributes, unsigned short ushLevel, bool bHardMode) {} - void CMarker::Update(const CSvgFile *pFile) + void CMarker::Draw(IRenderer *pRenderer, const CSvgFile* pFile, const TMarkerExternData& oExternalData, CommandeMode oMode, const TSvgStyles* pOtherStyles, const CRenderedObject* pContexObject) const { - if (NULL != m_pImage || (!m_oWindow.m_oWidth.Empty() && m_oWindow.m_oWidth.Zero()) || (!m_oWindow.m_oHeight.Empty() && m_oWindow.m_oHeight.Zero()) || - (!m_oViewBox.m_oWidth.Empty() && m_oViewBox.m_oWidth.Zero()) || (!m_oViewBox.m_oHeight.Empty() && m_oViewBox.m_oHeight.Zero())) + if (NULL == oExternalData.m_pPoints || oExternalData.m_pPoints->empty() || m_arObjects.empty() || (EMarkerUnits::StrokeWidth == m_enUnits && Equals(0., oExternalData.m_dStroke))) return; - double dVBWidth = m_oViewBox.m_oWidth .ToDouble(NSCSS::Pixel); - double dVBHeight = m_oViewBox.m_oHeight.ToDouble(NSCSS::Pixel); + const double dMaxScale = ((EMarkerUnits::StrokeWidth == m_enUnits) ? oExternalData.m_dStroke : 1.) * std::max((m_oWindow.m_oWidth.ToDouble(NSCSS::Pixel) / m_oViewBox.m_oWidth.ToDouble(NSCSS::Pixel)), (m_oWindow.m_oHeight.ToDouble(NSCSS::Pixel) / m_oViewBox.m_oHeight.ToDouble(NSCSS::Pixel))); - double dMaxValue = std::max(dVBWidth, dVBHeight); - - NSGraphics::IGraphicsRenderer* pGrRenderer = NSGraphics::Create(); - - double dMMtoPx = 96. / 25.4; - - int nWidth = dMaxValue * dMMtoPx + 1; - int nHeight = dMaxValue * dMMtoPx + 1; - - if (0 == nWidth || 0 == nHeight) - return; - - BYTE* pBgraData = new BYTE[nWidth * nHeight * 4]; - - if (!pBgraData) - return; + double dM11, dM12, dM21, dM22, dDx, dDy; + pRenderer->GetTransform(&dM11, &dM12, &dM21, &dM22, &dDx, &dDy); - unsigned int alfa = 0xffffff; - //дефолтный тон должен быть прозрачным, а не белым - //memset(pBgraData, 0xff, nWidth * nHeight * 4); - for (int i = 0; i < nWidth * nHeight; i++) - ((unsigned int*)pBgraData)[i] = alfa; + const double dSkipX = m_oWindow.m_oX.ToDouble(NSCSS::Pixel) * dMaxScale; + const double dSkipY = m_oWindow.m_oY.ToDouble(NSCSS::Pixel) * dMaxScale; - CBgraFrame oFrame; - oFrame.put_Data(pBgraData); - oFrame.put_Width(nWidth); - oFrame.put_Height(nHeight); - oFrame.put_Stride(-4 * nWidth); - - pGrRenderer->CreateFromBgraFrame(&oFrame); - pGrRenderer->put_Width (dMaxValue); - pGrRenderer->put_Height(dMaxValue); - - pGrRenderer->SetCoordTransformOffset(((dMaxValue - dVBWidth) / 2. - m_oViewBox.m_oX.ToDouble(NSCSS::Pixel)) * dMMtoPx, - ((dMaxValue - dVBHeight) / 2. - m_oViewBox.m_oY.ToDouble(NSCSS::Pixel)) * dMMtoPx); + for (const TPointData& oPoint : *oExternalData.m_pPoints) + { + Aggplus::CMatrix oTransform(dM11, dM12, dM21, dM22, dDx, dDy); + oTransform.Translate(oPoint.m_oPoint.dX - dSkipX, oPoint.m_oPoint.dY - dSkipY); - pGrRenderer->SetSwapRGB(false); - pGrRenderer->BeginCommand(c_nImageType); + if (EMarkerOrient::Angle == m_enOrient) + oTransform.RotateAt(m_dAngle, -dSkipX, -dSkipY); + else if (!Equals(0., oPoint.m_dAngle)) + oTransform.RotateAt(oPoint.m_dAngle, -dSkipX, -dSkipY); - for (const CRenderedObject* pObject : m_arObjects) - pObject->Draw(pGrRenderer, pFile); + Aggplus::CMatrix oTransform2(oTransform); + oTransform2.Scale(dMaxScale, dMaxScale); - pGrRenderer->EndCommand(c_nImageType); - RELEASEINTERFACE(pGrRenderer); + pRenderer->SetTransform(oTransform2.sx(), oTransform2.shy(), oTransform2.shx(), oTransform2.sy(), oTransform.tx(), oTransform.ty()); - oFrame.put_Data(NULL); + for (const CRenderedObject* pObject : m_arObjects) + pObject->Draw(pRenderer, pFile, oMode, pOtherStyles, pContexObject); + } - m_pImage = new Aggplus::CImage; - m_pImage->Create(pBgraData, oFrame.get_Width(), oFrame.get_Height(), oFrame.get_Stride()); + pRenderer->SetTransform(dM11, dM12, dM21, dM22, dDx, dDy); } - void CMarker::Draw(IRenderer *pRenderer, const std::vector &arPoints, double dStrokeWidth) const + bool CMarker::NeedExternalAngle() const { - if (NULL == m_pImage || arPoints.empty() || Equals(0., dStrokeWidth)) - return; - - double dWidth = m_oWindow.m_oWidth.ToDouble(NSCSS::Pixel) * ((Marker_StrokeWidth == m_enUnits) ? dStrokeWidth : 1.); - double dHeight = m_oWindow.m_oHeight.ToDouble(NSCSS::Pixel) * ((Marker_StrokeWidth == m_enUnits) ? dStrokeWidth : 1.); - - double dVBWidth = m_oViewBox.m_oWidth.ToDouble(NSCSS::Pixel); - double dVBHeight = m_oViewBox.m_oHeight.ToDouble(NSCSS::Pixel); - - double dMaxValue = std::max(dVBWidth, dVBHeight); - double dMaxScale = std::max(dMaxValue / dVBWidth, dMaxValue / dVBHeight); - - double dSkipX = (m_oWindow.m_oX.ToDouble(NSCSS::Pixel) - m_oViewBox.m_oX.ToDouble(NSCSS::Pixel)) / dMaxScale + (dMaxValue - dVBWidth) * (dWidth / (2 * dMaxValue)); - double dSkipY = (m_oWindow.m_oY.ToDouble(NSCSS::Pixel) - m_oViewBox.m_oY.ToDouble(NSCSS::Pixel)) / dMaxScale + (dMaxValue - dVBHeight) * (dHeight / (2 * dMaxValue)); - - for (const Point& oPoint : arPoints) - { - Point oNewPoint(oPoint); - - oNewPoint.dX -= dSkipX; - oNewPoint.dY -= dSkipY; + return m_enOrient != EMarkerOrient::Angle; + } - pRenderer->DrawImage((IGrObject*)m_pImage, oNewPoint.dX, oNewPoint.dY, dWidth, dHeight); - } + EMarkerOrient CMarker::GetOrientType() const + { + return m_enOrient; } } diff --git a/DesktopEditor/raster/Metafile/svg/SvgObjects/CMarker.h b/DesktopEditor/raster/Metafile/svg/SvgObjects/CMarker.h index ef301c69f31..8bb7b979244 100644 --- a/DesktopEditor/raster/Metafile/svg/SvgObjects/CMarker.h +++ b/DesktopEditor/raster/Metafile/svg/SvgObjects/CMarker.h @@ -5,11 +5,43 @@ namespace SVG { - typedef enum + enum class EMarkerUnits { - Marker_StrokeWidth, - Marker_UserSpaceOnUse - } MarkerUnits; + StrokeWidth, + UserSpaceOnUse + }; + + enum class EMarkerOrient + { + Auto, + Auto_start_reverse, + Angle + }; + + struct TPointData + { + Point m_oPoint; + double m_dAngle; + + TPointData() + : m_dAngle(0.) + {} + }; + + struct TMarkerExternData + { + std::vector* m_pPoints; + double m_dStroke; + + TMarkerExternData() + : m_pPoints(NULL), m_dStroke(0.) + {} + + ~TMarkerExternData() + { + RELEASEOBJECT(m_pPoints); + } + }; class CMarker : public CObject, public CContainer { @@ -21,16 +53,21 @@ namespace SVG void SetData(const std::map &mAttributes, unsigned short ushLevel, bool bHardMode) override; - void Update(const CSvgFile *pFile); + void Draw(IRenderer* pRenderer, const CSvgFile *pFile, const TMarkerExternData& oExternalData, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pOtherStyles = NULL, const CRenderedObject* pContexObject = NULL) const; - void Draw(IRenderer* pRenderer, const std::vector& arPoints, double dStrokeWidth) const; + bool NeedExternalAngle() const; + EMarkerOrient GetOrientType() const; private: - MarkerUnits m_enUnits; + EMarkerUnits m_enUnits; + EMarkerOrient m_enOrient; + + double m_dAngle; + + TRect m_oWindow; + TRect m_oViewBox; - TRect m_oWindow; - TRect m_oViewBox; + TBounds m_oBounds; - Aggplus::CImage *m_pImage; }; } diff --git a/DesktopEditor/raster/Metafile/svg/SvgObjects/CObjectBase.cpp b/DesktopEditor/raster/Metafile/svg/SvgObjects/CObjectBase.cpp index 50f33ab399b..651b3f9e67a 100644 --- a/DesktopEditor/raster/Metafile/svg/SvgObjects/CObjectBase.cpp +++ b/DesktopEditor/raster/Metafile/svg/SvgObjects/CObjectBase.cpp @@ -33,29 +33,7 @@ namespace SVG CObject::CObject(XmlUtils::CXmlNode &oNode) { - if (!oNode.IsValid()) - return; - - std::vector arProperties, arValues; - - oNode.GetAllAttributes(arProperties, arValues); - - m_oXmlNode.m_wsName = oNode.GetName(); - - for (unsigned int unIndex = 0; unIndex < arProperties.size(); ++unIndex) - { - if (L"class" == arProperties[unIndex]) - { - m_oXmlNode.m_wsClass = arValues[unIndex]; - std::transform(m_oXmlNode.m_wsClass.begin(), m_oXmlNode.m_wsClass.end(), m_oXmlNode.m_wsClass.begin(), std::towlower); - } - else if (L"id" == arProperties[unIndex]) - m_oXmlNode.m_wsId = arValues[unIndex]; - else if (L"style" == arProperties[unIndex]) - m_oXmlNode.m_wsStyle = arValues[unIndex]; - else - m_oXmlNode.m_mAttributes.insert({arProperties[unIndex], arValues[unIndex]}); - } + SetNodeData(oNode); } CObject::~CObject() @@ -68,32 +46,32 @@ namespace SVG SetData(NSCSS::NS_STATIC_FUNCTIONS::GetRules(wsStyles), ushLevel, bHardMode); } - + void CObject::SetTransform(const std::map &mAttributes, unsigned short ushLevel, bool bHardMode) { if (mAttributes.end() != mAttributes.find(L"transform")) - m_oTransformtaion.m_oTransform.SetMatrix(mAttributes.at(L"transform"), ushLevel, bHardMode); + m_oTransformation.m_oTransform.SetMatrix(mAttributes.at(L"transform"), ushLevel, bHardMode); else - m_oTransformtaion.m_oTransform.SetMatrix(L"", ushLevel, false); + m_oTransformation.m_oTransform.SetMatrix(L"", ushLevel, false); } void CObject::SetClip(const std::map &mAttributes, unsigned short ushLevel, bool bHardMode) { if (mAttributes.end() != mAttributes.find(L"clip-path")) - m_oTransformtaion.m_oClip.m_oHref.SetValue(mAttributes.at(L"clip-path"), ushLevel, bHardMode); + m_oTransformation.m_oClip.m_oHref.SetValue(mAttributes.at(L"clip-path"), ushLevel, bHardMode); else - m_oTransformtaion.m_oClip.m_oHref.SetValue(L"", ushLevel, false); + m_oTransformation.m_oClip.m_oHref.SetValue(L"", ushLevel, false); if (mAttributes.end() != mAttributes.find(L"clip-rule")) - m_oTransformtaion.m_oClip.m_oRule.SetValue(mAttributes.at(L"clip-rule"), std::vector{L"nonzero", L"evenodd"}, ushLevel, bHardMode); + m_oTransformation.m_oClip.m_oRule.SetValue(mAttributes.at(L"clip-rule"), std::vector{L"nonzero", L"evenodd"}, ushLevel, bHardMode); } void CObject::SetMask(const std::map &mAttributes, unsigned short ushLevel, bool bHardMode) { if (mAttributes.end() != mAttributes.find(L"mask")) - m_oTransformtaion.m_oMask.SetValue(mAttributes.at(L"mask"), ushLevel, bHardMode); + m_oTransformation.m_oMask.SetValue(mAttributes.at(L"mask"), ushLevel, bHardMode); else - m_oTransformtaion.m_oMask.SetValue(L"", ushLevel, false); + m_oTransformation.m_oMask.SetValue(L"", ushLevel, false); } void CObject::SetDisplay(const std::map &mAttributes, unsigned short ushLevel, bool bHardMode) @@ -107,9 +85,15 @@ namespace SVG wsVisibility = mAttributes.at(L"visibility"); if (L"none" == wsDisplay || L"hidden" == wsVisibility || L"collapse" == wsVisibility) - m_oTransformtaion.m_bDraw = false; + m_oTransformation.m_bDraw = false; else - m_oTransformtaion.m_bDraw = true; + m_oTransformation.m_bDraw = true; + } + + void CObject::SetOpacity(const std::map &mAttributes, unsigned short ushLevel, bool bHardMode) + { + if (mAttributes.end() != mAttributes.find(L"opacity")) + m_oTransformation.m_oOpacity.SetValue(mAttributes.at(L"opacity"), ushLevel, bHardMode); } bool CObject::ApplyTransform(IRenderer *pRenderer, const NSCSS::NSProperties::CTransform *pTransform, Aggplus::CMatrix& oOldMatrix) const @@ -134,12 +118,9 @@ namespace SVG bool CObject::ApplyClip(IRenderer *pRenderer, const TClip *pClip, const CSvgFile *pFile, const TBounds &oBounds) const { - if (NULL == pRenderer || NULL == pClip || NULL == pFile) + if (NULL == pRenderer || NULL == pClip || NULL == pFile || pClip->m_oHref.Empty() || NSCSS::NSProperties::ColorType::ColorUrl != pClip->m_oHref.GetType()) return false; - if (pClip->m_oHref.Empty() || NSCSS::NSProperties::ColorType::ColorUrl != pClip->m_oHref.GetType()) - return true; - if (pClip->m_oRule == L"evenodd") pRenderer->put_ClipMode(c_nClipRegionTypeEvenOdd); else @@ -147,7 +128,7 @@ namespace SVG pRenderer->BeginCommand(c_nResetClipType); pRenderer->EndCommand(c_nResetClipType); - + return ApplyDef(pRenderer, pFile, pClip->m_oHref.ToWString(), oBounds); } @@ -158,7 +139,7 @@ namespace SVG return ApplyDef(pRenderer, pFile, pMask->ToWString(), oBounds); } - + bool CObject::ApplyDef(IRenderer *pRenderer, const CSvgFile *pFile, const std::wstring &wsUrl, const TBounds &oBounds) const { if (NULL == pRenderer || NULL == pFile || wsUrl.empty()) @@ -171,7 +152,34 @@ namespace SVG return pDefObject->Apply(pRenderer, pFile, oBounds); } - + + void CObject::SetNodeData(XmlUtils::CXmlNode &oNode) + { + if (!oNode.IsValid()) + return; + + std::vector arProperties, arValues; + + oNode.GetAllAttributes(arProperties, arValues); + + m_oXmlNode.m_wsName = oNode.GetName(); + + for (unsigned int unIndex = 0; unIndex < arProperties.size(); ++unIndex) + { + if (L"class" == arProperties[unIndex]) + { + m_oXmlNode.m_wsClass = arValues[unIndex]; + std::transform(m_oXmlNode.m_wsClass.begin(), m_oXmlNode.m_wsClass.end(), m_oXmlNode.m_wsClass.begin(), std::towlower); + } + else if (L"id" == arProperties[unIndex]) + m_oXmlNode.m_wsId = arValues[unIndex]; + else if (L"style" == arProperties[unIndex]) + m_oXmlNode.m_wsStyle = arValues[unIndex]; + else + m_oXmlNode.m_mAttributes.insert({arProperties[unIndex], arValues[unIndex]}); + } + } + std::wstring CObject::GetId() const { return m_oXmlNode.m_wsId; @@ -205,9 +213,10 @@ namespace SVG void CRenderedObject::SetData(const std::map &mAttributes, unsigned short ushLevel, bool bHardMode) { SetTransform(mAttributes, ushLevel, bHardMode); - SetDisplay(mAttributes, ushLevel, bHardMode); - SetClip(mAttributes, ushLevel, bHardMode); - SetMask(mAttributes, ushLevel, bHardMode); + SetDisplay (mAttributes, ushLevel, bHardMode); + SetOpacity (mAttributes, ushLevel, bHardMode); + SetClip (mAttributes, ushLevel, bHardMode); + SetMask (mAttributes, ushLevel, bHardMode); } std::vector CRenderedObject::GetFullPath() const @@ -230,7 +239,8 @@ namespace SVG m_oStyles.m_oStroke.m_oMiterlimit = 4.; - m_oTransformtaion.m_bDraw = true; + m_oTransformation.m_oOpacity = 1.; + m_oTransformation.m_bDraw = true; } void CRenderedObject::SetStroke(const std::map &mAttributes, unsigned short ushLevel, bool bHardMode) @@ -267,22 +277,26 @@ namespace SVG if (mAttributes.end() != mAttributes.find(L"fill-opacity")) m_oStyles.m_oFill.SetOpacity(mAttributes.at(L"fill-opacity"), ushLevel, bHardMode); - - if (mAttributes.end() != mAttributes.find(L"opacity")) - m_oStyles.m_oFill.SetOpacity(mAttributes.at(L"opacity"), ushLevel, bHardMode); } - bool CRenderedObject::StartPath(IRenderer *pRenderer, const CSvgFile *pFile, Aggplus::CMatrix &oOldTransform, CommandeMode oMode) const + bool CRenderedObject::StartPath(IRenderer *pRenderer, const CSvgFile *pFile, Aggplus::CMatrix& oOldTransform, CommandeMode oMode) const { - if (NULL == pRenderer || !m_oTransformtaion.m_bDraw) + if (NULL == pRenderer || !m_oTransformation.m_bDraw || Equals(0., m_oTransformation.m_oOpacity.ToDouble())) return false; - ApplyTransform(pRenderer, &m_oTransformtaion.m_oTransform, oOldTransform); - ApplyClip(pRenderer, &m_oTransformtaion.m_oClip, pFile, GetBounds()); - ApplyMask(pRenderer, &m_oTransformtaion.m_oMask, pFile, GetBounds()); + const TBounds oBounds{GetBounds()}; + + ApplyTransform(pRenderer, &m_oTransformation.m_oTransform, oOldTransform); + ApplyClip(pRenderer, &m_oTransformation.m_oClip, pFile, oBounds); + ApplyMask(pRenderer, &m_oTransformation.m_oMask, pFile, oBounds); if (CommandeModeClip == oMode) pRenderer->BeginCommand(c_nClipType); + else if (1. != m_oTransformation.m_oOpacity.ToDouble()) + { + pRenderer->BeginCommand(c_nLayerType); + pRenderer->put_LayerOpacity(m_oTransformation.m_oOpacity.ToDouble()); + } pRenderer->BeginCommand(c_nPathType); pRenderer->PathCommandStart(); @@ -290,51 +304,58 @@ namespace SVG return true; } - void CRenderedObject::EndPath(IRenderer *pRenderer, const CSvgFile *pFile, const Aggplus::CMatrix &oOldTransform, CommandeMode oMode, const TSvgStyles* pOtherStyles) const + void CRenderedObject::EndPath(IRenderer *pRenderer, const CSvgFile *pFile, const Aggplus::CMatrix& oOldTransform, CommandeMode oMode, const TSvgStyles* pOtherStyles, const CRenderedObject* pContextObject) const { if (CommandeModeClip == oMode) { pRenderer->EndCommand(c_nClipType); pRenderer->EndCommand(c_nPathType); pRenderer->PathCommandEnd(); - pRenderer->SetTransform(oOldTransform.sx(), oOldTransform.shy(), oOldTransform.shx(), oOldTransform.sy(), oOldTransform.tx(), oOldTransform.ty()); + pRenderer->SetTransform(oOldTransform.sx(), oOldTransform.shy(), + oOldTransform.shx(), oOldTransform.sy(), + oOldTransform.tx(), oOldTransform.ty()); return; } int nPathType = 0; if (NULL == pOtherStyles) - ApplyStyle(pRenderer, &m_oStyles, pFile, nPathType); + ApplyStyle(pRenderer, &m_oStyles, pFile, nPathType, pContextObject); else { TSvgStyles oNewStyles(m_oStyles); oNewStyles += *pOtherStyles; - ApplyStyle(pRenderer, &oNewStyles, pFile, nPathType); + ApplyStyle(pRenderer, &oNewStyles, pFile, nPathType, pContextObject); } pRenderer->DrawPath(nPathType); pRenderer->EndCommand(c_nPathType); pRenderer->PathCommandEnd(); - if (!m_oTransformtaion.m_oClip.m_oHref.Empty()) + if (!m_oTransformation.m_oClip.m_oHref.Empty()) { pRenderer->BeginCommand(c_nResetClipType); pRenderer->EndCommand(c_nResetClipType); } - if (!m_oTransformtaion.m_oMask.Empty()) + if (!m_oTransformation.m_oMask.Empty()) { pRenderer->BeginCommand(c_nResetMaskType); pRenderer->EndCommand(c_nResetMaskType); } - pRenderer->SetTransform(oOldTransform.sx(), oOldTransform.shy(), oOldTransform.shx(), oOldTransform.sy(), oOldTransform.tx(), oOldTransform.ty()); + if (1. != m_oTransformation.m_oOpacity.ToDouble()) + pRenderer->EndCommand(c_nLayerType); + + pRenderer->SetTransform(oOldTransform.sx(), oOldTransform.shy(), + oOldTransform.shx(), oOldTransform.sy(), + oOldTransform.tx(), oOldTransform.ty()); } - void CRenderedObject::ApplyStyle(IRenderer *pRenderer, const TSvgStyles *pStyles, const CSvgFile *pFile, int &nTypePath) const + void CRenderedObject::ApplyStyle(IRenderer *pRenderer, const TSvgStyles *pStyles, const CSvgFile *pFile, int &nTypePath, const CRenderedObject* pContextObject) const {} - bool CRenderedObject::ApplyStroke(IRenderer *pRenderer, const TStroke *pStroke, bool bUseDefault) const + bool CRenderedObject::ApplyStroke(IRenderer *pRenderer, const TStroke *pStroke, bool bUseDefault, const CRenderedObject* pContextObject) const { if (NULL == pRenderer || NULL == pStroke || NSCSS::NSProperties::ColorType::ColorNone == pStroke->m_oColor.GetType() || (!bUseDefault && ((pStroke->m_oWidth.Empty() || pStroke->m_oWidth.Zero()) && pStroke->m_oColor.Empty()))) { @@ -347,10 +368,14 @@ namespace SVG if (Equals(0., dStrokeWidth)) dStrokeWidth = 1.; - int nColor = (pStroke->m_oColor.Empty() || NSCSS::NSProperties::ColorType::ColorNone == pStroke->m_oColor.GetType()) ? 0 : pStroke->m_oColor.ToInt(); + if (NSCSS::NSProperties::ColorType::ColorContextFill == pStroke->m_oColor.GetType() && NULL != pContextObject) + pRenderer->put_PenColor(pContextObject->m_oStyles.m_oFill.ToInt()); + else if (NSCSS::NSProperties::ColorType::ColorContextStroke == pStroke->m_oColor.GetType() && NULL != pContextObject) + pRenderer->put_PenColor(pContextObject->m_oStyles.m_oStroke.m_oColor.ToInt()); + else + pRenderer->put_PenColor((pStroke->m_oColor.Empty() || NSCSS::NSProperties::ColorType::ColorNone == pStroke->m_oColor.GetType()) ? 0 : pStroke->m_oColor.ToInt()); pRenderer->put_PenSize(dStrokeWidth); - pRenderer->put_PenColor(nColor); pRenderer->put_PenAlpha(255. * pStroke->m_oColor.GetOpacity()); if (!pStroke->m_arDash.empty()) @@ -373,7 +398,7 @@ namespace SVG return true; } - bool CRenderedObject::ApplyFill(IRenderer *pRenderer, const NSCSS::NSProperties::CColor *pFill, const CSvgFile *pFile, bool bUseDefault) const + bool CRenderedObject::ApplyFill(IRenderer *pRenderer, const NSCSS::NSProperties::CColor *pFill, const CSvgFile *pFile, bool bUseDefault, const CRenderedObject* pContextObject) const { if (NULL == pRenderer || NULL == pFill || NSCSS::NSProperties::ColorType::ColorNone == pFill->GetType() || (!bUseDefault && pFill->Empty())) { @@ -399,6 +424,10 @@ namespace SVG return false; } } + else if (NSCSS::NSProperties::ColorType::ColorContextFill == pFill->GetType() && NULL != pContextObject) + pRenderer->put_BrushColor1(pContextObject->m_oStyles.m_oFill.ToInt()); + else if (NSCSS::NSProperties::ColorType::ColorContextStroke == pFill->GetType() && NULL != pContextObject) + pRenderer->put_BrushColor1(pContextObject->m_oStyles.m_oStroke.m_oColor.ToInt()); else if (bUseDefault) { pRenderer->put_BrushColor1(0); @@ -410,6 +439,14 @@ namespace SVG return true; } + bool CRenderedObject::ApplyOpacity(IRenderer *pRenderer, const NSCSS::NSProperties::CDigit *pOpacity) const + { + if (NULL == pRenderer || NULL == pOpacity) + return false; + + return false; + } + CAppliedObject::CAppliedObject(XmlUtils::CXmlNode &oNode) : CObject(oNode) {} diff --git a/DesktopEditor/raster/Metafile/svg/SvgObjects/CObjectBase.h b/DesktopEditor/raster/Metafile/svg/SvgObjects/CObjectBase.h index 41a4ceca0e5..a31aafbaf4b 100644 --- a/DesktopEditor/raster/Metafile/svg/SvgObjects/CObjectBase.h +++ b/DesktopEditor/raster/Metafile/svg/SvgObjects/CObjectBase.h @@ -5,6 +5,7 @@ #include "../../../../../Common/3dParty/html/css/src/StaticFunctions.h" #include "../../../../xml/include/xmlutils.h" #include "../../../../graphics/IRenderer.h" +#include "../../../../common/IGrObject.h" #include "../SvgTypes.h" class CSvgFile; @@ -15,6 +16,7 @@ namespace SVG { SvgColor m_oFill; TStroke m_oStroke; + SvgDigit m_oOpacity; TSvgStyles& operator+=(const TSvgStyles& oSvgStyles); }; @@ -24,6 +26,7 @@ namespace SVG SvgTransform m_oTransform; TClip m_oClip; SvgColor m_oMask; + SvgDigit m_oOpacity; bool m_bDraw; }; @@ -33,7 +36,7 @@ namespace SVG AppliedObject }; - class CObject + class CObject : public IGrObject { public: CObject(const NSCSS::CNode& oData); @@ -49,18 +52,20 @@ namespace SVG void SetTransform(const std::map& mAttributes, unsigned short ushLevel, bool bHardMode = false); void SetClip(const std::map& mAttributes, unsigned short ushLevel, bool bHardMode = false); void SetMask(const std::map& mAttributes, unsigned short ushLevel, bool bHardMode = false); - void SetDisplay(const std::map& mAttributes, unsigned short ushLevel, bool bHardMode = false); - + void SetDisplay(const std::map& mAttributes, unsigned short ushLevel, bool bHardMode = false); + void SetOpacity(const std::map& mAttributes, unsigned short ushLevel, bool bHardMode = false); + std::wstring GetId() const; virtual std::vector GetFullPath() const; - private: bool ApplyTransform(IRenderer* pRenderer, const SvgTransform* pTransform, Aggplus::CMatrix& oOldMatrix) const; bool ApplyClip(IRenderer* pRenderer, const TClip* pClip, const CSvgFile *pFile, const TBounds& oBounds) const; bool ApplyMask(IRenderer* pRenderer, const SvgColor* pMask, const CSvgFile *pFile, const TBounds& oBounds) const; - + bool ApplyDef(IRenderer* pRenderer, const CSvgFile *pFile, const std::wstring& wsUrl, const TBounds& oBounds) const; - + + void SetNodeData(XmlUtils::CXmlNode& oNode); + friend class CRenderedObject; friend class CAppliedObject; @@ -75,11 +80,12 @@ namespace SVG friend class CPolygon; friend class CEllipse; friend class CPolyline; + friend class CGraphicsContainer; friend class CClipPath; NSCSS::CNode m_oXmlNode; - TSvgTransformation m_oTransformtaion; + TSvgTransformation m_oTransformation; }; enum CommandeMode @@ -100,7 +106,7 @@ namespace SVG virtual void SetData(const std::map& mAttributes, unsigned short ushLevel, bool bHardMode = false) override; - virtual bool Draw(IRenderer* pRenderer, const CSvgFile *pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pStyles = NULL) const = 0; + virtual bool Draw(IRenderer* pRenderer, const CSvgFile *pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pStyles = NULL, const CRenderedObject* pContextObject = NULL) const = 0; virtual TBounds GetBounds() const = 0; @@ -112,12 +118,13 @@ namespace SVG void SetFill(const std::map& mAttributes, unsigned short ushLevel, bool bHardMode = false); bool StartPath(IRenderer* pRenderer, const CSvgFile *pFile, Aggplus::CMatrix& oOldTransform, CommandeMode oMode = CommandeModeDraw) const; - void EndPath(IRenderer* pRenderer, const CSvgFile *pFile, const Aggplus::CMatrix& oOldTransform, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pOtherStyles = NULL) const; + void EndPath(IRenderer* pRenderer, const CSvgFile *pFile, const Aggplus::CMatrix& oOldTransform, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pOtherStyles = NULL, const CRenderedObject* pContextObject = NULL) const; - virtual void ApplyStyle(IRenderer* pRenderer, const TSvgStyles* pStyles, const CSvgFile *pFile, int& nTypePath) const; + virtual void ApplyStyle(IRenderer* pRenderer, const TSvgStyles* pStyles, const CSvgFile *pFile, int& nTypePath, const CRenderedObject* pContextObject = NULL) const; - bool ApplyStroke(IRenderer* pRenderer, const TStroke* pStroke, bool bUseDefault = false) const; - bool ApplyFill(IRenderer* pRenderer, const SvgColor* pFill, const CSvgFile *pFile, bool bUseDefault = false) const; + bool ApplyStroke(IRenderer* pRenderer, const TStroke* pStroke, bool bUseDefault = false, const CRenderedObject* pContextObject = NULL) const; + bool ApplyFill(IRenderer* pRenderer, const SvgColor* pFill, const CSvgFile *pFile, bool bUseDefault = false, const CRenderedObject* pContextObject = NULL) const; + bool ApplyOpacity(IRenderer* pRenderer, const SvgDigit* pOpacity) const; friend class CUse; friend class CLine; @@ -127,6 +134,7 @@ namespace SVG friend class CTSpan; friend class CImage; friend class CCircle; + friend class CSwitch; friend class CPolygon; friend class CEllipse; friend class CPolyline; diff --git a/DesktopEditor/raster/Metafile/svg/SvgObjects/CPath.cpp b/DesktopEditor/raster/Metafile/svg/SvgObjects/CPath.cpp index 87ed1fbc304..c43cac0b759 100644 --- a/DesktopEditor/raster/Metafile/svg/SvgObjects/CPath.cpp +++ b/DesktopEditor/raster/Metafile/svg/SvgObjects/CPath.cpp @@ -29,6 +29,11 @@ namespace SVG return oBounds; } + UINT IPathElement::GetPointCount() const + { + return m_arPoints.size(); + } + Point IPathElement::operator[](int nIndex) const { if (m_arPoints.empty() || (nIndex > 0 && nIndex >= m_arPoints.size()) || (nIndex < 0 && -nIndex > m_arPoints.size())) @@ -304,8 +309,12 @@ namespace SVG if ((int)(dStartAngle / 90.) == dStartAngle / 90.) dEndAngle = dStartAngle + ((dSweep > 0.) ? 90. : -90.); else + { dEndAngle = copysign(ceil(std::abs(dStartAngle) / 90.), dStartAngle) * ((dSweep > 0. || dStartAngle < 0.) ? 90. : -90.); + if (dStartAngle < 0. && dSweep > 0.) + dEndAngle += 90.; + } if (std::abs(dAngle - dEndAngle) > std::abs(dSweep)) dEndAngle = dAngle + dSweep; @@ -354,8 +363,8 @@ namespace SVG return; pRenderer->PathCommandCurveTo(m_arPoints[0].dX, m_arPoints[0].dY, - m_arPoints[1].dX, m_arPoints[1].dY, - m_arPoints[2].dX, m_arPoints[2].dY); + m_arPoints[1].dX, m_arPoints[1].dY, + m_arPoints[2].dX, m_arPoints[2].dY); } inline double ClampSinCos(const double& d) @@ -453,6 +462,7 @@ namespace SVG SetStroke(mAttributes, ushLevel, bHardMode); SetFill(mAttributes, ushLevel, bHardMode); + SetOpacity(mAttributes, ushLevel, bHardMode); SetMarker(mAttributes, ushLevel, bHardMode); std::map::const_iterator oIter = mAttributes.find(L"fill-rule"); @@ -464,7 +474,7 @@ namespace SVG } } - bool CPath::Draw(IRenderer *pRenderer, const CSvgFile *pFile, CommandeMode oMode, const TSvgStyles *pOtherStyles) const + bool CPath::Draw(IRenderer *pRenderer, const CSvgFile *pFile, CommandeMode oMode, const TSvgStyles *pOtherStyles, const CRenderedObject* pContexObject) const { Aggplus::CMatrix oOldTransform; @@ -474,7 +484,7 @@ namespace SVG for (const IPathElement* oElement : m_arElements) oElement->Draw(pRenderer); - EndPath(pRenderer, pFile, oOldTransform, oMode, pOtherStyles); + EndPath(pRenderer, pFile, oOldTransform, oMode, pOtherStyles, pContexObject); DrawMarkers(pRenderer, pFile, oMode); @@ -489,16 +499,16 @@ namespace SVG return m_arElements[(nIndex >= 0) ? nIndex : m_arElements.size() + nIndex]; } - void CPath::ApplyStyle(IRenderer *pRenderer, const TSvgStyles *pStyles, const CSvgFile *pFile, int &nTypePath) const - { - if (ApplyStroke(pRenderer, &pStyles->m_oStroke)) + void CPath::ApplyStyle(IRenderer *pRenderer, const TSvgStyles *pStyles, const CSvgFile *pFile, int &nTypePath, const CRenderedObject* pContexObject) const + { + if (ApplyStroke(pRenderer, &pStyles->m_oStroke, false, pContexObject)) nTypePath += c_nStroke; - if (ApplyFill(pRenderer, &pStyles->m_oFill, pFile, true)) + if (ApplyFill(pRenderer, &pStyles->m_oFill, pFile, true, pContexObject)) nTypePath += (m_bEvenOddRule) ? c_nEvenOddFillMode : c_nWindingFillMode; } - bool CPath::DrawMarkers(IRenderer *pRenderer, const CSvgFile *pFile, CommandeMode oMode) const + bool CPath::DrawMarkers(IRenderer *pRenderer, const CSvgFile *pFile, CommandeMode oMode, const TSvgStyles* pOtherStyles, const CRenderedObject* pContexObject) const { if (NULL == pRenderer || NULL == pFile || m_arElements.empty() || m_oStyles.m_oStroke.m_oWidth.Zero() || (m_oMarkers.m_oStart.Empty() && m_oMarkers.m_oMid.Empty() && m_oMarkers.m_oEnd.Empty())) @@ -509,7 +519,9 @@ namespace SVG if (!StartPath(pRenderer, pFile, oOldMatrix, oMode)) return false; - double dStrokeWidth = (m_oStyles.m_oStroke.m_oWidth.Empty()) ? 1. : m_oStyles.m_oStroke.m_oWidth.ToDouble(NSCSS::Pixel); + const double dStrokeWidth = (m_oStyles.m_oStroke.m_oWidth.Empty()) ? 1. : m_oStyles.m_oStroke.m_oWidth.ToDouble(NSCSS::Pixel); + + #define CALCULATE_ANGLE(firstPoint, secondPoint) std::atan2(secondPoint.dY - firstPoint.dY, secondPoint.dX - firstPoint.dX) * 180. / M_PI if (!m_oMarkers.m_oStart.Empty() && NSCSS::NSProperties::ColorType::ColorUrl == m_oMarkers.m_oStart.GetType()) { @@ -517,8 +529,36 @@ namespace SVG if (NULL != pStartMarker) { - pStartMarker->Update(pFile); - pStartMarker->Draw(pRenderer, {(*m_arElements.front())[0]}, dStrokeWidth); + TMarkerExternData oExternalData; + oExternalData.m_dStroke = dStrokeWidth; + oExternalData.m_pPoints = new std::vector(1); + + int unIndex = FindIndexFirstNotEmpty(); + + if (0 <= unIndex) + { + const IPathElement* pFirstElement{m_arElements[unIndex]}; + + (*oExternalData.m_pPoints)[0].m_oPoint = (*pFirstElement)[0]; + + if (pStartMarker->NeedExternalAngle()) + { + Point oCurent{(*pFirstElement)[0]}; + Point oNext; + + if (pFirstElement->GetPointCount() > 1) + oNext = (*pFirstElement)[1]; + else if (unIndex < m_arElements.size() - 1 && EPathElement::Close != m_arElements[unIndex + 1]->GetType() && EPathElement::Move != m_arElements[unIndex + 1]->GetType()) + oNext = (*m_arElements[unIndex + 1])[0]; + + (*oExternalData.m_pPoints)[0].m_dAngle = CALCULATE_ANGLE(oCurent, oNext); + + if (EMarkerOrient::Auto_start_reverse == pStartMarker->GetOrientType()) + (*oExternalData.m_pPoints)[0].m_dAngle += 180.; + } + + pStartMarker->Draw(pRenderer, pFile, oExternalData, oMode, pOtherStyles, this); + } } } @@ -526,15 +566,27 @@ namespace SVG { CMarker *pMidMarker = dynamic_cast(pFile->GetMarkedObject(m_oMarkers.m_oMid.ToWString())); - std::vector arPoints(m_arElements.size() - 2); - - for (unsigned int unIndex = 1; unIndex < m_arElements.size() - 1; ++unIndex) - arPoints[unIndex - 1] = (*m_arElements[unIndex])[-1]; - if (NULL != pMidMarker) { - pMidMarker->Update(pFile); - pMidMarker->Draw(pRenderer, arPoints, dStrokeWidth); + TMarkerExternData oExternalData; + oExternalData.m_dStroke = dStrokeWidth; + oExternalData.m_pPoints = new std::vector(m_arElements.size() - 2); + + for (unsigned int unIndex = 1; unIndex < m_arElements.size() - 1; ++unIndex) + { + if (EPathElement::Close != m_arElements[unIndex]->GetType()) + (*oExternalData.m_pPoints)[unIndex - 1].m_oPoint = (*m_arElements[unIndex])[-1]; + + if (pMidMarker->NeedExternalAngle()) + { + const Point oCurrent{(*m_arElements[unIndex])[0]}; + const Point oPrev{(*m_arElements[unIndex + 1])[-1]}; + + (*oExternalData.m_pPoints)[unIndex - 1].m_dAngle = CALCULATE_ANGLE(oCurrent, oPrev); + } + } + + pMidMarker->Draw(pRenderer, pFile, oExternalData, oMode, pOtherStyles, this); } } @@ -544,12 +596,37 @@ namespace SVG if (NULL != pEndMarker) { - pEndMarker->Update(pFile); - pEndMarker->Draw(pRenderer, {(*m_arElements.back())[-1]}, dStrokeWidth); + TMarkerExternData oExternalData; + oExternalData.m_dStroke = dStrokeWidth; + oExternalData.m_pPoints = new std::vector(1); + + int unIndex = FindIndexFirstNotEmpty(true); + + if (0 <= unIndex) + { + const IPathElement* pLastElement{m_arElements[unIndex]}; + + (*oExternalData.m_pPoints)[0].m_oPoint = (*pLastElement)[-1]; + + if (pEndMarker->NeedExternalAngle()) + { + Point oCurent{(*pLastElement)[-1]}; + Point oPrev; + + if (pLastElement->GetPointCount() > 1) + oPrev = (*pLastElement)[-2]; + else if (unIndex > 0 && EPathElement::Close != m_arElements[unIndex - 1]->GetType() && EPathElement::Move != m_arElements[unIndex - 1]->GetType()) + oPrev = (*m_arElements[unIndex - 1])[0]; + + (*oExternalData.m_pPoints)[0].m_dAngle = CALCULATE_ANGLE(oPrev, oCurent); + } + + pEndMarker->Draw(pRenderer, pFile, oExternalData, oMode, pOtherStyles, this); + } } } - EndPath(pRenderer, pFile, oOldMatrix, oMode); + EndPath(pRenderer, pFile, oOldMatrix, oMode, pOtherStyles, pContexObject); return true; } @@ -564,6 +641,13 @@ namespace SVG if (mAttributes.end() != mAttributes.find(L"marker-end")) m_oMarkers.m_oEnd.SetValue(mAttributes.at(L"marker-end"), ushLevel, bHardMode); + + if (mAttributes.end() != mAttributes.find(L"marker")) + { + m_oMarkers.m_oStart.SetValue(mAttributes.at(L"marker"), ushLevel, bHardMode); + m_oMarkers.m_oMid .SetValue(mAttributes.at(L"marker"), ushLevel, bHardMode); + m_oMarkers.m_oEnd .SetValue(mAttributes.at(L"marker"), ushLevel, bHardMode); + } } TBounds CPath::GetBounds() const @@ -583,6 +667,24 @@ namespace SVG return oBounds; } + const int CPath::FindIndexFirstNotEmpty(bool bReverseSearch) const + { + if (!bReverseSearch) + { + std::vector::const_iterator itFound = std::find_if(m_arElements.cbegin(), m_arElements.cend(), [](const IPathElement* pElement){ return EPathElement::Close != pElement->GetType(); }); + if (m_arElements.cend() != itFound) + return itFound - m_arElements.cbegin(); + } + else + { + std::vector::const_reverse_iterator itFound = std::find_if(m_arElements.crbegin(), m_arElements.crend(), [](const IPathElement* pElement){ return EPathElement::Close != pElement->GetType(); }); + if (m_arElements.crend() != itFound) + return itFound.base() - m_arElements.cbegin() - 1; + } + + return -1; + } + void CPath::ReadFromString(const std::wstring &wsValue) { CMoveElement *pMoveElement = NULL; @@ -603,7 +705,7 @@ namespace SVG } oSecondPos = std::find_if(oFirstPos + 1, wsValue.end(), [](wchar_t wChar){return ISPATHCOMMAND(wChar);}); - + std::vector arValues = StrUtils::ReadDoubleValues(oFirstPos, oSecondPos); switch(*oFirstPos) @@ -722,7 +824,7 @@ namespace SVG } CMovingPath::CMovingPath(const CPath *pPath) - : m_pPath(pPath), m_oPosition{DBL_MIN, DBL_MIN} + : m_pPath(pPath), m_oPosition{0., 0.} { ToStart(); } diff --git a/DesktopEditor/raster/Metafile/svg/SvgObjects/CPath.h b/DesktopEditor/raster/Metafile/svg/SvgObjects/CPath.h index 4e66f9425fc..61f66b9f747 100644 --- a/DesktopEditor/raster/Metafile/svg/SvgObjects/CPath.h +++ b/DesktopEditor/raster/Metafile/svg/SvgObjects/CPath.h @@ -35,6 +35,7 @@ namespace SVG virtual void Draw(IRenderer* pRenderer) const = 0; TBounds GetBounds() const; + UINT GetPointCount() const; virtual Point operator[](int nIndex) const; private: @@ -110,21 +111,24 @@ namespace SVG void SetData(const std::map& mAttributes, unsigned short ushLevel, bool bHardMode = false) override; - bool Draw(IRenderer* pRenderer, const CSvgFile *pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pOtherStyles = NULL) const override; + bool Draw(IRenderer* pRenderer, const CSvgFile *pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pOtherStyles = NULL, const CRenderedObject* pContexObject = NULL) const override; IPathElement* operator[](int nIndex) const; private: - void ApplyStyle(IRenderer* pRenderer, const TSvgStyles* pStyles, const CSvgFile *pFile, int& nTypePath) const override; - bool DrawMarkers(IRenderer* pRenderer, const CSvgFile *pFile, CommandeMode oMode = CommandeModeDraw) const; + void ApplyStyle(IRenderer* pRenderer, const TSvgStyles* pStyles, const CSvgFile *pFile, int& nTypePath, const CRenderedObject* pContexObject = NULL) const override; + bool DrawMarkers(IRenderer* pRenderer, const CSvgFile *pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pOtherStyles = NULL, const CRenderedObject* pContexObject = NULL) const; void SetMarker(const std::map &mAttributes, unsigned short ushLevel, bool bHardMode); TBounds GetBounds() const override; + const int FindIndexFirstNotEmpty(bool bReverseSearch = false) const; + void ReadFromString(const std::wstring& wsValue); bool AddElement(IPathElement* pElement); friend class CLine; + friend class CFont; friend class CPolygon; friend class CPolyline; diff --git a/DesktopEditor/raster/Metafile/svg/SvgObjects/CPattern.cpp b/DesktopEditor/raster/Metafile/svg/SvgObjects/CPattern.cpp index 67a1fe0c2d2..786cde3a5e2 100644 --- a/DesktopEditor/raster/Metafile/svg/SvgObjects/CPattern.cpp +++ b/DesktopEditor/raster/Metafile/svg/SvgObjects/CPattern.cpp @@ -53,7 +53,7 @@ namespace SVG if (0 == nWidth || 0 == nHeight) return; - BYTE* pBgraData = new BYTE[nWidth * nHeight * 4]; + BYTE* pBgraData = new(std::nothrow) BYTE[nWidth * nHeight * 4]; if (!pBgraData) return; diff --git a/DesktopEditor/raster/Metafile/svg/SvgObjects/CPattern.h b/DesktopEditor/raster/Metafile/svg/SvgObjects/CPattern.h index 28335687200..7ac81c88b86 100644 --- a/DesktopEditor/raster/Metafile/svg/SvgObjects/CPattern.h +++ b/DesktopEditor/raster/Metafile/svg/SvgObjects/CPattern.h @@ -2,6 +2,7 @@ #define CPATTERN_H #include "CContainer.h" +#include "../../../../graphics/pro/Fonts.h" namespace SVG { diff --git a/DesktopEditor/raster/Metafile/svg/SvgObjects/CRect.cpp b/DesktopEditor/raster/Metafile/svg/SvgObjects/CRect.cpp index 5ae96882d84..1c95355c23e 100644 --- a/DesktopEditor/raster/Metafile/svg/SvgObjects/CRect.cpp +++ b/DesktopEditor/raster/Metafile/svg/SvgObjects/CRect.cpp @@ -33,7 +33,7 @@ namespace SVG SetFill(mAttributes, ushLevel, bHardMode); } - bool CRect::Draw(IRenderer *pRenderer, const CSvgFile *pFile, CommandeMode oMode, const TSvgStyles *pOtherStyles) const + bool CRect::Draw(IRenderer *pRenderer, const CSvgFile *pFile, CommandeMode oMode, const TSvgStyles *pOtherStyles, const CRenderedObject* pContexObject) const { Aggplus::CMatrix oOldTransform; @@ -80,17 +80,17 @@ namespace SVG pRenderer->PathCommandClose(); } - EndPath(pRenderer, pFile, oOldTransform, oMode); + EndPath(pRenderer, pFile, oOldTransform, oMode, pOtherStyles, pContexObject); return true; } - void CRect::ApplyStyle(IRenderer *pRenderer, const TSvgStyles *pStyles, const CSvgFile *pFile, int &nTypePath) const + void CRect::ApplyStyle(IRenderer *pRenderer, const TSvgStyles *pStyles, const CSvgFile *pFile, int &nTypePath, const CRenderedObject* pContexObject) const { - if (ApplyStroke(pRenderer, &pStyles->m_oStroke)) + if (ApplyStroke(pRenderer, &pStyles->m_oStroke, false, pContexObject)) nTypePath += c_nStroke; - if (ApplyFill(pRenderer, &pStyles->m_oFill, pFile, true)) + if (ApplyFill(pRenderer, &pStyles->m_oFill, pFile, true, pContexObject)) nTypePath += c_nWindingFillMode; } diff --git a/DesktopEditor/raster/Metafile/svg/SvgObjects/CRect.h b/DesktopEditor/raster/Metafile/svg/SvgObjects/CRect.h index 2be5e036552..525c62ce6aa 100644 --- a/DesktopEditor/raster/Metafile/svg/SvgObjects/CRect.h +++ b/DesktopEditor/raster/Metafile/svg/SvgObjects/CRect.h @@ -14,10 +14,10 @@ namespace SVG void SetData(const std::map& mAttributes, unsigned short ushLevel, bool bHardMode = false) override; - bool Draw(IRenderer* pRenderer, const CSvgFile* pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pOtherStyles = NULL) const override; + bool Draw(IRenderer* pRenderer, const CSvgFile* pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pOtherStyles = NULL, const CRenderedObject* pContexObject = NULL) const override; private: - void ApplyStyle(IRenderer* pRenderer, const TSvgStyles* pStyles, const CSvgFile* pFile, int& nTypePath) const override; + void ApplyStyle(IRenderer* pRenderer, const TSvgStyles* pStyles, const CSvgFile* pFile, int& nTypePath, const CRenderedObject* pContexObject = NULL) const override; TBounds GetBounds() const override; diff --git a/DesktopEditor/raster/Metafile/svg/SvgObjects/CStyle.cpp b/DesktopEditor/raster/Metafile/svg/SvgObjects/CStyle.cpp index 51d77955801..98c64d9d55c 100644 --- a/DesktopEditor/raster/Metafile/svg/SvgObjects/CStyle.cpp +++ b/DesktopEditor/raster/Metafile/svg/SvgObjects/CStyle.cpp @@ -6,7 +6,6 @@ namespace SVG : m_pInternal(new NSCSS::CCssCalculator_Private) { m_pInternal->SetDpi(96); - m_pInternal->SetUnitMeasure(NSCSS::UnitMeasure::Pixel); } CSvgCalculator::~CSvgCalculator() @@ -30,139 +29,22 @@ namespace SVG if (NULL == pSvgObject) return; - const std::map *pData = m_pInternal->GetData(); const std::vector arSelectors = pSvgObject->GetFullPath(); - if ((NULL == pData || pData->empty()) && arSelectors.empty()) - return; - - std::vector arWords; - arWords.reserve(arSelectors.size() * 2); - - std::vector arNextNodes; - arNextNodes.reserve(arSelectors.size() * 2); - - for (std::vector::const_reverse_iterator oNode = arSelectors.rbegin(); oNode != arSelectors.rend(); ++oNode) - { - arWords.push_back(oNode->m_wsName); - - if (!oNode->m_wsClass.empty()) - { - if (oNode->m_wsClass.find(L' ') != std::wstring::npos) - { - std::vector arClasses = NSCSS::NS_STATIC_FUNCTIONS::GetWordsW(oNode->m_wsClass, L" "); - - if (arClasses.size() > 1) - arClasses.resize(unique(arClasses.begin(),arClasses.end()) - arClasses.begin()); - - arWords.push_back(std::accumulate(arClasses.begin(), arClasses.end(), std::wstring(), - [](std::wstring sRes, const std::wstring& sClass) - {return sRes += L'.' + sClass + L' ';})); - } - else - arWords.push_back(L'.' + oNode->m_wsClass); - } - if (!oNode->m_wsId.empty()) - arWords.push_back(L'#' + oNode->m_wsId); - } - - std::vector arElements; + std::vector arNodes = m_pInternal->CalculateAllNodes(arSelectors); + std::vector arPrevNodes; for (size_t i = 0; i < arSelectors.size(); ++i) { - std::wstring sName, sId; - std::vector arClasses; - - if (arWords.back()[0] == L'#') - { - sId = arWords.back(); - arWords.pop_back(); - arNextNodes.push_back(sId); - } - - if (arWords.back()[0] == L'.') - { - arClasses = NSCSS::NS_STATIC_FUNCTIONS::GetWordsW(arWords.back(), L" "); - arNextNodes.push_back(arWords.back()); - arWords.pop_back(); - } - - sName = arWords.back(); - arWords.pop_back(); - arNextNodes.push_back(sName); - - const std::map::const_iterator oFindName = pData->find(sName); - std::map::const_iterator oFindId; - std::vector arFindElements; - - if (!sId.empty()) - { - oFindId = pData->find(sId); - - if (oFindId != std::end(*pData)) - { - if (!oFindId->second->Empty()) - arFindElements.push_back(oFindId->second); - - const std::vector arTempPrev = oFindId->second->GetPrevElements(arNextNodes.rbegin() + ((arClasses.empty()) ? 1 : 2), arNextNodes.rend()); - - if (!arTempPrev.empty()) - arFindElements.insert(arFindElements.end(), arTempPrev.begin(), arTempPrev.end()); - } - } - - if (!arClasses.empty()) - { - for (std::vector::const_reverse_iterator iClass = arClasses.rbegin(); iClass != arClasses.rend(); ++iClass) - { - const std::map::const_iterator oFindClass = pData->find(*iClass); - if (oFindClass != std::end(*pData)) - { - if (!oFindClass->second->Empty()) - arFindElements.push_back(oFindClass->second); - - const std::vector arTempPrev = oFindClass->second->GetPrevElements(arNextNodes.rbegin() + 2, arNextNodes.rend()); - const std::vector arTempKins = oFindClass->second->GetNextOfKin(sName); - - if (!arTempPrev.empty()) - arFindElements.insert(arFindElements.end(), arTempPrev.begin(), arTempPrev.end()); - - if (!arTempKins.empty()) - arFindElements.insert(arFindElements.end(), arTempKins.begin(), arTempKins.end()); - } - } - } - - if (oFindName != std::end(*pData)) - { - if (!oFindName->second->Empty()) - arFindElements.push_back(oFindName->second); - - const std::vector arTempPrev = oFindName->second->GetPrevElements(arNextNodes.rbegin() + 1, arNextNodes.rend()); - const std::vector arTempKins = oFindName->second->GetNextOfKin(sName, arClasses); - - if (!arTempPrev.empty()) - arFindElements.insert(arFindElements.end(), arTempPrev.begin(), arTempPrev.end()); - - if (!arTempKins.empty()) - arFindElements.insert(arFindElements.end(), arTempKins.begin(), arTempKins.end()); - } - - - if (arFindElements.size() > 1) - { - std::sort(arFindElements.rbegin(), arFindElements.rend(), - [](NSCSS::CElement* oFirstElement, NSCSS::CElement* oSecondElement) - { - return oFirstElement->GetWeight() > oSecondElement->GetWeight(); - }); - } - pSvgObject->SetData(arSelectors[i].m_mAttributes, i + 1); - pSvgObject->SetData(arSelectors[i].m_wsStyle, i + 1, true); - for (const NSCSS::CElement* oElement : arFindElements) + for (const NSCSS::CElement* oElement : m_pInternal->FindElements(arNodes, arPrevNodes)) pSvgObject->SetData(oElement->GetStyle(), i + 1); + + if (!arSelectors[i].m_wsStyle.empty()) + pSvgObject->SetData(arSelectors[i].m_wsStyle, i + 1, true); } + + return; } } diff --git a/DesktopEditor/raster/Metafile/svg/SvgObjects/CSwitch.cpp b/DesktopEditor/raster/Metafile/svg/SvgObjects/CSwitch.cpp new file mode 100644 index 00000000000..58c0b592233 --- /dev/null +++ b/DesktopEditor/raster/Metafile/svg/SvgObjects/CSwitch.cpp @@ -0,0 +1,29 @@ +#include "CSwitch.h" + +namespace SVG +{ + CSwitch::CSwitch(XmlUtils::CXmlNode &oNode, CRenderedObject *pParent) + : CRenderedObject(oNode, pParent) + { + } + + bool CSwitch::Draw(IRenderer *pRenderer, const CSvgFile *pFile, CommandeMode oMode, const TSvgStyles *pStyles, const CRenderedObject* pContexObject) const + { + for (const CRenderedObject* pObject : m_arObjects) + { + if (NULL != pObject && pObject->Draw(pRenderer, pFile, oMode, pStyles, pContexObject)) + return true; + } + + return false; + } + + TBounds CSwitch::GetBounds() const + { + for (const CRenderedObject* pObject : m_arObjects) + if (NULL != pObject) + return pObject->GetBounds(); + + return TBounds{0., 0., 0., 0.}; + } +} diff --git a/DesktopEditor/raster/Metafile/svg/SvgObjects/CSwitch.h b/DesktopEditor/raster/Metafile/svg/SvgObjects/CSwitch.h new file mode 100644 index 00000000000..d15cf217322 --- /dev/null +++ b/DesktopEditor/raster/Metafile/svg/SvgObjects/CSwitch.h @@ -0,0 +1,18 @@ +#ifndef CSWITCH_H +#define CSWITCH_H + +#include "CContainer.h" + +namespace SVG +{ + class CSwitch : public CRenderedObject, public CContainer + { + public: + CSwitch(XmlUtils::CXmlNode& oNode, CRenderedObject* pParent = NULL); + + bool Draw(IRenderer* pRenderer, const CSvgFile *pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pStyles = NULL, const CRenderedObject* pContexObject = NULL) const override; + + TBounds GetBounds() const override; + }; +} +#endif // CSWITCH_H diff --git a/DesktopEditor/raster/Metafile/svg/SvgObjects/CSymbol.cpp b/DesktopEditor/raster/Metafile/svg/SvgObjects/CSymbol.cpp index c030c3aa4c5..2bc5a07ce4d 100644 --- a/DesktopEditor/raster/Metafile/svg/SvgObjects/CSymbol.cpp +++ b/DesktopEditor/raster/Metafile/svg/SvgObjects/CSymbol.cpp @@ -6,7 +6,7 @@ namespace SVG : CGraphicsContainer(oNode) {} - bool CSymbol::Draw(IRenderer *pRenderer, const CSvgFile *pFile, CommandeMode oMode, const TSvgStyles *pOtherStyles) const + bool CSymbol::Draw(IRenderer *pRenderer, const CSvgFile *pFile, CommandeMode oMode, const TSvgStyles *pOtherStyles, const CRenderedObject* pContexObject) const { if (NULL == pRenderer) return false; @@ -31,7 +31,7 @@ namespace SVG pRenderer->SetTransform(oMatrix.sx(), oMatrix.shy(), oMatrix.shx(), oMatrix.sy(), oMatrix.tx(), oMatrix.ty()); - CGraphicsContainer::Draw(pRenderer, pFile, oMode, pOtherStyles); + CGraphicsContainer::Draw(pRenderer, pFile, oMode, pOtherStyles, pContexObject); pRenderer->SetTransform(dM11, dM12, dM21, dM22, dDx, dDy); diff --git a/DesktopEditor/raster/Metafile/svg/SvgObjects/CSymbol.h b/DesktopEditor/raster/Metafile/svg/SvgObjects/CSymbol.h index f98f623ad43..7ba0c3a8b1e 100644 --- a/DesktopEditor/raster/Metafile/svg/SvgObjects/CSymbol.h +++ b/DesktopEditor/raster/Metafile/svg/SvgObjects/CSymbol.h @@ -2,6 +2,7 @@ #define CSYMBOL_H #include "CContainer.h" +#include "../../../graphics/pro/Fonts.h" namespace SVG { @@ -10,7 +11,7 @@ namespace SVG public: CSymbol(XmlUtils::CXmlNode& oNode, CRenderedObject* pParent = NULL, NSFonts::IFontManager *pFontManager = NULL); - bool Draw(IRenderer* pRenderer, const CSvgFile* pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pOtherStyles = NULL) const override; + bool Draw(IRenderer* pRenderer, const CSvgFile* pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pOtherStyles = NULL, const CRenderedObject* pContexObject = NULL) const override; }; } diff --git a/DesktopEditor/raster/Metafile/svg/SvgObjects/CText.cpp b/DesktopEditor/raster/Metafile/svg/SvgObjects/CText.cpp index 9447a8a9c23..aa3a67b8fb0 100644 --- a/DesktopEditor/raster/Metafile/svg/SvgObjects/CText.cpp +++ b/DesktopEditor/raster/Metafile/svg/SvgObjects/CText.cpp @@ -4,6 +4,7 @@ #include "../SvgUtils.h" #include "../CSvgFile.h" #include "CContainer.h" +#include "CFont.h" #include "CStyle.h" #ifndef MININT8 @@ -16,12 +17,17 @@ namespace SVG { + #define DEFAULT_TSPAN_FONT_SIZE 16 #define DefaultFontFamily L"Times New Roman" + #define MIN_FONT_SIZE 5 + #define MAX_FONT_SIZE 100 + #define MIN_SCALE 0.05 + #define MAX_SCALE 100 CTSpan::CTSpan(XmlUtils::CXmlNode& oNode, CRenderedObject* pParent, NSFonts::IFontManager* pFontManager, bool bCheckText) : CRenderedObject(oNode, pParent), m_pFontManager(pFontManager) { - m_oFont.UpdateSize(16); + m_oFont.UpdateSize(DEFAULT_TSPAN_FONT_SIZE,DEFAULT_TSPAN_FONT_SIZE); if (bCheckText) m_wsText = StrUtils::TrimExtraEnding(oNode.GetText()); @@ -40,6 +46,8 @@ namespace SVG if (NULL == pTSpan) return; + m_oStyles = pTSpan->m_oStyles; + if (m_oX.Empty()) { if (!pTSpan->m_arObjects.empty()) @@ -56,7 +64,7 @@ namespace SVG CTSpan::CTSpan(const std::wstring &wsText, const Point &oPosition, CRenderedObject *pParent, NSFonts::IFontManager *pFontManager, bool bCheckText) : CRenderedObject(NSCSS::CNode(L"tspan", L"", L""), pParent), m_pFontManager(pFontManager), m_wsText(wsText) { - m_oFont.UpdateSize(16); + m_oFont.UpdateSize(DEFAULT_TSPAN_FONT_SIZE, DEFAULT_TSPAN_FONT_SIZE); if (bCheckText) m_wsText = StrUtils::TrimExtraEnding(m_wsText); @@ -129,9 +137,17 @@ namespace SVG if (mAttributes.end() != mAttributes.find(L"text-decoration")) m_oText.SetDecoration(mAttributes.at(L"text-decoration"), ushLevel, bHardMode); + + //POSITION + if (mAttributes.end() != mAttributes.find(L"rotate")) + { + double dX, dY; + CalculatePosition(dX, dY); + m_oTransformation.m_oTransform.RotateAt(NSCSS::NS_STATIC_FUNCTIONS::ReadDouble(mAttributes.at(L"rotate")), dX, dY); + } } - bool CTSpan::Draw(IRenderer *pRenderer, const CSvgFile *pFile, CommandeMode oMode, const TSvgStyles *pOtherStyles) const + bool CTSpan::Draw(IRenderer *pRenderer, const CSvgFile *pFile, CommandeMode oMode, const TSvgStyles *pOtherStyles, const CRenderedObject* pContexObject) const { if (NULL == pRenderer || (m_wsText.empty() && m_arObjects.empty())) return false; @@ -141,19 +157,22 @@ namespace SVG if (!StartPath(pRenderer, pFile, oOldMatrix, oMode)) return false; - TBounds oBounds{(NULL != m_pParent) ? m_pParent->GetBounds() : TBounds{0., 0., 0., 0.}}; + double dX, dY; + CalculatePosition(dX, dY); - double dX = m_oX.ToDouble(NSCSS::Pixel, oBounds.m_dRight - oBounds.m_dLeft); - double dY = m_oY.ToDouble(NSCSS::Pixel, oBounds.m_dBottom - oBounds.m_dTop); - - ApplyFont(pRenderer, dX, dY); - - pRenderer->CommandDrawText(m_wsText, dX, dY, 0, 0); + if (!UseExternalFont(pFile, dX, dY, pRenderer, oMode, pOtherStyles, pContexObject)) + { + if (!m_wsText.empty()) + { + ApplyFont(pRenderer, dX, dY); + pRenderer->CommandDrawText(m_wsText, dX, dY, 0, 0); + } + } - for (const CRenderedObject* pTSpan : m_arObjects) - pTSpan->Draw(pRenderer, pFile, oMode, pOtherStyles); + for (const CTSpan* pTSpan : m_arObjects) + pTSpan->Draw(pRenderer, pFile, oMode, pOtherStyles, pContexObject); - EndPath(pRenderer, pFile, oOldMatrix, oMode, pOtherStyles); + EndPath(pRenderer, pFile, oOldMatrix, oMode, pOtherStyles, pContexObject); return true; } @@ -179,12 +198,12 @@ namespace SVG } } - void CTSpan::ApplyStyle(IRenderer *pRenderer, const TSvgStyles *pStyles, const CSvgFile *pFile, int &nTypePath) const + void CTSpan::ApplyStyle(IRenderer *pRenderer, const TSvgStyles *pStyles, const CSvgFile *pFile, int &nTypePath, const CRenderedObject* pContexObject) const { - if (ApplyStroke(pRenderer, &pStyles->m_oStroke, true)) + if (ApplyStroke(pRenderer, &pStyles->m_oStroke, true, pContexObject)) nTypePath += c_nStroke; - if (ApplyFill(pRenderer, &pStyles->m_oFill, pFile, true)) + if (ApplyFill(pRenderer, &pStyles->m_oFill, pFile, true, pContexObject)) nTypePath += c_nWindingFillMode; } @@ -287,6 +306,33 @@ namespace SVG pRenderer->put_BrushAlpha1(255); } + bool CTSpan::UseExternalFont(const CSvgFile *pFile, double dX, double dY, IRenderer *pRenderer, CommandeMode oMode, const TSvgStyles *pOtherStyles, const CRenderedObject* pContexObject) const + { + std::wstring wsFontFamily = DefaultFontFamily; + + if (!m_oFont.GetFamily().Empty()) + { + wsFontFamily = m_oFont.GetFamily().ToWString(); + CorrectFontFamily(wsFontFamily); + } + + CFont *pFont = pFile->GetFont(wsFontFamily); + + if (NULL == pFont) + return false; + + TSvgStyles oStyle; + + if (NULL != pOtherStyles) + oStyle = *pOtherStyles; + + oStyle += m_oStyles; + + pFont->Draw(m_wsText, dX, dY, m_oFont.GetSize().ToDouble(NSCSS::Pixel), pRenderer, pFile, oMode, &oStyle, pContexObject); + + return true; + } + TBounds CTSpan::GetBounds() const { TBounds oBounds; @@ -314,7 +360,7 @@ namespace SVG double CTSpan::GetWidth() const { - if (m_wsText.empty()) + if (m_wsText.empty() && m_arObjects.empty()) return 0.; std::wstring wsName = DefaultFontFamily; @@ -366,30 +412,52 @@ namespace SVG } } + void CTSpan::CalculatePosition(double &dX, double &dY) const + { + TBounds oBounds{(NULL != m_pParent) ? m_pParent->GetBounds() : TBounds{0., 0., 0., 0.}}; + + dX = m_oX.ToDouble(NSCSS::Pixel, oBounds.m_dRight - oBounds.m_dLeft); + dY = m_oY.ToDouble(NSCSS::Pixel, oBounds.m_dBottom - oBounds.m_dTop); + } + void CTSpan::Normalize(IRenderer *pRenderer, double &dX, double &dY, double &dFontHeight) const { if (NULL == pRenderer) return; - Aggplus::CMatrix oCurrentMatrix(m_oTransformtaion.m_oTransform.GetMatrix().GetFinalValue(NSCSS::NSProperties::TransformRotate)); + Aggplus::CMatrix oCurrentMatrix(m_oTransformation.m_oTransform.GetMatrix().GetFinalValue()); double dXScale = 1., dYScale = 1.; - double dModuleM11 = std::abs(oCurrentMatrix.sx()); - double dModuleM22 = std::abs(oCurrentMatrix.sy()); + const double dModuleM11 = std::abs(oCurrentMatrix.sx()); + const double dModuleM22 = std::abs(oCurrentMatrix.sy()); - if (!ISZERO(dModuleM11) && (dModuleM11 < 0.05 || dModuleM11 > 100)) + if (!ISZERO(dModuleM11) && (dModuleM11 < MIN_SCALE || dModuleM11 > MAX_SCALE)) dXScale /= dModuleM11; - if (!ISZERO(dModuleM22) && (dModuleM22 < 0.05 || dModuleM22 > 100)) + if (!ISZERO(dModuleM22) && (dModuleM22 < MIN_SCALE || dModuleM22 > MAX_SCALE)) dYScale /= dModuleM22; + dFontHeight *= dYScale; + + if (!Equals(0., dFontHeight) && dFontHeight < MIN_FONT_SIZE) + { + dXScale *= MIN_FONT_SIZE / dFontHeight; + dYScale *= MIN_FONT_SIZE / dFontHeight; + dFontHeight = MIN_FONT_SIZE; + } + else if (!Equals(0., dFontHeight) && dFontHeight > MAX_FONT_SIZE) + { + dXScale *= dFontHeight / MAX_FONT_SIZE; + dYScale *= dFontHeight / MAX_FONT_SIZE; + dFontHeight = MAX_FONT_SIZE; + } + if (Equals(1., dXScale) && Equals(1., dYScale)) return; - dX /= dXScale; - dY /= dYScale; - dFontHeight /= dYScale; + dX /= dXScale; + dY /= dYScale; double dM11, dM12, dM21, dM22, dDx, dDy; @@ -438,15 +506,12 @@ namespace SVG return new CText(oNode, pParent, pFontManager); } - bool CText::Draw(IRenderer *pRenderer, const CSvgFile *pFile, CommandeMode oMode, const TSvgStyles *pOtherStyles) const + bool CText::Draw(IRenderer *pRenderer, const CSvgFile *pFile, CommandeMode oMode, const TSvgStyles *pOtherStyles, const CRenderedObject* pContexObject) const { if (NULL == pRenderer || NULL == pRenderer) return false; - CTSpan::Draw(pRenderer, pFile, oMode, pOtherStyles); - - for (const CRenderedObject* pTSpan : m_arObjects) - pTSpan->Draw(pRenderer, pFile, oMode, pOtherStyles); + CTSpan::Draw(pRenderer, pFile, oMode, pOtherStyles, pContexObject); return true; } @@ -474,7 +539,7 @@ namespace SVG } } - bool CTextPath::Draw(IRenderer *pRenderer, const CSvgFile *pFile, CommandeMode oMode, const TSvgStyles *pOtherStyles) const + bool CTextPath::Draw(IRenderer *pRenderer, const CSvgFile *pFile, CommandeMode oMode, const TSvgStyles *pOtherStyles, const CRenderedObject* pContexObject) const { if (NULL == pRenderer || CommandeModeClip == oMode || NULL == m_pPath) return false; @@ -484,7 +549,7 @@ namespace SVG oMovingPath.Move(m_oX.ToDouble(NSCSS::Pixel)); for (CTSpan& oTSpan : Split()) - DrawGlyph(&oTSpan, oMovingPath, pRenderer, pFile, oMode); + DrawGlyph(&oTSpan, oMovingPath, pRenderer, pFile, oMode, pContexObject); for (const CTSpan* pTSpan : m_arObjects) { @@ -494,7 +559,7 @@ namespace SVG oMovingPath.Move(pTSpan->m_oX.ToDouble(NSCSS::Pixel)); } for (CTSpan& oGlyphs : pTSpan->Split()) - DrawGlyph(&oGlyphs, oMovingPath, pRenderer, pFile, oMode); + DrawGlyph(&oGlyphs, oMovingPath, pRenderer, pFile, oMode, pContexObject); } return true; @@ -511,7 +576,7 @@ namespace SVG return new CTextPath(oNode, pTSpan, pFontManager, pFile); } - void CTextPath::DrawGlyph(CTSpan* pTSpan, CMovingPath &oMovingPath, IRenderer *pRenderer, const CSvgFile *pFile, CommandeMode oMode) const + void CTextPath::DrawGlyph(CTSpan* pTSpan, CMovingPath &oMovingPath, IRenderer *pRenderer, const CSvgFile *pFile, CommandeMode oMode, const CRenderedObject* pContexObject) const { if (NULL == pTSpan) return; @@ -528,7 +593,7 @@ namespace SVG pTSpan->SetPosition(oPoint); pTSpan->SetTransform({std::make_pair(L"transform", L"rotate(" + std::to_wstring(dAngle) + L',' + std::to_wstring(oPoint.dX) + L',' + std::to_wstring(oPoint.dY) + L')')}, 0, true); - pTSpan->Draw(pRenderer, pFile, oMode); + pTSpan->Draw(pRenderer, pFile, oMode, NULL, pContexObject); oMovingPath.Move(dWidthSpan / 2); } diff --git a/DesktopEditor/raster/Metafile/svg/SvgObjects/CText.h b/DesktopEditor/raster/Metafile/svg/SvgObjects/CText.h index 63f7af4e0b4..5eb30892d64 100644 --- a/DesktopEditor/raster/Metafile/svg/SvgObjects/CText.h +++ b/DesktopEditor/raster/Metafile/svg/SvgObjects/CText.h @@ -22,20 +22,24 @@ namespace SVG void SetData(const std::map& mAttributes, unsigned short ushLevel, bool bHardMode = false) override; - bool Draw(IRenderer* pRenderer, const CSvgFile* pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pOtherStyles = NULL) const override; + bool Draw(IRenderer* pRenderer, const CSvgFile* pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pOtherStyles = NULL, const CRenderedObject* pContexObject = NULL) const override; bool AddObject(CTSpan* pObject) override; void InheritStyles(const CTSpan* pTSpan); private: - void ApplyStyle(IRenderer* pRenderer, const TSvgStyles* pStyles, const CSvgFile* pFile, int& nTypePath) const override; + void ApplyStyle(IRenderer* pRenderer, const TSvgStyles* pStyles, const CSvgFile* pFile, int& nTypePath, const CRenderedObject* pContexObject = NULL) const override; void ApplyFont(IRenderer* pRenderer, double& dX, double& dY) const; + bool UseExternalFont(const CSvgFile* pFile, double dX, double dY, IRenderer* pRenderer, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pOtherStyles = NULL, const CRenderedObject* pContexObject = NULL) const; + TBounds GetBounds() const override; double GetWidth() const; void CorrectFontFamily(std::wstring& wsFontFamily) const; + void CalculatePosition(double& dX, double& dY) const; + void Normalize(IRenderer* pRenderer, double& dX, double& dY, double& dFontHeight) const; void SetPosition(const Point& oPosition); @@ -62,7 +66,7 @@ namespace SVG static CText* Create(XmlUtils::CXmlNode& oNode, CRenderedObject* pParent = NULL, NSFonts::IFontManager* pFontManager = NULL); - bool Draw(IRenderer* pRenderer, const CSvgFile* pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pOtherStyles = NULL) const override; + bool Draw(IRenderer* pRenderer, const CSvgFile* pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pOtherStyles = NULL, const CRenderedObject* pContexObject = NULL) const override; }; class CTextPath : public CText @@ -70,11 +74,11 @@ namespace SVG public: CTextPath(XmlUtils::CXmlNode& oNode, CRenderedObject* pParent = NULL, NSFonts::IFontManager* pFontManager = NULL, const CSvgFile* pFile = NULL); - bool Draw(IRenderer* pRenderer, const CSvgFile* pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pOtherStyles = NULL) const override; + bool Draw(IRenderer* pRenderer, const CSvgFile* pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pOtherStyles = NULL, const CRenderedObject* pContexObject = NULL) const override; static CTextPath* Create(XmlUtils::CXmlNode& oNode, CRenderedObject* pParent = NULL, NSFonts::IFontManager* pFontManager = NULL, const CSvgFile* pFile = NULL); private: - void DrawGlyph(CTSpan* pTSpan, CMovingPath& oMovingPath, IRenderer* pRenderer, const CSvgFile* pFile, CommandeMode oMode) const; + void DrawGlyph(CTSpan* pTSpan, CMovingPath& oMovingPath, IRenderer* pRenderer, const CSvgFile* pFile, CommandeMode oMode, const CRenderedObject* pContexObject = NULL) const; const CPath *m_pPath; }; diff --git a/DesktopEditor/raster/Metafile/svg/SvgObjects/CUse.cpp b/DesktopEditor/raster/Metafile/svg/SvgObjects/CUse.cpp index fefd47fbc87..73f33188a89 100644 --- a/DesktopEditor/raster/Metafile/svg/SvgObjects/CUse.cpp +++ b/DesktopEditor/raster/Metafile/svg/SvgObjects/CUse.cpp @@ -3,8 +3,8 @@ namespace SVG { - CUse::CUse(XmlUtils::CXmlNode &oNode, CRenderedObject *pParent, const CSvgFile* pFile) - : CRenderedObject(oNode, pParent), m_pFile(pFile) + CUse::CUse(XmlUtils::CXmlNode &oNode, CRenderedObject *pParent) + : CRenderedObject(oNode, pParent) { m_wsHref = oNode.GetAttribute(L"href", oNode.GetAttribute(L"xlink:href")); @@ -25,16 +25,16 @@ namespace SVG SetFill(mAttributes, ushLevel, bHardMode); } - bool CUse::Draw(IRenderer *pRenderer, const CSvgFile *pFile, CommandeMode oMode, const TSvgStyles* pOtherStyles) const + bool CUse::Draw(IRenderer *pRenderer, const CSvgFile *pFile, CommandeMode oMode, const TSvgStyles* pOtherStyles, const CRenderedObject* pContexObject) const { - if (NULL == pRenderer || !m_oTransformtaion.m_bDraw) + if (NULL == pRenderer || !m_oTransformation.m_bDraw) return false; - - Aggplus::CMatrix oTransform; - - if (!StartPath(pRenderer, pFile, oTransform)) + + Aggplus::CMatrix oOldTransform; + + if (!StartPath(pRenderer, pFile, oOldTransform)) return false; - + double dM11, dM12, dM21, dM22, dDx, dDy; pRenderer->GetTransform(&dM11, &dM12, &dM21, &dM22, &dDx, &dDy); @@ -43,23 +43,25 @@ namespace SVG pRenderer->SetTransform(oNewTransform.sx(), oNewTransform.shy(), oNewTransform.shx(), oNewTransform.sy(), oNewTransform.tx(), oNewTransform.ty()); - const CRenderedObject *pFoundObj = dynamic_cast(m_pFile->GetMarkedObject(m_wsHref)); + const CRenderedObject *pFoundObj = dynamic_cast(pFile->GetMarkedObject(m_wsHref)); - if (NULL != pFoundObj) + bool bResult = false; + + if (NULL != pFoundObj && this != pFoundObj) { if (NULL != pOtherStyles) { TSvgStyles oNewStyles(m_oStyles); oNewStyles += *pOtherStyles; - pFoundObj->Draw(pRenderer, pFile, oMode, &oNewStyles); + bResult = pFoundObj->Draw(pRenderer, pFile, oMode, &oNewStyles, this); } else - pFoundObj->Draw(pRenderer, pFile, oMode, &m_oStyles); + bResult = pFoundObj->Draw(pRenderer, pFile, oMode, &m_oStyles, this); } - - EndPath(pRenderer, pFile, oTransform); - return true; + EndPath(pRenderer, pFile, oOldTransform); + + return bResult; } TBounds CUse::GetBounds() const diff --git a/DesktopEditor/raster/Metafile/svg/SvgObjects/CUse.h b/DesktopEditor/raster/Metafile/svg/SvgObjects/CUse.h index ba46b2867d3..fcbfa029701 100644 --- a/DesktopEditor/raster/Metafile/svg/SvgObjects/CUse.h +++ b/DesktopEditor/raster/Metafile/svg/SvgObjects/CUse.h @@ -9,12 +9,12 @@ namespace SVG class CUse : public CRenderedObject { public: - CUse(XmlUtils::CXmlNode& oNode, CRenderedObject* pParent = NULL, const CSvgFile* pFile = NULL); + CUse(XmlUtils::CXmlNode& oNode, CRenderedObject* pParent = NULL); virtual ~CUse(); void SetData(const std::map& mAttributes, unsigned short ushLevel, bool bHardMode = false) override; - bool Draw(IRenderer* pRenderer, const CSvgFile* pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pOtherStyles = NULL) const override; + bool Draw(IRenderer* pRenderer, const CSvgFile* pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pOtherStyles = NULL, const CRenderedObject* pContexObject = NULL) const override; private: TBounds GetBounds() const override; @@ -26,7 +26,6 @@ namespace SVG SvgDigit m_oHeight; std::wstring m_wsHref; - const CSvgFile *m_pFile; }; } #endif // CUSE_H diff --git a/DesktopEditor/raster/Metafile/svg/SvgTypes.h b/DesktopEditor/raster/Metafile/svg/SvgTypes.h index 38ea443a6dc..13a563466b0 100644 --- a/DesktopEditor/raster/Metafile/svg/SvgTypes.h +++ b/DesktopEditor/raster/Metafile/svg/SvgTypes.h @@ -14,6 +14,7 @@ namespace SVG #define SvgDigit NSCSS::NSProperties::CDigit #define SvgString NSCSS::NSProperties::CString #define SvgColor NSCSS::NSProperties::CColor + #define SvgURL NSCSS::NSProperties::CURL #define SvgEnum NSCSS::NSProperties::CEnum #define SvgTransform NSCSS::NSProperties::CTransform diff --git a/DesktopEditor/raster/Metafile/svg/SvgUtils.h b/DesktopEditor/raster/Metafile/svg/SvgUtils.h index 6a5e76fbdad..34b24a6373a 100644 --- a/DesktopEditor/raster/Metafile/svg/SvgUtils.h +++ b/DesktopEditor/raster/Metafile/svg/SvgUtils.h @@ -53,6 +53,41 @@ namespace SVG return ReadDoubleValues(wsValue.begin(), wsValue.end()); } + inline bool ReadDoubleValue(const std::wstring& wsValue, double& dValue) + { + std::wregex oPattern(LR"([-+]?(\d+(\.\d*)?|\.\d+)([eE][-+]?\d+)?)"); + std::wsmatch oMatch; + + if (!std::regex_search(wsValue, oMatch, oPattern)) + return false; + + dValue = std::stod(oMatch[0].str()); + + return true; + } + + inline bool ReadAngle(const std::wstring& wsValue, double& dValue) + { + std::wregex oPattern(LR"(([-+]?(\d+(\.\d*)?|\.\d+)([eE][-+]?\d+)?)(deg|rad|grad|turn))"); + std::wsmatch oMatch; + + if (!std::regex_search(wsValue, oMatch, oPattern)) + return false; + + const std::wstring wsUnit{oMatch[5].str()}; + + dValue = std::stod(oMatch[1].str()); + + if (L"grad" == wsUnit) + dValue *= 400. / 360.; + else if (L"rad" == wsUnit) + dValue *= 180. / 3.14159; + else if (L"turn" == wsUnit) + dValue *= 360.; + + return true; + } + inline std::wstring TrimExtraEnding(const std::wstring& wsString) { std::wstring::const_iterator itBeginPos = std::find_if(wsString.begin(), wsString.end(), [](const wchar_t& wChar){ return !iswspace(wChar);}); diff --git a/DesktopEditor/raster/Metafile/test/MetafileToSvg/main.cpp b/DesktopEditor/raster/Metafile/test/MetafileToSvg/main.cpp index 05c54979c33..ca3c658d0e6 100644 --- a/DesktopEditor/raster/Metafile/test/MetafileToSvg/main.cpp +++ b/DesktopEditor/raster/Metafile/test/MetafileToSvg/main.cpp @@ -29,35 +29,33 @@ * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode * */ -//#include +// #include +#include "../../../../fontengine/ApplicationFontsWorker.h" #include "../../../../graphics/pro/Fonts.h" #include "../../../../graphics/pro/Graphics.h" -#include "../../../../fontengine/ApplicationFontsWorker.h" -#include "../../../../raster/BgraFrame.h" #include "../../../../common/Directory.h" +#include "../../../../raster/BgraFrame.h" -int main(int argc, char *argv[]) +int main(int argc, char* argv[]) { - // Check system fonts - CApplicationFontsWorker oWorker; - oWorker.m_sDirectory = NSFile::GetProcessDirectory() + L"/fonts_cache"; - oWorker.m_bIsNeedThumbnails = false; - - if (!NSDirectory::Exists(oWorker.m_sDirectory)) - NSDirectory::CreateDirectory(oWorker.m_sDirectory); + // Check system fonts + CApplicationFontsWorker oWorker; + oWorker.m_sDirectory = NSFile::GetProcessDirectory() + L"/fonts_cache"; + oWorker.m_bIsNeedThumbnails = false; - NSFonts::IApplicationFonts* pFonts = oWorker.Check(); + if (!NSDirectory::Exists(oWorker.m_sDirectory)) + NSDirectory::CreateDirectory(oWorker.m_sDirectory); - MetaFile::IMetaFile* pMetafile = MetaFile::Create(pFonts); - pMetafile->LoadFromFile(L"PATH_TO_METAFILE"); + NSFonts::IApplicationFonts* pFonts = oWorker.Check(); - std::wstring wsData; + MetaFile::IMetaFile* pMetafile = MetaFile::Create(pFonts); + pMetafile->LoadFromFile(L"D:/image1.wmf"); - pMetafile->ConvertToSvg(wsData); + std::wstring wsData = pMetafile->ConvertToSvg(); pMetafile->Release(); - pFonts->Release(); - return 0; + pFonts->Release(); + return 0; } diff --git a/DesktopEditor/raster/PICT/PICFile.cpp b/DesktopEditor/raster/PICT/PICFile.cpp new file mode 100644 index 00000000000..12b6ec2b7ae --- /dev/null +++ b/DesktopEditor/raster/PICT/PICFile.cpp @@ -0,0 +1,138 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#include "PICFile.h" +#include "pic.h" + +#include "../../common/File.h" + +namespace PICT { + +bool ImageToFrame(ImagePICT* pImage, CBgraFrame* pFrame, bool isRGBA) +{ + int nWidth = pImage->m_nWidth; + int nHeight = pImage->m_nHeight; + int BufferSize = 4 * nWidth * nHeight; + + if (BufferSize < 1) + return false; + + pFrame->put_Height(nHeight); + pFrame->put_Width(nWidth); + pFrame->put_Stride(4 * nWidth); + + BYTE* pData = new BYTE[BufferSize]; + + if (!pData) + return false; + + pFrame->put_Data(pData); + + unsigned char* pBufferPtr = (unsigned char*)pData; + + unsigned int indR = isRGBA ? 2 : 0; + unsigned int indG = 1; + unsigned int indB = isRGBA ? 0 : 2; + + for (size_t i = 0; i < pImage->m_nHeight; i++) + { + unsigned char* q = pImage->ppixels + pImage->number_channels * (i * pImage->m_nWidth); + for (size_t j = 0; j < pImage->m_nWidth; j++) + { + pBufferPtr[indR] = * q; + pBufferPtr[indG] = * (q + 1); + pBufferPtr[indB] = * (q + 2); + pBufferPtr[3] = *(q + 3); + q += 4; + pBufferPtr += 4; + } + } + + return true; +} + +//////////////////////////////////////////////////////////////////////////////////////// + +bool CPictFile::Open(CBgraFrame *pFrame, const std::wstring &strFileName, bool isRGBA) +{ + NSFile::CFileBinary oFile; + if (!oFile.OpenFile(strFileName)) + return false; + + ImagePICT* pImage = new ImagePICT; + AquireImage(pImage); + + bool status = false; + if (DecodePICT(oFile.GetFileNative(), pImage)) + { + status = ImageToFrame(pImage, pFrame, isRGBA); + } + + DestroyImage(pImage); + oFile.CloseFile(); + + return status; +} + +bool CPictFile::Open(CBgraFrame *pFrame, BYTE *pBuffer, int nSize, bool isRGBA) +{ + NSFile::CFileBinary oFile; + std::wstring sTmpFile = NSFile::CFileBinary::CreateTempFileWithUniqueName(NSFile::CFileBinary::GetTempPath(), L"pct"); + + if (sTmpFile.empty()) + return false; + + if (!oFile.CreateFile(sTmpFile)) + return false; + + ImagePICT* pImage = new ImagePICT; + AquireImage(pImage); + + oFile.WriteFile(pBuffer, nSize); + oFile.CloseFile(); + + oFile.OpenFile(sTmpFile); + + bool status = false; + if (DecodePICT(oFile.GetFileNative(), pImage)) + { + status = ImageToFrame(pImage, pFrame, isRGBA); + } + + DestroyImage(pImage); + oFile.CloseFile(); + + if (NSFile::CFileBinary::Exists(sTmpFile)) + NSFile::CFileBinary::Remove(sTmpFile); + + return status; +} +} diff --git a/X2tConverter/test/iosTest/TestIOSX2tConverter/main.m b/DesktopEditor/raster/PICT/PICFile.h similarity index 81% rename from X2tConverter/test/iosTest/TestIOSX2tConverter/main.m rename to DesktopEditor/raster/PICT/PICFile.h index 15f7dc48359..40daae02f29 100644 --- a/X2tConverter/test/iosTest/TestIOSX2tConverter/main.m +++ b/DesktopEditor/raster/PICT/PICFile.h @@ -29,19 +29,17 @@ * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode * */ -// -// main.m -// TestIOSX2tConverter -// -// Created by alexey.musinov on 01.04.15. -// Copyright (c) 2015 Ascensio System SIA. All rights reserved. -// +#ifndef PICFILE_H +#define PICFILE_H -#import -#import "AppDelegate.h" +#include "../BgraFrame.h" -int main(int argc, char * argv[]) { - @autoreleasepool { - return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); - } +namespace PICT { + class GRAPHICS_DECL CPictFile { + public: + bool Open(CBgraFrame* pFrame, const std::wstring& strFileName, bool isRGBA); + bool Open(CBgraFrame* pFrame, BYTE* pBuffer, int nSize, bool isRGBA); + }; } + +#endif // PICFILE_H diff --git a/DesktopEditor/raster/PICT/pic.cpp b/DesktopEditor/raster/PICT/pic.cpp new file mode 100644 index 00000000000..cc786b44e20 --- /dev/null +++ b/DesktopEditor/raster/PICT/pic.cpp @@ -0,0 +1,3294 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#include "pic.h" + +static const PICTCode + codes[] = + { + /* 0x00 */ { "NOP", 0, "nop" }, + /* 0x01 */ { "ClipRgn", 0, "clip" }, + /* 0x02 */ { "BkPat", 8, "background pattern" }, + /* 0x03 */ { "TxFont", 2, "text font (word)" }, + /* 0x04 */ { "TxFace", 1, "text face (byte)" }, + /* 0x05 */ { "TxMode", 2, "text mode (word)" }, + /* 0x06 */ { "SpExtra", 4, "space extra (fixed point)" }, + /* 0x07 */ { "PnSize", 4, "pen size (point)" }, + /* 0x08 */ { "PnMode", 2, "pen mode (word)" }, + /* 0x09 */ { "PnPat", 8, "pen pattern" }, + /* 0x0a */ { "FillPat", 8, "fill pattern" }, + /* 0x0b */ { "OvSize", 4, "oval size (point)" }, + /* 0x0c */ { "Origin", 4, "dh, dv (word)" }, + /* 0x0d */ { "TxSize", 2, "text size (word)" }, + /* 0x0e */ { "FgColor", 4, "foreground color (long longword)" }, + /* 0x0f */ { "BkColor", 4, "background color (long longword)" }, + /* 0x10 */ { "TxRatio", 8, "numerator (point), denominator (point)" }, + /* 0x11 */ { "Version", 1, "version (byte)" }, + /* 0x12 */ { "BkPixPat", 0, "color background pattern" }, + /* 0x13 */ { "PnPixPat", 0, "color pen pattern" }, + /* 0x14 */ { "FillPixPat", 0, "color fill pattern" }, + /* 0x15 */ { "PnLocHFrac", 2, "fractional pen position" }, + /* 0x16 */ { "ChExtra", 2, "extra for each character" }, + /* 0x17 */ { "reserved", 0, "reserved for Apple use" }, + /* 0x18 */ { "reserved", 0, "reserved for Apple use" }, + /* 0x19 */ { "reserved", 0, "reserved for Apple use" }, + /* 0x1a */ { "RGBFgCol", 6, "RGB foreColor" }, + /* 0x1b */ { "RGBBkCol", 6, "RGB backColor" }, + /* 0x1c */ { "HiliteMode", 0, "hilite mode flag" }, + /* 0x1d */ { "HiliteColor", 6, "RGB hilite color" }, + /* 0x1e */ { "DefHilite", 0, "Use default hilite color" }, + /* 0x1f */ { "OpColor", 6, "RGB OpColor for arithmetic modes" }, + /* 0x20 */ { "Line", 8, "pnLoc (point), newPt (point)" }, + /* 0x21 */ { "LineFrom", 4, "newPt (point)" }, + /* 0x22 */ { "ShortLine", 6, "pnLoc (point, dh, dv (-128 .. 127))" }, + /* 0x23 */ { "ShortLineFrom", 2, "dh, dv (-128 .. 127)" }, + /* 0x24 */ { "reserved", -1, "reserved for Apple use" }, + /* 0x25 */ { "reserved", -1, "reserved for Apple use" }, + /* 0x26 */ { "reserved", -1, "reserved for Apple use" }, + /* 0x27 */ { "reserved", -1, "reserved for Apple use" }, + /* 0x28 */ { "LongText", 0, "txLoc (point), count (0..255), text" }, + /* 0x29 */ { "DHText", 0, "dh (0..255), count (0..255), text" }, + /* 0x2a */ { "DVText", 0, "dv (0..255), count (0..255), text" }, + /* 0x2b */ { "DHDVText", 0, "dh, dv (0..255), count (0..255), text" }, + /* 0x2c */ { "reserved", -1, "reserved for Apple use" }, + /* 0x2d */ { "reserved", -1, "reserved for Apple use" }, + /* 0x2e */ { "reserved", -1, "reserved for Apple use" }, + /* 0x2f */ { "reserved", -1, "reserved for Apple use" }, + /* 0x30 */ { "frameRect", 8, "rect" }, + /* 0x31 */ { "paintRect", 8, "rect" }, + /* 0x32 */ { "eraseRect", 8, "rect" }, + /* 0x33 */ { "invertRect", 8, "rect" }, + /* 0x34 */ { "fillRect", 8, "rect" }, + /* 0x35 */ { "reserved", 8, "reserved for Apple use" }, + /* 0x36 */ { "reserved", 8, "reserved for Apple use" }, + /* 0x37 */ { "reserved", 8, "reserved for Apple use" }, + /* 0x38 */ { "frameSameRect", 0, "rect" }, + /* 0x39 */ { "paintSameRect", 0, "rect" }, + /* 0x3a */ { "eraseSameRect", 0, "rect" }, + /* 0x3b */ { "invertSameRect", 0, "rect" }, + /* 0x3c */ { "fillSameRect", 0, "rect" }, + /* 0x3d */ { "reserved", 0, "reserved for Apple use" }, + /* 0x3e */ { "reserved", 0, "reserved for Apple use" }, + /* 0x3f */ { "reserved", 0, "reserved for Apple use" }, + /* 0x40 */ { "frameRRect", 8, "rect" }, + /* 0x41 */ { "paintRRect", 8, "rect" }, + /* 0x42 */ { "eraseRRect", 8, "rect" }, + /* 0x43 */ { "invertRRect", 8, "rect" }, + /* 0x44 */ { "fillRRrect", 8, "rect" }, + /* 0x45 */ { "reserved", 8, "reserved for Apple use" }, + /* 0x46 */ { "reserved", 8, "reserved for Apple use" }, + /* 0x47 */ { "reserved", 8, "reserved for Apple use" }, + /* 0x48 */ { "frameSameRRect", 0, "rect" }, + /* 0x49 */ { "paintSameRRect", 0, "rect" }, + /* 0x4a */ { "eraseSameRRect", 0, "rect" }, + /* 0x4b */ { "invertSameRRect", 0, "rect" }, + /* 0x4c */ { "fillSameRRect", 0, "rect" }, + /* 0x4d */ { "reserved", 0, "reserved for Apple use" }, + /* 0x4e */ { "reserved", 0, "reserved for Apple use" }, + /* 0x4f */ { "reserved", 0, "reserved for Apple use" }, + /* 0x50 */ { "frameOval", 8, "rect" }, + /* 0x51 */ { "paintOval", 8, "rect" }, + /* 0x52 */ { "eraseOval", 8, "rect" }, + /* 0x53 */ { "invertOval", 8, "rect" }, + /* 0x54 */ { "fillOval", 8, "rect" }, + /* 0x55 */ { "reserved", 8, "reserved for Apple use" }, + /* 0x56 */ { "reserved", 8, "reserved for Apple use" }, + /* 0x57 */ { "reserved", 8, "reserved for Apple use" }, + /* 0x58 */ { "frameSameOval", 0, "rect" }, + /* 0x59 */ { "paintSameOval", 0, "rect" }, + /* 0x5a */ { "eraseSameOval", 0, "rect" }, + /* 0x5b */ { "invertSameOval", 0, "rect" }, + /* 0x5c */ { "fillSameOval", 0, "rect" }, + /* 0x5d */ { "reserved", 0, "reserved for Apple use" }, + /* 0x5e */ { "reserved", 0, "reserved for Apple use" }, + /* 0x5f */ { "reserved", 0, "reserved for Apple use" }, + /* 0x60 */ { "frameArc", 12, "rect, startAngle, arcAngle" }, + /* 0x61 */ { "paintArc", 12, "rect, startAngle, arcAngle" }, + /* 0x62 */ { "eraseArc", 12, "rect, startAngle, arcAngle" }, + /* 0x63 */ { "invertArc", 12, "rect, startAngle, arcAngle" }, + /* 0x64 */ { "fillArc", 12, "rect, startAngle, arcAngle" }, + /* 0x65 */ { "reserved", 12, "reserved for Apple use" }, + /* 0x66 */ { "reserved", 12, "reserved for Apple use" }, + /* 0x67 */ { "reserved", 12, "reserved for Apple use" }, + /* 0x68 */ { "frameSameArc", 4, "rect, startAngle, arcAngle" }, + /* 0x69 */ { "paintSameArc", 4, "rect, startAngle, arcAngle" }, + /* 0x6a */ { "eraseSameArc", 4, "rect, startAngle, arcAngle" }, + /* 0x6b */ { "invertSameArc", 4, "rect, startAngle, arcAngle" }, + /* 0x6c */ { "fillSameArc", 4, "rect, startAngle, arcAngle" }, + /* 0x6d */ { "reserved", 4, "reserved for Apple use" }, + /* 0x6e */ { "reserved", 4, "reserved for Apple use" }, + /* 0x6f */ { "reserved", 4, "reserved for Apple use" }, + /* 0x70 */ { "framePoly", 0, "poly" }, + /* 0x71 */ { "paintPoly", 0, "poly" }, + /* 0x72 */ { "erasePoly", 0, "poly" }, + /* 0x73 */ { "invertPoly", 0, "poly" }, + /* 0x74 */ { "fillPoly", 0, "poly" }, + /* 0x75 */ { "reserved", 0, "reserved for Apple use" }, + /* 0x76 */ { "reserved", 0, "reserved for Apple use" }, + /* 0x77 */ { "reserved", 0, "reserved for Apple use" }, + /* 0x78 */ { "frameSamePoly", 0, "poly (NYI)" }, + /* 0x79 */ { "paintSamePoly", 0, "poly (NYI)" }, + /* 0x7a */ { "eraseSamePoly", 0, "poly (NYI)" }, + /* 0x7b */ { "invertSamePoly", 0, "poly (NYI)" }, + /* 0x7c */ { "fillSamePoly", 0, "poly (NYI)" }, + /* 0x7d */ { "reserved", 0, "reserved for Apple use" }, + /* 0x7e */ { "reserved", 0, "reserved for Apple use" }, + /* 0x7f */ { "reserved", 0, "reserved for Apple use" }, + /* 0x80 */ { "frameRgn", 0, "region" }, + /* 0x81 */ { "paintRgn", 0, "region" }, + /* 0x82 */ { "eraseRgn", 0, "region" }, + /* 0x83 */ { "invertRgn", 0, "region" }, + /* 0x84 */ { "fillRgn", 0, "region" }, + /* 0x85 */ { "reserved", 0, "reserved for Apple use" }, + /* 0x86 */ { "reserved", 0, "reserved for Apple use" }, + /* 0x87 */ { "reserved", 0, "reserved for Apple use" }, + /* 0x88 */ { "frameSameRgn", 0, "region (NYI)" }, + /* 0x89 */ { "paintSameRgn", 0, "region (NYI)" }, + /* 0x8a */ { "eraseSameRgn", 0, "region (NYI)" }, + /* 0x8b */ { "invertSameRgn", 0, "region (NYI)" }, + /* 0x8c */ { "fillSameRgn", 0, "region (NYI)" }, + /* 0x8d */ { "reserved", 0, "reserved for Apple use" }, + /* 0x8e */ { "reserved", 0, "reserved for Apple use" }, + /* 0x8f */ { "reserved", 0, "reserved for Apple use" }, + /* 0x90 */ { "BitsRect", 0, "copybits, rect clipped" }, + /* 0x91 */ { "BitsRgn", 0, "copybits, rgn clipped" }, + /* 0x92 */ { "reserved", -1, "reserved for Apple use" }, + /* 0x93 */ { "reserved", -1, "reserved for Apple use" }, + /* 0x94 */ { "reserved", -1, "reserved for Apple use" }, + /* 0x95 */ { "reserved", -1, "reserved for Apple use" }, + /* 0x96 */ { "reserved", -1, "reserved for Apple use" }, + /* 0x97 */ { "reserved", -1, "reserved for Apple use" }, + /* 0x98 */ { "PackBitsRect", 0, "packed copybits, rect clipped" }, + /* 0x99 */ { "PackBitsRgn", 0, "packed copybits, rgn clipped" }, + /* 0x9a */ { "DirectBitsRect", 0, "PixMap, srcRect, dstRect, mode, PixData" }, + /* 0x9b */ { "DirectBitsRgn", 0, "PixMap, srcRect, dstRect, mode, maskRgn, PixData" }, + /* 0x9c */ { "reserved", -1, "reserved for Apple use" }, + /* 0x9d */ { "reserved", -1, "reserved for Apple use" }, + /* 0x9e */ { "reserved", -1, "reserved for Apple use" }, + /* 0x9f */ { "reserved", -1, "reserved for Apple use" }, + /* 0xa0 */ { "ShortComment", 2, "kind (word)" }, + /* 0xa1 */ { "LongComment", 0, "kind (word), size (word), data" } + }; + +#define BackgroundColorRGBA 255,255,255,255 +#define TransparentAlpha ((unsigned char) 0) + +int LocaleToLowercase(const int c) +{ + if ((c == EOF) || (c != (unsigned char) c)) + return(c); + return(tolower((int) ((unsigned char) c))); +} + +int LocaleCompare(const char *p,const char *q) +{ + if (p == (char *) NULL) + { + if (q == (char *) NULL) + return(0); + return(-1); + } + if (q == (char *) NULL) + return(1); + { + const unsigned char + *r = (const unsigned char *) p, + *s = (const unsigned char *) q; + + for ( ; (*r != '\0') && (*s != '\0') && ((*r == *s) || + (LocaleToLowercase((int) *r) == LocaleToLowercase((int) *s))); r++, s++); + return(LocaleToLowercase((int) *r)-LocaleToLowercase((int) *s)); + } +} + +void LocaleLower(char *string) +{ + char + *q; + + for (q=string; *q != '\0'; q++) + *q=(char) LocaleToLowercase((int) *q); +} + +int LocaleNCompare(const char *p,const char *q,const size_t length) +{ + if (p == (char *) NULL) + { + if (q == (char *) NULL) + return(0); + return(-1); + } + if (q == (char *) NULL) + return(1); + if (length == 0) + return(0); + { + const unsigned char + *s = (const unsigned char *) p, + *t = (const unsigned char *) q; + + size_t + n = length; + + for (n--; (*s != '\0') && (*t != '\0') && (n != 0) && ((*s == *t) || + (LocaleToLowercase((int) *s) == LocaleToLowercase((int) *t))); s++, t++, n--); + return(LocaleToLowercase((int) *s)-LocaleToLowercase((int) *t)); + } +} + +char *ConstantString(const char *source) +{ + char + *destination; + + size_t + length; + + length=0; + if (source != (char *) NULL) + length+=strlen(source); + destination=(char *) NULL; + if (~length >= 1UL) + destination=(char *) malloc(length+1UL*sizeof(*destination)); + if (destination == (char *) NULL) + return NULL; + if (source != (char *) NULL) + (void) memcpy(destination,source,length*sizeof(*destination)); + destination[length]='\0'; + return(destination); +} + +int IsStringTrue(const char *value) +{ + if (value == (const char *) NULL) + return 0; + if (LocaleCompare(value,"true") == 0) + return 1; + if (LocaleCompare(value,"on") == 0) + return 1; + if (LocaleCompare(value,"yes") == 0) + return 1; + if (LocaleCompare(value,"1") == 0) + return 1; + return 0; +} + +size_t CopyMagickString(char *destination,const char *source,const size_t length) +{ + char + *q; + + const char + *p; + + size_t + n; + + p=source; + q=destination; + for (n=length; n > 4; n-=4) + { + if (((*q++)=(*p++)) == '\0') + return((size_t) (p-source-1)); + if (((*q++)=(*p++)) == '\0') + return((size_t) (p-source-1)); + if (((*q++)=(*p++)) == '\0') + return((size_t) (p-source-1)); + if (((*q++)=(*p++)) == '\0') + return((size_t) (p-source-1)); + } + if (length != 0) + { + while (--n != 0) + if (((*q++)=(*p++)) == '\0') + return((size_t) (p-source-1)); + *q='\0'; + } + return((size_t) (p-source)); +} + +StringInfo *AcquireStringInfo(const size_t length) +{ + StringInfo + *string_info; + + string_info=(StringInfo *) malloc(sizeof(*string_info)); + (void) memset(string_info,0,sizeof(*string_info)); + string_info->signature=0xabacadabUL; + string_info->length=length; + if (~string_info->length >= (4096-1)) + string_info->datum=(unsigned char *) malloc((string_info->length+4096)*sizeof(*string_info->datum)); + if (string_info->datum == (unsigned char *) NULL) + return (StringInfo *) NULL; + (void) memset(string_info->datum,0,(length+4096)* + sizeof(*string_info->datum)); + return(string_info); +} + +char *CloneString(char **destination,const char *source) +{ + size_t length; + + if (source == (const char *) NULL) + { + if (*destination != (char *) NULL) + free(*destination); + return(NULL); + } + if (*destination == (char *) NULL) + { + *destination=(char*) malloc((strlen(source) + 4096)/* * sizeof (*destination)*/); + + memcpy(*destination,source,strlen(source)/**sizeof(**destination)*/); + (*destination)[strlen(source)]='\0'; + return(*destination); + } + length=strlen(source); + if (~length < 4096) + return NULL; + free(*destination); + *destination = (char*) malloc((length+4096)/**sizeof (**destination)*/); + if (*destination == (char *) NULL) + return NULL; + if (length != 0) + memcpy(*destination,source,length/**sizeof(**destination)*/); + (*destination)[length]='\0'; + return(*destination); +} + +StringInfo *CloneStringInfo(const StringInfo *string_info) +{ + StringInfo *clone_info; + + clone_info=AcquireStringInfo(string_info->length); + CloneString(&clone_info->path,string_info->path); + CloneString(&clone_info->name,string_info->name); + if (string_info->length != 0) + memcpy(clone_info->datum,string_info->datum,string_info->length+1); + return(clone_info); +} + +StringInfo *DestroyStringInfo(StringInfo *string_info) +{ + if (string_info->datum != (unsigned char *) NULL) + free(string_info->datum); + if (string_info->name != (char *) NULL) + free(string_info->name); + if (string_info->path != (char *) NULL) + free(string_info->path); + string_info->signature=(~0xabacadabUL); + free(string_info); + return(string_info); +} + +StringInfo *BlobToStringInfo(const void *blob,const size_t length) +{ + StringInfo + *string_info; + + if (~length < 4096) + return (StringInfo*) NULL; + + string_info=(StringInfo *) malloc(sizeof(*string_info)); + (void) memset(string_info,0,sizeof(*string_info)); + string_info->signature=0xabacadabUL; + if (string_info == (StringInfo*) NULL) + return (StringInfo*) NULL; + string_info->length=length; + string_info->datum=(unsigned char *) malloc(length+4096*sizeof(*string_info->datum)); + if (string_info->datum == (unsigned char *) NULL) + { + string_info = DestroyStringInfo(string_info); + return((StringInfo *) NULL); + } + if (blob != (const void *) NULL) + (void) memcpy(string_info->datum,blob,length); + else + (void) memset(string_info->datum,0,length*sizeof(*string_info->datum)); + (void) memset(string_info->datum+length,0,4096*sizeof(*string_info->datum)); + return(string_info); +} + +void DeletePixelsMemory(ImagePICT* image) +{ + if (image->ppixels != NULL) + { + free(image->ppixels); + + image->ppixels = NULL; + image->m_nPixelsSize = 0; + } +} + +PixelChannelMap *AcquirePixelChannelMap() +{ + PixelChannelMap + *channel_map; + + long long + i; + + channel_map=(PixelChannelMap *) malloc(65*sizeof(*channel_map)); + if (channel_map == (PixelChannelMap *) NULL) + return (PixelChannelMap *) NULL; + (void) memset(channel_map,0,65*sizeof(*channel_map)); + for (i=0; i <= 64; i++) + channel_map[i].channel=(PixelChannel) i; + channel_map[RedPixelChannel].offset = 0; + channel_map[GreenPixelChannel].offset = 1; + channel_map[BluePixelChannel].offset = 2; + channel_map[AlphaPixelChannel].offset = 3; + channel_map[IndexPixelChannel].offset = 5; + + return(channel_map); +} + +void GetPixelInfo(ImagePICT *image,PixelInfo *pixel) +{ + (void) memset(pixel,0,sizeof(*pixel)); + pixel->storage_class=DirectClass; + pixel->colorspace=sRGBColorspace; + pixel->depth=8; + pixel->alpha_trait=UndefinedPixelTrait; + pixel->alpha=255.0; + if (image == (const ImagePICT *) NULL) + return; + pixel->storage_class=image->storage_class; + pixel->colorspace=image->colorspace; + pixel->alpha_trait=image->alpha_trait; + pixel->depth=image->m_ndepth; + pixel->fuzz=image->fuzz; +} + +void GetPixelInfoRGBA(const unsigned char red,const unsigned char green, const unsigned char blue,const unsigned char alpha,PixelInfo *pixel) +{ + GetPixelInfo((ImagePICT *) NULL,pixel); + pixel->red=red; + pixel->green=green; + pixel->blue=blue; + pixel->alpha=alpha; +} + +unsigned char GetPixelWriteMask(const ImagePICT *image,const unsigned char *pixel) +{ + if (image->channel_map[WriteMaskPixelChannel].traits == UndefinedPixelTrait) + return((unsigned char) 255); + return(pixel[image->channel_map[WriteMaskPixelChannel].offset]); +} + +int IsValidOffset(const long long x, const size_t a) +{ + if (a == 0) + return 0; + + if ((x >= (LLONG_MAX / 64 / (long long) a)) || + (x <= ((-LLONG_MAX - 1) / 64 / (long long) a))) + return 0; + return 1; +} + +int ReadPixels(ImagePICT* image, const long long x, const long long y, const size_t width, const size_t height, unsigned char* pixels) +{ + long long + offset, + i; + + size_t + extent, + length, + number_channels, + rows; + + unsigned char + *q, + *p; + + if (IsValidOffset(y, image->m_nWidth) == 0) + return 0; + offset = y * (long long) image->m_nWidth; + + if ((offset/ (long long) image->m_nWidth) != y) + { + strcpy(image->error, "UncorrectOffset"); + + return 0; + } + + offset += x; + number_channels = image->number_channels; + length = (size_t) number_channels * width * sizeof(unsigned char); + + if ((length / number_channels / sizeof(unsigned char)) != width) + { + strcpy(image->error, "UncorrectLength"); + + return 0; + } + + rows = height; + extent = length * rows; + + if ((extent == 0) || ((extent/length) != rows)) + { + strcpy(image->error, "UncorrectExtent"); + + return 0; + } + + i = 0; + q = pixels; + + /* + Read pixels from memory. + */ + if ((image->m_nWidth == width) && + (extent == (size_t) extent)) + { + length=extent; + rows=1UL; + } + p = image->ppixels + image->number_channels * offset; + for (i=0; i < (long long) rows; i++) + { + (void) memcpy(q,p,(size_t) length); + p += image->number_channels * image->m_nWidth; + q += image->number_channels * width; + } + + if (i < rows) + { + strcpy(image->error, "Overflow"); + + return 0; + } + + return 1; +} + +unsigned char* GetPixels(ImagePICT* image, const long long x, const long long y, const size_t width, const size_t height) +{ + unsigned char + *pixels; + + pixels = image->ppixels + image->number_channels * (y * image->m_nWidth + x); + + if (pixels == (unsigned char *) NULL) + return((unsigned char *) NULL); + + if (ReadPixels(image, x, y, width, height, pixels) == 0) + { + return ((unsigned char *) NULL); + } + + return pixels; +} + +static inline float PerceptibleReciprocal(const float x) +{ + float sign = x < (float) 0.0 ? (float) -1.0 : (float) 1.0; + return((sign*x) >= 1.0e-12 ? (float) 1.0/x : sign*((float) 1.0/1.0e-12)); +} + + +unsigned char GetPixelChannel(const ImagePICT *image,const PixelChannel channel,const unsigned char *pixel) +{ + if ((size_t) channel >= 64) + return((unsigned char) 0); + if (image->channel_map[channel].traits == UndefinedPixelTrait) + return((unsigned char) 0); + return(pixel[image->channel_map[channel].offset]); +} + +unsigned char GetPixelAlpha(const ImagePICT *image,const unsigned char *pixel) +{ + if (image->channel_map[AlphaPixelChannel].traits == UndefinedPixelTrait) + return (unsigned char) 0; + return(pixel[image->channel_map[AlphaPixelChannel].offset]); +} + +void SetPixelChannel(const ImagePICT *image,const PixelChannel channel,const unsigned char Quantum,unsigned char *pixel) +{ + if ((size_t) channel >= 64) + return; + if (image->channel_map[channel].traits != UndefinedPixelTrait) + pixel[image->channel_map[channel].offset]=Quantum; +} + +PixelChannel GetPixelChannelChannel(const ImagePICT *image,const long long offset) +{ + if ((offset < 0) || (offset >= 64)) + return(UndefinedPixelChannel); + return(image->channel_map[offset].channel); +} + +PixelTrait GetPixelChannelTraits(const ImagePICT *image,const PixelChannel channel) +{ + if ((size_t) channel >= 64) + return(UndefinedPixelTrait); + return(image->channel_map[channel].traits); +} + +static inline void SetPixelIndex(const ImagePICT *image, + const unsigned char index,unsigned char *pixel) +{ + if (image->channel_map[IndexPixelChannel].traits != UndefinedPixelTrait) + pixel[image->channel_map[IndexPixelChannel].offset]=index; +} + +static inline void SetPixelAlpha(const ImagePICT *image, + const unsigned char alpha,unsigned char *pixel) +{ + if (image->channel_map[AlphaPixelChannel].traits != UndefinedPixelTrait) + pixel[image->channel_map[AlphaPixelChannel].offset]=alpha; +} + +static inline void SetPixelRed(const ImagePICT *image, + const unsigned char red,unsigned char *pixel) +{ + pixel[image->channel_map[RedPixelChannel].offset]=red; +} + +static inline void SetPixelGreen(const ImagePICT *image, + const unsigned char green,unsigned char *pixel) +{ + pixel[image->channel_map[GreenPixelChannel].offset]=green; +} + +static inline void SetPixelBlue(const ImagePICT *image, + const unsigned char blue,unsigned char *pixel) +{ + pixel[image->channel_map[BluePixelChannel].offset]=blue; +} + +int AquirePixelsMemory(ImagePICT* image) +{ + if ((image->m_nHeight == 0) || (image->m_nWidth == 0)) + { + strcpy(image->error, "PixelSizeIsNull"); + + return 0; + } + + image->m_nPixelsSize = image->m_nHeight * image->m_nWidth * image->number_channels; + + if (image->ppixels == NULL) + image->ppixels = (unsigned char*) malloc(image->m_nPixelsSize); + else + image->ppixels = (unsigned char*) realloc(image->ppixels, image->m_nPixelsSize); + + return 1; +} + +int SetImageAlpha(ImagePICT* image, const unsigned char Alpha) +{ + int + status, + y; + + if (AquirePixelsMemory(image) == 0) + return 0; + + image->alpha_trait = BlendPixelTrait; + image->channel_map[AlphaPixelChannel].traits = UpdatePixelTrait; + status = 1; + for (y = 0; y < image->m_nHeight; y++) + { + unsigned char + *q; + + int + x; + + if (status == 0) + continue; + q = image->ppixels + image->number_channels * (y * image->m_nWidth); + if (q == (unsigned char*) NULL) + { + status = 0; + continue; + } + for (x = 0; x < image->m_nWidth; x++) + { + if (GetPixelWriteMask(image, q) > (255 / 2)) + SetPixelAlpha(image, Alpha, q); + q += image->number_channels; + } + } + + return status; +} + +int AquireImageColormap(ImagePICT* image, const size_t colors) +{ + long long + i; + + if (image == (ImagePICT*) NULL) + return 0; + + if (colors > 256UL) + { + image->colors = 0; + image->storage_class = DirectClass; + strcpy(image->error, "UnableToCreateColormap"); + + return 0; + } + + if (colors > 1) + image->colors = colors; + else + image->colors = 1; + if (image->colormap == (PixelInfo*) NULL) + image->colormap = (PixelInfo*) malloc((image->colors + 1) * sizeof(*image->colormap)); + else + image->colormap = (PixelInfo*) realloc(image->colormap, (image->colors + 1) * sizeof(*image->colormap)); + + if (image->colormap == (PixelInfo*) NULL) + { + image->colors = 0; + image->storage_class = DirectClass; + strcpy(image->error, "MemoryAllocationFailed"); + + return 0; + } + + for (i = 0; i < image->colors; i++) + { + double + pixel; + + GetPixelInfo(image, image->colormap+i); + if (colors - 1 > 1) + pixel = ((double) i * (255 / (colors - 1))); + else + pixel = ((double) i * 255); + + image->colormap[i].red = pixel; + image->colormap[i].green = pixel; + image->colormap[i].blue = pixel; + image->colormap[i].alpha = 255.0; + image->colormap[i].alpha_trait = BlendPixelTrait; + } + image->storage_class=PseudoClass; + return 1; +} + +static inline int IsRGBColorspace(const ColorspaceType colorspace) +{ + if ((colorspace == RGBColorspace) || (colorspace == scRGBColorspace) || + (colorspace == LinearGRAYColorspace)) + return 1; + return 0; +} + +static inline int IssRGBColorspace( + const ColorspaceType colorspace) +{ + if ((colorspace == sRGBColorspace) || (colorspace == TransparentColorspace)) + return 1; + return 0; +} + +static inline int IsGrayColorspace( + const ColorspaceType colorspace) +{ + if ((colorspace == LinearGRAYColorspace) || (colorspace == GRAYColorspace)) + return 1; + return 0; +} + +int SetImageColorspace(ImagePICT *image, const ColorspaceType colorspace) +{ + ImageType + type; + + if (image->colorspace == colorspace) + return 1; + image->colorspace=colorspace; + image->gamma=1.000/2.200; + (void) memset(&image->chromaticity,0,sizeof(image->chromaticity)); + type=image->type; + if (IsGrayColorspace(colorspace) != 0) + { + if (colorspace == LinearGRAYColorspace) + image->gamma=1.000; + type=GrayscaleType; + } + else + if ((IsRGBColorspace(colorspace) != 0) || + (colorspace == XYZColorspace) || (colorspace == xyYColorspace)) + image->gamma=1.000; + else + { + image->chromaticity.red_primary.x=0.6400; + image->chromaticity.red_primary.y=0.3300; + image->chromaticity.red_primary.z=0.0300; + image->chromaticity.green_primary.x=0.3000; + image->chromaticity.green_primary.y=0.6000; + image->chromaticity.green_primary.z=0.1000; + image->chromaticity.blue_primary.x=0.1500; + image->chromaticity.blue_primary.y=0.0600; + image->chromaticity.blue_primary.z=0.7900; + image->chromaticity.white_point.x=0.3127; + image->chromaticity.white_point.y=0.3290; + image->chromaticity.white_point.z=0.3583; + } + if (image->ppixels == (unsigned char*) NULL) + return 0; + image->type=type; + return 1; +} + +long long CastDoubleToLong(const double x) +{ + if (floor(x) > ((double) LLONG_MAX-1)) + { + return((long long) LLONG_MAX); + } + if (ceil(x) < ((double) LLONG_MIN+1)) + { + return((long long) LLONG_MIN); + } + return((long long) x); +} + +static inline unsigned char ClampPixel(const double pixel) +{ + if (pixel < 0.0) + return ((unsigned char) 0); + if (pixel >= 255.0) + return ((unsigned char) 255); + return ((unsigned char) (pixel)); +} + +static inline unsigned char ClampToQuantum(const double pixel) +{ + if ((isnan(pixel) != 0) || (pixel <= 0.0)) + return ((unsigned char) 0); + if (pixel >= 255.0) + return (unsigned char) 255; + return ((unsigned char) (pixel)); +} + +int Clamp(double x, double min, double max) { + if (x < min) { + return min; + } else if (x > max) { + return max; + } else { + return x; + } +} + +static inline int CopyPixel(const ImagePICT *image, + const unsigned char *source,unsigned char *destination) +{ + long long + i; + + if (source == (const unsigned char *) NULL) + { + destination[RedPixelChannel]=(unsigned char) (Clamp(image->background_color.red, 0.0f, 255.0f) + 0.5f); + destination[GreenPixelChannel]=(unsigned char) (Clamp(image->background_color.green, 0.0f, 255.0f) + 0.5f); + destination[BluePixelChannel]=(unsigned char) (Clamp(image->background_color.blue, 0.0f, 255.0f) + 0.5f); + destination[BlackPixelChannel]=(unsigned char) (Clamp(image->background_color.black, 0.0f, 255.0f) + 0.5f); + destination[AlphaPixelChannel]=(unsigned char) (Clamp(image->background_color.alpha, 0.0f, 255.0f) + 0.5f); + return 0; + } + for (i=0; i < 4; i++) + { + PixelChannel channel = GetPixelChannelChannel(image,i); + destination[channel]=source[i]; + } + return 1; +} + +int GetOneVirtualPixel(ImagePICT *image,const long long x,const long long y,unsigned char *pixel) +{ + const unsigned char + *p; + + (void) memset(pixel,0,64*sizeof(*pixel)); + p = GetPixels(image, x, y, 1UL, 1UL); + return(CopyPixel(image,p,pixel)); +} + +void AquireImage(ImagePICT* image) +{ + image->storage_class = DirectClass; + image->colorspace = sRGBColorspace; + image->gamma=1.000/2.200; + image->chromaticity.red_primary.x=0.6400; + image->chromaticity.red_primary.y=0.3300; + image->chromaticity.red_primary.z=0.0300; + image->chromaticity.green_primary.x=0.3000; + image->chromaticity.green_primary.y=0.6000; + image->chromaticity.green_primary.z=0.1000; + image->chromaticity.blue_primary.x=0.1500; + image->chromaticity.blue_primary.y=0.0600; + image->chromaticity.blue_primary.z=0.7900; + image->chromaticity.white_point.x=0.3127; + image->chromaticity.white_point.y=0.3290; + image->chromaticity.white_point.z=0.3583; + image->m_pctVersion = 0; + image->m_nHeight = 0; + image->m_nWidth = 0; + image->m_ndepth = 8; + image->colors = 0; + image->profiles = NULL; + image->artifacts = NULL; + image->fuzz = 0.0; + image->resolutionX = 0.0; + image->resolutionY = 0.0; + image->type = UndefinedType; + GetPixelInfoRGBA(BackgroundColorRGBA, &image->background_color); + image->alpha_trait = UndefinedPixelTrait; + image->ppixels = NULL; + image->m_nPixelsSize = 0; + image->colormap = NULL; + image->channel_map = AcquirePixelChannelMap(); + image->mask_trait = UndefinedPixelTrait; + image->taint = 0; + image->number_channels = 4; +} + +size_t GetSize(FILE* file) +{ + long long + file_discription; + + struct stat + st; + + file_discription = fileno(file); + if (fstat(file_discription, &st) == 0) + return st.st_size; + + return(0); +} + +int Read(FILE* file, const int length, void* data) +{ + if (!file) return 0; + if (data == NULL) return 0; + unsigned char* q; + q = (unsigned char*) data; + return fread(q, 1, length, file); +} + +int ReadByte(FILE* file) +{ + return getc(file); +} + +const void *ReadBlobStream(FILE* file, const size_t length, void *data, long long* count) +{ + *count = Read(file, length, (unsigned char*) data); + return data; +} + +unsigned short ReadShortValue(FILE* file) +{ + unsigned short + value; + + unsigned char + buffer[2]; + + const unsigned char + *p; + + long long + count; + + *buffer='\0'; + + p = (const unsigned char*) ReadBlobStream(file, 2, buffer, &count); + if (count != 2) + { + return(EOF); + } + value = (unsigned short) ((*p++) << 8); + value |= (unsigned short) (*p++); + return ((unsigned short) (value & 0xffff)); +} + +signed short ReadSignedShortValue(FILE* file) +{ + union + { + unsigned short unsigned_value; + + signed short signed_value; + } Quantum; + + Quantum.unsigned_value = ReadShortValue(file); + return (Quantum.signed_value); +} + +unsigned int ReadLongValue(FILE* file) +{ + const unsigned char + *p; + + unsigned int + value; + + int + count; + unsigned char + buffer[4]; + + *buffer='\0'; + count = Read(file, 4, buffer); + + if (count != 4) + { + return(EOF); + } + + p = (const unsigned char*) buffer; + + value=(unsigned int) (*p++) << 24; + value|=(unsigned int) (*p++) << 16; + value|=(unsigned int) (*p++) << 8; + value|=(unsigned int) (*p++); + + return value; +} + +int ReadRectangle(FILE* file, PICTrectangle *frame) +{ + frame->top = (short) ReadShortValue(file); + frame->left = (short) ReadShortValue(file); + frame->bottom = (short) ReadShortValue(file); + frame->right = (short) ReadShortValue(file); + + if (feof(file) != 0) + { + return 0; + } + + if (frame->bottom < frame->top) + { + return 0; + } + + if (frame->right < frame->left) + { + return 0; + } + + return 1; +} + +int ReadPixmap(FILE* file,PICTPixmap *pixmap) +{ + pixmap->version=(short) ReadShortValue(file); + pixmap->pack_type=(short) ReadShortValue(file); + pixmap->pack_size=ReadLongValue(file); + pixmap->horizontal_resolution=1UL*ReadShortValue(file); + (void) ReadShortValue(file); + pixmap->vertical_resolution=1UL*ReadShortValue(file); + (void) ReadShortValue(file); + pixmap->pixel_type=(short) ReadShortValue(file); + pixmap->bits_per_pixel=(short) ReadShortValue(file); + pixmap->component_count=(short) ReadShortValue(file); + pixmap->component_size=(short) ReadShortValue(file); + pixmap->plane_bytes=ReadLongValue(file); + pixmap->table=ReadLongValue(file); + pixmap->reserved=ReadLongValue(file); + if ((feof(file) != 0) || (pixmap->bits_per_pixel <= 0) || + (pixmap->bits_per_pixel > 32) || (pixmap->component_count <= 0) || + (pixmap->component_count > 4) || (pixmap->component_size <= 0)) + return(0); + return(1); +} + +SplayTreeInfo *DestroySplayTree(SplayTreeInfo *splay_tree) +{ + NodeInfo + *node; + + NodeInfo + *active, + *pend; + + if (splay_tree->root != (NodeInfo *) NULL) + { + for (pend=splay_tree->root; pend != (NodeInfo *) NULL; ) + { + active=pend; + for (pend=(NodeInfo *) NULL; active != (NodeInfo *) NULL; ) + { + if (active->left != (NodeInfo *) NULL) + { + free(active->left->key); + free(active->left->value); + pend=active->left; + } + if (active->right != (NodeInfo *) NULL) + { + free(active->right->key); + free(active->right->value); + pend=active->right; + } + node=active; + active=(NodeInfo *) node->key; + free(node); + } + } + } + + free(splay_tree); + return(splay_tree); +} + +SplayTreeInfo *NewSplayTree(int (*compare)(const void *,const void *)) +{ + SplayTreeInfo + *splay_tree; + + splay_tree=(SplayTreeInfo *) malloc(sizeof(*splay_tree)); + (void) memset(splay_tree,0,sizeof(*splay_tree)); + splay_tree->root=(NodeInfo *) NULL; + splay_tree->compare=compare; + splay_tree->balance=0; + splay_tree->key=(void *) NULL; + splay_tree->next=(void *) NULL; + splay_tree->nodes=0; + splay_tree->signature=0xabacadabUL; + return(splay_tree); +} + +static inline void *GetFirstSplayTreeNode(SplayTreeInfo *splay_tree) +{ + NodeInfo + *node; + + node=splay_tree->root; + if (splay_tree->root == (NodeInfo *) NULL) + return((NodeInfo *) NULL); + while (node->left != (NodeInfo *) NULL) + node=node->left; + return(node->key); +} + +NodeInfo *Splay(SplayTreeInfo *splay_tree,const size_t depth,const void *key,NodeInfo **node,NodeInfo **parent,NodeInfo **grandparent) +{ + int + compare; + + NodeInfo + **next; + + NodeInfo + *n, + *p; + + n=(*node); + if (n == (NodeInfo *) NULL) + { + if (parent != (NodeInfo **) NULL) + return(*parent); + else + return((NodeInfo *) NULL); + } + if (splay_tree->compare != (int (*)(const void *,const void *)) NULL) + compare=splay_tree->compare(n->key,key); + else + compare=(n->key > key) ? 1 : ((n->key < key) ? -1 : 0); + next=(NodeInfo **) NULL; + if (compare > 0) + next=(&n->left); + else + if (compare < 0) + next=(&n->right); + if (next != (NodeInfo **) NULL) + { + if (depth >= 1024) + { + splay_tree->balance=1; + return(n); + } + n=Splay(splay_tree,depth+1,key,next,node,parent); + if ((n != *node) || (splay_tree->balance != 0)) + return(n); + } + if (parent == (NodeInfo **) NULL) + return(n); + if (grandparent == (NodeInfo **) NULL) + { + if (n == (*parent)->left) + { + *node=n->right; + n->right=(*parent); + } + else + { + *node=n->left; + n->left=(*parent); + } + *parent=n; + return(n); + } + if ((n == (*parent)->left) && (*parent == (*grandparent)->left)) + { + p=(*parent); + (*grandparent)->left=p->right; + p->right=(*grandparent); + p->left=n->right; + n->right=p; + *grandparent=n; + return(n); + } + if ((n == (*parent)->right) && (*parent == (*grandparent)->right)) + { + p=(*parent); + (*grandparent)->right=p->left; + p->left=(*grandparent); + p->right=n->left; + n->left=p; + *grandparent=n; + return(n); + } + if (n == (*parent)->left) + { + (*parent)->left=n->right; + n->right=(*parent); + (*grandparent)->right=n->left; + n->left=(*grandparent); + *grandparent=n; + return(n); + } + (*parent)->right=n->left; + n->left=(*parent); + (*grandparent)->left=n->right; + n->right=(*grandparent); + *grandparent=n; + return(n); +} + +int IterateOverSplayTree(SplayTreeInfo *splay_tree, + int (*method)(NodeInfo *,const void *),const void *value) +{ + typedef enum + { + LeftTransition, + RightTransition, + DownTransition, + UpTransition + } TransitionType; + + int + status; + + int + final_transition; + + NodeInfo + **nodes; + + long long + i; + + NodeInfo + *node; + + TransitionType + transition; + + unsigned char + *transitions; + + if (splay_tree->root == (NodeInfo *) NULL) + return(0); + nodes=(NodeInfo **) malloc((size_t) splay_tree->nodes*sizeof(*nodes)); + transitions=(unsigned char *) malloc((size_t) splay_tree->nodes*sizeof(*transitions)); + if ((nodes == (NodeInfo **) NULL) || (transitions == (unsigned char *) NULL)) + return 0; + status=0; + final_transition=0; + nodes[0]=splay_tree->root; + transitions[0]=(unsigned char) LeftTransition; + for (i=0; final_transition == 0; ) + { + node=nodes[i]; + transition=(TransitionType) transitions[i]; + switch (transition) + { + case LeftTransition: + { + transitions[i]=(unsigned char) DownTransition; + if (node->left == (NodeInfo *) NULL) + break; + i++; + nodes[i]=node->left; + transitions[i]=(unsigned char) LeftTransition; + break; + } + case RightTransition: + { + transitions[i]=(unsigned char) UpTransition; + if (node->right == (NodeInfo *) NULL) + break; + i++; + nodes[i]=node->right; + transitions[i]=(unsigned char) LeftTransition; + break; + } + case DownTransition: + default: + { + transitions[i]=(unsigned char) RightTransition; + status=(*method)(node,value); + if (status != 0) + final_transition=1; + break; + } + case UpTransition: + { + if (i == 0) + { + final_transition=1; + break; + } + i--; + break; + } + } + } + free(nodes); + free(transitions); + return(status); +} + +NodeInfo *LinkSplayTreeNodes(NodeInfo **nodes,const size_t low,const size_t high) +{ + NodeInfo + *node; + + size_t + bisect; + + bisect=low+(high-low)/2; + node=nodes[bisect]; + if ((low+1) > bisect) + node->left=(NodeInfo *) NULL; + else + node->left=LinkSplayTreeNodes(nodes,low,bisect-1); + if ((bisect+1) > high) + node->right=(NodeInfo *) NULL; + else + node->right=LinkSplayTreeNodes(nodes,bisect+1,high); + return(node); +} + +inline int SplayTreeToNodeArray(NodeInfo *node,const void *nodes) +{ + const NodeInfo + ***p; + + p=(const NodeInfo ***) nodes; + *(*p)=node; + (*p)++; + return(0); +} + +void BalanceSplayTree(SplayTreeInfo *splay_tree) +{ + NodeInfo + **node, + **nodes; + + if (splay_tree->nodes <= 2) + { + splay_tree->balance=0; + return; + } + nodes=(NodeInfo **) malloc((size_t) splay_tree->nodes*sizeof(*nodes)); + if (nodes == (NodeInfo **) NULL) + return; + node=nodes; + (void) IterateOverSplayTree(splay_tree,SplayTreeToNodeArray,(const void *) + &node); + splay_tree->root=LinkSplayTreeNodes(nodes,0,splay_tree->nodes-1); + splay_tree->balance=0; + free(nodes); +} + +void SplaySplayTree(SplayTreeInfo *splay_tree,const void *key) +{ + if (splay_tree->root == (NodeInfo *) NULL) + return; + if (splay_tree->key != (void *) NULL) + { + int + compare; + + if (splay_tree->compare != (int (*)(const void *,const void *)) NULL) + compare=splay_tree->compare(splay_tree->root->key,key); + else + compare=(splay_tree->key > key) ? 1 : + ((splay_tree->key < key) ? -1 : 0); + if (compare == 0) + return; + } + (void) Splay(splay_tree,0UL,key,&splay_tree->root,(NodeInfo **) NULL, + (NodeInfo **) NULL); + if (splay_tree->balance != 0) + { + BalanceSplayTree(splay_tree); + (void) Splay(splay_tree,0UL,key,&splay_tree->root,(NodeInfo **) NULL, + (NodeInfo **) NULL); + if (splay_tree->balance != 0) + return; + } + splay_tree->key=(void *) key; +} + +int AddValueToSplayTree(SplayTreeInfo *splay_tree,const void *key,const void *value) +{ + int + compare; + + NodeInfo + *node; + + SplaySplayTree(splay_tree,key); + compare=0; + if (splay_tree->root != (NodeInfo *) NULL) + { + if (splay_tree->compare != (int (*)(const void *,const void *)) NULL) + compare=splay_tree->compare(splay_tree->root->key,key); + else + compare=(splay_tree->root->key > key) ? 1 : + ((splay_tree->root->key < key) ? -1 : 0); + if (compare == 0) + { + splay_tree->root->key=(void *) key; + splay_tree->root->value=(void *) value; + return(1); + } + } + node=(NodeInfo *) malloc(sizeof(*node)); + if (node == (NodeInfo *) NULL) + return(0); + node->key=(void *) key; + node->value=(void *) value; + if (splay_tree->root == (NodeInfo *) NULL) + { + node->left=(NodeInfo *) NULL; + node->right=(NodeInfo *) NULL; + } + else + if (compare < 0) + { + node->left=splay_tree->root; + node->right=node->left->right; + node->left->right=(NodeInfo *) NULL; + } + else + { + node->right=splay_tree->root; + node->left=node->right->left; + node->right->left=(NodeInfo *) NULL; + } + splay_tree->root=node; + splay_tree->key=(void *) NULL; + splay_tree->nodes++; + return(1); +} + +SplayTreeInfo *CloneSplayTree(SplayTreeInfo *splay_tree, void *(*clone_key)(void *),void *(*clone_value)(void *)) +{ + NodeInfo + *next, + *node; + + SplayTreeInfo + *clone_tree; + + clone_tree=NewSplayTree(splay_tree->compare); + if (splay_tree->root == (NodeInfo *) NULL) + { + return(clone_tree); + } + next=(NodeInfo *) GetFirstSplayTreeNode(splay_tree); + while (next != (NodeInfo *) NULL) + { + SplaySplayTree(splay_tree,next); + (void) AddValueToSplayTree(clone_tree,clone_key(splay_tree->root->key), + clone_value(splay_tree->root->value)); + next=(NodeInfo *) NULL; + node=splay_tree->root->right; + if (node != (NodeInfo *) NULL) + { + while (node->left != (NodeInfo *) NULL) + node=node->left; + next=(NodeInfo *) node->key; + } + } + return(clone_tree); +} + +int CompareSplayTreeString(const void *target,const void *source) +{ + const char + *p, + *q; + + p=(const char *) target; + q=(const char *) source; + return(LocaleCompare(p,q)); +} + +const void *GetValueFromSplayTree(SplayTreeInfo *splay_tree, const void *key) +{ + int + compare; + + void + *value; + + if (splay_tree->root == (NodeInfo *) NULL) + return((void *) NULL); + + SplaySplayTree(splay_tree,key); + if (splay_tree->compare != (int (*)(const void *,const void *)) NULL) + compare=splay_tree->compare(splay_tree->root->key,key); + else + compare=(splay_tree->root->key > key) ? 1 : + ((splay_tree->root->key < key) ? -1 : 0); + if (compare != 0) + return((void *) NULL); + value=splay_tree->root->value; + return(value); +} + +const void *GetRootValueFromSplayTree(SplayTreeInfo *splay_tree) +{ + const void + *value; + + value=(const void *) NULL; + if (splay_tree->root != (NodeInfo *) NULL) + value=splay_tree->root->value; + + return(value); +} + +const unsigned char *ReadResourceShort(const unsigned char *p, unsigned short *Quantum) +{ + *Quantum=(unsigned short) (*p++) << 8; + *Quantum|=(unsigned short) (*p++); + return(p); +} + +const unsigned char *ReadResourceByte(const unsigned char *p, unsigned char *Quantum) +{ + *Quantum=(*p++); + return(p); +} + +const unsigned char *ReadResourceLong(const unsigned char *p, unsigned int *Quantum) +{ + *Quantum=(unsigned int) (*p++) << 24; + *Quantum|=(unsigned int) (*p++) << 16; + *Quantum|=(unsigned int) (*p++) << 8; + *Quantum|=(unsigned int) (*p++); + return(p); +} + +void WriteResourceLong(unsigned char *p, + const unsigned int Quantum) +{ + unsigned char + buffer[4]; + + buffer[0]=(unsigned char) (Quantum >> 24); + buffer[1]=(unsigned char) (Quantum >> 16); + buffer[2]=(unsigned char) (Quantum >> 8); + buffer[3]=(unsigned char) Quantum; + (void) memcpy(p,buffer,4); +} + +void WriteTo8BimProfile(ImagePICT *image,const char *name, const StringInfo *profile) +{ + const unsigned char + *datum, + *q; + + const unsigned char + *p; + + size_t + length; + + StringInfo + *profile_8bim; + + long long + count; + + unsigned char + length_byte; + + unsigned int + value; + + unsigned short + id, + profile_id; + + if (LocaleCompare(name,"icc") == 0) + profile_id=0x040f; + else + if (LocaleCompare(name,"iptc") == 0) + profile_id=0x0404; + else + if (LocaleCompare(name,"xmp") == 0) + profile_id=0x0424; + else + return; + profile_8bim=(StringInfo *) GetValueFromSplayTree((SplayTreeInfo *) image->profiles,"8bim"); + if (profile_8bim == (StringInfo *) NULL) + return; + datum=profile_8bim->datum; + length=profile_8bim->length; + for (p=datum; p < (datum+length-16); ) + { + q=p; + if (LocaleNCompare((char *) p,"8BIM",4) != 0) + break; + p+=4; + p=ReadResourceShort(p,&id); + p=ReadResourceByte(p,&length_byte); + p+=length_byte; + if (((length_byte+1) & 0x01) != 0) + p++; + if (p > (datum+length-4)) + break; + p=ReadResourceLong(p,&value); + count=(long long) value; + if ((count & 0x01) != 0) + count++; + if ((count < 0) || (p > (datum+length-count)) || (count > (long long) length)) + break; + if (id != profile_id) + p+=count; + else + { + size_t + extent, + offset; + + long long + extract_extent; + + StringInfo + *extract_profile; + + extract_extent=0; + extent=(size_t) ((datum+length)-(p+count)); + if (profile == (StringInfo *) NULL) + { + offset=(size_t) (q-datum); + extract_profile=AcquireStringInfo(offset+extent); + (void) memcpy(extract_profile->datum,datum,offset); + } + else + { + offset=(size_t) (p-datum); + extract_extent=(long long) profile->length; + if ((extract_extent & 0x01) != 0) + extract_extent++; + extract_profile=AcquireStringInfo(offset+(size_t) extract_extent+ + extent); + (void) memcpy(extract_profile->datum,datum,offset-4); + WriteResourceLong(extract_profile->datum+offset-4,(unsigned int) + profile->length); + (void) memcpy(extract_profile->datum+offset, + profile->datum,profile->length); + } + (void) memcpy(extract_profile->datum+offset+extract_extent, + p+count,extent); + (void) AddValueToSplayTree((SplayTreeInfo *) image->profiles, ConstantString("8bim"),CloneStringInfo(extract_profile)); + extract_profile=DestroyStringInfo(extract_profile); + break; + } + } +} + +int SetImageProfileInternal(ImagePICT *image,const char *name,const StringInfo *profile,const int recursive) +{ + char + key[4096]; + + int + status; + + StringInfo + *clone_profile; + + clone_profile=CloneStringInfo(profile); + if (image->profiles == (SplayTreeInfo *) NULL) + image->profiles=NewSplayTree(CompareSplayTreeString); + (void) CopyMagickString(key,name,4096); + LocaleLower(key); + status=AddValueToSplayTree((SplayTreeInfo *) image->profiles,ConstantString(key),clone_profile); + if (status != 0) + { + WriteTo8BimProfile(image,name,clone_profile); + } + return(status); +} + +const char *GetImageArtifact(const ImagePICT *image,const char *artifact) +{ + const char + *p; + + p=(const char *) NULL; + if (image->artifacts != (void *) NULL) + { + if (artifact == (const char *) NULL) + return((const char *) GetRootValueFromSplayTree((SplayTreeInfo *) + image->artifacts)); + p=(const char *) GetValueFromSplayTree((SplayTreeInfo *) image->artifacts, + artifact); + if (p != (const char *) NULL) + return(p); + } + + return(p); +} + +ImagePICT *DestroyImage(ImagePICT *image) +{ + /* + Destroy image. + */ + free(image->ppixels); + free(image->channel_map); + delete image; + return(ImagePICT *) NULL; +} + +ImagePICT* CloneImage(const ImagePICT* image, const size_t colums, const size_t rows) +{ + if (image == (const ImagePICT*) NULL) + { + return((ImagePICT*) NULL); + } + + ImagePICT* clone_image = new ImagePICT; + + AquireImage(clone_image); + + clone_image->storage_class = image->storage_class; + clone_image->fuzz = image->fuzz; + clone_image->colorspace = image->colorspace; + clone_image->chromaticity.blue_primary = image->chromaticity.blue_primary; + clone_image->chromaticity.green_primary = image->chromaticity.green_primary; + clone_image->chromaticity.red_primary = image->chromaticity.red_primary; + clone_image->chromaticity.white_point = image->chromaticity.white_point; + clone_image->gamma = image->gamma; + clone_image->m_nHeight = image->m_nHeight; + if (rows != 0) + clone_image->m_nHeight = rows; + clone_image->m_nWidth = image->m_nWidth; + if (colums != 0) + clone_image->m_nWidth = colums; + clone_image->number_channels = image->number_channels; + clone_image->m_nPixelsSize = image->m_nPixelsSize; + clone_image->ppixels = NULL; + clone_image->resolutionX = image->resolutionX; + clone_image->resolutionY = image->resolutionY; + clone_image->alpha_trait = image->alpha_trait; + clone_image->background_color.blue = image->background_color.blue; + clone_image->background_color.green = image->background_color.green; + clone_image->background_color.red = image->background_color.red; + + clone_image->colors = image->colors; + if (image->colormap != NULL) + { + clone_image->colormap = (PixelInfo*) malloc((clone_image->colors + 1) * sizeof(*clone_image->colormap)); + memcpy(clone_image->colormap, image->colormap, clone_image->colors * sizeof(*clone_image->colormap)); + } + if (image->channel_map != NULL) + { + clone_image->channel_map = (PixelChannelMap*) malloc(65 * sizeof (image->channel_map)); + memcpy(clone_image->channel_map, image->channel_map, 65 * sizeof (image->channel_map)); + } + + if (image->profiles != NULL) + clone_image->profiles = CloneSplayTree(image->profiles, (void *(*)(void *)) ConstantString,(void *(*)(void *)) CloneStringInfo); + if (image->artifacts != NULL) + clone_image->artifacts = CloneSplayTree(image->artifacts, (void *(*)(void *)) ConstantString,(void *(*)(void *)) CloneStringInfo); + + clone_image->mask_trait = image->mask_trait; + clone_image->taint = image->taint; + + return clone_image; +} + +static inline unsigned char GetPixelReadMask(const ImagePICT *image, + const unsigned char *pixel) +{ + if (image->channel_map[ReadMaskPixelChannel].traits == UndefinedPixelTrait) + return((unsigned char) 255); + return(pixel[image->channel_map[ReadMaskPixelChannel].offset]); +} + +int CompositeImage(ImagePICT *image, const ImagePICT *composite, const int clip_to_self,const long long x_offset,const long long y_offset) +{ +#define CompositeImageTag "Composite/Image" + + const char + *value; + + GeometryInfo + geometry_info; + + ImagePICT + *canvas_image, + *source_image; + + int + clamp, + compose_sync, + status; + + long long + progress; + + double + amount, + canvas_dissolve, + midpoint, + percent_luma, + percent_chroma, + source_dissolve, + threshold; + + long long + y; + + image->storage_class = DirectClass; + + if (image->ppixels == (unsigned char*) NULL) + return 0; + source_image=CloneImage(composite,0,0); + if (!AquirePixelsMemory(source_image)) + return 0; + (void) memcpy(source_image->ppixels, composite->ppixels, source_image->m_nPixelsSize); + if (source_image == (const ImagePICT *) NULL) + return 0; + (void) SetImageColorspace(source_image,image->colorspace); + amount = 0.5; + canvas_image = (ImagePICT *) NULL; + canvas_dissolve = 1.0; + clamp = 1; + value = GetImageArtifact(image,"compose:clamp"); + if (value != (const char *) NULL) + clamp=IsStringTrue(value); + compose_sync = 1; + value = GetImageArtifact(image,"compose:sync"); + if (value != (const char *) NULL) + compose_sync = IsStringTrue(value); + (void) memset(&geometry_info,0,sizeof(geometry_info)); + percent_luma=100.0; + percent_chroma=100.0; + source_dissolve=1.0; + threshold=0.05f; + + image->channel_map[RedPixelChannel].traits = UpdatePixelTrait; + image->channel_map[GreenPixelChannel].traits = UpdatePixelTrait; + image->channel_map[BluePixelChannel].traits = UpdatePixelTrait; + image->channel_map[AlphaPixelChannel].traits = UpdatePixelTrait; + + source_image->channel_map[RedPixelChannel].traits = CopyPixelTrait; + source_image->channel_map[GreenPixelChannel].traits = CopyPixelTrait; + source_image->channel_map[BluePixelChannel].traits = CopyPixelTrait; + source_image->channel_map[AlphaPixelChannel].traits = CopyPixelTrait; + + if (!((x_offset < 0) || (y_offset < 0)) && !((x_offset+(long long) source_image->m_nWidth) > (long long) image->m_nWidth) && !((y_offset+(long long) source_image->m_nHeight) > (long long) image->m_nHeight)) + { + if ((source_image->alpha_trait == UndefinedPixelTrait) && + (image->alpha_trait != UndefinedPixelTrait)) + (void) SetImageAlpha(source_image, (const unsigned char) 255); + status = 1; + + for (y=0; y < (long long) source_image->m_nHeight; y++) + { + const unsigned char + *p; + + unsigned char + *q; + + long long + x; + + if (status == 0) + continue; + p=GetPixels(source_image,0,y,source_image->m_nWidth,1); + q=GetPixels(image,x_offset,y+y_offset, source_image->m_nWidth,1); + if ((p == (const unsigned char *) NULL) || (q == (unsigned char *) NULL)) + { + status=0; + continue; + } + for (x=0; x < (long long) source_image->m_nWidth; x++) + { + long long + i; + if (GetPixelReadMask(source_image, p) <= (255/2)) + { + p+=source_image->number_channels; + q+=image->number_channels; + continue; + } + for (i=0; i < source_image->number_channels; i++) + { + PixelChannel channel = GetPixelChannelChannel(source_image,i); + PixelTrait source_traits = GetPixelChannelTraits(source_image, + channel); + PixelTrait traits = GetPixelChannelTraits(image,channel); + if ((source_traits == UndefinedPixelTrait) || + (traits == UndefinedPixelTrait)) + continue; + SetPixelChannel(image,channel,p[i],q); + } + p+=source_image->number_channels; + q+=image->number_channels; + } + } + source_image=DestroyImage(source_image); + return(status); + } + + /* + Composite image. + */ + + status=1; + progress=0; + midpoint=128.0; + for (y=0; y < (long long) image->m_nHeight; y++) + { + const unsigned char + *pixels; + + PixelInfo + canvas_pixel, + source_pixel; + + const unsigned char + *p; + + unsigned char + *q; + + long long + x; + + if (status == 0) + continue; + if (clip_to_self != 0) + { + if (y < y_offset) + continue; + if ((y-(double) y_offset) >= (double) source_image->m_nHeight) + continue; + } + /* + If pixels is NULL, y is outside overlay region. + */ + pixels=(unsigned char *) NULL; + p=(unsigned char *) NULL; + if ((y >= y_offset) && + ((y-(double) y_offset) < (double) source_image->m_nHeight)) + { + p=GetPixels(source_image,0,y-y_offset,source_image->m_nWidth,1); + if (p == (const unsigned char *) NULL) + { + status=0; + continue; + } + pixels=p; + if (x_offset < 0) + p-=x_offset*source_image->number_channels; + } + q=GetPixels(image,0,y,image->m_nWidth,1); + if (q == (unsigned char *) NULL) + { + status=0; + continue; + } + GetPixelInfo(image,&canvas_pixel); + GetPixelInfo(source_image,&source_pixel); + for (x=0; x < (long long) image->m_nWidth; x++) + { + double + gamma = 0.0; + + double + alpha = 0.0, + Da = 0.0, + Dc = 0.0, + Dca = 0.0, + DcaDa = 0.0, + Sa = 0.0, + SaSca = 0.0, + Sc = 0.0, + Sca = 0.0; + + size_t + channels; + + long long + i; + + if (clip_to_self != 0) + { + if (x < x_offset) + { + q+=image->number_channels; + continue; + } + if ((x-(double) x_offset) >= (double) source_image->m_nWidth) + break; + } + if ((pixels == (unsigned char *) NULL) || (x < x_offset) || + ((x-(double) x_offset) >= (double) source_image->m_nWidth)) + { + unsigned char + source[64]; + + /* + Virtual composite: + Sc: source color. + Dc: canvas color. + */ + for (i=0; i < image->number_channels; i++) + { + double + pixel = 0; + + PixelChannel channel = GetPixelChannelChannel(image,i); + PixelTrait traits = GetPixelChannelTraits(image,channel); + PixelTrait source_traits = GetPixelChannelTraits(source_image, + channel); + if ((traits == UndefinedPixelTrait) || + (source_traits == UndefinedPixelTrait)) + continue; +////////////////////////////////////////////////////////////////////////// + if (channel == AlphaPixelChannel) + pixel = TransparentAlpha; + else + pixel=0; +///////////////////////////////////////////////////////////////////////// + q[i]=clamp != 0 ? ClampPixel(pixel) : + ClampToQuantum(pixel); + } + q+=image->number_channels; + continue; + } + /* + Authentic composite: + Sa: normalized source alpha. + Da: normalized canvas alpha. + */ + Sa = (1.0/255.0)* GetPixelAlpha(source_image,p); + Sa = Sa == 0 ? 1 : Sa; + Da = (1.0/255.0)* GetPixelAlpha(image,q); +/////////////////////////////////////////////////////////////////////// + alpha = 1.0; +////////////////////////////////////////////////////////////////////// + for (i=0; i < image->number_channels; i++) + { + double + pixel = 0.0; + + PixelChannel channel = GetPixelChannelChannel(image,i); + PixelTrait traits = GetPixelChannelTraits(image,channel); + PixelTrait source_traits = GetPixelChannelTraits(source_image,channel); + if (traits == UndefinedPixelTrait) + continue; + if ((channel == AlphaPixelChannel) && + ((traits & UpdatePixelTrait) != 0)) + { + /* + Set alpha channel. + */ +///////////////////////////////////////////////////////////////////// + pixel=255.0*Sa; +//////////////////////////////////////////////////////////////////// + q[i]=clamp != 0 ? ClampPixel(pixel) : + ClampToQuantum(pixel); + continue; + } + if (source_traits == UndefinedPixelTrait) + continue; + /* + Sc: source color. + Dc: canvas color. + */ + Sc= GetPixelChannel(source_image,channel,p); + Dc=q[i]; + if ((traits & CopyPixelTrait) != 0) + { + /* + Copy channel. + */ + q[i]=ClampToQuantum(Dc); + continue; + } + /* + Porter-Duff compositions: + Sca: source normalized color multiplied by alpha. + Dca: normalized canvas color multiplied by alpha. + */ + Sca=(1.0/255.0)*Sa*Sc; + Dca=(1.0/255.0)*Da*Dc; + SaSca=Sa*PerceptibleReciprocal(Sca); + DcaDa=Dca*PerceptibleReciprocal(Da); +///////////////////////////////////////////////////////////////////// + gamma=PerceptibleReciprocal(alpha); +//////////////////////////////////////////////////////////////////// + pixel=Dc; +/////////////////////////////////////////////////////////////////// + pixel=255.0*Sca; +////////////////////////////////////////////////////////////////// + q[i]=clamp != 0 ? ClampPixel(pixel) : + ClampToQuantum(pixel); + } + p+=source_image->number_channels; + channels=source_image->number_channels; + if (p >= (pixels+channels*source_image->m_nWidth)) + p=pixels; + q+=image->number_channels; + } + } + if (canvas_image != (ImagePICT * ) NULL) + canvas_image=DestroyImage(canvas_image); + else + source_image=DestroyImage(source_image); + return(status); +} + +int DecodeHeader(FILE* hFile, ImagePICT* image) +{ + unsigned char + header[4]; + + unsigned char + skip[1]; + + int + c; + + PICTrectangle + frame; + + Read(hFile, 4, header); + + if (!((header[0] == 0x50) && (header[1] == 0x49) && + (header[2] == 0x43) && (header[3] == 0x54 ))) + { + + frame.top =(short) ((header[2] << 8) | header[3]); + frame.left = (short) ReadShortValue(hFile); + frame.bottom = (short) ReadShortValue(hFile); + frame.right = (short) ReadShortValue(hFile); + + Read(hFile, 1, skip); + c = ReadByte(hFile); + if (c != 0x11) + { + fseek(hFile, 512, 0); + + (void) ReadShortValue(hFile); + + if (ReadRectangle(hFile, &frame) == 0) + { + strcpy(image->error, "ImproperImageHeader"); + + return 0; + } + + Read(hFile, 1, skip); + c = ReadByte(hFile); + + if (c == 0x11) + { + long long version = ReadByte(hFile); + + if (version == 2) + { + long long version2 = ReadByte(hFile); + if (version2 != 0xff) + return 0; + image->m_pctVersion = 2; + if ((frame.left < 0) || (frame.right < 0) || (frame.top < 0) || + (frame.bottom < 0) || (frame.left >= frame.right) || + (frame.top >= frame.bottom)) + { + strcpy(image->error, "ImproperImageHeader"); + + return 0; + } + image->m_nWidth=(size_t) (frame.right-frame.left); + image->m_nHeight=(size_t) (frame.bottom-frame.top); + + return 1; + } + else if (version == 1) + { + image->m_pctVersion = 1; + if ((frame.left < 0) || (frame.right < 0) || (frame.top < 0) || + (frame.bottom < 0) || (frame.left >= frame.right) || + (frame.top >= frame.bottom)) + { + strcpy(image->error, "ImproperImageHeader"); + + return 0; + } + image->m_nWidth=(size_t) (frame.right-frame.left); + image->m_nHeight=(size_t) (frame.bottom-frame.top); + + return 1; + } + else + { + strcpy(image->error, "ImproperImageHeader"); + + return 0; + } + } + else + { + strcpy(image->error, "ImproperImageHeader"); + + return 0; + } + } + } + + long long version = ReadByte(hFile); + + if (version == 2) + { + long long version2 = ReadByte(hFile); + if (version2 != 0xff) + return 0; + image->m_pctVersion = 2; + + if ((frame.left < 0) || (frame.right < 0) || (frame.top < 0) || + (frame.bottom < 0) || (frame.left >= frame.right) || + (frame.top >= frame.bottom)) + { + strcpy(image->error, "ImproperImageHeader"); + + return 0; + } + + image->m_nWidth = (size_t) (frame.right - frame.left); + image->m_nHeight=(size_t) (frame.bottom-frame.top); + } + else + { + image->m_pctVersion = 1; + + image->m_nWidth = (size_t) (frame.right - frame.left); + image->m_nHeight=(size_t) (frame.bottom-frame.top); + } + + return 1; +} + +static const unsigned char *UnpackScanline( + const unsigned char *pixels,const unsigned int bits_per_pixel, + unsigned char* scanline,size_t *bytes_per_line) +{ + const unsigned char + *p; + + long long + i; + + unsigned char + *q; + + p=pixels; + q=scanline; + switch (bits_per_pixel) + { + case 8: + case 16: + case 32: + return(pixels); + case 4: + { + for (i=0; i < (long long) *bytes_per_line; i++) + { + *q++=(*p >> 4) & 0xff; + *q++=(*p & 15); + p++; + } + *bytes_per_line*=2; + break; + } + case 2: + { + for (i=0; i < (long long) *bytes_per_line; i++) + { + *q++=(*p >> 6) & 0x03; + *q++=(*p >> 4) & 0x03; + *q++=(*p >> 2) & 0x03; + *q++=(*p & 3); + p++; + } + *bytes_per_line*=4; + break; + } + case 1: + { + for (i=0; i < (long long) *bytes_per_line; i++) + { + *q++=(*p >> 7) & 0x01; + *q++=(*p >> 6) & 0x01; + *q++=(*p >> 5) & 0x01; + *q++=(*p >> 4) & 0x01; + *q++=(*p >> 3) & 0x01; + *q++=(*p >> 2) & 0x01; + *q++=(*p >> 1) & 0x01; + *q++=(*p & 0x01); + p++; + } + *bytes_per_line*=8; + break; + } + default: + break; + } + return(scanline); +} + +static unsigned char *DecodeImage(FILE *blob,ImagePICT *image, + size_t bytes_per_line,const unsigned int bits_per_pixel,size_t *extent) +{ + int + status; + + size_t + number_pixels; + + const unsigned char + *p; + + long long + i; + + unsigned char + *q; + + size_t + bytes_per_pixel, + length, + row_bytes, + scanline_length, + width; + + long long + count, + j, + y; + + unsigned char + *pixels, + *scanline, + unpack_buffer[8*256]; + + /* + Determine pixel buffer size. + */ + if (bits_per_pixel <= 8) + bytes_per_line&=0x7fff; + width=image->m_nWidth; + bytes_per_pixel=1; + if (bits_per_pixel == 16) + { + bytes_per_pixel=2; + width*=2; + } + else + if (bits_per_pixel == 32) + width*=image->alpha_trait ? 4 : 3; + if (bytes_per_line == 0) + bytes_per_line=width; + row_bytes=(size_t) (image->m_nWidth | 0x8000); + if (image->storage_class == DirectClass) + row_bytes=(size_t) ((4*image->m_nWidth) | 0x8000); + /* + Allocate pixel and scanline buffer. + */ + pixels=(unsigned char *) malloc(image->m_nHeight*row_bytes* + sizeof(*pixels)); + if (pixels == (unsigned char *) NULL) + return((unsigned char *) NULL); + *extent=row_bytes*image->m_nHeight*sizeof(*pixels); + (void) memset(pixels,0,*extent); + scanline=(unsigned char *) malloc(row_bytes*2* + sizeof(*scanline)); + if (scanline == (unsigned char *) NULL) + { + free(pixels); + return((unsigned char *) NULL); + } + (void) memset(scanline,0,2*row_bytes*sizeof(*scanline)); + (void) memset(unpack_buffer,0,sizeof(unpack_buffer)); + status=1; + if (bytes_per_line < 8) + { + /* + Pixels are already uncompressed. + */ + for (y=0; y < (long long) image->m_nHeight; y++) + { + q=pixels+y*(long long) width*image->number_channels; + number_pixels=bytes_per_line; + count=Read(blob,(size_t) number_pixels,scanline); + if (count != (long long) number_pixels) + { + status=0; + break; + } + p=UnpackScanline(scanline,bits_per_pixel,unpack_buffer,&number_pixels); + if ((q+number_pixels) > (pixels+(*extent))) + { + status=0; + break; + } + (void) memcpy(q,p,(size_t) number_pixels); + } + free(scanline); + if (status == 0) + free(pixels); + return(pixels); + } + /* + Uncompress RLE pixels into uncompressed pixel buffer. + */ + for (y=0; y < (long long) image->m_nHeight; y++) + { + q=pixels+y*(long long) width; + if (bytes_per_line > 250) + scanline_length=ReadShortValue(blob); + else + scanline_length=(size_t) ReadByte(blob); + if ((scanline_length >= row_bytes) || (scanline_length == 0)) + { + status=0; + break; + } + count=Read(blob,scanline_length,scanline); + if (count != (long long) scanline_length) + { + status=0; + break; + } + for (j=0; j < (long long) scanline_length; ) + if ((scanline[j] & 0x80) == 0) + { + length=(size_t) ((scanline[j] & 0xff)+1); + number_pixels=length*bytes_per_pixel; + p=UnpackScanline(scanline+j+1,bits_per_pixel,unpack_buffer, + &number_pixels); + if ((size_t) (q-pixels+(long long) number_pixels) <= *extent) + (void) memcpy(q,p,(size_t) number_pixels); + q+=number_pixels; + j+=(long long) (length*bytes_per_pixel+1); + } + else + { + length=(size_t) (((scanline[j] ^ 0xff) & 0xff)+2); + number_pixels=bytes_per_pixel; + p=UnpackScanline(scanline+j+1,bits_per_pixel,unpack_buffer, + &number_pixels); + for (i=0; i < (long long) length; i++) + { + if ((size_t) (q-pixels+(long long) number_pixels) <= *extent) + (void) memcpy(q,p,(size_t) number_pixels); + q+=number_pixels; + } + j+=(long long) bytes_per_pixel+1; + } + } + free(scanline); + if (status == 0) + { + free(pixels); + pixels = NULL; + } + return(pixels); +} + +int DecodePICT(FILE* hFile, ImagePICT* image) +{ + long long + flags, + i, + j, + count, + x, + y; + int + jpeg, + code, + status; + + size_t + extent, + length; + + unsigned char + index; + + unsigned char + *q; + + PICTrectangle + frame; + + PICTPixmap + pixmap; + + ImagePICT* + tile_image; + + StringInfo + *profile; + + if (hFile == NULL) + { + strcpy(image->error, "FileError"); + + return 0; + } + + pixmap.bits_per_pixel=0; + pixmap.component_count=0; + + if (!DecodeHeader(hFile, image)) + { + return 0; + } + + if (feof(hFile) != 0) + { + strcpy(image->error, "EOFfile"); + + return 0; + } + + + flags = 0; + image->m_ndepth = 8; + image->resolutionX = 72.0; + image->resolutionY = 72.0; + + if (!AquirePixelsMemory(image)) + { + return 0; + } + + jpeg = 0; + for (code = 0; feof(hFile) == 0; ) + { + if ((image->m_pctVersion == 1) || ((ftell(hFile) % 2) != 0)) + code = ReadByte(hFile); + if (image->m_pctVersion == 2) + code = ReadSignedShortValue(hFile); + code &= 0xffff; + if (code < 0) + break; + if (code == 0) + continue; + if (code <= 0xa1) + { + switch(code) + { + case 0x01: + { + /* + Clipping rectangle. + */ + length = ReadShortValue(hFile); + if (length > GetSize(hFile)) + { + strcpy(image->error, "InsufficientImageDataInFile"); + + return 0; + } + + if (length != 0x000a) + { + for (i = 0; i < length - 2; i++) + if (ReadByte(hFile) == EOF) + break; + break; + } + if (ReadRectangle(hFile, &frame) == 0) + return 0; + if (((frame.left & 0x8000) != 0) || ((frame.top & 0x8000) != 0)) + break; + image->m_nHeight = (size_t) (frame.bottom - frame.top); + image->m_nWidth = (size_t) (frame.right - frame.left); + + if (!AquirePixelsMemory(image)) + { + return 0; + } + break; + } + case 0x12: + case 0x13: + case 0x14: + { + int + pattern; + + size_t + height, + width; + + /* + Skip pattern definition. + */ + pattern = (int) ReadShortValue(hFile); + for (i = 0; i < 8; i++) + if (ReadByte(hFile) == EOF) + break; + if (pattern == 2) + { + for (i=0; i < 5; i++) + if (ReadByte(hFile) == EOF) + break; + break; + } + if (pattern != 1) + { + DeletePixelsMemory(image); + + strcpy(image->error, "UnknownPatternType"); + + return 0; + } + + length = ReadShortValue(hFile); + if (length > GetSize(hFile)) + { + DeletePixelsMemory(image); + + strcpy(image->error, "InsufficientImageDataInFile"); + + return 0; + } + if (ReadRectangle(hFile, &frame) == 0) + { + DeletePixelsMemory(image); + + strcpy(image->error, "ImproperImageHeader"); + + return 0; + } + if (ReadPixmap(hFile, &pixmap) == 0) + { + DeletePixelsMemory(image); + + strcpy(image->error, "ImproperImageHeader"); + + return 0; + } + + image->m_ndepth = (size_t) pixmap.component_size; + image->resolutionX = 1.0 * pixmap.horizontal_resolution; + image->resolutionY = 1.0 * pixmap.vertical_resolution; + + (void) ReadLongValue(hFile); + flags=(long long) ReadShortValue(hFile); + length=ReadShortValue(hFile); + + if (length > GetSize(hFile)) + { + DeletePixelsMemory(image); + strcpy(image->error, "InsufficientImageDataInFile"); + + return 0; + } + + for (i = 0; i < length; i++) + (void) ReadLongValue(hFile); + width=(size_t) (frame.bottom-frame.top); + height=(size_t) (frame.right-frame.left); + + if (pixmap.bits_per_pixel <= 8) + length &= 0x7fff; + if (pixmap.bits_per_pixel == 16) + width <<= 1; + if (length == 0) + length = width; + if (length < 8) + { + for (i = 0; i < (length*height); i++) + if (ReadByte(hFile) == EOF) + break; + } + else + for (i = 0; i < height; i++) + { + size_t + scanline_length; + + if (feof(hFile) != 0) + break; + if (length > 200) + scanline_length=ReadShortValue(hFile); + else + scanline_length=(size_t) ReadByte(hFile); + if (scanline_length > GetSize(hFile)) + { + DeletePixelsMemory(image); + + strcpy(image->error, "InsufficientImageDataInFile"); + + return 0; + } + for (j=0; j < scanline_length; j++) + if (ReadByte(hFile) == EOF) + break; + } + break; + } + case 0x1b: + { + /* + Initialize image background color. + */ + image->background_color.red = 257.0 * ReadShortValue(hFile); + image->background_color.green = 257.0 * ReadShortValue(hFile); + image->background_color.blue = 257.0 * ReadShortValue(hFile); + break; + } + case 0x70: + case 0x71: + case 0x72: + case 0x73: + case 0x74: + case 0x75: + case 0x76: + case 0x77: + { + /* + Skip polygon or region. + */ + length = ReadShortValue(hFile); + if (length > GetSize(hFile)) + { + DeletePixelsMemory(image); + + strcpy(image->error, "InsufficientImageDataInFile"); + + return 0; + } + for (i=0; i < (length-2); i++) + if (ReadByte(hFile) == EOF) + break; + break; + } + case 0x90: + case 0x91: + case 0x98: + case 0x99: + case 0x9a: + case 0x9b: + { + PICTrectangle + source, + destination; + + unsigned char + *p; + + size_t + k; + + long long + bytes_per_line; + + unsigned char + *pixels; + + /* + Pixmap clipped by a rectangle. + */ + bytes_per_line = 0; + if ((code != 0x9a) && (code != 0x9b)) + bytes_per_line= (long long) ReadShortValue(hFile); + else + { + (void) ReadShortValue(hFile); + (void) ReadShortValue(hFile); + (void) ReadShortValue(hFile); + } + if (ReadRectangle(hFile, &frame) == 0) + { + DeletePixelsMemory(image); + + strcpy(image->error, "ImproperImageHeader"); + + return 0; + } + + /* + Initialize tile image. + */ + tile_image = CloneImage(image, (size_t) (frame.right-frame.left), (size_t) (frame.bottom-frame.top)); + if (tile_image == (ImagePICT*) NULL) + { + DeletePixelsMemory(image); + + strcpy(image->error, "ImproperImageHeader"); + + return 0; + } + if (!AquirePixelsMemory(tile_image)) + { + DeletePixelsMemory(image); + + return 0; + } + + if ((code == 0x9a) || (code == 0x9b) || + ((bytes_per_line & 0x8000) != 0)) + { + if (ReadPixmap(hFile, &pixmap) == 0) + { + DeletePixelsMemory(image); + DeletePixelsMemory(tile_image); + + strcpy(image->error, "ImproperImageHeader"); + + return 0; + } + tile_image->m_ndepth=(size_t) pixmap.component_size; + tile_image->alpha_trait=pixmap.component_count == 4 ? + BlendPixelTrait : UndefinedPixelTrait; + tile_image->resolutionX=(double) pixmap.horizontal_resolution; + tile_image->resolutionY=(double) pixmap.vertical_resolution; + if (tile_image->alpha_trait != UndefinedPixelTrait) + (void) SetImageAlpha(tile_image, 255); + } + if ((code != 0x9a) && (code != 0x9b)) + { + /* + Initialize colormap. + */ + tile_image->colors = 2; + if ((bytes_per_line & 0x8000) != 0) + { + (void) ReadLongValue(hFile); + flags = (long long) ReadShortValue(hFile); + tile_image->colors = 1UL * ReadShortValue(hFile) + 1; + } + status = AquireImageColormap(tile_image, tile_image->colors); + if (status == 0) + { + DeletePixelsMemory(image); + DeletePixelsMemory(tile_image); + + return 0; + } + + if ((bytes_per_line & 0x8000) != 0) + { + for (i = 0; i < tile_image->colors; i++) + { + k = ReadShortValue(hFile) % tile_image->colors; + if ((flags & 0x8000) != 0) + k = (size_t) i; + tile_image->colormap[k].red = (unsigned char) ReadShortValue(hFile)/* + 128U / 257U*/; + tile_image->colormap[k].green = (unsigned char) ReadShortValue(hFile)/* + 128U / 257U*/; + tile_image->colormap[k].blue = (unsigned char) ReadShortValue(hFile)/* + 128U / 257U*/; + } + } + else + { + for (i=0; i < (long long) tile_image->colors; i++) + { + tile_image->colormap[i].red=((double) 255 - tile_image->colormap[i].blue); + tile_image->colormap[i].green=((double) 255 - tile_image->colormap[i].green); + tile_image->colormap[i].blue=((double) 255 - tile_image->colormap[i].red); + } + } + } + if (feof(hFile) != 0) + { + DeletePixelsMemory(image); + DeletePixelsMemory(tile_image); + + strcpy(image->error, "EOFfile"); + + return 0; + } + + if (ReadRectangle(hFile, &source) == 0) + { + DeletePixelsMemory(image); + DeletePixelsMemory(tile_image); + + strcpy(image->error, "ImproperImageHeader"); + + return 0; + } + + if (ReadRectangle(hFile, &destination) == 0) + { + DeletePixelsMemory(image); + DeletePixelsMemory(tile_image); + + strcpy(image->error, "ImproperImageHeader"); + + return 0; + } + + (void) ReadShortValue(hFile); + + if ((code == 0x91) || (code == 0x99) || (code == 0x9b)) + { + /* + Skip region. + */ + length = ReadShortValue(hFile); + if ((size_t) length > GetSize(hFile)) + { + DeletePixelsMemory(image); + DeletePixelsMemory(tile_image); + + strcpy(image->error, "InsufficientImageDataInFile"); + + return 0; + } + + for (i = 0; i < length - 2; i++) + if (ReadByte(hFile) == EOF) + break; + } + + if ((code != 0x9a) && (code != 0x9b) && (bytes_per_line & 0x8000) == 0) + pixels = DecodeImage(hFile, tile_image, (size_t) bytes_per_line, 1, &extent); + else + pixels = DecodeImage(hFile, tile_image, (size_t) bytes_per_line, (unsigned int) pixmap.bits_per_pixel, &extent); + + if (pixels == (unsigned char*) NULL) + { + DeletePixelsMemory(image); + DeletePixelsMemory(tile_image); + + strcpy(image->error, "UnableToUncompressImage"); + + return 0; + } + + /* + Convert PICT tile image to pixel packets. + */ + p = pixels; + for (y=0; y < (long long) tile_image->m_nHeight; y++) + { + if (p > (pixels+extent+image->m_nWidth)) + { + free(pixels); + DeletePixelsMemory(image); + DeletePixelsMemory(tile_image); + + strcpy(image->error, "NotEnoughPixelData"); + + return 0; + } + q = tile_image->ppixels + tile_image->number_channels * (y * tile_image->m_nWidth); + if (q == (unsigned char *) NULL) + break; + for (x=0; x < tile_image->m_nWidth; x++) + { + if (tile_image->storage_class == PseudoClass) + { + if (((long long) *p < 0) || ((long long) *p >= (long long) tile_image->colors)) + index=0; + else + index=(long long) *p; + SetPixelIndex(tile_image,index,q); + SetPixelRed(tile_image, + tile_image->colormap[(long long) index].red,q); + SetPixelGreen(tile_image, + tile_image->colormap[(long long) index].green,q); + SetPixelBlue(tile_image, + tile_image->colormap[(long long) index].blue,q); + } + else + { + if (pixmap.bits_per_pixel == 16) + { + i=(long long) (*p++); + k=(size_t) (*p); + SetPixelRed(tile_image,(unsigned char) ((i & 0x7c) << 1),q); + SetPixelGreen(tile_image,(unsigned char) ((size_t) ((i & 0x03) << 6) |((k & 0xe0) >> 2)),q); + SetPixelBlue(tile_image,(unsigned char) ((k & 0x1f) << 3),q); + } + else + if (tile_image->alpha_trait == UndefinedPixelTrait) + { + if (p > (pixels+extent+2*image->m_nWidth)) + { + free(pixels); + DeletePixelsMemory(image); + DeletePixelsMemory(tile_image); + + strcpy(image->error, "NotEnoughPixelData"); + + return 0; + } + SetPixelRed(tile_image,*p,q); + SetPixelGreen(tile_image,*(p+tile_image->m_nWidth),q); + SetPixelBlue(tile_image,*(p+2*tile_image->m_nWidth),q); + } + else + { + if (p > (pixels+extent+3*image->m_nWidth)) + { + free(pixels); + DeletePixelsMemory(image); + DeletePixelsMemory(tile_image); + + strcpy(image->error, "NotEnoughPixelData"); + + return 0; + } + SetPixelAlpha(tile_image,*p,q); + SetPixelRed(tile_image,*(p+1*tile_image->m_nWidth),q); + SetPixelGreen(tile_image,*(p+2*tile_image->m_nWidth),q); + SetPixelBlue(tile_image,*(p+3*tile_image->m_nWidth),q); + } + } + p++; + q+=tile_image->number_channels; + } + if ((tile_image->storage_class == DirectClass) && + (pixmap.bits_per_pixel != 16)) + { + p+=(pixmap.component_count-1)*(long long) tile_image->m_nWidth; + if (p < pixels) + break; + } + } + + if (tile_image->storage_class == PseudoClass) + (void) SetImageAlpha(tile_image, 255); + else if (pixmap.bits_per_pixel == 16) + (void) SetImageAlpha(tile_image, 255); + else if (tile_image->alpha_trait == UndefinedPixelTrait) + (void) SetImageAlpha(tile_image, 255); + + free(pixels); + if ((jpeg == 0) && (feof(hFile) == 0)) + if ((code == 0x9a) || (code == 0x9b) || + ((bytes_per_line & 0x8000) != 0)) + (void) CompositeImage(image,tile_image,1,(long long) destination.left,(long long)destination.top); + tile_image=DestroyImage(tile_image); + break; + } + case 0xa1: + { + unsigned char + *info; + + size_t + type; + + /* + Comment. + */ + type = ReadShortValue(hFile); + length = ReadShortValue(hFile); + if ((size_t) length > GetSize(hFile)) + { + DeletePixelsMemory(image); + + strcpy(image->error, "InsufficientImageDataInFile"); + + return 0; + } + if (length == 0) + break; + info = (unsigned char*) malloc(length * sizeof (*info)); + if (info == (unsigned char*) NULL) + break; + count = Read(hFile, length, info); + if (count != length) + { + free(info); + + DeletePixelsMemory(image); + + strcpy(image->error, "UnableToReadImageData"); + + return 0; + } + switch (type) + { + case 0xe0: + { + profile = BlobToStringInfo((const void *) NULL, length); + if (profile->length != 0) + (void) memcpy(profile->datum,info,profile->length); + status = SetImageProfileInternal(image, "icc", profile, 0); + profile = DestroyStringInfo(profile); + if (status == 0) + { + free(info); + + DeletePixelsMemory(image); + + strcpy(image->error, "MemoryAllocationFailed"); + + return 0; + } + break; + } + case 0x1f2: + { + profile=BlobToStringInfo((const void *) NULL,length); + if (profile->length != 0) + (void) memcpy(profile->datum,info,profile->length); + status=SetImageProfileInternal(image,"iptc",profile,0); + if (status == 0) + { + free(info); + + DeletePixelsMemory(image); + + strcpy(image->error, "MemoryAllocationFailed"); + + return 0; + } + profile=DestroyStringInfo(profile); + break; + } + default: + break; + } + free(info); + break; + } + default: + /* + Skip to next op code. + */ + if (codes[code].length == -1) + (void) ReadShortValue(hFile); + else + for (i=0; i < (long long) codes[code].length; i++) + if (ReadByte(hFile) == EOF) + break; + } + } + if (code == 0xc00) + { + /* + Skip header. + */ + for (i=0; i < 24; i++) + if (ReadByte(hFile) == EOF) + break; + continue; + } + if (((code >= 0xb0) && (code <= 0xcf)) || + ((code >= 0x8000) && (code <= 0x80ff))) + continue; + if ((code == 0xff) || (code == 0xffff)) + continue; + if (((code >= 0xd0) && (code <= 0xfe)) || + ((code >= 0x8100) && (code <= 0xffff))) + { + /* + Skip reserved. + */ + length=ReadShortValue(hFile); + if (length > GetSize(hFile)) + { + DeletePixelsMemory(image); + + strcpy(image->error, "ImproperImageHeader"); + + return 0; + } + for (i=0; i < (long long) length; i++) + if (ReadByte(hFile) == EOF) + break; + continue; + } + if ((code >= 0x100) && (code <= 0x7fff)) + { + /* + Skip reserved. + */ + length=(size_t) ((code >> 7) & 0xff); + if (length > GetSize(hFile)) + { + DeletePixelsMemory(image); + + strcpy(image->error, "ImproperImageHeader"); + + return 0; + } + for (i=0; i < (long long) length; i++) + if (ReadByte(hFile) == EOF) + break; + continue; + } + } + return 1; +} + diff --git a/DesktopEditor/raster/PICT/pic.h b/DesktopEditor/raster/PICT/pic.h new file mode 100644 index 00000000000..d73074b732e --- /dev/null +++ b/DesktopEditor/raster/PICT/pic.h @@ -0,0 +1,391 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ + +#ifndef PIC_H +#define PIC_H + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +typedef enum +{ + UndefinedType, + BilevelType, + GrayscaleType, + GrayscaleAlphaType, + PaletteType, + PaletteAlphaType, + TrueColorType, + TrueColorAlphaType, + ColorSeparationType, + ColorSeparationAlphaType, + OptimizeType, + PaletteBilevelAlphaType +} ImageType; + +typedef struct +{ + char* path; + unsigned char* datum; + + size_t length; + size_t signature; + + char* name; +} StringInfo; + +typedef struct _NodeInfo +{ + void* key; + void* value; + + struct _NodeInfo* left; + struct _NodeInfo* right; +} NodeInfo; + +typedef struct +{ + NodeInfo* root; + + int (*compare)(const void*, const void*); + + int balance; + + void* key; + void* next; + + size_t nodes; + + size_t signature; +} SplayTreeInfo; + +typedef struct _PrimaryInfo +{ + double x; + double y; + double z; +} PrimaryInfo; + +typedef struct _ChromaticityInfo +{ + PrimaryInfo red_primary; + PrimaryInfo green_primary; + PrimaryInfo blue_primary; + PrimaryInfo white_point; +} ChromaticityInfo; + +typedef struct _PICTCode +{ + const char* name; + long long length; + + const char* description; +} PICTCode; + +typedef struct +{ + short top; + short left; + short bottom; + short right; +} PICTrectangle; + +typedef struct +{ + short version; + short pack_type; + + size_t pack_size; + size_t horizontal_resolution; + size_t vertical_resolution; + + short pixel_type; + short bits_per_pixel; + short component_count; + short component_size; + + size_t plane_bytes; + size_t table; + size_t reserved; +} PICTPixmap; + +typedef struct +{ + size_t width; + size_t height; + + long long x; + long long y; +} RectangleInfo; + +typedef struct _NexusInfo +{ + RectangleInfo region; + size_t length; + unsigned char* pixels; + int authentic_pixel_cache; + size_t signature; + struct _NexusInfo* virtual_nexus; +} NexusInfo; + + +typedef struct _GeometryInfo +{ + double rho; + double sigma; + double xi; + double psi; + double chi; +} GeometryInfo; + +typedef enum +{ + UndefinedChannel = 0x0000, + RedChannel = 0x0001, + GrayChannel = 0x0001, + CyanChannel = 0x0001, + LChannel = 0x0001, + GreenChannel = 0x0002, + MagentaChannel = 0x0002, + aChannel = 0x0002, + BlueChannel = 0x0004, + bChannel = 0x0002, + YellowChannel = 0x0004, + BlackChannel = 0x0008, + AlphaChannel = 0x0010, + OpacityChannel = 0x0010, + IndexChannel = 0x0020, /* Color Index Table? */ + ReadMaskChannel = 0x0040, /* Pixel is Not Readable? */ + WriteMaskChannel = 0x0080, /* Pixel is Write Protected? */ + MetaChannel = 0x0100, /* not used */ + CompositeMaskChannel = 0x0200, /* SVG mask */ + CompositeChannels = 0x001F, + AllChannels = 0X7FFFFFF, + /* + Special purpose channel types. + FUTURE: are these needed any more - they are more like hacks + SyncChannels for example is NOT a real channel but a 'flag' + It really says -- "User has not defined channels" + Though it does have extra meaning in the "-auto-level" operator + */ + TrueAlphaChannel = 0x0100, /* extract actual alpha channel from opacity */ + RGBChannels = 0x0200, /* set alpha from grayscale mask in RGB */ + GrayChannels = 0x0400, + SyncChannels = 0x20000, /* channels modified as a single unit */ + DefaultChannels = AllChannels +} ChannelType; + +typedef enum +{ + ReadMode, + WriteMode, + IOMode, + PersistMode +} MapMode; + +typedef enum +{ + UndefinedClass, + DirectClass, + PseudoClass +} ClassType; + +typedef enum +{ + UndefinedColorspace, + CMYColorspace, /* negated linear RGB colorspace */ + CMYKColorspace, /* CMY with Black separation */ + GRAYColorspace, /* Single Channel greyscale (non-linear) image */ + HCLColorspace, + HCLpColorspace, + HSBColorspace, + HSIColorspace, + HSLColorspace, + HSVColorspace, /* alias for HSB */ + HWBColorspace, + LabColorspace, + LCHColorspace, /* alias for LCHuv */ + LCHabColorspace, /* Cylindrical (Polar) Lab */ + LCHuvColorspace, /* Cylindrical (Polar) Luv */ + LogColorspace, + LMSColorspace, + LuvColorspace, + OHTAColorspace, + Rec601YCbCrColorspace, + Rec709YCbCrColorspace, + RGBColorspace, /* Linear RGB colorspace */ + scRGBColorspace, /* ??? */ + sRGBColorspace, /* Default: non-linear sRGB colorspace */ + TransparentColorspace, + xyYColorspace, + XYZColorspace, /* IEEE Color Reference colorspace */ + YCbCrColorspace, + YCCColorspace, + YDbDrColorspace, + YIQColorspace, + YPbPrColorspace, + YUVColorspace, + LinearGRAYColorspace, /* Single Channel greyscale (linear) image */ + JzazbzColorspace, + DisplayP3Colorspace, + Adobe98Colorspace, + ProPhotoColorspace, + OklabColorspace, + OklchColorspace +} ColorspaceType; + +typedef enum +{ + UndefinedPixelTrait = 0x000000, + CopyPixelTrait = 0x000001, + UpdatePixelTrait = 0x000002, + BlendPixelTrait = 0x000004 +} PixelTrait; + +typedef enum +{ + UndefinedPixelChannel = 0, + RedPixelChannel = 0, + CyanPixelChannel = 0, + GrayPixelChannel = 0, + LPixelChannel = 0, + LabelPixelChannel = 0, + YPixelChannel = 0, + aPixelChannel = 1, + GreenPixelChannel = 1, + MagentaPixelChannel = 1, + CbPixelChannel = 1, + bPixelChannel = 2, + BluePixelChannel = 2, + YellowPixelChannel = 2, + CrPixelChannel = 2, + BlackPixelChannel = 3, + AlphaPixelChannel = 4, + IndexPixelChannel = 5, + ReadMaskPixelChannel = 6, + WriteMaskPixelChannel = 7, + MetaPixelChannel = 8, /* deprecated */ + CompositeMaskPixelChannel = 9, + MetaPixelChannels = 10, + IntensityPixelChannel = 64, /* ???? */ + CompositePixelChannel = 64, /* ???? */ + SyncPixelChannel = 65 /* not a real channel */ +} PixelChannel; + +typedef struct +{ + PixelChannel channel; + PixelTrait traits; + long long offset; +} PixelChannelMap; + +typedef struct +{ + ClassType storage_class; + + ColorspaceType colorspace; + + PixelTrait alpha_trait; + + double fuzz; + + size_t depth; + size_t count; + + double red; + double green; + double blue; + double black; + double alpha; + double index; +} PixelInfo; + +typedef struct +{ + ClassType storage_class; + ColorspaceType colorspace; + ChromaticityInfo chromaticity; + int m_pctVersion; + + size_t m_nHeight; + size_t m_nWidth; + size_t m_ndepth; + size_t m_nPixelsSize; + size_t colors; + + SplayTreeInfo* profiles; + SplayTreeInfo* artifacts; + + double fuzz; + + unsigned char* ppixels; + + double resolutionX; + double resolutionY; + double gamma; + + ImageType type; + + PixelInfo background_color; + PixelInfo* colormap; + + PixelTrait alpha_trait; + + PixelChannelMap* channel_map; + + PixelTrait mask_trait; + + int taint; + + void* cache; + + size_t number_channels; + + char error[256]; +}ImagePICT; + +int DecodePICT(FILE* hFile, ImagePICT* image); +void AquireImage(ImagePICT* image); +ImagePICT* DestroyImage(ImagePICT* image); + +#endif // PIC_H diff --git a/DesktopEditor/xml/build/qt/libxml2.pri b/DesktopEditor/xml/build/qt/libxml2.pri index 0722b6932a7..960bacfa1a8 100644 --- a/DesktopEditor/xml/build/qt/libxml2.pri +++ b/DesktopEditor/xml/build/qt/libxml2.pri @@ -74,6 +74,8 @@ SOURCES += \ $$PWD/../../libxml2/valid.c \ $$PWD/../../libxml2/parser.c } + +!core_only_libxml { SOURCES += \ $$PWD/../../src/xmlwriter.cpp \ $$PWD/../../src/xmllight.cpp \ @@ -85,3 +87,4 @@ HEADERS += \ HEADERS += \ $$PWD/../../include/xmlutils.h \ $$PWD/../../include/xmlwriter.h +} diff --git a/DesktopEditor/xml/include/xmlutils.h b/DesktopEditor/xml/include/xmlutils.h index 41b7363bd75..666ef726326 100644 --- a/DesktopEditor/xml/include/xmlutils.h +++ b/DesktopEditor/xml/include/xmlutils.h @@ -250,7 +250,7 @@ namespace XmlUtils std::vector oNodes; \ if (node.GetNodes(name, oNodes)) \ { \ - int nCount = oNodes.size(); \ + size_t nCount = oNodes.size(); \ for (size_t i = 0; i < nCount; ++i) \ { \ XmlUtils::CXmlNode & oItem = oNodes[i]; \ diff --git a/DjVuFile/DjVu.cpp b/DjVuFile/DjVu.cpp index c30393a43a2..83230701a60 100644 --- a/DjVuFile/DjVu.cpp +++ b/DjVuFile/DjVu.cpp @@ -93,7 +93,7 @@ void CDjVuFile::GetPageInfo(int nPageIndex, double* pdWidth, double* pdHeight, d if (m_pImplementation) m_pImplementation->GetPageInfo(nPageIndex, pdWidth, pdHeight, pdDpiX, pdDpiY); } -void CDjVuFile::DrawPageOnRenderer(IRenderer* pRenderer, int nPageIndex, bool* pBreak) +void CDjVuFile::DrawPageOnRenderer(IRenderer* pRenderer, int nPageIndex, bool* pBreak, COfficeDrawingPageParams* pParams) { if (m_pImplementation) m_pImplementation->DrawPageOnRenderer(pRenderer, nPageIndex, pBreak); diff --git a/DjVuFile/DjVu.h b/DjVuFile/DjVu.h index 8a84360c7a9..3c1180e1e85 100644 --- a/DjVuFile/DjVu.h +++ b/DjVuFile/DjVu.h @@ -69,7 +69,7 @@ class DJVU_DECL_EXPORT CDjVuFile : public IOfficeDrawingFile virtual int GetPagesCount(); virtual void GetPageInfo(int nPageIndex, double* pdWidth, double* pdHeight, double* pdDpiX, double* pdDpiY); - virtual void DrawPageOnRenderer(IRenderer* pRenderer, int nPageIndex, bool* pBreak); + virtual void DrawPageOnRenderer(IRenderer* pRenderer, int nPageIndex, bool* pBreak, COfficeDrawingPageParams* pParams = NULL); virtual std::wstring GetInfo(); void ConvertToPdf(const std::wstring& path); diff --git a/DjVuFile/DjVuFileImplementation.cpp b/DjVuFile/DjVuFileImplementation.cpp index ee023a1a140..a60f149e19b 100644 --- a/DjVuFile/DjVuFileImplementation.cpp +++ b/DjVuFile/DjVuFileImplementation.cpp @@ -88,6 +88,37 @@ namespace NSDjvu return 0; } } + static int ComputeRed(int w, int h, int rw, int rh) + { + for (int red = 1; red < 16; ++red) + if ((w + red - 1) / red == rw && (h + red - 1) / red == rh) + return red; + return 1; + } + static void DrawPixmap(GP pImage, Aggplus::CImage* pImageRes) + { + unsigned int unPixmapH = pImage->rows(); + unsigned int unPixmapW = pImage->columns(); + BYTE* pBufferDst = new BYTE[4 * unPixmapH * unPixmapW]; + if (!pBufferDst) + return; + + pImageRes->Create(pBufferDst, unPixmapW, unPixmapH, 4 * unPixmapW); + + BYTE* pBuffer = pBufferDst; + for (int j = unPixmapH - 1; j >= 0; --j) + { + GPixel* pLine = pImage->operator [](j); + + for (int i = 0; i < unPixmapW; ++i, pBuffer += 4, ++pLine) + { + pBuffer[0] = pLine->b; + pBuffer[1] = pLine->g; + pBuffer[2] = pLine->r; + pBuffer[3] = 255; + } + } + } } CDjVuFileImplementation::CDjVuFileImplementation(NSFonts::IApplicationFonts* pFonts) @@ -423,8 +454,13 @@ BYTE* CDjVuFileImplementation::GetPageLinks(int nPageIndex) void CDjVuFileImplementation::CreateFrame(IRenderer* pRenderer, GP& pPage, int nPage, XmlUtils::CXmlNode& text) { - int nWidth = pPage->get_real_width(); - int nHeight = pPage->get_real_height(); + long lRendererType = c_nUnknownRenderer; + pRenderer->get_Type(&lRendererType); + if (c_nPDFWriter == lRendererType) + { + CreatePdfFrame(pRenderer, pPage, nPage, text); + return; + } int nDpi = pPage->get_dpi(); @@ -455,36 +491,6 @@ void CDjVuFileImplementation::CreateFrame(IRenderer* pRenderer, GP& p LONG lImageWidth = (LONG)(dRendDpiX * dRendWidth / dPixToMM); LONG lImageHeight = (LONG)(dRendDpiY * dRendHeight / dPixToMM); - long lRendererType = c_nUnknownRenderer; - pRenderer->get_Type(&lRendererType); - if (c_nPDFWriter == lRendererType) - { - lImageWidth = pPage->get_real_width(); - lImageHeight = pPage->get_real_height(); - } - else if (c_nHtmlRendrerer == lRendererType) - { - // TODO: Нужно реализовать функцию - // pRenderer->GetMaxImageSize(); - //VARIANT var; - //renderer->GetAdditionalParam(L"MaxImageSize", &var); - //LONG lMaxWidth = var.lVal; - //if ((lImageWidth > lMaxWidth) || (lImageHeight > lMaxWidth)) - //{ - // double dAspect = (double)(lImageWidth) / lImageHeight; - // if (lImageWidth > lImageHeight) - // { - // lImageWidth = lMaxWidth; - // lImageHeight = (LONG)(lImageHeight / dAspect); - // } - // else - // { - // lImageHeight = lMaxWidth; - // lImageWidth = (LONG)(dAspect * lImageHeight); - // } - //} - } - BYTE* pBufferDst = new BYTE[4 * lImageHeight * lImageWidth]; if (!pBufferDst) return; @@ -645,6 +651,14 @@ void CDjVuFileImplementation::CreatePdfFrame(IRenderer* pRenderer, GP LONG lImageWidth = pPage->get_real_width(); LONG lImageHeight = pPage->get_real_height(); + double dImageRedW = dWidth * 72.0 / 25.4 * 2.0; + double dImageRedH = dHeight * 72.0 / 25.4 * 2.0; + LONG lRed = std::min(lImageWidth / dImageRedW, lImageHeight / dImageRedH); + if (lRed > 1) + { + lImageWidth /= lRed; + lImageHeight /= lRed; + } CPdfFile* pPdf = (CPdfFile*)pRenderer; @@ -677,68 +691,37 @@ void CDjVuFileImplementation::CreatePdfFrame(IRenderer* pRenderer, GP } else if (pPage->is_legal_compound()) { - GRect oRectAll(0, 0, lImageWidth, lImageHeight); GP pIW44Image = pPage->get_bg44(); if (NULL != pIW44Image) { - int nBgWidth = pIW44Image->get_width(); - int nBgHeight = pIW44Image->get_height(); - GP pBgImage = pIW44Image->get_pixmap(); if (NULL != pBgImage) { - BYTE* pBgBuffer = new BYTE[4 * nBgWidth * nBgHeight]; - if (!pBgBuffer) - return; - - Aggplus::CImage oBgImage; - oBgImage.Create(pBgBuffer, nBgWidth, nBgHeight, 4 * nBgWidth); - - BYTE* pBuffer = pBgBuffer; - for (int j = nBgHeight - 1; j >= 0; --j) - { - GPixel* pLine = pBgImage->operator [](j); - - for (int i = 0; i < nBgWidth; ++i, pBuffer += 4, ++pLine) - { - pBuffer[0] = pLine->b; - pBuffer[1] = pLine->g; - pBuffer[2] = pLine->r; - pBuffer[3] = 255; - } - } - pRenderer->DrawImage((IGrObject*)&oBgImage, 0, 0, dWidth, dHeight); + Aggplus::CImage oImage; + NSDjvu::DrawPixmap(pBgImage, &oImage); + pRenderer->DrawImage((IGrObject*)&oImage, 0, 0, dWidth, dHeight); + } + } + else + { + GP pBgImage = pPage->get_bgpm(); + if (NULL != pBgImage) + { + Aggplus::CImage oImage; + NSDjvu::DrawPixmap(pBgImage, &oImage); + pRenderer->DrawImage((IGrObject*)&oImage, 0, 0, dWidth, dHeight); } } + GRect oRectAll(0, 0, lImageWidth, lImageHeight); GP pImage = pPage->get_fgpm(); if (NULL == pImage) - pImage = pPage->get_fg_pixmap(oRectAll); + pImage = pPage->get_fg_pixmap(oRectAll, oRectAll); if (NULL != pImage) { - unsigned int unPixmapH = pImage->rows(); - unsigned int unPixmapW = pImage->columns(); - BYTE* pBufferDst = new BYTE[4 * unPixmapH * unPixmapW]; - if (!pBufferDst) - return; - Aggplus::CImage oImage; - oImage.Create(pBufferDst, unPixmapW, unPixmapH, 4 * unPixmapW); - - BYTE* pBuffer = pBufferDst; - for (int j = unPixmapH - 1; j >= 0; --j) - { - GPixel* pLine = pImage->operator [](j); - - for (int i = 0; i < unPixmapW; ++i, pBuffer += 4, ++pLine) - { - pBuffer[0] = pLine->b; - pBuffer[1] = pLine->g; - pBuffer[2] = pLine->r; - pBuffer[3] = 255; - } - } + NSDjvu::DrawPixmap(pImage, &oImage); GP pBitmap = pPage->get_bitmap(oRectAll, oRectAll, 4); @@ -789,27 +772,9 @@ void CDjVuFileImplementation::CreatePdfFrame(IRenderer* pRenderer, GP if (NULL != pImage) { - BYTE* pBufferDst = new BYTE[4 * lImageHeight * lImageWidth]; - if (pBufferDst) - { - Aggplus::CImage oImage; - oImage.Create(pBufferDst, lImageWidth, lImageHeight, 4 * lImageWidth); - - BYTE* pBuffer = pBufferDst; - for (int j = lImageHeight - 1; j >= 0; --j) - { - GPixel* pLine = pImage->operator [](j); - - for (int i = 0; i < lImageWidth; ++i, pBuffer += 4, ++pLine) - { - pBuffer[0] = pLine->b; - pBuffer[1] = pLine->g; - pBuffer[2] = pLine->r; - pBuffer[3] = 255; - } - } - pRenderer->DrawImage((IGrObject*)&oImage, 0, 0, dWidth, dHeight); - } + Aggplus::CImage oImage; + NSDjvu::DrawPixmap(pImage, &oImage); + pRenderer->DrawImage((IGrObject*)&oImage, 0, 0, dWidth, dHeight); } else { @@ -896,7 +861,12 @@ XmlUtils::CXmlNode CDjVuFileImplementation::ParseText(GP pPage) XmlUtils::CXmlNode hiddenText; XmlUtils::CXmlNode pageColumn; XmlUtils::CXmlNode region; - hiddenText.FromXmlStringA(NSDjvu::MakeCString(pageText)); + std::string sPageText = NSDjvu::MakeCString(pageText); + if (!hiddenText.FromXmlStringA(sPageText)) + { + std::wstring sPageTextW = UTF8_TO_U(sPageText); + hiddenText.FromXmlString(sPageTextW); + } hiddenText.GetNode(L"PAGECOLUMN", pageColumn); pageColumn.GetNode(L"REGION", region); region.GetNode(L"PARAGRAPH", paragraph); diff --git a/DocxRenderer/DocxRenderer.cpp b/DocxRenderer/DocxRenderer.cpp index 9dc274099c3..740f66beac7 100644 --- a/DocxRenderer/DocxRenderer.cpp +++ b/DocxRenderer/DocxRenderer.cpp @@ -34,523 +34,632 @@ #include "../DesktopEditor/common/Directory.h" #include "../OfficeUtils/src/OfficeUtils.h" #include "src/logic/Document.h" +#include "../DesktopEditor/graphics/commands/DocInfo.h" +#include class CDocxRenderer_Private { - public: - NSDocxRenderer::CDocument m_oDocument; - std::wstring m_sTempDirectory; +public: + NSDocxRenderer::CDocument m_oDocument; + std::wstring m_sTempDirectory; + bool m_bIsSupportShapeCommands = false; - public: - CDocxRenderer_Private(NSFonts::IApplicationFonts* pFonts, IRenderer* pRenderer) : m_oDocument(pRenderer, pFonts) - { - } - ~CDocxRenderer_Private() - { - - } +public: + CDocxRenderer_Private(NSFonts::IApplicationFonts* pFonts, IRenderer* pRenderer) : m_oDocument(pRenderer, pFonts) + {} + ~CDocxRenderer_Private() + {} }; CDocxRenderer::CDocxRenderer(NSFonts::IApplicationFonts* pAppFonts) { - m_pInternal = new CDocxRenderer_Private(pAppFonts, this); + m_pInternal = new CDocxRenderer_Private(pAppFonts, this); } - CDocxRenderer::~CDocxRenderer() { - RELEASEOBJECT(m_pInternal); + RELEASEOBJECT(m_pInternal); } +HRESULT CDocxRenderer::Compress() +{ + COfficeUtils oCOfficeUtils(nullptr); + HRESULT hr = oCOfficeUtils.CompressFileOrDirectory(m_pInternal->m_oDocument.m_strTempDirectory, m_pInternal->m_oDocument.m_strDstFilePath, true); + + if (!m_pInternal->m_oDocument.m_strTempDirectory.empty()) + NSDirectory::DeleteDirectory(m_pInternal->m_oDocument.m_strTempDirectory); -HRESULT CDocxRenderer::CreateNewFile(const std::wstring& wsPath, bool bIsOutCompress) + m_pInternal->m_oDocument.m_strTempDirectory = L""; + return hr; +} + +HRESULT CDocxRenderer::SetTextAssociationType(const NSDocxRenderer::TextAssociationType& eType) { - m_pInternal->m_oDocument.m_strDstFilePath = wsPath; - m_pInternal->m_oDocument.m_strTempDirectory = bIsOutCompress ? - NSDirectory::CreateDirectoryWithUniqueName(m_pInternal->m_sTempDirectory) : - m_pInternal->m_sTempDirectory; - m_pInternal->m_oDocument.CreateDocument(); - return S_OK; + m_pInternal->m_oDocument.m_oCurrentPage.m_eTextAssociationType = eType; + return S_OK; } -HRESULT CDocxRenderer::Close() + +int CDocxRenderer::Convert(IOfficeDrawingFile* pFile, const std::wstring& sDst, bool bIsOutCompress) { - COfficeUtils oCOfficeUtils(nullptr); - HRESULT hr = oCOfficeUtils.CompressFileOrDirectory(m_pInternal->m_oDocument.m_strTempDirectory, m_pInternal->m_oDocument.m_strDstFilePath, true); - if (!m_pInternal->m_oDocument.m_strTempDirectory.empty()) - NSDirectory::DeleteDirectory(m_pInternal->m_oDocument.m_strTempDirectory); - m_pInternal->m_oDocument.m_strTempDirectory = L""; - return hr; +#ifndef DISABLE_FULL_DOCUMENT_CREATION + m_pInternal->m_oDocument.m_strDstFilePath = sDst; + + m_pInternal->m_oDocument.m_oCurrentPage.m_bUseDefaultFont = false; + m_pInternal->m_oDocument.m_oCurrentPage.m_bWriteStyleRaw = false; + m_pInternal->m_bIsSupportShapeCommands = false; + + if (bIsOutCompress) + m_pInternal->m_oDocument.m_strTempDirectory = NSDirectory::CreateDirectoryWithUniqueName(m_pInternal->m_sTempDirectory); + else + { + if (NSDirectory::Exists(sDst)) + NSDirectory::DeleteDirectory(sDst); + + NSDirectory::CreateDirectories(sDst); + m_pInternal->m_oDocument.m_strTempDirectory = sDst; + } + + m_pInternal->m_oDocument.Init(); + m_pInternal->m_oDocument.CreateTemplates(); + + int nPagesCount = pFile->GetPagesCount(); + m_pInternal->m_oDocument.m_lNumberPages = nPagesCount; + + for (int i = 0; i < nPagesCount; ++i) + DrawPage(pFile, i); + + HRESULT hr = S_OK; + m_pInternal->m_oDocument.Write(); + m_pInternal->m_oDocument.Clear(); + if (bIsOutCompress) hr = Compress(); + return (hr == S_OK) ? 0 : 1; +#else + return S_FALSE; +#endif } -HRESULT CDocxRenderer::SetTextAssociationType(const NSDocxRenderer::TextAssociationType& eType) +std::vector CDocxRenderer::ScanPage(IOfficeDrawingFile* pFile, size_t nPage) { - m_pInternal->m_oDocument.m_oCurrentPage.m_eTextAssociationType = eType; - return S_OK; + m_pInternal->m_oDocument.Clear(); + m_pInternal->m_oDocument.Init(false); + m_pInternal->m_oDocument.m_oCurrentPage.m_bUseDefaultFont = true; + m_pInternal->m_oDocument.m_oCurrentPage.m_bWriteStyleRaw = true; + m_pInternal->m_bIsSupportShapeCommands = false; + + DrawPage(pFile, nPage); + + auto xml_shapes = m_pInternal->m_oDocument.m_oCurrentPage.GetXmlShapes(); + m_pInternal->m_oDocument.Clear(); + return xml_shapes; } -int CDocxRenderer::Convert(IOfficeDrawingFile* pFile, const std::wstring& sDstFile, bool bIsOutCompress) +std::vector CDocxRenderer::ScanPagePptx(IOfficeDrawingFile* pFile, size_t nPage) { - CreateNewFile(sDstFile, bIsOutCompress); + m_pInternal->m_oDocument.Clear(); + m_pInternal->m_oDocument.Init(false); + m_pInternal->m_oDocument.m_oCurrentPage.m_bUseDefaultFont = true; + m_pInternal->m_oDocument.m_oCurrentPage.m_bWriteStyleRaw = true; + m_pInternal->m_bIsSupportShapeCommands = true; - if (odftPDF == pFile->GetType()) - m_pInternal->m_oDocument.m_bIsNeedPDFTextAnalyzer = true; + DrawPage(pFile, nPage); - int nPagesCount = pFile->GetPagesCount(); - for (int i = 0; i < nPagesCount; ++i) - { - //std::cout << "Page " << i + 1 << "/" << nPagesCount << std::endl; - NewPage(); - BeginCommand(c_nPageType); - m_pInternal->m_oDocument.m_bIsDisablePageCommand = true; + auto xml_shapes = m_pInternal->m_oDocument.m_oCurrentPage.GetXmlShapesPptx(); + m_pInternal->m_oDocument.Clear(); + return xml_shapes; +} + +void CDocxRenderer::SetExternalImageStorage(NSDocxRenderer::IImageStorage* pStorage) +{ + m_pInternal->m_oDocument.m_oImageManager.m_pExternalStorage = pStorage; +} - double dPageDpiX, dPageDpiY; - double dWidth, dHeight; - pFile->GetPageInfo(i, &dWidth, &dHeight, &dPageDpiX, &dPageDpiY); +void CDocxRenderer::DrawPage(IOfficeDrawingFile* pFile, size_t nPage) +{ + //std::cout << "Page " << i + 1 << "/" << nPagesCount << std::endl; + NewPage(); + BeginCommand(c_nPageType); + m_pInternal->m_oDocument.m_bIsDisablePageCommand = true; + m_pInternal->m_oDocument.m_lPageNum = nPage; - dWidth *= 25.4 / dPageDpiX; - dHeight *= 25.4 / dPageDpiY; + double dPageDpiX, dPageDpiY; + double dWidth, dHeight; + pFile->GetPageInfo(nPage, &dWidth, &dHeight, &dPageDpiX, &dPageDpiY); - put_Width(dWidth); - put_Height(dHeight); + dWidth *= 25.4 / dPageDpiX; + dHeight *= 25.4 / dPageDpiY; - pFile->DrawPageOnRenderer(this, i, nullptr); + put_Width(dWidth); + put_Height(dHeight); - m_pInternal->m_oDocument.m_bIsDisablePageCommand = false; - EndCommand(c_nPageType); - } + pFile->DrawPageOnRenderer(this, nPage, nullptr); - HRESULT hr = S_OK; - m_pInternal->m_oDocument.Close(); - if (bIsOutCompress) - hr = Close(); - return (hr == S_OK) ? 0 : 1; + m_pInternal->m_oDocument.m_bIsDisablePageCommand = false; + EndCommand(c_nPageType); } HRESULT CDocxRenderer::SetTempFolder(const std::wstring& wsPath) { - m_pInternal->m_sTempDirectory = wsPath; - return S_OK; + m_pInternal->m_sTempDirectory = wsPath; + return S_OK; +} + +HRESULT CDocxRenderer::IsSupportAdvancedCommand(const IAdvancedCommand::AdvancedCommandType& type) +{ + switch (type) + { + case IAdvancedCommand::AdvancedCommandType::ShapeStart: + case IAdvancedCommand::AdvancedCommandType::ShapeEnd: + return m_pInternal->m_bIsSupportShapeCommands ? S_OK: S_FALSE; + default: + break; + } + + return S_FALSE; +} +HRESULT CDocxRenderer::AdvancedCommand(IAdvancedCommand* command) +{ + if (NULL == command) + return S_FALSE; + + switch (command->GetCommandType()) + { + case IAdvancedCommand::AdvancedCommandType::ShapeStart: + { + CShapeStart* pShape = (CShapeStart*)command; + std::string& sUtf8Shape = pShape->GetShapeXML(); + Aggplus::CImage* pImage = pShape->GetShapeImage(); + if (pImage) + { + std::shared_ptr pInfo = m_pInternal->m_oDocument.m_oImageManager.GenerateImageID(pImage); + std::string sNewId = "r:embed=\"rId" + std::to_string(pInfo->m_nId + c_iStartingIdForImages) + "\""; + NSStringUtils::string_replaceA(sUtf8Shape, "r:embed=\"\"", sNewId); + } + m_pInternal->m_oDocument.m_oCurrentPage.AddCompleteXml(UTF8_TO_U(sUtf8Shape)); + return S_OK; + } + case IAdvancedCommand::AdvancedCommandType::ShapeEnd: + { + return S_OK; + } + default: + break; + } + return S_FALSE; } -//---------------------------------------------------------------------------------------- -// Тип рендерера -//---------------------------------------------------------------------------------------- + + HRESULT CDocxRenderer::get_Type(LONG* lType) { - *lType = c_nDocxWriter; - return S_OK; + *lType = c_nDocxWriter; + return S_OK; } -//---------------------------------------------------------------------------------------- -// Функции для работы со страницей -//---------------------------------------------------------------------------------------- + HRESULT CDocxRenderer::NewPage() { - return m_pInternal->m_oDocument.NewPage(); + return m_pInternal->m_oDocument.NewPage(); } HRESULT CDocxRenderer::get_Height(double* dHeight) { - return m_pInternal->m_oDocument.get_Height(dHeight); + return m_pInternal->m_oDocument.get_Height(dHeight); } HRESULT CDocxRenderer::put_Height(const double& dHeight) { - return m_pInternal->m_oDocument.put_Height(dHeight); + return m_pInternal->m_oDocument.put_Height(dHeight); } HRESULT CDocxRenderer::get_Width(double* dWidth) { - return m_pInternal->m_oDocument.get_Width(dWidth); + return m_pInternal->m_oDocument.get_Width(dWidth); } HRESULT CDocxRenderer::put_Width(const double& dWidth) { - return m_pInternal->m_oDocument.put_Width(dWidth); + return m_pInternal->m_oDocument.put_Width(dWidth); } HRESULT CDocxRenderer::get_DpiX(double* dDpiX) { - return m_pInternal->m_oDocument.get_DpiX(dDpiX); + return m_pInternal->m_oDocument.get_DpiX(dDpiX); } HRESULT CDocxRenderer::get_DpiY(double* dDpiY) { - return m_pInternal->m_oDocument.get_DpiY(dDpiY); + return m_pInternal->m_oDocument.get_DpiY(dDpiY); } -//---------------------------------------------------------------------------------------- -// Функции для работы с Pen -//---------------------------------------------------------------------------------------- + HRESULT CDocxRenderer::get_PenColor(LONG* lColor) { - return m_pInternal->m_oDocument.get_PenColor(lColor); + return m_pInternal->m_oDocument.get_PenColor(lColor); } HRESULT CDocxRenderer::put_PenColor(const LONG& lColor) { - return m_pInternal->m_oDocument.put_PenColor(lColor); + return m_pInternal->m_oDocument.put_PenColor(lColor); } HRESULT CDocxRenderer::get_PenAlpha(LONG* lAlpha) { - return m_pInternal->m_oDocument.get_PenAlpha(lAlpha); + return m_pInternal->m_oDocument.get_PenAlpha(lAlpha); } HRESULT CDocxRenderer::put_PenAlpha(const LONG& lAlpha) { - return m_pInternal->m_oDocument.put_PenAlpha(lAlpha); + return m_pInternal->m_oDocument.put_PenAlpha(lAlpha); } HRESULT CDocxRenderer::get_PenSize(double* dSize) { - return m_pInternal->m_oDocument.get_PenSize(dSize); + return m_pInternal->m_oDocument.get_PenSize(dSize); } HRESULT CDocxRenderer::put_PenSize(const double& dSize) { - return m_pInternal->m_oDocument.put_PenSize(dSize); + return m_pInternal->m_oDocument.put_PenSize(dSize); } HRESULT CDocxRenderer::get_PenDashStyle(BYTE* nDashStyle) { - return m_pInternal->m_oDocument.get_PenDashStyle(nDashStyle); + return m_pInternal->m_oDocument.get_PenDashStyle(nDashStyle); } HRESULT CDocxRenderer::put_PenDashStyle(const BYTE& nDashStyle) { - return m_pInternal->m_oDocument.put_PenDashStyle(nDashStyle); + return m_pInternal->m_oDocument.put_PenDashStyle(nDashStyle); } HRESULT CDocxRenderer::get_PenLineStartCap(BYTE* nCapStyle) { - return m_pInternal->m_oDocument.get_PenLineStartCap(nCapStyle); + return m_pInternal->m_oDocument.get_PenLineStartCap(nCapStyle); } HRESULT CDocxRenderer::put_PenLineStartCap(const BYTE& nCapStyle) { - return m_pInternal->m_oDocument.put_PenLineStartCap(nCapStyle); + return m_pInternal->m_oDocument.put_PenLineStartCap(nCapStyle); } HRESULT CDocxRenderer::get_PenLineEndCap(BYTE* nCapStyle) { - return m_pInternal->m_oDocument.get_PenLineEndCap(nCapStyle); + return m_pInternal->m_oDocument.get_PenLineEndCap(nCapStyle); } HRESULT CDocxRenderer::put_PenLineEndCap(const BYTE& nCapStyle) { - return m_pInternal->m_oDocument.put_PenLineEndCap(nCapStyle); + return m_pInternal->m_oDocument.put_PenLineEndCap(nCapStyle); } HRESULT CDocxRenderer::get_PenLineJoin(BYTE* nJoinStyle) { - return m_pInternal->m_oDocument.get_PenLineJoin(nJoinStyle); + return m_pInternal->m_oDocument.get_PenLineJoin(nJoinStyle); } HRESULT CDocxRenderer::put_PenLineJoin(const BYTE& nJoinStyle) { - return m_pInternal->m_oDocument.put_PenLineJoin(nJoinStyle); + return m_pInternal->m_oDocument.put_PenLineJoin(nJoinStyle); } HRESULT CDocxRenderer::get_PenDashOffset(double* dOffset) { - return m_pInternal->m_oDocument.get_PenDashOffset(dOffset); + return m_pInternal->m_oDocument.get_PenDashOffset(dOffset); } HRESULT CDocxRenderer::put_PenDashOffset(const double& dOffset) { - return m_pInternal->m_oDocument.put_PenDashOffset(dOffset); + return m_pInternal->m_oDocument.put_PenDashOffset(dOffset); } HRESULT CDocxRenderer::get_PenAlign(LONG* lAlign) { - return m_pInternal->m_oDocument.get_PenAlign(lAlign); + return m_pInternal->m_oDocument.get_PenAlign(lAlign); } HRESULT CDocxRenderer::put_PenAlign(const LONG& lAlign) { - return m_pInternal->m_oDocument.put_PenAlign(lAlign); + return m_pInternal->m_oDocument.put_PenAlign(lAlign); } HRESULT CDocxRenderer::get_PenMiterLimit(double* dMiter) { - return m_pInternal->m_oDocument.get_PenMiterLimit(dMiter); + return m_pInternal->m_oDocument.get_PenMiterLimit(dMiter); } HRESULT CDocxRenderer::put_PenMiterLimit(const double& dMiter) { - return m_pInternal->m_oDocument.put_PenMiterLimit(dMiter); + return m_pInternal->m_oDocument.put_PenMiterLimit(dMiter); } HRESULT CDocxRenderer::PenDashPattern(double* pPattern, LONG lCount) { - return m_pInternal->m_oDocument.PenDashPattern(pPattern, lCount); + return m_pInternal->m_oDocument.PenDashPattern(pPattern, lCount); } -//---------------------------------------------------------------------------------------- -// Функции для работы с Brush -//---------------------------------------------------------------------------------------- + HRESULT CDocxRenderer::get_BrushType(LONG* lType) { - return m_pInternal->m_oDocument.get_BrushType(lType); + return m_pInternal->m_oDocument.get_BrushType(lType); } HRESULT CDocxRenderer::put_BrushType(const LONG& lType) { - return m_pInternal->m_oDocument.put_BrushType(lType); + return m_pInternal->m_oDocument.put_BrushType(lType); } HRESULT CDocxRenderer::get_BrushColor1(LONG* lColor) { - return m_pInternal->m_oDocument.get_BrushColor1(lColor); + return m_pInternal->m_oDocument.get_BrushColor1(lColor); } HRESULT CDocxRenderer::put_BrushColor1(const LONG& lColor) { - return m_pInternal->m_oDocument.put_BrushColor1(lColor); + return m_pInternal->m_oDocument.put_BrushColor1(lColor); } HRESULT CDocxRenderer::get_BrushAlpha1(LONG* lAlpha) { - return m_pInternal->m_oDocument.get_BrushAlpha1(lAlpha); + return m_pInternal->m_oDocument.get_BrushAlpha1(lAlpha); } HRESULT CDocxRenderer::put_BrushAlpha1(const LONG& lAlpha) { - return m_pInternal->m_oDocument.put_BrushAlpha1(lAlpha); + return m_pInternal->m_oDocument.put_BrushAlpha1(lAlpha); } HRESULT CDocxRenderer::get_BrushColor2(LONG* lColor) { - return m_pInternal->m_oDocument.get_BrushColor2(lColor); + return m_pInternal->m_oDocument.get_BrushColor2(lColor); } HRESULT CDocxRenderer::put_BrushColor2(const LONG& lColor) { - return m_pInternal->m_oDocument.put_BrushColor2(lColor); + return m_pInternal->m_oDocument.put_BrushColor2(lColor); } HRESULT CDocxRenderer::get_BrushAlpha2(LONG* lAlpha) { - return m_pInternal->m_oDocument.get_BrushAlpha2(lAlpha); + return m_pInternal->m_oDocument.get_BrushAlpha2(lAlpha); } HRESULT CDocxRenderer::put_BrushAlpha2(const LONG& lAlpha) { - return m_pInternal->m_oDocument.put_BrushAlpha2(lAlpha); + return m_pInternal->m_oDocument.put_BrushAlpha2(lAlpha); } HRESULT CDocxRenderer::get_BrushTexturePath(std::wstring* wsPath) { - return m_pInternal->m_oDocument.get_BrushTexturePath(wsPath); + return m_pInternal->m_oDocument.get_BrushTexturePath(wsPath); } HRESULT CDocxRenderer::put_BrushTexturePath(const std::wstring& wsPath) { - return m_pInternal->m_oDocument.put_BrushTexturePath(wsPath); + return m_pInternal->m_oDocument.put_BrushTexturePath(wsPath); } HRESULT CDocxRenderer::get_BrushTextureMode(LONG* lMode) { - return m_pInternal->m_oDocument.get_BrushTextureMode(lMode); + return m_pInternal->m_oDocument.get_BrushTextureMode(lMode); } HRESULT CDocxRenderer::put_BrushTextureMode(const LONG& lMode) { - return m_pInternal->m_oDocument.put_BrushTextureMode(lMode); + return m_pInternal->m_oDocument.put_BrushTextureMode(lMode); } HRESULT CDocxRenderer::get_BrushTextureAlpha(LONG* lAlpha) { - return m_pInternal->m_oDocument.get_BrushTextureAlpha(lAlpha); + return m_pInternal->m_oDocument.get_BrushTextureAlpha(lAlpha); } HRESULT CDocxRenderer::put_BrushTextureAlpha(const LONG& lAlpha) { - return m_pInternal->m_oDocument.put_BrushTextureAlpha(lAlpha); + return m_pInternal->m_oDocument.put_BrushTextureAlpha(lAlpha); } HRESULT CDocxRenderer::get_BrushLinearAngle(double* dAngle) { - return m_pInternal->m_oDocument.get_BrushLinearAngle(dAngle); + return m_pInternal->m_oDocument.get_BrushLinearAngle(dAngle); } HRESULT CDocxRenderer::put_BrushLinearAngle(const double& dAngle) { - return m_pInternal->m_oDocument.put_BrushLinearAngle(dAngle); + return m_pInternal->m_oDocument.put_BrushLinearAngle(dAngle); } HRESULT CDocxRenderer::BrushRect(const INT& nVal, const double& dLeft, const double& dTop, const double& dWidth, const double& dHeight) { - return m_pInternal->m_oDocument.BrushRect(nVal, dLeft, dTop, dWidth, dHeight); + return m_pInternal->m_oDocument.BrushRect(nVal, dLeft, dTop, dWidth, dHeight); } HRESULT CDocxRenderer::BrushBounds(const double& dLeft, const double& dTop, const double& dWidth, const double& dHeight) { - // TODO: - return S_OK; + return m_pInternal->m_oDocument.BrushBounds(dLeft, dTop, dWidth, dHeight); } HRESULT CDocxRenderer::put_BrushGradientColors(LONG* pColors, double* pPositions, LONG lCount) { - // TODO: - return S_OK; + return m_pInternal->m_oDocument.put_BrushGradientColors(pColors, pPositions, lCount); +} +HRESULT CDocxRenderer::get_BrushTextureImage(Aggplus::CImage** pImage) +{ + *pImage = m_pInternal->m_oDocument.m_oCurrentPage.m_oBrush.Image; + return S_OK; +} +HRESULT CDocxRenderer::put_BrushTextureImage(Aggplus::CImage* pImage) +{ + RELEASEINTERFACE(m_pInternal->m_oDocument.m_oCurrentPage.m_oBrush.Image); + + if (NULL == pImage) + return S_FALSE; + + m_pInternal->m_oDocument.m_oCurrentPage.m_oBrush.Image = pImage; + m_pInternal->m_oDocument.m_oCurrentPage.m_oBrush.Image->AddRef(); + + return S_OK; +} +HRESULT CDocxRenderer::get_BrushTransform(Aggplus::CMatrix& oMatrix) +{ + return S_OK; +} +HRESULT CDocxRenderer::put_BrushTransform(const Aggplus::CMatrix& oMatrix) +{ + return S_OK; } -HRESULT CDocxRenderer::get_BrushTextureImage(Aggplus::CImage** pImage) { return S_OK; } -HRESULT CDocxRenderer::put_BrushTextureImage(Aggplus::CImage* pImage) { return S_OK; } -HRESULT CDocxRenderer::get_BrushTransform(Aggplus::CMatrix& oMatrix) { return S_OK; } -HRESULT CDocxRenderer::put_BrushTransform(const Aggplus::CMatrix& oMatrix) { return S_OK; } -//---------------------------------------------------------------------------------------- -// Функции для работы со шрифтами -//---------------------------------------------------------------------------------------- +void CDocxRenderer::put_BrushGradInfo(void* pGradInfo) +{ + m_pInternal->m_oDocument.put_BrushGradInfo(pGradInfo); +} + HRESULT CDocxRenderer::get_FontName(std::wstring* wsName) { - return m_pInternal->m_oDocument.get_FontName(wsName); + return m_pInternal->m_oDocument.get_FontName(wsName); } HRESULT CDocxRenderer::put_FontName(const std::wstring& wsName) { - return m_pInternal->m_oDocument.put_FontName(wsName); + return m_pInternal->m_oDocument.put_FontName(wsName); } HRESULT CDocxRenderer::get_FontPath(std::wstring* wsPath) { - return m_pInternal->m_oDocument.get_FontPath(wsPath); + return m_pInternal->m_oDocument.get_FontPath(wsPath); } HRESULT CDocxRenderer::put_FontPath(const std::wstring& wsPath) { - return m_pInternal->m_oDocument.put_FontPath(wsPath); + return m_pInternal->m_oDocument.put_FontPath(wsPath); } HRESULT CDocxRenderer::get_FontSize(double* dSize) { - return m_pInternal->m_oDocument.get_FontSize(dSize); + return m_pInternal->m_oDocument.get_FontSize(dSize); } HRESULT CDocxRenderer::put_FontSize(const double& dSize) { - return m_pInternal->m_oDocument.put_FontSize(dSize); + return m_pInternal->m_oDocument.put_FontSize(dSize); } HRESULT CDocxRenderer::get_FontStyle(LONG* lStyle) { - return m_pInternal->m_oDocument.get_FontStyle(lStyle); + return m_pInternal->m_oDocument.get_FontStyle(lStyle); } HRESULT CDocxRenderer::put_FontStyle(const LONG& lStyle) { - return m_pInternal->m_oDocument.put_FontStyle(lStyle); + return m_pInternal->m_oDocument.put_FontStyle(lStyle); } HRESULT CDocxRenderer::get_FontStringGID(INT* bGid) { - return m_pInternal->m_oDocument.get_FontStringGID(bGid); + return m_pInternal->m_oDocument.get_FontStringGID(bGid); } HRESULT CDocxRenderer::put_FontStringGID(const INT& bGid) { - return m_pInternal->m_oDocument.put_FontStringGID(bGid); + return m_pInternal->m_oDocument.put_FontStringGID(bGid); } HRESULT CDocxRenderer::get_FontCharSpace(double* dSpace) { - return m_pInternal->m_oDocument.get_FontCharSpace(dSpace); + return m_pInternal->m_oDocument.get_FontCharSpace(dSpace); } HRESULT CDocxRenderer::put_FontCharSpace(const double& dSpace) { - return m_pInternal->m_oDocument.put_FontCharSpace(dSpace); + return m_pInternal->m_oDocument.put_FontCharSpace(dSpace); } HRESULT CDocxRenderer::get_FontFaceIndex(int* lFaceIndex) { - return m_pInternal->m_oDocument.get_FontFaceIndex(lFaceIndex); + return m_pInternal->m_oDocument.get_FontFaceIndex(lFaceIndex); } HRESULT CDocxRenderer::put_FontFaceIndex(const int& lFaceIndex) { - return m_pInternal->m_oDocument.put_FontFaceIndex(lFaceIndex); + return m_pInternal->m_oDocument.put_FontFaceIndex(lFaceIndex); } -//---------------------------------------------------------------------------------------- -// Функции для вывода текста -//---------------------------------------------------------------------------------------- + HRESULT CDocxRenderer::CommandDrawTextCHAR(const LONG& lUnicode, const double& dX, const double& dY, const double& dW, const double& dH) { - return m_pInternal->m_oDocument.CommandDrawTextCHAR((int)lUnicode, dX, dY, dW, dH); + return m_pInternal->m_oDocument.CommandDrawTextCHAR((int)lUnicode, dX, dY, dW, dH); } HRESULT CDocxRenderer::CommandDrawTextExCHAR(const LONG& lUnicode, const LONG& lGid, const double& dX, const double& dY, const double& dW, const double& dH) { - return m_pInternal->m_oDocument.CommandDrawTextExCHAR((int)lUnicode, (int)lGid, dX, dY, dW, dH); + return m_pInternal->m_oDocument.CommandDrawTextExCHAR((int)lUnicode, (int)lGid, dX, dY, dW, dH); } HRESULT CDocxRenderer::CommandDrawText(const std::wstring& wsUnicodeText, const double& dX, const double& dY, const double& dW, const double& dH) { - return m_pInternal->m_oDocument.CommandDrawText(wsUnicodeText, dX, dY, dW, dH); + return m_pInternal->m_oDocument.CommandDrawText(wsUnicodeText, dX, dY, dW, dH); } HRESULT CDocxRenderer::CommandDrawTextEx(const std::wstring& wsUnicodeText, const unsigned int* pGids, const unsigned int nGidsCount, const double& dX, const double& dY, const double& dW, const double& dH) { - return m_pInternal->m_oDocument.CommandDrawTextEx(wsUnicodeText, pGids, nGidsCount, dX, dY, dW, dH); + return m_pInternal->m_oDocument.CommandDrawTextEx(wsUnicodeText, pGids, nGidsCount, dX, dY, dW, dH); } -//---------------------------------------------------------------------------------------- -// Маркеры команд -//---------------------------------------------------------------------------------------- + HRESULT CDocxRenderer::BeginCommand(const DWORD& lType) { - return m_pInternal->m_oDocument.BeginCommand(lType); + return m_pInternal->m_oDocument.BeginCommand(lType); } HRESULT CDocxRenderer::EndCommand(const DWORD& lType) { - return m_pInternal->m_oDocument.EndCommand(lType); + return m_pInternal->m_oDocument.EndCommand(lType); } -//---------------------------------------------------------------------------------------- -// Функции для работы с патом -//---------------------------------------------------------------------------------------- + HRESULT CDocxRenderer::PathCommandMoveTo(const double& dX, const double& dY) { - return m_pInternal->m_oDocument.PathCommandMoveTo(dX, dY); + return m_pInternal->m_oDocument.PathCommandMoveTo(dX, dY); } HRESULT CDocxRenderer::PathCommandLineTo(const double& dX, const double& dY) { - return m_pInternal->m_oDocument.PathCommandLineTo(dX, dY); + return m_pInternal->m_oDocument.PathCommandLineTo(dX, dY); } HRESULT CDocxRenderer::PathCommandLinesTo(double* pPoints, const int& nCount) { - return m_pInternal->m_oDocument.PathCommandLinesTo(pPoints, nCount); + return m_pInternal->m_oDocument.PathCommandLinesTo(pPoints, nCount); } HRESULT CDocxRenderer::PathCommandCurveTo(const double& dX1, const double& dY1, const double& dX2, const double& dY2, const double& dXe, const double& dYe) { - return m_pInternal->m_oDocument.PathCommandCurveTo(dX1, dY1, dX2, dY2, dXe, dYe); + return m_pInternal->m_oDocument.PathCommandCurveTo(dX1, dY1, dX2, dY2, dXe, dYe); } HRESULT CDocxRenderer::PathCommandCurvesTo(double* pPoints, const int& nCount) { - return m_pInternal->m_oDocument.PathCommandCurvesTo(pPoints, nCount); + return m_pInternal->m_oDocument.PathCommandCurvesTo(pPoints, nCount); } HRESULT CDocxRenderer::PathCommandArcTo(const double& dX, const double& dY, const double& dW, const double& dH, const double& dStartAngle, const double& dSweepAngle) { - return m_pInternal->m_oDocument.PathCommandArcTo(dX, dY, dW, dH, dStartAngle, dSweepAngle); + return m_pInternal->m_oDocument.PathCommandArcTo(dX, dY, dW, dH, dStartAngle, dSweepAngle); } HRESULT CDocxRenderer::PathCommandClose() { - return m_pInternal->m_oDocument.PathCommandClose(); + return m_pInternal->m_oDocument.PathCommandClose(); } HRESULT CDocxRenderer::PathCommandEnd() { - return m_pInternal->m_oDocument.PathCommandEnd(); + return m_pInternal->m_oDocument.PathCommandEnd(); } HRESULT CDocxRenderer::DrawPath(const LONG& lType) { - return m_pInternal->m_oDocument.DrawPath(lType); + return m_pInternal->m_oDocument.DrawPath(lType); } HRESULT CDocxRenderer::PathCommandStart() { - return m_pInternal->m_oDocument.PathCommandStart(); + return m_pInternal->m_oDocument.PathCommandStart(); } HRESULT CDocxRenderer::PathCommandGetCurrentPoint(double* dX, double* dY) { - return m_pInternal->m_oDocument.PathCommandGetCurrentPoint(dX, dY); + return m_pInternal->m_oDocument.PathCommandGetCurrentPoint(dX, dY); } HRESULT CDocxRenderer::PathCommandTextCHAR(const LONG& lUnicode, const double& dX, const double& dY, const double& dW, const double& dH) { - return m_pInternal->m_oDocument.PathCommandTextCHAR((int)lUnicode, dX, dY, dW, dH); + return m_pInternal->m_oDocument.PathCommandTextCHAR((int)lUnicode, dX, dY, dW, dH); } HRESULT CDocxRenderer::PathCommandTextExCHAR(const LONG& lUnicode, const LONG& lGid, const double& dX, const double& dY, const double& dW, const double& dH) { - return m_pInternal->m_oDocument.PathCommandTextExCHAR((int)lUnicode, (int)lGid, dX, dY, dW, dH); + return m_pInternal->m_oDocument.PathCommandTextExCHAR((int)lUnicode, (int)lGid, dX, dY, dW, dH); } HRESULT CDocxRenderer::PathCommandText(const std::wstring& wsUnicodeText, const double& dX, const double& dY, const double& dW, const double& dH) { - return m_pInternal->m_oDocument.PathCommandText(wsUnicodeText, dX, dY, dW, dH); + return m_pInternal->m_oDocument.PathCommandText(wsUnicodeText, dX, dY, dW, dH); } HRESULT CDocxRenderer::PathCommandTextEx(const std::wstring& wsUnicodeText, const unsigned int* pGids, const unsigned int nGidsCount, const double& dX, const double& dY, const double& dW, const double& dH) { - return m_pInternal->m_oDocument.PathCommandTextEx(wsUnicodeText, pGids, nGidsCount, dX, dY, dW, dH); + return m_pInternal->m_oDocument.PathCommandTextEx(wsUnicodeText, pGids, nGidsCount, dX, dY, dW, dH); } -//---------------------------------------------------------------------------------------- -// Функции для вывода изображений -//---------------------------------------------------------------------------------------- + HRESULT CDocxRenderer::DrawImage(IGrObject* pImage, const double& dX, const double& dY, const double& dW, const double& dH) { - return m_pInternal->m_oDocument.DrawImage(pImage, dX, dY, dW, dH); + return m_pInternal->m_oDocument.DrawImage(pImage, dX, dY, dW, dH); } HRESULT CDocxRenderer::DrawImageFromFile(const std::wstring& wsImagePath, const double& dX, const double& dY, const double& dW, const double& dH, const BYTE& nAlpha) { - return m_pInternal->m_oDocument.DrawImageFromFile(wsImagePath,dX, dY, dW, dH); + return m_pInternal->m_oDocument.DrawImageFromFile(wsImagePath,dX, dY, dW, dH); } -//---------------------------------------------------------------------------------------- -// Функции для выставления преобразования -//---------------------------------------------------------------------------------------- + HRESULT CDocxRenderer::SetTransform(const double& dM11, const double& dM12, const double& dM21, const double& dM22, const double& dX, const double& dY) { - return m_pInternal->m_oDocument.SetTransform(dM11, dM12, dM21, dM22, dX, dY); + return m_pInternal->m_oDocument.SetTransform(dM11, dM12, dM21, dM22, dX, dY); } HRESULT CDocxRenderer::GetTransform(double* dM11, double* dM12, double* dM21, double* dM22, double* dX, double* dY) { - return m_pInternal->m_oDocument.GetTransform(dM11, dM12, dM21, dM22, dX, dY); + return m_pInternal->m_oDocument.GetTransform(dM11, dM12, dM21, dM22, dX, dY); } HRESULT CDocxRenderer::ResetTransform() { - return m_pInternal->m_oDocument.ResetTransform(); + return m_pInternal->m_oDocument.ResetTransform(); } -//---------------------------------------------------------------------------------------- -// Тип клипа -//---------------------------------------------------------------------------------------- HRESULT CDocxRenderer::get_ClipMode(LONG* lMode) { - return m_pInternal->m_oDocument.get_ClipMode(lMode); + return m_pInternal->m_oDocument.get_ClipMode(lMode); } HRESULT CDocxRenderer::put_ClipMode(const LONG& lMode) { - return m_pInternal->m_oDocument.put_ClipMode(lMode); + return m_pInternal->m_oDocument.put_ClipMode(lMode); } -//---------------------------------------------------------------------------------------- -// Дополнительные функции -//---------------------------------------------------------------------------------------- HRESULT CDocxRenderer::CommandLong(const LONG& lType, const LONG& lCommand) { - return S_OK; + if (c_nSupportPathTextAsText == lType) + { + NSStructures::CBrush* pBrush = &m_pInternal->m_oDocument.m_oCurrentPage.m_oBrush; + if (c_BrushTypeSolid != pBrush->Type) + return S_FALSE; + + NSStructures::CPen* pPen = &m_pInternal->m_oDocument.m_oCurrentPage.m_oPen; + if (pBrush->Color1 != pPen->Color || pBrush->Alpha1 != pPen->Alpha) + return S_FALSE; + + Aggplus::CMatrix* pTransform = &m_pInternal->m_oDocument.m_oCurrentPage.m_oTransform; + if (std::abs(pTransform->z_Rotation()) > 1.0 || pTransform->sx() < 0 || pTransform->sy() < 0) + return S_FALSE; + + return S_OK; + } + return S_OK; } HRESULT CDocxRenderer::CommandDouble(const LONG& lType, const double& dCommand) { - return S_OK; + return S_OK; } HRESULT CDocxRenderer::CommandString(const LONG& lType, const std::wstring& sCommand) { - return S_OK; + return S_OK; } diff --git a/DocxRenderer/DocxRenderer.h b/DocxRenderer/DocxRenderer.h index 96f16c9ead0..18aa23a8dec 100644 --- a/DocxRenderer/DocxRenderer.h +++ b/DocxRenderer/DocxRenderer.h @@ -43,157 +43,144 @@ #define DOCXRENDERER_DECL_EXPORT Q_DECL_EXPORT #endif +#include "convert_params.h" +#include "src/logic/managers/ExternalImageStorage.h" + class CDocxRenderer_Private; class DOCXRENDERER_DECL_EXPORT CDocxRenderer : public IRenderer { - public: - CDocxRenderer(NSFonts::IApplicationFonts* pAppFonts); - virtual ~CDocxRenderer(); - - HRESULT CreateNewFile(const std::wstring& wsPath, bool bIsOutCompress = true); - HRESULT Close(); - - HRESULT SetTempFolder(const std::wstring& wsPath); - //---------------------------------------------------------------------------------------- - // Тип рендерера - //---------------------------------------------------------------------------------------- - virtual HRESULT get_Type(LONG* lType); - //---------------------------------------------------------------------------------------- - // Функции для работы со страницей - //---------------------------------------------------------------------------------------- - virtual HRESULT NewPage(); - virtual HRESULT get_Height(double* dHeight); - virtual HRESULT put_Height(const double& dHeight); - virtual HRESULT get_Width(double* dWidth); - virtual HRESULT put_Width(const double& dWidth); - virtual HRESULT get_DpiX(double* dDpiX); - virtual HRESULT get_DpiY(double* dDpiY); - //---------------------------------------------------------------------------------------- - // Функции для работы с Pen - //---------------------------------------------------------------------------------------- - virtual HRESULT get_PenColor(LONG* lColor); - virtual HRESULT put_PenColor(const LONG& lColor); - virtual HRESULT get_PenAlpha(LONG* lAlpha); - virtual HRESULT put_PenAlpha(const LONG& lAlpha); - virtual HRESULT get_PenSize(double* dSize); - virtual HRESULT put_PenSize(const double& dSize); - virtual HRESULT get_PenDashStyle(BYTE* nDashStyle); - virtual HRESULT put_PenDashStyle(const BYTE& nDashStyle); - virtual HRESULT get_PenLineStartCap(BYTE* nCapStyle); - virtual HRESULT put_PenLineStartCap(const BYTE& nCapStyle); - virtual HRESULT get_PenLineEndCap(BYTE* nCapStyle); - virtual HRESULT put_PenLineEndCap(const BYTE& nCapStyle); - virtual HRESULT get_PenLineJoin(BYTE* nJoinStyle); - virtual HRESULT put_PenLineJoin(const BYTE& nJoinStyle); - virtual HRESULT get_PenDashOffset(double* dOffset); - virtual HRESULT put_PenDashOffset(const double& dOffset); - virtual HRESULT get_PenAlign(LONG* lAlign); - virtual HRESULT put_PenAlign(const LONG& lAlign); - virtual HRESULT get_PenMiterLimit(double* dMiter); - virtual HRESULT put_PenMiterLimit(const double& dMiter); - virtual HRESULT PenDashPattern(double* pPattern, LONG lCount); - //---------------------------------------------------------------------------------------- - // Функции для работы с Brush - //---------------------------------------------------------------------------------------- - virtual HRESULT get_BrushType(LONG* lType); - virtual HRESULT put_BrushType(const LONG& lType); - virtual HRESULT get_BrushColor1(LONG* lColor); - virtual HRESULT put_BrushColor1(const LONG& lColor); - virtual HRESULT get_BrushAlpha1(LONG* lAlpha); - virtual HRESULT put_BrushAlpha1(const LONG& lAlpha); - virtual HRESULT get_BrushColor2(LONG* lColor); - virtual HRESULT put_BrushColor2(const LONG& lColor); - virtual HRESULT get_BrushAlpha2(LONG* lAlpha); - virtual HRESULT put_BrushAlpha2(const LONG& lAlpha); - virtual HRESULT get_BrushTexturePath(std::wstring* wsPath); - virtual HRESULT put_BrushTexturePath(const std::wstring& wsPath); - virtual HRESULT get_BrushTextureMode(LONG* lMode); - virtual HRESULT put_BrushTextureMode(const LONG& lMode); - virtual HRESULT get_BrushTextureAlpha(LONG* lAlpha); - virtual HRESULT put_BrushTextureAlpha(const LONG& lAlpha); - virtual HRESULT get_BrushLinearAngle(double* dAngle); - virtual HRESULT put_BrushLinearAngle(const double& dAngle); - virtual HRESULT BrushRect(const INT& nVal, const double& dLeft, const double& dTop, const double& dWidth, const double& dHeight); - virtual HRESULT BrushBounds(const double& dLeft, const double& dTop, const double& dWidth, const double& dHeight); - virtual HRESULT put_BrushGradientColors(LONG* pColors, double* pPositions, LONG lCount); - virtual HRESULT get_BrushTextureImage(Aggplus::CImage** pImage); - virtual HRESULT put_BrushTextureImage(Aggplus::CImage* pImage); - virtual HRESULT get_BrushTransform(Aggplus::CMatrix& oMatrix); - virtual HRESULT put_BrushTransform(const Aggplus::CMatrix& oMatrix); - //---------------------------------------------------------------------------------------- - // Функции для работы со шрифтами - //---------------------------------------------------------------------------------------- - virtual HRESULT get_FontName(std::wstring* wsName); - virtual HRESULT put_FontName(const std::wstring& wsName); - virtual HRESULT get_FontPath(std::wstring* wsPath); - virtual HRESULT put_FontPath(const std::wstring& wsPath); - virtual HRESULT get_FontSize(double* dSize); - virtual HRESULT put_FontSize(const double& dSize); - virtual HRESULT get_FontStyle(LONG* lStyle); - virtual HRESULT put_FontStyle(const LONG& lStyle); - virtual HRESULT get_FontStringGID(INT* bGid); - virtual HRESULT put_FontStringGID(const INT& bGid); - virtual HRESULT get_FontCharSpace(double* dSpace); - virtual HRESULT put_FontCharSpace(const double& dSpace); - virtual HRESULT get_FontFaceIndex(int* lFaceIndex); - virtual HRESULT put_FontFaceIndex(const int& lFaceIndex); - //---------------------------------------------------------------------------------------- - // Функции для вывода текста - //---------------------------------------------------------------------------------------- - virtual HRESULT CommandDrawTextCHAR (const LONG& lUnicode, const double& dX, const double& dY, const double& dW, const double& dH); - virtual HRESULT CommandDrawTextExCHAR(const LONG& lUnicode, const LONG& lGid, const double& dX, const double& dY, const double& dW, const double& dH); - virtual HRESULT CommandDrawText (const std::wstring& wsUnicodeText, const double& dX, const double& dY, const double& dW, const double& dH); - virtual HRESULT CommandDrawTextEx (const std::wstring& wsUnicodeText, const unsigned int* pGids, const unsigned int nGidsCount, const double& dX, const double& dY, const double& dW, const double& dH); - //---------------------------------------------------------------------------------------- - // Маркеры команд - //---------------------------------------------------------------------------------------- - virtual HRESULT BeginCommand(const DWORD& lType); - virtual HRESULT EndCommand(const DWORD& lType); - //---------------------------------------------------------------------------------------- - // Функции для работы с патом - //---------------------------------------------------------------------------------------- - virtual HRESULT PathCommandMoveTo(const double& dX, const double& dY); - virtual HRESULT PathCommandLineTo(const double& dX, const double& dY); - virtual HRESULT PathCommandLinesTo(double* pPoints, const int& nCount); - virtual HRESULT PathCommandCurveTo(const double& dX1, const double& dY1, const double& dX2, const double& dY2, const double& dXe, const double& dYe); - virtual HRESULT PathCommandCurvesTo(double* pPoints, const int& nCount); - virtual HRESULT PathCommandArcTo(const double& dX, const double& dY, const double& dW, const double& dH, const double& dStartAngle, const double& dSweepAngle); - virtual HRESULT PathCommandClose(); - virtual HRESULT PathCommandEnd(); - virtual HRESULT DrawPath(const LONG& lType); - virtual HRESULT PathCommandStart(); - virtual HRESULT PathCommandGetCurrentPoint(double* dX, double* dY); - virtual HRESULT PathCommandTextCHAR (const LONG& lUnicode, const double& dX, const double& dY, const double& dW, const double& dH); - virtual HRESULT PathCommandTextExCHAR(const LONG& lUnicode, const LONG& lGid, const double& dX, const double& dY, const double& dW, const double& dH); - virtual HRESULT PathCommandText (const std::wstring& wsUnicodeText, const double& dX, const double& dY, const double& dW, const double& dH); - virtual HRESULT PathCommandTextEx (const std::wstring& wsUnicodeText, const unsigned int* pGids, const unsigned int nGidsCount, const double& dX, const double& dY, const double& dW, const double& dH); - //---------------------------------------------------------------------------------------- - // Функции для вывода изображений - //---------------------------------------------------------------------------------------- - virtual HRESULT DrawImage(IGrObject* pImage, const double& dX, const double& dY, const double& dW, const double& dH); - virtual HRESULT DrawImageFromFile(const std::wstring& wsImagePath, const double& dX, const double& dY, const double& dW, const double& dH, const BYTE& nAlpha = 255); - //---------------------------------------------------------------------------------------- - // Функции для выставления преобразования - //---------------------------------------------------------------------------------------- - virtual HRESULT SetTransform(const double& dM11, const double& dM12, const double& dM21, const double& dM22, const double& dX, const double& dY); - virtual HRESULT GetTransform(double* dM11, double* dM12, double* dM21, double* dM22, double* dX, double* dY); - virtual HRESULT ResetTransform(); - //---------------------------------------------------------------------------------------- - // Тип клипа - //---------------------------------------------------------------------------------------- - virtual HRESULT get_ClipMode(LONG* lMode); - virtual HRESULT put_ClipMode(const LONG& lMode); - //---------------------------------------------------------------------------------------- - // Дополнительные функции - //---------------------------------------------------------------------------------------- - virtual HRESULT CommandLong(const LONG& lType, const LONG& lCommand); - virtual HRESULT CommandDouble(const LONG& lType, const double& dCommand); - virtual HRESULT CommandString(const LONG& lType, const std::wstring& sCommand); - - // методы, которыми будет пользоваться конвертер - HRESULT SetTextAssociationType(const NSDocxRenderer::TextAssociationType& eType); - int Convert(IOfficeDrawingFile* pFile, const std::wstring& sDstFile, bool bIsOutCompress = true); - - private: - CDocxRenderer_Private* m_pInternal; +public: + CDocxRenderer(NSFonts::IApplicationFonts* pAppFonts); + virtual ~CDocxRenderer(); + + HRESULT Compress(); + HRESULT SetTempFolder(const std::wstring& wsPath); + + virtual HRESULT get_Type(LONG* lType); + + virtual HRESULT NewPage(); + virtual HRESULT get_Height(double* dHeight); + virtual HRESULT put_Height(const double& dHeight); + virtual HRESULT get_Width(double* dWidth); + virtual HRESULT put_Width(const double& dWidth); + virtual HRESULT get_DpiX(double* dDpiX); + virtual HRESULT get_DpiY(double* dDpiY); + + virtual HRESULT get_PenColor(LONG* lColor); + virtual HRESULT put_PenColor(const LONG& lColor); + virtual HRESULT get_PenAlpha(LONG* lAlpha); + virtual HRESULT put_PenAlpha(const LONG& lAlpha); + virtual HRESULT get_PenSize(double* dSize); + virtual HRESULT put_PenSize(const double& dSize); + virtual HRESULT get_PenDashStyle(BYTE* nDashStyle); + virtual HRESULT put_PenDashStyle(const BYTE& nDashStyle); + virtual HRESULT get_PenLineStartCap(BYTE* nCapStyle); + virtual HRESULT put_PenLineStartCap(const BYTE& nCapStyle); + virtual HRESULT get_PenLineEndCap(BYTE* nCapStyle); + virtual HRESULT put_PenLineEndCap(const BYTE& nCapStyle); + virtual HRESULT get_PenLineJoin(BYTE* nJoinStyle); + virtual HRESULT put_PenLineJoin(const BYTE& nJoinStyle); + virtual HRESULT get_PenDashOffset(double* dOffset); + virtual HRESULT put_PenDashOffset(const double& dOffset); + virtual HRESULT get_PenAlign(LONG* lAlign); + virtual HRESULT put_PenAlign(const LONG& lAlign); + virtual HRESULT get_PenMiterLimit(double* dMiter); + virtual HRESULT put_PenMiterLimit(const double& dMiter); + virtual HRESULT PenDashPattern(double* pPattern, LONG lCount); + + virtual HRESULT get_BrushType(LONG* lType); + virtual HRESULT put_BrushType(const LONG& lType); + virtual HRESULT get_BrushColor1(LONG* lColor); + virtual HRESULT put_BrushColor1(const LONG& lColor); + virtual HRESULT get_BrushAlpha1(LONG* lAlpha); + virtual HRESULT put_BrushAlpha1(const LONG& lAlpha); + virtual HRESULT get_BrushColor2(LONG* lColor); + virtual HRESULT put_BrushColor2(const LONG& lColor); + virtual HRESULT get_BrushAlpha2(LONG* lAlpha); + virtual HRESULT put_BrushAlpha2(const LONG& lAlpha); + virtual HRESULT get_BrushTexturePath(std::wstring* wsPath); + virtual HRESULT put_BrushTexturePath(const std::wstring& wsPath); + virtual HRESULT get_BrushTextureMode(LONG* lMode); + virtual HRESULT put_BrushTextureMode(const LONG& lMode); + virtual HRESULT get_BrushTextureAlpha(LONG* lAlpha); + virtual HRESULT put_BrushTextureAlpha(const LONG& lAlpha); + virtual HRESULT get_BrushLinearAngle(double* dAngle); + virtual HRESULT put_BrushLinearAngle(const double& dAngle); + + virtual HRESULT BrushRect(const INT& nVal, const double& dLeft, const double& dTop, const double& dWidth, const double& dHeight); + virtual HRESULT BrushBounds(const double& dLeft, const double& dTop, const double& dWidth, const double& dHeight); + + virtual HRESULT put_BrushGradientColors(LONG* pColors, double* pPositions, LONG lCount); + virtual HRESULT get_BrushTextureImage(Aggplus::CImage** pImage); + virtual HRESULT put_BrushTextureImage(Aggplus::CImage* pImage); + virtual HRESULT get_BrushTransform(Aggplus::CMatrix& oMatrix); + virtual HRESULT put_BrushTransform(const Aggplus::CMatrix& oMatrix); + virtual void put_BrushGradInfo(void* pGradInfo) override; + + virtual HRESULT get_FontName(std::wstring* wsName); + virtual HRESULT put_FontName(const std::wstring& wsName); + virtual HRESULT get_FontPath(std::wstring* wsPath); + virtual HRESULT put_FontPath(const std::wstring& wsPath); + virtual HRESULT get_FontSize(double* dSize); + virtual HRESULT put_FontSize(const double& dSize); + virtual HRESULT get_FontStyle(LONG* lStyle); + virtual HRESULT put_FontStyle(const LONG& lStyle); + virtual HRESULT get_FontStringGID(INT* bGid); + virtual HRESULT put_FontStringGID(const INT& bGid); + virtual HRESULT get_FontCharSpace(double* dSpace); + virtual HRESULT put_FontCharSpace(const double& dSpace); + virtual HRESULT get_FontFaceIndex(int* lFaceIndex); + virtual HRESULT put_FontFaceIndex(const int& lFaceIndex); + + virtual HRESULT CommandDrawTextCHAR(const LONG& lUnicode, const double& dX, const double& dY, const double& dW, const double& dH); + virtual HRESULT CommandDrawTextExCHAR(const LONG& lUnicode, const LONG& lGid, const double& dX, const double& dY, const double& dW, const double& dH); + virtual HRESULT CommandDrawText(const std::wstring& wsUnicodeText, const double& dX, const double& dY, const double& dW, const double& dH); + virtual HRESULT CommandDrawTextEx(const std::wstring& wsUnicodeText, const unsigned int* pGids, const unsigned int nGidsCount, const double& dX, const double& dY, const double& dW, const double& dH); + + virtual HRESULT BeginCommand(const DWORD& lType); + virtual HRESULT EndCommand(const DWORD& lType); + + virtual HRESULT PathCommandMoveTo(const double& dX, const double& dY); + virtual HRESULT PathCommandLineTo(const double& dX, const double& dY); + virtual HRESULT PathCommandLinesTo(double* pPoints, const int& nCount); + virtual HRESULT PathCommandCurveTo(const double& dX1, const double& dY1, const double& dX2, const double& dY2, const double& dXe, const double& dYe); + virtual HRESULT PathCommandCurvesTo(double* pPoints, const int& nCount); + virtual HRESULT PathCommandArcTo(const double& dX, const double& dY, const double& dW, const double& dH, const double& dStartAngle, const double& dSweepAngle); + virtual HRESULT PathCommandClose(); + virtual HRESULT PathCommandEnd(); + virtual HRESULT DrawPath(const LONG& lType); + virtual HRESULT PathCommandStart(); + virtual HRESULT PathCommandGetCurrentPoint(double* dX, double* dY); + virtual HRESULT PathCommandTextCHAR(const LONG& lUnicode, const double& dX, const double& dY, const double& dW, const double& dH); + virtual HRESULT PathCommandTextExCHAR(const LONG& lUnicode, const LONG& lGid, const double& dX, const double& dY, const double& dW, const double& dH); + virtual HRESULT PathCommandText(const std::wstring& wsUnicodeText, const double& dX, const double& dY, const double& dW, const double& dH); + virtual HRESULT PathCommandTextEx (const std::wstring& wsUnicodeText, const unsigned int* pGids, const unsigned int nGidsCount, const double& dX, const double& dY, const double& dW, const double& dH); + + virtual HRESULT DrawImage(IGrObject* pImage, const double& dX, const double& dY, const double& dW, const double& dH); + virtual HRESULT DrawImageFromFile(const std::wstring& wsImagePath, const double& dX, const double& dY, const double& dW, const double& dH, const BYTE& nAlpha = 255); + + virtual HRESULT SetTransform(const double& dM11, const double& dM12, const double& dM21, const double& dM22, const double& dX, const double& dY); + virtual HRESULT GetTransform(double* dM11, double* dM12, double* dM21, double* dM22, double* dX, double* dY); + virtual HRESULT ResetTransform(); + + virtual HRESULT get_ClipMode(LONG* lMode); + virtual HRESULT put_ClipMode(const LONG& lMode); + + virtual HRESULT CommandLong(const LONG& lType, const LONG& lCommand); + virtual HRESULT CommandDouble(const LONG& lType, const double& dCommand); + virtual HRESULT CommandString(const LONG& lType, const std::wstring& sCommand); + + virtual HRESULT IsSupportAdvancedCommand(const IAdvancedCommand::AdvancedCommandType& type); + virtual HRESULT AdvancedCommand(IAdvancedCommand* command); + + // методы, которыми будет пользоваться конвертер + HRESULT SetTextAssociationType(const NSDocxRenderer::TextAssociationType& eType); + int Convert(IOfficeDrawingFile* pFile, const std::wstring& sDstFile, bool bIsOutCompress = true); + std::vector ScanPage(IOfficeDrawingFile* pFile, size_t nPage); + std::vector ScanPagePptx(IOfficeDrawingFile* pFile, size_t nPage); + + void SetExternalImageStorage(NSDocxRenderer::IImageStorage* pStorage); +private: + CDocxRenderer_Private* m_pInternal; + void DrawPage(IOfficeDrawingFile* pFile, size_t nPage); }; diff --git a/DocxRenderer/DocxRenderer.pro b/DocxRenderer/DocxRenderer.pro index d63e6d22a56..5b4dc732ef5 100644 --- a/DocxRenderer/DocxRenderer.pro +++ b/DocxRenderer/DocxRenderer.pro @@ -4,6 +4,7 @@ VERSION = 1.0.0.4 TARGET = DocxRenderer TEMPLATE = lib +CONFIG += c++11 CONFIG += shared CONFIG += plugin @@ -15,59 +16,66 @@ DEFINES += DOCXRENDERER_USE_DYNAMIC_LIBRARY ADD_DEPENDENCY(UnicodeConverter, kernel, graphics) -core_windows { +# Flag for disable full document creation. Enabled in pdf editor +#CONFIG += disable_full_document_creation -LIBS += -lgdi32 \ - -ladvapi32 \ - -luser32 \ - -lshell32 +core_windows { +LIBS += \ + -lgdi32 \ + -ladvapi32 \ + -luser32 \ + -lshell32 } HEADERS += \ - src/logic/elements/BaseItem.h \ - src/logic/elements/ContText.h \ - src/logic/elements/Image.h \ - src/logic/elements/OldShape.h \ - src/logic/elements/Paragraph.h \ - src/logic/elements/Shape.h \ - src/logic/elements/TextLine.h \ - src/logic/managers/ImageManager.h \ - src/logic/managers/FontManager.h \ - src/logic/managers/FontManagerBase.h \ - src/logic/managers/StyleManager.h \ - src/logic/styles/BaseStyle.h \ - src/logic/styles/FontStyle.h \ - src/resources/ColorTable.h \ - src/resources/Constants.h \ - src/resources/ImageInfo.h \ - src/resources/LinesTable.h \ - src/resources/SingletonTemplate.h \ - src/resources/SortElements.h \ - src/resources/VectorGraphics.h \ - src/resources/resources.h \ - src/resources/utils.h \ - src/logic/Page.h \ - src/logic/Document.h \ - DocxRenderer.h + src/logic/elements/BaseItem.h \ + src/logic/elements/ContText.h \ + src/logic/elements/Paragraph.h \ + src/logic/elements/Shape.h \ + src/logic/elements/Table.h \ + src/logic/elements/TextLine.h \ + src/logic/managers/ExternalImageStorage.h \ + src/logic/managers/FontStyleManager.h \ + src/logic/managers/ImageManager.h \ + src/logic/managers/FontManager.h \ + src/logic/managers/ParagraphStyleManager.h \ + src/logic/styles/FontStyle.h \ + src/logic/styles/ParagraphStyle.h \ + src/resources/ColorTable.h \ + src/resources/Constants.h \ + src/resources/ImageInfo.h \ + src/resources/LinesTable.h \ + src/resources/VectorGraphics.h \ + src/resources/resources.h \ + src/resources/utils.h \ + src/logic/Page.h \ + src/logic/Document.h \ + DocxRenderer.h SOURCES += \ - src/logic/elements/BaseItem.cpp \ - src/logic/elements/ContText.cpp \ - src/logic/elements/Image.cpp \ - src/logic/elements/OldShape.cpp \ - src/logic/elements/Paragraph.cpp \ - src/logic/elements/Shape.cpp \ - src/logic/elements/TextLine.cpp \ - src/logic/managers/FontManager.cpp \ - src/logic/managers/FontManagerBase.cpp \ - src/logic/managers/ImageManager.cpp \ - src/logic/managers/StyleManager.cpp \ - src/logic/styles/FontStyle.cpp \ - src/logic/Page.cpp \ - src/logic/Document.cpp \ - src/resources/VectorGraphics.cpp \ - src/resources/resources.cpp \ - DocxRenderer.cpp + src/logic/elements/BaseItem.cpp \ + src/logic/elements/ContText.cpp \ + src/logic/elements/Paragraph.cpp \ + src/logic/elements/Shape.cpp \ + src/logic/elements/Table.cpp \ + src/logic/elements/TextLine.cpp \ + src/logic/managers/FontManager.cpp \ + src/logic/managers/FontStyleManager.cpp \ + src/logic/managers/ImageManager.cpp \ + src/logic/managers/ParagraphStyleManager.cpp \ + src/logic/styles/FontStyle.cpp \ + src/logic/Page.cpp \ + src/logic/Document.cpp \ + src/logic/styles/ParagraphStyle.cpp \ + src/resources/VectorGraphics.cpp \ + DocxRenderer.cpp + +disable_full_document_creation { + DEFINES += DISABLE_FULL_DOCUMENT_CREATION +} else { + SOURCES += \ + src/resources/resources.cpp +} DISTFILES += \ - readme.md + readme.md diff --git a/DocxRenderer/convert_params.h b/DocxRenderer/convert_params.h index 79e277becb5..a0d5caef180 100644 --- a/DocxRenderer/convert_params.h +++ b/DocxRenderer/convert_params.h @@ -33,12 +33,13 @@ namespace NSDocxRenderer { - enum TextAssociationType - { - tatBlockChar = 0, // Каждый символ во фрейме - tatBlockLine = 1, // Каждая линия - параграф во фрейме. Линии могут объединяться в рамках одного блока. - tatPlainLine = 2, // Каждая линия - параграф обычный - tatShapeLine = 3, // Каждая линия - параграф в шейпе. Линии могут объединяться в рамках одного блока. - tatPlainParagraph = 4 // Линии объединяются в параграфы - }; + enum class TextAssociationType + { + tatBlockChar = 0, // Каждый символ во фрейме + tatBlockLine = 1, // Каждая линия - параграф во фрейме. Линии могут объединяться в рамках одного блока. + tatPlainLine = 2, // Каждая линия - параграф обычный + tatShapeLine = 3, // Каждая линия - параграф в шейпе. Линии могут объединяться в рамках одного блока. + tatPlainParagraph = 4, // Все линии объединяются в параграфы + tatParagraphToShape = 5 // Параграфы записываем в шейпы + }; } diff --git a/DocxRenderer/readme.md b/DocxRenderer/readme.md index af6b4370148..dfaddbc3823 100644 --- a/DocxRenderer/readme.md +++ b/DocxRenderer/readme.md @@ -1,3 +1,5 @@ +Логика описана в CPage::ProcessingAndRecordingOfPageData + I Этап 1. Собираются шейпы с векторной графикой (DrawPath -> m_arShapes) @@ -5,42 +7,33 @@ I Этап - определяется тип шейпа VectorTexture или VectorGraphics - первоначально определяем положение на стронице (перед текстом/позади текста - пока плохо работает, когда удалялись белые прямоугольники было лучше) - задаются геометрические параметры - - определяется тип графики (Rectangle, Curve, ComplicatedFigure, NoGraphics) и подтип (LongDash, Dash, Dot, Wave) + - определяется тип графики (Rectangle, Curve, ComplicatedFigure, NoGraphics) и подтип (LongDash, Dash, Dot, Wave) 2. Собираются шейпы-картинки (WriteImage -> m_arImages) - задаются геометрические параметры и тип шейпа Picture -3. Собираются буквы (CollectTextData -> m_arSymbol) +3. Собираются буквы и сразу распределются по текстовым линиям. Отдельно собираются DiacriticalSymbol (CollectTextData -> m_arTextLine, m_arDiacriticalSymbol) - отбрасываем все пробелы (нужно будет добавить доп юникоды для других типов пробелов) - работа FontManager - задаются геометрические параметры - - генерим или проверяем на наличие стиль (коприуются и анализируются текущие Font, Brush, PickFontName, PickFontStyle) + - генерим или проверяем на наличие стиль (копируются и анализируются текущие Font, Brush, PickFontName, PickFontStyle) II Этап Собрали все объекты для текущей страницы. Начинаем анализ. -1. Анализируем графику - AnalyzeCollectedShapes() +1. Анализируем графику - AnalyzeCollectedShapes() + - BuildTables(); - собираем таблицы из шейпов (в разработке) - DetermineLinesType() - превращаем шейпы в горизонтальные линии в зависимости от геометрии, удаляем обработанные шейпы, определяем тип полученной линии на основании типа графики (Rectangle, Curve, ComplicatedFigure, NoGraphics) и подтипа (LongDash, Dash, Dot, Wave). (2 вложенных цикла m_arShapes - m_arShapes с сортировкой вектора) -2. AnalyzeCollectedSymbols() - добавляем свойства каждому символу отдельно +2. AnalyzeCollectedTextLines() - добавляем свойства каждому символу отдельно - Определяем взаимотношения между символами - FontEffects, VertAlignTypeBetweenConts, IsDuplicate (2 вложенных цикла m_arSymbol - m_arSymbol) (удаляем отработанные символы) - DetermineStrikeoutsUnderlinesHighlights() - определяем взаимоотношения между графикой и символами Strikeouts, Underlines, Highlights, FontEffect (2 вложенных цикла m_arShapes - m_arSymbol) (удаляем отработанные шейпы) - -III Этап - AnalyzeLines() - Все свойства получены, можно собирать линии - -1. BuildLines() - сборка линий, создаются новый линии со своими векторами символов/слов/предложений, (1 цикл m_arSymbol), - - собирается вектор m_arTextLine - - задаются геометрические параметры линии - - определяется отношение VertAlign между линиями - - определяется количество линий-дубликатов -2. Сортировка линий по высоте -3. Сшиваются линии с VertAlign (1 цикл m_arTextLine), -4. CalculateWidth () - Высчитываем ширину линии (2 вложенных цикла m_arTextLine - m_arConts) -5. MergeConts() - Сшиваем буквы/слова/предложения в строке с одним стилем (2 вложенных цикла m_arTextLine - m_arConts) -6. DetermineDominantGraphics() - нужно, чтобы выделить шейп, который будет использоваться в качестве шейдинга параграфа (2 вложенных цикла m_arTextLine - m_arConts) -7. DeleteTextClipPage() - удаление линий вне страницы (1 цикл m_arTextLine) - -IV Этап BuildByTypePlainParagraph() - Распределение линий по параграфам и шейпам + - AddDiacriticalSymbols() - добавляем DiacriticalSymbol + - MergeLinesByVertAlignType() - объединяем линии с определенными eVertAlignType + - DeleteTextClipPage() - удаление линий вне страницы (1 цикл m_arTextLine) + - DetermineTextColumns() - определяем колонки текста и добавляем в таблицу (в разработке) + - BuildLines() - собираем из символов слова, добавляем пробелы + - DetermineDominantGraphics() - нужно, чтобы выделить шейп, который будет использоваться в качестве шейдинга параграфа (2 вложенных цикла m_arTextLine - m_arConts) + - BuildParagraphes() - собираем из текстовых строк параграфы/шейпы и добавляем в m_arOutputObjects -V Этап ToXml +III Этап ToXml diff --git a/DocxRenderer/src/logic/BaseItem.cpp b/DocxRenderer/src/logic/BaseItem.cpp deleted file mode 100644 index 9bd43be79aa..00000000000 --- a/DocxRenderer/src/logic/BaseItem.cpp +++ /dev/null @@ -1,126 +0,0 @@ -#include "BaseItem.h" -#include "../resources/Constants.h" -#include - -namespace NSDocxRenderer -{ - CBaseItem& CBaseItem::operator=(const CBaseItem& oSrc) - { - if (this == &oSrc) - { - return *this; - } - - m_eType = oSrc.m_eType; - m_bIsNotNecessaryToUse = oSrc.m_bIsNotNecessaryToUse; - - m_dLeft = oSrc.m_dLeft; - m_dTop = oSrc.m_dTop; - m_dWidth = oSrc.m_dWidth; - m_dHeight = oSrc.m_dHeight; - m_dBaselinePos = oSrc.m_dBaselinePos; - m_dRight = oSrc.m_dRight; - - return *this; - } - - bool CBaseItem::IsBigger(const CBaseItem* oSrc) - { - return (m_dLeft > oSrc->m_dLeft) ? true : false; - } - - bool CBaseItem::IsBiggerOrEqual(const CBaseItem* oSrc) - { - return (m_dLeft >= oSrc->m_dLeft) ? true : false; - } - - eVerticalCrossingType CBaseItem::GetVerticalCrossingType(const CBaseItem* oSrc) - { - if (m_dTop > oSrc->m_dTop && m_dBaselinePos < oSrc->m_dBaselinePos) - { - return eVerticalCrossingType::vctCurrentInsideNext; - } - else if (m_dTop < oSrc->m_dTop && m_dBaselinePos > oSrc->m_dBaselinePos) - { - return eVerticalCrossingType::vctCurrentOutsideNext; - } - else if (m_dTop < oSrc->m_dTop && m_dBaselinePos < oSrc->m_dBaselinePos && m_dBaselinePos > oSrc->m_dTop) - { - return eVerticalCrossingType::vctCurrentAboveNext; - } - else if (m_dTop > oSrc->m_dTop && m_dBaselinePos > oSrc->m_dBaselinePos && m_dTop < oSrc->m_dBaselinePos) - { - return eVerticalCrossingType::vctCurrentBelowNext; - } - else if (m_dTop == oSrc->m_dTop && m_dBaselinePos == oSrc->m_dBaselinePos && - m_dLeft == oSrc->m_dLeft && m_dRight == oSrc->m_dRight) - { - return eVerticalCrossingType::vctDublicate; - } - else if (fabs(m_dTop - oSrc->m_dTop) < c_dTHE_SAME_STRING_Y_PRECISION_MM) - { - return eVerticalCrossingType::vctTopBordersMatch; - } - else if (fabs(m_dBaselinePos - oSrc->m_dBaselinePos) < c_dTHE_SAME_STRING_Y_PRECISION_MM) - { - return eVerticalCrossingType::vctBottomBordersMatch; - } - else if (m_dBaselinePos < oSrc->m_dTop) - { - return eVerticalCrossingType::vctNoCrossingCurrentAboveNext; - } - else if (m_dTop > oSrc->m_dBaselinePos) - { - return eVerticalCrossingType::vctNoCrossingCurrentBelowNext; - } - else - { - return eVerticalCrossingType::vctUnknown; - } - } - - eHorizontalCrossingType CBaseItem::GetHorizontalCrossingType(const CBaseItem* oSrc) - { - if (m_dLeft > oSrc->m_dLeft && m_dRight < oSrc->m_dRight) - { - return eHorizontalCrossingType::hctCurrentInsideNext; - } - else if (m_dLeft < oSrc->m_dLeft && m_dRight > oSrc->m_dRight) - { - return eHorizontalCrossingType::hctCurrentOutsideNext; - } - else if (m_dLeft < oSrc->m_dLeft && m_dRight < oSrc->m_dRight && m_dRight > oSrc->m_dLeft) - { - return eHorizontalCrossingType::hctCurrentLeftOfNext; - } - else if (m_dLeft > oSrc->m_dLeft && m_dRight > oSrc->m_dRight && m_dLeft < oSrc->m_dRight) - { - return eHorizontalCrossingType::hctCurrentRightOfNext; - } - else if (m_dLeft == oSrc->m_dLeft && m_dRight == oSrc->m_dRight && - m_dTop == oSrc->m_dTop && m_dBaselinePos == oSrc->m_dBaselinePos) - { - return eHorizontalCrossingType::hctDublicate; - } - else if (fabs(m_dLeft - oSrc->m_dLeft) < c_dTHE_SAME_STRING_Y_PRECISION_MM) - { - return eHorizontalCrossingType::hctLeftBordersMatch; - } - else if (fabs(m_dRight - oSrc->m_dRight) < c_dTHE_SAME_STRING_Y_PRECISION_MM) - { - return eHorizontalCrossingType::hctRightBordersMatch; - } - else if (m_dRight < oSrc->m_dLeft) - { - return eHorizontalCrossingType::hctNoCrossingCurrentLeftOfNext; - } - else if (m_dLeft > oSrc->m_dRight) - { - return eHorizontalCrossingType::hctNoCrossingCurrentRightOfNext; - } - else - { - return eHorizontalCrossingType::hctUnknown; - } - } -} diff --git a/DocxRenderer/src/logic/Document.cpp b/DocxRenderer/src/logic/Document.cpp index cf4e77a3fa8..a2c73e2a9fd 100644 --- a/DocxRenderer/src/logic/Document.cpp +++ b/DocxRenderer/src/logic/Document.cpp @@ -1,1216 +1,1218 @@ #include "Document.h" +#include "../../../DesktopEditor/common/StringExt.h" + +#ifndef DISABLE_FULL_DOCUMENT_CREATION +#include "./../resources/resources.h" +#endif + +#define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x))) +#define CLAMP_ALPHA(x) CLAMP(x, 0, 255) + namespace NSDocxRenderer { - void WriteImageToWriter(NSStringUtils::CStringBuilder& oWriter, const std::shared_ptr& info) - { - oWriter.WriteString(L"m_nId); - oWriter.WriteString(L"\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image\" Target=\"media/"); - oWriter.WriteString(info->m_strFileName); - oWriter.WriteString(L"\"/>"); - } - - CDocument::CDocument(IRenderer* pRenderer, NSFonts::IApplicationFonts* pFonts) : - m_pAppFonts(pFonts), m_oCurrentPage(pFonts) - { - m_oSimpleGraphicsConverter.SetRenderer(pRenderer); - m_oWriter.AddSize(10000); - } - void CDocument::Clear() - { - m_oPen.SetDefaultParams(); - m_oBrush.SetDefaultParams(); - m_oFont.SetDefaultParams(); - m_oShadow.SetDefaultParams(); - m_oEdge.SetDefaultParams(); - - m_oTransform.Reset(); - - m_lClipMode = 0; - - m_lPagesCount = 0; - m_oWriter.Clear(); - } - - CDocument::~CDocument() { - m_lClipMode = 0; - RELEASEINTERFACE(m_pFontManager); - } - - HRESULT CDocument::NewPage() - { - if (0 != m_lPagesCount) - { - m_oCurrentPage.WriteSectionToFile(false, m_oWriter); - m_oDocumentStream.WriteStringUTF8(m_oWriter.GetData()); - m_oWriter.ClearNoAttack(); - } - - m_oPen.SetDefaultParams(); - m_oBrush.SetDefaultParams(); - m_oFont.SetDefaultParams(); - m_oShadow.SetDefaultParams(); - m_oEdge.SetDefaultParams(); - - m_oTransform.Reset(); - - ++m_lPagesCount; - m_oCurrentPage.Clear(); - - return S_OK; - } - HRESULT CDocument::get_Height(double* dHeight) - { - *dHeight = m_dHeight; - return S_OK; - } - HRESULT CDocument::put_Height(double dHeight) - { - m_dHeight = dHeight; - m_oCurrentPage.m_dHeight = dHeight; - return S_OK; - } - HRESULT CDocument::get_Width(double* dWidth) - { - *dWidth = m_dWidth; - return S_OK; - } - HRESULT CDocument::put_Width(double dWidth) - { - m_dWidth = dWidth; - m_oCurrentPage.m_dWidth = dWidth; - return S_OK; - } - HRESULT CDocument::get_DpiX(double* dDpiX) - { - *dDpiX = m_dDpiX; - return S_OK; - } - HRESULT CDocument::get_DpiY(double* dDpiY) - { - *dDpiY = m_dDpiY; - return S_OK; - } - //-------- Функции для задания настроек текста ---------------------------------------------- - // pen -------------------------------------------------------------------------------------- - HRESULT CDocument::get_PenColor(LONG* lColor) - { - *lColor = m_oPen.Color; - return S_OK; - } - HRESULT CDocument::put_PenColor(LONG lColor) - { - m_oPen.Color = lColor; - return S_OK; - } - HRESULT CDocument::get_PenAlpha(LONG* lAlpha) - { - *lAlpha = m_oPen.Alpha; - return S_OK; - } - HRESULT CDocument::put_PenAlpha(LONG lAlpha) - { - m_oPen.Alpha = lAlpha; - return S_OK; - } - HRESULT CDocument::get_PenSize(double* dSize) - { - *dSize = m_oPen.Size; - return S_OK; - } - HRESULT CDocument::put_PenSize(double dSize) - { - m_oPen.Size = dSize; - return S_OK; - } - HRESULT CDocument::get_PenDashStyle(BYTE* val) - { - *val = m_oPen.DashStyle; - return S_OK; - } - HRESULT CDocument::put_PenDashStyle(BYTE val) - { - m_oPen.DashStyle = val; - return S_OK; - } - HRESULT CDocument::get_PenLineStartCap(BYTE* val) - { - *val = m_oPen.LineStartCap; - return S_OK; - } - HRESULT CDocument::put_PenLineStartCap(BYTE val) - { - m_oPen.LineStartCap = val; - return S_OK; - } - HRESULT CDocument::get_PenLineEndCap(BYTE* val) - { - *val = m_oPen.LineEndCap; - return S_OK; - } - HRESULT CDocument::put_PenLineEndCap(BYTE val) - { - m_oPen.LineEndCap = val; - return S_OK; - } - HRESULT CDocument::get_PenLineJoin(BYTE* val) - { - *val = m_oPen.LineJoin; - return S_OK; - } - HRESULT CDocument::put_PenLineJoin(BYTE val) - { - m_oPen.LineJoin = val; - return S_OK; - } - HRESULT CDocument::get_PenDashOffset(double* val) - { - *val = m_oPen.DashOffset; - return S_OK; - } - HRESULT CDocument::put_PenDashOffset(double val) - { - m_oPen.DashOffset = val; - return S_OK; - } - HRESULT CDocument::get_PenAlign(LONG* val) - { - *val = m_oPen.Align; - return S_OK; - } - HRESULT CDocument::put_PenAlign(LONG val) - { - m_oPen.Align = val; - return S_OK; - } - HRESULT CDocument::get_PenMiterLimit(double* val) - { - *val = m_oPen.MiterLimit; - return S_OK; - } - HRESULT CDocument::put_PenMiterLimit(double val) - { - m_oPen.MiterLimit = val; - return S_OK; - } - HRESULT CDocument::PenDashPattern(double* pPattern, LONG lCount) - { - if (nullptr != pPattern) - { - m_oPen.SetDashPattern(pPattern, lCount); - } - - return S_OK; - } - // brush ------------------------------------------------------------------------------------ - HRESULT CDocument::get_BrushType(LONG* lType) - { - *lType = m_oBrush.Type; - return S_OK; - } - HRESULT CDocument::put_BrushType(LONG lType) - { - m_oBrush.Type = lType; - return S_OK; - } - HRESULT CDocument::get_BrushColor1(LONG* lColor) - { - *lColor = m_oBrush.Color1; - return S_OK; - } - HRESULT CDocument::put_BrushColor1(LONG lColor) - { - m_oBrush.Color1 = lColor; - return S_OK; - } - HRESULT CDocument::get_BrushAlpha1(LONG* lAlpha) - { - *lAlpha = m_oBrush.Alpha1; - return S_OK; - } - HRESULT CDocument::put_BrushAlpha1(LONG lAlpha) - { - m_oBrush.Alpha1 = lAlpha; - return S_OK; - } - HRESULT CDocument::get_BrushColor2(LONG* lColor) - { - *lColor = m_oBrush.Color2; - return S_OK; - } - HRESULT CDocument::put_BrushColor2(LONG lColor) - { - m_oBrush.Color2 = lColor; - return S_OK; - } - HRESULT CDocument::get_BrushAlpha2(LONG* lAlpha) - { - *lAlpha = m_oBrush.Alpha2; - return S_OK; - } - HRESULT CDocument::put_BrushAlpha2(LONG lAlpha) - { - m_oBrush.Alpha2 = lAlpha; - return S_OK; - } - HRESULT CDocument::get_BrushTexturePath(std::wstring* sPath) - { - *sPath = m_oBrush.TexturePath; - return S_OK; - } - HRESULT CDocument::put_BrushTexturePath(const std::wstring& sPath) - { - m_oBrush.TexturePath = sPath; - return S_OK; - } - HRESULT CDocument::get_BrushTextureMode(LONG* lMode) - { - *lMode = m_oBrush.TextureMode; - return S_OK; - } - HRESULT CDocument::put_BrushTextureMode(LONG lMode) - { - m_oBrush.TextureMode = lMode; - return S_OK; - } - HRESULT CDocument::get_BrushTextureAlpha(LONG* lTxAlpha) - { - *lTxAlpha = m_oBrush.TextureAlpha; - return S_OK; - } - HRESULT CDocument::put_BrushTextureAlpha(LONG lTxAlpha) - { - m_oBrush.TextureAlpha = lTxAlpha; - return S_OK; - } - HRESULT CDocument::get_BrushLinearAngle(double* dAngle) - { - *dAngle = m_oBrush.LinearAngle; - return S_OK; - } - HRESULT CDocument::put_BrushLinearAngle(double dAngle) - { - m_oBrush.LinearAngle = dAngle; - return S_OK; - } - HRESULT CDocument::BrushRect(bool val, double left, double top, double width, double height) - { - m_oBrush.Rectable = val ? 1 : 0; - m_oBrush.Rect.X = (float)left; - m_oBrush.Rect.Y = (float)top; - m_oBrush.Rect.Width = (float)width; - m_oBrush.Rect.Height = (float)height; - - return S_OK; - } - // font ------------------------------------------------------------------------------------- - HRESULT CDocument::get_FontName(std::wstring* sName) - { - *sName = m_oFont.Name; - return S_OK; - } - HRESULT CDocument::put_FontName(std::wstring sName) - { - m_oFont.Name = sName; - return S_OK; - } - HRESULT CDocument::get_FontPath(std::wstring* sPath) - { - *sPath = m_oFont.Path; - return S_OK; - } - HRESULT CDocument::put_FontPath(std::wstring sPath) - { - m_oFont.Path = sPath; - return S_OK; - } - HRESULT CDocument::get_FontSize(double* dSize) - { - *dSize = m_oFont.Size; - return S_OK; - } - HRESULT CDocument::put_FontSize(double dSize) - { - m_oFont.Size = dSize; - return S_OK; - } - HRESULT CDocument::get_FontStyle(LONG* lStyle) - { - *lStyle = m_oFont.GetStyle(); - return S_OK; - } - HRESULT CDocument::put_FontStyle(LONG lStyle) - { - m_oFont.SetStyle(lStyle); - return S_OK; - } - HRESULT CDocument::get_FontStringGID(INT* bGID) - { - *bGID = m_oFont.StringGID; - return S_OK; - } - HRESULT CDocument::put_FontStringGID(INT bGID) - { - m_oFont.StringGID = bGID; - return S_OK; - } - HRESULT CDocument::get_FontCharSpace(double* dSpace) - { - *dSpace = m_oFont.CharSpace; - return S_OK; - } - HRESULT CDocument::put_FontCharSpace(double dSpace) - { - m_oFont.CharSpace = dSpace; - return S_OK; - } - HRESULT CDocument::get_FontFaceIndex(int* lFaceIndex) - { - *lFaceIndex = m_oFont.FaceIndex; - return S_OK; - } - HRESULT CDocument::put_FontFaceIndex(const int& lFaceIndex) - { - m_oFont.FaceIndex = lFaceIndex; - return S_OK; - } - // shadow ----------------------------------------------------------------------------------- - HRESULT CDocument::get_ShadowDistanceX(double* val) - { - *val = m_oShadow.DistanceX; - return S_OK; - } - HRESULT CDocument::put_ShadowDistanceX(double val) - { - m_oShadow.DistanceX = val; - return S_OK; - } - HRESULT CDocument::get_ShadowDistanceY(double* val) - { - *val = m_oShadow.DistanceY; - return S_OK; - } - HRESULT CDocument::put_ShadowDistanceY(double val) - { - m_oShadow.DistanceY = val; - return S_OK; - } - HRESULT CDocument::get_ShadowBlurSize(double* val) - { - *val = m_oShadow.BlurSize; - return S_OK; - } - HRESULT CDocument::put_ShadowBlurSize(double val) - { - m_oShadow.BlurSize = val; - return S_OK; - } - HRESULT CDocument::get_ShadowColor(LONG* val) - { - *val = m_oShadow.Color; - return S_OK; - } - HRESULT CDocument::put_ShadowColor(LONG val) - { - m_oShadow.Color = val; - return S_OK; - } - HRESULT CDocument::get_ShadowAlpha(LONG* val) - { - *val = m_oShadow.Alpha; - return S_OK; - } - HRESULT CDocument::put_ShadowAlpha(LONG val) - { - m_oShadow.Alpha = val; - return S_OK; - } - HRESULT CDocument::get_ShadowVisible(INT* val) - { - *val = m_oShadow.Visible; - return S_OK; - } - HRESULT CDocument::put_ShadowVisible(INT val) - { - m_oShadow.Visible = val; - return S_OK; - } - // edge ------------------------------------------------------------------------------------- - HRESULT CDocument::get_EdgeVisible(LONG* val) - { - *val = m_oEdge.Visible; - return S_OK; - } - HRESULT CDocument::put_EdgeVisible(LONG val) - { - m_oEdge.Visible = val; - return S_OK; - } - HRESULT CDocument::get_EdgeColor(LONG* val) - { - *val = m_oEdge.Color; - return S_OK; - } - HRESULT CDocument::put_EdgeColor(LONG val) - { - m_oEdge.Color = val; - return S_OK; - } - HRESULT CDocument::get_EdgeAlpha(LONG* val) - { - *val = m_oEdge.Alpha; - return S_OK; - } - HRESULT CDocument::put_EdgeAlpha(LONG val) - { - m_oEdge.Alpha = val; - return S_OK; - } - HRESULT CDocument::get_EdgeDist(double* val) - { - *val = m_oEdge.Dist; - return S_OK; - } - HRESULT CDocument::put_EdgeDist(double val) - { - m_oEdge.Dist = val; - return S_OK; - } - - //-------- Функции для вывода текста -------------------------------------------------------- - HRESULT CDocument::CommandDrawTextPrivate(const int* pUnicodes, const int* pGids, int nCount, - const double& dX, const double& dY, const double& dW, - const double& dH, const double& dBaseLineOffset) - { - double dAngleMatrix = m_oTransform.z_Rotation(); - if (fabs(dAngleMatrix) > 1 || m_oTransform.sx() < 0 || m_oTransform.sy() < 0) - { - //note У повернутых символов не приходят координаты. - _SetFont(); - PathCommandEnd(); - BeginCommand(c_nPathType); - m_oSimpleGraphicsConverter.PathCommandText2(pUnicodes, pGids, nCount, m_pFontManager, dX, dY, dW, dH); - DrawPath(c_nWindingFillMode); - EndCommand(c_nPathType); - PathCommandEnd(); - return S_OK; - } - - m_oCurrentPage.CollectTextData((unsigned int*)pUnicodes, (unsigned int*)pGids, nCount, dX, dY, dW, dH, 0, m_bIsNeedPDFTextAnalyzer); - return S_OK; - } - - HRESULT CDocument::CommandDrawTextCHAR(const int& lUnicode, const double& dX, const double& dY, const double& dW, const double& dH) - { - return CommandDrawTextPrivate(&lUnicode, nullptr, 1, dX, dY, dW, dH); - } - HRESULT CDocument::CommandDrawTextExCHAR(const int& lUnicode, const int& lGid, const double& dX, const double& dY, const double& dW, const double& dH) - { - return CommandDrawTextPrivate(&lUnicode, &lGid, 1, dX, dY, dW, dH); - } - HRESULT CDocument::CommandDrawText(const std::wstring& wsUnicodeText, const double& dX, const double& dY, const double& dW, const double& dH) - { - unsigned int nLen = 0; - unsigned int* pUnicodes = NSStringExt::CConverter::GetUtf32FromUnicode(wsUnicodeText, nLen); - if (nLen == 0) - return S_OK; - CommandDrawTextPrivate((int*)pUnicodes, nullptr, nLen, dX, dY, dW, dH); - delete [] pUnicodes; - return S_OK; - } - HRESULT CDocument::CommandDrawTextEx(const std::wstring& wsUnicodeText, const unsigned int* pGids, const unsigned int nGidsCount, const double& dX, const double& dY, const double& dW, const double& dH) - { - unsigned int nLen = 0; - unsigned int* pUnicodes = NSStringExt::CConverter::GetUtf32FromUnicode(wsUnicodeText, nLen); - if (nLen == 0) - return S_OK; + CDocument::CDocument(IRenderer* pRenderer, NSFonts::IApplicationFonts* pFonts) : + m_pAppFonts(pFonts), + m_oFontManager(pFonts), + m_oFontSelector(pFonts), + m_oCurrentPage(pFonts, {&m_oImageManager, &m_oFontStyleManager, &m_oParagraphStyleManager, &m_oFontManager, &m_oFontSelector}) + { + m_oSimpleGraphicsConverter.SetRenderer(pRenderer); + } + void CDocument::Clear() + { + NewPage(); + + for(auto& val : m_mapXmlString) + delete val.second; + + m_mapXmlString.clear(); + m_lCurrentCommandType = 0; + m_oImageManager.Clear(); + m_oFontStyleManager.Clear(); + } + + CDocument::~CDocument() + { + Clear(); + RELEASEINTERFACE(m_pBaseFontManager); + } + + HRESULT CDocument::NewPage() + { + m_oCurrentPage.Clear(); + return S_OK; + } + HRESULT CDocument::get_Height(double* dHeight) + { + *dHeight = m_dHeight; + return S_OK; + } + HRESULT CDocument::put_Height(double dHeight) + { + m_dHeight = dHeight; + m_oCurrentPage.m_dHeight = dHeight; + return S_OK; + } + HRESULT CDocument::get_Width(double* dWidth) + { + *dWidth = m_dWidth; + return S_OK; + } + HRESULT CDocument::put_Width(double dWidth) + { + m_dWidth = dWidth; + m_oCurrentPage.m_dWidth = dWidth; + return S_OK; + } + HRESULT CDocument::get_DpiX(double* dDpiX) + { + *dDpiX = m_dDpiX; + return S_OK; + } + HRESULT CDocument::get_DpiY(double* dDpiY) + { + *dDpiY = m_dDpiY; + return S_OK; + } + //-------- Функции для задания настроек текста ---------------------------------------------- + // pen -------------------------------------------------------------------------------------- + HRESULT CDocument::get_PenColor(LONG* lColor) + { + *lColor = m_oCurrentPage.m_oPen.Color; + return S_OK; + } + HRESULT CDocument::put_PenColor(LONG lColor) + { + m_oCurrentPage.m_oPen.Color = lColor; + return S_OK; + } + HRESULT CDocument::get_PenAlpha(LONG* lAlpha) + { + *lAlpha = m_oCurrentPage.m_oPen.Alpha; + return S_OK; + } + HRESULT CDocument::put_PenAlpha(LONG lAlpha) + { + m_oCurrentPage.m_oPen.Alpha = CLAMP_ALPHA(lAlpha); + return S_OK; + } + HRESULT CDocument::get_PenSize(double* dSize) + { + *dSize = m_oCurrentPage.m_oPen.Size; + return S_OK; + } + HRESULT CDocument::put_PenSize(double dSize) + { + m_oCurrentPage.m_oPen.Size = dSize; + return S_OK; + } + HRESULT CDocument::get_PenDashStyle(BYTE* val) + { + *val = m_oCurrentPage.m_oPen.DashStyle; + return S_OK; + } + HRESULT CDocument::put_PenDashStyle(BYTE val) + { + m_oCurrentPage.m_oPen.DashStyle = val; + return S_OK; + } + HRESULT CDocument::get_PenLineStartCap(BYTE* val) + { + *val = m_oCurrentPage.m_oPen.LineStartCap; + return S_OK; + } + HRESULT CDocument::put_PenLineStartCap(BYTE val) + { + m_oCurrentPage.m_oPen.LineStartCap = val; + return S_OK; + } + HRESULT CDocument::get_PenLineEndCap(BYTE* val) + { + *val = m_oCurrentPage.m_oPen.LineEndCap; + return S_OK; + } + HRESULT CDocument::put_PenLineEndCap(BYTE val) + { + m_oCurrentPage.m_oPen.LineEndCap = val; + return S_OK; + } + HRESULT CDocument::get_PenLineJoin(BYTE* val) + { + *val = m_oCurrentPage.m_oPen.LineJoin; + return S_OK; + } + HRESULT CDocument::put_PenLineJoin(BYTE val) + { + m_oCurrentPage.m_oPen.LineJoin = val; + return S_OK; + } + HRESULT CDocument::get_PenDashOffset(double* val) + { + *val = m_oCurrentPage.m_oPen.DashOffset; + return S_OK; + } + HRESULT CDocument::put_PenDashOffset(double val) + { + m_oCurrentPage.m_oPen.DashOffset = val; + return S_OK; + } + HRESULT CDocument::get_PenAlign(LONG* val) + { + *val = m_oCurrentPage.m_oPen.Align; + return S_OK; + } + HRESULT CDocument::put_PenAlign(LONG val) + { + m_oCurrentPage.m_oPen.Align = val; + return S_OK; + } + HRESULT CDocument::get_PenMiterLimit(double* val) + { + *val = m_oCurrentPage.m_oPen.MiterLimit; + return S_OK; + } + HRESULT CDocument::put_PenMiterLimit(double val) + { + m_oCurrentPage.m_oPen.MiterLimit = val; + return S_OK; + } + HRESULT CDocument::PenDashPattern(double* pPattern, LONG lCount) + { + if (nullptr != pPattern) + { + m_oCurrentPage.m_oPen.SetDashPattern(pPattern, lCount); + } + + return S_OK; + } + // brush ------------------------------------------------------------------------------------ + HRESULT CDocument::get_BrushType(LONG* lType) + { + *lType = m_oCurrentPage.m_oBrush.Type; + return S_OK; + } + HRESULT CDocument::put_BrushType(LONG lType) + { + m_oCurrentPage.m_oBrush.Type = lType; + return S_OK; + } + HRESULT CDocument::get_BrushColor1(LONG* lColor) + { + *lColor = m_oCurrentPage.m_oBrush.Color1; + return S_OK; + } + HRESULT CDocument::put_BrushColor1(LONG lColor) + { + m_oCurrentPage.m_oBrush.Color1 = lColor; + return S_OK; + } + HRESULT CDocument::get_BrushAlpha1(LONG* lAlpha) + { + *lAlpha = m_oCurrentPage.m_oBrush.Alpha1; + return S_OK; + } + HRESULT CDocument::put_BrushAlpha1(LONG lAlpha) + { + m_oCurrentPage.m_oBrush.Alpha1 = CLAMP_ALPHA(lAlpha);; + return S_OK; + } + HRESULT CDocument::get_BrushColor2(LONG* lColor) + { + *lColor = m_oCurrentPage.m_oBrush.Color2; + return S_OK; + } + HRESULT CDocument::put_BrushColor2(LONG lColor) + { + m_oCurrentPage.m_oBrush.Color2 = lColor; + return S_OK; + } + HRESULT CDocument::get_BrushAlpha2(LONG* lAlpha) + { + *lAlpha = m_oCurrentPage.m_oBrush.Alpha2; + return S_OK; + } + HRESULT CDocument::put_BrushAlpha2(LONG lAlpha) + { + m_oCurrentPage.m_oBrush.Alpha2 = CLAMP_ALPHA(lAlpha);; + return S_OK; + } + HRESULT CDocument::get_BrushTexturePath(std::wstring* sPath) + { + *sPath = m_oCurrentPage.m_oBrush.TexturePath; + return S_OK; + } + HRESULT CDocument::put_BrushTexturePath(const std::wstring& sPath) + { + m_oCurrentPage.m_oBrush.TexturePath = sPath; + return S_OK; + } + HRESULT CDocument::get_BrushTextureMode(LONG* lMode) + { + *lMode = m_oCurrentPage.m_oBrush.TextureMode; + return S_OK; + } + HRESULT CDocument::put_BrushTextureMode(LONG lMode) + { + m_oCurrentPage.m_oBrush.TextureMode = lMode; + return S_OK; + } + HRESULT CDocument::get_BrushTextureAlpha(LONG* lTxAlpha) + { + *lTxAlpha = m_oCurrentPage.m_oBrush.TextureAlpha; + return S_OK; + } + HRESULT CDocument::put_BrushTextureAlpha(LONG lTxAlpha) + { + m_oCurrentPage.m_oBrush.TextureAlpha = CLAMP_ALPHA(lTxAlpha); + return S_OK; + } + HRESULT CDocument::get_BrushLinearAngle(double* dAngle) + { + *dAngle = m_oCurrentPage.m_oBrush.LinearAngle; + return S_OK; + } + HRESULT CDocument::put_BrushLinearAngle(double dAngle) + { + m_oCurrentPage.m_oBrush.LinearAngle = dAngle; + return S_OK; + } + HRESULT CDocument::BrushRect(bool val, double left, double top, double width, double height) + { + m_oCurrentPage.m_oBrush.Rectable = val ? 1 : 0; + m_oCurrentPage.m_oBrush.Rect.X = (float)left; + m_oCurrentPage.m_oBrush.Rect.Y = (float)top; + m_oCurrentPage.m_oBrush.Rect.Width = (float)width; + m_oCurrentPage.m_oBrush.Rect.Height = (float)height; + + return S_OK; + } + HRESULT CDocument::BrushBounds(const double& dLeft, const double& dTop, const double& dWidth, const double& dHeight) + { + m_oCurrentPage.m_oBrush.Bounds.left = dLeft; + m_oCurrentPage.m_oBrush.Bounds.top = dTop; + m_oCurrentPage.m_oBrush.Bounds.right = dLeft + dWidth; + m_oCurrentPage.m_oBrush.Bounds.bottom = dTop + dHeight; + return S_OK; + } + HRESULT CDocument::put_BrushGradientColors(LONG* pColors, double* pPositions, LONG lCount) + { + m_oCurrentPage.m_oBrush.m_arrSubColors.clear(); + for (LONG i = 0; i < lCount; ++i) + { + NSStructures::CBrush::TSubColor color; + color.color = pColors[i]; + color.position = (long)(pPositions[i] * 65536); + m_oCurrentPage.m_oBrush.m_arrSubColors.push_back(color); + } + m_oCurrentPage.m_bIsGradient = true; + return S_OK; + } + HRESULT CDocument::put_BrushGradInfo(void* pGradInfo) + { + m_oCurrentPage.m_oBrush.m_oGradientInfo = *((NSStructures::GradientInfo*)pGradInfo); + m_oCurrentPage.m_oBrush.m_oGradientInfo.transform(m_oCurrentPage.m_oTransform); + m_oCurrentPage.m_bIsGradient = true; + return S_OK; + } + // font ------------------------------------------------------------------------------------- + HRESULT CDocument::get_FontName(std::wstring* sName) + { + *sName = m_oCurrentPage.m_oFont.Name; + return S_OK; + } + HRESULT CDocument::put_FontName(std::wstring sName) + { + m_oCurrentPage.m_oFont.Name = sName; + return S_OK; + } + HRESULT CDocument::get_FontPath(std::wstring* sPath) + { + *sPath = m_oCurrentPage.m_oFont.Path; + return S_OK; + } + HRESULT CDocument::put_FontPath(std::wstring sPath) + { + m_oCurrentPage.m_oFont.Path = sPath; + return S_OK; + } + HRESULT CDocument::get_FontSize(double* dSize) + { + *dSize = m_oCurrentPage.m_oFont.Size; + return S_OK; + } + HRESULT CDocument::put_FontSize(double dSize) + { + m_oCurrentPage.m_oFont.Size = dSize; + m_oCurrentPage.m_bIsRecalcFontSize = true; + return S_OK; + } + HRESULT CDocument::get_FontStyle(LONG* lStyle) + { + *lStyle = m_oCurrentPage.m_oFont.GetStyle(); + return S_OK; + } + HRESULT CDocument::put_FontStyle(LONG lStyle) + { + m_oCurrentPage.m_oFont.SetStyle(lStyle); + return S_OK; + } + HRESULT CDocument::get_FontStringGID(INT* bGID) + { + *bGID = m_oCurrentPage.m_oFont.StringGID; + return S_OK; + } + HRESULT CDocument::put_FontStringGID(INT bGID) + { + m_oCurrentPage.m_oFont.StringGID = bGID; + return S_OK; + } + HRESULT CDocument::get_FontCharSpace(double* dSpace) + { + *dSpace = m_oCurrentPage.m_oFont.CharSpace; + return S_OK; + } + HRESULT CDocument::put_FontCharSpace(double dSpace) + { + m_oCurrentPage.m_oFont.CharSpace = dSpace; + return S_OK; + } + HRESULT CDocument::get_FontFaceIndex(int* lFaceIndex) + { + *lFaceIndex = m_oCurrentPage.m_oFont.FaceIndex; + return S_OK; + } + HRESULT CDocument::put_FontFaceIndex(const int& lFaceIndex) + { + m_oCurrentPage.m_oFont.FaceIndex = lFaceIndex; + return S_OK; + } + // shadow ----------------------------------------------------------------------------------- + HRESULT CDocument::get_ShadowDistanceX(double* val) + { + *val = m_oCurrentPage.m_oShadow.DistanceX; + return S_OK; + } + HRESULT CDocument::put_ShadowDistanceX(double val) + { + m_oCurrentPage.m_oShadow.DistanceX = val; + return S_OK; + } + HRESULT CDocument::get_ShadowDistanceY(double* val) + { + *val = m_oCurrentPage.m_oShadow.DistanceY; + return S_OK; + } + HRESULT CDocument::put_ShadowDistanceY(double val) + { + m_oCurrentPage.m_oShadow.DistanceY = val; + return S_OK; + } + HRESULT CDocument::get_ShadowBlurSize(double* val) + { + *val = m_oCurrentPage.m_oShadow.BlurSize; + return S_OK; + } + HRESULT CDocument::put_ShadowBlurSize(double val) + { + m_oCurrentPage.m_oShadow.BlurSize = val; + return S_OK; + } + HRESULT CDocument::get_ShadowColor(LONG* val) + { + *val = m_oCurrentPage.m_oShadow.Color; + return S_OK; + } + HRESULT CDocument::put_ShadowColor(LONG val) + { + m_oCurrentPage.m_oShadow.Color = val; + return S_OK; + } + HRESULT CDocument::get_ShadowAlpha(LONG* val) + { + *val = m_oCurrentPage.m_oShadow.Alpha; + return S_OK; + } + HRESULT CDocument::put_ShadowAlpha(LONG val) + { + m_oCurrentPage.m_oShadow.Alpha = val; + return S_OK; + } + HRESULT CDocument::get_ShadowVisible(INT* val) + { + *val = m_oCurrentPage.m_oShadow.Visible; + return S_OK; + } + HRESULT CDocument::put_ShadowVisible(INT val) + { + m_oCurrentPage.m_oShadow.Visible = val; + return S_OK; + } + // edge ------------------------------------------------------------------------------------- + HRESULT CDocument::get_EdgeVisible(LONG* val) + { + *val = m_oCurrentPage.m_oEdgeText.Visible; + return S_OK; + } + HRESULT CDocument::put_EdgeVisible(LONG val) + { + m_oCurrentPage.m_oEdgeText.Visible = val; + return S_OK; + } + HRESULT CDocument::get_EdgeColor(LONG* val) + { + *val = m_oCurrentPage.m_oEdgeText.Color; + return S_OK; + } + HRESULT CDocument::put_EdgeColor(LONG val) + { + m_oCurrentPage.m_oEdgeText.Color = val; + return S_OK; + } + HRESULT CDocument::get_EdgeAlpha(LONG* val) + { + *val = m_oCurrentPage.m_oEdgeText.Alpha; + return S_OK; + } + HRESULT CDocument::put_EdgeAlpha(LONG val) + { + m_oCurrentPage.m_oEdgeText.Alpha = val; + return S_OK; + } + HRESULT CDocument::get_EdgeDist(double* val) + { + *val = m_oCurrentPage.m_oEdgeText.Dist; + return S_OK; + } + HRESULT CDocument::put_EdgeDist(double val) + { + m_oCurrentPage.m_oEdgeText.Dist = val; + return S_OK; + } + + //-------- Функции для вывода текста -------------------------------------------------------- + HRESULT CDocument::CommandDrawTextPrivate(const int* pUnicodes, const int* pGids, int nCount, + const double& dX, const double& dY, const double& dW, + const double& dH, const double& dBaseLineOffset) + { + double dAngleMatrix = m_oCurrentPage.m_oTransform.z_Rotation(); + if (fabs(dAngleMatrix) > 1 || m_oCurrentPage.m_oTransform.sx() < 0 || m_oCurrentPage.m_oTransform.sy() < 0) + { + //note У повернутых символов не приходят координаты. + _SetFont(); + PathCommandEnd(); + BeginCommand(c_nPathType); + m_oSimpleGraphicsConverter.PathCommandText2(pUnicodes, pGids, nCount, m_pBaseFontManager, dX, dY, dW, dH); + DrawPath(c_nWindingFillMode); + EndCommand(c_nPathType); + PathCommandEnd(); + return S_OK; + } + + m_oCurrentPage.AddText((unsigned int*)pUnicodes, (unsigned int*)pGids, nCount, dX, dY, dW, dH, 0); + return S_OK; + } + + HRESULT CDocument::CommandDrawTextCHAR(const int& lUnicode, const double& dX, const double& dY, const double& dW, const double& dH) + { + return CommandDrawTextPrivate(&lUnicode, nullptr, 1, dX, dY, dW, dH); + } + HRESULT CDocument::CommandDrawTextExCHAR(const int& lUnicode, const int& lGid, const double& dX, const double& dY, const double& dW, const double& dH) + { + return CommandDrawTextPrivate(&lUnicode, &lGid, 1, dX, dY, dW, dH); + } + HRESULT CDocument::CommandDrawText(const std::wstring& wsUnicodeText, const double& dX, const double& dY, const double& dW, const double& dH) + { + unsigned int nLen = 0; + unsigned int* pUnicodes = NSStringExt::CConverter::GetUtf32FromUnicode(wsUnicodeText, nLen); + if (nLen == 0) + return S_OK; + CommandDrawTextPrivate((int*)pUnicodes, nullptr, nLen, dX, dY, dW, dH); + delete [] pUnicodes; + return S_OK; + } + HRESULT CDocument::CommandDrawTextEx(const std::wstring& wsUnicodeText, const unsigned int* pGids, const unsigned int nGidsCount, const double& dX, const double& dY, const double& dW, const double& dH) + { + unsigned int nLen = 0; + unsigned int* pUnicodes = NSStringExt::CConverter::GetUtf32FromUnicode(wsUnicodeText, nLen); + if (nLen == 0) + return S_OK; if (nLen != nGidsCount && 0 != nGidsCount) - { - delete [] pUnicodes; - return S_OK; - } + { + delete [] pUnicodes; + return S_OK; + } CommandDrawTextPrivate((int*)pUnicodes, (0 == nGidsCount) ? nullptr : (int*)pGids, (int)nLen, dX, dY, dW, dH); - delete [] pUnicodes; - return S_OK; - } - //-------- Маркеры для команд --------------------------------------------------------------- - HRESULT CDocument::BeginCommand(DWORD lType) - { - if (c_nPageType == lType && m_bIsDisablePageCommand) - return S_OK; - - m_lCurrentCommandType = (LONG)lType; - m_oCurrentPage.m_lCurrentCommand = m_lCurrentCommandType; - - if (c_nTextType == lType) - m_oCurrentPage.m_dLastTextX_block = -1; - - return S_OK; - } - HRESULT CDocument::EndCommand(DWORD lType) - { - if (c_nPageType == lType && m_bIsDisablePageCommand) - return S_OK; - - m_lCurrentCommandType = -1; - m_oCurrentPage.m_lCurrentCommand = m_lCurrentCommandType; - - if (c_nPageType == lType) - { - // нужно записать страницу в файл - m_oCurrentPage.AnalyzeCollectedShapes(); - m_oCurrentPage.AnalyzeCollectedSymbols(); - m_oCurrentPage.AnalyzeLines(); - m_oCurrentPage.BuildByType(); - m_oCurrentPage.ToXml(m_oWriter); - } - else if (c_nPathType == lType) - { - m_oCurrentPage.End(); - } - - if (c_nTextType == lType) - m_oCurrentPage.m_dLastTextX_block = -1; - - return S_OK; - } - //-------- Функции для работы с Graphics Path ----------------------------------------------- - HRESULT CDocument::PathCommandMoveTo(double fX, double fY) - { - if (c_nSimpleGraphicType == m_lCurrentCommandType) - { - m_oCurrentPage.MoveTo(fX, fY); - } - else - { - m_oSimpleGraphicsConverter.PathCommandMoveTo(fX, fY); - } - return S_OK; - } - HRESULT CDocument::PathCommandLineTo(double fX, double fY) - { - if (c_nSimpleGraphicType == m_lCurrentCommandType) - { - m_oCurrentPage.LineTo(fX, fY); - } - else - { - m_oSimpleGraphicsConverter.PathCommandLineTo(fX, fY); - } - return S_OK; - } - HRESULT CDocument::PathCommandLinesTo(double* pPoints, LONG lCount) - { - m_oSimpleGraphicsConverter.PathCommandLinesTo(pPoints, lCount); - return S_OK; - } - HRESULT CDocument::PathCommandCurveTo(double fX1, double fY1, double fX2, double fY2, double fX3, double fY3) - { - if (c_nSimpleGraphicType == m_lCurrentCommandType) - { - m_oCurrentPage.CurveTo(fX1, fY1, fX2, fY2, fX3, fY3); - } - else - { - m_oSimpleGraphicsConverter.PathCommandCurveTo(fX1, fY1, fX2, fY2, fX3, fY3); - } - return S_OK; - } - HRESULT CDocument::PathCommandCurvesTo(double* pPoints, LONG lCount) - { - m_oSimpleGraphicsConverter.PathCommandCurvesTo(pPoints, lCount); - return S_OK; - } - HRESULT CDocument::PathCommandArcTo(double fX, double fY, double fWidth, double fHeight, double fStartAngle, double fSweepAngle) - { - m_oSimpleGraphicsConverter.PathCommandArcTo(fX, fY, fWidth, fHeight, fStartAngle, fSweepAngle); - return S_OK; - } - HRESULT CDocument::PathCommandClose() - { - if (c_nSimpleGraphicType == m_lCurrentCommandType) - { - m_oCurrentPage.Close(); - } - else - { - m_oSimpleGraphicsConverter.PathCommandClose(); - } - return S_OK; - } - HRESULT CDocument::PathCommandEnd() - { - if (c_nSimpleGraphicType == m_lCurrentCommandType) - { - m_oCurrentPage.End(); - } - else - { - m_oSimpleGraphicsConverter.PathCommandEnd(); - } - return S_OK; - } - HRESULT CDocument::DrawPath(long nType) - { - std::shared_ptr pInfo = nullptr; - - if ((nType > 0xFF) && (c_BrushTypeTexture == m_oBrush.Type)) - { - double x = 0; - double y = 0; - double w = 0; - double h = 0; - pInfo = m_oImageManager.WriteImage(m_oBrush.TexturePath, x, y, w, h); - } - - m_oCurrentPage.DrawPath(nType, pInfo); - return S_OK; - } - HRESULT CDocument::PathCommandStart() - { - if (c_nSimpleGraphicType == m_lCurrentCommandType) - { - m_oCurrentPage.Start(); - } - else - { - m_oSimpleGraphicsConverter.PathCommandStart(); - } - return S_OK; - } - HRESULT CDocument::PathCommandGetCurrentPoint(double* fX, double* fY) - { - m_oSimpleGraphicsConverter.PathCommandGetCurrentPoint(fX, fY); - return S_OK; - } - - HRESULT CDocument::PathCommandTextCHAR(const int& lUnicode, const double& dX, const double& dY, const double& dW, const double& dH) - { - _SetFont(); - m_oSimpleGraphicsConverter.PathCommandText2(&lUnicode, nullptr, 1, m_pFontManager, dX, dY, dW, dH); - return S_OK; - } - HRESULT CDocument::PathCommandTextExCHAR(const int& lUnicode, const int& lGid, const double& dX, const double& dY, const double& dW, const double& dH) - { - _SetFont(); - m_oSimpleGraphicsConverter.PathCommandText2(&lUnicode, &lGid, 1, m_pFontManager, dX, dY, dW, dH); - return S_OK; - } - HRESULT CDocument::PathCommandText(const std::wstring& wsUnicodeText, const double& dX, const double& dY, const double& dW, const double& dH) - { - _SetFont(); - m_oSimpleGraphicsConverter.PathCommandText(wsUnicodeText, m_pFontManager, dX, dY, dW, dH, 0); - return S_OK; - } - HRESULT CDocument::PathCommandTextEx(const std::wstring& wsUnicodeText, const unsigned int* pGids, const unsigned int nGidsCount, const double& dX, const double& dY, const double& dW, const double& dH) - { - _SetFont(); - m_oSimpleGraphicsConverter.PathCommandText2(wsUnicodeText, (const int*)pGids, nGidsCount, m_pFontManager, dX, dY, dW, dH); - return S_OK; - } - - HRESULT CDocument::GetCommandParams(double* dAngle, double* dLeft, double* dTop, double* dWidth, double* dHeight, DWORD* lFlags) - { - return S_OK; - } - HRESULT CDocument::SetCommandParams(double dAngle, double dLeft, double dTop, double dWidth, double dHeight, DWORD lFlags) - { - ApplyTransform2(dAngle, dLeft, dTop, dWidth, dHeight, lFlags); - return S_OK; - } - //-------- Функции для вывода изображений -------------------------------------------------- - HRESULT CDocument::DrawImage(IGrObject* pImage, double fX, double fY, double fWidth, double fHeight) - { - m_oCurrentPage.WriteImage(m_oImageManager.WriteImage((Aggplus::CImage*)pImage, fX, fY, fWidth, fHeight), fX, fY, fWidth, fHeight); - return S_OK; - } - HRESULT CDocument::DrawImageFromFile(const std::wstring& sVal, double fX, double fY, double fWidth, double fHeight) - { - m_oCurrentPage.WriteImage(m_oImageManager.WriteImage(sVal, fX, fY, fWidth, fHeight), fX, fY, fWidth, fHeight); - return S_OK; - } - //------------------------------------------------------------------------------------------ - HRESULT CDocument::SetTransform(double dA, double dB, double dC, double dD, double dE, double dF) - { - ApplyTransform(dA, dB, dC, dD, dE, dF); - return S_OK; - } - HRESULT CDocument::GetTransform(double *pdA, double *pdB, double *pdC, double *pdD, double *pdE, double *pdF) - { - return S_OK; - } - HRESULT CDocument::ResetTransform(void) - { - m_oTransform.Reset(); - return S_OK; - } - HRESULT CDocument::get_ClipMode(LONG* plMode) - { - *plMode = m_lClipMode; - return S_OK; - } - HRESULT CDocument::put_ClipMode(LONG lMode) - { - m_lClipMode = lMode; - return S_OK; - } - - void CDocument::ApplyTransform(double d1, double d2, double d3, double d4, double d5, double d6) - { - m_oTransform.SetElements(d1, d2, d3, d4, d5, d6); - } - - void CDocument::ApplyTransform2(double dAngle, double dLeft, double dTop, double dWidth, double dHeight, DWORD lFlags) - { - if ((dWidth <= 1) || (dHeight <= 1)) - lFlags = 0; - - bool bFlipX = (0 != (c_nParamFlipX & lFlags)); - bool bFlipY = (0 != (c_nParamFlipY & lFlags)); - - double m11 = bFlipX ? -1.0 : 1.0; - double m22 = bFlipY ? -1.0 : 1.0; - - Aggplus::CMatrix oMatrix(1, 0, 0, 1, 0, 0); - - if ((0 != dAngle) || (0 != lFlags)) - { - double dCentreX = (dLeft + dWidth / 2.0); - double dCentreY = (dTop + dHeight / 2.0); - - oMatrix.Translate(-dCentreX, -dCentreY , Aggplus::MatrixOrderAppend); - - oMatrix.Rotate(dAngle , Aggplus::MatrixOrderAppend); - oMatrix.Scale(m11, m22 , Aggplus::MatrixOrderAppend); - - oMatrix.Translate(dCentreX, dCentreY , Aggplus::MatrixOrderAppend); - } - - m_oTransform = oMatrix; - } - - void CDocument::_SetFont() - { - if (nullptr == m_pFontManager) - { - m_pFontManager = NSFontManager::CreateFontManager(m_pAppFonts); - } - - double dPix = m_oFont.CharSpace * m_dDpiX / 25.4; - - if (m_oInstalledFont.IsEqual(&m_oFont)) - { - if (1 < m_dWidth) - { - m_pFontManager->SetCharSpacing(dPix); - } - return; - } - - m_pFontManager->SetStringGID(m_oFont.StringGID); - if (1 < m_dWidth) - { - m_pFontManager->SetCharSpacing(dPix); - } - - if (m_oFont.Path.empty()) - { - m_pFontManager->LoadFontByName(m_oFont.Name, (float)m_oFont.Size, m_oFont.GetStyle(), m_dDpiX, m_dDpiY); - } - else - { - m_pFontManager->LoadFontFromFile(m_oFont.Path, m_oFont.FaceIndex, (float)m_oFont.Size, m_dDpiX, m_dDpiY); - } - - m_oInstalledFont = m_oFont; - } - - bool CDocument::CreateDocument() - { - CreateTemplate(m_strTempDirectory); - - // Init - Clear(); - - m_lCurrentCommandType = 0; - m_oCurrentPage.Init(&m_oFont, &m_oPen, &m_oBrush, &m_oShadow, &m_oEdge, &m_oTransform, &m_oSimpleGraphicsConverter, &m_oStyleManager); - - m_oImageManager.NewDocument(); - m_oStyleManager.NewDocument(); - // media - m_oImageManager.m_strDstMedia = m_strTempDirectory + L"/word/media"; - NSDirectory::CreateDirectory(m_oImageManager.m_strDstMedia); - - m_oCurrentPage.m_oFontManager.Init(); - - m_oDocumentStream.CloseFile(); - m_oDocumentStream.CreateFileW(m_strTempDirectory + L"/word/document.xml"); - m_oDocumentStream.WriteStringUTF8(L"\ - \ - "); - - return true; - } - - void CDocument::Close() - { - BuildDocumentXmlRels(); - BuildFontTableXml(); - BuildStylesXml(); - - // document - m_oCurrentPage.WriteSectionToFile(true, m_oWriter); - m_oWriter.WriteString(L""); - m_oDocumentStream.WriteStringUTF8(m_oWriter.GetData()); - m_oWriter.ClearNoAttack(); - - m_oDocumentStream.CloseFile(); - } - - void CDocument::BuildDocumentXmlRels() - { - // сохраним rels (images & docs) - NSStringUtils::CStringBuilder oWriter; - - oWriter.WriteString(L"\ -\ -\ -\ -\ -\ -"); - - for (const auto& pImage : m_oImageManager.m_mapImageData) - { - WriteImageToWriter(oWriter, pImage.second); - } - - for (const auto& pImage : m_oImageManager.m_mapImagesFile) - { - WriteImageToWriter(oWriter, pImage.second); - } - - if (m_oImageManager.m_pEmptyInfo) - { - WriteImageToWriter(oWriter, m_oImageManager.m_pEmptyInfo); - } - - oWriter.WriteString(L""); - - NSFile::CFileBinary::SaveToFile(m_strTempDirectory + L"/word/_rels/document.xml.rels", oWriter.GetData()); - oWriter.ClearNoAttack(); - } - - void CDocument::BuildFontTableXml() - { - NSStringUtils::CStringBuilder oWriter; - // сохраним fontTable - oWriter.WriteString(L"\ - "); - - CFontTable* pFontTable = &m_oCurrentPage.m_oFontManager.m_oFontTable; - for (std::map::iterator iterFont = pFontTable->m_mapTable.begin(); iterFont != pFontTable->m_mapTable.end(); iterFont++) - { - CFontTableEntry& oEntry = iterFont->second; - - if (oEntry.m_strFamilyName.empty()) - { - continue; - } - - oWriter.WriteString(L""); - - oWriter.WriteString(L""); - - if (oEntry.m_bIsFixedWidth) - oWriter.WriteString(L""); - else - oWriter.WriteString(L""); - - oWriter.WriteString(L""); - - oWriter.WriteString(L""); - - oWriter.WriteString(L""); - } - - oWriter.WriteString(L""); - NSFile::CFileBinary::SaveToFile(m_strTempDirectory + L"/word/fontTable.xml", oWriter.GetData()); - } - - void CDocument::BuildStylesXml() - { - NSStringUtils::CStringBuilder oWriter; - - // сохраним styles - oWriter.WriteString(L"\ - "); - - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - - oWriter.WriteString(L""); - oWriter.WriteString(L""); - - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); //отключение проверки орфографии - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - - for (const auto &pStyle : m_oStyleManager.m_arStyles) - { - pStyle->ToXml(oWriter); - } - - oWriter.WriteString(L""); - - NSFile::CFileBinary::SaveToFile(m_strTempDirectory + L"/word/styles.xml", oWriter.GetData()); - } + delete [] pUnicodes; + return S_OK; + } + //-------- Маркеры для команд --------------------------------------------------------------- + HRESULT CDocument::BeginCommand(DWORD lType) + { + if (c_nPageType == lType && m_bIsDisablePageCommand) + return S_OK; + + m_lCurrentCommandType = static_cast(lType); + m_oCurrentPage.BeginCommand(lType); + + return S_OK; + } + HRESULT CDocument::EndCommand(DWORD lType) + { + if (lType == c_nPageType) + { + if (m_bIsDisablePageCommand) + return S_OK; + + m_lCurrentCommandType = -1; + m_oCurrentPage.m_lCurrentCommand = m_lCurrentCommandType; + + auto pWriter = new NSStringUtils::CStringBuilder(); + pWriter->AddSize(100000); + m_oCurrentPage.Analyze(); + m_oCurrentPage.Record(*pWriter, m_lPageNum >= m_lNumberPages - 1); + m_mapXmlString[m_lPageNum] = pWriter; + } + else + m_oCurrentPage.EndCommand(lType); + + return S_OK; + } + //-------- Функции для работы с Graphics Path ----------------------------------------------- + HRESULT CDocument::PathCommandMoveTo(double fX, double fY) + { + if (c_nSimpleGraphicType == m_lCurrentCommandType) + m_oCurrentPage.PathMoveTo(fX, fY); + else + m_oSimpleGraphicsConverter.PathCommandMoveTo(fX, fY); + return S_OK; + } + HRESULT CDocument::PathCommandLineTo(double fX, double fY) + { + if (c_nSimpleGraphicType == m_lCurrentCommandType) + m_oCurrentPage.PathLineTo(fX, fY); + else + m_oSimpleGraphicsConverter.PathCommandLineTo(fX, fY); + return S_OK; + } + HRESULT CDocument::PathCommandLinesTo(double* pPoints, LONG lCount) + { + m_oSimpleGraphicsConverter.PathCommandLinesTo(pPoints, lCount); + return S_OK; + } + HRESULT CDocument::PathCommandCurveTo(double fX1, double fY1, double fX2, double fY2, double fX3, double fY3) + { + if (c_nSimpleGraphicType == m_lCurrentCommandType) + m_oCurrentPage.PathCurveTo(fX1, fY1, fX2, fY2, fX3, fY3); + else + m_oSimpleGraphicsConverter.PathCommandCurveTo(fX1, fY1, fX2, fY2, fX3, fY3); + return S_OK; + } + HRESULT CDocument::PathCommandCurvesTo(double* pPoints, LONG lCount) + { + m_oSimpleGraphicsConverter.PathCommandCurvesTo(pPoints, lCount); + return S_OK; + } + HRESULT CDocument::PathCommandArcTo(double fX, double fY, double fWidth, double fHeight, double fStartAngle, double fSweepAngle) + { + m_oSimpleGraphicsConverter.PathCommandArcTo(fX, fY, fWidth, fHeight, fStartAngle, fSweepAngle); + return S_OK; + } + HRESULT CDocument::PathCommandClose() + { + if (c_nSimpleGraphicType == m_lCurrentCommandType) + m_oCurrentPage.PathClose(); + else + m_oSimpleGraphicsConverter.PathCommandClose(); + return S_OK; + } + HRESULT CDocument::PathCommandEnd() + { + if (c_nSimpleGraphicType == m_lCurrentCommandType) + m_oCurrentPage.PathEnd(); + else + m_oSimpleGraphicsConverter.PathCommandEnd(); + return S_OK; + } + HRESULT CDocument::DrawPath(long nType) + { + std::shared_ptr pInfo = nullptr; + if ((nType > 0xFF) && (c_BrushTypeTexture == m_oCurrentPage.m_oBrush.Type)) + { + double x = 0, y = 0, w = 0, h = 0; + if (m_oCurrentPage.m_oBrush.Image) + pInfo = m_oImageManager.WriteImage(m_oCurrentPage.m_oBrush.Image, x, y, w, h); + else + pInfo = m_oImageManager.WriteImage(m_oCurrentPage.m_oBrush.TexturePath, x, y, w, h); + } + m_oCurrentPage.DrawPath(nType, pInfo); + return S_OK; + } + HRESULT CDocument::PathCommandStart() + { + if (c_nSimpleGraphicType == m_lCurrentCommandType) + m_oCurrentPage.PathStart(); + else + m_oSimpleGraphicsConverter.PathCommandStart(); + return S_OK; + } + HRESULT CDocument::PathCommandGetCurrentPoint(double* fX, double* fY) + { + m_oSimpleGraphicsConverter.PathCommandGetCurrentPoint(fX, fY); + return S_OK; + } + + HRESULT CDocument::PathCommandTextCHAR(const int& lUnicode, const double& dX, const double& dY, const double& dW, const double& dH) + { + _SetFont(); + m_oSimpleGraphicsConverter.PathCommandText2(&lUnicode, nullptr, 1, m_pBaseFontManager, dX, dY, dW, dH); + return S_OK; + } + HRESULT CDocument::PathCommandTextExCHAR(const int& lUnicode, const int& lGid, const double& dX, const double& dY, const double& dW, const double& dH) + { + _SetFont(); + m_oSimpleGraphicsConverter.PathCommandText2(&lUnicode, &lGid, 1, m_pBaseFontManager, dX, dY, dW, dH); + return S_OK; + } + HRESULT CDocument::PathCommandText(const std::wstring& wsUnicodeText, const double& dX, const double& dY, const double& dW, const double& dH) + { + _SetFont(); + m_oSimpleGraphicsConverter.PathCommandText(wsUnicodeText, m_pBaseFontManager, dX, dY, dW, dH, 0); + return S_OK; + } + HRESULT CDocument::PathCommandTextEx(const std::wstring& wsUnicodeText, const unsigned int* pGids, const unsigned int nGidsCount, const double& dX, const double& dY, const double& dW, const double& dH) + { + _SetFont(); + m_oSimpleGraphicsConverter.PathCommandText2(wsUnicodeText, (const int*)pGids, nGidsCount, m_pBaseFontManager, dX, dY, dW, dH); + return S_OK; + } + + HRESULT CDocument::GetCommandParams(double* dAngle, double* dLeft, double* dTop, double* dWidth, double* dHeight, DWORD* lFlags) + { + return S_OK; + } + HRESULT CDocument::SetCommandParams(double dAngle, double dLeft, double dTop, double dWidth, double dHeight, DWORD lFlags) + { + ApplyTransform2(dAngle, dLeft, dTop, dWidth, dHeight, lFlags); + return S_OK; + } + //-------- Функции для вывода изображений -------------------------------------------------- + HRESULT CDocument::DrawImage(IGrObject* pImage, double fX, double fY, double fWidth, double fHeight) + { + m_oCurrentPage.WriteImage(m_oImageManager.WriteImage((Aggplus::CImage*)pImage, fX, fY, fWidth, fHeight), fX, fY, fWidth, fHeight); + return S_OK; + } + HRESULT CDocument::DrawImageFromFile(const std::wstring& sVal, double fX, double fY, double fWidth, double fHeight) + { + m_oCurrentPage.WriteImage(m_oImageManager.WriteImage(sVal, fX, fY, fWidth, fHeight), fX, fY, fWidth, fHeight); + return S_OK; + } + //------------------------------------------------------------------------------------------ + HRESULT CDocument::SetTransform(double dA, double dB, double dC, double dD, double dE, double dF) + { + ApplyTransform(dA, dB, dC, dD, dE, dF); + return S_OK; + } + HRESULT CDocument::GetTransform(double *pdA, double *pdB, double *pdC, double *pdD, double *pdE, double *pdF) + { + return S_OK; + } + HRESULT CDocument::ResetTransform(void) + { + m_oCurrentPage.m_oTransform.Reset(); + return S_OK; + } + HRESULT CDocument::get_ClipMode(LONG* plMode) + { + *plMode = m_oCurrentPage.m_lClipMode; + return S_OK; + } + HRESULT CDocument::put_ClipMode(LONG lMode) + { + m_oCurrentPage.m_lClipMode = lMode; + return S_OK; + } + + void CDocument::ApplyTransform(double d1, double d2, double d3, double d4, double d5, double d6) + { + m_oCurrentPage.m_oTransform.SetElements(d1, d2, d3, d4, d5, d6); + } + + void CDocument::ApplyTransform2(double dAngle, double dLeft, double dTop, double dWidth, double dHeight, DWORD lFlags) + { + if ((dWidth <= 1) || (dHeight <= 1)) + lFlags = 0; + + bool bFlipX = (0 != (c_nParamFlipX & lFlags)); + bool bFlipY = (0 != (c_nParamFlipY & lFlags)); + + double m11 = bFlipX ? -1.0 : 1.0; + double m22 = bFlipY ? -1.0 : 1.0; + + Aggplus::CMatrix oMatrix(1, 0, 0, 1, 0, 0); + + if ((0 != dAngle) || (0 != lFlags)) + { + double dCentreX = (dLeft + dWidth / 2.0); + double dCentreY = (dTop + dHeight / 2.0); + + oMatrix.Translate(-dCentreX, -dCentreY, Aggplus::MatrixOrderAppend); + oMatrix.Rotate(dAngle, Aggplus::MatrixOrderAppend); + oMatrix.Scale(m11, m22, Aggplus::MatrixOrderAppend); + oMatrix.Translate(dCentreX, dCentreY, Aggplus::MatrixOrderAppend); + } + + m_oCurrentPage.m_oTransform = oMatrix; + } + + void CDocument::_SetFont() + { + if (nullptr == m_pBaseFontManager) + { + m_pBaseFontManager = m_pAppFonts->GenerateFontManager(); + m_pBaseFontManager->CreateOwnerCache(8); + } + + double dPix = m_oCurrentPage.m_oFont.CharSpace * m_dDpiX / 25.4; + if (m_oInstalledFont.IsEqual(&m_oCurrentPage.m_oFont)) + { + if (1 < m_dWidth) + { + m_pBaseFontManager->SetCharSpacing(dPix); + } + return; + } + + m_pBaseFontManager->SetStringGID(m_oCurrentPage.m_oFont.StringGID); + if (1 < m_dWidth) + m_pBaseFontManager->SetCharSpacing(dPix); + + if (m_oCurrentPage.m_oFont.Path.empty()) + m_pBaseFontManager->LoadFontByName(m_oCurrentPage.m_oFont.Name, (float)m_oCurrentPage.m_oFont.Size, m_oCurrentPage.m_oFont.GetStyle(), m_dDpiX, m_dDpiY); + else + m_pBaseFontManager->LoadFontFromFile(m_oCurrentPage.m_oFont.Path, m_oCurrentPage.m_oFont.FaceIndex, (float)m_oCurrentPage.m_oFont.Size, m_dDpiX, m_dDpiY); + m_oInstalledFont = m_oCurrentPage.m_oFont; + } + + void CDocument::Init(bool bIsClearStreams) + { + Clear(); + + // Сбросим кэш шрифтов. По идее можно оставлять кэш для шрифтов "по имени", + // но для шрифтов из темповых папок - нет. Темповая папка для Reader (PDF/XPS/DJVU) + // может быть одной и той же. И создание там файлов функцией создания временных файлов + // может вернуть один и тот же путь. И шрифт возьмется из старого файла. + m_oFontSelector.ClearCache(); + m_oFontManager.ClearCache(); + if (m_pAppFonts && bIsClearStreams) m_pAppFonts->GetStreams()->Clear(); + } + +#ifndef DISABLE_FULL_DOCUMENT_CREATION + void CDocument::CreateTemplates() + { + CreateTemplate(m_strTempDirectory); + m_oImageManager.m_strDstMedia = m_strTempDirectory + L"/word/media"; + NSDirectory::CreateDirectory(m_oImageManager.m_strDstMedia); + } + + void CDocument::Write() + { + BuildDocumentXml(); + BuildDocumentXmlRels(); + BuildFontTableXml(); + BuildStylesXml(); + } + + void CDocument::BuildDocumentXml() + { + NSFile::CFileBinary oDocumentStream; + + oDocumentStream.CreateFileW(m_strTempDirectory + L"/word/document.xml"); + oDocumentStream.WriteStringUTF8(L"\ + \ + "); + + for (size_t i = 0; i < m_mapXmlString.size(); ++i) + { + oDocumentStream.WriteStringUTF8(m_mapXmlString[i]->GetData()); + } + + oDocumentStream.WriteStringUTF8(L""); + + oDocumentStream.CloseFile(); + } + + void CDocument::BuildDocumentXmlRels() + { + // сохраним rels (images & docs) + NSStringUtils::CStringBuilder oWriter; + + oWriter.WriteString(L"\ + \ + \ + \ + \ + \ + "); + + for (const auto& pImage : m_oImageManager.m_mapImageData) + { + auto pInfo = pImage.second; + + oWriter.WriteString(L"m_nId); + oWriter.WriteString(L"\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image\" Target=\"media/"); + oWriter.WriteString(pInfo->m_strFileName); + oWriter.WriteString(L"\"/>"); + } + + oWriter.WriteString(L""); + + NSFile::CFileBinary::SaveToFile(m_strTempDirectory + L"/word/_rels/document.xml.rels", oWriter.GetData()); + oWriter.ClearNoAttack(); + } + + void CDocument::BuildFontTableXml() + { + NSStringUtils::CStringBuilder oWriter; + // сохраним fontTable + oWriter.WriteString(L"\ + "); + + const auto& cache = m_oFontSelector.GetCache(); + std::list font_table; + std::map ar_is_written; + for (const auto& info : cache) + { + if (!ar_is_written[info.wsSelectedName]) + { + font_table.push_back(info); + ar_is_written[info.wsSelectedName] = true; + } + } + + for (auto& val : font_table) + { + if (val.wsSelectedName.empty()) + continue; + + oWriter.WriteString(L""); + + oWriter.WriteString(L"> 4); + char c2 = (char)(uc & 0x0F); + strPANOSE += (wchar_t)((c1 < 10) ? ('0' + c1) : ('A' + c1 - 10)); + strPANOSE += (wchar_t)((c2 < 10) ? ('0' + c2) : ('A' + c2 - 10)); + } + oWriter.WriteString(strPANOSE); + oWriter.WriteString(L"\"/>"); + + if (val.oFontSelectParams.bIsFixedWidth) + oWriter.WriteString(L""); + else + oWriter.WriteString(L""); + + oWriter.WriteString(L""); + + if (!val.oFontSelectParams.arSignature.empty()) + { + oWriter.WriteString(L""); + } + + oWriter.WriteString(L""); + } + + oWriter.WriteString(L""); + NSFile::CFileBinary::SaveToFile(m_strTempDirectory + L"/word/fontTable.xml", oWriter.GetData()); + } + + void CDocument::BuildStylesXml() + { + NSStringUtils::CStringBuilder oWriter; + + // сохраним styles + oWriter.WriteString(L"\ + "); + + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); //отключение проверки орфографии + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + + //oWriter.WriteString(L""); + //oWriter.WriteString(L""); + + m_oFontStyleManager.ToXml(oWriter); + m_oParagraphStyleManager.ToXml(oWriter); + + oWriter.WriteString(L""); + + NSFile::CFileBinary::SaveToFile(m_strTempDirectory + L"/word/styles.xml", oWriter.GetData()); + } +#endif } diff --git a/DocxRenderer/src/logic/Document.h b/DocxRenderer/src/logic/Document.h index c27fc561d13..da4c07b199d 100644 --- a/DocxRenderer/src/logic/Document.h +++ b/DocxRenderer/src/logic/Document.h @@ -1,206 +1,197 @@ #pragma once +#include "../../../DesktopEditor/common/Directory.h" + #include "Page.h" -#include "../DesktopEditor/common/Directory.h" -#include "../resources/resources.h" #include "managers/ImageManager.h" -#include "managers/StyleManager.h" +#include "managers/FontStyleManager.h" +#include "managers/ParagraphStyleManager.h" + namespace NSDocxRenderer { - class CDocument + class CDocument { public: - NSFonts::IApplicationFonts* m_pAppFonts; - - NSStructures::CPen m_oPen; - NSStructures::CBrush m_oBrush; - NSStructures::CFont m_oFont; - NSStructures::CShadow m_oShadow; - NSStructures::CEdgeText m_oEdge; - - NSStructures::CFont m_oInstalledFont; - - NSFonts::IFontManager* m_pFontManager {nullptr}; - Aggplus::CGraphicsPathSimpleConverter m_oSimpleGraphicsConverter; - - Aggplus::CMatrix m_oTransform; + Aggplus::CGraphicsPathSimpleConverter m_oSimpleGraphicsConverter; - LONG m_lCurrentCommandType {0}; + NSFonts::IApplicationFonts* m_pAppFonts {nullptr}; + NSFonts::IFontManager* m_pBaseFontManager{nullptr}; + NSStructures::CFont m_oInstalledFont; - LONG m_lClipMode; - CPage m_oCurrentPage; + CImageManager m_oImageManager; + CFontStyleManager m_oFontStyleManager; + CParagraphStyleManager m_oParagraphStyleManager; + CFontManager m_oFontManager; + CFontSelector m_oFontSelector; - CImageManager m_oImageManager; - CStyleManager m_oStyleManager; + CPage m_oCurrentPage; + LONG m_lCurrentCommandType {0}; - double m_dWidth {0.0}; - double m_dHeight {0.0}; + double m_dWidth {0.0}; + double m_dHeight {0.0}; + double m_dDpiX {72.0}; + double m_dDpiY {72.0}; - double m_dDpiX {72.0}; - double m_dDpiY {72.0}; + std::wstring m_strTempDirectory {L""}; + std::wstring m_strDstFilePath; - std::wstring m_strTempDirectory {L""}; - std::wstring m_strDstFilePath; + LONG m_lPageNum {0}; + LONG m_lNumberPages{0}; - NSFile::CFileBinary m_oDocumentStream; - LONG m_lPagesCount {0}; + bool m_bIsDisablePageCommand {false}; // disable commands inside draw function - NSStringUtils::CStringBuilder m_oWriter; - bool m_bIsNeedPDFTextAnalyzer {false}; - - bool m_bIsDisablePageCommand {false}; // disable commands inside draw function + std::map m_mapXmlString; public: - CDocument(IRenderer* pRenderer, NSFonts::IApplicationFonts* pFonts); - void Clear(); - - ~CDocument(); + CDocument(IRenderer* pRenderer, NSFonts::IApplicationFonts* pFonts); + ~CDocument(); public: - - HRESULT NewPage(); - HRESULT get_Height(double* dHeight); - HRESULT put_Height(double dHeight); - HRESULT get_Width(double* dWidth); - HRESULT put_Width(double dWidth); - HRESULT get_DpiX(double* dDpiX); - HRESULT get_DpiY(double* dDpiY); - //-------- Функции для задания настроек текста ---------------------------------------------- - // pen -------------------------------------------------------------------------------------- - HRESULT get_PenColor(LONG* lColor); - HRESULT put_PenColor(LONG lColor); - HRESULT get_PenAlpha(LONG* lAlpha); - HRESULT put_PenAlpha(LONG lAlpha); - HRESULT get_PenSize(double* dSize); - HRESULT put_PenSize(double dSize); - HRESULT get_PenDashStyle(BYTE* val); - HRESULT put_PenDashStyle(BYTE val); - HRESULT get_PenLineStartCap(BYTE* val); - HRESULT put_PenLineStartCap(BYTE val); - HRESULT get_PenLineEndCap(BYTE* val); - HRESULT put_PenLineEndCap(BYTE val); - HRESULT get_PenLineJoin(BYTE* val); - HRESULT put_PenLineJoin(BYTE val); - HRESULT get_PenDashOffset(double* val); - HRESULT put_PenDashOffset(double val); - HRESULT get_PenAlign(LONG* val); - HRESULT put_PenAlign(LONG val); - HRESULT get_PenMiterLimit(double* val); - HRESULT put_PenMiterLimit(double val); - HRESULT PenDashPattern(double* pPattern, LONG lCount); - // brush ------------------------------------------------------------------------------------ - HRESULT get_BrushType(LONG* lType); - HRESULT put_BrushType(LONG lType); - HRESULT get_BrushColor1(LONG* lColor); - HRESULT put_BrushColor1(LONG lColor); - HRESULT get_BrushAlpha1(LONG* lAlpha); - HRESULT put_BrushAlpha1(LONG lAlpha); - HRESULT get_BrushColor2(LONG* lColor); - HRESULT put_BrushColor2(LONG lColor); - HRESULT get_BrushAlpha2(LONG* lAlpha); - HRESULT put_BrushAlpha2(LONG lAlpha); - HRESULT get_BrushTexturePath(std::wstring* sPath); - HRESULT put_BrushTexturePath(const std::wstring& sPath); - HRESULT get_BrushTextureMode(LONG* lMode); - HRESULT put_BrushTextureMode(LONG lMode); - HRESULT get_BrushTextureAlpha(LONG* lTxAlpha); - HRESULT put_BrushTextureAlpha(LONG lTxAlpha); - HRESULT get_BrushLinearAngle(double* dAngle); - HRESULT put_BrushLinearAngle(double dAngle); - HRESULT BrushRect(bool val, double left, double top, double width, double height); - // font ------------------------------------------------------------------------------------- - HRESULT get_FontName(std::wstring* sName); - HRESULT put_FontName(std::wstring sName); - HRESULT get_FontPath(std::wstring* sPath); - HRESULT put_FontPath(std::wstring sPath); - HRESULT get_FontSize(double* dSize); - HRESULT put_FontSize(double dSize); - HRESULT get_FontStyle(LONG* lStyle); - HRESULT put_FontStyle(LONG lStyle); - HRESULT get_FontStringGID(INT* bGID); - HRESULT put_FontStringGID(INT bGID); - HRESULT get_FontCharSpace(double* dSpace); - HRESULT put_FontCharSpace(double dSpace); - HRESULT get_FontFaceIndex(int* lFaceIndex); - HRESULT put_FontFaceIndex(const int& lFaceIndex); - // shadow ----------------------------------------------------------------------------------- - HRESULT get_ShadowDistanceX(double* val); - HRESULT put_ShadowDistanceX(double val); - HRESULT get_ShadowDistanceY(double* val); - HRESULT put_ShadowDistanceY(double val); - HRESULT get_ShadowBlurSize(double* val); - HRESULT put_ShadowBlurSize(double val); - HRESULT get_ShadowColor(LONG* val); - HRESULT put_ShadowColor(LONG val); - HRESULT get_ShadowAlpha(LONG* val); - HRESULT put_ShadowAlpha(LONG val); - HRESULT get_ShadowVisible(INT* val); - HRESULT put_ShadowVisible(INT val); - // edge ------------------------------------------------------------------------------------- - HRESULT get_EdgeVisible(LONG* val); - HRESULT put_EdgeVisible(LONG val); - HRESULT get_EdgeColor(LONG* val); - HRESULT put_EdgeColor(LONG val); - HRESULT get_EdgeAlpha(LONG* val); - HRESULT put_EdgeAlpha(LONG val); - HRESULT get_EdgeDist(double* val); - HRESULT put_EdgeDist(double val); - //-------- Функции для вывода текста -------------------------------------------------------- - HRESULT CommandDrawTextPrivate(const int* pUnicodes, const int* pGids, int nCount, - const double& dX, const double& dY, const double& dW, - const double& dH, const double& dBaseLineOffset = 0); - HRESULT CommandDrawTextCHAR(const int& lUnicode, const double& dX, const double& dY, const double& dW, const double& dH); - HRESULT CommandDrawTextExCHAR(const int& lUnicode, const int& lGid, const double& dX, const double& dY, const double& dW, const double& dH); - virtual HRESULT CommandDrawText(const std::wstring& wsUnicodeText, const double& dX, const double& dY, const double& dW, const double& dH); - virtual HRESULT CommandDrawTextEx(const std::wstring& wsUnicodeText, const unsigned int* pGids, - const unsigned int nGidsCount, const double& dX, const double& dY, - const double& dW, const double& dH); - //-------- Маркеры для команд --------------------------------------------------------------- - HRESULT BeginCommand(DWORD lType); - HRESULT EndCommand(DWORD lType); - //-------- Функции для работы с Graphics Path ----------------------------------------------- - HRESULT PathCommandMoveTo(double fX, double fY); - HRESULT PathCommandLineTo(double fX, double fY); - HRESULT PathCommandLinesTo(double* pPoints, LONG lCount); - HRESULT PathCommandCurveTo(double fX1, double fY1, double fX2, double fY2, double fX3, double fY3); - HRESULT PathCommandCurvesTo(double* pPoints, LONG lCount); - HRESULT PathCommandArcTo(double fX, double fY, double fWidth, double fHeight, double fStartAngle, double fSweepAngle); - HRESULT PathCommandClose(); - HRESULT PathCommandEnd(); - HRESULT DrawPath(long nType); - HRESULT PathCommandStart(); - HRESULT PathCommandGetCurrentPoint(double* fX, double* fY); - - HRESULT PathCommandTextCHAR(const int& lUnicode, const double& dX, const double& dY, const double& dW, const double& dH); - HRESULT PathCommandTextExCHAR(const int& lUnicode, const int& lGid, const double& dX, const double& dY, const double& dW, const double& dH); - HRESULT PathCommandText(const std::wstring& wsUnicodeText, const double& dX, const double& dY, const double& dW, const double& dH); - HRESULT PathCommandTextEx(const std::wstring& wsUnicodeText, const unsigned int* pGids, const unsigned int nGidsCount, const double& dX, const double& dY, const double& dW, const double& dH); - - HRESULT GetCommandParams(double* dAngle, double* dLeft, double* dTop, double* dWidth, double* dHeight, DWORD* lFlags); - HRESULT SetCommandParams(double dAngle, double dLeft, double dTop, double dWidth, double dHeight, DWORD lFlags); - //-------- Функции для вывода изображений -------------------------------------------------- - HRESULT DrawImage(IGrObject* pImage, double fX, double fY, double fWidth, double fHeight); - HRESULT DrawImageFromFile(const std::wstring& sVal, double fX, double fY, double fWidth, double fHeight); - //------------------------------------------------------------------------------------------ - HRESULT SetTransform(double dA, double dB, double dC, double dD, double dE, double dF); - HRESULT GetTransform(double *pdA, double *pdB, double *pdC, double *pdD, double *pdE, double *pdF); - HRESULT ResetTransform(void); - HRESULT get_ClipMode(LONG* plMode); - HRESULT put_ClipMode(LONG lMode); + HRESULT NewPage(); + HRESULT get_Height(double* dHeight); + HRESULT put_Height(double dHeight); + HRESULT get_Width(double* dWidth); + HRESULT put_Width(double dWidth); + HRESULT get_DpiX(double* dDpiX); + HRESULT get_DpiY(double* dDpiY); + + HRESULT get_PenColor(LONG* lColor); + HRESULT put_PenColor(LONG lColor); + HRESULT get_PenAlpha(LONG* lAlpha); + HRESULT put_PenAlpha(LONG lAlpha); + HRESULT get_PenSize(double* dSize); + HRESULT put_PenSize(double dSize); + HRESULT get_PenDashStyle(BYTE* val); + HRESULT put_PenDashStyle(BYTE val); + HRESULT get_PenLineStartCap(BYTE* val); + HRESULT put_PenLineStartCap(BYTE val); + HRESULT get_PenLineEndCap(BYTE* val); + HRESULT put_PenLineEndCap(BYTE val); + HRESULT get_PenLineJoin(BYTE* val); + HRESULT put_PenLineJoin(BYTE val); + HRESULT get_PenDashOffset(double* val); + HRESULT put_PenDashOffset(double val); + HRESULT get_PenAlign(LONG* val); + HRESULT put_PenAlign(LONG val); + HRESULT get_PenMiterLimit(double* val); + HRESULT put_PenMiterLimit(double val); + HRESULT PenDashPattern(double* pPattern, LONG lCount); + + HRESULT get_BrushType(LONG* lType); + HRESULT put_BrushType(LONG lType); + HRESULT get_BrushColor1(LONG* lColor); + HRESULT put_BrushColor1(LONG lColor); + HRESULT get_BrushAlpha1(LONG* lAlpha); + HRESULT put_BrushAlpha1(LONG lAlpha); + HRESULT get_BrushColor2(LONG* lColor); + HRESULT put_BrushColor2(LONG lColor); + HRESULT get_BrushAlpha2(LONG* lAlpha); + HRESULT put_BrushAlpha2(LONG lAlpha); + HRESULT get_BrushTexturePath(std::wstring* sPath); + HRESULT put_BrushTexturePath(const std::wstring& sPath); + HRESULT get_BrushTextureMode(LONG* lMode); + HRESULT put_BrushTextureMode(LONG lMode); + HRESULT get_BrushTextureAlpha(LONG* lTxAlpha); + HRESULT put_BrushTextureAlpha(LONG lTxAlpha); + HRESULT get_BrushLinearAngle(double* dAngle); + HRESULT put_BrushLinearAngle(double dAngle); + HRESULT BrushRect(bool val, double left, double top, double width, double height); + HRESULT BrushBounds(const double& dLeft, const double& dTop, const double& dWidth, const double& dHeight); + HRESULT put_BrushGradientColors(LONG* pColors, double* pPositions, LONG lCount); + HRESULT put_BrushGradInfo(void* pGradInfo); + + HRESULT get_FontName(std::wstring* sName); + HRESULT put_FontName(std::wstring sName); + HRESULT get_FontPath(std::wstring* sPath); + HRESULT put_FontPath(std::wstring sPath); + HRESULT get_FontSize(double* dSize); + HRESULT put_FontSize(double dSize); + HRESULT get_FontStyle(LONG* lStyle); + HRESULT put_FontStyle(LONG lStyle); + HRESULT get_FontStringGID(INT* bGID); + HRESULT put_FontStringGID(INT bGID); + HRESULT get_FontCharSpace(double* dSpace); + HRESULT put_FontCharSpace(double dSpace); + HRESULT get_FontFaceIndex(int* lFaceIndex); + HRESULT put_FontFaceIndex(const int& lFaceIndex); + + HRESULT get_ShadowDistanceX(double* val); + HRESULT put_ShadowDistanceX(double val); + HRESULT get_ShadowDistanceY(double* val); + HRESULT put_ShadowDistanceY(double val); + HRESULT get_ShadowBlurSize(double* val); + HRESULT put_ShadowBlurSize(double val); + HRESULT get_ShadowColor(LONG* val); + HRESULT put_ShadowColor(LONG val); + HRESULT get_ShadowAlpha(LONG* val); + HRESULT put_ShadowAlpha(LONG val); + HRESULT get_ShadowVisible(INT* val); + HRESULT put_ShadowVisible(INT val); + + HRESULT get_EdgeVisible(LONG* val); + HRESULT put_EdgeVisible(LONG val); + HRESULT get_EdgeColor(LONG* val); + HRESULT put_EdgeColor(LONG val); + HRESULT get_EdgeAlpha(LONG* val); + HRESULT put_EdgeAlpha(LONG val); + HRESULT get_EdgeDist(double* val); + HRESULT put_EdgeDist(double val); + + HRESULT CommandDrawTextPrivate(const int* pUnicodes, const int* pGids, int nCount, const double& dX, const double& dY, const double& dW, const double& dH, const double& dBaseLineOffset = 0); + HRESULT CommandDrawTextCHAR(const int& lUnicode, const double& dX, const double& dY, const double& dW, const double& dH); + HRESULT CommandDrawTextExCHAR(const int& lUnicode, const int& lGid, const double& dX, const double& dY, const double& dW, const double& dH); + virtual HRESULT CommandDrawText(const std::wstring& wsUnicodeText, const double& dX, const double& dY, const double& dW, const double& dH); + virtual HRESULT CommandDrawTextEx(const std::wstring& wsUnicodeText, const unsigned int* pGids, const unsigned int nGidsCount, const double& dX, const double& dY, const double& dW, const double& dH); + + HRESULT BeginCommand(DWORD lType); + HRESULT EndCommand(DWORD lType); + + HRESULT PathCommandMoveTo(double fX, double fY); + HRESULT PathCommandLineTo(double fX, double fY); + HRESULT PathCommandLinesTo(double* pPoints, LONG lCount); + HRESULT PathCommandCurveTo(double fX1, double fY1, double fX2, double fY2, double fX3, double fY3); + HRESULT PathCommandCurvesTo(double* pPoints, LONG lCount); + HRESULT PathCommandArcTo(double fX, double fY, double fWidth, double fHeight, double fStartAngle, double fSweepAngle); + HRESULT PathCommandClose(); + HRESULT PathCommandEnd(); + HRESULT DrawPath(long nType); + HRESULT PathCommandStart(); + HRESULT PathCommandGetCurrentPoint(double* fX, double* fY); + + HRESULT PathCommandTextCHAR(const int& lUnicode, const double& dX, const double& dY, const double& dW, const double& dH); + HRESULT PathCommandTextExCHAR(const int& lUnicode, const int& lGid, const double& dX, const double& dY, const double& dW, const double& dH); + HRESULT PathCommandText(const std::wstring& wsUnicodeText, const double& dX, const double& dY, const double& dW, const double& dH); + HRESULT PathCommandTextEx(const std::wstring& wsUnicodeText, const unsigned int* pGids, const unsigned int nGidsCount, const double& dX, const double& dY, const double& dW, const double& dH); + + HRESULT GetCommandParams(double* dAngle, double* dLeft, double* dTop, double* dWidth, double* dHeight, DWORD* lFlags); + HRESULT SetCommandParams(double dAngle, double dLeft, double dTop, double dWidth, double dHeight, DWORD lFlags); + + HRESULT DrawImage(IGrObject* pImage, double fX, double fY, double fWidth, double fHeight); + HRESULT DrawImageFromFile(const std::wstring& sVal, double fX, double fY, double fWidth, double fHeight); + + HRESULT SetTransform(double dA, double dB, double dC, double dD, double dE, double dF); + HRESULT GetTransform(double *pdA, double *pdB, double *pdC, double *pdD, double *pdE, double *pdF); + HRESULT ResetTransform(void); + HRESULT get_ClipMode(LONG* plMode); + HRESULT put_ClipMode(LONG lMode); protected: - void ApplyTransform(double d1, double d2, double d3, double d4, double d5, double d6); + void ApplyTransform(double d1, double d2, double d3, double d4, double d5, double d6); + void ApplyTransform2(double dAngle, double dLeft, double dTop, double dWidth, double dHeight, DWORD lFlags); + void _SetFont(); + public: - void ApplyTransform2(double dAngle, double dLeft, double dTop, double dWidth, double dHeight, DWORD lFlags); + void Init(bool bIsClearStreams = true); + void Clear(); - void _SetFont(); - public: - - bool CreateDocument(); +#ifndef DISABLE_FULL_DOCUMENT_CREATION + void BuildDocumentXml(); + void BuildDocumentXmlRels(); + void BuildFontTableXml(); + void BuildStylesXml(); - void Close(); - void BuildDocumentXmlRels(); - void BuildFontTableXml(); - void BuildStylesXml(); + void CreateTemplates(); + void Write(); +#endif }; } diff --git a/DocxRenderer/src/logic/ElementContText.cpp b/DocxRenderer/src/logic/ElementContText.cpp deleted file mode 100644 index 712994ae30e..00000000000 --- a/DocxRenderer/src/logic/ElementContText.cpp +++ /dev/null @@ -1,534 +0,0 @@ -#include "ElementContText.h" -#include "../resources/ColorTable.h" -#include "../resources/SingletonTemplate.h" -#include "../resources/utils.h" - -namespace NSDocxRenderer -{ - CContText::CContText(CFontManagerLight& oManagerLight): CBaseItem(ElemType::etContText), - m_pManagerLight(&oManagerLight) - { - } - - void CContText::Clear() - { - } - - CContText::CContText(const CContText& oSrc): CBaseItem(ElemType::etContText) - { - *this = oSrc; - } - - CContText& CContText::operator=(const CContText& oSrc) - { - if (this == &oSrc) - { - return *this; - } - - CBaseItem::operator=(oSrc); - - m_oFont = oSrc.m_oFont; - m_oBrush = oSrc.m_oBrush; - - m_strPickFontName = oSrc.m_strPickFontName; - m_lPickFontStyle = oSrc.m_lPickFontStyle; - - m_oText = oSrc.m_oText; - - m_dBaselineOffset = oSrc.m_dBaselineOffset; - m_dLastX = oSrc.m_dLastX; - m_dSpaceWidthMM = oSrc.m_dSpaceWidthMM; - - m_bIsNeedSpace = oSrc.m_bIsNeedSpace; - m_bIsDoubleStrikeout = oSrc.m_bIsDoubleStrikeout; - m_bIsHighlightPresent = oSrc.m_bIsHighlightPresent; - m_lHighlightColor = oSrc.m_lHighlightColor; - - m_eUnderlineType = oSrc.m_eUnderlineType; - m_lUnderlineColor = oSrc.m_lUnderlineColor; - - m_eVertAlignType = oSrc.m_eVertAlignType; - - m_bIsShadowPresent = oSrc.m_bIsShadowPresent; - m_bIsOutlinePresent = oSrc.m_bIsOutlinePresent; - m_bIsEmbossPresent = oSrc.m_bIsEmbossPresent; - m_bIsEngravePresent = oSrc.m_bIsEngravePresent; - - m_pShape = oSrc.m_pShape; - m_pManagerLight = oSrc.m_pManagerLight; - m_pCont = oSrc.m_pCont; -#if USING_DELETE_DUPLICATING_CONTS == 0 - m_pDuplicateCont = oSrc.m_pDuplicateCont; -#endif - - return *this; - } - - double CContText::GetIntersect(const CContText* oSrc) const - { - double d1 = std::max(m_dLeft, oSrc->m_dLeft); - double d2 = std::min(m_dLeft + m_dWidth, oSrc->m_dLeft + oSrc->m_dWidth); - - if (d2 > d1) - return d2 - d1; - return 0; - } - - void CContText::ToXml(NSStringUtils::CStringBuilder& oWriter) - { - if (m_bIsNotNecessaryToUse) - { - return; - } - - oWriter.WriteString(L""); - oWriter.WriteString(L""); - - oWriter.WriteString(L""); //отключение проверки орфографии - - if (m_strPickFontName.empty()) - { - if (m_oFont.Bold) - oWriter.WriteString(L""); - if (m_oFont.Italic) - oWriter.WriteString(L""); - - if (m_bIsNeedSpace) - { - m_dWidth += m_dSpaceWidthMM; - m_oText += L" "; - } - } - else - { - if (0x01 == (0x01 & m_lPickFontStyle)) - oWriter.WriteString(L""); - if (0x02 == (0x02 & m_lPickFontStyle)) - oWriter.WriteString(L""); - - if (m_bIsNeedSpace) - { - m_dWidth += m_pManagerLight->GetSpaceWidth(); - m_oText += L" "; - } - - if (m_eVertAlignType != eVertAlignType::vatSubscript && - m_eVertAlignType != eVertAlignType::vatSuperscript) - { - // нужно перемерять... - double ___dSize = (double)(static_cast(m_oFont.Size * 2)) / 2; - m_pManagerLight->LoadFont(m_strPickFontName, m_lPickFontStyle, ___dSize, false); - double dWidth = m_pManagerLight->MeasureStringWidth(m_oText.ToStdWString()); - - double dSpacing = (m_dWidth - dWidth) / (m_oText.length() + 1); - dSpacing *= c_dMMToDx; - - LONG lSpacing = static_cast(dSpacing); - //note принудительно уменьшаем spacing чтобы текстовые линии не выходили за правую границу - lSpacing -= 1; - - if (lSpacing != 0) - { - oWriter.WriteString(L""); - } - } - } - - if (m_bIsEmbossPresent) - { - oWriter.WriteString(L""); - } - else if (m_bIsEngravePresent) - { - oWriter.WriteString(L""); - } - else - { - if (m_bIsOutlinePresent) - { - oWriter.WriteString(L""); - } - if (m_bIsShadowPresent) - { - oWriter.WriteString(L""); - } - } - - int lSize = static_cast(2 * m_oFont.Size); - oWriter.WriteString(L""); - - std::wstring& strFontName = m_strPickFontName.empty() ? m_oFont.Name : m_strPickFontName; - oWriter.WriteString(L""); - - if (m_eVertAlignType == eVertAlignType::vatSubscript) - { - oWriter.WriteString(L""); - } - else if (m_eVertAlignType == eVertAlignType::vatSuperscript) - { - oWriter.WriteString(L""); - } - - if (ConvertColorBGRToRGB(m_oBrush.Color1) != c_iBlackColor) - { - oWriter.WriteString(L""); - } - - if (m_oFont.Strikeout == TRUE) - { - if (m_bIsDoubleStrikeout) - { - oWriter.WriteString(L""); - } - else - { - oWriter.WriteString(L""); - } - } - - if (m_oFont.Underline == TRUE) - { - oWriter.WriteString(L""); - } - - if (m_bIsHighlightPresent) - { - ColorTable& colorTable = SingletonInstance(); - if (colorTable.IsStandardColor(m_lHighlightColor)) - { - oWriter.WriteString(L""); - } - - oWriter.WriteString(L""); - - oWriter.WriteString(L""); - oWriter.WriteEncodeXmlString(m_oText.ToStdWString()); - oWriter.WriteString(L""); - - oWriter.WriteString(L""); - } - - void CContText::AddWideSpaceToXml(double dSpacingMM, - NSStringUtils::CStringBuilder& oWriter, - bool bIsNeedSaveFormat) - { - oWriter.WriteString(L""); - - double dSpaceMMSize = m_dSpaceWidthMM; - if (m_strPickFontName.empty()) - { - if (m_oFont.Bold && bIsNeedSaveFormat) - oWriter.WriteString(L""); - if (m_oFont.Italic && bIsNeedSaveFormat) - oWriter.WriteString(L""); - } - else - { - if (0x01 == (0x01 & m_lPickFontStyle) && bIsNeedSaveFormat) - oWriter.WriteString(L""); - if (0x02 == (0x02 & m_lPickFontStyle) && bIsNeedSaveFormat) - oWriter.WriteString(L""); - - dSpaceMMSize = m_pManagerLight->GetSpaceWidth(); - } - - int lSize = (int)(2 * m_oFont.Size); - oWriter.WriteString(L""); - - std::wstring& strFontName = m_strPickFontName.empty() ? m_oFont.Name : m_strPickFontName; - oWriter.WriteString(L""); - - oWriter.WriteString(L""); - - LONG lSpacing = static_cast((dSpacingMM - dSpaceMMSize) * c_dMMToDx); - //note принудительно уменьшаем spacing чтобы текстовые линии не выходили за правую границу - lSpacing -= 1; - if (lSpacing != 0) - { - oWriter.WriteString(L""); - } - - if (ConvertColorBGRToRGB(m_oBrush.Color1) != c_iBlackColor) - { - oWriter.WriteString(L""); - } - - if (m_oFont.Strikeout == TRUE && bIsNeedSaveFormat) - { - oWriter.WriteString(L""); - } - - if (m_oFont.Underline == TRUE && bIsNeedSaveFormat) - { - oWriter.WriteString(L""); - } - - if (m_bIsHighlightPresent && bIsNeedSaveFormat) - { - ColorTable& colorTable = SingletonInstance(); - if (colorTable.IsStandardColor(m_lHighlightColor)) - { - oWriter.WriteString(L""); - } - - oWriter.WriteString(L""); - - oWriter.WriteString(L""); - oWriter.WriteString(L" "); - oWriter.WriteString(L""); - - oWriter.WriteString(L""); - } - - void CContText::AddSpaceToEnd() - { - m_bIsNeedSpace = true; - m_dWidth += m_dSpaceWidthMM; - } - - bool CContText::IsEqual(const CContText* oSrc) - { - //todo Скорее всего это временное решение - bool bIf1 = true; //m_strPickFontName == oSrc->m_strPickFontName; - bool bIf2 = m_eUnderlineType == oSrc->m_eUnderlineType; - bool bIf3 = m_lUnderlineColor == oSrc->m_lUnderlineColor; - bool bIf4 = m_bIsHighlightPresent == oSrc->m_bIsHighlightPresent; - bool bIf5 = m_lHighlightColor == oSrc->m_lHighlightColor; - bool bIf6 = m_bIsDoubleStrikeout == oSrc->m_bIsDoubleStrikeout; - bool bIf7 = m_bIsShadowPresent == oSrc->m_bIsShadowPresent; - bool bIf8 = m_pShape == oSrc->m_pShape; - bool bIf9 = m_oFont.Name == L"" || oSrc->m_oFont.Name == L"" ? true : m_oFont.IsEqual(&oSrc->m_oFont); - bool bIf10 = m_oBrush.IsEqual(&oSrc->m_oBrush); - - if (bIf1 && bIf2 && bIf3 && bIf4 && bIf5 && bIf6 && bIf7 && bIf8 && bIf9 && bIf10) - /*if( m_strPickFontName == oSrc->m_strPickFontName && - m_eUnderlineType == oSrc->m_eUnderlineType && - m_lUnderlineColor == oSrc->m_lUnderlineColor && - m_bIsHighlightPresent == oSrc->m_bIsHighlightPresent && - m_lHighlightColor == oSrc->m_lHighlightColor && - m_bIsDoubleStrikeout == oSrc->m_bIsDoubleStrikeout && - m_bIsShadowPresent == oSrc->m_bIsShadowPresent && - //m_eVertAlignType == oSrc->m_eVertAlignType && - m_pShape == oSrc->m_pShape && - m_oFont.IsEqual(&oSrc->m_oFont) && - m_oBrush.IsEqual(&oSrc->m_oBrush))*/ - { - return true; - } - return false; - } - - bool CContText::IsDuplicate(CContText* pCont, const eVerticalCrossingType& eVType) - { - if (eVType == eVerticalCrossingType::vctDublicate && - m_oText == pCont->m_oText) - { -#if USING_DELETE_DUPLICATING_CONTS - pCont->m_bIsNotNecessaryToUse = true; -#else - //В итоге собираем список дубликатов - if (!m_pDuplicateCont) - { - m_pDuplicateCont = pCont; - } - return true; -#endif - } - return false; - } - - bool CContText::IsThereAreFontEffects(CContText* pCont, const eVerticalCrossingType& eVType, const eHorizontalCrossingType& eHType) - { - //Условие пересечения по вертикали - bool bIf1 = eVType == eVerticalCrossingType::vctCurrentAboveNext; //текущий cont выше - bool bIf2 = eVType == eVerticalCrossingType::vctCurrentBelowNext; //текущий cont ниже - //Условие пересечения по горизонтали - bool bIf3 = eHType == eHorizontalCrossingType::hctCurrentLeftOfNext; //текущий cont левее - bool bIf4 = eHType == eHorizontalCrossingType::hctCurrentRightOfNext; //текущий cont правее - //Размеры шрифта и текст должны бать одинаковыми - bool bIf5 = m_oFont.Size == pCont->m_oFont.Size; - bool bIf6 = m_oText == pCont->m_oText; - //Цвет тени должен быть серым - bool bIf7 = m_oBrush.Color1 == c_iGreyColor; - bool bIf8 = pCont->m_oBrush.Color1 == c_iGreyColor; - bool bIf9 = m_oBrush.Color1 == c_iBlackColor; - bool bIf10 = pCont->m_oBrush.Color1 == c_iBlackColor; - bool bIf11 = m_oBrush.Color1 == c_iGreyColor2; - bool bIf12 = pCont->m_oBrush.Color1 == c_iGreyColor2; - - //note Каждый символ с Emboss или Engrave разбиваются на 3 символа с разными цветами - //note Логика подобрана для конкретного примера - возможно нужно будет ее обобщить. - if (bIf5 && bIf6) - { - if (m_bIsEmbossPresent && bIf11) - { - if (bIf2 && bIf4) - { - pCont->m_bIsEmbossPresent = true; - m_bIsNotNecessaryToUse = true; - return true; - } - } - - if (m_bIsEngravePresent && bIf9) - { - if (bIf2 && bIf4) - { - pCont->m_bIsEngravePresent = true; - m_bIsNotNecessaryToUse = true; - return true; - } - } - - //Shadow - if (bIf1 && bIf3 && bIf8) - { - m_bIsShadowPresent = true; - pCont->m_bIsNotNecessaryToUse = true; - return true; - } - else if (bIf2 && bIf4 && bIf7) - { - pCont->m_bIsShadowPresent = true; - m_bIsNotNecessaryToUse = true; - return true; - } - - //Emboss - else if (bIf2 && bIf4 && bIf10) - { - m_bIsEmbossPresent = true; - pCont->m_bIsNotNecessaryToUse = true; - return true; - } - //Engrave - else if (bIf2 && bIf4 && bIf12) - { - m_bIsEngravePresent = true; - pCont->m_bIsNotNecessaryToUse = true; - return true; - } - } - return false; - } - - bool CContText::IsVertAlignTypeBetweenConts(CContText* pCont, const eVerticalCrossingType& eVType, const eHorizontalCrossingType& eHType) - { - //Условие пересечения по вертикали - bool bIf1 = eVType == eVerticalCrossingType::vctCurrentAboveNext || - eVType == eVerticalCrossingType::vctCurrentInsideNext; - bool bIf2 = eVType == eVerticalCrossingType::vctCurrentBelowNext; - //Условие пересечения по горизонтали - bool bIf3 = (eHType == eHorizontalCrossingType::hctNoCrossingCurrentLeftOfNext || - eHType == eHorizontalCrossingType::hctCurrentLeftOfNext) && - fabs(m_dRight - pCont->m_dLeft) < c_dTHE_STRING_X_PRECISION_MM * 3; - bool bIf4 = (eHType == eHorizontalCrossingType::hctNoCrossingCurrentRightOfNext || - eHType == eHorizontalCrossingType::hctCurrentRightOfNext) && - fabs(m_dLeft - pCont->m_dRight) < c_dTHE_STRING_X_PRECISION_MM * 3; - //Размеры шрифта должны бать разными - bool bIf5 = m_oFont.Size * 0.7 > pCont->m_oFont.Size; - bool bIf6 = m_oFont.Size < pCont->m_oFont.Size * 0.7; - - if (bIf3 || bIf4) - { - if (bIf1 && bIf5) - { - pCont->m_eVertAlignType = eVertAlignType::vatSubscript; - pCont->m_pCont = this; - m_eVertAlignType = eVertAlignType::vatBase; - m_pCont = pCont; - return true; - } - else if (bIf2 && bIf5) - { - pCont->m_eVertAlignType = eVertAlignType::vatSuperscript; - pCont->m_pCont = this; - m_eVertAlignType = eVertAlignType::vatBase; - m_pCont = pCont; - return true; - } - else if (bIf1 && bIf6) - { - m_eVertAlignType = eVertAlignType::vatSuperscript; - m_pCont = pCont; - pCont->m_eVertAlignType = eVertAlignType::vatBase; - pCont->m_pCont = this; - return true; - } - else if (bIf2 && bIf6) - { - m_eVertAlignType = eVertAlignType::vatSubscript; - m_pCont = pCont; - pCont->m_eVertAlignType = eVertAlignType::vatBase; - pCont->m_pCont = this; - return true; - } - } - return false; - } -} diff --git a/DocxRenderer/src/logic/ElementContText.h b/DocxRenderer/src/logic/ElementContText.h deleted file mode 100644 index 9c4f60c2528..00000000000 --- a/DocxRenderer/src/logic/ElementContText.h +++ /dev/null @@ -1,85 +0,0 @@ -#pragma once -#include "BaseItem.h" -#include "../DesktopEditor/common/StringBuilder.h" -#include "FontManager.h" -#include "../resources/Constants.h" -#include "../resources/LinesTable.h" - - -namespace NSDocxRenderer -{ - class CShape; - - enum class eVertAlignType - { - vatUnknown, - vatBase, - vatSubscript, - vatSuperscript - }; - - class CContText : public CBaseItem - { - public: - NSStructures::CFont m_oFont; - NSStructures::CBrush m_oBrush; - - std::wstring m_strPickFontName {L""}; - LONG m_lPickFontStyle {0}; - - NSStringUtils::CStringUTF32 m_oText; - - double m_dBaselineOffset {0}; - double m_dLastX {0}; - - double m_dSpaceWidthMM {0}; - - bool m_bIsNeedSpace {false}; - bool m_bIsDoubleStrikeout {false}; - bool m_bIsHighlightPresent {false}; - LONG m_lHighlightColor {c_iBlackColor}; - - eLineType m_eUnderlineType {eLineType::ltUnknown}; - LONG m_lUnderlineColor {c_iBlackColor}; - - eVertAlignType m_eVertAlignType {eVertAlignType::vatUnknown}; - - bool m_bIsShadowPresent {false}; - bool m_bIsOutlinePresent {false}; - bool m_bIsEmbossPresent {false}; - bool m_bIsEngravePresent {false}; - - const CShape* m_pShape {nullptr}; //Если не nullptr, то есть фоновая графика - можно анализировать. - CFontManagerLight* m_pManagerLight {nullptr}; - const CContText* m_pCont {nullptr}; //Если не nullptr, то есть привязка к vatSubscript или vatSuperscript; - -#if USING_DELETE_DUPLICATING_CONTS == 0 - CContText* m_pDuplicateCont {nullptr}; -#endif - - public: - CContText(CFontManagerLight& oManagerLight); - ~CContText(){} - - void Clear() override final; - - CContText(const CContText& oSrc); - - CContText& operator=(const CContText& oSrc); - - double GetIntersect(const CContText* oSrc) const; - - void ToXml(NSStringUtils::CStringBuilder& oWriter) override final; - - void AddWideSpaceToXml(double dSpacingMM, - NSStringUtils::CStringBuilder& oWriter, - bool bIsNeedSaveFormat = false); - - void AddSpaceToEnd(); - bool IsEqual(const CContText* oSrc); - - bool IsDuplicate(CContText* pCont, const eVerticalCrossingType& eVType); - bool IsThereAreFontEffects(CContText* pCont, const eVerticalCrossingType& eVType, const eHorizontalCrossingType& eHType); - bool IsVertAlignTypeBetweenConts(CContText* pCont, const eVerticalCrossingType& eVType, const eHorizontalCrossingType& eHType); - }; -} diff --git a/DocxRenderer/src/logic/ElementShape.h b/DocxRenderer/src/logic/ElementShape.h deleted file mode 100644 index 4ef67a19c4d..00000000000 --- a/DocxRenderer/src/logic/ElementShape.h +++ /dev/null @@ -1,94 +0,0 @@ -#pragma once -#include "ElementParagraph.h" -#include "../resources/LinesTable.h" -#include "../resources/VectorGraphics.h" -#include "ImageManager.h" - -namespace NSDocxRenderer -{ - enum class eGraphicsType - { - gtUnknown, - gtRectangle, - gtCurve, - gtComplicatedFigure, - gtNoGraphics, - }; - - class CShape : public CBaseItem - { - public: - enum class eShapeType - { - stUnknown, - stTextBox, - stPicture, - stVectorGraphics, - stVectorTexture, - stGroup, - stCanvas, - }; - - public: - eShapeType m_eType {eShapeType::stUnknown}; - std::wstring m_strPath {L""}; - NSStructures::CBrush m_oBrush; - NSStructures::CPen m_oPen; - double m_dRotate {0.0}; - - bool m_bIsNoFill {true}; - bool m_bIsNoStroke {true}; - bool m_bIsBehindDoc {true}; - - eGraphicsType m_eGraphicsType {eGraphicsType::gtUnknown}; - eSimpleLineType m_eSimpleLineType {eSimpleLineType::sltUnknown}; - eLineType m_eLineType {eLineType::ltUnknown}; - - std::vector m_arParagraphs; - - CImageInfo* m_pImageInfo {nullptr}; - - //Показывает, что есть отношение графики к тексту (подчеркивания/зачеркивания/выделение). - //note Пока сюда записывается указатель на символ с наибольшем размером шрифта. - const CContText* m_pCont {nullptr}; - - private: - UINT m_nShapeId {0}; - - public: - CShape(); - virtual ~CShape(); - virtual void Clear() override final; - - CShape(const CShape& oSrc); - CShape(CImageInfo* pInfo, const std::wstring& strDstMedia); - - CShape& operator=(const CShape& oSrc); - - void GetDataFromVector(const CVectorGraphics& oVector, const LONG& lTypee); - - void WritePath(const CVectorGraphics& oVector); - - void DetermineGraphicsType(const double& dWidth, const double& dHeight, const size_t& nPeacks, const size_t& nCurves); - - bool IsItFitLine(); - bool IsCorrelated(const CShape* pShape); - void ChangeGeometryOfDesiredShape(CShape* pShape); - - void DetermineLineType(CShape* pShape = nullptr, bool bIsLast = false); - - virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) override final; - void BuildGeneralProperties(NSStringUtils::CStringBuilder &oWriter); - void BuildSpecificProperties(NSStringUtils::CStringBuilder &oWriter); - void BuildShapeProperties(NSStringUtils::CStringBuilder &oWriter); - void BuildPictureProperties(NSStringUtils::CStringBuilder &oWriter); - void BuildGroupProperties(NSStringUtils::CStringBuilder &oWriter); - void BuildCanvasProperties(NSStringUtils::CStringBuilder &oWriter); - void BuildGraphicProperties(NSStringUtils::CStringBuilder &oWriter); - void BuildTextBox(NSStringUtils::CStringBuilder &oWriter); - - private: - UINT GenerateShapeId(); - UINT GenerateRelativeHeight(); - }; -} diff --git a/DocxRenderer/src/logic/ImageManager.h b/DocxRenderer/src/logic/ImageManager.h deleted file mode 100644 index e85acd06b31..00000000000 --- a/DocxRenderer/src/logic/ImageManager.h +++ /dev/null @@ -1,88 +0,0 @@ -#pragma once -#include "../DesktopEditor/common/StringBuilder.h" -#include "../DesktopEditor/common/CalculatorCRC32.h" -#include "../DesktopEditor/raster/BgraFrame.h" -#include - -namespace NSDocxRenderer -{ - class CImageInfo - { - public: - enum ImageType - { - itPNG = 0, - itJPG = 1 - }; - - public: - ImageType m_eType {itPNG}; - UINT m_nId {0}; - std::wstring m_strFileName {L""}; - - public: - CImageInfo(){} - - CImageInfo(const CImageInfo &oSrc) - { - *this = oSrc; - } - - CImageInfo& operator=(const CImageInfo &oSrc) - { - if (this == &oSrc) - { - return *this; - } - - m_eType = oSrc.m_eType; - m_nId = oSrc.m_nId; - m_strFileName = oSrc.m_strFileName; - - return *this; - } - - }; - - class CImageManager - { - public: - std::map m_mapImagesFile; - std::map m_mapImageData; - - std::wstring m_strDstMedia {L""}; - - int m_lMaxSizeImage {1200}; - int m_lNextIDImage {0}; - - CCalculatorCRC32 m_oCRC; - - public: - - CImageManager(){}; - - void NewDocument(); - - public: - CImageInfo WriteImage(Aggplus::CImage* pImage, double& x, double& y, double& width, double& height); - - CImageInfo WriteImage(const std::wstring& strFile, double& x, double& y, double& width, double& height); - - protected: - void CopyFile(std::wstring& strFileSrc, std::wstring& strFileDst); - - void SaveImage(const std::wstring& strFileSrc, CImageInfo& oInfo); - - void SaveImage(Aggplus::CImage* pImage, CImageInfo& oInfo); - - CImageInfo GenerateImageID(Aggplus::CImage* pImage); - - CImageInfo GenerateImageID(const std::wstring& strFileName); - - CImageInfo::ImageType GetImageType(Aggplus::CImage* pFrame); - - void FlipY(Aggplus::CImage* pImage); - - void FlipX(CBgraFrame* pImage); - }; -} diff --git a/DocxRenderer/src/logic/Page.cpp b/DocxRenderer/src/logic/Page.cpp index f8bf37a421a..c7525f5bc10 100644 --- a/DocxRenderer/src/logic/Page.cpp +++ b/DocxRenderer/src/logic/Page.cpp @@ -1,1549 +1,2158 @@ #include "Page.h" + +#include +#include + +#include "../../../DesktopEditor/graphics/GraphicsPath.h" +#include "../../../DesktopEditor/graphics/pro/Graphics.h" + #include "../resources/Constants.h" -#include "../resources/SortElements.h" #include "../resources/utils.h" -#include namespace NSDocxRenderer { - CPage::CPage(NSFonts::IApplicationFonts* pFonts) : m_oFontManager(pFonts), m_oFontManagerLight(pFonts) - { - } - - void CPage::Init(NSStructures::CFont* pFont, NSStructures::CPen* pPen, NSStructures::CBrush* pBrush, - NSStructures::CShadow* pShadow, NSStructures::CEdgeText* pEdge, Aggplus::CMatrix* pMatrix, - Aggplus::CGraphicsPathSimpleConverter* pSimple, CStyleManager* pStyleManager) - { - m_pFont = pFont; - m_pPen = pPen; - m_pBrush = pBrush; - m_pShadow = pShadow; - m_pEdgeText = pEdge; - - m_pTransform = pMatrix; - m_pSimpleGraphicsConverter = pSimple; - - m_pStyleManager = pStyleManager; - - m_oFontManager.m_pFont = m_pFont; - m_oFontManager.m_pTransform = m_pTransform; - - m_pCurrentLine = nullptr; - - m_dLastTextX = -1; - m_dLastTextY = -1; - m_dLastTextX_block = m_dLastTextX; - - CShape::ResetRelativeHeight(); - } - - void CPage::Clear() - { - ClearTextData(); - ClearTextLines(); - ClearParagraphs(); - ClearShapes(); - ClearImages(); - - m_pCurrentLine = nullptr; - - m_dLastTextX = -1; - m_dLastTextY = -1; - m_dLastTextX_block = m_dLastTextX; - } - - void CPage::ClearImages() - { - m_arImages.clear(); - } - - void CPage::ClearTextData() - { - m_arSymbol.clear(); - } - - void CPage::ClearTextLines() - { - m_arTextLine.clear(); - } - - void CPage::ClearShapes() - { - m_arShapes.clear(); - } - - void CPage::ClearParagraphs() - { - m_arParagraphs.clear(); - } - - CPage::~CPage() - { - Clear(); - } - - void CPage::DeleteTextClipPage() - { - if (m_bIsDeleteTextClipPage) - { - // удалим все линии, которые выходят за границы страницы - for (const auto &pLine : m_arTextLine) - { - if (pLine->m_dTop >= m_dHeight || pLine->m_dBaselinePos <= 0) - { - pLine->m_bIsNotNecessaryToUse = true; - } - } - } - } - - // image commands - void CPage::WriteImage(const std::shared_ptr pInfo, double& fX, double& fY, double& fWidth, double& fHeight) - { - auto pImage = new CShape(pInfo, L""); - pImage->m_eType = CShape::eShapeType::stPicture; - - double dRotation = m_pTransform->z_Rotation(); - - if (fabs(dRotation) < 5.0) - { - double x1 = fX; - double y1 = fY; - double x2 = fX + fWidth; - double y2 = fY + fHeight; - - m_pTransform->TransformPoint(x1, y1); - m_pTransform->TransformPoint(x2, y2); - - if (x1 <= x2) - { - pImage->m_dLeft = x1; - pImage->m_dWidth = x2 - x1; - } - else - { - pImage->m_dLeft = x2; - pImage->m_dWidth = x1 - x2; - } - - if (y1 <= y2) - { - pImage->m_dTop = y1; - pImage->m_dHeight = y2 - y1; - } - else - { - pImage->m_dTop = y2; - pImage->m_dHeight = y1 - y2; - } - - pImage->m_dRotate = 0.0; - } - else - { - double x1 = fX; - double y1 = fY; - double x2 = fX + fWidth; - double y2 = fY + fHeight; - - Aggplus::CMatrix oTemp = *m_pTransform; - - double dCx = (x1 + x2) / 2; - double dCy = (y1 + y2) / 2; - m_pTransform->TransformPoint(dCx, dCy); - oTemp.RotateAt(-dRotation, dCx, dCy, Aggplus::MatrixOrderAppend); - - oTemp.TransformPoint(x1, y1); - oTemp.TransformPoint(x2, y2); - - if (x1 <= x2) - { - pImage->m_dLeft = x1; - pImage->m_dWidth = x2 - x1; - } - else - { - pImage->m_dLeft = x2; - pImage->m_dWidth = x1 - x2; - } - - if (y1 <= y2) - { - pImage->m_dTop = y1; - pImage->m_dHeight = y2 - y1; - } - else - { - pImage->m_dTop = y2; - pImage->m_dHeight = y1 - y2; - } - - pImage->m_dRotate = dRotation; - } - - pImage->m_dBaselinePos = pImage->m_dTop + pImage->m_dHeight; - pImage->m_dRight = pImage->m_dLeft + pImage->m_dWidth; - - m_arImages.push_back(pImage); - } - - // path commands - void CPage::MoveTo(double& dX, double& dY) - { - m_pTransform->TransformPoint(dX, dY); - m_oVector.MoveTo(dX, dY); - } - - void CPage::LineTo(double& dX, double& dY) - { - m_pTransform->TransformPoint(dX, dY); - m_oVector.LineTo(dX, dY); - } - - void CPage::CurveTo(double& x1, double& y1, double& x2, double& y2, double& x3, double& y3) - { - m_pTransform->TransformPoint(x1, y1); - m_pTransform->TransformPoint(x2, y2); - m_pTransform->TransformPoint(x3, y3); - - m_oVector.CurveTo(x1, y1, x2, y2, x3, y3); - } - - void CPage::Start() - { - } - - void CPage::End() - { - m_oVector.End(); - } - - void CPage::Close() - { - m_oVector.Close(); - } - - void CPage::DrawPath(LONG lType, const std::shared_ptr pInfo) - { - if ((m_oVector.m_dLeft <= m_oVector.m_dRight) && (m_oVector.m_dTop <= m_oVector.m_dBottom)) - { - if (!m_arShapes.empty()) - { - auto pLastShape = m_arShapes.back(); - - if (pLastShape->m_dLeft == m_oVector.m_dLeft && - pLastShape->m_dTop == m_oVector.m_dTop && - pLastShape->m_dWidth == m_oVector.m_dRight - m_oVector.m_dLeft && - pLastShape->m_dHeight == m_oVector.m_dBottom - m_oVector.m_dTop) - { - if (0x00 != (lType & 0x01)) - { - pLastShape->m_bIsNoStroke = false; - pLastShape->m_oPen = *m_pPen; - } - if (0x00 != (lType >> 8)) - { - pLastShape->m_bIsNoFill = false; - pLastShape->m_oBrush = *m_pBrush; - } - return; - } - } - - auto pShape = new CShape(); - - if (pInfo) - { - pShape->m_pImageInfo = pInfo; - pShape->m_eType = CShape::eShapeType::stVectorTexture; - } - else - { - pShape->m_eType = CShape::eShapeType::stVectorGraphics; - } - - if (0x00 != (lType & 0x01)) - { - pShape->m_bIsNoStroke = false; - pShape->m_oPen = *m_pPen; - } - if (0x00 != (lType >> 8)) - { - pShape->m_bIsNoFill = false; - pShape->m_oBrush = *m_pBrush; - } - - if (pShape->m_bIsNoStroke) - { - if ((fabs(m_oVector.m_dLeft - m_oVector.m_dRight) < 0.3) || (fabs(m_oVector.m_dTop - m_oVector.m_dBottom) < 0.3)) - { - pShape->m_oPen.Color = m_pBrush->Color1; - pShape->m_oPen.Alpha = m_pBrush->Alpha1; - } - } - - pShape->GetDataFromVector(m_oVector); - - m_arShapes.push_back(pShape); - - double dDeterminant = sqrt(fabs(m_pTransform->Determinant())); - pShape->m_oPen.Size *= dDeterminant; - } - } - - void CPage::CollectTextData(const PUINT pUnicodes, const PUINT pGids, const UINT& nCount, - const double& fX, const double& fY, const double& fWidth, const double& fHeight, - const double& fBaseLineOffset, const bool& bIsPDFAnalyzer) - { - if (pUnicodes != nullptr && nCount == 1 && IsSpaceUtf32(*pUnicodes)) - { - //note пробелы не нужны, добавляются при анализе - return; - } - - double dTextX = fX; - double dTextY = fY; - double dTextR = fX + fWidth; - double dTextB = fY + fHeight; - - m_pTransform->TransformPoint(dTextX, dTextY); - m_pTransform->TransformPoint(dTextR, dTextB); - - double dTextW = dTextR - dTextX; - double dTextH = dTextB - dTextY; - - NSStringUtils::CStringUTF32 oText((uint32_t*)pUnicodes, nCount); - - if ((pUnicodes != nullptr) && (pGids != nullptr)) - { - for (unsigned int i = 0; i < nCount; ++i) - { - if ( !IsUnicodeSymbol( pUnicodes[i] ) ) - { - oText[i] = ' '; - } - } - } - - bool bIsPath = ((nullptr == pGids) && !bIsPDFAnalyzer) ? false : true; - - m_oFontManager.LoadFont(0, !bIsPath); - - if (bIsPath) - m_oFontManager.GenerateFontName2(oText); - - if (fabs(dTextW) < 0.01 || (dTextW > 10)) - { - double _x = 0; - double _y = 0; - double _w = 0; - double _h = 0; - - if (nullptr != pGids) - { - m_oFontManager.SetStringGid(1); - m_oFontManager.MeasureStringGids(pGids, nCount, dTextX, dTextY, _x, _y, _w, _h, CFontManager::mtPosition); - } - else - { - // такого быть не должно (только из xps) - m_oFontManager.SetStringGid(0); - m_oFontManager.MeasureStringGids(pUnicodes, nCount, dTextX, dTextY, _x, _y, _w, _h, CFontManager::mtPosition); - } - - dTextW = _w; - } - - double dBaseLinePos = dTextY + fBaseLineOffset; - dTextH = m_oFontManager.GetFontHeight(); - - auto pCont = new CContText(&m_oFontManagerLight, m_pStyleManager); - - pCont->m_dLeft = dTextX; - pCont->m_dBaselinePos = dBaseLinePos; - pCont->m_dLastX = dTextX; - - pCont->m_dTop = dBaseLinePos - dTextH - m_oFontManager.m_oFont.m_dBaselineOffset; - pCont->m_dWidth = dTextW; - pCont->m_dHeight = dTextH; - pCont->m_dRight = dTextX + dTextW; - - pCont->m_oText = oText; - - //Первичное заполнение стилей - m_pStyleManager->m_pCurrentStyle->m_oFont = m_oFontManager.m_oFont.m_oFont; - m_pStyleManager->m_pCurrentStyle->m_oBrush = *m_pBrush; - - if (bIsPath) - { - m_pStyleManager->m_pCurrentStyle->m_strPickFontName = m_oFontManager.m_strCurrentPickFont; - m_pStyleManager->m_pCurrentStyle->m_lPickFontStyle = m_oFontManager.m_lCurrentPictFontStyle; - } - - pCont->m_pFontStyle = m_pStyleManager->GetStyle(); - - pCont->m_dSpaceWidthMM = m_oFontManager.m_dSpaceWidthMM; - - m_arSymbol.push_back(pCont); - } - - void CPage::AnalyzeCollectedShapes() - { - DetermineLinesType(); - } - - void CPage::DetermineLinesType() - { - for (size_t i = 0; i < m_arShapes.size(); ++i) - { - auto pCurrShape = m_arShapes[i]; - - if (pCurrShape->m_bIsNotNecessaryToUse || - pCurrShape->m_dHeight > c_dMAX_LINE_HEIGHT_MM || //рассматриваем только тонкие объекты - (pCurrShape->m_eGraphicsType != eGraphicsType::gtRectangle && - pCurrShape->m_eGraphicsType != eGraphicsType::gtCurve)) - { - continue; - } - - //Нужно собрать всю графику, которая находится на одной линии - std::vector arCurrShapes; - arCurrShapes.push_back(m_arShapes[i]); - - for (size_t j = i+1; j < m_arShapes.size(); ++j) - { - auto pNextShape = m_arShapes[j]; - bool bIf1 = !pNextShape->m_bIsNotNecessaryToUse; - bool bIf2 = pCurrShape->IsCorrelated(pNextShape); - //note довольно странное поведение - в зависимости от толщины линии информация о графике записывается в разные структуры - bool bIf3 = pCurrShape->m_oBrush.IsEqual(&pNextShape->m_oBrush); - bool bIf4 = pCurrShape->m_oPen.IsEqual(&pNextShape->m_oPen); - //линия должна быть одного размера по высоте - bool bIf5 = fabs(pCurrShape->m_dHeight - pNextShape->m_dHeight) < c_dGRAPHICS_ERROR_IN_LINES_MM; - //все должно быть на одной линии - bool bIf6 = fabs(pCurrShape->m_dTop - pNextShape->m_dTop) < c_dGRAPHICS_ERROR_IN_LINES_MM * 5; - - if (bIf1 && bIf2 && (bIf3 || bIf4) && bIf5 && bIf6) //все должно быть на одной линии - { - arCurrShapes.push_back(pNextShape); - } - } - - //Отсортируем собранный массив по x - size_t nCurrShapesCount = arCurrShapes.size(); - if (nCurrShapesCount > 1) - { - SortElements(arCurrShapes); - pCurrShape = arCurrShapes[0]; - - //сравнение - for (size_t k = 1; k < nCurrShapesCount; ++k) - { - auto pNextShape = arCurrShapes[k]; - - //note логика работатет только если arCurrShapes отсортирован по m_dLeft - pCurrShape->DetermineLineType(pNextShape, k == nCurrShapesCount - 1); - - if (pCurrShape->m_bIsNotNecessaryToUse) - { - pCurrShape = pNextShape; - k++; - } - } - } - else if (nCurrShapesCount == 1) - { - arCurrShapes[0]->DetermineLineType(); - } - - arCurrShapes.clear(); - } - } - - void CPage::AnalyzeCollectedSymbols() - { - for (size_t i = 0; i < m_arSymbol.size(); i++) - { - auto pCont = m_arSymbol[i]; - - if (pCont->m_bIsNotNecessaryToUse || - m_arSymbol.size() < 2 || - i >= m_arSymbol.size() - 1) - { - continue; - } - - for (size_t j = i + 1; j < m_arSymbol.size(); j++) - { - auto pNext = m_arSymbol[j]; - - if (pNext->m_bIsNotNecessaryToUse) - { - continue; - } - - eVerticalCrossingType eVType = pCont->GetVerticalCrossingType(pNext); - eHorizontalCrossingType eHType = pCont->GetHorizontalCrossingType(pNext); - - if (pCont->IsThereAreFontEffects(pNext, eVType, eHType)) - { - if (pCont->m_bIsNotNecessaryToUse) - { - break; - } - else - { - continue; - } - } - - if (pCont->IsVertAlignTypeBetweenConts(pNext, eVType, eHType)) - { - continue; - } - - if (pCont->IsDuplicate(pNext, eVType)) - { - continue; - } - } - } - - DetermineStrikeoutsUnderlinesHighlights(); - } - - void CPage::DetermineStrikeoutsUnderlinesHighlights() - { - for (const auto &pShape : m_arShapes) - { - if (pShape->m_eGraphicsType == eGraphicsType::gtNoGraphics || - pShape->m_bIsNotNecessaryToUse) - { - continue; - } - - for (const auto &pCont : m_arSymbol) - { - if (pCont->m_bIsNotNecessaryToUse) - { - continue; - } - - eVerticalCrossingType eVType = pCont->GetVerticalCrossingType(pShape); - eHorizontalCrossingType eHType = pCont->GetHorizontalCrossingType(pShape); - - bool bIf1 = pShape->m_eGraphicsType != eGraphicsType::gtComplicatedFigure; - bool bIf2 = IsLineCrossingText(pShape, pCont, eHType); - bool bIf3 = IsLineBelowText(pShape, pCont, eHType); - bool bIf4 = IsItHighlightingBackground(pShape, pCont, eHType); - - if (bIf1 && (bIf2 || bIf3 || bIf4)) - { - pShape->m_bIsNotNecessaryToUse = true; - } - - if (!bIf1) - { - bool bIf1 = pCont->m_pFontStyle->m_oBrush.Color1 == c_iGreyColor; - bool bIf2 = pCont->m_bIsShadowPresent && pCont->m_bIsOutlinePresent; - bool bIf3 = eVType == eVerticalCrossingType::vctCurrentOutsideNext; - bool bIf4 = eHType == eHorizontalCrossingType::hctCurrentOutsideNext; - bool bIf5 = eHType == eHorizontalCrossingType::hctCurrentRightOfNext; - - if ((bIf1 || bIf2) && bIf3 && (bIf4 || bIf5)) - { - if (!bIf2) - { - m_pStyleManager->m_pCurrentStyle->CopyFormat(*pCont->m_pFontStyle); - m_pStyleManager->m_pCurrentStyle->m_oBrush.Color1 = pShape->m_oPen.Color; - pCont->m_pFontStyle = m_pStyleManager->GetStyle(); - - pCont->m_bIsShadowPresent = true; - pCont->m_bIsOutlinePresent = true; - } - - pShape->m_bIsNotNecessaryToUse = true; - } - } - } - } - } - - bool CPage::IsLineCrossingText(const CShape *pShape, CContText *pCont, const eHorizontalCrossingType& eHType) - { - double dTopBorder = pCont->m_dTop + pCont->m_dHeight/3; //note Height - это максимально возможный размер символа. Больше реального размера. - - bool bIf1 = pShape->m_eGraphicsType == eGraphicsType::gtRectangle && - pShape->m_eLineType != eLineType::ltUnknown; - //Условие пересечения по вертикали - bool bIf2 = pShape->m_dTop > dTopBorder && pShape->m_dBaselinePos < pCont->m_dBaselinePos; - //Условие пересечения по горизонтали - bool bIf3 = eHType != eHorizontalCrossingType::hctUnknown && - eHType != eHorizontalCrossingType::hctCurrentLeftOfNext && - eHType != eHorizontalCrossingType::hctNoCrossingCurrentLeftOfNext && - eHType != eHorizontalCrossingType::hctNoCrossingCurrentRightOfNext; - //Условие для размеров по высоте - bool bIf4 = pShape->m_dHeight < pCont->m_dHeight && - pCont->m_dHeight - pShape->m_dHeight > c_dERROR_FOR_TEXT_WITH_GRAPHICS_MM; - - if (bIf1 && bIf2 && bIf3 && bIf4) - { - pCont->m_bIsStrikeoutPresent = true;; - if (pShape->m_eLineType == eLineType::ltDouble) - { - pCont->m_bIsDoubleStrikeout = true; - } - return true; - } - - return false; - } - - bool CPage::IsLineBelowText(const CShape *pShape, CContText *pCont, const eHorizontalCrossingType& eHType) - { - bool bIf1 = (pShape->m_eGraphicsType == eGraphicsType::gtRectangle || - pShape->m_eGraphicsType == eGraphicsType::gtCurve) && - pShape->m_eLineType != eLineType::ltUnknown; - //Условие по вертикали - bool bIf2 = fabs(pShape->m_dTop - pCont->m_dBaselinePos) < pCont->m_dHeight * 0.15; - //Условие пересечения по горизонтали - bool bIf3 = eHType != eHorizontalCrossingType::hctUnknown && - eHType != eHorizontalCrossingType::hctCurrentLeftOfNext && - eHType != eHorizontalCrossingType::hctNoCrossingCurrentLeftOfNext && - eHType != eHorizontalCrossingType::hctNoCrossingCurrentRightOfNext; - //Условие для размеров по высоте - bool bIf4 = pShape->m_dHeight < pCont->m_dHeight && - pCont->m_dHeight - pShape->m_dHeight > c_dERROR_FOR_TEXT_WITH_GRAPHICS_MM; - - if (bIf1 && bIf2 && bIf3 && bIf4) - { - pCont->m_bIsUnderlinePresent = true;; - pCont->m_eUnderlineType = pShape->m_eLineType; - pCont->m_lUnderlineColor = pShape->m_dHeight > 0.3 ? pShape->m_oBrush.Color1 : pShape->m_oPen.Color; - return true; - } - - return false; - } - - bool CPage::IsItHighlightingBackground(CShape *pShape, CContText* pCont, const eHorizontalCrossingType& eHType) - { - double dSomeBaseLine1 = pCont->m_dBaselinePos - pCont->m_dHeight * 0.75; - double dSomeBaseLine2 = pCont->m_dBaselinePos - pCont->m_dHeight * 0.5; - double dSomeBaseLine3 = pCont->m_dBaselinePos - pCont->m_dHeight * 0.25; - - bool bIf1 = pShape->m_eGraphicsType == eGraphicsType::gtRectangle; - //Условие пересечения по вертикали - bool bIf2 = (dSomeBaseLine1 > pShape->m_dTop && dSomeBaseLine1 < pShape->m_dBaselinePos && - dSomeBaseLine2 > pShape->m_dTop && dSomeBaseLine2 < pShape->m_dBaselinePos && - dSomeBaseLine3 > pShape->m_dTop && dSomeBaseLine3 < pShape->m_dBaselinePos); - //Условие пересечения по горизонтали - bool bIf3 = eHType != eHorizontalCrossingType::hctUnknown && - eHType != eHorizontalCrossingType::hctCurrentLeftOfNext && - eHType != eHorizontalCrossingType::hctNoCrossingCurrentLeftOfNext && - eHType != eHorizontalCrossingType::hctNoCrossingCurrentRightOfNext; - //Цвета должны быть разными - bool bIf4 = pCont->m_pFontStyle->m_oBrush.Color1 != pShape->m_oBrush.Color1; - bool bIf5 = pShape->m_oBrush.Color1 == c_iBlackColor && pShape->m_oPen.Color == c_iWhiteColor; - bool bIf6 = pShape->m_bIsNoFill == false; - bool bIf7 = pShape->m_bIsNoStroke == true; - - if (bIf1 && bIf2 && bIf3 && bIf4 && !bIf5 && bIf6 && bIf7) - { - //Удовлетворяет расположением и размером - привязываем указатель на картинку - pCont->m_pShape = pShape; - pCont->m_bIsHighlightPresent = true; - pCont->m_lHighlightColor = pShape->m_oBrush.Color1; - return true; - } - - return false; - } - - void CPage::AnalyzeLines() - { - BuildLines(); - - SortElements(m_arTextLine); - - MergeLinesByVertAlignType(); - - for (auto pLine : m_arTextLine) - { - if (pLine->m_bIsNotNecessaryToUse) - { - continue; - } - - pLine->SortConts(); - pLine->CalculateWidth(); - //pLine->DetermineAssumedTextAlignmentType(m_dWidth); - pLine->MergeConts(); - } - - if (m_eTextAssociationType == tatPlainParagraph || - m_eTextAssociationType == tatShapeLine || - m_eTextAssociationType == tatPlainLine) - { - DetermineDominantGraphics(); - } - - DeleteTextClipPage(); - } - - void CPage::BuildLines() - { - //note Элементы в m_arSymbol в случайных местах страницы - for (const auto &pCont : m_arSymbol) - { - if (pCont->m_bIsNotNecessaryToUse) - { - continue; - } - - SelectCurrentLine(pCont); - - CContText* pLastCont = nullptr; - size_t nCountConts = m_pCurrentLine->m_arConts.size(); - if (nCountConts != 0) - pLastCont = m_pCurrentLine->m_arConts.back(); - - if (nullptr == pLastCont) - { - // первое слово в линии - auto pNewCont = new CContText(*pCont); - - pNewCont->m_dLastX = pCont->m_dLeft; - - m_pCurrentLine->AddCont(pNewCont); - m_dLastTextX = pNewCont->m_dLeft; - m_dLastTextY = pNewCont->m_dBaselinePos; - m_dLastTextX_block = m_dLastTextX; - - CollectDublicateLines(pCont); - continue; - } - - if (pLastCont->IsEqual(pCont)) - { - bool bIsConditionPassed = false; - - // настройки одинаковые. теперь смотрим, на расположение - if (fabs(pLastCont->m_dRight - pCont->m_dLeft) < c_dTHE_STRING_X_PRECISION_MM) - { - // продолжаем слово - pLastCont->m_oText += pCont->m_oText; - pLastCont->m_dWidth = (pCont->m_dRight - pLastCont->m_dLeft); - pLastCont->m_dRight = pLastCont->m_dLeft + pLastCont->m_dWidth; - bIsConditionPassed = true; - } - else if ((pLastCont->m_dRight < pCont->m_dLeft) && ((pCont->m_dLeft - pLastCont->m_dRight) < pCont->m_dSpaceWidthMM)) - { - // продолжаем слово с пробелом - pLastCont->m_oText += uint32_t(' '); - pLastCont->m_oText += pCont->m_oText; - pLastCont->m_dWidth = (pCont->m_dRight - pLastCont->m_dLeft); - pLastCont->m_dRight = pLastCont->m_dLeft + pLastCont->m_dWidth; - bIsConditionPassed = true; - } - else if (fabs(pCont->m_dBaselinePos - pLastCont->m_dBaselinePos) < 0.01 && - fabs(m_dLastTextY - pLastCont->m_dBaselinePos) < 0.01 && - fabs(m_dLastTextX - pLastCont->m_dLastX) < 0.01) - { - // идет текст подряд, но с расстояниями что-то не так. смотрим - если новый текст идет после предыдущего, но - // просто левее чем предыдущий x + w - то считаем это нормальным. и дописываем слово. корректируя длину - if (pCont->m_dLeft < pLastCont->m_dRight && pCont->m_dLeft > pLastCont->m_dLastX) - { - // продолжаем слово - pLastCont->m_oText += pCont->m_oText; - double dNewW = (pCont->m_dRight - pLastCont->m_dLeft); - if (pLastCont->m_dWidth < dNewW) - pLastCont->m_dWidth = dNewW; - pLastCont->m_dRight = pLastCont->m_dLeft + pLastCont->m_dWidth; - bIsConditionPassed = true; - } - // еще одна заглушка на большой пробел - добавляем пробел, потом в линии все разрулится через spacing - else if (pCont->m_dLeft > pLastCont->m_dRight && (pCont->m_dLeft - pLastCont->m_dRight) < 5 && fabs(m_dLastTextX_block - m_dLastTextX) < 0.01) - { - // продолжаем слово с пробелом - pLastCont->m_oText += uint32_t(' '); - pLastCont->m_oText += pCont->m_oText; - pLastCont->m_dWidth = (pCont->m_dRight - pLastCont->m_dLeft); - pLastCont->m_dRight = pLastCont->m_dLeft + pLastCont->m_dWidth; - bIsConditionPassed = true; - } - } - - if (bIsConditionPassed) - { - m_dLastTextX = pCont->m_dLeft; - m_dLastTextY = pCont->m_dBaselinePos; - m_dLastTextX_block = m_dLastTextX; - pLastCont->m_dLastX = pCont->m_dLeft; - if (!pLastCont->m_pCont) - { - pLastCont->m_pCont = pCont->m_pCont; - pLastCont->m_eVertAlignType = pCont->m_eVertAlignType; - } - CollectDublicateLines(pCont); - continue; - } - } - - // либо пробел большой между словами, либо новый текст левее, либо настройки не те (шрифт, кисть) - // либо все вместе... просто добавл¤ем новое слово - m_pCurrentLine->AddCont(new CContText(*pCont)); - m_dLastTextX = pCont->m_dLeft; - m_dLastTextY = pCont->m_dBaselinePos; - m_dLastTextX_block = m_dLastTextX; - CollectDublicateLines(pCont); - } - } - - void CPage::SelectCurrentLine(const CContText *pCont) - { - if ((nullptr == m_pCurrentLine) || (tatBlockChar == m_eTextAssociationType)) - { - // пустая (в плане текста) страница - auto pLine = new CTextLine(); - m_pCurrentLine = pLine; - m_pCurrentLine->m_dBaselinePos = pCont->m_dBaselinePos; - if (m_pCurrentLine->m_eVertAlignType == eVertAlignType::vatUnknown && - pCont->m_eVertAlignType != eVertAlignType::vatUnknown) - { - //note считаем, что линия может иметь только один тип - m_pCurrentLine->m_eVertAlignType = pCont->m_eVertAlignType; - } - m_arTextLine.push_back(pLine); - return; - } - - if (fabs(m_pCurrentLine->m_dBaselinePos - pCont->m_dBaselinePos) <= c_dTHE_SAME_STRING_Y_PRECISION_MM) - { - if (m_pCurrentLine->m_eVertAlignType == eVertAlignType::vatUnknown && - pCont->m_eVertAlignType != eVertAlignType::vatUnknown) - { - //note считаем, что линия может иметь только один тип - m_pCurrentLine->m_eVertAlignType = pCont->m_eVertAlignType; - } - return; - } - - for (size_t i = 0; i < m_arTextLine.size(); ++i) - { - if (fabs(m_arTextLine[i]->m_dBaselinePos - pCont->m_dBaselinePos) <= c_dTHE_SAME_STRING_Y_PRECISION_MM) - { - m_pCurrentLine = m_arTextLine[i]; - if (m_pCurrentLine->m_eVertAlignType == eVertAlignType::vatUnknown && - pCont->m_eVertAlignType != eVertAlignType::vatUnknown) - { - //note считаем, что линия может иметь только один тип - m_pCurrentLine->m_eVertAlignType = pCont->m_eVertAlignType; - } - return; - } - } - - // линия не нашлась - не беда - создадим новую - auto pLine = new CTextLine(); - m_pCurrentLine = pLine; - m_pCurrentLine->m_dBaselinePos = pCont->m_dBaselinePos; - if (m_pCurrentLine->m_eVertAlignType == eVertAlignType::vatUnknown && - pCont->m_eVertAlignType != eVertAlignType::vatUnknown) - { - //note считаем, что линия может иметь только один тип - m_pCurrentLine->m_eVertAlignType = pCont->m_eVertAlignType; - } - m_arTextLine.push_back(pLine); - return; - } - - void CPage::CollectDublicateLines(const CContText *pCont) - { - if (pCont->m_iNumDuplicates > 0) - { - //todo обработать случаи когда в одной строке разное количество разных символов-дубликатов - m_pCurrentLine->m_iNumDuplicates = std::max(m_pCurrentLine->m_iNumDuplicates, pCont->m_iNumDuplicates); - } - } - - void CPage::MergeLinesByVertAlignType() - { - for (size_t i = 0; i < m_arTextLine.size(); i++) - { - auto pLine = m_arTextLine[i]; - - if (pLine->m_bIsNotNecessaryToUse) - { - continue; - } - - if (pLine->m_eVertAlignType != eVertAlignType::vatUnknown) - { - if (i > m_arTextLine.size() - 2) - { - continue; - } - - auto pLineNext = GetNextTextLine(i); - - if (pLine->m_eVertAlignType == eVertAlignType::vatSuperscript && - pLineNext->m_eVertAlignType == eVertAlignType::vatBase) - { - pLine->m_bIsNotNecessaryToUse = true; - for (const auto &pCont : pLine->m_arConts) - { - if (pCont->m_bIsNotNecessaryToUse) - { - continue; - } - - pCont->m_eVertAlignType = eVertAlignType::vatSuperscript; - - if (pCont->m_pCont) - { - //pCont->m_pFontStyle->m_oFont.Size = pCont->m_pCont->m_pFontStyle->m_oFont.Size; - m_pStyleManager->m_pCurrentStyle->CopyFormat(*pCont->m_pFontStyle); - m_pStyleManager->m_pCurrentStyle->m_oFont.Size = pCont->m_pCont->m_pFontStyle->m_oFont.Size; - pCont->m_pFontStyle = m_pStyleManager->GetStyle(); - } - - if (pLineNext->m_dLeft > pCont->m_dLeft) - { - pLineNext->m_dLeft = pCont->m_dLeft; - } - - pLineNext->m_arConts.push_back(new CContText(*pCont)); - } - } - else if (pLine->m_eVertAlignType == eVertAlignType::vatBase && - pLineNext->m_eVertAlignType == eVertAlignType::vatSubscript) - { - pLineNext->m_bIsNotNecessaryToUse = true; - for (const auto &pCont : pLineNext->m_arConts) - { - if (pCont->m_bIsNotNecessaryToUse) - { - continue; - } - - pCont->m_eVertAlignType = eVertAlignType::vatSubscript; - - if (pCont->m_pCont) - { - //pCont->m_pFontStyle->m_oFont.Size = pCont->m_pCont->m_pFontStyle->m_oFont.Size; - m_pStyleManager->m_pCurrentStyle->CopyFormat(*pCont->m_pFontStyle); - m_pStyleManager->m_pCurrentStyle->m_oFont.Size = pCont->m_pCont->m_pFontStyle->m_oFont.Size; - pCont->m_pFontStyle = m_pStyleManager->GetStyle(); - } - - if (pLine->m_dLeft > pCont->m_dLeft) - { - pLine->m_dLeft = pCont->m_dLeft; - } - - pLine->m_arConts.push_back(new CContText(*pCont)); - } - } - } - } - } - - void CPage::DetermineDominantGraphics() - { - CShape* pDominantShape = nullptr; - - for (const auto &pLine : m_arTextLine) - { - if (pLine->m_bIsNotNecessaryToUse) - { - continue; - } - - for (const auto &pCont : pLine->m_arConts) - { - if (pCont->m_bIsNotNecessaryToUse) - { - continue; - } - - if (pCont->m_pShape && pCont->m_pShape != pDominantShape) - { - if (pCont->m_pShape->m_dLeft < pCont->m_dLeft && - pCont->m_pShape->m_dRight > pCont->m_dRight) - { - if (!pDominantShape || - (pCont->m_pShape->m_dLeft < pDominantShape->m_dLeft && - pCont->m_pShape->m_dRight > pDominantShape->m_dRight)) - { - pDominantShape = pCont->m_pShape; - } - } - } - } - - pLine->m_pDominantShape = pDominantShape; - pDominantShape = nullptr; - } - } - - void CPage::BuildByType() - { - if (m_arTextLine.empty()) - return; - - switch (m_eTextAssociationType) - { - case tatBlockChar: - BuildByTypeBlockChar(); - break; - case tatBlockLine: - BuildByTypeBlockLine(); - break; - case tatPlainLine: - BuildByTypePlainLine(); - break; - case tatShapeLine: - BuildByTypeShapeLine(); - break; - case tatPlainParagraph: - BuildByTypePlainParagraph(); - break; - default: - break; - } - } - - void CPage::BuildByTypeBlockChar() - { - for (const auto &pLine : m_arTextLine) - { - auto pParagraph = new CParagraph(m_eTextAssociationType); - pParagraph->m_eTextConversionType = CParagraph::tctTextToFrame; - - pParagraph->m_dLeft = pLine->m_dLeft; - pParagraph->m_dTop = pLine->m_dBaselinePos - pLine->m_dHeight; - - pParagraph->m_arLines.push_back(pLine); - - m_arParagraphs.push_back(pParagraph); - } - } - - void CPage::BuildByTypeBlockLine() - { - auto pFirstLine = m_arTextLine[0]; - - auto pParagraph = new CParagraph(m_eTextAssociationType); - pParagraph->m_eTextConversionType = CParagraph::tctTextToFrame; - - pParagraph->m_dLeft = pFirstLine->m_dLeft; - pParagraph->m_dTop = pFirstLine->m_dBaselinePos - pFirstLine->m_dHeight; - double dCurrentTop = pParagraph->m_dTop; - - pParagraph->m_arLines.push_back(pFirstLine); - - m_arParagraphs.push_back(pParagraph); - - for (size_t i = 1; i < m_arTextLine.size(); ++i) - { - auto pTextLine = m_arTextLine[i]; - - auto pParagraph = new CParagraph(m_eTextAssociationType); - pParagraph->m_eTextConversionType = CParagraph::tctTextToFrame; - - if (((fabs(pTextLine->m_dBaselinePos - pTextLine->m_dHeight - pFirstLine->m_dBaselinePos) > c_dSTANDART_STRING_HEIGHT_MM) && (pTextLine->m_dLeft == pFirstLine->m_dLeft)) || - ((pTextLine->m_dLeft != pFirstLine->m_dLeft) && (pTextLine->m_dBaselinePos != pFirstLine->m_dBaselinePos))) - { - pParagraph->m_dLeft = pTextLine->m_dLeft; - pParagraph->m_dTop = pTextLine->m_dBaselinePos - pTextLine->m_dHeight; - dCurrentTop = pParagraph->m_dTop; - } - else - { - pParagraph->m_dLeft = pFirstLine->m_dLeft; - pParagraph->m_dTop = dCurrentTop; - } - - pFirstLine = pTextLine; - - pParagraph->m_arLines.push_back(pTextLine); - m_arParagraphs.push_back(pParagraph); - } - } - - void CPage::BuildByTypePlainLine() - { - Merge(c_dSTANDART_STRING_HEIGHT_MM / 3); - - double dPreviousStringBaseline = 0; - for (const auto &pLine : m_arTextLine) - { - double dBeforeSpacing = pLine->CalculateBeforeSpacing(dPreviousStringBaseline); - dPreviousStringBaseline = pLine->m_dBaselinePos; - double dRight = pLine->CalculateRightBorder(m_dWidth); - - CreateSingleLineParagraph(pLine, &dRight, &dBeforeSpacing); - } - } - - void CPage::BuildByTypeShapeLine() - { - for (const auto &pLine : m_arTextLine) - { - CreateSingleLineShape(pLine); - } - } - - void CPage::BuildByTypePlainParagraph() - { - //todo не отображается перенос в линии - //todo если в линии есть перенос нужно обеъдинить строки в один параграф - //todo в зависимости от очередности загрузки файлов проявляется проблема со шрифтами - текст в некоторых конвертированных файлах становится жирным, зачеркнутым или курсив. С одним файлом проблем не наблюдалось - //todo добавить различные типы текста для распознавания: обычный-сплошной, списки-содержание и тд - - CTextLine* pCurrLine; - CTextLine* pNextLine; - double dCurrRight = 0, dNextRight = 0; - double dCurrBeforeSpacing = 0, dNextBeforeSpacing = 0; - double dBeforeSpacingWithShapes = 0; - //note Все параграфы были сдвинуты на данное значение от верхнего края страницы - double dPreviousStringBaseline = c_dCORRECTION_FOR_FIRST_PARAGRAPH; - eVerticalCrossingType eCrossingType; - - bool bIf1, bIf2, bIf3, bIf4, bIf5, bIf6, bIf7; - - size_t nIndexForCheking = c_nAntiZero; - - for (size_t nIndex = 0; nIndex < m_arTextLine.size(); ++nIndex) - { - pCurrLine = m_arTextLine[nIndex]; - if (pCurrLine->m_bIsNotNecessaryToUse) - { - continue; - } - - dCurrBeforeSpacing = pCurrLine->CalculateBeforeSpacing(dPreviousStringBaseline); - dPreviousStringBaseline = pCurrLine->m_dBaselinePos; - - if (pCurrLine->m_iNumDuplicates > 0) - { - dBeforeSpacingWithShapes += dCurrBeforeSpacing + pCurrLine->m_dHeight; - - auto iNumDuplicates = pCurrLine->m_iNumDuplicates; - CreateSingleLineShape(pCurrLine); - while (iNumDuplicates > 0) - { - CreateSingleLineShape(pCurrLine); - iNumDuplicates--; - } - continue; - } - - dCurrRight = pCurrLine->CalculateRightBorder(m_dWidth); - pNextLine = GetNextTextLine(nIndex, &nIndexForCheking); - - //Это не последняя строка - bIf1 = pNextLine ? true : false; - - if (bIf1) - { - dNextRight = pNextLine->CalculateRightBorder(m_dWidth); - dNextBeforeSpacing = pNextLine->CalculateBeforeSpacing(dPreviousStringBaseline); - - eCrossingType = pCurrLine->GetVerticalCrossingType(pNextLine); - bool bIsPassed = false; - double dCurrentAdditive = 0.0; - - switch (eCrossingType) - { - case eVerticalCrossingType::vctCurrentInsideNext: - case eVerticalCrossingType::vctCurrentAboveNext: - dCurrentAdditive = dCurrBeforeSpacing + pCurrLine->m_dHeight + pNextLine->m_dBaselinePos - pCurrLine->m_dBaselinePos; - dPreviousStringBaseline = pNextLine->m_dBaselinePos; - bIsPassed = true; - break; - case eVerticalCrossingType::vctCurrentOutsideNext: - case eVerticalCrossingType::vctCurrentBelowNext: - case eVerticalCrossingType::vctDublicate: - dCurrentAdditive = dCurrBeforeSpacing + pCurrLine->m_dHeight; - bIsPassed = true; - break; - default: - break; - } - - if (bIsPassed) - { - CreateSingleLineShape(pCurrLine); - CreateSingleLineShape(pNextLine); - - dBeforeSpacingWithShapes += dCurrentAdditive; - - nIndex++; - continue; - } - } - - if (bIf1) - { - //Высота строк должна быть примерно одинаковой - bIf2 = fabs(pCurrLine->m_dHeight - pNextLine->m_dHeight) <= c_dTHE_SAME_STRING_Y_PRECISION_MM; - // - bIf3 = true; //pCurrLine->AreAlignmentsAppropriate(pNextLine); - //расстрояние между строк тоже одинаково - bIf4 = fabs(dCurrBeforeSpacing - dNextBeforeSpacing) < c_dLINE_DISTANCE_ERROR_MM; - //или - bIf5 = dCurrBeforeSpacing > dNextBeforeSpacing; - //есть отступ или нет отступа - bIf6 = pCurrLine->m_dLeft >= pNextLine->m_dLeft; - //следующая строка либо короче, либо такая же - bIf7 = (fabs(dCurrRight - dNextRight) <= c_dERROR_OF_RIGHT_BORDERS_MM || - dCurrRight < dNextRight); - } - - if (bIf1 && bIf2 && bIf3 && (bIf4 || bIf5) && bIf6 && bIf7) - { - //наверное это сплошной текст - auto pParagraph = new CParagraph(m_eTextAssociationType); - pParagraph->m_eTextConversionType = CParagraph::tctTextToParagraph; - - //делаем абзац в сплошном тексте - pParagraph->m_bIsNeedFirstLineIndent = pCurrLine->m_dLeft > pNextLine->m_dLeft ? true : false; - - pParagraph->m_dFirstLine = pCurrLine->m_dLeft - pNextLine->m_dLeft; - pParagraph->m_dRight = std::min(dCurrRight, dNextRight); - pParagraph->m_dLeft = std::min(pCurrLine->m_dLeft, pNextLine->m_dLeft); - pParagraph->m_dWidth = std::max(pCurrLine->m_dWidth + pCurrLine->m_arConts.back()->m_dSpaceWidthMM, - pNextLine->m_dWidth + pNextLine->m_arConts.back()->m_dSpaceWidthMM); - pParagraph->m_dTop = pCurrLine->m_dBaselinePos - pCurrLine->m_dHeight; - pParagraph->m_dBaselinePos = pCurrLine->m_dBaselinePos; - - if (fabs(dCurrRight - dNextRight) <= c_dERROR_OF_RIGHT_BORDERS_MM) //предположение - { - pParagraph->m_eTextAlignmentType = CParagraph::tatByWidth; - } - - //размер строк во всем параграфе - pParagraph->m_dHeight = pCurrLine->m_dHeight; - pParagraph->m_dSpaceBefore = std::max(dCurrBeforeSpacing, 0.0); - - //Объединим 2 строчки в параграф - pParagraph->m_arLines.push_back(pCurrLine); - pParagraph->m_arLines.push_back(pNextLine); - - if (IsShadingPresent(pCurrLine, pNextLine)) - { - pParagraph->m_bIsShadingPresent = true; - pParagraph->m_lColorOfShadingFill = pCurrLine->m_pDominantShape->m_oBrush.Color1; - } - - //сдвигаем рабочую точку - nIndex++; - pCurrLine = pNextLine; - pNextLine = GetNextTextLine(nIndex, &nIndexForCheking); - - dCurrBeforeSpacing = pCurrLine->CalculateBeforeSpacing(dPreviousStringBaseline); - dPreviousStringBaseline = pCurrLine->m_dBaselinePos; - double dCorrectionBeforeSpacing = dCurrBeforeSpacing; - - double dPrevRight = dCurrRight; - dCurrRight = dNextRight; - - if (pNextLine) - { - dNextBeforeSpacing = pNextLine->CalculateBeforeSpacing(dPreviousStringBaseline); - dNextRight = pNextLine->CalculateRightBorder(m_dWidth); - eCrossingType = pCurrLine->GetVerticalCrossingType(pNextLine); - } - - //проверим, подходят ли следующие строчки для текущего pParagraph - while(pNextLine && - fabs(pCurrLine->m_dHeight - pNextLine->m_dHeight) < c_dTHE_SAME_STRING_Y_PRECISION_MM && //высота строк должна быть примерно одинаковой - fabs(dCurrBeforeSpacing - dNextBeforeSpacing) < c_dLINE_DISTANCE_ERROR_MM && //расстрояние между строк тоже одинаково - (eCrossingType == eVerticalCrossingType::vctUnknown || - eCrossingType == eVerticalCrossingType::vctNoCrossingCurrentAboveNext || - eCrossingType == eVerticalCrossingType::vctNoCrossingCurrentBelowNext) && - ((fabs(pCurrLine->m_dLeft - pNextLine->m_dLeft) < c_dERROR_OF_LEFT_BORDERS_MM && //у последующих строк нет отступа относительно предыдущей непервой строки - (fabs(dCurrRight - dNextRight) < c_dERROR_OF_RIGHT_BORDERS_MM || //а следующая строка либо такая же - (dCurrRight < dNextRight && fabs(dPrevRight - dCurrRight) <= c_dERROR_OF_RIGHT_BORDERS_MM)))) //либо короче, но предыдущие равны - ) - { - //Объединим 2 параграфа-строчки - pParagraph->m_arLines.push_back(pNextLine); - - pParagraph->m_dRight = std::min(pParagraph->m_dRight, dCurrRight); - pParagraph->m_dLeft = std::min(pParagraph->m_dLeft, pNextLine->m_dLeft); - pParagraph->m_dWidth = std::max(pParagraph->m_dWidth, pNextLine->m_dWidth + pNextLine->m_arConts.back()->m_dSpaceWidthMM); - - if (!IsShadingPresent(pCurrLine, pNextLine)) - { - pParagraph->m_bIsShadingPresent = false; - pParagraph->m_lColorOfShadingFill = c_iWhiteColor; - } - - //сдвигаем рабочую точку - nIndex++; - pCurrLine = pNextLine; - pNextLine = GetNextTextLine(nIndex, &nIndexForCheking); - - dCurrBeforeSpacing = pCurrLine->CalculateBeforeSpacing(dPreviousStringBaseline); - dPreviousStringBaseline = pCurrLine->m_dBaselinePos; - dCorrectionBeforeSpacing = (dCorrectionBeforeSpacing + dCurrBeforeSpacing)/2; //наверное лучше так... текст может быть уже, чем в оригинале - - dPrevRight = dCurrRight; - dCurrRight = dNextRight; - - if (pNextLine) - { - dNextBeforeSpacing = pNextLine->CalculateBeforeSpacing(dPreviousStringBaseline); - dNextRight = pNextLine->CalculateRightBorder(m_dWidth); - eCrossingType = pCurrLine->GetVerticalCrossingType(pNextLine); - } - } - - if (eCrossingType != eVerticalCrossingType::vctUnknown && - eCrossingType != eVerticalCrossingType::vctNoCrossingCurrentAboveNext && - eCrossingType != eVerticalCrossingType::vctNoCrossingCurrentBelowNext) - { - CreateSingleLineShape(pNextLine); - nIndex++; - } - - //коррекция - pParagraph->m_dHeight += dCorrectionBeforeSpacing; - pParagraph->m_dSpaceBefore = fabs(pParagraph->m_dSpaceBefore - dCorrectionBeforeSpacing); - - pParagraph->m_dSpaceBefore += dBeforeSpacingWithShapes; - dBeforeSpacingWithShapes = 0; - - pParagraph->RemoveHighlightColor(); - pParagraph->MergeLines(); - - m_arParagraphs.push_back(pParagraph); - } - else - { - //будет отдельной параграфом-строчкой - dCurrBeforeSpacing += dBeforeSpacingWithShapes; - dBeforeSpacingWithShapes = 0; - - CreateSingleLineParagraph(pCurrLine, &dCurrRight, &dCurrBeforeSpacing); - } - - if (nIndexForCheking != c_nAntiZero) - { - nIndex = nIndexForCheking - 1; - nIndexForCheking = c_nAntiZero; - } - } - } - - CTextLine* CPage::GetNextTextLine(size_t& nCurrentIndex, size_t* pIndexForCheking) - { - CTextLine* pLine = nullptr; - - for (size_t nIndex = nCurrentIndex + 1; nIndex < m_arTextLine.size(); nIndex++) - { - pLine = m_arTextLine[nIndex]; - bool bIf1 = pLine->m_bIsNotNecessaryToUse; - bool bIf2 = pIndexForCheking && pLine->m_iNumDuplicates > 0; - - if (bIf1 || bIf2) - { - if (bIf2) - { - if (*pIndexForCheking == c_nAntiZero) - { - *pIndexForCheking = nIndex; - } - } - - nCurrentIndex++; //note изменяем входной индекс, чтобы не выбирать те же строки - pLine = nullptr; - continue; - } - else - { - break; - } - } - return pLine; - } - - bool CPage::IsShadingPresent(const CTextLine *pLine1, const CTextLine *pLine2) - { - if (pLine1->m_pDominantShape && pLine2->m_pDominantShape && - pLine1->m_pDominantShape->m_oBrush.Color1 == pLine2->m_pDominantShape->m_oBrush.Color1 && - fabs(pLine1->m_pDominantShape->m_dLeft - pLine2->m_pDominantShape->m_dLeft) < c_dGRAPHICS_ERROR_IN_LINES_MM && - fabs(pLine1->m_pDominantShape->m_dWidth - pLine2->m_pDominantShape->m_dWidth) < c_dGRAPHICS_ERROR_IN_LINES_MM) - { - return true; - } - - return false; - } - - void CPage::CreateSingleLineParagraph(CTextLine *pLine, const double *pRight, const double *pBeforeSpacing) - { - auto pParagraph = new CParagraph(m_eTextAssociationType); - pParagraph->m_eTextConversionType = CParagraph::tctTextToParagraph; - pParagraph->m_arLines.push_back(pLine); - - pParagraph->m_dLeft = pLine->m_dLeft; - pParagraph->m_dTop = pLine->m_dTop; - pParagraph->m_dFirstLine = 0; - pParagraph->m_dRight = *pRight; - pParagraph->m_dWidth = pLine->m_dWidth; - pParagraph->m_dHeight = pLine->m_dHeight; - if (*pBeforeSpacing < 0) - { - pParagraph->m_dHeight += *pBeforeSpacing; - } - - pParagraph->m_dSpaceBefore = std::max(*pBeforeSpacing, 0.0); - pParagraph->m_dBaselinePos = pLine->m_dBaselinePos; - - if (pLine->m_pDominantShape) - { - pParagraph->m_bIsShadingPresent = true; - pParagraph->m_lColorOfShadingFill = pLine->m_pDominantShape->m_oBrush.Color1; - pParagraph->RemoveHighlightColor(); - } - - m_arParagraphs.push_back(pParagraph); - } - - void CPage::CreateSingleLineOldShape(CTextLine *pLine) - { - auto pParagraph = new CParagraph(m_eTextAssociationType); - pParagraph->m_eTextConversionType = CParagraph::tctTextToShape; - pParagraph->m_arLines.push_back(pLine); - - if (pLine->m_pDominantShape) - { - pParagraph->m_bIsShadingPresent = true; - pParagraph->m_lColorOfShadingFill = pLine->m_pDominantShape->m_oBrush.Color1; - pParagraph->RemoveHighlightColor(); - } - - auto pShape = std::make_shared(); - pShape->m_arParagraphs.push_back(pParagraph); - - //todo В итоге Left и Top смещаются на несколько мм. не использовать margin-left и margin-top. - pShape->m_dLeft = pLine->m_dLeft - COldShape::POSITION_CORRECTION_FOR_X_MM; //подобранная константа - pShape->m_dTop = pLine->m_dBaselinePos - pLine->m_dHeight - COldShape::POSITION_CORRECTION_FOR_Y_MM;//подобранная константа - pShape->m_dWidth = pLine->m_dWidth + COldShape::SIZE_CORRECTION_FOR_X_MM; //5мм мало для длинной строки - pShape->m_dHeight = pLine->m_dHeight + COldShape::SIZE_CORRECTION_FOR_Y_MM; - - //m_arGraphicItems.push_back(pShape); - } - - void CPage::CreateSingleLineShape(CTextLine *pLine) - { - auto pParagraph = new CParagraph(m_eTextAssociationType); - pParagraph->m_eTextConversionType = CParagraph::tctTextToShape; - pParagraph->m_arLines.push_back(pLine); - - if (pLine->m_pDominantShape) - { - pParagraph->m_bIsShadingPresent = true; - pParagraph->m_lColorOfShadingFill = pLine->m_pDominantShape->m_oBrush.Color1; - pParagraph->RemoveHighlightColor(); - } - - auto pShape = new CShape(); - pShape->m_arParagraphs.push_back(pParagraph); - pShape->m_eType = CShape::eShapeType::stTextBox; - pShape->m_dLeft = pLine->m_dLeft; - pShape->m_dTop = pLine->m_dTop; - pShape->m_dWidth = pLine->m_dWidth; - pShape->m_dHeight = pLine->m_dHeight; - pShape->m_bIsBehindDoc = false; - - m_arShapes.push_back(pShape); - } - - void CPage::Merge(double dAffinity) - { - size_t nCount = m_arTextLine.size(); - if (1 < nCount) - { - auto pPrev = m_arTextLine[0]; - for (size_t i = 1; i < nCount; ++i) - { - auto pNext = m_arTextLine[i]; - - if (fabs(pNext->m_dBaselinePos - pPrev->m_dBaselinePos) < dAffinity) - { - pPrev->Merge(pNext); - pNext->m_bIsNotNecessaryToUse = true; - continue; - } - pPrev = pNext; - } - } - } - - void CPage::ToXml(NSStringUtils::CStringBuilder& oWriter) - { - if (!m_arImages.empty()) - { - oWriter.WriteString(L""); - //note при удалении строки откуда-то добавляется в начале страницы (если есть графика и текст), что добавляет дополнительную строку и сдвигает текст - oWriter.WriteString(L""); - - for (size_t i = 0; i < m_arImages.size(); i++) - { - m_arImages[i]->ToXml(oWriter); - } - - oWriter.WriteString(L""); - } - - // drawings - if (!m_arShapes.empty()) - { - oWriter.WriteString(L""); - //note при удалении строки откуда-то добавляется в начале страницы (если есть графика и текст), что добавляет дополнительную строку и сдвигает текст - oWriter.WriteString(L""); - - for (size_t i = 0; i < m_arShapes.size(); i++) - { - m_arShapes[i]->ToXml(oWriter); - } - - oWriter.WriteString(L""); - } - - for (size_t i = 0; i < m_arParagraphs.size(); i++) - { - m_arParagraphs[i]->ToXml(oWriter); - } - } - - void CPage::WriteSectionToFile(bool bLastPage, NSStringUtils::CStringBuilder& oWriter) - { - // section - int lWidthDx = (int)(m_dWidth * c_dMMToDx); - int lHeightDx = (int)(m_dHeight * c_dMMToDx); - - if (!bLastPage) - oWriter.WriteString(L""); - else - oWriter.WriteString(L""); - - oWriter.WriteString(L"= lHeightDx) ? oWriter.WriteString(L"landscape") : oWriter.WriteString(L"portrait"); - oWriter.WriteString(L"\"/>"); - - if (!bLastPage) - oWriter.WriteString(L""); - else - oWriter.WriteString(L""); - } + CPage::CPage(NSFonts::IApplicationFonts* pAppFonts, const CManagers& oManagers) : + m_oManagers(oManagers), m_oContBuilder(oManagers.pFontStyleManager, oManagers.pFontSelector) + { + m_pAppFonts = pAppFonts; + CShape::ResetRelativeHeight(); + } + + void CPage::BeginCommand(DWORD lType) + { + m_lCurrentCommand = static_cast(lType); + } + void CPage::EndCommand(DWORD lType) + { + m_lCurrentCommand = -1; + + if (lType == c_nResetClipType) + { + m_oClipVectorGraphics.Clear(); + } + else if (lType == c_nClipType) + { + // closing clip path if non-closed + if (!m_oCurrVectorGraphics.IsEmpty() && m_oCurrVectorGraphics.GetData().back().type != CVectorGraphics::ePathCommandType::pctClose) + m_oCurrVectorGraphics.Add({CVectorGraphics::ePathCommandType::pctClose, {}}); + + if (!m_oClipVectorGraphics.IsEmpty()) + { + m_oClipVectorGraphics = CVectorGraphics::CalcBoolean(m_oClipVectorGraphics, m_oCurrVectorGraphics, m_lClipMode); + m_oCurrVectorGraphics.Clear(); + } + else + m_oClipVectorGraphics = std::move(m_oCurrVectorGraphics); + } + } + + void CPage::Clear() + { + m_oPen.SetDefaultParams(); + m_oBrush.SetDefaultParams(); + m_oFont.SetDefaultParams(); + m_oShadow.SetDefaultParams(); + m_oEdgeText.SetDefaultParams(); + m_oTransform.Reset(); + + m_oHorVerLinesCollector.Clear(); + m_arConts.clear(); + m_arTextLines.clear(); + m_arDiacriticalSymbols.clear(); + m_arShapes.clear(); + m_arParagraphs.clear(); + m_arTables.clear(); + m_arOutputObjects.clear(); + m_oCurrVectorGraphics.Clear(); + m_oClipVectorGraphics.Clear(); + m_arCompleteObjectsXml.clear(); + } + + CPage::~CPage() + { + Clear(); + } + + void CPage::DeleteTextClipPage() + { + if (m_bIsDeleteTextClipPage) + for (auto& line : m_arTextLines) + if (line && (line->m_dTop >= m_dHeight || line->m_dBaselinePos <= 0)) + line = nullptr; + } + + // image commands + void CPage::WriteImage(const std::shared_ptr pInfo, double& fX, double& fY, double& fWidth, double& fHeight) + { + double rotation = m_oTransform.z_Rotation(); + + Point p1(fX, fY); + Point p2(fX + fWidth, fY + fHeight); + + m_oTransform.TransformPoint(p1.x, p1.y); + m_oTransform.TransformPoint(p2.x, p2.y); + + Point c((p1.x + p2.x) / 2, (p1.y + p2.y) / 2); + Aggplus::CMatrix rotate_matrix; + rotate_matrix.RotateAt(-rotation, c.x, c.y, Aggplus::MatrixOrderAppend); + + rotate_matrix.TransformPoint(p1.x, p1.y); + rotate_matrix.TransformPoint(p2.x, p2.y); + + Point p3(p1.x, p2.y); + Point p4(p2.x, p1.y); + + rotate_matrix.RotateAt(2 * rotation, c.x, c.y, Aggplus::MatrixOrderAppend); + rotate_matrix.TransformPoint(p1.x, p1.y); + rotate_matrix.TransformPoint(p2.x, p2.y); + rotate_matrix.TransformPoint(p3.x, p3.y); + rotate_matrix.TransformPoint(p4.x, p4.y); + + m_oCurrVectorGraphics.Clear(); + m_oCurrVectorGraphics.MoveTo(p1.x, p1.y); + m_oCurrVectorGraphics.LineTo(p3.x, p3.y); + m_oCurrVectorGraphics.LineTo(p2.x, p2.y); + m_oCurrVectorGraphics.LineTo(p4.x, p4.y); + m_oCurrVectorGraphics.LineTo(p1.x, p1.y); + m_oCurrVectorGraphics.Close(); + DrawPath(c_nWindingFillMode, pInfo); + } + + // path commands + void CPage::PathMoveTo(double& dX, double& dY) + { + m_oTransform.TransformPoint(dX, dY); + m_oCurrVectorGraphics.MoveTo(dX, dY); + } + + void CPage::PathLineTo(double& dX, double& dY) + { + m_oTransform.TransformPoint(dX, dY); + m_oCurrVectorGraphics.LineTo(dX, dY); + } + + void CPage::PathCurveTo(double& dX1, double& dY1, double& dX2, double& dY2, double& dX3, double& dY3) + { + m_oTransform.TransformPoint(dX1, dY1); + m_oTransform.TransformPoint(dX2, dY2); + m_oTransform.TransformPoint(dX3, dY3); + m_oCurrVectorGraphics.CurveTo(dX1, dY1, dX2, dY2, dX3, dY3); + } + + void CPage::PathStart() + { + m_oCurrVectorGraphics.Clear(); + } + + void CPage::PathEnd() + { + m_oCurrVectorGraphics.Clear(); + } + + void CPage::PathClose() + { + m_oCurrVectorGraphics.Close(); + } + + // c_nStroke = 0x0001; + // c_nWindingFillMode = 0x0100; + // c_nEvenOddFillMode = 0x0200; + void CPage::DrawPath(LONG lType, const std::shared_ptr pInfo) + { + // in case if text comes as a path with unicode 32 (space) + if (m_oCurrVectorGraphics.IsEmpty()) + return; + + double rotation = m_oTransform.z_Rotation(); + double left = m_oCurrVectorGraphics.GetLeft(); + double right = m_oCurrVectorGraphics.GetRight(); + double top = m_oCurrVectorGraphics.GetTop(); + double bot = m_oCurrVectorGraphics.GetBottom(); + double transform_det = sqrt(fabs(m_oTransform.Determinant())); + + // save default image vector before clip to calc blipFill + auto image_vector = m_oCurrVectorGraphics; + + auto set_fill_mode = [this, lType, &transform_det] (shape_ptr_t s) { + if (lType & c_nStroke) + { + s->m_bIsNoStroke = false; + s->m_oPen = m_oPen; + s->m_oPen.Size *= transform_det; + } + if (lType & c_nWindingFillMode || lType & c_nEvenOddFillMode) + { + s->m_bIsNoFill = false; + s->m_oBrush = m_oBrush; + } + }; + + if (!m_arShapes.empty()) + { + auto& last_shape = m_arShapes.back(); + if (last_shape->IsEqual(top, bot, left, right) && rotation == last_shape->m_dRotation) + { + set_fill_mode(last_shape); + return; + } + } + + auto shape = std::make_shared(); + shape->m_oPen.Size *= transform_det; + set_fill_mode(shape); + + if (shape->m_bIsNoStroke) + { + if ((fabs(left - right) < 0.3) || (fabs(top - bot) < 0.3)) + { + shape->m_oPen.Color = m_oBrush.Color1; + shape->m_oPen.Alpha = m_oBrush.Alpha1; + } + } + + if (!m_oClipVectorGraphics.IsEmpty()) + { + CVectorGraphics new_vector_graphics = CVectorGraphics::CalcBoolean( + m_oCurrVectorGraphics, + m_oClipVectorGraphics, + m_lClipMode, + lType); + + if (new_vector_graphics.IsEmpty()) + { + m_oCurrVectorGraphics.Clear(); + return; + } + m_oCurrVectorGraphics = std::move(new_vector_graphics); + } + shape->SetVector(std::move(m_oCurrVectorGraphics)); + + auto info = pInfo; + if (!info && m_bIsGradient) + { + // image with gradient must be closed + if (!shape->m_oVector.IsEmpty() && shape->m_oVector.GetData().back().type != CVectorGraphics::ePathCommandType::pctClose) + shape->m_oVector.Add({CVectorGraphics::ePathCommandType::pctClose, {}}); + + long width_pix = static_cast(shape->m_dWidth * c_dMMToPix); + long height_pix = static_cast(shape->m_dHeight * c_dMMToPix); + + if (width_pix == 0) width_pix = 1; + if (height_pix == 0) height_pix = 1; + + const long step = 4; + const long stride = -step * width_pix; + + std::unique_ptr frame(new CBgraFrame()); + size_t data_size = width_pix * height_pix * step; + BYTE* data = new BYTE[data_size]; + + // white and alpha is min (full transparent) + for (size_t i = 0; i < width_pix * height_pix; ++i) + reinterpret_cast(data)[i] = 0x00ffffff; + + frame->put_Data(data); + frame->put_Height(height_pix); + frame->put_Width(width_pix); + frame->put_Stride(stride); + + auto shifted_vector = shape->m_oVector; + Aggplus::CMatrix transform_matrix; + transform_matrix.Translate(-shifted_vector.GetLeft(), -shifted_vector.GetTop()); + shifted_vector.Transform(transform_matrix); + + NSStructures::CBrush shifted_brush = m_oBrush; + shifted_brush.Bounds.left = shifted_vector.GetLeft(); + shifted_brush.Bounds.right = shifted_vector.GetRight(); + shifted_brush.Bounds.bottom = shifted_vector.GetBottom(); + shifted_brush.Bounds.top = shifted_vector.GetTop(); + shifted_brush.m_oGradientInfo.transform(transform_matrix); + + NSGraphics::IGraphicsRenderer* g_renderer = NSGraphics::Create(); + g_renderer->CreateFromBgraFrame(frame.get()); + g_renderer->SetSwapRGB(false); + g_renderer->put_Width(shape->m_dWidth); + g_renderer->put_Height(shape->m_dHeight); + g_renderer->RestoreBrush(shifted_brush); + g_renderer->RestorePen(m_oPen); + g_renderer->BeginCommand(c_nPathType); + shifted_vector.DrawOnRenderer(g_renderer); + g_renderer->DrawPath(c_nWindingFillMode); + g_renderer->EndCommand(c_nPathType); + + Aggplus::CImage img; + img.Create(data, width_pix, height_pix, stride, true); + info = m_oManagers.pImageManager->WriteImage(&img, shape->m_dTop, shape->m_dBaselinePos, shape->m_dWidth, shape->m_dHeight); + rotation = 0; + image_vector = shape->m_oVector; + + m_bIsGradient = false; + RELEASEINTERFACE(g_renderer) + } + shape->m_dRotation = rotation; + + if (info) + { + shape->m_pImageInfo = info; + shape->m_eType = CShape::eShapeType::stVectorTexture; + image_vector.RotateAt(-shape->m_dRotation, shape->m_oVector.GetCenter()); + + shape->m_dImageBot = image_vector.GetBottom(); + shape->m_dImageTop = image_vector.GetTop(); + shape->m_dImageLeft = image_vector.GetLeft(); + shape->m_dImageRight = image_vector.GetRight(); + } + else + shape->m_eType = CShape::eShapeType::stVectorGraphics; + + if (!shape->IsOoxmlValid()) + return; + + // big white shape with page width & height skip + if (fabs(shape->m_dHeight - m_dHeight) <= c_dSHAPE_X_OFFSET * 2 && + fabs(shape->m_dWidth - m_dWidth) <= c_dSHAPE_X_OFFSET * 2 && + shape->m_oBrush.Color1 == c_iWhiteColor) + return; + + shape->m_nOrder = ++m_nShapeOrder; + m_arShapes.push_back(shape); + } + + void CPage::AddText( + const PUINT pUnicodes, + const PUINT pGids, + const UINT& nCount, + const double& fX, + const double& fY, + const double& fWidth, + const double& fHeight, + const double& fBaseLineOffset) + { + // 9 - \t + if (*pUnicodes == 9) + return; + + double dTextX = fX; + double dTextY = fY; + double dTextR = fX + fWidth; + double dTextB = fY + fHeight; + + m_oTransform.TransformPoint(dTextX, dTextY); + m_oTransform.TransformPoint(dTextR, dTextB); + + NSStringUtils::CStringUTF32 oText((uint32_t*)pUnicodes, nCount); + + if ((pUnicodes != nullptr) && (pGids != nullptr)) + for (unsigned int i = 0; i < nCount; ++i) + if (!CContText::IsUnicodeSymbol(pUnicodes[i])) + oText[i] = ' '; + + // иногда приходит неверный? размер, нужно перемерить (XPS) + if (m_bIsRecalcFontSize) + { + m_oFont.Size *= ((m_oTransform.sx() + m_oTransform.sy()) / 2); + m_bIsRecalcFontSize = false; + } + if (!m_oManagers.pFontManager->LoadFontByFile(m_oFont)) + return; + + double _x = 0; + double _y = 0; + double _w = 0; + double _h = 0; + + if (nullptr != pGids) + { + m_oManagers.pFontManager->SetStringGid(1); + m_oManagers.pFontManager->MeasureStringGids(pGids, nCount, dTextX, dTextY, _x, _y, _w, _h, CFontManager::mtPosition); + } + else + { + // такого быть не должно (только из xps) + m_oManagers.pFontManager->SetStringGid(0); + m_oManagers.pFontManager->MeasureStringGids(pUnicodes, nCount, dTextX, dTextY, _x, _y, _w, _h, CFontManager::mtPosition); + } + + _h = m_oManagers.pFontManager->GetFontHeight(); + + double baseline = dTextY + fBaseLineOffset; + double top = baseline - _h; + double left = dTextX; + double right = left + _w; + + // use forced fold option + const auto& oParams = m_oManagers.pFontManager->GetFontSelectParams(); + bool bForcedBold = oParams.bDefaultBold; + if (m_lCurrentCommand == c_nStrokeTextType && m_oFont.Bold) + bForcedBold = true; + + m_oManagers.pParagraphStyleManager->UpdateAvgFontSize(m_oFont.Size); + m_oContBuilder.AddUnicode(top, baseline, left, right, m_oFont, m_oBrush, m_oManagers.pFontManager, oText, bForcedBold, m_bUseDefaultFont, m_bWriteStyleRaw); + } + + void CPage::Analyze() + { + // building objects from symbols + m_arConts = m_oContBuilder.GetConts(); + m_arDiacriticalSymbols = MoveDiacriticalSymbols(); + m_arTextLines = BuildTextLines(); + + // analyzing data. can take shapes and set them to nullptr + AnalyzeShapes(); + AnalyzeTextLines(); + + // building final objects + m_arParagraphs = BuildParagraphs(); + + // if (m_bIsBuildTables) + // m_arTables = BuildTables(); + + // post analyze + CalcSelected(); + MergeShapes(); + CalcShapesRotation(); + + m_arOutputObjects = BuildOutputObjects(); + // for (auto& t : m_arTables) + // m_arOutputObjects.push_back(t); + } + + void CPage::Record(NSStringUtils::CStringBuilder& oWriter, bool bIsLastPage) + { + ToXml(oWriter); + WriteSectionToFile(bIsLastPage, oWriter); + } + + std::vector CPage::GetXmlShapes() + { + std::vector xml_shapes; + for (const auto& shape : m_arShapes) + { + if (!shape) continue; + auto writer = new NSStringUtils::CStringBuilder(); + shape->ToXml(*writer); + xml_shapes.push_back(writer->GetData()); + delete writer; + } + if (!m_arCompleteObjectsXml.empty()) + xml_shapes.insert(xml_shapes.end(), m_arCompleteObjectsXml.begin(), m_arCompleteObjectsXml.end()); + + return xml_shapes; + } + std::vector CPage::GetXmlShapesPptx() + { + ReorderShapesForPptx(); + + std::vector xml_shapes; + for (const auto& shape : m_arShapes) + { + if (!shape) continue; + auto writer = new NSStringUtils::CStringBuilder(); + shape->ToXmlPptx(*writer); + xml_shapes.push_back(writer->GetData()); + delete writer; + } + if (!m_arCompleteObjectsXml.empty()) + xml_shapes.insert(xml_shapes.end(), m_arCompleteObjectsXml.begin(), m_arCompleteObjectsXml.end()); + + return xml_shapes; + } + void CPage::AddCompleteXml(const std::wstring oXml) + { + m_arCompleteObjectsXml.push_back(oXml); + } + void CPage::ReorderShapesForPptx() + { + // переместим nullptr в конец и удалим + auto right = MoveNullptr(m_arShapes.begin(), m_arShapes.end()); + m_arShapes.erase(right, m_arShapes.end()); + + std::sort(m_arShapes.begin(), m_arShapes.end(), [] (const shape_ptr_t& s1, const shape_ptr_t& s2) { + if (s1->m_bIsBehindDoc && !s2->m_bIsBehindDoc) return true; + if (!s1->m_bIsBehindDoc && s2->m_bIsBehindDoc) return false; + return s1->m_nOrder < s2->m_nOrder; + }); + } + + std::vector CPage::MoveDiacriticalSymbols() + { + std::vector diac_symbols; + for (auto& cont : m_arConts) + if (cont && cont->IsDiacritical()) + diac_symbols.push_back(std::move(cont)); + return diac_symbols; + } + + std::vector CPage::BuildTextLines() + { + line_ptr_t curr_line = nullptr; + std::vector text_lines; + + for (auto& cont : m_arConts) + { + if (!cont) + continue; + + if (curr_line && fabs(curr_line->m_dBaselinePos - cont->m_dBaselinePos) <= c_dTHE_SAME_STRING_Y_PRECISION_MM) + { + curr_line->AddCont(cont); + continue; + } + + bool skip = false; + for (size_t i = 0; i < text_lines.size(); ++i) + { + if (fabs(text_lines[i]->m_dBaselinePos - cont->m_dBaselinePos) <= c_dTHE_SAME_STRING_Y_PRECISION_MM) + { + curr_line = text_lines[i]; + cont->m_bPossibleSplit = true; + curr_line->AddCont(cont); + skip = true; + } + } + + if (skip) + continue; + + curr_line = std::make_shared(); + curr_line->AddCont(cont); + text_lines.push_back(curr_line); + } + + for (size_t i = 0; i < text_lines.size(); i++) + { + bool only_spaces = true; + for (auto& cont : text_lines[i]->m_arConts) + { + if (!cont->IsOnlySpaces()) + { + only_spaces = false; + break; + } + } + if (only_spaces) + text_lines.erase(text_lines.begin() + i, text_lines.begin() + i + 1); + } + return text_lines; + } + + void CPage::MergeShapes() + { + if (m_arShapes.empty()) + return; + + std::sort(m_arShapes.begin(), m_arShapes.end(), [] (const shape_ptr_t& a, const shape_ptr_t& b) { + if (!a) return false; + if (!b) return true; + return a->m_nOrder < b->m_nOrder; + }); + + using shape_ref_ptr_t = std::reference_wrapper; + for (size_t i = 0; i < m_arShapes.size() - 1; i++) + { + shape_ref_ptr_t val = m_arShapes[i]; + shape_ref_ptr_t next_val = m_arShapes[i + 1]; + + if (!val.get() || ! next_val.get()) + continue; + + next_val.get()->TryMergeShape(val.get()); + } + } + void CPage::CalcShapesRotation() + { + for (auto& shape : m_arShapes) + { + if (!shape || fabs(shape->m_dRotation) < c_dMIN_ROTATION) continue; + shape->CalcNoRotVector(); + } + } + + std::vector CPage::BuildOutputObjects() + { + std::vector output_objects; + + if (m_eTextAssociationType == TextAssociationType::tatPlainParagraph || + m_eTextAssociationType == TextAssociationType::tatPlainLine) + { + CBaseItem* prev_p = nullptr; + + size_t first_index = 0; + size_t second_index = first_index + 1; + + for (; first_index < m_arParagraphs.size(); first_index = second_index++) + { + auto& first_p = m_arParagraphs[first_index]; + if (second_index != m_arParagraphs.size()) + { + auto& second_p = m_arParagraphs[second_index]; + while (second_index < m_arParagraphs.size() && first_p->m_dBaselinePos > second_p->m_dTop) + second_index++; + } + + if (second_index - first_index == 1) + { + auto& p = m_arParagraphs[first_index]; + + if (!prev_p) + p->m_dSpaceBefore = p->m_dTop + c_dCORRECTION_FOR_FIRST_PARAGRAPH; + else + p->m_dSpaceBefore = p->m_dTop - prev_p->m_dBaselinePos; + + output_objects.push_back(p); + prev_p = p.get(); + } + else + { + for (size_t j = first_index; j < second_index; ++j) + m_arShapes.push_back(CreateSingleParagraphShape(m_arParagraphs[j])); + } + } + } + + else if (m_eTextAssociationType == TextAssociationType::tatParagraphToShape || + m_eTextAssociationType == TextAssociationType::tatShapeLine) + { + for (auto& p : m_arParagraphs) + m_arShapes.push_back(CreateSingleParagraphShape(p)); + } + + return output_objects; + } + + void CPage::CalcSelected() + { + for (auto& line : m_arTextLines) + for (auto& cont : line->m_arConts) + { + if (cont && cont->m_oSelectedSizes.dHeight == 0.0 && cont->m_oSelectedSizes.dWidth == 0.0) + { + if (m_bUseDefaultFont) + { + cont->m_oSelectedSizes.dHeight = cont->m_dHeight; + cont->m_oSelectedSizes.dWidth = cont->m_dWidth; + } + else + { + cont->CalcSelected(); + } + } + } + } + + void CPage::AnalyzeShapes() + { + std::sort(m_arShapes.begin(), m_arShapes.end(), [] (const shape_ptr_t& a, const shape_ptr_t& b) { + return a->m_dLeft < b->m_dLeft; + }); + + AnalyzeLinesType(); + } + + void CPage::AnalyzeLinesType() + { + for (size_t i = 0; i < m_arShapes.size(); ++i) + { + if (!m_arShapes[i] || m_arShapes[i]->m_dHeight > c_dMAX_LINE_HEIGHT_MM || // рассматриваем только тонкие объекты + (m_arShapes[i]->m_eGraphicsType != eGraphicsType::gtRectangle && + m_arShapes[i]->m_eGraphicsType != eGraphicsType::gtCurve)) + { + continue; + } + + std::vector curr_shape_indexes; + curr_shape_indexes.push_back(i); + + for (size_t j = i + 1; j < m_arShapes.size(); ++j) + { + if (!m_arShapes[j] || m_arShapes[i]->AreObjectsNoCrossingByVertically(m_arShapes[j].get())) // значительно ускоряет работу + continue; + + bool bIf1 = m_arShapes[i]->IsCorrelated(m_arShapes[j]); + + // довольно странное поведение - в зависимости от толщины линии информация о графике записывается в разные структуры + bool bIf2 = m_arShapes[i]->m_oBrush.IsEqual(&m_arShapes[j]->m_oBrush); + bool bIf3 = m_arShapes[i]->m_oPen.IsEqual(&m_arShapes[j]->m_oPen); + + // линия должна быть одного размера по высоте + bool bIf4 = fabs(m_arShapes[i]->m_dHeight - m_arShapes[j]->m_dHeight) < c_dGRAPHICS_ERROR_IN_LINES_MM; + + // все должно быть на одной линии + bool bIf5 = fabs(m_arShapes[i]->m_dBaselinePos - m_arShapes[j]->m_dBaselinePos) < c_dGRAPHICS_ERROR_IN_LINES_MM * 5; + + if (bIf1 && (bIf2 || bIf3) && bIf4 && bIf5) // все должно быть на одной линии + curr_shape_indexes.push_back(j); + } + + if (curr_shape_indexes.size() > 1) + { + size_t j = 0; + for (size_t k = 1; k < curr_shape_indexes.size(); ++k) + { + auto& first_shape = m_arShapes[curr_shape_indexes[j]]; + auto& second_shape = m_arShapes[curr_shape_indexes[k]]; + + CShape::CheckLineType(first_shape, second_shape, k == curr_shape_indexes.size() - 1); + if (!m_arShapes[j]) + { + j = k; + k++; + } + } + } + else if (curr_shape_indexes.size() == 1) + CShape::CheckLineType(m_arShapes[curr_shape_indexes[0]]); + + curr_shape_indexes.clear(); + } + } + + void CPage::GetHorVerLines() + { + for (const auto& shape : m_arShapes) + if (shape) + { + const double out_of_page_coeff = 1.1; + bool is_out_of_page = shape->m_dTop < 0 || + shape->m_dBaselinePos > this->m_dHeight * out_of_page_coeff || + shape->m_dLeft < 0 || + shape->m_dRight > this->m_dWidth * out_of_page_coeff; + + + bool is_too_big = (!shape->m_bIsNoFill && (shape->m_dWidth > c_dSHAPE_TROUGH_MAX_MM || shape->m_dHeight > c_dSHAPE_TROUGH_MAX_MM)); + + if (is_too_big || is_out_of_page) + continue; + + m_oHorVerLinesCollector.AddVector(shape->m_oVector); + } + } + + void CPage::AnalyzeTextLines() + { + // вся логика основана на отсортированных списках объектов + std::sort(m_arTextLines.begin(), m_arTextLines.end(), [] (const line_ptr_t& a, const line_ptr_t& b) { + return a->m_dBaselinePos < b->m_dBaselinePos; + }); + + AnalyzeDropCaps(); + AnalyzeConts(); + AnalyzeEffects(); + + GetHorVerLines(); + + AddDiacriticalSymbols(); + MergeTextLinesByVatType(); + DeleteTextClipPage(); + MergeConts(); + SplitLines(); + AnalyzeOverlapLines(); + + // переместим nullptr в конец и удалим + auto right = MoveNullptr(m_arTextLines.begin(), m_arTextLines.end()); + m_arTextLines.erase(right, m_arTextLines.end()); + + std::sort(m_arTextLines.begin(), m_arTextLines.end(), [] (const line_ptr_t& a, const line_ptr_t& b) { + return a->m_dBaselinePos < b->m_dBaselinePos; + }); + } + + void CPage::AnalyzeDropCaps() + { + double avg_font_size = m_oManagers.pParagraphStyleManager->GetAvgFontSize(); + + std::vector> possible_caps; + std::vector drop_caps; + + for (size_t i = 0; i < m_arTextLines.size(); i++) + { + auto& line = m_arTextLines[i]; + for (auto& cont : line->m_arConts) + if (cont && cont->m_pFontStyle->dFontSize > 2 * avg_font_size && cont->GetText().length() == 1) + possible_caps.push_back({cont, line}); + } + + for (auto& possible_cap : possible_caps) + { + auto& drop_cap_cont = possible_cap.first; + auto& drop_cap_line = possible_cap.second; + + size_t num_of_lines = 0; + + for(auto& line : m_arTextLines) + { + if (!line || line == drop_cap_line) + continue; + + // буквица должна быть левее + if (line->m_dLeft < drop_cap_cont->m_dLeft) + continue; + + // если совпадает строка по высоте - берем ее и выходим + if (fabs(line->m_dBotWithMaxDescent - drop_cap_cont->m_dBotWithDescent) < c_dTHE_SAME_STRING_Y_PRECISION_MM) + { + num_of_lines++; + break; + } + + if (line->m_dBotWithMaxDescent < drop_cap_cont->m_dTopWithAscent) + continue; + + if (line->m_dTopWithMaxAscent > drop_cap_cont->m_dBotWithDescent) + break; + + num_of_lines++; + } + if (num_of_lines > 1) + { + drop_caps.push_back(std::move(drop_cap_cont)); + if (drop_cap_line->IsCanBeDeleted()) + drop_cap_line = nullptr; + + if (drop_cap_line) + drop_cap_line->RecalcSizes(); + } + } + + // шейпы из буквиц + for (auto&& drop_cap : drop_caps) + { + drop_cap->CalcSelected(); + + auto line = std::make_shared(); + line->AddCont(drop_cap); + + auto shape = CreateSingleLineShape(line); + m_arShapes.push_back(shape); + } + } + void CPage::AnalyzeConts() + { + for (size_t uCurrLineIndex = 0; uCurrLineIndex < m_arTextLines.size(); ++uCurrLineIndex) + { + auto& pCurrLine = m_arTextLines[uCurrLineIndex]; + if (!pCurrLine) + continue; + + for (size_t uCurrContIndex = 0; uCurrContIndex < pCurrLine->m_arConts.size(); ++uCurrContIndex) + { + auto& pCurrCont = pCurrLine->m_arConts[uCurrContIndex]; + if (!pCurrCont) + continue; + + // берем вторую линию, если символ последний - то начиная со следуюущей, иначе с той же + for (size_t uNextLineIndex = uCurrContIndex >= pCurrLine->m_arConts.size() - 1 ? + uCurrLineIndex + 1 : uCurrLineIndex; uNextLineIndex < m_arTextLines.size(); ++uNextLineIndex) + { + auto& pNextLine = m_arTextLines[uNextLineIndex]; + + // значительно ускоряет работу, то есть если никак не перескается - некст + if (!pNextLine || pCurrLine->AreObjectsNoCrossingByVertically(pNextLine.get())) + continue; + + // посимвольно смотрим некст линию - если та же то следующий символ, если другая - то с нуля + for (size_t uNextContIndex = uNextLineIndex != uCurrLineIndex ? 0 : uCurrContIndex + 1; + uNextContIndex < pNextLine->m_arConts.size(); ++uNextContIndex) + { + if (!pCurrCont) + break; + + // берем символ во второй линии + auto& pNextCont = pNextLine->m_arConts[uNextContIndex]; + if (!pNextCont) + continue; + + eVerticalCrossingType eVType = pCurrCont->GetVerticalCrossingType(pNextCont.get()); + eHorizontalCrossingType eHType = pCurrCont->GetHorizontalCrossingType(pNextCont.get()); + + bool is_font_effect = CContText::CheckFontEffects(pCurrCont, pNextCont, eVType, eHType); + if (!is_font_effect && CContText::CheckVertAlignTypeBetweenConts(pCurrCont, pNextCont, eVType, eHType)) + { + pCurrLine->SetVertAlignType(pCurrCont->m_eVertAlignType); + pNextLine->SetVertAlignType(pNextCont->m_eVertAlignType); + if ((pCurrLine->m_eVertAlignType == eVertAlignType::vatSuperscript && + pNextLine->m_eVertAlignType == eVertAlignType::vatBase) || + (pCurrLine->m_eVertAlignType == eVertAlignType::vatBase && + pNextLine->m_eVertAlignType == eVertAlignType::vatSubscript)) + { + pCurrLine->m_pLine = pNextLine; + pNextLine->m_pLine = pCurrLine; + } + } + else if (!is_font_effect && pCurrCont->IsDuplicate(pNextCont.get(), eVType, eHType)) + { + pNextCont = nullptr; + pCurrCont->m_iNumDuplicates++; + if (!pCurrCont->m_pFontStyle.get()->bBold) + { + CFontStyle font_style = *pCurrCont->m_pFontStyle; + font_style.bBold = true; + pCurrCont->m_pFontStyle = m_oManagers.pFontStyleManager->GetOrAddFontStyle(font_style); + } + } + } + if (pNextLine && pNextLine->IsCanBeDeleted()) + pNextLine = nullptr; + } + } + if (pCurrLine && pCurrLine->IsCanBeDeleted()) + pCurrLine = nullptr; + } + } + + void CPage::AnalyzeEffects() + { + for (size_t i = 0; i < m_arShapes.size(); ++i) + { + auto& shape = m_arShapes[i]; + if (!shape || shape->m_eGraphicsType == eGraphicsType::gtNoGraphics) + continue; + + bool shape_used = false; + for (size_t j = 0; j < m_arTextLines.size(); ++j) + { + auto& curr_line = m_arTextLines[j]; + if (!curr_line) + continue; + + bool is_no_crossing_v = curr_line->AreObjectsNoCrossingByVertically(shape.get()); + bool is_higher = curr_line->m_dTop > shape->m_dBaselinePos; + bool is_lower = curr_line->m_dBaselinePos + curr_line->m_dHeight < shape->m_dTop; + if (is_no_crossing_v && (is_higher || is_lower)) + continue; + + for (size_t k = 0; k < curr_line->m_arConts.size(); ++k) + { + cont_ptr_t curr_cont = curr_line->m_arConts[k]; + if (!curr_cont) + continue; + + bool is_width_equal = (curr_line->m_dWidth * 1.05 - shape->m_dWidth) > 0; + + bool is_crossing_text = IsLineCrossingText(shape, curr_cont) && is_width_equal; + bool is_below_text = IsLineBelowText(shape, curr_cont) && is_width_equal; + bool is_outline = IsOutline(shape, curr_cont); + bool is_highlight = IsHighlight(shape, curr_cont) && curr_line->m_dHeight * 1.5 > shape->m_dHeight && is_width_equal; + + bool is_smth_true = is_crossing_text || is_below_text || is_outline || is_highlight; + if (is_smth_true) + { + // if crossing a part of cont - split it + if (shape->m_dLeft > curr_cont->m_dLeft) + { + auto another_cont = curr_cont->Split(shape->m_dLeft); + if (another_cont != nullptr) + { + curr_line->m_arConts.insert(curr_line->m_arConts.begin() + k, another_cont); + ++k; + curr_cont = another_cont; + } + } + if (shape->m_dRight < curr_cont->m_dRight) + { + auto another_cont = curr_cont->Split(shape->m_dRight); + if (another_cont != nullptr) + { + curr_line->m_arConts.insert(curr_line->m_arConts.begin() + k + 1, another_cont); + ++k; + } + } + + if (is_crossing_text) + { + curr_cont->m_bIsStrikeoutPresent = true; + if (shape->m_eLineType == eLineType::ltDouble) + curr_cont->m_bIsDoubleStrikeout = true; + } + + else if (is_below_text) + { + curr_cont->m_bIsUnderlinePresent = true; + curr_cont->m_eUnderlineType = shape->m_eLineType; + curr_cont->m_lUnderlineColor = shape->m_dHeight > 0.3 ? shape->m_oBrush.Color1 : shape->m_oPen.Color; + } + + else if (is_highlight) + { + curr_cont->m_pShape = shape; + curr_cont->m_bIsHighlightPresent = true; + curr_cont->m_lHighlightColor = shape->m_oBrush.Color1; + } + + else if (is_outline) + { + auto oBrush = curr_cont->m_pFontStyle->oBrush; + oBrush.Color1 = shape->m_oPen.Color; + + curr_cont->m_pFontStyle = m_oManagers.pFontStyleManager->GetOrAddFontStyle( + oBrush, + curr_cont->m_pFontStyle->wsFontName, + curr_cont->m_pFontStyle->dFontSize, + curr_cont->m_pFontStyle->bItalic, + curr_cont->m_pFontStyle->bBold); + + curr_cont->m_bIsShadowPresent = true; + curr_cont->m_bIsOutlinePresent = true; + } + } + + // проверили - удаляем + if (is_smth_true) + shape_used = true; + } + } + if (shape_used) + shape = nullptr; + } + } + + bool CPage::IsLineCrossingText(shape_ptr_t pShape, cont_ptr_t pCont) const noexcept + { + auto h_type = pCont->CBaseItem::GetHorizontalCrossingType(pShape.get()); + double dTopBorder = pCont->m_dTop + pCont->m_dHeight / 3; + double dBotBorder = pCont->m_dBaselinePos - pCont->m_dHeight / 6; + + bool bIf1 = pShape->m_eGraphicsType == eGraphicsType::gtRectangle && + pShape->m_eLineType != eLineType::ltUnknown; + + // Условие пересечения по вертикали + bool bIf2 = pShape->m_dTop > dTopBorder && pShape->m_dBaselinePos < dBotBorder; + + // Условие пересечения по горизонтали + bool bIf3 = h_type != eHorizontalCrossingType::hctUnknown && + h_type != eHorizontalCrossingType::hctCurrentLeftOfNext && + h_type != eHorizontalCrossingType::hctNoCrossingCurrentLeftOfNext && + h_type != eHorizontalCrossingType::hctNoCrossingCurrentRightOfNext; + + // Условие для размеров по высоте + bool bIf4 = pShape->m_dHeight < pCont->m_dHeight && + pCont->m_dHeight - pShape->m_dHeight > c_dERROR_FOR_TEXT_WITH_GRAPHICS_MM; + + return bIf1 && bIf2 && bIf3 && bIf4; + } + + bool CPage::IsLineBelowText(shape_ptr_t pShape, cont_ptr_t pCont) const noexcept + { + auto h_type = pCont->CBaseItem::GetHorizontalCrossingType(pShape.get()); + bool bIf1 = (pShape->m_eGraphicsType == eGraphicsType::gtRectangle || + pShape->m_eGraphicsType == eGraphicsType::gtCurve) && + pShape->m_eLineType != eLineType::ltUnknown; + + //Условие по вертикали + double max_diff = std::min(c_dGRAPHICS_ERROR_MM * 3, pCont->m_dHeight * 0.5); + bool bIf2 = fabs(pShape->m_dBaselinePos - pCont->m_dBaselinePos) < max_diff; + + //Условие пересечения по горизонтали + bool bIf3 = h_type != eHorizontalCrossingType::hctUnknown && + h_type != eHorizontalCrossingType::hctCurrentLeftOfNext && + h_type != eHorizontalCrossingType::hctNoCrossingCurrentLeftOfNext && + h_type != eHorizontalCrossingType::hctNoCrossingCurrentRightOfNext; + + //Условие для размеров по высоте + bool bIf4 = pShape->m_dHeight < pCont->m_dHeight * 0.5 && + pCont->m_dHeight - pShape->m_dHeight > c_dERROR_FOR_TEXT_WITH_GRAPHICS_MM; + + return bIf1 && bIf2 && bIf3 && bIf4; + } + + bool CPage::IsHighlight(shape_ptr_t pShape, cont_ptr_t pCont) const noexcept + { + auto h_type = pCont->CBaseItem::GetHorizontalCrossingType(pShape.get()); + + double dSomeBaseLine1 = pCont->m_dBaselinePos - pCont->m_dHeight * 0.70; + double dSomeBaseLine2 = pCont->m_dBaselinePos - pCont->m_dHeight * 0.5; + double dSomeBaseLine3 = pCont->m_dBaselinePos - pCont->m_dHeight * 0.3; + + bool bIf1 = pShape->m_eGraphicsType == eGraphicsType::gtRectangle; + + //Условие пересечения по вертикали + bool bIf2 = (dSomeBaseLine1 > pShape->m_dTop && dSomeBaseLine1 < pShape->m_dBaselinePos && + dSomeBaseLine2 > pShape->m_dTop && dSomeBaseLine2 < pShape->m_dBaselinePos && + dSomeBaseLine3 > pShape->m_dTop && dSomeBaseLine3 < pShape->m_dBaselinePos); + + //Условие пересечения по горизонтали + bool bIf3 = h_type != eHorizontalCrossingType::hctUnknown && + h_type != eHorizontalCrossingType::hctCurrentLeftOfNext && + h_type != eHorizontalCrossingType::hctNoCrossingCurrentLeftOfNext && + h_type != eHorizontalCrossingType::hctNoCrossingCurrentRightOfNext; + + //Цвета должны быть разными + bool bIf4 = pCont->m_pFontStyle->oBrush.Color1 != pShape->m_oBrush.Color1; + bool bIf5 = pShape->m_oBrush.Color1 == c_iBlackColor && pShape->m_oPen.Color == c_iWhiteColor; + bool bIf6 = pShape->m_bIsNoFill == false; + bool bIf7 = pShape->m_bIsNoStroke == true; + + return bIf1 && bIf2 && bIf3 && bIf4 && !bIf5 && bIf6 && bIf7; + } + + bool CPage::IsOutline(shape_ptr_t pShape, cont_ptr_t pCont) const noexcept + { + auto h_type = pCont->CBaseItem::GetHorizontalCrossingType(pShape.get()); + auto v_type = pCont->CBaseItem::GetVerticalCrossingType(pShape.get()); + + bool bIsNotComplicatedFigure = pShape->m_eGraphicsType != eGraphicsType::gtComplicatedFigure; + if (!bIsNotComplicatedFigure) + { + bool bIf1 = pCont->m_pFontStyle->oBrush.Color1 == c_iGreyColor; + bool bIf2 = v_type == eVerticalCrossingType::vctCurrentOutsideNext; + bool bIf3 = h_type == eHorizontalCrossingType::hctCurrentOutsideNext; + bool bIf4 = h_type == eHorizontalCrossingType::hctCurrentRightOfNext; + + if (bIf1 && bIf2 && (bIf3 || bIf4)) + return true; + } + return false; + } + + void CPage::AddDiacriticalSymbols() + { + for (auto& d_sym : m_arDiacriticalSymbols) + { + if (!d_sym) + continue; + + bool isBreak = false; + + for (auto& line : m_arTextLines) + { + if (!line || line->AreObjectsNoCrossingByVertically(d_sym.get())) + continue; + + for (auto& cont : line->m_arConts) + { + if (!cont) + continue; + + eVerticalCrossingType eVType = cont->GetVerticalCrossingType(d_sym.get()); + eHorizontalCrossingType eHType = cont->GetHorizontalCrossingType(d_sym.get()); + + if (eVType != eVerticalCrossingType::vctNoCrossingCurrentAboveNext && + eVType != eVerticalCrossingType::vctNoCrossingCurrentBelowNext && + eHType != eHorizontalCrossingType::hctNoCrossingCurrentLeftOfNext && + eHType != eHorizontalCrossingType::hctNoCrossingCurrentRightOfNext) + { + bool bIf1 = eHType == eHorizontalCrossingType::hctCurrentOutsideNext; + bool bIf2 = eHType == eHorizontalCrossingType::hctCurrentLeftOfNext; + bool bIf3 = eHType == eHorizontalCrossingType::hctCurrentRightOfNext; + bool bIf4 = eHType == eHorizontalCrossingType::hctDublicate; + bool bIf5 = eHType == eHorizontalCrossingType::hctRightBorderMatch; + + bool bIf6 = eVType == eVerticalCrossingType::vctCurrentBelowNext || + eVType == eVerticalCrossingType::vctCurrentAboveNext; + bool bIf7 = eVType == eVerticalCrossingType::vctTopAndBottomBordersMatch; + bool bIf8 = eVType == eVerticalCrossingType::vctDublicate; + + if ((bIf1 && bIf6) || (bIf2 && bIf7) || (bIf4 && bIf8) || (bIf5 && bIf7)) + { + cont->AddSymBack(d_sym->GetText().at(0), 0); + } + else if (bIf3 && bIf7) + { + cont->AddSymFront(d_sym->GetText().at(0), 0); + } + d_sym = nullptr; + isBreak = true; + break; + } + } + if (isBreak) + break; + } + } + } + + void CPage::MergeTextLinesByVatType() + { + for (auto& line : m_arTextLines) + { + if (!line) + continue; + + if (line->m_eVertAlignType == eVertAlignType::vatSuperscript + || line->m_eVertAlignType == eVertAlignType::vatSubscript) + { + line_ptr_t& base_line = line->m_pLine; + if (base_line) + { + for (auto& pCont : line->m_arConts) + { + if (!pCont) + continue; + if (base_line->m_dLeft > pCont->m_dLeft) + base_line->m_dLeft = pCont->m_dLeft; + if (base_line->m_dRight < pCont->m_dRight) + base_line->m_dRight = pCont->m_dRight; + + base_line->m_dWidth = base_line->m_dRight - base_line->m_dLeft; + base_line->m_arConts.push_back(pCont); + pCont = nullptr; + } + line = nullptr; + } + } + } + } + + void CPage::ToXml(NSStringUtils::CStringBuilder& oWriter) const noexcept + { + bool bIsNeedWP = !m_arShapes.empty(); + + if (bIsNeedWP) + { + oWriter.WriteString(L""); + //note при удалении строки откуда-то добавляется в начале страницы (если есть графика и текст), что добавляет дополнительную строку и сдвигает текст + oWriter.WriteString(L""); + } + + for (const auto& shape : m_arShapes) + if (shape) + shape->ToXml(oWriter); + + if (bIsNeedWP) + { + oWriter.WriteString(L""); + } + + for (auto& obj : m_arOutputObjects) + obj->ToXml(oWriter); + } + + void CPage::MergeConts() + { + for (size_t i = 0; i < m_arTextLines.size(); ++i) + { + auto& curr_line = m_arTextLines[i]; + if (!curr_line) continue; + curr_line->MergeConts(); + } + DetermineDominantGraphics(); + } + + void CPage::DetermineDominantGraphics() + { + shape_ptr_t pDominantShape = nullptr; + + for (size_t i = 0; i < m_arTextLines.size(); ++i) + { + auto pLine = m_arTextLines[i]; + if (!pLine) + continue; + + for (size_t j = 0; j < pLine->m_arConts.size(); ++j) + { + auto pCont = pLine->m_arConts[j]; + if (!pCont) + continue; + + if (pCont->m_pShape && pCont->m_pShape != pDominantShape) + { + if (pCont->m_pShape->m_dLeft < pCont->m_dLeft && + pCont->m_pShape->m_dRight > pCont->m_dRight) + { + if (!pDominantShape || + (pCont->m_pShape->m_dLeft < pDominantShape->m_dLeft && + pCont->m_pShape->m_dRight > pDominantShape->m_dRight)) + { + pDominantShape = pCont->m_pShape; + } + } + } + } + + pLine->m_pDominantShape = pDominantShape; + pDominantShape = nullptr; + } + } + + bool CPage::IsVerticalLineBetween(item_ptr_t pFirst, item_ptr_t pSecond) const noexcept + { + double left = std::min(pFirst->m_dRight, pSecond->m_dRight); + double right = std::max(pFirst->m_dLeft, pSecond->m_dLeft); + double top = std::min(pFirst->m_dTop, pSecond->m_dTop); + double bot = std::max(pFirst->m_dBaselinePos, pSecond->m_dBaselinePos); + + auto dummy_cont = std::make_shared(); + dummy_cont->m_dLeft = left - c_dGRAPHICS_ERROR_MM; + dummy_cont->m_dRight = right + c_dGRAPHICS_ERROR_MM; + dummy_cont->m_dTop = top - c_dGRAPHICS_ERROR_MM; + dummy_cont->m_dBaselinePos = bot + c_dGRAPHICS_ERROR_MM; + + return IsVerticalLineTrough(dummy_cont); + } + bool CPage::IsHorizontalLineBetween(item_ptr_t pFirst, item_ptr_t pSecond) const noexcept + { + double left = std::min(pFirst->m_dLeft, pSecond->m_dLeft); + double right = std::max(pFirst->m_dRight, pSecond->m_dRight); + double top = std::min(pFirst->m_dBaselinePos, pSecond->m_dBaselinePos); + double bot = std::max(pFirst->m_dTop, pSecond->m_dTop); + + auto dummy_cont = std::make_shared(); + dummy_cont->m_dLeft = left - c_dGRAPHICS_ERROR_MM; + dummy_cont->m_dRight = right + c_dGRAPHICS_ERROR_MM; + dummy_cont->m_dTop = top - c_dGRAPHICS_ERROR_MM; + dummy_cont->m_dBaselinePos = bot + c_dGRAPHICS_ERROR_MM; + + return IsHorizontalLineTrough(dummy_cont); + } + bool CPage::IsVerticalLineBetween(line_ptr_t pFirst, line_ptr_t pSecond) const noexcept + { + double left = std::min(pFirst->m_dRight, pSecond->m_dRight); + double right = std::max(pFirst->m_dLeft, pSecond->m_dLeft); + double top = std::min(pFirst->m_dTopWithMaxAscent, pSecond->m_dTopWithMaxAscent); + double bot = std::max(pFirst->m_dBotWithMaxDescent, pSecond->m_dBotWithMaxDescent); + + auto dummy_cont = std::make_shared(); + dummy_cont->m_dLeft = left - c_dGRAPHICS_ERROR_MM; + dummy_cont->m_dRight = right + c_dGRAPHICS_ERROR_MM; + dummy_cont->m_dTop = top - c_dGRAPHICS_ERROR_MM; + dummy_cont->m_dBaselinePos = bot + c_dGRAPHICS_ERROR_MM; + + return IsVerticalLineTrough(dummy_cont); + } + bool CPage::IsHorizontalLineBetween(line_ptr_t pFirst, line_ptr_t pSecond) const noexcept + { + double left = std::min(pFirst->m_dLeft, pSecond->m_dLeft); + double right = std::max(pFirst->m_dRight, pSecond->m_dRight); + double top = std::min(pFirst->m_dBotWithMaxDescent, pSecond->m_dBotWithMaxDescent); + double bot = std::max(pFirst->m_dTopWithMaxAscent, pSecond->m_dTopWithMaxAscent); + + auto dummy_cont = std::make_shared(); + dummy_cont->m_dLeft = left - c_dGRAPHICS_ERROR_MM; + dummy_cont->m_dRight = right + c_dGRAPHICS_ERROR_MM; + dummy_cont->m_dTop = top - c_dGRAPHICS_ERROR_MM; + dummy_cont->m_dBaselinePos = bot + c_dGRAPHICS_ERROR_MM; + + return IsHorizontalLineTrough(dummy_cont); + } + + bool CPage::IsVerticalLineTrough(item_ptr_t pFirst) const noexcept + { + const auto& ver_lines = m_oHorVerLinesCollector.GetVertical(); + const auto height = pFirst->m_dBaselinePos - pFirst->m_dTop; + const auto center = pFirst->m_dTop + height / 2; + + for (const auto& line : ver_lines) + if (line.pos > pFirst->m_dLeft && line.pos < pFirst->m_dRight && line.min <= center && line.max >= center) + return true; + + return false; + } + bool CPage::IsHorizontalLineTrough(item_ptr_t pFirst) const noexcept + { + const auto& hor_lines = m_oHorVerLinesCollector.GetHorizontal(); + const auto width = pFirst->m_dRight - pFirst->m_dLeft; + const auto center = pFirst->m_dLeft + width / 2; + + for (const auto& line : hor_lines) + if (line.pos > pFirst->m_dTop && line.pos < pFirst->m_dBaselinePos && line.min <= center && line.max >= center) + return true; + + return false; + } + + void CPage::SplitLines() + { + for (size_t index = 0; index < m_arTextLines.size(); ++index) + { + auto& line = m_arTextLines[index]; + + if (!line) + continue; + + bool next_line = false; + for (size_t i = 0; i < line->m_arConts.size(); ++i) + { + bool is_space = line->m_arConts[i] && line->m_arConts[i]->GetText().ToStdWString() == L" "; + bool is_cont_wide = line->m_arConts[i]->m_dWidth > c_dLINE_SPLIT_DISTANCE_MM; + bool is_shape_trough = IsVerticalLineTrough(line->m_arConts[i]); + + if ((i != line->m_arConts.size() - 1 && line->m_arConts[i + 1]->m_bPossibleSplit && is_space) + || (is_space && is_cont_wide) + || is_shape_trough) + { + std::vector line_conts_first; + std::vector line_conts_second; + + // taking last cont or not + for (size_t j = 0; j < (is_space ? i : i + 1); ++j) + if (line->m_arConts[j]) + line_conts_first.push_back(line->m_arConts[j]); + + for (size_t j = i + 1; j < line->m_arConts.size(); ++j) + if (line->m_arConts[j]) + line_conts_second.push_back(line->m_arConts[j]); + + line_ptr_t line_first(new CTextLine()); + line_ptr_t line_second(new CTextLine()); + + line_first->AddConts(line_conts_first); + line_second->AddConts(line_conts_second); + + if (!line_second->m_arConts.empty()) + m_arTextLines.push_back(line_second); + + if (m_arTextLines[index]->m_arConts.empty()) + { + m_arTextLines.erase(m_arTextLines.begin() + index, m_arTextLines.begin() + index + 1); + index--; + } + else + m_arTextLines[index] = line_first; + + next_line = true; + break; + } + } + if (next_line) + continue; + } + } + + std::vector> CPage::GetLinesByGroups() + { + struct Group { + double left{}; + double right{}; + double top{}; + double bot{}; + bool closed{false}; + }; + + std::vector> line_groups; + std::vector groups; + + for (auto& line : m_arTextLines) + { + bool is_found = false; + bool is_create_new = false; + size_t insert_index = 0; + + for (size_t index = 0; index < groups.size(); ++index) + { + auto& group = groups[index]; + bool is_crossing_h = !((line->m_dRight <= group.left) || (line->m_dLeft >= group.right)); + bool is_crossing_v = !((line->m_dBotWithMaxDescent <= group.top) || (line->m_dTopWithMaxAscent >= group.bot)); + + if (!group.closed && is_crossing_h) + { + if (is_crossing_v) + { + groups[index].closed = true; + continue; + } + if (!is_found && !is_create_new) + { + is_found = true; + insert_index = index; + } + else + { + groups[insert_index].closed = true; + groups[index].closed = true; + is_create_new = true; + is_found = false; + } + } + } + if (is_found) + { + groups[insert_index].left = std::min(groups[insert_index].left, line->m_dLeft); + groups[insert_index].right = std::max(groups[insert_index].right, line->m_dRight); + groups[insert_index].bot = std::max(groups[insert_index].bot, line->m_dBaselinePos); + groups[insert_index].top = std::min(groups[insert_index].top, line->m_dTop); + line_groups[insert_index].push_back(line); + } + else + { + Group new_group; + new_group.left = line->m_dLeft; + new_group.right = line->m_dRight; + new_group.top = line->m_dTop; + new_group.bot = line->m_dBaselinePos; + new_group.closed = false; + groups.push_back(new_group); + + std::vector line_group; + line_group.push_back(line); + line_groups.push_back(line_group); + } + } + return line_groups; + } + + void CPage::AnalyzeOverlapLines() + { + auto no_crossing = [] (const eHorizontalCrossingType& h_type, const eVerticalCrossingType& v_type) { + return h_type == eHorizontalCrossingType::hctNoCrossingCurrentLeftOfNext || + h_type == eHorizontalCrossingType::hctNoCrossingCurrentRightOfNext || + v_type == eVerticalCrossingType::vctNoCrossingCurrentAboveNext || + v_type == eVerticalCrossingType::vctNoCrossingCurrentBelowNext; + }; + + // линии из которых сделаем шейпы + for (size_t index = 0; index < m_arTextLines.size(); ++index) + { + auto& curr_line = m_arTextLines[index]; + if (!curr_line) + continue; + + // если линия пересекается с предыдущей линией + if (index && m_arTextLines[index - 1]) + { + auto& prev_line = m_arTextLines[index - 1]; + + if (!prev_line) + continue; + + auto h_type = curr_line->GetHorizontalCrossingType(prev_line.get()); + auto v_type = curr_line->GetVerticalCrossingType(prev_line.get()); + + if (!no_crossing(h_type, v_type)) + { + prev_line->CalcFirstWordWidth(); + curr_line->CalcFirstWordWidth(); + + for (auto& cont : prev_line->m_arConts) + cont->CalcSelected(); + + for (auto& cont : curr_line->m_arConts) + cont->CalcSelected(); + + m_arShapes.push_back(CreateSingleLineShape(prev_line)); + m_arShapes.push_back(CreateSingleLineShape(curr_line)); + prev_line = nullptr; + curr_line = nullptr; + continue; + } + } + } + } + + std::vector CPage::BuildParagraphs() + { + if (m_arTextLines.empty()) + return {}; + + auto line_groups = GetLinesByGroups(); + std::vector ar_paragraphs; + + double min_left{m_dWidth}; + double max_right{0.0}; + + // совпадает ли left, right, center со строкой ниже + struct Position { + bool left{false}; + bool center{false}; + bool right{false}; + }; + + // lamda to setup and add paragpraph + auto add_paragraph = [this, &max_right, &min_left, &ar_paragraphs] (paragraph_ptr_t& paragraph) { + + paragraph->m_dBaselinePos = paragraph->m_arLines.back()->m_dBaselinePos; + paragraph->m_dTop = paragraph->m_arLines.front()->m_dTop; + paragraph->m_dRight = max_right + c_dERROR_OF_PARAGRAPH_BORDERS_MM; + paragraph->m_dLeft = min_left; + + paragraph->m_dWidth = paragraph->m_dRight - paragraph->m_dLeft; + paragraph->m_dHeight = paragraph->m_dBaselinePos - paragraph->m_dTop; + + paragraph->m_dRightBorder = m_dWidth - paragraph->m_dRight; + paragraph->m_dLeftBorder = min_left; + + paragraph->m_dLineHeight = paragraph->m_dHeight / paragraph->m_arLines.size(); + paragraph->m_bIsNeedFirstLineIndent = false; + paragraph->m_dFirstLine = 0; + paragraph->m_wsStyleId = m_oManagers.pParagraphStyleManager->GetDefaultParagraphStyleId(*paragraph); + + paragraph->MergeLines(); + + // setting TextAlignmentType + if (paragraph->m_arLines.size() > 1) + { + Position position_curr; + position_curr.left = true; + position_curr.center = true; + position_curr.right = true; + + bool first_left = false; + + for (size_t index = 1; index < paragraph->m_arLines.size(); ++index) + { + auto& curr_line = paragraph->m_arLines[index]; + auto& prev_line = paragraph->m_arLines[index - 1]; + + // indent check + if (index == 1) + first_left = fabs(curr_line->m_dLeft - prev_line->m_dLeft) < c_dERROR_OF_PARAGRAPH_BORDERS_MM; + else + position_curr.left &= fabs(curr_line->m_dLeft - prev_line->m_dLeft) < c_dERROR_OF_PARAGRAPH_BORDERS_MM; + + position_curr.right &= fabs(curr_line->m_dRight - prev_line->m_dRight) < c_dERROR_OF_PARAGRAPH_BORDERS_MM; + + auto center_curr = curr_line->m_dLeft + curr_line->m_dWidth / 2; + auto center_prev = prev_line->m_dLeft + prev_line->m_dWidth / 2; + + position_curr.center &= fabs(center_curr - center_prev) < c_dCENTER_POSITION_ERROR_MM; + } + if (position_curr.left && position_curr.right && first_left) + paragraph->m_eTextAlignmentType = CParagraph::tatByWidth; + else if (position_curr.left) + paragraph->m_eTextAlignmentType = CParagraph::tatByLeft; + else if (position_curr.right) + paragraph->m_eTextAlignmentType = CParagraph::tatByRight; + else if (position_curr.center) + paragraph->m_eTextAlignmentType = CParagraph::tatByCenter; + + // indent check + if (paragraph->m_eTextAlignmentType == CParagraph::tatByLeft && !first_left) + { + double left_diff = paragraph->m_arLines[0]->m_dLeft - paragraph->m_arLines[1]->m_dLeft; + paragraph->m_bIsNeedFirstLineIndent = true; + paragraph->m_dFirstLine = left_diff; + + if (left_diff < 0) + paragraph->m_dLeftBorder -= left_diff; + } + } + + ar_paragraphs.push_back(std::move(paragraph)); + paragraph = std::make_shared(); + + min_left = m_dWidth; + max_right = 0.0; + }; + + // lamda to add line and setup min_left/max_right + auto add_line = [&min_left, &max_right] (paragraph_ptr_t& paragraph, const line_ptr_t& curr_line) { + min_left = std::min(min_left, curr_line->m_dLeft); + max_right = std::max(max_right, curr_line->m_dRight); + paragraph->m_arLines.push_back(curr_line); + }; + + auto build_paragraphs = [this, add_line, add_paragraph] (const std::vector& text_lines) { + // ar_spacing[index]- расстояние строки до строки снизу + // если 0.0 - строка последняя + std::vector ar_spacings(text_lines.size(), 0.0); + + // позиции относительно других линий + std::vector ar_positions(text_lines.size()); + + // требуется ли отступ + std::vector ar_indents(text_lines.size(), false); + + // если ar_delims[index] == true, после строчки index нужно начинать новый параграф + std::vector ar_delims(text_lines.size(), false); + + double avg_spacing{0.0}; + size_t avg_spacing_n{0}; + + // параграф будет набиваться строчками + auto paragraph = std::make_shared(); + + // calcs first word widths + for (auto& line : text_lines) + line->CalcFirstWordWidth(); + + // calcs spacings & positions + for (size_t index = 0; index < text_lines.size() - 1; ++index) + { + ar_spacings[index] = text_lines[index + 1]->m_dTop - text_lines[index]->m_dBaselinePos; + avg_spacing = (avg_spacing / (avg_spacing_n + 1)) * avg_spacing_n + (ar_spacings[index] / (avg_spacing_n + 1)); + + auto& left_curr = text_lines[index]->m_dLeft; + auto& left_next = text_lines[index + 1]->m_dLeft; + + auto& right_curr = text_lines[index]->m_dRight; + auto& right_next = text_lines[index + 1]->m_dRight; + + auto center_curr = (text_lines[index]->m_dLeft + text_lines[index]->m_dWidth / 2); + auto center_next = (text_lines[index + 1]->m_dLeft + text_lines[index + 1]->m_dWidth / 2); + + if (fabs(center_curr - center_next) < c_dCENTER_POSITION_ERROR_MM) + ar_positions[index].center = true; + if (fabs(left_curr - left_next) < c_dERROR_OF_PARAGRAPH_BORDERS_MM) + ar_positions[index].left = true; + if (fabs(right_curr - right_next) < c_dERROR_OF_PARAGRAPH_BORDERS_MM) + ar_positions[index].right = true; + } + + // spacing check + for (size_t index = 0; index < ar_spacings.size(); ++index) + { + double spacing_top = 0.0; + double spacing_bot = 0.0; + + if (index != 0) spacing_top = ar_spacings[index - 1]; + spacing_bot = ar_spacings[index]; + + if (spacing_top == 0.0) spacing_top = spacing_bot; + if (spacing_bot == 0.0) spacing_bot = spacing_top; + + if (spacing_bot > c_dLINE_DISTANCE_MAX_MM) + ar_delims[index] = true; + else if (fabs(spacing_top - spacing_bot) < c_dLINE_DISTANCE_ERROR_MM) + ar_delims[index] = false; + else + { + // берем доп строчки сверху и снизу для анализа + bool same_double_top = false; + bool same_double_bot = false; + + if (index > 1) + { + double spacing_top_next = ar_spacings[index - 2]; + if (fabs(spacing_top - spacing_top_next) < c_dLINE_DISTANCE_ERROR_MM) + same_double_top = true; + } + if (index < ar_spacings.size() - 1) + { + double spacing_bot_next = ar_spacings[index + 1]; + if (fabs(spacing_bot - spacing_bot_next) < c_dLINE_DISTANCE_ERROR_MM) + same_double_bot = true; + } + + // если анализ доп строчек ничего не дал - разбиваем наиболее "вероятным" способом + if (same_double_top == same_double_bot) + { + if (spacing_top > spacing_bot) + ar_delims[index - 1] = true; + else if (spacing_top < spacing_bot) + ar_delims[index] = true; + } + // прикрепляем строчку к верху или низу + else + { + if (same_double_top) + ar_delims[index] = true; + else if (same_double_bot) + ar_delims[index - 1] = true; + } + } + } + + // alignment check + bool is_first_line = false; + Position curr_position; + + for (size_t index = 0; index < ar_positions.size() - 1; ++index) + { + Position& position = ar_positions[index]; + + auto& line_top = text_lines[index]; + auto& line_bot = text_lines[index + 1]; + + if (index == 0 || ar_delims[index - 1]) + { + is_first_line = true; + curr_position = position; + } + else + { + is_first_line = false; + curr_position.left &= position.left; + curr_position.center &= position.center; + curr_position.right &= position.right; + } + + // первая строка может быть с отступом + if (is_first_line) + { + // если больше трех линий - проверим третью + if (index < ar_positions.size() - 2) + { + if (!ar_delims[index] && !ar_delims[index + 1] && ar_positions[index + 1].left) + ar_indents[index] = true; + else if (!ar_delims[index] && ar_delims[index + 1]) + ar_indents[index] = true; + } + else + ar_indents[index] = true; + } + if (ar_indents[index]) + curr_position.left = true; + + bool is_unknown = !(curr_position.left || curr_position.right || curr_position.center); + bool is_enum = false; + if (is_unknown) + { + // bullet paragraphs + if (!ar_delims[index]) + { + double left_no_enum = line_top->GetLeftNoEnum(); + is_enum = left_no_enum != line_top->m_dLeft && fabs(left_no_enum - line_bot->m_dLeft) < c_dERROR_OF_PARAGRAPH_BORDERS_MM; + } + if (!is_enum) + ar_delims[index] = true; + } + } + + // gap check + // + // bla-bla-bla + // text bla-bla-bla-bla + // + // bla-bla-bla text + // bla-bla-bla-bla + + double curr_max_right = text_lines[0]->m_dRight; + double curr_min_left = text_lines[0]->m_dLeft; + for (size_t index = 0; index < ar_positions.size() - 1; ++index) + { + Position position = ar_positions[index]; + auto& line_top = text_lines[index]; + auto& line_bot = text_lines[index + 1]; + + if (ar_delims[index]) + { + curr_max_right = line_bot->m_dRight; + curr_min_left = line_bot->m_dLeft; + continue; + } + + cont_ptr_t cont = line_bot->m_arConts[0]; + double line_with_first_right = line_top->m_dRight + line_bot->m_dFirstWordWidth; + double line_with_first_left = line_top->m_dLeft - line_bot->m_dFirstWordWidth; + + curr_max_right = std::max(curr_max_right, line_bot->m_dRight); + curr_min_left = std::min(curr_min_left, line_bot->m_dLeft); + + double diff = 0; + + if (position.right) + diff = line_with_first_left - curr_min_left; + else if (position.left || ar_indents[index]) + diff = curr_max_right - line_with_first_right; + else if (position.center) + continue; + + if (diff <= 0) + continue; + else + { + ar_delims[index] = true; + curr_max_right = line_bot->m_dRight; + curr_min_left = line_bot->m_dLeft; + } + } + + // first symbol delim check (bullets etc...) + for (size_t index = 0; index < text_lines.size() - 1; ++index) + { + const auto& first_sym = text_lines[index + 1]->m_arConts.front()->GetText().at(0); + if (CContText::IsUnicodeBullet(first_sym)) + ar_delims[index] = true; + } + + // если между линий шейп - делим + for (size_t index = 0; index < ar_positions.size() - 1; ++index) + { + if (IsHorizontalLineBetween(text_lines[index], text_lines[index + 1])) + ar_delims[index] = true; + } + + // на основе ar_delims разбиваем на параграфы + for (size_t index = 0; index < ar_delims.size(); ++index) + { + add_line(paragraph, text_lines[index]); + if (ar_delims[index] || index == ar_delims.size() - 1) + add_paragraph(paragraph); + } + }; + + // 1 строчка в параграфе + if (m_eTextAssociationType == TextAssociationType::tatPlainLine || + m_eTextAssociationType == TextAssociationType::tatShapeLine) + { + auto paragraph = std::make_shared(); + for (auto& curr_line : m_arTextLines) + { + add_line(paragraph, curr_line); + add_paragraph(paragraph); + } + } + + else if (m_eTextAssociationType == TextAssociationType::tatPlainParagraph || + m_eTextAssociationType == TextAssociationType::tatParagraphToShape) + { + for (auto& g : line_groups) + build_paragraphs(g); + } + + std::sort(ar_paragraphs.begin(), ar_paragraphs.end(), [] (const paragraph_ptr_t& a, const paragraph_ptr_t& b) { + return a->m_dBaselinePos < b->m_dBaselinePos; + }); + + return ar_paragraphs; + } + + std::vector CPage::BuildTables() + { + auto cells = BuildCells(); + auto rows = BuildRows(cells); + std::vector tables; + + table_ptr_t curr_table = nullptr; + for (const auto& row : rows) + { + if (!curr_table) + { + curr_table = std::make_shared(); + } + else if (fabs(curr_table->m_dBaselinePos - row->m_dTop) > c_dGRAPHICS_ERROR_MM) + { + tables.push_back(std::move(curr_table)); + curr_table = std::make_shared(); + } + curr_table->AddRow(row); + } + if (!curr_table->IsEmpty()) + tables.push_back(std::move(curr_table)); + + return tables; + } + std::vector CPage::BuildCells() + { + struct Crossing + { + Point p {}; + std::vector lines {}; + Crossing(const Point& _p, const std::vector& _lines) + { + p = _p; + lines = _lines; + } + }; + std::vector crossings; + auto find_crossing = [&crossings] (const Point& p) -> Crossing* { + for (auto& crossing : crossings) + { + if (fabs(crossing.p.x - p.x) < c_dGRAPHICS_ERROR_MM && + fabs(crossing.p.y - p.y) < c_dGRAPHICS_ERROR_MM) + return &crossing; + } + return nullptr; + }; + + for (const auto& shape : m_arShapes) + { + if (!shape) + continue; + + Point prev {}; + for (const auto& command : shape->m_oVector.GetData()) + { + if (!command.points.empty()) + { + if (command.type == CVectorGraphics::ePathCommandType::pctLine) + { + const auto& curr = command.points.back(); + auto prev_crossing = find_crossing(prev); + auto curr_crossing = find_crossing(curr); + + // add empty vector if no exists + if (!prev_crossing) + crossings.push_back({prev, {curr}}); + else + prev_crossing->lines.push_back(curr); + + if (!curr_crossing) + crossings.push_back({curr, {prev}}); + else + curr_crossing->lines.push_back(prev); + + prev = curr; + } + prev = command.points.back(); + } + } + } + + // sorting guarantee creating cell once (by taking second cross j > i) + std::sort(crossings.begin(), crossings.end(), [] (const Crossing& c1, const Crossing& c2) { + if (fabs(c1.p.y - c2.p.y) < c_dGRAPHICS_ERROR_MM) + return c1.p.x < c2.p.x; + return c1.p.y < c2.p.y; + }); + + std::vector cells; + for (size_t i = 0; i < crossings.size(); ++i) + { + for (size_t j = i + 1; j < crossings.size(); ++j) + { + const auto& first = crossings.at(i); + const auto& second = crossings.at(j); + + // first should be top left corner + // and second right bot (not the same line ofc) + if (fabs(first.p.x - second.p.x) < c_dGRAPHICS_ERROR_MM || + first.p.x > second.p.x || + fabs(first.p.y - second.p.y) < c_dGRAPHICS_ERROR_MM || + first.p.y > second.p.y) + continue; + + // 2 points should be the same + size_t equals = 0; + for (const auto& fl : first.lines) + for (const auto& sl : second.lines) + if (fabs(fl.x - sl.x) < c_dGRAPHICS_ERROR_MM && fabs(fl.y - sl.y) < c_dGRAPHICS_ERROR_MM) + ++equals; + + if (equals == 2) + { + auto cell = std::make_shared(); + cell->m_dLeft = first.p.x; + cell->m_dRight = second.p.x; + cell->m_dTop = first.p.y; + cell->m_dBaselinePos = second.p.y; + cell->m_dWidth = cell->m_dRight - cell->m_dLeft; + cell->m_dHeight = cell->m_dBaselinePos - cell->m_dTop; + cells.push_back(cell); + break; + } + } + } + + // sets paragraphs into cells + for (auto& cell : cells) + for (auto& paragraph : m_arParagraphs) + { + if (!paragraph) + continue; + + bool top = fabs(cell->m_dTop - paragraph->m_dTop) < 2 * c_dGRAPHICS_ERROR_MM || paragraph->m_dTop > cell->m_dTop; + bool bot = fabs(cell->m_dBaselinePos - paragraph->m_dBaselinePos) < c_dGRAPHICS_ERROR_MM || paragraph->m_dBaselinePos < cell->m_dBaselinePos; + bool left = fabs(cell->m_dLeft - paragraph->m_dLeft) < c_dGRAPHICS_ERROR_MM || paragraph->m_dLeft > cell->m_dLeft; + bool right = fabs(cell->m_dRight - paragraph->m_dRight) < c_dGRAPHICS_ERROR_MM || paragraph->m_dRight < cell->m_dRight; + if (top && bot && left && right) + { + cell->AddParagraph(paragraph); + paragraph = nullptr; + } + } + auto right = MoveNullptr(m_arParagraphs.begin(), m_arParagraphs.end()); + m_arParagraphs.erase(right, m_arParagraphs.end()); + std::sort(m_arParagraphs.begin(), m_arParagraphs.end(), [] (const paragraph_ptr_t& p1, const paragraph_ptr_t& p2) { + return p1->m_dBaselinePos < p2->m_dBaselinePos; + }); + return cells; + } + std::vector CPage::BuildRows(std::vector& arCells) + { + std::sort(arCells.begin(), arCells.end(), [] (const CTable::cell_ptr_t c1, const CTable::cell_ptr_t& c2) { + if (fabs(c1->m_dBaselinePos - c2->m_dBaselinePos) < c_dGRAPHICS_ERROR_MM) + return c1->m_dLeft < c2->m_dLeft; + return c1->m_dBaselinePos < c2->m_dBaselinePos; + }); + + std::vector rows; + CTable::row_ptr_t curr_row = nullptr; + for (auto& cell : arCells) + { + if (!curr_row) + { + curr_row = std::make_shared(); + } + else if (fabs(curr_row->m_dBaselinePos - cell->m_dBaselinePos) > c_dGRAPHICS_ERROR_MM) + { + rows.push_back(std::move(curr_row)); + curr_row = std::make_shared(); + } + curr_row->AddCell(cell); + } + if (!curr_row->IsEmpty()) + rows.push_back(std::move(curr_row)); + + return rows; + } + + CPage::shape_ptr_t CPage::CreateSingleLineShape(line_ptr_t& pLine) + { + auto pParagraph = std::make_shared(); + + pParagraph->m_arLines.push_back(pLine); + pParagraph->m_dLeft = pLine->m_dLeft; + pParagraph->m_dTop = pLine->m_dTop; + pParagraph->m_dBaselinePos = pLine->m_dBaselinePos; + pParagraph->m_dWidth = pLine->m_dWidth + c_dERROR_OF_PARAGRAPH_BORDERS_MM; + pParagraph->m_dHeight = pLine->m_dHeight; + pParagraph->m_dRight = pLine->m_dRight; + pParagraph->m_dLineHeight = pParagraph->m_dHeight; + + if (pLine->m_pDominantShape) + { + pParagraph->m_bIsShadingPresent = true; + pParagraph->m_lColorOfShadingFill = pLine->m_pDominantShape->m_oBrush.Color1; + pParagraph->RemoveHighlightColor(); + } + + auto pShape = std::make_shared(); + pShape->m_arOutputObjects.push_back(pParagraph); + pShape->m_eType = CShape::eShapeType::stTextBox; + + pShape->m_dLeft = pParagraph->m_dLeft; + pShape->m_dTop = pParagraph->m_dTop; + pShape->m_dBaselinePos = pParagraph->m_dBaselinePos; + pShape->m_dWidth = pParagraph->m_dWidth; + pShape->m_dHeight = pParagraph->m_dHeight; + pShape->m_dRight = pParagraph->m_dRight; + pShape->m_bIsBehindDoc = false; + + return pShape; + } + + CPage::shape_ptr_t CPage::CreateSingleParagraphShape(paragraph_ptr_t& pParagraph) + { + auto pShape = std::make_shared(); + + pShape->m_dLeft = pParagraph->m_dLeft; + pShape->m_dTop = pParagraph->m_dTop; + pShape->m_dRight = pParagraph->m_dRight; + pShape->m_dBaselinePos = pParagraph->m_dBaselinePos; + pShape->m_dHeight = pParagraph->m_dHeight; + pShape->m_dWidth = pParagraph->m_dWidth; + + if (pParagraph->m_bIsNeedFirstLineIndent && pParagraph->m_dFirstLine < 0) + pParagraph->m_dLeftBorder = -pParagraph->m_dFirstLine; + else + pParagraph->m_dLeftBorder = 0; + + pParagraph->m_dRightBorder = 0; + + // first correction fix + if (pParagraph->m_dSpaceBefore > 0) pParagraph->m_dSpaceBefore = 0; + + pParagraph->m_dSpaceAfter = 0; + + pShape->m_arOutputObjects.push_back(pParagraph); + pShape->m_eType = CShape::eShapeType::stTextBox; + pShape->m_bIsBehindDoc = false; + + return pShape; + } + + void CPage::WriteSectionToFile(bool bLastPage, NSStringUtils::CStringBuilder& oWriter) const noexcept + { + // section + int lWidthDx = (int)(m_dWidth * c_dMMToDx); + int lHeightDx = (int)(m_dHeight * c_dMMToDx); + + if (!bLastPage) + oWriter.WriteString(L""); + else + oWriter.WriteString(L""); + + oWriter.WriteString(L"= lHeightDx) ? oWriter.WriteString(L"landscape") : oWriter.WriteString(L"portrait"); + oWriter.WriteString(L"\"/>"); + + if (!bLastPage) + oWriter.WriteString(L""); + else + oWriter.WriteString(L""); + } } diff --git a/DocxRenderer/src/logic/Page.h b/DocxRenderer/src/logic/Page.h index 98cb0d94dbc..e17e9fcb191 100644 --- a/DocxRenderer/src/logic/Page.h +++ b/DocxRenderer/src/logic/Page.h @@ -1,128 +1,212 @@ #pragma once -#include "../DesktopEditor/graphics/pro/Graphics.h" -#include "elements/OldShape.h" + #include "elements/Paragraph.h" +#include "elements/Table.h" #include "elements/Shape.h" -#include "managers/StyleManager.h" +#include "managers/ImageManager.h" +#include "managers/FontStyleManager.h" +#include "managers/ParagraphStyleManager.h" +#include "../../convert_params.h" namespace NSDocxRenderer { - class CPage - { - public: - NSStructures::CFont* m_pFont {nullptr}; - NSStructures::CPen* m_pPen {nullptr}; - NSStructures::CBrush* m_pBrush {nullptr}; - NSStructures::CShadow* m_pShadow {nullptr}; - NSStructures::CEdgeText* m_pEdgeText {nullptr}; - - Aggplus::CMatrix* m_pTransform {nullptr}; - Aggplus::CGraphicsPathSimpleConverter* m_pSimpleGraphicsConverter {nullptr}; - - CStyleManager* m_pStyleManager {nullptr}; - - CVectorGraphics m_oVector; - - double m_dWidth {0.0}; - double m_dHeight {0.0}; - - LONG m_lCurrentCommand {0}; - - std::vector m_arImages; - std::vector m_arSymbol ; - std::vector m_arTextLine; - std::vector m_arShapes; - std::vector m_arParagraphs; - - CTextLine* m_pCurrentLine {nullptr}; - - CFontManager m_oFontManager; - CFontManagerLight m_oFontManagerLight; - - TextAssociationType m_eTextAssociationType {tatPlainLine}; - - bool m_bIsDeleteTextClipPage {true}; - - double m_dLastTextX {-1}; - double m_dLastTextY {-1}; - double m_dLastTextX_block {-1}; - - public: - CPage(NSFonts::IApplicationFonts* pFonts); - ~CPage(); - void Init(NSStructures::CFont* pFont, NSStructures::CPen* pPen, NSStructures::CBrush* pBrush, - NSStructures::CShadow* pShadow, NSStructures::CEdgeText* pEdge, Aggplus::CMatrix* pMatrix, - Aggplus::CGraphicsPathSimpleConverter* pSimple, CStyleManager* pStyleManager); - - void Clear(); - void ClearImages(); - void ClearTextData(); - void ClearTextLines(); - void ClearShapes(); - void ClearParagraphs(); - - void SelectCurrentLine(const CContText* pCont); - //удаляем то, что выходит за границы страницы - void DeleteTextClipPage(); - - // image commands - //набивается содержимым вектор m_arImages - void WriteImage(const std::shared_ptr pInfo, double& fX, double& fY, double& fWidth, double& fHeight); - - // path commands - void MoveTo(double& dX, double& dY); - void LineTo(double& dX, double& dY); - void CurveTo(double& x1, double& y1, double& x2, double& y2, double& x3, double& y3); - void Start(); - void End(); - void Close(); - //набивается содержимым вектор m_arShapes - void DrawPath(LONG lType, const std::shared_ptr pInfo); - - //набивается содержимым вектор m_arTextData - void CollectTextData(const PUINT pUnicodes, const PUINT pGids, const UINT& nCount, - const double& fX, const double& fY, const double& fWidth, const double& fHeight, - const double& fBaseLineOffset, const bool& bIsPDFAnalyzer); - - void AnalyzeCollectedShapes(); - void DetermineLinesType(); - - //Собранные для текущей страницы данные нужно проанализировать и сгруппировать, лишнее удалить - void AnalyzeCollectedSymbols(); - void DetermineStrikeoutsUnderlinesHighlights(); - bool IsLineCrossingText(const CShape* pGraphicItem, CContText* pCont, const eHorizontalCrossingType& eHType); - bool IsLineBelowText(const CShape* pGraphicItem, CContText* pCont, const eHorizontalCrossingType& eHType); - bool IsItHighlightingBackground(CShape* pGraphicItem, CContText* pCont, const eHorizontalCrossingType& eHType); - - //набивается содержимым вектор m_arTextLine - void AnalyzeLines(); - void BuildLines(); - void CollectDublicateLines(const CContText *pCont); - void MergeLinesByVertAlignType(); - void DetermineDominantGraphics(); - - void BuildByType(); - void BuildByTypeBlockChar(); - void BuildByTypeBlockLine(); - void BuildByTypePlainLine(); - void BuildByTypeShapeLine(); - void BuildByTypePlainParagraph(); - - //Объединяем строки, которые находятся на расстроянии не большем dAffinity - void Merge(double dAffinity); - - //конвертим m_arImages, m_arShapes, m_arParagraphs в xml-строку - void ToXml(NSStringUtils::CStringBuilder& oWriter); - - void WriteSectionToFile(bool bLastPage, NSStringUtils::CStringBuilder& oWriter); + class CPage + { + public: + struct CManagers + { + CManagers() = default; + CManagers(const CManagers& other) = default; + ~CManagers() = default; + + CImageManager* pImageManager; + CFontStyleManager* pFontStyleManager; + CParagraphStyleManager* pParagraphStyleManager; + CFontManager* pFontManager; + CFontSelector* pFontSelector; + }; + + double m_dWidth {0.0}; + double m_dHeight{0.0}; + + LONG m_lCurrentCommand{0}; + LONG m_lClipMode {0}; + + TextAssociationType m_eTextAssociationType{TextAssociationType::tatPlainParagraph}; + NSFonts::IApplicationFonts* m_pAppFonts{nullptr}; + NSStructures::CFont m_oFont{}; + NSStructures::CPen m_oPen{}; + NSStructures::CBrush m_oBrush{}; + NSStructures::CShadow m_oShadow{}; + NSStructures::CEdgeText m_oEdgeText{}; + Aggplus::CMatrix m_oTransform{}; + + bool m_bIsDeleteTextClipPage{true}; + bool m_bIsRecalcFontSize {true}; + bool m_bIsGradient {false}; + bool m_bUseDefaultFont {false}; + bool m_bWriteStyleRaw {false}; + bool m_bIsBuildTables {false}; + + CPage(NSFonts::IApplicationFonts* pAppFonts, const CManagers& oManagers); + ~CPage(); + + void BeginCommand(DWORD lType); + void EndCommand(DWORD lType); + + void Clear(); + + void WriteImage(const std::shared_ptr pInfo, double& fX, double& fY, double& fWidth, double& fHeight); + + void PathMoveTo(double& dX, double& dY); + void PathLineTo(double& dX, double& dY); + void PathCurveTo(double& dX1, double& dY1, double& dX2, double& dY2, double& dX3, double& dY3); + void PathStart(); + void PathEnd(); + void PathClose(); + void DrawPath(LONG lType, const std::shared_ptr pInfo); + + void AddText( + const PUINT pUnicodes, + const PUINT pGids, + const UINT& nCount, + const double& fX, + const double& fY, + const double& fWidth, + const double& fHeight, + const double& fBaseLineOffset); + + void Analyze(); + void Record(NSStringUtils::CStringBuilder& oWriter, bool bIsLastPage); + + std::vector GetXmlShapes(); + std::vector GetXmlShapesPptx(); + void AddCompleteXml(const std::wstring oXml); + + private: + using shape_ptr_t = std::shared_ptr; + using cont_ptr_t = std::shared_ptr; + using line_ptr_t = std::shared_ptr; + using item_ptr_t = std::shared_ptr; + using paragraph_ptr_t = std::shared_ptr; + using table_ptr_t = std::shared_ptr; + + // returns std::vector of conts with diac. symbols and remove it from m_arConts + std::vector MoveDiacriticalSymbols(); + + // returns std::vector of text lines builded from m_arConts + std::vector BuildTextLines(); + + // returns std::vector of paragraphs builded from m_arTextLines + std::vector BuildParagraphs(); + + // returns std::vector of tables builded from shapes and paragraphes + std::vector BuildTables(); + + // returns std::vector of cells for tables + std::vector BuildCells(); + + // returns std::vector of rows for tables + std::vector BuildRows(std::vector& arCells); + + // returns std::vector of base items builded from m_arParagraphs + std::vector BuildOutputObjects(); + + // analyze shapes (set lines type) + void AnalyzeShapes(); + + // analyze type of lines (double, wave, etc.) + void AnalyzeLinesType(); + + // analyze m_arTextLines and add effects, adds diac, super-sub scripts etc. + void AnalyzeTextLines(); + + // analyze drop caps (creates shapes) + void AnalyzeDropCaps(); + + // analyze conts in text lines + void AnalyzeConts(); + + // strikeouts, underlines, highlights, outline + void AnalyzeEffects(); + + // adds diacritical symbols in conts + void AddDiacriticalSymbols(); + + // super-sub scripts line merge + void MergeTextLinesByVatType(); + + // remove out of bounds text lines + void DeleteTextClipPage(); + + // merging conts in text lines + void MergeConts(); + + // get horizontal and vertical lines from shapes + void GetHorVerLines(); + + // set dominant shapes + void DetermineDominantGraphics(); + + // split lines by graphics + void SplitLines(); + + // creates shapes from overlapping text lines + void AnalyzeOverlapLines(); + + // calc selected sizes of conts + void CalcSelected(); + + // merge shapes with each other + void MergeShapes(); + + // calc true shapes rotation for ooxml format + void CalcShapesRotation(); + + // for drawingml is no tag behind-doc - so we need to reorder shapes + void ReorderShapesForPptx(); + + // get lines by groups by X + std::vector> GetLinesByGroups(); + + bool IsLineCrossingText(shape_ptr_t pShape, cont_ptr_t pCont) const noexcept; + bool IsLineBelowText(shape_ptr_t pShape, cont_ptr_t pCont) const noexcept; + bool IsHighlight(shape_ptr_t pShape, cont_ptr_t pCont) const noexcept; + bool IsOutline(shape_ptr_t pShape, cont_ptr_t pCont) const noexcept; + + bool IsVerticalLineBetween(item_ptr_t pFirst, item_ptr_t pSecond) const noexcept; + bool IsHorizontalLineBetween(item_ptr_t pFirst, item_ptr_t pSecond) const noexcept; + + bool IsVerticalLineBetween(line_ptr_t pFirst, line_ptr_t pSecond) const noexcept; + bool IsHorizontalLineBetween(line_ptr_t pFirst, line_ptr_t pSecond) const noexcept; + + bool IsVerticalLineTrough(item_ptr_t pFirst) const noexcept; + bool IsHorizontalLineTrough(item_ptr_t pFirst) const noexcept; + + void ToXml(NSStringUtils::CStringBuilder& oWriter) const noexcept; + void WriteSectionToFile(bool bLastPage, NSStringUtils::CStringBuilder& oWriter) const noexcept; + + static shape_ptr_t CreateSingleLineShape(line_ptr_t& pLine); + static shape_ptr_t CreateSingleParagraphShape(paragraph_ptr_t& pParagraph); + + CManagers m_oManagers; + + CVectorGraphics m_oCurrVectorGraphics; + CVectorGraphics m_oClipVectorGraphics; + + CContTextBuilder m_oContBuilder; + CHorVerLinesCollector m_oHorVerLinesCollector; + + std::vector m_arConts; + std::vector m_arTextLines; + std::vector m_arDiacriticalSymbols; + std::vector m_arShapes; + std::vector m_arParagraphs; + std::vector m_arTables; + + std::vector m_arOutputObjects; + std::vector m_arCompleteObjectsXml; - void CreateSingleLineParagraph(CTextLine *pLine, const double *pRight, const double *pBeforeSpacing); - void CreateSingleLineOldShape(CTextLine *pLine); - void CreateSingleLineShape(CTextLine *pLine); - - bool IsShadingPresent(const CTextLine* pLine1, const CTextLine* pLine2); - - private: - CTextLine* GetNextTextLine(size_t& nCurrentIndex, size_t* pIndexForCheking = nullptr); - }; + size_t m_nShapeOrder = 0; + }; } diff --git a/DocxRenderer/src/logic/elements/BaseItem.cpp b/DocxRenderer/src/logic/elements/BaseItem.cpp index 333d9d9932e..48406eb64fe 100644 --- a/DocxRenderer/src/logic/elements/BaseItem.cpp +++ b/DocxRenderer/src/logic/elements/BaseItem.cpp @@ -1,126 +1,177 @@ #include "BaseItem.h" -#include "../../resources/Constants.h" + #include +#include "../../resources/Constants.h" + namespace NSDocxRenderer { - CBaseItem& CBaseItem::operator=(const CBaseItem& oSrc) - { - if (this == &oSrc) - { - return *this; - } + CBaseItem& CBaseItem::operator=(const CBaseItem& oSrc) + { + if (this == &oSrc) + return *this; + + m_dLeft = oSrc.m_dLeft; + m_dTop = oSrc.m_dTop; + m_dWidth = oSrc.m_dWidth; + m_dHeight = oSrc.m_dHeight; + m_dBaselinePos = oSrc.m_dBaselinePos; + m_dRight = oSrc.m_dRight; + + return *this; + } + bool CBaseItem::operator==(const CBaseItem& oSrc) + { + if (this == &oSrc) + return true; + + return m_dLeft == oSrc.m_dLeft && + m_dTop == oSrc.m_dTop && + m_dWidth == oSrc.m_dWidth && + m_dHeight == oSrc.m_dHeight && + m_dBaselinePos == oSrc.m_dBaselinePos && + m_dRight == oSrc.m_dRight; + } + + eVerticalCrossingType CBaseItem::GetVerticalCrossingType(const CBaseItem* oSrc) const + { + if (m_dTop > oSrc->m_dTop && m_dBaselinePos < oSrc->m_dBaselinePos) + { + return eVerticalCrossingType::vctCurrentInsideNext; + } + else if (m_dTop < oSrc->m_dTop && m_dBaselinePos > oSrc->m_dBaselinePos) + { + return eVerticalCrossingType::vctCurrentOutsideNext; + } + else if (m_dTop < oSrc->m_dTop && m_dBaselinePos < oSrc->m_dBaselinePos && + (m_dBaselinePos >= oSrc->m_dTop || fabs(m_dBaselinePos - oSrc->m_dTop) < c_dTHE_SAME_STRING_Y_PRECISION_MM)) + { + return eVerticalCrossingType::vctCurrentAboveNext; + } + else if (m_dTop > oSrc->m_dTop && m_dBaselinePos > oSrc->m_dBaselinePos && + (m_dTop <= oSrc->m_dBaselinePos || fabs(m_dTop - oSrc->m_dBaselinePos) < c_dTHE_SAME_STRING_Y_PRECISION_MM)) + { + return eVerticalCrossingType::vctCurrentBelowNext; + } + else if (m_dTop == oSrc->m_dTop && m_dBaselinePos == oSrc->m_dBaselinePos && + m_dLeft == oSrc->m_dLeft && m_dRight == oSrc->m_dRight) + { + return eVerticalCrossingType::vctDublicate; + } + else if (fabs(m_dTop - oSrc->m_dTop) < c_dTHE_SAME_STRING_Y_PRECISION_MM && + fabs(m_dBaselinePos - oSrc->m_dBaselinePos) < c_dTHE_SAME_STRING_Y_PRECISION_MM) + { + return eVerticalCrossingType::vctTopAndBottomBordersMatch; + } + else if (fabs(m_dTop - oSrc->m_dTop) < c_dTHE_SAME_STRING_Y_PRECISION_MM) + { + return eVerticalCrossingType::vctTopBorderMatch; + } + else if (fabs(m_dBaselinePos - oSrc->m_dBaselinePos) < c_dTHE_SAME_STRING_Y_PRECISION_MM) + { + return eVerticalCrossingType::vctBottomBorderMatch; + } + else if (m_dBaselinePos < oSrc->m_dTop) + { + return eVerticalCrossingType::vctNoCrossingCurrentAboveNext; + } + else if (m_dTop > oSrc->m_dBaselinePos) + { + return eVerticalCrossingType::vctNoCrossingCurrentBelowNext; + } + else + { + return eVerticalCrossingType::vctUnknown; + } + } + eHorizontalCrossingType CBaseItem::GetHorizontalCrossingType(const CBaseItem* oSrc) const + { + if (m_dLeft > oSrc->m_dLeft && m_dRight < oSrc->m_dRight) + { + return eHorizontalCrossingType::hctCurrentInsideNext; + } + else if (m_dLeft < oSrc->m_dLeft && m_dRight > oSrc->m_dRight) + { + return eHorizontalCrossingType::hctCurrentOutsideNext; + } + else if (m_dLeft < oSrc->m_dLeft && m_dRight < oSrc->m_dRight && + (m_dRight >= oSrc->m_dLeft || fabs(m_dRight - oSrc->m_dLeft) < c_dTHE_SAME_STRING_X_PRECISION_MM)) + { + return eHorizontalCrossingType::hctCurrentLeftOfNext; + } + else if (m_dLeft > oSrc->m_dLeft && m_dRight > oSrc->m_dRight && + (m_dLeft <= oSrc->m_dRight || fabs(m_dLeft - oSrc->m_dRight) < c_dTHE_SAME_STRING_X_PRECISION_MM)) + { + return eHorizontalCrossingType::hctCurrentRightOfNext; + } + else if (m_dLeft == oSrc->m_dLeft && m_dRight == oSrc->m_dRight && + m_dTop == oSrc->m_dTop && m_dBaselinePos == oSrc->m_dBaselinePos) + { + return eHorizontalCrossingType::hctDublicate; + } + else if (fabs(m_dLeft - oSrc->m_dLeft) < c_dTHE_SAME_STRING_X_PRECISION_MM && + fabs(m_dRight - oSrc->m_dRight) < c_dTHE_SAME_STRING_X_PRECISION_MM) + { + return eHorizontalCrossingType::hctLeftAndRightBordersMatch; + } + else if (fabs(m_dLeft - oSrc->m_dLeft) < c_dTHE_SAME_STRING_Y_PRECISION_MM) + { + return eHorizontalCrossingType::hctLeftBorderMatch; + } + else if (fabs(m_dRight - oSrc->m_dRight) < c_dTHE_SAME_STRING_Y_PRECISION_MM) + { + return eHorizontalCrossingType::hctRightBorderMatch; + } + else if (m_dRight < oSrc->m_dLeft) + { + return eHorizontalCrossingType::hctNoCrossingCurrentLeftOfNext; + } + else if (m_dLeft > oSrc->m_dRight) + { + return eHorizontalCrossingType::hctNoCrossingCurrentRightOfNext; + } + else + { + return eHorizontalCrossingType::hctUnknown; + } + } + + bool CBaseItem::AreObjectsNoCrossingByVertically(const CBaseItem* pObj) const noexcept + { + eVerticalCrossingType eVType = GetVerticalCrossingType(pObj); - m_eType = oSrc.m_eType; - m_bIsNotNecessaryToUse = oSrc.m_bIsNotNecessaryToUse; + return (eVType == eVerticalCrossingType::vctNoCrossingCurrentAboveNext || + eVType == eVerticalCrossingType::vctNoCrossingCurrentBelowNext); + } + bool CBaseItem::AreObjectsNoCrossingByHorizontally(const CBaseItem* pObj) const noexcept + { + eHorizontalCrossingType eHType = GetHorizontalCrossingType(pObj); - m_dLeft = oSrc.m_dLeft; - m_dTop = oSrc.m_dTop; - m_dWidth = oSrc.m_dWidth; - m_dHeight = oSrc.m_dHeight; - m_dBaselinePos = oSrc.m_dBaselinePos; - m_dRight = oSrc.m_dRight; + return (eHType == eHorizontalCrossingType::hctNoCrossingCurrentLeftOfNext || + eHType == eHorizontalCrossingType::hctNoCrossingCurrentRightOfNext); + } + bool CBaseItem::IsEqual(double dTop, double dBaselinePos, double dLeft, double dRight) const noexcept + { + return m_dLeft == dLeft && + m_dTop == dTop && + m_dBaselinePos == dBaselinePos && + m_dRight == dRight; + } - return *this; - } + void CBaseItem::RecalcWithNewItem(const CBaseItem* pItem) + { + m_dBaselinePos = std::max(m_dBaselinePos, pItem->m_dBaselinePos); - bool CBaseItem::IsBigger(const CBaseItem* oSrc) - { - return (m_dLeft > oSrc->m_dLeft) ? true : false; - } + if ((pItem->m_dLeft < m_dLeft) || (pItem->m_dLeft > 0 && m_dLeft == 0.0)) + m_dLeft = pItem->m_dLeft; - bool CBaseItem::IsBiggerOrEqual(const CBaseItem* oSrc) - { - return (m_dLeft >= oSrc->m_dLeft) ? true : false; - } + if ((pItem->m_dRight > m_dRight) || (pItem->m_dRight > 0 && m_dRight == 0.0)) + m_dRight = pItem->m_dRight; - eVerticalCrossingType CBaseItem::GetVerticalCrossingType(const CBaseItem* oSrc) - { - if (m_dTop > oSrc->m_dTop && m_dBaselinePos < oSrc->m_dBaselinePos) - { - return eVerticalCrossingType::vctCurrentInsideNext; - } - else if (m_dTop < oSrc->m_dTop && m_dBaselinePos > oSrc->m_dBaselinePos) - { - return eVerticalCrossingType::vctCurrentOutsideNext; - } - else if (m_dTop < oSrc->m_dTop && m_dBaselinePos < oSrc->m_dBaselinePos && m_dBaselinePos > oSrc->m_dTop) - { - return eVerticalCrossingType::vctCurrentAboveNext; - } - else if (m_dTop > oSrc->m_dTop && m_dBaselinePos > oSrc->m_dBaselinePos && m_dTop < oSrc->m_dBaselinePos) - { - return eVerticalCrossingType::vctCurrentBelowNext; - } - else if (m_dTop == oSrc->m_dTop && m_dBaselinePos == oSrc->m_dBaselinePos && - m_dLeft == oSrc->m_dLeft && m_dRight == oSrc->m_dRight) - { - return eVerticalCrossingType::vctDublicate; - } - else if (fabs(m_dTop - oSrc->m_dTop) < c_dTHE_SAME_STRING_Y_PRECISION_MM) - { - return eVerticalCrossingType::vctTopBordersMatch; - } - else if (fabs(m_dBaselinePos - oSrc->m_dBaselinePos) < c_dTHE_SAME_STRING_Y_PRECISION_MM) - { - return eVerticalCrossingType::vctBottomBordersMatch; - } - else if (m_dBaselinePos < oSrc->m_dTop) - { - return eVerticalCrossingType::vctNoCrossingCurrentAboveNext; - } - else if (m_dTop > oSrc->m_dBaselinePos) - { - return eVerticalCrossingType::vctNoCrossingCurrentBelowNext; - } - else - { - return eVerticalCrossingType::vctUnknown; - } - } + if (m_dTop > pItem->m_dTop || m_dTop == 0.0) + m_dTop = pItem->m_dTop; - eHorizontalCrossingType CBaseItem::GetHorizontalCrossingType(const CBaseItem* oSrc) - { - if (m_dLeft > oSrc->m_dLeft && m_dRight < oSrc->m_dRight) - { - return eHorizontalCrossingType::hctCurrentInsideNext; - } - else if (m_dLeft < oSrc->m_dLeft && m_dRight > oSrc->m_dRight) - { - return eHorizontalCrossingType::hctCurrentOutsideNext; - } - else if (m_dLeft < oSrc->m_dLeft && m_dRight < oSrc->m_dRight && m_dRight > oSrc->m_dLeft) - { - return eHorizontalCrossingType::hctCurrentLeftOfNext; - } - else if (m_dLeft > oSrc->m_dLeft && m_dRight > oSrc->m_dRight && m_dLeft < oSrc->m_dRight) - { - return eHorizontalCrossingType::hctCurrentRightOfNext; - } - else if (m_dLeft == oSrc->m_dLeft && m_dRight == oSrc->m_dRight && - m_dTop == oSrc->m_dTop && m_dBaselinePos == oSrc->m_dBaselinePos) - { - return eHorizontalCrossingType::hctDublicate; - } - else if (fabs(m_dLeft - oSrc->m_dLeft) < c_dTHE_SAME_STRING_Y_PRECISION_MM) - { - return eHorizontalCrossingType::hctLeftBordersMatch; - } - else if (fabs(m_dRight - oSrc->m_dRight) < c_dTHE_SAME_STRING_Y_PRECISION_MM) - { - return eHorizontalCrossingType::hctRightBordersMatch; - } - else if (m_dRight < oSrc->m_dLeft) - { - return eHorizontalCrossingType::hctNoCrossingCurrentLeftOfNext; - } - else if (m_dLeft > oSrc->m_dRight) - { - return eHorizontalCrossingType::hctNoCrossingCurrentRightOfNext; - } - else - { - return eHorizontalCrossingType::hctUnknown; - } - } + m_dWidth = m_dRight - m_dLeft; + m_dHeight = m_dBaselinePos - m_dTop; + } } diff --git a/DocxRenderer/src/logic/elements/BaseItem.h b/DocxRenderer/src/logic/elements/BaseItem.h index 23525509115..c2818ca994d 100644 --- a/DocxRenderer/src/logic/elements/BaseItem.h +++ b/DocxRenderer/src/logic/elements/BaseItem.h @@ -1,91 +1,68 @@ #pragma once -#include "../DesktopEditor/common/StringBuilder.h" + +#include "../../../../DesktopEditor/common/StringBuilder.h" namespace NSDocxRenderer { - enum class eVerticalCrossingType - { - vctUnknown, - vctCurrentInsideNext, - vctCurrentOutsideNext, - vctCurrentAboveNext, - vctCurrentBelowNext, - vctDublicate, - vctTopBordersMatch, - vctBottomBordersMatch, - vctNoCrossingCurrentAboveNext, - vctNoCrossingCurrentBelowNext - }; - - enum class eHorizontalCrossingType - { - hctUnknown, - hctCurrentInsideNext, - hctCurrentOutsideNext, - hctCurrentLeftOfNext, - hctCurrentRightOfNext, - hctDublicate, - hctLeftBordersMatch, - hctRightBordersMatch, - hctNoCrossingCurrentLeftOfNext, - hctNoCrossingCurrentRightOfNext - }; - - class CBaseItem - { - public: - enum class ElemType - { - etContText = 0, - etTextLine = 1, - etParagraph = 2, - etImage = 3, - etShape = 4, - etOldShape = 5, - }; - - ElemType m_eType; - - bool m_bIsNotNecessaryToUse {false}; - - //General - double m_dLeft {0.0}; - double m_dTop {0.0}; - double m_dWidth {0.0}; - double m_dHeight {0.0}; - - //Secondary - double m_dBaselinePos {0.0}; - double m_dRight {0.0}; + // взаимное расположение по вертикали со следующим объектом + enum class eVerticalCrossingType + { + vctUnknown, + vctCurrentInsideNext, + vctCurrentOutsideNext, + vctCurrentAboveNext, + vctCurrentBelowNext, + vctDublicate, + vctTopAndBottomBordersMatch, + vctTopBorderMatch, + vctBottomBorderMatch, + vctNoCrossingCurrentAboveNext, + vctNoCrossingCurrentBelowNext + }; - public: - CBaseItem(const ElemType& eType): m_eType(eType) {} - virtual ~CBaseItem() {} + // взаимное расположение по горизонтали со следующим объектом + enum class eHorizontalCrossingType + { + hctUnknown, + hctCurrentInsideNext, + hctCurrentOutsideNext, + hctCurrentLeftOfNext, + hctCurrentRightOfNext, + hctDublicate, + hctLeftAndRightBordersMatch, + hctLeftBorderMatch, + hctRightBorderMatch, + hctNoCrossingCurrentLeftOfNext, + hctNoCrossingCurrentRightOfNext + }; - CBaseItem& operator=(const CBaseItem& oSrc); + class CBaseItem + { + public: + double m_dTop {0.0}; + double m_dBaselinePos {0.0}; + double m_dHeight {0.0}; - friend bool operator == (const CBaseItem& lh, const CBaseItem& rh) - { - return (lh.m_dLeft == rh.m_dLeft) ? true : false; - } + double m_dLeft {0.0}; + double m_dRight {0.0}; + double m_dWidth {0.0}; - friend bool operator < (const CBaseItem& lh, const CBaseItem& rh) - { - return (lh.m_dLeft < rh.m_dLeft) ? true : false; - } + CBaseItem() = default; + virtual ~CBaseItem() = default; - friend bool operator > (const CBaseItem& lh, const CBaseItem& rh) - { - return (lh.m_dLeft > rh.m_dLeft) ? true : false; - } + virtual void Clear() = 0; + virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) const = 0; + virtual void ToXmlPptx(NSStringUtils::CStringBuilder& oWriter) const = 0; - virtual bool IsBigger(const CBaseItem* oSrc); - virtual bool IsBiggerOrEqual(const CBaseItem* oSrc); + virtual eVerticalCrossingType GetVerticalCrossingType(const CBaseItem* oSrc) const; + virtual eHorizontalCrossingType GetHorizontalCrossingType(const CBaseItem* oSrc) const; + virtual void RecalcWithNewItem(const CBaseItem* pObj); - virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) = 0; - virtual void Clear() = 0; + bool AreObjectsNoCrossingByVertically(const CBaseItem* pObj) const noexcept; + bool AreObjectsNoCrossingByHorizontally(const CBaseItem* pObj) const noexcept; + bool IsEqual(double dTop, double dBaselinePos, double dLeft, double dRight) const noexcept; - eVerticalCrossingType GetVerticalCrossingType(const CBaseItem* oSrc); - eHorizontalCrossingType GetHorizontalCrossingType(const CBaseItem* oSrc); - }; + CBaseItem& operator=(const CBaseItem& oSrc); + bool operator==(const CBaseItem& oSrc); + }; } diff --git a/DocxRenderer/src/logic/elements/ContText.cpp b/DocxRenderer/src/logic/elements/ContText.cpp index b7bfa8cd32d..566d934f49e 100644 --- a/DocxRenderer/src/logic/elements/ContText.cpp +++ b/DocxRenderer/src/logic/elements/ContText.cpp @@ -1,465 +1,1014 @@ #include "ContText.h" + #include "../../resources/ColorTable.h" #include "../../resources/SingletonTemplate.h" #include "../../resources/utils.h" namespace NSDocxRenderer { - CContText::CContText(CFontManagerLight* pManagerLight, CStyleManager* pStyleManager): - CBaseItem(ElemType::etContText), m_pManagerLight(pManagerLight), m_pStyleManager(pStyleManager) - { - } - - CContText::~CContText() - { - Clear(); - } - - void CContText::Clear() - { - m_pFontStyle = nullptr; - } - - double CContText::GetIntersect(const CContText* pCont) const - { - double d1 = std::max(m_dLeft, pCont->m_dLeft); - double d2 = std::min(m_dLeft + m_dWidth, pCont->m_dLeft + pCont->m_dWidth); - - if (d2 > d1) - return d2 - d1; - return 0; - } - - void CContText::ToXml(NSStringUtils::CStringBuilder& oWriter) - { - if (m_bIsNotNecessaryToUse) - { - return; - } - - oWriter.WriteString(L""); - oWriter.WriteString(L""); - - oWriter.WriteString(L"GetStyleId()); - oWriter.WriteString(L"\"/>"); - - LONG lCalculatedSpacing = 0; - - if (!m_pFontStyle->m_strPickFontName.empty() && !m_oText.empty()) - { - if (m_eVertAlignType != eVertAlignType::vatSubscript && - m_eVertAlignType != eVertAlignType::vatSuperscript) - { - // нужно перемерять... - m_pManagerLight->LoadFont(m_pFontStyle->m_strPickFontName, m_pFontStyle->m_lPickFontStyle, m_pFontStyle->m_oFont.Size, false); - double dWidth = m_pManagerLight->MeasureStringWidth(m_oText.ToStdWString()); - - double dSpacing = (m_dWidth - dWidth) / (m_oText.length()); - dSpacing *= c_dMMToDx; - - lCalculatedSpacing = static_cast(dSpacing); - } - } - - //note принудительно уменьшаем spacing чтобы текстовые линии не выходили за правую границу - //note 1 -> 0.5pt - lCalculatedSpacing -= 1; - - if (lCalculatedSpacing != 0) - { - oWriter.WriteString(L""); - } - - if (m_bIsEmbossPresent) - { - oWriter.WriteString(L""); - } - else if (m_bIsEngravePresent) - { - oWriter.WriteString(L""); - } - else - { - if (m_bIsOutlinePresent) - { - oWriter.WriteString(L""); - } - if (m_bIsShadowPresent) - { - oWriter.WriteString(L""); - } - } - - if (m_bIsStrikeoutPresent) - { - if (m_bIsDoubleStrikeout) - { - oWriter.WriteString(L""); - } - else - { - oWriter.WriteString(L""); - } - } - - if (m_bIsUnderlinePresent) - { - oWriter.WriteString(L""); - } - - if (m_bIsHighlightPresent) - { - //note В (); - if (colorTable.IsStandardColor(m_lHighlightColor)) - { - oWriter.WriteString(L""); - } - - if (m_eVertAlignType == eVertAlignType::vatSubscript) - { - oWriter.WriteString(L""); - } - else if (m_eVertAlignType == eVertAlignType::vatSuperscript) - { - oWriter.WriteString(L""); - } - - oWriter.WriteString(L""); - - oWriter.WriteString(L""); - oWriter.WriteEncodeXmlString(m_oText.ToStdWString()); - oWriter.WriteString(L""); - - oWriter.WriteString(L""); - } - - void CContText::AddWideSpaceToXml(double dSpacingMM, - NSStringUtils::CStringBuilder& oWriter, - bool bIsNeedSaveFormat) - { - oWriter.WriteString(L""); - - oWriter.WriteString(L"GetStyleId()); - oWriter.WriteString(L"\"/>"); - - double dSpaceMMSize = m_dSpaceWidthMM; - if (!m_pFontStyle->m_strPickFontName.empty()) - { - dSpaceMMSize = m_pManagerLight->GetSpaceWidth(); - } - - LONG lCalculatedSpacing = static_cast((dSpacingMM - dSpaceMMSize) * c_dMMToDx); - //note принудительно уменьшаем spacing чтобы текстовые линии не выходили за правую границу - lCalculatedSpacing -= 1; - if (lCalculatedSpacing != 0) - { - oWriter.WriteString(L""); - } - - if (m_bIsEmbossPresent && bIsNeedSaveFormat) - { - oWriter.WriteString(L""); - } - else if (m_bIsEngravePresent && bIsNeedSaveFormat) - { - oWriter.WriteString(L""); - } - else - { - if (m_bIsOutlinePresent && bIsNeedSaveFormat) - { - oWriter.WriteString(L""); - } - if (m_bIsShadowPresent && bIsNeedSaveFormat) - { - oWriter.WriteString(L""); - } - } - - if (m_bIsStrikeoutPresent && bIsNeedSaveFormat) - { - if (m_bIsDoubleStrikeout) - { - oWriter.WriteString(L""); - } - else - { - oWriter.WriteString(L""); - } - } - - if (m_bIsUnderlinePresent && bIsNeedSaveFormat) - { - oWriter.WriteString(L""); - } - - if (m_bIsHighlightPresent && bIsNeedSaveFormat) - { - //note В (); - if (colorTable.IsStandardColor(m_lHighlightColor)) - { - oWriter.WriteString(L""); - } - - oWriter.WriteString(L""); - - oWriter.WriteString(L""); - oWriter.WriteString(L" "); - oWriter.WriteString(L""); - - oWriter.WriteString(L""); - } - - bool CContText::IsEqual(const CContText *pCont) - { - bool bIf1 = m_pFontStyle->GetStyleId() == pCont->m_pFontStyle->GetStyleId(); - bool bIf2 = m_bIsStrikeoutPresent == pCont->m_bIsStrikeoutPresent; - bool bIf3 = m_bIsDoubleStrikeout == pCont->m_bIsDoubleStrikeout; - bool bIf4 = m_bIsHighlightPresent == pCont->m_bIsHighlightPresent; - bool bIf5 = m_lHighlightColor == pCont->m_lHighlightColor; - bool bIf6 = m_bIsUnderlinePresent == pCont->m_bIsUnderlinePresent; - bool bIf7 = m_eUnderlineType == pCont->m_eUnderlineType; - bool bIf8 = m_lUnderlineColor == pCont->m_lUnderlineColor; - bool bIf9 = m_bIsShadowPresent == pCont->m_bIsShadowPresent; - bool bIf10 = m_bIsOutlinePresent == pCont->m_bIsOutlinePresent; - bool bIf11 = m_bIsEmbossPresent == pCont->m_bIsEmbossPresent; - bool bIf12 = m_bIsEngravePresent == pCont->m_bIsEngravePresent; - - if (bIf1 && bIf2 && bIf3 && bIf4 && bIf5 && bIf6 && bIf7 && - bIf8 && bIf9 && bIf10 && bIf11 && bIf12) - { - return true; - } - return false; - } - - UINT CContText::GetNumberOfFeatures() - { - UINT ret = 0; - - if (m_pFontStyle->m_oFont.Bold) - { - ret++; - } - if (m_pFontStyle->m_oFont.Italic) - { - ret++; - } - if (m_bIsStrikeoutPresent) - { - ret++; - } - if (m_bIsDoubleStrikeout) - { - ret++; - } - if (m_bIsHighlightPresent) - { - ret++; - } - if (m_bIsUnderlinePresent) - { - ret++; - } - if (m_eVertAlignType != eVertAlignType::vatUnknown) - { - ret++; - } - - return ret; - } - - bool CContText::IsDuplicate(CContText* pCont, eVerticalCrossingType eVType) - { - if (eVType == eVerticalCrossingType::vctDublicate && - m_oText == pCont->m_oText) - { - pCont->m_bIsNotNecessaryToUse = true; - m_iNumDuplicates++; - return true; - } - return false; - } - - bool CContText::IsThereAreFontEffects(CContText* pCont, eVerticalCrossingType eVType, eHorizontalCrossingType eHType) - { - //Условие пересечения по вертикали - bool bIf1 = eVType == eVerticalCrossingType::vctCurrentAboveNext; //текущий cont выше - bool bIf2 = eVType == eVerticalCrossingType::vctCurrentBelowNext; //текущий cont ниже - //Условие пересечения по горизонтали - bool bIf3 = eHType == eHorizontalCrossingType::hctCurrentLeftOfNext; //текущий cont левее - bool bIf4 = eHType == eHorizontalCrossingType::hctCurrentRightOfNext; //текущий cont правее - //Размеры шрифта и текст должны бать одинаковыми - bool bIf5 = m_pFontStyle->m_oFont.Size == pCont->m_pFontStyle->m_oFont.Size; - bool bIf6 = m_oText == pCont->m_oText; - //Цвет тени должен быть серым - bool bIf7 = m_pFontStyle->m_oBrush.Color1 == c_iGreyColor; - bool bIf8 = pCont->m_pFontStyle->m_oBrush.Color1 == c_iGreyColor; - bool bIf9 = m_pFontStyle->m_oBrush.Color1 == c_iBlackColor; - bool bIf10 = pCont->m_pFontStyle->m_oBrush.Color1 == c_iBlackColor; - bool bIf11 = m_pFontStyle->m_oBrush.Color1 == c_iGreyColor2; - bool bIf12 = pCont->m_pFontStyle->m_oBrush.Color1 == c_iGreyColor2; - - //note Каждый символ с Emboss или Engrave разбиваются на 3 символа с разными цветами - //note Логика подобрана для конкретного примера - возможно нужно будет ее обобщить. - if (bIf5 && bIf6) - { - if (m_bIsEmbossPresent && bIf11) - { - if (bIf2 && bIf4) - { - pCont->m_bIsEmbossPresent = true; - m_bIsNotNecessaryToUse = true; - return true; - } - } - - if (m_bIsEngravePresent && bIf9) - { - if (bIf2 && bIf4) - { - pCont->m_bIsEngravePresent = true; - m_bIsNotNecessaryToUse = true; - return true; - } - } - - //Shadow - if (bIf1 && bIf3 && bIf8) - { - m_bIsShadowPresent = true; - pCont->m_bIsNotNecessaryToUse = true; - return true; - } - else if (bIf2 && bIf4 && bIf7) - { - pCont->m_bIsShadowPresent = true; - m_bIsNotNecessaryToUse = true; - return true; - } - - //Emboss - else if (bIf2 && bIf4 && bIf10) - { - m_bIsEmbossPresent = true; - pCont->m_bIsNotNecessaryToUse = true; - return true; - } - //Engrave - else if (bIf2 && bIf4 && bIf12) - { - m_bIsEngravePresent = true; - pCont->m_bIsNotNecessaryToUse = true; - return true; - } - } - return false; - } - - bool CContText::IsVertAlignTypeBetweenConts(CContText* pCont, eVerticalCrossingType eVType, eHorizontalCrossingType eHType) - { - //Условие пересечения по вертикали - bool bIf1 = eVType == eVerticalCrossingType::vctCurrentAboveNext || - eVType == eVerticalCrossingType::vctCurrentInsideNext; - bool bIf2 = eVType == eVerticalCrossingType::vctCurrentBelowNext; - //Условие пересечения по горизонтали - bool bIf3 = (eHType == eHorizontalCrossingType::hctNoCrossingCurrentLeftOfNext || - eHType == eHorizontalCrossingType::hctCurrentLeftOfNext) && - fabs(m_dRight - pCont->m_dLeft) < c_dTHE_STRING_X_PRECISION_MM * 3; - bool bIf4 = (eHType == eHorizontalCrossingType::hctNoCrossingCurrentRightOfNext || - eHType == eHorizontalCrossingType::hctCurrentRightOfNext) && - fabs(m_dLeft - pCont->m_dRight) < c_dTHE_STRING_X_PRECISION_MM * 3; - //Размеры шрифта должны бать разными - bool bIf5 = m_pFontStyle->m_oFont.Size * 0.7 > pCont->m_pFontStyle->m_oFont.Size; - bool bIf6 = m_pFontStyle->m_oFont.Size < pCont->m_pFontStyle->m_oFont.Size * 0.7; - - if (bIf3 || bIf4) - { - if (bIf1 && bIf5) - { - pCont->m_eVertAlignType = eVertAlignType::vatSubscript; - pCont->m_pCont = this; - m_eVertAlignType = eVertAlignType::vatBase; - m_pCont = pCont; - return true; - } - else if (bIf2 && bIf5) - { - pCont->m_eVertAlignType = eVertAlignType::vatSuperscript; - pCont->m_pCont = this; - m_eVertAlignType = eVertAlignType::vatBase; - m_pCont = pCont; - return true; - } - else if (bIf1 && bIf6) - { - m_eVertAlignType = eVertAlignType::vatSuperscript; - m_pCont = pCont; - pCont->m_eVertAlignType = eVertAlignType::vatBase; - pCont->m_pCont = this; - return true; - } - else if (bIf2 && bIf6) - { - m_eVertAlignType = eVertAlignType::vatSubscript; - m_pCont = pCont; - pCont->m_eVertAlignType = eVertAlignType::vatBase; - pCont->m_pCont = this; - return true; - } - } - return false; - } - - double CContText::CalculateWideSpace() - { - return m_dSpaceWidthMM * 4; - } - - double CContText::CalculateThinSpace() - { - return m_dSpaceWidthMM; - } + CSelectedSizes::CSelectedSizes(const CSelectedSizes& oSelectedSizes) + { + *this = oSelectedSizes; + } + CSelectedSizes& CSelectedSizes::operator=(const CSelectedSizes& oSelectedSizes) + { + dWidth = oSelectedSizes.dWidth; + dHeight = oSelectedSizes.dHeight; + return *this; + } + + CContText::CContText(const CContText& rCont) + { + *this = rCont; + } + + CContText::~CContText() + { + Clear(); + } + + void CContText::Clear() + { + m_pFontStyle = nullptr; + } + + CContText& CContText::operator= (const CContText& rCont) + { + if (this == &rCont) + return *this; + + CBaseItem::operator=(rCont); + + m_pFontStyle = rCont.m_pFontStyle; + + m_bIsStrikeoutPresent = rCont.m_bIsStrikeoutPresent; + m_bIsDoubleStrikeout = rCont.m_bIsDoubleStrikeout; + m_bIsHighlightPresent = rCont.m_bIsHighlightPresent; + m_lHighlightColor = rCont.m_lHighlightColor; + m_bIsUnderlinePresent = rCont.m_bIsUnderlinePresent; + m_eUnderlineType = rCont.m_eUnderlineType; + m_lUnderlineColor = rCont.m_lUnderlineColor; + m_bIsShadowPresent = rCont.m_bIsShadowPresent; + m_bIsOutlinePresent = rCont.m_bIsOutlinePresent; + m_bIsEmbossPresent = rCont.m_bIsEmbossPresent; + m_bIsEngravePresent = rCont.m_bIsEngravePresent; + + m_oText = rCont.m_oText; + + m_oSelectedSizes = rCont.m_oSelectedSizes; + m_dSpaceWidthMM = rCont.m_dSpaceWidthMM; + m_eVertAlignType = rCont.m_eVertAlignType; + + m_pManager = rCont.m_pManager; + + m_pShape = rCont.m_pShape; + m_pCont = rCont.m_pCont; + + m_iNumDuplicates = rCont.m_iNumDuplicates; + + m_dTopWithAscent = rCont.m_dTopWithAscent; + m_dBotWithDescent = rCont.m_dBotWithDescent; + + m_oSelectedFont = rCont.m_oSelectedFont; + m_bPossibleSplit = rCont.m_bPossibleSplit; + m_bWriteStyleRaw = rCont.m_bWriteStyleRaw; + + m_arSymWidths.clear(); + m_arSymWidths.resize(rCont.m_arSymWidths.size()); + for (size_t i = 0; i < rCont.m_arSymWidths.size(); ++i) + m_arSymWidths[i] = rCont.m_arSymWidths[i]; + + return *this; + } + + void CContText::CalcSelected() + { + if (!m_pFontStyle->wsFontName.empty() && !m_oText.empty()) + { + // нужно перемерять... + if (m_oSelectedFont.Path.empty()) + m_pManager->LoadFontByName(m_oSelectedFont); + else + m_pManager->LoadFontByFile(m_oSelectedFont); + + double dBoxX; + double dBoxY; + double dBoxWidth; + double dBoxHeight; + + if (m_oText.ToStdWString() == L" ") + dBoxWidth = m_pManager->GetSpaceWidthMM(); + else + { + m_pManager->SetStringGid(0); + m_pManager->MeasureString(m_oText.ToStdWString(), 0, 0, dBoxX, dBoxY, dBoxWidth, dBoxHeight, CFontManager::mtPosition); + } + + m_oSelectedSizes.dWidth = dBoxWidth; + m_oSelectedSizes.dHeight = dBoxHeight; + } + } + + size_t CContText::GetLength() const noexcept + { + return m_oText.length(); + } + + std::shared_ptr CContText::Split(size_t index) + { + const size_t len = GetLength(); + if (index >= len - 1) + return nullptr; + + auto lefts = GetSymLefts(); + + auto cont = std::make_shared(*this); + cont->m_oText = m_oText.substr(index + 1, (len - (index + 1))); + cont->m_dLeft = lefts[index + 1]; + cont->m_dWidth = cont->m_dRight - cont->m_dLeft; + + cont->m_arSymWidths.clear(); + for (size_t i = index + 1; i < len; ++i) + cont->m_arSymWidths.push_back(m_arSymWidths[i]); + + m_oText = m_oText.substr(0, index + 1); + m_dRight = cont->m_dLeft; + m_dWidth = m_dRight - m_dLeft; + m_arSymWidths.resize(index + 1); + m_bPossibleSplit = false; + + return cont; + } + std::shared_ptr CContText::Split(double dLeft) + { + if (dLeft < m_dLeft) + return nullptr; + + auto lefts = GetSymLefts(); + auto it = std::lower_bound(lefts.begin(), lefts.end(), dLeft); + + if (it == lefts.end()) + return nullptr; + + size_t index = std::distance(lefts.begin(), it); + if (index == 0) + return nullptr; + + index--; + + // if a little overlapped the next one - take the previous one + if (abs(lefts[index] - dLeft) < c_dTHE_STRING_X_PRECISION_MM) + index--; + + if (index == 0) + return nullptr; + + return Split(index); + } + + eVerticalCrossingType CContText::GetVerticalCrossingType(const CContText* pCont) const noexcept + { + const double& this_top = m_dTopWithAscent; + const double& this_bot = m_dBotWithDescent; + + const double& other_top = pCont->m_dTopWithAscent; + const double& other_bot = pCont->m_dBotWithDescent; + + if (this_top > other_top && this_bot < other_bot) + return eVerticalCrossingType::vctCurrentInsideNext; + + else if (this_top < other_top && this_bot > other_bot) + return eVerticalCrossingType::vctCurrentOutsideNext; + + else if (this_top < other_top && this_bot < other_bot && + (this_bot >= other_top || fabs(this_bot - other_top) < c_dTHE_SAME_STRING_Y_PRECISION_MM)) + return eVerticalCrossingType::vctCurrentAboveNext; + + else if (this_top > other_top && this_bot > other_bot && + (this_top <= other_bot || fabs(this_top - other_bot) < c_dTHE_SAME_STRING_Y_PRECISION_MM)) + return eVerticalCrossingType::vctCurrentBelowNext; + + else if (this_top == other_top && this_bot == other_bot) + return eVerticalCrossingType::vctDublicate; + + else if (fabs(this_top - other_top) < c_dTHE_SAME_STRING_Y_PRECISION_MM && + fabs(this_bot - other_bot) < c_dTHE_SAME_STRING_Y_PRECISION_MM) + return eVerticalCrossingType::vctTopAndBottomBordersMatch; + + else if (fabs(this_top - other_top) < c_dTHE_SAME_STRING_Y_PRECISION_MM) + return eVerticalCrossingType::vctTopBorderMatch; + + else if (fabs(this_bot - other_bot) < c_dTHE_SAME_STRING_Y_PRECISION_MM) + return eVerticalCrossingType::vctBottomBorderMatch; + + else if (this_bot < other_top) + return eVerticalCrossingType::vctNoCrossingCurrentAboveNext; + + else if (this_top > other_bot) + return eVerticalCrossingType::vctNoCrossingCurrentBelowNext; + + else + return eVerticalCrossingType::vctUnknown; + } + + void CContText::ToXml(NSStringUtils::CStringBuilder& oWriter) const + { + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + + if (m_bIsRtl) + oWriter.WriteString(L" "); + + if (!m_bWriteStyleRaw) + { + oWriter.WriteString(L"wsFontStyleId); + oWriter.WriteString(L"\"/>"); + } + + LONG lCalculatedSpacing = 0; + + if (!m_oText.empty()) + { + double dSpacing = (m_dWidth - m_oSelectedSizes.dWidth) / (m_oText.length()); + dSpacing *= c_dMMToDx; + + //mm to points * 20 + lCalculatedSpacing = static_cast(dSpacing); + } + + // принудительно уменьшаем spacing чтобы текстовые линии не выходили за правую границу + lCalculatedSpacing -= 1; + + if (lCalculatedSpacing != 0) + { + oWriter.WriteString(L""); + } + + if (m_bIsEmbossPresent) + oWriter.WriteString(L""); + else if(m_bIsEngravePresent) + oWriter.WriteString(L""); + else + { + if (m_bIsOutlinePresent) + oWriter.WriteString(L""); + if (m_bIsShadowPresent) + oWriter.WriteString(L""); + } + + if (m_bIsStrikeoutPresent) + { + if (m_bIsDoubleStrikeout) + oWriter.WriteString(L""); + else + oWriter.WriteString(L""); + } + + if (m_bIsUnderlinePresent) + { + oWriter.WriteString(L""); + } + + if (m_bIsHighlightPresent) + { + //note В (); + if (colorTable.IsStandardColor(m_lHighlightColor)) + { + oWriter.WriteString(L""); + } + + if (m_eVertAlignType == eVertAlignType::vatSubscript || m_eVertAlignType == eVertAlignType::vatSuperscript) + { + int lSize = static_cast(3.0 * m_pFontStyle->dFontSize); + oWriter.WriteString(L""); + } + else if (m_bWriteStyleRaw) + { + int lSize = static_cast(2.0 * m_pFontStyle->dFontSize); + oWriter.WriteString(L""); + } + + if (m_bWriteStyleRaw) + { + oWriter.WriteString(L"wsFontName); + oWriter.WriteString(L"\" w:hAnsi=\""); + oWriter.WriteEncodeXmlString(m_pFontStyle->wsFontName); + oWriter.WriteString(L"\" w:cs=\""); + oWriter.WriteEncodeXmlString(m_pFontStyle->wsFontName); + oWriter.WriteString(L"\" w:eastAsia=\""); + oWriter.WriteEncodeXmlString(m_pFontStyle->wsFontName); + oWriter.WriteString(L"\" w:hint=\"default\"/>"); + + if (m_pFontStyle->bBold) + { + oWriter.WriteString(L""); + oWriter.WriteString(L""); + } + if (m_pFontStyle->bItalic) + { + oWriter.WriteString(L""); + oWriter.WriteString(L""); + } + if (ConvertColorBGRToRGB(m_pFontStyle->oBrush.Color1) != c_iBlackColor2) + { + oWriter.WriteString(L"oBrush.Color1)); + oWriter.WriteString(L"\"/>"); + } + } + + if (m_eVertAlignType == eVertAlignType::vatSubscript) + oWriter.WriteString(L""); + else if (m_eVertAlignType == eVertAlignType::vatSuperscript) + oWriter.WriteString(L""); + + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteEncodeXmlString(m_oText.ToStdWString()); + oWriter.WriteString(L""); + if (m_bIsAddBrEnd) oWriter.WriteString(L""); + oWriter.WriteString(L""); + } + + void CContText::ToXmlPptx(NSStringUtils::CStringBuilder& oWriter) const + { + oWriter.WriteString(L""); + oWriter.WriteString(L"(dSpacing); + } + + // принудительно уменьшаем spacing чтобы текстовые линии не выходили за правую границу + lCalculatedSpacing -= 15; + + oWriter.WriteString(L" spc=\""); + oWriter.AddInt(lCalculatedSpacing); + oWriter.WriteString(L"\""); + + if (m_bIsOutlinePresent) + oWriter.WriteString(L" ln=\"1\""); + // if (m_bIsShadowPresent) + + if (m_bIsStrikeoutPresent) + { + if (m_bIsDoubleStrikeout) + oWriter.WriteString(L" strike=\"dblStrike\""); + else + oWriter.WriteString(L" strike=\"sngStrike\""); + } + + if (m_bIsUnderlinePresent) + { + oWriter.WriteString(L" u="); + oWriter.WriteString(SingletonInstance().ConvertLineToStringPptx(m_eUnderlineType)); + } + + UINT lSize = 0; + if (m_eVertAlignType == eVertAlignType::vatSubscript || m_eVertAlignType == eVertAlignType::vatSuperscript) + lSize = static_cast(1.5 * m_pFontStyle->dFontSize) * 100; + else if (m_bWriteStyleRaw) + lSize = static_cast(m_pFontStyle->dFontSize) * 100; + + oWriter.WriteString(L" sz=\""); + oWriter.AddUInt(lSize); + oWriter.WriteString(L"\""); + + if (m_pFontStyle->bBold) + oWriter.WriteString(L" b=\"1\""); + if (m_pFontStyle->bItalic) + oWriter.WriteString(L" i=\"1\""); + + if (m_eVertAlignType == eVertAlignType::vatSubscript) + oWriter.WriteString(L" baseline=\"-20000\">"); + else if (m_eVertAlignType == eVertAlignType::vatSuperscript) + oWriter.WriteString(L" baseline=\"30000\">"); + + oWriter.WriteString(L">"); + + oWriter.WriteString(L"wsFontName); + oWriter.WriteString(L"\"/>"); + + oWriter.WriteString(L"wsFontName); + oWriter.WriteString(L"\"/>"); + + oWriter.WriteString(L"wsFontName); + oWriter.WriteString(L"\"/>"); + + if (m_bIsUnderlinePresent && m_lUnderlineColor != m_pFontStyle->oBrush.Color1) + { + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + } + + if (m_bIsHighlightPresent) + { + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + } + + if (ConvertColorBGRToRGB(m_pFontStyle->oBrush.Color1) != c_iBlackColor) + { + oWriter.WriteString(L""); + oWriter.WriteString(L"oBrush.Color1)); + oWriter.WriteString(L"\"/>"); + oWriter.WriteString(L""); + } + + if (m_bIsRtl) + oWriter.WriteString(L" "); + + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteEncodeXmlString(m_oText.ToStdWString()); + oWriter.WriteString(L""); + if (m_bIsAddBrEnd) oWriter.WriteString(L""); + + // meta info for pdf-editor + oWriter.WriteString(L""); + + oWriter.WriteString(L""); + oWriter.WriteString(L""); + } + + bool CContText::IsEqual(const CContText *pCont) const noexcept + { + bool bIf1 = m_pFontStyle->wsFontStyleId == pCont->m_pFontStyle->wsFontStyleId; + bool bIf2 = m_bIsStrikeoutPresent == pCont->m_bIsStrikeoutPresent; + bool bIf3 = m_bIsDoubleStrikeout == pCont->m_bIsDoubleStrikeout; + bool bIf4 = m_bIsHighlightPresent == pCont->m_bIsHighlightPresent; + bool bIf5 = m_lHighlightColor == pCont->m_lHighlightColor; + bool bIf6 = m_bIsUnderlinePresent == pCont->m_bIsUnderlinePresent; + bool bIf7 = m_eUnderlineType == pCont->m_eUnderlineType; + bool bIf8 = m_lUnderlineColor == pCont->m_lUnderlineColor; + bool bIf9 = m_bIsShadowPresent == pCont->m_bIsShadowPresent; + bool bIf10 = m_bIsOutlinePresent == pCont->m_bIsOutlinePresent; + bool bIf11 = m_bIsEmbossPresent == pCont->m_bIsEmbossPresent; + bool bIf12 = m_bIsEngravePresent == pCont->m_bIsEngravePresent; + bool bIf13 = m_eVertAlignType == pCont->m_eVertAlignType; + bool bIf14 = m_eVertAlignType == eVertAlignType::vatUnknown && pCont->m_eVertAlignType == eVertAlignType::vatBase; + bool bIf15 = m_eVertAlignType == eVertAlignType::vatBase && pCont->m_eVertAlignType == eVertAlignType::vatUnknown; + + return (bIf1 && bIf2 && bIf3 && bIf4 && bIf5 && bIf6 && bIf7 && + bIf8 && bIf9 && bIf10 && bIf11 && bIf12 && (bIf13 || bIf14 || bIf15)); + } + + UINT CContText::GetNumberOfFeatures() const noexcept + { + UINT ret = 0; + if (m_pFontStyle->bBold) ret++; + if (m_pFontStyle->bItalic) ret++; + if (m_bIsStrikeoutPresent) ret++; + if (m_bIsDoubleStrikeout) ret++; + if (m_bIsHighlightPresent) ret++; + if (m_bIsUnderlinePresent) ret++; + if (m_eVertAlignType != eVertAlignType::vatUnknown) ret++; + return ret; + } + + bool CContText::IsDuplicate(CContText* pCont, eVerticalCrossingType eVType, eHorizontalCrossingType eHType) const noexcept + { + return m_oText == pCont->m_oText && + eVType == eVerticalCrossingType::vctDublicate && + (eHType == eHorizontalCrossingType::hctDublicate || + eHType == eHorizontalCrossingType::hctCurrentLeftOfNext || + eHType == eHorizontalCrossingType::hctCurrentRightOfNext); + } + + bool CContText::IsOnlySpaces() const + { + bool only_spaces = true; + for (size_t j = 0; j < m_oText.length(); ++j) + if (!CContText::IsUnicodeSpace(m_oText.at(j))) + { + only_spaces = false; + break; + } + return only_spaces; + } + bool CContText::IsDiacritical() const noexcept + { + const auto& text = GetText(); + return text.length() == 1 && CContText::IsUnicodeDiacriticalMark(text.at(0)); + } + + void CContText::AddTextBack(const NSStringUtils::CStringUTF32& oText, const std::vector& arSymWidths) + { + bool is_space_twice = m_oText.at(m_oText.length() - 1) == c_SPACE_SYM && + oText.at(0) == c_SPACE_SYM; + + for (size_t i = 0; i < arSymWidths.size(); ++i) + { + auto& w = arSymWidths[i]; + if (i == 0 && is_space_twice) + { + m_arSymWidths.back() = m_arSymWidths.back() + arSymWidths[i]; + m_dWidth += arSymWidths[i]; + continue; + } + m_arSymWidths.push_back(w); + m_dWidth += w; + m_oText += oText.at(i); + } + m_dRight = m_dLeft + m_dWidth; + } + void CContText::AddTextFront(const NSStringUtils::CStringUTF32& oText, const std::vector& arSymWidths) + { + m_oText = oText + m_oText; + + auto ar_sym_w = m_arSymWidths; + m_arSymWidths = arSymWidths; + + for (auto& w : ar_sym_w) + m_arSymWidths.push_back(w); + } + void CContText::SetText(const NSStringUtils::CStringUTF32& oText, const std::vector& arSymWidths) + { + m_oText = oText; + m_arSymWidths.clear(); + m_dWidth = 0; + for (auto& w : arSymWidths) + { + m_arSymWidths.push_back(w); + m_dWidth += w; + } + m_dRight = m_dLeft + m_dWidth; + } + + void CContText::AddSymBack(uint32_t cSym, double dWidth) + { + bool is_space_twice = m_oText.at(m_oText.length() - 1) == c_SPACE_SYM && cSym == c_SPACE_SYM; + + if (is_space_twice) + m_arSymWidths.back() += dWidth; + else + { + m_arSymWidths.push_back(dWidth); + m_oText += cSym; + } + m_dWidth += dWidth; + m_dRight = m_dLeft + m_dWidth; + + } + void CContText::AddSymFront(uint32_t cSym, double dWidth) + { + NSStringUtils::CStringUTF32 text; + text += cSym; + text += m_oText; + m_oText = text; + m_arSymWidths.insert(m_arSymWidths.begin(), dWidth); + } + void CContText::SetSym(uint32_t cSym, double dWidth) + { + m_oText = L""; + m_oText += cSym; + m_arSymWidths.clear(); + m_arSymWidths.push_back(dWidth); + m_dWidth = dWidth; + m_dRight = m_dLeft + m_dWidth; + } + void CContText::RemoveLastSym() + { + m_oText = m_oText.substr(0, m_oText.length() - 1); + m_dWidth -= m_arSymWidths[m_arSymWidths.size() - 1]; + m_dRight = m_dLeft + m_dWidth; + m_arSymWidths.resize(m_arSymWidths.size() - 1); + } + uint32_t CContText::GetLastSym() const + { + return m_oText.at(m_oText.length() - 1); + } + + const NSStringUtils::CStringUTF32& CContText::GetText() const noexcept + { + return m_oText; + } + const std::vector& CContText::GetSymWidths() const noexcept + { + return m_arSymWidths; + } + const std::vector CContText::GetSymLefts() const noexcept + { + std::vector lefts; + double left = m_dLeft; + for (auto& w : m_arSymWidths) + { + lefts.push_back(left); + left += w; + } + return lefts; + } + + bool CContText::CheckFontEffects + (std::shared_ptr& pFirstCont, + std::shared_ptr& pSecondCont, + eVerticalCrossingType eVType, + eHorizontalCrossingType eHType) + { + //Условие пересечения по вертикали + bool bIf1 = eVType == eVerticalCrossingType::vctCurrentAboveNext; //текущий cont выше + bool bIf2 = eVType == eVerticalCrossingType::vctCurrentBelowNext; //текущий cont ниже + + //Условие пересечения по горизонтали + bool bIf3 = eHType == eHorizontalCrossingType::hctCurrentLeftOfNext; //текущий cont левее + bool bIf4 = eHType == eHorizontalCrossingType::hctCurrentRightOfNext; //текущий cont правее + + //Размеры шрифта и текст должны бать одинаковыми + bool bIf5 = pFirstCont->m_pFontStyle->dFontSize == pSecondCont->m_pFontStyle->dFontSize; + bool bIf6 = pFirstCont->m_oText == pSecondCont->m_oText; + + //Цвет тени должен быть серым + bool bIf7 = pFirstCont->m_pFontStyle->oBrush.Color1 == c_iGreyColor; + bool bIf8 = pSecondCont->m_pFontStyle->oBrush.Color1 == c_iGreyColor; + + bool bIf9 = pFirstCont->m_pFontStyle->oBrush.Color1 == c_iBlackColor; + bool bIf10 = pSecondCont->m_pFontStyle->oBrush.Color1 == c_iBlackColor; + + bool bIf11 = pFirstCont->m_pFontStyle->oBrush.Color1 == c_iGreyColor2; + bool bIf12 = pSecondCont->m_pFontStyle->oBrush.Color1 == c_iGreyColor2; + + //note Каждый символ с Emboss или Engrave разбиваются на 3 символа с разными цветами + //note Логика подобрана для конкретного примера - возможно нужно будет ее обобщить. + //todo существует проблема неправильного определением FontEffects с физически пересекаемыми строчками - файл generaltest.pdf p.14 + if (bIf5 && bIf6) + { + if (bIf12 && pFirstCont->m_bIsEmbossPresent) + if (bIf1 && bIf3) + { + pFirstCont->m_bIsEmbossPresent = true; + pSecondCont = nullptr; + return true; + } + + if (bIf10 && pFirstCont->m_bIsEngravePresent) + if (bIf1 && bIf3) + { + pFirstCont->m_bIsEngravePresent = true; + pSecondCont = nullptr; + return true; + } + + //Shadow + if (bIf1 && bIf3 && bIf8) + { + pFirstCont->m_bIsShadowPresent = true; + pSecondCont = nullptr; + return true; + } + else if (bIf2 && bIf4 && bIf7) + { + pSecondCont->m_bIsShadowPresent = true; + pFirstCont = nullptr; + return true; + } + + //Emboss + //Первый проход + //c_iBlackColor -> c_iBlackColor -> c_iGreyColor2 + else if (bIf1 && bIf3 && bIf9) + { + pSecondCont->m_bIsEmbossPresent = true; + pFirstCont = nullptr; + return true; + } + //Engrave + else if (bIf1 && bIf3 && bIf11) + { + pSecondCont->m_bIsEngravePresent = true; + pFirstCont = nullptr; + return true; + } + } + return false; + } + + bool CContText::CheckVertAlignTypeBetweenConts + (std::shared_ptr pFirstCont, + std::shared_ptr pSecondCont, + eVerticalCrossingType eVType, + eHorizontalCrossingType eHType) + { + + bool bIf1 = eVType == eVerticalCrossingType::vctCurrentAboveNext || + eVType == eVerticalCrossingType::vctCurrentInsideNext; + + bool bIf2 = eVType == eVerticalCrossingType::vctCurrentBelowNext; + + bool bIf3 = (eHType == eHorizontalCrossingType::hctNoCrossingCurrentLeftOfNext || + eHType == eHorizontalCrossingType::hctCurrentLeftOfNext) && + fabs(pFirstCont->m_dRight - pSecondCont->m_dLeft) < c_dTHE_STRING_X_PRECISION_MM * 3; + + bool bIf4 = (eHType == eHorizontalCrossingType::hctNoCrossingCurrentRightOfNext || + eHType == eHorizontalCrossingType::hctCurrentRightOfNext) && + fabs(pFirstCont->m_dLeft - pSecondCont->m_dRight) < c_dTHE_STRING_X_PRECISION_MM * 3; + + //Размеры шрифта должны бать разными + bool bIf5 = pFirstCont->m_pFontStyle->dFontSize * 0.7 > pSecondCont->m_pFontStyle->dFontSize; + bool bIf6 = pFirstCont->m_pFontStyle->dFontSize < pSecondCont->m_pFontStyle->dFontSize * 0.7; + + if (bIf3 || bIf4) + { + if (bIf1 && bIf5) + { + pSecondCont->m_eVertAlignType = eVertAlignType::vatSubscript; + pSecondCont->m_pCont = pFirstCont; + pFirstCont->m_eVertAlignType = eVertAlignType::vatBase; + pFirstCont->m_pCont = pSecondCont; + pFirstCont->m_bPossibleSplit = false; + return true; + } + else if (bIf2 && bIf5) + { + pSecondCont->m_eVertAlignType = eVertAlignType::vatSuperscript; + pSecondCont->m_pCont = pFirstCont; + pFirstCont->m_eVertAlignType = eVertAlignType::vatBase; + pFirstCont->m_pCont = pSecondCont; + pFirstCont->m_bPossibleSplit = false; + return true; + } + else if (bIf1 && bIf6) + { + pFirstCont->m_eVertAlignType = eVertAlignType::vatSuperscript; + pFirstCont->m_pCont = pSecondCont; + pSecondCont->m_eVertAlignType = eVertAlignType::vatBase; + pSecondCont->m_pCont = pFirstCont; + pSecondCont->m_bPossibleSplit = false; + return true; + } + else if (bIf2 && bIf6) + { + pFirstCont->m_eVertAlignType = eVertAlignType::vatSubscript; + pFirstCont->m_pCont = pSecondCont; + pSecondCont->m_eVertAlignType = eVertAlignType::vatBase; + pSecondCont->m_pCont = pFirstCont; + pSecondCont->m_bPossibleSplit = false; + return true; + } + } + return false; + } + bool CContText::IsUnicodeRtl(uint32_t cSym) + { + bool is_herbew_arabic = (cSym >= 0x0590 && cSym <= 0x08FF); + + // alphabetic presentation forms + bool is_apf = (cSym >= 0xFB00 && cSym <= 0xFDFF); + bool is_apf_b = (cSym >= 0xFE70 && cSym <= 0xFEFF); + + bool is_other = (cSym >= 0x10800 && cSym <= 0x108AF); + + // more https://www.unicode.org/Public/UNIDATA/extracted/DerivedBidiClass.txt + return is_herbew_arabic || is_apf || is_apf_b || is_other; + } + bool CContText::IsUnicodeBullet(uint32_t cSym) + { + // more symbols of delims + bool is_bullet = + (cSym == 0x2022) || (cSym == 0x2023) || (cSym == 0x2043) || (cSym == 0x204C) || + (cSym == 0x204D) || (cSym == 0x2219) || (cSym == 0x25CB) || (cSym == 0x25CF) || + (cSym == 0x25D8) || (cSym == 0x25E6) || (cSym == 0x2619) || (cSym == 0x2765) || + (cSym == 0x2767) || (cSym == 0x29BE) || (cSym == 0x29BF) || (cSym == 0x25C9); + + bool is_another = + (cSym == 0xB7) || (cSym == 0xA7) || (cSym == 0xF076) || (cSym == 0x2013) || + (cSym == 0x2713) || (cSym == 0x2714) || (cSym == 0x2756) || (cSym == 0x25C6) || + (cSym == 0x25C7) || (cSym == 0x25C8); + + return is_bullet || is_another; + } + bool CContText::IsUnicodeEnumEnd(uint32_t cSym) + { + return cSym == 0x29 || cSym == 0x2e; + } + bool CContText::IsUnicodeNumber(uint32_t cSym) + { + return cSym >= 0x30 && cSym <= 0x39; + } + bool CContText::IsUnicodeSpace(uint32_t cSym) + { + return (0x20 == cSym || 0xA0 == cSym || 0x2003 == cSym); + } + + bool CContText::IsUnicodeSymbol(uint32_t cSym ) + { + bool is_unicode = + (( 0x0009 == cSym) || (0x000A == cSym ) || (0x000D == cSym ) || + (( 0x0020 <= cSym) && (0xD7FF >= cSym )) || ((0xE000 <= cSym) && (cSym <= 0xFFFD )) || + (( 0x10000 <= cSym) && cSym)); + + return is_unicode; + } + bool CContText::IsUnicodeDiacriticalMark(uint32_t cSym) + { + return 0x0300 <= cSym && 0x036F >= cSym; + } + + double CContText::CalculateSpace() const noexcept + { + return m_dSpaceWidthMM; + } + + CContTextBuilder::CContTextBuilder(CFontStyleManager* pFontStyleManager, CFontSelector* pFontSelector) : + m_pFontStyleManager(pFontStyleManager), m_pFontSelector(pFontSelector) + {} + + std::vector CContTextBuilder::GetConts() + { + return std::move(m_arConts); + } + + void CContTextBuilder::AddUnicode( + double dTop, + double dBot, + double dLeft, + double dRight, + const NSStructures::CFont& oFont, + const NSStructures::CBrush& oBrush, + CFontManager* pFontManager, + const NSStringUtils::CStringUTF32& oText, + bool bForcedBold, + bool bUseDefaultFont, + bool bWriteStyleRaw) + { + double dWidth = dRight - dLeft; + double dHeight = dBot - dTop; + + // if new text is close to current cont + if (m_pCurrCont != nullptr && + fabs(m_pCurrCont->m_dBaselinePos - dBot) < c_dTHE_SAME_STRING_Y_PRECISION_MM && + m_oPrevFont.IsEqual2(&oFont) && + m_oPrevBrush.IsEqual(&oBrush)) + { + + double avg_width = dWidth / oText.length(); + for (size_t i = 0; i < oText.length(); ++i) + if (oText.at(i) == c_SPACE_SYM) + m_pCurrCont->m_pFontStyle->UpdateAvgSpaceWidth(avg_width); + + double avg_space_width = m_pCurrCont->m_pFontStyle->GetAvgSpaceWidth(); + double space_width = + avg_space_width != 0.0 ? + avg_space_width * c_dAVERAGE_SPACE_WIDTH_COEF : + m_pCurrCont->CalculateSpace() * c_dSPACE_WIDTH_COEF; + + bool is_added = false; + + // some_text+more_text + if (fabs(m_pCurrCont->m_dRight - dLeft) < space_width && dRight > m_pCurrCont->m_dRight) + { + double left_avg_width = (dRight - m_pCurrCont->m_dRight) / oText.length(); + std::vector ar_widths; + for (size_t i = 0; i < oText.length(); ++i) + ar_widths.push_back(left_avg_width); + + m_pCurrCont->AddTextBack(oText, ar_widths); + is_added = true; + + } + // more_text+some_text + else if (fabs(m_pCurrCont->m_dLeft - dRight) < space_width && dLeft < m_pCurrCont->m_dLeft) + { + double right_avg_width = (m_pCurrCont->m_dLeft - dLeft) / oText.length(); + std::vector ar_widths; + for (size_t i = 0; i < oText.length(); ++i) + ar_widths.push_back(right_avg_width); + + m_pCurrCont->AddTextFront(oText, ar_widths); + is_added = true; + } + + if (is_added) + { + m_pCurrCont->m_dTop = std::min(m_pCurrCont->m_dTop, dTop); + m_pCurrCont->m_dBaselinePos = std::max(m_pCurrCont->m_dBaselinePos, dBot); + m_pCurrCont->m_dHeight = m_pCurrCont->m_dBaselinePos - m_pCurrCont->m_dTop; + m_pCurrCont->m_dWidth = m_pCurrCont->m_dRight - m_pCurrCont->m_dLeft; + return; + } + } + + auto pCont = std::make_shared(pFontManager); + const auto& oParams = pFontManager->GetFontSelectParams(); + const auto& oMetrics = pFontManager->GetFontMetrics(); + m_pFontSelector->SelectFont(oParams, oMetrics, oText); + + pCont->m_dBaselinePos = dBot; + pCont->m_dTop = dTop; + pCont->m_dHeight = dHeight; + pCont->m_dLeft = dLeft; + + // первичное получение стиля для текущего символа + // при дальнейшем анализе может измениться + pCont->m_pFontStyle = m_pFontStyleManager->GetOrAddFontStyle( + oBrush, + m_pFontSelector->GetSelectedName(), + oFont.Size, + m_pFontSelector->IsSelectedItalic(), + m_pFontSelector->IsSelectedBold() || bForcedBold); + + // just in case if oText contains more than 1 symbol + std::vector ar_widths; + double avg_width = abs(dRight - dLeft) / oText.length(); + for (size_t i = 0; i < oText.length(); ++i) + { + if (oText.at(i) == c_SPACE_SYM) pCont->m_pFontStyle->UpdateAvgSpaceWidth(avg_width); + ar_widths.push_back(avg_width); + } + + pCont->SetText(oText, ar_widths); + pCont->m_bIsRtl = CContText::IsUnicodeRtl(oText.at(0)); + + pCont->m_dWidth = dWidth; + pCont->m_dRight = dRight; + + double font_size = oFont.Size; + double em_height = oMetrics.dEmHeight; + double ratio = font_size / em_height * c_dPtToMM; + + pCont->m_dTopWithAscent = pCont->m_dBaselinePos - (oMetrics.dAscent * ratio) - oMetrics.dBaselineOffset; + pCont->m_dBotWithDescent = pCont->m_dBaselinePos + (oMetrics.dDescent * ratio) - oMetrics.dBaselineOffset; + pCont->m_dSpaceWidthMM = pFontManager->GetSpaceWidthMM(); + pCont->m_wsOriginFontName = oFont.Name; + + if (bUseDefaultFont) + { + pCont->m_oSelectedFont.Name = oFont.Name; + pCont->m_oSelectedFont.Path = oFont.Path; + pCont->m_oSelectedFont.Size = oFont.Size; + pCont->m_oSelectedFont.FaceIndex = oFont.FaceIndex; + } + else + { + pCont->m_oSelectedFont.Name = m_pFontSelector->GetSelectedName(); + pCont->m_oSelectedFont.Size = oFont.Size; + pCont->m_oSelectedFont.Bold = m_pFontSelector->IsSelectedBold(); + pCont->m_oSelectedFont.Italic = m_pFontSelector->IsSelectedItalic(); + } + pCont->m_bWriteStyleRaw = bWriteStyleRaw; + m_arConts.push_back(pCont); + + m_pCurrCont = pCont; + m_oPrevFont = oFont; + m_oPrevBrush = oBrush; + } } diff --git a/DocxRenderer/src/logic/elements/ContText.h b/DocxRenderer/src/logic/elements/ContText.h index 978e443f4d6..e1de82704f0 100644 --- a/DocxRenderer/src/logic/elements/ContText.h +++ b/DocxRenderer/src/logic/elements/ContText.h @@ -1,83 +1,184 @@ #pragma once +#include "../../../../DesktopEditor/common/StringBuilder.h" + #include "BaseItem.h" -#include "../DesktopEditor/common/StringBuilder.h" #include "../managers/FontManager.h" -#include "../managers/StyleManager.h" +#include "../managers//FontStyleManager.h" #include "../styles/FontStyle.h" #include "../../resources/Constants.h" #include "../../resources/LinesTable.h" namespace NSDocxRenderer { - class CShape; - - enum class eVertAlignType - { - vatUnknown, - vatBase, - vatSubscript, - vatSuperscript - }; - - class CContText : public CBaseItem - { - public: - std::shared_ptr m_pFontStyle {nullptr}; - - bool m_bIsStrikeoutPresent {false}; - bool m_bIsDoubleStrikeout {false}; - - bool m_bIsHighlightPresent {false}; - LONG m_lHighlightColor {c_iBlackColor}; - - bool m_bIsUnderlinePresent {false}; - eLineType m_eUnderlineType {eLineType::ltUnknown}; - LONG m_lUnderlineColor {c_iBlackColor}; - - bool m_bIsShadowPresent {false}; - bool m_bIsOutlinePresent {false}; - bool m_bIsEmbossPresent {false}; - bool m_bIsEngravePresent {false}; - - NSStringUtils::CStringUTF32 m_oText; - - double m_dLastX {0}; - double m_dSpaceWidthMM {0}; - bool m_bSpaceIsNotNeeded {false}; - - eVertAlignType m_eVertAlignType {eVertAlignType::vatUnknown}; - - CFontManagerLight* m_pManagerLight {nullptr}; - CStyleManager* m_pStyleManager {nullptr}; - - CShape* m_pShape {nullptr}; //Если не nullptr, то есть фоновая графика - можно анализировать. - const CContText* m_pCont {nullptr}; //Если не nullptr, то есть привязка к vatSubscript или vatSuperscript; - - UINT m_iNumDuplicates {0}; - - public: - CContText(CFontManagerLight* pManagerLight, CStyleManager* pStyleManager); - ~CContText(); - - void Clear() override final; - - double GetIntersect(const CContText* pCont) const; - - void ToXml(NSStringUtils::CStringBuilder& oWriter) override final; - - void AddWideSpaceToXml(double dSpacingMM, - NSStringUtils::CStringBuilder& oWriter, - bool bIsNeedSaveFormat = false); - - bool IsEqual(const CContText* pCont); - - UINT GetNumberOfFeatures(); - - bool IsDuplicate(CContText *pCont, eVerticalCrossingType eVType); - bool IsThereAreFontEffects(CContText *pCont, eVerticalCrossingType eVType, eHorizontalCrossingType eHType); - bool IsVertAlignTypeBetweenConts(CContText* pCont, eVerticalCrossingType eVType, eHorizontalCrossingType eHType); - - double CalculateWideSpace(); - double CalculateThinSpace(); - }; + class CShape; + + enum class eVertAlignType + { + vatUnknown, + vatBase, + vatSubscript, + vatSuperscript + }; + + // sizes in selected font + struct CSelectedSizes + { + double dWidth{0}; + double dHeight{0}; + + CSelectedSizes() = default; + ~CSelectedSizes() = default; + CSelectedSizes(const CSelectedSizes& oSelectedSizes); + CSelectedSizes& operator=(const CSelectedSizes& oSelectedSizes); + }; + + class CContText : public CBaseItem + { + public: + // utils + std::shared_ptr m_pFontStyle{nullptr}; + + CFontManager* m_pManager {nullptr}; + std::shared_ptr m_pShape{nullptr}; + + // super/sub script + std::weak_ptr m_pCont {}; + eVertAlignType m_eVertAlignType {eVertAlignType::vatUnknown}; + + // highlights + bool m_bIsStrikeoutPresent{false}; + bool m_bIsDoubleStrikeout {false}; + bool m_bIsHighlightPresent{false}; + LONG m_lHighlightColor {c_iBlackColor}; + bool m_bIsUnderlinePresent{false}; + eLineType m_eUnderlineType{eLineType::ltUnknown}; + LONG m_lUnderlineColor {c_iBlackColor}; + bool m_bIsShadowPresent {false}; + bool m_bIsOutlinePresent {false}; + bool m_bIsEmbossPresent {false}; + bool m_bIsEngravePresent {false}; + bool m_bIsRtl {false}; + + // font to calc selected sizes + NSStructures::CFont m_oSelectedFont{}; + + // origin font + std::wstring m_wsOriginFontName{}; + + // sizes + double m_dSpaceWidthMM{0}; + CSelectedSizes m_oSelectedSizes{}; + + double m_dTopWithAscent{0}; + double m_dBotWithDescent{0}; + + UINT m_iNumDuplicates{0}; + + bool m_bIsAddBrEnd{false}; + bool m_bWriteStyleRaw{false}; + bool m_bPossibleSplit{false}; + + CContText() = default; + CContText(CFontManager* pManager) : m_pManager(pManager) {} + CContText(const CContText& rCont); + virtual ~CContText(); + + virtual void Clear() override final; + virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) const override final; + virtual void ToXmlPptx(NSStringUtils::CStringBuilder& oWriter) const override final; + virtual eVerticalCrossingType GetVerticalCrossingType(const CContText* pItem) const noexcept; + + // calc sizes in selected font (uses m_oSelectedFont & m_pManager) + void CalcSelected(); + + size_t GetLength() const noexcept; + void AddTextBack(const NSStringUtils::CStringUTF32& oText, const std::vector& arSymWidths); + void AddTextFront(const NSStringUtils::CStringUTF32& oText, const std::vector& arSymWidths); + void SetText(const NSStringUtils::CStringUTF32& oText, const std::vector& arSymWidths); + + void AddSymBack(uint32_t cSym, double dWidth); + void AddSymFront(uint32_t cSym, double dWidth); + void SetSym(uint32_t cSym, double dWidth); + void RemoveLastSym(); + + uint32_t GetLastSym() const; + + const NSStringUtils::CStringUTF32& GetText() const noexcept; + const std::vector& GetSymWidths() const noexcept; + const std::vector GetSymLefts() const noexcept; + + std::shared_ptr Split(size_t index); + std::shared_ptr Split(double dLeft); + + CContText& operator=(const CContText& rCont); + bool IsEqual(const CContText* pCont) const noexcept; + + UINT GetNumberOfFeatures() const noexcept; + bool IsDuplicate(CContText* pCont, eVerticalCrossingType eVType, eHorizontalCrossingType eHType) const noexcept; + + bool IsOnlySpaces() const; + bool IsDiacritical() const noexcept; + double CalculateSpace() const noexcept; + + // check font effect and delete not needed cont + // return true if was deleted + static bool CheckFontEffects + (std::shared_ptr& pFirstCont, + std::shared_ptr& pSecondCont, + eVerticalCrossingType eVType, + eHorizontalCrossingType eHType); + + static bool CheckVertAlignTypeBetweenConts + (std::shared_ptr pFirstCont, + std::shared_ptr pSecondCont, + eVerticalCrossingType eVType, + eHorizontalCrossingType eHType); + + static bool IsUnicodeRtl(uint32_t cSym); + static bool IsUnicodeBullet(uint32_t cSym); + static bool IsUnicodeEnumEnd(uint32_t cSym); + static bool IsUnicodeNumber(uint32_t cSym); + static bool IsUnicodeSpace(uint32_t c); + static bool IsUnicodeSymbol(uint32_t symbol); + static bool IsUnicodeDiacriticalMark(uint32_t symbol); + + private: + NSStringUtils::CStringUTF32 m_oText{}; + std::vector m_arSymWidths{}; + }; + + class CContTextBuilder + { + protected: + using cont_ptr_t = std::shared_ptr; + + public: + CContTextBuilder() = delete; + CContTextBuilder(CFontStyleManager* pFontStyleManager, CFontSelector* pFontSelector); + ~CContTextBuilder() = default; + + // after call CContTextBuilder is empty + std::vector GetConts(); + void AddUnicode( + double dTop, + double dBot, + double dLeft, + double dRight, + const NSStructures::CFont& oFont, + const NSStructures::CBrush& oBrush, + CFontManager* pFontManager, + const NSStringUtils::CStringUTF32& oText, + bool bForcedBold = false, + bool bUseDefaultFont = false, + bool bWriteStyleRaw = false); + + private: + std::vector m_arConts; + cont_ptr_t m_pCurrCont {nullptr}; + NSStructures::CFont m_oPrevFont; + NSStructures::CBrush m_oPrevBrush; + + CFontStyleManager* m_pFontStyleManager {nullptr}; + CFontSelector* m_pFontSelector {nullptr}; + }; } diff --git a/DocxRenderer/src/logic/elements/Image.cpp b/DocxRenderer/src/logic/elements/Image.cpp deleted file mode 100644 index 43e90af5a65..00000000000 --- a/DocxRenderer/src/logic/elements/Image.cpp +++ /dev/null @@ -1,50 +0,0 @@ -#include "Image.h" -#include "../../resources/Constants.h" -#include - -namespace NSDocxRenderer -{ - CImage::CImage() : CBaseItem(ElemType::etImage) - { - } - CImage::CImage(const CImageInfo& oInfo, const std::wstring& strDstMedia) : CBaseItem(ElemType::etImage), - m_oImageInfo(oInfo), m_strPath(strDstMedia) - { - } - void CImage::Clear(){} - - void CImage::ToXml(NSStringUtils::CStringBuilder& oWriter) - { - if (m_bIsNotNecessaryToUse) - { - return; - } - - oWriter.WriteString(L" 0.01) - { - oWriter.WriteString(L"rotation:"); - oWriter.AddInt((int)m_dRotate); - oWriter.AddCharSafe(';'); - } - - oWriter.WriteString(L"z-index:-1;mso-position-horizontal-relative:page;mso-position-vertical-relative:page\" filled=\"f\">"); - - oWriter.WriteString(L""); - - oWriter.WriteString(L""); - } -} diff --git a/DocxRenderer/src/logic/elements/Image.h b/DocxRenderer/src/logic/elements/Image.h deleted file mode 100644 index a8ecbda02a8..00000000000 --- a/DocxRenderer/src/logic/elements/Image.h +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once -#include "BaseItem.h" -#include "../../resources/ImageInfo.h" - -namespace NSDocxRenderer -{ - class CImage : public CBaseItem - { - public: - CImageInfo m_oImageInfo; - - std::wstring m_strPath {L""}; - - bool m_bIsNoFill {true}; - bool m_bIsNoStroke {true}; - bool m_bIsBehindDoc {true}; - - double m_dRotate {0.0}; - - public: - CImage(); - CImage(const CImageInfo& oInfo, const std::wstring& strDstMedia); - void Clear() override final; - - void ToXml(NSStringUtils::CStringBuilder& oWriter) override final; - }; -} diff --git a/DocxRenderer/src/logic/elements/OldShape.cpp b/DocxRenderer/src/logic/elements/OldShape.cpp deleted file mode 100644 index abb60fe012c..00000000000 --- a/DocxRenderer/src/logic/elements/OldShape.cpp +++ /dev/null @@ -1,254 +0,0 @@ -#include "OldShape.h" -#include "../../resources/utils.h" - -namespace NSDocxRenderer -{ - const double COldShape::POSITION_CORRECTION_FOR_X_MM = 3.0; - const double COldShape::POSITION_CORRECTION_FOR_Y_MM = 2.0; - const double COldShape::SIZE_CORRECTION_FOR_X_MM = 10.0; - const double COldShape::SIZE_CORRECTION_FOR_Y_MM = 5.0; - - COldShape::COldShape() : CBaseItem(ElemType::etOldShape) - { - } - - COldShape::~COldShape() - { - Clear(); - } - - void COldShape::Clear() - { - m_arParagraphs.clear(); - } - - void COldShape::GetDataFromVector(const CVectorGraphics& oVector, const LONG& lType, const LONG& lCoordSize) - { - m_dLeft = oVector.m_dLeft; - m_dTop = oVector.m_dTop; - m_dWidth = oVector.m_dRight - m_dLeft; - m_dHeight = oVector.m_dBottom - m_dTop; - - if (m_dWidth < 0.0001) - m_dWidth = 0.0001; - if (m_dHeight < 0.0001) - m_dHeight = 0.0001; - - m_dBaselinePos = m_dTop + m_dHeight; - m_dRight = m_dLeft + m_dWidth; - - m_lCoordSizeX = lCoordSize; - m_lCoordSizeY = lCoordSize; - - if (0x00 == (lType & 0x01)) - { - m_bIsNoStroke = true; - } - if (0x00 == (lType >> 8)) - { - m_bIsNoFill = true; - } - - WritePath(oVector, lType, lCoordSize); - } - - void COldShape::WritePath(const CVectorGraphics& oVector, const LONG& lType, const LONG& lCoordSize) - { - size_t nCount = oVector.GetCurSize(); - double *pData = oVector.m_pData; - - double dWidth = oVector.m_dRight - m_dLeft; - double dHeight = oVector.m_dBottom - m_dTop; - - NSStringUtils::CStringBuilder oWriter; - - while (nCount > 0) - { - CVectorGraphics::VectorGraphicsType eType = static_cast((int)(0.5 + *pData++)); - - switch (eType) - { - case CVectorGraphics::vgtMove: - { - LONG lX = static_cast((*pData - m_dLeft) * lCoordSize / dWidth); - ++pData; - LONG lY = static_cast((*pData - m_dTop) * lCoordSize / dHeight); - ++pData; - - oWriter.AddCharSafe('m'); - oWriter.AddInt(lX); - oWriter.AddCharSafe(','); - oWriter.AddInt(lY); - - nCount -= 3; - break; - } - case CVectorGraphics::vgtLine: - { - LONG lX = static_cast((*pData - m_dLeft) * lCoordSize / dWidth); - ++pData; - LONG lY = static_cast((*pData - m_dTop) * lCoordSize / dHeight); - ++pData; - - oWriter.AddCharSafe('l'); - oWriter.AddInt(lX); - oWriter.AddCharSafe(','); - oWriter.AddInt(lY); - - nCount -= 3; - break; - } - case CVectorGraphics::vgtCurve: - { - LONG lX1 = static_cast((*pData - m_dLeft) * lCoordSize / dWidth); - ++pData; - LONG lY1 = static_cast((*pData - m_dTop) * lCoordSize / dHeight); - ++pData; - - LONG lX2 = static_cast((*pData - m_dLeft) * lCoordSize / dWidth); - ++pData; - LONG lY2 = static_cast((*pData - m_dTop) * lCoordSize / dHeight); - ++pData; - - LONG lX3 = static_cast((*pData - m_dLeft) * lCoordSize / dWidth); - ++pData; - LONG lY3 = static_cast((*pData - m_dTop) * lCoordSize / dHeight); - ++pData; - - oWriter.AddCharSafe('c'); - oWriter.AddInt(lX1); - oWriter.AddCharSafe(','); - oWriter.AddInt(lY1); - oWriter.AddCharSafe(','); - oWriter.AddInt(lX2); - oWriter.AddCharSafe(','); - oWriter.AddInt(lY2); - oWriter.AddCharSafe(','); - oWriter.AddInt(lX3); - oWriter.AddCharSafe(','); - oWriter.AddInt(lY3); - - nCount -= 7; - break; - } - case CVectorGraphics::vgtClose: - default: - oWriter.AddCharSafe('x'); - --nCount; - break; - } - } - - if (0x00 == (lType & 0x01)) - { - //m_bIsNoStroke = true; - oWriter.WriteString(L"ns"); - } - if (0x00 == (lType >> 8)) - { - //m_bIsNoFill = true; - oWriter.WriteString(L"nf"); - } - - oWriter.AddCharSafe('e'); - - m_strPath = oWriter.GetData(); - oWriter.ClearNoAttack(); - } - - void COldShape::ToXml(NSStringUtils::CStringBuilder &oWriter) - { - if (m_bIsNotNecessaryToUse) - { - return; - } - - oWriter.WriteString( - L"(m_lCoordSizeX)); - oWriter.AddCharSafe(','); - oWriter.AddInt(static_cast(m_lCoordSizeY)); - oWriter.WriteString(L"\" path=\""); - oWriter.WriteString(m_strPath); - if (c_BrushTypeTexture == m_oBrush.Type) - { - // у нас нет таких шейпов в pdf/xps - oWriter.WriteString(L"\" fillcolor=\"transparent"); - } - else - { - oWriter.WriteString(L"\" fillcolor=\"#"); - oWriter.WriteHexInt3(static_cast(ConvertColorBGRToRGB(m_oBrush.Color1))); - } - oWriter.WriteString(L"\" strokecolor=\"#"); - oWriter.WriteHexInt3(static_cast(ConvertColorBGRToRGB(m_oPen.Color))); - oWriter.WriteString(L"\" strokeweight=\""); - oWriter.AddDouble(m_oPen.Size, 2); - oWriter.WriteString(L"mm\">"); - - std::wstring g_string_fill_opacity = L""; - std::wstring g_string_stroke_opacity = L""; - - if (c_BrushTypeTexture == m_oBrush.Type && !m_bIsNoFill) - { - oWriter.WriteString(L""); - - if (0xFF != m_oBrush.TextureAlpha) - { - oWriter.WriteString(L"(m_oBrush.TextureAlpha / 255.0), 2); - oWriter.WriteString(L"\"/>"); - } - } - else - { - if (0xFF != m_oBrush.Alpha1) - { - oWriter.WriteString(L"(m_oBrush.Alpha1 / 255.0), 2); - oWriter.WriteString(L"\"/>"); - } - if (0xFF != m_oPen.Alpha) - { - oWriter.WriteString(L"(m_oPen.Alpha / 255.0), 2); - oWriter.WriteString(L"\"/>"); - } - } - - oWriter.WriteString(L""); - - if (!m_arParagraphs.empty()) - { - oWriter.WriteString(L""); - - for (const auto& pParagraph : m_arParagraphs) - { - pParagraph->ToXml(oWriter); - } - oWriter.WriteString(L""); - } - - oWriter.WriteString(L""); - } -} // namespace NSDocxRenderer diff --git a/DocxRenderer/src/logic/elements/OldShape.h b/DocxRenderer/src/logic/elements/OldShape.h deleted file mode 100644 index 6fd6f520783..00000000000 --- a/DocxRenderer/src/logic/elements/OldShape.h +++ /dev/null @@ -1,43 +0,0 @@ -#pragma once -#include "BaseItem.h" -#include "../../resources/VectorGraphics.h" -#include "Paragraph.h" - -namespace NSDocxRenderer -{ - class COldShape : public CBaseItem - { - public: - //Подобранные константы - static const double POSITION_CORRECTION_FOR_X_MM; - static const double POSITION_CORRECTION_FOR_Y_MM; - static const double SIZE_CORRECTION_FOR_X_MM; - static const double SIZE_CORRECTION_FOR_Y_MM; - - public: - std::wstring m_strPath {L""}; - NSStructures::CBrush m_oBrush; - NSStructures::CPen m_oPen; - - bool m_bIsNoFill {false}; - bool m_bIsNoStroke {false}; - - LONG m_lCoordSizeX {100000}; - LONG m_lCoordSizeY {100000}; - - LONG m_lTxId {-1}; - - std::vector m_arParagraphs; - - public: - COldShape(); - virtual ~COldShape(); - void Clear() override final; - - void GetDataFromVector(const CVectorGraphics& oVector, const LONG& lType, const LONG& lCoordSize); - - void WritePath(const CVectorGraphics& oVector, const LONG& lType, const LONG& lCoordSize); - - void ToXml(NSStringUtils::CStringBuilder& oWriter) override final; - }; -} diff --git a/DocxRenderer/src/logic/elements/Paragraph.cpp b/DocxRenderer/src/logic/elements/Paragraph.cpp index cfe9f343039..dedde155394 100644 --- a/DocxRenderer/src/logic/elements/Paragraph.cpp +++ b/DocxRenderer/src/logic/elements/Paragraph.cpp @@ -1,225 +1,213 @@ #include "Paragraph.h" -#include "src/resources/ColorTable.h" -#include "src/resources/utils.h" + +#include "../../resources/utils.h" namespace NSDocxRenderer { - CParagraph::CParagraph(const TextAssociationType& eType): - CBaseItem(ElemType::etParagraph), m_eTextAssociationType(eType) - { - } - - CParagraph::~CParagraph() - { - Clear(); - } - - void CParagraph::Clear() - { - m_arLines.clear(); - } - - void CParagraph::ToXml(NSStringUtils::CStringBuilder& oWriter) - { - if (m_bIsNotNecessaryToUse) - { - return; - } - - oWriter.WriteString(L""); - oWriter.WriteString(L""); - - switch (m_eTextConversionType) - { - case tctTextToFrame: - { - oWriter.WriteString(L"(m_dLeft * c_dMMToDx)); - oWriter.WriteString(L"\""); - - oWriter.WriteString(L" w:y=\""); - oWriter.AddInt(static_cast(m_dTop * c_dMMToDx)); - oWriter.WriteString(L"\""); - - oWriter.WriteString(L"/>"); //конец w:framePr - break; - } - case tctTextToShape: - case tctTextToParagraph: - { - oWriter.WriteString(L"(m_dSpaceBefore * c_dMMToDx)); - oWriter.WriteString(L"\""); - } - - if (m_eTextConversionType == tctTextToShape) - { - oWriter.WriteString(L" w:after=\""); - oWriter.AddInt(static_cast(m_dSpaceAfter * c_dMMToDx)); - oWriter.WriteString(L"\""); - } - - if (m_dHeight > 0) - { - oWriter.WriteString(L" w:line=\""); - oWriter.AddInt(static_cast(m_dHeight * c_dMMToDx)); - oWriter.WriteString(L"\" w:lineRule=\"exact\""); // exact - точный размер строки - } - - oWriter.WriteString(L"/>"); //конец w:spacing - - oWriter.WriteString(L" 0) - { - oWriter.WriteString(L" w:left=\""); - oWriter.AddInt(static_cast(m_dLeft * c_dMMToDx)); - oWriter.WriteString(L"\""); - } - if (m_dRight > 0) - { - oWriter.WriteString(L" w:right=\""); - oWriter.AddInt(static_cast(m_dRight * c_dMMToDx)); - oWriter.WriteString(L"\""); - } - if (m_bIsNeedFirstLineIndent) - { - oWriter.WriteString(L" w:firstLine=\""); - oWriter.AddInt(static_cast(m_dFirstLine * c_dMMToDx)); - oWriter.WriteString(L"\""); - } - oWriter.WriteString(L"/>"); //конец w:ind - - - if (m_eTextAssociationType == tatPlainParagraph) - { - switch (m_eTextAlignmentType) - { - case tatByCenter: - oWriter.WriteString(L""); - break; - case tatByRightEdge: - oWriter.WriteString(L""); - break; - case tatByWidth: - oWriter.WriteString(L""); - break; - case tatByLeftEdge: - oWriter.WriteString(L""); - break; - case tatUnknown: - default: //по умолчанию выравнивание по левому краю - можно ничего не добавлять - break; - } - } - - if (m_bIsShadingPresent) - { - oWriter.WriteString(L""); - } - break; - } - default: - break; - } - - oWriter.WriteString(L""); - - for(const auto &pLine : m_arLines) - { - pLine->ToXml(oWriter); - } - - oWriter.WriteString(L""); - } - - void CParagraph::RemoveHighlightColor() - { - if (!m_bIsShadingPresent) - { - return; - } - - for(const auto &pLine : m_arLines) - { - if (pLine->m_pDominantShape) - { - for (const auto &pCont : pLine->m_arConts) - { - if (m_lColorOfShadingFill == pCont->m_lHighlightColor) - { - pCont->m_bIsHighlightPresent = false; - } - } - } - } - } - - void CParagraph::MergeLines() - { - auto pLine = m_arLines.front(); - - for(size_t i = 1; i < m_arLines.size(); i++) - { - auto pLastCont = pLine->m_arConts.back(); - size_t iNumConts = pLine->m_arConts.size() - 1; - - while (pLastCont->m_bIsNotNecessaryToUse) - { - pLastCont = pLine->m_arConts[--iNumConts]; - } - - //Добавляем пробел в конец каждой строки - pLastCont->m_oText += L" "; - pLastCont->m_bSpaceIsNotNeeded = true; - pLastCont->m_dWidth += pLine->m_arConts.back()->m_dSpaceWidthMM; - - auto pNext = m_arLines[i]; - - auto pCont = pNext->m_arConts.front(); - - if (pLastCont->IsEqual(pCont) && - pLastCont->m_eVertAlignType == pCont->m_eVertAlignType) - { - pLastCont->m_oText += pCont->m_oText; - pLastCont->m_dWidth += pCont->m_dWidth; - pLastCont->m_dRight = pCont->m_dRight; - - pLastCont->m_bSpaceIsNotNeeded = false; - - pCont->m_bIsNotNecessaryToUse = true; - } - - for (const auto &pCont : pNext->m_arConts) - { - if (!pCont->m_bIsNotNecessaryToUse) - { - pLine->m_arConts.push_back(pCont); - } - } - - pNext->m_bIsNotNecessaryToUse = true; - } - } + CParagraph::~CParagraph() + { + Clear(); + } + + void CParagraph::Clear() + { + m_arLines.clear(); + } + + void CParagraph::ToXml(NSStringUtils::CStringBuilder& oWriter) const + { + oWriter.WriteString(L""); + oWriter.WriteString(L""); + + // styles + if(!m_wsStyleId.empty()) oWriter.WriteString(L""); + + oWriter.WriteString(L" 0) + oWriter.AddInt(static_cast(m_dSpaceBefore * c_dMMToDx)); + else + oWriter.AddInt(static_cast(0)); + oWriter.WriteString(L"\""); + + + if (m_dSpaceAfter > 0) + { + oWriter.WriteString(L" w:after=\""); + oWriter.AddInt(static_cast(m_dSpaceAfter * c_dMMToDx)); + oWriter.WriteString(L"\""); + } + + if (m_dLineHeight > 0) + { + oWriter.WriteString(L" w:line=\""); + oWriter.AddInt(static_cast(m_dLineHeight * c_dMMToDx)); + oWriter.WriteString(L"\" w:lineRule=\"exact\""); // exact - точный размер строки + } + + oWriter.WriteString(L"/>"); //конец w:spacing + + oWriter.WriteString(L" 0) + { + oWriter.WriteString(L" w:left=\""); + oWriter.AddInt(static_cast(m_dLeftBorder * c_dMMToDx)); + oWriter.WriteString(L"\""); + } + if (m_dRightBorder > 0) + { + oWriter.WriteString(L" w:right=\""); + oWriter.AddInt(static_cast(m_dRightBorder * c_dMMToDx)); //здесь m_dRight - расстояние от правого края + oWriter.WriteString(L"\""); + } + if (m_bIsNeedFirstLineIndent) + { + if (m_dFirstLine > 0) + { + oWriter.WriteString(L" w:firstLine=\""); + oWriter.AddInt(static_cast(m_dFirstLine * c_dMMToDx)); + oWriter.WriteString(L"\""); + } + else + { + oWriter.WriteString(L" w:hanging=\""); + oWriter.AddInt(static_cast(-m_dFirstLine * c_dMMToDx)); + oWriter.WriteString(L"\""); + } + } + oWriter.WriteString(L"/>"); //конец w:ind + + switch (m_eTextAlignmentType) + { + case tatByCenter: + oWriter.WriteString(L""); + break; + case tatByRight: + oWriter.WriteString(L""); + break; + case tatByWidth: + oWriter.WriteString(L""); + break; + case tatByLeft: + oWriter.WriteString(L""); + break; + case tatUnknown: + default: //по умолчанию выравнивание по левому краю - можно ничего не добавлять + break; + } + + if (m_bIsShadingPresent) + { + oWriter.WriteString(L""); + } + + oWriter.WriteString(L""); + for(const auto& line : m_arLines) + if(line) + line->ToXml(oWriter); + oWriter.WriteString(L""); + } + + void CParagraph::ToXmlPptx(NSStringUtils::CStringBuilder& oWriter) const + { + oWriter.WriteString(L""); + oWriter.WriteString(L"(m_dFirstLine * c_dMMToEMU)); + oWriter.WriteString(L"\""); + } + oWriter.WriteString(L">"); + + oWriter.WriteString(L""); + oWriter.WriteString(L"(m_dSpaceBefore * c_dMMToPt * 100)); + oWriter.WriteString(L"\"/>"); + oWriter.WriteString(L""); + + + oWriter.WriteString(L""); + oWriter.WriteString(L"(m_dSpaceBefore * c_dMMToPt * 100)); + oWriter.WriteString(L"\"/>"); + oWriter.WriteString(L""); + + oWriter.WriteString(L""); + oWriter.WriteString(L"(m_dLineHeight * c_dMMToPt * 100)); + oWriter.WriteString(L"\"/>"); + oWriter.WriteString(L""); + + oWriter.WriteString(L""); + for(const auto& line : m_arLines) + if(line) + line->ToXmlPptx(oWriter); + oWriter.WriteString(L""); + } + + void CParagraph::RemoveHighlightColor() + { + if (!m_bIsShadingPresent) + return; + + for(size_t i = 0; i < m_arLines.size(); ++i) + { + auto& pLine = m_arLines[i]; + if (pLine || pLine->m_pDominantShape) + { + for (size_t j = 0; j < pLine->m_arConts.size(); ++j) + { + auto& pCont = pLine->m_arConts[j]; + if(pCont) + if (m_lColorOfShadingFill == pCont->m_lHighlightColor) + pCont->m_bIsHighlightPresent = false; + } + } + } + } + + void CParagraph::MergeLines() + { + for(size_t i = 0; i < m_arLines.size() - 1; ++i) + { + auto pLine = m_arLines[i]; + auto pLastCont = pLine->m_arConts.back(); + size_t iNumConts = pLine->m_arConts.size() - 1; + + while(!pLastCont) + pLastCont = pLine->m_arConts[--iNumConts]; + + auto text = pLastCont->GetText(); + auto last_sym = text[text.length() - 1]; + + if (last_sym != c_SPACE_SYM && m_arLines.size() != 1) + pLastCont->AddSymBack(c_SPACE_SYM, 0); + } + } } diff --git a/DocxRenderer/src/logic/elements/Paragraph.h b/DocxRenderer/src/logic/elements/Paragraph.h index aeb552dc304..eef9894cb14 100644 --- a/DocxRenderer/src/logic/elements/Paragraph.h +++ b/DocxRenderer/src/logic/elements/Paragraph.h @@ -1,57 +1,47 @@ #pragma once #include "BaseItem.h" #include "TextLine.h" -#include "../../../convert_params.h" namespace NSDocxRenderer { - class CParagraph : public CBaseItem - { - public: - enum TextAlignmentType - { - tatUnknown, - tatByLeftEdge, - tatByCenter, - tatByRightEdge, - tatByWidth - }; - - enum TextConversionType - { - tctUnknown, - tctTextToParagraph, - tctTextToFrame, - tctTextToShape - }; - - // text frame properties - TextConversionType m_eTextConversionType {tctUnknown}; - bool m_bIsNeedFirstLineIndent {false}; - bool m_bIsAroundTextWrapping {true}; //по умолчанию обтекание включено, если отсутсвует w:wrap - bool m_bIsShadingPresent {false}; - LONG m_lColorOfShadingFill {c_iWhiteColor}; //BGR - TextAlignmentType m_eTextAlignmentType {tatUnknown}; - - // geometry paragraph - double m_dRight {0.0}; //сдвиг относительно правого края страницы - double m_dFirstLine {0.0}; //сдвиг относительно m_dLeft - - double m_dSpaceBefore {0.0}; //по умолчанию выставляется 0, если отсутсвует w:before - double m_dSpaceAfter {0.0}; //в shape по умолчанию выставляется 8pt, если отсутсвует w:after - double m_dBaselinePos {0.0}; - TextAssociationType m_eTextAssociationType {tatPlainParagraph}; - - std::vector m_arLines; - public: - CParagraph(const TextAssociationType& eType); - virtual ~CParagraph(); - void Clear() override final; - - void ToXml(NSStringUtils::CStringBuilder& oWriter) override final; - - void RemoveHighlightColor(); - - void MergeLines(); - }; + class CParagraph : public CBaseItem + { + public: + enum TextAlignmentType + { + tatUnknown, + tatByLeft, + tatByCenter, + tatByRight, + tatByWidth + }; + + // text frame properties + bool m_bIsNeedFirstLineIndent{false}; + bool m_bIsShadingPresent {false}; + LONG m_lColorOfShadingFill {c_iWhiteColor}; //BGR + TextAlignmentType m_eTextAlignmentType {tatUnknown}; + + // geometry paragraph + double m_dLeftBorder {0.0}; // сдвиг относительно левого края страницы/шейпа/таблицы + double m_dRightBorder{0.0}; // сдвиг относительно правого края страницы/шейпа/таблицы + double m_dFirstLine {0.0}; // сдвиг относительно m_dLeftBorder + + double m_dSpaceBefore{0.0}; // по умолчанию выставляется 0, если отсутсвует w:before + double m_dSpaceAfter {0.0}; // в shape по умолчанию выставляется 8pt, если отсутсвует w:after + double m_dLineHeight {0.0}; + + std::vector> m_arLines; + std::wstring m_wsStyleId; + + public: + CParagraph() : CBaseItem() {} + virtual ~CParagraph(); + virtual void Clear() override final; + virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) const override final; + virtual void ToXmlPptx(NSStringUtils::CStringBuilder& oWriter) const override final; + + void RemoveHighlightColor(); + void MergeLines(); + }; } diff --git a/DocxRenderer/src/logic/elements/Shape.cpp b/DocxRenderer/src/logic/elements/Shape.cpp index 17478339afa..6bdb4f2c3f6 100644 --- a/DocxRenderer/src/logic/elements/Shape.cpp +++ b/DocxRenderer/src/logic/elements/Shape.cpp @@ -1,931 +1,1050 @@ #include "Shape.h" + #include + #include "../../resources/Constants.h" #include "../../resources/utils.h" namespace NSDocxRenderer { - UINT CShape::m_gRelativeHeight = c_iStandartRelativeHeight; - - CShape::CShape() : CBaseItem(ElemType::etShape) - { - m_nRelativeHeight = m_gRelativeHeight; - m_gRelativeHeight += c_iStandartRelativeHeight; - } - - CShape::CShape(std::shared_ptr pInfo, const std::wstring& strDstMedia) : CBaseItem(ElemType::etShape), - m_strPath(strDstMedia), m_pImageInfo(pInfo) - { - m_nRelativeHeight = m_gRelativeHeight; - m_gRelativeHeight += c_iStandartRelativeHeight; - } - - CShape::~CShape() - { - Clear(); - } - - void CShape::Clear() - { - m_arParagraphs.clear(); - } - - UINT CShape::GenerateShapeId() - { - static UINT iId = 0; - iId++; - return iId; - } - - void CShape::ResetRelativeHeight() - { - m_gRelativeHeight = c_iStandartRelativeHeight; - } - - void CShape::GetDataFromVector(const CVectorGraphics& oVector) - { - m_dLeft = oVector.m_dLeft; - m_dTop = oVector.m_dTop; - m_dWidth = oVector.m_dRight - m_dLeft; - m_dHeight = oVector.m_dBottom - m_dTop; - - if (m_dWidth < 0.0001) - m_dWidth = 0.0001; - if (m_dHeight < 0.0001) - m_dHeight = 0.0001; - - m_dBaselinePos = m_dTop + m_dHeight; - m_dRight = m_dLeft + m_dWidth; - - WritePath(oVector); - } - - void CShape::WritePath(const CVectorGraphics& oVector) - { - size_t nCount = oVector.GetCurSize(); - double *pData = oVector.m_pData; - - double dWidth = oVector.m_dRight - oVector.m_dLeft; - double dHeight = oVector.m_dBottom - oVector.m_dTop; - - NSStringUtils::CStringBuilder oWriter; - - oWriter.WriteString(L"(dWidth * c_dMMToEMU)); - oWriter.WriteString(L"\" h=\""); - oWriter.AddInt(static_cast(dHeight * c_dMMToEMU)); - oWriter.WriteString(L"\">"); - - size_t nPeacks = 0; - size_t nCurves = 0; - - while (nCount > 0) - { - CVectorGraphics::VectorGraphicsType eType = static_cast((int)(0.5 + *pData++)); - - switch (eType) - { - case CVectorGraphics::vgtMove: - { - LONG lX = static_cast((*pData - m_dLeft) * c_dMMToEMU); - ++pData; - LONG lY = static_cast((*pData - m_dTop) * c_dMMToEMU); - ++pData; - - oWriter.WriteString(L"(lX)); - oWriter.WriteString(L"\" y=\""); - oWriter.AddInt(static_cast(lY)); - oWriter.WriteString(L"\"/>"); - - nPeacks++; - nCount -= 3; - break; - } - case CVectorGraphics::vgtLine: - { - LONG lX = static_cast((*pData - m_dLeft)* c_dMMToEMU); - ++pData; - LONG lY = static_cast((*pData - m_dTop)* c_dMMToEMU); - ++pData; - - oWriter.WriteString(L"(lX)); - oWriter.WriteString(L"\" y=\""); - oWriter.AddInt(static_cast(lY)); - oWriter.WriteString(L"\"/>"); - - nPeacks++; - nCount -= 3; - break; - } - case CVectorGraphics::vgtCurve: - { - LONG lX1 = static_cast((*pData - m_dLeft)* c_dMMToEMU); - ++pData; - LONG lY1 = static_cast((*pData - m_dTop)* c_dMMToEMU); - ++pData; - LONG lX2 = static_cast((*pData - m_dLeft)* c_dMMToEMU); - ++pData; - LONG lY2 = static_cast((*pData - m_dTop)* c_dMMToEMU); - ++pData; - LONG lX3 = static_cast((*pData - m_dLeft)* c_dMMToEMU); - ++pData; - LONG lY3 = static_cast((*pData - m_dTop)* c_dMMToEMU); - ++pData; - - oWriter.WriteString(L""); - - oWriter.WriteString(L"(lX1)); - oWriter.WriteString(L"\" y=\""); - oWriter.AddInt(static_cast(lY1)); - oWriter.WriteString(L"\"/>"); - oWriter.WriteString(L"(lX2)); - oWriter.WriteString(L"\" y=\""); - oWriter.AddInt(static_cast(lY2)); - oWriter.WriteString(L"\"/>"); - oWriter.WriteString(L"(lX3)); - oWriter.WriteString(L"\" y=\""); - oWriter.AddInt(static_cast(lY3)); - oWriter.WriteString(L"\"/>"); - - oWriter.WriteString(L""); - - nCurves++; - nCount -= 7; - break; - } - case CVectorGraphics::vgtClose: - default: - --nCount; - break; - } - } - oWriter.WriteString(L""); - oWriter.WriteString(L""); - - m_strPath = oWriter.GetData(); - - DetermineGraphicsType(dWidth, dHeight, nPeacks, nCurves); - - oWriter.ClearNoAttack(); - } - - void CShape::DetermineGraphicsType(double dWidth, double dHeight,size_t nPeacks, size_t nCurves) - { - //note параллельно для каждой текстовой строки создается шейп, который содержит цвет фона для данного текста. - if ((m_bIsNoStroke && m_bIsNoFill) || - (m_oBrush.Color1 == c_iWhiteColor && m_oPen.Color == c_iWhiteColor)) - { - m_eGraphicsType = eGraphicsType::gtNoGraphics; - } - else if ((nPeacks == 5 || nPeacks == 2) && !nCurves) //1 move + 4 Peacks или 2 Peacks - { - m_eGraphicsType = eGraphicsType::gtRectangle; - - if (dWidth > 2.0) //note длинное тире - 2.8mm у times new roman - { - m_eSimpleLineType = eSimpleLineType::sltLongDash; - } - else if (dWidth > 0.7) //минимальное тире - 0.75mm у dotDotDash - { - m_eSimpleLineType = eSimpleLineType::sltDash; - } - else //максимальна точка - 0.5mm - { - m_eSimpleLineType = eSimpleLineType::sltDot; - } - } - else if (nCurves > 0 && nPeacks <= 1) //1 move - { - m_eGraphicsType = eGraphicsType::gtCurve; - m_eSimpleLineType = eSimpleLineType::sltWave; - } - else if (nCurves > 0 && nPeacks > 1) - { - m_eGraphicsType = eGraphicsType::gtComplicatedFigure; - } - } - - bool CShape::IsItFitLine() - { - return (m_eGraphicsType == eGraphicsType::gtRectangle && (m_eSimpleLineType == eSimpleLineType::sltDot || m_eSimpleLineType == eSimpleLineType::sltDash || m_eSimpleLineType == eSimpleLineType::sltLongDash)) || - (m_eGraphicsType == eGraphicsType::gtCurve && m_eSimpleLineType == eSimpleLineType::sltWave); - } - - bool CShape::IsCorrelated(const CShape *pShape) - { - return m_eGraphicsType == pShape->m_eGraphicsType; - } - - void CShape::ChangeGeometryOfDesiredShape(CShape *pShape) - { - if (!pShape) - { - return; - } - - CShape* pModObject; - CShape* pDataObject; - - if (pShape->m_bIsNotNecessaryToUse) - { - pModObject = this; - pDataObject = pShape; - } - else if (m_bIsNotNecessaryToUse) - { - pModObject = pShape; - pDataObject = this; - } - else - { - return; - } - - double dModRight = pModObject->m_dLeft + pModObject->m_dWidth; - double dDataRight = pDataObject->m_dLeft + pDataObject->m_dWidth; - double dModBottom = pModObject->m_dTop + pModObject->m_dHeight; - double dDataBottom = pDataObject->m_dTop + pDataObject->m_dHeight; - - if (pModObject->m_dTop == pDataObject->m_dTop || - (pModObject->m_dTop < pDataObject->m_dTop && pModObject->m_dHeight > pDataObject->m_dHeight) || - (pModObject->m_dTop > pDataObject->m_dTop && pModObject->m_dHeight < pDataObject->m_dHeight)) - { - pModObject->m_dHeight = std::max(pModObject->m_dHeight, pDataObject->m_dHeight); - } - else if (pModObject->m_dTop < pDataObject->m_dTop) - { - pModObject->m_dHeight += pDataObject->m_dHeight + pDataObject->m_dTop - dModBottom; - } - else - { - pModObject->m_dHeight += pDataObject->m_dHeight + dDataBottom - pModObject->m_dTop; - } - - if (pModObject->m_dLeft == pDataObject->m_dLeft || - (pModObject->m_dLeft < pDataObject->m_dLeft && dModRight > dDataRight) || - (pModObject->m_dLeft > pDataObject->m_dLeft && dModRight < dDataRight)) - { - pModObject->m_dWidth = std::max(pModObject->m_dWidth, pDataObject->m_dWidth); - } - else if (pModObject->m_dLeft < pDataObject->m_dLeft) - { - pModObject->m_dWidth += pDataObject->m_dWidth + pDataObject->m_dLeft - dModRight; - } - else - { - pModObject->m_dWidth += pDataObject->m_dWidth + dDataRight - pModObject->m_dLeft; - } - - //note m_dWidth иногда меняет знак на "-" - pModObject->m_dHeight = fabs(pModObject->m_dHeight); - pModObject->m_dWidth = fabs(pModObject->m_dWidth); - pModObject->m_dLeft = std::min(pModObject->m_dLeft, pDataObject->m_dLeft); - pModObject->m_dTop = std::min(pModObject->m_dTop, pDataObject->m_dTop); - pModObject->m_dBaselinePos = pModObject->m_dTop + pModObject->m_dHeight; - pModObject->m_dRight = pModObject->m_dLeft + pModObject->m_dWidth; - } - - void CShape::DetermineLineType(CShape *pShape, bool bIsLast) - { - if (!pShape) - { - //Если нашелся один шейп в линии - if (m_eLineType == eLineType::ltUnknown && m_eSimpleLineType == eSimpleLineType::sltLongDash) - { - m_eLineType = m_dHeight > 0.3 ? eLineType::ltThick : eLineType::ltSingle; - } - else if (m_eLineType == eLineType::ltUnknown && m_eSimpleLineType == eSimpleLineType::sltWave) - { - m_eLineType = m_oPen.Size > 0.3 ? eLineType::ltWavyHeavy : eLineType::ltWave; - } - return; - } - - if (!IsItFitLine() || !pShape->IsItFitLine() || !IsCorrelated(pShape) || - fabs(m_dHeight - pShape->m_dHeight) > c_dGRAPHICS_ERROR_IN_LINES_MM) //линия должна быть одного размера по высоте - { - return; - } - - //Проверка на двойную линию - if (m_eLineType == eLineType::ltDouble || m_eLineType == eLineType::ltWavyDouble) - { - if (m_eLineType == eLineType::ltDouble) - { - if (m_dTop < pShape->m_dTop) - { - m_eLineType = eLineType::ltDouble; - pShape->m_bIsNotNecessaryToUse = true; - ChangeGeometryOfDesiredShape(pShape); - } - else - { - pShape->m_eLineType = eLineType::ltDouble; - m_bIsNotNecessaryToUse = true; - ChangeGeometryOfDesiredShape(pShape); - } - } - else if (m_eLineType == eLineType::ltWavyDouble) - { - if (m_dTop < pShape->m_dTop) - { - m_eLineType = eLineType::ltWavyDouble; - pShape->m_bIsNotNecessaryToUse = true; - ChangeGeometryOfDesiredShape(pShape); - } - else - { - pShape->m_eLineType = eLineType::ltWavyDouble; - m_bIsNotNecessaryToUse = true; - ChangeGeometryOfDesiredShape(pShape); - } - } - return; - } - else if (fabs(m_dTop - pShape->m_dTop) < c_dGRAPHICS_ERROR_IN_LINES_MM * 5 && - fabs(m_dWidth - pShape->m_dWidth) < c_dGRAPHICS_ERROR_IN_LINES_MM && - fabs(m_dLeft - pShape->m_dLeft) < c_dGRAPHICS_ERROR_IN_LINES_MM) - { - //Условие первого определения - if (m_eSimpleLineType == eSimpleLineType::sltLongDash && pShape->m_eSimpleLineType == eSimpleLineType::sltLongDash) - { - if (m_dTop < pShape->m_dTop) - { - m_eLineType = eLineType::ltDouble; - pShape->m_bIsNotNecessaryToUse = true; - ChangeGeometryOfDesiredShape(pShape); - } - else - { - pShape->m_eLineType = eLineType::ltDouble; - m_bIsNotNecessaryToUse = true; - ChangeGeometryOfDesiredShape(pShape); - } - } - else if (m_eSimpleLineType == eSimpleLineType::sltWave && pShape->m_eSimpleLineType == eSimpleLineType::sltWave) - { - if (m_dTop < pShape->m_dTop) - { - m_eLineType = eLineType::ltWavyDouble; - pShape->m_bIsNotNecessaryToUse = true; - ChangeGeometryOfDesiredShape(pShape); - } - else - { - pShape->m_eLineType = eLineType::ltWavyDouble; - m_bIsNotNecessaryToUse = true; - ChangeGeometryOfDesiredShape(pShape); - } - } - return; - } - else if (fabs(m_dTop - pShape->m_dTop) > c_dGRAPHICS_ERROR_IN_LINES_MM) - { - //все должно быть на одной линии - return; - } - - //Теперь считаем, что графика находится на одной линии - if (fabs(m_dLeft + m_dWidth - pShape->m_dLeft) > c_dGRAPHICS_ERROR_IN_LINES_MM * 5) - { - //расстояние между объектами на одной линии должно быть небольшим - if (m_eLineType == eLineType::ltUnknown && m_eSimpleLineType == eSimpleLineType::sltLongDash) - { - m_eLineType = m_dHeight > 0.3 ? eLineType::ltThick : eLineType::ltSingle; - } - else if (m_eLineType == eLineType::ltUnknown && m_eSimpleLineType == eSimpleLineType::sltWave) - { - m_eLineType = m_oPen.Size > 0.3 ? eLineType::ltWavyHeavy : eLineType::ltWave; - } - return; - } - - if (bIsLast) - { - //note Если имеем всего 2 шейпа в линии, то нужно специально определять тип - if (m_eLineType == eLineType::ltUnknown) - { - switch (m_eSimpleLineType) - { - case eSimpleLineType::sltDot: - if (pShape->m_eSimpleLineType == eSimpleLineType::sltDot) - { - m_eLineType = m_dHeight > 0.3 ? eLineType::ltDottedHeavy : eLineType::ltDotted; - } - break; - - case eSimpleLineType::sltDash: - if (pShape->m_eSimpleLineType == eSimpleLineType::sltDash) - { - m_eLineType = m_dHeight > 0.3 ? eLineType::ltDashedHeavy : eLineType::ltDash; - } - else if (pShape->m_eSimpleLineType == eSimpleLineType::sltDot) - { - m_eLineType = m_dHeight > 0.3 ? eLineType::ltDashDotHeavy : eLineType::ltDotDash; - } - break; - - case eSimpleLineType::sltLongDash: - if (fabs(m_dLeft + m_dWidth - pShape->m_dLeft) < 0.7) - { - m_eLineType = m_dHeight > 0.3 ? eLineType::ltThick : eLineType::ltSingle; - } - else - { - m_eLineType = m_dHeight > 0.3 ? eLineType::ltDashLongHeavy : eLineType::ltDashLong; - } - break; - - case eSimpleLineType::sltWave: - if (pShape->m_eSimpleLineType == eSimpleLineType::sltWave) - { - m_eLineType = m_oPen.Size > 0.3 ? eLineType::ltWavyHeavy : eLineType::ltWave; - } - break; - default: - break; - } - } - - pShape->m_bIsNotNecessaryToUse = true; - ChangeGeometryOfDesiredShape(pShape); - return; - } - - bool bIsConditionPassed = false; - - switch (m_eSimpleLineType) - { - case eSimpleLineType::sltDot: - if (pShape->m_eSimpleLineType == eSimpleLineType::sltDot) - { - if ((m_eLineType == eLineType::ltUnknown || m_eLineType == eLineType::ltDotted || - m_eLineType == eLineType::ltDottedHeavy) && pShape->m_eLineType == eLineType::ltUnknown) - { - m_eLineType = m_dHeight > 0.3 ? eLineType::ltDottedHeavy : eLineType::ltDotted; - bIsConditionPassed = true; - } - else if ((m_eLineType == eLineType::ltDotDash || m_eLineType == eLineType::ltDashDotHeavy || - m_eLineType == eLineType::ltDotDotDash || m_eLineType == eLineType::ltDashDotDotHeavy) && - pShape->m_eLineType == eLineType::ltUnknown) - { - m_eLineType = m_dHeight > 0.3 ? eLineType::ltDashDotDotHeavy : eLineType::ltDotDotDash; - m_eSimpleLineType = eSimpleLineType::sltDot; - bIsConditionPassed = true; - } - } - else if (pShape->m_eSimpleLineType == eSimpleLineType::sltDash) - { - if ((m_eLineType == eLineType::ltDotDash || m_eLineType == eLineType::ltDashDotHeavy) && - pShape->m_eLineType == eLineType::ltUnknown) - { - m_eSimpleLineType = eSimpleLineType::sltDash; - bIsConditionPassed = true; - } - else if ((m_eLineType == eLineType::ltDotDotDash || m_eLineType == eLineType::ltDashDotDotHeavy) && - pShape->m_eLineType == eLineType::ltUnknown) - { - m_eSimpleLineType = eSimpleLineType::sltDash; - bIsConditionPassed = true; - } - } - break; - case eSimpleLineType::sltDash: - if (pShape->m_eSimpleLineType == eSimpleLineType::sltDash) - { - if ((m_eLineType == eLineType::ltUnknown || m_eLineType == eLineType::ltDash || - m_eLineType == eLineType::ltDashedHeavy) && pShape->m_eLineType == eLineType::ltUnknown) - { - m_eLineType = m_dHeight > 0.3 ? eLineType::ltDashedHeavy : eLineType::ltDash; - bIsConditionPassed = true; - } - else if ((m_eLineType == eLineType::ltDotDash || m_eLineType == eLineType::ltDashDotHeavy) && - pShape->m_eLineType == eLineType::ltUnknown) - { - bIsConditionPassed = true; - } - } - else if (pShape->m_eSimpleLineType == eSimpleLineType::sltDot) - { - if ((m_eLineType == eLineType::ltUnknown || m_eLineType == eLineType::ltDotDash || - m_eLineType == eLineType::ltDashDotHeavy) && pShape->m_eLineType == eLineType::ltUnknown) - { - m_eLineType = m_dHeight > 0.3 ? eLineType::ltDashDotHeavy : eLineType::ltDotDash; - m_eSimpleLineType = eSimpleLineType::sltDot; - bIsConditionPassed = true; - } - else if ((m_eLineType == eLineType::ltDotDotDash || m_eLineType == eLineType::ltDashDotDotHeavy) && - pShape->m_eLineType == eLineType::ltUnknown) - { - m_eSimpleLineType = eSimpleLineType::sltDot; - bIsConditionPassed = true; - } - } - break; - - case eSimpleLineType::sltLongDash: - if (fabs(m_dLeft + m_dWidth - pShape->m_dLeft) < 0.7 || - m_eLineType == eLineType::ltThick || m_eLineType == eLineType::ltSingle) - { - m_eLineType = m_dHeight > 0.3 ? eLineType::ltThick : eLineType::ltSingle; - bIsConditionPassed = true; - } - else if ((m_eLineType == eLineType::ltUnknown || m_eLineType == eLineType::ltDashLong || - m_eLineType == eLineType::ltDashLongHeavy) && pShape->m_eLineType == eLineType::ltUnknown) - { - m_eLineType = m_dHeight > 0.3 ? eLineType::ltDashLongHeavy : eLineType::ltDashLong; - bIsConditionPassed = true; - } - break; - - case eSimpleLineType::sltWave: - if ((m_eLineType == eLineType::ltUnknown || m_eLineType == eLineType::ltWave || - m_eLineType == eLineType::ltWavyHeavy || m_eLineType == eLineType::ltWavyDouble) && - pShape->m_eLineType == eLineType::ltUnknown) - { - m_eLineType = m_oPen.Size > 0.3 ? eLineType::ltWavyHeavy : eLineType::ltWave; - bIsConditionPassed = true; - } - break; - default: - break; - } - - if (bIsConditionPassed) - { - pShape->m_bIsNotNecessaryToUse = true; - ChangeGeometryOfDesiredShape(pShape); - } - } - - void CShape::ToXml(NSStringUtils::CStringBuilder &oWriter) - { - //todo для уменьшения размера каждого шейпа ипользовавать только то, что необходимо - для графики, текста, графика+текст - //todo добавить все возможные параметры/атрибуты - - if (m_bIsNotNecessaryToUse) - { - return; - } - oWriter.WriteString(L""); - - oWriter.WriteString(L""); //отключение проверки орфографии - - oWriter.WriteString(L""); - - BuildGeneralProperties(oWriter); - - oWriter.WriteString(L""); - - oWriter.WriteString(L""); - } - - void CShape::BuildGeneralProperties(NSStringUtils::CStringBuilder &oWriter) - { - oWriter.WriteString(L"(m_bIsBehindDoc)); - oWriter.WriteString(L"\""); - oWriter.WriteString(L" locked=\"0\""); //true/1 Указывает, что местоположение привязки для этого объекта не должно быть изменено во время выполнения, когда приложение редактирует содержимое этого документа. - oWriter.WriteString(L" layoutInCell=\"0\""); //объект будет позиционирован, как указано, но таблица будет изменена в размерах и/или перемещена в документе, как это необходимо для размещения объекта. - oWriter.WriteString(L" allowOverlap=\"1\""); //разрешается перекрывать содержимое другого объекта - oWriter.WriteString(L" hidden=\"0\""); //Определяет, будет ли отображаться данный плавающий объект DrawingML. - oWriter.WriteString(L">"); - - oWriter.WriteString(L""); - - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.AddInt(static_cast(m_dLeft * c_dMMToEMU)); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.AddInt(static_cast(m_dTop * c_dMMToEMU)); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - - //координаты конца границы шейпа - oWriter.WriteString(L"(m_dWidth * c_dMMToEMU)); - oWriter.WriteString(L"\" cy=\""); - oWriter.AddInt(static_cast(m_dHeight * c_dMMToEMU)); - oWriter.WriteString(L"\"/>"); - - oWriter.WriteString(L""); //Этот элемент определяет дополнительное расстояние, которое должно быть добавлено к каждому краю изображения, чтобы компенсировать любые эффекты рисования, применяемые к объекту DrawingML - - oWriter.WriteString(L""); - - m_nShapeId = GenerateShapeId(); - - oWriter.WriteString(L""); - - oWriter.WriteString(L""); - - BuildSpecificProperties(oWriter); - - oWriter.WriteString(L""); - } - - void CShape::BuildSpecificProperties(NSStringUtils::CStringBuilder &oWriter) - { - oWriter.WriteString(L""); - - switch (m_eType) - { - case eShapeType::stPicture: - case eShapeType::stVectorTexture: - BuildPictureProperties(oWriter); - break; - case eShapeType::stCanvas: - BuildCanvasProperties(oWriter); - break; - case eShapeType::stGroup: - BuildGroupProperties(oWriter); - break; - case eShapeType::stTextBox: - case eShapeType::stVectorGraphics: - default: - BuildShapeProperties(oWriter); - break; - } - - oWriter.WriteString(L""); - } - - void CShape::BuildShapeProperties(NSStringUtils::CStringBuilder &oWriter) - { - oWriter.WriteString(L""); - - oWriter.WriteString(L""); - - oWriter.WriteString(L""); //non-visual shape properties. http://officeopenxml.com/drwSp-nvSpPr.php - - oWriter.WriteString(L""); //shape properties. http://officeopenxml.com/drwSp-SpPr.php - - //не работает - //oWriter.WriteString(L""); //shape styles. http://officeopenxml.com/drwSp-styles.php - - BuildGraphicProperties(oWriter); - - oWriter.WriteString(L""); - - BuildTextBox(oWriter); - - oWriter.WriteString(L""); - - oWriter.WriteString(L""); - } - - void CShape::BuildPictureProperties(NSStringUtils::CStringBuilder &oWriter) - { - oWriter.WriteString(L""); - - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L"m_nId); - oWriter.WriteString(L"\" name=\"Picture "); - oWriter.AddUInt(m_pImageInfo->m_nId); - oWriter.WriteString(L"\""); - //oWriter.WriteString(L" descr=\"Alt Text!\""); //Коммент к картинке - oWriter.WriteString(L"/>"); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L"m_nId); - oWriter.WriteString(L"\">"); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - - BuildGraphicProperties(oWriter); - - oWriter.WriteString(L""); - oWriter.WriteString(L""); - - oWriter.WriteString(L""); - } - - void CShape::BuildGroupProperties(NSStringUtils::CStringBuilder &oWriter) - { - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - BuildGraphicProperties(oWriter); - oWriter.WriteString(L""); - - //todo довабить любое количество элементов в группе - BuildPictureProperties(oWriter); - BuildShapeProperties(oWriter); - - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - } - - void CShape::BuildCanvasProperties(NSStringUtils::CStringBuilder &oWriter) - { - //todo добавить реализацию - oWriter.WriteString(L""); - } - - void CShape::BuildGraphicProperties(NSStringUtils::CStringBuilder &oWriter) - { - //отвечает за размеры прямоугольного фрейма шейпа - oWriter.WriteString(L" 0.01) - { - oWriter.WriteString(L" rot=\""); - oWriter.AddInt(static_cast(m_dRotate * c_dDegreeToAngle)); - oWriter.WriteString(L"\""); - } - oWriter.WriteString(L">"); - oWriter.WriteString(L""); - oWriter.WriteString(L"(m_dWidth * c_dMMToEMU)); - oWriter.WriteString(L"\" cy=\""); - oWriter.AddInt(static_cast(m_dHeight * c_dMMToEMU)); - oWriter.WriteString(L"\"/>"); - oWriter.WriteString(L""); - - //Если просто текст без графики - if (m_strPath.empty()) - { - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - } - else - { - //Рисуем сложный путь - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(m_strPath); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - } - - if (m_bIsNoFill) - { - //Нет заливки - oWriter.WriteString(L""); - } - else - { - //Есть заливка - oWriter.WriteString(L""); - oWriter.WriteString(L"(ConvertColorBGRToRGB(m_oBrush.Color1))); - if (0xFF != m_oBrush.TextureAlpha) - { - oWriter.WriteString(L"\">(m_oBrush.TextureAlpha / 255.0 * 100.0)); - oWriter.WriteString(L"%\"/>"); - } - else - { - oWriter.WriteString(L"\"/>"); - } - oWriter.WriteString(L""); - } - - if (m_bIsNoStroke) - { - oWriter.WriteString(L""); // w - width по умолчанию 0.75pt = 9525 - oWriter.WriteString(L""); - oWriter.WriteString(L""); - } - else - { - oWriter.WriteString(L"(m_oPen.Size * c_dMMToEMU)); //note можно писать в мм - oWriter.WriteString(L"\">"); - - oWriter.WriteString(L""); - - oWriter.WriteString(L"(ConvertColorBGRToRGB(m_oPen.Color))); //note можно вместо цвета использовать слова типа "black" - if (0xFF != m_oPen.Alpha) - { - oWriter.WriteString(L"\">(m_oPen.Alpha / 255.0 * 100.0)); - oWriter.WriteString(L"%\"/>"); - } - else - { - oWriter.WriteString(L"\"/>"); - } - - oWriter.WriteString(L""); - oWriter.WriteString(L""); - } - } - - void CShape::BuildTextBox(NSStringUtils::CStringBuilder &oWriter) - { - if (m_eType == eShapeType::stTextBox && !m_arParagraphs.empty()) - { - oWriter.WriteString(L""); //text within the shape. http://officeopenxml.com/drwSp-text.php - oWriter.WriteString(L""); - for (size_t i = 0; i < m_arParagraphs.size(); i++) - { - m_arParagraphs[i]->ToXml(oWriter); - } - oWriter.WriteString(L""); - oWriter.WriteString(L""); - - oWriter.WriteString(L"1) - oWriter.WriteString(L" rtlCol=\"0\""); //используются ли столбцы в порядке справа налево (true) или слева направо (false). - oWriter.WriteString(L" fromWordArt=\"0\""); //true/1 текст в этом текстовом поле является преобразованным текстом из объекта WordArt. - oWriter.WriteString(L" anchor=\"t\""); //Вертикальное выравнивание текста в шейпе (t - top, b - bottom, ctr - middle) по умолчанию top - oWriter.WriteString(L" anchorCtr=\"0\""); //true/1 Определяет центрирование текстового поля. - oWriter.WriteString(L" forceAA=\"0\""); //true/1 Заставляет текст отображаться сглаженным независимо от размера шрифта. - oWriter.WriteString(L" compatLnSpc=\"1\""); //межстрочный интервал для данного текста определяется упрощенным способом с помощью сцены шрифта. - oWriter.WriteString(L">"); - - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - } - else - { - oWriter.WriteString(L""); - } - } + UINT CShape::m_gRelativeHeight = c_iStandartRelativeHeight; + + unsigned int ClampUIntSign(const double& value) + { + if (value < 0) + return 0; + if (value > 0x7FFFFFFF) + return 0x7FFFFFFF; + return (unsigned int)value; + } + + CShape::CShape() + { + m_nRelativeHeight = m_gRelativeHeight; + m_gRelativeHeight += c_iStandartRelativeHeight; + } + + CShape::CShape(std::shared_ptr pInfo, const std::wstring& strDstMedia) : + m_strDstMedia(strDstMedia), m_pImageInfo(pInfo) + { + m_nRelativeHeight = m_gRelativeHeight; + m_gRelativeHeight += c_iStandartRelativeHeight; + } + + CShape::~CShape() + { + Clear(); + } + + void CShape::Clear() + { + m_arOutputObjects.clear(); + m_oVector.Clear(); + } + + UINT CShape::GenerateShapeId() + { + static UINT iId = 0; + iId++; + return iId; + } + + void CShape::ResetRelativeHeight() + { + m_gRelativeHeight = c_iStandartRelativeHeight; + } + + void CShape::SetVector(CVectorGraphics&& oVector) + { + m_oVector = std::move(oVector); + auto arData = m_oVector.GetData(); + + m_dLeft = m_oVector.GetLeft(); + m_dTop = m_oVector.GetTop(); + m_dWidth = m_oVector.GetRight() - m_dLeft; + m_dHeight = m_oVector.GetBottom() - m_dTop; + + size_t nPeacks = 0; + size_t nCurves = 0; + + for(auto& path_command : arData) + switch (path_command.type) + { + case CVectorGraphics::ePathCommandType::pctMove: + nPeacks++; + break; + + case CVectorGraphics::ePathCommandType::pctLine: + nPeacks++; + break; + + case CVectorGraphics::ePathCommandType::pctCurve: + nCurves++; + break; + + case CVectorGraphics::ePathCommandType::pctClose: + default: + break; + } + + DetermineGraphicsType(m_dWidth, m_dHeight, nPeacks, nCurves); + + if (m_dWidth < 0.0001) + m_dWidth = 0.0001; + if (m_dHeight < 0.0001) + m_dHeight = 0.0001; + + m_dBaselinePos = m_dTop + m_dHeight; + m_dRight = m_dLeft + m_dWidth; + } + + void CShape::CalcNoRotVector() + { + m_oNoRotVector = m_oVector; + m_oNoRotVector.Rotate(-m_dRotation); + } + + bool CShape::TryMergeShape(std::shared_ptr& pShape) + { + // можно попробовать подбирать динамически, например в зависимости от размера + double dHorNearby = 30; + double dVerNearby = 30; + + if( + // только для фигур + (pShape->m_eGraphicsType == eGraphicsType::gtComplicatedFigure || + pShape->m_eGraphicsType == eGraphicsType::gtRectangle) && + + (this->m_eGraphicsType == eGraphicsType::gtComplicatedFigure || + this->m_eGraphicsType == eGraphicsType::gtRectangle) && + + // все совпадает + pShape->m_eType == this->m_eType && + pShape->m_oPen.IsEqual(&m_oPen) && + pShape->m_oBrush.IsEqual(&m_oBrush) && + pShape->m_bIsNoFill == m_bIsNoFill && + pShape->m_bIsNoStroke == m_bIsNoStroke && + + // не картинка + pShape->m_pImageInfo == nullptr && + this->m_pImageInfo == nullptr && + + // недалеко друг от друга по горизонтали + (fabs(pShape->m_dRight - this->m_dLeft) < dHorNearby || + fabs(pShape->m_dLeft - this->m_dRight) < dHorNearby || + + // друг в друге тоже учитываем + fabs(pShape->m_dRight - this->m_dRight) < dHorNearby || + fabs(pShape->m_dLeft - this->m_dLeft) < dHorNearby) && + + // недалеко друг от друга по вертикали + (fabs(pShape->m_dBaselinePos - this->m_dTop) < dVerNearby || + fabs(pShape->m_dTop - this->m_dBaselinePos) < dVerNearby || + + // друг в друге + fabs(pShape->m_dBaselinePos - this->m_dBaselinePos) < dVerNearby || + fabs(pShape->m_dTop - this->m_dTop) < dVerNearby)) + { + RecalcWithNewItem(pShape.get()); + m_oVector.Join(std::move(pShape->m_oVector)); + pShape = nullptr; + + this->m_eGraphicsType = eGraphicsType::gtComplicatedFigure; + this->m_eLineType = eLineType::ltUnknown; + this->m_eSimpleLineType = eSimpleLineType::sltUnknown; + return true; + } + return false; + } + + std::wstring CShape::PathToWString() const + { + auto& vector = fabs(m_dRotation) > c_dMIN_ROTATION ? m_oNoRotVector : m_oVector; + auto& data = vector.GetData(); + + if (data.empty()) + return m_strDstMedia; + + double left = vector.GetLeft(); + double right = vector.GetRight(); + double top = vector.GetTop(); + double bot = vector.GetBottom(); + + double width = right - left; + double height = bot - top; + + NSStringUtils::CStringBuilder oWriter; + + oWriter.WriteString(L"(width * c_dMMToEMU)); + oWriter.WriteString(L"\" h=\""); + oWriter.AddUInt(static_cast(height * c_dMMToEMU)); + oWriter.WriteString(L"\">"); + + for(auto& path_command : data) + { + switch (path_command.type) + { + case CVectorGraphics::ePathCommandType::pctMove: + oWriter.WriteString(L""); + break; + + case CVectorGraphics::ePathCommandType::pctLine: + oWriter.WriteString(L""); + break; + + case CVectorGraphics::ePathCommandType::pctCurve: + oWriter.WriteString(L""); + break; + + case CVectorGraphics::ePathCommandType::pctClose: + default: + break; + } + + for(auto& point : path_command.points) + { + LONG lX = static_cast((point.x - left) * c_dMMToEMU); + LONG lY = static_cast((point.y - top) * c_dMMToEMU); + + oWriter.WriteString(L"(lX)); + oWriter.WriteString(L"\" y=\""); + oWriter.AddInt(static_cast(lY)); + oWriter.WriteString(L"\"/>"); + } + + switch (path_command.type) + { + case CVectorGraphics::ePathCommandType::pctMove: + oWriter.WriteString(L""); + break; + + case CVectorGraphics::ePathCommandType::pctLine: + oWriter.WriteString(L""); + break; + + case CVectorGraphics::ePathCommandType::pctCurve: + oWriter.WriteString(L""); + break; + + case CVectorGraphics::ePathCommandType::pctClose: + oWriter.WriteString(L""); + break; + default: + break; + } + } + oWriter.WriteString(L""); + std::wstring strPath = oWriter.GetData(); + oWriter.ClearNoAttack(); + return strPath; + } + + void CShape::DetermineGraphicsType(double dWidth, double dHeight,size_t nPeacks, size_t nCurves) noexcept + { + if ((m_bIsNoStroke && m_bIsNoFill) || (m_oBrush.Color1 == c_iWhiteColor && m_oPen.Color == c_iWhiteColor)) + m_eGraphicsType = eGraphicsType::gtNoGraphics; + else if ((nPeacks == 5 || nPeacks == 2) && !nCurves) //1 move + 4 Peacks или 2 Peacks + { + m_eGraphicsType = eGraphicsType::gtRectangle; + if (dHeight < 0.7) + { + if (dWidth > 2.0) // длинное тире - 2.8mm у times new roman + m_eSimpleLineType = eSimpleLineType::sltHLongDash; + else if (dWidth > 0.7) // минимальное тире - 0.75mm у dotDotDash + m_eSimpleLineType = eSimpleLineType::sltHDash; + else + m_eSimpleLineType = eSimpleLineType::sltHDot; // максимальная точка - 0.5mm + } + else if (dWidth < 0.7) + { + if (dHeight > 2.0) // длинное тире - 2.8mm у times new roman + m_eSimpleLineType = eSimpleLineType::sltVLongDash; + else if (dHeight > 0.7) // минимальное тире - 0.75mm у dotDotDash + m_eSimpleLineType = eSimpleLineType::sltVDash; + else + m_eSimpleLineType = eSimpleLineType::sltVDot; // максимальна точка - 0.5mm + } + } + else if (nCurves > 0 && nPeacks <= 1) // 1 move + { + m_eGraphicsType = eGraphicsType::gtCurve; + if (dHeight < dWidth) + m_eSimpleLineType = eSimpleLineType::sltHWave; + else + m_eSimpleLineType = eSimpleLineType::sltVWave; + } + else if (nCurves > 0 && nPeacks > 1) + m_eGraphicsType = eGraphicsType::gtComplicatedFigure; + } + + bool CShape::IsItFitLine() const noexcept + { + return (m_eGraphicsType == eGraphicsType::gtRectangle && ( + m_eSimpleLineType == eSimpleLineType::sltHDot || + m_eSimpleLineType == eSimpleLineType::sltHDash || + m_eSimpleLineType == eSimpleLineType::sltHLongDash)) || + (m_eGraphicsType == eGraphicsType::gtCurve && m_eSimpleLineType == eSimpleLineType::sltHWave); + } + + bool CShape::IsCorrelated(std::shared_ptr pShape) const noexcept + { + return m_eGraphicsType == pShape->m_eGraphicsType; + } + + bool CShape::IsPeak() const noexcept + { + return m_eSimpleLineType == eSimpleLineType::sltHDot || m_eSimpleLineType == eSimpleLineType::sltVDot; + } + + bool CShape::IsSide() const noexcept + { + return m_eSimpleLineType == eSimpleLineType::sltHLongDash || m_eSimpleLineType == eSimpleLineType::sltVLongDash; + } + bool CShape::IsOoxmlValid() const noexcept + { + bool is_offset = m_dLeft > c_dST_PositionOffsetMin && m_dTop > c_dST_PositionOffsetMin; + bool is_width = m_dWidth > c_dST_PositiveCoordinatetMin && m_dWidth < c_dST_PositiveCoordinatetMax; + bool is_height = m_dHeight > c_dST_PositiveCoordinatetMin && m_dHeight < c_dST_PositiveCoordinatetMax; + return is_offset && is_width && is_height; + } + + void CShape::CheckLineType(std::shared_ptr& pFirstShape) + { + if (!pFirstShape) + return; + + if (pFirstShape->m_eLineType == eLineType::ltUnknown && pFirstShape->m_eSimpleLineType == eSimpleLineType::sltHLongDash) + pFirstShape->m_eLineType = pFirstShape->m_dHeight > 0.3 ? eLineType::ltThick : eLineType::ltSingle; + + else if (pFirstShape->m_eLineType == eLineType::ltUnknown && pFirstShape->m_eSimpleLineType == eSimpleLineType::sltHWave) + pFirstShape->m_eLineType = pFirstShape->m_oPen.Size > 0.3 ? eLineType::ltWavyHeavy : eLineType::ltWave; + } + void CShape::CheckLineType(std::shared_ptr& pFirstShape, std::shared_ptr& pSecondShape, bool bIsLast) + { + if (!pFirstShape || !pSecondShape) + return; + + if (!pFirstShape->IsItFitLine() || !pSecondShape->IsItFitLine() || !pFirstShape->IsCorrelated(pSecondShape) || + fabs(pFirstShape->m_dHeight - pSecondShape->m_dHeight) > c_dGRAPHICS_ERROR_IN_LINES_MM) + { + return; // линия должна быть одного размера по высоте + } + + auto set_line_type = [] (std::shared_ptr& master, std::shared_ptr& slave, eLineType type) { + master->m_eLineType = type; + master->RecalcWithNewItem(slave.get()); + master->m_oVector.Join(std::move(slave->m_oVector)); + slave = nullptr; + }; + + // проверка на двойную линию + if (pFirstShape->m_eLineType == eLineType::ltDouble) + { + if (pFirstShape->m_dTop < pSecondShape->m_dTop) + set_line_type(pFirstShape, pSecondShape, eLineType::ltDouble); + else + set_line_type(pSecondShape, pFirstShape, eLineType::ltDouble); + + return; + } + if (pFirstShape->m_eLineType == eLineType::ltWavyDouble) + { + if (pFirstShape->m_dTop < pSecondShape->m_dTop) + set_line_type(pFirstShape, pSecondShape, eLineType::ltWavyDouble); + else + set_line_type(pSecondShape, pFirstShape, eLineType::ltWavyDouble); + + return; + } + + else if (fabs(pFirstShape->m_dTop - pSecondShape->m_dTop) < c_dGRAPHICS_ERROR_IN_LINES_MM * 5 && + fabs(pFirstShape->m_dWidth - pSecondShape->m_dWidth) < c_dGRAPHICS_ERROR_IN_LINES_MM && + fabs(pFirstShape->m_dLeft - pSecondShape->m_dLeft) < c_dGRAPHICS_ERROR_IN_LINES_MM) + { + // условие первого определения + if (pFirstShape->m_eSimpleLineType == eSimpleLineType::sltHLongDash && pSecondShape->m_eSimpleLineType == eSimpleLineType::sltHLongDash) + { + if (pFirstShape->m_dTop < pSecondShape->m_dTop) + set_line_type(pFirstShape, pSecondShape, eLineType::ltDouble); + else + set_line_type(pSecondShape, pFirstShape, eLineType::ltDouble); + } + else if (pFirstShape->m_eSimpleLineType == eSimpleLineType::sltHWave && pSecondShape->m_eSimpleLineType == eSimpleLineType::sltHWave) + { + if (pFirstShape->m_dTop < pSecondShape->m_dTop) + set_line_type(pFirstShape, pSecondShape, eLineType::ltWavyDouble); + else + set_line_type(pSecondShape, pFirstShape, eLineType::ltWavyDouble); + } + return; + } + else if (fabs(pFirstShape->m_dTop - pSecondShape->m_dTop) > c_dGRAPHICS_ERROR_IN_LINES_MM) + return; // все должно быть на одной линии + + // теперь считаем, что графика находится на одной линии + // расстояние между объектами на одной линии должно быть небольшим + if (fabs(pFirstShape->m_dLeft + pFirstShape->m_dWidth - pSecondShape->m_dLeft) > c_dGRAPHICS_ERROR_IN_LINES_MM * 5) + { + if (pFirstShape->m_eLineType == eLineType::ltUnknown && pFirstShape->m_eSimpleLineType == eSimpleLineType::sltHLongDash) + pFirstShape->m_eLineType = pFirstShape-> m_dHeight > 0.3 ? eLineType::ltThick : eLineType::ltSingle; + + else if (pFirstShape->m_eLineType == eLineType::ltUnknown && pFirstShape->m_eSimpleLineType == eSimpleLineType::sltHWave) + pFirstShape->m_eLineType = pFirstShape->m_oPen.Size > 0.3 ? eLineType::ltWavyHeavy : eLineType::ltWave; + + return; + } + + if (bIsLast) + { + // если имеем всего 2 шейпа в линии, то нужно специально определять тип + if (pFirstShape->m_eLineType == eLineType::ltUnknown) + { + switch (pFirstShape->m_eSimpleLineType) + { + case eSimpleLineType::sltHDot: + if (pSecondShape->m_eSimpleLineType == eSimpleLineType::sltHDot) + pFirstShape->m_eLineType = pFirstShape->m_dHeight > 0.3 ? eLineType::ltDottedHeavy : eLineType::ltDotted; + + break; + + case eSimpleLineType::sltHDash: + if (pSecondShape->m_eSimpleLineType == eSimpleLineType::sltHDash) + pFirstShape->m_eLineType = pFirstShape->m_dHeight > 0.3 ? eLineType::ltDashedHeavy : eLineType::ltDash; + + else if (pSecondShape->m_eSimpleLineType == eSimpleLineType::sltHDot) + pFirstShape->m_eLineType = pFirstShape->m_dHeight > 0.3 ? eLineType::ltDashDotHeavy : eLineType::ltDotDash; + + break; + + case eSimpleLineType::sltHLongDash: + if (fabs(pFirstShape->m_dLeft + pFirstShape->m_dWidth - pSecondShape->m_dLeft) < 0.7) + pFirstShape->m_eLineType = pFirstShape->m_dHeight > 0.3 ? eLineType::ltThick : eLineType::ltSingle; + + else + pFirstShape->m_eLineType = pFirstShape->m_dHeight > 0.3 ? eLineType::ltDashLongHeavy : eLineType::ltDashLong; + + break; + + case eSimpleLineType::sltHWave: + if (pSecondShape->m_eSimpleLineType == eSimpleLineType::sltHWave) + pFirstShape->m_eLineType = pFirstShape->m_oPen.Size > 0.3 ? eLineType::ltWavyHeavy : eLineType::ltWave; + + break; + default: + break; + } + } + + pFirstShape->RecalcWithNewItem(pSecondShape.get()); + pFirstShape->m_oVector.Join(std::move(pSecondShape->m_oVector)); + pSecondShape = nullptr; + return; + } + + bool passed = false; + switch (pFirstShape->m_eSimpleLineType) + { + case eSimpleLineType::sltHDot: + if (pSecondShape->m_eSimpleLineType == eSimpleLineType::sltHDot) + { + if ((pFirstShape->m_eLineType == eLineType::ltUnknown || pFirstShape->m_eLineType == eLineType::ltDotted || + pFirstShape->m_eLineType == eLineType::ltDottedHeavy) && pSecondShape->m_eLineType == eLineType::ltUnknown) + { + pFirstShape->m_eLineType = pFirstShape->m_dHeight > 0.3 ? eLineType::ltDottedHeavy : eLineType::ltDotted; + passed = true; + } + else if ((pFirstShape->m_eLineType == eLineType::ltDotDash || pFirstShape->m_eLineType == eLineType::ltDashDotHeavy || + pFirstShape->m_eLineType == eLineType::ltDotDotDash || pFirstShape->m_eLineType == eLineType::ltDashDotDotHeavy) && + pSecondShape->m_eLineType == eLineType::ltUnknown) + { + pFirstShape->m_eLineType = pFirstShape->m_dHeight > 0.3 ? eLineType::ltDashDotDotHeavy : eLineType::ltDotDotDash; + pFirstShape->m_eSimpleLineType = eSimpleLineType::sltHDot; + passed = true; + } + } + else if (pSecondShape->m_eSimpleLineType == eSimpleLineType::sltHDash) + { + if ((pFirstShape->m_eLineType == eLineType::ltDotDash || pFirstShape->m_eLineType == eLineType::ltDashDotHeavy) && + pSecondShape->m_eLineType == eLineType::ltUnknown) + { + pFirstShape->m_eSimpleLineType = eSimpleLineType::sltHDash; + passed = true; + } + else if ((pFirstShape->m_eLineType == eLineType::ltDotDotDash || pFirstShape->m_eLineType == eLineType::ltDashDotDotHeavy) && + pSecondShape->m_eLineType == eLineType::ltUnknown) + { + pFirstShape->m_eSimpleLineType = eSimpleLineType::sltHDash; + passed = true; + } + } + break; + + case eSimpleLineType::sltHDash: + if (pSecondShape->m_eSimpleLineType == eSimpleLineType::sltHDash) + { + if ((pFirstShape->m_eLineType == eLineType::ltUnknown || pFirstShape->m_eLineType == eLineType::ltDash || + pFirstShape->m_eLineType == eLineType::ltDashedHeavy) && pSecondShape->m_eLineType == eLineType::ltUnknown) + { + pFirstShape->m_eLineType = pFirstShape->m_dHeight > 0.3 ? eLineType::ltDashedHeavy : eLineType::ltDash; + passed = true; + } + else if ((pFirstShape->m_eLineType == eLineType::ltDotDash || pFirstShape->m_eLineType == eLineType::ltDashDotHeavy) && + pSecondShape->m_eLineType == eLineType::ltUnknown) + { + passed = true; + } + } + else if (pSecondShape->m_eSimpleLineType == eSimpleLineType::sltHDot) + { + if ((pFirstShape->m_eLineType == eLineType::ltUnknown || pFirstShape->m_eLineType == eLineType::ltDotDash || + pFirstShape->m_eLineType == eLineType::ltDashDotHeavy) && pSecondShape->m_eLineType == eLineType::ltUnknown) + { + pFirstShape->m_eLineType = pFirstShape->m_dHeight > 0.3 ? eLineType::ltDashDotHeavy : eLineType::ltDotDash; + pFirstShape->m_eSimpleLineType = eSimpleLineType::sltHDot; + passed = true; + } + else if ((pFirstShape->m_eLineType == eLineType::ltDotDotDash || pFirstShape->m_eLineType == eLineType::ltDashDotDotHeavy) && + pSecondShape->m_eLineType == eLineType::ltUnknown) + { + pFirstShape->m_eSimpleLineType = eSimpleLineType::sltHDot; + passed = true; + } + } + break; + + case eSimpleLineType::sltHLongDash: + if (fabs(pFirstShape->m_dLeft +pFirstShape->m_dWidth - pSecondShape->m_dLeft) < 0.7 || + pFirstShape->m_eLineType == eLineType::ltThick || pFirstShape->m_eLineType == eLineType::ltSingle) + { + pFirstShape->m_eLineType = pFirstShape->m_dHeight > 0.3 ? eLineType::ltThick : eLineType::ltSingle; + passed = true; + } + else if ((pFirstShape->m_eLineType == eLineType::ltUnknown || pFirstShape->m_eLineType == eLineType::ltDashLong || + pFirstShape->m_eLineType == eLineType::ltDashLongHeavy) && pSecondShape->m_eLineType == eLineType::ltUnknown) + { + pFirstShape->m_eLineType = pFirstShape->m_dHeight > 0.3 ? eLineType::ltDashLongHeavy : eLineType::ltDashLong; + passed = true; + } + break; + + case eSimpleLineType::sltHWave: + if ((pFirstShape->m_eLineType == eLineType::ltUnknown || pFirstShape->m_eLineType == eLineType::ltWave || + pFirstShape->m_eLineType == eLineType::ltWavyHeavy || pFirstShape->m_eLineType == eLineType::ltWavyDouble) && + pSecondShape->m_eLineType == eLineType::ltUnknown) + { + pFirstShape->m_eLineType = pFirstShape->m_oPen.Size > 0.3 ? eLineType::ltWavyHeavy : eLineType::ltWave; + passed = true; + } + break; + default: + break; + } + + if (passed) + { + pFirstShape->RecalcWithNewItem(pSecondShape.get()); + pFirstShape->m_oVector.Join(std::move(pSecondShape->m_oVector)); + pSecondShape = nullptr; + } + } + + void CShape::ToXml(NSStringUtils::CStringBuilder &oWriter) const + { + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + BuildGeneralProperties(oWriter); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + } + + void CShape::BuildGeneralProperties(NSStringUtils::CStringBuilder &oWriter) const + { + oWriter.WriteString(L"(m_bIsBehindDoc)); + oWriter.WriteString(L"\""); + oWriter.WriteString(L" locked=\"0\""); //true/1 Указывает, что местоположение привязки для этого объекта не должно быть изменено во время выполнения, когда приложение редактирует содержимое этого документа. + oWriter.WriteString(L" layoutInCell=\"0\""); //объект будет позиционирован, как указано, но таблица будет изменена в размерах и/или перемещена в документе, как это необходимо для размещения объекта. + oWriter.WriteString(L" allowOverlap=\"1\""); //разрешается перекрывать содержимое другого объекта + oWriter.WriteString(L" hidden=\"0\""); //Определяет, будет ли отображаться данный плавающий объект DrawingML. + oWriter.WriteString(L">"); + + oWriter.WriteString(L""); + + double left = fabs(m_dRotation) > c_dMIN_ROTATION ? m_oNoRotVector.GetLeft() : m_dLeft; + double right = fabs(m_dRotation) > c_dMIN_ROTATION ? m_oNoRotVector.GetRight() : m_dRight; + double top = fabs(m_dRotation) > c_dMIN_ROTATION ? m_oNoRotVector.GetTop() : m_dTop; + double bot = fabs(m_dRotation) > c_dMIN_ROTATION ? m_oNoRotVector.GetBottom() : m_dBaselinePos; + + double width = right - left; + double height = bot - top; + + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.AddInt64(static_cast(left * c_dMMToEMU)); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.AddInt64(static_cast(top * c_dMMToEMU)); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + + //координаты конца границы шейпа + oWriter.WriteString(L"(width * c_dMMToEMU)); + oWriter.WriteString(L"\" cy=\""); + oWriter.AddUInt(static_cast(height * c_dMMToEMU)); + oWriter.WriteString(L"\"/>"); + + oWriter.WriteString(L""); //Этот элемент определяет дополнительное расстояние, которое должно быть добавлено к каждому краю изображения, чтобы компенсировать любые эффекты рисования, применяемые к объекту DrawingML + oWriter.WriteString(L""); + + oWriter.WriteString(L""); + oWriter.WriteString(L""); + BuildSpecificProperties(oWriter); + oWriter.WriteString(L""); + } + + void CShape::BuildSpecificProperties(NSStringUtils::CStringBuilder &oWriter) const + { + oWriter.WriteString(L""); + + switch (m_eType) + { + case eShapeType::stVectorTexture: + BuildPictureProperties(oWriter); + break; + case eShapeType::stCanvas: + BuildCanvasProperties(oWriter); + break; + case eShapeType::stGroup: + BuildGroupProperties(oWriter); + break; + case eShapeType::stTextBox: + case eShapeType::stVectorGraphics: + default: + BuildShapeProperties(oWriter); + break; + } + + oWriter.WriteString(L""); + } + + void CShape::BuildShapeProperties(NSStringUtils::CStringBuilder &oWriter) const + { + oWriter.WriteString(L""); + + oWriter.WriteString(L""); + + oWriter.WriteString(L""); //non-visual shape properties. http://officeopenxml.com/drwSp-nvSpPr.php + + oWriter.WriteString(L""); //shape properties. http://officeopenxml.com/drwSp-SpPr.php + + //не работает + //oWriter.WriteString(L""); //shape styles. http://officeopenxml.com/drwSp-styles.php + BuildForm(oWriter); + BuildGraphicProperties(oWriter); + + oWriter.WriteString(L""); + + BuildTextBox(oWriter); + + oWriter.WriteString(L""); + + oWriter.WriteString(L""); + } + void CShape::BuildBlipFill(NSStringUtils::CStringBuilder &oWriter) const + { + oWriter.WriteString(L"m_nId); + oWriter.WriteString(L"\">"); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + if (m_oBrush.Image != NULL) + { + oWriter.WriteString(L""); + } + else + { + double left = fabs(m_dRotation) > c_dMIN_ROTATION ? m_oNoRotVector.GetLeft() : m_dLeft; + double right = fabs(m_dRotation) > c_dMIN_ROTATION ? m_oNoRotVector.GetRight() : m_dRight; + double top = fabs(m_dRotation) > c_dMIN_ROTATION ? m_oNoRotVector.GetTop() : m_dTop; + double bot = fabs(m_dRotation) > c_dMIN_ROTATION ? m_oNoRotVector.GetBottom() : m_dBaselinePos; + + double height = bot - top; + double width = right - left; + + // coeff + double offset_left = (right - m_dImageLeft) / width - 1; + double offset_right = (m_dImageRight - left) / width - 1; + double offset_top = (bot - m_dImageTop) / height - 1; + double offset_bot = (m_dImageBot - top) / height - 1; + + // percentage + offset_left *= 100; + offset_right *= 100; + offset_top *= 100; + offset_bot *= 100; + + // ooxml (percentage * 1000) + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L"(-offset_left * 1000)); + oWriter.WriteString(L"\" "); + oWriter.WriteString(L"r=\""); + oWriter.AddInt(static_cast(-offset_right * 1000)); + oWriter.WriteString(L"\" "); + oWriter.WriteString(L"t=\""); + oWriter.AddInt(static_cast(-offset_top * 1000)); + oWriter.WriteString(L"\" "); + oWriter.WriteString(L"b=\""); + oWriter.AddInt(static_cast(-offset_bot * 1000)); + oWriter.WriteString(L"\""); + oWriter.WriteString(L"/>"); + oWriter.WriteString(L""); + } + } + + void CShape::BuildPictureProperties(NSStringUtils::CStringBuilder &oWriter) const + { + oWriter.WriteString(L""); + + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L"m_nId); + oWriter.WriteString(L"\" name=\"Picture "); + oWriter.AddUInt(m_pImageInfo->m_nId); + oWriter.WriteString(L"\""); + oWriter.WriteString(L"/>"); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + BuildBlipFill(oWriter); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + + BuildForm(oWriter); + BuildGraphicProperties(oWriter); + + oWriter.WriteString(L""); + oWriter.WriteString(L""); + + oWriter.WriteString(L""); + } + + void CShape::BuildGroupProperties(NSStringUtils::CStringBuilder &oWriter) const + { + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + BuildForm(oWriter); + BuildGraphicProperties(oWriter); + oWriter.WriteString(L""); + + //todo довабить любое количество элементов в группе + BuildPictureProperties(oWriter); + BuildShapeProperties(oWriter); + + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + } + + void CShape::BuildCanvasProperties(NSStringUtils::CStringBuilder &oWriter) const + { + //todo добавить реализацию + oWriter.WriteString(L""); + } + + void CShape::BuildGraphicProperties(NSStringUtils::CStringBuilder &oWriter) const + { + std::wstring strPath = PathToWString(); + + //Если просто текст без графики + if (strPath.empty()) + { + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + } + else + { + //Рисуем сложный путь + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(strPath); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + } + + if (m_bIsNoFill) + { + oWriter.WriteString(L""); + } + else if (m_eType != CShape::eShapeType::stVectorTexture) + { + //Есть заливка + oWriter.WriteString(L""); + oWriter.WriteString(L"(ConvertColorBGRToRGB(m_oBrush.Color1))); + if (0xFF != m_oBrush.Alpha1) + { + oWriter.WriteString(L"\">(m_oBrush.Alpha1 / 255.0 * 100.0 * 1000)); + oWriter.WriteString(L"\"/>"); + } + else + { + oWriter.WriteString(L"\"/>"); + } + oWriter.WriteString(L""); + } + + if (m_bIsNoStroke) + { + oWriter.WriteString(L""); // w - width по умолчанию 0.75pt = 9525 + oWriter.WriteString(L""); + oWriter.WriteString(L""); + } + else + { + oWriter.WriteString(L"(m_oPen.Size * c_dMMToEMU)); //note можно писать в мм + oWriter.WriteString(L"\">"); + + oWriter.WriteString(L""); + + oWriter.WriteString(L"(ConvertColorBGRToRGB(m_oPen.Color))); //note можно вместо цвета использовать слова типа "black" + if (0xFF != m_oPen.Alpha) + { + oWriter.WriteString(L"\">(m_oPen.Alpha / 255.0 * 100.0)); + oWriter.WriteString(L"%\"/>"); + } + else + { + oWriter.WriteString(L"\"/>"); + } + + oWriter.WriteString(L""); + if (m_oPen.DashStyle == Aggplus::DashStyleCustom) + { + // dash pattern + std::vector dash_pattern(m_oPen.Count); + long count = m_oPen.Count; + m_oPen.GetDashPattern(dash_pattern.data(), count); + + oWriter.WriteString(L""); + for (size_t i = 0; i < count; i+= 2) + { + double to_percentage = 100.0 * 1000.0 / m_oPen.Size; + oWriter.WriteString(L""); + } + oWriter.WriteString(L""); + } + // Aggplus::DashStyleSolid + oWriter.WriteString(L""); + } + } + + void CShape::BuildForm(NSStringUtils::CStringBuilder &oWriter, const bool& bIsLT) const + { + double left = fabs(m_dRotation) > c_dMIN_ROTATION ? m_oNoRotVector.GetLeft() : m_dLeft; + double right = fabs(m_dRotation) > c_dMIN_ROTATION ? m_oNoRotVector.GetRight() : m_dRight; + double top = fabs(m_dRotation) > c_dMIN_ROTATION ? m_oNoRotVector.GetTop() : m_dTop; + double bot = fabs(m_dRotation) > c_dMIN_ROTATION ? m_oNoRotVector.GetBottom() : m_dBaselinePos; + + double height = bot - top; + double width = right - left; + + // отвечает за размеры прямоугольного фрейма шейпа + oWriter.WriteString(L" c_dMIN_ROTATION) + { + oWriter.WriteString(L" rot=\""); + oWriter.AddInt(static_cast(m_dRotation * c_dDegreeToAngle)); + oWriter.WriteString(L"\""); + } + oWriter.WriteString(L">"); + + if (!bIsLT) + { + oWriter.WriteString(L""); + } + else + { + oWriter.WriteString(L"(left * c_dMMToEMU)); + oWriter.WriteString(L"\" y=\""); + oWriter.AddInt64(static_cast(top * c_dMMToEMU)); + oWriter.WriteString(L"\"/>"); + } + + oWriter.WriteString(L"(width * c_dMMToEMU)); + oWriter.WriteString(L"\" cy=\""); + oWriter.AddUInt(static_cast(height * c_dMMToEMU)); + oWriter.WriteString(L"\"/>"); + + oWriter.WriteString(L""); + } + + void CShape::BuildTextBoxParams(NSStringUtils::CStringBuilder &oWriter) const + { + oWriter.WriteString(L" rot=\"0\""); //Определяет поворот, который применяется к тексту в пределах ограничивающей рамки. + oWriter.WriteString(L" spcFirstLastPara=\"0\""); //должен ли соблюдаться интервал между абзацами до и после, заданный пользователем. + oWriter.WriteString(L" vertOverflow=\"overflow\""); //может ли текст выходить за пределы ограничительной рамки по вертикали + oWriter.WriteString(L" horzOverflow=\"overflow\""); //может ли текст выходить за пределы ограничительной рамки по горизонтали. + oWriter.WriteString(L" vert=\"horz\""); + //oWriter.WriteString(L" wrap=\"none\""); //граница шейпа по ширине текста + oWriter.WriteString(L" wrap=\"square\""); //Определяет параметры обертки, которые будут использоваться для данного текстового тела. + //на сколько граница текста отступает от границы шейпа + oWriter.WriteString(L" lIns=\"0\""); //left по умолчанию 0.25см = 91440 + oWriter.WriteString(L" tIns=\"0\""); //top по умолчанию 0.13см = 45720 + oWriter.WriteString(L" rIns=\"0\""); //right по умолчанию 0.25см + oWriter.WriteString(L" bIns=\"0\""); //bottom по умолчанию 0.13см + oWriter.WriteString(L" numCol=\"1\""); //Определяет количество колонок текста в ограничивающем прямоугольнике. + oWriter.WriteString(L" spcCol=\"0\""); //Определяет пространство между колонками текста в текстовой области (только если numCol >1) + oWriter.WriteString(L" rtlCol=\"0\""); //используются ли столбцы в порядке справа налево (true) или слева направо (false). + oWriter.WriteString(L" fromWordArt=\"0\""); //true/1 текст в этом текстовом поле является преобразованным текстом из объекта WordArt. + oWriter.WriteString(L" anchor=\"t\""); //Вертикальное выравнивание текста в шейпе (t - top, b - bottom, ctr - middle) по умолчанию top + oWriter.WriteString(L" anchorCtr=\"0\""); //true/1 Определяет центрирование текстового поля. + oWriter.WriteString(L" forceAA=\"0\""); //true/1 Заставляет текст отображаться сглаженным независимо от размера шрифта. + oWriter.WriteString(L" compatLnSpc=\"1\""); //межстрочный интервал для данного текста определяется упрощенным способом с помощью сцены шрифта. + oWriter.WriteString(L">"); + + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + } + + void CShape::BuildTextBox(NSStringUtils::CStringBuilder &oWriter) const + { + if (m_eType == eShapeType::stTextBox && !m_arOutputObjects.empty()) + { + oWriter.WriteString(L""); //text within the shape. http://officeopenxml.com/drwSp-text.php + oWriter.WriteString(L""); + for (size_t i = 0; i < m_arOutputObjects.size(); ++i) + { + auto pObj = m_arOutputObjects[i]; + pObj->ToXml(oWriter); + } + oWriter.WriteString(L""); + oWriter.WriteString(L""); + + oWriter.WriteString(L""); + } + else + { + oWriter.WriteString(L""); + } + } + void CShape::ToXmlPptx(NSStringUtils::CStringBuilder &oWriter) const + { + if (m_eType == eShapeType::stVectorTexture) + { + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L"m_nId); + oWriter.WriteString(L"\" name=\"Picture "); + oWriter.AddUInt(m_pImageInfo->m_nId); + oWriter.WriteString(L"\"/>"); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + + oWriter.WriteString(L""); + BuildBlipFill(oWriter); + oWriter.WriteString(L""); + + oWriter.WriteString(L""); + BuildForm(oWriter, true); + BuildGraphicProperties(oWriter); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + return; + } + + oWriter.WriteString(L""); + oWriter.WriteString(L""); + + BuildForm(oWriter, true); + BuildGraphicProperties(oWriter); + oWriter.WriteString(L""); + + if (m_eType == eShapeType::stTextBox && !m_arOutputObjects.empty()) + { + oWriter.WriteString(L""); + oWriter.WriteString(L""); + + for (const auto& obj : m_arOutputObjects) + obj->ToXmlPptx(oWriter); + + oWriter.WriteString(L""); + } + oWriter.WriteString(L""); + } }; // namespace NSDocxRenderer diff --git a/DocxRenderer/src/logic/elements/Shape.h b/DocxRenderer/src/logic/elements/Shape.h index a96207695ae..0599b07b09b 100644 --- a/DocxRenderer/src/logic/elements/Shape.h +++ b/DocxRenderer/src/logic/elements/Shape.h @@ -1,91 +1,121 @@ #pragma once -#include "Paragraph.h" + +#include + +#include "../../../../DesktopEditor/graphics/structures.h" + #include "../../resources/ImageInfo.h" #include "../../resources/LinesTable.h" #include "../../resources/VectorGraphics.h" +#include "BaseItem.h" namespace NSDocxRenderer { - enum class eGraphicsType - { - gtUnknown, - gtRectangle, - gtCurve, - gtComplicatedFigure, - gtNoGraphics, - }; - - class CShape : public CBaseItem - { - public: - enum class eShapeType - { - stUnknown, - stTextBox, - stPicture, - stVectorGraphics, - stVectorTexture, - stGroup, - stCanvas, - }; - - public: - eShapeType m_eType {eShapeType::stUnknown}; - std::wstring m_strPath {L""}; - NSStructures::CBrush m_oBrush; - NSStructures::CPen m_oPen; - double m_dRotate {0.0}; - - bool m_bIsNoFill {true}; - bool m_bIsNoStroke {true}; - bool m_bIsBehindDoc {true}; - - eGraphicsType m_eGraphicsType {eGraphicsType::gtUnknown}; - eSimpleLineType m_eSimpleLineType {eSimpleLineType::sltUnknown}; - eLineType m_eLineType {eLineType::ltUnknown}; - - std::vector m_arParagraphs; - - std::shared_ptr m_pImageInfo {nullptr}; - - private: - UINT m_nShapeId {0}; - UINT m_nRelativeHeight {0}; - - static UINT m_gRelativeHeight; - - public: - CShape(); - virtual ~CShape(); - virtual void Clear() override final; - - CShape(std::shared_ptr pInfo, const std::wstring& strDstMedia); - - void GetDataFromVector(const CVectorGraphics& oVector); - - void WritePath(const CVectorGraphics& oVector); - - void DetermineGraphicsType(double dWidth, double dHeight, size_t nPeacks, size_t nCurves); - - bool IsItFitLine(); - bool IsCorrelated(const CShape* pShape); - void ChangeGeometryOfDesiredShape(CShape* pShape); - - void DetermineLineType(CShape* pShape = nullptr, bool bIsLast = false); - - virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) override final; - void BuildGeneralProperties(NSStringUtils::CStringBuilder &oWriter); - void BuildSpecificProperties(NSStringUtils::CStringBuilder &oWriter); - void BuildShapeProperties(NSStringUtils::CStringBuilder &oWriter); - void BuildPictureProperties(NSStringUtils::CStringBuilder &oWriter); - void BuildGroupProperties(NSStringUtils::CStringBuilder &oWriter); - void BuildCanvasProperties(NSStringUtils::CStringBuilder &oWriter); - void BuildGraphicProperties(NSStringUtils::CStringBuilder &oWriter); - void BuildTextBox(NSStringUtils::CStringBuilder &oWriter); - - static void ResetRelativeHeight(); - - private: - UINT GenerateShapeId(); - }; + enum class eGraphicsType + { + gtUnknown, + gtRectangle, + gtCurve, + gtComplicatedFigure, + gtNoGraphics, + }; + + class CShape : public CBaseItem + { + public: + enum class eShapeType + { + stUnknown, + stTextBox, + stVectorGraphics, + stVectorTexture, + stGroup, + stCanvas, + }; + + public: + eShapeType m_eType {eShapeType::stUnknown}; + + NSStructures::CBrush m_oBrush{}; + NSStructures::CPen m_oPen {}; + + CVectorGraphics m_oVector {}; + + // vector with rotation 0 (to write ooxml if m_dRotation is > c_dMinRotation) + CVectorGraphics m_oNoRotVector{}; + std::wstring m_strDstMedia {}; + + double m_dRotation {0.0}; + size_t m_nOrder {0}; + + bool m_bIsNoFill {true}; + bool m_bIsNoStroke {true}; + bool m_bIsBehindDoc {true}; + bool m_bIsUseInTable{false}; + + std::shared_ptr m_pImageInfo{nullptr}; + double m_dImageTop{}; + double m_dImageBot{}; + double m_dImageLeft{}; + double m_dImageRight{}; + + eGraphicsType m_eGraphicsType {eGraphicsType::gtUnknown}; + eSimpleLineType m_eSimpleLineType{eSimpleLineType::sltUnknown}; + eLineType m_eLineType {eLineType::ltUnknown}; + + std::vector> m_arOutputObjects; + + public: + CShape(); + CShape(std::shared_ptr pInfo, const std::wstring& strDstMedia); + virtual ~CShape(); + virtual void Clear() override final; + virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) const override final; + virtual void ToXmlPptx(NSStringUtils::CStringBuilder& oWriter)const override final; + + void SetVector(CVectorGraphics&& oVector); + void CalcNoRotVector(); + + // tries merge shape, return true if ok and pShape was deleted + bool TryMergeShape(std::shared_ptr& pShape); + + std::wstring PathToWString() const; + void DetermineGraphicsType(double dWidth, double dHeight, size_t nPeacks, size_t nCurves) noexcept; + + bool IsItFitLine() const noexcept; + bool IsCorrelated(std::shared_ptr pShape) const noexcept; + + bool IsPeak() const noexcept; + bool IsSide() const noexcept; + bool IsOoxmlValid() const noexcept; + + void BuildGeneralProperties(NSStringUtils::CStringBuilder &oWriter) const; + void BuildSpecificProperties(NSStringUtils::CStringBuilder &oWriter) const; + void BuildShapeProperties(NSStringUtils::CStringBuilder &oWriter) const; + void BuildPictureProperties(NSStringUtils::CStringBuilder &oWriter) const; + void BuildGroupProperties(NSStringUtils::CStringBuilder &oWriter) const; + void BuildCanvasProperties(NSStringUtils::CStringBuilder &oWriter) const; + void BuildGraphicProperties(NSStringUtils::CStringBuilder &oWriter) const; + void BuildTextBox(NSStringUtils::CStringBuilder &oWriter) const; + void BuildTextBoxParams(NSStringUtils::CStringBuilder &oWriter) const; + void BuildForm(NSStringUtils::CStringBuilder &oWriter, const bool& bIsLT = false) const; + void BuildBlipFill(NSStringUtils::CStringBuilder &oWriter) const; + + static void ResetRelativeHeight(); + + // check type of line and delete not needed shape + // one shape in line + static void CheckLineType(std::shared_ptr& pShape); + + // many shapes in line + static void CheckLineType(std::shared_ptr& pFirstShape, std::shared_ptr& pSecondShape, bool bIsLast = false); + + private: + + UINT m_nShapeId{0}; + UINT m_nRelativeHeight{0}; + + static UINT m_gRelativeHeight; + static UINT GenerateShapeId(); + }; } diff --git a/DocxRenderer/src/logic/elements/Table.cpp b/DocxRenderer/src/logic/elements/Table.cpp new file mode 100644 index 00000000000..f70646bfab6 --- /dev/null +++ b/DocxRenderer/src/logic/elements/Table.cpp @@ -0,0 +1,127 @@ +#include "Table.h" + +#include "../../resources/SingletonTemplate.h" +#include "../../resources/utils.h" + +namespace NSDocxRenderer +{ + void CTable::CCell::Clear() + { + m_arParagraphs.clear(); + } + void CTable::CCell::ToXml(NSStringUtils::CStringBuilder& oWriter) const + { + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L"(m_dWidth * c_dMMToDx)); + oWriter.WriteString(L"\"w:type=\"dxa\"/>"); + + oWriter.WriteString(L""); + + auto write_border = [&oWriter] (const CBorder& border, const std::wstring& prefix) { + oWriter.WriteString(L"(border.dWidth * c_dMMToPt / 8)); + oWriter.WriteString(L"\" w:space=\""); + oWriter.AddUInt(static_cast(border.dSpacing * c_dMMToPt)); + oWriter.WriteString(L"\" w:color=\""); + oWriter.WriteHexInt3(ConvertColorBGRToRGB(border.lColor)); + oWriter.WriteString(L"\" />"); + }; + + write_border(m_oBorderTop, L"top"); + write_border(m_oBorderBot, L"bot"); + write_border(m_oBorderLeft, L"left"); + write_border(m_oBorderRight, L"right"); + + oWriter.WriteString(L""); + oWriter.WriteString(L""); + + for (const auto& p : m_arParagraphs) + p->ToXml(oWriter); + + oWriter.WriteString(L""); + } + void CTable::CCell::ToXmlPptx(NSStringUtils::CStringBuilder& oWriter) const + { + + } + void CTable::CCell::AddParagraph(const paragraph_ptr_t& pParagraph) + { + m_arParagraphs.push_back(pParagraph); + } + + void CTable::CRow::Clear() + { + m_arCells.clear(); + } + void CTable::CRow::ToXml(NSStringUtils::CStringBuilder& oWriter) const + { + oWriter.WriteString(L""); + + oWriter.WriteString(L""); + oWriter.WriteString(L"(m_dHeight * c_dMMToDx)); + oWriter.WriteString(L"\" w:hRule=\"exact\"/>"); + oWriter.WriteString(L""); + + for (const auto& c : m_arCells) + c->ToXml(oWriter); + + oWriter.WriteString(L""); + } + void CTable::CRow::ToXmlPptx(NSStringUtils::CStringBuilder& oWriter) const + { + + } + void CTable::CRow::AddCell(const cell_ptr_t& pCell) + { + CBaseItem::RecalcWithNewItem(pCell.get()); + m_arCells.push_back(pCell); + } + bool CTable::CRow::IsEmpty() const + { + return m_arCells.empty(); + } + + void CTable::Clear() + { + m_arRows.clear(); + } + void CTable::ToXml(NSStringUtils::CStringBuilder& oWriter) const + { + oWriter.WriteString(L""); + + oWriter.WriteString(L""); + oWriter.WriteString(L"(m_dWidth * c_dMMToDx)); + oWriter.WriteString(L"\"w:type=\"dxa\"/>"); + oWriter.WriteString(L""); + + oWriter.WriteString(L""); + oWriter.WriteString(L""); + + for (const auto& r : m_arRows) + r->ToXml(oWriter); + + oWriter.WriteString(L""); + } + void CTable::ToXmlPptx(NSStringUtils::CStringBuilder& oWriter) const + { + + } + void CTable::AddRow(const row_ptr_t& pRow) + { + CBaseItem::RecalcWithNewItem(pRow.get()); + m_arRows.push_back(pRow); + } + bool CTable::IsEmpty() const + { + return m_arRows.empty(); + } + +} // namespace NSDocxRenderer diff --git a/DocxRenderer/src/logic/elements/Table.h b/DocxRenderer/src/logic/elements/Table.h new file mode 100644 index 00000000000..4c2ac69720b --- /dev/null +++ b/DocxRenderer/src/logic/elements/Table.h @@ -0,0 +1,82 @@ +#pragma once + +#include +#include + +#include "BaseItem.h" +#include "Paragraph.h" + +#include "../../resources/LinesTable.h" + +namespace NSDocxRenderer +{ + class CTable : public CBaseItem + { + public: + class CCell; + class CRow; + + using cell_ptr_t = std::shared_ptr; + using row_ptr_t = std::shared_ptr; + using paragraph_ptr_t = std::shared_ptr; + + public: + class CCell : public CBaseItem + { + public: + struct CBorder + { + double dWidth{}; + double dSpacing{}; + long lColor{}; + eLineType lineType{}; + }; + + CCell() = default; + virtual ~CCell() = default; + virtual void Clear() override final; + virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) const override final; + virtual void ToXmlPptx(NSStringUtils::CStringBuilder& oWriter) const override final; + + void AddParagraph(const paragraph_ptr_t& pParagraph); + + CBorder m_oBorderTop; + CBorder m_oBorderBot; + CBorder m_oBorderLeft; + CBorder m_oBorderRight; + + private: + std::vector m_arParagraphs; + }; + class CRow : public CBaseItem + { + public: + CRow() = default; + virtual ~CRow() = default; + virtual void Clear() override final; + virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) const override final; + virtual void ToXmlPptx(NSStringUtils::CStringBuilder& oWriter) const override final; + + void AddCell(const cell_ptr_t& pCell); + bool IsEmpty() const; + + private: + std::vector m_arCells; + }; + + CTable() = default; + virtual ~CTable() = default; + virtual void Clear() override final; + virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) const override final; + virtual void ToXmlPptx(NSStringUtils::CStringBuilder& oWriter) const override final; + + void AddRow(const row_ptr_t& pRow); + bool IsEmpty() const; + + private: + std::vector m_arRows; + }; +} // namespace NSDocxRenderer + + + diff --git a/DocxRenderer/src/logic/elements/TextLine.cpp b/DocxRenderer/src/logic/elements/TextLine.cpp index 96d38113cee..2d1905c0972 100644 --- a/DocxRenderer/src/logic/elements/TextLine.cpp +++ b/DocxRenderer/src/logic/elements/TextLine.cpp @@ -1,301 +1,342 @@ #include "TextLine.h" + +#include "../../logic/elements/Shape.h" #include "../../resources/Constants.h" -#include "../../resources/SortElements.h" #include "../../resources/utils.h" namespace NSDocxRenderer { - CTextLine::CTextLine() : CBaseItem(ElemType::etTextLine) - { - } - - void CTextLine::Clear() - { - m_arConts.clear(); - } - - CTextLine::~CTextLine() - { - Clear(); - } - - void CTextLine::AddCont(CContText *pCont) - { - m_dBaselinePos = std::max(m_dBaselinePos, pCont->m_dBaselinePos); - - if ( ( pCont->m_dLeft > 0 ) && ( ( m_dLeft == 0 ) || ( pCont->m_dLeft < m_dLeft ) ) ) - m_dLeft = pCont->m_dLeft; - - if (m_dHeight < pCont->m_dHeight) - m_dHeight = pCont->m_dHeight; - - if (m_dTop > pCont->m_dTop || m_dTop == 0.0) - m_dTop = pCont->m_dTop; - - if (pCont->m_pCont && m_eVertAlignType == eVertAlignType::vatUnknown) - { - m_eVertAlignType = pCont->m_eVertAlignType; - } - - m_arConts.push_back(pCont); - } - - bool CTextLine::IsBigger(const CBaseItem* oSrc) - { - return (m_dBaselinePos > dynamic_cast(oSrc)->m_dBaselinePos) ? true : false; - } - - bool CTextLine::IsBiggerOrEqual(const CBaseItem* oSrc) - { - return (m_dBaselinePos >= dynamic_cast(oSrc)->m_dBaselinePos) ? true : false; - } - - void CTextLine::SortConts() - { - // сортировка непрерывных слов по m_dX - SortElements(m_arConts); - } - - void CTextLine::Merge(CTextLine* pLine) - { - size_t nCount = pLine->m_arConts.size(); - if (0 != nCount) - { - if (pLine->m_dLeft < m_dLeft) - { - m_dLeft = pLine->m_dLeft; - } - if (pLine->m_dBaselinePos < m_dBaselinePos) - { - m_dHeight = (m_dBaselinePos - pLine->m_dBaselinePos + pLine->m_dHeight); - } - else - { - m_dHeight = (pLine->m_dBaselinePos - m_dBaselinePos + m_dHeight); - } - - for (const auto &pCont : pLine->m_arConts) - { - m_arConts.push_back(new CContText(*pCont)); - } - - SortConts(); - CalculateWidth(); - } - } - - void CTextLine::MergeConts() - { - if (m_arConts.empty()) - return; - - auto pFirst = m_arConts.front(); - - for (size_t i = 1; i < m_arConts.size(); ++i) - { - auto pCurrent = m_arConts[i]; - - if (pCurrent->m_bIsNotNecessaryToUse) - { - continue; - } - - bool bIsEqual = pFirst->IsEqual(pCurrent) && pFirst->m_eVertAlignType == pCurrent->m_eVertAlignType; - bool bIsBigDelta = fabs(pFirst->m_dRight - pCurrent->m_dLeft) > pFirst->CalculateThinSpace(); - bool bIsVeryBigDelta = fabs(pFirst->m_dRight - pCurrent->m_dLeft) > pFirst->CalculateWideSpace(); - - if (bIsVeryBigDelta) - { - pFirst->m_bSpaceIsNotNeeded = false; - pFirst = pCurrent; - - } - else if (bIsEqual) - { - if (bIsBigDelta) - { - pFirst->m_oText += L" "; - pFirst->m_dWidth += pFirst->m_dSpaceWidthMM; - } - - pFirst->m_oText += pCurrent->m_oText; - pFirst->m_dWidth += pCurrent->m_dWidth; - pFirst->m_dRight = pCurrent->m_dRight; - - pFirst->m_bSpaceIsNotNeeded = true; - pCurrent->m_bIsNotNecessaryToUse = true; - } - else - { - if (bIsBigDelta) - { - if (!IsSpaceUtf32(pFirst->m_oText[pFirst->m_oText.length()-1]) && - !IsSpaceUtf32(pCurrent->m_oText[0])) - { - if (pFirst->GetNumberOfFeatures() <= pCurrent->GetNumberOfFeatures()) - { - pFirst->m_oText += L" "; - pFirst->m_dWidth += pFirst->m_dSpaceWidthMM; - } - else - { - NSStringUtils::CStringUTF32 oNewText = L" "; - oNewText += pCurrent->m_oText; - pCurrent->m_oText = oNewText; - pCurrent->m_dWidth += pCurrent->m_dSpaceWidthMM; - } - } - - pFirst->m_bSpaceIsNotNeeded = true; - } - else - { - pFirst->m_bSpaceIsNotNeeded = false; - } - pFirst = pCurrent; - } - } - } - - void CTextLine::CalculateWidth() - { - if (m_arConts.empty()) - { - return; - } - - m_dWidth = m_arConts[0]->m_dWidth; - - for (size_t i = 1; i < m_arConts.size(); ++i) - { - m_dWidth += m_arConts[i]->m_dLeft - (m_arConts[i-1]->m_dLeft + m_arConts[i-1]->m_dWidth); - m_dWidth += m_arConts[i]->m_dWidth; - } - m_dRight = m_dLeft + m_dWidth; - } - - void CTextLine::DetermineAssumedTextAlignmentType(double dWidthOfPage) - { - //рассматриваем строки, которые короче трети ширины страницы - double maxTextLineWidth = dWidthOfPage/3; //нужна какая-нибудь отправная точка... - double delta = 2 * c_dCENTER_POSITION_ERROR_MM; //координата m_dWidth/2 +- c_dCENTER_POSITION_ERROR_MM - - if (fabs(dWidthOfPage/2 - m_dLeft - m_dWidth/2) <= delta && //если середины линий по x одинаковы - m_dWidth < maxTextLineWidth ) - { - m_eAlignmentType = atatByCenter; - } - else if ((m_dLeft + m_dWidth/2) > (dWidthOfPage/2 + c_dCENTER_POSITION_ERROR_MM) && //середина строки правее центра страницы - m_dWidth < maxTextLineWidth) - { - m_eAlignmentType = atatByRightEdge; - } - else if ((m_dLeft + m_dWidth/2) < (dWidthOfPage/2 - c_dCENTER_POSITION_ERROR_MM) && //середина строки левее центра страницы - m_dWidth < maxTextLineWidth) - { - m_eAlignmentType = atatByLeftEdge; - } - else if (fabs(dWidthOfPage/2 - m_dLeft - m_dWidth/2) <= delta && - m_dWidth > maxTextLineWidth + maxTextLineWidth/2 ) - { - m_eAlignmentType = atatByWidth; - } - else - { - m_eAlignmentType = atatUnknown; - } - } - - bool CTextLine::AreAlignmentsAppropriate(const CTextLine *pLine) - { - if ((m_eAlignmentType == pLine->m_eAlignmentType && m_eAlignmentType!= atatByLeftEdge) || - (m_eAlignmentType == atatByWidth && pLine->m_eAlignmentType == atatByLeftEdge) || - (m_eAlignmentType == atatByWidth && pLine->m_eAlignmentType == atatUnknown) || - (m_eAlignmentType == atatUnknown && pLine->m_eAlignmentType == atatByWidth)) - { - return true; - } - return false; - } - - void CTextLine::SetVertAlignType(const eVertAlignType& oType) - { - for (const auto &pCont : m_arConts) - { - pCont->m_eVertAlignType = oType; - } - } - - double CTextLine::CalculateBeforeSpacing(double dPreviousStringBaseline) - { - return m_dBaselinePos - dPreviousStringBaseline - m_dHeight; - } - - double CTextLine::CalculateRightBorder(const double& dPageWidth) - { - return dPageWidth - (m_dLeft + m_dWidth); - } - - bool CTextLine::IsForceBlock() - { - // линия отсортирована, так что сравниваем только соседние conts - size_t nCount = m_arConts.size(); - if (nCount <= 1) - return false; - - for (size_t i = 0; i < nCount; i++) - { - for (size_t j = i + 1; j < nCount; j++) - { - if (m_arConts[i]->GetIntersect(m_arConts[j]) > 10) - return true; - } - } - return false; - } - - void CTextLine::ToXml(NSStringUtils::CStringBuilder& oWriter) - { - if (m_bIsNotNecessaryToUse) - { - return; - } - - size_t nCountConts = m_arConts.size(); - - if (0 == nCountConts) - return; - - auto pPrev = m_arConts[0]; - double dDelta = 0; - - for (size_t i = 1; i < nCountConts; ++i) - { - auto pCurrent = m_arConts[i]; - - if (pCurrent->m_bIsNotNecessaryToUse) - { - continue; - } - - dDelta = pCurrent->m_dLeft - pPrev->m_dRight; - - if (dDelta < pPrev->CalculateWideSpace() || - pPrev->m_bSpaceIsNotNeeded) - { - // просто текст на тексте или сменились настройки (font/brush) - pPrev->ToXml(oWriter); - pPrev = pCurrent; - } - else - { - // расстояние слишком большое. нужно сделать большой пробел - pPrev->ToXml(oWriter); - pPrev->AddWideSpaceToXml(dDelta, oWriter, pPrev->IsEqual(pCurrent)); - pPrev = pCurrent; - } - } - - pPrev->ToXml(oWriter); - } + + CTextLine::~CTextLine() + { + Clear(); + } + + void CTextLine::Clear() + { + m_arConts.clear(); + m_pLine = nullptr; + } + void CTextLine::AddCont(std::shared_ptr oCont) + { + RecalcWithNewItem(oCont.get()); + m_arConts.push_back(oCont); + } + void CTextLine::AddConts(const std::vector>& arConts) + { + for (auto& cont : arConts) + AddCont(cont); + } + + bool CTextLine::IsCanBeDeleted() const + { + for (size_t i = 0; i < m_arConts.size(); ++i) + if (m_arConts[i]) + return false; + + return true; + } + + double CTextLine::GetLeftNoEnum() const noexcept + { + double left_no_enum = m_dLeft; + const auto& first_sym = m_arConts.front()->GetText().at(0); + + size_t i = 0, j = 0; + GetNextSym(i, j); + + if (CContText::IsUnicodeBullet(first_sym)) + { + while (CContText::IsUnicodeSpace(m_arConts[i]->GetText().at(j)) && i && j) GetNextSym(i, j); + + // one more time to get next + GetNextSym(i, j); + left_no_enum = (!i && !j) ? m_arConts.back()->m_dRight : m_arConts[i]->GetSymLefts().at(j); + } + return left_no_enum; + } + + void CTextLine::MergeConts() + { + if (m_arConts.empty()) + return; + + using cont_ptr_t = std::shared_ptr; + std::sort(m_arConts.begin(), m_arConts.end(), [] (const cont_ptr_t& a, const cont_ptr_t& b) { + if (!a) return false; + if (!b) return true; + return a->m_dLeft < b->m_dLeft; + }); + + std::shared_ptr pFirst; + size_t j = 0; + + for(; j < m_arConts.size() && !pFirst; ++j) + pFirst = m_arConts[j]; + + for (size_t i = j; i < m_arConts.size(); ++i) + { + auto& pCurrent = m_arConts[i]; + if (!pCurrent) + continue; + + double avg_space_width = pCurrent->m_pFontStyle->GetAvgSpaceWidth(); + double space_width = avg_space_width != 0.0 ? + avg_space_width * c_dAVERAGE_SPACE_WIDTH_COEF : + pCurrent->CalculateSpace() * c_dSPACE_WIDTH_COEF; + + double dDifference = pCurrent->m_dLeft - pFirst->m_dRight; + + bool bIsEqual = pFirst->IsEqual(pCurrent.get()); + bool bIsSpaceDelta = dDifference > space_width; + bool bIsWideSpaceDelta = dDifference > space_width * 3; + + if (bIsWideSpaceDelta || (pCurrent->m_bPossibleSplit && bIsSpaceDelta)) + { + if (CContText::IsUnicodeSpace(pFirst->GetLastSym())) + pFirst->RemoveLastSym(); + + auto wide_space = std::make_shared(pFirst->m_pManager); + + // sets all members for wide_space except highlight things + auto set_base = [&pFirst, &pCurrent, &wide_space] () { + wide_space->m_dLeft = pFirst->m_dRight; + wide_space->m_dRight = pCurrent->m_dLeft; + wide_space->m_dWidth = wide_space->m_dRight - wide_space->m_dLeft; + + wide_space->m_dBaselinePos = pCurrent->m_dBaselinePos; + wide_space->m_dTop = pCurrent->m_dTop; + + wide_space->m_dTopWithAscent = pCurrent->m_dTopWithAscent; + wide_space->m_dBotWithDescent = pCurrent->m_dBotWithDescent; + + wide_space->m_dHeight = pCurrent->m_dHeight; + + wide_space->SetSym(c_SPACE_SYM, wide_space->m_dRight - wide_space->m_dLeft); + wide_space->m_pFontStyle = pFirst->m_pFontStyle; + wide_space->m_pShape = nullptr; + wide_space->m_iNumDuplicates = 0; + }; + + if (bIsEqual) + { + // assign all + *wide_space = *pFirst; + + // then set all for wide space + set_base(); + } + else + set_base(); + + // pFrist cont contains only 1 space + if (pFirst->GetLength() == 0) + *pFirst = *wide_space; + else + { + m_arConts.insert(m_arConts.begin() + i, wide_space); + i++; + } + + while (!m_arConts[i] && i < m_arConts.size()) i++; + if (i == m_arConts.size()) break; + pFirst = m_arConts[i]; + } + else if (bIsEqual) + { + if (!bIsSpaceDelta) + { + pFirst->AddTextBack(pCurrent->GetText(), pCurrent->GetSymWidths()); + } + else + { + pFirst->AddSymBack(c_SPACE_SYM, pCurrent->m_dLeft - pFirst->m_dRight); + pFirst->AddTextBack(pCurrent->GetText(), pCurrent->GetSymWidths()); + } + + if (pFirst->m_pCont.expired()) + { + pFirst->m_pCont = pCurrent->m_pCont; + pFirst->m_eVertAlignType = pCurrent->m_eVertAlignType; + } + pCurrent = nullptr; + } + else + { + if (bIsSpaceDelta) + { + if (pFirst->GetNumberOfFeatures() <= pCurrent->GetNumberOfFeatures()) + pFirst->AddSymBack(c_SPACE_SYM, pCurrent->m_dLeft - pFirst->m_dRight); + else + pCurrent->AddSymFront(c_SPACE_SYM, pCurrent->m_dLeft - pFirst->m_dRight); + } + pFirst = pCurrent; + } + } + + auto right = MoveNullptr(m_arConts.begin(), m_arConts.end()); + m_arConts.erase(right, m_arConts.end()); + + using cont_ptr_t = std::shared_ptr; + std::sort(m_arConts.begin(), m_arConts.end(), [] (const cont_ptr_t& a, const cont_ptr_t& b) { + return a->m_dLeft < b->m_dLeft; + }); + } + + void CTextLine::CalcFirstWordWidth() + { + bool is_done = false; + double width = 0; + for (auto& cont : m_arConts) + { + if (!cont) + continue; + + const auto& text = cont->GetText(); + auto ar_widths = cont->GetSymWidths(); + for (size_t i = 0; i < text.length(); ++i) + { + if (text.at(i) == c_SPACE_SYM) + { + m_dFirstWordWidth = width; + is_done = true; + break; + } + width += ar_widths[i]; + } + if (is_done) + break; + } + if (!is_done) + m_dFirstWordWidth = m_dWidth; + } + + void CTextLine::RecalcSizes() + { + m_dLeft = 0.0; + m_dTop = 0.0; + m_dWidth = 0.0; + m_dHeight = 0.0; + m_dBaselinePos = 0.0; + m_dRight = 0.0; + m_dHeight = 0.0; + + for (const auto& cont : m_arConts) + if (cont) + RecalcWithNewItem(cont.get()); + } + + eVerticalCrossingType CTextLine::GetVerticalCrossingType(const CTextLine* pLine) const noexcept + { + const double& this_top = m_dTopWithMaxAscent; + const double& this_bot = m_dBotWithMaxDescent; + + const double& other_top = pLine->m_dTopWithMaxAscent; + const double& other_bot = pLine->m_dBotWithMaxDescent; + + if (this_top > other_top && this_bot < other_bot) + return eVerticalCrossingType::vctCurrentInsideNext; + + else if (this_top < other_top && this_bot > other_bot) + return eVerticalCrossingType::vctCurrentOutsideNext; + + else if (this_top < other_top && this_bot < other_bot && + (this_bot >= other_top || fabs(this_bot - other_top) < c_dTHE_SAME_STRING_Y_PRECISION_MM)) + return eVerticalCrossingType::vctCurrentAboveNext; + + else if (this_top > other_top && this_bot > other_bot && + (this_top <= other_bot || fabs(this_top - other_bot) < c_dTHE_SAME_STRING_Y_PRECISION_MM)) + return eVerticalCrossingType::vctCurrentBelowNext; + + else if (this_top == other_top && this_bot == other_bot && + m_dLeft == pLine->m_dLeft && m_dRight == pLine->m_dRight) + return eVerticalCrossingType::vctDublicate; + + else if (fabs(this_top - other_top) < c_dTHE_SAME_STRING_Y_PRECISION_MM && + fabs(this_bot - other_bot) < c_dTHE_SAME_STRING_Y_PRECISION_MM) + return eVerticalCrossingType::vctTopAndBottomBordersMatch; + + else if (fabs(this_top - other_top) < c_dTHE_SAME_STRING_Y_PRECISION_MM) + return eVerticalCrossingType::vctTopBorderMatch; + + else if (fabs(this_bot - other_bot) < c_dTHE_SAME_STRING_Y_PRECISION_MM) + return eVerticalCrossingType::vctBottomBorderMatch; + + else if (this_bot < other_top) + return eVerticalCrossingType::vctNoCrossingCurrentAboveNext; + + else if (this_top > other_bot) + return eVerticalCrossingType::vctNoCrossingCurrentBelowNext; + + else + return eVerticalCrossingType::vctUnknown; + } + + void CTextLine::RecalcWithNewItem(const CContText* pCont) + { + CBaseItem::RecalcWithNewItem(pCont); + if (m_dTopWithMaxAscent == 0.0) m_dTopWithMaxAscent = pCont->m_dTopWithAscent; + else m_dTopWithMaxAscent = std::min(m_dTopWithMaxAscent, pCont->m_dTopWithAscent); + + m_dBotWithMaxDescent = std::max(m_dBotWithMaxDescent, pCont->m_dBotWithDescent); + } + + void CTextLine::SetVertAlignType(const eVertAlignType& oType) + { + m_eVertAlignType = oType; + for (size_t i = 0; i < m_arConts.size(); ++i) + { + if(m_arConts[i]) + m_arConts[i]->m_eVertAlignType = oType; + } + } + + bool CTextLine::IsShadingPresent(const CTextLine *pLine) const noexcept + { + return (m_pDominantShape && pLine->m_pDominantShape && + m_pDominantShape->m_oBrush.Color1 == pLine->m_pDominantShape->m_oBrush.Color1 && + fabs(m_pDominantShape->m_dLeft - pLine->m_pDominantShape->m_dLeft) < c_dGRAPHICS_ERROR_IN_LINES_MM && + fabs(m_pDominantShape->m_dWidth - pLine->m_pDominantShape->m_dWidth) < c_dGRAPHICS_ERROR_IN_LINES_MM); + } + + void CTextLine::ToXml(NSStringUtils::CStringBuilder& oWriter) const + { + for (const auto& cont : m_arConts) + if(cont) + cont->ToXml(oWriter); + } + + void CTextLine::ToXmlPptx(NSStringUtils::CStringBuilder& oWriter) const + { + for (const auto& cont : m_arConts) + if(cont) + cont->ToXmlPptx(oWriter); + } + + size_t CTextLine::GetLength() const + { + size_t len = 0; + for (const auto& cont : m_arConts) + if (cont) + len += cont->GetLength(); + + return len; + } + void CTextLine::GetNextSym(size_t& nContPos, size_t& nSymPos) const noexcept + { + ++nSymPos; + if (m_arConts[nContPos]->GetLength() <= nSymPos) + for (nContPos = nContPos + 1; nContPos < m_arConts.size(); ++nContPos) + if (m_arConts[nContPos] && m_arConts[nContPos]->GetLength() != 0) + { + nSymPos = 0; + break; + } + + if (m_arConts.size() <= nContPos) + { + nContPos = 0; + nSymPos = 0; + } + } } diff --git a/DocxRenderer/src/logic/elements/TextLine.h b/DocxRenderer/src/logic/elements/TextLine.h index 3f0d7477bb2..05796a6e889 100644 --- a/DocxRenderer/src/logic/elements/TextLine.h +++ b/DocxRenderer/src/logic/elements/TextLine.h @@ -1,57 +1,58 @@ #pragma once #include "ContText.h" +#include "BaseItem.h" namespace NSDocxRenderer { - class CTextLine : public CBaseItem - { - public: - enum AssumedTextAlignmentType - { - atatUnknown, - atatByLeftEdge, - atatByCenter, - atatByRightEdge, - atatByWidth - }; - - std::vector m_arConts; - - AssumedTextAlignmentType m_eAlignmentType {atatUnknown}; - - eVertAlignType m_eVertAlignType {eVertAlignType::vatUnknown}; - - const CShape* m_pDominantShape {nullptr}; - - UINT m_iNumDuplicates {0}; - public: - CTextLine(); - void Clear() override final; - - ~CTextLine(); - - void AddCont(CContText *pCont); - bool IsBigger(const CBaseItem* oSrc) override final; - bool IsBiggerOrEqual(const CBaseItem* oSrc) override final; - void SortConts(); - - //Объединяем слова из двух строк - void Merge(CTextLine* pLine); - bool IsForceBlock(); - void ToXml(NSStringUtils::CStringBuilder& oWriter) override final; - - void MergeConts(); - //Вычисляем ширину сложной строки - void CalculateWidth(); - //Пытаемся понять тип выравнивания для текущей строки - void DetermineAssumedTextAlignmentType(double dWidthOfPage); - //Определяем на основании выравнивания подходят ли текущая и следующая строки для добавления в параграф - bool AreAlignmentsAppropriate(const CTextLine* pLine); - - void SetVertAlignType(const eVertAlignType& oType); - - //Вычисляем - double CalculateBeforeSpacing(double dPreviousStringBaseline); - double CalculateRightBorder(const double& dPageWidth); - }; + class CTextLine : public CBaseItem + { + public: + enum AssumedTextAlignmentType + { + atatUnknown, + atatByLeftEdge, + atatByCenter, + atatByRightEdge, + atatByWidth + }; + + std::vector> m_arConts; + + AssumedTextAlignmentType m_eAlignmentType{atatUnknown}; + eVertAlignType m_eVertAlignType {eVertAlignType::vatUnknown}; + + std::shared_ptr m_pLine; + std::shared_ptr m_pDominantShape {nullptr}; + + UINT m_iNumDuplicates {0}; + + double m_dTopWithMaxAscent{0}; + double m_dBotWithMaxDescent{0}; + + double m_dFirstWordWidth{0.0}; + + public: + CTextLine() = default; + virtual ~CTextLine(); + virtual void Clear() override final; + virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) const override final; + virtual void ToXmlPptx(NSStringUtils::CStringBuilder& oWriter) const override final; + virtual void RecalcWithNewItem(const CContText* pCont); + virtual eVerticalCrossingType GetVerticalCrossingType(const CTextLine* pLine) const noexcept; + + void AddCont(std::shared_ptr pCont); + void AddConts(const std::vector>& arConts); + void MergeConts(); + void CalcFirstWordWidth(); + void RecalcSizes(); + void SetVertAlignType(const eVertAlignType& oType); + + bool IsShadingPresent(const CTextLine* pLine) const noexcept; + bool IsCanBeDeleted() const; + + double GetLeftNoEnum() const noexcept; + + size_t GetLength() const; + void GetNextSym(size_t& nContPos, size_t& nSymPos) const noexcept; + }; } diff --git a/DocxRenderer/src/logic/managers/ExternalImageStorage.h b/DocxRenderer/src/logic/managers/ExternalImageStorage.h new file mode 100644 index 00000000000..77bcfd23d10 --- /dev/null +++ b/DocxRenderer/src/logic/managers/ExternalImageStorage.h @@ -0,0 +1,27 @@ +#pragma once +#include "../../../../DesktopEditor/graphics/Image.h" +#include "../../resources/ImageInfo.h" +#include + +#ifndef DOCXRENDERER_USE_DYNAMIC_LIBRARY +#define DOCXRENDERER_DECL_EXPORT +#else +#include "../../../../DesktopEditor/common/base_export.h" +#define DOCXRENDERER_DECL_EXPORT Q_DECL_EXPORT +#endif + +namespace NSDocxRenderer +{ + class DOCXRENDERER_DECL_EXPORT IImageStorage + { + public: + IImageStorage(); + virtual ~IImageStorage(); + + public: + virtual std::shared_ptr GenerateImageID(Aggplus::CImage* pImage) = 0; + virtual std::string* GetBase64(const int& nRId) = 0; + }; + + DOCXRENDERER_DECL_EXPORT IImageStorage* CreateWasmImageStorage(); +} diff --git a/DocxRenderer/src/logic/managers/FontManager.cpp b/DocxRenderer/src/logic/managers/FontManager.cpp index 78ea14ecb1f..f2a6c6b591f 100644 --- a/DocxRenderer/src/logic/managers/FontManager.cpp +++ b/DocxRenderer/src/logic/managers/FontManager.cpp @@ -1,258 +1,794 @@ #include "FontManager.h" + +#include "../../../../DesktopEditor/xml/include/xmlutils.h" +#include "../../../../DesktopEditor/common/Directory.h" +#include "../../../../DesktopEditor/common/StringExt.h" + #include "../../resources/Constants.h" + namespace NSDocxRenderer { - CFontTableEntry::CFontTableEntry(const CFontTableEntry& oSrc) - { - *this = oSrc; - } - - CFontTableEntry& CFontTableEntry::operator =(const CFontTableEntry& oSrc) - { - if (this == &oSrc) - { - return *this; - } - - m_strFamilyName = oSrc.m_strFamilyName; - m_strPANOSE = oSrc.m_strPANOSE; - m_lStyle = oSrc.m_lStyle; - m_arSignature = oSrc.m_arSignature; - m_bIsFixedWidth = oSrc.m_bIsFixedWidth; - - return *this; - } - - CFontManager::CFontManager(NSFonts::IApplicationFonts* pFonts) : CFontManagerBase(pFonts) - { - } - - void CFontManager::Init() - { - m_oFontTable.m_mapTable.clear(); - ClearPickUps(); - } - - void CFontManager::AddFontToMap() - { - if (m_oFontTable.m_mapTable.end() == m_oFontTable.m_mapTable.find(m_oFont.m_strFamilyName)) - { - CFontTableEntry oEntry; - oEntry.m_strFamilyName = m_oFont.m_strFamilyName; - oEntry.m_strPANOSE = m_oFont.m_strPANOSE; - oEntry.m_lStyle = m_oFont.m_lStyle; - oEntry.m_bIsFixedWidth = m_oFont.m_bIsFixedWidth; - oEntry.m_arSignature = m_oFont.m_arSignature; - - m_oFontTable.m_mapTable.insert(std::pair(m_oFont.m_strFamilyName, oEntry)); - } - } - - void CFontManager::LoadFont(long lFaceIndex, bool bNeedAddToMap) - { - if (nullptr == m_pManager) - return; - - double dSize = m_pFont->Size; - double dSizeFont = dSize * ((m_pTransform->sx() + m_pTransform->sy()) / 2); - - double dPix = m_pFont->CharSpace / c_dPixToMM; - - m_pFont->Size = dSizeFont; - - if (m_pFont->IsEqual2(&m_oFont.m_oFont)) - { - m_pFont->Size = dSize; - m_pManager->SetCharSpacing(dPix); - return; - } - - m_oFont.m_oFont = *m_pFont; - m_pFont->Size = dSize; - - if (m_pFont->Path.empty()) - { - CFontManagerBase::LoadFontByName(m_oFont.m_oFont.Name, m_oFont.m_oFont.Size, m_oFont.m_oFont.GetStyle(), c_dDpiX, c_dDpiY); - } - else - { - CFontManagerBase::LoadFontByFile(m_oFont.m_oFont.Path, m_oFont.m_oFont.Size, c_dDpiX, c_dDpiY, lFaceIndex); - - m_pFont->SetStyle(m_oFont.m_lStyle); - m_oFont.m_oFont.SetStyle(m_oFont.m_lStyle); - } - - int bIsGID = m_pManager->GetStringGID(); - m_pManager->SetStringGID(FALSE); - - m_pManager->LoadString2(L" ", 0, 0); - TBBox bbox = m_pManager->MeasureString2(); - - m_dSpaceWidthMM = (double)(bbox.fMaxX - bbox.fMinX) * c_dPixToMM; - if (0 >= m_dSpaceWidthMM) - { - m_dSpaceWidthMM = 1.0; - } - - m_pManager->SetStringGID(bIsGID); - - if (bNeedAddToMap) - AddFontToMap(); - } - - void CFontManager::MeasureString(const std::wstring& sText, double x, double y, double& dBoxX, double& dBoxY, double& dBoxWidth, double& dBoxHeight, MeasureType measureType) - { - LoadFont(); - - dBoxX = 0; - dBoxY = 0; - dBoxWidth = 0; - dBoxHeight = 0; - - if (nullptr == m_pManager) - return; - - m_pManager->LoadString1(sText, (float)x, (float)y); - - TBBox bbox; - if (mtGlyph == measureType) - { - bbox = m_pManager->MeasureString(); - } - else if (mtPosition == measureType) - { - bbox = m_pManager->MeasureString2(); - } - - dBoxX = (double)bbox.fMinX; - dBoxY = (double)bbox.fMinY; - dBoxWidth = (double)(bbox.fMaxX - bbox.fMinX); - dBoxHeight = (double)(bbox.fMaxY - bbox.fMinY); - - // переводим в миллиметры - dBoxX *= c_dPixToMM; - dBoxY *= c_dPixToMM; - dBoxWidth *= c_dPixToMM; - dBoxHeight *= c_dPixToMM; - } - - void CFontManager::MeasureStringGids(unsigned int* pGids, unsigned int count, double x, double y, double& dBoxX, double& dBoxY, double& dBoxWidth, double& dBoxHeight, MeasureType measureType) - { - LoadFont(); - - dBoxX = 0; - dBoxY = 0; - dBoxWidth = 0; - dBoxHeight = 0; - - if (nullptr == m_pManager) - return; - - m_pManager->LoadString1(pGids, count, (float)x, (float)y); - - TBBox bbox; - if (mtGlyph == measureType) - { - bbox = m_pManager->MeasureString(); - } - else if (mtPosition == measureType) - { - bbox = m_pManager->MeasureString2(); - } - - dBoxX = (double)bbox.fMinX; - dBoxY = (double)bbox.fMinY; - dBoxWidth = (double)(bbox.fMaxX - bbox.fMinX); - dBoxHeight = (double)(bbox.fMaxY - bbox.fMinY); - - // переводим в миллиметры - dBoxX *= c_dPixToMM; - dBoxY *= c_dPixToMM; - dBoxWidth *= c_dPixToMM; - dBoxHeight *= c_dPixToMM; - } - - double CFontManager::GetBaseLineOffset() - { - LoadFont(); - - double d1 = 3 * (m_oFont.m_dLineSpacing - m_oFont.m_dDescent) - m_oFont.m_dAscent; - d1 /= 2.0; - - d1 *= (m_oFont.m_oFont.Size / m_oFont.m_dEmHeight); - return d1; - } - - double CFontManager::GetFontHeight() - { - return c_dPtToMM * (m_oFont.m_dLineSpacing * m_oFont.m_oFont.Size ) / m_oFont.m_dEmHeight; - } - - void CFontManager::SetStringGid(const LONG& lGid) - { - if (nullptr != m_pManager) - m_pManager->SetStringGID(lGid); - } - - void CFontManager::GenerateFontName2(NSStringUtils::CStringUTF32& oText) - { - bool bIsNeedAddToMap = CFontManagerBase::GenerateFontName(oText); - - if (bIsNeedAddToMap) - { - if (m_oFontTable.m_mapTable.end() == m_oFontTable.m_mapTable.find(m_strCurrentPickFont)) - { - CFontTableEntry oEntry; - oEntry.m_strFamilyName = m_strCurrentPickFont; - oEntry.m_strPANOSE = m_oFont.m_strPANOSE; - oEntry.m_lStyle = m_oFont.m_lStyle; - oEntry.m_bIsFixedWidth = m_oFont.m_bIsFixedWidth; - oEntry.m_arSignature = m_oFont.m_arSignature; - - m_oFontTable.m_mapTable.insert(std::pair(m_oFont.m_strFamilyName, oEntry)); - } - } - } - - CFontManagerLight::CFontManagerLight(NSFonts::IApplicationFonts* pFonts) - { - m_pManager = NSFontManager::CreateFontManager(pFonts); - } - - CFontManagerLight::~CFontManagerLight() - { - RELEASEINTERFACE(m_pManager); - } - - double CFontManagerLight::GetSpaceWidth() - { - return m_dSpaceWidth; - } - - void CFontManagerLight::LoadFont(std::wstring& strFontName, LONG& lStyle, const double& dSize, const bool& bIsGID) - { - if ((strFontName == m_strFontName) && (lStyle == m_lFontStyle) && (dSize == m_dSize)) - { - m_pManager->SetStringGID(bIsGID); - return; - } - - m_strFontName = strFontName; - m_lFontStyle = lStyle; - m_dSize = dSize; - - m_pManager->LoadFontByName(strFontName, m_dSize, m_lFontStyle, c_dDpiX, c_dDpiY); - m_dSpaceWidth = MeasureStringWidth(L" "); - - m_pManager->SetStringGID(bIsGID); - } - - double CFontManagerLight::MeasureStringWidth(const std::wstring& sText) - { - m_pManager->LoadString2(sText, (float)0, (float)0); - TBBox bbox = m_pManager->MeasureString2(); - - return (bbox.fMaxX - bbox.fMinX) * c_dPixToMM; - } + CUnicodeRange::CUnicodeRange(const int& _start, const int& _end, + const BYTE& _range, const BYTE& _rangenum): + RangeNum(_rangenum), Range(_range), Start(_start), End(_end) + { + } + + CUnicodeRanges::CUnicodeRanges() + { + // https://docs.microsoft.com/en-us/typography/opentype/spec/os2#ur + + m_arRanges.push_back(CUnicodeRange(0x0000, 0x007F, 0, 0)); // Basic Latin + m_arRanges.push_back(CUnicodeRange(0x0080, 0x00FF, 1, 0)); // Latin-1 Supplement + m_arRanges.push_back(CUnicodeRange(0x0100, 0x017F, 2, 0)); // Latin Extended-A + m_arRanges.push_back(CUnicodeRange(0x0180, 0x024F, 3, 0)); // Latin Extended-B + m_arRanges.push_back(CUnicodeRange(0x0250, 0x02AF, 4, 0)); // IPA Extensions + m_arRanges.push_back(CUnicodeRange(0x1D00, 0x1D7F, 4, 0)); // Phonetic Extensions + m_arRanges.push_back(CUnicodeRange(0x1D80, 0x1DBF, 4, 0)); // Phonetic Extensions Supplement + m_arRanges.push_back(CUnicodeRange(0x02B0, 0x02FF, 5, 0)); // Spacing Modifier Letters + m_arRanges.push_back(CUnicodeRange(0xA700, 0xA71F, 5, 0)); // Modifier Tone Letters + m_arRanges.push_back(CUnicodeRange(0x0300, 0x036F, 6, 0)); // Combining Diacritical Marks + m_arRanges.push_back(CUnicodeRange(0x1DC0, 0x1DFF, 6, 0)); // Combining Diacritical Marks Supplement + m_arRanges.push_back(CUnicodeRange(0x0370, 0x03FF, 7, 0)); // Greek and Coptic + m_arRanges.push_back(CUnicodeRange(0x2C80, 0x2CFF, 8, 0)); // Coptic + m_arRanges.push_back(CUnicodeRange(0x0400, 0x04FF, 9, 0)); // Cyrillic + m_arRanges.push_back(CUnicodeRange(0x0500, 0x052F, 9, 0)); // Cyrillic Supplement + m_arRanges.push_back(CUnicodeRange(0x2DE0, 0x2DFF, 9, 0)); // Cyrillic Extended-A + m_arRanges.push_back(CUnicodeRange(0xA640, 0xA69F, 9, 0)); // Cyrillic Extended-B + m_arRanges.push_back(CUnicodeRange(0x0530, 0x058F, 10, 0)); // Armenian + m_arRanges.push_back(CUnicodeRange(0x0590, 0x05FF, 11, 0)); // Hebrew + m_arRanges.push_back(CUnicodeRange(0xA500, 0xA63F, 12, 0)); // Vai + m_arRanges.push_back(CUnicodeRange(0x0600, 0x06FF, 13, 0)); // Arabic + m_arRanges.push_back(CUnicodeRange(0x0750, 0x077F, 13, 0)); // Arabic Supplement + m_arRanges.push_back(CUnicodeRange(0x07C0, 0x07FF, 14, 0)); // NKo + m_arRanges.push_back(CUnicodeRange(0x0900, 0x097F, 15, 0)); // Devanagari + m_arRanges.push_back(CUnicodeRange(0x0980, 0x09FF, 16, 0)); // Bengali + m_arRanges.push_back(CUnicodeRange(0x0A00, 0x0A7F, 17, 0)); // Gurmukhi + m_arRanges.push_back(CUnicodeRange(0x0A80, 0x0AFF, 18, 0)); // Gujarati + m_arRanges.push_back(CUnicodeRange(0x0B00, 0x0B7F, 19, 0)); // Oriya + m_arRanges.push_back(CUnicodeRange(0x0B80, 0x0BFF, 20, 0)); // Tamil + m_arRanges.push_back(CUnicodeRange(0x0C00, 0x0C7F, 21, 0)); // Telugu + m_arRanges.push_back(CUnicodeRange(0x0C80, 0x0CFF, 22, 0)); // Kannada + m_arRanges.push_back(CUnicodeRange(0x0D00, 0x0D7F, 23, 0)); // Malayalam + m_arRanges.push_back(CUnicodeRange(0x0E00, 0x0E7F, 24, 0)); // Thai + m_arRanges.push_back(CUnicodeRange(0x0E80, 0x0EFF, 25, 0)); // Lao + m_arRanges.push_back(CUnicodeRange(0x10A0, 0x10FF, 26, 0)); // Georgian + m_arRanges.push_back(CUnicodeRange(0x2D00, 0x2D2F, 26, 0)); // Georgian Supplement + m_arRanges.push_back(CUnicodeRange(0x1B00, 0x1B7F, 27, 0)); // Balinese + m_arRanges.push_back(CUnicodeRange(0x1100, 0x11FF, 28, 0)); // Hangul Jamo + m_arRanges.push_back(CUnicodeRange(0x1E00, 0x1EFF, 29, 0)); // Latin Extended Additional + m_arRanges.push_back(CUnicodeRange(0x2C60, 0x2C7F, 29, 0)); // Latin Extended-C + m_arRanges.push_back(CUnicodeRange(0xA720, 0xA7FF, 29, 0)); // Latin Extended-D + m_arRanges.push_back(CUnicodeRange(0x1F00, 0x1FFF, 30, 0)); // Greek Extended + m_arRanges.push_back(CUnicodeRange(0x2000, 0x206F, 31, 0)); // General Punctuation + m_arRanges.push_back(CUnicodeRange(0x2E00, 0x2E7F, 31, 0)); // Supplemental Punctuation + + m_arRanges.push_back(CUnicodeRange(0x2070, 0x209F, 0, 1)); // Superscripts And Subscripts + m_arRanges.push_back(CUnicodeRange(0x20A0, 0x20CF, 1, 1)); // Currency Symbols + m_arRanges.push_back(CUnicodeRange(0x20D0, 0x20FF, 2, 1)); // Combining Diacritical Marks For Symbols + m_arRanges.push_back(CUnicodeRange(0x2100, 0x214F, 3, 1)); // Letterlike Symbols + m_arRanges.push_back(CUnicodeRange(0x2150, 0x218F, 4, 1)); // Number Forms + m_arRanges.push_back(CUnicodeRange(0x2190, 0x21FF, 5, 1)); // Arrows + m_arRanges.push_back(CUnicodeRange(0x27F0, 0x27FF, 5, 1)); // Supplemental Arrows-A + m_arRanges.push_back(CUnicodeRange(0x2900, 0x297F, 5, 1)); // Supplemental Arrows-B + m_arRanges.push_back(CUnicodeRange(0x2B00, 0x2BFF, 5, 1)); // Miscellaneous Symbols and Arrows + m_arRanges.push_back(CUnicodeRange(0x2200, 0x22FF, 6, 1)); // Mathematical Operators + m_arRanges.push_back(CUnicodeRange(0x2A00, 0x2AFF, 6, 1)); // Supplemental Mathematical Operators + m_arRanges.push_back(CUnicodeRange(0x27C0, 0x27EF, 6, 1)); // Miscellaneous Mathematical Symbols-A + m_arRanges.push_back(CUnicodeRange(0x2980, 0x29FF, 6, 1)); // Miscellaneous Mathematical Symbols-B + m_arRanges.push_back(CUnicodeRange(0x2300, 0x23FF, 7, 1)); // Miscellaneous Technical + m_arRanges.push_back(CUnicodeRange(0x2400, 0x243F, 8, 1)); // Control Pictures + m_arRanges.push_back(CUnicodeRange(0x2440, 0x245F, 9, 1)); // Optical Character Recognition + m_arRanges.push_back(CUnicodeRange(0x2460, 0x24FF, 10, 1)); // Enclosed Alphanumerics + m_arRanges.push_back(CUnicodeRange(0x2500, 0x257F, 11, 1)); // Box Drawing + m_arRanges.push_back(CUnicodeRange(0x2580, 0x259F, 12, 1)); // Block Elements + m_arRanges.push_back(CUnicodeRange(0x25A0, 0x25FF, 13, 1)); // Geometric Shapes + m_arRanges.push_back(CUnicodeRange(0x2600, 0x26FF, 14, 1)); // Miscellaneous Symbols + m_arRanges.push_back(CUnicodeRange(0x2700, 0x27BF, 15, 1)); // Dingbats + m_arRanges.push_back(CUnicodeRange(0x3000, 0x303F, 16, 1)); // CJK Symbols And Punctuation + m_arRanges.push_back(CUnicodeRange(0x3040, 0x309F, 17, 1)); // Hiragana + m_arRanges.push_back(CUnicodeRange(0x30A0, 0x30FF, 18, 1)); // Katakana + m_arRanges.push_back(CUnicodeRange(0x31F0, 0x31FF, 18, 1)); // Katakana Phonetic Extensions + m_arRanges.push_back(CUnicodeRange(0x3100, 0x312F, 19, 1)); // Bopomofo + m_arRanges.push_back(CUnicodeRange(0x31A0, 0x31BF, 19, 1)); // Bopomofo Extended + m_arRanges.push_back(CUnicodeRange(0x3130, 0x318F, 20, 1)); // Hangul Compatibility Jamo + m_arRanges.push_back(CUnicodeRange(0xA840, 0xA87F, 21, 1)); // Phags-pa + m_arRanges.push_back(CUnicodeRange(0x3200, 0x32FF, 22, 1)); // Enclosed CJK Letters And Months + m_arRanges.push_back(CUnicodeRange(0x3300, 0x33FF, 23, 1)); // CJK Compatibility + m_arRanges.push_back(CUnicodeRange(0xAC00, 0xD7AF, 24, 1)); // Hangul Syllables + m_arRanges.push_back(CUnicodeRange(0x10000, 0x10FFFF, 25, 1)); // Non-Plane 0 + m_arRanges.push_back(CUnicodeRange(0x10900, 0x1091F, 26, 1)); // Phoenician + m_arRanges.push_back(CUnicodeRange(0x4E00, 0x9FFF, 27, 1)); // CJK Unified Ideographs + m_arRanges.push_back(CUnicodeRange(0x2E80, 0x2EFF, 27, 1)); // CJK Radicals Supplement + m_arRanges.push_back(CUnicodeRange(0x2F00, 0x2FDF, 27, 1)); // Kangxi Radicals + m_arRanges.push_back(CUnicodeRange(0x2FF0, 0x2FFF, 27, 1)); // Ideographic Description Characters + m_arRanges.push_back(CUnicodeRange(0x3400, 0x4DBF, 27, 1)); // CJK Unified Ideographs Extension A + m_arRanges.push_back(CUnicodeRange(0x3190, 0x319F, 27, 1)); // Kanbun + m_arRanges.push_back(CUnicodeRange(0x20000, 0x2A6DF, 27, 1)); // CJK Unified Ideographs Extension B + m_arRanges.push_back(CUnicodeRange(0xE000, 0xF8FF, 28, 1)); // Private Use Area (plane 0) + m_arRanges.push_back(CUnicodeRange(0x31C0, 0x31EF, 29, 1)); // CJK Strokes + m_arRanges.push_back(CUnicodeRange(0xF900, 0xFAFF, 29, 1)); // CJK Compatibility Ideographs + m_arRanges.push_back(CUnicodeRange(0x2F800, 0x2FA1F, 29, 1)); // CJK Compatibility Ideographs Supplement + m_arRanges.push_back(CUnicodeRange(0xFB00, 0xFB4F, 30, 1)); // Alphabetic Presentation Forms + m_arRanges.push_back(CUnicodeRange(0xFB50, 0xFDFF, 31, 1)); // Arabic Presentation Forms-A + + m_arRanges.push_back(CUnicodeRange(0xFE20, 0xFE2F, 0, 2)); // Combining Half Marks + m_arRanges.push_back(CUnicodeRange(0xFE10, 0xFE1F, 1, 2)); // Vertical Forms + m_arRanges.push_back(CUnicodeRange(0xFE30, 0xFE4F, 1, 2)); // CJK Compatibility Forms + m_arRanges.push_back(CUnicodeRange(0xFE50, 0xFE6F, 2, 2)); // Small Form Variants + m_arRanges.push_back(CUnicodeRange(0xFE70, 0xFEFF, 3, 2)); // Arabic Presentation Forms-B + m_arRanges.push_back(CUnicodeRange(0xFF00, 0xFFEF, 4, 2)); // Halfwidth And Fullwidth Forms + m_arRanges.push_back(CUnicodeRange(0xFFF0, 0xFFFF, 5, 2)); // Specials + m_arRanges.push_back(CUnicodeRange(0x0F00, 0x0FFF, 6, 2)); // Tibetan + m_arRanges.push_back(CUnicodeRange(0x0700, 0x074F, 7, 2)); // Syriac + m_arRanges.push_back(CUnicodeRange(0x0780, 0x07BF, 8, 2)); // Thaana + m_arRanges.push_back(CUnicodeRange(0x0D80, 0x0DFF, 9, 2)); // Sinhala + m_arRanges.push_back(CUnicodeRange(0x1000, 0x109F, 10, 2)); // Myanmar + m_arRanges.push_back(CUnicodeRange(0x1200, 0x137F, 11, 2)); // Ethiopic + m_arRanges.push_back(CUnicodeRange(0x1380, 0x139F, 11, 2)); // Ethiopic Supplement + m_arRanges.push_back(CUnicodeRange(0x2D80, 0x2DDF, 11, 2)); // Ethiopic Extended + m_arRanges.push_back(CUnicodeRange(0x13A0, 0x13FF, 12, 2)); // Cherokee + m_arRanges.push_back(CUnicodeRange(0x1400, 0x167F, 13, 2)); // Unified Canadian Aboriginal Syllabics + m_arRanges.push_back(CUnicodeRange(0x1680, 0x169F, 14, 2)); // Ogham + m_arRanges.push_back(CUnicodeRange(0x16A0, 0x16FF, 15, 2)); // Runic + m_arRanges.push_back(CUnicodeRange(0x1780, 0x17FF, 16, 2)); // Khmer + m_arRanges.push_back(CUnicodeRange(0x19E0, 0x19FF, 16, 2)); // Khmer Symbols + m_arRanges.push_back(CUnicodeRange(0x1800, 0x18AF, 17, 2)); // Mongolian + m_arRanges.push_back(CUnicodeRange(0x2800, 0x28FF, 18, 2)); // Braille Patterns + m_arRanges.push_back(CUnicodeRange(0xA000, 0xA48F, 19, 2)); // Yi Syllables + m_arRanges.push_back(CUnicodeRange(0xA490, 0xA4CF, 19, 2)); // Yi Radicals + m_arRanges.push_back(CUnicodeRange(0x1700, 0x171F, 20, 2)); // Tagalog + m_arRanges.push_back(CUnicodeRange(0x1720, 0x173F, 20, 2)); // Hanunoo + m_arRanges.push_back(CUnicodeRange(0x1740, 0x175F, 20, 2)); // Buhid + m_arRanges.push_back(CUnicodeRange(0x1760, 0x177F, 20, 2)); // Tagbanwa + m_arRanges.push_back(CUnicodeRange(0x10300, 0x1032F, 21, 2)); // Old Italic + m_arRanges.push_back(CUnicodeRange(0x10330, 0x1034F, 22, 2)); // Gothic + m_arRanges.push_back(CUnicodeRange(0x10400, 0x1044F, 23, 2)); // Deseret + m_arRanges.push_back(CUnicodeRange(0x1D000, 0x1D0FF, 24, 2)); // Byzantine Musical Symbols + m_arRanges.push_back(CUnicodeRange(0x1D100, 0x1D1FF, 24, 2)); // Musical Symbols + m_arRanges.push_back(CUnicodeRange(0x1D200, 0x1D24F, 24, 2)); // Ancient Greek Musical Notation + m_arRanges.push_back(CUnicodeRange(0x1D400, 0x1D7FF, 25, 2)); // Mathematical Alphanumeric Symbols + m_arRanges.push_back(CUnicodeRange(0xF0000, 0xFFFFD, 26, 2)); // Private Use (plane 15) + m_arRanges.push_back(CUnicodeRange(0x100000, 0x10FFFD, 26, 2)); // Private Use (plane 16) + m_arRanges.push_back(CUnicodeRange(0xFE00, 0xFE0F, 27, 2)); // Variation Selectors + m_arRanges.push_back(CUnicodeRange(0xE0100, 0xE01EF, 27, 2)); // Variation Selectors Supplement + m_arRanges.push_back(CUnicodeRange(0xE0000, 0xE007F, 28, 2)); // Tags + m_arRanges.push_back(CUnicodeRange(0x1900, 0x194F, 29, 2)); // Limbu + m_arRanges.push_back(CUnicodeRange(0x1950, 0x197F, 30, 2)); // Tai Le + m_arRanges.push_back(CUnicodeRange(0x1980, 0x19DF, 31, 2)); // New Tai Lue + + m_arRanges.push_back(CUnicodeRange(0x1A00, 0x1A1F, 0, 3)); // Buginese + m_arRanges.push_back(CUnicodeRange(0x2C00, 0x2C5F, 1, 3)); // Glagolitic + m_arRanges.push_back(CUnicodeRange(0x2D30, 0x2D7F, 2, 3)); // Tifinagh + m_arRanges.push_back(CUnicodeRange(0x4DC0, 0x4DFF, 3, 3)); // Yijing Hexagram Symbols + m_arRanges.push_back(CUnicodeRange(0xA800, 0xA82F, 4, 3)); // Syloti Nagri + m_arRanges.push_back(CUnicodeRange(0x10000, 0x1007F, 5, 3)); // Linear B Syllabary + m_arRanges.push_back(CUnicodeRange(0x10080, 0x100FF, 5, 3)); // Linear B Ideograms + m_arRanges.push_back(CUnicodeRange(0x10100, 0x1013F, 5, 3)); // Aegean Numbers + m_arRanges.push_back(CUnicodeRange(0x10140, 0x1018F, 6, 3)); // Ancient Greek Numbers + m_arRanges.push_back(CUnicodeRange(0x10380, 0x1039F, 7, 3)); // Ugaritic + m_arRanges.push_back(CUnicodeRange(0x103A0, 0x103DF, 8, 3)); // Old Persian + m_arRanges.push_back(CUnicodeRange(0x10450, 0x1047F, 9, 3)); // Shavian + m_arRanges.push_back(CUnicodeRange(0x10480, 0x104AF, 10, 3)); // Osmanya + m_arRanges.push_back(CUnicodeRange(0x10800, 0x1083F, 11, 3)); // Cypriot Syllabary + m_arRanges.push_back(CUnicodeRange(0x10A00, 0x10A5F, 12, 3)); // Kharoshthi + m_arRanges.push_back(CUnicodeRange(0x1D300, 0x1D35F, 13, 3)); // Tai Xuan Jing Symbols + m_arRanges.push_back(CUnicodeRange(0x12000, 0x123FF, 14, 3)); // Cuneiform + m_arRanges.push_back(CUnicodeRange(0x12400, 0x1247F, 14, 3)); // Cuneiform Numbers and Punctuation + m_arRanges.push_back(CUnicodeRange(0x1D360, 0x1D37F, 15, 3)); // Counting Rod Numerals + m_arRanges.push_back(CUnicodeRange(0x1B80, 0x1BBF, 16, 3)); // Sundanese + m_arRanges.push_back(CUnicodeRange(0x1C00, 0x1C4F, 17, 3)); // Lepcha + m_arRanges.push_back(CUnicodeRange(0x1C50, 0x1C7F, 18, 3)); // Ol Chiki + m_arRanges.push_back(CUnicodeRange(0xA880, 0xA8DF, 19, 3)); // Saurashtra + m_arRanges.push_back(CUnicodeRange(0xA900, 0xA92F, 20, 3)); // Kayah Li + m_arRanges.push_back(CUnicodeRange(0xA930, 0xA95F, 21, 3)); // Rejang + m_arRanges.push_back(CUnicodeRange(0xAA00, 0xAA5F, 22, 3)); // Cham + m_arRanges.push_back(CUnicodeRange(0x10190, 0x101CF, 23, 3)); // Ancient Symbols + m_arRanges.push_back(CUnicodeRange(0x101D0, 0x101FF, 24, 3)); // Phaistos Disc + m_arRanges.push_back(CUnicodeRange(0x102A0, 0x102DF, 25, 3)); // Carian + m_arRanges.push_back(CUnicodeRange(0x10280, 0x1029F, 25, 3)); // Lycian + m_arRanges.push_back(CUnicodeRange(0x10920, 0x1093F, 25, 3)); // Lydian + m_arRanges.push_back(CUnicodeRange(0x1F030, 0x1F09F, 26, 3)); // Domino Tiles + m_arRanges.push_back(CUnicodeRange(0x1F000, 0x1F02F, 26, 3)); // Mahjong Tiles + // 27: "Reserved for process-internal usage" + // 28: "Reserved for process-internal usage" + // 29: "Reserved for process-internal usage" + // 30: "Reserved for process-internal usage" + // 31: "Reserved for process-internal usage" + } + + void CUnicodeRanges::CheckRange(const int& symbol, BYTE& Range, BYTE& RangeNum) + { + // определяем range и двигаем его в начало. + std::list::iterator iter = m_arRanges.begin(); + while (iter != m_arRanges.end()) + { + CUnicodeRange& range = *iter; + if (symbol >= range.Start && symbol <= range.End) + { + Range = range.Range; + RangeNum = range.RangeNum; + + m_arRanges.splice(m_arRanges.begin(), m_arRanges, iter); + return; + } + iter++; + } + } + + void CUnicodeRanges::CheckRange(const int& symbol, int& Range1, int& Range2, int& Range3, int& Range4) + { + BYTE nRange = 0xFF; + BYTE nRangeNum = 0xFF; + CheckRange(symbol, nRange, nRangeNum); + + switch (nRangeNum) + { + case 0: Range1 |= (1 << nRange); break; + case 1: Range2 |= (1 << nRange); break; + case 2: Range3 |= (1 << nRange); break; + case 3: Range4 |= (1 << nRange); break; + default: + break; + } + } + + CFontSelectParams::CFontSelectParams(const CFontSelectParams& oOther) : CFontSelectParams() + { + *this = oOther; + } + CFontSelectParams& CFontSelectParams::operator=(const CFontSelectParams& oOther) + { + wsDefaultName = oOther.wsDefaultName; + bDefaultBold = oOther.bDefaultBold; + bDefaultItalic = oOther.bDefaultItalic; + + lAvgWidth = oOther.lAvgWidth; + bIsFixedWidth = oOther.bIsFixedWidth; + + for(int i = 0; i < 10; i++) + arPANOSE[i] = oOther.arPANOSE[i]; + + arSignature.clear(); + arSignature.resize(oOther.arSignature.size()); + + for(int i = 0; i < arSignature.size(); i++) + arSignature[i] = oOther.arSignature[i]; + + return *this; + } + bool CFontSelectParams::operator==(const CFontSelectParams& oOther) + { + bool bEqual = true; + + bEqual &= wsDefaultName == oOther.wsDefaultName; + bEqual &= bDefaultBold == oOther.bDefaultBold; + bEqual &= bDefaultItalic == oOther.bDefaultItalic; + + bEqual &= lAvgWidth == oOther.lAvgWidth; + bEqual &= bIsFixedWidth == oOther.bIsFixedWidth; + + for(int i = 0; i < 10; i++) + bEqual &= arPANOSE[i] == oOther.arPANOSE[i]; + + if (arSignature.size() == oOther.arSignature.size()) + { + for(int i = 0; i < arSignature.size(); i++) + bEqual &= arSignature[i] == oOther.arSignature[i]; + } + else + bEqual = false; + + return bEqual; + } + + CFontSelector::CFontSelector(NSFonts::IApplicationFonts* pApplication) + { + m_pManager = pApplication->GenerateFontManager(); + m_pManager->CreateOwnerCache(8); + } + CFontSelector::~CFontSelector() + { + ClearCache(); + RELEASEINTERFACE(m_pManager); + } + + std::wstring CFontSelector::GetSelectedName() const noexcept + { + return m_wsSelectedName; + } + bool CFontSelector::IsSelectedBold() const noexcept + { + return m_bIsSelectedBold; + } + bool CFontSelector::IsSelectedItalic() const noexcept + { + return m_bIsSelectedItalic; + } + + const std::list& CFontSelector::GetCache() const + { + return m_arParamsCache; + } + + void CFontSelector::ClearCache() + { + if(!m_arParamsCache.empty()) + m_arParamsCache.clear(); + } + + void CFontSelector::SelectFont(const CFontSelectParams& oFontSelectParams, + const CFontMetrics& oFontMetrics, + const NSStringUtils::CStringUTF32& oText) + { + BYTE lRangeNum = 0xFF; + BYTE lRange = 0xFF; + + m_oRanges.CheckRange(oText.at(0), lRange, lRangeNum); + + for(auto it = m_arParamsCache.begin(); it != m_arParamsCache.end(); it++) + { + // нашли в кэше, ничего не подбираем, выкинем наверх + if(it->oFontSelectParams == oFontSelectParams && it->lRange == lRange && it->lRangeNum == lRangeNum) + { + m_bIsSelectedBold = it->bIsSelectedBold; + m_bIsSelectedItalic = it->bIsSelectedItalic; + m_wsSelectedName = it->wsSelectedName; + + if(it != m_arParamsCache.begin()) + { + m_arParamsCache.push_front(*it); + m_arParamsCache.erase(it); + } + return; + } + } + + // не нашли... + CFontSelectInfo oInfoCache; + oInfoCache.oFontSelectParams = oFontSelectParams; + oInfoCache.lRange = lRange; + oInfoCache.lRangeNum = lRangeNum; + + UINT dwR1 = 0; + UINT dwR2 = 0; + UINT dwR3 = 0; + UINT dwR4 = 0; + + if (!oFontSelectParams.arSignature.empty()) + { + dwR1 = oFontSelectParams.arSignature[0]; + dwR2 = oFontSelectParams.arSignature[1]; + dwR3 = oFontSelectParams.arSignature[2]; + dwR4 = oFontSelectParams.arSignature[3]; + } + + UINT dwCodePage1 = 0; + UINT dwCodePage2 = 0; + + if ((lRangeNum == 1) && (lRange == 28)) + { + dwCodePage1 = 0x80000000; + //strText = (WCHAR)(strText[0] - 0xF000); + } + else if (((lRangeNum == 2) && (lRange == 3)) || ((lRangeNum == 1) && (lRange == 31)) || ((lRangeNum == 0) && (lRange == 13))) + { + // арабский язык!!! + dwR1 = 1 << 13; + dwR2 = 1 << 31; + dwR3 = 1 << 3; + } + else + { + CheckRanges(dwR1, dwR2, dwR3, dwR4, lRangeNum, lRange); + } + + NSFonts::CFontSelectFormat oFormat; + std::wstring sFontNameSelect = oFontSelectParams.wsDefaultName; + + bool bSelectBold = false; + bool bSelectItalic = false; + CheckFontNamePDF(sFontNameSelect, bSelectBold, bSelectItalic); + + bSelectBold |= oFontSelectParams.bDefaultBold; + bSelectItalic |= oFontSelectParams.bDefaultItalic; + + bool bIsPanosePresent = false; + for (int i = 0; i < 10; i++) + { + if (0 != oFontSelectParams.arPANOSE[i]) + { + bIsPanosePresent = true; + break; + } + } + + if (bIsPanosePresent) + { + oFormat.pPanose = new BYTE[10]; + memcpy(oFormat.pPanose, oFontSelectParams.arPANOSE, 10 * sizeof(BYTE)); + } + + oFormat.bBold = new INT(bSelectBold); + oFormat.bItalic = new INT(bSelectItalic); + oFormat.bFixedWidth = new INT(oFontSelectParams.bIsFixedWidth ? 1 : 0); + + if (-1 != oFontSelectParams.lAvgWidth) + oFormat.shAvgCharWidth = new SHORT((SHORT)oFontSelectParams.lAvgWidth); + + oFormat.ulRange1 = new UINT(dwR1); + oFormat.ulRange2 = new UINT(dwR2); + oFormat.ulRange3 = new UINT(dwR3); + oFormat.ulRange4 = new UINT(dwR4); + oFormat.ulCodeRange1 = new UINT(dwCodePage1); + oFormat.ulCodeRange2 = new UINT(dwCodePage2); + + if (oFormat.bBold && *(oFormat.bBold) == 1 && oFormat.pPanose && oFormat.pPanose[2] < 7) + oFormat.pPanose[2] = 7; + + oFormat.wsName = new std::wstring(sFontNameSelect); + + NSFonts::CFontInfo* pInfo = m_pManager->GetFontInfoByParams(oFormat); + + m_bIsSelectedBold = pInfo->m_bBold; + m_bIsSelectedItalic = pInfo->m_bItalic; + m_wsSelectedName = pInfo->m_wsFontName; + + // закинем в кэш, чтобы потом не подбирать + oInfoCache.bIsSelectedBold = m_bIsSelectedBold; + oInfoCache.bIsSelectedItalic = m_bIsSelectedItalic; + oInfoCache.wsSelectedName = m_wsSelectedName; + m_arParamsCache.push_back(oInfoCache); + return; + } + + void CFontSelector::CheckFontNamePDF(std::wstring& wsName, bool& bBold, bool& bItalic) + { + if (wsName.length() > 7 && wsName.at(6) == '+') + { + bool bIsRemove = true; + for (int nIndex = 0; nIndex < 6; ++nIndex) + { + wchar_t nChar = wsName.at(nIndex); + if (nChar < 'A' || nChar > 'Z') + { + bIsRemove = false; + break; + } + } + if (bIsRemove) + { + wsName.erase(0, 7); + } + } + + CheckFontNameStyle(wsName, L"regular"); + CheckFontNameStyle(wsName, L"condensed"); + CheckFontNameStyle(wsName, L"condensedlight"); + //CheckFontNameStyle(wsName, L"light"); + + CheckFontNameStyle(wsName, L"condensedbold"); + if (CheckFontNameStyle(wsName, L"semibold")) bBold = true; + if (CheckFontNameStyle(wsName, L"boldmt")) bBold = true; + if (CheckFontNameStyle(wsName, L"bold")) bBold = true; + + if (CheckFontNameStyle(wsName, L"italicmt")) bItalic = true; + if (CheckFontNameStyle(wsName, L"italic")) bItalic = true; + if (CheckFontNameStyle(wsName, L"oblique")) bItalic = true; + + if (CheckFontNameStyle(wsName, L"bolditalicmt")) { bBold = true; bItalic = true; } + if (CheckFontNameStyle(wsName, L"bolditalic")) { bBold = true; bItalic = true; } + if (CheckFontNameStyle(wsName, L"bold_italic")) { bBold = true; bItalic = true; } + if (CheckFontNameStyle(wsName, L"boldoblique")) { bBold = true; bItalic = true; } + if (CheckFontNameStyle(wsName, L"bold_oblique")) { bBold = true; bItalic = true; } + } + bool CFontSelector::CheckFontNameStyle(std::wstring& wsName, const std::wstring& sStyle) + { + size_t nPos = 0; + size_t nLenReplace = sStyle.length(); + bool bRet = false; + + std::wstring wsName2 = wsName; + NSStringExt::ToLower(wsName2); + + while (std::wstring::npos != (nPos = wsName2.find(sStyle, nPos))) + { + size_t nOffset = 0; + if ((nPos > 0) && wsName2.at(nPos - 1) == '-') + { + --nPos; + ++nOffset; + } + + bRet = true; + wsName.erase(nPos, nLenReplace + nOffset); + wsName2.erase(nPos, nLenReplace + nOffset); + } + return bRet; + } + + void CFontSelector::CheckRanges(UINT& lRange1, UINT& lRange2, UINT& lRange3, UINT& lRange4, BYTE& lRangeNum, BYTE& lRange) + { + if (0 == lRangeNum) + lRange1 |= 1 << lRange; + else if (1 == lRangeNum) + lRange2 |= 1 << lRange; + else if (2 == lRangeNum) + lRange3 |= 1 << lRange; + else + lRange4 |= 1 << lRange; + } + + CFontManager::CFontManager(NSFonts::IApplicationFonts* pApplication) + { + m_pManager = pApplication->GenerateFontManager(); + m_pManager->CreateOwnerCache(8); + } + CFontManager::~CFontManager() + { + RELEASEINTERFACE(m_pManager); + } + + bool CFontManager::LoadFontByFile(const NSStructures::CFont& oFont) + { + if (m_oFont.IsEqual2(&oFont)) + return true; + + if (!m_pManager->LoadFontFromFile(oFont.Path, (int)oFont.FaceIndex, (float)oFont.Size, c_dDpiX, c_dDpiY)) + return false; + + m_oFont = oFont; + m_pManager->AfterLoad(); + + LoadFontMetrics(); + LoadFontSelectParams(); + + if (m_oFontSelectParams.wsDefaultName.empty()) + m_oFontSelectParams.wsDefaultName = m_oFont.Name; + + CheckPdfResources(); + + return true; + } + bool CFontManager::LoadFontByName(const NSStructures::CFont& oFont) + { + if (m_oFont.IsEqual2(&oFont)) + return true; + + m_oFont = oFont; + + if (!m_pManager->LoadFontByName(m_oFont.Name, (float)m_oFont.Size, m_oFont.GetStyle2(), c_dDpiX, c_dDpiY)) + return false; + + m_pManager->AfterLoad(); + LoadFontMetrics(); + LoadFontSelectParams(); + + return true; + } + + const CFontSelectParams& CFontManager::GetFontSelectParams() const noexcept + { + return m_oFontSelectParams; + } + const CFontMetrics& CFontManager::GetFontMetrics() const noexcept + { + return m_oFontMetrics; + } + + double CFontManager::GetFontHeight() const + { + return c_dPtToMM * (m_oFontMetrics.dLineSpacing * m_oFont.Size) / m_oFontMetrics.dEmHeight; + } + double CFontManager::GetSpaceWidthMM() const + { + double dSpaceWidthMM = 0.0; + // int bIsGID = m_pManager->GetStringGID(); + // m_pManager->SetStringGID(FALSE); + + m_pManager->LoadString2(L" ", 0, 0); + TBBox bbox = m_pManager->MeasureString2(); + + dSpaceWidthMM = (double)(bbox.fMaxX - bbox.fMinX) * c_dPixToMM; + if (0 >= dSpaceWidthMM) + dSpaceWidthMM = 1.0; + + // m_pManager->SetStringGID(bIsGID); + return dSpaceWidthMM; + } + + void CFontManager::SetStringGid(const LONG& lGid) + { + if (nullptr != m_pManager) + m_pManager->SetStringGID(lGid); + } + + void CFontManager::MeasureString( + const std::wstring& wsText, + double x, + double y, + double& dBoxX, + double& dBoxY, + double& dBoxWidth, + double& dBoxHeight, + MeasureType measureType) const + { + dBoxX = 0; + dBoxY = 0; + dBoxWidth = 0; + dBoxHeight = 0; + + if (nullptr == m_pManager) + return; + + m_pManager->LoadString1(wsText, (float)x, (float)y); + + TBBox bbox; + if (mtGlyph == measureType) bbox = m_pManager->MeasureString(); + else if (mtPosition == measureType) bbox = m_pManager->MeasureString2(); + + dBoxX = (double)bbox.fMinX; + dBoxY = (double)bbox.fMinY; + dBoxWidth = (double)(bbox.fMaxX - bbox.fMinX); + dBoxHeight = (double)(bbox.fMaxY - bbox.fMinY); + + // переводим в миллиметры + dBoxX *= c_dPixToMM; + dBoxY *= c_dPixToMM; + dBoxWidth *= c_dPixToMM; + dBoxHeight *= c_dPixToMM; + } + void CFontManager::MeasureStringGids( + unsigned int* pGids, + unsigned int count, + double x, + double y, + double& dBoxX, + double& dBoxY, + double& dBoxWidth, + double& dBoxHeight, + MeasureType measureType) const + { + dBoxX = 0; + dBoxY = 0; + dBoxWidth = 0; + dBoxHeight = 0; + + if (nullptr == m_pManager) + return; + + m_pManager->LoadString1(pGids, count, (float)x, (float)y); + + TBBox bbox; + if (mtGlyph == measureType) bbox = m_pManager->MeasureString(); + else if (mtPosition == measureType) bbox = m_pManager->MeasureString2(); + + dBoxX = (double)bbox.fMinX; + dBoxY = (double)bbox.fMinY; + dBoxWidth = (double)(bbox.fMaxX - bbox.fMinX); + dBoxHeight = (double)(bbox.fMaxY - bbox.fMinY); + + // переводим в миллиметры + dBoxX *= c_dPixToMM; + dBoxY *= c_dPixToMM; + dBoxWidth *= c_dPixToMM; + dBoxHeight *= c_dPixToMM; + } + + void CFontManager::LoadFontMetrics() + { + m_oFontMetrics.dAscent = m_pManager->GetAscender(); + m_oFontMetrics.dDescent = m_pManager->GetDescender(); + m_oFontMetrics.dLineSpacing = m_pManager->GetLineHeight(); + m_oFontMetrics.dEmHeight = m_pManager->GetUnitsPerEm(); + m_oFontMetrics.dBaselineOffset = (c_dPtToMM * m_oFontMetrics.dDescent * m_oFont.Size / m_oFontMetrics.dEmHeight); + } + void CFontManager::LoadFontSelectParams() + { + if (nullptr == m_pManager || nullptr == m_pManager->GetFile()) + return; + + m_oFontSelectParams.bDefaultBold = m_pManager->GetFile()->IsBold(); + m_oFontSelectParams.bDefaultItalic = m_pManager->GetFile()->IsItalic(); + m_oFontSelectParams.wsDefaultName = m_pManager->GetName(); + + // PANOSE + BYTE pPanose[10]; + m_pManager->GetFile()->GetPanose(pPanose); + + for(int i = 0; i < 10; ++i) + m_oFontSelectParams.arPANOSE[i] = pPanose[i]; + + // IsFixed + m_oFontSelectParams.bIsFixedWidth = m_pManager->GetFile()->IsFixedWidth(); + + // Signature + m_oFontSelectParams.arSignature.clear(); + + // check os2 present: + bool bIsOS2Present = (-1 != m_pManager->GetFile()->IsUnicodeRangeAvailable(0, 0)) ? true : false; + + if (bIsOS2Present) + { + for ( unsigned int i = 0; i < 6; ++i ) + { + DWORD value = 0; + for ( unsigned long bit = 0; bit < 32; ++bit ) + if (m_pManager->GetFile()->IsUnicodeRangeAvailable(bit, i)) + value |= ( 1 << bit ); + + m_oFontSelectParams.arSignature.push_back(value); + } + } + } + + void CFontManager::CheckPdfResources() + { +#ifndef DISABLE_FILESYSTEM + bool bIsCID = false; + std::wstring sFileExt = NSFile::GetFileExtention(m_oFont.Path); + if (std::wstring::npos != sFileExt.find(L"cid")) + bIsCID = true; + + std::wstring sFileName = NSFile::GetFileName(m_oFont.Path); + std::wstring::size_type pos = sFileName.rfind('.'); + if (std::wstring::npos != pos) + sFileName = sFileName.substr(0, pos); + std::wstring sEncFilePath = NSFile::GetDirectoryName(m_oFont.Path) + L"/" + sFileName + L".enc"; + + XmlUtils::CXmlNode oMainNode; + oMainNode.FromXmlFile(sEncFilePath); + + if (L"PDF-resources" == oMainNode.GetName()) + { + if (bIsCID) + { + XmlUtils::CXmlNode oType0Node; + if ( oMainNode.GetNode( L"Type0", oType0Node ) ) + { + XmlUtils::CXmlNode oNode; + if ( oType0Node.GetNode( L"DescendantFonts", oNode ) ) + { + XmlUtils::CXmlNode oDescNode; + if ( oNode.GetNode( L"FontDescriptor", oDescNode ) ) + { + XmlUtils::CXmlNode oCurNode; + if ( oNode.GetNode( L"AvgWidth", oCurNode ) ) + { + std::wstring sValue = oCurNode.GetAttribute(L"value"); + try { + m_oFontSelectParams.lAvgWidth = (SHORT)std::stol(sValue); + } catch (std::invalid_argument &) {} + } + } + } + } + } + else + { + XmlUtils::CXmlNode oNode; + if ( oMainNode.GetNode( L"FontDescriptor", oNode ) ) + { + XmlUtils::CXmlNode oCurNode; + if ( oNode.GetNode( L"AvgWidth", oCurNode ) ) + { + std::wstring sValue = oCurNode.GetAttribute(L"value"); + try { + m_oFontSelectParams.lAvgWidth = (SHORT)std::stol(sValue); + } catch (std::invalid_argument &) {} + } + } + } + } +#endif + } + + void CFontManager::ClearCache() + { + m_oFont = {}; + if (nullptr == m_pManager) + return; + m_pManager->GetCache()->Clear(); + } } diff --git a/DocxRenderer/src/logic/managers/FontManager.h b/DocxRenderer/src/logic/managers/FontManager.h index 05cfbf5d08d..17e4d7286a4 100644 --- a/DocxRenderer/src/logic/managers/FontManager.h +++ b/DocxRenderer/src/logic/managers/FontManager.h @@ -1,96 +1,166 @@ #pragma once -#include "FontManagerBase.h" -#include "../DesktopEditor/graphics/Matrix.h" +#include +#include + +#include "../../../../DesktopEditor/graphics/structures.h" +#include "../../../../DesktopEditor/graphics/pro/Fonts.h" +#include "../../../../DesktopEditor/common/StringUTF32.h" namespace NSDocxRenderer { - using namespace NSFontManager; - - class CFontTableEntry - { - public: - std::wstring m_strFamilyName {L""}; - std::wstring m_strPANOSE {L""}; - LONG m_lStyle {0}; - std::vector m_arSignature; - bool m_bIsFixedWidth {false}; - - public: - CFontTableEntry(){} - virtual ~CFontTableEntry(){} - - CFontTableEntry(const CFontTableEntry& oSrc); - - CFontTableEntry& operator =(const CFontTableEntry& oSrc); - }; - - class CFontTable - { - public: - std::map m_mapTable; - - public: - CFontTable() : m_mapTable(){} - }; - - class CFontManager : public CFontManagerBase - { - public: - NSStructures::CFont* m_pFont {nullptr}; - Aggplus::CMatrix* m_pTransform {nullptr}; - double m_dSpaceWidthMM {0.0}; - - public: - CFontTable m_oFontTable; - - public: - CFontManager(NSFonts::IApplicationFonts* pFonts); - virtual ~CFontManager(){} - - public: - void Init(); - - void AddFontToMap(); - - public: - virtual void LoadFont(long lFaceIndex = 0, bool bNeedAddToMap = true); - - virtual void MeasureString(const std::wstring& sText, double x, double y, double& dBoxX, double& dBoxY, - double& dBoxWidth, double& dBoxHeight, MeasureType measureType); - - void MeasureStringGids(unsigned int* pGids, unsigned int count, double x, double y, - double& dBoxX, double& dBoxY, double& dBoxWidth, double& dBoxHeight, MeasureType measureType); - - double GetBaseLineOffset(); - - double GetFontHeight(); - - void SetStringGid(const LONG& lGid); - - void GenerateFontName2(NSStringUtils::CStringUTF32& oText); - }; - - class CFontManagerLight - { - private: - std::wstring m_strFontName {L""}; - LONG m_lFontStyle {0}; - double m_dSize {0.0}; - - double m_dSpaceWidth {0.0}; - - NSFonts::IFontManager* m_pManager {nullptr}; - - public: - CFontManagerLight(NSFonts::IApplicationFonts* pFonts); - virtual ~CFontManagerLight(); - - double GetSpaceWidth(); - - public: - void LoadFont(std::wstring& strFontName, LONG& lStyle, const double &dSize, const bool& bIsGID); - - double MeasureStringWidth(const std::wstring& sText); - }; - + class CUnicodeRange + { + public: + BYTE RangeNum {0}; + BYTE Range {0}; + + int Start {0}; + int End {0}; + + CUnicodeRange(const int& _start = 0, const int& _end = 0, const BYTE& _range = 0, const BYTE& _rangenum = 0); + }; + + // класс для проставления Ranges для подбора шрифта по символу + class CUnicodeRanges + { + public: + std::list m_arRanges; + + public: + CUnicodeRanges(); + void CheckRange(const int& symbol, BYTE& Range, BYTE& RangeNum); + void CheckRange(const int& symbol, int& Range1, int& Range2, int& Range3, int& Range4); + }; + + struct CFontMetrics + { + double dAscent {0.0}; + double dDescent {0.0}; + double dLineSpacing {0.0}; + double dEmHeight {0.0}; + double dBaselineOffset {0.0}; + }; + + struct CFontSelectParams + { + // изначальные параметры, которые могут быть нам известны + std::wstring wsDefaultName{L""}; + bool bDefaultBold{false}; + bool bDefaultItalic{false}; + + SHORT lAvgWidth{-1}; + bool bIsFixedWidth{false}; + + BYTE arPANOSE[10]{}; + std::vector arSignature; + + CFontSelectParams() = default; + CFontSelectParams(const CFontSelectParams& oOther); + CFontSelectParams& operator=(const CFontSelectParams& oOther); + bool operator==(const CFontSelectParams& oOther); + }; + + // подбирает шрифт по параметрам + class CFontSelector + { + public: + // структура для хранения уже подобранных шрифтов + struct CFontSelectInfo + { + CFontSelectParams oFontSelectParams; + BYTE lRangeNum; + BYTE lRange; + + std::wstring wsSelectedName; + bool bIsSelectedBold; + bool bIsSelectedItalic; + }; + + CFontSelector(NSFonts::IApplicationFonts* pApplication); + ~CFontSelector(); + + void SelectFont(const CFontSelectParams& oFontSelectParams, + const CFontMetrics& oFontMetrics, + const NSStringUtils::CStringUTF32& oText); + std::wstring GetSelectedName() const noexcept; + bool IsSelectedBold() const noexcept; + bool IsSelectedItalic() const noexcept; + + const std::list& GetCache() const; + void ClearCache(); + + private: + std::list m_arParamsCache; + + NSFonts::IFontManager* m_pManager; + std::wstring m_wsSelectedName; + bool m_bIsSelectedBold; + bool m_bIsSelectedItalic; + + CUnicodeRanges m_oRanges; + void CheckRanges(UINT& lRange1, UINT& lRange2, UINT& lRange3, UINT& lRange4, BYTE& lRangeNum, BYTE& lRange); + + void CheckFontNamePDF(std::wstring& wsName, bool& bBold, bool& bItalic); + bool CheckFontNameStyle(std::wstring& wsName, const std::wstring& sStyle); + }; + + // грузит шрифт, его параметры и метрики + измеряет шрифт + class CFontManager + { + public: + enum MeasureType + { + mtGlyph = 0, + mtPosition = 1 + }; + + CFontManager(NSFonts::IApplicationFonts* pFonts); + ~CFontManager(); + + bool LoadFontByFile(const NSStructures::CFont& oFont); + bool LoadFontByName(const NSStructures::CFont& oFont); + + const CFontSelectParams& GetFontSelectParams() const noexcept; + const CFontMetrics& GetFontMetrics() const noexcept; + + double GetFontHeight() const; + double GetSpaceWidthMM() const; + + void SetStringGid(const LONG& lGid); + + void MeasureString( + const std::wstring& wsText, + double x, + double y, + double& dBoxX, + double& dBoxY, + double& dBoxWidth, + double& dBoxHeight, + MeasureType measureType) const; + + void MeasureStringGids( + unsigned int* pGids, + unsigned int count, + double x, + double y, + double& dBoxX, + double& dBoxY, + double& dBoxWidth, + double& dBoxHeight, + MeasureType measureType) const; + + void ClearCache(); + private: + NSFonts::IFontManager* m_pManager; + + NSStructures::CFont m_oFont; + CFontMetrics m_oFontMetrics; + CFontSelectParams m_oFontSelectParams; + + void LoadFontMetrics(); + void LoadFontSelectParams(); + + void CheckPdfResources(); + + }; } diff --git a/DocxRenderer/src/logic/managers/FontManagerBase.cpp b/DocxRenderer/src/logic/managers/FontManagerBase.cpp deleted file mode 100644 index b66ac57a82b..00000000000 --- a/DocxRenderer/src/logic/managers/FontManagerBase.cpp +++ /dev/null @@ -1,700 +0,0 @@ -#include "FontManagerBase.h" -#include "../DesktopEditor/common/Directory.h" -#include "../DesktopEditor/xml/include/xmlutils.h" -#include "src/resources/Constants.h" - -namespace NSFontManager -{ - CUnicodeRange::CUnicodeRange(const int& _start, const int& _end, - const BYTE& _range, const BYTE& _rangenum): - RangeNum(_rangenum), Range(_range), Start(_start), End(_end) - { - } - - CUnicodeRanges::CUnicodeRanges() - { - // https://docs.microsoft.com/en-us/typography/opentype/spec/os2#ur - - m_arRanges.push_back(CUnicodeRange(0x0000, 0x007F, 0, 0)); // Basic Latin - m_arRanges.push_back(CUnicodeRange(0x0080, 0x00FF, 1, 0)); // Latin-1 Supplement - m_arRanges.push_back(CUnicodeRange(0x0100, 0x017F, 2, 0)); // Latin Extended-A - m_arRanges.push_back(CUnicodeRange(0x0180, 0x024F, 3, 0)); // Latin Extended-B - m_arRanges.push_back(CUnicodeRange(0x0250, 0x02AF, 4, 0)); // IPA Extensions - m_arRanges.push_back(CUnicodeRange(0x1D00, 0x1D7F, 4, 0)); // Phonetic Extensions - m_arRanges.push_back(CUnicodeRange(0x1D80, 0x1DBF, 4, 0)); // Phonetic Extensions Supplement - m_arRanges.push_back(CUnicodeRange(0x02B0, 0x02FF, 5, 0)); // Spacing Modifier Letters - m_arRanges.push_back(CUnicodeRange(0xA700, 0xA71F, 5, 0)); // Modifier Tone Letters - m_arRanges.push_back(CUnicodeRange(0x0300, 0x036F, 6, 0)); // Combining Diacritical Marks - m_arRanges.push_back(CUnicodeRange(0x1DC0, 0x1DFF, 6, 0)); // Combining Diacritical Marks Supplement - m_arRanges.push_back(CUnicodeRange(0x0370, 0x03FF, 7, 0)); // Greek and Coptic - m_arRanges.push_back(CUnicodeRange(0x2C80, 0x2CFF, 8, 0)); // Coptic - m_arRanges.push_back(CUnicodeRange(0x0400, 0x04FF, 9, 0)); // Cyrillic - m_arRanges.push_back(CUnicodeRange(0x0500, 0x052F, 9, 0)); // Cyrillic Supplement - m_arRanges.push_back(CUnicodeRange(0x2DE0, 0x2DFF, 9, 0)); // Cyrillic Extended-A - m_arRanges.push_back(CUnicodeRange(0xA640, 0xA69F, 9, 0)); // Cyrillic Extended-B - m_arRanges.push_back(CUnicodeRange(0x0530, 0x058F, 10, 0)); // Armenian - m_arRanges.push_back(CUnicodeRange(0x0590, 0x05FF, 11, 0)); // Hebrew - m_arRanges.push_back(CUnicodeRange(0xA500, 0xA63F, 12, 0)); // Vai - m_arRanges.push_back(CUnicodeRange(0x0600, 0x06FF, 13, 0)); // Arabic - m_arRanges.push_back(CUnicodeRange(0x0750, 0x077F, 13, 0)); // Arabic Supplement - m_arRanges.push_back(CUnicodeRange(0x07C0, 0x07FF, 14, 0)); // NKo - m_arRanges.push_back(CUnicodeRange(0x0900, 0x097F, 15, 0)); // Devanagari - m_arRanges.push_back(CUnicodeRange(0x0980, 0x09FF, 16, 0)); // Bengali - m_arRanges.push_back(CUnicodeRange(0x0A00, 0x0A7F, 17, 0)); // Gurmukhi - m_arRanges.push_back(CUnicodeRange(0x0A80, 0x0AFF, 18, 0)); // Gujarati - m_arRanges.push_back(CUnicodeRange(0x0B00, 0x0B7F, 19, 0)); // Oriya - m_arRanges.push_back(CUnicodeRange(0x0B80, 0x0BFF, 20, 0)); // Tamil - m_arRanges.push_back(CUnicodeRange(0x0C00, 0x0C7F, 21, 0)); // Telugu - m_arRanges.push_back(CUnicodeRange(0x0C80, 0x0CFF, 22, 0)); // Kannada - m_arRanges.push_back(CUnicodeRange(0x0D00, 0x0D7F, 23, 0)); // Malayalam - m_arRanges.push_back(CUnicodeRange(0x0E00, 0x0E7F, 24, 0)); // Thai - m_arRanges.push_back(CUnicodeRange(0x0E80, 0x0EFF, 25, 0)); // Lao - m_arRanges.push_back(CUnicodeRange(0x10A0, 0x10FF, 26, 0)); // Georgian - m_arRanges.push_back(CUnicodeRange(0x2D00, 0x2D2F, 26, 0)); // Georgian Supplement - m_arRanges.push_back(CUnicodeRange(0x1B00, 0x1B7F, 27, 0)); // Balinese - m_arRanges.push_back(CUnicodeRange(0x1100, 0x11FF, 28, 0)); // Hangul Jamo - m_arRanges.push_back(CUnicodeRange(0x1E00, 0x1EFF, 29, 0)); // Latin Extended Additional - m_arRanges.push_back(CUnicodeRange(0x2C60, 0x2C7F, 29, 0)); // Latin Extended-C - m_arRanges.push_back(CUnicodeRange(0xA720, 0xA7FF, 29, 0)); // Latin Extended-D - m_arRanges.push_back(CUnicodeRange(0x1F00, 0x1FFF, 30, 0)); // Greek Extended - m_arRanges.push_back(CUnicodeRange(0x2000, 0x206F, 31, 0)); // General Punctuation - m_arRanges.push_back(CUnicodeRange(0x2E00, 0x2E7F, 31, 0)); // Supplemental Punctuation - - m_arRanges.push_back(CUnicodeRange(0x2070, 0x209F, 0, 1)); // Superscripts And Subscripts - m_arRanges.push_back(CUnicodeRange(0x20A0, 0x20CF, 1, 1)); // Currency Symbols - m_arRanges.push_back(CUnicodeRange(0x20D0, 0x20FF, 2, 1)); // Combining Diacritical Marks For Symbols - m_arRanges.push_back(CUnicodeRange(0x2100, 0x214F, 3, 1)); // Letterlike Symbols - m_arRanges.push_back(CUnicodeRange(0x2150, 0x218F, 4, 1)); // Number Forms - m_arRanges.push_back(CUnicodeRange(0x2190, 0x21FF, 5, 1)); // Arrows - m_arRanges.push_back(CUnicodeRange(0x27F0, 0x27FF, 5, 1)); // Supplemental Arrows-A - m_arRanges.push_back(CUnicodeRange(0x2900, 0x297F, 5, 1)); // Supplemental Arrows-B - m_arRanges.push_back(CUnicodeRange(0x2B00, 0x2BFF, 5, 1)); // Miscellaneous Symbols and Arrows - m_arRanges.push_back(CUnicodeRange(0x2200, 0x22FF, 6, 1)); // Mathematical Operators - m_arRanges.push_back(CUnicodeRange(0x2A00, 0x2AFF, 6, 1)); // Supplemental Mathematical Operators - m_arRanges.push_back(CUnicodeRange(0x27C0, 0x27EF, 6, 1)); // Miscellaneous Mathematical Symbols-A - m_arRanges.push_back(CUnicodeRange(0x2980, 0x29FF, 6, 1)); // Miscellaneous Mathematical Symbols-B - m_arRanges.push_back(CUnicodeRange(0x2300, 0x23FF, 7, 1)); // Miscellaneous Technical - m_arRanges.push_back(CUnicodeRange(0x2400, 0x243F, 8, 1)); // Control Pictures - m_arRanges.push_back(CUnicodeRange(0x2440, 0x245F, 9, 1)); // Optical Character Recognition - m_arRanges.push_back(CUnicodeRange(0x2460, 0x24FF, 10, 1)); // Enclosed Alphanumerics - m_arRanges.push_back(CUnicodeRange(0x2500, 0x257F, 11, 1)); // Box Drawing - m_arRanges.push_back(CUnicodeRange(0x2580, 0x259F, 12, 1)); // Block Elements - m_arRanges.push_back(CUnicodeRange(0x25A0, 0x25FF, 13, 1)); // Geometric Shapes - m_arRanges.push_back(CUnicodeRange(0x2600, 0x26FF, 14, 1)); // Miscellaneous Symbols - m_arRanges.push_back(CUnicodeRange(0x2700, 0x27BF, 15, 1)); // Dingbats - m_arRanges.push_back(CUnicodeRange(0x3000, 0x303F, 16, 1)); // CJK Symbols And Punctuation - m_arRanges.push_back(CUnicodeRange(0x3040, 0x309F, 17, 1)); // Hiragana - m_arRanges.push_back(CUnicodeRange(0x30A0, 0x30FF, 18, 1)); // Katakana - m_arRanges.push_back(CUnicodeRange(0x31F0, 0x31FF, 18, 1)); // Katakana Phonetic Extensions - m_arRanges.push_back(CUnicodeRange(0x3100, 0x312F, 19, 1)); // Bopomofo - m_arRanges.push_back(CUnicodeRange(0x31A0, 0x31BF, 19, 1)); // Bopomofo Extended - m_arRanges.push_back(CUnicodeRange(0x3130, 0x318F, 20, 1)); // Hangul Compatibility Jamo - m_arRanges.push_back(CUnicodeRange(0xA840, 0xA87F, 21, 1)); // Phags-pa - m_arRanges.push_back(CUnicodeRange(0x3200, 0x32FF, 22, 1)); // Enclosed CJK Letters And Months - m_arRanges.push_back(CUnicodeRange(0x3300, 0x33FF, 23, 1)); // CJK Compatibility - m_arRanges.push_back(CUnicodeRange(0xAC00, 0xD7AF, 24, 1)); // Hangul Syllables - m_arRanges.push_back(CUnicodeRange(0x10000, 0x10FFFF, 25, 1)); // Non-Plane 0 - m_arRanges.push_back(CUnicodeRange(0x10900, 0x1091F, 26, 1)); // Phoenician - m_arRanges.push_back(CUnicodeRange(0x4E00, 0x9FFF, 27, 1)); // CJK Unified Ideographs - m_arRanges.push_back(CUnicodeRange(0x2E80, 0x2EFF, 27, 1)); // CJK Radicals Supplement - m_arRanges.push_back(CUnicodeRange(0x2F00, 0x2FDF, 27, 1)); // Kangxi Radicals - m_arRanges.push_back(CUnicodeRange(0x2FF0, 0x2FFF, 27, 1)); // Ideographic Description Characters - m_arRanges.push_back(CUnicodeRange(0x3400, 0x4DBF, 27, 1)); // CJK Unified Ideographs Extension A - m_arRanges.push_back(CUnicodeRange(0x3190, 0x319F, 27, 1)); // Kanbun - m_arRanges.push_back(CUnicodeRange(0x20000, 0x2A6DF, 27, 1)); // CJK Unified Ideographs Extension B - m_arRanges.push_back(CUnicodeRange(0xE000, 0xF8FF, 28, 1)); // Private Use Area (plane 0) - m_arRanges.push_back(CUnicodeRange(0x31C0, 0x31EF, 29, 1)); // CJK Strokes - m_arRanges.push_back(CUnicodeRange(0xF900, 0xFAFF, 29, 1)); // CJK Compatibility Ideographs - m_arRanges.push_back(CUnicodeRange(0x2F800, 0x2FA1F, 29, 1)); // CJK Compatibility Ideographs Supplement - m_arRanges.push_back(CUnicodeRange(0xFB00, 0xFB4F, 30, 1)); // Alphabetic Presentation Forms - m_arRanges.push_back(CUnicodeRange(0xFB50, 0xFDFF, 31, 1)); // Arabic Presentation Forms-A - - m_arRanges.push_back(CUnicodeRange(0xFE20, 0xFE2F, 0, 2)); // Combining Half Marks - m_arRanges.push_back(CUnicodeRange(0xFE10, 0xFE1F, 1, 2)); // Vertical Forms - m_arRanges.push_back(CUnicodeRange(0xFE30, 0xFE4F, 1, 2)); // CJK Compatibility Forms - m_arRanges.push_back(CUnicodeRange(0xFE50, 0xFE6F, 2, 2)); // Small Form Variants - m_arRanges.push_back(CUnicodeRange(0xFE70, 0xFEFF, 3, 2)); // Arabic Presentation Forms-B - m_arRanges.push_back(CUnicodeRange(0xFF00, 0xFFEF, 4, 2)); // Halfwidth And Fullwidth Forms - m_arRanges.push_back(CUnicodeRange(0xFFF0, 0xFFFF, 5, 2)); // Specials - m_arRanges.push_back(CUnicodeRange(0x0F00, 0x0FFF, 6, 2)); // Tibetan - m_arRanges.push_back(CUnicodeRange(0x0700, 0x074F, 7, 2)); // Syriac - m_arRanges.push_back(CUnicodeRange(0x0780, 0x07BF, 8, 2)); // Thaana - m_arRanges.push_back(CUnicodeRange(0x0D80, 0x0DFF, 9, 2)); // Sinhala - m_arRanges.push_back(CUnicodeRange(0x1000, 0x109F, 10, 2)); // Myanmar - m_arRanges.push_back(CUnicodeRange(0x1200, 0x137F, 11, 2)); // Ethiopic - m_arRanges.push_back(CUnicodeRange(0x1380, 0x139F, 11, 2)); // Ethiopic Supplement - m_arRanges.push_back(CUnicodeRange(0x2D80, 0x2DDF, 11, 2)); // Ethiopic Extended - m_arRanges.push_back(CUnicodeRange(0x13A0, 0x13FF, 12, 2)); // Cherokee - m_arRanges.push_back(CUnicodeRange(0x1400, 0x167F, 13, 2)); // Unified Canadian Aboriginal Syllabics - m_arRanges.push_back(CUnicodeRange(0x1680, 0x169F, 14, 2)); // Ogham - m_arRanges.push_back(CUnicodeRange(0x16A0, 0x16FF, 15, 2)); // Runic - m_arRanges.push_back(CUnicodeRange(0x1780, 0x17FF, 16, 2)); // Khmer - m_arRanges.push_back(CUnicodeRange(0x19E0, 0x19FF, 16, 2)); // Khmer Symbols - m_arRanges.push_back(CUnicodeRange(0x1800, 0x18AF, 17, 2)); // Mongolian - m_arRanges.push_back(CUnicodeRange(0x2800, 0x28FF, 18, 2)); // Braille Patterns - m_arRanges.push_back(CUnicodeRange(0xA000, 0xA48F, 19, 2)); // Yi Syllables - m_arRanges.push_back(CUnicodeRange(0xA490, 0xA4CF, 19, 2)); // Yi Radicals - m_arRanges.push_back(CUnicodeRange(0x1700, 0x171F, 20, 2)); // Tagalog - m_arRanges.push_back(CUnicodeRange(0x1720, 0x173F, 20, 2)); // Hanunoo - m_arRanges.push_back(CUnicodeRange(0x1740, 0x175F, 20, 2)); // Buhid - m_arRanges.push_back(CUnicodeRange(0x1760, 0x177F, 20, 2)); // Tagbanwa - m_arRanges.push_back(CUnicodeRange(0x10300, 0x1032F, 21, 2)); // Old Italic - m_arRanges.push_back(CUnicodeRange(0x10330, 0x1034F, 22, 2)); // Gothic - m_arRanges.push_back(CUnicodeRange(0x10400, 0x1044F, 23, 2)); // Deseret - m_arRanges.push_back(CUnicodeRange(0x1D000, 0x1D0FF, 24, 2)); // Byzantine Musical Symbols - m_arRanges.push_back(CUnicodeRange(0x1D100, 0x1D1FF, 24, 2)); // Musical Symbols - m_arRanges.push_back(CUnicodeRange(0x1D200, 0x1D24F, 24, 2)); // Ancient Greek Musical Notation - m_arRanges.push_back(CUnicodeRange(0x1D400, 0x1D7FF, 25, 2)); // Mathematical Alphanumeric Symbols - m_arRanges.push_back(CUnicodeRange(0xF0000, 0xFFFFD, 26, 2)); // Private Use (plane 15) - m_arRanges.push_back(CUnicodeRange(0x100000, 0x10FFFD, 26, 2)); // Private Use (plane 16) - m_arRanges.push_back(CUnicodeRange(0xFE00, 0xFE0F, 27, 2)); // Variation Selectors - m_arRanges.push_back(CUnicodeRange(0xE0100, 0xE01EF, 27, 2)); // Variation Selectors Supplement - m_arRanges.push_back(CUnicodeRange(0xE0000, 0xE007F, 28, 2)); // Tags - m_arRanges.push_back(CUnicodeRange(0x1900, 0x194F, 29, 2)); // Limbu - m_arRanges.push_back(CUnicodeRange(0x1950, 0x197F, 30, 2)); // Tai Le - m_arRanges.push_back(CUnicodeRange(0x1980, 0x19DF, 31, 2)); // New Tai Lue - - m_arRanges.push_back(CUnicodeRange(0x1A00, 0x1A1F, 0, 3)); // Buginese - m_arRanges.push_back(CUnicodeRange(0x2C00, 0x2C5F, 1, 3)); // Glagolitic - m_arRanges.push_back(CUnicodeRange(0x2D30, 0x2D7F, 2, 3)); // Tifinagh - m_arRanges.push_back(CUnicodeRange(0x4DC0, 0x4DFF, 3, 3)); // Yijing Hexagram Symbols - m_arRanges.push_back(CUnicodeRange(0xA800, 0xA82F, 4, 3)); // Syloti Nagri - m_arRanges.push_back(CUnicodeRange(0x10000, 0x1007F, 5, 3)); // Linear B Syllabary - m_arRanges.push_back(CUnicodeRange(0x10080, 0x100FF, 5, 3)); // Linear B Ideograms - m_arRanges.push_back(CUnicodeRange(0x10100, 0x1013F, 5, 3)); // Aegean Numbers - m_arRanges.push_back(CUnicodeRange(0x10140, 0x1018F, 6, 3)); // Ancient Greek Numbers - m_arRanges.push_back(CUnicodeRange(0x10380, 0x1039F, 7, 3)); // Ugaritic - m_arRanges.push_back(CUnicodeRange(0x103A0, 0x103DF, 8, 3)); // Old Persian - m_arRanges.push_back(CUnicodeRange(0x10450, 0x1047F, 9, 3)); // Shavian - m_arRanges.push_back(CUnicodeRange(0x10480, 0x104AF, 10, 3)); // Osmanya - m_arRanges.push_back(CUnicodeRange(0x10800, 0x1083F, 11, 3)); // Cypriot Syllabary - m_arRanges.push_back(CUnicodeRange(0x10A00, 0x10A5F, 12, 3)); // Kharoshthi - m_arRanges.push_back(CUnicodeRange(0x1D300, 0x1D35F, 13, 3)); // Tai Xuan Jing Symbols - m_arRanges.push_back(CUnicodeRange(0x12000, 0x123FF, 14, 3)); // Cuneiform - m_arRanges.push_back(CUnicodeRange(0x12400, 0x1247F, 14, 3)); // Cuneiform Numbers and Punctuation - m_arRanges.push_back(CUnicodeRange(0x1D360, 0x1D37F, 15, 3)); // Counting Rod Numerals - m_arRanges.push_back(CUnicodeRange(0x1B80, 0x1BBF, 16, 3)); // Sundanese - m_arRanges.push_back(CUnicodeRange(0x1C00, 0x1C4F, 17, 3)); // Lepcha - m_arRanges.push_back(CUnicodeRange(0x1C50, 0x1C7F, 18, 3)); // Ol Chiki - m_arRanges.push_back(CUnicodeRange(0xA880, 0xA8DF, 19, 3)); // Saurashtra - m_arRanges.push_back(CUnicodeRange(0xA900, 0xA92F, 20, 3)); // Kayah Li - m_arRanges.push_back(CUnicodeRange(0xA930, 0xA95F, 21, 3)); // Rejang - m_arRanges.push_back(CUnicodeRange(0xAA00, 0xAA5F, 22, 3)); // Cham - m_arRanges.push_back(CUnicodeRange(0x10190, 0x101CF, 23, 3)); // Ancient Symbols - m_arRanges.push_back(CUnicodeRange(0x101D0, 0x101FF, 24, 3)); // Phaistos Disc - m_arRanges.push_back(CUnicodeRange(0x102A0, 0x102DF, 25, 3)); // Carian - m_arRanges.push_back(CUnicodeRange(0x10280, 0x1029F, 25, 3)); // Lycian - m_arRanges.push_back(CUnicodeRange(0x10920, 0x1093F, 25, 3)); // Lydian - m_arRanges.push_back(CUnicodeRange(0x1F030, 0x1F09F, 26, 3)); // Domino Tiles - m_arRanges.push_back(CUnicodeRange(0x1F000, 0x1F02F, 26, 3)); // Mahjong Tiles - // 27: "Reserved for process-internal usage" - // 28: "Reserved for process-internal usage" - // 29: "Reserved for process-internal usage" - // 30: "Reserved for process-internal usage" - // 31: "Reserved for process-internal usage" - } - - void CUnicodeRanges::CheckRange(const int& symbol, BYTE& Range, BYTE& RangeNum) - { - // определяем range и двигаем его в начало. - std::list::iterator iter = m_arRanges.begin(); - while (iter != m_arRanges.end()) - { - CUnicodeRange& range = *iter; - if (symbol >= range.Start && symbol <= range.End) - { - Range = range.Range; - RangeNum = range.RangeNum; - - m_arRanges.splice(m_arRanges.begin(), m_arRanges, iter); - return; - } - iter++; - } - } - - void CUnicodeRanges::CheckRange(const int& symbol, int& Range1, int& Range2, int& Range3, int& Range4) - { - BYTE nRange = 0xFF; - BYTE nRangeNum = 0xFF; - CheckRange(symbol, nRange, nRangeNum); - - switch (nRangeNum) - { - case 0: Range1 |= (1 << nRange); break; - case 1: Range2 |= (1 << nRange); break; - case 2: Range3 |= (1 << nRange); break; - case 3: Range4 |= (1 << nRange); break; - default: - break; - } - } - - CFontAdvanced::CFontAdvanced() - { - m_oFont.SetDefaultParams(); - m_arSignature.clear(); - } - - CFontAdvanced::CFontAdvanced(const CFontAdvanced& oSrc) - { - *this = oSrc; - } - - CFontAdvanced& CFontAdvanced::operator=(const CFontAdvanced& oSrc) - { - if (this == &oSrc) - { - return *this; - } - - m_oFont = oSrc.m_oFont; - - m_dAscent = oSrc.m_dAscent; - m_dDescent = oSrc.m_dDescent; - m_dLineSpacing = oSrc.m_dLineSpacing; - m_dEmHeight = oSrc.m_dEmHeight; - - m_dBaselineOffset = oSrc.m_dBaselineOffset; - - m_dSpaceWidthMM = oSrc.m_dSpaceWidthMM; - - m_strFamilyName = oSrc.m_strFamilyName; - m_strPANOSE = oSrc.m_strPANOSE; - m_lStyle = oSrc.m_lStyle; - m_arSignature = oSrc.m_arSignature; - m_bIsFixedWidth = oSrc.m_bIsFixedWidth; - m_lAvgWidth = oSrc.m_lAvgWidth; - - return *this; - } - - CFontPickUp::CFontPickUp() : m_oFont() - { - } - - CFontPickUp::CFontPickUp(const CFontPickUp& oSrc) - { - *this = oSrc; - } - - CFontPickUp& CFontPickUp::operator=(const CFontPickUp& oSrc) - { - if (this == &oSrc) - { - return *this; - } - - m_oFont = oSrc.m_oFont; - m_lRange = oSrc.m_lRange; - m_lRangeNum = oSrc.m_lRangeNum; - m_strPickFont = oSrc.m_strPickFont; - m_lPickStyle = oSrc.m_lPickStyle; - - return *this; - } - - CFontManagerBase::CFontManagerBase(NSFonts::IApplicationFonts* pFonts) - { - m_pManager = NSFontManager::CreateFontManager(pFonts); - - SetDefaultFont(L"Arial"); - - ClearPickUps(); - } - - CFontManagerBase::~CFontManagerBase() - { - RELEASEINTERFACE(m_pManager); - } - - void CFontManagerBase::ClearPickUps() - { - m_arListPicUps.clear(); - m_strCurrentPickFont = L""; - m_lCurrentPictFontStyle = 0; - } - - void CFontManagerBase::SetDefaultFont(const std::wstring& strName) - { - m_strDefaultFont = strName; - } - - std::wstring CFontManagerBase::GetDefaultFont() - { - return m_strDefaultFont; - } - - void CFontManagerBase::LoadFont(long lFaceIndex, bool bIsNeedAddToMap) - { - } - - void CFontManagerBase::LoadFontByName(const std::wstring& strName, const double& dSize, const LONG& lStyle, const double& dDpiX, const double& dDpiY) - { - m_pManager->LoadFontByName(strName, (float)dSize, lStyle, dDpiX, dDpiY); - m_pManager->AfterLoad(); - - LoadFontMetrics(); - LoadFontParams(); - - m_oFont.m_lAvgWidth = -1; - } - - void CFontManagerBase::LoadFontByFile(const std::wstring& strPath, const double& dSize, const double& dDpiX, const double& dDpiY, const LONG& lFaceIndex) - { - m_pManager->LoadFontFromFile(strPath, (int)lFaceIndex, (float)dSize, dDpiX, dDpiY); - m_pManager->AfterLoad(); - - LoadFontMetrics(); - LoadFontParams(); - m_oFont.m_oFont.Name = m_pManager->GetName(); - m_oFont.m_strFamilyName = m_oFont.m_oFont.Name; - - m_oFont.m_lAvgWidth = -1; - - bool bIsCID = false; - std::wstring sFileExt = NSFile::GetFileExtention(strPath); - if (std::wstring::npos != sFileExt.find(L"cid")) - bIsCID = true; - - std::wstring sFileName = NSFile::GetFileName(strPath); - std::wstring::size_type pos = sFileName.rfind('.'); - if (std::wstring::npos != pos) - sFileName = sFileName.substr(0, pos); - std::wstring sEncFilePath = NSFile::GetDirectoryName(strPath) + L"/" + sFileName + L".enc"; - - XmlUtils::CXmlNode oMainNode; - oMainNode.FromXmlFile(sEncFilePath); - - if (L"PDF-resources" == oMainNode.GetName()) - { - if (bIsCID) - { - XmlUtils::CXmlNode oType0Node; - if ( oMainNode.GetNode( L"Type0", oType0Node ) ) - { - XmlUtils::CXmlNode oNode; - if ( oType0Node.GetNode( L"DescendantFonts", oNode ) ) - { - XmlUtils::CXmlNode oDescNode; - if ( oNode.GetNode( L"FontDescriptor", oDescNode ) ) - { - XmlUtils::CXmlNode oCurNode; - if ( oNode.GetNode( L"AvgWidth", oCurNode ) ) - { - std::wstring sValue = oCurNode.GetAttribute(L"value"); - try { - m_oFont.m_lAvgWidth = (SHORT)std::stol(sValue); - } catch (std::invalid_argument &) {} - } - } - } - } - } - else - { - XmlUtils::CXmlNode oNode; - if ( oMainNode.GetNode( L"FontDescriptor", oNode ) ) - { - XmlUtils::CXmlNode oCurNode; - if ( oNode.GetNode( L"AvgWidth", oCurNode ) ) - { - std::wstring sValue = oCurNode.GetAttribute(L"value"); - try { - m_oFont.m_lAvgWidth = (SHORT)std::stol(sValue); - } catch (std::invalid_argument &) {} - } - } - } - } - } - - void CFontManagerBase::CalculateBaselineOffset() - { - LoadFont(); - - double d1 = 3 * (m_oFont.m_dLineSpacing - m_oFont.m_dDescent) - m_oFont.m_dAscent; - d1 /= 2.0; - - d1 *= (m_oFont.m_oFont.Size / m_oFont.m_dEmHeight); - m_oFont.m_dBaselineOffset = d1; - } - - void CFontManagerBase::LoadFontMetrics() - { - m_oFont.m_dAscent = m_pManager->GetAscender(); - m_oFont.m_dDescent = m_pManager->GetDescender(); - m_oFont.m_dLineSpacing = m_pManager->GetLineHeight(); - m_oFont.m_dEmHeight = m_pManager->GetUnitsPerEm(); - - m_oFont.m_dBaselineOffset = (c_dPtToMM * m_oFont.m_dDescent * m_oFont.m_oFont.Size / m_oFont.m_dEmHeight); - } - - std::wstring CFontManagerBase::ToHexString( BYTE uc ) - { - std::wstring sRet = L""; - char c1 = (char)(uc >> 4); - char c2 = (char)(uc & 0x0F); - sRet += (wchar_t)((c1 < 10) ? ('0' + c1) : ('A' + c1 - 10)); - sRet += (wchar_t)((c2 < 10) ? ('0' + c2) : ('A' + c2 - 10)); - return sRet; - } - - BYTE CFontManagerBase::FromHexString( wchar_t c1, wchar_t c2 ) - { - BYTE res = 0; - res |= ((c1 >= 'A') ? (c1 - 'A' + 10) : (c1 - '0')); - res <<= 4; - res |= ((c2 >= 'A') ? (c2 - 'A' + 10) : (c2 - '0')); - return res; - } - - void CFontManagerBase::LoadFontParams(bool bIsPath) - { - // читаем и выставляем все настройки шрифта - if (nullptr == m_pManager || nullptr == m_pManager->GetFile()) - return; - - m_oFont.m_strFamilyName = m_oFont.m_oFont.Name; - - m_oFont.m_lStyle = 0x00; - if (m_pManager->GetFile()->IsBold()) - { - m_oFont.m_lStyle |= 0x01; - } - if (m_pManager->GetFile()->IsItalic()) - { - m_oFont.m_lStyle |= 0x02; - } - - // PANOSE - BYTE pPanose[10]; - m_pManager->GetFile()->GetPanose(pPanose); - m_oFont.m_strPANOSE.clear(); - for ( int i = 0; i < 10; i++ ) - { - m_oFont.m_strPANOSE += ToHexString(pPanose[i]); - } - - // IsFixed - m_oFont.m_bIsFixedWidth = m_pManager->GetFile()->IsFixedWidth(); - - // Signature - m_oFont.m_arSignature.clear(); - - for ( unsigned int i = 0; i < 6; i++ ) - { - DWORD value = 0; - - for ( unsigned long bit = 0; bit < 32; bit++ ) - { - if (m_pManager->GetFile()->IsUnicodeRangeAvailable(bit, i)) - { - value |= ( 1 << bit ); - } - } - - m_oFont.m_arSignature.push_back(value); - } - } - - void CFontManagerBase::CheckRanges(UINT& lRange1, UINT& lRange2, UINT& lRange3, UINT& lRange4, BYTE& lRangeNum, BYTE& lRange) - { - if (0 == lRangeNum) - lRange1 |= 1 << lRange; - else if (1 == lRangeNum) - lRange2 |= 1 << lRange; - else if (2 == lRangeNum) - lRange3 |= 1 << lRange; - else - lRange4 |= 1 << lRange; - } - - bool CFontManagerBase::GenerateFontName(NSStringUtils::CStringUTF32& oText) - { - if (m_oFont.m_oFont.Path.empty() || oText.empty()) - { - m_strCurrentPickFont = m_oFont.m_strFamilyName; - m_lCurrentPictFontStyle = m_oFont.m_lStyle; - return false; - } - - BYTE lRangeNum = 0xFF; - BYTE lRange = 0xFF; - - m_oRanges.CheckRange(oText[0], lRange, lRangeNum); - std::list::iterator posStart, pos; - posStart = pos = m_arListPicUps.begin(); - - while (m_arListPicUps.end() != pos) - { - std::list::iterator posOld = pos; - CFontPickUp& oPick = *(pos++); - if ((oPick.m_oFont.m_oFont.IsEqual2(&m_oFont.m_oFont)) && (lRangeNum == oPick.m_lRangeNum) && (lRange == oPick.m_lRange)) - { - // нашли! ничего подбирать не нужно - // нужно просто выкинуть этот шрифт наверх - m_arListPicUps.splice(m_arListPicUps.begin(), m_arListPicUps, posOld); - m_strCurrentPickFont = oPick.m_strPickFont; - m_lCurrentPictFontStyle = oPick.m_lPickStyle; - return false; - } - } - - // не нашли... - CFontPickUp oPick; - oPick.m_lRangeNum = lRangeNum; - oPick.m_lRange = lRange; - oPick.m_oFont = m_oFont; - oPick.m_strPickFont = m_oFont.m_strFamilyName; - oPick.m_lPickStyle = m_oFont.m_lStyle; - - UINT dwR1 = m_oFont.m_arSignature[0]; - UINT dwR2 = m_oFont.m_arSignature[1]; - UINT dwR3 = m_oFont.m_arSignature[2]; - UINT dwR4 = m_oFont.m_arSignature[3]; - UINT dwCodePage1 = 0; - UINT dwCodePage2 = 0; - - if ((lRangeNum == 1) && (lRange == 28)) - { - dwCodePage1 = 0x80000000; - //strText = (WCHAR)(strText[0] - 0xF000); - } - else if (((lRangeNum == 2) && (lRange == 3)) || ((lRangeNum == 1) && (lRange == 31)) || ((lRangeNum == 0) && (lRange == 13))) - { - // арабский язык!!! - dwR1 = 1 << 13; - dwR2 = 1 << 31; - dwR3 = 1 << 3; - } - else - { - CheckRanges(dwR1, dwR2, dwR3, dwR4, lRangeNum, lRange); - } - - NSFonts::CFontSelectFormat oFormat; - - std::wstring sFontNameSelect = L""; - if (m_oFont.m_strFamilyName.empty() && !m_oFont.m_oFont.Path.empty()) - sFontNameSelect = m_strDefaultFont; - else - sFontNameSelect = m_oFont.m_strFamilyName; - - bool bSelectBold = false; - bool bSelectItalic = false; - CheckFontNamePDF(sFontNameSelect, bSelectBold, bSelectItalic); - - oFormat.wsName = new std::wstring(sFontNameSelect); - - if (!m_oFont.m_strPANOSE.empty()) - { - oFormat.pPanose = new BYTE[10]; - - const wchar_t* pPanoseStr = m_oFont.m_strPANOSE.c_str(); - for (int i = 0; i < 10; ++i) - { - oFormat.pPanose[i] = FromHexString(pPanoseStr[0], pPanoseStr[1]); - pPanoseStr += 2; - } - } - - oFormat.bBold = new INT(((m_oFont.m_lStyle & 0x01) == 0x01) ? 1 : 0); - oFormat.bItalic = new INT(((m_oFont.m_lStyle & 0x02) == 0x02) ? 1 : 0); - oFormat.bFixedWidth = new INT(m_oFont.m_bIsFixedWidth ? 1 : 0); - if (-1 != m_oFont.m_lAvgWidth) - oFormat.shAvgCharWidth = new SHORT((SHORT)m_oFont.m_lAvgWidth); - oFormat.ulRange1 = new UINT(dwR1); - oFormat.ulRange2 = new UINT(dwR2); - oFormat.ulRange3 = new UINT(dwR3); - oFormat.ulRange4 = new UINT(dwR4); - oFormat.ulCodeRange1 = new UINT(dwCodePage1); - oFormat.ulCodeRange2 = new UINT(dwCodePage2); - - if (oFormat.bBold && *(oFormat.bBold) == 1 && oFormat.pPanose && oFormat.pPanose[2] < 7) - oFormat.pPanose[2] = 7; - - oFormat.wsDefaultName = new std::wstring(L"Arial"); - - NSFonts::CFontInfo* pInfo = m_pManager->GetFontInfoByParams(oFormat); - - oPick.m_strPickFont = pInfo->m_wsFontName; - oPick.m_lPickStyle = 0; - if (pInfo->m_bBold) - oPick.m_lPickStyle |= 0x01; - if (pInfo->m_bItalic) - oPick.m_lPickStyle |= 0x02; - - m_strCurrentPickFont = oPick.m_strPickFont; - m_lCurrentPictFontStyle = oPick.m_lPickStyle; - - m_arListPicUps.push_front(oPick); - return true; - } - - bool CFontManagerBase::CheckFontNameStyle(std::wstring& sName, const std::wstring& sStyle) - { - size_t nPos = 0; - size_t nLenReplace = sStyle.length(); - bool bRet = false; - - std::wstring sName2 = sName; - NSStringExt::ToLower(sName2); - - while (std::wstring::npos != (nPos = sName2.find(sStyle, nPos))) - { - size_t nOffset = 0; - if ((nPos > 0) && sName2.at(nPos - 1) == '-') - { - --nPos; - ++nOffset; - } - - bRet = true; - sName.erase(nPos, nLenReplace + nOffset); - sName2.erase(nPos, nLenReplace + nOffset); - } - return bRet; - } - - void CFontManagerBase::CheckFontNamePDF(std::wstring& sName, bool& bBold, bool& bItalic) - { - if (sName.length() > 7 && sName.at(6) == '+') - { - bool bIsRemove = true; - for (int nIndex = 0; nIndex < 6; nIndex++) - { - wchar_t nChar = sName.at(nIndex); - if (nChar < 'A' || nChar > 'Z') - { - bIsRemove = false; - break; - } - } - if (bIsRemove) - { - sName.erase(0, 7); - } - } - - CheckFontNameStyle(sName, L"regular"); - CheckFontNameStyle(sName, L"condensed"); - CheckFontNameStyle(sName, L"condensedlight"); - //CheckFontNameStyle(sName, L"light"); - - CheckFontNameStyle(sName, L"condensedbold"); - CheckFontNameStyle(sName, L"semibold"); - if (CheckFontNameStyle(sName, L"boldmt")) bBold = true; - if (CheckFontNameStyle(sName, L"bold")) bBold = true; - - if (CheckFontNameStyle(sName, L"italicmt")) bItalic = true; - if (CheckFontNameStyle(sName, L"italic")) bItalic = true; - if (CheckFontNameStyle(sName, L"oblique")) bItalic = true; - - if (CheckFontNameStyle(sName, L"bolditalicmt")) { bBold = true; bItalic = true; } - if (CheckFontNameStyle(sName, L"bolditalic")) { bBold = true; bItalic = true; } - if (CheckFontNameStyle(sName, L"bold_italic")) { bBold = true; bItalic = true; } - if (CheckFontNameStyle(sName, L"boldoblique")) { bBold = true; bItalic = true; } - if (CheckFontNameStyle(sName, L"bold_oblique")) { bBold = true; bItalic = true; } - } -} diff --git a/DocxRenderer/src/logic/managers/FontManagerBase.h b/DocxRenderer/src/logic/managers/FontManagerBase.h deleted file mode 100644 index 7e29b7acade..00000000000 --- a/DocxRenderer/src/logic/managers/FontManagerBase.h +++ /dev/null @@ -1,155 +0,0 @@ -#pragma once -#include "../DesktopEditor/graphics/structures.h" -#include "../DesktopEditor/graphics/pro/Fonts.h" -#include "../DesktopEditor/common/StringUTF32.h" -#include - -namespace NSFontManager -{ - static NSFonts::IFontManager* CreateFontManager(NSFonts::IApplicationFonts* pApplication) - { - NSFonts::IFontManager* pManager = pApplication->GenerateFontManager(); - pManager->CreateOwnerCache(8); - return pManager; - } - - class CUnicodeRange - { - public: - BYTE RangeNum {0}; - BYTE Range {0}; - - int Start {0}; - int End {0}; - - CUnicodeRange(const int& _start = 0, - const int& _end = 0, - const BYTE& _range = 0, - const BYTE& _rangenum = 0); - }; - - // класс для проставления Ranges для подбора шрифта по символу - class CUnicodeRanges - { - public: - std::list m_arRanges; - - public: - CUnicodeRanges(); - - void CheckRange(const int& symbol, BYTE& Range, BYTE& RangeNum); - - void CheckRange(const int& symbol, int& Range1, int& Range2, int& Range3, int& Range4); - }; - - class CFontAdvanced - { - public: - NSStructures::CFont m_oFont; - - // font metrics - double m_dAscent {0.0}; - double m_dDescent {0.0}; - double m_dLineSpacing {0.0}; - double m_dEmHeight {0.0}; - - double m_dBaselineOffset {0.0}; - - double m_dSpaceWidthMM {0.0}; - - // font params - std::wstring m_strFamilyName {L""}; - std::wstring m_strPANOSE {L""}; - LONG m_lStyle {0}; - std::vector m_arSignature; - bool m_bIsFixedWidth {false}; - SHORT m_lAvgWidth {-1}; - - public: - CFontAdvanced(); - - CFontAdvanced(const CFontAdvanced& oSrc); - - CFontAdvanced& operator=(const CFontAdvanced& oSrc); - }; - - class CFontPickUp - { - public: - CFontAdvanced m_oFont; - BYTE m_lRangeNum {0xFF}; - BYTE m_lRange {0xFF}; - std::wstring m_strPickFont {L""}; - LONG m_lPickStyle {0}; - - public: - CFontPickUp(); - CFontPickUp(const CFontPickUp& oSrc); - CFontPickUp& operator=(const CFontPickUp& oSrc); - }; - - class CFontManagerBase - { - public: - enum MeasureType - { - mtGlyph = 0, - mtPosition = 1 - }; - - protected: - NSFonts::IFontManager* m_pManager; - std::wstring m_strDefaultFont; - - public: - - CFontAdvanced m_oFont; - - //для подбора шрифтов - CUnicodeRanges m_oRanges; - - std::list m_arListPicUps; - std::wstring m_strCurrentPickFont; - LONG m_lCurrentPictFontStyle; - - public: - CFontManagerBase(NSFonts::IApplicationFonts* pFonts); - virtual ~CFontManagerBase(); - - void ClearPickUps(); - - public: - void SetDefaultFont(const std::wstring& strName); - std::wstring GetDefaultFont(); - - virtual void LoadFont(long lFaceIndex = 0, bool bIsNeedAddToMap = true); - - void LoadFontByName(const std::wstring& strName, const double& dSize, const LONG& lStyle, const double& dDpiX, const double& dDpiY); - - void LoadFontByFile(const std::wstring& strPath, const double& dSize, const double& dDpiX, const double& dDpiY, const LONG& lFaceIndex); - - public: - virtual void MeasureString(const std::wstring& sText, double x, double y, double& dBoxX, double& dBoxY, - double& dBoxWidth, double& dBoxHeight, MeasureType measureType) = 0; - virtual void CalculateBaselineOffset(); - - public: - void LoadFontMetrics(); - - std::wstring ToHexString( BYTE uc ); - - BYTE FromHexString( wchar_t c1, wchar_t c2 ); - - void LoadFontParams(bool bIsPath = true); - - private: - void CheckRanges(UINT& lRange1, UINT& lRange2, UINT& lRange3, UINT& lRange4, BYTE& lRangeNum, BYTE& lRange); - - public: - bool GenerateFontName(NSStringUtils::CStringUTF32& oText); - - bool CheckFontNameStyle(std::wstring& sName, const std::wstring& sStyle); - - void CheckFontNamePDF(std::wstring& sName, bool& bBold, bool& bItalic); - }; -} diff --git a/DocxRenderer/src/logic/managers/FontStyleManager.cpp b/DocxRenderer/src/logic/managers/FontStyleManager.cpp new file mode 100644 index 00000000000..63d8aadebae --- /dev/null +++ b/DocxRenderer/src/logic/managers/FontStyleManager.cpp @@ -0,0 +1,77 @@ +#include "FontStyleManager.h" + +#include + +namespace NSDocxRenderer +{ + CFontStyleManager::CFontStyleManager() + { + } + + CFontStyleManager::~CFontStyleManager() + { + Clear(); + } + + void CFontStyleManager::Clear() + { + m_arFontStyles.clear(); + } + + void CFontStyleManager::ToXml(NSStringUtils::CStringBuilder& oWriter) + { + for(auto& val : m_arFontStyles) + val->ToXml(oWriter); + } + + std::shared_ptr CFontStyleManager::GetOrAddFontStyle(const CFontStyle& oFontStyle) + { + return GetOrAddFontStyle( + oFontStyle.oBrush, + oFontStyle.wsFontName, + oFontStyle.dFontSize, + oFontStyle.bItalic, + oFontStyle.bBold); + } + std::shared_ptr CFontStyleManager::GetOrAddFontStyle( + const NSStructures::CBrush& oBrush, + const std::wstring& wsFontName, + double dFontSize, + bool bItalic, + bool bBold) + { + for(auto it = m_arFontStyles.begin(); it != m_arFontStyles.end(); ++it) + { + if (oBrush.Type == (*it)->oBrush.Type && + oBrush.Color1 == (*it)->oBrush.Color1 && + oBrush.Color2 == (*it)->oBrush.Color2 && + oBrush.Alpha1 == (*it)->oBrush.Alpha1 && + oBrush.Alpha2 == (*it)->oBrush.Alpha2 && + oBrush.LinearAngle == (*it)->oBrush.LinearAngle && + dFontSize == (*it)->dFontSize && + wsFontName == (*it)->wsFontName && + (bItalic == (*it)->bItalic) && (bBold == (*it)->bBold)) + { + auto val = *it; + + // в начало списка + if (it != m_arFontStyles.begin()) + { + m_arFontStyles.erase(it); + m_arFontStyles.push_front(val); + + } + return val; + } + } + auto pFontStyle = std::make_shared(); + pFontStyle->oBrush = oBrush; + pFontStyle->wsFontName = wsFontName; + pFontStyle->dFontSize = dFontSize; + pFontStyle->bItalic = bItalic; + pFontStyle->bBold = bBold; + + m_arFontStyles.push_front(pFontStyle); + return pFontStyle; + } +} diff --git a/DocxRenderer/src/logic/managers/FontStyleManager.h b/DocxRenderer/src/logic/managers/FontStyleManager.h new file mode 100644 index 00000000000..eb58389d6dc --- /dev/null +++ b/DocxRenderer/src/logic/managers/FontStyleManager.h @@ -0,0 +1,29 @@ +#pragma once +#include + +#include "../styles/FontStyle.h" + +namespace NSDocxRenderer +{ + class CFontStyleManager + { + public: + CFontStyleManager(); + ~CFontStyleManager(); + + void Clear(); + void ToXml(NSStringUtils::CStringBuilder& oWriter); + + std::shared_ptr GetOrAddFontStyle(const CFontStyle& oFontStyle); + std::shared_ptr GetOrAddFontStyle( + const NSStructures::CBrush& oBrush, + const std::wstring& wsFontName, + double dFontSize, + bool bItalic, + bool bBold); + + private: + std::list> m_arFontStyles; + }; +} + diff --git a/DocxRenderer/src/logic/managers/ImageManager.cpp b/DocxRenderer/src/logic/managers/ImageManager.cpp index 6483fdd6aa8..2036ea99f9d 100644 --- a/DocxRenderer/src/logic/managers/ImageManager.cpp +++ b/DocxRenderer/src/logic/managers/ImageManager.cpp @@ -1,158 +1,225 @@ #include "ImageManager.h" -#include "../DesktopEditor/common/Directory.h" + +#include "../../../../DesktopEditor/common/Directory.h" +#include "../../../../DesktopEditor/raster/BgraFrame.h" + +#include "../../resources/Constants.h" namespace NSDocxRenderer { - void CImageManager::NewDocument() + IImageStorage::IImageStorage(){} + IImageStorage::~IImageStorage(){} + + class CDataImageStorage : public IImageStorage { - m_strDstMedia = L""; - m_lMaxSizeImage = 1200; - m_lNextIDImage = 0; + private: + std::map> m_mapImageData; + std::map m_mapImages; - m_mapImageData.clear(); - m_mapImagesFile.clear(); - } + int m_lMaxSizeImage{1200}; + int m_lNextIDImage{0}; - std::shared_ptr CImageManager::WriteImage(Aggplus::CImage* pImage, double& x, double& y, double& width, double& height) - { - if (height < 0) + CCalculatorCRC32 m_oCRC; + + public: + CDataImageStorage() : IImageStorage() + { + } + virtual ~CDataImageStorage() { - FlipY(pImage); - height = -height; - y -= height; } - return GenerateImageID(pImage); - } + virtual std::shared_ptr GenerateImageID(Aggplus::CImage* pImage) + { + BYTE* pData = pImage->GetData(); + DWORD nWidth = pImage->GetWidth(); + DWORD nHeight = pImage->GetHeight(); + long nStride = pImage->GetStride(); - std::shared_ptr CImageManager::WriteImage(const std::wstring& strFile, double& x, double& y, double& width, double& height) - { - return GenerateImageID(strFile); - } + int nSize = pImage->GetStride() * nHeight; + if (nSize < 0) + nSize = -nSize; - void CImageManager::CopyFile(std::wstring& strFileSrc, std::wstring& strFileDst) - { - NSFile::CFileBinary::Copy(strFileSrc, strFileDst); - } + DWORD dwSum = m_oCRC.Calc(pData, nSize); - void CImageManager::SaveEmptyImage(std::shared_ptr pInfo) - { - Aggplus::CImage oFrame; + auto find = m_mapImageData.find(dwSum); + if (find != m_mapImageData.end()) + return find->second; - int nW = 10; - int nH = 10; - int nMax = nW * nH; - BYTE* pDataExternal = new BYTE[nMax * 4]; - memset(pDataExternal, 0xFF, 4 * nMax); + ++m_lNextIDImage; - BYTE* pDataCurrent = pDataExternal + 3; - for (int i = 0; i < nMax; i++, pDataCurrent += 4) - *pDataCurrent = 0; + auto pInfo = std::make_shared(); + pInfo->m_nId = m_lNextIDImage; + pInfo->m_eType = CImageManager::GetImageType(pImage); + pInfo->m_strFileName = L"image" + std::to_wstring(pInfo->m_nId) + ((pInfo->m_eType == CImageInfo::itJPG) ? L".jpg" : L".png"); - oFrame.Create(pDataExternal, nW, nH, 4 * nW, true); + CBgraFrame oBgraFrame; + oBgraFrame.put_Width(nWidth); + oBgraFrame.put_Height(nHeight); + oBgraFrame.put_Stride(nStride); + oBgraFrame.put_Data(pData); + bool bIsResized = false; - pInfo->m_eType = CImageInfo::itPNG; - pInfo->m_strFileName += (L"image" + std::to_wstring(pInfo->m_nId) + L".png"); + if (nWidth > m_lMaxSizeImage || nHeight > m_lMaxSizeImage) + { + int lW = 0; + int lH = 0; + double dAspect = (double)nWidth / nHeight; + + if (nWidth >= nHeight) + { + lW = m_lMaxSizeImage; + lH = (int)((double)lW / dAspect); + if (lH < 1) lH = 1; + } + else + { + lH = m_lMaxSizeImage; + lW = (int)(dAspect * lH); + if (lW < 1) lW = 1; + } + + bIsResized = true; + oBgraFrame.Resize(lW, lH, false); + } - oFrame.SaveFile(m_strDstMedia + L"/" + pInfo->m_strFileName, 4); - delete[] pDataExternal; - } + BYTE* pEncodeBuffer = NULL; + int nEncodeBufferSize = 0; + oBgraFrame.Encode(pEncodeBuffer, nEncodeBufferSize, (pInfo->m_eType == CImageInfo::itJPG) ? 3 : 4); - void CImageManager::SaveImage(Aggplus::CImage* pImage, std::shared_ptr pInfo) - { - if (nullptr == pImage) - return; + if (!bIsResized) + oBgraFrame.put_Data(NULL); - int w = pImage->GetWidth(); - int h = pImage->GetHeight(); + int nBase64DataSize = NSBase64::Base64EncodeGetRequiredLength(nEncodeBufferSize); + int nHeaderSize = (pInfo->m_eType == CImageInfo::itPNG) ? 22 : 23; - pInfo->m_eType = GetImageType(pImage); + char* pBase64Data = new char[nBase64DataSize + nHeaderSize]; + if (pInfo->m_eType == CImageInfo::itPNG) + memcpy(pBase64Data, "data:image/png;base64,", nHeaderSize); + else + memcpy(pBase64Data, "data:image/jpeg;base64,", nHeaderSize); - UINT format = (pInfo->m_eType == CImageInfo::itJPG) ? 3 : 4; - pInfo->m_strFileName = L"image" + std::to_wstring(pInfo->m_nId); - pInfo->m_strFileName += ((pInfo->m_eType == CImageInfo::itJPG) ? L".jpg" : L".png"); + NSBase64::Base64Encode(pEncodeBuffer, nEncodeBufferSize, (BYTE*)pBase64Data + nHeaderSize, &nBase64DataSize, NSBase64::B64_BASE64_FLAG_NOCRLF); + RELEASEARRAYOBJECTS(pEncodeBuffer); - std::wstring sSavedFile = m_strDstMedia + L"/" + pInfo->m_strFileName; + m_mapImages.insert(std::pair((int)pInfo->m_nId, std::string(pBase64Data, nHeaderSize + nBase64DataSize))); + RELEASEARRAYOBJECTS(pBase64Data); - if (w <= m_lMaxSizeImage && h <= m_lMaxSizeImage) - { - pImage->SaveFile(sSavedFile, format); + m_mapImageData.insert(std::pair>(dwSum, pInfo)); + return pInfo; } - else + + virtual std::string* GetBase64(const int& nRId) { - int lW = 0; - int lH = 0; - double dAspect = (double)w / h; + std::map::iterator iter = m_mapImages.find(nRId - c_iStartingIdForImages); + if (iter == m_mapImages.end()) + return NULL; - if (w >= h) - { - lW = m_lMaxSizeImage; - lH = (int)((double)lW / dAspect); - } - else - { - lH = m_lMaxSizeImage; - lW = (LONG)(dAspect * lH); - } + return &iter->second; + } + }; + + IImageStorage* CreateWasmImageStorage() + { + return new CDataImageStorage(); + } +} - // TODO: resize - pImage->SaveFile(sSavedFile, format); +namespace NSDocxRenderer +{ + void CImageManager::Clear() + { + m_strDstMedia = L""; + m_lMaxSizeImage = 1200; + m_lNextIDImage = 0; + + m_mapImageData.clear(); + } + + std::shared_ptr CImageManager::WriteImage(Aggplus::CImage* pImage, double& x, double& y, double& width, double& height) + { + if (height < 0) + { + FlipY(pImage); + height = -height; + y -= height; } + return GenerateImageID(pImage); + } + + std::shared_ptr CImageManager::WriteImage(const std::wstring& strFile, double& x, double& y, double& width, double& height) + { + Aggplus::CImage image(strFile); + return GenerateImageID(&image); } std::shared_ptr CImageManager::GenerateImageID(Aggplus::CImage* pImage) { - BYTE* pData = pImage->GetData(); - int nSize = pImage->GetStride() * pImage->GetHeight(); - if (nSize < 0) - nSize = -nSize; + if (pImage->GetStride() > 0) + FlipY(pImage); - DWORD dwSum = m_oCRC.Calc(pData, nSize); + if (m_pExternalStorage) + return m_pExternalStorage->GenerateImageID(pImage); - auto find = m_mapImageData.find(dwSum); + int size = pImage->GetStride() * pImage->GetHeight(); + if (size < 0) + size = -size; + + BYTE* data = pImage->GetData(); + DWORD width = pImage->GetWidth(); + DWORD height = pImage->GetHeight(); + long stride = pImage->GetStride(); + + DWORD sum = m_oCRC.Calc(data, size); + auto find = m_mapImageData.find(sum); if (find != m_mapImageData.end()) return find->second; ++m_lNextIDImage; auto pInfo = std::make_shared(); pInfo->m_nId = m_lNextIDImage; - SaveImage(pImage, pInfo); - m_mapImageData.insert(std::pair>(dwSum, pInfo)); - - return pInfo; - } - - std::shared_ptr CImageManager::GenerateImageID(const std::wstring& strFileName) - { - auto find = m_mapImagesFile.find(strFileName); - if (find != m_mapImagesFile.end()) - return find->second; + pInfo->m_eType = GetImageType(pImage); + pInfo->m_strFileName = L"image" + std::to_wstring(pInfo->m_nId); + pInfo->m_strFileName += ((pInfo->m_eType == CImageInfo::itJPG) ? L".jpg" : L".png"); - Aggplus::CImage oFrame(strFileName); + UINT format = (pInfo->m_eType == CImageInfo::itJPG) ? 3 : 4; + std::wstring saved_file = m_strDstMedia + L"/" + pInfo->m_strFileName; - if (nullptr == oFrame.GetData()) + if (width <= m_lMaxSizeImage && height <= m_lMaxSizeImage) { - if (m_pEmptyInfo) - return m_pEmptyInfo; - - ++m_lNextIDImage; - m_pEmptyInfo = std::make_shared(); - m_pEmptyInfo->m_nId = m_lNextIDImage; - m_pEmptyInfo->m_eType = CImageInfo::itPNG; - m_pEmptyInfo->m_strFileName += (L"image" + std::to_wstring(m_pEmptyInfo->m_nId) + L".png"); - - // можно не сохранять - но тогда несуществующие картинки. - // создадим пустую - и посмотрим на жалобы - SaveEmptyImage(m_pEmptyInfo); - return m_pEmptyInfo; + pImage->SaveFile(saved_file, format); } + else + { + CBgraFrame oBgraFrame; + oBgraFrame.put_Width(width); + oBgraFrame.put_Height(height); + oBgraFrame.put_Stride(stride); + oBgraFrame.put_Data(data); - ++m_lNextIDImage; - auto pInfo = std::make_shared(); - pInfo->m_nId = m_lNextIDImage; - SaveImage(&oFrame, pInfo); - m_mapImagesFile.insert(std::pair>(strFileName, pInfo)); - + if (width > m_lMaxSizeImage || height > m_lMaxSizeImage) + { + int lW = 0; + int lH = 0; + double dAspect = (double)width / height; + + if (width >= height) + { + lW = m_lMaxSizeImage; + lH = (int)((double)lW / dAspect); + if (lH < 1) lH = 1; + } + else + { + lH = m_lMaxSizeImage; + lW = (int)(dAspect * lH); + if (lW < 1) lW = 1; + } + oBgraFrame.Resize(lW, lH, false); + } + oBgraFrame.SaveFile(saved_file, format); + } + m_mapImageData.insert(std::pair>(sum, pInfo)); return pInfo; } @@ -201,44 +268,10 @@ namespace NSDocxRenderer memcpy(pBuffer, pBufferEnd, stride); memcpy(pBufferEnd, pBufferMem, stride); - pBuffer += stride; - pBufferEnd -= stride; + pBuffer += stride; + pBufferEnd -= stride; } RELEASEARRAYOBJECTS(pBufferMem); } - - void CImageManager::FlipX(CBgraFrame* pImage) - { - if (nullptr == pImage) - return; - - int w = pImage->get_Width(); - int h = pImage->get_Height(); - BYTE* pBuffer = pImage->get_Data(); - int stride = pImage->get_Stride(); - - if (stride < 0) - stride = -stride; - - if ((w * 4) != stride) - return; - - DWORD* pBufferDWORD = (DWORD*)pBuffer; - - LONG lW2 = w / 2; - for (LONG lIndexV = 0; lIndexV < h; ++lIndexV) - { - DWORD* pMem1 = pBufferDWORD; - DWORD* pMem2 = pBufferDWORD + w - 1; - - LONG lI = 0; - while (lI < lW2) - { - DWORD dwMem = *pMem1; - *pMem1++ = *pMem2; - *pMem2-- = dwMem; - } - } - } -} // namespace NSDocxRenderer +} diff --git a/DocxRenderer/src/logic/managers/ImageManager.h b/DocxRenderer/src/logic/managers/ImageManager.h index bcd2b45db47..d3810fd3e1c 100644 --- a/DocxRenderer/src/logic/managers/ImageManager.h +++ b/DocxRenderer/src/logic/managers/ImageManager.h @@ -1,51 +1,35 @@ #pragma once -#include "../DesktopEditor/common/CalculatorCRC32.h" -#include "../DesktopEditor/raster/BgraFrame.h" -#include "../../resources/ImageInfo.h" + #include -#include + +#include "../../../../DesktopEditor/common/CalculatorCRC32.h" + +#include "ExternalImageStorage.h" namespace NSDocxRenderer { class CImageManager { public: - std::map> m_mapImagesFile; std::map> m_mapImageData; - std::shared_ptr m_pEmptyInfo; - - std::wstring m_strDstMedia{L""}; - - int m_lMaxSizeImage{1200}; - int m_lNextIDImage{0}; - - CCalculatorCRC32 m_oCRC; - - public: - CImageManager(){}; + std::wstring m_strDstMedia {L""}; + IImageStorage* m_pExternalStorage = nullptr; - void NewDocument(); + CImageManager() = default; + ~CImageManager() = default; + void Clear(); - public: std::shared_ptr WriteImage(Aggplus::CImage* pImage, double& x, double& y, double& width, double& height); - std::shared_ptr WriteImage(const std::wstring& strFile, double& x, double& y, double& width, double& height); - - protected: - void CopyFile(std::wstring& strFileSrc, std::wstring& strFileDst); - - void SaveImage(Aggplus::CImage* pImage, std::shared_ptr pInfo); - - void SaveEmptyImage(std::shared_ptr pInfo); - std::shared_ptr GenerateImageID(Aggplus::CImage* pImage); + static CImageInfo::ImageType GetImageType(Aggplus::CImage* pFrame); + private: std::shared_ptr GenerateImageID(const std::wstring& strFileName); - - CImageInfo::ImageType GetImageType(Aggplus::CImage* pFrame); - void FlipY(Aggplus::CImage* pImage); - void FlipX(CBgraFrame* pImage); + int m_lMaxSizeImage {1200}; + int m_lNextIDImage {0}; + CCalculatorCRC32 m_oCRC; }; -} // namespace NSDocxRenderer +} diff --git a/DocxRenderer/src/logic/managers/ParagraphStyleManager.cpp b/DocxRenderer/src/logic/managers/ParagraphStyleManager.cpp new file mode 100644 index 00000000000..dd38ee699c1 --- /dev/null +++ b/DocxRenderer/src/logic/managers/ParagraphStyleManager.cpp @@ -0,0 +1,57 @@ +#include "ParagraphStyleManager.h" + +namespace NSDocxRenderer +{ + CParagraphStyleManager::CParagraphStyleManager() + { + // стандартные стили + CParagraphStyle oNormal(L"Normal", L"Normal"); + CParagraphStyle oHeading1(L"Heading1", L"Heading 1"); + CParagraphStyle oHeading2(L"Heading2", L"Heading 2"); + + oNormal.bIsDefault = true; + + oHeading1.wsBasedOn = oNormal.wsStyleId; + oHeading1.nUiPriority = 9; + + oHeading2.wsBasedOn = oNormal.wsStyleId; + oHeading2.nUiPriority = 9; + + m_arDefaultParagraphStyles.push_back(oNormal); + m_arDefaultParagraphStyles.push_back(oHeading1); + m_arDefaultParagraphStyles.push_back(oHeading2); + + } + CParagraphStyleManager::~CParagraphStyleManager() + { + m_arDefaultParagraphStyles.clear(); + } + + std::wstring CParagraphStyleManager::GetDefaultParagraphStyleId(const CParagraph& oParagraph) const noexcept + { + if(oParagraph.m_arLines.size() > 1) return L"Normal"; + + bool isHeading = true; + for(auto& val : oParagraph.m_arLines[0]->m_arConts) + if(val && val->m_pFontStyle->dFontSize <= m_dAvgFontSize + 1 && !val->m_pFontStyle->bBold) + isHeading = false; + + return isHeading ? L"Heading1" : L"Normal"; + } + double CParagraphStyleManager::GetAvgFontSize() const noexcept + { + return m_dAvgFontSize; + } + void CParagraphStyleManager::UpdateAvgFontSize(double dFontSize) + { + m_dAvgFontSize = (m_dAvgFontSize / (m_nN + 1)) * m_nN + (dFontSize / (m_nN + 1)); + m_nN++; + } + + void CParagraphStyleManager::ToXml(NSStringUtils::CStringBuilder& oWriter) + { + for(auto& val : m_arDefaultParagraphStyles) + val.ToXml(oWriter); + } +} + diff --git a/DocxRenderer/src/logic/managers/ParagraphStyleManager.h b/DocxRenderer/src/logic/managers/ParagraphStyleManager.h new file mode 100644 index 00000000000..ed4d1ae1823 --- /dev/null +++ b/DocxRenderer/src/logic/managers/ParagraphStyleManager.h @@ -0,0 +1,28 @@ +#pragma once +#include + +#include "../elements/Paragraph.h" +#include "../styles/ParagraphStyle.h" + +namespace NSDocxRenderer +{ + class CParagraphStyleManager + { + public: + CParagraphStyleManager(); + ~CParagraphStyleManager(); + + std::wstring GetDefaultParagraphStyleId(const CParagraph& oParagraph) const noexcept; + double GetAvgFontSize() const noexcept; + + void UpdateAvgFontSize(double dFontSize); + void ToXml(NSStringUtils::CStringBuilder& oWriter); + + private: + std::list m_arDefaultParagraphStyles; + // std::list m_arCustomParagraphStyles; + + double m_dAvgFontSize = 0; + int m_nN = 0; + }; +} diff --git a/DocxRenderer/src/logic/managers/StyleManager.cpp b/DocxRenderer/src/logic/managers/StyleManager.cpp deleted file mode 100644 index 87c1ca2ef15..00000000000 --- a/DocxRenderer/src/logic/managers/StyleManager.cpp +++ /dev/null @@ -1,44 +0,0 @@ -#include "StyleManager.h" -#include - -namespace NSDocxRenderer -{ - CStyleManager::CStyleManager() - { - m_pCurrentStyle = std::make_shared(); - } - - CStyleManager::~CStyleManager() - { - Clear(); - } - - void CStyleManager::Clear() - { - m_arStyles.clear(); - } - - void CStyleManager::NewDocument() - { - Clear(); - } - - std::shared_ptr CStyleManager::GetStyle() - { - for (const auto &pStyle : m_arStyles) - { - if (pStyle->IsEqual(m_pCurrentStyle)) - { - return pStyle; - } - } - - m_arStyles.push_back(m_pCurrentStyle); - - auto pStyle = m_pCurrentStyle; - - m_pCurrentStyle = std::make_shared(); - - return pStyle; - } -} diff --git a/DocxRenderer/src/logic/managers/StyleManager.h b/DocxRenderer/src/logic/managers/StyleManager.h deleted file mode 100644 index c555ad96da8..00000000000 --- a/DocxRenderer/src/logic/managers/StyleManager.h +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once -#include -#include "../styles/FontStyle.h" - -namespace NSDocxRenderer -{ - class CStyleManager - { - public: - std::vector> m_arStyles; - - std::shared_ptr m_pCurrentStyle; - - public: - CStyleManager(); - virtual ~CStyleManager(); - - void Clear(); - - void NewDocument(); - - std::shared_ptr GetStyle(); - }; -} - diff --git a/DocxRenderer/src/logic/styles/BaseStyle.cpp b/DocxRenderer/src/logic/styles/BaseStyle.cpp deleted file mode 100644 index f87eb708b73..00000000000 --- a/DocxRenderer/src/logic/styles/BaseStyle.cpp +++ /dev/null @@ -1,6 +0,0 @@ -#include "BaseStyle.h" - -CBaseStyle::CBaseStyle() -{ - -} diff --git a/DocxRenderer/src/logic/styles/BaseStyle.h b/DocxRenderer/src/logic/styles/BaseStyle.h deleted file mode 100644 index e329daf06b2..00000000000 --- a/DocxRenderer/src/logic/styles/BaseStyle.h +++ /dev/null @@ -1,45 +0,0 @@ -#pragma once -#include "../DesktopEditor/common/StringBuilder.h" - -namespace NSDocxRenderer -{ - class CBaseStyle - { - protected: - enum class eStyleType - { - stUnknown, - stParagraph, - stCharacter, - stTable, - stNumbering - }; - - public: - CBaseStyle(const eStyleType& eType): m_eType(eType) {} - virtual ~CBaseStyle() {} - - CBaseStyle& operator=(const CBaseStyle& oSrc) - { - if (this == &oSrc) - { - return *this; - } - - m_eType = oSrc.m_eType; - m_bIsNotNecessaryToUse = oSrc.m_bIsNotNecessaryToUse; - - return *this; - } - - virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) = 0; - - private: - eStyleType m_eType {eStyleType::stUnknown}; - - public: - bool m_bIsNotNecessaryToUse {false}; - }; - -} - diff --git a/DocxRenderer/src/logic/styles/FontStyle.cpp b/DocxRenderer/src/logic/styles/FontStyle.cpp index aff9871cd0a..ec378218938 100644 --- a/DocxRenderer/src/logic/styles/FontStyle.cpp +++ b/DocxRenderer/src/logic/styles/FontStyle.cpp @@ -1,172 +1,128 @@ #include "FontStyle.h" + #include "../../resources/Constants.h" #include "../../resources/utils.h" namespace NSDocxRenderer { - CFontStyle::CFontStyle() : CBaseStyle(CBaseStyle::eStyleType::stCharacter) - { - static UINT iId = 0; - iId++; - if (iId < 10) - { - m_strStyleId = L"fontstyle0" + std::to_wstring(iId); - } - else - { - m_strStyleId = L"fontstyle" + std::to_wstring(iId); - } - } - - CFontStyle& CFontStyle::operator=(const CFontStyle& oSrc) - { - if (this == &oSrc) - { - return *this; - } - - CBaseStyle::operator=(oSrc); - - m_strStyleId = oSrc.m_strStyleId; - - m_oFont = oSrc.m_oFont; - m_oBrush = oSrc.m_oBrush; - - m_strPickFontName = oSrc.m_strPickFontName; - m_lPickFontStyle = oSrc.m_lPickFontStyle; - - return *this; - } - - void CFontStyle::CopyFormat(const CFontStyle& oSrc) - { - if (this == &oSrc) - { - return; - } - - CBaseStyle::operator=(oSrc); - - m_oFont = oSrc.m_oFont; - m_oBrush = oSrc.m_oBrush; - - m_strPickFontName = oSrc.m_strPickFontName; - m_lPickFontStyle = oSrc.m_lPickFontStyle; - } - - bool CFontStyle::IsEqual(std::shared_ptr oSrc) - { - //note Бывают fonts только с разными path => новый стиль => m_oFont.IsEqual не берем - //todo проверить FaceIndex StringGID - bool bIf1 = m_oFont.Name == oSrc->m_oFont.Name; - bool bIf2 = m_oFont.Size == oSrc->m_oFont.Size; - bool bIf3 = m_oFont.Bold == oSrc->m_oFont.Bold; - bool bIf4 = m_oFont.Italic == oSrc->m_oFont.Italic; - bool bIf5 = m_oFont.Underline == oSrc->m_oFont.Underline; - bool bIf6 = m_oFont.Strikeout == oSrc->m_oFont.Strikeout; - - bool bIf7 = m_oBrush.Type == oSrc->m_oBrush.Type; - bool bIf8 = m_oBrush.Color1 == oSrc->m_oBrush.Color1; - bool bIf9 = m_oBrush.Color2 == oSrc->m_oBrush.Color2; - bool bIf10 = m_oBrush.Alpha1 == oSrc->m_oBrush.Alpha1; - bool bIf11 = m_oBrush.Alpha2 == oSrc->m_oBrush.Alpha2; - bool bIf12 = m_oBrush.LinearAngle == oSrc->m_oBrush.LinearAngle; - - //todo - // (TexturePath == pBrush->TexturePath) && (TextureAlpha == pBrush->TextureAlpha) && (TextureMode == pBrush->TextureMode) && - // (Rectable == pBrush->Rectable) && (Rect.Equals(pBrush->Rect))); - //bool bIf7 = m_oBrush.IsEqual(&oSrc->m_oBrush); - - bool bIf13 = m_strPickFontName == oSrc->m_strPickFontName; - bool bIf14 = m_lPickFontStyle == oSrc->m_lPickFontStyle; - - if (bIf1 && bIf2 && bIf3 && bIf4 && bIf5 && bIf6 && - bIf7 && bIf8 && bIf9 && bIf10 && bIf11 && bIf12 && - bIf13 && bIf14) - { - return true; - } - return false; - } - \ - void CFontStyle::ToXml(NSStringUtils::CStringBuilder& oWriter) - { - if (m_bIsNotNecessaryToUse) - { - return; - } - - oWriter.WriteString(L""); - - oWriter.WriteString(L""); - - oWriter.WriteString(L""); - - //oWriter.WriteString(L""); - - oWriter.WriteString(L""); - - std::wstring& strFontName = m_strPickFontName.empty() ? m_oFont.Name : m_strPickFontName; - oWriter.WriteString(L""); - - if (m_strPickFontName.empty()) - { - if (m_oFont.Bold) - { - oWriter.WriteString(L""); - oWriter.WriteString(L""); - } - if (m_oFont.Italic) - { - oWriter.WriteString(L""); - oWriter.WriteString(L""); - } - } - else - { - if (0x01 == (0x01 & m_lPickFontStyle)) - { - oWriter.WriteString(L""); - oWriter.WriteString(L""); - } - if (0x02 == (0x02 & m_lPickFontStyle)) - { - oWriter.WriteString(L""); - oWriter.WriteString(L""); - } - } - - if (ConvertColorBGRToRGB(m_oBrush.Color1) != c_iBlackColor2) - { - oWriter.WriteString(L""); - } - - int lSize = static_cast(2 * m_oFont.Size); - oWriter.WriteString(L""); - - oWriter.WriteString(L""); - - oWriter.WriteString(L""); - } + CFontStyle::CFontStyle() + { + static LONG lId = 0; + lId++; + wsFontStyleId = m_wsIdStart; + + if(lId < 10) + wsFontStyleId += L"0" + std::to_wstring(lId); + else + wsFontStyleId += std::to_wstring(lId); + } + CFontStyle::CFontStyle(const CFontStyle& oFontStyle) : CFontStyle() + { + *this = oFontStyle; + } + CFontStyle::~CFontStyle() + { + } + + CFontStyle& CFontStyle::operator=(const CFontStyle& oSrc) + { + if (this == &oSrc) + return *this; + + dFontSize = oSrc.dFontSize; + oBrush = oSrc.oBrush; + + wsFontName = oSrc.wsFontName; + bBold = oSrc.bBold; + bItalic = oSrc.bItalic; + return *this; + } + bool CFontStyle::operator==(const CFontStyle& oSrc) + { + bool bIf1 = oBrush.Type == oSrc.oBrush.Type; + bool bIf2 = oBrush.Color1 == oSrc.oBrush.Color1; + bool bIf3 = oBrush.Color2 == oSrc.oBrush.Color2; + bool bIf4 = oBrush.Alpha1 == oSrc.oBrush.Alpha1; + bool bIf5 = oBrush.Alpha2 == oSrc.oBrush.Alpha2; + bool bIf6 = oBrush.LinearAngle == oSrc.oBrush.LinearAngle; + + bool bIf7 = dFontSize == oSrc.dFontSize; + bool bIf8 = wsFontName == oSrc.wsFontName; + bool bIf9 = (bItalic == oSrc.bItalic) && (bBold == oSrc.bBold); + + //todo + // (TexturePath == pBrush->TexturePath) && (TextureAlpha == pBrush->TextureAlpha) && (TextureMode == pBrush->TextureMode) && + // (Rectable == pBrush->Rectable) && (Rect.Equals(pBrush->Rect))); + //bool bIf7 = m_oBrush.IsEqual(&oSrc->m_oBrush); + + return (bIf1 && bIf2 && bIf3 && bIf4 && bIf5 && bIf6 && + bIf7 && bIf8 && bIf9); + } + + void CFontStyle::ToXml(NSStringUtils::CStringBuilder& oWriter) + { + oWriter.WriteString(L""); + + oWriter.WriteString(L""); + + oWriter.WriteString(L""); + + //oWriter.WriteString(L""); + + oWriter.WriteString(L""); + + oWriter.WriteString(L""); + + if (bBold) + { + oWriter.WriteString(L""); + oWriter.WriteString(L""); + } + if (bItalic) + { + oWriter.WriteString(L""); + oWriter.WriteString(L""); + } + + if (ConvertColorBGRToRGB(oBrush.Color1) != c_iBlackColor2) + { + oWriter.WriteString(L""); + } + + int lSize = static_cast(2 * dFontSize); + oWriter.WriteString(L""); + + oWriter.WriteString(L""); + oWriter.WriteString(L""); + } + void CFontStyle::UpdateAvgSpaceWidth(double dWidth) + { + dAvgSpaceWidth = (dAvgSpaceWidth / (m_nN + 1)) * m_nN + (dWidth / (m_nN + 1)); + m_nN++; + } + double CFontStyle::GetAvgSpaceWidth() const + { + return dAvgSpaceWidth; + } } diff --git a/DocxRenderer/src/logic/styles/FontStyle.h b/DocxRenderer/src/logic/styles/FontStyle.h index 469ad7c0ac0..d6e52a1a0bc 100644 --- a/DocxRenderer/src/logic/styles/FontStyle.h +++ b/DocxRenderer/src/logic/styles/FontStyle.h @@ -1,36 +1,38 @@ #pragma once #include -#include "BaseStyle.h" -#include "../managers/FontManager.h" +#include "../../../../DesktopEditor/graphics/structures.h" +#include "../../../../DesktopEditor/common/StringBuilder.h" namespace NSDocxRenderer { - class CFontStyle : public CBaseStyle - { - public: - NSStructures::CFont m_oFont; - NSStructures::CBrush m_oBrush; - - std::wstring m_strPickFontName {L""}; - LONG m_lPickFontStyle {0}; - - private: - std::wstring m_strStyleId {L""}; - - public: - CFontStyle(); - ~CFontStyle(){} - - CFontStyle& operator=(const CFontStyle& oSrc); - void CopyFormat(const CFontStyle& oSrc); - - void ToXml(NSStringUtils::CStringBuilder& oWriter) override final; - - bool IsEqual(std::shared_ptr oSrc); - - std::wstring GetStyleId() {return m_strStyleId;} - }; + class CFontStyle + { + public: + CFontStyle(); + CFontStyle(const CFontStyle& oFontStyle); + ~CFontStyle(); + + CFontStyle& operator=(const CFontStyle& oSrc); + bool operator==(const CFontStyle& oSrc); + + void ToXml(NSStringUtils::CStringBuilder& oWriter); + void UpdateAvgSpaceWidth(double dWidth); + double GetAvgSpaceWidth() const; + + std::wstring wsFontStyleId {L""}; + NSStructures::CBrush oBrush; + std::wstring wsFontName {L""}; + double dFontSize {0}; + bool bItalic {false}; + bool bBold {false}; + + + private: + const std::wstring m_wsIdStart = L"fontstyle"; + double dAvgSpaceWidth {0}; + size_t m_nN {0}; + }; } diff --git a/DocxRenderer/src/logic/styles/ParagraphStyle.cpp b/DocxRenderer/src/logic/styles/ParagraphStyle.cpp new file mode 100644 index 00000000000..ec04f1a6cfe --- /dev/null +++ b/DocxRenderer/src/logic/styles/ParagraphStyle.cpp @@ -0,0 +1,33 @@ +#include "ParagraphStyle.h" + +namespace NSDocxRenderer +{ + CParagraphStyle::CParagraphStyle() + { + } + CParagraphStyle::CParagraphStyle(const std::wstring& wsStyleId, const std::wstring& wsName) + { + this->wsStyleId = wsStyleId; + this->wsName = wsName; + } + CParagraphStyle::~CParagraphStyle() + { + } + + void CParagraphStyle::ToXml(NSStringUtils::CStringBuilder& oWriter) + { + oWriter.WriteString(L""); + oWriter.WriteString(L""); + + if(!wsBasedOn.empty()) oWriter.WriteString(L""); + if(bIsUnhideWhenUsed) oWriter.WriteString(L""); + if(bIsSemiHidden) oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + + oWriter.WriteString(L""); + } +} + diff --git a/DocxRenderer/src/logic/styles/ParagraphStyle.h b/DocxRenderer/src/logic/styles/ParagraphStyle.h new file mode 100644 index 00000000000..115088cd1ca --- /dev/null +++ b/DocxRenderer/src/logic/styles/ParagraphStyle.h @@ -0,0 +1,24 @@ +#pragma once +#include "../../../../DesktopEditor/common/StringBuilder.h" + +namespace NSDocxRenderer +{ + class CParagraphStyle + { + public: + CParagraphStyle(); + CParagraphStyle(const std::wstring& wsStyleId, const std::wstring& wsName); + ~CParagraphStyle(); + + void ToXml(NSStringUtils::CStringBuilder& oWriter); + + std::wstring wsStyleId; + std::wstring wsName; + std::wstring wsBasedOn; + + bool bIsDefault {false}; + bool bIsSemiHidden {false}; + bool bIsUnhideWhenUsed {true}; + LONG nUiPriority {0}; + }; +} diff --git a/DocxRenderer/src/resources/ColorTable.h b/DocxRenderer/src/resources/ColorTable.h index 6df05c6faed..aafd08683ed 100644 --- a/DocxRenderer/src/resources/ColorTable.h +++ b/DocxRenderer/src/resources/ColorTable.h @@ -1,65 +1,64 @@ #pragma once #include #include -#include class ColorTable { - public: - ColorTable () - { - InitClrTable (); - } +public: + ColorTable () + { + InitClrTable (); + } - inline std::wstring ConverColorToString(const unsigned int& sKey) - { - auto iter = m_Table.find(sKey); - if (iter == m_Table.end()) - { - //note если не нашли стандартный цвет, отсылаем что есть - return L"none"; - } - else - { - return iter->second; - } - } + inline std::wstring ConverColorToString(const unsigned int& sKey) + { + auto iter = m_Table.find(sKey); + if (iter == m_Table.end()) + { + //note если не нашли стандартный цвет, отсылаем что есть + return L"none"; + } + else + { + return iter->second; + } + } - inline bool IsStandardColor(const unsigned int& sKey) - { - auto iter = m_Table.find(sKey); - return iter == m_Table.end() ? false : true; - } + inline bool IsStandardColor(const unsigned int& sKey) + { + auto iter = m_Table.find(sKey); + return iter == m_Table.end() ? false : true; + } - private: - std::map m_Table; +private: + std::map m_Table; - private: - void InitClrTable() - { - if (m_Table.size()) - return; +private: + void InitClrTable() + { + if (m_Table.size()) + return; - //ECMA-376-1:2016 17.18.40 ST_HighlightColor (Text Highlight Colors) - m_Table.insert({0x000000, L"black" }); - m_Table.insert({0x0000FF, L"blue" }); - m_Table.insert({0x00FFFF, L"cyan" }); - m_Table.insert({0x00008B, L"darkBlue" }); - m_Table.insert({0x008B8B, L"darkCyan" }); - m_Table.insert({0xA9A9A9, L"darkGray" }); - m_Table.insert({0x006400, L"darkGreen" }); - m_Table.insert({0x800080, L"darkMagenta" }); - m_Table.insert({0x8B0000, L"darkRed" }); - m_Table.insert({0x808000, L"darkYellow" }); - m_Table.insert({0x00FF00, L"green" }); - m_Table.insert({0xD3D3D3, L"lightGray" }); - m_Table.insert({0xFF00FF, L"magenta" }); - m_Table.insert({0xFF0000, L"red" }); - m_Table.insert({0xFFFFFF, L"white" }); - m_Table.insert({0xFFFF00, L"yellow" }); + //ECMA-376-1:2016 17.18.40 ST_HighlightColor (Text Highlight Colors) + m_Table.insert({0x000000, L"black" }); + m_Table.insert({0x0000FF, L"blue" }); + m_Table.insert({0x00FFFF, L"cyan" }); + m_Table.insert({0x00008B, L"darkBlue" }); + m_Table.insert({0x008B8B, L"darkCyan" }); + m_Table.insert({0xA9A9A9, L"darkGray" }); + m_Table.insert({0x006400, L"darkGreen" }); + m_Table.insert({0x800080, L"darkMagenta" }); + m_Table.insert({0x8B0000, L"darkRed" }); + m_Table.insert({0x808000, L"darkYellow" }); + m_Table.insert({0x00FF00, L"green" }); + m_Table.insert({0xD3D3D3, L"lightGray" }); + m_Table.insert({0xFF00FF, L"magenta" }); + m_Table.insert({0xFF0000, L"red" }); + m_Table.insert({0xFFFFFF, L"white" }); + m_Table.insert({0xFFFF00, L"yellow" }); - //note Больше цветов здесь - //core\Common\3dParty\html\css\src\ConstValues.h - //core\DesktopEditor\agg-2.4\svg\agg_svg_color_parser.cpp - } + //note Больше цветов здесь + //core\Common\3dParty\html\css\src\ConstValues.h + //core\DesktopEditor\agg-2.4\svg\agg_svg_color_parser.cpp + } }; diff --git a/DocxRenderer/src/resources/Constants.h b/DocxRenderer/src/resources/Constants.h index 3b9b1ed7b39..0e9b1d98c32 100644 --- a/DocxRenderer/src/resources/Constants.h +++ b/DocxRenderer/src/resources/Constants.h @@ -1,33 +1,48 @@ #pragma once -#include "../DesktopEditor/common/Types.h" +#include +#include + +#include "../../../DesktopEditor/common/Types.h" + #define USING_DELETE_DUPLICATING_CONTS 0 // 0 - все сточки-дубликаты превращаются в shape, 1 - строчки дубликаты удаляются +// #define USE_DEFAULT_FONT_TO_RECALC -const double c_dDpiX = 72.0; -const double c_dDpiY = 72.0; +const double c_dDpiX = 72.0; +const double c_dDpiY = 72.0; -const double c_dInchToMM = 25.4; -constexpr double c_dPixToMM = 25.4 / 72.0; -constexpr double c_dPtToMM = 25.4 / 72.0; -constexpr double c_dMMToPt = 72.0 / 25.4; -constexpr double c_dMMToDx = 72 * 20 / 25.4; -const double c_dMMToEMU = 36000.0; -const double c_dInchToEMU = 914400.0; -const double c_dPtToEMU = 12700.0; -const double c_dDegreeToAngle = 60000.0; +constexpr double c_dMMToPix = 72.0 / 25.4; +constexpr double c_dPixToMM = 25.4 / 72.0; +constexpr double c_dMMToPt = 72.0 / 25.4; +constexpr double c_dPtToMM = 25.4 / 72.0; +constexpr double c_dInchToMM = 25.4; +constexpr double c_dMMToDx = 72 * 20 / 25.4; +constexpr double c_dMMToEMU = 36000.0; +constexpr double c_dInchToEMU = 914400.0; +constexpr double c_dPtToEMU = 12700.0; +constexpr double c_dDegreeToAngle = 60000.0; const double c_dSTANDART_STRING_HEIGHT_MM = 4.2333333333333334; -const double c_dTHE_SAME_STRING_Y_PRECISION_MM = 0.01; -const double c_dLINE_DISTANCE_ERROR_MM = 0.5; -const double c_dERROR_OF_RIGHT_BORDERS_MM = 0.5; -const double c_dERROR_OF_LEFT_BORDERS_MM = 0.1; +const double c_dTHE_SAME_STRING_Y_PRECISION_MM = 0.02; +const double c_dTHE_SAME_STRING_X_PRECISION_MM = 0.02; +const double c_dLINE_DISTANCE_ERROR_MM = 0.3; +const double c_dERROR_OF_PARAGRAPH_BORDERS_MM = 1.0; +const double c_dERROR_GAP = 1.5; const double c_dCENTER_POSITION_ERROR_MM = 1.5; const double c_dTHE_STRING_X_PRECISION_MM = 0.5; const double c_dERROR_FOR_TEXT_WITH_GRAPHICS_MM = 0.1; const double c_dGRAPHICS_ERROR_MM = 0.5; const double c_dGRAPHICS_ERROR_IN_LINES_MM = 0.3; const double c_dMAX_LINE_HEIGHT_MM = 2.5; +const double c_dMAX_LINE_WITH_TEXT_ERROR_MM = 2.5; const double c_dCORRECTION_FOR_FIRST_PARAGRAPH = -1.5; +const double c_dLINE_DISTANCE_MAX_MM = 50.0; +const double c_dSHAPE_TROUGH_MAX_MM = 120.0; +const double c_dLINE_SPLIT_DISTANCE_MM = 10.0; +const double c_dSHAPE_X_OFFSET = 1.5; +const double c_dAVERAGE_SPACE_WIDTH_COEF = 0.9; +const double c_dSPACE_WIDTH_COEF = 0.4; +const double c_dMIN_ROTATION = 0.01; const UINT c_iWhiteColor = 0xFFFFFF; const UINT c_iBlackColor = 0x000000; @@ -39,6 +54,19 @@ const double c_dSTANDART_LEFT_INDENT_MM = 30; const double c_dSTANDART_RIGHT_INDENT_MM = 15; const double c_dSTANDART_FIRSTLINE_INDENT_MM = 12.5; +const uint32_t c_SPACE_SYM = 0x20; + const UINT c_iStartingIdForImages = 6; constexpr size_t c_nAntiZero = ~0; const UINT c_iStandartRelativeHeight = 0x0400; + +constexpr int32_t c_iST_PositionOffsetMax = std::numeric_limits::max(); +constexpr int32_t c_iST_PositionOffsetMin = std::numeric_limits::min(); +constexpr uint64_t c_iST_PositiveCoordinatetMin = 0; +constexpr uint64_t c_iST_PositiveCoordinatetMax = 27273042316900; + +constexpr double c_dST_PositionOffsetMax = c_iST_PositionOffsetMax / c_dMMToEMU; +constexpr double c_dST_PositionOffsetMin = c_iST_PositionOffsetMin / c_dMMToEMU; +constexpr double c_dST_PositiveCoordinatetMin = c_iST_PositiveCoordinatetMin / c_dMMToEMU; +constexpr double c_dST_PositiveCoordinatetMax = c_iST_PositiveCoordinatetMax / c_dMMToEMU; + diff --git a/DocxRenderer/src/resources/ImageInfo.h b/DocxRenderer/src/resources/ImageInfo.h index 6fa00e408c1..311212aaad2 100644 --- a/DocxRenderer/src/resources/ImageInfo.h +++ b/DocxRenderer/src/resources/ImageInfo.h @@ -1,44 +1,45 @@ #pragma once #include -#include "../DesktopEditor/common/Types.h" + +#include "../../../DesktopEditor/common/Types.h" namespace NSDocxRenderer { - class CImageInfo - { - public: - enum ImageType - { - itPNG = 0, - itJPG = 1 - }; - - public: - ImageType m_eType {itPNG}; - UINT m_nId {0}; - std::wstring m_strFileName {L""}; - - public: - CImageInfo(){} - - CImageInfo(const CImageInfo &oSrc) - { - *this = oSrc; - } - - CImageInfo& operator=(const CImageInfo &oSrc) - { - if (this == &oSrc) - { - return *this; - } - - m_eType = oSrc.m_eType; - m_nId = oSrc.m_nId; - m_strFileName = oSrc.m_strFileName; - - return *this; - } - - }; + class CImageInfo + { + public: + enum ImageType + { + itPNG = 0, + itJPG = 1 + }; + + public: + ImageType m_eType {itPNG}; + UINT m_nId {0}; + std::wstring m_strFileName {L""}; + + public: + CImageInfo(){} + + CImageInfo(const CImageInfo &oSrc) + { + *this = oSrc; + } + + CImageInfo& operator=(const CImageInfo &oSrc) + { + if (this == &oSrc) + { + return *this; + } + + m_eType = oSrc.m_eType; + m_nId = oSrc.m_nId; + m_strFileName = oSrc.m_strFileName; + + return *this; + } + + }; } diff --git a/DocxRenderer/src/resources/LinesTable.h b/DocxRenderer/src/resources/LinesTable.h index 0716e56eef8..e52876bafae 100644 --- a/DocxRenderer/src/resources/LinesTable.h +++ b/DocxRenderer/src/resources/LinesTable.h @@ -5,78 +5,108 @@ enum class eSimpleLineType { - sltUnknown, - sltDot, - sltDash, - sltLongDash, - sltWave + sltUnknown, + sltHDot, //Horizontal + sltVDot, //Vertical + sltHDash, + sltVDash, + sltHLongDash, + sltVLongDash, + sltHWave, + sltVWave }; enum class eLineType { - ltUnknown, - ltSingle, - ltDouble, - ltThick, - ltDotted, - ltDottedHeavy, - ltDash, - ltDashedHeavy, - ltDashLong, - ltDashLongHeavy, - ltDotDash, - ltDashDotHeavy, - ltDotDotDash, - ltDashDotDotHeavy, - ltWave, - ltWavyHeavy, - ltWavyDouble, - ltWords, - ltNone + ltUnknown, + ltSingle, + ltDouble, + ltThick, + ltDotted, + ltDottedHeavy, + ltDash, + ltDashedHeavy, + ltDashLong, + ltDashLongHeavy, + ltDotDash, + ltDashDotHeavy, + ltDotDotDash, + ltDashDotDotHeavy, + ltWave, + ltWavyHeavy, + ltWavyDouble, + ltWords, + ltNone }; class LinesTable { - public: - LinesTable () - { - InitLinesTable (); - } +public: + LinesTable() + { + InitLinesTable(); + } - inline std::wstring ConverLineToString(const eLineType& sKey) - { - auto iter = m_Table.find(sKey); - return iter == m_Table.end() ? L"\"none\"" : iter->second; - } + inline std::wstring ConvertLineToString(const eLineType& sKey) + { + auto iter = m_Table.find(sKey); + return iter == m_Table.end() ? L"\"none\"" : iter->second; + } - private: - std::map m_Table; + inline std::wstring ConvertLineToStringPptx(const eLineType& sKey) + { + auto iter = m_TablePptx.find(sKey); + return iter == m_TablePptx.end() ? L"\"none\"" : iter->second; + } - private: - void InitLinesTable() - { - if (m_Table.size()) - return; +private: + std::map m_Table; + std::map m_TablePptx; - //ECMA-376 Part 1 17.18.99 ST_Underline (Underline Patterns) - m_Table.insert({eLineType::ltSingle, L"\"single\""}); - m_Table.insert({eLineType::ltDouble, L"\"double\"" }); - m_Table.insert({eLineType::ltThick, L"\"thick\"" }); - m_Table.insert({eLineType::ltDotted, L"\"dotted\"" }); - m_Table.insert({eLineType::ltDottedHeavy, L"\"dottedHeavy\"" }); - m_Table.insert({eLineType::ltDash, L"\"dash\"" }); - m_Table.insert({eLineType::ltDashedHeavy, L"\"dashedHeavy\"" }); - m_Table.insert({eLineType::ltDashLong, L"\"dashLong\"" }); - m_Table.insert({eLineType::ltDashLongHeavy, L"\"dashLongHeavy\"" }); - m_Table.insert({eLineType::ltDotDash, L"\"dotDash\"" }); - m_Table.insert({eLineType::ltDashDotHeavy, L"\"dashDotHeavy\"" }); - m_Table.insert({eLineType::ltDotDotDash, L"\"dotDotDash\"" }); - m_Table.insert({eLineType::ltDashDotDotHeavy, L"\"dashDotDotHeavy\"" }); - m_Table.insert({eLineType::ltWave, L"\"wave\"" }); - m_Table.insert({eLineType::ltWavyHeavy, L"\"wavyHeavy\"" }); - m_Table.insert({eLineType::ltWavyDouble, L"\"wavyDouble\"" }); - m_Table.insert({eLineType::ltWords, L"\"words\"" }); - m_Table.insert({eLineType::ltNone, L"\"none\"" }); - } +private: + void InitLinesTable() + { + if (m_Table.size()) + return; + + //ECMA-376 Part 1 17.18.99 ST_Underline (Underline Patterns) + m_Table.insert({eLineType::ltSingle, L"\"single\""}); + m_Table.insert({eLineType::ltDouble, L"\"double\"" }); + m_Table.insert({eLineType::ltThick, L"\"thick\"" }); + m_Table.insert({eLineType::ltDotted, L"\"dotted\"" }); + m_Table.insert({eLineType::ltDottedHeavy, L"\"dottedHeavy\"" }); + m_Table.insert({eLineType::ltDash, L"\"dash\"" }); + m_Table.insert({eLineType::ltDashedHeavy, L"\"dashedHeavy\"" }); + m_Table.insert({eLineType::ltDashLong, L"\"dashLong\"" }); + m_Table.insert({eLineType::ltDashLongHeavy, L"\"dashLongHeavy\"" }); + m_Table.insert({eLineType::ltDotDash, L"\"dotDash\"" }); + m_Table.insert({eLineType::ltDashDotHeavy, L"\"dashDotHeavy\"" }); + m_Table.insert({eLineType::ltDotDotDash, L"\"dotDotDash\"" }); + m_Table.insert({eLineType::ltDashDotDotHeavy, L"\"dashDotDotHeavy\"" }); + m_Table.insert({eLineType::ltWave, L"\"wave\"" }); + m_Table.insert({eLineType::ltWavyHeavy, L"\"wavyHeavy\"" }); + m_Table.insert({eLineType::ltWavyDouble, L"\"wavyDouble\"" }); + m_Table.insert({eLineType::ltWords, L"\"words\"" }); + m_Table.insert({eLineType::ltNone, L"\"none\"" }); + + m_TablePptx.insert({eLineType::ltSingle, L"\"sng\""}); + m_TablePptx.insert({eLineType::ltDouble, L"\"dbl\"" }); + m_TablePptx.insert({eLineType::ltThick, L"\"heavy\"" }); + m_TablePptx.insert({eLineType::ltDotted, L"\"dotted\"" }); + m_TablePptx.insert({eLineType::ltDottedHeavy, L"\"dottedHeavy\"" }); + m_TablePptx.insert({eLineType::ltDash, L"\"dash\"" }); + m_TablePptx.insert({eLineType::ltDashedHeavy, L"\"dashHeavy\"" }); + m_TablePptx.insert({eLineType::ltDashLong, L"\"dashLong\"" }); + m_TablePptx.insert({eLineType::ltDashLongHeavy, L"\"dashLongHeavy\"" }); + m_TablePptx.insert({eLineType::ltDotDash, L"\"dotDash\"" }); + m_TablePptx.insert({eLineType::ltDashDotHeavy, L"\"dotDashHeavy\"" }); + m_TablePptx.insert({eLineType::ltDotDotDash, L"\"dotDotDash\"" }); + m_TablePptx.insert({eLineType::ltDashDotDotHeavy, L"\"dotDotDashHeavy\"" }); + m_TablePptx.insert({eLineType::ltWave, L"\"wavy\"" }); + m_TablePptx.insert({eLineType::ltWavyHeavy, L"\"wavyHeavy\"" }); + m_TablePptx.insert({eLineType::ltWavyDouble, L"\"wavyDbl\"" }); + m_TablePptx.insert({eLineType::ltWords, L"\"words\"" }); + m_TablePptx.insert({eLineType::ltNone, L"\"none\"" }); + } }; diff --git a/DocxRenderer/src/resources/SingletonTemplate.h b/DocxRenderer/src/resources/SingletonTemplate.h index bb589adee57..ba038f04c85 100644 --- a/DocxRenderer/src/resources/SingletonTemplate.h +++ b/DocxRenderer/src/resources/SingletonTemplate.h @@ -3,20 +3,20 @@ template class SingletonTemplate{ public: - static T& GetInstance() - { - static T instance; - return instance; - } + static T& GetInstance() + { + static T instance; + return instance; + } protected: - SingletonTemplate(){} - SingletonTemplate(const SingletonTemplate&) = delete; - SingletonTemplate& operator=(const SingletonTemplate&) = delete; - virtual ~SingletonTemplate() {} + SingletonTemplate(){} + SingletonTemplate(const SingletonTemplate&) = delete; + SingletonTemplate& operator=(const SingletonTemplate&) = delete; + virtual ~SingletonTemplate() {} }; template inline T& SingletonInstance() { - return SingletonTemplate::GetInstance(); + return SingletonTemplate::GetInstance(); } diff --git a/DocxRenderer/src/resources/SortElements.h b/DocxRenderer/src/resources/SortElements.h deleted file mode 100644 index e696ea09bae..00000000000 --- a/DocxRenderer/src/resources/SortElements.h +++ /dev/null @@ -1,79 +0,0 @@ -#pragma once -#include - -// у класса T должен быть метод IsBigger, IsBiggerOrEqual -template -void SortElements(std::vector& oArray) -{ - int nSize = (int)oArray.size(); - - // handle 0, 1 and 2 elements - if (nSize <= 1) - return; - if (nSize == 2) - { - if (oArray[0]->IsBigger(oArray[1])) - { - std::swap(oArray[0], oArray[1]); - } - return; - } - - T* tTemp; - - // arrange elements as tree with greater elements appearing first - int nIndex = (nSize >> 1) - 1, nCurr = 0, nNext = 0; - int nLast = nSize - 1; - int nHalf = nSize >> 1; - do - { - // save element at start of chain - tTemp = oArray[nIndex]; - - nCurr = nIndex; - while (nCurr < nHalf) - { - nNext = (nCurr << 1) + 1; - if (nNext < nLast && (oArray[nNext + 1]->IsBigger(oArray[nNext]))) - nNext++; - if (tTemp->IsBiggerOrEqual(oArray[nNext])) - break; - - // promote element in chain - oArray[nCurr] = oArray[nNext]; - nCurr = nNext; - } - - // restore element at end of chain - oArray[nCurr] = tTemp; - } - while (nIndex--); - - // sequentially reduce tree size by removing maximum element and rebalancing - nIndex = nSize; - while (--nIndex) - { - // save element at start of chain - tTemp = oArray[nIndex]; - oArray[nIndex] = oArray[0]; - - nCurr = 0; - nLast = nIndex - 1; - nHalf = nIndex >> 1; - while (nCurr < nHalf) - { - nNext = (nCurr << 1) + 1; - if (nNext < nLast && (oArray[nNext + 1]->IsBigger(oArray[nNext]))) - nNext++; - if (tTemp->IsBiggerOrEqual(oArray[nNext])) - break; - - // promote element in chain - oArray[nCurr] = oArray[nNext]; - nCurr = nNext; - } - - // restore element at end of chain - oArray[nCurr] = tTemp; - } -} diff --git a/DocxRenderer/src/resources/VectorGraphics.cpp b/DocxRenderer/src/resources/VectorGraphics.cpp index 5195fe42660..56e8d46be24 100644 --- a/DocxRenderer/src/resources/VectorGraphics.cpp +++ b/DocxRenderer/src/resources/VectorGraphics.cpp @@ -1,175 +1,437 @@ -#include #include "VectorGraphics.h" -#include "../DesktopEditor/common/Types.h" + #include +#include + +#include "../../../DesktopEditor/graphics/Matrix.h" + +#include "Constants.h" namespace NSDocxRenderer { - CVectorGraphics::CVectorGraphics() - { - m_pData = nullptr; - m_lSize = 0; - - m_pDataCur = m_pData; - m_lSizeCur = m_lSize; - - End(); - } - - CVectorGraphics::~CVectorGraphics() - { - RELEASEMEM(m_pData); - } - - void CVectorGraphics::AddSize(size_t nSize) - { - if (nullptr == m_pData) - { - m_lSize = std::max(nSize, (size_t)500); - m_pData = (double *)malloc(m_lSize * sizeof(double)); - - m_lSizeCur = 0; - m_pDataCur = m_pData; - return; - } - - if ((m_lSizeCur + nSize) > m_lSize) - { - while ((m_lSizeCur + nSize) > m_lSize) - { - m_lSize *= 2; - } - - double *pRealloc = (double *)realloc(m_pData, m_lSize * sizeof(double)); - if (nullptr != pRealloc) - { - // реаллок сработал - m_pData = pRealloc; - m_pDataCur = m_pData + m_lSizeCur; - } - else - { - double *pMalloc = (double *)malloc(m_lSize * sizeof(double)); - memcpy(pMalloc, m_pData, m_lSizeCur * sizeof(double)); - - free(m_pData); - m_pData = pMalloc; - m_pDataCur = m_pData + m_lSizeCur; - } - } - } - - void CVectorGraphics::MoveTo(const double &x1, const double &y1) - { - AddSize(3); - *m_pDataCur = vgtMove; - ++m_pDataCur; - - *m_pDataCur = x1; - ++m_pDataCur; - *m_pDataCur = y1; - ++m_pDataCur; - - m_lSizeCur += 3; - - CheckPoint(x1, y1); - } - - void CVectorGraphics::LineTo(const double &x1, const double &y1) - { - AddSize(3); - *m_pDataCur = vgtLine; - ++m_pDataCur; - - *m_pDataCur = x1; - ++m_pDataCur; - *m_pDataCur = y1; - ++m_pDataCur; - - m_lSizeCur += 3; - - CheckPoint(x1, y1); - } - - void CVectorGraphics::CurveTo(const double &x1, const double &y1, - const double &x2, const double &y2, - const double &x3, const double &y3) - { - AddSize(7); - *m_pDataCur = vgtCurve; - ++m_pDataCur; - - *m_pDataCur = x1; - ++m_pDataCur; - *m_pDataCur = y1; - ++m_pDataCur; - *m_pDataCur = x2; - ++m_pDataCur; - *m_pDataCur = y2; - ++m_pDataCur; - *m_pDataCur = x3; - ++m_pDataCur; - *m_pDataCur = y3; - ++m_pDataCur; - - m_lSizeCur += 7; - - CheckPoint(x1, y1); - CheckPoint(x2, y2); - CheckPoint(x3, y3); - } - - void CVectorGraphics::Close() - { - AddSize(1); - *m_pDataCur = vgtClose; - ++m_pDataCur; - - m_lSizeCur += 1; - } - - size_t CVectorGraphics::GetCurSize() const - { - return m_lSizeCur; - } - - void CVectorGraphics::Clear() - { - RELEASEMEM(m_pData); - - m_pData = nullptr; - m_lSize = 0; - - m_pDataCur = m_pData; - m_lSizeCur = 0; - } - - void CVectorGraphics::ClearNoAttack() - { - m_pDataCur = m_pData; - m_lSizeCur = 0; - } - - void CVectorGraphics::End() - { - ClearNoAttack(); - - //todo - m_dLeft = 0xFFFFFF; - m_dTop = 0xFFFFFF; - m_dRight = -0xFFFFFF; - m_dBottom = -0xFFFFFF; - } - - void CVectorGraphics::CheckPoint(const double &x, const double &y) - { - if (m_dLeft > x) - m_dLeft = x; - if (m_dRight < x) - m_dRight = x; - if (m_dTop > y) - m_dTop = y; - if (m_dBottom < y) - m_dBottom = y; - } + CVectorGraphics::CVectorGraphics() noexcept + { + ResetBorders(); + } + CVectorGraphics::CVectorGraphics(const CVectorGraphics& other) noexcept + : CVectorGraphics() + { + *this = other; + } + CVectorGraphics::CVectorGraphics(CVectorGraphics&& other) noexcept + : CVectorGraphics() + { + *this = std::move(other); + } + CVectorGraphics::CVectorGraphics(const Aggplus::CGraphicsPath& other) noexcept + : CVectorGraphics() + { + size_t close_count = other.GetCloseCount(); + size_t count = static_cast(other.GetPointCount()) + close_count; + std::vector points = other.GetPoints(0, count); + for (size_t idx = 0; idx < count; ++idx) + { + const auto& point = points[idx]; + if (other.IsMovePoint(idx)) + MoveTo(point.X, point.Y); + else if (other.IsLinePoint(idx)) + LineTo(point.X, point.Y); + else if (idx < count - 2 && + other.IsCurvePoint(idx) && + other.IsCurvePoint(idx + 1) && + other.IsCurvePoint(idx + 2)) + { + const auto& point1 = points[idx + 1]; + const auto& point2 = points[idx + 2]; + CurveTo(point.X, point.Y, point1.X, point1.Y, point2.X, point2.Y); + idx += 2; + } + else if (other.IsClosePoint(idx)) + Close(); + } + } + + + CVectorGraphics::~CVectorGraphics() + { + m_arData.clear(); + } + CVectorGraphics& CVectorGraphics::operator=(CVectorGraphics&& other) noexcept + { + if (this == &other) + return *this; + + m_arData = std::move(other.m_arData); + m_dLeft = other.m_dLeft; + m_dTop = other.m_dTop; + m_dRight = other.m_dRight; + m_dBottom = other.m_dBottom; + + other.Clear(); + return *this; + } + CVectorGraphics& CVectorGraphics::operator=(const CVectorGraphics& other) noexcept + { + if (this == &other) + return *this; + + m_arData = other.m_arData; + m_dLeft = other.m_dLeft; + m_dTop = other.m_dTop; + m_dRight = other.m_dRight; + m_dBottom = other.m_dBottom; + return *this; + } + + bool CVectorGraphics::operator<(const CVectorGraphics& other) const noexcept + { + return m_dBottom < other.m_dBottom && + m_dTop > other.m_dTop && + m_dRight < other.m_dRight && + m_dLeft > other.m_dLeft; + } + bool CVectorGraphics::operator>(const CVectorGraphics& other) const noexcept + { + return m_dBottom > other.m_dBottom && + m_dTop < other.m_dTop && + m_dRight > other.m_dRight && + m_dLeft < other.m_dLeft; + } + bool CVectorGraphics::operator==(const CVectorGraphics& other) const noexcept + { + return fabs(m_dBottom - other.m_dBottom < c_dGRAPHICS_ERROR_MM) && + fabs(m_dTop - other.m_dTop < c_dGRAPHICS_ERROR_MM) && + fabs(m_dRight - other.m_dRight < c_dGRAPHICS_ERROR_MM) && + fabs(m_dLeft - other.m_dLeft < c_dGRAPHICS_ERROR_MM); + } + bool CVectorGraphics::operator!=(const CVectorGraphics& other) const noexcept + { + return !(*this == other); + } + bool CVectorGraphics::operator<=(const CVectorGraphics& other) const noexcept + { + return m_dBottom - c_dGRAPHICS_ERROR_MM < other.m_dBottom && + m_dTop + c_dGRAPHICS_ERROR_MM > other.m_dTop && + m_dRight - c_dGRAPHICS_ERROR_MM < other.m_dRight && + m_dLeft + c_dGRAPHICS_ERROR_MM > other.m_dLeft; + } + bool CVectorGraphics::operator>=(const CVectorGraphics& other) const noexcept + { + return m_dBottom + c_dGRAPHICS_ERROR_MM > other.m_dBottom && + m_dTop - c_dGRAPHICS_ERROR_MM < other.m_dTop && + m_dRight + c_dGRAPHICS_ERROR_MM > other.m_dRight && + m_dLeft - c_dGRAPHICS_ERROR_MM < other.m_dLeft; + } + + void CVectorGraphics::ResetBorders() noexcept + { + m_dLeft = std::numeric_limits().max(); + m_dTop = std::numeric_limits().max(); + m_dRight = std::numeric_limits::lowest(); + m_dBottom = std::numeric_limits::lowest(); + } + + double CVectorGraphics::GetLeft() const noexcept + { + return m_dLeft; + } + double CVectorGraphics::GetTop() const noexcept + { + return m_dTop; + } + double CVectorGraphics::GetRight() const noexcept + { + return m_dRight; + } + double CVectorGraphics::GetBottom() const noexcept + { + return m_dBottom; + } + double CVectorGraphics::GetWidth() const noexcept + { + return m_dRight - m_dLeft; + } + double CVectorGraphics::GetHeight() const noexcept + { + return m_dBottom - m_dTop; + } + Point CVectorGraphics::GetCenter() const noexcept + { + return Point((m_dLeft + m_dRight) / 2, (m_dTop + m_dBottom) / 2); + } + bool CVectorGraphics::IsEmpty() const noexcept + { + return m_arData.empty(); + } + + const std::list& CVectorGraphics::GetData() const + { + return m_arData; + } + + void CVectorGraphics::MoveTo(const double &x1, const double &y1) + { + Point point = {x1, y1}; + ePathCommandType type = ePathCommandType::pctMove; + m_arData.push_back({type, {point}}); + + CheckPoint(point); + } + + void CVectorGraphics::LineTo(const double &x1, const double &y1) + { + Point point = {x1, y1}; + ePathCommandType type = ePathCommandType::pctLine; + m_arData.push_back({type, {point}}); + + CheckPoint(point); + } + + void CVectorGraphics::CurveTo( + const double &x1, const double &y1, + const double &x2, const double &y2, + const double &x3, const double &y3) + { + double x0 = m_arData.back().points.back().x; + double y0 = m_arData.back().points.back().y; + + std::list points = {{x1, y1}, {x2, y2}, {x3, y3}}; + ePathCommandType type = ePathCommandType::pctCurve; + m_arData.push_back({type, points}); + + std::vector curve_points = GetPointsCurve( + {Point{x0, y0}, Point{x1, y1}, Point{x2, y2}, Point{x3, y3}}, 0.1); + + for(auto& point : curve_points) + CheckPoint(point); + } + + void CVectorGraphics::Close() + { + ePathCommandType type = ePathCommandType::pctClose; + m_arData.push_back({type, {}}); + } + + void CVectorGraphics::Clear() + { + m_arData.clear(); + ResetBorders(); + } + + void CVectorGraphics::Add(const PathCommand& command) + { + m_arData.push_back(command); + } + void CVectorGraphics::Join(CVectorGraphics&& other) + { + CheckPoint(other.m_dLeft, other.m_dTop); + CheckPoint(other.m_dRight, other.m_dBottom); + m_arData.splice(m_arData.end(), std::move(other.m_arData)); + other.Clear(); + } + + void CVectorGraphics::CheckPoint(const Point& point) noexcept + { + if (m_dLeft > point.x) m_dLeft = point.x; + if (m_dRight < point.x) m_dRight = point.x; + if (m_dTop > point.y) m_dTop = point.y; + if (m_dBottom < point.y) m_dBottom = point.y; + } + void CVectorGraphics::CheckPoint(const double& x, const double& y) noexcept + { + Point point = {x, y}; + CheckPoint(point); + } + void CVectorGraphics::Rotate(const double& rotation) + { + Point center(GetCenter()); + Aggplus::CMatrix rotate_matrix; + rotate_matrix.RotateAt(rotation, center.x, center.y, Aggplus::MatrixOrderAppend); + Transform(rotate_matrix); + } + void CVectorGraphics::RotateAt(const double& rotation, const Point& point) + { + Aggplus::CMatrix rotate_matrix; + rotate_matrix.RotateAt(rotation, point.x, point.y, Aggplus::MatrixOrderAppend); + Transform(rotate_matrix); + } + void CVectorGraphics::Transform(const Aggplus::CMatrix& matrix) + { + auto data = std::move(m_arData); + Clear(); + + for (auto& command : data) + for (auto& point : command.points) + matrix.TransformPoint(point.x, point.y); + + for (const auto& path : data) + { + if (path.type == ePathCommandType::pctMove) + MoveTo(path.points.front().x, path.points.front().y); + else if (path.type == ePathCommandType::pctLine) + LineTo(path.points.front().x, path.points.front().y); + else if (path.type == ePathCommandType::pctClose) + Close(); + else if (path.type == ePathCommandType::pctCurve) + { + std::vector points; + for (const auto& point : path.points) + points.push_back(point); + + CurveTo( + points[0].x, points[0].y, + points[1].x, points[1].y, + points[2].x, points[2].y); + } + } + } + void CVectorGraphics::DrawOnRenderer(IRenderer* renderer) const noexcept + { + for (const auto& path : m_arData) + { + if (path.type == ePathCommandType::pctMove) + renderer->PathCommandMoveTo(path.points.front().x, path.points.front().y); + else if (path.type == ePathCommandType::pctLine) + renderer->PathCommandLineTo(path.points.front().x, path.points.front().y); + else if (path.type == ePathCommandType::pctClose) + renderer->PathCommandClose(); + else if (path.type == ePathCommandType::pctCurve) + { + std::vector points; + for (const auto& point : path.points) + points.push_back(point); + + renderer->PathCommandCurveTo( + points[0].x, points[0].y, + points[1].x, points[1].y, + points[2].x, points[2].y); + } + } + } + + // ClipRegionTypeWinding = 0x0000; + // ClipRegionTypeEvenOdd = 0x0001; + // ClipRegionIntersect = 0x0000; + // ClipRegionUnion = 0x0100; + // ClipRegionXor = 0x0200; + // ClipRegionDiff = 0x0400; + + // c_nStroke = 0x0001; + // c_nWindingFillMode = 0x0100; + // c_nEvenOddFillMode = 0x0200; + CVectorGraphics CVectorGraphics::CalcBoolean(const CVectorGraphics& vg1, const CVectorGraphics& vg2, long clipType, long fillType) + { + auto op = GetOpType(clipType); + Aggplus::CGraphicsPath result = Aggplus::CalcBooleanOperation(vg1.GetGraphicsPath(), vg2.GetGraphicsPath(), op, fillType); + return CVectorGraphics(result); + } + + Aggplus::CGraphicsPath CVectorGraphics::GetGraphicsPath() const noexcept + { + Aggplus::CGraphicsPath ret_value; + for (const auto& path : m_arData) + { + if (path.type == ePathCommandType::pctMove) + ret_value.MoveTo(path.points.front().x, path.points.front().y); + else if (path.type == ePathCommandType::pctLine) + ret_value.LineTo(path.points.front().x, path.points.front().y); + else if (path.type == ePathCommandType::pctClose) + ret_value.CloseFigure(); + else if (path.type == ePathCommandType::pctCurve) + { + std::vector points; + for (const auto& point : path.points) + points.push_back(point); + + ret_value.CurveTo( + points[0].x, points[0].y, + points[1].x, points[1].y, + points[2].x, points[2].y); + } + } + + return ret_value; + } + Aggplus::BooleanOpType CVectorGraphics::GetOpType(long nClipType) + { + if (nClipType & c_nClipRegionUnion) + return Aggplus::BooleanOpType::Union; + else if (nClipType & c_nClipRegionXor) + return Aggplus::BooleanOpType::Exclusion; + else if (nClipType & c_nClipRegionDiff) + return Aggplus::BooleanOpType::Subtraction; + else + return Aggplus::BooleanOpType::Intersection; + } + std::vector CVectorGraphics::GetPointsCurve(const std::array& curve, double step) + { + std::vector points; + double t = 0; + auto calc = [&curve] (double t) -> Point { + Point point; + point.x = pow(1 - t, 3) * curve[0].x + + 3 * pow(1 - t, 2) * t * curve[1].x + + 3 * (1 - t) * t * t * curve[2].x + + t * t * t * curve[3].x; + point.y = pow(1 - t, 3) * curve[0].y + + 3 * pow(1 - t, 2) * t * curve[1].y + + 3 * (1 - t) * t * t * curve[2].y + + t * t * t * curve[3].y; + return point; + }; + + while (t <= 1) + { + points.push_back(calc(t)); + t += step; + } + + return points; + } + + CHorVerLinesCollector::CHorVerLine::CHorVerLine(const double& _min, const double& _max, const double& _pos) + { + min = _min; + max = _max; + pos = _pos; + } + const std::vector& CHorVerLinesCollector::GetHorizontal() const + { + return m_arHorizontal; + } + const std::vector& CHorVerLinesCollector::GetVertical() const + { + return m_arVertical; + } + + void CHorVerLinesCollector::AddVector(const CVectorGraphics& oVector) + { + double last_x{}; + double last_y{}; + + for (const auto& command : oVector.GetData()) + { + if (command.type == CVectorGraphics::ePathCommandType::pctLine) + { + double x = command.points.front().x; + double y = command.points.front().y; + + if (x - last_x <= std::numeric_limits::epsilon()) + m_arVertical.push_back({std::min(last_y, y), std::max(last_y, y), x}); + + else if (y - last_y <= std::numeric_limits::epsilon()) + m_arHorizontal.push_back({std::min(last_x, x), std::max(last_x, x), y}); + } + if (!command.points.empty()) + { + last_x = command.points.back().x; + last_y = command.points.back().y; + } + } + } + void CHorVerLinesCollector::Clear() + { + m_arVertical.clear(); + m_arHorizontal.clear(); + } } diff --git a/DocxRenderer/src/resources/VectorGraphics.h b/DocxRenderer/src/resources/VectorGraphics.h index ff09addc5db..11fa3b8eb00 100644 --- a/DocxRenderer/src/resources/VectorGraphics.h +++ b/DocxRenderer/src/resources/VectorGraphics.h @@ -1,50 +1,126 @@ #pragma once +#include "../../../DesktopEditor/graphics/GraphicsPath.h" + +#include +#include namespace NSDocxRenderer { - class CVectorGraphics - { - public: - enum VectorGraphicsType - { - vgtMove = 0, - vgtLine = 1, - vgtCurve = 2, - vgtClose = 3 - }; - - public: - double* m_pData; - size_t m_lSize; - - double* m_pDataCur; - size_t m_lSizeCur; - - public: - double m_dLeft; - double m_dTop; - double m_dRight; - double m_dBottom; - - public: - CVectorGraphics(); - ~CVectorGraphics(); - - inline void AddSize(size_t nSize); - - public: - void MoveTo(const double& x1, const double& y1); - void LineTo(const double& x1, const double& y1); - void CurveTo(const double& x1, const double& y1, const double& x2, const double& y2, const double& x3, const double& y3); - void Close(); - - size_t GetCurSize() const; - - void Clear(); - void ClearNoAttack(); - - void End(); - - void CheckPoint(const double& x, const double& y); - }; + struct Point + { + double x = 0; + double y = 0; + + Point() {} + Point(double x, double y) : x(x), y(y) {} + Point(const Point& point) : x(point.x), y(point.y) {} + Point& operator=(const Point& point) {x = point.x; y = point.y; return *this;} + };; + + class CVectorGraphics + { + public: + enum class ePathCommandType + { + pctMove = 0, + pctLine = 1, + pctCurve = 2, + pctClose = 3 + }; + + struct PathCommand + { + ePathCommandType type; + std::list points; + }; + + CVectorGraphics() noexcept; + CVectorGraphics(const CVectorGraphics& other) noexcept; + CVectorGraphics(CVectorGraphics&& other) noexcept; + CVectorGraphics(const Aggplus::CGraphicsPath& other) noexcept; + ~CVectorGraphics(); + + CVectorGraphics& operator=(CVectorGraphics&& other) noexcept; + CVectorGraphics& operator=(const CVectorGraphics& other) noexcept; + + bool operator<(const CVectorGraphics& other) const noexcept; + bool operator>(const CVectorGraphics& other) const noexcept; + bool operator==(const CVectorGraphics& other) const noexcept; + bool operator!=(const CVectorGraphics& other) const noexcept; + bool operator<=(const CVectorGraphics& other) const noexcept; + bool operator>=(const CVectorGraphics& other) const noexcept; + + const std::list& GetData() const; + + double GetLeft() const noexcept; + double GetTop() const noexcept; + double GetRight() const noexcept; + double GetBottom() const noexcept; + double GetWidth() const noexcept; + double GetHeight() const noexcept; + Point GetCenter() const noexcept; + bool IsEmpty() const noexcept; + + void MoveTo(const double& x1, const double& y1); + void LineTo(const double& x1, const double& y1); + void CurveTo( + const double& x1, const double& y1, + const double& x2, const double& y2, + const double& x3, const double& y3); + void Close(); + + void Add(const PathCommand& command); + void Join(CVectorGraphics&& other); + + void Clear(); + void CheckPoint(const Point& point) noexcept; + void CheckPoint(const double& x, const double& y) noexcept; + void RotateAt(const double& rotation, const Point& point); + void Rotate(const double& rotation); + void Transform(const Aggplus::CMatrix& matrix); + void DrawOnRenderer(IRenderer* renderer) const noexcept; + + static CVectorGraphics CalcBoolean(const CVectorGraphics& vg1, const CVectorGraphics& vg2, long clipType, long fillType = c_nWindingFillMode); + + private: + std::list m_arData; + + double m_dLeft; + double m_dTop; + double m_dRight; + double m_dBottom; + + void ResetBorders() noexcept; + + Aggplus::CGraphicsPath GetGraphicsPath() const noexcept; + static Aggplus::BooleanOpType GetOpType(long nClipType); + static std::vector GetPointsCurve(const std::array& curve, double step = 0.05); + }; + + // collect and contains horizontal and vertical lines + class CHorVerLinesCollector + { + public: + struct CHorVerLine + { + double min{}; + double max{}; + double pos{}; + + CHorVerLine(const double& _min, const double& _max, const double& _pos); + }; + + CHorVerLinesCollector() = default; + ~CHorVerLinesCollector() = default; + + const std::vector& GetHorizontal() const; + const std::vector& GetVertical() const; + + void AddVector(const CVectorGraphics& oVector); + void Clear(); + + private: + std::vector m_arHorizontal; + std::vector m_arVertical; + }; } diff --git a/DocxRenderer/src/resources/resources.cpp b/DocxRenderer/src/resources/resources.cpp index c22ff541ff1..149ac854d24 100644 --- a/DocxRenderer/src/resources/resources.cpp +++ b/DocxRenderer/src/resources/resources.cpp @@ -1,4 +1,5 @@ -#include "./resources.h" +#include "resources.h" + #include "../../../DesktopEditor/common/Directory.h" #include "../../../DesktopEditor/common/SystemUtils.h" #include "../../../DesktopEditor/common/StringBuilder.h" @@ -10,58 +11,58 @@ bool WriteXmlUTF8(const std::wstring& strFile, const std::string& sContent) { - bool bRes = false; - NSFile::CFileBinary oFileBinary; - if (oFileBinary.CreateFileW(strFile)) - { - oFileBinary.WriteFile((BYTE*)sContent.c_str(), (DWORD)sContent.length()); - oFileBinary.CloseFile(); - } - return bRes; + bool bRes = false; + NSFile::CFileBinary oFileBinary; + if (oFileBinary.CreateFileW(strFile)) + { + oFileBinary.WriteFile((BYTE*)sContent.c_str(), (DWORD)sContent.length()); + oFileBinary.CloseFile(); + } + return bRes; } bool CreateTemplate(const std::wstring& strDirectory) { - if (NSDirectory::Exists(strDirectory)) - NSDirectory::CreateDirectory(strDirectory); + if (NSDirectory::Exists(strDirectory)) + NSDirectory::CreateDirectory(strDirectory); - std::string str_resource_app = "1100ONLYOFFICE011falsefalse0falsefalse"; - std::string str_resource_contenttypes = "\n"; - std::string str_resource_core = "1"; - std::string str_resource_rels = ""; - std::string str_resource_settings = ""; - std::string str_resource_theme = ""; - std::string str_resource_websettings = ""; + std::string str_resource_app = "1100ONLYOFFICE011falsefalse0falsefalse"; + std::string str_resource_contenttypes = "\n"; + std::string str_resource_core = "1"; + std::string str_resource_rels = ""; + std::string str_resource_settings = ""; + std::string str_resource_theme = ""; + std::string str_resource_websettings = ""; - std::wstring str_resource_app_replace = NSSystemUtils::GetEnvVariable(NSSystemUtils::gc_EnvApplicationName); - if (str_resource_app_replace.empty()) - str_resource_app_replace = NSSystemUtils::gc_EnvApplicationNameDefault; + std::wstring str_resource_app_replace = NSSystemUtils::GetEnvVariable(NSSystemUtils::gc_EnvApplicationName); + if (str_resource_app_replace.empty()) + str_resource_app_replace = NSSystemUtils::gc_EnvApplicationNameDefault; #if defined(INTVER) - std::string s = VALUE2STR(INTVER); - str_resource_app_replace += (L"/" + UTF8_TO_U(s)); + std::string s = VALUE2STR(INTVER); + str_resource_app_replace += (L"/" + UTF8_TO_U(s)); #endif - std::string str_resource_app_replace_a = "" + U_TO_UTF8(str_resource_app_replace) + ""; - NSStringUtils::string_replaceA(str_resource_app, "ONLYOFFICE", str_resource_app_replace_a); + std::string str_resource_app_replace_a = "" + U_TO_UTF8(str_resource_app_replace) + ""; + NSStringUtils::string_replaceA(str_resource_app, "ONLYOFFICE", str_resource_app_replace_a); - NSDirectory::CreateDirectory(strDirectory + L"/_rels"); - WriteXmlUTF8(strDirectory + L"/_rels/.rels", str_resource_rels); + NSDirectory::CreateDirectory(strDirectory + L"/_rels"); + WriteXmlUTF8(strDirectory + L"/_rels/.rels", str_resource_rels); - NSDirectory::CreateDirectory(strDirectory + L"/docProps"); - WriteXmlUTF8(strDirectory + L"/docProps/app.xml", str_resource_app); - WriteXmlUTF8(strDirectory + L"/docProps/core.xml", str_resource_core); + NSDirectory::CreateDirectory(strDirectory + L"/docProps"); + WriteXmlUTF8(strDirectory + L"/docProps/app.xml", str_resource_app); + WriteXmlUTF8(strDirectory + L"/docProps/core.xml", str_resource_core); - WriteXmlUTF8(strDirectory + L"/[Content_Types].xml", str_resource_contenttypes); + WriteXmlUTF8(strDirectory + L"/[Content_Types].xml", str_resource_contenttypes); - NSDirectory::CreateDirectory(strDirectory + L"/word"); - WriteXmlUTF8(strDirectory + L"/word/settings.xml", str_resource_settings); - WriteXmlUTF8(strDirectory + L"/word/webSettings.xml", str_resource_websettings); + NSDirectory::CreateDirectory(strDirectory + L"/word"); + WriteXmlUTF8(strDirectory + L"/word/settings.xml", str_resource_settings); + WriteXmlUTF8(strDirectory + L"/word/webSettings.xml", str_resource_websettings); - NSDirectory::CreateDirectory(strDirectory + L"/word/theme"); - WriteXmlUTF8(strDirectory + L"/word/theme/theme.xml", str_resource_theme); + NSDirectory::CreateDirectory(strDirectory + L"/word/theme"); + WriteXmlUTF8(strDirectory + L"/word/theme/theme.xml", str_resource_theme); - NSDirectory::CreateDirectory(strDirectory + L"/word/_rels"); - return true; + NSDirectory::CreateDirectory(strDirectory + L"/word/_rels"); + return true; } diff --git a/DocxRenderer/src/resources/utils.h b/DocxRenderer/src/resources/utils.h index ed85a99f766..96820a7ce49 100644 --- a/DocxRenderer/src/resources/utils.h +++ b/DocxRenderer/src/resources/utils.h @@ -1,47 +1,29 @@ #pragma once -#include "../DesktopEditor/common/Types.h" -#include "../DesktopEditor/common/StringUTF32.h" +#include -inline LONG ConvertColorBGRToRGB(LONG lBGR) -{ - return (0x00FFFFFF & (((lBGR & 0xFF) << 16) | (lBGR & 0x0000FF00) | ((lBGR >> 16) & 0xFF))); -} - -inline bool IsSpaceUtf32(const uint32_t& c) -{ - return (0x20 == c || //пробел - 0xA0 == c || //неразрывный пробел - 0x2003 == c //Em пробел - ) ? true : false; -} -inline bool IsSpaceUtf32(const NSStringUtils::CStringUTF32& oText) -{ - if (1 != oText.length()) - return false; - return IsSpaceUtf32(oText.ToStdWString()[0]); -} +#include "../../../DesktopEditor/common/Types.h" +#include "../../../DesktopEditor/common/StringUTF32.h" -inline bool IsUnicodeSymbol(const int& symbol ) +inline LONG ConvertColorBGRToRGB(LONG lBGR) { - if ( ( 0x0009 == symbol ) || ( 0x000A == symbol ) || ( 0x000D == symbol ) || - ( ( 0x0020 <= symbol ) && ( 0xD7FF >= symbol ) ) || ( ( 0xE000 <= symbol ) && ( symbol <= 0xFFFD ) ) || - ( ( 0x10000 <= symbol ) && symbol ) ) - { - return true; - } - return false; + return (0x00FFFFFF & (((lBGR & 0xFF) << 16) | (lBGR & 0x0000FF00) | ((lBGR >> 16) & 0xFF))); } -// 2-byte number -inline short little_endian_2_big_endian( short s ) +// перемещает nullptr в конец и возвращает итератор, после которого начинаются nullptr +template +It MoveNullptr(It start, It end) { - return ( ( s >> 8) & 0xff ) + ( ( s << 8 ) & 0xff00 ); -} - -/*========================================================================================================*/ + if (end <= start) return start; + It left = start, right = end - 1; + for (;;) + { + while (!*right && left < right) right--; + while (*left && left < right) left++; + if (left >= right) break; + std::swap(*left, *right); + } + if (*right) + ++right; -// 4-byte number -inline int little_endian_2_big_endian( int i ) -{ - return ( ( i & 0xff ) << 24 ) + ( ( i & 0xff00 ) << 8 ) + ( ( i & 0xff0000 ) >> 8 ) + ( ( i >> 24 ) & 0xff ); + return right; } diff --git a/DocxRenderer/test/main.cpp b/DocxRenderer/test/main.cpp index bfcdfd2f5d1..43640f6398d 100644 --- a/DocxRenderer/test/main.cpp +++ b/DocxRenderer/test/main.cpp @@ -32,7 +32,6 @@ #include "../../DesktopEditor/common/Directory.h" #include "../../DesktopEditor/graphics/pro/Fonts.h" -#include "../../DesktopEditor/graphics/pro/Graphics.h" #include "../../DesktopEditor/fontengine/ApplicationFontsWorker.h" #include "../../PdfFile/PdfFile.h" @@ -41,8 +40,10 @@ #include "../DocxRenderer.h" #include "../../Common/OfficeFileFormatChecker.h" +#include + #ifdef TEST_FOR_HTML_RENDERER_TEXT -#include "../../HtmlRenderer/include/HTMLRendererText.h" +#include "../../DesktopEditor/graphics/pro/js/wasm/src/HTMLRendererText.h" #endif //#define LOAD_FILE_AS_BINARY @@ -87,26 +88,25 @@ int main(int argc, char *argv[]) if (!NSDirectory::Exists(sTempDirOut)) NSDirectory::CreateDirectory(sTempDirOut); - //Добавляем все файлы из определенного каталога - //std::vector sSourceFiles = NSDirectory::GetFiles(L"C:\\Folder"); - std::vector sSourceFiles; - //Или добавляем любой нужный файл - sSourceFiles.push_back(L""); + std::vector sSourceFiles = NSDirectory::GetFiles(L""); + //sSourceFiles.push_back(L""); - std::wstring sTextDirOut = NSFile::GetProcessDirectory() + L"/text"; + std::wstring sTextDirOut = NSFile::GetProcessDirectory() + L"/output"; if (!NSDirectory::Exists(sTextDirOut)) NSDirectory::CreateDirectory(sTextDirOut); IOfficeDrawingFile* pReader = NULL; COfficeFileFormatChecker oChecker; - int nFileType = 0; + int nFileType = 0; CDocxRenderer oDocxRenderer(pFonts); oDocxRenderer.SetTempFolder(sTempDirOut); for (size_t nIndex = 0; nIndex < sSourceFiles.size(); nIndex++) { + // нужно скинуть тип, чтобы не определялся как OOXML всегда (см чеккер). + oChecker.nFileType = 0; if (oChecker.isOfficeFile(sSourceFiles[nIndex])) { nFileType = oChecker.nFileType; @@ -127,10 +127,7 @@ int main(int argc, char *argv[]) } if (!pReader) - { - pFonts->Release(); - return 0; - } + continue; pReader->SetTempDirectory(sTempDir); @@ -164,20 +161,26 @@ int main(int argc, char *argv[]) std::wstring sDocx = L"/" + sFileName + L".docx"; std::wstring sZip = L"/" + sFileName + L".zip"; - // проверить все режимы NSDocxRenderer::TextAssociationType taType; - //taType = NSDocxRenderer::tatBlockChar; - //taType = NSDocxRenderer::tatBlockLine; - //taType = NSDocxRenderer::tatPlainLine; - //taType = NSDocxRenderer::tatShapeLine; - taType = NSDocxRenderer::tatPlainParagraph; + //taType = NSDocxRenderer::TextAssociationType::tatPlainLine; + //taType = NSDocxRenderer::TextAssociationType::tatShapeLine; + //taType = NSDocxRenderer::TextAssociationType::tatPlainParagraph; + taType = NSDocxRenderer::TextAssociationType::tatParagraphToShape; + + NSDocxRenderer::IImageStorage* pExternalImagheStorage = NSDocxRenderer::CreateWasmImageStorage(); + //oDocxRenderer.SetExternalImageStorage(pExternalImagheStorage); oDocxRenderer.SetTextAssociationType(taType); oDocxRenderer.Convert(pReader, sTextDirOut+sDocx); - //Если сразу нужен zip-архив - //oDocxRenderer.Convert(pReader, sPlainParagraphDirOut+sZip); + +// std::wstring test_txt_file = L""; +// std::ofstream fin(test_txt_file); +// auto shapes = oDocxRenderer.ScanPagePptx(pReader, 0); +// for (auto& s : shapes) +// fin << U_TO_UTF8(s); #endif - delete pReader; + RELEASEOBJECT(pReader); + RELEASEOBJECT(pExternalImagheStorage); } pFonts->Release(); diff --git a/DocxRenderer/test/test.pro b/DocxRenderer/test/test.pro index 2f2b2beeadd..5858aaffb7f 100644 --- a/DocxRenderer/test/test.pro +++ b/DocxRenderer/test/test.pro @@ -22,7 +22,7 @@ SOURCES += main.cpp SOURCES += \ $$CORE_ROOT_DIR/Common/OfficeFileFormatChecker2.cpp \ $$CORE_ROOT_DIR/Common/3dParty/pole/pole.cpp \ - $$CORE_ROOT_DIR/OOXML/Base/unicode_util.cpp + $$CORE_ROOT_DIR/OOXML/Base/unicode_util.cpp DESTDIR = $$PWD_ROOT_DIR/build @@ -30,6 +30,6 @@ DESTDIR = $$PWD_ROOT_DIR/build use_test_html_renderer { DEFINES += TEST_FOR_HTML_RENDERER_TEXT - HEADERS += $$CORE_ROOT_DIR/HtmlRenderer/include/HTMLRendererText.h - SOURCES += $$CORE_ROOT_DIR/HtmlRenderer/src/HTMLRendererText.cpp + HEADERS += $$CORE_ROOT_DIR/DesktopEditor/graphics/pro/js/wasm/src/HTMLRendererText.h + SOURCES += $$CORE_ROOT_DIR/DesktopEditor/graphics/pro/js/wasm/src/HTMLRendererText.cpp } diff --git a/EpubFile/src/CBookInfo.cpp b/EpubFile/src/CBookInfo.cpp index 928f4ed924f..0f31c89958f 100644 --- a/EpubFile/src/CBookInfo.cpp +++ b/EpubFile/src/CBookInfo.cpp @@ -146,6 +146,13 @@ const std::wstring CBookInfo::GetLanguages() const return sLanguages; } +const std::wstring CBookInfo::GetLanguage() const +{ + if (m_arLanguages.empty()) + return L""; + return m_arLanguages.front(); +} + const std::wstring CBookInfo::GetContibutors() const { if (m_arContributors.empty()) diff --git a/EpubFile/src/CBookInfo.h b/EpubFile/src/CBookInfo.h index 86023084d0a..343adc8067c 100644 --- a/EpubFile/src/CBookInfo.h +++ b/EpubFile/src/CBookInfo.h @@ -30,6 +30,7 @@ class CBookInfo const std::wstring GetCreators() const; const std::wstring GetPublishers() const; const std::wstring GetLanguages() const; + const std::wstring GetLanguage() const; const std::wstring GetContibutors() const; const std::wstring GetDescriptions() const; const std::wstring GetSubjects() const; diff --git a/EpubFile/src/CBookItem.cpp b/EpubFile/src/CBookItem.cpp index 69c3ea39702..e25c16ec43d 100644 --- a/EpubFile/src/CBookItem.cpp +++ b/EpubFile/src/CBookItem.cpp @@ -63,10 +63,7 @@ bool CBookItem::ReadItem(XmlUtils::CXmlLiteReader& oXmlLiteReader, int depth) std::wstring sAttributeValue = oXmlLiteReader.GetText(); if (sAttributeName == L"href") - { - sAttributeValue = URLDecode(sAttributeValue); - m_sRef = NSFile::GetFileName(sAttributeValue); - } + m_sRef = URLDecode(sAttributeValue); else if (sAttributeName == L"id") m_sID = sAttributeValue; else if (sAttributeName == L"media-type") diff --git a/EpubFile/src/CEpubFile.cpp b/EpubFile/src/CEpubFile.cpp index 0dc7da562b5..eeb91f6e74d 100644 --- a/EpubFile/src/CEpubFile.cpp +++ b/EpubFile/src/CEpubFile.cpp @@ -69,19 +69,25 @@ HRESULT CEpubFile::Convert(const std::wstring& sInputFile, const std::wstring& s COfficeUtils oOfficeUtils; wchar_t* password = NULL; - if (oOfficeUtils.ExtractToDirectory(sInputFile, m_sTempDir.c_str(), password, 1) != S_OK) + if (oOfficeUtils.ExtractToDirectory(sInputFile, m_sTempDir.c_str(), password, 0) != S_OK) return S_FALSE; std::wstring sFileContent; std::wstring sContent; - if (!NSFile::CFileBinary::ReadAllTextUtf8(m_sTempDir + L"/container.xml", sFileContent)) + if (!NSFile::CFileBinary::ReadAllTextUtf8(m_sTempDir + L"/META-INF/container.xml", sFileContent)) return S_FALSE; size_t nContent = sFileContent.find(L"full-path"); if (nContent != std::wstring::npos) { nContent += 11; - sContent = NSFile::GetFileName(sFileContent.substr(nContent, sFileContent.find(L'\"', nContent) - nContent)); + sContent = sFileContent.substr(nContent, sFileContent.find_first_of(L"\"'", nContent) - nContent); } + + std::wstring sContentPath; + + if (std::wstring::npos != sContent.find(L'/') || std::wstring::npos != sContent.find(L'\\')) + sContentPath = NSFile::GetDirectoryName(sContent); + sContent = m_sTempDir + (sContent.empty() ? L"/content.opf" : L'/' + sContent); XmlUtils::CXmlLiteReader oXmlLiteReader; @@ -137,23 +143,26 @@ HRESULT CEpubFile::Convert(const std::wstring& sInputFile, const std::wstring& s CHtmlFile2 oFile; CHtmlParams oFileParams; - oFileParams.SetAuthors(m_oBookInfo.GetCreators()); - oFileParams.SetGenres (m_oBookInfo.GetSubjects()); - oFileParams.SetTitle (m_oBookInfo.GetTitle()); - oFileParams.SetDate (m_oBookInfo.GetDate()); - oFileParams.SetDescription(m_oBookInfo.GetDescriptions()); + oFileParams.SetAuthors (m_oBookInfo.GetCreators()); + oFileParams.SetGenres (m_oBookInfo.GetSubjects()); + oFileParams.SetTitle (m_oBookInfo.GetTitle()); + oFileParams.SetDate (m_oBookInfo.GetDate()); + oFileParams.SetDescription (m_oBookInfo.GetDescriptions()); + oFileParams.SetLanguage (m_oBookInfo.GetLanguage()); + oFileParams.SetPageBreakBefore(true); std::wstring sDocxFileTempDir = m_sTempDir + L"/tmp"; NSDirectory::CreateDirectory(sDocxFileTempDir); oFile.SetTmpDirectory(sDocxFileTempDir); + oFile.SetCoreDirectory(NSFile::GetDirectoryName(sContent)); std::vector arFiles; for (const CBookContentItem& oContent : m_arContents) { std::wstring sFile = m_mapRefs[oContent.m_sID].GetRef(); replace_all(sFile, L"%20", L" "); - arFiles.push_back(m_sTempDir + L"/" + sFile); + arFiles.push_back(m_sTempDir + ((!sContentPath.empty()) ? (L"/" + sContentPath) : L"" ) + L"/" + sFile); } #ifdef _DEBUG diff --git a/Fb2File/Fb2File.cpp b/Fb2File/Fb2File.cpp index 24af84c5a4a..7df93ce4da3 100644 --- a/Fb2File/Fb2File.cpp +++ b/Fb2File/Fb2File.cpp @@ -1551,65 +1551,27 @@ class CFb2File_Private m_oTitleInfo.m_sKeywords = EncodeXmlString(sAtrContent); } } - else if (sName == L"h1") + else if (sName == L"h1" || sName == L"h2" || sName == L"h3" || sName == L"h4" || sName == L"h5" || sName == L"h6") { - if (!m_bInTable) - oXml.WriteString(L"
<p>"); - m_bInP = true; - readStream(oXml); - m_bInP = false; - if (!m_bInTable) - oXml.WriteString(L"</p>
"); - } - else if (sName == L"h2") - { - if (!m_bInTable) - oXml.WriteString(L"
<p>"); - m_bInP = true; - readStream(oXml); - m_bInP = false; - if (!m_bInTable) - oXml.WriteString(L"</p>
"); - } - else if (sName == L"h3") - { - if (!m_bInTable) - oXml.WriteString(L"
<p>"); - m_bInP = true; - readStream(oXml); - m_bInP = false; - if (!m_bInTable) - oXml.WriteString(L"</p>
"); - } - else if (sName == L"h4") - { - if (!m_bInTable) - oXml.WriteString(L"
<p>"); - m_bInP = true; - readStream(oXml); - m_bInP = false; - if (!m_bInTable) - oXml.WriteString(L"</p>
"); - } - else if (sName == L"h5") - { - if (!m_bInTable) - oXml.WriteString(L"
<p>"); - m_bInP = true; - readStream(oXml); - m_bInP = false; - if (!m_bInTable) - oXml.WriteString(L"</p>
"); - } - else if (sName == L"h6") - { - if (!m_bInTable) - oXml.WriteString(L"
<p>"); - m_bInP = true; + bool bInH = false; + int nH = 0; + if (!m_bInTable && !m_bInP) + { + nH = stoi(sName.substr(1)); + for (int i = 0; i < nH; ++i) + oXml.WriteString(L"<section>"); + oXml.WriteString(L"<title><p>"); + bInH = true; + m_bInP = true; + } readStream(oXml); - m_bInP = false; - if (!m_bInTable) - oXml.WriteString(L"</p>
"); + if (bInH) + { + oXml.WriteString(L"

"); + for (int i = 0; i < nH; ++i) + oXml.WriteString(L""); + m_bInP = false; + } } else if (sName == L"span") { diff --git a/Fb2File/Fb2File.pro b/Fb2File/Fb2File.pro index f9a3359fcbe..e04f6d44195 100644 --- a/Fb2File/Fb2File.pro +++ b/Fb2File/Fb2File.pro @@ -18,6 +18,9 @@ include($$CORE_ROOT_DIR/Common/3dParty/html/gumbo.pri) ADD_DEPENDENCY(kernel, UnicodeConverter, graphics) +CONFIG += core_boost_regex +include($$CORE_ROOT_DIR/Common/3dParty/boost/boost.pri) + SOURCES += Fb2File.cpp HEADERS += Fb2File.h diff --git a/HtmlFile2/HtmlFile2.pro b/HtmlFile2/HtmlFile2.pro index ea196402003..c1c03a784ca 100644 --- a/HtmlFile2/HtmlFile2.pro +++ b/HtmlFile2/HtmlFile2.pro @@ -10,6 +10,8 @@ CONFIG += plugin DEFINES += HTMLFILE2_USE_DYNAMIC_LIBRARY DEFINES += CSSCALCULATOR_LIBRARY_STATIC +DEFINES += CSS_CALCULATOR_WITH_XHTML +DEFINES += DISABLE_RUBY_SUPPORT CORE_ROOT_DIR = $$PWD/.. PWD_ROOT_DIR = $$PWD @@ -29,4 +31,6 @@ ADD_DEPENDENCY(kernel, UnicodeConverter, graphics, kernel_network) SOURCES += htmlfile2.cpp -HEADERS += htmlfile2.h +HEADERS += htmlfile2.h \ + ./src/StringFinder.h \ + ./src/Languages.h diff --git a/HtmlFile2/htmlfile2.cpp b/HtmlFile2/htmlfile2.cpp index 67e797953bd..7e6c605bdf1 100644 --- a/HtmlFile2/htmlfile2.cpp +++ b/HtmlFile2/htmlfile2.cpp @@ -6,8 +6,6 @@ #include #include #include -#include -#include #include "../Common/3dParty/html/htmltoxhtml.h" #include "../Common/3dParty/html/css/src/CCssCalculator.h" @@ -23,9 +21,10 @@ #include "../DesktopEditor/common/ProcessEnv.h" #include "../DesktopEditor/xml/include/xmlutils.h" #include "../DesktopEditor/raster/BgraFrame.h" -#include "../DesktopEditor/graphics/pro/Fonts.h" #include "../DesktopEditor/graphics/pro/Graphics.h" + #include "htmlfile2.h" +#include "src/Languages.h" #include @@ -34,13 +33,210 @@ #define VALUE2STR(x) VALUE_TO_STRING(x) #endif -std::wstring rStyle = L" a area b strong bdo bdi big br center cite dfn em i var code kbd samp tt del s font img ins u mark q rt sup small sub svg input basefont button label data object noscript output abbr time ruby progress hgroup meter span acronym "; +#define MAXCOLUMNSINTABLE 63 +#define MAXROWSINTABLE 32767 + +#define DEFAULT_PAGE_WIDTH 12240 // Значение в Twips +#define DEFAULT_PAGE_HEIGHT 15840 // Значение в Twips + +#define DEFAULT_LANGUAGE std::wstring(L"en-US") +#define DEFAULT_FONT_FAMILY std::wstring(L"Times New Roman") +#define DEFAULT_FONT_SIZE 24 + +#define DEFAULT_IMAGE_WIDTH 304800 +#define DEFAULT_IMAGE_HEIGHT 304800 + +#define SAVE_NORMALIZED_HTML 0 + +#define RELEASE_VECTOR_PTR(vector_object, object_type) \ + for (object_type* pElement : vector_object) \ + RELEASEOBJECT(pElement) \ + +const static double HTML_FONTS[7] = {7.5, 10, 12, 13.5, 18, 24, 36}; + +#define HTML_TAG(tag) GUMBO_TAG_##tag +#define ADD_TAG(strName, enumName) {strName, HTML_TAG(enumName)} +#define SKIP_TAG SCRIPT +#define UNKNOWN_TAG GumboTag::GUMBO_TAG_UNKNOWN + +#define HtmlTag GumboTag + +#define MAX_STRING_BLOCK_SIZE (size_t)10485760 + +const std::map m_HTML_TAGS +{ + ADD_TAG(L"a", A), + ADD_TAG(L"abbr", ABBR), + ADD_TAG(L"acronym", ACRONYM), + ADD_TAG(L"address", ADDRESS), + ADD_TAG(L"applet", APPLET), + ADD_TAG(L"area", AREA), + ADD_TAG(L"article", ARTICLE), + ADD_TAG(L"aside", ASIDE), + ADD_TAG(L"audio", AUDIO), + ADD_TAG(L"b", B), + ADD_TAG(L"base", BASE), + ADD_TAG(L"basefont", BASEFONT), + ADD_TAG(L"bdi", BDI), + ADD_TAG(L"bdo", BDO), + ADD_TAG(L"bgsound", BGSOUND), + ADD_TAG(L"blockquote", BLOCKQUOTE), + ADD_TAG(L"big", BIG), + ADD_TAG(L"body", BODY), + ADD_TAG(L"blink", BLINK), + ADD_TAG(L"br", BR), + ADD_TAG(L"button", BUTTON), + ADD_TAG(L"canvas", CANVAS), + ADD_TAG(L"caption", CAPTION), + ADD_TAG(L"center", CENTER), + ADD_TAG(L"cite", CITE), + ADD_TAG(L"code", CODE), + ADD_TAG(L"col", COL), + ADD_TAG(L"colgroup", COLGROUP), + ADD_TAG(L"command", SKIP_TAG), // Данного обозначения нет, но т.к.мы всё равно пропускаем, то делаем script + ADD_TAG(L"comment", SKIP_TAG), // Данного обозначения нет, но т.к.мы всё равно пропускаем, то делаем script + ADD_TAG(L"datalist", DATALIST), + ADD_TAG(L"dd", DD), + ADD_TAG(L"del", DEL), + ADD_TAG(L"details", DETAILS), + ADD_TAG(L"dfn", DFN), + ADD_TAG(L"dir", DIR), + ADD_TAG(L"div", DIV), + ADD_TAG(L"dl", DL), + ADD_TAG(L"dt", DT), + ADD_TAG(L"em", EM), + ADD_TAG(L"embed", EMBED), + ADD_TAG(L"fieldset", FIELDSET), + ADD_TAG(L"figcaption", FIGCAPTION), + ADD_TAG(L"figure", FIGURE), + ADD_TAG(L"font", FONT), + ADD_TAG(L"form", FORM), + ADD_TAG(L"footer", FOOTER), + ADD_TAG(L"frame", FRAME), + ADD_TAG(L"frameset", FRAMESET), + ADD_TAG(L"h1", H1), + ADD_TAG(L"h2", H2), + ADD_TAG(L"h3", H3), + ADD_TAG(L"h4", H4), + ADD_TAG(L"h5", H5), + ADD_TAG(L"h6", H6), + ADD_TAG(L"head", HEAD), + ADD_TAG(L"header", HEADER), + ADD_TAG(L"hgroup", HGROUP), + ADD_TAG(L"hr", HR), + ADD_TAG(L"html", HTML), + ADD_TAG(L"i", I), + ADD_TAG(L"iframe", IFRAME), + ADD_TAG(L"img", IMG), + ADD_TAG(L"input", INPUT), + ADD_TAG(L"ins", INS), + ADD_TAG(L"isindex", ISINDEX), + ADD_TAG(L"kbd", KBD), + ADD_TAG(L"keygen", KEYGEN), + ADD_TAG(L"label", LABEL), + ADD_TAG(L"legend", LEGEND), + ADD_TAG(L"li", LI), + ADD_TAG(L"link", LINK), + ADD_TAG(L"main", MAIN), + ADD_TAG(L"map", MAP), + ADD_TAG(L"marquee", MARQUEE), + ADD_TAG(L"mark", MARK), + ADD_TAG(L"menu", MENU), + ADD_TAG(L"meta", META), + ADD_TAG(L"meter", METER), + ADD_TAG(L"nav", NAV), + ADD_TAG(L"nobr", NOBR), + ADD_TAG(L"noembed", NOEMBED), + ADD_TAG(L"noframes", NOFRAMES), + ADD_TAG(L"noscript", NOSCRIPT), + ADD_TAG(L"object", OBJECT), + ADD_TAG(L"ol", OL), + ADD_TAG(L"optgroup", OPTGROUP), + ADD_TAG(L"option", OPTION), + ADD_TAG(L"output", OUTPUT), + ADD_TAG(L"p", P), + ADD_TAG(L"param", PARAM), + ADD_TAG(L"plaintext", PLAINTEXT), + ADD_TAG(L"pre", PRE), + ADD_TAG(L"progress", PROGRESS), + ADD_TAG(L"q", Q), + ADD_TAG(L"rp", RP), + ADD_TAG(L"rt", RT), + ADD_TAG(L"ruby", RUBY), + ADD_TAG(L"s", S), + ADD_TAG(L"samp", SAMP), + ADD_TAG(L"script", SCRIPT), + ADD_TAG(L"section", SECTION), + ADD_TAG(L"select", SELECT), + ADD_TAG(L"small", SMALL), + ADD_TAG(L"span", SPAN), + ADD_TAG(L"source", SOURCE), + ADD_TAG(L"strike", STRIKE), + ADD_TAG(L"strong", STRONG), + ADD_TAG(L"style", STYLE), + ADD_TAG(L"sub", SUB), + ADD_TAG(L"summary", SUMMARY), + ADD_TAG(L"sup", SUP), + ADD_TAG(L"table", TABLE), + ADD_TAG(L"tbody", TBODY), + ADD_TAG(L"td", TD), + ADD_TAG(L"textarea", TEXTAREA), + ADD_TAG(L"tfoot", TFOOT), + ADD_TAG(L"th", TH), + ADD_TAG(L"thead", THEAD), + ADD_TAG(L"time", TIME), + ADD_TAG(L"title", TITLE), + ADD_TAG(L"tr", TR), + ADD_TAG(L"tt", TT), + ADD_TAG(L"u", U), + ADD_TAG(L"ul", UL), + ADD_TAG(L"var", VAR), + ADD_TAG(L"video", VIDEO), + ADD_TAG(L"wbr", WBR), + ADD_TAG(L"xmp", XMP), + + ADD_TAG(L"svg", SVG) +}; + +bool TagIsUnprocessed(const std::wstring& wsTagName) +{ + return L"xml" == wsTagName; +} + +static inline HtmlTag GetHtmlTag(const std::wstring& wsStrTag) +{ + std::map::const_iterator oFound = m_HTML_TAGS.find(wsStrTag); + + if (oFound == m_HTML_TAGS.cend()) + { + if (wsStrTag.length() > 3 && wsStrTag.compare(wsStrTag.length() - 3, 3, L"svg") == 0) + return HTML_TAG(SVG); + return UNKNOWN_TAG; + } + + return oFound->second; +} + +static inline void WriteToStringBuilder(NSStringUtils::CStringBuilder& oSrcStringBuilder, NSStringUtils::CStringBuilder& oDstStringBuilder) +{ + if (oSrcStringBuilder.GetCurSize() < MAX_STRING_BLOCK_SIZE) + { + oDstStringBuilder.Write(oSrcStringBuilder); + return; + } + + size_t ulSize = oSrcStringBuilder.GetCurSize(); + size_t ulCurrentBlockSize = 0, ulPosition = 0; -//struct CTree -//{ -// NSCSS::CNode m_oNode; -// std::vector m_arrChild; -//}; + while (ulSize > 0) + { + ulCurrentBlockSize = std::min(ulSize, MAX_STRING_BLOCK_SIZE); + oDstStringBuilder.WriteString(oSrcStringBuilder.GetSubData(ulPosition, ulCurrentBlockSize)); + + ulSize -= ulCurrentBlockSize; + ulPosition += ulCurrentBlockSize; + } +} // Ячейка таблицы struct CTc @@ -48,8 +244,10 @@ struct CTc int i; int j; std::wstring sGridSpan = L"1"; + std::wstring sPr = L""; - CTc(int _i, int _j, const std::wstring& sColspan) : i(_i), j(_j), sGridSpan(sColspan) {} + CTc(int _i, int _j, const std::wstring& sColspan, const std::wstring& sTcPr = L"") + : i(_i), j(_j), sGridSpan(sColspan), sPr(sTcPr) {} bool operator==(const CTc& c2) { @@ -62,1435 +260,3560 @@ struct CTextSettings { bool bBdo; // Реверс текста bool bPre; // Сохранение форматирования (Сохранение пробелов, табуляций, переносов строк) + bool bQ; // Цитата + bool bAddSpaces; // Добавлять пробелы перед текстом? + bool bMergeText; // Объединять подяр идущий текст в 1? int nLi; // Уровень списка - std::wstring sRStyle; // w:rStyle - std::wstring sPStyle; // w:pStyle - CTextSettings(bool _bBdo, bool _bPre, int _nLi, const std::wstring& _sRStyle, const std::wstring& _sPStyle) : - bBdo(_bBdo), bPre(_bPre), nLi(_nLi), sRStyle(_sRStyle), sPStyle(_sPStyle) {} + std::wstring sPStyle; + + enum ETextMode + { + Normal, + Superscript, + Subscript + } eTextMode; + + NSCSS::CCompiledStyle oAdditionalStyle; + + CTextSettings() + : bBdo(false), bPre(false), bQ(false), bAddSpaces(true), bMergeText(false), nLi(-1), eTextMode(Normal) + {} CTextSettings(const CTextSettings& oTS) : - bBdo(oTS.bBdo), bPre(oTS.bPre), nLi(oTS.nLi), sRStyle(oTS.sRStyle), sPStyle(oTS.sPStyle) {} + bBdo(oTS.bBdo), bPre(oTS.bPre), bQ(oTS.bQ), bAddSpaces(oTS.bAddSpaces), bMergeText(oTS.bMergeText), nLi(oTS.nLi), sPStyle(oTS.sPStyle) + {} + + void AddPStyle(const std::wstring& wsStyle) + { + if (std::wstring::npos == sPStyle.find(wsStyle)) + sPStyle += wsStyle; + } }; -void replace_all(std::wstring& s, const std::wstring& s1, const std::wstring& s2) +struct TImageData { - size_t pos = s.find(s1); - size_t l = s2.length(); - while (pos != std::string::npos) + UINT m_unWidth; + UINT m_unHeight; + + int m_nHSpace; + int m_nVSpace; + + std::wstring m_wsAlign; + + TImageData() + : m_unWidth(0), m_unHeight(0), m_nHSpace(0), m_nVSpace(0), m_wsAlign(L"left") + {} + + bool ZeroSize() const { - if (!(s1 == L"&" && s2 == L"&" && s.length() > pos + 4 && s[pos] == L'&' && s[pos + 1] == L'a' && s[pos + 2] == L'm' && s[pos + 3] == L'p' && s[pos + 4] == L';')) - s.replace(pos, s1.length(), s2); - pos = s.find(s1, pos + l); + return 0 == m_unWidth || 0 == m_unHeight; + } + + bool ZeroSpaces() const + { + return 0 == m_nHSpace && 0 == m_nVSpace; } +}; + +void WriteEmptyParagraph(NSStringUtils::CStringBuilder* pXml, bool bVahish = false, bool bInP = false) +{ + if (NULL == pXml) + return; + + if (!bInP) + pXml->WriteString(L""); + + pXml->WriteString(L""); + + if (bVahish) + pXml->WriteString(L""); + + pXml->WriteString(L""); + + if (!bInP) + pXml->WriteString(L""); } -std::wstring EncodeXmlString(const std::wstring& s) +void WriteLine(NSStringUtils::CStringBuilder* pXml, const std::wstring& wsAlign, const std::wstring& wsColor, bool bShade, double dSize, double dWidth) { - std::wstring sRes = s; + if (dWidth < 0) + dWidth = -dWidth; - replace_all(sRes, L"&", L"&"); - replace_all(sRes, L"<", L"<"); - replace_all(sRes, L">", L">"); - replace_all(sRes, L"\"", L"""); - replace_all(sRes, L"\'", L"'"); - replace_all(sRes, L"\n", L" "); - replace_all(sRes, L"\r", L" "); - replace_all(sRes, L"\t", L" "); + if (dSize < 0) + dSize = -dSize; - return sRes; + if (dWidth > 100) + dWidth = 0; + + pXml->WriteNodeBegin(L"w:pict"); + pXml->WriteString(L""); + pXml->WriteNodeEnd(L"w:pict"); } -class CHtmlFile2_Private +bool ElementInTable(const std::vector& arSelectors) { -public: - XmlUtils::CXmlLiteReader m_oLightReader; // SAX Reader - NSCSS::CCssCalculator m_oStylesCalculator; // Css калькулятор - NSCSS::CDocumentStyle m_oXmlStyle; // Ooxml стиль + return arSelectors.crend() != std::find_if(arSelectors.crbegin(), arSelectors.crend(), [](const NSCSS::CNode& oNode) { return L"table" == oNode.m_wsName; }); +} - std::wstring m_sTmp; // Temp папка - std::wstring m_sSrc; // Директория источника - std::wstring m_sDst; // Директория назначения - std::wstring m_sBase; // Полный базовый адрес +UINT GetFontSizeLevel(UINT unFontSize) +{ + if (unFontSize <= 18) + return 1; + else if (unFontSize <= 22) + return 2; + else if (unFontSize <= 26) + return 3; + else if (unFontSize <= 30) + return 4; + else if (unFontSize <= 40) + return 5; + else if (unFontSize <= 59) + return 6; + else + return 7; +} - NSCSS::CTree m_oTree; // Дерево body html-файла +UINT GetFontSizeByLevel(UINT unLevel) +{ + if (0 == unLevel) + return 15; + else if (unLevel > 7) + return 72; -private: - int m_nFootnoteId; // ID сноски - int m_nHyperlinkId; // ID ссылки - int m_nCrossId; // ID перекрестной ссылки - int m_nNumberingId; // ID списка + switch (unLevel) + { + case 1: return 15; + case 2: return 20; + case 3: return 24; + case 4: return 27; + case 5: return 36; + case 6: return 48; + case 7: return 72; + } + return 24; +} - NSStringUtils::CStringBuilder m_oStylesXml; // styles.xml - NSStringUtils::CStringBuilder m_oDocXmlRels; // document.xml.rels - NSStringUtils::CStringBuilder m_oNoteXmlRels; // footnotes.xml.rels - NSStringUtils::CStringBuilder m_oDocXml; // document.xml - NSStringUtils::CStringBuilder m_oNoteXml; // footnotes.xml - NSStringUtils::CStringBuilder m_oNumberXml; // numbering.xml +int CalculateFontChange(const std::vector& arSelectors) +{ + int nFontChange = 0; - bool m_bInP; // открыт? - bool m_bWasPStyle; // записан? - bool m_bWasSpace; // Был пробел? + for (const NSCSS::CNode& oNode : arSelectors) + { + if (L"big" == oNode.m_wsName) + ++nFontChange; + else if (L"small" == oNode.m_wsName) + --nFontChange; + } - std::vector m_arrImages; // Картинки - std::map m_mFootnotes; // Сноски -public: + return nFontChange; +} + +#define FIRST_ELEMENT 0x00000001 +#define LAST_ELEMENT 0x00000002 +#define MID_ELEMENT 0x00000004 + +#define PARSE_MODE_HEADER 0x00000100 +#define PARSE_MODE_BODY 0x00000200 +#define PARSE_MODE_FOOTHER 0x00000400 + +#define COL_POSITION_MASK 0x0000000F +#define ROW_POSITION_MASK 0x000000F0 +#define PARSE_MODE_MASK 0x00000F00 + +typedef enum +{ + ParseModeHeader, + ParseModeBody, + ParseModeFoother +} ERowParseMode; + +//Необходимые стили таблицы +struct TTableStyles +{ + NSCSS::NSProperties::CIndent m_oPadding; + NSCSS::NSProperties::CIndent m_oMargin; + NSCSS::NSProperties::CBorder m_oBorder; + NSCSS::NSProperties::CDigit m_oWidth; + + int m_nCellSpacing; - CHtmlFile2_Private() : m_nFootnoteId(1), m_nHyperlinkId(1), m_nCrossId(1), m_nNumberingId(1), m_bInP(false), m_bWasPStyle(false), m_bWasSpace(false) + std::wstring m_wsAlign; + + enum ETableRules + { + All, + Groups, + Cols, + None, + Rows + } m_enRules; + + TTableStyles() + : m_nCellSpacing(-1), m_enRules(None) + {} + + bool Empty() const { - //Установим размер исходного и нового окна для Css калькулятора (должны быть одинаковые единицы измерения (желательно пункты)) - //Это нужно для масштабирования некоторых значений - m_oStylesCalculator.SetSizeSourceWindow(NSCSS::CSizeWindow(4940 * (1366 * (25.4 / m_oStylesCalculator.GetDpi())), 0)); - m_oStylesCalculator.SetSizeDeviceWindow(NSCSS::CSizeWindow(4940, 0)); + return m_oPadding.Empty() && m_oMargin.Empty() && m_oBorder.Empty() && m_oWidth.Empty() && -1 == m_nCellSpacing && m_wsAlign.empty(); } +}; - ~CHtmlFile2_Private() +std::wstring CreateBorders(const NSCSS::NSProperties::CBorder& oBorder, const NSCSS::NSProperties::CIndent* pPadding = NULL, bool bAddIntermediateLines = false, TTableStyles::ETableRules enTableRule = TTableStyles::ETableRules::None) +{ + std::wstring wsTable; + + if (oBorder.EqualSides() && (NULL == pPadding || pPadding->Equals())) { - m_oLightReader .Clear(); - m_oStylesCalculator.Clear(); - m_oXmlStyle .Clear(); - m_oStylesXml .Clear(); - m_oDocXmlRels .Clear(); - m_oNoteXmlRels .Clear(); - m_oDocXml .Clear(); - m_oNoteXml .Clear(); - m_oNumberXml .Clear(); + const std::wstring wsBorderStyle = NSCSS::CDocumentStyle::CalculateBorderStyle(oBorder.GetLeftBorder(), ((NULL == pPadding) ? NULL : (&(pPadding->GetLeft())))); + + wsTable = L"" + L"" + + L"" + L""; } + else + { + if (oBorder.GetTopBorder().Valid()) + wsTable += L"GetTop())))) + L"/>"; - // Проверяет наличие тэга html - bool isHtml() + if (oBorder.GetLeftBorder().Valid()) + wsTable += L"GetLeft())))) + L"/>"; + + if (oBorder.GetBottomBorder().Valid()) + wsTable += L"GetBottom())))) + L"/>"; + + if (oBorder.GetRightBorder().Valid()) + wsTable += L"GetRight())))) + L"/>"; + } + + if (!bAddIntermediateLines) + return wsTable; + + if (TTableStyles::ETableRules::Rows == enTableRule || TTableStyles::ETableRules::All == enTableRule) { - return (m_oLightReader.ReadNextNode() ? m_oLightReader.GetName() == L"html" : false); + NSCSS::NSProperties::CBorderSide oNewSide(oBorder.GetBottomBorder()); + oNewSide.SetWidth(L"1pt", 0, true); + + wsTable += L""; } - // Создаёт основу docx - void CreateDocxEmpty(CHtmlParams* oParams) + if (TTableStyles::ETableRules::Cols == enTableRule || TTableStyles::ETableRules::All == enTableRule) { - // Создаем пустые папки - NSDirectory::CreateDirectory(m_sDst + L"/_rels"); - NSDirectory::CreateDirectory(m_sDst + L"/docProps"); - NSDirectory::CreateDirectory(m_sDst + L"/word"); - NSDirectory::CreateDirectory(m_sDst + L"/word/_rels"); - NSDirectory::CreateDirectory(m_sDst + L"/word/media"); - NSDirectory::CreateDirectory(m_sDst + L"/word/theme"); + NSCSS::NSProperties::CBorderSide oNewSide(oBorder.GetRightBorder()); + oNewSide.SetWidth(L"1pt", 0, true); - // theme1.xml - std::wstring sTheme = L""; - NSFile::CFileBinary oThemeWriter; - if (oThemeWriter.CreateFileW(m_sDst + L"/word/theme/theme1.xml")) - { - oThemeWriter.WriteStringUTF8(sTheme); - oThemeWriter.CloseFile(); - } + wsTable += L""; + } - // app.xml - std::wstring sApplication = NSSystemUtils::GetEnvVariable(NSSystemUtils::gc_EnvApplicationName); - if (sApplication.empty()) - sApplication = NSSystemUtils::gc_EnvApplicationNameDefault; -#if defined(INTVER) - std::string sVersion = VALUE2STR(INTVER); -#endif - std::wstring sApp = L""; - sApp += sApplication + L"/" + UTF8_TO_U(sVersion); - sApp += L"0falsefalsefalsefalse"; - NSFile::CFileBinary oAppWriter; - if (oAppWriter.CreateFileW(m_sDst + L"/docProps/app.xml")) - { - oAppWriter.WriteStringUTF8(sApp); - oAppWriter.CloseFile(); - } + return wsTable; +} - // .rels - std::wstring sRels = L""; - NSFile::CFileBinary oRelsWriter; - if (oRelsWriter.CreateFileW(m_sDst + L"/_rels/.rels")) - { - oRelsWriter.WriteStringUTF8(sRels); - oRelsWriter.CloseFile(); - } +std::wstring CreateBorders(const std::wstring& wsStyle, UINT unSize, UINT unSpace, const std::wstring& wsAuto) +{ + const std::wstring wsBodyBorder{L"w:val=\"" + wsStyle + L"\" w:sz=\"" + std::to_wstring(unSize) + L"\" w:space=\"" + std::to_wstring(unSpace) + L"\" w:color=\"" + wsAuto + L"\""}; - // [Content_Types].xml - std::wstring sContent = L""; - NSFile::CFileBinary oContentWriter; - if (oContentWriter.CreateFileW(m_sDst + L"/[Content_Types].xml")) - { - oContentWriter.WriteStringUTF8(sContent); - oContentWriter.CloseFile(); - } + return L"" + + L"" + + L"" + + L""; +} - // fontTable.xml - std::wstring sFontTable = L""; - NSFile::CFileBinary oFontTableWriter; - if (oFontTableWriter.CreateFileW(m_sDst + L"/word/fontTable.xml")) - { - oFontTableWriter.WriteStringUTF8(sFontTable); - oFontTableWriter.CloseFile(); - } +#define CreateOutsetBorders(enType) CreateBorders(L"outset", 6, 0, L"auto", enType) - // settings.xml - std::wstring sSettings = L""; - NSFile::CFileBinary oSettingsWriter; - if (oSettingsWriter.CreateFileW(m_sDst + L"/word/settings.xml")) - { - oSettingsWriter.WriteStringUTF8(sSettings); - oSettingsWriter.CloseFile(); - } +std::wstring CreateDefaultBorder(std::wstring wsSideName) +{ + std::transform(wsSideName.begin(), wsSideName.end(), wsSideName.begin(), std::towlower); + return L""; +} - // webSettings.xml - std::wstring sWebSettings = L""; - NSFile::CFileBinary oWebWriter; - if (oWebWriter.CreateFileW(m_sDst + L"/word/webSettings.xml")) - { - oWebWriter.WriteStringUTF8(sWebSettings); - oWebWriter.CloseFile(); - } +struct TTableRowStyle +{ + UINT m_unMaxIndex; + UINT m_unMaxHeight; + bool m_bIsHeader; - // numbering.xml - // Маркированный список - m_oNumberXml += L""; + TTableRowStyle() + : m_unMaxIndex(0), m_unMaxHeight(0), m_bIsHeader(false) + {} - // core.xml - std::wstring sCore = L""; - if(oParams) - { - if(!oParams->m_sBookTitle.empty()) - { - sCore += L""; - sCore += EncodeXmlString(oParams->m_sBookTitle); - sCore += L""; - } - if(!oParams->m_sAuthors.empty()) - { - sCore += L""; - sCore += EncodeXmlString(oParams->m_sAuthors); - sCore += L""; - } - if(!oParams->m_sGenres.empty()) - { - sCore += L""; - sCore += EncodeXmlString(oParams->m_sGenres); - sCore += L""; - } - if(!oParams->m_sDate.empty()) - { - sCore += L""; - sCore += EncodeXmlString(oParams->m_sDate); - sCore += L""; - } - if(!oParams->m_sDescription.empty()) + bool Empty() const + { + return 0 == m_unMaxHeight && false == m_bIsHeader; + } +}; + +struct TTableCellStyle +{ + NSCSS::NSProperties::CDigit m_oWidth; + NSCSS::NSProperties::CDigit m_oHeight; + NSCSS::NSProperties::CBorder m_oBorder; + NSCSS::NSProperties::CIndent m_oPadding; + NSCSS::NSProperties::CColor m_oBackground; + + std::wstring m_wsHAlign; + std::wstring m_wsVAlign; + + TTableCellStyle(){} + + bool Empty() + { + return m_oWidth.Empty() && m_oHeight.Empty() && m_oBorder.Empty() && m_oPadding.Empty() && m_wsVAlign.empty() && m_wsVAlign.empty(); + } + + void Copy(const TTableCellStyle* pTableCellStyle) + { + if (NULL == pTableCellStyle) + return; + + m_oWidth = pTableCellStyle->m_oWidth; + m_oHeight = pTableCellStyle->m_oHeight; + m_oBorder = pTableCellStyle->m_oBorder; + m_oPadding = pTableCellStyle->m_oPadding; + m_oBackground = pTableCellStyle->m_oBackground; + + m_wsHAlign = pTableCellStyle->m_wsHAlign; + m_wsVAlign = pTableCellStyle->m_wsVAlign; + } + + TTableCellStyle& operator+=(const TTableCellStyle* pCellStyle) + { + if (NULL == pCellStyle) + return *this; + + m_oWidth += pCellStyle->m_oWidth; + m_oHeight += pCellStyle->m_oHeight; + m_oBorder += pCellStyle->m_oBorder; + m_oPadding += pCellStyle->m_oPadding; + m_oBackground += pCellStyle->m_oBackground; + + if (m_wsHAlign.empty()) + m_wsHAlign = pCellStyle->m_wsHAlign; + + if (m_wsVAlign.empty()) + m_wsVAlign = pCellStyle->m_wsVAlign; + + return *this; + } +}; + +class CTable; + +class CTableCell +{ +public: + CTableCell() + : m_unColspan(1), m_unRowSpan(1), m_bIsMerged(false), m_bIsEmpty(false) + {} + + CTableCell(UINT unColspan, UINT unRowspan, bool bIsMerged, bool bIsEmpty) + : m_unColspan(unColspan), m_unRowSpan(unRowspan), m_bIsMerged(bIsMerged), m_bIsEmpty(bIsEmpty) + {} + + CTableCell(CTableCell& oCell) + : m_unColspan(oCell.m_unColspan), m_unRowSpan(oCell.m_unRowSpan), m_bIsMerged(oCell.m_bIsMerged), + m_bIsEmpty(oCell.m_bIsEmpty), m_oStyles(oCell.m_oStyles) + { + WriteToStringBuilder(oCell.m_oData, m_oData); + } + + bool Empty() + { + return m_bIsEmpty; + } + + bool Merged() + { + return m_bIsMerged; + } + + CTableCell* Copy() + { + return new CTableCell(*this); + } + + static CTableCell* CreateEmpty(UINT unColspan = 1, bool m_bIsMerged = false, const TTableCellStyle* pStyle = NULL) + { + CTableCell *pCell = new CTableCell(unColspan, 1, m_bIsMerged, true); + + pCell->m_oStyles.Copy(pStyle); + + return pCell; + } + + static CTableCell* CreateEmpty(const TTableCellStyle* pStyle) + { + CTableCell *pCell = new CTableCell(1, 1, false, true); + + pCell->m_oStyles.Copy(pStyle); + + return pCell; + } + + void SetColspan(UINT unColspan, UINT unCurrentIndex) + { + if (MAXCOLUMNSINTABLE - 1 != unCurrentIndex) + m_unColspan = std::min(MAXCOLUMNSINTABLE - 1 - unCurrentIndex, unColspan); + else + m_unColspan = 1; + } + + UINT GetColspan() const + { + return m_unColspan; + } + + void SetRowspan(UINT unRowspan) + { + m_unRowSpan = unRowspan; + } + + UINT GetRowspan() const + { + return m_unRowSpan; + } + + NSStringUtils::CStringBuilder* GetData() + { + return &m_oData; + } + + const TTableCellStyle* GetStyles() const + { + return &m_oStyles; + } + + TTableCellStyle* GetStyles() + { + return &m_oStyles; + } + + void SetWidth(const NSCSS::NSProperties::CDigit& oWidth) + { + m_oStyles.m_oWidth = oWidth; + } + + void SetHeight(const NSCSS::NSProperties::CDigit& oHeight) + { + m_oStyles.m_oHeight = oHeight; + } + + UINT GetHeight() const + { + return m_oStyles.m_oHeight.ToInt(NSCSS::Twips, DEFAULT_PAGE_HEIGHT); + } + + void SetBorder(const NSCSS::NSProperties::CBorder& oBorder) + { + m_oStyles.m_oBorder = oBorder; + } + + void ClearTopBorder() + { + m_oStyles.m_oBorder.SetTopSide(L"none", 0, true); + } + + void ClearLeftBorder() + { + m_oStyles.m_oBorder.SetLeftSide(L"none", 0, true); + } + + void ClearBottomBorder() + { + m_oStyles.m_oBorder.SetBottomSide(L"none", 0, true); + } + + void ClearRightBorder() + { + m_oStyles.m_oBorder.SetRightSide(L"none", 0, true); + } + + void SetPadding(const NSCSS::NSProperties::CIndent& oPadding) + { + m_oStyles.m_oPadding = oPadding; + } + + void SetHAlign(const std::wstring& wsAlign) + { + m_oStyles.m_wsHAlign = wsAlign; + } + + void SetVAlign(const std::wstring& wsAlign) + { + m_oStyles.m_wsVAlign = wsAlign; + } + + void SetBackground(const NSCSS::NSProperties::CColor& oColor) + { + m_oStyles.m_oBackground = oColor; + } + + std::wstring ConvertToOOXML(const CTable& oTable, UINT unColumnNumber, int nInstruction); +private: + UINT m_unColspan; + UINT m_unRowSpan; + + bool m_bIsMerged; + bool m_bIsEmpty; + + TTableCellStyle m_oStyles; + NSStringUtils::CStringBuilder m_oData; +}; + +class CTableRow +{ +public: + CTableRow() + {} + + ~CTableRow() + { + for (CTableCell* pCell : m_arCells) + RELEASEOBJECT(pCell); + } + + void AddCell(CTableCell* pCell) + { + InsertCell(pCell, -1); + } + + void InsertCell(CTableCell *pCell, int nPosition) + { + if (NULL == pCell) + return; + + if (nPosition < 0) + { + std::vector::iterator itFoundEmpty = std::find_if(m_arCells.begin(), m_arCells.end(), [](CTableCell* pCell) { return pCell->Empty() && !pCell->Merged(); }); + + if (m_arCells.end() != itFoundEmpty) + { + --m_oStyles.m_unMaxIndex; + delete *itFoundEmpty; + *itFoundEmpty = pCell; + + if (1 != pCell->GetColspan()) + { + ++itFoundEmpty; + UINT unColspan = pCell->GetColspan() - 1; + + while (m_arCells.end() != itFoundEmpty && (*itFoundEmpty)->Empty() && unColspan > 0) + { + --m_oStyles.m_unMaxIndex; + --unColspan; + delete (*itFoundEmpty); + itFoundEmpty = m_arCells.erase(itFoundEmpty); + } + + if (unColspan != 0) + pCell->SetColspan(pCell->GetColspan() - unColspan, MAXCOLUMNSINTABLE); + } + } + else + m_arCells.push_back(pCell); + } + else if (nPosition >= m_arCells.size()) + { + const UINT unMissingCount = nPosition - m_arCells.size(); + + for (UINT unIndex = 0; unIndex < unMissingCount; ++unIndex) + m_arCells.push_back(CTableCell::CreateEmpty()); + + m_oStyles.m_unMaxIndex += unMissingCount; + + m_arCells.push_back(pCell); + } + else if (m_arCells[nPosition]->Empty()) + { + delete m_arCells[nPosition]; + --m_oStyles.m_unMaxIndex; + m_arCells[nPosition] = pCell; + + if (1 != pCell->GetColspan()) + { + ++nPosition; + UINT unDeleteCount = pCell->GetColspan() - 1; + while (nPosition < m_arCells.size() && m_arCells[nPosition]->Empty() && !m_arCells[nPosition]->Merged() && unDeleteCount > 0) + { + delete m_arCells[nPosition]; + --m_oStyles.m_unMaxIndex; + m_arCells.erase(m_arCells.begin() + nPosition); + --unDeleteCount; + } + + if (0 != unDeleteCount) + pCell->SetColspan(pCell->GetColspan() - unDeleteCount, MAXCOLUMNSINTABLE); + } + } + else + m_arCells.insert(m_arCells.begin() + nPosition, pCell); + + m_oStyles.m_unMaxIndex += pCell->GetColspan(); + + if (1 == pCell->GetColspan() && 1 == pCell->GetRowspan()) + m_oStyles.m_unMaxHeight = std::max(m_oStyles.m_unMaxHeight, pCell->GetHeight()); + } + + UINT GetIndex() const + { + return m_oStyles.m_unMaxIndex; + } + + UINT GetCount() const + { + return m_arCells.size(); + } + + std::wstring ConvertToOOXML(const CTable& oTable, int nInstruction); + + CTableCell* operator[](UINT unIndex) + { + if (unIndex >= m_arCells.size()) + return NULL; + + return m_arCells[unIndex]; + } +private: + TTableRowStyle m_oStyles; + std::vector m_arCells; +}; + +class CTableCol +{ +public: + CTableCol(UINT unSpan) + : m_unSpan(unSpan) + {} + + CTableCol(XmlUtils::CXmlLiteReader& oLiteReader) + : m_unSpan(1) + { + while (oLiteReader.MoveToNextAttribute()) + { + if (L"span" == oLiteReader.GetName()) + m_unSpan = NSStringFinder::ToInt(oLiteReader.GetText(), 1); + } + + oLiteReader.MoveToElement(); + } + + UINT GetSpan() const + { + return m_unSpan; + } + + TTableCellStyle* GetStyle() + { + return &m_oStyle; + } + + const TTableCellStyle* GetStyle() const + { + return &m_oStyle; + } +private: + UINT m_unSpan; + TTableCellStyle m_oStyle; +}; + +class CTableColgroup +{ +public: + CTableColgroup(XmlUtils::CXmlLiteReader& oLiteReader) + : m_unWidth(0) + { + while (oLiteReader.MoveToNextAttribute()) + { + if (L"width" == oLiteReader.GetName()) + m_unWidth = NSStringFinder::ToInt(oLiteReader.GetText()); + } + + oLiteReader.MoveToElement(); + } + + ~CTableColgroup() + { + RELEASE_VECTOR_PTR(m_arCols, CTableCol) + } + + bool Empty() const + { + return m_arCols.empty(); + } + + void AddCol(CTableCol* pCol) + { + if (NULL != pCol) + m_arCols.push_back(pCol); + } + + const std::vector& GetCols() const + { + return m_arCols; + } +private: + std::vector m_arCols; + UINT m_unWidth; +}; + +class CTable +{ +public: + CTable() + : m_unMaxColumns(0) + {} + + ~CTable() + { + for (std::vector& arHeaders : m_arHeaders) + RELEASE_VECTOR_PTR(arHeaders, CTableRow) + + RELEASE_VECTOR_PTR(m_arFoother, CTableRow) + RELEASE_VECTOR_PTR(m_arRows, CTableRow) + RELEASE_VECTOR_PTR(m_arColgroups, CTableColgroup) + } + + CTableRow* operator[](UINT unIndex) + { + if (unIndex < m_arRows.size()) + return m_arRows[unIndex]; + + return NULL; + } + + bool Empty() const + { + return m_arRows.empty(); + } + + bool HaveCaption() + { + return 0 != m_oCaption.GetCurSize(); + } + + bool HaveColgroups() const + { + return !m_arColgroups.empty(); + } + + UINT GetRowCount() const + { + return m_arRows.size(); + } + + TTableStyles GetTableStyles() const + { + return m_oStyles; + } + + const TTableCellStyle* GetColStyle(UINT unColumnNumber) const + { + if (m_arColgroups.empty()) + return NULL; + + UINT unCurrentNumber = 0; + + for (const CTableColgroup* pColgroup : m_arColgroups) + { + for (const CTableCol* pCol : pColgroup->GetCols()) + { + unCurrentNumber += pCol->GetSpan(); + + if (unCurrentNumber >= unColumnNumber) + return pCol->GetStyle(); + } + } + + return NULL; + } + + std::wstring CalculateSidesToClean(UINT unColumnNumber) const + { + if (m_arColgroups.empty()) + return std::wstring(); + + UINT unCurrentNumber = 0; + + for (const CTableColgroup* pColgroup : m_arColgroups) + { + for (const CTableCol* pCol : pColgroup->GetCols()) + { + if (unCurrentNumber + 1 == unCurrentNumber) + return (1 != pCol->GetSpan()) ? L"" : std::wstring(); + + unCurrentNumber += pCol->GetSpan(); + + if (unColumnNumber == unCurrentNumber) + return (1 != pCol->GetSpan()) ? L"" : std::wstring(); + else if (unColumnNumber < unCurrentNumber) + return std::wstring((1 != unColumnNumber) ? L"" : L"") + std::wstring((m_unMaxColumns != unColumnNumber) ? L"" : L""); + } + } + + return std::wstring(); + } + + void AddRows(std::vector& m_arRows, ERowParseMode eParseMode = ERowParseMode::ParseModeBody) + { + if (m_arRows.empty()) + return; + + if (ERowParseMode::ParseModeFoother == eParseMode && !m_arFoother.empty()) + eParseMode = ERowParseMode::ParseModeHeader; + + if (ERowParseMode::ParseModeHeader == eParseMode) + m_arHeaders.push_back({}); + + for (CTableRow* pRow : m_arRows) + AddRow(pRow, eParseMode); + } + + void AddRow(CTableRow* pRow, ERowParseMode eParseMode = ERowParseMode::ParseModeBody) + { + if (NULL == pRow) + return; + + for (UINT unIndex = 0; unIndex < pRow->GetCount(); ++unIndex) + { + if (unIndex >= m_arMinColspan.size()) + m_arMinColspan.push_back((*pRow)[unIndex]->GetColspan()); + else if ((*pRow)[unIndex]->GetColspan() < m_arMinColspan[unIndex]) + m_arMinColspan[unIndex] = (*pRow)[unIndex]->GetColspan(); + } + + switch (eParseMode) + { + default: + case ERowParseMode::ParseModeBody: + { + m_arRows.push_back(pRow); + break; + } + case ERowParseMode::ParseModeHeader: + { + if (m_arHeaders.empty()) + m_arHeaders.push_back({}); + + m_arHeaders.back().push_back(pRow); + break; + } + case ERowParseMode::ParseModeFoother: + { + m_arFoother.push_back(pRow); + break; + } + } + } + + void AddCaption(NSStringUtils::CStringBuilder& oCaption) + { + WriteToStringBuilder(oCaption, m_oCaption); + } + + void SetPadding(const NSCSS::NSProperties::CIndent& oPadding) + { + m_oStyles.m_oPadding = oPadding; + } + + void SetMargin(const NSCSS::NSProperties::CIndent& oMargin) + { + m_oStyles.m_oMargin = oMargin; + } + + const NSCSS::NSProperties::CIndent& GetPadding() const + { + return m_oStyles.m_oPadding; + } + + void SetBorder(const NSCSS::NSProperties::CBorder& oBorder) + { + m_oStyles.m_oBorder = oBorder; + } + + void SetWidth(const NSCSS::NSProperties::CDigit& oWidth) + { + m_oStyles.m_oWidth = oWidth; + } + + void SetCellSpacing(int nCellSpacing) + { + m_oStyles.m_nCellSpacing = nCellSpacing; + } + + void SetAlign(const std::wstring& wsValue) + { + m_oStyles.m_wsAlign = wsValue; + } + + void SetRules(const std::wstring& wsValue) + { + if (wsValue.empty()) + return; + + if (NSStringFinder::Equals(wsValue, L"all")) + m_oStyles.m_enRules = TTableStyles::ETableRules::All; + else if (NSStringFinder::Equals(wsValue, L"groups")) + m_oStyles.m_enRules = TTableStyles::ETableRules::Groups; + else if (NSStringFinder::Equals(wsValue, L"cols")) + m_oStyles.m_enRules = TTableStyles::ETableRules::Cols; + else if (NSStringFinder::Equals(wsValue, L"none")) + m_oStyles.m_enRules = TTableStyles::ETableRules::None; + else if (NSStringFinder::Equals(wsValue, L"rows")) + m_oStyles.m_enRules = TTableStyles::ETableRules::Rows; + } + + void AddColgroup(CTableColgroup* pElement) + { + if (NULL != pElement) + m_arColgroups.push_back(pElement); + } + + void RecalculateMaxColumns() + { + for (const CTableRow* pRow : m_arRows) + m_unMaxColumns = std::max(m_unMaxColumns, pRow->GetIndex()); + } + + void Shorten() + { + UINT unIndex = 0; + CTableCell* pCell = NULL; + + UINT unMaxIndex = 0; //Максимальный индекс без учета строк, где имеется только 1 ячейка + + for (const CTableRow* pRow : m_arRows) + { + if (1 < pRow->GetCount()) + unMaxIndex = std::max(unMaxIndex, pRow->GetIndex()); + } + + while (unIndex < m_arMinColspan.size()) + { + for (CTableRow* pRow : m_arRows) + { + if (0 != unMaxIndex && 1 == pRow->GetCount() && pRow->GetIndex() > unMaxIndex) + { + pCell = (*pRow)[unIndex]; + + if (NULL == pCell) + continue; + + pCell->SetColspan(unMaxIndex, MAXCOLUMNSINTABLE); + continue; + } + + if (1 == m_arMinColspan[unIndex]) + break; + + pCell = (*pRow)[unIndex]; + + if (NULL == pCell) + continue; + + if (1 < pCell->GetColspan() && pCell->GetColspan() > m_arMinColspan[unIndex]) + { + pCell->SetColspan(m_arMinColspan[unIndex], MAXCOLUMNSINTABLE); + continue; + } + + if ((*pRow)[unIndex]->GetColspan() == m_arMinColspan[unIndex] + 1) + (*pRow)[unIndex]->SetColspan(2, MAXCOLUMNSINTABLE); + else if ((*pRow)[unIndex]->GetColspan() > m_arMinColspan[unIndex]) + (*pRow)[unIndex]->SetColspan((*pRow)[unIndex]->GetColspan() - m_arMinColspan[unIndex], MAXCOLUMNSINTABLE); + } + + ++unIndex; + } + } + + void CompleteTable() + { + UINT unMaxIndex = 0; + + for (CTableRow* pRow : m_arRows) + unMaxIndex = std::max(unMaxIndex, pRow->GetIndex()); + + for (CTableRow* pRow : m_arRows) + { + if (NULL == pRow || 0 == pRow->GetCount()) + continue; + + for (UINT unIndex = pRow->GetIndex(); unIndex < unMaxIndex; ++unIndex) + pRow->InsertCell(CTableCell::CreateEmpty(), unIndex); + } + + RecalculateMaxColumns(); + } + + bool ConvertToOOXML(NSStringUtils::CStringBuilder& oStringBuilder) + { + if (m_arRows.empty()) + return false; + + oStringBuilder.WriteNodeBegin(L"w:tbl"); + oStringBuilder.WriteNodeBegin(L"w:tblPr"); + + if (!m_oStyles.m_oWidth.Empty() && !m_oStyles.m_oWidth.Zero()) + { + if (NSCSS::UnitMeasure::Percent == m_oStyles.m_oWidth.GetUnitMeasure()) + oStringBuilder += L""; + else + oStringBuilder += L""; + } + else + oStringBuilder += L""; + + if (!m_oStyles.m_oMargin.GetLeft().Empty() && !m_oStyles.m_oMargin.GetLeft().Zero()) + { + if (NSCSS::UnitMeasure::Percent == m_oStyles.m_oMargin.GetLeft().GetUnitMeasure()) + oStringBuilder += L""; + else + oStringBuilder += L""; + } + + if (!m_oStyles.m_wsAlign.empty()) + oStringBuilder += L""; + + if (0 < m_oStyles.m_nCellSpacing && m_oStyles.m_oBorder.GetCollapse() != NSCSS::NSProperties::BorderCollapse::Collapse) + oStringBuilder += L""; + + if (!m_oStyles.m_oBorder.Empty() && !m_oStyles.m_oBorder.Zero()) + oStringBuilder += L"" + CreateBorders(m_oStyles.m_oBorder, NULL, true, (TTableStyles::ETableRules::Groups == m_oStyles.m_enRules && !m_arColgroups.empty()) ? TTableStyles::ETableRules::Cols : m_oStyles.m_enRules) + L""; + + if (!m_oStyles.m_oPadding.Empty() && !m_oStyles.m_oPadding.Zero()) + { + const int nTopPadding = std::max(0, m_oStyles.m_oPadding.GetTop() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_HEIGHT)); + const int nLeftPadding = std::max(0, m_oStyles.m_oPadding.GetLeft() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_WIDTH )); + const int nBottomPadding = std::max(0, m_oStyles.m_oPadding.GetBottom().ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_HEIGHT)); + const int nRightPadding = std::max(0, m_oStyles.m_oPadding.GetRight() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_WIDTH )); + + oStringBuilder.WriteNodeBegin(L"w:tblCellMar"); + + if (0 != nTopPadding) + oStringBuilder += L""; + + if (0 != nLeftPadding) + oStringBuilder += L""; + + if (0 != nBottomPadding) + oStringBuilder += L""; + + if (0 != nRightPadding) + oStringBuilder += L""; + + oStringBuilder.WriteNodeEnd(L"w:tblCellMar"); + } + else + oStringBuilder += L""; + + oStringBuilder += L""; + oStringBuilder.WriteNodeEnd(L"w:tblPr"); + + if (HaveCaption()) + { + oStringBuilder.WriteNodeBegin(L"w:tr"); + oStringBuilder.WriteNodeBegin(L"w:tc"); + oStringBuilder.WriteNodeBegin(L"w:tcPr"); + oStringBuilder += L""; + oStringBuilder += L""; + oStringBuilder += L""; + oStringBuilder += L""; + oStringBuilder += L""; + oStringBuilder.WriteNodeEnd(L"w:tcPr"); + WriteToStringBuilder(m_oCaption, oStringBuilder); + oStringBuilder.WriteNodeEnd(L"w:tc"); + oStringBuilder.WriteNodeEnd(L"w:tr"); + } + + #define CONVERT_ROWS(rows, mode) \ + { \ + for (UINT unRowIndex = 0; unRowIndex < rows.size(); ++unRowIndex) \ + { \ + int nInstruction = 0; \ + if (0 == unRowIndex) \ + nInstruction |= FIRST_ELEMENT << 4; \ + if (rows.size() - 1 == unRowIndex) \ + nInstruction |= LAST_ELEMENT << 4; \ + else if (0 != unRowIndex) \ + nInstruction |= MID_ELEMENT << 4; \ + nInstruction |= mode; \ + oStringBuilder += rows[unRowIndex]->ConvertToOOXML(*this, nInstruction); \ + } \ + } + + for (std::vector& arRows : m_arHeaders) + CONVERT_ROWS(arRows, PARSE_MODE_HEADER) + + CONVERT_ROWS(m_arRows, PARSE_MODE_BODY) + CONVERT_ROWS(m_arFoother, PARSE_MODE_FOOTHER) + + oStringBuilder.WriteNodeEnd(L"w:tbl"); + + return true; + } +private: + std::vector> m_arHeaders; + std::vector m_arFoother; + std::vector m_arRows; + + std::vector m_arMinColspan; + + NSStringUtils::CStringBuilder m_oCaption; + + std::vector m_arColgroups; + + TTableStyles m_oStyles; + + UINT m_unMaxColumns; +}; + +enum class EAbstructNumType +{ + Bullet, + CardinalText, + Chicago, + Decimal, + DecimalEnclosedCircle, + DecimalEnclosedFullstop, + DecimalEnclosedParen, + DecimalZero, + LowerLetter, + LowerRoman, + None, + OrdinalText, + UpperLetter, + UpperRoman +}; + +void replace_all(std::wstring& s, const std::wstring& s1, const std::wstring& s2) +{ + size_t pos = s.find(s1); + size_t l = s2.length(); + while (pos != std::string::npos) + { + if (!(s1 == L"&" && s2 == L"&" && s.length() > pos + 4 && s[pos] == L'&' && s[pos + 1] == L'a' && s[pos + 2] == L'm' && s[pos + 3] == L'p' && s[pos + 4] == L';')) + s.replace(pos, s1.length(), s2); + pos = s.find(s1, pos + l); + } +} + +void ReplaceSpaces(std::wstring& wsValue) +{ + boost::wregex oRegex(L"\\s+"); + wsValue = boost::regex_replace(wsValue, oRegex, L" "); +} + +std::wstring EncodeXmlString(const std::wstring& s) +{ + std::wstring sRes = s; + + replace_all(sRes, L"&", L"&"); + replace_all(sRes, L"<", L"<"); + replace_all(sRes, L">", L">"); + replace_all(sRes, L"\"", L"""); + replace_all(sRes, L"\'", L"'"); + replace_all(sRes, L"\n", L" "); + replace_all(sRes, L"\r", L" "); + replace_all(sRes, L"\t", L" "); + + return sRes; +} + +bool GetStatusUsingExternalLocalFiles() +{ + if (NSProcessEnv::IsPresent(NSProcessEnv::Converter::gc_allowPrivateIP)) + return NSProcessEnv::GetBoolValue(NSProcessEnv::Converter::gc_allowPrivateIP); + + return true; +} + +bool CanUseThisPath(const std::wstring& wsPath, const std::wstring& wsSrcPath, const std::wstring& wsCorePath, bool bIsAllowExternalLocalFiles) +{ + if (bIsAllowExternalLocalFiles) + return true; + + if (!wsCorePath.empty()) + { + const std::wstring wsFullPath = NSSystemPath::ShortenPath(NSSystemPath::Combine(wsSrcPath, wsPath)); + return boost::starts_with(wsFullPath, wsCorePath); + } + + if (wsPath.length() >= 3 && L"../" == wsPath.substr(0, 3)) + return false; + + return true; +} + +class CHtmlFile2_Private +{ +public: + XmlUtils::CXmlLiteReader m_oLightReader; // SAX Reader + NSCSS::CCssCalculator m_oStylesCalculator; // Css калькулятор + NSCSS::CDocumentStyle m_oXmlStyle; // Ooxml стиль + + NSCSS::NSProperties::CPage m_oPageData; // Стили страницы + + std::wstring m_sTmp; // Temp папка + std::wstring m_sSrc; // Директория источника + std::wstring m_sDst; // Директория назначения + std::wstring m_sBase; // Полный базовый адрес + std::wstring m_sCore; // Путь до корневого файла (используется для работы с Epub) + +private: + int m_nFootnoteId; // ID сноски + int m_nHyperlinkId; // ID ссылки + int m_nNumberingId; // ID списка + int m_nId; // ID остальные элементы + + NSStringUtils::CStringBuilder m_oStylesXml; // styles.xml + NSStringUtils::CStringBuilder m_oDocXmlRels; // document.xml.rels + NSStringUtils::CStringBuilder m_oNoteXmlRels; // footnotes.xml.rels + NSStringUtils::CStringBuilder m_oDocXml; // document.xml + NSStringUtils::CStringBuilder m_oNoteXml; // footnotes.xml + NSStringUtils::CStringBuilder m_oNumberXml; // numbering.xml + NSStringUtils::CStringBuilder m_oWebSettings; // webSettings.xml + + struct TState + { + bool m_bInP; // открыт? + bool m_bInR; // открыт? + bool m_bInT; // открыт? + bool m_bWasPStyle; // записан? + bool m_bWasSpace; // Был пробел? + bool m_bInHyperlink; // открыт? + + bool m_bBanUpdatePageData; // Запретить обновление данных о странице? + + TState() + : m_bInP(false), m_bInR(false), m_bInT(false), m_bWasPStyle(false), m_bWasSpace(true), m_bInHyperlink(false), m_bBanUpdatePageData(false) + {} + } m_oState; + + std::vector m_arrImages; // Картинки + std::map m_mFootnotes; // Сноски + std::map m_mBookmarks; // Закладки + std::map m_mDivs; // Div элементы +public: + + CHtmlFile2_Private() + : m_nFootnoteId(1), m_nHyperlinkId(1), m_nNumberingId(1), m_nId(1) + { + m_oPageData.SetSize (std::to_wstring(DEFAULT_PAGE_WIDTH) + L"tw " + std::to_wstring(DEFAULT_PAGE_HEIGHT) + L"tw", 0, true); + m_oPageData.SetMargin(L"1440tw 1440tw 1440tw 1440tw", 0, true); + m_oPageData.SetFooter(L"720tw", 0, true); + m_oPageData.SetHeader(L"720tw", 0, true); + } + + ~CHtmlFile2_Private() + { + m_oLightReader .Clear(); + m_oStylesCalculator.Clear(); + m_oXmlStyle .Clear(); + m_oStylesXml .Clear(); + m_oDocXmlRels .Clear(); + m_oNoteXmlRels .Clear(); + m_oDocXml .Clear(); + m_oNoteXml .Clear(); + m_oNumberXml .Clear(); + m_oWebSettings .Clear(); + } + + // Проверяет наличие тэга html + bool isHtml() + { + return (m_oLightReader.ReadNextNode() ? m_oLightReader.GetName() == L"html" : false); + } + + // Создаёт основу docx + void CreateDocxEmpty(CHtmlParams* oParams) + { + // Создаем пустые папки + NSDirectory::CreateDirectory(m_sDst + L"/_rels"); + NSDirectory::CreateDirectory(m_sDst + L"/docProps"); + NSDirectory::CreateDirectory(m_sDst + L"/word"); + NSDirectory::CreateDirectory(m_sDst + L"/word/_rels"); + NSDirectory::CreateDirectory(m_sDst + L"/word/media"); + NSDirectory::CreateDirectory(m_sDst + L"/word/theme"); + + // theme1.xml + std::wstring sTheme = L""; + NSFile::CFileBinary oThemeWriter; + if (oThemeWriter.CreateFileW(m_sDst + L"/word/theme/theme1.xml")) + { + oThemeWriter.WriteStringUTF8(sTheme); + oThemeWriter.CloseFile(); + } + + // app.xml + std::wstring sApplication = NSSystemUtils::GetEnvVariable(NSSystemUtils::gc_EnvApplicationName); + if (sApplication.empty()) + sApplication = NSSystemUtils::gc_EnvApplicationNameDefault; +#if defined(INTVER) + std::string sVersion = VALUE2STR(INTVER); +#endif + std::wstring sApp = L""; + sApp += sApplication + L"/" + UTF8_TO_U(sVersion); + sApp += L"0falsefalsefalsefalse"; + NSFile::CFileBinary oAppWriter; + if (oAppWriter.CreateFileW(m_sDst + L"/docProps/app.xml")) + { + oAppWriter.WriteStringUTF8(sApp); + oAppWriter.CloseFile(); + } + + // .rels + std::wstring sRels = L""; + NSFile::CFileBinary oRelsWriter; + if (oRelsWriter.CreateFileW(m_sDst + L"/_rels/.rels")) + { + oRelsWriter.WriteStringUTF8(sRels); + oRelsWriter.CloseFile(); + } + + // [Content_Types].xml + std::wstring sContent = L""; + NSFile::CFileBinary oContentWriter; + if (oContentWriter.CreateFileW(m_sDst + L"/[Content_Types].xml")) + { + oContentWriter.WriteStringUTF8(sContent); + oContentWriter.CloseFile(); + } + + // fontTable.xml + std::wstring sFontTable = L""; + NSFile::CFileBinary oFontTableWriter; + if (oFontTableWriter.CreateFileW(m_sDst + L"/word/fontTable.xml")) + { + oFontTableWriter.WriteStringUTF8(sFontTable); + oFontTableWriter.CloseFile(); + } + + // settings.xml + std::wstring sSettings = L""; + NSFile::CFileBinary oSettingsWriter; + if (oSettingsWriter.CreateFileW(m_sDst + L"/word/settings.xml")) + { + oSettingsWriter.WriteStringUTF8(sSettings); + oSettingsWriter.CloseFile(); + } + + // numbering.xml + // Маркированный список + m_oNumberXml += L""; + + std::wstring wsCurrentLanguage; + + // core.xml + std::wstring sCore = L""; + if(oParams) + { + if(!oParams->m_sBookTitle.empty()) + { + sCore += L""; + sCore += EncodeXmlString(oParams->m_sBookTitle); + sCore += L""; + } + if(!oParams->m_sAuthors.empty()) + { + sCore += L""; + sCore += EncodeXmlString(oParams->m_sAuthors); + sCore += L""; + } + if(!oParams->m_sGenres.empty()) + { + sCore += L""; + sCore += EncodeXmlString(oParams->m_sGenres); + sCore += L""; + } + if(!oParams->m_sDate.empty()) + { + sCore += L""; + sCore += EncodeXmlString(oParams->m_sDate); + sCore += L""; + } + if(!oParams->m_sDescription.empty()) + { + sCore += L""; + sCore += EncodeXmlString(oParams->m_sDescription); + sCore += L""; + } + if (!oParams->m_sLanguage.empty()) + { + wsCurrentLanguage = IndentifyLanguage(oParams->m_sLanguage); + + sCore += L""; + sCore += wsCurrentLanguage; + sCore += L""; + } + } + sCore += L""; + NSFile::CFileBinary oCoreWriter; + if (oCoreWriter.CreateFileW(m_sDst + L"/docProps/core.xml")) + { + oCoreWriter.WriteStringUTF8(sCore); + oCoreWriter.CloseFile(); + } + + // Начала файлов + m_oDocXmlRels += L""; + m_oDocXmlRels += L""; + m_oDocXmlRels += L""; + m_oDocXmlRels += L""; + m_oDocXmlRels += L""; + m_oDocXmlRels += L""; + m_oDocXmlRels += L""; + m_oDocXmlRels += L""; + m_oNoteXmlRels += L""; + m_oDocXml += L""; + m_oNoteXml += L""; + m_oNoteXml += L""; + m_oStylesXml += L""; + m_oWebSettings += L""; + + m_nId += 7; + + // docDefaults по умолчанию + if(oParams && !oParams->m_sdocDefaults.empty()) + m_oStylesXml += oParams->m_sdocDefaults; + else + { + m_oStylesXml += L""; + m_oStylesXml += L""; + m_oStylesXml += L""; + m_oStylesXml += L""; + m_oStylesXml += L""; + +// m_oStylesXml += L""; + } + + // normal по умолчанию + if(oParams && !oParams->m_sNormal.empty()) + m_oStylesXml += oParams->m_sNormal; + else + { + m_oStylesXml += L""; + m_oStylesXml += L""; + m_oStylesXml += L""; + } + + // Маркированный список + m_oStylesXml += L""; + // Ссылки + m_oStylesXml += L""; + // Таблицы +// m_oStylesXml += L""; + // Сноски + m_oStylesXml += L""; + // Web стиль по-умолчанию + m_oStylesXml += L""; + } + + // Читает файл + void readSrc() + { + // Читаем html + m_oLightReader.ReadNextNode(); + + int nDeath = m_oLightReader.GetDepth(); + while(m_oLightReader.ReadNextSiblingNode(nDeath)) + { + std::wstring sName = m_oLightReader.GetName(); + if(sName == L"head") + readHead(); + else if(sName == L"body") + readBody(); + } + } + + // Дописывает концы docx + void write() + { + m_oDocXmlRels.WriteString(L""); + NSFile::CFileBinary oRelsWriter; + if (oRelsWriter.CreateFileW(m_sDst + L"/word/_rels/document.xml.rels")) + { + oRelsWriter.WriteStringUTF8(m_oDocXmlRels.GetData()); + oRelsWriter.CloseFile(); + } + + for (const std::pair& oFootnote : m_mFootnotes) + { + m_oNoteXml.WriteString(L""); + m_oNoteXml.WriteEncodeXmlString(oFootnote.first); + m_oNoteXml.WriteString(L""); + } + + m_oNoteXmlRels.WriteString(L""); + if (oRelsWriter.CreateFileW(m_sDst + L"/word/_rels/footnotes.xml.rels")) + { + oRelsWriter.WriteStringUTF8(m_oNoteXmlRels.GetData()); + oRelsWriter.CloseFile(); + } + + if (m_oState.m_bInP) + m_oDocXml.WriteString(L""); + + m_oDocXml.WriteString(L""); + m_oDocXml.WriteString(L""); + m_oDocXml.WriteString(L""); + + NSFile::CFileBinary oDocumentWriter; + if (oDocumentWriter.CreateFileW(m_sDst + L"/word/document.xml")) + { + oDocumentWriter.WriteStringUTF8(m_oDocXml.GetData()); + oDocumentWriter.CloseFile(); + } + + m_oNoteXml.WriteString(L""); + NSFile::CFileBinary oFootnotesWriter; + if (oFootnotesWriter.CreateFileW(m_sDst + L"/word/footnotes.xml")) + { + oFootnotesWriter.WriteStringUTF8(m_oNoteXml.GetData()); + oFootnotesWriter.CloseFile(); + } + + // styles.xml + m_oStylesXml.WriteString(L""); + NSFile::CFileBinary oStylesWriter; + if (oStylesWriter.CreateFileW(m_sDst + L"/word/styles.xml")) + { + oStylesWriter.WriteStringUTF8(m_oStylesXml.GetData()); + oStylesWriter.CloseFile(); + } + + // numbering.xml + // Маркированный список + m_oNumberXml.WriteString(L""); + // Нумерованный список + for(int i = 1; i < m_nNumberingId; i++) + { + m_oNumberXml.WriteString(L""); + } + m_oNumberXml.WriteString(L""); + NSFile::CFileBinary oNumberingWriter; + if (oNumberingWriter.CreateFileW(m_sDst + L"/word/numbering.xml")) + { + oNumberingWriter.WriteStringUTF8(m_oNumberXml.GetData()); + oNumberingWriter.CloseFile(); + } + + // webSettings.xml + if (!m_mDivs.empty()) + m_oWebSettings.WriteString(L""); + + m_oWebSettings.WriteString(L""); + NSFile::CFileBinary oWebSettingsWriter; + if (oWebSettingsWriter.CreateFileW(m_sDst + L"/word/webSettings.xml")) + { + oWebSettingsWriter.WriteStringUTF8(m_oWebSettings.GetData()); + oWebSettingsWriter.CloseFile(); + } + } + + // Конвертирует html в xhtml + bool htmlXhtml(const std::wstring& sSrc) + { + BYTE* pData; + DWORD nLength; + if (!NSFile::CFileBinary::ReadAllBytes(sSrc, &pData, nLength)) + return false; + + std::string sFileContent = XmlUtils::GetUtf8FromFileContent(pData, nLength); + + bool bNeedConvert = true; + if (nLength > 4) + { + if (pData[0] == 0xFF && pData[1] == 0xFE && !(pData[2] == 0x00 && pData[3] == 0x00)) + bNeedConvert = false; + if (pData[0] == 0xFE && pData[1] == 0xFF) + bNeedConvert = false; + + if (pData[0] == 0xFF && pData[1] == 0xFE && pData[2] == 0x00 && pData[3] == 0x00) + bNeedConvert = false; + if (pData[0] == 0 && pData[1] == 0 && pData[2] == 0xFE && pData[3] == 0xFF) + bNeedConvert = false; + } + + RELEASEARRAYOBJECTS(pData); + + size_t nFind = sFileContent.find("version=\""); + if(nFind != std::string::npos) + { + nFind += 9; + size_t nFindEnd = sFileContent.find("\"", nFind); + if(nFindEnd != std::string::npos) + sFileContent.replace(nFind, nFindEnd - nFind, "1.0"); + } + + std::wstring sRes = htmlToXhtml(sFileContent, bNeedConvert); + + #ifdef SAVE_NORMALIZED_HTML + #if 1 == SAVE_NORMALIZED_HTML + NSFile::CFileBinary oWriter; + if (oWriter.CreateFileW(m_sTmp + L"/res.html")) + { + oWriter.WriteStringUTF8(sRes); + oWriter.CloseFile(); + } + #endif + #endif + + return m_oLightReader.FromString(sRes); + } + + // Конвертирует mht в xhtml + bool mhtXhtml(const std::wstring& sSrc) + { + NSFile::CFileBinary file; + if (!file.OpenFile(sSrc)) + return false; + + unsigned char* buffer = new unsigned char[4096]; + if (!buffer) + { + file.CloseFile(); + return false; + } + + DWORD dwReadBytes = 0; + file.ReadFile(buffer, 4096, dwReadBytes); + file.CloseFile(); + std::string xml_string = XmlUtils::GetUtf8FromFileContent(buffer, dwReadBytes); + + const std::string sContentType = NSStringFinder::FindPropety(xml_string, "content-type", ":", ";"); + bool bRes = false; + + if(NSStringFinder::Equals(sContentType, "multipart/related")) + { + BYTE* pData; + DWORD nLength; + if (!NSFile::CFileBinary::ReadAllBytes(sSrc, &pData, nLength)) + return false; + + std::string sFileContent = XmlUtils::GetUtf8FromFileContent(pData, nLength); + RELEASEARRAYOBJECTS(pData); + std::wstring sRes = mhtToXhtml(sFileContent); + /* + NSFile::CFileBinary oWriter; + if (oWriter.CreateFileW(m_sTmp + L"/res.html")) { - sCore += L""; - sCore += EncodeXmlString(oParams->m_sDescription); - sCore += L""; + oWriter.WriteStringUTF8(sRes); + oWriter.CloseFile(); + } + */ + bRes = m_oLightReader.FromString(sRes); + } + else + bRes = htmlXhtml(sSrc); + + RELEASEARRAYOBJECTS(buffer); + return bRes; + } + + // Читает стили + void readStyle() + { + if(m_oLightReader.IsEmptyNode()) + return; + + int nDeath = m_oLightReader.GetDepth(); + while(m_oLightReader.ReadNextSiblingNode(nDeath)) + { + std::wstring sName = m_oLightReader.GetName(); + + if(sName == L"body") + readStyle2(); + else + { + // Стиль по ссылке + if(sName == L"link") + { + while(m_oLightReader.MoveToNextAttribute()) + { + if(m_oLightReader.GetName() != L"href") + continue; + std::wstring sRef = m_oLightReader.GetText(); + if(NSFile::GetFileExtention(sRef) != L"css") + continue; + std::wstring sFName = NSFile::GetFileName(sRef); + // Стиль в сети + if(sRef.substr(0, 4) == L"http") + { + sFName = m_sTmp + L'/' + sFName; + NSNetwork::NSFileTransport::CFileDownloader oDownloadStyle(sRef, false); + oDownloadStyle.SetFilePath(sFName); + if(oDownloadStyle.DownloadSync()) + { + m_oStylesCalculator.AddStylesFromFile(sFName); + NSFile::CFileBinary::Remove(sFName); + } + } + else + { + m_oStylesCalculator.AddStylesFromFile(m_sSrc + L'/' + sFName); + m_oStylesCalculator.AddStylesFromFile(m_sSrc + L'/' + sRef); + } + } + m_oLightReader.MoveToElement(); + } + // тэг style содержит стили для styles.xml + else if(sName == L"style") + m_oStylesCalculator.AddStyles(m_oLightReader.GetText2()); + else + readStyle(); + } + } + } + + void readStyle2() + { + std::wstring sName = m_oLightReader.GetName(); + // Стиль по ссылке + if(sName == L"link") + { + while(m_oLightReader.MoveToNextAttribute()) + { + if(m_oLightReader.GetName() != L"href") + continue; + std::wstring sRef = m_oLightReader.GetText(); + if(NSFile::GetFileExtention(sRef) != L"css") + continue; + std::wstring sFName = NSFile::GetFileName(sRef); + // Стиль в сети + if(sRef.substr(0, 4) == L"http") + { + sFName = m_sTmp + L'/' + sFName; + NSNetwork::NSFileTransport::CFileDownloader oDownloadStyle(sRef, false); + oDownloadStyle.SetFilePath(sFName); + if(oDownloadStyle.DownloadSync()) + { + m_oStylesCalculator.AddStylesFromFile(sFName); + NSFile::CFileBinary::Remove(sFName); + } + } + else + { + m_oStylesCalculator.AddStylesFromFile(m_sSrc + L'/' + sFName); + m_oStylesCalculator.AddStylesFromFile(m_sSrc + L'/' + sRef); + } + } + m_oLightReader.MoveToElement(); + } + // тэг style содержит стили для styles.xml + else if(sName == L"style") + m_oStylesCalculator.AddStyles(m_oLightReader.GetText2()); + + int nDeath = m_oLightReader.GetDepth(); + while(m_oLightReader.ReadNextSiblingNode(nDeath)) + { + if(!m_oLightReader.IsEmptyNode()) + readStyle2(); + } + } + + void PageBreakBefore() + { + if (!m_oState.m_bInP) + m_oDocXml.WriteString(L""); + + m_oDocXml.WriteString(L""); + + if (!m_oState.m_bInP) + m_oDocXml.WriteString(L""); + } + +private: + bool NodeBelongToTable(const std::wstring& wsNodeName) const + { + return L"table" == wsNodeName || L"tbody" == wsNodeName || L"th" == wsNodeName || L"td" == wsNodeName || + L"tr" == wsNodeName || L"thead" == wsNodeName || L"tfoot" == wsNodeName; + } + + std::wstring GetArgumentValue(const std::wstring& wsArgumentName, const std::wstring& wsDefaultValue = L"") + { + if (!m_oLightReader.MoveToFirstAttribute()) + return wsDefaultValue; + + std::wstring wsValue{wsDefaultValue}; + + do + { + if (wsArgumentName == m_oLightReader.GetName()) + { + wsValue = m_oLightReader.GetText(); + break; + } + } while (m_oLightReader.MoveToNextAttribute()); + + m_oLightReader.MoveToElement(); + return wsValue; + } + + // Так как CSS калькулятор не знает для какой ноды производится расчет стиля + // и не знает, что некоторые стили предназначены только определенной ноде, + // то проще пока обрабатывать это заранее + // ! Используется для стилей, заданных через аргументы ! + bool CheckArgumentMath(const std::wstring& wsNodeName, const std::wstring& wsStyleName) const + { + if (L"border" == wsStyleName && L"table" != wsNodeName) + return false; + + return true; + } + + bool OpenP(NSStringUtils::CStringBuilder* pXml) + { + if (m_oState.m_bInP) + return false; + + pXml->WriteString(L""); + m_oState.m_bInP = true; + m_oState.m_bWasPStyle = false; + + return true; + } + + bool OpenR(NSStringUtils::CStringBuilder* pXml) + { + if (m_oState.m_bInR) + return false; + + pXml->WriteString(L""); + m_oState.m_bInR = true; + return true; + } + + void CloseR(NSStringUtils::CStringBuilder* pXml) + { + if (!m_oState.m_bInR) + return; + + pXml->WriteString(L""); + m_oState.m_bInR = false; + } + + bool OpenT(NSStringUtils::CStringBuilder* pXml) + { + if (m_oState.m_bInT) + return false; + + pXml->WriteString(L""); + m_oState.m_bInT = true; + return true; + } + + void CloseT(NSStringUtils::CStringBuilder* pXml) + { + if (!m_oState.m_bInT) + return; + + pXml->WriteString(L""); + m_oState.m_bInT = false; + } + + void CloseP(NSStringUtils::CStringBuilder* pXml, const std::vector& arSelectors) + { + m_oState.m_bWasSpace = true; + + if (!m_oState.m_bInP) + return; + + CloseT(pXml); + CloseR(pXml); + + if (m_oState.m_bInHyperlink) + { + if (arSelectors.rend() != std::find_if(arSelectors.rbegin(), arSelectors.rend(), [](const NSCSS::CNode& oNode) { return L"a" == oNode.m_wsName; })) + { + pXml->WriteString(L""); + m_oState.m_bInHyperlink = false; } } - sCore += L""; - NSFile::CFileBinary oCoreWriter; - if (oCoreWriter.CreateFileW(m_sDst + L"/docProps/core.xml")) + + pXml->WriteString(L""); + m_oState.m_bInP = false; + } + + void WriteSpace(NSStringUtils::CStringBuilder* pXml) + { + if (NULL == pXml) + return; + + OpenR(pXml); + pXml->WriteString(L" "); + CloseR(pXml); + m_oState.m_bWasSpace = true; + } + + void WriteBookmark(NSStringUtils::CStringBuilder* pXml, const std::wstring& wsId) + { + if (NULL == pXml) + return; + + const std::wstring sCrossId = std::to_wstring(m_mBookmarks.size() + 1); + std::wstring sName; + + if (m_mBookmarks.end() != m_mBookmarks.find(wsId)) + sName = wsId + L"_" + std::to_wstring(++m_mBookmarks[wsId]); + else { - oCoreWriter.WriteStringUTF8(sCore); - oCoreWriter.CloseFile(); + sName = wsId; + m_mBookmarks.insert({wsId, 1}); } - // Начала файлов - m_oDocXmlRels += L""; - m_oDocXmlRels += L""; - m_oDocXmlRels += L""; - m_oDocXmlRels += L""; - m_oDocXmlRels += L""; - m_oDocXmlRels += L""; - m_oDocXmlRels += L""; - m_oDocXmlRels += L""; - m_oNoteXmlRels += L""; - m_oDocXml += L""; - m_oNoteXml += L""; - m_oNoteXml += L""; - m_oStylesXml += L""; + pXml->WriteString(L"WriteString(sCrossId); + pXml->WriteString(L"\" w:name=\""); + pXml->WriteEncodeXmlString(sName); + pXml->WriteString(L"\"/>WriteString(sCrossId); + pXml->WriteString(L"\"/>"); + } - // docDefaults по умолчанию - if(oParams && !oParams->m_sdocDefaults.empty()) - m_oStylesXml += oParams->m_sdocDefaults; - else - m_oStylesXml += L""; + std::wstring WriteDiv(NSStringUtils::CStringBuilder* pXml, std::vector& sSelectors, CTextSettings& oTS) + { + if (NULL == pXml || sSelectors.empty()) + return std::wstring(); - // normal по умолчанию - if(oParams && !oParams->m_sNormal.empty()) - m_oStylesXml += oParams->m_sNormal; - else - m_oStylesXml += L""; + const std::wstring wsKeyWord{sSelectors.back().m_wsName}; - // Маркированный список - m_oStylesXml += L""; - // Ссылки - m_oStylesXml += L""; - // Таблицы - m_oStylesXml += L""; - // Сноски - m_oStylesXml += L""; + std::map::const_iterator itFound = m_mDivs.find(wsKeyWord); + + if (m_mDivs.end() != itFound) + return std::to_wstring(itFound->second); + + const std::wstring wsId{std::to_wstring(m_mDivs.size() + 1)}; + + if (m_mDivs.empty()) + pXml->WriteString(L""); + + NSCSS::CCompiledStyle oStyle; + m_oStylesCalculator.GetCompiledStyle(oStyle, sSelectors); + + const bool bInTable = ElementInTable(sSelectors); + + INT nMarLeft = (!bInTable) ? 720 : 0; + INT nMarRight = (!bInTable) ? 720 : 0; + INT nMarTop = (!bInTable) ? 100 : 0; + INT nMarBottom = (!bInTable) ? 100 : 0; + + if (!oStyle.m_oMargin.GetLeft().Empty() && !oStyle.m_oMargin.GetLeft().Zero()) + nMarLeft = oStyle.m_oMargin.GetLeft().ToInt(NSCSS::Twips, m_oPageData.GetWidth().ToInt(NSCSS::Twips)); + + if (!oStyle.m_oMargin.GetRight().Empty() && !oStyle.m_oMargin.GetRight().Zero()) + nMarRight = oStyle.m_oMargin.GetRight().ToInt(NSCSS::Twips, m_oPageData.GetWidth().ToInt(NSCSS::Twips)); + + if (!oStyle.m_oMargin.GetTop().Empty() && !oStyle.m_oMargin.GetTop().Zero()) + nMarTop = oStyle.m_oMargin.GetTop().ToInt(NSCSS::Twips, m_oPageData.GetHeight().ToInt(NSCSS::Twips)); + + if (!oStyle.m_oMargin.GetBottom().Empty() && !oStyle.m_oMargin.GetBottom().Zero()) + nMarBottom = oStyle.m_oMargin.GetBottom().ToInt(NSCSS::Twips, m_oPageData.GetHeight().ToInt(NSCSS::Twips)); + + if (L"blockquote" == wsKeyWord) + { + sSelectors.back().m_mAttributes.insert({L"margin", L"0px"}); + + pXml->WriteString(L""); + pXml->WriteString(L""); + pXml->WriteString(L""); + pXml->WriteString(L""); + pXml->WriteString(L""); + pXml->WriteString(L""); + pXml->WriteString(L""); + pXml->WriteString(L""); + pXml->WriteString(L""); + pXml->WriteString(L""); + pXml->WriteString(L""); + pXml->WriteString(L""); + pXml->WriteString(L""); + } + + m_mDivs.insert(std::make_pair(wsKeyWord, m_mDivs.size() + 1)); + + return wsId; } - // Читает файл - void readSrc() + std::wstring GetSubClass(NSStringUtils::CStringBuilder* oXml, std::vector& sSelectors) { - // Читаем html - m_oLightReader.ReadNextNode(); + NSCSS::CNode oNode; + std::wstring sNote; + oNode.m_wsName = m_oLightReader.GetName(); + // Стиль по атрибуту + while(m_oLightReader.MoveToNextAttribute()) + { + std::wstring sName = m_oLightReader.GetName(); + if(sName == L"class") + oNode.m_wsClass = EncodeXmlString(m_oLightReader.GetText()); + else if(sName == L"id") + { + oNode.m_wsId = EncodeXmlString(m_oLightReader.GetText()); + WriteBookmark(oXml, oNode.m_wsId); + } + else if(sName == L"style") + oNode.m_wsStyle += m_oLightReader.GetText(); + else if(sName == L"title") + sNote = m_oLightReader.GetText(); + else + { + if (CheckArgumentMath(oNode.m_wsName, sName)) + oNode.m_mAttributes[sName] = m_oLightReader.GetText(); + } + } + m_oLightReader.MoveToElement(); + sSelectors.push_back(oNode); + return sNote; + } + + std::wstring GetStyle(const NSCSS::CCompiledStyle& oStyle, bool bP) + { +// NSCSS::CCompiledStyle oStyle = m_oStylesCalculator.GetCompiledStyle(sSelectors); + if ((bP && !m_oXmlStyle.WritePStyle(oStyle)) || (!bP && !m_oXmlStyle.WriteRStyle(oStyle))) + return L""; + + m_oStylesXml.WriteString(m_oXmlStyle.GetStyle()); + return m_oXmlStyle.GetIdAndClear(); + } + void readHead() + { + if(m_oLightReader.IsEmptyNode()) + return; int nDeath = m_oLightReader.GetDepth(); - while(m_oLightReader.ReadNextSiblingNode(nDeath)) + while (m_oLightReader.ReadNextSiblingNode(nDeath)) { - std::wstring sName = m_oLightReader.GetName(); - if(sName == L"head") - readHead(); - else if(sName == L"body") - readBody(); + const std::wstring wsName = m_oLightReader.GetName(); + // Базовый адрес + if (L"base" == wsName) + m_sBase = GetArgumentValue(L"href"); } + + m_oLightReader.MoveToElement(); } - // Дописывает концы docx - void write() + void readBody() { - m_oDocXmlRels.WriteString(L""); - NSFile::CFileBinary oRelsWriter; - if (oRelsWriter.CreateFileW(m_sDst + L"/word/_rels/document.xml.rels")) + std::vector sSelectors; + + sSelectors.push_back(NSCSS::CNode(L"html", L"", L"")); + + GetSubClass(&m_oDocXml, sSelectors); + /* + std::wstring sCrossId = std::to_wstring(m_nCrossId++); + m_oDocXml.WriteString(L""); + */ + + if (!sSelectors.back().m_mAttributes.empty()) { - oRelsWriter.WriteStringUTF8(m_oDocXmlRels.GetData()); - oRelsWriter.CloseFile(); + std::map::iterator itFound = sSelectors.back().m_mAttributes.find(L"bgcolor"); + + if (sSelectors.back().m_mAttributes.end() != itFound) + { + NSCSS::NSProperties::CColor oColor; + oColor.SetValue(itFound->second); + + if (!oColor.Empty() && !oColor.None()) + { + const std::wstring wsHEXColor{oColor.ToHEX()}; + + if (!wsHEXColor.empty()) + m_oDocXml.WriteString(L""); + + sSelectors.back().m_mAttributes.erase(itFound); + } + } } + m_oLightReader.MoveToElement(); - m_oNoteXmlRels.WriteString(L""); - if (oRelsWriter.CreateFileW(m_sDst + L"/word/_rels/footnotes.xml.rels")) + CTextSettings oTS; + readStream(&m_oDocXml, sSelectors, oTS); + } + + bool ReadText(NSStringUtils::CStringBuilder* pXml, const std::vector& arSelectors, CTextSettings& oTS) + { + if (NULL == pXml) + return false; + + std::wstring sText = m_oLightReader.GetText(); + + if (sText.end() == std::find_if_not(sText.begin(), sText.end(), [](wchar_t wchChar){ return iswspace(wchChar);})) + return false; + + if(oTS.bBdo) + std::reverse(sText.begin(), sText.end()); + + const bool bInT = m_oState.m_bInT; + + if (oTS.bPre) { - oRelsWriter.WriteStringUTF8(m_oNoteXmlRels.GetData()); - oRelsWriter.CloseFile(); + CloseT(pXml); + CloseR(pXml); } - if (m_bInP) - m_oDocXml.WriteString(L""); - m_oDocXml.WriteString(L""); - NSFile::CFileBinary oDocumentWriter; - if (oDocumentWriter.CreateFileW(m_sDst + L"/word/document.xml")) + if (oTS.bAddSpaces && m_oState.m_bInP && !m_oState.m_bInR && !iswspace(sText.front()) && !m_oState.m_bWasSpace && CTextSettings::Normal == oTS.eTextMode) + WriteSpace(pXml); + + OpenP(pXml); + + NSStringUtils::CStringBuilder oPPr; + + std::wstring sPStyle = wrP(&oPPr, arSelectors, oTS); + + WriteToStringBuilder(oPPr, *pXml); + + NSStringUtils::CStringBuilder oRPr; + std::wstring sRStyle; + + if (OpenR(pXml)) { - oDocumentWriter.WriteStringUTF8(m_oDocXml.GetData()); - oDocumentWriter.CloseFile(); + sRStyle = wrRPr(&oRPr, arSelectors, oTS); + + WriteToStringBuilder(oRPr, *pXml); + + if (oTS.bQ) + pXml->WriteString(L"""); } - m_oNoteXml.WriteString(L""); - NSFile::CFileBinary oFootnotesWriter; - if (oFootnotesWriter.CreateFileW(m_sDst + L"/word/footnotes.xml")) + if (oTS.bQ) + pXml->WriteString(L"""); + + if(oTS.bPre) { - oFootnotesWriter.WriteStringUTF8(m_oNoteXml.GetData()); - oFootnotesWriter.CloseFile(); + if (L'\n' == sText.front() || L'\r' == sText.front()) + sText.erase(0, 1); + + size_t nAfter = sText.find_first_of(L"\n\r\t"); + while(nAfter != std::wstring::npos) + { + if (L'\t' == sText[0]) + { + pXml->WriteString(L""); + sText.erase(0, 1); + + if (0 == nAfter) + { + nAfter = sText.find_first_of(L"\n\r\t"); + continue; + } + + nAfter--; + } + + OpenT(pXml); + pXml->WriteEncodeXmlString(sText.c_str(), nAfter); + CloseT(pXml); + CloseR(pXml); + + if (L'\t' == sText[nAfter]) + { + sText.erase(0, nAfter); + nAfter = 1; + } + else + { + CloseP(pXml, arSelectors); + OpenP(pXml); + WriteToStringBuilder(oPPr, *pXml); + sText.erase(0, nAfter + 1); + nAfter = 0; + } + OpenR(pXml); + WriteToStringBuilder(oRPr, *pXml); + nAfter = sText.find_first_of(L"\n\r\t", nAfter); + } + + if (sText.empty()) + return true; } + else + ReplaceSpaces(sText); - // styles.xml - m_oStylesXml.WriteString(L""); - NSFile::CFileBinary oStylesWriter; - if (oStylesWriter.CreateFileW(m_sDst + L"/word/styles.xml")) + if (!sText.empty() && L'\t' == sText[0]) { - oStylesWriter.WriteStringUTF8(m_oStylesXml.GetData()); - oStylesWriter.CloseFile(); + pXml->WriteString(L""); + sText.erase(0, 1); } - // numbering.xml - // Маркированный список - m_oNumberXml.WriteString(L""); - // Нумерованный список - for(int i = 1; i < m_nNumberingId; i++) + if (!oTS.bPre && !sText.empty() && std::iswspace(sText.front()) && m_oState.m_bWasSpace) + sText.erase(0, 1); + + if (!sText.empty()) { - m_oNumberXml.WriteString(L""); + OpenT(pXml); + + if (oTS.bMergeText && !m_oState.m_bWasSpace && bInT && !oTS.bPre) + pXml->WriteEncodeXmlString(L" "); + + m_oState.m_bWasSpace = std::iswspace(sText.back()); + + pXml->WriteEncodeXmlString(sText); } - m_oNumberXml.WriteString(L""); - NSFile::CFileBinary oNumberingWriter; - if (oNumberingWriter.CreateFileW(m_sDst + L"/word/numbering.xml")) + + if (oTS.bQ) + pXml->WriteString(L"""); + + if (!oTS.bMergeText) + { + CloseT(pXml); + CloseR(pXml); + } + + return true; + } + + bool ReadAbbr(NSStringUtils::CStringBuilder* pXml, std::vector& arSelectors, CTextSettings& oTS, std::wstring& wsNote) + { + if (NULL == pXml || wsNote.empty()) + return false; + + wrP(pXml, arSelectors, oTS); + const std::wstring wsName{L"Bookmark" + std::to_wstring(m_mBookmarks.size() + 1)}; + m_mBookmarks.insert(std::make_pair(wsName, m_mBookmarks.size() + 1)); + pXml->WriteString(L"HYPERLINK \\l \"" + wsName + L"\" \\o \""); + pXml->WriteEncodeXmlString(wsNote); + pXml->WriteString(L"\""); + pXml->WriteString(L""); + const bool bResult = readStream(pXml, arSelectors, oTS); + pXml->WriteString(L""); + wsNote.clear(); + + return bResult; + } + + bool ReadBold(NSStringUtils::CStringBuilder* pXml, std::vector& arSelectors, CTextSettings& oTS) + { + if (NULL == pXml) + return false; + + CTextSettings oTSR(oTS); + oTSR.oAdditionalStyle.m_oFont.SetWeight(L"bold", UINT_MAX, true); + + return readStream(pXml, arSelectors, oTSR); + } + + bool ReadBdo(NSStringUtils::CStringBuilder* pXml, std::vector& arSelectors, CTextSettings& oTS) + { + if (NULL == pXml) + return false; + + const std::wstring sDir{GetArgumentValue(L"dir")}; + + CTextSettings oTSBdo(oTS); + oTSBdo.bBdo = (sDir == L"rtl"); + + return readStream(pXml, arSelectors, oTSBdo); + } + + bool ReadBdi(NSStringUtils::CStringBuilder* pXml, std::vector& arSelectors, CTextSettings& oTS) + { + if (NULL == pXml) + return false; + + CTextSettings oTSBdo(oTS); + oTSBdo.bBdo = false; + return readStream(pXml, arSelectors, oTSBdo); + } + + bool ReadBr(NSStringUtils::CStringBuilder* pXml, std::vector& arSelectors, CTextSettings& oTS) + { + if (NULL == pXml) + return false; + + if (m_oState.m_bInP) { - oNumberingWriter.WriteStringUTF8(m_oNumberXml.GetData()); - oNumberingWriter.CloseFile(); + OpenR(pXml); + NSCSS::CCompiledStyle oStyle = m_oStylesCalculator.GetCompiledStyle(arSelectors); + if(oStyle.m_oText.GetAlign() == L"both") + pXml->WriteString(L""); + pXml->WriteString(L""); + CloseR(pXml); } + else + WriteEmptyParagraph(pXml, false, m_oState.m_bInP); + + m_oState.m_bWasSpace = true; + + return true; } - // Конвертирует html в xhtml - bool htmlXhtml(const std::wstring& sSrc) + bool ReadCenter(NSStringUtils::CStringBuilder* pXml, std::vector& arSelectors, CTextSettings& oTS) { - BYTE* pData; - DWORD nLength; - if (!NSFile::CFileBinary::ReadAllBytes(sSrc, &pData, nLength)) + if (NULL == pXml) return false; - std::string sFileContent = XmlUtils::GetUtf8FromFileContent(pData, nLength); - bool bNeedConvert = true; - if (nLength > 4) - { - if (pData[0] == 0xFF && pData[1] == 0xFE && !(pData[2] == 0x00 && pData[3] == 0x00)) - bNeedConvert = false; - if (pData[0] == 0xFE && pData[1] == 0xFF) - bNeedConvert = false; + CTextSettings oTSP(oTS); + oTSP.oAdditionalStyle.m_oText.SetAlign(L"center", UINT_MAX, true); - if (pData[0] == 0xFF && pData[1] == 0xFE && pData[2] == 0x00 && pData[3] == 0x00) - bNeedConvert = false; - if (pData[0] == 0 && pData[1] == 0 && pData[2] == 0xFE && pData[3] == 0xFF) - bNeedConvert = false; - } - RELEASEARRAYOBJECTS(pData); + return readStream(pXml, arSelectors, oTSP); + } - size_t nFind = sFileContent.find("version=\""); - if(nFind != std::string::npos) - { - nFind += 9; - size_t nFindEnd = sFileContent.find("\"", nFind); - if(nFindEnd != std::string::npos) - sFileContent.replace(nFind, nFindEnd - nFind, "1.0"); - } - std::wstring sRes = htmlToXhtml(sFileContent, bNeedConvert); - /* - NSFile::CFileBinary oWriter; - if (oWriter.CreateFileW(m_sTmp + L"/res.html")) - { - oWriter.WriteStringUTF8(sRes); - oWriter.CloseFile(); - } - */ - return m_oLightReader.FromString(sRes); + bool ReadItalic(NSStringUtils::CStringBuilder* pXml, std::vector& arSelectors, CTextSettings& oTS) + { + if (NULL == pXml) + return false; + + CTextSettings oTSR(oTS); + oTSR.oAdditionalStyle.m_oFont.SetStyle(L"italic", UINT_MAX, true); + + return readStream(pXml, arSelectors, oTSR); } - // Конвертирует mht в xhtml - bool mhtXhtml(const std::wstring& sSrc) + bool ReadCode(NSStringUtils::CStringBuilder* pXml, std::vector& arSelectors, CTextSettings& oTS) { - NSFile::CFileBinary file; - if (!file.OpenFile(sSrc)) + if (NULL == pXml || arSelectors.empty()) return false; - unsigned char* buffer = new unsigned char[4096]; - if (!buffer) - { - file.CloseFile(); + CTextSettings oTSR(oTS); + oTSR.oAdditionalStyle.m_oFont.SetFamily(L"Courier New", UINT_MAX, true); + oTSR.oAdditionalStyle.m_oFont.SetSize(20, UINT_MAX, true); + + return readStream(pXml, arSelectors, oTSR); + } + + bool ReadKbd(NSStringUtils::CStringBuilder* pXml, std::vector& arSelectors, CTextSettings& oTS) + { + if (NULL == pXml) return false; - } - DWORD dwReadBytes = 0; - file.ReadFile(buffer, 4096, dwReadBytes); - file.CloseFile(); - std::string xml_string = XmlUtils::GetUtf8FromFileContent(buffer, dwReadBytes); + CTextSettings oTSR(oTS); + oTSR.oAdditionalStyle.m_oFont.SetFamily(L"Courier New", UINT_MAX, true); + oTSR.oAdditionalStyle.m_oFont.SetSize(20, UINT_MAX, true); + oTSR.oAdditionalStyle.m_oFont.SetWeight(L"bold", UINT_MAX, true); - bool bRes = false; - if (std::string::npos != xml_string.find("Content-Type: multipart/related")) - { - BYTE* pData; - DWORD nLength; - if (!NSFile::CFileBinary::ReadAllBytes(sSrc, &pData, nLength)) - return false; + return readStream(pXml, arSelectors, oTSR); + } - std::string sFileContent = XmlUtils::GetUtf8FromFileContent(pData, nLength); - RELEASEARRAYOBJECTS(pData); - std::wstring sRes = mhtToXhtml(sFileContent); - /* - NSFile::CFileBinary oWriter; - if (oWriter.CreateFileW(m_sTmp + L"/res.html")) - { - oWriter.WriteStringUTF8(sRes); - oWriter.CloseFile(); - } - */ - bRes = m_oLightReader.FromString(sRes); - } - else - bRes = htmlXhtml(sSrc); + bool ReadSamp(NSStringUtils::CStringBuilder* pXml, std::vector& arSelectors, CTextSettings& oTS) + { + if (NULL == pXml) + return false; - RELEASEARRAYOBJECTS(buffer); - return bRes; + CTextSettings oTSR(oTS); + oTSR.oAdditionalStyle.m_oFont.SetFamily(L"Courier New", UINT_MAX, true); + + return readStream(pXml, arSelectors, oTSR); } - // Читает стили - void readStyle() + bool ReadStrike(NSStringUtils::CStringBuilder* pXml, std::vector& arSelectors, CTextSettings& oTS) { - if(m_oLightReader.IsEmptyNode()) - return; + if (NULL == pXml) + return false; - int nDeath = m_oLightReader.GetDepth(); - while(m_oLightReader.ReadNextSiblingNode(nDeath)) - { - std::wstring sName = m_oLightReader.GetName(); + CTextSettings oTSR(oTS); + oTSR.oAdditionalStyle.m_oText.SetDecoration(L"line-through", UINT_MAX, true); - if(sName == L"body") - readStyle2(m_oTree); - else - { - // Стиль по ссылке - if(sName == L"link") - { - while(m_oLightReader.MoveToNextAttribute()) - { - if(m_oLightReader.GetName() != L"href") - continue; - std::wstring sRef = m_oLightReader.GetText(); - if(NSFile::GetFileExtention(sRef) != L"css") - continue; - std::wstring sFName = NSFile::GetFileName(sRef); - // Стиль в сети - if(sRef.substr(0, 4) == L"http") - { - sFName = m_sTmp + L'/' + sFName; - NSNetwork::NSFileTransport::CFileDownloader oDownloadStyle(sRef, false); - oDownloadStyle.SetFilePath(sFName); - if(oDownloadStyle.DownloadSync()) - { - m_oStylesCalculator.AddStylesFromFile(sFName); - NSFile::CFileBinary::Remove(sFName); - } - } - else - { - m_oStylesCalculator.AddStylesFromFile(m_sSrc + L'/' + sFName); - m_oStylesCalculator.AddStylesFromFile(m_sSrc + L'/' + sRef); - } - } - m_oLightReader.MoveToElement(); - } - // тэг style содержит стили для styles.xml - else if(sName == L"style") - m_oStylesCalculator.AddStyles(m_oLightReader.GetText2()); - else - readStyle(); - } - } + return readStream(pXml, arSelectors, oTSR); } - void readStyle2(NSCSS::CTree& oTree) + bool ReadFont(NSStringUtils::CStringBuilder* pXml, std::vector& arSelectors, CTextSettings& oTS) { - std::wstring sName = m_oLightReader.GetName(); - // Стиль по ссылке - if(sName == L"link") + if (NULL == pXml) + return false; + + CTextSettings oTSR(oTS); + + while(m_oLightReader.MoveToNextAttribute()) { - while(m_oLightReader.MoveToNextAttribute()) + std::wstring sAName = m_oLightReader.GetName(); + if(sAName == L"color") + oTSR.oAdditionalStyle.m_oText.SetColor(m_oLightReader.GetText(), UINT_MAX, true); + else if(sAName == L"face") + oTSR.oAdditionalStyle.m_oFont.SetFamily(m_oLightReader.GetText(), UINT_MAX, true); + else if(sAName == L"size") { - if(m_oLightReader.GetName() != L"href") - continue; - std::wstring sRef = m_oLightReader.GetText(); - if(NSFile::GetFileExtention(sRef) != L"css") - continue; - std::wstring sFName = NSFile::GetFileName(sRef); - // Стиль в сети - if(sRef.substr(0, 4) == L"http") - { - sFName = m_sTmp + L'/' + sFName; - NSNetwork::NSFileTransport::CFileDownloader oDownloadStyle(sRef, false); - oDownloadStyle.SetFilePath(sFName); - if(oDownloadStyle.DownloadSync()) - { - m_oStylesCalculator.AddStylesFromFile(sFName); - NSFile::CFileBinary::Remove(sFName); - } - } - else + int nSize = 3; + const std::wstring sSize = m_oLightReader.GetText(); + if(!sSize.empty()) { - m_oStylesCalculator.AddStylesFromFile(m_sSrc + L'/' + sFName); - m_oStylesCalculator.AddStylesFromFile(m_sSrc + L'/' + sRef); + if(sSize.front() == L'+') + nSize += NSStringFinder::ToInt(sSize.substr(1)); + else if(sSize.front() == L'-') + nSize -= NSStringFinder::ToInt(sSize.substr(1)); + else + nSize = NSStringFinder::ToInt(sSize); } - } - m_oLightReader.MoveToElement(); - } - // тэг style содержит стили для styles.xml - else if(sName == L"style") - m_oStylesCalculator.AddStyles(m_oLightReader.GetText2()); - oTree.m_oNode.m_wsName = sName; - // Стиль по атрибуту - while(m_oLightReader.MoveToNextAttribute()) - { - std::wstring sNameA = m_oLightReader.GetName(); - if(sNameA == L"class") - oTree.m_oNode.m_wsClass = m_oLightReader.GetText(); - else if(sNameA == L"id") - oTree.m_oNode.m_wsId = m_oLightReader.GetText(); - else if(sNameA == L"style") - oTree.m_oNode.m_wsStyle += m_oLightReader.GetText(); - else - oTree.m_oNode.m_mAttributes[sNameA] = m_oLightReader.GetText(); - } - m_oLightReader.MoveToElement(); + if (nSize < 1 || nSize > 7) + nSize = 3; - int nDeath = m_oLightReader.GetDepth(); - while(m_oLightReader.ReadNextSiblingNode(nDeath)) - { - if(!m_oLightReader.IsEmptyNode()) - { - NSCSS::CTree oChildTree; - readStyle2(oChildTree); - oTree.m_arrChild.push_back(oChildTree); + oTSR.oAdditionalStyle.m_oFont.SetSize(HTML_FONTS[nSize - 1], UINT_MAX, true); } } + m_oLightReader.MoveToElement(); + const bool bResult = readStream(pXml, arSelectors, oTSR); + m_oState.m_bWasSpace = true; + + return bResult; } - void PageBreakBefore() + bool ReadUnderline(NSStringUtils::CStringBuilder* pXml, std::vector& arSelectors, CTextSettings& oTS) { - m_oDocXml.WriteString(L""); + if (NULL == pXml) + return false; + + CTextSettings oTSR(oTS); + oTSR.oAdditionalStyle.m_oText.SetDecoration(L"underline", UINT_MAX, true); + + return readStream(pXml, arSelectors, oTSR); } -private: + bool ReadMark(NSStringUtils::CStringBuilder* pXml, std::vector& arSelectors, CTextSettings& oTS) + { + if (NULL == pXml) + return false; - std::wstring GetSubClass(NSStringUtils::CStringBuilder* oXml, std::vector& sSelectors) + CTextSettings oTSR(oTS); + oTSR.oAdditionalStyle.m_oText.SetHighlight(L"yellow", UINT_MAX, true); + + return readStream(pXml, arSelectors, oTSR); + } + + bool ReadQ(NSStringUtils::CStringBuilder* pXml, std::vector& arSelectors, CTextSettings& oTS) { - NSCSS::CNode oNode; - std::wstring sNote; - oNode.m_wsName = m_oLightReader.GetName(); - // Стиль по атрибуту - while(m_oLightReader.MoveToNextAttribute()) + if (NULL == pXml) + return false; + + CTextSettings oTSQ(oTS); + oTSQ.bQ = true; + + return readStream(pXml, arSelectors, oTSQ); + } + + bool ReadSup(NSStringUtils::CStringBuilder* pXml, std::vector& arSelectors, CTextSettings& oTS) + { + if (NULL == pXml) + return false; + + CTextSettings oTSR(oTS); + oTSR.eTextMode = CTextSettings::Superscript; + + return readStream(pXml, arSelectors, oTSR); + } + + bool ReadSub(NSStringUtils::CStringBuilder* pXml, std::vector& arSelectors, CTextSettings& oTS) + { + if (NULL == pXml) + return false; + + CTextSettings oTSR(oTS); + oTSR.eTextMode = CTextSettings::Subscript; + + return readStream(pXml, arSelectors, oTSR); + } + + bool ReadSpan(NSStringUtils::CStringBuilder* pXml, std::vector& arSelectors, CTextSettings& oTS) + { + if (NULL == pXml || arSelectors.empty() || arSelectors.back().m_wsClass == L"MsoFootnoteReference") + return false; + + return readStream(pXml, arSelectors, oTS); + } + + bool ReadNobr(NSStringUtils::CStringBuilder* pXml, std::vector& arSelectors, CTextSettings& oTS) + { + if (NULL == pXml) + return false; + + CTextSettings oTSPre(oTS); + oTSPre.bPre = true; + + return readStream(pXml, arSelectors, oTSPre); + } + + bool ReadBasefont(NSStringUtils::CStringBuilder* pXml, std::vector& arSelectors, CTextSettings& oTS) + { + if (NULL == pXml || !m_oLightReader.MoveToFirstAttribute()) + return false; + + do { - std::wstring sName = m_oLightReader.GetName(); - if(sName == L"class") - oNode.m_wsClass = m_oLightReader.GetText(); - else if(sName == L"id") - { - oNode.m_wsId = m_oLightReader.GetText(); - std::wstring sCrossId = std::to_wstring(m_nCrossId++); - oXml->WriteString(L"WriteString(sCrossId); - oXml->WriteString(L"\" w:name=\""); - oXml->WriteEncodeXmlString(oNode.m_wsId); - oXml->WriteString(L"\"/>WriteString(sCrossId); - oXml->WriteString(L"\"/>"); - } - else if(sName == L"style") - oNode.m_wsStyle += m_oLightReader.GetText(); - else if(sName == L"title") - sNote = m_oLightReader.GetText(); - else - oNode.m_mAttributes[sName] = m_oLightReader.GetText(); - } + if (L"face" == m_oLightReader.GetName()) + oTS.oAdditionalStyle.m_oFont.SetFamily(m_oLightReader.GetText(), UINT_MAX, true); + else if (L"size" == m_oLightReader.GetName()) + { + switch(NSStringFinder::ToInt(m_oLightReader.GetText(), 3)) + { + case 1: oTS.oAdditionalStyle.m_oFont.SetSize(7.5, UINT_MAX, true); break; + case 2: oTS.oAdditionalStyle.m_oFont.SetSize(10, UINT_MAX, true); break; + default: + case 3: oTS.oAdditionalStyle.m_oFont.SetSize(12, UINT_MAX, true); break; + case 4: oTS.oAdditionalStyle.m_oFont.SetSize(13.5, UINT_MAX, true); break; + case 5: oTS.oAdditionalStyle.m_oFont.SetSize(18, UINT_MAX, true); break; + case 6: oTS.oAdditionalStyle.m_oFont.SetSize(24, UINT_MAX, true); break; + case 7: oTS.oAdditionalStyle.m_oFont.SetSize(36, UINT_MAX, true); break; + } + } + else if (L"color" == m_oLightReader.GetName()) + oTS.oAdditionalStyle.m_oText.SetColor(m_oLightReader.GetText(), UINT_MAX, true); + } while (m_oLightReader.MoveToNextAttribute()); + m_oLightReader.MoveToElement(); - sSelectors.push_back(oNode); - return sNote; + + oTS.oAdditionalStyle.SetID(m_oStylesCalculator.CalculateStyleId(arSelectors.back())); + + return true; } - std::wstring GetStyle(const NSCSS::CCompiledStyle& oStyle, bool bP) + bool ReadDD(NSStringUtils::CStringBuilder* pXml, std::vector& arSelectors, CTextSettings& oTS) { -// NSCSS::CCompiledStyle oStyle = m_oStylesCalculator.GetCompiledStyle(sSelectors); - bP ? m_oXmlStyle.WritePStyle(oStyle) : m_oXmlStyle.WriteRStyle(oStyle); - m_oStylesXml.WriteString(m_oXmlStyle.GetStyle()); - return m_oXmlStyle.GetIdAndClear(); + if (NULL == pXml) + return false; + + CTextSettings oTSP(oTS); + oTSP.oAdditionalStyle.m_oMargin.SetLeft(720, UINT_MAX, true); + + return readStream(pXml, arSelectors, oTSP); } - void readHead() + bool ReadDiv(NSStringUtils::CStringBuilder* pXml, std::vector& arSelectors, CTextSettings& oTS) { - if(m_oLightReader.IsEmptyNode()) - return; - int nDeath = m_oLightReader.GetDepth(); - while (m_oLightReader.ReadNextSiblingNode(nDeath)) + if (NULL == pXml) + return false; + + if (!m_oState.m_bBanUpdatePageData) + m_oStylesCalculator.CalculatePageStyle(m_oPageData, arSelectors); + + int bMsoFootnote = 0; + std::wstring sFootnoteID; + while (m_oLightReader.MoveToNextAttribute()) { - // Базовый адрес - if (m_oLightReader.GetName() == L"base") + std::wstring sAName = m_oLightReader.GetName(); + std::wstring sAText = m_oLightReader.GetText(); + if (sAName == L"epub:type" && sAText == L"footnote") + bMsoFootnote++; + else if (sAName == L"style" && sAText == L"mso-element:footnote") + bMsoFootnote++; + else if (sAName == L"id") { - while (m_oLightReader.MoveToNextAttribute()) - if (m_oLightReader.GetName() == L"href") - m_sBase = m_oLightReader.GetText(); - m_oLightReader.MoveToElement(); + std::map::iterator it = m_mFootnotes.find(sAText); + if (it != m_mFootnotes.end()) + { + bMsoFootnote++; + sFootnoteID = it->second; + } } } + m_oLightReader.MoveToElement(); + if (bMsoFootnote >= 2) + { + m_oNoteXml.WriteString(L""); + readStream(&m_oNoteXml, arSelectors, oTS); + m_oNoteXml.WriteString(L""); + } + else + return readStream(pXml, arSelectors, oTS); + + return true; } - void readBody() + bool ReadBlockquote(NSStringUtils::CStringBuilder* pXml, std::vector& arSelectors, CTextSettings& oTS) { - std::vector sSelectors; - - sSelectors.push_back(NSCSS::CNode(L"html", L"", L"")); - - GetSubClass(&m_oDocXml, sSelectors); - /* - std::wstring sCrossId = std::to_wstring(m_nCrossId++); - m_oDocXml.WriteString(L""); - */ + if (NULL == pXml) + return false; + + CTextSettings oNewTS{oTS}; + oNewTS.sPStyle += L""; - readStream(&m_oDocXml, sSelectors, { false, false, -1, L"", L"" }); + return readStream(pXml, arSelectors, oNewTS); } - void readInside (NSStringUtils::CStringBuilder* oXml, std::vector& sSelectors, const CTextSettings& oTS, const std::wstring& sName) + bool ReadHr(NSStringUtils::CStringBuilder* pXml, std::vector& arSelectors, CTextSettings& oTS) { - if(sName == L"#text") + if (NULL == pXml) + return false; + + bool bPrint = true; + + for (const NSCSS::CNode& item : arSelectors) { - std::wstring sText = m_oLightReader.GetText(); - size_t find = sText.find_first_not_of(L" \n\t\r"); - if (find == std::wstring::npos) + if (item.m_wsName == L"div" && item.m_wsStyle == L"mso-element:footnote-list") { - m_bWasSpace = true; - return; + bPrint = false; + break; } - else if (find != 1 || m_bWasSpace || sText.front() != L' ') - sText.erase(0, find); + } - std::wstring sPStyle = wrP(oXml, sSelectors, oTS); - oXml->WriteString(L""); - std::wstring sRStyle = wrR(oXml, sSelectors, oTS); - oXml->WriteString(L""); + if (bPrint) + { + NSCSS::NSProperties::CDigit oSize, oWidth; + NSCSS::NSProperties::CColor oColor; + bool bShade = false; + std::wstring wsAlign{L"center"}; - std::wstring::iterator end; - if(oTS.bBdo) - std::reverse(sText.begin(), sText.end()); - if (m_bWasSpace) - { - sText.insert(sText.begin(), L' '); - m_bWasSpace = false; - } - if(oTS.bPre) + if (m_oLightReader.MoveToFirstAttribute()) { - size_t nAfter = sText.find_first_of(L"\n\r"); - while(nAfter != std::wstring::npos) + std::wstring wsAttributeName; + do { - oXml->WriteEncodeXmlString(sText.c_str(), nAfter); - oXml->WriteString(L"
"); - if(!sPStyle.empty()) + wsAttributeName = m_oLightReader.GetName(); + + if (L"align" == wsAttributeName) { - oXml->WriteString(L"WriteString(sPStyle); - oXml->WriteString(L"\"/>"); - oXml->WriteString(oTS.sPStyle); - oXml->WriteString(L""); + const std::wstring wsValue{m_oLightReader.GetText()}; + + if (NSStringFinder::Equals(L"left", wsValue)) + wsAlign = L"left"; + else if (NSStringFinder::Equals(L"right", wsValue)) + wsAlign = L"right"; + else if (NSStringFinder::Equals(L"center", wsValue)) + wsAlign = L"center"; } - oXml->WriteString(L"WriteString(sRStyle); - oXml->WriteString(L"\"/>"); - oXml->WriteString(oTS.sRStyle); - oXml->WriteString(L""); - sText.erase(0, nAfter + 1); - nAfter = sText.find_first_of(L"\n\r"); - } - end = sText.end(); + if (L"color" == wsAttributeName) + oColor.SetValue(m_oLightReader.GetText()); + else if (L"noshade" == wsAttributeName) + bShade = true; + else if (L"size" == wsAttributeName) + oSize.SetValue(m_oLightReader.GetText()); + else if (L"width" == wsAttributeName) + oWidth.SetValue(m_oLightReader.GetText()); + } while (m_oLightReader.MoveToNextAttribute()); + + m_oLightReader.MoveToElement(); } - else - end = std::unique(sText.begin(), sText.end(), [] (wchar_t l, wchar_t r) { return std::iswspace(l) && std::iswspace(r); }); - sText = std::wstring(sText.begin(), end); - oXml->WriteEncodeXmlString(sText); - oXml->WriteString(L""); - return; - } + const bool bOpenedP = OpenP(pXml); - std::wstring sNote = GetSubClass(oXml, sSelectors); + OpenR(pXml); + WriteLine(pXml, wsAlign, (!oColor.Empty()) ? oColor.ToWString() : L"a0a0a0", bShade, (!oSize.Empty()) ? oSize.ToDouble(NSCSS::Point) : 1.5, (NSCSS::UnitMeasure::Percent == oWidth.GetUnitMeasure()) ? oWidth.ToDouble() : 0); + CloseR(pXml); - // Ссылка - // Область ссылки - if(sName == L"a" || sName == L"area") - readA(oXml, sSelectors, oTS, sNote); - // Полужирный текст - // Акцентированный текст - else if(sName == L"b" || sName == L"strong") - { - CTextSettings oTSR(oTS); - oTSR.sRStyle += L""; - readStream(oXml, sSelectors, oTSR); - } - // Направление текста - else if(sName == L"bdo") - { - std::wstring sDir; - while(m_oLightReader.MoveToNextAttribute()) - if(m_oLightReader.GetName() == L"dir") - sDir = m_oLightReader.GetText(); - m_oLightReader.MoveToElement(); + if (bOpenedP) + CloseP(pXml, arSelectors); - CTextSettings oTSBdo(oTS); - oTSBdo.bBdo = (sDir == L"rtl"); - readStream(oXml, sSelectors, oTSBdo); - } - // Отмена направления текста - else if(sName == L"bdi") - { - CTextSettings oTSBdo(oTS); - oTSBdo.bBdo = false; - readStream(oXml, sSelectors, oTSBdo); - } - // Увеличивает размер шрифта - else if(sName == L"big") - { - CTextSettings oTSR(oTS); - oTSR.sRStyle += L""; - readStream(oXml, sSelectors, oTSR); - } - // Перенос строки - else if(sName == L"br") - { - wrP(oXml, sSelectors, oTS); - oXml->WriteString(L""); - NSCSS::CCompiledStyle oStyle = m_oStylesCalculator.GetCompiledStyle(sSelectors); - if(oStyle.m_oText.GetAlign() == L"both") - oXml->WriteString(L""); - oXml->WriteString(L""); - m_bWasSpace = false; - } - else if(sName == L"center") - { - CTextSettings oTSP(oTS); - oTSP.sPStyle += L""; - readStream(oXml, sSelectors, oTSP); - } - // Цитата, обычно выделяется курсивом - // Новый термин, обычно выделяется курсивом - // Акцентированный текст - // Курсивный текст - // Переменная, обычно выделяется курсивом - else if(sName == L"cite" || sName == L"dfn" || sName == L"em" || sName == L"i" || sName == L"var") - { - CTextSettings oTSR(oTS); - oTSR.sRStyle += L""; - readStream(oXml, sSelectors, oTSR); - } - // Код - // Моноширинный шрифт, например, Consolas - // Результат скрипта - else if(sName == L"code" || sName == L"kbd" || sName == L"samp" || sName == L"tt") - { - CTextSettings oTSR(oTS); - oTSR.sRStyle += L""; - readStream(oXml, sSelectors, oTSR); + return true; } - // Зачеркнутый текст - else if(sName == L"del" || sName == L"s") + + return false; + } + + bool ReadPre(NSStringUtils::CStringBuilder* pXml, std::vector& arSelectors, CTextSettings& oTS) + { + if (NULL == pXml) + return false; + + CTextSettings oTSPre(oTS); + oTSPre.oAdditionalStyle.m_oFont.SetFamily(L"Courier New", NEXT_LEVEL); + oTSPre.oAdditionalStyle.m_oFont.SetSize(20, NEXT_LEVEL); + oTSPre.oAdditionalStyle.m_oMargin.SetTop(0, NEXT_LEVEL); + oTSPre.oAdditionalStyle.m_oMargin.SetBottom(0, NEXT_LEVEL); + oTSPre.bPre = true; + + return readStream(pXml, arSelectors, oTSPre); + } + + bool ReadTextarea(NSStringUtils::CStringBuilder* pXml, std::vector& arSelectors, CTextSettings& oTS) + { + if (NULL == pXml) + return false; + + CTextSettings oTSP(oTS); + oTSP.AddPStyle(L""); + + return readStream(pXml, arSelectors, oTSP); + } + + bool ReadDetails(NSStringUtils::CStringBuilder* pXml, std::vector& arSelectors, CTextSettings& oTS) + { + if (NULL == pXml) + return false; + + bool bOpened = false; + if (m_oLightReader.MoveToFirstAttribute()) { - CTextSettings oTSR(oTS); - oTSR.sRStyle += L""; - readStream(oXml, sSelectors, oTSR); + do + { + bOpened = (L"open" == m_oLightReader.GetName()); + } while (m_oLightReader.MoveToNextAttribute() && !bOpened); } - else if(sName == L"font") + m_oLightReader.MoveToElement(); + + int nDeath = m_oLightReader.GetDepth(); + if(m_oLightReader.IsEmptyNode() || !m_oLightReader.ReadNextSiblingNode2(nDeath)) + return false; + + NSStringUtils::CStringBuilder oSummary; + NSStringUtils::CStringBuilder oBody; + + const TState oCurrentState{m_oState}; + TState oSummaryState{m_oState}; + TState oBodyState{m_oState}; + + do { - while(m_oLightReader.MoveToNextAttribute()) + if (L"summary" == m_oLightReader.GetName()) { - std::wstring sAName = m_oLightReader.GetName(); - if(sAName == L"color") - sSelectors.back().m_wsStyle += L"; color: " + m_oLightReader.GetText(); - else if(sAName == L"face") - sSelectors.back().m_wsStyle += L"; font-family: " + m_oLightReader.GetText(); - else if(sAName == L"size") + m_oState = oSummaryState; + if (0 == oSummary.GetSize()) { - int nSize = 3; - std::wstring sSize = m_oLightReader.GetText(); - if(!sSize.empty()) - { - if(sSize.front() == L'+') - nSize += std::stoi(sSize.substr(1)); - else if(sSize.front() == L'-') - nSize -= std::stoi(sSize.substr(1)); - else - nSize = std::stoi(sSize); - } - sSize = nSize >= 1 && nSize <= 7 ? std::to_wstring(10 + nSize * 5) : L"22"; - sSelectors.back().m_wsStyle += L"; font-size: " + sSize; + OpenP(&oSummary); + OpenR(&oSummary); + OpenT(&oSummary); + oSummary.WriteString((bOpened) ? L"\u25BD" : L"\u25B7"); } + + readStream(&oSummary, arSelectors, oTS); + CloseP(&oSummary, arSelectors); + oSummaryState = m_oState; + m_oState = oCurrentState; } - m_oLightReader.MoveToElement(); - readStream(oXml, sSelectors, oTS); - } - // Картинки - else if(sName == L"img") - readImage(oXml, sSelectors, oTS); - // Подчеркнутый - else if(sName == L"ins" || sName == L"u") - { - CTextSettings oTSR(oTS); - oTSR.sRStyle += L""; - readStream(oXml, sSelectors, oTSR); - } - // Выделенный текст, обычно выделяется желтым - else if(sName == L"mark") - { - CTextSettings oTSR(oTS); - oTSR.sRStyle += L""; - readStream(oXml, sSelectors, oTSR); - } - // Цитата, выделенная кавычками, обычно выделяется курсивом - else if(sName == L"q") - { - wrP(oXml, sSelectors, oTS); - oXml->WriteString(L""); - std::wstring sRStyle = wrR(oXml, sSelectors, oTS); - oXml->WriteString(L"""); + else if (bOpened) + { + m_oState = oBodyState; + readStream(&oBody, arSelectors, oTS); + CloseP(&oBody, arSelectors); + oBodyState = m_oState; + m_oState = oCurrentState; + } + } while (m_oLightReader.ReadNextSiblingNode2(nDeath)); - CTextSettings oTSR(oTS); - oTSR.sRStyle += L""; - readStream(oXml, sSelectors, oTSR); + WriteToStringBuilder(oSummary, *pXml); - wrP(oXml, sSelectors, oTS); - oXml->WriteString(L"WriteString(sRStyle); - oXml->WriteString(L"\"/>"); - oXml->WriteString(oTS.sRStyle); - oXml->WriteString(L"""); - } - // Текст верхнего регистра - else if(sName == L"rt" || sName == L"sup") - { - CTextSettings oTSR(oTS); - oTSR.sRStyle += L""; - readStream(oXml, sSelectors, oTSR); - } - // Уменьшает размер шрифта - else if(sName == L"small") - { - CTextSettings oTSR(oTS); - oTSR.sRStyle += L""; - readStream(oXml, sSelectors, oTSR); - } - // Текст нижнего регистра - else if(sName == L"sub") - { - CTextSettings oTSR(oTS); - oTSR.sRStyle += L""; - readStream(oXml, sSelectors, oTSR); - } - // Векторная картинка - else if(sName == L"svg" || (sName.length() > 3 && sName.compare(sName.length() - 3, 3, L"svg") == 0)) - { - wrP(oXml, sSelectors, oTS); - readSVG(oXml); - } - else if(sName == L"input") - readInput(oXml, sSelectors, oTS); - // Игнорируются тэги выполняющие скрипт - else if(sName == L"template" || sName == L"canvas" || sName == L"video" || sName == L"math" || sName == L"rp" || - sName == L"command" || sName == L"iframe" || sName == L"embed" || sName == L"wbr" || sName == L"audio" || - sName == L"bgsound" || sName == L"applet" || sName == L"blink" || sName == L"keygen"|| sName == L"script" || - sName == L"comment" || sName == L"title" || sName == L"style") + if (bOpened) { - sSelectors.pop_back(); - return; + m_oState = oBodyState; + WriteToStringBuilder(oBody, *pXml); } - else if (sName == L"span") + + return true; + } + + bool readInside (NSStringUtils::CStringBuilder* oXml, std::vector& sSelectors, CTextSettings& oTS, const std::wstring& sName) + { + //TODO:: обработать все варианты return'а + + if(sName == L"#text") + return ReadText(oXml, sSelectors, oTS); + + if (TagIsUnprocessed(sName)) + return false; + + std::wstring sNote = GetSubClass(oXml, sSelectors); + bool bResult = true; + // Ссылка + // Область ссылки + + const HtmlTag eHtmlTag{GetHtmlTag(sName)}; + + switch(eHtmlTag) { - if (sSelectors.back().m_wsClass == L"MsoFootnoteReference") + case HTML_TAG(A): + case HTML_TAG(AREA): { - sSelectors.pop_back(); - return; + bResult = readA(oXml, sSelectors, oTS, sNote); + break; } - readStream(oXml, sSelectors, oTS); - } - // Без нового абзаца - else if(sName == L"basefont" || sName == L"button" || sName == L"label" || sName == L"data" || sName == L"object" || - sName == L"noscript" || sName == L"output" || sName == L"abbr" || sName == L"time" || sName == L"ruby" || - sName == L"progress" || sName == L"hgroup" || sName == L"meter" || sName == L"acronym") - readStream(oXml, sSelectors, oTS); - // С нового абзаца - else - { - if (m_bInP) + case HTML_TAG(ABBR): + { + bResult = ReadAbbr(oXml, sSelectors, oTS, sNote); + break; + } + case HTML_TAG(B): + case HTML_TAG(STRONG): + { + bResult = ReadBold(oXml, sSelectors, oTS); + break; + } + case HTML_TAG(BDO): + { + bResult = ReadBdo(oXml, sSelectors, oTS); + break; + } + case HTML_TAG(BDI): + { + bResult = ReadBdi(oXml, sSelectors, oTS); + break; + } + case HTML_TAG(BR): + { + bResult = ReadBr(oXml, sSelectors, oTS); + break; + } + case HTML_TAG(CENTER): { - for (const NSCSS::CNode& item : sSelectors) - if (item.m_wsName == L"a") - oXml->WriteString(L""); - oXml->WriteString(L""); - m_bInP = false; + bResult = ReadCenter(oXml, sSelectors, oTS); + break; + } + case HTML_TAG(CITE): + case HTML_TAG(DFN): + case HTML_TAG(EM): + case HTML_TAG(I): + case HTML_TAG(VAR): + { + bResult = ReadItalic(oXml, sSelectors, oTS); + break; + } + case HTML_TAG(CODE): + case HTML_TAG(TT): + { + bResult = ReadCode(oXml, sSelectors, oTS); + break; + } + case HTML_TAG(KBD): + { + bResult = ReadKbd(oXml, sSelectors, oTS); + break; + } + case HTML_TAG(SAMP): + { + bResult = ReadSamp(oXml, sSelectors, oTS); + break; + } + case HTML_TAG(DEL): + case HTML_TAG(S): + case HTML_TAG(STRIKE): + { + bResult = ReadStrike(oXml, sSelectors, oTS); + break; + } + case HTML_TAG(FONT): + { + bResult = ReadFont(oXml, sSelectors, oTS); + break; + } + case HTML_TAG(IMG): + { + bResult = readImage(oXml, sSelectors, oTS); + break; + } + case HTML_TAG(INS): + case HTML_TAG(U): + { + bResult = ReadUnderline(oXml, sSelectors, oTS); + break; + } + case HTML_TAG(MARK): + { + bResult = ReadMark(oXml, sSelectors, oTS); + break; + } + case HTML_TAG(Q): + { + bResult = ReadQ(oXml, sSelectors, oTS); + break; + } + case HTML_TAG(SUP): + { + bResult = ReadSup(oXml, sSelectors, oTS); + break; + } + case HTML_TAG(SUB): + { + bResult = ReadSub(oXml, sSelectors, oTS); + break; } - m_bWasSpace = false; + case HTML_TAG(SVG): + { + wrP(oXml, sSelectors, oTS); + bResult = readSVG(m_oLightReader.GetOuterXml()); - // Адрес - if(sName == L"address") + if (bResult) + ImageRels(oXml, -1, L"", L"png"); + + break; + } + case HTML_TAG(INPUT): + { + bResult = readInput(oXml, sSelectors, oTS); + break; + } + case HTML_TAG(CANVAS): + case HTML_TAG(VIDEO): + case HTML_TAG(MATH): + case HTML_TAG(IFRAME): + case HTML_TAG(EMBED): + case HTML_TAG(WBR): + case HTML_TAG(AUDIO): + case HTML_TAG(BGSOUND): + case HTML_TAG(APPLET): + case HTML_TAG(BLINK): + case HTML_TAG(KEYGEN): + case HTML_TAG(TITLE): + case HTML_TAG(STYLE): + case HTML_TAG(SCRIPT): + { + WriteEmptyParagraph(oXml, false, m_oState.m_bInP); + sSelectors.pop_back(); + return true; + } + case HTML_TAG(SPAN): + { + bResult = ReadSpan(oXml, sSelectors, oTS); + break; + } + case HTML_TAG(NOBR): + { + bResult = ReadNobr(oXml, sSelectors, oTS); + break; + } + case HTML_TAG(BASEFONT): { - CTextSettings oTSR(oTS); - oTSR.sRStyle += L""; - readStream(oXml, sSelectors, oTSR); + bResult = ReadBasefont(oXml, sSelectors, oTS); + break; } - // Определение термина, отступ от левого края - else if(sName == L"dd") + case HTML_TAG(BUTTON): + case HTML_TAG(LABEL): + case HTML_TAG(DATA): + case HTML_TAG(OBJECT): + case HTML_TAG(NOSCRIPT): + case HTML_TAG(OUTPUT): + case HTML_TAG(TIME): + case HTML_TAG(SMALL): + case HTML_TAG(PROGRESS): + case HTML_TAG(HGROUP): + case HTML_TAG(METER): + case HTML_TAG(ACRONYM): + case HTML_TAG(BIG): { - CTextSettings oTSP(oTS); - oTSP.sPStyle += L""; - readStream(oXml, sSelectors, oTSP); + bResult = readStream(oXml, sSelectors, oTS); + break; } - // aside возможно использовать для сносок в epub - else if (sName == L"aside" || sName == L"div") + default: { - int bMsoFootnote = 0; - std::wstring sFootnoteID; - while (m_oLightReader.MoveToNextAttribute()) + NSStringUtils::CStringBuilder oXmlData; + TState oCurentState{m_oState}; + + CloseP(&oXmlData, sSelectors); + + switch(eHtmlTag) { - std::wstring sAName = m_oLightReader.GetName(); - std::wstring sAText = m_oLightReader.GetText(); - if (sAName == L"epub:type" && sAText == L"footnote") - bMsoFootnote++; - else if (sAName == L"style" && sAText == L"mso-element:footnote") - bMsoFootnote++; - else if (sAName == L"id") + case HTML_TAG(ADDRESS): + { + bResult = ReadItalic(&oXmlData, sSelectors, oTS); + break; + } + case HTML_TAG(DD): + { + bResult = ReadDD(&oXmlData, sSelectors, oTS); + break; + } + case HTML_TAG(ASIDE): + case HTML_TAG(DIV): + { + bResult = ReadDiv(&oXmlData, sSelectors, oTS); + break; + } + case HTML_TAG(BLOCKQUOTE): { - std::map::iterator it = m_mFootnotes.find(sAText); - if (it != m_mFootnotes.end()) - { - bMsoFootnote++; - sFootnoteID = it->second; - } + bResult = ReadBlockquote(&oXmlData, sSelectors, oTS); + break; } - } - m_oLightReader.MoveToElement(); - if (bMsoFootnote >= 2) - { - m_oNoteXml.WriteString(L""); - readStream(&m_oNoteXml, sSelectors, oTS); - m_oNoteXml.WriteString(L""); - } - else - readStream(oXml, sSelectors, oTS); - } - // С нового абзаца - else if(sName == L"article" || sName == L"header" || sName == L"blockquote" || sName == L"main" || sName == L"dir" || - sName == L"summary" || sName == L"footer" || sName == L"nav" || sName == L"figcaption" || sName == L"form" || - sName == L"details" || sName == L"option" || sName == L"dt" || sName == L"p" || - sName == L"section" || sName == L"figure" || sName == L"dl" || sName == L"legend" || sName == L"map" || - sName == L"h1" || sName == L"h2" || sName == L"h3" || sName == L"h4" || sName == L"h5" || sName == L"h6") - readStream(oXml, sSelectors, oTS); - // Горизонтальная линия - else if(sName == L"hr") - { - bool bPrint = true; - for (const NSCSS::CNode& item : sSelectors) - { - if (item.m_wsName == L"div" && item.m_wsStyle == L"mso-element:footnote-list") + case HTML_TAG(ARTICLE): + case HTML_TAG(HEADER): + case HTML_TAG(MAIN): + case HTML_TAG(SUMMARY): + case HTML_TAG(FOOTER): + case HTML_TAG(NAV): + case HTML_TAG(FIGCAPTION): + case HTML_TAG(FORM): + case HTML_TAG(OPTION): + case HTML_TAG(DT): + case HTML_TAG(P): + case HTML_TAG(SECTION): + case HTML_TAG(FIGURE): + case HTML_TAG(DL): + case HTML_TAG(LEGEND): + case HTML_TAG(MAP): + case HTML_TAG(H1): + case HTML_TAG(H2): + case HTML_TAG(H3): + case HTML_TAG(H4): + case HTML_TAG(H5): + case HTML_TAG(H6): + { + bResult = readStream(&oXmlData, sSelectors, oTS); + break; + } + case HTML_TAG(HR): + { + bResult = ReadHr(&oXmlData, sSelectors, oTS); + break; + } + case HTML_TAG(UL): + case HTML_TAG(MENU): + case HTML_TAG(SELECT): + case HTML_TAG(DATALIST): + case HTML_TAG(DIR): + case HTML_TAG(OL): + { + bResult = readLi(&oXmlData, sSelectors, oTS, HTML_TAG(OL) != eHtmlTag); + break; + } + case HTML_TAG(PRE): + case HTML_TAG(XMP): + { + bResult = ReadPre(&oXmlData, sSelectors, oTS); + break; + } + case HTML_TAG(TABLE): + { + bResult = ParseTable(&oXmlData, sSelectors, oTS); + break; + } + case HTML_TAG(RUBY): + { + bResult = ParseRuby(&oXmlData, sSelectors, oTS); + break; + } + case HTML_TAG(TEXTAREA): + case HTML_TAG(FIELDSET): + { + bResult = ReadTextarea(&oXmlData, sSelectors, oTS); + break; + } + case HTML_TAG(DETAILS): + { + bResult = ReadDetails(&oXmlData, sSelectors, oTS); + break; + } + default: { - bPrint = false; + bResult = readStream(&oXmlData, sSelectors, oTS); break; } } - if (bPrint) - oXml->WriteString(L""); - } - // Меню - // Маркированный список - else if(sName == L"menu" || sName == L"ul" || sName == L"select" || sName == L"datalist") - readLi(oXml, sSelectors, oTS, true); - // Нумерованный список - else if(sName == L"ol") - readLi(oXml, sSelectors, oTS, false); - // Предварительно форматированный текст - else if(sName == L"pre" || sName == L"xmp") - { - CTextSettings oTSPre(oTS); - oTSPre.bPre = true; - oTSPre.sRStyle += L""; - oTSPre.sPStyle += L""; - readStream(oXml, sSelectors, oTSPre); - } - // Таблицы - else if(sName == L"table") - readTable(oXml, sSelectors, oTS); - // Текст с границами - else if(sName == L"textarea" || sName == L"fieldset") - { - CTextSettings oTSP(oTS); - oTSP.sPStyle += L""; - readStream(oXml, sSelectors, oTSP); - } - // Неизвестный тэг. Выделять ли его абзацем? - else - readStream(oXml, sSelectors, oTS); - readNote(oXml, sSelectors, sNote); - sNote = L""; - if (m_bInP) - { - for (const NSCSS::CNode& item : sSelectors) - if (item.m_wsName == L"a") - oXml->WriteString(L""); - oXml->WriteString(L"
"); - m_bInP = false; + readNote(&oXmlData, sSelectors, sNote); + + CloseP(&oXmlData, sSelectors); + + if (bResult) + WriteToStringBuilder(oXmlData, *oXml); + else + m_oState = oCurentState; } - m_bWasSpace = false; } + + if (HTML_TAG(DIV) != eHtmlTag && HTML_TAG(ASIDE) != eHtmlTag) + m_oState.m_bBanUpdatePageData = true; + readNote(oXml, sSelectors, sNote); sSelectors.pop_back(); + return bResult; } - bool readStream (NSStringUtils::CStringBuilder* oXml, std::vector& sSelectors, const CTextSettings& oTS) + bool readStream (NSStringUtils::CStringBuilder* oXml, std::vector& sSelectors, CTextSettings& oTS, bool bInsertEmptyP = false) { int nDeath = m_oLightReader.GetDepth(); if(m_oLightReader.IsEmptyNode() || !m_oLightReader.ReadNextSiblingNode2(nDeath)) + { + if (bInsertEmptyP) + { + wrP(oXml, sSelectors, oTS); + wrRPr(oXml, sSelectors, oTS); + CloseP(oXml, sSelectors); + m_oState.m_bInP = false; + } return false; + } + + bool bResult = false; do { - readInside(oXml, sSelectors, oTS, m_oLightReader.GetName()); + if (readInside(oXml, sSelectors, oTS, m_oLightReader.GetName())) + bResult = true; } while(m_oLightReader.ReadNextSiblingNode2(nDeath)); - return true; + + if (!bResult && bInsertEmptyP) + { + wrP(oXml, sSelectors, oTS); + wrRPr(oXml, sSelectors, oTS); + CloseP(oXml, sSelectors); + m_oState.m_bInP = false; + } + + return bResult; } - void readTr (NSStringUtils::CStringBuilder* oXml, std::vector& sSelectors, const CTextSettings& oTS, const std::wstring& sBorders) + void CalculateCellStyles(TTableCellStyle* pCellStyle, const std::vector& arSelectors) { - std::vector mTable; - int nDeath = m_oLightReader.GetDepth(); - int i = 1; // Строка + if (NULL == pCellStyle) + return; - while(m_oLightReader.ReadNextSiblingNode(nDeath)) - { - // tr - строки в таблице - if(m_oLightReader.GetName() != L"tr") - continue; - int nTrDeath = m_oLightReader.GetDepth(); - if(m_oLightReader.IsEmptyNode() || !m_oLightReader.ReadNextSiblingNode(nTrDeath)) - continue; + NSCSS::CCompiledStyle oStyle; + m_oStylesCalculator.GetCompiledStyle(oStyle, arSelectors); - int j = 1; // Столбец - oXml->WriteString(L""); + pCellStyle->m_wsVAlign = oStyle.m_oDisplay.GetVAlign().ToWString(); + pCellStyle->m_wsHAlign = oStyle.m_oDisplay.GetHAlign().ToWString(); + pCellStyle->m_oBackground = oStyle.m_oBackground.GetColor(); + pCellStyle->m_oHeight = oStyle.m_oDisplay.GetHeight(); + pCellStyle->m_oWidth = oStyle.m_oDisplay.GetWidth(); + pCellStyle->m_oPadding = oStyle.m_oPadding; + pCellStyle->m_oBorder = oStyle.m_oBorder; + + if (pCellStyle->m_wsHAlign.empty()) + pCellStyle->m_wsHAlign = oStyle.m_oText.GetAlign().ToWString(); + } + + void ParseTableCaption(CTable& oTable, std::vector& sSelectors, const CTextSettings& oTS) + { + GetSubClass(NULL, sSelectors); + + NSStringUtils::CStringBuilder oData; + + CTextSettings oTSCaption{oTS}; + oTSCaption.sPStyle += L""; + + wrP(&oData, sSelectors, oTSCaption); + readStream(&oData, sSelectors, oTSCaption); + CloseP(&oData, sSelectors); + + oTable.AddCaption(oData); + + sSelectors.pop_back(); + return; + } + + void ParseTableColspan(CTable& oTable) + { + CTableColgroup *pColgroup = new CTableColgroup(m_oLightReader); + + if (NULL == pColgroup) + return; + + std::vector arNodes; + + GetSubClass(NULL, arNodes); + + oTable.AddColgroup(pColgroup); + + const int nDeath = m_oLightReader.GetDepth(); + if (!m_oLightReader.IsEmptyNode() && m_oLightReader.ReadNextSiblingNode2(nDeath)) + { do { - int nColspan = 1; - int nRowspan = 1; - while(m_oLightReader.MoveToNextAttribute()) - { - if(m_oLightReader.GetName() == L"colspan") - nColspan = stoi(m_oLightReader.GetText()); - else if(m_oLightReader.GetName() == L"rowspan") - nRowspan = stoi(m_oLightReader.GetText()); - } - m_oLightReader.MoveToElement(); + if (L"col" != m_oLightReader.GetName()) + continue; - // Вставляем ячейки до - std::vector::iterator it1 = std::find_if(mTable.begin(), mTable.end(), [i, j](const CTc& item){ return item.i == i && item.j == j; }); - std::vector::iterator it2 = std::find_if(mTable.begin(), mTable.end(), [j] (const CTc& item){ return item.i == 0 && item.j == j; }); - while(it1 != mTable.end() || it2 != mTable.end()) - { - oXml->WriteString(L""); - oXml->WriteString(!sBorders.empty() ? sBorders : L""); - oXml->WriteString(L"sGridSpan : it2->sGridSpan); - oXml->WriteString(sCol); - oXml->WriteString(L"\"/>"); - j += stoi(sCol); - it1 = std::find_if(mTable.begin(), mTable.end(), [i, j](const CTc& item){ return item.i == i && item.j == j; }); - it2 = std::find_if(mTable.begin(), mTable.end(), [j] (const CTc& item){ return item.i == 0 && item.j == j; }); - } + CTableCol *pCol = new CTableCol(m_oLightReader); - GetSubClass(oXml, sSelectors); - oXml->WriteString(L""); + if (NULL == pCol) + continue; + + GetSubClass(NULL, arNodes); + CalculateCellStyles(pCol->GetStyle(), arNodes); + arNodes.pop_back(); - NSCSS::CCompiledStyle oStyleSetting = m_oStylesCalculator.GetCompiledStyle({sSelectors.back()}, true); - NSCSS::CCompiledStyle oStyle = m_oStylesCalculator.GetCompiledStyle({sSelectors.back()}, false); + if (NULL == pCol) + continue; - NSCSS::CCompiledStyle::StyleEquation(oStyle, oStyleSetting); + pColgroup->AddCol(pCol); + } while(m_oLightReader.ReadNextSiblingNode2(nDeath)); + } - int nWidth = oStyle.m_oDisplay.GetWidth().ToInt(NSCSS::UnitMeasure::Point, m_oStylesCalculator.GetSizeDeviceWindow().m_ushWidth); - std::wstring wsType = L"dxa"; + if(pColgroup->Empty()) + { + std::map::const_iterator itFound = arNodes.begin()->m_mAttributes.find(L"span"); - //Если ширина указана в %, то используем тип dxa, если же в других единицах измерения, то в pct - #if 1 - // проблема с regex в старом gcc (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52719) - boost::wregex oWidthRegex(L"((width)+)[\\s]*:[\\s]*(.+%)"); - bool bIsWidthPct = boost::regex_search(sSelectors.back().m_wsStyle, oWidthRegex); - #else - std::wregex oWidthRegex(L"((width)+)[\\s]*:[\\s]*(.+%)"); - bool bIsWidthPct = std::regex_search(sSelectors.back().m_wsStyle, oWidthRegex); - #endif + CTableCol *pCol = new CTableCol((arNodes.begin()->m_mAttributes.cend() != itFound) ? NSStringFinder::ToInt(itFound->second, 1) : 1); - if (bIsWidthPct) - wsType = L"pct"; - else - { - nWidth *= 10; - // ограничиваем, примерно как в ms (22 inch) - if (nWidth > 31680) - nWidth = 31680; - } - //------------------------- + if (NULL == pCol) + return; + + CalculateCellStyles(pCol->GetStyle(), arNodes); + + pColgroup->AddCol(pCol); + } + } + + struct TRowspanElement + { + UINT m_unRowSpan; + UINT m_unColumnIndex; + const CTableCell* m_pCell; + + TRowspanElement(UINT unRowSpan, UINT unColumnIndex, const CTableCell* pCell) + : m_unRowSpan(unRowSpan), m_unColumnIndex(unColumnIndex), m_pCell(pCell) + {} + }; + + void ParseTableRows(CTable& oTable, std::vector& sSelectors, CTextSettings& oTS, ERowParseMode eMode) + { + std::vector arRowspanElements; + std::vector arRows; + + int nDeath = m_oLightReader.GetDepth(); + while (m_oLightReader.ReadNextSiblingNode(nDeath)) + { + if (L"tr" != m_oLightReader.GetName()) + continue; + + GetSubClass(NULL, sSelectors); + + CTableRow *pRow = new CTableRow(); + + for (std::vector::iterator itElement = arRowspanElements.begin(); itElement < arRowspanElements.end();) + { + pRow->InsertCell(CTableCell::CreateEmpty(itElement->m_pCell->GetColspan(), true, itElement->m_pCell->GetStyles()), itElement->m_unColumnIndex); - if (nWidth > 0) - oXml->WriteString(L""); + itElement->m_unRowSpan--; + if (1 == itElement->m_unRowSpan) + itElement = arRowspanElements.erase(itElement); else - oXml->WriteString(L""); + ++itElement; + } - if(nColspan != 1) - { - oXml->WriteString(L"WriteString(std::to_wstring(nColspan)); - oXml->WriteString(L"\"/>"); + UINT unColumnIndex = 0; + int nTrDepth = m_oLightReader.GetDepth(); + while (m_oLightReader.ReadNextSiblingNode(nTrDepth)) + { + CTableCell *pCell = new CTableCell(); - j += nColspan - 1; - } + if (NULL == pCell) + continue; - oXml->WriteString(L""); - oXml->WriteString(!sBorders.empty() ? sBorders : L""); - oXml->WriteString(L""); - if(nRowspan != 1) - { - oXml->WriteString(L""); - std::wstring sColspan = std::to_wstring(nColspan); - if(nRowspan == 0) - mTable.push_back({0, j, sColspan}); - else - for(int k = i + 1; k < i + nRowspan; k++) - mTable.push_back({k, j, sColspan}); - } + GetSubClass(pCell->GetData(), sSelectors); + + const std::vector arNewSelectors{(std::vector::const_iterator)std::find_if(sSelectors.begin(), sSelectors.end(), [](const NSCSS::CNode& oNode){ return L"table" == oNode.m_wsName; }), sSelectors.cend()}; - std::wstring wsVerticalAlign = oStyle.m_oDisplay.GetVAlign().ToWString(); + CalculateCellStyles(pCell->GetStyles(), arNewSelectors); - if (!wsVerticalAlign.empty()) - oXml->WriteString(L""); + while(m_oLightReader.MoveToNextAttribute()) + { + if(m_oLightReader.GetName() == L"colspan") + pCell->SetColspan(NSStringFinder::ToInt(m_oLightReader.GetText(), 1), pRow->GetIndex()); + else if(m_oLightReader.GetName() == L"rowspan") + { + pCell->SetRowspan(NSStringFinder::ToInt(m_oLightReader.GetText(), 1)); + + if (1 != pCell->GetRowspan()) + arRowspanElements.push_back({pCell->GetRowspan(), unColumnIndex, pCell}); + } + } - oXml->WriteString(L""); - m_bWasPStyle = false; + m_oLightReader.MoveToElement(); + m_oState.m_bWasPStyle = false; // Читаем th. Ячейка заголовка таблицы. Выравнивание посередине. Выделяется полужирным if(m_oLightReader.GetName() == L"th") { CTextSettings oTSR(oTS); - oTSR.sRStyle += L""; - readStream(oXml, sSelectors, oTSR); + + if (pCell->GetStyles()->m_wsHAlign.empty()) + oTSR.oAdditionalStyle.m_oText.SetAlign(L"center", NEXT_LEVEL); + + oTSR.oAdditionalStyle.m_oFont.SetWeight(L"bold", NEXT_LEVEL); + + readStream(pCell->GetData(), sSelectors, oTSR, true); } - // Читаем td. Ячейка таблицы. Выравнивание вправо + // Читаем td. Ячейка таблицы else if(m_oLightReader.GetName() == L"td") - readStream(oXml, sSelectors, oTS); - sSelectors.pop_back(); - if (m_bInP) - { - wrP(oXml, sSelectors, oTS); - for (const NSCSS::CNode& item : sSelectors) - if (item.m_wsName == L"a") - oXml->WriteString(L""); - oXml->WriteString(L"
"); - m_bInP = false; - } - else if (oXml->GetSubData(oXml->GetCurSize() - 6) != L"") - oXml->WriteString(L""); - m_bWasSpace = false; - oXml->WriteString(L""); - j++; - - // Вставляем ячейки после - it1 = std::find_if(mTable.begin(), mTable.end(), [i, j](const CTc& item){ return item.i == i && item.j == j; }); - it2 = std::find_if(mTable.begin(), mTable.end(), [j] (const CTc& item){ return item.i == 0 && item.j == j; }); - while(it1 != mTable.end() || it2 != mTable.end()) + readStream(pCell->GetData(), sSelectors, oTS, true); + + if (pRow->GetIndex() == MAXCOLUMNSINTABLE - 1) { - oXml->WriteString(L""); - oXml->WriteString(!sBorders.empty() ? sBorders : L""); - oXml->WriteString(L"sGridSpan : it2->sGridSpan); - oXml->WriteString(sCol); - oXml->WriteString(L"\"/>"); - j += stoi(sCol); - it1 = std::find_if(mTable.begin(), mTable.end(), [i, j](const CTc& item){ return item.i == i && item.j == j; }); - it2 = std::find_if(mTable.begin(), mTable.end(), [j] (const CTc& item){ return item.i == 0 && item.j == j; }); + CTextSettings oTrTS{oTS}; + oTrTS.bMergeText = true; + oTrTS.bAddSpaces = true; + m_oState.m_bWasSpace = true; + + while (m_oLightReader.ReadNextSiblingNode(nTrDepth)) + { + if (L"td" != m_oLightReader.GetName() && L"th" != m_oLightReader.GetName()) + continue; + + GetSubClass(pCell->GetData(), sSelectors); + readStream(pCell->GetData(), sSelectors, oTrTS); + sSelectors.pop_back(); + } } - } while(m_oLightReader.ReadNextSiblingNode(nTrDeath)); - oXml->WriteString(L""); - i++; + CloseP(pCell->GetData(), sSelectors); + + pRow->AddCell(pCell); + + sSelectors.pop_back(); + + ++unColumnIndex; + + if (pRow->GetIndex() == MAXCOLUMNSINTABLE) + break; + } + + sSelectors.pop_back(); + arRows.push_back(pRow); } + + oTable.AddRows(arRows, eMode); } - void readTable (NSStringUtils::CStringBuilder* oXml, std::vector& sSelectors, const CTextSettings& oTS) + bool ParseRuby(NSStringUtils::CStringBuilder* oXml, std::vector& sSelectors, CTextSettings& oTS) { if(m_oLightReader.IsEmptyNode()) - return; - - NSStringUtils::CStringBuilder oHead; - NSStringUtils::CStringBuilder oBody; - NSStringUtils::CStringBuilder oFoot; - - NSCSS::CCompiledStyle oStyle = m_oStylesCalculator.GetCompiledStyle(sSelectors, false); + return false; - if (oXml->GetSubData(oXml->GetCurSize() - 6) != L"") - oXml->WriteString(L""); - m_bWasSpace = false; + const int nDepth = m_oLightReader.GetDepth(); - // Начало таблицы - std::wstring wsTable = L""; + #ifdef DISABLE_RUBY_SUPPORT + wrP(oXml, sSelectors, oTS); - int nWidth = oStyle.m_oDisplay.GetWidth().ToInt(NSCSS::UnitMeasure::Point, m_oStylesCalculator.GetSizeDeviceWindow().m_ushWidth); - std::wstring wsAlign = oStyle.m_oDisplay.GetHAlign().ToWString(); + while (m_oLightReader.ReadNextSiblingNode2(nDepth)) + { + GetSubClass(NULL, sSelectors); - if (0 < nWidth) - wsTable += L""; - else if (m_oStylesCalculator.GetSizeDeviceWindow().m_ushWidth != 0) - wsTable += L""; - else - wsTable += L""; + if (L"rp" == sSelectors.back().m_wsName) + { + sSelectors.pop_back(); + continue; + } + else if (L"rt" == sSelectors.back().m_wsName) + readStream(oXml, sSelectors, oTS); + else + readInside(oXml, sSelectors, oTS, sSelectors.back().m_wsName); - if (wsAlign.empty()) - { - NSCSS::CNode oLastNode = sSelectors.back(); sSelectors.pop_back(); + } - NSCSS::CCompiledStyle oTempSettingsStyle = m_oStylesCalculator.GetCompiledStyle(sSelectors, true); + CloseP(oXml, sSelectors); - wsAlign = oTempSettingsStyle.m_oText.GetAlign().ToWString(); + return true; + #endif - if (wsAlign.empty()) - { - NSCSS::CCompiledStyle oTempStyle = m_oStylesCalculator.GetCompiledStyle(sSelectors, false); + NSStringUtils::CStringBuilder oBase; + NSStringUtils::CStringBuilder oRT; - wsAlign = oTempStyle.m_oText.GetAlign().ToWString(); - } + TState oRtState{m_oState}; + oRtState.m_bInP = true; - sSelectors.push_back(oLastNode); - } + TState oBaseState{m_oState}; + oBaseState.m_bInP = true; - if (!oStyle.m_oMargin.Empty() && (0 < oStyle.m_oMargin.GetTop().ToInt() || 0 < oStyle.m_oMargin.GetBottom().ToInt())) + while (m_oLightReader.ReadNextSiblingNode2(nDepth)) { - wsTable += L""; + GetSubClass(NULL, sSelectors); - if (0 < oStyle.m_oMargin.GetTop().ToInt()) - wsTable += L"(oStyle.m_oMargin.GetTop().ToInt() * 10 + 0.5f)) + L"\" w:type=\"dxa\"/>"; + CTextSettings oNewSettings{oTS}; -// if (0 < oStyle.m_pMargin.GetLeftSide()) -// wsTable += L"(oStyle.m_pMargin.GetLeftSide() * 10 + 0.5f)) + L"\" w:type=\"dxa\"/>"; + NSCSS::CCompiledStyle oStyle{m_oStylesCalculator.GetCompiledStyle(sSelectors)}; - if (0 < oStyle.m_oMargin.GetBottom().ToInt()) - wsTable += L"(oStyle.m_oMargin.GetBottom().ToInt() * 10 + 0.5f)) + L"\" w:type=\"dxa\"/>"; + const std::wstring wsHighlight{oStyle.m_oBackground.GetColor().EquateToColor({{{0, 0, 0}, L"black"}, {{0, 0, 255}, L"blue"}, {{0, 255, 255}, L"cyan"}, + {{0, 255, 0}, L"green"}, {{255, 0, 255}, L"magenta"}, {{255, 0, 0}, L"red"}, + {{255, 255, 0}, L"yellow"}, {{255, 255, 255}, L"white"}, {{0, 0, 139}, L"darkBlue"}, + {{0, 139, 139}, L"darkCyan"}, {{0, 100, 0}, L"darkGreen"}, {{139, 0, 139}, L"darkMagenta"}, + {{139, 0, 0}, L"darkRed"}, {{128, 128, 0}, L"darkYellow"},{{169, 169, 169}, L"darkGray"}, + {{211, 211, 211}, L"lightGray"}})}; -// if (0 < oStyle.m_pMargin.GetRightSide()) -// wsTable += L"(oStyle.m_pMargin.GetRightSide() * 10 + 0.5f)) + L"\" w:type=\"dxa\"/>"; + if (L"none" != wsHighlight) + oNewSettings.oAdditionalStyle.m_oText.SetHighlight(oStyle.m_oBackground.GetColor().ToWString(), NEXT_LEVEL); + // oNewSettings.AddRStyle(L""); - wsTable += L""; + if (L"rt" == sSelectors.back().m_wsName) + { + std::swap(m_oState, oRtState); + readStream(&oRT, sSelectors, oNewSettings); + std::swap(m_oState, oRtState); + } + else if (L"rp" == sSelectors.back().m_wsName) + { + sSelectors.pop_back(); + continue; + } + else if (L"#text" == sSelectors.back().m_wsName) + { + std::swap(m_oState, oBaseState); + readInside(&oBase, sSelectors, oNewSettings, sSelectors.back().m_wsName); + std::swap(m_oState, oBaseState); + } + sSelectors.pop_back(); } - if (!wsAlign.empty()) - wsTable += L""; + WriteSpace(&oBase); - wsTable += L""; - wsTable += L""; + wrP(oXml, sSelectors, oTS); - // borders - std::wstring sBorders; - oStyle.m_oBorder.Unblock(); - if (oStyle.m_oBorder.Empty()) - { - sBorders = L""; - } - else + if (0 != oRT.GetSize()) { - if (oStyle.m_oBorder.EqualSides()) - { - std::wstring sColor = oStyle.m_oBorder.GetBottomBorder().GetColor().ToWString(); - std::wstring sSz = oStyle.m_oBorder.GetBottomBorder().GetWidth().ToWString(); - std::wstring sStyle = oStyle.m_oBorder.GetBottomBorder().GetStyle().ToWString(); + NSCSS::CCompiledStyle oStyle{m_oStylesCalculator.GetCompiledStyle(sSelectors)}; - sBorders = L"" + - L"" + - L"" + - L"" + - L"" + - L""; - } - else - { - std::wstring sColorLeftSide = oStyle.m_oBorder.GetLeftBorder().GetColor().ToWString(); - std::wstring sSzLeftSide = oStyle.m_oBorder.GetLeftBorder().GetWidth().ToWString(); - std::wstring sStyleLeftSide = oStyle.m_oBorder.GetLeftBorder().GetStyle().ToWString(); - std::wstring sColorTopSide = oStyle.m_oBorder.GetTopBorder().GetColor().ToWString(); - std::wstring sSzTopSide = oStyle.m_oBorder.GetTopBorder().GetWidth().ToWString(); - std::wstring sStyleTopSide = oStyle.m_oBorder.GetTopBorder().GetStyle().ToWString(); - std::wstring sColorRightSide = oStyle.m_oBorder.GetRightBorder().GetColor().ToWString(); - std::wstring sSzRightSide = oStyle.m_oBorder.GetRightBorder().GetWidth().ToWString(); - std::wstring sStyleRightSide = oStyle.m_oBorder.GetRightBorder().GetStyle().ToWString(); - std::wstring sColorBottomSide = oStyle.m_oBorder.GetBottomBorder().GetColor().ToWString(); - std::wstring sSzBottomSide = oStyle.m_oBorder.GetBottomBorder().GetWidth().ToWString(); - std::wstring sStyleBottomSide = oStyle.m_oBorder.GetBottomBorder().GetColor().ToWString(); + int nFontSize = 24; + + if (!oStyle.m_oFont.GetSize().Empty() && !oStyle.m_oFont.GetSize().Zero()) + nFontSize = oStyle.m_oFont.GetSize().ToInt(NSCSS::Point) * 2; + + bool bConsistsChineseCharacters = false; + + const std::vector::const_reverse_iterator oFound{std::find_if(sSelectors.crbegin(), sSelectors.crend(), [](const NSCSS::CNode& oNode){ return oNode.m_mAttributes.cend() != oNode.m_mAttributes.find(L"lang");})}; - sBorders = L"" + - L"" + - L"" + - L""; + if (sSelectors.crend() != oFound) + { + const size_t unFound{oFound->m_mAttributes.at(L"lang").find(L"-")}; + if (std::wstring::npos != unFound) + bConsistsChineseCharacters = ConsistsChineseCharacters(oFound->m_mAttributes.at(L"lang").substr(0, unFound)); } + + OpenR(oXml); + oXml->WriteString(L""); + oXml->WriteString(L""); + WriteToStringBuilder(oRT, *oXml); + oXml->WriteString(L""); + oXml->WriteString(L""); + WriteToStringBuilder(oBase, *oXml); + oXml->WriteString(L""); + oXml->WriteString(L""); + CloseR(oXml); } + else + WriteToStringBuilder(oBase, *oXml); - oXml->WriteString(wsTable); + CloseP(oXml, sSelectors); - /* - NSCSS::CCompiledStyle oStyleSetting = m_oStylesCalculator.GetCompiledStyle(sSelectors, true); - oStyle = m_oStylesCalculator.GetCompiledStyle(sSelectors); - NSCSS::CCompiledStyle::StyleEquation(oStyle, oStyleSetting); - m_oXmlStyle.WriteLitePStyle(oStyleSetting); - std::wstring sPSettings = m_oXmlStyle.GetStyle(); - m_oXmlStyle.Clear(); - size_t nBdr = sPSettings.find(L""); - if (nBdr != std::wstring::npos) + return true; + } + + bool ParseTable(NSStringUtils::CStringBuilder* oXml, std::vector& sSelectors, const CTextSettings& oTS) + { + if(m_oLightReader.IsEmptyNode()) + return false; + + CTable oTable; + CTextSettings oTextSettings{oTS}; + oTextSettings.sPStyle.clear(); + + NSCSS::CCompiledStyle oStyle; + m_oStylesCalculator.GetCompiledStyle(oStyle, sSelectors); + + //Table styles + std::wstring wsFrame; + + for (const std::pair& oArgument : sSelectors.back().m_mAttributes) { - nBdr += 8; - size_t nBdrEnd = sPSettings.find(L"", nBdr); - if (nBdrEnd != std::wstring::npos) + if (oStyle.m_oBorder.Empty() && L"border" == oArgument.first) { - sBorders = sPSettings.substr(nBdr, nBdrEnd - nBdr); - size_t nSpace = sBorders.find(L"w:space=\""); - while (nSpace != std::wstring::npos) + const int nWidth = NSStringFinder::ToInt(oArgument.second); + + if (0 < nWidth) + { + oStyle.m_oBorder.SetStyle(L"outset", 0, true); + oStyle.m_oBorder.SetWidth(nWidth, 0, true); + oStyle.m_oBorder.SetColor(L"auto", 0, true); + oTable.SetRules(L"all"); + } + else { - nSpace += 9; - size_t nSpaceEnd = sBorders.find(L'\"', nSpace); - sBorders.replace(nSpace, nSpaceEnd - nSpace, L"0"); - nSpace = sBorders.find(L"w:space=\"", nSpace); + oStyle.m_oBorder.SetNone(0, true); + oTable.SetRules(L"none"); } } + else if (L"cellpadding" == oArgument.first) + oStyle.m_oPadding.SetValues(oArgument.second + L"px", 0, true); + else if (L"rules" == oArgument.first) + oTable.SetRules(oArgument.second); + else if (L"frame" == oArgument.first) + wsFrame = oArgument.second; } - */ - int nDeath = m_oLightReader.GetDepth(); - while(m_oLightReader.ReadNextSiblingNode(nDeath)) + if (!wsFrame.empty() && oStyle.m_oBorder.Empty()) { - std::wstring sName = m_oLightReader.GetName(); - GetSubClass(oXml, sSelectors); - // Заголовок таблицы - if(sName == L"caption") + #define SetDefaultBorderSide(side) \ + oStyle.m_oBorder.SetStyle##side(L"solid", 0, true); \ + oStyle.m_oBorder.SetWidth##side(1, 0, true); \ + oStyle.m_oBorder.SetColor##side(L"black", 0, true); + + if (NSStringFinder::Equals(L"border", wsFrame)) { - size_t nHyp = 0; - if (!m_bInP) - { - oXml->WriteString(L""); - for (const NSCSS::CNode& item : sSelectors) - { - if (item.m_wsName == L"a") - { - oXml->WriteString(L""); - nHyp++; - } - } - m_bInP = true; - m_bWasPStyle = false; - } - // Заголовок таблицы выравнивание посередине - CTextSettings oTSP { oTS.bBdo, oTS.bPre, oTS.nLi, oTS.sRStyle, oTS.sPStyle + L"" }; - readStream(oXml, sSelectors, oTSP); - if (m_bInP) - { - for (size_t i = 0; i < nHyp; i++) - oXml->WriteString(L""); - oXml->WriteString(L""); - m_bInP = false; - m_bWasPStyle = false; - } - m_bWasSpace = false; + SetDefaultBorderSide() + } + else if (NSStringFinder::Equals(L"above", wsFrame)) + { + SetDefaultBorderSide(TopSide) + } + else if (NSStringFinder::Equals(L"below", wsFrame)) + { + SetDefaultBorderSide(BottomSide) } + else if (NSStringFinder::Equals(L"hsides", wsFrame)) + { + SetDefaultBorderSide(TopSide) + SetDefaultBorderSide(BottomSide) + } + else if (NSStringFinder::Equals(L"vsides", wsFrame)) + { + SetDefaultBorderSide(LeftSide) + SetDefaultBorderSide(RightSide) + } + else if (NSStringFinder::Equals(L"rhs", wsFrame)) + { + SetDefaultBorderSide(RightSide) + } + else if (NSStringFinder::Equals(L"lhs", wsFrame)) + { + SetDefaultBorderSide(LeftSide) + } + } + + if (oStyle.m_oBorder.GetCollapse() == NSCSS::NSProperties::BorderCollapse::Collapse) + oTable.SetCellSpacing(0); + else if (sSelectors.back().m_mAttributes.end() != sSelectors.back().m_mAttributes.find(L"cellspacing")) + oTable.SetCellSpacing(NSStringFinder::ToInt(sSelectors.back().m_mAttributes[L"cellspacing"])); + else if (oStyle.m_oBorder.GetCollapse() == NSCSS::NSProperties::BorderCollapse::Separate) + oTable.SetCellSpacing(15); + + oTable.SetWidth(oStyle.m_oDisplay.GetWidth()); + oTable.SetBorder(oStyle.m_oBorder); + oTable.SetPadding(oStyle.m_oPadding); + oTable.SetMargin(oStyle.m_oMargin); + oTable.SetAlign(oStyle.m_oDisplay.GetHAlign().ToWString()); + //------ + + int nDeath = m_oLightReader.GetDepth(); + while(m_oLightReader.ReadNextSiblingNode(nDeath)) + { + const std::wstring sName = m_oLightReader.GetName(); + GetSubClass(oXml, sSelectors); + + if(sName == L"caption") + ParseTableCaption(oTable, sSelectors, oTS); if(sName == L"thead") - readTr(&oHead, sSelectors, oTS, sBorders); - else if(sName == L"tbody") - readTr(&oBody, sSelectors, oTS, sBorders); + ParseTableRows(oTable, sSelectors, oTextSettings, ERowParseMode::ParseModeHeader); + if(sName == L"tbody") + ParseTableRows(oTable, sSelectors, oTextSettings, ERowParseMode::ParseModeBody); else if(sName == L"tfoot") - readTr(&oFoot, sSelectors, oTS, sBorders); + ParseTableRows(oTable, sSelectors, oTextSettings, ERowParseMode::ParseModeFoother); + else if (sName == L"colgroup") + ParseTableColspan(oTable); + sSelectors.pop_back(); } - // Конец таблицы - oXml->WriteString(oHead.GetData()); - oXml->WriteString(oBody.GetData()); - oXml->WriteString(oFoot.GetData()); - oXml->WriteString(L""); + oTable.Shorten(); + oTable.CompleteTable(); + oTable.ConvertToOOXML(*oXml); + WriteEmptyParagraph(oXml, true); + + return true; } - void readInput (NSStringUtils::CStringBuilder* oXml, std::vector& sSelectors, const CTextSettings& oTS) + bool readInput (NSStringUtils::CStringBuilder* oXml, std::vector& sSelectors, CTextSettings& oTS) { std::wstring sValue; std::wstring sAlt; @@ -1507,36 +3830,38 @@ class CHtmlFile2_Private } m_oLightReader.MoveToElement(); if(sType == L"hidden") - return; + return false; if(sValue.empty()) sValue = sAlt; if(!sValue.empty()) { wrP(oXml, sSelectors, oTS); - oXml->WriteString(L""); - wrR(oXml, sSelectors, oTS); - oXml->WriteString(L""); + OpenR(oXml); + wrRPr(oXml, sSelectors, oTS); + OpenT(oXml); oXml->WriteEncodeXmlString(sValue + L' '); - oXml->WriteString(L""); + CloseT(oXml); + CloseR(oXml); } - readStream(oXml, sSelectors, oTS); + + return readStream(oXml, sSelectors, oTS, ElementInTable(sSelectors)); } - void readLi (NSStringUtils::CStringBuilder* oXml, std::vector& sSelectors, const CTextSettings& oTS, bool bType) + bool readLi (NSStringUtils::CStringBuilder* oXml, std::vector& sSelectors, CTextSettings& oTS, bool bType) { if(m_oLightReader.IsEmptyNode()) - return; + return false; - std::wstring sStart = L"1"; + int nStart = 1; while(m_oLightReader.MoveToNextAttribute()) if(m_oLightReader.GetName() == L"start") - sStart = m_oLightReader.GetText(); + nStart = NSStringFinder::ToInt(m_oLightReader.GetText(), 1); m_oLightReader.MoveToElement(); int nDeath = m_oLightReader.GetDepth(); while(m_oLightReader.ReadNextSiblingNode(nDeath)) { - std::wstring sName = m_oLightReader.GetName(); + const std::wstring sName = m_oLightReader.GetName(); if (sName == L"optgroup") { GetSubClass(oXml, sSelectors); @@ -1544,21 +3869,15 @@ class CHtmlFile2_Private { if(m_oLightReader.GetName() != L"label") continue; - if (m_bInP) - { - for (const NSCSS::CNode& item : sSelectors) - if (item.m_wsName == L"a") - oXml->WriteString(L""); - oXml->WriteString(L""); - m_bInP = false; - } - m_bWasSpace = false; + + CloseP(oXml, sSelectors); wrP(oXml, sSelectors, oTS); - oXml->WriteString(L""); - wrR(oXml, sSelectors, oTS); - oXml->WriteString(L""); + OpenR(oXml); + wrRPr(oXml, sSelectors, oTS); + OpenT(oXml); oXml->WriteEncodeXmlString(m_oLightReader.GetText()); - oXml->WriteString(L""); + CloseT(oXml); + CloseR(oXml); } m_oLightReader.MoveToElement(); readLi(oXml, sSelectors, oTS, true); @@ -1571,65 +3890,99 @@ class CHtmlFile2_Private continue; } + CloseP(oXml, sSelectors); + + CTextSettings oTSLiP(oTS); + + std::wstring wsValue; + const std::wstring wsParentName{(!sSelectors.empty()) ? sSelectors.back().m_wsName : L""}; + GetSubClass(oXml, sSelectors); + + std::wstring wsArgumentName; + while(m_oLightReader.MoveToNextAttribute()) - if(m_oLightReader.GetName() == L"value") - sStart = m_oLightReader.GetText(); + { + wsArgumentName = m_oLightReader.GetName(); + + if(L"value" == wsArgumentName && L"datalist" == wsParentName) + { + if (sName == L"option") + wsValue = m_oLightReader.GetText(); + else + nStart = NSStringFinder::ToInt(m_oLightReader.GetText(), 1); + } + else if (L"disabled" == wsArgumentName) + oTSLiP.oAdditionalStyle.m_oText.SetColor(L"#808080", NEXT_LEVEL); + else if (L"selected" == wsArgumentName) + oTSLiP.oAdditionalStyle.m_oText.SetDecoration(L"underline", NEXT_LEVEL); + // oTSLiP.AddRStyle(L""); + } m_oLightReader.MoveToElement(); - if (m_bInP) + if (std::wstring::npos != oTS.sPStyle.find(L"")) { - for (const NSCSS::CNode& item : sSelectors) - if (item.m_wsName == L"a") - oXml->WriteString(L""); - oXml->WriteString(L""); - m_bInP = false; + wrP(oXml, sSelectors, oTS); + CloseP(oXml, sSelectors); + oTSLiP.sPStyle.clear(); } - m_bWasSpace = false; - CTextSettings oTSLiP(oTS); + oTSLiP.nLi++; + + const std::wstring wsOldPStyle{oTSLiP.sPStyle}; + oTSLiP.sPStyle += L""; - readStream(oXml, sSelectors, oTSLiP); - if (m_bInP) + (bType ? L"1" : std::to_wstring(m_nNumberingId + 1)) + L"\"/>"; + + wrP(oXml, sSelectors, oTSLiP); + oTSLiP.sPStyle = wsOldPStyle; + + if (!wsValue.empty()) { - for (const NSCSS::CNode& item : sSelectors) - if (item.m_wsName == L"a") - oXml->WriteString(L""); - oXml->WriteString(L""); - m_bInP = false; + OpenR(oXml); + OpenT(oXml); + oXml->WriteEncodeXmlString(wsValue); + CloseT(oXml); + CloseR(oXml); } - m_bWasSpace = false; + + readStream(oXml, sSelectors, oTSLiP); + + CloseP(oXml, sSelectors); + sSelectors.pop_back(); } // Нумерованный список if(!bType) { + const std::wstring wsStart(std::to_wstring(nStart)); m_oNumberXml.WriteString(L""); + m_oNumberXml.WriteString(wsStart); + m_oNumberXml.WriteString(L"\"/>"); } + + return true; } - void readA (NSStringUtils::CStringBuilder* oXml, std::vector& sSelectors, const CTextSettings& oTS, std::wstring& sNote) + bool readA (NSStringUtils::CStringBuilder* oXml, std::vector& sSelectors, CTextSettings& oTS, std::wstring& sNote) { std::wstring sRef; std::wstring sAlt; @@ -1646,16 +3999,7 @@ class CHtmlFile2_Private bCross = true; } else if(sName == L"name") - { - std::wstring sCrossId = std::to_wstring(m_nCrossId++); - oXml->WriteString(L"WriteString(sCrossId); - oXml->WriteString(L"\" w:name=\""); - oXml->WriteString(sText); - oXml->WriteString(L"\"/>WriteString(sCrossId); - oXml->WriteString(L"\"/>"); - } + WriteBookmark(oXml, sText); else if(sName == L"alt") sAlt = sText; else if (sName == L"style" && sText.find(L"mso-footnote-id") != std::wstring::npos) @@ -1664,25 +4008,22 @@ class CHtmlFile2_Private sFootnote = L"href"; } m_oLightReader.MoveToElement(); + if(sNote.empty()) sNote = sRef; if (bCross && sFootnote == L"href") sFootnote = sRef.substr(sRef.find('#') + 1); - if (!m_bInP) - { - oXml->WriteString(L""); - for (size_t i = 0; i < sSelectors.size() - 1; i++) - if (sSelectors[i].m_wsName == L"a") - oXml->WriteString(L""); - m_bInP = true; - m_bWasPStyle = false; - } - wrP(oXml, sSelectors, oTS); + if (!OpenP(oXml)) + CloseR(oXml); + else + wrP(oXml, sSelectors, oTS); + // Перекрестная ссылка внутри файла if(bCross) { + m_oState.m_bInHyperlink = true; oXml->WriteString(L"WriteEncodeXmlString(sRef); oRelationshipXml->WriteString(L"\" TargetMode=\"External\"/>"); + m_oState.m_bInHyperlink = true; // Пишем в document.xml oXml->WriteString(L"WriteEncodeXmlString(sNote); @@ -1713,15 +4055,21 @@ class CHtmlFile2_Private if(!readStream(oXml, sSelectors, oTS)) { - oXml->WriteString(L""); - wrR(oXml, sSelectors, oTS); - oXml->WriteString(L""); - oXml->WriteEncodeXmlString(sAlt); - oXml->WriteString(L""); + OpenR(oXml); + wrRPr(oXml, sSelectors, oTS); + OpenT(oXml); + oXml->WriteEncodeXmlString(!sAlt.empty() ? sAlt : L" "); + CloseT(oXml); + CloseR(oXml); } - if (m_bInP) + + if (m_oState.m_bInP) { - oXml->WriteString(L""); + if (m_oState.m_bInHyperlink) + { + oXml->WriteString(L""); + m_oState.m_bInHyperlink = false; + } bool bFootnote = false; if (sSelectors.size() > 1) @@ -1736,16 +4084,27 @@ class CHtmlFile2_Private if (!bFootnote) { std::wstring sFootnoteID = std::to_wstring(m_nFootnoteId++); - oXml->WriteString(L"WriteString(L"WriteString(sFootnoteID); - oXml->WriteString(L"\"/>"); + oXml->WriteString(L"\"/>"); + CloseR(oXml); m_mFootnotes.insert(std::make_pair(sFootnote, sFootnoteID)); } else - oXml->WriteString(L""); + { + OpenR(oXml); + oXml->WriteString(L""); + CloseR(oXml); + } } + + // CloseP(oXml, sSelectors); } - sNote = L""; + + sNote.clear(); + + return true; } bool readBase64 (const std::wstring& sSrcM, std::wstring& sExtention) @@ -1761,29 +4120,41 @@ class CHtmlFile2_Private if (sExtention == L"octet-stream") sExtention = L"jpg"; + if (NotValidExtension(sExtention)) + return bRes; + nBase = sSrcM.find(L"base64", nEndBase); if (nBase == std::wstring::npos) return bRes; - NSFile::CFileBinary oImageWriter; - std::wstring sImageName = std::to_wstring(m_arrImages.size()) + L'.' + sExtention; - if (oImageWriter.CreateFileW(m_sDst + L"/word/media/i" + sImageName)) + int nOffset = nBase + 7; + int nSrcLen = (int)(sSrcM.length() - nBase + 1); + int nDecodeLen = NSBase64::Base64DecodeGetRequiredLength(nSrcLen); + if (nDecodeLen != 0) { - std::string sSrc = U_TO_UTF8(sSrcM); - std::string sBase64 = sSrc.substr(nBase + 7); - int nSrcLen = (int)sBase64.length(); - int nDecodeLen = NSBase64::Base64DecodeGetRequiredLength(nSrcLen); - if (nDecodeLen != 0) + BYTE* pImageData = new BYTE[nDecodeLen]; + + if (!pImageData || FALSE == NSBase64::Base64Decode(sSrcM.c_str() + nOffset, nSrcLen, pImageData, &nDecodeLen)) + return bRes; + + if (L"svg" == sExtention || L"svg+xml" == sExtention) { - BYTE* pImageData = new BYTE[nDecodeLen]; - if (TRUE == NSBase64::Base64Decode(sBase64.c_str(), nSrcLen, pImageData, &nDecodeLen)) - { - oImageWriter.WriteFile(pImageData, (DWORD)nDecodeLen); - bRes = true; - } - RELEASEARRAYOBJECTS(pImageData); + std::wstring wsSvg(pImageData, pImageData + nDecodeLen); + bRes = readSVG(wsSvg); + sExtention = L"png"; } - oImageWriter.CloseFile(); + else + { + NSFile::CFileBinary oImageWriter; + std::wstring sImageName = std::to_wstring(m_arrImages.size()) + L'.' + sExtention; + + if (oImageWriter.CreateFileW(m_sDst + L"/word/media/i" + sImageName)) + bRes = oImageWriter.WriteFile(pImageData, (DWORD)nDecodeLen); + + oImageWriter.CloseFile(); + } + + RELEASEARRAYOBJECTS(pImageData); } return bRes; @@ -1815,47 +4186,82 @@ class CHtmlFile2_Private sExtention != L"tga" && sExtention != L"tpic" && sExtention != L"tiff" && sExtention != L"tif" && sExtention != L"wmf" && sExtention != L"wmz"; } - void ImageAlternative(NSStringUtils::CStringBuilder* oXml, std::vector& sSelectors, const CTextSettings& oTS, const std::wstring& wsAlt) + void ImageAlternative(NSStringUtils::CStringBuilder* oXml, std::vector& sSelectors, const CTextSettings& oTS, const std::wstring& wsAlt, const std::wstring& wsSrc, const TImageData& oImageData) { - if (wsAlt.empty()) - return; + m_oDocXmlRels.WriteString(L""); - wrP(oXml, sSelectors, oTS); - oXml->WriteString(L""); - wrR(oXml, sSelectors, oTS); - oXml->WriteString(L""); - oXml->WriteEncodeXmlString(wsAlt); - oXml->WriteString(L""); + const bool bOpenedP{OpenP(oXml)}; + + WriteEmptyImage(oXml, (0 != oImageData.m_unWidth) ? oImageData.m_unWidth : DEFAULT_IMAGE_WIDTH, (0 != oImageData.m_unHeight) ? oImageData.m_unHeight : DEFAULT_IMAGE_HEIGHT, L"", wsAlt); + + if (bOpenedP) + CloseP(oXml, sSelectors); } - void readImage (NSStringUtils::CStringBuilder* oXml, std::vector& sSelectors, const CTextSettings& oTS) + bool readImage (NSStringUtils::CStringBuilder* oXml, std::vector& sSelectors, const CTextSettings& oTS) { std::wstring wsAlt, sSrcM; bool bRes = false; + TImageData oImageData; + + #define READ_IMAGE_DATA(data) \ + { \ + NSCSS::NSProperties::CDigit oDigit; \ + if (oDigit.SetValue(m_oLightReader.GetText())) \ + { \ + if (NSCSS::UnitMeasure::None == oDigit.GetUnitMeasure()) \ + data = static_cast(NSCSS::CUnitMeasureConverter::ConvertPx(oDigit.ToDouble(), NSCSS::Inch, 96) * 914400); \ + else \ + data = static_cast(oDigit.ToDouble(NSCSS::Inch) * 914400); \ + } \ + }\ + while (m_oLightReader.MoveToNextAttribute()) { - std::wstring wsName = m_oLightReader.GetName(); + const std::wstring wsName = m_oLightReader.GetName(); if (wsName == L"alt") wsAlt = m_oLightReader.GetText(); else if (wsName == L"src") sSrcM = m_oLightReader.GetText(); + else if (wsName == L"width") + READ_IMAGE_DATA(oImageData.m_unWidth) + else if (wsName == L"height") + READ_IMAGE_DATA(oImageData.m_unHeight) + else if (wsName == L"hspace") + READ_IMAGE_DATA(oImageData.m_nHSpace) + else if (wsName == L"vspace") + READ_IMAGE_DATA(oImageData.m_nVSpace) } m_oLightReader.MoveToElement(); if (sSrcM.empty()) { - ImageAlternative(oXml, sSelectors, oTS, wsAlt); - return; + ImageAlternative(oXml, sSelectors, oTS, wsAlt, sSrcM, oImageData); + return true; } - bool bIsAllowExternalLocalFiles = true; - if (NSProcessEnv::IsPresent(NSProcessEnv::Converter::gc_allowPrivateIP)) - bIsAllowExternalLocalFiles = NSProcessEnv::GetBoolValue(NSProcessEnv::Converter::gc_allowPrivateIP); + const bool bIsAllowExternalLocalFiles = GetStatusUsingExternalLocalFiles(); + + bool bIsBase64 = false; + if (sSrcM.length() > 4 && sSrcM.substr(0, 4) == L"data" && sSrcM.find(L"/", 4) != std::wstring::npos) + bIsBase64 = true; + + if (!bIsBase64 && (sSrcM.length() <= 7 || L"http" != sSrcM.substr(0, 4))) + { + sSrcM = NSSystemPath::ShortenPath(sSrcM); + + if (!CanUseThisPath(sSrcM, m_sSrc, m_sCore, bIsAllowExternalLocalFiles)) + return true; + } int nImageId = -1; std::wstring sImageSrc, sExtention; // Предполагаем картинку в Base64 - if (sSrcM.length() > 4 && sSrcM.substr(0, 4) == L"data" && sSrcM.find(L"/", 4) != std::wstring::npos) + if (bIsBase64) bRes = readBase64(sSrcM, sExtention); if (!bRes) @@ -1865,8 +4271,8 @@ class CHtmlFile2_Private std::transform(sExtention.begin(), sExtention.end(), sExtention.begin(), tolower); if (NotValidExtension(sExtention)) { - ImageAlternative(oXml, sSelectors, oTS, wsAlt); - return; + ImageAlternative(oXml, sSelectors, oTS, wsAlt, sSrcM, oImageData); + return true; } // Проверка на повтор @@ -1911,85 +4317,62 @@ class CHtmlFile2_Private } if (!bRes) - ImageAlternative(oXml, sSelectors, oTS, wsAlt); + ImageAlternative(oXml, sSelectors, oTS, wsAlt, sSrcM, oImageData); else { wrP(oXml, sSelectors, oTS); - ImageRels(oXml, nImageId, sImageSrc, sExtention); + ImageRels(oXml, nImageId, sImageSrc, sExtention, oImageData); } + + return true; } - std::wstring wrP(NSStringUtils::CStringBuilder* oXml, std::vector& sSelectors, const CTextSettings& oTS) + std::wstring wrP(NSStringUtils::CStringBuilder* oXml, const std::vector& sSelectors, const CTextSettings& oTS) { - if (!m_bInP) - { - oXml->WriteString(L""); - for (const NSCSS::CNode& item : sSelectors) - if (item.m_wsName == L"a") - oXml->WriteString(L""); - m_bInP = true; - m_bWasPStyle = false; - } - if (m_bWasPStyle) + OpenP(oXml); + + if (m_oState.m_bWasPStyle) return L""; - oXml->WriteString(L"> temporary; - size_t i = 0; - while(i != sSelectors.size()) - { - if (sSelectors[i].Empty() && rStyle.find(L' ' + sSelectors[i].m_wsName + L' ') != std::wstring::npos) - { - temporary.push_back(std::make_pair(i, sSelectors[i])); - sSelectors.erase(sSelectors.begin() + i); - } - else - i++; - } - NSCSS::CCompiledStyle oStyleSetting = m_oStylesCalculator.GetCompiledStyle(sSelectors, true); + NSCSS::CCompiledStyle oStyleSetting{oTS.oAdditionalStyle}; NSCSS::CCompiledStyle oStyle = m_oStylesCalculator.GetCompiledStyle(sSelectors); NSCSS::CCompiledStyle::StyleEquation(oStyle, oStyleSetting); std::wstring sPStyle = GetStyle(oStyle, true); + if (sPStyle.empty() && !ElementInTable(sSelectors)) + sPStyle = L"normal-web"; + + if (sPStyle.empty() && oTS.sPStyle.empty()) + return L""; + m_oXmlStyle.WriteLitePStyle(oStyleSetting); - std::wstring sPSettings = m_oXmlStyle.GetStyle(); + const std::wstring sPSettings = m_oXmlStyle.GetStyle(); m_oXmlStyle.Clear(); - for(int i = temporary.size() - 1; i >= 0; i--) - sSelectors.insert(sSelectors.begin() + temporary[i].first, temporary[i].second); + oXml->WriteNodeBegin(L"w:pPr"); - // Если в таблице, то игнориуются Paragraph Borders - bool bInTable = false; - for (const NSCSS::CNode& item : sSelectors) - if (item.m_wsName == L"table") - bInTable = true; - if (bInTable) + if (!sPStyle.empty()) { - size_t nBdr = sPSettings.find(L""); - if (nBdr != std::wstring::npos) - { - size_t nBdrEnd = sPSettings.find(L"", nBdr); - if (nBdrEnd != std::wstring::npos) - sPSettings.erase(nBdr, nBdrEnd + 9 - nBdr); - } + oXml->WriteString(L"WriteString(sPStyle); + oXml->WriteString(L"\"/>"); } - oXml->WriteString(sPStyle); - oXml->WriteString(L"\"/>"); - oXml->WriteString(oTS.sPStyle + L' ' + sPSettings); - oXml->WriteString(L""); - m_bWasPStyle = true; + oXml->WriteString(oTS.sPStyle + sPSettings); + oXml->WriteNodeEnd(L"w:pPr"); + m_oState.m_bWasPStyle = true; + return sPStyle; } - std::wstring wrR(NSStringUtils::CStringBuilder* oXml, std::vector& sSelectors, const CTextSettings& oTS) + std::wstring wrRPr(NSStringUtils::CStringBuilder* oXml, const std::vector& sSelectors, const CTextSettings& oTS) { - if (!m_bInP) + if (!m_oState.m_bInP) return L""; - NSCSS::CCompiledStyle oStyleSetting = m_oStylesCalculator.GetCompiledStyle(sSelectors, true); + NSCSS::CCompiledStyle oStyleSetting{oTS.oAdditionalStyle}; NSCSS::CCompiledStyle oStyle = m_oStylesCalculator.GetCompiledStyle(sSelectors); NSCSS::CCompiledStyle::StyleEquation(oStyle, oStyleSetting); @@ -2000,16 +4383,138 @@ class CHtmlFile2_Private const std::wstring sRSettings = m_oXmlStyle.GetStyle(); m_oXmlStyle.Clear(); - oXml->WriteString(L"WriteString(sRStyle); - oXml->WriteString(L"\"/>"); + std::wstring wsFontSize; + + const int nCalculatedFontChange{CalculateFontChange(sSelectors)}; + + if (0 != nCalculatedFontChange) + { + int nFontSizeLevel{static_cast((oStyle.m_oFont.Empty()) ? 3 : GetFontSizeLevel(oStyle.m_oFont.GetSize().ToInt(NSCSS::Point) * 2))}; + + nFontSizeLevel += nCalculatedFontChange; + + const UINT unFontSize{GetFontSizeByLevel(nFontSizeLevel)}; + + wsFontSize += L""; + } + + if (!sRStyle.empty() || CTextSettings::Normal != oTS.eTextMode || !wsFontSize.empty() || !sRSettings.empty()) + { + oXml->WriteString(L""); + if (!sRStyle.empty()) + { + oXml->WriteString(L"WriteString(sRStyle); + oXml->WriteString(L"\"/>"); + } + + switch (oTS.eTextMode) + { + case CTextSettings::Subscript: + { + oXml->WriteString(L""); + break; + } + case CTextSettings::Superscript: + { + oXml->WriteString(L""); + break; + } + default: + break; + } - oXml->WriteString(oTS.sRStyle + L' ' + sRSettings); - oXml->WriteString(L""); + oXml->WriteString(sRSettings + wsFontSize); + oXml->WriteString(L""); + } return sRStyle; } - void ImageRels (NSStringUtils::CStringBuilder* oXml, int nImageId, const std::wstring& sImageSrc, const std::wstring& sExtention) + void WriteImage(NSStringUtils::CStringBuilder* pXml, const TImageData& oImageData, const std::wstring& wsId) + { + if (NULL == pXml) + return; + + OpenR(pXml); + + // Пишем в document.xml + if (oImageData.ZeroSpaces()) + { + pXml->WriteString(L"WriteString(std::to_wstring(oImageData.m_unWidth)); + pXml->WriteString(L"\" cy=\""); + pXml->WriteString(std::to_wstring(oImageData.m_unHeight)); + pXml->WriteString(L"\"/>WriteString(wsId); + pXml->WriteString(L"\" name=\"Picture " + wsId + L"\"/>WriteString(wsId); + pXml->WriteString(L"\" name=\"Picture " + wsId + L"\"/>WriteString(wsId); + pXml->WriteString(L"\"/>WriteString(std::to_wstring(oImageData.m_unWidth)); + pXml->WriteString(L"\" cy=\""); + pXml->WriteString(std::to_wstring(oImageData.m_unHeight)); + pXml->WriteString(L"\"/>"); + } + else + { + pXml->WriteString(L""); + pXml->WriteString(L""); + pXml->WriteString(L""); + pXml->WriteString(L"" + oImageData.m_wsAlign + L""); + pXml->WriteString(L"0"); + pXml->WriteString(L""); + pXml->WriteString(L""); + pXml->WriteString(L""); + pXml->WriteString(L""); + pXml->WriteString(L""); + pXml->WriteString(L""); + pXml->WriteString(L""); + pXml->WriteString(L""); + pXml->WriteString(L""); + pXml->WriteString(L""); + pXml->WriteString(L""); + pXml->WriteString(L""); + pXml->WriteString(L""); + pXml->WriteString(L"00"); + pXml->WriteString(L""); + } + + CloseR(pXml); + } + + #define WRITE_ENCODE_ARGUMENT(ptrStringBuilder, argumentName, argumentValue) \ + ptrStringBuilder->WriteString(L" " + std::wstring(argumentName) + L"=\""); \ + ptrStringBuilder->WriteEncodeXmlString(argumentValue); \ + ptrStringBuilder->WriteString(L"\"") + + void WriteEmptyImage(NSStringUtils::CStringBuilder* pXml, int nWidth, int nHeight, const std::wstring& wsName = L"", const std::wstring& wsDescr = L"") + { + if (NULL == pXml) + return; + + OpenR(pXml); + + pXml->WriteString(L""); + pXml->WriteString(L"WriteString(L"/>"); + pXml->WriteString(L""); + pXml->WriteString(L""); + pXml->WriteString(L"WriteString(L"/>"); + pXml->WriteString(L""); + pXml->WriteString(L""); + pXml->WriteString(L""); + pXml->WriteString(L""); + + CloseR(pXml); + } + + void ImageRels (NSStringUtils::CStringBuilder* oXml, int nImageId, const std::wstring& sImageSrc, const std::wstring& sExtention, const TImageData& oImageData = TImageData()) { bool bNew = nImageId < 0; if (bNew) @@ -2019,8 +4524,10 @@ class CHtmlFile2_Private std::wstring sImageName = sImageId + L'.' + sExtention; CBgraFrame oBgraFrame; if (!oBgraFrame.OpenFile(m_sDst + L"/word/media/i" + sImageName)) + { + NSFile::CFileBinary::Remove(m_sDst + L"/word/media/i" + sImageName); return; - + } // Прописать рельсы if (bNew) { @@ -2033,62 +4540,47 @@ class CHtmlFile2_Private m_oDocXmlRels.WriteString(L"\"/>"); } + if (!oImageData.ZeroSize()) + return WriteImage(oXml, oImageData, sImageId); + + TImageData oNewImageData{oImageData}; + // Получаем размеры картинки - int nHy = oBgraFrame.get_Height(); - int nWx = oBgraFrame.get_Width(); - if (nWx > nHy) + oNewImageData.m_unWidth = oBgraFrame.get_Width(); + oNewImageData.m_unHeight = oBgraFrame.get_Height(); + + if (oNewImageData.m_unWidth > oNewImageData.m_unHeight) { - int nW = nWx * 9525; + int nW = oNewImageData.m_unWidth * 9525; nW = (nW > 7000000 ? 7000000 : nW); - nHy = (int)((double)nHy * (double)nW / (double)nWx); - nWx = nW; + oNewImageData.m_unHeight = (int)((double)oNewImageData.m_unHeight * (double)nW / (double)oNewImageData.m_unWidth); + oNewImageData.m_unWidth = nW; } else { - int nH = nHy * 9525; + int nH = oNewImageData.m_unHeight * 9525; nH = (nH > 8000000 ? 8000000 : nH); - int nW = (int)((double)nWx * (double)nH / (double)nHy); + int nW = (int)((double)oNewImageData.m_unWidth * (double)nH / (double)oNewImageData.m_unHeight); if (nW > 7000000) { nW = 7000000; - nHy = (int)((double)nHy * (double)nW / (double)nWx); + oNewImageData.m_unHeight = (int)((double)oNewImageData.m_unHeight * (double)nW / (double)oNewImageData.m_unWidth); } else - nHy = nH; - nWx = nW; + oNewImageData.m_unHeight = nH; + oNewImageData.m_unWidth = nW; } - // Пишем в document.xml - oXml->WriteString(L"WriteString(std::to_wstring(nWx)); - oXml->WriteString(L"\" cy=\""); - oXml->WriteString(std::to_wstring(nHy)); - oXml->WriteString(L"\"/>WriteString(sImageId); - oXml->WriteString(L"\" name=\"\"/>WriteString(sImageId); - oXml->WriteString(L"\" name=\"\"/>WriteString(sImageId); - oXml->WriteString(L"\"/>WriteString(std::to_wstring(nWx)); - oXml->WriteString(L"\" cy=\""); - oXml->WriteString(std::to_wstring(nHy)); - oXml->WriteString(L"\"/>"); - } - - void readNote (NSStringUtils::CStringBuilder* oXml, std::vector& sSelectors, const std::wstring& sNote) + WriteImage(oXml, oNewImageData, sImageId); + } + + void readNote (NSStringUtils::CStringBuilder* oXml, std::vector& sSelectors, std::wstring& sNote) { if(sNote.empty()) return; - if (!m_bInP) - { - oXml->WriteString(L""); - for (const NSCSS::CNode& item : sSelectors) - if (item.m_wsName == L"a") - oXml->WriteString(L""); - m_bInP = true; - m_bWasPStyle = false; - } + + OpenP(oXml); + oXml->WriteString(L"WriteString(std::to_wstring(m_nFootnoteId)); oXml->WriteString(L"\"/>"); @@ -2097,89 +4589,105 @@ class CHtmlFile2_Private m_oNoteXml.WriteString(L"\">"); m_oNoteXml.WriteEncodeXmlString(sNote); m_oNoteXml.WriteString(L""); + + sNote.clear(); } - void readSVG (NSStringUtils::CStringBuilder* oXml) + bool readSVG (const std::wstring& wsSvg) { - // Сохранить как .svg картинку - NSStringUtils::CStringBuilder oSVG; - oSVG.WriteString(L"Initialize(); + + MetaFile::IMetaFile* pSvgReader = MetaFile::Create(pFonts); + if (!pSvgReader->LoadFromString(wsSvg)) { - std::wstring sName = m_oLightReader.GetName(); - if(sName.find(L"xmlns") != std::wstring::npos) - continue; - oSVG.WriteString(sName); - oSVG.WriteString(L"=\""); - oSVG.WriteString(m_oLightReader.GetText()); - oSVG.WriteString(L"\" "); + RELEASEINTERFACE(pSvgReader); + RELEASEINTERFACE(pFonts); + return false; } - m_oLightReader.MoveToElement(); - oSVG.WriteString(L"xmlns=\"http://www.w3.org/2000/svg\">"); - std::wstring sSVG = m_oLightReader.GetInnerXml(); - size_t nRef = sSVG.find(L"image"); - while (nRef != std::wstring::npos) - { - size_t nRefBegin = sSVG.rfind(L'<', nRef); - if (nRefBegin != std::wstring::npos) - { - if (sSVG[nRefBegin + 1] == L'/') - nRefBegin++; - sSVG.erase(nRefBegin + 1, nRef - nRefBegin - 1); - nRef = nRefBegin + 1; - } + NSGraphics::IGraphicsRenderer* pGrRenderer = NSGraphics::Create(); + pGrRenderer->SetFontManager(pSvgReader->get_FontManager()); - size_t nRefEnd = sSVG.find(L'>', nRef); - size_t nHRef = sSVG.find(L"href", nRef); - if (nHRef == std::wstring::npos || nRefEnd == std::wstring::npos) - break; - nHRef += 6; - if (nHRef > nRefEnd || sSVG.compare(nHRef, 4, L"http") == 0) - { - nRef = sSVG.find(L"image", nRef + 5); - continue; - } - size_t nHRefLen = sSVG.find(L"\"", nHRef); - if(nHRefLen == std::wstring::npos) - break; - std::wstring sImageName = sSVG.substr(nHRef, nHRefLen - nHRef); - std::wstring sTIN(sImageName); - sTIN.erase(std::remove_if(sTIN.begin(), sTIN.end(), [] (wchar_t ch) { return std::iswspace(ch) || (ch == L'^'); }), sTIN.end()); - sTIN = NSFile::GetFileName(sTIN); - bool bRes = NSFile::CFileBinary::Copy(m_sSrc + L"/" + sImageName, m_sDst + L"/word/media/" + sTIN); - if(!bRes) - bRes = NSFile::CFileBinary::Copy(m_sSrc + L"/" + NSFile::GetFileName(sImageName), m_sDst + L"/word/media/" + sTIN); - if(bRes) - sSVG.replace(nHRef, nHRefLen - nHRef, sTIN); - nRef = sSVG.find(L"image", nRef + 5); + double dX, dY, dW, dH; + pSvgReader->GetBounds(&dX, &dY, &dW, &dH); + + if (dW < 0) dW = -dW; + if (dH < 0) dH = -dH; + + double dOneMaxSize = (double)1000.; + + if (dW > dH && dW > dOneMaxSize) + { + dH *= (dOneMaxSize / dW); + dW = dOneMaxSize; + } + else if (dH > dW && dH > dOneMaxSize) + { + dW *= (dOneMaxSize / dH); + dH = dOneMaxSize; } - oSVG.WriteString(sSVG); - oSVG.WriteString(L""); + int nWidth = static_cast(dW + 0.5); + int nHeight = static_cast(dH + 0.5); + + double dWidth = 25.4 * nWidth / 96; + double dHeight = 25.4 * nHeight / 96; - std::wstring sImageId = std::to_wstring(m_arrImages.size()); - NSFile::CFileBinary oSVGWriter; - std::wstring sImageFile = m_sDst + L"/word/media/i" + sImageId + L".svg"; - if (oSVGWriter.CreateFileW(sImageFile)) + BYTE* pBgraData = (BYTE*)malloc(nWidth * nHeight * 4); + if (!pBgraData) { - oSVGWriter.WriteStringUTF8(oSVG.GetData()); - oSVGWriter.CloseFile(); + double dKoef = 2000.0 / (nWidth > nHeight ? nWidth : nHeight); + + nWidth = (int)(dKoef * nWidth); + nHeight = (int)(dKoef * nHeight); + + dWidth = 25.4 * nWidth / 96; + dHeight = 25.4 * nHeight / 96; + + pBgraData = (BYTE*)malloc(nWidth * nHeight * 4); } - // Конвертация из svg в png - NSFonts::IApplicationFonts* pFonts = NSFonts::NSApplication::Create(); - MetaFile::IMetaFile* pMetafile = MetaFile::Create(pFonts); - bool bLoad = pMetafile->LoadFromFile(sImageFile.data()); - if (bLoad) + if (!pBgraData) + return false; + + unsigned int alfa = 0xffffff; + //дефолтный тон должен быть прозрачным, а не белым + //memset(pBgraData, 0xff, nWidth * nHeight * 4); + for (int i = 0; i < nWidth * nHeight; i++) { - std::wstring sPngFile = m_sDst + L"/word/media/i" + sImageId + L".png"; - pMetafile->ConvertToRaster(sPngFile.data(), 4, 1000); + ((unsigned int*)pBgraData)[i] = alfa; } - pMetafile->Release(); - pFonts->Release(); + CBgraFrame oFrame; + oFrame.put_Data(pBgraData); + oFrame.put_Width(nWidth); + oFrame.put_Height(nHeight); + oFrame.put_Stride(-4 * nWidth); - ImageRels(oXml, -1, L"", L"png"); + pGrRenderer->CreateFromBgraFrame(&oFrame); + pGrRenderer->SetSwapRGB(false); + pGrRenderer->put_Width(dWidth); + pGrRenderer->put_Height(dHeight); + + // TODO: src directory as tmp - it's not good idea + pSvgReader->SetTempDirectory(m_sSrc); + pSvgReader->DrawOnRenderer(pGrRenderer, 0, 0, dWidth, dHeight); + + oFrame.SaveFile(m_sDst + L"/word/media/i" + std::to_wstring(m_arrImages.size()) + L".png", 4); + oFrame.put_Data(NULL); + + RELEASEINTERFACE(pGrRenderer); + + if (pBgraData) + free(pBgraData); + + RELEASEINTERFACE(pSvgReader); + RELEASEINTERFACE(pFonts); + + return true; } }; @@ -2213,7 +4721,12 @@ bool CHtmlFile2::IsMhtFile(const std::wstring& sFile) void CHtmlFile2::SetTmpDirectory(const std::wstring& sFolder) { - m_internal->m_sTmp = sFolder; + m_internal->m_sTmp = NSSystemPath::NormalizePath(sFolder); +} + +void CHtmlFile2::SetCoreDirectory(const std::wstring& wsFolder) +{ + m_internal->m_sCore = NSSystemPath::NormalizePath(wsFolder); } HRESULT CHtmlFile2::OpenHtml(const std::wstring& sSrc, const std::wstring& sDst, CHtmlParams* oParams) @@ -2227,8 +4740,6 @@ HRESULT CHtmlFile2::OpenHtml(const std::wstring& sSrc, const std::wstring& sDst, m_internal->CreateDocxEmpty(oParams); m_internal->readStyle(); - m_internal->m_oStylesCalculator.SetBodyTree(m_internal->m_oTree); - // Переходим в начало if(!m_internal->m_oLightReader.MoveToStart()) return S_FALSE; @@ -2251,8 +4762,6 @@ HRESULT CHtmlFile2::OpenMht(const std::wstring& sSrc, const std::wstring& sDst, m_internal->CreateDocxEmpty(oParams); m_internal->readStyle(); - m_internal->m_oStylesCalculator.SetBodyTree(m_internal->m_oTree); - // Переходим в начало if(!m_internal->m_oLightReader.MoveToStart()) return S_FALSE; @@ -2281,8 +4790,6 @@ HRESULT CHtmlFile2::OpenBatchHtml(const std::vector& sSrc, const s continue; m_internal->readStyle(); - m_internal->m_oStylesCalculator.SetBodyTree(m_internal->m_oTree); - // Переходим в начало if(m_internal->m_oLightReader.MoveToStart()) { @@ -2293,9 +4800,171 @@ HRESULT CHtmlFile2::OpenBatchHtml(const std::vector& sSrc, const s m_internal->m_oLightReader.Clear(); m_internal->m_sBase.clear(); } - m_internal->m_oStylesCalculator.Clear(); + + // Очищаем разрешенные файлы стилей + // Это необходимо, чтобы мы не могли взять стили из не подключенного файла, но при этом, чтобы данные оставались, + // т.к. ко многим файлам может быть подключен один и тот же файл (проблема возникает когда он большой) + // и подключать (в нашем случае заново парсить) его будет долго + m_internal->m_oStylesCalculator.ClearAllowedStyleFiles(); + m_internal->m_oStylesCalculator.ClearEmbeddedStyles(); } m_internal->write(); return S_OK; } + +std::wstring CTableRow::ConvertToOOXML(const CTable& oTable, int nInstruction) +{ + if (m_arCells.empty()) + return std::wstring(); + + NSStringUtils::CStringBuilder oRow; + oRow.WriteNodeBegin(L"w:tr"); + + const TTableStyles oTableStyles{oTable.GetTableStyles()}; + + if (!m_oStyles.Empty() || 0 < oTableStyles.m_nCellSpacing) + { + oRow.WriteNodeBegin(L"w:trPr"); + + if (m_oStyles.m_bIsHeader) + oRow += L""; + + if (0 < m_oStyles.m_unMaxHeight) + oRow += L""; + + if (0 < oTableStyles.m_nCellSpacing) + oRow += L""; + + oRow.WriteNodeEnd(L"w:trPr"); + } + + for (UINT unIndex = 0; unIndex < m_arCells.size(); ++unIndex) + { + int nNewInstruction{nInstruction}; + + if (0 == unIndex) + nNewInstruction |= FIRST_ELEMENT; + if (m_arCells.size() - 1 == unIndex) + nNewInstruction |= LAST_ELEMENT; + else if (0 != unIndex) + nNewInstruction |= MID_ELEMENT; + + oRow += m_arCells[unIndex]->ConvertToOOXML(oTable, unIndex, nNewInstruction); + } + + oRow.WriteNodeEnd(L"w:tr"); + + return oRow.GetData(); +} + +std::wstring CTableCell::ConvertToOOXML(const CTable& oTable, UINT unColumnNumber, int nInstruction) +{ + NSStringUtils::CStringBuilder oCell; + + oCell.WriteNodeBegin(L"w:tc"); + oCell.WriteNodeBegin(L"w:tcPr"); + + if (PARSE_MODE_HEADER == (nInstruction & PARSE_MODE_MASK)) + oCell += L""; + + TTableCellStyle oCellStyle(m_oStyles); + + const TTableCellStyle* pColStyle = oTable.GetColStyle(unColumnNumber); + + if (NULL != pColStyle) + oCellStyle += pColStyle; + + if (!oCellStyle.m_oWidth.Empty()) + { + if (NSCSS::UnitMeasure::Percent == oCellStyle.m_oWidth.GetUnitMeasure()) + oCell += L""; + else + { + if (!oCellStyle.m_oWidth.Zero()) + { + int nWidth; + if (NSCSS::UnitMeasure::None != oCellStyle.m_oWidth.GetUnitMeasure()) + nWidth = oCellStyle.m_oWidth.ToInt(NSCSS::UnitMeasure::Twips); + else + nWidth = static_cast(NSCSS::CUnitMeasureConverter::ConvertPx(oCellStyle.m_oWidth.ToDouble(), NSCSS::UnitMeasure::Twips, 96) + 0.5); + + oCell += L""; + } + else + oCell += L""; + } + } + else + oCell += L""; + + if (1 != m_unColspan) + oCell += L""; + + if (m_bIsMerged) + oCell += L""; + else if (1 < m_unRowSpan) + oCell += L""; + + const TTableStyles oTableStyles{oTable.GetTableStyles()}; + + if (!oCellStyle.m_oBorder.Empty() && !oCellStyle.m_oBorder.Zero() /*&& oCellStyle.m_oBorder != oTableStyles.m_oBorder*/) + oCell += L"" + CreateBorders(oCellStyle.m_oBorder, &oCellStyle.m_oPadding) + L""; + else if (TTableStyles::ETableRules::Groups == oTable.GetTableStyles().m_enRules) + { + std::wstring wsBorders; + + if (oTable.HaveColgroups()) + wsBorders += oTable.CalculateSidesToClean(unColumnNumber); + + if (PARSE_MODE_HEADER == (nInstruction & PARSE_MODE_MASK) && (((nInstruction & ROW_POSITION_MASK) >> 4) & LAST_ELEMENT)) + wsBorders += CreateDefaultBorder(L"bottom"); + else if (PARSE_MODE_FOOTHER == (nInstruction & PARSE_MODE_MASK) && (((nInstruction & ROW_POSITION_MASK) >> 4) & FIRST_ELEMENT)) + wsBorders += CreateDefaultBorder(L"top"); + + if (!wsBorders.empty()) + oCell += L"" + wsBorders + L""; + } + + if (!oCellStyle.m_oBackground.Empty()) + { + const std::wstring wsShdFill{(NSCSS::NSProperties::ColorNone == oCellStyle.m_oBackground.GetType()) ? L"auto" : oCellStyle.m_oBackground.ToWString()}; + oCell += L""; + } + + if (!oCellStyle.m_wsVAlign.empty()) + oCell += L""; + else + oCell += L""; + + if (!oCellStyle.m_oPadding.Empty() && oTableStyles.m_oPadding != oCellStyle.m_oPadding) + { + const int nTopPadding = std::max(oTableStyles.m_oPadding.GetTop() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_HEIGHT), + oCellStyle .m_oPadding.GetTop() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_HEIGHT)); + const int nLeftPadding = std::max(oTableStyles.m_oPadding.GetLeft() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_WIDTH), + oCellStyle .m_oPadding.GetLeft() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_WIDTH)); + const int nBottomPadding = std::max(oTableStyles.m_oPadding.GetBottom().ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_HEIGHT), + oCellStyle .m_oPadding.GetBottom().ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_HEIGHT)); + const int nRightPadding = std::max(oTableStyles.m_oPadding.GetRight() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_WIDTH), + oCellStyle .m_oPadding.GetRight() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_WIDTH)); + + oCell += L"" + "" + "" + "" + "" + ""; + } + + oCell += L""; + oCell.WriteNodeEnd(L"w:tcPr"); + + if (0 != m_oData.GetCurSize()) + oCell += m_oData.GetData(); + else + WriteEmptyParagraph(&oCell); + + oCell.WriteNodeEnd(L"w:tc"); + + return oCell.GetData(); +} diff --git a/HtmlFile2/htmlfile2.h b/HtmlFile2/htmlfile2.h index 9ecb12486df..a7c70f9ae8c 100644 --- a/HtmlFile2/htmlfile2.h +++ b/HtmlFile2/htmlfile2.h @@ -19,6 +19,7 @@ struct CHtmlParams std::wstring m_sBookTitle; // Название std::wstring m_sDate; // Дата std::wstring m_sDescription; // описание + std::wstring m_sLanguage; // Язык bool m_bNeedPageBreakBefore; // Новый html с новой страницы std::wstring m_sdocDefaults; // Стиль docDefaults std::wstring m_sNormal; // Стиль normal @@ -64,6 +65,11 @@ struct CHtmlParams { m_sBookTitle = sTitle; } + + void SetLanguage(const std::wstring& sLanguage) + { + m_sLanguage = sLanguage; + } }; class CHtmlFile2_Private; @@ -78,6 +84,7 @@ class HTMLFILE2_DECL_EXPORT CHtmlFile2 bool IsHtmlFile(const std::wstring& sFile); bool IsMhtFile (const std::wstring& sFile); void SetTmpDirectory(const std::wstring& sFolder); + void SetCoreDirectory(const std::wstring& wsFolder); HRESULT OpenHtml(const std::wstring& sPath, const std::wstring& sDirectory, CHtmlParams* oParams = NULL); HRESULT OpenMht (const std::wstring& sPath, const std::wstring& sDirectory, CHtmlParams* oParams = NULL); HRESULT OpenBatchHtml(const std::vector& sPath, const std::wstring& sDirectory, CHtmlParams* oParams = NULL); diff --git a/HtmlFile2/src/Languages.h b/HtmlFile2/src/Languages.h new file mode 100644 index 00000000000..a0449f94ef0 --- /dev/null +++ b/HtmlFile2/src/Languages.h @@ -0,0 +1,91 @@ +#ifndef LANGUAGES_LIST_H +#define LANGUAGES_LIST_H + +#include +#include +#include + +const static std::map m_Languages_HTML +{ + //Язык, Регион + {L"en", L"US"}, // Английский - США + {L"ru", L"RU"}, // Русский - Россия + {L"es", L"ES"}, // Испанский - Испания + {L"de", L"DE"}, // Немецкий - Германия + {L"fr", L"FR"}, // Французский - Франция + {L"it", L"IT"}, // Итальянский - Италия + {L"pt", L"PT"}, // Португальский - Португалия + {L"pl", L"PL"}, // Польский - Польша + {L"nl", L"NL"}, // Нидерландский - Нидерланды + {L"sv", L"SE"}, // Шведский - Швеция + {L"nb", L"NO"}, // Норвежский - Новегия + {L"da", L"DK"}, // Датский - Дания + {L"fi", L"FI"}, // Финский - Финляндия + {L"el", L"GR"}, // Греческий - Греция + {L"tr", L"TR"}, // Турецкий - Турция + {L"ar", L"SA"}, // Арабский - Саудовская Аравия + {L"he", L"IL"}, // Иврит - Израиль + {L"ja", L"JP"}, // Японский - Япония + {L"zh", L"CN"}, // Китайский (упрощенный) - Китай + {L"hu", L"HU"}, // Венгерский - Венгрия + {L"cs", L"CZ"}, // Чешский - Чехия + {L"ro", L"RO"}, // Румынский - Румыния + {L"bg", L"BG"}, // Болгарский - Болгария + {L"hr", L"HR"}, // Хорватский - Хорватия + {L"sr", L"Latn-RS"}, //Сербский - Сербия + {L"sl", L"SI"}, // Словенский - Словения + {L"lt", L"LT"}, // Литовский - Литва + {L"lv", L"LV"}, // Латышский - Латвия + {L"et", L"EE"}, // Эстонский - Эстония + {L"uk", L"UA"}, // Украинский - Украина + {L"be", L"BY"}, // Белорусский - Беларусь + {L"kk", L"KZ"}, // Казахский - Казахстан + {L"hi", L"IN"}, // Хинди - Индия + {L"th", L"TH"}, // Тайский - Таиланд + {L"vi", L"VN"}, // Вьетнамский - Вьетнам + {L"id", L"ID"}, // Индонезийский - Индонезия + {L"ms", L"MY"}, // Малайский - Малайзия + {L"fil", L"PH"}, // Филиппинский - Филиппины + {L"ko", L"KR"}, // Корейский - Южная Корея + {L"is", L"IS"}, // Исландский - Исландия + {L"ga", L"IE"}, // Ирландский - Ирландия + {L"cy", L"GB"}, // Валлийский - Великобритания + {L"ca", L"ES"}, // Каталанский - Испания + {L"eu", L"ES"}, // Баскский - Испания + {L"gl", L"ES"}, // Галисийский - Испания + {L"af", L"ZA"}, // Африкаанс - Южная Африка + {L"zu", L"ZA"}, // Зулу - Южная Африка + {L"ha", L"Latn-NG"}, // Хауса - Нигерия + {L"yo", L"NG"}, // Йоруба - Нигерия + {L"sw", L"KE"}, // Суахили - Кения + {L"am", L"ET"}, // Амхарский - Эфиопия + {L"ti", L"ET"}, // Тигринья - Эфиопия + {L"ur", L"PK"}, // Урду - Пакистан + {L"pa", L"IN"}, // Панджаби - Индия + {L"gu", L"IN"}, // Гуджарати - Индия + {L"ta", L"IN"}, // Тамильский - Индия + {L"te", L"IN"}, // Телугу - Индия + {L"ml", L"IN"}, // Малаялам - Индия + {L"kn", L"IN"} // Каннада - Индия +}; + +static std::wstring IndentifyLanguage(std::wstring wsLanguage) +{ + std::transform(wsLanguage.begin(), wsLanguage.end(), wsLanguage.begin(), towlower); + + std::map::const_iterator itFounded = m_Languages_HTML.find(wsLanguage); + + if (m_Languages_HTML.end() != itFounded) + return itFounded->first + L"-" + itFounded->second; + + return std::wstring(); +} + +static bool ConsistsChineseCharacters(std::wstring wsLanguage) +{ + std::transform(wsLanguage.begin(), wsLanguage.end(), wsLanguage.begin(), towlower); + + return L"zh" == wsLanguage || L"ja" == wsLanguage || L"ko" == wsLanguage; +} + +#endif // LANGUAGES_LIST_H diff --git a/HtmlFile2/src/StringFinder.h b/HtmlFile2/src/StringFinder.h new file mode 100644 index 00000000000..3b4fd572bb9 --- /dev/null +++ b/HtmlFile2/src/StringFinder.h @@ -0,0 +1,255 @@ +#ifndef STRINGFINDER_H +#define STRINGFINDER_H + +#include +#include +#include + +#if defined(_WIN32) || defined (_WIN64) +#include +#elif __linux__ || MAC +#include +#endif + +namespace NSStringFinder +{ + template, std::allocator>> + struct TFoundedData + { + size_t m_unBeginPosition; + size_t m_unEndPosition; + StringType m_sValue; + + TFoundedData() + : m_unBeginPosition(0), m_unEndPosition(0) + {} + + bool Empty() const + { + return 0 == m_unEndPosition || StringType::npos == m_unEndPosition; + } + }; + + template, std::allocator>> + StringType FindPropetyTemplate(const StringType& sString, const StringType& sProperty, const StringType& sDelimiter, const StringType& sEnding, const size_t& unStarting, size_t& unEndPosition) + { + if (sString.length() < unStarting) + return StringType(); + + typedef const boost::iterator_range StringRange; + + StringRange itFound = boost::algorithm::ifind_first(StringRange(sString.begin() + unStarting, sString.end()), sProperty); + + if (itFound.empty()) + return StringType(); + + StringRange itFoundBegin = boost::algorithm::ifind_first(StringRange(itFound.end(), sString.end()), sDelimiter); + + if (itFoundBegin.empty()) + return StringType(); + + StringRange itFoundEnd = boost::algorithm::ifind_first(StringRange(itFoundBegin.end(), sString.end()), sEnding); + + if (itFoundEnd.empty()) + return StringType(); + + unEndPosition += (itFoundEnd.end() - sString.begin()); + + StringType sValue{itFoundBegin.end(), itFoundEnd.begin()}; + boost::algorithm::trim(sValue); + return sValue; + } + + std::string FindPropety(const std::string& sString, const std::string& sProperty, const std::string& sDelimiter, const std::string& sEnding, const size_t& unStarting, size_t& unEndPosition) + { + return FindPropetyTemplate(sString, sProperty, sDelimiter, sEnding, unStarting, unEndPosition); + } + + std::wstring FindPropety(const std::wstring& wsString, const std::wstring& wsProperty, const std::wstring& wsDelimiter, const std::wstring& wsEnding, const size_t& unStarting, size_t& unEndPosition) + { + return FindPropetyTemplate(wsString, wsProperty, wsDelimiter, wsEnding, unStarting, unEndPosition); + } + + std::string FindPropety(const std::string& sString, const std::string& sProperty, const std::string& sDelimiter, const std::string& sEnding, const size_t& unStarting = 0) + { + size_t unEndPosition = 0; + return FindPropetyTemplate(sString, sProperty, sDelimiter, sEnding, unStarting, unEndPosition); + } + + std::wstring FindPropety(const std::wstring& wsString, const std::wstring& wsProperty, const std::wstring& wsDelimiter, const std::wstring& wsEnding, const size_t& unStarting = 0) + { + size_t unEndPosition = 0; + return FindPropetyTemplate(wsString, wsProperty, wsDelimiter, wsEnding, unStarting, unEndPosition); + } + + template, std::allocator>> + TFoundedData FindPropetyTemplate(const StringType& sString, const StringType& sProperty, const std::vector& arDelimiters, const std::vector& arEndings, const size_t& unStarting) + { + if (sString.length() < unStarting) + return TFoundedData(); + + std::wstring wsRegexValue = L"(?i)" + std::wstring(sProperty.begin(), sProperty.end()); + + if (!arDelimiters.empty()) + { + wsRegexValue += L"\\s*["; + for (const StringType& wsDelimiter : arDelimiters) + wsRegexValue += std::wstring(wsDelimiter.begin(), wsDelimiter.end()) + L"|"; + wsRegexValue.pop_back(); + wsRegexValue += L"]{1}"; + } + + if (!arEndings.empty()) + { + std::wstring wsEndingValue; + + for (const StringType& sEnding : arEndings) + wsEndingValue += std::wstring(sEnding.begin(), sEnding.end()) + L"|"; + + wsEndingValue.pop_back(); + + wsRegexValue += L"\\s*(.[^" + wsEndingValue + L"]*)\\s*[" + wsEndingValue + L"]?"; + } + else + wsRegexValue += L"\\s*(.*)[\\n|\\r]?"; + + boost::wregex oRegex(wsRegexValue); + boost::match_results oResult; + + if (!boost::regex_search(sString.begin() + unStarting, sString.end(), oResult, oRegex)) + return TFoundedData(); + + TFoundedData oData; + + oData.m_unBeginPosition = unStarting + oResult.position(); + oData.m_unEndPosition = unStarting + oResult.position() + oResult.length(); + + oData.m_sValue = oResult[1]; + boost::algorithm::trim(oData.m_sValue); + + return oData; + } + + TFoundedData FindPropety(const std::string& sString, const std::string& sProperty, const std::vector& arDelimiters, const std::vector& arEndings, const size_t& unStarting = 0) + { + return FindPropetyTemplate(sString, sProperty, arDelimiters, arEndings, unStarting); + } + + TFoundedData FindPropety(const std::wstring& wsString, const std::wstring& wsProperty, const std::vector& arDelimiters, const std::vector& arEndings, const size_t& unStarting = 0) + { + return FindPropetyTemplate(wsString, wsProperty, arDelimiters, arEndings, unStarting); + } + + template, std::allocator>> + bool RemoveEmptyTagTemplate(StringType& sValue, const StringType& sTagName, size_t unStart) + { + boost::wregex oRegex(L"<\\s*(?i)" + std::wstring(sTagName.begin(), sTagName.end()) + L"\\s*[^>]*/>"); + boost::match_results oResult; + + if (unStart >= sValue.length() || !boost::regex_search(sValue.cbegin() + unStart, sValue.cend(), oResult, oRegex)) + return false; + + sValue.erase(unStart + oResult.position(), oResult.length()); + + return true; + } + + bool RemoveEmptyTag(std::string& sValue, const std::string& sTagName, size_t unStart = 0) + { + return RemoveEmptyTagTemplate(sValue, sTagName, unStart); + } + + bool RemoveEmptyTag(std::wstring& sValue, const std::wstring& sTagName, size_t unStart = 0) + { + return RemoveEmptyTagTemplate(sValue, sTagName, unStart); + } + + template + void CutInside(StringType& sString, const StringEndgeType& sLeftEdge, const StringEndgeType& sRightEdge) + { + typedef const boost::iterator_range StringRange; + + StringRange itFoundBegin = boost::algorithm::ifind_first(StringRange(sString.begin(), sString.end()), sLeftEdge); + + if (itFoundBegin.empty()) + return; + + StringRange itFoundEnd = boost::algorithm::ifind_first(StringRange(itFoundBegin.end(), sString.cend()), sRightEdge); + + if (itFoundEnd.empty()) + { + sString = StringType{itFoundBegin.end(), sString.cend()}; + return; + } + + sString = StringType{itFoundBegin.end(), itFoundEnd.begin()}; + } + + template + void CutInside(StringType& sString, const StringEdgeType& sEdge) + { + CutInside(sString, sEdge, sEdge); + } + + template + bool Equals(const StringFirstType& sFirstString, const StringSecondType& sSecondString) + { + return boost::iequals(sFirstString, sSecondString); + } + + template + bool EqualOf(const StringFirstType& sFirstString, const std::vector& arStrings) + { + for (const StringFirstType& sString : arStrings) + if (boost::iequals(sFirstString, sString)) + return true; + + return false; + } + + template + bool EqualOf(const StringFirstType& sFirstString, const std::initializer_list& arStrings) + { + for (const StringFirstType& sString : arStrings) + if (boost::iequals(sFirstString, sString)) + return true; + + return false; + } + + template + bool Find(const StringType& sString, const StringValueType& sValue) + { + return !boost::algorithm::ifind_first(sString, sValue).empty(); + } + + int ToInt(const std::wstring& oValue, int nMinValue = 0) + { + boost::wregex oRegex(LR"((-?\.\d+|-?\d+(\.\d+)?))"); + + boost::match_results oResult; + + if (!boost::regex_search(oValue.begin(), oValue.end(), oResult, oRegex)) + return nMinValue; + + const int nValue = std::stoi(*oResult.begin()); + + return std::max(nMinValue, nValue); + } + + int ToDouble(const std::wstring& oValue, double dMinValue = 0.) + { + boost::wregex oRegex(LR"((-?\.\d+|-?\d+(\.\d+)?))"); + + boost::match_results oResult; + + if (!boost::regex_search(oValue.begin(), oValue.end(), oResult, oRegex)) + return dMinValue; + + const double dValue = std::stod(*oResult.begin()); + + return (dValue >= dMinValue) ? dValue : dMinValue; + } +} + +#endif // STRINGFINDER_H diff --git a/HtmlRenderer/Mac/HtmlRenderer.xcodeproj/project.pbxproj b/HtmlRenderer/Mac/HtmlRenderer.xcodeproj/project.pbxproj deleted file mode 100644 index fed55df155e..00000000000 --- a/HtmlRenderer/Mac/HtmlRenderer.xcodeproj/project.pbxproj +++ /dev/null @@ -1,326 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - 6967BEDE1E28BC7300A129E2 /* HTMLRenderer3.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6967BED51E28BC7300A129E2 /* HTMLRenderer3.cpp */; }; -/* End PBXBuildFile section */ - -/* Begin PBXCopyFilesBuildPhase section */ - 6967BEBF1E28BC1700A129E2 /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = "include/$(PRODUCT_NAME)"; - dstSubfolderSpec = 16; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXCopyFilesBuildPhase section */ - -/* Begin PBXFileReference section */ - 6967BEC11E28BC1700A129E2 /* libHtmlRenderer.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libHtmlRenderer.a; sourceTree = BUILT_PRODUCTS_DIR; }; - 6967BECF1E28BC7300A129E2 /* CanvasWriter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CanvasWriter.h; sourceTree = ""; }; - 6967BED01E28BC7300A129E2 /* Common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Common.h; sourceTree = ""; }; - 6967BED11E28BC7300A129E2 /* Common2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Common2.h; sourceTree = ""; }; - 6967BED21E28BC7300A129E2 /* Document.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Document.h; sourceTree = ""; }; - 6967BED31E28BC7300A129E2 /* FontManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FontManager.h; sourceTree = ""; }; - 6967BED41E28BC7300A129E2 /* FontManagerBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FontManagerBase.h; sourceTree = ""; }; - 6967BED51E28BC7300A129E2 /* HTMLRenderer3.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HTMLRenderer3.cpp; sourceTree = ""; }; - 6967BED61E28BC7300A129E2 /* SVGWriter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGWriter.h; sourceTree = ""; }; - 6967BED71E28BC7300A129E2 /* SVGWriter2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGWriter2.h; sourceTree = ""; }; - 6967BED81E28BC7300A129E2 /* Text.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Text.h; sourceTree = ""; }; - 6967BED91E28BC7300A129E2 /* VectorGraphicsWriter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VectorGraphicsWriter.h; sourceTree = ""; }; - 6967BEDA1E28BC7300A129E2 /* VectorGraphicsWriter2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VectorGraphicsWriter2.h; sourceTree = ""; }; - 6967BEDB1E28BC7300A129E2 /* VMLWriter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VMLWriter.h; sourceTree = ""; }; - 6967BEDC1E28BC7300A129E2 /* Writer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Writer.h; sourceTree = ""; }; - 6967BEE11E28BC7900A129E2 /* HTMLRenderer3.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTMLRenderer3.h; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 6967BEBE1E28BC1700A129E2 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 6967BEB81E28BC1700A129E2 = { - isa = PBXGroup; - children = ( - 6967BEC31E28BC1700A129E2 /* HtmlRenderer */, - 6967BEC21E28BC1700A129E2 /* Products */, - ); - sourceTree = ""; - }; - 6967BEC21E28BC1700A129E2 /* Products */ = { - isa = PBXGroup; - children = ( - 6967BEC11E28BC1700A129E2 /* libHtmlRenderer.a */, - ); - name = Products; - sourceTree = ""; - }; - 6967BEC31E28BC1700A129E2 /* HtmlRenderer */ = { - isa = PBXGroup; - children = ( - 6967BEDF1E28BC7900A129E2 /* include */, - 6967BECD1E28BC7300A129E2 /* src */, - ); - path = HtmlRenderer; - sourceTree = ""; - }; - 6967BECD1E28BC7300A129E2 /* src */ = { - isa = PBXGroup; - children = ( - 6967BECF1E28BC7300A129E2 /* CanvasWriter.h */, - 6967BED01E28BC7300A129E2 /* Common.h */, - 6967BED11E28BC7300A129E2 /* Common2.h */, - 6967BED21E28BC7300A129E2 /* Document.h */, - 6967BED31E28BC7300A129E2 /* FontManager.h */, - 6967BED41E28BC7300A129E2 /* FontManagerBase.h */, - 6967BED51E28BC7300A129E2 /* HTMLRenderer3.cpp */, - 6967BED61E28BC7300A129E2 /* SVGWriter.h */, - 6967BED71E28BC7300A129E2 /* SVGWriter2.h */, - 6967BED81E28BC7300A129E2 /* Text.h */, - 6967BED91E28BC7300A129E2 /* VectorGraphicsWriter.h */, - 6967BEDA1E28BC7300A129E2 /* VectorGraphicsWriter2.h */, - 6967BEDB1E28BC7300A129E2 /* VMLWriter.h */, - 6967BEDC1E28BC7300A129E2 /* Writer.h */, - ); - name = src; - path = ../../src; - sourceTree = ""; - }; - 6967BEDF1E28BC7900A129E2 /* include */ = { - isa = PBXGroup; - children = ( - 6967BEE11E28BC7900A129E2 /* HTMLRenderer3.h */, - ); - name = include; - path = ../../include; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 6967BEC01E28BC1700A129E2 /* HtmlRenderer */ = { - isa = PBXNativeTarget; - buildConfigurationList = 6967BECA1E28BC1700A129E2 /* Build configuration list for PBXNativeTarget "HtmlRenderer" */; - buildPhases = ( - 6967BEBD1E28BC1700A129E2 /* Sources */, - 6967BEBE1E28BC1700A129E2 /* Frameworks */, - 6967BEBF1E28BC1700A129E2 /* CopyFiles */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = HtmlRenderer; - productName = HtmlRenderer; - productReference = 6967BEC11E28BC1700A129E2 /* libHtmlRenderer.a */; - productType = "com.apple.product-type.library.static"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 6967BEB91E28BC1700A129E2 /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 0820; - ORGANIZATIONNAME = OnlyOffce; - TargetAttributes = { - 6967BEC01E28BC1700A129E2 = { - CreatedOnToolsVersion = 8.2; - DevelopmentTeam = 2WH24U26GJ; - ProvisioningStyle = Automatic; - }; - }; - }; - buildConfigurationList = 6967BEBC1E28BC1700A129E2 /* Build configuration list for PBXProject "HtmlRenderer" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 0; - knownRegions = ( - en, - ); - mainGroup = 6967BEB81E28BC1700A129E2; - productRefGroup = 6967BEC21E28BC1700A129E2 /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 6967BEC01E28BC1700A129E2 /* HtmlRenderer */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXSourcesBuildPhase section */ - 6967BEBD1E28BC1700A129E2 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 6967BEDE1E28BC7300A129E2 /* HTMLRenderer3.cpp in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin XCBuildConfiguration section */ - 6967BEC81E28BC1700A129E2 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 10.2; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - }; - name = Debug; - }; - 6967BEC91E28BC1700A129E2 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 10.2; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = iphoneos; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - 6967BECB1E28BC1700A129E2 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - DEVELOPMENT_TEAM = 2WH24U26GJ; - HEADER_SEARCH_PATHS = ( - "$(inherited)", - /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, - /usr/include/, - /usr/include/libxml2/, - "$(PROJECT_DIR)/../../DesktopEditor/freetype-2.5.2/include", - "$(PROJECT_DIR)/../../DesktopEditor/freetype-2.5.2/devel", - "$(PROJECT_DIR)/../../DesktopEditor/agg-2.4/include", - ); - OTHER_LDFLAGS = "-ObjC"; - PRODUCT_NAME = "$(TARGET_NAME)"; - SKIP_INSTALL = YES; - }; - name = Debug; - }; - 6967BECC1E28BC1700A129E2 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - DEVELOPMENT_TEAM = 2WH24U26GJ; - HEADER_SEARCH_PATHS = ( - "$(inherited)", - /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, - /usr/include/, - /usr/include/libxml2/, - "$(PROJECT_DIR)/../../DesktopEditor/freetype-2.5.2/include", - "$(PROJECT_DIR)/../../DesktopEditor/freetype-2.5.2/devel", - "$(PROJECT_DIR)/../../DesktopEditor/agg-2.4/include", - ); - OTHER_LDFLAGS = "-ObjC"; - PRODUCT_NAME = "$(TARGET_NAME)"; - SKIP_INSTALL = YES; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 6967BEBC1E28BC1700A129E2 /* Build configuration list for PBXProject "HtmlRenderer" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 6967BEC81E28BC1700A129E2 /* Debug */, - 6967BEC91E28BC1700A129E2 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 6967BECA1E28BC1700A129E2 /* Build configuration list for PBXNativeTarget "HtmlRenderer" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 6967BECB1E28BC1700A129E2 /* Debug */, - 6967BECC1E28BC1700A129E2 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 6967BEB91E28BC1700A129E2 /* Project object */; -} diff --git a/HtmlRenderer/Mac/HtmlRenderer.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/HtmlRenderer/Mac/HtmlRenderer.xcodeproj/project.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 0dbedda47db..00000000000 --- a/HtmlRenderer/Mac/HtmlRenderer.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/HtmlRenderer/Mac/HtmlRenderer/NOTE.txt b/HtmlRenderer/Mac/HtmlRenderer/NOTE.txt deleted file mode 100644 index 70fa9cd654f..00000000000 --- a/HtmlRenderer/Mac/HtmlRenderer/NOTE.txt +++ /dev/null @@ -1 +0,0 @@ -DO NOT REMOVE FOLDER FOR XCODE \ No newline at end of file diff --git a/HtmlRenderer/htmlrenderer.pro b/HtmlRenderer/htmlrenderer.pro deleted file mode 100644 index eb2f30daa5b..00000000000 --- a/HtmlRenderer/htmlrenderer.pro +++ /dev/null @@ -1,47 +0,0 @@ -QT -= core -QT -= gui - -VERSION = 1.0.0.3 -TARGET = HtmlRenderer -TEMPLATE = lib - -CONFIG += shared -CONFIG += plugin - -DEFINES += HTMLRENDERER_USE_DYNAMIC_LIBRARY - -CORE_ROOT_DIR = $$PWD/.. -PWD_ROOT_DIR = $$PWD -include(../Common/base.pri) - -ADD_DEPENDENCY(graphics, kernel, UnicodeConverter) - -core_windows { -LIBS += -lgdi32 \ - -ladvapi32 \ - -luser32 \ - -lshell32 -} - -SOURCES += \ - src/HTMLRenderer3.cpp - -HEADERS += \ - src/CanvasWriter.h \ - src/Common.h \ - src/Document.h \ - src/FontManager.h \ - src/FontManagerBase.h \ - src/SVGWriter.h \ - src/SVGWriter2.h \ - src/Text.h \ - src/VectorGraphicsWriter.h \ - src/VectorGraphicsWriter2.h \ - src/VMLWriter.h \ - src/Writer.h \ - include/HTMLRenderer3.h \ - src/Common2.h \ - src/Meta.h - -#HEADERS += $$PWD/include/HTMLRendererText.h -#SOURCES += $$PWD/src/HTMLRendererText.cpp diff --git a/HtmlRenderer/include/ASCSVGWriter.h b/HtmlRenderer/include/ASCSVGWriter.h deleted file mode 100644 index e082bb42b69..00000000000 --- a/HtmlRenderer/include/ASCSVGWriter.h +++ /dev/null @@ -1,240 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2023 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _ASC_HTMLRENDERER_SVG_WRITER_H_ -#define _ASC_HTMLRENDERER_SVG_WRITER_H_ - -#include "../../DesktopEditor/graphics/IRenderer.h" -#include "../../DesktopEditor/graphics/pro/Fonts.h" -#include "../../DesktopEditor/graphics/GraphicsPath.h" - -namespace NSHtmlRenderer -{ - class CSVGGraphicsWriter; -} -namespace NSStructures -{ - class CPen; - class CBrush; - class CFont; -} -namespace NSHtmlRenderer -{ - class CASCSVGWriter : public IRenderer - { - public: - CASCSVGWriter(bool bIsInitializeFonts = true); - ~CASCSVGWriter(); - - void Reset(); - - // тип рендерера----------------------------------------------------------------------------- - HRESULT get_Type(LONG* lType); - //-------- Функции для работы со страницей -------------------------------------------------- - HRESULT NewPage(); - HRESULT get_Height(double* dHeight); - HRESULT put_Height(const double& dHeight); - HRESULT get_Width(double* dWidth); - HRESULT put_Width(const double& dWidth); - HRESULT get_DpiX(double* dDpiX); - HRESULT get_DpiY(double* dDpiY); - - // pen -------------------------------------------------------------------------------------- - HRESULT get_PenColor(LONG* lColor); - HRESULT put_PenColor(const LONG& lColor); - HRESULT get_PenAlpha(LONG* lAlpha); - HRESULT put_PenAlpha(const LONG& lAlpha); - HRESULT get_PenSize(double* dSize); - HRESULT put_PenSize(const double& dSize); - HRESULT get_PenDashStyle(BYTE* val); - HRESULT put_PenDashStyle(const BYTE& val); - HRESULT get_PenLineStartCap(BYTE* val); - HRESULT put_PenLineStartCap(const BYTE& val); - HRESULT get_PenLineEndCap(BYTE* val); - HRESULT put_PenLineEndCap(const BYTE& val); - HRESULT get_PenLineJoin(BYTE* val); - HRESULT put_PenLineJoin(const BYTE& val); - HRESULT get_PenDashOffset(double* dOffset); - HRESULT put_PenDashOffset(const double& dOffset); - HRESULT get_PenAlign(LONG* lAlign); - HRESULT put_PenAlign(const LONG& lAlign); - HRESULT get_PenMiterLimit(double* dOffset); - HRESULT put_PenMiterLimit(const double& dOffset); - HRESULT PenDashPattern(double* pPattern, LONG lCount); - - // brush ------------------------------------------------------------------------------------ - HRESULT get_BrushType(LONG* lType); - HRESULT put_BrushType(const LONG& lType); - HRESULT get_BrushColor1(LONG* lColor); - HRESULT put_BrushColor1(const LONG& lColor); - HRESULT get_BrushAlpha1(LONG* lAlpha); - HRESULT put_BrushAlpha1(const LONG& lAlpha); - HRESULT get_BrushColor2(LONG* lColor); - HRESULT put_BrushColor2(const LONG& lColor); - HRESULT get_BrushAlpha2(LONG* lAlpha); - HRESULT put_BrushAlpha2(const LONG& lAlpha); - HRESULT get_BrushTexturePath(std::wstring* bsPath); - HRESULT put_BrushTexturePath(const std::wstring& bsPath); - HRESULT get_BrushTextureMode(LONG* lMode); - HRESULT put_BrushTextureMode(const LONG& lMode); - HRESULT get_BrushTextureAlpha(LONG* lTxAlpha); - HRESULT put_BrushTextureAlpha(const LONG& lTxAlpha); - HRESULT get_BrushLinearAngle(double* dAngle); - HRESULT put_BrushLinearAngle(const double& dAngle); - HRESULT BrushRect(const INT& val, const double& left, const double& top, const double& width, const double& height); - HRESULT BrushBounds(const double& left, const double& top, const double& width, const double& height); - - HRESULT put_BrushGradientColors(LONG* lColors, double* pPositions, LONG nCount); - - HRESULT get_BrushTextureImage(Aggplus::CImage** pImage) { return S_OK; } - HRESULT put_BrushTextureImage(Aggplus::CImage* pImage) { return S_OK; } - HRESULT get_BrushTransform(Aggplus::CMatrix& oMatrix) { return S_OK; } - HRESULT put_BrushTransform(const Aggplus::CMatrix& oMatrix) { return S_OK; } - // font ------------------------------------------------------------------------------------- - HRESULT get_FontName(std::wstring* bsName); - HRESULT put_FontName(const std::wstring& bsName); - HRESULT get_FontPath(std::wstring* bsName); - HRESULT put_FontPath(const std::wstring& bsName); - HRESULT get_FontSize(double* dSize); - HRESULT put_FontSize(const double& dSize); - HRESULT get_FontStyle(LONG* lStyle) ; - HRESULT put_FontStyle(const LONG& lStyle); - HRESULT get_FontStringGID(INT* bGID); - HRESULT put_FontStringGID(const INT& bGID); - HRESULT get_FontCharSpace(double* dSpace); - HRESULT put_FontCharSpace(const double& dSpace); - HRESULT get_FontFaceIndex(int* lFaceIndex); - HRESULT put_FontFaceIndex(const int& lFaceIndex); - - //-------- Функции для вывода текста -------------------------------------------------------- - HRESULT CommandDrawTextCHAR(const LONG& c, const double& x, const double& y, const double& w, const double& h); - HRESULT CommandDrawText(const std::wstring& bsText, const double& x, const double& y, const double& w, const double& h); - - HRESULT CommandDrawTextExCHAR(const LONG& c, const LONG& gid, const double& x, const double& y, const double& w, const double& h); - HRESULT CommandDrawTextEx(const std::wstring& bsUnicodeText, const unsigned int* pGids, const unsigned int nGidsCount, const double& x, const double& y, const double& w, const double& h); - - //-------- Маркеры для команд --------------------------------------------------------------- - HRESULT BeginCommand(const DWORD& lType); - HRESULT EndCommand(const DWORD& lType); - - //-------- Функции для работы с Graphics Path ----------------------------------------------- - HRESULT PathCommandMoveTo(const double& x, const double& y); - HRESULT PathCommandLineTo(const double& x, const double& y); - HRESULT PathCommandLinesTo(double* points, const int& count); - HRESULT PathCommandCurveTo(const double& x1, const double& y1, const double& x2, const double& y2, const double& x3, const double& y3); - HRESULT PathCommandCurvesTo(double* points, const int& count); - HRESULT PathCommandArcTo(const double& x, const double& y, const double& w, const double& h, const double& startAngle, const double& sweepAngle); - HRESULT PathCommandClose(); - HRESULT PathCommandEnd(); - HRESULT DrawPath(const LONG& nType); - HRESULT PathCommandStart(); - HRESULT PathCommandGetCurrentPoint(double* x, double* y); - - HRESULT PathCommandTextCHAR(const LONG& c, const double& x, const double& y, const double& w, const double& h); - HRESULT PathCommandText(const std::wstring& bsText, const double& x, const double& y, const double& w, const double& h); - - HRESULT PathCommandTextExCHAR(const LONG& c, const LONG& gid, const double& x, const double& y, const double& w, const double& h); - HRESULT PathCommandTextEx(const std::wstring& sText, const unsigned int* pGids, const unsigned int nGidsCount, const double& x, const double& y, const double& w, const double& h); - - //-------- Функции для вывода изображений --------------------------------------------------- - HRESULT DrawImage(IGrObject* pImage, const double& x, const double& y, const double& w, const double& h); - HRESULT DrawImageFromFile(const std::wstring&, const double& x, const double& y, const double& w, const double& h, const BYTE& lAlpha); - - // transform -------------------------------------------------------------------------------- - HRESULT SetTransform(const double& m1, const double& m2, const double& m3, const double& m4, const double& m5, const double& m6); - HRESULT GetTransform(double *pdA, double *pdB, double *pdC, double *pdD, double *pdE, double *pdF); - HRESULT ResetTransform(); - - // ----------------------------------------------------------------------------------------- - HRESULT get_ClipMode(LONG* plMode); - HRESULT put_ClipMode(const LONG& lMode); - // additiaonal params ---------------------------------------------------------------------- - HRESULT SaveFile(const std::wstring& strFileSave); - HRESULT ReInit(); - HRESULT IsRaster(bool* bVal); - HRESULT GetSVGDataSize(LONG* lVal); - // additiaonal params ---------------------------------------------------------------------- - HRESULT CommandLong(const LONG& lType, const LONG& lCommand); - HRESULT CommandDouble(const LONG& lType, const double& dCommand); - HRESULT CommandString(const LONG& lType, const std::wstring& sCommand); - public: - - void SetFontManager(NSFonts::IFontManager* pFontManager); - - private: - - NSHtmlRenderer::CSVGGraphicsWriter* m_pVectorWriter; - - Aggplus::CGraphicsPathSimpleConverter* m_pSimpleGraphicsConverter; // конвертер сложных гафических путей в простые - NSFonts::IFontManager* m_pFontManager; // менеджер шрифтов - - Aggplus::CMatrix* m_pBaseTransform; // матрица перерасчета координатных осей (здесь: миллиметры -> пикселы) - Aggplus::CMatrix* m_pTransform; // текущая матрица преобразований рендерера - Aggplus::CMatrix* m_pFullTransform; // полная матрица преобразований (m_oBaseTransform * m_oTransform) - - double m_dTransformAngle; - - LONG m_lCurrentCommandType; // текущая команда - - double m_dDpiX; - double m_dDpiY; - - double m_dWidth; - double m_dHeight; - - LONG m_lClipMode; - - NSStructures::CPen* m_pPen; // настройки всей графики (скопирован ашник из AVSGraphics) - NSStructures::CBrush* m_pBrush; - NSStructures::CFont* m_pFont; - - NSStructures::CFont* m_pInstalledFont; - - bool m_bIsRaster; - - double m_dTextScale; - bool m_bIsTextPath; - //todo - //IASCWinFonts* m_pFonts; - - protected: - void CalculateFullTransform(); - inline void MoveTo(const double& dX, const double& dY); - inline void LineTo(const double& dX, const double& dY); - inline void CurveTo(const double& x1, const double& y1, const double& x2, const double& y2, const double& x3, const double& y3); - void Start(); - void End(); - void Close(); - void _SetFont(); - }; -} - -#endif // _ASC_HTMLRENDERER_SVG_WRITER_H_ diff --git a/HtmlRenderer/include/HTMLRenderer3.h b/HtmlRenderer/include/HTMLRenderer3.h deleted file mode 100644 index 44872985058..00000000000 --- a/HtmlRenderer/include/HTMLRenderer3.h +++ /dev/null @@ -1,204 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2023 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _ASC_HTMLRENDERER3_H_ -#define _ASC_HTMLRENDERER3_H_ - -#include "../../DesktopEditor/graphics/IRenderer.h" -#include "../../DesktopEditor/graphics/pro/officedrawingfile.h" - -#ifndef HTMLRENDERER_USE_DYNAMIC_LIBRARY -#define HTMLRENDERER_DECL_EXPORT -#else -#include "../../DesktopEditor/common/base_export.h" -#define HTMLRENDERER_DECL_EXPORT Q_DECL_EXPORT -#endif - -namespace NSHtmlRenderer -{ - class CASCHTMLRenderer3_Private; - class HTMLRENDERER_DECL_EXPORT CASCHTMLRenderer3 : public IRenderer - { - public: - CASCHTMLRenderer3(); - virtual ~CASCHTMLRenderer3(); - public: - // тип рендерера----------------------------------------------------------------------------- - virtual HRESULT get_Type(LONG* lType); - //-------- Функции для работы со страницей -------------------------------------------------- - virtual HRESULT NewPage(); - virtual HRESULT get_Height(double* dHeight); - virtual HRESULT put_Height(const double& dHeight); - virtual HRESULT get_Width(double* dWidth); - virtual HRESULT put_Width(const double& dWidth); - virtual HRESULT get_DpiX(double* dDpiX); - virtual HRESULT get_DpiY(double* dDpiY); - - // pen -------------------------------------------------------------------------------------- - virtual HRESULT get_PenColor(LONG* lColor); - virtual HRESULT put_PenColor(const LONG& lColor); - virtual HRESULT get_PenAlpha(LONG* lAlpha); - virtual HRESULT put_PenAlpha(const LONG& lAlpha); - virtual HRESULT get_PenSize(double* dSize); - virtual HRESULT put_PenSize(const double& dSize); - virtual HRESULT get_PenDashStyle(BYTE* val); - virtual HRESULT put_PenDashStyle(const BYTE& val); - virtual HRESULT get_PenLineStartCap(BYTE* val); - virtual HRESULT put_PenLineStartCap(const BYTE& val); - virtual HRESULT get_PenLineEndCap(BYTE* val); - virtual HRESULT put_PenLineEndCap(const BYTE& val); - virtual HRESULT get_PenLineJoin(BYTE* val); - virtual HRESULT put_PenLineJoin(const BYTE& val); - virtual HRESULT get_PenDashOffset(double* dOffset); - virtual HRESULT put_PenDashOffset(const double& dOffset); - virtual HRESULT get_PenAlign(LONG* lAlign); - virtual HRESULT put_PenAlign(const LONG& lAlign); - virtual HRESULT get_PenMiterLimit(double* dOffset); - virtual HRESULT put_PenMiterLimit(const double& dOffset); - virtual HRESULT PenDashPattern(double* pPattern, LONG lCount); - - // brush ------------------------------------------------------------------------------------ - virtual HRESULT get_BrushType(LONG* lType); - virtual HRESULT put_BrushType(const LONG& lType); - virtual HRESULT get_BrushColor1(LONG* lColor); - virtual HRESULT put_BrushColor1(const LONG& lColor); - virtual HRESULT get_BrushAlpha1(LONG* lAlpha); - virtual HRESULT put_BrushAlpha1(const LONG& lAlpha); - virtual HRESULT get_BrushColor2(LONG* lColor); - virtual HRESULT put_BrushColor2(const LONG& lColor); - virtual HRESULT get_BrushAlpha2(LONG* lAlpha); - virtual HRESULT put_BrushAlpha2(const LONG& lAlpha); - virtual HRESULT get_BrushTexturePath(std::wstring* bsPath); - virtual HRESULT put_BrushTexturePath(const std::wstring& bsPath); - virtual HRESULT get_BrushTextureMode(LONG* lMode); - virtual HRESULT put_BrushTextureMode(const LONG& lMode); - virtual HRESULT get_BrushTextureAlpha(LONG* lTxAlpha); - virtual HRESULT put_BrushTextureAlpha(const LONG& lTxAlpha); - virtual HRESULT get_BrushLinearAngle(double* dAngle); - virtual HRESULT put_BrushLinearAngle(const double& dAngle); - virtual HRESULT BrushRect(const INT& val, const double& left, const double& top, const double& width, const double& height); - virtual HRESULT BrushBounds(const double& left, const double& top, const double& width, const double& height); - - virtual HRESULT put_BrushGradientColors(LONG* lColors, double* pPositions, LONG nCount); - - virtual HRESULT get_BrushTextureImage(Aggplus::CImage** pImage); - virtual HRESULT put_BrushTextureImage(Aggplus::CImage* pImage); - virtual HRESULT get_BrushTransform(Aggplus::CMatrix& oMatrix); - virtual HRESULT put_BrushTransform(const Aggplus::CMatrix& oMatrix); - - // font ------------------------------------------------------------------------------------- - virtual HRESULT get_FontName(std::wstring* bsName); - virtual HRESULT put_FontName(const std::wstring& bsName); - virtual HRESULT get_FontPath(std::wstring* bsName); - virtual HRESULT put_FontPath(const std::wstring& bsName); - virtual HRESULT get_FontSize(double* dSize); - virtual HRESULT put_FontSize(const double& dSize); - virtual HRESULT get_FontStyle(LONG* lStyle); - virtual HRESULT put_FontStyle(const LONG& lStyle); - virtual HRESULT get_FontStringGID(INT* bGID); - virtual HRESULT put_FontStringGID(const INT& bGID); - virtual HRESULT get_FontCharSpace(double* dSpace); - virtual HRESULT put_FontCharSpace(const double& dSpace); - virtual HRESULT get_FontFaceIndex(int* lFaceIndex); - virtual HRESULT put_FontFaceIndex(const int& lFaceIndex); - - //-------- Функции для вывода текста -------------------------------------------------------- - virtual HRESULT CommandDrawTextCHAR(const LONG& c, const double& x, const double& y, const double& w, const double& h); - virtual HRESULT CommandDrawText(const std::wstring& bsText, const double& x, const double& y, const double& w, const double& h); - - virtual HRESULT CommandDrawTextExCHAR(const LONG& c, const LONG& gid, const double& x, const double& y, const double& w, const double& h); - virtual HRESULT CommandDrawTextEx(const std::wstring& bsUnicodeText, const unsigned int* pGids, const unsigned int nGidsCount, const double& x, const double& y, const double& w, const double& h); - - //-------- Маркеры для команд --------------------------------------------------------------- - virtual HRESULT BeginCommand(const DWORD& lType); - virtual HRESULT EndCommand(const DWORD& lType); - - //-------- Функции для работы с Graphics Path ----------------------------------------------- - virtual HRESULT PathCommandMoveTo(const double& x, const double& y); - virtual HRESULT PathCommandLineTo(const double& x, const double& y); - virtual HRESULT PathCommandLinesTo(double* points, const int& count); - virtual HRESULT PathCommandCurveTo(const double& x1, const double& y1, const double& x2, const double& y2, const double& x3, const double& y3); - virtual HRESULT PathCommandCurvesTo(double* points, const int& count); - virtual HRESULT PathCommandArcTo(const double& x, const double& y, const double& w, const double& h, const double& startAngle, const double& sweepAngle); - virtual HRESULT PathCommandClose(); - virtual HRESULT PathCommandEnd(); - virtual HRESULT DrawPath(const LONG& nType); - virtual HRESULT PathCommandStart(); - virtual HRESULT PathCommandGetCurrentPoint(double* x, double* y); - - virtual HRESULT PathCommandTextCHAR(const LONG& c, const double& x, const double& y, const double& w, const double& h); - virtual HRESULT PathCommandText(const std::wstring& bsText, const double& x, const double& y, const double& w, const double& h); - - virtual HRESULT PathCommandTextExCHAR(const LONG& c, const LONG& gid, const double& x, const double& y, const double& w, const double& h); - virtual HRESULT PathCommandTextEx(const std::wstring& bsUnicodeText, const unsigned int* pGids, const unsigned int nGidsCount, const double& x, const double& y, const double& w, const double& h); - - //-------- Функции для вывода изображений --------------------------------------------------- - virtual HRESULT DrawImage(IGrObject* pImage, const double& x, const double& y, const double& w, const double& h); - virtual HRESULT DrawImageFromFile(const std::wstring&, const double& x, const double& y, const double& w, const double& h, const BYTE& lAlpha = 255); - - // transform -------------------------------------------------------------------------------- - virtual HRESULT SetTransform(const double& m1, const double& m2, const double& m3, const double& m4, const double& m5, const double& m6); - virtual HRESULT GetTransform(double *pdA, double *pdB, double *pdC, double *pdD, double *pdE, double *pdF); - virtual HRESULT ResetTransform(); - - // ----------------------------------------------------------------------------------------- - virtual HRESULT get_ClipMode(LONG* plMode); - virtual HRESULT put_ClipMode(const LONG& lMode); - - // additiaonal params ---------------------------------------------------------------------- - virtual HRESULT CommandLong(const LONG& lType, const LONG& lCommand); - virtual HRESULT CommandDouble(const LONG& lType, const double& dCommand); - virtual HRESULT CommandString(const LONG& lType, const std::wstring& sCommand); - - virtual HRESULT StartConvertCoordsToIdentity(); - virtual HRESULT EndConvertCoordsToIdentity(); - - // owner params ---------------------------------------------------------------------- - virtual HRESULT get_Mode(LONG *plMode); - virtual HRESULT put_Mode(LONG lMode); - - virtual HRESULT CreateOfficeFile(std::wstring bsFileName, const std::wstring& fontsDir = L""); - virtual HRESULT CloseFile(bool bIsNoBase64 = false); - - virtual HRESULT SetAdditionalParam(std::string sParamName, int nValue); - virtual HRESULT SetAdditionalParam(std::string sParamName, const std::wstring& sParam); - - bool GetOnlyTextMode(); - void SetOnlyTextMode(const bool& enabled); - - void GetLastPageInfo(int& paragraphs, int& words, int& symbols, int& spaces, std::string& sBase64Data); - - protected: - CASCHTMLRenderer3_Private* m_pInternal; - }; -} - -#endif // _ASC_HTMLRENDERER3_H_ diff --git a/HtmlRenderer/src/ASCSVGWriter.cpp b/HtmlRenderer/src/ASCSVGWriter.cpp deleted file mode 100644 index 84e21b147cd..00000000000 --- a/HtmlRenderer/src/ASCSVGWriter.cpp +++ /dev/null @@ -1,1053 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2023 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#include "../include/ASCSVGWriter.h" - -#include "../../DesktopEditor/graphics/GraphicsPath.h" -#include "VectorGraphicsWriter2.h" -#include "../../DesktopEditor/graphics/pro/Graphics.h" - -namespace NSHtmlRenderer -{ - CASCSVGWriter::CASCSVGWriter(bool bIsInitializeFonts) - { - m_dDpiX = 72; - m_dDpiY = 72; - - m_dWidth = 100; - m_dHeight = 100; - m_bIsRaster = false; - - m_lClipMode = c_nClipRegionTypeWinding; - - m_pSimpleGraphicsConverter = new Aggplus::CGraphicsPathSimpleConverter(); - m_pSimpleGraphicsConverter->SetRenderer(this); - - m_dTransformAngle = 0.0; - - m_pFontManager = NULL; - m_pPen = new NSStructures::CPen(); - m_pBrush = new NSStructures::CBrush(); - m_pFont = new NSStructures::CFont(); - m_pInstalledFont = new NSStructures::CFont(); - - m_pBaseTransform = new Aggplus::CMatrix(); - m_pTransform = new Aggplus::CMatrix(); - m_pFullTransform = new Aggplus::CMatrix(); - - //todo вроде как подбора нет, но может нужно передавать? - m_pFontManager = NULL; - if (bIsInitializeFonts) - { - m_pFontManager = NSFonts::NSFontManager::Create(); - m_pFontManager->Initialize(); - } - - m_pVectorWriter = new NSHtmlRenderer::CSVGGraphicsWriter(); - m_pVectorWriter->m_pSimpleConverter = m_pSimpleGraphicsConverter; - m_pVectorWriter->m_pFullTransform = m_pFullTransform; - m_pVectorWriter->SetSettings(m_pPen, m_pBrush, m_pSimpleGraphicsConverter); - } - CASCSVGWriter::~CASCSVGWriter() - { - RELEASEOBJECT(m_pSimpleGraphicsConverter); - RELEASEOBJECT(m_pPen); - RELEASEOBJECT(m_pBrush); - RELEASEOBJECT(m_pFont); - RELEASEOBJECT(m_pInstalledFont); - RELEASEOBJECT(m_pBaseTransform); - RELEASEOBJECT(m_pTransform); - RELEASEOBJECT(m_pFullTransform); - RELEASEOBJECT(m_pVectorWriter); - - RELEASEINTERFACE(m_pFontManager); - } - void CASCSVGWriter::Reset() - { - m_dDpiX = 72; - m_dDpiY = 72; - - m_dWidth = 100; - m_dHeight = 100; - m_bIsRaster = false; - - m_lClipMode = c_nClipRegionTypeWinding; - - RELEASEOBJECT(m_pSimpleGraphicsConverter); - - RELEASEOBJECT(m_pPen); - RELEASEOBJECT(m_pBrush); - RELEASEOBJECT(m_pFont); - RELEASEOBJECT(m_pInstalledFont); - RELEASEOBJECT(m_pBaseTransform); - RELEASEOBJECT(m_pTransform); - RELEASEOBJECT(m_pFullTransform); - RELEASEOBJECT(m_pVectorWriter); - - m_pSimpleGraphicsConverter = new Aggplus::CGraphicsPathSimpleConverter(); - m_pSimpleGraphicsConverter->SetRenderer(this); - - m_dTransformAngle = 0.0; - - m_pPen = new NSStructures::CPen(); - m_pBrush = new NSStructures::CBrush(); - m_pFont = new NSStructures::CFont(); - m_pInstalledFont = new NSStructures::CFont(); - - m_pBaseTransform = new Aggplus::CMatrix(); - m_pTransform = new Aggplus::CMatrix(); - m_pFullTransform = new Aggplus::CMatrix(); - - m_pVectorWriter = new NSHtmlRenderer::CSVGGraphicsWriter(); - m_pVectorWriter->m_pSimpleConverter = m_pSimpleGraphicsConverter; - m_pVectorWriter->m_pFullTransform = m_pFullTransform; - m_pVectorWriter->SetSettings(m_pPen, m_pBrush, m_pSimpleGraphicsConverter); - } - - HRESULT CASCSVGWriter::get_Type(LONG* lType) - { - if (NULL == lType) - return S_FALSE; - - *lType = c_nSVGRendrerer; - return S_OK; - } - //-------- Функции для работы со страницей -------------------------------------------------- - HRESULT CASCSVGWriter::NewPage() - { - return S_OK; - } - HRESULT CASCSVGWriter::get_Height(double* dHeight) - { - *dHeight = m_dHeight; - return S_OK; - } - HRESULT CASCSVGWriter::put_Height(const double& dHeight) - { - m_dHeight = dHeight; - return S_OK; - } - HRESULT CASCSVGWriter::get_Width(double* dWidth) - { - *dWidth = m_dWidth; - return S_OK; - } - HRESULT CASCSVGWriter::put_Width(const double& dWidth) - { - m_dWidth = dWidth; - return S_OK; - } - - HRESULT CASCSVGWriter::get_DpiX(double* dDpiX) - { - if (NULL != dDpiX) - *dDpiX = m_dDpiX; - return S_OK; - } - HRESULT CASCSVGWriter::get_DpiY(double* dDpiY) - { - if (NULL != dDpiY) - *dDpiY = m_dDpiY; - return S_OK; - } - // pen -------------------------------------------------------------------------------------- - HRESULT CASCSVGWriter::get_PenColor(LONG* lColor) - { - *lColor = m_pPen->Color; - return S_OK; - } - HRESULT CASCSVGWriter::put_PenColor(const LONG& lColor) - { - m_pPen->Color = lColor; - return S_OK; - } - HRESULT CASCSVGWriter::get_PenAlpha(LONG* lAlpha) - { - *lAlpha = m_pPen->Alpha; - return S_OK; - } - HRESULT CASCSVGWriter::put_PenAlpha(const LONG& lAlpha) - { - m_pPen->Alpha = lAlpha; - return S_OK; - } - HRESULT CASCSVGWriter::get_PenSize(double* dSize) - { - *dSize = m_pPen->Size; - return S_OK; - } - HRESULT CASCSVGWriter::put_PenSize(const double& dSize) - { - m_pPen->Size = dSize; - return S_OK; - } - HRESULT CASCSVGWriter::get_PenDashStyle(BYTE* val) - { - *val = m_pPen->DashStyle; - return S_OK; - } - HRESULT CASCSVGWriter::put_PenDashStyle(const BYTE& val) - { - m_pPen->DashStyle = val; - return S_OK; - } - HRESULT CASCSVGWriter::get_PenLineStartCap(BYTE* val) - { - *val = m_pPen->LineStartCap; - return S_OK; - } - HRESULT CASCSVGWriter::put_PenLineStartCap(const BYTE& val) - { - m_pPen->LineStartCap = val; - return S_OK; - } - HRESULT CASCSVGWriter::get_PenLineEndCap(BYTE* val) - { - *val = m_pPen->LineEndCap; - return S_OK; - } - HRESULT CASCSVGWriter::put_PenLineEndCap(const BYTE& val) - { - m_pPen->LineEndCap = val; - return S_OK; - } - HRESULT CASCSVGWriter::get_PenLineJoin(BYTE* val) - { - *val = m_pPen->LineJoin; - return S_OK; - } - HRESULT CASCSVGWriter::put_PenLineJoin(const BYTE& val) - { - m_pPen->LineJoin = val; - return S_OK; - } - HRESULT CASCSVGWriter::get_PenDashOffset(double* val) - { - *val = m_pPen->DashOffset; - return S_OK; - } - HRESULT CASCSVGWriter::put_PenDashOffset(const double& val) - { - m_pPen->DashOffset = val; - return S_OK; - } - HRESULT CASCSVGWriter::get_PenAlign(LONG* val) - { - *val = m_pPen->Align; - return S_OK; - } - HRESULT CASCSVGWriter::put_PenAlign(const LONG& val) - { - m_pPen->Align = val; - return S_OK; - } - HRESULT CASCSVGWriter::get_PenMiterLimit(double* val) - { - *val = m_pPen->MiterLimit; - return S_OK; - } - HRESULT CASCSVGWriter::put_PenMiterLimit(const double& val) - { - m_pPen->MiterLimit = val; - return S_OK; - } - HRESULT CASCSVGWriter::PenDashPattern(double* pPattern, LONG lCount) - { - if (NULL != pPattern) - { - m_pPen->SetDashPattern(pPattern, lCount); - } - - return S_OK; - } - // brush ------------------------------------------------------------------------------------ - HRESULT CASCSVGWriter::get_BrushType(LONG* lType) - { - *lType = m_pBrush->Type; - return S_OK; - } - HRESULT CASCSVGWriter::put_BrushType(const LONG& lType) - { - m_pBrush->Type = lType; - return S_OK; - } - HRESULT CASCSVGWriter::get_BrushColor1(LONG* lColor) - { - *lColor = m_pBrush->Color1; - return S_OK; - } - HRESULT CASCSVGWriter::put_BrushColor1(const LONG& lColor) - { - m_pBrush->Color1 = lColor; - return S_OK; - } - HRESULT CASCSVGWriter::get_BrushAlpha1(LONG* lAlpha) - { - *lAlpha = m_pBrush->Alpha1; - return S_OK; - } - HRESULT CASCSVGWriter::put_BrushAlpha1(const LONG& lAlpha) - { - m_pBrush->Alpha1 = lAlpha; - return S_OK; - } - HRESULT CASCSVGWriter::get_BrushColor2(LONG* lColor) - { - *lColor = m_pBrush->Color2; - return S_OK; - } - HRESULT CASCSVGWriter::put_BrushColor2(const LONG& lColor) - { - m_pBrush->Color2 = lColor; - return S_OK; - } - HRESULT CASCSVGWriter::get_BrushAlpha2(LONG* lAlpha) - { - *lAlpha = m_pBrush->Alpha2; - return S_OK; - } - HRESULT CASCSVGWriter::put_BrushAlpha2(const LONG& lAlpha) - { - m_pBrush->Alpha2 = lAlpha; - return S_OK; - } - HRESULT CASCSVGWriter::get_BrushTexturePath(std::wstring* bsPath) - { - *bsPath = m_pBrush->TexturePath; - return S_OK; - } - HRESULT CASCSVGWriter::put_BrushTexturePath(const std::wstring& bsPath) - { - m_pBrush->TexturePath = bsPath; - return S_OK; - } - HRESULT CASCSVGWriter::get_BrushTextureMode(LONG* lMode) - { - *lMode = m_pBrush->TextureMode; - return S_OK; - } - HRESULT CASCSVGWriter::put_BrushTextureMode(const LONG& lMode) - { - m_pBrush->TextureMode = lMode; - return S_OK; - } - HRESULT CASCSVGWriter::get_BrushTextureAlpha(LONG* lTxAlpha) - { - *lTxAlpha = m_pBrush->TextureAlpha; - return S_OK; - } - HRESULT CASCSVGWriter::put_BrushTextureAlpha(const LONG& lTxAlpha) - { - m_pBrush->TextureAlpha = lTxAlpha; - return S_OK; - } - HRESULT CASCSVGWriter::get_BrushLinearAngle(double* dAngle) - { - *dAngle = m_pBrush->LinearAngle; - return S_OK; - } - HRESULT CASCSVGWriter::put_BrushLinearAngle(const double& dAngle) - { - m_pBrush->LinearAngle = dAngle; - return S_OK; - } - HRESULT CASCSVGWriter::BrushRect(const INT& val, const double& left, const double& top, const double& width, const double& height) - { - m_pBrush->Rectable = val; - m_pBrush->Rect.X = (float)left; - m_pBrush->Rect.Y = (float)top; - m_pBrush->Rect.Width = (float)width; - m_pBrush->Rect.Height = (float)height; - - return S_OK; - } - HRESULT CASCSVGWriter::BrushBounds(const double& left, const double& top, const double& width, const double& height) - { - return S_OK; - } - - HRESULT CASCSVGWriter::put_BrushGradientColors(LONG* lColors, double* pPositions, LONG nCount) - { - return S_OK; - } - - // font ------------------------------------------------------------------------------------- - HRESULT CASCSVGWriter::get_FontName(std::wstring* bsName) - { - *bsName = m_pFont->Name; - return S_OK; - } - HRESULT CASCSVGWriter::put_FontName(const std::wstring& bsName) - { - m_pFont->Name = bsName; - return S_OK; - } - HRESULT CASCSVGWriter::get_FontPath(std::wstring* bsName) - { - *bsName = m_pFont->Path; - return S_OK; - } - HRESULT CASCSVGWriter::put_FontPath(const std::wstring& bsName) - { - m_pFont->Path = bsName; - return S_OK; - } - HRESULT CASCSVGWriter::get_FontSize(double* dSize) - { - *dSize = m_pFont->Size; - return S_OK; - } - HRESULT CASCSVGWriter::put_FontSize(const double& dSize) - { - m_pFont->Size = dSize; - return S_OK; - } - HRESULT CASCSVGWriter::get_FontStyle(LONG* lStyle) - { - *lStyle = m_pFont->GetStyle(); - return S_OK; - } - HRESULT CASCSVGWriter::put_FontStyle(const LONG& lStyle) - { - m_pFont->SetStyle(lStyle); - return S_OK; - } - HRESULT CASCSVGWriter::get_FontStringGID(INT* bGID) - { - *bGID = m_pFont->StringGID; - return S_OK; - } - HRESULT CASCSVGWriter::put_FontStringGID(const INT& bGID) - { - m_pFont->StringGID = bGID; - m_pFontManager->SetStringGID(bGID); - return S_OK; - } - HRESULT CASCSVGWriter::get_FontCharSpace(double* dSpace) - { - *dSpace = m_pFont->CharSpace; - return S_OK; - } - HRESULT CASCSVGWriter::put_FontCharSpace(const double& dSpace) - { - m_pFont->CharSpace = dSpace; - return S_OK; - } - HRESULT CASCSVGWriter::get_FontFaceIndex(int* lFaceIndex) - { - *lFaceIndex = m_pFont->FaceIndex; - return S_OK; - } - HRESULT CASCSVGWriter::put_FontFaceIndex(const int& lFaceIndex) - { - m_pFont->FaceIndex = lFaceIndex; - return S_OK; - } - //-------- Функции для вывода текста -------------------------------------------------------- - HRESULT CASCSVGWriter::CommandDrawTextCHAR(const LONG& c, const double& x, const double& y, const double& w, const double& h) - { - if (m_bIsRaster) - return S_OK; - - m_bIsTextPath = true; - PathCommandEnd(); - BeginCommand(c_nPathType); - PathCommandTextCHAR(c, x, y, w, h); - DrawPath(c_nWindingFillMode); - EndCommand(c_nPathType); - PathCommandEnd(); - m_bIsTextPath = false; - return S_OK; - } - HRESULT CASCSVGWriter::CommandDrawText(const std::wstring& bsText,const double& x,const double& y,const double& w, const double& h) - { - if (c_nHyperlinkType == m_lCurrentCommandType) - return S_OK; - - if (m_bIsRaster) - return S_OK; - - m_bIsTextPath = true; - PathCommandEnd(); - BeginCommand(c_nPathType); - PathCommandText(bsText, x, y, w, h); - DrawPath(c_nWindingFillMode); - EndCommand(c_nPathType); - PathCommandEnd(); - m_bIsTextPath = false; - return S_OK; - } - HRESULT CASCSVGWriter::CommandDrawTextExCHAR(const LONG& c, const LONG& gid, const double& x, const double& y, const double& w, const double& h) - { - if (m_bIsRaster) - return S_OK; - - m_bIsTextPath = true; - PathCommandEnd(); - BeginCommand(c_nPathType); - PathCommandTextExCHAR(c, gid, x, y, w, h); - DrawPath(c_nWindingFillMode); - EndCommand(c_nPathType); - PathCommandEnd(); - m_bIsTextPath = false; - return S_OK; - } - HRESULT CASCSVGWriter::CommandDrawTextEx(const std::wstring& bsUnicodeText, const unsigned int* pGids, const unsigned int nGidsCount, const double& x, const double& y, const double& w, const double& h) - { - if (m_bIsRaster) - return S_OK; - - m_bIsTextPath = true; - PathCommandEnd(); - BeginCommand(c_nPathType); - PathCommandTextEx(bsUnicodeText, pGids,nGidsCount , x, y, w, h); - DrawPath(c_nWindingFillMode); - EndCommand(c_nPathType); - PathCommandEnd(); - m_bIsTextPath = false; - return S_OK; - } - //-------- Маркеры для команд --------------------------------------------------------------- - HRESULT CASCSVGWriter::BeginCommand(const DWORD& lType) - { - if (m_bIsRaster) - return S_OK; - - if (c_nClipType == lType) - { - m_pVectorWriter->WritePathClip(); - } - else if (c_nPathType == lType) - { - m_pVectorWriter->WritePathStart(); - m_pSimpleGraphicsConverter->PathCommandEnd(); - } - m_lCurrentCommandType = lType; - return S_OK; - } - HRESULT CASCSVGWriter::EndCommand(const DWORD& lType) - { - if (m_bIsRaster) - return S_OK; - - if (c_nClipType == lType) - { - m_pVectorWriter->WritePathClipEnd(); - } - else if (c_nResetClipType == lType) - { - m_pVectorWriter->WritePathResetClip(); - } - m_lCurrentCommandType = -1; - return S_OK; - } - //-------- Функции для работы с Graphics Path ----------------------------------------------- - HRESULT CASCSVGWriter::PathCommandMoveTo(const double& fX, const double& fY) - { - if (m_bIsRaster) - return S_OK; - - if (c_nSimpleGraphicType == m_lCurrentCommandType) - { - MoveTo(fX, fY); - } - else - { - m_pSimpleGraphicsConverter->PathCommandMoveTo(fX, fY); - } - return S_OK; - } - HRESULT CASCSVGWriter::PathCommandLineTo(const double& fX, const double& fY) - { - if (m_bIsRaster) - return S_OK; - - if (c_nSimpleGraphicType == m_lCurrentCommandType) - { - LineTo(fX, fY); - } - else - { - m_pSimpleGraphicsConverter->PathCommandLineTo(fX, fY); - } - - return S_OK; - } - HRESULT CASCSVGWriter::PathCommandLinesTo(double* points, const int& count) - { - if (m_bIsRaster) - return S_OK; - - m_pSimpleGraphicsConverter->PathCommandLinesTo(points, count); - return S_OK; - } - HRESULT CASCSVGWriter::PathCommandCurveTo(const double& fX1, const double& fY1, const double& fX2, const double& fY2, const double& fX3, const double& fY3) - { - if (m_bIsRaster) - return S_OK; - - if (c_nSimpleGraphicType == m_lCurrentCommandType) - { - CurveTo(fX1, fY1, fX2, fY2, fX3, fY3); - } - else - { - m_pSimpleGraphicsConverter->PathCommandCurveTo(fX1, fY1, fX2, fY2, fX3, fY3); - } - - return S_OK; - } - HRESULT CASCSVGWriter::PathCommandCurvesTo(double* points, const int& count) - { - if (m_bIsRaster) - return S_OK; - - m_pSimpleGraphicsConverter->PathCommandCurvesTo(points, count); - return S_OK; - } - HRESULT CASCSVGWriter::PathCommandArcTo(const double& fX, const double& fY, const double& fWidth, const double& fHeight, const double& fStartAngle, const double& fSweepAngle) - { - if (m_bIsRaster) - return S_OK; - - m_pSimpleGraphicsConverter->PathCommandArcTo(fX, fY, fWidth, fHeight, fStartAngle, fSweepAngle); - return S_OK; - } - HRESULT CASCSVGWriter::PathCommandClose() - { - if (m_bIsRaster) - return S_OK; - - if (c_nSimpleGraphicType == m_lCurrentCommandType) - { - Close(); - } - else - { - m_pSimpleGraphicsConverter->PathCommandClose(); - } - - return S_OK; - } - HRESULT CASCSVGWriter::PathCommandEnd() - { - if (m_bIsRaster) - return S_OK; - - if (c_nSimpleGraphicType == m_lCurrentCommandType) - { - End(); - } - else - { - m_pSimpleGraphicsConverter->PathCommandEnd(); - } - - return S_OK; - } - HRESULT CASCSVGWriter::DrawPath(const long& nType) - { - switch (m_pBrush->Type) - { - case c_BrushTypeTexture: - case c_BrushTypePathGradient1: - case c_BrushTypePathGradient2: - { - m_bIsRaster = true; - break; - } - default: - break; - } - - if (m_bIsRaster) - return S_OK; - - m_pVectorWriter->WriteDrawPath(nType); - return S_OK; - } - HRESULT CASCSVGWriter::PathCommandStart() - { - if (m_bIsRaster) - return S_OK; - - if (c_nSimpleGraphicType == m_lCurrentCommandType) - { - Start(); - } - else - { - m_pSimpleGraphicsConverter->PathCommandEnd(); - m_pSimpleGraphicsConverter->PathCommandStart(); - } - - return S_OK; - } - HRESULT CASCSVGWriter::PathCommandGetCurrentPoint(double* fX, double* fY) - { - m_pSimpleGraphicsConverter->PathCommandGetCurrentPoint(fX, fY); - return S_OK; - } - HRESULT CASCSVGWriter::PathCommandTextCHAR(const LONG& c, const double& x, const double& y, const double& w, const double& h) - { - if (m_bIsRaster) - return S_OK; - - int _c = (int)c; - - _SetFont(); - m_pSimpleGraphicsConverter->PathCommandText2(&_c, NULL, 1, m_pFontManager, x, y, w, h); - return S_OK; - } - HRESULT CASCSVGWriter::PathCommandText(const std::wstring& bsText, const double& fX, const double& fY, const double& fWidth, const double& fHeight) - { - if (m_bIsRaster) - return S_OK; - - _SetFont(); - m_pSimpleGraphicsConverter->PathCommandText(bsText, m_pFontManager, fX, fY, fWidth, fHeight, 0); - return S_OK; - } - HRESULT CASCSVGWriter::PathCommandTextExCHAR(const LONG& c, const LONG& gid, const double& x, const double& y, const double& w, const double& h) - { - if (m_bIsRaster) - return S_OK; - - _SetFont(); - - int _c = (int)c; - int _g = (int)gid; - - m_pSimpleGraphicsConverter->PathCommandText2(&_c, &_g, 1, m_pFontManager, x, y, w, h); - return S_OK; - } - HRESULT CASCSVGWriter::PathCommandTextEx(const std::wstring& sText, const unsigned int* pGids, const unsigned int nGidsCount, const double& x, const double& y, const double& w, const double& h) - { - if (m_bIsRaster) - return S_OK; - - _SetFont(); - - m_pSimpleGraphicsConverter->PathCommandText2(sText, (const int*)pGids, nGidsCount, m_pFontManager, x, y, w, h); - return S_OK; - } - //-------- Функции для вывода изображений --------------------------------------------------- - HRESULT CASCSVGWriter::DrawImage(IGrObject* pImage, const double& fX, const double& fY, const double& fWidth, const double& fHeight) - { - m_bIsRaster = true; - /* - double x = fX; - double y = fY; - - double r = fX + fWidth; - double b = fY + fHeight; - - if (0 == m_dTransformAngle) - { - m_pFullTransform->TransformPoint(x, y); - m_pFullTransform->TransformPoint(r, b); - } - else - { - NSHtmlRenderer::CMatrix oTemp = *m_pFullTransform; - - double dCx = (x + r) / 2; - double dCy = (y + b) / 2; - m_pFullTransform->TransformPoint(dCx, dCy); - oTemp.RotateAt(-m_dTransformAngle, dCx, dCy, Aggplus::MatrixOrderAppend); - - oTemp.TransformPoint(x, y); - oTemp.TransformPoint(r, b); - } - - m_oWriter.WriteImage(pInterface, x, y, r - x, b - y, m_dTransformAngle); - */ - - return S_OK; - } - HRESULT CASCSVGWriter::DrawImageFromFile(const std::wstring& sVal, const double& x, const double& y, const double& w, const double& h, const BYTE& lAlpha = 255) - { - m_bIsRaster = true; - /* - double x = fX; - double y = fY; - - double r = fX + fWidth; - double b = fY + fHeight; - - if (0 == m_dTransformAngle) - { - m_pFullTransform->TransformPoint(x, y); - m_pFullTransform->TransformPoint(r, b); - } - else - { - NSHtmlRenderer::CMatrix oTemp = *m_pFullTransform; - - double dCx = (x + r) / 2; - double dCy = (y + b) / 2; - m_pFullTransform->TransformPoint(dCx, dCy); - oTemp.RotateAt(-m_dTransformAngle, dCx, dCy, Aggplus::MatrixOrderAppend); - - oTemp.TransformPoint(x, y); - oTemp.TransformPoint(r, b); - } - - m_oWriter.WriteImage((std::wstring)bstrVal, x, y, r - x, b - y, m_pTransform->z_Rotation()); - */ - - return S_OK; - } - // transform -------------------------------------------------------------------------------- - HRESULT CASCSVGWriter::SetTransform(const double& dA, const double& dB, const double& dC, const double& dD, const double& dE, const double& dF) - { - Aggplus::CMatrix oTrans(dA, dB, dC, dD, dE, dF); - *m_pTransform = oTrans; - - CalculateFullTransform(); - - return S_OK; - } - HRESULT CASCSVGWriter::GetTransform(double *pdA, double *pdB, double *pdC, double *pdD, double *pdE, double *pdF) - { - *pdA = m_pTransform->sx(); - *pdB = m_pTransform->shy(); - *pdC = m_pTransform->shx(); - *pdD = m_pTransform->sy(); - *pdE = m_pTransform->tx(); - *pdF = m_pTransform->ty(); - return S_OK; - } - HRESULT CASCSVGWriter::ResetTransform(void) - { - m_pTransform->Reset(); - CalculateFullTransform(); - return S_OK; - } - // ----------------------------------------------------------------------------------------- - HRESULT CASCSVGWriter::get_ClipMode(LONG* plMode) - { - *plMode = m_lClipMode; - return S_OK; - } - HRESULT CASCSVGWriter::put_ClipMode(const LONG& lMode) - { - m_lClipMode = lMode; - m_pVectorWriter->SetClipMode(m_lClipMode); - return S_OK; - } - // additiaonal params ---------------------------------------------------------------------- - HRESULT CASCSVGWriter::SaveFile(const std::wstring& strFileSave) - { - NSFile::CFileBinary oFile; - if(oFile.CreateFileW(strFileSave)) - { - NSStringUtils::CStringBuilder oBuilder; - WriteFormatted(L"\n", &oBuilder); - - oFile.WriteStringUTF8(oBuilder.GetData()); - oFile.WriteStringUTF8(m_pVectorWriter->m_oSVG.m_oDocument.GetData()); - oFile.WriteStringUTF8(L""); - } - oFile.CloseFile(); - return S_OK; - } - HRESULT CASCSVGWriter::ReInit() - { - m_dDpiX = 72.0; - m_dDpiY = 72.0; - - m_dWidth = 100; - m_dHeight = 100; - m_bIsRaster = false; - - m_lClipMode = c_nClipRegionTypeWinding; - - RELEASEOBJECT(m_pSimpleGraphicsConverter); - m_pSimpleGraphicsConverter = new Aggplus::CGraphicsPathSimpleConverter(); - m_pSimpleGraphicsConverter->SetRenderer(this); - - m_dTransformAngle = 0.0; - - - m_pVectorWriter->m_pSimpleConverter = m_pSimpleGraphicsConverter; - m_pVectorWriter->m_pFullTransform = m_pFullTransform; - m_pVectorWriter->SetSettings(m_pPen, m_pBrush, m_pSimpleGraphicsConverter); - - m_pPen->SetDefaultParams(); - m_pBrush->SetDefaultParams(); - m_pFont->SetDefaultParams(); - - m_pBaseTransform->Reset(); - m_pTransform->Reset(); - m_pFullTransform->Reset(); - - m_pVectorWriter->m_oSVG.ReInit(); - return S_OK; - } - HRESULT CASCSVGWriter::IsRaster(bool* bVal) - { - *bVal = m_bIsRaster; - return S_OK; - } - HRESULT CASCSVGWriter::GetSVGDataSize(LONG* lVal) - { - *lVal = m_pVectorWriter ? m_pVectorWriter->m_oSVG.m_oDocument.GetCurSize() : 0; - return S_OK; - } -// additiaonal params ---------------------------------------------------------------------- - HRESULT CASCSVGWriter::CommandLong(const LONG& lType, const LONG& lCommand) - { - //todo new command - return S_OK; - } - HRESULT CASCSVGWriter::CommandDouble(const LONG& lType, const double& dCommand) - { - //todo new command - return S_OK; - } - HRESULT CASCSVGWriter::CommandString(const LONG& lType, const std::wstring& sCommand) - { - //todo new command - return S_OK; - } - // -------------------------------------------------------------------------------------------- - void CASCSVGWriter::SetFontManager(NSFonts::IFontManager* pFontManager) - { - if (NULL == pFontManager) - return; - - RELEASEINTERFACE(m_pFontManager); - m_pFontManager = pFontManager; - ADDREFINTERFACE(m_pFontManager); - } - void CASCSVGWriter::CalculateFullTransform() - { - *m_pFullTransform = *m_pBaseTransform; - m_pFullTransform->Multiply(m_pTransform, Aggplus::MatrixOrderPrepend); - - m_dTransformAngle = m_pTransform->z_Rotation(); - } - - inline void CASCSVGWriter::MoveTo(const double& dX, const double& dY) - { - double x = dX; - double y = dY; - m_pFullTransform->TransformPoint(x, y); - - m_pVectorWriter->WritePathMoveTo(x, y); - } - inline void CASCSVGWriter::LineTo(const double& dX, const double& dY) - { - double x = dX; - double y = dY; - m_pFullTransform->TransformPoint(x, y); - - m_pVectorWriter->WritePathLineTo(x, y); - } - inline void CASCSVGWriter::CurveTo(const double& x1, const double& y1, const double& x2, const double& y2, const double& x3, const double& y3) - { - double _x1 = x1; - double _y1 = y1; - m_pFullTransform->TransformPoint(_x1, _y1); - - double _x2 = x2; - double _y2 = y2; - m_pFullTransform->TransformPoint(_x2, _y2); - - double _x3 = x3; - double _y3 = y3; - m_pFullTransform->TransformPoint(_x3, _y3); - - m_pVectorWriter->WritePathCurveTo(_x1, _y1, _x2, _y2, _x3, _y3); - } - void CASCSVGWriter::Start() - { - m_pVectorWriter->WritePathStart(); - } - void CASCSVGWriter::End() - { - m_pVectorWriter->WriteEndPath(); - } - void CASCSVGWriter::Close() - { - m_pVectorWriter->WritePathClose(); - } - - void CASCSVGWriter::_SetFont() - { - double dPix = m_pFont->CharSpace * m_dDpiX / 25.4; - - if (m_pInstalledFont->IsEqual(m_pFont)) - { - if (1 < m_dWidth) - { - m_pFontManager->SetCharSpacing(dPix); - } - return; - } - - m_pFontManager->SetStringGID(m_pFont->StringGID); - if (1 < m_dWidth) - { - m_pFontManager->SetCharSpacing(dPix); - } - - double dSizeFont = m_pFont->Size; - m_dTextScale = 1.0; - bool bIsTransform = false; - if (dSizeFont > 1000) - { - bIsTransform = true; - m_dTextScale = dSizeFont / 1000; - dSizeFont = 1000; - } - - if (m_pFont->Path.empty()) - { - m_pFontManager->LoadFontByName(m_pFont->Name, (float)dSizeFont, m_pFont->GetStyle(), m_dDpiX, m_dDpiY); - } - else - { - m_pFontManager->LoadFontFromFile(m_pFont->Path, (float)dSizeFont, m_dDpiX, m_dDpiY, 0); - } - - if (bIsTransform && NULL != m_pFontManager->GetFile()) - { - m_pFontManager->GetFile()->SetFontMatrix(m_dTextScale, 0, 0, m_dTextScale, 0, 0); - m_pFontManager->GetFile()->CheckTextMatrix(); - } - - *m_pInstalledFont = *m_pFont; - } -} diff --git a/HtmlRenderer/src/CanvasWriter.h b/HtmlRenderer/src/CanvasWriter.h deleted file mode 100644 index 1d60dbdbf9e..00000000000 --- a/HtmlRenderer/src/CanvasWriter.h +++ /dev/null @@ -1,243 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2023 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _ASC_HTMLRENDERER_CANVASWRITER_H_ -#define _ASC_HTMLRENDERER_CANVASWRITER_H_ - -#include "Common.h" -#include "../../DesktopEditor/graphics/GraphicsPath.h" - -namespace NSHtmlRenderer -{ - class CCanvasWriter - { - public: - NSStringUtils::CStringBuilder m_oPath; - NSStringUtils::CStringBuilder m_oDocument; - - LONG m_lCurDocumentID; - LONG m_lClippingPath; - - bool m_bIsClipping; - LONG m_lClipMode; - bool m_bIsMoveTo; - - NSStructures::CPen* m_pPen; - NSStructures::CBrush* m_pBrush; - - double m_lWidth; - double m_lHeight; - - double m_dDpiX; - double m_dDpiY; - - public: - CCanvasWriter() : m_oPath(), m_oDocument() - { - m_lCurDocumentID = 0; - m_lClippingPath = 0; - - m_pPen = NULL; - m_pBrush = NULL; - - m_dDpiX = 96; - m_dDpiY = 96; - - m_lClipMode = c_nWindingFillMode; - - m_bIsClipping = false; - m_bIsMoveTo = false; - } - - void SetSettings(NSStructures::CPen* pPen, NSStructures::CBrush* pBrush) - { - m_pPen = pPen; - m_pBrush = pBrush; - } - - void CloseFile(std::wstring strFile = L"") - { - if (!strFile.empty()) - { - NSFile::CFileBinary::SaveToFile(strFile, m_oDocument.GetData()); - } - - m_oDocument.ClearNoAttack(); - m_oPath.ClearNoAttack(); - } - void NewDocument(double& dWidth, double& dHeigth) - { - CloseFile(L""); - - m_lWidth = (int)dWidth; - m_lHeight = (int)dHeigth; - } - - public: - - inline void WritePathEnd() - { - } - inline void WritePathStart() - { - m_bIsMoveTo = false; - m_oDocument.WriteString(L"b(c);\n", 6); - } - void WritePathClose() - { - m_oDocument.WriteString(L"x(c);\n", 6); - } - - void WritePathMoveTo(double& x, double& y) - { - m_oDocument.WriteString(L"m(c,", 4); - WriteIntsToStringBuilder(round(x), round(y), &m_oDocument); - m_oDocument.WriteString(L");\n", 3); - - m_bIsMoveTo = true; - } - void WritePathLineTo(double& x, double& y) - { - if (false == m_bIsMoveTo) - WritePathMoveTo(x, y); - - m_oDocument.WriteString(L"l(c,", 4); - WriteIntsToStringBuilder(round(x), round(y), &m_oDocument); - m_oDocument.WriteString(L");\n", 3); - } - void WritePathCurveTo(double& x1, double& y1, double& x2, double& y2, double& x3, double& y3) - { - if (false == m_bIsMoveTo) - WritePathMoveTo(x1, y1); - - m_oDocument.WriteString(L"cu(c,", 5); - WriteIntsToStringBuilder(round(x1), round(y1), round(x2), round(y2), round(x3), round(y3), &m_oDocument); - m_oDocument.WriteString(L");\n", 3); - } - void WriteDrawPath(LONG lType, Aggplus::CMatrix* pTransform, Aggplus::CGraphicsPathSimpleConverter* pConverter, LONG lTxId) - { - bool bStroke = false; - - if (m_pPen->Alpha == 0) - lType &= 0xFF00; - - if ((-1 == lTxId) && (0 == m_pBrush->Alpha1)) - lType &= 0xFF; - - if ((lType & 0x01) == 0x01) - { - SetStrokeColor(m_pPen->Color, m_pPen->Alpha, &m_oDocument); - - bStroke = true; - } - if (lType > 0x01) - { - if (-1 != lTxId) - { - // текстура! - double x = 0; - double y = 0; - double w = 0; - double h = 0; - - pConverter->PathCommandGetBounds(x, y, w, h); - - double r = x + w; - double b = y + h; - - pTransform->TransformPoint(x, y); - pTransform->TransformPoint(r, b); - - w = r - x; - h = b - y; - - m_oDocument.WriteString(L"img", 3); - m_oDocument.AddInt(lTxId); - m_oDocument.WriteString(L".src = \"media\\\\image", 20); - m_oDocument.AddInt(lTxId); - m_oDocument.WriteString(L".jpg\";img", 9); - m_oDocument.AddInt(lTxId); - m_oDocument.WriteString(L".onload = function(){c.drawImage(img", 36); - WriteIntsToStringBuilder(lTxId, round(x), round(y), round(w), round(h), &m_oDocument); - m_oDocument.WriteString(L");drawpage", 10); - m_oDocument.AddInt(m_lCurDocumentID); - m_oDocument.AddCharSafe('_'); - m_oDocument.AddInt(lTxId); - m_oDocument.WriteString(L"(c);};\n}\nfunction drawpage", 26); - m_oDocument.AddInt(m_lCurDocumentID); - m_oDocument.AddCharSafe('_'); - m_oDocument.AddInt(lTxId); - m_oDocument.WriteString(L"(c)\n{\n", 6); - } - else - { - SetFillColor(m_pBrush->Color1, m_pBrush->Alpha1, &m_oDocument); - m_oDocument.WriteString(L"f(c);\n", 6); - } - } - - if (bStroke) - { - m_oDocument.WriteString(L"s(c);\n", 6); - } - } - - void WritePathClip() - { - m_bIsClipping = true; - ++m_lClippingPath; - } - void WritePathClipEnd() - { - if (!m_bIsClipping) - { - m_oDocument.WriteString(L"c.save();\n", 10); - } - m_bIsClipping = true; - m_oDocument.WriteString(L"c.clip();\n", 10); - } - void WritePathResetClip() - { - if (m_bIsClipping) - { - m_oDocument.WriteString(L"c.restore();\n", 13); - } - - m_bIsClipping = false; - } - - inline void WriteStyleClip() - { - } - }; -} - -#endif // _ASC_HTMLRENDERER_CANVASWRITER_H_ diff --git a/HtmlRenderer/src/Common.h b/HtmlRenderer/src/Common.h deleted file mode 100644 index 02eef04c367..00000000000 --- a/HtmlRenderer/src/Common.h +++ /dev/null @@ -1,304 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2023 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _ASC_HTMLRENDERER_COMMON_H_ -#define _ASC_HTMLRENDERER_COMMON_H_ - -#include "../../DesktopEditor/common/Types.h" -#include "../../DesktopEditor/common/File.h" -#include "../../DesktopEditor/common/Directory.h" -#include "../../DesktopEditor/graphics/Matrix.h" -#include "../../DesktopEditor/graphics/structures.h" -#include "../../DesktopEditor/common/StringBuilder.h" -#include "../../DesktopEditor/graphics/IRenderer.h" -#include "../../DesktopEditor/graphics/pro/Fonts.h" - -#define SVG_WRITER_SCALE 100 - -namespace NSHtmlRenderer -{ - class IBaseMatrixUpdater - { - public: - virtual void OnBaseMatrixUpdate(const double& dWidth, const double& dHeight) = 0; - }; - - class CDstInfo - { - public: - std::wstring m_strDstFilePath; - std::wstring m_strAdditionalPath; - std::wstring m_strDstMedia; - bool m_bIsWeb; - - public: - CDstInfo() - { - m_strDstFilePath = L""; - m_strAdditionalPath = L""; - m_strDstMedia = L""; - m_bIsWeb = false; - } - CDstInfo(const CDstInfo& oInfo) - { - *this = oInfo; - } - CDstInfo& operator=(const CDstInfo& oSrc) - { - m_strDstFilePath = oSrc.m_strDstFilePath; - m_strAdditionalPath = oSrc.m_strAdditionalPath; - m_strDstMedia = oSrc.m_strDstMedia; - m_bIsWeb = oSrc.m_bIsWeb; - return *this; - } - }; -} - -namespace NSHtmlRenderer -{ - inline LONG ConvertColor(const LONG& lBGR) - { - return (0x00FFFFFF & (((lBGR & 0xFF) << 16) | (lBGR & 0x0000FF00) | ((lBGR >> 16) & 0xFF))); - } - - inline void WriteIntsToStringBuilder(const int& n1, const int& n2, NSStringUtils::CStringBuilder* pBuilder) - { - pBuilder->AddSize(21); - pBuilder->AddIntNoCheck(n1); - pBuilder->AddCharNoSafe(','); - pBuilder->AddIntNoCheck(n2); - } - inline void WriteIntsToStringBuilder(const int& n1, const int& n2, - const int& n3, const int& n4, - NSStringUtils::CStringBuilder* pBuilder) - { - pBuilder->AddSize(65); - pBuilder->AddIntNoCheck(n1); - pBuilder->AddCharNoSafe(','); - pBuilder->AddIntNoCheck(n2); - pBuilder->AddCharNoSafe(','); - pBuilder->AddIntNoCheck(n3); - pBuilder->AddCharNoSafe(','); - pBuilder->AddIntNoCheck(n4); - } - inline void WriteIntsToStringBuilder(const int& n1, const int& n2, - const int& n3, const int& n4, - const int& n5, - NSStringUtils::CStringBuilder* pBuilder) - { - pBuilder->AddSize(65); - pBuilder->AddIntNoCheck(n1); - pBuilder->AddCharNoSafe(','); - pBuilder->AddIntNoCheck(n2); - pBuilder->AddCharNoSafe(','); - pBuilder->AddIntNoCheck(n3); - pBuilder->AddCharNoSafe(','); - pBuilder->AddIntNoCheck(n4); - pBuilder->AddCharNoSafe(','); - pBuilder->AddIntNoCheck(n5); - } - inline void WriteIntsToStringBuilder(const int& n1, const int& n2, - const int& n3, const int& n4, - const int& n5, const int& n6, - NSStringUtils::CStringBuilder* pBuilder) - { - pBuilder->AddSize(65); - pBuilder->AddIntNoCheck(n1); - pBuilder->AddCharNoSafe(','); - pBuilder->AddIntNoCheck(n2); - pBuilder->AddCharNoSafe(','); - pBuilder->AddIntNoCheck(n3); - pBuilder->AddCharNoSafe(','); - pBuilder->AddIntNoCheck(n4); - pBuilder->AddCharNoSafe(','); - pBuilder->AddIntNoCheck(n5); - pBuilder->AddCharNoSafe(','); - pBuilder->AddIntNoCheck(n6); - } - - inline void WriteFormatted(const wchar_t* s1, const int& n1, - const wchar_t* s2, - NSStringUtils::CStringBuilder* pBuilder) - { - pBuilder->WriteString(s1, wcslen(s1)); - pBuilder->AddInt(n1); - pBuilder->WriteString(s2, wcslen(s2)); - } - inline void WriteFormatted(const wchar_t* s1, const int& n1, - const wchar_t* s2, const int& n2, - const wchar_t* s3, - NSStringUtils::CStringBuilder* pBuilder) - { - pBuilder->WriteString(s1, wcslen(s1)); - pBuilder->AddInt(n1); - pBuilder->WriteString(s2, wcslen(s2)); - pBuilder->AddInt(n2); - pBuilder->WriteString(s3, wcslen(s3)); - } - inline void WriteFormatted(const wchar_t* s1, const int& n1, - const wchar_t* s2, const int& n2, - const wchar_t* s3, const int& n3, - const wchar_t* s4, - NSStringUtils::CStringBuilder* pBuilder) - { - pBuilder->WriteString(s1, wcslen(s1)); - pBuilder->AddInt(n1); - pBuilder->WriteString(s2, wcslen(s2)); - pBuilder->AddInt(n2); - pBuilder->WriteString(s3, wcslen(s3)); - pBuilder->AddInt(n3); - pBuilder->WriteString(s4, wcslen(s4)); - } - inline void WriteFormatted(const wchar_t* s1, const int& n1, - const wchar_t* s2, const int& n2, - const wchar_t* s3, const int& n3, - const wchar_t* s4, const int& n4, - const wchar_t* s5, - NSStringUtils::CStringBuilder* pBuilder) - { - pBuilder->WriteString(s1, wcslen(s1)); - pBuilder->AddInt(n1); - pBuilder->WriteString(s2, wcslen(s2)); - pBuilder->AddInt(n2); - pBuilder->WriteString(s3, wcslen(s3)); - pBuilder->AddInt(n3); - pBuilder->WriteString(s4, wcslen(s4)); - pBuilder->AddInt(n4); - pBuilder->WriteString(s5, wcslen(s5)); - } - - inline void SetStringColor(LONG lBGR, NSStringUtils::CStringBuilder* pBuilder) - { - BYTE R = (BYTE)(lBGR & 0xFF); - BYTE G = (BYTE)((lBGR >> 8) & 0xFF); - BYTE B = (BYTE)((lBGR >> 16) & 0xFF); - - pBuilder->AddSize(50); - pBuilder->WriteString(L"rgb(", 4); - pBuilder->AddIntNoCheck(R); - pBuilder->AddCharNoSafe(','); - pBuilder->AddIntNoCheck(G); - pBuilder->AddCharNoSafe(','); - pBuilder->AddIntNoCheck(B); - pBuilder->AddCharSafe(')'); - } - inline void SetStrokeColor(LONG lBGR, LONG lA, NSStringUtils::CStringBuilder* pBuilder) - { - BYTE R = (BYTE)(lBGR & 0xFF); - BYTE G = (BYTE)((lBGR >> 8) & 0xFF); - BYTE B = (BYTE)((lBGR >> 16) & 0xFF); - - pBuilder->WriteString(L"c.strokeStyle = \"rgba(", 22); - pBuilder->AddSize(70); - pBuilder->AddIntNoCheck(R); - pBuilder->AddCharNoSafe(','); - pBuilder->AddIntNoCheck(G); - pBuilder->AddCharNoSafe(','); - pBuilder->AddIntNoCheck(B); - pBuilder->AddCharNoSafe(','); - pBuilder->AddIntNoCheckDel100(100 * lA / 255); - pBuilder->WriteString(L")\";\n", 4); - } - inline void SetFillColor(LONG lBGR, LONG lA, NSStringUtils::CStringBuilder* pBuilder) - { - BYTE R = (BYTE)(lBGR & 0xFF); - BYTE G = (BYTE)((lBGR >> 8) & 0xFF); - BYTE B = (BYTE)((lBGR >> 16) & 0xFF); - - pBuilder->WriteString(L"c.fillStyle = \"rgba(", 20); - pBuilder->AddSize(70); - pBuilder->AddIntNoCheck(R); - pBuilder->AddCharNoSafe(','); - pBuilder->AddIntNoCheck(G); - pBuilder->AddCharNoSafe(','); - pBuilder->AddIntNoCheck(B); - pBuilder->AddCharNoSafe(','); - pBuilder->AddIntNoCheckDel100(100 * lA / 255); - pBuilder->WriteString(L")\";\n", 4); - } - - struct RECT - { - LONG left; - LONG top; - LONG right; - LONG bottom; - }; - - const double c_ag_Inch_to_MM = 25.4; - const double c_ag_1pxWidth = 25.4 / 96; - - enum ImageType - { - itJPG = 0, - itPNG = 1 - }; - - class CImageInfo - { - public: - ImageType m_eType; - LONG m_lID; - - CImageInfo() - { - m_eType = itJPG; - m_lID = -1; - } - CImageInfo(const CImageInfo& oSrc) - { - *this = oSrc; - } - CImageInfo& operator=(const CImageInfo& oSrc) - { - m_eType = oSrc.m_eType; - m_lID = oSrc.m_lID; - - return *this; - } - }; - - inline double FABS(double dVal) - { - return (dVal >= 0) ? dVal : -dVal; - } - inline int round(double dVal) - { - return (int)(dVal + 0.5); - } - inline int round2(double dVal) - { - // повышаем точность - return (int)(SVG_WRITER_SCALE * dVal + 0.5); - } -} - -#endif // _ASC_HTMLRENDERER_COMMON_H_ diff --git a/HtmlRenderer/src/Common2.h b/HtmlRenderer/src/Common2.h deleted file mode 100644 index 9ab51a3388e..00000000000 --- a/HtmlRenderer/src/Common2.h +++ /dev/null @@ -1,234 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2023 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _ASC_HTMLRENDERER_COMMON2_H_ -#define _ASC_HTMLRENDERER_COMMON2_H_ - -#include "Common.h" -#include "Meta.h" -#include "../../DesktopEditor/raster/BgraFrame.h" -#include "../../DesktopEditor/xml/include/xmlutils.h" - -namespace NSHtmlRenderer -{ - static RECT GetImageBounds(CBgraFrame* pFrame) - { - BYTE* pBuffer = pFrame->get_Data(); - LONG lWidth = (LONG)pFrame->get_Width(); - LONG lHeight = (LONG)pFrame->get_Height(); - - RECT rect; - rect.left = 0; - rect.top = 0; - rect.right = lWidth - 1; - rect.bottom = lHeight - 1; - - // top - unsigned int* pData = (unsigned int*)pBuffer; - for (; rect.top < lHeight; rect.top++) - { - bool bIsBreak = false; - for (LONG i = 0; i < lWidth; ++i, ++pData) - { - if (*pData != 0x00) - { - bIsBreak = true; - break; - } - } - if (bIsBreak) - break; - } - if (rect.top >= lHeight) - rect.top = (lHeight - 1); - - // bottom - for (; rect.bottom >= rect.top; rect.bottom--) - { - pData = (unsigned int*)pBuffer; - pData += (lWidth * rect.bottom); - - bool bIsBreak = false; - for (LONG i = 0; i < lWidth; ++i, ++pData) - { - if (*pData != 0x00) - { - bIsBreak = true; - break; - } - } - if (bIsBreak) - break; - } - if (rect.bottom < rect.top) - rect.bottom = rect.top; - - LONG lDelta = rect.bottom - rect.top + 1; - - // left - for (; rect.left < lWidth; rect.left++) - { - pData = (unsigned int*)(pBuffer + 4 * lWidth * rect.top); - pData += rect.left; - - bool bIsBreak = false; - for (LONG i = 0; i < lDelta; ++i, pData += lWidth) - { - if (*pData != 0x00) - { - bIsBreak = true; - break; - } - } - if (bIsBreak) - break; - } - if (rect.left >= lWidth) - rect.left = lWidth - 1; - - // right - for (; rect.right >= rect.left; rect.right--) - { - pData = (unsigned int*)(pBuffer + 4 * lWidth * rect.top); - pData += rect.right; - - bool bIsBreak = false; - for (LONG i = 0; i < lDelta; ++i, pData += lWidth) - { - if (*pData != 0x00) - { - bIsBreak = true; - break; - } - } - if (bIsBreak) - break; - } - if (rect.right < rect.left) - rect.right = rect.left; - - return rect; - } - - static RECT GetImageBounds2(CBgraFrame* pFrame, BYTE* pCache) - { - BYTE* pBuffer = pFrame->get_Data(); - LONG lWidth = (LONG)pFrame->get_Width(); - LONG lHeight = (LONG)pFrame->get_Height(); - - RECT rect; - rect.left = 0; - rect.top = 0; - rect.right = lWidth - 1; - rect.bottom = lHeight - 1; - - // top - unsigned int** pData = (unsigned int**)pBuffer; - unsigned int** pDataSrc = (unsigned int**)pCache; - for (; rect.top < lHeight; rect.top++) - { - if (0 != memcmp((void*)pData, (void*)pDataSrc, 4 * lWidth)) - break; - - pData += lWidth; - pDataSrc += lWidth; - } - if (rect.top >= lHeight) - rect.top = (lHeight - 1); - - // bottom - for (; rect.bottom >= rect.top; rect.bottom--) - { - pData = (unsigned int**)pBuffer; - pData += (lWidth * rect.bottom); - pDataSrc = (unsigned int**)pCache; - pDataSrc += (lWidth * rect.bottom); - - if (0 != memcmp((void*)pData, (void*)pDataSrc, 4 * lWidth)) - break; - } - if (rect.bottom < rect.top) - rect.bottom = rect.top; - - LONG lDelta = rect.bottom - rect.top + 1; - - // left - for (; rect.left < lWidth; rect.left++) - { - pData = (unsigned int**)(pBuffer + 4 * lWidth * rect.top); - pData += rect.left; - pDataSrc = (unsigned int**)(pCache + 4 * lWidth * rect.top); - pDataSrc += rect.left; - - bool bIsBreak = false; - for (LONG i = 0; i < lDelta; ++i, pData += lWidth, pDataSrc += lWidth) - { - if (*pData != *pDataSrc) - { - bIsBreak = true; - break; - } - } - if (bIsBreak) - break; - } - if (rect.left >= lWidth) - rect.left = lWidth - 1; - - // right - for (; rect.right >= rect.left; rect.right--) - { - pData = (unsigned int**)(pBuffer + 4 * lWidth * rect.top); - pData += rect.right; - - pDataSrc = (unsigned int**)(pCache + 4 * lWidth * rect.top); - pDataSrc += rect.right; - - bool bIsBreak = false; - for (LONG i = 0; i < lDelta; ++i, pData += lWidth) - { - if (*pData != *pDataSrc) - { - bIsBreak = true; - break; - } - } - if (bIsBreak) - break; - } - if (rect.right < rect.left) - rect.right = rect.left; - - return rect; - } -} - -#endif // _ASC_HTMLRENDERER_COMMON2_H_ diff --git a/HtmlRenderer/src/Document.h b/HtmlRenderer/src/Document.h deleted file mode 100644 index 2ecb8a33cbb..00000000000 --- a/HtmlRenderer/src/Document.h +++ /dev/null @@ -1,859 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2023 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _ASC_HTMLRENDERER_DOCUMENT_H_ -#define _ASC_HTMLRENDERER_DOCUMENT_H_ - -#include "Common.h" -#include -#include "../../DesktopEditor/graphics/pro/Graphics.h" - -namespace NSHtmlRenderer -{ - class CPageInfo - { - private: - double m_dWidthMM; - double m_dHeightMM; - - bool m_bInitW; - bool m_bInitH; - - IBaseMatrixUpdater* m_pUpdater; - - public: - CPageInfo() - { - m_dWidthMM = 190; - m_dHeightMM = 270; - - m_bInitW = false; - m_bInitH = false; - - m_pUpdater = NULL; - } - CPageInfo(const CPageInfo& oSrc) - { - *this = oSrc; - } - CPageInfo& operator=(const CPageInfo& oSrc) - { - m_dWidthMM = oSrc.m_dWidthMM; - m_dHeightMM = oSrc.m_dHeightMM; - - m_bInitW = oSrc.m_bInitW; - m_bInitH = oSrc.m_bInitH; - - m_pUpdater = oSrc.m_pUpdater; - return *this; - } - - inline double GetWidth() - { - return m_dWidthMM; - } - inline double GetHeight() - { - return m_dHeightMM; - } - inline void SetWidth(const double& width) - { - m_dWidthMM = width; - m_bInitW = true; - - if (m_bInitH && (NULL != m_pUpdater)) - { - m_pUpdater->OnBaseMatrixUpdate(m_dWidthMM, m_dHeightMM); - } - } - inline void SetHeight(const double& height) - { - m_dHeightMM = height; - m_bInitH = true; - - if (m_bInitW && (NULL != m_pUpdater)) - { - m_pUpdater->OnBaseMatrixUpdate(m_dWidthMM, m_dHeightMM); - } - } - inline void SetUpdater(IBaseMatrixUpdater* pUpdater) - { - m_pUpdater = pUpdater; - } - }; - - class CDocument - { - private: - - public: - std::vector m_arrPages; - IBaseMatrixUpdater* m_pUpdater; - - public: - CDocument() : m_arrPages() - { - m_pUpdater = NULL; - } - inline void SetUpdater(IBaseMatrixUpdater* pUpdater) - { - m_pUpdater = pUpdater; - } - - public: - - inline void NewPage() - { - CPageInfo oInfo; - oInfo.SetUpdater(m_pUpdater); - m_arrPages.push_back(oInfo); - } - inline void SetWidth(const double& dValue) - { - size_t nCount = m_arrPages.size(); - if (nCount > 0) - { - m_arrPages[nCount - 1].SetWidth(dValue); - } - } - inline void SetHeight(const double& dValue) - { - size_t nCount = m_arrPages.size(); - if (nCount > 0) - { - m_arrPages[nCount - 1].SetHeight(dValue); - } - } - - // -------------------------------------------------------------------- - - std::wstring GetThumbnailsHTML() - { - std::wstring strHTML = L""; - - strHTML += GetThumbnailsHeader(); - strHTML += GetThumbnailsBody(); - - strHTML += L""; - - return strHTML; - } - std::wstring GetViewerHTML() - { - std::wstring strHTML = L""; - - strHTML += GetViewerHeader(); - strHTML += GetViewerBody(); - - strHTML += L""; - - return strHTML; - } - - std::wstring GetThumbnailBlockHTML(int nPageNum) - { - std::wstring strPage = std::to_wstring(nPageNum); - - std::wstring strResult = L"
" + L"page" + strPage + L"
"; - return strResult; - } - std::wstring GetThumbnailsBody() - { - std::wstring strBody = L""; - - size_t nCount = m_arrPages.size(); - for (size_t i = 0; i < nCount; ++i) - { - strBody += GetThumbnailBlockHTML((int)(i + 1)); - } - - strBody += L""; - return strBody; - } - - std::wstring GetThumbnailsHeader() - { - return L"\ - \ - thumbnails\ - \ - \ - "; - } - - std::wstring GetViewerHeader() - { - return L"\ - \ - viewer\ - \ - \ - "; - } - - std::wstring GetViewerBlockHTML(int nPageNum) - { - std::wstring strPage = std::to_wstring(nPageNum); - - std::wstring strResult = L"
\n
\n\n" + L"
\n
\n" + L"
\n"; - return strResult; - } - std::wstring GetViewerBody() - { - std::wstring strBody = L""; - - size_t nCount = m_arrPages.size(); - for (size_t i = 0; i < nCount; ++i) - { - strBody += GetViewerBlockHTML((int)(i + 1)); - } - - strBody += L""; - - return strBody; - } - - std::wstring GetMenuHTML() - { - return L"\ - \ - \ - menu\ - \ - \ - \ - "; - } - std::wstring GetDocumentHTML() - { - return L"\ - \ - \ - document viewer\ - \ - \ - \ - \ - \ - \ - \ - \ - "; - } - - void CreateDirectories(std::wstring strHTML) - { - NSDirectory::CreateDirectory(strHTML); - NSDirectory::CreateDirectory(strHTML + L"/thumbnails"); - } - - void CreateHTMLs(std::wstring strHTML) - { - NSFile::CFileBinary::SaveToFile(strHTML + L"/docviewer.html", GetDocumentHTML(), true); - NSFile::CFileBinary::SaveToFile(strHTML + L"/menu.html", GetMenuHTML(), true); - NSFile::CFileBinary::SaveToFile(strHTML + L"/viewer.html", GetViewerHTML(), true); - NSFile::CFileBinary::SaveToFile(strHTML + L"/thumbnails.html", GetThumbnailsHTML(), true); - } - -}; - -class CThumbnails -{ -private: - NSGraphics::IGraphicsRenderer* m_pRenderer; - CBgraFrame* m_pFrame; - - LONG m_lWidth; - LONG m_lHeight; - -public: - CThumbnails() - { - m_pRenderer = NULL; - m_pFrame = NULL; - m_lWidth = 0; - m_lHeight = 0; - } - ~CThumbnails() - { - RELEASEOBJECT(m_pRenderer); - RELEASEOBJECT(m_pFrame); - } - -public: - void Create(const double& dWidth, const double& dHeight, LONG lSizeMax = 200) - { - LONG lWidthNew = 0; - LONG lHeightNew = 0; - - if (dWidth >= dHeight) - { - lWidthNew = lSizeMax; - lHeightNew = (LONG)((dHeight / dWidth) * lWidthNew); - } - else - { - lHeightNew = lSizeMax; - lWidthNew = (LONG)((dWidth / dHeight) * lHeightNew); - } - - if ((m_lWidth == lWidthNew) && (m_lHeight == lHeightNew) && (NULL != m_pFrame)) - { - // размер не поменялся - значит и память перевыделять не нужно - BYTE* pBuffer = m_pFrame->get_Data(); - memset(pBuffer, 0xFF, 4 * m_lWidth * m_lHeight); - - CreateRenderer(); - return; - } - - RELEASEOBJECT(m_pFrame); - m_lWidth = lWidthNew; - m_lHeight = lHeightNew; - - CreateMediaData(); - CreateRenderer(); - - m_pRenderer->put_Width(dWidth); - m_pRenderer->put_Height(dHeight); - } - inline void Save(std::wstring& strFile) - { - SaveFrame(strFile); - } - -protected: - void CreateMediaData() - { - RELEASEOBJECT(m_pFrame); - - m_pFrame = new CBgraFrame(); - m_pFrame->put_Width(m_lWidth); - m_pFrame->put_Height(m_lHeight); - m_pFrame->put_Stride(4 * m_lWidth); - BYTE* pBuffer = new BYTE[4 * m_lWidth * m_lHeight]; - memset(pBuffer, 0xFF, 4 * m_lWidth * m_lHeight); - m_pFrame->put_Data(pBuffer); - } - void CreateRenderer() - { - // теперь на всякий случай (сбросить все состояния) - пересоздадим рендерер - RELEASEINTERFACE(m_pRenderer); - - m_pRenderer = NSGraphics::Create(); - m_pRenderer->CreateFromBgraFrame(m_pFrame); - } - - void SaveFrame(const std::wstring& strFile) - { - m_pFrame->SaveFile(strFile, 4); - } - -public: - inline HRESULT get_Type(LONG* lType) - { - return m_pRenderer->get_Type(lType); - } - - //-------- Функции для работы со страницей -------------------------------------------------- - inline HRESULT NewPage() - { - if (NULL == m_pRenderer) - return S_OK; - - return m_pRenderer->NewPage(); - } - inline HRESULT get_Height(double* dHeight) - { - return m_pRenderer->get_Height(dHeight); - } - inline HRESULT put_Height(const double& dHeight) - { - if (NULL == m_pRenderer) - return S_OK; - - return m_pRenderer->put_Height(dHeight); - } - inline HRESULT get_Width(double* dWidth) - { - return m_pRenderer->get_Width(dWidth); - } - inline HRESULT put_Width(const double& dWidth) - { - if (NULL == m_pRenderer) - return S_OK; - - return m_pRenderer->put_Width(dWidth); - } - inline HRESULT get_DpiX(double* dDpiX) - { - return m_pRenderer->get_DpiX(dDpiX); - } - inline HRESULT get_DpiY(double* dDpiY) - { - return m_pRenderer->get_DpiY(dDpiY); - } - - // pen -------------------------------------------------------------------------------------- - inline HRESULT get_PenColor(LONG* lColor) - { - return m_pRenderer->get_PenColor(lColor); - } - inline HRESULT put_PenColor(const LONG& lColor) - { - return m_pRenderer->put_PenColor(lColor); - } - inline HRESULT get_PenAlpha(LONG* lAlpha) - { - return m_pRenderer->get_PenAlpha(lAlpha); - } - inline HRESULT put_PenAlpha(const LONG& lAlpha) - { - return m_pRenderer->put_PenAlpha(lAlpha); - } - inline HRESULT get_PenSize(double* dSize) - { - return m_pRenderer->get_PenSize(dSize); - } - inline HRESULT put_PenSize(const double& dSize) - { - return m_pRenderer->put_PenSize(dSize); - } - inline HRESULT get_PenDashStyle(BYTE* val) - { - return m_pRenderer->get_PenDashStyle(val); - } - inline HRESULT put_PenDashStyle(const BYTE& val) - { - return m_pRenderer->put_PenDashStyle(val); - } - inline HRESULT get_PenLineStartCap(BYTE* val) - { - return m_pRenderer->get_PenLineStartCap(val); - } - inline HRESULT put_PenLineStartCap(const BYTE& val) - { - return m_pRenderer->put_PenLineStartCap(val); - } - inline HRESULT get_PenLineEndCap(BYTE* val) - { - return m_pRenderer->get_PenLineEndCap(val); - } - inline HRESULT put_PenLineEndCap(const BYTE& val) - { - return m_pRenderer->put_PenLineEndCap(val); - } - inline HRESULT get_PenLineJoin(BYTE* val) - { - return m_pRenderer->get_PenLineJoin(val); - } - inline HRESULT put_PenLineJoin(const BYTE& val) - { - return m_pRenderer->put_PenLineJoin(val); - } - inline HRESULT get_PenDashOffset(double* val) - { - return m_pRenderer->get_PenDashOffset(val); - } - inline HRESULT put_PenDashOffset(const double& val) - { - return m_pRenderer->put_PenDashOffset(val); - } - inline HRESULT get_PenAlign(LONG* val) - { - return m_pRenderer->get_PenAlign(val); - } - inline HRESULT put_PenAlign(const LONG& val) - { - return m_pRenderer->put_PenAlign(val); - } - inline HRESULT get_PenMiterLimit(double* val) - { - return m_pRenderer->get_PenMiterLimit(val); - } - inline HRESULT put_PenMiterLimit(const double& val) - { - return m_pRenderer->put_PenMiterLimit(val); - } - inline HRESULT PenDashPattern(double* pPattern, LONG lCount) - { - return m_pRenderer->PenDashPattern(pPattern, lCount); - } - - // brush ------------------------------------------------------------------------------------ - inline HRESULT get_BrushType(LONG* lType) - { - return m_pRenderer->get_BrushType(lType); - } - inline HRESULT put_BrushType(const LONG& lType) - { - return m_pRenderer->put_BrushType(lType); - } - inline HRESULT get_BrushColor1(LONG* lColor) - { - return m_pRenderer->get_BrushColor1(lColor); - } - inline HRESULT put_BrushColor1(const LONG& lColor) - { - return m_pRenderer->put_BrushColor1(lColor); - } - inline HRESULT get_BrushAlpha1(LONG* lAlpha) - { - return m_pRenderer->get_BrushAlpha1(lAlpha); - } - inline HRESULT put_BrushAlpha1(const LONG& lAlpha) - { - return m_pRenderer->put_BrushAlpha1(lAlpha); - } - inline HRESULT get_BrushColor2(LONG* lColor) - { - return m_pRenderer->get_BrushColor2(lColor); - } - inline HRESULT put_BrushColor2(const LONG& lColor) - { - return m_pRenderer->put_BrushColor2(lColor); - } - inline HRESULT get_BrushAlpha2(LONG* lAlpha) - { - return m_pRenderer->get_BrushAlpha2(lAlpha); - } - inline HRESULT put_BrushAlpha2(const LONG& lAlpha) - { - return m_pRenderer->put_BrushAlpha2(lAlpha); - } - inline HRESULT get_BrushTexturePath(std::wstring* sPath) - { - return m_pRenderer->get_BrushTexturePath(sPath); - } - inline HRESULT put_BrushTexturePath(const std::wstring& bsPath) - { - return m_pRenderer->put_BrushTexturePath(bsPath); - } - inline HRESULT get_BrushTextureMode(LONG* lMode) - { - return m_pRenderer->get_BrushTextureMode(lMode); - } - inline HRESULT put_BrushTextureMode(const LONG& lMode) - { - return m_pRenderer->put_BrushTextureMode(lMode); - } - inline HRESULT get_BrushTextureAlpha(LONG* lTxAlpha) - { - return m_pRenderer->get_BrushTextureAlpha(lTxAlpha); - } - inline HRESULT put_BrushTextureAlpha(const LONG lTxAlpha) - { - return m_pRenderer->put_BrushTextureAlpha(lTxAlpha); - } - inline HRESULT get_BrushLinearAngle(double* dAngle) - { - return m_pRenderer->get_BrushLinearAngle(dAngle); - } - inline HRESULT put_BrushLinearAngle(const double& dAngle) - { - return m_pRenderer->put_BrushLinearAngle(dAngle); - } - inline HRESULT BrushRect(const INT& val, const double& left, const double& top, const double& width, const double& height) - { - return m_pRenderer->BrushRect(val, left, top, width, height); - } - - inline HRESULT BrushBounds(const double& left, const double& top, const double& width, const double& height) - { - return m_pRenderer->BrushBounds(left, top, width, height); - } - - inline HRESULT put_BrushGradientColors(LONG* lColors, double* pPositions, LONG nCount) - { - return m_pRenderer->put_BrushGradientColors(lColors, pPositions, nCount); - } - - // font ------------------------------------------------------------------------------------- - inline HRESULT get_FontName(std::wstring* bsName) - { - return m_pRenderer->get_FontName(bsName); - } - inline HRESULT put_FontName(const std::wstring& bsName) - { - return m_pRenderer->put_FontName(bsName); - } - inline HRESULT get_FontPath(std::wstring* bsName) - { - return m_pRenderer->get_FontPath(bsName); - } - inline HRESULT put_FontPath(const std::wstring& bsName) - { - return m_pRenderer->put_FontPath(bsName); - } - inline HRESULT get_FontSize(double* dSize) - { - return m_pRenderer->get_FontSize(dSize); - } - inline HRESULT put_FontSize(const double& dSize) - { - return m_pRenderer->put_FontSize(dSize); - } - inline HRESULT get_FontStyle(LONG* lStyle) - { - return m_pRenderer->get_FontStyle(lStyle); - } - inline HRESULT put_FontStyle(const LONG& lStyle) - { - return m_pRenderer->put_FontStyle(lStyle); - } - inline HRESULT get_FontStringGID(INT* bGID) - { - return m_pRenderer->get_FontStringGID(bGID); - } - inline HRESULT put_FontStringGID(const INT& bGID) - { - return m_pRenderer->put_FontStringGID(bGID); - } - inline HRESULT get_FontCharSpace(double* dSpace) - { - return m_pRenderer->get_FontCharSpace(dSpace); - } - inline HRESULT put_FontCharSpace(const double& dSpace) - { - return m_pRenderer->put_FontCharSpace(dSpace); - } - inline HRESULT get_FontFaceIndex(int* lFaceIndex) - { - return m_pRenderer->get_FontFaceIndex(lFaceIndex); - } - inline HRESULT put_FontFaceIndex(const int& lFaceIndex) - { - return m_pRenderer->put_FontFaceIndex(lFaceIndex); - } - - //-------- Функции для вывода текста -------------------------------------------------------- - virtual HRESULT CommandDrawTextCHAR(const LONG& c, const double& x, const double& y, const double& w, const double& h) - { - return m_pRenderer->CommandDrawTextCHAR(c, x, y, w, h); - } - virtual HRESULT CommandDrawText(const std::wstring& bsText, const double& x, const double& y, const double& w, const double& h) - { - return m_pRenderer->CommandDrawText(bsText, x, y, w, h); - } - virtual HRESULT CommandDrawTextExCHAR(const LONG& c, const LONG& gid, const double& x, const double& y, const double& w, const double& h) - { - return m_pRenderer->CommandDrawTextExCHAR(c, gid, x, y, w, h); - } - virtual HRESULT CommandDrawTextEx(const std::wstring& bsUnicodeText, const unsigned int* pGids, const unsigned int nGidsCount, const double& x, const double& y, const double& w, const double& h) - { - return m_pRenderer->CommandDrawTextEx(bsUnicodeText, pGids, nGidsCount, x, y, w, h); - } - - - //-------- Маркеры для команд --------------------------------------------------------------- - inline HRESULT BeginCommand(const DWORD& lType) - { - return m_pRenderer->BeginCommand(lType); - } - inline HRESULT EndCommand(const DWORD& lType) - { - return m_pRenderer->EndCommand(lType); - } - - //-------- Функции для работы с Graphics Path ----------------------------------------------- - inline HRESULT PathCommandMoveTo(const double& fX, const double& fY) - { - return m_pRenderer->PathCommandMoveTo(fX, fY); - } - inline HRESULT PathCommandLineTo(const double& fX, const double& fY) - { - return m_pRenderer->PathCommandLineTo(fX, fY); - } - inline HRESULT PathCommandLinesTo(double* points, const int& count) - { - return m_pRenderer->PathCommandLinesTo(points, count); - } - inline HRESULT PathCommandCurveTo(const double& fX1, const double& fY1, const double& fX2, const double& fY2, const double& fX3, const double& fY3) - { - return m_pRenderer->PathCommandCurveTo(fX1, fY1, fX2, fY2, fX3, fY3); - } - inline HRESULT PathCommandCurvesTo(double* points, const int& count) - { - return m_pRenderer->PathCommandCurvesTo(points, count); - } - inline HRESULT PathCommandArcTo(const double& fX, const double& fY, const double& fWidth, const double& fHeight, const double& fStartAngle, const double& fSweepAngle) - { - return m_pRenderer->PathCommandArcTo(fX, fY, fWidth, fHeight, fStartAngle, fSweepAngle); - } - inline HRESULT PathCommandClose() - { - return m_pRenderer->PathCommandClose(); - } - inline HRESULT PathCommandEnd() - { - return m_pRenderer->PathCommandEnd(); - } - inline HRESULT DrawPath(const LONG& nType) - { - return m_pRenderer->DrawPath(nType); - } - inline HRESULT PathCommandStart() - { - return m_pRenderer->PathCommandStart(); - } - inline HRESULT PathCommandGetCurrentPoint(double* fX, double* fY) - { - return m_pRenderer->PathCommandGetCurrentPoint(fX, fY); - } - - inline HRESULT PathCommandTextCHAR(const LONG& c, const double& x, const double& y, const double& w, const double& h) - { - return m_pRenderer->PathCommandTextCHAR(c, x, y, w, h); - } - inline HRESULT PathCommandText(const std::wstring& bsText, const double& x, const double& y, const double& w, const double& h) - { - return m_pRenderer->PathCommandText(bsText, x, y, w, h); - } - inline HRESULT PathCommandTextExCHAR(const LONG& c, const LONG& gid, const double& x, const double& y, const double& w, const double& h) - { - return m_pRenderer->PathCommandTextExCHAR(c, gid, x, y, w, h); - } - inline HRESULT PathCommandTextEx(const std::wstring& bsUnicodeText, const unsigned int* pGids, const unsigned int nGidsCount, const double& x, const double& y, const double& w, const double& h) - { - return m_pRenderer->PathCommandTextEx(bsUnicodeText, pGids, nGidsCount, x, y, w, h); - } - - //-------- Функции для вывода изображений --------------------------------------------------- - inline HRESULT DrawImage(IGrObject* pInterface, const double& fX, const double& fY, const double& fWidth, const double& fHeight) - { - return m_pRenderer->DrawImage(pInterface, fX, fY, fWidth, fHeight); - } - inline HRESULT DrawImageFromFile(const std::wstring& sPath, const double& x, const double& y, const double& w, const double& h, const BYTE& lAlpha = 255) - { - return m_pRenderer->DrawImageFromFile(sPath, x, y, w, h, lAlpha); - } - - // transform -------------------------------------------------------------------------------- - inline HRESULT SetTransform(const double& dA, const double& dB, const double& dC, const double& dD, const double& dE, const double& dF) - { - return m_pRenderer->SetTransform(dA, dB, dC, dD, dE, dF); - } - inline HRESULT GetTransform(double *pdA, double *pdB, double *pdC, double *pdD, double *pdE, double *pdF) - { - return m_pRenderer->GetTransform(pdA, pdB, pdC, pdD, pdE, pdF); - } - inline HRESULT ResetTransform(void) - { - return m_pRenderer->ResetTransform(); - } - - // ----------------------------------------------------------------------------------------- - inline HRESULT get_ClipMode(LONG* plMode) - { - return m_pRenderer->get_ClipMode(plMode); - } - inline HRESULT put_ClipMode(const LONG& lMode) - { - return m_pRenderer->put_ClipMode(lMode); - } - - // additiaonal params ---------------------------------------------------------------------- - inline HRESULT CommandLong(const LONG& lType, const LONG& lCommand) - { - return m_pRenderer->CommandLong(lType, lCommand); - } - inline HRESULT CommandDouble(const LONG& lType, const double& dCommand) - { - return m_pRenderer->CommandDouble(lType, dCommand); - } - inline HRESULT CommandString(const LONG& lType, const std::wstring& sCommand) - { - return m_pRenderer->CommandString(lType, sCommand); - } - -}; -} - -#endif // _ASC_HTMLRENDERER_DOCUMENT_H_ diff --git a/HtmlRenderer/src/FontManager.h b/HtmlRenderer/src/FontManager.h deleted file mode 100644 index 677569f76b8..00000000000 --- a/HtmlRenderer/src/FontManager.h +++ /dev/null @@ -1,120 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2023 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _ASC_HTMLRENDERER_FM_H_ -#define _ASC_HTMLRENDERER_FM_H_ - -#include "FontManagerBase.h" - -namespace NSHtmlRenderer -{ - using namespace NSFontManager; - - const long g_lNewNoJustifySpace = 5; - - class CFontManager : public CFontManagerBase - { - public: - NSStructures::CFont* m_pFont; - Aggplus::CMatrix* m_pTransform; - - double m_dSpaceWidthMM; - - public: - CFontManager() : m_pFont(NULL), CFontManagerBase() - { - m_pTransform = NULL; - m_dSpaceWidthMM = 0; - } - virtual ~CFontManager() - { - } - - public: - virtual void LoadFont(long lFaceIndex = 0, bool bIsNeedAddToMap = true) - { - if (NULL == m_pManager) - return; - - double dSize = m_pFont->Size; - double dSizeFont = dSize * ((m_pTransform->sx() + m_pTransform->sy()) / 2); - - m_pFont->Size = dSizeFont; - - if (IsEqual2(m_pFont, &m_oFont.m_oFont)) - { - m_pFont->Size = dSize; - return; - } - - m_oFont.m_oFont = *m_pFont; - m_pFont->Size = dSize; - - bool bIsPath = false; - - if (L"" == m_pFont->Path) - { - CFontManagerBase::LoadFontByName(m_oFont.m_oFont.Name, m_oFont.m_oFont.Size, m_oFont.m_oFont.GetStyle()); - } - else - { - CFontManagerBase::LoadFontByFile(m_oFont.m_oFont.Path, m_oFont.m_oFont.Size, lFaceIndex); - - m_pFont->SetStyle(m_oFont.m_oProperties.m_lStyle); - m_oFont.m_oFont.SetStyle(m_oFont.m_oProperties.m_lStyle); - - bIsPath = true; - } - - CalculateSpace(); - } - - inline void CalculateSpace() - { - LONG lGid = m_pManager->GetStringGID(); - m_pManager->SetStringGID(FALSE); - - m_pManager->LoadString1(L" ", 0, 0); - - TBBox _box = m_pManager->MeasureString2(); - - m_dSpaceWidthMM = (double)(_box.fMaxX - _box.fMinX) * c_dPixToMM; - if (0 >= m_dSpaceWidthMM) - { - m_dSpaceWidthMM = 1.0; - } - - m_pManager->SetStringGID(lGid); - } - }; -} - -#endif // _ASC_HTMLRENDERER_FM_H_ diff --git a/HtmlRenderer/src/FontManagerBase.h b/HtmlRenderer/src/FontManagerBase.h deleted file mode 100644 index 3590ab1fe9c..00000000000 --- a/HtmlRenderer/src/FontManagerBase.h +++ /dev/null @@ -1,1639 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2023 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _ASC_HTMLRENDERER_FMBASE_H_ -#define _ASC_HTMLRENDERER_FMBASE_H_ - -#include "../../DesktopEditor/common/Types.h" -#include "../../DesktopEditor/graphics/Matrix.h" -#include "../../DesktopEditor/graphics/structures.h" -#include "../../DesktopEditor/common/StringBuilder.h" -#include "../../DesktopEditor/graphics/IRenderer.h" -#include "../../DesktopEditor/graphics/pro/Fonts.h" -#include "../../DesktopEditor/xml/include/xmlutils.h" - -#include -#include -#include - -namespace NSHtmlRenderer -{ - namespace NSFontManager - { - const double c_dInchToMM = 25.4; - const double c_dPixToMM = 25.4 / 72.0; - const double c_dPtToMM = 25.4 / 72.0; - const double c_dMMToPt = 72.0 / 25.4; - const double c_dDpi = 72.0; - - class CFontProperties - { - public: - std::wstring m_strFamilyName; - BYTE m_strPANOSE[10]; - LONG m_lStyle; - std::vector m_arSignature; - bool m_bIsFixedWidth; - LONG m_lAvgWidth; - - public: - CFontProperties() - { - m_strFamilyName = L""; - memset(m_strPANOSE, 0, 10); - m_lStyle = 0; - m_arSignature.clear(); - m_bIsFixedWidth = false; - m_lAvgWidth = -1; - } - - CFontProperties(const CFontProperties& oSrc) - { - *this = oSrc; - } - CFontProperties& operator=(const CFontProperties& oSrc) - { - m_strFamilyName = oSrc.m_strFamilyName; - memcpy(m_strPANOSE, oSrc.m_strPANOSE, 10); - m_lStyle = oSrc.m_lStyle; - m_arSignature = oSrc.m_arSignature; - m_bIsFixedWidth = oSrc.m_bIsFixedWidth; - m_lAvgWidth = oSrc.m_lAvgWidth; - - return *this; - } - ~CFontProperties() - { - } - }; - - class CFontAdvanced - { - public: - NSStructures::CFont m_oFont; - - // font metrics - double m_dAscent; - double m_dDescent; - double m_dLineSpacing; - double m_dEmHeight; - - double m_dBaselineOffsetDOCX; - double m_dBaselineOffsetHTML; - - double m_dSpaceWidthMM; - - // font params - CFontProperties m_oProperties; - public: - CFontAdvanced(): m_oProperties() - { - m_oFont.SetDefaultParams(); - - m_dAscent = 0; - m_dDescent = 0; - m_dLineSpacing = 0; - m_dEmHeight = 0; - - m_dBaselineOffsetDOCX = 0; - m_dBaselineOffsetHTML = 0; - - m_dSpaceWidthMM = 0; - } - - CFontAdvanced(const CFontAdvanced& oSrc) - { - *this = oSrc; - } - - CFontAdvanced& operator=(const CFontAdvanced& oSrc) - { - m_oFont = oSrc.m_oFont; - - m_dAscent = oSrc.m_dAscent; - m_dDescent = oSrc.m_dDescent; - m_dLineSpacing = oSrc.m_dLineSpacing; - m_dEmHeight = oSrc.m_dEmHeight; - - m_dBaselineOffsetDOCX = oSrc.m_dBaselineOffsetDOCX; - m_dBaselineOffsetHTML = oSrc.m_dBaselineOffsetHTML; - - m_dSpaceWidthMM = oSrc.m_dSpaceWidthMM; - - m_oProperties = oSrc.m_oProperties; - - return *this; - } - }; - - class CFontPickUp - { - public: - CFontAdvanced m_oFont; - BYTE m_lRangeNum; - BYTE m_lRange; - std::wstring m_strPickFont; - LONG m_lPickStyle; - - public: - CFontPickUp() : m_oFont() - { - m_lRangeNum = 0xFF; - m_lRange = 0xFF; - m_strPickFont = L""; - m_lPickStyle = 0; - } - CFontPickUp(const CFontPickUp& oSrc) - { - *this = oSrc; - } - CFontPickUp& operator=(const CFontPickUp& oSrc) - { - m_oFont = oSrc.m_oFont; - m_lRange = oSrc.m_lRange; - m_lRangeNum = oSrc.m_lRangeNum; - m_strPickFont = oSrc.m_strPickFont; - m_lPickStyle = oSrc.m_lPickStyle; - - return *this; - } - }; - - class CFontManagerBase - { - public: - enum MeasureType - { - MeasureTypeGlyph = 0, - MeasureTypePosition = 1 - }; - - protected: - NSFonts::IApplicationFonts* m_pApplicationFonts; - NSFonts::IFontManager* m_pManager; - std::wstring m_strDefaultFont; - - public: - - CFontAdvanced m_oFont; - - //для подбора шрифтов - BYTE m_pRanges[0xFFFF]; - BYTE m_pRangesNums[0xFFFF]; - - BYTE m_mapUnicode[0xFFFF]; - - std::map m_mapFontPathToProperties; - CFontProperties* m_pCurrentProperties; - - std::list m_arListPicUps; - std::wstring m_strCurrentPickFont; - LONG m_lCurrentPictFontStyle; - - bool m_bIsUseFontWidth; - - public: - CFontManagerBase() : m_oFont(), m_mapFontPathToProperties() - { - m_pApplicationFonts = NSFonts::NSApplication::Create(); - m_pApplicationFonts->Initialize(); - m_pApplicationFonts->GetCache()->SetCacheSize(16); - m_pManager = m_pApplicationFonts->GenerateFontManager(); - - SetDefaultFont(L"Arial"); - - ClearPickUps(); - - InitializeRanges(); - InitializeUnicodeMap(); - - ClearPickUps(); - - m_pCurrentProperties = NULL; - m_bIsUseFontWidth = false; - } - virtual ~CFontManagerBase() - { - RELEASEOBJECT(m_pManager); - RELEASEOBJECT(m_pApplicationFonts); - } - - inline void ClearPickUps() - { - m_arListPicUps.clear(); - m_strCurrentPickFont = L""; - m_lCurrentPictFontStyle = 0; - } - - public: - inline void SetDefaultFont(const std::wstring& strName) - { - m_strDefaultFont = strName; - //m_pManager->SetDefaultFont(m_strDefaultFont); - } - inline std::wstring GetDefaultFont() - { - return m_strDefaultFont; - } - - virtual void LoadFont(long lFaceIndex = 0, bool bIsNeedAddToMap = true) - { - } - - inline void LoadCurrentFont(long lFaceIndex = 0) - { - if (m_oFont.m_oFont.Path.empty()) - { - LoadFontByName(m_oFont.m_oFont.Name, m_oFont.m_oFont.Size, m_oFont.m_oFont.GetStyle()); - } - else - { - LoadFontByFile(m_oFont.m_oFont.Path, m_oFont.m_oFont.Size, lFaceIndex); - m_oFont.m_oFont.SetStyle(m_oFont.m_oProperties.m_lStyle); - } - } - - void LoadFontByName(std::wstring& strName, const double& dSize, const LONG& lStyle) - { - m_pManager->LoadFontByName(strName, (float)dSize, lStyle, c_dDpi, c_dDpi); - - LoadFontMetrics(); - - m_oFont.m_oProperties.m_strFamilyName = m_oFont.m_oFont.Name; - m_oFont.m_oProperties.m_lStyle = m_oFont.m_oFont.GetStyle(); - - m_strCurrentPickFont = m_oFont.m_oProperties.m_strFamilyName; - m_lCurrentPictFontStyle = m_oFont.m_oProperties.m_lStyle; - - m_oFont.m_oProperties.m_lAvgWidth = -1; - } - - void LoadFontByFile(std::wstring& strPath, const double& dSize, const LONG& lFaceIndex) - { - m_pManager->LoadFontFromFile(strPath, lFaceIndex, dSize, c_dDpi, c_dDpi); - - m_oFont.m_oProperties.m_strFamilyName = m_oFont.m_oFont.Name; - m_oFont.m_oProperties.m_lStyle = m_oFont.m_oFont.GetStyle(); - - m_strCurrentPickFont = m_oFont.m_oProperties.m_strFamilyName; - m_lCurrentPictFontStyle = m_oFont.m_oProperties.m_lStyle; - - m_oFont.m_oProperties.m_lAvgWidth = -1; - - LoadFontMetrics(); - LoadFontParams(); - } - - public: - - void MeasureString(const std::wstring& strText, double x, double y, double& dBoxX, double& dBoxY, double& dBoxWidth, double& dBoxHeight, MeasureType measureType) - { - MeasureStringPix(strText, x, y, dBoxX, dBoxY, dBoxWidth, dBoxHeight, measureType); - - // переводим в миллиметры - dBoxX *= c_dPixToMM; - dBoxY *= c_dPixToMM; - dBoxWidth *= c_dPixToMM; - dBoxHeight *= c_dPixToMM; - } - - void MeasureStringPix(std::wstring bsText, double x, double y, double& dBoxX, double& dBoxY, double& dBoxWidth, double& dBoxHeight, MeasureType measureType) - { - dBoxX = 0; - dBoxY = 0; - dBoxWidth = 0; - dBoxHeight = 0; - - if (NULL == m_pManager) - return; - - m_pManager->LoadString1(bsText, (float)x, (float)y); - - TBBox tBox; - - if (MeasureTypeGlyph == measureType) - { - tBox = m_pManager->MeasureString(); - } - else if (MeasureTypePosition == measureType) - { - tBox = m_pManager->MeasureString2(); - } - - dBoxX = (double)tBox.fMinX; - dBoxY = (double)tBox.fMinY; - dBoxWidth = (double)(tBox.fMaxX - tBox.fMinX); - dBoxHeight = (double)(tBox.fMaxY - tBox.fMinY); - } - - public: - void LoadFontMetrics() - { - m_pManager->AfterLoad(); - m_oFont.m_dAscent = m_pManager->GetAscender(); - m_oFont.m_dDescent = m_pManager->GetDescender(); - m_oFont.m_dLineSpacing = m_pManager->GetLineHeight(); - m_oFont.m_dEmHeight = m_pManager->GetUnitsPerEm(); - - m_oFont.m_dBaselineOffsetDOCX = (c_dPtToMM * m_oFont.m_dDescent * m_oFont.m_oFont.Size / m_oFont.m_dEmHeight); - - double d1 = 3 * (m_oFont.m_dLineSpacing - m_oFont.m_dDescent) - m_oFont.m_dAscent; - d1 /= 2.0; - - d1 *= (m_oFont.m_oFont.Size / m_oFont.m_dEmHeight); - m_oFont.m_dBaselineOffsetHTML = d1; - } - - std::wstring DeletePdfPrefix(const std::wstring& sFamilyName) - { - // Удаляем префикс, который встречается в шрифтах внедренных в PDF - // Его вид : BAAAAA+FamilyName (6 латинских букв в верхнем регистре и '+') - // Пример : EOODIA+Poetica - - if ( sFamilyName.length() > 7 ) - { - const wchar_t* buf = sFamilyName.c_str(); - bool bPrefix = true; - for ( int nIndex = 0; nIndex < 6; nIndex++ ) - { - wchar_t nChar = buf[nIndex]; - if ( nChar < (wchar_t)('A') || nChar > (wchar_t)('Z') ) - { - bPrefix = false; - break; - } - } - - if ( buf[6] != wchar_t('+') ) - bPrefix = false; - - if ( bPrefix ) - { - return sFamilyName.substr(7); - } - } - - // Ничего не делаем - return sFamilyName; - } - - void LoadFontParams() - { - // читаем и выставляем все настройки шрифта - if (NULL == m_pManager) - return; - - // загрузка была из path - std::map::const_iterator iFind = m_mapFontPathToProperties.find(m_oFont.m_oFont.Path); - - if (iFind != m_mapFontPathToProperties.end()) - { - m_oFont.m_oProperties = iFind->second; - return; - } - - if (m_oFont.m_oFont.Name.empty()) - { - // FamilyName - m_oFont.m_oProperties.m_strFamilyName = DeletePdfPrefix(m_pManager->GetName()); - } - else - { - m_oFont.m_oProperties.m_strFamilyName = m_oFont.m_oFont.Name; - } - - NSFonts::IFontFile* pFontFile = m_pManager->GetFile(); - if (!pFontFile) - return; - - // StyleName - std::string strStyle = pFontFile->GetStyleName(); - if ("Bold" == strStyle) - { - m_oFont.m_oProperties.m_lStyle = 0x01; - } - else if ("Italic" == strStyle) - { - m_oFont.m_oProperties.m_lStyle = 0x02; - } - else if ("Bold Italic" == strStyle) - { - m_oFont.m_oProperties.m_lStyle = 0x03; - } - else - { - m_oFont.m_oProperties.m_lStyle = 0x00; - } - - pFontFile->GetPanose(m_oFont.m_oProperties.m_strPANOSE); - - // IsFixed - m_oFont.m_oProperties.m_bIsFixedWidth = pFontFile->IsFixedWidth(); - - // Signature - m_oFont.m_oProperties.m_arSignature.clear(); - - for ( unsigned int i = 0; i < 6; i++ ) - { - UINT value = 0; - - for ( unsigned long bit = 0; bit < 32; bit++ ) - { - int iRes = pFontFile->IsUnicodeRangeAvailable( bit, i ); - - if( iRes > 0 ) - { - value |= ( 1 << bit ); - } - } - - m_oFont.m_oProperties.m_arSignature.push_back(value); - } - - if (m_bIsUseFontWidth) - { - std::wstring sExt; - std::wstring sEncodingPath; - - std::wstring::size_type nFindExt = m_oFont.m_oFont.Path.find_last_of((wchar_t)'.'); - if (nFindExt == std::wstring::npos) - { - sEncodingPath = m_oFont.m_oFont.Path + L".enc"; - sExt = L""; - } - else - { - sExt = m_oFont.m_oFont.Path.substr(nFindExt + 1); - sEncodingPath = m_oFont.m_oFont.Path.substr(0, nFindExt); - } - - bool bIsCID = false; - if (std::wstring::npos != sExt.find(L"cid")) - bIsCID = true; - - XmlUtils::CXmlNode oMainNode; - oMainNode.FromXmlFile(sEncodingPath); - - if (L"PDF-resources" == oMainNode.GetName()) - { - if (bIsCID) - { - XmlUtils::CXmlNode oType0Node; - if ( oMainNode.GetNode( L"Type0", oType0Node ) ) - { - XmlUtils::CXmlNode oNode; - if ( oType0Node.GetNode( L"DescendantFonts", oNode ) ) - { - XmlUtils::CXmlNode oDescNode; - if ( oNode.GetNode( L"FontDescriptor", oDescNode ) ) - { - XmlUtils::CXmlNode oCurNode; - if ( oNode.GetNode( L"AvgWidth", oCurNode ) ) - { - m_oFont.m_oProperties.m_lAvgWidth = oCurNode.GetAttributeInt(L"value"); - } - } - } - } - } - else - { - XmlUtils::CXmlNode oNode; - if ( oMainNode.GetNode( L"FontDescriptor", oNode ) ) - { - XmlUtils::CXmlNode oCurNode; - if ( oNode.GetNode( L"AvgWidth", oCurNode ) ) - { - m_oFont.m_oProperties.m_lAvgWidth = oCurNode.GetAttributeInt(L"value"); - } - else - { - XmlUtils::CXmlNode oNodeWidths; - if (oMainNode.GetNode(L"Widths", oNodeWidths)) - { - LONG lCount = 0; - double dWidth = 0; - std::vector oNodesW; - if (oNodeWidths.GetNodes(L"Width", oNodesW)) - { - size_t nCountW = oNodesW.size(); - for (size_t i = 0; i < nCountW; ++i) - { - XmlUtils::CXmlNode & oNodeMem = oNodesW[i]; - - double dMem = oCurNode.GetAttributeDouble(L"value"); - if (0 < dMem) - { - ++lCount; - dWidth += dMem; - } - } - } - - if (10 < lCount) - { - m_oFont.m_oProperties.m_lAvgWidth = (LONG)(0.8 * dWidth / lCount); - } - } - } - } - } - } - } - - m_mapFontPathToProperties.insert(std::pair(m_oFont.m_oFont.Path, m_oFont.m_oProperties)); - } - - private: - void InitializeRanges() - { - memset(m_pRanges, 0xFF, 0xFFFF); - memset(m_pRangesNums, 0xFF, 0xFFFF); - - // теперь просто по порядку заполняем все рэнджи - int nStart = 0; - int nCount = 0; - - // rangeNum 0 - // case 00: sUCRName = "Basic Latin"; break; /* U+0020-U+007E */ - nStart = 0x0020; - nCount = 0x007E - nStart + 1; - memset(m_pRanges + nStart, 0, nCount); - memset(m_pRangesNums + nStart, 0, nCount); - - //case 01: sUCRName = "Latin-1 Supplement"; break; /* U+0080-U+00FF */ - nStart = 0x0080; - nCount = 0x00FF - nStart + 1; - memset(m_pRanges + nStart, 1, nCount); - memset(m_pRangesNums + nStart, 0, nCount); - - //case 02: sUCRName = "Latin Extended-A"; break; /* U+0100-U+017F */ - nStart = 0x0100; - nCount = 0x017F - nStart + 1; - memset(m_pRanges + nStart, 2, nCount); - memset(m_pRangesNums + nStart, 0, nCount); - - //case 03: sUCRName = "Latin Extended-B"; break; /* U+0180-U+024F */ - nStart = 0x0180; - nCount = 0x024F - nStart + 1; - memset(m_pRanges + nStart, 3, nCount); - memset(m_pRangesNums + nStart, 0, nCount); - - //case 04: sUCRName = "IPA Extensions"; break; /* U+0250-U+02AF */ /* U+1D00-U+1D7F */ /* U+1D80-U+1DBF */ - nStart = 0x0250; - nCount = 0x02AF - nStart + 1; - memset(m_pRanges + nStart, 4, nCount); - memset(m_pRangesNums + nStart, 0, nCount); - - nStart = 0x1D00; - nCount = 0x1D7F - nStart + 1; - memset(m_pRanges + nStart, 4, nCount); - memset(m_pRangesNums + nStart, 0, nCount); - - nStart = 0x1D80; - nCount = 0x1DBF - nStart + 1; - memset(m_pRanges + nStart, 4, nCount); - memset(m_pRangesNums + nStart, 0, nCount); - - //case 05: sUCRName = "Spacing Modifier Letters"; break; /* U+02B0-U+02FF */ /* U+A700-U+A71F */ - nStart = 0x02B0; - nCount = 0x02FF - nStart + 1; - memset(m_pRanges + nStart, 5, nCount); - memset(m_pRangesNums + nStart, 0, nCount); - - nStart = 0xA700; - nCount = 0xA71F - nStart + 1; - memset(m_pRanges + nStart, 5, nCount); - memset(m_pRangesNums + nStart, 0, nCount); - - //case 06: sUCRName = "Combining Diacritical Marks"; break; /* U+0300-U+036F */ /* U+1DC0-U+1DFF */ - nStart = 0x0300; - nCount = 0x036F - nStart + 1; - memset(m_pRanges + nStart, 6, nCount); - memset(m_pRangesNums + nStart, 0, nCount); - - nStart = 0x1DC0; - nCount = 0x1DFF - nStart + 1; - memset(m_pRanges + nStart, 6, nCount); - memset(m_pRangesNums + nStart, 0, nCount); - - //case 07: sUCRName = "Greek and Coptic"; break; /* U+0370-U+03FF */ - nStart = 0x0370; - nCount = 0x03FF - nStart + 1; - memset(m_pRanges + nStart, 7, nCount); - memset(m_pRangesNums + nStart, 0, nCount); - - //case 08: sUCRName = "Coptic"; break; /* U+2C80-U+2CFF */ - nStart = 0x2C80; - nCount = 0x2CFF - nStart + 1; - memset(m_pRanges + nStart, 8, nCount); - memset(m_pRangesNums + nStart, 0, nCount); - - //case 09: sUCRName = "Cyrillic"; break; /* U+0400-U+04FF */ /* U+0500-U+052F */ /* U+2DE0-U+2DFF */ /* U+A640-U+A69F */ - nStart = 0x0400; - nCount = 0x04FF - nStart + 1; - memset(m_pRanges + nStart, 9, nCount); - memset(m_pRangesNums + nStart, 0, nCount); - - nStart = 0x0500; - nCount = 0x052F - nStart + 1; - memset(m_pRanges + nStart, 9, nCount); - memset(m_pRangesNums + nStart, 0, nCount); - - nStart = 0x2DE0; - nCount = 0x2DFF - nStart + 1; - memset(m_pRanges + nStart, 9, nCount); - memset(m_pRangesNums + nStart, 0, nCount); - - nStart = 0xA640; - nCount = 0xA69F - nStart + 1; - memset(m_pRanges + nStart, 9, nCount); - memset(m_pRangesNums + nStart, 0, nCount); - - //case 10: sUCRName = "Armenian"; break; /* U+0530-U+058F */ - nStart = 0x0530; - nCount = 0x058F - nStart + 1; - memset(m_pRanges + nStart, 10, nCount); - memset(m_pRangesNums + nStart, 0, nCount); - - //case 11: sUCRName = "Hebrew"; break; /* U+0590-U+05FF */ - nStart = 0x0590; - nCount = 0x05FF - nStart + 1; - memset(m_pRanges + nStart, 11, nCount); - memset(m_pRangesNums + nStart, 0, nCount); - - //case 12: sUCRName = "Vai"; break; /* U+A500-U+A63F */ - nStart = 0xA500; - nCount = 0xA63F - nStart + 1; - memset(m_pRanges + nStart, 12, nCount); - memset(m_pRangesNums + nStart, 0, nCount); - - //case 13: sUCRName = "Arabic"; break; /* U+0600-U+06FF */ /* U+0750-U+077F */ - nStart = 0x0600; - nCount = 0x06FF - nStart + 1; - memset(m_pRanges + nStart, 13, nCount); - memset(m_pRangesNums + nStart, 0, nCount); - - nStart = 0x0750; - nCount = 0x077F - nStart + 1; - memset(m_pRanges + nStart, 13, nCount); - memset(m_pRangesNums + nStart, 0, nCount); - - //case 14: sUCRName = "NKo"; break; /* U+07C0-U+07FF */ - nStart = 0x07C0; - nCount = 0x07FF - nStart + 1; - memset(m_pRanges + nStart, 14, nCount); - memset(m_pRangesNums + nStart, 0, nCount); - - //case 15: sUCRName = "Devanagari"; break; /* U+0900-U+097F */ - nStart = 0x0900; - nCount = 0x097F - nStart + 1; - memset(m_pRanges + nStart, 15, nCount); - memset(m_pRangesNums + nStart, 0, nCount); - - //case 16: sUCRName = "Bengali"; break; /* U+0980-U+09FF */ - nStart = 0x0980; - nCount = 0x09FF - nStart + 1; - memset(m_pRanges + nStart, 16, nCount); - memset(m_pRangesNums + nStart, 0, nCount); - - //case 17: sUCRName = "Gurmukhi"; break; /* U+0A00-U+0A7F */ - nStart = 0x0A00; - nCount = 0x0A7F - nStart + 1; - memset(m_pRanges + nStart, 17, nCount); - memset(m_pRangesNums + nStart, 0, nCount); - - //case 18: sUCRName = "Gujarati"; break; /* U+0A80-U+0AFF */ - nStart = 0x0A80; - nCount = 0x0AFF - nStart + 1; - memset(m_pRanges + nStart, 18, nCount); - memset(m_pRangesNums + nStart, 0, nCount); - - //case 19: sUCRName = "Oriya"; break; /* U+0B00-U+0B7F */ - nStart = 0x0B00; - nCount = 0x0B7F - nStart + 1; - memset(m_pRanges + nStart, 19, nCount); - memset(m_pRangesNums + nStart, 0, nCount); - - //case 20: sUCRName = "Tamil"; break; /* U+0B80-U+0BFF */ - nStart = 0x0B80; - nCount = 0x0BFF - nStart + 1; - memset(m_pRanges + nStart, 20, nCount); - memset(m_pRangesNums + nStart, 0, nCount); - - //case 21: sUCRName = "Telugu"; break; /* U+0C00-U+0C7F */ - nStart = 0x0C00; - nCount = 0x0C7F - nStart + 1; - memset(m_pRanges + nStart, 21, nCount); - memset(m_pRangesNums + nStart, 0, nCount); - - //case 22: sUCRName = "Kannada"; break; /* U+0C80-U+0CFF */ - nStart = 0x0C80; - nCount = 0x0CFF - nStart + 1; - memset(m_pRanges + nStart, 22, nCount); - memset(m_pRangesNums + nStart, 0, nCount); - - //case 23: sUCRName = "Malayalam"; break; /* U+0D00-U+0D7F */ - nStart = 0x0D00; - nCount = 0x0D7F - nStart + 1; - memset(m_pRanges + nStart, 23, nCount); - memset(m_pRangesNums + nStart, 0, nCount); - - //case 24: sUCRName = "Thai"; break; /* U+0E00-U+0E7F */ - nStart = 0x0E00; - nCount = 0x0E7F - nStart + 1; - memset(m_pRanges + nStart, 24, nCount); - memset(m_pRangesNums + nStart, 0, nCount); - - //case 25: sUCRName = "Lao"; break; /* U+0E80-U+0EFF */ - nStart = 0x0E80; - nCount = 0x0EFF - nStart + 1; - memset(m_pRanges + nStart, 25, nCount); - memset(m_pRangesNums + nStart, 0, nCount); - - //case 26: sUCRName = "Georgian"; break; /* U+10A0-U+10FF */ /* U+2D00-U+2D2F */ - nStart = 0x10A0; - nCount = 0x10FF - nStart + 1; - memset(m_pRanges + nStart, 26, nCount); - memset(m_pRangesNums + nStart, 0, nCount); - - nStart = 0x2D00; - nCount = 0x2D2F - nStart + 1; - memset(m_pRanges + nStart, 26, nCount); - memset(m_pRangesNums + nStart, 0, nCount); - - //case 27: sUCRName = "Balinese"; break; /* U+1B00-U+1B7F */ - nStart = 0x1B00; - nCount = 0x1B7F - nStart + 1; - memset(m_pRanges + nStart, 27, nCount); - memset(m_pRangesNums + nStart, 0, nCount); - - //case 28: sUCRName = "Hangul Jamo"; break; /* U+1100-U+11FF */ - nStart = 0x1100; - nCount = 0x11FF - nStart + 1; - memset(m_pRanges + nStart, 28, nCount); - memset(m_pRangesNums + nStart, 0, nCount); - - //case 29: sUCRName = "Latin Extended Additional"; break; /* U+1E00-U+1EFF */ /* U+2C60-U+2C7F */ /* U+A720-U+A7FF */ - nStart = 0x1E00; - nCount = 0x1EFF - nStart + 1; - memset(m_pRanges + nStart, 29, nCount); - memset(m_pRangesNums + nStart, 0, nCount); - - nStart = 0x2C60; - nCount = 0x2C7F - nStart + 1; - memset(m_pRanges + nStart, 29, nCount); - memset(m_pRangesNums + nStart, 0, nCount); - - nStart = 0xA720; - nCount = 0xA7FF - nStart + 1; - memset(m_pRanges + nStart, 29, nCount); - memset(m_pRangesNums + nStart, 0, nCount); - - //case 30: sUCRName = "Greek Extended"; break; /* U+1F00-U+1FFF */ - nStart = 0x1F00; - nCount = 0x1FFF - nStart + 1; - memset(m_pRanges + nStart, 30, nCount); - memset(m_pRangesNums + nStart, 0, nCount); - - //case 31: sUCRName = "General Punctuation"; break; /* U+2000-U+206F */ /* U+2E00-U+2E7F */ - nStart = 0x2000; - nCount = 0x206F - nStart + 1; - memset(m_pRanges + nStart, 31, nCount); - memset(m_pRangesNums + nStart, 0, nCount); - - nStart = 0x2E00; - nCount = 0x2E7F - nStart + 1; - memset(m_pRanges + nStart, 31, nCount); - memset(m_pRangesNums + nStart, 0, nCount); - - // rangeNum 1 - //case 00: sUCRName = "Superscripts And Subscripts"; break; /* U+2070-U+209F */ - nStart = 0x2070; - nCount = 0x209F - nStart + 1; - memset(m_pRanges + nStart, 0, nCount); - memset(m_pRangesNums + nStart, 1, nCount); - - //case 01: sUCRName = "Currency Symbols"; break; /* U+20A0-U+20CF */ - nStart = 0x20A0; - nCount = 0x20CF - nStart + 1; - memset(m_pRanges + nStart, 1, nCount); - memset(m_pRangesNums + nStart, 1, nCount); - - //case 02: sUCRName = "Combining Diacritical Marks For Symbols"; break; /* U+20D0-U+20FF */ - nStart = 0x20D0; - nCount = 0x20FF - nStart + 1; - memset(m_pRanges + nStart, 2, nCount); - memset(m_pRangesNums + nStart, 1, nCount); - - //case 03: sUCRName = "Letterlike Symbols"; break; /* U+2100-U+214F */ - nStart = 0x2100; - nCount = 0x214F - nStart + 1; - memset(m_pRanges + nStart, 3, nCount); - memset(m_pRangesNums + nStart, 1, nCount); - - //case 04: sUCRName = "Number Forms"; break; /* U+2150-U+218F */ - nStart = 0x2150; - nCount = 0x218F - nStart + 1; - memset(m_pRanges + nStart, 4, nCount); - memset(m_pRangesNums + nStart, 1, nCount); - - //case 05: sUCRName = "Arrows"; break; /* U+2190-U+21FF */ /* U+27F0-U+27FF */ /* U+2900-U+297F */ /* U+2B00-U+2BFF */ - nStart = 0x2190; - nCount = 0x21FF - nStart + 1; - memset(m_pRanges + nStart, 5, nCount); - memset(m_pRangesNums + nStart, 1, nCount); - - nStart = 0x27F0; - nCount = 0x27FF - nStart + 1; - memset(m_pRanges + nStart, 5, nCount); - memset(m_pRangesNums + nStart, 1, nCount); - - nStart = 0x2900; - nCount = 0x297F - nStart + 1; - memset(m_pRanges + nStart, 5, nCount); - memset(m_pRangesNums + nStart, 1, nCount); - - nStart = 0x2B00; - nCount = 0x2BFF - nStart + 1; - memset(m_pRanges + nStart, 5, nCount); - memset(m_pRangesNums + nStart, 1, nCount); - - //case 06: sUCRName = "Mathematical Operators"; break; /* U+2200-U+22FF */ /* U+2A00-U+2AFF */ /* U+27C0-U+27EF */ /* U+2980-U+29FF */ - nStart = 0x2200; - nCount = 0x22FF - nStart + 1; - memset(m_pRanges + nStart, 6, nCount); - memset(m_pRangesNums + nStart, 1, nCount); - - nStart = 0x2A00; - nCount = 0x2AFF - nStart + 1; - memset(m_pRanges + nStart, 6, nCount); - memset(m_pRangesNums + nStart, 1, nCount); - - nStart = 0x27C0; - nCount = 0x27EF - nStart + 1; - memset(m_pRanges + nStart, 6, nCount); - memset(m_pRangesNums + nStart, 1, nCount); - - nStart = 0x2980; - nCount = 0x29FF - nStart + 1; - memset(m_pRanges + nStart, 6, nCount); - memset(m_pRangesNums + nStart, 1, nCount); - - //case 07: sUCRName = "Miscellaneous Technical"; break; /* U+2300-U+23FF */ - nStart = 0x2300; - nCount = 0x23FF - nStart + 1; - memset(m_pRanges + nStart, 7, nCount); - memset(m_pRangesNums + nStart, 1, nCount); - - //case 08: sUCRName = "Control Pictures"; break; /* U+2400-U+243F */ - nStart = 0x2400; - nCount = 0x243F - nStart + 1; - memset(m_pRanges + nStart, 8, nCount); - memset(m_pRangesNums + nStart, 1, nCount); - - //case 09: sUCRName = "Optical Character Recognition"; break; /* U+2440-U+245F */ - nStart = 0x2440; - nCount = 0x245F - nStart + 1; - memset(m_pRanges + nStart, 9, nCount); - memset(m_pRangesNums + nStart, 1, nCount); - - //case 10: sUCRName = "Enclosed Alphanumerics"; break; /* U+2460-U+24FF */ - nStart = 0x2460; - nCount = 0x24FF - nStart + 1; - memset(m_pRanges + nStart, 10, nCount); - memset(m_pRangesNums + nStart, 1, nCount); - - //case 11: sUCRName = "Box Drawing"; break; /* U+2500-U+257F */ - nStart = 0x2500; - nCount = 0x257F - nStart + 1; - memset(m_pRanges + nStart, 11, nCount); - memset(m_pRangesNums + nStart, 1, nCount); - - //case 12: sUCRName = "Block Elements"; break; /* U+2580-U+259F */ - nStart = 0x2580; - nCount = 0x259F - nStart + 1; - memset(m_pRanges + nStart, 12, nCount); - memset(m_pRangesNums + nStart, 1, nCount); - - //case 13: sUCRName = "Geometric Shapes"; break; /* U+25A0-U+25FF */ - nStart = 0x25A0; - nCount = 0x25FF - nStart + 1; - memset(m_pRanges + nStart, 13, nCount); - memset(m_pRangesNums + nStart, 1, nCount); - - //case 14: sUCRName = "Miscellaneous Symbols"; break; /* U+2600-U+26FF */ - nStart = 0x2600; - nCount = 0x26FF - nStart + 1; - memset(m_pRanges + nStart, 14, nCount); - memset(m_pRangesNums + nStart, 1, nCount); - - //case 15: sUCRName = "Dingbats"; break; /* U+2700-U+27BF */ - nStart = 0x2700; - nCount = 0x27BF - nStart + 1; - memset(m_pRanges + nStart, 15, nCount); - memset(m_pRangesNums + nStart, 1, nCount); - - //case 16: sUCRName = "CJK Symbols and Punctuation"; break; /* U+3000-U+303F */ - nStart = 0x3000; - nCount = 0x303F - nStart + 1; - memset(m_pRanges + nStart, 16, nCount); - memset(m_pRangesNums + nStart, 1, nCount); - - //case 17: sUCRName = "Hiragana"; break; /* U+3040-U+309F */ - nStart = 0x3040; - nCount = 0x309F - nStart + 1; - memset(m_pRanges + nStart, 17, nCount); - memset(m_pRangesNums + nStart, 1, nCount); - - //case 18: sUCRName = "Katakana"; break; /* U+30A0-U+30FF */ /* U+31F0-U+31FF */ - nStart = 0x30A0; - nCount = 0x30FF - nStart + 1; - memset(m_pRanges + nStart, 18, nCount); - memset(m_pRangesNums + nStart, 1, nCount); - - nStart = 0x31F0; - nCount = 0x31FF - nStart + 1; - memset(m_pRanges + nStart, 18, nCount); - memset(m_pRangesNums + nStart, 1, nCount); - - //case 19: sUCRName = "Bopomofo"; break; /* U+3100-U+312F */ /* U+31A0-U+31BF */ - nStart = 0x3100; - nCount = 0x312F - nStart + 1; - memset(m_pRanges + nStart, 19, nCount); - memset(m_pRangesNums + nStart, 1, nCount); - - nStart = 0x31A0; - nCount = 0x31BF - nStart + 1; - memset(m_pRanges + nStart, 19, nCount); - memset(m_pRangesNums + nStart, 1, nCount); - - //case 20: sUCRName = "Hangul Compatibility Jamo"; break; /* U+3130-U+318F */ - nStart = 0x3130; - nCount = 0x318F - nStart + 1; - memset(m_pRanges + nStart, 20, nCount); - memset(m_pRangesNums + nStart, 1, nCount); - - //case 21: sUCRName = "Phags-pa"; break; /* U+A840-U+A87F */ - nStart = 0xA840; - nCount = 0xA87F - nStart + 1; - memset(m_pRanges + nStart, 21, nCount); - memset(m_pRangesNums + nStart, 1, nCount); - - //case 22: sUCRName = "Enclosed CJK Letters and Months"; break; /* U+3200-U+32FF */ - nStart = 0x3200; - nCount = 0x32FF - nStart + 1; - memset(m_pRanges + nStart, 22, nCount); - memset(m_pRangesNums + nStart, 1, nCount); - - //case 23: sUCRName = "CJK Compatibility"; break; /* U+3300-U+33FF */ - nStart = 0x3300; - nCount = 0x33FF - nStart + 1; - memset(m_pRanges + nStart, 23, nCount); - memset(m_pRangesNums + nStart, 1, nCount); - - //case 24: sUCRName = "Hangul Syllables"; break; /* U+AC00-U+D7AF */ - nStart = 0xAC00; - nCount = 0xD7AF - nStart + 1; - memset(m_pRanges + nStart, 24, nCount); - memset(m_pRangesNums + nStart, 1, nCount); - - //case 25: sUCRName = "Non-Plane 0"; break; /* U+D800-U+DB7F */ /* U+DB80-U+DBFF */ /* U+DC00-U+DFFF */ // Не юникодные символы - nStart = 0xD800; - nCount = 0xDB7F - nStart + 1; - memset(m_pRanges + nStart, 25, nCount); - memset(m_pRangesNums + nStart, 1, nCount); - - nStart = 0xDB80; - nCount = 0xDBFF - nStart + 1; - memset(m_pRanges + nStart, 25, nCount); - memset(m_pRangesNums + nStart, 1, nCount); - - nStart = 0xDC00; - nCount = 0xDFFF - nStart + 1; - memset(m_pRanges + nStart, 25, nCount); - memset(m_pRangesNums + nStart, 1, nCount); - - //case 26: sUCRName = "Phoenician"; break; /*U+10900-U+1091F*/ - - //case 27: sUCRName = "CJK Unified Ideographs"; break; /* U+4E00-U+9FFF */ /* U+2E80-U+2EFF */ /* U+2F00-U+2FDF */ /* U+2FF0-U+2FFF */ /* U+3400-U+4DB5 */ /*U+20000-U+2A6D6*/ /* U+3190-U+319F */ - nStart = 0x4E00; - nCount = 0x9FFF - nStart + 1; - memset(m_pRanges + nStart, 27, nCount); - memset(m_pRangesNums + nStart, 1, nCount); - - nStart = 0x2E80; - nCount = 0x2EFF - nStart + 1; - memset(m_pRanges + nStart, 27, nCount); - memset(m_pRangesNums + nStart, 1, nCount); - - nStart = 0x2F00; - nCount = 0x2FDF - nStart + 1; - memset(m_pRanges + nStart, 27, nCount); - memset(m_pRangesNums + nStart, 1, nCount); - - nStart = 0x2FF0; - nCount = 0x2FFF - nStart + 1; - memset(m_pRanges + nStart, 27, nCount); - memset(m_pRangesNums + nStart, 1, nCount); - - nStart = 0x3400; - nCount = 0x4DB5 - nStart + 1; - memset(m_pRanges + nStart, 27, nCount); - memset(m_pRangesNums + nStart, 1, nCount); - - nStart = 0x3190; - nCount = 0x319F - nStart + 1; - memset(m_pRanges + nStart, 27, nCount); - memset(m_pRangesNums + nStart, 1, nCount); - - //case 28: sUCRName = "Private Use Area (plane 0)"; break; /* U+E000-U+F8FF */ // Не юникодные символы - nStart = 0xE000; - nCount = 0xF8FF - nStart + 1; - memset(m_pRanges + nStart, 28, nCount); - memset(m_pRangesNums + nStart, 1, nCount); - - //case 29: sUCRName = "CJK Strokes"; break; /* U+31C0-U+31EF */ /* U+F900-U+FAFF */ /*U+2F800-U+2FA1F*/ - nStart = 0x31C0; - nCount = 0x31EF - nStart + 1; - memset(m_pRanges + nStart, 29, nCount); - memset(m_pRangesNums + nStart, 1, nCount); - - nStart = 0xF900; - nCount = 0xFAFF - nStart + 1; - memset(m_pRanges + nStart, 29, nCount); - memset(m_pRangesNums + nStart, 1, nCount); - - //case 30: sUCRName = "Alphabetic Presentation Forms"; break; /* U+FB00-U+FB4F */ - nStart = 0xFB00; - nCount = 0xFB4F - nStart + 1; - memset(m_pRanges + nStart, 30, nCount); - memset(m_pRangesNums + nStart, 1, nCount); - - //case 31: sUCRName = "Arabic Presentation Forms-A"; break; /* U+FB50-U+FDFF */ - nStart = 0xFB50; - nCount = 0xFDFF - nStart + 1; - memset(m_pRanges + nStart, 31, nCount); - memset(m_pRangesNums + nStart, 1, nCount); - - // rangeNum 2 - //case 00: sUCRName = "Combining Half Marks"; break; /* U+FE20-U+FE2F */ - nStart = 0xFE20; - nCount = 0xFE2F - nStart + 1; - memset(m_pRanges + nStart, 0, nCount); - memset(m_pRangesNums + nStart, 2, nCount); - - //case 01: sUCRName = "Vertical forms"; break; /* U+FE10-U+FE1F */ /* U+FE30-U+FE4F */ - nStart = 0xFE10; - nCount = 0xFE1F - nStart + 1; - memset(m_pRanges + nStart, 1, nCount); - memset(m_pRangesNums + nStart, 2, nCount); - - nStart = 0xFE30; - nCount = 0xFE4F - nStart + 1; - memset(m_pRanges + nStart, 1, nCount); - memset(m_pRangesNums + nStart, 2, nCount); - - //case 02: sUCRName = "Small Form Variants"; break; /* U+FE50-U+FE6F */ - nStart = 0xFE50; - nCount = 0xFE6F - nStart + 1; - memset(m_pRanges + nStart, 2, nCount); - memset(m_pRangesNums + nStart, 2, nCount); - - //case 03: sUCRName = "Arabic Presentation Forms-B"; break; /* U+FE70-U+FEFE */ - nStart = 0xFE70; - nCount = 0xFEFE - nStart + 1; - memset(m_pRanges + nStart, 3, nCount); - memset(m_pRangesNums + nStart, 2, nCount); - - //case 04: sUCRName = "Halfwidth and Fullwidth Forms"; break; /* U+FF00-U+FFEF */ - nStart = 0xFF00; - nCount = 0xFFEF - nStart + 1; - memset(m_pRanges + nStart, 4, nCount); - memset(m_pRangesNums + nStart, 2, nCount); - - //case 05: sUCRName = "Specials"; break; /* U+FFF0-U+FFFF */ - nStart = 0xFFF0; - nCount = 0xFFFF - nStart + 1; - memset(m_pRanges + nStart, 5, nCount); - memset(m_pRangesNums + nStart, 2, nCount); - - //case 06: sUCRName = "Tibetan"; break; /* U+0F00-U+0FFF */ - nStart = 0x0F00; - nCount = 0x0FFF - nStart + 1; - memset(m_pRanges + nStart, 6, nCount); - memset(m_pRangesNums + nStart, 2, nCount); - - //case 07: sUCRName = "Syriac"; break; /* U+0700-U+074F */ - nStart = 0x0700; - nCount = 0x074F - nStart + 1; - memset(m_pRanges + nStart, 7, nCount); - memset(m_pRangesNums + nStart, 2, nCount); - - //case 08: sUCRName = "Thaana"; break; /* U+0780-U+07BF */ - nStart = 0x0780; - nCount = 0x07BF - nStart + 1; - memset(m_pRanges + nStart, 8, nCount); - memset(m_pRangesNums + nStart, 2, nCount); - - //case 09: sUCRName = "Sinhala"; break; /* U+0D80-U+0DFF */ - nStart = 0x0D80; - nCount = 0x0DFF - nStart + 1; - memset(m_pRanges + nStart, 9, nCount); - memset(m_pRangesNums + nStart, 2, nCount); - - //case 10: sUCRName = "Myanmar"; break; /* U+1000-U+109F */ - nStart = 0x1000; - nCount = 0x109F - nStart + 1; - memset(m_pRanges + nStart, 10, nCount); - memset(m_pRangesNums + nStart, 2, nCount); - - //case 11: sUCRName = "Ethiopic"; break; /* U+1200-U+137F */ /* U+1380-U+139F */ /* U+2D80-U+2DDF */ - nStart = 0x1200; - nCount = 0x137F - nStart + 1; - memset(m_pRanges + nStart, 11, nCount); - memset(m_pRangesNums + nStart, 2, nCount); - - nStart = 0x1380; - nCount = 0x139F - nStart + 1; - memset(m_pRanges + nStart, 11, nCount); - memset(m_pRangesNums + nStart, 2, nCount); - - nStart = 0x2D80; - nCount = 0x2DDF - nStart + 1; - memset(m_pRanges + nStart, 11, nCount); - memset(m_pRangesNums + nStart, 2, nCount); - - //case 12: sUCRName = "Cherokee"; break; /* U+13A0-U+13FF */ - nStart = 0x13A0; - nCount = 0x13FF - nStart + 1; - memset(m_pRanges + nStart, 12, nCount); - memset(m_pRangesNums + nStart, 2, nCount); - - //case 13: sUCRName = "Unified Canadian Aboriginal Syllabics"; break; /* U+1400-U+167F */ - nStart = 0x1400; - nCount = 0x167F - nStart + 1; - memset(m_pRanges + nStart, 13, nCount); - memset(m_pRangesNums + nStart, 2, nCount); - - //case 14: sUCRName = "Ogham"; break; /* U+1680-U+169F */ - nStart = 0x1680; - nCount = 0x169F - nStart + 1; - memset(m_pRanges + nStart, 14, nCount); - memset(m_pRangesNums + nStart, 2, nCount); - - //case 15: sUCRName = "Runic"; break; /* U+16A0-U+16FF */ - nStart = 0x16A0; - nCount = 0x16FF - nStart + 1; - memset(m_pRanges + nStart, 15, nCount); - memset(m_pRangesNums + nStart, 2, nCount); - - //case 16: sUCRName = "Khmer"; break; /* U+1780-U+17FF */ /* U+19E0-U+19FF */ - nStart = 0x1780; - nCount = 0x17FF - nStart + 1; - memset(m_pRanges + nStart, 16, nCount); - memset(m_pRangesNums + nStart, 2, nCount); - - nStart = 0x19E0; - nCount = 0x19FF - nStart + 1; - memset(m_pRanges + nStart, 16, nCount); - memset(m_pRangesNums + nStart, 2, nCount); - - //case 17: sUCRName = "Mongolian"; break; /* U+1800-U+18AF */ - nStart = 0x1800; - nCount = 0x18AF - nStart + 1; - memset(m_pRanges + nStart, 17, nCount); - memset(m_pRangesNums + nStart, 2, nCount); - - //case 18: sUCRName = "Braille Patterns"; break; /* U+2800-U+28FF */ - nStart = 0x2800; - nCount = 0x28FF - nStart + 1; - memset(m_pRanges + nStart, 18, nCount); - memset(m_pRangesNums + nStart, 2, nCount); - - //case 19: sUCRName = "Yi Syllables"; break; /* U+A000-U+A48F */ /* U+A490-U+A4CF */ - nStart = 0xA000; - nCount = 0xA48F - nStart + 1; - memset(m_pRanges + nStart, 19, nCount); - memset(m_pRangesNums + nStart, 2, nCount); - - nStart = 0xA490; - nCount = 0xA4CF - nStart + 1; - memset(m_pRanges + nStart, 19, nCount); - memset(m_pRangesNums + nStart, 2, nCount); - - //case 20: sUCRName = "Tagalog"; break; /* U+1700-U+171F */ /* U+1720-U+173F */ /* U+1740-U+175F */ /* U+1760-U+177F */ - nStart = 0x1700; - nCount = 0x171F - nStart + 1; - memset(m_pRanges + nStart, 20, nCount); - memset(m_pRangesNums + nStart, 2, nCount); - - nStart = 0x1720; - nCount = 0x173F - nStart + 1; - memset(m_pRanges + nStart, 20, nCount); - memset(m_pRangesNums + nStart, 2, nCount); - - nStart = 0x1740; - nCount = 0x175F - nStart + 1; - memset(m_pRanges + nStart, 20, nCount); - memset(m_pRangesNums + nStart, 2, nCount); - - nStart = 0x1760; - nCount = 0x177F - nStart + 1; - memset(m_pRanges + nStart, 20, nCount); - memset(m_pRangesNums + nStart, 2, nCount); - - //case 21: sUCRName = "Old Italic"; break; /*U+10300-U+1032F*/ - //case 22: sUCRName = "Gothic"; break; /*U+10330-U+1034F*/ - //case 23: sUCRName = "Deseret"; break; /*U+10400-U+1044F*/ - //case 24: sUCRName = "Byzantine Musical Symbols"; break; /*U+1D000-U+1D0FF*/ /*U+1D100-U+1D1FF*/ /*U+1D200-U+1D24F*/ - //case 25: sUCRName = "Mathematical Alphanumeric Symbols"; break; /*U+1D400-U+1D7FF*/ - //case 26: sUCRName = "Private Use (plane 15)"; break; /*U+F0000-U+FFFFD*/ /*U+100000-U+10FFFD*/ // Не юникодные символы - - //case 27: sUCRName = "Variation Selectors"; break; /* U+FE00-U+FE0F */ /*U+E0100-U+E01EF*/ - nStart = 0xFE00; - nCount = 0xFE0F - nStart + 1; - memset(m_pRanges + nStart, 27, nCount); - memset(m_pRangesNums + nStart, 2, nCount); - - //case 28: sUCRName = "Tags"; break; /*U+E0000-U+E007F*/ - //case 29: sUCRName = "Limbu"; break; /* U+1900-U+194F */ - nStart = 0x1900; - nCount = 0x194F - nStart + 1; - memset(m_pRanges + nStart, 29, nCount); - memset(m_pRangesNums + nStart, 2, nCount); - - //case 30: sUCRName = "Tai Le"; break; /* U+1950-U+197F */ - nStart = 0x1950; - nCount = 0x197F - nStart + 1; - memset(m_pRanges + nStart, 30, nCount); - memset(m_pRangesNums + nStart, 2, nCount); - - //case 31: sUCRName = "New Tai Lue"; break; /* U+1980-U+19DF */ - nStart = 0x1980; - nCount = 0x19DF - nStart + 1; - memset(m_pRanges + nStart, 31, nCount); - memset(m_pRangesNums + nStart, 2, nCount); - - // rangeNum 3 - //case 00: sUCRName = "Buginese"; break; /* U+1A00-U+1A1F */ - nStart = 0x1A00; - nCount = 0x1A1F - nStart + 1; - memset(m_pRanges + nStart, 0, nCount); - memset(m_pRangesNums + nStart, 3, nCount); - - //case 01: sUCRName = "Glagolitic"; break; /* U+2C00-U+2C5F */ - nStart = 0x2C00; - nCount = 0x2C5F - nStart + 1; - memset(m_pRanges + nStart, 1, nCount); - memset(m_pRangesNums + nStart, 3, nCount); - - //case 02: sUCRName = "Tifinagh"; break; /* U+2D30-U+2D7F */ - nStart = 0x2D30; - nCount = 0x2D7F - nStart + 1; - memset(m_pRanges + nStart, 2, nCount); - memset(m_pRangesNums + nStart, 3, nCount); - - //case 03: sUCRName = "Yijing Hexagram Symbols"; break; /* U+4DC0-U+4DFF */ - nStart = 0x4DC0; - nCount = 0x4DFF - nStart + 1; - memset(m_pRanges + nStart, 3, nCount); - memset(m_pRangesNums + nStart, 3, nCount); - - //case 04: sUCRName = "Syloti Nagri"; break; /* U+A800-U+A82F */ - nStart = 0xA800; - nCount = 0xA82F - nStart + 1; - memset(m_pRanges + nStart, 4, nCount); - memset(m_pRangesNums + nStart, 3, nCount); - - //case 05: sUCRName = "Linear B Syllabary"; break; /*U+10000-U+1007F*/ /*U+10080-U+100FF*/ /*U+10100-U+1013F*/ - //case 06: sUCRName = "Ancient Greek Numbers"; break; /*U+10140-U+1018F*/ - //case 07: sUCRName = "Ugaritic"; break; /*U+10380-U+1039F*/ - //case 08: sUCRName = "Old Persian"; break; /*U+103A0-U+103DF*/ - //case 09: sUCRName = "Shavian"; break; /*U+10450-U+1047F*/ - //case 10: sUCRName = "Osmanya"; break; /*U+10480-U+104AF*/ - //case 11: sUCRName = "Cypriot Syllabary"; break; /*U+10800-U+1083F*/ - //case 12: sUCRName = "Kharoshthi"; break; /*U+10A00-U+10A5F*/ - //case 13: sUCRName = "Tai Xuan Jing Symbols"; break; /*U+1D300-U+1D35F*/ - //case 14: sUCRName = "Cuneiform"; break; /*U+12000-U+123FF*/ /*U+12400-U+1247F*/ - //case 15: sUCRName = "Counting Rod Numerals"; break; /*U+1D360-U+1D37F*/ - - //case 16: sUCRName = "Sundanese"; break; /* U+1B80-U+1BBF */ - nStart = 0x1B80; - nCount = 0x1BBF - nStart + 1; - memset(m_pRanges + nStart, 16, nCount); - memset(m_pRangesNums + nStart, 3, nCount); - - //case 17: sUCRName = "Lepcha"; break; /* U+1C00-U+1C4F */ - nStart = 0x1C00; - nCount = 0x1C4F - nStart + 1; - memset(m_pRanges + nStart, 17, nCount); - memset(m_pRangesNums + nStart, 3, nCount); - - //case 18: sUCRName = "Ol Chiki"; break; /* U+1C50-U+1C7F */ - nStart = 0x1C50; - nCount = 0x1C7F - nStart + 1; - memset(m_pRanges + nStart, 18, nCount); - memset(m_pRangesNums + nStart, 3, nCount); - - //case 19: sUCRName = "Saurashtra"; break; /* U+A880-U+A8DF */ - nStart = 0xA880; - nCount = 0xA8DF - nStart + 1; - memset(m_pRanges + nStart, 19, nCount); - memset(m_pRangesNums + nStart, 3, nCount); - - //case 20: sUCRName = "Kayah Li"; break; /* U+A900-U+A92F */ - nStart = 0xA900; - nCount = 0xA92F - nStart + 1; - memset(m_pRanges + nStart, 20, nCount); - memset(m_pRangesNums + nStart, 3, nCount); - - //case 21: sUCRName = "Rejang"; break; /* U+A930-U+A95F */ - nStart = 0xA930; - nCount = 0xA95F - nStart + 1; - memset(m_pRanges + nStart, 21, nCount); - memset(m_pRangesNums + nStart, 3, nCount); - - //case 22: sUCRName = "Cham"; break; /* U+AA00-U+AA5F */ - nStart = 0xAA00; - nCount = 0xAA5F - nStart + 1; - memset(m_pRanges + nStart, 22, nCount); - memset(m_pRangesNums + nStart, 3, nCount); - - //case 23: sUCRName = "Ancient Symbols"; break; /*U+10190-U+101CF*/ - //case 24: sUCRName = "Phaistos Disc"; break; /*U+101D0-U+101FF*/ - //case 25: sUCRName = "Carian"; break; /*U+102A0-U+102DF*/ /*U+10280-U+1029F*/ /*U+10920-U+1093F*/ - //case 26: sUCRName = "Domino Tiles"; break; /*U+1F030-U+1F09F*/ /*U+1F000-U+1F02F*/ - //case 27: sUCRName = "Reserved for process-internal usage"; break; - //case 28: sUCRName = "Reserved for process-internal usage"; break; - //case 29: sUCRName = "Reserved for process-internal usage"; break; - //case 30: sUCRName = "Reserved for process-internal usage"; break; - //case 31: sUCRName = "Reserved for process-internal usage"; break; - } - - inline void InitializeUnicodeMap() - { - memset(m_mapUnicode, 0, 0xFFFF); - - m_mapUnicode[0x0009] = 1; - m_mapUnicode[0x000A] = 1; - m_mapUnicode[0x000D] = 1; - - memset(m_mapUnicode + 0x0020, 1, 0xD7FF - 0x0020 + 1); - memset(m_mapUnicode + 0xE000, 1, 0xFFFD - 0xE000 + 1); - } - - inline bool GetRange(const WCHAR& symbol, BYTE& lRangeNum, BYTE& lRange) - { - lRangeNum = m_pRangesNums[symbol]; - lRange = m_pRanges[symbol]; - - return (0xFF != lRangeNum); - } - - inline void CheckRanges(DWORD& lRange1, DWORD& lRange2, DWORD& lRange3, DWORD& lRange4, const std::wstring& strText) - { - int lCount = strText.length(); - const WCHAR* pData = strText.c_str(); - - BYTE lRangeNum = 0xFF; - BYTE lRange = 0xFF; - for (int i = 0; i < lCount; ++i, ++pData) - { - if (GetRange(*pData, lRangeNum, lRange)) - { - if (0 == lRangeNum) - lRange1 |= 1 << lRange; - else if (1 == lRangeNum) - lRange2 |= 1 << lRange; - else if (2 == lRangeNum) - lRange3 |= 1 << lRange; - else - lRange4 |= 1 << lRange; - } - } - } - inline void CheckRanges(UINT& lRange1, UINT& lRange2, UINT& lRange3, UINT& lRange4, BYTE& lRangeNum, BYTE& lRange) - { - if (0 == lRangeNum) - lRange1 |= 1 << lRange; - else if (1 == lRangeNum) - lRange2 |= 1 << lRange; - else if (2 == lRangeNum) - lRange3 |= 1 << lRange; - else - lRange4 |= 1 << lRange; - } - - public: - inline static bool IsEqual3(NSStructures::CFont* f1, NSStructures::CFont* f2) - { - return ((f1->Path == f2->Path) && (f1->Bold == f2->Bold) && (f1->Italic == f2->Italic)); - } - inline static bool IsEqual2(NSStructures::CFont* f1, NSStructures::CFont* f2, double dScalingSrcSize = 1) - { - if (!f1->Path.empty() && !f2->Path.empty()) - return ((f1->Path == f2->Path) && - (f1->StringGID == f2->StringGID) && - (fabs(f1->Size - (f2->Size * dScalingSrcSize)) < 0.0001) && - (f1->Bold == f2->Bold) && - (f1->Italic == f2->Italic)); - - return ((f1->Name == f2->Name) && - (f1->Path == f2->Path) && - (f1->StringGID == f2->StringGID) && - (f1->Size == (f2->Size * dScalingSrcSize)) && - (f1->Bold == f2->Bold) && - (f1->Italic == f2->Italic)); - } - - public: - inline bool GenerateFontName(NSStringUtils::CStringBuilder& oTextItem, bool bIsFontChanged) - { - if (m_oFont.m_oFont.Path.empty()) - return false; - - BYTE lRangeNum = 0xFF; - BYTE lRange = 0xFF; - - GetRange(oTextItem.GetBuffer()[0], lRangeNum, lRange); - - if (!bIsFontChanged && (0 != m_arListPicUps.size())) - { - CFontPickUp& oPick = *m_arListPicUps.begin(); - - if ((lRangeNum == oPick.m_lRangeNum) && (lRange == oPick.m_lRange)) - { - // по идее не надо приравнивать, они должны были быть выставлены ещ раньше - //m_strCurrentPickFont = oPick.m_strPickFont; - //m_lCurrentPictFontStyle = oPick.m_lPickStyle; - return false; - } - } - - std::list::iterator pos = m_arListPicUps.begin(); - while (pos != m_arListPicUps.end()) - { - CFontPickUp& oPick = *pos; - pos++; - - if ((IsEqual3(&m_oFont.m_oFont, &oPick.m_oFont.m_oFont)) && (lRangeNum == oPick.m_lRangeNum) && (lRange == oPick.m_lRange)) - { - // нашли! ничего подбирать не нужно - // нужно просто выкинуть этот шрифт наверх - if (pos != m_arListPicUps.begin()) - { - m_arListPicUps.splice(m_arListPicUps.begin(), m_arListPicUps, pos, std::next(pos)); - } - - m_strCurrentPickFont = oPick.m_strPickFont; - m_lCurrentPictFontStyle = oPick.m_lPickStyle; - return false; - } - } - - // не нашли... - CFontPickUp oPick; - - oPick.m_lRangeNum = lRangeNum; - oPick.m_lRange = lRange; - oPick.m_oFont = m_oFont; - oPick.m_strPickFont = m_oFont.m_oProperties.m_strFamilyName; - oPick.m_lPickStyle = m_oFont.m_oProperties.m_lStyle; - - LONG lCountSigs = (LONG)m_oFont.m_oProperties.m_arSignature.size(); - UINT dwR1 = 0; - if (0 < lCountSigs) - dwR1 = m_oFont.m_oProperties.m_arSignature[0]; - UINT dwR2 = 0; - if (1 < lCountSigs) - dwR2 = m_oFont.m_oProperties.m_arSignature[1]; - UINT dwR3 = 0; - if (2 < lCountSigs) - dwR3 = m_oFont.m_oProperties.m_arSignature[2]; - UINT dwR4 = 0; - if (3 < lCountSigs) - dwR4 = m_oFont.m_oProperties.m_arSignature[3]; - - DWORD dwCodePage1 = 0; - DWORD dwCodePage2 = 0; - - if ((lRangeNum == 1) && (lRange == 28)) - { - dwCodePage1 = 0x80000000; - //strText = (WCHAR)(strText[0] - 0xF000); - } - else if (((lRangeNum == 2) && (lRange == 3)) || ((lRangeNum == 1) && (lRange == 31)) || ((lRangeNum == 0) && (lRange == 13))) - { - // арабский язык!!! - dwR1 = 1 << 13; - dwR2 = 1 << 31; - dwR3 = 1 << 3; - } - else - { - CheckRanges(dwR1, dwR2, dwR3, dwR4, lRangeNum, lRange); - } - - NSFonts::CFontSelectFormat oFormat; - oFormat.wsName = new std::wstring(m_oFont.m_oProperties.m_strFamilyName); - oFormat.pPanose = new BYTE[10]; - memcpy(oFormat.pPanose, m_oFont.m_oProperties.m_strPANOSE, 10); - oFormat.bBold = new INT(m_oFont.m_oFont.Bold); - oFormat.bItalic = new INT(m_oFont.m_oFont.Italic); - oFormat.bFixedWidth = new INT(m_oFont.m_oProperties.m_bIsFixedWidth ? 1 : 0); - - if (0 != dwR1) - oFormat.ulRange1 = new UINT(dwR1); - if (0 != dwR2) - oFormat.ulRange2 = new UINT(dwR2); - if (0 != dwR3) - oFormat.ulRange3 = new UINT(dwR3); - if (0 != dwR4) - oFormat.ulRange4 = new UINT(dwR4); - if (0 != dwCodePage1) - oFormat.ulCodeRange1 = new UINT(dwCodePage1); - if (0 != dwCodePage2) - oFormat.ulCodeRange2 = new UINT(dwCodePage2); - - NSFonts::CFontInfo* pInfo = m_pManager->GetFontInfoByParams(oFormat); - oPick.m_strPickFont = pInfo->m_wsFontName; - oPick.m_lPickStyle = m_oFont.m_oFont.GetStyle(); - m_strCurrentPickFont = oPick.m_strPickFont; - m_lCurrentPictFontStyle = oPick.m_lPickStyle; - - m_arListPicUps.push_front(oPick); - return true; - } - - inline void SetStringGid(const LONG& lGid) - { - m_pManager->SetStringGID(lGid); - } - inline LONG GetStringGid() - { - return m_pManager->GetStringGID(); - } - - inline wchar_t* GetUnicodeString(wchar_t* bsText) - { - wchar_t* start = (wchar_t*)bsText; - wchar_t* s = start; - for (; *s != 0; ++s); - - LONG lLen = (LONG)(s - start); - - wchar_t* pData = new wchar_t[lLen + 1]; - for (LONG i = 0; i < lLen; ++i, ++start) - { - if (m_mapUnicode[*start]) - pData[i] = *start; - else - pData[i] = (wchar_t)(' '); - } - return pData; - } - - std::wstring GetFontPath(NSStructures::CFont* pFont) - { - NSFonts::CFontSelectFormat oFormat; - oFormat.bBold = new INT(pFont->Bold); - oFormat.bItalic = new INT(pFont->Italic); - oFormat.wsName = new std::wstring(pFont->Name); - - NSFonts::CFontInfo* pInfo = m_pManager->GetFontInfoByParams(oFormat); - return pInfo->m_wsFontPath; - } - }; - } -} - -#endif // _ASC_HTMLRENDERER_FMBASE_H_ diff --git a/HtmlRenderer/src/HTMLRenderer3.cpp b/HtmlRenderer/src/HTMLRenderer3.cpp deleted file mode 100644 index fd4a96df0b7..00000000000 --- a/HtmlRenderer/src/HTMLRenderer3.cpp +++ /dev/null @@ -1,1362 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2023 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#include "../include/HTMLRenderer3.h" -#include "./Common.h" -#include "./Document.h" -#include "./Writer.h" - -namespace NSHtmlRenderer -{ - class CASCHTMLRenderer3_Private : public NSHtmlRenderer::IBaseMatrixUpdater - { - public: - NSHtmlRenderer::CDocument m_oDocument; // вся информация о документе (только страницы и их размеры) - NSHtmlRenderer::CWriter m_oWriter; // сам вьюер. основной класс - - NSHtmlRenderer::CGraphicsDumper m_oDumper; - bool m_bIsGraphicsDumperMode; - - std::wstring m_strDstFile; - int m_lLastSavedPage; - - Aggplus::CGraphicsPathSimpleConverter m_oSimpleGraphicsConverter; // конвертер сложных гафических путей в простые - - NSFonts::IApplicationFonts* m_pApplicationFonts; - NSFonts::IFontManager* m_pFontManager; // менеджер шрифтов - - Aggplus::CMatrix m_oTransform; // текущая матрица преобразований рендерера - double m_dTransformAngle; - - int m_lCurrentCommandType; // текущая команда - int m_lCurrentPage; // текущая страница - bool m_bIsMetafileDrawing; - bool m_bIsTextGraphicType; - - int m_lClipMode; - - NSStructures::CPen m_oPen; // настройки всей графики (скопирован ашник из AVSGraphics) - NSStructures::CBrush m_oBrush; - NSStructures::CFont m_oFont; - - NSStructures::CFont m_oInstalledFont; - - bool m_bPageClosed; - bool m_bPageOpened; - - bool m_bIsChangedFontParamBetweenDrawText; - - public: - int* m_pTempUnicodes; - int m_nTempUnicodesAlloc; - int m_nTempUnicodesLen; - - bool m_bIsOnlyTextMode; - bool m_bDisablePageEnd; - - public: - CASCHTMLRenderer3_Private() - { - // initialize move to CreateOfficeFile (custom directory support) - //m_oApplicationFonts.Initialize(); - m_pApplicationFonts = NSFonts::NSApplication::Create(); - m_pApplicationFonts->GetCache()->SetCacheSize(16); - - m_lLastSavedPage = 0; - m_oDocument.SetUpdater(this); - - m_oWriter.m_pPen = &m_oPen; - m_oWriter.m_pBrush = &m_oBrush; - m_oWriter.m_pFont = &m_oFont; - - m_bPageClosed = true; - - m_dTransformAngle = 0.0; - - m_pFontManager = NULL; - - m_oWriter.SetSimpleConverter(&m_oSimpleGraphicsConverter, &m_oTransform); - m_oWriter.SetApplicationFonts(m_pApplicationFonts); - - m_bIsMetafileDrawing = false; - m_bIsTextGraphicType = false; - - m_bIsChangedFontParamBetweenDrawText = true; - m_bIsGraphicsDumperMode = false; - - m_nTempUnicodesAlloc = 100; - m_pTempUnicodes = new int[m_nTempUnicodesAlloc]; - m_nTempUnicodesLen = 0; - - m_bIsOnlyTextMode = false; - m_bPageOpened = false; - - m_bDisablePageEnd = false; - } - ~CASCHTMLRenderer3_Private() - { - RELEASEOBJECT(m_pApplicationFonts); - RELEASEARRAYOBJECTS(m_pTempUnicodes); - } - - public: - void GetUnicodes(const std::wstring& sText) - { - int nLen = (int)sText.length(); - if (nLen > m_nTempUnicodesAlloc) - { - RELEASEARRAYOBJECTS(m_pTempUnicodes); - m_nTempUnicodesAlloc = nLen; - m_pTempUnicodes = new int[m_nTempUnicodesAlloc]; - } - - m_nTempUnicodesLen = 0; - const wchar_t* pWchars = sText.c_str(); - - if (sizeof(wchar_t) == 2) - { - for (int nIndex = 0, nGlyphIndex = 0; nIndex < nLen; ++nIndex, ++nGlyphIndex) - { - int code = (int)pWchars[nIndex]; - if (code >= 0xD800 && code <= 0xDFFF && (nIndex + 1) < nLen) - { - ++nIndex; - code = 0x10000 + (((code & 0x3FF) << 10) | (0x03FF & pWchars[nIndex])); - } - - m_pTempUnicodes[m_nTempUnicodesLen++] = code; - } - } - else - { - for ( int nIndex = 0; nIndex < nLen; ++nIndex ) - { - m_pTempUnicodes[m_nTempUnicodesLen++] = (int)pWchars[nIndex]; - } - } - } - - public: - virtual void OnBaseMatrixUpdate(const double& dWidth, const double& dHeight) - { - if (m_bPageClosed) - { - // значит размеры пришли не в первый раз для текущей страницы - return; - } - m_bPageClosed = true; - StartPage(dWidth, dHeight); - } - - void CalculateFullTransform() - { - m_dTransformAngle = m_oTransform.z_Rotation(); - } - - inline void MoveTo(const double& dX, const double& dY) - { - m_oWriter.WritePathMoveTo(dX, dY); - } - inline void LineTo(const double& dX, const double& dY) - { - m_oWriter.WritePathLineTo(dX, dY); - } - inline void CurveTo(const double& x1, const double& y1, const double& x2, const double& y2, const double& x3, const double& y3) - { - m_oWriter.WritePathCurveTo(x1, y1, x2, y2, x3, y3); - } - void Start() - { - m_oWriter.WriteBeginPath(); - } - void End() - { - m_oWriter.WriteEndPath(); - } - void Close() - { - m_oWriter.WritePathClose(); - } - - void StartPage(const double& dWidth, const double& dHeight) - { - ++m_lCurrentPage; - m_oWriter.NewPage(dWidth, dHeight); - } - void EndPage() - { - m_oWriter.EndPage(); - m_bPageOpened = false; - } - - void _SetFont() - { - if (NULL == m_pFontManager) - { - m_pFontManager = m_pApplicationFonts->GenerateFontManager(); - } - - double dPix = m_oFont.CharSpace * 96 / 25.4; - - if (m_oInstalledFont.IsEqual(&m_oFont)) - { - if (1 < m_oWriter.m_dWidth) - { - m_pFontManager->SetCharSpacing(dPix); - } - return; - } - - m_pFontManager->SetStringGID(m_oFont.StringGID); - if (1 < m_oWriter.m_dWidth) - { - m_pFontManager->SetCharSpacing(dPix); - } - - if (m_oFont.Path.empty()) - { - m_pFontManager->LoadFontByName(m_oFont.Name, m_oFont.Size, m_oFont.GetStyle(), 96, 96); - } - else - { - m_pFontManager->LoadFontFromFile(m_oFont.Path, m_oFont.FaceIndex, m_oFont.Size, 96, 96); - } - - m_oInstalledFont = m_oFont; - } - }; - - CASCHTMLRenderer3::CASCHTMLRenderer3() - { - m_pInternal = new CASCHTMLRenderer3_Private(); - } - CASCHTMLRenderer3::~CASCHTMLRenderer3() - { - RELEASEOBJECT(m_pInternal); - } - - HRESULT CASCHTMLRenderer3::get_Type(LONG* lType) - { - *lType = c_nHtmlRendrerer2; - return S_OK; - } - - //-------- Функции для работы со страницей -------------------------------------------------- - HRESULT CASCHTMLRenderer3::NewPage() - { - if (m_pInternal->m_bPageOpened) - { - m_pInternal->EndPage(); - } - - m_pInternal->m_oPen.SetDefaultParams(); - m_pInternal->m_oBrush.SetDefaultParams(); - m_pInternal->m_oFont.SetDefaultParams(); - - m_pInternal->m_oDocument.NewPage(); - m_pInternal->m_bPageClosed = false; - m_pInternal->m_bPageOpened = true; - - m_pInternal->m_bIsMetafileDrawing = false; - m_pInternal->m_bIsTextGraphicType = false; - return S_OK; - } - HRESULT CASCHTMLRenderer3::get_Height(double* dHeight) - { - size_t nCount = m_pInternal->m_oDocument.m_arrPages.size(); - if ((nCount > 0) && (NULL != dHeight)) - *dHeight = m_pInternal->m_oDocument.m_arrPages[nCount - 1].GetHeight(); - return S_OK; - } - HRESULT CASCHTMLRenderer3::put_Height(const double& dHeight) - { - size_t nCount = m_pInternal->m_oDocument.m_arrPages.size(); - if (nCount > 0) - m_pInternal->m_oDocument.m_arrPages[nCount - 1].SetHeight(dHeight); - return S_OK; - } - HRESULT CASCHTMLRenderer3::get_Width(double* dWidth) - { - size_t nCount = m_pInternal->m_oDocument.m_arrPages.size(); - if ((nCount > 0) && (NULL != dWidth)) - *dWidth = m_pInternal->m_oDocument.m_arrPages[nCount - 1].GetWidth(); - return S_OK; - } - HRESULT CASCHTMLRenderer3::put_Width(const double& dWidth) - { - size_t nCount = m_pInternal->m_oDocument.m_arrPages.size(); - if (nCount > 0) - m_pInternal->m_oDocument.m_arrPages[nCount - 1].SetWidth(dWidth); - return S_OK; - } - HRESULT CASCHTMLRenderer3::get_DpiX(double* dDpiX) - { - *dDpiX = 96; - return S_OK; - } - HRESULT CASCHTMLRenderer3::get_DpiY(double* dDpiY) - { - *dDpiY = 96; - return S_OK; - } - - // pen -------------------------------------------------------------------------------------- - HRESULT CASCHTMLRenderer3::get_PenColor(LONG* lColor) - { - *lColor = m_pInternal->m_oPen.Color; - return S_OK; - } - HRESULT CASCHTMLRenderer3::put_PenColor(const LONG& lColor) - { - if (m_pInternal->m_bIsGraphicsDumperMode) - return m_pInternal->m_oDumper.put_PenColor(lColor); - - m_pInternal->m_oPen.Color = lColor; - return S_OK; - } - HRESULT CASCHTMLRenderer3::get_PenAlpha(LONG* lAlpha) - { - *lAlpha = m_pInternal->m_oPen.Alpha; - return S_OK; - } - HRESULT CASCHTMLRenderer3::put_PenAlpha(const LONG& lAlpha) - { - if (m_pInternal->m_bIsGraphicsDumperMode) - return m_pInternal->m_oDumper.put_PenAlpha(lAlpha); - - m_pInternal->m_oPen.Alpha = lAlpha; - return S_OK; - } - HRESULT CASCHTMLRenderer3::get_PenSize(double* dSize) - { - *dSize = m_pInternal->m_oPen.Size; - return S_OK; - } - HRESULT CASCHTMLRenderer3::put_PenSize(const double& dSize) - { - if (m_pInternal->m_bIsGraphicsDumperMode) - return m_pInternal->m_oDumper.put_PenSize(dSize); - - m_pInternal->m_oPen.Size = dSize; - return S_OK; - } - HRESULT CASCHTMLRenderer3::get_PenDashStyle(BYTE* val) - { - *val = m_pInternal->m_oPen.DashStyle; - return S_OK; - } - HRESULT CASCHTMLRenderer3::put_PenDashStyle(const BYTE& val) - { - if (m_pInternal->m_bIsGraphicsDumperMode) - return m_pInternal->m_oDumper.put_PenDashStyle(val); - - m_pInternal->m_oPen.DashStyle = val; - return S_OK; - } - HRESULT CASCHTMLRenderer3::get_PenLineStartCap(BYTE* val) - { - *val = m_pInternal->m_oPen.LineStartCap; - return S_OK; - } - HRESULT CASCHTMLRenderer3::put_PenLineStartCap(const BYTE& val) - { - if (m_pInternal->m_bIsGraphicsDumperMode) - return m_pInternal->m_oDumper.put_PenLineStartCap(val); - - m_pInternal->m_oPen.LineStartCap = val; - return S_OK; - } - HRESULT CASCHTMLRenderer3::get_PenLineEndCap(BYTE* val) - { - *val = m_pInternal->m_oPen.LineEndCap; - return S_OK; - } - HRESULT CASCHTMLRenderer3::put_PenLineEndCap(const BYTE& val) - { - if (m_pInternal->m_bIsGraphicsDumperMode) - return m_pInternal->m_oDumper.put_PenLineEndCap(val); - - m_pInternal->m_oPen.LineEndCap = val; - return S_OK; - } - HRESULT CASCHTMLRenderer3::get_PenLineJoin(BYTE* val) - { - *val = m_pInternal->m_oPen.LineJoin; - return S_OK; - } - HRESULT CASCHTMLRenderer3::put_PenLineJoin(const BYTE& val) - { - if (m_pInternal->m_bIsGraphicsDumperMode) - return m_pInternal->m_oDumper.put_PenLineJoin(val); - - m_pInternal->m_oPen.LineJoin = val; - return S_OK; - } - HRESULT CASCHTMLRenderer3::get_PenDashOffset(double* dOffset) - { - *dOffset = m_pInternal->m_oPen.DashOffset; - return S_OK; - } - HRESULT CASCHTMLRenderer3::put_PenDashOffset(const double& dOffset) - { - if (m_pInternal->m_bIsGraphicsDumperMode) - return m_pInternal->m_oDumper.put_PenDashOffset(dOffset); - - m_pInternal->m_oPen.DashOffset = dOffset; - return S_OK; - } - HRESULT CASCHTMLRenderer3::get_PenAlign(LONG* lAlign) - { - *lAlign = m_pInternal->m_oPen.Align; - return S_OK; - } - HRESULT CASCHTMLRenderer3::put_PenAlign(const LONG& lAlign) - { - if (m_pInternal->m_bIsGraphicsDumperMode) - return m_pInternal->m_oDumper.put_PenAlign(lAlign); - - m_pInternal->m_oPen.Align = lAlign; - return S_OK; - } - HRESULT CASCHTMLRenderer3::get_PenMiterLimit(double* dOffset) - { - *dOffset = m_pInternal->m_oPen.MiterLimit; - return S_OK; - } - HRESULT CASCHTMLRenderer3::put_PenMiterLimit(const double& dOffset) - { - if (m_pInternal->m_bIsGraphicsDumperMode) - return m_pInternal->m_oDumper.put_PenMiterLimit(dOffset); - - m_pInternal->m_oPen.MiterLimit = dOffset; - return S_OK; - } - HRESULT CASCHTMLRenderer3::PenDashPattern(double* pPattern, LONG lCount) - { - if (m_pInternal->m_bIsGraphicsDumperMode) - return m_pInternal->m_oDumper.PenDashPattern(pPattern, lCount); - - m_pInternal->m_oPen.SetDashPattern(pPattern, lCount); - return S_OK; - } - - // brush ------------------------------------------------------------------------------------ - HRESULT CASCHTMLRenderer3::get_BrushType(LONG* lType) - { - *lType = m_pInternal->m_oBrush.Type; - return S_OK; - } - HRESULT CASCHTMLRenderer3::put_BrushType(const LONG& lType) - { - if (m_pInternal->m_bIsGraphicsDumperMode) - return m_pInternal->m_oDumper.put_BrushType(lType); - - m_pInternal->m_oBrush.Type = lType; - return S_OK; - } - HRESULT CASCHTMLRenderer3::get_BrushColor1(LONG* lColor) - { - *lColor = m_pInternal->m_oBrush.Color1; - return S_OK; - } - HRESULT CASCHTMLRenderer3::put_BrushColor1(const LONG& lColor) - { - if (m_pInternal->m_bIsGraphicsDumperMode) - return m_pInternal->m_oDumper.put_BrushColor1(lColor); - - m_pInternal->m_oBrush.Color1 = lColor; - return S_OK; - } - HRESULT CASCHTMLRenderer3::get_BrushAlpha1(LONG* lAlpha) - { - *lAlpha = m_pInternal->m_oBrush.Alpha1; - return S_OK; - } - HRESULT CASCHTMLRenderer3::put_BrushAlpha1(const LONG& lAlpha) - { - if (m_pInternal->m_bIsGraphicsDumperMode) - return m_pInternal->m_oDumper.put_BrushAlpha1(lAlpha); - - m_pInternal->m_oBrush.Alpha1 = lAlpha; - return S_OK; - } - HRESULT CASCHTMLRenderer3::get_BrushColor2(LONG* lColor) - { - *lColor = m_pInternal->m_oBrush.Color2; - return S_OK; - } - HRESULT CASCHTMLRenderer3::put_BrushColor2(const LONG& lColor) - { - if (m_pInternal->m_bIsGraphicsDumperMode) - return m_pInternal->m_oDumper.put_BrushColor2(lColor); - - m_pInternal->m_oBrush.Color2 = lColor; - return S_OK; - } - HRESULT CASCHTMLRenderer3::get_BrushAlpha2(LONG* lAlpha) - { - *lAlpha = m_pInternal->m_oBrush.Alpha2; - return S_OK; - } - HRESULT CASCHTMLRenderer3::put_BrushAlpha2(const LONG& lAlpha) - { - if (m_pInternal->m_bIsGraphicsDumperMode) - return m_pInternal->m_oDumper.put_BrushAlpha2(lAlpha); - - m_pInternal->m_oBrush.Alpha2 = lAlpha; - return S_OK; - } - HRESULT CASCHTMLRenderer3::get_BrushTexturePath(std::wstring* bsPath) - { - *bsPath = m_pInternal->m_oBrush.TexturePath; - return S_OK; - } - HRESULT CASCHTMLRenderer3::put_BrushTexturePath(const std::wstring& bsPath) - { - if (m_pInternal->m_bIsGraphicsDumperMode) - return m_pInternal->m_oDumper.put_BrushTexturePath(bsPath); - - m_pInternal->m_oBrush.TexturePath = bsPath; - return S_OK; - } - HRESULT CASCHTMLRenderer3::get_BrushTextureMode(LONG* lMode) - { - *lMode = m_pInternal->m_oBrush.TextureMode; - return S_OK; - } - HRESULT CASCHTMLRenderer3::put_BrushTextureMode(const LONG& lMode) - { - if (m_pInternal->m_bIsGraphicsDumperMode) - return m_pInternal->m_oDumper.put_BrushTextureMode(lMode); - - m_pInternal->m_oBrush.TextureMode = lMode; - return S_OK; - } - HRESULT CASCHTMLRenderer3::get_BrushTextureAlpha(LONG* lTxAlpha) - { - *lTxAlpha = m_pInternal->m_oBrush.TextureAlpha; - return S_OK; - } - HRESULT CASCHTMLRenderer3::put_BrushTextureAlpha(const LONG& lTxAlpha) - { - if (m_pInternal->m_bIsGraphicsDumperMode) - return m_pInternal->m_oDumper.put_BrushTextureAlpha(lTxAlpha); - - m_pInternal->m_oBrush.TextureAlpha = lTxAlpha; - return S_OK; - } - HRESULT CASCHTMLRenderer3::get_BrushLinearAngle(double* dAngle) - { - *dAngle = m_pInternal->m_oBrush.LinearAngle; - return S_OK; - } - HRESULT CASCHTMLRenderer3::put_BrushLinearAngle(const double& dAngle) - { - if (m_pInternal->m_bIsGraphicsDumperMode) - return m_pInternal->m_oDumper.put_BrushLinearAngle(dAngle); - - m_pInternal->m_oBrush.LinearAngle = dAngle; - return S_OK; - } - HRESULT CASCHTMLRenderer3::BrushRect(const INT& val, const double& left, const double& top, const double& width, const double& height) - { - if (m_pInternal->m_bIsGraphicsDumperMode) - return m_pInternal->m_oDumper.BrushRect(val, left, top, width, height); - - m_pInternal->m_oBrush.Rectable = val; - m_pInternal->m_oBrush.Rect.X = (float)left; - m_pInternal->m_oBrush.Rect.Y = (float)top; - m_pInternal->m_oBrush.Rect.Width = (float)width; - m_pInternal->m_oBrush.Rect.Height = (float)height; - return S_OK; - } - HRESULT CASCHTMLRenderer3::BrushBounds(const double& left, const double& top, const double& width, const double& height) - { - if (m_pInternal->m_bIsGraphicsDumperMode) - return m_pInternal->m_oDumper.BrushBounds(left, top, width, height); - - m_pInternal->m_oBrush.Bounds.left = left; - m_pInternal->m_oBrush.Bounds.top = top; - m_pInternal->m_oBrush.Bounds.right = left + width; - m_pInternal->m_oBrush.Bounds.bottom = top + height; - return S_OK; - } - HRESULT CASCHTMLRenderer3::put_BrushGradientColors(LONG* lColors, double* pPositions, LONG nCount) - { - if (m_pInternal->m_bIsGraphicsDumperMode) - return m_pInternal->m_oDumper.put_BrushGradientColors(lColors, pPositions, nCount); - - m_pInternal->m_oBrush.m_arrSubColors.clear(); - for (LONG i = 0; i < nCount; ++i) - { - NSStructures::CBrush::TSubColor color; - color.color = lColors[i]; - color.position = (long)(pPositions[i] * 65536); - m_pInternal->m_oBrush.m_arrSubColors.push_back(color); - } - return S_OK; - } - - HRESULT CASCHTMLRenderer3::get_BrushTextureImage(Aggplus::CImage** pImage) { return S_OK; } - HRESULT CASCHTMLRenderer3::put_BrushTextureImage(Aggplus::CImage* pImage) { return S_OK; } - HRESULT CASCHTMLRenderer3::get_BrushTransform(Aggplus::CMatrix& oMatrix) { return S_OK; } - HRESULT CASCHTMLRenderer3::put_BrushTransform(const Aggplus::CMatrix& oMatrix) { return S_OK; } - - // font ------------------------------------------------------------------------------------- - HRESULT CASCHTMLRenderer3::get_FontName(std::wstring* bsName) - { - *bsName = m_pInternal->m_oFont.Name; - return S_OK; - } - HRESULT CASCHTMLRenderer3::put_FontName(const std::wstring& bsName) - { - if (m_pInternal->m_bIsGraphicsDumperMode) - return m_pInternal->m_oDumper.put_FontName(bsName); - - m_pInternal->m_oFont.Name = bsName; - m_pInternal->m_bIsChangedFontParamBetweenDrawText = true; - return S_OK; - } - HRESULT CASCHTMLRenderer3::get_FontPath(std::wstring* bsName) - { - *bsName = m_pInternal->m_oFont.Path; - return S_OK; - } - HRESULT CASCHTMLRenderer3::put_FontPath(const std::wstring& bsName) - { - if (m_pInternal->m_bIsGraphicsDumperMode) - return m_pInternal->m_oDumper.put_FontPath(bsName); - - m_pInternal->m_oFont.Path = bsName; - m_pInternal->m_bIsChangedFontParamBetweenDrawText = true; - return S_OK; - } - HRESULT CASCHTMLRenderer3::get_FontSize(double* dSize) - { - *dSize = m_pInternal->m_oFont.Size; - return S_OK; - } - HRESULT CASCHTMLRenderer3::put_FontSize(const double& dSize) - { - if (m_pInternal->m_bIsGraphicsDumperMode) - return m_pInternal->m_oDumper.put_FontSize(dSize); - - if (m_pInternal->m_oFont.Size != dSize) - { - m_pInternal->m_oFont.Size = dSize; - m_pInternal->m_bIsChangedFontParamBetweenDrawText = true; - } - return S_OK; - } - HRESULT CASCHTMLRenderer3::get_FontStyle(LONG* lStyle) - { - *lStyle = m_pInternal->m_oFont.GetStyle(); - return S_OK; - } - HRESULT CASCHTMLRenderer3::put_FontStyle(const LONG& lStyle) - { - if (m_pInternal->m_bIsGraphicsDumperMode) - return m_pInternal->m_oDumper.put_FontStyle(lStyle); - - LONG lOld = m_pInternal->m_oFont.GetStyle(); - if (lOld != lStyle) - { - m_pInternal->m_oFont.SetStyle(lStyle); - m_pInternal->m_bIsChangedFontParamBetweenDrawText = true; - } - return S_OK; - } - HRESULT CASCHTMLRenderer3::get_FontStringGID(INT* bGID) - { - *bGID = m_pInternal->m_oFont.StringGID; - return S_OK; - } - HRESULT CASCHTMLRenderer3::put_FontStringGID(const INT& bGID) - { - if (m_pInternal->m_bIsGraphicsDumperMode) - return m_pInternal->m_oDumper.put_FontStringGID(bGID); - - m_pInternal->m_oFont.StringGID = bGID; - m_pInternal->m_pFontManager->SetStringGID(bGID); - return S_OK; - } - HRESULT CASCHTMLRenderer3::get_FontCharSpace(double* dSpace) - { - *dSpace = m_pInternal->m_oFont.CharSpace; - return S_OK; - } - HRESULT CASCHTMLRenderer3::put_FontCharSpace(const double& dSpace) - { - if (m_pInternal->m_bIsGraphicsDumperMode) - return m_pInternal->m_oDumper.put_FontCharSpace(dSpace); - - m_pInternal->m_oFont.CharSpace = dSpace; - return S_OK; - } - HRESULT CASCHTMLRenderer3::get_FontFaceIndex(int* lFaceIndex) - { - *lFaceIndex = m_pInternal->m_oFont.FaceIndex; - return S_OK; - } - HRESULT CASCHTMLRenderer3::put_FontFaceIndex(const int& lFaceIndex) - { - if (m_pInternal->m_bIsGraphicsDumperMode) - return m_pInternal->m_oDumper.put_FontFaceIndex(lFaceIndex); - - m_pInternal->m_oFont.FaceIndex = lFaceIndex; - return S_OK; - } - - //-------- Функции для вывода текста -------------------------------------------------------- - HRESULT CASCHTMLRenderer3::CommandDrawTextCHAR(const LONG& c, const double& x, const double& y, const double& w, const double& h) - { - if (m_pInternal->m_bIsGraphicsDumperMode) - return m_pInternal->m_oDumper.CommandDrawTextCHAR(c, x, y, w, h); - - if (c_nHyperlinkType == m_pInternal->m_lCurrentCommandType) - return S_OK; - - int _c = (int)c; - m_pInternal->m_oWriter.WriteText(&_c, NULL, 1, x, y, w, h, m_pInternal->m_bIsChangedFontParamBetweenDrawText); - m_pInternal->m_bIsChangedFontParamBetweenDrawText = false; - return S_OK; - } - HRESULT CASCHTMLRenderer3::CommandDrawText(const std::wstring& bsText, const double& x, const double& y, const double& w, const double& h) - { - if (m_pInternal->m_bIsGraphicsDumperMode) - return m_pInternal->m_oDumper.CommandDrawText(bsText, x, y, w, h); - - if (c_nHyperlinkType == m_pInternal->m_lCurrentCommandType) - return S_OK; - - m_pInternal->GetUnicodes(bsText); - m_pInternal->m_oWriter.WriteText(m_pInternal->m_pTempUnicodes, NULL, m_pInternal->m_nTempUnicodesLen, - x, y, w, h, m_pInternal->m_bIsChangedFontParamBetweenDrawText); - m_pInternal->m_bIsChangedFontParamBetweenDrawText = false; - return S_OK; - } - HRESULT CASCHTMLRenderer3::CommandDrawTextExCHAR(const LONG& c, const LONG& gid, const double& x, const double& y, const double& w, const double& h) - { - if (m_pInternal->m_bIsGraphicsDumperMode) - return m_pInternal->m_oDumper.CommandDrawTextExCHAR(c, gid, x, y, w, h); - - if (c_nHyperlinkType == m_pInternal->m_lCurrentCommandType) - return S_OK; - - int _c = (int)c; - int _g = (int)gid; - - m_pInternal->m_oWriter.WriteText(&_c, &_g, 1, - x, y, w, h, m_pInternal->m_bIsChangedFontParamBetweenDrawText); - m_pInternal->m_bIsChangedFontParamBetweenDrawText = false; - return S_OK; - } - HRESULT CASCHTMLRenderer3::CommandDrawTextEx(const std::wstring& bsUnicodeText, const unsigned int* pGids, const unsigned int nGidsCount, const double& x, const double& y, const double& w, const double& h) - { - if (m_pInternal->m_bIsGraphicsDumperMode) - return m_pInternal->m_oDumper.CommandDrawText(bsUnicodeText, x, y, w, h); - - if (c_nHyperlinkType == m_pInternal->m_lCurrentCommandType) - return S_OK; - - m_pInternal->GetUnicodes(bsUnicodeText); - m_pInternal->m_oWriter.WriteText(m_pInternal->m_pTempUnicodes, (const int*)pGids, m_pInternal->m_nTempUnicodesLen, - x, y, w, h, m_pInternal->m_bIsChangedFontParamBetweenDrawText); - m_pInternal->m_bIsChangedFontParamBetweenDrawText = false; - return S_OK; - } - - //-------- Маркеры для команд --------------------------------------------------------------- - HRESULT CASCHTMLRenderer3::BeginCommand(const DWORD& lType) - { - if (m_pInternal->m_bIsOnlyTextMode) - { - m_pInternal->m_lCurrentCommandType = lType; - return S_OK; - } - - if (m_pInternal->m_bIsGraphicsDumperMode && lType != c_nPDFTilingFill) - return m_pInternal->m_oDumper.BeginCommand(lType); - - if (c_nClipType == lType) - { - m_pInternal->m_oWriter.WritePathClip(); - } - else if (c_nPathType == lType) - { - m_pInternal->m_oWriter.WriteBeginPath(); - m_pInternal->m_oSimpleGraphicsConverter.PathCommandEnd(); - } - else if (c_nImageType == lType) - { - m_pInternal->m_bIsMetafileDrawing = true; - } - else if (c_nTextGraphicType == lType) - { - m_pInternal->m_bIsTextGraphicType = true; - } - else if (c_nPDFTilingFill == lType) - { - m_pInternal->m_oWriter.m_lTilingCounter++; - } - m_pInternal->m_lCurrentCommandType = lType; - - return S_OK; - } - HRESULT CASCHTMLRenderer3::EndCommand(const DWORD& lType) - { - if (m_pInternal->m_bIsOnlyTextMode) - { - if (c_nPageType == lType && !m_pInternal->m_bDisablePageEnd) - { - m_pInternal->EndPage(); - } - m_pInternal->m_lCurrentCommandType = -1; - return S_OK; - } - - if (m_pInternal->m_bIsGraphicsDumperMode && lType != c_nPDFTilingFill) - return m_pInternal->m_oDumper.EndCommand(lType); - - if (c_nPageType == lType && !m_pInternal->m_bDisablePageEnd) - { - m_pInternal->EndPage(); - } - else if (c_nClipType == lType) - { - m_pInternal->m_oWriter.WritePathClipEnd(); - } - else if (c_nResetClipType == lType) - { - m_pInternal->m_oWriter.WritePathResetClip(); - } - //else if (c_nPathType == lType) - //{ - // PathCommandEnd(); - //} - else if (c_nImageType == lType) - { - m_pInternal->m_bIsMetafileDrawing = false; - } - else if (c_nTextGraphicType == lType) - { - m_pInternal->m_bIsTextGraphicType = false; - } - else if (c_nPDFTilingFill == lType) - { - m_pInternal->m_oWriter.m_lTilingCounter--; - - if (0 == m_pInternal->m_oWriter.m_lTilingCounter) - { - m_pInternal->m_bIsGraphicsDumperMode = false; - - // dump Graphics - CBgraFrame* pFrame = m_pInternal->m_oDumper.ConvertVectorGraphics(); - m_pInternal->m_oWriter.WritePattern(pFrame, m_pInternal->m_oDumper.m_oTile); - RELEASEOBJECT(pFrame); - } - } - //else if (c_nParagraphType == lType) - //{ - // m_oWriter.m_oPage.m_oText.EndParagraph(); - //} - m_pInternal->m_lCurrentCommandType = -1; - - return S_OK; - } - - //-------- Функции для работы с Graphics Path ----------------------------------------------- - HRESULT CASCHTMLRenderer3::PathCommandMoveTo(const double& x, const double& y) - { - if (m_pInternal->m_bIsOnlyTextMode) - return S_OK; - - if (m_pInternal->m_bIsGraphicsDumperMode) - return m_pInternal->m_oDumper.PathCommandMoveTo(x, y); - - if (c_nSimpleGraphicType == m_pInternal->m_lCurrentCommandType) - { - m_pInternal->MoveTo(x, y); - } - else - { - m_pInternal->m_oSimpleGraphicsConverter.PathCommandMoveTo(x, y); - } - - return S_OK; - } - HRESULT CASCHTMLRenderer3::PathCommandLineTo(const double& x, const double& y) - { - if (m_pInternal->m_bIsOnlyTextMode) - return S_OK; - - if (m_pInternal->m_bIsGraphicsDumperMode) - return m_pInternal->m_oDumper.PathCommandLineTo(x, y); - - if (c_nSimpleGraphicType == m_pInternal->m_lCurrentCommandType) - { - m_pInternal->LineTo(x, y); - } - else - { - m_pInternal->m_oSimpleGraphicsConverter.PathCommandLineTo(x, y); - } - - return S_OK; - } - HRESULT CASCHTMLRenderer3::PathCommandLinesTo(double* points, const int& count) - { - if (m_pInternal->m_bIsOnlyTextMode) - return S_OK; - - if (m_pInternal->m_bIsGraphicsDumperMode) - return m_pInternal->m_oDumper.PathCommandLinesTo(points, count); - - m_pInternal->m_oSimpleGraphicsConverter.PathCommandLinesTo(points, count); - return S_OK; - } - HRESULT CASCHTMLRenderer3::PathCommandCurveTo(const double& x1, const double& y1, const double& x2, const double& y2, const double& x3, const double& y3) - { - if (m_pInternal->m_bIsOnlyTextMode) - return S_OK; - - if (m_pInternal->m_bIsGraphicsDumperMode) - return m_pInternal->m_oDumper.PathCommandCurveTo(x1, y1, x2, y2, x3, y3); - - if (c_nSimpleGraphicType == m_pInternal->m_lCurrentCommandType) - { - m_pInternal->CurveTo(x1, y1, x2, y2, x3, y3); - } - else - { - m_pInternal->m_oSimpleGraphicsConverter.PathCommandCurveTo(x1, y1, x2, y2, x3, y3); - } - - return S_OK; - } - HRESULT CASCHTMLRenderer3::PathCommandCurvesTo(double* points, const int& count) - { - if (m_pInternal->m_bIsOnlyTextMode) - return S_OK; - - if (m_pInternal->m_bIsGraphicsDumperMode) - return m_pInternal->m_oDumper.PathCommandCurvesTo(points, count); - - m_pInternal->m_oSimpleGraphicsConverter.PathCommandCurvesTo(points, count); - return S_OK; - } - HRESULT CASCHTMLRenderer3::PathCommandArcTo(const double& x, const double& y, const double& w, const double& h, const double& startAngle, const double& sweepAngle) - { - if (m_pInternal->m_bIsOnlyTextMode) - return S_OK; - - if (m_pInternal->m_bIsGraphicsDumperMode) - return m_pInternal->m_oDumper.PathCommandArcTo(x, y, w, h, startAngle, sweepAngle); - - m_pInternal->m_oSimpleGraphicsConverter.PathCommandArcTo(x, y, w, h, startAngle, sweepAngle); - return S_OK; - } - HRESULT CASCHTMLRenderer3::PathCommandClose() - { - if (m_pInternal->m_bIsOnlyTextMode) - return S_OK; - - if (m_pInternal->m_bIsGraphicsDumperMode) - return m_pInternal->m_oDumper.PathCommandClose(); - - if (c_nSimpleGraphicType == m_pInternal->m_lCurrentCommandType) - { - m_pInternal->Close(); - } - else - { - m_pInternal->m_oSimpleGraphicsConverter.PathCommandClose(); - } - - return S_OK; - } - HRESULT CASCHTMLRenderer3::PathCommandEnd() - { - if (m_pInternal->m_bIsOnlyTextMode) - return S_OK; - - if (m_pInternal->m_bIsGraphicsDumperMode) - return m_pInternal->m_oDumper.PathCommandEnd(); - - if (c_nSimpleGraphicType == m_pInternal->m_lCurrentCommandType) - { - m_pInternal->End(); - } - else - { - m_pInternal->m_oSimpleGraphicsConverter.PathCommandEnd(); - } - - return S_OK; - } - HRESULT CASCHTMLRenderer3::DrawPath(const LONG& nType) - { - if (m_pInternal->m_bIsOnlyTextMode) - return S_OK; - - if (m_pInternal->m_bIsGraphicsDumperMode) - return m_pInternal->m_oDumper.DrawPath(nType); - - m_pInternal->m_oWriter.WriteDrawPath(nType); - return S_OK; - } - HRESULT CASCHTMLRenderer3::PathCommandStart() - { - if (m_pInternal->m_bIsOnlyTextMode) - return S_OK; - - if (m_pInternal->m_bIsGraphicsDumperMode) - return m_pInternal->m_oDumper.PathCommandStart(); - - if (c_nSimpleGraphicType == m_pInternal->m_lCurrentCommandType) - { - m_pInternal->Start(); - } - else - { - m_pInternal->m_oSimpleGraphicsConverter.PathCommandEnd(); - m_pInternal->m_oSimpleGraphicsConverter.PathCommandStart(); - } - - return S_OK; - } - HRESULT CASCHTMLRenderer3::PathCommandGetCurrentPoint(double* x, double* y) - { - if (m_pInternal->m_bIsOnlyTextMode) - return S_OK; - - m_pInternal->m_oSimpleGraphicsConverter.PathCommandGetCurrentPoint(x, y); - return S_OK; - } - HRESULT CASCHTMLRenderer3::PathCommandTextCHAR(const LONG& c, const double& x, const double& y, const double& w, const double& h) - { - if (m_pInternal->m_bIsOnlyTextMode) - return S_OK; - - if (m_pInternal->m_bIsGraphicsDumperMode) - return m_pInternal->m_oDumper.PathCommandTextCHAR(c, x, y, w, h); - - int _c = (int)c; - - m_pInternal->_SetFont(); - m_pInternal->m_oSimpleGraphicsConverter.PathCommandText2(&_c, NULL, 1, m_pInternal->m_pFontManager, x, y, w, h); - return S_OK; - } - HRESULT CASCHTMLRenderer3::PathCommandText(const std::wstring& bsText, const double& x, const double& y, const double& w, const double& h) - { - if (m_pInternal->m_bIsOnlyTextMode) - return S_OK; - - if (m_pInternal->m_bIsGraphicsDumperMode) - return m_pInternal->m_oDumper.PathCommandText(bsText, x, y, w, h); - - m_pInternal->GetUnicodes(bsText); - - m_pInternal->_SetFont(); - m_pInternal->m_oSimpleGraphicsConverter.PathCommandText2(m_pInternal->m_pTempUnicodes, NULL, m_pInternal->m_nTempUnicodesLen, - m_pInternal->m_pFontManager, x, y, w, h); - return S_OK; - } - HRESULT CASCHTMLRenderer3::PathCommandTextExCHAR(const LONG& c, const LONG& gid, const double& x, const double& y, const double& w, const double& h) - { - if (m_pInternal->m_bIsOnlyTextMode) - return S_OK; - - if (m_pInternal->m_bIsGraphicsDumperMode) - return m_pInternal->m_oDumper.PathCommandTextExCHAR(c, gid, x, y, w, h); - - int _c = (int)c; - int _g = (int)gid; - - m_pInternal->_SetFont(); - m_pInternal->m_oSimpleGraphicsConverter.PathCommandText2(&_c, &_g, 1, - m_pInternal->m_pFontManager, x, y, w, h); - return S_OK; - } - HRESULT CASCHTMLRenderer3::PathCommandTextEx(const std::wstring& bsUnicodeText, const unsigned int* pGids, const unsigned int nGidsCount, const double& x, const double& y, const double& w, const double& h) - { - if (m_pInternal->m_bIsOnlyTextMode) - return S_OK; - - if (m_pInternal->m_bIsGraphicsDumperMode) - return m_pInternal->m_oDumper.PathCommandTextEx(bsUnicodeText, pGids, nGidsCount, x, y, w, h); - - m_pInternal->_SetFont(); - m_pInternal->m_oSimpleGraphicsConverter.PathCommandText2(NULL, (const int*)pGids, nGidsCount, - m_pInternal->m_pFontManager, x, y, w, h); - return S_OK; - } - - //-------- Функции для вывода изображений --------------------------------------------------- - HRESULT CASCHTMLRenderer3::DrawImage(IGrObject* pImage, const double& x, const double& y, const double& w, const double& h) - { - if (m_pInternal->m_bIsOnlyTextMode) - return S_OK; - - if (m_pInternal->m_bIsGraphicsDumperMode) - return m_pInternal->m_oDumper.DrawImage(pImage, x, y, w, h); - - if (NULL == pImage) - return S_OK; - - m_pInternal->m_oWriter.WriteImage(pImage, x, y, w, h); - return S_OK; - } - - HRESULT CASCHTMLRenderer3::DrawImageFromFile(const std::wstring& sPath, const double& x, const double& y, const double& w, const double& h, const BYTE& lAlpha) - { - if (m_pInternal->m_bIsOnlyTextMode) - return S_OK; - - if (m_pInternal->m_bIsGraphicsDumperMode) - return m_pInternal->m_oDumper.DrawImageFromFile(sPath, x, y, w, h, lAlpha); - - m_pInternal->m_oWriter.WriteImage(sPath, x, y, w, h); - return S_OK; - } - - // transform -------------------------------------------------------------------------------- - HRESULT CASCHTMLRenderer3::SetTransform(const double& m1, const double& m2, const double& m3, const double& m4, const double& m5, const double& m6) - { - if (m_pInternal->m_bIsGraphicsDumperMode) - return m_pInternal->m_oDumper.SetTransform(m1, m2, m3, m4, m5, m6); - - m_pInternal->m_oTransform.SetElements(m1, m2, m3, m4, m5, m6); - return S_OK; - } - HRESULT CASCHTMLRenderer3::GetTransform(double *pdA, double *pdB, double *pdC, double *pdD, double *pdE, double *pdF) - { - *pdA = m_pInternal->m_oTransform.sx(); - *pdB = m_pInternal->m_oTransform.shy(); - *pdC = m_pInternal->m_oTransform.shx(); - *pdD = m_pInternal->m_oTransform.sy(); - *pdE = m_pInternal->m_oTransform.tx(); - *pdF = m_pInternal->m_oTransform.ty(); - return S_OK; - } - HRESULT CASCHTMLRenderer3::ResetTransform() - { - if (m_pInternal->m_bIsGraphicsDumperMode) - return m_pInternal->m_oDumper.ResetTransform(); - - m_pInternal->m_oTransform.Reset(); - return S_OK; - } - - // ----------------------------------------------------------------------------------------- - HRESULT CASCHTMLRenderer3::get_ClipMode(LONG* plMode) - { - *plMode = m_pInternal->m_lClipMode; - return S_OK; - } - HRESULT CASCHTMLRenderer3::put_ClipMode(const LONG& lMode) - { - if (m_pInternal->m_bIsGraphicsDumperMode) - return m_pInternal->m_oDumper.put_ClipMode(lMode); - - m_pInternal->m_lClipMode = lMode; - m_pInternal->m_oWriter.m_oSVGWriter.m_lClipMode = lMode; - return S_OK; - } - - // additiaonal params ---------------------------------------------------------------------- - HRESULT CASCHTMLRenderer3::CommandLong(const LONG& lType, const LONG& lCommand) - { - if (c_nCommandLongTypeOnlyText == lType) - { - return GetOnlyTextMode() ? S_OK : S_FALSE; - } - return S_OK; - } - HRESULT CASCHTMLRenderer3::CommandDouble(const LONG& lType, const double& dCommand) - { - return S_OK; - } - HRESULT CASCHTMLRenderer3::CommandString(const LONG& lType, const std::wstring& sCommand) - { - return S_OK; - } - - HRESULT CASCHTMLRenderer3::StartConvertCoordsToIdentity() - { - m_bUseTransformCoordsToIdentity = true; - if (m_pInternal->m_bIsGraphicsDumperMode) - return m_pInternal->m_oDumper.StartConvertCoordsToIdentity(); - return S_OK; - } - HRESULT CASCHTMLRenderer3::EndConvertCoordsToIdentity() - { - m_bUseTransformCoordsToIdentity = false; - if (m_pInternal->m_bIsGraphicsDumperMode) - return m_pInternal->m_oDumper.EndConvertCoordsToIdentity(); - return S_OK; - } - - // owner params ---------------------------------------------------------------------- - HRESULT CASCHTMLRenderer3::get_Mode(LONG *plMode) - { - return S_OK; - } - HRESULT CASCHTMLRenderer3::put_Mode(LONG lMode) - { - return S_OK; - } - - HRESULT CASCHTMLRenderer3::CreateOfficeFile(std::wstring bsFileName, const std::wstring& fontsDir) - { - if (fontsDir.empty()) - m_pInternal->m_pApplicationFonts->Initialize(); - else - m_pInternal->m_pApplicationFonts->InitializeFromFolder(fontsDir); - - m_pInternal->m_strDstFile = bsFileName; - - size_t pos1 = m_pInternal->m_strDstFile.find_last_of(wchar_t('/')); - size_t pos2 = m_pInternal->m_strDstFile.find_last_of(wchar_t('\\')); - - size_t pos = std::wstring::npos; - if (pos1 != std::wstring::npos) - pos = pos1; - - if (pos2 != std::wstring::npos) - { - if (pos == std::wstring::npos) - pos = pos2; - else if (pos2 > pos) - pos = pos2; - } - - if (pos == std::wstring::npos) - return S_FALSE; - - std::wstring strDir = m_pInternal->m_strDstFile.substr(0, pos); - - size_t nIndexExt = m_pInternal->m_strDstFile.find_last_of(wchar_t('.')); - if (nIndexExt == std::wstring::npos || nIndexExt <= pos) - nIndexExt = pos; - - std::wstring strName = m_pInternal->m_strDstFile.substr(pos + 1, nIndexExt - pos - 1); - - m_pInternal->m_oWriter.m_pTransform = &m_pInternal->m_oTransform; - m_pInternal->m_oWriter.CreateFile(strDir, strName); - m_pInternal->m_oWriter.WriteStartDocument(); - - m_pInternal->m_oWriter.m_oSmartText.m_oFontManager.Init(m_pInternal->m_pApplicationFonts); - - m_pInternal->m_lCurrentPage = -1; - m_pInternal->m_bPageOpened = false; - - m_pInternal->m_pFontManager = m_pInternal->m_pApplicationFonts->GenerateFontManager(); - NSFonts::IFontsCache* pGraphicsFontCache = NSFonts::NSFontCache::Create(); - pGraphicsFontCache->SetStreams(m_pInternal->m_pApplicationFonts->GetStreams()); - pGraphicsFontCache->SetCacheSize(16); - m_pInternal->m_pFontManager->SetOwnerCache(pGraphicsFontCache); - - m_pInternal->m_oFont.SetDefaultParams(); - m_pInternal->m_oInstalledFont.SetDefaultParams(); - - m_pInternal->m_oSimpleGraphicsConverter.SetRenderer(this); - return S_OK; - } - HRESULT CASCHTMLRenderer3::CloseFile(bool bIsNoBase64) - { - if (m_pInternal->m_bPageOpened) - { - m_pInternal->EndPage(); - } - - m_pInternal->m_oWriter.WriteEndDocument(m_pInternal->m_oDocument, bIsNoBase64); - return S_OK; - } - - HRESULT CASCHTMLRenderer3::SetAdditionalParam(std::string sParamName, int nValue) - { - if ("SourceType" == sParamName) - { - m_pInternal->m_oWriter.m_lSrcFileType = nValue; - return S_OK; - } - return S_OK; - } - HRESULT CASCHTMLRenderer3::SetAdditionalParam(std::string sParamName, const std::wstring& sParam) - { - if ("DisablePageEnd" == sParamName) - { - m_pInternal->m_bDisablePageEnd = L"yes" == sParam; - } - - if (m_pInternal->m_bIsOnlyTextMode) - return S_OK; - - if ("TilingHtmlPattern" == sParamName) - { - if (1 == m_pInternal->m_oWriter.m_lTilingCounter) - { - m_pInternal->m_bIsGraphicsDumperMode = true; - m_pInternal->m_oDumper.m_oTile.LoadFromXml(sParam); - - m_pInternal->m_oDumper.NewPage(m_pInternal->m_oWriter.m_dWidth, m_pInternal->m_oWriter.m_dHeight); - - m_pInternal->m_oDumper.m_oTile.bbox_x = 0; - m_pInternal->m_oDumper.m_oTile.bbox_y = 0; - m_pInternal->m_oDumper.m_oTile.bbox_r = m_pInternal->m_oDumper.m_lWidthPix - 1; - m_pInternal->m_oDumper.m_oTile.bbox_b = m_pInternal->m_oDumper.m_lHeightPix - 1; - - m_pInternal->m_oDumper.m_oBounds.left = 0; - m_pInternal->m_oDumper.m_oBounds.top = 0; - m_pInternal->m_oDumper.m_oBounds.right = m_pInternal->m_oDumper.m_lWidthPix - 1; - m_pInternal->m_oDumper.m_oBounds.bottom = m_pInternal->m_oDumper.m_lHeightPix - 1; - } - } - return S_OK; - } - - bool CASCHTMLRenderer3::GetOnlyTextMode() - { - return m_pInternal->m_bIsOnlyTextMode; - } - - void CASCHTMLRenderer3::SetOnlyTextMode(const bool& enabled) - { - m_pInternal->m_oWriter.m_bIsOnlyTextMode = enabled; - m_pInternal->m_bIsOnlyTextMode = enabled; - } - - void CASCHTMLRenderer3::GetLastPageInfo(int& paragraphs, int& words, int& symbols, int& spaces, std::string& sBase64Data) - { - m_pInternal->m_oWriter.GetLastPageInfo(paragraphs, words, symbols, spaces, sBase64Data); - } -} diff --git a/HtmlRenderer/src/Meta.h b/HtmlRenderer/src/Meta.h deleted file mode 100644 index f4dc0fce5d4..00000000000 --- a/HtmlRenderer/src/Meta.h +++ /dev/null @@ -1,492 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2023 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _ASC_HTMLRENDERER_META_H_ -#define _ASC_HTMLRENDERER_META_H_ - -#include "../../DesktopEditor/common/Types.h" -#include "../../DesktopEditor/graphics/Matrix.h" -#include - -namespace NSHtmlRenderer -{ - inline bool IsEqualMain(const Aggplus::CMatrix* pMatrix, const Aggplus::CMatrix* pMatrix2) - { - return Aggplus::CMatrix::IsEqual(pMatrix, pMatrix2, 0.001, true); - } - - class CMetafile - { - public: - enum CommandType - { - // pen - 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, - ctBrushAngle = 30, - ctBrushSubColors = 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, - - ctCommandTextLine = 160, - ctCommandTextTransform = 161, - ctCommandTextLineEnd = 162, - - ctCommandTextClipRectReset = 163, - ctCommandTextClipRect = 164, - - ctError = 255 - }; - - private: - - // сам метафайл - BYTE* m_pBuffer; - BYTE* m_pBufferMem; - - size_t m_lPosition; - size_t m_lSize; - - LONG m_lSizeofDouble; - LONG m_lSizeofFloat; - LONG m_lSizeofLONG; - LONG m_lSizeofBYTE; - - public: - double m_fWidth; - double m_fHeight; - - public: - CMetafile() - { - Clear(); - - m_lSizeofDouble = sizeof(double); - m_lSizeofFloat = sizeof(float); - m_lSizeofLONG = sizeof(int); - m_lSizeofBYTE = sizeof(BYTE); - } - ~CMetafile() - { - RELEASEARRAYOBJECTS(m_pBuffer); - } - - public: - template - inline void write_value(const T& value) - { -#if 0 - printf("write (%d): %d, %d\n", sizeof(T), (int)value, (int)m_lPosition); -#endif - //*((T*)(m_pBuffer + m_lPosition)) = value; - memcpy(m_pBuffer + m_lPosition, &value, sizeof(T)); - m_lPosition += sizeof(T); - } - - public: - inline LONG GetPosition() - { - return (LONG)m_lPosition; - } - inline BYTE* GetData() - { - return m_pBuffer; - } - inline void ClearNoAttack() - { - m_lPosition = 0; - m_pBufferMem = m_pBuffer; - } - - inline void Clear() - { - m_lSize = 0; - m_lPosition = 0; - - m_pBuffer = NULL; - m_pBufferMem = NULL; - } - inline void Seek(LONG lPos) - { - m_lPosition = (size_t)lPos; - m_pBufferMem = m_pBuffer + m_lPosition; - } - - inline void CheckBufferSize(size_t lPlus) - { - if (NULL != m_pBuffer) - { - size_t nNewSize = m_lPosition + lPlus; - - if (nNewSize >= m_lSize) - { - while (nNewSize >= m_lSize) - { - m_lSize *= 2; - } - - BYTE* pNew = new BYTE[m_lSize]; - memcpy(pNew, m_pBuffer, m_lPosition); - - RELEASEARRAYOBJECTS(m_pBuffer); - m_pBuffer = pNew; - } - } - else - { - m_lSize = 1000; - m_pBuffer = new BYTE[m_lSize]; - - CheckBufferSize(lPlus); - } - } - - inline void WriteCommandType(const CommandType& eType) - { - CheckBufferSize(m_lSizeofBYTE); - - *(m_pBuffer + m_lPosition) = (BYTE)eType; - m_lPosition += m_lSizeofBYTE; - } - - // - inline void WriteBYTE_nocheck(const BYTE& lValue) - { - *(m_pBuffer + m_lPosition) = lValue; - m_lPosition += m_lSizeofBYTE; - } - inline void WriteLONG_nocheck(const int& lValue) - { - write_value(lValue); - } - inline void WriteUSHORT_nocheck(const USHORT& lValue) - { - write_value(lValue); - } - inline void WriteWCHAR_nocheck(const WCHAR& lValue) - { - write_value(lValue); - } - inline void WriteWCHAR_nocheck2(const int& lValue) - { - if (lValue < 0x10000) - { - write_value((USHORT)lValue); - } - else - { - int code = lValue - 0x10000; - write_value((USHORT)(0xD800 | ((code >> 10) & 0x03FF))); - write_value((USHORT)(0xDC00 | (code & 0x03FF))); - } - } - inline void WriteDouble_nocheck(const double& dValue) - { - // здесь никаких даблов. Сплошные округления - LONG lValue = (LONG)(dValue * 10000); - WriteLONG_nocheck(lValue); - } - inline void WriteDouble2_nocheck(const double& dValue) - { - write_value((SHORT)(dValue * 100)); - } - // - inline void WriteBYTE(const BYTE& lValue) - { - CheckBufferSize(m_lSizeofBYTE); - - m_pBuffer[m_lPosition] = lValue; - m_lPosition += m_lSizeofBYTE; - } - inline void WriteLONG(const int& lValue) - { - CheckBufferSize(m_lSizeofLONG); - write_value(lValue); - } - inline void WriteUSHORT(const USHORT& lValue) - { - CheckBufferSize(sizeof(USHORT)); - write_value(lValue); - - } - inline void WriteWCHAR(const WCHAR& lValue) - { - CheckBufferSize(sizeof(WCHAR)); - write_value(lValue); - } - inline void WriteDouble(const double& dValue) - { - // здесь никаких даблов. Сплошные округления - int lValue = (int)(dValue * 10000); - WriteLONG(lValue); - return; - - CheckBufferSize(m_lSizeofDouble); - - *((double*)(m_pBuffer + m_lPosition)) = dValue; - m_lPosition += m_lSizeofDouble; - } - inline void WriteDouble2(const double& dValue) - { - CheckBufferSize(sizeof(SHORT)); - write_value((SHORT)(dValue * 100)); - } - inline void WriteFloat(const float& fValue) - { - CheckBufferSize(m_lSizeofFloat); - write_value(fValue); - } - inline void WriteString(wchar_t* bstrValue) - { - int lSize = (int)wcslen(bstrValue) + 1; - - int lSizeMem = lSize * sizeof(wchar_t); - - CheckBufferSize(m_lSizeofLONG + lSizeMem); - write_value(lSizeMem); - - memcpy(m_pBuffer + m_lPosition, bstrValue, lSizeMem); - m_lPosition += lSizeMem; - } - - inline void WriteBYTE(const CommandType& eType, const BYTE& lValue) - { - CheckBufferSize(2 * m_lSizeofBYTE); - - *(m_pBuffer + m_lPosition) = (BYTE)eType; - m_lPosition += m_lSizeofBYTE; - - *(m_pBuffer + m_lPosition) = lValue; - m_lPosition += m_lSizeofBYTE; - } - inline void WriteLONG(const CommandType& eType, const int& lValue) - { - CheckBufferSize(m_lSizeofBYTE + m_lSizeofLONG); - - *(m_pBuffer + m_lPosition) = (BYTE)eType; - m_lPosition += m_lSizeofBYTE; - - write_value(lValue); - } - inline void WriteDouble(const CommandType& eType, const double& dValue) - { - CheckBufferSize(m_lSizeofBYTE + m_lSizeofDouble); - - *(m_pBuffer + m_lPosition) = (BYTE)eType; - m_lPosition += m_lSizeofBYTE; - - write_value(dValue); - } - inline void WriteFloat(const CommandType& eType, const float& fValue) - { - CheckBufferSize(m_lSizeofBYTE + m_lSizeofFloat); - - *(m_pBuffer + m_lPosition) = (BYTE)eType; - m_lPosition += m_lSizeofBYTE; - - write_value(fValue); - } - inline void WriteString(const CommandType& eType, wchar_t* bstrValue) - { - int lSize = (int)wcslen(bstrValue) + 1; - - int lSizeMem = lSize * sizeof(wchar_t); - - CheckBufferSize(m_lSizeofBYTE + m_lSizeofLONG + lSizeMem); - - *(m_pBuffer + m_lPosition) = (BYTE)eType; - m_lPosition += m_lSizeofBYTE; - - write_value(lSizeMem); - - memcpy(m_pBuffer + m_lPosition, bstrValue, lSizeMem); - m_lPosition += lSizeMem; - } - - inline void Write(const BYTE* pData, const LONG& lLen) - { - CheckBufferSize((size_t)lLen); - memcpy(m_pBuffer + m_lPosition, pData, lLen); - m_lPosition += lLen; - } - - inline void Write(const CommandType& eCommand, const double& f1, const double& f2) - { - size_t lMem = m_lSizeofBYTE + 2 * m_lSizeofDouble; - - CheckBufferSize(lMem); - - *(m_pBuffer + m_lPosition) = (BYTE)eCommand; m_lPosition += m_lSizeofBYTE; - write_value(f1); - write_value(f2); - } - - inline void Write(const CommandType& eCommand, const double& f1, const double& f2, const double& f3, const double& f4, const double& f5, const double& f6) - { - size_t lMem = m_lSizeofBYTE + 6 * m_lSizeofDouble; - - CheckBufferSize(lMem); - - *(m_pBuffer + m_lPosition) = (BYTE)eCommand; m_lPosition += m_lSizeofBYTE; - - write_value(f1); - write_value(f2); - write_value(f3); - write_value(f4); - write_value(f5); - write_value(f6); - } - - inline void Write(const CommandType& eCommand, const int& lCount, float* pData) - { - size_t lFloats = lCount * m_lSizeofFloat; - size_t lMem = m_lSizeofBYTE + m_lSizeofLONG + lFloats; - - CheckBufferSize(lMem); - - *(m_pBuffer + m_lPosition) = (BYTE)eCommand; m_lPosition += m_lSizeofBYTE; - write_value(lCount); - - memcpy(m_pBuffer + m_lPosition, pData, lFloats); - m_lPosition += lFloats; - } - inline void Write(const CommandType& eCommand, const int& lCount, double* pData) - { - size_t lFloats = lCount * m_lSizeofDouble; - size_t lMem = m_lSizeofBYTE + m_lSizeofLONG + lFloats; - - CheckBufferSize(lMem); - - *(m_pBuffer + m_lPosition) = (BYTE)eCommand; m_lPosition += m_lSizeofBYTE; - write_value(lCount); - - memcpy(m_pBuffer + m_lPosition, pData, lFloats); - m_lPosition += lFloats; - } - - inline void Write(CMetafile& oMeta) - { - LONG lPos = oMeta.GetPosition(); - CheckBufferSize(lPos); - - memcpy(m_pBuffer + m_lPosition, oMeta.GetData(), lPos); - m_lPosition += lPos; - } - }; -} - -#endif // _ASC_HTMLRENDERER_META_H_ diff --git a/HtmlRenderer/src/SVGWriter.h b/HtmlRenderer/src/SVGWriter.h deleted file mode 100644 index 79116a20be5..00000000000 --- a/HtmlRenderer/src/SVGWriter.h +++ /dev/null @@ -1,853 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2023 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _ASC_HTMLRENDERER_SVGWRITER_H_ -#define _ASC_HTMLRENDERER_SVGWRITER_H_ - -#include "Common.h" -#include -#include -#include "../../DesktopEditor/graphics/GraphicsPath.h" -#include "../../DesktopEditor/graphics/pro/Graphics.h" - -namespace NSHtmlRenderer -{ - class CClipSVG - { - public: - std::vector m_arPaths; - std::vector m_arTypes; - - LONG m_lWidth; - LONG m_lHeight; - - CClipSVG() : m_arPaths(), m_arTypes() - { - m_lWidth = 0; - m_lHeight = 0; - } - ~CClipSVG() - { - } - - void Write(NSStringUtils::CStringBuilder& oWriter, LONG& lCurrentClipPath) - { - // сначала запишем все пути - size_t nCount = m_arPaths.size(); - - for (size_t i = 0; i < nCount; ++i) - { - oWriter.WriteString(L"", 35); - else - oWriter.WriteString(L"\" clip-rule=\"evenodd\" />", 35); - - ++lCurrentClipPath; - } - - LONG lWritePathID = (LONG)lCurrentClipPath - 2; - // теперь запишем пересечения - for (size_t i = 1; i < nCount; ++i) - { - oWriter.WriteString(L"", &oWriter); - - ++lCurrentClipPath; - --lWritePathID; - } - } - - void Write2(NSStringUtils::CStringBuilder& oWriter, LONG& lCurrentClipPath) - { - // сначала запишем все пути - size_t nCount = m_arPaths.size(); - double dMemoryClipTypes = 0; - for (size_t i = 0; i < nCount; ++i) - { - dMemoryClipTypes += m_arTypes[i]; - } - dMemoryClipTypes /= nCount; - if (0 != dMemoryClipTypes && 1 != dMemoryClipTypes) - return Write(oWriter, lCurrentClipPath); - - oWriter.WriteString(L"", 35); - else - oWriter.WriteString(L"\" clip-rule=\"evenodd\" />", 35); - - ++lCurrentClipPath; - } - - inline void Clear() - { - m_arPaths.clear(); - m_arTypes.clear(); - } - inline bool IsInit() - { - return (0 != m_arPaths.size()); - } - }; - - class CClipSVG2 - { - public: - std::vector m_arPaths; - std::vector m_arTypes; - - LONG m_lWidth; - LONG m_lHeight; - - LONG m_lCountWriteClips; - - CClipSVG2() : m_arPaths(), m_arTypes() - { - m_lWidth = 0; - m_lHeight = 0; - - m_lCountWriteClips = 0; - } - ~CClipSVG2() - { - } - - void Write(NSStringUtils::CStringBuilder& oWriter, LONG& lCurrentClipPath) - { - // сначала запишем все пути - size_t nCount = m_arPaths.size(); - - LONG lOld = lCurrentClipPath; - for (size_t i = 0; i < nCount; ++i) - { - oWriter.WriteString(L"", 35); - else - oWriter.WriteString(L"\" clip-rule=\"evenodd\" />", 35); - - ++lCurrentClipPath; - } - - m_lCountWriteClips = (LONG)nCount; - - for (LONG i = 0; i < m_lCountWriteClips; i++) - { - oWriter.WriteString(L"", 3); - } - } - - void WriteEnd(NSStringUtils::CStringBuilder& oWriter) - { - while (m_lCountWriteClips > 0) - { - oWriter.WriteString(L"\n", 5); - --m_lCountWriteClips; - } - } - - inline void Clear() - { - m_arPaths.clear(); - m_arTypes.clear(); - } - inline bool IsInit() - { - return (0 != m_arPaths.size()); - } - }; - - class CSVGWriter - { - public: - NSStringUtils::CStringBuilder m_oPath; - NSStringUtils::CStringBuilder m_oDocument; - - LONG m_lCurDocumentID; - LONG m_lClippingPath; - LONG m_lPatternID; - - bool m_bIsClipping; - bool m_bIsNeedUpdateClip; - LONG m_lClipMode; - - NSStructures::CPen* m_pPen; - NSStructures::CBrush* m_pBrush; - - int m_lWidth; - int m_lHeight; - - double m_dDpiX; - double m_dDpiY; - - CClipSVG m_oClip; - - public: - CSVGWriter() : m_oPath(), m_oDocument() - { - m_lCurDocumentID = 0; - m_lClippingPath = 0; - m_lPatternID = 0; - - m_pPen = NULL; - m_pBrush = NULL; - - m_dDpiX = 96; - m_dDpiY = 96; - - m_lClipMode = c_nClipRegionTypeWinding; - - m_bIsClipping = false; - m_bIsNeedUpdateClip = false; - } - - void ReInit() - { - m_oClip.Clear(); - m_oPath.ClearNoAttack(); - m_oDocument.ClearNoAttack(); - - m_lCurDocumentID = 0; - m_lClippingPath = 0; - m_lPatternID = 0; - - m_dDpiX = 96; - m_dDpiY = 96; - - m_lClipMode = c_nClipRegionTypeWinding; - - m_bIsClipping = false; - m_bIsNeedUpdateClip = false; - } - - void SetSettings(NSStructures::CPen* pPen, NSStructures::CBrush* pBrush) - { - m_pPen = pPen; - m_pBrush = pBrush; - } - - void CloseFile(std::wstring strFile = L"") - { - if (!strFile.empty()) - { - m_oDocument.WriteString(L"", 5); - NSFile::CFileBinary::SaveToFile(strFile, m_oDocument.GetData()); - } - - if (3000000 < m_oDocument.GetSize()) - m_oDocument.Clear(); - - m_oDocument.ClearNoAttack(); - m_oPath.ClearNoAttack(); - - m_oClip.Clear(); - m_lClippingPath = 0; - m_lPatternID = 0; - m_bIsClipping = false; - } - void NewDocument(double& dWidth, double& dHeigth, LONG& lPageNumber) - { - m_lWidth = (int)dWidth; - m_lHeight = (int)dHeigth; - - m_oClip.m_lWidth = m_lWidth; - m_oClip.m_lHeight = m_lHeight; - - m_lCurDocumentID = lPageNumber; - - WriteFormatted(L"\n", &m_oDocument); - - m_oClip.Clear(); - - m_lClippingPath = 0; - m_bIsClipping = false; - m_bIsNeedUpdateClip = false; - } - void NewDocument(int& lWidth, int& lHeigth) - { - m_lWidth = lWidth; - m_lHeight = lHeigth; - - m_oClip.m_lWidth = m_lWidth; - m_oClip.m_lHeight = m_lHeight; - - WriteFormatted(L"\n", &m_oDocument); - - m_oClip.Clear(); - - m_lClippingPath = 0; - m_bIsClipping = false; - m_bIsNeedUpdateClip = false; - } - - public: - - inline void WritePathEnd() - { - m_oPath.ClearNoAttack(); - } - inline void WritePathStart() - { - m_oPath.ClearNoAttack(); - } - void WritePathClose() - { - m_oPath.AddSize(2); - m_oPath.AddCharNoCheck('Z'); - m_oPath.AddSpaceNoCheck(); - } - - void WritePathMoveTo(double& x, double& y) - { - m_oPath.AddSize(30); - m_oPath.AddCharNoCheck('M'); - m_oPath.AddSpaceNoCheck(); - - m_oPath.AddIntNoCheck(round2(x)); - m_oPath.AddCharNoCheck(','); - m_oPath.AddIntNoCheck(round2(y)); - m_oPath.AddSpaceNoCheck(); - } - void WritePathLineTo(double& x, double& y) - { - if (0 == m_oPath.GetCurSize()) - { - WritePathMoveTo(x, y); - } - - m_oPath.AddSize(30); - m_oPath.AddCharNoCheck('L'); - m_oPath.AddSpaceNoCheck(); - - m_oPath.AddIntNoCheck(round2(x)); - m_oPath.AddCharNoCheck(','); - m_oPath.AddIntNoCheck(round2(y)); - m_oPath.AddSpaceNoCheck(); - } - void WritePathCurveTo(double& x1, double& y1, double& x2, double& y2, double& x3, double& y3) - { - if (0 == m_oPath.GetCurSize()) - { - WritePathMoveTo(x1, y1); - } - - m_oPath.AddSize(80); - m_oPath.AddCharNoCheck('C'); - m_oPath.AddSpaceNoCheck(); - - m_oPath.AddIntNoCheck(round2(x1)); - m_oPath.AddCharNoCheck(','); - m_oPath.AddIntNoCheck(round2(y1)); - m_oPath.AddSpaceNoCheck(); - - m_oPath.AddIntNoCheck(round2(x2)); - m_oPath.AddCharNoCheck(','); - m_oPath.AddIntNoCheck(round2(y2)); - m_oPath.AddSpaceNoCheck(); - - m_oPath.AddIntNoCheck(round2(x3)); - m_oPath.AddCharNoCheck(','); - m_oPath.AddIntNoCheck(round2(y3)); - m_oPath.AddSpaceNoCheck(); - } - void WriteHatchPattern() - { - std::wstring sPatternId = std::to_wstring(m_lPatternID++); - - m_oDocument.WriteString(L""); - m_oDocument.WriteString(L"TexturePath, - m_pBrush->Color1 & 0xFF, (m_pBrush->Color1 >> 8) & 0xFF, (m_pBrush->Color1 >> 16) & 0xFF, m_pBrush->Alpha1 & 0xFF, - m_pBrush->Color2 & 0xFF, (m_pBrush->Color2 >> 8) & 0xFF, (m_pBrush->Color2 >> 16) & 0xFF, m_pBrush->Alpha2 & 0xFF); - - m_oDocument.WriteString(UTF8_TO_U(sHatchPattern)); - - m_oDocument.WriteString(L"\" />"); - } - void WriteDrawPath(LONG nType, Aggplus::CMatrix* pTransform, Aggplus::CGraphicsPathSimpleConverter* pConverter, CImageInfo& oInfo, const double& dAngle) - { - if (m_oPath.GetCurSize() < 3) - return; - - WriteClip(); - - double dScaleTransform = (pTransform->sx() + pTransform->sy()) / 2.0; - int nPenW = int(m_pPen->Size * dScaleTransform * SVG_WRITER_SCALE); - - if (0 == nPenW) - nPenW = 1; - - if (0 == m_pPen->Alpha) - nType &= 0xFF00; - - if (c_BrushTypeTexture == m_pBrush->Type) - { - if (0 == m_pBrush->TextureAlpha) - nType &= 0xFF; - } - else - { - if (0 == m_pBrush->Alpha1) - nType &= 0xFF; - } - - bool bStroke = (0x01 == (0x01 & nType)); - bool bFill = (0x01 < nType); - - if (!bFill) - { - // stroke - m_oDocument.WriteString(L"Color); - m_oDocument.WriteString(L";stroke-width:", 14); - m_oDocument.AddInt(nPenW); - m_oDocument.WriteString(L"px;stroke-opacity:", 18); - m_oDocument.AddIntDel100(100 * m_pPen->Alpha / 255); - - if (m_pPen->DashStyle == 0) - { - m_oDocument.WriteString(L";\" ", 3); - } - else - { - m_oDocument.WriteString(L";stroke-dasharray: 2,2;\" ", 25); - } - - WriteStyleClip(); - m_oDocument.WriteString(L" d=\"", 4); - m_oDocument.Write(m_oPath); - m_oDocument.WriteString(L"\" />\n", 5); - return; - } - else if (c_BrushTypeTexture == m_pBrush->Type) - { - double x = 0; - double y = 0; - double r = 0; - double b = 0; - - pConverter->PathCommandGetBounds(x, y, r, b); - r += x; - b += y; - - if (0 == dAngle) - { - pTransform->TransformPoint(x, y); - pTransform->TransformPoint(r, b); - } - else - { - Aggplus::CMatrix oTemp = *pTransform; - - double dCx = (x + r) / 2; - double dCy = (y + b) / 2; - pTransform->TransformPoint(dCx, dCy); - oTemp.RotateAt(-dAngle, dCx, dCy, Aggplus::MatrixOrderAppend); - - oTemp.TransformPoint(x, y); - oTemp.TransformPoint(r, b); - } - - // пока заглушка - return WriteImage(oInfo, x, y, r - x, b - y, dAngle); - -#if 0 - CString strPattern = _T(""); - - /* - if (itJPG == oInfo.m_eType) - { - strPattern.Format(g_svg_string_pattern_jpg, m_lPatternID, _w, _h, _w, _h, _x, _y, _w, _h, oInfo.m_lID); - } - else - { - strPattern.Format(g_svg_string_pattern_png, m_lPatternID, _w, _h, _w, _h, _x, _y, _w, _h, oInfo.m_lID); - } - */ - - m_oDocument.WriteString(strPattern); - - CString strMode = _T("nonzero"); - if (nType & c_nEvenOddFillMode) - strMode = _T("evenodd"); - - if (!bStroke) - { - CString strStyle = _T(""); - strStyle.Format(g_svg_string_vml_StyleFillTx, m_lPatternID, (double)m_pBrush->Alpha1 / 255, strMode); - - m_oDocument.WriteString(g_svg_bstr_vml_Path); - m_oDocument.WriteString(strStyle); - WriteStyleClip(); - m_oDocument.WriteString(g_svg_bstr_path_d); - m_oDocument.Write(m_oPath); - m_oDocument.WriteString(g_svg_bstr_path_d_end); - m_oDocument.WriteString(g_svg_bstr_nodeClose); - } - else - { - int nPenColor = ConvertColor(m_pPen->Color); - - CString strStyle = _T(""); - strStyle.Format(g_svg_string_vml_StyleTx, m_lPatternID, (double)m_pBrush->Alpha1 / 255, strMode, nPenColor, nPenW, (double)m_pPen->Alpha / 255); - - m_oDocument.WriteString(g_svg_bstr_vml_Path); - m_oDocument.WriteString(strStyle); - WriteStyleClip(); - m_oDocument.WriteString(g_svg_bstr_path_d); - m_oDocument.Write(m_oPath); - m_oDocument.WriteString(g_svg_bstr_path_d_end); - m_oDocument.WriteString(g_svg_bstr_nodeClose); - } - - ++m_lPatternID; - return; -#endif - } - - if (!bStroke) - { - if (c_BrushTypeHatch1 == m_pBrush->Type) - WriteHatchPattern(); - - m_oDocument.WriteString(L"Type) - { - m_oDocument.WriteString(L"url(#hatch" + std::to_wstring(m_lPatternID - 1) + L")"); - } - else - { - m_oDocument.WriteHexColor3(m_pBrush->Color1); - m_oDocument.WriteString(L";fill-opacity:", 14); - m_oDocument.AddIntDel100(100 * m_pBrush->Alpha1 / 255); - } - - if (nType & c_nEvenOddFillMode) - m_oDocument.WriteString(L";fill-rule:evenodd;stroke:none\"", 31); - else - m_oDocument.WriteString(L";fill-rule:nonzero;stroke:none\"", 31); - - WriteStyleClip(); - m_oDocument.WriteString(L" d=\"", 4); - m_oDocument.Write(m_oPath); - m_oDocument.WriteString(L"\" />\n", 5); - return; - } - - if (c_BrushTypeHatch1 == m_pBrush->Type) - WriteHatchPattern(); - - m_oDocument.WriteString(L"Type) - { - m_oDocument.WriteString(L"url(#hatch" + std::to_wstring(m_lPatternID - 1) + L")"); - } - else - { - m_oDocument.WriteHexColor3(m_pBrush->Color1); - m_oDocument.WriteString(L";fill-opacity:", 14); - m_oDocument.AddIntDel100(100 * m_pBrush->Alpha1 / 255); - } - - if (nType & c_nEvenOddFillMode) - m_oDocument.WriteString(L";fill-rule:evenodd;stroke:", 26); - else - m_oDocument.WriteString(L";fill-rule:nonzero;stroke:", 26); - m_oDocument.WriteHexColor3(m_pPen->Color); - m_oDocument.WriteString(L";stroke-width:", 14); - m_oDocument.AddInt(nPenW); - m_oDocument.WriteString(L";stroke-opacity:", 16); - m_oDocument.AddIntDel100(100 * m_pPen->Alpha / 255); - m_oDocument.WriteString(L"\" ", 2); - - WriteStyleClip(); - m_oDocument.WriteString(L" d=\"", 4); - m_oDocument.Write(m_oPath); - m_oDocument.WriteString(L"\" />\n", 5); - } - - void WritePathClip() - { - m_bIsClipping = true; - m_bIsNeedUpdateClip = true; - } - void WritePathClipEnd() - { - if (0 == m_oPath.GetCurSize()) - return; - - std::wstring sNewClip = m_oPath.GetData(); - int nSizeCurrent = m_oClip.m_arPaths.size(); - if (nSizeCurrent != 0) - { - if (m_oClip.m_arTypes[nSizeCurrent - 1] == m_lClipMode && m_oClip.m_arPaths[nSizeCurrent - 1] == sNewClip) - return; - } - - m_oClip.m_arPaths.push_back(sNewClip); - m_oClip.m_arTypes.push_back(m_lClipMode); - } - void WritePathResetClip() - { - m_bIsClipping = false; - m_bIsNeedUpdateClip = false; - m_oClip.Clear(); - } - - void WriteImage(CImageInfo& oInfo, const double& x, const double& y, const double& w, const double& h, const double& dAngle) - { - bool bIsClipping = false; - if ((1 < h) && (1 < w) && (1 > fabs(dAngle))) - { - WriteClip(); - bIsClipping = m_bIsClipping; - } - - double dCentreX = x + w / 2.0; - double dCentreY = y + h / 2.0; - - dCentreX *= SVG_WRITER_SCALE; - dCentreY *= SVG_WRITER_SCALE; - - bool bIsRotate = (abs(dAngle) > 1) ? true : false; - - if (itJPG == oInfo.m_eType) - { - if (bIsClipping) - { - m_oDocument.WriteString(L"", 34); - } - else - { - m_oDocument.WriteString(L".jpg\" preserveAspectRatio=\"none\" transform=\"rotate(", 51); - m_oDocument.AddDouble(dAngle, 4); - m_oDocument.AddCharSafe(','); - m_oDocument.AddDouble(dCentreX, 2); - m_oDocument.AddCharSafe(','); - m_oDocument.AddDouble(dCentreY, 2); - m_oDocument.WriteString(L")\"/>", 4); - } - } - else - { - m_oDocument.WriteString(L"", 34); - } - else - { - m_oDocument.WriteString(L".jpg\" preserveAspectRatio=\"none\" transform=\"rotate(", 51); - m_oDocument.AddDouble(dAngle, 4); - m_oDocument.AddCharSafe(','); - m_oDocument.AddDouble(dCentreX, 2); - m_oDocument.AddCharSafe(','); - m_oDocument.AddDouble(dCentreY, 2); - m_oDocument.WriteString(L")\"/>", 4); - } - } - } - else - { - if (bIsClipping) - { - m_oDocument.WriteString(L"", 34); - } - else - { - m_oDocument.WriteString(L".png\" preserveAspectRatio=\"none\" transform=\"rotate(", 51); - m_oDocument.AddDouble(dAngle, 4); - m_oDocument.AddCharSafe(','); - m_oDocument.AddDouble(dCentreX, 2); - m_oDocument.AddCharSafe(','); - m_oDocument.AddDouble(dCentreY, 2); - m_oDocument.WriteString(L")\"/>", 4); - } - } - else - { - m_oDocument.WriteString(L"", 34); - } - else - { - m_oDocument.WriteString(L".png\" preserveAspectRatio=\"none\" transform=\"rotate(", 51); - m_oDocument.AddDouble(dAngle, 4); - m_oDocument.AddCharSafe(','); - m_oDocument.AddDouble(dCentreX, 2); - m_oDocument.AddCharSafe(','); - m_oDocument.AddDouble(dCentreY, 2); - m_oDocument.WriteString(L")\"/>", 4); - } - } - } - } - - inline void WriteClip() - { - if (m_bIsClipping && m_bIsNeedUpdateClip && (m_oClip.IsInit())) - { - m_oClip.Write(m_oDocument, m_lClippingPath); - //m_oClip.Clear(); - m_bIsNeedUpdateClip = false; - } - } - - inline void WriteToMainHtml_1(NSStringUtils::CStringBuilder* pWriter, const CDstInfo& oInfo) - { - if (!oInfo.m_bIsWeb) - { - pWriter->WriteString(L"AddInt(m_lCurDocumentID); - pWriter->WriteString(L".svg\" type=\"image/svg+xml\">", 27); - - CloseFile(oInfo.m_strDstFilePath + L"/page" + std::to_wstring(m_lCurDocumentID) + L".svg"); - } - else - { - pWriter->WriteString(L"WriteString(oInfo.m_strAdditionalPath); - pWriter->WriteString(L"/page", 5); - pWriter->AddInt(m_lCurDocumentID); - pWriter->WriteString(L".svg\" type=\"image/svg+xml\">", 27); - - CloseFile(oInfo.m_strDstFilePath + L"/page" + std::to_wstring(m_lCurDocumentID) + L".svg"); - } - } - inline void WriteToMainHtml_2(NSStringUtils::CStringBuilder* pWriter) - { - pWriter->WriteString(L"", 9); - } - - inline void WriteStyleClip() - { - if (m_bIsClipping) - { - if (!m_oDocument.IsSpace()) - m_oDocument.AddCharSafe(' '); - - m_oDocument.WriteString(L"clip-path=\"url(#clip", 20); - m_oDocument.AddInt(m_lClippingPath - 1); - m_oDocument.WriteString(L")\" ", 3); - } - } - }; -} - -#endif // _ASC_HTMLRENDERER_SVGWRITER_H_ diff --git a/HtmlRenderer/src/SVGWriter2.h b/HtmlRenderer/src/SVGWriter2.h deleted file mode 100644 index 95d83965bff..00000000000 --- a/HtmlRenderer/src/SVGWriter2.h +++ /dev/null @@ -1,1946 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2023 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _ASC_HTMLRENDERER_SVGWRITER2_H_ -#define _ASC_HTMLRENDERER_SVGWRITER2_H_ - -#include "Common2.h" -#include "SVGWriter.h" -#include "../../DesktopEditor/graphics/pro/Graphics.h" - -#define SVG_INLINE_MAX_SIZE 500000 // 500Kb -#define SVG_TO_RASTER_MIN_SIZE 50000000 // 1Mb - -const long c_nClipType2 = 0x0021; // c_nClipType + 1 - -namespace NSHtmlRenderer -{ -#define USE_SIMPLE_GRAPHICS_NOSVG - //#define USE_BIG_GRAPHICS_TORASTER // разкоментировать, как научимся скидывать в растр!!! (пока свг не кроссплатформенный) - - class CRendererGr - { - public: - NSGraphics::IGraphicsRenderer* m_pRenderer; - CBgraFrame* m_pFrame; - - double m_dWidth; - double m_dHeight; - - LONG m_lWidthPix; - LONG m_lHeightPix; - - bool m_bIsRasterNeed; - - public: - CRendererGr() - { - m_pRenderer = NULL; - m_pFrame = NULL; - - m_dWidth = -1; - m_dHeight = -1; - - m_lWidthPix = -1; - m_lHeightPix = -1; - } - ~CRendererGr() - { - RELEASEOBJECT(m_pRenderer); - RELEASEOBJECT(m_pFrame); - } - - inline void UncheckRaster() - { - m_bIsRasterNeed = false; - } - inline void CheckRasterNeed(const bool& bIsRaster) - { - if (!m_bIsRasterNeed) - m_bIsRasterNeed = bIsRaster; - } - - void CheckRaster(double dWidth, double dHeight) - { - if (dWidth != m_dWidth || dHeight != m_dHeight) - { - RELEASEOBJECT(m_pFrame); - - m_dWidth = dWidth; - m_dHeight = dHeight; - } - - RELEASEOBJECT(m_pRenderer); - - m_lWidthPix = (LONG)(96 * m_dWidth / 25.4); - m_lHeightPix = (LONG)(96 * m_dHeight / 25.4); - - if (NULL == m_pFrame) - { - m_pFrame = new CBgraFrame(); - m_pFrame->put_Width((int)m_lWidthPix); - m_pFrame->put_Height((int)m_lHeightPix); - m_pFrame->put_Stride(4 * ((int)m_lWidthPix)); - - BYTE* pData = new BYTE[4 * m_lWidthPix * m_lHeightPix]; - memset(pData, 0xFF, 4 * m_lWidthPix * m_lHeightPix); - m_pFrame->put_Data(pData); - } - - m_pRenderer = NSGraphics::Create(); - - m_pRenderer->put_Width(m_dWidth); - m_pRenderer->put_Height(m_dHeight); - m_pRenderer->CreateFromBgraFrame(m_pFrame); - } - - template - void CheckRasterData(T pPage, double& dWidth, double& dHeight) - { - if (m_bIsRasterNeed) - { - CheckRaster(dWidth, dHeight); - GetRasterData(pPage); - } - UncheckRaster(); - } - - template - void GetRasterData(T pPage) - { - // определяем размеры картинки - if (NULL == m_pFrame) - return; - - BYTE* pBuffer = m_pFrame->get_Data(); - - RECT rect = GetImageBounds(m_pFrame); - - if (((rect.right - rect.left) < 5) && ((rect.bottom - rect.top) < 5)) - return; - - BYTE* pBufferSrcMem = pBuffer + 4 * rect.top * m_lWidthPix + 4 * rect.left; - LONG lWidthShape = rect.right - rect.left + 1; - LONG lHeightShape = rect.bottom - rect.top + 1; - - CBgraFrame* pShapePicture = new CBgraFrame(); - pShapePicture->put_Width((int)lWidthShape); - pShapePicture->put_Height((int)lHeightShape); - pShapePicture->put_Stride(4 * ((int)lWidthShape)); - - BYTE* pBufferDst = new BYTE[4 * lWidthShape * lHeightShape]; - m_pFrame->put_Data(pBufferDst); - - for (LONG lLine = 0; lLine < lHeightShape; ++lLine) - { - memcpy(pBufferDst, pBufferSrcMem, 4 * lWidthShape); - pBufferDst += 4 * lWidthShape; - pBufferSrcMem += 4 * m_lWidthPix; - } - - double dL = 25.4 * rect.left / 96.0; - double dT = 25.4 * rect.top / 96.0; - double dW = 25.4 * lWidthShape / 96.0; - double dH = 25.4 * lHeightShape / 96.0; - - double dHeightMM = 25.4 * m_lWidthPix / 96.0; - dT = (dHeightMM - dT - dH); - - pPage->WriteImage(pShapePicture, dL, dT, dW, dH); - - RELEASEOBJECT(pShapePicture); - } - }; - - class CDoubleBounds - { - public: - bool IsCleared; - - double x; - double y; - double r; - double b; - - public: - CDoubleBounds() - { - Clear(); - } - - void Clear() - { - IsCleared = true; - - x = 10000000.0; - y = 10000000.0; - r = -10000000.0; - b = -10000000.0; - } - - inline void CheckPoint(const double& _x, const double& _y) - { - IsCleared = false; - if (x > _x) - x = _x; - if (y > _y) - y = _y; - if (r < _x) - r = _x; - if (b < _y) - b = _y; - } - - inline void Intersect(const CDoubleBounds& oBounds) - { - if (IsCleared) - { - x = oBounds.x; - y = oBounds.y; - r = oBounds.r; - b = oBounds.b; - - IsCleared = false; - } - else - { - if (oBounds.x > x) - x = oBounds.x; - - if (oBounds.y > y) - y = oBounds.y; - - if (oBounds.r < r) - r = oBounds.r; - - if (oBounds.b < b) - b = oBounds.b; - } - } - }; - - class CSVGWriter2 - { - public: - NSStringUtils::CStringBuilder m_oPath; - NSStringUtils::CStringBuilder m_oDocument; - - LONG m_lCurDocumentID; - LONG m_lClippingPath; - LONG m_lPatternID; - - bool m_bIsClipping; - bool m_bIsNeedUpdateClip; - LONG m_lClipMode; - - NSStructures::CPen* m_pPen; - NSStructures::CBrush* m_pBrush; - - NSStructures::CPen* m_pLastPen; - NSStructures::CBrush* m_pLastBrush; - - Aggplus::CMatrix* m_pTransform; - - int m_lWidth; - int m_lHeight; - - double m_dDpiX; - double m_dDpiY; - - CClipSVG2 m_oClip; - - // здесь храним пат в координатах не трансформированных - // (чтобы, если заливки сложные - можно было делать трансформы - // непосредственно при использовании графического пути). - double* m_pCoordsArray; - unsigned int m_lCoordsSize; - double* m_pCoordsArrayCur; - unsigned int m_lCoordsSizeCur; - - bool m_bIsCurveToExist; - - BYTE* m_pPathTypes; - unsigned int m_lPathTypesSize; - BYTE* m_pPathTypesCur; - unsigned int m_lPathTypesSizeCur; - - double m_dCoordsScaleX; - double m_dCoordsScaleY; - - unsigned int m_lEmtyDocChecker; - - BYTE* m_pBase64Code; - CDoubleBounds m_oTextClipBounds; - - // переменная говорит о том, какой клип для текста записан сейчас - // если true - то послана команда ResetTextClipRect - // если false - то нет - bool m_bIsTextClipWriteCleared; - // были ли новые clip'ы - bool m_bIsIntersectNewClipRect; - - // сохранение в растр. (если сложная заливка, или слишком большая векторная графика) - //CRendererGr m_oGrRenderer; - //Graphics::IASCMetafile* m_pGrRenderer; - - // клип для картинок. для конвертации сложной векторной графики в растр - CMetafile m_oClipMetafile; - - int m_nDEBUG_svg_index; - -#ifdef USE_SIMPLE_GRAPHICS_NOSVG - - CMetafile m_oVectors; - bool m_bIsSimpleGraphics; - bool m_bIsSimpleSetupBrush; - LONG m_lBrushColorOld; - LONG m_lBrushAlphaOld; - -#endif - - public: - CSVGWriter2() : m_oPath(), m_oDocument() - { - m_lCurDocumentID = 0; - m_lClippingPath = 0; - m_lPatternID = 0; - - m_pPen = NULL; - m_pBrush = NULL; - - m_pLastPen = NULL; - m_pLastBrush = NULL; - - m_dDpiX = 96; - m_dDpiY = 96; - - m_dCoordsScaleX = m_dDpiX / 25.4; - m_dCoordsScaleY = m_dDpiY / 25.4; - - m_lClipMode = c_nClipRegionTypeWinding; - - m_bIsClipping = false; - m_bIsNeedUpdateClip = false; - - m_pCoordsArray = NULL; - m_lCoordsSize = 0; - m_pCoordsArrayCur = NULL; - m_lCoordsSizeCur = 0; - - m_pPathTypes = NULL; - m_lPathTypesSize = 0; - m_pPathTypesCur = NULL; - m_lPathTypesSizeCur = 0; - - m_lEmtyDocChecker = 0; - - m_pBase64Code = new BYTE[2 * SVG_INLINE_MAX_SIZE]; - m_bIsTextClipWriteCleared = true; - m_bIsIntersectNewClipRect = false; - - m_bIsCurveToExist = false; - - m_nDEBUG_svg_index = 0; - -#ifdef USE_SIMPLE_GRAPHICS_NOSVG - m_bIsSimpleGraphics = true; - m_bIsSimpleSetupBrush = false; - - m_lBrushColorOld = 0; - m_lBrushAlphaOld = 255; -#endif - } - ~CSVGWriter2() - { - RELEASEARRAYOBJECTS(m_pBase64Code); - } - - void ReInit() - { - m_bIsTextClipWriteCleared = true; - m_bIsIntersectNewClipRect = false; - m_oTextClipBounds.Clear(); - m_oClip.Clear(); - m_oPath.ClearNoAttack(); - m_oDocument.ClearNoAttack(); - - m_lCurDocumentID = 0; - m_lClippingPath = 0; - m_lPatternID = 0; - - m_dDpiX = 96; - m_dDpiY = 96; - - m_lClipMode = c_nClipRegionTypeWinding; - - m_bIsClipping = false; - m_bIsNeedUpdateClip = false; - } - - void SetSettings(NSStructures::CPen* pPen, NSStructures::CBrush* pBrush) - { - m_pPen = pPen; - m_pBrush = pBrush; - } - - void CloseFile(std::wstring strFile = L"") - { - if (!strFile.empty()) - { - m_oDocument.WriteString(L"", 6); - NSFile::CFileBinary::SaveToFile(strFile, m_oDocument.GetData()); - } - - if (3000000 < m_oDocument.GetSize()) - m_oDocument.Clear(); - - m_oDocument.ClearNoAttack(); - m_oPath.ClearNoAttack(); - - m_oClip.Clear(); - m_lClippingPath = 0; - m_lPatternID = 0; - m_bIsClipping = false; - } - - std::wstring GetSVGXml() - { - m_oClip.WriteEnd(m_oDocument); - m_oDocument.WriteString(L"", 6); - - return m_oDocument.GetData(); - } - - void DEBUG_DumpSVG(const std::wstring& sTempPath) - { - std::wstring sEndDebug = L""; - int nCountWriteClips = m_oClip.m_lCountWriteClips; - while (nCountWriteClips > 0) - { - sEndDebug += L"\n"; - --nCountWriteClips; - } - sEndDebug += L""; - - m_nDEBUG_svg_index++; - - std::wstring sDocument = m_oDocument.GetData() + sEndDebug; - - NSFile::CFileBinary::SaveToFile(sTempPath + L"/svg_" + std::to_wstring(m_nDEBUG_svg_index) + L".svg", sDocument); - } - - void CloseFile2(std::wstring strFile, bool bIsNeedEnd = true) - { - if (bIsNeedEnd) - { - m_oClip.WriteEnd(m_oDocument); - m_oDocument.WriteString(L"", 6); - } - - NSFile::CFileBinary::SaveToFile(strFile, m_oDocument.GetData()); - m_oDocument.ClearNoAttack(); - m_oPath.ClearNoAttack(); - - if (m_bIsClipping) - { - m_bIsNeedUpdateClip = true; - } - - m_lPatternID = 0; - } - int CloseFile3(NSHtmlRenderer::CMetafile* m_pMeta, bool bIsNeedEnd = true) - { - if (bIsNeedEnd) - { - m_oClip.WriteEnd(m_oDocument); - m_oDocument.WriteString(L"", 6); - } - - BYTE* pDataSrc = NULL; - LONG nLenSrc = 0; - NSFile::CUtf8Converter::GetUtf8StringFromUnicode(m_oDocument.GetBuffer(), (LONG)m_oDocument.GetCurSize(), pDataSrc, nLenSrc); - - char* pBase64 = NULL; - int nLenDst = 2 * SVG_INLINE_MAX_SIZE; - NSBase64::Base64Encode(pDataSrc, (int)nLenSrc, m_pBase64Code, &nLenDst); - - RELEASEARRAYOBJECTS(pDataSrc); - - m_pMeta->WriteLONG(nLenDst); - m_pMeta->Write(m_pBase64Code, nLenDst); - - m_oDocument.ClearNoAttack(); - m_oPath.ClearNoAttack(); - - if (m_bIsClipping) - { - m_bIsNeedUpdateClip = true; - } - - m_lPatternID = 0; - - return nLenDst; - } - - void NewDocument(const double& dWidth, const double& dHeigth, const LONG& lPageNumber) - { - m_lWidth = (int)(dWidth * m_dCoordsScaleX); - m_lHeight = (int)(dHeigth * m_dCoordsScaleY); - - m_oClip.m_lWidth = m_lWidth; - m_oClip.m_lHeight = m_lHeight; - - m_lCurDocumentID = lPageNumber; - - m_oDocument.ClearNoAttack(); - - m_oDocument.WriteString(L"\n", 95); - - m_oClip.Clear(); - - m_lClippingPath = 0; - m_bIsClipping = false; - m_bIsNeedUpdateClip = false; - - m_lEmtyDocChecker = (unsigned int)m_oDocument.GetCurSize(); - } - - public: - - inline void WritePathEnd() - { - m_bIsCurveToExist = false; - m_oPath.ClearNoAttack(); - - ClearVectorCoords(); - } - inline void WritePathStart() - { - m_bIsCurveToExist = false; - m_oPath.ClearNoAttack(); - - ClearVectorCoords(); - } - void WritePathClose() - { - CheckSizeVectorB(); - *m_pPathTypesCur++ = 3; - ++m_lPathTypesSizeCur; - - /* - m_oPath.AddSize(2); - m_oPath.AddCharNoCheck('Z'); - m_oPath.AddSpaceNoCheck(); - */ - } - - void WritePathMoveTo(const double& x, const double& y) - { - CheckSizeVectorB(); - *m_pPathTypesCur++ = 0; - ++m_lPathTypesSizeCur; - - CheckSizeVectorD(2); - m_pCoordsArrayCur[0] = x; - m_pCoordsArrayCur[1] = y; - - m_pTransform->TransformPoint(m_pCoordsArrayCur[0], m_pCoordsArrayCur[1]); - - m_pCoordsArrayCur += 2; - m_lCoordsSizeCur += 2; - - /* - m_oPath.AddSize(30); - m_oPath.AddCharNoCheck('M'); - m_oPath.AddSpaceNoCheck(); - - m_oPath.AddIntNoCheck(round(x)); - m_oPath.AddCharNoCheck(','); - m_oPath.AddIntNoCheck(round(y)); - m_oPath.AddSpaceNoCheck(); - */ - } - void WritePathLineTo(const double& x, const double& y) - { - if (0 == m_lPathTypesSizeCur) - { - WritePathMoveTo(x, y); - return; - } - - CheckSizeVectorB(); - *m_pPathTypesCur++ = 1; - ++m_lPathTypesSizeCur; - - CheckSizeVectorD(2); - m_pCoordsArrayCur[0] = x; - m_pCoordsArrayCur[1] = y; - - m_pTransform->TransformPoint(m_pCoordsArrayCur[0], m_pCoordsArrayCur[1]); - - if (fabs(m_pCoordsArray[m_lCoordsSizeCur - 2] - m_pCoordsArrayCur[0]) < 0.1 && - fabs(m_pCoordsArray[m_lCoordsSizeCur - 1] - m_pCoordsArrayCur[1]) < 0.1) - { - // попали в текущую точку. не добавляем - --m_pPathTypesCur; - --m_lPathTypesSizeCur; - return; - } - - m_pCoordsArrayCur += 2; - m_lCoordsSizeCur += 2; - - /* - m_oPath.AddSize(30); - m_oPath.AddCharNoCheck('L'); - m_oPath.AddSpaceNoCheck(); - - m_oPath.AddIntNoCheck(round(x)); - m_oPath.AddCharNoCheck(','); - m_oPath.AddIntNoCheck(round(y)); - m_oPath.AddSpaceNoCheck(); - */ - } - void WritePathCurveTo(const double& x1, const double& y1, const double& x2, const double& y2, const double& x3, const double& y3) - { - if (0 == m_lPathTypesSizeCur) - WritePathMoveTo(x1, y1); - - CheckSizeVectorB(); - *m_pPathTypesCur++ = 2; - ++m_lPathTypesSizeCur; - - CheckSizeVectorD(6); - m_pCoordsArrayCur[0] = x1; - m_pCoordsArrayCur[1] = y1; - m_pCoordsArrayCur[2] = x2; - m_pCoordsArrayCur[3] = y2; - m_pCoordsArrayCur[4] = x3; - m_pCoordsArrayCur[5] = y3; - - m_pTransform->TransformPoint(m_pCoordsArrayCur[0], m_pCoordsArrayCur[1]); - m_pTransform->TransformPoint(m_pCoordsArrayCur[2], m_pCoordsArrayCur[3]); - m_pTransform->TransformPoint(m_pCoordsArrayCur[4], m_pCoordsArrayCur[5]); - - m_pCoordsArrayCur += 6; - m_lCoordsSizeCur += 6; - - m_bIsCurveToExist = true; - - /* - m_oPath.AddSize(80); - m_oPath.AddCharNoCheck('C'); - m_oPath.AddSpaceNoCheck(); - - m_oPath.AddIntNoCheck(round(x1)); - m_oPath.AddCharNoCheck(','); - m_oPath.AddIntNoCheck(round(y1)); - m_oPath.AddSpaceNoCheck(); - - m_oPath.AddIntNoCheck(round(x2)); - m_oPath.AddCharNoCheck(','); - m_oPath.AddIntNoCheck(round(y2)); - m_oPath.AddSpaceNoCheck(); - - m_oPath.AddIntNoCheck(round(x3)); - m_oPath.AddCharNoCheck(','); - m_oPath.AddIntNoCheck(round(y3)); - m_oPath.AddSpaceNoCheck(); - */ - } - - void WriteDrawPath(LONG nType, Aggplus::CGraphicsPathSimpleConverter* pConverter, CImageInfo& oInfo) - { - if (m_lPathTypesSizeCur == 0) - return; - - WriteClip(); - -#ifdef USE_SIMPLE_GRAPHICS_NOSVG - if (m_bIsClipping) - m_bIsSimpleGraphics = false; -#endif - - if (0 == m_pPen->Alpha) - nType &= 0xFF00; - - if (c_BrushTypeTexture == m_pBrush->Type) - { - if (0 == m_pBrush->TextureAlpha) - nType &= 0xFF; - } - else - { - if (0 == m_pBrush->Alpha1) - nType &= 0xFF; - } - - bool bIsNeedTransform = true; - // первым делом нужно понять, будем ли мы трансформировать пути - if (nType > 0xFF && m_pBrush->Type == c_BrushTypeTexture) - { - bIsNeedTransform = false; - } - - int nPenW = 1; - if (0 != m_pPen->Size) - { - if (!bIsNeedTransform) - { - nPenW = (int)(m_pPen->Size); - } - else - { - double _x1 = 0; - double _y1 = 0; - double _x2 = 1; - double _y2 = 1; - m_pTransform->TransformPoint(_x1, _y1); - m_pTransform->TransformPoint(_x2, _y2); - - double dScaleTransform = sqrt(((_x2 - _x1) * (_x2 - _x1) + (_y2 - _y1) * (_y2 - _y1)) / 2) * m_dCoordsScaleX; - nPenW = (int)(m_pPen->Size * dScaleTransform); - } - } - - bool bStroke = (0x01 == (0x01 & nType)); - - if (nPenW == 0 && bStroke) - nPenW = 1; - - bool bFill = (0x01 < nType); - bool bIsLine = false; - -#ifdef USE_SIMPLE_GRAPHICS_NOSVG - - if (m_bIsSimpleGraphics) - { - if (bFill && ((0 != (nType & c_nEvenOddFillMode)) || m_pBrush->Type != c_BrushTypeSolid)) - m_bIsSimpleGraphics = false; - - if (bStroke && m_pPen->DashStyle != 0) - m_bIsSimpleGraphics = false; - } - - if (m_bIsSimpleGraphics) - { - // пишем вектор и настройки brush/pen - m_oVectors.WriteCommandType(CMetafile::ctPathCommandStart); - WriteToPathToSimpleVector(); - - bIsLine = WriteToPathToSVGPath(false, (bFill && !bStroke) ? true : false); - - if (bFill && !bIsLine) - { - if (!m_pLastBrush->IsEqual(m_pBrush)) - { - if (!m_bIsSimpleSetupBrush) - { - m_lBrushColorOld = m_pLastBrush->Color1; - m_lBrushAlphaOld = m_pLastBrush->Alpha1; - m_bIsSimpleSetupBrush = true; - } - - *m_pLastBrush = *m_pBrush; - - m_oVectors.WriteCommandType(CMetafile::ctBrushColor1); - LONG lBGR = m_pBrush->Color1; - - m_oVectors.WriteBYTE((BYTE)(lBGR & 0xFF)); - m_oVectors.WriteBYTE((BYTE)((lBGR >> 8) & 0xFF)); - m_oVectors.WriteBYTE((BYTE)((lBGR >> 16) & 0xFF)); - m_oVectors.WriteBYTE((BYTE)m_pBrush->Alpha1); - } - } - else if (bIsLine) - { - LONG _C = m_pPen->Color; - LONG _A = m_pPen->Alpha; - double _W = m_pPen->Size; - - m_pPen->Color = m_pBrush->Color1; - m_pPen->Alpha = m_pBrush->Alpha1; - m_pPen->Size = 1 / m_dCoordsScaleX; - - if (!m_pLastPen->IsEqual(m_pPen)) - { - *m_pLastPen = *m_pPen; - - m_oVectors.WriteCommandType(CMetafile::ctPenColor); - LONG lBGR = m_pPen->Color; - - m_oVectors.WriteBYTE((BYTE)(lBGR & 0xFF)); - m_oVectors.WriteBYTE((BYTE)((lBGR >> 8) & 0xFF)); - m_oVectors.WriteBYTE((BYTE)((lBGR >> 16) & 0xFF)); - m_oVectors.WriteBYTE((BYTE)m_pPen->Alpha); - - m_oVectors.WriteCommandType(CMetafile::ctPenSize); - m_oVectors.WriteDouble((double)nPenW / m_dCoordsScaleX); - } - - m_pPen->Color = _C; - m_pPen->Alpha = _A; - m_pPen->Size = _W; - } - if (bStroke) - { - if (!m_pLastPen->IsEqual(m_pPen)) - { - *m_pLastPen = *m_pPen; - - m_oVectors.WriteCommandType(CMetafile::ctPenColor); - LONG lBGR = m_pPen->Color; - - m_oVectors.WriteBYTE((BYTE)(lBGR & 0xFF)); - m_oVectors.WriteBYTE((BYTE)((lBGR >> 8) & 0xFF)); - m_oVectors.WriteBYTE((BYTE)((lBGR >> 16) & 0xFF)); - m_oVectors.WriteBYTE((BYTE)m_pPen->Alpha); - - m_oVectors.WriteCommandType(CMetafile::ctPenSize); - m_oVectors.WriteDouble((double)nPenW / m_dCoordsScaleX); - } - } - - m_oVectors.WriteCommandType(CMetafile::ctDrawPath); - m_oVectors.WriteLONG(bIsLine ? 1 : nType); - - m_oVectors.WriteCommandType(CMetafile::ctPathCommandStart); - } - else - { - bIsLine = WriteToPathToSVGPath(false, (bFill && !bStroke) ? true : false); - } - -#else - bIsLine = WriteToPathToSVGPath(false, (bFill && !bStroke) ? true : false); -#endif - - if (!bFill) - { - // stroke - m_oDocument.WriteString(L"Color); - else - m_oDocument.WriteString(L"none"); - m_oDocument.WriteString(L";stroke-width:", 14); - m_oDocument.AddInt(nPenW); - m_oDocument.WriteString(L";stroke-opacity:", 16); - m_oDocument.AddDouble((double)m_pPen->Alpha / 255, 2); - if (m_pPen->DashStyle == 0) - m_oDocument.WriteString(L";\" ", 3); - else - m_oDocument.WriteString(L";stroke-dasharray: 2,2;\" ", 25); - - WriteStyleClip(); - m_oDocument.WriteString(L" d=\"", 4); - m_oDocument.Write(m_oPath); - m_oDocument.WriteString(L"\" />\n", 5); - return; - } - else if (c_BrushTypeTexture == m_pBrush->Type) - { - double x = 0; - double y = 0; - double w = 0; - double h = 0; - pConverter->PathCommandGetBounds(x, y, w, h); - - if (m_pBrush->TextureMode == c_BrushTextureModeStretch || true) - { - // 1) пишем паттерн - double _tx = m_pTransform->tx() * m_dCoordsScaleX; - double _ty = m_pTransform->ty() * m_dCoordsScaleY; - - double _w = w * m_dCoordsScaleX; - double _h = h * m_dCoordsScaleY; - - m_oDocument.WriteString(L"sx(), 3); - m_oDocument.AddCharSafe(','); - m_oDocument.AddDouble(m_pTransform->shy(), 3); - m_oDocument.AddCharSafe(','); - m_oDocument.AddDouble(m_pTransform->shx(), 3); - m_oDocument.AddCharSafe(','); - m_oDocument.AddDouble(m_pTransform->sy(), 3); - m_oDocument.AddCharSafe(','); - m_oDocument.AddDouble(_tx, 3); - m_oDocument.AddCharSafe(','); - m_oDocument.AddDouble(_ty, 3); - m_oDocument.WriteString(L")\">", 44); - else - m_oDocument.WriteString(L".png\" preserveAspectRatio=\"none\"/>", 44); - } - else - { - // TODO: - } - - m_oDocument.WriteString(L"Alpha1 / 255, 2); - if (nType & c_nEvenOddFillMode) - m_oDocument.WriteString(L";fill-rule:evenodd;", 19); - else - m_oDocument.WriteString(L";fill-rule:nonzero;", 19); - - if (!bStroke) - { - m_oDocument.WriteString(L"stroke:none;\" ", 14); - } - else - { - m_oDocument.WriteString(L"stroke:", 7); - m_oDocument.WriteHexColor3(m_pPen->Color); - m_oDocument.WriteString(L";stroke-width:", 14); - m_oDocument.AddInt(nPenW); - m_oDocument.WriteString(L";stroke-opacity:", 16); - m_oDocument.AddDouble((double)m_pPen->Alpha / 255, 2); - m_oDocument.WriteString(L"\" ", 2); - } - - WriteStyleClip(); - m_oDocument.WriteString(L" d=\"", 4); - m_oDocument.Write(m_oPath); - m_oDocument.WriteString(L"\" />\n", 5); - - ++m_lPatternID; - return; - } - - int nColorBrush = ConvertColor(m_pBrush->Color1); - if (nType & c_nEvenOddFillMode) - { -#ifdef USE_SIMPLE_GRAPHICS_NOSVG - m_bIsSimpleGraphics = false; -#endif - } - - if (!bStroke) - { - if (bIsLine) - { - m_oDocument.WriteString(L"Color1); - m_oDocument.WriteString(L";stroke-width:", 14); - m_oDocument.AddInt(1); - m_oDocument.WriteString(L";stroke-opacity:", 16); - m_oDocument.AddDouble((double)m_pBrush->Alpha1 / 255, 2); - m_oDocument.WriteString(L";\" ", 3); - - WriteStyleClip(); - m_oDocument.WriteString(L" d=\"", 4); - m_oDocument.Write(m_oPath); - m_oDocument.WriteString(L"\" />\n", 5); - return; - } - - m_oDocument.WriteString(L"Color1); - m_oDocument.WriteString(L";fill-opacity:", 14); - m_oDocument.AddDouble((double)m_pBrush->Alpha1 / 255, 2); - if (nType & c_nEvenOddFillMode) - m_oDocument.WriteString(L";fill-rule:evenodd;stroke:none\" ", 32); - else - m_oDocument.WriteString(L";fill-rule:nonzero;stroke:none\" ", 32); - - WriteStyleClip(); - m_oDocument.WriteString(L" d=\"", 4); - m_oDocument.Write(m_oPath); - m_oDocument.WriteString(L"\" />\n", 5); - return; - } - - m_oDocument.WriteString(L"Color1); - m_oDocument.WriteString(L";fill-opacity:", 14); - m_oDocument.AddDouble((double)m_pBrush->Alpha1 / 255, 2); - if (nType & c_nEvenOddFillMode) - m_oDocument.WriteString(L";fill-rule:evenodd;stroke:", 26); - else - m_oDocument.WriteString(L";fill-rule:nonzero;stroke:", 26); - m_oDocument.WriteHexColor3(m_pPen->Color); - m_oDocument.WriteString(L";stroke-width:", 14); - m_oDocument.AddInt(nPenW); - m_oDocument.WriteString(L";stroke-opacity:", 16); - m_oDocument.AddDouble((double)m_pPen->Alpha / 255, 2); - m_oDocument.WriteString(L";\" ", 3); - - WriteStyleClip(); - m_oDocument.WriteString(L" d=\"", 4); - m_oDocument.Write(m_oPath); - m_oDocument.WriteString(L"\" />\n", 5); - } - - void WritePathClip() - { - m_bIsClipping = true; - m_bIsNeedUpdateClip = true; - } - void WritePathClipEnd() - { - /* - if (1 == m_lPathTypesSizeCur && m_pPathTypes[0] <= 1) - { - // не надо клип делать. пат странен) - return; - } - else if (2 == m_lPathTypesSizeCur && - ((m_pPathTypes[0] == 0 || m_pPathTypes[1] == 0) && (m_pPathTypes[0] <= 1 && m_pPathTypes[1] <= 1))) - { - // пат все еще странен - return; - } - */ - m_oClip.WriteEnd(m_oDocument); - - m_bIsIntersectNewClipRect = true; - WriteToPathToSVGPath(true); - - if (0 == m_oPath.GetCurSize()) - return; - - m_oClip.m_arPaths.push_back(m_oPath.GetData()); - m_oClip.m_arTypes.push_back(m_lClipMode); - } - void WritePathResetClip() - { - m_bIsClipping = false; - m_bIsNeedUpdateClip = false; - m_oClip.Clear(); - m_oTextClipBounds.Clear(); - - m_oClipMetafile.ClearNoAttack(); - - m_oClip.WriteEnd(m_oDocument); - } - - void WriteImage(CImageInfo& oInfo, const double& x, const double& y, const double& w, const double& h) - { - bool bIsClipping = false; - if ((1 < h) && (1 < w)) - { - WriteClip(); - bIsClipping = m_bIsClipping; - } - - double dCentreX = x + w / 2.0; - double dCentreY = y + h / 2.0; - - bool bIsNoNeedTransform = m_pTransform->IsIdentity2(0.0001); - - if (bIsNoNeedTransform) - { - double _x = x + m_pTransform->tx(); - double _y = y + m_pTransform->ty(); - - _x *= m_dCoordsScaleX; - _y *= m_dCoordsScaleY; - - double _w = w * m_dCoordsScaleX; - double _h = h * m_dCoordsScaleY; - - if (itJPG == oInfo.m_eType) - { - /*if (bIsClipping) - { - //(""); - strImage.Format(g_svg_string_image_clip_jpg1, round(_x), round(_y), round(_w), round(_h), m_lClippingPath - 1, oInfo.m_lID); - } - else*/ - { - m_oDocument.WriteString(L"", 34); - } - } - else - { - /*if (bIsClipping) - { - //(""); - strImage.Format(g_svg_string_image_clip_png1, round(_x), round(_y), round(_w), round(_h), m_lClippingPath - 1, oInfo.m_lID); - } - else*/ - { - m_oDocument.WriteString(L"", 34); - } - } - } - else - { - double _tx = m_pTransform->tx() * m_dCoordsScaleX; - double _ty = m_pTransform->ty() * m_dCoordsScaleY; - - double _x = x * m_dCoordsScaleX; - double _y = y * m_dCoordsScaleY; - - double _w = w * m_dCoordsScaleX; - double _h = h * m_dCoordsScaleY; - - if (itJPG == oInfo.m_eType) - { - /*if (bIsClipping) - { - //_T(""); - strImage.Format(g_svg_string_image_clip_jpg_mtx, _x, _y, _w, _h, m_lClippingPath - 1, oInfo.m_lID, mtx->sx, mtx->shy, mtx->shx, mtx->sy, _tx, _ty); - } - else*/ - { - m_oDocument.WriteString(L"", 53); - - m_oDocument.AddDouble(m_pTransform->sx(), 3); - m_oDocument.AddCharSafe(','); - m_oDocument.AddDouble(m_pTransform->shy(), 3); - m_oDocument.AddCharSafe(','); - m_oDocument.AddDouble(m_pTransform->shx(), 3); - m_oDocument.AddCharSafe(','); - m_oDocument.AddDouble(m_pTransform->sy(), 3); - m_oDocument.AddCharSafe(','); - m_oDocument.AddDouble(_tx, 3); - m_oDocument.AddCharSafe(','); - m_oDocument.AddDouble(_ty, 3); - m_oDocument.WriteString(L")\"/>", 4); - } - } - else - { - /*if (bIsClipping) - { - //_T(""); - strImage.Format(g_svg_string_image_clip_png_mtx, _x, _y, _w, _h, m_lClippingPath - 1, oInfo.m_lID, mtx->sx, mtx->shy, mtx->shx, mtx->sy, _tx, _ty); - } - else*/ - { - m_oDocument.WriteString(L"", 53); - - m_oDocument.AddDouble(m_pTransform->sx(), 3); - m_oDocument.AddCharSafe(','); - m_oDocument.AddDouble(m_pTransform->shy(), 3); - m_oDocument.AddCharSafe(','); - m_oDocument.AddDouble(m_pTransform->shx(), 3); - m_oDocument.AddCharSafe(','); - m_oDocument.AddDouble(m_pTransform->sy(), 3); - m_oDocument.AddCharSafe(','); - m_oDocument.AddDouble(_tx, 3); - m_oDocument.AddCharSafe(','); - m_oDocument.AddDouble(_ty, 3); - m_oDocument.WriteString(L")\"/>", 4); - } - } - } - } - - inline void WriteClip() - { - if (m_bIsClipping && m_bIsNeedUpdateClip && (m_oClip.IsInit())) - { - m_oClip.Write(m_oDocument, m_lClippingPath); - //m_oClip.Clear(); - m_bIsNeedUpdateClip = false; - } - } - - inline void WriteStyleClip() - { - // сейчас не пишем (оборачиваем в g) - return; - - if (m_bIsClipping) - { - //_T("clip-path=\"url(#clip%d)\" "); - m_oDocument.WriteString(L"clip-path=\"url(#clip", 20); - m_oDocument.AddInt(m_lClippingPath - 1); - m_oDocument.WriteString(L")\" ", 3); - } - } - - void CheckSizeVectorB(const int& len = 1) - { - if (NULL != m_pPathTypes) - { - unsigned int nNewSize = (unsigned int)(m_lPathTypesSizeCur + len); - if (nNewSize >= m_lPathTypesSize) - { - if (nNewSize >= m_lPathTypesSize) - { - while (nNewSize >= m_lPathTypesSize) - { - m_lPathTypesSize *= 2; - } - - BYTE* pNew = new BYTE[m_lPathTypesSize]; - memcpy(pNew, m_pPathTypes, m_lPathTypesSizeCur); - - RELEASEARRAYOBJECTS(m_pPathTypes); - m_pPathTypes = pNew; - m_pPathTypesCur = m_pPathTypes + m_lPathTypesSizeCur; - } - } - } - else - { - m_lPathTypesSize = 1000; - m_pPathTypes = new BYTE[m_lPathTypesSize]; - m_pPathTypesCur = m_pPathTypes; - m_lPathTypesSizeCur = 0; - } - } - - void CheckSizeVectorD(const int& len) - { - if (NULL != m_pCoordsArray) - { - unsigned int nNewSize = (unsigned int)(m_lCoordsSizeCur + len); - if (nNewSize >= m_lCoordsSize) - { - while (nNewSize >= m_lCoordsSize) - { - m_lCoordsSize *= 2; - } - - double* pNew = new double[m_lCoordsSize]; - memcpy(pNew, m_pCoordsArray, m_lCoordsSizeCur * sizeof(double)); - - RELEASEARRAYOBJECTS(m_pCoordsArray); - m_pCoordsArray = pNew; - m_pCoordsArrayCur = m_pCoordsArray + m_lCoordsSizeCur; - } - } - else - { - m_lCoordsSize = 1000; - m_pCoordsArray = new double[m_lCoordsSize]; - m_pCoordsArrayCur = m_pCoordsArray; - m_lCoordsSizeCur = 0; - } - } - - void ClearVectorCoords() - { - m_lCoordsSizeCur = 0; - m_pCoordsArrayCur = m_pCoordsArray; - - m_lPathTypesSizeCur = 0; - m_pPathTypesCur = m_pPathTypes; - } - - bool WriteToPathToSVGPath(bool bIsClipping = false, bool bIsNeedAnalyzeLine = false) - { - m_oPath.ClearNoAttack(); - - CDoubleBounds oBounds; - - if (!bIsNeedAnalyzeLine) - { - unsigned int lSize = m_lCoordsSizeCur; - for (unsigned int i = 0; i < lSize; i += 2) - { - if (bIsClipping) - { - oBounds.CheckPoint(m_pCoordsArray[i], m_pCoordsArray[i + 1]); - } - - m_pCoordsArray[i] *= m_dCoordsScaleX; - m_pCoordsArray[i + 1] *= m_dCoordsScaleY; - } - } - else - { - if (!bIsClipping && m_lPathTypesSizeCur <= 4 && !m_bIsCurveToExist) - { - unsigned int lSize = m_lCoordsSizeCur; - for (unsigned int i = 0; i < lSize; i += 2) - { - m_pCoordsArray[i] *= m_dCoordsScaleX; - m_pCoordsArray[i + 1] *= m_dCoordsScaleY; - } - - switch (m_lPathTypesSizeCur) - { - case 2: - { - if (0 == m_pPathTypes[0] && 1 == m_pPathTypes[1]) - { - m_oPath.AddSize(60); - m_oPath.AddCharNoCheck('M'); - m_oPath.AddSpaceNoCheck(); - - m_oPath.AddIntNoCheckDel10(round(10 * m_pCoordsArray[0])); - m_oPath.AddCharNoCheck(','); - m_oPath.AddIntNoCheckDel10(round(10 * m_pCoordsArray[1])); - m_oPath.AddSpaceNoCheck(); - - m_oPath.AddCharNoCheck('L'); - m_oPath.AddSpaceNoCheck(); - - m_oPath.AddIntNoCheckDel10(round(10 * m_pCoordsArray[2])); - m_oPath.AddCharNoCheck(','); - m_oPath.AddIntNoCheckDel10(round(10 * m_pCoordsArray[3])); - m_oPath.AddSpaceNoCheck(); - return true; - } - break; - } - case 3: - { - if (0 == m_pPathTypes[0] && 1 == m_pPathTypes[1]) - { - if (3 == m_pPathTypes[2]) - { - m_oPath.AddSize(60); - m_oPath.AddCharNoCheck('M'); - m_oPath.AddSpaceNoCheck(); - - m_oPath.AddIntNoCheckDel10(round(10 * m_pCoordsArray[0])); - m_oPath.AddCharNoCheck(','); - m_oPath.AddIntNoCheckDel10(round(10 * m_pCoordsArray[1])); - m_oPath.AddSpaceNoCheck(); - - m_oPath.AddCharNoCheck('L'); - m_oPath.AddSpaceNoCheck(); - - m_oPath.AddIntNoCheckDel10(round(10 * m_pCoordsArray[2])); - m_oPath.AddCharNoCheck(','); - m_oPath.AddIntNoCheckDel10(round(10 * m_pCoordsArray[3])); - m_oPath.AddSpaceNoCheck(); - return true; - } - else - { - if ((fabs(m_pCoordsArray[4] - m_pCoordsArray[0]) < 0.2) && - (fabs(m_pCoordsArray[5] - m_pCoordsArray[1]) < 0.2)) - { - m_oPath.AddSize(60); - m_oPath.AddCharNoCheck('M'); - m_oPath.AddSpaceNoCheck(); - - m_oPath.AddIntNoCheckDel10(round(10 * m_pCoordsArray[0])); - m_oPath.AddCharNoCheck(','); - m_oPath.AddIntNoCheckDel10(round(10 * m_pCoordsArray[1])); - m_oPath.AddSpaceNoCheck(); - - m_oPath.AddCharNoCheck('L'); - m_oPath.AddSpaceNoCheck(); - - m_oPath.AddIntNoCheckDel10(round(10 * m_pCoordsArray[2])); - m_oPath.AddCharNoCheck(','); - m_oPath.AddIntNoCheckDel10(round(10 * m_pCoordsArray[3])); - m_oPath.AddSpaceNoCheck(); - return true; - } - else if ((fabs(m_pCoordsArray[2] - m_pCoordsArray[0]) < 0.2) && - (fabs(m_pCoordsArray[3] - m_pCoordsArray[1]) < 0.2)) - { - m_oPath.AddSize(60); - m_oPath.AddCharNoCheck('M'); - m_oPath.AddSpaceNoCheck(); - - m_oPath.AddIntNoCheckDel10(round(10 * m_pCoordsArray[0])); - m_oPath.AddCharNoCheck(','); - m_oPath.AddIntNoCheckDel10(round(10 * m_pCoordsArray[1])); - m_oPath.AddSpaceNoCheck(); - - m_oPath.AddCharNoCheck('L'); - m_oPath.AddSpaceNoCheck(); - - m_oPath.AddIntNoCheckDel10(round(10 * m_pCoordsArray[4])); - m_oPath.AddCharNoCheck(','); - m_oPath.AddIntNoCheckDel10(round(10 * m_pCoordsArray[5])); - m_oPath.AddSpaceNoCheck(); - return true; - } - } - } - break; - } - case 4: - { - if (0 == m_pPathTypes[0] && 1 == m_pPathTypes[1] && 1 == m_pPathTypes[2]) - { - if ((fabs(m_pCoordsArray[4] - m_pCoordsArray[0]) < 0.2) && - (fabs(m_pCoordsArray[5] - m_pCoordsArray[1]) < 0.2)) - { - if (3 == m_pPathTypes[3]) - { - m_oPath.AddSize(60); - m_oPath.AddCharNoCheck('M'); - m_oPath.AddSpaceNoCheck(); - - m_oPath.AddIntNoCheckDel10(round(10 * m_pCoordsArray[0])); - m_oPath.AddCharNoCheck(','); - m_oPath.AddIntNoCheckDel10(round(10 * m_pCoordsArray[1])); - m_oPath.AddSpaceNoCheck(); - - m_oPath.AddCharNoCheck('L'); - m_oPath.AddSpaceNoCheck(); - - m_oPath.AddIntNoCheckDel10(round(10 * m_pCoordsArray[2])); - m_oPath.AddCharNoCheck(','); - m_oPath.AddIntNoCheckDel10(round(10 * m_pCoordsArray[3])); - m_oPath.AddSpaceNoCheck(); - return true; - } - else if (1 == m_pPathTypes[3] && ((fabs(m_pCoordsArray[6] - m_pCoordsArray[2]) < 0.2) && - (fabs(m_pCoordsArray[7] - m_pCoordsArray[3]) < 0.2))) - { - m_oPath.AddSize(60); - m_oPath.AddCharNoCheck('M'); - m_oPath.AddSpaceNoCheck(); - - m_oPath.AddIntNoCheckDel10(round(10 * m_pCoordsArray[0])); - m_oPath.AddCharNoCheck(','); - m_oPath.AddIntNoCheckDel10(round(10 * m_pCoordsArray[1])); - m_oPath.AddSpaceNoCheck(); - - m_oPath.AddCharNoCheck('L'); - m_oPath.AddSpaceNoCheck(); - - m_oPath.AddIntNoCheckDel10(round(10 * m_pCoordsArray[2])); - m_oPath.AddCharNoCheck(','); - m_oPath.AddIntNoCheckDel10(round(10 * m_pCoordsArray[3])); - m_oPath.AddSpaceNoCheck(); - return true; - } - } - else if ((fabs(m_pCoordsArray[2] - m_pCoordsArray[0]) < 0.2) && - (fabs(m_pCoordsArray[3] - m_pCoordsArray[1]) < 0.2)) - { - if (3 == m_pPathTypes[3]) - { - m_oPath.AddSize(60); - m_oPath.AddCharNoCheck('M'); - m_oPath.AddSpaceNoCheck(); - - m_oPath.AddIntNoCheckDel10(round(10 * m_pCoordsArray[0])); - m_oPath.AddCharNoCheck(','); - m_oPath.AddIntNoCheckDel10(round(10 * m_pCoordsArray[1])); - m_oPath.AddSpaceNoCheck(); - - m_oPath.AddCharNoCheck('L'); - m_oPath.AddSpaceNoCheck(); - - m_oPath.AddIntNoCheckDel10(round(10 * m_pCoordsArray[4])); - m_oPath.AddCharNoCheck(','); - m_oPath.AddIntNoCheckDel10(round(10 * m_pCoordsArray[5])); - m_oPath.AddSpaceNoCheck(); - return true; - } - else if (1 == m_pPathTypes[3] && ((fabs(m_pCoordsArray[6] - m_pCoordsArray[2]) < 0.2) && - (fabs(m_pCoordsArray[7] - m_pCoordsArray[3]) < 0.2))) - { - m_oPath.AddSize(60); - m_oPath.AddCharNoCheck('M'); - m_oPath.AddSpaceNoCheck(); - - m_oPath.AddIntNoCheckDel10(round(10 * m_pCoordsArray[0])); - m_oPath.AddCharNoCheck(','); - m_oPath.AddIntNoCheckDel10(round(10 * m_pCoordsArray[1])); - m_oPath.AddSpaceNoCheck(); - - m_oPath.AddCharNoCheck('L'); - m_oPath.AddSpaceNoCheck(); - - m_oPath.AddIntNoCheckDel10(round(10 * m_pCoordsArray[4])); - m_oPath.AddCharNoCheck(','); - m_oPath.AddIntNoCheckDel10(round(10 * m_pCoordsArray[5])); - m_oPath.AddSpaceNoCheck(); - return true; - } - } - } - break; - } - default: - break; - } - } - else - { - unsigned int lSize = m_lCoordsSizeCur; - for (unsigned int i = 0; i < lSize; i += 2) - { - if (bIsClipping) - { - oBounds.CheckPoint(m_pCoordsArray[i], m_pCoordsArray[i + 1]); - } - - m_pCoordsArray[i] *= m_dCoordsScaleX; - m_pCoordsArray[i + 1] *= m_dCoordsScaleY; - } - } - } - - if (bIsClipping) - m_oTextClipBounds.Intersect(oBounds); - - unsigned int lCurrentCoord = 0; - for (unsigned int nCommand = 0; nCommand < m_lPathTypesSizeCur; ++nCommand) - { - switch (m_pPathTypes[nCommand]) - { - case 0: - { - m_oPath.AddSize(30); - m_oPath.AddCharNoCheck('M'); - m_oPath.AddSpaceNoCheck(); - - m_oPath.AddIntNoCheckDel10(round(10 * m_pCoordsArray[lCurrentCoord++])); - m_oPath.AddCharNoCheck(','); - m_oPath.AddIntNoCheckDel10(round(10 * m_pCoordsArray[lCurrentCoord++])); - m_oPath.AddSpaceNoCheck(); - break; - } - case 1: - { - m_oPath.AddSize(30); - m_oPath.AddCharNoCheck('L'); - m_oPath.AddSpaceNoCheck(); - - m_oPath.AddIntNoCheckDel10(round(10 * m_pCoordsArray[lCurrentCoord++])); - m_oPath.AddCharNoCheck(','); - m_oPath.AddIntNoCheckDel10(round(10 * m_pCoordsArray[lCurrentCoord++])); - m_oPath.AddSpaceNoCheck(); - break; - } - case 2: - { - m_oPath.AddSize(80); - m_oPath.AddCharNoCheck('C'); - m_oPath.AddSpaceNoCheck(); - - m_oPath.AddIntNoCheckDel10(round(10 * m_pCoordsArray[lCurrentCoord++])); - m_oPath.AddCharNoCheck(','); - m_oPath.AddIntNoCheckDel10(round(10 * m_pCoordsArray[lCurrentCoord++])); - m_oPath.AddSpaceNoCheck(); - - m_oPath.AddIntNoCheckDel10(round(10 * m_pCoordsArray[lCurrentCoord++])); - m_oPath.AddCharNoCheck(','); - m_oPath.AddIntNoCheckDel10(round(10 * m_pCoordsArray[lCurrentCoord++])); - m_oPath.AddSpaceNoCheck(); - - m_oPath.AddIntNoCheckDel10(round(10 * m_pCoordsArray[lCurrentCoord++])); - m_oPath.AddCharNoCheck(','); - m_oPath.AddIntNoCheckDel10(round(10 * m_pCoordsArray[lCurrentCoord++])); - m_oPath.AddSpaceNoCheck(); - break; - } - case 3: - { - m_oPath.AddSize(2); - m_oPath.AddCharNoCheck('Z'); - m_oPath.AddSpaceNoCheck(); - break; - } - default: - break; - } - } - - if (bIsClipping) - { - m_oClipMetafile.WriteCommandType(CMetafile::ctPathCommandStart); - m_oClipMetafile.WriteLONG(CMetafile::ctBeginCommand, c_nClipType); - - lCurrentCoord = 0; - for (ULONG nCommand = 0; nCommand < m_lPathTypesSizeCur; ++nCommand) - { - switch (m_pPathTypes[nCommand]) - { - case 0: - { - m_oClipMetafile.WriteCommandType(CMetafile::ctPathCommandMoveTo); - m_oClipMetafile.WriteDouble(m_pCoordsArray[lCurrentCoord++] / m_dCoordsScaleX); - m_oClipMetafile.WriteDouble(m_pCoordsArray[lCurrentCoord++] / m_dCoordsScaleY); - break; - } - case 1: - { - m_oClipMetafile.WriteCommandType(CMetafile::ctPathCommandLineTo); - m_oClipMetafile.WriteDouble(m_pCoordsArray[lCurrentCoord++] / m_dCoordsScaleX); - m_oClipMetafile.WriteDouble(m_pCoordsArray[lCurrentCoord++] / m_dCoordsScaleY); - break; - } - case 2: - { - m_oClipMetafile.WriteCommandType(CMetafile::ctPathCommandCurveTo); - m_oClipMetafile.WriteDouble(m_pCoordsArray[lCurrentCoord++] / m_dCoordsScaleX); - m_oClipMetafile.WriteDouble(m_pCoordsArray[lCurrentCoord++] / m_dCoordsScaleY); - m_oClipMetafile.WriteDouble(m_pCoordsArray[lCurrentCoord++] / m_dCoordsScaleX); - m_oClipMetafile.WriteDouble(m_pCoordsArray[lCurrentCoord++] / m_dCoordsScaleY); - m_oClipMetafile.WriteDouble(m_pCoordsArray[lCurrentCoord++] / m_dCoordsScaleX); - m_oClipMetafile.WriteDouble(m_pCoordsArray[lCurrentCoord++] / m_dCoordsScaleY); - break; - } - case 3: - { - m_oClipMetafile.WriteCommandType(CMetafile::ctPathCommandClose); - break; - } - default: - break; - } - } - - m_oClipMetafile.WriteLONG(CMetafile::ctEndCommand, c_nClipType2); - m_oClipMetafile.WriteLONG(m_lClipMode); - m_oClipMetafile.WriteCommandType(CMetafile::ctPathCommandEnd); - } - - return false; - } - - LONG WriteTempClip() - { - LONG nRet = m_oClipMetafile.GetPosition(); - - m_oClipMetafile.WriteCommandType(CMetafile::ctPathCommandStart); - m_oClipMetafile.WriteLONG(CMetafile::ctBeginCommand, c_nClipType); - - LONG lCurrentCoord = 0; - for (ULONG nCommand = 0; nCommand < m_lPathTypesSizeCur; ++nCommand) - { - switch (m_pPathTypes[nCommand]) - { - case 0: - { - m_oClipMetafile.WriteCommandType(CMetafile::ctPathCommandMoveTo); - m_oClipMetafile.WriteDouble(m_pCoordsArray[lCurrentCoord++]); - m_oClipMetafile.WriteDouble(m_pCoordsArray[lCurrentCoord++]); - break; - } - case 1: - { - m_oClipMetafile.WriteCommandType(CMetafile::ctPathCommandLineTo); - m_oClipMetafile.WriteDouble(m_pCoordsArray[lCurrentCoord++]); - m_oClipMetafile.WriteDouble(m_pCoordsArray[lCurrentCoord++]); - break; - } - case 2: - { - m_oClipMetafile.WriteCommandType(CMetafile::ctPathCommandCurveTo); - m_oClipMetafile.WriteDouble(m_pCoordsArray[lCurrentCoord++]); - m_oClipMetafile.WriteDouble(m_pCoordsArray[lCurrentCoord++]); - m_oClipMetafile.WriteDouble(m_pCoordsArray[lCurrentCoord++]); - m_oClipMetafile.WriteDouble(m_pCoordsArray[lCurrentCoord++]); - m_oClipMetafile.WriteDouble(m_pCoordsArray[lCurrentCoord++]); - m_oClipMetafile.WriteDouble(m_pCoordsArray[lCurrentCoord++]); - break; - } - case 3: - { - m_oClipMetafile.WriteCommandType(CMetafile::ctPathCommandClose); - break; - } - default: - break; - } - } - - m_oClipMetafile.WriteLONG(CMetafile::ctEndCommand, c_nClipType2); - m_oClipMetafile.WriteLONG(m_lClipMode); - m_oClipMetafile.WriteCommandType(CMetafile::ctPathCommandEnd); - - return nRet; - } - -#ifdef USE_SIMPLE_GRAPHICS_NOSVG - - void WriteToPathToSimpleVector() - { - if (m_lPathTypesSizeCur <= 4 && !m_bIsCurveToExist) - { - switch (m_lPathTypesSizeCur) - { - case 2: - { - if (0 == m_pPathTypes[0] && 1 == m_pPathTypes[1]) - { - m_oVectors.WriteCommandType(CMetafile::ctPathCommandMoveTo); - m_oVectors.WriteDouble(m_pCoordsArray[0]); - m_oVectors.WriteDouble(m_pCoordsArray[1]); - - m_oVectors.WriteCommandType(CMetafile::ctPathCommandLineTo); - m_oVectors.WriteDouble(m_pCoordsArray[2]); - m_oVectors.WriteDouble(m_pCoordsArray[3]); - return; - } - break; - } - case 3: - { - if (0 == m_pPathTypes[0] && 1 == m_pPathTypes[1]) - { - if (3 == m_pPathTypes[2]) - { - m_oVectors.WriteCommandType(CMetafile::ctPathCommandMoveTo); - m_oVectors.WriteDouble(m_pCoordsArray[0]); - m_oVectors.WriteDouble(m_pCoordsArray[1]); - - m_oVectors.WriteCommandType(CMetafile::ctPathCommandLineTo); - m_oVectors.WriteDouble(m_pCoordsArray[2]); - m_oVectors.WriteDouble(m_pCoordsArray[3]); - return; - } - else - { - if ((fabs(m_pCoordsArray[4] - m_pCoordsArray[0]) < 0.2) && - (fabs(m_pCoordsArray[5] - m_pCoordsArray[1]) < 0.2)) - { - m_oVectors.WriteCommandType(CMetafile::ctPathCommandMoveTo); - m_oVectors.WriteDouble(m_pCoordsArray[0]); - m_oVectors.WriteDouble(m_pCoordsArray[1]); - - m_oVectors.WriteCommandType(CMetafile::ctPathCommandLineTo); - m_oVectors.WriteDouble(m_pCoordsArray[2]); - m_oVectors.WriteDouble(m_pCoordsArray[3]); - return; - } - else if ((fabs(m_pCoordsArray[2] - m_pCoordsArray[0]) < 0.2) && - (fabs(m_pCoordsArray[3] - m_pCoordsArray[1]) < 0.2)) - { - m_oVectors.WriteCommandType(CMetafile::ctPathCommandMoveTo); - m_oVectors.WriteDouble(m_pCoordsArray[0]); - m_oVectors.WriteDouble(m_pCoordsArray[1]); - - m_oVectors.WriteCommandType(CMetafile::ctPathCommandLineTo); - m_oVectors.WriteDouble(m_pCoordsArray[4]); - m_oVectors.WriteDouble(m_pCoordsArray[5]); - return; - } - } - } - break; - } - case 4: - { - if (0 == m_pPathTypes[0] && 1 == m_pPathTypes[1] && 1 == m_pPathTypes[2]) - { - if ((fabs(m_pCoordsArray[4] - m_pCoordsArray[0]) < 0.2) && - (fabs(m_pCoordsArray[5] - m_pCoordsArray[1]) < 0.2)) - { - if (3 == m_pPathTypes[3]) - { - m_oVectors.WriteCommandType(CMetafile::ctPathCommandMoveTo); - m_oVectors.WriteDouble(m_pCoordsArray[0]); - m_oVectors.WriteDouble(m_pCoordsArray[1]); - - m_oVectors.WriteCommandType(CMetafile::ctPathCommandLineTo); - m_oVectors.WriteDouble(m_pCoordsArray[2]); - m_oVectors.WriteDouble(m_pCoordsArray[3]); - return; - } - else if (1 == m_pPathTypes[3] && ((fabs(m_pCoordsArray[6] - m_pCoordsArray[2]) < 0.2) && - (fabs(m_pCoordsArray[7] - m_pCoordsArray[3]) < 0.2))) - { - m_oVectors.WriteCommandType(CMetafile::ctPathCommandMoveTo); - m_oVectors.WriteDouble(m_pCoordsArray[0]); - m_oVectors.WriteDouble(m_pCoordsArray[1]); - - m_oVectors.WriteCommandType(CMetafile::ctPathCommandLineTo); - m_oVectors.WriteDouble(m_pCoordsArray[2]); - m_oVectors.WriteDouble(m_pCoordsArray[3]); - return; - } - } - else if ((fabs(m_pCoordsArray[2] - m_pCoordsArray[0]) < 0.2) && - (fabs(m_pCoordsArray[3] - m_pCoordsArray[1]) < 0.2)) - { - if (3 == m_pPathTypes[3]) - { - m_oVectors.WriteCommandType(CMetafile::ctPathCommandMoveTo); - m_oVectors.WriteDouble(m_pCoordsArray[0]); - m_oVectors.WriteDouble(m_pCoordsArray[1]); - - m_oVectors.WriteCommandType(CMetafile::ctPathCommandLineTo); - m_oVectors.WriteDouble(m_pCoordsArray[4]); - m_oVectors.WriteDouble(m_pCoordsArray[5]); - return; - } - else if (1 == m_pPathTypes[3] && ((fabs(m_pCoordsArray[6] - m_pCoordsArray[2]) < 0.2) && - (fabs(m_pCoordsArray[7] - m_pCoordsArray[3]) < 0.2))) - { - m_oVectors.WriteCommandType(CMetafile::ctPathCommandMoveTo); - m_oVectors.WriteDouble(m_pCoordsArray[0]); - m_oVectors.WriteDouble(m_pCoordsArray[1]); - - m_oVectors.WriteCommandType(CMetafile::ctPathCommandLineTo); - m_oVectors.WriteDouble(m_pCoordsArray[4]); - m_oVectors.WriteDouble(m_pCoordsArray[5]); - return; - } - } - } - break; - } - default: - break; - } - } - - unsigned int lCurrentCoord = 0; - for (unsigned int nCommand = 0; nCommand < m_lPathTypesSizeCur; ++nCommand) - { - switch (m_pPathTypes[nCommand]) - { - case 0: - { - m_oVectors.WriteCommandType(CMetafile::ctPathCommandMoveTo); - m_oVectors.WriteDouble(m_pCoordsArray[lCurrentCoord++]); - m_oVectors.WriteDouble(m_pCoordsArray[lCurrentCoord++]); - break; - } - case 1: - { - m_oVectors.WriteCommandType(CMetafile::ctPathCommandLineTo); - m_oVectors.WriteDouble(m_pCoordsArray[lCurrentCoord++]); - m_oVectors.WriteDouble(m_pCoordsArray[lCurrentCoord++]); - break; - } - case 2: - { - m_oVectors.WriteCommandType(CMetafile::ctPathCommandCurveTo); - m_oVectors.WriteDouble(m_pCoordsArray[lCurrentCoord++]); - m_oVectors.WriteDouble(m_pCoordsArray[lCurrentCoord++]); - m_oVectors.WriteDouble(m_pCoordsArray[lCurrentCoord++]); - m_oVectors.WriteDouble(m_pCoordsArray[lCurrentCoord++]); - m_oVectors.WriteDouble(m_pCoordsArray[lCurrentCoord++]); - m_oVectors.WriteDouble(m_pCoordsArray[lCurrentCoord++]); - break; - } - case 3: - { - m_oVectors.WriteCommandType(CMetafile::ctPathCommandClose); - break; - } - default: - break; - } - } - } - -#endif - - void CheckPathTextRect(CDoubleBounds& oBounds) - { - unsigned int lSize = m_lCoordsSizeCur; - for (unsigned int i = 0; i < lSize; i += 2) - { - oBounds.CheckPoint(m_pCoordsArray[i] * m_dCoordsScaleX, m_pCoordsArray[i + 1] * m_dCoordsScaleY); - } - } - - inline void NewSVG() - { - m_oDocument.SetCurSize(m_lEmtyDocChecker); - -#ifdef USE_SIMPLE_GRAPHICS_NOSVG - - if (m_bIsSimpleSetupBrush && !m_bIsSimpleGraphics) - { - m_pLastBrush->Color1 = m_lBrushColorOld; - m_pLastBrush->Alpha1 = m_lBrushAlphaOld; - } - - m_oVectors.ClearNoAttack(); - m_bIsSimpleGraphics = true; - m_bIsSimpleSetupBrush = false; - -#endif - } - }; -} - -#endif // _ASC_HTMLRENDERER_SVGWRITER2_H_ diff --git a/HtmlRenderer/src/Text.h b/HtmlRenderer/src/Text.h deleted file mode 100644 index 47359e13864..00000000000 --- a/HtmlRenderer/src/Text.h +++ /dev/null @@ -1,975 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2023 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _ASC_HTMLRENDERER_TEXT_H_ -#define _ASC_HTMLRENDERER_TEXT_H_ - -#include "FontManager.h" -#include "../../Common/OfficeFileFormats.h" -#include "Meta.h" - -#ifdef min -#undef min -#endif -#include - -namespace NSHtmlRenderer -{ - class CHChar - { - public: - int unicode; // юникодное значение - int gid; // индекс глифа в файле - double x; // сдвиг по baseline - double width; // ширина символа (сдвиг до след буквы) - double* matrix; // матрица преобразования (!!! без сдвига) - - public: - CHChar() - { - unicode = 0; - gid = 0; - width = 0; - matrix = NULL; - } - CHChar(const CHChar& oSrc) - { - *this = oSrc; - } - CHChar& operator=(const CHChar& oSrc) - { - unicode = oSrc.unicode; - gid = oSrc.gid; - width = oSrc.width; - matrix = NULL; - if (NULL != oSrc.matrix) - { - matrix = new double[4]; - memcpy(matrix, oSrc.matrix, 4 * sizeof(double)); - } - return *this; - } - ~CHChar() - { - RELEASEARRAYOBJECTS(matrix); - } - - inline void Clear() - { - unicode = 0; - gid = 0; - width = 0; - - RELEASEARRAYOBJECTS(matrix); - } - }; - - class CHLine - { - public: - double m_dAscent; - double m_dDescent; - double m_dX; - double m_dY; - - double m_dEndX; - double m_dEndY; - - // baseline ruler: y = k*x + b - double m_dK; - double m_dB; - double m_ex; - double m_ey; - bool m_bIsConstX; - - // symbols - // не менять на списки. постоянное создание объектов и их удаление - - // плохо влияет на скорость - CHChar* m_pChars; - LONG m_lSizeChars; - LONG m_lCharsTail; - - bool m_bIsSetUpTransform; - double m_sx; - double m_sy; - double m_shx; - double m_shy; - - public: - CHLine() - { - m_dAscent = 0; - m_dDescent = 0; - m_dX = 0; - m_dY = 0; - - m_dK = 0; - m_dB = 0; - m_bIsConstX = false; - - m_ex = 0; - m_ey = 0; - - m_lSizeChars = 1000; - m_lCharsTail = 0; - m_pChars = new CHChar[m_lSizeChars]; - - m_bIsSetUpTransform = false; - m_sx = 1; - m_sy = 1; - m_shx = 0; - m_shy = 0; - } - CHLine& operator=(const CHLine& oLine) - { - m_dAscent = oLine.m_dAscent; - m_dDescent = oLine.m_dDescent; - m_dX = oLine.m_dX; - m_dY = oLine.m_dY; - - m_dK = oLine.m_dK; - m_dB = oLine.m_dB; - - m_lSizeChars = oLine.m_lSizeChars; - m_lCharsTail = oLine.m_lCharsTail; - - RELEASEARRAYOBJECTS(m_pChars); - m_pChars = new CHChar[m_lSizeChars]; - - for (LONG i = 0; i < m_lSizeChars; ++i) - m_pChars[i] = oLine.m_pChars[i]; - - m_bIsSetUpTransform = oLine.m_bIsSetUpTransform; - m_sx = oLine.m_sx; - m_sy = oLine.m_sy; - m_shx = oLine.m_shx; - m_shy = oLine.m_shy; - - return *this; - } - ~CHLine() - { - RELEASEARRAYOBJECTS(m_pChars); - } - - inline void Clear() - { - m_dAscent = 0; - m_dDescent = 0; - m_dX = 0; - m_dY = 0; - - m_dK = 0; - m_dB = 0; - m_bIsConstX = false; - - m_ex = 0; - m_ey = 0; - - m_lCharsTail = 0; - - m_bIsSetUpTransform = false; - m_sx = 1; - m_sy = 1; - m_shx = 0; - m_shy = 0; - } - - inline CHChar* AddTail() - { - if (m_lCharsTail >= m_lSizeChars) - { - CHChar* pNews = new CHChar[2 * m_lSizeChars]; - for (LONG i = 0; i < m_lSizeChars; ++i) - { - pNews[i] = m_pChars[i]; - } - - RELEASEARRAYOBJECTS(m_pChars); - m_pChars = pNews; - m_lSizeChars *= 2; - } - - CHChar* pChar = &m_pChars[m_lCharsTail]; - ++m_lCharsTail; - pChar->Clear(); - - return pChar; - } - - inline CHChar* GetTail() - { - if (0 == m_lCharsTail) - return NULL; - - return &m_pChars[m_lCharsTail - 1]; - } - - inline LONG GetCountChars() - { - return m_lCharsTail; - } - }; - - const BYTE g_lfHorizontal = 0x01; - const BYTE g_lfGids = 0x02; - const BYTE g_lfWidth = 0x04; - - class CHFontInfo - { - public: - USHORT m_lAscent; - USHORT m_lDescent; - USHORT m_lLineHeight; - USHORT m_lUnitsPerEm; - - public: - CHFontInfo() - { - m_lAscent = 0; - m_lDescent = 0; - m_lLineHeight = 0; - m_lUnitsPerEm = 0; - } - - CHFontInfo(const CHFontInfo& oSrc) - { - m_lAscent = oSrc.m_lAscent; - m_lDescent = oSrc.m_lDescent; - m_lLineHeight = oSrc.m_lLineHeight; - m_lUnitsPerEm = oSrc.m_lUnitsPerEm; - } - - CHFontInfo& operator=(const CHFontInfo& oSrc) - { - m_lAscent = oSrc.m_lAscent; - m_lDescent = oSrc.m_lDescent; - m_lLineHeight = oSrc.m_lLineHeight; - m_lUnitsPerEm = oSrc.m_lUnitsPerEm; - - return *this; - } - }; - - class CFontMapInfo - { - public: - std::wstring Path; - int FaceIndex; - - public: - CFontMapInfo() - { - Path = L""; - FaceIndex = 0; - } - CFontMapInfo(const CFontMapInfo& oSrc) - { - Path = oSrc.Path; - FaceIndex = oSrc.FaceIndex; - } - CFontMapInfo& operator=(const CFontMapInfo& oSrc) - { - Path = oSrc.Path; - FaceIndex = oSrc.FaceIndex; - - return *this; - } - }; - - class CFontManagerWrapper - { - private: - NSFonts::IFontManager* m_pManager; - public: - CHFontInfo m_oCurrentInfo; - NSStructures::CFont* m_pFont; - - std::map m_mapInfos; - - public: - CFontManagerWrapper() - { - m_pManager = NULL; - } - void Init(NSFonts::IApplicationFonts* pApplicationFonts, int nCacheSize = 0) - { - RELEASEOBJECT(m_pManager); - m_pManager = pApplicationFonts->GenerateFontManager(); - - if (0 != nCacheSize) - { - NSFonts::IFontsCache* pFontCache = NSFonts::NSFontCache::Create(); - pFontCache->SetStreams(pApplicationFonts->GetStreams()); - pFontCache->SetCacheSize(nCacheSize); - m_pManager->SetOwnerCache(pFontCache); - } - } - - virtual ~CFontManagerWrapper() - { - RELEASEOBJECT(m_pManager); - } - - void SetStringGID(INT bGid) - { - m_pManager->SetStringGID(bGid); - } - - public: - inline void LoadCurrentFont(bool bIsAttack, int lFaceIndex = 0) - { - if (m_pFont->Path.empty()) - { - std::wstring sFind = m_pFont->Name + L"__ASC_FONT__" + std::to_wstring(m_pFont->GetStyle()); - - std::map::const_iterator pPair = m_mapInfos.find(sFind); - if (m_mapInfos.end() != pPair) - { - if (bIsAttack) - { - LoadFontByName(m_pFont->Name, m_pFont->Size, m_pFont->GetStyle()); - } - else - { - m_oCurrentInfo = pPair->second; - } - } - else - { - LoadFontByName(m_pFont->Name, m_pFont->Size, m_pFont->GetStyle()); - m_mapInfos.insert(std::pair(sFind, m_oCurrentInfo)); - } - } - else - { - std::map::const_iterator pPair = m_mapInfos.find(m_pFont->Path); - if (m_mapInfos.end() != pPair) - { - if (bIsAttack) - { - LoadFontByFile(m_pFont->Path, m_pFont->Size, lFaceIndex); - } - else - { - m_oCurrentInfo = pPair->second; - } - } - else - { - LoadFontByFile(m_pFont->Path, m_pFont->Size, lFaceIndex); - m_mapInfos.insert(std::pair(m_pFont->Path, m_oCurrentInfo)); - } - } - } - - inline void LoadFontByName(const std::wstring& strName, const double& dSize, const LONG& lStyle) - { - m_pManager->LoadFontByName(strName, dSize, lStyle, c_dDpi, c_dDpi); - LoadFontMetrics(); - } - - inline void LoadFontByFile(const std::wstring& strPath, const double& dSize, const int& lFaceIndex) - { - m_pManager->LoadFontFromFile(strPath, lFaceIndex, dSize, c_dDpi, c_dDpi); - LoadFontMetrics(); - } - - public: - - double MeasureString(const unsigned int* symbols, const int& count, double x, double y, double& dBoxX, double& dBoxY, double& dBoxWidth, double& dBoxHeight) - { - dBoxX = 0; - dBoxY = 0; - dBoxWidth = 0; - dBoxHeight = 0; - - if (NULL == m_pManager) - return 0; - - m_pManager->LoadString1(symbols, count, (float)x, (float)y); - - TBBox _box = m_pManager->MeasureString2(); - - dBoxX = (double)(_box.fMinX); - dBoxY = (double)(_box.fMinY); - dBoxWidth = (double)(_box.fMaxX - _box.fMinX); - dBoxHeight = (double)(_box.fMaxY - _box.fMinY); - - if (dBoxWidth < 0) - dBoxWidth = -dBoxWidth; - if (dBoxHeight < 0) - dBoxHeight = -dBoxHeight; - - // переводим в миллиметры - dBoxX *= c_dPixToMM; - dBoxY *= c_dPixToMM; - dBoxWidth *= c_dPixToMM; - dBoxHeight *= c_dPixToMM; - - return dBoxWidth; - } - - public: - void LoadFontMetrics() - { - m_pManager->AfterLoad(); - int lA = m_pManager->GetAscender(); - int lD = m_pManager->GetDescender(); - int lL = m_pManager->GetLineHeight(); - int lU = m_pManager->GetUnitsPerEm(); - - if (lA < 0) - lA = -lA; - if (lD < 0) - lD = -lD; - if (lL < 0) - lL = -lL; - if (lU < 0) - lU = -lU; - - m_oCurrentInfo.m_lAscent = (USHORT)(lA); - m_oCurrentInfo.m_lDescent = (USHORT)(lD); - m_oCurrentInfo.m_lLineHeight = (USHORT)(lL); - m_oCurrentInfo.m_lUnitsPerEm = (USHORT)(lU); - } - }; - - class CHText - { - public: - CFontManagerWrapper m_oFontManager; - - CHLine m_oLine; - CMetafile* m_pMeta; - - NSStructures::CBrush* m_pBrush; - NSStructures::CFont* m_pFont; - - NSStructures::CBrush* m_pLastBrush; - - Aggplus::CMatrix* m_pTransform; - Aggplus::CMatrix* m_pLastTransform; - - CMetafile m_oMeta; - CMetafile* m_pPageMeta; - - double m_dTextSpaceEps; - - LONG m_lCountParagraphs; - LONG m_lCountWords; - LONG m_lCountSymbols; - LONG m_lCountSpaces; - - public: - CHText() : m_oFontManager(), m_oLine() - { - m_dTextSpaceEps = 0.1; - - m_lCountParagraphs = 0; - m_lCountWords = 0; - m_lCountSymbols = 0; - m_lCountSpaces = 0; - } - void Init(NSFonts::IApplicationFonts* pApplicationFonts, int nCacheSize = 0) - { - m_oFontManager.Init(pApplicationFonts, nCacheSize); - } - - void ClearStatistics() - { - m_lCountParagraphs = 0; - m_lCountWords = 0; - m_lCountSymbols = 0; - m_lCountSpaces = 0; - } - - template - void SetParams(T writer) - { - m_oFontManager.m_pFont = writer->m_pFont; - - m_pBrush = writer->m_pBrush; - m_pFont = writer->m_pFont; - - m_pLastBrush = &writer->m_oLastBrush; - - m_pTransform = writer->m_pTransform; - m_pLastTransform = &writer->m_oLastTransform; - - m_pPageMeta = &writer->m_oPage; - - switch (writer->m_lSrcFileType) - { - case AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_PDF: - case AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_XPS: - break; - default: - m_dTextSpaceEps = 0.1; - break; - } - } - - ~CHText() - { - } - - void NewPage() - { - m_oMeta.ClearNoAttack(); - } - void ClosePage() - { - LONG nCount = m_oLine.GetCountChars(); - if (0 != nCount) - DumpLine(); - } - - public: - template - void CommandText(const int* pUnicodes, const int* pGids, const int& nCount, - const double& x, const double& y, const double& width, const double& height, bool bIsDumpFont, T writer) - { - // 1) сначала определяем точку отсчета и направление baseline - double _x1 = x; - double _y1 = y; - double _x2 = x + 1; - double _y2 = y; - m_pTransform->TransformPoint(_x1, _y1); - m_pTransform->TransformPoint(_x2, _y2); - - double _k = 0; - double _b = 0; - bool _isConstX = false; - if (fabs(_x1 - _x2) < 0.001) - { - _isConstX = true; - _b = _x1; - } - else - { - _k = (_y1 - _y2) / (_x1 - _x2); - _b = _y1 - _k * _x1; - } - - double dAbsVec = sqrt((_x1 - _x2) * (_x1 - _x2) + (_y1 - _y2) * (_y1 - _y2)); - if (dAbsVec == 0) - dAbsVec = 1; - - LONG nCountChars = m_oLine.GetCountChars(); - - bool bIsNewLine = true; - - if (0 != nCountChars) - { - if (_isConstX && m_oLine.m_bIsConstX && fabs(_b - m_oLine.m_dB) < 0.001) - bIsNewLine = false; - else if (!_isConstX && !m_oLine.m_bIsConstX && fabs(_k - m_oLine.m_dK) < 0.001 && fabs(_b - m_oLine.m_dB) < 0.001) - bIsNewLine = false; - } - - if (bIsNewLine && (0 != nCountChars)) - { - // не совпала baseline. поэтому просто скидываем линию в поток - DumpLine(); - } - - // теперь нужно определить сдвиг по baseline относительно destination точки - nCountChars = m_oLine.GetCountChars(); - double dOffsetX = 0; - if (0 == nCountChars) - { - m_oLine.m_bIsConstX = _isConstX; - m_oLine.m_dK = _k; - m_oLine.m_dB = _b; - - m_oLine.m_dX = _x1; - m_oLine.m_dY = _y1; - - m_oLine.m_ex = (_x2 - _x1) / dAbsVec; - m_oLine.m_ey = (_y2 - _y1) / dAbsVec; - - m_oLine.m_dEndX = _x1; - m_oLine.m_dEndY = _y1; - } - else - { - double sx = _x1 - m_oLine.m_dEndX; - double sy = _y1 - m_oLine.m_dEndY; - double len = sqrt(sx*sx + sy*sy); - - if (sx*m_oLine.m_ex >= 0 && sy*m_oLine.m_ey >= 0) - { - // продолжаем линию - dOffsetX = len; - - // теперь посмотрим, может быть нужно вставить пробел?? - CHChar* pLastChar = m_oLine.GetTail(); - if (dOffsetX > (pLastChar->width + 0.5)) - { - // вставляем пробел. Пробел у нас будет не совсем пробел. А специфический - CHChar* pSpaceChar = m_oLine.AddTail(); - pSpaceChar->x = pLastChar->width; - pSpaceChar->width = dOffsetX - pLastChar->width; - pSpaceChar->unicode = 0xFFFF; - pSpaceChar->gid = 0xFFFF; - dOffsetX -= pLastChar->width; - - m_oMeta.WriteBYTE(0); - } - } - else - { - // буква сдвинута влево относительно предыдущей буквы - // на такую ситуацию реагируем просто - просто начинаем новую линию, - // предварительно сбросив старую - DumpLine(); - - m_oLine.m_bIsConstX = _isConstX; - - m_oLine.m_dX = _x1; - m_oLine.m_dY = _y1; - - m_oLine.m_dK = _k; - m_oLine.m_dB = _b; - - m_oLine.m_ex = (_x2 - _x1) / dAbsVec; - m_oLine.m_ey = (_y2 - _y1) / dAbsVec; - } - - m_oLine.m_dEndX = _x1; - m_oLine.m_dEndY = _y1; - } - - // смотрим, совпадает ли главная часть матрицы. - bool bIsTransform = !IsEqualMain(m_pLastTransform, m_pTransform); - if (bIsTransform) - bIsDumpFont = true; - - bool bIsColor = ((m_pBrush->Color1 != m_pLastBrush->Color1) || (m_pBrush->Alpha1 != m_pLastBrush->Alpha1)); - - BYTE nLenMetaCommands = 0; - if (bIsColor) - nLenMetaCommands += 5; - if (bIsTransform) - nLenMetaCommands += 17; - if (bIsDumpFont) - nLenMetaCommands += 13; - - m_oMeta.WriteBYTE(nLenMetaCommands); - - double _dumpSize = writer->m_dCurrentFontSize; - double _dumpMtx[4]; - _dumpMtx[0] = m_pTransform->sx(); - _dumpMtx[1] = m_pTransform->shy(); - _dumpMtx[2] = m_pTransform->shx(); - _dumpMtx[3] = m_pTransform->sy(); - - double dTextScale = std::min( sqrt( _dumpMtx[2] * _dumpMtx[2] + _dumpMtx[3] * _dumpMtx[3] ), sqrt( _dumpMtx[0] * _dumpMtx[0] + _dumpMtx[1] * _dumpMtx[1] ) ); - - if ((_dumpSize < 0.1 && dTextScale > 10) || (_dumpSize > 10 && dTextScale < 0.1)) - { - _dumpSize *= dTextScale; - - _dumpMtx[0] /= dTextScale; - _dumpMtx[1] /= dTextScale; - _dumpMtx[2] /= dTextScale; - _dumpMtx[3] /= dTextScale; - } - - if (bIsDumpFont) - { - m_oMeta.WriteCommandType(CMetafile::ctFontName); - m_oMeta.WriteLONG(writer->m_lCurrentFont); - m_oMeta.WriteLONG(writer->m_pFont->GetStyle()); - m_oMeta.WriteDouble(_dumpSize/*writer->m_dCurrentFontSize*/); - } - if (bIsTransform) - { - m_pLastTransform->SetElements(m_pTransform->sx(), m_pTransform->shy(), m_pTransform->shx(), m_pTransform->sy(), m_pLastTransform->tx(), m_pLastTransform->ty()); - - m_oLine.m_bIsSetUpTransform = true; - m_oLine.m_sx = m_pTransform->sx(); - m_oLine.m_shx = m_pTransform->shx(); - m_oLine.m_shy = m_pTransform->shy(); - m_oLine.m_sy = m_pTransform->sy(); - - m_oMeta.WriteBYTE(CMetafile::ctCommandTextTransform); - //m_oMeta.WriteDouble(_dst->sx); - //m_oMeta.WriteDouble(_dst->shy); - //m_oMeta.WriteDouble(_dst->shx); - //m_oMeta.WriteDouble(_dst->sy); - - m_oMeta.WriteDouble(_dumpMtx[0]); - m_oMeta.WriteDouble(_dumpMtx[1]); - m_oMeta.WriteDouble(_dumpMtx[2]); - m_oMeta.WriteDouble(_dumpMtx[3]); - } - if (bIsColor) - { - m_pLastBrush->Color1 = m_pBrush->Color1; - m_pLastBrush->Alpha1 = m_pBrush->Alpha1; - - m_oMeta.WriteBYTE(CMetafile::ctBrushColor1); - - LONG lBGR = m_pBrush->Color1; - m_oMeta.WriteBYTE((BYTE)(lBGR & 0xFF)); - m_oMeta.WriteBYTE((BYTE)((lBGR >> 8) & 0xFF)); - m_oMeta.WriteBYTE((BYTE)((lBGR >> 16) & 0xFF)); - m_oMeta.WriteBYTE((BYTE)m_pBrush->Alpha1); - } - - // все, baseline установлен. теперь просто продолжаем линию - LONG lTextLen = nCount; - bool bIsLoadFontAttack = true; - - // плохие значения приходят из пдф - /* - if (1 == lTextLen && 0 <= width) - bIsLoadFontAttack = false; - */ - - if (bIsDumpFont) - m_oFontManager.LoadCurrentFont(bIsLoadFontAttack); - - double dKoef = m_oFontManager.m_pFont->Size * 25.4 / (72 * m_oFontManager.m_oCurrentInfo.m_lUnitsPerEm); - double dKoefMetr = dAbsVec; - double dAscender = m_oFontManager.m_oCurrentInfo.m_lAscent * dKoef * dKoefMetr; - double dDescender = m_oFontManager.m_oCurrentInfo.m_lDescent * dKoef * dKoefMetr; - - if (m_oLine.m_dAscent < dAscender) - m_oLine.m_dAscent = dAscender; - if (m_oLine.m_dDescent < dDescender) - m_oLine.m_dDescent = dDescender; - - if (!bIsLoadFontAttack) - { - CHChar* pChar = m_oLine.AddTail(); - - pChar->unicode = pUnicodes[0]; - pChar->gid = (NULL == pGids) ? 0xFFFF : pGids[0]; - pChar->width = width; - pChar->x = dOffsetX; - } - else - { - double dPlusOffset = 0; - - const int* input = NULL; - if (NULL != pGids) - { - input = pGids; - m_oFontManager.SetStringGID(TRUE); - } - else - { - input = pUnicodes; - m_oFontManager.SetStringGID(FALSE); - } - - double dBoxX = 0; - double dBoxY = 0; - double dBoxW = 0; - double dBoxH = 0; - - double dPrevW = dOffsetX; - for (LONG lIndex = 0; lIndex < lTextLen; ++lIndex) - { - double dW = m_oFontManager.MeasureString((const unsigned int*)(input + lIndex), 1, 0, 0, dBoxX, dBoxY, dBoxW, dBoxH); - - CHChar* pChar = m_oLine.AddTail(); - pChar->unicode = pUnicodes[lIndex]; - pChar->gid = (NULL == pGids) ? 0xFFFF : pGids[lIndex]; - - pChar->x = dPrevW; - if (lIndex != 0) - dPlusOffset += dPrevW; - dPrevW = dW; - - pChar->width = dW * dAbsVec; - - if (0 != lIndex) - m_oMeta.WriteBYTE(0); - - if (lIndex == (lTextLen - 1)) - { - m_oLine.m_dEndX += dPlusOffset * m_oLine.m_ex; - m_oLine.m_dEndY += dPlusOffset * m_oLine.m_ey; - } - } - } - } - - void DumpLine() - { - if (m_oLine.m_bIsSetUpTransform) - { - // выставится трансформ!!! - // cравнивать нужно с ним!!! - m_pLastTransform->SetElements(m_oLine.m_sx, m_oLine.m_shy, m_oLine.m_shx, m_oLine.m_sy); - } - - // скидываем линию в поток pMeta - BYTE mask = 0; - if (fabs(m_oLine.m_ex - 1.0) < 0.001 && fabs(m_oLine.m_ey) < 0.001) - mask |= g_lfHorizontal; - - LONG lCountSpaces = 0; - LONG lCountSymbols = 0; - LONG lCountWords = 0; - bool bIsLastSymbol = false; - - bool bIsGidExist = false; - - LONG nCount = m_oLine.GetCountChars(); - for (LONG i = 0; i < nCount; ++i) - { - CHChar* pChar = &m_oLine.m_pChars[i]; - if (pChar->gid != 0xFFFF) - { - mask |= g_lfGids; - bIsGidExist = true; - } - - if (0xFFFF == pChar->unicode || ((WCHAR)' ') == pChar->unicode || ((WCHAR)'\t') == pChar->unicode) - { - lCountSpaces++; - if (bIsLastSymbol) - { - bIsLastSymbol = false; - lCountWords++; - } - } - else - { - lCountSymbols++; - bIsLastSymbol = true; - } - } - - if (bIsLastSymbol) - lCountWords++; - - if (0 == nCount) - { - m_oLine.Clear(); - m_oMeta.ClearNoAttack(); - return; - } - - m_lCountParagraphs += 1; - m_lCountWords += lCountWords; - m_lCountSymbols += lCountSymbols; - m_lCountSpaces += lCountSpaces; - - if (nCount > 1) - mask |= g_lfWidth; - - m_pPageMeta->CheckBufferSize(60); - - m_pPageMeta->WriteBYTE_nocheck(CMetafile::ctCommandTextLine); - m_pPageMeta->WriteBYTE_nocheck(mask); - - m_pPageMeta->WriteDouble_nocheck(m_oLine.m_dX); - m_pPageMeta->WriteDouble_nocheck(m_oLine.m_dY); - - if ((mask & g_lfHorizontal) == 0) - { - m_pPageMeta->WriteDouble_nocheck(m_oLine.m_ex); - m_pPageMeta->WriteDouble_nocheck(m_oLine.m_ey); - } - - m_pPageMeta->WriteDouble_nocheck(m_oLine.m_dAscent); - m_pPageMeta->WriteDouble_nocheck(m_oLine.m_dDescent); - - LONG _position = 0; - if (nCount > 1) - { - _position = m_pPageMeta->GetPosition(); - m_pPageMeta->WriteLONG_nocheck(0); - } - - BYTE* pBufferMeta = m_oMeta.GetData(); - double dWidthLine = 0; - - double dCurrentGlyphLineOffset = 0; - for (LONG lIndexChar = 0; lIndexChar < nCount; ++lIndexChar) - { - CHChar* pChar = &m_oLine.m_pChars[lIndexChar]; - - // все настроки буквы (m_oMeta) - BYTE lLen = *pBufferMeta; - ++pBufferMeta; - if (lLen > 0) - { - m_pPageMeta->Write(pBufferMeta, lLen); - } - pBufferMeta += lLen; - // смещение относительно предыдущей буквы (у всех, кроме первой) - // юникодное значение - // гид (если bIsGidExist == true) - // ширина буквы - - m_pPageMeta->CheckBufferSize(20); - - m_pPageMeta->WriteBYTE_nocheck(CMetafile::ctDrawText); - if (0 != lIndexChar) - { - m_pPageMeta->WriteDouble2_nocheck(pChar->x); - } - - m_pPageMeta->WriteWCHAR_nocheck2(pChar->unicode); - if (bIsGidExist) - m_pPageMeta->WriteUSHORT_nocheck(pChar->gid); - m_pPageMeta->WriteDouble2_nocheck(pChar->width); - - if (lIndexChar != 0) - dCurrentGlyphLineOffset += pChar->x; - - if (lIndexChar == (nCount - 1)) - dWidthLine = dCurrentGlyphLineOffset + pChar->width; - } - - if (nCount > 1) - { - int nWidthBuf = (int)(dWidthLine * 10000); - memcpy(m_pPageMeta->GetData() + _position, &nWidthBuf, 4); - } - - m_oLine.Clear(); - m_oMeta.ClearNoAttack(); - - m_pPageMeta->WriteBYTE(CMetafile::ctCommandTextLineEnd); - } - }; -} - -#endif // _ASC_HTMLRENDERER_TEXT_H_ diff --git a/HtmlRenderer/src/VMLWriter.h b/HtmlRenderer/src/VMLWriter.h deleted file mode 100644 index 2e741d6bab3..00000000000 --- a/HtmlRenderer/src/VMLWriter.h +++ /dev/null @@ -1,381 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2023 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _ASC_HTMLRENDERER_VMLWRITER_H_ -#define _ASC_HTMLRENDERER_VMLWRITER_H_ - -#include "Common.h" - -namespace NSHtmlRenderer -{ - class CVMLWriter - { - public: - NSStringUtils::CStringBuilder m_oPath; - NSStringUtils::CStringBuilder m_oDocument; - - LONG m_lCurDocumentID; - LONG m_lClippingPath; - - bool m_bIsClipping; - LONG m_lClipMode; - bool m_bIsClippingNow; - - NSStructures::CPen* m_pPen; - NSStructures::CBrush* m_pBrush; - - double m_lWidth; - double m_lHeight; - - double m_dDpiX; - double m_dDpiY; - - public: - CVMLWriter() : m_oPath(), m_oDocument() - { - m_lCurDocumentID = 0; - m_lClippingPath = 0; - - m_pPen = NULL; - m_pBrush = NULL; - - m_dDpiX = 96; - m_dDpiY = 96; - - m_lClipMode = c_nWindingFillMode; - - m_bIsClipping = false; - m_bIsClippingNow = false; - } - - void SetSettings(NSStructures::CPen* pPen, NSStructures::CBrush* pBrush) - { - m_pPen = pPen; - m_pBrush = pBrush; - } - - void CloseFile(std::wstring strFile = L"") - { - if (L"" != strFile) - { - m_oDocument.WriteString(L"\n", 17); - NSFile::CFileBinary oFile; - oFile.CreateFileW(strFile); - BYTE* pData; - LONG nDataSize; - NSFile::CUtf8Converter::GetUtf8StringFromUnicode(m_oDocument.GetBuffer(), m_oDocument.GetCurSize(), pData, nDataSize); - oFile.WriteFile(pData, nDataSize); - RELEASEARRAYOBJECTS(pData); - } - - if (3000000 < m_oDocument.GetSize()) - m_oDocument.Clear(); - - m_oDocument.ClearNoAttack(); - m_oPath.ClearNoAttack(); - } - void NewDocument(double& dWidth, double& dHeigth, LONG& lPageNumber) - { - CloseFile(L""); - - m_lWidth = (int)dWidth; - m_lHeight = (int)dHeigth; - - m_lCurDocumentID = lPageNumber; - - m_oDocument.AddSize(150); - m_oDocument.WriteString(L"\n\n", 66); - } - - public: - - inline void WritePathEnd() - { - m_oPath.ClearNoAttack(); - } - inline void WritePathStart() - { - m_oPath.ClearNoAttack(); - } - void WritePathClose() - { - if (m_bIsClippingNow) - return; - - m_oPath.AddCharSafe('x'); - } - - void WritePathMoveTo(double& x, double& y) - { - if (m_bIsClippingNow) - return; - - m_oPath.AddSize(30); - m_oPath.AddCharNoSafe('m'); - m_oPath.AddIntNoCheck(round(x)); - m_oPath.AddCharNoSafe(','); - m_oPath.AddIntNoCheck(round(y)); - m_oPath.AddCharNoSafe(' '); - } - void WritePathLineTo(double& x, double& y) - { - if (m_bIsClippingNow) - return; - - if (0 == m_oPath.GetCurSize()) - { - WritePathMoveTo(x, y); - } - m_oPath.AddSize(30); - m_oPath.AddCharNoSafe('l'); - m_oPath.AddIntNoCheck(round(x)); - m_oPath.AddCharNoSafe(','); - m_oPath.AddIntNoCheck(round(y)); - m_oPath.AddCharNoSafe(' '); - } - void WritePathCurveTo(double& x1, double& y1, double& x2, double& y2, double& x3, double& y3) - { - if (0 == m_oPath.GetCurSize()) - { - WritePathMoveTo(x1, y1); - } - - m_oPath.AddSize(80); - m_oPath.AddCharNoSafe('c'); - m_oPath.AddIntNoCheck(round(x1)); - m_oPath.AddCharNoSafe(','); - m_oPath.AddIntNoCheck(round(y1)); - m_oPath.AddCharNoSafe(','); - m_oPath.AddIntNoCheck(round(x2)); - m_oPath.AddCharNoSafe(','); - m_oPath.AddIntNoCheck(round(y2)); - m_oPath.AddCharNoSafe(','); - m_oPath.AddIntNoCheck(round(x3)); - m_oPath.AddCharNoSafe(','); - m_oPath.AddIntNoCheck(round(y3)); - m_oPath.AddCharNoSafe(' '); - } - void WriteDrawPath(LONG lType, Aggplus::CMatrix* pTransform, Aggplus::CGraphicsPathSimpleConverter* pConverter, CImageInfo& oInfo, const double& dAngle) - { - if (m_oPath.GetCurSize() < 3) - return; - - int nStrokeColor = ConvertColor(m_pPen->Color); - - m_oDocument.WriteString(L"Alpha == 0) - lType &= 0xFF00; - - if ((-1 == oInfo.m_lID) && (0 == m_pBrush->Alpha1)) - lType &= 0xFF; - - // canvas - if ((lType & 0x01) == 0x01) - { - bStroke = true; - } - if (lType > 0x01) - { - bFilled = true; - } - - if (bStroke) - m_oDocument.WriteString(L"true", 4); - else - m_oDocument.WriteString(L"false", 5); - - m_oDocument.WriteString(L"\" strokecolor=\"", 15); - m_oDocument.WriteHexColor3(nStrokeColor); - - m_oDocument.WriteString(L"\" filled=\"", 10); - - if (bFilled) - m_oDocument.WriteString(L"true", 4); - else - m_oDocument.WriteString(L"false", 5); - - m_oDocument.WriteString(L"\" ", 2); - - if (-1 != oInfo.m_lID) - { - if (itJPG == oInfo.m_eType) - { - m_oDocument.WriteString(L"path=\"", 6); - m_oDocument.Write(m_oPath); - m_oDocument.WriteString(L"\">TextureAlpha) / 255); - m_oDocument.WriteString(L"\"/>\n", 14); - } - else - { - m_oDocument.WriteString(L"path=\"", 6); - m_oDocument.Write(m_oPath); - m_oDocument.WriteString(L"\">TextureAlpha) / 255); - m_oDocument.WriteString(L"\"/>\n", 14); - } - } - else if (0xFF == m_pBrush->Alpha1) - { - if (0x00 == (lType & 0xFF) || (0 == m_pPen->DashStyle)) - { - m_oDocument.WriteString(L"fillcolor=\"", 11); - m_oDocument.WriteHexColor3(ConvertColor(m_pBrush->Color1)); - m_oDocument.WriteString(L"\" path=\"", 8); - m_oDocument.Write(m_oPath); - m_oDocument.WriteString(L"\" />\n", 5); - } - else - { - m_oDocument.WriteString(L"fillcolor=\"", 11); - m_oDocument.WriteHexColor3(ConvertColor(m_pBrush->Color1)); - m_oDocument.WriteString(L"\" path=\"", 8); - m_oDocument.Write(m_oPath); - m_oDocument.WriteString(L"\">\n", 40); - } - - } - else - { - if (0x00 == (lType & 0xFF) || (0 == m_pPen->DashStyle)) - { - m_oDocument.WriteString(L"fillcolor=\"", 11); - m_oDocument.WriteHexColor3(ConvertColor(m_pBrush->Color1)); - m_oDocument.WriteString(L"\" path=\"", 8); - m_oDocument.Write(m_oPath); - m_oDocument.WriteString(L"\">Alpha1) / 255); - m_oDocument.WriteString(L"\" />\n", 5); - } - else - { - m_oDocument.WriteString(L"fillcolor=\"", 11); - m_oDocument.WriteHexColor3(ConvertColor(m_pBrush->Color1)); - m_oDocument.WriteString(L"\" path=\"", 8); - m_oDocument.Write(m_oPath); - m_oDocument.WriteString(L"\">Alpha1) / 255); - m_oDocument.WriteString(L"\">\n", 40); - } - } - } - - void WriteImage(CImageInfo oInfo, const double& x, const double& y, const double& w, const double& h, const double& dAngle) - { - m_oDocument.WriteString(L"", 4); - } - - void WritePathClip() - { - m_bIsClipping = true; - m_bIsClippingNow = true; - ++m_lClippingPath; - } - void WritePathClipEnd() - { - m_bIsClippingNow = false; - } - void WritePathResetClip() - { - m_bIsClipping = false; - } - - inline void WriteStyleClip() - { - } - - void WriteToMainHtml(NSStringUtils::CStringBuilder* pWriter, const CDstInfo& oInfo) - { - if (!oInfo.m_bIsWeb) - { - pWriter->WriteString(L"AddSize(100); - pWriter->AddIntNoCheck((int)m_lWidth); - pWriter->AddCharNoSafe(','); - pWriter->AddIntNoCheck((int)m_lHeight); - pWriter->WriteString(L"\" src=\"page", 11); - pWriter->AddIntNoCheck(m_lCurDocumentID); - pWriter->WriteString(L".vml#page", 9); - pWriter->AddIntNoCheck(m_lCurDocumentID); - pWriter->WriteString(L"\" unselectable=\"on\"/>\n", 22); - - std::wstring sPath = oInfo.m_strDstFilePath + L"\\page" + std::to_wstring(m_lCurDocumentID) + L".vml"; - CloseFile(sPath); - } - else - { - pWriter->WriteString(L"AddSize(100); - pWriter->AddIntNoCheck((int)m_lWidth); - pWriter->AddCharNoSafe(','); - pWriter->AddIntNoCheck((int)m_lHeight); - pWriter->WriteString(L"\" src=\"", 7); - pWriter->WriteString(oInfo.m_strAdditionalPath); - pWriter->WriteString(L"/page", 5); - pWriter->AddIntNoCheck(m_lCurDocumentID); - pWriter->WriteString(L".vml#page", 9); - pWriter->AddIntNoCheck(m_lCurDocumentID); - pWriter->WriteString(L"\" unselectable=\"on\"/>\n", 22); - - std::wstring sPath = oInfo.m_strDstFilePath + L"\\page" + std::to_wstring(m_lCurDocumentID) + L".vml"; - CloseFile(sPath); - } - } - }; -} - -#endif // _ASC_HTMLRENDERER_VMLWRITER_H_ diff --git a/HtmlRenderer/src/VectorGraphicsWriter.h b/HtmlRenderer/src/VectorGraphicsWriter.h deleted file mode 100644 index 7a4f62cf463..00000000000 --- a/HtmlRenderer/src/VectorGraphicsWriter.h +++ /dev/null @@ -1,760 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2023 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _ASC_HTMLRENDERER_VGW_H_ -#define _ASC_HTMLRENDERER_VGW_H_ - -#include "Common.h" -#include "../../DesktopEditor/graphics/GraphicsPath.h" -#include - -namespace NSHtmlRenderer -{ - // приходится в html разруливать простую графику. - // (линии (горизонтальные/вектикальные), ректы (не повернутые)). - // для них не нужно генерить html5-код, который генерит тяжелую картинку - // и подгружает ее в память - - const LONG g_lSimpleCommandsCountMax = 100; - - class CVectorGraphicsWriter - { - public: - enum SimpleCommand - { - scMoveTo = 0, - scLineTo = 1, - scClose = 2 - }; - class CSimpleCommand - { - public: - SimpleCommand m_eType; - double m_dX; - double m_dY; - }; - - public: - NSStringUtils::CStringBuilder m_oWriterSimpleGraphics; - NSStringUtils::CStringBuilder m_oWriterVMLPath; - NSStringUtils::CStringBuilder m_oWriterCanvas; - NSStringUtils::CStringBuilder m_oWriterVML; - - Aggplus::CGraphicsPathSimpleConverter* m_pSimpleConverter; - - NSStructures::CPen* m_pPen; - NSStructures::CBrush* m_pBrush; - - Aggplus::CMatrix* m_pFullTransform; - - double m_dCurrentMoveToX; - double m_dCurrentMoveToY; - - bool m_bIsSimpleGraphics; - - public: - bool m_bIsSimple; - - bool m_bIsClip; - bool m_bIsClipping; - - CSimpleCommand* m_arSimpleCommands; - LONG m_lCountSC; - - public: - CVectorGraphicsWriter() : m_oWriterVML(), m_oWriterCanvas(), m_oWriterSimpleGraphics(), m_oWriterVMLPath() - { - m_bIsClip = FALSE; - m_bIsClipping = FALSE; - - m_bIsSimple = TRUE; - - m_pSimpleConverter = NULL; - - m_pPen = NULL; - m_pBrush = NULL; - - m_pFullTransform = NULL; - - m_dCurrentMoveToX = 0; - m_dCurrentMoveToY = 0; - - m_lCountSC = 0; - - m_bIsSimpleGraphics = true; - - m_arSimpleCommands = new CSimpleCommand[g_lSimpleCommandsCountMax]; - } - ~CVectorGraphicsWriter() - { - RELEASEARRAYOBJECTS(m_arSimpleCommands); - } - - inline void EndPage() - { - m_oWriterSimpleGraphics.ClearNoAttack(); - m_oWriterVMLPath.ClearNoAttack(); - m_oWriterCanvas.ClearNoAttack(); - m_oWriterVML.ClearNoAttack(); - - m_bIsSimpleGraphics = true; - } - - inline void WriteBeginPath() - { - m_oWriterCanvas.WriteString(L"b(c);\n", 6); - } - - inline void WriteEndPath() - { - m_oWriterVMLPath.ClearNoAttack(); - - m_bIsSimple = true; - m_lCountSC = 0; - } - - void WritePathStart() - { - m_oWriterCanvas.WriteString(L"b(c);\n", 6); - } - void WritePathClose() - { - m_oWriterCanvas.WriteString(L"x(c);\n", 6); - - if (!m_bIsClipping) - { - m_oWriterVMLPath.AddCharSafe('x'); - } - - if (m_bIsSimple) - { - if (0 < m_lCountSC) - { - m_arSimpleCommands[m_lCountSC].m_eType = scLineTo; - m_arSimpleCommands[m_lCountSC].m_dX = m_dCurrentMoveToX; - m_arSimpleCommands[m_lCountSC].m_dY = m_dCurrentMoveToY; - - ++m_lCountSC; - - if (m_lCountSC == g_lSimpleCommandsCountMax) - { - m_bIsSimple = false; - } - } - } - } - - void WritePathMoveTo(double& x, double& y) - { - m_oWriterCanvas.WriteString(L"m(c,", 4); - WriteIntsToStringBuilder(round(x), round(y), &m_oWriterCanvas); - m_oWriterCanvas.WriteString(L");\n", 3); - - if (!m_bIsClipping) - { - m_oWriterVMLPath.AddCharSafe('m'); - WriteIntsToStringBuilder(round(x), round(y), &m_oWriterVMLPath); - m_oWriterVMLPath.AddCharSafe(' '); - } - - if (m_bIsSimple) - { - m_arSimpleCommands[m_lCountSC].m_eType = scMoveTo; - m_arSimpleCommands[m_lCountSC].m_dX = x; - m_arSimpleCommands[m_lCountSC].m_dY = y; - - m_dCurrentMoveToX = x; - m_dCurrentMoveToY = y; - - ++m_lCountSC; - if (m_lCountSC == g_lSimpleCommandsCountMax) - { - m_bIsSimple = false; - } - } - } - void WritePathLineTo(double& x, double& y) - { - if (0 == m_oWriterVMLPath.GetCurSize()) - { - m_oWriterCanvas.WriteString(L"m(c,", 4); - WriteIntsToStringBuilder(round(x), round(y), &m_oWriterCanvas); - m_oWriterCanvas.WriteString(L");\n", 3); - - m_oWriterVMLPath.AddCharSafe('m'); - WriteIntsToStringBuilder(round(x), round(y), &m_oWriterVMLPath); - m_oWriterVMLPath.AddCharSafe(' '); - } - - m_oWriterCanvas.WriteString(L"l(c,", 4); - WriteIntsToStringBuilder(round(x), round(y), &m_oWriterCanvas); - m_oWriterCanvas.WriteString(L");\n", 3); - - if (!m_bIsClipping) - { - m_oWriterVMLPath.AddCharSafe('l'); - WriteIntsToStringBuilder(round(x), round(y), &m_oWriterVMLPath); - m_oWriterVMLPath.AddCharSafe(' '); - } - - if (m_bIsSimple) - { - if (0 == m_lCountSC) - { - m_arSimpleCommands[m_lCountSC].m_eType = scMoveTo; - m_arSimpleCommands[m_lCountSC].m_dX = x; - m_arSimpleCommands[m_lCountSC].m_dY = y; - - m_dCurrentMoveToX = x; - m_dCurrentMoveToY = y; - - ++m_lCountSC; - } - else - { - double _x = m_arSimpleCommands[m_lCountSC - 1].m_dX; - double _y = m_arSimpleCommands[m_lCountSC - 1].m_dY; - - if ((FABS(_x - x) < 0.01) || (FABS(_y - y) < 0.01)) - { - // продолжаем симпл! - m_arSimpleCommands[m_lCountSC].m_eType = scLineTo; - m_arSimpleCommands[m_lCountSC].m_dX = x; - m_arSimpleCommands[m_lCountSC].m_dY = y; - - ++m_lCountSC; - - if (m_lCountSC == g_lSimpleCommandsCountMax) - { - m_bIsSimple = false; - } - } - } - } - } - void WritePathCurveTo(double& x1, double& y1, double& x2, double& y2, double& x3, double& y3) - { - if (0 == m_oWriterVMLPath.GetCurSize()) - { - m_oWriterCanvas.WriteString(L"m(c,", 4); - WriteIntsToStringBuilder(round(x), round(y), &m_oWriterCanvas); - m_oWriterCanvas.WriteString(L");\n", 3); - - m_oWriterVMLPath.AddCharSafe('m'); - WriteIntsToStringBuilder(round(x), round(y), &m_oWriterVMLPath); - m_oWriterVMLPath.AddCharSafe(' '); - } - - m_oWriterCanvas.WriteString(L"cu(c,", 5); - WriteIntsToStringBuilder(round(x1), round(y1), round(x2), round(y2), round(x3), round(y3), &m_oWriterCanvas); - m_oWriterCanvas.WriteString(L");\n", 3); - - if (!m_bIsClipping) - { - m_oWriterVMLPath.AddCharSafe('c'); - WriteIntsToStringBuilder(round(x1), round(y1), round(x2), round(y2), round(x3), round(y3), &m_oWriterVMLPath); - m_oWriterVMLPath.AddCharSafe(' '); - } - - m_bIsSimple = false; - } - void WriteDrawPath(LONG lType, LONG lIDTx, LONG& lCurTxNumber, LONG& lPageNumber) - { - if (m_bIsSimple && (-1 == lIDTx)) - { - // пишем по-крутому - double x = 0; - double y = 0; - double w = 0; - double h = 0; - - bool bIsRect = IsRect(x, y, w, h); - - if (bIsRect) - { - if ((0 == w && 0 == h)) - return; - - w = max(1, w); - h = max(1, h); - - if (bIsRect) - { - CString strLineColor = GetStringColor(m_pPen->Color); - CString strFillColor = GetStringColor(m_pBrush->Color1); - - if (0 == m_pBrush->Alpha1) - strFillColor = _T("transparent"); - - if ((1 >= w) || (1 >= h) && (lType < 0xFF)) - { - m_oWriterSimpleGraphics.WriteString(L"
Color, &m_oWriterSimpleGraphics); - m_oWriterSimpleGraphics.WriteString(L"; border-color: ", 16); - SetStringColor(m_pPen->Color, &m_oWriterSimpleGraphics); - m_oWriterSimpleGraphics.WriteString(L"; opacity:", 10); - m_oWriterSimpleGraphics.AddIntNoCheckDel100(100 * m_pPen->Alpha / 255); - m_oWriterSimpleGraphics.AddSize(100); - m_oWriterSimpleGraphics.WriteString(L"; left: ", 8); - m_oWriterSimpleGraphics.AddIntNoCheck(round(x)); - m_oWriterSimpleGraphics.WriteString(L"px; top: ", 9); - m_oWriterSimpleGraphics.AddIntNoCheck(round(y)); - m_oWriterSimpleGraphics.WriteString(L"px; width: ", 11); - m_oWriterSimpleGraphics.AddIntNoCheck(round(w)); - m_oWriterSimpleGraphics.WriteString(L"px; height: ", 12); - m_oWriterSimpleGraphics.AddIntNoCheck(round(h)); - m_oWriterSimpleGraphics.WriteString(L"px;\">
\n"); - } - else - { - if (0x00 == (lType & 0xFF)) - { - m_oWriterSimpleGraphics.WriteString(L"
Alpha1) - m_oWriterSimpleGraphics.WriteString(L"transparent", 11); - else - SetStringColor(m_pBrush->Color1, &m_oWriterSimpleGraphics); - m_oWriterSimpleGraphics.WriteString(L"; border-color: ", 16); - SetStringColor(m_pPen->Color, &m_oWriterSimpleGraphics); - m_oWriterSimpleGraphics.WriteString(L"; opacity:", 10); - m_oWriterSimpleGraphics.AddIntNoCheckDel100(100 * m_pBrush->Alpha1 / 255); - m_oWriterSimpleGraphics.AddSize(100); - m_oWriterSimpleGraphics.WriteString(L"; left: ", 8); - m_oWriterSimpleGraphics.AddIntNoCheck(round(x)); - m_oWriterSimpleGraphics.WriteString(L"px; top: ", 9); - m_oWriterSimpleGraphics.AddIntNoCheck(round(y)); - m_oWriterSimpleGraphics.WriteString(L"px; width: ", 11); - m_oWriterSimpleGraphics.AddIntNoCheck(round(w)); - m_oWriterSimpleGraphics.WriteString(L"px; height: ", 12); - m_oWriterSimpleGraphics.AddIntNoCheck(round(h)); - m_oWriterSimpleGraphics.WriteString(L"px;\">
\n"); - } - else if (lType < 0xFF) - { - m_oWriterSimpleGraphics.WriteString(L"
Alpha1) - m_oWriterSimpleGraphics.WriteString(L"transparent", 11); - else - SetStringColor(m_pBrush->Color1, &m_oWriterSimpleGraphics); - m_oWriterSimpleGraphics.WriteString(L"; border-color: ", 16); - SetStringColor(m_pPen->Color, &m_oWriterSimpleGraphics); - m_oWriterSimpleGraphics.WriteString(L"; opacity:", 10); - m_oWriterSimpleGraphics.AddIntNoCheckDel100(100 * m_pPen->Alpha / 255); - m_oWriterSimpleGraphics.AddSize(100); - m_oWriterSimpleGraphics.WriteString(L"; left: ", 8); - m_oWriterSimpleGraphics.AddIntNoCheck(round(x)); - m_oWriterSimpleGraphics.WriteString(L"px; top: ", 9); - m_oWriterSimpleGraphics.AddIntNoCheck(round(y)); - m_oWriterSimpleGraphics.WriteString(L"px; width: ", 11); - m_oWriterSimpleGraphics.AddIntNoCheck(round(w)); - m_oWriterSimpleGraphics.WriteString(L"px; height: ", 12); - m_oWriterSimpleGraphics.AddIntNoCheck(round(h)); - m_oWriterSimpleGraphics.WriteString(L"px;\">
\n"); - } - else - { - m_oWriterSimpleGraphics.WriteString(L"
Alpha1) - m_oWriterSimpleGraphics.WriteString(L"transparent", 11); - else - SetStringColor(m_pBrush->Color1, &m_oWriterSimpleGraphics); - m_oWriterSimpleGraphics.WriteString(L"; border-color: ", 16); - SetStringColor(m_pPen->Color, &m_oWriterSimpleGraphics); - m_oWriterSimpleGraphics.WriteString(L"; opacity:", 10); - m_oWriterSimpleGraphics.AddIntNoCheckDel100(100 * m_pBrush->Alpha1 / 255); - m_oWriterSimpleGraphics.AddSize(100); - m_oWriterSimpleGraphics.WriteString(L"; left: ", 8); - m_oWriterSimpleGraphics.AddIntNoCheck(round(x)); - m_oWriterSimpleGraphics.WriteString(L"px; top: ", 9); - m_oWriterSimpleGraphics.AddIntNoCheck(round(y)); - m_oWriterSimpleGraphics.WriteString(L"px; width: ", 11); - m_oWriterSimpleGraphics.AddIntNoCheck(round(w)); - m_oWriterSimpleGraphics.WriteString(L"px; height: ", 12); - m_oWriterSimpleGraphics.AddIntNoCheck(round(h)); - m_oWriterSimpleGraphics.WriteString(L"px;\">
\n"); - } - } - } - } - else - { - m_bIsSimpleGraphics = false; - } - } - else - { - m_bIsSimpleGraphics = false; - } - - std::wstring strStroked = L"false"; - std::wstring strFilled = L"false"; - - //if (0x00 != (0x02 & (lType >> 8)) && ((lType & 0xFF) == 0x00)) - //{ - // lType = 1; - // m_pPen->Color = m_pBrush->Color1; - // m_pPen->Alpha = m_pBrush->Alpha1; - //} - - bool bStroke = false; - - if (m_pPen->Alpha == 0) - lType &= 0xFF00; - - if ((-1 == lIDTx) && (0 == m_pBrush->Alpha1)) - lType &= 0xFF; - - // canvas - if ((lType & 0x01) == 0x01) - { - SetStrokeColor(m_pPen->Color, m_pPen->Alpha, &m_oWriterCanvas); - - bStroke = true; - - if (0x00 != m_pPen->Alpha) - { - strStroked = L"true"; - } - } - if (lType > 0x01) - { - if (-1 != lIDTx) - { - double x = 0; - double y = 0; - double w = 0; - double h = 0; - - m_pSimpleConverter->PathCommandGetBounds(&x, &y, &w, &h); - - double r = x + w; - double b = y + h; - - m_pFullTransform->TransformPoint(x, y); - m_pFullTransform->TransformPoint(r, b); - - w = r - x; - h = b - y; - - m_oWriterCanvas.WriteString(L"img", 3); - m_oWriterCanvas.AddInt(lIDTx); - m_oWriterCanvas.WriteString(L".src = \"media\\\\image", 20); - m_oWriterCanvas.AddInt(lIDTx); - m_oWriterCanvas.WriteString(L".jpg\";img", 9); - m_oWriterCanvas.AddInt(lIDTx); - m_oWriterCanvas.WriteString(L".onload = function(){c.drawImage(img", 36); - WriteIntsToStringBuilder(lIDTx, round(x), round(y), round(w), round(h), &m_oWriterCanvas); - m_oWriterCanvas.WriteString(L");drawpage", 10); - m_oWriterCanvas.AddInt(lPageNumber); - m_oWriterCanvas.AddCharSafe('_'); - m_oWriterCanvas.AddInt(lCurTxNumber); - m_oWriterCanvas.WriteString(L"(c);};\n}\nfunction drawpage", 26); - m_oWriterCanvas.AddInt(lPageNumber); - m_oWriterCanvas.AddCharSafe('_'); - m_oWriterCanvas.AddInt(lCurTxNumber); - m_oWriterCanvas.WriteString(L"(c)\n{\n", 6); - } - else - { - SetFillColor(m_pBrush->Color1, m_pBrush->Alpha1, &m_oWriterCanvas); - m_oWriterCanvas.WriteString(L"f(c);\n", 6); - } - - strFilled = L"true"; - } - - if (bStroke) - { - m_oWriterCanvas.WriteString(L"s(c);\n", 6); - } - - if (-1 != lIDTx) - { - m_oWriterVML.WriteString(L"Color)); - m_oWriterVML.WriteString(L"\" filled=\"", 10); - m_oWriterVML.WriteString(strFilled); - m_oWriterVML.WriteString(L"\" path=\"", 8); - m_oWriterVML.Write(m_oWriterVMLPath); - m_oWriterVML.WriteString(L"\">Alpha1 / 255); - m_oWriterVML.WriteString(L"\"/>\n", 14); - - } - else if (0xFF == m_pBrush->Alpha1) - { - m_oWriterVML.WriteString(L"Color)); - m_oWriterVML.WriteString(L"\" filled=\"", 10); - m_oWriterVML.WriteString(strFilled); - m_oWriterVML.WriteString(L"\" fillcolor=\"", 13); - m_oWriterVML.WriteHexColor3(ConvertColor(m_pBrush->Color1)); - m_oWriterVML.WriteString(L"\" path=\"", 8); - m_oWriterVML.Write(m_oWriterVMLPath); - m_oWriterVML.WriteString(L"\" />\n", 5); - } - else - { - m_oWriterVML.WriteString(L"Color)); - m_oWriterVML.WriteString(L"\" filled=\"", 10); - m_oWriterVML.WriteString(strFilled); - m_oWriterVML.WriteString(L"\" fillcolor=\"", 13); - m_oWriterVML.WriteHexColor3(ConvertColor(m_pBrush->Color1)); - m_oWriterVML.WriteString(L"\" path=\"", 8); - m_oWriterVML.Write(m_oWriterVMLPath); - m_oWriterVML.WriteString(L"\">Alpha1 / 255); - m_oWriterVML.WriteString(L"\"/>\n", 14); - } - m_oWriterVML.WriteString(strVML); - - if (-1 != lIDTx) - { - ++lCurTxNumber; - } - } - - void WritePathClip() - { - m_bIsClipping = true; - } - void WritePathClipEnd() - { - m_bIsClipping = false; - - double x = 0; - double y = 0; - double w = 0; - double h = 0; - - m_pSimpleConverter->PathCommandGetBounds(&x, &y, &w, &h); - if ((0 > w) || (0 > h)) - { - // никакого клипа нет! - return; - } - else - { - if (!m_bIsClip) - { - m_oWriterCanvas.WriteString(L"c.save();\n", 10); - } - m_bIsClip = true; - m_oWriterCanvas.WriteString(L"c.clip();\n", 10); - } - } - void WritePathResetClip() - { - if (m_bIsClip) - { - m_oWriterCanvas.WriteString(L"c.restore();\n", 13); - } - - m_bIsClip = false; - m_bIsClipping = false; - } - - protected: - - bool IsRect(double& x, double& y, double& w, double& h) - { - if (1 >= m_lCountSC) - return false; - - double dPrevX = m_arSimpleCommands[0].m_dX; - double dPrevY = m_arSimpleCommands[0].m_dY; - - long lCurDirection = 0; - - std::vector arX; - std::vector arY; - - arX.push_back(dPrevX); - arY.push_back(dPrevY); - - double dXmin = dPrevX; - double dXmax = dPrevX; - double dYmin = dPrevY; - double dYmax = dPrevY; - - double _dX = m_arSimpleCommands[m_lCountSC - 1].m_dX; - double _dY = m_arSimpleCommands[m_lCountSC - 1].m_dY; - - for (LONG i = 1; i < m_lCountSC; ++i) - { - CSimpleCommand* pComm = &m_arSimpleCommands[i]; - - if (scLineTo != pComm->m_eType) - return false; - - long lDir = SkipCurDirection(lCurDirection, i, dPrevX, dPrevY); - - double dX = _dX; - double dY = _dY; - - if (i < m_lCountSC) - { - dX = m_arSimpleCommands[i - 1].m_dX; - dY = m_arSimpleCommands[i - 1].m_dY; - } - - if (dX > dXmax) - dXmax = dX; - else if (dX < dXmin) - dXmin = dX; - - if (dY > dYmax) - dYmax = dY; - else if (dY < dYmin) - dYmin = dY; - - arX.push_back(dX); - arY.push_back(dY); - - lCurDirection = lDir; - } - - // все, массивы заполнены. - // теперь осталось определить, рект ли это - // должно: - // 1) кроме минимумов и максимумов ничего не может быть. - // 2) все точки ректа должны присутствовать - - bool b1 = false; - bool b2 = false; - bool b3 = false; - bool b4 = false; - - int lCount = (int)arX.size(); - for (int i = 0; i < lCount; ++i) - { - double ___x = arX[i]; - double ___y = arY[i]; - bool bBreak = false; - - if (IsEqualPoint(___x, ___y, dXmin, dYmin)) - b1 = true; - else if (IsEqualPoint(___x, ___y, dXmax, dYmin)) - b2 = true; - else if (IsEqualPoint(___x, ___y, dXmin, dYmax)) - b4 = true; - else if (IsEqualPoint(___x, ___y, dXmax, dYmax)) - b3 = true; - else - return false; - } - - x = dXmin; - y = dYmin; - w = dXmax - dXmin; - h = dYmax - dYmin; - - if (b1 && b2 && !b3 && !b4) - return true; - if (b1 && !b2 && !b3 && b4) - return true; - if (!b1 && b2 && b3 && !b4) - return true; - if (!b1 && !b2 && b3 && b4) - return true; - if (b1 && b2 && b3 && b4) - return true; - - return false; - } - - // direction: (0 - вправо, 1 - вниз, 2 - влево, 3 - вверх) - inline long SkipCurDirection(const long& lDirection, long& lIndexCur, double& dPrevX, double& dPrevY) - { - for (; lIndexCur < m_lCountSC; ++lIndexCur) - { - long lDir = GetCurDirection(lIndexCur, dPrevX, dPrevY); - - dPrevX = m_arSimpleCommands[lIndexCur].m_dX; - dPrevY = m_arSimpleCommands[lIndexCur].m_dY; - - if ((-1 == lDir) || (lDir == lDirection)) - continue; - - return lDir; - } - return -1; - } - inline long GetCurDirection(const long& lIndex, const double& dPrevX, const double& dPrevY) - { - double x = m_arSimpleCommands[lIndex].m_dX; - double y = m_arSimpleCommands[lIndex].m_dY; - - if (FABS(y - dPrevY) < 0.01) - { - if (FABS(x - dPrevX) < 0.01) - { - return -1; - } - - return (x >= dPrevX) ? 0 : 2; - } - else - { - return (y >= dPrevY) ? 1 : 3; - } - } - - inline bool IsEqualPoint(double& x, double&y, double& _x, double& _y) - { - if ((FABS(x - _x) < 0.1) && (FABS(y - _y) < 0.1)) - return true; - - return false; - } - - bool IsTwoRectOneDirection() - { - return true; - } - - LONG SkipRect(LONG& lStart, LONG& lEnd) - { - - } - }; -} - -#endif // _ASC_HTMLRENDERER_VGW_H_ diff --git a/HtmlRenderer/src/VectorGraphicsWriter2.h b/HtmlRenderer/src/VectorGraphicsWriter2.h deleted file mode 100644 index 383d3050ef6..00000000000 --- a/HtmlRenderer/src/VectorGraphicsWriter2.h +++ /dev/null @@ -1,349 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2023 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _ASC_HTMLRENDERER_VGW2_H_ -#define _ASC_HTMLRENDERER_VGW2_H_ - -#include "Common.h" -#include "SVGWriter.h" -#include "VMLWriter.h" -#include "../../DesktopEditor/graphics/GraphicsPath.h" - -namespace NSHtmlRenderer -{ - class CVectorGraphicsWriter - { - public: - CSVGWriter m_oSVG; - CVMLWriter m_oVML; - //CCanvasWriter m_oCanvas; - - Aggplus::CGraphicsPathSimpleConverter* m_pSimpleConverter; - - NSStructures::CPen* m_pPen; - NSStructures::CBrush* m_pBrush; - - Aggplus::CMatrix* m_pFullTransform; - - LONG m_lCurrentObjectInPage; - - LONG m_lCurrentPageNumber; - double m_dWidth; - double m_dHeight; - - public: - CVectorGraphicsWriter() : m_oSVG(), m_oVML()/*, m_oCanvas()*/ - { - m_pSimpleConverter = NULL; - m_lCurrentObjectInPage = 0; - } - ~CVectorGraphicsWriter() - { - } - - void SetSettings(NSStructures::CPen* pPen, NSStructures::CBrush* pBrush, Aggplus::CGraphicsPathSimpleConverter* pSimpleConverter) - { - m_pPen = pPen; - m_pBrush = pBrush; - m_pSimpleConverter = pSimpleConverter; - - m_oSVG.SetSettings(m_pPen, m_pBrush); - m_oVML.SetSettings(m_pPen, m_pBrush); - //m_oCanvas.SetSettings(m_pPen, m_pBrush, m_pSimpleConverter); - } - - - inline void NewPage(double& dW, double& dH, const LONG& lPageNumber) - { - m_lCurrentPageNumber = lPageNumber; - m_dWidth = dW; - m_dHeight = dH; - - m_oSVG.NewDocument(m_dWidth, m_dHeight, m_lCurrentPageNumber); - m_oVML.NewDocument(m_dWidth, m_dHeight, m_lCurrentPageNumber); - } - inline void EndPage() - { - m_oSVG.CloseFile(); - m_oVML.CloseFile(); - //m_oCanvas.CloseFile(); - - m_lCurrentObjectInPage = 0; - } - - inline void WriteEndPath() - { - m_oSVG.WritePathEnd(); - m_oVML.WritePathEnd(); - //m_oCanvas.WritePathEnd(); - } - - inline void WritePathStart() - { - m_oSVG.WritePathStart(); - m_oVML.WritePathStart(); - //m_oCanvas.WritePathStart(); - } - inline void WritePathClose() - { - m_oSVG.WritePathClose(); - m_oVML.WritePathClose(); - //m_oCanvas.WritePathClose(); - } - - inline void WritePathMoveTo(double& x, double& y) - { - m_oSVG.WritePathMoveTo(x, y); - m_oVML.WritePathMoveTo(x, y); - //m_oCanvas.WritePathMoveTo(x,y); - } - inline void WritePathLineTo(double& x, double& y) - { - m_oSVG.WritePathLineTo(x, y); - m_oVML.WritePathLineTo(x, y); - //m_oCanvas.WritePathLineTo(x, y); - } - inline void WritePathCurveTo(double& x1, double& y1, double& x2, double& y2, double& x3, double& y3) - { - m_oSVG.WritePathCurveTo(x1, y1, x2, y2, x3, y3); - m_oVML.WritePathCurveTo(x1, y1, x2, y2, x3, y3); - //m_oCanvas.WritePathCurveTo(x1, y1, x2, y2, x3, y3); - } - inline void WriteDrawPath(LONG lType, CImageInfo& oInfo, const double& dAngle) - { - // вот мега заглушка под некоторые таблицы из pdf - // проблема в том, что приходит path нулевой толщины - а след-но он не рисуется. - // здесь это отслеживаем и правим пат. Не очень хорошо, так как всякие пунктирности - // в таких патах - теряются при таком подходе - if (0x00 == (lType & 0xFF)) - { - double x = 0; - double y = 0; - double r = 0; - double b = 0; - m_pSimpleConverter->PathCommandGetBounds(x, y, r, b); - - r += x; - b += y; - - if ((fabs(r - x) < 0.5) || (fabs(b - y) < 0.5)) - { - m_pFullTransform->TransformPoint(x, y); - m_pFullTransform->TransformPoint(r, b); - - int _x = round(x); - int _y = round(y); - int _r = round(r); - int _b = round(b); - - if ((_x == _r) || (_y == _b)) - { - LONG lPenColor = m_pPen->Color; - LONG lPenAlpha = m_pPen->Alpha; - double dPenW = m_pPen->Size; - - m_pPen->Color = m_pBrush->Color1; - m_pPen->Alpha = m_pBrush->Alpha1; - m_pPen->Size = c_ag_1pxWidth; - - WriteEndPath(); - WritePathStart(); - WritePathMoveTo(x, y); - WritePathLineTo(r, b); - - WriteDrawPath(0x01, oInfo, dAngle); - - m_pPen->Color = lPenColor; - m_pPen->Alpha = lPenAlpha; - m_pPen->Size = dPenW; - return; - } - } - } - - m_oSVG.WriteDrawPath(lType, m_pFullTransform, m_pSimpleConverter, oInfo, dAngle); - m_oVML.WriteDrawPath(lType, m_pFullTransform, m_pSimpleConverter, oInfo, dAngle); - - m_pSimpleConverter->PathCommandEnd(); - //m_oCanvas.WriteDrawPath(lType, m_pFullTransform, m_pSimpleConverter, lIdTx); - } - - inline void WritePathClip() - { - m_oSVG.WritePathClip(); - m_oVML.WritePathClip(); - //m_oCanvas.WritePathClip(); - } - inline void WritePathClipEnd() - { - m_oSVG.WritePathClipEnd(); - m_oVML.WritePathClipEnd(); - //m_oCanvas.WritePathClipEnd(); - } - inline void SetClipMode(LONG lClipMode) - { - m_oSVG.m_lClipMode = lClipMode; - m_oVML.m_lClipMode = lClipMode; - } - inline void WriteImage(double& x, double& y, double& width, double& height, CImageInfo& oInfo, double dAngle) - { - m_oSVG.WriteImage(oInfo, x, y, width, height, dAngle); - m_oVML.WriteImage(oInfo, x, y, width, height, dAngle); - } - inline void WritePathResetClip() - { - m_oSVG.WritePathResetClip(); - m_oVML.WritePathResetClip(); - //m_oCanvas.WritePathResetClip(); - } - - inline bool IsGraphics() - { - // 10 цифр на номер страницы - // LEN(\n\n) = 131 - return ((131 + 10) < (int)m_oVML.m_oDocument.GetCurSize()); - } - - inline void WriteToDocument(NSStringUtils::CStringBuilder* pDocument, const CDstInfo& oInfo) - { - m_oSVG.WriteToMainHtml_1(pDocument, oInfo); - m_oVML.WriteToMainHtml(pDocument, oInfo); - m_oSVG.WriteToMainHtml_2(pDocument); - } - }; - - class CSVGGraphicsWriter - { - public: - CSVGWriter m_oSVG; - Aggplus::CGraphicsPathSimpleConverter* m_pSimpleConverter; - - NSStructures::CPen* m_pPen; - NSStructures::CBrush* m_pBrush; - - Aggplus::CMatrix* m_pFullTransform; - - double m_dWidth; - double m_dHeight; - - public: - CSVGGraphicsWriter() : m_oSVG() - { - m_pSimpleConverter = NULL; - } - ~CSVGGraphicsWriter() - { - } - - void SetSettings(NSStructures::CPen* pPen, NSStructures::CBrush* pBrush, Aggplus::CGraphicsPathSimpleConverter* pSimpleConverter) - { - m_pPen = pPen; - m_pBrush = pBrush; - m_pSimpleConverter = pSimpleConverter; - - m_oSVG.SetSettings(m_pPen, m_pBrush); - } - - - inline void NewPage(double& dW, double& dH) - { - m_dWidth = dW; - m_dHeight = dH; - } - inline void EndPage() - { - m_oSVG.CloseFile(); - } - - inline void WriteEndPath() - { - m_oSVG.WritePathEnd(); - } - - inline void WritePathStart() - { - m_oSVG.WritePathStart(); - } - inline void WritePathClose() - { - m_oSVG.WritePathClose(); - } - - inline void WritePathMoveTo(double& x, double& y) - { - m_oSVG.WritePathMoveTo(x, y); - } - inline void WritePathLineTo(double& x, double& y) - { - m_oSVG.WritePathLineTo(x, y); - } - inline void WritePathCurveTo(double& x1, double& y1, double& x2, double& y2, double& x3, double& y3) - { - m_oSVG.WritePathCurveTo(x1, y1, x2, y2, x3, y3); - } - inline void WriteDrawPath(LONG lType) - { - CImageInfo oInfo; - m_oSVG.WriteDrawPath(lType, m_pFullTransform, m_pSimpleConverter, oInfo, 0.0); - m_pSimpleConverter->PathCommandEnd(); - } - - inline void WritePathClip() - { - m_oSVG.WritePathClip(); - } - inline void WritePathClipEnd() - { - m_oSVG.WritePathClipEnd(); - } - inline void SetClipMode(LONG lClipMode) - { - m_oSVG.m_lClipMode = lClipMode; - } - inline void WriteImage(double& x, double& y, double& width, double& height, CImageInfo& oInfo, double dAngle) - { - m_oSVG.WriteImage(oInfo, x, y, width, height, dAngle); - } - inline void WritePathResetClip() - { - m_oSVG.WritePathResetClip(); - } - - inline bool IsGraphics() - { - // 10 цифр на номер страницы - // LEN(\n\n) = 131 - return ((131 + 10) < (int)m_oSVG.m_oDocument.GetCurSize()); - } - }; -} - -#endif // _ASC_HTMLRENDERER_VGW2_H_ diff --git a/HtmlRenderer/src/Writer.h b/HtmlRenderer/src/Writer.h deleted file mode 100644 index 5e992f20bd4..00000000000 --- a/HtmlRenderer/src/Writer.h +++ /dev/null @@ -1,2167 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2023 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _ASC_HTMLRENDERER_WRITER_H_ -#define _ASC_HTMLRENDERER_WRITER_H_ - -#include "SVGWriter2.h" -#include -#include "../../DesktopEditor/xml/include/xmlutils.h" -#include "../../DesktopEditor/common/CalculatorCRC32.h" -#include "Text.h" -#include "Document.h" -#include "../../DesktopEditor/fontengine/FontConverter.h" - -namespace NSHtmlRenderer -{ - static double __g_matrix_eps = 0.0001; - - class CTileInfo - { - /* - _T("\ - \ - \ - - */ - - public: - double x; - double y; - double countx; - double county; - double stepx; - double stepy; - - double bbox_x; - double bbox_y; - double bbox_r; - double bbox_b; - - double transform_1; - double transform_2; - double transform_3; - double transform_4; - double transform_5; - double transform_6; - - public: - CTileInfo() - { - Clear(); - } - - public: - - void Clear() - { - x = 0; - y = 0; - countx = 0; - county = 0; - stepx = 0; - stepy = 0; - - bbox_x = 0; - bbox_y = 0; - bbox_r = 0; - bbox_b = 0; - - transform_1 = 1; - transform_2 = 0; - transform_3 = 0; - transform_4 = 1; - transform_5 = 0; - transform_6 = 0; - } - - void LoadFromXml(const std::wstring& strXml) - { - XmlUtils::CXmlNode oNode; - if (oNode.FromXmlString(strXml)) - { - x = oNode.ReadAttributeDouble(L"x", 0); - y = oNode.ReadAttributeDouble(L"y", 0); - countx = oNode.ReadAttributeDouble(L"countx", 0); - county = oNode.ReadAttributeDouble(L"county", 0); - stepx = oNode.ReadAttributeDouble(L"stepx", 0); - stepy = oNode.ReadAttributeDouble(L"stepy", 0); - - XmlUtils::CXmlNode oNodeBox; - if (oNode.GetNode(L"bbox", oNodeBox)) - { - bbox_x = oNode.ReadAttributeDouble(L"x", 0); - bbox_y = oNode.ReadAttributeDouble(L"y", 0); - bbox_r = oNode.ReadAttributeDouble(L"r", 0); - bbox_b = oNode.ReadAttributeDouble(L"b", 0); - } - - XmlUtils::CXmlNode oNodeTr; - if (oNode.GetNode(L"transform", oNodeTr)) - { - transform_1 = oNode.ReadAttributeDouble(L"m1", 0); - transform_2 = oNode.ReadAttributeDouble(L"m2", 0); - transform_3 = oNode.ReadAttributeDouble(L"m3", 0); - transform_4 = oNode.ReadAttributeDouble(L"m4", 0); - transform_5 = oNode.ReadAttributeDouble(L"m5", 0); - transform_6 = oNode.ReadAttributeDouble(L"m6", 0); - } - } - } - }; - - class CGraphicsDumper - { - public: - NSGraphics::IGraphicsRenderer* m_pRenderer; - CBgraFrame* m_pFrame; - - double m_dWidth; - double m_dHeight; - - int m_lWidthPix; - int m_lHeightPix; - - RECT m_oBounds; - - CTileInfo m_oTile; - - public: - CGraphicsDumper() - { - m_pRenderer = NULL; - m_pFrame = NULL; - - m_dWidth = -1; - m_dHeight = -1; - - m_lWidthPix = -1; - m_lHeightPix = -1; - - m_oBounds.left = 0; - m_oBounds.top = 0; - m_oBounds.right = 0; - m_oBounds.bottom = 0; - } - ~CGraphicsDumper() - { - RELEASEOBJECT(m_pRenderer); - RELEASEOBJECT(m_pFrame); - } - - void NewPage(double dWidth, double dHeight) - { - if (dWidth != m_dWidth || dHeight != m_dHeight) - { - RELEASEOBJECT(m_pFrame); - - m_dWidth = dWidth; - m_dHeight = dHeight; - } - - RELEASEOBJECT(m_pRenderer); - - m_lWidthPix = (int)(96 * dWidth / 25.4); - m_lHeightPix = (int)(96 * dHeight / 25.4); - - if (NULL == m_pFrame) - { - m_pFrame = new CBgraFrame(); - m_pFrame->put_Width(m_lWidthPix); - m_pFrame->put_Height(m_lHeightPix); - m_pFrame->put_Stride(4 * m_lWidthPix * m_lHeightPix); - m_pFrame->put_Data(new BYTE[4 * m_lWidthPix * m_lHeightPix]); - } - - BYTE* pBuffer = m_pFrame->get_Data(); - memset(pBuffer, 0xFF, 4 * m_lWidthPix * m_lHeightPix); - - m_pRenderer = NSGraphics::Create(); - m_pRenderer->put_Width(m_dWidth); - m_pRenderer->put_Height(m_dHeight); - m_pRenderer->CreateFromBgraFrame(m_pFrame); - } - - CBgraFrame* ConvertVectorGraphics() - { - BYTE* pBuffer = m_pFrame->get_Data(); - - BYTE* pBufferSrcMem = pBuffer + 4 * m_oBounds.top * m_lWidthPix + 4 * m_oBounds.left; - int lWidthShape = (int)(m_oBounds.right - m_oBounds.left + 1); - int lHeightShape = (int)(m_oBounds.bottom - m_oBounds.top + 1); - - CBgraFrame* pReturnFrame = new CBgraFrame(); - pReturnFrame->put_Width(lWidthShape); - pReturnFrame->put_Height(lHeightShape); - pReturnFrame->put_Stride(4 * lWidthShape * lHeightShape); - - BYTE* pBufferDst = new BYTE[4 * lWidthShape * lHeightShape]; - pReturnFrame->put_Data(pBufferDst); - - for (LONG lLine = 0; lLine < lHeightShape; ++lLine) - { - memcpy(pBufferDst, pBufferSrcMem, 4 * lWidthShape); - - pBufferDst += 4 * lWidthShape; - pBufferSrcMem += 4 * m_lWidthPix; - } - - return pReturnFrame; - } - - public: - inline HRESULT get_Type(LONG* lType) - { - if (m_pRenderer) - return m_pRenderer->get_Type(lType); - return S_OK; - } - - //-------- Функции для работы со страницей -------------------------------------------------- - inline HRESULT NewPage() - { - if (m_pRenderer) - return m_pRenderer->NewPage(); - return S_OK; - } - inline HRESULT get_Height(double* dHeight) - { - if (m_pRenderer) - return m_pRenderer->get_Height(dHeight); - return S_OK; - } - inline HRESULT put_Height(const double& dHeight) - { - if (m_pRenderer) - return m_pRenderer->put_Height(dHeight); - return S_OK; - } - inline HRESULT get_Width(double* dWidth) - { - if (m_pRenderer) - return m_pRenderer->get_Width(dWidth); - return S_OK; - } - inline HRESULT put_Width(const double& dWidth) - { - if (m_pRenderer) - return m_pRenderer->put_Width(dWidth); - return S_OK; - } - inline HRESULT get_DpiX(double* dDpiX) - { - if (m_pRenderer) - return m_pRenderer->get_DpiX(dDpiX); - return S_OK; - } - inline HRESULT get_DpiY(double* dDpiY) - { - if (m_pRenderer) - return m_pRenderer->get_DpiY(dDpiY); - return S_OK; - } - - // pen -------------------------------------------------------------------------------------- - inline HRESULT get_PenColor(LONG* lColor) - { - if (m_pRenderer) - return m_pRenderer->get_PenColor(lColor); - return S_OK; - } - inline HRESULT put_PenColor(const LONG& lColor) - { - if (m_pRenderer) - return m_pRenderer->put_PenColor(lColor); - return S_OK; - } - inline HRESULT get_PenAlpha(LONG* lAlpha) - { - if (m_pRenderer) - return m_pRenderer->get_PenAlpha(lAlpha); - return S_OK; - } - inline HRESULT put_PenAlpha(const LONG& lAlpha) - { - if (m_pRenderer) - return m_pRenderer->put_PenAlpha(lAlpha); - return S_OK; - } - inline HRESULT get_PenSize(double* dSize) - { - if (m_pRenderer) - return m_pRenderer->get_PenSize(dSize); - return S_OK; - } - inline HRESULT put_PenSize(const double& dSize) - { - if (m_pRenderer) - return m_pRenderer->put_PenSize(dSize); - return S_OK; - } - inline HRESULT get_PenDashStyle(BYTE* val) - { - if (m_pRenderer) - return m_pRenderer->get_PenDashStyle(val); - return S_OK; - } - inline HRESULT put_PenDashStyle(const BYTE& val) - { - if (m_pRenderer) - return m_pRenderer->put_PenDashStyle(val); - return S_OK; - } - inline HRESULT get_PenLineStartCap(BYTE* val) - { - if (m_pRenderer) - return m_pRenderer->get_PenLineStartCap(val); - return S_OK; - } - inline HRESULT put_PenLineStartCap(const BYTE& val) - { - if (m_pRenderer) - return m_pRenderer->put_PenLineStartCap(val); - return S_OK; - } - inline HRESULT get_PenLineEndCap(BYTE* val) - { - if (m_pRenderer) - return m_pRenderer->get_PenLineEndCap(val); - return S_OK; - } - inline HRESULT put_PenLineEndCap(const BYTE& val) - { - if (m_pRenderer) - return m_pRenderer->put_PenLineEndCap(val); - return S_OK; - } - inline HRESULT get_PenLineJoin(BYTE* val) - { - if (m_pRenderer) - return m_pRenderer->get_PenLineJoin(val); - return S_OK; - } - inline HRESULT put_PenLineJoin(const BYTE& val) - { - if (m_pRenderer) - return m_pRenderer->put_PenLineJoin(val); - return S_OK; - } - inline HRESULT get_PenDashOffset(double* dOffset) - { - if (m_pRenderer) - return m_pRenderer->get_PenDashOffset(dOffset); - return S_OK; - } - inline HRESULT put_PenDashOffset(const double& dOffset) - { - if (m_pRenderer) - return m_pRenderer->put_PenDashOffset(dOffset); - return S_OK; - } - inline HRESULT get_PenAlign(LONG* lAlign) - { - if (m_pRenderer) - return m_pRenderer->get_PenAlign(lAlign); - return S_OK; - } - inline HRESULT put_PenAlign(const LONG& lAlign) - { - if (m_pRenderer) - return m_pRenderer->put_PenAlign(lAlign); - return S_OK; - } - inline HRESULT get_PenMiterLimit(double* dOffset) - { - if (m_pRenderer) - return m_pRenderer->get_PenMiterLimit(dOffset); - return S_OK; - } - inline HRESULT put_PenMiterLimit(const double& dOffset) - { - if (m_pRenderer) - return m_pRenderer->put_PenMiterLimit(dOffset); - return S_OK; - } - inline HRESULT PenDashPattern(double* pPattern, LONG lCount) - { - if (m_pRenderer) - return m_pRenderer->PenDashPattern(pPattern, lCount); - return S_OK; - } - - // brush ------------------------------------------------------------------------------------ - inline HRESULT get_BrushType(LONG* lType) - { - if (m_pRenderer) - return m_pRenderer->get_BrushType(lType); - return S_OK; - } - inline HRESULT put_BrushType(const LONG& lType) - { - if (m_pRenderer) - return m_pRenderer->put_BrushType(lType); - return S_OK; - } - inline HRESULT get_BrushColor1(LONG* lColor) - { - if (m_pRenderer) - return m_pRenderer->get_BrushColor1(lColor); - return S_OK; - } - inline HRESULT put_BrushColor1(const LONG& lColor) - { - if (m_pRenderer) - return m_pRenderer->put_BrushColor1(lColor); - return S_OK; - } - inline HRESULT get_BrushAlpha1(LONG* lAlpha) - { - if (m_pRenderer) - return m_pRenderer->get_BrushAlpha1(lAlpha); - return S_OK; - } - inline HRESULT put_BrushAlpha1(const LONG& lAlpha) - { - if (m_pRenderer) - return m_pRenderer->put_BrushAlpha1(lAlpha); - return S_OK; - } - inline HRESULT get_BrushColor2(LONG* lColor) - { - if (m_pRenderer) - return m_pRenderer->get_BrushColor2(lColor); - return S_OK; - } - inline HRESULT put_BrushColor2(const LONG& lColor) - { - if (m_pRenderer) - return m_pRenderer->put_BrushColor2(lColor); - return S_OK; - } - inline HRESULT get_BrushAlpha2(LONG* lAlpha) - { - if (m_pRenderer) - return m_pRenderer->get_BrushAlpha2(lAlpha); - return S_OK; - } - inline HRESULT put_BrushAlpha2(const LONG& lAlpha) - { - if (m_pRenderer) - return m_pRenderer->put_BrushAlpha2(lAlpha); - return S_OK; - } - inline HRESULT get_BrushTexturePath(std::wstring* bsPath) - { - if (m_pRenderer) - return m_pRenderer->get_BrushTexturePath(bsPath); - return S_OK; - } - inline HRESULT put_BrushTexturePath(const std::wstring& bsPath) - { - if (m_pRenderer) - return m_pRenderer->put_BrushTexturePath(bsPath); - return S_OK; - } - inline HRESULT get_BrushTextureMode(LONG* lMode) - { - if (m_pRenderer) - return m_pRenderer->get_BrushTextureMode(lMode); - return S_OK; - } - inline HRESULT put_BrushTextureMode(const LONG& lMode) - { - if (m_pRenderer) - return m_pRenderer->put_BrushTextureMode(lMode); - return S_OK; - } - inline HRESULT get_BrushTextureAlpha(LONG* lTxAlpha) - { - if (m_pRenderer) - return m_pRenderer->get_BrushTextureAlpha(lTxAlpha); - return S_OK; - } - inline HRESULT put_BrushTextureAlpha(const LONG& lTxAlpha) - { - if (m_pRenderer) - return m_pRenderer->put_BrushTextureAlpha(lTxAlpha); - return S_OK; - } - inline HRESULT get_BrushLinearAngle(double* dAngle) - { - if (m_pRenderer) - return m_pRenderer->get_BrushLinearAngle(dAngle); - return S_OK; - } - inline HRESULT put_BrushLinearAngle(const double& dAngle) - { - if (m_pRenderer) - return m_pRenderer->put_BrushLinearAngle(dAngle); - return S_OK; - } - inline HRESULT BrushRect(const INT& val, const double& left, const double& top, const double& width, const double& height) - { - if (m_pRenderer) - return m_pRenderer->BrushRect(val, left, top, width, height); - return S_OK; - } - inline HRESULT BrushBounds(const double& left, const double& top, const double& width, const double& height) - { - if (m_pRenderer) - return m_pRenderer->BrushBounds(left, top, width, height); - return S_OK; - } - inline HRESULT put_BrushGradientColors(LONG* lColors, double* pPositions, LONG nCount) - { - if (m_pRenderer) - return m_pRenderer->put_BrushGradientColors(lColors, pPositions, nCount); - return S_OK; - } - - // font ------------------------------------------------------------------------------------- - inline HRESULT get_FontName(std::wstring* bsName) - { - if (m_pRenderer) - return m_pRenderer->get_FontName(bsName); - return S_OK; - } - inline HRESULT put_FontName(const std::wstring& bsName) - { - if (m_pRenderer) - return m_pRenderer->put_FontName(bsName); - return S_OK; - } - inline HRESULT get_FontPath(std::wstring* bsName) - { - if (m_pRenderer) - return m_pRenderer->get_FontPath(bsName); - return S_OK; - } - inline HRESULT put_FontPath(const std::wstring& bsName) - { - if (m_pRenderer) - return m_pRenderer->put_FontPath(bsName); - return S_OK; - } - inline HRESULT get_FontSize(double* dSize) - { - if (m_pRenderer) - return m_pRenderer->get_FontSize(dSize); - return S_OK; - } - inline HRESULT put_FontSize(const double& dSize) - { - if (m_pRenderer) - return m_pRenderer->put_FontSize(dSize); - return S_OK; - } - inline HRESULT get_FontStyle(LONG* lStyle) - { - if (m_pRenderer) - return m_pRenderer->get_FontStyle(lStyle); - return S_OK; - } - inline HRESULT put_FontStyle(const LONG& lStyle) - { - if (m_pRenderer) - return m_pRenderer->put_FontStyle(lStyle); - return S_OK; - } - inline HRESULT get_FontStringGID(INT* bGID) - { - if (m_pRenderer) - return m_pRenderer->get_FontStringGID(bGID); - return S_OK; - } - inline HRESULT put_FontStringGID(const INT& bGID) - { - if (m_pRenderer) - return m_pRenderer->put_FontStringGID(bGID); - return S_OK; - } - inline HRESULT get_FontCharSpace(double* dSpace) - { - if (m_pRenderer) - return m_pRenderer->get_FontCharSpace(dSpace); - return S_OK; - } - inline HRESULT put_FontCharSpace(const double& dSpace) - { - if (m_pRenderer) - return m_pRenderer->put_FontCharSpace(dSpace); - return S_OK; - } - inline HRESULT get_FontFaceIndex(int* lFaceIndex) - { - if (m_pRenderer) - return m_pRenderer->get_FontFaceIndex(lFaceIndex); - return S_OK; - } - inline HRESULT put_FontFaceIndex(const int& lFaceIndex) - { - if (m_pRenderer) - return m_pRenderer->put_FontFaceIndex(lFaceIndex); - return S_OK; - } - - //-------- Функции для вывода текста -------------------------------------------------------- - inline HRESULT CommandDrawTextCHAR(const LONG& c, const double& x, const double& y, const double& w, const double& h) - { - if (m_pRenderer) - return m_pRenderer->CommandDrawTextCHAR(c, x, y, w, h); - return S_OK; - } - inline HRESULT CommandDrawText(const std::wstring& bsText, const double& x, const double& y, const double& w, const double& h) - { - if (m_pRenderer) - return m_pRenderer->CommandDrawText(bsText, x, y, w, h); - return S_OK; - } - inline HRESULT CommandDrawTextExCHAR(const LONG& c, const LONG& gid, const double& x, const double& y, const double& w, const double& h) - { - if (m_pRenderer) - return m_pRenderer->CommandDrawTextExCHAR(c, gid, x, y, w, h); - return S_OK; - } - inline HRESULT CommandDrawTextEx(const std::wstring& bsUnicodeText, const unsigned int* pGids, const unsigned int nGidsCount, const double& x, const double& y, const double& w, const double& h) - { - if (m_pRenderer) - return m_pRenderer->CommandDrawTextEx(bsUnicodeText, pGids, nGidsCount, x, y, w, h); - return S_OK; - } - - //-------- Маркеры для команд --------------------------------------------------------------- - inline HRESULT BeginCommand(const DWORD& lType) - { - if (m_pRenderer) - return m_pRenderer->BeginCommand(lType); - return S_OK; - } - inline HRESULT EndCommand(const DWORD& lType) - { - if (m_pRenderer) - return m_pRenderer->EndCommand(lType); - return S_OK; - } - - //-------- Функции для работы с Graphics Path ----------------------------------------------- - inline HRESULT PathCommandMoveTo(const double& x, const double& y) - { - if (m_pRenderer) - return m_pRenderer->PathCommandMoveTo(x, y); - return S_OK; - } - inline HRESULT PathCommandLineTo(const double& x, const double& y) - { - if (m_pRenderer) - return m_pRenderer->PathCommandLineTo(x, y); - return S_OK; - } - inline HRESULT PathCommandLinesTo(double* points, const int& count) - { - if (m_pRenderer) - return m_pRenderer->PathCommandLinesTo(points, count); - return S_OK; - } - inline HRESULT PathCommandCurveTo(const double& x1, const double& y1, const double& x2, const double& y2, const double& x3, const double& y3) - { - if (m_pRenderer) - return m_pRenderer->PathCommandCurveTo(x1, y1, x2, y2, x3, y3); - return S_OK; - } - inline HRESULT PathCommandCurvesTo(double* points, const int& count) - { - if (m_pRenderer) - return m_pRenderer->PathCommandCurvesTo(points, count); - return S_OK; - } - inline HRESULT PathCommandArcTo(const double& x, const double& y, const double& w, const double& h, const double& startAngle, const double& sweepAngle) - { - if (m_pRenderer) - return m_pRenderer->PathCommandArcTo(x, y, w, h, startAngle, sweepAngle); - return S_OK; - } - inline HRESULT PathCommandClose() - { - if (m_pRenderer) - return m_pRenderer->PathCommandClose(); - return S_OK; - } - inline HRESULT PathCommandEnd() - { - if (m_pRenderer) - return m_pRenderer->PathCommandEnd(); - return S_OK; - } - inline HRESULT DrawPath(const LONG& nType) - { - if (m_pRenderer) - return m_pRenderer->DrawPath(nType); - return S_OK; - } - inline HRESULT PathCommandStart() - { - if (m_pRenderer) - return m_pRenderer->PathCommandStart(); - return S_OK; - } - inline HRESULT PathCommandGetCurrentPoint(double* x, double* y) - { - if (m_pRenderer) - return m_pRenderer->PathCommandGetCurrentPoint(x, y); - return S_OK; - } - inline HRESULT PathCommandTextCHAR(const LONG& c, const double& x, const double& y, const double& w, const double& h) - { - if (m_pRenderer) - return m_pRenderer->PathCommandTextCHAR(c, x, y, w, h); - return S_OK; - } - inline HRESULT PathCommandText(const std::wstring& bsText, const double& x, const double& y, const double& w, const double& h) - { - if (m_pRenderer) - return m_pRenderer->PathCommandText(bsText, x, y, w, h); - return S_OK; - } - inline HRESULT PathCommandTextExCHAR(const LONG& c, const LONG& gid, const double& x, const double& y, const double& w, const double& h) - { - if (m_pRenderer) - return m_pRenderer->PathCommandTextExCHAR(c, gid, x, y, w, h); - return S_OK; - } - inline HRESULT PathCommandTextEx(const std::wstring& bsUnicodeText, const unsigned int* pGids, const unsigned int nGidsCount, const double& x, const double& y, const double& w, const double& h) - { - if (m_pRenderer) - return m_pRenderer->PathCommandTextEx(bsUnicodeText, pGids, nGidsCount, x, y, w, h); - return S_OK; - } - - //-------- Функции для вывода изображений --------------------------------------------------- - inline HRESULT DrawImage(IGrObject* pImage, const double& x, const double& y, const double& w, const double& h) - { - if (m_pRenderer) - return m_pRenderer->DrawImage(pImage, x, y, w, h); - return S_OK; - } - - inline HRESULT DrawImageFromFile(const std::wstring& sPath, const double& x, const double& y, const double& w, const double& h, const BYTE& lAlpha = 255) - { - if (m_pRenderer) - return m_pRenderer->DrawImageFromFile(sPath, x, y, w, h, lAlpha); - return S_OK; - } - - // transform -------------------------------------------------------------------------------- - inline HRESULT SetTransform(const double& m1, const double& m2, const double& m3, const double& m4, const double& m5, const double& m6) - { - if (m_pRenderer) - return m_pRenderer->SetTransform(m1, m2, m3, m4, m5, m6); - return S_OK; - } - inline HRESULT GetTransform(double *pdA, double *pdB, double *pdC, double *pdD, double *pdE, double *pdF) - { - if (m_pRenderer) - return m_pRenderer->GetTransform(pdA, pdB, pdC, pdD, pdE, pdF); - return S_OK; - } - inline HRESULT ResetTransform() - { - if (m_pRenderer) - return m_pRenderer->ResetTransform(); - return S_OK; - } - - // ----------------------------------------------------------------------------------------- - inline HRESULT get_ClipMode(LONG* plMode) - { - if (m_pRenderer) - return m_pRenderer->get_ClipMode(plMode); - return S_OK; - } - inline HRESULT put_ClipMode(const LONG& lMode) - { - if (m_pRenderer) - return m_pRenderer->put_ClipMode(lMode); - return S_OK; - } - - inline virtual HRESULT StartConvertCoordsToIdentity() - { - if (m_pRenderer) - m_pRenderer->StartConvertCoordsToIdentity(); - return S_OK; - } - inline virtual HRESULT EndConvertCoordsToIdentity() - { - if (m_pRenderer) - m_pRenderer->EndConvertCoordsToIdentity(); - return S_OK; - } - }; - - - class CPageMeta - { - public: - double m_dWidth; - double m_dHeight; - LONG m_lStart; - LONG m_lEnd; - - public: - CPageMeta() - { - m_dWidth = 0; - m_dHeight = 0; - m_lStart = 0; - m_lEnd = 0; - } - CPageMeta(const CPageMeta& oSrc) - { - *this = oSrc; - } - - CPageMeta& operator=(const CPageMeta& oSrc) - { - m_dWidth = oSrc.m_dWidth; - m_dHeight = oSrc.m_dHeight; - m_lStart = oSrc.m_lStart; - m_lEnd = oSrc.m_lEnd; - - return *this; - } - }; - - class CFontEmbedded - { - public: - std::map m_mapChars; - - std::wstring m_strFontName; - LONG m_lFontStyle; - int m_lFontPathLen; - - std::wstring m_strFontPath; - DWORD m_dwCRC32; - - public: - CFontEmbedded() : m_mapChars() - { - m_strFontName = L""; - m_strFontPath = L""; - - m_lFontPathLen = 0; - m_lFontStyle = 0; - m_dwCRC32 = 0; - } - CFontEmbedded(const CFontEmbedded& oSrc) - { - *this = oSrc; - } - CFontEmbedded& operator=(const CFontEmbedded& oSrc) - { - m_strFontPath = oSrc.m_strFontPath; - m_strFontName = oSrc.m_strFontName; - m_lFontStyle = oSrc.m_lFontStyle; - m_dwCRC32 = oSrc.m_dwCRC32; - - m_lFontPathLen = oSrc.m_lFontPathLen; - - for (std::map::const_iterator i = oSrc.m_mapChars.begin(); i != oSrc.m_mapChars.end(); i++) - { - m_mapChars.insert(std::pair(i->first, i->second)); - } - return *this; - } - - public: - void AddString(const int* sText, const int& len) - { - if (NULL != sText) - { - for (int i = 0; i < len; ++i) - { - if (m_mapChars.end() == m_mapChars.find(sText[i])) - m_mapChars.insert(std::pair(sText[i], 1)); - } - } - } - void GenerateArray(int*& pData, int& nCount) - { - nCount = m_mapChars.size(); - if (0 == nCount) - return; - - pData = new int[nCount]; - - int* pDataCur = pData; - for (std::map::const_iterator i = m_mapChars.begin(); i != m_mapChars.end(); i++) - { - *pDataCur++ = i->first; - } - } - }; - - class CFontDstGenerator - { - public: - CFontEmbedded* m_pFonts; - LONG m_lCurrentIndex; - LONG m_lCountFonts; - LONG m_lSize; - - std::map m_mapFontPathCRC; - std::map m_mapFontCRCIndex; - CCalculatorCRC32 m_oCalc; - - std::wstring m_strCurrentFontPath; - int m_lCurrentFontStyle; - int m_lCurrentFontPathLen; - std::map m_mapFontPathToIndex; - - public: - CFontDstGenerator() - { - m_lSize = 50; - m_pFonts = NULL; - m_lCurrentIndex = -1; - m_lCountFonts = 0; - - m_strCurrentFontPath = L""; - m_lCurrentFontPathLen = 0; - m_lCurrentFontStyle = -1; - - Grow(); - } - ~CFontDstGenerator() - { - RELEASEARRAYOBJECTS(m_pFonts); - } - public: - - LONG AddFont(NSStructures::CFont* pFont, CFontManagerBase* pBase, const int* symbols, const int& count) - { - // TODO: - // нужно учитывать FaceIndex. В пдфах не бывает никогда таких файлов (но могут) - // поэтому решил не менять, чтобы не нарушить. Как будет время - сделать зависимость кэша - // не только от пути, но и от индекса - - bool bIsDumpFontEmptyPath = false; - - int nLen = (int)pFont->Path.length(); - if (nLen == 0) - { - pFont->Path = pBase->GetFontPath(pFont); - nLen = pFont->Path.length(); - bIsDumpFontEmptyPath = true; - } - - LONG lNewStyle = pFont->GetStyle2(); - - bool bIsFontChanged = true; - if (nLen == m_lCurrentFontPathLen && (m_lCurrentFontStyle == lNewStyle)) - { - if (m_strCurrentFontPath == pFont->Path) - bIsFontChanged = false; - } - - if (!bIsFontChanged) - { - m_pFonts[m_lCurrentIndex].AddString(symbols, count); - - if (bIsDumpFontEmptyPath) - pFont->Path = L""; - - return m_lCurrentIndex; - } - - std::map::const_iterator pPairIndex = m_mapFontPathToIndex.find(pFont->Path); - if (m_mapFontPathToIndex.end() != pPairIndex) - { - m_lCurrentIndex = pPairIndex->second; - - NSHtmlRenderer::CFontEmbedded* pEmb = &m_pFonts[m_lCurrentIndex]; - - m_strCurrentFontPath = pFont->Path; - m_lCurrentFontPathLen = nLen; - m_lCurrentFontStyle = lNewStyle; - - pEmb->AddString(symbols, count); - - if (bIsDumpFontEmptyPath) - pFont->Path = L""; - - return m_lCurrentIndex; - } - - // такой путь еще не приходил. - // первым делом проверим, не совпадает ли он с каким-то (по чексумме) - NSFile::CFileBinary oFile; - oFile.OpenFile(pFont->Path); - DWORD lFontFileSize = (DWORD)oFile.GetFileSize(); - BYTE* pFontPathData = new BYTE[lFontFileSize]; - DWORD dwRead = 0; - oFile.ReadFile(pFontPathData, lFontFileSize, dwRead); - DWORD dwCRC32 = m_oCalc.Calc(pFontPathData, (int)lFontFileSize); - - oFile.CloseFile(); - RELEASEARRAYOBJECTS(pFontPathData); - - std::map::const_iterator pPair2 = m_mapFontCRCIndex.find(dwCRC32); - if (m_mapFontCRCIndex.end() == pPair2) - { - // шрифт реально новый - m_mapFontCRCIndex.insert(std::pair(dwCRC32, m_lCountFonts)); - m_mapFontPathToIndex.insert(std::pair(pFont->Path, m_lCountFonts)); - } - else - { - m_lCurrentIndex = pPair2->second; - m_mapFontPathToIndex.insert(std::pair(pFont->Path, m_lCurrentIndex)); - - m_strCurrentFontPath = pFont->Path; - m_lCurrentFontPathLen = nLen; - m_lCurrentFontStyle = lNewStyle; - - m_pFonts[m_lCurrentIndex].AddString(symbols, count); - - if (bIsDumpFontEmptyPath) - pFont->Path = L""; - - return m_lCurrentIndex; - } - - if (m_lCountFonts == m_lSize) - { - // нужно перевыделить память - Grow(); - } - - m_lCurrentIndex = m_lCountFonts; - ++m_lCountFonts; - - NSHtmlRenderer::CFontEmbedded* pCurEmb = &m_pFonts[m_lCurrentIndex]; - pCurEmb->m_strFontName = pFont->Name; - pCurEmb->m_strFontPath = pFont->Path; - pCurEmb->m_lFontStyle = lNewStyle; - pCurEmb->m_lFontPathLen = nLen; - pCurEmb->AddString(symbols, count); - - // теперь нужно найти к нему путь... - if (0 == nLen) - { - pCurEmb->m_strFontPath = pBase->GetFontPath(pFont); - pCurEmb->m_lFontPathLen = pCurEmb->m_strFontPath.length(); - } - - if (bIsDumpFontEmptyPath) - pFont->Path = L""; - - m_strCurrentFontPath = pCurEmb->m_strFontPath; - m_lCurrentFontPathLen = pCurEmb->m_lFontPathLen; - m_lCurrentFontStyle = pCurEmb->m_lFontStyle; - - return m_lCurrentIndex; - } - - - public: - void WriteFonts(NSFonts::IFontManager* pFontManager, const std::wstring& strFolderDst, bool bIsGid = false) - { - std::wstring sDstF = strFolderDst; - NSDirectory::CreateDirectory(sDstF); - - std::wstring strAllTypes = L""; - - std::wstring strTempFont = sDstF + L"/font.tmp"; - - CFontConverter oFontConverter; - - LONG lFontConverterFlag = 16; - if (bIsGid) - lFontConverterFlag |= 0x0080; - - for (LONG lIndex = 0; lIndex < m_lCountFonts; ++lIndex) - { - CFontEmbedded& oCur = m_pFonts[lIndex]; - pFontManager->LoadFontFromFile(oCur.m_strFontPath, 0, 12, 72, 72); - - std::wstring sName = L""; - - std::wstring sNameSrc = pFontManager->GetName(); - int nNameLen = (int)sNameSrc.length(); - const wchar_t* pNameStr = sNameSrc.c_str(); - for (int i = 0; i < nNameLen; ++i) - { - if ((pNameStr[i] >= 'a' && pNameStr[i] <= 'z') || - (pNameStr[i] >= 'A' && pNameStr[i] <= 'Z') || - (pNameStr[i] >= '0' && pNameStr[i] <= '9')) - { - sName.push_back(pNameStr[i]); - } - else - { - sName.push_back((wchar_t)'_'); - } - } - - strAllTypes += (L"embedded" + std::to_wstring(lIndex)); - strAllTypes += L": "; - strAllTypes += pFontManager->GetFontType(); - strAllTypes += L", "; - strAllTypes += sName; - strAllTypes += L"\n"; - - int* symbols = NULL; - int symbolsCount = 0; - oCur.GenerateArray(symbols, symbolsCount); - - // есть проблема с композитными глифами (буква ё). пока отключу конвертацию - lFontConverterFlag = 0; - oFontConverter.ToOTF(oCur.m_strFontPath, strTempFont, (unsigned int*)symbols, symbolsCount, sName, lFontConverterFlag); // TRUETYPE only - - RELEASEARRAYOBJECTS(symbols); - - // dump font - NSFile::CFileBinary oFileFontFile; - oFileFontFile.OpenFile(strTempFont); - - int nInputLen = (int)oFileFontFile.GetFileSize(); - BYTE* pData = new BYTE[nInputLen]; - DWORD dwReadSize = 0; - oFileFontFile.ReadFile(pData, (DWORD)nInputLen, dwReadSize); - oFileFontFile.CloseFile(); - - char* pOutput = NULL; - int nOutputLen = 0; - NSFile::CBase64Converter::Encode(pData, nInputLen, pOutput, nOutputLen, NSBase64::B64_BASE64_FLAG_NOCRLF); - - NSFile::CFileBinary oFileFontFileJS; - oFileFontFileJS.CreateFileW(sDstF + L"/embedded" + std::to_wstring(lIndex) + L".js"); - - std::string sHeader = "window[\"embedded" + std::to_string(lIndex) + "\"] = \"" + std::to_string(nInputLen) + ";"; - oFileFontFileJS.WriteFile((const BYTE*)sHeader.c_str(), sHeader.length()); - oFileFontFileJS.WriteFile((const BYTE*)pOutput, nOutputLen); - std::string sFooter = "\";"; - oFileFontFileJS.WriteFile((const BYTE*)sFooter.c_str(), sFooter.length()); - - RELEASEARRAYOBJECTS(pOutput); - RELEASEARRAYOBJECTS(pData); - - NSFile::CFileBinary::Remove(strTempFont); - } - - NSFile::CFileBinary oFileFontFileJS_type; - oFileFontFileJS_type.CreateFileW(sDstF + L"/types.txt"); - oFileFontFileJS_type.WriteStringUTF8(strAllTypes); - oFileFontFileJS_type.CloseFile(); - } - - protected: - void Grow() - { - if (NULL == m_pFonts) - { - m_pFonts = new CFontEmbedded[m_lSize]; - return; - } - - m_lSize *= 2; - CFontEmbedded* pNewBuffer = new CFontEmbedded[m_lSize]; - for (LONG i = 0; i < m_lCountFonts; ++i) - { - pNewBuffer[i] = m_pFonts[i]; - } - RELEASEARRAYOBJECTS(m_pFonts); - m_pFonts = pNewBuffer; - } - }; - - class CWriter - { - public: - CMetafile m_oPage; - CSVGWriter2 m_oSVGWriter; - - std::vector m_arrPages; - bool m_bIsBigPicture; - - int m_lTilingCounter; - - public: - NSStructures::CPen* m_pPen; - NSStructures::CBrush* m_pBrush; - NSStructures::CFont* m_pFont; - - NSStructures::CPen m_oLastPen; - NSStructures::CBrush m_oLastBrush; - - int m_lCurrentFont; - double m_dCurrentFontSize; - - CFontDstGenerator m_oDstFontGenerator; - NSHtmlRenderer::CFontManager m_oFontManager; - - CHText m_oSmartText; - - double m_dDpiX; - double m_dDpiY; - - bool m_bPathClosed; - - std::map m_mapImagesFile; - std::map m_mapImageData; - - CCalculatorCRC32 m_oCRC; - - double m_dWidthDocMM; - double m_dHeightDocMM; - double m_dHeightPageMM; - - Aggplus::CGraphicsPathSimpleConverter* m_pSimpleConverter; - NSFile::CFileBinary m_oFileWriter; - - bool m_bIsGids; - - NSFonts::IApplicationFonts* m_pApplicationFonts; - - public: - - double m_dWidth; - double m_dHeight; - bool m_bIsImageFromVectors; - - private: - - LONG m_lNextIDShape; - LONG m_lNextIDImage; - - LONG m_lCurrentPage; - LONG m_lCurrentFunctionPage; - LONG m_lPagesCount; - - LONG m_lMaxSizeImage; - - public: - std::wstring m_strDstDirectory; - std::wstring m_strDstMedia; - std::wstring m_strDstDirectoryFiles; - std::wstring m_strFileName; - - Aggplus::CMatrix* m_pTransform; - Aggplus::CMatrix m_oLastTransform; - - int m_lCurrentDumpSize; - - int m_lSrcFileType; - - bool m_bIsClipping; - bool m_bIsSimpleGraphics; - - bool m_bIsOnlyTextMode; - - public: - CWriter() - { - m_dDpiX = 96.0; - m_dDpiY = 96.0; - - m_dWidth = 0; - m_dHeight = 0; - - m_lNextIDImage = 0; - m_lNextIDShape = 0; - - m_lCurrentPage = -1; - - m_bPathClosed = true; - - m_pSimpleConverter = NULL; - - m_lMaxSizeImage = 800; - - m_dWidthDocMM = 0; - m_dHeightDocMM = 0; - m_dHeightPageMM = 0; - - m_lPagesCount = 0; - - m_bIsImageFromVectors = false; - - m_lSrcFileType = 0; - - m_bIsClipping = false; - m_bIsSimpleGraphics = false; - m_lTilingCounter = 0; - - m_bIsOnlyTextMode = false; - } - - void SetApplicationFonts(NSFonts::IApplicationFonts* pFonts) - { - m_pApplicationFonts = pFonts; - } - - void SetSimpleConverter(Aggplus::CGraphicsPathSimpleConverter* pSimpleConverter, Aggplus::CMatrix* pMatrix) - { - m_pSimpleConverter = pSimpleConverter; - m_pTransform = pMatrix; - - m_oSVGWriter.m_pTransform = m_pTransform; - - m_oSVGWriter.m_pPen = m_pPen; - m_oSVGWriter.m_pBrush = m_pBrush; - - m_oSVGWriter.m_pLastPen = &m_oLastPen; - m_oSVGWriter.m_pLastBrush = &m_oLastBrush; - } - - void WriteText(const int* pUnicodes, const int* pGids, const int& nCount, const double& x, const double& y, - const double& width, const double& height, const bool& bIsChangedFontParamBetweenDrawText) - { - if (m_lSrcFileType == AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_DJVU) - { - // не нужно ничего писать из djvu - return; - } - - CheckVectorGraphics(); - CheckTectClipRect(); - - bool bIsDumpFont = false; - - if (m_lCurrentFont == -1 || bIsChangedFontParamBetweenDrawText) - { - const int* pSymbols = (NULL == pGids) ? pUnicodes : pGids; - LONG lCurrentFontIndex = m_oDstFontGenerator.AddFont(m_pFont, &m_oFontManager, pSymbols, nCount); - if ((lCurrentFontIndex != m_lCurrentFont) || (m_pFont->Size != m_dCurrentFontSize)) - { - m_lCurrentFont = lCurrentFontIndex; - m_dCurrentFontSize = m_pFont->Size; - - bIsDumpFont = true; - } - } - else - { - const int* pSymbols = (NULL == pGids) ? pUnicodes : pGids; - m_oDstFontGenerator.m_pFonts[m_lCurrentFont].AddString(pSymbols, nCount); - } - - if (NULL != pGids) - m_bIsGids = true; - - m_oSmartText.CommandText(pUnicodes, pGids, nCount, x, y, width, height, bIsDumpFont, this); - return; - } - - inline void CheckTectClipRect() - { - // смотрим, нужно ли обновить рект для клиппирования текста - if (m_oSVGWriter.m_bIsTextClipWriteCleared) - { - if (!m_oSVGWriter.m_oTextClipBounds.IsCleared) - { - m_oSmartText.DumpLine(); - // записать клип - m_oPage.WriteCommandType(CMetafile::ctCommandTextClipRect); - m_oPage.WriteDouble(m_oSVGWriter.m_oTextClipBounds.x); - m_oPage.WriteDouble(m_oSVGWriter.m_oTextClipBounds.y); - m_oPage.WriteDouble(m_oSVGWriter.m_oTextClipBounds.r); - m_oPage.WriteDouble(m_oSVGWriter.m_oTextClipBounds.b); - m_oSVGWriter.m_bIsTextClipWriteCleared = false; - } - } - else - { - if (m_oSVGWriter.m_oTextClipBounds.IsCleared) - { - m_oSmartText.DumpLine(); - // записать команду сброса клипа текстректа - m_oPage.WriteCommandType(CMetafile::ctCommandTextClipRectReset); - m_oSVGWriter.m_bIsTextClipWriteCleared = true; - return; - } - else if (m_oSVGWriter.m_bIsIntersectNewClipRect) - { - m_oSmartText.DumpLine(); - // записать клип - m_oPage.WriteCommandType(CMetafile::ctCommandTextClipRect); - m_oPage.WriteDouble(m_oSVGWriter.m_oTextClipBounds.x); - m_oPage.WriteDouble(m_oSVGWriter.m_oTextClipBounds.y); - m_oPage.WriteDouble(m_oSVGWriter.m_oTextClipBounds.r); - m_oPage.WriteDouble(m_oSVGWriter.m_oTextClipBounds.b); - m_oSVGWriter.m_bIsIntersectNewClipRect = false; - } - } - } - - inline void WriteBeginPath() - { - } - inline void WriteEndPath() - { - m_oSVGWriter.WritePathEnd(); - } - inline void WritePathStart() - { - } - inline void WritePathClose() - { - m_oSVGWriter.WritePathClose(); - } - inline void WritePathMoveTo(const double& x, const double& y) - { - m_oSVGWriter.WritePathMoveTo(x, y); - } - inline void WritePathLineTo(const double& x, const double& y) - { - m_oSVGWriter.WritePathLineTo(x, y); - } - inline void WritePathCurveTo(const double& x1, const double& y1, const double& x2, const double& y2, const double& x3, const double& y3) - { - m_oSVGWriter.WritePathCurveTo(x1, y1, x2, y2, x3, y3); - } - inline void WriteDrawPath(LONG lType) - { - /* - if (lType > 0xFF) - { - if (!m_oLastBrush.IsEqual(m_pBrush)) - { - m_oLastBrush = *m_pBrush; - SetFillColor(true); - } - } - if (lType & 0x01) - { - if (!m_oLastPen.IsEqual(m_pPen)) - { - m_oLastPen = *m_pPen; - SetStrokeColor(true); - SetLineWidth(true); - } - } - - m_oVectors.WriteCommandType(CMetafile::ctDrawPath); - m_oVectors.WriteLONG(lType); - */ - - CImageInfo oInfo; - if ((lType > 0xFF) && (c_BrushTypeTexture == m_pBrush->Type)) - { - oInfo = GenerateImageID(m_pBrush->TexturePath); - - if (TRUE) - { - // пока делаем так - double x = 0; - double y = 0; - double w = 0; - double h = 0; - m_pSimpleConverter->PathCommandGetBounds(x, y, w, h); - - CheckVectorGraphics(); - - /* - bool bIsClip = (m_oSVGWriter.m_oClipMetafile.GetPosition() > 0) ? true : false; - if (bIsClip) - m_oPage.Write(m_oSVGWriter.m_oClipMetafile); - */ - LONG _oldPos = m_oSVGWriter.WriteTempClip(); - m_oPage.Write(m_oSVGWriter.m_oClipMetafile); - - WriteImage2(oInfo, x, y, w, h); - - m_oSVGWriter.m_oClipMetafile.Seek(_oldPos); - - /* - if (bIsClip) - m_oPage.WriteLONG(CMetafile::ctBeginCommand, c_nResetClipType); - */ - m_oPage.WriteLONG(CMetafile::ctBeginCommand, c_nResetClipType); - - lType &= 0xFF; - } - } - - m_oSVGWriter.WriteDrawPath(lType, m_pSimpleConverter, oInfo); - } - inline void WritePathClip() - { - m_oSVGWriter.WritePathClip(); - } - inline void WritePathClipEnd() - { - m_oSVGWriter.WritePathClipEnd(); - } - inline void WritePathResetClip() - { - m_oSVGWriter.WritePathResetClip(); - } - - void NewPage(const double& dWidthMM, const double& dHeightMM) - { - ++m_lPagesCount; - - CPageMeta oInfo; - oInfo.m_dWidth = dWidthMM; - oInfo.m_dHeight = dHeightMM; - oInfo.m_lStart = m_lCurrentDumpSize; - oInfo.m_lEnd = 0; - - m_dWidth = dWidthMM; - m_dHeight = dHeightMM; - - m_arrPages.push_back(oInfo); - - m_oLastBrush.Color1 = -1; - m_oLastPen.Color = -1; - - m_lCurrentFont = -1; - m_dCurrentFontSize = 0.0; - - m_oLastTransform.Reset(); - m_pTransform->Reset(); - - m_bIsBigPicture = false; - - m_oSVGWriter.NewDocument(m_dWidth, m_dHeight, m_lPagesCount - 1); - } - void EndPage() - { - m_oSmartText.ClosePage(); - CheckVectorGraphics(); - - m_arrPages[m_arrPages.size() - 1].m_lEnd = m_lCurrentDumpSize + m_oPage.GetPosition(); - m_lCurrentDumpSize += m_oPage.GetPosition(); - - if (!m_bIsOnlyTextMode) - m_oFileWriter.WriteFile(m_oPage.GetData(), m_oPage.GetPosition()); - - m_oPage.Clear(); - } - - void GetLastPageInfo(int& paragraphs, int& words, int& symbols, int& spaces, std::string& sBase64Data) - { - m_oSmartText.ClosePage(); - - paragraphs = (int)m_oSmartText.m_lCountParagraphs; - words = (int)m_oSmartText.m_lCountWords; - spaces = (int)m_oSmartText.m_lCountSpaces; - symbols = (int)m_oSmartText.m_lCountSymbols; - sBase64Data = ""; - - if (m_lPagesCount > 0) - { - char* pDst = NULL; - int nDst = 0; - NSFile::CBase64Converter::Encode(m_oPage.GetData(), (int)m_oPage.GetPosition(), pDst, nDst, NSBase64::B64_BASE64_FLAG_NOCRLF); - - if (0 < nDst) - sBase64Data = std::string(pDst, (size_t)nDst); - - sBase64Data = std::to_string((int)m_oPage.GetPosition()) + ";" + sBase64Data; - - RELEASEARRAYOBJECTS(pDst); - } - } - - inline void CheckVectorGraphics() - { - /* - if (0 < m_oVectors.GetPosition() && m_bIsSimpleGraphics && !m_oSVGWriter.m_bIsClipping) - { - m_oPage.Write(m_oVectors); - } - else if (m_oSVGWriter.m_oDocument.GetCurSize() > 0) - { - WriteImageID_SVG(); - } - - m_oVectors.ClearNoAttack(); - */ - if (m_oSVGWriter.m_lEmtyDocChecker < (ULONG)m_oSVGWriter.m_oDocument.GetCurSize()) - WriteImageID_SVG(); - } - - inline void WritePattern(CBgraFrame* pPattern, CTileInfo& oTile) - { - CheckVectorGraphics(); - m_oSmartText.DumpLine(); - SetTransformToDocument(true); - - NSHtmlRenderer::CImageInfo oInfo = GenerateImageID(pPattern); - - bool bIsClip = (m_oSVGWriter.m_oClipMetafile.GetPosition() > 0) ? true : false; - if (bIsClip) - m_oPage.Write(m_oSVGWriter.m_oClipMetafile); - - WriteImagePattrern(oInfo, oTile); - - if (bIsClip) - m_oPage.WriteLONG(CMetafile::ctBeginCommand, c_nResetClipType); - } - - inline void WriteImage(IGrObject* pImage, double x, double y, double width, double height) - { - CheckVectorGraphics(); - m_oSmartText.DumpLine(); - SetTransformToDocument(true); - - bool bIsClip = (m_oSVGWriter.m_oClipMetafile.GetPosition() > 0) ? true : false; - if (bIsClip) - m_oPage.Write(m_oSVGWriter.m_oClipMetafile); - - NSHtmlRenderer::CImageInfo oInfo = GenerateImageID(pImage); - //m_oSVGWriter.WriteImage(oInfo, x, y, width, height); - WriteImage2(oInfo, x, y, width, height); - - if (bIsClip) - m_oPage.WriteLONG(CMetafile::ctBeginCommand, c_nResetClipType); - } - inline void WriteImage(const std::wstring& sPath, double x, double y, double width, double height) - { - if (m_lTilingCounter > 0) - { - NSHtmlRenderer::CImageInfo oInfo = GenerateImageID(sPath); - m_oSVGWriter.WriteImage(oInfo, x, y, width, height); - return; - } - - CheckVectorGraphics(); - m_oSmartText.DumpLine(); - SetTransformToDocument(true); - - bool bIsClip = (m_oSVGWriter.m_oClipMetafile.GetPosition() > 0) ? true : false; - if (bIsClip) - m_oPage.Write(m_oSVGWriter.m_oClipMetafile); - - NSHtmlRenderer::CImageInfo oInfo = GenerateImageID(sPath); - //m_oSVGWriter.WriteImage(oInfo, x, y, width, height); - WriteImage2(oInfo, x, y, width, height); - - if (bIsClip) - m_oPage.WriteLONG(CMetafile::ctBeginCommand, c_nResetClipType); - } - - NSHtmlRenderer::CImageInfo GenerateImageID(IGrObject* pGrObject) - { - CBgraFrame* pFrame = new CBgraFrame(); - pFrame->FromImage(pGrObject, false); - - NSHtmlRenderer::CImageInfo _info = GenerateImageID(pFrame, true); - - pFrame->put_Data(NULL); - RELEASEOBJECT(pFrame); - return _info; - } - - NSHtmlRenderer::CImageInfo GenerateImageID(CBgraFrame* pFrame, bool bIsFromObject = false) - { - CImageInfo oInfo; - - if (NULL == pFrame) - return oInfo; - - int nLen = 4 * pFrame->get_Width() * pFrame->get_Height(); - BYTE* pBuffer = pFrame->get_Data(); - - DWORD dwSum = (DWORD)m_oCRC.Calc(pBuffer, nLen); - - std::map::const_iterator pPair = m_mapImageData.find(dwSum); - if (m_mapImageData.end() == pPair) - { - // нужно добавить - ++m_lNextIDImage; - - oInfo.m_lID = m_lNextIDImage; - SaveImage(pFrame, oInfo, !bIsFromObject); - - m_mapImageData.insert(std::pair(dwSum, oInfo)); - } - else - { - pFrame->put_Data(NULL); - oInfo = pPair->second; - } - - return oInfo; - } - CImageInfo GenerateImageID(const std::wstring& strFileName) - { - CImageInfo oInfo; - std::map::const_iterator pPair = m_mapImagesFile.find(strFileName); - - if (m_mapImagesFile.end() == pPair) - { - // нужно добавить - ++m_lNextIDImage; - - oInfo.m_lID = m_lNextIDImage; - - CBgraFrame oFrame; - oFrame.OpenFile(strFileName); - SaveImage(&oFrame, oInfo, true); - - m_mapImagesFile.insert(std::pair(strFileName, oInfo)); - } - else - { - oInfo = pPair->second; - } - - return oInfo; - } - - ImageType GetImageType(CBgraFrame* pFrame) - { - BYTE* pBufferMem = pFrame->get_Data() + 3; - LONG lCountPix = pFrame->get_Width() * pFrame->get_Height(); - - for (LONG i = 0; i < lCountPix; ++i, pBufferMem += 4) - { - if (255 != *pBufferMem) - return itPNG; - } - return itJPG; - } - - inline void SaveImage(CBgraFrame* pFrame, CImageInfo& oInfo, bool bIsDestroy) - { - oInfo.m_eType = GetImageType(pFrame); - - int lWidth = pFrame->get_Width(); - int lHeight = pFrame->get_Height(); - - bool bIsResized = false; - if (true || (lWidth <= m_lMaxSizeImage) && (lHeight <= m_lMaxSizeImage)) - { - // не ресайзим - } - else - { - LONG lW = 0; - LONG lH = 0; - double dAspect = (double)lWidth / lHeight; - - if (lWidth >= lHeight) - { - lW = m_lMaxSizeImage; - lH = (LONG)((double)lW / dAspect); - } - else - { - lH = m_lMaxSizeImage; - lW = (LONG)(dAspect * lH); - } - - bIsResized = true; - pFrame->Resize(lW, lH, bIsDestroy); - } - - std::wstring strSave = m_strDstMedia + L"/image" + std::to_wstring(oInfo.m_lID) + ((itJPG == oInfo.m_eType) ? L".jpg" : L".png"); - pFrame->SaveFile(strSave, (itJPG == oInfo.m_eType) ? 3 : 4); - - if (!bIsDestroy && !bIsResized) - pFrame->put_Data(NULL); - } - - inline void WriteImage2(NSHtmlRenderer::CImageInfo& oID, const double& x, const double& y, const double& w, const double& h) - { - SetTransformToDocument(true); - - if (fabs(m_pTransform->shx()) < 0.0000001 && fabs(m_pTransform->shy()) < 0.0000001 && - m_pTransform->sx() >= 0 && m_pTransform->sy() >= 0) - { - double xx = x; - double yy = y; - double rr = x + w; - double bb = y + h; - m_pTransform->TransformPoint(xx, yy); - m_pTransform->TransformPoint(rr, bb); - - if (oID.m_eType == itJPG) - { - m_oPage.WriteCommandType(CMetafile::ctDrawImage); - m_oPage.WriteBYTE(0); - m_oPage.WriteLONG(oID.m_lID); - m_oPage.WriteDouble(xx); - m_oPage.WriteDouble(yy); - m_oPage.WriteDouble(rr - xx); - m_oPage.WriteDouble(bb - yy); - } - else - { - m_oPage.WriteCommandType(CMetafile::ctDrawImage); - m_oPage.WriteBYTE(1); - m_oPage.WriteLONG(oID.m_lID); - m_oPage.WriteDouble(xx); - m_oPage.WriteDouble(yy); - m_oPage.WriteDouble(rr - xx); - m_oPage.WriteDouble(bb - yy); - } - } - else - { - if (oID.m_eType == itJPG) - { - m_oPage.WriteCommandType(CMetafile::ctDrawImage); - m_oPage.WriteBYTE(10); - m_oPage.WriteLONG(oID.m_lID); - m_oPage.WriteDouble(x); - m_oPage.WriteDouble(y); - m_oPage.WriteDouble(w); - m_oPage.WriteDouble(h); - - m_oPage.WriteDouble(m_pTransform->sx()); - m_oPage.WriteDouble(m_pTransform->shy()); - m_oPage.WriteDouble(m_pTransform->shx()); - m_oPage.WriteDouble(m_pTransform->sy()); - m_oPage.WriteDouble(m_pTransform->tx()); - m_oPage.WriteDouble(m_pTransform->ty()); - } - else - { - m_oPage.WriteCommandType(CMetafile::ctDrawImage); - m_oPage.WriteBYTE(11); - m_oPage.WriteLONG(oID.m_lID); - m_oPage.WriteDouble(x); - m_oPage.WriteDouble(y); - m_oPage.WriteDouble(w); - m_oPage.WriteDouble(h); - - m_oPage.WriteDouble(m_pTransform->sx()); - m_oPage.WriteDouble(m_pTransform->shy()); - m_oPage.WriteDouble(m_pTransform->shx()); - m_oPage.WriteDouble(m_pTransform->sy()); - m_oPage.WriteDouble(m_pTransform->tx()); - m_oPage.WriteDouble(m_pTransform->ty()); - } - } - } - - inline void WriteImagePattrern(NSHtmlRenderer::CImageInfo& oID, CTileInfo& oTile) - { - SetTransformToDocument(true); - double dKoef = 25.4 / m_dDpiX; - - double xx = oTile.bbox_x * dKoef; - double yy = oTile.bbox_y * dKoef; - double rr = oTile.bbox_r * dKoef; - double bb = oTile.bbox_b * dKoef; - - if (oID.m_eType == itJPG) - { - m_oPage.WriteCommandType(CMetafile::ctDrawImage); - m_oPage.WriteBYTE(0); - m_oPage.WriteLONG(oID.m_lID); - m_oPage.WriteDouble(xx); - m_oPage.WriteDouble(yy); - m_oPage.WriteDouble(rr - xx); - m_oPage.WriteDouble(bb - yy); - } - else - { - m_oPage.WriteCommandType(CMetafile::ctDrawImage); - m_oPage.WriteBYTE(1); - m_oPage.WriteLONG(oID.m_lID); - m_oPage.WriteDouble(xx); - m_oPage.WriteDouble(yy); - m_oPage.WriteDouble(rr - xx); - m_oPage.WriteDouble(bb - yy); - } - } - - void WriteImageID_SVG() - { - m_oSmartText.DumpLine(); - SetTransformToDocument(true); - -#if 0 - m_oSVGWriter.DEBUG_DumpSVG(m_strDstMedia); -#endif - - bool bIsBIG = false; - -#ifdef USE_SIMPLE_GRAPHICS_NOSVG - - if (m_oSVGWriter.m_bIsSimpleGraphics) - { - if (m_oSVGWriter.m_oVectors.GetPosition() > SVG_TO_RASTER_MIN_SIZE) - bIsBIG = true; - - if (!bIsBIG) - { - m_oPage.Write(m_oSVGWriter.m_oVectors); - m_oSVGWriter.NewSVG(); - return; - } - } - -#endif - - if (!bIsBIG) - { - if (m_oSVGWriter.m_oDocument.GetCurSize() > SVG_TO_RASTER_MIN_SIZE) - bIsBIG = true; - } - - bool bIsNeedWriteEndSVG = true; - if (bIsBIG) - { -#ifdef USE_BIG_GRAPHICS_TORASTER - bool bIsBIGWrite = WriteSVGAsBitmap(); - bIsNeedWriteEndSVG = false; - if (bIsBIGWrite) - { - m_oSVGWriter.NewSVG(); - return; - } -#endif - } - - if ((m_oSVGWriter.m_oDocument.GetCurSize() > SVG_INLINE_MAX_SIZE)) - { - ++m_lNextIDImage; - - std::wstring strSaveItem = m_strDstMedia + L"/image" + std::to_wstring(m_lNextIDImage) + L".svg"; - m_oSVGWriter.CloseFile2(strSaveItem, bIsNeedWriteEndSVG); - - m_oPage.WriteCommandType(CMetafile::ctDrawImage); - m_oPage.WriteBYTE(2); - m_oPage.WriteLONG(m_lNextIDImage); - } - else - { - m_oPage.WriteCommandType(CMetafile::ctDrawImage); - m_oPage.WriteBYTE(3); - m_oSVGWriter.CloseFile3(&m_oPage, bIsNeedWriteEndSVG); - } - - m_oSVGWriter.NewSVG(); - } - - - bool WriteSVGAsBitmap() - { - // TODO: - return true; - } - - inline void SetTransformToDocument(bool bIsFromGraphics) - { - if (NULL == m_pTransform) - return; - - if (bIsFromGraphics) - { - if (m_oLastTransform.IsIdentity2(__g_matrix_eps)) - { - // ничего делать не нужно - } - else - { - m_oPage.WriteCommandType(CMetafile::ctResetTransform); - m_oLastTransform.Reset(); - } - } - else - { - if (true) - { - m_oLastTransform = *m_pTransform; - - //m_oPage.Write(CMetafile::ctSetTransform, m->sx, m->shy, m->shx, m->sy, m->tx, m->ty); - m_oPage.WriteCommandType(CMetafile::ctSetTransform); - m_oPage.WriteDouble(m_pTransform->sx()); - m_oPage.WriteDouble(m_pTransform->shy()); - m_oPage.WriteDouble(m_pTransform->shx()); - m_oPage.WriteDouble(m_pTransform->sy()); - m_oPage.WriteDouble(m_pTransform->tx()); - m_oPage.WriteDouble(m_pTransform->ty()); - return; - } - - if (Aggplus::CMatrix::IsEqual(m_pTransform, &m_oLastTransform, __g_matrix_eps, false)) - { - // ничего делать не нужно - return; - } - - if (m_pTransform->IsIdentity2(__g_matrix_eps) && m_oLastTransform.IsIdentity2(__g_matrix_eps)) - { - // ничего делать не нужно - m_oLastTransform.Reset(); - } - else - { - if (m_pTransform->IsIdentity2(__g_matrix_eps)) - { - // ничего делать не нужно - m_oPage.WriteCommandType(CMetafile::ctResetTransform); - m_oLastTransform.Reset(); - return; - } - - m_oLastTransform = *m_pTransform; - - //m_oPage.Write(CMetafile::ctSetTransform, m->sx, m->shy, m->shx, m->sy, m->tx, m->ty); - m_oPage.WriteCommandType(CMetafile::ctSetTransform); - m_oPage.WriteDouble(m_pTransform->sx()); - m_oPage.WriteDouble(m_pTransform->shy()); - m_oPage.WriteDouble(m_pTransform->shx()); - m_oPage.WriteDouble(m_pTransform->sy()); - m_oPage.WriteDouble(m_pTransform->tx()); - m_oPage.WriteDouble(m_pTransform->ty()); - } - } - } - - ///////////////////////////////////////////////////// - void WriteStartDocument() - { - m_bIsGids = false; - } - - void WriteEndDocument(CDocument& oDocument, bool bIsNoBase64) - { - CMetafile oDocInfo; - oDocInfo.WriteLONG(m_lPagesCount); - oDocInfo.WriteLONG(m_oSmartText.m_lCountParagraphs); - oDocInfo.WriteLONG(m_oSmartText.m_lCountWords); - oDocInfo.WriteLONG(m_oSmartText.m_lCountSymbols); - oDocInfo.WriteLONG(m_oSmartText.m_lCountSpaces); - - oDocInfo.WriteLONG(m_oDstFontGenerator.m_lCountFonts); - - LONG lOffset = (6 + 4 * m_lPagesCount) * sizeof(int); - for (LONG i = 0; i < m_lPagesCount; i++) - { - CPageMeta& oMeta = m_arrPages[i]; - oDocInfo.WriteDouble(oMeta.m_dWidth); - oDocInfo.WriteDouble(oMeta.m_dHeight); - oDocInfo.WriteLONG(oMeta.m_lStart + lOffset); - oDocInfo.WriteLONG(oMeta.m_lEnd + lOffset); - } - - m_oFileWriter.CloseFile(); - - NSFile::CFileBinary oFilePages; - oFilePages.OpenFile(m_strDstDirectoryFiles + L"/document_temp.bin"); - - LONG lMetaSize = (LONG)oFilePages.GetFileSize(); - LONG lSizeAll = oDocInfo.GetPosition() + lMetaSize; - - BYTE* pData = new BYTE[lSizeAll]; - memcpy(pData, oDocInfo.GetData(), oDocInfo.GetPosition()); - - DWORD dwRead = 0; - oFilePages.ReadFile(pData + oDocInfo.GetPosition(), lMetaSize, dwRead); - - oFilePages.CloseFile(); - - NSFile::CFileBinary::Remove(m_strDstDirectoryFiles + L"/document_temp.bin"); - - if (bIsNoBase64) - { - NSFile::CFileBinary oDestinationFile; - oDestinationFile.CreateFileW(m_strDstDirectoryFiles + L"/Editor.bin"); - oDestinationFile.WriteFile(pData, (DWORD)lSizeAll); - oDestinationFile.CloseFile(); - - RELEASEARRAYOBJECTS(pData); - } - else - { - char* pOutput = NULL; - int nOutputLen = 0; - NSFile::CBase64Converter::Encode(pData, lSizeAll, pOutput, nOutputLen, NSBase64::B64_BASE64_FLAG_NOCRLF); - - RELEASEARRAYOBJECTS(pData); - - std::string sDstLen = std::to_string(nOutputLen); - sDstLen += ";"; - - NSFile::CFileBinary _file; - _file.CreateFileW(m_strDstDirectoryFiles + L"/Editor.bin"); - - _file.WriteFile((BYTE*)sDstLen.c_str(), (DWORD)sDstLen.length()); - _file.WriteFile((BYTE*)pOutput, (DWORD)nOutputLen); - - _file.CloseFile(); - - RELEASEARRAYOBJECTS(pOutput); - } - - NSFonts::IFontManager* pFontManager = m_pApplicationFonts->GenerateFontManager(); - m_oDstFontGenerator.WriteFonts(pFontManager, m_strDstDirectoryFiles + L"/fonts", m_bIsGids); - RELEASEOBJECT(pFontManager); - } - - void CreateFile(std::wstring& strDir, std::wstring& strFileName) - { - m_lPagesCount = 0; - m_lCurrentPage = -1; - - m_strDstDirectory = strDir; - m_strDstDirectoryFiles = m_strDstDirectory + L"/" + strFileName;// + _T("_files"); - m_strFileName = strFileName; - - if (!m_bIsOnlyTextMode) - NSDirectory::CreateDirectory(m_strDstDirectoryFiles); - m_strDstMedia = m_strDstDirectoryFiles + L"/media"; - if (!m_bIsOnlyTextMode) - NSDirectory::CreateDirectory(m_strDstMedia); - - std::wstring strFileFonts = m_strDstDirectoryFiles + L"/fonts"; - if (!m_bIsOnlyTextMode) - NSDirectory::CreateDirectory(strFileFonts); - - std::wstring strDocRendererS = m_strDstDirectoryFiles + L"/document_temp.bin"; - if (!m_bIsOnlyTextMode) - m_oFileWriter.CreateFileW(strDocRendererS); - - m_oPage.Clear(); - m_arrPages.clear(); - m_bIsGids = false; - m_lCurrentDumpSize = 0; - - m_oSmartText.SetParams(this); - - m_oSmartText.m_lCountParagraphs = 0; - m_oSmartText.m_lCountWords = 0; - m_oSmartText.m_lCountSymbols = 0; - m_oSmartText.m_lCountSpaces = 0; - } - }; -} - -#endif // _ASC_HTMLRENDERER_WRITER_H_ diff --git a/HtmlRenderer/test/HtmlRenderer_vs2005.vcproj b/HtmlRenderer/test/HtmlRenderer_vs2005.vcproj deleted file mode 100644 index dba36b5f099..00000000000 --- a/HtmlRenderer/test/HtmlRenderer_vs2005.vcproj +++ /dev/null @@ -1,228 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/HtmlRenderer/test/main.cpp b/HtmlRenderer/test/main.cpp deleted file mode 100644 index 74d2df566b5..00000000000 --- a/HtmlRenderer/test/main.cpp +++ /dev/null @@ -1,422 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2023 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -//#include - -#include "../../DesktopEditor/graphics/pro/Fonts.h" -#include "../../DesktopEditor/graphics/pro/Graphics.h" -#include "../../DesktopEditor/fontengine/ApplicationFontsWorker.h" - -#include "../../DjVuFile/DjVu.h" -#include "../../XpsFile/XpsFile.h" -#include "../../PdfFile/PdfFile.h" -#include "../include/HTMLRenderer3.h" - -#include "../../DesktopEditor/raster/BgraFrame.h" -#include "../../DesktopEditor/common/Directory.h" - -#include "../include/ASCSVGWriter.h" - -#include "../../Common/Network/FileTransporter/include/FileTransporter.h" - - -void Download_OnComplete(int error) -{ - int y = error; - return; -} - -//#define RASTER_TEST -//#define METAFILE_TEST -//#define METAFILE_TEST_X2T -//#define METAFILE_TEST_RASTER -#define ONLINE_WORD_TO_PDF -//#define TO_PDF -//#define TO_HTML_RENDERER -//#define ONLY_TEXT -//#define DOWNLOADER_TEST - -#include "Windows.h" -#include -#undef CreateDirectory - -bool DownloadFilePS(const std::wstring& sFileURL, const std::wstring& strFileOutput) -{ - STARTUPINFO sturtupinfo; - ZeroMemory(&sturtupinfo,sizeof(STARTUPINFO)); - sturtupinfo.cb = sizeof(STARTUPINFO); - - std::wstring sFileDst = strFileOutput; - size_t posn = 0; - while (std::wstring::npos != (posn = sFileDst.find('\\', posn))) - { - sFileDst.replace(posn, 1, L"/"); - posn += 1; - } - - std::wstring sApp = L"powershell.exe –c \"(new-object System.Net.WebClient).DownloadFile('" + sFileURL + L"','" + sFileDst + L"')\""; - - wchar_t* 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(NULL, pCommandLine, NULL, NULL, TRUE, CREATE_NO_WINDOW, NULL, NULL, &sturtupinfo, &processinfo); - - if (bResult && ghJob) - { - AssignProcessToJobObject(ghJob, processinfo.hProcess); - } - - ::WaitForSingleObject(processinfo.hProcess, INFINITE); - - RELEASEARRAYOBJECTS(pCommandLine); - - return NSFile::CFileBinary::Exists(sFileDst); -} - -int main(int argc, char *argv[]) -{ - //DownloadFilePS(L"https://natworld.info/wp-content/uploads/2018/02/vodosvinka-ili-kapibara.jpg", L"D:/222.jpg"); - -#ifdef DOWNLOADER_TEST - NSNetwork::NSFileTransport::CFileDownloader oDownloader(L"https://natworld.info/wp-content/uploads/2018/02/vodosvinka-ili-kapibara.jpg", false); - oDownloader.SetFilePath(L"D:\\111.jpg"); - oDownloader.SetEvent_OnComplete(Download_OnComplete); - oDownloader.DownloadSync(); -#endif - -#ifdef RASTER_TEST - CBgraFrame oFrame; - oFrame.OpenFile(L"D:\\22.png"); - oFrame.SaveFile(L"D:\\oleg.png", 4); - return 0; -#endif - - CApplicationFontsWorker oWorker; - oWorker.m_sDirectory = NSFile::GetProcessDirectory() + L"/fonts_cache"; - //oWorker.m_arAdditionalFolders.push_back(L"D:\\GIT\\core-fonts"); - oWorker.m_bIsNeedThumbnails = false; - - if (!NSDirectory::Exists(oWorker.m_sDirectory)) - NSDirectory::CreateDirectory(oWorker.m_sDirectory); - - NSFonts::IApplicationFonts* pFonts = oWorker.Check(); - -#if 0 - NSFonts::CFontSelectFormat oFormat; - oFormat.wsName = new std::wstring(L"@ËÎÌå"); - - NSFonts::IFontManager* pTestManager = pFonts->GenerateFontManager(); - - NSFonts::CFontInfo* pFontInfo = pTestManager->GetFontInfoByParams(oFormat); - - pTestManager->Release(); -#endif - -#ifdef METAFILE_TEST_X2T - - MetaFile::IMetaFile* pMetafile = MetaFile::Create(pFonts); - if (pMetafile->LoadFromFile(L"image.emf")) - { - NSFonts::IFontManager* pFontManager = pFonts->GenerateFontManager(); - - double x = 0, y = 0, w = 0, h = 0; - pMetafile->GetBounds(&x, &y, &w, &h); - - double _max = (w >= h) ? w : h; - double dKoef = 1000.0 / _max; - - int WW = (int)(dKoef * w + 0.5); - int HH = (int)(dKoef * h + 0.5); - - NSHtmlRenderer::CASCSVGWriter oWriterSVG; - oWriterSVG.SetFontManager(pFontManager); - oWriterSVG.put_Width(WW); - oWriterSVG.put_Height(HH); - - bool bRes = true; - bool bIsBigestSVG = false; - bool bIsRaster = true; - try - { - bRes = pMetafile->DrawOnRenderer(&oWriterSVG, 0, 0, WW, HH); - } - catch (...) - { - bRes = false; - } - - if (bRes) - { - oWriterSVG.IsRaster(&bIsRaster); - - LONG lSvgDataSize = 0; - oWriterSVG.GetSVGDataSize(&lSvgDataSize); - - bIsBigestSVG = (lSvgDataSize > 5 * 1024 * 1024); - } - - if (bIsRaster || bIsBigestSVG || !bRes) - { - int nWidth = 0; - int nHeight = 0; - - int nMaxPixSize = 1000; - - double dKoef = nMaxPixSize / _max; - - nWidth = (int)(dKoef * w + 0.5); - nHeight = (int)(dKoef * h + 0.5); - - pMetafile->ConvertToRaster(L"image.png", 4 /*CXIMAGE_FORMAT_PNG*/, nWidth, nHeight); - } - else - { - oWriterSVG.SaveFile(L"image.svg"); - } - - RELEASEINTERFACE(pFontManager); - } - RELEASEOBJECT(pMetafile); - -#endif - -#ifdef METAFILE_TEST - - NSFonts::IFontManager* pManager = pFonts->GenerateFontManager(); - - NSHtmlRenderer::CASCSVGWriter oWriterSVG; - oWriterSVG.SetFontManager(pManager); - - MetaFile::IMetaFile* pMetafile = MetaFile::Create(pFonts); - - //pMetafile->LoadFromFile(L"D:\\2\\ppt\\media\\image4.wmf"); - pMetafile->LoadFromFile(L"D:\\SVG\\Disigner 2.svg"); - - double x = 0, y = 0, w = 0, h = 0; - pMetafile->GetBounds(&x, &y, &w, &h); - - double _max = (w >= h) ? w : h; - double dKoef = 100000.0 / _max; - - int WW = (int)(dKoef * w + 0.5); - int HH = (int)(dKoef * h + 0.5); - - oWriterSVG.put_Width(WW); - oWriterSVG.put_Height(HH); - pMetafile->DrawOnRenderer(&oWriterSVG, 0, 0, WW, HH); - - oWriterSVG.SaveFile(L"D:\\SVG\\out.png"); - - RELEASEOBJECT(pMetafile); - RELEASEINTERFACE(pManager); - RELEASEOBJECT(pFonts); - return 0; - -#endif - -#ifdef METAFILE_TEST_RASTER - - NSFonts::IFontManager* pManager = pFonts->GenerateFontManager(); - - NSGraphics::IGraphicsRenderer* pRasterRenderer = NSGraphics::Create(); - pRasterRenderer->SetFontManager(pManager); - - int nRasterW = 1000; - int nRasterH = 1000; - BYTE* pData = new BYTE[4 * nRasterW * nRasterH]; - //memset(pData, 255, 4 * nRasterW * nRasterH); - - unsigned int back = 0xffffff; - unsigned int* pData32 = (unsigned int*)pData; - unsigned int* pData32End = pData32 + nRasterW * nRasterH; - //дефолтный тон должен быть прозрачным, а не белым - while (pData32 < pData32End) - *pData32++ = back; - - CBgraFrame oFrame; - oFrame.put_Data(pData); - oFrame.put_Width(nRasterW); - oFrame.put_Height(nRasterH); - oFrame.put_Stride(4 * nRasterW); - - pRasterRenderer->CreateFromBgraFrame(&oFrame); - pRasterRenderer->SetSwapRGB(false); - - double dW_MM = nRasterW * 25.4 / 96; - double dH_MM = nRasterH * 25.4 / 96; - - pRasterRenderer->put_Width(dW_MM); - pRasterRenderer->put_Height(dH_MM); - - MetaFile::IMetaFile* pMetafile = MetaFile::Create(pFonts); - pMetafile->LoadFromFile(L"D:\\test\\123.svg"); - - double x = 0, y = 0, w = 0, h = 0; - pMetafile->GetBounds(&x, &y, &w, &h); - - pMetafile->DrawOnRenderer(pRasterRenderer, dW_MM / 4, dW_MM / 4, dW_MM / 2, dH_MM / 2); - pMetafile->ConvertToRaster(L"D:\\SVG\\out2.png", 4, 1000); - - oFrame.SaveFile(L"D:\\SVG\\out.png", 4); - - RELEASEOBJECT(pMetafile); - RELEASEINTERFACE(pManager); - RELEASEINTERFACE(pRasterRenderer); - return 0; - -#endif - -#ifdef ONLINE_WORD_TO_PDF - CPdfFile oPdfW(pFonts); - oPdfW.CreatePdf(); - oPdfW.SetTempDirectory(L"C:\\Git\\Test\\Temp"); - oPdfW.OnlineWordToPdf(L"C:\\Git\\Test\\123.txt", L"C:\\Git\\Test\\123.pdf"); - RELEASEOBJECT(pFonts); - return 0; -#endif - - - //std::wstring sFile = L"\\\\KIRILLOV8\\_Office\\PDF\\Android intro(2p).pdf"; - //std::wstring sFile = L"D:\\activex\\Pi(1p).pdf"; - //std::wstring sFile = L"\\\\192.168.3.208\\allusers\\Files\\PDF\\AllPDF\\asia.pdf"; - //std::wstring sFile = L"D:\\knut.djvu"; - //std::wstring sFile = L"D:\\bankomats.xps"; - //std::wstring sFile = L"\\\\kirillov8\\_Office\\DJVU\\Основы разработки приложений на платформе Microsoft .NET Framework. Учебный курс Microsoft экзамен 70-536.djvu"; - //std::wstring sFile = L"D:\\TESTFILES\\Алгоритмы - построение и анализ.djvu"; -#ifndef WIN32 - std::wstring sFile = L"/home/oleg/GIT/ddd/ZfAvCwDsowJALpClgmE_/source/ZfAvCwDsowJALpClgmE_.pdf"; -#else - //std::wstring sFile = L"D:\\ddd\\ZfAvCwDsowJALpClgmE_\\source\\ZfAvCwDsowJALpClgmE_.pdf"; - //std::wstring sFile = L"D:\\2.pdf"; - std::wstring sFile = L"D:\\OoPdfFormExample2.pdf"; -#endif - -#ifdef WIN32 - std::wstring sDst = L"D:\\test\\Document"; -#else - std::wstring sDst = L"/home/oleg/test/Document"; -#endif - - //std::wstring sFile = L"/home/oleg/activex/Android intro(2p).pdf"; - //std::wstring sFile = L"/home/oleg/activex/Pi(1p).pdf"; - //std::wstring sFile = L"/home/oleg/activex/knut.djvu"; - //std::wstring sFile = L"/home/oleg/activex/bankomats.xps"; - //std::wstring sDst = L"/home/oleg/activex/1"; - - //NSFonts::NSApplicationFontStream::SetGlobalMemoryStorage(NSFonts::NSApplicationFontStream::CreateDefaultGlobalMemoryStorage()); - - IOfficeDrawingFile* pReader = NULL; - pReader = new CPdfFile(pFonts); - //pReader = new CDjVuFile(pFonts); - //pReader = new CXpsFile(pFonts); - - pReader->SetTempDirectory(sDst); - pReader->LoadFromFile(sFile); - - pReader->ConvertToRaster(0, L"D:\\111.png", 4); - -#ifdef TO_HTML_RENDERER - NSHtmlRenderer::CASCHTMLRenderer3 oRenderer; -#ifdef ONLY_TEXT - oRenderer.SetOnlyTextMode(true); - oRenderer.CreateOfficeFile(L"temp/temp"); -#else - oRenderer.CreateOfficeFile(sDst); -#endif -#else - CPdfFile oRenderer(pFonts); - oRenderer.SetTempDirectory(sDst); -#endif - - int nPagesCount = pReader->GetPagesCount(); - for (int i = 0; i < nPagesCount; ++i) - { - oRenderer.NewPage(); - oRenderer.BeginCommand(c_nPageType); - - double dPageDpiX, dPageDpiY; - double dWidth, dHeight; - pReader->GetPageInfo(i, &dWidth, &dHeight, &dPageDpiX, &dPageDpiY); - - dWidth *= 25.4 / dPageDpiX; - dHeight *= 25.4 / dPageDpiY; - - oRenderer.put_Width(dWidth); - oRenderer.put_Height(dHeight); - -#ifdef ONLY_TEXT - oRenderer.SetAdditionalParam("DisablePageEnd", L"yes"); -#endif - pReader->DrawPageOnRenderer(&oRenderer, i, NULL); - -#ifdef ONLY_TEXT - oRenderer.SetAdditionalParam("DisablePageEnd", L"no"); - - int paragraphs = 0; - int words = 0; - int symbols = 0; - int spaces = 0; - std::string info; - oRenderer.GetLastPageInfo(paragraphs, words, symbols, spaces, info); -#endif - - oRenderer.EndCommand(c_nPageType); - } - -#ifdef TO_HTML_RENDERER -#ifndef ONLY_TEXT - oRenderer.CloseFile(); -#endif -#else - oRenderer.SaveToFile(L"D:/11.pdf"); -#endif - - RELEASEOBJECT(pFonts); - return 0; -} diff --git a/HtmlRenderer/test/test.pro b/HtmlRenderer/test/test.pro deleted file mode 100644 index ad7ff8708a3..00000000000 --- a/HtmlRenderer/test/test.pro +++ /dev/null @@ -1,49 +0,0 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2015-07-21T18:28:42 -# -#------------------------------------------------- - -QT -= core - -QT -= gui - -TARGET = test -CONFIG += console -CONFIG -= app_bundle - -DEFINES += PDFREADER_USE_DYNAMIC_LIBRARY -DEFINES += PDFWRITER_USE_DYNAMIC_LIBRARY -DEFINES += XPS_USE_DYNAMIC_LIBRARY -DEFINES += DJVU_USE_DYNAMIC_LIBRARY -DEFINES += HTMLRENDERER_USE_DYNAMIC_LIBRARY - -DEFINES += KERNEL_USE_DYNAMIC_LIBRARY -DEFINES += GRAPHICS_USE_DYNAMIC_LIBRARY - -TEMPLATE = app - -CORE_ROOT_DIR = $$PWD/../.. -PWD_ROOT_DIR = $$PWD -include($$CORE_ROOT_DIR/Common/base.pri) -include($$PWD/../../Common/3dParty/icu/icu.pri) - -ADD_DEPENDENCY(UnicodeConverter kernel graphics kernel_network HtmlRenderer PdfFile DjVuFile XpsFile) - -win32 { -LIBS += -lgdi32 \ - -ladvapi32 \ - -luser32 \ - -lshell32 -} - -linux-g++ | linux-g++-64 | linux-g++-32 { - LIBS += -lz -} - -SOURCES += main.cpp - -SOURCES += \ - ../src/ASCSVGWriter.cpp - -HEADERS += ../include/ASCSVGWriter.h diff --git a/HwpFile/HWPFile.cpp b/HwpFile/HWPFile.cpp new file mode 100644 index 00000000000..0a126d1921d --- /dev/null +++ b/HwpFile/HWPFile.cpp @@ -0,0 +1,72 @@ +#include "HWPFile.h" + +#include "HwpDoc/Common/WriterContext.h" +#include "../DesktopEditor/common/File.h" + +#include "HwpDoc/Conversion/Converter2OOXML.h" + +CHWPFile::CHWPFile() + : m_pInternal(new HWP::CWriterContext()) +{} + +CHWPFile::~CHWPFile() +{ + if (nullptr != m_pInternal) + delete m_pInternal; +} + +void CHWPFile::SetTempDirectory(const std::wstring& wsTempDirectory) +{ + m_wsTempDirectory = wsTempDirectory; +} + +bool CHWPFile::OpenHWP(const std::wstring& wsFilePath) +{ + if (nullptr == m_pInternal) + return false; + + return m_pInternal->Open(wsFilePath, HWP::EHanType::HWP); +} + +bool CHWPFile::OpenHWPX(const std::wstring& wsFilePath) +{ + if (nullptr == m_pInternal) + return false; + + return m_pInternal->Open(wsFilePath, HWP::EHanType::HWPX); +} + +void CHWPFile::Close() +{ + if (nullptr != m_pInternal) + m_pInternal->Close(); +} + +bool CHWPFile::ConvertToOOXML(const std::wstring& wsFilePath) +{ + HWP::CConverter2OOXML oConverter; + + oConverter.SetContext(m_pInternal); + oConverter.SetTempDirectory(m_wsTempDirectory); + + return oConverter.ConvertToFile(wsFilePath); +} + +bool CHWPFile::ConvertToOOXML_Dir(const std::wstring& wsDirectoryPath) +{ + HWP::CConverter2OOXML oConverter; + + oConverter.SetContext(m_pInternal); + + return oConverter.ConvertToDir(wsDirectoryPath); +} + +bool CHWPFile::IsHWPFormat(const std::wstring& wsFilePath) +{ + return HWP::EHanType::HWP == HWP::CWriterContext::DetectHancom(wsFilePath); +} + +bool CHWPFile::IsHWPXFormat(const std::wstring& wsFilePath) +{ + return HWP::EHanType::HWPX == HWP::CWriterContext::DetectHancom(wsFilePath); +} diff --git a/HwpFile/HWPFile.h b/HwpFile/HWPFile.h new file mode 100644 index 00000000000..bf64f7ee33d --- /dev/null +++ b/HwpFile/HWPFile.h @@ -0,0 +1,35 @@ +#ifndef HWPFILE_H +#define HWPFILE_H + +#include + +#ifndef HWPFILE_USE_DYNAMIC_LIBRARY +#define HWP_FILE_DECL_EXPORT +#else +#include "../DesktopEditor/common/base_export.h" +#define HWP_FILE_DECL_EXPORT Q_DECL_EXPORT +#endif + +namespace HWP { class CWriterContext; } +class HWP_FILE_DECL_EXPORT CHWPFile +{ + HWP::CWriterContext *m_pInternal; + std::wstring m_wsFileName; + std::wstring m_wsTempDirectory; +public: + CHWPFile(); + ~CHWPFile(); + + void SetTempDirectory(const std::wstring& wsTempDirectory); + + bool OpenHWP(const std::wstring& wsFilePath); + bool OpenHWPX(const std::wstring& wsFilePath); + void Close(); + bool ConvertToOOXML(const std::wstring& wsFilePath); + bool ConvertToOOXML_Dir(const std::wstring& wsDirectoryPath); + + static bool IsHWPFormat(const std::wstring& wsFilePath); + static bool IsHWPXFormat(const std::wstring& wsFilePath); +}; + +#endif // HWPFILE_H diff --git a/HwpFile/HWPFile.pro b/HwpFile/HWPFile.pro new file mode 100644 index 00000000000..7814ddb3ea9 --- /dev/null +++ b/HwpFile/HWPFile.pro @@ -0,0 +1,183 @@ +QT -= core gui + +VERSION = 0.0.0.1 +TARGET = HWPFile +TEMPLATE = lib + +CONFIG += shared +CONFIG += plugin + +CORE_ROOT_DIR = $$PWD/.. +PWD_ROOT_DIR = $$PWD + +include($$CORE_ROOT_DIR/Common/base.pri) + +LIBS += -L$$CORE_BUILDS_LIBRARIES_PATH -lCryptoPPLib + +ADD_DEPENDENCY(kernel, UnicodeConverter, graphics) + +DEFINES += HWPFILE_USE_DYNAMIC_LIBRARY + +SOURCES += \ + HWPFile.cpp \ + HwpDoc/Common/XMLReader.cpp \ + HwpDoc/Common/WriterContext.cpp \ + HwpDoc/Conversion/Converter2OOXML.cpp \ + HwpDoc/Conversion/FootnoteConverter.cpp \ + HwpDoc/Conversion/NumberingConverter.cpp \ + HwpDoc/Conversion/OleConverter.cpp \ + HwpDoc/HWPDocInfo.cpp \ + HwpDoc/HWPElements/HWPRecord.cpp \ + HwpDoc/HWPElements/HWPRecordBinData.cpp \ + HwpDoc/HWPElements/HWPRecordBorderFill.cpp \ + HwpDoc/HWPElements/HWPRecordBullet.cpp \ + HwpDoc/HWPElements/HWPRecordCharShape.cpp \ + HwpDoc/HWPElements/HWPRecordCtrlData.cpp \ + HwpDoc/HWPElements/HWPRecordCtrlHeader.cpp \ + HwpDoc/HWPElements/HWPRecordDocumentProperties.cpp \ + HwpDoc/HWPElements/HWPRecordFaceName.cpp \ + HwpDoc/HWPElements/HWPRecordFormObject.cpp \ + HwpDoc/HWPElements/HWPRecordIDMaping.cpp \ + HwpDoc/HWPElements/HWPRecordListHeader.cpp \ + HwpDoc/HWPElements/HWPRecordNumbering.cpp \ + HwpDoc/HWPElements/HWPRecordParaRangeTag.cpp \ + HwpDoc/HWPElements/HWPRecordParaShape.cpp \ + HwpDoc/HWPElements/HWPRecordParaText.cpp \ + HwpDoc/HWPElements/HWPRecordStyle.cpp \ + HwpDoc/HWPElements/HwpRecordTabDef.cpp \ + HwpDoc/HWPFile.cpp \ + HwpDoc/HWPSection.cpp \ + HwpDoc/HWPStream.cpp \ + HwpDoc/HWPXFile.cpp \ + HwpDoc/HwpFileHeader.cpp \ + HwpDoc/OLEdoc/CompoundFile.cpp \ + HwpDoc/OLEdoc/DirectoryEntry.cpp \ + HwpDoc/Paragraph/CapParagraph.cpp \ + HwpDoc/Paragraph/CellParagraph.cpp \ + HwpDoc/Paragraph/CharShape.cpp \ + HwpDoc/Paragraph/Ctrl.cpp \ + HwpDoc/Paragraph/CtrlAutoNumber.cpp \ + HwpDoc/Paragraph/CtrlCharacter.cpp \ + HwpDoc/Paragraph/CtrlClick.cpp \ + HwpDoc/Paragraph/CtrlColumnDef.cpp \ + HwpDoc/Paragraph/CtrlCommon.cpp \ + HwpDoc/Paragraph/CtrlContainer.cpp \ + HwpDoc/Paragraph/CtrlEmpty.cpp \ + HwpDoc/Paragraph/CtrlEqEdit.cpp \ + HwpDoc/Paragraph/CtrlField.cpp \ + HwpDoc/Paragraph/CtrlForm.cpp \ + HwpDoc/Paragraph/CtrlGeneralShape.cpp \ + HwpDoc/Paragraph/CtrlHeadFoot.cpp \ + HwpDoc/Paragraph/CtrlNewNumber.cpp \ + HwpDoc/Paragraph/CtrlNote.cpp \ + HwpDoc/Paragraph/CtrlObjElement.cpp \ + HwpDoc/Paragraph/CtrlPageNumPos.cpp \ + HwpDoc/Paragraph/CtrlSectionDef.cpp \ + HwpDoc/Paragraph/CtrlShapeArc.cpp \ + HwpDoc/Paragraph/CtrlShapeConnectLine.cpp \ + HwpDoc/Paragraph/CtrlShapeCurve.cpp \ + HwpDoc/Paragraph/CtrlShapeEllipse.cpp \ + HwpDoc/Paragraph/CtrlShapeLine.cpp \ + HwpDoc/Paragraph/CtrlShapeOle.cpp \ + HwpDoc/Paragraph/CtrlShapePic.cpp \ + HwpDoc/Paragraph/CtrlShapePolygon.cpp \ + HwpDoc/Paragraph/CtrlShapeRect.cpp \ + HwpDoc/Paragraph/CtrlShapeTextArt.cpp \ + HwpDoc/Paragraph/CtrlShapeVideo.cpp \ + HwpDoc/Paragraph/CtrlTable.cpp \ + HwpDoc/Paragraph/HWPPargraph.cpp \ + HwpDoc/Paragraph/LineSeg.cpp \ + HwpDoc/Paragraph/ParaText.cpp \ + HwpDoc/Paragraph/TblCell.cpp \ + HwpDoc/Section/NoteShape.cpp \ + HwpDoc/Section/Page.cpp \ + HwpDoc/Section/PageBorderFill.cpp + +HEADERS += \ + HWPFile.h \ + HwpDoc/Common/Common.h \ + HwpDoc/Common/XMLNode.h \ + HwpDoc/Common/WriterContext.h \ + HwpDoc/Conversion/Converter2OOXML.h \ + HwpDoc/Conversion/FootnoteConverter.h \ + HwpDoc/Conversion/NumberingConverter.h \ + HwpDoc/Conversion/OleConverter.h \ + HwpDoc/Conversion/Transform.h \ + HwpDoc/Conversion/Types.h \ + HwpDoc/Errors.h \ + HwpDoc/HWPDocInfo.h \ + HwpDoc/HWPElements/HWPRecord.h \ + HwpDoc/HWPElements/HWPRecordBinData.h \ + HwpDoc/HWPElements/HWPRecordBorderFill.h \ + HwpDoc/HWPElements/HWPRecordBullet.h \ + HwpDoc/HWPElements/HWPRecordCharShape.h \ + HwpDoc/HWPElements/HWPRecordCtrlData.h \ + HwpDoc/HWPElements/HWPRecordCtrlHeader.h \ + HwpDoc/HWPElements/HWPRecordDocumentProperties.h \ + HwpDoc/HWPElements/HWPRecordFaceName.h \ + HwpDoc/HWPElements/HWPRecordFormObject.h \ + HwpDoc/HWPElements/HWPRecordIDMaping.h \ + HwpDoc/HWPElements/HWPRecordListHeader.h \ + HwpDoc/HWPElements/HWPRecordNumbering.h \ + HwpDoc/HWPElements/HWPRecordParaRangeTag.h \ + HwpDoc/HWPElements/HWPRecordParaShape.h \ + HwpDoc/HWPElements/HWPRecordParaText.h \ + HwpDoc/HWPElements/HWPRecordStyle.h \ + HwpDoc/HWPElements/HWPTag.h \ + HwpDoc/HWPElements/HWPType.h \ + HwpDoc/HWPElements/HwpRecordTabDef.h \ + HwpDoc/HWPElements/HwpRecordTypes.h \ + HwpDoc/HWPFile.h \ + HwpDoc/HWPSection.h \ + HwpDoc/HWPStream.h \ + HwpDoc/HWPXFile.h \ + HwpDoc/HanType.h \ + HwpDoc/HwpFileHeader.h \ + HwpDoc/OLEdoc/CompoundFile.h \ + HwpDoc/OLEdoc/DirectoryEntry.h \ + HwpDoc/OLEdoc/Sector.h \ + HwpDoc/OLEdoc/SectorType.h \ + HwpDoc/Paragraph/CapParagraph.h \ + HwpDoc/Paragraph/CellParagraph.h \ + HwpDoc/Paragraph/CharShape.h \ + HwpDoc/Paragraph/CommonObj.h \ + HwpDoc/Paragraph/Ctrl.h \ + HwpDoc/Paragraph/CtrlAutoNumber.h \ + HwpDoc/Paragraph/CtrlCharacter.h \ + HwpDoc/Paragraph/CtrlClick.h \ + HwpDoc/Paragraph/CtrlColumnDef.h \ + HwpDoc/Paragraph/CtrlCommon.h \ + HwpDoc/Paragraph/CtrlContainer.h \ + HwpDoc/Paragraph/CtrlEmpty.h \ + HwpDoc/Paragraph/CtrlEqEdit.h \ + HwpDoc/Paragraph/CtrlField.h \ + HwpDoc/Paragraph/CtrlForm.h \ + HwpDoc/Paragraph/CtrlGeneralShape.h \ + HwpDoc/Paragraph/CtrlHeadFoot.h \ + HwpDoc/Paragraph/CtrlNewNumber.h \ + HwpDoc/Paragraph/CtrlNote.h \ + HwpDoc/Paragraph/CtrlObjElement.h \ + HwpDoc/Paragraph/CtrlPageNumPos.h \ + HwpDoc/Paragraph/CtrlSectionDef.h \ + HwpDoc/Paragraph/CtrlShapeArc.h \ + HwpDoc/Paragraph/CtrlShapeConnectLine.h \ + HwpDoc/Paragraph/CtrlShapeCurve.h \ + HwpDoc/Paragraph/CtrlShapeEllipse.h \ + HwpDoc/Paragraph/CtrlShapeLine.h \ + HwpDoc/Paragraph/CtrlShapeOle.h \ + HwpDoc/Paragraph/CtrlShapePic.h \ + HwpDoc/Paragraph/CtrlShapePolygon.h \ + HwpDoc/Paragraph/CtrlShapeRect.h \ + HwpDoc/Paragraph/CtrlShapeTextArt.h \ + HwpDoc/Paragraph/CtrlShapeVideo.h \ + HwpDoc/Paragraph/CtrlTable.h \ + HwpDoc/Paragraph/HWPPargraph.h \ + HwpDoc/Paragraph/LineSeg.h \ + HwpDoc/Paragraph/ParaText.h \ + HwpDoc/Paragraph/Point.h \ + HwpDoc/Paragraph/RangeTag.h \ + HwpDoc/Paragraph/TblCell.h \ + HwpDoc/Section/NoteShape.h \ + HwpDoc/Section/Page.h \ + HwpDoc/Section/PageBorderFill.h + diff --git a/HwpFile/HwpDoc/Common/Common.h b/HwpFile/HwpDoc/Common/Common.h new file mode 100644 index 00000000000..307d5dae868 --- /dev/null +++ b/HwpFile/HwpDoc/Common/Common.h @@ -0,0 +1,76 @@ +#ifndef COMMON_H +#define COMMON_H + +#include +#include +#include + +namespace HWP +{ +typedef char16_t HWP_CHAR; +typedef std::wstring HWP_STRING; +typedef char HWP_BYTE; + +#define LIST std::list +#define VECTOR std::vector + +#define TO_HWP_STRING(val) std::to_wstring(val) + +#define CLEAR_ARRAY(type, array) \ + for (type* pValue : array) \ + if (nullptr != pValue) \ + delete pValue + +#define SWITCH(type, value) switch(static_cast(value)) +#define CASE(value) case value : return value +#define DEFAULT(value) case value: default: return value + +#define MAKE_STR(value) #value +#define MAKE_WSTR(value) L##value +#define WSTR(value) MAKE_WSTR(#value) + +#define IF_STRING_IN_ENUM(checked_value, value, enum_type)\ + if (WSTR(checked_value) == value)\ + return enum_type::checked_value +#define ELSE_IF_STRING_IN_ENUM(checked_value, value, enum_type)\ + else if (WSTR(checked_value) == value)\ + return enum_type::checked_value +#define ELSE_STRING_IN_ENUM(checked_value, enum_type)\ + else\ + return enum_type::checked_value + +#define RETURN_VECTOR_CONST_PTR(type, array_values) \ + std::vector arTempVector(array_values.size()); \ + for (unsigned int unIndex = 0; unIndex < array_values.size(); ++unIndex) \ + arTempVector[unIndex] = dynamic_cast(array_values[unIndex]); \ + return arTempVector + +class IRef +{ + unsigned long m_ulRef; +public: + IRef() + { + m_ulRef = 1; + } + + virtual ~IRef() + { + } + + virtual unsigned long AddRef() + { + ++m_ulRef; + return m_ulRef; + } + + virtual unsigned long Release() + { + unsigned long ulRet = --m_ulRef; + if (0 == m_ulRef) + delete this; + return ulRet; + } +}; +} +#endif // COMMON_H diff --git a/HwpFile/HwpDoc/Common/WriterContext.cpp b/HwpFile/HwpDoc/Common/WriterContext.cpp new file mode 100644 index 00000000000..ad5f6955cf5 --- /dev/null +++ b/HwpFile/HwpDoc/Common/WriterContext.cpp @@ -0,0 +1,346 @@ +#include "WriterContext.h" +#include "../HWPFile.h" +#include "../HWPXFile.h" + +#include +#include + +namespace HWP +{ +CWriterContext::CWriterContext() + : m_eType(EHanType::NONE), m_pHWPFile(nullptr), m_pHWPXFile(nullptr) +{} + +CWriterContext::~CWriterContext() +{ + if (nullptr != m_pHWPFile) + delete m_pHWPFile; + + if (nullptr != m_pHWPXFile) + delete m_pHWPXFile; +} + +void CWriterContext::Clear() +{ + m_eType = EHanType::NONE; + + if (nullptr != m_pHWPFile) + { + delete m_pHWPFile; + m_pHWPFile = nullptr; + } + + if (nullptr != m_pHWPXFile) + { + delete m_pHWPXFile; + m_pHWPXFile = nullptr; + } +} + +EHanType CWriterContext::GetType() +{ + return m_eType; +} + +VECTOR CWriterContext::GetSections() +{ + switch(m_eType) + { + case EHanType::NONE: break; + case EHanType::HWP: + { + if (nullptr != m_pHWPFile) + return m_pHWPFile->GetSections(); + + break; + } + case EHanType::HWPX: + { + if(nullptr != m_pHWPXFile) + return m_pHWPXFile->GetSections(); + + break; + } + } + + return VECTOR(); +} + +EHanType CWriterContext::DetectHancom(const HWP_STRING& sPathToFile) +{ + bool bDetected = false; + + CHWPFile* pHwpTemp = new CHWPFile(sPathToFile); + if (nullptr != pHwpTemp) + { + if (pHwpTemp->Detect()) + { + bDetected = true; + pHwpTemp->Close(); + } + + delete pHwpTemp; + } + + if (bDetected) + return EHanType::HWP; + + CHWPXFile* pHwpxTemp = new CHWPXFile(sPathToFile); + if (nullptr != pHwpxTemp) + { + if (pHwpxTemp->Detect()) + { + bDetected = true; + pHwpxTemp->Close(); + } + + delete pHwpxTemp; + } + + if (bDetected) + return EHanType::HWPX; + + return EHanType::NONE; +} + +bool CWriterContext::Detect() +{ + switch(m_eType) + { + case EHanType::HWP: + { + if (nullptr == m_pHWPFile) + return false; + + return m_pHWPFile->Detect(); + } + case EHanType::HWPX: + { + if (nullptr == m_pHWPXFile) + return false; + + return m_pHWPXFile->Detect(); + } + case EHanType::NONE: + return false; + } +} + +bool CWriterContext::Open(const HWP_STRING& sPathToFile, EHanType eHanType) +{ + Clear(); + + m_eType = eHanType; + + switch (m_eType) + { + case EHanType::HWP: + { + m_pHWPFile = new CHWPFile(sPathToFile); + + if (nullptr == m_pHWPFile) + return false; + + return m_pHWPFile->Open(); + } + case EHanType::HWPX: + { + m_pHWPXFile = new CHWPXFile(sPathToFile); + + if (nullptr == m_pHWPXFile) + return false; + + return m_pHWPXFile->Open(); + } + case EHanType::NONE: + break; + } + + return false; +} + +void CWriterContext::Close() +{ + switch (m_eType) + { + case EHanType::HWP: + { + if (nullptr != m_pHWPFile) + m_pHWPFile->Close(); + break; + } + case EHanType::HWPX: + { + if (nullptr != m_pHWPXFile) + m_pHWPXFile->Close(); + break; + } + case EHanType::NONE: + break; + } +} + +const CHWPDocInfo* CWriterContext::GetDocInfo() +{ + switch (m_eType) + { + case EHanType::HWP: + { + if (nullptr == m_pHWPFile) + return nullptr; + + return m_pHWPFile->GetDocInfo(); + } + case EHanType::HWPX: + { + if (nullptr == m_pHWPXFile) + return nullptr; + + return m_pHWPXFile->GetDocInfo(); + } + case EHanType::NONE: + return nullptr; + } +} + +const CHWPRecordBorderFill* CWriterContext::GetBorderFill(short shId) +{ + const CHWPDocInfo* pDocInfo = GetDocInfo(); + + if (nullptr == pDocInfo) + return nullptr; + + return (CHWPRecordBorderFill*)pDocInfo->GetBorderFill(shId); +} + +const CHWPRecordParaShape* CWriterContext::GetParaShape(int nId) +{ + const CHWPDocInfo* pDocInfo = GetDocInfo(); + + if (nullptr == pDocInfo) + return nullptr; + + return (CHWPRecordParaShape*)pDocInfo->GetParaShape(nId); +} + +const CHWPRecordStyle* CWriterContext::GetParaStyle(short shId) +{ + const CHWPDocInfo* pDocInfo = GetDocInfo(); + + if (nullptr == pDocInfo) + return nullptr; + + return (CHWPRecordStyle*)pDocInfo->GetStyle(shId); +} + +const CHWPRecordCharShape* CWriterContext::GetCharShape(int nId) +{ + const CHWPDocInfo* pDocInfo = GetDocInfo(); + + if (nullptr == pDocInfo) + return nullptr; + + return (CHWPRecordCharShape*)pDocInfo->GetCharShape(nId); +} + +const CHWPRecordNumbering* CWriterContext::GetNumbering(short shId) +{ + const CHWPDocInfo* pDocInfo = GetDocInfo(); + + if (nullptr == pDocInfo) + return nullptr; + + return (CHWPRecordNumbering*)pDocInfo->GetNumbering(shId); +} + +const CHWPRecordBullet* CWriterContext::GetBullet(short shId) +{ + const CHWPDocInfo* pDocInfo = GetDocInfo(); + + if (nullptr == pDocInfo) + return nullptr; + + return (CHWPRecordBullet*)pDocInfo->GetBullet(shId); +} + +const CHwpRecordTabDef* CWriterContext::GetTabDef(short shId) +{ + const CHWPDocInfo* pDocInfo = GetDocInfo(); + + if (nullptr == pDocInfo) + return nullptr; + + return (CHwpRecordTabDef*)pDocInfo->GetTabDef(shId); +} + +HWP_STRING CWriterContext::GetBinFilename(const HWP_STRING& sId) +{ + const CHWPDocInfo* pDocInfo = GetDocInfo(); + + if (nullptr == pDocInfo) + return HWP_STRING(); + + const CHWPRecordBinData* pBinData = dynamic_cast(pDocInfo->GetBinData(sId)); + + return (nullptr != pBinData) ? pBinData->GetPath() : HWP_STRING(); +} + +bool CWriterContext::GetBinBytes(const HWP_STRING& sId, CHWPStream& oBuffer, HWP_STRING& sFileName) +{ + const CHWPDocInfo* pDocInfo = nullptr; + + pDocInfo = GetDocInfo(); + + if (nullptr == pDocInfo) + return false; + + const CHWPRecordBinData* pBinData = dynamic_cast(pDocInfo->GetBinData(sId)); + + if (nullptr == pBinData) + return false; + + if (EType::LINK == pBinData->GetType()) + { + switch (m_eType) + { + case EHanType::HWPX: + { + sFileName = NSFile::GetFileName(pBinData->GetPath()); + return m_pHWPXFile->GetChildStream(pBinData->GetPath(), oBuffer); + } + default: + return false; + } + } + else + { + std::wostringstream oStringStream; + + switch (m_eType) + { + case EHanType::HWP: + { + oStringStream << L"BIN" << std::setw(4) << std::setfill(L'0') << std::hex << pBinData->GetBinDataID() << L"." << pBinData->GetFormat(); + sFileName = oStringStream.str(); + return m_pHWPFile->GetChildStream(oStringStream.str(), pBinData->GetCompressed(), oBuffer); + } + case EHanType::HWPX: + { + oStringStream << sId << L"." << pBinData->GetFormat(); + sFileName = oStringStream.str(); + return m_pHWPXFile->GetChildStream(L"BinData/" + oStringStream.str(), oBuffer); + } + default: + return false; + } + } + + return false; +} + +HWP_STRING CWriterContext::GetBinFormat(const HWP_STRING& sId) +{ + //TODO::реализовать + return HWP_STRING(); +} +} diff --git a/HwpFile/HwpDoc/Common/WriterContext.h b/HwpFile/HwpDoc/Common/WriterContext.h new file mode 100644 index 00000000000..0e5e2d0f3d6 --- /dev/null +++ b/HwpFile/HwpDoc/Common/WriterContext.h @@ -0,0 +1,50 @@ +#ifndef WRITERCONTEXT_H +#define WRITERCONTEXT_H + +#include "../HanType.h" +#include "../HWPFile.h" +#include "../HWPXFile.h" + +#include "../HWPElements/HWPRecordParaShape.h" +#include "../HWPElements/HWPRecordStyle.h" +#include "../HWPElements/HWPRecordCharShape.h" +#include "../HWPElements/HWPRecordNumbering.h" +#include "../HWPElements/HWPRecordBullet.h" +#include "../HWPElements/HwpRecordTabDef.h" + +namespace HWP +{ +class CWriterContext +{ + EHanType m_eType; + CHWPFile* m_pHWPFile; + CHWPXFile* m_pHWPXFile; +public: + CWriterContext(); + ~CWriterContext(); + + void Clear(); + EHanType GetType(); + + VECTOR GetSections(); + static EHanType DetectHancom(const HWP_STRING& sPathToFile); + bool Detect(); + bool Open(const HWP_STRING& sPathToFile, EHanType eHanType); + void Close(); + + const CHWPDocInfo* GetDocInfo(); + const CHWPRecordBorderFill* GetBorderFill(short shId); + const CHWPRecordParaShape* GetParaShape(int nId); + const CHWPRecordStyle* GetParaStyle(short shId); + const CHWPRecordCharShape* GetCharShape(int nId); + const CHWPRecordNumbering* GetNumbering(short shId); + const CHWPRecordBullet* GetBullet(short shId); + const CHwpRecordTabDef* GetTabDef(short shId); + + HWP_STRING GetBinFilename(const HWP_STRING& sId); + bool GetBinBytes(const HWP_STRING& sId, CHWPStream& oBuffer, HWP_STRING& sFileName); + HWP_STRING GetBinFormat(const HWP_STRING& sId); +}; +} + +#endif // WRITERCONTEXT_H diff --git a/HwpFile/HwpDoc/Common/XMLNode.h b/HwpFile/HwpDoc/Common/XMLNode.h new file mode 100644 index 00000000000..40709461132 --- /dev/null +++ b/HwpFile/HwpDoc/Common/XMLNode.h @@ -0,0 +1,24 @@ +#ifndef XMLNODEH_H +#define XMLNODEH_H + +#include "../../../DesktopEditor/xml/include/xmlutils.h" + +namespace HWP +{ +class CXMLNode : public XmlUtils::CXmlNode +{ +public: + CXMLNode(); + CXMLNode(const XmlUtils::CXmlNode& oNode); + + bool GetAttributeBool(const std::wstring& wsName); + int GetAttributeColor(const std::wstring& wsName, const int& _default = 0x00000000); + CXMLNode GetChild(const std::wstring& wsName); + std::vector GetChilds(); + std::vector GetChilds(const std::wstring& wsName); +}; + +int ConvertWidthToHWP(const std::wstring& wsValue); +} + +#endif // XMLNODEH_H diff --git a/HwpFile/HwpDoc/Common/XMLReader.cpp b/HwpFile/HwpDoc/Common/XMLReader.cpp new file mode 100644 index 00000000000..8b022f95b57 --- /dev/null +++ b/HwpFile/HwpDoc/Common/XMLReader.cpp @@ -0,0 +1,101 @@ +#include "XMLNode.h" + +namespace HWP +{ +CXMLNode::CXMLNode() + : XmlUtils::CXmlNode() +{} + +CXMLNode::CXMLNode(const CXmlNode& oNode) + : XmlUtils::CXmlNode(oNode) +{} + +bool CXMLNode::GetAttributeBool(const std::wstring& wsName) +{ + return L"1" == XmlUtils::CXmlNode::GetAttribute(wsName, L"0"); +} + +int CXMLNode::GetAttributeColor(const std::wstring& wsName, const int& _default) +{ + std::wstring sColor = XmlUtils::CXmlNode::GetAttribute(wsName); + + if (L"none" != sColor) + { + if (L'#' == sColor.front()) + sColor.erase(0, 1); + + if (sColor.length() < 6) + return _default; + + return std::stoi(sColor.substr(0, 6), nullptr, 16); + } + + return _default; +} + +CXMLNode CXMLNode::GetChild(const std::wstring& wsName) +{ + return CXMLNode(XmlUtils::CXmlNode::GetNode(wsName)); +} + +std::vector CXMLNode::GetChilds() +{ + std::vector arChilds; + XmlUtils::CXmlNode::GetChilds(arChilds); + + std::vector arNewChilds(arChilds.size()); + for (unsigned int unIndex = 0; unIndex < arChilds.size(); ++unIndex) + arNewChilds[unIndex] = CXMLNode(arChilds[unIndex]); + + return arNewChilds; +} + +std::vector CXMLNode::GetChilds(const std::wstring& wsName) +{ + std::vector arChilds{XmlUtils::CXmlNode::GetNodes(wsName)}; + + std::vector arNewChilds(arChilds.size()); + for (unsigned int unIndex = 0; unIndex < arChilds.size(); ++unIndex) + arNewChilds[unIndex] = CXMLNode(arChilds[unIndex]); + + return arNewChilds; +} + +int ConvertWidthToHWP(const std::wstring& wsValue) +{ + if (wsValue.empty() || L"0.1" == wsValue || L"0.1 mm" == wsValue) + return 0; + else if (L"0.12" == wsValue || L"0.12 mm" == wsValue) + return 1; + else if (L"0.15" == wsValue || L"0.15 mm" == wsValue) + return 2; + else if (L"0.2" == wsValue || L"0.2 mm" == wsValue) + return 3; + else if (L"0.25" == wsValue || L"0.25 mm" == wsValue) + return 4; + else if (L"0.3" == wsValue || L"0.3 mm" == wsValue) + return 5; + else if (L"0.4" == wsValue || L"0.4 mm" == wsValue) + return 6; + else if (L"0.5" == wsValue || L"0.5 mm" == wsValue) + return 7; + else if (L"0.6" == wsValue || L"0.6 mm" == wsValue) + return 8; + else if (L"0.7" == wsValue || L"0.7 mm" == wsValue) + return 9; + else if (L"1.0" == wsValue || L"1.0 mm" == wsValue) + return 10; + else if (L"1.5" == wsValue || L"1.5 mm" == wsValue) + return 11; + else if (L"2.0" == wsValue || L"2.0 mm" == wsValue) + return 12; + else if (L"3.0" == wsValue || L"3.0 mm" == wsValue) + return 13; + else if (L"4.0" == wsValue || L"4.0 mm" == wsValue) + return 14; + else if (L"5.0" == wsValue || L"5.0 mm" == wsValue) + return 15; + + return 0; +} +} diff --git a/HwpFile/HwpDoc/Conversion/Converter2OOXML.cpp b/HwpFile/HwpDoc/Conversion/Converter2OOXML.cpp new file mode 100644 index 00000000000..95d57abbf59 --- /dev/null +++ b/HwpFile/HwpDoc/Conversion/Converter2OOXML.cpp @@ -0,0 +1,2202 @@ +#include "Converter2OOXML.h" + +#include + +#include "../../../DesktopEditor/common/File.h" +#include "../../../DesktopEditor/common/Directory.h" +#include "../../../DesktopEditor/common/SystemUtils.h" +#include "../../../DesktopEditor/raster/BgraFrame.h" +#include "../../../OfficeUtils/src/OfficeUtils.h" + +#include "../../../DesktopEditor/graphics/pro/Graphics.h" + +#include "../Paragraph/ParaText.h" +#include "../Paragraph/CtrlTable.h" +#include "../Paragraph/CtrlEqEdit.h" +#include "../Paragraph/CtrlShapeArc.h" +#include "../Paragraph/CtrlShapePolygon.h" +#include "../Paragraph/CtrlShapeCurve.h" + +#include "../HWPElements/HWPRecordParaShape.h" +#include "../HWPElements/HWPRecordCharShape.h" + +#include "Transform.h" + +#define DEFAULT_FONT_FAMILY std::wstring(L"Arial") +#define DEFAULT_FONT_SIZE 18 +#define DEFAULT_LANGUAGE std::wstring(L"en") +#define PARA_SPACING_SCALE 0.85 +#define SPACING_SCALE_MS_WORD 1.21 + +namespace HWP +{ +static const std::vector> arHighlightColors + {{{{0, 0, 0}, L"black"}, {{0, 0, 255}, L"blue"}, {{0, 255, 255}, L"cyan"}, + {{0, 255, 0}, L"green"}, {{255, 0, 255}, L"magenta"}, {{255, 0, 0}, L"red"}, + {{255, 255, 0}, L"yellow"}, {{255, 255, 255}, L"white"}, {{0, 0, 139}, L"darkBlue"}, + {{0, 139, 139}, L"darkCyan"}, {{0, 100, 0}, L"darkGreen"}, {{139, 0, 139}, L"darkMagenta"}, + {{139, 0, 0}, L"darkRed"}, {{128, 128, 0}, L"darkYellow"},{{169, 169, 169}, L"darkGray"}, + {{211, 211, 211}, L"lightGray"}}}; + +enum class EShapeObjectType +{ + Arc, + Curve, + Ellipse, + Line, + Ole, + Picture, + Polygon, + Rectangle, + Unknown +}; + +EShapeObjectType GetShapeObjectType(const std::wstring& wsID) +{ + if (L"cra$" == wsID) + return EShapeObjectType::Arc; + if (L"ruc$" == wsID) + return EShapeObjectType::Curve; + if (L"lle$" == wsID) + return EShapeObjectType::Ellipse; + if (L"nil$" == wsID || L"loc$" == wsID) + return EShapeObjectType::Line; + if (L"elo$" == wsID) + return EShapeObjectType::Ole; + if (L"cip$" == wsID) + return EShapeObjectType::Picture; + if (L"lop$" == wsID) + return EShapeObjectType::Polygon; + if (L"cer$" == wsID) + return EShapeObjectType::Rectangle; + + return EShapeObjectType::Unknown; +} + +CConverter2OOXML::CConverter2OOXML() + : m_pContext(nullptr), m_ushShapeCount(0), m_ushPageCount(1), m_ushTableCount(0), + m_ushEquationCount(0), m_ushBookmarkCount(0) +{} + +CConverter2OOXML::~CConverter2OOXML() +{} + +void CConverter2OOXML::SetContext(CWriterContext* pContext) +{ + m_pContext = pContext; +} + +void CConverter2OOXML::SetTempDirectory(const HWP_STRING& sTempDirectory) +{ + m_sTempDirectory = sTempDirectory; + m_oOleConverter.SetTempDir(m_sTempDirectory); +} + +void CConverter2OOXML::CreateEmptyFiles() +{ + NSDirectory::CreateDirectory(m_sTempDirectory + L"/_rels"); + NSDirectory::CreateDirectory(m_sTempDirectory + L"/docProps"); + NSDirectory::CreateDirectory(m_sTempDirectory + L"/word"); + NSDirectory::CreateDirectory(m_sTempDirectory + L"/word/_rels"); + NSDirectory::CreateDirectory(m_sTempDirectory + L"/word/media"); + NSDirectory::CreateDirectory(m_sTempDirectory + L"/word/theme"); + + // theme1.xml + std::wstring wsTheme = L""; + NSFile::CFileBinary oThemeWriter; + if (oThemeWriter.CreateFileW(m_sTempDirectory + L"/word/theme/theme1.xml")) + { + oThemeWriter.WriteStringUTF8(wsTheme); + oThemeWriter.CloseFile(); + } + + // app.xml + std::wstring wsApplication = NSSystemUtils::GetEnvVariable(NSSystemUtils::gc_EnvApplicationName); + if (wsApplication.empty()) + wsApplication = NSSystemUtils::gc_EnvApplicationNameDefault; + + std::wstring wsApp = L""; + wsApp += wsApplication; + wsApp += L"0falsefalsefalsefalse"; + NSFile::CFileBinary oAppWriter; + if (oAppWriter.CreateFileW(m_sTempDirectory + L"/docProps/app.xml")) + { + oAppWriter.WriteStringUTF8(wsApp); + oAppWriter.CloseFile(); + } + + // .rels + std::wstring wsRels = L""; + NSFile::CFileBinary oRelsWriter; + if (oRelsWriter.CreateFileW(m_sTempDirectory + L"/_rels/.rels")) + { + oRelsWriter.WriteStringUTF8(wsRels); + oRelsWriter.CloseFile(); + } + + // fontTable.xml + std::wstring wsFontTable = L""; + NSFile::CFileBinary oFontTableWriter; + if (oFontTableWriter.CreateFileW(m_sTempDirectory + L"/word/fontTable.xml")) + { + oFontTableWriter.WriteStringUTF8(wsFontTable); + oFontTableWriter.CloseFile(); + } + + // settings.xml + std::wstring wsSettings = L""; + NSFile::CFileBinary oSettingsWriter; + if (oSettingsWriter.CreateFileW(m_sTempDirectory + L"/word/settings.xml")) + { + oSettingsWriter.WriteStringUTF8(wsSettings); + oSettingsWriter.CloseFile(); + } + + // core.xml + std::wstring wsCore = L""; + wsCore += L""; + NSFile::CFileBinary oCoreWriter; + if (oCoreWriter.CreateFileW(m_sTempDirectory + L"/docProps/core.xml")) + { + oCoreWriter.WriteStringUTF8(wsCore); + oCoreWriter.CloseFile(); + } + + FillDefaultData(); +} + +void CConverter2OOXML::FillDefaultData() +{ + // Заполняем начало файлов + AddRelationship(L"styles", L"styles.xml"); + AddRelationship(L"settings", L"settings.xml"); + AddRelationship(L"webSettings", L"webSettings.xml"); + AddRelationship(L"fontTable", L"fontTable.xml"); + AddRelationship(L"theme", L"theme/theme1.xml"); + + AddContentType(L"document.xml", L"application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"); + AddContentType(L"styles.xml", L"application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml"); + AddContentType(L"settings.xml", L"application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml"); + AddContentType(L"webSettings.xml", L"application/vnd.openxmlformats-officedocument.wordprocessingml.webSettings+xml"); + AddContentType(L"fontTable.xml", L"application/vnd.openxmlformats-officedocument.wordprocessingml.fontTable+xml"); + AddContentType(L"theme/theme1.xml", L"application/vnd.openxmlformats-officedocument.theme+xml"); + + m_oNoteXmlRels.WriteString(L""); + m_oDocXml .WriteString(L""); + m_oWebSettings.WriteString(L""); + + m_oStylesXml.WriteString(L""); + m_oStylesXml.WriteString(L""); + m_oStylesXml.WriteString(L""); + m_oStylesXml.WriteString(L""); + m_oStylesXml.WriteString(L""); + m_oStylesXml.WriteString(L""); + + m_oStylesXml.WriteString(L""); + m_oStylesXml.WriteString(L""); + m_oStylesXml.WriteString(L""); + + m_oStylesXml.WriteString(L""); + m_oStylesXml.WriteString(L""); + m_oStylesXml.WriteString(L""); + m_oStylesXml.WriteString(L""); +} + +void CConverter2OOXML::Close() +{ + // Дописываем концы файлов + m_oDocXml.WriteString(L""); + + NSFile::CFileBinary oDocumentWriter; + if (oDocumentWriter.CreateFileW(m_sTempDirectory + L"/word/document.xml")) + { + oDocumentWriter.WriteStringUTF8(m_oDocXml.GetData()); + oDocumentWriter.CloseFile(); + } + + if (m_oFootnoteConverter.SaveToFile(m_sTempDirectory + FILE_SEPARATOR_STR + L"word" + FILE_SEPARATOR_STR)) + { + AddRelationship(L"footnotes", L"footnotes.xml"); + AddRelationship(L"endnotes", L"endnotes.xml"); + + AddContentType(L"footnotes.xml", L"application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml"); + AddContentType(L"endnotes.xml", L"application/vnd.openxmlformats-officedocument.wordprocessingml.endnotes+xml"); + } + + // styles.xml + m_oStylesXml.WriteString(L""); + NSFile::CFileBinary oStylesWriter; + if (oStylesWriter.CreateFileW(m_sTempDirectory + L"/word/styles.xml")) + { + oStylesWriter.WriteStringUTF8(m_oStylesXml.GetData()); + oStylesWriter.CloseFile(); + } + + // numbering.xml + if (m_oNumberingConverter.SaveToFile(m_sTempDirectory + FILE_SEPARATOR_STR + L"word" + FILE_SEPARATOR_STR)) + { + AddRelationship(L"numbering", L"numbering.xml"); + + AddContentType(L"numbering.xml", L"application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml"); + } + + // webSettings.xml + m_oWebSettings.WriteString(L""); + NSFile::CFileBinary oWebSettingsWriter; + if (oWebSettingsWriter.CreateFileW(m_sTempDirectory + L"/word/webSettings.xml")) + { + oWebSettingsWriter.WriteStringUTF8(m_oWebSettings.GetData()); + oWebSettingsWriter.CloseFile(); + } + + // [Content_Types].xml + NSFile::CFileBinary oContentTypeWriter; + if (oContentTypeWriter.CreateFileW(m_sTempDirectory + L"/[Content_Types].xml")) + { + oContentTypeWriter.WriteStringUTF8(L""); + oContentTypeWriter.WriteStringUTF8(L""); + + for (const TContentType& oContentType : m_arDefaultContentType) + oContentTypeWriter.WriteStringUTF8(L""); + + for (const TContentType& oContentType : m_arContentTypes) + oContentTypeWriter.WriteStringUTF8(L""); + + oContentTypeWriter.WriteStringUTF8(L""); + oContentTypeWriter.WriteStringUTF8(L""); + + oContentTypeWriter.WriteStringUTF8(L""); + oContentTypeWriter.CloseFile(); + } + + NSFile::CFileBinary oRelsWriter; + if (oRelsWriter.CreateFileW(m_sTempDirectory + L"/word/_rels/document.xml.rels")) + { + oRelsWriter.WriteStringUTF8(L""); + + for (const TRelationship& oRelationship : m_arRelationships) + { + oRelsWriter.WriteStringUTF8(L""); + else + oRelsWriter.WriteStringUTF8(L"/>"); + } + + oRelsWriter.WriteStringUTF8(L""); + + oRelsWriter.CloseFile(); + } +} + +void CConverter2OOXML::Convert() +{ + if (nullptr == m_pContext) + return; + + TConversionState oState; + + std::vector arSetcions{m_pContext->GetSections()}; + + for (const CHWPSection* pSection : arSetcions) + { + const bool bIsLastSection = pSection == arSetcions.back(); + + for (const CHWPPargraph *pPara : pSection->GetParagraphs()) + WriteParagraph(pPara, m_oDocXml, oState); + + if (!bIsLastSection) + m_oDocXml.WriteString(L""); + + WriteSectionSettings(oState); + + if (!bIsLastSection) + m_oDocXml.WriteString(L""); + + ++oState.m_ushSecdIndex; + } +} + +bool CConverter2OOXML::IsRasterFormat(const HWP_STRING& sFormat) +{ + return L"png" == sFormat || L"jpg" == sFormat || L"jpeg" == sFormat || L"bmp" == sFormat; +} + +void CConverter2OOXML::WriteCharacter(const CCtrlCharacter* pCharacter, short shParaShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState) +{ + if (nullptr == pCharacter) + return; + + switch (pCharacter->GetType()) + { + case ECtrlCharType::PARAGRAPH_BREAK: + { + if (!oState.m_bOpenedP) + break; + + oState.m_bOpenedP = false; + oBuilder.WriteString(L"
"); + + break; + } + case ECtrlCharType::LINE_BREAK: + { + oState.m_eBreakType = TConversionState::EBreakType::TextWrapping; + break; + } + case ECtrlCharType::HARD_HYPHEN: + case ECtrlCharType::HARD_SPACE: + break; + } +} + +void CConverter2OOXML::WriteShape(const CCtrlGeneralShape* pShape, short shParaShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState) +{ + if (nullptr == pShape || oState.m_bInTextBox) + return; + + switch (pShape->GetShapeType()) + { + case EShapeType::Arc: + case EShapeType::Ellipse: + case EShapeType::Rect: + case EShapeType::Line: + case EShapeType::Polygon: + case EShapeType::Curve: + { + WriteGeometryShape(pShape, shParaShapeID, oBuilder, oState); + break; + } + case EShapeType::Pic: + { + WritePicture((const CCtrlShapePic*)pShape, shParaShapeID, oBuilder, oState); + break; + } + case EShapeType::EqEdit: + { + WriteEqEditShape((const CCtrlEqEdit*)pShape, shParaShapeID, oBuilder, oState); + break; + } + case EShapeType::Ole: + { + WriteOleShape((const CCtrlShapeOle*)pShape, shParaShapeID, oBuilder, oState); + break; + } + case EShapeType::Video: + { + WriteVideo((const CCtrlShapeVideo*)pShape, shParaShapeID, oBuilder, oState); + break; + } + case EShapeType::GeneralShape: + case EShapeType::ConnectLine: + case EShapeType::Container: + case EShapeType::TextArt: + break; + } +} + +void CConverter2OOXML::WriteNote(const CCtrlNote* pNote, short shParaShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState) +{ + oBuilder.WriteString(L""); + + WriteRunnerStyle(oState.m_ushLastCharShapeId, oBuilder, oState, L""); + + oBuilder.WriteString(m_oFootnoteConverter.CreateNote((const CCtrlNote*)pNote, *this)); + + oBuilder.WriteString(L""); +} + +void CConverter2OOXML::WriteField(const CCtrlField* pShape, short shParaShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState) +{ + if (nullptr == pShape) + return; + + switch (pShape->GetType()) + { + case EFieldType::Hyperlink: + { + HWP_STRING wsHref = pShape->GetStringParam(L"Path"); + + if(wsHref.empty()) + { + HWP_STRING sCommand = pShape->GetStringParam(L"Command"); + + if (sCommand.empty()) + sCommand = pShape->GetCommand(); + + sCommand = sCommand.substr(0, sCommand.find(L';')); + + size_t unFound = sCommand.find(L'\\'); + + while (HWP_STRING::npos != unFound) + { + sCommand.erase(unFound, 1); + unFound = sCommand.find(L'\\', unFound); + } + + wsHref = sCommand; + } + + if (wsHref.empty()) + break; + + const HWP_STRING wsID = AddRelationship(L"hyperlink", wsHref); + + OpenParagraph(shParaShapeID, oBuilder, oState); + oBuilder.WriteString(L""); + + oState.m_mOpenField.insert(std::make_pair(pShape->GetInstanceID(), pShape)); + + break; + } + case EFieldType::HyperlinkClosing: + { + oBuilder.WriteString(L""); + break; + } + case EFieldType::Bookmark: + { + oBuilder.WriteString(L"GetStringParam(L"bookmarkname")); + oBuilder.WriteString(L"\"/>"); + + oState.m_arOpenedBookmarks.push(m_ushBookmarkCount++); + oState.m_mOpenField.insert(std::make_pair(pShape->GetInstanceID(), pShape)); + + break; + } + case EFieldType::BookmarkClosing: + { + if (oState.m_arOpenedBookmarks.empty()) + break; + + oBuilder.WriteString(L""); + oState.m_arOpenedBookmarks.pop(); + break; + } + //TODO:: как-будто хочется определить тип закрывающей field на этапе парса hwpx + case EFieldType::Unknown: + { + std::map::const_iterator itFound = oState.m_mOpenField.find(pShape->GetInstanceID()); + + if (oState.m_mOpenField.cend() != itFound) + { + switch (itFound->second->GetType()) + { + case EFieldType::Hyperlink: + { + oBuilder.WriteString(L"
"); + break; + } + case EFieldType::Bookmark: + { + if (oState.m_arOpenedBookmarks.empty()) + break; + + oBuilder.WriteString(L""); + oState.m_arOpenedBookmarks.pop(); + break; + } + default: + break; + } + } + + break; + } + } +} + +void CConverter2OOXML::WriteCaption(const CCtrlCommon* pCtrlCommon, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState) +{ + if (nullptr == pCtrlCommon || !pCtrlCommon->HaveCaption()) + return; + + for (const CCapParagraph* pCapParagraph : pCtrlCommon->GetCaptionParas()) + WriteParagraph(pCapParagraph, oBuilder, oState); +} + +void CConverter2OOXML::WriteParagraph(const CHWPPargraph* pParagraph, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState) +{ + if (nullptr == pParagraph) + return; + + CloseParagraph(oBuilder, oState); + + if (0 < pParagraph->GetBreakType()) + { + if ((0x04 == (pParagraph->GetBreakType() & 0x04)) && (0 < oState.m_unParaIndex)) + { + oState.m_eBreakType = TConversionState::EBreakType::Page; + // oBuilder.WriteString(L""); + ++m_ushPageCount; + } + else if (0x08 == (pParagraph->GetBreakType() & 0x08)) + oState.m_eBreakType = TConversionState::EBreakType::Column; + // oBuilder.WriteString(L""); + } + + ++oState.m_unParaIndex; + + for (const CCtrl* pCtrl : pParagraph->GetCtrls()) + { + switch (pCtrl->GetCtrlType()) + { + case ECtrlObjectType::ParaText: + { + WriteText((const CParaText*)pCtrl, pParagraph->GetRangeTags(), pParagraph->GetShapeID(), oBuilder, oState); + // WriteText(((const CParaText*)pCtrl)->GetText(), pParagraph->GetShapeID(), ((const CParaText*)pCtrl)->GetCharShapeID(), oBuilder, oState); + break; + } + case ECtrlObjectType::Character: + { + WriteCharacter((const CCtrlCharacter*)pCtrl, pParagraph->GetShapeID(), oBuilder, oState); + break; + } + case ECtrlObjectType::Shape: + { + WriteShape((const CCtrlGeneralShape*)pCtrl, pParagraph->GetShapeID(), oBuilder, oState); + break; + } + case ECtrlObjectType::Table: + { + WriteTable((const CCtrlTable*)pCtrl, pParagraph->GetShapeID(), oBuilder, oState); + break; + } + case ECtrlObjectType::Note: + { + WriteNote((const CCtrlNote*)pCtrl, pParagraph->GetShapeID(), oBuilder, oState); + break; + } + case ECtrlObjectType::SectionDef: + { + oState.m_pSectionDef = (const CCtrlSectionDef*)pCtrl; + break; + } + case ECtrlObjectType::ColumnDef: + { + oState.m_pColumnDef = (const CCtrlColumnDef*)(pCtrl); + break; + } + case ECtrlObjectType::AutoNumber: + { + WriteAutoNumber((const CCtrlAutoNumber*)pCtrl, pParagraph->GetShapeID(), oState.m_ushLastCharShapeId, oBuilder, oState); + break; + } + case ECtrlObjectType::Field: + { + WriteField((const CCtrlField*)pCtrl, pParagraph->GetShapeID(), oBuilder, oState); + break; + } + case ECtrlObjectType::HeadFoot: + { + if (EHanType::HWPX == m_pContext->GetType()) + oState.m_arCtrlsHeadFoot.push_back((const CCtrlHeadFoot*)pCtrl); + break; + } + default: + break; + } + } + + CloseParagraph(oBuilder, oState); +} + +void CConverter2OOXML::WriteParagraphProperties(short shParaShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState) +{ + oBuilder.WriteString(L""); + + WriteParaShapeProperties(shParaShapeID, oBuilder, oState); + + oBuilder.WriteString(L""); +} + +void CConverter2OOXML::WriteParaShapeProperties(short shParaShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState) +{ + if (nullptr == m_pContext) + return; + + const CHWPRecordParaShape* pParaShape = dynamic_cast(m_pContext->GetParaShape(shParaShapeID)); + + if (nullptr == pParaShape) + return; + + if (pParaShape->GetPageBreakBefore()) + oState.m_eBreakType = TConversionState::EBreakType::Page; + + oBuilder.WriteString(L"KeepWithNext()) ? L"true" : L"false") + L"\"/>"); + + const int nIndent = pParaShape->GetIndent(); + + if (0 != nIndent) + oBuilder.WriteString(L"(std::ceil(nIndent / 10.))) + L"\"/>"); + + switch(pParaShape->GetHorizantalAlign()) + { + case EHorizontalAlign::JUSTIFY: oBuilder.WriteString(L""); break; + case EHorizontalAlign::LEFT: oBuilder.WriteString(L""); break; + case EHorizontalAlign::RIGHT: oBuilder.WriteString(L""); break; + case EHorizontalAlign::CENTER: oBuilder.WriteString(L""); break; + case EHorizontalAlign::DISTRIBUTE: + case EHorizontalAlign::DISTRIBUTE_SPACE: oBuilder.WriteString(L""); break; + } + + switch(pParaShape->GetVerticalAlign()) + { + case EVerticalAlign::BOTTOM: oBuilder.WriteString(L""); break; + case EVerticalAlign::TOP: oBuilder.WriteString(L""); break; + case EVerticalAlign::CENTER: oBuilder.WriteString(L""); break; + case EVerticalAlign::BASELINE: + break; + } + + int nLineSpacing = 240; + HWP_STRING sType = L"auto"; + + switch(pParaShape->GetLineSpacingType()) + { + case 0x0: + { + sType = L"auto"; + nLineSpacing = static_cast(240. * (double)pParaShape->GetLineSpacing() / 100.); // TODO:: в hwp изначально межстрочный интервал меньше. Множитель 1 в hwp ≈ 0.65 MS + break; + } + case 0x01: + { + sType = L"exact"; + nLineSpacing = static_cast((double)pParaShape->GetLineSpacing() / 2. * 20)/*0.352778*/; //(1pt=0.352778mm) //TODO:: проверить, как найдется пример + break; + break; + } + case 0x02: + case 0x03: + default: + { + sType = L"atLeast"; + nLineSpacing = static_cast((double)pParaShape->GetLineSpacing()); //TODO:: проверить, как найдется пример + break; + } + } + + oBuilder.WriteString(L"((double)pParaShape->GetMarginPrev() / 10.)) + + L"\" w:after=\"" + std::to_wstring(static_cast((double)pParaShape->GetMarginNext() / 10.)) + L"\"/>"); + + switch (pParaShape->GetHeadingType()) + { + case EHeadingType::NUMBER: + case EHeadingType::BULLET: + { + const int nNumId = m_oNumberingConverter.CreateNumbering(dynamic_cast(m_pContext->GetNumbering(pParaShape->GetHeadingIdRef())), pParaShape->GetHeadingType()); + + if (0 == nNumId) + break; + + oBuilder.WriteString(L""); + + oBuilder.WriteString(L"GetHeadingLevel()) + L"\"/>"); + oBuilder.WriteString(L""); + + oBuilder.WriteString(L""); + + break; + } + case EHeadingType::OUTLINE: + case EHeadingType::NONE: + break; + } +} + +void CConverter2OOXML::WriteTable(const CCtrlTable* pTable, short shParaShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState) +{ + if (nullptr == pTable || pTable->Empty()) + return; + + CloseParagraph(oBuilder, oState); + + ++m_ushTableCount; + + oBuilder.WriteString(L""); + + WriteTableProperties(pTable, shParaShapeID, oBuilder, oState); + + std::vector>> m_arrCells(pTable->GetRows()); + + for (unsigned int unRowIndex = 0; unRowIndex < pTable->GetRows(); ++unRowIndex) + { + m_arrCells[unRowIndex].resize(pTable->GetCols()); + + for (unsigned int unColIndex = 0; unColIndex < pTable->GetCols(); ++unColIndex) + m_arrCells[unRowIndex][unColIndex] = std::make_pair(ECellCreator::NOT_CREATED, nullptr); + } + + for (unsigned int unCellIndex = 0; unCellIndex < pTable->GetCountCells(); ++unCellIndex) + { + const CTblCell* pCell = pTable->GetCell(unCellIndex); + + if (nullptr == pCell || pCell->GetRowAddr() >= pTable->GetRows() || pCell->GetColAddr() >= pTable->GetCols()) + continue; + + m_arrCells[pCell->GetRowAddr()][pCell->GetColAddr()] = std::make_pair(ECellCreator::FILE, pCell); + } + + for (unsigned int unRowIndex = 0; unRowIndex < pTable->GetRows(); ++unRowIndex) + { + for (unsigned int unColIndex = 0; unColIndex < pTable->GetCols(); ++unColIndex) + { + std::pair oValue = m_arrCells[unRowIndex][unColIndex]; + + if (ECellCreator::NOT_CREATED == oValue.first) + continue; + + if (ECellCreator::FILE == oValue.first) + { + if (1 != oValue.second->GetRowSpan()) + { + for (unsigned int unIndex = 1; unIndex < oValue.second->GetRowSpan() && unRowIndex + unIndex < pTable->GetRows(); ++unIndex) + m_arrCells[unRowIndex + unIndex][unColIndex] = std::make_pair(ECellCreator::EMPTY, oValue.second); + } + } + + unColIndex += oValue.second->GetColSpan() - 1; + } + } + + //TODO:: в случаях, когда есть пустые столбцы необходимо добавить возможность удаления данных столбцов + // Например для матрицы 3x2, у которой значения есть только в 2x2, необходимо удалить последний столбец + + for (unsigned int unRowIndex = 0; unRowIndex < pTable->GetRows(); ++unRowIndex) + { + oBuilder.WriteString(L""); + + int nHeight = 0; + + for (unsigned int unColIndex = 0; unColIndex < pTable->GetCols(); ++unColIndex) + { + std::pair oValue = m_arrCells[unRowIndex][unColIndex]; + if (ECellCreator::FILE == oValue.first && 1 == oValue.second->GetRowSpan()) + nHeight = (std::max)(nHeight, oValue.second->GetHeight()); + } + + oBuilder.WriteString(L""); + oBuilder.WriteString(L""); + oBuilder.WriteString(L""); + + for (unsigned int unColIndex = 0; unColIndex < pTable->GetCols(); ++unColIndex) + { + std::pair oValue = m_arrCells[unRowIndex][unColIndex]; + + WriteCell(oValue.second, oBuilder, oState, oValue.first); + } + + oBuilder.WriteString(L""); + } + + oBuilder.WriteString(L""); +} + +void CConverter2OOXML::WriteTableProperties(const CCtrlTable* pTable, short shParaShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState) +{ + if (nullptr == pTable) + return; + + oBuilder.WriteString(L""); + + oBuilder.WriteString(L""); + + WriteParaShapeProperties(shParaShapeID, oBuilder, oState); + + const CHWPRecordBorderFill* pBorderFill = nullptr; + + if (nullptr != m_pContext) + pBorderFill = dynamic_cast(m_pContext->GetBorderFill(pTable->GetBorderFillID())); + + if (nullptr == pBorderFill) + { + oBuilder.WriteString(L""); + return; + } + + oBuilder.WriteString(L""); +} + +void CConverter2OOXML::WriteCell(const CTblCell* pCell, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState, ECellCreator eCellCreator) +{ + if (nullptr == pCell) + return; + + oBuilder.WriteString(L""); + + oBuilder.WriteString(L""); + oBuilder.WriteString(L"GetWidth())) + L"\" w:type=\"dxa\"/>"); + + if (1 != pCell->GetColSpan()) + oBuilder.WriteString(L"GetColSpan()) + L"\"/>"); + + if (1 != pCell->GetRowSpan()) + oBuilder.WriteString(L""); + + WriteCellProperties(pCell->GetBorderFillID(), oBuilder); + + switch(pCell->GetVertAlign()) + { + case EVertAlign::TOP: oBuilder.WriteString(L""); break; + case EVertAlign::CENTER: oBuilder.WriteString(L""); break; + case EVertAlign::BOTTOM: oBuilder.WriteString(L""); break; + case EVertAlign::INSIDE: + case EVertAlign::OUTSIDE: + break; + } + + oBuilder.WriteString(L""); + + if (ECellCreator::FILE == eCellCreator && !pCell->GetParagraphs().empty()) + { + for (const CHWPPargraph* pParagraph : pCell->GetParagraphs()) + { + NSStringUtils::CStringBuilder oCellBuilder; + TConversionState oCellState; + + WriteParagraph(pParagraph, oCellBuilder, oCellState); + + if (0 == oCellBuilder.GetCurSize()) + { + OpenParagraph(pParagraph->GetShapeID(), oBuilder, oCellState); + CloseParagraph(oBuilder, oCellState); + } + else + oBuilder.Write(oCellBuilder); + } + } + else + oBuilder.WriteString(L""); + + oBuilder.WriteString(L""); +} + +void CConverter2OOXML::WriteCellProperties(short shBorderFillID, NSStringUtils::CStringBuilder& oBuilder) +{ + const CHWPRecordBorderFill* pBorderFill = nullptr; + + if (nullptr != m_pContext) + pBorderFill = dynamic_cast(m_pContext->GetBorderFill(shBorderFillID)); + + if (nullptr == pBorderFill) + return; + + if (nullptr != pBorderFill->GetFill() && pBorderFill->GetFill()->ColorFill()) + oBuilder.WriteString(L"GetFill()->GetFaceColor()) + L"\"/>"); + + oBuilder.WriteString(L""); + + WriteBorder(pBorderFill->GetTopBorder(), L"top", oBuilder); + WriteBorder(pBorderFill->GetLeftBorder(), L"left", oBuilder); + WriteBorder(pBorderFill->GetBottomBorder(), L"bottom", oBuilder); + WriteBorder(pBorderFill->GetRightBorder(), L"right", oBuilder); + + oBuilder.WriteString(L""); +} + +void CConverter2OOXML::WriteBorder(const TBorder& oBorder, const HWP_STRING& sBorderName, NSStringUtils::CStringBuilder& oBuilder) +{ + if (0x00 == oBorder.m_chWidth || sBorderName.empty()) + return; + + HWP_STRING sType; + + //TODO:: проверить стиль линий + switch(oBorder.m_eStyle) + { + case ELineStyle2::NONE: oBuilder.WriteString(L""); return; + case ELineStyle2::SOLID: sType = L"single"; break; + case ELineStyle2::DASH: sType = L"dashed"; break; + case ELineStyle2::DOT: sType = L"dotted"; break; + case ELineStyle2::DASH_DOT: sType = L"dotDash"; break; + case ELineStyle2::DASH_DOT_DOT: sType = L"dotDotDash"; break; + case ELineStyle2::LONG_DASH: sType = L"dashed"; break; + case ELineStyle2::CIRCLE: sType = L"dashed"; break; + case ELineStyle2::DOUBLE_SLIM: sType = L"thickThinMediumGap"; break; + case ELineStyle2::SLIM_THICK: sType = L"thickThinMediumGap"; break; + case ELineStyle2::THICK_SLIM: sType = L"thickThinMediumGap"; break; + case ELineStyle2::SLIM_THICK_SLIM: sType = L"thickThinMediumGap"; break; + break; + } + + oBuilder.WriteString(L""); +} + +VECTOR ArcToBezier(const TPoint& oStart, const TPoint& oEnd, const TPoint& oCenter) +{ + const double dRadiusX = std::abs(oStart.m_nX - oCenter.m_nX); + const double dRadiusY = std::abs(oStart.m_nY - oCenter.m_nY); + + // Вычисление углов + double dStartAngle = std::atan2(oStart.m_nY - oCenter.m_nY, oStart.m_nX - oCenter.m_nX); + double dEndAngle = std::atan2(oEnd.m_nY - oCenter.m_nY, oEnd.m_nX - oCenter.m_nX); + + if (dEndAngle < dStartAngle) + std::swap(dStartAngle, dEndAngle); + + TPoint oControl1{static_cast(oStart.m_nX + dRadiusX * std::cos(dStartAngle)), static_cast(oStart.m_nY + dRadiusY * std::sin(dStartAngle))}; + TPoint oControl2{static_cast(oEnd.m_nX - dRadiusX * std::cos(dEndAngle )), static_cast(oEnd.m_nY + dRadiusY * std::sin(dEndAngle ))}; + + return {oStart, oControl1, oControl2, oEnd}; +} + +void CConverter2OOXML::WriteGeometryShape(const CCtrlGeneralShape* pGeneralShape, short shParaShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState) +{ + if (nullptr == pGeneralShape) + return; + + EShapeObjectType eShapeType = GetShapeObjectType(pGeneralShape->GetID()); + + if (EShapeObjectType::Unknown == eShapeType) + return; + + ++m_ushShapeCount; + + WriteCaption((const CCtrlCommon*)pGeneralShape, oBuilder, oState); + + OpenParagraph(shParaShapeID, oBuilder, oState); + + const int nWidth = Transform::HWPUINT2OOXML(pGeneralShape->GetWidth()); + const int nHeight = Transform::HWPUINT2OOXML(pGeneralShape->GetHeight()); + + const std::wstring wsWidth = std::to_wstring(nWidth); + const std::wstring wsHeight = std::to_wstring(nHeight); + + oBuilder.WriteString(L""); + oBuilder.WriteString(L""); + + OpenDrawingNode(pGeneralShape, oBuilder); + + oBuilder.WriteString(L""); + oBuilder.WriteString(L""); + oBuilder.WriteString(L""); + oBuilder.WriteString(L""); + oBuilder.WriteString(L""); + oBuilder.WriteString(L""); + + switch (eShapeType) + { + case EShapeObjectType::Arc: + { + const CCtrlShapeArc *pShapeArc = (const CCtrlShapeArc*)pGeneralShape; + VECTOR arBezierPoints{ArcToBezier({Transform::HWPUINT2OOXML(pShapeArc->GetFirstPoint() .m_nX), Transform::HWPUINT2OOXML(pShapeArc->GetFirstPoint() .m_nY)}, + {Transform::HWPUINT2OOXML(pShapeArc->GetSecondPoint().m_nX), Transform::HWPUINT2OOXML(pShapeArc->GetSecondPoint().m_nY)}, + {Transform::HWPUINT2OOXML(pShapeArc->GetCenterPoint().m_nX), Transform::HWPUINT2OOXML(pShapeArc->GetCenterPoint().m_nY)})}; + + oBuilder.WriteString(L""); + oBuilder.WriteString(L""); + + oBuilder.WriteString(L""); + oBuilder.WriteString(L""); + oBuilder.WriteString(L""); + oBuilder.WriteString(L""); + oBuilder.WriteString(L""); + + oBuilder.WriteString(L""); + + break; + } + case EShapeObjectType::Ellipse: + { + oBuilder.WriteString(L""); + break; + } + case EShapeObjectType::Line: + { + oBuilder.WriteString(L""); + break; + } + + case EShapeObjectType::Rectangle: + { + oBuilder.WriteString(L""); + break; + } + case EShapeObjectType::Polygon: + { + VECTOR arPoints{((const CCtrlShapePolygon*)pGeneralShape)->GetPoints()}; + + if (2 > arPoints.size()) + break; + + oBuilder.WriteString(L""); + oBuilder.WriteString(L""); + + for (unsigned short ushIndex = 1; ushIndex < arPoints.size(); ++ushIndex) + oBuilder.WriteString(L""); + + oBuilder.WriteString(L""); + break; + } + case EShapeObjectType::Curve: + { + VECTOR arPoints{((const CCtrlShapeCurve*)pGeneralShape)->GetPoints()}; + + if (2 > arPoints.size()) + break; + + VECTOR arSegmentType{((const CCtrlShapeCurve*)pGeneralShape)->GetSegmentsType()}; + oBuilder.WriteString(L""); + oBuilder.WriteString(L""); + + for (unsigned short ushIndex = 0; ushIndex < arSegmentType.size(); ++ushIndex) + { + if (0x01 == arSegmentType[ushIndex]) + { + oBuilder.WriteString(L""); + oBuilder.WriteString(L""); + oBuilder.WriteString(L""); + oBuilder.WriteString(L""); + oBuilder.WriteString(L""); + ushIndex += 2; + } + else + oBuilder.WriteString(L""); + } + + oBuilder.WriteString(L""); + break; + } + case EShapeObjectType::Ole: + case EShapeObjectType::Picture: + case EShapeObjectType::Unknown: + break; + } + + const CFill *pFill = pGeneralShape->GetFill(); + + if (nullptr == pFill || pFill->NoneFill()) + oBuilder.WriteString(L""); + else if (pFill->ColorFill()) + oBuilder.WriteString(L"GetFaceColor()) + L"\"/>"); + else if (pFill->ImageFill()) + { + const HWP_STRING sPictureId = SavePicture(pFill->GetBinItemID()); + + if (!sPictureId.empty()) + oBuilder.WriteString(L""); + else + oBuilder.WriteString(L""); + } + + WriteLineSettings(pGeneralShape, oBuilder); + + oBuilder.WriteString(L""); + + unsigned int nCountParagraphs = pGeneralShape->GetCountParagraphs(); + + if (0 < nCountParagraphs) + { + oBuilder.WriteString(L""); + + TConversionState oShapeState; + oShapeState.m_bInTextBox = true; + + for (unsigned int unParaIndex = 0; unParaIndex < nCountParagraphs; ++unParaIndex) + WriteParagraph(pGeneralShape->GetParagraphs(unParaIndex), oBuilder, oShapeState); + + oBuilder.WriteString(L""); + } + + oBuilder.WriteString(L""); + + oBuilder.WriteString(L""); + CloseDrawingNode(pGeneralShape, oBuilder); + oBuilder.WriteString(L""); +} + +void CConverter2OOXML::WriteEqEditShape(const CCtrlEqEdit* pEqEditShape, short shParaShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState) +{ + //TODO:: добавить конвертацию eqn формулы в ooxml + ++m_ushEquationCount; + + WriteCaption((const CCtrlCommon*)pEqEditShape, oBuilder, oState); + + OpenParagraph(shParaShapeID, oBuilder, oState); + + oBuilder.WriteString(L""); + + oBuilder.WriteString(L""); + oBuilder.WriteEncodeXmlString(pEqEditShape->GetEqn()); + oBuilder.WriteString(L""); +} + +void CConverter2OOXML::WriteOleShape(const CCtrlShapeOle* pOleShape, short shParaShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState) +{ + //TODO:: добавить конвертацию hwp ole -> ooxml chart + //TODO:: необходимо добавить поддержку формата "Hwp Document File Formats - Charts" (для случаев, когда нет ooxml представления) + // Пока можем вытащить лишь ooxml представление данных + // Реализовать с использованием pole.h? + + if (nullptr == m_pContext) + return; + + CHWPStream oBuffer; + HWP_STRING sFileName; + + if (!m_pContext->GetBinBytes(pOleShape->GetBinDataID(), oBuffer, sFileName)) + return; + + m_oOleConverter.CreateChart(oBuffer); + + const unsigned int unChartIndex = m_oOleConverter.GetChartsCount(); + + if (0 == unChartIndex) + return; + + ++m_ushShapeCount; + + WriteCaption((const CCtrlCommon*)pOleShape, oBuilder, oState); + + const std::wstring wsWidth = std::to_wstring(Transform::HWPUINT2OOXML(pOleShape->GetWidth())); + const std::wstring wsHeight = std::to_wstring(Transform::HWPUINT2OOXML(pOleShape->GetHeight())); + const std::wstring wsRelID = AddRelationship(L"chart", L"charts/chart" + std::to_wstring(unChartIndex) + L".xml"); + + OpenParagraph(shParaShapeID, oBuilder, oState); + + oBuilder.WriteString(L""); + + OpenDrawingNode(pOleShape, oBuilder); + + oBuilder.WriteString(L""); + oBuilder.WriteString(L""); + oBuilder.WriteString(L""); + oBuilder.WriteString(L""); + CloseDrawingNode(pOleShape, oBuilder); + oBuilder.WriteString(L""); + + AddContentType(L"charts/chart" + std::to_wstring(unChartIndex) + L".xml", L"application/vnd.openxmlformats-officedocument.drawingml.chart+xml"); + AddContentType(L"charts/style" + std::to_wstring(unChartIndex) + L".xml", L"application/vnd.ms-office.chartstyle+xml"); + AddContentType(L"charts/colors" + std::to_wstring(unChartIndex) + L".xml", L"application/vnd.ms-office.chartcolorstyle+xml"); +} + +void CConverter2OOXML::WriteSectionSettings(TConversionState& oState) +{ + m_oDocXml.WriteString(L""); + + if (nullptr != oState.m_pSectionDef) + { + std::vector arCtrlsHeadFoot; + + if (EHanType::HWP == m_pContext->GetType()) + arCtrlsHeadFoot = oState.m_pSectionDef->GetHeaderFooters(); + else if (EHanType::HWPX == m_pContext->GetType()) + { + arCtrlsHeadFoot = oState.m_arCtrlsHeadFoot; + oState.m_arCtrlsHeadFoot.clear(); + } + + for (const CCtrlHeadFoot* pCtrlHeadFoot : arCtrlsHeadFoot) + { + const std::wstring wsID = m_oFootnoteConverter.CreateHeadOrFoot((const CCtrlHeadFoot*)pCtrlHeadFoot, *this); + + if (!wsID.empty() && wsID.length() > 6) + { + const std::wstring wsType = wsID.substr(0, 6); + + AddContentType(wsID, L"application/vnd.openxmlformats-officedocument.wordprocessingml." + wsType + L"+xml"); + + m_oDocXml.WriteString(L""); + } + } + } + + const CPage *pPage = (nullptr != oState.m_pSectionDef) ? oState.m_pSectionDef->GetPage() : nullptr; + + if (nullptr == pPage) + { + //DEFAULT_VALUE + m_oDocXml.WriteString(L""); + m_oDocXml.WriteString(L""); + } + else + { + m_oDocXml.WriteString(L"GetWidth())) + L"\" w:h=\"" + std::to_wstring(Transform::HWPUINT2Twips(pPage->GetHeight())) + L"\"/>"); + m_oDocXml.WriteString(L"GetMarginTop())) + L"\" w:right=\"" + std::to_wstring(Transform::HWPUINT2Twips(pPage->GetMarginRight())) + L"\" w:bottom=\"" + + std::to_wstring(Transform::HWPUINT2Twips(pPage->GetMarginBottom())) + L"\" w:left=\"" + std::to_wstring(Transform::HWPUINT2Twips(pPage->GetMarginRight())) + L"\" w:header=\"" + + std::to_wstring(Transform::HWPUINT2Twips(pPage->GetMarginHeader())) + L"\" w:footer=\"" + std::to_wstring(Transform::HWPUINT2Twips(pPage->GetMarginFooter())) + L"\" w:gutter=\"" + + std::to_wstring(Transform::HWPUINT2Twips(pPage->GetMarginGutter())) + L"\"/>"); + } + + if (nullptr != oState.m_pColumnDef && 1 < oState.m_pColumnDef->GetColCount()) + { + //TODO:: Добавить поддержку остальный свойств + m_oDocXml.WriteString(L"GetColCount()) + L"\" w:space=\"454\""); + + if (ELineStyle2::NONE != oState.m_pColumnDef->GetColLineStyle()) + m_oDocXml.WriteString(L" w:sep=\"true\""); + + m_oDocXml.WriteString(L"/>"); + } + else + m_oDocXml.WriteString(L""); + + m_oDocXml.WriteString(L""); +} + +void CConverter2OOXML::WritePicture(const CCtrlShapePic* pCtrlPic, short shParaShapeId, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState) +{ + if (nullptr == pCtrlPic) + return; + + HWP_STRING sPictureID = SavePicture(pCtrlPic->GetBinDataID()); + + if (sPictureID.empty()) + return; + + ++m_ushShapeCount; + + WriteCaption((const CCtrlCommon*)pCtrlPic, oBuilder, oState); + + OpenParagraph(shParaShapeId, oBuilder, oState); + + oBuilder.WriteString(L""); + + OpenDrawingNode(pCtrlPic, oBuilder); + + oBuilder.WriteString(L""); + oBuilder.WriteString(L""); + oBuilder.WriteString(L""); + oBuilder.WriteString(L""); + oBuilder.WriteString(L""); + oBuilder.WriteString(L""); + oBuilder.WriteString(L"GetFinalWidth())) + L"\" cy=\"" + std::to_wstring(Transform::HWPUINT2OOXML(pCtrlPic->GetFinalHeight())) + L"\"/>"); + oBuilder.WriteString(L""); + WriteBorderSettings(pCtrlPic, oBuilder); + oBuilder.WriteString(L""); + CloseDrawingNode(pCtrlPic, oBuilder); + oBuilder.WriteString(L""); +} + +void CConverter2OOXML::WriteVideo(const CCtrlShapeVideo* pCtrlVideo, short shParaShapeId, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState) +{ + if (nullptr == pCtrlVideo || 1 != pCtrlVideo->GetVideoType()) + return; + + HWP_STRING sPictureID = SavePicture(pCtrlVideo->GetThumnailBinID()); + + if (sPictureID.empty()) + return; + + ++m_ushShapeCount; + + WriteCaption((const CCtrlCommon*)pCtrlVideo, oBuilder, oState); + + OpenParagraph(shParaShapeId, oBuilder, oState); + + oBuilder.WriteString(L""); + + OpenDrawingNode(pCtrlVideo, oBuilder); + + oBuilder.WriteString(L""); + oBuilder.WriteString(L""); + oBuilder.WriteString(L""); + oBuilder.WriteString(L"GetDesc() + L"\">"); + oBuilder.WriteString(L"GetWebUrl()) + L"\"/>"); + oBuilder.WriteString(L""); + oBuilder.WriteString(L""); + oBuilder.WriteString(L""); + + const int nIFrameWidth = (int)((double)Transform::HWPUINT2OOXML(pCtrlVideo->GetWidth()) / 22860.); + const int nIFrameHeight = (int)((double)Transform::HWPUINT2OOXML(pCtrlVideo->GetHeight()) / 22860.); + + oBuilder.WriteString(L""); + oBuilder.WriteString(L"GetWebUrl() + L"\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen=\"\" title=\"\" sandbox=\"allow-scripts allow-same-origin allow-popups\">"); + oBuilder.WriteString(L"\" h=\"" + std::to_wstring(nIFrameWidth) + L"\" w=\"" + std::to_wstring(nIFrameHeight) + L"\"/>"); + + oBuilder.WriteString(L""); + oBuilder.WriteString(L"GetFinalWidth())) + L"\" cy=\"" + std::to_wstring(Transform::HWPUINT2OOXML(pCtrlVideo->GetFinalHeight())) + L"\"/>"); + oBuilder.WriteString(L""); + + CloseDrawingNode(pCtrlVideo, oBuilder); + oBuilder.WriteString(L""); +} + +bool CConverter2OOXML::SaveSVGFile(const HWP_STRING& sSVG, HWP_STRING& sFileName) +{ + if (sSVG.empty()) + return false; + + NSFonts::IApplicationFonts* pFonts = NSFonts::NSApplication::Create(); + pFonts->Initialize(); + + MetaFile::IMetaFile* pSvgReader = MetaFile::Create(pFonts); + + if (!pSvgReader->LoadFromString(sSVG)) + { + RELEASEINTERFACE(pSvgReader); + RELEASEINTERFACE(pFonts); + return false; + } + + NSGraphics::IGraphicsRenderer* pGrRenderer = NSGraphics::Create(); + pGrRenderer->SetFontManager(pSvgReader->get_FontManager()); + + double dX, dY, dW, dH; + pSvgReader->GetBounds(&dX, &dY, &dW, &dH); + + if (dW < 0) dW = -dW; + if (dH < 0) dH = -dH; + + double dOneMaxSize = (double)1000.; + + if (dW > dH && dW > dOneMaxSize) + { + dH *= (dOneMaxSize / dW); + dW = dOneMaxSize; + } + else if (dH > dW && dH > dOneMaxSize) + { + dW *= (dOneMaxSize / dH); + dH = dOneMaxSize; + } + + int nWidth = static_cast(dW + 0.5); + int nHeight = static_cast(dH + 0.5); + + double dWidth = 25.4 * nWidth / 96; + double dHeight = 25.4 * nHeight / 96; + + unsigned char* pBgraData = (unsigned char*)malloc(nWidth * nHeight * 4); + if (!pBgraData) + { + double dKoef = 2000.0 / (nWidth > nHeight ? nWidth : nHeight); + + nWidth = (int)(dKoef * nWidth); + nHeight = (int)(dKoef * nHeight); + + dWidth = 25.4 * nWidth / 96; + dHeight = 25.4 * nHeight / 96; + + pBgraData = (unsigned char*)malloc(nWidth * nHeight * 4); + } + + if (!pBgraData) + return false; + + unsigned int alfa = 0xffffff; + //дефолтный тон должен быть прозрачным, а не белым + //memset(pBgraData, 0xff, nWidth * nHeight * 4); + for (int i = 0; i < nWidth * nHeight; i++) + { + ((unsigned int*)pBgraData)[i] = alfa; + } + + CBgraFrame oFrame; + oFrame.put_Data(pBgraData); + oFrame.put_Width(nWidth); + oFrame.put_Height(nHeight); + oFrame.put_Stride(-4 * nWidth); + + pGrRenderer->CreateFromBgraFrame(&oFrame); + pGrRenderer->SetSwapRGB(false); + pGrRenderer->put_Width(dWidth); + pGrRenderer->put_Height(dHeight); + + pSvgReader->SetTempDirectory(m_sTempDirectory); + pSvgReader->DrawOnRenderer(pGrRenderer, 0, 0, dWidth, dHeight); + + sFileName = sFileName.substr(0, sFileName.find(L'.')); + sFileName += L".png"; + + oFrame.SaveFile(m_sTempDirectory + L"/word/media/" + sFileName, 4); + oFrame.put_Data(NULL); + + RELEASEINTERFACE(pGrRenderer); + + if (pBgraData) + free(pBgraData); + + RELEASEINTERFACE(pSvgReader); + RELEASEINTERFACE(pFonts); + + return true; +} + +HWP_STRING CConverter2OOXML::SavePicture(const HWP_STRING& sBinItemId) +{ + if (nullptr == m_pContext) + return HWP_STRING(); + + //TODO:: добавить поддержку устновки размеров изображения из свойств шейпа + CHWPStream oBuffer; + HWP_STRING sFileName; + + if (!m_pContext->GetBinBytes(sBinItemId, oBuffer, sFileName)) + return HWP_STRING(); + + oBuffer.MoveToStart(); + + if (IsRasterFormat(NSFile::GetFileExtention(sFileName))) + { + NSFile::CFileBinary oFile; + oFile.CreateFileW(m_sTempDirectory + L"/word/media/" + sFileName); + if (!oFile.WriteFile((unsigned char*)oBuffer.GetCurPtr(), oBuffer.GetSize())) + { + oFile.CloseFile(); + return HWP_STRING(); + } + oFile.CloseFile(); + } + else if (L"svg" == NSFile::GetFileExtention(sFileName)) + { + std::string sSVG(oBuffer.GetCurPtr(), oBuffer.GetSize()); + if (!SaveSVGFile(UTF8_TO_U(sSVG), sFileName)) + return HWP_STRING(); + } + + AddContentType(L"media/" + sFileName, L"image/" + NSFile::GetFileExtention(sFileName)); + return AddRelationship(L"image", L"media/" + sFileName); +} + +HWP_STRING ConvertIntRgbToStr(const THWPColor& oCurrentColor) +{ + std::wstring wsSelectedColor; + double dMinDistance = DBL_MAX; + double dDistance; + + for (const std::pair& oColor : arHighlightColors) + { + dDistance = sqrt(pow(oCurrentColor.m_uchRed - oColor.first.m_uchRed, 2) + pow(oCurrentColor.m_uchGreen - oColor.first.m_uchGreen, 2) + pow(oCurrentColor.m_uchBlue - oColor.first.m_uchBlue, 2)); + + if (dDistance < dMinDistance) + { + dMinDistance = dDistance; + wsSelectedColor = oColor.second; + } + } + + return wsSelectedColor; +} + +void CConverter2OOXML::WriteRunnerStyle(short shCharShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState, const HWP_STRING& sExternStyles) +{ + if (nullptr == m_pContext) + return; + + const CHWPRecordCharShape* pCharShape = dynamic_cast(m_pContext->GetCharShape(shCharShapeID)); + + if (nullptr == pCharShape) + return; + + oState.m_ushLastCharShapeId = shCharShapeID; + + oBuilder.WriteString(L""); + + HWP_STRING sFontFamily = pCharShape->GetFontName(ELang::LATIN); + HWP_STRING sFontFamilyAsian = pCharShape->GetFontName(ELang::HANGUL); + + if (sFontFamilyAsian.empty() && !sFontFamily.empty()) + sFontFamilyAsian = sFontFamily; + else if (!sFontFamilyAsian.empty() && sFontFamily.empty()) + sFontFamily = sFontFamilyAsian; + + if (!sFontFamily.empty() && !sFontFamilyAsian.empty()) + { + oBuilder.WriteString(L""); + } + + if (pCharShape->Bold()) + oBuilder.WriteString(L""); + + if (pCharShape->Italic()) + oBuilder.WriteString(L""); + + const int nHeight = static_cast(((double)(std::abs)(pCharShape->GetHeight()) * ((double)pCharShape->GetRelSize(ELang::LATIN) / 100.) / 100.) * 2.); + + oBuilder.WriteString(L""); + + oBuilder.WriteString(L"GetTextColor()) + L"\"/>"); + + bool bStrike = false; + + if (pCharShape->Underline()) + { + EUnderline eUnderlineType = pCharShape->GetUnderlineType(); + ELineStyle1 eUnderlineStyle = pCharShape->GetUnderlineStyle(); + + if (EUnderline::BOTTOM == eUnderlineType) + { + oBuilder.WriteString(L"GetUnderlineColor()) + L"\"/>"); + } + else if (EUnderline::CENTER == eUnderlineType) + { + if (eUnderlineStyle == ELineStyle1::DOUBLE_SLIM || + eUnderlineStyle == ELineStyle1::DOUBLE_WAVE) + oBuilder.WriteString(L""); + else + oBuilder.WriteString(L""); + + bStrike = true; + } + } + + if (!bStrike && pCharShape->StrikeOut()) + oBuilder.WriteString(L""); + + //TODO:: на данный момент вычисляется не правильно. Необходимо более точно разобраться + // double dSpacing = ((double)pCharShape->GetHeight() / 100.) * ((double)pCharShape->GetSpacing(ELang::HANGUL) / 100) * 0.8 + 0.4; + // dSpacing *= 20; // pt to twips (20 = 1440 / 72) + + // oBuilder.WriteString(L""); + + if (nullptr != oState.m_pHighlightColor) + oBuilder.WriteString(L""); + + WriteTextBorderStyle(pCharShape->GetBorderFillID(), oBuilder, oState); + + oBuilder.WriteString(sExternStyles); + + oBuilder.WriteString(L""); + + switch(oState.m_eBreakType) + { + case TConversionState::EBreakType::Page: + oBuilder.WriteString(L""); break; + case TConversionState::EBreakType::Column: + oBuilder.WriteString(L""); break; + case TConversionState::EBreakType::TextWrapping: + oBuilder.WriteString(L""); break; + case TConversionState::EBreakType::None: + break; + } + + oState.m_eBreakType = TConversionState::EBreakType::None; +} + +void CConverter2OOXML::WriteTextBorderStyle(short shBorderFillId, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState) +{ + const CHWPRecordBorderFill* pBorderFill = dynamic_cast(m_pContext->GetBorderFill(shBorderFillId)); + + if (nullptr == pBorderFill) + return; + + TBorder oBorder{pBorderFill->GetLeftBorder()}; + + if (ELineStyle2::NONE == oBorder.m_eStyle) + return; + + WriteBorder(pBorderFill->GetLeftBorder(), L"bdr", oBuilder); +} + +void CConverter2OOXML::OpenDrawingNode(const CCtrlCommon* pCtrlShape, NSStringUtils::CStringBuilder& oBuilder) +{ + if (nullptr == pCtrlShape) + return; + + oBuilder.WriteString(L""); + + if (pCtrlShape->GetTreatAsChar()) + { + oBuilder.WriteString(L"GetTopMargin() / 10)) + + L"\" distB=\"" + std::to_wstring(Transform::HWPUINT2OOXML(pCtrlShape->GetBottomMargin() / 10)) + + L"\" distL=\"" + std::to_wstring(Transform::HWPUINT2OOXML(pCtrlShape->GetLeftMargin() / 10)) + + L"\" distR=\"" + std::to_wstring(Transform::HWPUINT2OOXML(pCtrlShape->GetRightMargin() / 10)) + + L"\">"); + + WriteShapeExtent(pCtrlShape, oBuilder); + } + else + { + oBuilder.WriteString(L"GetTextWrap() ? L"1" : L"0")) + + L"\" relativeHeight=\"" + std::to_wstring(pCtrlShape->GetZOrder()) + + L"\" distT=\"" + std::to_wstring(Transform::HWPUINT2OOXML(pCtrlShape->GetTopMargin() / 10)) + + L"\" distB=\"" + std::to_wstring(Transform::HWPUINT2OOXML(pCtrlShape->GetBottomMargin() / 10)) + + L"\" distL=\"" + std::to_wstring(Transform::HWPUINT2OOXML(pCtrlShape->GetLeftMargin() / 10)) + + L"\" distR=\"" + std::to_wstring(Transform::HWPUINT2OOXML(pCtrlShape->GetRightMargin() / 10)) + + L"\" simplePos=\"0\" locked=\"0\" layoutInCell=\"1\" allowOverlap=\"1\">"); + + WriteShapePosition(pCtrlShape, oBuilder); + WriteShapeExtent(pCtrlShape, oBuilder); + WriteShapeWrapMode(pCtrlShape, oBuilder); + } + + WriteShapeProperty(pCtrlShape, oBuilder); +} + +void CConverter2OOXML::CloseDrawingNode(const CCtrlCommon* pCtrlShape, NSStringUtils::CStringBuilder& oBuilder) +{ + if (nullptr == pCtrlShape) + return; + + if (pCtrlShape->GetTreatAsChar()) + oBuilder.WriteString(L""); + else + { + oBuilder.WriteString(L"00"); + oBuilder.WriteString(L""); + } + + oBuilder.WriteString(L""); +} + +HWP_STRING GetVRelativeFrom(EVRelTo eRelTo) +{ + switch (eRelTo) + { + case EVRelTo::PARA: + return L"paragraph"; + case EVRelTo::PAPER: + case EVRelTo::PAGE: + return L"page"; + } +} + +HWP_STRING GetHRelativeFrom(EHRelTo eRelTo) +{ + switch (eRelTo) + { + case EHRelTo::PAPER: + case EHRelTo::PAGE: + return L"page"; + case EHRelTo::COLUMN: + return L"column"; + case EHRelTo::PARA: + return L"character"; + } +} + +void CConverter2OOXML::WriteShapeProperty(const CCtrlCommon* pCtrlShape, NSStringUtils::CStringBuilder& oBuilder) +{ + if (nullptr == pCtrlShape) + return; + + oBuilder.WriteString(L"GetDesc()); + oBuilder.WriteString(L"\"/>"); + oBuilder.WriteString(L""); +} + +void CConverter2OOXML::WriteShapePosition(const CCtrlCommon* pCtrlShape, NSStringUtils::CStringBuilder& oBuilder) +{ + if (nullptr == pCtrlShape) + return; + + oBuilder.WriteString(L""); + oBuilder.WriteString(L"GetHorzRelTo()) + L"\">" + std::to_wstring(Transform::HWPUINT2OOXML(pCtrlShape->GetHorzOffset())) + L""); + oBuilder.WriteString(L"GetVertRelTo()) + L"\">" + std::to_wstring(Transform::HWPUINT2OOXML(pCtrlShape->GetVertOffset())) + L""); +} + +void CConverter2OOXML::WriteShapeExtent(const CCtrlCommon* pCtrlShape, NSStringUtils::CStringBuilder& oBuilder) +{ + if (nullptr == pCtrlShape) + return; + + oBuilder.WriteString(L"GetWidth())) + L"\" cy=\"" + std::to_wstring(Transform::HWPUINT2OOXML(pCtrlShape->GetHeight())) + L"\"/>"); + oBuilder.WriteString(L""); +} + +void CConverter2OOXML::WriteShapeWrapMode(const CCtrlCommon* pCtrlShape, NSStringUtils::CStringBuilder& oBuilder) +{ + if (nullptr == pCtrlShape) + return; + + switch (pCtrlShape->GetTextWrap()) + { + case ETextWrap::SQUARE: + { + oBuilder.WriteString(L"GetTextFlow()) + { + case 0x0: default: oBuilder.WriteString(L"bothSides"); break; + case 0x1: oBuilder.WriteString(L"left"); break; + case 0x2: oBuilder.WriteString(L"right"); break; + case 0x3: oBuilder.WriteString(L"largest"); break; + } + oBuilder.WriteString(L"\"/>"); + break; + } + case ETextWrap::TOP_AND_BOTTOM: + { + oBuilder.WriteString(L""); + break; + } + case ETextWrap::BEHIND_TEXT: + case ETextWrap::IN_FRONT_OF_TEXT: + { + oBuilder.WriteString(L""); + break; + } + } +} + +void CConverter2OOXML::OpenParagraph(short shParaShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState) +{ + if (oState.m_bOpenedP) + return; + + oBuilder.WriteString(L""); + oState.m_bOpenedP = true; + WriteParagraphProperties(shParaShapeID, oBuilder, oState); +} + +void CConverter2OOXML::CloseParagraph(NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState) +{ + if (!oState.m_bOpenedP) + return; + + oBuilder.WriteString(L""); + oState.m_bOpenedP = false; +} + +void CConverter2OOXML::WriteText(const CParaText* pParaText, const std::vector& arRangeTags, short shParaShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState) +{ + if (nullptr == pParaText) + return; + + if (arRangeTags.empty()) + { + WriteText(pParaText->GetText(), shParaShapeID, pParaText->GetCharShapeID(), oBuilder, oState); + return; + } + + HWP_STRING wsText = pParaText->GetText(); + int nParaTextPosition = pParaText->GetStartIDx(); + int unStartText = 0; + + for (size_t unTextPosition = 0; unTextPosition < wsText.length(); ++unTextPosition) + { + for (const TRangeTag& oRangeTag : arRangeTags) + { + if (unTextPosition + nParaTextPosition == oRangeTag.m_nStartPos) + { + WriteText(wsText.substr(unStartText, unTextPosition - unStartText), shParaShapeID, pParaText->GetCharShapeID(), oBuilder, oState); + unStartText = unTextPosition; + + switch (oRangeTag.m_chType) + { + case 0x02: //highlight + { + oState.m_pHighlightColor = new THWPColor{(unsigned char)oRangeTag.m_arData[0], (unsigned char)oRangeTag.m_arData[1], (unsigned char)oRangeTag.m_arData[2]}; + break; + } + default: + break; + } + } + else if (unTextPosition + nParaTextPosition == oRangeTag.m_nEndPos) + { + WriteText(wsText.substr(unStartText, unTextPosition - unStartText), shParaShapeID, pParaText->GetCharShapeID(), oBuilder, oState); + unStartText = unTextPosition; + + switch (oRangeTag.m_chType) + { + case 0x02: //highlight + { + if (nullptr != oState.m_pHighlightColor) + { + delete oState.m_pHighlightColor; + oState.m_pHighlightColor = nullptr; + } + break; + } + default: + break; + } + } + } + } + + if (unStartText < wsText.length()) + WriteText(wsText.substr(unStartText), shParaShapeID, pParaText->GetCharShapeID(), oBuilder, oState); +} + +std::vector SplitText(const std::wstring& wsText) +{ + if (wsText.empty()) + return std::vector{L""}; + + std::vector arTexts; + + std::wstring wsCurrentText; + bool bWasLetter = iswalpha(wsText[0]); + wsCurrentText.push_back(wsText[0]); + + for (unsigned int unIndex = 1; unIndex < wsText.length(); ++unIndex) + { + bool bCurrentIsLetter = iswalnum(wsText[unIndex]); + + if (bCurrentIsLetter != bWasLetter) + { + arTexts.push_back(wsCurrentText); + wsCurrentText.clear(); + bWasLetter = bCurrentIsLetter; + } + + wsCurrentText.push_back(wsText[unIndex]); + } + + if (!wsCurrentText.empty()) + arTexts.push_back(wsCurrentText); + + return arTexts; +} + +void CConverter2OOXML::WriteText(const HWP_STRING& wsText, short shParaShapeID, short shCharShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState) +{ + OpenParagraph(shParaShapeID, oBuilder, oState); + + if (wsText.empty()) + { + oBuilder.WriteString(L""); + WriteRunnerStyle(shCharShapeID, oBuilder, oState); + oBuilder.WriteString(L""); + return; + } + + oBuilder.WriteString(L""); + + WriteRunnerStyle(shCharShapeID, oBuilder, oState); + + oBuilder.WriteString(L""); + else + oBuilder.WriteString(L">"); + + if (bNeedAddSpace) + oBuilder.WriteString(L" "); + + oBuilder.WriteEncodeXmlString(wsText); + oBuilder.WriteString(L""); + + return; + + for (const std::wstring& wsTextElement : SplitText(wsText)) + { + oBuilder.WriteString(L""); + + WriteRunnerStyle(shCharShapeID, oBuilder, oState); + + if (!wsTextElement.empty()) + { + oBuilder.WriteString(L""); + + oBuilder.WriteEncodeXmlString(wsTextElement); + oBuilder.WriteString(L""); + } + + oBuilder.WriteString(L""); + } +} + +void CConverter2OOXML::WriteLineSettings(const CCtrlGeneralShape* pCtrlGeneralShape, NSStringUtils::CStringBuilder& oBuilder) +{ + if (nullptr == pCtrlGeneralShape) + return; + + WriteLineSettings(pCtrlGeneralShape->GetLineStyle(), pCtrlGeneralShape->GetLineColor(), pCtrlGeneralShape->GetLineThick(), 1, oBuilder); +} + +void CConverter2OOXML::WriteLineSettings(ELineStyle2 eLineStyle, int nColor, int nThick, HWP_BYTE nCompoundLineType, NSStringUtils::CStringBuilder& oBuilder) +{ + if (ELineStyle2::NONE == eLineStyle) + { + oBuilder.WriteString(L""); + return; + } + + if (0 == nThick) + nThick = 100; + + oBuilder.WriteString(L""); + + oBuilder.WriteString(L""); + + switch (eLineStyle) + { + case ELineStyle2::DASH: + { + oBuilder.WriteString(L""); + break; + } + case ELineStyle2::DOT: + { + oBuilder.WriteString(L""); + break; + } + case ELineStyle2::DASH_DOT: + { + oBuilder.WriteString(L""); + break; + } + case ELineStyle2::DASH_DOT_DOT: + { + oBuilder.WriteString(L""); + break; + } + case ELineStyle2::LONG_DASH: + { + oBuilder.WriteString(L""); + break; + } + case ELineStyle2::CIRCLE: + { + oBuilder.WriteString(L""); + break; + } + default: + break; + } + + switch (nCompoundLineType) + { + case 0x00: + { + oBuilder.WriteString(L""); + break; + } + case 0x01: + { + oBuilder.WriteString(L""); + break; + } + } + + oBuilder.WriteString(L""); +} + +void CConverter2OOXML::WriteBorderSettings(const CCtrlShapePic* pCtrlPic, NSStringUtils::CStringBuilder& oBuilder) +{ + if (nullptr == pCtrlPic) + return; + + WriteLineSettings(pCtrlPic->GetBorderLineStyle(), pCtrlPic->GetBorderColor(), pCtrlPic->GetBorderThick(), pCtrlPic->GetBorderCompoundLineType(), oBuilder); +} + +void CConverter2OOXML::WriteAutoNumber(const CCtrlAutoNumber* pAutoNumber,short shParaShapeID, short shCharShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState) +{ + if (nullptr == pAutoNumber) + return; + + unsigned short ushValue = 0; + HWP_STRING wsType; + + //TODO:: лучше перейти не на ручной подсчет, а на автоматический в word (но там есть свои проблемы) + switch (pAutoNumber->GetNumType()) + { + case ENumType::PAGE: + { + OpenParagraph(shParaShapeID, oBuilder, oState); + oBuilder.WriteString(L"1"); + return; + } + case ENumType::TOTAL_PAGE: + ushValue = m_ushPageCount; break; + case ENumType::FOOTNOTE: + { + OpenParagraph(shParaShapeID, oBuilder, oState); + oBuilder.WriteString(L""); + WriteRunnerStyle(shCharShapeID, oBuilder, oState, L""); + oBuilder.WriteString(L""); + return; + } + case ENumType::ENDNOTE: + { + OpenParagraph(shParaShapeID, oBuilder, oState); + oBuilder.WriteString(L""); + WriteRunnerStyle(shCharShapeID, oBuilder, oState, L""); + oBuilder.WriteString(L""); + return; + } + case ENumType::FIGURE: + { + wsType = L"Figure"; + ushValue = m_ushShapeCount; break; + } + case ENumType::TABLE: + { + wsType = L"Table"; + ushValue = m_ushTableCount; break; + } + case ENumType::EQUATION: + { + wsType = L"Equation"; + ushValue = m_ushEquationCount; break; + } + } + + if (0 == ushValue) + return; + + if (!wsType.empty()) + oBuilder.WriteString(L""); + + WriteText(std::to_wstring(ushValue), shParaShapeID, shCharShapeID, oBuilder, oState); + + if (!wsType.empty()) + oBuilder.WriteString(L""); +} + +HWP_STRING CConverter2OOXML::AddRelationship(const HWP_STRING& wsType, const HWP_STRING& wsTarget) +{ + if (wsType.empty() || wsTarget.empty()) + return HWP_STRING(); + + VECTOR::const_iterator itFound = std::find_if(m_arRelationships.cbegin(), m_arRelationships.cend(), [wsTarget](const TRelationship& oRelationship){ return wsTarget == oRelationship.m_wsTarget; }); + + if (m_arRelationships.cend() != itFound) + return itFound->m_wsID; + + if (L"hyperlink" == wsType) + { + NSStringUtils::CStringBuilder oBuilder; + oBuilder.WriteEncodeXmlString(wsTarget); + + m_arRelationships.push_back({L"rId" + std::to_wstring(m_arRelationships.size() + 1), wsType, oBuilder.GetData()}); + } + else + m_arRelationships.push_back({L"rId" + std::to_wstring(m_arRelationships.size() + 1), wsType, wsTarget}); + + return m_arRelationships.back().m_wsID; +} + +void CConverter2OOXML::AddContentType(const HWP_STRING& wsName, const HWP_STRING& wsType) +{ + if (wsName.empty() || wsType.empty()) + return; + + VECTOR::const_iterator itFound = std::find_if(m_arContentTypes.cbegin(), m_arContentTypes.cend(), [wsName](const TContentType& oContentType){ return wsName == oContentType.m_wsName; }); + + if (m_arContentTypes.cend() != itFound) + return; + + AddDefaultContentType(NSFile::GetFileExtention(wsName)); + + m_arContentTypes.push_back({wsName, wsType}); +} + +void CConverter2OOXML::AddDefaultContentType(const HWP_STRING& wsName) +{ + if (wsName.empty()) + return; + + VECTOR::const_iterator itFound = std::find_if(m_arDefaultContentType.cbegin(), m_arDefaultContentType.cend(), [wsName](const TContentType& oContentType){ return wsName == oContentType.m_wsName; }); + + if (m_arDefaultContentType.cend() != itFound) + return; + + if (IsRasterFormat(wsName)) + m_arDefaultContentType.push_back({wsName, L"image/" + wsName}); + else if (L"xml" == wsName) + m_arDefaultContentType.push_back({wsName, L"application/xml"}); +} + +bool CConverter2OOXML::ConvertToFile(const HWP_STRING& sFilePath) +{ + if (nullptr == m_pContext || sFilePath.empty()) + return false; + + CreateEmptyFiles(); + Convert(); + Close(); + + COfficeUtils oZip; + oZip.CompressFileOrDirectory(m_sTempDirectory, sFilePath); + + return true; +} + +bool CConverter2OOXML::ConvertToDir(const HWP_STRING& sDirectoryPath) +{ + if (nullptr == m_pContext || sDirectoryPath.empty()) + return false; + + HWP_STRING sCurrentTempDir{m_sTempDirectory}; + + SetTempDirectory(sDirectoryPath); + + CreateEmptyFiles(); + Convert(); + Close(); + + SetTempDirectory(sCurrentTempDir); + + return true; +} + +HWP_STRING CConverter2OOXML::GetTempDirectory() const +{ + return m_sTempDirectory; +} + +TConversionState::TConversionState() + : m_bOpenedP(false), m_bOpenedR(false), m_bIsNote(false), m_bInTextBox(false), m_ushLastCharShapeId(-1), m_ushSecdIndex(0), m_unParaIndex(0), m_pHighlightColor(nullptr), + m_pSectionDef(nullptr), m_pColumnDef(nullptr), m_eBreakType(EBreakType::None) +{} + +} diff --git a/HwpFile/HwpDoc/Conversion/Converter2OOXML.h b/HwpFile/HwpDoc/Conversion/Converter2OOXML.h new file mode 100644 index 00000000000..29f28b62390 --- /dev/null +++ b/HwpFile/HwpDoc/Conversion/Converter2OOXML.h @@ -0,0 +1,189 @@ +#ifndef CONVERTER2OOXML_H +#define CONVERTER2OOXML_H + +#include "../../../DesktopEditor/common/StringBuilder.h" + +#include "../Paragraph/CtrlField.h" +#include "../Paragraph/CtrlAutoNumber.h" +#include "../Paragraph/CtrlSectionDef.h" +#include "../Paragraph/CtrlShapeVideo.h" +#include "../Paragraph/CtrlCharacter.h" +#include "../Paragraph/CtrlColumnDef.h" +#include "../Paragraph/CtrlShapePic.h" +#include "../Paragraph/CtrlShapeOle.h" +#include "../Paragraph/CtrlEqEdit.h" +#include "../Paragraph/CtrlTable.h" +#include "../Paragraph/CtrlNote.h" +#include "../Paragraph/ParaText.h" + +#include "../Paragraph/TblCell.h" + +#include "FootnoteConverter.h" +#include "OleConverter.h" +#include "NumberingConverter.h" + +#include "../Common/WriterContext.h" + +namespace HWP +{ +struct THWPColor +{ + BYTE m_uchRed; + BYTE m_uchGreen; + BYTE m_uchBlue; +}; + +struct TConversionState +{ + bool m_bOpenedP; + bool m_bOpenedR; + bool m_bIsNote; + + bool m_bInTextBox; // TODO:: используется, чтобы в wps:txbx не появилась новая фигура (посмотреть этот момент нужно подробнее) + + unsigned short m_ushLastCharShapeId; + + unsigned short m_ushSecdIndex; + unsigned int m_unParaIndex; + + THWPColor *m_pHighlightColor; + + VECTOR m_arCtrlsHeadFoot; //only for hwpx + std::stack m_arOpenedBookmarks; + + const CCtrlSectionDef* m_pSectionDef; + const CCtrlColumnDef* m_pColumnDef; + + enum class EBreakType + { + Page, + Column, + TextWrapping, + None + } m_eBreakType; + + std::map m_mOpenField; + + TConversionState(); +}; + +struct TRelationship +{ + HWP_STRING m_wsID; + HWP_STRING m_wsType; + HWP_STRING m_wsTarget; +}; + +struct TContentType +{ + HWP_STRING m_wsName; + HWP_STRING m_wsType; +}; + +enum class ECellCreator +{ + FILE, + EMPTY, + NOT_CREATED +}; + +class CConverter2OOXML +{ + CWriterContext * m_pContext; + HWP_STRING m_sTempDirectory; + + NSStringUtils::CStringBuilder m_oStylesXml; // styles.xml + NSStringUtils::CStringBuilder m_oDocXml; // document.xml + NSStringUtils::CStringBuilder m_oNoteXmlRels; // footnotes.xml.rels + NSStringUtils::CStringBuilder m_oWebSettings; // webSettings.xml + + VECTOR m_arDefaultContentType; + VECTOR m_arContentTypes; + VECTOR m_arRelationships; + + CNumberingConverter m_oNumberingConverter; + CFootnoteConverter m_oFootnoteConverter; + COleConverter m_oOleConverter; + + unsigned short m_ushShapeCount; + unsigned short m_ushPageCount; + unsigned short m_ushTableCount; + unsigned short m_ushEquationCount; + + unsigned short m_ushBookmarkCount; + + void CreateEmptyFiles(); + void FillDefaultData(); + void Close(); + void Convert(); + + bool IsRasterFormat(const HWP_STRING& sFormat); + + void WriteParagraphProperties(short shParaShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState); + void WriteTable(const CCtrlTable* pTable, short shParaShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState); + void WriteTableProperties(const CCtrlTable* pTable, short shParaShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState); + void WriteCell(const CTblCell* pCell, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState, ECellCreator eCellCreator); + void WriteCellProperties(short shBorderFillID, NSStringUtils::CStringBuilder& oBuilder); + void WriteBorder(const TBorder& oBorder, const HWP_STRING& sBorderName, NSStringUtils::CStringBuilder& oBuilder); + + void WriteGeometryShape(const CCtrlGeneralShape* pGeneralShape, short shParaShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState); + void WriteEqEditShape(const CCtrlEqEdit* pEqEditShape, short shParaShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState); + void WriteOleShape(const CCtrlShapeOle* pOleShape, short shParaShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState); + + void WriteSectionSettings(TConversionState& oState); + void WritePicture(const CCtrlShapePic* pCtrlPic, short shParaShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState); + void WriteVideo(const CCtrlShapeVideo* pCtrlVideo, short shParaShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState); + bool SaveSVGFile(const HWP_STRING& sSVG, HWP_STRING& sFileName); + HWP_STRING SavePicture(const HWP_STRING& sBinItemId); + + void WriteParaShapeProperties(short shParaShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState); + void WriteRunnerStyle(short shCharShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState, const HWP_STRING& sExternStyles = L""); + void WriteTextBorderStyle(short shBorderFillId, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState); + + void OpenDrawingNode(const CCtrlCommon* pCtrlShape, NSStringUtils::CStringBuilder& oBuilder); + void CloseDrawingNode(const CCtrlCommon* pCtrlShape, NSStringUtils::CStringBuilder& oBuilder); + + void WriteShapePosition(const CCtrlCommon* pCtrlShape, NSStringUtils::CStringBuilder& oBuilder); + void WriteShapeExtent(const CCtrlCommon* pCtrlShape, NSStringUtils::CStringBuilder& oBuilder); + void WriteShapeWrapMode(const CCtrlCommon* pCtrlShape, NSStringUtils::CStringBuilder& oBuilder); + void WriteShapeProperty(const CCtrlCommon* pCtrlShape, NSStringUtils::CStringBuilder& oBuilder); + + void OpenParagraph(short shParaShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState); + void CloseParagraph(NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState); + + void WriteText(const CParaText* pParaText, const VECTOR& arRangeTags, short shParaShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState); + void WriteText(const HWP_STRING& wsText, short shParaShapeID, short shCharShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState); + void WriteLineSettings(const CCtrlGeneralShape* pCtrlGeneralShape, NSStringUtils::CStringBuilder& oBuilder); + void WriteLineSettings(ELineStyle2 eLineStyle, int nColor, int nThick, HWP_BYTE nCompoundLineType, NSStringUtils::CStringBuilder& oBuilder); + void WriteBorderSettings(const CCtrlShapePic* pCtrlPic, NSStringUtils::CStringBuilder& oBuilder); + + void WriteAutoNumber(const CCtrlAutoNumber* pAutoNumber, short shParaShapeID, short shCharShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState); + void WriteCharacter(const CCtrlCharacter* pCharacter, short shParaShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState); + void WriteShape(const CCtrlGeneralShape* pShape, short shParaShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState); + + void WriteNote(const CCtrlNote* pNote, short shParaShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState); + + void WriteField(const CCtrlField* pHyperlink, short shParaShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState); + void CloseField(const CCtrlField* pHyperlink, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState); + + void WriteCaption(const CCtrlCommon* pCtrlCommon, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState); + + HWP_STRING AddRelationship(const HWP_STRING& wsType, const HWP_STRING& wsTarget); + void AddContentType(const HWP_STRING& wsName, const HWP_STRING& wsType); + void AddDefaultContentType(const HWP_STRING& wsName); +public: + CConverter2OOXML(); + ~CConverter2OOXML(); + + void WriteParagraph(const CHWPPargraph* pParagraph, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState); + + void SetContext(CWriterContext* pContext); + void SetTempDirectory(const HWP_STRING& sTempDirectory); + bool ConvertToFile(const HWP_STRING& sFilePath); + bool ConvertToDir(const HWP_STRING& sDirectoryPath); + + HWP_STRING GetTempDirectory() const; +}; +} + +#endif // CONVERTER2OOXML_H diff --git a/HwpFile/HwpDoc/Conversion/FootnoteConverter.cpp b/HwpFile/HwpDoc/Conversion/FootnoteConverter.cpp new file mode 100644 index 00000000000..7f0f8460b64 --- /dev/null +++ b/HwpFile/HwpDoc/Conversion/FootnoteConverter.cpp @@ -0,0 +1,150 @@ +#include "FootnoteConverter.h" + +#include "../../../DesktopEditor/common/File.h" + +#include "../Paragraph/CtrlAutoNumber.h" +#include "../Paragraph/ParaText.h" + +#include "Converter2OOXML.h" + +namespace HWP +{ +CFootnoteConverter::CFootnoteConverter() + : m_ushCountFootnotes(0), m_ushCountEndnotes(0), + m_ushHeaderCount(0), m_ushFooterCount(0) +{} + +std::wstring CFootnoteConverter::CreateNote(const CCtrlNote* pNote, CConverter2OOXML& oConverter) +{ + if (nullptr == pNote) + return std::wstring(); + + NSStringUtils::CStringBuilder *pXMLBuilder = &m_oFootnoteXml; + std::wstring wsPrefix = L"foot"; + std::wstring wsIndex; + + if (L" ne" == pNote->GetID()) + { + wsPrefix = L"end"; + pXMLBuilder = &m_oEndnoteXml; + wsIndex = std::to_wstring(++m_ushCountEndnotes); + } + else + wsIndex = std::to_wstring(++m_ushCountFootnotes); + + pXMLBuilder->WriteString(L""); + + TConversionState oState; + oState.m_bIsNote = true; + + for (const CHWPPargraph* pParagraph : pNote->GetParagraphs()) + oConverter.WriteParagraph(pParagraph, *pXMLBuilder, oState); + + pXMLBuilder->WriteString(L""); + + return L""; +} + +std::wstring CFootnoteConverter::CreateHeadOrFoot(const CCtrlHeadFoot* pCtrlHeadFoot, CConverter2OOXML& oConverter) +{ + if (nullptr == pCtrlHeadFoot) + return std::wstring(); + + NSStringUtils::CStringBuilder oNewDocumentBuilder; + + TConversionState oState; + + for (const CHWPPargraph* pParagraphs : pCtrlHeadFoot->GetParagraphs()) + oConverter.WriteParagraph(pParagraphs, oNewDocumentBuilder, oState); + + const std::wstring wsFileName{(pCtrlHeadFoot->IsHeader() ? (L"header" + std::to_wstring(++m_ushHeaderCount)) : (L"footer" + std::to_wstring(++m_ushFooterCount))) + L".xml"}; + + NSFile::CFileBinary oFile; + if (!oFile.CreateFileW(oConverter.GetTempDirectory() + L"/word/" + wsFileName)) + return std::wstring(); + + const std::wstring wsNodeName{pCtrlHeadFoot->IsHeader() ? L"hdr" : L"ftr"}; + + oFile.WriteStringUTF8(L""); + oFile.WriteStringUTF8(oNewDocumentBuilder.GetData()); + oFile.WriteStringUTF8(L""); + + return wsFileName; +} + +bool CFootnoteConverter::SaveToFile(const std::wstring& wsDirectory) +{ + if (0 == m_ushCountFootnotes && 0 == m_ushCountEndnotes && 0 == m_ushFooterCount && 0 == m_ushHeaderCount) + return false; + + NSFile::CFileBinary oFootnoteWriter; + if (!oFootnoteWriter.CreateFileW(wsDirectory + L"footnotes.xml")) + return false; + + NSFile::CFileBinary oEndNotesWriter; + if (!oEndNotesWriter.CreateFile(wsDirectory + L"endnotes.xml")) + return false; + + oFootnoteWriter.WriteStringUTF8(L""); + oFootnoteWriter.WriteStringUTF8(L" "); + oFootnoteWriter.WriteStringUTF8(L""); + oFootnoteWriter.WriteStringUTF8(m_oFootnoteXml.GetData()); + oFootnoteWriter.WriteStringUTF8(L""); + + oFootnoteWriter.CloseFile(); + + oEndNotesWriter.WriteStringUTF8(L""); + oEndNotesWriter.WriteStringUTF8(L""); + oEndNotesWriter.WriteStringUTF8(m_oEndnoteXml.GetData()); + oEndNotesWriter.WriteStringUTF8(L""); + + oEndNotesWriter.CloseFile(); + + return true; +} +} + +unsigned short HWP::CFootnoteConverter::GetFootnoteCount() const +{ + return m_ushCountFootnotes; +} + +unsigned short HWP::CFootnoteConverter::GetEndnoteCount() const +{ + return m_ushCountEndnotes; +} diff --git a/HwpFile/HwpDoc/Conversion/FootnoteConverter.h b/HwpFile/HwpDoc/Conversion/FootnoteConverter.h new file mode 100644 index 00000000000..0f5e45cdb71 --- /dev/null +++ b/HwpFile/HwpDoc/Conversion/FootnoteConverter.h @@ -0,0 +1,35 @@ +#ifndef FOOTNOTECONVERTER_H +#define FOOTNOTECONVERTER_H + +#include "../../../DesktopEditor/common/StringBuilder.h" + +#include "../Paragraph/CtrlNote.h" +#include "../Paragraph/CtrlHeadFoot.h" + +namespace HWP +{ +class CConverter2OOXML; +class CFootnoteConverter +{ + unsigned short m_ushCountFootnotes; + unsigned short m_ushCountEndnotes; + + unsigned short m_ushHeaderCount; + unsigned short m_ushFooterCount; + + NSStringUtils::CStringBuilder m_oFootnoteXml; + NSStringUtils::CStringBuilder m_oEndnoteXml; +public: + CFootnoteConverter(); + + std::wstring CreateNote(const CCtrlNote* pNote, CConverter2OOXML& oConverter); + std::wstring CreateHeadOrFoot(const CCtrlHeadFoot* pCtrlHeadFoot, CConverter2OOXML& oConverter); + + bool SaveToFile(const std::wstring& wsDirectory); + + unsigned short GetFootnoteCount() const; + unsigned short GetEndnoteCount() const; +}; +} + +#endif // FOOTNOTECONVERTER_H diff --git a/HwpFile/HwpDoc/Conversion/NumberingConverter.cpp b/HwpFile/HwpDoc/Conversion/NumberingConverter.cpp new file mode 100644 index 00000000000..c0db760fdd4 --- /dev/null +++ b/HwpFile/HwpDoc/Conversion/NumberingConverter.cpp @@ -0,0 +1,199 @@ +#include "NumberingConverter.h" +#include "../../../DesktopEditor/common/File.h" + +namespace HWP +{ +CNumberingConverter::CNumberingConverter() +{} + +unsigned int CNumberingConverter::GetCountNumbering() const +{ + return m_arUsedNumbering.size(); +} + +std::wstring HeadingTypeToWSTR(EHeadingType eHeadingType) +{ + switch(eHeadingType) + { + case EHeadingType::NONE: return std::wstring(); + case EHeadingType::OUTLINE: return std::wstring(); + case EHeadingType::NUMBER: return std::wstring(L"decimal"); + case EHeadingType::BULLET: return std::wstring(L"bullet"); + } +} + +int CNumberingConverter::CreateNumbering(const CHWPRecordNumbering* pNumbering, EHeadingType eHeadingType) +{ + if (nullptr == pNumbering || eHeadingType == EHeadingType::NONE || EHeadingType::OUTLINE == eHeadingType) + return 0; + + std::vector>::const_iterator itFound = std::find_if(m_arUsedNumbering.cbegin(), m_arUsedNumbering.cend(), + [pNumbering, eHeadingType](const std::pair& oValue) + { return eHeadingType == oValue.first && pNumbering == oValue.second;}); + + if (m_arUsedNumbering.cend() != itFound) + return itFound - m_arUsedNumbering.cbegin() + 1; + + m_arUsedNumbering.push_back(std::make_pair(eHeadingType, pNumbering)); + + m_oNumberXml.WriteString(L""); + + const std::wstring wsNumFormat{HeadingTypeToWSTR(eHeadingType)}; + + std::wstring wsLvlText; + + if (EHeadingType::NUMBER == eHeadingType) + { + for (short shIndex = 0; shIndex < 7; ++shIndex) + { + m_oNumberXml.WriteString(L""); + + m_oNumberXml.WriteString(L"GetStartNumber(shIndex)) + L"\"/>"); + m_oNumberXml.WriteString(L""); + m_oNumberXml.WriteString(L""); + + wsLvlText = pNumbering->GetNumFormat(shIndex); + + if (wsLvlText.empty()) + { + for (short shLvl = 0; shLvl <= shIndex; ++shLvl) + wsLvlText += L'%' + std::to_wstring(shLvl + 1) + L'.'; + } + else + std::replace(wsLvlText.begin(), wsLvlText.end(), L'^', L'%'); + + m_oNumberXml.WriteString(L""); + + m_oNumberXml.WriteString(L"GetAlign(shIndex)) + { + default: + case 0x0: m_oNumberXml.WriteString(L"start"); break; + case 0x1: m_oNumberXml.WriteString(L"center"); break; + case 0x2: m_oNumberXml.WriteString(L"right"); break; + } + m_oNumberXml.WriteString(L"\"/>"); + + m_oNumberXml.WriteString(L""); + } + } + else if (EHeadingType::BULLET == eHeadingType) + { + for (short shIndex = 0; shIndex < 9; ++shIndex) + { + m_oNumberXml.WriteString(L""); + + m_oNumberXml.WriteString(L""); + m_oNumberXml.WriteString(L""); + + m_oNumberXml.WriteString(L"GetAlign(shIndex)) + { + default: + case 0x0: m_oNumberXml.WriteString(L"start"); break; + case 0x1: m_oNumberXml.WriteString(L"center"); break; + case 0x2: m_oNumberXml.WriteString(L"right"); break; + } + m_oNumberXml.WriteString(L"\"/>"); + + switch (shIndex % 3) + { + case 0: + { + m_oNumberXml.WriteString(L""); + m_oNumberXml.WriteString(L""); + break; + } + case 1: + { + m_oNumberXml.WriteString(L""); + m_oNumberXml.WriteString(L""); + break; + } + case 2: + { + m_oNumberXml.WriteString(L""); + m_oNumberXml.WriteString(L""); + break; + } + } + + m_oNumberXml.WriteString(L""); + } + } + + m_oNumberXml.WriteString(L""); + + return m_arUsedNumbering.size(); +} + +bool CNumberingConverter::SaveToFile(const std::wstring& wsDirectory) +{ + if (m_arUsedNumbering.empty()) + return false; + + NSStringUtils::CStringBuilder oNumberingData; + + oNumberingData.WriteString(L""); + oNumberingData.WriteString(L""); + oNumberingData.WriteString(m_oNumberXml.GetData()); + + if (m_arUsedNumbering.empty()) + { + oNumberingData.WriteString(L""); + oNumberingData.WriteString(L""); + oNumberingData.WriteString(L""); + oNumberingData.WriteString(L""); + oNumberingData.WriteString(L""); + oNumberingData.WriteString(L""); + oNumberingData.WriteString(L""); + oNumberingData.WriteString(L""); + oNumberingData.WriteString(L""); + oNumberingData.WriteString(L""); + oNumberingData.WriteString(L""); + oNumberingData.WriteString(L""); + oNumberingData.WriteString(L""); + oNumberingData.WriteString(L""); + oNumberingData.WriteString(L""); + oNumberingData.WriteString(L""); + oNumberingData.WriteString(L""); + oNumberingData.WriteString(L""); + oNumberingData.WriteString(L""); + oNumberingData.WriteString(L""); + oNumberingData.WriteString(L""); + + oNumberingData.WriteString(L""); + } + else + { + for (unsigned short ushIndex = 1; ushIndex <= m_arUsedNumbering.size(); ++ushIndex) + oNumberingData.WriteString(L""); + } + + oNumberingData.WriteString(L""); + + NSFile::CFileBinary oNumberingWriter; + if (!oNumberingWriter.CreateFileW(wsDirectory + L"numbering.xml")) + return false; + + oNumberingWriter.WriteStringUTF8(oNumberingData.GetData()); + oNumberingWriter.CloseFile(); + return true; +} +} diff --git a/HwpFile/HwpDoc/Conversion/NumberingConverter.h b/HwpFile/HwpDoc/Conversion/NumberingConverter.h new file mode 100644 index 00000000000..bee7f33944f --- /dev/null +++ b/HwpFile/HwpDoc/Conversion/NumberingConverter.h @@ -0,0 +1,25 @@ +#ifndef NUMBERINGCONVERTER_H +#define NUMBERINGCONVERTER_H + +#include "../HWPElements/HWPRecordNumbering.h" +#include "../HWPElements/HWPRecordParaShape.h" + +#include "../../../DesktopEditor/common/StringBuilder.h" + +namespace HWP +{ +class CNumberingConverter +{ + NSStringUtils::CStringBuilder m_oNumberXml; + std::vector> m_arUsedNumbering; +public: + CNumberingConverter(); + + unsigned int GetCountNumbering() const; + + int CreateNumbering(const CHWPRecordNumbering* pNumbering, EHeadingType eHeadingType); + bool SaveToFile(const std::wstring& wsDirectory); +}; +} + +#endif // NUMBERINGCONVERTER_H diff --git a/HwpFile/HwpDoc/Conversion/OleConverter.cpp b/HwpFile/HwpDoc/Conversion/OleConverter.cpp new file mode 100644 index 00000000000..fed8215f053 --- /dev/null +++ b/HwpFile/HwpDoc/Conversion/OleConverter.cpp @@ -0,0 +1,135 @@ +#include "OleConverter.h" + +#include "../../../DesktopEditor/common/File.h" +#include "../../../DesktopEditor/common/Directory.h" +#include "../../../DesktopEditor/common/StringBuilder.h" + +namespace HWP +{ +COleConverter::COleConverter() + : m_unCountCharts(0) +{} + +void COleConverter::Clear() +{ + m_unCountCharts = 0; + m_wsTempDir.clear(); +} + +unsigned int COleConverter::GetChartsCount() const +{ + return m_unCountCharts; +} + +void COleConverter::SetTempDir(const std::wstring& wsTempDir) +{ + m_wsTempDir = wsTempDir; +} +void COleConverter::CreateChartData(const std::wstring& wsChartData) +{ + const std::wstring wsPath = m_wsTempDir + FILE_SEPARATOR_STR + L"word" + FILE_SEPARATOR_STR + L"charts" + FILE_SEPARATOR_STR; + + NSFile::CFileBinary oChartFile; + oChartFile.CreateFileW(wsPath + L"chart" + std::to_wstring(m_unCountCharts) + L".xml"); + oChartFile.WriteStringUTF8(wsChartData); + oChartFile.CloseFile(); + + NSStringUtils::CStringBuilder oColorData; + oColorData.WriteString(L""); + oColorData.WriteString(L""); + oColorData.WriteString(L""); + oColorData.WriteString(L""); + oColorData.WriteString(L""); + oColorData.WriteString(L""); + oColorData.WriteString(L""); + + NSFile::CFileBinary oColorFile; + oColorFile.CreateFileW(wsPath + L"colors" + std::to_wstring(m_unCountCharts) + L".xml"); + oColorFile.WriteStringUTF8(oColorData.GetData()); + oColorFile.CloseFile(); + + NSStringUtils::CStringBuilder oStyleData; + oStyleData.WriteString(L""); + oStyleData.WriteString(L""); + oStyleData.WriteString(L""); + oStyleData.WriteString(L""); + oStyleData.WriteString(L""); + oStyleData.WriteString(L""); + oStyleData.WriteString(L""); + oStyleData.WriteString(L""); + oStyleData.WriteString(L""); + oStyleData.WriteString(L""); + oStyleData.WriteString(L""); + oStyleData.WriteString(L""); + oStyleData.WriteString(L""); + oStyleData.WriteString(L""); + oStyleData.WriteString(L""); + oStyleData.WriteString(L""); + oStyleData.WriteString(L""); + oStyleData.WriteString(L""); + oStyleData.WriteString(L""); + oStyleData.WriteString(L""); + oStyleData.WriteString(L""); + oStyleData.WriteString(L""); + oStyleData.WriteString(L""); + oStyleData.WriteString(L""); + oStyleData.WriteString(L""); + oStyleData.WriteString(L""); + oStyleData.WriteString(L""); + oStyleData.WriteString(L""); + oStyleData.WriteString(L""); + oStyleData.WriteString(L""); + oStyleData.WriteString(L""); + oStyleData.WriteString(L""); + oStyleData.WriteString(L""); + + NSFile::CFileBinary oStyleFile; + oStyleFile.CreateFileW(wsPath + L"style" + std::to_wstring(m_unCountCharts) + L".xml"); + oStyleFile.WriteStringUTF8(oStyleData.GetData()); + oStyleFile.CloseFile(); +} + +void COleConverter::CreateChart(CHWPStream& oOleStream) +{ + std::string sData = std::string(oOleStream.GetCurPtr(), oOleStream.GetSize()); + + size_t unBegin = sData.find("", unBegin); + + if (std::string::npos == unEnd) + return; + + const std::string sCharDataA = sData.substr(unBegin, unEnd - unBegin + 15); + const std::wstring wsChartData = UTF8_TO_U(sCharDataA); + + const std::wstring wsPath = m_wsTempDir + FILE_SEPARATOR_STR + L"word" + FILE_SEPARATOR_STR + L"charts"; + + if (!NSDirectory::Exists(wsPath)) + NSDirectory::CreateDirectory(wsPath); + + ++m_unCountCharts; + + CreateChartData(wsChartData); + + const std::wstring wsRelsPath = wsPath + FILE_SEPARATOR_STR + L"_rels"; + + if (!NSDirectory::Exists(wsRelsPath)) + NSDirectory::CreateDirectory(wsRelsPath); + + NSStringUtils::CStringBuilder oRelsData; + oRelsData.WriteString(L""); + oRelsData.WriteString(L""); + oRelsData.WriteString(L""); + oRelsData.WriteString(L""); + oRelsData.WriteString(L""); + + NSFile::CFileBinary oRelsFile; + oRelsFile.CreateFileW(wsRelsPath + FILE_SEPARATOR_STR + L"chart" + std::to_wstring(m_unCountCharts) + L".xml.rels"); + oRelsFile.WriteStringUTF8(oRelsData.GetData()); + oRelsFile.CloseFile(); +} +} diff --git a/HwpFile/HwpDoc/Conversion/OleConverter.h b/HwpFile/HwpDoc/Conversion/OleConverter.h new file mode 100644 index 00000000000..7e241339a78 --- /dev/null +++ b/HwpFile/HwpDoc/Conversion/OleConverter.h @@ -0,0 +1,27 @@ +#ifndef OLECONVERTER_H +#define OLECONVERTER_H + +#include "../HWPStream.h" + +namespace HWP +{ +class COleConverter +{ + unsigned int m_unCountCharts; + std::wstring m_wsTempDir; + + void CreateChartData(const std::wstring& wsChartData); +public: + COleConverter(); + + void Clear(); + + unsigned int GetChartsCount() const; + + void SetTempDir(const std::wstring& wsTempDir); + void CreateChart(CHWPStream& oOleStream); + void CreateRels(); +}; +} + +#endif // OLECONVERTER_H diff --git a/HwpFile/HwpDoc/Conversion/Transform.h b/HwpFile/HwpDoc/Conversion/Transform.h new file mode 100644 index 00000000000..3f83f5ac33c --- /dev/null +++ b/HwpFile/HwpDoc/Conversion/Transform.h @@ -0,0 +1,80 @@ +#ifndef TRANSFORM_H +#define TRANSFORM_H + +#include +#include + +namespace HWP +{ +namespace Transform +{ + inline int HWPINT2OOXML(int nValue) + { + return static_cast((double)nValue * 21000. / 59529.); + } + inline int HWPUINT2OOXML(int nValue) + { + return static_cast((double)nValue * 127.); // 914400. / 7200. = 127 + } + + inline int HWPUINT2Twips(int nValue) + { + return static_cast((double)nValue / 7200. * 1440.); + } + + inline std::wstring IntColorToHEX(int nColor) + { + std::wstringstream oSStream; + + oSStream << std::uppercase << std::hex << std::setw(6) << std::setfill(L'0') << nColor; + + return oSStream.str(); + } + + short LineWidth2Pt(short shHWPThick) + { + //TODO:: проверить + return (short)std::ceil((double)shHWPThick * 4 * 25.4 / 72.); + + switch(shHWPThick) + { + case 0: // 0.1mm + return 10; + case 1: // 0.12mm + return 12; + case 2: // 0.15mm + return 15; + case 3: // 0.2mm + return 20; + case 4: // 0.25mm + return 25; + case 5: // 0.3mm + return 30; + case 6: // 0.4mm + return 40; + case 7: // 0.5mm + return 50; + case 8: // 0.6mm + return 60; + case 9: // 0.7mm + return 70; + case 10: // 1.0mm + return 100; + case 11: // 1.5mm + return 150; + case 12: // 2.0mm + return 200; + case 13: // 3.0mm + return 300; + case 14: // 4.0mm + return 400; + case 15: // 5.0mm + return 500; + default: + return 0; + } + } +} +} + +#endif // TRANSFORM_H diff --git a/HwpFile/HwpDoc/Conversion/Types.h b/HwpFile/HwpDoc/Conversion/Types.h new file mode 100644 index 00000000000..4cc8ffbbbb5 --- /dev/null +++ b/HwpFile/HwpDoc/Conversion/Types.h @@ -0,0 +1,15 @@ +#ifndef TYPES_H +#define TYPES_H + +namespace HWP +{ + struct TBorderLine + { + int m_nColor; + int m_nInnerLineWidth; + int m_nOuterLineWudth; + int nLineDistance; + }; +} + +#endif // TYPES_H diff --git a/HwpFile/HwpDoc/Errors.h b/HwpFile/HwpDoc/Errors.h new file mode 100644 index 00000000000..ec1e57e46cc --- /dev/null +++ b/HwpFile/HwpDoc/Errors.h @@ -0,0 +1,22 @@ +#ifndef ERRORS_H +#define ERRORS_H + +namespace HWP +{ +enum class EErrorsCode +{ + UNDEFINED, + SIGANTURE_NOT_MATCH, + INVALID_MAJORVERSION, + INVALID_MINORVERSION, + INVALID_BYTEORDER, + INVALID_SECTORSHIFT, + INVALID_MINISECTORSHIFT, + INVALID_NUM_DIRECTORYSECTOR, + INVALID_MINI_STREAM_CUTOFF, + FILE_READ_ERROR, + INVALID_ZIP_DATA_FORMAT +}; +} + +#endif // ERRORS_H diff --git a/HwpFile/HwpDoc/HWPDocInfo.cpp b/HwpFile/HwpDoc/HWPDocInfo.cpp new file mode 100644 index 00000000000..cb9cc18366c --- /dev/null +++ b/HwpFile/HwpDoc/HWPDocInfo.cpp @@ -0,0 +1,359 @@ +#include "HWPDocInfo.h" + +#include "HWPElements/HWPRecordBinData.h" +#include "HWPElements/HWPRecordDocumentProperties.h" +#include "HWPElements/HWPRecordIDMaping.h" +#include "HWPElements/HWPRecordFaceName.h" +#include "HWPElements/HWPRecordBorderFill.h" +#include "HWPElements/HWPRecordCharShape.h" +#include "HWPElements/HWPRecordBullet.h" +#include "HWPElements/HWPRecordNumbering.h" +#include "HWPElements/HWPRecordParaShape.h" +#include "HWPElements/HWPRecordStyle.h" +#include "HWPElements/HwpRecordTabDef.h" + +namespace HWP +{ +ECompatDoc GetCompatDoc(int nValue) +{ + switch(static_cast(nValue)) + { + case ECompatDoc::HWP: return ECompatDoc::HWP; + case ECompatDoc::OLD_HWP: return ECompatDoc::OLD_HWP; + case ECompatDoc::MS_WORD: return ECompatDoc::MS_WORD; + default: + return ECompatDoc::UNKNOWN; + } +} + +CHWPDocInfo::CHWPDocInfo(EHanType eHanType) + : m_eHanType(eHanType), m_eCompatibleDoc(ECompatDoc::HWP) +{} + +CHWPDocInfo::CHWPDocInfo(CHWPXFile* pHWPXFile) + : m_eHanType(EHanType::HWPX), m_pParentHWPX(pHWPXFile), m_eCompatibleDoc(ECompatDoc::UNKNOWN) +{} + +CHWPDocInfo::CHWPDocInfo(CHWPFile* pHWPFile) + : m_eHanType(EHanType::HWP), m_pParentHWP(pHWPFile), m_eCompatibleDoc(ECompatDoc::HWP) +{} + +CHWPDocInfo::~CHWPDocInfo() +{ + #define REMOVE_LIST_DATA(array) \ + for (CHWPRecord* pRecord : array) \ + { \ + if (nullptr != pRecord) \ + delete pRecord; \ + } \ + array.clear() \ + + REMOVE_LIST_DATA(m_arRecords); + REMOVE_LIST_DATA(m_arFaseNames); + REMOVE_LIST_DATA(m_arBorderFills); + REMOVE_LIST_DATA(m_arCharShapes); + REMOVE_LIST_DATA(m_arNumberings); + REMOVE_LIST_DATA(m_arBullets); + REMOVE_LIST_DATA(m_arParaShapes); + REMOVE_LIST_DATA(m_arStyles); + REMOVE_LIST_DATA(m_arTabDefs); + + for (const std::pair& oBinData : m_mBinDatas) + { + if (nullptr != oBinData.second) + delete oBinData.second; + } + + m_mBinDatas.clear(); +} + +bool CHWPDocInfo::Parse(CHWPStream& oBuffer, int nVersion) +{ + int nHeader, nTagNum, nLevel, nSize; + + while (oBuffer.CanRead()) + { + oBuffer.ReadInt(nHeader); + nTagNum = nHeader & 0x3FF; // 10 bits (0 - 9 bit) + nLevel = (nHeader & 0xFFC00) >> 10; // 10 bits (10-19 bit) + nSize = (nHeader & 0xFFF00000) >> 20; // 12 bits (20-31 bit) + + if (0xFFF == nSize) + { + //TODO:: buf[off+7]<<24&0xFF000000 | buf[off+6]<<16&0xFF0000 | buf[off+5]<<8&0xFF00 | buf[off+4]&0xFF; + oBuffer.ReadInt(nSize); + } + + CHWPRecord *pRecord = nullptr; + EHWPTag eTag = GetTagFromNum(nTagNum); + + #define CREATE_AND_ADD_RECORD(type_record, array) \ + pRecord = new type_record(*this, nTagNum, nLevel, nSize, oBuffer, 0, nVersion); \ + if (nullptr != pRecord) \ + array.push_back(pRecord) + + oBuffer.SavePosition(); + + switch (eTag) + { + case HWPTAG_DOCUMENT_PROPERTIES: + { + CREATE_AND_ADD_RECORD(CHWPRecordDocumentProperties, m_arRecords); + break; + } + case HWPTAG_ID_MAPPINGS: + { + CREATE_AND_ADD_RECORD(CHWPRecordIDMaping, m_arRecords); + break; + } + case HWPTAG_BIN_DATA: + { + CHWPRecordBinData *pBindData = new CHWPRecordBinData(*this, nTagNum, nLevel, nSize, oBuffer, 0, nVersion); + + if (nullptr != pBindData) + m_mBinDatas.insert(std::make_pair(pBindData->GetItemID(), pBindData)); + + break; + } + case HWPTAG_FACE_NAME: + { + CREATE_AND_ADD_RECORD(CHWPRecordFaceName, m_arFaseNames); + break; + } + case HWPTAG_BORDER_FILL: + { + CREATE_AND_ADD_RECORD(CHWPRecordBorderFill, m_arBorderFills); + break; + } + case HWPTAG_HWP_CHAR_SHAPE: + { + CREATE_AND_ADD_RECORD(CHWPRecordCharShape, m_arCharShapes); + break; + } + case HWPTAG_TAB_DEF: + { + CREATE_AND_ADD_RECORD(CHwpRecordTabDef, m_arTabDefs); + break; + } + case HWPTAG_NUMBERING: + { + CREATE_AND_ADD_RECORD(CHWPRecordNumbering, m_arNumberings); + break; + } + case HWPTAG_BULLET: + { + CREATE_AND_ADD_RECORD(CHWPRecordBullet, m_arBullets); + break; + } + case HWPTAG_PARA_SHAPE: + { + CREATE_AND_ADD_RECORD(CHWPRecordParaShape, m_arParaShapes); + break; + } + case HWPTAG_STYLE: + { + CREATE_AND_ADD_RECORD(CHWPRecordStyle, m_arStyles); + break; + } + case HWPTAG_COMPATIBLE_DOCUMENT: + { + int nCompatDoc; + oBuffer.ReadInt(nCompatDoc); + + m_eCompatibleDoc = GetCompatDoc(nCompatDoc); + break; + } + case HWPTAG_LAYOUT_COMPATIBILITY: + case HWPTAG_DOC_DATA: + case HWPTAG_DISTRIBUTE_DOC_DATA: + case HWPTAG_TRACKCHANGE: + case HWPTAG_MEMO_SHAPE: + case HWPTAG_FORBIDDEN_HWP_CHAR: + case HWPTAG_TRACK_CHANGE: + case HWPTAG_TRACK_CHANGE_AUTHOR: + break; + default: + {} + } + + oBuffer.Skip(nSize - oBuffer.GetDistanceToLastPos(true)); + } + + return true; +} + +bool CHWPDocInfo::Parse(CXMLNode& oNode, int nVersion) +{ + for (CXMLNode& oChild : oNode.GetChilds()) + { + if (L"hh:beginNum" == oChild.GetName()) + m_arRecords.push_back(new CHWPRecordDocumentProperties(*this, oChild, nVersion)); + else if (L"hh:refList" == oChild.GetName()) + ReadRefList(oChild, nVersion); + } + + return true; +} + +bool CHWPDocInfo::ReadRefList(CXMLNode& oNode, int nVersion) +{ + for (CXMLNode& oChild : oNode.GetChilds()) + { + if (L"hh:fontfaces" == oChild.GetName()) + { + for (CXMLNode& oFontFaceNode : oChild.GetChilds(L"hh:fontface")) + for (CXMLNode& oFontNode : oFontFaceNode.GetChilds(L"hh:font")) + m_arFaseNames.push_back(new CHWPRecordFaceName(*this, oFontNode, nVersion)); + } + else if (L"hh:borderFills" == oChild.GetName()) + { + for (CXMLNode& oBorderFillNode : oChild.GetChilds(L"hh:borderFill")) + m_arBorderFills.push_back(new CHWPRecordBorderFill(*this, oBorderFillNode, nVersion)); + } + else if (L"hh:charProperties" == oChild.GetName()) + { + for (CXMLNode& oCharPrNode : oChild.GetChilds(L"hh:charPr")) + m_arCharShapes.push_back(new CHWPRecordCharShape(*this, oCharPrNode, nVersion)); + } + else if (L"hh:tabProperties" == oChild.GetName()) + { + for (CXMLNode& oTabPrNode : oChild.GetChilds(L"hh:tabPr")) + m_arTabDefs.push_back(new CHwpRecordTabDef(*this, oTabPrNode, nVersion)); + } + else if (L"hh:numberings" == oChild.GetName()) + { + for (CXMLNode& oNumberingNode : oChild.GetChilds(L"hh:numbering")) + m_arNumberings.push_back(new CHWPRecordNumbering(*this, oNumberingNode, nVersion)); + } + else if (L"hh:bullets" == oChild.GetName()) + { + for (CXMLNode& oBulletNode : oChild.GetChilds()) + m_arBullets.push_back(new CHWPRecordBullet(*this, oBulletNode, nVersion)); + } + else if (L"hh:paraProperties" == oChild.GetName()) + { + for (CXMLNode& oParaPrNode : oChild.GetChilds(L"hh:paraPr")) + m_arParaShapes.push_back(new CHWPRecordParaShape(*this, oParaPrNode, nVersion)); + } + else if (L"hh:styles" == oChild.GetName()) + { + for (CXMLNode& oStyleNode : oChild.GetChilds(L"hh:style")) + m_arStyles.push_back(new CHWPRecordStyle(*this, oStyleNode, nVersion)); + } + } + + return true; +} + +bool CHWPDocInfo::ReadContentHpf(CXMLNode& oNode, int nVersion) +{ + CHWPRecordBinData *pRecordBinData = nullptr; + + for (CXMLNode& oChild : oNode.GetChilds(L"opf:manifest")) + { + for (CXMLNode& oGrandChild : oChild.GetChilds(L"opf:item")) + { + pRecordBinData = new CHWPRecordBinData(oGrandChild, nVersion); + m_mBinDatas.insert(std::make_pair(pRecordBinData->GetItemID(), (HWP::CHWPRecord*)pRecordBinData)); + } + } + + return true; +} + +#define GET_RECORD(array_records, index) \ + if (array_records.size() <= index || index < 0) \ + return nullptr; \ + return array_records[index] + +const CHWPRecord* CHWPDocInfo::GetRecord(int nIndex) const +{ + GET_RECORD(m_arRecords, nIndex); +} + +const CHWPRecord* CHWPDocInfo::GetFaceName(int nIndex) const +{ + GET_RECORD(m_arFaseNames, nIndex); +} + +const CHWPRecord* CHWPDocInfo::GetBorderFill(int nIndex) const +{ + GET_RECORD(m_arBorderFills, nIndex - 1); +} + +const CHWPRecord* CHWPDocInfo::GetCharShape(int nIndex) const +{ + GET_RECORD(m_arCharShapes, nIndex); +} + +const CHWPRecord* CHWPDocInfo::GetNumbering(int nIndex) const +{ + GET_RECORD(m_arNumberings, nIndex); +} + +const CHWPRecord* CHWPDocInfo::GetBullet(int nIndex) const +{ + GET_RECORD(m_arBullets, nIndex - 1); +} + +const CHWPRecord* CHWPDocInfo::GetParaShape(int nIndex) const +{ + GET_RECORD(m_arParaShapes, nIndex); +} + +const CHWPRecord* CHWPDocInfo::GetStyle(int nIndex) const +{ + GET_RECORD(m_arStyles, nIndex); +} + +const CHWPRecord* CHWPDocInfo::GetTabDef(int nIndex) const +{ + GET_RECORD(m_arTabDefs, nIndex); +} + +CHWPFile* CHWPDocInfo::GetParentHWP() +{ + return m_pParentHWP; +} + +const CHWPRecord* CHWPDocInfo::GetBinData(const HWP_STRING& sID) const +{ + switch (m_eHanType) + { + case EHanType::HWP: + { + short shID = std::stoi(sID) - 1; + + if (shID >= m_mBinDatas.size()) + return nullptr; + + std::map::const_iterator itElement = m_mBinDatas.cbegin(); + + for (unsigned short ushIndex = 0; ushIndex < shID; ++ushIndex) + ++itElement; + + return itElement->second; + } + case EHanType::HWPX: + { + if (m_mBinDatas.end() == m_mBinDatas.find(sID)) + return nullptr; + + return m_mBinDatas.at(sID); + break; + } + default: + return nullptr; + } +} + +EHanType CHWPDocInfo::GetHanType() const +{ + return m_eHanType; +} + +ECompatDoc CHWPDocInfo::GetCompatibleDoc() const +{ + return m_eCompatibleDoc; +} +} diff --git a/HwpFile/HwpDoc/HWPDocInfo.h b/HwpFile/HwpDoc/HWPDocInfo.h new file mode 100644 index 00000000000..5f847179964 --- /dev/null +++ b/HwpFile/HwpDoc/HWPDocInfo.h @@ -0,0 +1,72 @@ +#ifndef HWPDOCINFO_H +#define HWPDOCINFO_H + +#include "HanType.h" +#include "HWPStream.h" +#include "HWPElements/HWPRecord.h" +#include "Common/XMLNode.h" + +#include + +namespace HWP +{ +enum class ECompatDoc +{ + HWP, + OLD_HWP, + MS_WORD, + UNKNOWN +}; + +class CHWPFile; +class CHWPXFile; +class CHWPDocInfo +{ + EHanType m_eHanType; + CHWPXFile *m_pParentHWPX; + CHWPFile *m_pParentHWP; + VECTOR m_arRecords; + + std::map m_mBinDatas; + VECTOR m_arFaseNames; + VECTOR m_arBorderFills; + VECTOR m_arCharShapes; + VECTOR m_arNumberings; + VECTOR m_arBullets; + VECTOR m_arParaShapes; + VECTOR m_arStyles; + VECTOR m_arTabDefs; + + ECompatDoc m_eCompatibleDoc; +public: + CHWPDocInfo(EHanType eHanType); + CHWPDocInfo(CHWPXFile* pHWPXFile); + CHWPDocInfo(CHWPFile* pHWPFile); + + ~CHWPDocInfo(); + + bool Parse(CHWPStream& oBuffer, int nVersion); + bool Parse(CXMLNode& oNode, int nVersion); + bool ReadContentHpf(CXMLNode& oNode, int nVersion); + + const CHWPRecord* GetRecord(int nIndex) const; + const CHWPRecord* GetFaceName(int nIndex) const; + const CHWPRecord* GetBorderFill(int nIndex) const; + const CHWPRecord* GetCharShape(int nIndex) const; + const CHWPRecord* GetNumbering(int nIndex) const; + const CHWPRecord* GetBullet(int nIndex) const; + const CHWPRecord* GetParaShape(int nIndex) const; + const CHWPRecord* GetStyle(int nIndex) const; + const CHWPRecord* GetTabDef(int nIndex) const; + + CHWPFile* GetParentHWP(); + + const CHWPRecord* GetBinData(const HWP_STRING& sID) const; + EHanType GetHanType() const; + ECompatDoc GetCompatibleDoc() const; +private: + bool ReadRefList(CXMLNode& oNode, int nVersion); +}; +} + +#endif // HWPDOCINFO_H diff --git a/HwpFile/HwpDoc/HWPElements/HWPRecord.cpp b/HwpFile/HwpDoc/HWPElements/HWPRecord.cpp new file mode 100644 index 00000000000..473c0de7d45 --- /dev/null +++ b/HwpFile/HwpDoc/HWPElements/HWPRecord.cpp @@ -0,0 +1,17 @@ +#include "HWPRecord.h" + +namespace HWP +{ +CHWPRecord::CHWPRecord(int nTagNum, int nLevel, int nSize) + : m_nLevel(nLevel), m_nSize(nSize) +{ + m_eTag = GetTagFromNum(nTagNum); +} + +CHWPRecord::CHWPRecord(EHWPTag eTag, int nLevel, int nSize) + : m_eTag(eTag), m_nLevel(nLevel), m_nSize(nSize) +{} + +CHWPRecord::~CHWPRecord() +{} +} diff --git a/HwpFile/HwpDoc/HWPElements/HWPRecord.h b/HwpFile/HwpDoc/HWPElements/HWPRecord.h new file mode 100644 index 00000000000..db189c33215 --- /dev/null +++ b/HwpFile/HwpDoc/HWPElements/HWPRecord.h @@ -0,0 +1,20 @@ +#ifndef HWPRECORD_H +#define HWPRECORD_H + +#include "HWPTag.h" + +namespace HWP +{ +class CHWPRecord +{ + EHWPTag m_eTag; + int m_nLevel; + int m_nSize; +public: + CHWPRecord(int nTagNum, int nLevel, int nSize); + CHWPRecord(EHWPTag eTag, int nLevel, int nSize); + virtual ~CHWPRecord(); +}; +} + +#endif // HWPRECORD_H diff --git a/HwpFile/HwpDoc/HWPElements/HWPRecordBinData.cpp b/HwpFile/HwpDoc/HWPElements/HWPRecordBinData.cpp new file mode 100644 index 00000000000..53ead34f053 --- /dev/null +++ b/HwpFile/HwpDoc/HWPElements/HWPRecordBinData.cpp @@ -0,0 +1,137 @@ +#include "HWPRecordBinData.h" + +#include "../HWPFile.h" + +#include +#include +#include + +namespace HWP +{ +ECompressed GetCompressed(int nValue) +{ + SWITCH(ECompressed, nValue) + { + DEFAULT(ECompressed::FOLLOW_STORAGE); + CASE(ECompressed::COMPRESS); + CASE(ECompressed::NO_COMPRESS); + } +} + +EType GetType(int nValue) +{ + SWITCH(EType, nValue) + { + DEFAULT(EType::LINK); + CASE(EType::EMBEDDING); + CASE(EType::STORAGE); + } +} + + +EState GetState(int nValue) +{ + SWITCH(EState, nValue) + { + DEFAULT(EState::NEVER_ACCESSED); + CASE(EState::FOUND_FILE_BY_ACCESS); + CASE(EState::ACCESS_FAILED); + CASE(EState::LINK_ACCESS_IGNORED); + } +} + +CHWPRecordBinData::CHWPRecordBinData(CHWPDocInfo& oDocInfo, int nTagNum, int nLevel, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) + : CHWPRecord(nTagNum, nLevel, nSize) +{ + oBuffer.SavePosition(); + + short shTypeBits; + oBuffer.ReadShort(shTypeBits); + + m_eType = ::HWP::GetType(shTypeBits & 0x0F); + m_eCompressed = ::HWP::GetCompressed(shTypeBits & 0x30); + m_eState = GetState(shTypeBits & 0x300); + + if (EType::LINK == m_eType) + { + oBuffer.ReadString(m_sAPath, EStringCharacter::UTF16); + oBuffer.ReadString(m_sRPath, EStringCharacter::UTF16); + } + if (EType::EMBEDDING == m_eType || EType::STORAGE == m_eType) + { + oBuffer.ReadShort(m_shBinDataID); + m_sItemID = TO_HWP_STRING(m_shBinDataID); + } + if (EType::EMBEDDING == m_eType || EType::STORAGE == m_eType) + { + oBuffer.ReadString(m_sFormat, EStringCharacter::UTF16); + + std::wostringstream oStringStream; + oStringStream << L"BIN" << std::setw(4) << std::setfill(L'0') << std::hex << m_shBinDataID << L"." << m_sFormat; + m_sAPath = oStringStream.str(); + } + + oBuffer.Skip(nSize - oBuffer.GetDistanceToLastPos(true)); +} + +CHWPRecordBinData::CHWPRecordBinData(CXMLNode& oNode, int nVersion) + : CHWPRecord(EHWPTag::HWPTAG_BIN_DATA, 0, 0) +{ + m_sItemID = oNode.GetAttribute(L"id"); + + HWP_STRING sType = oNode.GetAttribute(L"isEmbeded"); + + if (L"0" == sType) + { + m_eType = EType::LINK; + + m_sAPath = oNode.GetAttribute(L"sub-path"); + + if (m_sAPath.empty()) + m_sAPath = oNode.GetAttribute(L"href"); + } + else if (L"1" == sType) + { + m_eType = EType::EMBEDDING; + m_sAPath = oNode.GetAttribute(L"href"); + } + else + m_sAPath = oNode.GetAttribute(L"href"); + + m_sFormat = oNode.GetAttribute(L"media-type"); + + std::wregex oRegex(L"image/(.*)"); + + m_sFormat = std::regex_replace(m_sFormat, oRegex, L"$1"); +} + +HWP_STRING CHWPRecordBinData::GetPath() const +{ + return m_sAPath; +} + +HWP_STRING CHWPRecordBinData::GetItemID() const +{ + return m_sItemID; +} + +HWP_STRING CHWPRecordBinData::GetFormat() const +{ + return m_sFormat; +} + +EType CHWPRecordBinData::GetType() const +{ + return m_eType; +} + +ECompressed CHWPRecordBinData::GetCompressed() const +{ + return m_eCompressed; +} + +short CHWPRecordBinData::GetBinDataID() const +{ + return m_shBinDataID; +} +} diff --git a/HwpFile/HwpDoc/HWPElements/HWPRecordBinData.h b/HwpFile/HwpDoc/HWPElements/HWPRecordBinData.h new file mode 100644 index 00000000000..c225fa3f170 --- /dev/null +++ b/HwpFile/HwpDoc/HWPElements/HWPRecordBinData.h @@ -0,0 +1,60 @@ +#ifndef HWPRECORDBINDATA_H +#define HWPRECORDBINDATA_H + +#include "HWPRecord.h" +#include "../HWPStream.h" +#include "../HWPDocInfo.h" +#include "../Common/XMLNode.h" + +namespace HWP +{ +enum class ECompressed +{ + FOLLOW_STORAGE = 0x00, + COMPRESS = 0x10, + NO_COMPRESS = 0x20, +}; + +enum class EType +{ + LINK = 0x0, + EMBEDDING = 0x1, + STORAGE = 0x2 +}; + +enum class EState +{ + NEVER_ACCESSED = 0x000, + FOUND_FILE_BY_ACCESS = 0x100, + ACCESS_FAILED = 0x200, + LINK_ACCESS_IGNORED = 0x400 +}; + +class CHWPRecordBinData : public CHWPRecord +{ + EType m_eType; + ECompressed m_eCompressed; + EState m_eState; + + HWP_STRING m_sAPath; + HWP_STRING m_sRPath; + short m_shBinDataID; + HWP_STRING m_sFormat; + + HWP_STRING m_sItemID; +public: + CHWPRecordBinData(CHWPDocInfo& oDocInfo, int nTagNum, int nLevel, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); + CHWPRecordBinData(CXMLNode& oNode, int nVersion); + + HWP_STRING GetPath() const; + HWP_STRING GetItemID() const; + HWP_STRING GetFormat() const; + + EType GetType() const; + ECompressed GetCompressed() const; + + short GetBinDataID() const; +}; +} + +#endif // HWPRECORDBINDATA_H diff --git a/HwpFile/HwpDoc/HWPElements/HWPRecordBorderFill.cpp b/HwpFile/HwpDoc/HWPElements/HWPRecordBorderFill.cpp new file mode 100644 index 00000000000..2569ee8618b --- /dev/null +++ b/HwpFile/HwpDoc/HWPElements/HWPRecordBorderFill.cpp @@ -0,0 +1,398 @@ +#include "HWPRecordBorderFill.h" +#include + +namespace HWP +{ +EImageFillType GetImageFillType(int nType) +{ + switch (static_cast(nType)) + { + case EImageFillType::TILE: + case EImageFillType::TILE_HORZ_TOP: + case EImageFillType::TILE_HORZ_BOTTOM: + case EImageFillType::TILE_VERT_LEFT: + case EImageFillType::TILE_VERT_RIGHT: + case EImageFillType::TOTAL: + case EImageFillType::CENTER: + case EImageFillType::CENTER_TOP: + case EImageFillType::CENTER_BOTTOM: + case EImageFillType::LEFT_CENTER: + case EImageFillType::LEFT_TOP: + case EImageFillType::LEFT_BOTTOM: + case EImageFillType::RIGHT_CENTER: + case EImageFillType::RIGHT_TOP: + case EImageFillType::RIGHT_BOTTOM: + case EImageFillType::ZOOM: + return static_cast(nType); + default: + return EImageFillType::NONE; + } +} + +EGradFillType GetGradFillType(int nType) +{ + switch(static_cast(nType)) + { + case EGradFillType::LINEAR: + case EGradFillType::RADIAL: + case EGradFillType::CONICAL: + case EGradFillType::SQUARE: + return static_cast(nType); + default: + return EGradFillType::LINEAR; + } +} + +EColorFillPattern GetColorFillPattern(int nPattern) +{ + switch (static_cast(nPattern)) + { + case EColorFillPattern::VERTICAL: + case EColorFillPattern::HORIZONTAL: + case EColorFillPattern::BACK_SLASH: + case EColorFillPattern::SLASH: + case EColorFillPattern::CROSS: + case EColorFillPattern::CROSS_DIAGONAL: + return static_cast(nPattern); + default: + return EColorFillPattern::NONE; + } +} + +void TBorder::ReadFromNode(CXMLNode& oNode) +{ + m_eStyle = GetLineStyle2(oNode.GetAttribute(L"type")); + + HWP_STRING sColor = std::regex_replace(oNode.GetAttribute(L"color"), std::wregex(L"^#([0-9A-Fa-f]+)$"), L"$1"); + + if (L"none" != sColor) + m_nColor = std::stoi(sColor, 0, 16); + + m_chWidth = (HWP_BYTE)ConvertWidthToHWP(oNode.GetAttribute(L"width")); +} + +CFill::CFill() +{} + +CFill::CFill(CHWPStream& oBuffer, int nOff, int nSize) +{ + oBuffer.SavePosition(); + + oBuffer.ReadInt(m_nFillType); + + if (CHECK_FLAG(m_nFillType, 0x01)) + { + oBuffer.ReadColor(m_nFaceColor); + oBuffer.ReadColor(m_nHatchColor); + + int nPattern; + oBuffer.ReadInt(nPattern); + + m_eHatchStyle = GetColorFillPattern(nPattern); + } + + if (CHECK_FLAG(m_nFillType, 0x04)) + { + HWP_BYTE chTypeNum; + oBuffer.ReadByte(chTypeNum); + m_eGradType = GetGradFillType((int)chTypeNum); + + oBuffer.ReadInt(m_nAngle); + oBuffer.ReadInt(m_nCenterX); + oBuffer.ReadInt(m_nCenterY); + oBuffer.ReadInt(m_nStep); + oBuffer.ReadInt(m_nColorNum); + + if (m_nColorNum > 0) + { + m_arColors.resize(m_nColorNum); + + if (m_nColorNum > 2) + { + oBuffer.Skip(4 * (m_nColorNum - 2)); + } + + for (int nIndex = 0; nIndex < m_nColorNum; ++nIndex) + oBuffer.ReadColor(m_arColors[nIndex]); + } + } + + if (CHECK_FLAG(m_nFillType, 0x02)) + { + HWP_BYTE nTypeNum; + oBuffer.ReadByte(nTypeNum); + m_eMode = GetImageFillType(nTypeNum); + + oBuffer.ReadByte(m_chBright); + oBuffer.ReadByte(m_chContrast); + oBuffer.ReadByte(m_chEffect); + + short shBinTemp; + oBuffer.ReadShort(shBinTemp); + + m_sBinItemID = TO_HWP_STRING(shBinTemp); + } + + int nMoreSize; + oBuffer.ReadInt(nMoreSize); + + if (nMoreSize > 0) + { + oBuffer.ReadByte(m_chStepCenter); + oBuffer.Skip(nMoreSize - 1); + } + + if (m_nFillType > 0) + oBuffer.ReadByte(m_chAlpha); + + if (CHECK_FLAG(m_nFillType, 0x02)) + oBuffer.ReadByte(m_chAlpha); + + m_nSize = oBuffer.GetDistanceToLastPos(true); +} + +CFill::CFill(CXMLNode& oNode) +{ + for (CXMLNode& oChild : oNode.GetChilds()) + { + if (L"hc:winBrush" == oChild.GetName()) + { + ReadWinBrush(oChild); + m_nFillType |= 0x01; + } + else if (L"hc:gradation" == oChild.GetName()) + { + ReadGradation(oChild); + m_nFillType |= 0x04; + } + else if (L"hc:imgBrush" == oChild.GetName()) + { + ReadImgBrush(oChild); + m_nFillType |= 0x02; + } + } +} + +void CFill::ReadWinBrush(CXMLNode& oNode) +{ + m_nFaceColor = oNode.GetAttributeColor(L"faceColor", 0xFFFFFFFF); + m_nHatchColor = oNode.GetAttributeColor(L"hatchColor", 0x000000); + m_eHatchStyle = GetColorFillPattern(oNode.GetAttributeInt(L"hatchStyle", -1)); + m_chAlpha = (HWP_BYTE)oNode.GetAttributeInt(L"alpha", 255); +} + +void CFill::ReadGradation(CXMLNode& oNode) +{ + m_eGradType = GetGradFillType(oNode.GetAttributeInt(L"type")); + m_nAngle = oNode.GetAttributeInt(L"angle"); + m_nCenterX = oNode.GetAttributeInt(L"centerX"); + m_nCenterY = oNode.GetAttributeInt(L"centerY"); + m_nStep = oNode.GetAttributeInt(L"step"); + m_nColorNum = oNode.GetAttributeInt(L"colorNum"); + m_chStepCenter = (HWP_BYTE)oNode.GetAttributeInt(L"stepCenter"); + m_chAlpha = (HWP_BYTE)oNode.GetAttributeInt(L"alpha", 255); + + std::vector arChilds; + + oNode.GetNodes(L"Color", arChilds); + + m_arColors.resize(arChilds.size()); + + for (unsigned int unIndex = 0; unIndex < arChilds.size(); ++unIndex) + m_arColors[unIndex] = std::stoi(std::regex_replace(arChilds[unIndex].GetText(), std::wregex(L"\\D"), L""), 0, 16); +} + +void CFill::ReadImgBrush(CXMLNode& oNode) +{ + m_eMode = GetImageFillType(oNode.GetAttributeInt(L"mode", (int)EImageFillType::NONE)); + + for (CXMLNode& oChild : oNode.GetChilds()) + { + if (L"hc:img" == oChild.GetName()) + { + m_chBright = (HWP_BYTE)oChild.GetAttributeInt(L"bright"); + m_chContrast = (HWP_BYTE)oChild.GetAttributeInt(L"contrast"); + + HWP_STRING sEffect = oChild.GetAttribute(L"effect"); + + if (L"REAL_PIC" == sEffect) + m_chEffect = 0; + else if (L"GRAY_SCALE" == sEffect) + m_chEffect = 1; + else if (L"BLACK_WHITE" == sEffect) + m_chEffect = 2; + + m_sBinItemID = oChild.GetAttribute(L"binaryItemIDRef"); + m_chAlpha = (HWP_BYTE)oChild.GetAttributeInt(L"alpha", 255); + } + } +} + +int CFill::GetSize() const +{ + return m_nSize; +} + +bool CFill::NoneFill() const +{ + return !ColorFill() && !GradFill() && !ImageFill(); +} + +bool CFill::ColorFill() const +{ + return CHECK_FLAG(m_nFillType, 0x01); +} + +bool CFill::GradFill() const +{ + return CHECK_FLAG(m_nFillType, 0x04); +} + +bool CFill::ImageFill() const +{ + return CHECK_FLAG(m_nFillType, 0x02); +} + +int CFill::GetFaceColor() const +{ + return m_nFaceColor; +} + +HWP_STRING CFill::GetBinItemID() const +{ + return m_sBinItemID; +} + +CHWPRecordBorderFill::CHWPRecordBorderFill(int nTagNum, int nLevel, int nSize) + : CHWPRecord(nTagNum, nLevel, nSize), m_pFill(nullptr) +{} + +CHWPRecordBorderFill::CHWPRecordBorderFill(CHWPDocInfo& oDocInfo, int nTagNum, int nLevel, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) + : CHWPRecord(nTagNum, nLevel, nSize), m_pFill(nullptr) +{ + short shTypeBits; + oBuffer.ReadShort(shTypeBits); + + m_bThreeD = CHECK_FLAG(shTypeBits, 0x01); + m_bShadow = CHECK_FLAG(shTypeBits, 0x02); + m_chSlash = (HWP_BYTE)((shTypeBits >> 2) & 0x07); + m_chBackSlash = (HWP_BYTE)((shTypeBits >> 5) & 0x07); + m_chCrookedSlash = (HWP_BYTE)((shTypeBits >> 8) & 0x03); + m_chCrookedBackSlash = (HWP_BYTE)((shTypeBits >> 10) & 0x01); + m_bCounterSlash = CHECK_FLAG(shTypeBits, 0x800); + m_bCounterBackSlash = CHECK_FLAG(shTypeBits, 0x1000); + m_bBreakCellSeparateLine = CHECK_FLAG(shTypeBits, 0x2000); + + + #define READ_SIDE(side) \ + oBuffer.ReadByte(chLineStyleNum); \ + side.m_eStyle = GetLineStyle2(chLineStyleNum); \ + oBuffer.ReadByte(side.m_chWidth);\ + oBuffer.ReadColor(side.m_nColor) + + HWP_BYTE chLineStyleNum; + + READ_SIDE(m_oLeft); + READ_SIDE(m_oRight); + READ_SIDE(m_oTop); + READ_SIDE(m_oBottom); + READ_SIDE(m_oDiagonal); + + m_pFill = new CFill(oBuffer, 0, 0); // TODO:: перейти от использования off и size +} + +CHWPRecordBorderFill::CHWPRecordBorderFill(CHWPDocInfo& oDocInfo, CXMLNode& oNode, int nVersion) + : CHWPRecord(EHWPTag::HWPTAG_BORDER_FILL, 0, 0), m_pFill(nullptr) +{ + m_bThreeD = oNode.GetAttributeBool(L"threeD"); + m_bShadow = oNode.GetAttributeBool(L"shadow"); + m_bBreakCellSeparateLine = oNode.GetAttributeBool(L"breakCellSeparateLine"); + + HWP_STRING sChildName; + + for (CXMLNode& oChild : oNode.GetChilds()) + { + if (L"hh:slash" == oChild.GetName()) + { + HWP_STRING sType = oChild.GetAttribute(L"type"); + + if (L"NONE" == sType) + m_chSlash = 0x0; + else if (L"CENTER" == sType) + m_chSlash = 0b010; + else if (L"CENTER_BELOW" == sType) + m_chSlash = 0b011; + else if (L"CENTER_ABOVE" == sType) + m_chSlash = 0b110; + else if (L"ALL" == sType) + m_chSlash = 0b111; + + m_chCrookedSlash = oChild.GetAttributeBool(L"Crooked"); + m_bCounterSlash = oChild.GetAttributeBool(L"isCounter"); + } + else if (L"hh:backSlash" == oChild.GetName()) + { + HWP_STRING sType = oChild.GetAttribute(L"type"); + + if (L"NONE" == sType) + m_chBackSlash = 0x0; + else if (L"CENTER" == sType) + m_chBackSlash = 0b010; + else if (L"CENTER_BELOW" == sType) + m_chBackSlash = 0b011; + else if (L"CENTER_ABOVE" == sType) + m_chBackSlash = 0b110; + else if (L"ALL" == sType) + m_chBackSlash = 0b111; + + m_chCrookedBackSlash = oChild.GetAttributeBool(L"Crooked"); + m_bCounterBackSlash = oChild.GetAttributeBool(L"isCounter"); + } + else if (L"hh:leftBorder" == oChild.GetName()) + m_oLeft.ReadFromNode(oChild); + else if (L"hh:rightBorder" == oChild.GetName()) + m_oRight.ReadFromNode(oChild); + else if (L"hh:topBorder" == oChild.GetName()) + m_oTop.ReadFromNode(oChild); + else if (L"hh:bottomBorder" == oChild.GetName()) + m_oBottom.ReadFromNode(oChild); + else if (L"hh:diagonal" == oChild.GetName()) + m_oDiagonal.ReadFromNode(oChild); + else if (L"hc:fillBrush" == oChild.GetName()) + m_pFill = new CFill(oChild); + } +} + +CHWPRecordBorderFill::~CHWPRecordBorderFill() +{ + if (nullptr != m_pFill) + delete m_pFill; +} + +TBorder CHWPRecordBorderFill::GetLeftBorder() const +{ + return m_oLeft; +} + +TBorder CHWPRecordBorderFill::GetRightBorder() const +{ + return m_oRight; +} + +TBorder CHWPRecordBorderFill::GetTopBorder() const +{ + return m_oTop; +} + +TBorder CHWPRecordBorderFill::GetBottomBorder() const +{ + return m_oBottom; +} + +const CFill* CHWPRecordBorderFill::GetFill() const +{ + return m_pFill; +} + + +} diff --git a/HwpFile/HwpDoc/HWPElements/HWPRecordBorderFill.h b/HwpFile/HwpDoc/HWPElements/HWPRecordBorderFill.h new file mode 100644 index 00000000000..55568594a45 --- /dev/null +++ b/HwpFile/HwpDoc/HWPElements/HWPRecordBorderFill.h @@ -0,0 +1,142 @@ +#ifndef HWPRECORDBORDERFILL_H +#define HWPRECORDBORDERFILL_H + +#include "../HWPDocInfo.h" +#include "HwpRecordTypes.h" +#include "../HWPStream.h" +#include "../Common/XMLNode.h" +#include + +namespace HWP +{ +struct TBorder +{ + ELineStyle2 m_eStyle; + HWP_BYTE m_chWidth; + int m_nColor; + + void ReadFromNode(CXMLNode& oNode); +}; + +enum class EImageFillType +{ + TILE, + TILE_HORZ_TOP, + TILE_HORZ_BOTTOM, + TILE_VERT_LEFT, + TILE_VERT_RIGHT, + TOTAL, + CENTER, + CENTER_TOP, + CENTER_BOTTOM, + LEFT_CENTER, + LEFT_TOP, + LEFT_BOTTOM, + RIGHT_CENTER, + RIGHT_TOP, + RIGHT_BOTTOM, + ZOOM, + NONE +}; + +enum class EGradFillType +{ + LINEAR = 1, + RADIAL = 2, + CONICAL = 3, + SQUARE = 4 +}; + +enum class EColorFillPattern +{ + NONE = -1, + VERTICAL = 0, // - - - + HORIZONTAL = 1, // ||||| + BACK_SLASH = 2, /* \\\\\ */ + SLASH = 3, // ///// + CROSS = 4, // +++++ + CROSS_DIAGONAL = 5 // xxxxx +}; + +class CFill : public IRef +{ + int m_nSize; + + int m_nFillType; + CHWPStream m_oExtraFill; + + int m_nFaceColor; + int m_nHatchColor; + EColorFillPattern m_eHatchStyle; + + EGradFillType m_eGradType; + int m_nAngle; + int m_nCenterX; + int m_nCenterY; + int m_nStep; + int m_nColorNum; + std::vector m_arColors; + + EImageFillType m_eMode; + HWP_BYTE m_chBright; + HWP_BYTE m_chContrast; + HWP_BYTE m_chEffect; + HWP_STRING m_sBinItemID; + HWP_BYTE m_chStepCenter; + + HWP_BYTE m_chAlpha; + + void ReadWinBrush(CXMLNode& oNode); + void ReadGradation(CXMLNode& oNode); + void ReadImgBrush(CXMLNode& oNode); +public: + CFill(); + CFill(CHWPStream& oBuffer, int nOff, int nSize); + CFill(CXMLNode& oNode); + + int GetSize() const; + bool NoneFill() const; + bool ColorFill() const; + bool GradFill() const; + bool ImageFill() const; + + int GetFaceColor() const; + HWP_STRING GetBinItemID() const; +}; + +class CHWPRecordBorderFill : public CHWPRecord +{ + static constexpr const float LINE_THICK[] = { 0.1f, 0.12f, 0.15f, 0.2f, 0.25f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 1.0f, 1.5f, 2.0f, 3.0f, 4.0f, 5.0f }; + + bool m_bThreeD; + bool m_bShadow; + HWP_BYTE m_chSlash; + HWP_BYTE m_chBackSlash; + HWP_BYTE m_chCrookedSlash; + HWP_BYTE m_chCrookedBackSlash; + bool m_bCounterSlash; + bool m_bCounterBackSlash; + bool m_bBreakCellSeparateLine; + + TBorder m_oLeft; + TBorder m_oRight; + TBorder m_oTop; + TBorder m_oBottom; + TBorder m_oDiagonal; + CFill *m_pFill; +public: + CHWPRecordBorderFill(int nTagNum, int nLevel, int nSize); + CHWPRecordBorderFill(CHWPDocInfo& oDocInfo, int nTagNum, int nLevel, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); + CHWPRecordBorderFill(CHWPDocInfo& oDocInfo, CXMLNode& oNode, int nVersion); + ~CHWPRecordBorderFill(); + + TBorder GetLeftBorder() const; + TBorder GetRightBorder() const; + TBorder GetTopBorder() const; + TBorder GetBottomBorder() const; + + const CFill* GetFill() const; +}; +} + +#endif // HWPRECORDBORDERFILL_H diff --git a/HwpFile/HwpDoc/HWPElements/HWPRecordBullet.cpp b/HwpFile/HwpDoc/HWPElements/HWPRecordBullet.cpp new file mode 100644 index 00000000000..877ebae3150 --- /dev/null +++ b/HwpFile/HwpDoc/HWPElements/HWPRecordBullet.cpp @@ -0,0 +1,61 @@ +#include "HWPRecordBullet.h" + +namespace HWP +{ +CHWPRecordBullet::CHWPRecordBullet(CHWPDocInfo& oDocInfo, int nTagNum, int nLevel, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) + : CHWPRecord(nTagNum, nLevel, nSize), m_pParent(&oDocInfo) +{ + oBuffer.SavePosition(); + + int nTypeBits; + oBuffer.ReadInt(nTypeBits); + + m_oHeaderInfo.m_chAlign = (HWP_BYTE)((nTypeBits) & 0x03); + m_oHeaderInfo.m_bUseInstWidth = CHECK_FLAG(nTypeBits, 0x40); + m_oHeaderInfo.m_bAutoIndent = CHECK_FLAG(nTypeBits, 0x80); + m_oHeaderInfo.m_chTextOffsetType = (HWP_BYTE)((nTypeBits >> 4) & 0x01); + + oBuffer.ReadShort(m_oHeaderInfo.m_shWidthAdjust); + oBuffer.ReadShort(m_oHeaderInfo.m_shTextOffset); + oBuffer.ReadInt(m_oHeaderInfo.m_nCharShape); + + oBuffer.ReadChar(m_chBulletChar); + + if (nSize > oBuffer.GetDistanceToLastPos()) + oBuffer.ReadInt(m_nBulletImage); + + if (nSize > oBuffer.GetDistanceToLastPos()) + oBuffer.ReadByte(m_chBright); + + if (nSize > oBuffer.GetDistanceToLastPos()) + oBuffer.ReadByte(m_chContrast); + + if (nSize > oBuffer.GetDistanceToLastPos()) + oBuffer.ReadByte(m_chImageEffect); + + if (nSize > oBuffer.GetDistanceToLastPos()) + { + short shValue; + oBuffer.ReadShort(shValue); + + m_sBinItemRefID = TO_HWP_STRING(shValue); + } + + if (nSize > oBuffer.GetDistanceToLastPos(true)) + oBuffer.ReadChar(m_chCheckBulletChar); +} + +CHWPRecordBullet::CHWPRecordBullet(CHWPDocInfo& oDocInfo, CXMLNode& oNode, int nVersion) + : CHWPRecord(EHWPTag::HWPTAG_BULLET, 0, 0), m_pParent(&oDocInfo) +{ + m_chBulletChar = oNode.GetAttribute(L"char").at(0); + m_chCheckBulletChar = oNode.GetAttribute(L"checkedChar").at(0); + m_nBulletImage = oNode.GetAttributeInt(L"useImage"); + + for (CXMLNode& oChild : oNode.GetChilds()) + { + if (L"hc:img" == oChild.GetName()) + m_sBinItemRefID = oChild.GetAttribute(L"binaryItemIDRef"); + } +} +} diff --git a/HwpFile/HwpDoc/HWPElements/HWPRecordBullet.h b/HwpFile/HwpDoc/HWPElements/HWPRecordBullet.h new file mode 100644 index 00000000000..2037770d04e --- /dev/null +++ b/HwpFile/HwpDoc/HWPElements/HWPRecordBullet.h @@ -0,0 +1,31 @@ +#ifndef HWPRECORDBULLET_H +#define HWPRECORDBULLET_H + +#include "HWPRecord.h" +#include "../HWPStream.h" +#include "../HWPDocInfo.h" +#include "HWPRecordNumbering.h" +#include "../Common/XMLNode.h" + +namespace HWP +{ +class CHWPRecordBullet : public CHWPRecord +{ + CHWPDocInfo *m_pParent; + + TNumbering m_oHeaderInfo; + HWP_CHAR m_chBulletChar; + int m_nBulletImage; + + HWP_BYTE m_chBright; + HWP_BYTE m_chContrast; + HWP_BYTE m_chImageEffect; + HWP_STRING m_sBinItemRefID; + HWP_CHAR m_chCheckBulletChar; +public: + CHWPRecordBullet(CHWPDocInfo& oDocInfo, int nTagNum, int nLevel, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); + CHWPRecordBullet(CHWPDocInfo& oDocInfo, CXMLNode& oNode, int nVersion); +}; +} + +#endif // HWPRECORDBULLET_H diff --git a/HwpFile/HwpDoc/HWPElements/HWPRecordCharShape.cpp b/HwpFile/HwpDoc/HWPElements/HWPRecordCharShape.cpp new file mode 100644 index 00000000000..1c4fa485134 --- /dev/null +++ b/HwpFile/HwpDoc/HWPElements/HWPRecordCharShape.cpp @@ -0,0 +1,380 @@ +#include "HWPRecordCharShape.h" +#include "../HWPElements/HWPRecordFaceName.h" + +namespace HWP +{ +EAccent GetAccent(int nValue) +{ + SWITCH(EAccent, nValue) + { + DEFAULT(EAccent::NONE); + CASE(EAccent::DOT); + CASE(EAccent::RING); + CASE(EAccent::CARON); + CASE(EAccent::TILDE); + CASE(EAccent::ARAEA); + CASE(EAccent::TWOARAEA); + } +} + +EAccent GetAccent(const HWP_STRING& sValue) +{ + IF_STRING_IN_ENUM(DOT, sValue, EAccent); + ELSE_IF_STRING_IN_ENUM(RING, sValue, EAccent); + ELSE_IF_STRING_IN_ENUM(CARON, sValue, EAccent); + ELSE_IF_STRING_IN_ENUM(TILDE, sValue, EAccent); + ELSE_IF_STRING_IN_ENUM(ARAEA, sValue, EAccent); + ELSE_IF_STRING_IN_ENUM(TWOARAEA, sValue, EAccent); + ELSE_STRING_IN_ENUM(NONE, EAccent); +} + +ELang GetLang(int nValue) +{ + switch (static_cast(nValue)) + { + case ELang::HANGUL: + case ELang::LATIN: + case ELang::HANJA: + case ELang::JAPANESE: + case ELang::OTHER: + case ELang::SYMBOL: + case ELang::USER: + case ELang::MAX: + return static_cast(nValue); + default: + return ELang::HANGUL; + } +} + +EUnderline GetUnderline(int nValue) +{ + SWITCH(EUnderline, nValue) + { + DEFAULT(EUnderline::NONE); + CASE(EUnderline::BOTTOM); + CASE(EUnderline::CENTER); + CASE(EUnderline::TOP); + } +} + +EUnderline GetUnderline(const HWP_STRING& sValue) +{ + IF_STRING_IN_ENUM(BOTTOM, sValue, EUnderline); + ELSE_IF_STRING_IN_ENUM(CENTER, sValue, EUnderline); + ELSE_IF_STRING_IN_ENUM(TOP, sValue, EUnderline); + ELSE_STRING_IN_ENUM(NONE, EUnderline); +} + +EOutline GetOutline(int nValue) +{ + SWITCH(EOutline, nValue) + { + DEFAULT(EOutline::NONE); + CASE(EOutline::SOLID); + CASE(EOutline::DOTTED); + CASE(EOutline::BOLD); + CASE(EOutline::DASHED); + CASE(EOutline::DASH_DOT); + CASE(EOutline::DASH_2DOT); + } +} + +EOutline GetOutline(const HWP_STRING& sValue) +{ + IF_STRING_IN_ENUM(SOLID, sValue, EOutline); + ELSE_IF_STRING_IN_ENUM(DOTTED, sValue, EOutline); + ELSE_IF_STRING_IN_ENUM(BOLD, sValue, EOutline); + ELSE_IF_STRING_IN_ENUM(DASHED, sValue, EOutline); + ELSE_IF_STRING_IN_ENUM(DASH_DOT, sValue, EOutline); + ELSE_IF_STRING_IN_ENUM(DASH_2DOT, sValue, EOutline); + ELSE_STRING_IN_ENUM(NONE, EOutline); +} + +EShadow GetShadow(int nValue) +{ + SWITCH(EShadow, nValue) + { + DEFAULT(EShadow::NONE); + CASE(EShadow::DISCRETE); + CASE(EShadow::CONTINUOUS); + } +} + +EShadow GetShadow(const HWP_STRING& sValue) +{ + IF_STRING_IN_ENUM(DISCRETE, sValue, EShadow); + ELSE_IF_STRING_IN_ENUM(CONTINUOUS, sValue, EShadow); + ELSE_STRING_IN_ENUM(NONE, EShadow); +} + +void CHWPRecordCharShape::ReadContainerData(CXMLNode& oNode, short arValues[], int nDefaultValue) +{ + arValues[(int)ELang::HANGUL] = oNode.GetAttributeInt(L"hangul", nDefaultValue); + arValues[(int)ELang::LATIN] = oNode.GetAttributeInt(L"latin", nDefaultValue); + arValues[(int)ELang::HANJA] = oNode.GetAttributeInt(L"hanja", nDefaultValue); + arValues[(int)ELang::JAPANESE] = oNode.GetAttributeInt(L"japanese", nDefaultValue); + arValues[(int)ELang::OTHER] = oNode.GetAttributeInt(L"other", nDefaultValue); + arValues[(int)ELang::SYMBOL] = oNode.GetAttributeInt(L"symbol", nDefaultValue); + arValues[(int)ELang::USER] = oNode.GetAttributeInt(L"user", nDefaultValue); +} + +CHWPRecordCharShape::CHWPRecordCharShape(CHWPDocInfo& oDocInfo, int nTagNum, int nLevel, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) + : CHWPRecord(nTagNum, nLevel, nSize), m_pParent(&oDocInfo) +{ + oBuffer.SavePosition(); + + for (int nIndex = 0; nIndex < MAX_ELEMENTS; ++nIndex) + { + short shFontID; + oBuffer.ReadShort(shFontID); + + const CHWPRecordFaceName* pFaceName = dynamic_cast(m_pParent->GetFaceName(shFontID)); + + if (nullptr != pFaceName) + m_arFontNames[nIndex] = pFaceName->GetFaceName(); + } + + #define READ_SHORT (short)(oBuffer[0] & 0x00FF); oBuffer.Skip(1) + + for (int nIndex = 0; nIndex < MAX_ELEMENTS; ++nIndex) + { + m_arRatios[nIndex] = READ_SHORT; + } + + for (int nIndex = 0; nIndex < MAX_ELEMENTS; ++nIndex) + { + m_arSpacings[nIndex] = READ_SHORT; + } + + for (int nIndex = 0; nIndex < MAX_ELEMENTS; ++nIndex) + { + m_arRelSizes[nIndex] = READ_SHORT; + } + + for (int nIndex = 0; nIndex < MAX_ELEMENTS; ++nIndex) + { + m_arCharOffset[nIndex] = (HWP_BYTE)(oBuffer[0] & 0x00FF); + oBuffer.Skip(1); + } + + oBuffer.ReadInt(m_nHeight); + + int nAttrBits; + oBuffer.ReadInt(nAttrBits); + + // Attributes + m_bItalic = CHECK_FLAG(nAttrBits, 0x01); + m_bBold = CHECK_FLAG(nAttrBits, 0x02); + m_eUnderline = GetUnderline((nAttrBits >> 2) & 0x03); + m_eUnderLineShape = GetLineStyle1((nAttrBits >> 4) & 0x0F); + m_eOutline = GetOutline((nAttrBits >> 8) & 0x07); + m_eShadow = GetShadow((nAttrBits >> 11) & 0x03); + m_bEmboss = CHECK_FLAG(nAttrBits, 0x2000); + m_bEngrave = CHECK_FLAG(nAttrBits, 0x4000); + m_bSuperScript = CHECK_FLAG(nAttrBits, 0x8000); + m_bSubScript = CHECK_FLAG(nAttrBits, 0xF000); + m_chStrikeOut = (HWP_BYTE)((nAttrBits >> 18) & 0x07); + m_eSymMark = GetAccent((nAttrBits >> 21) & 0x0F); + m_bUseFontSpace = CHECK_FLAG(nAttrBits, 0x2000000); + m_eStrikeOutShape = GetLineStyle2((nAttrBits >> 26) & 0x0F); + m_bUseKerning = CHECK_FLAG(nAttrBits, 0x40000000); + + oBuffer.ReadByte(m_chShadowOffsetX); + oBuffer.ReadByte(m_chShadowOffsetY); + oBuffer.ReadColor(m_nTextColor); + oBuffer.ReadColor(m_nUnderlineColor); + oBuffer.ReadColor(m_nShadeColor); + oBuffer.ReadColor(m_nShadeColor); + + if (nSize > oBuffer.GetDistanceToLastPos()) + oBuffer.ReadShort(m_shBorderFillIDRef); + + if (nVersion > 5030 && nSize > oBuffer.GetDistanceToLastPos()) + oBuffer.ReadColor(m_nStrikeOutColor); + + oBuffer.RemoveLastSavedPos(); +} + +CHWPRecordCharShape::CHWPRecordCharShape(CHWPDocInfo& oDocInfo, CXMLNode& oNode, int nVersion) + : CHWPRecord(EHWPTag::HWPTAG_HWP_CHAR_SHAPE, 0, 0), m_pParent(&oDocInfo), + m_bItalic(false), m_bBold(false), m_bEmboss(false), m_bEngrave(false), + m_bSuperScript(false), m_bSubScript(false) +{ + m_eUnderline = EUnderline::NONE; + m_eUnderLineShape = ELineStyle1::SOLID; + m_eOutline = EOutline::NONE; + m_eShadow = EShadow::NONE; + m_eStrikeOutShape = ELineStyle2::NONE; + + m_nHeight = oNode.GetAttributeInt(L"height", 1000); + m_nTextColor = oNode.GetAttributeColor(L"textColor", 0x000000); + m_nShadeColor = oNode.GetAttributeColor(L"shadeColor", 0xFFFFFFFF); + m_bUseFontSpace = oNode.GetAttributeBool(L"useFontSpace"); + m_bUseKerning = oNode.GetAttributeBool(L"useKerning"); + + m_eSymMark = GetAccent(oNode.GetAttribute(L"symMark")); + + m_shBorderFillIDRef = oNode.GetAttributeInt(L"borderFillIDRef"); + + for (CXMLNode& oChild : oNode.GetChilds()) + { + if (L"hh:fontRef" == oChild.GetName()) + { + if (nullptr == m_pParent) + continue; + + const CHWPRecordFaceName* pFaceName = nullptr; + + #define UPDATE_FACENAME(node_name, elang_type) \ + pFaceName = dynamic_cast(m_pParent->GetFaceName(oChild.GetAttributeInt(node_name))); \ + if (nullptr != pFaceName) \ + m_arFontNames[(int)elang_type] = pFaceName->GetFaceName() + + UPDATE_FACENAME(L"hangul", ELang::HANGUL); + UPDATE_FACENAME(L"latin", ELang::LATIN); + UPDATE_FACENAME(L"hanja", ELang::HANJA); + UPDATE_FACENAME(L"japanese", ELang::JAPANESE); + UPDATE_FACENAME(L"other", ELang::OTHER); + UPDATE_FACENAME(L"symbol", ELang::SYMBOL); + UPDATE_FACENAME(L"user", ELang::USER); + } + else if (L"hh:ratio" == oChild.GetName()) + ReadContainerData(oChild, m_arRatios, 100); + else if (L"hh:spacing" == oChild.GetName()) + ReadContainerData(oChild, m_arSpacings); + else if (L"hh:relSz" == oChild.GetName()) + ReadContainerData(oChild, m_arRelSizes, 100); + else if (L"hh:offset" == oChild.GetName()) + ReadContainerData(oChild, m_arCharOffset); + else if (L"hh:underline" == oChild.GetName()) + { + m_eUnderline = GetUnderline(oChild.GetAttribute(L"type")); + m_eUnderLineShape = GetLineStyle1(oChild.GetAttribute(L"shape")); + m_nUnderlineColor = oChild.GetAttributeColor(L"color"); + } + else if (L"hh:strikeout" == oChild.GetName()) + { + m_eStrikeOutShape = GetLineStyle2(oChild.GetAttribute(L"shape")); + m_nStrikeOutColor = oChild.GetAttributeColor(L"color"); + + if (L"3D" == oChild.GetAttribute(L"shape")) + m_eStrikeOutShape = ELineStyle2::NONE; + } + else if (L"hh:outline" == oChild.GetName()) + { + m_eOutline = GetOutline(oChild.GetAttribute(L"type")); + } + else if (L"hh:shadow" == oChild.GetName()) + { + HWP_STRING sType = oChild.GetAttribute(L"type"); + + if (L"DROP" == sType) + m_eShadow = EShadow::DISCRETE; + else if (L"CONTINUOUS" == sType) + m_eShadow = EShadow::CONTINUOUS; + else + m_eShadow = EShadow::NONE; + + m_nShadowColor = oChild.GetAttributeColor(L"color"); + m_chShadowOffsetX = (HWP_BYTE)oChild.GetAttributeInt(L"offsetX"); + m_chShadowOffsetY = (HWP_BYTE)oChild.GetAttributeInt(L"offsetY"); + } + else if (L"hh:italic" == oChild.GetName()) + m_bItalic = true; + else if (L"hh:bold" == oChild.GetName()) + m_bBold = true; + else if (L"hh:emboss" == oChild.GetName()) + m_bEmboss = true; + else if (L"hh:engrave" == oChild.GetName()) + m_bEmboss = true; + else if (L"hh:supscript" == oChild.GetName()) + m_bSuperScript = true; + else if (L"hh:subscript" == oChild.GetName()) + m_bSubScript = true; + } +} + +bool CHWPRecordCharShape::Bold() const +{ + return m_bBold; +} + +bool CHWPRecordCharShape::Italic() const +{ + return m_bItalic; +} + +bool CHWPRecordCharShape::Underline() const +{ + return EUnderline::NONE != m_eUnderline; +} + +bool CHWPRecordCharShape::StrikeOut() const +{ + return ELineStyle2::NONE != m_eStrikeOutShape; +} + +int CHWPRecordCharShape::GetHeight() const +{ + return m_nHeight; +} + +EUnderline CHWPRecordCharShape::GetUnderlineType() const +{ + return m_eUnderline; +} + +ELineStyle1 CHWPRecordCharShape::GetUnderlineStyle() const +{ + return m_eUnderLineShape; +} + +int CHWPRecordCharShape::GetUnderlineColor() const +{ + return m_nUnderlineColor; +} + +ELineStyle2 CHWPRecordCharShape::GetStrikeOutType() const +{ + return m_eStrikeOutShape; +} + +int CHWPRecordCharShape::GetStrikeOutColor() const +{ + return m_nStrikeOutColor; +} + +short CHWPRecordCharShape::GetRelSize(ELang eLang) const +{ + if (ELang::MAX == eLang) + return 0; + + return m_arRelSizes[(int)eLang]; +} + +HWP_STRING CHWPRecordCharShape::GetFontName(ELang eLang) const +{ + if (ELang::MAX == eLang) + return HWP_STRING(); + + return m_arFontNames[(int)eLang]; +} + +short CHWPRecordCharShape::GetSpacing(ELang eLang) const +{ + if (ELang::MAX == eLang) + return 0; + + return m_arSpacings[(int)eLang]; +} + +int CHWPRecordCharShape::GetTextColor() const +{ + return m_nTextColor; +} + +short CHWPRecordCharShape::GetBorderFillID() const +{ + return m_shBorderFillIDRef; +} +} diff --git a/HwpFile/HwpDoc/HWPElements/HWPRecordCharShape.h b/HwpFile/HwpDoc/HWPElements/HWPRecordCharShape.h new file mode 100644 index 00000000000..e6d304cdb5d --- /dev/null +++ b/HwpFile/HwpDoc/HWPElements/HWPRecordCharShape.h @@ -0,0 +1,131 @@ +#ifndef HWPRECORDCHARSHAPE_H +#define HWPRECORDCHARSHAPE_H + +#include "../HWPDocInfo.h" +#include "../HWPStream.h" +#include "HWPRecord.h" +#include "HwpRecordTypes.h" +#include "../Common/XMLNode.h" + +namespace HWP +{ + +enum class ELang +{ + HANGUL, + LATIN, + HANJA, + JAPANESE, + OTHER, + SYMBOL, + USER, + MAX +}; + +enum class EUnderline +{ + NONE, + BOTTOM, + CENTER, + TOP +}; + +enum class EOutline +{ + NONE, + SOLID, + DOTTED, + BOLD, + DASHED, + DASH_DOT, + DASH_2DOT +}; + +enum class EShadow +{ + NONE, + DISCRETE, + CONTINUOUS +}; + +enum class EAccent +{ + NONE, + DOT, + RING, + CARON, + TILDE, + ARAEA, + TWOARAEA +}; + +EAccent GetAccent(int nValue); +EAccent GetAccent(const HWP_STRING& sValue); + +#define MAX_ELEMENTS (int)ELang::MAX + +class CHWPRecordCharShape : public CHWPRecord +{ + CHWPDocInfo *m_pParent; + + HWP_STRING m_arFontNames[MAX_ELEMENTS]; + short m_arRatios[MAX_ELEMENTS]; + short m_arSpacings[MAX_ELEMENTS]; + short m_arRelSizes[MAX_ELEMENTS]; + short m_arCharOffset[MAX_ELEMENTS]; + int m_nHeight; + + bool m_bItalic; + bool m_bBold; + EUnderline m_eUnderline; + ELineStyle1 m_eUnderLineShape; + int m_nUnderlineColor; + EOutline m_eOutline; + EShadow m_eShadow; + bool m_bEmboss; + bool m_bEngrave; + bool m_bSuperScript; + bool m_bSubScript; + HWP_BYTE m_chStrikeOut; + EAccent m_eSymMark; + bool m_bUseFontSpace; + ELineStyle2 m_eStrikeOutShape; + bool m_bUseKerning; + + HWP_BYTE m_chShadowOffsetX; + HWP_BYTE m_chShadowOffsetY; + int m_nTextColor; + int m_nShadeColor; + int m_nShadowColor; + short m_shBorderFillIDRef; + int m_nStrikeOutColor; + + void ReadContainerData(CXMLNode& oNode, short arValues[], int nDefaultValue = 0); +public: + CHWPRecordCharShape(CHWPDocInfo& oDocInfo, int nTagNum, int nLevel, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); + CHWPRecordCharShape(CHWPDocInfo& oDocInfo, CXMLNode& oNode, int nVersion); + + bool Bold() const; + bool Italic() const; + bool Underline() const; + bool StrikeOut() const; + + int GetHeight() const; + + EUnderline GetUnderlineType() const; + ELineStyle1 GetUnderlineStyle() const; + int GetUnderlineColor() const; + + ELineStyle2 GetStrikeOutType() const; + int GetStrikeOutColor() const; + + short GetRelSize(ELang eLang) const; + HWP_STRING GetFontName(ELang eLang) const; + short GetSpacing(ELang eLang) const; + int GetTextColor() const; + + short GetBorderFillID() const; +}; +} + +#endif // HWPRECORDCHARSHAPE_H diff --git a/HwpFile/HwpDoc/HWPElements/HWPRecordCtrlData.cpp b/HwpFile/HwpDoc/HWPElements/HWPRecordCtrlData.cpp new file mode 100644 index 00000000000..4ede34fb404 --- /dev/null +++ b/HwpFile/HwpDoc/HWPElements/HWPRecordCtrlData.cpp @@ -0,0 +1,88 @@ +#include "HWPRecordCtrlData.h" +#include "../Paragraph/CtrlField.h" + +namespace HWP +{ + +EParamItemType GetParamItemType(int nValue) +{ + switch(static_cast(nValue)) + { + case EParamItemType::PIT_NULL: + case EParamItemType::PIT_BSTR: + case EParamItemType::PIT_I1: + case EParamItemType::PIT_I2: + case EParamItemType::PIT_I4: + case EParamItemType::PIT_I: + case EParamItemType::PIT_UI1: + case EParamItemType::PIT_UI2: + case EParamItemType::PIT_UI4: + case EParamItemType::PIT_UI: + case EParamItemType::PIT_SET: + case EParamItemType::PIT_ARRAY: + case EParamItemType::PIT_BINDATA: + return static_cast(nValue); + default: + return EParamItemType::PIT_NULL; + } +} + +CHWPRecordCtrlData::CHWPRecordCtrlData(int nTagNum, int nLevel, int nSize) + : CHWPRecord(nTagNum, nLevel, nSize) +{} + +int CHWPRecordCtrlData::ParseCtrl(CCtrl& oCtrl, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) +{ + // TODO:: Вернуться к этому моменту + // Само по себе содержание документа Hankom не позволяет понять, как его интерпретировать. + + oBuffer.SavePosition(); + + if (ECtrlObjectType::Field == oCtrl.GetCtrlType()) + { + short shSetID, shNumberItems; + + oBuffer.ReadShort(shSetID); + oBuffer.ReadShort(shNumberItems); + + short shItemID, shItemType; + for (unsigned short ushIndex = 0; ushIndex < shNumberItems; ++ushIndex) + { + oBuffer.ReadShort(shItemID); + short shUnknownValue; + oBuffer.ReadShort(shUnknownValue); // Unknown Data + oBuffer.ReadShort(shItemType); + + switch (GetParamItemType(shItemType)) + { + case EParamItemType::PIT_NULL: oBuffer.Skip(4); break; + case EParamItemType::PIT_BSTR: + { + HWP_STRING sValue; + oBuffer.ReadString(sValue, EStringCharacter::UTF16); + + if (EFieldType::Bookmark == ((CCtrlField&)oCtrl).GetType()) + ((CCtrlField&)oCtrl).AddStringParam(L"bookmarkname", sValue); + + break; + } + case EParamItemType::PIT_I1: oBuffer.Skip(1); break; + case EParamItemType::PIT_I2: oBuffer.Skip(2); break; + case EParamItemType::PIT_I4: oBuffer.Skip(4); break; + case EParamItemType::PIT_I: oBuffer.Skip(4); break; + case EParamItemType::PIT_UI1: oBuffer.Skip(1); break; + case EParamItemType::PIT_UI2: oBuffer.Skip(2); break; + case EParamItemType::PIT_UI4: oBuffer.Skip(4); break; + case EParamItemType::PIT_UI: oBuffer.Skip(4); break; + case EParamItemType::PIT_SET: + case EParamItemType::PIT_ARRAY: + case EParamItemType::PIT_BINDATA: + break; + } + } + } + + oBuffer.Skip(nSize - oBuffer.GetDistanceToLastPos(true)); + return nSize; +} +} diff --git a/HwpFile/HwpDoc/HWPElements/HWPRecordCtrlData.h b/HwpFile/HwpDoc/HWPElements/HWPRecordCtrlData.h new file mode 100644 index 00000000000..2efe2ba8d4c --- /dev/null +++ b/HwpFile/HwpDoc/HWPElements/HWPRecordCtrlData.h @@ -0,0 +1,51 @@ +#ifndef HWPRECORDCTRLDATA_H +#define HWPRECORDCTRLDATA_H + +#include "../HWPStream.h" +#include "HWPRecord.h" +#include "../Paragraph/Ctrl.h" + +namespace HWP +{ +enum class EParamItemType +{ + PIT_NULL, + PIT_BSTR, + PIT_I1, + PIT_I2, + PIT_I4, + PIT_I, + PIT_UI1, + PIT_UI2, + PIT_UI4, + PIT_UI, + PIT_SET = 0x8000, + PIT_ARRAY = 0x8001, + PIT_BINDATA = 0x8002 +}; + +struct TParameterItem +{ + short m_shItemId; + EParamItemType m_eItemType; + CHWPStream m_oItemData; +}; + +struct TParameterSet +{ + short m_shParamSetId; + short m_shNItems; + LIST m_arItems; +}; + +class CHWPRecordCtrlData : public CHWPRecord +{ + LIST m_arParamSets; +public: + CHWPRecordCtrlData(int nTagNum, int nLevel, int nSize); + + static int ParseCtrl(CCtrl& oCtrl, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); +}; +} + +#endif // HWPRECORDCTRLDATA_H diff --git a/HwpFile/HwpDoc/HWPElements/HWPRecordCtrlHeader.cpp b/HwpFile/HwpDoc/HWPElements/HWPRecordCtrlHeader.cpp new file mode 100644 index 00000000000..7aeca8fc17f --- /dev/null +++ b/HwpFile/HwpDoc/HWPElements/HWPRecordCtrlHeader.cpp @@ -0,0 +1,112 @@ +#include "HWPRecordCtrlHeader.h" + +#include "../Paragraph/CtrlAutoNumber.h" +#include "../Paragraph/CtrlClick.h" +#include "../Paragraph/CtrlColumnDef.h" +#include "../Paragraph/CtrlEqEdit.h" +#include "../Paragraph/CtrlForm.h" +#include "../Paragraph/CtrlGeneralShape.h" +#include "../Paragraph/CtrlHeadFoot.h" +#include "../Paragraph/CtrlNewNumber.h" +#include "../Paragraph/CtrlNote.h" +#include "../Paragraph/CtrlPageNumPos.h" +#include "../Paragraph/CtrlSectionDef.h" +#include "../Paragraph/CtrlTable.h" +#include "../Paragraph/CtrlEmpty.h" +#include "../Paragraph/CtrlField.h" + +namespace HWP +{ +CHWPRecordCtrlHeader::CHWPRecordCtrlHeader(int nTagNum, int nLevel, int nSize) + : CHWPRecord(nTagNum, nLevel, nSize) +{} + +CCtrl* CHWPRecordCtrlHeader::Parse(int nTagNum, int nLevel, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) +{ + oBuffer.SavePosition(); + + HWP_STRING sCtrlID; + oBuffer.ReadString(sCtrlID, 4, EStringCharacter::ASCII); + + CCtrl* pCtrl = nullptr; + + if (L"dces" == sCtrlID) + pCtrl = new CCtrlSectionDef(sCtrlID, nSize - oBuffer.GetDistanceToLastPos(), oBuffer, 0, nVersion); + else if (L"dloc" == sCtrlID) + pCtrl = new CCtrlColumnDef(sCtrlID, nSize - oBuffer.GetDistanceToLastPos(), oBuffer, 0, nVersion); + else if (L"daeh" == sCtrlID) + pCtrl = new CCtrlHeadFoot(sCtrlID, nSize - oBuffer.GetDistanceToLastPos(), oBuffer, 0, nVersion, true); + else if (L"toof" == sCtrlID) + pCtrl = new CCtrlHeadFoot(sCtrlID, nSize - oBuffer.GetDistanceToLastPos(), oBuffer, 0, nVersion, false); + else if (L" nf" == sCtrlID || L" ne" == sCtrlID) + pCtrl = new CCtrlNote(sCtrlID, nSize - oBuffer.GetDistanceToLastPos(), oBuffer, 0, nVersion); + else if (L" lbt" == sCtrlID) + pCtrl = new CCtrlTable(sCtrlID, nSize - oBuffer.GetDistanceToLastPos(), oBuffer, 0, nVersion); + else if (L"onta" == sCtrlID) + pCtrl = new CCtrlAutoNumber(sCtrlID, nSize - oBuffer.GetDistanceToLastPos(), oBuffer, 0, nVersion); + else if (L"onwn" == sCtrlID) + pCtrl = new CCtrlNewNumber(sCtrlID, nSize - oBuffer.GetDistanceToLastPos(), oBuffer, 0, nVersion); + else if (L" osg" == sCtrlID) + pCtrl = new CCtrlGeneralShape(sCtrlID, nSize - oBuffer.GetDistanceToLastPos(), oBuffer, 0, nVersion); + else if (L"deqe" == sCtrlID) + pCtrl = new CCtrlEqEdit(sCtrlID, nSize - oBuffer.GetDistanceToLastPos(), oBuffer, 0, nVersion); + else if (L"dhgp" == sCtrlID) + { + int nTempSize = nSize - oBuffer.GetDistanceToLastPos(); + oBuffer.Skip(nTempSize); + } + else if (L"cot%" == sCtrlID) + { + // Когда содержимое считывается как UTF_16LE, следующее содержимое остается тем же самым + // ¥TableOfContents:set:140:ContentsMake:uint:17 ContentsStyles:wstring:0: ContentsLevel:int:5 ContentsAutoTabRight:int:0 ContentsLeader:int:3 ContentsHyperlink:bool:1 + + int nTempSize = nSize - oBuffer.GetDistanceToLastPos(); + oBuffer.Skip(nTempSize); + } + else if (L"klc%" == sCtrlID) + { + pCtrl = new CCtrlClick(sCtrlID, nSize - oBuffer.GetDistanceToLastPos(), oBuffer, 0, nVersion); + pCtrl->SetFullFilled(); + } + else if (L"mrof" == sCtrlID) + { + pCtrl = new CCtrlForm(sCtrlID, nSize - oBuffer.GetDistanceToLastPos(), oBuffer, 0, nVersion); + pCtrl->SetFullFilled(); + } + else if (L"pngp" == sCtrlID) + { + pCtrl = new CCtrlPageNumPos(sCtrlID, nSize - oBuffer.GetDistanceToLastPos(), oBuffer, 0, nVersion); + pCtrl->SetFullFilled(); + } + else if (L"klh%" == sCtrlID || + L"kmb%" == sCtrlID) + { + pCtrl = new CCtrlField(sCtrlID, nSize - oBuffer.GetDistanceToLastPos(), oBuffer, 0, nVersion); + pCtrl->SetFullFilled(); + } + // else if (L"klh%" == sCtrlID || // hyperlink + // L"frx%" == sCtrlID || // FIELD_CROSSREF + // L"knu%" == sCtrlID || // FIELD_UNKNOWN + // L"etd%" == sCtrlID || // FIELD_DATE + // L"tdd%" == sCtrlID || // FIELD_DOCDATE + // L"tap%" == sCtrlID || // FIELD_PATH + // L"kmb%" == sCtrlID || // FIELD_BOOKMARK + // L"gmm%" == sCtrlID || // FIELD_MAILMERGE + // L"umf%" == sCtrlID || // FIELD_FORMULA + // L"mxdi" == sCtrlID || // ??? + // L"mkob" == sCtrlID || // ??? + // L"spct" == sCtrlID || // ??? + // L"tmct" == sCtrlID || // ??? + // L"tcgp" == sCtrlID || // ??? + // L"tudt" == sCtrlID) // ??? + else + { + int nTempSize = nSize - oBuffer.GetDistanceToLastPos(); + pCtrl = new CCtrlEmpty(sCtrlID); + pCtrl->SetFullFilled(); + oBuffer.Skip(nTempSize); + } + + return pCtrl; +} +} diff --git a/HwpFile/HwpDoc/HWPElements/HWPRecordCtrlHeader.h b/HwpFile/HwpDoc/HWPElements/HWPRecordCtrlHeader.h new file mode 100644 index 00000000000..ca01ce8575d --- /dev/null +++ b/HwpFile/HwpDoc/HWPElements/HWPRecordCtrlHeader.h @@ -0,0 +1,20 @@ +#ifndef HWPRECORDCTRLHEADER_H +#define HWPRECORDCTRLHEADER_H + +#include "HWPRecord.h" + +#include "../Paragraph/Ctrl.h" +#include "../HWPStream.h" + +namespace HWP +{ +class CHWPRecordCtrlHeader : public CHWPRecord +{ +public: + CHWPRecordCtrlHeader(int nTagNum, int nLevel, int nSize); + + static CCtrl* Parse(int nTagNum, int nLevel, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); +}; +} + +#endif // HWPRECORDCTRLHEADER_H diff --git a/HwpFile/HwpDoc/HWPElements/HWPRecordDocumentProperties.cpp b/HwpFile/HwpDoc/HWPElements/HWPRecordDocumentProperties.cpp new file mode 100644 index 00000000000..cada1bee0eb --- /dev/null +++ b/HwpFile/HwpDoc/HWPElements/HWPRecordDocumentProperties.cpp @@ -0,0 +1,29 @@ +#include "HWPRecordDocumentProperties.h" + +namespace HWP +{ +CHWPRecordDocumentProperties::CHWPRecordDocumentProperties(CHWPDocInfo& oDocInfo, int nTagNum, int nLevel, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) + : CHWPRecord(nTagNum, nLevel, nSize), m_pParent(&oDocInfo) +{ + oBuffer.ReadShort(m_shSectionSize); + oBuffer.ReadShort(m_shPageStartNo); + oBuffer.ReadShort(m_shFootNoteStartNo); + oBuffer.ReadShort(m_shEndNoteStartNo); + oBuffer.ReadShort(m_shFigureStartNo); + oBuffer.ReadShort(m_shTableStartNo); + oBuffer.ReadInt(m_nListID); + oBuffer.ReadInt(m_nParaID); + oBuffer.ReadInt(m_nCharUnitLocInPara); +} + +CHWPRecordDocumentProperties::CHWPRecordDocumentProperties(CHWPDocInfo& oDocInfo, CXMLNode& oNode, int nVersion) + : CHWPRecord(EHWPTag::HWPTAG_DOCUMENT_PROPERTIES, 0, 0), m_pParent(&oDocInfo) +{ + m_shFigureStartNo = oNode.GetAttributeInt(L"page"); + m_shFootNoteStartNo = oNode.GetAttributeInt(L"footnote"); + m_shEndNoteStartNo = oNode.GetAttributeInt(L"endnote"); + m_shFigureStartNo = oNode.GetAttributeInt(L"pic"); + m_shTableStartNo = oNode.GetAttributeInt(L"tbl"); + m_shEqStartNo = oNode.GetAttributeInt(L"equation"); +} +} diff --git a/HwpFile/HwpDoc/HWPElements/HWPRecordDocumentProperties.h b/HwpFile/HwpDoc/HWPElements/HWPRecordDocumentProperties.h new file mode 100644 index 00000000000..ab2dd86a1f5 --- /dev/null +++ b/HwpFile/HwpDoc/HWPElements/HWPRecordDocumentProperties.h @@ -0,0 +1,31 @@ +#ifndef HWPRECORDDOCUMENTPROPERTIES_H +#define HWPRECORDDOCUMENTPROPERTIES_H + +#include "../HWPDocInfo.h" +#include "../HWPStream.h" +#include "HWPRecord.h" +#include "../Common/XMLNode.h" + +namespace HWP +{ +class CHWPRecordDocumentProperties : public CHWPRecord +{ + CHWPDocInfo *m_pParent; + + short m_shSectionSize; + short m_shPageStartNo; + short m_shFootNoteStartNo; + short m_shEndNoteStartNo; + short m_shFigureStartNo; + short m_shTableStartNo; + short m_shEqStartNo; + int m_nListID; + int m_nParaID; + int m_nCharUnitLocInPara; +public: + CHWPRecordDocumentProperties(CHWPDocInfo& oDocInfo, int nTagNum, int nLevel, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); + CHWPRecordDocumentProperties(CHWPDocInfo& oDocInfo, CXMLNode& oNode, int nVersion); +}; +} + +#endif // HWPRECORDDOCUMENTPROPERTIES_H diff --git a/HwpFile/HwpDoc/HWPElements/HWPRecordFaceName.cpp b/HwpFile/HwpDoc/HWPElements/HWPRecordFaceName.cpp new file mode 100644 index 00000000000..4652f375802 --- /dev/null +++ b/HwpFile/HwpDoc/HWPElements/HWPRecordFaceName.cpp @@ -0,0 +1,103 @@ +#include "HWPRecordFaceName.h" + +namespace HWP +{ + +EAltType GetAltType(int nValue) +{ + switch(static_cast(nValue)) + { + case EAltType::UNKNOWN: + default: return EAltType::UNKNOWN; + case EAltType::FFT: return EAltType::FFT; + case EAltType::HFT: return EAltType::HFT; + } +} + +CHWPRecordFaceName::CHWPRecordFaceName(CHWPDocInfo& oDocInfo, int nTagNum, int nLevel, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) + : CHWPRecord(nTagNum, nLevel, nSize), m_pParent(&oDocInfo) +{ + HWP_BYTE chDataBits; + oBuffer.ReadByte(chDataBits); + + m_bBasicFaceExists = CHECK_FLAG(chDataBits, 0x20); + m_bAttrExists = CHECK_FLAG(chDataBits, 0x40); + m_bSubstExists = CHECK_FLAG(chDataBits, 0x80); + + oBuffer.ReadString(m_sFaceName, EStringCharacter::UTF16); + + if (m_bSubstExists) + { + char chSubsType; + oBuffer.ReadByte(chSubsType); + m_eSubstType = GetAltType(chSubsType & 0x0F); + + oBuffer.ReadString(m_sSubstFace, EStringCharacter::UTF16); + } + + if (m_bAttrExists) + { + oBuffer.ReadByte(m_chFamilyType); + oBuffer.ReadByte(m_chSerifStyle); + m_shWeight = oBuffer.ReadByte(); + m_shPropotion = oBuffer.ReadByte(); + m_shContrast = oBuffer.ReadByte(); + m_shStrokeVariation = oBuffer.ReadByte(); + m_shArmStyle = oBuffer.ReadByte(); + m_shLetterform = oBuffer.ReadByte(); + m_shMidLine = oBuffer.ReadByte(); + m_shXHeight = oBuffer.ReadByte(); + } + + if (m_bBasicFaceExists) + oBuffer.ReadString(m_sBasicFaceName, EStringCharacter::UTF16); +} + +CHWPRecordFaceName::CHWPRecordFaceName(CHWPDocInfo& oDocInfo, CXMLNode& oNode, int nVersion) + : CHWPRecord(EHWPTag::HWPTAG_FACE_NAME, 0, 0), m_pParent(&oDocInfo) +{ + m_sFaceName = oNode.GetAttribute(L"face"); + + for (CXMLNode& oChild: oNode.GetChilds()) + { + if (L"hh:substFont" == oChild.GetName()) + { + m_bSubstExists = true; + m_sSubstFace = oChild.GetAttribute(L"face"); + + HWP_STRING sType = oChild.GetAttribute(L"type"); + + if (L"TTF" == sType) + m_eSubstType = EAltType::FFT; + else if (L"HFT" == sType) + m_eSubstType = EAltType::HFT; + else + m_eSubstType = EAltType::UNKNOWN; + } + else if (L"hh:typeInfo" == oChild.GetName()) + { + m_bAttrExists = true; + + m_sBasicFaceName = oChild.GetAttribute(L"familyType"); + + if (!m_sBasicFaceName.empty()) + m_bBasicFaceExists = true; + + m_chSerifStyle = (HWP_BYTE)oChild.GetAttributeInt(L"serifStyle"); + m_shWeight = oChild.GetAttributeInt(L"weight"); + m_shPropotion = oChild.GetAttributeInt(L"proportion"); + m_shContrast = oChild.GetAttributeInt(L"contrast"); + m_shStrokeVariation = oChild.GetAttributeInt(L"strokeVariation"); + m_shArmStyle = oChild.GetAttributeInt(L"armStyle"); + m_shLetterform = oChild.GetAttributeInt(L"letterform"); + m_shMidLine = oChild.GetAttributeInt(L"midline"); + m_shXHeight = oChild.GetAttributeInt(L"xHeight"); + } + } +} + +HWP_STRING CHWPRecordFaceName::GetFaceName() const +{ + return m_sFaceName; +} +} diff --git a/HwpFile/HwpDoc/HWPElements/HWPRecordFaceName.h b/HwpFile/HwpDoc/HWPElements/HWPRecordFaceName.h new file mode 100644 index 00000000000..cad477eb293 --- /dev/null +++ b/HwpFile/HwpDoc/HWPElements/HWPRecordFaceName.h @@ -0,0 +1,49 @@ +#ifndef HWPRECORDFACENAME_H +#define HWPRECORDFACENAME_H + +#include "../Common/XMLNode.h" +#include "../HWPDocInfo.h" +#include "../HWPStream.h" +#include "HWPRecord.h" + +namespace HWP +{ + +enum class EAltType +{ + UNKNOWN, + FFT, + HFT +}; + +class CHWPRecordFaceName : public CHWPRecord +{ + CHWPDocInfo *m_pParent; + + bool m_bBasicFaceExists; + bool m_bAttrExists; + bool m_bSubstExists; + + HWP_STRING m_sFaceName; + EAltType m_eSubstType; + HWP_STRING m_sSubstFace; + HWP_STRING m_sBasicFaceName; + + HWP_BYTE m_chFamilyType; + HWP_BYTE m_chSerifStyle; + short m_shWeight; + short m_shPropotion; + short m_shContrast; + short m_shStrokeVariation; + short m_shArmStyle; + short m_shLetterform; + short m_shMidLine; + short m_shXHeight; +public: + CHWPRecordFaceName(CHWPDocInfo& oDocInfo, int nTagNum, int nLevel, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); + CHWPRecordFaceName(CHWPDocInfo& oDocInfo, CXMLNode& oNode, int nVersion); + + HWP_STRING GetFaceName() const; +}; +} +#endif // HWPRECORDFACENAME_H diff --git a/HwpFile/HwpDoc/HWPElements/HWPRecordFormObject.cpp b/HwpFile/HwpDoc/HWPElements/HWPRecordFormObject.cpp new file mode 100644 index 00000000000..59e3900b166 --- /dev/null +++ b/HwpFile/HwpDoc/HWPElements/HWPRecordFormObject.cpp @@ -0,0 +1,23 @@ +#include "HWPRecordFormObject.h" + +namespace HWP +{ +CHWPRecordFormObject::CHWPRecordFormObject(int nTagNum, int nLevel, int nSize) + : CHWPRecord(nTagNum, nLevel, nSize) +{} + +int CHWPRecordFormObject::ParseCtrl(CCtrlForm& oForm, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) +{ + oBuffer.SavePosition(); + + oBuffer.Skip(4); // tbp+ + oBuffer.Skip(4); // tbp+ + oBuffer.Skip(4); // Длина строки? + + short shLen = oBuffer.ReadShort() * 2; + oBuffer.Skip(shLen); + // oBuffer.ReadString(m_sFormStr, EStringCharacter::UTF16); + + return oBuffer.GetDistanceToLastPos(true); +} +} diff --git a/HwpFile/HwpDoc/HWPElements/HWPRecordFormObject.h b/HwpFile/HwpDoc/HWPElements/HWPRecordFormObject.h new file mode 100644 index 00000000000..4d456d2a116 --- /dev/null +++ b/HwpFile/HwpDoc/HWPElements/HWPRecordFormObject.h @@ -0,0 +1,19 @@ +#ifndef HWPRECORDFORMOBJECT_H +#define HWPRECORDFORMOBJECT_H + +#include "../Paragraph/CtrlForm.h" +#include "HWPRecord.h" + +namespace HWP +{ +class CHWPRecordFormObject : public CHWPRecord +{ + static HWP_STRING m_sFormStr; +public: + CHWPRecordFormObject(int nTagNum, int nLevel, int nSize); + + static int ParseCtrl(CCtrlForm& oForm, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); +}; +} + +#endif // HWPRECORDFORMOBJECT_H diff --git a/HwpFile/HwpDoc/HWPElements/HWPRecordIDMaping.cpp b/HwpFile/HwpDoc/HWPElements/HWPRecordIDMaping.cpp new file mode 100644 index 00000000000..1f8f3c58899 --- /dev/null +++ b/HwpFile/HwpDoc/HWPElements/HWPRecordIDMaping.cpp @@ -0,0 +1,49 @@ +#include "HWPRecordIDMaping.h" +#include "../HWPFile.h" +#include "../OLEdoc/CompoundFile.h" + +namespace HWP +{ + +EIndex GetIndex(int nValue) +{ + switch(static_cast(nValue)) + { + case EIndex::BIN_DATA: + case EIndex::FACENAME_HANGUL: + case EIndex::FACENAME_ENGLISH: + case EIndex::FACENAME_CHINESE: + case EIndex::FACENAME_JAPANESE: + case EIndex::FACENAME_ETC: + case EIndex::FACENAME_SYMBOL: + case EIndex::FACENAME_USER: + case EIndex::BORDER_FILL: + case EIndex::HWP_CHAR_SHAPE: + case EIndex::TAB_DEF: + case EIndex::NUMBERING: + case EIndex::BULLET: + case EIndex::PARA_SHAPE: + case EIndex::STYLE: + case EIndex::MEMO_SHAPE: + case EIndex::TRACK_CHANGE: + case EIndex::TRACK_CHANGE_USER: + case EIndex::MAX: + return static_cast(nValue); + default: + return EIndex::null; + } +} + +CHWPRecordIDMaping::CHWPRecordIDMaping(CHWPDocInfo& oDocInfo, int nTagNum, int nLevel, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) + : CHWPRecord(nTagNum, nLevel, nSize), m_pParent(&oDocInfo) +{ + for (int nIndex = 0; nIndex < (nSize / 4); ++nIndex) + { + int nCount; + oBuffer.ReadInt(nCount); + m_arIdMappingNum.push_back(nCount); + + m_arCounts[nIndex] = nCount; + } +} +} diff --git a/HwpFile/HwpDoc/HWPElements/HWPRecordIDMaping.h b/HwpFile/HwpDoc/HWPElements/HWPRecordIDMaping.h new file mode 100644 index 00000000000..4e7f44b6da7 --- /dev/null +++ b/HwpFile/HwpDoc/HWPElements/HWPRecordIDMaping.h @@ -0,0 +1,47 @@ +#ifndef HWPRECORDIDMAPING_H +#define HWPRECORDIDMAPING_H + +#include "HwpDoc/HWPDocInfo.h" +#include "../HWPStream.h" +#include "HWPRecord.h" +#include + +namespace HWP +{ +enum class EIndex +{ + BIN_DATA, + FACENAME_HANGUL, + FACENAME_ENGLISH, + FACENAME_CHINESE, + FACENAME_JAPANESE, + FACENAME_ETC, + FACENAME_SYMBOL, + FACENAME_USER, + BORDER_FILL, + HWP_CHAR_SHAPE, + TAB_DEF, + NUMBERING, + BULLET, + PARA_SHAPE, + STYLE, + MEMO_SHAPE, + TRACK_CHANGE, + TRACK_CHANGE_USER, + MAX, + null +}; + +class CHWPRecordIDMaping : public CHWPRecord +{ + CHWPDocInfo *m_pParent; + LIST m_arIdMappingNum; + + int m_arCounts[static_cast(EIndex::MAX)]; + +public: + CHWPRecordIDMaping(CHWPDocInfo& oDocInfo, int nTagNum, int nLevel, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); +}; +} + +#endif // HWPRECORDIDMAPING_H diff --git a/HwpFile/HwpDoc/HWPElements/HWPRecordListHeader.cpp b/HwpFile/HwpDoc/HWPElements/HWPRecordListHeader.cpp new file mode 100644 index 00000000000..f522f397065 --- /dev/null +++ b/HwpFile/HwpDoc/HWPElements/HWPRecordListHeader.cpp @@ -0,0 +1,26 @@ +#include "HWPRecordListHeader.h" + +namespace HWP +{ +CHWPRecordListHeader::CHWPRecordListHeader(int nTagNum, int nLevel, int nSize) + : CHWPRecord(nTagNum, nLevel, nSize) +{} + +int CHWPRecordListHeader::GetCount(int nTagNum, int nLevel, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) +{ + short m_shParas; + oBuffer.ReadShort(m_shParas); + oBuffer.Skip(4); + + return m_shParas; +} + +EVertAlign CHWPRecordListHeader::GetVertAlign(int nSize, CHWPStream& oBuffer, int nOff, int nVersion) +{ + oBuffer.Skip(2); + int nAttr; + oBuffer.ReadInt(nAttr); + + return HWP::GetVertAlign((nAttr >> 21) & 0x03); +} +} diff --git a/HwpFile/HwpDoc/HWPElements/HWPRecordListHeader.h b/HwpFile/HwpDoc/HWPElements/HWPRecordListHeader.h new file mode 100644 index 00000000000..5f31b5599c6 --- /dev/null +++ b/HwpFile/HwpDoc/HWPElements/HWPRecordListHeader.h @@ -0,0 +1,20 @@ +#ifndef HWPRECORDLISTHEADER_H +#define HWPRECORDLISTHEADER_H + +#include "HWPRecord.h" +#include "../HWPStream.h" +#include "../Paragraph/CtrlCommon.h" + +namespace HWP +{ +class CHWPRecordListHeader : public CHWPRecord +{ +public: + CHWPRecordListHeader(int nTagNum, int nLevel, int nSize); + + static int GetCount(int nTagNum, int nLevel, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); + static EVertAlign GetVertAlign(int nSize, CHWPStream& oBuffer, int nOff, int nVersion); +}; +} + +#endif // HWPRECORDLISTHEADER_H diff --git a/HwpFile/HwpDoc/HWPElements/HWPRecordNumbering.cpp b/HwpFile/HwpDoc/HWPElements/HWPRecordNumbering.cpp new file mode 100644 index 00000000000..76ad9df2680 --- /dev/null +++ b/HwpFile/HwpDoc/HWPElements/HWPRecordNumbering.cpp @@ -0,0 +1,229 @@ +#include "HWPRecordNumbering.h" + +namespace HWP +{ +CHWPRecordNumbering::CHWPRecordNumbering(CHWPDocInfo& oDocInfo, int nTagNum, int nLevel, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) + : CHWPRecord(nTagNum, nLevel, nSize), m_pParent(&oDocInfo) +{ + oBuffer.SavePosition(); + + for (int nIndex = 0; nIndex < 7; ++nIndex) + { + int nTypeBits; + oBuffer.ReadInt(nTypeBits); + + m_arNumbering[nIndex].m_chAlign = (HWP_BYTE)(nTypeBits & 0x03); + m_arNumbering[nIndex].m_bUseInstWidth = CHECK_FLAG(nTypeBits, 0x40); + m_arNumbering[nIndex].m_bAutoIndent = CHECK_FLAG(nTypeBits, 0x80); + m_arNumbering[nIndex].m_chTextOffsetType = (HWP_BYTE)((nTypeBits >> 4) & 0x01); + + oBuffer.ReadShort(m_arNumbering[nIndex].m_shWidthAdjust); + oBuffer.ReadShort(m_arNumbering[nIndex].m_shTextOffset); + oBuffer.ReadInt(m_arNumbering[nIndex].m_nCharShape); + oBuffer.ReadString(m_arNumbering[nIndex].m_sNumFormat, EStringCharacter::UTF16); + } + + oBuffer.ReadShort(m_shStart); + + if (nVersion > 5025 && (nSize > oBuffer.GetDistanceToLastPos())) //TODO:: добавить проверку offset-off < size + { + for (int nIndex = 0; nIndex < 7; ++nIndex) + oBuffer.ReadInt(m_arNumbering[nIndex].m_nStartNumber); + } + + if (nVersion > 5100 && (nSize > oBuffer.GetDistanceToLastPos())) //TODO:: добавить проверку offset-off < size + { + for (int nIndex = 0; nIndex < 3; ++nIndex) + { + //Содержимое неизвестно, но оно содержит 8 байт. + oBuffer.Skip(8); + + //Содержимое неизвестно, но оно содержит 4 байт. + oBuffer.Skip(4); + + short shLen; + oBuffer.ReadShort(shLen); + + oBuffer.Skip(shLen); + } + + for (int nIndex = 0; nIndex < 3; ++nIndex) + oBuffer.ReadInt(m_arExtLevelStart[nIndex]); + } + + oBuffer.RemoveLastSavedPos(); +} + +CHWPRecordNumbering::CHWPRecordNumbering(CHWPDocInfo& oDocInfo, CXMLNode& oNode, int nVersion) + : CHWPRecord(EHWPTag::HWPTAG_NUMBERING, 0, 0), m_pParent(&oDocInfo) +{ + m_shStart = oNode.GetAttributeInt(L"start", 1); + + unsigned int unIndex = 0; + HWP_STRING sType; + + for (CXMLNode& oChild : oNode.GetChilds()) + { + if (L"hh:paraHead" == oChild.GetName() || + L"paraHead" == oChild.GetName()) + { + sType = oChild.GetAttribute(L"align"); + + if (L"LEFT" == sType) + m_arNumbering[unIndex].m_chAlign = 0; + else if (L"CENTER" == sType) + m_arNumbering[unIndex].m_chAlign = 1; + else if (L"RIGHT" == sType) + m_arNumbering[unIndex].m_chAlign = 2; + + m_arNumbering[unIndex].m_bUseInstWidth = oChild.GetAttributeBool(L"useInstWidth"); + m_arNumbering[unIndex].m_bAutoIndent = oChild.GetAttributeBool(L"autoIndent"); + m_arNumbering[unIndex].m_shWidthAdjust = oChild.GetAttributeInt(L"widthAdjust"); + + sType = oChild.GetAttribute(L"textOffsetType"); + + if (L"PERCENT" == sType) + m_arNumbering[unIndex].m_chTextOffsetType = 0; + else if (L"HWPUNIT" == sType) + m_arNumbering[unIndex].m_chTextOffsetType = 1; + + m_arNumbering[unIndex].m_shTextOffset = oChild.GetAttributeInt(L"textOffset"); + + short shLevel = oChild.GetAttributeInt(L"level"); + + sType = oChild.GetAttribute(L"numFormat"); + + if (L"DIGIT" == sType) + { + if (shLevel > 0 && shLevel < 11) + m_arNumbering[unIndex].m_sNumFormat = L'^' + std::to_wstring(shLevel) + L'.'; + } + else if (L"HANGUL_SYLLABLE" == sType || + L"HANGUL_JAMO" == sType) + { + switch (shLevel) + { + case 1: m_arNumbering[unIndex].m_sNumFormat = L"^가."; break; + case 2: m_arNumbering[unIndex].m_sNumFormat = L"^나."; break; + case 3: m_arNumbering[unIndex].m_sNumFormat = L"^다."; break; + case 4: m_arNumbering[unIndex].m_sNumFormat = L"^라."; break; + case 5: m_arNumbering[unIndex].m_sNumFormat = L"^마."; break; + case 6: m_arNumbering[unIndex].m_sNumFormat = L"^바."; break; + case 7: m_arNumbering[unIndex].m_sNumFormat = L"^사."; break; + case 8: m_arNumbering[unIndex].m_sNumFormat = L"^아."; break; + case 9: m_arNumbering[unIndex].m_sNumFormat = L"^자."; break; + case 10: m_arNumbering[unIndex].m_sNumFormat = L"^차."; break; + } + } + else if (L"CIRCLED_DIGIT" == sType) + { + switch (shLevel) + { + case 1: m_arNumbering[unIndex].m_sNumFormat = L"^\u2460."; break; + case 2: m_arNumbering[unIndex].m_sNumFormat = L"^\u2461."; break; + case 3: m_arNumbering[unIndex].m_sNumFormat = L"^\u2462."; break; + case 4: m_arNumbering[unIndex].m_sNumFormat = L"^\u2463."; break; + case 5: m_arNumbering[unIndex].m_sNumFormat = L"^\u2464."; break; + case 6: m_arNumbering[unIndex].m_sNumFormat = L"^\u2465."; break; + case 7: m_arNumbering[unIndex].m_sNumFormat = L"^\u2466."; break; + case 8: m_arNumbering[unIndex].m_sNumFormat = L"^\u2467."; break; + case 9: m_arNumbering[unIndex].m_sNumFormat = L"^\u2468."; break; + case 10: m_arNumbering[unIndex].m_sNumFormat = L"^\u2469."; break; + } + } + else if (L"LATIN_SMALL" == sType) + { + switch (shLevel) + { + case 1: m_arNumbering[unIndex].m_sNumFormat = L"^a."; break; + case 2: m_arNumbering[unIndex].m_sNumFormat = L"^b."; break; + case 3: m_arNumbering[unIndex].m_sNumFormat = L"^c."; break; + case 4: m_arNumbering[unIndex].m_sNumFormat = L"^d."; break; + case 5: m_arNumbering[unIndex].m_sNumFormat = L"^e."; break; + case 6: m_arNumbering[unIndex].m_sNumFormat = L"^f."; break; + case 7: m_arNumbering[unIndex].m_sNumFormat = L"^g."; break; + case 8: m_arNumbering[unIndex].m_sNumFormat = L"^h."; break; + case 9: m_arNumbering[unIndex].m_sNumFormat = L"^i."; break; + case 10: m_arNumbering[unIndex].m_sNumFormat = L"^j."; break; + } + } + else if (L"CIRCLED_HANGUL_SYLLABLE" == sType) + { + switch (shLevel) + { + case 1: m_arNumbering[unIndex].m_sNumFormat = L"^\u326E."; break; + case 2: m_arNumbering[unIndex].m_sNumFormat = L"^\u326F."; break; + case 3: m_arNumbering[unIndex].m_sNumFormat = L"^\u3270."; break; + case 4: m_arNumbering[unIndex].m_sNumFormat = L"^\u3271."; break; + case 5: m_arNumbering[unIndex].m_sNumFormat = L"^\u3272."; break; + case 6: m_arNumbering[unIndex].m_sNumFormat = L"^\u3273."; break; + case 7: m_arNumbering[unIndex].m_sNumFormat = L"^\u3274."; break; + case 8: m_arNumbering[unIndex].m_sNumFormat = L"^\u3275."; break; + case 9: m_arNumbering[unIndex].m_sNumFormat = L"^\u3276."; break; + case 10: m_arNumbering[unIndex].m_sNumFormat = L"^\u3277."; break; + } + } + else if (L"ROMAN_SMALL" == sType) + { + switch (shLevel) + { + case 1: m_arNumbering[unIndex].m_sNumFormat = L"^\u2170."; break; + case 2: m_arNumbering[unIndex].m_sNumFormat = L"^\u2171."; break; + case 3: m_arNumbering[unIndex].m_sNumFormat = L"^\u2172."; break; + case 4: m_arNumbering[unIndex].m_sNumFormat = L"^\u2173."; break; + case 5: m_arNumbering[unIndex].m_sNumFormat = L"^\u2174."; break; + case 6: m_arNumbering[unIndex].m_sNumFormat = L"^\u2175."; break; + case 7: m_arNumbering[unIndex].m_sNumFormat = L"^\u2176."; break; + case 8: m_arNumbering[unIndex].m_sNumFormat = L"^\u2177."; break; + case 9: m_arNumbering[unIndex].m_sNumFormat = L"^\u2178."; break; + case 10: m_arNumbering[unIndex].m_sNumFormat = L"^\u2179."; break; + } + } + + m_arNumbering[unIndex].m_nCharShape = std::abs(oChild.GetAttributeInt(L"charPrIDRef")); + m_arNumbering[unIndex].m_nStartNumber = oChild.GetAttributeInt(L"start"); + ++unIndex; + } + + if (7 == unIndex) + return; + } +} + +short CHWPRecordNumbering::GetStart() const +{ + return m_shStart; +} + +HWP_STRING CHWPRecordNumbering::GetNumFormat(unsigned short ushIndex) const +{ + if (ushIndex >= 7) + return HWP_STRING(); + + return m_arNumbering[ushIndex].m_sNumFormat; +} + +HWP_BYTE CHWPRecordNumbering::GetAlign(unsigned short ushIndex) const +{ + if (ushIndex >= 7) + return 0; + + return m_arNumbering[ushIndex].m_chAlign; +} + +int CHWPRecordNumbering::GetStartNumber(unsigned short ushIndex) const +{ + if (ushIndex >= 7) + return 0; + + return m_arNumbering[ushIndex].m_nStartNumber; +} + +int CHWPRecordNumbering::GetCharShape(unsigned short ushIndex) const +{ + if (ushIndex >= 7) + return 0; + + return m_arNumbering[ushIndex].m_nCharShape; +} +} diff --git a/HwpFile/HwpDoc/HWPElements/HWPRecordNumbering.h b/HwpFile/HwpDoc/HWPElements/HWPRecordNumbering.h new file mode 100644 index 00000000000..6798cad30ae --- /dev/null +++ b/HwpFile/HwpDoc/HWPElements/HWPRecordNumbering.h @@ -0,0 +1,49 @@ +#ifndef HWPRECORDNUMBERING_H +#define HWPRECORDNUMBERING_H + +#include "../HWPDocInfo.h" +#include "../HWPStream.h" +#include "HWPRecord.h" +#include "../Common/XMLNode.h" + +namespace HWP +{ + +struct TParaHeadInfo +{ + HWP_BYTE m_chAlign; + bool m_bUseInstWidth; + bool m_bAutoIndent; + HWP_BYTE m_chTextOffsetType; + short m_shWidthAdjust; + short m_shTextOffset; + int m_nCharShape; + int m_nStartNumber; +}; + +struct TNumbering : public TParaHeadInfo +{ + HWP_STRING m_sNumFormat; +}; + +class CHWPRecordNumbering : public CHWPRecord +{ + CHWPDocInfo *m_pParent; + + TNumbering m_arNumbering[7]; + short m_shStart; + HWP_STRING m_arExtLevelFormat[3]; + int m_arExtLevelStart[3]; +public: + CHWPRecordNumbering(CHWPDocInfo& oDocInfo, int nTagNum, int nLevel, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); + CHWPRecordNumbering(CHWPDocInfo& oDocInfo, CXMLNode& oNode, int nVersion); + + short GetStart() const; + HWP_STRING GetNumFormat(unsigned short ushIndex) const; + HWP_BYTE GetAlign(unsigned short ushIndex) const; + int GetStartNumber(unsigned short ushIndex) const; + int GetCharShape(unsigned short ushIndex) const; +}; +} + +#endif // HWPRECORDNUMBERING_H diff --git a/HwpFile/HwpDoc/HWPElements/HWPRecordParaRangeTag.cpp b/HwpFile/HwpDoc/HWPElements/HWPRecordParaRangeTag.cpp new file mode 100644 index 00000000000..47d31da633f --- /dev/null +++ b/HwpFile/HwpDoc/HWPElements/HWPRecordParaRangeTag.cpp @@ -0,0 +1,32 @@ +#include "HWPRecordParaRangeTag.h" +#include "../Paragraph/RangeTag.h" + +namespace HWP +{ +CHWPRecordParaRangeTag::CHWPRecordParaRangeTag(int nTagNum, int nLevel, int nSize) + : CHWPRecord(nTagNum, nLevel, nSize) +{} + +int CHWPRecordParaRangeTag::Parse(CHWPPargraph& oPara, int nTagNum, int nLevel, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) +{ + oBuffer.SavePosition(); + + while (nSize - oBuffer.GetDistanceToLastPos() >= 12) + { + TRangeTag oRangeTag; + + oBuffer.ReadInt(oRangeTag.m_nStartPos); + oBuffer.ReadInt(oRangeTag.m_nEndPos); + + for (unsigned short ushIndex = 0; ushIndex < 3; ++ushIndex) + oBuffer.ReadByte(oRangeTag.m_arData[ushIndex]); + + oBuffer.ReadByte(oRangeTag.m_chType); + + oPara.AddRangeTag(oRangeTag); + } + + oBuffer.Skip(nSize - oBuffer.GetDistanceToLastPos(true)); + return nSize; +} +} diff --git a/HwpFile/HwpDoc/HWPElements/HWPRecordParaRangeTag.h b/HwpFile/HwpDoc/HWPElements/HWPRecordParaRangeTag.h new file mode 100644 index 00000000000..a833c9ea1c0 --- /dev/null +++ b/HwpFile/HwpDoc/HWPElements/HWPRecordParaRangeTag.h @@ -0,0 +1,18 @@ +#ifndef HWPRECORDPARARANGETAG_H +#define HWPRECORDPARARANGETAG_H + +#include "HWPRecord.h" +#include "../Paragraph/HWPPargraph.h" + +namespace HWP +{ +class CHWPRecordParaRangeTag : public CHWPRecord +{ +public: + CHWPRecordParaRangeTag(int nTagNum, int nLevel, int nSize); + + static int Parse(CHWPPargraph& oPara, int nTagNum, int nLevel, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); +}; +} + +#endif // HWPRECORDPARARANGETAG_H diff --git a/HwpFile/HwpDoc/HWPElements/HWPRecordParaShape.cpp b/HwpFile/HwpDoc/HWPElements/HWPRecordParaShape.cpp new file mode 100644 index 00000000000..42b5e4a7901 --- /dev/null +++ b/HwpFile/HwpDoc/HWPElements/HWPRecordParaShape.cpp @@ -0,0 +1,300 @@ +#include "HWPRecordParaShape.h" + +namespace HWP +{ +EHeadingType GetHeadingType(int nValue) +{ + SWITCH(EHeadingType, nValue) + { + CASE(EHeadingType::OUTLINE); + CASE(EHeadingType::NUMBER); + CASE(EHeadingType::BULLET); + DEFAULT(EHeadingType::NONE); + } +} + +EHeadingType GetHeadingType(const HWP_STRING& sValue) +{ + IF_STRING_IN_ENUM(OUTLINE, sValue, EHeadingType); + ELSE_IF_STRING_IN_ENUM(NUMBER, sValue, EHeadingType); + ELSE_IF_STRING_IN_ENUM(BULLET, sValue, EHeadingType); + ELSE_STRING_IN_ENUM(NONE, EHeadingType); +} + +EHorizontalAlign GetHorizontalAlign(int nValue) +{ + SWITCH(EHorizontalAlign, nValue) + { + CASE(EHorizontalAlign::LEFT); + CASE(EHorizontalAlign::RIGHT); + CASE(EHorizontalAlign::CENTER); + CASE(EHorizontalAlign::DISTRIBUTE); + CASE(EHorizontalAlign::DISTRIBUTE_SPACE); + DEFAULT(EHorizontalAlign::JUSTIFY); + } +} + +EHorizontalAlign GetHorizontalAlign(const HWP_STRING& sValue) +{ + IF_STRING_IN_ENUM(RIGHT, sValue, EHorizontalAlign); + ELSE_IF_STRING_IN_ENUM(CENTER, sValue, EHorizontalAlign); + ELSE_IF_STRING_IN_ENUM(DISTRIBUTE, sValue, EHorizontalAlign); + ELSE_IF_STRING_IN_ENUM(DISTRIBUTE_SPACE, sValue, EHorizontalAlign); + ELSE_IF_STRING_IN_ENUM(JUSTIFY, sValue, EHorizontalAlign); + ELSE_STRING_IN_ENUM(LEFT, EHorizontalAlign); +} + +EVerticalAlign GetVerticalAlign(int nValue) +{ + SWITCH(EVerticalAlign, nValue) + { + CASE(EVerticalAlign::TOP); + CASE(EVerticalAlign::CENTER); + CASE(EVerticalAlign::BOTTOM); + DEFAULT(EVerticalAlign::BASELINE); + } +} + +EVerticalAlign GetVerticalAlign(const HWP_STRING& sValue) +{ + IF_STRING_IN_ENUM(CENTER, sValue, EVerticalAlign); + ELSE_IF_STRING_IN_ENUM(BOTTOM, sValue, EVerticalAlign); + ELSE_IF_STRING_IN_ENUM(BASELINE, sValue, EVerticalAlign); + ELSE_STRING_IN_ENUM(TOP, EVerticalAlign); +} + +CHWPRecordParaShape::CHWPRecordParaShape(CHWPDocInfo& oDocInfo, int nTagNum, int nLevel, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) + : CHWPRecord(nTagNum, nLevel, nSize), m_pParent(&oDocInfo) +{ + int nTypeBits; + oBuffer.ReadInt(nTypeBits); + + m_eAlign = GetHorizontalAlign((nTypeBits >> 2) & 0x07); + m_chBreakLatinWord = (HWP_BYTE)((nTypeBits >> 5) & 0x03); + m_chBreakNonLatinWord = (HWP_BYTE)((nTypeBits >> 7) & 0x01); + m_bSnapToGrid = CHECK_FLAG(nTypeBits, 0x80); + m_chCondense = (HWP_BYTE)((nTypeBits >> 9) & 0x7F); + m_bWidowOrphan = CHECK_FLAG(nTypeBits, 0x10000); + m_bKeepWithNext = CHECK_FLAG(nTypeBits, 0x20000); + m_bPageBreakBefore = CHECK_FLAG(nTypeBits, 0x40000); + m_eVertAlign = ::HWP::GetVerticalAlign((nTypeBits >> 20) & 0x03); + m_bFontLineHeight = CHECK_FLAG(nTypeBits, 0x100000); + m_eHeadingType = ::HWP::GetHeadingType((nTypeBits >> 23) & 0x03); + m_chHeadingLevel = (HWP_BYTE)((nTypeBits >> 25) & 0x07); + m_bConnect = CHECK_FLAG(nTypeBits, 0x800000); + m_bIgnoreMargin = CHECK_FLAG(nTypeBits, 0x1000000); + m_bParaTailShape = CHECK_FLAG(nTypeBits, 0x2000000); + + oBuffer.ReadInt(m_nMarginLeft); + oBuffer.ReadInt(m_nMarginRight); + oBuffer.ReadInt(m_nIndent); + oBuffer.ReadInt(m_nMarginPrev); + oBuffer.ReadInt(m_nMarginNext); + + if (nVersion < 5025) + { + m_nLineSpacingType = (HWP_BYTE)(nTypeBits & 0x03); + oBuffer.ReadInt(m_nLineSpacing); + } + else + oBuffer.Skip(4); + + oBuffer.ReadShort(m_shTabDef); + oBuffer.ReadShort(m_shHeadingIdRef); + oBuffer.ReadShort(m_shBorderFill); + oBuffer.ReadShort(m_shOffsetLeft); + oBuffer.ReadShort(m_shOffsetRight); + oBuffer.ReadShort(m_shOffsetTop); + oBuffer.ReadShort(m_shOffsetBottom); + + if (nVersion >= 5017) + { + int nAttrBits; + oBuffer.ReadInt(nAttrBits); + + m_chLineWrap = (HWP_BYTE)(nAttrBits & 0x03); + m_bAutoSpaceEAsianEng = CHECK_FLAG(nAttrBits, 0x10); + m_bAutoSpaceEAsianNum = CHECK_FLAG(nAttrBits, 0x20); + } + else + oBuffer.Skip(4); + + if (nVersion >= 5025) + { + int nAttrBits; + oBuffer.ReadInt(nAttrBits); + + m_nLineSpacingType = (HWP_BYTE)(nAttrBits & 0x0F); + oBuffer.ReadInt(m_nLineSpacing); + } + else + oBuffer.Skip(8); +} + +CHWPRecordParaShape::CHWPRecordParaShape(CHWPDocInfo& oDocInfo, CXMLNode& oNode, int nVersion) + : CHWPRecord(EHWPTag::HWPTAG_PARA_SHAPE, 0, 0), m_pParent(&oDocInfo), + m_eAlign(EHorizontalAlign::JUSTIFY), m_bWidowOrphan(false), m_bKeepWithNext(false), + m_bPageBreakBefore(false), m_eVertAlign(EVerticalAlign::BASELINE), m_eHeadingType(EHeadingType::NONE), + m_bConnect(false), m_bIgnoreMargin(false), m_bParaTailShape(false) +{ + m_shTabDef = oNode.GetAttributeInt(L"tabPrIDRef"); + m_chCondense = (HWP_BYTE)oNode.GetAttributeInt(L"condense"); + + m_bFontLineHeight = oNode.GetAttributeBool(L"fontLineHeight"); + m_bSnapToGrid = oNode.GetAttributeBool(L"snapToGrid"); + + for (CXMLNode& oChild : oNode.GetChilds()) + RecursiveParaShape(oChild); +} + +void CHWPRecordParaShape::RecursiveParaShape(CXMLNode& oNode) +{ + if (L"hh:align" == oNode.GetName()) + { + m_eAlign = ::HWP::GetHorizontalAlign(oNode.GetAttribute(L"horizontal")); + m_eVertAlign = ::HWP::GetVerticalAlign(oNode.GetAttribute(L"vertical")); + } + else if (L"hh:heading" == oNode.GetName()) + { + m_eHeadingType = ::HWP::GetHeadingType(oNode.GetAttribute(L"type")); + m_shHeadingIdRef = oNode.GetAttributeInt(L"idRef"); + m_chHeadingLevel = (HWP_BYTE)oNode.GetAttributeInt(L"level"); + } + else if (L"hh:breakSetting" == oNode.GetName()) + { + HWP_STRING sType = oNode.GetAttribute(L"breakLatinWord"); + + if (L"KEEP_WORD" == sType) + m_chBreakLatinWord = 0; + else if (L"BREAK_WORD" == sType) + m_chBreakLatinWord = 1; + + sType = oNode.GetAttribute(L"breakNonLatinWord"); + + if (L"KEEP_WORD" == sType) + m_chBreakNonLatinWord = 0; + else if (L"BREAK_WORD" == sType) + m_chBreakNonLatinWord = 1; + + m_bWidowOrphan = oNode.GetAttributeBool(L"widowOrphan"); + m_bKeepWithNext = oNode.GetAttributeBool(L"keepWithNext"); + m_bPageBreakBefore = oNode.GetAttributeBool(L"pageBreakBefore"); + + sType = oNode.GetAttribute(L"lineWrap"); + + if (L"BREAK" == sType) + m_chLineWrap = 0; + else if (L"SQUEEZE" == sType) + m_chLineWrap = 1; + } + else if (L"hh:lineSpacing" == oNode.GetName()) + { + HWP_STRING sType = oNode.GetAttribute(L"type"); + + if (L"PERCENT" == sType) + m_nLineSpacingType = 0; + else if (L"FIXED" == sType) + m_nLineSpacingType = 1; + else if (L"BETWEENLINES" == sType) + m_nLineSpacingType = 2; + else if (L"AT_LEAST" == sType) + m_nLineSpacingType = 4; + + m_nLineSpacing = oNode.GetAttributeInt(L"value"); + } + else if (L"hh:border" == oNode.GetName()) + { + m_shBorderFill = oNode.GetAttributeInt(L"borderFillIDRef"); + m_shOffsetLeft = oNode.GetAttributeInt(L"offsetLeft"); + m_shOffsetRight = oNode.GetAttributeInt(L"offsetRight"); + m_shOffsetTop = oNode.GetAttributeInt(L"offsetTop"); + m_shOffsetBottom = oNode.GetAttributeInt(L"offsetBottom"); + + m_bConnect = oNode.GetAttributeBool(L"connect"); + m_bIgnoreMargin = oNode.GetAttributeBool(L"ignoreMargin"); + } + else if (L"hh:autoSpacing" == oNode.GetName()) + { + m_bAutoSpaceEAsianEng = oNode.GetAttributeBool(L"eAsianEng"); + m_bAutoSpaceEAsianNum = oNode.GetAttributeBool(L"eAsianNum"); + } + else if (L"hc:intent" == oNode.GetName()) + m_nIndent = oNode.GetAttributeInt(L"value"); + else if (L"hc:left" == oNode.GetName()) + m_nMarginLeft = oNode.GetAttributeInt(L"value"); + else if (L"hc:right" == oNode.GetName()) + m_nMarginRight = oNode.GetAttributeInt(L"value"); + else if (L"hc:prev" == oNode.GetName()) + m_nMarginPrev = oNode.GetAttributeInt(L"value"); + else if (L"hc:next" == oNode.GetName()) + m_nMarginNext = oNode.GetAttributeInt(L"value"); + else if (L"hp:switch" == oNode.GetName() || + L"hp:case" == oNode.GetName() || + L"hp:default" == oNode.GetName() || + L"hh:margin" == oNode.GetName()) + { + for (CXMLNode& oChild : oNode.GetChilds()) + RecursiveParaShape(oChild); + } +} + +EHorizontalAlign CHWPRecordParaShape::GetHorizantalAlign() const +{ + return m_eAlign; +} + +EVerticalAlign CHWPRecordParaShape::GetVerticalAlign() const +{ + return m_eVertAlign; +} + +EHeadingType CHWPRecordParaShape::GetHeadingType() const +{ + return m_eHeadingType; +} + +HWP_BYTE CHWPRecordParaShape::GetHeadingLevel() const +{ + return m_chHeadingLevel; +} + +short CHWPRecordParaShape::GetHeadingIdRef() const +{ + return m_shHeadingIdRef; +} + +bool CHWPRecordParaShape::GetPageBreakBefore() const +{ + return m_bPageBreakBefore; +} + +int CHWPRecordParaShape::GetLineSpacingType() const +{ + return m_nLineSpacingType; +} + +int CHWPRecordParaShape::GetLineSpacing() const +{ + return m_nLineSpacing; +} + +int CHWPRecordParaShape::GetMarginPrev() const +{ + return m_nMarginPrev; +} + +int CHWPRecordParaShape::GetMarginNext() const +{ + return m_nMarginNext; +} + +int CHWPRecordParaShape::GetIndent() const +{ + return m_nIndent; +} + +bool CHWPRecordParaShape::KeepWithNext() const +{ + return m_bKeepWithNext; +} +} diff --git a/HwpFile/HwpDoc/HWPElements/HWPRecordParaShape.h b/HwpFile/HwpDoc/HWPElements/HWPRecordParaShape.h new file mode 100644 index 00000000000..f0498c2ea06 --- /dev/null +++ b/HwpFile/HwpDoc/HWPElements/HWPRecordParaShape.h @@ -0,0 +1,99 @@ +#ifndef HWPRECORDPARASHAPE_H +#define HWPRECORDPARASHAPE_H + +#include "HWPRecord.h" +#include "../HWPDocInfo.h" +#include "../Common/XMLNode.h" + +namespace HWP +{ +enum class EHeadingType +{ + NONE, + OUTLINE, + NUMBER, + BULLET +}; + +enum class EHorizontalAlign +{ + JUSTIFY, + LEFT, + RIGHT, + CENTER, + DISTRIBUTE, + DISTRIBUTE_SPACE +}; + +enum class EVerticalAlign +{ + BASELINE, + TOP, + CENTER, + BOTTOM +}; + +class CHWPRecordParaShape : public CHWPRecord +{ + CHWPDocInfo *m_pParent; + + EHorizontalAlign m_eAlign; + HWP_BYTE m_chBreakLatinWord; + HWP_BYTE m_chBreakNonLatinWord; + bool m_bSnapToGrid; + HWP_BYTE m_chCondense; + bool m_bWidowOrphan; + bool m_bKeepWithNext; + bool m_bPageBreakBefore; + EVerticalAlign m_eVertAlign; + bool m_bFontLineHeight; + EHeadingType m_eHeadingType; + + HWP_BYTE m_chHeadingLevel; + bool m_bConnect; + bool m_bIgnoreMargin; + bool m_bParaTailShape; + + int m_nIndent; + int m_nMarginLeft; + int m_nMarginRight; + int m_nMarginPrev; + int m_nMarginNext; + int m_nLineSpacing; + + short m_shTabDef; + short m_shHeadingIdRef; + short m_shBorderFill; + short m_shOffsetLeft; + short m_shOffsetRight; + short m_shOffsetTop; + short m_shOffsetBottom; + + HWP_BYTE m_chLineWrap; + bool m_bAutoSpaceEAsianEng; + bool m_bAutoSpaceEAsianNum; + + int m_nLineSpacingType; + void RecursiveParaShape(CXMLNode& oNode); +public: + CHWPRecordParaShape(CHWPDocInfo& oDocInfo, int nTagNum, int nLevel, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); + CHWPRecordParaShape(CHWPDocInfo& oDocInfo, CXMLNode& oNode, int nVersion); + + EHorizontalAlign GetHorizantalAlign() const; + EVerticalAlign GetVerticalAlign() const; + EHeadingType GetHeadingType() const; + HWP_BYTE GetHeadingLevel() const; + short GetHeadingIdRef() const; + bool GetPageBreakBefore() const; + int GetLineSpacingType() const; + int GetLineSpacing() const; + int GetMarginPrev() const; + int GetMarginNext() const; + + int GetIndent() const; + + bool KeepWithNext() const; +}; +} + +#endif // HWPRECORDPARASHAPE_H diff --git a/HwpFile/HwpDoc/HWPElements/HWPRecordParaText.cpp b/HwpFile/HwpDoc/HWPElements/HWPRecordParaText.cpp new file mode 100644 index 00000000000..89161d88beb --- /dev/null +++ b/HwpFile/HwpDoc/HWPElements/HWPRecordParaText.cpp @@ -0,0 +1,193 @@ +#include "HWPRecordParaText.h" + +#include "../Paragraph/ParaText.h" +#include "../Paragraph/CtrlCharacter.h" +#include "../Paragraph/CtrlHeadFoot.h" +#include "../Paragraph/CtrlAutoNumber.h" +#include "../Paragraph/CtrlPageNumPos.h" +#include "../Paragraph/CtrlNewNumber.h" +#include "../Paragraph/CtrlSectionDef.h" +#include "../Paragraph/CtrlColumnDef.h" +#include "../Paragraph/CtrlNote.h" +#include "../Paragraph/CtrlGeneralShape.h" +#include "../Paragraph/CtrlTable.h" +#include "../Paragraph/CtrlEqEdit.h" +#include "../Paragraph/CtrlField.h" + +#include + +#include "../../../DesktopEditor/common/File.h" + +namespace HWP +{ +CHWPRecordParaText::CHWPRecordParaText(int nTagNum, int nLevel, int nSize) + : CHWPRecord(nTagNum, nLevel, nSize) +{} + +LIST CHWPRecordParaText::Parse(int nTagNum, int nLevel, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) +{ + oBuffer.SavePosition(); + + HWP_STRING sText; + oBuffer.ReadString(sText, nSize, EStringCharacter::UTF16); + + if (sText.empty()) + { + oBuffer.Skip(nSize - oBuffer.GetDistanceToLastPos(true)); + return LIST(); + } + + //TODO:: перейти на обычный проход по символам + std::wregex oRegex(L"([\\u0000-\\u001f]|.{2}[\\u0000-\\u0017]{4})"); // [\\u0000\\u000a\\u000d\\u0018-\\u001f]|[\\u0001\\u0002-\\u0009\\u000b-\\u000c\\u000e-\\u0017].{6}[\\u0001\\u0002-\\u0009\\u000b-\\u000c\\u000e-\\u0017] + std::wsregex_iterator itCurrent(sText.begin(), sText.end(), oRegex); + std::wsregex_iterator itEnd = std::wsregex_iterator(); + + int nPrevIndex = 0; + + LIST arParas; + + HWP_STRING sCurrentText; + bool bEnd = false; + + #define UPDATE_CURRENT_TEXT() \ + do { \ + if (!sCurrentText.empty() && (unsigned int)sCurrentText[0] > 0x001f) \ + { \ + arParas.push_back(new CParaText(L"____", sCurrentText, nPrevIndex + 1)); \ + sCurrentText.clear(); \ + }} while (false) + + while(itCurrent != itEnd && !bEnd) + { + if (itCurrent->position() > nPrevIndex) + { + // write text + sCurrentText += sText.substr(nPrevIndex, itCurrent->position() - nPrevIndex); + } + + if (1 == itCurrent->length()) + { + switch(itCurrent->str()[0]) + { + case 0x00: + case 0x02: + // case 0x17: + // case 0x19: + { + sCurrentText.clear(); + break; + } + case 0x03: + case 0x04: + { + UPDATE_CURRENT_TEXT(); + break; + } + case 0x08: + { + if (!sCurrentText.empty()) + sCurrentText.pop_back(); + break; + } + case 0x09: + { + sCurrentText.push_back(L'\t'); + break; + } + case 0x0b: + { + sCurrentText.push_back(L'\v'); + break; + } + case 0x0a: + { + UPDATE_CURRENT_TEXT(); + arParas.push_back(new CCtrlCharacter(L" _", ECtrlCharType::LINE_BREAK)); + break; + } + case 0x0d: + { + UPDATE_CURRENT_TEXT(); + arParas.push_back(new CCtrlCharacter(L" _", ECtrlCharType::PARAGRAPH_BREAK)); + break; + } + case 0x18: + { + UPDATE_CURRENT_TEXT(); + arParas.push_back(new CCtrlCharacter(L" _", ECtrlCharType::HARD_HYPHEN)); + break; + } + case 0x1e: + case 0x1f: + { + UPDATE_CURRENT_TEXT(); + arParas.push_back(new CCtrlCharacter(L" _", ECtrlCharType::HARD_SPACE)); + break; + } + } + } + // Пока данный вариант невозможен + else if (6 == itCurrent->length()) + { + UPDATE_CURRENT_TEXT(); + + //TODO:: Проверить + HWP_STRING sInfo = sText.substr(itCurrent->position(), 2); + std::wregex wrReplaceRegex(L"[\\u0000-\\u0017]+$"); + sInfo = std::regex_replace(sInfo, wrReplaceRegex, L""); + + HWP_STRING sType; + sType.resize(4); + + sType[0] = (sInfo[0] & 0xFF); + sType[1] = ((sInfo[0] >> 8) & 0xFF); + sType[2] = (sInfo[1] & 0xFF); + sType[3] = ((sInfo[1] >> 8) & 0xFF); + + if (0x17 >= sType[3]) + sType[3] = L' '; + + //TODO:: более подробно разобраться в данном моменте + if (L"daeh" == sType || + L"tood" == sType) + arParas.push_back(new CCtrlHeadFoot(sType)); + else if (L"onta" == sType) + arParas.push_back(new CCtrlAutoNumber(sType)); + else if (L"pngp" == sType) + arParas.push_back(new CCtrlPageNumPos(sType)); + else if (L"onwn" == sType) + arParas.push_back(new CCtrlNewNumber(sType)); + else if (L"dces" == sType) + arParas.push_back(new CCtrlSectionDef(sType)); + else if (L"dloc" == sType) + arParas.push_back(new CCtrlColumnDef(sType)); + else if (L" nf" == sType || + L" ne" == sType) + arParas.push_back(new CCtrlNote(sType)); + else if (L" osg" == sType) + arParas.push_back(new CCtrlGeneralShape(sType)); + else if (L" lbt" == sType) + arParas.push_back(new CCtrlTable(sType)); + else if (L"deqe" == sType) + arParas.push_back(new CCtrlEqEdit(sType)); + else if (L"klh%" == sType || // hyperlink start + L"klh " == sType || // hyperlink end + L"kmb%" == sType || // bookmark start + L"kmb " == sType) // bookmark end + arParas.push_back(new CCtrlField(sType)); + } + + nPrevIndex = itCurrent->position() + itCurrent->length(); + ++itCurrent; + } + + if (!bEnd) + sCurrentText += sText.substr(nPrevIndex); + + if (!sCurrentText.empty()) + arParas.push_back(new CParaText(L"____", sCurrentText, nPrevIndex + 1)); + + oBuffer.Skip(nSize - oBuffer.GetDistanceToLastPos(true)); + return arParas; +} +} diff --git a/HwpFile/HwpDoc/HWPElements/HWPRecordParaText.h b/HwpFile/HwpDoc/HWPElements/HWPRecordParaText.h new file mode 100644 index 00000000000..ff8b35c30d1 --- /dev/null +++ b/HwpFile/HwpDoc/HWPElements/HWPRecordParaText.h @@ -0,0 +1,19 @@ +#ifndef HWPRECORDPARATEXT_H +#define HWPRECORDPARATEXT_H + +#include "HWPRecord.h" +#include "../HWPStream.h" +#include "../Paragraph/Ctrl.h" + +namespace HWP +{ +class CHWPRecordParaText : public CHWPRecord +{ +public: + CHWPRecordParaText(int nTagNum, int nLevel, int nSize); + + static LIST Parse(int nTagNum, int nLevel, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); +}; +} + +#endif // HWPRECORDPARATEXT_H diff --git a/HwpFile/HwpDoc/HWPElements/HWPRecordStyle.cpp b/HwpFile/HwpDoc/HWPElements/HWPRecordStyle.cpp new file mode 100644 index 00000000000..3b1834cadcd --- /dev/null +++ b/HwpFile/HwpDoc/HWPElements/HWPRecordStyle.cpp @@ -0,0 +1,41 @@ +#include "HWPRecordStyle.h" + +namespace HWP +{ +CHWPRecordStyle::CHWPRecordStyle(int nTagNum, int nLevel, int nSize) + : CHWPRecord(nTagNum, nLevel, nSize), m_pParent(nullptr) +{} + +CHWPRecordStyle::CHWPRecordStyle(CHWPDocInfo& oDocInfo, int nTagNum, int nLevel, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) + : CHWPRecord(nTagNum, nLevel, nSize), m_pParent(&oDocInfo) +{ + oBuffer.ReadString(m_sName, EStringCharacter::UTF16); + oBuffer.ReadString(m_sEngName, EStringCharacter::UTF16); + + m_chType = (HWP_BYTE)(oBuffer.ReadByte() & 0x00FF); + m_chNextStyle = (HWP_BYTE)(oBuffer.ReadByte() & 0x00FF); + + oBuffer.ReadShort(m_shLangID); + m_nParaShape = oBuffer.ReadShort(); + m_nCharShape = oBuffer.ReadShort(); +} + +CHWPRecordStyle::CHWPRecordStyle(CHWPDocInfo& oDocInfo, CXMLNode& oNode, int nVersion) + : CHWPRecord(EHWPTag::HWPTAG_STYLE, 0, 0), m_pParent(&oDocInfo) +{ + HWP_STRING sType = oNode.GetAttribute(L"type"); + + if (L"PARA" == sType) + m_chType = 0; + else if (L"CHAR" == sType) + m_chType = 1; + + m_sName = oNode.GetAttribute(L"name"); + m_sEngName = oNode.GetAttribute(L"engName"); + m_nParaShape = oNode.GetAttributeInt(L"paraPrIDRef"); + m_nCharShape = oNode.GetAttributeInt(L"charPrIDRef"); + m_chNextStyle = oNode.GetAttributeInt(L"nextStyleIDRef"); + m_shLangID = oNode.GetAttributeInt(L"langID"); + m_bLockForm = oNode.GetAttributeBool(L"lockForm"); +} +} diff --git a/HwpFile/HwpDoc/HWPElements/HWPRecordStyle.h b/HwpFile/HwpDoc/HWPElements/HWPRecordStyle.h new file mode 100644 index 00000000000..123fea9b578 --- /dev/null +++ b/HwpFile/HwpDoc/HWPElements/HWPRecordStyle.h @@ -0,0 +1,29 @@ +#ifndef HWPRECORDSTYLE_H +#define HWPRECORDSTYLE_H + +#include "HWPRecord.h" +#include "../HWPDocInfo.h" +#include "../Common/XMLNode.h" + +namespace HWP +{ +class CHWPRecordStyle : public CHWPRecord +{ + CHWPDocInfo* m_pParent; + + HWP_STRING m_sName; + HWP_STRING m_sEngName; + HWP_BYTE m_chType; + HWP_BYTE m_chNextStyle; + short m_shLangID; + int m_nParaShape; + int m_nCharShape; + bool m_bLockForm; +public: + CHWPRecordStyle(int nTagNum, int nLevel, int nSize); + CHWPRecordStyle(CHWPDocInfo& oDocInfo, int nTagNum, int nLevel, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); + CHWPRecordStyle(CHWPDocInfo& oDocInfo, CXMLNode& oNode, int nVersion); +}; +} + +#endif // HWPRECORDSTYLE_H diff --git a/HwpFile/HwpDoc/HWPElements/HWPTag.h b/HwpFile/HwpDoc/HWPElements/HWPTag.h new file mode 100644 index 00000000000..0a80dbae68b --- /dev/null +++ b/HwpFile/HwpDoc/HWPElements/HWPTag.h @@ -0,0 +1,125 @@ +#ifndef HWPTAG_H +#define HWPTAG_H + +namespace HWP +{ + +#define ADD_TAG(name, index) name = 0x010 + index + +enum EHWPTag +{ + ADD_TAG(null, -1), + + ADD_TAG(HWPTAG_DOCUMENT_PROPERTIES, 0), + ADD_TAG(HWPTAG_ID_MAPPINGS, 1), + ADD_TAG(HWPTAG_BIN_DATA, 2), + ADD_TAG(HWPTAG_FACE_NAME, 3), + ADD_TAG(HWPTAG_BORDER_FILL, 4), + ADD_TAG(HWPTAG_HWP_CHAR_SHAPE, 5), + ADD_TAG(HWPTAG_TAB_DEF, 6), + ADD_TAG(HWPTAG_NUMBERING, 7), + ADD_TAG(HWPTAG_BULLET, 8), + ADD_TAG(HWPTAG_PARA_SHAPE, 9), + ADD_TAG(HWPTAG_STYLE, 10), + ADD_TAG(HWPTAG_DOC_DATA, 11), + ADD_TAG(HWPTAG_DISTRIBUTE_DOC_DATA, 12), + ADD_TAG(HWPTAG_COMPATIBLE_DOCUMENT, 13), + ADD_TAG(HWPTAG_LAYOUT_COMPATIBILITY, 14), + ADD_TAG(HWPTAG_TRACKCHANGE, 15), + + ADD_TAG(HWPTAG_PARA_HEADER, 50), + ADD_TAG(HWPTAG_PARA_TEXT, 51), + ADD_TAG(HWPTAG_PARA_HWP_CHAR_SHAPE, 52), + ADD_TAG(HWPTAG_PARA_LINE_SEG, 53), + ADD_TAG(HWPTAG_PARA_RANGE_TAG, 54), + ADD_TAG(HWPTAG_CTRL_HEADER, 55), + ADD_TAG(HWPTAG_LIST_HEADER, 56), + ADD_TAG(HWPTAG_PAGE_DEF, 57), + ADD_TAG(HWPTAG_FOOTNOTE_SHAPE, 58), + ADD_TAG(HWPTAG_PAGE_BORDER_FILL, 59), + ADD_TAG(HWPTAG_SHAPE_COMPONENT, 60), + ADD_TAG(HWPTAG_TABLE, 61), + ADD_TAG(HWPTAG_SHAPE_COMPONENT_LINE, 62), + ADD_TAG(HWPTAG_SHAPE_COMPONENT_RECTANGLE, 63), + ADD_TAG(HWPTAG_SHAPE_COMPONENT_ELLIPSE, 64), + ADD_TAG(HWPTAG_SHAPE_COMPONENT_ARC, 65), + ADD_TAG(HWPTAG_SHAPE_COMPONENT_POLYGON, 66), + ADD_TAG(HWPTAG_SHAPE_COMPONENT_CURVE, 67), + ADD_TAG(HWPTAG_SHAPE_COMPONENT_OLE, 68), + ADD_TAG(HWPTAG_SHAPE_COMPONENT_PICTURE, 69), + ADD_TAG(HWPTAG_SHAPE_COMPONENT_CONTAINER, 70), + ADD_TAG(HWPTAG_CTRL_DATA, 71), + ADD_TAG(HWPTAG_EQEDIT, 72), + ADD_TAG(HWPTAG_SHAPE_COMPONENT_TEXTART, 74), + ADD_TAG(HWPTAG_FORM_OBJECT, 75), + ADD_TAG(HWPTAG_MEMO_SHAPE, 76), + ADD_TAG(HWPTAG_MEMO_LIST, 77), + ADD_TAG(HWPTAG_FORBIDDEN_HWP_CHAR, 78), + ADD_TAG(HWPTAG_HWP_CHART_DATA, 79), + ADD_TAG(HWPTAG_TRACK_CHANGE, 80), + ADD_TAG(HWPTAG_TRACK_CHANGE_AUTHOR, 81), + ADD_TAG(HWPTAG_VIDEO_DATA, 82), + ADD_TAG(HWPTAG_SHAPE_COMPONENT_UNKNOWN, 99) +}; + +inline EHWPTag GetTagFromNum(int nTagNum) +{ + switch (static_cast(nTagNum)) + { + case HWPTAG_DOCUMENT_PROPERTIES: + case HWPTAG_ID_MAPPINGS: + case HWPTAG_BIN_DATA: + case HWPTAG_FACE_NAME: + case HWPTAG_BORDER_FILL: + case HWPTAG_HWP_CHAR_SHAPE: + case HWPTAG_TAB_DEF: + case HWPTAG_NUMBERING: + case HWPTAG_BULLET: + case HWPTAG_PARA_SHAPE: + case HWPTAG_STYLE: + case HWPTAG_DISTRIBUTE_DOC_DATA: + case HWPTAG_COMPATIBLE_DOCUMENT: + case HWPTAG_LAYOUT_COMPATIBILITY: + case HWPTAG_TRACKCHANGE: + case HWPTAG_PARA_HEADER: + case HWPTAG_PARA_TEXT: + case HWPTAG_PARA_HWP_CHAR_SHAPE: + case HWPTAG_PARA_LINE_SEG: + case HWPTAG_PARA_RANGE_TAG: + case HWPTAG_CTRL_HEADER: + case HWPTAG_LIST_HEADER: + case HWPTAG_PAGE_DEF: + case HWPTAG_FOOTNOTE_SHAPE: + case HWPTAG_PAGE_BORDER_FILL: + case HWPTAG_SHAPE_COMPONENT: + case HWPTAG_TABLE: + case HWPTAG_SHAPE_COMPONENT_LINE: + case HWPTAG_SHAPE_COMPONENT_RECTANGLE: + case HWPTAG_SHAPE_COMPONENT_ELLIPSE: + case HWPTAG_SHAPE_COMPONENT_ARC: + case HWPTAG_SHAPE_COMPONENT_POLYGON: + case HWPTAG_SHAPE_COMPONENT_CURVE: + case HWPTAG_SHAPE_COMPONENT_OLE: + case HWPTAG_SHAPE_COMPONENT_PICTURE: + case HWPTAG_SHAPE_COMPONENT_CONTAINER: + case HWPTAG_CTRL_DATA: + case HWPTAG_EQEDIT: + case HWPTAG_SHAPE_COMPONENT_TEXTART: + case HWPTAG_FORM_OBJECT: + case HWPTAG_MEMO_SHAPE: + case HWPTAG_MEMO_LIST: + case HWPTAG_FORBIDDEN_HWP_CHAR: + case HWPTAG_HWP_CHART_DATA: + case HWPTAG_TRACK_CHANGE: + case HWPTAG_TRACK_CHANGE_AUTHOR: + case HWPTAG_VIDEO_DATA: + case HWPTAG_SHAPE_COMPONENT_UNKNOWN: + return static_cast(nTagNum); + default: + return null; + } +} + +} + +#endif // HWPTAG_H diff --git a/HwpFile/HwpDoc/HWPElements/HWPType.h b/HwpFile/HwpDoc/HWPElements/HWPType.h new file mode 100644 index 00000000000..34bbe909763 --- /dev/null +++ b/HwpFile/HwpDoc/HWPElements/HWPType.h @@ -0,0 +1,17 @@ +#ifndef HWPTYPE_H +#define HWPTYPE_H + +#include "HWPTag.h" + +namespace HWP +{ +class CHWPType +{ +public: + CHWPType(){}; + + EHWPTag m_eTag; +}; +} + +#endif // HWPTYPE_H diff --git a/HwpFile/HwpDoc/HWPElements/HwpRecordTabDef.cpp b/HwpFile/HwpDoc/HWPElements/HwpRecordTabDef.cpp new file mode 100644 index 00000000000..70321d8e491 --- /dev/null +++ b/HwpFile/HwpDoc/HWPElements/HwpRecordTabDef.cpp @@ -0,0 +1,83 @@ +#include "HwpRecordTabDef.h" + +namespace HWP +{ +TTab::TTab() +{} + +TTab::TTab(CXMLNode& oNode) +{ + m_nPos = oNode.GetAttributeInt(L"pos"); + SetType(oNode.GetAttributeInt(L"type")); + m_eLeader = GetLineStyle2(oNode.GetAttribute(L"leader")); +} + +void TTab::SetType(int nValue) +{ + SWITCH(TTab::EType, nValue) + { + case EType::LEFT: default: m_eType = EType::LEFT; break; + case EType::RIGHT: m_eType = EType::RIGHT; break; + case EType::CENTER: m_eType = EType::CENTER; break; + case EType::DECIMAL: m_eType = EType::DECIMAL; break; + } +} + +CHwpRecordTabDef::CHwpRecordTabDef(int nTagNum, int nLevel, int nSize) + : CHWPRecord(nTagNum, nLevel, nSize), m_pParent(nullptr) +{} + +CHwpRecordTabDef::CHwpRecordTabDef(CHWPDocInfo& oDocInfo, int nTagNum, int nLevel, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) + : CHWPRecord(nTagNum, nLevel, nSize), m_pParent(&oDocInfo) +{ + oBuffer.SavePosition(); + + oBuffer.ReadInt(m_nAttr); + oBuffer.ReadInt(m_nCount); + + if (nSize - oBuffer.GetDistanceToLastPos() != m_nCount * 8) + return; // TODO:: ошибка + + TTab *pTab = nullptr; + for (unsigned int unIndex = 0; unIndex < m_nCount; ++unIndex) + { + pTab = new TTab(); + + if (nullptr == pTab) + { + oBuffer.Skip(8); + continue; + } + + oBuffer.ReadInt(pTab->m_nPos); + pTab->SetType(oBuffer.ReadByte()); + pTab->m_eLeader = GetLineStyle2(oBuffer.ReadByte()); + oBuffer.Skip(2); // reserved 2 bytes for align + + m_arTabs.push_back(pTab); + } + + oBuffer.RemoveLastSavedPos(); +} + +CHwpRecordTabDef::CHwpRecordTabDef(CHWPDocInfo& oDocInfo, CXMLNode& oNode, int nVersion) + : CHWPRecord(EHWPTag::HWPTAG_TAB_DEF, 0, 0), m_pParent(&oDocInfo) +{ + if (oNode.GetAttributeBool(L"autoTabLeft")) + m_nAttr |= 0x00000001; + else + m_nAttr &= 0xFFFFFFFE; + + if (oNode.GetAttributeBool(L"autoTabRight")) + m_nAttr |= 0x00000002; + else + m_nAttr &= 0xFFFFFFFD; + + for (CXMLNode& oChild : oNode.GetChilds(L"hp:switch")) + for (CXMLNode& oGrandChild : oChild.GetChilds(L"hp:default")) + { + CXMLNode oTabItem{oGrandChild.GetChild(L"hh:tabItem")}; + m_arTabs.push_back(new TTab(oTabItem)); + } +} +} diff --git a/HwpFile/HwpDoc/HWPElements/HwpRecordTabDef.h b/HwpFile/HwpDoc/HWPElements/HwpRecordTabDef.h new file mode 100644 index 00000000000..3e466de2f30 --- /dev/null +++ b/HwpFile/HwpDoc/HWPElements/HwpRecordTabDef.h @@ -0,0 +1,44 @@ +#ifndef HWPRECORDTABDEF_H +#define HWPRECORDTABDEF_H + +#include "HWPRecord.h" +#include "../HWPDocInfo.h" +#include "HwpRecordTypes.h" +#include "../Common/XMLNode.h" + +namespace HWP +{ +struct TTab +{ + int m_nPos; + enum class EType + { + LEFT, + RIGHT, + CENTER, + DECIMAL + } m_eType; + ELineStyle2 m_eLeader; + + + TTab(); + TTab(CXMLNode& oNode); + + void SetType(int nValue); +}; + +class CHwpRecordTabDef : public CHWPRecord +{ + CHWPDocInfo *m_pParent; + + int m_nAttr; + int m_nCount; + LIST m_arTabs; +public: + CHwpRecordTabDef(int nTagNum, int nLevel, int nSize); + CHwpRecordTabDef(CHWPDocInfo& oDocInfo, int nTagNum, int nLevel, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); + CHwpRecordTabDef(CHWPDocInfo& oDocInfo, CXMLNode& oNode, int nVersion); +}; +} + +#endif // HWPRECORDTABDEF_H diff --git a/HwpFile/HwpDoc/HWPElements/HwpRecordTypes.h b/HwpFile/HwpDoc/HWPElements/HwpRecordTypes.h new file mode 100644 index 00000000000..70d078811bd --- /dev/null +++ b/HwpFile/HwpDoc/HWPElements/HwpRecordTypes.h @@ -0,0 +1,353 @@ +#ifndef HWPRECORDTYPES_H +#define HWPRECORDTYPES_H + +#include "../Common/Common.h" + +namespace HWP +{ +enum class ELineStyle1 +{ + SOLID, + DASH, + DOT, + DASH_DOT, + DASH_DOT_DOT, + LONG_DASH, + CIRCLE, + DOUBLE_SLIM, + SLIM_THICK, + THICK_SLIM, + SLIM_THICK_SLIM, + WAVE, + DOUBLE_WAVE, + THICK_3D, + THICK_3D_REVERS_LI, + SOLID_3D, + SOLID_3D_REVERS_LI +}; + +inline ELineStyle1 GetLineStyle1(int nValue) +{ + SWITCH(ELineStyle1, nValue) + { + DEFAULT(ELineStyle1::SOLID); + CASE(ELineStyle1::DASH); + CASE(ELineStyle1::DOT); + CASE(ELineStyle1::DASH_DOT); + CASE(ELineStyle1::DASH_DOT_DOT); + CASE(ELineStyle1::LONG_DASH); + CASE(ELineStyle1::CIRCLE); + CASE(ELineStyle1::DOUBLE_SLIM); + CASE(ELineStyle1::SLIM_THICK); + CASE(ELineStyle1::THICK_SLIM); + CASE(ELineStyle1::SLIM_THICK_SLIM); + CASE(ELineStyle1::WAVE); + CASE(ELineStyle1::DOUBLE_WAVE); + CASE(ELineStyle1::THICK_3D); + CASE(ELineStyle1::THICK_3D_REVERS_LI); + CASE(ELineStyle1::SOLID_3D); + CASE(ELineStyle1::SOLID_3D_REVERS_LI); + } +} + +inline ELineStyle1 GetLineStyle1(const HWP_STRING& sValue) +{ + IF_STRING_IN_ENUM(SOLID, sValue, ELineStyle1); + ELSE_IF_STRING_IN_ENUM(DASH, sValue, ELineStyle1); + ELSE_IF_STRING_IN_ENUM(DOT, sValue, ELineStyle1); + ELSE_IF_STRING_IN_ENUM(DASH_DOT, sValue, ELineStyle1); + ELSE_IF_STRING_IN_ENUM(DASH_DOT_DOT, sValue, ELineStyle1); + ELSE_IF_STRING_IN_ENUM(LONG_DASH, sValue, ELineStyle1); + ELSE_IF_STRING_IN_ENUM(CIRCLE, sValue, ELineStyle1); + ELSE_IF_STRING_IN_ENUM(DOUBLE_SLIM, sValue, ELineStyle1); + ELSE_IF_STRING_IN_ENUM(SLIM_THICK, sValue, ELineStyle1); + ELSE_IF_STRING_IN_ENUM(THICK_SLIM, sValue, ELineStyle1); + ELSE_IF_STRING_IN_ENUM(SLIM_THICK_SLIM, sValue, ELineStyle1); + ELSE_IF_STRING_IN_ENUM(WAVE, sValue, ELineStyle1); + ELSE_IF_STRING_IN_ENUM(DOUBLE_WAVE, sValue, ELineStyle1); + ELSE_IF_STRING_IN_ENUM(THICK_3D, sValue, ELineStyle1); + ELSE_IF_STRING_IN_ENUM(THICK_3D_REVERS_LI, sValue, ELineStyle1); + ELSE_IF_STRING_IN_ENUM(SOLID_3D, sValue, ELineStyle1); + ELSE_IF_STRING_IN_ENUM(SOLID_3D_REVERS_LI, sValue, ELineStyle1); + ELSE_STRING_IN_ENUM(SOLID, ELineStyle1); +} + +enum class ELineStyle2 +{ + NONE, + SOLID, + DASH, + DOT, + DASH_DOT, + DASH_DOT_DOT, + LONG_DASH, + CIRCLE, + DOUBLE_SLIM, + SLIM_THICK, + THICK_SLIM, + SLIM_THICK_SLIM +}; + +inline ELineStyle2 GetLineStyle2(int nValue) +{ + SWITCH(ELineStyle2, nValue) + { + DEFAULT(ELineStyle2::NONE); + CASE(ELineStyle2::SOLID); + CASE(ELineStyle2::DASH); + CASE(ELineStyle2::DOT); + CASE(ELineStyle2::DASH_DOT); + CASE(ELineStyle2::DASH_DOT_DOT); + CASE(ELineStyle2::LONG_DASH); + CASE(ELineStyle2::CIRCLE); + CASE(ELineStyle2::DOUBLE_SLIM); + CASE(ELineStyle2::SLIM_THICK); + CASE(ELineStyle2::THICK_SLIM); + CASE(ELineStyle2::SLIM_THICK_SLIM); + } +} + +inline ELineStyle2 GetLineStyle2(const HWP_STRING& sValue) +{ + IF_STRING_IN_ENUM(NONE, sValue, ELineStyle2); + ELSE_IF_STRING_IN_ENUM(SOLID, sValue, ELineStyle2); + ELSE_IF_STRING_IN_ENUM(DASH, sValue, ELineStyle2); + ELSE_IF_STRING_IN_ENUM(DOT, sValue, ELineStyle2); + ELSE_IF_STRING_IN_ENUM(DASH_DOT, sValue, ELineStyle2); + ELSE_IF_STRING_IN_ENUM(DASH_DOT_DOT, sValue, ELineStyle2); + ELSE_IF_STRING_IN_ENUM(LONG_DASH, sValue, ELineStyle2); + ELSE_IF_STRING_IN_ENUM(CIRCLE, sValue, ELineStyle2); + ELSE_IF_STRING_IN_ENUM(DOUBLE_SLIM, sValue, ELineStyle2); + ELSE_IF_STRING_IN_ENUM(SLIM_THICK, sValue, ELineStyle2); + ELSE_IF_STRING_IN_ENUM(THICK_SLIM, sValue, ELineStyle2); + ELSE_IF_STRING_IN_ENUM(SLIM_THICK_SLIM, sValue, ELineStyle2); + ELSE_STRING_IN_ENUM(NONE, ELineStyle2); +} + +enum class ENumberShape1 +{ + DIGIT, + CIRCLE_DIGIT, + ROMAN_CAPITAL, + ROMAN_SMALL, + LATIN_CAPITAL, + LATIN_SMALL, + CIRCLED_LATIN_CAPITAL, + CIRCLED_LATIN_SMALL, + HANGLE_SYLLABLE, + CIRCLED_HANGUL_SYLLABLE, + HANGUL_JAMO, + CIRCLED_HANGUL_JAMO, + HANGUL_PHONETIC, + IDEOGRAPH, + CIRCLED_IDEOGRAPH +}; + +inline ENumberShape1 GetNumberShape1(int nValue) +{ + SWITCH(ENumberShape1, nValue) + { + DEFAULT(ENumberShape1::DIGIT); + CASE(ENumberShape1::CIRCLE_DIGIT); + CASE(ENumberShape1::ROMAN_CAPITAL); + CASE(ENumberShape1::ROMAN_SMALL); + CASE(ENumberShape1::LATIN_CAPITAL); + CASE(ENumberShape1::LATIN_SMALL); + CASE(ENumberShape1::CIRCLED_LATIN_CAPITAL); + CASE(ENumberShape1::CIRCLED_LATIN_SMALL); + CASE(ENumberShape1::HANGLE_SYLLABLE); + CASE(ENumberShape1::CIRCLED_HANGUL_SYLLABLE); + CASE(ENumberShape1::HANGUL_JAMO); + CASE(ENumberShape1::CIRCLED_HANGUL_JAMO); + CASE(ENumberShape1::HANGUL_PHONETIC); + CASE(ENumberShape1::IDEOGRAPH); + CASE(ENumberShape1::CIRCLED_IDEOGRAPH); + } +} + +inline ENumberShape1 GetNumberShape1(const HWP_STRING& sValue) +{ + IF_STRING_IN_ENUM(DIGIT, sValue, ENumberShape1); + ELSE_IF_STRING_IN_ENUM(CIRCLE_DIGIT, sValue, ENumberShape1); + ELSE_IF_STRING_IN_ENUM(ROMAN_CAPITAL, sValue, ENumberShape1); + ELSE_IF_STRING_IN_ENUM(ROMAN_SMALL, sValue, ENumberShape1); + ELSE_IF_STRING_IN_ENUM(LATIN_CAPITAL, sValue, ENumberShape1); + ELSE_IF_STRING_IN_ENUM(LATIN_SMALL, sValue, ENumberShape1); + ELSE_IF_STRING_IN_ENUM(CIRCLED_LATIN_CAPITAL, sValue, ENumberShape1); + ELSE_IF_STRING_IN_ENUM(CIRCLED_LATIN_SMALL, sValue, ENumberShape1); + ELSE_IF_STRING_IN_ENUM(HANGLE_SYLLABLE, sValue, ENumberShape1); + ELSE_IF_STRING_IN_ENUM(CIRCLED_HANGUL_SYLLABLE, sValue, ENumberShape1); + ELSE_IF_STRING_IN_ENUM(HANGUL_JAMO, sValue, ENumberShape1); + ELSE_IF_STRING_IN_ENUM(CIRCLED_HANGUL_JAMO, sValue, ENumberShape1); + ELSE_IF_STRING_IN_ENUM(HANGUL_PHONETIC, sValue, ENumberShape1); + ELSE_IF_STRING_IN_ENUM(IDEOGRAPH, sValue, ENumberShape1); + ELSE_IF_STRING_IN_ENUM(CIRCLED_IDEOGRAPH, sValue, ENumberShape1); + ELSE_STRING_IN_ENUM(DIGIT, ENumberShape1); +} + +enum class ENumberShape2 +{ + DIGIT, + CIRCLE_DIGIT, + ROMAN_CAPITAL, + ROMAN_SMALL, + LATIN_CAPITAL, + LATIN_SMALL, + CIRCLED_LATIN_CAPITAL, + CIRCLED_LATIN_SMALL, + HANGLE_SYLLABLE, + CIRCLED_HANGUL_SYLLABLE, + HANGUL_JAMO, + CIRCLED_HANGUL_JAMO, + HANGUL_PHONETIC, + IDEOGRAPH, + CIRCLED_IDEOGRAPH, + DECAGON_CIRCLE, + DECAGON_CRICLE_HANGJA, + SYMBOL = 0x80, + USER_HWP_CHAR = 0x81 +}; + +inline ENumberShape2 GetNumberShape2(int nValue) +{ + SWITCH(ENumberShape2, nValue) + { + DEFAULT(ENumberShape2::DIGIT); + CASE(ENumberShape2::CIRCLE_DIGIT); + CASE(ENumberShape2::ROMAN_CAPITAL); + CASE(ENumberShape2::ROMAN_SMALL); + CASE(ENumberShape2::LATIN_CAPITAL); + CASE(ENumberShape2::LATIN_SMALL); + CASE(ENumberShape2::CIRCLED_LATIN_CAPITAL); + CASE(ENumberShape2::CIRCLED_LATIN_SMALL); + CASE(ENumberShape2::HANGLE_SYLLABLE); + CASE(ENumberShape2::CIRCLED_HANGUL_SYLLABLE); + CASE(ENumberShape2::HANGUL_JAMO); + CASE(ENumberShape2::CIRCLED_HANGUL_JAMO); + CASE(ENumberShape2::HANGUL_PHONETIC); + CASE(ENumberShape2::IDEOGRAPH); + CASE(ENumberShape2::CIRCLED_IDEOGRAPH); + CASE(ENumberShape2::DECAGON_CIRCLE); + CASE(ENumberShape2::DECAGON_CRICLE_HANGJA); + CASE(ENumberShape2::SYMBOL); + CASE(ENumberShape2::USER_HWP_CHAR); + } +} + +inline ENumberShape2 GetNumberShape2(const HWP_STRING& sValue) +{ + IF_STRING_IN_ENUM(DIGIT, sValue, ENumberShape2); + ELSE_IF_STRING_IN_ENUM(CIRCLE_DIGIT, sValue, ENumberShape2); + ELSE_IF_STRING_IN_ENUM(ROMAN_CAPITAL, sValue, ENumberShape2); + ELSE_IF_STRING_IN_ENUM(ROMAN_SMALL, sValue, ENumberShape2); + ELSE_IF_STRING_IN_ENUM(LATIN_CAPITAL, sValue, ENumberShape2); + ELSE_IF_STRING_IN_ENUM(LATIN_SMALL, sValue, ENumberShape2); + ELSE_IF_STRING_IN_ENUM(CIRCLED_LATIN_CAPITAL, sValue, ENumberShape2); + ELSE_IF_STRING_IN_ENUM(CIRCLED_LATIN_SMALL, sValue, ENumberShape2); + ELSE_IF_STRING_IN_ENUM(HANGLE_SYLLABLE, sValue, ENumberShape2); + ELSE_IF_STRING_IN_ENUM(CIRCLED_HANGUL_SYLLABLE, sValue, ENumberShape2); + ELSE_IF_STRING_IN_ENUM(HANGUL_JAMO, sValue, ENumberShape2); + ELSE_IF_STRING_IN_ENUM(CIRCLED_HANGUL_JAMO, sValue, ENumberShape2); + ELSE_IF_STRING_IN_ENUM(HANGUL_PHONETIC, sValue, ENumberShape2); + ELSE_IF_STRING_IN_ENUM(IDEOGRAPH, sValue, ENumberShape2); + ELSE_IF_STRING_IN_ENUM(CIRCLED_IDEOGRAPH, sValue, ENumberShape2); + ELSE_IF_STRING_IN_ENUM(DECAGON_CIRCLE, sValue, ENumberShape2); + ELSE_IF_STRING_IN_ENUM(DECAGON_CRICLE_HANGJA, sValue, ENumberShape2); + ELSE_IF_STRING_IN_ENUM(SYMBOL, sValue, ENumberShape2); + ELSE_IF_STRING_IN_ENUM(USER_HWP_CHAR, sValue, ENumberShape2); + ELSE_STRING_IN_ENUM(DIGIT, ENumberShape2); +} + +enum class ELineArrowStyle +{ + NORMAL, + ARROW, + SPEAR, + CONCAVE_ARROW, + DIAMOND, + CIRCLE, + BOX, + EMPTY_DIAMOND, + EMPTY_CIRCLE, + EMPTY_BOX +}; + +inline ELineArrowStyle GetLineArrowStyle(int nNum, bool bFill) +{ + switch (nNum) + { + case 0: return ELineArrowStyle::NORMAL; + case 1: return ELineArrowStyle::ARROW; + case 2: return ELineArrowStyle::SPEAR; + case 3: return ELineArrowStyle::CONCAVE_ARROW; + case 4: + case 7: return bFill ? ELineArrowStyle::DIAMOND : ELineArrowStyle::EMPTY_DIAMOND; + case 5: + case 8: return bFill ? ELineArrowStyle::CIRCLE : ELineArrowStyle::EMPTY_CIRCLE; + case 6: + case 9: return bFill ? ELineArrowStyle::BOX : ELineArrowStyle::EMPTY_BOX; + default: return ELineArrowStyle::NORMAL; + } +} + +inline ELineArrowStyle GetLineArrowStyle(const HWP_STRING& sValue) +{ + IF_STRING_IN_ENUM(NORMAL, sValue, ELineArrowStyle); + ELSE_IF_STRING_IN_ENUM(ARROW, sValue, ELineArrowStyle); + ELSE_IF_STRING_IN_ENUM(SPEAR, sValue, ELineArrowStyle); + ELSE_IF_STRING_IN_ENUM(CONCAVE_ARROW, sValue, ELineArrowStyle); + ELSE_IF_STRING_IN_ENUM(DIAMOND, sValue, ELineArrowStyle); + ELSE_IF_STRING_IN_ENUM(CIRCLE, sValue, ELineArrowStyle); + ELSE_IF_STRING_IN_ENUM(BOX, sValue, ELineArrowStyle); + ELSE_IF_STRING_IN_ENUM(EMPTY_DIAMOND, sValue, ELineArrowStyle); + ELSE_IF_STRING_IN_ENUM(EMPTY_CIRCLE, sValue, ELineArrowStyle); + ELSE_IF_STRING_IN_ENUM(EMPTY_BOX, sValue, ELineArrowStyle); + ELSE_STRING_IN_ENUM(NORMAL, ELineArrowStyle); +} + +enum class ELineArrowSize +{ + SMALL_SMALL, + SMALL_MEDIUM, + SMALL_LARGE, + MEDIUM_SMALL, + MEDIUM_MEDIUM, + MEDIUM_LARGE, + LARGE_SMALL, + LARGE_MEDIUM, + LARGE_LARGE +}; + +inline ELineArrowSize GetLineArrowSize(int nValue) +{ + SWITCH(ELineArrowSize, nValue) + { + DEFAULT(ELineArrowSize::SMALL_SMALL); + CASE(ELineArrowSize::SMALL_MEDIUM); + CASE(ELineArrowSize::SMALL_LARGE); + CASE(ELineArrowSize::MEDIUM_SMALL); + CASE(ELineArrowSize::MEDIUM_MEDIUM); + CASE(ELineArrowSize::MEDIUM_LARGE); + CASE(ELineArrowSize::LARGE_SMALL); + CASE(ELineArrowSize::LARGE_MEDIUM); + CASE(ELineArrowSize::LARGE_LARGE); + } +} + +inline ELineArrowSize GetLineArrowSize(const HWP_STRING& sValue) +{ + IF_STRING_IN_ENUM(SMALL_SMALL, sValue, ELineArrowSize); + ELSE_IF_STRING_IN_ENUM(SMALL_MEDIUM, sValue, ELineArrowSize); + ELSE_IF_STRING_IN_ENUM(SMALL_LARGE, sValue, ELineArrowSize); + ELSE_IF_STRING_IN_ENUM(MEDIUM_SMALL, sValue, ELineArrowSize); + ELSE_IF_STRING_IN_ENUM(MEDIUM_MEDIUM, sValue, ELineArrowSize); + ELSE_IF_STRING_IN_ENUM(MEDIUM_LARGE, sValue, ELineArrowSize); + ELSE_IF_STRING_IN_ENUM(LARGE_SMALL, sValue, ELineArrowSize); + ELSE_IF_STRING_IN_ENUM(LARGE_MEDIUM, sValue, ELineArrowSize); + ELSE_IF_STRING_IN_ENUM(LARGE_LARGE, sValue, ELineArrowSize); + ELSE_STRING_IN_ENUM(SMALL_SMALL, ELineArrowSize); +} + +} + +#endif // HWPRECORDTYPES_H diff --git a/HwpFile/HwpDoc/HWPFile.cpp b/HwpFile/HwpDoc/HWPFile.cpp new file mode 100644 index 00000000000..b0dd099d101 --- /dev/null +++ b/HwpFile/HwpDoc/HWPFile.cpp @@ -0,0 +1,412 @@ +#include "HWPFile.h" +#include "HWPDocInfo.h" + +#include "../OfficeUtils/src/OfficeUtils.h" +#include "../DesktopEditor/common/Directory.h" + +// For decrypt +#include "../../Common/3dParty/cryptopp/modes.h" +#include "../../Common/3dParty/cryptopp/aes.h" +#include "../../Common/3dParty/cryptopp/filters.h" +// ---------- + +#define DEFAULT_BUFFER_SIZE 8096 + +namespace HWP +{ +CHWPFile::CHWPFile(const HWP_STRING& sFileName) + : m_sFileName(sFileName), m_oOleFile(sFileName), m_oDocInfo(this) +{} + +CHWPFile::~CHWPFile() +{ + Close(); + + CLEAR_ARRAY(CHWPSection, m_arBodyTexts); + CLEAR_ARRAY(CHWPSection, m_arViewTexts); +} + +std::vector CHWPFile::GetSections() +{ + if (m_oFileHeader.Distributable()) + { + RETURN_VECTOR_CONST_PTR(CHWPSection, m_arViewTexts); + } + else + { + RETURN_VECTOR_CONST_PTR(CHWPSection, m_arBodyTexts); + } +} + +const CCompoundFile* CHWPFile::GetOleFile() const +{ + return &m_oOleFile; +} + +bool CHWPFile::Detect() +{ + // read CompoundFile structure + if (!m_oOleFile.Open() || !GetFileHeader()) + { + m_oOleFile.Close(); + return false; + } + + return true; +} + +bool CHWPFile::Open() +{ + if ((m_oFileHeader.SignatureEmpty() || m_oFileHeader.VersionEmpty()) && !Detect()) + return false; + + //TODO:: добавить отдельный метод StringToInt + m_nVersion = std::stoi(m_oFileHeader.GetVersion()); + + //TODO:: проверить данный момент + if (m_oFileHeader.PasswordEncrypted()) + return false; + + if (!GetDocInfo(m_nVersion)) + return false; + + if (!m_oFileHeader.Distributable() && !GetBodyText(m_nVersion)) + return false; + + if (m_oFileHeader.Distributable() && !GetViewText(m_nVersion)) + return false; + + return true; +} + +void CHWPFile::Close() +{ + m_oOleFile.Close(); +} + +bool CHWPFile::GetFileHeader() +{ + CHWPStream oBuffer; + if (!GetComponent(L"FileHeader", oBuffer)) + return false; + + return m_oFileHeader.Parse(oBuffer); +} + +const CHWPDocInfo* CHWPFile::GetDocInfo() const +{ + return &m_oDocInfo; +} + +bool CHWPFile::GetDocInfo(int nVersion) +{ + CHWPStream oBuffer; + if (m_oFileHeader.Compressed()) + { + CHWPStream oTempBuffer; + + if (!GetComponent(L"DocInfo", oTempBuffer) || !Unzip(oTempBuffer, oBuffer)) + return false; + } + else + { + if (GetComponent(L"DocInfo", oBuffer)) + return false; + } + + return m_oDocInfo.Parse(oBuffer, m_nVersion); +} + +bool CHWPFile::GetComponent(const HWP_STRING& sEntryName, CHWPStream& oBuffer) +{ + return m_oOleFile.GetComponent(sEntryName, oBuffer); +} +//------------ +CDirectoryEntry* CHWPFile::FindChildEntry(const HWP_STRING& sBasePath, const CDirectoryEntry& oBaseEntry, const HWP_STRING& sEntryName) const +{ + for (CDirectoryEntry* pEntry : m_oOleFile.GetChildEntries(&oBaseEntry)) + { + if (0x01 == pEntry->GetObjectType()) + { + //TODO:: проверить + HWP_STRING sChildPath = sBasePath + FILE_SEPARATOR_STR + pEntry->GetDirectoryEntryName(); + return FindChildEntry(sChildPath, *pEntry, sEntryName); + } + else + { + if (sEntryName == pEntry->GetDirectoryEntryName()) + return pEntry; + } + } + + return nullptr; +} + +HWP_STRING CHWPFile::SaveChildEntry(const HWP_STRING& sRootPath, const HWP_STRING& sEntryName, ECompressed eCompressed) +{ + //TODO:: перенести + return HWP_STRING(); +} + +bool CHWPFile::GetChildStream(const HWP_STRING& sEntryName, ECompressed eCompressed, CHWPStream& oBuffer) +{ + // HWP_STRING sRegexStr = L".*" + HWP_STRING(FILE_SEPARATOR_STR) + L"([" + HWP_STRING(FILE_SEPARATOR_STR) + L"]+)$"; + + // HWP_STRING sShortFilename = std::regex_replace(m_sFileName, std::wregex(sRegexStr), L"$1"); + // sShortFilename = std::regex_replace(sShortFilename, std::wregex(L"(.*)\\.hwp$"), L"$1"); + + CDirectoryEntry *pTargetEntry = nullptr; + + VECTOR arEntries = m_oOleFile.GetChildEntries(L"Root Entry"); + + for (CDirectoryEntry* pEntry : arEntries) + { + if (0x01 == pEntry->GetObjectType()) + { + HWP_STRING sChildPath = /*sShortFilename + FILE_SEPARATOR_STR + */pEntry->GetDirectoryEntryName(); + pTargetEntry = FindChildEntry(sChildPath, *pEntry, sEntryName); + + if (nullptr != pTargetEntry) + break; + } + else + { + if (sEntryName == pEntry->GetDirectoryEntryName()) + { + pTargetEntry = pEntry; + break; + } + } + } + + if (nullptr == pTargetEntry) + return false; + + if (ECompressed::COMPRESS == eCompressed || (ECompressed::FOLLOW_STORAGE == eCompressed && m_oFileHeader.Compressed())) + { + CHWPStream oTempBuffer; + if (!m_oOleFile.Read(*pTargetEntry, oTempBuffer)) + return false; + + return Unzip(oTempBuffer, oBuffer); + } + else + return m_oOleFile.Read(*pTargetEntry, oBuffer); + + return false; +} + +bool CHWPFile::Unzip(CHWPStream& oInput, CHWPStream& oBuffer) +{ + unsigned char* pInBuffer = new(std::nothrow) unsigned char[DEFAULT_BUFFER_SIZE]; + + if (nullptr == pInBuffer) + return false; + + unsigned char* pOutBuffer = new(std::nothrow) unsigned char[DEFAULT_BUFFER_SIZE]; + + if (nullptr == pOutBuffer) + { + delete[] pInBuffer; + return false; + } + + CInflate oInflater; + + oInflater.SetOut(pOutBuffer, DEFAULT_BUFFER_SIZE); + oInflater.Init2(); + oInflater.SetIn(pInBuffer, 0); + + int nRes = DEFLATE_OK; + + while (true) + { + const unsigned int unSize = oInput.ReadBytes((HWP_BYTE*)pInBuffer, DEFAULT_BUFFER_SIZE); + + oInflater.SetIn(pInBuffer, unSize); + + if (0 == unSize) + break; + + while (oInflater.GetAvailIn() > 0) + { + nRes = oInflater.Process(DEFLATE_NO_FLUSH); + + if (DEFLATE_OK != nRes && DEFLATE_STREAM_END != nRes) + break; + + if (oInflater.GetAvailOut() == 0) + { + oBuffer.WriteBytes((HWP_BYTE*)pOutBuffer, DEFAULT_BUFFER_SIZE); + oInflater.SetOut(pOutBuffer, DEFAULT_BUFFER_SIZE); + } + + if (DEFLATE_STREAM_END == nRes) + break; + } + } + + bool bEnd = false; + + while (DEFLATE_OK == nRes || DEFLATE_STREAM_END == nRes) + { + nRes = oInflater.Process(DEFLATE_FINISH); + + if (DEFLATE_OK != nRes && DEFLATE_STREAM_END != nRes) + { + oInflater.End(); + } + + if (DEFLATE_STREAM_END == nRes) + bEnd = true; + + if (oInflater.GetAvailOut() < DEFAULT_BUFFER_SIZE) + { + unsigned long ulSize = DEFAULT_BUFFER_SIZE - oInflater.GetAvailOut(); + oBuffer.WriteBytes((HWP_BYTE*)pOutBuffer, ulSize); + oInflater.SetOut(pOutBuffer, DEFAULT_BUFFER_SIZE); + } + + if (bEnd) + break; + } + + oInflater.End(); + + delete[] pInBuffer; + delete[] pOutBuffer; + + oBuffer.MoveToStart(); + + return DEFLATE_OK == nRes || DEFLATE_STREAM_END == nRes; +} + +// Так как на всех ОС необходимо одинаковое поведение, +// то используем свой рандомайзер + +class CRandomizer +{ + uint32_t m_unSeed; +public: + CRandomizer(uint32_t unSeed) + : m_unSeed(unSeed) + {} + + int rand() + { + m_unSeed = m_unSeed * 214013L + 2531011L; + return (m_unSeed >> 16) & 0x7fff; + } +}; + +bool CHWPFile::Decrypt(CHWPStream& oInput, CHWPStream& oBuffer) +{ + int nHeader; + oInput.ReadInt(nHeader); + + int nTagNum = nHeader & 0x3FF; // 10 bits (0 - 9 bit) + // int nLevel = (nHeader & 0xFFC00) >> 10; // 10 bits (10-19 bit) + int nSize = (nHeader & 0xFFF00000) >> 20; // 12 bits (20-31 bit) + + EHWPTag eTag = GetTagFromNum(nTagNum); + + if (HWPTAG_DISTRIBUTE_DOC_DATA != eTag) + return false; + + if (256 != nSize) + return false; + + CHWPStream oDocData(256); + oDocData.Copy(oInput, 256); + oInput.Skip(256); + + int nSeed; + oDocData.ReadInt(nSeed); + oDocData.Skip(-4); + + CRandomizer oRandomizer(nSeed); + + unsigned char chKey; + + for (unsigned int unIndex = 0, unCount = 0; unIndex < 256; ++unIndex) + { + if (0 == unCount) + { + chKey = oRandomizer.rand() & 0xFF; + unCount = (oRandomizer.rand() & 0xF) + 1; + } + if (unIndex >= 4) + *(oDocData.GetCurPtr() + unIndex) = oDocData[unIndex] ^ chKey; + + --unCount; + } + + int nHashOffset = (nSeed & 0x0f) + 4; + + oBuffer.Expand(oInput.SizeToEnd()); + + using namespace CryptoPP; + + ECB_Mode::Decryption oDecryptor; + oDecryptor.SetKey((byte*)(oDocData.GetCurPtr() + nHashOffset), 16); + + ArraySource((byte*)oInput.GetCurPtr(), oInput.SizeToEnd(), true, new StreamTransformationFilter(oDecryptor, new ArraySink( (byte*)oBuffer.GetCurPtr(), oBuffer.GetSize()), StreamTransformationFilter::NO_PADDING)); + + return true; +} + +bool CHWPFile::GetBodyText(int nVersion) +{ + VECTOR arSections{m_oOleFile.GetChildEntries(L"BodyText")}; + + for (const CDirectoryEntry* pSection : arSections) + { + CHWPStream oBuffer; + + if (m_oFileHeader.Compressed()) + { + CHWPStream oTempBuffer; + if (!m_oOleFile.Read(*pSection, oTempBuffer) || !Unzip(oTempBuffer, oBuffer)) + return false; + } + else if (!m_oOleFile.Read(*pSection, oBuffer)) + return false; + + CHWPSection *pHwpSection = new CHWPSection(); + pHwpSection->Parse(oBuffer, m_nVersion); + m_arBodyTexts.push_back(pHwpSection); + } + + return true; +} + +bool CHWPFile::GetViewText(int nVersion) +{ + VECTOR arSections{m_oOleFile.GetChildEntries(L"ViewText")}; + + for (const CDirectoryEntry* pSection : arSections) + { + CHWPStream oBuffer; + + if (m_oFileHeader.Compressed()) + { + CHWPStream oTempDecryptBuffer, oTempBuffer; + if (!m_oOleFile.Read(*pSection, oTempDecryptBuffer) || !Decrypt(oTempDecryptBuffer, oTempBuffer) || !Unzip(oTempBuffer, oBuffer)) + return false; + } + else + { + CHWPStream oTempBuffer; + + if (!m_oOleFile.Read(*pSection, oTempBuffer) || !Decrypt(oTempBuffer, oBuffer)) + return false; + } + + CHWPSection *pHwpSection = new CHWPSection(); + pHwpSection->Parse(oBuffer, m_nVersion); + m_arViewTexts.push_back(pHwpSection); + } + + return true; +} +} diff --git a/HwpFile/HwpDoc/HWPFile.h b/HwpFile/HwpDoc/HWPFile.h new file mode 100644 index 00000000000..c073051a337 --- /dev/null +++ b/HwpFile/HwpDoc/HWPFile.h @@ -0,0 +1,48 @@ +#ifndef HWPFILE_H +#define HWPFILE_H + +#include "HwpFileHeader.h" +#include "OLEdoc/CompoundFile.h" +#include "HWPElements/HWPRecordBinData.h" +#include "HWPSection.h" + +namespace HWP +{ +class CHWPFile +{ + HWP_STRING m_sFileName; + CCompoundFile m_oOleFile; + CHwpFileHeader m_oFileHeader; + int m_nVersion; + CHWPDocInfo m_oDocInfo; + VECTOR m_arBodyTexts; + VECTOR m_arViewTexts; +public: + CHWPFile(const HWP_STRING& sFileName); + ~CHWPFile(); + + VECTOR GetSections(); + const CCompoundFile* GetOleFile() const; + + bool Detect(); + bool Open(); + void Close(); + + bool GetFileHeader(); + const CHWPDocInfo* GetDocInfo() const; + bool GetDocInfo(int nVersion); + bool GetComponent(const HWP_STRING& sEntryName, CHWPStream& oBuffer); + bool GetChildStream(const HWP_STRING& sEntryName, ECompressed eCompressed, CHWPStream& oBuffer); +private: + CDirectoryEntry* FindChildEntry(const HWP_STRING& sBasePath, const CDirectoryEntry& oBaseEntry, const HWP_STRING& sEntryName) const; + HWP_STRING SaveChildEntry(const HWP_STRING& sRootPath, const HWP_STRING& sEntryName, ECompressed eCompressed); + + bool Unzip(CHWPStream& oInput, CHWPStream& oBuffer); + bool Decrypt(CHWPStream& oInput, CHWPStream& oBuffer); + + bool GetBodyText(int nVersion); + bool GetViewText(int nVersion); +}; +} + +#endif // HWPFILE_H diff --git a/HwpFile/HwpDoc/HWPSection.cpp b/HwpFile/HwpDoc/HWPSection.cpp new file mode 100644 index 00000000000..342a2dd04a0 --- /dev/null +++ b/HwpFile/HwpDoc/HWPSection.cpp @@ -0,0 +1,1143 @@ +#include "HWPSection.h" + +#include "HWPElements/HWPTag.h" + +#include "HwpDoc/Paragraph/CtrlEqEdit.h" +#include "Paragraph/CtrlTable.h" +#include "Paragraph/CtrlSectionDef.h" +#include "Paragraph/CtrlCommon.h" +#include "Paragraph/CtrlCharacter.h" +#include "Paragraph/CharShape.h" +#include "Paragraph/CtrlHeadFoot.h" +#include "Paragraph/CtrlTable.h" +#include "Paragraph/CtrlNote.h" +#include "Paragraph/CtrlForm.h" + +#include "Paragraph/CtrlGeneralShape.h" +#include "Paragraph/CtrlShapeRect.h" +#include "Paragraph/CtrlShapePolygon.h" +#include "Paragraph/CtrlShapeEllipse.h" +#include "Paragraph/CtrlShapePic.h" +#include "Paragraph/CtrlShapeLine.h" +#include "Paragraph/CtrlShapeArc.h" +#include "Paragraph/CtrlShapeCurve.h" +#include "Paragraph/CtrlShapeOle.h" +#include "Paragraph/CtrlShapeTextArt.h" +#include "Paragraph/CtrlShapeVideo.h" + +#include "Paragraph/CellParagraph.h" +#include "Paragraph/CapParagraph.h" + +#include "HWPElements/HWPRecordParaText.h" +#include "HWPElements/HWPRecordParaRangeTag.h" +#include "HWPElements/HWPRecordCtrlHeader.h" +#include "HWPElements/HWPRecordListHeader.h" +#include "HWPElements/HWPRecordFormObject.h" +#include "HWPElements/HWPRecordCtrlData.h" + +#ifdef _DEBUG +#include +#define PRINT_HWPTAG(prefix, tag, postfix) \ + do \ + { \ + std::cout << prefix; \ + switch (eTag) \ + { \ + case HWPTAG_DOCUMENT_PROPERTIES: std::cout << "HWPTAG_DOCUMENT_PROPERTIES"; break; \ + case HWPTAG_ID_MAPPINGS: std::cout << "HWPTAG_ID_MAPPINGS"; break; \ + case HWPTAG_BIN_DATA: std::cout << "HWPTAG_BIN_DATA"; break; \ + case HWPTAG_FACE_NAME: std::cout << "HWPTAG_FACE_NAME"; break; \ + case HWPTAG_BORDER_FILL: std::cout << "HWPTAG_BORDER_FILL"; break; \ + case HWPTAG_HWP_CHAR_SHAPE: std::cout << "HWPTAG_HWP_CHAR_SHAPE"; break; \ + case HWPTAG_TAB_DEF: std::cout << "HWPTAG_TAB_DEF"; break; \ + case HWPTAG_NUMBERING: std::cout << "HWPTAG_NUMBERING"; break; \ + case HWPTAG_BULLET: std::cout << "HWPTAG_BULLET"; break; \ + case HWPTAG_PARA_SHAPE: std::cout << "HWPTAG_PARA_SHAPE"; break; \ + case HWPTAG_STYLE: std::cout << "HWPTAG_STYLE"; break; \ + case HWPTAG_DOC_DATA: std::cout << "HWPTAG_DOC_DATA"; break; \ + case HWPTAG_DISTRIBUTE_DOC_DATA: std::cout << "HWPTAG_DISTRIBUTE_DOC_DATA"; break; \ + case HWPTAG_COMPATIBLE_DOCUMENT: std::cout << "HWPTAG_COMPATIBLE_DOCUMENT"; break; \ + case HWPTAG_LAYOUT_COMPATIBILITY: std::cout << "HWPTAG_LAYOUT_COMPATIBILITY"; break; \ + case HWPTAG_TRACKCHANGE: std::cout << "HWPTAG_TRACKCHANGE"; break; \ + case HWPTAG_PARA_HEADER: std::cout << "HWPTAG_PARA_HEADER"; break; \ + case HWPTAG_PARA_TEXT: std::cout << "HWPTAG_PARA_TEXT"; break; \ + case HWPTAG_PARA_HWP_CHAR_SHAPE: std::cout << "HWPTAG_PARA_HWP_CHAR_SHAPE"; break; \ + case HWPTAG_PARA_LINE_SEG: std::cout << "HWPTAG_PARA_LINE_SEG"; break; \ + case HWPTAG_PARA_RANGE_TAG: std::cout << "HWPTAG_PARA_RANGE_TAG"; break; \ + case HWPTAG_CTRL_HEADER: std::cout << "HWPTAG_CTRL_HEADER"; break; \ + case HWPTAG_LIST_HEADER: std::cout << "HWPTAG_LIST_HEADER"; break; \ + case HWPTAG_PAGE_DEF: std::cout << "HWPTAG_PAGE_DEF"; break; \ + case HWPTAG_FOOTNOTE_SHAPE: std::cout << "HWPTAG_FOOTNOTE_SHAPE"; break; \ + case HWPTAG_PAGE_BORDER_FILL: std::cout << "HWPTAG_PAGE_BORDER_FILL"; break; \ + case HWPTAG_SHAPE_COMPONENT: std::cout << "HWPTAG_SHAPE_COMPONENT"; break; \ + case HWPTAG_TABLE: std::cout << "HWPTAG_TABLE"; break; \ + case HWPTAG_SHAPE_COMPONENT_LINE: std::cout << "HWPTAG_SHAPE_COMPONENT_LINE"; break; \ + case HWPTAG_SHAPE_COMPONENT_RECTANGLE: std::cout << "HWPTAG_SHAPE_COMPONENT_RECTANGLE"; break; \ + case HWPTAG_SHAPE_COMPONENT_ELLIPSE: std::cout << "HWPTAG_SHAPE_COMPONENT_ELLIPSE"; break; \ + case HWPTAG_SHAPE_COMPONENT_ARC: std::cout << "HWPTAG_SHAPE_COMPONENT_ARC"; break; \ + case HWPTAG_SHAPE_COMPONENT_POLYGON: std::cout << "HWPTAG_SHAPE_COMPONENT_POLYGON"; break; \ + case HWPTAG_SHAPE_COMPONENT_CURVE: std::cout << "HWPTAG_SHAPE_COMPONENT_CURVE"; break; \ + case HWPTAG_SHAPE_COMPONENT_OLE: std::cout << "HWPTAG_SHAPE_COMPONENT_OLE"; break; \ + case HWPTAG_SHAPE_COMPONENT_PICTURE: std::cout << "HWPTAG_SHAPE_COMPONENT_PICTURE"; break; \ + case HWPTAG_SHAPE_COMPONENT_CONTAINER: std::cout << "HWPTAG_SHAPE_COMPONENT_CONTAINER"; break; \ + case HWPTAG_CTRL_DATA: std::cout << "HWPTAG_CTRL_DATA"; break; \ + case HWPTAG_EQEDIT: std::cout << "HWPTAG_EQEDIT"; break; \ + case HWPTAG_SHAPE_COMPONENT_TEXTART: std::cout << "HWPTAG_SHAPE_COMPONENT_TEXTART"; break; \ + case HWPTAG_FORM_OBJECT: std::cout << "HWPTAG_FORM_OBJECT"; break; \ + case HWPTAG_MEMO_SHAPE: std::cout << "HWPTAG_MEMO_SHAPE"; break; \ + case HWPTAG_MEMO_LIST: std::cout << "HWPTAG_MEMO_LIST"; break; \ + case HWPTAG_FORBIDDEN_HWP_CHAR: std::cout << "HWPTAG_FORBIDDEN_HWP_CHAR"; break; \ + case HWPTAG_HWP_CHART_DATA: std::cout << "HWPTAG_HWP_CHART_DATA"; break; \ + case HWPTAG_TRACK_CHANGE: std::cout << "HWPTAG_TRACK_CHANGE"; break; \ + case HWPTAG_TRACK_CHANGE_AUTHOR: std::cout << "HWPTAG_TRACK_CHANGE_AUTHOR"; break; \ + case HWPTAG_VIDEO_DATA: std::cout << "HWPTAG_VIDEO_DATA"; break; \ + case HWPTAG_SHAPE_COMPONENT_UNKNOWN: std::cout << "HWPTAG_SHAPE_COMPONENT_UNKNOWN"; break; \ + default: std::cout << "UNKNOWN"; break; \ + } \ + std::cout << postfix << std::endl; \ + } \ + while (false) +#else +#define PRINT_HWPTAG(prefix, tag, postfix) do {} while(false) +#endif + +namespace HWP +{ +CHWPSection::CHWPSection() +{} + +CHWPSection::~CHWPSection() +{ + CLEAR_ARRAY(CHWPPargraph, m_arParas); +} + +bool CHWPSection::Parse(CXMLNode& oNode, int nVersion) +{ + std::vector arParagraphNodes{oNode.GetChilds(L"hp:p")}; + + m_arParas.resize(arParagraphNodes.size()); + + for (unsigned int unIndex = 0; unIndex < arParagraphNodes.size(); ++unIndex) + m_arParas[unIndex] = new CHWPPargraph(arParagraphNodes[unIndex], nVersion); + + return true; +} + +bool CHWPSection::Parse(CHWPStream& oBuffer, int nVersion) +{ + oBuffer.MoveToStart(); + + int nHeader, nTagNum, nLevel, nSize; + + while (oBuffer.CanRead()) + { + oBuffer.ReadInt(nHeader); + oBuffer.Skip(-4); + nTagNum = nHeader & 0x3FF; // 10 bits (0 - 9 bit) + nLevel = (nHeader & 0xFFC00) >> 10; // 10 bits (10-19 bit) + nSize = (nHeader & 0xFFF00000) >> 20; // 12 bits (20-31 bit) + + if (nLevel > 0) + { + if (m_arParas.empty()) + return false; + + ParseRecurse(m_arParas.back(), nLevel, oBuffer, 0, nVersion); + continue; + } + + if (0xFFF == nSize) + { + //TODO:: buf[off+7]<<24&0xFF000000 | buf[off+6]<<16&0xFF0000 | buf[off+5]<<8&0xFF00 | buf[off+4]&0xFF; + oBuffer.Skip(4); + oBuffer.ReadInt(nSize); + } + else + oBuffer.Skip(4); + + EHWPTag eTag = GetTagFromNum(nTagNum); + + PRINT_HWPTAG("Main parse: ", eTag, " : size=" << std::to_string(nSize) << " level=" << std::to_string(nLevel)); + + if (0 == nLevel && HWPTAG_PARA_HEADER == eTag) + { + CHWPPargraph *pCurrPara = CHWPPargraph::Parse(nTagNum, nLevel, nSize, oBuffer, 0, nVersion); + + if (nullptr != pCurrPara) + m_arParas.push_back(pCurrPara); + + oBuffer.Skip(nSize); + } + } + + return true; +} + +template +T* FindLastElement(ECtrlObjectType eCtrlType, const VECTOR& arCtrls) +{ + for (VECTOR::const_reverse_iterator itCtrl = arCtrls.crbegin(); itCtrl != arCtrls.crend(); ++itCtrl) + { + if (eCtrlType == (*itCtrl)->GetCtrlType()) + return dynamic_cast(*itCtrl); + } + + return nullptr; +} + +int CHWPSection::ParseRecurse(CHWPPargraph* pCurrPara, int nRunLevel, CHWPStream& oBuffer, int nOff, int nVersion) +{ + oBuffer.SavePosition(); + + int nHeader, nTagNum, nLevel, nSize, nHeaderSize; + + while (oBuffer.CanRead()) + { + oBuffer.ReadInt(nHeader); + oBuffer.Skip(-4); + nTagNum = nHeader & 0x3FF; // 10 bits (0 - 9 bit) + nLevel = (nHeader & 0xFFC00) >> 10; // 10 bits (10-19 bit) + nSize = (nHeader & 0xFFF00000) >> 20; // 12 bits (20-31 bit) + + if (0xFFF == nSize) + { + nHeaderSize = 8; + //TODO:: buf[off+7]<<24&0xFF000000 | buf[off+6]<<16&0xFF0000 | buf[off+5]<<8&0xFF00 | buf[off+4]&0xFF; + oBuffer.Skip(4); + oBuffer.ReadInt(nSize); + oBuffer.Skip(-8); + } + else + { + nHeaderSize = 4; + } + + if (nLevel < nRunLevel) + break; + + EHWPTag eTag = GetTagFromNum(nTagNum); + + PRINT_HWPTAG("Recurse parse: ", eTag, " : size=" << std::to_string(nSize) << " level=" << std::to_string(nLevel)); + + if (nLevel > nRunLevel) + { + switch(eTag) + { + case HWPTAG_PARA_HEADER: + case HWPTAG_PARA_TEXT: + case HWPTAG_PARA_HWP_CHAR_SHAPE: + case HWPTAG_PARA_LINE_SEG: + case HWPTAG_PARA_RANGE_TAG: + case HWPTAG_CTRL_HEADER: + { + ParseRecurse(pCurrPara, nLevel, oBuffer, 0, nVersion); + break; + } + case HWPTAG_TABLE: + { + CCtrlTable *pTable = FindLastElement(ECtrlObjectType::Table, pCurrPara->GetCtrls()); + + if (nullptr != pTable) + ParseCtrlRecurse(pTable, nLevel, oBuffer, 0, nVersion); + + break; + } + case HWPTAG_LIST_HEADER: + { + oBuffer.Skip(nHeaderSize); + oBuffer.Skip(nSize); + break; + } + case HWPTAG_PAGE_DEF: + case HWPTAG_FOOTNOTE_SHAPE: + case HWPTAG_PAGE_BORDER_FILL: + { + CCtrlSectionDef *pCtrlSecDef = dynamic_cast(pCurrPara->FindLastElement(L"dces")); + + if (nullptr != pCtrlSecDef) + ParseCtrlRecurse(pCtrlSecDef, nLevel, oBuffer, 0, nVersion); + + break; + } + case HWPTAG_SHAPE_COMPONENT: + case HWPTAG_SHAPE_COMPONENT_PICTURE: + case HWPTAG_SHAPE_COMPONENT_LINE: + case HWPTAG_SHAPE_COMPONENT_RECTANGLE: + case HWPTAG_SHAPE_COMPONENT_ELLIPSE: + case HWPTAG_SHAPE_COMPONENT_ARC: + case HWPTAG_SHAPE_COMPONENT_POLYGON: + case HWPTAG_SHAPE_COMPONENT_CURVE: + case HWPTAG_SHAPE_COMPONENT_OLE: + case HWPTAG_EQEDIT: + case HWPTAG_SHAPE_COMPONENT_TEXTART: + case HWPTAG_SHAPE_COMPONENT_UNKNOWN: + { + CCtrlGeneralShape *pCtrlGeneral = dynamic_cast(pCurrPara->FindLastElement(L" osg")); + + if (nullptr != pCtrlGeneral) + ParseCtrlRecurse(pCtrlGeneral, nLevel, oBuffer, 0, nVersion); + + break; + } + case HWPTAG_CTRL_DATA: + case HWPTAG_FORM_OBJECT: + case HWPTAG_MEMO_SHAPE: + case HWPTAG_MEMO_LIST: + case HWPTAG_HWP_CHART_DATA: + case HWPTAG_VIDEO_DATA: + default: + { + CCtrlCommon *pCtrlCommon = FindLastElement(ECtrlObjectType::Common, pCurrPara->GetCtrls()); + + if (nullptr != pCtrlCommon) + ParseCtrlRecurse(pCtrlCommon, nLevel, oBuffer, 0, nVersion); + else + oBuffer.Skip(nHeaderSize); + + break; + } + } + } + else if (nLevel == nRunLevel) + { + oBuffer.Skip(nHeaderSize); + + switch (eTag) + { + case HWPTAG_PARA_HEADER: + { + if (EParagraphType::Cell == pCurrPara->GetType()) + { + oBuffer.Skip(-nHeaderSize); + return oBuffer.GetDistanceToLastPos(true); + } + else if (EParagraphType::Cap == pCurrPara->GetType()) + { + CHWPPargraph::Parse(*pCurrPara, nSize, oBuffer, 0, nVersion); + break; + } + else + { + if (1 == nRunLevel) //TODO:: проверить + { + oBuffer.Skip(nSize); + return oBuffer.GetDistanceToLastPos(true); + } + + oBuffer.Skip(-nHeaderSize); + return oBuffer.GetDistanceToLastPos(true); + } + } + case HWPTAG_PARA_TEXT: + { + pCurrPara->AddCtrls(CHWPRecordParaText::Parse(nTagNum, nLevel, nSize, oBuffer, 0, nVersion)); + break; + } + case HWPTAG_PARA_HWP_CHAR_SHAPE: + { + if (0 == pCurrPara->GetCountCtrls()) + pCurrPara->AddCtrl(new CCtrlCharacter(L" _", ECtrlCharType::PARAGRAPH_BREAK)); + + CCharShape::FillCharShape(nTagNum, nLevel, nSize, oBuffer, 0, nVersion, pCurrPara->GetCtrls()); + break; + } + case HWPTAG_PARA_LINE_SEG: + { + pCurrPara->SetLineSeg(new CLineSeg(nTagNum, nLevel, nSize, oBuffer, 0, nVersion)); + break; + } + case HWPTAG_PARA_RANGE_TAG: + { + CHWPRecordParaRangeTag::Parse(*pCurrPara, nTagNum, nLevel, nSize, oBuffer, 0, nVersion); + break; + } + case HWPTAG_CTRL_HEADER: + { + oBuffer.SavePosition(); + + CCtrl *pCtrl = CHWPRecordCtrlHeader::Parse(nTagNum, nLevel, nSize, oBuffer, 0, nVersion); + + if (nullptr == pCtrl) + { + oBuffer.Skip(nSize - oBuffer.GetDistanceToLastPos(true)); + break; + } + + if (ECtrlObjectType::Shape == pCtrl->GetCtrlType()) + ((CCtrlGeneralShape*)pCtrl)->SetParent(pCurrPara); + + unsigned int nIndex; + CCtrl* pCtrlOrigOp = pCurrPara->FindFirstElement(pCtrl->GetID(), false, nIndex); + + if (nullptr != pCtrlOrigOp) + pCurrPara->SetCtrl(pCtrl, nIndex); + + if (ECtrlObjectType::HeadFoot == pCtrl->GetCtrlType()) + { + CCtrlSectionDef* pSecD = dynamic_cast(pCurrPara->FindLastElement(L"dces")); + + if (nullptr != pSecD) + pSecD->AddHeadFoot((CCtrlHeadFoot*)pCtrl); + } + + oBuffer.Skip(nSize - oBuffer.GetDistanceToLastPos()); + ParseCtrlRecurse(pCtrl, nLevel, oBuffer, 0, nVersion); + + oBuffer.RemoveLastSavedPos(); + break; + } + case HWPTAG_TABLE: + { + oBuffer.Skip(-nHeaderSize); + return oBuffer.GetDistanceToLastPos(true); + } + case HWPTAG_LIST_HEADER: + { + if (1 == nRunLevel) + { + oBuffer.Skip(nSize); + return oBuffer.GetDistanceToLastPos(true); + } + oBuffer.Skip(-nHeaderSize); + return oBuffer.GetDistanceToLastPos(true); + } + case HWPTAG_SHAPE_COMPONENT: + case HWPTAG_SHAPE_COMPONENT_PICTURE: + case HWPTAG_SHAPE_COMPONENT_LINE: + case HWPTAG_SHAPE_COMPONENT_RECTANGLE: + case HWPTAG_SHAPE_COMPONENT_ELLIPSE: + case HWPTAG_SHAPE_COMPONENT_ARC: + case HWPTAG_SHAPE_COMPONENT_POLYGON: + case HWPTAG_SHAPE_COMPONENT_CURVE: + case HWPTAG_SHAPE_COMPONENT_OLE: + case HWPTAG_EQEDIT: + case HWPTAG_SHAPE_COMPONENT_TEXTART: + { + oBuffer.Skip(-nHeaderSize); + return oBuffer.GetDistanceToLastPos(true); + } + case HWPTAG_CTRL_DATA: + case HWPTAG_FORM_OBJECT: + case HWPTAG_MEMO_SHAPE: + case HWPTAG_MEMO_LIST: + case HWPTAG_HWP_CHART_DATA: + case HWPTAG_VIDEO_DATA: + case HWPTAG_SHAPE_COMPONENT_UNKNOWN: + { + oBuffer.Skip(nSize); + break; + } + default: {} + } + } + } + + return oBuffer.GetDistanceToLastPos(true); +} + +int CHWPSection::ParseCtrlRecurse(CCtrl* pCurrCtrl, int nRunLevel, CHWPStream& oBuffer, int nOff, int nVersion) +{ + CCtrl* pCtrl = pCurrCtrl; + + oBuffer.SavePosition(); + + int nHeader, nTagNum, nLevel, nSize, nHeaderSize; + + while (oBuffer.CanRead()) + { + oBuffer.ReadInt(nHeader); + oBuffer.Skip(-4); + nTagNum = nHeader & 0x3FF; // 10 bits (0 - 9 bit) + nLevel = (nHeader & 0xFFC00) >> 10; // 10 bits (10-19 bit) + nSize = (nHeader & 0xFFF00000) >> 20; // 12 bits (20-31 bit) + + if (0xFFF == nSize) + { + nHeaderSize = 8; + //TODO:: buf[off+7]<<24&0xFF000000 | buf[off+6]<<16&0xFF0000 | buf[off+5]<<8&0xFF00 | buf[off+4]&0xFF; + oBuffer.Skip(4); + oBuffer.ReadInt(nSize); + oBuffer.Skip(-8); + } + else + { + nHeaderSize = 4; + } + + if (nLevel < nRunLevel) + break; + + EHWPTag eTag = GetTagFromNum(nTagNum); + + PRINT_HWPTAG("Recurse ctrl parse: ", eTag, " : size=" << std::to_string(nSize) << " level=" << std::to_string(nLevel)); + + if (nLevel > nRunLevel) + { + switch(eTag) + { + case HWPTAG_PARA_HEADER: + { + if (nullptr != dynamic_cast(pCtrl)) + ParseCtrlRecurse((CCtrlCommon*)pCtrl, nLevel, oBuffer, 0, nVersion); + else + { + oBuffer.Skip(nHeaderSize); + oBuffer.Skip(nSize); + } + break; + } + case HWPTAG_PARA_TEXT: + { + if (nullptr != dynamic_cast(pCtrl)) + { + CHWPPargraph* pLastPara = ((CCtrlCommon*)pCtrl)->GetLastPara(); + + if (nullptr == pLastPara) + { + oBuffer.Skip(nHeaderSize); + oBuffer.Skip(nSize); + break; + } + + ParseRecurse(pLastPara, nLevel, oBuffer, 0, nVersion); + } + else + { + oBuffer.Skip(nHeaderSize); + oBuffer.Skip(nSize); + } + break; + } + case HWPTAG_LIST_HEADER: + { + oBuffer.Skip(nHeaderSize); + + int nSubParaCount = CHWPRecordListHeader::GetCount(nTagNum, nLevel, nSize, oBuffer, 0, nVersion); + + if (ECtrlObjectType::Table == pCtrl->GetCtrlType()) + { + ParseListAppend(*(CCtrlCommon*)pCtrl, nSize - 6, oBuffer, 0, nVersion); + CCtrlTable *pCtrlTable = (CCtrlTable*)pCtrl; + if (pCtrlTable->HaveCells()) + { + //TODO:: проверить + break; + } + + CCapParagraph* pNewPara = new CCapParagraph(); + pCtrlTable->AddCaption(pNewPara); + ParseRecurse(pNewPara, nLevel, oBuffer, 0, nVersion); + } + else if (ECtrlObjectType::Shape == pCtrl->GetCtrlType()) + { + CCtrlCommon* pCtrlCommon = (CCtrlCommon*)pCtrl; + oBuffer.Skip(-6); + + pCtrlCommon->SetTextVerAlign(CHWPRecordListHeader::GetVertAlign(6, oBuffer, 0, nVersion)); + + ParseListAppend(*pCtrlCommon, nSize - 6, oBuffer, 0, nVersion); + ParseCtrlRecurse(pCtrlCommon, nLevel, oBuffer, 0, nVersion); + } + else if (ECtrlObjectType::HeadFoot == pCtrl->GetCtrlType() || + ECtrlObjectType::Note == pCtrl->GetCtrlType()) + { + ParseListAppend(*pCtrl, nSize - 6, oBuffer, 0, nVersion); + ParseCtrlRecurse(pCtrl, nLevel, oBuffer, 0, nVersion); + } + else + oBuffer.Skip(nSize - 6); + + break; + } + case HWPTAG_PAGE_DEF: + case HWPTAG_FOOTNOTE_SHAPE: + case HWPTAG_PAGE_BORDER_FILL: + { + if (ECtrlObjectType::SectionDef == pCtrl->GetCtrlType()) + ParseCtrlRecurse((CCtrlSectionDef*)pCtrl, nLevel, oBuffer, 0, nVersion); + + break; + } + case HWPTAG_SHAPE_COMPONENT: + case HWPTAG_SHAPE_COMPONENT_PICTURE: + case HWPTAG_SHAPE_COMPONENT_LINE: + case HWPTAG_SHAPE_COMPONENT_RECTANGLE: + case HWPTAG_SHAPE_COMPONENT_ELLIPSE: + case HWPTAG_SHAPE_COMPONENT_ARC: + case HWPTAG_SHAPE_COMPONENT_POLYGON: + case HWPTAG_SHAPE_COMPONENT_CURVE: + case HWPTAG_SHAPE_COMPONENT_OLE: + case HWPTAG_EQEDIT: + case HWPTAG_SHAPE_COMPONENT_TEXTART: + case HWPTAG_SHAPE_COMPONENT_UNKNOWN: + { + if (ECtrlObjectType::Shape == pCtrl->GetCtrlType()) + ParseCtrlRecurse((CCtrlGeneralShape*)pCtrl, nLevel, oBuffer, 0, nVersion); + else + return oBuffer.GetDistanceToLastPos(true); + + break; + } + case HWPTAG_TABLE: + { + ParseCtrlRecurse(pCtrl, nLevel, oBuffer, 0, nVersion); + break; + } + case HWPTAG_CTRL_HEADER: + { + return oBuffer.GetDistanceToLastPos(true); + } + case HWPTAG_PARA_RANGE_TAG: + case HWPTAG_CTRL_DATA: + case HWPTAG_FORM_OBJECT: + case HWPTAG_MEMO_SHAPE: + case HWPTAG_MEMO_LIST: + case HWPTAG_HWP_CHART_DATA: + case HWPTAG_VIDEO_DATA: + default: + { + ParseCtrlRecurse(pCtrl, nLevel, oBuffer, 0, nVersion); + break; + } + } + } + else if (nLevel == nRunLevel) + { + oBuffer.Skip(nHeaderSize); + + switch (eTag) + { + case HWPTAG_PARA_HEADER: + { + if (ECtrlObjectType::Table == pCtrl->GetCtrlType()) + { + CCtrlTable *pCtrltable = (CCtrlTable*)pCtrl; + if (!pCtrltable->HaveCells()) + { + CHWPPargraph *pNewPara = CHWPPargraph::Parse(nTagNum, nLevel, nSize, oBuffer, 0, nVersion); + pCtrltable->AddParagraph(pNewPara); + oBuffer.Skip(nSize); + ParseRecurse(pNewPara, nLevel, oBuffer, 0, nVersion); + } + else + { + CTblCell* pCell = pCtrltable->GetLastCell(); + + CCellParagraph* pNewPara = new CCellParagraph(); + pCell->AddParagraph(pNewPara); + + CHWPPargraph::Parse(*pNewPara, nSize, oBuffer, 0, nVersion); + ParseRecurse(pNewPara, nLevel, oBuffer, 0, nVersion); + } + } + else if (ECtrlObjectType::Shape == pCtrl->GetCtrlType() && EShapeType::Rect == ((CCtrlGeneralShape*)pCtrl)->GetShapeType()) + { + CHWPPargraph *pNewPara = CHWPPargraph::Parse(nTagNum, nLevel, nSize, oBuffer, 0, nVersion); + ((CCtrlCommon*)pCtrl)->AddParagraph(pNewPara); + CHWPPargraph::Parse(*pNewPara, nSize, oBuffer, 0, nVersion); + ParseRecurse(pNewPara, nLevel, oBuffer, 0, nVersion); + } + else if (ECtrlObjectType::Shape == pCtrl->GetCtrlType()) + { + CCtrlCommon *pCtrlCommon = (CCtrlCommon*)(pCtrl); + if (0 < pCtrlCommon->GetCaptionWidth() && pCtrlCommon->CaptionsEmpty()) + { + CCapParagraph *pNewPara = new CCapParagraph(); + pCtrlCommon->AddCaption(pNewPara); + CHWPPargraph::Parse(*pNewPara, nSize, oBuffer, 0, nVersion); + ParseRecurse(pNewPara, nLevel, oBuffer, 0, nVersion); + } + else + { + CHWPPargraph *pNewPara = CHWPPargraph::Parse(nTagNum, nLevel, nSize, oBuffer, 0, nVersion); + pCtrlCommon->AddParagraph(pNewPara); + CHWPPargraph::Parse(*pNewPara, nLevel, oBuffer, 0, nVersion); + ParseRecurse(pNewPara, nLevel, oBuffer, 0, nVersion); + } + } + else if (ECtrlObjectType::HeadFoot == pCtrl->GetCtrlType()) + { + CHWPPargraph *pNewPara = CHWPPargraph::Parse(nTagNum, nLevel, nSize, oBuffer, 0, nVersion); + ((CCtrlHeadFoot*)pCtrl)->AddParagraph(pNewPara); + oBuffer.Skip(nSize); + ParseRecurse(pNewPara, nLevel, oBuffer, 0, nVersion); + } + else if (ECtrlObjectType::SectionDef == pCtrl->GetCtrlType()) + { + CHWPPargraph *pNewPara = CHWPPargraph::Parse(nTagNum, nLevel, nSize, oBuffer, 0, nVersion); + ((CCtrlSectionDef*)pCtrl)->AddParagraph(pNewPara); + oBuffer.Skip(nSize); + ParseRecurse(pNewPara, nLevel, oBuffer, 0, nVersion); + } + else if (ECtrlObjectType::Note == pCtrl->GetCtrlType()) + { + CHWPPargraph *pNewPara = CHWPPargraph::Parse(nTagNum, nLevel, nSize, oBuffer, 0, nVersion); + ((CCtrlNote*)pCtrl)->AddParagraph(pNewPara); + oBuffer.Skip(nSize); + ParseRecurse(pNewPara, nLevel, oBuffer, 0, nVersion); + } + else + { + //TODO:: проверить + CHWPPargraph *pNewPara = CHWPPargraph::Parse(nTagNum, nLevel, nSize, oBuffer, 0, nVersion); + oBuffer.Skip(nSize); + ParseRecurse(pNewPara, nLevel, oBuffer, 0, nVersion); + delete pNewPara; + } + + break; + } + case HWPTAG_CTRL_HEADER: + { + oBuffer.Skip(-nHeaderSize); + return true; + } + case HWPTAG_PAGE_DEF: + { + if (ECtrlObjectType::SectionDef == pCtrl->GetCtrlType()) + ((CCtrlSectionDef*)pCtrl)->SetPage(CPage::Parse(nLevel, nSize, oBuffer, 0, nVersion)); + + break; + } + case HWPTAG_FOOTNOTE_SHAPE: + { + if (ECtrlObjectType::SectionDef != pCtrl->GetCtrlType()) + break; + + ((CCtrlSectionDef*)pCtrl)->AddNoteShape(CNoteShape::Parse(nLevel, nSize, oBuffer, 0, nVersion)); + + break; + } + case HWPTAG_PAGE_BORDER_FILL: + { + if (ECtrlObjectType::SectionDef != pCtrl->GetCtrlType()) + break; + + ((CCtrlSectionDef*)pCtrl)->AddPageBorderFill(CPageBorderFill::Parse(nLevel, nSize, oBuffer, 0, nVersion)); + + break; + } + case HWPTAG_TABLE: + { + int nLen = CCtrlTable::ParseCtrl(*(CCtrlTable*)pCtrl, nSize, oBuffer, 0, nVersion); + break; + } + case HWPTAG_LIST_HEADER: + { + if (ECtrlObjectType::Table != pCtrl->GetCtrlType()) + { + oBuffer.Skip(nSize); + break; + } + + EVertAlign eVerAlign = CHWPRecordListHeader::GetVertAlign(nSize, oBuffer, 0, nVersion); + + CTblCell* pCell = new CTblCell(nSize - 6, oBuffer, 0, nVersion); + pCell->SetVertAlign(eVerAlign); + + ((CCtrlTable*)pCtrl)->AddCell(pCell); + + break; + } + case HWPTAG_SHAPE_COMPONENT: + { + if (ECtrlObjectType::Shape == pCtrl->GetCtrlType() && EShapeType::Container == ((CCtrlGeneralShape*)pCtrl)->GetShapeType()) + { + oBuffer.Skip(-nHeaderSize); + ParseContainerRecurse((CCtrlContainer*)pCtrl, nLevel, oBuffer, 0, nVersion); + } + else if (ECtrlObjectType::Shape == pCtrl->GetCtrlType()) + { + CCtrlGeneralShape *pNewCtrl = CCtrlGeneralShape::Parse(*(CCtrlGeneralShape*)pCtrl, nSize, oBuffer, 0, nVersion); + CHWPPargraph *pParentPara = ((CCtrlGeneralShape*)pCtrl)->GetParent(); + int nCtrlIbdex = pParentPara->IndexOf(pCtrl); + + if (nCtrlIbdex >= 0) + pParentPara->SetCtrl(pNewCtrl, nCtrlIbdex); + else + pParentPara->AddCtrl(pNewCtrl); + + //TODO:: проверить + pCtrl = pNewCtrl; + } + + break; + } + + #define PROCESS_SHAPE_COMPONENT(type_component, class_component) \ + if (ECtrlObjectType::Shape != pCtrl->GetCtrlType() && type_component != ((CCtrlGeneralShape*)pCtrl)->GetShapeType()) \ + { \ + oBuffer.Skip(nSize); \ + break; \ + } \ + class_component::ParseElement(*(class_component*)pCtrl, nSize, oBuffer, 0, nVersion) + + case HWPTAG_SHAPE_COMPONENT_PICTURE: + { + PROCESS_SHAPE_COMPONENT(EShapeType::Pic, CCtrlShapePic); + break; + } + case HWPTAG_SHAPE_COMPONENT_LINE: + { + PROCESS_SHAPE_COMPONENT(EShapeType::Line, CCtrlShapeLine); + break; + } + case HWPTAG_SHAPE_COMPONENT_RECTANGLE: + { + PROCESS_SHAPE_COMPONENT(EShapeType::Rect, CCtrlShapeRect); + break; + } + case HWPTAG_SHAPE_COMPONENT_ELLIPSE: + { + PROCESS_SHAPE_COMPONENT(EShapeType::Ellipse, CCtrlShapeEllipse); + break; + } + case HWPTAG_SHAPE_COMPONENT_ARC: + { + PROCESS_SHAPE_COMPONENT(EShapeType::Arc, CCtrlShapeArc); + break; + } + case HWPTAG_SHAPE_COMPONENT_POLYGON: + { + PROCESS_SHAPE_COMPONENT(EShapeType::Polygon, CCtrlShapePolygon); + break; + } + case HWPTAG_SHAPE_COMPONENT_CURVE: + { + PROCESS_SHAPE_COMPONENT(EShapeType::Curve, CCtrlShapeCurve); + break; + } + case HWPTAG_SHAPE_COMPONENT_OLE: + { + PROCESS_SHAPE_COMPONENT(EShapeType::Ole, CCtrlShapeOle); + break; + } + case HWPTAG_EQEDIT: + { + PROCESS_SHAPE_COMPONENT(EShapeType::EqEdit, CCtrlEqEdit); + break; + } + case HWPTAG_VIDEO_DATA: + { + PROCESS_SHAPE_COMPONENT(EShapeType::Video, CCtrlShapeVideo); + break; + } + case HWPTAG_SHAPE_COMPONENT_TEXTART: + { + PROCESS_SHAPE_COMPONENT(EShapeType::TextArt, CCtrlShapeTextArt); + break; + } + case HWPTAG_FORM_OBJECT: + { + if (nullptr == dynamic_cast(pCtrl)) + { + oBuffer.Skip(nSize); + break; + } + + CHWPRecordFormObject::ParseCtrl(*(CCtrlForm*)pCtrl, nSize, oBuffer, 0, nVersion); + break; + } + case HWPTAG_CTRL_DATA: + { + CHWPRecordCtrlData::ParseCtrl(*pCtrl, nSize, oBuffer, 0, nVersion); + break; + } + case HWPTAG_SHAPE_COMPONENT_UNKNOWN: + default: + { + oBuffer.Skip(nSize); + break; + } + } + } + } + + oBuffer.RemoveLastSavedPos(); + + return 0; +} + +template +void CheckAndParseShape(EShapeType eShapeType, CCtrlContainer* pContainer, CHWPStream& oBuffer, int nSize, int nVersion) +{ + T* pCtrl = nullptr; + + const VECTOR arCtrls = pContainer->GetShapes(); + + for (VECTOR::const_reverse_iterator itCtrl = arCtrls.crbegin(); itCtrl != arCtrls.crend(); ++itCtrl) + { + if (eShapeType == (*itCtrl)->GetShapeType()) + { + pCtrl = dynamic_cast(*itCtrl); + break; + } + } + + if (nullptr == pCtrl) + { + pCtrl = new T(); + + if (nullptr != pContainer) + pContainer->AddShape(pCtrl); + } + + T::ParseElement((T&)(*pCtrl), nSize, oBuffer, 0, nVersion); +} + +int CHWPSection::ParseContainerRecurse(CCtrlContainer* pContainer, int nRunLevel, CHWPStream& oBuffer, int nOff, int nVersion) +{ + oBuffer.SavePosition(); + + int nHeader, nTagNum, nLevel, nSize, nHeaderSize; + + while (oBuffer.CanRead()) + { + oBuffer.ReadInt(nHeader); + oBuffer.Skip(-4); + nTagNum = nHeader & 0x3FF; // 10 bits (0 - 9 bit) + nLevel = (nHeader & 0xFFC00) >> 10; // 10 bits (10-19 bit) + nSize = (nHeader & 0xFFF00000) >> 20; // 12 bits (20-31 bit) + + if (0xFFF == nSize) + { + nHeaderSize = 8; + //TODO:: buf[off+7]<<24&0xFF000000 | buf[off+6]<<16&0xFF0000 | buf[off+5]<<8&0xFF00 | buf[off+4]&0xFF; + oBuffer.Skip(4); + oBuffer.ReadInt(nSize); + oBuffer.Skip(-8); + } + else + { + nHeaderSize = 4; + } + + if (nLevel < nRunLevel) + break; + + EHWPTag eTag = GetTagFromNum(nTagNum); + + PRINT_HWPTAG("Container parse: ", eTag, " : size=" << std::to_string(nSize) << " level=" << std::to_string(nLevel)); + + if (nLevel > nRunLevel) + { + oBuffer.Skip(nHeaderSize); + + switch (eTag) + { + case HWPTAG_SHAPE_COMPONENT_PICTURE: + { + CheckAndParseShape(EShapeType::Pic, pContainer, oBuffer, nSize, nVersion); + break; + } + case HWPTAG_SHAPE_COMPONENT_LINE: + { + CheckAndParseShape(EShapeType::Line, pContainer, oBuffer, nSize, nVersion); + break; + } + case HWPTAG_SHAPE_COMPONENT_RECTANGLE: + { + CheckAndParseShape(EShapeType::Rect, pContainer, oBuffer, nSize, nVersion); + break; + } + case HWPTAG_SHAPE_COMPONENT_ELLIPSE: + { + CheckAndParseShape(EShapeType::Ellipse, pContainer, oBuffer, nSize, nVersion); + break; + } + case HWPTAG_SHAPE_COMPONENT_ARC: + { + CheckAndParseShape(EShapeType::Arc, pContainer, oBuffer, nSize, nVersion); + break; + } + case HWPTAG_SHAPE_COMPONENT_POLYGON: + { + CheckAndParseShape(EShapeType::Polygon, pContainer, oBuffer, nSize, nVersion); + break; + } + case HWPTAG_SHAPE_COMPONENT_CURVE: + { + CheckAndParseShape(EShapeType::Curve, pContainer, oBuffer, nSize, nVersion); + break; + } + case HWPTAG_SHAPE_COMPONENT_OLE: + { + CheckAndParseShape(EShapeType::Ole, pContainer, oBuffer, nSize, nVersion); + break; + } + case HWPTAG_EQEDIT: + { + CheckAndParseShape(EShapeType::EqEdit, pContainer, oBuffer, nSize, nVersion); + break; + } + case HWPTAG_SHAPE_COMPONENT_TEXTART: + { + CheckAndParseShape(EShapeType::TextArt, pContainer, oBuffer, nSize, nVersion); + break; + } + case HWPTAG_LIST_HEADER: + { + CCtrlGeneralShape* pCtrl = pContainer->GetLastShape(); + int nSubParaCount = CHWPRecordListHeader::GetCount(nTagNum, nLevel, nSize, oBuffer, 0, nVersion); + + if (EShapeType::Rect == pCtrl->GetShapeType() || EShapeType::Polygon == pCtrl->GetShapeType()) + { + if (EShapeType::Rect == pCtrl->GetShapeType()) + pCtrl->SetID(L"cer$"); + else + pCtrl->SetID(L"lop$"); + + oBuffer.Skip(-6); + pCtrl->SetTextVerAlign(CHWPRecordListHeader::GetVertAlign(6, oBuffer, 0, nVersion)); + ParseListAppend(*pCtrl, nSize -6, oBuffer, 0, nVersion); + ParseCtrlRecurse(pCtrl, nLevel, oBuffer, 0, nVersion); + } + else + oBuffer.Skip(nSize - 6); + + break; + } + case HWPTAG_SHAPE_COMPONENT: + { + CCtrlGeneralShape oBaseCtrl; + CCtrlGeneralShape *pNewCtrl = CCtrlGeneralShape::Parse(oBaseCtrl, nSize, oBuffer, 0, nVersion); + + if (nullptr == pNewCtrl) + break; + + pContainer->AddShape(pNewCtrl); + + if (EShapeType::Container != pNewCtrl->GetShapeType()) + break; + + ParseContainerRecurse((CCtrlContainer*)pNewCtrl, nLevel, oBuffer, 0, nVersion); + break; + } + case HWPTAG_SHAPE_COMPONENT_UNKNOWN: + case HWPTAG_TABLE: + case HWPTAG_PARA_HEADER: + case HWPTAG_PARA_TEXT: + case HWPTAG_PAGE_DEF: + case HWPTAG_FOOTNOTE_SHAPE: + case HWPTAG_PAGE_BORDER_FILL: + case HWPTAG_PARA_RANGE_TAG: + case HWPTAG_CTRL_DATA: + case HWPTAG_FORM_OBJECT: + case HWPTAG_MEMO_SHAPE: + case HWPTAG_MEMO_LIST: + case HWPTAG_HWP_CHART_DATA: + case HWPTAG_VIDEO_DATA: + default: + { + oBuffer.Skip(nSize); + break; + } + } + } + else if (nLevel == nRunLevel) + { + oBuffer.Skip(nHeaderSize); + + switch (eTag) + { + case HWPTAG_PARA_HEADER: + case HWPTAG_CTRL_HEADER: + case HWPTAG_PAGE_DEF: + case HWPTAG_FOOTNOTE_SHAPE: + case HWPTAG_PAGE_BORDER_FILL: + case HWPTAG_TABLE: + case HWPTAG_LIST_HEADER: + case HWPTAG_VIDEO_DATA: + case HWPTAG_FORM_OBJECT: + case HWPTAG_CTRL_DATA: + { + oBuffer.Skip(nSize); + break; + } + case HWPTAG_SHAPE_COMPONENT: + { + CCtrlGeneralShape oBaseCtrl; + CCtrlGeneralShape *pNewCtrl = CCtrlGeneralShape::Parse(oBaseCtrl, nSize, oBuffer, 0, nVersion); + + if (nullptr == pNewCtrl) + break; + + pContainer->AddShape(pNewCtrl); + + if (EShapeType::Container != pNewCtrl->GetShapeType()) + break; + + ParseContainerRecurse((CCtrlContainer*)pNewCtrl, nLevel, oBuffer, 0, nVersion); + break; + } + case HWPTAG_SHAPE_COMPONENT_PICTURE: + case HWPTAG_SHAPE_COMPONENT_LINE: + case HWPTAG_SHAPE_COMPONENT_RECTANGLE: + case HWPTAG_SHAPE_COMPONENT_ELLIPSE: + case HWPTAG_SHAPE_COMPONENT_ARC: + case HWPTAG_SHAPE_COMPONENT_POLYGON: + case HWPTAG_SHAPE_COMPONENT_CURVE: + case HWPTAG_SHAPE_COMPONENT_OLE: + case HWPTAG_EQEDIT: + case HWPTAG_SHAPE_COMPONENT_TEXTART: + case HWPTAG_SHAPE_COMPONENT_UNKNOWN: + default: + { + oBuffer.Skip(nSize); + break; + } + } + } + } + + return oBuffer.GetDistanceToLastPos(true); +} + +VECTOR CHWPSection::GetParagraphs() const +{ + VECTOR arParagraphs(m_arParas.size()); + + for (unsigned int unIndex = 0; unIndex < m_arParas.size(); ++unIndex) + arParagraphs[unIndex] = dynamic_cast(m_arParas[unIndex]); + + return arParagraphs; +} + +int CHWPSection::ParseListAppend(CCtrlCommon& oObj, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) +{ + oBuffer.SavePosition(); + + if (L"cer$" == oObj.GetID()) + CCtrlShapeRect::ParseListHeaderAppend((CCtrlShapeRect&)(oObj), nSize, oBuffer, 0, nVersion); + else if (L" osg" == oObj.GetID()) + CCtrlGeneralShape::ParseListHeaderApend((CCtrlGeneralShape&)(oObj), nSize, oBuffer, 0, nVersion); + else if (L" lbt" == oObj.GetID()) + CCtrlTable::ParseListHeaderAppend((CCtrlTable&)(oObj), nSize, oBuffer, 0, nVersion); + else if (L"deqe" == oObj.GetID()) + CCtrlEqEdit::ParseListHeaderAppend((CCtrlEqEdit&)(oObj), nSize, oBuffer, 0, nVersion); + else if (L"lop$" == oObj.GetID()) + CCtrlShapePolygon::ParseListHeaderAppend((CCtrlShapePolygon&)(oObj), nSize, oBuffer, 0, nVersion); + else if (L"lle$" == oObj.GetID()) + CCtrlShapeEllipse::ParseListHeaderAppend((CCtrlShapeEllipse&)(oObj), nSize, oBuffer, 0, nVersion); + else + oBuffer.Skip(nSize - oBuffer.GetDistanceToLastPos()); + + return oBuffer.GetDistanceToLastPos(true); +} + +int CHWPSection::ParseListAppend(CCtrl& oObj, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) +{ + if (L"dces" == oObj.GetID()) + oBuffer.Skip(nSize - 6); + else if (L"daeh" == oObj.GetID() || L"toof" == oObj.GetID()) + { + oBuffer.SavePosition(); + CCtrlHeadFoot::ParseListHeaderAppend((CCtrlHeadFoot&)(oObj), nSize, oBuffer, 0, nVersion); + oBuffer.Skip(nSize - oBuffer.GetDistanceToLastPos(true)); + } + else + oBuffer.Skip(nSize); + + return nSize; +} +} diff --git a/HwpFile/HwpDoc/HWPSection.h b/HwpFile/HwpDoc/HWPSection.h new file mode 100644 index 00000000000..dbeb8ffd248 --- /dev/null +++ b/HwpFile/HwpDoc/HWPSection.h @@ -0,0 +1,29 @@ +#ifndef HWPSECTION_H +#define HWPSECTION_H + +#include "Paragraph/HWPPargraph.h" +#include "Paragraph/CtrlContainer.h" + +namespace HWP +{ +class CHWPSection +{ + VECTOR m_arParas; + + int ParseListAppend(CCtrlCommon& oObj, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); + int ParseListAppend(CCtrl& oObj, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); +public: + CHWPSection(); + ~CHWPSection(); + + bool Parse(CXMLNode& oNode, int nVersion); + bool Parse(CHWPStream& oBuffer, int nVersion); + int ParseRecurse(CHWPPargraph* oCurrPara, int nRunLevel, CHWPStream& oBuffer, int nOff, int nVersion); + int ParseCtrlRecurse(CCtrl* oCurrCtrl, int nRunLevel, CHWPStream& oBuffer, int nOff, int nVersion); + int ParseContainerRecurse(CCtrlContainer* oContainer, int nRunLevel, CHWPStream& oBuffer, int nOff, int nVersion); + + VECTOR GetParagraphs() const; +}; +} + +#endif // HWPSECTION_H diff --git a/HwpFile/HwpDoc/HWPStream.cpp b/HwpFile/HwpDoc/HWPStream.cpp new file mode 100644 index 00000000000..fec0d4b31a4 --- /dev/null +++ b/HwpFile/HwpDoc/HWPStream.cpp @@ -0,0 +1,368 @@ +#include "HWPStream.h" + +#include "../../DesktopEditor/common/StringExt.h" + +namespace HWP +{ +CHWPStream::CHWPStream() + : m_pBegin(nullptr), m_pCur(nullptr), m_pEnd(nullptr), m_bExternalBuffer(false) +{} + +CHWPStream::CHWPStream(unsigned long ulSize) + : m_pBegin(nullptr), m_pCur(nullptr), m_pEnd(nullptr), m_bExternalBuffer(false) +{ + Expand(ulSize); +} + +CHWPStream::CHWPStream(HWP_BYTE* pBuffer, unsigned long ulSize, bool bExternalBuffer) + : m_pBegin(pBuffer), m_pCur(pBuffer), m_pEnd(pBuffer + ulSize), m_bExternalBuffer(bExternalBuffer) +{} + +CHWPStream::~CHWPStream() +{ + Clear(); +} + +void CHWPStream::Clear() +{ + if (nullptr != m_pBegin && !m_bExternalBuffer) + free(m_pBegin); + + m_pBegin = nullptr; + m_pCur = nullptr; + m_pEnd = nullptr; + + while (!m_arSavedPositions.empty()) + m_arSavedPositions.pop(); +} + +void CHWPStream::Copy(CHWPStream& oStream, unsigned long ulSize) +{ + memcpy(m_pCur, oStream.GetCurPtr(), (std::min)(SizeToEnd(), (unsigned long)(std::min)(ulSize, oStream.SizeToEnd()))); +} + +void CHWPStream::SetStream(HWP_BYTE* pBuffer, unsigned long ulSize, bool bExternalBuffer) +{ + m_pBegin = pBuffer; + m_pCur = pBuffer; + m_pEnd = pBuffer + ulSize; + + m_bExternalBuffer = bExternalBuffer; +} + +HWP_BYTE* CHWPStream::GetCurPtr() +{ + return m_pCur; +} + +unsigned long CHWPStream::Tell() const +{ + return (!IsValid()) ? 0 : m_pCur - m_pBegin; +} + +unsigned long CHWPStream::SizeToEnd() const +{ + return (!IsValid() || IsEof()) ? 0 : m_pEnd - m_pCur; +} + +void CHWPStream::Expand(unsigned long ulSize) +{ + if (nullptr != m_pBegin) + { + unsigned long ulCurrentPos = Tell(); + unsigned long ulNewSize = GetSize() + ulSize; + + m_pBegin = (HWP_BYTE*)realloc(m_pBegin, ulNewSize); + m_pEnd = m_pBegin + ulNewSize; + m_pCur = m_pBegin + ulCurrentPos; + } + else + { + m_pBegin = (HWP_BYTE*)malloc(ulSize); + m_pBegin[0] = 0x11; + m_pEnd = m_pBegin + ulSize; + m_pCur = m_pBegin; + } +} + +bool CHWPStream::ReadChar(HWP_CHAR& chValue) +{ + if (m_pCur + 2 > m_pEnd) + return false; + + chValue = (HWP_CHAR)(((m_pCur[1] << 8) & 0x0000FF00) | (m_pCur[0] & 0x000000FF)); + m_pCur += 2; + + return true; +} + +bool CHWPStream::ReadFloat(float& fValue) +{ + //TODO:: Проверить + int nValue; + if (!ReadInt(nValue)) + return false; + + fValue = *(float*)&nValue; + + return true; +} + +bool CHWPStream::ReadDouble(double& dValue) +{ + //TODO:: реализовать + long long lValue; + if (!ReadLong(lValue)) + return false; + + dValue = *(double*)&lValue; + + return true; +} + +bool CHWPStream::ReadLong(long long& lValue) +{ + if (m_pCur + 8 > m_pEnd) + return false; + + lValue = ((m_pCur[7] << 24) & 0xFF000000) | ((m_pCur[6 ]<< 16) & 0xFF0000) | ((m_pCur[5] << 8) & 0xFF00) | (m_pCur[4] & 0xFF); + lValue = (lValue << 32) | ((m_pCur[3] << 24) & 0xFF000000) | ((m_pCur[2] << 16) & 0xFF0000) | ((m_pCur[1] << 8) & 0xFF00) | (m_pCur[0] & 0xFF); + + m_pCur += 8; + + return true; +} + +bool CHWPStream::ReadInt(int& nValue) +{ + if (m_pCur + 4 > m_pEnd) + return false; + + nValue = ((m_pCur[3] << 24) & 0xFF000000) | ((m_pCur[2] << 16) & 0x00FF0000) | ((m_pCur[1] << 8) & 0x0000FF00) | (m_pCur[0] & 0x000000FF); + m_pCur += 4; + + return true; +} + +bool CHWPStream::ReadColor(int& nValue) +{ + if (m_pCur + 4 > m_pEnd) + return false; + + nValue = ((m_pCur[3] << 24) & 0xFF000000) | ((m_pCur[0] << 16) & 0x00FF0000) | ((m_pCur[1] << 8) & 0x0000FF00) | (m_pCur[2] & 0x000000FF); + m_pCur += 4; + + return true; +} + +bool CHWPStream::ReadShort(short& shValue) +{ + if (m_pCur + 2 > m_pEnd) + return false; + + shValue = (short)(((m_pCur[1] << 8) & 0x0000FF00) | (m_pCur[0] & 0x000000FF)); + m_pCur += 2; + + return true; +} + +short CHWPStream::ReadShort() +{ + if (m_pCur + 1 > m_pEnd) + return 0; + + short shValue = (short)(((m_pCur[1] << 8) & 0x0000FF00) | (m_pCur[0] & 0x000000FF)); + m_pCur += 2; + + return shValue; +} + +bool CHWPStream::ReadByte(HWP_BYTE& chValue) +{ + if (m_pCur + 1 > m_pEnd) + return false; + + chValue = m_pCur[0]; + ++m_pCur; + + return true; +} + +HWP_BYTE CHWPStream::ReadByte() +{ + if (m_pCur + 1 > m_pEnd) + return 0; + + HWP_BYTE chValue = m_pCur[0]++; + ++m_pCur; + + return chValue; +} + +void Trim(HWP_STRING& sValue) +{ + HWP_STRING::const_iterator itBegin = std::find_if(sValue.cbegin(), sValue.cend(), [](wchar_t wChar){ return !iswcntrl(wChar); }); + + if (itBegin != sValue.cend()) + sValue.erase(0, itBegin - sValue.cbegin()); + + HWP_STRING::const_reverse_iterator itEnd = std::find_if(sValue.crbegin(), sValue.crend(), [](wchar_t wChar){ return !iswcntrl(wChar); }); + + if (itEnd != sValue.crbegin()) + sValue.erase(itEnd.base()); +} + +bool CHWPStream::ReadString(HWP_STRING& sValue, EStringCharacter eCharacter) +{ + short shLen; + if (!ReadShort(shLen)) + return false; + + return ReadString(sValue, (int)shLen * 2, eCharacter); +} + +bool CHWPStream::ReadString(HWP_STRING& sValue, int nLength, EStringCharacter eCharacter) +{ + sValue.clear(); + + if (0 == nLength) + return true; + + if (!CanRead(nLength)) + nLength = m_pEnd - GetCurPtr(); + + switch (eCharacter) + { + case EStringCharacter::ASCII: + { + sValue = NSStringExt::CConverter::GetUnicodeFromSingleByteString((unsigned char*)GetCurPtr(), nLength); + break; + } + case EStringCharacter::UTF16: + { + sValue = NSStringExt::CConverter::GetUnicodeFromUTF16((unsigned short*)GetCurPtr(), nLength / 2); + break; + } + case EStringCharacter::UTF32: + { + sValue = NSStringExt::CConverter::GetUnicodeFromUTF32((unsigned int*)GetCurPtr(), nLength / 4); + break; + } + } + + Trim(sValue); + Skip(nLength); + + return true; +} + +unsigned long CHWPStream::ReadBytes(HWP_BYTE* pBytes, unsigned long unSize) +{ + if (!IsValid() || IsEof()) + return 0; + + unsigned long ulNewSize = (std::min)(unSize, SizeToEnd()); + + memcpy(pBytes, m_pCur, ulNewSize); + m_pCur += ulNewSize; + return ulNewSize; +} + +void CHWPStream::Skip(int nStep) +{ + if (nStep > 0) + { + if (m_pCur + nStep > m_pEnd) + m_pCur = m_pEnd; + else + m_pCur += nStep; + } + else if (nStep < 0) + { + if (m_pCur + nStep > m_pBegin) + m_pCur += nStep; + else + m_pCur = m_pBegin; + } +} + +void CHWPStream::MoveToStart() +{ + m_pCur = m_pBegin; + + while (!m_arSavedPositions.empty()) + m_arSavedPositions.pop(); +} + +void CHWPStream::MoveTo(unsigned int unPosition) +{ + if (unPosition < m_pEnd - m_pBegin) + m_pCur = m_pBegin + unPosition; + else + m_pCur = m_pEnd; +} + +bool CHWPStream::CanRead(int nSize) const +{ + if (!IsValid()) + return false; + + return m_pCur + nSize <= m_pEnd; +} + +bool CHWPStream::IsValid() const +{ + return nullptr != m_pBegin; +} + +bool CHWPStream::IsEof() const +{ + return m_pCur > m_pEnd; +} + +unsigned int CHWPStream::GetSize() const +{ + return (unsigned int)(m_pEnd - m_pBegin); +} + +void CHWPStream::SavePosition() +{ + m_arSavedPositions.push(m_pCur); +} + +void CHWPStream::RemoveLastSavedPos() +{ + if (!m_arSavedPositions.empty()) + m_arSavedPositions.pop(); +} + +int CHWPStream::GetDistanceToLastPos(bool bRemoveLastPos) +{ + int nDistance = (!m_arSavedPositions.empty()) ? m_pCur - m_arSavedPositions.top() : 0; + + if (bRemoveLastPos) + RemoveLastSavedPos(); + + return nDistance; +} + +HWP_BYTE CHWPStream::operator[](unsigned int unPosition) const +{ + if (m_pCur > m_pEnd) + return *(m_pEnd - 1); + + return *(m_pCur + unPosition); +} + +bool CHWPStream::WriteBytes(const HWP_BYTE* pBuffer, unsigned long ulSize) +{ + unsigned long ulSizeToEnd = SizeToEnd(); + + if (ulSize > ulSizeToEnd) + Expand(ulSize - ulSizeToEnd); + + memcpy(m_pCur, pBuffer, ulSize); + m_pCur += ulSize; + return true; +} +} diff --git a/HwpFile/HwpDoc/HWPStream.h b/HwpFile/HwpDoc/HWPStream.h new file mode 100644 index 00000000000..3ca6d63db4a --- /dev/null +++ b/HwpFile/HwpDoc/HWPStream.h @@ -0,0 +1,76 @@ +#ifndef HWPSTREAM_H +#define HWPSTREAM_H + +#include +#include "Common/Common.h" + +namespace HWP +{ +enum class EStringCharacter +{ + ASCII, + UTF16, + UTF32 +}; + +class CHWPStream +{ + HWP_BYTE* m_pBegin; + HWP_BYTE* m_pCur; + HWP_BYTE* m_pEnd; + std::stack m_arSavedPositions; + + bool m_bExternalBuffer; +public: + CHWPStream(); + CHWPStream(unsigned long ulSize); + CHWPStream(HWP_BYTE* pBuffer, unsigned long ulSize, bool bExternalBuffer = true); + ~CHWPStream(); + + void Clear(); + void Copy(CHWPStream& oStream, unsigned long ulSize); + + void SetStream(HWP_BYTE* pBuffer, unsigned long ulSize, bool bExternalBuffer = true); + + HWP_BYTE* GetCurPtr(); + unsigned long Tell() const; + unsigned long SizeToEnd() const; + + void Expand(unsigned long ulSize); + + bool ReadChar(HWP_CHAR& chValue); + bool ReadFloat(float& fValue); + bool ReadDouble(double& dValue); + bool ReadLong(long long& lValue); + bool ReadInt(int& nValue); + bool ReadColor(int& nValue); + bool ReadShort(short& shValue); + short ReadShort(); + bool ReadByte(HWP_BYTE& chValue); + HWP_BYTE ReadByte(); + bool ReadString(HWP_STRING& sValue, EStringCharacter eCharacter); + bool ReadString(HWP_STRING& sValue, int nLength, EStringCharacter eCharacter); + unsigned long ReadBytes(HWP_BYTE* pBytes, unsigned long unSize); + + void Skip(int nStep); + void MoveToStart(); + void MoveTo(unsigned int unPosition); + + bool CanRead(int nSize = 1) const; + bool IsValid() const; + bool IsEof() const; + unsigned int GetSize() const; + + void SavePosition(); + void RemoveLastSavedPos(); + int GetDistanceToLastPos(bool bRemoveLastPos = false); + + HWP_BYTE operator[](unsigned int unPosition) const; + + bool WriteBytes(const HWP_BYTE* pBuffer, unsigned long ulSize); +}; + +#define CHECK_FLAG(value, flag) ((value) & flag) == flag +} + +#endif // HWPSTREAM_H diff --git a/HwpFile/HwpDoc/HWPXFile.cpp b/HwpFile/HwpDoc/HWPXFile.cpp new file mode 100644 index 00000000000..19377036d88 --- /dev/null +++ b/HwpFile/HwpDoc/HWPXFile.cpp @@ -0,0 +1,181 @@ +#include "HWPXFile.h" + +#include + +namespace HWP +{ +CHWPXFile::CHWPXFile(const HWP_STRING& sFileName) + : m_sFileName(sFileName), m_pZipFolder(nullptr), m_oDocInfo(this) +{} + +CHWPXFile::~CHWPXFile() +{ + Close(); + CLEAR_ARRAY(CHWPSection, m_arSections); +} + +VECTOR CHWPXFile::GetSections() const +{ + RETURN_VECTOR_CONST_PTR(CHWPSection, m_arSections); +} + +bool CHWPXFile::Detect() +{ + BYTE *pBuffer = NULL; + DWORD dwBufferSize = 0; + + if (!NSFile::CFileBinary::ReadAllBytes(m_sFileName, &pBuffer, dwBufferSize)) + return false; + + m_pZipFolder = new CZipFolderMemory(pBuffer, dwBufferSize); + + return GetFileHeader(); +} + +bool CHWPXFile::Open() +{ + if (!NSFile::CFileBinary::Exists(m_sFileName)) + return false; + + if (m_oFileHeader.VersionEmpty() && !Detect()) + return false; + + m_nVersion = std::stoi(m_oFileHeader.GetVersion()); + + if (!GetDocInfo(m_nVersion)) + return false; + + std::vector arPathToSections{GetPathsToSections()}; + + for (const std::wstring& wsPath : arPathToSections) + ReadSection(wsPath, m_nVersion); + + return true; +} + +void CHWPXFile::Close() +{ + if (nullptr != m_pZipFolder) + { + delete m_pZipFolder; + m_pZipFolder = nullptr; + } +} + +VECTOR CHWPXFile::GetPathsToSections() const +{ + VECTOR arPaths{m_pZipFolder->getFiles(L"Contents", false)}; + + if (arPaths.empty()) + return VECTOR{}; + + struct TPathInfo + { + std::wstring m_wsPath; + unsigned short m_ushIndex; + + bool operator<(const TPathInfo& oPathInfo) const + { + return m_ushIndex < oPathInfo.m_ushIndex; + } + }; + + VECTOR arPathsToSectors; + size_t unFoundPos, unNumberStart, unNumberEnd; + + for (const std::wstring& wsPath : arPaths) + { + unFoundPos = wsPath.find(L"/Contents/section"); + if (std::wstring::npos ==unFoundPos) + continue; + + unNumberStart = unFoundPos + 17; + unNumberEnd = unNumberStart; + + while (unNumberEnd < wsPath.length() && iswdigit(wsPath[unNumberEnd])) + ++unNumberEnd; + + if (unNumberEnd == unNumberStart || + unNumberEnd >= wsPath.length() || + L".xml" != wsPath.substr(unNumberEnd, 4)) + continue; + + arPathsToSectors.push_back({wsPath, static_cast(std::stoi(wsPath.substr(unNumberStart, unNumberEnd - unNumberStart)))}); + } + + std::sort(arPathsToSectors.begin(), arPathsToSectors.end()); + + VECTOR arResult{arPathsToSectors.size()}; + + for (unsigned int unIndex = 0; unIndex < arPathsToSectors.size(); ++unIndex) + arResult[unIndex] = arPathsToSectors[unIndex].m_wsPath; + + return arResult; +} + +bool CHWPXFile::GetFileHeader() +{ + CXMLNode oVersionXml{GetDocument(L"version.xml")}; + return m_oFileHeader.Parse(oVersionXml); +} + +const CHWPDocInfo* CHWPXFile::GetDocInfo() const +{ + return &m_oDocInfo; +} + +bool CHWPXFile::GetChildStream(const HWP_STRING& sFileName, CHWPStream& oBuffer) +{ + if (nullptr == m_pZipFolder || !m_pZipFolder->exists(sFileName)) + return false; + + CZipFolderMemory::CBuffer *pFileBuffer = nullptr; + m_pZipFolder->read(sFileName, pFileBuffer); + + if (nullptr == pFileBuffer) + return false; + + pFileBuffer->UnsetDestroy(); + + oBuffer.SetStream((HWP_BYTE*)pFileBuffer->Buffer, pFileBuffer->Size); + + delete pFileBuffer; + + return true; +} + +bool CHWPXFile::GetDocInfo(int nVersion) +{ + CXMLNode oContent{GetDocument(L"Contents/content.hpf")}; + if (m_oDocInfo.ReadContentHpf(oContent, nVersion)) + { + CXMLNode oHeader{GetDocument(L"Contents/header.xml")}; + return m_oDocInfo.Parse(oHeader, nVersion); + } + + return false; +} + +bool CHWPXFile::ReadSection(const HWP_STRING& sName, int nVersion) +{ + CXMLNode oRootNode{GetDocument(sName)}; + + CHWPSection* pSection = new CHWPSection(); + const bool bResult = pSection->Parse(oRootNode, nVersion); + + if (bResult) + m_arSections.push_back(pSection); + else + delete pSection; + + return bResult; +} + +CXMLNode CHWPXFile::GetDocument(const HWP_STRING& sEntryName) +{ + if (nullptr == m_pZipFolder) + return CXMLNode(); + + return CXMLNode(m_pZipFolder->getNodeFromFile(sEntryName)); +} +} diff --git a/HwpFile/HwpDoc/HWPXFile.h b/HwpFile/HwpDoc/HWPXFile.h new file mode 100644 index 00000000000..867ad4cff48 --- /dev/null +++ b/HwpFile/HwpDoc/HWPXFile.h @@ -0,0 +1,39 @@ +#ifndef HWPXFILE_H +#define HWPXFILE_H + +#include "HWPSection.h" +#include "HwpFileHeader.h" + +#include "../../OfficeUtils/src/ZipFolder.h" + +namespace HWP +{ +class CHWPXFile +{ + HWP_STRING m_sFileName; + CZipFolderMemory *m_pZipFolder; + CHwpFileHeader m_oFileHeader; + int m_nVersion; + CHWPDocInfo m_oDocInfo; + VECTOR m_arSections; +public: + CHWPXFile(const HWP_STRING& sFileName); + ~CHWPXFile(); + + VECTOR GetSections() const; + const CHWPDocInfo* GetDocInfo() const; + bool GetChildStream(const HWP_STRING& sFileName, CHWPStream& oBuffer); + + bool Detect(); + bool Open(); + void Close(); +private: + VECTOR GetPathsToSections() const; + bool GetFileHeader(); + bool GetDocInfo(int nVersion); + bool ReadSection(const HWP_STRING& sName, int nVersion); + CXMLNode GetDocument(const HWP_STRING& sEntryName); +}; +} + +#endif // HWPXFILE_H diff --git a/HwpFile/HwpDoc/HanType.h b/HwpFile/HwpDoc/HanType.h new file mode 100644 index 00000000000..3960f921f15 --- /dev/null +++ b/HwpFile/HwpDoc/HanType.h @@ -0,0 +1,14 @@ +#ifndef HANTYPE_H +#define HANTYPE_H + +namespace HWP +{ +enum class EHanType +{ + NONE, + HWP, + HWPX +}; +} + +#endif // HANTYPE_H diff --git a/HwpFile/HwpDoc/HwpFileHeader.cpp b/HwpFile/HwpDoc/HwpFileHeader.cpp new file mode 100644 index 00000000000..7a5655eeed2 --- /dev/null +++ b/HwpFile/HwpDoc/HwpFileHeader.cpp @@ -0,0 +1,105 @@ +#include "HwpFileHeader.h" + +namespace HWP +{ +CHwpFileHeader::CHwpFileHeader() +{} + +bool CHwpFileHeader::Parse(CHWPStream& oBuffer) +{ + if (!oBuffer.IsValid()) + return false; + + oBuffer.ReadString(m_sSignature, 32, EStringCharacter::ASCII); + + if (L"HWP Document File" != m_sSignature) + return false; + + //version + m_sVersion = std::to_wstring((int)oBuffer[3]) + std::to_wstring((int)oBuffer[2]) + std::to_wstring((int)oBuffer[1]) + std::to_wstring((int)oBuffer[0]); + oBuffer.Skip(4); + + m_bCompressed = CHECK_FLAG(oBuffer[0], 0x01); + m_bPasswordEncrypted = CHECK_FLAG(oBuffer[0], 0x02); + m_bDistributable = CHECK_FLAG(oBuffer[0], 0x04); + m_bSaveScript = CHECK_FLAG(oBuffer[0], 0x08); + m_bDRMprotected = CHECK_FLAG(oBuffer[0], 0x10); + m_bHasXMLTemplateStorage =CHECK_FLAG(oBuffer[0], 0x20); + m_bHasDocumentHistory = CHECK_FLAG(oBuffer[0], 0x40); + m_bHasPkiSignature = CHECK_FLAG(oBuffer[0], 0x80); + + oBuffer.Skip(1); + + m_bPkiEncrypted = CHECK_FLAG(oBuffer[0], 0x01); + m_bReservePkiSignature = CHECK_FLAG(oBuffer[0], 0x02); + m_bPkiCertificateDRM = CHECK_FLAG(oBuffer[0], 0x04); + m_bCCLDocument = CHECK_FLAG(oBuffer[0], 0x08); + m_bMobileOptimized = CHECK_FLAG(oBuffer[0], 0x10); + m_bPrivateInformation = CHECK_FLAG(oBuffer[0], 0x20); + m_bModifyTracking = CHECK_FLAG(oBuffer[0], 0x40); + m_bCopyrightKOGL = CHECK_FLAG(oBuffer[0], 0x80); + + oBuffer.Skip(1); + + m_bHasVideoControl = CHECK_FLAG(oBuffer[0], 0x01); + m_bHasMarkFieldControl = CHECK_FLAG(oBuffer[0], 0x02); + + oBuffer.Skip(2); + + m_bCopyrighted = CHECK_FLAG(oBuffer[0], 0x01); + m_bCopyProhibited = CHECK_FLAG(oBuffer[0], 0x02); + m_bCopyPermitted = CHECK_FLAG(oBuffer[0], 0x04); + + oBuffer.Skip(4); + + //encryptVersion + oBuffer.Skip(4); + + m_nCountryKOGLLicensed = (int)oBuffer[0]; + + return true; +} + +bool CHwpFileHeader::Parse(CXMLNode& oNode) +{ + if (!oNode.IsValid()) + return false; + + m_sVersion += oNode.GetAttribute(L"major"); + m_sVersion += oNode.GetAttribute(L"minor"); + m_sVersion += oNode.GetAttribute(L"micro"); + m_sVersion += oNode.GetAttribute(L"buildNumber"); + + return true; +} + +bool CHwpFileHeader::Compressed() const +{ + return m_bCompressed; +} + +bool CHwpFileHeader::PasswordEncrypted() const +{ + return m_bPasswordEncrypted; +} + +bool CHwpFileHeader::Distributable() const +{ + return m_bDistributable; +} + +bool CHwpFileHeader::SignatureEmpty() const +{ + return m_sSignature.empty(); +} + +bool CHwpFileHeader::VersionEmpty() const +{ + return m_sVersion.empty(); +} + +HWP_STRING CHwpFileHeader::GetVersion() const +{ + return m_sVersion; +} +} diff --git a/HwpFile/HwpDoc/HwpFileHeader.h b/HwpFile/HwpDoc/HwpFileHeader.h new file mode 100644 index 00000000000..54103ca9c8b --- /dev/null +++ b/HwpFile/HwpDoc/HwpFileHeader.h @@ -0,0 +1,54 @@ +#ifndef HWPFILEHEADER_H +#define HWPFILEHEADER_H + +#include "HWPStream.h" +#include "Common/XMLNode.h" + +namespace HWP +{ +class CHwpFileHeader +{ + HWP_STRING m_sSignature; + HWP_STRING m_sVersion; + bool m_bCompressed; + bool m_bPasswordEncrypted; + bool m_bDistributable; + bool m_bSaveScript; + bool m_bDRMprotected; + bool m_bHasXMLTemplateStorage; + bool m_bHasDocumentHistory; + bool m_bHasPkiSignature; + bool m_bPkiEncrypted; + bool m_bReservePkiSignature; + bool m_bPkiCertificateDRM; + bool m_bCCLDocument; + bool m_bMobileOptimized; + bool m_bPrivateInformation; + bool m_bModifyTracking; + bool m_bCopyrightKOGL; + bool m_bHasVideoControl; + bool m_bHasMarkFieldControl; + + bool m_bCopyrighted; + bool m_bCopyProhibited; + bool m_bCopyPermitted; + + int m_nEncryptVersion; + int m_nCountryKOGLLicensed; +public: + CHwpFileHeader(); + + bool Compressed() const; + bool PasswordEncrypted() const; + bool Distributable() const; + bool SignatureEmpty() const; + bool VersionEmpty() const; + + HWP_STRING GetVersion() const; + + bool Parse(CHWPStream& oBuffer); + bool Parse(CXMLNode& oNode); +}; +} + +#endif // HWPFILEHEADER_H diff --git a/HwpFile/HwpDoc/OLEdoc/CompoundFile.cpp b/HwpFile/HwpDoc/OLEdoc/CompoundFile.cpp new file mode 100644 index 00000000000..82f48e8e499 --- /dev/null +++ b/HwpFile/HwpDoc/OLEdoc/CompoundFile.cpp @@ -0,0 +1,706 @@ +#include "CompoundFile.h" +#include +#include + +namespace HWP +{ +CCompoundFile::CCompoundFile(const HWP_STRING& sFileName) + : m_nSectorSize(512) +{ + m_oFile.OpenFile(sFileName); +} + +CCompoundFile::~CCompoundFile() +{ + Close(); + + CLEAR_ARRAY(CDirectoryEntry, m_arDirectoryEntries); +} + +const CDirectoryEntry* CCompoundFile::GetEntry(const HWP_STRING& sFileName) const +{ + VECTOR::const_iterator itFound = std::find_if(m_arDirectoryEntries.cbegin(), m_arDirectoryEntries.cend(), [&sFileName](const CDirectoryEntry* pDirectoryEntry){ return sFileName == pDirectoryEntry->GetDirectoryEntryName();}); + + if (m_arDirectoryEntries.cend() == itFound) + return nullptr; + + return *itFound; +} + +bool CCompoundFile::GetComponent(const HWP_STRING& sEntryName, CHWPStream& oBuffer) +{ + const CDirectoryEntry* pEntry = GetEntry(sEntryName); + + if (nullptr == pEntry) + return false; + + return Read(*pEntry, oBuffer); +} + +VECTOR CCompoundFile::GetChildEntries(const CDirectoryEntry* pBaseEntry) const +{ + //TODO:: реализовать + VECTOR arEntryIdx; + + int nIndex = 0; + if (nullptr == pBaseEntry) + { + if (!m_arDirectoryEntries.empty()) + nIndex = m_arDirectoryEntries.at(0)->GetChildID(); + else + return VECTOR(); + } + else + nIndex = pBaseEntry->GetChildID(); + + AddSiblings(arEntryIdx, nIndex); + + VECTOR arEntries; + + for (int nCurIndex : arEntryIdx) + { + if (nCurIndex < m_arDirectoryEntries.size()) + arEntries.push_back(m_arDirectoryEntries.at(nCurIndex)); + } + + return arEntries; +} + +VECTOR CCompoundFile::GetChildEntries(const HWP_STRING& sBaseEntryName) const +{ + VECTOR::const_iterator itFound = std::find_if(m_arDirectoryEntries.cbegin(), m_arDirectoryEntries.cend(), + [&sBaseEntryName](const CDirectoryEntry* pDirectoryEntry) + { return sBaseEntryName == pDirectoryEntry->GetDirectoryEntryName(); }); + + if (m_arDirectoryEntries.cend() == itFound) + return VECTOR(); + + return GetChildEntries(*itFound); +} + +bool CCompoundFile::Read(const CDirectoryEntry& oEntry, CHWPStream& oBuffer) +{ + HWP_BYTE *pBuffer = new(std::nothrow) HWP_BYTE[oEntry.GetStreamSize()]; + + if (nullptr == pBuffer) + return false; + + oBuffer.SetStream(pBuffer, oEntry.GetStreamSize(), false); + + VECTOR arStreamContainerSectors; + + int nRemainSize = (int)oEntry.GetStreamSize(); + + if (oEntry.GetStreamSize() < m_nMiniStreamCutoffSize) + { + if (m_arDirectoryEntries.empty()) + return false; + + arStreamContainerSectors = m_arDirectoryEntries.at(0)->GetSecNums(); + + for (int nSecNum : oEntry.GetSecNums()) + { + int nStreamIndex = nSecNum / (m_nSectorSize / 64); + int nStreamOffset = nSecNum % (m_nSectorSize / 64); + + if (nStreamIndex >= arStreamContainerSectors.size()) + return false; + + int nSatID = arStreamContainerSectors.at(nStreamIndex); + + DWORD dwSizeRead; + m_oFile.SeekFile((nSatID + 1) * m_nSectorSize + nStreamOffset * 64); + m_oFile.ReadFile((BYTE*)oBuffer.GetCurPtr(), nRemainSize >= 64 ? 64 : nRemainSize, dwSizeRead); + + oBuffer.Skip(dwSizeRead); + nRemainSize -= dwSizeRead; + } + } + else + { + for (int nSecNum : oEntry.GetSecNums()) + { + if (0xFFFFFFFE == nSecNum) + continue; + + // readStream + DWORD dwSizeRead; + m_oFile.SeekFile((nSecNum + 1) * m_nSectorSize); + m_oFile.ReadFile((BYTE*)oBuffer.GetCurPtr(), nRemainSize >= m_nSectorSize ? m_nSectorSize : nRemainSize, dwSizeRead); + + oBuffer.Skip(dwSizeRead); + nRemainSize -= dwSizeRead; + } + } + + oBuffer.MoveToStart(); + + return true; +} + +bool CCompoundFile::Open() +{ + CHWPStream oBuffer(m_nSectorSize); + + if (!oBuffer.IsValid()) + return false; + + DWORD dwSizeRead; + m_oFile.ReadFile((BYTE*)oBuffer.GetCurPtr(), m_nSectorSize, dwSizeRead); + + if (dwSizeRead != m_nSectorSize || !ParseHeader(oBuffer)) + return false; + + if (0x0004 == m_nMajorVersion) + { + m_oFile.SeekFile(4096); + m_nSectorSize = 4096; + oBuffer.Clear(); + oBuffer.Expand(m_nSectorSize); + } + + // collect MSAT SecID + int nSecID = m_nFirstSecIDMSAT; + + if (0xFFFFFFFE != nSecID && 0xFFFFFFFF != nSecID) + ReadMSATSector(nSecID); + + // Directory + nSecID = m_nFirstSecIDDirectory; + m_arDirectorySecIDs.push_back(nSecID); + + while (0xFFFFFFFE != nSecID) + { + int nSatIndex = nSecID / (m_nSectorSize / 4); + + // collect Directory SecID + if (nSatIndex >= m_arSATs.size()) + return false; + + int nSatID = m_arSATs.at(nSatIndex); + VECTOR arSecIDs = GetSecIDsFromSAT(nSatID, nSatIndex, nSecID); + + if (arSecIDs.empty()) + continue; + + for (int nSecID : arSecIDs) + { + if (m_arDirectorySecIDs.cend() == std::find(m_arDirectorySecIDs.cbegin(), m_arDirectorySecIDs.cend(), nSecID)) + m_arDirectorySecIDs.push_back(nSecID); + } + + nSecID = arSecIDs.back(); + } + + // collect Directory Entries + for (int nSecIDDirectory : m_arDirectorySecIDs) + { + if (0xFFFFFFFE != nSecIDDirectory) + ReadDirectorySector(nSecIDDirectory); + } + + // collect SSAT SecID + int nLastSecID = m_nFirstSecIDSSAT; + m_arSSATSecIDs.push_back(nLastSecID); + + while (0xFFFFFFFE != nLastSecID) + { + int nSatIndex = nLastSecID / (m_nSectorSize / 4); + + if (nSatIndex >= m_arSATs.size()) + return false; + + int nSatID = m_arSATs.at(nSatIndex); + VECTOR arSecIDs = GetSecIDsFromSAT(nSatID, nSatIndex, nLastSecID); + + if (arSecIDs.empty()) + continue; + + for (int nSecID : arSecIDs) + { + if (m_arSSATSecIDs.cend() == std::find(m_arSSATSecIDs.cbegin(), m_arSSATSecIDs.cend(), nSecID)) + m_arSSATSecIDs.push_back(nSecID); + } + + nLastSecID = arSecIDs.back(); + } + + // collect SecID of Stream for each Directory entries + for (CDirectoryEntry* pEntry : m_arDirectoryEntries) + { + if (0x05 == pEntry->GetObjectType()) // Root Storage + { + // Short Stream container Stream SecID + nLastSecID = pEntry->GetStartingSectorID(); + VECTOR& arEntrySecNums{pEntry->GetSecNums()}; + arEntrySecNums.push_back(nLastSecID); + + while (0xFFFFFFFE != nLastSecID) + { + int nContainerIndex = nLastSecID / (m_nSectorSize / 4); + + if (nContainerIndex >= m_arSATs.size()) + return false; + + int nSatID = m_arSATs.at(nContainerIndex); + VECTOR arSecIDs = GetSecIDsFromSAT(nSatID, nContainerIndex, nLastSecID); + + if (arSecIDs.empty()) + continue; + + for (int nSecID : arSecIDs) + { + if (arEntrySecNums.cend() == std::find(arEntrySecNums.cbegin(), arEntrySecNums.cend(), nSecID)) + arEntrySecNums.push_back(nSecID); + } + + nLastSecID = arSecIDs.back(); + } + } + else if (0x02 == pEntry->GetObjectType()) // Stream + { + VECTOR& arEntrySecNums{pEntry->GetSecNums()}; + arEntrySecNums.push_back(pEntry->GetStartingSectorID()); + + if (pEntry->GetStreamSize() < m_nMiniStreamCutoffSize) + { + // ShortStream + int nLastSSecID = pEntry->GetStartingSectorID(); + + while (0xFFFFFFFE != nLastSSecID) + { + int nSSatIndex = nLastSSecID / (m_nSectorSize / 4); + + if (nSSatIndex >= m_arSSATSecIDs.size()) + return false; + + int nSSatID = m_arSSATSecIDs.at(nSSatIndex); + + VECTOR arSecIDs = GetSecIDsFromSAT(nSSatID, nSSatIndex, nLastSSecID); + + if (arSecIDs.empty()) + continue; + + for (int nSecID : arSecIDs) + { + if (arEntrySecNums.cend() == std::find(arEntrySecNums.cbegin(), arEntrySecNums.cend(), nSecID)) + arEntrySecNums.push_back(nSecID); + } + + nLastSSecID = arEntrySecNums.back(); + } + } + else + { + // Stream + int nLastSectID = pEntry->GetStartingSectorID(); + + while (0xFFFFFFFE != nLastSectID) + { + int nSatIndex = nLastSectID / (m_nSectorSize / 4); + + if (nSatIndex >= m_arSATs.size()) + return false; + + int nSatID = m_arSATs.at(nSatIndex); + + VECTOR arSecIDs = GetSecIDsFromSAT(nSatID, nSatIndex, nLastSectID); + + if (arSecIDs.empty()) + continue; + + for (int nSecID : arSecIDs) + { + if (arEntrySecNums.cend() == std::find(arEntrySecNums.cbegin(), arEntrySecNums.cend(), nSecID)) + arEntrySecNums.push_back(nSecID); + } + + nLastSectID = arEntrySecNums.back(); + } + + } + } + else + continue; + } + + return true; +} + +void CCompoundFile::Close() +{ + m_oFile.CloseFile(); +} + +void CCompoundFile::AddSiblings(VECTOR& arIndexs, int nCurrentIndex) const +{ + if (-1 == nCurrentIndex) + return; + + if (arIndexs.end() == std::find(arIndexs.cbegin(), arIndexs.cend(), nCurrentIndex)) + arIndexs.push_back(nCurrentIndex); + + if (nCurrentIndex >= m_arDirectoryEntries.size()) + return; + + const int nLeftSibling = m_arDirectoryEntries.size() > nCurrentIndex ? m_arDirectoryEntries.at(nCurrentIndex)->GetLeftSiblingID() : -1; + const int nRightSibling = m_arDirectoryEntries.size() > nCurrentIndex ? m_arDirectoryEntries.at(nCurrentIndex)->GetRightSiblingID() : -1; + + if (-1 != nRightSibling) + { + const int nElderIndex = std::find(arIndexs.cbegin(), arIndexs.cend(), nCurrentIndex) - arIndexs.cbegin(); + arIndexs.insert(arIndexs.begin() + nElderIndex + 1, nRightSibling); + + if (nRightSibling < m_arDirectoryEntries.size()) + AddSiblings(arIndexs, nRightSibling); + } + + if (-1 != nLeftSibling) + { + const int nElderIndex = std::find(arIndexs.cbegin(), arIndexs.cend(), nCurrentIndex) - arIndexs.cbegin(); + arIndexs.insert(arIndexs.begin() + nElderIndex, nLeftSibling); + + if (nLeftSibling < m_arDirectoryEntries.size()) + AddSiblings(arIndexs, nLeftSibling); + } +} + +VECTOR CCompoundFile::GetSecIDsFromSAT(int nSecID, int nSatIndex, int nSecIDSSAT) +{ + CHWPStream oBuffer(m_nSectorSize); + + if (!oBuffer.IsValid()) + return VECTOR(); + + DWORD dwSizeRead; + m_oFile.SeekFile((nSecID + 1) * m_nSectorSize); + m_oFile.ReadFile((BYTE*)oBuffer.GetCurPtr(), m_nSectorSize, dwSizeRead); + + if (dwSizeRead != m_nSectorSize) + return VECTOR(); + + int nCurrSecID = nSecIDSSAT; + VECTOR arSecIDs; + + oBuffer.MoveTo(nCurrSecID % (m_nSectorSize / 4) * 4); + + while (((m_nSectorSize / 4) * nSatIndex <= nCurrSecID) && (nCurrSecID < (m_nSectorSize / 4) * (nSatIndex + 1))) + { + oBuffer.ReadInt(nCurrSecID); + arSecIDs.push_back(nCurrSecID); + + if (0xFFFFFFFE == nCurrSecID) + break; + + oBuffer.MoveTo(nCurrSecID % (m_nSectorSize / 4) * 4); + } + + return arSecIDs; +} + +void CCompoundFile::ReadDirectorySector(int nSecID) +{ + CHWPStream oBuffer(m_nSectorSize); + + if (!oBuffer.IsValid()) + return; + + DWORD dwSizeRead; + m_oFile.SeekFile((nSecID + 1) * m_nSectorSize); + m_oFile.ReadFile((BYTE*)oBuffer.GetCurPtr(), m_nSectorSize, dwSizeRead); + + if (dwSizeRead == m_nSectorSize) + ParseDirectorySector(oBuffer); +} + +void CCompoundFile::ReadSSATSector(int nSecID) +{ + CHWPStream oBuffer(m_nSectorSize); + + if (!oBuffer.IsValid()) + return; + + DWORD dwSizeRead; + m_oFile.SeekFile((nSecID + 1) * m_nSectorSize); + m_oFile.ReadFile((BYTE*)oBuffer.GetCurPtr(), m_nSectorSize, dwSizeRead); + + if (dwSizeRead == m_nSectorSize) + ParseSSATSector(oBuffer); +} + +void CCompoundFile::ReadMSATSector(int nSecID) +{ + CHWPStream oBuffer(m_nSectorSize); + + if (!oBuffer.IsValid()) + return; + + DWORD dwSizeRead; + m_oFile.SeekFile((nSecID + 1) * m_nSectorSize); + m_oFile.ReadFile((BYTE*)oBuffer.GetCurPtr(), m_nSectorSize, dwSizeRead); + + if (dwSizeRead == m_nSectorSize) + ParseMSATSector(oBuffer); +} + +void CCompoundFile::ParseSectors(int nSecID, CHWPStream& oBuffer) +{ + int nSectorType; + oBuffer.ReadInt(nSectorType); // for DIFAT, FAT, MiniFAT, + + if (m_arSATs.cend() != std::find(m_arSATs.cbegin(), m_arSATs.cend(), nSecID)) + ParseSATSector(nSecID, oBuffer); + + if (nSecID < m_nFirstSecIDDirectory &&nSecID == m_nFirstSecIDSSAT) + ParseSSATSector(oBuffer); +} + +void CCompoundFile::ParseSATSector(int nSecID, CHWPStream& oBuffer) +{ + for (int nIndex = nSecID * (m_nSectorSize / 4); oBuffer.CanRead(4); ++nIndex) + { + int nNextSecID; + oBuffer.ReadInt(nNextSecID); + + TSector oSectorInChain; + oSectorInChain.m_nSectorNum = nIndex; + + switch ((unsigned int)nNextSecID) + { + case 0xFFFFFFFC: // DIFAT + { + oSectorInChain.m_eType = ESectorType::MSAT; + break; + } + case 0xFFFFFFFD: // FAT + { + oSectorInChain.m_eType = ESectorType::SAT; + break; + } + case 0xFFFFFFFA: // maximum regular sector number + case 0xFFFFFFFE: // ENDOFCHAIN + { + oSectorInChain.m_eType = ESectorType::ENDOFCHAIN; + // Directory + // FAT + // MiniFAT + // DIFAT + // Stream (User-Defined Data) + // Range Lock + break; + } + case 0xFFFFFFFF: // unallocated + { + oSectorInChain.m_eType = ESectorType::FREE; + break; + } + case 0xFFFFFFFB: // Reserved for future use. + { + oSectorInChain.m_eType = ESectorType::CONTINUE; + break; + } + default: + { + oSectorInChain.m_eType = ESectorType::CONTINUE; + oSectorInChain.m_nNextNum = nNextSecID; + } + } + + if (0xFFFFFFFF > nNextSecID) + m_arSectors.push_back(oSectorInChain); + } +} + +void CCompoundFile::ParseDirectorySector(CHWPStream& oBuffer) +{ + for (int nIndex = 0; nIndex <= m_nSectorSize - 128; nIndex += 128) + { + oBuffer.MoveTo(64 + nIndex); + + short shEntryNameLen; + HWP_STRING sDirectiryEnryName; + + oBuffer.ReadShort(shEntryNameLen); + oBuffer.MoveTo(nIndex); + oBuffer.ReadString(sDirectiryEnryName, shEntryNameLen, EStringCharacter::UTF16); + oBuffer.MoveTo(66 + nIndex); + // + int nObjectType = oBuffer.ReadByte() & 0xFF; + int nColorFlag = oBuffer.ReadByte() & 0xFF; + + int nLeftSiblingID, nRightSiblingID, nChildID; + oBuffer.ReadInt(nLeftSiblingID); + oBuffer.ReadInt(nRightSiblingID); + oBuffer.ReadInt(nChildID); + + long long lClsID1, lClsID2; + oBuffer.ReadLong(lClsID1); + oBuffer.ReadLong(lClsID2); + + int nStateBit; + oBuffer.ReadInt(nStateBit); + + long long lCreationTime, lModifiedTime; + oBuffer.ReadLong(lCreationTime); + oBuffer.ReadLong(lModifiedTime); + + int nStartingSectorID; + oBuffer.ReadInt(nStartingSectorID); + + long long lStreamSize; + oBuffer.ReadLong(lStreamSize); + + CDirectoryEntry *pDirectoryEntry = new CDirectoryEntry(); + + if (nullptr == pDirectoryEntry) + continue; + + pDirectoryEntry->SetDirectoryEntryName(sDirectiryEnryName); + pDirectoryEntry->SetObjectType(nObjectType); + pDirectoryEntry->SetColorFlag(nColorFlag); + pDirectoryEntry->SetLeftSiblingID(nLeftSiblingID); + pDirectoryEntry->SetRightSiblingID(nRightSiblingID); + pDirectoryEntry->SetChildID(nChildID); + pDirectoryEntry->SetClsID1(lClsID1); + pDirectoryEntry->SetClsID2(lClsID2); + pDirectoryEntry->SetStateBit(nStateBit); + pDirectoryEntry->SetCreationTime(lCreationTime); + pDirectoryEntry->SetModifiedTime(lModifiedTime); + pDirectoryEntry->SetStartingSectorID(nStartingSectorID); + pDirectoryEntry->SetStreamSize(lStreamSize); + + m_arDirectoryEntries.push_back(pDirectoryEntry); + } +} + +void CCompoundFile::ParseSSATSector(CHWPStream& oBuffer) +{ + int nNextSectorId; + + while (oBuffer.CanRead(4)) + { + oBuffer.ReadInt(nNextSectorId); + + if (0xFFFFFFFF != nNextSectorId) + m_arSStreams.push_back(nNextSectorId); + } +} + +void CCompoundFile::ParseMSATSector(CHWPStream& oBuffer) +{ + int nSector; + + while (4 < oBuffer.SizeToEnd()) + { + oBuffer.ReadInt(nSector); + + if (0xFFFFFFFF != nSector) + m_arSATs.push_back(nSector); + } + + int nNextSecIDMSAT; + oBuffer.ReadInt(nNextSecIDMSAT); + + if (0xFFFFFFFE != nNextSecIDMSAT && 0xFFFFFFFF != nNextSecIDMSAT) + ReadMSATSector(nNextSecIDMSAT); +} + +bool CCompoundFile::ParseHeader(CHWPStream& oBuffer) +{ + CheckSignature(oBuffer); + + oBuffer.Skip(16); // Header CLSID + m_nMinorVersion = oBuffer.ReadShort(); + + if (0x003E != m_nMinorVersion) + return false; //TODO:: возможно следует просто пропускать такие несоответсвия + + m_nMajorVersion = oBuffer.ReadShort(); + + if (0x0003 != m_nMajorVersion && 0x0004 != m_nMajorVersion) + return false; + + short shByteOrder = oBuffer.ReadShort(); + + if (0xFFFE != (unsigned short)shByteOrder) + return false; + + int nSectorShift = oBuffer.ReadShort(); + + m_nSectorSize = pow(2., (double)nSectorShift); + + if ((0x0003 == m_nMajorVersion && 0x0009 != nSectorShift) || + (0x0004 == m_nMajorVersion && 0x000C != nSectorShift)) + return false; + + nSectorShift = oBuffer.ReadShort(); + m_nShortSectorSize = pow(2., (double)nSectorShift); + + if (0x0006 != nSectorShift) + return false; + + oBuffer.Skip(6); // reserved + oBuffer.ReadInt(m_nNumDirectory); + + if (0x0003 == m_nMajorVersion && 0x0000 != m_nNumDirectory) + return false; + + oBuffer.ReadInt(m_nNumSAT); + oBuffer.ReadInt(m_nFirstSecIDDirectory); + oBuffer.Skip(4); // Transaction Signature Number + oBuffer.ReadInt(m_nMiniStreamCutoffSize); + + if (0x00001000 != m_nMiniStreamCutoffSize) + return false; + + oBuffer.ReadInt(m_nFirstSecIDSSAT); + oBuffer.ReadInt(m_nNumSSAT); + oBuffer.ReadInt(m_nFirstSecIDMSAT); + oBuffer.ReadInt(m_nNumMSAT); + + int nSector; + while(oBuffer.Tell() < 512) + { + oBuffer.ReadInt(nSector); + + if (0xFFFFFFFF != nSector) + m_arSATs.push_back(nSector); + } + + return true; +} + +bool CCompoundFile::CheckSignature(CHWPStream& oBuffer) +{ + if (!oBuffer.CanRead(8)) + return false; + + HWP_BYTE arBufSig[8]; + + if (!oBuffer.ReadBytes(arBufSig, 8)) + return false; + + if ((HWP_BYTE)0xD0 == arBufSig[0] && (HWP_BYTE)0xCF == arBufSig[1] && (HWP_BYTE)0x11 == arBufSig[2] && (HWP_BYTE)0xE0 == arBufSig[3] && + (HWP_BYTE)0xA1 == arBufSig[4] && (HWP_BYTE)0xB1 == arBufSig[5] && (HWP_BYTE)0x1A == arBufSig[6] && (HWP_BYTE)0xE1 == arBufSig[7]) + return true; + + return false; +} + +ESectorType CCompoundFile::LookupSectorType(CHWPStream& oBuffer) +{ + int nSector; + + while (oBuffer.CanRead(4)) + { + oBuffer.ReadInt(nSector); + + if (0xFFFFFFFC == nSector) + return ESectorType::MSAT; + else if (0xFFFFFFFD == nSector) + return ESectorType::SAT; + } + + return ESectorType::CONTINUE; +} +} diff --git a/HwpFile/HwpDoc/OLEdoc/CompoundFile.h b/HwpFile/HwpDoc/OLEdoc/CompoundFile.h new file mode 100644 index 00000000000..50a52288aa4 --- /dev/null +++ b/HwpFile/HwpDoc/OLEdoc/CompoundFile.h @@ -0,0 +1,69 @@ +#ifndef COMPOUNDFILE_H +#define COMPOUNDFILE_H + +#include "Sector.h" +#include "DirectoryEntry.h" +#include "../HWPStream.h" +#include "../../../DesktopEditor/common/File.h" + +namespace HWP +{ +class CCompoundFile +{ + NSFile::CFileBinary m_oFile; + int m_nMinorVersion; + int m_nMajorVersion; + int m_nSectorSize; + int m_nShortSectorSize; + int m_nNumDirectory; // Support only in version 4 + int m_nNumSAT; + int m_nFirstSecIDDirectory; + int m_nMiniStreamCutoffSize; + int m_nFirstSecIDSSAT; + int m_nNumSSAT; + int m_nFirstSecIDMSAT; + int m_nNumMSAT; + + VECTOR m_arSectors; + VECTOR m_arSATs; + VECTOR m_arSSATSecIDs; + VECTOR m_arDirectorySecIDs; + VECTOR m_arSStreamSecIDs; + VECTOR m_arSStreams; + VECTOR m_arDirectoryEntries; +public: + CCompoundFile(const HWP_STRING& sFileName); + ~CCompoundFile(); + + const CDirectoryEntry* GetEntry(const HWP_STRING& sFileName) const; + bool GetComponent(const HWP_STRING& sEntryName, CHWPStream& oBuffer); + + VECTOR GetChildEntries(const CDirectoryEntry* pBaseEntry) const; + VECTOR GetChildEntries(const HWP_STRING& sBaseEntryName) const; + + bool Read(const CDirectoryEntry& oEntry, CHWPStream& oBuffer); + bool Open(); + void Close(); +private: + void AddSiblings(VECTOR& arIndexs, int nCurrentIndex) const; + + VECTOR GetSecIDsFromSAT(int nSecID, int nSatIndex, int nSecIDSSAT); + + void ReadDirectorySector(int nSecID); + void ReadSSATSector(int nSecID); + void ReadMSATSector(int nSecID); + + void ParseSectors(int nSecID, CHWPStream& oBuffer); + void ParseSATSector(int nSecID, CHWPStream& oBuffer); + void ParseDirectorySector(CHWPStream& oBuffer); + void ParseSSATSector(CHWPStream& oBuffer); + void ParseMSATSector(CHWPStream& oBuffer); + bool ParseHeader(CHWPStream& oBuffer); + + bool CheckSignature(CHWPStream& oBuffer); + + ESectorType LookupSectorType(CHWPStream& oBuffer); +}; +} + +#endif // COMPOUNDFILE_H diff --git a/HwpFile/HwpDoc/OLEdoc/DirectoryEntry.cpp b/HwpFile/HwpDoc/OLEdoc/DirectoryEntry.cpp new file mode 100644 index 00000000000..895208d18f2 --- /dev/null +++ b/HwpFile/HwpDoc/OLEdoc/DirectoryEntry.cpp @@ -0,0 +1,117 @@ +#include "DirectoryEntry.h" + +namespace HWP +{ +HWP::CDirectoryEntry::CDirectoryEntry() +{} + +void CDirectoryEntry::SetDirectoryEntryName(const HWP_STRING& sDirectoryEntryName) +{ + m_sDirectoryEntryName = sDirectoryEntryName; +} + +void CDirectoryEntry::SetObjectType(int nObjectType) +{ + m_nObjectType = nObjectType; +} + +void CDirectoryEntry::SetColorFlag(int nColorFlag) +{ + m_nColorFlag = nColorFlag; +} + +void CDirectoryEntry::SetLeftSiblingID(int nLeftSiblingID) +{ + m_nLeftSiblingID = nLeftSiblingID; +} + +void CDirectoryEntry::SetRightSiblingID(int nRightSiblingID) +{ + m_nRightSiblingID = nRightSiblingID; +} + +void CDirectoryEntry::SetChildID(int nChildID) +{ + m_nChildID = nChildID; +} + +void CDirectoryEntry::SetClsID1(const long long& lClsID1) +{ + m_lClsID1 = lClsID1; +} + +void CDirectoryEntry::SetClsID2(const long long& lClsID2) +{ + m_lClsID2 = lClsID2; +} + +void CDirectoryEntry::SetStateBit(int nStateBit) +{ + m_nStateBit = nStateBit; +} + +void CDirectoryEntry::SetCreationTime(const long long& lCreationTime) +{ + m_lCreationTime = lCreationTime; +} + +void CDirectoryEntry::SetModifiedTime(const long long& lModifiedTime) +{ + m_lModifiedTime = lModifiedTime; +} + +void CDirectoryEntry::SetStartingSectorID(int nStartingSectorID) +{ + m_nStartingSectorID = nStartingSectorID; +} + +void CDirectoryEntry::SetStreamSize(const long long& lStreamSize) +{ + m_lStreamSize = lStreamSize; +} + +HWP_STRING CDirectoryEntry::GetDirectoryEntryName() const +{ + return m_sDirectoryEntryName; +} + +int CDirectoryEntry::GetLeftSiblingID() const +{ + return m_nLeftSiblingID; +} + +int CDirectoryEntry::GetRightSiblingID() const +{ + return m_nRightSiblingID; +} + +int CDirectoryEntry::GetChildID() const +{ + return m_nChildID; +} + +int CDirectoryEntry::GetStartingSectorID() const +{ + return m_nStartingSectorID; +} + +long long CDirectoryEntry::GetStreamSize() const +{ + return m_lStreamSize; +} + +VECTOR CDirectoryEntry::GetSecNums() const +{ + return m_arSecNums; +} + +VECTOR& CDirectoryEntry::GetSecNums() +{ + return m_arSecNums; +} + +int CDirectoryEntry::GetObjectType() const +{ + return m_nObjectType; +} +} diff --git a/HwpFile/HwpDoc/OLEdoc/DirectoryEntry.h b/HwpFile/HwpDoc/OLEdoc/DirectoryEntry.h new file mode 100644 index 00000000000..d38d0ed4f62 --- /dev/null +++ b/HwpFile/HwpDoc/OLEdoc/DirectoryEntry.h @@ -0,0 +1,55 @@ +#ifndef DIRECTORYENTRY_H +#define DIRECTORYENTRY_H + +#include "../Common/Common.h" + +namespace HWP +{ +class CDirectoryEntry +{ + HWP_STRING m_sDirectoryEntryName; + int m_nObjectType; + int m_nColorFlag; + int m_nLeftSiblingID; + int m_nRightSiblingID; + int m_nChildID; + long long m_lClsID1; + long long m_lClsID2; + int m_nStateBit; + long long m_lCreationTime; + long long m_lModifiedTime; + int m_nStartingSectorID; + long long m_lStreamSize; + VECTOR m_arSecNums; +public: + CDirectoryEntry(); + + void SetDirectoryEntryName(const HWP_STRING& sDirectoryEntryName); + void SetObjectType(int nObjectType); + void SetColorFlag(int nColorFlag); + void SetLeftSiblingID(int nLeftSiblingID); + void SetRightSiblingID(int nRightSiblingID); + void SetChildID(int nChildID); + void SetClsID1(const long long& lClsID1); + void SetClsID2(const long long& lClsID2); + void SetStateBit(int nStateBit); + void SetCreationTime(const long long& lCreationTime); + void SetModifiedTime(const long long& lModifiedTime); + void SetStartingSectorID(int nStartingSectorID); + void SetStreamSize(const long long& lStreamSize); + + int GetLeftSiblingID() const; + int GetRightSiblingID() const; + int GetChildID() const; + int GetStartingSectorID() const; + long long GetStreamSize() const; + VECTOR GetSecNums() const; + + VECTOR& GetSecNums(); + + int GetObjectType() const; + HWP_STRING GetDirectoryEntryName() const; +}; +} + +#endif // DIRECTORYENTRY_H diff --git a/HwpFile/HwpDoc/OLEdoc/Sector.h b/HwpFile/HwpDoc/OLEdoc/Sector.h new file mode 100644 index 00000000000..91d3467b774 --- /dev/null +++ b/HwpFile/HwpDoc/OLEdoc/Sector.h @@ -0,0 +1,16 @@ +#ifndef SECTOR_H +#define SECTOR_H + +#include "SectorType.h" + +namespace HWP +{ +struct TSector +{ + ESectorType m_eType; + int m_nSectorNum; + int m_nNextNum; +}; +} + +#endif // SECTOR_H diff --git a/HwpFile/HwpDoc/OLEdoc/SectorType.h b/HwpFile/HwpDoc/OLEdoc/SectorType.h new file mode 100644 index 00000000000..085dc97fcc4 --- /dev/null +++ b/HwpFile/HwpDoc/OLEdoc/SectorType.h @@ -0,0 +1,17 @@ +#ifndef SECTORTYPE_H +#define SECTORTYPE_H + +namespace HWP +{ +enum class ESectorType +{ + SAT, + MSAT, + ENDOFCHAIN, + CONTINUE, + FREE, + MAX +}; +} + +#endif // SECTORTYPE_H diff --git a/HwpFile/HwpDoc/Paragraph/CapParagraph.cpp b/HwpFile/HwpDoc/Paragraph/CapParagraph.cpp new file mode 100644 index 00000000000..144d56c1f54 --- /dev/null +++ b/HwpFile/HwpDoc/Paragraph/CapParagraph.cpp @@ -0,0 +1,17 @@ +#include "CapParagraph.h" + +namespace HWP +{ +CCapParagraph::CCapParagraph() + : CHWPPargraph() +{} + +CCapParagraph::CCapParagraph(CXMLNode& oNode, int nVersion) + : CHWPPargraph(oNode, nVersion) +{} + +EParagraphType CCapParagraph::GetType() const +{ + return EParagraphType::Cap; +} +} diff --git a/HwpFile/HwpDoc/Paragraph/CapParagraph.h b/HwpFile/HwpDoc/Paragraph/CapParagraph.h new file mode 100644 index 00000000000..a107e66b0f6 --- /dev/null +++ b/HwpFile/HwpDoc/Paragraph/CapParagraph.h @@ -0,0 +1,18 @@ +#ifndef CAPPARAGRAPH_H +#define CAPPARAGRAPH_H + +#include "HWPPargraph.h" + +namespace HWP +{ +class CCapParagraph : public CHWPPargraph +{ +public: + CCapParagraph(); + CCapParagraph(CXMLNode& oNode, int nVersion); + + EParagraphType GetType() const override; +}; +} + +#endif // CAPPARAGRAPH_H diff --git a/HwpFile/HwpDoc/Paragraph/CellParagraph.cpp b/HwpFile/HwpDoc/Paragraph/CellParagraph.cpp new file mode 100644 index 00000000000..8087a970277 --- /dev/null +++ b/HwpFile/HwpDoc/Paragraph/CellParagraph.cpp @@ -0,0 +1,18 @@ +#include "CellParagraph.h" + +namespace HWP +{ +CCellParagraph::CCellParagraph() + : CHWPPargraph() +{ +} + +CCellParagraph::CCellParagraph(CXMLNode& oNode, int nVersion) + : CHWPPargraph(oNode, nVersion) +{} + +EParagraphType CCellParagraph::GetType() const +{ + return EParagraphType::Cell; +} +} diff --git a/HwpFile/HwpDoc/Paragraph/CellParagraph.h b/HwpFile/HwpDoc/Paragraph/CellParagraph.h new file mode 100644 index 00000000000..8f24372d767 --- /dev/null +++ b/HwpFile/HwpDoc/Paragraph/CellParagraph.h @@ -0,0 +1,18 @@ +#ifndef CELLPARAGRAPH_H +#define CELLPARAGRAPH_H + +#include "HWPPargraph.h" + +namespace HWP +{ +class CCellParagraph : public CHWPPargraph +{ +public: + CCellParagraph(); + CCellParagraph(CXMLNode& oNode, int nVersion); + + EParagraphType GetType() const override; +}; +} + +#endif // CELLPARAGRAPH_H diff --git a/HwpFile/HwpDoc/Paragraph/CharShape.cpp b/HwpFile/HwpDoc/Paragraph/CharShape.cpp new file mode 100644 index 00000000000..27060b45719 --- /dev/null +++ b/HwpFile/HwpDoc/Paragraph/CharShape.cpp @@ -0,0 +1,118 @@ +#include "CharShape.h" +#include "CtrlCharacter.h" +#include "CtrlAutoNumber.h" +#include "ParaText.h" +#include + +namespace HWP +{ +CCharShape::CCharShape() +{ +} + +CCharShape::CCharShape(int nStart, int nID) + : m_nStart(nStart), m_nCharShapeID(nID) +{ +} + +int CCharShape::GetStart() const +{ + return m_nStart; +} + +int CCharShape::GetCharShapeID() const +{ + return m_nCharShapeID; +} + +VECTOR CCharShape::Parse(int nTagNum, int nLevel, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) +{ + oBuffer.SavePosition(); + + VECTOR arCharShapes; + + int nStart, nCharShapeID; + + while (nSize - 8 >= oBuffer.GetDistanceToLastPos()) + { + oBuffer.ReadInt(nStart); + oBuffer.ReadInt(nCharShapeID); + + arCharShapes.push_back(new CCharShape(nStart, nCharShapeID)); + } + + oBuffer.Skip(nSize - oBuffer.GetDistanceToLastPos(true)); + + return arCharShapes; +} + +int CCharShape::FillCharShape(int nTagNum, int nLevel, int nSize, CHWPStream& oBuffer, int nOff, int nVersion, std::vector& arParas) +{ + if (arParas.empty()) + { + oBuffer.Skip(nSize); + return 0; + } + + oBuffer.SavePosition(); + + VECTOR arCharShape = Parse(nTagNum, nLevel, nSize, oBuffer, nOff, nVersion); + + for (CCharShape* pCharShape : arCharShape) + { + if (0 == pCharShape->m_nStart) + { + for (CCtrl* pCtrl : arParas) + { + if (ECtrlObjectType::ParaText == pCtrl->GetCtrlType()) + ((CParaText*)pCtrl)->SetCharShapeID(pCharShape->m_nCharShapeID); + + if (ECtrlObjectType::Character == pCtrl->GetCtrlType()) + ((CCtrlCharacter*)pCtrl)->SetCharShapeID(pCharShape->m_nCharShapeID); + } + } + else if (0 < pCharShape->m_nStart) + { + VECTOR::const_reverse_iterator itFound = std::find_if(arParas.crbegin(), arParas.crend(), + [pCharShape](CCtrl* pCurCtrl) + { if (nullptr == dynamic_cast(pCurCtrl)) return false; + return ((CParaText*)pCurCtrl)->GetStartIDx() <= pCharShape->m_nStart && pCharShape->m_nStart < ((CParaText*)pCurCtrl)->GetStartIDx() + ((CParaText*)pCurCtrl)->GetTextLength(); }); + + if (itFound != arParas.crend()) + { + CParaText* pParaText = (CParaText*)*itFound; + + if (pParaText->GetStartIDx() == pCharShape->m_nStart) + pParaText->SetCharShapeID(pCharShape->m_nCharShapeID); + else + { + // split + int nLenToSplit = pCharShape->m_nStart - pParaText->GetStartIDx(); + + HWP_STRING sSplitLeftText = pParaText->GetText().substr(0, nLenToSplit); + HWP_STRING sSplitRightText = pParaText->GetText().substr(nLenToSplit); + + pParaText->SetText(sSplitLeftText); + + CParaText *pNewParaText = new CParaText(L"____", sSplitRightText, pCharShape->m_nStart, pCharShape->m_nCharShapeID); + + arParas.insert(itFound.base(), pNewParaText); + } + } + + for (CCtrl* pCtrl : arParas) + { + if (ECtrlObjectType::ParaText == pCtrl->GetCtrlType() && ((CParaText*)pCtrl)->GetStartIDx() > pCharShape->m_nStart) + ((CParaText*)pCtrl)->SetCharShapeID(pCharShape->m_nCharShapeID); + + if (ECtrlObjectType::Character == pCtrl->GetCtrlType()) + ((CCtrlCharacter*)pCtrl)->SetCharShapeID(pCharShape->m_nCharShapeID); + } + } + } + + oBuffer.Skip(nSize - oBuffer.GetDistanceToLastPos(true)); + + return nSize; +} +} diff --git a/HwpFile/HwpDoc/Paragraph/CharShape.h b/HwpFile/HwpDoc/Paragraph/CharShape.h new file mode 100644 index 00000000000..e0ccfa5ff88 --- /dev/null +++ b/HwpFile/HwpDoc/Paragraph/CharShape.h @@ -0,0 +1,25 @@ +#ifndef CHARSHAPE_H +#define CHARSHAPE_H + +#include "../HWPStream.h" +#include "Ctrl.h" + +namespace HWP +{ +class CCharShape +{ + int m_nStart; + int m_nCharShapeID; +public: + CCharShape(); + CCharShape(int nStart, int nID); + + int GetStart() const; + int GetCharShapeID() const; + + static VECTOR Parse(int nTagNum, int nLevel, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); + static int FillCharShape(int nTagNum, int nLevel, int nSize, CHWPStream& oBuffer, int nOff, int nVersion, VECTOR& arParas); +}; +} + +#endif // CHARSHAPE_H diff --git a/HwpFile/HwpDoc/Paragraph/CommonObj.h b/HwpFile/HwpDoc/Paragraph/CommonObj.h new file mode 100644 index 00000000000..c6794c4f155 --- /dev/null +++ b/HwpFile/HwpDoc/Paragraph/CommonObj.h @@ -0,0 +1,34 @@ +#ifndef COMMONOBJ_H +#define COMMONOBJ_H + +#include "HWPPargraph.h" +#include +#include +#include + +namespace HWP +{ +struct TCommonObj +{ + HWP_STRING m_sCtrlID; + + int m_nObjAttr; + int m_nYOffset; + int m_nXOffset; + int m_nObjWidth; + int m_nObjHeight; + int m_nZOrder; + VECTOR m_arObjSpaces; + int m_nObjInstanceID; + int m_nBlockPageBreak; + HWP_STRING m_sObjDesc; + + LIST m_arParas; + int m_nCaptionAttr; + int m_nCaptionWidth; + int m_nCaptionSpacing; + int m_nCaptionMaxW; +}; +} + +#endif // COMMONOBJ_H diff --git a/HwpFile/HwpDoc/Paragraph/Ctrl.cpp b/HwpFile/HwpDoc/Paragraph/Ctrl.cpp new file mode 100644 index 00000000000..8257483ed06 --- /dev/null +++ b/HwpFile/HwpDoc/Paragraph/Ctrl.cpp @@ -0,0 +1,77 @@ +#include "Ctrl.h" + +#include "CtrlColumnDef.h" +#include "CtrlAutoNumber.h" +#include "CtrlHeadFoot.h" +#include "CtrlNewNumber.h" +#include "CtrlNote.h" +#include "CtrlPageNumPos.h" +#include "CtrlField.h" + +namespace HWP +{ +CCtrl::CCtrl() + : m_bFullFilled(false) +{} + +CCtrl::CCtrl(const HWP_STRING& sCtrlID) + : m_sCtrlID(sCtrlID), m_bFullFilled(false) +{} + +CCtrl::~CCtrl() +{} + +void CCtrl::SetID(const HWP_STRING& sCtrlID) +{ + m_sCtrlID = sCtrlID; +} + +HWP_STRING CCtrl::GetID() const +{ + return m_sCtrlID; +} + +bool CCtrl::FullFilled() const +{ + return m_bFullFilled; +} + +void CCtrl::SetFullFilled() +{ + m_bFullFilled = true; +} + +bool CCtrl::Equals(CCtrl* pFirstCtrl, CCtrl* pSecondCtrl) +{ + if (nullptr == pFirstCtrl || nullptr == pSecondCtrl) + return false; + + return pFirstCtrl->m_sCtrlID == pSecondCtrl->m_sCtrlID && + pFirstCtrl->m_bFullFilled == pSecondCtrl->m_bFullFilled; +} + +CCtrl* CCtrl::GetCtrl(CXMLNode& oNode, int nVersion) +{ + if (L"hp:colPr" == oNode.GetName()) + return new CCtrlColumnDef(L"dloc", oNode, nVersion); + else if (L"hp:header" == oNode.GetName()) + return new CCtrlHeadFoot(L"daeh", oNode, nVersion); + else if (L"hp:footer" == oNode.GetName()) + return new CCtrlHeadFoot(L"toof", oNode, nVersion); + else if (L"hp:footNote" == oNode.GetName()) + return new CCtrlNote(L" nf", oNode, nVersion); + else if (L"hp:endNote" == oNode.GetName()) + return new CCtrlNote(L" ne", oNode, nVersion); + else if (L"hp:autoNum" == oNode.GetName()) + return new CCtrlAutoNumber(L"onta", oNode, nVersion); + else if (L"hp:newNum" == oNode.GetName()) + return new CCtrlNewNumber(L"onwn", oNode, nVersion); + else if (L"hp:pageNum" == oNode.GetName()) + return new CCtrlPageNumPos(L"pngp", oNode, nVersion); + else if (L"hp:fieldBegin" == oNode.GetName() || + L"hp:fieldEnd" == oNode.GetName()) + return new CCtrlField(L"", oNode, nVersion); + + return nullptr; +} +} diff --git a/HwpFile/HwpDoc/Paragraph/Ctrl.h b/HwpFile/HwpDoc/Paragraph/Ctrl.h new file mode 100644 index 00000000000..ae50822346b --- /dev/null +++ b/HwpFile/HwpDoc/Paragraph/Ctrl.h @@ -0,0 +1,53 @@ +#ifndef CTRL_H +#define CTRL_H + +#include "../Common/Common.h" +#include "../Common/XMLNode.h" + +namespace HWP +{ +enum class ECtrlObjectType +{ + AutoNumber, + Character, + Click, + ColumnDef, + Form, + HeadFoot, + NewNumber, + Note, + PageNumPos, + SectionDef, + Shape, + Table, + ParaText, + Common, + Field, + + Empty +}; + +class CCtrl +{ + HWP_STRING m_sCtrlID; +protected: + bool m_bFullFilled; +public: + CCtrl(); + CCtrl(const HWP_STRING& sCtrlID); + virtual ~CCtrl(); + + virtual ECtrlObjectType GetCtrlType() const = 0; + + void SetID(const HWP_STRING& sCtrlID); + HWP_STRING GetID() const; + bool FullFilled() const; + + void SetFullFilled(); + + static bool Equals(CCtrl* pFirstCtrl, CCtrl* pSecondCtrl); + static CCtrl* GetCtrl(CXMLNode& oNode, int nVersion); +}; +} + +#endif // CTRL_H diff --git a/HwpFile/HwpDoc/Paragraph/CtrlAutoNumber.cpp b/HwpFile/HwpDoc/Paragraph/CtrlAutoNumber.cpp new file mode 100644 index 00000000000..fdab363ca2d --- /dev/null +++ b/HwpFile/HwpDoc/Paragraph/CtrlAutoNumber.cpp @@ -0,0 +1,112 @@ +#include "CtrlAutoNumber.h" + +namespace HWP +{ +ENumType GetNumType(int nValue) +{ + SWITCH(ENumType, nValue) + { + DEFAULT(ENumType::PAGE); + CASE(ENumType::FOOTNOTE); + CASE(ENumType::ENDNOTE); + CASE(ENumType::FIGURE); + CASE(ENumType::TABLE); + CASE(ENumType::EQUATION); + CASE(ENumType::TOTAL_PAGE); + } +} + +ENumType GetNumType(const HWP_STRING& sValue) +{ + IF_STRING_IN_ENUM(FOOTNOTE, sValue, ENumType); + ELSE_IF_STRING_IN_ENUM(ENDNOTE, sValue, ENumType); + ELSE_IF_STRING_IN_ENUM(FIGURE, sValue, ENumType); + ELSE_IF_STRING_IN_ENUM(TABLE, sValue, ENumType); + ELSE_IF_STRING_IN_ENUM(EQUATION, sValue, ENumType); + ELSE_IF_STRING_IN_ENUM(TOTAL_PAGE, sValue, ENumType); + ELSE_STRING_IN_ENUM(PAGE, ENumType); +} + +CCtrlAutoNumber::CCtrlAutoNumber(const HWP_STRING& sCtrlID) + : CCtrl(sCtrlID) +{} + +CCtrlAutoNumber::CCtrlAutoNumber(const HWP_STRING& sCtrlID, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) + : CCtrl(sCtrlID) +{ + int nAttr; + oBuffer.ReadInt(nAttr); + + m_eNumType = ::HWP::GetNumType(nAttr & 0xF); + m_eNumShape = GetNumberShape2(nAttr >> 4 & 0xFF); + m_bSuperscript = CHECK_FLAG(nAttr >> 12, 0x1); + + m_bFullFilled = true; +} + +CCtrlAutoNumber::CCtrlAutoNumber(const HWP_STRING& sCtrlID, CXMLNode& oNode, int nVersion) + : CCtrl(sCtrlID) +{ + m_eNumType = ::HWP::GetNumType(oNode.GetAttribute(L"numType")); + + HWP_STRING sType; + + for (CXMLNode& oChild : oNode.GetChilds()) + { + m_bSuperscript = oChild.GetAttributeBool(L"supscript"); + + sType = oChild.GetAttribute(L"type"); + + if (L"DIGIT" == sType) + m_eNumShape = ENumberShape2::DIGIT; + else if (L"CIRCLE_DIGIT" == sType) + m_eNumShape = ENumberShape2::CIRCLE_DIGIT; + else if (L"ROMAN_CAPITAL" == sType) + m_eNumShape = ENumberShape2::ROMAN_CAPITAL; + else if (L"ROMAN_SMALL" == sType) + m_eNumShape = ENumberShape2::ROMAN_SMALL; + else if (L"LATIN_CAPITAL" == sType) + m_eNumShape = ENumberShape2::LATIN_CAPITAL; + else if (L"LATIN_SMALL" == sType) + m_eNumShape = ENumberShape2::LATIN_SMALL; + else if (L"CIRCLED_LATIN_CAPITAL" == sType) + m_eNumShape = ENumberShape2::CIRCLED_LATIN_CAPITAL; + else if (L"CIRCLED_LATIN_SMALL" == sType) + m_eNumShape = ENumberShape2::CIRCLED_LATIN_SMALL; + else if (L"CIRCLED_HANGUL_SYLLABLE" == sType) + m_eNumShape = ENumberShape2::CIRCLED_HANGUL_SYLLABLE; + else if (L"HANGUL_JAMO" == sType) + m_eNumShape = ENumberShape2::HANGUL_JAMO; + else if (L"CIRCLED_HANGUL_JAMO" == sType) + m_eNumShape = ENumberShape2::CIRCLED_HANGUL_JAMO; + else if (L"HANGUL_PHONETIC" == sType) + m_eNumShape = ENumberShape2::HANGUL_PHONETIC; + else if (L"IDEOGRAPH" == sType) + m_eNumShape = ENumberShape2::IDEOGRAPH; + else if (L"CIRCLED_IDEOGRAPH" == sType) + m_eNumShape = ENumberShape2::CIRCLED_IDEOGRAPH; + else if (L"DECAGON_CIRCLE" == sType) + m_eNumShape = ENumberShape2::DECAGON_CIRCLE; + else if (L"DECAGON_CRICLE_HANGJA" == sType) + m_eNumShape = ENumberShape2::DECAGON_CRICLE_HANGJA; + else if (L"SYMBOL" == sType) + m_eNumShape = ENumberShape2::SYMBOL; + else if (L"USER_CHAR" == sType) + m_eNumShape = ENumberShape2::USER_HWP_CHAR; + + m_eNumShape = GetNumberShape2(oChild.GetAttributeInt(L"hp:autoNumFormat", oChild.GetAttributeInt(L"autoNumFormat"))); + } + + m_bFullFilled = true; +} + +ECtrlObjectType CCtrlAutoNumber::GetCtrlType() const +{ + return ECtrlObjectType::AutoNumber; +} + +ENumType CCtrlAutoNumber::GetNumType() const +{ + return m_eNumType; +} +} diff --git a/HwpFile/HwpDoc/Paragraph/CtrlAutoNumber.h b/HwpFile/HwpDoc/Paragraph/CtrlAutoNumber.h new file mode 100644 index 00000000000..1d28a62ae63 --- /dev/null +++ b/HwpFile/HwpDoc/Paragraph/CtrlAutoNumber.h @@ -0,0 +1,43 @@ +#ifndef CTRLAUTONUMBER_H +#define CTRLAUTONUMBER_H + +#include "Ctrl.h" +#include "../HWPStream.h" +#include "../HWPElements/HwpRecordTypes.h" +#include "../Common/Common.h" +#include "../Common/XMLNode.h" + +namespace HWP +{ + +enum class ENumType +{ + PAGE, + FOOTNOTE, + ENDNOTE, + FIGURE, + TABLE, + EQUATION, + TOTAL_PAGE +}; + +ENumType GetNumType(int nValue); +ENumType GetNumType(const HWP_STRING& sValue); + +class CCtrlAutoNumber : public CCtrl +{ + ENumType m_eNumType; + ENumberShape2 m_eNumShape; + bool m_bSuperscript; +public: + CCtrlAutoNumber(const HWP_STRING& sCtrlID); + CCtrlAutoNumber(const HWP_STRING& sCtrlID, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); + CCtrlAutoNumber(const HWP_STRING& sCtrlID, CXMLNode& oNode, int nVersion); + + ECtrlObjectType GetCtrlType() const override; + + ENumType GetNumType() const; +}; +} + +#endif // CTRLAUTONUMBER_H diff --git a/HwpFile/HwpDoc/Paragraph/CtrlCharacter.cpp b/HwpFile/HwpDoc/Paragraph/CtrlCharacter.cpp new file mode 100644 index 00000000000..463e6fc7ef7 --- /dev/null +++ b/HwpFile/HwpDoc/Paragraph/CtrlCharacter.cpp @@ -0,0 +1,33 @@ +#include "CtrlCharacter.h" + +namespace HWP +{ +CCtrlCharacter::CCtrlCharacter(const HWP_STRING& sCtrlID, ECtrlCharType eCtrlChar) + : CCtrl(sCtrlID), m_eCtrlChar(eCtrlChar) +{} + +CCtrlCharacter::CCtrlCharacter(const HWP_STRING& sCtrlID, ECtrlCharType eCtrlChar, int nCharShapeID) + : CCtrl(sCtrlID), m_eCtrlChar(eCtrlChar), m_nCharShapeID(nCharShapeID) +{} + +ECtrlObjectType CCtrlCharacter::GetCtrlType() const +{ + return ECtrlObjectType::Character; +} + +int CCtrlCharacter::GetCharShapeId() const +{ + return m_nCharShapeID; +} + + +ECtrlCharType CCtrlCharacter::GetType() const +{ + return m_eCtrlChar; +} + +void CCtrlCharacter::SetCharShapeID(int nCharShapeID) +{ + m_nCharShapeID = nCharShapeID; +} +} diff --git a/HwpFile/HwpDoc/Paragraph/CtrlCharacter.h b/HwpFile/HwpDoc/Paragraph/CtrlCharacter.h new file mode 100644 index 00000000000..65d06641525 --- /dev/null +++ b/HwpFile/HwpDoc/Paragraph/CtrlCharacter.h @@ -0,0 +1,32 @@ +#ifndef CTRLCHARACTER_H +#define CTRLCHARACTER_H + +#include "Ctrl.h" + +namespace HWP +{ +enum class ECtrlCharType +{ + LINE_BREAK = 0x1, + PARAGRAPH_BREAK = 0x2, + HARD_HYPHEN = 0x3, + HARD_SPACE = 0x04 +}; + +class CCtrlCharacter : public CCtrl +{ + ECtrlCharType m_eCtrlChar; + int m_nCharShapeID; +public: + CCtrlCharacter(const HWP_STRING& sCtrlID, ECtrlCharType eCtrlChar); + CCtrlCharacter(const HWP_STRING& sCtrlID, ECtrlCharType eCtrlChar, int nCharShapeID); + + ECtrlObjectType GetCtrlType() const override; + int GetCharShapeId() const; + ECtrlCharType GetType() const; + + void SetCharShapeID(int nCharShapeID); +}; +} + +#endif // CTRLCHARACTER_H diff --git a/HwpFile/HwpDoc/Paragraph/CtrlClick.cpp b/HwpFile/HwpDoc/Paragraph/CtrlClick.cpp new file mode 100644 index 00000000000..a4e7956f63c --- /dev/null +++ b/HwpFile/HwpDoc/Paragraph/CtrlClick.cpp @@ -0,0 +1,21 @@ +#include "CtrlClick.h" + +namespace HWP +{ +CCtrlClick::CCtrlClick(const HWP_STRING& sCtrlId, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) + : CCtrl(sCtrlId) +{ + oBuffer.Skip(4); + oBuffer.Skip(1); + + oBuffer.ReadString(m_sClickHereStr, EStringCharacter::UTF16); + + oBuffer.Skip(4); + oBuffer.Skip(4); +} + +ECtrlObjectType CCtrlClick::GetCtrlType() const +{ + return ECtrlObjectType::Click; +} +} diff --git a/HwpFile/HwpDoc/Paragraph/CtrlClick.h b/HwpFile/HwpDoc/Paragraph/CtrlClick.h new file mode 100644 index 00000000000..5d500e3804a --- /dev/null +++ b/HwpFile/HwpDoc/Paragraph/CtrlClick.h @@ -0,0 +1,19 @@ +#ifndef CTRLCLICK_H +#define CTRLCLICK_H + +#include "Ctrl.h" +#include "../HWPStream.h" + +namespace HWP +{ +class CCtrlClick : public CCtrl +{ + HWP_STRING m_sClickHereStr; +public: + CCtrlClick(const HWP_STRING& sCtrlId, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); + + ECtrlObjectType GetCtrlType() const override; +}; +} + +#endif // CTRLCLICK_H diff --git a/HwpFile/HwpDoc/Paragraph/CtrlColumnDef.cpp b/HwpFile/HwpDoc/Paragraph/CtrlColumnDef.cpp new file mode 100644 index 00000000000..fa69f62886a --- /dev/null +++ b/HwpFile/HwpDoc/Paragraph/CtrlColumnDef.cpp @@ -0,0 +1,90 @@ +#include "CtrlColumnDef.h" + +namespace HWP +{ +CCtrlColumnDef::CCtrlColumnDef(const HWP_STRING& sCtrlID) + : CCtrl(sCtrlID) +{} + +CCtrlColumnDef::CCtrlColumnDef(const HWP_STRING& sCtrlID, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) + : CCtrl(sCtrlID) +{ + short shAttrLowBits; + oBuffer.ReadShort(shAttrLowBits); + oBuffer.ReadShort(m_shSameGap); + + m_shColCount = (short)(shAttrLowBits >> 2 & 0xFF); + m_bSameSz = CHECK_FLAG(shAttrLowBits >> 12, 0x1); + + if (!m_bSameSz) + { + m_arColSzWidths.resize(m_shColCount); + m_arColSzGaps.resize(m_shColCount - 1); + + for (int nIndex = 0; nIndex < m_shColCount; ++nIndex) + { + oBuffer.ReadShort(m_arColSzWidths[nIndex]); + if (nIndex < m_shColCount - 1) + oBuffer.ReadShort(m_arColSzGaps[nIndex]); + } + } + + short shAttrHighBits; + oBuffer.ReadShort(shAttrHighBits); + m_eColLineStyle = GetLineStyle2(oBuffer.ReadByte()); + oBuffer.ReadByte(m_chColLineWidth); + oBuffer.ReadInt(m_nColLineColor); + + m_nAttr = shAttrHighBits << 16 | shAttrLowBits; + + m_bFullFilled = true; +} + +CCtrlColumnDef::CCtrlColumnDef(const HWP_STRING& sCtrlID, CXMLNode& oNode, int nVersion) + : CCtrl(sCtrlID) +{ + m_eColLineStyle = ELineStyle2::SOLID; + m_shColCount = oNode.GetAttributeInt(L"colCount"); + m_bSameSz = oNode.GetAttributeBool(L"sameSz"); + + if (!m_bSameSz) + { + m_arColSzWidths.resize(m_shColCount); + m_arColSzGaps.resize(m_shColCount); + } + + unsigned int unColSzIndex = 0; + + for (CXMLNode& oChild : oNode.GetChilds()) + { + if (L"hp:colLine" == oChild.GetName()) + { + m_eColLineStyle = GetLineStyle2(oChild.GetAttribute(L"type")); + m_chColLineWidth = (HWP_BYTE)ConvertWidthToHWP(oChild.GetAttribute(L"width")); + m_nColLineColor = oChild.GetAttributeColor(L"color"); + } + else if (L"hp:colSz" == oChild.GetName()) + { + m_arColSzWidths[unColSzIndex] = oChild.GetAttributeInt(L"width"); + m_arColSzGaps[unColSzIndex++] = oChild.GetAttributeInt(L"gap"); + } + } + + m_bFullFilled = true; +} + +ECtrlObjectType CCtrlColumnDef::GetCtrlType() const +{ + return ECtrlObjectType::ColumnDef; +} + +short CCtrlColumnDef::GetColCount() const +{ + return m_shColCount; +} + +ELineStyle2 CCtrlColumnDef::GetColLineStyle() const +{ + return m_eColLineStyle; +} +} diff --git a/HwpFile/HwpDoc/Paragraph/CtrlColumnDef.h b/HwpFile/HwpDoc/Paragraph/CtrlColumnDef.h new file mode 100644 index 00000000000..1ae218e8c40 --- /dev/null +++ b/HwpFile/HwpDoc/Paragraph/CtrlColumnDef.h @@ -0,0 +1,34 @@ +#ifndef CTRLCOLUMNDEF_H +#define CTRLCOLUMNDEF_H + +#include "../HWPElements/HwpRecordTypes.h" +#include "../HWPStream.h" +#include "Ctrl.h" +#include "../Common/XMLNode.h" + +namespace HWP +{ +class CCtrlColumnDef : public CCtrl +{ + int m_nAttr; + short m_shColCount; + bool m_bSameSz; + short m_shSameGap; + VECTOR m_arColSzWidths; + VECTOR m_arColSzGaps; + ELineStyle2 m_eColLineStyle; + HWP_BYTE m_chColLineWidth; + int m_nColLineColor; +public: + CCtrlColumnDef(const HWP_STRING& sCtrlID); + CCtrlColumnDef(const HWP_STRING& sCtrlID, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); + CCtrlColumnDef(const HWP_STRING& sCtrlID, CXMLNode& oNode, int nVersion); + + ECtrlObjectType GetCtrlType() const override; + + short GetColCount() const; + ELineStyle2 GetColLineStyle() const; +}; +} + +#endif // CTRLCOLUMNDEF_H diff --git a/HwpFile/HwpDoc/Paragraph/CtrlCommon.cpp b/HwpFile/HwpDoc/Paragraph/CtrlCommon.cpp new file mode 100644 index 00000000000..0e8ea2642c1 --- /dev/null +++ b/HwpFile/HwpDoc/Paragraph/CtrlCommon.cpp @@ -0,0 +1,537 @@ +#include "CtrlCommon.h" +#include "../Common/Common.h" + +#include "CapParagraph.h" + +namespace HWP +{ + EVertAlign GetVertAlign(int nValue) + { + SWITCH(EVertAlign, nValue) + { + DEFAULT(EVertAlign::TOP); + CASE(EVertAlign::CENTER); + CASE(EVertAlign::BOTTOM); + CASE(EVertAlign::INSIDE); + CASE(EVertAlign::OUTSIDE); + } + } + + EVertAlign GetVertAlign(const HWP_STRING& sValue) + { + IF_STRING_IN_ENUM(CENTER, sValue, EVertAlign); + ELSE_IF_STRING_IN_ENUM(BOTTOM, sValue, EVertAlign); + ELSE_IF_STRING_IN_ENUM(INSIDE, sValue, EVertAlign); + ELSE_IF_STRING_IN_ENUM(OUTSIDE, sValue, EVertAlign); + ELSE_STRING_IN_ENUM(TOP, EVertAlign); + } + + EVRelTo GetVRelTo(int nValue) + { + SWITCH(EVRelTo, nValue) + { + CASE(EVRelTo::PARA); + CASE(EVRelTo::PAGE); + DEFAULT(EVRelTo::PAPER); + } + } + + EVRelTo GetVRelTo(const HWP_STRING& sValue) + { + IF_STRING_IN_ENUM(PARA, sValue, EVRelTo); + ELSE_IF_STRING_IN_ENUM(PAGE, sValue, EVRelTo); + ELSE_IF_STRING_IN_ENUM(PAPER, sValue, EVRelTo); + ELSE_STRING_IN_ENUM(PARA, EVRelTo); + } + + EHRelTo GetHRelTo(int nValue) + { + SWITCH(EHRelTo, nValue) + { + CASE(EHRelTo::PAGE); + CASE(EHRelTo::PARA); + CASE(EHRelTo::COLUMN); + DEFAULT(EHRelTo::PAPER); + } + } + + EHRelTo GetHRelTo(const HWP_STRING& sValue) + { + IF_STRING_IN_ENUM(PAGE, sValue, EHRelTo); + ELSE_IF_STRING_IN_ENUM(PARA, sValue, EHRelTo); + ELSE_IF_STRING_IN_ENUM(COLUMN, sValue, EHRelTo); + ELSE_STRING_IN_ENUM(PAPER, EHRelTo); + } + + EWidthRelTo GetWidthRelTo(int nValue) + { + SWITCH(EWidthRelTo, nValue) + { + CASE(EWidthRelTo::PAGE); + CASE(EWidthRelTo::PARA); + CASE(EWidthRelTo::COLUMN); + CASE(EWidthRelTo::ABSOLUTE); + DEFAULT(EWidthRelTo::PAPER); + } + } + + EWidthRelTo GetWidthRelTo(const HWP_STRING& sValue) + { + IF_STRING_IN_ENUM(PAGE, sValue, EWidthRelTo); + ELSE_IF_STRING_IN_ENUM(PARA, sValue, EWidthRelTo); + ELSE_IF_STRING_IN_ENUM(COLUMN, sValue, EWidthRelTo); + ELSE_IF_STRING_IN_ENUM(ABSOLUTE, sValue, EWidthRelTo); + ELSE_STRING_IN_ENUM(PAPER, EWidthRelTo); + } + + EHeightRelTo GetHeightRelTo(int nValue) + { + SWITCH(EHeightRelTo, nValue) + { + CASE(EHeightRelTo::PAGE); + CASE(EHeightRelTo::ABSOLUTE); + DEFAULT(EHeightRelTo::PAPER); + } + } + + EHeightRelTo GetHeightRelTo(const HWP_STRING& sValue) + { + IF_STRING_IN_ENUM(PAGE, sValue, EHeightRelTo); + ELSE_IF_STRING_IN_ENUM(ABSOLUTE, sValue, EHeightRelTo); + ELSE_STRING_IN_ENUM(PAPER, EHeightRelTo); + } + + EHorzAlign GetHorzAlign(int nValue) + { + SWITCH(EHorzAlign, nValue) + { + CASE(EHorzAlign::CENTER); + CASE(EHorzAlign::RIGHT); + CASE(EHorzAlign::INSIDE); + CASE(EHorzAlign::OUTSIDE); + DEFAULT(EHorzAlign::LEFT); + } + } + + EHorzAlign GetHorzAlign(const HWP_STRING& sValue) + { + IF_STRING_IN_ENUM(CENTER, sValue, EHorzAlign); + ELSE_IF_STRING_IN_ENUM(RIGHT, sValue, EHorzAlign); + ELSE_IF_STRING_IN_ENUM(INSIDE, sValue, EHorzAlign); + ELSE_IF_STRING_IN_ENUM(OUTSIDE, sValue, EHorzAlign); + ELSE_STRING_IN_ENUM(LEFT, EHorzAlign); + } + + ETextWrap GetTextWrap(int nValue) + { + SWITCH(ETextWrap, nValue) + { + CASE(ETextWrap::TOP_AND_BOTTOM); + CASE(ETextWrap::BEHIND_TEXT); + CASE(ETextWrap::IN_FRONT_OF_TEXT); + DEFAULT(ETextWrap::SQUARE); + } + } + + ETextWrap GetTextWrap(const HWP_STRING& sValue) + { + IF_STRING_IN_ENUM(TOP_AND_BOTTOM, sValue, ETextWrap); + ELSE_IF_STRING_IN_ENUM(BEHIND_TEXT, sValue, ETextWrap); + ELSE_IF_STRING_IN_ENUM(IN_FRONT_OF_TEXT, sValue, ETextWrap); + ELSE_STRING_IN_ENUM(SQUARE, ETextWrap); + } + + CCtrlCommon::CCtrlCommon() + : m_nVertOffset(0), m_nHorzOffset(0) + {} + + CCtrlCommon::CCtrlCommon(const HWP_STRING& sCtrlID) + : CCtrl(sCtrlID), m_eTextVerAlign(EVertAlign::TOP) + {} + + CCtrlCommon::CCtrlCommon(const CCtrlCommon& oCtrlCommon) + : CCtrl(oCtrlCommon.GetID()) + { + m_nObjAttr = oCtrlCommon.m_nObjAttr; + m_bTreatAsChar = oCtrlCommon.m_bTreatAsChar; + m_bAffectLSpacing = oCtrlCommon.m_bAffectLSpacing; + m_eVertRelTo = oCtrlCommon.m_eVertRelTo; + m_eVertAlign = oCtrlCommon.m_eVertAlign; + m_eHorzRelTo = oCtrlCommon.m_eHorzRelTo; + m_eHorzAlign = oCtrlCommon.m_eHorzAlign; + m_bFlowWithText = oCtrlCommon.m_bFlowWithText; + m_bAllowOverlap = oCtrlCommon.m_bAllowOverlap; + m_eWidthRelTo = oCtrlCommon.m_eWidthRelTo; + m_eHeightRelTo = oCtrlCommon.m_eHeightRelTo; + m_eTextWrap = oCtrlCommon.m_eTextWrap; + m_chTextFlow = oCtrlCommon.m_chTextFlow; + m_chNumeringType = oCtrlCommon.m_chNumeringType; + + m_nVertOffset = oCtrlCommon.m_nVertOffset; + m_nHorzOffset = oCtrlCommon.m_nHorzOffset; + m_nWidth = oCtrlCommon.m_nWidth; + m_nHeight = oCtrlCommon.m_nHeight; + m_nZOrder = oCtrlCommon.m_nZOrder; + + for (unsigned int unIndex = 0; unIndex < 4; ++unIndex) + m_arOutMargin[unIndex] = oCtrlCommon.m_arOutMargin[unIndex]; + + m_nObjInstanceID = oCtrlCommon.m_nObjInstanceID; + m_nBlockPageBreak = oCtrlCommon.m_nBlockPageBreak; + m_sObjDesc = oCtrlCommon.m_sObjDesc; + + m_arParas.resize(oCtrlCommon.m_arParas.size()); + for (unsigned int unIndex = 0; unIndex < oCtrlCommon.m_arParas.size(); ++unIndex) + { + oCtrlCommon.m_arParas[unIndex]->AddRef(); + m_arParas[unIndex] = oCtrlCommon.m_arParas[unIndex]; + } + + m_nCaptionAttr = oCtrlCommon.m_nCaptionAttr; + m_nCaptionWidth = oCtrlCommon.m_nCaptionWidth; + m_nCaptionSpacing = oCtrlCommon.m_nCaptionSpacing; + m_nCaptionMaxW = oCtrlCommon.m_nCaptionMaxW; + + m_arCaption.resize(oCtrlCommon.m_arCaption.size()); + for (unsigned int unIndex = 0; unIndex < oCtrlCommon.m_arCaption.size(); ++unIndex) + { + oCtrlCommon.m_arCaption[unIndex]->AddRef(); + m_arCaption[unIndex] = oCtrlCommon.m_arCaption[unIndex]; + } + + m_eTextVerAlign = oCtrlCommon.m_eTextVerAlign; + } + + CCtrlCommon::CCtrlCommon(const HWP_STRING& sCtrlID, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) + : CCtrl(sCtrlID) + { + oBuffer.SavePosition(); + + oBuffer.ReadInt(m_nObjAttr); + + m_bTreatAsChar = CHECK_FLAG(m_nObjAttr, 0x01); + m_bAffectLSpacing = CHECK_FLAG(m_nObjAttr, 0x04); + m_eVertRelTo = GetVRelTo(m_nObjAttr >> 3 & 0x03); + m_eVertAlign = GetVertAlign(m_nObjAttr >> 5 & 0x07); + m_eHorzRelTo = GetHRelTo(m_nObjAttr >> 8 & 0x03); + m_eHorzAlign = GetHorzAlign(m_nObjAttr >> 10 & 0x07); + m_bFlowWithText = CHECK_FLAG(m_nObjAttr, 0x2000); + m_bAllowOverlap = CHECK_FLAG(m_nObjAttr, 0x4000); + m_eWidthRelTo = ::HWP::GetWidthRelTo(m_nObjAttr >> 15 & 0x07); + m_eHeightRelTo = ::HWP::GetHeightRelTo(m_nObjAttr >> 18 & 0x03); + m_eTextWrap = ::HWP::GetTextWrap(m_nObjAttr >> 21 & 0x07); + m_chTextFlow = (HWP_BYTE)(m_nObjAttr >> 24 & 0x03); + m_chNumeringType = (HWP_BYTE)(m_nObjAttr >> 26 & 0x07); + + oBuffer.ReadInt(m_nVertOffset); + oBuffer.ReadInt(m_nHorzOffset); + oBuffer.ReadInt(m_nWidth); + oBuffer.ReadInt(m_nHeight); + oBuffer.ReadInt(m_nZOrder); + + for (int nIndex = 0; nIndex < 4; ++nIndex) + oBuffer.ReadShort(m_arOutMargin[nIndex]); + + oBuffer.ReadInt(m_nObjInstanceID); + oBuffer.ReadInt(m_nBlockPageBreak); + + if (nSize > oBuffer.GetDistanceToLastPos(true)) + oBuffer.ReadString(m_sObjDesc, EStringCharacter::UTF16); + } + + CCtrlCommon::CCtrlCommon(const HWP_STRING& sCtrlID, CXMLNode& oNode, int nVersion) + : CCtrl(sCtrlID), m_eTextVerAlign(EVertAlign::TOP) + { + m_nObjInstanceID = std::abs(oNode.GetAttributeInt(L"id")); + + HWP_STRING sType = oNode.GetAttribute(L"textFlow"); + + if (L"BOTH_SIDES" == sType) + m_chTextFlow = 0; + else if (L"LEFT_ONLY" == sType) + m_chTextFlow = 1; + else if (L"RIGHT_ONLY" == sType) + m_chTextFlow = 2; + else if (L"LARGEST_ONLY" == sType) + m_chTextFlow = 3; + + sType = oNode.GetAttribute(L"textWrap"); + + if (L"SQUARE" == sType) + m_eTextWrap = ETextWrap::SQUARE; + else if (L"TOP_AND_BOTTOM" == sType) + m_eTextWrap = ETextWrap::TOP_AND_BOTTOM; + else if (L"BEHIND_TEXT" == sType) + m_eTextWrap = ETextWrap::BEHIND_TEXT; + else if (L"IN_FRONT_OF_TEXT" == sType) + m_eTextWrap = ETextWrap::IN_FRONT_OF_TEXT; + + m_nZOrder = oNode.GetAttributeInt(L"zOrder"); + + sType = oNode.GetAttribute(L"numberingType"); + + if (L"NONE" == sType) + m_chNumeringType = 0; + else if (L"PICTURE" == sType) + m_chNumeringType = 1; + else if (L"TABLE" == sType) + m_chNumeringType = 2; + else if (L"EQUATION" == sType) + m_chNumeringType = 3; + + for (CXMLNode& oChild : oNode.GetChilds()) + { + if (L"hp:sz" == oChild.GetName()) + { + m_nWidth = oChild.GetAttributeInt(L"width"); + m_eWidthRelTo = ::HWP::GetWidthRelTo(oChild.GetAttribute(L"widthRelTo")); + m_nHeight = oChild.GetAttributeInt(L"height"); + m_eHeightRelTo = ::HWP::GetHeightRelTo(oChild.GetAttribute(L"heightRelTo")); + } + else if (L"hp:pos" == oChild.GetName()) + { + m_bTreatAsChar = oChild.GetAttributeBool(L"treatAsChar"); + + if (m_bTreatAsChar) + m_bAffectLSpacing = oChild.GetAttributeBool(L"affectLSpacing"); + else + m_bAllowOverlap = oChild.GetAttributeBool(L"allowOverlap"); + + m_eVertRelTo = GetVRelTo(oChild.GetAttribute(L"vertRelTo")); + m_eHorzRelTo = GetHRelTo(oChild.GetAttribute(L"horzRelTo")); + + if (EVRelTo::PARA == m_eVertRelTo) + m_bFlowWithText = oChild.GetAttributeBool(L"flowWithText"); + + m_eVertAlign = GetVertAlign(oChild.GetAttribute(L"vertAlign")); + m_eHorzAlign = GetHorzAlign(oChild.GetAttribute(L"horzAlign")); + m_nVertOffset = oChild.GetAttributeInt(L"vertOffset"); + m_nHorzOffset = oChild.GetAttributeInt(L"horzOffset"); + } + else if (L"hp:outMargin" == oChild.GetName()) + { + m_arOutMargin[0] = oChild.GetAttributeInt(L"left"); + m_arOutMargin[1] = oChild.GetAttributeInt(L"right"); + m_arOutMargin[2] = oChild.GetAttributeInt(L"top"); + m_arOutMargin[3] = oChild.GetAttributeInt(L"bottom"); + } + else if (L"hp:caption" == oChild.GetName()) + { + HWP_STRING sType = oChild.GetAttribute(L"side"); + + if (L"LEFT" == sType) + m_nCaptionAttr = 0b00; + else if (L"RIGHT" == sType) + m_nCaptionAttr = 0b01; + else if (L"TOP" == sType) + m_nCaptionAttr = 0b10; + else if (L"BOTTOM" == sType) + m_nCaptionAttr = 0b11; + + if (oChild.GetAttributeBool(L"fullSz")) + m_nCaptionAttr |= 0b100; + + m_nCaptionWidth = oChild.GetAttributeInt(L"width"); + m_nCaptionSpacing = oChild.GetAttributeInt(L"gap"); + m_nCaptionMaxW = oChild.GetAttributeInt(L"lastWidth"); + + for (CXMLNode& oSubList : oChild.GetChilds(L"hp:subList")) + { + for (CXMLNode& oParagraph : oSubList.GetChilds(L"hp:p")) + m_arCaption.push_back(new CCapParagraph(oParagraph, nVersion)); + } + } + } + } + + CCtrlCommon::~CCtrlCommon() + { + for (CHWPPargraph* pParagraph : m_arParas) + { + if (0 == pParagraph->Release()) + pParagraph = nullptr; + } + + for (CCapParagraph* pCapParagraph : m_arCaption) + { + if (0 == pCapParagraph->Release()) + pCapParagraph = nullptr; + } + } + + ECtrlObjectType CCtrlCommon::GetCtrlType() const + { + return ECtrlObjectType::Common; + } + + void CCtrlCommon::SetTextVerAlign(EVertAlign eVertAlign) + { + m_eTextVerAlign = eVertAlign; + } + + void CCtrlCommon::AddParagraph(CHWPPargraph* pParagraph) + { + m_arParas.push_back(pParagraph); + } + + void CCtrlCommon::AddCaption(CCapParagraph* pCapPara) + { + m_arCaption.push_back(pCapPara); + } + + CHWPPargraph* CCtrlCommon::GetLastPara() + { + return (!m_arParas.empty()) ? m_arParas.back() : nullptr; + } + + unsigned int CCtrlCommon::GetCountParagraphs() const + { + return (unsigned int)m_arParas.size(); + } + + const CHWPPargraph* CCtrlCommon::GetParagraphs(unsigned int unIndex) const + { + if (unIndex >= m_arParas.size()) + return nullptr; + + return m_arParas[unIndex]; + } + + short CCtrlCommon::GetLeftMargin() const + { + return m_arOutMargin[0]; + } + + short CCtrlCommon::GetTopMargin() const + { + return m_arOutMargin[2]; + } + + short CCtrlCommon::GetRightMargin() const + { + return m_arOutMargin[1]; + } + + short CCtrlCommon::GetBottomMargin() const + { + return m_arOutMargin[3]; + } + + bool CCtrlCommon::GetTreatAsChar() const + { + return m_bTreatAsChar; + } + + bool CCtrlCommon::GetFlowWithText() const + { + return m_bFlowWithText; + } + + int CCtrlCommon::GetHorzOffset() const + { + return m_nHorzOffset; + } + + int CCtrlCommon::GetVertOffset() const + { + return m_nVertOffset; + } + + EVRelTo CCtrlCommon::GetVertRelTo() const + { + return m_eVertRelTo; + } + + EHRelTo CCtrlCommon::GetHorzRelTo() const + { + return m_eHorzRelTo; + } + + int CCtrlCommon::GetCaptionWidth() const + { + return m_nCaptionWidth; + } + + bool CCtrlCommon::CaptionsEmpty() const + { + return m_arCaption.empty(); + } + + HWP_STRING CCtrlCommon::GetDesc() const + { + return m_sObjDesc; + } + + EWidthRelTo CCtrlCommon::GetWidthRelTo() const + { + return m_eWidthRelTo; + } + + EHeightRelTo CCtrlCommon::GetHeightRelTo() const + { + return m_eHeightRelTo; + } + + int CCtrlCommon::GetWidth() const + { + return m_nWidth; + } + + int CCtrlCommon::GetHeight() const + { + return m_nHeight; + } + + ETextWrap CCtrlCommon::GetTextWrap() const + { + return m_eTextWrap; + } + + HWP_BYTE CCtrlCommon::GetTextFlow() const + { + return m_chTextFlow; + } + + int CCtrlCommon::GetZOrder() const + { + return m_nZOrder; + } + + bool CCtrlCommon::HaveCaption() const + { + return !m_arCaption.empty(); + } + + std::vector CCtrlCommon::GetCaptionParas() const + { + RETURN_VECTOR_CONST_PTR(CCapParagraph, m_arCaption); + } + + int CCtrlCommon::ParseCtrl(CCtrlCommon& oObj, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) + { + HWP_STRING sCtrlId; + oBuffer.ReadString(sCtrlId, 4, EStringCharacter::ASCII); + + if (L"nil$" == sCtrlId || L"loc$" == sCtrlId || L"cer$" == sCtrlId || L"lle$" == sCtrlId || + L"cra$" == sCtrlId || L"lop$" == sCtrlId || L"ruc$" == sCtrlId || L"deqe" == sCtrlId || + L"cip$" == sCtrlId || L"elo$" == sCtrlId || L"noc$" == sCtrlId || L"div$" == sCtrlId || + L"tat$" == sCtrlId) + return 4; + + oBuffer.Skip(-4); + return 0; + + //TODO:: проверить данный метод + // в исходном коде есть дальнейшие действия + } + + int CCtrlCommon::ParseCaption(CCtrlCommon& oObj, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) + { + oBuffer.ReadInt(oObj.m_nCaptionAttr); + oBuffer.ReadInt(oObj.m_nCaptionWidth); + oBuffer.ReadInt(oObj.m_nCaptionSpacing); + oBuffer.ReadInt(oObj.m_nCaptionMaxW); + + return 16; + } +} diff --git a/HwpFile/HwpDoc/Paragraph/CtrlCommon.h b/HwpFile/HwpDoc/Paragraph/CtrlCommon.h new file mode 100644 index 00000000000..525d88e7ce9 --- /dev/null +++ b/HwpFile/HwpDoc/Paragraph/CtrlCommon.h @@ -0,0 +1,160 @@ +#ifndef CTRLCOMMON_H +#define CTRLCOMMON_H + +#include "../HWPStream.h" +#include "CapParagraph.h" +#include "Ctrl.h" + +namespace HWP +{ + +enum class EVRelTo +{ + PAPER, + PAGE, + PARA +}; + +enum class EHRelTo +{ + PAPER, + PAGE, + COLUMN, + PARA +}; + +enum class EWidthRelTo +{ + PAPER, + PAGE, + COLUMN, + PARA, + ABSOLUTE +}; + +enum class EHeightRelTo +{ + PAPER, + PAGE, + ABSOLUTE +}; + +enum class EVertAlign +{ + TOP, + CENTER, + BOTTOM, + INSIDE, + OUTSIDE +}; + +EVertAlign GetVertAlign(int nValue); +EVertAlign GetVertAlign(const HWP_STRING& sValue); + +enum class EHorzAlign +{ + LEFT, + CENTER, + RIGHT, + INSIDE, + OUTSIDE +}; + +enum class ETextWrap +{ + SQUARE, + TOP_AND_BOTTOM, + BEHIND_TEXT, + IN_FRONT_OF_TEXT +}; + +class CCtrlCommon : public CCtrl +{ + int m_nObjAttr; + bool m_bTreatAsChar; + bool m_bAffectLSpacing; + EVRelTo m_eVertRelTo; + EVertAlign m_eVertAlign; + EHRelTo m_eHorzRelTo; + EHorzAlign m_eHorzAlign; + bool m_bFlowWithText; + bool m_bAllowOverlap; + EWidthRelTo m_eWidthRelTo; + EHeightRelTo m_eHeightRelTo; + ETextWrap m_eTextWrap; + HWP_BYTE m_chTextFlow; + HWP_BYTE m_chNumeringType; + + int m_nVertOffset; + int m_nHorzOffset; + int m_nWidth; + int m_nHeight; + int m_nZOrder; + short m_arOutMargin[4]; + int m_nObjInstanceID; + int m_nBlockPageBreak; + HWP_STRING m_sObjDesc; + + VECTOR m_arParas; + int m_nCaptionAttr; + int m_nCaptionWidth; + int m_nCaptionSpacing; + int m_nCaptionMaxW; + VECTOR m_arCaption; + + EVertAlign m_eTextVerAlign; + + friend class CCtrlGeneralShape; + friend class CCtrlShapeVideo; + friend class CCtrlEqEdit; + friend class CCtrlTable; +public: + CCtrlCommon(); + CCtrlCommon(const HWP_STRING& sCtrlID); + CCtrlCommon(const CCtrlCommon& oCtrlCommon); + CCtrlCommon(const HWP_STRING& sCtrlID, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); + CCtrlCommon(const HWP_STRING& sCtrlID, CXMLNode& oNode, int nVersion); + virtual ~CCtrlCommon(); + + ECtrlObjectType GetCtrlType() const override; + + void SetTextVerAlign(EVertAlign eVertAlign); + + void AddParagraph(CHWPPargraph* pParagraph); + void AddCaption(CCapParagraph* pCapPara); + + CHWPPargraph* GetLastPara(); + unsigned int GetCountParagraphs() const; + const CHWPPargraph* GetParagraphs(unsigned int unIndex) const; + + short GetLeftMargin() const; + short GetTopMargin() const; + short GetRightMargin() const; + short GetBottomMargin() const; + + bool GetTreatAsChar() const; + bool GetFlowWithText() const; + int GetHorzOffset() const; + int GetVertOffset() const; + EVRelTo GetVertRelTo() const; + EHRelTo GetHorzRelTo() const; + int GetCaptionWidth() const; + bool CaptionsEmpty() const; + HWP_STRING GetDesc() const; + EWidthRelTo GetWidthRelTo() const; + EHeightRelTo GetHeightRelTo() const; + int GetWidth() const; + int GetHeight() const; + ETextWrap GetTextWrap() const; + HWP_BYTE GetTextFlow() const; + int GetZOrder() const; + + bool HaveCaption() const; + VECTOR GetCaptionParas() const; + + static int ParseCtrl(CCtrlCommon& oObj, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); + static int ParseCaption(CCtrlCommon& oObj, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); +}; +} + +#endif // CTRLCOMMON_H diff --git a/HwpFile/HwpDoc/Paragraph/CtrlContainer.cpp b/HwpFile/HwpDoc/Paragraph/CtrlContainer.cpp new file mode 100644 index 00000000000..320aaeec06e --- /dev/null +++ b/HwpFile/HwpDoc/Paragraph/CtrlContainer.cpp @@ -0,0 +1,165 @@ +#include "CtrlContainer.h" + +#include "CtrlShapeArc.h" +#include "CtrlShapePic.h" +#include "CtrlShapeOle.h" +#include "CtrlShapeRect.h" +#include "CtrlShapeLine.h" +#include "CtrlContainer.h" +#include "CtrlShapeCurve.h" +#include "CtrlShapeEllipse.h" +#include "CtrlShapePolygon.h" +#include "CtrlShapeConnectLine.h" + +namespace HWP +{ +CCtrlContainer::CCtrlContainer(const HWP_STRING& sCtrlID) + : CCtrlGeneralShape(sCtrlID) +{} + +CCtrlContainer::CCtrlContainer(const CCtrlGeneralShape& oShape) + : CCtrlGeneralShape(oShape) +{} + +CCtrlContainer::CCtrlContainer(const HWP_STRING& sCtrlID, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) + : CCtrlGeneralShape(sCtrlID, nSize, oBuffer, nOff, nVersion) +{} + +CCtrlContainer::CCtrlContainer(const HWP_STRING& sCtrlID, CXMLNode& oNode, int nVersion) + : CCtrlGeneralShape(sCtrlID, oNode, nVersion) +{ + for (CXMLNode& oChild : oNode.GetChilds()) + { + if (L"hp:container" == oChild.GetName()) + m_arShapes.push_back(new CCtrlContainer(L"noc$", oChild, nVersion)); + else if (L"hp:line" == oChild.GetName()) + m_arShapes.push_back(new CCtrlShapeLine(L"nil$", oChild, nVersion)); + else if (L"hp:rect" == oChild.GetName()) + m_arShapes.push_back(new CCtrlShapeRect(L"cer$", oChild, nVersion)); + else if (L"hp:ellipse" == oChild.GetName()) + m_arShapes.push_back(new CCtrlShapeEllipse(L"lle$", oChild, nVersion)); + else if (L"hp:arc" == oChild.GetName()) + m_arShapes.push_back(new CCtrlShapeArc(L"cra$", oChild, nVersion)); + else if (L"hp:polygon" == oChild.GetName()) + m_arShapes.push_back(new CCtrlShapePolygon(L"lop$", oChild, nVersion)); + else if (L"hp:curve" == oChild.GetName()) + m_arShapes.push_back(new CCtrlShapeCurve(L"ruc$", oChild, nVersion)); + else if (L"hp:connectLine" == oChild.GetName()) + m_arShapes.push_back(new CCtrlShapeConnectLine(L"loc$", oChild, nVersion)); + else if (L"hp:pic" == oChild.GetName()) + m_arShapes.push_back(new CCtrlShapePic(L"cip$", oChild, nVersion)); + else if (L"hp:ole" == oChild.GetName()) + m_arShapes.push_back(new CCtrlShapeOle(L"elo$", oChild, nVersion)); + } + + m_shNElement = m_arShapes.size(); +} + +CCtrlContainer::~CCtrlContainer() +{ + for (CCtrlGeneralShape* pElement : m_arShapes) + { + if (nullptr != pElement) + delete pElement; + } +} + +EShapeType CCtrlContainer::GetShapeType() const +{ + return EShapeType::Container; +} + +void CCtrlContainer::AddShape(CCtrlGeneralShape* pShape) +{ + m_arShapes.push_back(pShape); +} + +bool CCtrlContainer::Empty() const +{ + return m_arShapes.empty(); +} + +std::vector CCtrlContainer::GetShapes() const +{ + return m_arShapes; +} + +CCtrlGeneralShape* CCtrlContainer::GetLastShape() +{ + return (!m_arShapes.empty()) ? m_arShapes.back() : nullptr; +} + +int CCtrlContainer::ParseElement(CCtrlContainer& oObj, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) +{ + oBuffer.SavePosition(); + + oBuffer.ReadShort(oObj.m_shNElement); + + if (oObj.m_shNElement <= 0) + return oBuffer.GetDistanceToLastPos(true); + + oObj.m_arCtrlIdList.resize(oObj.m_shNElement); + + for (unsigned int unIndex = 0; unIndex < oObj.m_shNElement; ++unIndex) + oBuffer.ReadString(oObj.m_arCtrlIdList[unIndex], 4, EStringCharacter::ASCII); + + oObj.m_arShapes.resize(oObj.m_shNElement); + + HWP_STRING sCtrlId; + + #define CREATE_OBJECT(class_name) \ + { \ + pChldObj = new class_name(sCtrlId, nSize - oBuffer.GetDistanceToLastPos(), oBuffer, 0, nVersion); \ + class_name::ParseCtrl((class_name&)pChldObj, nSize, oBuffer, 0, nVersion); \ + pChldObj->SetID(sCtrlId); \ + } + + for (unsigned int unIndex = 0; unIndex < oObj.m_shNElement; ++unIndex) + { + CCtrlGeneralShape* pChldObj = nullptr; + + oBuffer.ReadString(sCtrlId, 4, EStringCharacter::ASCII); + + if (L"cip$" == sCtrlId) + CREATE_OBJECT(CCtrlShapePic) + else if (L"cer$" == sCtrlId) + CREATE_OBJECT(CCtrlShapeRect) + else if (L"nil$" == sCtrlId) + CREATE_OBJECT(CCtrlShapeLine) + else if (L"noc$" == sCtrlId) + CREATE_OBJECT(CCtrlContainer) + else if (L"lle$" == sCtrlId) + CREATE_OBJECT(CCtrlShapeEllipse) + else if (L"lop$" == sCtrlId) + CREATE_OBJECT(CCtrlShapePolygon) + else if (L"cra$" == sCtrlId) + CREATE_OBJECT(CCtrlShapeArc) + else if (L"ruc$" == sCtrlId) + CREATE_OBJECT(CCtrlShapeCurve) + else if (L"elo$" == sCtrlId) + CREATE_OBJECT(CCtrlShapeOle) + + oObj.m_arShapes[unIndex] = pChldObj; + } + + return oBuffer.GetDistanceToLastPos(true); +} + +int CCtrlContainer::ParseCtrl(CCtrlContainer& oObj, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) +{ + oBuffer.SavePosition(); + + CCtrlObjElement::ParseCtrl(oObj, nSize, oBuffer, nOff, nVersion); + + oBuffer.ReadShort(oObj.m_shNElement); + + oObj.m_arCtrlIdList.resize(oObj.m_shNElement); + + for (unsigned int unIndex = 0; unIndex < oObj.m_shNElement; ++unIndex) + oBuffer.ReadString(oObj.m_arCtrlIdList[unIndex], 4, EStringCharacter::ASCII); + + oBuffer.Skip(4); + + return oBuffer.GetDistanceToLastPos(true); +} +} diff --git a/HwpFile/HwpDoc/Paragraph/CtrlContainer.h b/HwpFile/HwpDoc/Paragraph/CtrlContainer.h new file mode 100644 index 00000000000..3c92cf5d4d2 --- /dev/null +++ b/HwpFile/HwpDoc/Paragraph/CtrlContainer.h @@ -0,0 +1,35 @@ +#ifndef CTRLCONTAINER_H +#define CTRLCONTAINER_H + +#include "CtrlGeneralShape.h" + +namespace HWP +{ +class CCtrlContainer : public CCtrlGeneralShape +{ + short m_shNElement; + VECTOR m_arCtrlIdList; + VECTOR m_arShapes; +public: + CCtrlContainer(const HWP_STRING& sCtrlID); + CCtrlContainer(const CCtrlGeneralShape& oShape); + CCtrlContainer(const HWP_STRING& sCtrlID, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); + CCtrlContainer(const HWP_STRING& sCtrlID, CXMLNode& oNode, int nVersion); + + ~CCtrlContainer(); + + EShapeType GetShapeType() const override; + + bool Empty() const; + + VECTOR GetShapes() const; + + void AddShape(CCtrlGeneralShape* pShape); + CCtrlGeneralShape* GetLastShape(); + + static int ParseElement(CCtrlContainer& oObj, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); + static int ParseCtrl(CCtrlContainer& oObj, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); +}; +} + +#endif // CTRLCONTAINER_H diff --git a/HwpFile/HwpDoc/Paragraph/CtrlEmpty.cpp b/HwpFile/HwpDoc/Paragraph/CtrlEmpty.cpp new file mode 100644 index 00000000000..e7d6267ecb3 --- /dev/null +++ b/HwpFile/HwpDoc/Paragraph/CtrlEmpty.cpp @@ -0,0 +1,16 @@ +#include "CtrlEmpty.h" + +namespace HWP +{ +CCtrlEmpty::CCtrlEmpty() +{} + +CCtrlEmpty::CCtrlEmpty(const HWP_STRING& sCtrlID) + : CCtrl(sCtrlID) +{} + +ECtrlObjectType CCtrlEmpty::GetCtrlType() const +{ + return ECtrlObjectType::Empty; +} +} diff --git a/HwpFile/HwpDoc/Paragraph/CtrlEmpty.h b/HwpFile/HwpDoc/Paragraph/CtrlEmpty.h new file mode 100644 index 00000000000..02372f15eb7 --- /dev/null +++ b/HwpFile/HwpDoc/Paragraph/CtrlEmpty.h @@ -0,0 +1,18 @@ +#ifndef CTRLEMPTY_H +#define CTRLEMPTY_H + +#include "Ctrl.h" + +namespace HWP +{ +class CCtrlEmpty : public CCtrl +{ +public: + CCtrlEmpty(); + CCtrlEmpty(const HWP_STRING& sCtrlID); + + ECtrlObjectType GetCtrlType() const override; +}; +} + +#endif // CTRLEMPTY_H diff --git a/HwpFile/HwpDoc/Paragraph/CtrlEqEdit.cpp b/HwpFile/HwpDoc/Paragraph/CtrlEqEdit.cpp new file mode 100644 index 00000000000..f0730e8dc6a --- /dev/null +++ b/HwpFile/HwpDoc/Paragraph/CtrlEqEdit.cpp @@ -0,0 +1,100 @@ +#include "CtrlEqEdit.h" + +namespace HWP +{ +CCtrlEqEdit::CCtrlEqEdit() +{} + +CCtrlEqEdit::CCtrlEqEdit(const HWP_STRING& sCtrlID) + : CCtrlGeneralShape(sCtrlID) +{} + +CCtrlEqEdit::CCtrlEqEdit(const CCtrlGeneralShape& oShape) + : CCtrlGeneralShape(oShape) +{} + +CCtrlEqEdit::CCtrlEqEdit(const HWP_STRING& sCtrlID, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) + : CCtrlGeneralShape(sCtrlID, nSize, oBuffer, nOff, nVersion) +{} + +CCtrlEqEdit::CCtrlEqEdit(const HWP_STRING& sCtrlID, CXMLNode& oNode, int nVersion) + : CCtrlGeneralShape(sCtrlID) +{ + m_sVersion = oNode.GetAttribute(L"version"); + m_nBaseline = oNode.GetAttributeInt(L"baseLine"); + m_nColor = oNode.GetAttributeColor(L"textColor"); + m_nCharSize = oNode.GetAttributeInt(L"baseUnit"); + + HWP_STRING sType = oNode.GetAttribute(L"lineMode"); + + if (L"LINE" == sType) + m_nAttr = 1; + else if (L"CHAR" == sType) + m_nAttr = 0; + + m_sFont = oNode.GetAttribute(L"font"); + m_sEqn = oNode.GetChild(L"hp:script").GetText(); + + m_bFullFilled = true; +} + +EShapeType CCtrlEqEdit::GetShapeType() const +{ + return EShapeType::EqEdit; +} + +HWP_STRING CCtrlEqEdit::GetEqn() const +{ + return m_sEqn; +} + +int CCtrlEqEdit::ParseElement(CCtrlEqEdit& oObj, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) +{ + oBuffer.SavePosition(); + + oObj.m_bFullFilled = true; + + oBuffer.ReadInt(oObj.m_nAttr); + oBuffer.ReadString(oObj.m_sEqn, EStringCharacter::UTF16); + oBuffer.ReadInt(oObj.m_nCharSize); + oBuffer.ReadColor(oObj.m_nColor); + oBuffer.ReadInt(oObj.m_nBaseline); + oBuffer.ReadString(oObj.m_sVersion, EStringCharacter::UTF16); + + if (oBuffer.GetDistanceToLastPos() + 2 <= nSize) + { + short shLen = oBuffer.ReadShort(); + + if (oBuffer.GetDistanceToLastPos() + shLen <= nSize) + oBuffer.ReadString(oObj.m_sFont, shLen, EStringCharacter::UTF16); + } + + oBuffer.Skip(nSize - oBuffer.GetDistanceToLastPos(true)); + + return nSize; +} + +int CCtrlEqEdit::ParseCtrl(CCtrlEqEdit& oObj, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) +{ + return CCtrlCommon::ParseCtrl(oObj, nSize, oBuffer, nOff, nVersion); +} + +int CCtrlEqEdit::ParseListHeaderAppend(CCtrlEqEdit& oObj, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) +{ + if (24 != nSize) + { + oBuffer.Skip(nSize); + return nSize; + } + + oBuffer.Skip(2); + oBuffer.ReadInt(oObj.m_nCaptionAttr); + oBuffer.ReadInt(oObj.m_nCaptionWidth); + oObj.m_nCaptionSpacing = oBuffer.ReadShort(); + oBuffer.ReadInt(oObj.m_nCaptionMaxW); + oBuffer.Skip(8); + + return nSize; +} + +} diff --git a/HwpFile/HwpDoc/Paragraph/CtrlEqEdit.h b/HwpFile/HwpDoc/Paragraph/CtrlEqEdit.h new file mode 100644 index 00000000000..e4602c5cbe8 --- /dev/null +++ b/HwpFile/HwpDoc/Paragraph/CtrlEqEdit.h @@ -0,0 +1,34 @@ +#ifndef CTRLEQEDIT_H +#define CTRLEQEDIT_H + +#include "CtrlGeneralShape.h" + +namespace HWP +{ +class CCtrlEqEdit : public CCtrlGeneralShape +{ + int m_nAttr; + HWP_STRING m_sEqn; + int m_nCharSize; + int m_nColor; + int m_nBaseline; + HWP_STRING m_sVersion; + HWP_STRING m_sFont; +public: + CCtrlEqEdit(); + CCtrlEqEdit(const HWP_STRING& sCtrlID); + CCtrlEqEdit(const CCtrlGeneralShape& oShape); + CCtrlEqEdit(const HWP_STRING& sCtrlID, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); + CCtrlEqEdit(const HWP_STRING& sCtrlID, CXMLNode& oNode, int nVersion); + + EShapeType GetShapeType() const override; + + HWP_STRING GetEqn() const; + + static int ParseElement(CCtrlEqEdit& oObj, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); + static int ParseCtrl(CCtrlEqEdit& oObj, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); + static int ParseListHeaderAppend(CCtrlEqEdit& oObj, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); +}; +} + +#endif // CTRLEQEDIT_H diff --git a/HwpFile/HwpDoc/Paragraph/CtrlField.cpp b/HwpFile/HwpDoc/Paragraph/CtrlField.cpp new file mode 100644 index 00000000000..5a891c3bd9c --- /dev/null +++ b/HwpFile/HwpDoc/Paragraph/CtrlField.cpp @@ -0,0 +1,113 @@ +#include "CtrlField.h" +#include +#include + +namespace HWP +{ +CCtrlField::CCtrlField(const HWP_STRING& sCtrlID) + : CCtrl(sCtrlID), m_eType(EFieldType::Unknown) +{ + UpdateType(sCtrlID); +} + +CCtrlField::CCtrlField(const HWP_STRING& sCtrlID, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) + : CCtrl(sCtrlID), m_eType(EFieldType::Unknown) +{ + UpdateType(sCtrlID); + + oBuffer.ReadInt(m_nProperty); + oBuffer.ReadByte(m_chEtcProperty); + oBuffer.ReadString(m_sCommand, EStringCharacter::UTF16); + oBuffer.ReadInt(m_nInstanceID); +} + +void CCtrlField::UpdateType(const HWP_STRING& sCtrlID) +{ + if (L"klh%" == sCtrlID) + m_eType = EFieldType::Hyperlink; + else if (L"klh " == sCtrlID) + m_eType = EFieldType::HyperlinkClosing; + else if (L"kmb%" == sCtrlID) + m_eType = EFieldType::Bookmark; + else if (L"kmb " == sCtrlID) + m_eType = EFieldType::BookmarkClosing; +} + +CCtrlField::CCtrlField(const HWP_STRING& sCtrlID, CXMLNode& oNode, int nVersion) + : CCtrl(sCtrlID), m_eType(EFieldType::Unknown) +{ + if (L"hp:fieldBegin" == oNode.GetName()) + { + HWP_STRING sType = oNode.GetAttribute(L"type"); + + if (L"HYPERLINK" == sType) + m_eType = EFieldType::Hyperlink; + else if (L"BOOKMARK" == sType) + m_eType = EFieldType::Bookmark; + + m_nInstanceID = oNode.GetAttributeInt(L"fieldid"); + + HWP_STRING sName = oNode.GetAttribute(L"name"); + + if (!sName.empty() && EFieldType::Bookmark == m_eType) + AddStringParam(L"bookmarkname", sName); + + for (CXMLNode& oChild : oNode.GetChild(L"hp:parameters").GetChilds()) + { + if (L"hp:stringParam" == oChild.GetName()) + AddStringParam(oChild.GetAttribute(L"name"), oChild.GetText()); + else if (L"hp:integerParam" == oChild.GetName()) + AddIntegerParam(oChild.GetAttribute(L"name"), std::stoi(oChild.GetText())); + } + } + else if (L"hp:fieldEnd" == oNode.GetName()) + { + m_nInstanceID = oNode.GetAttributeInt(L"fieldid"); + } +} + +ECtrlObjectType CCtrlField::GetCtrlType() const +{ + return ECtrlObjectType::Field; +} + +void CCtrlField::AddStringParam(const HWP_STRING& wsName, const HWP_STRING& wsValue) +{ + m_mStringParams.insert(std::make_pair(wsName, wsValue)); +} + +void CCtrlField::AddIntegerParam(const HWP_STRING& wsName, int nValue) +{ + m_mIntegerParam.insert(std::make_pair(wsName, nValue)); +} + +HWP_STRING CCtrlField::GetStringParam(const HWP_STRING& wsName) const +{ + std::map::const_iterator itFound = m_mStringParams.find(wsName); + + return ((m_mStringParams.cend() != itFound) ? itFound->second : HWP_STRING()); +} + +int CCtrlField::GetIntegerParam(const HWP_STRING& wsName) const +{ + std::map::const_iterator itFound = m_mIntegerParam.find(wsName); + + return ((m_mIntegerParam.cend() != itFound) ? itFound->second : 0); +} + +int CCtrlField::GetInstanceID() const +{ + return m_nInstanceID; +} + +EFieldType CCtrlField::GetType() const +{ + return m_eType; +} + +HWP_STRING CCtrlField::GetCommand() const +{ + return m_sCommand; +} + +} diff --git a/HwpFile/HwpDoc/Paragraph/CtrlField.h b/HwpFile/HwpDoc/Paragraph/CtrlField.h new file mode 100644 index 00000000000..f84944566ea --- /dev/null +++ b/HwpFile/HwpDoc/Paragraph/CtrlField.h @@ -0,0 +1,51 @@ +#ifndef CTRLFIELD_H +#define CTRLFIELD_H + +#include "Ctrl.h" +#include "../HWPStream.h" + +namespace HWP +{ +enum class EFieldType +{ + Hyperlink, + HyperlinkClosing, + Bookmark, + BookmarkClosing, + + Unknown +}; + +class CCtrlField : public CCtrl +{ + int m_nProperty; + HWP_BYTE m_chEtcProperty; + HWP_STRING m_sCommand; + int m_nInstanceID; + + EFieldType m_eType; + + std::map m_mStringParams; + std::map m_mIntegerParam; + + void UpdateType(const HWP_STRING& sCtrlID); +public: + CCtrlField(const HWP_STRING& sCtrlID); + CCtrlField(const HWP_STRING& sCtrlID, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); + CCtrlField(const HWP_STRING& sCtrlID, CXMLNode& oNode, int nVersion); + + ECtrlObjectType GetCtrlType() const override; + + void AddStringParam(const HWP_STRING& wsName, const HWP_STRING& wsValue); + void AddIntegerParam(const HWP_STRING& wsName, int nValue); + + HWP_STRING GetStringParam(const HWP_STRING& wsName) const; + int GetIntegerParam(const HWP_STRING& wsName) const; + + int GetInstanceID() const; + EFieldType GetType() const; + HWP_STRING GetCommand() const; +}; +} + +#endif // CTRLFIELD_H diff --git a/HwpFile/HwpDoc/Paragraph/CtrlForm.cpp b/HwpFile/HwpDoc/Paragraph/CtrlForm.cpp new file mode 100644 index 00000000000..04ea80c6077 --- /dev/null +++ b/HwpFile/HwpDoc/Paragraph/CtrlForm.cpp @@ -0,0 +1,13 @@ +#include "CtrlForm.h" + +namespace HWP +{ +CCtrlForm::CCtrlForm(const HWP_STRING& sCtrlID, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) + : CCtrl(sCtrlID) +{} + +ECtrlObjectType CCtrlForm::GetCtrlType() const +{ + return ECtrlObjectType::Form; +} +} diff --git a/HwpFile/HwpDoc/Paragraph/CtrlForm.h b/HwpFile/HwpDoc/Paragraph/CtrlForm.h new file mode 100644 index 00000000000..acccbe4b936 --- /dev/null +++ b/HwpFile/HwpDoc/Paragraph/CtrlForm.h @@ -0,0 +1,18 @@ +#ifndef CTRLFORM_H +#define CTRLFORM_H + +#include "Ctrl.h" +#include "../HWPStream.h" + +namespace HWP +{ +class CCtrlForm : public CCtrl +{ +public: + CCtrlForm(const HWP_STRING& sCtrlID, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); + + ECtrlObjectType GetCtrlType() const override; +}; +} + +#endif // CTRLFORM_H diff --git a/HwpFile/HwpDoc/Paragraph/CtrlGeneralShape.cpp b/HwpFile/HwpDoc/Paragraph/CtrlGeneralShape.cpp new file mode 100644 index 00000000000..8a3160f0348 --- /dev/null +++ b/HwpFile/HwpDoc/Paragraph/CtrlGeneralShape.cpp @@ -0,0 +1,382 @@ +#include "CtrlGeneralShape.h" + +#include "CtrlShapePic.h" +#include "CtrlShapeRect.h" +#include "CtrlShapeLine.h" +#include "CtrlContainer.h" +#include "CtrlShapeEllipse.h" +#include "CtrlShapePolygon.h" +#include "CtrlShapeArc.h" +#include "CtrlShapeCurve.h" +#include "CtrlEqEdit.h" +#include "CtrlShapeOle.h" +#include "CtrlShapeVideo.h" +#include "CtrlShapeTextArt.h" +#include "CtrlCharacter.h" + +namespace HWP +{ +CCtrlGeneralShape::CCtrlGeneralShape() +{ + InitData(); +} + +CCtrlGeneralShape::CCtrlGeneralShape(const HWP_STRING& sCtrlID) + : CCtrlObjElement(sCtrlID) +{ + InitData(); +} + +CCtrlGeneralShape::CCtrlGeneralShape(const CCtrlGeneralShape& oGeneralShape) + : CCtrlObjElement(oGeneralShape) +{ + InitData(); + + m_pParent = oGeneralShape.m_pParent; + + m_nLineColor = oGeneralShape.m_nLineColor; + m_nLineThick = oGeneralShape.m_nLineThick; + m_eLineHead = oGeneralShape.m_eLineHead; + m_eLineTail = oGeneralShape.m_eLineTail; + m_eLineHeadSz = oGeneralShape.m_eLineHeadSz; + m_eLineTailSz = oGeneralShape.m_eLineTailSz; + m_eLineStyle = oGeneralShape.m_eLineStyle; + m_chOutline = oGeneralShape.m_chOutline; + + m_nFillType = oGeneralShape.m_nFillType; + m_pFill = oGeneralShape.m_pFill; + + if (nullptr != m_pFill) + m_pFill->AddRef(); + + m_shLeftSpace = oGeneralShape.m_shLeftSpace; + m_shRightSpace = oGeneralShape.m_shRightSpace; + m_shTopSpace = oGeneralShape.m_shTopSpace; + m_shBottomSpace = oGeneralShape.m_shBottomSpace; + m_nMaxTxtWidth = oGeneralShape.m_nMaxTxtWidth; +} + +CCtrlGeneralShape::CCtrlGeneralShape(const HWP_STRING& sCtrlID, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) + : CCtrlObjElement(sCtrlID, nSize, oBuffer, nOff, nVersion) +{ + InitData(); +} + +CCtrlGeneralShape::CCtrlGeneralShape(const HWP_STRING& sCtrlID, CXMLNode& oNode, int nVersion) + : CCtrlObjElement(sCtrlID, oNode, nVersion) +{ + InitData(); + + for (CXMLNode& oChild : oNode.GetChilds()) + { + if (L"hp:lineShape" == oChild.GetName()) + { + m_nLineColor = oChild.GetAttributeColor(L"color"); + m_nLineThick = std::abs(oChild.GetAttributeInt(L"width")); + m_eLineStyle = GetLineStyle2(oChild.GetAttribute(L"style")); + + HWP_STRING sType = oChild.GetAttribute(L"headStyle"); + + if (L"ARROW" == sType) + m_eLineHead = ELineArrowStyle::ARROW; + else if (L"SPEAR" == sType) + m_eLineHead = ELineArrowStyle::SPEAR; + else if (L"CONCAVE_ARROW" == sType) + m_eLineHead = ELineArrowStyle::CONCAVE_ARROW; + else if (L"EMPTY_DIAMOND" == sType) + m_eLineHead = (oChild.GetAttributeBool(L"headfill")) ? ELineArrowStyle::DIAMOND : ELineArrowStyle::EMPTY_DIAMOND; + else if (L"EMPTY_CIRCLE" == sType) + m_eLineHead = (oChild.GetAttributeBool(L"headfill")) ? ELineArrowStyle::CIRCLE : ELineArrowStyle::EMPTY_CIRCLE; + else if (L"EMPTY_BOX" == sType) + m_eLineHead = (oChild.GetAttributeBool(L"headfill")) ? ELineArrowStyle::BOX : ELineArrowStyle::EMPTY_BOX; + else + m_eLineHead = ELineArrowStyle::NORMAL; + + sType = oChild.GetAttribute(L"headSz"); + + if (L"SMALL_SMALL" == sType) + m_eLineHeadSz = ELineArrowSize::SMALL_SMALL; + else if (L"SMALL_MEDIUM" == sType) + m_eLineHeadSz = ELineArrowSize::SMALL_MEDIUM; + else if (L"SMALL_LARGE" == sType) + m_eLineHeadSz = ELineArrowSize::SMALL_LARGE; + else if (L"MEDIUM_SMALL" == sType) + m_eLineHeadSz = ELineArrowSize::MEDIUM_SMALL; + else if (L"MEDIUM_MEDIUM" == sType) + m_eLineHeadSz = ELineArrowSize::MEDIUM_MEDIUM; + else if (L"MEDIUM_LARGE" == sType) + m_eLineHeadSz = ELineArrowSize::MEDIUM_LARGE; + else if (L"LARGE_SMALL" == sType) + m_eLineHeadSz = ELineArrowSize::LARGE_SMALL; + else if (L"LARGE_MEDIUM" == sType) + m_eLineHeadSz = ELineArrowSize::LARGE_MEDIUM; + else if (L"LARGE_LARGE" == sType) + m_eLineHeadSz = ELineArrowSize::LARGE_LARGE; + else + m_eLineHeadSz = ELineArrowSize::MEDIUM_MEDIUM; + + sType = oChild.GetAttribute(L"tailStyle"); + + if (L"ARROW" == sType) + m_eLineTail = ELineArrowStyle::ARROW; + else if (L"SPEAR" == sType) + m_eLineTail = ELineArrowStyle::SPEAR; + else if (L"CONCAVE_ARROW" == sType) + m_eLineTail = ELineArrowStyle::CONCAVE_ARROW; + else if (L"EMPTY_DIAMOND" == sType) + m_eLineTail = (oChild.GetAttributeBool(L"tailfill")) ? ELineArrowStyle::DIAMOND : ELineArrowStyle::EMPTY_DIAMOND; + else if (L"EMPTY_CIRCLE" == sType) + m_eLineTail = (oChild.GetAttributeBool(L"tailfill")) ? ELineArrowStyle::CIRCLE : ELineArrowStyle::EMPTY_CIRCLE; + else if (L"EMPTY_BOX" == sType) + m_eLineTail = (oChild.GetAttributeBool(L"tailfill")) ? ELineArrowStyle::BOX : ELineArrowStyle::EMPTY_BOX; + else + m_eLineTail = ELineArrowStyle::NORMAL; + + sType = oChild.GetAttribute(L"tailSz"); + + if (L"SMALL_SMALL" == sType) + m_eLineTailSz = ELineArrowSize::SMALL_SMALL; + else if (L"SMALL_MEDIUM" == sType) + m_eLineTailSz = ELineArrowSize::SMALL_MEDIUM; + else if (L"SMALL_LARGE" == sType) + m_eLineTailSz = ELineArrowSize::SMALL_LARGE; + else if (L"MEDIUM_SMALL" == sType) + m_eLineTailSz = ELineArrowSize::MEDIUM_SMALL; + else if (L"MEDIUM_MEDIUM" == sType) + m_eLineTailSz = ELineArrowSize::MEDIUM_MEDIUM; + else if (L"MEDIUM_LARGE" == sType) + m_eLineTailSz = ELineArrowSize::MEDIUM_LARGE; + else if (L"LARGE_SMALL" == sType) + m_eLineTailSz = ELineArrowSize::LARGE_SMALL; + else if (L"LARGE_MEDIUM" == sType) + m_eLineTailSz = ELineArrowSize::LARGE_MEDIUM; + else if (L"LARGE_LARGE" == sType) + m_eLineTailSz = ELineArrowSize::LARGE_LARGE; + else + m_eLineTailSz = ELineArrowSize::MEDIUM_MEDIUM; + } + else if (L"hc:fillBrush" == oChild.GetName()) + m_pFill = new CFill(oChild); + else if (L"hp:drawText" == oChild.GetName()) + { + m_nMaxTxtWidth = oChild.GetAttributeInt(L"lastWidth"); + + for (CXMLNode& oGrandChild : oChild.GetChilds()) + { + if (L"hp:textMargin" == oGrandChild.GetName()) + { + m_shLeftSpace = oGrandChild.GetAttributeInt(L"left"); + m_shRightSpace = oGrandChild.GetAttributeInt(L"right"); + m_shTopSpace = oGrandChild.GetAttributeInt(L"top"); + m_shBottomSpace = oGrandChild.GetAttributeInt(L"bottom"); + } + else if (L"hp:subList" == oGrandChild.GetName()) + { + ReadSubList(oGrandChild, nVersion); + } + } + } + } +} + +CCtrlGeneralShape::~CCtrlGeneralShape() +{ + if (nullptr != m_pFill && 0 == m_pFill->Release()) + m_pFill = nullptr; +} + +ECtrlObjectType CCtrlGeneralShape::GetCtrlType() const +{ + return ECtrlObjectType::Shape; +} + +EShapeType CCtrlGeneralShape::GetShapeType() const +{ + return EShapeType::GeneralShape; +} + +void CCtrlGeneralShape::InitData() +{ + m_eLineStyle = ELineStyle2::NONE; + m_pFill = nullptr; +} + +void CCtrlGeneralShape::ReadSubList(CXMLNode& oNode, int nVersion) +{ + m_eTextVerAlign = GetVertAlign(oNode.ReadAttributeInt(L"vertAlign")); + + std::vector arChilds{oNode.GetChilds()}; + + for (unsigned int unIndex = 0; unIndex < arChilds.size(); ++unIndex) + { + CHWPPargraph* pLatestParagraph = nullptr; + + if (L"hp:p" == arChilds[unIndex].GetName()) + { + CHWPPargraph* pParagraph = new CHWPPargraph(arChilds[unIndex], nVersion); + + if (nullptr == pParagraph) + continue; + + m_arParas.push_back(pParagraph); + pLatestParagraph = pParagraph; + } + + if (nullptr != pLatestParagraph && 0 != pLatestParagraph->GetCountCtrls() && ECtrlObjectType::ParaText == pLatestParagraph->GetCtrls().back()->GetCtrlType() && unIndex < arChilds.size() - 1) + pLatestParagraph->AddCtrl(new CCtrlCharacter(L" _", ECtrlCharType::PARAGRAPH_BREAK)); + } +} + +void CCtrlGeneralShape::SetParent(CHWPPargraph* pParent) +{ + m_pParent = pParent; +} + +CHWPPargraph* CCtrlGeneralShape::GetParent() +{ + return m_pParent; +} + +const CFill* CCtrlGeneralShape::GetFill() const +{ + return m_pFill; +} + +ELineStyle2 CCtrlGeneralShape::GetLineStyle() const +{ + return m_eLineStyle; +} + +int CCtrlGeneralShape::GetLineColor() const +{ + return m_nLineColor; +} + +int CCtrlGeneralShape::GetLineThick() const +{ + return m_nLineThick; +} + +CCtrlGeneralShape* CCtrlGeneralShape::Parse(CCtrlGeneralShape& oObj, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) +{ + oBuffer.SavePosition(); + + HWP_STRING sCtrlId; + oBuffer.ReadString(sCtrlId, 4, EStringCharacter::ASCII); + + CCtrlGeneralShape *pShape = nullptr; + + #define CREATE_AND_PARSE_SHAPE(type)\ + pShape = new type(oObj); \ + \ + if (nullptr != pShape) \ + type::ParseCtrl((type&)(*pShape), nSize - oBuffer.GetDistanceToLastPos(), oBuffer, 0, nVersion); \ + else \ + oBuffer.Skip(nSize - oBuffer.GetDistanceToLastPos()) + + if (L"cip$" == sCtrlId) + { + CREATE_AND_PARSE_SHAPE(CCtrlShapePic); + } + else if (L"cer$" == sCtrlId) + { + CREATE_AND_PARSE_SHAPE(CCtrlShapeRect); + } + else if (L"nil$" == sCtrlId || + L"loc$" == sCtrlId) + { + CREATE_AND_PARSE_SHAPE(CCtrlShapeLine); + } + else if (L"noc$" == sCtrlId) + { + CREATE_AND_PARSE_SHAPE(CCtrlContainer); + } + else if (L"lle$" == sCtrlId) + { + CREATE_AND_PARSE_SHAPE(CCtrlShapeEllipse); + } + else if (L"lop$" == sCtrlId) + { + CREATE_AND_PARSE_SHAPE(CCtrlShapePolygon); + } + else if (L"cra$" == sCtrlId) + { + CREATE_AND_PARSE_SHAPE(CCtrlShapeArc); + } + else if (L"ruc$" == sCtrlId) + { + CREATE_AND_PARSE_SHAPE(CCtrlShapeCurve); + } + else if (L"deqe" == sCtrlId) + { + CREATE_AND_PARSE_SHAPE(CCtrlEqEdit); + } + else if (L"elo$" == sCtrlId) + { + CREATE_AND_PARSE_SHAPE(CCtrlShapeOle); + } + else if (L"div$" == sCtrlId) + { + CREATE_AND_PARSE_SHAPE(CCtrlShapeVideo); + } + else if (L"tat$" == sCtrlId) + { + CREATE_AND_PARSE_SHAPE(CCtrlShapeTextArt); + } + + if (nullptr != pShape) + pShape->SetID(sCtrlId); + + oBuffer.RemoveLastSavedPos(); + + return pShape; +} + +int CCtrlGeneralShape::ParseListHeaderApend(CCtrlGeneralShape& oObj, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) +{ + oBuffer.SavePosition(); + + if (nSize >= 16) + { + oBuffer.Skip(2); + oBuffer.ReadInt(oObj.m_nCaptionAttr); + oBuffer.ReadInt(oObj.m_nCaptionWidth); + oObj.m_nCaptionSpacing = oBuffer.ReadShort(); + oBuffer.ReadInt(oObj.m_nCaptionMaxW); + } + + if ((nSize - oBuffer.GetDistanceToLastPos()) == 8) + oBuffer.Skip(8); + + oBuffer.Skip(nSize - oBuffer.GetDistanceToLastPos(true)); + return nSize; +} + +int CCtrlGeneralShape::ParseCtrl(CCtrlGeneralShape& oObj, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) +{ + oBuffer.SavePosition(); + + CCtrlObjElement::ParseCtrl(oObj, nSize, oBuffer, nOff, nVersion); + + oBuffer.ReadColor(oObj.m_nLineColor); + oObj.m_nLineThick = oBuffer.ReadShort(); + + oBuffer.Skip(2); + + int nLineAttr; + oBuffer.ReadInt(nLineAttr); + + oObj.m_eLineStyle = GetLineStyle2(nLineAttr & 0x3F); + oObj.m_eLineHead = GetLineArrowStyle(((nLineAttr >> 10) & 0x3F), CHECK_FLAG(nLineAttr >> 30, 0x1)); + oObj.m_eLineHeadSz = GetLineArrowSize((nLineAttr >> 22) & 0x0F); + oObj.m_eLineTail = GetLineArrowStyle(((nLineAttr >> 16) & 0x3F), CHECK_FLAG(nLineAttr >> 31, 0x1)); + oObj.m_eLineTailSz = GetLineArrowSize((nLineAttr >> 26) & 0x0F); + oBuffer.ReadByte(oObj.m_chOutline); + + oObj.m_pFill = new CFill(oBuffer, 0, nSize - oBuffer.GetDistanceToLastPos() - 22); + + oBuffer.Skip(22); + + return oBuffer.GetDistanceToLastPos(true); +} +} diff --git a/HwpFile/HwpDoc/Paragraph/CtrlGeneralShape.h b/HwpFile/HwpDoc/Paragraph/CtrlGeneralShape.h new file mode 100644 index 00000000000..0f6d127da39 --- /dev/null +++ b/HwpFile/HwpDoc/Paragraph/CtrlGeneralShape.h @@ -0,0 +1,83 @@ +#ifndef CTRLGENERALSHAPE_H +#define CTRLGENERALSHAPE_H + +#include "../HWPElements/HWPRecordBorderFill.h" +#include "CtrlObjElement.h" +#include "HWPPargraph.h" + +namespace HWP +{ +enum class EShapeType +{ + GeneralShape, + Arc, + ConnectLine, + Curve, + Ellipse, + Line, + Ole, + Pic, + Polygon, + Rect, + TextArt, + Video, + EqEdit, + Container +}; + +class CCtrlGeneralShape : public CCtrlObjElement +{ + CHWPPargraph* m_pParent; + + int m_nLineColor; + int m_nLineThick; + ELineArrowStyle m_eLineHead; + ELineArrowStyle m_eLineTail; + ELineArrowSize m_eLineHeadSz; + ELineArrowSize m_eLineTailSz; + ELineStyle2 m_eLineStyle; + HWP_BYTE m_chOutline; + + int m_nFillType; + CFill* m_pFill; + + short m_shLeftSpace; + short m_shRightSpace; + short m_shTopSpace; + short m_shBottomSpace; + int m_nMaxTxtWidth; + + void InitData(); + + friend class CCtrlShapeEllipse; + friend class CCtrlShapePolygon; + friend class CCtrlShapeRect; + + void ReadSubList(CXMLNode& oNode, int nVersion); +public: + CCtrlGeneralShape(); + CCtrlGeneralShape(const HWP_STRING& sCtrlID); + CCtrlGeneralShape(const CCtrlGeneralShape& oGeneralShape); + CCtrlGeneralShape(const HWP_STRING& sCtrlID, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); + CCtrlGeneralShape(const HWP_STRING& sCtrlID, CXMLNode& oNode, int nVersion); + virtual ~CCtrlGeneralShape(); + + ECtrlObjectType GetCtrlType() const override; + virtual EShapeType GetShapeType() const; + + void SetParent(CHWPPargraph* pParent); + CHWPPargraph* GetParent(); + + const CFill* GetFill() const; + + ELineStyle2 GetLineStyle() const; + int GetLineColor() const; + int GetLineThick() const; + + static CCtrlGeneralShape* Parse(CCtrlGeneralShape& oObj, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); + static int ParseListHeaderApend(CCtrlGeneralShape& oObj, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); + static int ParseCtrl(CCtrlGeneralShape& oObj, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); +}; +} + +#endif // CTRLGENERALSHAPE_H diff --git a/HwpFile/HwpDoc/Paragraph/CtrlHeadFoot.cpp b/HwpFile/HwpDoc/Paragraph/CtrlHeadFoot.cpp new file mode 100644 index 00000000000..daa01db178c --- /dev/null +++ b/HwpFile/HwpDoc/Paragraph/CtrlHeadFoot.cpp @@ -0,0 +1,90 @@ +#include "CtrlHeadFoot.h" + +namespace HWP +{ +EPageRange GetPageRange(int nValue) +{ + switch(static_cast(nValue)) + { + case EPageRange::BOTH: default: return EPageRange::BOTH; + case EPageRange::EVEN: return EPageRange::EVEN; + case EPageRange::ODD: return EPageRange::ODD; + } +} + +CCtrlHeadFoot::CCtrlHeadFoot(const HWP_STRING& sCtrlID) + : CCtrl(sCtrlID) +{} + +CCtrlHeadFoot::CCtrlHeadFoot(const HWP_STRING& sCtrlID, int nSize, CHWPStream& oBuffer, int nOff, int nVersion, bool bIsHeader) + : CCtrl(sCtrlID), m_bIsHeader(bIsHeader) +{ + oBuffer.ReadInt(m_nAttr); + m_eWhichPage = GetPageRange(m_nAttr & 0x03); + oBuffer.ReadInt(m_nSerialInSec); +} + +CCtrlHeadFoot::CCtrlHeadFoot(const HWP_STRING& sCtrlID, CXMLNode& oNode, int nVersion) + : CCtrl(sCtrlID) +{ + m_bIsHeader = L"daeh" == sCtrlID; + + m_eWhichPage = GetPageRange(oNode.GetAttributeInt(L"applyPageType")); + + for (CXMLNode& oChild : oNode.GetChilds(L"hp:subList")) + { + m_chRefLevelNum = (HWP_BYTE)oChild.GetAttributeInt(L"hasNumRef"); + m_chRefLevelText = (HWP_BYTE)oChild.GetAttributeInt(L"hasTextRef"); + m_nTextHeight = oChild.GetAttributeInt(L"textHeight"); + m_nTextWidth = oChild.GetAttributeInt(L"textWidth"); + + for (CXMLNode& oGrandChild : oChild.GetChilds(L"hp:p")) + m_arParas.push_back(new CHWPPargraph(oGrandChild, nVersion)); + } + + m_bFullFilled = true; +} + +ECtrlObjectType CCtrlHeadFoot::GetCtrlType() const +{ + return ECtrlObjectType::HeadFoot; +} + +bool CCtrlHeadFoot::IsHeader() const +{ + return m_bIsHeader; +} + +void CCtrlHeadFoot::AddParagraph(CHWPPargraph* pParagraph) +{ + m_arParas.push_back(pParagraph); +} + +VECTOR CCtrlHeadFoot::GetParagraphs() const +{ + VECTOR arParagraphs(m_arParas.size()); + + for (unsigned int unIndex = 0; unIndex < m_arParas.size(); ++unIndex) + arParagraphs[unIndex] = dynamic_cast(m_arParas[unIndex]); + + return arParagraphs; +} + +int CCtrlHeadFoot::ParseListHeaderAppend(CCtrlHeadFoot& oObj, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) +{ + oBuffer.SavePosition(); + + oBuffer.Skip(2); + oBuffer.ReadInt(oObj.m_nTextWidth); + oBuffer.ReadInt(oObj.m_nTextHeight); + oBuffer.ReadByte(oObj.m_chRefLevelText); + oBuffer.ReadByte(oObj.m_chRefLevelNum); + + if (nSize - oBuffer.GetDistanceToLastPos()) + oBuffer.Skip(nSize - oBuffer.GetDistanceToLastPos()); + + oObj.m_bFullFilled = true; + + return oBuffer.GetDistanceToLastPos(true); +} +} diff --git a/HwpFile/HwpDoc/Paragraph/CtrlHeadFoot.h b/HwpFile/HwpDoc/Paragraph/CtrlHeadFoot.h new file mode 100644 index 00000000000..bd1d55e0d57 --- /dev/null +++ b/HwpFile/HwpDoc/Paragraph/CtrlHeadFoot.h @@ -0,0 +1,48 @@ +#ifndef CTRLHEADFOOT_H +#define CTRLHEADFOOT_H + +#include "Ctrl.h" +#include "HWPPargraph.h" +#include "../HWPStream.h" +#include + +namespace HWP +{ +enum class EPageRange +{ + BOTH, + EVEN, + ODD +}; + +class CCtrlHeadFoot : public CCtrl +{ + bool m_bIsHeader; + int m_nAttr; + EPageRange m_eWhichPage; + int m_nSerialInSec; + + int m_nTextWidth; + int m_nTextHeight; + HWP_BYTE m_chRefLevelText; + HWP_BYTE m_chRefLevelNum; + + VECTOR m_arParas; +public: + CCtrlHeadFoot(const HWP_STRING& sCtrlID); + CCtrlHeadFoot(const HWP_STRING& sCtrlID, int nSize, CHWPStream& oBuffer, int nOff, int nVersion, bool bIsHeader); + CCtrlHeadFoot(const HWP_STRING& sCtrlID, CXMLNode& oNode, int nVersion); + + ECtrlObjectType GetCtrlType() const override; + + bool IsHeader() const; + + void AddParagraph(CHWPPargraph* pParagraph); + + VECTOR GetParagraphs() const; + + static int ParseListHeaderAppend(CCtrlHeadFoot& oObj, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); +}; +} + +#endif // CTRLHEADFOOT_H diff --git a/HwpFile/HwpDoc/Paragraph/CtrlNewNumber.cpp b/HwpFile/HwpDoc/Paragraph/CtrlNewNumber.cpp new file mode 100644 index 00000000000..f0052b7a83c --- /dev/null +++ b/HwpFile/HwpDoc/Paragraph/CtrlNewNumber.cpp @@ -0,0 +1,38 @@ +#include "CtrlNewNumber.h" + +namespace HWP +{ +CCtrlNewNumber::CCtrlNewNumber(const HWP_STRING& sCtrlID) + : CCtrl(sCtrlID) +{} + +CCtrlNewNumber::CCtrlNewNumber(const HWP_STRING& sCtrlID, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) + : CCtrl(sCtrlID) +{ + int nAttr; + oBuffer.ReadInt(nAttr); + + m_eNumType = GetNumType(nAttr & 0xF); + m_eNumShape = GetNumberShape2((nAttr >> 4) & 0xF); + + oBuffer.ReadShort(m_shNum); + + m_bFullFilled = true; +} + +CCtrlNewNumber::CCtrlNewNumber(const HWP_STRING& sCtrlID, CXMLNode& oNode, int nVersion) + : CCtrl(sCtrlID) +{ + m_shNum = oNode.GetAttributeInt(L"num"); + m_eNumType = GetNumType(oNode.GetAttributeInt(L"numType")); + //TODO:: проверить данный момент + m_eNumShape = GetNumberShape2(oNode.GetAttributeInt(L"autoNumFormat")); + + m_bFullFilled = true; +} + +ECtrlObjectType CCtrlNewNumber::GetCtrlType() const +{ + return ECtrlObjectType::NewNumber; +} +} diff --git a/HwpFile/HwpDoc/Paragraph/CtrlNewNumber.h b/HwpFile/HwpDoc/Paragraph/CtrlNewNumber.h new file mode 100644 index 00000000000..a2d82efdee9 --- /dev/null +++ b/HwpFile/HwpDoc/Paragraph/CtrlNewNumber.h @@ -0,0 +1,22 @@ +#ifndef CTRLNEWNUMBER_H +#define CTRLNEWNUMBER_H + +#include "CtrlAutoNumber.h" + +namespace HWP +{ +class CCtrlNewNumber : public CCtrl +{ + ENumType m_eNumType; + ENumberShape2 m_eNumShape; + short m_shNum; +public: + CCtrlNewNumber(const HWP_STRING& sCtrlID); + CCtrlNewNumber(const HWP_STRING& sCtrlID, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); + CCtrlNewNumber(const HWP_STRING& sCtrlID, CXMLNode& oNode, int nVersion); + + ECtrlObjectType GetCtrlType() const override; +}; +} + +#endif // CTRLNEWNUMBER_H diff --git a/HwpFile/HwpDoc/Paragraph/CtrlNote.cpp b/HwpFile/HwpDoc/Paragraph/CtrlNote.cpp new file mode 100644 index 00000000000..da96c5ad668 --- /dev/null +++ b/HwpFile/HwpDoc/Paragraph/CtrlNote.cpp @@ -0,0 +1,50 @@ +#include "CtrlNote.h" + +namespace HWP +{ +CCtrlNote::CCtrlNote() +{} + +CCtrlNote::CCtrlNote(const HWP_STRING& sCtrlID) + : CCtrl(sCtrlID) +{} + +CCtrlNote::CCtrlNote(const HWP_STRING& sCtrlID, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) + : CCtrl(sCtrlID) +{ + oBuffer.Skip(8); + m_bFullFilled = true; +} + +CCtrlNote::CCtrlNote(const HWP_STRING& sCtrlID, CXMLNode& oNode, int nVersion) + : CCtrl(sCtrlID) +{ + for (CXMLNode& oChild : oNode.GetChilds(L"hp:subList")) + { + for (CXMLNode& oGrandChild : oChild.GetChilds(L"hp:p")) + m_arParas.push_back(new CHWPPargraph(oGrandChild, nVersion)); + } + + m_bFullFilled = true; +} + +ECtrlObjectType CCtrlNote::GetCtrlType() const +{ + return ECtrlObjectType::Note; +} + +std::vector CCtrlNote::GetParagraphs() const +{ + std::vector arParagraphs(m_arParas.size()); + + for (unsigned int unIndex = 0; unIndex < m_arParas.size(); ++unIndex) + arParagraphs[unIndex] = dynamic_cast(m_arParas[unIndex]); + + return arParagraphs; +} + +void CCtrlNote::AddParagraph(CHWPPargraph* pParagraph) +{ + m_arParas.push_back(pParagraph); +} +} diff --git a/HwpFile/HwpDoc/Paragraph/CtrlNote.h b/HwpFile/HwpDoc/Paragraph/CtrlNote.h new file mode 100644 index 00000000000..679db83307c --- /dev/null +++ b/HwpFile/HwpDoc/Paragraph/CtrlNote.h @@ -0,0 +1,27 @@ +#ifndef CTRLNOTE_H +#define CTRLNOTE_H + +#include "HWPPargraph.h" +#include "Ctrl.h" +#include + +namespace HWP +{ +class CCtrlNote : public CCtrl +{ + VECTOR m_arParas; +public: + CCtrlNote(); + CCtrlNote(const HWP_STRING& sCtrlID); + CCtrlNote(const HWP_STRING& sCtrlID, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); + CCtrlNote(const HWP_STRING& sCtrlID, CXMLNode& oNode, int nVersion); + + ECtrlObjectType GetCtrlType() const override; + + VECTOR GetParagraphs() const; + + void AddParagraph(CHWPPargraph* pParagraph); +}; +} + +#endif // CTRLNOTE_H diff --git a/HwpFile/HwpDoc/Paragraph/CtrlObjElement.cpp b/HwpFile/HwpDoc/Paragraph/CtrlObjElement.cpp new file mode 100644 index 00000000000..8e8700aee7a --- /dev/null +++ b/HwpFile/HwpDoc/Paragraph/CtrlObjElement.cpp @@ -0,0 +1,192 @@ +#include "CtrlObjElement.h" + +namespace HWP +{ +CCtrlObjElement::CCtrlObjElement() +{ + InitMatrix(); +} + +CCtrlObjElement::CCtrlObjElement(const HWP_STRING& sCtrlID) + : CCtrlCommon(sCtrlID) +{ + InitMatrix(); +} + +CCtrlObjElement::CCtrlObjElement(const CCtrlObjElement& oObjElement) + : CCtrlCommon(oObjElement) +{ + m_nXGrpOffset = oObjElement.m_nXGrpOffset; + m_nYGrpOffset = oObjElement.m_nYGrpOffset; + m_shNGrp = oObjElement.m_shNGrp; + m_shVer = oObjElement.m_shVer; + m_nIniWidth = oObjElement.m_nIniWidth; + m_nIniHeight = oObjElement.m_nIniHeight; + m_nCurWidth = oObjElement.m_nCurWidth; + m_nCurHeight = oObjElement.m_nCurHeight; + m_bHorzFlip = oObjElement.m_bHorzFlip; + m_bVerFlip = oObjElement.m_bVerFlip; + m_shRotat = oObjElement.m_shRotat; + m_nXCenter = oObjElement.m_nXCenter; + m_nYCenter = oObjElement.m_nYCenter; + m_shMatCnt = oObjElement.m_shMatCnt; + + m_arMatrix.resize(6); + for (unsigned int unIndex = 0; unIndex < 6; ++unIndex) + m_arMatrix[unIndex] = oObjElement.m_arMatrix[unIndex]; + + m_arMatrixSeq.resize(oObjElement.m_arMatrixSeq.size()); + for (unsigned int unIndex = 0; unIndex < oObjElement.m_arMatrixSeq.size(); ++unIndex) + m_arMatrixSeq[unIndex] = oObjElement.m_arMatrixSeq[unIndex]; +} + +CCtrlObjElement::CCtrlObjElement(const HWP_STRING& sCtrlID, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) + : CCtrlCommon(sCtrlID, nSize, oBuffer, nOff, nVersion) +{ + InitMatrix(); +} + +CCtrlObjElement::CCtrlObjElement(const HWP_STRING& sCtrlID, CXMLNode& oNode, int nVersion) + : CCtrlCommon(sCtrlID, oNode, nVersion) +{ + InitMatrix(); + + m_shNGrp = oNode.GetAttributeInt(L"groupLevel"); + + m_arMatrixSeq.resize((m_shNGrp + 1) * 6 * 2); + + short shScaMatCnt = 0, shRotMatCnt = 0; + + for (CXMLNode& oChild : oNode.GetChilds()) + { + if (L"hp:offset" == oChild.GetName()) + { + m_nXGrpOffset = oChild.GetAttributeInt(L"x"); + m_nYGrpOffset = oChild.GetAttributeInt(L"y"); + } + else if (L"hp:orgSz" == oChild.GetName()) + { + m_nIniWidth = oChild.GetAttributeInt(L"width"); + m_nIniHeight = oChild.GetAttributeInt(L"height"); + } + else if (L"hp:curSz" == oChild.GetName()) + { + m_nCurWidth = oChild.GetAttributeInt(L"width"); + m_nCurHeight = oChild.GetAttributeInt(L"height"); + } + else if (L"hp:flip" == oChild.GetName()) + { + m_bHorzFlip = oChild.GetAttributeBool(L"horizontal"); + m_bVerFlip = oChild.GetAttributeBool(L"vertical"); + } + else if (L"hp:rotationInfo" == oChild.GetName()) + { + m_shRotat = oChild.GetAttributeInt(L"angle"); + m_nXCenter = oChild.GetAttributeInt(L"centerX"); + m_nYCenter = oChild.GetAttributeInt(L"centerY"); + } + else if (L"hp:renderingInfo" == oChild.GetName()) + { + for (CXMLNode& oGrandChild : oChild.GetChilds()) + { + if (L"hc:transMatrix" == oGrandChild.GetName()) + SetMatrix(oGrandChild, m_arMatrix, 0); + else if (L"hc:scaMatrix" == oGrandChild.GetName()) + { + SetMatrix(oGrandChild, m_arMatrixSeq, shScaMatCnt * 12); + ++shScaMatCnt; + } + else if (L"hc:rotMatrix" == oGrandChild.GetName()) + { + SetMatrix(oGrandChild, m_arMatrixSeq, shRotMatCnt * 12 + 6); + ++shRotMatCnt; + } + } + } + } +} + +int CCtrlObjElement::GetCurWidth() const +{ + return m_nCurWidth; +} + +int CCtrlObjElement::GetCurHeight() const +{ + return m_nCurHeight; +} + +int CCtrlObjElement::GetFinalWidth() const +{ + if (0 != m_nCurWidth) + return m_nCurWidth; + + return CCtrlCommon::GetWidth(); +} + +int CCtrlObjElement::GetFinalHeight() const +{ + if (0 != m_nCurHeight) + return m_nCurHeight; + + return CCtrlCommon::GetHeight(); +} + +int CCtrlObjElement::ParseCtrl(CCtrlObjElement& oObj, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) +{ + oBuffer.SavePosition(); + + CCtrlCommon::ParseCtrl(oObj, nSize, oBuffer, nOff, nVersion); + + oBuffer.ReadInt(oObj.m_nXGrpOffset); + oBuffer.ReadInt(oObj.m_nYGrpOffset); + oBuffer.ReadShort(oObj.m_shNGrp); + oBuffer.ReadShort(oObj.m_shVer); + oBuffer.ReadInt(oObj.m_nIniWidth); + oBuffer.ReadInt(oObj.m_nIniHeight); + oBuffer.ReadInt(oObj.m_nCurWidth); + oBuffer.ReadInt(oObj.m_nCurHeight); + oObj.m_bHorzFlip = CHECK_FLAG(oBuffer[0], 0x01); + oObj.m_bVerFlip = CHECK_FLAG(oBuffer[0], 0x02); + oBuffer.Skip(4); + oBuffer.ReadShort(oObj.m_shRotat); + oBuffer.ReadInt(oObj.m_nXCenter); + oBuffer.ReadInt(oObj.m_nYCenter); + oBuffer.ReadShort(oObj.m_shMatCnt); + + for (int nIndex = 0; nIndex < 6; ++nIndex) + oBuffer.ReadDouble(oObj.m_arMatrix[nIndex]); + + int nMatrixSize = ((int)oObj.m_shMatCnt) * 6 * 2; + if (nMatrixSize > 0) + { + oObj.m_arMatrixSeq.resize(nMatrixSize); + + for (int nIndex = 0; nIndex < nMatrixSize; ++nIndex) + oBuffer.ReadDouble(oObj.m_arMatrixSeq[nIndex]); + } + + return oBuffer.GetDistanceToLastPos(true); +} + +void CCtrlObjElement::InitMatrix() +{ + m_arMatrix.resize(6); + m_arMatrix[0] = 1.; + m_arMatrix[1] = 0.; + m_arMatrix[2] = 0.; + m_arMatrix[3] = 1.; + m_arMatrix[4] = 0.; + m_arMatrix[5] = 0.; +} + +void CCtrlObjElement::SetMatrix(CXMLNode& oNode, std::vector& arMatrix, int nOffset) +{ + arMatrix[0 + nOffset] = oNode.GetAttributeDouble(L"e1"); + arMatrix[1 + nOffset] = oNode.GetAttributeDouble(L"e2"); + arMatrix[2 + nOffset] = oNode.GetAttributeDouble(L"e3"); + arMatrix[3 + nOffset] = oNode.GetAttributeDouble(L"e4"); + arMatrix[4 + nOffset] = oNode.GetAttributeDouble(L"e5"); + arMatrix[5 + nOffset] = oNode.GetAttributeDouble(L"e6"); +} +} diff --git a/HwpFile/HwpDoc/Paragraph/CtrlObjElement.h b/HwpFile/HwpDoc/Paragraph/CtrlObjElement.h new file mode 100644 index 00000000000..b2583130c9c --- /dev/null +++ b/HwpFile/HwpDoc/Paragraph/CtrlObjElement.h @@ -0,0 +1,47 @@ +#ifndef CTRLOBJELEMENT_H +#define CTRLOBJELEMENT_H + +#include "CtrlCommon.h" + +namespace HWP +{ +class CCtrlObjElement : public CCtrlCommon +{ + int m_nXGrpOffset; + int m_nYGrpOffset; + short m_shNGrp; + short m_shVer; + int m_nIniWidth; + int m_nIniHeight; + int m_nCurWidth; + int m_nCurHeight; + bool m_bHorzFlip; + bool m_bVerFlip; + short m_shRotat; + int m_nXCenter; + int m_nYCenter; + short m_shMatCnt; + VECTOR m_arMatrix; + VECTOR m_arMatrixSeq; + + void InitMatrix(); + + void SetMatrix(CXMLNode& oNode, VECTOR& arMatrix, int nOffset); +public: + CCtrlObjElement(); + CCtrlObjElement(const HWP_STRING& sCtrlID); + CCtrlObjElement(const CCtrlObjElement& oObjElement); + CCtrlObjElement(const HWP_STRING& sCtrlID, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); + CCtrlObjElement(const HWP_STRING& sCtrlID, CXMLNode& oNode, int nVersion); + + int GetCurWidth() const; + int GetCurHeight() const; + + int GetFinalWidth() const; + int GetFinalHeight() const; + + static int ParseCtrl(CCtrlObjElement& oObj, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); +}; +} + +#endif // CTRLOBJELEMENT_H diff --git a/HwpFile/HwpDoc/Paragraph/CtrlPageNumPos.cpp b/HwpFile/HwpDoc/Paragraph/CtrlPageNumPos.cpp new file mode 100644 index 00000000000..5297386323d --- /dev/null +++ b/HwpFile/HwpDoc/Paragraph/CtrlPageNumPos.cpp @@ -0,0 +1,56 @@ +#include "CtrlPageNumPos.h" + +namespace HWP +{ +ENumPos GetNumPos(int nValue) +{ + switch(static_cast(nValue)) + { + case ENumPos::LEFT_TOP: + case ENumPos::CENTER_TOP: + case ENumPos::RIGHT_TOP: + case ENumPos::LEFT_BOTTOM: + case ENumPos::BOTTOM_CENTER: + case ENumPos::RIGHT_BOTTOM: + case ENumPos::OUTER_TOP: + case ENumPos::OUTER_BOTTOM: + case ENumPos::INNER_TOP: + case ENumPos::INNER_BOTTOM: + return static_cast(nValue); + case ENumPos::NONE: + default: + return ENumPos::NONE; + } +} + +CCtrlPageNumPos::CCtrlPageNumPos(const HWP_STRING& sCtrlID) + : CCtrl(sCtrlID) +{} + +CCtrlPageNumPos::CCtrlPageNumPos(const HWP_STRING& sCtrlID, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) + : CCtrl(sCtrlID) +{ + int nAttr; + oBuffer.ReadInt(nAttr); + m_eNumShape = GetNumberShape2(nAttr & 0xFF); + m_ePos = GetNumPos((nAttr >> 8) & 0xF); + + oBuffer.Skip(2); + oBuffer.ReadString(m_sUserDef, 2, EStringCharacter::UTF16); + oBuffer.ReadString(m_sPrefix, 2, EStringCharacter::UTF16); + oBuffer.ReadString(m_sPostfix, 2, EStringCharacter::UTF16); + oBuffer.ReadString(m_sConstantDash, 2, EStringCharacter::UTF16); +} + +CCtrlPageNumPos::CCtrlPageNumPos(const HWP_STRING& sCtrlID, CXMLNode& oNode, int nVersion) + : CCtrl(sCtrlID) +{ + m_ePos = GetNumPos(oNode.GetAttributeInt(L"pos")); + m_eNumShape = GetNumberShape2(oNode.GetAttributeInt(L"formatType")); +} + +ECtrlObjectType CCtrlPageNumPos::GetCtrlType() const +{ + return ECtrlObjectType::PageNumPos; +} +} diff --git a/HwpFile/HwpDoc/Paragraph/CtrlPageNumPos.h b/HwpFile/HwpDoc/Paragraph/CtrlPageNumPos.h new file mode 100644 index 00000000000..8306cfa0cc0 --- /dev/null +++ b/HwpFile/HwpDoc/Paragraph/CtrlPageNumPos.h @@ -0,0 +1,43 @@ +#ifndef CTRLPAGENUMPOS_H +#define CTRLPAGENUMPOS_H + +#include "Ctrl.h" +#include "../HWPStream.h" +#include "../HWPElements/HwpRecordTypes.h" +#include "../Common/XMLNode.h" + +namespace HWP +{ +enum class ENumPos +{ + NONE, + LEFT_TOP, + CENTER_TOP, + RIGHT_TOP, + LEFT_BOTTOM, + BOTTOM_CENTER, + RIGHT_BOTTOM, + OUTER_TOP, + OUTER_BOTTOM, + INNER_TOP, + INNER_BOTTOM +}; + +class CCtrlPageNumPos : public CCtrl +{ + ENumPos m_ePos; + ENumberShape2 m_eNumShape; + HWP_STRING m_sUserDef; + HWP_STRING m_sPrefix; + HWP_STRING m_sPostfix; + HWP_STRING m_sConstantDash; +public: + CCtrlPageNumPos(const HWP_STRING& sCtrlID); + CCtrlPageNumPos(const HWP_STRING& sCtrlID, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); + CCtrlPageNumPos(const HWP_STRING& sCtrlID, CXMLNode& oNode, int nVersion); + + ECtrlObjectType GetCtrlType() const override; +}; +} + +#endif // CTRLPAGENUMPOS_H diff --git a/HwpFile/HwpDoc/Paragraph/CtrlSectionDef.cpp b/HwpFile/HwpDoc/Paragraph/CtrlSectionDef.cpp new file mode 100644 index 00000000000..bf36ad142e7 --- /dev/null +++ b/HwpFile/HwpDoc/Paragraph/CtrlSectionDef.cpp @@ -0,0 +1,191 @@ +#include "CtrlSectionDef.h" + +namespace HWP +{ +CCtrlSectionDef::CCtrlSectionDef(const HWP_STRING& sCtrlID) + : CCtrl(sCtrlID), m_pPage(nullptr) +{} + +CCtrlSectionDef::CCtrlSectionDef(const HWP_STRING& sCtrlID, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) + : CCtrl(sCtrlID), m_pPage(nullptr) +{ + int nAttr; + oBuffer.ReadInt(nAttr); + + m_bHideHeader = CHECK_FLAG(nAttr, 0x01); + m_bHideFooter = CHECK_FLAG(nAttr, 0x02); + m_bHideMasterPage = CHECK_FLAG(nAttr, 0x04); + m_bHideBorder = CHECK_FLAG(nAttr, 0x08); + m_bHideFill = CHECK_FLAG(nAttr, 0x10); + m_bHidePageNumPos = CHECK_FLAG(nAttr, 0x20); + m_bShowFirstBorder = CHECK_FLAG(nAttr, 0x100); + m_bShowFirstFill = CHECK_FLAG(nAttr, 0x200); + m_chTextDirection = (HWP_BYTE)((nAttr >> 16) & 0x07); + m_bHideEmptyLine = CHECK_FLAG(nAttr, 0x20000); + m_chPageStartOn = (HWP_BYTE)((nAttr >> 20) & 0x03); + + oBuffer.ReadShort(m_shSpaceColumns); + oBuffer.ReadShort(m_shLineGrid); + oBuffer.ReadShort(m_shCharGrid); + oBuffer.ReadInt(m_nTabStop); + m_nOutlineNumberingID = oBuffer.ReadShort(); + oBuffer.ReadShort(m_shPageNum); + oBuffer.ReadShort(m_shFigure); + oBuffer.ReadShort(m_shTable); + oBuffer.ReadShort(m_shEquation); + + if (nVersion >= 5015) + oBuffer.ReadShort(m_shLang); + + m_bFullFilled = true; +} + +CCtrlSectionDef::CCtrlSectionDef(const HWP_STRING& sCtrlID, CXMLNode& oNode, int nVersion) + : CCtrl(sCtrlID), m_pPage(nullptr) +{ + HWP_STRING sType = oNode.GetAttribute(L"textDirection"); + + if (L"HORIZONTAL" == sType) + m_chTextDirection = 0; + else if (L"VERTICAL" == sType) + m_chTextDirection = 1; + + m_shSpaceColumns = oNode.GetAttributeInt(L"spaceColumns"); + m_nTabStop = oNode.GetAttributeInt(L"tabStop"); + m_nOutlineNumberingID = oNode.GetAttributeInt(L"outlineShapeIDRef"); + + for (CXMLNode& oChild : oNode.GetChilds()) + { + if (L"hp:startNum" == oChild.GetName()) + { + sType = oChild.GetAttribute(L"pageStartsOn"); + + if (L"BOTH" == sType) + m_chPageStartOn = 0; + else if (L"EVEN" == sType) + m_chPageStartOn = 1; + else if (L"ODD" == sType) + m_chPageStartOn = 2; + + m_shPageNum = oChild.GetAttributeInt(L"page"); + m_shFigure = oChild.GetAttributeInt(L"pic"); + m_shTable = oChild.GetAttributeInt(L"tbl"); + m_shEquation = oChild.GetAttributeInt(L"equation"); + } + else if (L"hp:grid" == oChild.GetName()) + { + m_shLineGrid = oChild.GetAttributeInt(L"lineGrid"); + m_shCharGrid = oChild.GetAttributeInt(L"charGrid"); + } + else if (L"hp:visibility" == oChild.GetName()) + { + m_bHideHeader = oChild.GetAttributeBool(L"hideFirstHeader"); + m_bHideFooter = oChild.GetAttributeBool(L"hideFirstFooter"); + m_bHideMasterPage = oChild.GetAttributeBool(L"hideFirstMasterPage"); + + sType = oChild.GetAttribute(L"border"); + + if (L"HIDE_FIRST" == sType) + { + m_bHideBorder = true; + m_bShowFirstBorder = false; + } + else if (L"SHOW_FIRST" == sType) + { + m_bHideBorder = true; + m_bShowFirstBorder = true; + } + else if (L"SHOW_ALL" == sType) + { + m_bHideBorder = false; + m_bShowFirstBorder = false; + } + + sType = oChild.GetAttribute(L"fill"); + + if (L"HIDE_FIRST" == sType) + { + m_bHideFill = true; + m_bShowFirstFill = false; + } + else if (L"SHOW_FIRST" == sType) + { + m_bHideFill = true; + m_bShowFirstFill = true; + } + else if (L"SHOW_ALL" == sType) + { + m_bHideFill = false; + m_bShowFirstFill = false; + } + + m_bHidePageNumPos = oChild.GetAttributeBool(L"hideFirstPageNum"); + m_bHideEmptyLine = oChild.GetAttributeBool(L"hideFirstEmptyLine"); + } + else if (L"hp:pagePr" == oChild.GetName()) + m_pPage = new CPage(oChild); + else if (L"hp:footNotePr" == oChild.GetName() || + L"hp:endNotePr" == oChild.GetName()) + m_arNoteShapes.push_back(new CNoteShape(oChild, nVersion)); + else if (L"hp:pageBorderFill" == oChild.GetName()) + m_arBorderFills.push_back(new CPageBorderFill(oChild, nVersion)); + else if (L"hp:masterPage" == oChild.GetName()) + { + //TODO:: добавить реализацию + } + } + + m_bFullFilled = true; +} + +CCtrlSectionDef::~CCtrlSectionDef() +{ + if (nullptr != m_pPage) + delete m_pPage; +} + +ECtrlObjectType CCtrlSectionDef::GetCtrlType() const +{ + return ECtrlObjectType::SectionDef; +} + +void CCtrlSectionDef::SetPage(CPage* pPage) +{ + m_pPage = pPage; +} + +void CCtrlSectionDef::AddHeadFoot(CCtrlHeadFoot* pHeadFoot) +{ + m_arHeaderFooter.push_back(pHeadFoot); +} + +void CCtrlSectionDef::AddParagraph(CHWPPargraph* pParagraph) +{ + m_arParas.push_back(pParagraph); +} + +void CCtrlSectionDef::AddNoteShape(CNoteShape* pNoteShape) +{ + m_arNoteShapes.push_back(pNoteShape); +} + +void CCtrlSectionDef::AddPageBorderFill(CPageBorderFill* pPageBorderFill) +{ + m_arBorderFills.push_back(pPageBorderFill); +} + +const CPage* CCtrlSectionDef::GetPage() const +{ + return m_pPage; +} + +VECTOR CCtrlSectionDef::GetHeaderFooters() const +{ + VECTOR arHeaderFooters(m_arHeaderFooter.size()); + + for (unsigned int unIndex = 0; unIndex < m_arHeaderFooter.size(); ++unIndex) + arHeaderFooters[unIndex] = dynamic_cast(m_arHeaderFooter[unIndex]); + + return arHeaderFooters; +} +} diff --git a/HwpFile/HwpDoc/Paragraph/CtrlSectionDef.h b/HwpFile/HwpDoc/Paragraph/CtrlSectionDef.h new file mode 100644 index 00000000000..a16478934dc --- /dev/null +++ b/HwpFile/HwpDoc/Paragraph/CtrlSectionDef.h @@ -0,0 +1,65 @@ +#ifndef CTRLSECTIONDEF_H +#define CTRLSECTIONDEF_H + +#include "Ctrl.h" +#include "../Section/Page.h" + +#include "CtrlHeadFoot.h" +#include "../Section/NoteShape.h" +#include "../Section/PageBorderFill.h" + +namespace HWP +{ +class CCtrlSectionDef : public CCtrl +{ + bool m_bHideHeader; + bool m_bHideFooter; + bool m_bHideMasterPage; + bool m_bHideBorder; + bool m_bHideFill; + bool m_bHidePageNumPos; + bool m_bShowFirstBorder; + bool m_bShowFirstFill; + HWP_BYTE m_chTextDirection; + bool m_bHideEmptyLine; + HWP_BYTE m_chPageStartOn; + + short m_shSpaceColumns; + short m_shLineGrid; + short m_shCharGrid; + int m_nTabStop; + int m_nOutlineNumberingID; + short m_shPageNum; + short m_shFigure; + short m_shTable; + short m_shEquation; + short m_shLang; + + CPage *m_pPage; + VECTOR m_arHeaderFooter; + VECTOR m_arNoteShapes; + VECTOR m_arBorderFills; + + VECTOR m_arParas; + +public: + CCtrlSectionDef(const HWP_STRING& sCtrlID); + CCtrlSectionDef(const HWP_STRING& sCtrlID, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); + CCtrlSectionDef(const HWP_STRING& sCtrlID, CXMLNode& oNode, int nVersion); + ~CCtrlSectionDef(); + + ECtrlObjectType GetCtrlType() const override; + + void SetPage(CPage* pPage); + + void AddHeadFoot(CCtrlHeadFoot* pHeadFoot); + void AddParagraph(CHWPPargraph* pParagraph); + void AddNoteShape(CNoteShape* pNoteShape); + void AddPageBorderFill(CPageBorderFill* pPageBorderFill); + + const CPage* GetPage() const; + VECTOR GetHeaderFooters() const; +}; +} + +#endif // CTRLSECTIONDEF_H diff --git a/HwpFile/HwpDoc/Paragraph/CtrlShapeArc.cpp b/HwpFile/HwpDoc/Paragraph/CtrlShapeArc.cpp new file mode 100644 index 00000000000..0ee8be0f523 --- /dev/null +++ b/HwpFile/HwpDoc/Paragraph/CtrlShapeArc.cpp @@ -0,0 +1,87 @@ +#include "CtrlShapeArc.h" + +namespace HWP +{ +CCtrlShapeArc::CCtrlShapeArc() +{} + +CCtrlShapeArc::CCtrlShapeArc(const HWP_STRING& sCtrlID) + : CCtrlGeneralShape(sCtrlID) +{} + +CCtrlShapeArc::CCtrlShapeArc(const CCtrlGeneralShape& oShape) + : CCtrlGeneralShape(oShape) +{} + +CCtrlShapeArc::CCtrlShapeArc(const HWP_STRING& sCtrlID, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) + : CCtrlGeneralShape(sCtrlID, nSize, oBuffer, nOff, nVersion) +{} + +CCtrlShapeArc::CCtrlShapeArc(const HWP_STRING& sCtrlID, CXMLNode& oNode, int nVersion) + : CCtrlGeneralShape(sCtrlID, oNode, nVersion) +{ + m_eType = GetArcType(oNode.GetAttributeInt(L"type")); + + for (CXMLNode& oChild : oNode.GetChilds()) + { + if (L"hp:center" == oChild.GetName()) + { + m_nCenterX = oChild.GetAttributeInt(L"x"); + m_nCenterY = oChild.GetAttributeInt(L"y"); + } + else if (L"hp:ax1" == oChild.GetName()) + { + m_nAxixX1 = oChild.GetAttributeInt(L"x"); + m_nAxixY1 = oChild.GetAttributeInt(L"y"); + } + else if (L"hp:ax2" == oChild.GetName()) + { + m_nAxixX2 = oChild.GetAttributeInt(L"x"); + m_nAxixY2 = oChild.GetAttributeInt(L"y"); + } + } +} + +EShapeType CCtrlShapeArc::GetShapeType() const +{ + return EShapeType::Arc; +} + +TPoint CCtrlShapeArc::GetCenterPoint() const +{ + return {m_nCenterX, m_nCenterY}; +} + +TPoint CCtrlShapeArc::GetFirstPoint() const +{ + return {m_nAxixX1, m_nAxixY1}; +} + +TPoint CCtrlShapeArc::GetSecondPoint() const +{ + return {m_nAxixX2, m_nAxixY2}; +} + +int CCtrlShapeArc::ParseElement(CCtrlShapeArc& oObj, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) +{ + oBuffer.SavePosition(); + + oObj.m_eType = GetArcType(oBuffer.ReadByte()); + oBuffer.ReadInt(oObj.m_nCenterX); + oBuffer.ReadInt(oObj.m_nCenterY); + oBuffer.ReadInt(oObj.m_nAxixX1); + oBuffer.ReadInt(oObj.m_nAxixY1); + oBuffer.ReadInt(oObj.m_nAxixX2); + oBuffer.ReadInt(oObj.m_nAxixY2); + + oBuffer.Skip(nSize - oBuffer.GetDistanceToLastPos(true)); + + return nSize; +} + +int CCtrlShapeArc::ParseCtrl(CCtrlShapeArc& oObj, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) +{ + return CCtrlGeneralShape::ParseCtrl(oObj, nSize, oBuffer, nOff, nVersion); +} + +} diff --git a/HwpFile/HwpDoc/Paragraph/CtrlShapeArc.h b/HwpFile/HwpDoc/Paragraph/CtrlShapeArc.h new file mode 100644 index 00000000000..f9e891d5726 --- /dev/null +++ b/HwpFile/HwpDoc/Paragraph/CtrlShapeArc.h @@ -0,0 +1,36 @@ +#ifndef CTRLSHAPEARC_H +#define CTRLSHAPEARC_H + +#include "CtrlShapeEllipse.h" +#include "Point.h" + +namespace HWP +{ +class CCtrlShapeArc : public CCtrlGeneralShape +{ + EArcType m_eType; + int m_nCenterX; + int m_nCenterY; + int m_nAxixX1; + int m_nAxixY1; + int m_nAxixX2; + int m_nAxixY2; +public: + CCtrlShapeArc(); + CCtrlShapeArc(const HWP_STRING& sCtrlID); + CCtrlShapeArc(const CCtrlGeneralShape& oShape); + CCtrlShapeArc(const HWP_STRING& sCtrlID, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); + CCtrlShapeArc(const HWP_STRING& sCtrlID, CXMLNode& oNode, int nVersion); + + EShapeType GetShapeType() const override; + + TPoint GetCenterPoint() const; + TPoint GetFirstPoint() const; + TPoint GetSecondPoint() const; + + static int ParseElement(CCtrlShapeArc& oObj, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); + static int ParseCtrl(CCtrlShapeArc& oObj, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); +}; +} + +#endif // CTRLSHAPEARC_H diff --git a/HwpFile/HwpDoc/Paragraph/CtrlShapeConnectLine.cpp b/HwpFile/HwpDoc/Paragraph/CtrlShapeConnectLine.cpp new file mode 100644 index 00000000000..d3f3fe44f2c --- /dev/null +++ b/HwpFile/HwpDoc/Paragraph/CtrlShapeConnectLine.cpp @@ -0,0 +1,56 @@ +#include "CtrlShapeConnectLine.h" + +namespace HWP +{ +EConnectLineType GetConnectLineType(int nValue) +{ + switch(static_cast(nValue)) + { + case EConnectLineType::STRAIGHT_NOARROW: + case EConnectLineType::STRAIGHT_ONEWAY: + case EConnectLineType::STRAIGHT_BOTH: + case EConnectLineType::STROKE_NOARROW: + case EConnectLineType::STROKE_ONEWAY: + case EConnectLineType::STROKE_BOTH: + case EConnectLineType::ARC_NOARROW: + case EConnectLineType::ARC_ONEWAY: + case EConnectLineType::ARC_BOTH: + return static_cast(nValue); + default: + return EConnectLineType::null; + } +} + +CCtrlShapeConnectLine::CCtrlShapeConnectLine(const HWP_STRING& sCtrlID, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) + : CCtrlGeneralShape(sCtrlID, nSize, oBuffer, nOff, nVersion) +{} + +CCtrlShapeConnectLine::CCtrlShapeConnectLine(const HWP_STRING& sCtrlID, CXMLNode& oNode, int nVersion) + : CCtrlGeneralShape(sCtrlID, oNode, nVersion) +{ + m_eType = GetConnectLineType(oNode.GetAttributeInt(L"type")); + + for (CXMLNode& oChild : oNode.GetChilds()) + { + if (L"hp:startPt" == oChild.GetName()) + { + m_oStartPt.m_nX = oChild.GetAttributeInt(L"x"); + m_oStartPt.m_nY = oChild.GetAttributeInt(L"y"); + m_oStartPt.m_shSubjectIDRef = oChild.GetAttributeInt(L"subjectIDRef"); + m_oStartPt.m_shSubjectIdx = oChild.GetAttributeInt(L"subjectIdx"); + } + else if (L"hp:endPt" == oChild.GetName()) + { + m_oEndPt.m_nX = oChild.GetAttributeInt(L"x"); + m_oEndPt.m_nY = oChild.GetAttributeInt(L"y"); + m_oEndPt.m_shSubjectIDRef = oChild.GetAttributeInt(L"subjectIDRef"); + m_oEndPt.m_shSubjectIdx = oChild.GetAttributeInt(L"subjectIdx"); + } + } +} + +EShapeType CCtrlShapeConnectLine::GetShapeType() const +{ + return EShapeType::ConnectLine; +} +} diff --git a/HwpFile/HwpDoc/Paragraph/CtrlShapeConnectLine.h b/HwpFile/HwpDoc/Paragraph/CtrlShapeConnectLine.h new file mode 100644 index 00000000000..2ac0ee7daf3 --- /dev/null +++ b/HwpFile/HwpDoc/Paragraph/CtrlShapeConnectLine.h @@ -0,0 +1,42 @@ +#ifndef CTRLSHAPECONNECTLINE_H +#define CTRLSHAPECONNECTLINE_H + +#include "CtrlGeneralShape.h" +#include "Point.h" + +namespace HWP +{ +struct TConnectPoint : public TPoint +{ + short m_shSubjectIDRef; + short m_shSubjectIdx; +}; + +enum class EConnectLineType +{ + STRAIGHT_NOARROW, + STRAIGHT_ONEWAY, + STRAIGHT_BOTH, + STROKE_NOARROW, + STROKE_ONEWAY, + STROKE_BOTH, + ARC_NOARROW, + ARC_ONEWAY, + ARC_BOTH, + null +}; + +class CCtrlShapeConnectLine : public CCtrlGeneralShape +{ + EConnectLineType m_eType; + TConnectPoint m_oStartPt; + TConnectPoint m_oEndPt; +public: + CCtrlShapeConnectLine(const HWP_STRING& sCtrlID, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); + CCtrlShapeConnectLine(const HWP_STRING& sCtrlID, CXMLNode& oNode, int nVersion); + + EShapeType GetShapeType() const override; +}; +} + +#endif // CTRLSHAPECONNECTLINE_H diff --git a/HwpFile/HwpDoc/Paragraph/CtrlShapeCurve.cpp b/HwpFile/HwpDoc/Paragraph/CtrlShapeCurve.cpp new file mode 100644 index 00000000000..937b4016f4f --- /dev/null +++ b/HwpFile/HwpDoc/Paragraph/CtrlShapeCurve.cpp @@ -0,0 +1,100 @@ +#include "CtrlShapeCurve.h" + +namespace HWP +{ +CCtrlShapeCurve::CCtrlShapeCurve() +{} + +CCtrlShapeCurve::CCtrlShapeCurve(const HWP_STRING& sCtrlID) + : CCtrlGeneralShape(sCtrlID) +{} + +CCtrlShapeCurve::CCtrlShapeCurve(const CCtrlGeneralShape& oShape) + : CCtrlGeneralShape(oShape) +{} + +CCtrlShapeCurve::CCtrlShapeCurve(const HWP_STRING& sCtrlID, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) + : CCtrlGeneralShape(sCtrlID, nSize, oBuffer, nOff, nVersion) +{} + +CCtrlShapeCurve::CCtrlShapeCurve(const HWP_STRING& sCtrlID, CXMLNode& oNode, int nVersion) + : CCtrlGeneralShape(sCtrlID, oNode, nVersion) +{ + std::vector arChilds{oNode.GetChilds(L"hp:seg")}; + + m_arPoints.resize(arChilds.size() + 1); + m_arSegmentType.resize(arChilds.size()); + + HWP_STRING sType; + + for (unsigned int unIndex = 0; unIndex < arChilds.size(); ++unIndex) + { + sType = arChilds[unIndex].GetAttribute(L"type"); + + if (L"CURVE" == sType) + m_arSegmentType[unIndex] = 1; + else if (L"LINE" == sType) + m_arSegmentType[unIndex] = 0; + + m_arPoints[unIndex].m_nX = arChilds[unIndex].GetAttributeInt(L"x1"); + m_arPoints[unIndex].m_nY = arChilds[unIndex].GetAttributeInt(L"y1"); + + if (unIndex == arChilds.size() - 1) + { + m_arPoints[unIndex + 1].m_nX = arChilds[unIndex].GetAttributeInt(L"x2"); + m_arPoints[unIndex + 1].m_nY = arChilds[unIndex].GetAttributeInt(L"y2"); + } + } +} + +EShapeType CCtrlShapeCurve::GetShapeType() const +{ + return EShapeType::Curve; +} + +VECTOR CCtrlShapeCurve::GetPoints() const +{ + return m_arPoints; +} + +VECTOR CCtrlShapeCurve::GetSegmentsType() const +{ + return m_arSegmentType; +} + +int CCtrlShapeCurve::ParseElement(CCtrlShapeCurve& oObj, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) +{ + oBuffer.SavePosition(); + + oBuffer.ReadInt(oObj.m_nPoints); + + if (0 < oObj.m_nPoints) + { + oObj.m_arPoints.resize(oObj.m_nPoints); + for (unsigned int unIndex = 0; unIndex < oObj.m_nPoints; ++unIndex) + { + oBuffer.ReadInt(oObj.m_arPoints[unIndex].m_nX); + oBuffer.ReadInt(oObj.m_arPoints[unIndex].m_nY); + } + } + + if (1 < oObj.m_nPoints) + { + oObj.m_arSegmentType.resize(oObj.m_nPoints - 1); + for (unsigned int unIndex = 0; unIndex < oObj.m_nPoints - 1; ++unIndex) + oBuffer.ReadByte(oObj.m_arSegmentType[unIndex]); + } + + oBuffer.Skip(4); + + oBuffer.Skip(nSize - oBuffer.GetDistanceToLastPos(true)); + + return nSize; +} + +int CCtrlShapeCurve::ParseCtrl(CCtrlShapeCurve& oObj, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) +{ + return CCtrlGeneralShape::ParseCtrl(oObj, nSize, oBuffer, nOff, nVersion); +} + +} diff --git a/HwpFile/HwpDoc/Paragraph/CtrlShapeCurve.h b/HwpFile/HwpDoc/Paragraph/CtrlShapeCurve.h new file mode 100644 index 00000000000..11a3bc1ab83 --- /dev/null +++ b/HwpFile/HwpDoc/Paragraph/CtrlShapeCurve.h @@ -0,0 +1,31 @@ +#ifndef CTRLSHAPECURVE_H +#define CTRLSHAPECURVE_H + +#include "CtrlGeneralShape.h" +#include "Point.h" + +namespace HWP +{ +class CCtrlShapeCurve : public CCtrlGeneralShape +{ + int m_nPoints; + VECTOR m_arPoints; + VECTOR m_arSegmentType; +public: + CCtrlShapeCurve(); + CCtrlShapeCurve(const HWP_STRING& sCtrlID); + CCtrlShapeCurve(const CCtrlGeneralShape& oShape); + CCtrlShapeCurve(const HWP_STRING& sCtrlID, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); + CCtrlShapeCurve(const HWP_STRING& sCtrlID, CXMLNode& oNode, int nVersion); + + EShapeType GetShapeType() const override; + + VECTOR GetPoints() const; + VECTOR GetSegmentsType() const; + + static int ParseElement(CCtrlShapeCurve& oObj, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); + static int ParseCtrl(CCtrlShapeCurve& oObj, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); +}; +} + +#endif // CTRLSHAPECURVE_H diff --git a/HwpFile/HwpDoc/Paragraph/CtrlShapeEllipse.cpp b/HwpFile/HwpDoc/Paragraph/CtrlShapeEllipse.cpp new file mode 100644 index 00000000000..30f534d17c1 --- /dev/null +++ b/HwpFile/HwpDoc/Paragraph/CtrlShapeEllipse.cpp @@ -0,0 +1,153 @@ +#include "CtrlShapeEllipse.h" + +namespace HWP +{ +EArcType GetArcType(int nValue) +{ + SWITCH(EArcType, nValue) + { + DEFAULT(EArcType::NORMAL); + CASE(EArcType::PIE); + CASE(EArcType::CHORD); + } +} + +EArcType GetArcType(const HWP_STRING& sValue) +{ + IF_STRING_IN_ENUM(PIE, sValue, EArcType); + ELSE_IF_STRING_IN_ENUM(CHORD, sValue, EArcType); + ELSE_STRING_IN_ENUM(NORMAL, EArcType); +} + +CCtrlShapeEllipse::CCtrlShapeEllipse() +{} + +CCtrlShapeEllipse::CCtrlShapeEllipse(const HWP_STRING& sCtrlID) + : CCtrlGeneralShape(sCtrlID) +{} + +CCtrlShapeEllipse::CCtrlShapeEllipse(const CCtrlGeneralShape& oShape) + : CCtrlGeneralShape(oShape) +{} + +CCtrlShapeEllipse::CCtrlShapeEllipse(const HWP_STRING& sCtrlID, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) + : CCtrlGeneralShape(sCtrlID, nSize, oBuffer, nOff, nVersion) +{} + +CCtrlShapeEllipse::CCtrlShapeEllipse(const HWP_STRING& sCtrlID, CXMLNode& oNode, int nVersion) + : CCtrlGeneralShape(sCtrlID, oNode, nVersion) +{ + m_bIntervalDirty = oNode.GetAttributeBool(L"intervalDirty"); + m_bHasArcProperty = oNode.GetAttributeBool(L"hasArcPr"); + m_eArcType = GetArcType(oNode.GetAttribute(L"arcType")); + + for (CXMLNode& oChild : oNode.GetChilds()) + { + if (L"hc:center" == oChild.GetName()) + { + m_nCenterX = oChild.GetAttributeInt(L"x"); + m_nCenterY = oChild.GetAttributeInt(L"y"); + } + else if (L"hp:ax1" == oChild.GetName()) + { + m_nAxixX1 = oChild.GetAttributeInt(L"x"); + m_nAxixY1 = oChild.GetAttributeInt(L"y"); + } + else if (L"hp:ax2" == oChild.GetName()) + { + m_nAxixX2 = oChild.GetAttributeInt(L"x"); + m_nAxixY2 = oChild.GetAttributeInt(L"y"); + } + else if (L"hc:start1" == oChild.GetName()) + { + m_nStartX1 = oChild.GetAttributeInt(L"x"); + m_nStartY1 = oChild.GetAttributeInt(L"y"); + } + else if (L"hc:start2" == oChild.GetName()) + { + m_nStartX2 = oChild.GetAttributeInt(L"x"); + m_nStartY2 = oChild.GetAttributeInt(L"y"); + } + else if (L"hc:end1" == oChild.GetName()) + { + m_nEndX1 = oChild.GetAttributeInt(L"x"); + m_nEndY1 = oChild.GetAttributeInt(L"y"); + } + else if (L"hc:end2" == oChild.GetName()) + { + m_nEndX2 = oChild.GetAttributeInt(L"x"); + m_nEndY2 = oChild.GetAttributeInt(L"y"); + } + } +} + +EShapeType CCtrlShapeEllipse::GetShapeType() const +{ + return EShapeType::Ellipse; +} + +int CCtrlShapeEllipse::ParseElement(CCtrlShapeEllipse& oObj, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) +{ + oBuffer.SavePosition(); + + int nAttr; + oBuffer.ReadInt(nAttr); + + oObj.m_bIntervalDirty = CHECK_FLAG(nAttr, 0x01); + oObj.m_bHasArcProperty = CHECK_FLAG(nAttr, 0x02); + oObj.m_eArcType = GetArcType(nAttr << 2 & 0xFF); + oBuffer.Skip(4); + oBuffer.ReadInt(oObj.m_nCenterX); + oBuffer.ReadInt(oObj.m_nCenterY); + oBuffer.ReadInt(oObj.m_nAxixX1); + oBuffer.ReadInt(oObj.m_nAxixY1); + oBuffer.ReadInt(oObj.m_nAxixX2); + oBuffer.ReadInt(oObj.m_nAxixY2); + oBuffer.ReadInt(oObj.m_nStartX1); + oBuffer.ReadInt(oObj.m_nStartY1); + oBuffer.ReadInt(oObj.m_nEndX1); + oBuffer.ReadInt(oObj.m_nEndY1); + oBuffer.ReadInt(oObj.m_nStartX2); + oBuffer.ReadInt(oObj.m_nStartY2); + oBuffer.ReadInt(oObj.m_nEndX2); + oBuffer.ReadInt(oObj.m_nEndY2); + + oBuffer.Skip(nSize - oBuffer.GetDistanceToLastPos(true)); + + return nSize; +} + +int CCtrlShapeEllipse::ParseCtrl(CCtrlShapeEllipse& oObj, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) +{ + oBuffer.SavePosition(); + CCtrlGeneralShape::ParseCtrl(oObj, nSize, oBuffer, nOff, nVersion); + return oBuffer.GetDistanceToLastPos(true); +} + +int CCtrlShapeEllipse::ParseListHeaderAppend(CCtrlShapeEllipse& oObj, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) +{ + oBuffer.SavePosition(); + + oBuffer.Skip(2); + + oBuffer.ReadShort(oObj.m_shLeftSpace); + oBuffer.ReadShort(oObj.m_shRightSpace); + oBuffer.ReadShort(oObj.m_shTopSpace); + oBuffer.ReadShort(oObj.m_shBottomSpace); + + oBuffer.ReadInt(oObj.m_nMaxTxtWidth); + + oBuffer.Skip(13); + + if (nSize > oBuffer.GetDistanceToLastPos()) + { + oBuffer.Skip(10); + HWP_STRING sFieldName; + oBuffer.ReadString(sFieldName, EStringCharacter::UTF16); + + oBuffer.Skip(nSize - oBuffer.GetDistanceToLastPos()); + } + + return oBuffer.GetDistanceToLastPos(true); +} +} diff --git a/HwpFile/HwpDoc/Paragraph/CtrlShapeEllipse.h b/HwpFile/HwpDoc/Paragraph/CtrlShapeEllipse.h new file mode 100644 index 00000000000..ad0b28ba7c3 --- /dev/null +++ b/HwpFile/HwpDoc/Paragraph/CtrlShapeEllipse.h @@ -0,0 +1,52 @@ +#ifndef CTRLSHAPEELLIPSE_H +#define CTRLSHAPEELLIPSE_H + +#include "CtrlGeneralShape.h" + +namespace HWP +{ +enum class EArcType +{ + NORMAL, + PIE, + CHORD +}; + +EArcType GetArcType(int nValue); +EArcType GetArcType(const HWP_STRING& sValue); + +class CCtrlShapeEllipse : public CCtrlGeneralShape +{ + bool m_bIntervalDirty; + bool m_bHasArcProperty; + EArcType m_eArcType; + int m_nCenterX; + int m_nCenterY; + int m_nAxixX1; + int m_nAxixY1; + int m_nAxixX2; + int m_nAxixY2; + int m_nStartX1; + int m_nStartY1; + int m_nEndX1; + int m_nEndY1; + int m_nStartX2; + int m_nStartY2; + int m_nEndX2; + int m_nEndY2; +public: + CCtrlShapeEllipse(); + CCtrlShapeEllipse(const HWP_STRING& sCtrlID); + CCtrlShapeEllipse(const CCtrlGeneralShape& oShape); + CCtrlShapeEllipse(const HWP_STRING& sCtrlID, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); + CCtrlShapeEllipse(const HWP_STRING& sCtrlID, CXMLNode& oNode, int nVersion); + + EShapeType GetShapeType() const override; + + static int ParseElement(CCtrlShapeEllipse& oObj, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); + static int ParseCtrl(CCtrlShapeEllipse& oObj, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); + static int ParseListHeaderAppend(CCtrlShapeEllipse& oObj, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); +}; +} + +#endif // CTRLSHAPEELLIPSE_H diff --git a/HwpFile/HwpDoc/Paragraph/CtrlShapeLine.cpp b/HwpFile/HwpDoc/Paragraph/CtrlShapeLine.cpp new file mode 100644 index 00000000000..665df293f91 --- /dev/null +++ b/HwpFile/HwpDoc/Paragraph/CtrlShapeLine.cpp @@ -0,0 +1,74 @@ +#include "CtrlShapeLine.h" + +namespace HWP +{ +CCtrlShapeLine::CCtrlShapeLine() +{} + +CCtrlShapeLine::CCtrlShapeLine(const HWP_STRING& sCtrlID) + : CCtrlGeneralShape(sCtrlID) +{} + +CCtrlShapeLine::CCtrlShapeLine(const CCtrlGeneralShape& oShape) + : CCtrlGeneralShape(oShape) +{} + +CCtrlShapeLine::CCtrlShapeLine(const HWP_STRING& sCtrlID, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) + : CCtrlGeneralShape(sCtrlID, nSize, oBuffer, nOff, nVersion) +{} + +CCtrlShapeLine::CCtrlShapeLine(const HWP_STRING& sCtrlID, CXMLNode& oNode, int nVersion) + : CCtrlGeneralShape(sCtrlID, oNode, nVersion) +{ + m_shAttr = (short)oNode.GetAttributeBool(L"isReverseHV"); + + for (CXMLNode& oChild : oNode.GetChilds()) + { + if (L"hc:startPt" == oChild.GetName()) + { + m_nStartX = oChild.GetAttributeInt(L"x"); + m_nStartY = oChild.GetAttributeInt(L"y"); + } + else if (L"hc:endPt" == oChild.GetName()) + { + m_nEndX = oChild.GetAttributeInt(L"x"); + m_nEndY = oChild.GetAttributeInt(L"y"); + } + } +} + +EShapeType CCtrlShapeLine::GetShapeType() const +{ + return EShapeType::Line; +} + +void CCtrlShapeLine::ParseElement(CCtrlShapeLine& oObj, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) +{ + oBuffer.SavePosition(); + + if (L"loc$" == oObj.GetID()) + oBuffer.Skip(4); + + oBuffer.ReadInt(oObj.m_nStartX); + oBuffer.ReadInt(oObj.m_nStartY); + oBuffer.ReadInt(oObj.m_nEndX); + oBuffer.ReadInt(oObj.m_nEndY); + + if (nSize == oBuffer.GetDistanceToLastPos()) + { + oBuffer.RemoveLastSavedPos(); + return; + } + + oBuffer.ReadShort(oObj.m_shAttr); + oBuffer.Skip(2); + + oBuffer.Skip(nSize - oBuffer.GetDistanceToLastPos(true)); +} + +void CCtrlShapeLine::ParseCtrl(CCtrlShapeLine& oObj, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) +{ + CCtrlGeneralShape::ParseCtrl(oObj, nSize, oBuffer, nOff, nVersion); +} + +} diff --git a/HwpFile/HwpDoc/Paragraph/CtrlShapeLine.h b/HwpFile/HwpDoc/Paragraph/CtrlShapeLine.h new file mode 100644 index 00000000000..45aa7d87222 --- /dev/null +++ b/HwpFile/HwpDoc/Paragraph/CtrlShapeLine.h @@ -0,0 +1,29 @@ +#ifndef CTRLSHAPELINE_H +#define CTRLSHAPELINE_H + +#include "CtrlGeneralShape.h" + +namespace HWP +{ +class CCtrlShapeLine : public CCtrlGeneralShape +{ + int m_nStartX; + int m_nStartY; + int m_nEndX; + int m_nEndY; + short m_shAttr; +public: + CCtrlShapeLine(); + CCtrlShapeLine(const HWP_STRING& sCtrlID); + CCtrlShapeLine(const CCtrlGeneralShape& oShape); + CCtrlShapeLine(const HWP_STRING& sCtrlID, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); + CCtrlShapeLine(const HWP_STRING& sCtrlID, CXMLNode& oNode, int nVersion); + + EShapeType GetShapeType() const override; + + static void ParseElement(CCtrlShapeLine& oObj, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); + static void ParseCtrl(CCtrlShapeLine& oObj, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); +}; +} + +#endif // CTRLSHAPELINE_H diff --git a/HwpFile/HwpDoc/Paragraph/CtrlShapeOle.cpp b/HwpFile/HwpDoc/Paragraph/CtrlShapeOle.cpp new file mode 100644 index 00000000000..d209927c52b --- /dev/null +++ b/HwpFile/HwpDoc/Paragraph/CtrlShapeOle.cpp @@ -0,0 +1,63 @@ +#include "CtrlShapeOle.h" + +namespace HWP +{ +CCtrlShapeOle::CCtrlShapeOle() +{} + +CCtrlShapeOle::CCtrlShapeOle(const HWP_STRING& sCtrlID) + : CCtrlGeneralShape(sCtrlID) +{} + +CCtrlShapeOle::CCtrlShapeOle(const CCtrlGeneralShape& oShape) + : CCtrlGeneralShape(oShape) +{} + +CCtrlShapeOle::CCtrlShapeOle(const HWP_STRING& sCtrlID, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) + : CCtrlGeneralShape(sCtrlID, nSize, oBuffer, nOff, nVersion) +{} + +CCtrlShapeOle::CCtrlShapeOle(const HWP_STRING& sCtrlID, CXMLNode& oNode, int nVersion) + : CCtrlGeneralShape(sCtrlID, oNode, nVersion) +{ + m_sBinDataID = oNode.GetAttribute(L"binaryItemIDRef"); + + for (CXMLNode& oChild : oNode.GetChilds(L"hc:extent")) + { + m_nExtentX = oChild.GetAttributeInt(L"x"); + m_nExtentY = oChild.GetAttributeInt(L"y"); + } +} + +EShapeType CCtrlShapeOle::GetShapeType() const +{ + return EShapeType::Ole; +} + +HWP_STRING CCtrlShapeOle::GetBinDataID() const +{ + return m_sBinDataID; +} + +int CCtrlShapeOle::ParseElement(CCtrlShapeOle& oObj, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) +{ + oBuffer.SavePosition(); + + oBuffer.ReadInt(oObj.m_nAttr); + oBuffer.ReadInt(oObj.m_nExtentX); + oBuffer.ReadInt(oObj.m_nExtentY); + oObj.m_sBinDataID = std::to_wstring(oBuffer.ReadShort()); + oBuffer.ReadColor(oObj.m_nBorderColor); + oBuffer.ReadInt(oObj.m_nBorderThick); + oBuffer.ReadInt(oObj.m_nBorderAttr); + + oBuffer.Skip(nSize - oBuffer.GetDistanceToLastPos(true)); + return nSize; +} + +int CCtrlShapeOle::ParseCtrl(CCtrlShapeOle& oObj, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) +{ + return CCtrlObjElement::ParseCtrl(oObj, nSize, oBuffer, nOff, nVersion); +} + +} diff --git a/HwpFile/HwpDoc/Paragraph/CtrlShapeOle.h b/HwpFile/HwpDoc/Paragraph/CtrlShapeOle.h new file mode 100644 index 00000000000..97bd07b4ecb --- /dev/null +++ b/HwpFile/HwpDoc/Paragraph/CtrlShapeOle.h @@ -0,0 +1,33 @@ +#ifndef CTRLSHAPEOLE_H +#define CTRLSHAPEOLE_H + +#include "CtrlGeneralShape.h" + +namespace HWP +{ +class CCtrlShapeOle : public CCtrlGeneralShape +{ + int m_nAttr; + int m_nExtentX; + int m_nExtentY; + HWP_STRING m_sBinDataID; + int m_nBorderColor; + int m_nBorderThick; + int m_nBorderAttr; +public: + CCtrlShapeOle(); + CCtrlShapeOle(const HWP_STRING& sCtrlID); + CCtrlShapeOle(const CCtrlGeneralShape& oShape); + CCtrlShapeOle(const HWP_STRING& sCtrlID, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); + CCtrlShapeOle(const HWP_STRING& sCtrlID, CXMLNode& oNode, int nVersion); + + EShapeType GetShapeType() const override; + + HWP_STRING GetBinDataID() const; + + static int ParseElement(CCtrlShapeOle& oObj, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); + static int ParseCtrl(CCtrlShapeOle& oObj, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); +}; +} + +#endif // CTRLSHAPEOLE_H diff --git a/HwpFile/HwpDoc/Paragraph/CtrlShapePic.cpp b/HwpFile/HwpDoc/Paragraph/CtrlShapePic.cpp new file mode 100644 index 00000000000..78df7aa2405 --- /dev/null +++ b/HwpFile/HwpDoc/Paragraph/CtrlShapePic.cpp @@ -0,0 +1,413 @@ +#include "CtrlShapePic.h" + +namespace HWP +{ +EPicEffectType GetPicEffectType(int nValue) +{ + switch(static_cast(nValue)) + { + case EPicEffectType::SHADOW: + case EPicEffectType::GLOW: + case EPicEffectType::SOFT_EDGE: + case EPicEffectType::REFLECT: + return static_cast(nValue); + default: + return EPicEffectType::NONE; + } +} + +CPicColor::CPicColor(CHWPStream& oBuffer, int nOff, int nSize) +{ + oBuffer.ReadInt(m_nType); + oBuffer.ReadInt(m_nRGB); + + oBuffer.Skip(nSize - 8); + m_nSize = nSize; +} + +CPicColor::CPicColor(CXMLNode& oNode) +{ + //TODO:: проверить + m_nType = 0; +} + +CPicEffect::CPicEffect(EPicEffectType eType) + : m_eType(eType) +{} + +CPicEffect::CPicEffect(int nType) +{ + m_eType = GetPicEffectType(nType); +} + +int CPicEffect::GetSize() +{ + return m_nSize; +} + +CShadow::CShadow(int nTypeNum, CHWPStream& oBuffer, int nOff, int nSize) + : CPicEffect(nTypeNum), m_pColor(nullptr) +{ + oBuffer.SavePosition(); + + oBuffer.ReadInt(m_nStyle); + oBuffer.ReadInt(m_nTransparency); + oBuffer.ReadInt(m_nBlur); + oBuffer.ReadInt(m_nDirection); + oBuffer.ReadInt(m_nDistance); + oBuffer.ReadFloat(m_fAngleX); + oBuffer.ReadFloat(m_fAngleY); + oBuffer.ReadFloat(m_fMagnifyX); + oBuffer.ReadFloat(m_fMagnifyY); + oBuffer.ReadInt(m_nRotation); + m_pColor = new CPicColor(oBuffer, nOff, nSize - oBuffer.GetDistanceToLastPos()); + + m_nSize = oBuffer.GetDistanceToLastPos(true); +} + +CShadow::CShadow(CXMLNode& oNode, int nVersion) + : CPicEffect(EPicEffectType::SHADOW), m_pColor(nullptr) +{ + m_nStyle = oNode.GetAttributeInt(L"style"); + m_nTransparency = oNode.GetAttributeInt(L"alpha"); + m_nBlur = oNode.GetAttributeInt(L"radius"); + m_nDirection = oNode.GetAttributeInt(L"direction"); + m_nDistance = oNode.GetAttributeInt(L"distance"); + m_nRotation = (int)oNode.GetAttributeBool(L"rotationStyle"); + + for (CXMLNode& oChild : oNode.GetChilds()) + { + if (L"hp:skew" == oChild.GetName()) + { + m_fAngleX = oChild.GetAttributeDouble(L"x"); + m_fAngleY = oChild.GetAttributeDouble(L"y"); + } + else if (L"hp:scale" == oChild.GetName()) + { + m_fMagnifyX = oChild.GetAttributeDouble(L"x"); + m_fMagnifyY = oChild.GetAttributeDouble(L"y"); + } + else if (L"hp:effectsColor" == oChild.GetName()) + { + m_pColor = new CPicColor(oChild); + } + } +} + +CShadow::~CShadow() +{ + if (nullptr != m_pColor) + delete m_pColor; +} + +CNeon::CNeon(int nTypeNum, CHWPStream& oBuffer, int nOff, int nSize) + : CPicEffect(nTypeNum), m_pColor(nullptr) +{ + oBuffer.SavePosition(); + + oBuffer.ReadFloat(m_fTransparency); + oBuffer.ReadFloat(m_fRadius); + m_pColor = new CPicColor(oBuffer, nOff, nSize - oBuffer.GetDistanceToLastPos()); + + m_nSize = oBuffer.GetDistanceToLastPos(true); +} + +CNeon::CNeon(CXMLNode& oNode, int nVersion) + : CPicEffect(EPicEffectType::GLOW), m_pColor(nullptr) +{ + m_fTransparency = oNode.GetAttributeDouble(L"alpha"); + m_fRadius = oNode.GetAttributeDouble(L"radius"); + + CXMLNode oChild{oNode.GetChild(L"hp:effectsColor")}; + m_pColor = new CPicColor(oChild); +} + +CNeon::~CNeon() +{ + if (nullptr != m_pColor) + delete m_pColor; +} + +CSoftEdge::CSoftEdge(int nTypeNum, CHWPStream& oBuffer, int nOff, int nSize) + : CPicEffect(nTypeNum) +{ + oBuffer.ReadFloat(m_fRadius); + + m_nSize = 4; +} + +CSoftEdge::CSoftEdge(CXMLNode& oNode, int nVersion) + : CPicEffect(EPicEffectType::SOFT_EDGE) +{ + m_fRadius = oNode.GetAttributeDouble(L"radius"); +} + +CReflect::CReflect(int nTypeNum, CHWPStream& oBuffer, int nOff, int nSize) + : CPicEffect(nTypeNum) +{ + oBuffer.SavePosition(); + + oBuffer.ReadInt(m_nStyle); + oBuffer.ReadFloat(m_fRadius); + oBuffer.ReadFloat(m_fDirection); + oBuffer.ReadFloat(m_fDistance); + oBuffer.ReadFloat(m_fAngleX); + oBuffer.ReadFloat(m_fAngleY); + oBuffer.ReadFloat(m_fMagnifyX); + oBuffer.ReadFloat(m_fMagnifyY); + oBuffer.ReadInt(m_nRotateStyle); + oBuffer.ReadFloat(m_fStartTrans); + oBuffer.ReadFloat(m_fStartPos); + oBuffer.ReadFloat(m_fEndTrans); + oBuffer.ReadFloat(m_fEndPos); + oBuffer.ReadFloat(m_fOffsetDirection); + + m_nSize = oBuffer.GetDistanceToLastPos(true); +} + +CReflect::CReflect(CXMLNode& oNode, int nVersion) + : CPicEffect(EPicEffectType::REFLECT) +{ + m_fRadius = oNode.GetAttributeDouble(L"radius"); + m_fDirection = oNode.GetAttributeInt(L"direction"); + m_fDistance = oNode.GetAttributeInt(L"distance"); + m_nRotateStyle = (int)oNode.GetAttributeBool(L"rotationStyle"); + m_fOffsetDirection = oNode.GetAttributeInt(L"fadeDirection"); + + for (CXMLNode& oChild : oNode.GetChilds()) + { + if (L"hp:skew" == oChild.GetName()) + { + m_fAngleX = oChild.GetAttributeDouble(L"x"); + m_fAngleY = oChild.GetAttributeDouble(L"y"); + } + else if (L"hp:scale" == oChild.GetName()) + { + m_fMagnifyX = oChild.GetAttributeDouble(L"x"); + m_fMagnifyY = oChild.GetAttributeDouble(L"y"); + } + else if (L"hp:alpha" == oChild.GetName()) + { + m_fStartTrans = oChild.GetAttributeDouble(L"start"); + m_fEndTrans = oChild.GetAttributeDouble(L"end"); + } + else if (L"hp:pos" == oChild.GetName()) + { + m_fStartPos = oChild.GetAttributeDouble(L"start"); + m_fEndPos = oChild.GetAttributeDouble(L"end"); + } + } +} + +CCtrlShapePic::CCtrlShapePic() + : CCtrlGeneralShape() +{} + +CCtrlShapePic::CCtrlShapePic(const HWP_STRING& sCtrlID) + : CCtrlGeneralShape(sCtrlID) +{} + +CCtrlShapePic::CCtrlShapePic(const CCtrlGeneralShape& oShape) + : CCtrlGeneralShape(oShape) +{} + +CCtrlShapePic::CCtrlShapePic(const HWP_STRING& sCtrlID, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) + : CCtrlGeneralShape(sCtrlID, nSize, oBuffer, nOff, nVersion) +{} + +CCtrlShapePic::CCtrlShapePic(const HWP_STRING& sCtrlID, CXMLNode& oNode, int nVersion) + : CCtrlGeneralShape(sCtrlID, oNode, nVersion) +{ + for (CXMLNode& oChild : oNode.GetChilds()) + { + if (L"hp:imgRect" == oChild.GetName()) + { + for (CXMLNode& oGrandChild : oChild.GetChilds()) + { + for (unsigned int unIndex = 0; unIndex < 4; ++unIndex) + { + if ((L"hc:pt" + std::to_wstring(unIndex)) == oGrandChild.GetName()) + { + m_arBorderPoints[unIndex].m_nX = oChild.GetAttributeInt(L"x"); + m_arBorderPoints[unIndex].m_nY = oChild.GetAttributeInt(L"y"); + break; + } + } + } + } + else if (L"hp:imgClip" == oChild.GetName()) + { + m_nCropLeft = oChild.GetAttributeInt(L"left"); + m_nCropRight = oChild.GetAttributeInt(L"right"); + m_nCropTop = oChild.GetAttributeInt(L"top"); + m_nCropBottom = oChild.GetAttributeInt(L"bottom"); + } + else if (L"hp:effects" == oChild.GetName()) + { + for (CXMLNode& oGrandChild : oChild.GetChilds()) + { + if (L"hp:shadow" == oGrandChild.GetName()) + m_arPicEffect.push_back(new CShadow(oGrandChild, nVersion)); + else if (L"hp:glow" == oGrandChild.GetName()) + m_arPicEffect.push_back(new CNeon(oGrandChild, nVersion)); + else if (L"hp:softEdge" == oGrandChild.GetName()) + m_arPicEffect.push_back(new CSoftEdge(oGrandChild, nVersion)); + else if (L"hp:reflection" == oGrandChild.GetName()) + m_arPicEffect.push_back(new CReflect(oGrandChild, nVersion)); + } + } + else if (L"hc:img" == oChild.GetName()) + { + m_chBright = (HWP_BYTE)oChild.GetAttributeInt(L"bright"); + m_chContrast = (HWP_BYTE)oChild.GetAttributeInt(L"contrast"); + + HWP_STRING sType = oChild.GetAttribute(L"effect"); + + if (L"REAL_PIC" == sType) + m_chEffect = 0; + else if (L"GRAY_SCALE" == sType) + m_chEffect = 1; + else if (L"BLACK_WHITE" == sType) + m_chEffect = 2; + + m_sBinDataID = oChild.GetAttribute(L"binaryItemIDRef"); + } + else if (L"hp:imgDim" == oChild.GetName()) + { + m_nIniPicWidth = oChild.GetAttributeInt(L"dimwidth"); + m_nIniPicHeight = oChild.GetAttributeInt(L"dimheight"); + } + } +} + +CCtrlShapePic::~CCtrlShapePic() +{ + for (CPicEffect* pEffect : m_arPicEffect) + { + if (nullptr != pEffect) + delete pEffect; + } +} + +EShapeType CCtrlShapePic::GetShapeType() const +{ + return EShapeType::Pic; +} + +HWP_STRING CCtrlShapePic::GetBinDataID() const +{ + return m_sBinDataID; +} + +int CCtrlShapePic::GetPicWidth() const +{ + return m_nIniPicWidth; +} + +int CCtrlShapePic::GetPicHeight() const +{ + return m_nIniPicHeight; +} + +ELineStyle2 CCtrlShapePic::GetBorderLineStyle() const +{ + return ::HWP::GetLineStyle2((m_nBorderAttr & ((1 << 5) - 1))); +} + +HWP_BYTE CCtrlShapePic::GetBorderCompoundLineType() const +{ + return (HWP_BYTE)((m_nBorderAttr >> 6) & ((1 << 3) - 1)); +} + +int CCtrlShapePic::GetBorderColor() const +{ + return m_nBorderColor; +} + +int CCtrlShapePic::GetBorderThick() const +{ + return m_nBorderThick; +} + +int CCtrlShapePic::ParseElement(CCtrlShapePic& oObj, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) +{ + oBuffer.SavePosition(); + + oBuffer.ReadColor(oObj.m_nBorderColor); + oBuffer.ReadInt(oObj.m_nBorderThick); + oBuffer.ReadInt(oObj.m_nBorderAttr); + + for (unsigned int unIndex = 0; unIndex < 4; ++unIndex) + { + oBuffer.ReadInt(oObj.m_arBorderPoints[unIndex].m_nX); + oBuffer.ReadInt(oObj.m_arBorderPoints[unIndex].m_nY); + } + + oBuffer.ReadInt(oObj.m_nCropLeft); + oBuffer.ReadInt(oObj.m_nCropTop); + oBuffer.ReadInt(oObj.m_nCropRight); + oBuffer.ReadInt(oObj.m_nCropBottom); + + for (unsigned int unIndex = 0; unIndex < 4; ++unIndex) + oBuffer.ReadShort(oObj.m_arInnerSpaces[unIndex]); + + oBuffer.ReadByte(oObj.m_chBright); + oBuffer.ReadByte(oObj.m_chContrast); + oBuffer.ReadByte(oObj.m_chEffect); + + short shBinItemID; + oBuffer.ReadShort(shBinItemID); + oObj.m_sBinDataID = std::to_wstring(shBinItemID); + + oBuffer.ReadByte(oObj.m_chBorderAlpha); + + #define CAN_READ() \ + if (oBuffer.GetDistanceToLastPos() >= nSize) \ + { \ + oBuffer.Skip(nSize - oBuffer.GetDistanceToLastPos(true)); \ + return nSize; \ + } + + CAN_READ(); + + oBuffer.ReadInt(oObj.m_nInstanceID); + + CAN_READ(); + + oBuffer.ReadInt(oObj.m_nPicEffectInfo); + + #define ADD_EFFECT(flag, effect, size) \ + if (CHECK_FLAG(oObj.m_nPicEffectInfo, flag)) \ + { \ + CPicEffect* pEffect = new effect(oObj.m_nPicEffectInfo, oBuffer, nOff, size); \ + if (nullptr != pEffect) \ + oObj.m_arPicEffect.push_back(pEffect); \ + } + + if (oObj.m_nPicEffectInfo && oBuffer.GetDistanceToLastPos() < nSize) + { + ADD_EFFECT(0x1, CShadow, 56) + ADD_EFFECT(0x2, CNeon, 28) + ADD_EFFECT(0x4, CSoftEdge, 4 ) + ADD_EFFECT(0x8, CReflect, 56) + } + + CAN_READ(); + + oBuffer.ReadInt(oObj.m_nIniPicWidth); + oBuffer.ReadInt(oObj.m_nIniPicHeight); + + if (nSize - oBuffer.GetDistanceToLastPos() >= 1) + oBuffer.ReadByte(oObj.m_chPicAlpha); + + oBuffer.Skip(nSize - oBuffer.GetDistanceToLastPos(true)); + + return nSize; +} + +int CCtrlShapePic::ParseCtrl(CCtrlShapePic& oObj, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) +{ + return CCtrlObjElement::ParseCtrl(oObj, nSize, oBuffer, nOff, nVersion); +} + +} diff --git a/HwpFile/HwpDoc/Paragraph/CtrlShapePic.h b/HwpFile/HwpDoc/Paragraph/CtrlShapePic.h new file mode 100644 index 00000000000..2f8078fc2fd --- /dev/null +++ b/HwpFile/HwpDoc/Paragraph/CtrlShapePic.h @@ -0,0 +1,156 @@ +#ifndef CTRLSHAPEPIC_H +#define CTRLSHAPEPIC_H + +#include "CtrlGeneralShape.h" +#include "Point.h" + +namespace HWP +{ +enum class EImagePathType +{ + COMPOUND, + OWPML, + LINK, + UNKNOWN +}; + +enum class EPicEffectType +{ + NONE, + SHADOW, + GLOW, + SOFT_EDGE, + REFLECT +}; + +class CPicColor +{ + int m_nSize; + + int m_nType; + int m_nRGB; +public: + CPicColor(CHWPStream& oBuffer, int nOff, int nSize); + CPicColor(CXMLNode& oNode); +}; + +class CPicEffect +{ + EPicEffectType m_eType; +protected: + int m_nSize; +public: + CPicEffect(EPicEffectType eType); + CPicEffect(int nType); + + int GetSize(); +}; + +class CShadow : public CPicEffect +{ + int m_nStyle; + int m_nTransparency; + int m_nBlur; + int m_nDirection; + int m_nDistance; + float m_fAngleX; + float m_fAngleY; + float m_fMagnifyX; + float m_fMagnifyY; + int m_nRotation; + CPicColor *m_pColor; +public: + CShadow(int nTypeNum, CHWPStream& oBuffer, int nOff, int nSize); + CShadow(CXMLNode& oNode, int nVersion); + ~CShadow(); +}; + +class CNeon : public CPicEffect +{ + float m_fTransparency; + float m_fRadius; + CPicColor *m_pColor; +public: + CNeon(int nTypeNum, CHWPStream& oBuffer, int nOff, int nSize); + CNeon(CXMLNode& oNode, int nVersion); + ~CNeon(); +}; + +class CSoftEdge : public CPicEffect +{ + float m_fRadius; +public: + CSoftEdge(int nTypeNum, CHWPStream& oBuffer, int nOff, int nSize); + CSoftEdge(CXMLNode& oNode, int nVersion); +}; + +class CReflect : public CPicEffect +{ + int m_nStyle; + float m_fRadius; + float m_fDirection; + float m_fDistance; + float m_fAngleX; + float m_fAngleY; + float m_fMagnifyX; + float m_fMagnifyY; + int m_nRotateStyle; + float m_fStartTrans; + float m_fStartPos; + float m_fEndTrans; + float m_fEndPos; + float m_fOffsetDirection; +public: + CReflect(int nTypeNum, CHWPStream& oBuffer, int nOff, int nSize); + CReflect(CXMLNode& oNode, int nVersion); +}; + +class CCtrlShapePic : public CCtrlGeneralShape +{ + int m_nBorderColor; + int m_nBorderThick; + int m_nBorderAttr; + TPoint m_arBorderPoints[4]; + int m_nCropLeft; + int m_nCropTop; + int m_nCropRight; + int m_nCropBottom; + short m_arInnerSpaces[4]; + HWP_BYTE m_chBright; + HWP_BYTE m_chContrast; + HWP_BYTE m_chEffect; + HWP_STRING m_sBinDataID; + + HWP_BYTE m_chBorderAlpha; + int m_nInstanceID; + int m_nPicEffectInfo; + LIST m_arPicEffect; + + int m_nIniPicWidth; + int m_nIniPicHeight; + HWP_BYTE m_chPicAlpha; +public: + CCtrlShapePic(); + CCtrlShapePic(const HWP_STRING& sCtrlID); + CCtrlShapePic(const CCtrlGeneralShape& oShape); + CCtrlShapePic(const HWP_STRING& sCtrlID, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); + CCtrlShapePic(const HWP_STRING& sCtrlID, CXMLNode& oNode, int nVersion); + ~CCtrlShapePic(); + + EShapeType GetShapeType() const override; + + HWP_STRING GetBinDataID() const; + int GetPicWidth() const; + int GetPicHeight() const; + + ELineStyle2 GetBorderLineStyle() const; + HWP_BYTE GetBorderCompoundLineType() const; + int GetBorderColor() const; + int GetBorderThick() const; + + static int ParseElement(CCtrlShapePic& oObj, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); + static int ParseCtrl(CCtrlShapePic& oObj, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); +}; +} + +#endif // CTRLSHAPEPIC_H diff --git a/HwpFile/HwpDoc/Paragraph/CtrlShapePolygon.cpp b/HwpFile/HwpDoc/Paragraph/CtrlShapePolygon.cpp new file mode 100644 index 00000000000..a5fe6ce9e3c --- /dev/null +++ b/HwpFile/HwpDoc/Paragraph/CtrlShapePolygon.cpp @@ -0,0 +1,103 @@ +#include "CtrlShapePolygon.h" + +namespace HWP +{ +CCtrlShapePolygon::CCtrlShapePolygon() +{} + +CCtrlShapePolygon::CCtrlShapePolygon(const HWP_STRING& sCtrlID) + : CCtrlGeneralShape(sCtrlID) +{} + +CCtrlShapePolygon::CCtrlShapePolygon(const CCtrlGeneralShape& oShape) + : CCtrlGeneralShape(oShape) +{} + +CCtrlShapePolygon::CCtrlShapePolygon(const HWP_STRING& sCtrlID, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) + : CCtrlGeneralShape(sCtrlID, nSize, oBuffer, nOff, nVersion) +{} + +CCtrlShapePolygon::CCtrlShapePolygon(const HWP_STRING& sCtrlID, CXMLNode& oNode, int nVersion) + : CCtrlGeneralShape(sCtrlID, oNode, nVersion) +{ + std::vector arChilds{oNode.GetChilds(L"hc:pt")}; + + m_arPoints.resize(arChilds.size()); + + for (unsigned int unIndex = 0; unIndex < arChilds.size(); ++unIndex) + { + m_arPoints[unIndex].m_nX = arChilds[unIndex].GetAttributeInt(L"x"); + m_arPoints[unIndex].m_nY = arChilds[unIndex].GetAttributeInt(L"y"); + } + + m_nPoints = m_arPoints.size(); +} + +EShapeType CCtrlShapePolygon::GetShapeType() const +{ + return EShapeType::Polygon; +} + +std::vector CCtrlShapePolygon::GetPoints() const +{ + return m_arPoints; +} + +int CCtrlShapePolygon::ParseElement(CCtrlShapePolygon& oObj, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) +{ + oBuffer.SavePosition(); + + oBuffer.ReadInt(oObj.m_nPoints); + + if (0 < oObj.m_nPoints) + { + TPoint oPoint; + for (unsigned int unIndex = 0; unIndex < oObj.m_nPoints; ++unIndex) + { + oBuffer.ReadInt(oPoint.m_nX); + oBuffer.ReadInt(oPoint.m_nY); + oObj.m_arPoints.push_back(oPoint); + } + } + + if (4 == (nSize - oBuffer.GetDistanceToLastPos())) + oBuffer.Skip(4); + + oBuffer.Skip(nSize - oBuffer.GetDistanceToLastPos(true)); + + return nSize; +} + +int CCtrlShapePolygon::ParseCtrl(CCtrlShapePolygon& oObj, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) +{ + return CCtrlGeneralShape::ParseCtrl(oObj, nSize, oBuffer, nOff, nVersion); +} + +int CCtrlShapePolygon::ParseListHeaderAppend(CCtrlShapePolygon& oObj, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) +{ + oBuffer.SavePosition(); + + oBuffer.Skip(2); + + oBuffer.ReadShort(oObj.m_shLeftSpace); + oBuffer.ReadShort(oObj.m_shRightSpace); + oBuffer.ReadShort(oObj.m_shTopSpace); + oBuffer.ReadShort(oObj.m_shBottomSpace); + oBuffer.ReadInt(oObj.m_nMaxTxtWidth); + + oBuffer.Skip(13); + + if (nSize > oBuffer.GetDistanceToLastPos()) + { + oBuffer.Skip(10); + HWP_STRING sFieldName; + oBuffer.ReadString(sFieldName, EStringCharacter::UTF16); + + oBuffer.Skip(nSize - oBuffer.GetDistanceToLastPos()); + } + + return oBuffer.GetDistanceToLastPos(true); +} + + +} diff --git a/HwpFile/HwpDoc/Paragraph/CtrlShapePolygon.h b/HwpFile/HwpDoc/Paragraph/CtrlShapePolygon.h new file mode 100644 index 00000000000..0aa129fde4c --- /dev/null +++ b/HwpFile/HwpDoc/Paragraph/CtrlShapePolygon.h @@ -0,0 +1,30 @@ +#ifndef CTRLSHAPEPOLYGON_H +#define CTRLSHAPEPOLYGON_H + +#include "CtrlGeneralShape.h" +#include "Point.h" + +namespace HWP +{ +class CCtrlShapePolygon : public CCtrlGeneralShape +{ + int m_nPoints; + VECTOR m_arPoints; +public: + CCtrlShapePolygon(); + CCtrlShapePolygon(const HWP_STRING& sCtrlID); + CCtrlShapePolygon(const CCtrlGeneralShape& oShape); + CCtrlShapePolygon(const HWP_STRING& sCtrlID, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); + CCtrlShapePolygon(const HWP_STRING& sCtrlID, CXMLNode& oNode, int nVersion); + + EShapeType GetShapeType() const override; + + VECTOR GetPoints() const; + + static int ParseElement(CCtrlShapePolygon& oObj, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); + static int ParseCtrl(CCtrlShapePolygon& oObj, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); + static int ParseListHeaderAppend(CCtrlShapePolygon& oObj, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); +}; +} + +#endif // CTRLSHAPEPOLYGON_H diff --git a/HwpFile/HwpDoc/Paragraph/CtrlShapeRect.cpp b/HwpFile/HwpDoc/Paragraph/CtrlShapeRect.cpp new file mode 100644 index 00000000000..f01f39ecd25 --- /dev/null +++ b/HwpFile/HwpDoc/Paragraph/CtrlShapeRect.cpp @@ -0,0 +1,94 @@ +#include "CtrlShapeRect.h" + +namespace HWP +{ +CCtrlShapeRect::CCtrlShapeRect() +{} + +CCtrlShapeRect::CCtrlShapeRect(const HWP_STRING& sCtrlID) + : CCtrlGeneralShape(sCtrlID) +{} + +CCtrlShapeRect::CCtrlShapeRect(const CCtrlGeneralShape& oShape) + : CCtrlGeneralShape(oShape) +{} + +CCtrlShapeRect::CCtrlShapeRect(const HWP_STRING& sCtrlID, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) + : CCtrlGeneralShape(sCtrlID, nSize, oBuffer, nOff, nVersion) +{} + +CCtrlShapeRect::CCtrlShapeRect(const HWP_STRING& sCtrlID, CXMLNode& oNode, int nVersion) + : CCtrlGeneralShape(sCtrlID, oNode, nVersion) +{ + m_chCurv = (HWP_BYTE)oNode.GetAttributeInt(L"ratio"); + + for (unsigned int unIndex = 0; unIndex < 4; ++unIndex) + { + if ((L"hc:pt" + std::to_wstring(unIndex)) == oNode.GetName()) + { + m_arPoints[unIndex].m_nX = oNode.GetAttributeInt(L"x"); + m_arPoints[unIndex].m_nY = oNode.GetAttributeInt(L"y"); + break; + } + } +} + +EShapeType CCtrlShapeRect::GetShapeType() const +{ + return EShapeType::Rect; +} + +int CCtrlShapeRect::ParseElement(CCtrlShapeRect& oObj, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) +{ + oBuffer.SavePosition(); + + oBuffer.ReadByte(oObj.m_chCurv); + + for (unsigned int unIndex = 0; unIndex < 4; ++unIndex) + { + oBuffer.ReadInt(oObj.m_arPoints[unIndex].m_nX); + oBuffer.ReadInt(oObj.m_arPoints[unIndex].m_nY); + } + + oBuffer.Skip(nSize - oBuffer.GetDistanceToLastPos(true)); + return nSize; +} + +int CCtrlShapeRect::ParseCtrl(CCtrlShapeRect& oObj, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) +{ + return CCtrlGeneralShape::ParseCtrl(oObj, nSize, oBuffer, nOff, nVersion); +} + +int CCtrlShapeRect::ParseListHeaderAppend(CCtrlShapeRect& oObj, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) +{ + oBuffer.SavePosition(); + + oBuffer.Skip(2); + + oBuffer.ReadShort(oObj.m_shLeftSpace); + oBuffer.ReadShort(oObj.m_shRightSpace); + oBuffer.ReadShort(oObj.m_shTopSpace); + oBuffer.ReadShort(oObj.m_shBottomSpace); + oBuffer.ReadInt(oObj.m_nMaxTxtWidth); + + if (nSize - 12 <= 13) + { + oBuffer.Skip(nSize - oBuffer.GetDistanceToLastPos(true)); + return nSize; + } + + oBuffer.Skip(13); + + if (nSize > oBuffer.GetDistanceToLastPos()) + { + oBuffer.Skip(10); + HWP_STRING sFieldName; + oBuffer.ReadString(sFieldName, EStringCharacter::UTF16); + + oBuffer.Skip(nSize - oBuffer.GetDistanceToLastPos()); + } + + return oBuffer.GetDistanceToLastPos(true); +} + +} diff --git a/HwpFile/HwpDoc/Paragraph/CtrlShapeRect.h b/HwpFile/HwpDoc/Paragraph/CtrlShapeRect.h new file mode 100644 index 00000000000..ad12478cac8 --- /dev/null +++ b/HwpFile/HwpDoc/Paragraph/CtrlShapeRect.h @@ -0,0 +1,28 @@ +#ifndef CTRLSHAPERECT_H +#define CTRLSHAPERECT_H + +#include "CtrlGeneralShape.h" +#include "Point.h" + +namespace HWP +{ +class CCtrlShapeRect : public CCtrlGeneralShape +{ + HWP_BYTE m_chCurv; + TPoint m_arPoints[4]; +public: + CCtrlShapeRect(); + CCtrlShapeRect(const HWP_STRING& sCtrlID); + CCtrlShapeRect(const CCtrlGeneralShape& oShape); + CCtrlShapeRect(const HWP_STRING& sCtrlID, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); + CCtrlShapeRect(const HWP_STRING& sCtrlID, CXMLNode& oNode, int nVersion); + + EShapeType GetShapeType() const override; + + static int ParseElement(CCtrlShapeRect& oObj, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); + static int ParseCtrl(CCtrlShapeRect& oObj, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); + static int ParseListHeaderAppend(CCtrlShapeRect& oObj, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); +}; +} + +#endif // CTRLSHAPERECT_H diff --git a/HwpFile/HwpDoc/Paragraph/CtrlShapeTextArt.cpp b/HwpFile/HwpDoc/Paragraph/CtrlShapeTextArt.cpp new file mode 100644 index 00000000000..7436ab86577 --- /dev/null +++ b/HwpFile/HwpDoc/Paragraph/CtrlShapeTextArt.cpp @@ -0,0 +1,94 @@ +#include "CtrlShapeTextArt.h" + +namespace HWP +{ +CCtrlShapeTextArt::CCtrlShapeTextArt() +{} + +CCtrlShapeTextArt::CCtrlShapeTextArt(const HWP_STRING& sCtrlID) + : CCtrlGeneralShape(sCtrlID) +{} + +CCtrlShapeTextArt::CCtrlShapeTextArt(const CCtrlGeneralShape& oShape) + : CCtrlGeneralShape(oShape) +{} + +CCtrlShapeTextArt::CCtrlShapeTextArt(const HWP_STRING& sCtrlID, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) + : CCtrlGeneralShape(sCtrlID, nSize, oBuffer, nOff, nVersion) +{} + +CCtrlShapeTextArt::CCtrlShapeTextArt(const HWP_STRING& sCtrlID, CXMLNode& oNode, int nVersion) + : CCtrlGeneralShape(sCtrlID, oNode, nVersion) +{ + m_sText = oNode.GetAttribute(L"text"); + + for (CXMLNode& oChild : oNode.GetChilds()) + { + if (L"hp:pt0" == oChild.GetName()) + { + m_oPt0.m_nX = oNode.GetAttributeInt(L"x"); + m_oPt0.m_nY = oNode.GetAttributeInt(L"y"); + } + else if (L"hp:pt1" == oChild.GetName()) + { + m_oPt1.m_nX = oNode.GetAttributeInt(L"x"); + m_oPt1.m_nY = oNode.GetAttributeInt(L"y"); + } + else if (L"hp:pt2" == oChild.GetName()) + { + m_oPt2.m_nX = oNode.GetAttributeInt(L"x"); + m_oPt2.m_nY = oNode.GetAttributeInt(L"y"); + } + else if (L"hp:pt3" == oChild.GetName()) + { + m_oPt3.m_nX = oNode.GetAttributeInt(L"x"); + m_oPt3.m_nY = oNode.GetAttributeInt(L"y"); + } + else if (L"hp:textartPr" == oChild.GetName()) + { + m_sFontName = oChild.GetAttribute(L"fontName"); + m_sFontStyle = oChild.GetAttribute(L"fontStyle"); + m_sFontType = oChild.GetAttribute(L"fontType"); + m_sTextShape = oChild.GetAttribute(L"textShape"); + m_sFontStyle = oChild.GetAttribute(L"fontStyle"); + m_shLineSpacing = oChild.GetAttributeInt(L"lineSpacing"); + m_shSpacing = oChild.GetAttributeInt(L"spacing"); + m_sAlign = oChild.GetAttribute(L"align"); + + //TODO:: реализовать shadows + } + else if (L"hp:outline" == oChild.GetName()) + { + std::vector arGrandChilds{oChild.GetChilds(L"hp:pt")}; + m_arOutline.resize(arGrandChilds.size()); + + for (unsigned int unIndex = 0; unIndex < arGrandChilds.size(); ++unIndex) + { + m_arOutline[unIndex].m_nX = arGrandChilds[unIndex].GetAttributeInt(L"x"); + m_arOutline[unIndex].m_nY = arGrandChilds[unIndex].GetAttributeInt(L"y"); + } + } + } +} + +EShapeType CCtrlShapeTextArt::GetShapeType() const +{ + return EShapeType::TextArt; +} + +int CCtrlShapeTextArt::ParseElement(CCtrlShapeTextArt& oObj, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) +{ + // TODO:: проверить + + // [HWP ambiguous] following 120bytes are unknown. + // Document doesn't mention about this at all. + + oBuffer.Skip(nSize); + return nSize; +} + +int CCtrlShapeTextArt::ParseCtrl(CCtrlShapeTextArt& oObj, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) +{ + return CCtrlGeneralShape::ParseCtrl(oObj, nSize, oBuffer, nOff, nVersion); +} +} diff --git a/HwpFile/HwpDoc/Paragraph/CtrlShapeTextArt.h b/HwpFile/HwpDoc/Paragraph/CtrlShapeTextArt.h new file mode 100644 index 00000000000..37ba39b5971 --- /dev/null +++ b/HwpFile/HwpDoc/Paragraph/CtrlShapeTextArt.h @@ -0,0 +1,40 @@ +#ifndef CTRLSHAPETEXTART_H +#define CTRLSHAPETEXTART_H + +#include "CtrlGeneralShape.h" +#include "Point.h" + +namespace HWP +{ +class CCtrlShapeTextArt : public CCtrlGeneralShape +{ + HWP_STRING m_sText; + TPoint m_oPt0; + TPoint m_oPt1; + TPoint m_oPt2; + TPoint m_oPt3; + + HWP_STRING m_sFontName; + HWP_STRING m_sFontStyle; + HWP_STRING m_sFontType; + HWP_STRING m_sTextShape; + short m_shLineSpacing; + short m_shSpacing; + HWP_STRING m_sAlign; + + std::vector m_arOutline; +public: + CCtrlShapeTextArt(); + CCtrlShapeTextArt(const HWP_STRING& sCtrlID); + CCtrlShapeTextArt(const CCtrlGeneralShape& oShape); + CCtrlShapeTextArt(const HWP_STRING& sCtrlID, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); + CCtrlShapeTextArt(const HWP_STRING& sCtrlID, CXMLNode& oNode, int nVersion); + + EShapeType GetShapeType() const override; + + static int ParseElement(CCtrlShapeTextArt& oObj, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); + static int ParseCtrl(CCtrlShapeTextArt& oObj, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); +}; +} + +#endif // CTRLSHAPETEXTART_H diff --git a/HwpFile/HwpDoc/Paragraph/CtrlShapeVideo.cpp b/HwpFile/HwpDoc/Paragraph/CtrlShapeVideo.cpp new file mode 100644 index 00000000000..afb2f8736a6 --- /dev/null +++ b/HwpFile/HwpDoc/Paragraph/CtrlShapeVideo.cpp @@ -0,0 +1,82 @@ +#include "CtrlShapeVideo.h" + +namespace HWP +{ +CCtrlShapeVideo::CCtrlShapeVideo(const HWP_STRING& sCtrlID) + : CCtrlGeneralShape(sCtrlID) +{} + +CCtrlShapeVideo::CCtrlShapeVideo(const CCtrlGeneralShape& oShape) + : CCtrlGeneralShape(oShape) +{} + +CCtrlShapeVideo::CCtrlShapeVideo(const HWP_STRING& sCtrlID, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) + : CCtrlGeneralShape(sCtrlID, nSize, oBuffer, nOff, nVersion) +{} + +CCtrlShapeVideo::CCtrlShapeVideo(const HWP_STRING& sCtrlID, CXMLNode& oNode, int nVersion) + : CCtrlGeneralShape(sCtrlID, oNode, nVersion) +{ + HWP_STRING sType = oNode.GetAttribute(L"videotype"); + + if (L"Local" == sType) + m_nVideoType = 0; + else if (L"Web" == sType) + m_nVideoType = 1; + + m_shVideoBinID = oNode.GetAttributeInt(L"fileIDRef"); + m_sThumnailBinID = oNode.GetAttribute(L"imageIDRef"); + + if (1 == m_nVideoType) + m_sWebURL = oNode.GetAttribute(L"tag"); +} + +EShapeType CCtrlShapeVideo::GetShapeType() const +{ + return EShapeType::Video; +} + +int CCtrlShapeVideo::GetVideoType() const +{ + return m_nVideoType; +} + +short CCtrlShapeVideo::GetVedeoBinID() const +{ + return m_shVideoBinID; +} + +HWP_STRING CCtrlShapeVideo::GetWebUrl() const +{ + return m_sWebURL; +} + +HWP_STRING CCtrlShapeVideo::GetThumnailBinID() const +{ + return m_sThumnailBinID; +} + +int CCtrlShapeVideo::ParseElement(CCtrlShapeVideo& oObj, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) +{ + oBuffer.SavePosition(); + + oBuffer.ReadInt(oObj.m_nVideoType); + + if (0 == oObj.m_nVideoType) + oBuffer.ReadShort(oObj.m_shVideoBinID); + else if (1 == oObj.m_nVideoType) + oBuffer.ReadString(oObj.m_sWebURL, EStringCharacter::UTF16); + + short m_sBinID; + oBuffer.ReadShort(m_sBinID); + oObj.m_sThumnailBinID = std::to_wstring(m_sBinID); + + oBuffer.Skip(nSize - oBuffer.GetDistanceToLastPos(true)); + return nSize; +} + +int CCtrlShapeVideo::ParseCtrl(CCtrlShapeVideo& oObj, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) +{ + return CCtrlObjElement::ParseCtrl(oObj, nSize, oBuffer, nOff, nVersion); +} +} diff --git a/HwpFile/HwpDoc/Paragraph/CtrlShapeVideo.h b/HwpFile/HwpDoc/Paragraph/CtrlShapeVideo.h new file mode 100644 index 00000000000..d3716a2bfe4 --- /dev/null +++ b/HwpFile/HwpDoc/Paragraph/CtrlShapeVideo.h @@ -0,0 +1,32 @@ +#ifndef CTRLSHAPEVIDEO_H +#define CTRLSHAPEVIDEO_H + +#include "CtrlGeneralShape.h" + +namespace HWP +{ +class CCtrlShapeVideo : public CCtrlGeneralShape +{ + int m_nVideoType; + short m_shVideoBinID; + HWP_STRING m_sWebURL; + HWP_STRING m_sThumnailBinID; +public: + CCtrlShapeVideo(const HWP_STRING& sCtrlID); + CCtrlShapeVideo(const CCtrlGeneralShape& oShape); + CCtrlShapeVideo(const HWP_STRING& sCtrlID, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); + CCtrlShapeVideo(const HWP_STRING& sCtrlID, CXMLNode& oNode, int nVersion); + + EShapeType GetShapeType() const override; + + int GetVideoType() const; + short GetVedeoBinID() const; + HWP_STRING GetWebUrl() const; + HWP_STRING GetThumnailBinID() const; + + static int ParseElement(CCtrlShapeVideo& oObj, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); + static int ParseCtrl(CCtrlShapeVideo& oObj, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); +}; +} + +#endif // CTRLSHAPEVIDEO_H diff --git a/HwpFile/HwpDoc/Paragraph/CtrlTable.cpp b/HwpFile/HwpDoc/Paragraph/CtrlTable.cpp new file mode 100644 index 00000000000..0aafd41c9fe --- /dev/null +++ b/HwpFile/HwpDoc/Paragraph/CtrlTable.cpp @@ -0,0 +1,195 @@ +#include "CtrlTable.h" + +namespace HWP +{ +CCtrlTable::CCtrlTable(const HWP_STRING& sCtrlID) + : CCtrlCommon(sCtrlID) +{} + +CCtrlTable::CCtrlTable(const HWP_STRING& sCtrlID, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) + : CCtrlCommon(sCtrlID, nSize, oBuffer, nOff, nVersion) +{} + +CCtrlTable::CCtrlTable(const HWP_STRING& sCtrlID, CXMLNode& oNode, int nVersion) + : CCtrlCommon(sCtrlID, oNode, nVersion) +{ + m_shNRows = oNode.GetAttributeInt(L"rowCnt"); + m_shNCols = oNode.GetAttributeInt(L"colCnt"); + m_shCellSpacing = oNode.GetAttributeInt(L"cellSpacing"); + m_shBorderFillID = oNode.GetAttributeInt(L"borderFillIDRef"); + + for (CXMLNode& oChild : oNode.GetChilds()) + { + if (L"hp:inMargin" == oChild.GetName()) + { + m_shInLSpace = oChild.GetAttributeInt(L"left"); + m_shInRSpace = oChild.GetAttributeInt(L"right"); + m_shInTSpace = oChild.GetAttributeInt(L"top"); + m_shInBSpace = oChild.GetAttributeInt(L"bottom"); + } + else if (L"hp:cellzoneList" == oChild.GetName()) + { + for (CXMLNode& oGrandChild : oChild.GetChilds(L"hp:cellzone")) + { + TCellZone* pCellZone = new TCellZone(); + + pCellZone->m_shStartRowAddr = oGrandChild.GetAttributeInt(L"startRowAddr"); + pCellZone->m_shStartColAddr = oGrandChild.GetAttributeInt(L"startColAddr"); + pCellZone->m_shEndRowAddr = oGrandChild.GetAttributeInt(L"endRowAddr"); + pCellZone->m_shEndColAddr = oGrandChild.GetAttributeInt(L"endColAddr"); + pCellZone->m_shBorderFillIDRef = oGrandChild.GetAttributeInt(L"borderFillIDRef"); + + m_arCellzoneList.push_back(pCellZone); + } + } + else if(L"hp:tr" == oChild.GetName()) + { + for (CXMLNode& oGrandChild : oChild.GetChilds(L"hp:tc")) + m_arCells.push_back(new CTblCell(oGrandChild, nVersion)); + } + } +} + +CCtrlTable::~CCtrlTable() +{ + for (TCellZone* pCellzone : m_arCellzoneList) + { + if (nullptr != pCellzone) + delete pCellzone; + } + + for (CTblCell* pTblCell : m_arCells) + { + if (nullptr != pTblCell) + delete pTblCell; + } +} + +ECtrlObjectType CCtrlTable::GetCtrlType() const +{ + return ECtrlObjectType::Table; +} + +bool CCtrlTable::Empty() const +{ + return m_arCells.empty(); +} + +short CCtrlTable::GetRows() const +{ + return m_shNRows; +} + +short CCtrlTable::GetCols() const +{ + return m_shNCols; +} + +short CCtrlTable::GetColsInRow(short shRowIndex) const +{ + if (shRowIndex >= m_arRowSize.size()) + return 1; + + return m_arRowSize[shRowIndex]; +} + +short CCtrlTable::GetCountCells() const +{ + return m_arCells.size(); +} + +short CCtrlTable::GetBorderFillID() const +{ + return m_shBorderFillID; +} + +void CCtrlTable::AddCell(CTblCell* pCell) +{ + m_arCells.push_back(pCell); +} + +bool CCtrlTable::HaveCells() +{ + return !m_arCells.empty(); +} + +const CTblCell* CCtrlTable::GetCell(unsigned int unIndex) const +{ + if (unIndex >= m_arCells.size()) + return nullptr; + + return m_arCells[unIndex]; +} + +CTblCell* CCtrlTable::GetLastCell() +{ + return (!m_arCells.empty()) ? m_arCells.back() : nullptr; +} + +int CCtrlTable::ParseCtrl(CCtrlTable& oObj, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) +{ + oBuffer.SavePosition(); + + oBuffer.ReadInt(oObj.m_nAttr); + oBuffer.ReadShort(oObj.m_shNRows); + oBuffer.ReadShort(oObj.m_shNCols); + oBuffer.ReadShort(oObj.m_shCellSpacing); + oBuffer.ReadShort(oObj.m_shInLSpace); + oBuffer.ReadShort(oObj.m_shInRSpace); + oBuffer.ReadShort(oObj.m_shInTSpace); + oBuffer.ReadShort(oObj.m_shInBSpace); + + oObj.m_arRowSize.resize(oObj.m_shNRows); + for (unsigned int unIndex = 0; unIndex < oObj.m_shNRows; ++unIndex) + oBuffer.ReadShort(oObj.m_arRowSize[unIndex]); + + oBuffer.ReadShort(oObj.m_shBorderFillID); + + if (nVersion >= 5010 && (oBuffer.GetDistanceToLastPos() < nSize)) + { + oBuffer.ReadShort(oObj.m_shValidZoneSize); + + if (0 < oObj.m_shValidZoneSize && (oBuffer.GetDistanceToLastPos() < nSize)) + { + for (unsigned int unIndex = 0; unIndex < oObj.m_shValidZoneSize; ++unIndex) + { + TCellZone *pCellZone = new TCellZone(); + + if (nullptr == pCellZone) + continue; + + oBuffer.ReadShort(pCellZone->m_shStartRowAddr); + oBuffer.ReadShort(pCellZone->m_shStartColAddr); + oBuffer.ReadShort(pCellZone->m_shEndRowAddr); + oBuffer.ReadShort(pCellZone->m_shEndColAddr); + oBuffer.ReadShort(pCellZone->m_shBorderFillIDRef); + + oObj.m_arCellzoneList.push_back(pCellZone); + } + } + } + + oObj.m_bFullFilled = true; + + oBuffer.Skip(nSize - oBuffer.GetDistanceToLastPos(true)); + return nSize; +} + +int CCtrlTable::ParseListHeaderAppend(CCtrlTable& oObj, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) +{ + if (24 != nSize) + { + oBuffer.Skip(nSize); + return nSize; + } + + oBuffer.Skip(2); + oBuffer.ReadInt(oObj.m_nCaptionAttr); + oBuffer.ReadInt(oObj.m_nCaptionWidth); + oObj.m_nCaptionSpacing = oBuffer.ReadShort(); + oBuffer.ReadInt(oObj.m_nCaptionMaxW); + oBuffer.Skip(8); + + return nSize; +} +} diff --git a/HwpFile/HwpDoc/Paragraph/CtrlTable.h b/HwpFile/HwpDoc/Paragraph/CtrlTable.h new file mode 100644 index 00000000000..f0fc18742ec --- /dev/null +++ b/HwpFile/HwpDoc/Paragraph/CtrlTable.h @@ -0,0 +1,59 @@ +#ifndef CTRLTABLE_H +#define CTRLTABLE_H + +#include "TblCell.h" + +namespace HWP +{ +struct TCellZone +{ + short m_shStartRowAddr; + short m_shStartColAddr;; + short m_shEndRowAddr; + short m_shEndColAddr; + short m_shBorderFillIDRef; +}; + +class CCtrlTable : public CCtrlCommon +{ + int m_nAttr; + short m_shNRows; + short m_shNCols; + short m_shCellSpacing; + short m_shInLSpace; + short m_shInRSpace; + short m_shInTSpace; + short m_shInBSpace; + VECTOR m_arRowSize; + short m_shBorderFillID; + short m_shValidZoneSize; + VECTOR m_arCellzoneList; + VECTOR m_arCells; +public: + CCtrlTable(const HWP_STRING& sCtrlID); + CCtrlTable(const HWP_STRING& sCtrlID, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); + CCtrlTable(const HWP_STRING& sCtrlID, CXMLNode& oNode, int nVersion); + ~CCtrlTable(); + + ECtrlObjectType GetCtrlType() const override; + + bool Empty() const; + short GetRows() const; + short GetCols() const; + short GetColsInRow(short shRowIndex) const; + short GetCountCells() const; + short GetBorderFillID() const; + + void AddCell(CTblCell* pCell); + + bool HaveCells(); + + const CTblCell* GetCell(unsigned int unIndex) const; + CTblCell* GetLastCell(); + + static int ParseCtrl(CCtrlTable& oObj, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); + static int ParseListHeaderAppend(CCtrlTable& oObj, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); +}; +} + +#endif // CTRLTABLE_H diff --git a/HwpFile/HwpDoc/Paragraph/HWPPargraph.cpp b/HwpFile/HwpDoc/Paragraph/HWPPargraph.cpp new file mode 100644 index 00000000000..01fdbe30ee4 --- /dev/null +++ b/HwpFile/HwpDoc/Paragraph/HWPPargraph.cpp @@ -0,0 +1,322 @@ +#include "HWPPargraph.h" +#include + +#include "CtrlCharacter.h" +#include "CtrlSectionDef.h" +#include "CtrlContainer.h" +#include "CtrlShapePic.h" +#include "CtrlTable.h" +#include "CtrlEqEdit.h" +#include "CtrlShapeArc.h" +#include "CtrlShapeConnectLine.h" +#include "CtrlShapeCurve.h" +#include "CtrlShapeEllipse.h" +#include "CtrlShapeLine.h" +#include "CtrlShapeOle.h" +#include "CtrlShapePolygon.h" +#include "CtrlShapeRect.h" +#include "CtrlShapeTextArt.h" +#include "CtrlShapeVideo.h" +#include "ParaText.h" + +namespace HWP +{ +CHWPPargraph::CHWPPargraph() + : m_pLineSegs(nullptr) +{} + +CHWPPargraph::CHWPPargraph(CXMLNode& oNode, int nVersion) + : m_chBreakType(0), m_pLineSegs(nullptr) +{ + m_shParaShapeID = oNode.GetAttributeInt(L"paraPrIDRef"); + m_shParaStyleID = oNode.GetAttributeInt(L"styleIDRef"); + + if (oNode.GetAttributeBool(L"pageBreak")) + m_chBreakType |= 0b00000100; + else + m_chBreakType &= 0b11111011; + + if (oNode.GetAttributeBool(L"columnBreak")) + m_chBreakType |= 0b00001000; + else + m_chBreakType &= 0b11110111; + + int nCharShapeID = 0; + + for (CXMLNode& oChild : oNode.GetChilds()) + { + if (L"hp:run" == oChild.GetName()) + { + nCharShapeID = oChild.GetAttributeInt(L"charPrIDRef"); + + for (CXMLNode& oGrandChild : oChild.GetChilds()) + ParseHWPParagraph(oGrandChild, nCharShapeID, nVersion); + } + else if (L"hp:linesegarray" == oChild.GetName()) + { + CXMLNode oGrandChild{oChild.GetChild(L"hp:lineseg")}; + m_pLineSegs = new CLineSeg(oGrandChild, nVersion); + } + } + + if (m_arP.empty() || ECtrlObjectType::Character != m_arP.back()->GetCtrlType()) + m_arP.push_back(new CCtrlCharacter(L" _", ECtrlCharType::PARAGRAPH_BREAK)); +} + +CHWPPargraph::~CHWPPargraph() +{ + if (nullptr != m_pLineSegs) + delete m_pLineSegs; +} + +bool CHWPPargraph::ParseHWPParagraph(CXMLNode& oNode, int nCharShapeID, int nVersion) +{ + const size_t unCurrentParaCount = m_arP.size(); + + if (L"hp:secPr" == oNode.GetName()) + m_arP.push_back(new CCtrlSectionDef(L"dces", oNode, nVersion)); + else if (L"hp:ctrl" == oNode.GetName()) + { + for(CXMLNode& oChild : oNode.GetChilds()) + AddCtrl(CCtrl::GetCtrl(oChild, nVersion)); + } + else if (L"hp:t" == oNode.GetName()) + { + m_arP.push_back(new CParaText(L"____", oNode.GetText(), 0, nCharShapeID)); + + for(CXMLNode& oChild : oNode.GetChilds()) + { + if (L"hp:lineBreak" == oChild.GetName()) + m_arP.push_back(new CCtrlCharacter(L" _", ECtrlCharType::LINE_BREAK)); + else if (L"hp:hyphen" == oChild.GetName()) + m_arP.push_back(new CCtrlCharacter(L" _", ECtrlCharType::HARD_HYPHEN)); + else if (L"hp:nbSpace" == oChild.GetName()|| + L"hp:fwSpace" == oChild.GetName()) + m_arP.push_back(new CCtrlCharacter(L" _", ECtrlCharType::HARD_SPACE)); + else if (L"hp:tab" == oChild.GetName()) + m_arP.push_back(new CParaText(L"____", L"\t", 0)); + } + } + else if (L"hp:tbl" == oNode.GetName()) + m_arP.push_back(new CCtrlTable(L" lbt", oNode, nVersion)); + else if (L"hp:pic" == oNode.GetName()) + m_arP.push_back(new CCtrlShapePic(L"cip$", oNode, nVersion)); + else if (L"hp:container" == oNode.GetName()) + m_arP.push_back(new CCtrlContainer(L"noc$", oNode, nVersion)); + else if (L"hp:ole" == oNode.GetName()) + m_arP.push_back(new CCtrlShapeOle(L"elo$", oNode, nVersion)); + else if (L"hp:equation" == oNode.GetName()) + m_arP.push_back(new CCtrlEqEdit(L"deqe", oNode, nVersion)); + else if (L"hp:line" == oNode.GetName()) + m_arP.push_back(new CCtrlShapeLine(L"nil$", oNode, nVersion)); + else if (L"hp:rect" == oNode.GetName()) + m_arP.push_back(new CCtrlShapeRect(L"cer$", oNode, nVersion)); + else if (L"hp:ellipse" == oNode.GetName()) + m_arP.push_back(new CCtrlShapeEllipse(L"lle$", oNode, nVersion)); + else if (L"hp:arc" == oNode.GetName()) + m_arP.push_back(new CCtrlShapeArc(L"cra$", oNode, nVersion)); + else if (L"hp:polygon" == oNode.GetName()) + m_arP.push_back(new CCtrlShapePolygon(L"lop$", oNode, nVersion)); + else if (L"hp:curve" == oNode.GetName()) + m_arP.push_back(new CCtrlShapeCurve(L"ruc$", oNode, nVersion)); + else if (L"hp:connectLine" == oNode.GetName()) + m_arP.push_back(new CCtrlShapeConnectLine(L"loc$", oNode, nVersion)); + else if (L"hp:textart" == oNode.GetName()) + m_arP.push_back(new CCtrlShapeTextArt(L"tat$", oNode, nVersion)); + else if (L"hp:video" == oNode.GetName()) + m_arP.push_back(new CCtrlShapeVideo(L"div$", oNode, nVersion)); + + if (unCurrentParaCount != m_arP.size()) + return true; + + if (L"hp:switch" == oNode.GetName()) + { + for (CXMLNode& oCaseChild : oNode.GetChilds(L"hp:case")) + { + for (CXMLNode& oChild : oCaseChild.GetChilds()) + if (ParseHWPParagraph(oChild, nCharShapeID, nVersion)) + return true; + } + + CXMLNode oDefaultChild{oNode.GetChild(L"hp:default")}; + for (CXMLNode& oChild : oDefaultChild.GetChilds()) + if (ParseHWPParagraph(oChild, nCharShapeID, nVersion)) + return true; + } + + return false; +} + + +EParagraphType CHWPPargraph::GetType() const +{ + return EParagraphType::Normal; +} + +void CHWPPargraph::SetLineSeg(CLineSeg* pLineSeg) +{ + if (nullptr != m_pLineSegs) + delete m_pLineSegs; + + m_pLineSegs = pLineSeg; +} + +void CHWPPargraph::AddRangeTag(const TRangeTag& oRangeTag) +{ + m_arRangeTags.push_back(oRangeTag); +} + +void CHWPPargraph::AddCtrl(CCtrl* pCtrl) +{ + if (nullptr != pCtrl) + m_arP.push_back(pCtrl); +} + +void CHWPPargraph::AddCtrls(const LIST& arCtrls) +{ + m_arP.insert(m_arP.end(), arCtrls.begin(), arCtrls.end()); +} + +bool CHWPPargraph::SetCtrl(CCtrl* pCtrl, unsigned int unIndex) +{ + if (unIndex >= m_arP.size() || nullptr == pCtrl) + return false; + + CCtrl* pOldCtrl = m_arP[unIndex]; + + if (nullptr != pOldCtrl) + delete pOldCtrl; + + m_arP[unIndex] = pCtrl; + + return true; +} + +VECTOR& CHWPPargraph::GetCtrls() +{ + return m_arP; +} + +std::vector CHWPPargraph::GetCtrls() const +{ + RETURN_VECTOR_CONST_PTR(CCtrl, m_arP); +} + +unsigned int CHWPPargraph::GetCountCtrls() const +{ + return m_arP.size(); +} + +short CHWPPargraph::GetShapeID() const +{ + return m_shParaShapeID; +} + +short CHWPPargraph::GetStyleID() const +{ + return m_shParaStyleID; +} + +HWP_BYTE CHWPPargraph::GetBreakType() const +{ + return m_chBreakType; +} + +const CLineSeg* CHWPPargraph::GetLineSeg() const +{ + return m_pLineSegs; +} + +VECTOR CHWPPargraph::GetRangeTags() const +{ + return m_arRangeTags; +} + +CHWPPargraph* CHWPPargraph::Parse(int nTagNum, int nLevel, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) +{ + CHWPPargraph *pPara = new CHWPPargraph(); + + if (nullptr == pPara) + return nullptr; + + oBuffer.SavePosition(); + Parse(*pPara, nSize, oBuffer, nOff, nVersion); + oBuffer.Skip(-oBuffer.GetDistanceToLastPos(true)); + + return pPara; +} + +int CHWPPargraph::Parse(CHWPPargraph& oPara, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) +{ + oBuffer.SavePosition(); + + oBuffer.Skip(4); // nChars + + int nControlMask; + oBuffer.ReadInt(nControlMask); + + oBuffer.ReadShort(oPara.m_shParaShapeID); + oPara.m_shParaStyleID = (short)(oBuffer.ReadByte() & 0x00FF); + oBuffer.ReadByte(oPara.m_chBreakType); + + short shNCharShapeInfo; + oBuffer.ReadShort(shNCharShapeInfo); + + short shNRangeTags; + oBuffer.ReadShort(shNRangeTags); + + short shNLineSeg; + oBuffer.ReadShort(shNLineSeg); + + int nParaInstanceID; + oBuffer.ReadInt(nParaInstanceID); + + if (nVersion >= 5032 && oBuffer.GetDistanceToLastPos() < nSize) + { + short shCangeTrackingMerge; + oBuffer.ReadShort(shCangeTrackingMerge); + } + + oBuffer.Skip(nSize - oBuffer.GetDistanceToLastPos(true)); + return nSize; +} + +CCtrl* CHWPPargraph::FindFirstElement(const HWP_STRING& sID, bool bFullfilled, unsigned int& nIndex) const +{ + for (VECTOR::const_iterator itCtrl = m_arP.cbegin(); itCtrl != m_arP.cend(); ++itCtrl) + { + if (sID == (*itCtrl)->GetID() && bFullfilled == (*itCtrl)->FullFilled()) + { + nIndex = itCtrl - m_arP.cbegin(); + return (*itCtrl); + } + } + + return nullptr; +} + +CCtrl* CHWPPargraph::FindLastElement(const HWP_STRING& sID) +{ + for (VECTOR::const_reverse_iterator itCtrl = m_arP.crbegin(); itCtrl != m_arP.crend(); ++itCtrl) + { + if (sID == (*itCtrl)->GetID()) + return (*itCtrl); + } + + return nullptr; +} + +int CHWPPargraph::IndexOf(CCtrl* pCtrl) +{ + if (nullptr == pCtrl || m_arP.empty()) + return -1; + + VECTOR::const_iterator itFound = std::find_if(m_arP.cbegin(), m_arP.cend(), [pCtrl](CCtrl *pCurrCtrl){ return CCtrl::Equals(pCurrCtrl, pCtrl); }); + + if (itFound != m_arP.cend()) + return itFound - m_arP.cbegin(); + + return -1; +} + +} diff --git a/HwpFile/HwpDoc/Paragraph/HWPPargraph.h b/HwpFile/HwpDoc/Paragraph/HWPPargraph.h new file mode 100644 index 00000000000..7a18af03067 --- /dev/null +++ b/HwpFile/HwpDoc/Paragraph/HWPPargraph.h @@ -0,0 +1,68 @@ +#ifndef HWPPARGRAPH_H +#define HWPPARGRAPH_H + +#include "LineSeg.h" +#include "RangeTag.h" +#include "Ctrl.h" +#include "../Common/XMLNode.h" + +namespace HWP +{ +enum class EParagraphType +{ + Normal, + Cap, + Cell +}; + +class CHWPPargraph : public IRef +{ + short m_shParaShapeID; // HWPTAG_PARA_HEADER + short m_shParaStyleID; // HWPTAG_PARA_HEADER + HWP_BYTE m_chBreakType; // HWPTAG_PARA_HEADER + + CLineSeg *m_pLineSegs; // HWPTAG_PARA_LINE_SEG + VECTOR m_arRangeTags; // HWPTAG_PARA_RANGE_TAG + + VECTOR m_arP; //HWPTAG_PARA_TEXT + + bool ParseHWPParagraph(CXMLNode& oNode, int nCharShapeID, int nVersion); +public: + CHWPPargraph(); + CHWPPargraph(CXMLNode& oNode, int nVersion); + virtual ~CHWPPargraph(); + + virtual EParagraphType GetType() const; + + void SetLineSeg(CLineSeg* pLineSeg); + + void AddRangeTag(const TRangeTag& oRangeTag); + + void AddCtrl(CCtrl* pCtrl); + void AddCtrls(const LIST& arCtrls); + + bool SetCtrl(CCtrl* pCtrl, unsigned int unIndex); + + VECTOR& GetCtrls(); + VECTOR GetCtrls() const; + + unsigned int GetCountCtrls() const; + short GetShapeID() const; + short GetStyleID() const; + HWP_BYTE GetBreakType() const; + + const CLineSeg* GetLineSeg() const; + + VECTOR GetRangeTags() const; + + static CHWPPargraph* Parse(int nTagNum, int nLevel, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); + static int Parse(CHWPPargraph& oPara, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); + + CCtrl* FindFirstElement(const HWP_STRING& sID, bool bFullfilled, unsigned int& nIndex) const; + CCtrl* FindLastElement(const HWP_STRING& sID); + + int IndexOf(CCtrl* pCtrl); +}; +} + +#endif // HWPPARGRAPH_H diff --git a/HwpFile/HwpDoc/Paragraph/LineSeg.cpp b/HwpFile/HwpDoc/Paragraph/LineSeg.cpp new file mode 100644 index 00000000000..b781577bb91 --- /dev/null +++ b/HwpFile/HwpDoc/Paragraph/LineSeg.cpp @@ -0,0 +1,34 @@ +#include "LineSeg.h" + +namespace HWP +{ +CLineSeg::CLineSeg(int nTagNum, int nLevel, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) +{ + oBuffer.SavePosition(); + + oBuffer.ReadInt(m_nStartPos); + oBuffer.ReadInt(m_nLineVerticalPos); + oBuffer.ReadInt(m_nLineHeight); + oBuffer.ReadInt(m_nTextHeight); + oBuffer.ReadInt(m_nLineDistanceToBase); + oBuffer.ReadInt(m_nLineSpacing); + oBuffer.ReadInt(m_nColumnStartPos); + oBuffer.ReadInt(m_nSegmentWidth); + oBuffer.ReadInt(m_nLineTag); + m_bIsHeadingApplied = CHECK_FLAG(m_nLineTag >> 21, 0x01); + + oBuffer.Skip(nSize - oBuffer.GetDistanceToLastPos(true)); +} + +CLineSeg::CLineSeg(CXMLNode& oNode, int nVersion) +{ + //TODO:: реализовать + m_nLineSpacing = oNode.GetAttributeInt(L"spacing"); + m_nTextHeight = oNode.GetAttributeInt(L"textheight"); +} + +int CLineSeg::GetLineSpacing() const +{ + return m_nLineSpacing; +} +} diff --git a/HwpFile/HwpDoc/Paragraph/LineSeg.h b/HwpFile/HwpDoc/Paragraph/LineSeg.h new file mode 100644 index 00000000000..56419e161be --- /dev/null +++ b/HwpFile/HwpDoc/Paragraph/LineSeg.h @@ -0,0 +1,29 @@ +#ifndef LINESEG_H +#define LINESEG_H + +#include "../HWPStream.h" +#include "../Common/XMLNode.h" + +namespace HWP +{ +class CLineSeg +{ + int m_nStartPos; + int m_nLineVerticalPos; + int m_nLineHeight; + int m_nTextHeight; + int m_nLineDistanceToBase; + int m_nLineSpacing; + int m_nColumnStartPos; + int m_nSegmentWidth; + int m_nLineTag; + bool m_bIsHeadingApplied; +public: + CLineSeg(int nTagNum, int nLevel, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); + CLineSeg(CXMLNode& oNode, int nVersion); + + int GetLineSpacing() const; +}; +} + +#endif // LINESEG_H diff --git a/HwpFile/HwpDoc/Paragraph/ParaText.cpp b/HwpFile/HwpDoc/Paragraph/ParaText.cpp new file mode 100644 index 00000000000..3f1a83171a5 --- /dev/null +++ b/HwpFile/HwpDoc/Paragraph/ParaText.cpp @@ -0,0 +1,47 @@ +#include "ParaText.h" + +namespace HWP +{ +CParaText::CParaText(const HWP_STRING& sCtrlID, const HWP_STRING& sText, int nStartIDx) + : CCtrl(sCtrlID), m_sText(sText), m_nStartIDx(nStartIDx) +{} + +CParaText::CParaText(const HWP_STRING& sCtrlID, const HWP_STRING& sText, int nStartIDx, int nCharShapeID) + : CCtrl(sCtrlID), m_sText(sText), m_nStartIDx(nStartIDx), m_nCharShapeID(nCharShapeID) +{} + +ECtrlObjectType CParaText::GetCtrlType() const +{ + return ECtrlObjectType::ParaText; +} + +unsigned int CParaText::GetTextLength() const +{ + return m_sText.length(); +} + +int CParaText::GetStartIDx() const +{ + return m_nStartIDx; +} + +int CParaText::GetCharShapeID() const +{ + return m_nCharShapeID; +} + +HWP_STRING CParaText::GetText() const +{ + return m_sText; +} + +void CParaText::SetCharShapeID(int nCharShapeID) +{ + m_nCharShapeID = nCharShapeID; +} + +void CParaText::SetText(const HWP_STRING& sText) +{ + m_sText = sText; +} +} diff --git a/HwpFile/HwpDoc/Paragraph/ParaText.h b/HwpFile/HwpDoc/Paragraph/ParaText.h new file mode 100644 index 00000000000..91b50af5498 --- /dev/null +++ b/HwpFile/HwpDoc/Paragraph/ParaText.h @@ -0,0 +1,30 @@ +#ifndef PARATEXT_H +#define PARATEXT_H + +#include "Ctrl.h" + +namespace HWP +{ +class CParaText : public CCtrl +{ + HWP_STRING m_sText; + int m_nStartIDx; + int m_nCharShapeID; +public: + CParaText(const HWP_STRING& sCtrlID, const HWP_STRING& sText, int nStartIDx); + CParaText(const HWP_STRING& sCtrlID, const HWP_STRING& sText, int nStartIDx, int nCharShapeID); + + ECtrlObjectType GetCtrlType() const override; + + unsigned int GetTextLength() const; + + int GetStartIDx() const; + int GetCharShapeID() const; + HWP_STRING GetText() const; + + void SetCharShapeID(int nCharShapeID); + void SetText(const HWP_STRING& sText); +}; +} + +#endif // PARATEXT_H diff --git a/HwpFile/HwpDoc/Paragraph/Point.h b/HwpFile/HwpDoc/Paragraph/Point.h new file mode 100644 index 00000000000..4dacef02577 --- /dev/null +++ b/HwpFile/HwpDoc/Paragraph/Point.h @@ -0,0 +1,13 @@ +#ifndef POINT_H +#define POINT_H + +namespace HWP +{ +struct TPoint +{ + int m_nX; + int m_nY; +}; +} + +#endif // POINT_H diff --git a/HwpFile/HwpDoc/Paragraph/RangeTag.h b/HwpFile/HwpDoc/Paragraph/RangeTag.h new file mode 100644 index 00000000000..a5c5b3d2c10 --- /dev/null +++ b/HwpFile/HwpDoc/Paragraph/RangeTag.h @@ -0,0 +1,17 @@ +#ifndef RANGETAG_H +#define RANGETAG_H + +#include "../Common/Common.h" + +namespace HWP +{ +struct TRangeTag +{ + int m_nStartPos; + int m_nEndPos; + HWP_BYTE m_chType; + HWP_BYTE m_arData[3]; +}; +} + +#endif // RANGETAG_H diff --git a/HwpFile/HwpDoc/Paragraph/TblCell.cpp b/HwpFile/HwpDoc/Paragraph/TblCell.cpp new file mode 100644 index 00000000000..2d0ffd922a5 --- /dev/null +++ b/HwpFile/HwpDoc/Paragraph/TblCell.cpp @@ -0,0 +1,136 @@ +#include "TblCell.h" +#include "CtrlCharacter.h" + +namespace HWP +{ +CTblCell::CTblCell(int nSize, CHWPStream& oBuffer, int nOff, int nVersion) + : m_nSize(nSize) +{ + oBuffer.SavePosition(); + + oBuffer.Skip(2); + + oBuffer.ReadShort(m_shColAddr); + oBuffer.ReadShort(m_shRowAddr); + oBuffer.ReadShort(m_shColSpan); + oBuffer.ReadShort(m_shRowSpan); + oBuffer.ReadInt(m_nWidth); + oBuffer.ReadInt(m_nHeight); + + for (unsigned int unIndex = 0; unIndex < 4; ++unIndex) + m_arMargin[unIndex] = oBuffer.ReadShort(); + + oBuffer.ReadShort(m_shBorderFill); + + oBuffer.Skip(nSize - oBuffer.GetDistanceToLastPos(true)); +} + +CTblCell::CTblCell(CXMLNode& oNode, int nVersion) +{ + m_shBorderFill = oNode.GetAttributeInt(L"borderFillIDRef"); + + for (CXMLNode& oChild : oNode.GetChilds()) + { + if (L"hp:cellAddr" == oChild.GetName()) + { + m_shColAddr = oChild.GetAttributeInt(L"colAddr"); + m_shRowAddr = oChild.GetAttributeInt(L"rowAddr"); + } + else if (L"hp:cellSpan" == oChild.GetName()) + { + m_shColSpan = oChild.GetAttributeInt(L"colSpan"); + m_shRowSpan = oChild.GetAttributeInt(L"rowSpan"); + } + else if (L"hp:cellSz" == oChild.GetName()) + { + m_nWidth = oChild.GetAttributeInt(L"width"); + m_nHeight = oChild.GetAttributeInt(L"height"); + } + else if (L"hp:cellMargin" == oChild.GetName()) + { + m_arMargin[0] = oChild.GetAttributeInt(L"left"); + m_arMargin[1] = oChild.GetAttributeInt(L"rifht"); + m_arMargin[2] = oChild.GetAttributeInt(L"top"); + m_arMargin[3] = oChild.GetAttributeInt(L"bottom"); + } + else if (L"hp:subList" == oChild.GetName()) + { + m_eVertAlign = ::HWP::GetVertAlign(oChild.GetAttributeInt(L"vertAlign")); + + for (CXMLNode& oGrandChild : oChild.GetChilds(L"hp:p")) + { + CCellParagraph *pCellParagraphs = new CCellParagraph(oGrandChild, nVersion); + + if (nullptr == pCellParagraphs) + continue; + + if (ECtrlObjectType::Character != pCellParagraphs->GetCtrls().back()->GetCtrlType()) + pCellParagraphs->AddCtrl(new CCtrlCharacter(L" _", ECtrlCharType::PARAGRAPH_BREAK)); + + m_arParas.push_back(pCellParagraphs); + } + } + } +} + +void CTblCell::SetVertAlign(EVertAlign eVertAlign) +{ + m_eVertAlign = eVertAlign; +} + +void CTblCell::AddParagraph(CCellParagraph* pParagraph) +{ + m_arParas.push_back(pParagraph); +} + +int CTblCell::GetSize() +{ + return m_nSize; +} + +short CTblCell::GetColAddr() const +{ + return m_shColAddr; +} + +short CTblCell::GetRowAddr() const +{ + return m_shRowAddr; +} + +short CTblCell::GetColSpan() const +{ + return m_shColSpan; +} + +short CTblCell::GetRowSpan() const +{ + return m_shRowSpan; +} + +VECTOR CTblCell::GetParagraphs() const +{ + return m_arParas; +} + +int CTblCell::GetWidth() const +{ + return m_nWidth; +} + +int CTblCell::GetHeight() const +{ + return m_nHeight; +} + +EVertAlign CTblCell::GetVertAlign() const +{ + return m_eVertAlign; +} + +short CTblCell::GetBorderFillID() const +{ + return m_shBorderFill; +} + +} diff --git a/HwpFile/HwpDoc/Paragraph/TblCell.h b/HwpFile/HwpDoc/Paragraph/TblCell.h new file mode 100644 index 00000000000..dc056d0c9eb --- /dev/null +++ b/HwpFile/HwpDoc/Paragraph/TblCell.h @@ -0,0 +1,47 @@ +#ifndef TBLCELL_H +#define TBLCELL_H + +#include "CellParagraph.h" +#include "CtrlCommon.h" + +namespace HWP +{ +class CTblCell +{ + int m_nSize; + + short m_shColAddr; + short m_shRowAddr; + short m_shColSpan; + short m_shRowSpan; + int m_nWidth; + int m_nHeight; + int m_arMargin[4]; + short m_shBorderFill; + VECTOR m_arParas; + EVertAlign m_eVertAlign; + + HWP_STRING m_sMergedColName; +public: + CTblCell(int nSize, CHWPStream& oBuffer, int nOff, int nVersion); + CTblCell(CXMLNode& oNode, int nVersion); + + void SetVertAlign(EVertAlign eVertAlign); + + void AddParagraph(CCellParagraph* pParagraph); + + int GetSize(); + + short GetColAddr() const; + short GetRowAddr() const; + short GetColSpan() const; + short GetRowSpan() const; + VECTOR GetParagraphs() const; + int GetWidth() const; + int GetHeight() const; + EVertAlign GetVertAlign() const; + short GetBorderFillID() const; +}; +} + +#endif // TBLCELL_H diff --git a/HwpFile/HwpDoc/Section/NoteShape.cpp b/HwpFile/HwpDoc/Section/NoteShape.cpp new file mode 100644 index 00000000000..f4955d2a6a1 --- /dev/null +++ b/HwpFile/HwpDoc/Section/NoteShape.cpp @@ -0,0 +1,65 @@ +#include "NoteShape.h" + +namespace HWP +{ +ENoteNumbering GetNoteNumbering(int nValue) +{ + switch(static_cast(nValue)) + { + case ENoteNumbering::CONTINUOUS: return ENoteNumbering::CONTINUOUS; + case ENoteNumbering::ON_SECTION: return ENoteNumbering::ON_SECTION; + case ENoteNumbering::ON_PAGE: return ENoteNumbering::ON_PAGE; + default: + return ENoteNumbering::UNKNOWN; + } +} + +CNoteShape::CNoteShape() +{} + +CNoteShape::CNoteShape(CXMLNode& oNode, int nVersion) +{} + +CNoteShape* CNoteShape::Parse(int nLevel, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) +{ + CNoteShape* pNoteShape = new CNoteShape(); + + if (nullptr == pNoteShape) + { + oBuffer.Skip(nSize); + return nullptr; + } + + oBuffer.SavePosition(); + + pNoteShape->m_eNumberShape = GetNumberShape2(oBuffer.ReadByte()); + + HWP_BYTE chAttr; + oBuffer.ReadByte(chAttr); + + pNoteShape->m_chPlacement = (HWP_BYTE)(chAttr & 0x03); + pNoteShape->m_eNumbering = GetNoteNumbering((chAttr >> 2) & 0x03); + pNoteShape->m_bSuperscript = CHECK_FLAG(chAttr >> 4, 0x01); + pNoteShape->m_bBeneathText = CHECK_FLAG(chAttr >> 5, 0x01); + oBuffer.Skip(2); + + oBuffer.ReadChar(pNoteShape->m_chUserChar); + oBuffer.ReadChar(pNoteShape->m_chPrefixChar); + oBuffer.ReadChar(pNoteShape->m_chSuffixChar); + oBuffer.ReadShort(pNoteShape->m_shNewNumber); + oBuffer.ReadInt(pNoteShape->m_nNoteLineLength); + oBuffer.ReadShort(pNoteShape->m_shSpacingAboveLine); + oBuffer.ReadShort(pNoteShape->m_shSpacingBelowLine); + oBuffer.ReadShort(pNoteShape->m_shSpacingBetweenNotes); + + pNoteShape->m_eNoteLineType = GetLineStyle1(oBuffer.ReadByte()); + oBuffer.ReadByte(pNoteShape->m_chNoteLineWidth); + oBuffer.ReadColor(pNoteShape->m_nNoteLineColor); + + oBuffer.Skip(nSize - oBuffer.GetDistanceToLastPos(true)); + + return pNoteShape; +} + + +} diff --git a/HwpFile/HwpDoc/Section/NoteShape.h b/HwpFile/HwpDoc/Section/NoteShape.h new file mode 100644 index 00000000000..9d9069793ae --- /dev/null +++ b/HwpFile/HwpDoc/Section/NoteShape.h @@ -0,0 +1,56 @@ +#ifndef NOTESHAPE_H +#define NOTESHAPE_H + +#include "../HWPElements/HwpRecordTypes.h" +#include "../HWPStream.h" +#include "../Common/XMLNode.h" + +namespace HWP +{ +enum class ENoteNumbering +{ + CONTINUOUS, + ON_SECTION, + ON_PAGE, + UNKNOWN +}; + +//TODO:: проверить данный enum +// в олигинале и EachColumn и EndOfDocument имеют одинаковые значения +enum class ENotePlacement +{ + EachColumn, + MergedColumn, + RightMostColumn, + + EndOfDocument, + EndOfSection +}; + +class CNoteShape +{ + ENumberShape2 m_eNumberShape; + HWP_BYTE m_chPlacement; + ENoteNumbering m_eNumbering; + bool m_bSuperscript; + bool m_bBeneathText; + char16_t m_chUserChar; + char16_t m_chPrefixChar; + char16_t m_chSuffixChar; + short m_shNewNumber; + int m_nNoteLineLength; + short m_shSpacingAboveLine; + short m_shSpacingBelowLine; + short m_shSpacingBetweenNotes; + ELineStyle1 m_eNoteLineType; + HWP_BYTE m_chNoteLineWidth; + int m_nNoteLineColor; +public: + CNoteShape(); + CNoteShape(CXMLNode& oNode, int nVersion); + + static CNoteShape* Parse(int nLevel, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); +}; +} + +#endif // NOTESHAPE_H diff --git a/HwpFile/HwpDoc/Section/Page.cpp b/HwpFile/HwpDoc/Section/Page.cpp new file mode 100644 index 00000000000..43b075f8542 --- /dev/null +++ b/HwpFile/HwpDoc/Section/Page.cpp @@ -0,0 +1,114 @@ +#include "Page.h" + +namespace HWP +{ +HWP::CPage::CPage() +{} + +CPage::CPage(CXMLNode& oNode) +{ + m_bLandscape = L"NARROWLY" == oNode.GetAttribute(L"landscape"); + + m_nWidth = oNode.GetAttributeInt(L"width"); + m_nHeight = oNode.GetAttributeInt(L"height"); + + std::wstring wsType = oNode.GetAttribute(L"gutterType"); + + if (L"LEFT_ONELY" == wsType) + m_chGutterType = 0; + else if (L"LEFT_RIGHT" == wsType) + m_chGutterType = 1; + else if (L"TOP_BOTTOM" == wsType) + m_chGutterType = 2; + + for (CXMLNode& oChild : oNode.GetChilds(L"hp:margin")) + { + m_nMarginLeft = oChild.GetAttributeInt(L"left"); + m_nMarginRight = oChild.GetAttributeInt(L"right"); + m_nMarginTop = oChild.GetAttributeInt(L"top"); + m_nMarginBottom = oChild.GetAttributeInt(L"bottom"); + m_nMarginHeader = oChild.GetAttributeInt(L"header"); + m_nMarginFooter = oChild.GetAttributeInt(L"footer"); + m_nMarginGutter = oChild.GetAttributeInt(L"gutter"); + } +} + +int CPage::GetWidth() const +{ + return m_nWidth; +} + +int CPage::GetHeight() const +{ + return m_nHeight; +} + +int CPage::GetMarginLeft() const +{ + return m_nMarginLeft; +} + +int CPage::GetMarginRight() const +{ + return m_nMarginRight; +} + +int CPage::GetMarginTop() const +{ + return m_nMarginTop; +} + +int CPage::GetMarginBottom() const +{ + return m_nMarginBottom; +} + +int CPage::GetMarginHeader() const +{ + return m_nMarginHeader; +} + +int CPage::GetMarginFooter() const +{ + return m_nMarginFooter; +} + +int CPage::GetMarginGutter() const +{ + return m_nMarginGutter; +} + +CPage* CPage::Parse(int nLevel, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) +{ + oBuffer.SavePosition(); + + CPage *pPage = new CPage(); + + if (nullptr == pPage) + { + oBuffer.Skip(nSize); + oBuffer.RemoveLastSavedPos(); + return nullptr; + } + + oBuffer.ReadInt(pPage->m_nWidth); + oBuffer.ReadInt(pPage->m_nHeight); + oBuffer.ReadInt(pPage->m_nMarginLeft); + oBuffer.ReadInt(pPage->m_nMarginRight); + oBuffer.ReadInt(pPage->m_nMarginTop); + oBuffer.ReadInt(pPage->m_nMarginBottom); + oBuffer.ReadInt(pPage->m_nMarginHeader); + oBuffer.ReadInt(pPage->m_nMarginFooter); + oBuffer.ReadInt(pPage->m_nMarginGutter); + + int nAttr; + oBuffer.ReadInt(nAttr); + + pPage->m_bLandscape = CHECK_FLAG(nAttr, 0x01); + pPage->m_chGutterType = (HWP_BYTE)((nAttr >> 1) & 0x03); + + oBuffer.Skip(nSize - oBuffer.GetDistanceToLastPos(true)); + + return pPage; +} +} diff --git a/HwpFile/HwpDoc/Section/Page.h b/HwpFile/HwpDoc/Section/Page.h new file mode 100644 index 00000000000..a2b5f492430 --- /dev/null +++ b/HwpFile/HwpDoc/Section/Page.h @@ -0,0 +1,40 @@ +#ifndef PAGE_H +#define PAGE_H + +#include "../HWPStream.h" +#include "../Common/XMLNode.h" + +namespace HWP +{ +class CPage +{ + bool m_bLandscape; + int m_nWidth; + int m_nHeight; + HWP_BYTE m_chGutterType; + int m_nMarginLeft; + int m_nMarginRight; + int m_nMarginTop; + int m_nMarginBottom; + int m_nMarginHeader; + int m_nMarginFooter; + int m_nMarginGutter; +public: + CPage(); + CPage(CXMLNode& oNode); + + int GetWidth() const; + int GetHeight() const; + int GetMarginLeft() const; + int GetMarginRight() const; + int GetMarginTop() const; + int GetMarginBottom() const; + int GetMarginHeader() const; + int GetMarginFooter() const; + int GetMarginGutter() const; + + static CPage* Parse(int nLevel, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); +}; +} + +#endif // PAGE_H diff --git a/HwpFile/HwpDoc/Section/PageBorderFill.cpp b/HwpFile/HwpDoc/Section/PageBorderFill.cpp new file mode 100644 index 00000000000..7ea47183a5b --- /dev/null +++ b/HwpFile/HwpDoc/Section/PageBorderFill.cpp @@ -0,0 +1,60 @@ +#include "PageBorderFill.h" + +namespace HWP +{ +CPageBorderFill::CPageBorderFill() +{} + +CPageBorderFill::CPageBorderFill(CXMLNode& oNode, int nVersion) +{ + m_shBorderFill = oNode.GetAttributeInt(L"borderFillIDRef"); + m_bTextBorder = L"PAPER" == oNode.GetAttribute(L"textBorder"); + m_bHeaderInside = oNode.GetAttributeBool(L"headerInside"); + m_bFooterInside = oNode.GetAttributeBool(L"footerInside"); + + HWP_STRING sType = oNode.GetAttribute(L"fillArea"); + + if (L"PAPER" == sType) + m_chFillArea = 0; + else if (L"PAGE" == sType) + m_chFillArea = 1; + else if (L"BORDER" == sType) + m_chFillArea = 2; + + for (CXMLNode& oChild : oNode.GetChilds(L"offset")) + { + m_shOffsetLeft = oChild.GetAttributeInt(L"left"); + m_shOffsetRight = oChild.GetAttributeInt(L"right"); + m_shOffsetTop = oChild.GetAttributeInt(L"top"); + m_shOffsetBottom = oChild.GetAttributeInt(L"bottom"); + } +} + +CPageBorderFill* CPageBorderFill::Parse(int nLevel, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) +{ + CPageBorderFill* pBorderFill = new CPageBorderFill(); + + if (nullptr == pBorderFill) + return nullptr; + + oBuffer.SavePosition(); + + int nAttr; + oBuffer.ReadInt(nAttr); + + pBorderFill->m_bTextBorder = CHECK_FLAG(nAttr, 0x01); + pBorderFill->m_bHeaderInside = CHECK_FLAG(nAttr, 0x02); + pBorderFill->m_bHeaderInside = CHECK_FLAG(nAttr, 0x04); + pBorderFill->m_chFillArea = (HWP_BYTE)((nAttr >> 3) & 0x03); + + oBuffer.ReadShort(pBorderFill->m_shOffsetLeft); + oBuffer.ReadShort(pBorderFill->m_shOffsetRight); + oBuffer.ReadShort(pBorderFill->m_shOffsetTop); + oBuffer.ReadShort(pBorderFill->m_shOffsetBottom); + oBuffer.ReadShort(pBorderFill->m_shBorderFill); + + oBuffer.Skip(nSize - oBuffer.GetDistanceToLastPos(true)); + + return pBorderFill; +} +} diff --git a/HwpFile/HwpDoc/Section/PageBorderFill.h b/HwpFile/HwpDoc/Section/PageBorderFill.h new file mode 100644 index 00000000000..5993f5b5421 --- /dev/null +++ b/HwpFile/HwpDoc/Section/PageBorderFill.h @@ -0,0 +1,28 @@ +#ifndef PAGEBORDERFILL_H +#define PAGEBORDERFILL_H + +#include "../HWPStream.h" +#include "../Common/XMLNode.h" + +namespace HWP +{ +class CPageBorderFill +{ + bool m_bTextBorder; + bool m_bHeaderInside; + bool m_bFooterInside; + HWP_BYTE m_chFillArea; + short m_shOffsetLeft; + short m_shOffsetRight; + short m_shOffsetTop; + short m_shOffsetBottom; + short m_shBorderFill; +public: + CPageBorderFill(); + CPageBorderFill(CXMLNode& oNode, int nVersion); + + static CPageBorderFill* Parse(int nLevel, int nSize, CHWPStream& oBuffer, int nOff, int nVersion); +}; +} + +#endif // PAGEBORDERFILL_H diff --git a/HwpFile/test/main.cpp b/HwpFile/test/main.cpp new file mode 100644 index 00000000000..ed8e0d03e0f --- /dev/null +++ b/HwpFile/test/main.cpp @@ -0,0 +1,27 @@ +#include "../HWPFile.h" +#include "../../DesktopEditor/common/Directory.h" +#include + +int main() +{ + CHWPFile oFile; + + // if (oFile.OpenHWPX(L"YOUR_PATH")) + if (oFile.OpenHWP(L"YOUR_PATH")) + { + std::cout << "Successful" << std::endl; + } + else + { + std::cout << "Unsuccessful" << std::endl; + oFile.Close(); + return -1; + } + std::wstring wsTempDir = NSFile::GetProcessDirectory() + L"/temp"; + + NSDirectory::DeleteDirectory(wsTempDir); + NSDirectory::CreateDirectory(wsTempDir); + oFile.SetTempDirectory(wsTempDir); + oFile.ConvertToOOXML(L"result.docx"); + oFile.Close(); +} diff --git a/HwpFile/test/test.pro b/HwpFile/test/test.pro new file mode 100644 index 00000000000..57583476358 --- /dev/null +++ b/HwpFile/test/test.pro @@ -0,0 +1,20 @@ +QT -= core +QT -= gui + +TARGET = test +CONFIG += console +CONFIG -= app_bundle +TEMPLATE = app + +DEFINES += HWPFILE_USE_DYNAMIC_LIBRARY + +SOURCES += main.cpp + +CORE_ROOT_DIR = $$PWD/../../ +PWD_ROOT_DIR = $$PWD +include($$CORE_ROOT_DIR/Common/base.pri) +include($$CORE_ROOT_DIR/Common/3dParty/icu/icu.pri) + +ADD_DEPENDENCY(kernel, UnicodeConverter, HWPFile) + +DESTDIR = $$PWD/build/$$CORE_BUILDS_PLATFORM_PREFIX diff --git a/MsBinaryFile/Common/Base/FormatUtils.cpp b/MsBinaryFile/Common/Base/FormatUtils.cpp new file mode 100644 index 00000000000..7f7e4a71880 --- /dev/null +++ b/MsBinaryFile/Common/Base/FormatUtils.cpp @@ -0,0 +1,397 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#include "FormatUtils.h" + +namespace DocFileFormat +{ +#define WriteWCharPadding(STLCollection, padding) \ +for (int i = 0; i < padding; ++i)\ +{\ +STLCollection->push_back((wchar_t)0);\ +} + static void WriteUtf16ToWChar(int code, std::vector* STLCollection, int padding) + { + int used = 0; + if (code < 0x10000) + { + STLCollection->push_back((wchar_t)code); + used = 1; + } + else + { + code -= 0x10000; + STLCollection->push_back((wchar_t)(0xD800 | ((code >> 10) & 0x03FF))); + STLCollection->push_back((wchar_t)(0xDC00 | (code & 0x03FF))); + used = 2; + } + WriteWCharPadding(STLCollection, padding - used); + + } + + static bool GetSTLCollectionFromUtf8(std::vector* STLCollection, unsigned char* pBuffer, int lCount) + { + if ((STLCollection == NULL) || (pBuffer == NULL)) + { + return false; + } + int lIndex = 0; + if (sizeof(wchar_t) == 2)//utf8 -> utf16 + { + while (lIndex < lCount) + { + BYTE byteMain = pBuffer[lIndex]; + if (0x00 == (byteMain & 0x80)) + { + // 1 byte + STLCollection->push_back((WCHAR)byteMain); + ++lIndex; + } + else if (0x00 == (byteMain & 0x20)) + { + // 2 byte + int val = 0; + if ((lIndex + 1) < lCount) + { + val = (int)(((byteMain & 0x1F) << 6) | + (pBuffer[lIndex + 1] & 0x3F)); + } + STLCollection->push_back((wchar_t)val); + STLCollection->push_back((wchar_t)0); + lIndex += 2; + } + else if (0x00 == (byteMain & 0x10)) + { + // 3 byte + int val = 0; + if ((lIndex + 2) < lCount) + { + val = (int)(((byteMain & 0x0F) << 12) | + ((pBuffer[lIndex + 1] & 0x3F) << 6) | + (pBuffer[lIndex + 2] & 0x3F)); + } + WriteUtf16ToWChar(val, STLCollection, 3); + lIndex += 3; + } + else if (0x00 == (byteMain & 0x0F)) + { + // 4 byte + int val = 0; + if ((lIndex + 3) < lCount) + { + val = (int)(((byteMain & 0x07) << 18) | + ((pBuffer[lIndex + 1] & 0x3F) << 12) | + ((pBuffer[lIndex + 2] & 0x3F) << 6) | + (pBuffer[lIndex + 3] & 0x3F)); + } + WriteUtf16ToWChar(val, STLCollection, 4); + lIndex += 4; + } + else if (0x00 == (byteMain & 0x08)) + { + // 4 byte + int val = 0; + if ((lIndex + 3) < lCount) + { + val = (int)(((byteMain & 0x07) << 18) | + ((pBuffer[lIndex + 1] & 0x3F) << 12) | + ((pBuffer[lIndex + 2] & 0x3F) << 6) | + (pBuffer[lIndex + 3] & 0x3F)); + } + WriteUtf16ToWChar(val, STLCollection, 4); + lIndex += 4; + } + else if (0x00 == (byteMain & 0x04)) + { + // 5 byte + int val = 0; + if ((lIndex + 4) < lCount) + { + val = (int)(((byteMain & 0x03) << 24) | + ((pBuffer[lIndex + 1] & 0x3F) << 18) | + ((pBuffer[lIndex + 2] & 0x3F) << 12) | + ((pBuffer[lIndex + 3] & 0x3F) << 6) | + (pBuffer[lIndex + 4] & 0x3F)); + } + WriteUtf16ToWChar(val, STLCollection, 5); + lIndex += 5; + } + else + { + // 6 byte + int val = 0; + if ((lIndex + 5) < lCount) + { + val = (int)(((byteMain & 0x01) << 30) | + ((pBuffer[lIndex + 1] & 0x3F) << 24) | + ((pBuffer[lIndex + 2] & 0x3F) << 18) | + ((pBuffer[lIndex + 3] & 0x3F) << 12) | + ((pBuffer[lIndex + 4] & 0x3F) << 6) | + (pBuffer[lIndex + 5] & 0x3F)); + } + WriteUtf16ToWChar(val, STLCollection, 6); + lIndex += 6; + } + } + } + else //utf8 -> utf32 + { + while (lIndex < lCount) + { + BYTE byteMain = pBuffer[lIndex]; + if (0x00 == (byteMain & 0x80)) + { + // 1 byte + STLCollection->push_back((WCHAR)byteMain); + ++lIndex; + } + else if (0x00 == (byteMain & 0x20)) + { + // 2 byte + int val = 0; + if ((lIndex + 1) < lCount) + { + val = (int)(((byteMain & 0x1F) << 6) | + (pBuffer[lIndex + 1] & 0x3F)); + } + + STLCollection->push_back((WCHAR)val); + STLCollection->push_back((WCHAR)0); + lIndex += 2; + } + else if (0x00 == (byteMain & 0x10)) + { + // 3 byte + int val = 0; + if ((lIndex + 2) < lCount) + { + val = (int)(((byteMain & 0x0F) << 12) | + ((pBuffer[lIndex + 1] & 0x3F) << 6) | + (pBuffer[lIndex + 2] & 0x3F)); + } + STLCollection->push_back((WCHAR)val); + WriteWCharPadding(STLCollection, 2); + lIndex += 3; + } + else if (0x00 == (byteMain & 0x0F)) + { + // 4 byte + int val = 0; + if ((lIndex + 3) < lCount) + { + val = (int)(((byteMain & 0x07) << 18) | + ((pBuffer[lIndex + 1] & 0x3F) << 12) | + ((pBuffer[lIndex + 2] & 0x3F) << 6) | + (pBuffer[lIndex + 3] & 0x3F)); + } + + STLCollection->push_back((WCHAR)val); + WriteWCharPadding(STLCollection, 3); + lIndex += 4; + } + else if (0x00 == (byteMain & 0x08)) + { + // 4 byte + int val = 0; + if ((lIndex + 3) < lCount) + { + val = (int)(((byteMain & 0x07) << 18) | + ((pBuffer[lIndex + 1] & 0x3F) << 12) | + ((pBuffer[lIndex + 2] & 0x3F) << 6) | + (pBuffer[lIndex + 3] & 0x3F)); + } + STLCollection->push_back((WCHAR)val); + WriteWCharPadding(STLCollection, 3); + lIndex += 4; + } + else if (0x00 == (byteMain & 0x04)) + { + // 5 byte + int val = 0; + if ((lIndex + 4) < lCount) + { + val = (int)(((byteMain & 0x03) << 24) | + ((pBuffer[lIndex + 1] & 0x3F) << 18) | + ((pBuffer[lIndex + 2] & 0x3F) << 12) | + ((pBuffer[lIndex + 3] & 0x3F) << 6) | + (pBuffer[lIndex + 4] & 0x3F)); + } + STLCollection->push_back((WCHAR)val); + WriteWCharPadding(STLCollection, 4); + lIndex += 5; + } + else + { + // 6 byte + int val = 0; + if ((lIndex + 5) < lCount) + { + val = (int)(((byteMain & 0x01) << 30) | + ((pBuffer[lIndex + 1] & 0x3F) << 24) | + ((pBuffer[lIndex + 2] & 0x3F) << 18) | + ((pBuffer[lIndex + 3] & 0x3F) << 12) | + ((pBuffer[lIndex + 4] & 0x3F) << 6) | + (pBuffer[lIndex + 5] & 0x3F)); + } + STLCollection->push_back((WCHAR)val); + WriteWCharPadding(STLCollection, 5); + lIndex += 6; + } + } + } + return true; + } +} + +bool DocFileFormat::FormatUtils::GetWStringFromBytes(std::wstring& string, unsigned char* bytes, int size, int code_page) +{ + if (bytes == NULL) + { + return false; + } + + if (code_page == ENCODING_UTF8) + { + string = NSFile::CUtf8Converter::GetUnicodeStringFromUTF8(bytes, size); + return true; + } + else if (code_page == ENCODING_UTF16) + { + string = NSFile::CUtf8Converter::GetWStringFromUTF16((unsigned short*)bytes, size / 2); + } + else if (code_page == ENCODING_WINDOWS_1250) + { + wchar_t wch = 0; + int i = 0; + while (i < size) + { + wch = MapByteToWChar(bytes[i++]); + + string += (wch); + } + } + else + { + std::string sCodePage; + std::map::const_iterator pFind = NSUnicodeConverter::mapEncodingsICU.find(code_page); + if (pFind != NSUnicodeConverter::mapEncodingsICU.end()) + { + sCodePage = pFind->second; + } + + if (sCodePage.empty()) + sCodePage = "CP1250"/* + std::to_string(code_page)*/; + + NSUnicodeConverter::CUnicodeConverter oConverter; + string = oConverter.toUnicode((char*)bytes, (unsigned int)size, sCodePage.c_str()); + } + + return true; +} + +bool DocFileFormat::FormatUtils::GetSTLCollectionFromBytes(std::vector* STLCollection, unsigned char* bytes, int size, int code_page) +{ + if (bytes == NULL) + { + return false; + } + + if (code_page == ENCODING_UTF8) + { + return GetSTLCollectionFromUtf8(STLCollection, bytes, size); + } + else if (code_page == ENCODING_UTF16) + { + int i = 0; +#if !defined(_WIN32) && !defined(_WIN64) + int nCount = size / 2; + unsigned short* pShort = (unsigned short*)bytes; + + int nCurrent = 0; + while (nCurrent < nCount) + { + if (*pShort < 0xD800 || *pShort > 0xDBFF) + { + STLCollection->push_back((wchar_t)(*pShort)); + ++pShort; + ++nCurrent; + } + else + { + STLCollection->push_back((wchar_t)(((((pShort[0] - 0xD800) & 0x03FF) << 10) | ((pShort[1] - 0xDC00) & 0x03FF)) + 0x10000)); + STLCollection->push_back((wchar_t)0); + pShort += 2; + nCurrent += 2; + } + } +#else + while (i < size) + { + STLCollection->push_back(FormatUtils::BytesToUInt16(bytes, i, size)); + + i += 2; + } +#endif + } + else if (code_page == ENCODING_WINDOWS_1250) + { + wchar_t wch = 0; + int i = 0; + while (i < size) + { + wch = MapByteToWChar(bytes[i++]); + + STLCollection->push_back(wch); + } + } + else + { + std::string sCodePage; + std::map::const_iterator pFind = NSUnicodeConverter::mapEncodingsICU.find(code_page); + if (pFind != NSUnicodeConverter::mapEncodingsICU.end()) + { + sCodePage = pFind->second; + } + + if (sCodePage.empty()) + sCodePage = "CP1250"/* + std::to_string(code_page)*/; + + NSUnicodeConverter::CUnicodeConverter oConverter; + std::wstring unicode_string = oConverter.toUnicode((char*)bytes, (unsigned int)size, sCodePage.c_str()); + + for (size_t i = 0; i < unicode_string.size(); i++) + { + STLCollection->push_back(unicode_string[i]); + } + } + + return true; +} diff --git a/MsBinaryFile/Common/Base/FormatUtils.h b/MsBinaryFile/Common/Base/FormatUtils.h index 02a90140152..dcde3afd4c4 100644 --- a/MsBinaryFile/Common/Base/FormatUtils.h +++ b/MsBinaryFile/Common/Base/FormatUtils.h @@ -56,6 +56,7 @@ #include "../../../DesktopEditor/common/Types.h" #include "../../../OOXML/Base/unicode_util.h" #include "../../../UnicodeConverter/UnicodeConverter.h" +#include "../../../DesktopEditor/common/File.h" #include @@ -493,157 +494,8 @@ namespace DocFileFormat } return true; } - - template static bool GetSTLCollectionFromUtf8( T *STLCollection, unsigned char *bytes, int size) - { - if ( ( STLCollection == NULL ) || ( bytes == NULL ) ) - { - return false; - } - if (sizeof(wchar_t) == 2)//utf8 -> utf16 - { - unsigned int nLength = size; - - UTF16 *pStrUtf16 = new UTF16 [nLength+1]; - memset ((void *) pStrUtf16, 0, sizeof (UTF16) * (nLength+1)); - - UTF8 *pStrUtf8 = (UTF8 *) bytes; - - // this values will be modificated - const UTF8 *pStrUtf8_Conv = pStrUtf8; - UTF16 *pStrUtf16_Conv = pStrUtf16; - - ConversionResult eUnicodeConversionResult = ConvertUTF8toUTF16 (&pStrUtf8_Conv, &pStrUtf8[nLength] - , &pStrUtf16_Conv, &pStrUtf16 [nLength] - , strictConversion); - - if (conversionOK != eUnicodeConversionResult) - { - delete [] pStrUtf16; - return GetSTLCollectionFromLocale(STLCollection, bytes,size); - } - for (unsigned int i = 0; i < nLength; i++) - { - STLCollection->push_back(pStrUtf16[i]); - } - delete [] pStrUtf16; - return true; - } - else //utf8 -> utf32 - { - unsigned int nLength = size; - - UTF32 *pStrUtf32 = new UTF32 [nLength+1]; - memset ((void *) pStrUtf32, 0, sizeof (UTF32) * (nLength+1)); - - - UTF8 *pStrUtf8 = (UTF8 *) bytes; - - // this values will be modificated - const UTF8 *pStrUtf8_Conv = pStrUtf8; - UTF32 *pStrUtf32_Conv = pStrUtf32; - - ConversionResult eUnicodeConversionResult = ConvertUTF8toUTF32 (&pStrUtf8_Conv, &pStrUtf8[nLength] - , &pStrUtf32_Conv, &pStrUtf32 [nLength] - , strictConversion); - - if (conversionOK != eUnicodeConversionResult) - { - delete [] pStrUtf32; - return GetSTLCollectionFromLocale(STLCollection, bytes, size); - } - for (unsigned int i = 0; i < nLength; i++) - { - STLCollection->push_back(pStrUtf32[i]); - } - delete [] pStrUtf32; - return true; - } - } - - template static bool GetSTLCollectionFromBytes( T *STLCollection, unsigned char *bytes, int size, int code_page ) - { - if ( ( STLCollection == NULL ) || ( bytes == NULL ) ) - { - return false; - } - - if (code_page == ENCODING_UTF8) - { - return GetSTLCollectionFromUtf8(STLCollection, bytes, size); - } - else if (code_page == ENCODING_UTF16) - { - int i = 0; -#if !defined(_WIN32) && !defined(_WIN64) - size /= 2; - ConversionResult eUnicodeConversionResult; - UTF32 *pStrUtf32 = new UTF32 [size + 1]; - - memset ((void *) pStrUtf32, 0, sizeof (UTF32) * (size + 1)); - - const UTF16 *pStrUtf16_Conv = (const UTF16 *) bytes; - UTF32 *pStrUtf32_Conv = pStrUtf32; - - eUnicodeConversionResult = ConvertUTF16toUTF32 ( &pStrUtf16_Conv - , &pStrUtf16_Conv[size] - , &pStrUtf32_Conv - , &pStrUtf32 [size] - , strictConversion); - - if (conversionOK != eUnicodeConversionResult) - { - delete [] pStrUtf32; pStrUtf32 = NULL; - return false; - } - for (long i=0; i < size; i++) - { - STLCollection->push_back(pStrUtf32[i]); - } - if (pStrUtf32) delete [] pStrUtf32; -#else - while ( i < size ) - { - STLCollection->push_back( FormatUtils::BytesToUInt16( bytes, i, size ) ); - - i += 2; - } -#endif - } - else if (code_page == ENCODING_WINDOWS_1250) - { - wchar_t wch = 0; - int i = 0; - while ( i < size ) - { - wch = MapByteToWChar( bytes[i++] ); - - STLCollection->push_back( wch ); - } - } - else - { - std::string sCodePage; - std::map::const_iterator pFind = NSUnicodeConverter::mapEncodingsICU.find(code_page); - if (pFind != NSUnicodeConverter::mapEncodingsICU.end()) - { - sCodePage = pFind->second; - } - - if (sCodePage.empty()) - sCodePage = "CP1250"/* + std::to_string(code_page)*/; - - NSUnicodeConverter::CUnicodeConverter oConverter; - std::wstring unicode_string = oConverter.toUnicode((char*)bytes, (unsigned int)size, sCodePage.c_str()); - - for (size_t i = 0; i < unicode_string.size(); i++) - { - STLCollection->push_back(unicode_string[i]); - } - } - - return true; - } + static bool GetWStringFromBytes(std::wstring & string, unsigned char* bytes, int size, int code_page); + static bool GetSTLCollectionFromBytes(std::vector* STLCollection, unsigned char* bytes, int size, int code_page); static int BitmaskToInt( int value, int mask ) { diff --git a/MsBinaryFile/Common/SummaryInformation/PropertySetStream.cpp b/MsBinaryFile/Common/SummaryInformation/PropertySetStream.cpp index f03c8938303..7c79b4e6b8e 100644 --- a/MsBinaryFile/Common/SummaryInformation/PropertySetStream.cpp +++ b/MsBinaryFile/Common/SummaryInformation/PropertySetStream.cpp @@ -64,6 +64,15 @@ namespace OLEPS *stream >> NumPropertySets; + if (SystemIdentifier == NumPropertySets) + {//oops + _GUID_ Clsid2 = {}; + _UINT32 reserved1 = 0, reserved2 = 0; + + *stream >> Clsid2 >> reserved1 >> reserved2; // ??? ReportBuilder + *stream >> NumPropertySets; + } + if (NumPropertySets != 0x01 && NumPropertySets != 0x02) { NumPropertySets = 0x01; @@ -82,7 +91,7 @@ namespace OLEPS property_sets_offsets.push_back(Offset); } - for (_UINT32 i = 0; i < NumPropertySets; ++i) + for (_UINT32 i = 0; i < property_sets_offsets.size(); ++i) { PropertySetPtr set = PropertySetPtr(new PropertySet(stream, property_sets_offsets[i], ext)); diff --git a/MsBinaryFile/Common/Vba/Records.cpp b/MsBinaryFile/Common/Vba/Records.cpp index 180fa7636a3..775ed93cfb9 100644 --- a/MsBinaryFile/Common/Vba/Records.cpp +++ b/MsBinaryFile/Common/Vba/Records.cpp @@ -148,6 +148,9 @@ namespace VBA std::wstring readStringPadding(CVbaFileStreamPtr stream, _UINT32 & size) { if (!stream) return L""; + + if ( GETBITS(size, 0, 30) > 0xfff) + return L""; std::wstring result = readString(stream->getDataCurrent(), size); @@ -1088,8 +1091,9 @@ namespace VBA } stream->Align(4); if (propMask.fZoom) *stream >> Zoom; - if (propMask.fPictureAlignment) *stream >> PictureAlignment; - if (propMask.fPictureSizeMode) *stream >> PictureSizeMode; + if (propMask.fPicture && propMask.fPictureAlignment) *stream >> PictureAlignment; + if (propMask.fPicture && propMask.fPictureSizeMode) *stream >> PictureSizeMode; + stream->Align(4); if (propMask.fShapeCookie) *stream >> ShapeCookie; if (propMask.fDrawBuffer) *stream >> DrawBuffer; //- FormExtraDataBlock @@ -1237,6 +1241,11 @@ namespace VBA TypeOrCount = GETBITS(flag, 0, 6); fCount = GETBIT(flag, 7); + + if (fCount == 1) + { + *stream >> OptionalType; // 1 - OLE control + } } //------------------------------------------------------------------------------------------ OleSiteConcreteControl::OleSiteConcreteControl(CVbaFileStreamPtr stream) { load(stream); } @@ -1307,10 +1316,17 @@ namespace VBA { *stream >> RuntimeLicKeyLengthAndCompression; } + pos1 = stream->GetDataPos(); if (propMask.fControlSource) { *stream >> ControlSourceLengthAndCompression; } + //pos2 = stream->GetDataPos(); + //count_padding = 4 - ((pos2 - pos1) % 4); + + //if (count_padding > 0 && count_padding < 4) + // stream->skipBytes(count_padding); + if (propMask.fRowSource) { *stream >> RowSourceLengthAndCompression; @@ -1365,7 +1381,10 @@ namespace VBA } } _UINT32 CountOfSites = 0, CountOfBytes = 0; - *stream >> CountOfSites >> CountOfBytes; + *stream >> CountOfSites >> CountOfBytes; + + if (CountOfSites > 0xffff) + return; _UINT32 pos1 = stream->GetDataPos(); diff --git a/MsBinaryFile/Common/Vba/Records.h b/MsBinaryFile/Common/Vba/Records.h index 835e385b0d1..9e1f94c65f7 100644 --- a/MsBinaryFile/Common/Vba/Records.h +++ b/MsBinaryFile/Common/Vba/Records.h @@ -886,6 +886,8 @@ namespace VBA unsigned char Depth = 0; unsigned char TypeOrCount = 0; bool fCount = false; + + _CP_OPT(unsigned char) OptionalType; }; typedef boost::shared_ptr FormObjectDepthTypeCountPtr; //-------------------------------------------------------------------------------------------------------------- diff --git a/MsBinaryFile/Common/Vba/StreamObjects.cpp b/MsBinaryFile/Common/Vba/StreamObjects.cpp index 44badb466b9..64ae0f1c4b9 100644 --- a/MsBinaryFile/Common/Vba/StreamObjects.cpp +++ b/MsBinaryFile/Common/Vba/StreamObjects.cpp @@ -41,6 +41,8 @@ namespace VBA bool DirStreamObject::loadContent() { + if (!reader) return false; + InformationRecord = boost::make_shared(reader); ReferencesRecord = boost::make_shared(reader); ModulesRecord = boost::make_shared(reader); @@ -50,12 +52,16 @@ bool DirStreamObject::loadContent() bool ModuleStreamObject::loadContent() { - SourceCode = convert_string_icu((char*)reader->getData(), (unsigned int)reader->getDataSize(), reader->CodePage); + if (!reader) return false; + + SourceCode = convert_string_icu((char*)reader->getData(), (unsigned int)reader->getDataSize(), reader->CodePage); return true; } bool ProjectStreamObject::loadContent() { + if (!reader) return false; + std::string strProps((char*)reader->getData(), reader->getDataSize()); std::vector arrProps; @@ -72,6 +78,8 @@ bool ProjectStreamObject::loadContent() } bool VBFrameObject::loadContent() { + if (!reader) return false; + std::wstring strProps = convert_string_icu((char*)reader->getData(), (unsigned int)reader->getDataSize(), reader->CodePage); std::vector arrProps; @@ -94,6 +102,8 @@ bool VBFrameObject::loadContent() bool FormControlStream::loadContent() { + if (!reader) return false; + unsigned char MinorVersion, MajorVersion; _UINT16 cbForm; diff --git a/MsBinaryFile/Common/Vba/VbaReader.cpp b/MsBinaryFile/Common/Vba/VbaReader.cpp index 8ffd5c2a0fc..6bf886f7dc8 100644 --- a/MsBinaryFile/Common/Vba/VbaReader.cpp +++ b/MsBinaryFile/Common/Vba/VbaReader.cpp @@ -190,6 +190,10 @@ const std::wstring CVbaReader::convert() { std::wstring streamName = ProjectStreamObject->DesignerModules[i] + L"/VBFrame"; CVbaFileStreamPtr strmVBFrame = vbaProject_file_->getNamedStream(streamName); + if (!strmVBFrame) + { + continue; + } strmVBFrame->CodePage = code_page_; VBA::VBFrameObjectPtr VBFrameObject = VBA::VBFrameObjectPtr(new VBA::VBFrameObject(strmVBFrame)); @@ -321,13 +325,19 @@ std::wstring CVbaReader::convertObject(const std::wstring & name, unsigned int c { for (size_t i = 0; i < FormControlStream->SiteData->Sites.size(); ++i) { - VBA::OleSiteConcreteControlPtr & site = FormControlStream->SiteData->Sites[i]; - if (site->ObjectStreamSize && strmObject) - { - site->Object = VBA::ActiveXObjectPtr(OOX::ActiveXObject::Create(*site->ClsidCacheIndex)); + VBA::OleSiteConcreteControlPtr& site = FormControlStream->SiteData->Sites[i]; + if (!site) + continue; - site->Object->Parse(strmObject->getData() + nextStreamPositionEmbedded, *site->ObjectStreamSize); - nextStreamPositionEmbedded += *site->ObjectStreamSize; + if (strmObject) + { + site->Object = VBA::ActiveXObjectPtr(OOX::ActiveXObject::Create(site->ClsidCacheIndex ? *site->ClsidCacheIndex : 0)); + + if (strmObject->getDataSize() > nextStreamPositionEmbedded && site->ObjectStreamSize) + { + site->Object->Parse(strmObject->getData() + nextStreamPositionEmbedded, *site->ObjectStreamSize); + nextStreamPositionEmbedded += *site->ObjectStreamSize; + } } CP_XML_NODE(L"Site") diff --git a/MsBinaryFile/Common/Vml/PPTShape/CustomGeomShape.cpp b/MsBinaryFile/Common/Vml/PPTShape/CustomGeomShape.cpp index dc1d3ada025..d1253afaf4a 100644 --- a/MsBinaryFile/Common/Vml/PPTShape/CustomGeomShape.cpp +++ b/MsBinaryFile/Common/Vml/PPTShape/CustomGeomShape.cpp @@ -80,7 +80,7 @@ namespace NSCustomVML break; case 0xb300: // arcto m_eRuler = ODRAW::rtArc; - m_nCount = 2; + m_nCount = 0; break; case 0xac00: case 0xaa00: // nofill @@ -476,9 +476,8 @@ namespace NSCustomVML } bool CCustomVML::IsCustom() { - //return (m_bIsVerticesPresent && m_bIsPathPresent); - return (m_bIsVerticesPresent && !m_arVertices.empty() && (m_bIsPathPresent || !m_arSegments.empty())); - } + return ((m_bIsVerticesPresent || !m_arVertices.empty()) && (m_bIsPathPresent || !m_arSegments.empty())); + } void CCustomVML::SetPath(ODRAW::RulesType ePath) { m_ePath = ePath; diff --git a/MsBinaryFile/Common/Vml/PPTShape/Ppt2PptxShapeConverter.cpp b/MsBinaryFile/Common/Vml/PPTShape/Ppt2PptxShapeConverter.cpp index 110e92af9f7..c6c4fa7db87 100644 --- a/MsBinaryFile/Common/Vml/PPTShape/Ppt2PptxShapeConverter.cpp +++ b/MsBinaryFile/Common/Vml/PPTShape/Ppt2PptxShapeConverter.cpp @@ -49,7 +49,7 @@ namespace NSGuidesVML point.x = lParam; if (m_eRuler != rtRMoveTo && m_eRuler != rtRLineTo && m_eRuler != rtRCurveTo) { - //point.x -= m_lX; + point.x -= m_lX; } point.y = 0; pointType.x = eParType; @@ -62,7 +62,7 @@ namespace NSGuidesVML m_arPoints.back().y = lParam; if (m_eRuler != rtRMoveTo && m_eRuler != rtRLineTo && m_eRuler != rtRCurveTo) { - //m_arPoints.back().y -= m_lY; + m_arPoints.back().y -= m_lY; } m_arPointsType.back().y = eParType; @@ -272,8 +272,8 @@ namespace NSGuidesVML m_lWidth = oPart.width; m_lHeight = oPart.height; - //m_lX = oPart.x; - //m_lY = oPart.y; + m_lX = oPart.x; + m_lY = oPart.y; } bool bFill = false; diff --git a/MsBinaryFile/Common/Vml/VmlPath.cpp b/MsBinaryFile/Common/Vml/VmlPath.cpp index a093071b190..868d5988149 100644 --- a/MsBinaryFile/Common/Vml/VmlPath.cpp +++ b/MsBinaryFile/Common/Vml/VmlPath.cpp @@ -852,6 +852,8 @@ namespace ODRAW for (size_t nIndex = 0; nIndex < oArray.size(); ++nIndex) { + if (oArray[nIndex].empty()) continue; + CPartPath part; part.x = m_lX; diff --git a/MsBinaryFile/DocFile/AnnotationReferenceDescriptor.cpp b/MsBinaryFile/DocFile/AnnotationReferenceDescriptor.cpp index fc1927028dd..03ce84359cc 100644 --- a/MsBinaryFile/DocFile/AnnotationReferenceDescriptor.cpp +++ b/MsBinaryFile/DocFile/AnnotationReferenceDescriptor.cpp @@ -45,8 +45,8 @@ namespace DocFileFormat short cch = reader->ReadByte(); unsigned char *chars = reader->ReadBytes(cch, true); - FormatUtils::GetSTLCollectionFromBytes( &(newObject->m_UserInitials), chars, cch , ENCODING_WINDOWS_1250); - + FormatUtils::GetWStringFromBytes(newObject->m_UserInitials, chars, cch , ENCODING_WINDOWS_1250); + newObject->m_AuthorIndex = reader->ReadUInt16(); newObject->m_BookmarkId = reader->ReadInt16(); @@ -59,19 +59,17 @@ namespace DocFileFormat else { short cch = reader->ReadInt16(); - - unsigned char *chars = reader->ReadBytes(18, true); - FormatUtils::GetSTLCollectionFromBytes( &(newObject->m_UserInitials), chars, ( cch * 2 ), ENCODING_UTF16); - + newObject->m_UserInitials = NSFile::CUtf8Converter::GetWStringFromUTF16((unsigned short*)(chars), cch); + RELEASEARRAYOBJECTS(chars); + newObject->m_AuthorIndex = reader->ReadUInt16(); //skip 4 bytes unsigned int skip = reader->ReadUInt32(); newObject->m_BookmarkId = reader->ReadInt32(); //-1 - comment is on a length zero text range in the Main Document - RELEASEARRAYOBJECTS(chars); } diff --git a/MsBinaryFile/DocFile/BookmarkFirst.cpp b/MsBinaryFile/DocFile/BookmarkFirst.cpp index 87a232b99a8..0141e72050c 100644 --- a/MsBinaryFile/DocFile/BookmarkFirst.cpp +++ b/MsBinaryFile/DocFile/BookmarkFirst.cpp @@ -62,7 +62,10 @@ namespace DocFileFormat { ProtInfoBookmark *newObject = new ProtInfoBookmark(); - newObject->id = reader->ReadUInt32(); + if (length > 8) + { + newObject->id = reader->ReadUInt32(); + } newObject->uidSel = reader->ReadUInt16(); newObject->iProt = reader->ReadUInt16(); diff --git a/MsBinaryFile/DocFile/BorderCode.cpp b/MsBinaryFile/DocFile/BorderCode.cpp index 63792615aff..b47e30440cb 100644 --- a/MsBinaryFile/DocFile/BorderCode.cpp +++ b/MsBinaryFile/DocFile/BorderCode.cpp @@ -34,22 +34,32 @@ namespace DocFileFormat { - BorderCode::BorderCode(): cv(0), dptLineWidth(0), brcType(0), ico( Global::ColorNameIdentifier[0] ), dptSpace(0), fShadow(false), fFrame(false), fNil(false) + BorderCode::BorderCode(): dptLineWidth(0), brcType(0), ico( Global::ColorIdentifier[0] ), dptSpace(0), fShadow(false), fFrame(false), fNil(false) { } /// Parses the unsigned char for a BRC BorderCode::BorderCode( unsigned char* bytes, int size ): - cv(0), dptLineWidth(0), brcType(0), ico( Global::ColorNameIdentifier[0] ), dptSpace(0), fShadow(false), fFrame(false), fNil(false) + dptLineWidth(0), brcType(0), ico( Global::ColorIdentifier[0] ), dptSpace(0), fShadow(false), fFrame(false), fNil(false) { if ( FormatUtils::ArraySum( bytes, size ) == ( size * 255 ) ) { fNil = true; } else if ( size == 8 ) - { - //it's a border code of Word 2000/2003 + { //it's a border code of Word 2000/2003 cv = FormatUtils::BytesToInt32( bytes, 0, size ); + BYTE auto_ = GETBITS(*cv, 24, 31); + + if (auto_ == 0) + { + BYTE B = GETBITS(*cv, 0, 7); + BYTE G = GETBITS(*cv, 8, 15); + BYTE R = GETBITS(*cv, 16, 23); + cv = (B << 16) + (G << 8) + (R); + } + else cv = boost::none; + ico = std::wstring( Global::ColorIdentifier[0] ); dptLineWidth = bytes[4]; @@ -71,7 +81,7 @@ namespace DocFileFormat val = FormatUtils::BytesToUInt16( bytes, 2, size ); - ico = FormatUtils::MapValueToWideString( ( val & 0x00FF ), &Global::ColorNameIdentifier[0][0], 17, 12 ); + ico = FormatUtils::MapValueToWideString( ( val & 0x00FF ), &Global::ColorIdentifier[0][0], 17, 12 ); dptSpace = ( val & 0x1F00 ) >> 8; } else if (size == 2) @@ -81,7 +91,7 @@ namespace DocFileFormat dptLineWidth = GETBITS(val, 0, 2); brcType = GETBITS(val, 3, 4); fShadow = GETBIT(val, 5); - ico = FormatUtils::MapValueToWideString(GETBITS(val, 6, 10), &Global::ColorNameIdentifier[0][0], 17, 12 ); + ico = FormatUtils::MapValueToWideString(GETBITS(val, 6, 10), &Global::ColorIdentifier[0][0], 17, 12 ); dptSpace = GETBITS(val, 11, 15); } @@ -100,11 +110,22 @@ namespace DocFileFormat fNil = bc.fNil; } } - + std::wstring BorderCode::getColor() + { + if (cv) + { + return FormatUtils::IntToFormattedWideString(*cv, L"#%06x"); + } + else if (false == ico.empty()) + { + return ico; + } + else return L"auto"; + } bool BorderCode::operator == ( const BorderCode& bc ) { if ( ( cv == bc.cv ) && ( dptLineWidth == bc.dptLineWidth ) && ( brcType == bc.brcType ) && - ( ico == bc.ico ) && ( dptSpace == bc.dptSpace ) && ( fShadow == bc.fShadow ) && + (ico == bc.ico ) && ( dptSpace == bc.dptSpace ) && ( fShadow == bc.fShadow ) && ( fFrame == bc.fFrame ) && ( fNil == bc.fNil ) ) { return true; diff --git a/MsBinaryFile/DocFile/BorderCode.h b/MsBinaryFile/DocFile/BorderCode.h index 2b1c96c1c00..3b7997ae1a4 100644 --- a/MsBinaryFile/DocFile/BorderCode.h +++ b/MsBinaryFile/DocFile/BorderCode.h @@ -73,54 +73,19 @@ namespace DocFileFormat friend class VMLPictureMapping; private: - /// 24-bit border color - int cv; - /// Width of a single line in 1/8pt, max of 32pt + boost::optional<_UINT32> cv; unsigned char dptLineWidth; - /// Border type code: - /// 0 none - /// 1 single - /// 2 thick - /// 3 double - /// 5 hairline - /// 6 dot - /// 7 dash large gap - /// 8 dot dash - /// 9 dot dot dash - /// 10 triple - /// 11 thin-thick small gap - /// 12 tick-thin small gap - /// 13 thin-thick-thin small gap - /// 14 thin-thick medium gap - /// 15 thick-thin medium gap - /// 16 thin-thick-thin medium gap - /// 17 thin-thick large gap - /// 18 thick-thin large gap - /// 19 thin-thick-thin large gap - /// 20 wave - /// 21 double wave - /// 22 dash small gap - /// 23 dash dot stroked - /// 24 emboss 3D - /// 25 engrave 3D unsigned char brcType; - /// The color of the Border. - /// Unused if cv is set. std::wstring ico; - /// Width of space to maintain between border and text within border int dptSpace; - /// When true, border is drawn with shadow. Must be false when BRC is substructure of the TC bool fShadow; - /// When true, don't reverse the border bool fFrame; - /// It's a nil BRC, bytes are FFFF. bool fNil; public: - /// Creates a new BorderCode with default values + std::wstring getColor(); BorderCode(); - /// Parses the unsigned char for a BRC BorderCode( unsigned char* bytes, int size ); BorderCode( const BorderCode& bc ); diff --git a/MsBinaryFile/DocFile/CharacterPropertiesMapping.cpp b/MsBinaryFile/DocFile/CharacterPropertiesMapping.cpp index d3a224d6451..e7e1793cbd4 100644 --- a/MsBinaryFile/DocFile/CharacterPropertiesMapping.cpp +++ b/MsBinaryFile/DocFile/CharacterPropertiesMapping.cpp @@ -485,6 +485,36 @@ namespace DocFileFormat } } } + if (_doc->nWordVersion > 0) + { + if (false == m_sAsciiFont.empty()) + { + if (m_sEastAsiaFont.empty()) + { + m_sEastAsiaFont = m_sAsciiFont; + XMLTools::XMLAttribute* eastAsia = new XMLTools::XMLAttribute(L"w:eastAsia"); + eastAsia->SetValue(FormatUtils::XmlEncode(m_sEastAsiaFont)); + rFonts->AppendAttribute(*eastAsia); + RELEASEOBJECT(eastAsia); + } + if (m_shAnsiFont.empty()) + { + m_shAnsiFont = m_sAsciiFont; + XMLTools::XMLAttribute* ansi = new XMLTools::XMLAttribute(L"w:hAnsi"); + ansi->SetValue(FormatUtils::XmlEncode(m_shAnsiFont)); + rFonts->AppendAttribute(*ansi); + RELEASEOBJECT(ansi); + } + if (m_sCsFont.empty()) + { + m_sCsFont = m_sAsciiFont; + XMLTools::XMLAttribute* cs = new XMLTools::XMLAttribute(L"w:cs"); + cs->SetValue(FormatUtils::XmlEncode(m_sCsFont, true)); + rFonts->AppendAttribute(*cs); + RELEASEOBJECT(cs); + } + } + } if ( lang->GetAttributeCount() > 0 ) { parent->AppendChild( *lang ); @@ -556,7 +586,9 @@ namespace DocFileFormat if ( _styleChpx ) { StyleSheetDescription* thisStyle = _doc->Styles->Styles->at( styleId ); - styleId = (unsigned short)thisStyle->istdBase; + + if (thisStyle) + styleId = (unsigned short)thisStyle->istdBase; } //build the style hierarchy diff --git a/MsBinaryFile/DocFile/DocumentMapping.cpp b/MsBinaryFile/DocFile/DocumentMapping.cpp index 8d484d7077e..9bfde987b1b 100644 --- a/MsBinaryFile/DocFile/DocumentMapping.cpp +++ b/MsBinaryFile/DocFile/DocumentMapping.cpp @@ -143,6 +143,41 @@ namespace DocFileFormat return result; } + std::vector> DocumentMapping::get_subsequence( int cpStart, int cpEnd, int fcStars, int fcEnd ) + { + std::vector> outptu; + + int currentFc = fcStars; + int currentCp = cpStart; + int oldElem = fcStars; + int currentStart = fcStars; + int currentStartcp = cpStart; + + while ( cpEnd > currentCp) + { + currentCp ++; + currentFc = m_document->FindFileCharPos(currentCp); + if (currentFc < oldElem) + { + currentStart = currentFc; + outptu.emplace_back(currentStartcp, currentCp - 1); + currentStartcp = currentCp; + } + /*else if (currentFc > oldElem) + { + } + else + { + // -1 //че-нить в лог написать + }*/ + + oldElem = currentFc; + } + outptu.emplace_back(currentStartcp, currentCp); + + return outptu; + } + // Writes a Paragraph that starts at the given cp and // ends at the next paragraph end mark or section end mark @@ -178,13 +213,49 @@ namespace DocFileFormat bool sectionEnd = isSectionEnd(cpParaEnd); cpParaEnd++; - return writeParagraph(cp, cpParaEnd, sectionEnd); + return writeParagraph(cp, cpParaEnd, sectionEnd, false, START_END_PARAGRAPH); } else { cpParaEnd++; - - return writeParagraph(cp, (std::min)(cpEnd, cpParaEnd), false); + + int inpCpEnd = ( std::min )( cpEnd, cpParaEnd ); + int fc = m_document->FindFileCharPos( cp ); + int fcEnd = m_document->FindFileCharPos( inpCpEnd ); + + if ( fc < 0 || fcEnd < 0 || fc == fcEnd ) + return -1; + + std::vector> cpStartEnd = get_subsequence( cp, inpCpEnd, fc, fcEnd ); + if (cpStartEnd.empty()) + { + return -1; + } + if ( cpStartEnd.size() == 1 ) + { + return writeParagraph(cpStartEnd.front().first, cpStartEnd.front().second, false, false, START_END_PARAGRAPH); + } + + int retCp = cpParaEnd; + for (auto elem : cpStartEnd) + { + int curCpStart = elem.first; + int curCpEnd = elem.second; + + if (elem == cpStartEnd.front()) + { + retCp = writeParagraph(curCpStart, curCpEnd, false, false, START_PARAGRAPH); + } + else if (elem == cpStartEnd.back()) + { + retCp = writeParagraph(curCpStart, curCpEnd, false, false, END_PARAGRAPH); + } + else + { + retCp = writeParagraph(curCpStart, curCpEnd, false, false, NOSTART_NOEND_PARAGRAPH); + } + } + return retCp; } } @@ -194,29 +265,21 @@ namespace DocFileFormat // Writes a Paragraph that starts at the given cpStart and // ends at the given cpEnd - int DocumentMapping::writeParagraph (int initialCp, int cpEnd, bool sectionEnd, bool lastBad) + int DocumentMapping::writeParagraph( int initialCp, int cpEnd, bool sectionEnd, bool lastBad, int paragraphState ) { int cp = initialCp; int fc = m_document->FindFileCharPos(cp); int fcEnd = m_document->FindFileCharPos(cpEnd); - if (fc < 0 || fcEnd < 0 || fc == fcEnd) - return -1; - ParagraphPropertyExceptions* papx = findValidPapx(fc); // get all CHPX between these boundaries to determine the count of runs - + std::vector* chpxs = m_document->GetCharacterPropertyExceptions(fc, fcEnd); std::vector* chpxFcs = m_document->GetFileCharacterPositions(fc, fcEnd); CharacterPropertyExceptions* paraEndChpx = NULL; - if (chpxFcs) - { - chpxFcs->push_back(fcEnd); - } - if (chpxs) { // the last of these CHPX formats the paragraph end mark @@ -224,7 +287,8 @@ namespace DocFileFormat } // start paragraph - + if ( paragraphState & START_PARAGRAPH ) + { m_pXmlWriter->WriteNodeBegin(L"w:p", true); if (false == _paraId.empty()) @@ -232,6 +296,8 @@ namespace DocFileFormat m_pXmlWriter->WriteAttribute(L"w14:paraId", _paraId); } writeParagraphRsid(papx); + } + // ----------- check for section properties bool isBidi = false; @@ -247,8 +313,8 @@ namespace DocFileFormat { // this is the last paragraph of this section // write properties with section properties - - if (papx) + + if ( papx && ( paragraphState & START_PARAGRAPH ) ) { ParagraphPropertiesMapping oMapping(m_pXmlWriter, m_context, m_document, paraEndChpx, isBidi, findValidSepx(cpEnd), _sectionNr); papx->Convert(&oMapping); @@ -261,8 +327,8 @@ namespace DocFileFormat else { // write properties - - if (papx) + + if ( papx && ( paragraphState & START_PARAGRAPH ) ) { ParagraphPropertiesMapping oMapping(m_pXmlWriter, m_context, m_document, paraEndChpx, isBidi); papx->Convert(&oMapping); @@ -278,7 +344,7 @@ namespace DocFileFormat { //get the FC range for this run - int fcChpxStart = chpxFcs ? chpxFcs->at(i) : fc; + int fcChpxStart = ((chpxFcs) && (i < chpxFcs->size())) ? chpxFcs->at(i) : fc; int fcChpxEnd = fcEnd; if ((chpxFcs) && ( i < chpxFcs->size() - 1)) @@ -372,18 +438,18 @@ namespace DocFileFormat } //end paragraph - m_pXmlWriter->WriteNodeEnd(L"w:p"); + if ( paragraphState & END_PARAGRAPH ) m_pXmlWriter->WriteNodeEnd( L"w:p" ); } else { //end paragraph - m_pXmlWriter->WriteNodeEnd(L"w:p"); + if ( paragraphState & END_PARAGRAPH ) m_pXmlWriter->WriteNodeEnd( L"w:p" ); } RELEASEOBJECT(chpxFcs); RELEASEOBJECT(chpxs); - return cpEnd++; + return cpEnd; return (std::max)(cp, cpEnd); //ralph_scovile.doc } @@ -668,7 +734,7 @@ namespace DocFileFormat _skipRuns = 5; //with separator } } - else if ( bEMBED || (bLINK && !bHYPERLINK)|| bQUOTE) + else if ( bEMBED || (bLINK && !bHYPERLINK)/*|| bQUOTE*/) { int cpPic = searchNextTextMark(m_document->Text, cpFieldStart, TextMark::Picture); int cpFieldSep = searchNextTextMark(m_document->Text, cpFieldStart, TextMark::FieldSeparator); @@ -1441,7 +1507,7 @@ namespace DocFileFormat case sprmPFInnerTableCell: case sprmPFInnerTtp: { - fEndNestingLevel = ( iter->Arguments[0] == 1 && (nestingLevel == iTap_current)) ? (true) : (false); + fEndNestingLevel = ( iter->Arguments[0] == 1 ) ? (true) : (false); }break; case sprmOldPFInTable: @@ -1453,6 +1519,8 @@ namespace DocFileFormat break; } } + fEndNestingLevel == (nestingLevel == iTap_current) ? fEndNestingLevel : false; + if (nestingLevel == iTap_current) { bool bPresent = false; //118854.doc @@ -1485,7 +1553,7 @@ namespace DocFileFormat } } } - if ((nestingLevel != iTap_current || fEndNestingLevel) && !mapBoundaries.empty()) + if ((nestingLevel != iTap_current && fEndNestingLevel) && !mapBoundaries.empty()) break; //get the next papx papx = findValidPapx( fcRowEnd ); diff --git a/MsBinaryFile/DocFile/DocumentMapping.h b/MsBinaryFile/DocFile/DocumentMapping.h index bbe76a0c24c..33c4e02ad56 100644 --- a/MsBinaryFile/DocFile/DocumentMapping.h +++ b/MsBinaryFile/DocFile/DocumentMapping.h @@ -51,6 +51,11 @@ #include "FormFieldData.h" #include "FormFieldDataMapping.h" +#define START_PARAGRAPH 0x1 +#define END_PARAGRAPH 0x2 +#define START_END_PARAGRAPH 0x3 +#define NOSTART_NOEND_PARAGRAPH 0x0 + namespace DocFileFormat { class FootnotesMapping; @@ -87,7 +92,7 @@ namespace DocFileFormat bool isSectionEnd ( int cp ); int writeParagraph( int cp, int cpEnd ); - int writeParagraph( int initialCp, int cpEnd, bool sectionEnd, bool lastBad = false ); + int writeParagraph( int initialCp, int cpEnd, bool sectionEnd, bool lastBad = false, int paragraphState = 0 ); int writeRun( std::vector* chars, CharacterPropertyExceptions* chpx, int initialCp ); int writeText ( std::vector* chars, int initialCp, CharacterPropertyExceptions* chpx, bool writeDeletedText ); void writeParagraphRsid ( const ParagraphPropertyExceptions* papx ); @@ -132,6 +137,8 @@ namespace DocFileFormat Symbol getSymbol ( const CharacterPropertyExceptions* chpx ); void AddBoundary(short boundary1, short boundary2, std::map &boundaries); + + std::vector> get_subsequence(int cpStart, int cpEnd, int fcStars, int fcEnd); //---------------------------------------------------------------------------------------------------------------------- bool m_bInternalXmlWriter; diff --git a/MsBinaryFile/DocFile/DocumentProperties.cpp b/MsBinaryFile/DocFile/DocumentProperties.cpp index aaaf5725cfb..8b5c19185b9 100644 --- a/MsBinaryFile/DocFile/DocumentProperties.cpp +++ b/MsBinaryFile/DocFile/DocumentProperties.cpp @@ -574,7 +574,6 @@ namespace DocFileFormat } else if ( nFib < Fib1997 ) { - //throw new UnspportedFileVersionException(); } } @@ -749,7 +748,7 @@ namespace DocFileFormat fAutofitLikeWW11 = false; fUnderlineTabInNumList = false; fHangulWidthLikeWW11 = false; - fSplitPgBreakAndParaMark = false; + fSplitPgBreakAndParaMark = true; fDontVertAlignCellWithSp = false; fDontBreakConstrainedForcedTables = false; fDontVertAlignInTxbx = false; diff --git a/MsBinaryFile/DocFile/DocumentTypographyInfo.cpp b/MsBinaryFile/DocFile/DocumentTypographyInfo.cpp index 89dd5199a20..f7eb053b202 100644 --- a/MsBinaryFile/DocFile/DocumentTypographyInfo.cpp +++ b/MsBinaryFile/DocFile/DocumentTypographyInfo.cpp @@ -63,13 +63,9 @@ namespace DocFileFormat this->cchFollowingPunct = FormatUtils::BytesToInt16( bytes, 2, size ); this->cchLeadingPunct = FormatUtils::BytesToInt16( bytes, 4, size ); - unsigned char fpunctBytes[202]; - memcpy( fpunctBytes, ( bytes + 6 ), 202 ); - FormatUtils::GetSTLCollectionFromBytes( &(this->rgxchFPunct), fpunctBytes, 202, ENCODING_UTF16 ); + this->rgxchFPunct = NSFile::CUtf8Converter::GetWStringFromUTF16((unsigned short*)(bytes + 6), 202 / 2); + this->rgxchLPunct = NSFile::CUtf8Converter::GetWStringFromUTF16((unsigned short*)(bytes + 208), 102 / 2); - unsigned char lpunctBytes[102]; - memcpy( lpunctBytes, ( bytes + 208 ), 102 ); - FormatUtils::GetSTLCollectionFromBytes( &(this->rgxchLPunct), lpunctBytes, 102, ENCODING_UTF16 ); } else { diff --git a/MsBinaryFile/DocFile/FontFamilyName.cpp b/MsBinaryFile/DocFile/FontFamilyName.cpp index 1420d12ca03..dddd9526683 100644 --- a/MsBinaryFile/DocFile/FontFamilyName.cpp +++ b/MsBinaryFile/DocFile/FontFamilyName.cpp @@ -107,11 +107,11 @@ namespace DocFileFormat if (reader->nWordVersion > 0) { - FormatUtils::GetSTLCollectionFromBytes( &(newObject->xszFtn), bytes, (int)( strEnd - strStart ), ENCODING_WINDOWS_1250 ); + FormatUtils::GetWStringFromBytes(newObject->xszFtn, bytes, (int)( strEnd - strStart ), ENCODING_WINDOWS_1250 ); } else { - FormatUtils::GetSTLCollectionFromBytes( &(newObject->xszFtn), bytes, (int)( strEnd - strStart ), ENCODING_UTF16 ); + newObject->xszFtn = NSFile::CUtf8Converter::GetWStringFromUTF16((unsigned short*)(bytes), (strEnd - strStart) / 2); } if (newObject->xszFtn.length() > 0) @@ -141,11 +141,11 @@ namespace DocFileFormat if (reader->nWordVersion > 0) { - FormatUtils::GetSTLCollectionFromBytes( &(newObject->xszAlt), bytes, (int)( strEnd - strStart ), ENCODING_WINDOWS_1250); + FormatUtils::GetWStringFromBytes( newObject->xszAlt, bytes, (int)( strEnd - strStart ), ENCODING_WINDOWS_1250); } else { - FormatUtils::GetSTLCollectionFromBytes( &(newObject->xszAlt), bytes, (int)( strEnd - strStart ), ENCODING_UTF16 ); + newObject->xszAlt = NSFile::CUtf8Converter::GetWStringFromUTF16((unsigned short*)(bytes), (strEnd - strStart) / 2); } RELEASEARRAYOBJECTS( bytes ); } diff --git a/MsBinaryFile/DocFile/FormFieldData.cpp b/MsBinaryFile/DocFile/FormFieldData.cpp index c1bb7388ea5..1eb0bd21afb 100644 --- a/MsBinaryFile/DocFile/FormFieldData.cpp +++ b/MsBinaryFile/DocFile/FormFieldData.cpp @@ -36,42 +36,65 @@ namespace DocFileFormat { -std::wstring readXstz(VirtualStreamReader *reader) +std::wstring readXstz(VirtualStreamReader *reader, bool bWide) { if (!reader) return L""; unsigned short flags, cch, chTerm; - - cch = reader->ReadUInt16(); - std::wstring ret; - if (cch > 0 && cch < 0x0fff) + if (bWide) { - std::shared_ptrdata = std::shared_ptr(reader->ReadBytes(cch * 2, true)); + cch = reader->ReadUInt16(); + + if (cch > 0 && cch < 0x0fff) + { + std::shared_ptrdata = std::shared_ptr(reader->ReadBytes(cch * 2, true)); #if defined(_WIN32) || defined(_WIN64) - ret = std::wstring((wchar_t*)data.get(), cch ); + ret = std::wstring((wchar_t*)data.get(), cch); #else - ret = convertUtf16ToWString((UTF16*)data.get(), cch ); + ret = convertUtf16ToWString((UTF16*)data.get(), cch); #endif + } + chTerm = reader->ReadUInt16(); + } + else + { + short cch = reader->ReadByte(); + + unsigned char* chars = reader->ReadBytes(cch, true); + FormatUtils::GetWStringFromBytes(ret, chars, cch, ENCODING_WINDOWS_1250); + + RELEASEARRAYOBJECTS(chars); } - chTerm = reader->ReadUInt16(); return ret; }; -void FormFieldData::_HFD::read(VirtualStreamReader *reader) +void FormFieldData::_HFD::read(VirtualStreamReader *reader, int size) { if (!reader) return; } -void FormFieldData::_FFData::read(VirtualStreamReader *reader) +void FormFieldData::_FFData::read(VirtualStreamReader *reader, int size) { if (!reader) return; bExist = true; - unsigned short flags; + unsigned short flags, version; + bool bWide = true; + + if (0xff == reader->ReadByte()) + { + version = 0xFFFFFFFF; //must be 0xFFFFFFFF + reader->ReadBytes(3, false); + } + else + { + reader->ReadBytes(1, false); + version = 0; + bWide = false; + } - version = reader->ReadUInt32(); flags = reader->ReadUInt16(); iType = GETBITS(flags, 0, 1); @@ -87,22 +110,22 @@ void FormFieldData::_FFData::read(VirtualStreamReader *reader) cch_field = reader->ReadUInt16(); hps = reader->ReadUInt16(); - xstzName = readXstz(reader); - + xstzName = readXstz(reader, bWide); + if (iType == 0) { - xstzTextDef = readXstz(reader); + xstzTextDef = readXstz(reader, bWide); } else if (iType == 1 || iType == 2) { wDef = reader->ReadUInt16(); } - xstzTextFormat = readXstz(reader); - xstzHelpText = readXstz(reader); - xstzStatText = readXstz(reader); - xstzEntryMcr = readXstz(reader); - xstzExitMcr = readXstz(reader); + xstzTextFormat = readXstz(reader, bWide); + xstzHelpText = readXstz(reader, bWide); + xstzStatText = readXstz(reader, bWide); + xstzEntryMcr = readXstz(reader, bWide); + xstzExitMcr = readXstz(reader, bWide); if (iType == 2) { @@ -185,18 +208,25 @@ FormFieldData::FormFieldData( int type, const CharacterPropertyExceptions* chpx, //ignored reader.ReadBytes(62, false); + _UINT32 pos = reader.GetPosition(); + switch(type) { - case 1: - HFD.read(&reader); - case 2: - FFData.read(&reader); - break; - default: - binary_data_size = lcb - cbHeader; - binary_data = std::shared_ptr(reader.ReadBytes(binary_data_size, true)); - break; + case 1: + { + HFD.read(&reader, lcb - cbHeader); + }break; + case 2: + { + FFData.read(&reader, lcb - cbHeader); + }break; + default: + { + binary_data_size = lcb - cbHeader; + binary_data = std::shared_ptr(reader.ReadBytes(binary_data_size, true)); + }break; } + reader.Seek(pos + (lcb - cbHeader), 0); } } diff --git a/MsBinaryFile/DocFile/FormFieldData.h b/MsBinaryFile/DocFile/FormFieldData.h index 59de05599ad..8f37e25a1f6 100644 --- a/MsBinaryFile/DocFile/FormFieldData.h +++ b/MsBinaryFile/DocFile/FormFieldData.h @@ -77,7 +77,7 @@ namespace DocFileFormat std::wstring guid; _UINT64 fileTime = 0; - void read(VirtualStreamReader* reader); + void read(VirtualStreamReader* reader, int size); }; struct _FFData { @@ -106,7 +106,7 @@ namespace DocFileFormat std::wstring xstzExitMcr; //STTB hsttbDropList; - void read(VirtualStreamReader* reader); + void read(VirtualStreamReader* reader, int size); }; FormFieldData( int type, const CharacterPropertyExceptions* chpx, POLE::Stream* stream, int nWordVersion ); virtual ~FormFieldData() {} diff --git a/MsBinaryFile/DocFile/FormattedDiskPageCHPX.cpp b/MsBinaryFile/DocFile/FormattedDiskPageCHPX.cpp index ca971e4954e..61224cc9684 100644 --- a/MsBinaryFile/DocFile/FormattedDiskPageCHPX.cpp +++ b/MsBinaryFile/DocFile/FormattedDiskPageCHPX.cpp @@ -36,24 +36,24 @@ namespace DocFileFormat { FormattedDiskPageCHPX::~FormattedDiskPageCHPX() { - RELEASEARRAYOBJECTS( rgfc ); - RELEASEARRAYOBJECTS( rgb ); + RELEASEARRAYOBJECTS(rgfc); + RELEASEARRAYOBJECTS(rgb); - if ( grpchpx != NULL ) + if (grpchpx != NULL) { - for ( unsigned int i = 0; i < grpchpxSize; i++ ) + for (unsigned int i = 0; i < grpchpxSize; i++) { - RELEASEOBJECT( grpchpx[i] ); + RELEASEOBJECT(grpchpx[i]); } - RELEASEARRAYOBJECTS( grpchpx ); + RELEASEARRAYOBJECTS(grpchpx); } } /*========================================================================================================*/ - FormattedDiskPageCHPX::FormattedDiskPageCHPX( POLE::Stream* wordStream, int offset, int nWordVersion ): - FormattedDiskPage(), rgb(NULL), grpchpxSize(0), grpchpx(NULL) + FormattedDiskPageCHPX::FormattedDiskPageCHPX(POLE::Stream* wordStream, int offset, int nWordVersion) : + FormattedDiskPage(), rgb(NULL), grpchpxSize(0), grpchpx(NULL) { Type = Character; WordStream = wordStream; @@ -62,8 +62,8 @@ namespace DocFileFormat unsigned char* bytes = NULL; bytes = new unsigned char[512]; - WordStream->seek( offset); - WordStream->read( bytes, 512 ); + WordStream->seek(offset); + WordStream->read(bytes, 512); //get the count first crun = bytes[511]; @@ -74,28 +74,28 @@ namespace DocFileFormat int j = 0; - for ( unsigned int i = 0; i < rgfcSize; i++ ) + for (unsigned int i = 0; i < rgfcSize; i++) { - rgfc[i] = FormatUtils::BytesToInt32( bytes, j, 512 ); + rgfc[i] = FormatUtils::BytesToInt32(bytes, j, 512); j += 4; } - grpchpxSize = crun; - rgb = new unsigned char[crun]; - grpchpx = new CharacterPropertyExceptions*[grpchpxSize]; + grpchpxSize = crun; + rgb = new unsigned char[crun]; + grpchpx = new CharacterPropertyExceptions * [grpchpxSize]; - j = 4 * ( crun + 1 ); + j = 4 * (crun + 1); unsigned char* chpx = NULL; - for ( int i = 0; i < crun; i++ ) + for (int i = 0; i < crun; i++) { //fill the rgb array unsigned char wordOffset = bytes[j]; rgb[i] = wordOffset; j++; - if ( wordOffset != 0 ) + if (wordOffset != 0) { //read first unsigned char of CHPX //it's the count of bytes @@ -103,12 +103,12 @@ namespace DocFileFormat //read the bytes of chpx chpx = new unsigned char[cb]; - memcpy( chpx, ( bytes + (wordOffset * 2) + 1 ), cb ); + memcpy(chpx, (bytes + (wordOffset * 2) + 1), cb); //parse CHPX and fill grpchpx - grpchpx[i] = new CharacterPropertyExceptions( chpx, cb, nWordVersion); + grpchpx[i] = new CharacterPropertyExceptions(chpx, cb, nWordVersion); - RELEASEARRAYOBJECTS( chpx ); + RELEASEARRAYOBJECTS(chpx); } else { @@ -117,18 +117,20 @@ namespace DocFileFormat } } - RELEASEARRAYOBJECTS( bytes ); + RELEASEARRAYOBJECTS(bytes); } /*========================================================================================================*/ /// Parses the 0Table (or 1Table) for FKP _entries containing CHPX - std::vector* FormattedDiskPageCHPX::GetAllCHPXFKPs( FileInformationBlock* fib, POLE::Stream* wordStream, POLE::Stream* tableStream ) + std::vector* FormattedDiskPageCHPX::GetAllCHPXFKPs(FileInformationBlock* fib, POLE::Stream* wordStream, POLE::Stream* tableStream) { std::vector* CHPXlist = new std::vector(); - //get bintable for CHPX - unsigned char* binTableChpx = new unsigned char[fib->m_FibWord97.lcbPlcfBteChpx]; + if ((fib->m_FibWord97.lcbPlcfBteChpx < 4 && fib->m_nWordVersion == 0) || fib->m_FibWord97.lcbPlcfBteChpx < 8) return CHPXlist; + + //get bintable for CHPX + unsigned char* binTableChpx = new unsigned char[fib->m_FibWord97.lcbPlcfBteChpx + 1]; if (tableStream) { @@ -139,7 +141,7 @@ namespace DocFileFormat if (fib->m_nWordVersion > 0) { - int n = ( ( (int)fib->m_FibWord97.lcbPlcfBteChpx - 8 ) / 6 ) + 1; + int n = ( ( (int)fib->m_FibWord97.lcbPlcfBteChpx - 8 ) / 6 ) + 1; unsigned int first = FormatUtils::BytesToInt32(binTableChpx, 0, fib->m_FibWord97.lcbPlcfBteChpx ); unsigned int last = FormatUtils::BytesToInt32(binTableChpx, 4, fib->m_FibWord97.lcbPlcfBteChpx ); diff --git a/MsBinaryFile/DocFile/FormattedDiskPagePAPX.cpp b/MsBinaryFile/DocFile/FormattedDiskPagePAPX.cpp index c817eabf6d4..29120f3ea9d 100644 --- a/MsBinaryFile/DocFile/FormattedDiskPagePAPX.cpp +++ b/MsBinaryFile/DocFile/FormattedDiskPagePAPX.cpp @@ -36,24 +36,24 @@ namespace DocFileFormat { FormattedDiskPagePAPX::~FormattedDiskPagePAPX() { - RELEASEARRAYOBJECTS( rgfc ); - RELEASEARRAYOBJECTS( rgbx ); + RELEASEARRAYOBJECTS(rgfc); + RELEASEARRAYOBJECTS(rgbx); - if ( grppapx != NULL ) - { - for ( unsigned int i = 0; i < grppapxSize; i++ ) + if (grppapx != NULL) { - RELEASEOBJECT( grppapx[i] ); - } + for (unsigned int i = 0; i < grppapxSize; i++) + { + RELEASEOBJECT(grppapx[i]); + } - RELEASEARRAYOBJECTS( grppapx ); - } + RELEASEARRAYOBJECTS(grppapx); + } } /*========================================================================================================*/ - - FormattedDiskPagePAPX::FormattedDiskPagePAPX( POLE::Stream* wordStream, int offset, POLE::Stream* dataStream, int nWordVersion, bool fComplex): - FormattedDiskPage(), rgbx(NULL), grppapxSize(0), grppapx(NULL) + + FormattedDiskPagePAPX::FormattedDiskPagePAPX(POLE::Stream* wordStream, int offset, POLE::Stream* dataStream, int nWordVersion, bool fComplex) : + FormattedDiskPage(), rgbx(NULL), grppapxSize(0), grppapx(NULL) { Type = Paragraph; WordStream = wordStream; @@ -62,90 +62,90 @@ namespace DocFileFormat unsigned char* bytes = NULL; bytes = new unsigned char[512]; - WordStream->seek( offset); - WordStream->read( bytes, 512); + WordStream->seek(offset); + WordStream->read(bytes, 512); //get the count crun = bytes[511]; //create and fill the array with the adresses - rgfcSize = crun + 1; - rgfc = new int[rgfcSize]; + rgfcSize = crun + 1; + rgfc = new int[rgfcSize]; int j = 0; - - for ( unsigned int i = 0; i < rgfcSize; i++ ) + + for (unsigned int i = 0; i < rgfcSize; i++) { - rgfc[i] = FormatUtils::BytesToInt32( bytes, j, 512 ); + rgfc[i] = FormatUtils::BytesToInt32(bytes, j, 512); j += 4; } rgbx = new BX[crun]; grppapxSize = crun; - grppapx = new ParagraphPropertyExceptions*[grppapxSize]; + grppapx = new ParagraphPropertyExceptions * [grppapxSize]; - for ( unsigned int i = 0; i < grppapxSize; i++ ) + for (unsigned int i = 0; i < grppapxSize; i++) { grppapx[i] = NULL; } - j = 4 * ( crun + 1 ); + j = 4 * (crun + 1); unsigned char phe[12]; - - for ( unsigned char i = 0; i < crun; i++ ) + + for (unsigned char i = 0; i < crun; i++) { BX bx; bx.wordOffset = bytes[j]; j++; - + if (fComplex || nWordVersion == 0) { - memcpy( phe, ( bytes + j), 12 ); + memcpy(phe, (bytes + j), 12); //fill the rgbx array - bx.phe = ParagraphHeight( phe, 12, false ); + bx.phe = ParagraphHeight(phe, 12, false); j += 12; } else if (nWordVersion == 2) { - memcpy( phe, ( bytes + bx.wordOffset * 2 + j + 1), 6); + memcpy(phe, (bytes + bx.wordOffset * 2 + j + 1), 6); //fill the rgbx array - bx.phe = ParagraphHeight( phe, 6, false ); + bx.phe = ParagraphHeight(phe, 6, false); } else { - memcpy( phe, ( bytes + j), 6); + memcpy(phe, (bytes + j), 6); //fill the rgbx array - bx.phe = ParagraphHeight( phe, 6, false ); + bx.phe = ParagraphHeight(phe, 6, false); j += 6; } rgbx[i] = bx; - if ( bx.wordOffset != 0 ) + if (bx.wordOffset != 0) { unsigned char padbyte = 0; unsigned char cw = bytes[bx.wordOffset * 2]; //if that unsigned char is zero, it's a pad unsigned char, and the word count is the following unsigned char - if ( cw == 0 ) + if (cw == 0) { padbyte = 1; cw = bytes[bx.wordOffset * 2 + 1]; } - if ( cw != 0 ) + if (cw != 0) { int sz = cw * 2; //read the bytes for papx unsigned char* papx = new unsigned char[sz]; - memcpy( papx, ( bytes + (bx.wordOffset * 2) + padbyte + 1 ), sz ); + memcpy(papx, (bytes + (bx.wordOffset * 2) + padbyte + 1), sz); //parse PAPX and fill grppapx - grppapx[i] = new ParagraphPropertyExceptions( papx, sz, dataStream, nWordVersion ); + grppapx[i] = new ParagraphPropertyExceptions(papx, sz, dataStream, nWordVersion); - RELEASEARRAYOBJECTS( papx ); + RELEASEARRAYOBJECTS(papx); } } @@ -156,51 +156,53 @@ namespace DocFileFormat } } - RELEASEARRAYOBJECTS( bytes ); + RELEASEARRAYOBJECTS(bytes); } /*========================================================================================================*/ /// Parses the 0Table (or 1Table) for FKP _entries containing PAPX - std::vector* FormattedDiskPagePAPX::GetAllPAPXFKPs( FileInformationBlock* fib, POLE::Stream* wordStream, POLE::Stream* tableStream, POLE::Stream* dataStream) - { - std::vector* PAPXlist = new std::vector(); - - //get bintable for PAPX - unsigned char* binTablePapx = new unsigned char[fib->m_FibWord97.lcbPlcfBtePapx]; - - if (tableStream) - { - tableStream->seek( fib->m_FibWord97.fcPlcfBtePapx); - tableStream->read( binTablePapx, fib->m_FibWord97.lcbPlcfBtePapx); - } - - //there are n offsets and n-1 fkp's in the bin table - - if (fib->m_nWordVersion > 0 && fib->m_FibBase.fComplex == false) - { - int n = ( ( (int)fib->m_FibWord97.lcbPlcfBtePapx - 8 ) / 6 ) + 1; - - unsigned int first = FormatUtils::BytesToInt32(binTablePapx, 0, fib->m_FibWord97.lcbPlcfBtePapx ); - unsigned int last = FormatUtils::BytesToInt32(binTablePapx, 4, fib->m_FibWord97.lcbPlcfBtePapx ); - + std::vector* FormattedDiskPagePAPX::GetAllPAPXFKPs(FileInformationBlock* fib, POLE::Stream* wordStream, POLE::Stream* tableStream, POLE::Stream* dataStream) + { + std::vector* PAPXlist = new std::vector(); + + if ((fib->m_FibWord97.lcbPlcfBtePapx < 8 && fib->m_nWordVersion > 0 && fib->m_FibBase.fComplex == false) || fib->m_FibWord97.lcbPlcfBtePapx < 4) return PAPXlist; + + //get bintable for PAPX + unsigned char* binTablePapx = new unsigned char[fib->m_FibWord97.lcbPlcfBtePapx + 1]; + + if (tableStream) + { + tableStream->seek(fib->m_FibWord97.fcPlcfBtePapx); + tableStream->read(binTablePapx, fib->m_FibWord97.lcbPlcfBtePapx); + } + + //there are n offsets and n-1 fkp's in the bin table + + if (fib->m_nWordVersion > 0 && fib->m_FibBase.fComplex == false) + { + int n = (((int)fib->m_FibWord97.lcbPlcfBtePapx - 8) / 6) + 1; + + unsigned int first = FormatUtils::BytesToInt32(binTablePapx, 0, fib->m_FibWord97.lcbPlcfBtePapx); + unsigned int last = FormatUtils::BytesToInt32(binTablePapx, 4, fib->m_FibWord97.lcbPlcfBtePapx); + int start_papx = 8; - if (fib->m_FibWord97.lcbPlcfBtePapx - 8 > (n - 1) * 4) + if (fib->m_FibWord97.lcbPlcfBtePapx - 8 > (n - 1) * 4) { - start_papx+= ((n-1) * 4); //дублирование crun + start_papx += ((n - 1) * 4); //дублирование crun } int offset = 0; - for ( unsigned int i = start_papx; i < fib->m_FibWord97.lcbPlcfBtePapx; i += 2 ) + for (unsigned int i = start_papx; i < fib->m_FibWord97.lcbPlcfBtePapx; i += 2) { //indexed FKP is the xth 512byte page - int fkpnr = FormatUtils::BytesToInt16( binTablePapx, i, fib->m_FibWord97.lcbPlcfBtePapx ); + int fkpnr = FormatUtils::BytesToInt16(binTablePapx, i, fib->m_FibWord97.lcbPlcfBtePapx); //so starts at: int offset = fkpnr * 512; //parse the FKP and add it to the list - PAPXlist->push_back( new FormattedDiskPagePAPX( wordStream, offset, dataStream, fib->m_nWordVersion, fib->m_FibBase.fComplex) ); + PAPXlist->push_back(new FormattedDiskPagePAPX(wordStream, offset, dataStream, fib->m_nWordVersion, fib->m_FibBase.fComplex)); } //if (PAPXlist->back()->rgfc[PAPXlist->back()->rgfcSize-1] < last) @@ -210,112 +212,112 @@ namespace DocFileFormat // //offset+=512; // //PAPXlist->push_back( new FormattedDiskPagePAPX( wordStream, offset, dataStream ) ); //} - } - else - { - int n = ( ( (int)fib->m_FibWord97.lcbPlcfBtePapx - 4 ) / 8 ) + 1; - //Get the indexed PAPX FKPs - for ( unsigned int i = ( n * 4 ); i < fib->m_FibWord97.lcbPlcfBtePapx; i += 4 ) - { - //indexed FKP is the xth 512byte page - int fkpnr = FormatUtils::BytesToInt32( binTablePapx, i, fib->m_FibWord97.lcbPlcfBtePapx ); - - //so starts at: - int offset = fkpnr * 512; - - //parse the FKP and add it to the list - PAPXlist->push_back( new FormattedDiskPagePAPX( wordStream, offset, dataStream, fib->m_nWordVersion, fib->m_FibBase.fComplex) ); - } - - } - - RELEASEARRAYOBJECTS( binTablePapx ); - - return PAPXlist; - } + } + else + { + int n = (((int)fib->m_FibWord97.lcbPlcfBtePapx - 4) / 8) + 1; + //Get the indexed PAPX FKPs + for (unsigned int i = (n * 4); i < fib->m_FibWord97.lcbPlcfBtePapx; i += 4) + { + //indexed FKP is the xth 512byte page + int fkpnr = FormatUtils::BytesToInt32(binTablePapx, i, fib->m_FibWord97.lcbPlcfBtePapx); + + //so starts at: + int offset = fkpnr * 512; + + //parse the FKP and add it to the list + PAPXlist->push_back(new FormattedDiskPagePAPX(wordStream, offset, dataStream, fib->m_nWordVersion, fib->m_FibBase.fComplex)); + } + + } + + RELEASEARRAYOBJECTS(binTablePapx); + + return PAPXlist; + } /*========================================================================================================*/ /// Returns a list of all PAPX FCs between they given boundaries. std::vector* FormattedDiskPagePAPX::GetFileCharacterPositions ( - int fcMin, - int fcMax, - FileInformationBlock* fib, - POLE::Stream* wordStream, - POLE::Stream* tableStream, - POLE::Stream* dataStream + int fcMin, + int fcMax, + FileInformationBlock* fib, + POLE::Stream* wordStream, + POLE::Stream* tableStream, + POLE::Stream* dataStream ) - { - std::vector* cpList = new std::vector(); - std::vector *fkps = FormattedDiskPagePAPX::GetAllPAPXFKPs( fib, wordStream, tableStream, dataStream ); - unsigned int i = 0; - FormattedDiskPagePAPX* fkp = NULL; - - for (size_t i = 0; i < fkps->size(); ++i ) - { - fkp = fkps->at(i); - - //the last entry of each is always the same as the first entry of the next FKP - //so, ignore all last _entries except for the last FKP. - int max_ = fkp->rgfcSize; - - if ( i++ < fkps->size() - 1 ) + { + std::vector* cpList = new std::vector(); + std::vector* fkps = FormattedDiskPagePAPX::GetAllPAPXFKPs(fib, wordStream, tableStream, dataStream); + unsigned int i = 0; + FormattedDiskPagePAPX* fkp = NULL; + + for (size_t i = 0; i < fkps->size(); ++i) { - max_--; - } - - for ( int j = 0; j < max_; j++ ) - { - if( ( fkp->rgfc[j] >= fcMin ) && ( fkp->rgfc[j] < fcMax ) ) - { - cpList->push_back( fkp->rgfc[j] ); - } - } + fkp = fkps->at(i); - RELEASEOBJECT( fkp ); - } + //the last entry of each is always the same as the first entry of the next FKP + //so, ignore all last _entries except for the last FKP. + int max_ = fkp->rgfcSize; - fkps->clear(); - RELEASEOBJECT( fkps ); + if (i++ < fkps->size() - 1) + { + max_--; + } - return cpList; - } + for (int j = 0; j < max_; j++) + { + if ((fkp->rgfc[j] >= fcMin) && (fkp->rgfc[j] < fcMax)) + { + cpList->push_back(fkp->rgfc[j]); + } + } + + RELEASEOBJECT(fkp); + } + + fkps->clear(); + RELEASEOBJECT(fkps); + + return cpList; + } /*========================================================================================================*/ - /// Returnes a list of all ParagraphPropertyExceptions which correspond to text - /// between the given offsets. + /// Returnes a list of all ParagraphPropertyExceptions which correspond to text + /// between the given offsets. std::vector* FormattedDiskPagePAPX::GetParagraphPropertyExceptions ( - int fcMin, - int fcMax, - FileInformationBlock* fib, - POLE::Stream* wordStream, - POLE::Stream* tableStream, - POLE::Stream* dataStream + int fcMin, + int fcMax, + FileInformationBlock* fib, + POLE::Stream* wordStream, + POLE::Stream* tableStream, + POLE::Stream* dataStream ) - { - std::vector* ppxList = new std::vector(); - std::vector* fkps = FormattedDiskPagePAPX::GetAllPAPXFKPs( fib, wordStream, tableStream, dataStream ); - - for (size_t i = 0; i < fkps->size(); ++i) - { - FormattedDiskPagePAPX* fkp = fkps->at(i); - - for (unsigned int j = 0; j < fkp->grppapxSize; j++) - { - if ((fkp->rgfc[j] >= fcMin) && (fkp->rgfc[j] < fcMax)) - { - ppxList->push_back(fkp->grppapx[j]); - } - } - - RELEASEOBJECT(fkp); - - fkps->clear(); - RELEASEOBJECT(fkps); - } - return ppxList; + { + std::vector* ppxList = new std::vector(); + std::vector* fkps = FormattedDiskPagePAPX::GetAllPAPXFKPs(fib, wordStream, tableStream, dataStream); + + for (size_t i = 0; i < fkps->size(); ++i) + { + FormattedDiskPagePAPX* fkp = fkps->at(i); + + for (unsigned int j = 0; j < fkp->grppapxSize; j++) + { + if ((fkp->rgfc[j] >= fcMin) && (fkp->rgfc[j] < fcMax)) + { + ppxList->push_back(fkp->grppapx[j]); + } + } + + RELEASEOBJECT(fkp); + + fkps->clear(); + RELEASEOBJECT(fkps); + } + return ppxList; } } \ No newline at end of file diff --git a/MsBinaryFile/DocFile/Global.h b/MsBinaryFile/DocFile/Global.h index 4299265bc1c..0bf5b5e0f1a 100644 --- a/MsBinaryFile/DocFile/Global.h +++ b/MsBinaryFile/DocFile/Global.h @@ -46,14 +46,14 @@ namespace Global L"FF0000",//L"red", L"FFFF00",//L"yellow", L"FFFFFF",//L"white", - L"darkBlue", - L"darkCyan", - L"darkGreen", - L"darkMagenta", - L"darkRed", - L"darkYellow", - L"darkGray", - L"lightGray" + L"000080", //darkBlue + L"008080", //darkCyan + L"008000", //darkGreen + L"800080", //darkMagenta + L"800000", //darkRed + L"808000", //darkYellow + L"808080", //darkGray + L"C0C0C0" //lightGray }; static const wchar_t ColorNameIdentifier[17][12] = { diff --git a/MsBinaryFile/DocFile/ListData.cpp b/MsBinaryFile/DocFile/ListData.cpp index 5c7fdb63990..a8bd7e351fa 100644 --- a/MsBinaryFile/DocFile/ListData.cpp +++ b/MsBinaryFile/DocFile/ListData.cpp @@ -228,7 +228,7 @@ namespace DocFileFormat } if (strLen > 0) { - FormatUtils::GetSTLCollectionFromBytes( &(xst), data + 20, ( strLen ), ENCODING_WINDOWS_1250); + FormatUtils::GetWStringFromBytes( xst, data + 20, ( strLen ), ENCODING_WINDOWS_1250); } } OutlineListDescriptor::~OutlineListDescriptor() @@ -273,7 +273,7 @@ namespace DocFileFormat } if (strLen > 0) { - FormatUtils::GetSTLCollectionFromBytes( &(xst), data + 20, ( strLen ), ENCODING_WINDOWS_1250); + FormatUtils::GetWStringFromBytes( xst, data + 20, ( strLen ), ENCODING_WINDOWS_1250); } } } diff --git a/MsBinaryFile/DocFile/ListLevel.cpp b/MsBinaryFile/DocFile/ListLevel.cpp index d0ef939bc12..91b7ca64f82 100644 --- a/MsBinaryFile/DocFile/ListLevel.cpp +++ b/MsBinaryFile/DocFile/ListLevel.cpp @@ -93,7 +93,7 @@ namespace DocFileFormat if (strLen > 0)//file(14).doc { bytes = reader->ReadBytes( ( strLen * 2 ), true ); - FormatUtils::GetSTLCollectionFromBytes( &(xst), bytes, ( strLen * 2 ), ENCODING_UTF16 ); + xst = NSFile::CUtf8Converter::GetWStringFromUTF16((unsigned short*)(bytes), strLen); RELEASEARRAYOBJECTS( bytes ); } } diff --git a/MsBinaryFile/DocFile/MainDocumentMapping.cpp b/MsBinaryFile/DocFile/MainDocumentMapping.cpp index 743d328563c..8d3e2d5a01e 100644 --- a/MsBinaryFile/DocFile/MainDocumentMapping.cpp +++ b/MsBinaryFile/DocFile/MainDocumentMapping.cpp @@ -162,7 +162,7 @@ namespace DocFileFormat //// Read the chars //std::vector* chars = m_document->GetChars (fc, fcEnd, fc); - writeParagraph(cp, countTextRel, false, true ); + writeParagraph(cp, countTextRel, false, true, START_END_PARAGRAPH); cp = m_document->FIB->m_RgLw97.ccpText; } diff --git a/MsBinaryFile/DocFile/MemoryStream.cpp b/MsBinaryFile/DocFile/MemoryStream.cpp index e083216c77a..44eae54ad8a 100644 --- a/MsBinaryFile/DocFile/MemoryStream.cpp +++ b/MsBinaryFile/DocFile/MemoryStream.cpp @@ -31,6 +31,7 @@ */ #include "MemoryStream.h" +#include "../XlsFile/Format/Logging/Log.h" MemoryStream::MemoryStream (unsigned char* data, unsigned long size, bool bMemCopy) : m_Data(NULL), m_Size(0), m_Position(0), bMemoryCopy(bMemCopy) { @@ -61,11 +62,15 @@ _UINT64 MemoryStream::ReadUInt64() { _UINT64 rdU64 = 0; - if (m_Data) + if (m_Data && (m_Position + 8 <= m_Size)) { rdU64 = DocFileFormat::FormatUtils::BytesToUInt64(m_Data, m_Position, m_Size); m_Position += 8; } + else + { + Log::warning(L"MemoryStream: UInt64 read"); + } return rdU64; } @@ -73,12 +78,15 @@ unsigned short MemoryStream::ReadUInt16() { unsigned short rdUShort = 0; - if (m_Data) + if (m_Data && (m_Position + sizeof(unsigned short) <= m_Size)) { rdUShort = DocFileFormat::FormatUtils::BytesToUInt16 (m_Data, m_Position, m_Size); m_Position += 2; } - + else + { + Log::warning(L"MemoryStream: UInt16 read"); + } return rdUShort; } void MemoryStream::WriteUInt16(unsigned short val) @@ -88,17 +96,24 @@ void MemoryStream::WriteUInt16(unsigned short val) ((unsigned short *)(m_Data + m_Position))[0] = val; m_Position += 2; } + else + { + Log::warning(L"MemoryStream: UInt16 write"); + } } short MemoryStream::ReadInt16() { short rdShort = 0; - if (m_Data) + if (m_Data && (m_Position + sizeof(short) <= m_Size)) { rdShort = DocFileFormat::FormatUtils::BytesToInt16 (m_Data, m_Position, m_Size); m_Position += 2; } - + else + { + Log::warning(L"MemoryStream: Int16 read"); + } return rdShort; } @@ -106,12 +121,15 @@ int MemoryStream::ReadInt32() { int rdInt = 0; - if (m_Data) + if (m_Data && (m_Position + sizeof(_INT32) <= m_Size)) { rdInt = DocFileFormat::FormatUtils::BytesToInt32 (m_Data, m_Position, m_Size); m_Position += 4; } - + else + { + Log::warning(L"MemoryStream: Int32 read"); + } return rdInt; } void MemoryStream::WriteInt32(_INT32 val) @@ -121,6 +139,10 @@ void MemoryStream::WriteInt32(_INT32 val) ((_INT32 *)(m_Data + m_Position))[0] = val; m_Position += 4; } + else + { + Log::warning(L"MemoryStream: Int32 read"); + } } void MemoryStream::Align(_UINT32 val) { @@ -139,7 +161,10 @@ unsigned int MemoryStream::ReadUInt32() rdUInt = DocFileFormat::FormatUtils::BytesToUInt32 (m_Data, m_Position, m_Size); m_Position += 4; } - + else + { + Log::warning(L"MemoryStream: UInt32 read"); + } return rdUInt; } void MemoryStream::WriteByte(unsigned char val) @@ -157,6 +182,10 @@ void MemoryStream::WriteUInt32(_UINT32 val) ((_UINT32 *)(m_Data + m_Position))[0] = val; m_Position += sizeof(_UINT32); } + else + { + Log::warning(L"MemoryStream: UInt32 write"); + } } unsigned char MemoryStream::ReadByte() { @@ -167,7 +196,10 @@ unsigned char MemoryStream::ReadByte() rdByte = (m_Position < m_Size) ? m_Data[m_Position] : 0; m_Position += sizeof(rdByte); } - + else + { + Log::warning(L"MemoryStream: UInt8 read"); + } return rdByte; } @@ -194,10 +226,16 @@ void MemoryStream::WriteBytes(unsigned char* pData, int size) memcpy(m_Data + m_Position, pData, size); m_Position += size; } + else + { + Log::warning(L"MemoryStream: bytes write"); + } } unsigned long MemoryStream::GetPosition() const { + if (m_Position > m_Size) + return m_Size; return m_Position; } unsigned long MemoryStream::GetSize() const diff --git a/MsBinaryFile/DocFile/NumberingMapping.cpp b/MsBinaryFile/DocFile/NumberingMapping.cpp index b3f3a87d181..943ef0cfece 100644 --- a/MsBinaryFile/DocFile/NumberingMapping.cpp +++ b/MsBinaryFile/DocFile/NumberingMapping.cpp @@ -627,7 +627,7 @@ namespace DocFileFormat m_pXmlWriter->WriteNodeEnd( L"", TRUE ); // pPr bool isBidi = false; - ParagraphPropertiesMapping oppMapping(m_pXmlWriter, m_context, m_document, NULL, isBidi); + ParagraphPropertiesMapping oppMapping(m_pXmlWriter, m_context, m_document, NULL, isBidi, NULL, -1, false); lvl->grpprlPapx->Convert(&oppMapping); // пишем rPr diff --git a/MsBinaryFile/DocFile/OfficeDrawing/MetafilePictBlip.cpp b/MsBinaryFile/DocFile/OfficeDrawing/MetafilePictBlip.cpp index b65251f0ca6..4bf52f930a8 100644 --- a/MsBinaryFile/DocFile/OfficeDrawing/MetafilePictBlip.cpp +++ b/MsBinaryFile/DocFile/OfficeDrawing/MetafilePictBlip.cpp @@ -95,6 +95,21 @@ namespace DocFileFormat m_pMetaHeader = pHeader; m_lMetaHeaderSize = lSize; } + void CMetaFileBuffer::AddData(BYTE* pBuf, LONG lBuf) + { + BYTE *pMetaFile = new BYTE[lBuf + m_lMetaFileSize]; + if (m_pMetaFile) + memcpy(pMetaFile, m_pMetaFile, m_lMetaFileSize); + if (pBuf) + memcpy(pMetaFile + m_lMetaFileSize, pBuf, lBuf); + + if (m_pMetaFile) + delete[]m_pMetaFile; + + m_pMetaFile = pMetaFile; + m_lMetaFileSize += lBuf; + } + void CMetaFileBuffer::SetData(BYTE* pCompress, LONG lCompressSize, LONG lUncompressSize, bool bIsCompressed) { if (!bIsCompressed) @@ -127,6 +142,18 @@ namespace DocFileFormat } } } + bool CMetaFileBuffer::isWMV() + { + if (!m_pMetaFile) return false; + if (m_lMetaFileSize < 3) return false; + + for (int i = 0; i < (std::min)((int)m_lMetaFileSize, 1024) - 2; ++i) + { + if (m_pMetaFile[i] == 'W' && m_pMetaFile[i + 1] == 'M') + return true; + } + return false; + } int CMetaFileBuffer::ToBuffer(BYTE *& Data) { int sz = 0; @@ -205,6 +232,18 @@ namespace DocFileFormat oMetaHeader.compression = m_fCompression; oMetaHeader.filter = m_fFilter; + oMetaFile.SetData(m_pvBits, oMetaHeader.cbSave, oMetaHeader.cbSize, 0 == oMetaHeader.compression); + + //if (sz - m_cbSave > m_cb) + //{ + // oMetaFile.AddData(m_pvBits + m_cbSave, sz - m_cbSave); + //} + + //if (oMetaFile.isWMV()) + //{ + // typeCode = 0xf01b; + //} + if (typeCode == 0xf01b) { oMetaFile.m_sExtension = L".wmf"; @@ -220,10 +259,8 @@ namespace DocFileFormat } if (typeCode == 0xf01c) { - oMetaFile.m_sExtension = L".pcz"; - //decompress??? + oMetaFile.m_sExtension = L".pct"; } - oMetaFile.SetData(m_pvBits, oMetaHeader.cbSave, oMetaHeader.cbSize, 0 == oMetaHeader.compression); } MetafilePictBlip::~MetafilePictBlip() diff --git a/MsBinaryFile/DocFile/OfficeDrawing/MetafilePictBlip.h b/MsBinaryFile/DocFile/OfficeDrawing/MetafilePictBlip.h index bb0385780d3..02bb23aab63 100644 --- a/MsBinaryFile/DocFile/OfficeDrawing/MetafilePictBlip.h +++ b/MsBinaryFile/DocFile/OfficeDrawing/MetafilePictBlip.h @@ -91,10 +91,11 @@ class CMetaFileBuffer void SetHeader(BYTE* pHeader, LONG lSize); void SetData(BYTE* pCompress, LONG lCompressSize, LONG lUncompressSize, bool bIsCompressed); + void AddData(BYTE* pBuf, LONG lBuf); int ToBuffer(BYTE *& Data); - void ToFile(NSFile::CFileBinary* pFile); + bool isWMV(); }; diff --git a/MsBinaryFile/DocFile/OleObject.cpp b/MsBinaryFile/DocFile/OleObject.cpp index fa9bb0d0ec1..dbc6de5aa8f 100644 --- a/MsBinaryFile/DocFile/OleObject.cpp +++ b/MsBinaryFile/DocFile/OleObject.cpp @@ -127,7 +127,6 @@ bool OleObject::processLinkInfoStream( const std::wstring& linkStream ) VirtualStreamReader reader( pLinkStream, 0, false); processLinkInfoStream(reader); - delete pLinkStream; res = true; } if (pLinkStream) delete pLinkStream; @@ -172,7 +171,8 @@ bool OleObject::processPackageStream(const std::wstring& packageStream) POLE::Stream* pPackageStream = new POLE::Stream(oleStorage, packageStream); if ((pPackageStream) && (false == pPackageStream->fail())) - { + { +// AVS_OFFICESTUDIO_FILE_OTHER_PACKAGE_IN_OLE VirtualStreamReader reader(pPackageStream, 0, false); size_t sz = reader.GetSize(); @@ -356,7 +356,7 @@ void OleObject::processLinkInfoStream( VirtualStreamReader& reader ) { short cch = reader.ReadInt16(); unsigned char* str = reader.ReadBytes( cch, true ); - FormatUtils::GetSTLCollectionFromBytes( &this->Link, str, cch, ENCODING_WINDOWS_1250 ); + FormatUtils::GetWStringFromBytes( this->Link, str, cch, ENCODING_WINDOWS_1250 ); RELEASEARRAYOBJECTS( str ); //skip the terminating zero of the ANSI string @@ -371,7 +371,8 @@ void OleObject::processLinkInfoStream( VirtualStreamReader& reader ) cch = reader.ReadInt16(); str = reader.ReadBytes( ( cch * 2 ), true ); - FormatUtils::GetSTLCollectionFromBytes( &this->Link, str, ( cch * 2 ), ENCODING_UTF16 ); + + this->Link = NSFile::CUtf8Converter::GetWStringFromUTF16((unsigned short*)(str), cch); RELEASEARRAYOBJECTS( str ); //skip the terminating zero of the Unicode string diff --git a/MsBinaryFile/DocFile/OleObjectMapping.cpp b/MsBinaryFile/DocFile/OleObjectMapping.cpp index 5b6695c2a69..29b74e17b8c 100644 --- a/MsBinaryFile/DocFile/OleObjectMapping.cpp +++ b/MsBinaryFile/DocFile/OleObjectMapping.cpp @@ -45,49 +45,47 @@ namespace DocFileFormat void OleObjectMapping::Apply(IVisitable* visited) { - OleObject* ole = static_cast(visited); - - if ( ole != NULL ) + OleObject* ole = dynamic_cast(visited); + if (!ole) return; + + if (ole->isEmbedded || ole->isPackage) { - if (ole->isEmbedded || ole->isPackage) - { - if (ole->isEquation) ole->ClipboardFormat = L"Equation"; - else if (ole->ClipboardFormat.empty()) ole->ClipboardFormat = L"MSWordDocx"; + if (ole->isEquation) ole->ClipboardFormat = L"Equation"; + else if (ole->ClipboardFormat.empty()) ole->ClipboardFormat = L"MSWordDocx"; - ole->Program = L"Word.Document"; - } - m_pXmlWriter->WriteNodeBegin( L"o:OLEObject", TRUE ); + ole->Program = L"Word.Document"; + } + m_pXmlWriter->WriteNodeBegin(L"o:OLEObject", TRUE); - int relID = -1; + int relID = -1; - if ( ole->isLinked) - { - relID = m_context->_docx->RegisterExternalOLEObject(_caller, ole->ClipboardFormat, ole->Link); + if (ole->isLinked) + { + relID = m_context->_docx->RegisterExternalOLEObject(_caller, ole->ClipboardFormat, ole->Link); - m_pXmlWriter->WriteAttribute( L"Type", L"Link" ); - m_pXmlWriter->WriteAttribute( L"UpdateMode", ole->UpdateMode); - } + m_pXmlWriter->WriteAttribute(L"Type", L"Link"); + m_pXmlWriter->WriteAttribute(L"UpdateMode", ole->UpdateMode); + } + else + { + if (ole->isEmbedded || ole->isPackage) + relID = m_context->_docx->RegisterPackage(_caller, ole->ClipboardFormat); else - { - if (ole->isEmbedded || ole->isPackage) - relID = m_context->_docx->RegisterPackage(_caller, ole->ClipboardFormat); - else - relID = m_context->_docx->RegisterOLEObject(_caller, ole->ClipboardFormat); + relID = m_context->_docx->RegisterOLEObject(_caller, ole->ClipboardFormat); - m_pXmlWriter->WriteAttribute( L"Type", L"Embed" ); + m_pXmlWriter->WriteAttribute(L"Type", L"Embed"); - copyEmbeddedObject( ole ); - } + copyEmbeddedObject(ole); + } - m_pXmlWriter->WriteAttribute( L"ProgID", ole->Program); - m_pXmlWriter->WriteAttribute( L"ShapeID", _shapeId); - m_pXmlWriter->WriteAttribute( L"DrawAspect", L"Content" ); - m_pXmlWriter->WriteAttribute( L"ObjectID", ole->ObjectId); - m_pXmlWriter->WriteAttribute( L"r:id", L"rId"+ FormatUtils::IntToWideString( relID ) ); - m_pXmlWriter->WriteNodeEnd( L"", TRUE, FALSE ); + m_pXmlWriter->WriteAttribute(L"ProgID", ole->Program); + m_pXmlWriter->WriteAttribute(L"ShapeID", _shapeId); + m_pXmlWriter->WriteAttribute(L"DrawAspect", L"Content"); + m_pXmlWriter->WriteAttribute(L"ObjectID", ole->ObjectId); + m_pXmlWriter->WriteAttribute(L"r:id", L"rId" + FormatUtils::IntToWideString(relID)); + m_pXmlWriter->WriteNodeEnd(L"", TRUE, FALSE); - m_pXmlWriter->WriteNodeEnd( L"o:OLEObject" ); - } + m_pXmlWriter->WriteNodeEnd(L"o:OLEObject"); } std::wstring OleObjectMapping::GetTargetExt(const std::wstring& objectType) diff --git a/MsBinaryFile/DocFile/PictureDescriptor.cpp b/MsBinaryFile/DocFile/PictureDescriptor.cpp index 457d860a84b..af401e075dc 100644 --- a/MsBinaryFile/DocFile/PictureDescriptor.cpp +++ b/MsBinaryFile/DocFile/PictureDescriptor.cpp @@ -310,7 +310,7 @@ namespace DocFileFormat if ( stPicName != NULL ) { std::wstring picName; - FormatUtils::GetSTLCollectionFromBytes( &picName, stPicName, cchPicName, ENCODING_WINDOWS_1250 ); + FormatUtils::GetWStringFromBytes( picName, stPicName, cchPicName, ENCODING_WINDOWS_1250 ); RELEASEARRAYOBJECTS(stPicName); } } diff --git a/MsBinaryFile/DocFile/PieceTable.cpp b/MsBinaryFile/DocFile/PieceTable.cpp index 5613baf16b7..cf49adc5370 100644 --- a/MsBinaryFile/DocFile/PieceTable.cpp +++ b/MsBinaryFile/DocFile/PieceTable.cpp @@ -188,7 +188,7 @@ namespace DocFileFormat stream->seek(pcd.fc); stream->read(bytes, cb); - FormatUtils::GetSTLCollectionFromBytes >(piecePairs, bytes, cb, pcd.code_page); + FormatUtils::GetSTLCollectionFromBytes(piecePairs, bytes, cb, pcd.code_page); RELEASEARRAYOBJECTS(bytes); } @@ -234,7 +234,7 @@ namespace DocFileFormat wordStream->read( bytes, cb); //get the chars - FormatUtils::GetSTLCollectionFromBytes>( encodingChars, bytes, cb, pcd.code_page ); + FormatUtils::GetSTLCollectionFromBytes( encodingChars, bytes, cb, pcd.code_page ); RELEASEARRAYOBJECTS( bytes ); } @@ -253,7 +253,7 @@ namespace DocFileFormat wordStream->read( bytes, cb); //get the chars - FormatUtils::GetSTLCollectionFromBytes>( encodingChars, bytes, cb, pcd.code_page ); + FormatUtils::GetSTLCollectionFromBytes( encodingChars, bytes, cb, pcd.code_page ); RELEASEARRAYOBJECTS( bytes ); } @@ -272,7 +272,7 @@ namespace DocFileFormat wordStream->read( bytes, cb); //get the chars - FormatUtils::GetSTLCollectionFromBytes>(encodingChars, bytes, cb, pcd.code_page); + FormatUtils::GetSTLCollectionFromBytes(encodingChars, bytes, cb, pcd.code_page); RELEASEARRAYOBJECTS(bytes); @@ -295,7 +295,7 @@ namespace DocFileFormat wordStream->read( bytes, cb ); //get the chars - FormatUtils::GetSTLCollectionFromBytes>( encodingChars, bytes, cb, pcd.code_page ); + FormatUtils::GetSTLCollectionFromBytes( encodingChars, bytes, cb, pcd.code_page ); RELEASEARRAYOBJECTS( bytes ); @@ -484,7 +484,7 @@ namespace DocFileFormat word->read(bytes, size); - FormatUtils::GetSTLCollectionFromBytes>(encodingChars, bytes, size, coding); + FormatUtils::GetSTLCollectionFromBytes(encodingChars, bytes, size, coding); RELEASEARRAYOBJECTS(bytes); diff --git a/MsBinaryFile/DocFile/PropertiesMapping.cpp b/MsBinaryFile/DocFile/PropertiesMapping.cpp index 2615c589036..9158bb77610 100644 --- a/MsBinaryFile/DocFile/PropertiesMapping.cpp +++ b/MsBinaryFile/DocFile/PropertiesMapping.cpp @@ -447,7 +447,8 @@ namespace DocFileFormat border->AppendAttribute( space ); XMLTools::XMLAttribute color( L"w:color" ); - color.SetValue( RGBColor( brc->cv, RedFirst ).SixDigitHexCode); + color.SetValue(brc->getColor()); + border->AppendAttribute( color ); if ( brc->fShadow ) diff --git a/MsBinaryFile/DocFile/SectionPropertiesMapping.cpp b/MsBinaryFile/DocFile/SectionPropertiesMapping.cpp index 4d818922fd1..02a0762df55 100644 --- a/MsBinaryFile/DocFile/SectionPropertiesMapping.cpp +++ b/MsBinaryFile/DocFile/SectionPropertiesMapping.cpp @@ -374,10 +374,13 @@ namespace DocFileFormat if (m_nColumns) // there is at least one width set, so create the array { if (NULL == m_arrWidth) - m_arrWidth = new short [m_nColumns]; + m_arrWidth = new short[m_nColumns]; - unsigned char nInd = iter->Arguments[0]; - m_arrWidth[nInd] = FormatUtils::BytesToInt16 (iter->Arguments, 1, iter->argumentsSize); + unsigned char nInd = iter->Arguments[0]; + if (nInd < m_nColumns) + { + m_arrWidth[nInd] = FormatUtils::BytesToInt16(iter->Arguments, 1, iter->argumentsSize); + } } } break; @@ -490,7 +493,7 @@ namespace DocFileFormat appendValueAttribute( &pgNumType, L"w:start", wsSprmSPgnStart ); // build the columns - if (m_arrWidth) + if (m_arrWidth && m_nColumns > 0) { XMLTools::XMLAttribute equalWidth( L"w:equalWidth", L"0" ); cols.AppendAttribute( equalWidth ); diff --git a/MsBinaryFile/DocFile/SettingsMapping.cpp b/MsBinaryFile/DocFile/SettingsMapping.cpp index 9458f5d3e13..bba5b52cfdd 100644 --- a/MsBinaryFile/DocFile/SettingsMapping.cpp +++ b/MsBinaryFile/DocFile/SettingsMapping.cpp @@ -83,32 +83,48 @@ namespace DocFileFormat if (_ctx->_doc->FIB->m_FibBase.fWriteReservation) { - m_oXmlWriter.WriteNodeBegin( L"w:writeProtection", TRUE ); - WideString* passw = static_cast(_ctx->_doc->AssocNames->operator[]( 17 )); + CRYPT::_ecmaWriteProtectData data; + + WideString* passw = static_cast(_ctx->_doc->AssocNames->operator[]( 17 )); if (passw && false == passw->empty()) { - CRYPT::_ecmaWriteProtectData data; - CRYPT::ECMAWriteProtect protect; protect.SetCryptData(data); protect.SetPassword(*passw); protect.Generate(); protect.GetCryptData(data); + } + m_oXmlWriter.WriteNodeBegin(L"w:writeProtection", TRUE); + if (false == data.saltValue.empty()) + { //m_oXmlWriter.WriteAttribute ( L"w:cryptProviderType", L"rsaAES"); //m_oXmlWriter.WriteAttribute ( L"w:cryptAlgorithmSid", 14); //sha-512 //m_oXmlWriter.WriteAttribute ( L"w:cryptAlgorithmType", L"typeAny"); //m_oXmlWriter.WriteAttribute ( L"w:cryptAlgorithmClass", L"hash"); - //m_oXmlWriter.WriteAttribute ( L"w:cryptSpinCount", data.spinCount); - //m_oXmlWriter.WriteAttribute ( L"w:hash", EncodeBase64(data.hashValue)); - //m_oXmlWriter.WriteAttribute ( L"w:salt", EncodeBase64(data.saltValue)); + m_oXmlWriter.WriteAttribute ( L"w:algorithmName", L"SHA-512"); m_oXmlWriter.WriteAttribute ( L"w:spinCount", data.spinCount); m_oXmlWriter.WriteAttribute ( L"w:hashValue", EncodeBase64(data.hashValue)); - m_oXmlWriter.WriteAttribute ( L"w:saltValue", EncodeBase64(data.saltValue)); + m_oXmlWriter.WriteAttribute ( L"w:saltValue", EncodeBase64(data.saltValue)); } m_oXmlWriter.WriteNodeEnd( L"", TRUE, TRUE ); + if (false == data.saltValue.empty()) + { + m_oXmlWriter.WriteNodeBegin(L"w:documentProtection", TRUE); + m_oXmlWriter.WriteAttribute(L"w:edit", L"readOnly"); + m_oXmlWriter.WriteAttribute(L"w:enforcement", L"1"); + m_oXmlWriter.WriteAttribute(L"w:cryptProviderType", L"rsaAES"); + m_oXmlWriter.WriteAttribute(L"w:cryptAlgorithmClass", L"hash"); + m_oXmlWriter.WriteAttribute(L"w:cryptAlgorithmType", L"typeAny"); + m_oXmlWriter.WriteAttribute(L"w:cryptAlgorithmSid", 14); //sha-512 + m_oXmlWriter.WriteAttribute(L"w:cryptSpinCount", data.spinCount); + m_oXmlWriter.WriteAttribute(L"w:spinCount", data.spinCount); + m_oXmlWriter.WriteAttribute(L"w:hash", EncodeBase64(data.hashValue)); + m_oXmlWriter.WriteAttribute(L"w:salt", EncodeBase64(data.saltValue)); + m_oXmlWriter.WriteNodeEnd(L"", TRUE, TRUE); + } } //zoom m_oXmlWriter.WriteNodeBegin ( L"w:zoom", TRUE ); diff --git a/MsBinaryFile/DocFile/StringTable.h b/MsBinaryFile/DocFile/StringTable.h index dd9a8274d6c..f190d012d66 100644 --- a/MsBinaryFile/DocFile/StringTable.h +++ b/MsBinaryFile/DocFile/StringTable.h @@ -60,15 +60,10 @@ namespace DocFileFormat for ( size_t i = 0; i < Data.size(); ++i ) { RELEASEOBJECT( Data[i] ); - - if (false == DataExtra.empty()) - { - if (DataExtra[i]) - { - delete []DataExtra[i]; - DataExtra[i] = NULL; - } - } + } + for (size_t i = 0; i < DataExtra.size(); ++i) + { + RELEASEOBJECT(DataExtra[i]); } } StringTable( VirtualStreamReader *reader, int code_page_ ) diff --git a/MsBinaryFile/DocFile/StyleSheet.cpp b/MsBinaryFile/DocFile/StyleSheet.cpp index e708c32a761..4265df3d056 100644 --- a/MsBinaryFile/DocFile/StyleSheet.cpp +++ b/MsBinaryFile/DocFile/StyleSheet.cpp @@ -72,13 +72,13 @@ namespace DocFileFormat //read the bytes of the STSHI tableReader.Seek( ( fib->m_FibWord97.fcStshf + 2 ), 0/*STREAM_SEEK_SET*/ ); - unsigned char* stshi = tableReader.ReadBytes( cbStshi, true ); + unsigned char* stshi_data = tableReader.ReadBytes( cbStshi, true ); //parses STSHI - this->stshi = new StyleSheetInformation( stshi, cbStshi ); - RELEASEARRAYOBJECTS( stshi ); + stshi = new StyleSheetInformation(stshi_data, cbStshi ); + RELEASEARRAYOBJECTS(stshi_data); - for ( int i = 0; i < this->stshi->cstd; i++ ) + for ( unsigned short i = 0; i < stshi->cstd; i++ ) { //get the cbStd unsigned short cbStd = tableReader.ReadUInt16(); @@ -89,7 +89,7 @@ namespace DocFileFormat unsigned char* std = tableReader.ReadBytes( cbStd, true ); //parse the STD bytes - Styles->push_back( new StyleSheetDescription( std, cbStd, (int)this->stshi->cbSTDBaseInFile, dataStream, fib->m_nWordVersion) ); + Styles->push_back( new StyleSheetDescription( std, cbStd, (int)stshi->cbSTDBaseInFile, dataStream, fib->m_nWordVersion) ); RELEASEARRAYOBJECTS( std ); } @@ -116,7 +116,7 @@ namespace DocFileFormat { //user style unsigned char *bytes = tableReader.ReadBytes( sz_name, true ); - FormatUtils::GetSTLCollectionFromBytes( &std->xstzName, bytes, sz_name, ENCODING_WINDOWS_1250 ); + FormatUtils::GetWStringFromBytes( std->xstzName, bytes, sz_name, ENCODING_WINDOWS_1250 ); RELEASEARRAYOBJECTS( bytes ); } // ms style diff --git a/MsBinaryFile/DocFile/StyleSheet.h b/MsBinaryFile/DocFile/StyleSheet.h index 4d7b3ae06ba..0fc612d4a5d 100644 --- a/MsBinaryFile/DocFile/StyleSheet.h +++ b/MsBinaryFile/DocFile/StyleSheet.h @@ -43,14 +43,8 @@ namespace DocFileFormat { public: virtual ~StyleSheet(); - /// Parses the streams to retrieve a StyleSheet. StyleSheet(FileInformationBlock* fib, POLE::Stream* tableStream, POLE::Stream* dataStream); - - public: - - /// The StyleSheetInformation of the stylesheet. StyleSheetInformation* stshi; - /// The list contains all styles. std::vector* Styles; }; } \ No newline at end of file diff --git a/MsBinaryFile/DocFile/StyleSheetDescription.cpp b/MsBinaryFile/DocFile/StyleSheetDescription.cpp index 4cb04dfba7b..e408a449c1b 100644 --- a/MsBinaryFile/DocFile/StyleSheetDescription.cpp +++ b/MsBinaryFile/DocFile/StyleSheetDescription.cpp @@ -138,16 +138,15 @@ namespace DocFileFormat { name = new unsigned char[characterCount];//characters are zero-terminated, so 1 char has 2 bytes: memcpy( name, ( bytes + cbStdBase + 1 ), ( characterCount ) ); - FormatUtils::GetSTLCollectionFromBytes( &(xstzName), name, ( characterCount ), ENCODING_WINDOWS_1250 ); + FormatUtils::GetWStringFromBytes( xstzName, name, ( characterCount ), ENCODING_WINDOWS_1250 ); upxOffset = cbStdBase + 1 + ( characterCount /** 2*/ ) + 1; } else { name = new unsigned char[characterCount * 2];//characters are zero-terminated, so 1 char has 2 bytes: memcpy( name, ( bytes + cbStdBase + 2 ), ( characterCount * 2 ) ); - //remove zero-termination - FormatUtils::GetSTLCollectionFromBytes( &(xstzName), name, ( characterCount * 2 ), ENCODING_UTF16 ); - + xstzName = NSFile::CUtf8Converter::GetWStringFromUTF16((unsigned short*)(name), characterCount); + //parse the UPX structs upxOffset = cbStdBase + 1 + ( characterCount * 2 ) + 2; } @@ -173,29 +172,23 @@ namespace DocFileFormat if ( stk == table_style ) { //first upx is TAPX; second PAPX, third CHPX - switch ( i ) + switch (i) { - case 0: + case 0: { - //todooo не реализовано - //RELEASEOBJECT( tapx ); - //tapx = new TablePropertyExceptions( upxBytes, cbUPX, dataStream, nWordVersion); - } - break; - - case 1: + RELEASEOBJECT(tapx); + tapx = new TablePropertyExceptions(upxBytes, cbUPX, nWordVersion); + }break; + case 1: { - RELEASEOBJECT( papx ); - papx = new ParagraphPropertyExceptions( upxBytes, cbUPX, dataStream, nWordVersion); - } - break; - - case 2: + RELEASEOBJECT(papx); + papx = new ParagraphPropertyExceptions(upxBytes, cbUPX, dataStream, nWordVersion); + }break; + case 2: { - RELEASEOBJECT( chpx ); - chpx = new CharacterPropertyExceptions( upxBytes, cbUPX , nWordVersion); - } - break; + RELEASEOBJECT(chpx); + chpx = new CharacterPropertyExceptions(upxBytes, cbUPX, nWordVersion); + }break; } } else if ( stk == paragraph_style ) diff --git a/MsBinaryFile/DocFile/StyleSheetMapping.cpp b/MsBinaryFile/DocFile/StyleSheetMapping.cpp index ea2e57bf563..b2f963d5531 100644 --- a/MsBinaryFile/DocFile/StyleSheetMapping.cpp +++ b/MsBinaryFile/DocFile/StyleSheetMapping.cpp @@ -81,134 +81,151 @@ namespace DocFileFormat //NormalTable writeNormalTableStyle(); } - - for ( std::vector::iterator iter = sheet->Styles->begin(); iter != sheet->Styles->end(); iter++ ) + int count_styles = 0; + for ( size_t i = 0; i < sheet->Styles->size(); ++i) { - if ( *iter != NULL ) - { - m_pXmlWriter->WriteNodeBegin( L"w:style", true); + StyleSheetDescription* style = sheet->Styles->at(i); + if (!style) continue; - m_pXmlWriter->WriteAttribute( L"w:type", FormatUtils::MapValueToWideString( (*iter)->stk, &StyleKindMap[0][0], 5, 10 )); + count_styles++; + + if (count_styles > 4080) // todooo - skip/remap equal styles + break; - //!!!TODO: There is NO default styles in DOC file. So, we can't choose one of them!!! - /*if ( ( (*iter)->sti != Null ) && ( (*iter)->sti != User ) ) - { - //it's a default style - m_pXmlWriter->WriteAttribute( L"w:default", L"1" ); - }*/ - - m_pXmlWriter->WriteAttribute( L"w:styleId", FormatUtils::XmlEncode(MakeStyleId( *iter ))); - m_pXmlWriter->WriteNodeEnd( L"", true, false ); - - // - std::wstring sName = FormatUtils::XmlEncode(getStyleName(*iter), true); - m_pXmlWriter->WriteNodeBegin( L"w:name", true); - if ((*iter)->sti == StyleIdentifier::Normal) - m_pXmlWriter->WriteAttribute(L"w:val", L"Normal"); - else - m_pXmlWriter->WriteAttribute(L"w:val", sName); - m_pXmlWriter->WriteNodeEnd( L"", true); + m_pXmlWriter->WriteNodeBegin(L"w:style", true); - if ((*iter)->sti == StyleIdentifier::Normal) // ??? < sti < 159 - { - m_pXmlWriter->WriteNodeBegin(L"w:aliases", true); - m_pXmlWriter->WriteAttribute(L"w:val", sName); - m_pXmlWriter->WriteNodeEnd(L"", true); - } + m_pXmlWriter->WriteAttribute(L"w:type", FormatUtils::MapValueToWideString(style->stk, &StyleKindMap[0][0], 5, 10)); - // - if ( ( (*iter)->istdBase != 4095 ) && ( (*iter)->istdBase < sheet->Styles->size() ) ) + //!!!TODO: There is NO default styles in DOC file. So, we can't choose one of them!!! + /*if ( ( style->sti != Null ) && ( style->sti != User ) ) + { + //it's a default style + m_pXmlWriter->WriteAttribute( L"w:default", L"1" ); + }*/ + + m_pXmlWriter->WriteAttribute(L"w:styleId", FormatUtils::XmlEncode(MakeStyleId(style))); + m_pXmlWriter->WriteNodeEnd(L"", true, false); + + std::wstring sAliases; + std::wstring sName = FormatUtils::XmlEncode(getStyleName(style), true); + m_pXmlWriter->WriteNodeBegin(L"w:name", true); + if (style->sti == StyleIdentifier::Normal) + m_pXmlWriter->WriteAttribute(L"w:val", L"Normal"); + else + { + std::size_t pos = sName.find(L","); + if (pos != std::wstring::npos) { - m_pXmlWriter->WriteNodeBegin( L"w:basedOn", true); - m_pXmlWriter->WriteAttribute( L"w:val", FormatUtils::XmlEncode(MakeStyleId( sheet->Styles->at( (*iter)->istdBase ) ))); - m_pXmlWriter->WriteNodeEnd( L"", true); + sAliases = sName.substr(pos + 1); + sName = sName.substr(0, pos); } + m_pXmlWriter->WriteAttribute(L"w:val", sName); + } + m_pXmlWriter->WriteNodeEnd(L"", true); - // - if ( (*iter)->istdNext < sheet->Styles->size() ) - { - m_pXmlWriter->WriteNodeBegin( L"w:next", true); - m_pXmlWriter->WriteAttribute( L"w:val", FormatUtils::XmlEncode(MakeStyleId( sheet->Styles->at( (*iter)->istdNext ) ))); - m_pXmlWriter->WriteNodeEnd( L"", true); - } + if (false == sAliases.empty()) + { + m_pXmlWriter->WriteNodeBegin(L"w:aliases", true); + m_pXmlWriter->WriteAttribute(L"w:val", sAliases); + m_pXmlWriter->WriteNodeEnd(L"", true); + } + else + if (style->sti == StyleIdentifier::Normal) // ??? < sti < 159 + { + m_pXmlWriter->WriteNodeBegin(L"w:aliases", true); + m_pXmlWriter->WriteAttribute(L"w:val", sName); + m_pXmlWriter->WriteNodeEnd(L"", true); + } - // - if ( (*iter)->istdLink < sheet->Styles->size() ) - { - m_pXmlWriter->WriteNodeBegin( L"w:link", true); - m_pXmlWriter->WriteAttribute( L"w:val", FormatUtils::XmlEncode(MakeStyleId( sheet->Styles->at( (*iter)->istdLink ) ))); - m_pXmlWriter->WriteNodeEnd( L"", true); - } - if ((*iter)->fAutoRedef) - { - m_pXmlWriter->WriteNodeBegin(L"w:autoRedefine", true); - m_pXmlWriter->WriteNodeEnd(L"", true); - } - if ( (*iter)->fHidden ) - { - m_pXmlWriter->WriteNodeBegin( L"w:hidden", true); - m_pXmlWriter->WriteNodeEnd(L"", true); - } - if ((*iter)->uiPriority > 0) - { - m_pXmlWriter->WriteNodeBegin(L"w:uiPriority", true); - m_pXmlWriter->WriteAttribute(L"w:val", std::to_wstring((*iter)->uiPriority)); - m_pXmlWriter->WriteNodeEnd(L"", true); - } - if ((*iter)->fQFormat) - { - m_pXmlWriter->WriteNodeBegin(L"w:qFormat", true); - m_pXmlWriter->WriteNodeEnd(L"", true); - } - if ( (*iter)->fSemiHidden ) - { - m_pXmlWriter->WriteNodeBegin( L"w:semiHidden", true); - m_pXmlWriter->WriteNodeEnd(L"", true); - } - if ((*iter)->fUnhideWhenUsed) - { - m_pXmlWriter->WriteNodeBegin(L"w:unhideWhenUsed", true); - m_pXmlWriter->WriteNodeEnd(L"", true); - } - if ((*iter)->fLocked) - { - m_pXmlWriter->WriteNodeBegin(L"w:locked", true); - m_pXmlWriter->WriteNodeEnd(L"", true); - } - if ((*iter)->rsid > 0) - { - m_pXmlWriter->WriteNodeBegin(L"w:rsid", true); - m_pXmlWriter->WriteAttribute(L"w:val", FormatUtils::IntToFormattedWideString((*iter)->rsid, L"%08X")); - m_pXmlWriter->WriteNodeEnd(L"", true); - } - //write paragraph properties - if ( (*iter)->papx != NULL ) - { - bool isBidi = false; - ParagraphPropertiesMapping* ppMappingnew = new ParagraphPropertiesMapping (m_pXmlWriter, _ctx, m_document, NULL, isBidi, false); - (*iter)->papx->Convert( ppMappingnew ); - RELEASEOBJECT( ppMappingnew ); - } + if ((style->istdBase != 4095) && (style->istdBase < sheet->Styles->size())) + { + m_pXmlWriter->WriteNodeBegin(L"w:basedOn", true); + m_pXmlWriter->WriteAttribute(L"w:val", FormatUtils::XmlEncode(MakeStyleId(sheet->Styles->at(style->istdBase)))); + m_pXmlWriter->WriteNodeEnd(L"", true); + } - //write character properties - if ( (*iter)->chpx != NULL ) - { - RevisionData rev; - rev.Type = NoRevision; - CharacterPropertiesMapping* cpMapping = new CharacterPropertiesMapping (m_pXmlWriter, m_document, &rev, (*iter)->papx, true, false); - (*iter)->chpx->Convert( cpMapping ); - RELEASEOBJECT( cpMapping ); - } - //write table properties - if ( (*iter)->tapx != NULL ) - { - std::vector tableGrid; - TablePropertiesMapping* tpMapping = new TablePropertiesMapping (m_pXmlWriter, sheet, &tableGrid, false); - (*iter)->tapx->Convert( tpMapping ); - RELEASEOBJECT( tpMapping ); - } - m_pXmlWriter->WriteNodeEnd( L"w:style" ); + if (style->istdNext < sheet->Styles->size()) + { + m_pXmlWriter->WriteNodeBegin(L"w:next", true); + m_pXmlWriter->WriteAttribute(L"w:val", FormatUtils::XmlEncode(MakeStyleId(sheet->Styles->at(style->istdNext)))); + m_pXmlWriter->WriteNodeEnd(L"", true); + } + + if (style->istdLink < sheet->Styles->size()) + { + m_pXmlWriter->WriteNodeBegin(L"w:link", true); + m_pXmlWriter->WriteAttribute(L"w:val", FormatUtils::XmlEncode(MakeStyleId(sheet->Styles->at(style->istdLink)))); + m_pXmlWriter->WriteNodeEnd(L"", true); + } + if (style->fAutoRedef) + { + m_pXmlWriter->WriteNodeBegin(L"w:autoRedefine", true); + m_pXmlWriter->WriteNodeEnd(L"", true); + } + if (style->fHidden) + { + m_pXmlWriter->WriteNodeBegin(L"w:hidden", true); + m_pXmlWriter->WriteNodeEnd(L"", true); + } + if (style->uiPriority > 0) + { + m_pXmlWriter->WriteNodeBegin(L"w:uiPriority", true); + m_pXmlWriter->WriteAttribute(L"w:val", std::to_wstring(style->uiPriority)); + m_pXmlWriter->WriteNodeEnd(L"", true); + } + if (style->fQFormat) + { + m_pXmlWriter->WriteNodeBegin(L"w:qFormat", true); + m_pXmlWriter->WriteNodeEnd(L"", true); + } + if (style->fSemiHidden) + { + m_pXmlWriter->WriteNodeBegin(L"w:semiHidden", true); + m_pXmlWriter->WriteNodeEnd(L"", true); + } + if (style->fUnhideWhenUsed) + { + m_pXmlWriter->WriteNodeBegin(L"w:unhideWhenUsed", true); + m_pXmlWriter->WriteNodeEnd(L"", true); + } + if (style->fLocked) + { + m_pXmlWriter->WriteNodeBegin(L"w:locked", true); + m_pXmlWriter->WriteNodeEnd(L"", true); + } + if (style->rsid > 0) + { + m_pXmlWriter->WriteNodeBegin(L"w:rsid", true); + m_pXmlWriter->WriteAttribute(L"w:val", FormatUtils::IntToFormattedWideString(style->rsid, L"%08X")); + m_pXmlWriter->WriteNodeEnd(L"", true); + } + //write paragraph properties + if (style->papx != NULL) + { + bool isBidi = false; + ParagraphPropertiesMapping* ppMappingnew = new ParagraphPropertiesMapping(m_pXmlWriter, _ctx, m_document, NULL, isBidi, false); + style->papx->Convert(ppMappingnew); + RELEASEOBJECT(ppMappingnew); + } + + //write character properties + if (style->chpx != NULL) + { + RevisionData rev; + rev.Type = NoRevision; + CharacterPropertiesMapping* cpMapping = new CharacterPropertiesMapping(m_pXmlWriter, m_document, &rev, style->papx, true, false); + style->chpx->Convert(cpMapping); + RELEASEOBJECT(cpMapping); + } + //write table properties + if (style->tapx != NULL) + { + std::vector tableGrid; + TablePropertiesMapping* tpMapping = new TablePropertiesMapping(m_pXmlWriter, sheet, &tableGrid, false); + style->tapx->Convert(tpMapping); + RELEASEOBJECT(tpMapping); } + m_pXmlWriter->WriteNodeEnd(L"w:style"); } m_pXmlWriter->WriteNodeEnd( L"w:styles" ); diff --git a/MsBinaryFile/DocFile/TableCellPropertiesMapping.cpp b/MsBinaryFile/DocFile/TableCellPropertiesMapping.cpp index 3d5016afaca..4945e1e5d29 100644 --- a/MsBinaryFile/DocFile/TableCellPropertiesMapping.cpp +++ b/MsBinaryFile/DocFile/TableCellPropertiesMapping.cpp @@ -94,7 +94,7 @@ namespace DocFileFormat } bool bPresentDefTable = false; - for (std::vector::reverse_iterator iter = tapx->grpprl->rbegin(); iter != tapx->grpprl->rend(); ++iter) + for (std::vector::iterator iter = tapx->grpprl->begin(); iter != tapx->grpprl->end(); ++iter) { switch (iter->OpCode) { @@ -114,7 +114,7 @@ namespace DocFileFormat // Технические_Требования_1_287_ДИТ.DOC if (tdef.rgTc80[j].horzMerge == 0 && tdef.rgTc80[j].wWidth < 1) { - bUseWidth = false; + //bUseWidth = false; break; } } @@ -289,6 +289,61 @@ namespace DocFileFormat } } break; + case sprmTTableBorders80: + { + const int size = 4; + unsigned char brc80[size]; + + memcpy(brc80, iter->Arguments, size); + if (!_brcTop) + _brcTop = std::shared_ptr(new BorderCode(brc80, size)); + + memcpy(brc80, (iter->Arguments + 4), size); + if (!_brcLeft) + _brcLeft = std::shared_ptr(new BorderCode(brc80, size)); + + memcpy(brc80, (iter->Arguments + 8), size); + if (!_brcBottom) + _brcBottom = std::shared_ptr(new BorderCode(brc80, size)); + + memcpy(brc80, (iter->Arguments + 12), size); + if (!_brcRight) + _brcRight = std::shared_ptr(new BorderCode(brc80, size)); + + //memcpy(brc80, (iter->Arguments + 16), size); + //_brcHorz = std::shared_ptr(new BorderCode(brc80, size)); + + //memcpy(brc80, (iter->Arguments + 20), size); + //_brcVert = std::shared_ptr(new BorderCode(brc80, size)); + }break; + case sprmOldTTableBorders: + case sprmTTableBorders: + { + const int size = 8; + unsigned char brc[size]; + + memcpy(brc, iter->Arguments, size); + if (!_brcTop) + _brcTop = std::shared_ptr(new BorderCode(brc, size)); + + memcpy(brc, (iter->Arguments + 8), size); + if (!_brcLeft) + _brcLeft = std::shared_ptr(new BorderCode(brc, size)); + + memcpy(brc, (iter->Arguments + 16), size); + if (!_brcBottom) + _brcBottom = std::shared_ptr(new BorderCode(brc, size)); + + memcpy(brc, (iter->Arguments + 24), size); + if (!_brcRight) + _brcRight = std::shared_ptr(new BorderCode(brc, size)); + + //memcpy(brc, (iter->Arguments + 32), size); + //_brcHorz = std::shared_ptr(new BorderCode(brc, size)); + + //memcpy(brc, (iter->Arguments + 40), size); + //_brcVert = std::shared_ptr(new BorderCode(brc, size)); + }break; case sprmOldTSetBrc: case sprmTSetBrc: { //borders (cell definition) diff --git a/MsBinaryFile/DocFile/TablePropertiesMapping.cpp b/MsBinaryFile/DocFile/TablePropertiesMapping.cpp index 0902b32c308..0e3d123f966 100644 --- a/MsBinaryFile/DocFile/TablePropertiesMapping.cpp +++ b/MsBinaryFile/DocFile/TablePropertiesMapping.cpp @@ -34,388 +34,396 @@ namespace DocFileFormat { - TablePropertiesMapping::TablePropertiesMapping (XMLTools::CStringXmlWriter* pWriter, StyleSheet* styles, std::vector* grid, bool isTableStyleNeeded ): - PropertiesMapping(pWriter), _tblPr(NULL), _tblGrid(NULL), _tblBorders(NULL), _grid(grid), - brcLeft(NULL), brcTop(NULL), brcBottom(NULL), brcRight(NULL), brcHorz(NULL), brcVert(NULL), _styles(styles), - _isTableStyleNeeded(isTableStyleNeeded) -{ - _tblPr = new XMLTools::XMLElement( L"w:tblPr"); - _tblBorders = new XMLTools::XMLElement( L"w:tblBorders"); -} -TablePropertiesMapping::~TablePropertiesMapping() -{ - RELEASEOBJECT (_tblPr); - RELEASEOBJECT (_tblGrid); - RELEASEOBJECT (_tblBorders); -} + TablePropertiesMapping::TablePropertiesMapping(XMLTools::CStringXmlWriter* pWriter, StyleSheet* styles, std::vector* grid, bool isTableStyleNeeded) : + PropertiesMapping(pWriter), _tblPr(NULL), _tblGrid(NULL), _tblBorders(NULL), _grid(grid), + brcLeft(NULL), brcTop(NULL), brcBottom(NULL), brcRight(NULL), brcHorz(NULL), brcVert(NULL), _styles(styles), + _isTableStyleNeeded(isTableStyleNeeded) + { + _tblPr = new XMLTools::XMLElement(L"w:tblPr"); + _tblBorders = new XMLTools::XMLElement(L"w:tblBorders"); + } + TablePropertiesMapping::~TablePropertiesMapping() + { + RELEASEOBJECT(_tblPr); + RELEASEOBJECT(_tblGrid); + RELEASEOBJECT(_tblBorders); + } -void TablePropertiesMapping::Apply(IVisitable* visited) -{ - TablePropertyExceptions* tapx = static_cast(visited); + void TablePropertiesMapping::Apply(IVisitable* visited) + { + TablePropertyExceptions* tapx = static_cast(visited); - XMLTools::XMLElement tblCellMar(L"w:tblCellMar"); - XMLTools::XMLElement tblLayout(L"w:tblLayout"); - XMLTools::XMLElement tblpPr(L"w:tblpPr"); - XMLTools::XMLAttribute layoutType(L"w:type", L"fixed"); + XMLTools::XMLElement tblCellMar(L"w:tblCellMar"); + XMLTools::XMLElement tblLayout(L"w:tblLayout"); + XMLTools::XMLElement tblpPr(L"w:tblpPr"); + XMLTools::XMLAttribute layoutType(L"w:type", L"fixed"); - _CP_OPT(short) tblIndent; - short gabHalf = 0; - short marginLeft = 0; - short marginRight = 0; + _CP_OPT(short) tblIndent; + _CP_OPT(short) gabHalf; + _CP_OPT(short) marginLeft; + _CP_OPT(short) marginRight; - short cellSpacing = 0; + short cellSpacing = 0; - BYTE itcFirst = 0; - BYTE itcLim = 0; + BYTE itcFirst = 0; + BYTE itcLim = 0; - bool bTableW = false; + bool bTableW = false; - for (std::vector::iterator iter = tapx->grpprl->begin(); iter != tapx->grpprl->end(); iter++) - { - switch (iter->OpCode) - { - case sprmOldTDxaGapHalf: - case sprmTDxaGapHalf: - { - gabHalf = FormatUtils::BytesToInt16(iter->Arguments, 0, iter->argumentsSize); - }break; - case sprmOldTDefTable: - case sprmTDefTable: + for (std::vector::iterator iter = tapx->grpprl->begin(); iter != tapx->grpprl->end(); iter++) { - //table definition - SprmTDefTable tDef(iter->Arguments, iter->argumentsSize); - //Workaround for retrieving the indent of the table: - //In some files there is a indent but no sprmTWidthIndent is set. - //For this cases we can calculate the indent of the table by getting the - //first boundary of the TDef and adding the padding of the cells - - tblIndent = gabHalf + FormatUtils::BytesToInt16(iter->Arguments, 1, iter->argumentsSize); - //If there follows a real sprmTWidthIndent, this value will be overwritten - - //tblIndent = (std::max)((int)tblIndent,0); //cerere.doc - }break; - case sprmTTableWidth: - { - //preferred table width - unsigned char fts = iter->Arguments[0]; - short width = FormatUtils::BytesToInt16(iter->Arguments, 1, iter->argumentsSize); + switch (iter->OpCode) + { + case sprmOldTDxaGapHalf: + case sprmTDxaGapHalf: + { + gabHalf = FormatUtils::BytesToInt16(iter->Arguments, 0, iter->argumentsSize); + }break; + case sprmOldTDefTable: + case sprmTDefTable: + { + //table definition + SprmTDefTable tDef(iter->Arguments, iter->argumentsSize); + //Workaround for retrieving the indent of the table: + //In some files there is a indent but no sprmTWidthIndent is set. + //For this cases we can calculate the indent of the table by getting the + //first boundary of the TDef and adding the padding of the cells + + tblIndent = FormatUtils::BytesToInt16(iter->Arguments, 1, iter->argumentsSize); + //If there follows a real sprmTWidthIndent, this value will be overwritten + + //tblIndent = (std::max)((int)tblIndent,0); //cerere.doc + }break; + case sprmTTableWidth: + { + //preferred table width + unsigned char fts = iter->Arguments[0]; - XMLTools::XMLElement tblW(L"w:tblW"); + if (fts == 0) fts = 1; //auto - 江苏领辉M5仪表_2号协议&5S协议说明书-V1.1 - EN.doc + short width = FormatUtils::BytesToInt16(iter->Arguments, 1, iter->argumentsSize); - XMLTools::XMLAttribute w(L"w:w", FormatUtils::IntToWideString(width)); - XMLTools::XMLAttribute type(L"w:type", FormatUtils::MapValueToWideString(fts, &WidthType[0][0], 4, 5)); + XMLTools::XMLElement tblW(L"w:tblW"); - tblW.AppendAttribute(type); - tblW.AppendAttribute(w); + XMLTools::XMLAttribute w(L"w:w", FormatUtils::IntToWideString(width)); + XMLTools::XMLAttribute type(L"w:type", FormatUtils::MapValueToWideString(fts, &WidthType[0][0], 4, 5)); - _tblPr->AppendChild(tblW); + tblW.AppendAttribute(type); + tblW.AppendAttribute(w); - bTableW = true; - }break; - case sprmTMerge: - { - itcFirst = iter->Arguments[0]; - itcLim = iter->Arguments[1]; - }break; - case sprmTSplit: - { + _tblPr->AppendChild(tblW); - }break; - case sprmOldTJc: - case sprmTJc: - case sprmTJcRow: - { - appendValueElement(_tblPr, L"jc", FormatUtils::MapValueToWideString(iter->Arguments[0], &Global::JustificationCode[0][0], 10, 15), true); - }break; - case sprmTWidthIndent: - { - tblIndent = FtsWWidth_Indent(iter->Arguments).wWidth; - }break; - case sprmTIstd: - case sprmTIstdPermute: - { - if (_isTableStyleNeeded) + bTableW = true; + }break; + case sprmTMerge: + { + itcFirst = iter->Arguments[0]; + itcLim = iter->Arguments[1]; + }break; + case sprmTSplit: { - size_t ind = FormatUtils::BytesToInt16(iter->Arguments, 0, iter->argumentsSize); - - std::wstring id = ind < _styles->Styles->size() ? StyleSheetMapping::MakeStyleId(_styles->Styles->at(ind)) : L""; - if (id != std::wstring(L"TableNormal") && !id.empty()) + }break; + case sprmOldTJc: + case sprmTJc: + case sprmTJcRow: + { + appendValueElement(_tblPr, L"jc", FormatUtils::MapValueToWideString(iter->Arguments[0], &Global::JustificationCode[0][0], 10, 15), true); + }break; + case sprmTWidthIndent: + { + tblIndent = FtsWWidth_Indent(iter->Arguments).wWidth; + }break; + case sprmTIstd: + case sprmTIstdPermute: + { + if (_isTableStyleNeeded) { - appendValueElement(_tblPr, L"tblStyle", id, true); + size_t ind = FormatUtils::BytesToInt16(iter->Arguments, 0, iter->argumentsSize); + + std::wstring id = ind < _styles->Styles->size() ? StyleSheetMapping::MakeStyleId(_styles->Styles->at(ind)) : L""; + + if (id != std::wstring(L"TableNormal") && !id.empty()) + { + appendValueElement(_tblPr, L"tblStyle", id, true); + } } - } - }break; - case sprmTFBiDi: - case sprmTFBiDi90: - { - appendValueElement(_tblPr, L"bidiVisual", FormatUtils::BytesToInt16(iter->Arguments, 0, iter->argumentsSize), true); - }break; - case sprmOldTTlp: - case sprmTTlp: - { - appendValueElement(_tblPr, L"tblLook", FormatUtils::IntToFormattedWideString(FormatUtils::BytesToInt16(iter->Arguments, 2, iter->argumentsSize), L"%04x"), true); - }break; - case sprmTFAutofit: - { - if (iter->Arguments[0] == 1) + }break; + case sprmTFBiDi: + case sprmTFBiDi90: { - layoutType.SetValue(L"auto"); - } - }break; - case sprmTCellSpacing: - case sprmTCellSpacingDefault: - { - unsigned char grfbrc = iter->Arguments[2]; - short wSpc = FormatUtils::BytesToInt16(iter->Arguments, 4, iter->argumentsSize); - std::wstring strValue = FormatUtils::IntToWideString(wSpc); - if (FormatUtils::BitmaskToBool((int)grfbrc, 0x01)) + appendValueElement(_tblPr, L"bidiVisual", FormatUtils::BytesToInt16(iter->Arguments, 0, iter->argumentsSize), true); + }break; + case sprmOldTTlp: + case sprmTTlp: { - appendDxaElement(_tblPr, L"tblCellSpacing", strValue, true); - } - if (FormatUtils::BitmaskToBool((int)grfbrc, 0x02)) + appendValueElement(_tblPr, L"tblLook", FormatUtils::IntToFormattedWideString(FormatUtils::BytesToInt16(iter->Arguments, 2, iter->argumentsSize), L"%04x"), true); + }break; + case sprmTFAutofit: { - cellSpacing = wSpc; - } - }break; - case sprmTCellPadding: - case sprmTCellPaddingDefault: - case sprmTCellPaddingOuter: - {//default cell padding (margin) - unsigned char grfbrc = iter->Arguments[2]; - short wMar = FormatUtils::BytesToInt16(iter->Arguments, 4, iter->argumentsSize); - std::wstring strValue = FormatUtils::IntToWideString(wMar); - - if (FormatUtils::BitmaskToBool((int)grfbrc, 0x01)) + if (iter->Arguments[0] == 1) + { + layoutType.SetValue(L"auto"); + } + }break; + case sprmTCellSpacing: + case sprmTCellSpacingDefault: { - appendDxaElement(&tblCellMar, L"top", strValue, true); - } - if (FormatUtils::BitmaskToBool((int)grfbrc, 0x02)) + unsigned char grfbrc = iter->Arguments[2]; + short wSpc = FormatUtils::BytesToInt16(iter->Arguments, 4, iter->argumentsSize); + std::wstring strValue = FormatUtils::IntToWideString(wSpc); + if (FormatUtils::BitmaskToBool((int)grfbrc, 0x01)) + { + appendDxaElement(_tblPr, L"tblCellSpacing", strValue, true); + } + if (FormatUtils::BitmaskToBool((int)grfbrc, 0x02)) + { + cellSpacing = wSpc; + } + }break; + case sprmTCellPaddingDefault: + case sprmTCellPadding: + case sprmTCellPaddingOuter: + {//cell padding (margin) + unsigned char grfbrc = iter->Arguments[2]; + short wMar = FormatUtils::BytesToInt16(iter->Arguments, 4, iter->argumentsSize); + std::wstring strValue = FormatUtils::IntToWideString(wMar); + + if (FormatUtils::BitmaskToBool((int)grfbrc, 0x01)) + { + appendDxaElement(&tblCellMar, L"top", strValue, true); + } + if (FormatUtils::BitmaskToBool((int)grfbrc, 0x02)) + { + marginLeft = wMar; + } + if (FormatUtils::BitmaskToBool((int)grfbrc, 0x04)) + { + appendDxaElement(&tblCellMar, L"bottom", strValue, true); + } + if (FormatUtils::BitmaskToBool((int)grfbrc, 0x08)) + { + marginRight = wMar; + } + }break; + case sprmTCHorzBands: { - marginLeft = wMar; - } - if (FormatUtils::BitmaskToBool((int)grfbrc, 0x04)) + appendValueElement(_tblPr, L"tblStyleRowBandSize", iter->Arguments[0], true); + }break; + case sprmTCVertBands: { - appendDxaElement(&tblCellMar, L"bottom", strValue, true); - } - if (FormatUtils::BitmaskToBool((int)grfbrc, 0x08)) + appendValueElement(_tblPr, L"tblStyleColBandSize", iter->Arguments[0], true); + }break; + case sprmTFNoAllowOverlap: { - marginRight = wMar; - } - }break; - case sprmTCHorzBands: - { - appendValueElement(_tblPr, L"tblStyleRowBandSize", iter->Arguments[0], true); - }break; - case sprmTCVertBands: - { - appendValueElement(_tblPr, L"tblStyleColBandSize", iter->Arguments[0], true); - }break; - case sprmTFNoAllowOverlap: - { - std::wstring tblOverlapVal(L"overlap"); + std::wstring tblOverlapVal(L"overlap"); - if (iter->Arguments[0]) - { - tblOverlapVal = L"never"; - } + if (iter->Arguments[0]) + { + tblOverlapVal = L"never"; + } - appendValueElement(_tblPr, L"tblOverlap", tblOverlapVal, true); - }break; - case sprmOldTSetShd: - case sprmTSetShdTable: - { + appendValueElement(_tblPr, L"tblOverlap", tblOverlapVal, true); + }break; + case sprmOldTSetShd: + case sprmTSetShdTable: + { - appendShading(_tblPr, ShadingDescriptor(iter->Arguments, iter->argumentsSize)); - }break; - case sprmTTableBorders80: - { - const int size = 4; - unsigned char brc80[size]; + appendShading(_tblPr, ShadingDescriptor(iter->Arguments, iter->argumentsSize)); + }break; + case sprmTTableBorders80: + { + const int size = 4; + unsigned char brc80[size]; - memcpy(brc80, iter->Arguments, size); - brcTop = std::shared_ptr(new BorderCode(brc80, size)); + memcpy(brc80, iter->Arguments, size); + brcTop = std::shared_ptr(new BorderCode(brc80, size)); - memcpy(brc80, (iter->Arguments + 4), size); - brcLeft = std::shared_ptr(new BorderCode(brc80, size)); + memcpy(brc80, (iter->Arguments + 4), size); + brcLeft = std::shared_ptr(new BorderCode(brc80, size)); - memcpy(brc80, (iter->Arguments + 8), size); - brcBottom = std::shared_ptr(new BorderCode(brc80, size)); + memcpy(brc80, (iter->Arguments + 8), size); + brcBottom = std::shared_ptr(new BorderCode(brc80, size)); - memcpy(brc80, (iter->Arguments + 12), size); - brcRight = std::shared_ptr(new BorderCode(brc80, size)); + memcpy(brc80, (iter->Arguments + 12), size); + brcRight = std::shared_ptr(new BorderCode(brc80, size)); - memcpy(brc80, (iter->Arguments + 16), size); - brcHorz = std::shared_ptr(new BorderCode(brc80, size)); + memcpy(brc80, (iter->Arguments + 16), size); + brcHorz = std::shared_ptr(new BorderCode(brc80, size)); - memcpy(brc80, (iter->Arguments + 20), size); - brcVert = std::shared_ptr(new BorderCode(brc80, size)); - }break; - case sprmOldTTableBorders: - case sprmTTableBorders: - { - const int size = 8; - unsigned char brc[size]; + memcpy(brc80, (iter->Arguments + 20), size); + brcVert = std::shared_ptr(new BorderCode(brc80, size)); + }break; + case sprmOldTTableBorders: + case sprmTTableBorders: + { + const int size = 8; + unsigned char brc[size]; - memcpy(brc, iter->Arguments, size); - brcTop = std::shared_ptr(new BorderCode(brc, size)); + memcpy(brc, iter->Arguments, size); + brcTop = std::shared_ptr(new BorderCode(brc, size)); - memcpy(brc, (iter->Arguments + 8), size); - brcLeft = std::shared_ptr(new BorderCode(brc, size)); + memcpy(brc, (iter->Arguments + 8), size); + brcLeft = std::shared_ptr(new BorderCode(brc, size)); - memcpy(brc, (iter->Arguments + 16), size); - brcBottom = std::shared_ptr(new BorderCode(brc, size)); + memcpy(brc, (iter->Arguments + 16), size); + brcBottom = std::shared_ptr(new BorderCode(brc, size)); - memcpy(brc, (iter->Arguments + 24), size); - brcRight = std::shared_ptr(new BorderCode(brc, size)); + memcpy(brc, (iter->Arguments + 24), size); + brcRight = std::shared_ptr(new BorderCode(brc, size)); - memcpy(brc, (iter->Arguments + 32), size); - brcHorz = std::shared_ptr(new BorderCode(brc, size)); + memcpy(brc, (iter->Arguments + 32), size); + brcHorz = std::shared_ptr(new BorderCode(brc, size)); - memcpy(brc, (iter->Arguments + 40), size); - brcVert = std::shared_ptr(new BorderCode(brc, size)); - }break; - case sprmTPc: - { - unsigned char flag = (iter->Arguments[0] & 0x30) >> 4; + memcpy(brc, (iter->Arguments + 40), size); + brcVert = std::shared_ptr(new BorderCode(brc, size)); + }break; + case sprmTPc: + { + unsigned char flag = (iter->Arguments[0] & 0x30) >> 4; - appendValueAttribute(&tblpPr, L"w:vertAnchor", FormatUtils::MapValueToWideString(flag, &Global::VerticalPositionCode[0][0], 4, 7)); + appendValueAttribute(&tblpPr, L"w:vertAnchor", FormatUtils::MapValueToWideString(flag, &Global::VerticalPositionCode[0][0], 4, 7)); - flag = (iter->Arguments[0] & 0xC0) >> 6; + flag = (iter->Arguments[0] & 0xC0) >> 6; - appendValueAttribute(&tblpPr, L"w:horzAnchor", FormatUtils::MapValueToWideString(flag, &Global::HorizontalPositionCode[0][0], 4, 7)); - }break; - case sprmTDxaFromText: - { - appendValueAttribute(&tblpPr, L"w:leftFromText", FormatUtils::BytesToInt16(iter->Arguments, 0, iter->argumentsSize)); - }break; - case sprmTDxaFromTextRight: - { - appendValueAttribute(&tblpPr, L"w:rightFromText", FormatUtils::BytesToInt16(iter->Arguments, 0, iter->argumentsSize)); - }break; - case sprmTDyaFromText: - { - appendValueAttribute(&tblpPr, L"w:topFromText", FormatUtils::BytesToInt16(iter->Arguments, 0, iter->argumentsSize)); - }break; - case sprmTDyaFromTextBottom: - { - appendValueAttribute(&tblpPr, L"w:bottomFromText", FormatUtils::BytesToInt16(iter->Arguments, 0, iter->argumentsSize)); - }break; - case sprmTDxaAbs: - { - appendValueAttribute(&tblpPr, L"w:tblpX", FormatUtils::BytesToInt16(iter->Arguments, 0, iter->argumentsSize)); - }break; - case sprmTDyaAbs: - { - appendValueAttribute(&tblpPr, L"w:tblpY", FormatUtils::BytesToInt16(iter->Arguments, 0, iter->argumentsSize)); - }break; + appendValueAttribute(&tblpPr, L"w:horzAnchor", FormatUtils::MapValueToWideString(flag, &Global::HorizontalPositionCode[0][0], 4, 7)); + }break; + case sprmTDxaFromText: + { + appendValueAttribute(&tblpPr, L"w:leftFromText", FormatUtils::BytesToInt16(iter->Arguments, 0, iter->argumentsSize)); + }break; + case sprmTDxaFromTextRight: + { + appendValueAttribute(&tblpPr, L"w:rightFromText", FormatUtils::BytesToInt16(iter->Arguments, 0, iter->argumentsSize)); + }break; + case sprmTDyaFromText: + { + appendValueAttribute(&tblpPr, L"w:topFromText", FormatUtils::BytesToInt16(iter->Arguments, 0, iter->argumentsSize)); + }break; + case sprmTDyaFromTextBottom: + { + appendValueAttribute(&tblpPr, L"w:bottomFromText", FormatUtils::BytesToInt16(iter->Arguments, 0, iter->argumentsSize)); + }break; + case sprmTDxaAbs: + { + appendValueAttribute(&tblpPr, L"w:tblpX", FormatUtils::BytesToInt16(iter->Arguments, 0, iter->argumentsSize)); + }break; + case sprmTDyaAbs: + { + appendValueAttribute(&tblpPr, L"w:tblpY", FormatUtils::BytesToInt16(iter->Arguments, 0, iter->argumentsSize)); + }break; + } } - } - if (false == bTableW) - { - XMLTools::XMLElement tblW(L"w:tblW"); + if (false == bTableW) + { + XMLTools::XMLElement tblW(L"w:tblW"); - XMLTools::XMLAttribute w(L"w:w", L"0"); - XMLTools::XMLAttribute type(L"w:type", L"auto"); + XMLTools::XMLAttribute w(L"w:w", L"0"); + XMLTools::XMLAttribute type(L"w:type", L"auto"); - tblW.AppendAttribute(type); - tblW.AppendAttribute(w); + tblW.AppendAttribute(type); + tblW.AppendAttribute(w); - _tblPr->AppendChild(tblW); - } + _tblPr->AppendChild(tblW); + } - if (tblIndent) - { - XMLTools::XMLElement tblInd(L"w:tblInd"); + if (tblIndent) + { + if (gabHalf) + tblIndent = *tblIndent + *gabHalf; - XMLTools::XMLAttribute tblIndW(L"w:w", FormatUtils::IntToWideString(*tblIndent)); - tblInd.AppendAttribute(tblIndW); + XMLTools::XMLElement tblInd(L"w:tblInd"); - XMLTools::XMLAttribute tblIndType(L"w:type", L"dxa"); - tblInd.AppendAttribute(tblIndType); + XMLTools::XMLAttribute tblIndW(L"w:w", FormatUtils::IntToWideString(*tblIndent)); + tblInd.AppendAttribute(tblIndW); - _tblPr->AppendChild(tblInd); - } + XMLTools::XMLAttribute tblIndType(L"w:type", L"dxa"); + tblInd.AppendAttribute(tblIndType); - if (tblpPr.GetAttributeCount() > 0) - { - _tblPr->AppendChild(tblpPr); - } + _tblPr->AppendChild(tblInd); + } - if (brcTop) - { - XMLTools::XMLElement topBorder(L"w:top"); - appendBorderAttributes(brcTop.get(), &topBorder); - addOrSetBorder(_tblBorders, &topBorder); - } + if (tblpPr.GetAttributeCount() > 0) + { + _tblPr->AppendChild(tblpPr); + } - if (brcLeft) - { - XMLTools::XMLElement leftBorder(L"w:left"); - appendBorderAttributes(brcLeft.get(), &leftBorder); - addOrSetBorder(_tblBorders, &leftBorder); - } + if (brcTop) + { + XMLTools::XMLElement topBorder(L"w:top"); + appendBorderAttributes(brcTop.get(), &topBorder); + addOrSetBorder(_tblBorders, &topBorder); + } - if (brcBottom) - { - XMLTools::XMLElement bottomBorder(L"w:bottom"); - appendBorderAttributes(brcBottom.get(), &bottomBorder); - addOrSetBorder(_tblBorders, &bottomBorder); - } + if (brcLeft) + { + XMLTools::XMLElement leftBorder(L"w:left"); + appendBorderAttributes(brcLeft.get(), &leftBorder); + addOrSetBorder(_tblBorders, &leftBorder); + } - if (brcRight) - { - XMLTools::XMLElement rightBorder(L"w:right"); - appendBorderAttributes(brcRight.get(), &rightBorder); - addOrSetBorder(_tblBorders, &rightBorder); - } + if (brcBottom) + { + XMLTools::XMLElement bottomBorder(L"w:bottom"); + appendBorderAttributes(brcBottom.get(), &bottomBorder); + addOrSetBorder(_tblBorders, &bottomBorder); + } - if (brcHorz) - { - XMLTools::XMLElement insideHBorder(L"w:insideH"); - appendBorderAttributes(brcHorz.get(), &insideHBorder); - addOrSetBorder(_tblBorders, &insideHBorder); - } + if (brcRight) + { + XMLTools::XMLElement rightBorder(L"w:right"); + appendBorderAttributes(brcRight.get(), &rightBorder); + addOrSetBorder(_tblBorders, &rightBorder); + } - if (brcVert) - { - XMLTools::XMLElement insideVBorder(L"w:insideV"); - appendBorderAttributes(brcVert.get(), &insideVBorder); - addOrSetBorder(_tblBorders, &insideVBorder); - } + if (brcHorz) + { + XMLTools::XMLElement insideHBorder(L"w:insideH"); + appendBorderAttributes(brcHorz.get(), &insideHBorder); + addOrSetBorder(_tblBorders, &insideHBorder); + } - if (_tblBorders->GetChildCount() > 0) - { - _tblPr->AppendChild(*_tblBorders); - } + if (brcVert) + { + XMLTools::XMLElement insideVBorder(L"w:insideV"); + appendBorderAttributes(brcVert.get(), &insideVBorder); + addOrSetBorder(_tblBorders, &insideVBorder); + } - if (false == layoutType.GetValue().empty()) - { - tblLayout.AppendAttribute(layoutType); - } - _tblPr->AppendChild(tblLayout); + if (_tblBorders->GetChildCount() > 0) + { + _tblPr->AppendChild(*_tblBorders); + } - if ((marginLeft == 0) && (gabHalf != 0)) - { - appendDxaElement(&tblCellMar, L"left", FormatUtils::IntToWideString(gabHalf), true); - } - else - { - appendDxaElement(&tblCellMar, L"left", FormatUtils::IntToWideString(marginLeft), true); - } + if (false == layoutType.GetValue().empty()) + { + tblLayout.AppendAttribute(layoutType); + } + _tblPr->AppendChild(tblLayout); - if ((marginRight == 0) && (gabHalf != 0)) - { - appendDxaElement(&tblCellMar, L"right", FormatUtils::IntToWideString(gabHalf), true); - } - else - { - appendDxaElement(&tblCellMar, L"right", FormatUtils::IntToWideString(marginRight), true); - } + if ((gabHalf) && (*gabHalf != 0)) + { + appendDxaElement(&tblCellMar, L"left", FormatUtils::IntToWideString(*gabHalf), true); + } + else if (marginLeft) + { + appendDxaElement(&tblCellMar, L"left", FormatUtils::IntToWideString(*marginLeft), true); + } - _tblPr->AppendChild(tblCellMar); + if ((gabHalf) && (*gabHalf != 0)) + { + appendDxaElement(&tblCellMar, L"right", FormatUtils::IntToWideString(*gabHalf), true); + } + else if (marginRight) + { + appendDxaElement(&tblCellMar, L"right", FormatUtils::IntToWideString(*marginRight), true); + } + + if (tblCellMar.GetChildCount() > 0 || tblCellMar.GetAttributeCount() > 0) + { + _tblPr->AppendChild(tblCellMar); + } - if ((_tblPr->GetChildCount() > 0) || (_tblPr->GetAttributeCount() > 0)) + if (_tblPr->GetChildCount() > 0 || _tblPr->GetAttributeCount() > 0) { m_pXmlWriter->WriteString(_tblPr->GetXMLString()); } diff --git a/MsBinaryFile/DocFile/TableRowPropertiesMapping.cpp b/MsBinaryFile/DocFile/TableRowPropertiesMapping.cpp index a74ba36ddac..e322590c9f2 100644 --- a/MsBinaryFile/DocFile/TableRowPropertiesMapping.cpp +++ b/MsBinaryFile/DocFile/TableRowPropertiesMapping.cpp @@ -60,7 +60,9 @@ namespace DocFileFormat std::shared_ptr brcHorz; std::shared_ptr brcVert; - //delete infos + XMLTools::XMLElement* _tcMar = NULL; + + //delete infos RevisionData rev( _rowEndChpx ); if ( ( _rowEndChpx != NULL ) && ( rev.Type == Deleted ) ) @@ -72,133 +74,162 @@ namespace DocFileFormat XMLTools::XMLElement rowHeight(L"w:trHeight"); for ( std::vector::iterator iter = tapx->grpprl->begin(); iter != tapx->grpprl->end(); iter++ ) { - switch ( iter->OpCode ) + switch (iter->OpCode) + { + case sprmOldTDefTable: + case sprmTDefTable: { - case sprmOldTDefTable: - case sprmTDefTable: + //SprmTDefTable tdef = new SprmTDefTable(sprm.Arguments); + }break; + case sprmOldTTableHeader: + case sprmTTableHeader: + { //header row + + bool fHeader = (iter->Arguments[0] != 0) ? (true) : (false); + + if (fHeader) { - //SprmTDefTable tdef = new SprmTDefTable(sprm.Arguments); - }break; - case sprmOldTTableHeader: - case sprmTTableHeader: - { //header row - - bool fHeader = ( iter->Arguments[0] != 0 ) ? (true) : (false); - - if ( fHeader ) - { - XMLTools::XMLElement header( L"w:tblHeader" ); - _trPr->AppendChild( header ); - } - }break; - case sprmTWidthAfter: - { //width after - XMLTools::XMLElement wAfter( L"w:wAfter" ); - XMLTools::XMLAttribute wAfterValue( L"w:w", FormatUtils::IntToWideString( FormatUtils::BytesToInt16( iter->Arguments, 1, iter->argumentsSize ) ) ); - wAfter.AppendAttribute( wAfterValue ); - - XMLTools::XMLAttribute wAfterType( L"w:type", L"dxa" ); - wAfter.AppendAttribute( wAfterType ); - _trPr->AppendChild( wAfter, true ); - }break; - case sprmTWidthBefore: - { //width before - short before = FormatUtils::BytesToInt16( iter->Arguments, 1, iter->argumentsSize ); - - if ( before != 0 ) - { - XMLTools::XMLElement wBefore( L"w:wBefore" ); - XMLTools::XMLAttribute wBeforeValue( L"w:w", FormatUtils::IntToWideString( before ) ); - wBefore.AppendAttribute( wBeforeValue ); - - XMLTools::XMLAttribute wBeforeType( L"w:type", L"dxa" ); - wBefore.AppendAttribute( wBeforeType ); - _trPr->AppendChild( wBefore, true ); - } - }break; - case sprmOldTDyaRowHeight: - case sprmTDyaRowHeight: - { //row height - XMLTools::XMLAttribute rowHeightVal( L"w:val" ); - XMLTools::XMLAttribute rowHeightRule( L"w:hRule" ); - - short rH = FormatUtils::BytesToInt16( iter->Arguments, 0, iter->argumentsSize ); - - if ( rH > 0 ) - { - rowHeightRule.SetValue( L"atLeast" ); - rowHeightVal.SetValue( FormatUtils::IntToWideString( rH ) ); - rowHeight.AppendAttribute( rowHeightVal ); - } - else if( rH == 0 ) - { - rowHeightRule.SetValue( L"auto" ); - } - else - { - rowHeightRule.SetValue( L"exact" ); - rH *= -1; - rowHeightVal.SetValue( FormatUtils::IntToWideString( rH ) ); - rowHeight.AppendAttribute( rowHeightVal ); - } - rowHeight.AppendAttribute( rowHeightRule ); + XMLTools::XMLElement header(L"w:tblHeader"); + _trPr->AppendChild(header); } - break; - case sprmOldTFCantSplit: - case sprmTFCantSplit: - break; - case sprmTFCantSplit90: - { //can't split - if (iter->argumentsSize > 0 && iter->Arguments[0] != 0) - appendFlagElement( _trPr, *iter, L"cantSplit", true ); - }break; - case sprmTIpgp:// = PGPInfo.ipgpSelf (PGPInfo structure describes the border and margin properties) - { //div id - }break; - case sprmTCellSpacing: - case sprmTCellSpacingDefault: + }break; + case sprmTWidthAfter: + { //width after + XMLTools::XMLElement wAfter(L"w:wAfter"); + XMLTools::XMLAttribute wAfterValue(L"w:w", FormatUtils::IntToWideString(FormatUtils::BytesToInt16(iter->Arguments, 1, iter->argumentsSize))); + wAfter.AppendAttribute(wAfterValue); + + XMLTools::XMLAttribute wAfterType(L"w:type", L"dxa"); + wAfter.AppendAttribute(wAfterType); + _trPr->AppendChild(wAfter, true); + }break; + case sprmTWidthBefore: + { //width before + short before = FormatUtils::BytesToInt16(iter->Arguments, 1, iter->argumentsSize); + + if (before != 0) + { + XMLTools::XMLElement wBefore(L"w:wBefore"); + XMLTools::XMLAttribute wBeforeValue(L"w:w", FormatUtils::IntToWideString(before)); + wBefore.AppendAttribute(wBeforeValue); + + XMLTools::XMLAttribute wBeforeType(L"w:type", L"dxa"); + wBefore.AppendAttribute(wBeforeType); + _trPr->AppendChild(wBefore, true); + } + }break; + case sprmOldTDyaRowHeight: + case sprmTDyaRowHeight: + { //row height + XMLTools::XMLAttribute rowHeightVal(L"w:val"); + XMLTools::XMLAttribute rowHeightRule(L"w:hRule"); + + short rH = FormatUtils::BytesToInt16(iter->Arguments, 0, iter->argumentsSize); + + if (rH > 0) + { + rowHeightRule.SetValue(L"atLeast"); + rowHeightVal.SetValue(FormatUtils::IntToWideString(rH)); + rowHeight.AppendAttribute(rowHeightVal); + } + else if (rH == 0) + { + rowHeightRule.SetValue(L"auto"); + } + else { - unsigned char grfbrc = iter->Arguments[2]; - short wSpc = FormatUtils::BytesToInt16(iter->Arguments, 4, iter->argumentsSize); - std::wstring strValue = FormatUtils::IntToWideString(wSpc); - if (FormatUtils::BitmaskToBool((int)grfbrc, 0x01)) - { - appendDxaElement(_trPr, L"tblCellSpacing", strValue, true); - } - }break; - case sprmTTableBorders80: + rowHeightRule.SetValue(L"exact"); + rH *= -1; + rowHeightVal.SetValue(FormatUtils::IntToWideString(rH)); + rowHeight.AppendAttribute(rowHeightVal); + } + rowHeight.AppendAttribute(rowHeightRule); + } + break; + case sprmOldTFCantSplit: + case sprmTFCantSplit: + break; + case sprmTFCantSplit90: + { //can't split + if (iter->argumentsSize > 0 && iter->Arguments[0] != 0) + appendFlagElement(_trPr, *iter, L"cantSplit", true); + }break; + case sprmTIpgp:// = PGPInfo.ipgpSelf (PGPInfo structure describes the border and margin properties) + { //div id + }break; + case sprmTCellSpacing: + case sprmTCellSpacingDefault: + { + unsigned char grfbrc = iter->Arguments[2]; + short wSpc = FormatUtils::BytesToInt16(iter->Arguments, 4, iter->argumentsSize); + std::wstring strValue = FormatUtils::IntToWideString(wSpc); + if (FormatUtils::BitmaskToBool((int)grfbrc, 0x01)) { - const int size = 4; - unsigned char brc80[size]; + appendDxaElement(_trPr, L"tblCellSpacing", strValue, true); + } + }break; + case sprmTTableBorders80: + { + const int size = 4; + unsigned char brc80[size]; + + memcpy(brc80, iter->Arguments, size); + brcTop = std::shared_ptr(new BorderCode(brc80, size)); + + memcpy(brc80, (iter->Arguments + 4), size); + brcLeft = std::shared_ptr(new BorderCode(brc80, size)); + + memcpy(brc80, (iter->Arguments + 8), size); + brcBottom = std::shared_ptr(new BorderCode(brc80, size)); - memcpy(brc80, iter->Arguments, size); - brcTop = std::shared_ptr(new BorderCode(brc80, size)); + memcpy(brc80, (iter->Arguments + 12), size); + brcRight = std::shared_ptr(new BorderCode(brc80, size)); - memcpy(brc80, (iter->Arguments + 4), size); - brcLeft = std::shared_ptr(new BorderCode(brc80, size)); + memcpy(brc80, (iter->Arguments + 16), size); + brcHorz = std::shared_ptr(new BorderCode(brc80, size)); - memcpy(brc80, (iter->Arguments + 8), size); - brcBottom = std::shared_ptr(new BorderCode(brc80, size)); + memcpy(brc80, (iter->Arguments + 20), size); + brcVert = std::shared_ptr(new BorderCode(brc80, size)); + }break; + case sprmTCellPaddingDefault: + case sprmTCellPadding: + case sprmTCellPaddingOuter: + { + unsigned char first = iter->Arguments[0]; + unsigned char lim = iter->Arguments[1]; + unsigned char ftsMargin = iter->Arguments[3]; + short wMargin = FormatUtils::BytesToInt16(iter->Arguments, 4, iter->argumentsSize); - memcpy(brc80, (iter->Arguments + 12), size); - brcRight = std::shared_ptr(new BorderCode(brc80, size)); + if (!_tcMar) _tcMar = new XMLTools::XMLElement(L"w:tblCellMar"); + if (FormatUtils::GetBitFromInt(iter->Arguments[2], 0) == true) + { + appendDxaElement(_tcMar, L"top", FormatUtils::IntToWideString(wMargin), true); + } + + if (FormatUtils::GetBitFromInt(iter->Arguments[2], 1) == true) + { + appendDxaElement(_tcMar, L"left", FormatUtils::IntToWideString(wMargin), true); + } - memcpy(brc80, (iter->Arguments + 16), size); - brcHorz = std::shared_ptr(new BorderCode(brc80, size)); + if (FormatUtils::GetBitFromInt(iter->Arguments[2], 2) == true) + { + appendDxaElement(_tcMar, L"bottom", FormatUtils::IntToWideString(wMargin), true); + } - memcpy(brc80, (iter->Arguments + 20), size); - brcVert = std::shared_ptr(new BorderCode(brc80, size)); - }break; - default: - break; + if (FormatUtils::GetBitFromInt(iter->Arguments[2], 3) == true) + { + appendDxaElement(_tcMar, L"right", FormatUtils::IntToWideString(wMargin), true); + } + } + default: + break; } } if (rowHeight.GetAttributeCount() > 0) { _trPr->AppendChild(rowHeight); } - - //set borders + //set borders XMLTools::XMLElement* _tblBorders = new XMLTools::XMLElement(L"w:tblBorders"); if (brcTop) { @@ -240,6 +271,10 @@ namespace DocFileFormat { _tblPrEx->AppendChild(*_tblBorders); } + if (_tcMar && _tcMar->GetChildCount() > 0) + { + _tblPrEx->AppendChild(*(_tcMar)); + } //--------------------------------------------------------------------------- if ( _tblPrEx->GetChildCount() > 0 ) { @@ -249,5 +284,7 @@ namespace DocFileFormat { m_pXmlWriter->WriteString( _trPr->GetXMLString() ); } + + RELEASEOBJECT(_tcMar); } } diff --git a/MsBinaryFile/DocFile/TextboxMapping.cpp b/MsBinaryFile/DocFile/TextboxMapping.cpp index af087539772..27c92a8406d 100644 --- a/MsBinaryFile/DocFile/TextboxMapping.cpp +++ b/MsBinaryFile/DocFile/TextboxMapping.cpp @@ -140,6 +140,10 @@ namespace DocFileFormat cpStart = txtbxSubdocStart + m_document->TextboxBreakPlexHeader->CharacterPositions[m_nTBIndex]; cpEnd = txtbxSubdocStart + m_document->TextboxBreakPlexHeader->CharacterPositions[m_nTBIndex + 1]; } + else + { + cpEnd = 0x7fffffff; + } bool bUsed = bkd ? bkd->bUsed : false; _isTextBoxContent = true; @@ -170,7 +174,7 @@ namespace DocFileFormat else { //this PAPX is for a normal paragraph - cp = writeParagraph(cp, 0x7fffffff); + cp = writeParagraph(cp, cpEnd - 1); } } _isTextBoxContent = false; diff --git a/MsBinaryFile/DocFile/VMLPictureMapping.cpp b/MsBinaryFile/DocFile/VMLPictureMapping.cpp index 18ea383a638..281956b7a29 100644 --- a/MsBinaryFile/DocFile/VMLPictureMapping.cpp +++ b/MsBinaryFile/DocFile/VMLPictureMapping.cpp @@ -51,41 +51,41 @@ using namespace DocFileFormat; namespace DocFileFormat { - struct __BITMAPINFOHEADER - { - _UINT32 biSize; - _INT32 biWidth; - _INT32 biHeight; - _UINT16 biPlanes; - _UINT16 biBitCount; - _UINT32 biCompression; - _UINT32 biSizeImage; - _INT32 biXPelsPerMeter; - _INT32 biYPelsPerMeter; - _UINT32 biClrUsed; - _UINT32 biClrImportant; - }; - - struct __BITMAPCOREHEADER - { - _UINT32 bcSize; /* used to get to color table */ - _UINT16 bcWidth; - _UINT16 bcHeight; - _UINT16 bcPlanes; - _UINT16 bcBitCount; - }; - Global::BlipType GetFormatPict(unsigned char* data, int size) + struct __BITMAPINFOHEADER + { + _UINT32 biSize; + _INT32 biWidth; + _INT32 biHeight; + _UINT16 biPlanes; + _UINT16 biBitCount; + _UINT32 biCompression; + _UINT32 biSizeImage; + _INT32 biXPelsPerMeter; + _INT32 biYPelsPerMeter; + _UINT32 biClrUsed; + _UINT32 biClrImportant; + }; + + struct __BITMAPCOREHEADER + { + _UINT32 bcSize; /* used to get to color table */ + _UINT16 bcWidth; + _UINT16 bcHeight; + _UINT16 bcPlanes; + _UINT16 bcBitCount; + }; + Global::BlipType GetFormatPict(unsigned char* data, int size) { Global::BlipType btWin32 = Global::msoblipDIB; - + int offset = 0, biSizeImage = 0; - __BITMAPINFOHEADER * header = (__BITMAPINFOHEADER*)data; + __BITMAPINFOHEADER* header = (__BITMAPINFOHEADER*)data; if (!header) return btWin32; if (header->biWidth > 100000 || header->biHeight > 100000 || header->biSize != 40) { - __BITMAPCOREHEADER * header_core = (__BITMAPCOREHEADER *)data; + __BITMAPCOREHEADER* header_core = (__BITMAPCOREHEADER*)data; if (header_core->bcSize != 12) { @@ -94,50 +94,50 @@ namespace DocFileFormat else { offset = 12; //sizeof(BITMAPCOREHEADER) - int stride = (size - offset) / header_core->bcHeight; + int stride = (size - offset) / header_core->bcHeight; biSizeImage = size - offset; - - if (stride >= header_core->bcWidth && header_core->bcBitCount >=24 ) + + if (stride >= header_core->bcWidth && header_core->bcBitCount >= 24) { - btWin32 = Global::msoblipPNG; + btWin32 = Global::msoblipPNG; } } } else { offset = 40; //sizeof(BITMAPINFOHEADER) - int sz_bitmap = header->biHeight * header->biWidth * header->biBitCount/ 8; - + int sz_bitmap = header->biHeight * header->biWidth * header->biBitCount / 8; + int stride = (size - offset) / header->biHeight; if (stride >= header->biWidth && header->biBitCount >= 24) { - btWin32 = Global::msoblipPNG; + btWin32 = Global::msoblipPNG; } } return btWin32; } - bool VMLPictureMapping::ParseEmbeddedBlob( const std::string & xmlString, std::wstring & newXmlString) + bool VMLPictureMapping::ParseEmbeddedBlob(const std::string& xmlString, std::wstring& newXmlString) { newXmlString.clear(); std::wstring sTempFolder = m_context->_doc->m_sTempFolder; if (sTempFolder.empty()) { - sTempFolder = NSFile::CFileBinary::GetTempPath(); + sTempFolder = NSFile::CFileBinary::GetTempPath(); } std::wstring sTempXmlFile = NSDirectory::CreateTempFileWithUniqueName(sTempFolder, L"emb"); - NSFile::CFileBinary file; + NSFile::CFileBinary file; file.CreateFileW(sTempXmlFile); file.WriteFile((BYTE*)xmlString.c_str(), xmlString.size()); file.CloseFile(); COfficeUtils officeUtils(NULL); - BYTE *utf8Data = NULL; + BYTE* utf8Data = NULL; ULONG utf8DataSize = 0; if (S_OK != officeUtils.LoadFileFromArchive(sTempXmlFile, L"drs/shapexml.xml", &utf8Data, utf8DataSize)) { @@ -155,7 +155,7 @@ namespace DocFileFormat { newXmlString = NSFile::CUtf8Converter::GetUnicodeStringFromUTF8(utf8Data, utf8DataSize); - delete []utf8Data; + delete[]utf8Data; } NSFile::CFileBinary::Remove(sTempXmlFile); @@ -163,7 +163,7 @@ namespace DocFileFormat return true; } - bool VMLPictureMapping::ParseEmbeddedEquation(std::pair, size_t> & data, std::wstring & xmlString) + bool VMLPictureMapping::ParseEmbeddedEquation(std::pair, size_t>& data, std::wstring& xmlString) { xmlString.clear(); @@ -172,12 +172,12 @@ namespace DocFileFormat std::wstring sTempFolder = m_context->_doc->m_sTempFolder; if (sTempFolder.empty()) { - sTempFolder = NSFile::CFileBinary::GetTempPath(); + sTempFolder = NSFile::CFileBinary::GetTempPath(); } std::wstring sTempXmlFile = NSDirectory::CreateTempFileWithUniqueName(sTempFolder, L"emb"); - NSFile::CFileBinary file; + NSFile::CFileBinary file; file.CreateFileW(sTempXmlFile); file.WriteFile((BYTE*)data.first.get(), data.second); file.CloseFile(); @@ -186,14 +186,14 @@ namespace DocFileFormat OOX::CDocument docEmbedded(NULL, path, path); bool res = false; - for (std::vector::iterator it = docEmbedded.m_arrItems.begin(); it != docEmbedded.m_arrItems.end(); ++it) + for (std::vector::iterator it = docEmbedded.m_arrItems.begin(); it != docEmbedded.m_arrItems.end(); ++it) { if ((*it)->getType() == OOX::et_w_p) { - OOX::Logic::CParagraph *paragraph = dynamic_cast(*it); + OOX::Logic::CParagraph* paragraph = dynamic_cast(*it); - for (std::vector::iterator jt = paragraph->m_arrItems.begin(); - (paragraph) && (jt != paragraph->m_arrItems.end()); jt++) + for (std::vector::iterator jt = paragraph->m_arrItems.begin(); + (paragraph) && (jt != paragraph->m_arrItems.end()); jt++) { if ((*jt)->getType() == OOX::et_m_oMath) { @@ -203,10 +203,10 @@ namespace DocFileFormat } else if ((*jt)->getType() == OOX::et_m_oMathPara) { - OOX::Logic::COMathPara *mathPara = dynamic_cast(*jt); - - for (std::vector::iterator kt = mathPara->m_arrItems.begin(); - (mathPara) && (kt != mathPara->m_arrItems.end()); kt++) + OOX::Logic::COMathPara* mathPara = dynamic_cast(*jt); + + for (std::vector::iterator kt = mathPara->m_arrItems.begin(); + (mathPara) && (kt != mathPara->m_arrItems.end()); kt++) { if ((*kt)->getType() == OOX::et_m_oMath) { @@ -224,26 +224,26 @@ namespace DocFileFormat NSFile::CFileBinary::Remove(sTempXmlFile); return res; } -//--------------------------------------------------------------- + //--------------------------------------------------------------- void VMLPictureMapping::appendStyleProperty(std::wstring& style, const std::wstring& propName, const std::wstring& propValue) const { - style += ( propName ); - style += ( L":" ); - style += ( propValue ); - style +=( L";" ); + style += (propName); + style += (L":"); + style += (propValue); + style += (L";"); } VMLPictureMapping::VMLPictureMapping(ConversionContext* ctx, XMLTools::CStringXmlWriter* writer, bool olePreview, IMapping* caller, bool isInlinePicture, bool inGroup) : PropertiesMapping(writer) { - m_context = ctx; - m_isOlePreview = olePreview; - m_imageData = NULL; - m_nImageId = 0; - m_caller = caller; - m_isInlinePicture = isInlinePicture; - m_inGroup = inGroup; - - m_imageData = new XMLTools::XMLElement( L"v:imagedata" ); + m_context = ctx; + m_isOlePreview = olePreview; + m_imageData = NULL; + m_nImageId = 0; + m_caller = caller; + m_isInlinePicture = isInlinePicture; + m_inGroup = inGroup; + + m_imageData = new XMLTools::XMLElement(L"v:imagedata"); } VMLPictureMapping::~VMLPictureMapping() @@ -262,7 +262,7 @@ namespace DocFileFormat return strXmlAttr; } - void VMLPictureMapping::Apply( IVisitable* visited ) + void VMLPictureMapping::Apply(IVisitable* visited) { PictureDescriptor* pict = dynamic_cast(visited); if (!pict) return; @@ -270,92 +270,93 @@ namespace DocFileFormat double xScaling = pict->mx / 1000.0; double yScaling = pict->my / 1000.0; - TwipsValue width( ( pict->dxaGoal - ( pict->dxaCropLeft + pict->dxaCropRight ) ) * xScaling ); - TwipsValue height( ( pict->dyaGoal - ( pict->dyaCropTop + pict->dyaCropBottom ) ) * yScaling ); + TwipsValue width((pict->dxaGoal - (pict->dxaCropLeft + pict->dxaCropRight)) * xScaling); + TwipsValue height((pict->dyaGoal - (pict->dyaCropTop + pict->dyaCropBottom)) * yScaling); - std::wstring strWidth = FormatUtils::DoubleToWideString( width.ToPoints() ); - std::wstring strHeight = FormatUtils::DoubleToWideString( height.ToPoints() ); + std::wstring strWidth = FormatUtils::DoubleToWideString(width.ToPoints()); + std::wstring strHeight = FormatUtils::DoubleToWideString(height.ToPoints()); std::wstring strStyle; - + std::vector options; - + PictureFrameType type; Shape* pShape = NULL; if ((pict->shapeContainer || pict->blipStoreEntry) && pict->shapeContainer->Children.size() > 0) { - pShape = static_cast(*(pict->shapeContainer->Children.begin())); - options = pict->shapeContainer->ExtractOptions(); + pShape = static_cast(*(pict->shapeContainer->Children.begin())); + options = pict->shapeContainer->ExtractOptions(); //v:shapetype type.SetType(pShape->Instance); - - VMLShapeTypeMapping* vmlShapeTypeMapping = new VMLShapeTypeMapping( m_pXmlWriter, m_isInlinePicture ); - type.Convert( vmlShapeTypeMapping ); - RELEASEOBJECT( vmlShapeTypeMapping ); + VMLShapeTypeMapping* vmlShapeTypeMapping = new VMLShapeTypeMapping(m_pXmlWriter, m_isInlinePicture); + + type.Convert(vmlShapeTypeMapping); + RELEASEOBJECT(vmlShapeTypeMapping); } else if (pict->embeddedData) { type.SetType(msosptPictureFrame); } - m_pXmlWriter->WriteNodeBegin( L"v:shape", true ); + m_pXmlWriter->WriteNodeBegin(L"v:shape", true); //m_shapeId = GetShapeID(pShape); - todooo одинаковые картинки (одинаковый spid) - Anexo№3.doc - + if (m_shapeId.empty()) { m_context->_doc->GetOfficeArt()->m_uLastShapeId++; - m_shapeId = L"_x0000_i" + FormatUtils::IntToWideString(m_context->_doc->GetOfficeArt()->m_uLastShapeId); + m_shapeId = L"_x0000_i" + FormatUtils::IntToWideString(m_context->_doc->GetOfficeArt()->m_uLastShapeId); } - - m_pXmlWriter->WriteAttribute( L"id", m_shapeId); - - m_pXmlWriter->WriteAttribute( L"type", std::wstring( L"#" + VMLShapeTypeMapping::GenerateTypeId(&type))); -//todooo oбъединить с shape_mapping + m_pXmlWriter->WriteAttribute(L"id", m_shapeId); + + m_pXmlWriter->WriteAttribute(L"type", std::wstring(L"#" + VMLShapeTypeMapping::GenerateTypeId(&type))); + + //todooo oбъединить с shape_mapping + int nColorRGBBase = 0xffffff; for (size_t i = 0; i < options.size(); i++) { - ODRAW::OfficeArtFOPTEPtr & iter = options[i]; + ODRAW::OfficeArtFOPTEPtr& iter = options[i]; switch (iter->opid) { case ODRAW::wzEquationXML: + { + ODRAW::XmlString* pXml = dynamic_cast(iter.get()); + if (pXml) { - ODRAW::XmlString *pXml = dynamic_cast(iter.get()); - if (pXml) - { - m_isEquation = true; - m_isEmbedded = true; + m_isEquation = true; + m_isEmbedded = true; - m_embeddedData = pXml->data; + m_embeddedData = pXml->data; - if (ParseEmbeddedEquation(m_embeddedData, m_equationXml)) - { - m_isEmbedded = false; - } - } - }break; - case ODRAW::metroBlob: - {//встроенная неведомая хуйня - ODRAW::MetroBlob* blob = dynamic_cast(iter.get()); - if (blob) + if (ParseEmbeddedEquation(m_embeddedData, m_equationXml)) { - m_isBlob = true; - m_isEmbedded = true; - //if (ParseEmbeddedBlob( blob->data.first, blob->data.second)) // todoooo - //{ - // m_isEmbedded = false; - //} + m_isEmbedded = false; } - }break; + } + }break; + case ODRAW::metroBlob: + {//встроенная неведомая хуйня + ODRAW::MetroBlob* blob = dynamic_cast(iter.get()); + if (blob) + { + m_isBlob = true; + m_isEmbedded = true; + //if (ParseEmbeddedBlob( blob->data.first, blob->data.second)) // todoooo + //{ + // m_isEmbedded = false; + //} + } + }break; //BORDERS case ODRAW::borderBottomColor: if (!pict->brcBottom) { ODRAW::OfficeArtCOLORREF bottomColor((_UINT32)iter->op); - m_context->_doc->CorrectColor(bottomColor); + m_context->_doc->CorrectColor(bottomColor, nColorRGBBase); if (false == bottomColor.sColorRGB.empty()) m_pXmlWriter->WriteAttribute(L"o:borderbottomcolor", L"#" + bottomColor.sColorRGB); } @@ -364,7 +365,7 @@ namespace DocFileFormat if (!pict->brcLeft) { ODRAW::OfficeArtCOLORREF leftColor((_UINT32)iter->op); - m_context->_doc->CorrectColor(leftColor); + m_context->_doc->CorrectColor(leftColor, nColorRGBBase); if (false == leftColor.sColorRGB.empty()) m_pXmlWriter->WriteAttribute(L"o:borderleftcolor", L"#" + leftColor.sColorRGB); } @@ -373,7 +374,7 @@ namespace DocFileFormat if (!pict->brcRight) { ODRAW::OfficeArtCOLORREF rightColor((_UINT32)iter->op); - m_context->_doc->CorrectColor(rightColor); + m_context->_doc->CorrectColor(rightColor, nColorRGBBase); if (false == rightColor.sColorRGB.empty()) m_pXmlWriter->WriteAttribute(L"o:borderrightcolor", L"#" + rightColor.sColorRGB); } @@ -382,271 +383,325 @@ namespace DocFileFormat if (!pict->brcTop) { ODRAW::OfficeArtCOLORREF topColor((_UINT32)iter->op); - m_context->_doc->CorrectColor(topColor); + m_context->_doc->CorrectColor(topColor, nColorRGBBase); if (false == topColor.sColorRGB.empty()) m_pXmlWriter->WriteAttribute(L"o:bordertopcolor", L"#" + topColor.sColorRGB); } break; - //CROPPING - case ODRAW::cropFromBottom: + case ODRAW::pibName: + { + ODRAW::AnyString* str = dynamic_cast(iter.get()); + if ((str) && (!str->string_.empty())) { - //cast to signed integer - int cropBottom = (int)iter->op; - appendValueAttribute(m_imageData, L"cropbottom", FormatUtils::IntToWideString(cropBottom) + L"f"); + appendValueAttribute(m_imageData, L"o:title", str->string_); } - break; + }break; + case ODRAW::pictureTransparent: + { + + }break; + case ODRAW::pictureContrast: + { + appendValueAttribute(m_imageData, L"gain", (std::to_wstring(iter->op) + L"f")); + }break; + case ODRAW::pictureBrightness: + { + appendValueAttribute(m_imageData, L"blacklevel", (std::to_wstring(iter->op) + L"f")); + }break; + case ODRAW::pictureGamma: + { + appendValueAttribute(m_imageData, L"gamma", (std::to_wstring(iter->op) + L"f")); + }break; + //CROPPING + case ODRAW::cropFromBottom: + { + //cast to signed integer + int cropBottom = (int)iter->op; + appendValueAttribute(m_imageData, L"cropbottom", FormatUtils::IntToWideString(cropBottom) + L"f"); + } + break; case ODRAW::cropFromLeft: - { - //cast to signed integer - int cropLeft = (int)iter->op; - appendValueAttribute(m_imageData, L"cropleft", FormatUtils::IntToWideString(cropLeft) + L"f"); - } - break; + { + //cast to signed integer + int cropLeft = (int)iter->op; + appendValueAttribute(m_imageData, L"cropleft", FormatUtils::IntToWideString(cropLeft) + L"f"); + } + break; case ODRAW::cropFromRight: - { - //cast to signed integer - int cropRight = (int)iter->op; - appendValueAttribute(m_imageData, L"cropright", FormatUtils::IntToWideString(cropRight) + L"f"); - } - break; + { + //cast to signed integer + int cropRight = (int)iter->op; + appendValueAttribute(m_imageData, L"cropright", FormatUtils::IntToWideString(cropRight) + L"f"); + } + break; case ODRAW::cropFromTop: - { - //cast to signed integer - int cropTop = (int)iter->op; - appendValueAttribute(m_imageData, L"croptop", FormatUtils::IntToWideString(cropTop) + L"f"); - } - break; + { + //cast to signed integer + int cropTop = (int)iter->op; + appendValueAttribute(m_imageData, L"croptop", FormatUtils::IntToWideString(cropTop) + L"f"); + } + break; //------------------------------------------------------------ case ODRAW::ePropertyId_rotation: - { - double dAngle = (double)((int)iter->op) / 65535.0; + { + double dAngle = (double)((int)iter->op) / 65535.0; - if (dAngle < -360.0) - dAngle += 360.0; + if (dAngle < -360.0) + dAngle += 360.0; - std::wstring v = strHeight; - strHeight = strWidth; strWidth = v; + std::wstring v = strHeight; + strHeight = strWidth; strWidth = v; - appendStyleProperty(strStyle, L"rotation", FormatUtils::DoubleToWideString(dAngle)); - }break; + appendStyleProperty(strStyle, L"rotation", FormatUtils::DoubleToWideString(dAngle)); + }break; case ODRAW::posh: - { - appendStyleProperty(strStyle, L"mso-position-horizontal", VMLShapeMapping::mapHorizontalPosition((PositionHorizontal)iter->op)); - }break; + { + appendStyleProperty(strStyle, L"mso-position-horizontal", VMLShapeMapping::mapHorizontalPosition((PositionHorizontal)iter->op)); + }break; case ODRAW::posrelh: - { - if (false == m_inGroup) - appendStyleProperty(strStyle, L"mso-position-horizontal-relative", VMLShapeMapping::mapHorizontalPositionRelative((PositionHorizontalRelative)iter->op)); - }break; + { + if (false == m_inGroup) + appendStyleProperty(strStyle, L"mso-position-horizontal-relative", VMLShapeMapping::mapHorizontalPositionRelative((PositionHorizontalRelative)iter->op)); + }break; case ODRAW::posv: - { - appendStyleProperty(strStyle, L"mso-position-vertical", VMLShapeMapping::mapVerticalPosition((PositionVertical)iter->op)); - }break; + { + appendStyleProperty(strStyle, L"mso-position-vertical", VMLShapeMapping::mapVerticalPosition((PositionVertical)iter->op)); + }break; case ODRAW::posrelv: - { - if (false == m_inGroup) - appendStyleProperty(strStyle, L"mso-position-vertical-relative", VMLShapeMapping::mapVerticalPositionRelative((PositionVerticalRelative)iter->op)); - }break; + { + if (false == m_inGroup) + appendStyleProperty(strStyle, L"mso-position-vertical-relative", VMLShapeMapping::mapVerticalPositionRelative((PositionVerticalRelative)iter->op)); + }break; case ODRAW::groupShapeBooleanProperties: - { - ODRAW::GroupShapeBooleanProperties* booleans = dynamic_cast(iter.get()); + { + ODRAW::GroupShapeBooleanProperties* booleans = dynamic_cast(iter.get()); - if (booleans->fUsefBehindDocument && booleans->fBehindDocument) - { - //The shape is behind the text, so the z-index must be negative. - appendStyleProperty(strStyle, L"z-index", L"-1"); - } - //else if (!m_isInlinePicture) - //{ - // appendStyleProperty( &strStyle, L"z-index", FormatUtils::IntToWideString(zIndex + 0x7ffff)); - //} + if (booleans->fUsefBehindDocument && booleans->fBehindDocument) + { + //The shape is behind the text, so the z-index must be negative. + appendStyleProperty(strStyle, L"z-index", L"-1"); + } + //else if (!m_isInlinePicture) + //{ + // appendStyleProperty( &strStyle, L"z-index", FormatUtils::IntToWideString(zIndex + 0x7ffff)); + //} - if (booleans->fHidden && booleans->fUsefHidden) - { - appendStyleProperty(strStyle, L"visibility", L"hidden"); - } - }break; + if (booleans->fHidden && booleans->fUsefHidden) + { + appendStyleProperty(strStyle, L"visibility", L"hidden"); + } + }break; case ODRAW::blipBooleanProperties: + { + ODRAW::BlipBooleanProperties* bools = (ODRAW::BlipBooleanProperties*)(iter.get()); + if (bools) { - ODRAW::BlipBooleanProperties * bools = (ODRAW::BlipBooleanProperties *)(iter.get()); - if (bools) - { - if (bools->fUsefPictureGray && bools->fPictureGray) - appendValueAttribute(m_imageData, L"grayscale", L"t"); - if (bools->fUsefPictureBiLevel && bools->fPictureBiLevel) - appendValueAttribute(m_imageData, L"bilevel", L"t"); - } - }break; + if (bools->fUsefPictureGray && bools->fPictureGray) + appendValueAttribute(m_imageData, L"grayscale", L"t"); + if (bools->fUsefPictureBiLevel && bools->fPictureBiLevel) + appendValueAttribute(m_imageData, L"bilevel", L"t"); + } + }break; default: - { - }break; + { + }break; } } - strStyle += L"width:" + strWidth + L"pt;" + L"height:" + strHeight + L"pt;"; + strStyle += L"width:" + strWidth + L"pt;" + L"height:" + strHeight + L"pt;"; - m_pXmlWriter->WriteAttribute( L"style", strStyle); + m_pXmlWriter->WriteAttribute(L"style", strStyle); if (m_isOlePreview) { - m_pXmlWriter->WriteAttribute( L"o:ole", L"t" ); + m_pXmlWriter->WriteAttribute(L"o:ole", L"t"); } else if (m_isBullete) { - m_pXmlWriter->WriteAttribute( L"o:bullet", L"1" ); + m_pXmlWriter->WriteAttribute(L"o:bullet", L"1"); } {//borders color if (pict->brcTop) - m_pXmlWriter->WriteAttribute( L"o:bordertopcolor", - pict->brcTop->ico.empty() ? FormatUtils::IntToFormattedWideString(pict->brcTop->cv, L"#%06x") : pict->brcTop->ico); + m_pXmlWriter->WriteAttribute(L"o:bordertopcolor", pict->brcTop->getColor()); if (pict->brcLeft) - m_pXmlWriter->WriteAttribute( L"o:borderleftcolor", - pict->brcTop->ico.empty() ? FormatUtils::IntToFormattedWideString(pict->brcLeft->cv, L"#%06x") : pict->brcLeft->ico); + m_pXmlWriter->WriteAttribute(L"o:borderleftcolor", pict->brcLeft->getColor()); if (pict->brcBottom) - m_pXmlWriter->WriteAttribute( L"o:borderbottomcolor", - pict->brcTop->ico.empty() ? FormatUtils::IntToFormattedWideString(pict->brcBottom->cv, L"#%06x") : pict->brcBottom->ico); + m_pXmlWriter->WriteAttribute(L"o:borderbottomcolor", pict->brcBottom->getColor()); if (pict->brcRight) - m_pXmlWriter->WriteAttribute( L"o:borderrightcolor", - pict->brcTop->ico.empty() ? FormatUtils::IntToFormattedWideString(pict->brcRight->cv, L"#%06x") : pict->brcRight->ico); + m_pXmlWriter->WriteAttribute(L"o:borderrightcolor", pict->brcRight->getColor()); } - m_pXmlWriter->WriteNodeEnd( L"", TRUE, FALSE ); - + m_pXmlWriter->WriteNodeEnd(L"", TRUE, FALSE); + //v:imageData if (CopyPicture(pict)) { appendValueAttribute(m_imageData, L"r:id", L"rId" + FormatUtils::IntToWideString(m_nImageId)); - appendValueAttribute(m_imageData, L"o:title", L"" ); - m_pXmlWriter->WriteString(m_imageData->GetXMLString()); } else + { m_isPictureBroken = true; + } + if (m_imageData->GetAttributeCount() > 0 || m_imageData->GetChildCount() > 0) + { + m_pXmlWriter->WriteString(m_imageData->GetXMLString()); + } {//borders - writePictureBorder( L"bordertop", pict->brcTop ); - writePictureBorder( L"borderleft", pict->brcLeft ); - writePictureBorder( L"borderbottom", pict->brcBottom ); - writePictureBorder( L"borderright", pict->brcRight ); + writePictureBorder(L"bordertop", pict->brcTop); + writePictureBorder(L"borderleft", pict->brcLeft); + writePictureBorder(L"borderbottom", pict->brcBottom); + writePictureBorder(L"borderright", pict->brcRight); } - m_pXmlWriter->WriteNodeEnd( L"v:shape" ); + m_pXmlWriter->WriteNodeEnd(L"v:shape"); } - void VMLPictureMapping::writePictureBorder( const std::wstring & name, const BorderCode* brc ) + void VMLPictureMapping::writePictureBorder(const std::wstring& name, const BorderCode* brc) { if (!brc || name.empty()) return; - m_pXmlWriter->WriteNodeBegin( L"w10:" + name, true ); - m_pXmlWriter->WriteAttribute( L"type", getBorderType( brc->brcType )); - m_pXmlWriter->WriteAttribute( L"width", FormatUtils::IntToWideString( brc->dptLineWidth )); - m_pXmlWriter->WriteNodeEnd ( L"", true ); + m_pXmlWriter->WriteNodeBegin(L"w10:" + name, true); + m_pXmlWriter->WriteAttribute(L"type", getBorderType(brc->brcType)); + m_pXmlWriter->WriteAttribute(L"width", FormatUtils::IntToWideString(brc->dptLineWidth)); + m_pXmlWriter->WriteNodeEnd(L"", true); } - bool VMLPictureMapping::CopyPicture (PictureDescriptor* pict) + bool VMLPictureMapping::CopyPicture(PictureDescriptor* pict) { if (!pict) return false; bool result = false; - BlipStoreEntry* oBlipEntry = pict->blipStoreEntry; + BlipStoreEntry* pBlipEntry = pict->blipStoreEntry; if (pict->embeddedData && pict->embeddedDataSize > 0) { - Global::BlipType btWin32 = GetFormatPict(pict->embeddedData, pict->embeddedDataSize); + Global::BlipType btWin32 = GetFormatPict(pict->embeddedData, pict->embeddedDataSize); if (btWin32 == Global::msoblipWMF) { CMetaHeader oMetaHeader; - - oMetaHeader.rcBounds.right = pict->mfp.xExt ; - oMetaHeader.rcBounds.bottom = pict->mfp.yExt ; + + oMetaHeader.rcBounds.right = pict->mfp.xExt; + oMetaHeader.rcBounds.bottom = pict->mfp.yExt; WmfPlaceableFileHeader oWmfHeader = {}; oMetaHeader.ToWMFHeader(&oWmfHeader); - + int lLenHeader = 22 + (pict->embeddedDataHeader ? 114 : 0); - unsigned char *newData = new unsigned char[pict->embeddedDataSize + lLenHeader]; - - memcpy(newData, (unsigned char *)(&oWmfHeader), 22); + unsigned char* newData = new unsigned char[pict->embeddedDataSize + lLenHeader]; + + memcpy(newData, (unsigned char*)(&oWmfHeader), 22); if (pict->embeddedDataHeader) { - memcpy(newData + 22, pict->embeddedDataHeader, 114 ); + memcpy(newData + 22, pict->embeddedDataHeader, 114); } - + memcpy(newData + lLenHeader, pict->embeddedData, pict->embeddedDataSize); pict->embeddedDataSize += lLenHeader; - delete []pict->embeddedData; + delete[]pict->embeddedData; pict->embeddedData = newData; } - m_context->_docx->ImagesList.push_back(ImageFileStructure(GetTargetExt(btWin32), + m_context->_docx->ImagesList.push_back(ImageFileStructure(GetTargetExt(btWin32), pict->embeddedData, pict->embeddedDataSize, btWin32)); - - m_nImageId = m_context->_docx->RegisterImage(m_caller, btWin32); - result = true; + + m_nImageId = m_context->_docx->RegisterImage(m_caller, btWin32); + result = true; } - else if ((oBlipEntry != NULL) && (oBlipEntry->Blip != NULL)) + else if ((pBlipEntry != NULL) && (pBlipEntry->Blip != NULL)) { - switch (oBlipEntry->btWin32) + switch (pBlipEntry->btWin32) + { + case Global::msoblipEMF: + case Global::msoblipWMF: { - case Global::msoblipEMF: - case Global::msoblipWMF: - case Global::msoblipPICT: + MetafilePictBlip* metaBlip = static_cast(pBlipEntry->Blip); + if (metaBlip) + {//decompress inside MetafilePictBlip + unsigned char* newData = NULL; + unsigned int newDataSize = metaBlip->oMetaFile.ToBuffer(newData); + + boost::shared_array arData(newData); + m_context->_docx->ImagesList.push_back(ImageFileStructure(GetTargetExt(pBlipEntry->btWin32), arData, newDataSize)); + } + }break; + case Global::msoblipDIB: + {//user_manual_v52.doc + + BitmapBlip* bitBlip = static_cast(pBlipEntry->Blip); + if (bitBlip) { - MetafilePictBlip* metaBlip = static_cast(oBlipEntry->Blip); - if (metaBlip) - {//decompress inside MetafilePictBlip - unsigned char *newData = NULL; - unsigned int newDataSize = metaBlip->oMetaFile.ToBuffer(newData); - - boost::shared_array arData(newData); - m_context->_docx->ImagesList.push_back(ImageFileStructure(GetTargetExt(oBlipEntry->btWin32), arData, newDataSize)); + std::wstring file_name = m_context->_doc->m_sTempFolder + FILE_SEPARATOR_STR + L"tmp_image"; + pBlipEntry->btWin32 = ImageHelper::SaveImageToFileFromDIB(bitBlip->m_pvBits, bitBlip->pvBitsSize, file_name); + + unsigned char* pData = NULL; + DWORD nData = 0; + if (NSFile::CFileBinary::ReadAllBytes(file_name, &pData, nData)) + { + m_context->_docx->ImagesList.push_back(ImageFileStructure(GetTargetExt(pBlipEntry->btWin32), + boost::shared_array(pData), nData, pBlipEntry->btWin32)); } - }break; - case Global::msoblipDIB: - {//user_manual_v52.doc - - BitmapBlip* bitBlip = static_cast(oBlipEntry->Blip); - if (bitBlip) + NSFile::CFileBinary::Remove(file_name); + } + }break; + case Global::msoblipPICT: + { + MetafilePictBlip* metaBlip = static_cast(pBlipEntry->Blip); + if (metaBlip) + { + unsigned char* newData = NULL; + unsigned int newDataSize = metaBlip->oMetaFile.ToBuffer(newData); + + CBgraFrame bgraFrame; + if (bgraFrame.Decode(newData, newDataSize)) { std::wstring file_name = m_context->_doc->m_sTempFolder + FILE_SEPARATOR_STR + L"tmp_image"; - oBlipEntry->btWin32 = ImageHelper::SaveImageToFileFromDIB(bitBlip->m_pvBits, bitBlip->pvBitsSize, file_name); + bgraFrame.SaveFile(file_name, 4); // png unsigned char* pData = NULL; DWORD nData = 0; if (NSFile::CFileBinary::ReadAllBytes(file_name, &pData, nData)) { - m_context->_docx->ImagesList.push_back(ImageFileStructure(GetTargetExt(oBlipEntry->btWin32), - boost::shared_array(pData), nData, oBlipEntry->btWin32)); - - break; + pBlipEntry->btWin32 = Global::msoblipPNG; + + m_context->_docx->ImagesList.push_back(ImageFileStructure(GetTargetExt(pBlipEntry->btWin32), + boost::shared_array(pData), nData, pBlipEntry->btWin32)); } - } - } - case Global::msoblipJPEG: - case Global::msoblipCMYKJPEG: - case Global::msoblipPNG: - case Global::msoblipTIFF: - { - BitmapBlip* bitBlip = static_cast(oBlipEntry->Blip); - if (bitBlip) + NSFile::CFileBinary::Remove(file_name); + } + else { - m_context->_docx->ImagesList.push_back(ImageFileStructure(GetTargetExt(oBlipEntry->btWin32), - bitBlip->m_pvBits, bitBlip->pvBitsSize, oBlipEntry->btWin32)); + m_context->_docx->ImagesList.push_back(ImageFileStructure(metaBlip->oMetaFile.m_sExtension, + newData, newDataSize, pBlipEntry->btWin32)); } - }break; - - default: + } + }break; + case Global::msoblipJPEG: + case Global::msoblipCMYKJPEG: + case Global::msoblipPNG: + case Global::msoblipTIFF: + { + BitmapBlip* bitBlip = static_cast(pBlipEntry->Blip); + if (bitBlip) { - return false; - }break; + m_context->_docx->ImagesList.push_back(ImageFileStructure(GetTargetExt(pBlipEntry->btWin32), + bitBlip->m_pvBits, bitBlip->pvBitsSize, pBlipEntry->btWin32)); + } + }break; + + default: + { + return false; + }break; } - m_nImageId = m_context->_docx->RegisterImage(m_caller, oBlipEntry->btWin32); - result = true; + m_nImageId = m_context->_docx->RegisterImage(m_caller, pBlipEntry->btWin32); + result = true; } return result; @@ -655,7 +710,7 @@ namespace DocFileFormat namespace DocFileFormat { - std::wstring VMLPictureMapping::GetTargetExt (Global::BlipType nType) + std::wstring VMLPictureMapping::GetTargetExt(Global::BlipType nType) { switch (nType) { @@ -679,14 +734,14 @@ namespace DocFileFormat return std::wstring(L".wmf"); case Global::msoblipPICT: - return std::wstring(L".pcz"); + return std::wstring(L".pct"); default: return std::wstring(L".png"); } } - std::wstring VMLPictureMapping::GetContentType (Global::BlipType nType) + std::wstring VMLPictureMapping::GetContentType(Global::BlipType nType) { switch (nType) { @@ -720,7 +775,7 @@ namespace DocFileFormat case Global::msoblipDIB: return std::wstring(OpenXmlContentTypes::Bmp); - + default: return std::wstring(OpenXmlContentTypes::Png); } diff --git a/MsBinaryFile/DocFile/VMLShapeMapping.cpp b/MsBinaryFile/DocFile/VMLShapeMapping.cpp index 723c2825374..55e7d3aff54 100644 --- a/MsBinaryFile/DocFile/VMLShapeMapping.cpp +++ b/MsBinaryFile/DocFile/VMLShapeMapping.cpp @@ -294,7 +294,9 @@ namespace DocFileFormat boost::optional ShadowOriginY; boost::optional xCoord; boost::optional yCoord; - + boost::optional xCoord2; + boost::optional yCoord2; + bool bStroked = true; bool bFilled = true; bool hasTextbox = false; @@ -323,15 +325,24 @@ namespace DocFileFormat ODRAW::OfficeArtFOPTEPtr opConnectAngles; ODRAW::OfficeArtFOPTEPtr opConnectLocs; + int nColorRGBBase = 0xffffff, nFillType = 0; + + bool bFlipColors = false; + + boost::optional fill_left; + boost::optional fill_top; + boost::optional fill_right; + boost::optional fill_bottom; + for (size_t i = 0; i < options.size(); i++) { ODRAW::OfficeArtFOPTEPtr & iter = options[i]; switch (iter->opid) { - //BOOLEANS + //BOOLEANS case ODRAW::geometryBooleanProperties: { - ODRAW::GeometryBooleanProperties *booleans = dynamic_cast(iter.get()); + ODRAW::GeometryBooleanProperties* booleans = dynamic_cast(iter.get()); if (booleans->fUsefLineOK && !booleans->fLineOK) { bStroked = false; @@ -352,7 +363,7 @@ namespace DocFileFormat break; case ODRAW::fillStyleBooleanProperties: { - ODRAW::FillStyleBooleanProperties *booleans = dynamic_cast(iter.get()); + ODRAW::FillStyleBooleanProperties* booleans = dynamic_cast(iter.get()); if (booleans->fUsefFilled && !booleans->fFilled) { bFilled = false; @@ -365,7 +376,7 @@ namespace DocFileFormat }break; case ODRAW::lineStyleBooleanProperties: { - ODRAW::LineStyleBooleanProperties *booleans = dynamic_cast(iter.get()); + ODRAW::LineStyleBooleanProperties* booleans = dynamic_cast(iter.get()); if (booleans->fUsefLine && !booleans->fLine) { bStroked = false; @@ -383,14 +394,14 @@ namespace DocFileFormat break; case ODRAW::groupShapeBooleanProperties: { - ODRAW::GroupShapeBooleanProperties *booleans = dynamic_cast(iter.get()); + ODRAW::GroupShapeBooleanProperties* booleans = dynamic_cast(iter.get()); if (booleans->fUsefLayoutInCell) { layoutInCell = booleans->fLayoutInCell; } } break; - // GEOMETRY + // GEOMETRY case ODRAW::shapePath: { bHavePath = true; @@ -471,6 +482,14 @@ namespace DocFileFormat m_pXmlWriter->WriteAttribute(L"wrapcoords", wrapCoords); } }break; + case ODRAW::geoLeft: + { + xCoord2 = iter->op; + }break; + case ODRAW::geoTop: + { + yCoord2 = iter->op; + }break; case ODRAW::geoRight: { xCoord = iter->op; @@ -483,7 +502,7 @@ namespace DocFileFormat case ODRAW::lineColor: { ODRAW::OfficeArtCOLORREF lineColor((_UINT32)iter->op); - m_context->_doc->CorrectColor(lineColor); + m_context->_doc->CorrectColor(lineColor, nColorRGBBase); if (false == lineColor.sColorRGB.empty() && !pShape->fBackground) m_pXmlWriter->WriteAttribute(L"strokecolor", (std::wstring(L"#") + lineColor.sColorRGB)); }break; @@ -542,18 +561,20 @@ namespace DocFileFormat case 3: m_pXmlWriter->WriteAttribute(L"o:connectortype", L"none"); break; } }break; - // FILL + // FILL case ODRAW::fillColor: { ODRAW::OfficeArtCOLORREF fillColor((_UINT32)iter->op); - m_context->_doc->CorrectColor(fillColor); + m_context->_doc->CorrectColor(fillColor, nColorRGBBase); if (false == fillColor.sColorRGB.empty()) m_pXmlWriter->WriteAttribute(L"fillcolor", (std::wstring(L"#") + fillColor.sColorRGB)); + + nColorRGBBase = fillColor.nColorRGB; }break; case ODRAW::fillBackColor: { ODRAW::OfficeArtCOLORREF fillBackColor((_UINT32)iter->op); - m_context->_doc->CorrectColor(fillBackColor); + m_context->_doc->CorrectColor(fillBackColor, nColorRGBBase); if (false == fillBackColor.sColorRGB.empty()) appendValueAttribute(&m_fill, L"color2", (std::wstring(L"#") + fillBackColor.sColorRGB)); @@ -573,13 +594,47 @@ namespace DocFileFormat }break; case ODRAW::fillFocus: { - appendValueAttribute(&m_fill, L"focus", (std::to_wstring(iter->op) + L"%")); - appendValueAttribute(&m_fill, L"focusposition", L".5, .5"); + appendValueAttribute(&m_fill, L"focus", (std::to_wstring(iter->op) + L"%")); appendValueAttribute(&m_fill, L"focussize", L""); }break; case ODRAW::fillType: { - appendValueAttribute(&m_fill, L"type", getFillType(iter->op)); + nFillType = iter->op; + appendValueAttribute(&m_fill, L"type", getFillType(nFillType)); + if (nFillType == 6) + { + fill_top = 0.5; + fill_left = 0.5; + } + + //if (nFillType == 7) bFlipColors = true; + }break; + case ODRAW::fillToLeft: + { + ODRAW::FixedPoint* point = dynamic_cast(iter.get()); + if (point) fill_left = point->dVal; + }break; + case ODRAW::fillToTop: + { + ODRAW::FixedPoint* point = dynamic_cast(iter.get()); + if (point) fill_top = point->dVal; + }break; + case ODRAW::fillToRight: + { + ODRAW::FixedPoint* point = dynamic_cast(iter.get()); + if (point) fill_right = point->dVal; + }break; + case ODRAW::fillToBottom: + { + ODRAW::FixedPoint* point = dynamic_cast(iter.get()); + if (point) fill_bottom = point->dVal; + }break; + case ODRAW::fillRectLeft: + case ODRAW::fillRectTop: + case ODRAW::fillRectRight: + case ODRAW::fillRectBottom: + { + }break; case ODRAW::fillBlip: { @@ -630,7 +685,7 @@ namespace DocFileFormat case ODRAW::shadowColor: { ODRAW::OfficeArtCOLORREF shadowColor((_UINT32)iter->op); - m_context->_doc->CorrectColor(shadowColor); + m_context->_doc->CorrectColor(shadowColor, nColorRGBBase); if (false == shadowColor.sColorRGB.empty()) appendValueAttribute(&m_shadow, L"color", (std::wstring(L"#") + shadowColor.sColorRGB)); }break; @@ -932,6 +987,18 @@ namespace DocFileFormat } } + if (fill_top || fill_left) + { + std::wstring focusposition; + if (fill_left) focusposition += FormatUtils::DoubleToFormattedWideString(*fill_left, L"%.2f"); + if (fill_top) + { + focusposition += L","; + focusposition += FormatUtils::DoubleToFormattedWideString(*fill_top, L"%.2f"); + } + appendValueAttribute(&m_fill, L"focusposition", focusposition); + } + ODRAW::PVertices* pVP = dynamic_cast(opVerticles.get()); ODRAW::PSegmentInfo* pSI = dynamic_cast(opSegmentInfo.get()); if (pVP && pSI) @@ -964,7 +1031,15 @@ namespace DocFileFormat if ( xCoord && yCoord ) { - m_pXmlWriter->WriteAttribute( L"coordsize", ( FormatUtils::SizeTToWideString( *xCoord ) + L"," + FormatUtils::SizeTToWideString( *yCoord ) )); + if (xCoord2 && yCoord2) + { + m_pXmlWriter->WriteAttribute(L"coordorigin", (FormatUtils::SizeTToWideString(*xCoord2) + L"," + FormatUtils::SizeTToWideString(*yCoord2))); + m_pXmlWriter->WriteAttribute(L"coordsize", (FormatUtils::SizeTToWideString(*xCoord - *xCoord2) + L"," + FormatUtils::SizeTToWideString(*yCoord - *yCoord2))); + } + else + { + m_pXmlWriter->WriteAttribute(L"coordsize", (FormatUtils::SizeTToWideString(*xCoord) + L"," + FormatUtils::SizeTToWideString(*yCoord))); + } } int nCode = 0; diff --git a/MsBinaryFile/DocFile/VirtualStreamReader.cpp b/MsBinaryFile/DocFile/VirtualStreamReader.cpp index 62d4a3080e7..a79170931d9 100644 --- a/MsBinaryFile/DocFile/VirtualStreamReader.cpp +++ b/MsBinaryFile/DocFile/VirtualStreamReader.cpp @@ -194,7 +194,7 @@ std::wstring VirtualStreamReader::ReadXst() int xstzSize = DocFileFormat::FormatUtils::BytesToUChar( cch, 0, cchSize ) * 1; xstz = ReadBytes(xstzSize, true); - DocFileFormat::FormatUtils::GetSTLCollectionFromBytes( &wstrResult, xstz, xstzSize, ENCODING_WINDOWS_1250 ); + DocFileFormat::FormatUtils::GetWStringFromBytes( wstrResult, xstz, xstzSize, ENCODING_WINDOWS_1250 ); } else { @@ -204,7 +204,7 @@ std::wstring VirtualStreamReader::ReadXst() int xstzSize = DocFileFormat::FormatUtils::BytesToInt16( cch, 0, cchSize ) * 2; xstz = ReadBytes(xstzSize, true); - DocFileFormat::FormatUtils::GetSTLCollectionFromBytes( &wstrResult, xstz, xstzSize, ENCODING_UTF16 ); + wstrResult = NSFile::CUtf8Converter::GetWStringFromUTF16((unsigned short*)(xstz), xstzSize / 2); } RELEASEARRAYOBJECTS(xstz); @@ -228,7 +228,7 @@ std::wstring VirtualStreamReader::ReadLengthPrefixedUnicodeString() //dont read the terminating zero unsigned char* stringBytes = ReadBytes( ( cch * 2 ), true ); - DocFileFormat::FormatUtils::GetSTLCollectionFromBytes( &result, stringBytes, ( ( cch * 2 ) - 2 ), ENCODING_UTF16 ); + result = NSFile::CUtf8Converter::GetWStringFromUTF16((unsigned short*)(stringBytes), cch - 1); RELEASEARRAYOBJECTS( stringBytes ); } @@ -272,7 +272,7 @@ std::wstring VirtualStreamReader::ReadLengthPrefixedAnsiString(unsigned int max_ //dont read the terminating zero stringBytes = ReadBytes( cch, true ); - DocFileFormat::FormatUtils::GetSTLCollectionFromBytes( &result, stringBytes, ( cch - 1 ), ENCODING_WINDOWS_1250); + DocFileFormat::FormatUtils::GetWStringFromBytes( result, stringBytes, ( cch - 1 ), ENCODING_WINDOWS_1250); } RELEASEARRAYOBJECTS( stringBytes ); diff --git a/MsBinaryFile/DocFile/WideString.cpp b/MsBinaryFile/DocFile/WideString.cpp index c91499ff50f..314d87627fa 100644 --- a/MsBinaryFile/DocFile/WideString.cpp +++ b/MsBinaryFile/DocFile/WideString.cpp @@ -54,11 +54,11 @@ namespace DocFileFormat //It's a real string table if (reader->nWordVersion > 0) { - FormatUtils::GetSTLCollectionFromBytes( newObject, bytes, length, ENCODING_WINDOWS_1250 ); + FormatUtils::GetWStringFromBytes( *newObject, bytes, length, ENCODING_WINDOWS_1250 ); } else { - FormatUtils::GetSTLCollectionFromBytes( newObject, bytes, length, ENCODING_UTF16 ); + FormatUtils::GetWStringFromBytes( *newObject, bytes, length, ENCODING_UTF16 ); } RELEASEARRAYOBJECTS( bytes ); diff --git a/MsBinaryFile/DocFile/WordDocument.cpp b/MsBinaryFile/DocFile/WordDocument.cpp index 5f9f9ec20d6..4066179619b 100644 --- a/MsBinaryFile/DocFile/WordDocument.cpp +++ b/MsBinaryFile/DocFile/WordDocument.cpp @@ -499,8 +499,13 @@ namespace DocFileFormat RELEASEOBJECT(Text); Text = new std::vector(); - FormatUtils::GetSTLCollectionFromBytes>(Text, bytes, cb, nFontsCodePage != ENCODING_WINDOWS_1250 ? nFontsCodePage : nDocumentCodePage); + int coding = nFontsCodePage != ENCODING_WINDOWS_1250 ? nFontsCodePage : (nWordVersion < 1 ? nDocumentCodePage : ENCODING_WINDOWS_1250); + FormatUtils::GetSTLCollectionFromBytes(Text, bytes, cb, coding); + + //std::wstring strTest1 = NSFile::CUtf8Converter::GetUnicodeStringFromUTF8(bytes, cb); + //std::wstring strTest2; + //FormatUtils::GetWStringFromBytes(strTest2, bytes, cb, ENCODING_WINDOWS_1250); RELEASEARRAYOBJECTS(bytes); } } @@ -639,17 +644,12 @@ namespace DocFileFormat } m_sTempDecryptFileName = m_sTempFolder + FILE_SEPARATOR_STR + L"~tempFile.doc"; - POLE::Storage *storageIn = m_pStorage->GetStorage(); - POLE::Storage *storageOut = new POLE::Storage(m_sTempDecryptFileName.c_str()); + POLE::Storage *storageIn = m_pStorage->GetStorage(); + CFCPP::CompoundFile* storageOut = new CFCPP::CompoundFile(CFCPP::Ver_3, CFCPP::Default); if (!storageOut || !storageIn) return false; - if (!storageOut->open(true, true)) - { - delete storageOut; - return false; - } - DecryptStream( 0, L"/", storageIn, storageOut, Decryptor); + DecryptStream( 0, L"/", storageIn, storageOut->RootStorage(), Decryptor); //std::list listStream = storageIn->entries(); @@ -671,7 +671,8 @@ namespace DocFileFormat //} - storageOut->close(); + bool result = storageOut->Save(m_sTempDecryptFileName); + storageOut->Close(); delete storageOut; //reset streams @@ -690,10 +691,10 @@ namespace DocFileFormat { if (!m_pStorage->GetStream (L"0Table", &TableStream)) m_pStorage->GetStream (L"1Table", &TableStream); } - return true; + return result; } - void WordDocument::DecryptStream( int level, std::wstring path, POLE::Storage * storageIn, POLE::Storage * storageOut, CRYPT::Decryptor* Decryptor) + void WordDocument::DecryptStream( int level, std::wstring path, POLE::Storage* storageIn, std::shared_ptr storageOut, CRYPT::Decryptor* Decryptor) { std::list entries, entries_files, entries_dir; entries = storageIn->entries_with_prefix( path ); @@ -716,7 +717,8 @@ namespace DocFileFormat { std::wstring fullname = path + *it; - DecryptStream( level + 1, fullname + L"/", storageIn, storageOut, Decryptor ); + std::shared_ptr storageOutNew = storageOut->AddStorage(*it); + DecryptStream( level + 1, fullname + L"/", storageIn, storageOutNew, Decryptor ); } //if (bSortFiles) @@ -724,8 +726,6 @@ namespace DocFileFormat for( std::list::iterator it = entries_files.begin(); it != entries_files.end(); ++it ) { - std::wstring fullname_create = path + *it; - if (it->at(0) < 32) { *it = it->substr(1); // without prefix @@ -743,10 +743,10 @@ namespace DocFileFormat { bDecrypt = true; } - DecryptStream(fullname_open, storageIn, fullname_create, storageOut, Decryptor, bDecrypt); + DecryptStream(fullname_open, storageIn, *it, storageOut, Decryptor, bDecrypt); } } - bool WordDocument::DecryptStream(std::wstring streamName_open, POLE::Storage * storageIn, std::wstring streamName_create, POLE::Storage * storageOut, CRYPT::Decryptor* Decryptor, bool bDecrypt) + bool WordDocument::DecryptStream(std::wstring streamName_open, POLE::Storage* storageIn, std::wstring streamName_create, std::shared_ptr storageOut, CRYPT::Decryptor* Decryptor, bool bDecrypt) { POLE::Stream *stream = new POLE::Stream(storageIn, streamName_open); if (!stream) return false; @@ -754,7 +754,7 @@ namespace DocFileFormat stream->seek(0); POLE::uint64 size_stream = stream->size(); - POLE::Stream *streamNew = new POLE::Stream(storageOut, streamName_create, true, size_stream); + std::shared_ptr streamNew = storageOut->AddStream(streamName_create); if (!streamNew) return false; unsigned char* data_stream = new unsigned char[size_stream]; @@ -789,14 +789,11 @@ namespace DocFileFormat if (data_store) memcpy(data_stream, data_store, size_data_store); - streamNew->write(data_stream, size_stream); + streamNew->Write((char*)data_stream, 0, size_stream); RELEASEARRAYOBJECTS(data_store); RELEASEARRAYOBJECTS(data_stream); - streamNew->flush(); - - delete streamNew; delete stream; return true; @@ -953,6 +950,10 @@ namespace DocFileFormat { RELEASEOBJECT( intVector ); } + else + { + intVector->push_back(fcMax); + } return intVector; } @@ -1032,14 +1033,40 @@ namespace DocFileFormat return encodingChars; } } - void WordDocument::CorrectColor(ODRAW::OfficeArtCOLORREF & color) + void WordDocument::CorrectColor(ODRAW::OfficeArtCOLORREF & color, int base_color) { -#if 0 + struct _color + { + _color(unsigned char nR, unsigned char nG, unsigned char nB) + { + SetRGB(nR, nG, nB); + } + _color() {} + int nRGB = 0; + std::wstring sRGB; + int index = -1; + bool bScheme = false; + + void SetRGB(unsigned char nR, unsigned char nG, unsigned char nB) + { + nRGB = (nR << 16) | (nG << 8) | nB; + sRGB = STR::toRGB(nR, nG, nB); + + index = -1; + } + + unsigned char GetB() { return (unsigned char)(nRGB); } + unsigned char GetG() { return (unsigned char)(nRGB >> 8); } + unsigned char GetR() { return (unsigned char)(nRGB >> 16); } + + double opacity = 0; + }; + if (false == color.sColorRGB.empty()) return; if (color.fSysIndex) { - oox::_color sys_color; + _color sys_color; _UINT32 nColorCode = color.index; unsigned short nParameter = (unsigned short)((nColorCode >> 16) & 0x00ff); // the HiByte of nParameter is not zero, an exclusive AND is helping :o @@ -1048,17 +1075,20 @@ namespace DocFileFormat unsigned short nColorIndex = (unsigned short)(nColorCode & 0x00ff); unsigned short nPropColor = 0; - _UINT32 systemColors[25] = + _UINT32 systemColors[25] = { 0xc0c0c0, 0x008080, 0x000080, 0x808080, 0xc0c0c0, 0xffffff, 0x000000, 0x000000, 0x000000, 0xffffff, 0xc0c0c0, 0xc0c0c0, 0x808080, 0x000080, 0xffffff, 0xc0c0c0, 0x808080, 0x808080, 0x000000, 0xc0c0c0, 0xffffff, 0x000000, 0xc0c0c0, 0x000000, 0xffffc0 }; - - if (nColorIndex < 25) + if (nColorIndex == 0xf0) + { + sys_color.SetRGB((unsigned char)(base_color), (unsigned char)(base_color >> 8), (unsigned char)(base_color >> 16)); + } + else if (nColorIndex < 25) { - sys_color.SetRGB((unsigned char)(systemColors[nColorIndex]>>16), (unsigned char)(systemColors[nColorIndex]>>8), (unsigned char)(systemColors[nColorIndex])); + sys_color.SetRGB((unsigned char)(systemColors[nColorIndex] >> 16), (unsigned char)(systemColors[nColorIndex] >> 8), (unsigned char)(systemColors[nColorIndex])); } else return; @@ -1086,7 +1116,7 @@ namespace DocFileFormat BYTE B = static_cast((nInvParameter + (nParameter * sys_color.GetB())) >> 8); sys_color.SetRGB(R, G, B); - }break; + }break; case 0x03: // add grey level RGB(p,p,p) { short nR = (short)sys_color.GetR() + (short)nParameter; @@ -1098,7 +1128,7 @@ namespace DocFileFormat if (nB > 0x00ff) nB = 0x00ff; sys_color.SetRGB((BYTE)nR, (BYTE)nG, (BYTE)nB); - }break; + }break; case 0x04: // substract grey level RGB(p,p,p) { short nR = (short)sys_color.GetR() - (short)nParameter; @@ -1108,7 +1138,7 @@ namespace DocFileFormat if (nG < 0) nG = 0; if (nB < 0) nB = 0; sys_color.SetRGB((BYTE)nR, (BYTE)nG, (BYTE)nB); - } break; + } break; case 0x05: // substract from gray level RGB(p,p,p) { short nR = (short)nParameter - (short)sys_color.GetR(); @@ -1118,7 +1148,7 @@ namespace DocFileFormat if (nG < 0) nG = 0; if (nB < 0) nB = 0; sys_color.SetRGB((BYTE)nR, (BYTE)nG, (BYTE)nB); - }break; + }break; case 0x06: // per component: black if < p, white if >= p { BYTE R = sys_color.GetR() < nParameter ? 0x00 : 0xff; @@ -1126,7 +1156,7 @@ namespace DocFileFormat BYTE B = sys_color.GetB() < nParameter ? 0x00 : 0xff; sys_color.SetRGB(R, G, B); - }break; + }break; } if (nAdditionalFlags & 0x40) // top-bit invert sys_color.SetRGB(sys_color.GetR() ^ 0x80, sys_color.GetG() ^ 0x80, sys_color.GetB() ^ 0x80); @@ -1144,7 +1174,6 @@ namespace DocFileFormat // color.sColorRGB = it->second; // } //} -#endif } } diff --git a/MsBinaryFile/DocFile/WordDocument.h b/MsBinaryFile/DocFile/WordDocument.h index b1d4e443d4e..683a60c7a7d 100644 --- a/MsBinaryFile/DocFile/WordDocument.h +++ b/MsBinaryFile/DocFile/WordDocument.h @@ -60,6 +60,7 @@ #include "IVisitable.h" #include "../../Common/MS-LCID.h" +#include "../../Common/cfcpp/compoundfile.h" namespace CRYPT { @@ -68,11 +69,11 @@ namespace CRYPT namespace DocFileFormat { - class WordDocument: public IVisitable + class WordDocument : public IVisitable { friend class FootnotesMapping; friend class EndnotesMapping; - friend class CommentsMapping; + friend class CommentsMapping; friend class Converter; friend class CharacterPropertiesMapping; friend class DocumentMapping; @@ -93,16 +94,16 @@ namespace DocFileFormat friend class WordprocessingDocument; public: - WordDocument (const std::wstring & tempFolder, const int userLCID); + WordDocument(const std::wstring& tempFolder, const int userLCID); virtual ~WordDocument(); - _UINT32 LoadDocument(const std::wstring & fileName, const std::wstring & password); + _UINT32 LoadDocument(const std::wstring& fileName, const std::wstring& password); int nWordVersion; int nDocumentCodePage; bool bDocumentCodePage; int nFontsCodePage; - + inline StructuredStorageReader* GetStorage() const { return m_pStorage; @@ -114,16 +115,16 @@ namespace DocFileFormat private: bool LoadDocumentFlat(); - bool DecryptOfficeFile (CRYPT::Decryptor* Decryptor); - - bool DecryptStream (std::wstring streamName_open, POLE::Storage * storageIn, std::wstring streamName_create, POLE::Storage * storageOut, CRYPT::Decryptor* Decryptor, bool bDecrypt); - void DecryptStream (int level, std::wstring streamName, POLE::Storage * storageIn, POLE::Storage * storageOut, CRYPT::Decryptor* Decryptor); - - inline OfficeArtContent* GetOfficeArt () + bool DecryptOfficeFile(CRYPT::Decryptor* Decryptor); + + bool DecryptStream(std::wstring streamName_open, POLE::Storage* storageIn, std::wstring streamName_create, std::shared_ptr storageOut, CRYPT::Decryptor* Decryptor, bool bDecrypt); + void DecryptStream(int level, std::wstring streamName, POLE::Storage* storageIn, std::shared_ptr storageOut, CRYPT::Decryptor* Decryptor); + + inline OfficeArtContent* GetOfficeArt() { return officeArtContent; } - + inline int FindFileCharPos(int cp) { if (FIB->m_FibBase.fComplex) @@ -137,41 +138,41 @@ namespace DocFileFormat else { int fc = cp + FIB->m_FibBase.fcMin; - if (fc > FIB->m_FibBase.fcMac) + if (fc > FIB->m_FibBase.fcMac) return -1; return fc; } } - std::vector* GetEncodingChars (int fcStart, int fcEnd); - std::vector* GetChars (int fcStart, int fcEnd, int cp); - - std::vector* GetFileCharacterPositions ( int fcMin, int fcMax ); - std::vector* GetCharacterPropertyExceptions ( int fcMin, int fcMax ); - + std::vector* GetEncodingChars(int fcStart, int fcEnd); + std::vector* GetChars(int fcStart, int fcEnd, int cp); + + std::vector* GetFileCharacterPositions(int fcMin, int fcMax); + std::vector* GetCharacterPropertyExceptions(int fcMin, int fcMax); + void Clear(); MS_LCID_converter m_lcidConverter; - + std::wstring m_sFileName; - std::wstring m_sPassword; + std::wstring m_sPassword; std::wstring m_sTempFolder; std::wstring m_sTempDecryptFileName; int m_nUserLCID; std::wstring m_sXmlApp; std::wstring m_sXmlCore; - POLE::Stream * WordDocumentStream; // The stream "WordDocument" - POLE::Stream * TableStream; // The stream "0Table" or "1Table" - POLE::Stream * DataStream; // The stream called "Data" - StructuredStorageReader * m_pStorage; //POLE::Storage* Storage - - std::vector * Text; // All text of the Word document - std::vector * AllPapxFkps; // A list of all FKPs that contain PAPX - std::vector * AllChpxFkps; // A list of all FKPs that contain CHPX - - std::map * AllPapx; // The value is the PAPX that formats the paragraph. - std::map * AllSepx; // The value is the SEPX that formats the section. - std::vector * AllPapxVector;// A vector to quick find in AllPapx + POLE::Stream* WordDocumentStream; // The stream "WordDocument" + POLE::Stream* TableStream; // The stream "0Table" or "1Table" + POLE::Stream* DataStream; // The stream called "Data" + StructuredStorageReader* m_pStorage; //POLE::Storage* Storage + + std::vector* Text; // All text of the Word document + std::vector* AllPapxFkps; // A list of all FKPs that contain PAPX + std::vector* AllChpxFkps; // A list of all FKPs that contain CHPX + + std::map* AllPapx; // The value is the PAPX that formats the paragraph. + std::map* AllSepx; // The value is the SEPX that formats the section. + std::vector* AllPapxVector;// A vector to quick find in AllPapx std::map PictureBulletsCPsMap; @@ -180,79 +181,79 @@ namespace DocFileFormat struct _bmkStartEnd { int start; - int end; + int end; _UINT32 bookmarkId; }; std::vector<_bmkStartEnd> BookmarkStartEndCPs; std::vector<_bmkStartEnd> BookmarkProtStartEndCPs; std::vector<_bmkStartEnd> AnnotStartEndCPs; - + std::map mapAnnotBookmarks; //id, index std::map mapProtBookmarks; - FileInformationBlock * FIB; - StyleSheet * Styles; // The style sheet of the document - PieceTable * m_PieceTable; // PieceTable PieceTable; - ListFormatOverrideTable * listFormatOverrideTable; // lists and numberings in the document. - HeaderAndFooterTable * headerAndFooterTable; - AnnotationOwnerList * AnnotationOwners; - ListTable * listTable; // list numberings in the document. - WordDocumentProperties * DocProperties; - EncryptionHeader * encryptionHeader; - OfficeArtContent * officeArtContent; // info about the drawings in the document. - - StringTable *RevisionAuthorTable; - StringTable *FontTable; // A list of all font names, used in the doucument - StringTable *BookmarkNames; - StringTable *AutoTextNames; - StringTable *AssocNames; - StringTable *BkmkAnnotNames; - StringTable *Captions; - StringTable *AutoCaptions; - - StringTableEx *BkmkProt; - StringTable *BkmkProtUser; - - Plex *IndividualFootnotesPlex; //A plex of locations of individual footnotes - Plex *FootnoteReferenceCharactersPlex; //A plex of footnote reference characters - - Plex *IndividualEndnotesPlex; //A plex of locations of individual endnotes - Plex *EndnoteReferenceCharactersPlex; //A plex of endnote reference characters - - Plex *HeaderStoriesPlex; //A plex of the header document - Plex *IndividualCommentsPlex; // A plex with all ATRDPre10 structs - - Plex *TextboxIndividualPlex; - Plex *TextboxBreakPlex; // Describes the breaks inside the textbox subdocument - Plex *TextboxBreakPlexHeader; // Describes the breaks inside the header textbox subdocument - - Plex *OutlineListDescriptorPlex; - Plex *OfficeDrawingPlex; - Plex *OfficeDrawingPlexHeader; - - Plex *SectionPlex; - - Plex *BookmarkStartPlex; - Plex *BookmarkEndPlex; - - Plex *AnnotStartPlex; - Plex *AnnotEndPlex; - - Plex *BookmarkProtStartPlex; - Plex *BookmarkProtEndPlex; - - Plex *ListPlex; - Plex *FieldsPlex; - Plex *FootnoteDocumentFieldsPlex; - Plex *EndnoteDocumentFieldsPlex; - Plex *HeadersAndFootersDocumentFieldsPlex; - Plex *AnnotationsFieldsPlex; - Plex *AnnotationsReferencePlex; - Plex *AutoTextPlex; - - - AnnotationReferenceExDescriptors *AnnotationsReferencesEx; -//------------------------------------------------------------------------------ - void CorrectColor(ODRAW::OfficeArtCOLORREF & color); + FileInformationBlock* FIB; + StyleSheet* Styles; // The style sheet of the document + PieceTable* m_PieceTable; // PieceTable PieceTable; + ListFormatOverrideTable* listFormatOverrideTable; // lists and numberings in the document. + HeaderAndFooterTable* headerAndFooterTable; + AnnotationOwnerList* AnnotationOwners; + ListTable* listTable; // list numberings in the document. + WordDocumentProperties* DocProperties; + EncryptionHeader* encryptionHeader; + OfficeArtContent* officeArtContent; // info about the drawings in the document. + + StringTable* RevisionAuthorTable; + StringTable* FontTable; // A list of all font names, used in the doucument + StringTable* BookmarkNames; + StringTable* AutoTextNames; + StringTable* AssocNames; + StringTable* BkmkAnnotNames; + StringTable* Captions; + StringTable* AutoCaptions; + + StringTableEx* BkmkProt; + StringTable* BkmkProtUser; + + Plex* IndividualFootnotesPlex; //A plex of locations of individual footnotes + Plex* FootnoteReferenceCharactersPlex; //A plex of footnote reference characters + + Plex* IndividualEndnotesPlex; //A plex of locations of individual endnotes + Plex* EndnoteReferenceCharactersPlex; //A plex of endnote reference characters + + Plex* HeaderStoriesPlex; //A plex of the header document + Plex* IndividualCommentsPlex; // A plex with all ATRDPre10 structs + + Plex* TextboxIndividualPlex; + Plex* TextboxBreakPlex; // Describes the breaks inside the textbox subdocument + Plex* TextboxBreakPlexHeader; // Describes the breaks inside the header textbox subdocument + + Plex* OutlineListDescriptorPlex; + Plex* OfficeDrawingPlex; + Plex* OfficeDrawingPlexHeader; + + Plex* SectionPlex; + + Plex* BookmarkStartPlex; + Plex* BookmarkEndPlex; + + Plex* AnnotStartPlex; + Plex* AnnotEndPlex; + + Plex* BookmarkProtStartPlex; + Plex* BookmarkProtEndPlex; + + Plex* ListPlex; + Plex* FieldsPlex; + Plex* FootnoteDocumentFieldsPlex; + Plex* EndnoteDocumentFieldsPlex; + Plex* HeadersAndFootersDocumentFieldsPlex; + Plex* AnnotationsFieldsPlex; + Plex* AnnotationsReferencePlex; + Plex* AutoTextPlex; + + + AnnotationReferenceExDescriptors* AnnotationsReferencesEx; + //------------------------------------------------------------------------------ + void CorrectColor(ODRAW::OfficeArtCOLORREF& color, int base_color); }; } diff --git a/MsBinaryFile/PptFile/Drawing/Animations.h b/MsBinaryFile/PptFile/Drawing/Animations.h index be26c76ca0e..f1fe9104c5f 100644 --- a/MsBinaryFile/PptFile/Drawing/Animations.h +++ b/MsBinaryFile/PptFile/Drawing/Animations.h @@ -36,25 +36,25 @@ namespace PPT { enum PointPathType { - etMoveTo = 0, - etLineTo = 1, - etCurveTo = 2, - etCloseLoop = 3, - etHorzTo = 4, - etVertTo = 5, - etEnd = 6 + etMoveTo = 0, + etLineTo = 1, + etCurveTo = 2, + etCloseLoop = 3, + etHorzTo = 4, + etVertTo = 5, + etEnd = 6 // add arc, c3, c2 ???? }; enum EffectType { - FadeInType = 1, - FadeExitType = 2, - EmphasisEffect = 3, - MotionEffect = 4, - VerbEffect = 5, - MediaCallEffect = 6 + FadeInType = 1, + FadeExitType = 2, + EmphasisEffect = 3, + MotionEffect = 4, + VerbEffect = 5, + MediaCallEffect = 6 }; class CMotionPath @@ -65,157 +65,157 @@ namespace PPT { int Type; - double X [ 4 ]; - double Y [ 4 ]; + double X[4]; + double Y[4]; }; public: -// inline bool FromStr (const std::wstring& Str) -// { -// m_Points.clear(); + // inline bool FromStr (const std::wstring& Str) + // { + // m_Points.clear(); -// int To = 0; -// std::wstring Tokens = _T(" mlczevh"); + // int To = 0; + // std::wstring Tokens = L" mlczevh"); -// double dEndX = 0.0; -// double dEndY = 0.0; + // double dEndX = 0.0; + // double dEndY = 0.0; -// PathPoint oPoint; + // PathPoint oPoint; -// for ( int i = 0; i < Str.length (); ++i ) -// { -// if ( _T('m') == Str [ i ] ) oPoint.Type = etMoveTo; -// else if ( _T('l') == Str [ i ] ) oPoint.Type = etLineTo; -// else if ( _T('c') == Str [ i ] ) oPoint.Type = etCurveTo; -// else if ( _T('z') == Str [ i ] ) oPoint.Type = etCloseLoop; // This action requires no points. -// else if ( _T('e') == Str [ i ] ) oPoint.Type = etEnd; // This action requires no points. -// else if ( _T('h') == Str [ i ] ) oPoint.Type = etHorzTo; // -// else if ( _T('v') == Str [ i ] ) oPoint.Type = etVertTo; // -// else if ( _T('M') == Str [ i ] ) oPoint.Type = etMoveTo; -// else if ( _T('L') == Str [ i ] ) oPoint.Type = etLineTo; -// else if ( _T('C') == Str [ i ] ) oPoint.Type = etCurveTo; -// else if ( _T('Z') == Str [ i ] ) oPoint.Type = etCloseLoop; -// else if ( _T('E') == Str [ i ] ) oPoint.Type = etEnd; -// else continue; + // for ( int i = 0; i < Str.length (); ++i ) + // { + // if ( _T('m') == Str [ i ] ) oPoint.Type = etMoveTo; + // else if ( _T('l') == Str [ i ] ) oPoint.Type = etLineTo; + // else if ( _T('c') == Str [ i ] ) oPoint.Type = etCurveTo; + // else if ( _T('z') == Str [ i ] ) oPoint.Type = etCloseLoop; // This action requires no points. + // else if ( _T('e') == Str [ i ] ) oPoint.Type = etEnd; // This action requires no points. + // else if ( _T('h') == Str [ i ] ) oPoint.Type = etHorzTo; // + // else if ( _T('v') == Str [ i ] ) oPoint.Type = etVertTo; // + // else if ( _T('M') == Str [ i ] ) oPoint.Type = etMoveTo; + // else if ( _T('L') == Str [ i ] ) oPoint.Type = etLineTo; + // else if ( _T('C') == Str [ i ] ) oPoint.Type = etCurveTo; + // else if ( _T('Z') == Str [ i ] ) oPoint.Type = etCloseLoop; + // else if ( _T('E') == Str [ i ] ) oPoint.Type = etEnd; + // else continue; -// To = i + 1; + // To = i + 1; -// if ( etMoveTo == oPoint.Type ) -// { -// oPoint.X [ 0 ] = _tstof ( Str.Tokenize ( Tokens, To ) ); if ( -1 == To ) break; -// oPoint.Y [ 0 ] = _tstof ( Str.Tokenize ( Tokens, To ) ); if ( -1 == To ) break; - -// dEndX = oPoint.X [ 0 ]; -// dEndY = oPoint.Y [ 0 ]; + // if ( etMoveTo == oPoint.Type ) + // { + // oPoint.X [ 0 ] = _tstof ( Str.Tokenize ( Tokens, To ) ); if ( -1 == To ) break; + // oPoint.Y [ 0 ] = _tstof ( Str.Tokenize ( Tokens, To ) ); if ( -1 == To ) break; + + // dEndX = oPoint.X [ 0 ]; + // dEndY = oPoint.Y [ 0 ]; -// continue; -// } + // continue; + // } -// if ( etLineTo == oPoint.Type ) -// { -// oPoint.X [ 0 ] = dEndX; -// oPoint.Y [ 0 ] = dEndY; + // if ( etLineTo == oPoint.Type ) + // { + // oPoint.X [ 0 ] = dEndX; + // oPoint.Y [ 0 ] = dEndY; -// oPoint.X [ 1 ] = _tstof ( Str.Tokenize ( Tokens, To ) ); if ( -1 == To ) break; -// oPoint.Y [ 1 ] = _tstof ( Str.Tokenize ( Tokens, To ) ); if ( -1 == To ) break; + // oPoint.X [ 1 ] = _tstof ( Str.Tokenize ( Tokens, To ) ); if ( -1 == To ) break; + // oPoint.Y [ 1 ] = _tstof ( Str.Tokenize ( Tokens, To ) ); if ( -1 == To ) break; -// dEndX = oPoint.X [ 1 ]; -// dEndY = oPoint.Y [ 1 ]; -// } + // dEndX = oPoint.X [ 1 ]; + // dEndY = oPoint.Y [ 1 ]; + // } -// if ( etHorzTo == oPoint.Type ) -// { -// oPoint.Type = etLineTo; + // if ( etHorzTo == oPoint.Type ) + // { + // oPoint.Type = etLineTo; -// oPoint.X [ 0 ] = dEndX; -// oPoint.Y [ 0 ] = dEndY; + // oPoint.X [ 0 ] = dEndX; + // oPoint.Y [ 0 ] = dEndY; -// oPoint.X [ 1 ] = _tstof ( Str.Tokenize ( Tokens, To ) ); if ( -1 == To ) break; -// oPoint.Y [ 1 ] = oPoint.Y [ 0 ]; + // oPoint.X [ 1 ] = _tstof ( Str.Tokenize ( Tokens, To ) ); if ( -1 == To ) break; + // oPoint.Y [ 1 ] = oPoint.Y [ 0 ]; -// dEndX = oPoint.X [ 1 ]; -// dEndY = oPoint.Y [ 1 ]; -// } + // dEndX = oPoint.X [ 1 ]; + // dEndY = oPoint.Y [ 1 ]; + // } -// if ( etVertTo == oPoint.Type ) -// { -// oPoint.Type = etLineTo; + // if ( etVertTo == oPoint.Type ) + // { + // oPoint.Type = etLineTo; -// oPoint.X [ 0 ] = dEndX; -// oPoint.Y [ 0 ] = dEndY; + // oPoint.X [ 0 ] = dEndX; + // oPoint.Y [ 0 ] = dEndY; -// oPoint.X [ 1 ] = oPoint.X [ 0 ]; -// oPoint.Y [ 1 ] = _tstof ( Str.Tokenize ( Tokens, To ) ); if ( -1 == To ) break; + // oPoint.X [ 1 ] = oPoint.X [ 0 ]; + // oPoint.Y [ 1 ] = _tstof ( Str.Tokenize ( Tokens, To ) ); if ( -1 == To ) break; -// dEndX = oPoint.X [ 1 ]; -// dEndY = oPoint.Y [ 1 ]; -// } + // dEndX = oPoint.X [ 1 ]; + // dEndY = oPoint.Y [ 1 ]; + // } -// if ( etCurveTo == oPoint.Type ) -// { -// oPoint.X [ 0 ] = dEndX; -// oPoint.Y [ 0 ] = dEndY; + // if ( etCurveTo == oPoint.Type ) + // { + // oPoint.X [ 0 ] = dEndX; + // oPoint.Y [ 0 ] = dEndY; -// oPoint.X [ 1 ] = _tstof ( Str.Tokenize ( Tokens, To ) ); if ( -1 == To ) break; -// oPoint.Y [ 1 ] = _tstof ( Str.Tokenize ( Tokens, To ) ); if ( -1 == To ) break; + // oPoint.X [ 1 ] = _tstof ( Str.Tokenize ( Tokens, To ) ); if ( -1 == To ) break; + // oPoint.Y [ 1 ] = _tstof ( Str.Tokenize ( Tokens, To ) ); if ( -1 == To ) break; -// oPoint.X [ 2 ] = _tstof ( Str.Tokenize ( Tokens, To ) ); if ( -1 == To ) break; -// oPoint.Y [ 2 ] = _tstof ( Str.Tokenize ( Tokens, To ) ); if ( -1 == To ) break; + // oPoint.X [ 2 ] = _tstof ( Str.Tokenize ( Tokens, To ) ); if ( -1 == To ) break; + // oPoint.Y [ 2 ] = _tstof ( Str.Tokenize ( Tokens, To ) ); if ( -1 == To ) break; -// oPoint.X [ 3 ] = _tstof ( Str.Tokenize ( Tokens, To ) ); if ( -1 == To ) break; -// oPoint.Y [ 3 ] = _tstof ( Str.Tokenize ( Tokens, To ) ); if ( -1 == To ) break; + // oPoint.X [ 3 ] = _tstof ( Str.Tokenize ( Tokens, To ) ); if ( -1 == To ) break; + // oPoint.Y [ 3 ] = _tstof ( Str.Tokenize ( Tokens, To ) ); if ( -1 == To ) break; -// dEndX = oPoint.X [ 3 ]; -// dEndY = oPoint.Y [ 3 ]; -// } + // dEndX = oPoint.X [ 3 ]; + // dEndY = oPoint.Y [ 3 ]; + // } -// m_Points.push_back ( oPoint ); -// } + // m_Points.push_back ( oPoint ); + // } -// return ( m_Points.size() >= 2 ); -// } + // return ( m_Points.size() >= 2 ); + // } -// inline std::wstring ToXml (double dW, double dH) -// { -// std::wstring Xml; + // inline std::wstring ToXml (double dW, double dH) + // { + // std::wstring Xml; -// for ( long i = 0; i < (long)m_Points.size(); ++i ) -// { -// std::wstring Fmt; - -// if ( etMoveTo == m_Points [ i ].Type ) -// { -// Fmt.Format ( _T(""), -// m_Points [ i ].X [ 0 ] * dW, m_Points [ i ].Y [ 0 ] * dH ); -// } + // for ( long i = 0; i < (long)m_Points.size(); ++i ) + // { + // std::wstring Fmt; + + // if ( etMoveTo == m_Points [ i ].Type ) + // { + // Fmt.Format ( L""), + // m_Points [ i ].X [ 0 ] * dW, m_Points [ i ].Y [ 0 ] * dH ); + // } -// if ( etLineTo == m_Points [ i ].Type ) -// { -// Fmt.Format ( _T(""), -// m_Points [ i ].X [ 0 ] * dW, m_Points [ i ].Y [ 0 ] * dH, -// m_Points [ i ].X [ 1 ] * dW, m_Points [ i ].Y [ 1 ] * dH ); -// } + // if ( etLineTo == m_Points [ i ].Type ) + // { + // Fmt.Format ( L""), + // m_Points [ i ].X [ 0 ] * dW, m_Points [ i ].Y [ 0 ] * dH, + // m_Points [ i ].X [ 1 ] * dW, m_Points [ i ].Y [ 1 ] * dH ); + // } -// if ( etCurveTo == m_Points [ i ].Type ) -// { -// Fmt.Format ( _T(""), -// m_Points [ i ].X [ 0 ] * dW, m_Points [ i ].Y [ 0 ] * dH, -// m_Points [ i ].X [ 1 ] * dW, m_Points [ i ].Y [ 1 ] * dH, -// m_Points [ i ].X [ 2 ] * dW, m_Points [ i ].Y [ 2 ] * dH, -// m_Points [ i ].X [ 3 ] * dW, m_Points [ i ].Y [ 3 ] * dH ); -// } + // if ( etCurveTo == m_Points [ i ].Type ) + // { + // Fmt.Format ( L""), + // m_Points [ i ].X [ 0 ] * dW, m_Points [ i ].Y [ 0 ] * dH, + // m_Points [ i ].X [ 1 ] * dW, m_Points [ i ].Y [ 1 ] * dH, + // m_Points [ i ].X [ 2 ] * dW, m_Points [ i ].Y [ 2 ] * dH, + // m_Points [ i ].X [ 3 ] * dW, m_Points [ i ].Y [ 3 ] * dH ); + // } -// Xml += Fmt; -// } + // Xml += Fmt; + // } -// return Xml; -// } + // return Xml; + // } - inline std::wstring ToStr () + inline std::wstring ToStr() { - return _T(""); + return L""; } private: @@ -228,35 +228,35 @@ namespace PPT public: CAnimationSimple() { - m_nRefID = -1; + m_nRefID = -1; - m_nBeginTime = 0; - m_nDuration = 0; + m_nBeginTime = 0; + m_nDuration = 0; - m_nEffectID = 0; - m_nEffectDir = 0; - m_nEffectType = 0; - m_nEffectNodeType = 0; + m_nEffectID = 0; + m_nEffectDir = 0; + m_nEffectType = 0; + m_nEffectNodeType = 0; - m_dSX = 1.0; - m_dSY = 1.0; + m_dSX = 1.0; + m_dSY = 1.0; - m_dRotateAngle = 0.0; + m_dRotateAngle = 0.0; - m_dTransparency = 1.0; + m_dTransparency = 1.0; - m_nSchemeColor = 0; - m_nColorTo = 0; + m_nSchemeColor = 0; + m_nColorTo = 0; - m_dTimeAccel = 0.0; - m_dTimeDecel = 0.0; + m_dTimeAccel = 0.0; + m_dTimeDecel = 0.0; - m_bIgnoreShape = false; - m_nTextSequence = -1; - m_bRemoveEmptyBlocks = false; + m_bIgnoreShape = false; + m_nTextSequence = -1; + m_bRemoveEmptyBlocks = false; - m_nMediaCMD = -1; + m_nMediaCMD = -1; } public: @@ -308,8 +308,8 @@ namespace PPT } CAnimationInfo& operator=(const CAnimationInfo& oSrc) { - m_dSlideWidth = oSrc.m_dSlideWidth; - m_dSlideHeight = oSrc.m_dSlideHeight; + m_dSlideWidth = oSrc.m_dSlideWidth; + m_dSlideHeight = oSrc.m_dSlideHeight; m_arAnimations.insert(m_arAnimations.end(), oSrc.m_arAnimations.begin(), oSrc.m_arAnimations.end()); return *this; @@ -323,133 +323,133 @@ namespace PPT } -// std::wstring ToXml(const double& dStartTime, const double& dEndTime, bool bIgnore = false) -// { -// std::wstring baseXML; -// baseXML.Format ( _T(""), m_dSlideWidth, m_dSlideHeight ); - -// std::wstring Source; - -// for ( long i = 0; i < (long)m_arAnimations.size(); ++i ) -// { -// CAnimationSimple* pEffect = &m_arAnimations[i]; -// if (NULL==pEffect) -// continue; - -// if (bIgnore) -// { -// if (pEffect->m_bIgnoreShape) -// continue; -// } - -// double dEffectBegin = dStartTime + pEffect->m_nBeginTime; - -// m_oQuery.clear (); - -// m_oQuery.push_back ( _T(" id = '") + PPT::ToString (pEffect->m_nEffectID) + _T("' ")); -// m_oQuery.push_back ( _T(" type = '") + PPT::ToString (pEffect->m_nEffectType) + _T("' ")); -// m_oQuery.push_back ( _T(" dir = '") + PPT::ToString (pEffect->m_nEffectDir) + _T("' ")); - -// m_oQuery.push_back ( _T(" begin = '") + PPT::ToString (dEffectBegin) + _T("' ")); -// m_oQuery.push_back ( _T(" dur = '") + PPT::ToString (pEffect->m_nDuration) + _T("' ")); -// m_oQuery.push_back ( _T(" accel = '") + PPT::ToString (pEffect->m_dTimeAccel) + _T("' ")); -// m_oQuery.push_back ( _T(" decel = '") + PPT::ToString (pEffect->m_dTimeDecel) + _T("' ")); - -// m_oQuery.push_back ( _T(" sx = '") + PPT::ToString (pEffect->m_dSX) + _T("' ")); -// m_oQuery.push_back ( _T(" sy = '") + PPT::ToString (pEffect->m_dSY) + _T("' ")); -// m_oQuery.push_back ( _T(" alpha = '") + PPT::ToString (pEffect->m_dTransparency) + _T("' ")); - -// m_oQuery.push_back ( _T(" angle = '") + PPT::ToString (pEffect->m_dRotateAngle) + _T("' ")); -// m_oQuery.push_back ( _T(" color = '") + PPT::ToString (pEffect->m_nColorTo) + _T("' ")); - -// m_oQuery.push_back ( _T(" block = '") + PPT::ToString (pEffect->m_nTextSequence) + _T("' ")); -// m_oQuery.push_back ( _T(" removeemptyblocks = '") + PPT::ToString (pEffect->m_bRemoveEmptyBlocks) + _T("' ")); - -// std::wstring Effect; - -// if (MotionEffect == pEffect->m_nEffectType || pEffect->m_MotionPath.length()) -// { -// CMotionPath oPath; -// if ( oPath.FromStr ( pEffect->m_MotionPath ) ) -// { -// Effect.Format ( _T("%s"), FormatXml (), oPath.ToXml(1.0,1.0)); -// Source += Effect; -// } -// } - -// if ( FadeInType == pEffect->m_nEffectType ) -// { -// Effect.Format ( _T(""), FormatXml ()); -// Source += Effect; -// } - -// if ( FadeExitType == pEffect->m_nEffectType ) -// { -// Effect.Format ( _T(""), FormatXml ()); -// Source += Effect; -// } - -// if (EmphasisEffect == pEffect->m_nEffectType ) -// { -// if (6 == pEffect->m_nEffectID) // GrowAndShrink Effect -// { -// Effect.Format ( _T(""), FormatXml ()); -// } -// else if (8 == pEffect->m_nEffectID || 32 == pEffect->m_nEffectID) // Spin Effect || Teeter Effect -// { -// Effect.Format ( _T(""), FormatXml ()); -// } -// else if (9 == pEffect->m_nEffectID || 35 == pEffect->m_nEffectID) // Blink - 36 - мигание -// { -// Effect.Format ( _T(""), FormatXml ()); -// } -// else if (26 == pEffect->m_nEffectID) // FlashBulb Effect ( Пульсация ) -// { -// Effect.Format ( _T(""), FormatXml ()); -// Source += Effect; - -// Effect.Format ( _T(""), FormatXml ()); -// Source += Effect; - -// continue; -// } -// else if (27 == pEffect->m_nEffectID // Flicker (÷ветовая пульсация) -// || 1 == pEffect->m_nEffectID // ChangeFillColor - fill color -// || 3 == pEffect->m_nEffectID // ChangeFillColor - font color -// || 7 == pEffect->m_nEffectID // ChangeFillColor - fill lines -// || 19 == pEffect->m_nEffectID) // ColorBlend - object fill color -// { -// Effect.Format ( _T(""), FormatXml ()); -// } -// else -// { -// Effect.Format ( _T(""), FormatXml ()); -// } - -// Source += Effect; -// } - -// if (MediaCallEffect == pEffect->m_nEffectType ) -// { -// std::wstring sTime; -// sTime.Format(_T(" begin='%f' dur='%f' accel='%f' decel='%f' "), dStartTime + pEffect->m_nBeginTime, pEffect->m_nDuration, pEffect->m_dTimeAccel, pEffect->m_dTimeDecel); - -// Effect.Format(_T(""), pEffect->m_nEffectID, sTime, pEffect->m_nMediaCMD); -// Source += Effect; -// } -// } - -// if (bIgnore) -// { -// if (0 == Source.length()) -// return _T(""); -// } - -// baseXML += Source; -// baseXML += std::wstring(_T("")); - -// return baseXML; -// } + // std::wstring ToXml(const double& dStartTime, const double& dEndTime, bool bIgnore = false) + // { + // std::wstring baseXML; + // baseXML.Format ( L""), m_dSlideWidth, m_dSlideHeight ); + + // std::wstring Source; + + // for ( long i = 0; i < (long)m_arAnimations.size(); ++i ) + // { + // CAnimationSimple* pEffect = &m_arAnimations[i]; + // if (NULL==pEffect) + // continue; + + // if (bIgnore) + // { + // if (pEffect->m_bIgnoreShape) + // continue; + // } + + // double dEffectBegin = dStartTime + pEffect->m_nBeginTime; + + // m_oQuery.clear (); + + // m_oQuery.push_back ( L" id = '") + PPT::ToString (pEffect->m_nEffectID) + L"' ")); + // m_oQuery.push_back ( L" type = '") + PPT::ToString (pEffect->m_nEffectType) + L"' ")); + // m_oQuery.push_back ( L" dir = '") + PPT::ToString (pEffect->m_nEffectDir) + L"' ")); + + // m_oQuery.push_back ( L" begin = '") + PPT::ToString (dEffectBegin) + L"' ")); + // m_oQuery.push_back ( L" dur = '") + PPT::ToString (pEffect->m_nDuration) + L"' ")); + // m_oQuery.push_back ( L" accel = '") + PPT::ToString (pEffect->m_dTimeAccel) + L"' ")); + // m_oQuery.push_back ( L" decel = '") + PPT::ToString (pEffect->m_dTimeDecel) + L"' ")); + + // m_oQuery.push_back ( L" sx = '") + PPT::ToString (pEffect->m_dSX) + L"' ")); + // m_oQuery.push_back ( L" sy = '") + PPT::ToString (pEffect->m_dSY) + L"' ")); + // m_oQuery.push_back ( L" alpha = '") + PPT::ToString (pEffect->m_dTransparency) + L"' ")); + + // m_oQuery.push_back ( L" angle = '") + PPT::ToString (pEffect->m_dRotateAngle) + L"' ")); + // m_oQuery.push_back ( L" color = '") + PPT::ToString (pEffect->m_nColorTo) + L"' ")); + + // m_oQuery.push_back ( L" block = '") + PPT::ToString (pEffect->m_nTextSequence) + L"' ")); + // m_oQuery.push_back ( L" removeemptyblocks = '") + PPT::ToString (pEffect->m_bRemoveEmptyBlocks) + L"' ")); + + // std::wstring Effect; + + // if (MotionEffect == pEffect->m_nEffectType || pEffect->m_MotionPath.length()) + // { + // CMotionPath oPath; + // if ( oPath.FromStr ( pEffect->m_MotionPath ) ) + // { + // Effect.Format ( L"%s"), FormatXml (), oPath.ToXml(1.0,1.0)); + // Source += Effect; + // } + // } + + // if ( FadeInType == pEffect->m_nEffectType ) + // { + // Effect.Format ( L""), FormatXml ()); + // Source += Effect; + // } + + // if ( FadeExitType == pEffect->m_nEffectType ) + // { + // Effect.Format ( L""), FormatXml ()); + // Source += Effect; + // } + + // if (EmphasisEffect == pEffect->m_nEffectType ) + // { + // if (6 == pEffect->m_nEffectID) // GrowAndShrink Effect + // { + // Effect.Format ( L""), FormatXml ()); + // } + // else if (8 == pEffect->m_nEffectID || 32 == pEffect->m_nEffectID) // Spin Effect || Teeter Effect + // { + // Effect.Format ( L""), FormatXml ()); + // } + // else if (9 == pEffect->m_nEffectID || 35 == pEffect->m_nEffectID) // Blink - 36 - мигание + // { + // Effect.Format ( L""), FormatXml ()); + // } + // else if (26 == pEffect->m_nEffectID) // FlashBulb Effect ( Пульсация ) + // { + // Effect.Format ( L""), FormatXml ()); + // Source += Effect; + + // Effect.Format ( L""), FormatXml ()); + // Source += Effect; + + // continue; + // } + // else if (27 == pEffect->m_nEffectID // Flicker (÷ветовая пульсация) + // || 1 == pEffect->m_nEffectID // ChangeFillColor - fill color + // || 3 == pEffect->m_nEffectID // ChangeFillColor - font color + // || 7 == pEffect->m_nEffectID // ChangeFillColor - fill lines + // || 19 == pEffect->m_nEffectID) // ColorBlend - object fill color + // { + // Effect.Format ( L""), FormatXml ()); + // } + // else + // { + // Effect.Format ( L""), FormatXml ()); + // } + + // Source += Effect; + // } + + // if (MediaCallEffect == pEffect->m_nEffectType ) + // { + // std::wstring sTime; + // sTime.Format(L" begin='%f' dur='%f' accel='%f' decel='%f' "), dStartTime + pEffect->m_nBeginTime, pEffect->m_nDuration, pEffect->m_dTimeAccel, pEffect->m_dTimeDecel); + + // Effect.Format(L""), pEffect->m_nEffectID, sTime, pEffect->m_nMediaCMD); + // Source += Effect; + // } + // } + + // if (bIgnore) + // { + // if (0 == Source.length()) + // return L""); + // } + + // baseXML += Source; + // baseXML += std::wstring(L"")); + + // return baseXML; + // } }; } diff --git a/MsBinaryFile/PptFile/Drawing/Attributes.h b/MsBinaryFile/PptFile/Drawing/Attributes.h index 12ff5a7f356..7029dedc8d3 100644 --- a/MsBinaryFile/PptFile/Drawing/Attributes.h +++ b/MsBinaryFile/PptFile/Drawing/Attributes.h @@ -44,24 +44,24 @@ #include "../../../OOXML/Base/Unit.h" #include -static void ReplaceAll(std::wstring & str, const std::wstring& from, const std::wstring& to) +static void ReplaceAll(std::wstring& str, const std::wstring& from, const std::wstring& to) { size_t start_pos = 0; - while((start_pos = str.find(from, start_pos)) != std::wstring::npos) + while ((start_pos = str.find(from, start_pos)) != std::wstring::npos) { str.replace(start_pos, from.length(), to); start_pos += to.length(); } } -static void CorrectXmlString2(std::wstring & strText) +static void CorrectXmlString2(std::wstring& strText) { - ReplaceAll(strText, L"'", L"'"); - ReplaceAll(strText, L"<", L"<"); - ReplaceAll(strText, L">", L">"); - ReplaceAll(strText, L""", L"\""); - ReplaceAll(strText, L"&", L"&"); + ReplaceAll(strText, L"'", L"'"); + ReplaceAll(strText, L"<", L"<"); + ReplaceAll(strText, L">", L">"); + ReplaceAll(strText, L""", L"\""); + ReplaceAll(strText, L"&", L"&"); } -static void CorrectXmlString(std::wstring & strText) +static void CorrectXmlString(std::wstring& strText) { strText = XmlUtils::EncodeXmlString(strText); } @@ -72,1138 +72,1166 @@ static inline std::wstring BoolToString(bool bValue) namespace PPT { -class CExFilesInfo -{ -public: - enum ExFilesType - { - eftNone = 0, - eftVideo = 1, - eftAudio = 2, - eftHyperlink = 3, - eftObject = 4, - eftSlide = 5, - eftFile = 6 - }; - - ExFilesType m_type = eftNone; - _UINT32 m_dwID = 0; - std::wstring m_strFilePath = L""; - std::wstring m_name; - - // clip - double m_dStartTime = 0.0; - double m_dEndTime = 1.0; - - // loop - bool m_bLoop = false; - bool m_fNarration = false; // isNarration pptx - bool m_fRewind = false; - - CExFilesInfo() + class CExFilesInfo { - } - CExFilesInfo(const CExFilesInfo& oSrc) - { - *this = oSrc; - } - - static int GetSlideNumber(const std::wstring &str) - { - std::wstring sldHeader = L"Slide "; - int strIter = (int)str.find(sldHeader); - if (strIter != -1) - { - std::wstring sNum(str.begin() + sldHeader.size() + strIter, str.end()); - int num = -1; - try { - num = std::stoi(sNum); - if (num > 0 && num < 256) - return num; - } catch (...) { - - } + public: + enum ExFilesType + { + eftNone = 0, + eftVideo = 1, + eftAudio = 2, + eftHyperlink = 3, + eftObject = 4, + eftSlide = 5, + eftFile = 6, + eftOleObject = 7 + }; + + ExFilesType m_type = ExFilesType::eftNone; + + _UINT32 m_dwID = 0; + std::wstring m_strFilePath; + std::wstring m_strFileExt; + + std::wstring m_name; + std::wstring m_progName; + + // clip + double m_dStartTime = 0.0; + double m_dEndTime = 1.0; + + // loop + bool m_bLoop = false; + bool m_fNarration = false; // isNarration pptx + bool m_fRewind = false; + + CExFilesInfo() + { + } + CExFilesInfo(const CExFilesInfo& oSrc) + { + *this = oSrc; } - // Second chance - std::vector splited; - boost::split(splited, str, boost::is_any_of(L",")); - if (splited.size() == 3) + static int GetSlideNumber(const std::wstring& str) { - try { - int num = std::stoi(splited[1]); - if (num > 0 && num < 256) - return num; - } catch (...) { + std::wstring sldHeader = L"Slide "; + int strIter = (int)str.find(sldHeader); + if (strIter != -1) + { + std::wstring sNum(str.begin() + sldHeader.size() + strIter, str.end()); + int num = -1; + try { + num = std::stoi(sNum); + if (num > 0 && num < 256) + return num; + } + catch (...) { + + } + } + // Second chance + std::vector splited; + boost::split(splited, str, boost::is_any_of(L",")); + if (splited.size() == 3) + { + try { + int num = std::stoi(splited[1]); + if (num > 0 && num < 256) + return num; + } + catch (...) { + + } } + return -1; } - return -1; - } - static bool isHTTPLink(const std::wstring &str) - { - int iter1 = (int)str.find(L"http://"); - int iter2 = (int)str.find(L"https://"); - return iter1 != -1 || iter2 != -1; - } - static bool isAudioLink(const std::wstring &str) - { - int iter1 = (int)str.find(L".mp3"); - int iter2 = (int)str.find(L".wav"); - int iter3 = (int)str.find(L".waw"); - return iter1 != -1 || iter2 != -1 || iter3 != -1; - } -}; - -class CExMedia -{ -public: - std::wstring m_strPresentationDirectory; - - std::vector m_arVideos; - std::vector m_arImages; - std::vector m_arAudios; - std::vector m_arHyperlinks; - std::vector m_arSlides; - std::vector m_arFiles; - - std::vector m_arAudioCollection; + static bool isHTTPLink(const std::wstring& str) + { + int iter1 = (int)str.find(L"http://"); + int iter2 = (int)str.find(L"https://"); + return iter1 != -1 || iter2 != -1; + } + static bool isAudioLink(const std::wstring& str) + { + int iter1 = (int)str.find(L".mp3"); + int iter2 = (int)str.find(L".wav"); + int iter3 = (int)str.find(L".waw"); + return iter1 != -1 || iter2 != -1 || iter3 != -1; + } + }; - void Clear() + class CExMedia { - m_arVideos.clear(); - m_arImages.clear(); - m_arAudios.clear(); - m_arAudioCollection.clear(); - } + public: + std::wstring m_strPresentationDirectory; - CExMedia() : m_arVideos(), m_arImages(), m_arAudios() - { - } + std::vector m_arVideos; + std::vector m_arImages; + std::vector m_arAudios; + std::vector m_arHyperlinks; + std::vector m_arSlides; + std::vector m_arFiles; + std::vector m_arOleObjects; - CExMedia(const CExMedia& oSrc) - { - *this = oSrc; - } + std::vector m_arAudioCollection; - CExMedia& operator=(const CExMedia& oSrc) - { - m_strPresentationDirectory = oSrc.m_strPresentationDirectory; + void Clear() + { + m_arVideos.clear(); + m_arImages.clear(); + m_arAudios.clear(); + m_arAudioCollection.clear(); + m_arOleObjects.clear(); + } - for (size_t i=0; i < oSrc.m_arVideos.size(); i++) - m_arVideos.push_back(oSrc.m_arVideos[i]); - for (size_t i=0; i < oSrc.m_arVideos.size(); i++) - m_arImages.push_back(oSrc.m_arImages[i]); - for (size_t i=0; i < oSrc.m_arVideos.size(); i++) - m_arAudios.push_back(oSrc.m_arAudios[i]); + CExMedia() + { + } - return *this; - } - CExFilesInfo* LockHyperlink(_UINT32 dwID) - { - size_t nCount = m_arHyperlinks.size(); - for (size_t i = 0; i < nCount; ++i) + CExMedia(const CExMedia& oSrc) { - if (dwID == m_arHyperlinks[i].m_dwID) - { - return &m_arHyperlinks[i]; - } + *this = oSrc; } - return NULL; - } - CExFilesInfo* LockSlide(_UINT32 dwID) - { - size_t nCount = m_arSlides.size(); - for (size_t i = 0; i < nCount; ++i) + CExMedia& operator=(const CExMedia& oSrc) + { + m_strPresentationDirectory = oSrc.m_strPresentationDirectory; + + for (size_t i = 0; i < oSrc.m_arVideos.size(); i++) + m_arVideos.push_back(oSrc.m_arVideos[i]); + for (size_t i = 0; i < oSrc.m_arVideos.size(); i++) + m_arImages.push_back(oSrc.m_arImages[i]); + for (size_t i = 0; i < oSrc.m_arVideos.size(); i++) + m_arAudios.push_back(oSrc.m_arAudios[i]); + for (size_t i = 0; i < oSrc.m_arOleObjects.size(); i++) + m_arOleObjects.push_back(oSrc.m_arOleObjects[i]); + + return *this; + } + CExFilesInfo* LockHyperlink(_UINT32 dwID) { - if (dwID == m_arSlides[i].m_dwID) + size_t nCount = m_arHyperlinks.size(); + for (size_t i = 0; i < nCount; ++i) { - return &m_arSlides[i]; + if (dwID == m_arHyperlinks[i].m_dwID) + { + return &m_arHyperlinks[i]; + } } - } - return NULL; - } - CExFilesInfo* LockVideo(_UINT32 dwID) - { - size_t nCount = m_arVideos.size(); - for (size_t i = 0; i < nCount; ++i) + return NULL; + } + CExFilesInfo* LockSlide(_UINT32 dwID) { - if (dwID == m_arVideos[i].m_dwID) + size_t nCount = m_arSlides.size(); + for (size_t i = 0; i < nCount; ++i) { - return &m_arVideos[i]; + if (dwID == m_arSlides[i].m_dwID) + { + return &m_arSlides[i]; + } } - } - return NULL; - } - CExFilesInfo* LockImage(_UINT32 dwID) - { - size_t nCount = m_arImages.size(); - for (size_t i = 0; i < nCount; ++i) + return NULL; + } + CExFilesInfo* LockVideo(_UINT32 dwID) { - if (dwID == m_arImages[i].m_dwID) + size_t nCount = m_arVideos.size(); + for (size_t i = 0; i < nCount; ++i) { - return &m_arImages[i]; + if (dwID == m_arVideos[i].m_dwID) + { + return &m_arVideos[i]; + } } - } - return NULL; - } - CExFilesInfo* LockAudio(_UINT32 dwID) - { - size_t nCount = m_arAudios.size(); - for (size_t i = 0; i < nCount; ++i) + return NULL; + } + CExFilesInfo* LockImage(_UINT32 dwID) { - if (dwID == m_arAudios[i].m_dwID) + size_t nCount = m_arImages.size(); + for (size_t i = 0; i < nCount; ++i) { - return &m_arAudios[i]; + if (dwID == m_arImages[i].m_dwID) + { + return &m_arImages[i]; + } } - } - return NULL; - } - CExFilesInfo* LockAudioFromCollection(_UINT32 dwID) - { - size_t nCount = m_arAudioCollection.size(); - for (size_t i = 0; i < nCount; ++i) + return NULL; + } + CExFilesInfo* LockAudio(_UINT32 dwID) { - if (dwID == m_arAudioCollection[i].m_dwID) + size_t nCount = m_arAudios.size(); + for (size_t i = 0; i < nCount; ++i) { - return &m_arAudioCollection[i]; + if (dwID == m_arAudios[i].m_dwID) + { + return &m_arAudios[i]; + } } - } - - return NULL; - } - CExFilesInfo* Lock(_UINT32 dwID, CExFilesInfo::ExFilesType& eType) - { - CExFilesInfo* pInfo = NULL; - - pInfo = LockHyperlink(dwID); - if (NULL != pInfo) - { - eType = CExFilesInfo::eftHyperlink; - return pInfo; + return NULL; } - pInfo = LockVideo(dwID); - if (NULL != pInfo) + CExFilesInfo* LockOleObject(_UINT32 dwID) { - eType = CExFilesInfo::eftVideo; - return pInfo; + size_t nCount = m_arOleObjects.size(); + for (size_t i = 0; i < nCount; ++i) + { + if (dwID == m_arOleObjects[i].m_dwID) + { + return &m_arOleObjects[i]; + } + } + + return NULL; } - pInfo = LockAudio(dwID); - if (NULL != pInfo) + CExFilesInfo* LockAudioFromCollection(_UINT32 dwID) { - eType = CExFilesInfo::eftAudio; - return pInfo; + size_t nCount = m_arAudioCollection.size(); + for (size_t i = 0; i < nCount; ++i) + { + if (dwID == m_arAudioCollection[i].m_dwID) + { + return &m_arAudioCollection[i]; + } + } + + return NULL; } - pInfo = LockSlide(dwID); - if (NULL != pInfo) + + CExFilesInfo* Lock(_UINT32 dwID, CExFilesInfo::ExFilesType& eType) { - eType = CExFilesInfo::eftSlide; - return pInfo; + CExFilesInfo* pInfo = NULL; + + pInfo = LockHyperlink(dwID); + if (NULL != pInfo) + { + eType = CExFilesInfo::eftHyperlink; + return pInfo; + } + pInfo = LockVideo(dwID); + if (NULL != pInfo) + { + eType = CExFilesInfo::eftVideo; + return pInfo; + } + pInfo = LockAudio(dwID); + if (NULL != pInfo) + { + eType = CExFilesInfo::eftAudio; + return pInfo; + } + pInfo = LockOleObject(dwID); + if (NULL != pInfo) + { + eType = CExFilesInfo::eftOleObject; + return pInfo; + } + pInfo = LockSlide(dwID); + if (NULL != pInfo) + { + eType = CExFilesInfo::eftSlide; + return pInfo; + } + eType = CExFilesInfo::eftNone; + return LockImage(dwID); } - eType = CExFilesInfo::eftNone; - return LockImage(dwID); - } -}; + }; } namespace ODRAW { -class CColor -{ -public: - BYTE R; - BYTE G; - BYTE B; - BYTE A; + class CColor + { + public: + BYTE R; + BYTE G; + BYTE B; + BYTE A; - _INT32 m_lSchemeIndex; + _INT32 m_lSchemeIndex; - CColor() - { - R = 0; - G = 0; - B = 0; - A = 255; + CColor() + { + R = 0; + G = 0; + B = 0; + A = 255; - m_lSchemeIndex = -1; - } - CColor(_UINT32 rgb) - { - (*this) = CreateColor(rgb); - } - CColor& operator =(const CColor& oSrc) - { - R = oSrc.R; - G = oSrc.G; - B = oSrc.B; - A = oSrc.A; + m_lSchemeIndex = -1; + } + CColor(_UINT32 rgb) + { + (*this) = CreateColor(rgb); + } + CColor& operator =(const CColor& oSrc) + { + R = oSrc.R; + G = oSrc.G; + B = oSrc.B; + A = oSrc.A; - m_lSchemeIndex = oSrc.m_lSchemeIndex; - return (*this); - } - inline bool IsEqual(const CColor& oSrc) - { - return ((R == oSrc.R) && (G == oSrc.G) && (B == oSrc.B) && (m_lSchemeIndex == oSrc.m_lSchemeIndex)); - } - static CColor CreateColor(_UINT32 dwColor) - { - CColor oColor; - oColor.R = (BYTE)(dwColor >> 16); - oColor.G = (BYTE)(dwColor >> 8); - oColor.B = (BYTE)(dwColor); - oColor.A = 0xFF; - - oColor.m_lSchemeIndex = -1; - return oColor; - } + m_lSchemeIndex = oSrc.m_lSchemeIndex; + return (*this); + } + inline bool IsEqual(const CColor& oSrc) + { + return ((R == oSrc.R) && (G == oSrc.G) && (B == oSrc.B) && (m_lSchemeIndex == oSrc.m_lSchemeIndex)); + } + static CColor CreateColor(_UINT32 dwColor) + { + CColor oColor; + oColor.R = (BYTE)(dwColor >> 16); + oColor.G = (BYTE)(dwColor >> 8); + oColor.B = (BYTE)(dwColor); + oColor.A = 0xFF; + + oColor.m_lSchemeIndex = -1; + return oColor; + } - CColor& operator =(const _UINT32& oSrc) - { - R = (BYTE)(oSrc >> 8); - G = (BYTE)(oSrc >> 16); - B = (BYTE)(oSrc >> 24); - A = (BYTE)oSrc; + CColor& operator =(const _UINT32& oSrc) + { + R = (BYTE)(oSrc >> 8); + G = (BYTE)(oSrc >> 16); + B = (BYTE)(oSrc >> 24); + A = (BYTE)oSrc; - m_lSchemeIndex = -1; - return (*this); - } - void SetSBGR(const _UINT32& lBGR) - { - R = (BYTE)(lBGR); - G = (BYTE)(lBGR >> 8); - B = (BYTE)(lBGR >> 16); + m_lSchemeIndex = -1; + return (*this); + } + void SetSBGR(const _UINT32& lBGR) + { + R = (BYTE)(lBGR); + G = (BYTE)(lBGR >> 8); + B = (BYTE)(lBGR >> 16); - if (lBGR & 0xFF000000) - m_lSchemeIndex = R; - } - void SetBGR(const _INT32& lBGR) - { - R = (BYTE)(lBGR); - G = (BYTE)(lBGR >> 8); - B = (BYTE)(lBGR >> 16); + if (lBGR & 0xFF000000) + m_lSchemeIndex = R; + } + void SetBGR(const _INT32& lBGR) + { + R = (BYTE)(lBGR); + G = (BYTE)(lBGR >> 8); + B = (BYTE)(lBGR >> 16); - m_lSchemeIndex = -1; - } - void SetRGB(BYTE r, BYTE g, BYTE b) - { - R = r; - G = g; - B = b; + m_lSchemeIndex = -1; + } + void SetRGB(BYTE r, BYTE g, BYTE b) + { + R = r; + G = g; + B = b; - m_lSchemeIndex = -1; - } - void SetR(BYTE r){ R = r; } - void SetG(BYTE g){ G = g; } - void SetB(BYTE b){ B = b; } + m_lSchemeIndex = -1; + } + void SetR(BYTE r) { R = r; } + void SetG(BYTE g) { G = g; } + void SetB(BYTE b) { B = b; } - BYTE GetR(){ return R; } - BYTE GetG(){ return G; } - BYTE GetB(){ return B; } + BYTE GetR() { return R; } + BYTE GetG() { return G; } + BYTE GetB() { return B; } - friend bool operator==(const CColor& color1, const CColor& color2) - { - return ((color1.R == color2.R) && (color1.G == color2.G) && (color1.B == color2.B)); - } + friend bool operator==(const CColor& color1, const CColor& color2) + { + return ((color1.R == color2.R) && (color1.G == color2.G) && (color1.B == color2.B)); + } - _INT32 GetLONG() const - { - _INT32 dwColor = 0; - dwColor |= R; - dwColor |= (G << 8); - dwColor |= (B << 16); + _INT32 GetLONG() const + { + _INT32 dwColor = 0; + dwColor |= R; + dwColor |= (G << 8); + dwColor |= (B << 16); - return dwColor; - } - _INT32 GetLONG_RGB() const - { - _INT32 dwColor = 0; - dwColor |= B; - dwColor |= (G << 8); - dwColor |= (R << 16); + return dwColor; + } + _INT32 GetLONG_RGB() const + { + _INT32 dwColor = 0; + dwColor |= B; + dwColor |= (G << 8); + dwColor |= (R << 16); - return dwColor; - } + return dwColor; + } - std::wstring ToString() - { - _UINT32 dwColor = 0; - dwColor |= R; - dwColor |= (G << 8); - dwColor |= (B << 16); - return std::to_wstring((int)dwColor); - } + std::wstring ToString() + { + _UINT32 dwColor = 0; + dwColor |= R; + dwColor |= (G << 8); + dwColor |= (B << 16); + return std::to_wstring((int)dwColor); + } - void FromString(std::wstring str) - { - int lColor; - if (str.find(_T("#")) == 0) + void FromString(std::wstring str) { - lColor = XmlUtils::GetColorBGR(str.substr(1, 6)); - R = (BYTE)(lColor); - G = (BYTE)(lColor >> 8); - B = (BYTE)(lColor >> 16); - A = 255; + int lColor; + if (str.find(L"#") == 0) + { + lColor = XmlUtils::GetColorBGR(str.substr(1, 6)); + R = (BYTE)(lColor); + G = (BYTE)(lColor >> 8); + B = (BYTE)(lColor >> 16); + A = 255; + } + else + { + size_t nLen = str.length(); + + wchar_t* pBuffer = (wchar_t*)str.c_str(); + wchar_t* pBuffer1 = pBuffer; + wchar_t* pBuffer2 = pBuffer; + wchar_t* pBufferEnd = pBuffer + nLen; + + while ((pBuffer1 < pBufferEnd) && !XmlUtils::IsDigit(*pBuffer1)) + ++pBuffer1; + pBuffer2 = pBuffer1; + while ((pBuffer2 < pBufferEnd) && XmlUtils::IsDigit(*pBuffer2)) + ++pBuffer2; + R = _GetColor(pBuffer1, pBuffer2); + + pBuffer1 = pBuffer2; + while ((pBuffer1 < pBufferEnd) && !XmlUtils::IsDigit(*pBuffer1)) + ++pBuffer1; + pBuffer2 = pBuffer1; + while ((pBuffer2 < pBufferEnd) && XmlUtils::IsDigit(*pBuffer2)) + ++pBuffer2; + G = _GetColor(pBuffer1, pBuffer2); + + pBuffer1 = pBuffer2; + while ((pBuffer1 < pBufferEnd) && !XmlUtils::IsDigit(*pBuffer1)) + ++pBuffer1; + pBuffer2 = pBuffer1; + while ((pBuffer2 < pBufferEnd) && XmlUtils::IsDigit(*pBuffer2)) + ++pBuffer2; + B = _GetColor(pBuffer1, pBuffer2); + + A = 0xFF; + m_lSchemeIndex = -1; + } } - else - { - size_t nLen = str.length(); - - wchar_t* pBuffer = (wchar_t*)str.c_str(); - wchar_t* pBuffer1 = pBuffer; - wchar_t* pBuffer2 = pBuffer; - wchar_t* pBufferEnd = pBuffer + nLen; - - while ((pBuffer1 < pBufferEnd) && !XmlUtils::IsDigit(*pBuffer1)) - ++pBuffer1; - pBuffer2 = pBuffer1; - while ((pBuffer2 < pBufferEnd) && XmlUtils::IsDigit(*pBuffer2)) - ++pBuffer2; - R = _GetColor(pBuffer1, pBuffer2); - - pBuffer1 = pBuffer2; - while ((pBuffer1 < pBufferEnd) && !XmlUtils::IsDigit(*pBuffer1)) - ++pBuffer1; - pBuffer2 = pBuffer1; - while ((pBuffer2 < pBufferEnd) && XmlUtils::IsDigit(*pBuffer2)) - ++pBuffer2; - G = _GetColor(pBuffer1, pBuffer2); - - pBuffer1 = pBuffer2; - while ((pBuffer1 < pBufferEnd) && !XmlUtils::IsDigit(*pBuffer1)) - ++pBuffer1; - pBuffer2 = pBuffer1; - while ((pBuffer2 < pBufferEnd) && XmlUtils::IsDigit(*pBuffer2)) - ++pBuffer2; - B = _GetColor(pBuffer1, pBuffer2); - - A = 0xFF; - m_lSchemeIndex = -1; + void From_UINT32(_UINT32 dwVal) + { + } - } - void From_UINT32(_UINT32 dwVal) - { - } + private: + BYTE _GetColor(wchar_t* pChar1, wchar_t* pChar2) + { + if (pChar1 == pChar2) + return 0; + std::wstring s(pChar1, (int)(pChar2 - pChar1)); + return (BYTE)XmlUtils::GetInteger(s); + } + }; -private: - BYTE _GetColor(wchar_t* pChar1, wchar_t* pChar2) + class CPen { - if (pChar1 == pChar2) - return 0; - std::wstring s(pChar1, (int)(pChar2 - pChar1)); - return (BYTE)XmlUtils::GetInteger(s); - } -}; - -class CPen -{ -public: - CColor Color; - long Alpha; - long Size; + public: + CColor Color; + long Alpha; + long Size; - unsigned char DashStyle; - unsigned char LineStyle; - unsigned char LineJoin; + unsigned char DashStyle; + unsigned char LineStyle; + unsigned char LineJoin; - unsigned char LineEndCap; - unsigned char LineEndLength; - unsigned char LineEndWidth; + unsigned char LineEndCap; + unsigned char LineEndLength; + unsigned char LineEndWidth; - unsigned char LineStartCap; - unsigned char LineStartLength; - unsigned char LineStartWidth; + unsigned char LineStartCap; + unsigned char LineStartLength; + unsigned char LineStartWidth; - double* DashPattern; - long Count; + double* DashPattern; + long Count; - double DashOffset; + double DashOffset; - _INT32 Align; - double MiterLimit; + _INT32 Align; + double MiterLimit; - CColor Color2; //backLine + CColor Color2; //backLine - void GetDashPattern(double* arrDashPattern, long& nCount) const - { - if (nCount == Count) + void GetDashPattern(double* arrDashPattern, long& nCount) const { - for (int i = 0; i < Count; ++i) + if (nCount == Count) { - arrDashPattern[i] = DashPattern[i]; + for (int i = 0; i < Count; ++i) + { + arrDashPattern[i] = DashPattern[i]; + } } } - } - void SetDashPattern(double* arrDashPattern, long nCount) - { - if ((arrDashPattern == NULL) || (nCount == 0)) - { - Count = 0; - RELEASEARRAYOBJECTS(DashPattern); - } - else + void SetDashPattern(double* arrDashPattern, long nCount) { - if (Count != nCount) + if ((arrDashPattern == NULL) || (nCount == 0)) { - Count = nCount; + Count = 0; RELEASEARRAYOBJECTS(DashPattern); - DashPattern = new double[Count]; } - - for (int i = 0; i < Count; ++i) + else { - DashPattern[i] = arrDashPattern[i]; + if (Count != nCount) + { + Count = nCount; + RELEASEARRAYOBJECTS(DashPattern); + DashPattern = new double[Count]; + } + + for (int i = 0; i < Count; ++i) + { + DashPattern[i] = arrDashPattern[i]; + } } } - } - void ScaleAlpha( double dScale ) - { - long dNewAlpha = long(Alpha * dScale + 0.5); + void ScaleAlpha(double dScale) + { + long dNewAlpha = long(Alpha * dScale + 0.5); - if( dNewAlpha > 255 ) dNewAlpha = 255; - else if( dNewAlpha < 0 ) dNewAlpha = 0; + if (dNewAlpha > 255) dNewAlpha = 255; + else if (dNewAlpha < 0) dNewAlpha = 0; - Alpha = dNewAlpha; - } + Alpha = dNewAlpha; + } - bool IsEqual(CPen* pPen) - { - if (NULL == pPen) - return false; + bool IsEqual(CPen* pPen) + { + if (NULL == pPen) + return false; - return ((Color == pPen->Color) && (Alpha == pPen->Alpha) && (Size == pPen->Size) && + return ((Color == pPen->Color) && (Alpha == pPen->Alpha) && (Size == pPen->Size) && (DashStyle == pPen->DashStyle) && (LineStartCap == pPen->LineStartCap) && (LineEndCap == pPen->LineEndCap) && (LineJoin == pPen->LineJoin)); - } - void SetToRenderer(IRenderer *pRenderer) - { - if (-1 == Color.m_lSchemeIndex) - pRenderer->put_PenColor(Color.GetLONG()); - else - { - _INT32 lColor = Color.GetLONG(); - lColor |= (0xFF000000 & ((Color.m_lSchemeIndex + 1 + 100) << 24)); - pRenderer->put_PenColor(lColor); } - pRenderer->put_PenAlpha(Alpha); - pRenderer->put_PenSize(Size); - pRenderer->put_PenDashStyle(DashStyle); - pRenderer->put_PenLineStartCap(LineStartCap); - pRenderer->put_PenLineEndCap(LineEndCap); - pRenderer->put_PenLineJoin(LineJoin); - pRenderer->put_PenAlign(Align); - - if (DashStyle != Gdiplus::DashStyleSolid) + void SetToRenderer(IRenderer* pRenderer) { + if (-1 == Color.m_lSchemeIndex) + pRenderer->put_PenColor(Color.GetLONG()); + else + { + _INT32 lColor = Color.GetLONG(); + lColor |= (0xFF000000 & ((Color.m_lSchemeIndex + 1 + 100) << 24)); + pRenderer->put_PenColor(lColor); + } + pRenderer->put_PenAlpha(Alpha); + pRenderer->put_PenSize(Size); + pRenderer->put_PenDashStyle(DashStyle); + pRenderer->put_PenLineStartCap(LineStartCap); + pRenderer->put_PenLineEndCap(LineEndCap); + pRenderer->put_PenLineJoin(LineJoin); + pRenderer->put_PenAlign(Align); + + if (DashStyle != Gdiplus::DashStyleSolid) + { - pRenderer->PenDashPattern(DashPattern, Count); + pRenderer->PenDashPattern(DashPattern, Count); - pRenderer->put_PenDashOffset(DashOffset); + pRenderer->put_PenDashOffset(DashOffset); + } } - } - void SetDefaultParams() - { - Alpha = 255; - Size = 9524; + void SetDefaultParams() + { + Alpha = 255; + Size = 9524; - LineStyle = 0; //single(Simple) - DashStyle = 0; //Solid - LineJoin = 2; //round + LineStyle = 0; //single(Simple) + DashStyle = 0; //Solid + LineJoin = 2; //round - LineStartCap = 0; - LineEndCap = 0; - LineEndLength = 1; //med - LineStartLength = 1; - LineEndWidth = 1; - LineStartWidth = 1; + LineStartCap = 0; + LineEndCap = 0; + LineEndLength = 1; //med + LineStartLength = 1; + LineEndWidth = 1; + LineStartWidth = 1; - DashPattern = NULL; - Count = 0; + DashPattern = NULL; + Count = 0; - Color.SetRGB (0x00, 0x00, 0x00); - Color2.SetRGB (0xff, 0xff, 0xff); + Color.SetRGB(0x00, 0x00, 0x00); + Color2.SetRGB(0xff, 0xff, 0xff); - DashOffset = 0; - Align = Gdiplus::PenAlignmentCenter; - MiterLimit = 0.5; - } + DashOffset = 0; + Align = Gdiplus::PenAlignmentCenter; + MiterLimit = 0.5; + } - CPen() - { - SetDefaultParams(); - } - CPen( const CPen& other ) - { - *this = other; - } - CPen& operator=(const CPen& other) - { - Color = other.Color; - Color2 = other.Color2; - Alpha = other.Alpha; - Size = other.Size; - - DashStyle = other.DashStyle; - LineStartCap = other.LineStartCap; - LineEndCap = other.LineEndCap; - LineJoin = other.LineJoin; - - RELEASEARRAYOBJECTS(DashPattern); - Count = other.Count; - if (Count != 0) - { - DashPattern = new double[Count]; - for (int i = 0; i < Count; ++i) + CPen() + { + SetDefaultParams(); + } + CPen(const CPen& other) + { + *this = other; + } + CPen& operator=(const CPen& other) + { + Color = other.Color; + Color2 = other.Color2; + Alpha = other.Alpha; + Size = other.Size; + + DashStyle = other.DashStyle; + LineStartCap = other.LineStartCap; + LineEndCap = other.LineEndCap; + LineJoin = other.LineJoin; + + RELEASEARRAYOBJECTS(DashPattern); + Count = other.Count; + if (Count != 0) { - DashPattern[i] = other.DashPattern[i]; + DashPattern = new double[Count]; + for (int i = 0; i < Count; ++i) + { + DashPattern[i] = other.DashPattern[i]; + } } - } - DashOffset = other.DashOffset; - Align = other.Align; - MiterLimit = other.MiterLimit; + DashOffset = other.DashOffset; + Align = other.Align; + MiterLimit = other.MiterLimit; - return *this; - } - virtual ~CPen() - { - RELEASEARRAYOBJECTS(DashPattern); - } + return *this; + } + virtual ~CPen() + { + RELEASEARRAYOBJECTS(DashPattern); + } -}; + }; -class CBrush -{ -public: - long Type; + class CBrush + { + public: + long Type; - CColor Color1; - CColor Color2; + CColor Color1; + CColor Color2; - long Alpha1; - long Alpha2; + long Alpha1; + long Alpha2; - std::wstring TexturePath; - long TextureAlpha; - long TextureMode; + std::wstring TexturePath; + long TextureAlpha; + long TextureMode; - bool Rectable; - Gdiplus::RectF Rect; + bool Rectable; + Gdiplus::RectF Rect; - double LinearAngle; + double LinearAngle; - std::vector> ColorsPosition; + std::vector> ColorsPosition; - inline _INT32 ConstantCompatible(_INT32 nConstant) - { - if( c_BrushTypeDiagonal1_ == nConstant ) - nConstant = c_BrushTypeDiagonal2_; - else if( c_BrushTypeDiagonal2_ == nConstant ) - nConstant = c_BrushTypeDiagonal1_; - - if (1000 <= nConstant) - return nConstant; - if (c_BrushTypeSolid_ == nConstant) - return nConstant + 1000; - if (c_BrushTypeHorizontal_ <= nConstant && c_BrushTypePathGradient2_ >= nConstant) - return nConstant + 2000; - if (c_BrushTypeTexture_ == nConstant) - return nConstant + 3000; - if (c_BrushTypeHatch1_ <= nConstant && c_BrushTypeHatch53_ >= nConstant) - return nConstant + 4000; - if (c_BrushTypeGradient1_ <= nConstant && c_BrushTypeGradient6_ >= nConstant) - return nConstant + 2000 - 61; - - return 1000; - } + inline _INT32 ConstantCompatible(_INT32 nConstant) + { + if (c_BrushTypeDiagonal1_ == nConstant) + nConstant = c_BrushTypeDiagonal2_; + else if (c_BrushTypeDiagonal2_ == nConstant) + nConstant = c_BrushTypeDiagonal1_; + + if (1000 <= nConstant) + return nConstant; + if (c_BrushTypeSolid_ == nConstant) + return nConstant + 1000; + if (c_BrushTypeHorizontal_ <= nConstant && c_BrushTypePathGradient2_ >= nConstant) + return nConstant + 2000; + if (c_BrushTypeTexture_ == nConstant) + return nConstant + 3000; + if (c_BrushTypeHatch1_ <= nConstant && c_BrushTypeHatch53_ >= nConstant) + return nConstant + 4000; + if (c_BrushTypeGradient1_ <= nConstant && c_BrushTypeGradient6_ >= nConstant) + return nConstant + 2000 - 61; + + return 1000; + } - void ScaleAlpha1( double dScale ) - { - long dNewAlpha = long(Alpha1 * dScale + 0.5); + void ScaleAlpha1(double dScale) + { + long dNewAlpha = long(Alpha1 * dScale + 0.5); - if( dNewAlpha > 255 ) dNewAlpha = 255; - else if( dNewAlpha < 0 ) dNewAlpha = 0; + if (dNewAlpha > 255) dNewAlpha = 255; + else if (dNewAlpha < 0) dNewAlpha = 0; - Alpha1 = dNewAlpha; - } - void ScaleAlpha2( double dScale ) - { - long dNewAlpha = long(Alpha2 * dScale + 0.5); + Alpha1 = dNewAlpha; + } + void ScaleAlpha2(double dScale) + { + long dNewAlpha = long(Alpha2 * dScale + 0.5); - if( dNewAlpha > 255 ) dNewAlpha = 255; - else if( dNewAlpha < 0 ) dNewAlpha = 0; + if (dNewAlpha > 255) dNewAlpha = 255; + else if (dNewAlpha < 0) dNewAlpha = 0; - Alpha2 = dNewAlpha; - } + Alpha2 = dNewAlpha; + } - void ScaleTextureAlpha( double dScale ) - { - long dNewAlpha = long(TextureAlpha * dScale + 0.5); + void ScaleTextureAlpha(double dScale) + { + long dNewAlpha = long(TextureAlpha * dScale + 0.5); - if( dNewAlpha > 255 ) dNewAlpha = 255; - else if( dNewAlpha < 0 ) dNewAlpha = 0; + if (dNewAlpha > 255) dNewAlpha = 255; + else if (dNewAlpha < 0) dNewAlpha = 0; - TextureAlpha = dNewAlpha; - } + TextureAlpha = dNewAlpha; + } - bool IsEqual(CBrush* pBrush) - { - if (NULL == pBrush) - return false; + bool IsEqual(CBrush* pBrush) + { + if (NULL == pBrush) + return false; - /*return ((Type == pBrush->Type) && - (Color1 == pBrush->Color1) && (Color2 == pBrush->Color2) && - (Alpha1 == pBrush->Alpha1) && (Alpha2 == pBrush->Alpha2));*/ + /*return ((Type == pBrush->Type) && + (Color1 == pBrush->Color1) && (Color2 == pBrush->Color2) && + (Alpha1 == pBrush->Alpha1) && (Alpha2 == pBrush->Alpha2));*/ - return ((Type == pBrush->Type) && + return ((Type == pBrush->Type) && (Color1 == pBrush->Color1) && (Color2 == pBrush->Color2) && (Alpha1 == pBrush->Alpha1) && (Alpha2 == pBrush->Alpha2) && (LinearAngle == pBrush->LinearAngle) && (TexturePath == pBrush->TexturePath) && (TextureAlpha == pBrush->TextureAlpha) && (TextureMode == pBrush->TextureMode) && (Rectable == pBrush->Rectable) && (Rect.Equals(pBrush->Rect))); - } - - void SetDefaultParams() - { - Type = c_BrushTypeNotSet; + } - Color1 = 0xFFFFFFFF; - Alpha1 = 255; - Color2 = 0xFFFFFFFF; - Alpha2 = 255; + void SetDefaultParams() + { + Type = c_BrushTypeNotSet; - TextureAlpha = 255; - TextureMode = c_BrushTextureModeStretch; + Color1 = 0xFFFFFFFF; + Alpha1 = 255; + Color2 = 0xFFFFFFFF; + Alpha2 = 255; - LinearAngle = 0; + TextureAlpha = 255; + TextureMode = c_BrushTextureModeStretch; - TexturePath = _T(""); + LinearAngle = 0; - Rectable = false; + TexturePath = L""; - Rect.X = 0.0F; - Rect.Y = 0.0F; - Rect.Width = 0.0F; - Rect.Height = 0.0F; + Rectable = false; - ColorsPosition.clear(); - } + Rect.X = 0.0F; + Rect.Y = 0.0F; + Rect.Width = 0.0F; + Rect.Height = 0.0F; - CBrush() - { - SetDefaultParams(); - } - CBrush( const CBrush& other ) - { - Type = other.Type; + ColorsPosition.clear(); + } - Color1 = other.Color1; - Alpha1 = other.Alpha1; - Color2 = other.Color2; - Alpha2 = other.Alpha2; + CBrush() + { + SetDefaultParams(); + } + CBrush(const CBrush& other) + { + Type = other.Type; - TexturePath = other.TexturePath; - TextureAlpha = other.TextureAlpha; - TextureMode = other.TextureMode; + Color1 = other.Color1; + Alpha1 = other.Alpha1; + Color2 = other.Color2; + Alpha2 = other.Alpha2; - Rectable = other.Rectable; - Rect = other.Rect; + TexturePath = other.TexturePath; + TextureAlpha = other.TextureAlpha; + TextureMode = other.TextureMode; - LinearAngle = other.LinearAngle; + Rectable = other.Rectable; + Rect = other.Rect; - ColorsPosition = other.ColorsPosition; - } - CBrush& operator=(const CBrush& other) - { - Type = other.Type; + LinearAngle = other.LinearAngle; - Color1 = other.Color1; - Alpha1 = other.Alpha1; - Color2 = other.Color2; - Alpha2 = other.Alpha2; + ColorsPosition = other.ColorsPosition; + } + CBrush& operator=(const CBrush& other) + { + Type = other.Type; - TexturePath = other.TexturePath; - TextureAlpha = other.TextureAlpha; - TextureMode = other.TextureMode; + Color1 = other.Color1; + Alpha1 = other.Alpha1; + Color2 = other.Color2; + Alpha2 = other.Alpha2; - Rectable = other.Rectable; - Rect = other.Rect; + TexturePath = other.TexturePath; + TextureAlpha = other.TextureAlpha; + TextureMode = other.TextureMode; - LinearAngle = other.LinearAngle; + Rectable = other.Rectable; + Rect = other.Rect; - ColorsPosition = other.ColorsPosition; - return *this; - } - virtual ~CBrush() - { - } + LinearAngle = other.LinearAngle; - bool IsTexture() - { - return (c_BrushTypeTexture == Type); - } - bool IsOneColor() - { - return (c_BrushTypeSolid == Type); - } - bool IsTwoColor() - { - return ((c_BrushTypeHorizontal <= Type && c_BrushTypeCylinderVer >= Type) || - (c_BrushTypeHatch1 <= Type && c_BrushTypeHatch53 >= Type)); - } - - void SetToRenderer(IRenderer *pRenderer) - { - Type = ConstantCompatible(Type); - pRenderer->put_BrushType(Type); - if (IsOneColor()) + ColorsPosition = other.ColorsPosition; + return *this; + } + virtual ~CBrush() { - //pRenderer->put_BrushColor1(Color1.GetLONG()); - - if (-1 == Color1.m_lSchemeIndex) - pRenderer->put_BrushColor1(Color1.GetLONG()); - else - { - _INT32 lColor = Color1.GetLONG(); - lColor |= (0xFF000000 & ((Color1.m_lSchemeIndex + 1 + 100) << 24)); - pRenderer->put_BrushColor1(lColor); - } + } - pRenderer->put_BrushAlpha1(Alpha1); + bool IsTexture() + { + return (c_BrushTypeTexture == Type); } - else if (IsTexture()) + bool IsOneColor() { - //BSTR bstrTexturePath = TexturePath.AllocSysString(); - pRenderer->put_BrushTexturePath(TexturePath); - //SysFreeString(bstrTexturePath); - pRenderer->put_BrushTextureMode(TextureMode); - pRenderer->put_BrushTextureAlpha(TextureAlpha); - pRenderer->BrushRect(Rectable, Rect.X, Rect.Y, Rect.Width, Rect.Height); + return (c_BrushTypeSolid == Type); } - else if (IsTwoColor()) + bool IsTwoColor() { - //pRenderer->put_BrushColor1(Color1.GetLONG()); + return ((c_BrushTypeHorizontal <= Type && c_BrushTypeCylinderVer >= Type) || + (c_BrushTypeHatch1 <= Type && c_BrushTypeHatch53 >= Type)); + } - if (-1 == Color1.m_lSchemeIndex) - pRenderer->put_BrushColor1(Color1.GetLONG()); - else + void SetToRenderer(IRenderer* pRenderer) + { + Type = ConstantCompatible(Type); + pRenderer->put_BrushType(Type); + if (IsOneColor()) { - _INT32 lColor = Color1.GetLONG(); - lColor |= (0xFF000000 & ((Color1.m_lSchemeIndex + 1 + 100) << 24)); - pRenderer->put_BrushColor1(lColor); + //pRenderer->put_BrushColor1(Color1.GetLONG()); + + if (-1 == Color1.m_lSchemeIndex) + pRenderer->put_BrushColor1(Color1.GetLONG()); + else + { + _INT32 lColor = Color1.GetLONG(); + lColor |= (0xFF000000 & ((Color1.m_lSchemeIndex + 1 + 100) << 24)); + pRenderer->put_BrushColor1(lColor); + } + + pRenderer->put_BrushAlpha1(Alpha1); + } + else if (IsTexture()) + { + //BSTR bstrTexturePath = TexturePath.AllocSysString(); + pRenderer->put_BrushTexturePath(TexturePath); + //SysFreeString(bstrTexturePath); + pRenderer->put_BrushTextureMode(TextureMode); + pRenderer->put_BrushTextureAlpha(TextureAlpha); + pRenderer->BrushRect(Rectable, Rect.X, Rect.Y, Rect.Width, Rect.Height); + } + else if (IsTwoColor()) + { + //pRenderer->put_BrushColor1(Color1.GetLONG()); + + if (-1 == Color1.m_lSchemeIndex) + pRenderer->put_BrushColor1(Color1.GetLONG()); + else + { + _INT32 lColor = Color1.GetLONG(); + lColor |= (0xFF000000 & ((Color1.m_lSchemeIndex + 1 + 100) << 24)); + pRenderer->put_BrushColor1(lColor); + } + + pRenderer->put_BrushAlpha1(Alpha1); + pRenderer->put_BrushColor2(Color2.GetLONG()); + pRenderer->put_BrushAlpha2(Alpha2); } - - pRenderer->put_BrushAlpha1(Alpha1); - pRenderer->put_BrushColor2(Color2.GetLONG()); - pRenderer->put_BrushAlpha2(Alpha2); } - } -}; + }; -class CFont -{ -public: - std::wstring Path; - std::wstring Name; - double Size; - bool Bold; - bool Italic; - BYTE Underline; - BYTE Strikeout; - - bool StringGID; - double CharSpace; - - BYTE PitchFamily; - BYTE Charset; - bool Monospace; - - bool IsEqual(CFont* pFont) + class CFont { - if (NULL == pFont) - return false; + public: + std::wstring Path; + std::wstring Name; + double Size; + bool Bold; + bool Italic; + BYTE Underline; + BYTE Strikeout; - return ((Name == pFont->Name) && (Path == pFont->Path) && (StringGID == pFont->StringGID) && (Size == pFont->Size) && + bool StringGID; + double CharSpace; + + BYTE PitchFamily; + BYTE Charset; + bool Monospace; + + bool IsEqual(CFont* pFont) + { + if (NULL == pFont) + return false; + + return ((Name == pFont->Name) && (Path == pFont->Path) && (StringGID == pFont->StringGID) && (Size == pFont->Size) && (Bold == pFont->Bold) && (Italic == pFont->Italic) && (Underline == pFont->Underline) && (Strikeout == pFont->Strikeout)); - } - bool IsEqual2(CFont* pFont) - { - if (NULL == pFont) - return false; + } + bool IsEqual2(CFont* pFont) + { + if (NULL == pFont) + return false; - return ((Name == pFont->Name) && (Path == pFont->Path) && (StringGID == pFont->StringGID) && (Size == pFont->Size) && + return ((Name == pFont->Name) && (Path == pFont->Path) && (StringGID == pFont->StringGID) && (Size == pFont->Size) && (Bold == pFont->Bold) && (Italic == pFont->Italic)); - } - - _INT32 GetStyle() const - { - _INT32 lStyle = 0; - if (Bold) - lStyle |= 0x01; - if (Italic) - lStyle |= 0x02; - lStyle |= Underline << 2; - lStyle |= Strikeout << 7; - return lStyle; - } - void SetStyle(_INT32 const& lStyle) - { - Bold = (0x01 == (0x01 & lStyle)); - Italic = (0x02 == (0x02 & lStyle)); - Underline = (BYTE)(0x7C & lStyle) >> 2; - Strikeout = (BYTE)(0x0180 & lStyle) >> 7; - } - void SetToRenderer(IRenderer *pRenderer) - { - pRenderer->put_FontName(Name); - pRenderer->put_FontPath(Path); - + } - pRenderer->put_FontSize(Size); - pRenderer->put_FontStyle(GetStyle()); - pRenderer->put_FontStringGID(StringGID); - pRenderer->put_FontCharSpace(CharSpace); - } - void SetDefaultParams() - { - Name = _T("Arial"); - Path = _T(""); + _INT32 GetStyle() const + { + _INT32 lStyle = 0; + if (Bold) + lStyle |= 0x01; + if (Italic) + lStyle |= 0x02; + lStyle |= Underline << 2; + lStyle |= Strikeout << 7; + return lStyle; + } + void SetStyle(_INT32 const& lStyle) + { + Bold = (0x01 == (0x01 & lStyle)); + Italic = (0x02 == (0x02 & lStyle)); + Underline = (BYTE)(0x7C & lStyle) >> 2; + Strikeout = (BYTE)(0x0180 & lStyle) >> 7; + } + void SetToRenderer(IRenderer* pRenderer) + { + pRenderer->put_FontName(Name); + pRenderer->put_FontPath(Path); - Size = 0; - Bold = false; - Italic = false; - Underline = 0; - Strikeout = 0; - StringGID = false; - CharSpace = 0.0; + pRenderer->put_FontSize(Size); + pRenderer->put_FontStyle(GetStyle()); + pRenderer->put_FontStringGID(StringGID); + pRenderer->put_FontCharSpace(CharSpace); + } + void SetDefaultParams() + { + Name = L"Arial"; + Path = L""; - PitchFamily = 0; - Charset = 0; - Monospace = false; - } + Size = 0; + Bold = false; + Italic = false; + Underline = 0; + Strikeout = 0; - CFont() - { - SetDefaultParams(); - } - CFont( const CFont& other ) - { - *this = other; - } - CFont& operator=(const CFont& other) - { - Name = other.Name; - Path = other.Path; - Size = other.Size; - Bold = other.Bold; - Italic = other.Italic; - Underline = other.Underline; - Strikeout = other.Strikeout; - - StringGID = other.StringGID; - CharSpace = other.CharSpace; - - PitchFamily = other.PitchFamily; - Charset = other.Charset; - Monospace = other.Monospace; - - return *this; - } - virtual ~CFont() - { - } -}; + StringGID = false; + CharSpace = 0.0; -class CShadow -{ -public: + PitchFamily = 0; + Charset = 0; + Monospace = false; + } - bool Visible; + CFont() + { + SetDefaultParams(); + } + CFont(const CFont& other) + { + *this = other; + } + CFont& operator=(const CFont& other) + { + Name = other.Name; + Path = other.Path; + Size = other.Size; + Bold = other.Bold; + Italic = other.Italic; + Underline = other.Underline; + Strikeout = other.Strikeout; + + StringGID = other.StringGID; + CharSpace = other.CharSpace; + + PitchFamily = other.PitchFamily; + Charset = other.Charset; + Monospace = other.Monospace; + + return *this; + } + virtual ~CFont() + { + } + }; - double DistanceX; - double DistanceY; + class CShadow + { + public: - double OriginX; - double OriginY; + bool Visible; - double BlurSize; - CColor Color; - long Alpha; + double DistanceX; + double DistanceY; - int Type; + double OriginX; + double OriginY; - double ScaleXToX; - double ScaleXToY; - double ScaleYToX; - double ScaleYToY; + double BlurSize; + CColor Color; + long Alpha; - int PerspectiveX; - int PerspectiveY; + int Type; - void SetDefaultParams() - { - Visible = false; - DistanceX = 25400; - DistanceY = 25400; - BlurSize = 0; - Alpha = 255; + double ScaleXToX; + double ScaleXToY; + double ScaleYToX; + double ScaleYToY; - OriginX = 0; - OriginY = 0; + int PerspectiveX; + int PerspectiveY; - Type = -1; + void SetDefaultParams() + { + Visible = false; + DistanceX = 25400; + DistanceY = 25400; + BlurSize = 0; + Alpha = 255; - ScaleXToX = 1.; - ScaleXToY = 1.; - ScaleYToX = 1.; - ScaleYToY = 1.; + OriginX = 0; + OriginY = 0; - PerspectiveX = 0; - PerspectiveY = 0; + Type = -1; - Color.SetRGB(0x80, 0x80, 0x80); - } + ScaleXToX = 1.; + ScaleXToY = 1.; + ScaleYToX = 1.; + ScaleYToY = 1.; - CShadow() - { - SetDefaultParams(); - } - CShadow( const CShadow& other ) - { - Visible = other.Visible; - DistanceX = other.DistanceX; - DistanceY = other.DistanceY; - OriginX = other.OriginX; - OriginY = other.OriginY; - BlurSize = other.BlurSize; - Color = other.Color; - Alpha = other.Alpha; - - Type = other.Type; - - ScaleXToX = other.ScaleXToX; - ScaleXToY = other.ScaleXToY; - ScaleYToX = other.ScaleYToX; - ScaleYToY = other.ScaleYToY; - - PerspectiveX= other.PerspectiveX; - PerspectiveY= other.PerspectiveY; - } - CShadow& operator=(const CShadow& other) - { - Visible = other.Visible; - DistanceX = other.DistanceX; - DistanceY = other.DistanceY; - OriginX = other.OriginX; - OriginY = other.OriginY; - BlurSize = other.BlurSize; - Color = other.Color; - Alpha = other.Alpha; - Type = other.Type; - - PerspectiveX= other.PerspectiveX; - PerspectiveY= other.PerspectiveY; - - ScaleXToX = other.ScaleXToX; - ScaleXToY = other.ScaleXToY; - ScaleYToX = other.ScaleYToX; - ScaleYToY = other.ScaleYToY; - - return *this; - } - virtual ~CShadow() - { - } -}; + PerspectiveX = 0; + PerspectiveY = 0; -class CEdgeText -{ -public: + Color.SetRGB(0x80, 0x80, 0x80); + } - long Visible; - double Dist; - CColor Color; - long Alpha; + CShadow() + { + SetDefaultParams(); + } + CShadow(const CShadow& other) + { + Visible = other.Visible; + DistanceX = other.DistanceX; + DistanceY = other.DistanceY; + OriginX = other.OriginX; + OriginY = other.OriginY; + BlurSize = other.BlurSize; + Color = other.Color; + Alpha = other.Alpha; + + Type = other.Type; + + ScaleXToX = other.ScaleXToX; + ScaleXToY = other.ScaleXToY; + ScaleYToX = other.ScaleYToX; + ScaleYToY = other.ScaleYToY; + + PerspectiveX = other.PerspectiveX; + PerspectiveY = other.PerspectiveY; + } + CShadow& operator=(const CShadow& other) + { + Visible = other.Visible; + DistanceX = other.DistanceX; + DistanceY = other.DistanceY; + OriginX = other.OriginX; + OriginY = other.OriginY; + BlurSize = other.BlurSize; + Color = other.Color; + Alpha = other.Alpha; + Type = other.Type; + + PerspectiveX = other.PerspectiveX; + PerspectiveY = other.PerspectiveY; + + ScaleXToX = other.ScaleXToX; + ScaleXToY = other.ScaleXToY; + ScaleYToX = other.ScaleYToX; + ScaleYToY = other.ScaleYToY; + + return *this; + } + virtual ~CShadow() + { + } + }; - void SetDefaultParams() + class CEdgeText { - Visible = 0; - Dist = 5; - Color = 0; - Alpha = 255; - } + public: - CEdgeText() - { - SetDefaultParams(); - } - CEdgeText( const CEdgeText& other ) - { - Visible = other.Visible; - Dist = other.Dist; - Color = other.Color; - Alpha = other.Alpha; - } - CEdgeText& operator=(const CEdgeText& other) - { - Visible = other.Visible; - Dist = other.Dist; - Color = other.Color; - Alpha = other.Alpha; + long Visible; + double Dist; + CColor Color; + long Alpha; - return *this; - } - virtual ~CEdgeText() - { - } -}; + void SetDefaultParams() + { + Visible = 0; + Dist = 5; + Color = 0; + Alpha = 255; + } -class CTextAttributes -{ -public: - CFont m_oFont; - CBrush m_oTextBrush; - CShadow m_oTextShadow; - CEdgeText m_oTextEdge; + CEdgeText() + { + SetDefaultParams(); + } + CEdgeText(const CEdgeText& other) + { + Visible = other.Visible; + Dist = other.Dist; + Color = other.Color; + Alpha = other.Alpha; + } + CEdgeText& operator=(const CEdgeText& other) + { + Visible = other.Visible; + Dist = other.Dist; + Color = other.Color; + Alpha = other.Alpha; - int m_nTextAlignHorizontal; - int m_nTextAlignVertical; - double m_dTextRotate; + return *this; + } + virtual ~CEdgeText() + { + } + }; - CTextAttributes() : m_oFont(), m_oTextBrush(), m_oTextShadow(), m_oTextEdge() + class CTextAttributes { - m_oFont.Size = 36; - m_oTextBrush.Color1 = 0xFF; + public: + CFont m_oFont; + CBrush m_oTextBrush; + CShadow m_oTextShadow; + CEdgeText m_oTextEdge; - m_nTextAlignHorizontal = 0; - m_nTextAlignVertical = -1; //not set - m_dTextRotate = 0; - } - CTextAttributes& operator =(const CTextAttributes& oSrc) - { - m_oFont = oSrc.m_oFont; - m_oTextBrush = oSrc.m_oTextBrush; - m_oTextShadow = oSrc.m_oTextShadow; - m_oTextEdge = oSrc.m_oTextEdge; + int m_nTextAlignHorizontal; + int m_nTextAlignVertical; + double m_dTextRotate; - m_nTextAlignHorizontal = oSrc.m_nTextAlignHorizontal; - m_nTextAlignVertical = oSrc.m_nTextAlignVertical; - m_dTextRotate = oSrc.m_dTextRotate; + CTextAttributes() : m_oFont(), m_oTextBrush(), m_oTextShadow(), m_oTextEdge() + { + m_oFont.Size = 36; + m_oTextBrush.Color1 = 0xFF; - return (*this); - } -}; + m_nTextAlignHorizontal = 0; + m_nTextAlignVertical = -1; //not set + m_dTextRotate = 0; + } + CTextAttributes& operator =(const CTextAttributes& oSrc) + { + m_oFont = oSrc.m_oFont; + m_oTextBrush = oSrc.m_oTextBrush; + m_oTextShadow = oSrc.m_oTextShadow; + m_oTextEdge = oSrc.m_oTextEdge; + m_nTextAlignHorizontal = oSrc.m_nTextAlignHorizontal; + m_nTextAlignVertical = oSrc.m_nTextAlignVertical; + m_dTextRotate = oSrc.m_dTextRotate; + return (*this); + } + }; } diff --git a/MsBinaryFile/PptFile/Drawing/AudioOverlay.h b/MsBinaryFile/PptFile/Drawing/AudioOverlay.h index 1451f301e35..7cf6cafaa86 100644 --- a/MsBinaryFile/PptFile/Drawing/AudioOverlay.h +++ b/MsBinaryFile/PptFile/Drawing/AudioOverlay.h @@ -108,7 +108,7 @@ namespace PPT { if (NULL == pAudioElem) { - m_strFile = _T(""); + m_strFile = L""; m_dStartTime = 0.0; m_dEndTime = -1.0; @@ -149,7 +149,7 @@ namespace PPT public: void CalculateDuration() { - if (0.0 < m_dAudioDuration || _T("") == m_strFile) + if (0.0 < m_dAudioDuration || L"" == m_strFile) return; } }; @@ -260,7 +260,7 @@ namespace PPT std::wstring GetAudioOverlay() { - std::wstring strRes = _T(""); + std::wstring strRes; size_t nCount = m_arParts.size(); diff --git a/MsBinaryFile/PptFile/Drawing/Document.h b/MsBinaryFile/PptFile/Drawing/Document.h index a3dff96e2c7..62a5c11fbfe 100644 --- a/MsBinaryFile/PptFile/Drawing/Document.h +++ b/MsBinaryFile/PptFile/Drawing/Document.h @@ -52,10 +52,10 @@ class CDocument CThemePtr m_pNotesMaster; CThemePtr m_pHandoutMaster; - bool m_bMacros; + bool m_bMacroEnabled; std::wstring m_sVbaProjectFile; - CDocument() : m_bMacros (true) + CDocument() : m_bMacroEnabled(true) { m_lSlideWidth = 0; m_lSlideHeight = 0; diff --git a/MsBinaryFile/PptFile/Drawing/Element.h b/MsBinaryFile/PptFile/Drawing/Element.h index a36fc9c2755..3ca24b614a6 100644 --- a/MsBinaryFile/PptFile/Drawing/Element.h +++ b/MsBinaryFile/PptFile/Drawing/Element.h @@ -38,13 +38,14 @@ namespace PPT { enum ElementType { - etGroup = 0, - etVideo = 1, - etAudio = 2, - etPicture = 3, - etShape = 4, - etText = 5, - etTable = 6 + etGroup = 0, + etVideo = 1, + etAudio = 2, + etPicture = 3, + etShape = 4, + etText = 5, + etTable = 6, + etOleObject = 7 }; class CTheme; diff --git a/MsBinaryFile/PptFile/Drawing/Elements.cpp b/MsBinaryFile/PptFile/Drawing/Elements.cpp index 8b812e57932..bcbae43ce2c 100644 --- a/MsBinaryFile/PptFile/Drawing/Elements.cpp +++ b/MsBinaryFile/PptFile/Drawing/Elements.cpp @@ -34,18 +34,18 @@ #include "../../Common/Vml/PPTShape/Ppt2PptxShapeConverter.h" #ifndef DISABLE_FILE_DOWNLOADER - #include "../../../Common/Network/FileTransporter/include/FileTransporter.h" - #include "../../../DesktopEditor/raster/ImageFileFormatChecker.h" +#include "../../../Common/Network/FileTransporter/include/FileTransporter.h" +#include "../../../DesktopEditor/raster/ImageFileFormatChecker.h" #endif std::wstring PPT::CImageElement::DownloadImage(const std::wstring& strFile) { #ifndef DISABLE_FILE_DOWNLOADER - NSNetwork::NSFileTransport::CFileDownloader oDownloader(strFile, true); - if ( oDownloader.DownloadSync() ) + NSNetwork::NSFileTransport::CFileDownloader oDownloader(strFile, true); + if (oDownloader.DownloadSync()) { m_strImageFileName = oDownloader.GetFilePath(); - + CImageFileFormatChecker checker; if (false == checker.isImageFile(m_strImageFileName)) { @@ -53,7 +53,7 @@ std::wstring PPT::CImageElement::DownloadImage(const std::wstring& strFile) } } #endif - return m_strImageFileName; + return m_strImageFileName; } void PPT::CShapeElement::CalculateColor(CColor& oColor, CSlide* pSlide, CTheme* pTheme, CLayout* pLayout) { @@ -61,11 +61,11 @@ void PPT::CShapeElement::CalculateColor(CColor& oColor, CSlide* pSlide, CTheme* if (-1 == oColor.m_lSchemeIndex) return; - std::vector* pArray = NULL; + std::vector* pArray = NULL; - if (pTheme) pArray = &pTheme->m_arColorScheme; + if (pTheme) pArray = &pTheme->m_arColorScheme; - if ((NULL != pLayout) && (!pLayout->m_bUseThemeColorScheme)) + if ((NULL != pLayout) && (!pLayout->m_bUseThemeColorScheme)) pArray = &pLayout->m_arColorScheme; if (NULL != pSlide) @@ -74,13 +74,13 @@ void PPT::CShapeElement::CalculateColor(CColor& oColor, CSlide* pSlide, CTheme* pArray = &pSlide->m_arColorScheme; } - if ((0 > oColor.m_lSchemeIndex) || ((pArray) && (oColor.m_lSchemeIndex >= (LONG)pArray->size()))) + if ((0 > oColor.m_lSchemeIndex) || ((pArray) && (oColor.m_lSchemeIndex >= (LONG)pArray->size()))) return; - if (pArray) - { - oColor = pArray->at(oColor.m_lSchemeIndex); - } + if (pArray) + { + oColor = pArray->at(oColor.m_lSchemeIndex); + } oColor.m_lSchemeIndex = lOldIndex; } @@ -108,7 +108,7 @@ void PPT::CShapeElement::SetupTextProperties(CSlide* pSlide, CTheme* pTheme, CLa for (size_t i = 0; i < nCountCFs; ++i) { CTextCFRun* pRun = &pAttributes->m_arParagraphs[nIndex].m_arSpans[i].m_oRun; - + if (pRun->Color.is_init()) { int nColorIndex = (int)pRun->Color->m_lSchemeIndex; @@ -149,22 +149,22 @@ bool PPT::CShapeElement::SetUpTextPlaceholder(std::wstring newText) bool result = false; PPT::CTextAttributesEx* pText = &m_pShape->m_oText; - for (size_t p = 0 ; p < pText->m_arParagraphs.size(); p++) //тут по всем -> 1-(33).ppt + for (size_t p = 0; p < pText->m_arParagraphs.size(); p++) //тут по всем -> 1-(33).ppt { - if (pText->m_arParagraphs[p].m_arSpans.size() >0)//??? по всем? + if (pText->m_arParagraphs[p].m_arSpans.size() > 0)//??? по всем? { int pos = (int)pText->m_arParagraphs[p].m_arSpans[0].m_strText.find(L"*"); - + if (pos >= 0) { CSpan first = pText->m_arParagraphs[p].m_arSpans[0]; CSpan last = pText->m_arParagraphs[p].m_arSpans[0]; - - first.m_strText = pText->m_arParagraphs[p].m_arSpans[0].m_strText.substr(0, pos); - last.m_strText = pText->m_arParagraphs[p].m_arSpans[0].m_strText.substr(pos + 1); + + first.m_strText = pText->m_arParagraphs[p].m_arSpans[0].m_strText.substr(0, pos); + last.m_strText = pText->m_arParagraphs[p].m_arSpans[0].m_strText.substr(pos + 1); pText->m_arParagraphs[p].m_arSpans[0].m_strText = newText; - pText->m_arParagraphs[p].m_arSpans[0].m_bField = true; + pText->m_arParagraphs[p].m_arSpans[0].m_bField = true; if (last.m_strText.empty() == false) pText->m_arParagraphs[p].m_arSpans.insert(pText->m_arParagraphs[p].m_arSpans.begin() + 1, last); @@ -280,13 +280,13 @@ namespace PPT { if (bIsNamespace) { - return _T(""); + return L""; } - return _T(""); + return L""; - std::wstring strXmlPPTX = bIsNamespace ? _T("") : _T(""); + std::wstring strXmlPPTX = bIsNamespace ? L"" : L""; - strXmlPPTX += _T(""); + strXmlPPTX += L""; return strXmlPPTX; } @@ -305,7 +305,7 @@ namespace PPT m_bShapePreset = false; - } + } CShapeElement::CShapeElement::CShapeElement() : CElement() { m_lShapeType = 0x1000; @@ -327,10 +327,10 @@ namespace PPT //virtual void NormalizeCoordsByMetric() //{ // CElement::NormalizeCoordsByMetric(); - + // double dScaleX = (double)m_oMetric.m_lUnitsHor / m_oMetric.m_lMillimetresHor; // double dScaleY = (double)m_oMetric.m_lUnitsVer / m_oMetric.m_lMillimetresVer; - + // m_pShape->m_oText.m_oBounds.left = (int)(dScaleX * m_pShape->m_oText.m_oBounds.left); // m_pShape->m_oText.m_oBounds.right = (int)(dScaleX * m_pShape->m_oText.m_oBounds.right); // m_pShape->m_oText.m_oBounds.top = (int)(dScaleY * m_pShape->m_oText.m_oBounds.top); @@ -373,7 +373,7 @@ namespace PPT if (NULL == pPPTShape) { // такого быть не может - return _T(""); + return L""; } NSGuidesVML::CFormParam pParamCoef; @@ -389,27 +389,27 @@ namespace PPT { if (bIsNamespace) { - return _T(""); + return L""; } - return _T(""); + return L""; } else if (pPPTShape->m_eType == PPTShapes::sptCLine) { if (bIsNamespace) { - return _T(""); + return L""; } - return _T(""); + return L""; } else if (pPPTShape->m_eType == PPTShapes::sptCEllipse) { if (bIsNamespace) { - return _T(""); + return L""; } - return _T(""); + return L""; } - std::wstring strXmlPPTX = bIsNamespace ? _T("") : _T(""); + std::wstring strXmlPPTX = bIsNamespace ? L"" : L""; CFormulaConverter pFormulaConverter; @@ -454,43 +454,60 @@ namespace PPT //adj---------------------------- if (pFormulaConverter.m_oAdjRes.GetSize() == 0) - strXmlPPTX += _T(""); + strXmlPPTX += L""; else - strXmlPPTX += _T("") + pFormulaConverter.m_oAdjRes.GetXmlString() + _T(""); + strXmlPPTX += L"" + pFormulaConverter.m_oAdjRes.GetXmlString() + L""; //guids-------------------------- if (pFormulaConverter.m_oGuidsRes.GetSize() == 0) - strXmlPPTX += _T("") + pFormulaConverter.m_oCoef.GetXmlString() + _T(""); + strXmlPPTX += L"" + pFormulaConverter.m_oCoef.GetXmlString() + L""; else - strXmlPPTX += _T("") + pFormulaConverter.m_oCoef.GetXmlString() + pFormulaConverter.m_oGuidsRes.GetXmlString() + _T(""); + strXmlPPTX += L"" + pFormulaConverter.m_oCoef.GetXmlString() + pFormulaConverter.m_oGuidsRes.GetXmlString() + L""; //handles--------------------------- if (pFormulaConverter.m_oHandleRes.GetSize() == 0) - strXmlPPTX += _T(""); + strXmlPPTX += L""; else - strXmlPPTX += _T("") + pFormulaConverter.m_oHandleRes.GetXmlString() + _T(""); + strXmlPPTX += L"" + pFormulaConverter.m_oHandleRes.GetXmlString() + L""; //connectors------------------------- - strXmlPPTX += _T(""); + strXmlPPTX += L""; //textRect--------------------------- if (pFormulaConverter.m_oTextRect.GetSize() != 0) strXmlPPTX += pFormulaConverter.m_oTextRect.GetXmlString(); //path------------------------------ - strXmlPPTX += _T(""); + strXmlPPTX += L""; strXmlPPTX += pFormulaConverter.m_oPathRes.GetXmlString(); - strXmlPPTX += _T(""); + strXmlPPTX += L""; } else { - return _T(""); + return L""; } - strXmlPPTX += _T(""); + strXmlPPTX += L""; return strXmlPPTX; } + COleObjectElement::COleObjectElement() : CImageElement() + { + m_etType = etOleObject; + } + COleObjectElement::~COleObjectElement() + { + } + CElementPtr COleObjectElement::CreateDublicate() + { + COleObjectElement* pOleObjectElement = new COleObjectElement(); + CElementPtr pElement = CElementPtr(pOleObjectElement); + SetProperiesToDublicate(pElement); + + pOleObjectElement->m_strOleName = m_strOleName; + pOleObjectElement->m_strProgId = m_strProgId; + return pElement; + } CAudioElement::CAudioElement() : CImageElement() { m_etType = etAudio; @@ -604,12 +621,12 @@ namespace PPT int CTableElement::GetWidth()const { double multip = m_bAnchorEnabled ? 1587.5 : 1; - return round(m_rcAnchor.GetWidth() * multip); + return round(m_rcAnchor.GetWidth() * multip); } int CTableElement::GetHeight()const { double multip = m_bAnchorEnabled ? 1587.5 : 1; - return round(m_rcAnchor.GetHeight() * multip); + return round(m_rcAnchor.GetHeight() * multip); } std::wstring CTableElement::ConvertPPTShapeToPPTX(bool bIsNamespace) { diff --git a/MsBinaryFile/PptFile/Drawing/Elements.h b/MsBinaryFile/PptFile/Drawing/Elements.h index 3e813fd6776..34e4bdd5cd1 100644 --- a/MsBinaryFile/PptFile/Drawing/Elements.h +++ b/MsBinaryFile/PptFile/Drawing/Elements.h @@ -101,7 +101,19 @@ class CShapeElement : public CElement std::wstring ConvertPPTShapeToPPTX(bool bIsNamespace = false); std::wstring ConvertPPTtoPPTX(CPPTShape* pPPTShape, const NSGuidesVML::CFormParam& pCoef, bool bIsNamespace = false); }; +class COleObjectElement : public CImageElement +{ +public: + std::wstring m_strBinFileName; + + std::wstring m_strOleName; + std::wstring m_strProgId; + COleObjectElement(); + virtual ~COleObjectElement(); + + virtual CElementPtr CreateDublicate(); +}; class CAudioElement : public CImageElement { public: diff --git a/MsBinaryFile/PptFile/Drawing/Layout.cpp b/MsBinaryFile/PptFile/Drawing/Layout.cpp index a7220e6b6a0..e8a11daac16 100644 --- a/MsBinaryFile/PptFile/Drawing/Layout.cpp +++ b/MsBinaryFile/PptFile/Drawing/Layout.cpp @@ -32,7 +32,7 @@ #include "Layout.h" -void PPT::CorrectPlaceholderType(int &type) +void PPT::CorrectPlaceholderType(int& type) { switch (type) { @@ -83,20 +83,20 @@ void PPT::CLayout::Clear() m_arElements.clear(); m_mapPlaceholders.clear(); - m_bIsTitleMaster = false; + m_bIsTitleMaster = false; - m_bHasDate = false; - m_bHasSlideNumber = false; - m_bHasFooter = false; - m_nFormatDate = 1; + m_bHasDate = false; + m_bHasSlideNumber = false; + m_bHasFooter = false; + m_nFormatDate = 1; - for (int i = 0 ; i < 3 ; i++) + for (int i = 0; i < 3; i++) m_PlaceholdersReplaceString[i].clear(); - m_bUseThemeColorScheme = true; - m_bShowMasterShapes = true; - m_strLayoutType = _T("obj"); - m_bIsBackground = false; + m_bUseThemeColorScheme = true; + m_bShowMasterShapes = true; + m_strLayoutType = L"obj"; + m_bIsBackground = false; } void PPT::CLayout::CreateDublicateElements() @@ -145,7 +145,7 @@ LONG PPT::CLayout::GetCountPlaceholderWithType(LONG lType) return lFound; } -ODRAW::CColor PPT::CLayout::GetColor(const LONG &lIndexScheme) +ODRAW::CColor PPT::CLayout::GetColor(const LONG& lIndexScheme) { if (lIndexScheme < (LONG)m_arColorScheme.size()) { @@ -154,14 +154,14 @@ ODRAW::CColor PPT::CLayout::GetColor(const LONG &lIndexScheme) return ODRAW::CColor(); } -void PPT::CLayout::CheckPlaceholderStyle(std::wstring strStyleName, LONG &lType, LONG &lLevel, LONG &lTypeStyle) +void PPT::CLayout::CheckPlaceholderStyle(std::wstring strStyleName, LONG& lType, LONG& lLevel, LONG& lTypeStyle) { - size_t nLen = strStyleName.length(); - wchar_t* pData = (wchar_t*)strStyleName.c_str(); + size_t nLen = strStyleName.length(); + wchar_t* pData = (wchar_t*)strStyleName.c_str(); - lType = 0; - lLevel = 0; - lTypeStyle = -1; + lType = 0; + lLevel = 0; + lTypeStyle = -1; wchar_t* pDataEnd = pData + nLen; wchar_t* pDataMem = pData + 1; diff --git a/MsBinaryFile/PptFile/Drawing/Shapes/Shape.h b/MsBinaryFile/PptFile/Drawing/Shapes/Shape.h index 566c30e3089..552b857c5e8 100644 --- a/MsBinaryFile/PptFile/Drawing/Shapes/Shape.h +++ b/MsBinaryFile/PptFile/Drawing/Shapes/Shape.h @@ -206,7 +206,7 @@ class CShape virtual bool LoadFromXML(XmlUtils::CXmlNode& root) { - if(_T("ooxml-shape") == root.GetName()) + if(L"ooxml-shape" == root.GetName()) { m_pShape = CBaseShapePtr(new CPPTXShape()); @@ -214,7 +214,7 @@ class CShape return pptx_shape ? pptx_shape->LoadFromXML(root) : false; } - else if(_T("shape") == root.GetName()) + else if(L"shape" == root.GetName()) { m_pShape = CBaseShapePtr(new CPPTShape()); @@ -264,23 +264,23 @@ class CShape void SetPen(XmlUtils::CXmlNode& oNodePict) { XmlUtils::CXmlNode oNodeTemplate; - if (oNodePict.GetNode(_T("stroke"), oNodeTemplate)) + if (oNodePict.GetNode(L"stroke", oNodeTemplate)) { - std::wstring strColor = oNodeTemplate.GetAttributeOrValue(_T("strokecolor")); - //if (strColor != _T("")) + std::wstring strColor = oNodeTemplate.GetAttributeOrValue(L"strokecolor"); + //if (strColor != L"")) // m_oPen.Color.FromString(strColor); - //std::wstring strSize = oNodeTemplate.GetAttributeOrValue(_T("strokeweight")); - //if (strSize != _T("")) + //std::wstring strSize = oNodeTemplate.GetAttributeOrValue(L"strokeweight")); + //if (strSize != L"")) // m_oPen.Size = XmlUtils::GetDouble(strSize); - //std::wstring strStroke = oNodeTemplate.GetAttributeOrValue(_T("stroked")); - //if (strStroke != _T("")) + //std::wstring strStroke = oNodeTemplate.GetAttributeOrValue(L"stroked")); + //if (strStroke != L"")) // m_oPen.Alpha = 0; } - if (oNodePict.GetNode(_T("v:stroke"), oNodeTemplate)) + if (oNodePict.GetNode(L"v:stroke", oNodeTemplate)) { - std::wstring strColor = oNodeTemplate.GetAttributeOrValue(_T("dashstyle")); - //if (strColor != _T("")) + std::wstring strColor = oNodeTemplate.GetAttributeOrValue(L"dashstyle"); + //if (strColor != L"")) // m_oPen.DashStyle = XmlUtils::GetInteger(strColor); } } @@ -288,22 +288,22 @@ class CShape void SetBrush(XmlUtils::CXmlNode& oNodePict) { XmlUtils::CXmlNode oNodeTemplate; - if (oNodePict.GetNode(_T("fillcolor"), oNodeTemplate)) + if (oNodePict.GetNode(L"fillcolor", oNodeTemplate)) { - std::wstring strColor = oNodeTemplate.GetAttributeOrValue(_T("val")); - //if (strColor != _T("")) + std::wstring strColor = oNodeTemplate.GetAttributeOrValue(L"val"); + //if (strColor != L"")) // m_oBrush.Color1.FromString(strColor); } } void SetCoordPos(XmlUtils::CXmlNode& oNodePict) { - if (_T("shape") == oNodePict.GetName()) + if (L"shape" == oNodePict.GetName()) { XmlUtils::CXmlNode oNodeTemplate; - if (oNodePict.GetNode(_T("coordorigin"), oNodeTemplate)) + if (oNodePict.GetNode(L"coordorigin", oNodeTemplate)) { - std::wstring strCoordSize = oNodeTemplate.GetAttributeOrValue(_T("val")); + std::wstring strCoordSize = oNodeTemplate.GetAttributeOrValue(L"val"); if (!strCoordSize.empty()) { std::vector oArray; @@ -315,8 +315,8 @@ class CShape } else { - std::wstring id = oNodePict.GetAttributeOrValue(_T("type")); - if (id != _T("")) + std::wstring id = oNodePict.GetAttributeOrValue(L"type"); + if (id != L"") { m_dXLogic = 0; m_dYLogic = 0; @@ -324,9 +324,9 @@ class CShape else { XmlUtils::CXmlNode oNodeTemplate; - if (oNodePict.GetNode(_T("template"), oNodeTemplate)) + if (oNodePict.GetNode(L"template", oNodeTemplate)) { - std::wstring strCoordSize = oNodeTemplate.GetAttributeOrValue(_T("coordorigin")); + std::wstring strCoordSize = oNodeTemplate.GetAttributeOrValue(L"coordorigin"); if (!strCoordSize.empty()) { std::vector oArray; @@ -342,13 +342,13 @@ class CShape } void SetCoordSize(XmlUtils::CXmlNode& oNodePict) { - if (_T("shape") == oNodePict.GetName()) + if (L"shape" == oNodePict.GetName()) { XmlUtils::CXmlNode oNodeTemplate; - if (oNodePict.GetNode(_T("coordsize"), oNodeTemplate)) + if (oNodePict.GetNode(L"coordsize", oNodeTemplate)) { - std::wstring strCoordSize = oNodeTemplate.GetAttributeOrValue(_T("val")); - if (strCoordSize != _T("")) + std::wstring strCoordSize = oNodeTemplate.GetAttributeOrValue(L"val"); + if (strCoordSize != L"") { std::vector oArray; boost::algorithm::split(oArray, strCoordSize, boost::algorithm::is_any_of(L","), boost::algorithm::token_compress_on); @@ -359,8 +359,8 @@ class CShape } else { - std::wstring id = oNodePict.GetAttributeOrValue(_T("type")); - if (id != _T("")) + std::wstring id = oNodePict.GetAttributeOrValue(L"type"); + if (id != L"") { m_dWidthLogic = 21600; m_dHeightLogic = 21600; @@ -368,10 +368,10 @@ class CShape else { XmlUtils::CXmlNode oNodeTemplate; - if (oNodePict.GetNode(_T("template"), oNodeTemplate)) + if (oNodePict.GetNode(L"template", oNodeTemplate)) { - std::wstring strCoordSize = oNodeTemplate.GetAttributeOrValue(_T("coordsize")); - if (strCoordSize != _T("")) + std::wstring strCoordSize = oNodeTemplate.GetAttributeOrValue(L"coordsize"); + if (strCoordSize != L"") { std::vector oArray; boost::algorithm::split(oArray, strCoordSize, boost::algorithm::is_any_of(L","), boost::algorithm::token_compress_on); diff --git a/MsBinaryFile/PptFile/Drawing/Slide.cpp b/MsBinaryFile/PptFile/Drawing/Slide.cpp index 89e9cec3762..07d0f77faae 100644 --- a/MsBinaryFile/PptFile/Drawing/Slide.cpp +++ b/MsBinaryFile/PptFile/Drawing/Slide.cpp @@ -57,6 +57,7 @@ void CSlide::Clear() m_dEndTime = 0.0; m_dDuration = 30000.0; + m_bHidden = false; m_bShowMasterShapes = true; m_strComment.clear(); m_sName.clear(); @@ -91,6 +92,7 @@ CSlide::CSlide(const CSlide &oSrc) m_bIsBackground = oSrc.m_bIsBackground; m_oBackground = oSrc.m_oBackground; + m_bHidden = oSrc.m_bHidden; m_bShowMasterShapes = oSrc.m_bShowMasterShapes; for (int i = 0 ; i < 3 ; i++) m_PlaceholdersReplaceString[i] = oSrc.m_PlaceholdersReplaceString[i]; diff --git a/MsBinaryFile/PptFile/Drawing/Slide.h b/MsBinaryFile/PptFile/Drawing/Slide.h index 49a3782984c..f6491550b4f 100644 --- a/MsBinaryFile/PptFile/Drawing/Slide.h +++ b/MsBinaryFile/PptFile/Drawing/Slide.h @@ -61,6 +61,7 @@ class CSlide std::vector m_arColorScheme; bool m_bUseLayoutColorScheme; bool m_bShowMasterShapes; + bool m_bHidden; vector_string m_PlaceholdersReplaceString[3]; std::wstring m_strComment; diff --git a/MsBinaryFile/PptFile/Drawing/TextStructures.cpp b/MsBinaryFile/PptFile/Drawing/TextStructures.cpp index e2a4f8094d2..488c2ccf539 100644 --- a/MsBinaryFile/PptFile/Drawing/TextStructures.cpp +++ b/MsBinaryFile/PptFile/Drawing/TextStructures.cpp @@ -46,53 +46,53 @@ if (oSrc.##EXIST_PARAM) \ PARAM = oSrc.##PARAM; \ } -std::wstring ToNode(const NSCommon::nullable_base &prop, const std::wstring &strName) +std::wstring ToNode(const NSCommon::nullable_base& prop, const std::wstring& strName) { if (!prop.is_init()) return L""; - return _T("<") + strName + _T(">") + std::to_wstring( (int)prop.get() ) + _T(""); + return L"<" + strName + L">" + std::to_wstring((int)prop.get()) + L""; } -std::wstring ToNode(const NSCommon::nullable_base &prop, const std::wstring &strName) +std::wstring ToNode(const NSCommon::nullable_base& prop, const std::wstring& strName) { if (!prop.is_init()) return L""; - return _T("<") + strName + _T(">") + std::to_wstring( (int)prop.get() ) + _T(""); + return L"<" + strName + L">" + std::to_wstring((int)prop.get()) + L""; } -std::wstring ToNode(const NSCommon::nullable_base<_UINT32> &prop, const std::wstring &strName) +std::wstring ToNode(const NSCommon::nullable_base<_UINT32>& prop, const std::wstring& strName) { if (!prop.is_init()) return L""; - return _T("<") + strName + _T(">") + std::to_wstring((int)prop.get()) + _T(""); + return L"<" + strName + L">" + std::to_wstring((int)prop.get()) + L""; } -std::wstring ToNode(const NSCommon::nullable_base &prop, const std::wstring &strName) +std::wstring ToNode(const NSCommon::nullable_base& prop, const std::wstring& strName) { if (!prop.is_init()) return L""; - return _T("<") + strName + _T(">") + XmlUtils::ToString(prop.get()) + _T(""); + return L"<" + strName + L">" + XmlUtils::ToString(prop.get()) + L""; } -std::wstring ToNode(const NSCommon::nullable_base &prop, const std::wstring &strName) +std::wstring ToNode(const NSCommon::nullable_base& prop, const std::wstring& strName) { if (!prop.is_init()) return L""; - return _T("<") + strName + _T(">") + std::to_wstring((unsigned int)prop->GetLONG()) + _T(""); + return L"<" + strName + L">" + std::to_wstring((unsigned int)prop->GetLONG()) + L""; } PPT::CFontProperty::CFontProperty() : PitchFamily(0), Charset(0) {} -PPT::CFontProperty::CFontProperty(const CFontProperty &oSrc) +PPT::CFontProperty::CFontProperty(const CFontProperty& oSrc) { *this = oSrc; } -PPT::CFontProperty &PPT::CFontProperty::operator=(const CFontProperty &oSrc) +PPT::CFontProperty& PPT::CFontProperty::operator=(const CFontProperty& oSrc) { - Name = oSrc.Name; - PitchFamily = oSrc.PitchFamily; - Charset = oSrc.Charset; + Name = oSrc.Name; + PitchFamily = oSrc.PitchFamily; + Charset = oSrc.Charset; return *this; } @@ -113,7 +113,7 @@ bool PPT::CFontProperty::IsValidCharset(int value) if (value <= 0 || value > 255) return false; - std::set BLCharset = {128, 136, 129}; + std::set BLCharset = { 128, 136, 129 }; return BLCharset.find(value) == BLCharset.end(); } @@ -122,28 +122,28 @@ bool PPT::CFontProperty::IsValidPitchFamily(int value) if (value <= 0 || value > 255) return false; - std::set BLPitchFamily = { 0x00, 0x01, 0x02, 0x10, 0x11, 0x12, 0x20, 0x21, 0x22, 0x30, 0x31, 0x32, 0x40, 0x41, 0x42, 0x50, 0x51, 0x52}; + std::set BLPitchFamily = { 0x00, 0x01, 0x02, 0x10, 0x11, 0x12, 0x20, 0x21, 0x22, 0x30, 0x31, 0x32, 0x40, 0x41, 0x42, 0x50, 0x51, 0x52 }; return BLPitchFamily.find(value) != BLPitchFamily.end(); } bool PPT::CBulletAutoNum::isDefault() const { return type.get_value_or(L"arabicPeriod") == L"arabicPeriod" && - (startAt.is_init() ? *startAt == 1 : true); + (startAt.is_init() ? *startAt == 1 : true); } PPT::CFontProperties::CFontProperties() { } -PPT::CFontProperties::CFontProperties(const CFontProperties &oSrc) +PPT::CFontProperties::CFontProperties(const CFontProperties& oSrc) { *this = oSrc; } -PPT::CFontProperties &PPT::CFontProperties::operator=(const CFontProperties &oSrc) +PPT::CFontProperties& PPT::CFontProperties::operator=(const CFontProperties& oSrc) { - font = oSrc.font; - ansi = oSrc.ansi; - ea = oSrc.ea; - sym = oSrc.sym; + font = oSrc.font; + ansi = oSrc.ansi; + ea = oSrc.ea; + sym = oSrc.sym; return *this; } @@ -152,37 +152,37 @@ PPT::CTextCFRun::CTextCFRun() { } -PPT::CTextCFRun::CTextCFRun(const CTextCFRun &oSrc) +PPT::CTextCFRun::CTextCFRun(const CTextCFRun& oSrc) { *this = oSrc; } -PPT::CTextCFRun &PPT::CTextCFRun::operator=(const CTextCFRun &oSrc) +PPT::CTextCFRun& PPT::CTextCFRun::operator=(const CTextCFRun& oSrc) { - FontBold = oSrc.FontBold; - FontItalic = oSrc.FontItalic; - FontUnderline = oSrc.FontUnderline; - FontStrikeout = oSrc.FontStrikeout; - FontShadow = oSrc.FontShadow; + FontBold = oSrc.FontBold; + FontItalic = oSrc.FontItalic; + FontUnderline = oSrc.FontUnderline; + FontStrikeout = oSrc.FontStrikeout; + FontShadow = oSrc.FontShadow; - fontRef = oSrc.fontRef; - eaFontRef = oSrc.eaFontRef; - ansiFontRef = oSrc.ansiFontRef; - symbolFontRef = oSrc.symbolFontRef; - pp9rt = oSrc.pp9rt; - BaseLineOffset = oSrc.BaseLineOffset; + fontRef = oSrc.fontRef; + eaFontRef = oSrc.eaFontRef; + ansiFontRef = oSrc.ansiFontRef; + symbolFontRef = oSrc.symbolFontRef; + pp9rt = oSrc.pp9rt; + BaseLineOffset = oSrc.BaseLineOffset; - Color = oSrc.Color; - Size = oSrc.Size; + Color = oSrc.Color; + Size = oSrc.Size; - font = oSrc.font; - font.ea = oSrc.font.ea; - font.ansi = oSrc.font.ansi; - font.sym = oSrc.font.sym; + font = oSrc.font; + font.ea = oSrc.font.ea; + font.ansi = oSrc.font.ansi; + font.sym = oSrc.font.sym; - Cap = oSrc.Cap; + Cap = oSrc.Cap; - Language = oSrc.Language; + Language = oSrc.Language; return *this; } @@ -190,7 +190,7 @@ PPT::CTextCFRun::~CTextCFRun() { } -void PPT::CTextCFRun::ApplyBefore(const CTextCFRun &oSrc) +void PPT::CTextCFRun::ApplyBefore(const CTextCFRun& oSrc) { if (!FontBold.is_init()) FontBold = oSrc.FontBold; if (!FontItalic.is_init()) FontItalic = oSrc.FontItalic; @@ -208,15 +208,15 @@ void PPT::CTextCFRun::ApplyBefore(const CTextCFRun &oSrc) if (!Size.is_init()) Size = oSrc.Size; if (!Cap.is_init()) Cap = oSrc.Cap; - if (!font.font.is_init()) font.font = oSrc.font.font; - if (!font.ansi.is_init()) font.ansi = oSrc.font.ansi; - if (!font.ea.is_init()) font.ea = oSrc.font.ea; - if (!font.sym.is_init()) font.sym = oSrc.font.sym; + if (!font.font.is_init()) font.font = oSrc.font.font; + if (!font.ansi.is_init()) font.ansi = oSrc.font.ansi; + if (!font.ea.is_init()) font.ea = oSrc.font.ea; + if (!font.sym.is_init()) font.sym = oSrc.font.sym; if (!Language.is_init()) Language = oSrc.Language; } -void PPT::CTextCFRun::ApplyAfter(const CTextCFRun &oSrc) +void PPT::CTextCFRun::ApplyAfter(const CTextCFRun& oSrc) { if (oSrc.FontBold.is_init()) FontBold = oSrc.FontBold; if (oSrc.FontItalic.is_init()) FontItalic = oSrc.FontItalic; @@ -258,59 +258,59 @@ PPT::CTextPFRun::CTextPFRun() : bIsOneLine(false) { } -PPT::CTextPFRun::CTextPFRun(const CTextPFRun &oSrc) +PPT::CTextPFRun::CTextPFRun(const CTextPFRun& oSrc) { *this = oSrc; } -PPT::CTextPFRun &PPT::CTextPFRun::operator =(const CTextPFRun &oSrc) +PPT::CTextPFRun& PPT::CTextPFRun::operator =(const CTextPFRun& oSrc) { - hasBullet = oSrc.hasBullet; + hasBullet = oSrc.hasBullet; - bulletFontRef = oSrc.bulletFontRef; - bulletSize = oSrc.bulletSize; - bulletChar = oSrc.bulletChar; - bulletColor = oSrc.bulletColor; + bulletFontRef = oSrc.bulletFontRef; + bulletSize = oSrc.bulletSize; + bulletChar = oSrc.bulletChar; + bulletColor = oSrc.bulletColor; bulletFontProperties = oSrc.bulletFontProperties; - bulletAutoNum = oSrc.bulletAutoNum; + bulletAutoNum = oSrc.bulletAutoNum; - textAlignment = oSrc.textAlignment; - lineSpacing = oSrc.lineSpacing; - spaceBefore = oSrc.spaceBefore; - spaceAfter = oSrc.spaceAfter; - leftMargin = oSrc.leftMargin; - indent = oSrc.indent; - defaultTabSize = oSrc.defaultTabSize; + textAlignment = oSrc.textAlignment; + lineSpacing = oSrc.lineSpacing; + spaceBefore = oSrc.spaceBefore; + spaceAfter = oSrc.spaceAfter; + leftMargin = oSrc.leftMargin; + indent = oSrc.indent; + defaultTabSize = oSrc.defaultTabSize; - tabStops = oSrc.tabStops; + tabStops = oSrc.tabStops; - fontAlign = oSrc.fontAlign; - textDirection = oSrc.textDirection; - wrapFlags = oSrc.wrapFlags; + fontAlign = oSrc.fontAlign; + textDirection = oSrc.textDirection; + wrapFlags = oSrc.wrapFlags; - bIsOneLine = oSrc.bIsOneLine; + bIsOneLine = oSrc.bIsOneLine; return *this; } -void PPT::CTextPFRun::ApplyBefore(const CTextPFRun &oSrc) +void PPT::CTextPFRun::ApplyBefore(const CTextPFRun& oSrc) { if (!hasBullet.is_init()) { - hasBullet = oSrc.hasBullet; + hasBullet = oSrc.hasBullet; } if (!bulletSize.is_init()) { - bulletSize = oSrc.bulletSize; + bulletSize = oSrc.bulletSize; } if (!bulletChar.is_init())//master style (78).ppt { - bulletChar = oSrc.bulletChar; - bulletFontRef = oSrc.bulletFontRef; + bulletChar = oSrc.bulletChar; + bulletFontRef = oSrc.bulletFontRef; } if (!bulletColor.is_init()) { - bulletColor = oSrc.bulletColor; + bulletColor = oSrc.bulletColor; } bulletFontProperties.reset(); bulletAutoNum.reset(); @@ -333,34 +333,34 @@ void PPT::CTextPFRun::ApplyBefore(const CTextPFRun &oSrc) } } -void PPT::CTextPFRun::ApplyAfter(const CTextPFRun &oSrc) +void PPT::CTextPFRun::ApplyAfter(const CTextPFRun& oSrc) { if (oSrc.hasBullet.is_init()) { hasBullet = oSrc.hasBullet; bulletSize = oSrc.bulletSize; - bulletChar = oSrc.bulletChar; - bulletFontRef = oSrc.bulletFontRef; - bulletColor = oSrc.bulletColor; + bulletChar = oSrc.bulletChar; + bulletFontRef = oSrc.bulletFontRef; + bulletColor = oSrc.bulletColor; bulletFontProperties.reset(); bulletAutoNum.reset(); } - if (oSrc.textAlignment.is_init()) textAlignment = oSrc.textAlignment; - if (oSrc.lineSpacing.is_init()) lineSpacing = oSrc.lineSpacing; - if (oSrc.spaceBefore.is_init()) spaceBefore = oSrc.spaceBefore; - if (oSrc.spaceAfter.is_init()) spaceAfter = oSrc.spaceAfter; - if (oSrc.leftMargin.is_init()) leftMargin = oSrc.leftMargin; - if (oSrc.indent.is_init()) indent = oSrc.indent; - if (oSrc.defaultTabSize.is_init()) defaultTabSize = oSrc.defaultTabSize; + if (oSrc.textAlignment.is_init()) textAlignment = oSrc.textAlignment; + if (oSrc.lineSpacing.is_init()) lineSpacing = oSrc.lineSpacing; + if (oSrc.spaceBefore.is_init()) spaceBefore = oSrc.spaceBefore; + if (oSrc.spaceAfter.is_init()) spaceAfter = oSrc.spaceAfter; + if (oSrc.leftMargin.is_init()) leftMargin = oSrc.leftMargin; + if (oSrc.indent.is_init()) indent = oSrc.indent; + if (oSrc.defaultTabSize.is_init()) defaultTabSize = oSrc.defaultTabSize; - if (oSrc.fontAlign.is_init()) fontAlign = oSrc.fontAlign; - if (oSrc.textDirection.is_init()) textDirection = oSrc.textDirection; - if (oSrc.wrapFlags.is_init()) wrapFlags = oSrc.wrapFlags; + if (oSrc.fontAlign.is_init()) fontAlign = oSrc.fontAlign; + if (oSrc.textDirection.is_init()) textDirection = oSrc.textDirection; + if (oSrc.wrapFlags.is_init()) wrapFlags = oSrc.wrapFlags; - if (!oSrc.tabStops.empty()) tabStops = oSrc.tabStops; + if (!oSrc.tabStops.empty()) tabStops = oSrc.tabStops; } std::wstring PPT::CTextPFRun::ToString(LONG lCount) @@ -372,16 +372,16 @@ PPT::CTextRuler::CTextRuler() { } -PPT::CTextRuler::CTextRuler(const CTextRuler &oSrc) +PPT::CTextRuler::CTextRuler(const CTextRuler& oSrc) { *this = oSrc; } -PPT::CTextRuler &PPT::CTextRuler::operator =(const CTextRuler &oSrc) +PPT::CTextRuler& PPT::CTextRuler::operator =(const CTextRuler& oSrc) { - DefaultTabSize = oSrc.DefaultTabSize; - CLevels = oSrc.CLevels; - TabStops = oSrc.TabStops; + DefaultTabSize = oSrc.DefaultTabSize; + CLevels = oSrc.CLevels; + TabStops = oSrc.TabStops; LeftMargin1 = oSrc.LeftMargin1; LeftMargin2 = oSrc.LeftMargin2; @@ -405,10 +405,10 @@ PPT::CTextRuler::~CTextRuler() tabsStops.clear(); } -void PPT::CTextRuler::ApplyBefore(const CTextRuler &oSrc) +void PPT::CTextRuler::ApplyBefore(const CTextRuler& oSrc) { if (!DefaultTabSize.is_init()) DefaultTabSize = oSrc.DefaultTabSize; - if (!CLevels.is_init()) CLevels = oSrc.CLevels; + if (!CLevels.is_init()) CLevels = oSrc.CLevels; if (!LeftMargin1.is_init()) LeftMargin1 = oSrc.LeftMargin1; if (!LeftMargin2.is_init()) LeftMargin2 = oSrc.LeftMargin2; @@ -433,7 +433,7 @@ std::wstring PPT::CTextRuler::ToString() PPT::CTextSIRun::CTextSIRun() { bIsExt = true; - lCount = 0; + lCount = 0; bSpell = false; bLang = false; @@ -453,39 +453,39 @@ PPT::CTextSIRun::CTextSIRun() bGramma = false; } -PPT::CTextSIRun::CTextSIRun(const CTextSIRun &oSrc) +PPT::CTextSIRun::CTextSIRun(const CTextSIRun& oSrc) { *this = oSrc; } -PPT::CTextSIRun &PPT::CTextSIRun::operator =(const CTextSIRun &oSrc) +PPT::CTextSIRun& PPT::CTextSIRun::operator =(const CTextSIRun& oSrc) { - bIsExt = oSrc.bIsExt; - lCount = oSrc.lCount; + bIsExt = oSrc.bIsExt; + lCount = oSrc.lCount; - bSpell = oSrc.bSpell; - bLang = oSrc.bLang; - bAltLang = oSrc.bAltLang; + bSpell = oSrc.bSpell; + bLang = oSrc.bLang; + bAltLang = oSrc.bAltLang; - bPp10ext = oSrc.bPp10ext; - bBidi = oSrc.bBidi; - bSmartTag = oSrc.bSmartTag; + bPp10ext = oSrc.bPp10ext; + bBidi = oSrc.bBidi; + bSmartTag = oSrc.bSmartTag; - Spell = oSrc.Spell; - Lang = oSrc.Lang; - AltLang = oSrc.AltLang; + Spell = oSrc.Spell; + Lang = oSrc.Lang; + AltLang = oSrc.AltLang; - Bidi = oSrc.Bidi; - pp10runid = oSrc.pp10runid; + Bidi = oSrc.Bidi; + pp10runid = oSrc.pp10runid; - bGramma = oSrc.bGramma; + bGramma = oSrc.bGramma; arSmartTags = oSrc.arSmartTags; return *this; } -void PPT::CTextSIRun::ApplyBefore(const CTextSIRun &oSrc) +void PPT::CTextSIRun::ApplyBefore(const CTextSIRun& oSrc) { /* * gcc 4.8 doesn't understand this construction: @@ -538,17 +538,17 @@ PPT::CSpan::CSpan() : m_bField(false), m_bBreak(false) { } -PPT::CSpan::CSpan(const CSpan &oSrc) +PPT::CSpan::CSpan(const CSpan& oSrc) { *this = oSrc; } -PPT::CSpan &PPT::CSpan::operator=(const CSpan &oSrc) +PPT::CSpan& PPT::CSpan::operator=(const CSpan& oSrc) { - m_oRun = oSrc.m_oRun; - m_strText = oSrc.m_strText; - m_bField = oSrc.m_bField; - m_bBreak = oSrc.m_bBreak; + m_oRun = oSrc.m_oRun; + m_strText = oSrc.m_strText; + m_bField = oSrc.m_bField; + m_bBreak = oSrc.m_bBreak; m_arrInteractive = oSrc.m_arrInteractive; return *this; @@ -562,26 +562,26 @@ PPT::CTextStyleLevel::CTextStyleLevel() { } -PPT::CTextStyleLevel::CTextStyleLevel(const CTextStyleLevel &oSrc) +PPT::CTextStyleLevel::CTextStyleLevel(const CTextStyleLevel& oSrc) { *this = oSrc; } -PPT::CTextStyleLevel &PPT::CTextStyleLevel::operator=(const CTextStyleLevel &oSrc) +PPT::CTextStyleLevel& PPT::CTextStyleLevel::operator=(const CTextStyleLevel& oSrc) { - m_oPFRun = oSrc.m_oPFRun; - m_oCFRun = oSrc.m_oCFRun; + m_oPFRun = oSrc.m_oPFRun; + m_oCFRun = oSrc.m_oCFRun; return *this; } -void PPT::CTextStyleLevel::ApplyAfter(const CTextStyleLevel &oSrc) +void PPT::CTextStyleLevel::ApplyAfter(const CTextStyleLevel& oSrc) { m_oPFRun.ApplyAfter(oSrc.m_oPFRun); m_oCFRun.ApplyAfter(oSrc.m_oCFRun); } -void PPT::CTextStyleLevel::ApplyBefore(const CTextStyleLevel &oSrc) +void PPT::CTextStyleLevel::ApplyBefore(const CTextStyleLevel& oSrc) { m_oPFRun.ApplyBefore(oSrc.m_oPFRun); m_oCFRun.ApplyBefore(oSrc.m_oCFRun); @@ -595,12 +595,12 @@ PPT::CTextStyles::CTextStyles() } } -PPT::CTextStyles::CTextStyles(const CTextStyles &oSrc) +PPT::CTextStyles::CTextStyles(const CTextStyles& oSrc) { *this = oSrc; } -PPT::CTextStyles &PPT::CTextStyles::operator=(const CTextStyles &oSrc) +PPT::CTextStyles& PPT::CTextStyles::operator=(const CTextStyles& oSrc) { for (int i = 0; i < 10; ++i) { @@ -609,7 +609,7 @@ PPT::CTextStyles &PPT::CTextStyles::operator=(const CTextStyles &oSrc) return *this; } -void PPT::CTextStyles::SetStyles(CTextStyles *pStyles) +void PPT::CTextStyles::SetStyles(CTextStyles* pStyles) { for (int i = 0; i < 10; ++i) { @@ -617,7 +617,7 @@ void PPT::CTextStyles::SetStyles(CTextStyles *pStyles) } } -void PPT::CTextStyles::SetLanguage(nullable &language) +void PPT::CTextStyles::SetLanguage(nullable& language) { if (!language.is_init()) return; @@ -630,7 +630,7 @@ void PPT::CTextStyles::SetLanguage(nullable &language) } } -void PPT::CTextStyles::ApplyAfter(const CTextStyles &oSrc) +void PPT::CTextStyles::ApplyAfter(const CTextStyles& oSrc) { for (int i = 0; i < 10; ++i) { @@ -646,7 +646,7 @@ void PPT::CTextStyles::ApplyAfter(const CTextStyles &oSrc) } } -void PPT::CTextStyles::ApplyBefore(const CTextStyles &oSrc) +void PPT::CTextStyles::ApplyBefore(const CTextStyles& oSrc) { for (int i = 0; i < 10; ++i) { @@ -664,25 +664,25 @@ void PPT::CTextStyles::ApplyBefore(const CTextStyles &oSrc) PPT::CParagraph::CParagraph() { - m_lTextType = -1; - m_lTextLevel = 0; - m_lStyleThemeIndex = -1; + m_lTextType = -1; + m_lTextLevel = 0; + m_lStyleThemeIndex = -1; } -PPT::CParagraph::CParagraph(const CParagraph &oSrc) +PPT::CParagraph::CParagraph(const CParagraph& oSrc) { *this = oSrc; } -PPT::CParagraph &PPT::CParagraph::operator=(const CParagraph &oSrc) +PPT::CParagraph& PPT::CParagraph::operator=(const CParagraph& oSrc) { - m_lTextLevel = oSrc.m_lTextLevel; - m_lTextType = oSrc.m_lTextType; - m_lStyleThemeIndex = oSrc.m_lStyleThemeIndex; + m_lTextLevel = oSrc.m_lTextLevel; + m_lTextType = oSrc.m_lTextType; + m_lStyleThemeIndex = oSrc.m_lStyleThemeIndex; - m_oPFRun = oSrc.m_oPFRun; + m_oPFRun = oSrc.m_oPFRun; - m_arSpans = oSrc.m_arSpans; + m_arSpans = oSrc.m_arSpans; return *this; } @@ -701,7 +701,7 @@ void PPT::CParagraph::CheckErrors() size_t nCountS = m_arSpans.size(); for (size_t i = 0; i < nCountS; ++i) { - std::replace( m_arSpans[i].m_strText.begin(), m_arSpans[i].m_strText.end(), (wchar_t)(11), (wchar_t)(13)); + std::replace(m_arSpans[i].m_strText.begin(), m_arSpans[i].m_strText.end(), (wchar_t)(11), (wchar_t)(13)); } } diff --git a/MsBinaryFile/PptFile/Main/PPTFormatLib.cpp b/MsBinaryFile/PptFile/Main/PPTFormatLib.cpp index c985bfa9f9a..aebb08fd787 100644 --- a/MsBinaryFile/PptFile/Main/PPTFormatLib.cpp +++ b/MsBinaryFile/PptFile/Main/PPTFormatLib.cpp @@ -53,7 +53,7 @@ COfficePPTFile::~COfficePPTFile() CloseFile(); } -_UINT32 COfficePPTFile::OpenFile(const std::wstring & sFileName, const std::wstring & password, bool &bMacros) +_UINT32 COfficePPTFile::OpenFile(const std::wstring & sFileName, const std::wstring & password, bool &bMacro) { CloseFile(); @@ -76,7 +76,7 @@ _UINT32 COfficePPTFile::OpenFile(const std::wstring & sFileName, const std::wstr PPT::CPPTFileReader* pptReader = (PPT::CPPTFileReader*)m_pReader; pptReader->m_oDocumentInfo.m_strPassword = password; - pptReader->m_oDocumentInfo.m_bMacros = bMacros; + pptReader->m_oDocumentInfo.m_bMacroEnabled = bMacro; if (pptReader->IsPowerPoint() == false) { @@ -98,7 +98,7 @@ _UINT32 COfficePPTFile::OpenFile(const std::wstring & sFileName, const std::wstr //pptReader->ReadEncryptedSummary(); pptReader->ReadDocument(); - bMacros = pptReader->m_oDocumentInfo.m_bMacros; + bMacro = pptReader->m_oDocumentInfo.m_bMacroEnabled; m_Status = READMODE; return S_OK; @@ -109,7 +109,7 @@ bool COfficePPTFile::CloseFile() PPT::CPPTFileReader* r = (PPT::CPPTFileReader*)m_pReader; RELEASEOBJECT(r); m_pReader = NULL; - return S_OK; + return true; } _UINT32 COfficePPTFile::LoadFromFile(std::wstring sSrcFileName, std::wstring sDstPath, std::wstring password, bool &bMacros) diff --git a/MsBinaryFile/PptFile/PPTXWriter/BulletsConverter.cpp b/MsBinaryFile/PptFile/PPTXWriter/BulletsConverter.cpp index 29bf29e884b..036ac05124f 100644 --- a/MsBinaryFile/PptFile/PPTXWriter/BulletsConverter.cpp +++ b/MsBinaryFile/PptFile/PPTXWriter/BulletsConverter.cpp @@ -111,7 +111,7 @@ void BulletsConverter::ConvertPFRun(PPTX::Logic::TextParagraphPr &oPPr, CTextPFR pLnSpc->m_name = L"a:lnSpc"; if (val > 0) - pLnSpc->spcPct = val * 12.5; + pLnSpc->spcPts = val * 12.5; else if (val < 0 && val > -13200) pLnSpc->spcPct = val * -1000; diff --git a/MsBinaryFile/PptFile/PPTXWriter/Converter.cpp b/MsBinaryFile/PptFile/PPTXWriter/Converter.cpp index 2187e856ca7..943564f3c67 100644 --- a/MsBinaryFile/PptFile/PPTXWriter/Converter.cpp +++ b/MsBinaryFile/PptFile/PPTXWriter/Converter.cpp @@ -65,152 +65,156 @@ typedef boost::uuids::detail::md5 MD5; namespace PPT { - static std::string md5(const BYTE* pData, const ULONG dataLen) - { - std::string strHash; - boost::uuids::detail::md5 hash; - boost::uuids::detail::md5::digest_type digest; - - hash.process_bytes(pData, dataLen); - hash.get_digest(digest); - - const auto charDigest = reinterpret_cast(&digest); - boost::algorithm::hex(charDigest, charDigest + sizeof(boost::uuids::detail::md5::digest_type), - std::back_inserter(strHash)); - - return strHash; - } -namespace NSPPTXWriterConst -{ -static std::wstring g_string_rels_presentation = _T("\ + static std::string md5(const BYTE* pData, const ULONG dataLen) + { + std::string strHash; + boost::uuids::detail::md5 hash; + boost::uuids::detail::md5::digest_type digest; + + hash.process_bytes(pData, dataLen); + hash.get_digest(digest); + + const auto charDigest = reinterpret_cast(&digest); + boost::algorithm::hex(charDigest, charDigest + sizeof(boost::uuids::detail::md5::digest_type), + std::back_inserter(strHash)); + + return strHash; + } + namespace NSPPTXWriterConst + { + static std::wstring g_string_rels_presentation = L"\ \ \ \ \ - "); + "; - static std::wstring g_string_core = _T("\ + static std::wstring g_string_core = L"\ \ Slide 1\ 1\ - "); -} - + "; + } -CPPTXWriter::CPPTXWriter(const std::wstring& destPath) : m_strDestPath(destPath) -{ - m_pDocument = NULL; - m_pUserInfo = NULL; - m_pShapeWriter = new CShapeWriter(); -} + CPPTXWriter::CPPTXWriter(const std::wstring& destPath) : m_strDestPath(destPath) + { + m_pDocument = NULL; + m_pUserInfo = NULL; -CPPTXWriter::~CPPTXWriter() -{ - RELEASEOBJECT(m_pShapeWriter); -} + m_pShapeWriter = new CShapeWriter(); + } -void CPPTXWriter::CreateFile(CPPTUserInfo* pUserInfo) -{ - m_pUserInfo = pUserInfo; + CPPTXWriter::~CPPTXWriter() + { + RELEASEOBJECT(m_pShapeWriter); + } - m_pDocument = dynamic_cast(pUserInfo); + void CPPTXWriter::CreateFile(CPPTUserInfo* pUserInfo) + { + m_pUserInfo = pUserInfo; - m_oManager.Clear(); - m_oManager.SetDstMedia(m_strDestPath + FILE_SEPARATOR_STR + _T("ppt") + FILE_SEPARATOR_STR + _T("media") + FILE_SEPARATOR_STR); + m_pDocument = dynamic_cast(pUserInfo); - m_pShapeWriter->InitNextId(); + m_oManager.Clear(); + m_oManager.SetDstMedia(m_strDestPath + FILE_SEPARATOR_STR + L"ppt" + FILE_SEPARATOR_STR + L"media" + FILE_SEPARATOR_STR); + m_oManager.SetDstEmbeddings(m_strDestPath + FILE_SEPARATOR_STR + L"ppt" + FILE_SEPARATOR_STR + L"embeddings" + FILE_SEPARATOR_STR); + + m_oManager.SetTempMedia(m_pUserInfo->m_pDocumentInfo->m_pCommonInfo->tempPath); + + m_pShapeWriter->InitNextId(); - NSDirectory::CreateDirectory(m_strDestPath); - NSFile::CFileBinary oFile; - std::wstring strMemory; + NSDirectory::CreateDirectory(m_strDestPath); + NSFile::CFileBinary oFile; + std::wstring strMemory; - // _rels - NSDirectory::CreateDirectory(m_strDestPath + FILE_SEPARATOR_STR + _T("_rels")); + // _rels + NSDirectory::CreateDirectory(m_strDestPath + FILE_SEPARATOR_STR + L"_rels"); - oFile.CreateFileW(m_strDestPath + FILE_SEPARATOR_STR + _T("_rels") + FILE_SEPARATOR_STR + _T(".rels")); - strMemory = NSPPTXWriterConst::g_string_rels_presentation; - oFile.WriteStringUTF8(strMemory); - oFile.CloseFile(); + oFile.CreateFileW(m_strDestPath + FILE_SEPARATOR_STR + L"_rels" + FILE_SEPARATOR_STR + L".rels"); + strMemory = NSPPTXWriterConst::g_string_rels_presentation; + oFile.WriteStringUTF8(strMemory); + oFile.CloseFile(); - // docProps - NSDirectory::CreateDirectory(m_strDestPath + FILE_SEPARATOR_STR + _T("docProps")); + // docProps + NSDirectory::CreateDirectory(m_strDestPath + FILE_SEPARATOR_STR + L"docProps"); - // core - oFile.CreateFileW(m_strDestPath + FILE_SEPARATOR_STR + _T("docProps") + FILE_SEPARATOR_STR + _T("core.xml")); - if (m_xmlCore.empty()) - m_xmlCore = NSPPTXWriterConst::g_string_core; - oFile.WriteStringUTF8(m_xmlCore); - oFile.CloseFile(); + // core + oFile.CreateFileW(m_strDestPath + FILE_SEPARATOR_STR + L"docProps" + FILE_SEPARATOR_STR + L"core.xml"); + if (m_xmlCore.empty()) + m_xmlCore = NSPPTXWriterConst::g_string_core; + oFile.WriteStringUTF8(m_xmlCore); + oFile.CloseFile(); - // app - oFile.CreateFileW(m_strDestPath + FILE_SEPARATOR_STR + _T("docProps") + FILE_SEPARATOR_STR + _T("app.xml")); - WriteApp(oFile); - oFile.CloseFile(); + // app + oFile.CreateFileW(m_strDestPath + FILE_SEPARATOR_STR + L"docProps" + FILE_SEPARATOR_STR + L"app.xml"); + WriteApp(oFile); + oFile.CloseFile(); - // content types - WriteContentTypes(); + // content types + WriteContentTypes(); - // ppt - NSDirectory::CreateDirectory(m_strDestPath + FILE_SEPARATOR_STR + _T("ppt")); - WritePresInfo(); + // ppt + NSDirectory::CreateDirectory(m_strDestPath + FILE_SEPARATOR_STR + L"ppt"); + WritePresInfo(); - WriteAll(); -} + WriteAll(); + } -void CPPTXWriter::CreateFile(CDocument* pDocument) -{ - m_pDocument = pDocument; - m_oManager.Clear(); - m_oManager.SetDstMedia(m_strDestPath + FILE_SEPARATOR_STR + _T("ppt") + FILE_SEPARATOR_STR + _T("media") + FILE_SEPARATOR_STR); + void CPPTXWriter::CreateFile(CDocument* pDocument) + { + m_pDocument = pDocument; + m_oManager.Clear(); + m_oManager.SetDstMedia(m_strDestPath + FILE_SEPARATOR_STR + L"ppt" + FILE_SEPARATOR_STR + L"media" + FILE_SEPARATOR_STR); + m_oManager.SetDstEmbeddings(m_strDestPath + FILE_SEPARATOR_STR + L"ppt" + FILE_SEPARATOR_STR + L"embeddings" + FILE_SEPARATOR_STR); - m_pShapeWriter->InitNextId(); + m_pShapeWriter->InitNextId(); - NSDirectory::CreateDirectory(m_strDestPath); - NSFile::CFileBinary oFile; - std::wstring strMemory = _T(""); + NSDirectory::CreateDirectory(m_strDestPath); + NSFile::CFileBinary oFile; + std::wstring strMemory; - // _rels - NSDirectory::CreateDirectory(m_strDestPath + FILE_SEPARATOR_STR + _T("_rels")); + // _rels + NSDirectory::CreateDirectory(m_strDestPath + FILE_SEPARATOR_STR + L"_rels"); - oFile.CreateFileW(m_strDestPath + FILE_SEPARATOR_STR + _T("_rels") + FILE_SEPARATOR_STR + _T(".rels")); - strMemory = NSPPTXWriterConst::g_string_rels_presentation; - oFile.WriteStringUTF8(strMemory); - oFile.CloseFile(); + oFile.CreateFileW(m_strDestPath + FILE_SEPARATOR_STR + L"_rels" + FILE_SEPARATOR_STR + L".rels"); + strMemory = NSPPTXWriterConst::g_string_rels_presentation; + oFile.WriteStringUTF8(strMemory); + oFile.CloseFile(); - // docProps - NSDirectory::CreateDirectory(m_strDestPath + FILE_SEPARATOR_STR + _T("docProps")); + // docProps + NSDirectory::CreateDirectory(m_strDestPath + FILE_SEPARATOR_STR + L"docProps"); - // core - oFile.CreateFileW(m_strDestPath + FILE_SEPARATOR_STR + _T("docProps") + FILE_SEPARATOR_STR + _T("core.xml")); - strMemory = NSPPTXWriterConst::g_string_core; - oFile.WriteStringUTF8(strMemory); - oFile.CloseFile(); + // core + oFile.CreateFileW(m_strDestPath + FILE_SEPARATOR_STR + L"docProps" + FILE_SEPARATOR_STR + L"core.xml"); + strMemory = NSPPTXWriterConst::g_string_core; + oFile.WriteStringUTF8(strMemory); + oFile.CloseFile(); - // app - oFile.CreateFileW(m_strDestPath + FILE_SEPARATOR_STR + _T("docProps") + FILE_SEPARATOR_STR + _T("app.xml")); - WriteApp(oFile); - oFile.CloseFile(); + // app + oFile.CreateFileW(m_strDestPath + FILE_SEPARATOR_STR + L"docProps" + FILE_SEPARATOR_STR + L"app.xml"); + WriteApp(oFile); + oFile.CloseFile(); - // content types - WriteContentTypes(); + // content types + WriteContentTypes(); - // ppt - NSDirectory::CreateDirectory(m_strDestPath + FILE_SEPARATOR_STR + _T("ppt")); - WritePresInfo(); + // ppt + NSDirectory::CreateDirectory(m_strDestPath + FILE_SEPARATOR_STR + L"ppt"); + WritePresInfo(); - WriteAll(); -} + WriteAll(); + } -void CPPTXWriter::CloseFile() -{ - m_oManager.Clear(); -} + void CPPTXWriter::CloseFile() + { + m_oManager.Clear(); + } -void CPPTXWriter::WriteContentTypes() -{ - std::wstring strContentTypes = L"\ + void CPPTXWriter::WriteContentTypes() + { + std::wstring strContentTypes = L"\ \ \ \ @@ -220,6 +224,7 @@ void CPPTXWriter::WriteContentTypes() \ \ \ + \ \ \ \ @@ -234,622 +239,926 @@ void CPPTXWriter::WriteContentTypes() \ "; - if (m_pDocument->m_bMacros) - { - strContentTypes += L"\ + if (m_pDocument->m_bMacroEnabled) + { + strContentTypes += L"\ "; - } - else - { - strContentTypes += L""; - } - strContentTypes += L"\ + } + else + { + strContentTypes += L""; + } + strContentTypes += L"\ \ \ \ "; - int nIndexLayout = 1, nIndexTheme = 1; + int nIndexLayout = 1, nIndexTheme = 1; - for (size_t nT = 0; nT < m_pDocument->m_arThemes.size(); nT++, nIndexTheme++) - { - strContentTypes += L"m_arThemes.size(); nT++, nIndexTheme++) + { + strContentTypes += L""; - strContentTypes += L""; - for (size_t nL = 0; nL < m_pDocument->m_arThemes[nT]->m_arLayouts.size(); nL++, nIndexLayout++) - { - strContentTypes += L"m_arThemes[nT]->m_arLayouts.size(); nL++, nIndexLayout++) + { + strContentTypes += L""; + } } - } - if (m_pDocument->m_pNotesMaster) - { - strContentTypes += L"m_pNotesMaster) + { + strContentTypes += L""; - strContentTypes += L""; - } - if (m_pDocument->m_pHandoutMaster) - { - strContentTypes += L""; + } + if (m_pDocument->m_pHandoutMaster) + { + strContentTypes += L""; - strContentTypes += L""; - } + strContentTypes += L""; + } - for (size_t nS = 0; nS < m_pDocument->m_arSlides.size(); ++nS) - { - strContentTypes += L"m_arSlides.size(); ++nS) + { + strContentTypes += L""; - } + } - for (size_t nS = 0; nS < m_pDocument->m_arNotes.size(); ++nS) - { - strContentTypes += L"m_arNotes.size(); ++nS) + { + strContentTypes += L""; + } + strContentTypes += L""; + + NSFile::CFileBinary oFile; + oFile.CreateFileW(m_strDestPath + FILE_SEPARATOR_STR + L"[Content_Types].xml"); + oFile.WriteStringUTF8(strContentTypes); + oFile.CloseFile(); } - strContentTypes += _T(""); - NSFile::CFileBinary oFile; - oFile.CreateFileW(m_strDestPath + FILE_SEPARATOR_STR + _T("[Content_Types].xml")); - oFile.WriteStringUTF8(strContentTypes); - oFile.CloseFile(); -} + void CPPTXWriter::WriteApp(NSFile::CFileBinary& oFile) + { + if (m_xmlApp.empty()) + { + std::wstringstream strm; -void CPPTXWriter::WriteApp(NSFile::CFileBinary& oFile) -{ - if (m_xmlApp.empty()) - { - std::wstringstream strm; - - CP_XML_WRITER(strm) - { - CP_XML_NODE(L"Properties") - { - CP_XML_ATTR(L"xmlns", L"http://schemas.openxmlformats.org/officeDocument/2006/extended-properties"); - CP_XML_ATTR(L"xmlns:vt", L"http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes"); - - CP_XML_NODE(L"TotalTime") - { - CP_XML_STREAM() << 0; - } - CP_XML_NODE(L"Words") - { - CP_XML_STREAM() << 0; - } - std::wstring sApplication = NSSystemUtils::GetEnvVariable(NSSystemUtils::gc_EnvApplicationName); - if (sApplication.empty()) - sApplication = NSSystemUtils::gc_EnvApplicationNameDefault; + CP_XML_WRITER(strm) + { + CP_XML_NODE(L"Properties") + { + CP_XML_ATTR(L"xmlns", L"http://schemas.openxmlformats.org/officeDocument/2006/extended-properties"); + CP_XML_ATTR(L"xmlns:vt", L"http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes"); + + CP_XML_NODE(L"TotalTime") + { + CP_XML_STREAM() << 0; + } + CP_XML_NODE(L"Words") + { + CP_XML_STREAM() << 0; + } + std::wstring sApplication = NSSystemUtils::GetEnvVariable(NSSystemUtils::gc_EnvApplicationName); + if (sApplication.empty()) + sApplication = NSSystemUtils::gc_EnvApplicationNameDefault; #if defined(INTVER) - std::string s = VALUE2STR(INTVER); - sApplication += L"/" + std::wstring(s.begin(), s.end()); + std::string s = VALUE2STR(INTVER); + sApplication += L"/" + std::wstring(s.begin(), s.end()); #endif - CP_XML_NODE(L"Application") - { - CP_XML_STREAM() << sApplication; - } - //CP_XML_NODE(L"AppVersion") - //{ - // CP_XML_STREAM() << L"1.0"; - //} - CP_XML_NODE(L"Paragraphs") - { - CP_XML_STREAM() << 0; - } - CP_XML_NODE(L"PresentationFormat") - { - CP_XML_STREAM() << L"On-screen Show (4:3)"; - } - CP_XML_NODE(L"Slides") - { - CP_XML_STREAM() << m_pDocument->m_arSlides.size(); - } - CP_XML_NODE(L"Notes") - { - CP_XML_STREAM() << m_pDocument->m_arNotes.size(); - } - CP_XML_NODE(L"HiddenSlides") - { - CP_XML_STREAM() << 0; - } - CP_XML_NODE(L"MMClips") - { - CP_XML_STREAM() << 0; - } - CP_XML_NODE(L"ScaleCrop") - { - CP_XML_STREAM() << L"false"; - } - CP_XML_NODE(L"HeadingPairs") - { - CP_XML_NODE(L"vt:vector") - { - CP_XML_ATTR(L"size", 4); - CP_XML_ATTR(L"baseType", L"variant"); - - CP_XML_NODE(L"vt:variant") - { - CP_XML_NODE(L"vt:lpstr") - { - CP_XML_STREAM() << L"Theme"; - } - } - CP_XML_NODE(L"vt:variant") - { - CP_XML_NODE(L"vt:i4") - { - CP_XML_STREAM() << m_pDocument->m_arThemes.size(); - } - } - CP_XML_NODE(L"vt:variant") - { - CP_XML_NODE(L"vt:lpstr") - { - CP_XML_STREAM() << L"Slide Titles"; - } - } - CP_XML_NODE(L"vt:variant") - { - CP_XML_NODE(L"vt:i4") - CP_XML_STREAM() << m_pDocument->m_arSlides.size(); - } - } - } - CP_XML_NODE(L"TitlesOfParts") - { - CP_XML_NODE(L"vt:vector") - { - CP_XML_ATTR(L"size", m_pDocument->m_arSlides.size() + m_pDocument->m_arThemes.size()); - CP_XML_ATTR(L"baseType", L"lpstr"); - - for (size_t i = 1; i <= m_pDocument->m_arThemes.size(); ++i) - { - CP_XML_NODE(L"vt:lpstr") - { - CP_XML_STREAM() << L"Theme " << i; - } - } - for (size_t i = 1; i <= m_pDocument->m_arSlides.size(); ++i) - { - CP_XML_NODE(L"vt:lpstr") - { - CP_XML_STREAM() << L"Slide " << i; - } - } - } - } - - //CP_XML_NODE(L"Company"); - CP_XML_NODE(L"LinksUpToDate") - { - CP_XML_STREAM() << L"false"; - } - CP_XML_NODE(L"SharedDoc") - { - CP_XML_STREAM() << L"false"; - } - CP_XML_NODE(L"HyperlinksChanged") - { - CP_XML_STREAM() << L"false"; - } - } - } - - m_xmlApp = strm.str(); - } - oFile.WriteStringUTF8(L""); - oFile.WriteStringUTF8(m_xmlApp); -} + CP_XML_NODE(L"Application") + { + CP_XML_STREAM() << sApplication; + } + //CP_XML_NODE(L"AppVersion") + //{ + // CP_XML_STREAM() << L"1.0"; + //} + CP_XML_NODE(L"Paragraphs") + { + CP_XML_STREAM() << 0; + } + CP_XML_NODE(L"PresentationFormat") + { + CP_XML_STREAM() << L"On-screen Show (4:3)"; + } + CP_XML_NODE(L"Slides") + { + CP_XML_STREAM() << m_pDocument->m_arSlides.size(); + } + CP_XML_NODE(L"Notes") + { + CP_XML_STREAM() << m_pDocument->m_arNotes.size(); + } + CP_XML_NODE(L"HiddenSlides") + { + CP_XML_STREAM() << 0; + } + CP_XML_NODE(L"MMClips") + { + CP_XML_STREAM() << 0; + } + CP_XML_NODE(L"ScaleCrop") + { + CP_XML_STREAM() << L"false"; + } + CP_XML_NODE(L"HeadingPairs") + { + CP_XML_NODE(L"vt:vector") + { + CP_XML_ATTR(L"size", 4); + CP_XML_ATTR(L"baseType", L"variant"); -void CPPTXWriter::WritePresInfo() -{ - NSFile::CFileBinary oFile; + CP_XML_NODE(L"vt:variant") + { + CP_XML_NODE(L"vt:lpstr") + { + CP_XML_STREAM() << L"Theme"; + } + } + CP_XML_NODE(L"vt:variant") + { + CP_XML_NODE(L"vt:i4") + { + CP_XML_STREAM() << m_pDocument->m_arThemes.size(); + } + } + CP_XML_NODE(L"vt:variant") + { + CP_XML_NODE(L"vt:lpstr") + { + CP_XML_STREAM() << L"Slide Titles"; + } + } + CP_XML_NODE(L"vt:variant") + { + CP_XML_NODE(L"vt:i4") + CP_XML_STREAM() << m_pDocument->m_arSlides.size(); + } + } + } + CP_XML_NODE(L"TitlesOfParts") + { + CP_XML_NODE(L"vt:vector") + { + CP_XML_ATTR(L"size", m_pDocument->m_arSlides.size() + m_pDocument->m_arThemes.size()); + CP_XML_ATTR(L"baseType", L"lpstr"); + + for (size_t i = 1; i <= m_pDocument->m_arThemes.size(); ++i) + { + CP_XML_NODE(L"vt:lpstr") + { + CP_XML_STREAM() << L"Theme " << i; + } + } + for (size_t i = 1; i <= m_pDocument->m_arSlides.size(); ++i) + { + CP_XML_NODE(L"vt:lpstr") + { + CP_XML_STREAM() << L"Slide " << i; + } + } + } + } + + //CP_XML_NODE(L"Company"); + CP_XML_NODE(L"LinksUpToDate") + { + CP_XML_STREAM() << L"false"; + } + CP_XML_NODE(L"SharedDoc") + { + CP_XML_STREAM() << L"false"; + } + CP_XML_NODE(L"HyperlinksChanged") + { + CP_XML_STREAM() << L"false"; + } + } + } + + m_xmlApp = strm.str(); + } + oFile.WriteStringUTF8(L""); + oFile.WriteStringUTF8(m_xmlApp); + } + + void CPPTXWriter::WritePresInfo() + { + NSFile::CFileBinary oFile; - // tableStyles.xml - oFile.CreateFileW(m_strDestPath + FILE_SEPARATOR_STR + _T("ppt") + FILE_SEPARATOR_STR + _T("tableStyles.xml")); + // tableStyles.xml + oFile.CreateFileW(m_strDestPath + FILE_SEPARATOR_STR + L"ppt" + FILE_SEPARATOR_STR + L"tableStyles.xml"); - oFile.WriteStringUTF8(L"\ + oFile.WriteStringUTF8(L"\ "); - oFile.CloseFile(); + oFile.CloseFile(); - // presProps.xml - oFile.CreateFileW(m_strDestPath + FILE_SEPARATOR_STR + _T("ppt") + FILE_SEPARATOR_STR + _T("presProps.xml")); - oFile.WriteStringUTF8(L"\ + // presProps.xml + oFile.CreateFileW(m_strDestPath + FILE_SEPARATOR_STR + L"ppt" + FILE_SEPARATOR_STR + L"presProps.xml"); + oFile.WriteStringUTF8(L"\ \ \ \ \ \ "); - oFile.CloseFile(); + oFile.CloseFile(); - // viewProps.xml - oFile.CreateFileW(m_strDestPath + FILE_SEPARATOR_STR + _T("ppt") + FILE_SEPARATOR_STR + _T("viewProps.xml")); - oFile.WriteStringUTF8(L"\ + // viewProps.xml + oFile.CreateFileW(m_strDestPath + FILE_SEPARATOR_STR + L"ppt" + FILE_SEPARATOR_STR + L"viewProps.xml"); + oFile.WriteStringUTF8(L"\ \ \ \ \ "); - oFile.CloseFile(); + oFile.CloseFile(); - // presentation.xml + _rels/presentation.xml.rels - std::wstring strPresRels; + // presentation.xml + _rels/presentation.xml.rels + std::wstring strPresRels; - std::wstring strPresMasters; - std::wstring strPresSlides; - std::wstring strNotesIDs; - std::wstring strHandoutIDs; + std::wstring strPresMasters; + std::wstring strPresSlides; + std::wstring strNotesIDs; + std::wstring strHandoutIDs; - size_t nCountLayouts = 0; + size_t nCountLayouts = 0; - for (size_t nIndexTheme = 0; nIndexTheme < m_pDocument->m_arThemes.size(); ++nIndexTheme) - { - strPresRels += L"m_arThemes.size(); ++nIndexTheme) + { + strPresRels += L""; - strPresRels += L""; - strPresMasters += L""; + strPresMasters += L""; - nCountLayouts += m_pDocument->m_arThemes[nIndexTheme]->m_arLayouts.size(); - nCountLayouts += 1; - } + nCountLayouts += m_pDocument->m_arThemes[nIndexTheme]->m_arLayouts.size(); + nCountLayouts += 1; + } - int nCurrentRels = (int)(2 * m_pDocument->m_arThemes.size() + 1); + int nCurrentRels = (int)(2 * m_pDocument->m_arThemes.size() + 1); - if (m_pDocument->m_pNotesMaster) - { - strNotesIDs = L""; - strPresRels += L""; - ++nCurrentRels; - } - if (m_pDocument->m_pHandoutMaster) - { - strHandoutIDs = L""; - strPresRels += L""; - ++nCurrentRels; - } - for (size_t nIndexSlide = 0; nIndexSlide < m_pDocument->m_arSlides.size(); ++nIndexSlide, ++nCurrentRels) - { - strPresRels += L"m_pNotesMaster) + { + strNotesIDs = L""; + strPresRels += L""; + ++nCurrentRels; + } + if (m_pDocument->m_pHandoutMaster) + { + strHandoutIDs = L""; + strPresRels += L""; + ++nCurrentRels; + } + for (size_t nIndexSlide = 0; nIndexSlide < m_pDocument->m_arSlides.size(); ++nIndexSlide, ++nCurrentRels) + { + strPresRels += L""; - strPresSlides += L""; - } - - strPresRels += L""; - strPresRels += L""; - strPresRels += L""; + strPresSlides += L""; + } - if (m_pDocument->m_bMacros) - { - std::wstring strVbaProject = m_strDestPath + FILE_SEPARATOR_STR + _T("ppt") + FILE_SEPARATOR_STR + _T("vbaProject.bin"); + strPresRels += L""; + strPresRels += L""; + strPresRels += L""; - if (CDirectory::CopyFile(m_pDocument->m_sVbaProjectFile, strVbaProject)) + if (m_pDocument->m_bMacroEnabled) { - strPresRels += L""; + std::wstring strVbaProject = m_strDestPath + FILE_SEPARATOR_STR + L"ppt" + FILE_SEPARATOR_STR + L"vbaProject.bin"; + + if (CDirectory::CopyFile(m_pDocument->m_sVbaProjectFile, strVbaProject)) + { + strPresRels += L""; + } } - } - strPresRels = L"" + strPresRels = L"" + strPresRels + L""; - std::wstring strPptRels = m_strDestPath + FILE_SEPARATOR_STR + _T("ppt") + FILE_SEPARATOR_STR + _T("_rels"); + std::wstring strPptRels = m_strDestPath + FILE_SEPARATOR_STR + L"ppt" + FILE_SEPARATOR_STR + L"_rels"; - NSDirectory::CreateDirectory(strPptRels); - oFile.CreateFileW(strPptRels + FILE_SEPARATOR_STR + _T("presentation.xml.rels")); - oFile.WriteStringUTF8(strPresRels); - oFile.CloseFile(); + NSDirectory::CreateDirectory(strPptRels); + oFile.CreateFileW(strPptRels + FILE_SEPARATOR_STR + L"presentation.xml.rels"); + oFile.WriteStringUTF8(strPresRels); + oFile.CloseFile(); - std::wstring strSizePres = L"m_lSlideWidth) + + std::wstring strSizePres = L"m_lSlideWidth) + L"\" cy=\"" + std::to_wstring(m_pDocument->m_lSlideHeight) + L"\" type=\"screen4x3\" />m_lNotesWidth) + L"\" cy=\"" + std::to_wstring(m_pDocument->m_lNotesHeight) + L"\"/>"; - std::wstring strDefaultTextStyle = _T(""); + std::wstring strDefaultTextStyle = L""; - if (false == m_pDocument->m_arThemes.empty()) - { - CStylesWriter styleWriter(m_pDocument->m_arThemes[0].get()); - strDefaultTextStyle += styleWriter.ConvertStyles(m_pDocument->m_arThemes[0]->m_pStyles[0], 9); - } - strDefaultTextStyle += _T(""); + if (false == m_pDocument->m_arThemes.empty()) + { + CStylesWriter styleWriter(m_pDocument->m_arThemes[0].get()); + strDefaultTextStyle += styleWriter.ConvertStyles(m_pDocument->m_arThemes[0]->m_pStyles[0], 9); + } + strDefaultTextStyle += L""; - std::wstring strPres = _T(""); - strPres += _T("m_bRtl)) - { - strPres += _T(" rtl=\"1\""); + std::wstring strPres = L""; + strPres += L"m_bRtl)) + { + strPres += L" rtl=\"1\""; + } + strPres += L">"; + strPres += L"" + strPresMasters + L""; + strPres += strNotesIDs; + strPres += strHandoutIDs; + strPres += L"" + strPresSlides + L""; + strPres += strSizePres; + strPres += strDefaultTextStyle; + strPres += L""; + + oFile.CreateFileW(m_strDestPath + FILE_SEPARATOR_STR + L"ppt" + FILE_SEPARATOR_STR + L"presentation.xml"); + oFile.WriteStringUTF8(strPres); + oFile.CloseFile(); } - strPres += _T(">"); - strPres += _T("") + strPresMasters + _T(""); - strPres += strNotesIDs ; - strPres += strHandoutIDs ; - strPres +=_T("") + strPresSlides + _T(""); - strPres += strSizePres; - strPres += strDefaultTextStyle; - strPres +=_T(""); - - oFile.CreateFileW(m_strDestPath+ FILE_SEPARATOR_STR + _T("ppt") + FILE_SEPARATOR_STR + _T("presentation.xml")); - oFile.WriteStringUTF8(strPres); - oFile.CloseFile(); -} -void CPPTXWriter::WriteAll() -{ - std::wstring strPptDirectory = m_strDestPath + FILE_SEPARATOR_STR + _T("ppt") + FILE_SEPARATOR_STR ; - - NSDirectory::CreateDirectory(strPptDirectory + _T("media")); - NSDirectory::CreateDirectory(strPptDirectory + _T("theme")); - NSDirectory::CreateDirectory(strPptDirectory + _T("slideMasters")); - NSDirectory::CreateDirectory(strPptDirectory + _T("slideMasters") + FILE_SEPARATOR_STR + _T("_rels")); - NSDirectory::CreateDirectory(strPptDirectory + _T("slideLayouts")); - NSDirectory::CreateDirectory(strPptDirectory + _T("slideLayouts") + FILE_SEPARATOR_STR + _T("_rels")); - NSDirectory::CreateDirectory(strPptDirectory + _T("slides")); - NSDirectory::CreateDirectory(strPptDirectory + _T("slides") + FILE_SEPARATOR_STR + _T("_rels")); - - if (m_pDocument->m_pHandoutMaster) - { - NSDirectory::CreateDirectory(strPptDirectory + _T("handoutMasters")); - NSDirectory::CreateDirectory(strPptDirectory + _T("handoutMasters") + FILE_SEPARATOR_STR + _T("_rels")); - } - if (m_pDocument->m_pNotesMaster) + void CPPTXWriter::WriteAll() { - NSDirectory::CreateDirectory(strPptDirectory + _T("notesMasters")); - NSDirectory::CreateDirectory(strPptDirectory + _T("notesMasters") + FILE_SEPARATOR_STR + _T("_rels")); - } - if (!m_pDocument->m_arNotes.empty()) - { - NSDirectory::CreateDirectory(strPptDirectory + _T("notesSlides")); - NSDirectory::CreateDirectory(strPptDirectory + _T("notesSlides") + FILE_SEPARATOR_STR + _T("_rels")); - } - WriteThemes(); - - WriteSlides(); - WriteNotes(); -} + std::wstring strPptDirectory = m_strDestPath + FILE_SEPARATOR_STR + L"ppt" + FILE_SEPARATOR_STR; -// todo reforming and refactoring! -void CPPTXWriter::WriteThemes() -{ - int nStartLayout = 0, nIndexTheme = 0; + NSDirectory::CreateDirectory(strPptDirectory + L"theme"); + NSDirectory::CreateDirectory(strPptDirectory + L"slideMasters"); + NSDirectory::CreateDirectory(strPptDirectory + L"slideMasters" + FILE_SEPARATOR_STR + L"_rels"); + NSDirectory::CreateDirectory(strPptDirectory + L"slideLayouts"); + NSDirectory::CreateDirectory(strPptDirectory + L"slideLayouts" + FILE_SEPARATOR_STR + L"_rels"); + NSDirectory::CreateDirectory(strPptDirectory + L"slides"); + NSDirectory::CreateDirectory(strPptDirectory + L"slides" + FILE_SEPARATOR_STR + L"_rels"); - if (HasRoundTrips() && m_pDocument->m_arThemes.size()) - { - std::unordered_set writedFilesHash; - for (const auto& oIterSlide : m_pUserInfo->m_mapMasters) + if (m_pDocument->m_pHandoutMaster) + { + NSDirectory::CreateDirectory(strPptDirectory + L"handoutMasters"); + NSDirectory::CreateDirectory(strPptDirectory + L"handoutMasters" + FILE_SEPARATOR_STR + L"_rels"); + } + if (m_pDocument->m_pNotesMaster) + { + NSDirectory::CreateDirectory(strPptDirectory + L"notesMasters"); + NSDirectory::CreateDirectory(strPptDirectory + L"notesMasters" + FILE_SEPARATOR_STR + L"_rels"); + } + if (!m_pDocument->m_arNotes.empty()) { - WriteRoundTripTheme(oIterSlide.second, writedFilesHash, nIndexTheme, nStartLayout); + NSDirectory::CreateDirectory(strPptDirectory + L"notesSlides"); + NSDirectory::CreateDirectory(strPptDirectory + L"notesSlides" + FILE_SEPARATOR_STR + L"_rels"); } + WriteThemes(); - writedFilesHash.clear(); - for (const auto& oIterSlide : m_pUserInfo->m_mapNotesMasters) - WriteRoundTripTheme(oIterSlide.second, writedFilesHash, nIndexTheme, nStartLayout); - writedFilesHash.clear(); - for (const auto& oIterSlide : m_pUserInfo->m_mapHandoutMasters) - WriteRoundTripTheme(oIterSlide.second, writedFilesHash, nIndexTheme, nStartLayout); + WriteSlides(); + WriteNotes(); } - else + + // todo reforming and refactoring! + void CPPTXWriter::WriteThemes() { - for (size_t i = 0; i < m_pDocument->m_arThemes.size(); i++) + int nStartLayout = 0, nIndexTheme = 0; + + if (HasRoundTrips() && m_pDocument->m_arThemes.size()) { - m_pShapeWriter->m_pTheme = m_pDocument->m_arThemes[i].get(); - WriteTheme(m_pDocument->m_arThemes[i], nIndexTheme, nStartLayout); - m_pShapeWriter->m_pTheme = NULL; + std::unordered_set writedFilesHash; + for (const auto& oIterSlide : m_pUserInfo->m_mapMasters) + { + WriteRoundTripTheme(oIterSlide.second, writedFilesHash, nIndexTheme, nStartLayout); + } + + writedFilesHash.clear(); + for (const auto& oIterSlide : m_pUserInfo->m_mapNotesMasters) + WriteRoundTripTheme(oIterSlide.second, writedFilesHash, nIndexTheme, nStartLayout); + writedFilesHash.clear(); + for (const auto& oIterSlide : m_pUserInfo->m_mapHandoutMasters) + WriteRoundTripTheme(oIterSlide.second, writedFilesHash, nIndexTheme, nStartLayout); } + else + { + for (size_t i = 0; i < m_pDocument->m_arThemes.size(); i++) + { + m_pShapeWriter->m_pTheme = m_pDocument->m_arThemes[i].get(); + WriteTheme(m_pDocument->m_arThemes[i], nIndexTheme, nStartLayout); + m_pShapeWriter->m_pTheme = NULL; + } - WriteTheme(m_pDocument->m_pNotesMaster, nIndexTheme, nStartLayout); - WriteTheme(m_pDocument->m_pHandoutMaster, nIndexTheme, nStartLayout); + WriteTheme(m_pDocument->m_pNotesMaster, nIndexTheme, nStartLayout); + WriteTheme(m_pDocument->m_pHandoutMaster, nIndexTheme, nStartLayout); + } } -} -bool CPPTXWriter::HasRoundTrips() const -{ - if (m_pUserInfo == nullptr || m_pUserInfo->m_mapMasters.empty() || m_pUserInfo->m_mapMasters.begin()->second == nullptr) - return false; + bool CPPTXWriter::HasRoundTrips() const + { + if (m_pUserInfo == nullptr || m_pUserInfo->m_mapMasters.empty() || m_pUserInfo->m_mapMasters.begin()->second == nullptr) + return false; - std::vector arrRTTheme; - std::vector arrRTLayouts; - std::vector arrRTNotes; - auto pSlide = m_pUserInfo->m_mapMasters.begin()->second; - pSlide->GetRecordsByType(&arrRTLayouts, false, false); - pSlide->GetRecordsByType(&arrRTTheme, false, true); - pSlide->GetRecordsByType(&arrRTNotes, false, true); + std::vector arrRTTheme; + std::vector arrRTLayouts; + std::vector arrRTNotes; + auto pSlide = m_pUserInfo->m_mapMasters.begin()->second; + pSlide->GetRecordsByType(&arrRTLayouts, false, false); + pSlide->GetRecordsByType(&arrRTTheme, false, true); + pSlide->GetRecordsByType(&arrRTNotes, false, true); - if (m_pDocument->m_pNotesMaster && arrRTNotes.empty()) - return false; + if (m_pDocument->m_pNotesMaster && arrRTNotes.empty()) + return false; - if (m_pDocument->m_pHandoutMaster) - { - for (const auto& oIterSlide : m_pUserInfo->m_mapHandoutMasters) + if (m_pDocument->m_pHandoutMaster) { - std::vector arrRTTheme; - oIterSlide.second->GetRecordsByType(&arrRTTheme, false, true); - if (arrRTTheme.empty()) - return false; + for (const auto& oIterSlide : m_pUserInfo->m_mapHandoutMasters) + { + std::vector arrRTTheme; + oIterSlide.second->GetRecordsByType(&arrRTTheme, false, true); + if (arrRTTheme.empty()) + return false; + } } - } - return arrRTTheme.size() && arrRTLayouts.size(); -} + return arrRTTheme.size() && arrRTLayouts.size(); + } -bool CPPTXWriter::WriteRoundTripTheme(const CRecordSlide *pSlide, std::unordered_set& writedFilesHash, int & nIndexTheme, int & nStartLayout) -{ - if (!pSlide) - return false; - - // Write Theme - CRelsGenerator themeRels(&m_oManager); - std::wstring strPptDirectory = m_strDestPath + FILE_SEPARATOR_STR + _T("ppt") + FILE_SEPARATOR_STR ; - std::wstring strThemeDirectory = strPptDirectory + FILE_SEPARATOR + _T("theme"); - if (nIndexTheme == 0) - NSDirectory::CreateDirectory(strThemeDirectory); - - std::vector arrRTTheme; - std::vector arrRTColor; - std::vector arrRTLayouts; - std::vector arrRTMaster; - std::vector arrRTNotes; - pSlide->GetRecordsByType(&arrRTLayouts, false, false); - pSlide->GetRecordsByType(&arrRTTheme, false, true); - pSlide->GetRecordsByType(&arrRTColor, false, true); - pSlide->GetRecordsByType(&arrRTMaster, false, true); - pSlide->GetRecordsByType(&arrRTNotes, false, true); - - const int oldThemeSize = m_pDocument->m_arThemes.size(); - const unsigned oldThemeIndex = nIndexTheme < oldThemeSize ? nIndexTheme : oldThemeSize-1; - if (arrRTLayouts.size()) - m_pShapeWriter->m_pTheme = m_pDocument->m_arThemes[oldThemeIndex].get(); - else if (arrRTNotes.size()) - m_pShapeWriter->m_pTheme = m_pDocument->m_pNotesMaster.get(); - else if (m_pDocument->m_pHandoutMaster.get()) - m_pShapeWriter->m_pTheme = m_pDocument->m_pHandoutMaster.get(); - if (m_pShapeWriter->m_pTheme == nullptr) - return false; - - auto themeType = m_pShapeWriter->m_pTheme->m_eType; - - if (arrRTTheme.empty()) - return false; - - RoundTripExtractor extractor(arrRTTheme[0], m_pUserInfo->m_pDocumentInfo->m_pCommonInfo->tempPath); - - std::wstring oneThemePathS = std::wstring (L"theme") + FILE_SEPARATOR_STR; - std::wstring twoThemePathS = oneThemePathS + std::wstring (L"theme") + FILE_SEPARATOR_STR; - auto strThemePath = extractor.getOneFile(twoThemePathS + L"theme1.xml"); - if (strThemePath.empty()) - return false; - - auto themeRelsPath = extractor.getOneFile(twoThemePathS + L"_rels" + FILE_SEPARATOR_STR + L"theme1.xml.rels"); - auto arrImagesPaths = extractor.find( L".*image[0-9]+.*"); - - BYTE *utf8Data = NULL; - ULONG utf8DataSize = 0; - bool wasThemeWrite = false; - bool needRels = false; - - // read file bytes - NSFile::CFileBinary::ReadAllBytes(strThemePath, &utf8Data, utf8DataSize); - // compare hash - char* pointerToThemeElems = strstr((char*)utf8Data, ""); - UINT hashShift = pointerToThemeElems ? pointerToThemeElems - (char*)utf8Data : 0; - - auto strHash = md5(utf8Data+hashShift, utf8DataSize-hashShift); - - needRels = (int)std::string(utf8Data, utf8Data + utf8DataSize).find("rId") != -1; - - // cp file with new name or write bytes - if (writedFilesHash.find(strHash) == writedFilesHash.end()) + bool CPPTXWriter::WriteRoundTripTheme(const CRecordSlide* pSlide, std::unordered_set& writedFilesHash, int& nIndexTheme, int& nStartLayout) { - std::wstring strThemeFile = L"theme" + std::to_wstring(++nIndexTheme) + L".xml"; - std::wstring outputThemePath = strThemeDirectory + FILE_SEPARATOR_STR + strThemeFile; - NSFile::CFileBinary file; - file.CreateFileW(outputThemePath); - file.WriteFile(utf8Data, utf8DataSize); - file.CloseFile(); + if (!pSlide) + return false; - // clear bytes - RELEASEOBJECT(utf8Data); - utf8DataSize = 0; + // Write Theme + CRelsGenerator themeRels(&m_oManager); + std::wstring strPptDirectory = m_strDestPath + FILE_SEPARATOR_STR + L"ppt" + FILE_SEPARATOR_STR; + std::wstring strThemeDirectory = strPptDirectory + FILE_SEPARATOR + L"theme"; + if (nIndexTheme == 0) + NSDirectory::CreateDirectory(strThemeDirectory); - writedFilesHash.insert(strHash); - wasThemeWrite = true; + std::vector arrRTTheme; + std::vector arrRTColor; + std::vector arrRTLayouts; + std::vector arrRTMaster; + std::vector arrRTNotes; + pSlide->GetRecordsByType(&arrRTLayouts, false, false); + pSlide->GetRecordsByType(&arrRTTheme, false, true); + pSlide->GetRecordsByType(&arrRTColor, false, true); + pSlide->GetRecordsByType(&arrRTMaster, false, true); + pSlide->GetRecordsByType(&arrRTNotes, false, true); - for (auto& strImagePath : arrImagesPaths) - { - themeRels.WriteImage(strImagePath); - } - } + const int oldThemeSize = m_pDocument->m_arThemes.size(); + const unsigned oldThemeIndex = nIndexTheme < oldThemeSize ? nIndexTheme : oldThemeSize - 1; + if (arrRTLayouts.size()) + m_pShapeWriter->m_pTheme = m_pDocument->m_arThemes[oldThemeIndex].get(); + else if (arrRTNotes.size()) + m_pShapeWriter->m_pTheme = m_pDocument->m_pNotesMaster.get(); + else if (m_pDocument->m_pHandoutMaster.get()) + m_pShapeWriter->m_pTheme = m_pDocument->m_pHandoutMaster.get(); + if (m_pShapeWriter->m_pTheme == nullptr) + return false; - // if (wasThemeWrite == false) - // return; + auto themeType = m_pShapeWriter->m_pTheme->m_eType; - // write theme _rels - if (!themeRelsPath.empty() && needRels) - { - std::wstring relsFolder = strPptDirectory + L"theme" + FILE_SEPARATOR_STR + L"_rels" + FILE_SEPARATOR_STR; - std::wstring relsName = L"theme" + std::to_wstring(nIndexTheme) + L".xml.rels"; - NSDirectory::CreateDirectory(relsFolder); + if (arrRTTheme.empty()) + return false; - NSFile::CFileBinary::ReadAllBytes(themeRelsPath, &utf8Data, utf8DataSize); - NSFile::CFileBinary oFile; - oFile.CreateFileW(relsFolder + relsName); - oFile.WriteFile(utf8Data, utf8DataSize); + RoundTripExtractor extractor(arrRTTheme[0], m_pUserInfo->m_pDocumentInfo->m_pCommonInfo->tempPath); - oFile.CloseFile(); - RELEASEOBJECT(utf8Data); - utf8DataSize = 0; - } + std::wstring oneThemePathS = std::wstring(L"theme") + FILE_SEPARATOR_STR; + std::wstring twoThemePathS = oneThemePathS + std::wstring(L"theme") + FILE_SEPARATOR_STR; + auto strThemePath = extractor.getOneFile(twoThemePathS + L"theme1.xml"); + if (strThemePath.empty()) + return false; - // get slide master ID - std::vector arrMasterID; - pSlide->GetRecordsByType(&arrMasterID, false, true); + auto themeRelsPath = extractor.getOneFile(twoThemePathS + L"_rels" + FILE_SEPARATOR_STR + L"theme1.xml.rels"); + auto arrImagesPaths = extractor.find(L".*image[0-9]+.*"); - // Write layouts - if (themeType == _typeMaster::typeMaster) - { - std::wstring strOutputLayoutsPath = strPptDirectory + FILE_SEPARATOR_STR + L"slideLayouts" + FILE_SEPARATOR_STR; - std::wstring strOutputRelsLayoutsPath = strOutputLayoutsPath + L"_rels" + FILE_SEPARATOR_STR; + BYTE* utf8Data = NULL; + ULONG utf8DataSize = 0; + bool wasThemeWrite = false; + bool needRels = false; - if (nIndexTheme == 1) - { - NSDirectory::CreateDirectory(strOutputLayoutsPath); - NSDirectory::CreateDirectory(strOutputRelsLayoutsPath); - } - } + // read file bytes + NSFile::CFileBinary::ReadAllBytes(strThemePath, &utf8Data, utf8DataSize); + // compare hash + char* pointerToThemeElems = strstr((char*)utf8Data, ""); + UINT hashShift = pointerToThemeElems ? pointerToThemeElems - (char*)utf8Data : 0; - // Write Masters - if (wasThemeWrite) - { - CStringWriter oWriter; - CRelsGenerator oRels(&m_oManager); - int nCountLayouts = m_pShapeWriter->m_pTheme->m_arLayouts.size(); - oRels.StartMaster(nIndexTheme-1, nStartLayout, nCountLayouts); - auto* pTheme = m_pShapeWriter->m_pTheme; - oWriter.WriteString(L""); + auto strHash = md5(utf8Data + hashShift, utf8DataSize - hashShift); - if (pTheme->m_eType == typeMaster) - { - oWriter.WriteString(L""); - } - else if (pTheme->m_eType == typeNotesMaster) - { - oWriter.WriteString(L""); - } - else if (pTheme->m_eType == typeHandoutMaster) + needRels = (int)std::string(utf8Data, utf8Data + utf8DataSize).find("rId") != -1; + + // cp file with new name or write bytes + if (writedFilesHash.find(strHash) == writedFilesHash.end()) { - oWriter.WriteString(L""); + std::wstring strThemeFile = L"theme" + std::to_wstring(++nIndexTheme) + L".xml"; + std::wstring outputThemePath = strThemeDirectory + FILE_SEPARATOR_STR + strThemeFile; + NSFile::CFileBinary file; + file.CreateFileW(outputThemePath); + file.WriteFile(utf8Data, utf8DataSize); + file.CloseFile(); + + // clear bytes + RELEASEOBJECT(utf8Data); + utf8DataSize = 0; + + writedFilesHash.insert(strHash); + wasThemeWrite = true; + + for (auto& strImagePath : arrImagesPaths) + { + themeRels.WriteImage(strImagePath); + } } - oWriter.WriteString(L""); - if (pTheme->m_bIsBackground) + // if (wasThemeWrite == false) + // return; + + // write theme _rels + if (!themeRelsPath.empty() && needRels) { - WriteBackground(oWriter, oRels, pTheme->m_oBackground); + std::wstring relsFolder = strPptDirectory + L"theme" + FILE_SEPARATOR_STR + L"_rels" + FILE_SEPARATOR_STR; + std::wstring relsName = L"theme" + std::to_wstring(nIndexTheme) + L".xml.rels"; + NSDirectory::CreateDirectory(relsFolder); + + NSFile::CFileBinary::ReadAllBytes(themeRelsPath, &utf8Data, utf8DataSize); + NSFile::CFileBinary oFile; + oFile.CreateFileW(relsFolder + relsName); + oFile.WriteFile(utf8Data, utf8DataSize); + + oFile.CloseFile(); + RELEASEOBJECT(utf8Data); + utf8DataSize = 0; } - oWriter.WriteString(L"\ - "); - CGroupElement *pGroupElement = !pTheme->m_arElements.empty() ? dynamic_cast(pTheme->m_arElements[0].get()) : NULL; + // get slide master ID + std::vector arrMasterID; + pSlide->GetRecordsByType(&arrMasterID, false, true); - size_t start_index = 0; - if (pGroupElement) + // Write layouts + if (themeType == _typeMaster::typeMaster) { - for (size_t i = 0; i < pGroupElement->m_pChildElements.size(); ++i) + std::wstring strOutputLayoutsPath = strPptDirectory + FILE_SEPARATOR_STR + L"slideLayouts" + FILE_SEPARATOR_STR; + std::wstring strOutputRelsLayoutsPath = strOutputLayoutsPath + L"_rels" + FILE_SEPARATOR_STR; + + if (nIndexTheme == 1) { - if (isBodyPlaceholder(pGroupElement->m_pChildElements[i]->m_lPlaceholderType)) - pGroupElement->m_pChildElements[i]->m_lPlaceholderType = 100; //body тип прописывать !! + NSDirectory::CreateDirectory(strOutputLayoutsPath); + NSDirectory::CreateDirectory(strOutputRelsLayoutsPath); + } + } - //if (pGroupElement->m_pChildElements[i]->m_bAnchorEnabled == false && - // pGroupElement->m_pChildElements[i]->m_bChildAnchorEnabled == false) + // Write Masters + if (wasThemeWrite) + { + CStringWriter oWriter; + CRelsGenerator oRels(&m_oManager); + int nCountLayouts = m_pShapeWriter->m_pTheme->m_arLayouts.size(); + oRels.StartMaster(nIndexTheme - 1, nStartLayout, nCountLayouts); + auto* pTheme = m_pShapeWriter->m_pTheme; + oWriter.WriteString(L""); + + if (pTheme->m_eType == typeMaster) + { + oWriter.WriteString(L""); + } + else if (pTheme->m_eType == typeNotesMaster) + { + oWriter.WriteString(L""); + } + else if (pTheme->m_eType == typeHandoutMaster) + { + oWriter.WriteString(L""); + } + oWriter.WriteString(L""); + + if (pTheme->m_bIsBackground) + { + WriteBackground(oWriter, oRels, pTheme->m_oBackground); + } + oWriter.WriteString(L"\ + "); + + CGroupElement* pGroupElement = !pTheme->m_arElements.empty() ? dynamic_cast(pTheme->m_arElements[0].get()) : NULL; + + size_t start_index = 0; + if (pGroupElement) + { + for (size_t i = 0; i < pGroupElement->m_pChildElements.size(); ++i) + { + if (isBodyPlaceholder(pGroupElement->m_pChildElements[i]->m_lPlaceholderType)) + pGroupElement->m_pChildElements[i]->m_lPlaceholderType = 100; //body тип прописывать !! + + //if (pGroupElement->m_pChildElements[i]->m_bAnchorEnabled == false && + // pGroupElement->m_pChildElements[i]->m_bChildAnchorEnabled == false) + // continue; + + //if (pTheme->m_eType == typeNotesMaster) + //{ + // pGroupElement->m_pChildElements[i]->m_lPlaceholderID = -1; + //} + //else if (pTheme->m_eType == typeHandoutMaster) + //{ + // pGroupElement->m_pChildElements[i]->m_lPlaceholderID = -1; + // pGroupElement->m_pChildElements[i]->m_lPlaceholderSizePreset = -1; + //} + WriteElement(oWriter, oRels, pGroupElement->m_pChildElements[i]); + } + + start_index = 1; + } + + for (size_t i = start_index; i < pTheme->m_arElements.size(); ++i) + { + if (isBodyPlaceholder(pTheme->m_arElements[i]->m_lPlaceholderType)) + pTheme->m_arElements[i]->m_lPlaceholderType = 100; //body тип прописывать !! + + //if (pTheme->m_arElements[i]->m_bAnchorEnabled == false && + // pTheme->m_arElements[i]->m_bChildAnchorEnabled == false) + // continue; + + //if (pTheme->m_eType == typeNotesMaster) + //{ + // pTheme->m_arElements[i]->m_lPlaceholderID = -1; + //} + //else if (pTheme->m_eType == typeHandoutMaster) + //{ + // pTheme->m_arElements[i]->m_lPlaceholderID = -1; + // pTheme->m_arElements[i]->m_lPlaceholderSizePreset = -1; + //} + + WriteElement(oWriter, oRels, pTheme->m_arElements[i]); + } + + oWriter.WriteString(std::wstring(L"")); + + // std::wstring strOverrideColorScheme = L""); + oWriter.WriteString(arrRTColor[0]->getPClrMap()); + + if (pTheme->m_eType == typeMaster) + { + oWriter.WriteString(std::wstring(L"")); + + for (int nIndexLayout = 0; nIndexLayout < nCountLayouts; ++nIndexLayout) + { + const unsigned sldLayoutId = 0x80000000 + nIndexTheme + nStartLayout + nIndexLayout; + oWriter.WriteString(L""); + + WriteLayout(pTheme->m_arLayouts[nIndexLayout], nIndexLayout, nStartLayout, nIndexTheme - 1); + } + + oWriter.WriteString(std::wstring(L"")); + } + + if (pTheme->m_bHasDate || pTheme->m_bHasFooter || pTheme->m_bHasSlideNumber) + { + oWriter.WriteString(std::wstring(L"m_bHasDate) oWriter.WriteString(std::wstring(L" dt=\"0\"")); + if (!pTheme->m_bHasSlideNumber) oWriter.WriteString(std::wstring(L" sldNum=\"0\"")); + oWriter.WriteString(std::wstring(L" hdr=\"0\"")); + if (!pTheme->m_bHasFooter) oWriter.WriteString(std::wstring(L" ftr=\"0\"")); + oWriter.WriteString(std::wstring(L"/>")); + } + CStylesWriter styleWriter; + styleWriter.m_pTheme = pTheme; + + + // inserted roundtrip master + // add media here rId + if (pTheme->m_eType == typeMaster && arrRTMaster.size()) + { + + RoundTripExtractor extractorMaster(arrRTMaster[0], m_pUserInfo->m_pDocumentInfo->m_pCommonInfo->tempPath); + + auto masterPath = extractorMaster.getOneFile(std::wstring(L"drs") + FILE_SEPARATOR_STR + L"slideMasters" + FILE_SEPARATOR_STR + L"slideMaster1.xml"); + auto mediaPathes = extractorMaster.find(L".*image[0-9]+.*"); + int rIdShift = oRels.getRId() - 1; + for (auto& strMediaPath : mediaPathes) + { + oRels.WriteImage(strMediaPath); + } + + std::wstring utf8strMaster; + NSFile::CFileBinary::ReadAllTextUtf8(masterPath, utf8strMaster); + auto txStylesIter = utf8strMaster.find(L"m_eType == typeNotesMaster) + { + oWriter.WriteString(std::wstring(L"")); + + RoundTripExtractor extractorNotes(arrRTNotes[0], m_pUserInfo->m_pDocumentInfo->m_pCommonInfo->tempPath); + + auto masterPath = extractorNotes.getOneFile(std::wstring(L"drs") + FILE_SEPARATOR_STR + L"slideMasters" + FILE_SEPARATOR_STR + L"slideMaster1.xml"); + std::wstring utf8strNotes; + NSFile::CFileBinary::ReadAllTextUtf8(masterPath, utf8strNotes); + auto lvl1pPrIter = utf8strNotes.find(L""); + if (lvl1pPrIter != (UINT)-1 && bodyStyleIter != (UINT)-1) + oWriter.WriteString(utf8strNotes.substr(lvl1pPrIter, bodyStyleIter - lvl1pPrIter)); + + oWriter.WriteString(std::wstring(L"")); + } + + std::wstring strSlideMasterFile; + std::wstring strSlideMasterRelsFile; + if (pTheme->m_eType == typeMaster) + { + oWriter.WriteString(std::wstring(L"")); + + strSlideMasterFile = L"slideMaster" + std::to_wstring(nIndexTheme) + L".xml"; + strSlideMasterFile = strPptDirectory + L"slideMasters" + FILE_SEPARATOR_STR + strSlideMasterFile; + + strSlideMasterRelsFile = L"slideMaster" + std::to_wstring(nIndexTheme) + L".xml.rels"; + strSlideMasterRelsFile = strPptDirectory + L"slideMasters" + FILE_SEPARATOR_STR + L"_rels" + FILE_SEPARATOR_STR + strSlideMasterRelsFile; + } + else if (pTheme->m_eType == typeNotesMaster) + { + oWriter.WriteString(std::wstring(L"")); + + strSlideMasterFile = L"notesMaster1.xml"; + strSlideMasterFile = strPptDirectory + L"notesMasters" + FILE_SEPARATOR_STR + strSlideMasterFile; + + strSlideMasterRelsFile = L"notesMaster1.xml.rels"; + strSlideMasterRelsFile = strPptDirectory + L"notesMasters" + FILE_SEPARATOR_STR + L"_rels" + FILE_SEPARATOR_STR + strSlideMasterRelsFile; + } + else if (pTheme->m_eType == typeHandoutMaster) + { + oWriter.WriteString(std::wstring(L"")); + + strSlideMasterFile = L"handoutMaster1.xml"; + strSlideMasterFile = strPptDirectory + L"handoutMasters" + FILE_SEPARATOR_STR + strSlideMasterFile; + + strSlideMasterRelsFile = L"handoutMaster1.xml.rels"; + strSlideMasterRelsFile = strPptDirectory + L"handoutMasters" + FILE_SEPARATOR_STR + L"_rels" + FILE_SEPARATOR_STR + strSlideMasterRelsFile; + } + NSFile::CFileBinary oFile; + oFile.CreateFileW(strSlideMasterFile); + std::wstring strMaster = oWriter.GetData(); + oFile.WriteStringUTF8(strMaster); + oFile.CloseFile(); + + oRels.CloseRels(); + oRels.SaveRels(strSlideMasterRelsFile); + + nStartLayout += nCountLayouts; + } + + m_pShapeWriter->m_pTheme = NULL; + + return true; + } + + void CPPTXWriter::WriteTheme(CThemePtr pTheme, int& nIndexTheme, int& nStartLayout) + { + if (!pTheme) return; + + std::wstring strPptDirectory = m_strDestPath + FILE_SEPARATOR_STR + L"ppt" + FILE_SEPARATOR_STR; + + std::wstring strThemeFile = L"theme" + std::to_wstring(nIndexTheme + 1) + L".xml"; + strThemeFile = strPptDirectory + L"theme" + FILE_SEPARATOR_STR + strThemeFile; + + NSFile::CFileBinary oFile; + oFile.CreateFileW(strThemeFile); + + CStringWriter oStringWriter; + + oStringWriter.WriteString(std::wstring(L"m_sThemeName); + oStringWriter.WriteString(std::wstring(L"\">")); + + WriteColorScheme(oStringWriter, L"Default", pTheme->m_arColorScheme); + + if (!pTheme->m_arFonts.empty()) + { + oStringWriter.WriteString(std::wstring(L"m_arFonts[0].Name); + oStringWriter.WriteString(std::wstring(L"\"/>")); + + oStringWriter.WriteString(std::wstring(L"m_arFonts.size() > 1) oStringWriter.WriteString(pTheme->m_arFonts[1].Name); + else oStringWriter.WriteStringXML(pTheme->m_arFonts[0].Name); + } + + oStringWriter.WriteString(std::wstring(L"\"/>")); + oStringWriter.WriteString(std::wstring(L"")); + + oStringWriter.WriteString(std::wstring(L"\ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + ")); + + oStringWriter.WriteString(std::wstring(L"")); + + if (pTheme->m_arExtraColorScheme.size()) + { + oStringWriter.WriteString(std::wstring(L"")); + + for (size_t i = 0; i < pTheme->m_arExtraColorScheme.size(); i++) + { + std::wstring str = L" " + std::to_wstring(i + 1); + WriteColorScheme(oStringWriter, pTheme->m_sThemeName + str, pTheme->m_arExtraColorScheme[i], true); //extra + } + + oStringWriter.WriteString(std::wstring(L"")); + } + else + oStringWriter.WriteString(std::wstring(L"")); + + oStringWriter.WriteString(std::wstring(L"")); + + oFile.WriteStringUTF8(oStringWriter.GetData()); + oFile.CloseFile(); + + CRelsGenerator oRels(&m_oManager); + int nCountLayouts = (int)pTheme->m_arLayouts.size(); + oRels.StartMaster(nIndexTheme, nStartLayout, nCountLayouts); + + CStringWriter oWriter; + oWriter.WriteString(L""); + + if (pTheme->m_eType == typeMaster) + { + oWriter.WriteString(L""); + } + else if (pTheme->m_eType == typeNotesMaster) + { + oWriter.WriteString(L""); + } + else if (pTheme->m_eType == typeHandoutMaster) + { + oWriter.WriteString(L""); + } + oWriter.WriteString(L""); + + if (pTheme->m_bIsBackground) + { + WriteBackground(oWriter, oRels, pTheme->m_oBackground); + } + oWriter.WriteString(L"\ + "); + + CGroupElement* pGroupElement = !pTheme->m_arElements.empty() ? dynamic_cast(pTheme->m_arElements[0].get()) : NULL; + + size_t start_index = 0; + if (pGroupElement) + { + for (size_t i = 0; i < pGroupElement->m_pChildElements.size(); ++i) + { + if (isBodyPlaceholder(pGroupElement->m_pChildElements[i]->m_lPlaceholderType)) + pGroupElement->m_pChildElements[i]->m_lPlaceholderType = 100; //body тип прописывать !! + + //if (pGroupElement->m_pChildElements[i]->m_bAnchorEnabled == false && + // pGroupElement->m_pChildElements[i]->m_bChildAnchorEnabled == false) // continue; //if (pTheme->m_eType == typeNotesMaster) @@ -891,8 +1200,8 @@ bool CPPTXWriter::WriteRoundTripTheme(const CRecordSlide *pSlide, std::unordered oWriter.WriteString(std::wstring(L"")); - // std::wstring strOverrideColorScheme = _T(""); - oWriter.WriteString(arrRTColor[0]->getPClrMap()); + std::wstring strOverrideColorScheme = L""; + oWriter.WriteString(strOverrideColorScheme); if (pTheme->m_eType == typeMaster) { @@ -900,10 +1209,9 @@ bool CPPTXWriter::WriteRoundTripTheme(const CRecordSlide *pSlide, std::unordered for (int nIndexLayout = 0; nIndexLayout < nCountLayouts; ++nIndexLayout) { - const unsigned sldLayoutId = 0x80000000 + nIndexTheme + nStartLayout + nIndexLayout; - oWriter.WriteString(L""); + oWriter.WriteString(L""); - WriteLayout(pTheme->m_arLayouts[nIndexLayout], nIndexLayout, nStartLayout, nIndexTheme-1); + WriteLayout(pTheme->m_arLayouts[nIndexLayout], nIndexLayout, nStartLayout, nIndexTheme); } oWriter.WriteString(std::wstring(L"")); @@ -919,66 +1227,30 @@ bool CPPTXWriter::WriteRoundTripTheme(const CRecordSlide *pSlide, std::unordered oWriter.WriteString(std::wstring(L"/>")); } CStylesWriter styleWriter; - styleWriter.m_pTheme = pTheme; - + styleWriter.m_pTheme = pTheme.get(); - // inserted roundtrip master - // add media here rId - if (pTheme->m_eType == typeMaster && arrRTMaster.size()) + if (pTheme->m_eType == typeMaster) { + oWriter.WriteString(std::wstring(L"")); - RoundTripExtractor extractorMaster(arrRTMaster[0], m_pUserInfo->m_pDocumentInfo->m_pCommonInfo->tempPath); - - auto masterPath = extractorMaster.getOneFile(std::wstring(L"drs") + FILE_SEPARATOR_STR + L"slideMasters" + FILE_SEPARATOR_STR + L"slideMaster1.xml"); - auto mediaPathes = extractorMaster.find(L".*image[0-9]+.*"); - int rIdShift = oRels.getRId() - 1; - for (auto& strMediaPath : mediaPathes) - { - oRels.WriteImage(strMediaPath); - } - - std::wstring utf8strMaster; - NSFile::CFileBinary::ReadAllTextUtf8(masterPath, utf8strMaster); - auto txStylesIter = utf8strMaster.find(L"")); + styleWriter.ConvertStyles(pTheme->m_pStyles[1], oWriter, 9); + oWriter.WriteString(std::wstring(L"")); - UINT proccesed = 0; - UINT rIdIter = 0; - UINT rIdIterEnd = 0; - const std::wstring searchStrEmbed = L"")); + styleWriter.ConvertStyles(pTheme->m_pStyles[2], oWriter, 9); + oWriter.WriteString(std::wstring(L"")); - auto strId = strTxStyles.substr(proccesed, rIdIterEnd - proccesed); - unsigned numId = std::stoi(strId) + rIdShift; - strId = std::to_wstring(numId); + oWriter.WriteString(std::wstring(L"")); + styleWriter.ConvertStyles(pTheme->m_pStyles[3], oWriter, 9); + oWriter.WriteString(std::wstring(L"")); - strTxStyles.erase(proccesed, rIdIterEnd - proccesed); - strTxStyles.insert(proccesed, strId); - } - oWriter.WriteString(strTxStyles); - } + oWriter.WriteString(std::wstring(L"")); } else if (pTheme->m_eType == typeNotesMaster) { oWriter.WriteString(std::wstring(L"")); - - RoundTripExtractor extractorNotes(arrRTNotes[0], m_pUserInfo->m_pDocumentInfo->m_pCommonInfo->tempPath); - - auto masterPath = extractorNotes.getOneFile(std::wstring(L"drs") + FILE_SEPARATOR_STR + L"slideMasters" + FILE_SEPARATOR_STR + L"slideMaster1.xml"); - std::wstring utf8strNotes; - NSFile::CFileBinary::ReadAllTextUtf8(masterPath, utf8strNotes); - auto lvl1pPrIter = utf8strNotes.find(L""); - if (lvl1pPrIter != (UINT)-1 && bodyStyleIter != (UINT)-1) - oWriter.WriteString(utf8strNotes.substr(lvl1pPrIter, bodyStyleIter - lvl1pPrIter)); - + styleWriter.ConvertStyles(pTheme->m_pStyles[1], oWriter, 9); oWriter.WriteString(std::wstring(L"")); } @@ -988,33 +1260,32 @@ bool CPPTXWriter::WriteRoundTripTheme(const CRecordSlide *pSlide, std::unordered { oWriter.WriteString(std::wstring(L"")); - strSlideMasterFile = L"slideMaster" + std::to_wstring(nIndexTheme) + L".xml"; - strSlideMasterFile = strPptDirectory + _T("slideMasters") + FILE_SEPARATOR_STR + strSlideMasterFile; + strSlideMasterFile = L"slideMaster" + std::to_wstring(nIndexTheme + 1) + L".xml"; + strSlideMasterFile = strPptDirectory + L"slideMasters" + FILE_SEPARATOR_STR + strSlideMasterFile; - strSlideMasterRelsFile = L"slideMaster" + std::to_wstring(nIndexTheme) + L".xml.rels"; - strSlideMasterRelsFile = strPptDirectory + _T("slideMasters") + FILE_SEPARATOR_STR + _T("_rels") + FILE_SEPARATOR_STR + strSlideMasterRelsFile; + strSlideMasterRelsFile = L"slideMaster" + std::to_wstring(nIndexTheme + 1) + L".xml.rels"; + strSlideMasterRelsFile = strPptDirectory + L"slideMasters" + FILE_SEPARATOR_STR + L"_rels" + FILE_SEPARATOR_STR + strSlideMasterRelsFile; } else if (pTheme->m_eType == typeNotesMaster) { oWriter.WriteString(std::wstring(L"")); strSlideMasterFile = L"notesMaster1.xml"; - strSlideMasterFile = strPptDirectory + _T("notesMasters") + FILE_SEPARATOR_STR + strSlideMasterFile; + strSlideMasterFile = strPptDirectory + L"notesMasters" + FILE_SEPARATOR_STR + strSlideMasterFile; strSlideMasterRelsFile = L"notesMaster1.xml.rels"; - strSlideMasterRelsFile = strPptDirectory + _T("notesMasters") + FILE_SEPARATOR_STR + _T("_rels") + FILE_SEPARATOR_STR + strSlideMasterRelsFile; + strSlideMasterRelsFile = strPptDirectory + L"notesMasters" + FILE_SEPARATOR_STR + L"_rels" + FILE_SEPARATOR_STR + strSlideMasterRelsFile; } else if (pTheme->m_eType == typeHandoutMaster) { oWriter.WriteString(std::wstring(L"")); strSlideMasterFile = L"handoutMaster1.xml"; - strSlideMasterFile = strPptDirectory + _T("handoutMasters") + FILE_SEPARATOR_STR + strSlideMasterFile; + strSlideMasterFile = strPptDirectory + L"handoutMasters" + FILE_SEPARATOR_STR + strSlideMasterFile; strSlideMasterRelsFile = L"handoutMaster1.xml.rels"; - strSlideMasterRelsFile = strPptDirectory + _T("handoutMasters") + FILE_SEPARATOR_STR + _T("_rels") + FILE_SEPARATOR_STR + strSlideMasterRelsFile; + strSlideMasterRelsFile = strPptDirectory + L"handoutMasters" + FILE_SEPARATOR_STR + L"_rels" + FILE_SEPARATOR_STR + strSlideMasterRelsFile; } - NSFile::CFileBinary oFile; oFile.CreateFileW(strSlideMasterFile); std::wstring strMaster = oWriter.GetData(); oFile.WriteStringUTF8(strMaster); @@ -1024,892 +1295,637 @@ bool CPPTXWriter::WriteRoundTripTheme(const CRecordSlide *pSlide, std::unordered oRels.SaveRels(strSlideMasterRelsFile); nStartLayout += nCountLayouts; + nIndexTheme++; } - m_pShapeWriter->m_pTheme = NULL; + void CPPTXWriter::WriteColorScheme(CStringWriter& oStringWriter, const std::wstring& name, const std::vector& colors, bool extra) + { + if (colors.size() < 1) + { + oStringWriter.WriteString(L"\ + \ + \ + \ + \ + "); + return; + } - return true; -} + if (extra) + oStringWriter.WriteString(L""); -void CPPTXWriter::WriteTheme(CThemePtr pTheme, int & nIndexTheme, int & nStartLayout) -{ - if (!pTheme) return; + oStringWriter.WriteString(L""); - std::wstring strThemeFile = L"theme" + std::to_wstring(nIndexTheme + 1) + L".xml"; - strThemeFile = strPptDirectory + _T("theme") + FILE_SEPARATOR_STR + strThemeFile; + oStringWriter.WriteString(L""); - NSFile::CFileBinary oFile; - oFile.CreateFileW(strThemeFile); + oStringWriter.WriteString(L""); - CStringWriter oStringWriter; + oStringWriter.WriteString(L""); - oStringWriter.WriteString(std::wstring(L"m_sThemeName); - oStringWriter.WriteString(std::wstring(L"\">")); + oStringWriter.WriteString(L""); - WriteColorScheme(oStringWriter, L"Default", pTheme->m_arColorScheme); + oStringWriter.WriteString(L""); - if (!pTheme->m_arFonts.empty()) - { - oStringWriter.WriteString(std::wstring(L"m_arFonts[0].Name); - oStringWriter.WriteString(std::wstring(L"\"/>")); + oStringWriter.WriteString(L""); - oStringWriter.WriteString(std::wstring(L""); - if (pTheme->m_arFonts.size() > 1 ) oStringWriter.WriteString (pTheme->m_arFonts[1].Name); - else oStringWriter.WriteStringXML(pTheme->m_arFonts[0].Name); - } + oStringWriter.WriteString(L""); - oStringWriter.WriteString(std::wstring(L"\"/>")); - oStringWriter.WriteString(std::wstring(L"")); + oStringWriter.WriteString(L""); - oStringWriter.WriteString(std::wstring(L"\ - \ - \ - \ - \ - \ - \ - \ - \ - \ - \ - \ - \ - \ - \ - \ - \ - \ - \ - \ - \ - \ - \ - \ - \ - ")); + oStringWriter.WriteString(L""); - oStringWriter.WriteString(std::wstring(L"")); + oStringWriter.WriteString(L""); - if (pTheme->m_arExtraColorScheme.size()) - { - oStringWriter.WriteString(std::wstring(L"")); + oStringWriter.WriteString(L""); - for (size_t i = 0 ; i < pTheme->m_arExtraColorScheme.size(); i++) + oStringWriter.WriteString(L""); + if (extra) { - std::wstring str = L" " + std::to_wstring(i + 1); - WriteColorScheme(oStringWriter, pTheme->m_sThemeName + str, pTheme->m_arExtraColorScheme[i], true); //extra + oStringWriter.WriteString(L""); + oStringWriter.WriteString(L""); } + } - oStringWriter.WriteString(std::wstring(L"")); - } else - oStringWriter.WriteString(std::wstring(L"")); - - oStringWriter.WriteString(std::wstring(L"")); - - oFile.WriteStringUTF8(oStringWriter.GetData()); - oFile.CloseFile(); - - CRelsGenerator oRels(&m_oManager); - int nCountLayouts = (int)pTheme->m_arLayouts.size(); - oRels.StartMaster(nIndexTheme, nStartLayout, nCountLayouts); - - CStringWriter oWriter; - oWriter.WriteString(L""); - - if (pTheme->m_eType == typeMaster) + void CPPTXWriter::WriteBackground(CStringWriter& oWriter, CRelsGenerator& oRels, CBrush& oBackground) { - oWriter.WriteString(L""); + m_pShapeWriter->SetRelsGenerator(&oRels); + std::wstring sBg = m_pShapeWriter->ConvertBrush(oBackground); + + if (false == sBg.empty()) + { + oWriter.WriteString(std::wstring(L"")); + oWriter.WriteString(sBg); + oWriter.WriteString(std::wstring(L"")); + } } - else if (pTheme->m_eType == typeNotesMaster) + void CPPTXWriter::WriteGroup(CStringWriter& oWriter, CRelsGenerator& oRels, CElementPtr pElement, CLayout* pLayout) { - oWriter.WriteString(L""); + CGroupElement* pGroupElement = dynamic_cast(pElement.get()); + + m_pShapeWriter->SetElement(pElement); + oWriter.WriteString(m_pShapeWriter->ConvertGroup()); + + for (size_t i = 0; i < pGroupElement->m_pChildElements.size(); i++) + { + WriteElement(oWriter, oRels, pGroupElement->m_pChildElements[i], pLayout); + } + oWriter.WriteString(L""); } - else if (pTheme->m_eType == typeHandoutMaster) + void CPPTXWriter::WriteTable(CStringWriter& oWriter, CRelsGenerator& oRels, CElementPtr pElement, CLayout* pLayout) { - oWriter.WriteString(L""); + CTableElement* pTableElement = dynamic_cast(pElement.get()); + + + PPTX::Logic::GraphicFrame gf; + TableWriter table(pTableElement, &oRels); + if (pTableElement->m_xmlRawData.empty()) + { + table.Convert(gf); + oWriter.WriteString(gf.toXML()); + } + else + { + oWriter.WriteString(table.getXmlForGraphicFrame(pElement->m_lID, pElement->m_lPlaceholderID)); + } } - oWriter.WriteString(L""); - if (pTheme->m_bIsBackground) + void CPPTXWriter::WriteElement(CStringWriter& oWriter, CRelsGenerator& oRels, CElementPtr pElement, CLayout* pLayout) { - WriteBackground(oWriter, oRels, pTheme->m_oBackground); - } - oWriter.WriteString(L"\ - "); + if (!pElement) return; - CGroupElement *pGroupElement = !pTheme->m_arElements.empty() ? dynamic_cast(pTheme->m_arElements[0].get()) : NULL; - size_t start_index = 0; - if (pGroupElement) - { - for (size_t i = 0; i < pGroupElement->m_pChildElements.size(); ++i) + CTableElement* pTableElement = dynamic_cast(pElement.get()); + if (pTableElement) { - if (isBodyPlaceholder(pGroupElement->m_pChildElements[i]->m_lPlaceholderType)) - pGroupElement->m_pChildElements[i]->m_lPlaceholderType = 100; //body тип прописывать !! - - //if (pGroupElement->m_pChildElements[i]->m_bAnchorEnabled == false && - // pGroupElement->m_pChildElements[i]->m_bChildAnchorEnabled == false) - // continue; + return WriteTable(oWriter, oRels, pElement, pLayout); + } - //if (pTheme->m_eType == typeNotesMaster) - //{ - // pGroupElement->m_pChildElements[i]->m_lPlaceholderID = -1; - //} - //else if (pTheme->m_eType == typeHandoutMaster) - //{ - // pGroupElement->m_pChildElements[i]->m_lPlaceholderID = -1; - // pGroupElement->m_pChildElements[i]->m_lPlaceholderSizePreset = -1; - //} - WriteElement(oWriter, oRels, pGroupElement->m_pChildElements[i]); - } - - start_index = 1; - } - - for (size_t i = start_index; i < pTheme->m_arElements.size(); ++i) - { - if (isBodyPlaceholder(pTheme->m_arElements[i]->m_lPlaceholderType)) - pTheme->m_arElements[i]->m_lPlaceholderType = 100; //body тип прописывать !! - - //if (pTheme->m_arElements[i]->m_bAnchorEnabled == false && - // pTheme->m_arElements[i]->m_bChildAnchorEnabled == false) - // continue; - - //if (pTheme->m_eType == typeNotesMaster) - //{ - // pTheme->m_arElements[i]->m_lPlaceholderID = -1; - //} - //else if (pTheme->m_eType == typeHandoutMaster) - //{ - // pTheme->m_arElements[i]->m_lPlaceholderID = -1; - // pTheme->m_arElements[i]->m_lPlaceholderSizePreset = -1; - //} - - WriteElement(oWriter, oRels, pTheme->m_arElements[i]); - } - - oWriter.WriteString(std::wstring(L"")); - - std::wstring strOverrideColorScheme = _T(""); - oWriter.WriteString(strOverrideColorScheme); - - if (pTheme->m_eType == typeMaster) - { - oWriter.WriteString(std::wstring(L"")); - - for (int nIndexLayout = 0; nIndexLayout < nCountLayouts; ++nIndexLayout) + CGroupElement* pGroupElement = dynamic_cast(pElement.get()); + if (pGroupElement) { - oWriter.WriteString(L""); - - WriteLayout(pTheme->m_arLayouts[nIndexLayout], nIndexLayout, nStartLayout, nIndexTheme); + return WriteGroup(oWriter, oRels, pElement, pLayout); } - oWriter.WriteString(std::wstring(L"")); - } - - if (pTheme->m_bHasDate || pTheme->m_bHasFooter || pTheme->m_bHasSlideNumber) - { - oWriter.WriteString(std::wstring(L"m_bHasDate) oWriter.WriteString(std::wstring(L" dt=\"0\"")); - if (!pTheme->m_bHasSlideNumber) oWriter.WriteString(std::wstring(L" sldNum=\"0\"")); - oWriter.WriteString(std::wstring(L" hdr=\"0\"")); - if (!pTheme->m_bHasFooter) oWriter.WriteString(std::wstring(L" ftr=\"0\"")); - oWriter.WriteString(std::wstring(L"/>")); - } - CStylesWriter styleWriter; - styleWriter.m_pTheme = pTheme.get(); - - if (pTheme->m_eType == typeMaster) - { - oWriter.WriteString(std::wstring(L"")); - - oWriter.WriteString(std::wstring(L"")); - styleWriter.ConvertStyles(pTheme->m_pStyles[1], oWriter, 9); - oWriter.WriteString(std::wstring(L"")); - - oWriter.WriteString(std::wstring(L"")); - styleWriter.ConvertStyles(pTheme->m_pStyles[2], oWriter, 9); - oWriter.WriteString(std::wstring(L"")); - - oWriter.WriteString(std::wstring(L"")); - styleWriter.ConvertStyles(pTheme->m_pStyles[3], oWriter, 9); - oWriter.WriteString(std::wstring(L"")); - - oWriter.WriteString(std::wstring(L"")); - } - else if (pTheme->m_eType == typeNotesMaster) - { - oWriter.WriteString(std::wstring(L"")); - styleWriter.ConvertStyles(pTheme->m_pStyles[1], oWriter, 9); - oWriter.WriteString(std::wstring(L"")); - } - - std::wstring strSlideMasterFile; - std::wstring strSlideMasterRelsFile; - if (pTheme->m_eType == typeMaster) - { - oWriter.WriteString(std::wstring(L"")); - - strSlideMasterFile = L"slideMaster" + std::to_wstring(nIndexTheme + 1) + L".xml"; - strSlideMasterFile = strPptDirectory + _T("slideMasters") + FILE_SEPARATOR_STR + strSlideMasterFile; + bool bObject = m_pShapeWriter->SetElement(pElement); - strSlideMasterRelsFile = L"slideMaster" + std::to_wstring(nIndexTheme + 1) + L".xml.rels"; - strSlideMasterRelsFile = strPptDirectory + _T("slideMasters") + FILE_SEPARATOR_STR + _T("_rels") + FILE_SEPARATOR_STR + strSlideMasterRelsFile; - } - else if (pTheme->m_eType == typeNotesMaster) - { - oWriter.WriteString(std::wstring(L"")); + if (bObject) + { + m_pShapeWriter->SetRelsGenerator(&oRels); - strSlideMasterFile = L"notesMaster1.xml"; - strSlideMasterFile = strPptDirectory + _T("notesMasters") + FILE_SEPARATOR_STR + strSlideMasterFile; + if (NULL != pLayout) + { + if (-1 != pElement->m_lPlaceholderType) + { + size_t nCountElements = pLayout->m_arElements.size(); + for (size_t nIndex = 0; nIndex < nCountElements; ++nIndex) + { + if ((pElement->m_lPlaceholderType == pLayout->m_arElements[nIndex]->m_lPlaceholderType) && + (pElement->m_lPlaceholderID == pLayout->m_arElements[nIndex]->m_lPlaceholderID)) + { + CElementPtr pElLayout = pLayout->m_arElements[nIndex]; - strSlideMasterRelsFile = L"notesMaster1.xml.rels"; - strSlideMasterRelsFile = strPptDirectory + _T("notesMasters") + FILE_SEPARATOR_STR + _T("_rels") + FILE_SEPARATOR_STR + strSlideMasterRelsFile; - } - else if (pTheme->m_eType == typeHandoutMaster) - { - oWriter.WriteString(std::wstring(L"")); + bool bIsEqualTransform = ((pElement->m_dRotate == pElLayout->m_dRotate) + && (pElement->m_bFlipH == pElLayout->m_bFlipH) && (pElement->m_bFlipV == pElLayout->m_bFlipV)); - strSlideMasterFile = L"handoutMaster1.xml"; - strSlideMasterFile = strPptDirectory + _T("handoutMasters") + FILE_SEPARATOR_STR + strSlideMasterFile; + if (bIsEqualTransform) + { + if (pElement->m_bAnchorEnabled == pElLayout->m_bAnchorEnabled && pElLayout->m_bAnchorEnabled == true) + { + if (pElement->m_rcAnchor.IsEqual(pElLayout->m_rcAnchor, 0.5)) + pElement->m_bAnchorEnabled = false; + } + if (pElement->m_bChildAnchorEnabled == pElLayout->m_bChildAnchorEnabled && pElLayout->m_bChildAnchorEnabled == true) + { + if (pElement->m_rcChildAnchor.IsEqual(pElLayout->m_rcChildAnchor, 0.5)) + pElement->m_bChildAnchorEnabled = false; + } + } - strSlideMasterRelsFile = L"handoutMaster1.xml.rels"; - strSlideMasterRelsFile = strPptDirectory + _T("handoutMasters") + FILE_SEPARATOR_STR + _T("_rels") + FILE_SEPARATOR_STR + strSlideMasterRelsFile; + break; + } + } + } + } + oWriter.WriteString(m_pShapeWriter->ConvertShape()); + } } - oFile.CreateFileW(strSlideMasterFile); - std::wstring strMaster = oWriter.GetData(); - oFile.WriteStringUTF8(strMaster); - oFile.CloseFile(); - oRels.CloseRels(); - oRels.SaveRels(strSlideMasterRelsFile); - - nStartLayout += nCountLayouts; - nIndexTheme++; -} - -void CPPTXWriter::WriteColorScheme(CStringWriter& oStringWriter, const std::wstring & name, const std::vector & colors, bool extra) -{ - if (colors.size() < 1) + void CPPTXWriter::WriteLayout(CLayoutPtr pLayout, int nIndexLayout, int nStartLayout, int nIndexTheme) { - oStringWriter.WriteString(L"\ - \ - \ - \ - \ - "); - return; - } - - if (extra) - oStringWriter.WriteString(L""); - - oStringWriter.WriteString(L""); - - oStringWriter.WriteString(L""); - - oStringWriter.WriteString(L""); - - oStringWriter.WriteString(L""); - - oStringWriter.WriteString(L""); + if (!pLayout) return; - oStringWriter.WriteString(L""); + CStringWriter oWriter; - oStringWriter.WriteString(L""); + CRelsGenerator oRels(&m_oManager); + oRels.StartLayout(nIndexTheme); - oStringWriter.WriteString(L""); + oWriter.WriteString(std::wstring(L"")); - oStringWriter.WriteString(L""); + oWriter.WriteString(std::wstring(L"m_strLayoutType + L"\""); + oWriter.WriteString(std::wstring(L" showMasterSp=\"") + (pLayout->m_bShowMasterShapes ? L"1" : L"0")); + oWriter.WriteString(std::wstring(L"\" preserve=\"1\">"); + if (pLayout->m_sName.empty() == false) + oWriter.WriteString(std::wstring(L" name=\"") + pLayout->m_sName + std::wstring(L"\"")); + oWriter.WriteString(std::wstring(L">")); - oStringWriter.WriteString(L""); + if (pLayout->m_bIsBackground) + { + WriteBackground(oWriter, oRels, pLayout->m_oBackground); + } - oStringWriter.WriteString(L""); + std::wstring strElems = L"\ + "; + oWriter.WriteString(strElems); - oStringWriter.WriteString(L""); + size_t start_index = 0; - oStringWriter.WriteString(L""); - if (extra) - { - oStringWriter.WriteString(L""); - oStringWriter.WriteString(L""); - } -} + if (pLayout->m_bIsTitleMaster) + { + CGroupElement* pGroupElement = (!pLayout->m_arElements.empty()) ? dynamic_cast(pLayout->m_arElements[0].get()) : NULL; -void CPPTXWriter::WriteBackground(CStringWriter& oWriter, CRelsGenerator& oRels, CBrush& oBackground) -{ - m_pShapeWriter->SetRelsGenerator(&oRels); - std::wstring sBg = m_pShapeWriter->ConvertBrush(oBackground); - - if (false == sBg.empty()) - { - oWriter.WriteString(std::wstring(L"")); - oWriter.WriteString(sBg); - oWriter.WriteString(std::wstring(L"")); - } -} -void CPPTXWriter::WriteGroup(CStringWriter& oWriter, CRelsGenerator& oRels, CElementPtr pElement, CLayout* pLayout) -{ - CGroupElement *pGroupElement = dynamic_cast(pElement.get()); + if (pGroupElement) + { + for (size_t i = 0; i < pGroupElement->m_pChildElements.size(); ++i) + { + WriteElement(oWriter, oRels, pGroupElement->m_pChildElements[i]); + } - m_pShapeWriter->SetElement(pElement); - oWriter.WriteString(m_pShapeWriter->ConvertGroup()); + start_index = 1; + } + } - for (size_t i = 0; i < pGroupElement->m_pChildElements.size(); i++) - { - WriteElement(oWriter, oRels, pGroupElement->m_pChildElements[i], pLayout); - } - oWriter.WriteString(L""); -} -void CPPTXWriter::WriteTable(CStringWriter& oWriter, CRelsGenerator& oRels, CElementPtr pElement, CLayout* pLayout) -{ - CTableElement *pTableElement = dynamic_cast(pElement.get()); + for (size_t i = start_index; i < pLayout->m_arElements.size(); ++i) + { + WriteElement(oWriter, oRels, pLayout->m_arElements[i]); + } + oWriter.WriteString(std::wstring(L"")); + oWriter.WriteString(std::wstring(L"")); + oWriter.WriteString(std::wstring(L"")); - PPTX::Logic::GraphicFrame gf; - TableWriter table(pTableElement, &oRels); - if (pTableElement->m_xmlRawData.empty()) - { - table.Convert(gf); - oWriter.WriteString(gf.toXML()); - } else - { - oWriter.WriteString(table.getXmlForGraphicFrame(pElement->m_lID, pElement->m_lPlaceholderID)); - } -} + oRels.CloseRels(); -void CPPTXWriter::WriteElement(CStringWriter& oWriter, CRelsGenerator& oRels, CElementPtr pElement, CLayout* pLayout) -{ - if (!pElement) return; + std::wstring strXml = oWriter.GetData(); + std::wstring strFile = L"slideLayout" + std::to_wstring(nIndexLayout + nStartLayout + 1) + L".xml"; + NSFile::CFileBinary oFile; + std::wstring strFileLayoutPath = m_strDestPath + FILE_SEPARATOR_STR + L"ppt" + FILE_SEPARATOR_STR + L"slideLayouts" + FILE_SEPARATOR_STR; + oFile.CreateFileW(strFileLayoutPath + strFile); + oFile.WriteStringUTF8(strXml); + oFile.CloseFile(); - CTableElement *pTableElement = dynamic_cast(pElement.get()); - if (pTableElement) - { - return WriteTable(oWriter, oRels, pElement, pLayout); + strFile = L"slideLayout" + std::to_wstring(nIndexLayout + nStartLayout + 1) + L".xml.rels"; + oRels.SaveRels(strFileLayoutPath + L"_rels" + FILE_SEPARATOR_STR + strFile); } - - CGroupElement *pGroupElement = dynamic_cast(pElement.get()); - if (pGroupElement) + void CPPTXWriter::WriteSlide(int nIndexSlide) { - return WriteGroup(oWriter, oRels, pElement, pLayout); - } - - bool bObject = m_pShapeWriter->SetElement(pElement); + CStringWriter oWriter; + CRelsGenerator oRels(&m_oManager); - if (bObject) - { - m_pShapeWriter->SetRelsGenerator(&oRels); + CSlide* pSlide = m_pDocument->m_arSlides[nIndexSlide]; - if (NULL != pLayout) + if (0 == pSlide->m_lThemeID) + oRels.StartSlide(pSlide->m_lLayoutID, pSlide->m_lNotesID); + else { - if (-1 != pElement->m_lPlaceholderType) + int nLayout = pSlide->m_lLayoutID; + for (int i = 0; i < pSlide->m_lThemeID; ++i) { - size_t nCountElements = pLayout->m_arElements.size(); - for (size_t nIndex = 0; nIndex < nCountElements; ++nIndex) - { - if ((pElement->m_lPlaceholderType == pLayout->m_arElements[nIndex]->m_lPlaceholderType) && - (pElement->m_lPlaceholderID == pLayout->m_arElements[nIndex]->m_lPlaceholderID)) - { - CElementPtr pElLayout = pLayout->m_arElements[nIndex]; - - bool bIsEqualTransform = ((pElement->m_dRotate == pElLayout->m_dRotate) - && (pElement->m_bFlipH == pElLayout->m_bFlipH) && (pElement->m_bFlipV == pElLayout->m_bFlipV)); - - if (bIsEqualTransform) - { - if (pElement->m_bAnchorEnabled == pElLayout->m_bAnchorEnabled && pElLayout->m_bAnchorEnabled == true) - { - if (pElement->m_rcAnchor.IsEqual(pElLayout->m_rcAnchor, 0.5)) - pElement->m_bAnchorEnabled = false; - } - if (pElement->m_bChildAnchorEnabled == pElLayout->m_bChildAnchorEnabled && pElLayout->m_bChildAnchorEnabled == true) - { - if (pElement->m_rcChildAnchor.IsEqual(pElLayout->m_rcChildAnchor, 0.5)) - pElement->m_bChildAnchorEnabled = false; - } - } - - break; - } - } + nLayout += (int)m_pDocument->m_arThemes[i]->m_arLayouts.size(); } - } - oWriter.WriteString(m_pShapeWriter->ConvertShape()); - } -} -void CPPTXWriter::WriteLayout(CLayoutPtr pLayout, int nIndexLayout, int nStartLayout, int nIndexTheme) -{ - if (!pLayout) return; - - CStringWriter oWriter; - - CRelsGenerator oRels(&m_oManager); - oRels.StartLayout(nIndexTheme); - - oWriter.WriteString(std::wstring(L"")); - - oWriter.WriteString(std::wstring(L"m_strLayoutType + _T("\"")); - oWriter.WriteString(std::wstring(L" showMasterSp=\"") + (pLayout->m_bShowMasterShapes ? _T("1") : _T("0"))); - oWriter.WriteString(std::wstring(L"\" preserve=\"1\">m_sName.empty() == false) - oWriter.WriteString(std::wstring(L" name=\"") + pLayout->m_sName + std::wstring(L"\"")); - oWriter.WriteString(std::wstring(L">")); + oRels.StartSlide(nLayout, pSlide->m_lNotesID); + } - if (pLayout->m_bIsBackground) - { - WriteBackground(oWriter, oRels, pLayout->m_oBackground); - } + oWriter.WriteString(std::wstring(L"")); + oWriter.WriteString(std::wstring(L"m_bShowMasterShapes) + oWriter.WriteString(std::wstring(L" showMasterSp=\"0\"")); + if (pSlide->m_bHidden) + oWriter.WriteString(std::wstring(L" show=\"0\"")); + oWriter.WriteString(std::wstring(L">")); + + oWriter.WriteString(std::wstring(L"m_sName.empty() == false) + oWriter.WriteString(std::wstring(L" name=\"") + pSlide->m_sName + std::wstring(L"\"")); + + oWriter.WriteString(std::wstring(L">")); + + if (pSlide->m_bIsBackground) + { + WriteBackground(oWriter, oRels, pSlide->m_oBackground); + } - std::wstring strElems = _T("\ - "); - oWriter.WriteString(strElems); + oWriter.WriteString(std::wstring(L"\ + ")); - size_t start_index = 0; + CGroupElement* pGroupElement = !pSlide->m_arElements.empty() ? dynamic_cast(pSlide->m_arElements[0].get()) : NULL; - if (pLayout->m_bIsTitleMaster) - { - CGroupElement *pGroupElement = (!pLayout->m_arElements.empty()) ? dynamic_cast(pLayout->m_arElements[0].get()) : NULL; + size_t start_index = 0; if (pGroupElement) { for (size_t i = 0; i < pGroupElement->m_pChildElements.size(); ++i) { - WriteElement(oWriter, oRels, pGroupElement->m_pChildElements[i]); + auto& element = pGroupElement->m_pChildElements[i]; + WriteElement(oWriter, oRels, element); } start_index = 1; } - } - for (size_t i = start_index; i < pLayout->m_arElements.size(); ++i) - { - WriteElement(oWriter, oRels, pLayout->m_arElements[i]); - } - oWriter.WriteString(std::wstring(L"")); + for (size_t i = start_index; i < pSlide->m_arElements.size(); ++i) + { + auto& element = pSlide->m_arElements[i]; + WriteElement(oWriter, oRels, element); + } - oWriter.WriteString(std::wstring(L"")); - oWriter.WriteString(std::wstring(L"")); + oWriter.WriteString(std::wstring(L"")); - oRels.CloseRels(); + oWriter.WriteString(std::wstring(L"")); - std::wstring strXml = oWriter.GetData(); - std::wstring strFile = L"slideLayout" + std::to_wstring(nIndexLayout + nStartLayout + 1) + L".xml"; + WriteTransition(oWriter, pSlide->m_oSlideShow); - NSFile::CFileBinary oFile; - std::wstring strFileLayoutPath= m_strDestPath + FILE_SEPARATOR_STR + _T("ppt") + FILE_SEPARATOR_STR + _T("slideLayouts") + FILE_SEPARATOR_STR; - oFile.CreateFileW(strFileLayoutPath + strFile); - oFile.WriteStringUTF8(strXml); - oFile.CloseFile(); + // TODO write new method and class for timing + WriteTiming(oWriter, oRels, nIndexSlide); - strFile = L"slideLayout" + std::to_wstring(nIndexLayout + nStartLayout + 1) + L".xml.rels"; - oRels.SaveRels(strFileLayoutPath + _T("_rels") + FILE_SEPARATOR_STR + strFile); -} -void CPPTXWriter::WriteSlide(int nIndexSlide) -{ - CStringWriter oWriter; - CRelsGenerator oRels(&m_oManager); - CSlide* pSlide = m_pDocument->m_arSlides[nIndexSlide]; + oWriter.WriteString(std::wstring(L"")); - if (0 == pSlide->m_lThemeID) - oRels.StartSlide(pSlide->m_lLayoutID, pSlide->m_lNotesID); - else - { - int nLayout = pSlide->m_lLayoutID; - for (int i = 0; i < pSlide->m_lThemeID; ++i) - { - nLayout += (int)m_pDocument->m_arThemes[i]->m_arLayouts.size(); - } - oRels.StartSlide(nLayout, pSlide->m_lNotesID); - } - oWriter.WriteString(std::wstring(L"")); - oWriter.WriteString(std::wstring(L"m_bShowMasterShapes) - oWriter.WriteString(std::wstring(L" showMasterSp=\"0\"")); - oWriter.WriteString(std::wstring(L">")); - oWriter.WriteString(std::wstring(L"m_sName.empty() == false) - oWriter.WriteString(std::wstring(L" name=\"") + pSlide->m_sName + std::wstring(L"\"")); + std::wstring strXml = oWriter.GetData(); + std::wstring strFile = L"slide" + std::to_wstring(nIndexSlide + 1) + L".xml"; + std::wstring strFileSlidePath = m_strDestPath + FILE_SEPARATOR_STR + L"ppt" + FILE_SEPARATOR_STR + L"slides" + FILE_SEPARATOR_STR; - oWriter.WriteString(std::wstring(L">")); + NSFile::CFileBinary oFile; + oFile.CreateFileW(strFileSlidePath + strFile); + oFile.WriteStringUTF8(strXml); + oFile.CloseFile(); - if (pSlide->m_bIsBackground) - { - WriteBackground(oWriter, oRels, pSlide->m_oBackground); + strFile = L"slide" + std::to_wstring(nIndexSlide + 1) + L".xml.rels"; + oRels.SaveRels(strFileSlidePath + L"_rels" + FILE_SEPARATOR_STR + strFile); } - oWriter.WriteString(std::wstring(L"\ - ")); - - CGroupElement *pGroupElement = !pSlide->m_arElements.empty() ? dynamic_cast(pSlide->m_arElements[0].get()) : NULL; - - size_t start_index = 0; - - if (pGroupElement) + void CPPTXWriter::WriteTransition(CStringWriter& oWriter, CSlideShowInfo& oSSInfo) { - for (size_t i = 0; i < pGroupElement->m_pChildElements.size(); ++i) - { - auto& element = pGroupElement->m_pChildElements[i]; - WriteElement(oWriter, oRels, element); - } - - start_index = 1; + Converter::Transition transitionConverter(oSSInfo, m_pShapeWriter->m_pRels); + auto transition = transitionConverter.Convert(); + oWriter.WriteString(transition.toXML()); } - for (size_t i = start_index; i < pSlide->m_arElements.size(); ++i) + void CPPTXWriter::WriteNotes(int nIndexNotes) { - auto& element = pSlide->m_arElements[i]; - WriteElement(oWriter, oRels, element); - } - - oWriter.WriteString(std::wstring(L"")); - - oWriter.WriteString(std::wstring(L"")); - - WriteTransition(oWriter, pSlide->m_oSlideShow); + CStringWriter oWriter; + CRelsGenerator oRels(&m_oManager); - // TODO write new method and class for timing - WriteTiming(oWriter, oRels, nIndexSlide); + CSlide* pNotes = m_pDocument->m_arNotes[nIndexNotes]; + oRels.StartNotes(pNotes->m_lSlideID, m_pDocument->m_pNotesMaster != NULL); - oWriter.WriteString(std::wstring(L"")); + oWriter.WriteString(std::wstring(L"")); + oWriter.WriteString(std::wstring(L"m_bShowMasterShapes) + oWriter.WriteString(std::wstring(L" showMasterSp=\"0\"")); + oWriter.WriteString(std::wstring(L">")); + oWriter.WriteString(std::wstring(L"")); + if (pNotes->m_bIsBackground) + { + WriteBackground(oWriter, oRels, pNotes->m_oBackground); + } + oWriter.WriteString(std::wstring(L"\ + ")); - oRels.CloseRels(); + CGroupElement* pGroupElement = !pNotes->m_arElements.empty() ? dynamic_cast(pNotes->m_arElements[0].get()) : NULL; - std::wstring strXml = oWriter.GetData(); - std::wstring strFile = L"slide" + std::to_wstring(nIndexSlide + 1) + L".xml"; - std::wstring strFileSlidePath= m_strDestPath + FILE_SEPARATOR_STR + _T("ppt") + FILE_SEPARATOR_STR + _T("slides") + FILE_SEPARATOR_STR; + size_t start_index = 0; - NSFile::CFileBinary oFile; - oFile.CreateFileW(strFileSlidePath + strFile); - oFile.WriteStringUTF8(strXml); - oFile.CloseFile(); + if (pGroupElement) + { + for (size_t i = 0; i < pGroupElement->m_pChildElements.size(); ++i) + { + WriteElement(oWriter, oRels, pGroupElement->m_pChildElements[i]); + } - strFile = L"slide" + std::to_wstring(nIndexSlide + 1) + L".xml.rels"; - oRels.SaveRels(strFileSlidePath + _T("_rels") + FILE_SEPARATOR_STR + strFile); -} + start_index = 1; + } -void CPPTXWriter::WriteTransition(CStringWriter& oWriter, CSlideShowInfo &oSSInfo) -{ - Converter::Transition transitionConverter(oSSInfo, m_pShapeWriter->m_pRels); - auto transition = transitionConverter.Convert(); - oWriter.WriteString(transition.toXML()); -} + for (size_t i = start_index; i < pNotes->m_arElements.size(); ++i) + { + WriteElement(oWriter, oRels, pNotes->m_arElements[i]); + } -void CPPTXWriter::WriteNotes(int nIndexNotes) -{ - CStringWriter oWriter; - CRelsGenerator oRels(&m_oManager); + oWriter.WriteString(std::wstring(L"")); - CSlide* pNotes = m_pDocument->m_arNotes[nIndexNotes]; + oWriter.WriteString(std::wstring(L"")); + oWriter.WriteString(std::wstring(L"")); - oRels.StartNotes(pNotes->m_lSlideID, m_pDocument->m_pNotesMaster != NULL); + oRels.CloseRels(); - oWriter.WriteString(std::wstring(L"")); - oWriter.WriteString(std::wstring(L"m_bShowMasterShapes) - oWriter.WriteString(std::wstring(L" showMasterSp=\"0\"")); - oWriter.WriteString(std::wstring(L">")); + std::wstring strXml = oWriter.GetData(); + std::wstring strFile = L"notesSlide" + std::to_wstring(nIndexNotes + 1) + L".xml"; + std::wstring strFileSlidePath = m_strDestPath + FILE_SEPARATOR_STR + L"ppt" + FILE_SEPARATOR_STR + L"notesSlides" + FILE_SEPARATOR_STR; - oWriter.WriteString(std::wstring(L"")); + NSFile::CFileBinary oFile; + oFile.CreateFileW(strFileSlidePath + strFile); + oFile.WriteStringUTF8(strXml); + oFile.CloseFile(); - if (pNotes->m_bIsBackground) - { - WriteBackground(oWriter, oRels, pNotes->m_oBackground); + strFile = L"notesSlide" + std::to_wstring(nIndexNotes + 1) + L".xml.rels"; + oRels.SaveRels(strFileSlidePath + L"_rels" + FILE_SEPARATOR_STR + strFile); } - oWriter.WriteString(std::wstring(L"\ - ")); - - CGroupElement *pGroupElement = !pNotes->m_arElements.empty() ? dynamic_cast(pNotes->m_arElements[0].get()) : NULL; - - size_t start_index = 0; - - if (pGroupElement) + void CPPTXWriter::WriteSlides() { - for (size_t i = 0; i < pGroupElement->m_pChildElements.size(); ++i) + m_oManager.WriteAudioCollection(m_pUserInfo->m_oExMedia.m_arAudioCollection); + for (size_t nIndexS = 0; nIndexS < m_pDocument->m_arSlides.size(); ++nIndexS) { - WriteElement(oWriter, oRels, pGroupElement->m_pChildElements[i]); + WriteSlide((int)nIndexS); } - - start_index = 1; } - - for (size_t i = start_index; i < pNotes->m_arElements.size(); ++i) + void CPPTXWriter::WriteNotes() { - WriteElement(oWriter, oRels, pNotes->m_arElements[i]); + for (size_t nIndexS = 0; nIndexS < m_pDocument->m_arNotes.size(); ++nIndexS) + { + WriteNotes((int)nIndexS); + } } - oWriter.WriteString(std::wstring(L"")); - - oWriter.WriteString(std::wstring(L"")); - oWriter.WriteString(std::wstring(L"")); - - oRels.CloseRels(); - - std::wstring strXml = oWriter.GetData(); - std::wstring strFile = L"notesSlide" + std::to_wstring(nIndexNotes + 1) + L".xml"; - std::wstring strFileSlidePath = m_strDestPath + FILE_SEPARATOR_STR + _T("ppt") + FILE_SEPARATOR_STR + _T("notesSlides") + FILE_SEPARATOR_STR; + void CPPTXWriter::WriteLayoutAfterTheme(CThemePtr pTheme, const int nIndexTheme, int& nStartLayout) + {//nIndexTheme тут уже +1 + CRelsGenerator oRels(&m_oManager); + int nCountLayouts = (int)pTheme->m_arLayouts.size(); + oRels.StartMaster(nIndexTheme - 1, nStartLayout, nCountLayouts); - NSFile::CFileBinary oFile; - oFile.CreateFileW(strFileSlidePath + strFile); - oFile.WriteStringUTF8(strXml); - oFile.CloseFile(); + CStringWriter oWriter; + oWriter.WriteString(L""); - strFile = L"notesSlide" + std::to_wstring(nIndexNotes + 1) + L".xml.rels"; - oRels.SaveRels(strFileSlidePath + _T("_rels") + FILE_SEPARATOR_STR + strFile); -} + if (pTheme->m_eType == typeMaster) + { + oWriter.WriteString(L""); + } + else if (pTheme->m_eType == typeNotesMaster) + { + oWriter.WriteString(L""); + } + else if (pTheme->m_eType == typeHandoutMaster) + { + oWriter.WriteString(L""); + } + oWriter.WriteString(L""); -void CPPTXWriter::WriteSlides() -{ - m_oManager.WriteAudioCollection(m_pUserInfo->m_oExMedia.m_arAudioCollection); - for (size_t nIndexS = 0; nIndexS < m_pDocument->m_arSlides.size(); ++nIndexS) - { - WriteSlide((int)nIndexS); - } -} -void CPPTXWriter::WriteNotes() -{ - for (size_t nIndexS = 0; nIndexS < m_pDocument->m_arNotes.size(); ++nIndexS) - { - WriteNotes((int)nIndexS); - } -} + if (pTheme->m_bIsBackground) + { + WriteBackground(oWriter, oRels, pTheme->m_oBackground); + } + oWriter.WriteString(L"\ + "); -void CPPTXWriter::WriteLayoutAfterTheme(CThemePtr pTheme, const int nIndexTheme, int &nStartLayout) -{//nIndexTheme тут уже +1 - CRelsGenerator oRels(&m_oManager); - int nCountLayouts = (int)pTheme->m_arLayouts.size(); - oRels.StartMaster(nIndexTheme - 1, nStartLayout, nCountLayouts); + CGroupElement* pGroupElement = !pTheme->m_arElements.empty() ? dynamic_cast(pTheme->m_arElements[0].get()) : NULL; - CStringWriter oWriter; - oWriter.WriteString(L""); + size_t start_index = 0; + if (pGroupElement) + { + for (size_t i = 0; i < pGroupElement->m_pChildElements.size(); ++i) + { + if (isBodyPlaceholder(pGroupElement->m_pChildElements[i]->m_lPlaceholderType)) + pGroupElement->m_pChildElements[i]->m_lPlaceholderType = 100; //body тип прописывать !! - if (pTheme->m_eType == typeMaster) - { - oWriter.WriteString(L""); - } - else if (pTheme->m_eType == typeNotesMaster) - { - oWriter.WriteString(L""); - } - else if (pTheme->m_eType == typeHandoutMaster) - { - oWriter.WriteString(L""); - } - oWriter.WriteString(L""); + //if (pGroupElement->m_pChildElements[i]->m_bAnchorEnabled == false && + // pGroupElement->m_pChildElements[i]->m_bChildAnchorEnabled == false) + // continue; - if (pTheme->m_bIsBackground) - { - WriteBackground(oWriter, oRels, pTheme->m_oBackground); - } - oWriter.WriteString(L"\ - "); + //if (pTheme->m_eType == typeNotesMaster) + //{ + // pGroupElement->m_pChildElements[i]->m_lPlaceholderID = -1; + //} + //else if (pTheme->m_eType == typeHandoutMaster) + //{ + // pGroupElement->m_pChildElements[i]->m_lPlaceholderID = -1; + // pGroupElement->m_pChildElements[i]->m_lPlaceholderSizePreset = -1; + //} + WriteElement(oWriter, oRels, pGroupElement->m_pChildElements[i]); + } - CGroupElement *pGroupElement = !pTheme->m_arElements.empty() ? dynamic_cast(pTheme->m_arElements[0].get()) : NULL; + start_index = 1; + } - size_t start_index = 0; - if (pGroupElement) - { - for (size_t i = 0; i < pGroupElement->m_pChildElements.size(); ++i) + for (size_t i = start_index; i < pTheme->m_arElements.size(); ++i) { - if (isBodyPlaceholder(pGroupElement->m_pChildElements[i]->m_lPlaceholderType)) - pGroupElement->m_pChildElements[i]->m_lPlaceholderType = 100; //body тип прописывать !! + if (isBodyPlaceholder(pTheme->m_arElements[i]->m_lPlaceholderType)) + pTheme->m_arElements[i]->m_lPlaceholderType = 100; //body тип прописывать !! - //if (pGroupElement->m_pChildElements[i]->m_bAnchorEnabled == false && - // pGroupElement->m_pChildElements[i]->m_bChildAnchorEnabled == false) + //if (pTheme->m_arElements[i]->m_bAnchorEnabled == false && + // pTheme->m_arElements[i]->m_bChildAnchorEnabled == false) // continue; //if (pTheme->m_eType == typeNotesMaster) //{ - // pGroupElement->m_pChildElements[i]->m_lPlaceholderID = -1; + // pTheme->m_arElements[i]->m_lPlaceholderID = -1; //} //else if (pTheme->m_eType == typeHandoutMaster) //{ - // pGroupElement->m_pChildElements[i]->m_lPlaceholderID = -1; - // pGroupElement->m_pChildElements[i]->m_lPlaceholderSizePreset = -1; + // pTheme->m_arElements[i]->m_lPlaceholderID = -1; + // pTheme->m_arElements[i]->m_lPlaceholderSizePreset = -1; //} - WriteElement(oWriter, oRels, pGroupElement->m_pChildElements[i]); - } - start_index = 1; - } + WriteElement(oWriter, oRels, pTheme->m_arElements[i]); + } - for (size_t i = start_index; i < pTheme->m_arElements.size(); ++i) - { - if (isBodyPlaceholder(pTheme->m_arElements[i]->m_lPlaceholderType)) - pTheme->m_arElements[i]->m_lPlaceholderType = 100; //body тип прописывать !! - - //if (pTheme->m_arElements[i]->m_bAnchorEnabled == false && - // pTheme->m_arElements[i]->m_bChildAnchorEnabled == false) - // continue; - - //if (pTheme->m_eType == typeNotesMaster) - //{ - // pTheme->m_arElements[i]->m_lPlaceholderID = -1; - //} - //else if (pTheme->m_eType == typeHandoutMaster) - //{ - // pTheme->m_arElements[i]->m_lPlaceholderID = -1; - // pTheme->m_arElements[i]->m_lPlaceholderSizePreset = -1; - //} - - WriteElement(oWriter, oRels, pTheme->m_arElements[i]); - } + oWriter.WriteString(std::wstring(L"")); - oWriter.WriteString(std::wstring(L"")); + std::wstring strOverrideColorScheme = L""; + oWriter.WriteString(strOverrideColorScheme); - std::wstring strOverrideColorScheme = _T(""); - oWriter.WriteString(strOverrideColorScheme); + if (pTheme->m_eType == typeMaster) + { + oWriter.WriteString(std::wstring(L"")); - if (pTheme->m_eType == typeMaster) - { - oWriter.WriteString(std::wstring(L"")); + size_t __nCountLayouts = 0; + for (int nIndexLayout = 0; nIndexLayout < nCountLayouts; ++nIndexLayout) + { + oWriter.WriteString(L""); - size_t __nCountLayouts = 0; - for (int nIndexLayout = 0; nIndexLayout < nCountLayouts; ++nIndexLayout) - { - oWriter.WriteString(L""); + WriteLayout(pTheme->m_arLayouts[nIndexLayout], nIndexLayout, nStartLayout, nIndexTheme - 1); + } - WriteLayout(pTheme->m_arLayouts[nIndexLayout], nIndexLayout, nStartLayout, nIndexTheme - 1); + oWriter.WriteString(std::wstring(L"")); } - oWriter.WriteString(std::wstring(L"")); - } - - if (pTheme->m_bHasDate || pTheme->m_bHasFooter || pTheme->m_bHasSlideNumber) - { - oWriter.WriteString(std::wstring(L"m_bHasDate) oWriter.WriteString(std::wstring(L" dt=\"0\"")); - if (!pTheme->m_bHasSlideNumber) oWriter.WriteString(std::wstring(L" sldNum=\"0\"")); - oWriter.WriteString(std::wstring(L" hdr=\"0\"")); - if (!pTheme->m_bHasFooter) oWriter.WriteString(std::wstring(L" ftr=\"0\"")); - oWriter.WriteString(std::wstring(L"/>")); - } - CStylesWriter styleWriter; - styleWriter.m_pTheme = pTheme.get(); + if (pTheme->m_bHasDate || pTheme->m_bHasFooter || pTheme->m_bHasSlideNumber) + { + oWriter.WriteString(std::wstring(L"m_bHasDate) oWriter.WriteString(std::wstring(L" dt=\"0\"")); + if (!pTheme->m_bHasSlideNumber) oWriter.WriteString(std::wstring(L" sldNum=\"0\"")); + oWriter.WriteString(std::wstring(L" hdr=\"0\"")); + if (!pTheme->m_bHasFooter) oWriter.WriteString(std::wstring(L" ftr=\"0\"")); + oWriter.WriteString(std::wstring(L"/>")); + } + CStylesWriter styleWriter; + styleWriter.m_pTheme = pTheme.get(); - if (pTheme->m_eType == typeMaster) - { - oWriter.WriteString(std::wstring(L"")); + if (pTheme->m_eType == typeMaster) + { + oWriter.WriteString(std::wstring(L"")); - oWriter.WriteString(std::wstring(L"")); - styleWriter.ConvertStyles(pTheme->m_pStyles[1], oWriter, 9); - oWriter.WriteString(std::wstring(L"")); + oWriter.WriteString(std::wstring(L"")); + styleWriter.ConvertStyles(pTheme->m_pStyles[1], oWriter, 9); + oWriter.WriteString(std::wstring(L"")); - oWriter.WriteString(std::wstring(L"")); - styleWriter.ConvertStyles(pTheme->m_pStyles[2], oWriter, 9); - oWriter.WriteString(std::wstring(L"")); + oWriter.WriteString(std::wstring(L"")); + styleWriter.ConvertStyles(pTheme->m_pStyles[2], oWriter, 9); + oWriter.WriteString(std::wstring(L"")); - oWriter.WriteString(std::wstring(L"")); - styleWriter.ConvertStyles(pTheme->m_pStyles[3], oWriter, 9); - oWriter.WriteString(std::wstring(L"")); + oWriter.WriteString(std::wstring(L"")); + styleWriter.ConvertStyles(pTheme->m_pStyles[3], oWriter, 9); + oWriter.WriteString(std::wstring(L"")); - oWriter.WriteString(std::wstring(L"")); - } - else if (pTheme->m_eType == typeNotesMaster) - { - oWriter.WriteString(std::wstring(L"")); - styleWriter.ConvertStyles(pTheme->m_pStyles[1], oWriter, 9); - oWriter.WriteString(std::wstring(L"")); - } + oWriter.WriteString(std::wstring(L"")); + } + else if (pTheme->m_eType == typeNotesMaster) + { + oWriter.WriteString(std::wstring(L"")); + styleWriter.ConvertStyles(pTheme->m_pStyles[1], oWriter, 9); + oWriter.WriteString(std::wstring(L"")); + } - std::wstring strPptDirectory = m_strDestPath + FILE_SEPARATOR_STR + _T("ppt") + FILE_SEPARATOR_STR ; + std::wstring strPptDirectory = m_strDestPath + FILE_SEPARATOR_STR + L"ppt" + FILE_SEPARATOR_STR; - std::wstring strSlideMasterFile; - std::wstring strSlideMasterRelsFile; - if (pTheme->m_eType == typeMaster) - { - oWriter.WriteString(std::wstring(L"")); + std::wstring strSlideMasterFile; + std::wstring strSlideMasterRelsFile; + if (pTheme->m_eType == typeMaster) + { + oWriter.WriteString(std::wstring(L"")); - strSlideMasterFile = L"slideMaster" + std::to_wstring(nIndexTheme) + L".xml"; - strSlideMasterFile = strPptDirectory + _T("slideMasters") + FILE_SEPARATOR_STR + strSlideMasterFile; + strSlideMasterFile = L"slideMaster" + std::to_wstring(nIndexTheme) + L".xml"; + strSlideMasterFile = strPptDirectory + L"slideMasters" + FILE_SEPARATOR_STR + strSlideMasterFile; - strSlideMasterRelsFile = L"slideMaster" + std::to_wstring(nIndexTheme) + L".xml.rels"; - strSlideMasterRelsFile = strPptDirectory + _T("slideMasters") + FILE_SEPARATOR_STR + _T("_rels") + FILE_SEPARATOR_STR + strSlideMasterRelsFile; - } - else if (pTheme->m_eType == typeNotesMaster) - { - oWriter.WriteString(std::wstring(L"")); + strSlideMasterRelsFile = L"slideMaster" + std::to_wstring(nIndexTheme) + L".xml.rels"; + strSlideMasterRelsFile = strPptDirectory + L"slideMasters" + FILE_SEPARATOR_STR + L"_rels" + FILE_SEPARATOR_STR + strSlideMasterRelsFile; + } + else if (pTheme->m_eType == typeNotesMaster) + { + oWriter.WriteString(std::wstring(L"")); - strSlideMasterFile = L"notesMaster1.xml"; - strSlideMasterFile = strPptDirectory + _T("notesMasters") + FILE_SEPARATOR_STR + strSlideMasterFile; + strSlideMasterFile = L"notesMaster1.xml"; + strSlideMasterFile = strPptDirectory + L"notesMasters" + FILE_SEPARATOR_STR + strSlideMasterFile; - strSlideMasterRelsFile = L"notesMaster1.xml.rels"; - strSlideMasterRelsFile = strPptDirectory + _T("notesMasters") + FILE_SEPARATOR_STR + _T("_rels") + FILE_SEPARATOR_STR + strSlideMasterRelsFile; - } - else if (pTheme->m_eType == typeHandoutMaster) - { - oWriter.WriteString(std::wstring(L"")); + strSlideMasterRelsFile = L"notesMaster1.xml.rels"; + strSlideMasterRelsFile = strPptDirectory + L"notesMasters" + FILE_SEPARATOR_STR + L"_rels" + FILE_SEPARATOR_STR + strSlideMasterRelsFile; + } + else if (pTheme->m_eType == typeHandoutMaster) + { + oWriter.WriteString(std::wstring(L"")); - strSlideMasterFile = L"handoutMaster1.xml"; - strSlideMasterFile = strPptDirectory + _T("handoutMasters") + FILE_SEPARATOR_STR + strSlideMasterFile; + strSlideMasterFile = L"handoutMaster1.xml"; + strSlideMasterFile = strPptDirectory + L"handoutMasters" + FILE_SEPARATOR_STR + strSlideMasterFile; - strSlideMasterRelsFile = L"handoutMaster1.xml.rels"; - strSlideMasterRelsFile = strPptDirectory + _T("handoutMasters") + FILE_SEPARATOR_STR + _T("_rels") + FILE_SEPARATOR_STR + strSlideMasterRelsFile; - } + strSlideMasterRelsFile = L"handoutMaster1.xml.rels"; + strSlideMasterRelsFile = strPptDirectory + L"handoutMasters" + FILE_SEPARATOR_STR + L"_rels" + FILE_SEPARATOR_STR + strSlideMasterRelsFile; + } - NSFile::CFileBinary oFile; - oFile.CreateFileW(strSlideMasterFile); - std::wstring strMaster = oWriter.GetData(); - oFile.WriteStringUTF8(strMaster); - oFile.CloseFile(); + NSFile::CFileBinary oFile; + oFile.CreateFileW(strSlideMasterFile); + std::wstring strMaster = oWriter.GetData(); + oFile.WriteStringUTF8(strMaster); + oFile.CloseFile(); - oRels.CloseRels(); - oRels.SaveRels(strSlideMasterRelsFile); + oRels.CloseRels(); + oRels.SaveRels(strSlideMasterRelsFile); - nStartLayout += nCountLayouts; -} + nStartLayout += nCountLayouts; + } -void CPPTXWriter::WriteTiming(CStringWriter& oWriter, CRelsGenerator &oRels, int nIndexSlide) -{ - auto slide_iter = m_pUserInfo->m_mapSlides.find(m_pUserInfo->m_arrSlidesOrder[nIndexSlide]); - CSlide* pCSlide = m_pDocument->m_arSlides[nIndexSlide]; + void CPPTXWriter::WriteTiming(CStringWriter& oWriter, CRelsGenerator& oRels, int nIndexSlide) + { + auto slide_iter = m_pUserInfo->m_mapSlides.find(m_pUserInfo->m_arrSlidesOrder[nIndexSlide]); + CSlide* pCSlide = m_pDocument->m_arSlides[nIndexSlide]; - auto intermediateSlideAnimation = Intermediate::ParseSlideAnimation(slide_iter->second, pCSlide); - auto timing = + auto intermediateSlideAnimation = Intermediate::ParseSlideAnimation(slide_iter->second, pCSlide); + auto timing = Converter::Timing(intermediateSlideAnimation). Convert(&(m_pUserInfo->m_oExMedia), &oRels); - oWriter.WriteString(timing.toXML()); -} + oWriter.WriteString(timing.toXML()); + } -std::vector CPPTXWriter::GrepPaths(const std::vector &paths, const std::wstring &strRegEx) -{ - std::vector filtredPaths; - try + std::vector CPPTXWriter::GrepPaths(const std::vector& paths, const std::wstring& strRegEx) { - boost::wregex regEx(strRegEx); - boost::wsmatch wSmath; - for (const auto& path : paths) + std::vector filtredPaths; + try { - if (boost::regex_match(path, wSmath, regEx)) - filtredPaths.push_back(path); + boost::wregex regEx(strRegEx); + boost::wsmatch wSmath; + for (const auto& path : paths) + { + if (boost::regex_match(path, wSmath, regEx)) + filtredPaths.push_back(path); + } } - } catch(...) {} + catch (...) {} - return filtredPaths; -} + return filtredPaths; + } } diff --git a/MsBinaryFile/PptFile/PPTXWriter/ImageManager.cpp b/MsBinaryFile/PptFile/PPTXWriter/ImageManager.cpp index f128695e130..831f83be9a2 100644 --- a/MsBinaryFile/PptFile/PPTXWriter/ImageManager.cpp +++ b/MsBinaryFile/PptFile/PPTXWriter/ImageManager.cpp @@ -31,16 +31,15 @@ */ #include "ImageManager.h" #include +#include "../../../OOXML/SystemUtility/SystemUtility.h" +#include "../../../DesktopEditor/common/Directory.h" - -CMediaManager::CMediaManager() : m_lIndexNextImage(0), m_lIndexNextAudio(0), m_lIndexNextVideo(0) +CMediaManager::CMediaManager() : m_lIndexNextImage(0), m_lIndexNextAudio(0), m_lIndexNextVideo(0), m_lIndexNextOleObject(0) { } - CMediaManager::~CMediaManager() { } - void CMediaManager::Clear() { m_mapMedia.clear(); @@ -48,6 +47,7 @@ void CMediaManager::Clear() m_lIndexNextImage = 0; m_lIndexNextAudio = 0; m_lIndexNextVideo = 0; + m_lIndexNextOleObject = 0; } std::wstring CMediaManager::FindMedia(const std::wstring &strInput) @@ -59,33 +59,96 @@ std::wstring CMediaManager::FindMedia(const std::wstring &strInput) } return L""; } - +void CMediaManager::SetDstEmbeddings(const std::wstring& strDst) +{ + m_strDstEmbeddings = strDst; +} void CMediaManager::SetDstMedia(const std::wstring &strDst) { m_strDstMedia = strDst; } - -std::wstring CMediaManager::GenerateVideo(const std::wstring &strInput) +void CMediaManager::SetTempMedia(const std::wstring& strSrc) { - return GenerateMedia(strInput, L"video", m_lIndexNextVideo, L".avi"); + OOX::CPath pathSrc(strSrc); + m_strTempMedia = pathSrc.GetPath(); +} +std::wstring CMediaManager::GenerateVideo(const std::wstring &strInput, const std::wstring& strExt) +{ + return GenerateMedia(strInput, L"video", m_lIndexNextVideo, strExt.empty() ? L".avi" : strExt); } -std::wstring CMediaManager::GenerateAudio(const std::wstring &strInput) +std::wstring CMediaManager::GenerateAudio(const std::wstring &strInput, const std::wstring& strExt) { - return GenerateMedia(strInput, L"audio", m_lIndexNextAudio, L".wav"); + return GenerateMedia(strInput, L"audio", m_lIndexNextAudio, strExt.empty() ? L".wav" : strExt); } std::wstring CMediaManager::GenerateImage(const std::wstring &strInput) { return GenerateMedia(strInput, L"image", m_lIndexNextImage, L".png"); } - +std::wstring CMediaManager::GenerateOleObject(const std::wstring& strInput) +{ + return GenerateEmbedding(strInput, L"oleObject", m_lIndexNextOleObject, L".bin"); +} std::wstring CMediaManager::GenerateImageJPEG(const std::wstring &strInput) { return GenerateMedia(strInput, L"image", m_lIndexNextImage, L".jpeg"); } -std::wstring CMediaManager::GenerateMedia(const std::wstring &strInput, const std::wstring &Template, long &Indexer, const std::wstring &strDefaultExt) +std::wstring CMediaManager::GenerateEmbedding(const std::wstring &strInput, const std::wstring &Template, long &Indexer, const std::wstring &strDefaultExt) +{ + std::map::iterator pPair = m_mapMedia.find(strInput); + if (m_mapMedia.end() != pPair) + { + return pPair->second; + } + +// if (IsNeedDownload(strInput)) +// { +//#ifndef DISABLE_FILE_DOWNLOADER +// NSNetwork::NSFileTransport::CFileDownloader oDownloader(strInput, TRUE); +// if ( oDownloader.DownloadSync() ) +// { +// std::wstring file_name = oDownloader.GetFilePath(); +// +// //todooo - check media file +// return GenerateEmbedding(file_name , Template, Indexer, strDefaultExt); +// } +//#endif +// } + + std::wstring strExts = strDefaultExt; + int nIndexExt = strInput.rfind(wchar_t('.')); + if (-1 != nIndexExt) + strExts = strInput.substr(nIndexExt); + + if (strExts == L".tmp" || strExts.empty()) strExts = strDefaultExt; + + std::wstring strMediaName = Template + std::to_wstring(++Indexer); + + std::wstring strOutput = m_strDstEmbeddings + strMediaName + strExts; + strMediaName = L"../embeddings/" + strMediaName + strExts; + + OOX::CPath pathInput(strInput); + std::wstring strPathInput = pathInput.GetPath(); + + if (std::wstring::npos == strPathInput.find(m_strTempMedia)) + { + return L""; + } + if (strOutput != strInput) + { + NSDirectory::CreateDirectory(m_strDstEmbeddings); + + if (NSFile::CFileBinary::Copy(strInput, strOutput) == false) + { + return L""; + } + } + m_mapMedia[strInput] = strMediaName; + return strMediaName; +} +std::wstring CMediaManager::GenerateMedia(const std::wstring& strInput, const std::wstring& Template, long& Indexer, const std::wstring& strDefaultExt) { std::map::iterator pPair = m_mapMedia.find(strInput); if (m_mapMedia.end() != pPair) @@ -97,12 +160,12 @@ std::wstring CMediaManager::GenerateMedia(const std::wstring &strInput, const st { #ifndef DISABLE_FILE_DOWNLOADER NSNetwork::NSFileTransport::CFileDownloader oDownloader(strInput, TRUE); - if ( oDownloader.DownloadSync() ) + if (oDownloader.DownloadSync()) { std::wstring file_name = oDownloader.GetFilePath(); //todooo - check media file - return GenerateMedia(file_name , Template, Indexer, strDefaultExt); + return GenerateMedia(file_name, Template, Indexer, strDefaultExt); } #endif } @@ -112,22 +175,36 @@ std::wstring CMediaManager::GenerateMedia(const std::wstring &strInput, const st if (-1 != nIndexExt) strExts = strInput.substr(nIndexExt); - if (strExts == _T(".video") || strExts == _T(".audio")) + if (strExts == L".video" || strExts == L".audio") { std::wstring strInput1 = strInput.substr(0, nIndexExt); - nIndexExt = strInput1.rfind(wchar_t('.')); - strExts = nIndexExt < 0 ? L"" : strInput1.substr(nIndexExt); + strExts.clear(); + } + if (strExts == L".tmp" || strExts.empty()) strExts = strDefaultExt; + + if (strDefaultExt == L"sfil") + { + strExts = L".wav"; + //todooo - detect format by file } - if (strExts == _T(".tmp") || strExts.empty()) strExts = strDefaultExt; std::wstring strMediaName = Template + std::to_wstring(++Indexer); std::wstring strOutput = m_strDstMedia + strMediaName + strExts; - strMediaName = _T("../media/") + strMediaName + strExts; + strMediaName = L"../media/" + strMediaName + strExts; - // теперь нужно скопировать + OOX::CPath pathInput(strInput); + std::wstring strPathInput = pathInput.GetPath(); + + if (std::wstring::npos == strPathInput.find(m_strTempMedia)) + { + return L""; + } + //todooo ? test format if (strOutput != strInput) { + NSDirectory::CreateDirectory(m_strDstMedia); + if (NSFile::CFileBinary::Copy(strInput, strOutput) == false) { return L""; @@ -143,9 +220,8 @@ void CMediaManager::WriteAudioCollection(const std::vector &a for (auto& audio : audioCont) { - auto pathAudio = GenerateAudio(audio.m_strFilePath); + auto pathAudio = GenerateAudio(audio.m_strFilePath, audio.m_strFileExt); } - } bool CMediaManager::IsNeedDownload(const std::wstring &strFile) @@ -167,11 +243,11 @@ std::wstring CorrectXmlString3(const std::wstring &str) { switch(str[pos]) { - case '&': buffer.append(_T("&")); break; - case '\"': buffer.append(_T(""")); break; - case '\'': buffer.append(_T("'")); break; - case '<': buffer.append(_T("<")); break; - case '>': buffer.append(_T(">")); break; + case '&': buffer.append(L"&"); break; + case '\"': buffer.append(L"""); break; + case '\'': buffer.append(L"'"); break; + case '<': buffer.append(L"<"); break; + case '>': buffer.append(L">"); break; default: buffer.append(&str[pos], 1); break; } } @@ -197,8 +273,8 @@ void CRelsGenerator::Clear() void CRelsGenerator::StartMaster(int nIndexTheme, int nStartLayoutIndex, int nCountLayouts) { - std::wstring str1 = _T("\ - "); + std::wstring str1 = L"\ + "; m_oWriter.WriteString(str1); @@ -217,8 +293,8 @@ void CRelsGenerator::StartMaster(int nIndexTheme, int nStartLayoutIndex, int nCo void CRelsGenerator::StartLayout(int nIndexTheme) { - std::wstring str1 = _T("\ - "); + std::wstring str1 = L"\ + "; m_oWriter.WriteString(str1); @@ -264,7 +340,7 @@ void CRelsGenerator::StartSlide(int nIndexLayout, int nIndexNotes) void CRelsGenerator::CloseRels() { - std::wstring str = _T(""); + std::wstring str = L""; m_oWriter.WriteString(str); } @@ -353,19 +429,24 @@ std::wstring CRelsGenerator::WriteHyperlinkMedia(const std::wstring &strMedia, b return strRid; } -std::wstring CRelsGenerator::WriteHyperlinkImage(const std::wstring &strImage, bool bExternal) +std::wstring CRelsGenerator::WriteHyperlinkImage(const std::wstring & strFileName, bool bExternal) +{ + return WriteHyperlinkMedia(strFileName, bExternal, false, L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image"); +} + +std::wstring CRelsGenerator::WriteHyperlinkAudio(const std::wstring & strFileName, bool bExternal) { - return WriteHyperlinkMedia(strImage, bExternal, false, L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image"); + return WriteHyperlinkMedia(strFileName, bExternal, false, L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/audio"); } -std::wstring CRelsGenerator::WriteHyperlinkAudio(const std::wstring &strImage, bool bExternal) +std::wstring CRelsGenerator::WriteHyperlinkVideo(const std::wstring & strFileName, bool bExternal) { - return WriteHyperlinkMedia(strImage, bExternal, false, L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/audio"); + return WriteHyperlinkMedia(strFileName, bExternal, false, L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/video"); } -std::wstring CRelsGenerator::WriteHyperlinkVideo(const std::wstring &strImage, bool bExternal) +std::wstring CRelsGenerator::WriteHyperlinkOleObject(const std::wstring &strFileName, bool bExternal) { - return WriteHyperlinkMedia(strImage, bExternal, false, L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/video"); + return WriteHyperlinkMedia(strFileName, bExternal, false, L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/oleObject"); } std::wstring CRelsGenerator::WriteMedia(const std::wstring &strMediaPath) @@ -383,7 +464,14 @@ std::wstring CRelsGenerator::WriteImage(const std::wstring &strImagePath) if (strImage.empty()) return WriteHyperlinkImage(CorrectXmlString3(strImagePath), true); return WriteHyperlinkImage(strImage, false); } +std::wstring CRelsGenerator::WriteOleObject(const std::wstring& strOleObjectPath) +{ + std::wstring strOleObject = m_pManager->GenerateOleObject(strOleObjectPath); + if (strOleObject.empty()) + return WriteHyperlinkOleObject(CorrectXmlString3(strOleObjectPath), true); + return WriteHyperlinkOleObject(strOleObject, false); +} std::wstring CRelsGenerator::WriteSlideRef(const std::wstring &strLocation) { int sldNum = PPT::CExFilesInfo::GetSlideNumber(strLocation); diff --git a/MsBinaryFile/PptFile/PPTXWriter/ImageManager.h b/MsBinaryFile/PptFile/PPTXWriter/ImageManager.h index 789f97d5e91..5e357909ec8 100644 --- a/MsBinaryFile/PptFile/PPTXWriter/ImageManager.h +++ b/MsBinaryFile/PptFile/PPTXWriter/ImageManager.h @@ -43,25 +43,36 @@ class CMediaManager { private: - std::map m_mapMedia; + std::map m_mapMedia; - long m_lIndexNextAudio; - long m_lIndexNextVideo; - long m_lIndexNextImage; + long m_lIndexNextAudio; + long m_lIndexNextVideo; + long m_lIndexNextImage; + long m_lIndexNextOleObject; - std::wstring m_strDstMedia; + std::wstring m_strDstMedia; + std::wstring m_strTempMedia; + std::wstring m_strDstEmbeddings; public: CMediaManager(); ~CMediaManager(); void Clear(); std::wstring FindMedia(const std::wstring& strInput); + + void SetDstEmbeddings(const std::wstring& strDst); void SetDstMedia(const std::wstring& strDst); - std::wstring GenerateVideo(const std::wstring& strInput); - std::wstring GenerateAudio(const std::wstring& strInput); + void SetTempMedia(const std::wstring& strSrc); + + std::wstring GenerateVideo(const std::wstring& strInput, const std::wstring& strExt = L""); + std::wstring GenerateAudio(const std::wstring& strInput, const std::wstring& strExt = L""); + std::wstring GenerateOleObject(const std::wstring& strInput); std::wstring GenerateImage(const std::wstring& strInput); std::wstring GenerateImageJPEG(const std::wstring& strInput); - std::wstring GenerateMedia(const std::wstring& strInput, const std::wstring& Template, long & Indexer, const std::wstring& strDefaultExt); + + std::wstring GenerateMedia(const std::wstring& strInput, const std::wstring& Template, long& Indexer, const std::wstring& strDefaultExt); + std::wstring GenerateEmbedding(const std::wstring& strInput, const std::wstring& Template, long& Indexer, const std::wstring& strDefaultExt); + void WriteAudioCollection(const std::vector& audioCont); bool IsNeedDownload(const std::wstring& strFile); }; @@ -70,11 +81,11 @@ std::wstring CorrectXmlString3(const std::wstring & str); class CRelsGenerator { private: - PPT::CStringWriter m_oWriter; - int m_lNextRelsID; - std::map m_mapMediaRelsID; - CMediaManager* m_pManager; - std::map m_mapHyperlinks; + PPT::CStringWriter m_oWriter; + int m_lNextRelsID; + std::map m_mapMediaRelsID; + CMediaManager* m_pManager; + std::map m_mapHyperlinks; public: CRelsGenerator(CMediaManager* pManager); @@ -88,20 +99,21 @@ class CRelsGenerator void StartNotes(int nIndexSlide, bool bMaster); void StartSlide(int nIndexLayout, int nIndexNotes); void CloseRels(); - void SaveRels(const std::wstring &strFile); - std::wstring WriteHyperlink(const std::wstring &strHyperlink, bool isExternal = false); + void SaveRels(const std::wstring& strFile); + std::wstring WriteHyperlink(const std::wstring& strHyperlink, bool isExternal = false); void StartLayout(int nIndexTheme); - std::wstring WriteHyperlinkMedia(const std::wstring& strMedia, bool bExternal = true, bool newRIdAlways = false, std::wstring strRelsType = L"http://schemas.microsoft.com/office/2007/relationships/media"); std::wstring WriteHyperlinkImage(const std::wstring& strImage, bool bExternal = true); std::wstring WriteHyperlinkAudio(const std::wstring& strImage, bool bExternal = true); std::wstring WriteHyperlinkVideo(const std::wstring& strImage, bool bExternal = true); + std::wstring WriteHyperlinkOleObject(const std::wstring& strImage, bool bExternal = true); std::wstring WriteMedia(const std::wstring& strMediaPath); std::wstring WriteImage(const std::wstring& strImagePath); std::wstring WriteSlideRef(const std::wstring& strLocation); - std::wstring WriteAudio(const std::wstring& strAudioPath, bool & bExternal); - std::wstring WriteVideo(const std::wstring& strVideoPath, bool & bExternal); + std::wstring WriteAudio(const std::wstring& strAudioPath, bool& bExternal); + std::wstring WriteVideo(const std::wstring& strVideoPath, bool& bExternal); + std::wstring WriteOleObject(const std::wstring& strOleObjectPath); int getRId()const { return m_lNextRelsID; } }; diff --git a/MsBinaryFile/PptFile/PPTXWriter/ShapeWriter.cpp b/MsBinaryFile/PptFile/PPTXWriter/ShapeWriter.cpp index 80d800291db..c22e19b8f07 100644 --- a/MsBinaryFile/PptFile/PPTXWriter/ShapeWriter.cpp +++ b/MsBinaryFile/PptFile/PPTXWriter/ShapeWriter.cpp @@ -55,7 +55,7 @@ void CStylesWriter::ConvertStyleLevel(PPT::CTextStyleLevel& oLevel, PPT::CString {//дублирование CTextPFRun и CTextCFRun с ShapeWriter - todooo - вынести отдельно std::wstring str1; if (nLevel == 9) - str1 = _T("Language.get()); if (str_lang.length() > 0) - oWriter.WriteString(std::wstring(L" lang=\"") + str_lang + _T("\"")); + oWriter.WriteString(std::wstring(L" lang=\"") + str_lang + L"\""); } if (pCF->Size.is_init()) { @@ -387,7 +387,7 @@ std::wstring PPT::CShapeWriter::ConvertShadow(CShadow & shadow) std::wstring Preset; bool Inner = false; - if (shadow.Visible == false) return _T(""); + if (shadow.Visible == false) return L""; double dist = sqrt(shadow.DistanceY * shadow.DistanceY + shadow.DistanceX * shadow.DistanceX); double dir = 0; @@ -436,8 +436,6 @@ std::wstring PPT::CShapeWriter::ConvertShadow(CShadow & shadow) std::wstring strSY; if (shadow.ScaleYToY < 1 || shadow.ScaleYToY > 1) { - if (shadow.ScaleYToX < 1)shadow.ScaleYToY = -shadow.ScaleYToY; - strSY = L" sy=\"" + std::to_wstring((int)(shadow.ScaleYToY * 100000)) + L"\""; } std::wstring strSX; @@ -554,7 +552,8 @@ void PPT::CShapeWriter::WriteImageInfo() if (pImageElement->m_lID < 0) pImageElement->m_lID = m_lNextShapeID; - std::wstring strShapeID = std::to_wstring(pImageElement->m_lID); + COleObjectElement* pOleObjectElement = dynamic_cast(m_pElement.get()); + std::wstring strShapeID = std::to_wstring(pOleObjectElement ? 0 : pImageElement->m_lID); m_oWriter.WriteString(std::wstring(L"")); - WriteHyperlink(m_pElement->m_arrActions); m_oWriter.WriteString(std::wstring(L"")); - std::wstring str2 = _T(""); + std::wstring str2 = L""; m_oWriter.WriteString(str2); } void PPT::CShapeWriter::WriteGroupInfo() @@ -701,10 +699,89 @@ void PPT::CShapeWriter::WriteGroupInfo() m_oWriter.WriteString(std::wstring(L"")); - std::wstring str2 = _T(""); + std::wstring str2 = L""; m_oWriter.WriteString(str2); } +void PPT::CShapeWriter::WriteOleObjectInfo(const std::wstring& strRid, const std::wstring& xfrm) +{ + COleObjectElement* pOleObjectElement = dynamic_cast(m_pElement.get()); + if (!pOleObjectElement) return; + + m_oWriter.WriteString(std::wstring(L"")); + + m_oWriter.WriteString(std::wstring(L"")); + + if (pOleObjectElement->m_lID < 0) + pOleObjectElement->m_lID = m_lNextShapeID; + + std::wstring strTableID = std::to_wstring(pOleObjectElement->m_lID); + + m_oWriter.WriteString(std::wstring(L"m_sName.empty()) pOleObjectElement->m_sName = std::wstring(L"Group ") + strTableID; + + if (pOleObjectElement->m_bHidden) m_oWriter.WriteString(std::wstring(L" hidden=\"1\"")); + + m_oWriter.WriteString(std::wstring(L" name=\"")); + m_oWriter.WriteStringXML(pOleObjectElement->m_sName); + m_oWriter.WriteString(std::wstring(L"\"")); + + if (!pOleObjectElement->m_sDescription.empty()) + { + m_oWriter.WriteString(std::wstring(L" descr=\"")); + m_oWriter.WriteStringXML(XmlUtils::EncodeXmlStringExtend(pOleObjectElement->m_sDescription)); + m_oWriter.WriteString(std::wstring(L"\"")); + } + m_oWriter.WriteString(std::wstring(L">")); + if (!pOleObjectElement->m_sHyperlink.empty()) + { + std::wstring rId = m_pRels->WriteHyperlink(pOleObjectElement->m_sHyperlink); + + if (false == rId.empty()) + { + m_oWriter.WriteString(std::wstring(L"")); + } + } + m_oWriter.WriteString(std::wstring(L"")); + + m_oWriter.WriteString(std::wstring(L"")); + + ++m_lNextShapeID; + + m_oWriter.WriteString(std::wstring(L"")); + + m_oWriter.WriteString(std::wstring(L"")); + + if (pOleObjectElement->m_bChildAnchorEnabled || pOleObjectElement->m_bAnchorEnabled) + { + m_oWriter.WriteString(std::wstring(L"")); + } + m_oWriter.WriteString(std::wstring(L"")); + m_oWriter.WriteString(std::wstring(L"")); + m_oWriter.WriteString(std::wstring(L"m_strOleName.empty()) + { + m_oWriter.WriteString(std::wstring(L" name=\"") + pOleObjectElement->m_strOleName + L"\""); + } + m_oWriter.WriteString(std::wstring(L" r:id=\"") + strRid + L"\""); + + _INT64 width = (_INT64)(pOleObjectElement->m_bChildAnchorEnabled ? pOleObjectElement->m_rcChildAnchor.GetWidth() : pOleObjectElement->m_rcAnchor.GetWidth()) / 1.78; + _INT64 height = (_INT64)(pOleObjectElement->m_bChildAnchorEnabled ? pOleObjectElement->m_rcChildAnchor.GetHeight() : pOleObjectElement->m_rcAnchor.GetHeight()) / 1.78; + + m_oWriter.WriteString(std::wstring(L" imgW=\"") + std::to_wstring(width) + L"\""); + m_oWriter.WriteString(std::wstring(L" imgH=\"") + std::to_wstring(height) + L"\""); + + if (false == pOleObjectElement->m_strProgId.empty()) + { + m_oWriter.WriteString(std::wstring(L" progId=\"") + pOleObjectElement->m_strProgId + L"\""); + } + m_oWriter.WriteString(std::wstring(L">")); +} void PPT::CShapeWriter::WriteTableInfo() { CGroupElement* pGroupElement = dynamic_cast(m_pElement.get()); @@ -754,7 +831,7 @@ void PPT::CShapeWriter::WriteTableInfo() m_oWriter.WriteString(std::wstring(L"")); - std::wstring str2 = _T(""); + std::wstring str2 = L""; m_oWriter.WriteString(str2); } @@ -822,7 +899,7 @@ void PPT::CShapeWriter::WriteShapeInfo() m_oWriter.WriteString(std::wstring(L"m_lPlaceholderType > 0 && pShapeElement->m_lPlaceholderType != PT_Body_Empty) - m_oWriter.WriteString(std::wstring(L" type=\"") + GetPhType(pShapeElement->m_lPlaceholderType) + _T("\"")); + m_oWriter.WriteString(std::wstring(L" type=\"") + GetPhType(pShapeElement->m_lPlaceholderType) + L"\""); else if (pShapeElement->m_lPlaceholderID == -1) m_oWriter.WriteString(std::wstring(L" type=\"obj\"")); @@ -853,7 +930,7 @@ void PPT::CShapeWriter::WriteShapeInfo() m_oWriter.WriteString(std::wstring(L"")); } - std::wstring str2 = _T(""); + std::wstring str2 = L""; m_oWriter.WriteString(str2); } void PPT::CShapeWriter::Write3dShape() @@ -1118,7 +1195,7 @@ void PPT::CShapeWriter::WriteTextInfo(PPT::CTextCFRun* pLastCF) { std::wstring prstTxWarp = oox::Spt2WordArtShapeType((oox::MSOSPT)pShapeElement->m_lShapeType); m_oWriter.WriteString(std::wstring(L"")); + m_oWriter.WriteString(std::wstring(L" prst=\"") + prstTxWarp + L"\">"); m_oWriter.WriteString(std::wstring(L""));//модификаторы CPPTShape *pPPTShape = dynamic_cast(pShapeElement->m_pShape->getBaseShape().get()); @@ -1198,7 +1275,7 @@ void PPT::CShapeWriter::WriteTextInfo(PPT::CTextCFRun* pLastCF) { if (true) { - if ((nSpan == (nCountSpans - 1)) && (_T("\n") == pParagraph->m_arSpans[nSpan].m_strText || pParagraph->m_arSpans[nSpan].m_strText.empty()) ) + if ((nSpan == (nCountSpans - 1)) && (L"\n" == pParagraph->m_arSpans[nSpan].m_strText || pParagraph->m_arSpans[nSpan].m_strText.empty())) { PPT::CTextCFRun* pCF = &pParagraph->m_arSpans[nSpan].m_oRun; if ((pCF->Size.is_init()) && (pCF->Size.get() > 0) && (pCF->Size.get() < 4001)) @@ -1250,7 +1327,7 @@ void PPT::CShapeWriter::WriteTextInfo(PPT::CTextCFRun* pLastCF) std::wstring str_lang = m_lcidConverter.get_wstring(pCF->Language.get()); if (str_lang.length() > 0) - m_oWriter.WriteString(std::wstring(L" lang=\"") + str_lang + _T("\"")); + m_oWriter.WriteString(std::wstring(L" lang=\"") + str_lang + L"\""); } if ((pCF->Size.is_init()) && (pCF->Size.get() > 0) && (pCF->Size.get() < 4001)) { @@ -1300,7 +1377,7 @@ void PPT::CShapeWriter::WriteTextInfo(PPT::CTextCFRun* pLastCF) { if (pCF->Color->m_lSchemeIndex != -1) { - std::wstring strProp = _T("Color->m_lSchemeIndex) + _T("\"/>"); + std::wstring strProp = L"Color->m_lSchemeIndex) + L"\"/>"; m_oWriter.WriteString(strProp); } else @@ -1365,7 +1442,7 @@ void PPT::CShapeWriter::WriteTextInfo(PPT::CTextCFRun* pLastCF) } else { - std::wstring strT1 = _T(""); + std::wstring strT1 = L""; m_oWriter.WriteString(strT1); std::wstring strT = pParagraph->m_arSpans[nSpan].m_strText; @@ -1374,7 +1451,7 @@ void PPT::CShapeWriter::WriteTextInfo(PPT::CTextCFRun* pLastCF) m_oWriter.WriteString(strT); - std::wstring strT2 = _T(""); + std::wstring strT2 = L""; m_oWriter.WriteString(strT2); if ((pShapeElement->m_lPlaceholderType == PT_MasterSlideNumber || @@ -1387,11 +1464,11 @@ void PPT::CShapeWriter::WriteTextInfo(PPT::CTextCFRun* pLastCF) } } - std::wstring strEndPar = _T(""); + std::wstring strEndPar = L""; m_oWriter.WriteString(strEndPar); } - std::wstring str5 = _T(""); + std::wstring str5 = L""; m_oWriter.WriteString(str5); } @@ -1727,7 +1804,7 @@ std::vector CShapeWriter::getActionsByNum(const int num) } // TODO! Not work correct -std::wstring PPT::CShapeWriter::ConvertTable () +std::wstring PPT::CShapeWriter::ConvertTable() { CGroupElement* pGroupElement = dynamic_cast(m_pElement.get()); if (!pGroupElement) return L""; @@ -1805,7 +1882,7 @@ std::wstring PPT::CShapeWriter::ConvertShape() if (pImageElement) return ConvertImage(); if (pGroupElement) return ConvertGroup(); - if (pShapeElement == NULL) return _T(""); + if (pShapeElement == NULL) return L""; std::wstring prstTxWarp; std::wstring prstGeom = oox::Spt2ShapeType_mini((oox::MSOSPT)pShapeElement->m_lShapeType); @@ -2003,15 +2080,14 @@ void PPT::CShapeWriter::ParseXmlAlternative(const std::wstring & xml) } } - std::wstring PPT::CShapeWriter::ConvertImage() -{ +{ CImageElement* pImageElement = dynamic_cast(m_pElement.get()); if (!pImageElement) return L""; - + if (pImageElement->m_bImagePresent == false) { - if (pImageElement->m_sName.empty()) return _T(""); + if (pImageElement->m_sName.empty()) return L""; //ppt_presentation.ppt - ссылка на файл на диске pImageElement->m_strImageFileName.clear(); @@ -2027,27 +2103,75 @@ std::wstring PPT::CShapeWriter::ConvertImage() strRid = m_pRels->WriteHyperlinkImage(CorrectXmlString3(pImageElement->m_sImageName)); } - if (strRid.empty()) return _T(""); + if (strRid.empty()) return L""; - m_oWriter.WriteString(std::wstring(L"")); - - WriteImageInfo(); + std::wstring strAnchor; CGeomShapeInfo oInfo; - oInfo.m_lOriginalWidth = m_pElement->m_bChildAnchorEnabled ? (LONG)m_pElement->m_rcChildAnchor.GetWidth() : (LONG)m_pElement->m_rcAnchor.GetWidth(); - oInfo.m_lOriginalHeight = m_pElement->m_bChildAnchorEnabled ? (LONG)m_pElement->m_rcChildAnchor.GetHeight() : (LONG)m_pElement->m_rcAnchor.GetHeight(); + oInfo.m_lOriginalWidth = m_pElement->m_bChildAnchorEnabled ? (LONG)m_pElement->m_rcChildAnchor.GetWidth() : (LONG)m_pElement->m_rcAnchor.GetWidth(); + oInfo.m_lOriginalHeight = m_pElement->m_bChildAnchorEnabled ? (LONG)m_pElement->m_rcChildAnchor.GetHeight() : (LONG)m_pElement->m_rcAnchor.GetHeight(); m_pElement->NormalizeCoordsByMetric(); oInfo.SetBounds(m_pElement->m_bChildAnchorEnabled ? m_pElement->m_rcChildAnchor : m_pElement->m_rcAnchor); oInfo.m_dRotate = pImageElement->m_dRotate; - oInfo.m_bFlipH = pImageElement->m_bFlipH; - oInfo.m_bFlipV = pImageElement->m_bFlipV; + oInfo.m_bFlipH = pImageElement->m_bFlipH; + oInfo.m_bFlipV = pImageElement->m_bFlipV; + + if (pImageElement->m_bChildAnchorEnabled || pImageElement->m_bAnchorEnabled) + { + if (0 != pImageElement->m_dRotate) + { + strAnchor += L" rot=\"" + std::to_wstring((int)(pImageElement->m_dRotate * 60000)) + L"\""; + } + if (pImageElement->m_bFlipH) + { + strAnchor += L" flipH=\"1\""; + } + if (pImageElement->m_bFlipV) + { + strAnchor += L" flipV=\"1\""; + } + strAnchor += L">"; + + strAnchor += L"m_bChildAnchorEnabled ? (int)pImageElement->m_rcChildAnchor.left : (int)pImageElement->m_rcAnchor.left) + + L"\" y=\"" + + std::to_wstring(pImageElement->m_bChildAnchorEnabled ? (int)pImageElement->m_rcChildAnchor.top : (int)pImageElement->m_rcAnchor.top) + + L"\"/>"; + + _INT64 width = (_INT64)(pImageElement->m_bChildAnchorEnabled ? pImageElement->m_rcChildAnchor.GetWidth() : pImageElement->m_rcAnchor.GetWidth()); + _INT64 height = (_INT64)(pImageElement->m_bChildAnchorEnabled ? pImageElement->m_rcChildAnchor.GetHeight() : pImageElement->m_rcAnchor.GetHeight()); + + if ((width > 0 && height > 0) && ((_UINT64)width) < 0xffffffffffff && ((_UINT64)height) < 0xffffffffffff) + { + strAnchor += L""; + } + else + { + strAnchor += L""; + } + } + + COleObjectElement* pOleObjectElement = dynamic_cast(m_pElement.get()); + if (pOleObjectElement) + { + std::wstring strRidOleObject = m_pRels->WriteOleObject(pOleObjectElement->m_strBinFileName); + if (false == strRidOleObject.empty()) + { + WriteOleObjectInfo(strRidOleObject, strAnchor); + } + else pOleObjectElement = NULL; + } + + m_oWriter.WriteString(std::wstring(L"")); + + WriteImageInfo(); m_oWriter.WriteString(std::wstring(L"")); - std::wstring strWrite = _T("m_lpictureBrightness != 0 || pImageElement->m_lpictureContrast != 0x10000) { @@ -2109,41 +2233,7 @@ std::wstring PPT::CShapeWriter::ConvertImage() if (pImageElement->m_bChildAnchorEnabled || pImageElement->m_bAnchorEnabled) { - std::wstring str; - - m_oWriter.WriteString(std::wstring(L"m_dRotate) - { - m_oWriter.WriteString(L" rot=\"" + std::to_wstring((int)(pImageElement->m_dRotate * 60000)) + L"\""); - } - if (pImageElement->m_bFlipH) - { - m_oWriter.WriteString(std::wstring(L" flipH=\"1\"")); - } - if (pImageElement->m_bFlipV) - { - m_oWriter.WriteString(std::wstring(L" flipV=\"1\"")); - } - m_oWriter.WriteString(std::wstring(L">")); - - m_oWriter.WriteString(L"m_bChildAnchorEnabled ? (int)pImageElement->m_rcChildAnchor.left : (int)pImageElement->m_rcAnchor.left) - + L"\" y=\"" + - std::to_wstring(pImageElement->m_bChildAnchorEnabled ? (int)pImageElement->m_rcChildAnchor.top : (int)pImageElement->m_rcAnchor.top) + - L"\"/>"); - - _INT64 width = (_INT64)(pImageElement->m_bChildAnchorEnabled ? pImageElement->m_rcChildAnchor.GetWidth() : pImageElement->m_rcAnchor.GetWidth()); - _INT64 height = (_INT64)(pImageElement->m_bChildAnchorEnabled ? pImageElement->m_rcChildAnchor.GetHeight() : pImageElement->m_rcAnchor.GetHeight()); - - if (( width > 0 && height > 0 ) && ((_UINT64)width) < 0xffffffffffff && ((_UINT64)height) < 0xffffffffffff) - { - m_oWriter.WriteString(L""); - } - else - { - m_oWriter.WriteString(L""); - } - m_oWriter.WriteString(std::wstring(L"")); + m_oWriter.WriteString(std::wstring(L"")); } m_oWriter.WriteString(std::wstring(L"")); @@ -2157,6 +2247,14 @@ std::wstring PPT::CShapeWriter::ConvertImage() m_oWriter.WriteString(std::wstring(L"")); m_oWriter.WriteString(std::wstring(L"")); + + if (pOleObjectElement) + { + m_oWriter.WriteString(std::wstring(L"")); + m_oWriter.WriteString(std::wstring(L"")); + m_oWriter.WriteString(std::wstring(L"")); + m_oWriter.WriteString(std::wstring(L"")); + } pImageElement = NULL; return m_oWriter.GetData(); diff --git a/MsBinaryFile/PptFile/PPTXWriter/ShapeWriter.h b/MsBinaryFile/PptFile/PPTXWriter/ShapeWriter.h index e9045cb9c4f..76cebf1e0f9 100644 --- a/MsBinaryFile/PptFile/PPTXWriter/ShapeWriter.h +++ b/MsBinaryFile/PptFile/PPTXWriter/ShapeWriter.h @@ -110,26 +110,26 @@ namespace PPT switch (TypePPTX) { - case 0: return _T("body"); - case 100: return _T("body"); // для master pages - case 1: return _T("chart"); - case 2: return _T("clipArt"); - case 3: return _T("ctrTitle"); - case 4: return _T("dgm"); - case 5: return _T("dt"); - case 6: return _T("ftr"); - case 7: return _T("hdr"); - case 8: return _T("media"); - case 9: return _T("obj"); - case 10: return _T("pic"); - case 11: return _T("sldImg"); - case 12: return _T("sldNum"); - case 13: return _T("subTitle"); - case 14: return _T("tbl"); - case 15: return _T("title"); + case 0: return L"body"; + case 100: return L"body"; // для master pages + case 1: return L"chart"; + case 2: return L"clipArt"; + case 3: return L"ctrTitle"; + case 4: return L"dgm"; + case 5: return L"dt"; + case 6: return L"ftr"; + case 7: return L"hdr"; + case 8: return L"media"; + case 9: return L"obj"; + case 10: return L"pic"; + case 11: return L"sldImg"; + case 12: return L"sldNum"; + case 13: return L"subTitle"; + case 14: return L"tbl"; + case 15: return L"title"; default: break; } - return _T("body"); + return L"body"; } class CShapeWriter @@ -360,7 +360,7 @@ namespace PPT m_pFontManager->SetStringGID(m_oFont.StringGID); - if (_T("") == m_oFont.Path) + if (L"" == m_oFont.Path) { m_pFontManager->LoadFontByName(m_oFont.Name, m_oFont.Size, m_oFont.GetStyle(), m_dDpiX, m_dDpiY); } @@ -444,7 +444,7 @@ namespace PPT } void Close() { - std::wstring str = _T(""); + std::wstring str = L""; m_oWriterPath.WriteString(str); } @@ -457,7 +457,8 @@ namespace PPT std::wstring ConvertTableCell(); void WriteShapeInfo(); void WriteImageInfo(); - void WriteTextInfo(CTextCFRun *pLastCF = nullptr); + void WriteOleObjectInfo(const std::wstring& strRid, const std::wstring& xfrm); + void WriteTextInfo(CTextCFRun *pLastCF = nullptr); static std::wstring WriteBullets(CTextPFRun* pPF, CRelsGenerator *pRels); void Write3dShape(); std::wstring getOWriterStr() const; diff --git a/MsBinaryFile/PptFile/PPTXWriter/TableWriter.cpp b/MsBinaryFile/PptFile/PPTXWriter/TableWriter.cpp index 393d0504862..d20540b458a 100644 --- a/MsBinaryFile/PptFile/PPTXWriter/TableWriter.cpp +++ b/MsBinaryFile/PptFile/PPTXWriter/TableWriter.cpp @@ -243,7 +243,15 @@ bool ProtoTable::fillCells(std::vector &arrCells) if (top == m_arrTop[posRow]) break; for (; posCol < countCol; posCol++) if (left == m_arrLeft[posCol]) break; - TCell* pParent = &m_table[posRow][posCol]; + TCell* pParent = NULL; + + if (posRow < m_table.size()) + { + if (posCol < m_table[posRow].size()) + { + pParent = &m_table[posRow][posCol]; + } + } UINT posRightCol = 0, posBottomRow = 0; for (; posBottomRow < countRow; posBottomRow++) @@ -263,9 +271,11 @@ bool ProtoTable::fillCells(std::vector &arrCells) if (posRow == cRow) tCell.setRowSpan(posBottomRow - cRow); } - pParent->setPParent(nullptr); - pParent->setPShape(ptrCell); - + if (pParent) + { + pParent->setPParent(nullptr); + pParent->setPShape(ptrCell); + } // pParent->setGridSpan(posRightCol - posCol); // pParent->setRowSpan(posBottomRow - posRow); } @@ -562,7 +572,7 @@ bool TCell::isRealCell() const return true; } -void TCell::FillTxBody(PPTX::Logic::TxBody &oTxBody, CTextCFRun* pLastCF) +void TCell::FillTxBody(PPTX::Logic::TxBody& oTxBody, CTextCFRun* pLastCF) { TxBodyConverter txBodyConverter(m_ptrSpElCell, m_pRels, pLastCF); txBodyConverter.FillTxBody(oTxBody); @@ -570,6 +580,8 @@ void TCell::FillTxBody(PPTX::Logic::TxBody &oTxBody, CTextCFRun* pLastCF) void TCell::FillTcPr(PPTX::Logic::TableCellProperties &oTcPr) { + if (!m_ptrSpElCell) return; + auto pShapeEl = static_cast(m_ptrSpElCell.get()); auto pShape = pShapeEl->m_pShape; //anchor @@ -732,7 +744,8 @@ void TCell::FillLn(PPTX::Logic::Ln &Ln, TCell::eBorderPossition eBP, CElementPtr pLineEnd->len = new PPTX::Limit::LineEndSize; Ln.tailEnd = pLineEnd; - Ln.Join.type = PPTX::Logic::eJoin::JoinRound; + Ln.join.Init(); + Ln.join->type = PPTX::Logic::eJoin::JoinRound; } void TCell::SetLnName(PPTX::Logic::Ln &Ln, eBorderPossition eBP) const diff --git a/MsBinaryFile/PptFile/Reader/ClassesAtom.cpp b/MsBinaryFile/PptFile/Reader/ClassesAtom.cpp index c22eabd85da..e173a623cb6 100644 --- a/MsBinaryFile/PptFile/Reader/ClassesAtom.cpp +++ b/MsBinaryFile/PptFile/Reader/ClassesAtom.cpp @@ -68,8 +68,8 @@ void CUserEdit::FromAtom(CRecordUserEditAtom *pAtom) CCurrentUser::CCurrentUser() { - m_bIsEncrypt = false; - m_nOffsetToCurrentEdit = 0; + m_bIsEncrypt = false; + m_nOffsetToCurrentEdit = 0; } CCurrentUser::~CCurrentUser() diff --git a/MsBinaryFile/PptFile/Reader/PPTDocumentInfo.cpp b/MsBinaryFile/PptFile/Reader/PPTDocumentInfo.cpp index 408ff9eb5e0..f5623ebbef5 100644 --- a/MsBinaryFile/PptFile/Reader/PPTDocumentInfo.cpp +++ b/MsBinaryFile/PptFile/Reader/PPTDocumentInfo.cpp @@ -33,7 +33,7 @@ using namespace PPT; -CPPTDocumentInfo::CPPTDocumentInfo() : m_oCurrentUser(), m_bMacros(true) +CPPTDocumentInfo::CPPTDocumentInfo() : m_oCurrentUser(), m_bMacroEnabled(true), m_pStream(NULL) { } @@ -57,6 +57,7 @@ void CPPTDocumentInfo::Clear() bool CPPTDocumentInfo::ReadFromStream(CRecordCurrentUserAtom *pCurrentUser, POLE::Stream *pStream) { + m_pStream = pStream; m_oCurrentUser.FromAtom(pCurrentUser); _UINT32 offsetToEdit = m_oCurrentUser.m_nOffsetToCurrentEdit; @@ -78,14 +79,13 @@ bool CPPTDocumentInfo::ReadFromStream(CRecordCurrentUserAtom *pCurrentUser, POLE pInfo->m_pDocumentInfo = this; - pInfo->m_bEncrypt = m_oCurrentUser.m_bIsEncrypt; - pInfo->m_strPassword = m_strPassword; - pInfo->m_bMacros = m_bMacros; + pInfo->m_bEncrypt = m_oCurrentUser.m_bIsEncrypt; + pInfo->m_strPassword = m_strPassword; + pInfo->m_bMacroEnabled = m_bMacroEnabled; bool bResult = pInfo->ReadFromStream(&oUserAtom, pStream); - m_bMacros = pInfo->m_bMacros; - offsetToEdit = pInfo->m_oUser.m_nOffsetLastEdit; + offsetToEdit = pInfo->m_oUser.m_nOffsetLastEdit; m_oCurrentUser.m_bIsEncrypt = pInfo->m_bEncrypt; if (bResult == false) @@ -105,9 +105,36 @@ bool CPPTDocumentInfo::ReadFromStream(CRecordCurrentUserAtom *pCurrentUser, POLE pInfo = NULL; } - return true; } +std::wstring CPPTDocumentInfo::GetBinFromStg(const std::wstring& name, _UINT32 nRef) +{ + for (size_t i = 0; i < m_arUsers.size(); ++i) + { + std::map<_UINT32, _UINT32>::iterator nIndexPsrRef = m_arUsers[i]->m_mapOffsetInPIDs.find(nRef); + if (m_arUsers[i]->m_mapOffsetInPIDs.end() != nIndexPsrRef) + { + std::wstring result; + _UINT32 offset_stream = nIndexPsrRef->second; + StreamUtils::StreamSeek(offset_stream, m_pStream); + + SRecordHeader oHeader; + oHeader.ReadFromStream(m_pStream); + + CRecordExObjStg* pExObjStg = new CRecordExObjStg(name, m_pCommonInfo->tempPath); + + if (pExObjStg) + { + pExObjStg->ReadFromStream(oHeader, m_pStream); + result = pExObjStg->m_sFileName; + + RELEASEOBJECT(pExObjStg); + } + return result; + } + } + return L""; +} bool CPPTDocumentInfo::LoadDocument() { @@ -115,8 +142,10 @@ bool CPPTDocumentInfo::LoadDocument() try { - m_arUsers[0]->ReadExtenalObjects(); + m_arUsers[0]->ReadExtenalObjects(); // todooo ???? прочитать по всем (см 66864) m_arUsers[0]->FromDocument(); + + m_bMacroEnabled = m_arUsers[0]->m_bMacroEnabled; } catch(int) //error code { diff --git a/MsBinaryFile/PptFile/Reader/PPTDocumentInfo.h b/MsBinaryFile/PptFile/Reader/PPTDocumentInfo.h index bc29978a11c..dfa8caa5eb2 100644 --- a/MsBinaryFile/PptFile/Reader/PPTDocumentInfo.h +++ b/MsBinaryFile/PptFile/Reader/PPTDocumentInfo.h @@ -39,13 +39,15 @@ namespace PPT class CPPTDocumentInfo { public: + friend class CPPTUserInfo; + _commonInfo* m_pCommonInfo = NULL; CCurrentUser m_oCurrentUser; std::vector m_arUsers; std::map m_mapStoreImageFile; std::wstring m_strPassword; - bool m_bMacros; + bool m_bMacroEnabled; std::wstring m_app_xml; std::wstring m_core_xml; @@ -57,5 +59,9 @@ class CPPTDocumentInfo bool ReadFromStream(CRecordCurrentUserAtom* pCurrentUser, POLE::Stream* pStream); bool LoadDocument(); + + std::wstring GetBinFromStg(const std::wstring& name, _UINT32 nRef); +private: + POLE::Stream* m_pStream; }; } diff --git a/MsBinaryFile/PptFile/Reader/PPTDocumentInfoOneUser.cpp b/MsBinaryFile/PptFile/Reader/PPTDocumentInfoOneUser.cpp index ef0d894553a..70603dae79e 100644 --- a/MsBinaryFile/PptFile/Reader/PPTDocumentInfoOneUser.cpp +++ b/MsBinaryFile/PptFile/Reader/PPTDocumentInfoOneUser.cpp @@ -35,48 +35,47 @@ #include "../Records/RecordsIncluder.h" -//#include "../Records/ExObjListContainer.h" -//#include "../Records/SoundCollectionContainer.h" -//#include "../Records/SoundContainer.h" + //#include "../Records/ExObjListContainer.h" + //#include "../Records/SoundCollectionContainer.h" + //#include "../Records/SoundContainer.h" #include "../Enums/_includer.h" using namespace PPT; using namespace ODRAW; -CPPTUserInfo::CPPTUserInfo() : CDocument(), - m_oUser(), - m_mapOffsetInPIDs(), - m_oDocument(), - m_mapMasters(), - m_mapNotes(), - m_mapSlides(), - m_bEncrypt(false), - m_pStorageDecrypt(NULL), - m_pDecryptor(NULL), - m_arOffsetPictures() +CPPTUserInfo::CPPTUserInfo() : CDocument(), +m_oUser(), +m_mapOffsetInPIDs(), +m_oDocument(), +m_mapMasters(), +m_mapNotes(), +m_mapSlides(), +m_bEncrypt(false), +m_pStorageDecrypt(NULL), +m_pDecryptor(NULL), +m_arOffsetPictures() { - m_VbaProjectStg = NULL; - m_pDocumentInfo = NULL; - m_lIndexThisUser = -1; + m_pDocumentInfo = NULL; + m_lIndexThisUser = -1; - m_pNotesMasterWrapper = NULL; - m_pHandoutMasterWrapper = NULL; + m_pNotesMasterWrapper = NULL; + m_pHandoutMasterWrapper = NULL; - m_nWriteSlideTimeOffset = 0.0; - m_nWriteSlideTime = 0.0; + m_nWriteSlideTimeOffset = 0.0; + m_nWriteSlideTime = 0.0; - m_bIsSetupEmpty = false; + m_bIsSetupEmpty = false; - m_bRtl = false; - m_bShowComments = false; + m_bRtl = false; + m_bShowComments = false; - m_bHasDate = false; - m_bHasSlideNumber = false; - m_bHasFooter = false; - m_nFormatDate = 1; + m_bHasDate = false; + m_bHasSlideNumber = false; + m_bHasFooter = false; + m_nFormatDate = 1; - m_current_elements = NULL; - m_current_level = 0; + m_current_elements = NULL; + m_current_level = 0; } CPPTUserInfo::~CPPTUserInfo() @@ -90,7 +89,6 @@ void CPPTUserInfo::Clear() RELEASEOBJECT(m_pDecryptor); RELEASEOBJECT(m_pStorageDecrypt); - RELEASEOBJECT(m_VbaProjectStg); for (std::map<_UINT32, CRecordSlide*>::iterator pPair = m_mapSlides.begin(); pPair != m_mapSlides.end(); ++pPair) { @@ -137,7 +135,7 @@ void CPPTUserInfo::Clear() // } // m_mapAnimations.clear(); - m_mapTransitions.clear (); + m_mapTransitions.clear(); m_arOffsetPictures.clear(); } @@ -171,7 +169,7 @@ bool CPPTUserInfo::ReadFromStream(CRecordUserEditAtom* pUser, POLE::Stream* pStr StreamUtils::StreamSeek(pPair->second, pStream); oHeader.ReadFromStream(pStream); - if (RT_CryptSession10Container == oHeader.RecType) + if (RT_CryptSession10Container == oHeader.RecType) { m_bEncrypt = true; m_oEncryptionHeader.ReadFromStream(oHeader, pStream); @@ -199,11 +197,11 @@ bool CPPTUserInfo::ReadFromStream(CRecordUserEditAtom* pUser, POLE::Stream* pStr return true; } -void CPPTUserInfo::DecryptStream(POLE::Stream *pStream, int block) +void CPPTUserInfo::DecryptStream(POLE::Stream* pStream, int block) { long size = long(pStream->size() - pStream->tell()); - POLE::Stream *pStreamTmp = new POLE::Stream(m_pStorageDecrypt, L"Tmp" + std::to_wstring(m_arStreamDecrypt.size() + 1), true, size); + POLE::Stream* pStreamTmp = new POLE::Stream(m_pStorageDecrypt, L"Tmp" + std::to_wstring(m_arStreamDecrypt.size() + 1), true, size); unsigned char* data_stream = new unsigned char[size]; pStream->read(data_stream, size); @@ -227,7 +225,7 @@ bool CPPTUserInfo::ReadDocumentPersists(POLE::Stream* pStream) StreamUtils::StreamSeek(offset_stream, pStream); - POLE::Stream * pStreamTmp = pStream; + POLE::Stream* pStreamTmp = pStream; if (m_pDecryptor) { DecryptStream(pStream, m_oUser.m_nDocumentRef); @@ -252,7 +250,7 @@ bool CPPTUserInfo::ReadDocumentPersists(POLE::Stream* pStream) offset_stream = nIndexPsrRef->second; StreamUtils::StreamSeek(offset_stream, pStream); - POLE::Stream *pStreamTmp = pStream; + POLE::Stream* pStreamTmp = pStream; if (m_pDecryptor) { DecryptStream(pStream, m_oDocument.m_arMasterPersists[index].m_nPsrRef); @@ -262,11 +260,11 @@ bool CPPTUserInfo::ReadDocumentPersists(POLE::Stream* pStream) CRecordSlide* pSlide = new CRecordSlide(); pSlide->m_pCommonInfo = m_pDocumentInfo->m_pCommonInfo; - + pSlide->ReadFromStream(oHeader, pStreamTmp); pSlide->m_oPersist = m_oDocument.m_arMasterPersists[index]; - pSlide->m_Index = m_mapMasters.size(); + pSlide->m_Index = m_mapMasters.size(); m_mapMasters.insert(m_mapMasters.end(), std::pair<_UINT32, CRecordSlide*>(m_oDocument.m_arMasterPersists[index].m_nSlideID, pSlide)); pSlide = NULL; } @@ -285,7 +283,7 @@ bool CPPTUserInfo::ReadDocumentPersists(POLE::Stream* pStream) offset_stream = nIndexPsrRef->second; StreamUtils::StreamSeek(offset_stream, pStream); - POLE::Stream *pStreamTmp = pStream; + POLE::Stream* pStreamTmp = pStream; if (m_pDecryptor) { DecryptStream(pStream, m_oDocument.m_arNotePersists[index].m_nPsrRef); @@ -295,11 +293,11 @@ bool CPPTUserInfo::ReadDocumentPersists(POLE::Stream* pStream) CRecordSlide* pSlide = new CRecordSlide(); pSlide->m_pCommonInfo = m_pDocumentInfo->m_pCommonInfo; - + pSlide->ReadFromStream(oHeader, pStreamTmp); pSlide->m_oPersist = m_oDocument.m_arNotePersists[index]; - pSlide->m_Index = m_mapNotes.size(); + pSlide->m_Index = m_mapNotes.size(); m_mapNotes.insert(std::pair<_UINT32, CRecordSlide*>(m_oDocument.m_arNotePersists[index].m_nSlideID, pSlide)); pSlide = NULL; } @@ -319,7 +317,7 @@ bool CPPTUserInfo::ReadDocumentPersists(POLE::Stream* pStream) offset_stream = (long)nIndexPsrRef->second; StreamUtils::StreamSeek(offset_stream, pStream); - POLE::Stream *pStreamTmp = pStream; + POLE::Stream* pStreamTmp = pStream; if (m_pDecryptor) { DecryptStream(pStream, m_oDocument.m_arSlidePersists[index].m_nPsrRef); @@ -329,20 +327,20 @@ bool CPPTUserInfo::ReadDocumentPersists(POLE::Stream* pStream) CRecordSlide* pSlide = new CRecordSlide(); pSlide->m_pCommonInfo = m_pDocumentInfo->m_pCommonInfo; - + pSlide->ReadFromStream(oHeader, pStreamTmp); - pSlide->m_oPersist = m_oDocument.m_arSlidePersists[index]; + pSlide->m_oPersist = m_oDocument.m_arSlidePersists[index]; - pSlide->m_Index = m_mapSlides.size(); // in m_arrSlidesOrder + pSlide->m_Index = m_mapSlides.size(); // in m_arrSlidesOrder - m_mapSlides.insert( std::pair<_UINT32, CRecordSlide*>(m_oDocument.m_arSlidePersists[index].m_nSlideID, pSlide )); + m_mapSlides.insert(std::pair<_UINT32, CRecordSlide*>(m_oDocument.m_arSlidePersists[index].m_nSlideID, pSlide)); - if ( pSlide->m_bExistsTransition ) + if (pSlide->m_bExistsTransition) { - m_mapTransitions.insert (std::pair<_UINT32, CSlideShowSlideInfoAtom>( (_UINT32)index, pSlide->m_oSlideShowSlideInfoAtom )); + m_mapTransitions.insert(std::pair<_UINT32, CSlideShowSlideInfoAtom>((_UINT32)index, pSlide->m_oSlideShowSlideInfoAtom)); } - if ( pSlide->m_pSlideProgTagsContainer ) + if (pSlide->m_pSlideProgTagsContainer) { // Animations::CSlideTimeLine* pEffects = pSlide->m_pSlideProgTagsContainer->GetTimeLine (); // if (pEffects) @@ -353,7 +351,7 @@ bool CPPTUserInfo::ReadDocumentPersists(POLE::Stream* pStream) } else { - m_mapSlides.insert( std::pair<_UINT32, CRecordSlide*>(m_oDocument.m_arSlidePersists[index].m_nSlideID, NULL)); + m_mapSlides.insert(std::pair<_UINT32, CRecordSlide*>(m_oDocument.m_arSlidePersists[index].m_nSlideID, NULL)); } m_arrSlidesOrder.push_back(m_oDocument.m_arSlidePersists[index].m_nSlideID); } @@ -369,7 +367,7 @@ bool CPPTUserInfo::ReadDocumentPersists(POLE::Stream* pStream) offset_stream = nIndexPsrRef->second; StreamUtils::StreamSeek(offset_stream, pStream); - POLE::Stream *pStreamTmp = pStream; + POLE::Stream* pStreamTmp = pStream; if (m_pDecryptor) { DecryptStream(pStream, oArrayDoc[0]->m_nNotesMasterPersistIDRef); @@ -379,12 +377,12 @@ bool CPPTUserInfo::ReadDocumentPersists(POLE::Stream* pStream) CRecordSlide* pSlide = new CRecordSlide(); pSlide->m_pCommonInfo = m_pDocumentInfo->m_pCommonInfo; - + pSlide->ReadFromStream(oHeader, pStreamTmp); pSlide->m_oPersist.m_nPsrRef = oArrayDoc[0]->m_nNotesMasterPersistIDRef; - pSlide->m_Index = 0; + pSlide->m_Index = 0; - m_mapNotesMasters.insert( std::pair<_UINT32, CRecordSlide*>(0, pSlide )); + m_mapNotesMasters.insert(std::pair<_UINT32, CRecordSlide*>(0, pSlide)); } nIndexPsrRef = m_mapOffsetInPIDs.find(oArrayDoc[0]->m_nHandoutMasterPersistIDRef); @@ -393,7 +391,7 @@ bool CPPTUserInfo::ReadDocumentPersists(POLE::Stream* pStream) offset_stream = nIndexPsrRef->second; StreamUtils::StreamSeek(offset_stream, pStream); - POLE::Stream *pStreamTmp = pStream; + POLE::Stream* pStreamTmp = pStream; if (m_pDecryptor) { DecryptStream(pStream, oArrayDoc[0]->m_nHandoutMasterPersistIDRef); @@ -402,60 +400,16 @@ bool CPPTUserInfo::ReadDocumentPersists(POLE::Stream* pStream) oHeader.ReadFromStream(pStreamTmp); CRecordSlide* pSlide = new CRecordSlide(); - pSlide->m_pCommonInfo = m_pDocumentInfo->m_pCommonInfo; - + pSlide->m_pCommonInfo = m_pDocumentInfo->m_pCommonInfo; + pSlide->ReadFromStream(oHeader, pStreamTmp); pSlide->m_oPersist.m_nPsrRef = oArrayDoc[0]->m_nHandoutMasterPersistIDRef; - pSlide->m_Index = 0; + pSlide->m_Index = 0; - m_mapHandoutMasters.insert( std::pair<_UINT32, CRecordSlide*>(0, pSlide )); + m_mapHandoutMasters.insert(std::pair<_UINT32, CRecordSlide*>(0, pSlide)); } } - if (m_bMacros) - { - m_bMacros = false; - std::vector oArrayDocInfo; - m_oDocument.GetRecordsByType(&oArrayDocInfo, true, true); - - CRecordVBAInfoAtom* pVbaAtom = nullptr; - if (!oArrayDocInfo.empty()) - pVbaAtom = oArrayDocInfo[0]->getVBAInfoAtom(); - if (pVbaAtom) - { - if (pVbaAtom->m_nHasMacros) - { - nIndexPsrRef = m_mapOffsetInPIDs.find(pVbaAtom->m_nObjStgDataRef); - - if (m_mapOffsetInPIDs.end() != nIndexPsrRef) - { - offset_stream = nIndexPsrRef->second; - StreamUtils::StreamSeek(offset_stream, pStream); - - POLE::Stream *pStreamTmp = pStream; - if (m_pDecryptor) - { - DecryptStream(pStream, pVbaAtom->m_nObjStgDataRef); - pStreamTmp = m_arStreamDecrypt.back()->stream_; - } - oHeader.ReadFromStream(pStreamTmp); - - m_VbaProjectStg = new CRecordVbaProjectStg(m_pDocumentInfo->m_pCommonInfo->tempPath); - m_VbaProjectStg->ReadFromStream(oHeader, pStreamTmp); - - if (m_VbaProjectStg->m_sFileName.empty()) - { - RELEASEOBJECT(m_VbaProjectStg); - } - else - { - m_sVbaProjectFile = m_VbaProjectStg->m_sFileName; - m_bMacros = true; - } - } - } - } - } return true; } //-------------------------------------------------------------------------------------------- @@ -467,7 +421,7 @@ void CPPTUserInfo::ReadExtenalObjects() PPT::CExFilesInfo oInfo; oInfo.m_strFilePath = m_oExMedia.m_strPresentationDirectory; - oInfo.m_dwID = 0xFFFFFFFF; + oInfo.m_dwID = 0xFFFFFFFF; m_oExMedia.m_arImages.push_back(oInfo); // читаем все внешние объекты @@ -495,8 +449,8 @@ void CPPTUserInfo::ReadExtenalObjects() { CFontProperty oFont; - oFont.Name = oArrayFonts[nIndex]->m_strFaceName; - oFont.Charset = oArrayFonts[nIndex]->m_lfCharSet; + oFont.Name = oArrayFonts[nIndex]->m_strFaceName; + oFont.Charset = oArrayFonts[nIndex]->m_lfCharSet; oFont.PitchFamily = oArrayFonts[nIndex]->m_lfPitchAndFamily; m_arrFonts.push_back(oFont); @@ -507,6 +461,27 @@ void CPPTUserInfo::ReadExtenalObjects() m_bIsSetupEmpty = TRUE; m_arrBlipStore[0]->SetUpPicturesInfos(&m_arOffsetPictures); } + + if (m_bMacroEnabled) + { + m_bMacroEnabled = false; + std::vector oArrayDocInfo; + m_oDocument.GetRecordsByType(&oArrayDocInfo, true, true); + + CRecordVBAInfoAtom* pVbaAtom = nullptr; + if (!oArrayDocInfo.empty()) + pVbaAtom = oArrayDocInfo[0]->getVBAInfoAtom(); + + if (pVbaAtom) + { + if (pVbaAtom->m_nHasMacros) + { + m_sVbaProjectFile = m_pDocumentInfo->GetBinFromStg(L"vbaProject.bin", pVbaAtom->m_nObjStgDataRef); + + m_bMacroEnabled = (false == m_sVbaProjectFile.empty()); + } + } + } } void CPPTUserInfo::FromDocument() @@ -546,34 +521,49 @@ void CPPTUserInfo::FromDocument() if (0 != oArrayHeadersFootersInfo.size()) { - for (int i = 0 ; i < 3; i++) m_PlaceholdersReplaceString[i] = oArrayHeadersFootersInfo[0]->m_HeadersFootersString[i]; + for (int i = 0; i < 3; i++) + { + m_PlaceholdersReplaceString[i] = oArrayHeadersFootersInfo[0]->m_HeadersFootersString[i]; + } if (oArrayHeadersFootersInfo[0]->m_oHeadersFootersAtom) { - m_bHasDate = oArrayHeadersFootersInfo[0]->m_oHeadersFootersAtom->m_bHasDate/* || + m_bHasDate = oArrayHeadersFootersInfo[0]->m_oHeadersFootersAtom->m_bHasDate/* || oArrayHeadersFootersInfo[0]->m_oHeadersFootersAtom->m_bHasTodayDate || oArrayHeadersFootersInfo[0]->m_oHeadersFootersAtom->m_bHasUserDate*/; - m_bHasFooter = oArrayHeadersFootersInfo[0]->m_oHeadersFootersAtom->m_bHasFooter; - m_bHasSlideNumber = oArrayHeadersFootersInfo[0]->m_oHeadersFootersAtom->m_bHasSlideNumber; + m_bHasFooter = oArrayHeadersFootersInfo[0]->m_oHeadersFootersAtom->m_bHasFooter; + m_bHasSlideNumber = oArrayHeadersFootersInfo[0]->m_oHeadersFootersAtom->m_bHasSlideNumber; if (oArrayHeadersFootersInfo[0]->m_oHeadersFootersAtom->m_bHasUserDate) m_nFormatDate = 2; } } - double master_to_emu = 1./576. ;//inch + double master_to_emu = 1. / 576.;//inch master_to_emu *= 72;//pt master_to_emu *= 12700;//emu - m_lSlideWidth = (oArrayDoc[0]->m_oSlideSize.X * 1587.5 + 0.5); - m_lSlideHeight = (oArrayDoc[0]->m_oSlideSize.Y * 1587.5 + 0.5); + m_lSlideWidth = (oArrayDoc[0]->m_oSlideSize.X * 1587.5 + 0.5); + m_lSlideHeight = (oArrayDoc[0]->m_oSlideSize.Y * 1587.5 + 0.5); + + m_lNotesWidth = (oArrayDoc[0]->m_oNotesSize.X * 1587.5 + 0.5); + m_lNotesHeight = (oArrayDoc[0]->m_oNotesSize.Y * 1587.5 + 0.5); + + m_bRtl = (oArrayDoc[0]->m_bRightToLeft != 0); + m_bShowComments = (oArrayDoc[0]->m_bShowComments != 0); + + for (size_t i = 0; i < m_arrSlidesOrder.size(); i++) + { + std::map<_UINT32, CRecordSlide*>::iterator pPair = m_mapSlides.find(m_arrSlidesOrder[i]); - m_lNotesWidth = (oArrayDoc[0]->m_oNotesSize.X * 1587.5 + 0.5); - m_lNotesHeight = (oArrayDoc[0]->m_oNotesSize.Y * 1587.5 + 0.5); + if (pPair == m_mapSlides.end()) + continue; - m_bRtl = (oArrayDoc[0]->m_bRightToLeft!=0); - m_bShowComments = (oArrayDoc[0]->m_bShowComments!=0); + LoadSlideFromPrevUsers(pPair->first); + TestSlide(pPair->first); + } + LoadMasters(); double DurationSlide = PPT_DEFAULT_SLIDE_DURATION; @@ -583,12 +573,12 @@ void CPPTUserInfo::FromDocument() { std::map<_UINT32, CRecordSlide*>::iterator pPair = m_mapSlides.find(m_arrSlidesOrder[i]); - if (pPair == m_mapSlides.end()) + if (pPair == m_mapSlides.end()) continue; - LoadSlideFromPrevUsers ( pPair->first ); + LoadSlideFromPrevUsers(pPair->first); - DurationSlide = PPT_DEFAULT_SLIDE_DURATION; + DurationSlide = PPT_DEFAULT_SLIDE_DURATION; m_arSlides.push_back(new CSlide()); @@ -605,32 +595,32 @@ void CPPTUserInfo::FromDocument() CSlide* pSlide = m_arSlides.back(); - pSlide->m_dStartTime = 0.0; - pSlide->m_dEndTime = DurationSlide; - pSlide->m_dDuration = DurationSlide; + pSlide->m_dStartTime = 0.0; + pSlide->m_dEndTime = DurationSlide; + pSlide->m_dDuration = DurationSlide; - pSlide->m_lSlideID = pPair->first; + pSlide->m_lSlideID = pPair->first; - LoadSlide ( pPair->first, pSlide); + LoadSlide(pPair->first, pSlide); } m_arNotes.reserve(m_arrNotesOrder.size()); - for (size_t i = 0; i< m_arrNotesOrder.size(); i++) + for (size_t i = 0; i < m_arrNotesOrder.size(); i++) { std::map<_UINT32, CRecordSlide*>::iterator pPair = m_mapNotes.find(m_arrNotesOrder[i]); - if (pPair == m_mapNotes.end()) + if (pPair == m_mapNotes.end()) continue; - LoadNotesFromPrevUsers ( pPair->first ); + LoadNotesFromPrevUsers(pPair->first); - DurationSlide = PPT_DEFAULT_SLIDE_DURATION; + DurationSlide = PPT_DEFAULT_SLIDE_DURATION; m_arNotes.push_back(new CSlide()); CSlide* pSlide = m_arNotes.back(); - LoadNotes ( pPair->first, pSlide); + LoadNotes(pPair->first, pSlide); } CalculateEditor(); @@ -656,16 +646,16 @@ void CPPTUserInfo::LoadNotes(_UINT32 dwNoteID, CSlide* pNotes) int indexUser = pRecordSlide->m_IndexUser; if (m_pDocumentInfo->m_arUsers[indexUser]->m_arOffsetPictures.empty()) - pNotesWrapper->m_parEmptyPictures = &m_pDocumentInfo->m_arUsers[0]->m_arOffsetPictures; + pNotesWrapper->m_parEmptyPictures = &m_pDocumentInfo->m_arUsers[0]->m_arOffsetPictures; else - pNotesWrapper->m_parEmptyPictures = &m_pDocumentInfo->m_arUsers[indexUser]->m_arOffsetPictures; + pNotesWrapper->m_parEmptyPictures = &m_pDocumentInfo->m_arUsers[indexUser]->m_arOffsetPictures; - pNotesWrapper->m_mapFilePictures = &m_pDocumentInfo->m_mapStoreImageFile; -// pNotesWrapper->m_arTextPlaceHolders = pRecordSlide->m_oPersist.m_arTextAttrs; + pNotesWrapper->m_mapFilePictures = &m_pDocumentInfo->m_mapStoreImageFile; + // pNotesWrapper->m_arTextPlaceHolders = pRecordSlide->m_oPersist.m_arTextAttrs; pNotesWrapper->m_arTextPlaceHolders.clear(); - for (auto* pTextAttr : pRecordSlide->m_oPersist.m_arTextAttrs) - if (pTextAttr) - pNotesWrapper->m_arTextPlaceHolders.push_back(*pTextAttr); + for (auto* pTextAttr : pRecordSlide->m_oPersist.m_arTextAttrs) + if (pTextAttr) + pNotesWrapper->m_arTextPlaceHolders.push_back(*pTextAttr); std::vector oArrayNotesAtoms; @@ -676,8 +666,8 @@ void CPPTUserInfo::LoadNotes(_UINT32 dwNoteID, CSlide* pNotes) return; } bool bMasterColorScheme = oArrayNotesAtoms[0]->m_bMasterScheme; - bool bMasterBackGround = oArrayNotesAtoms[0]->m_bMasterBackground; - bool bMasterObjects = oArrayNotesAtoms[0]->m_bMasterObjects; + bool bMasterBackGround = oArrayNotesAtoms[0]->m_bMasterBackground; + bool bMasterObjects = oArrayNotesAtoms[0]->m_bMasterObjects; std::map<_UINT32, CRecordSlide*>::iterator pPairSlide = m_mapSlides.find(oArrayNotesAtoms[0]->m_nSlideIDRef); @@ -689,16 +679,16 @@ void CPPTUserInfo::LoadNotes(_UINT32 dwNoteID, CSlide* pNotes) size_t index = pPairSlide->second->m_Index; if (index >= m_arSlides.size()) return; - CSlide* pSlide = m_arSlides[pPairSlide->second->m_Index]; + CSlide* pSlide = m_arSlides[pPairSlide->second->m_Index]; - pNotes->m_lSlideID = pPairSlide->second->m_Index; - pSlide->m_lNotesID = m_arNotes.size() - 1; + pNotes->m_lSlideID = pPairSlide->second->m_Index; + pSlide->m_lNotesID = m_arNotes.size() - 1; //----------------------------------------------------- - CTheme * pTheme = m_pNotesMaster.get(); - CSlideInfo * pThemeWrapper = m_pNotesMasterWrapper; + CTheme* pTheme = m_pNotesMaster.get(); + CSlideInfo* pThemeWrapper = m_pNotesMasterWrapper; - CLayout* pLayout = NULL; + CLayout* pLayout = NULL; //----------------------------------------------------- std::vector* pArrayColorScheme = pTheme ? &pTheme->m_arColorScheme : NULL; @@ -740,10 +730,10 @@ void CPPTUserInfo::LoadNotes(_UINT32 dwNoteID, CSlide* pNotes) } } //------------------------------------------------------------------------------------ - bool bHasDate = false; + bool bHasDate = false; bool bHasSlideNumber = false; - bool bHasFooter = false; - int nFormatDate = 1; + bool bHasFooter = false; + int nFormatDate = 1; std::vector oArrayHeadersFootersInfo; pRecordSlide->GetRecordsByType(&oArrayHeadersFootersInfo, true, false); @@ -752,18 +742,18 @@ void CPPTUserInfo::LoadNotes(_UINT32 dwNoteID, CSlide* pNotes) { if (oArrayHeadersFootersInfo[0]->m_oHeadersFootersAtom) { - bHasDate = oArrayHeadersFootersInfo[0]->m_oHeadersFootersAtom->m_bHasDate/* || + bHasDate = oArrayHeadersFootersInfo[0]->m_oHeadersFootersAtom->m_bHasDate/* || oArrayHeadersFootersInfo[0]->m_oHeadersFootersAtom->m_bHasTodayDate || oArrayHeadersFootersInfo[0]->m_oHeadersFootersAtom->m_bHasUserDate*/; - bHasFooter = oArrayHeadersFootersInfo[0]->m_oHeadersFootersAtom->m_bHasFooter; - bHasSlideNumber = oArrayHeadersFootersInfo[0]->m_oHeadersFootersAtom->m_bHasSlideNumber; + bHasFooter = oArrayHeadersFootersInfo[0]->m_oHeadersFootersAtom->m_bHasFooter; + bHasSlideNumber = oArrayHeadersFootersInfo[0]->m_oHeadersFootersAtom->m_bHasSlideNumber; if (oArrayHeadersFootersInfo[0]->m_oHeadersFootersAtom->m_bHasUserDate) nFormatDate = 2; } - for (int i = 0 ; i < 3; i++) + for (int i = 0; i < 3; i++) pNotes->m_PlaceholdersReplaceString[i] = oArrayHeadersFootersInfo[0]->m_HeadersFootersString[i]; } - pNotes->m_bIsBackground = false; + pNotes->m_bIsBackground = false; //------------------------------------------------------------------------------------------------------- std::vector oArrayDrawing; @@ -789,7 +779,7 @@ void CPPTUserInfo::LoadNotes(_UINT32 dwNoteID, CSlide* pNotes) if (pShapeGroup) { CElementPtr pElement = pShapeGroup->GetElement(false, &m_oExMedia, - pTheme, pLayout, pThemeWrapper, pNotesWrapper, pNotes); + pTheme, pLayout, pThemeWrapper, pNotesWrapper, pNotes); CShapeElement* pShape = dynamic_cast(pElement.get()); if (NULL != pShape && pShape->m_bIsBackground && !pShape->m_bHaveAnchor) @@ -797,15 +787,40 @@ void CPPTUserInfo::LoadNotes(_UINT32 dwNoteID, CSlide* pNotes) pShape->SetupProperties(pNotes, pTheme, pLayout); pNotes->m_bIsBackground = true; - pNotes->m_oBackground = pShape->m_oBrush; + pNotes->m_oBackground = pShape->m_oBrush; } } } } } } +void CPPTUserInfo::TestSlide(_UINT32 dwSlideID) +{ + std::map<_UINT32, CRecordSlide*>::iterator pPairSlide = m_mapSlides.find(dwSlideID); + if (pPairSlide == m_mapSlides.end()) return; + CRecordSlide* pRecordSlide = pPairSlide->second; + if (NULL == pRecordSlide) return; + + std::vector oArraySlideAtoms; + pRecordSlide->GetRecordsByType(&oArraySlideAtoms, false, true); + if (0 == oArraySlideAtoms.size()) + { + // ошибка!!! + return; + } + std::map<_UINT32, LONG>::iterator pFind = m_mapRealUsedMaster.find(oArraySlideAtoms[0]->m_nMasterIDRef); + + if (pFind == m_mapRealUsedMaster.end()) + { + m_mapRealUsedMaster.insert(std::make_pair(oArraySlideAtoms[0]->m_nMasterIDRef, 1)); + } + else + { + pFind->second++; + } +} void CPPTUserInfo::LoadSlide(_UINT32 dwSlideID, CSlide* pSlide) { std::map<_UINT32, CRecordSlide*>::iterator pPairSlide = m_mapSlides.find(dwSlideID); @@ -822,33 +837,35 @@ void CPPTUserInfo::LoadSlide(_UINT32 dwSlideID, CSlide* pSlide) if (pRecordSlide->m_bExistsTransition) { - CSlideShowSlideInfoAtom* pAtom = &pRecordSlide->m_oSlideShowSlideInfoAtom; + CSlideShowSlideInfoAtom* pAtom = &pRecordSlide->m_oSlideShowSlideInfoAtom; - pTransition->m_bAudioPresent = pAtom->m_bSound; + pTransition->m_bAudioPresent = pAtom->m_bSound; - PPT::CExFilesInfo* pInfo = m_oExMedia.LockAudioFromCollection(pAtom->m_nSoundRef); + PPT::CExFilesInfo* pInfo = m_oExMedia.LockAudioFromCollection(pAtom->m_nSoundRef); if (NULL != pInfo) { pTransition->m_oAudio.m_strAudioFileName = pInfo->m_strFilePath; } - pTransition->m_bLoopSound = pAtom->m_bLoopSound; - pTransition->m_bStopSound = pAtom->m_bStopSound; + pTransition->m_bLoopSound = pAtom->m_bLoopSound; + pTransition->m_bStopSound = pAtom->m_bStopSound; pTransition->m_nEffectDirection = pAtom->m_nEffectDirection; - pTransition->m_nEffectType = pAtom->m_nEffectType; // тут нужно сконвертить тип // конвертится в Converter.cpp - pTransition->m_nSpeed = pAtom->m_nSpeed; + pTransition->m_nEffectType = pAtom->m_nEffectType; // тут нужно сконвертить тип // конвертится в Converter.cpp + pTransition->m_nSpeed = pAtom->m_nSpeed; - pSlide->m_oSlideShow.m_dSlideDuration = pAtom->m_nSlideTime; - pSlide->m_oSlideShow.m_bManulClick = pAtom->m_bManualAdvance; - pSlide->m_oSlideShow.m_bAdvClick = pAtom->m_bAutoAdvance; + pSlide->m_oSlideShow.m_dSlideDuration = pAtom->m_nSlideTime; + pSlide->m_oSlideShow.m_bManulClick = pAtom->m_bManualAdvance; + pSlide->m_oSlideShow.m_bAdvClick = pAtom->m_bAutoAdvance; + + pSlide->m_bHidden = pAtom->m_bHidden; } - CSlideShowSlideInfoAtom* pAtom = &pRecordSlide->m_oSlideShowSlideInfoAtom; + CSlideShowSlideInfoAtom* pAtom = &pRecordSlide->m_oSlideShowSlideInfoAtom; if (pAtom->m_bSound) { - PPT::CExFilesInfo* pInfo = m_oExMedia.LockAudioFromCollection(pAtom->m_nSoundRef); + PPT::CExFilesInfo* pInfo = m_oExMedia.LockAudioFromCollection(pAtom->m_nSoundRef); if (NULL != pInfo) - AddAudioTransition (pAtom->m_nSoundRef, pTransition, pInfo->m_strFilePath); + AddAudioTransition(pAtom->m_nSoundRef, pTransition, pInfo->m_strFilePath); } // анимации @@ -863,16 +880,16 @@ void CPPTUserInfo::LoadSlide(_UINT32 dwSlideID, CSlide* pSlide) int indexUser = pRecordSlide->m_IndexUser; if (m_pDocumentInfo->m_arUsers[indexUser]->m_arOffsetPictures.empty()) - pSlideWrapper->m_parEmptyPictures = &m_pDocumentInfo->m_arUsers[0]->m_arOffsetPictures; + pSlideWrapper->m_parEmptyPictures = &m_pDocumentInfo->m_arUsers[0]->m_arOffsetPictures; else - pSlideWrapper->m_parEmptyPictures = &m_pDocumentInfo->m_arUsers[indexUser]->m_arOffsetPictures; + pSlideWrapper->m_parEmptyPictures = &m_pDocumentInfo->m_arUsers[indexUser]->m_arOffsetPictures; - pSlideWrapper->m_mapFilePictures = &m_pDocumentInfo->m_mapStoreImageFile; -// pSlideWrapper->m_arTextPlaceHolders = pRecordSlide->m_oPersist.m_arTextAttrs; + pSlideWrapper->m_mapFilePictures = &m_pDocumentInfo->m_mapStoreImageFile; + // pSlideWrapper->m_arTextPlaceHolders = pRecordSlide->m_oPersist.m_arTextAttrs; pSlideWrapper->m_arTextPlaceHolders.clear(); - for (auto* pTextAttr : pRecordSlide->m_oPersist.m_arTextAttrs) - if (pTextAttr) - pSlideWrapper->m_arTextPlaceHolders.push_back(*pTextAttr); + for (auto* pTextAttr : pRecordSlide->m_oPersist.m_arTextAttrs) + if (pTextAttr) + pSlideWrapper->m_arTextPlaceHolders.push_back(*pTextAttr); // записываем шрифты std::vector oArraySlideAtoms; @@ -883,8 +900,8 @@ void CPPTUserInfo::LoadSlide(_UINT32 dwSlideID, CSlide* pSlide) return; } bool bMasterColorScheme = oArraySlideAtoms[0]->m_bMasterScheme; - bool bMasterBackGround = oArraySlideAtoms[0]->m_bMasterBackground; - bool bMasterObjects = oArraySlideAtoms[0]->m_bMasterObjects; + bool bMasterBackGround = oArraySlideAtoms[0]->m_bMasterBackground; + bool bMasterObjects = oArraySlideAtoms[0]->m_bMasterObjects; std::map<_UINT32, LONG>::iterator pPairTheme = m_mapMasterToTheme.find(oArraySlideAtoms[0]->m_nMasterIDRef); @@ -895,42 +912,42 @@ void CPPTUserInfo::LoadSlide(_UINT32 dwSlideID, CSlide* pSlide) pPairTheme = m_mapMasterToTheme.begin(); else { - throw 1; // file format error + throw 1; // 第58课时 绘制频数直方图.ppt } } //----------------- - pSlide->m_lThemeID = pPairTheme->second; + pSlide->m_lThemeID = pPairTheme->second; - CTheme * pTheme = m_arThemes [pSlide->m_lThemeID].get(); - CSlideInfo * pThemeWrapper = &m_arMasterWrapper[pSlide->m_lThemeID]; + CTheme* pTheme = m_arThemes[pSlide->m_lThemeID].get(); + CSlideInfo* pThemeWrapper = &m_arMasterWrapper[pSlide->m_lThemeID]; - CLayout* pLayout = NULL; + CLayout* pLayout = NULL; - std::map<_UINT32, LONG>::iterator pPairLayoutTitle = pTheme->m_mapTitleLayout.find(oArraySlideAtoms[0]->m_nMasterIDRef); + std::map<_UINT32, LONG>::iterator pPairLayoutTitle = pTheme->m_mapTitleLayout.find(oArraySlideAtoms[0]->m_nMasterIDRef); if (pPairLayoutTitle != pTheme->m_mapTitleLayout.end()) { //основан на заголовочном шаблоне pSlide->m_bShowMasterShapes = bMasterObjects; - pSlide->m_lLayoutID = pPairLayoutTitle->second; - pLayout = pTheme->m_arLayouts[pSlide->m_lLayoutID].get(); + pSlide->m_lLayoutID = pPairLayoutTitle->second; + pLayout = pTheme->m_arLayouts[pSlide->m_lLayoutID].get(); } else { - pSlide->m_bShowMasterShapes = true; //??? + pSlide->m_bShowMasterShapes = true; //??? //основан на типовом шаблоне - std::map<_UINT64, LONG>::iterator pPairLayoutGeom = pTheme->m_mapGeomToLayout.find(oArraySlideAtoms[0]->m_oLayout.m_hash); + std::map<_UINT64, LONG>::iterator pPairLayoutGeom = pTheme->m_mapGeomToLayout.find(oArraySlideAtoms[0]->m_oLayout.m_hash); if (pPairLayoutGeom == pTheme->m_mapGeomToLayout.end()) { pSlide->m_lLayoutID = AddNewLayout(pTheme, pRecordSlide, true, bMasterObjects); - pLayout = pTheme->m_arLayouts[pSlide->m_lLayoutID].get(); - pLayout->m_bShowMasterShapes = true; + pLayout = pTheme->m_arLayouts[pSlide->m_lLayoutID].get(); + pLayout->m_bShowMasterShapes = true; } else { pSlide->m_lLayoutID = pPairLayoutGeom->second; - pLayout = pTheme->m_arLayouts[pSlide->m_lLayoutID].get(); + pLayout = pTheme->m_arLayouts[pSlide->m_lLayoutID].get(); } } @@ -976,10 +993,10 @@ void CPPTUserInfo::LoadSlide(_UINT32 dwSlideID, CSlide* pSlide) } } //------------------------------------------------------------------------------------ - bool bHasDate = false; + bool bHasDate = false; bool bHasSlideNumber = false; - bool bHasFooter = false; - int nFormatDate = 1; + bool bHasFooter = false; + int nFormatDate = 1; std::vector oArrayHeadersFootersInfo; pRecordSlide->GetRecordsByType(&oArrayHeadersFootersInfo, true, false); @@ -988,24 +1005,24 @@ void CPPTUserInfo::LoadSlide(_UINT32 dwSlideID, CSlide* pSlide) { if (oArrayHeadersFootersInfo[0]->m_oHeadersFootersAtom) { - bHasDate = oArrayHeadersFootersInfo[0]->m_oHeadersFootersAtom->m_bHasDate/* || + bHasDate = oArrayHeadersFootersInfo[0]->m_oHeadersFootersAtom->m_bHasDate/* || oArrayHeadersFootersInfo[0]->m_oHeadersFootersAtom->m_bHasTodayDate || oArrayHeadersFootersInfo[0]->m_oHeadersFootersAtom->m_bHasUserDate*/; - bHasFooter = oArrayHeadersFootersInfo[0]->m_oHeadersFootersAtom->m_bHasFooter; - bHasSlideNumber = oArrayHeadersFootersInfo[0]->m_oHeadersFootersAtom->m_bHasSlideNumber; + bHasFooter = oArrayHeadersFootersInfo[0]->m_oHeadersFootersAtom->m_bHasFooter; + bHasSlideNumber = oArrayHeadersFootersInfo[0]->m_oHeadersFootersAtom->m_bHasSlideNumber; if (oArrayHeadersFootersInfo[0]->m_oHeadersFootersAtom->m_bHasUserDate) nFormatDate = 2; } - for (int i = 0 ; i < 3; i++) pSlide->m_PlaceholdersReplaceString[i] = oArrayHeadersFootersInfo[0]->m_HeadersFootersString[i]; + for (int i = 0; i < 3; i++) pSlide->m_PlaceholdersReplaceString[i] = oArrayHeadersFootersInfo[0]->m_HeadersFootersString[i]; } else { - bHasDate = pLayout->m_bHasDate; - bHasFooter = pLayout->m_bHasFooter; - bHasSlideNumber = pLayout->m_bHasSlideNumber; - nFormatDate = pLayout->m_nFormatDate; + bHasDate = pLayout->m_bHasDate; + bHasFooter = pLayout->m_bHasFooter; + bHasSlideNumber = pLayout->m_bHasSlideNumber; + nFormatDate = pLayout->m_nFormatDate; - for (int i = 0 ; i < 3; i++) pSlide->m_PlaceholdersReplaceString[i] = pLayout->m_PlaceholdersReplaceString[i]; + for (int i = 0; i < 3; i++) pSlide->m_PlaceholdersReplaceString[i] = pLayout->m_PlaceholdersReplaceString[i]; } //------------------------------------------------------------------------------------------------------- std::vector oArrayStrings; @@ -1042,7 +1059,7 @@ void CPPTUserInfo::LoadSlide(_UINT32 dwSlideID, CSlide* pSlide) if (pShapeGroup) { CElementPtr pElement = pShapeGroup->GetElement(false, &m_oExMedia, - pTheme, pLayout, pThemeWrapper, pSlideWrapper, pSlide); + pTheme, pLayout, pThemeWrapper, pSlideWrapper, pSlide); if (pElement->m_bIsBackground && !pElement->m_bHaveAnchor && !bMasterBackGround) { @@ -1052,7 +1069,7 @@ void CPPTUserInfo::LoadSlide(_UINT32 dwSlideID, CSlide* pSlide) pShape->SetupProperties(pSlide, pTheme, pLayout); pSlide->m_bIsBackground = true; - pSlide->m_oBackground = pShape->m_oBrush; + pSlide->m_oBackground = pShape->m_oBrush; } } } @@ -1074,12 +1091,12 @@ void CPPTUserInfo::LoadSlide(_UINT32 dwSlideID, CSlide* pSlide) } void CPPTUserInfo::LoadGroupShapeContainer(CRecordGroupShapeContainer* pGroupContainer, std::vector* pParentElements, CTheme* pTheme, CLayout* pLayout, - CSlideInfo* pThemeWrapper, CSlideInfo* pSlideWrapper, CSlide* pSlide) + CSlideInfo* pThemeWrapper, CSlideInfo* pSlideWrapper, CSlide* pSlide) { if (!pGroupContainer) return; if (pGroupContainer->m_arRecords.empty()) return; -// LoadAutoNumbering(pGroupContainer, pTheme); + // LoadAutoNumbering(pGroupContainer, pTheme); CRecordShapeContainer* pShapeGroup = dynamic_cast(pGroupContainer->m_arRecords[0]); @@ -1106,7 +1123,7 @@ void CPPTUserInfo::LoadGroupShapeContainer(CRecordGroupShapeContainer* pGroupCon if (pGroup) { - LoadGroupShapeContainer(pGroup, pParentElements, pTheme, pLayout, pThemeWrapper, pSlideWrapper, pSlide); + LoadGroupShapeContainer(pGroup, pParentElements, pTheme, pLayout, pThemeWrapper, pSlideWrapper, pSlide); } else { @@ -1116,7 +1133,7 @@ void CPPTUserInfo::LoadGroupShapeContainer(CRecordGroupShapeContainer* pGroupCon CElementPtr pElement = pShapeGroup->GetElement(m_current_level > 1, &m_oExMedia, pTheme, pLayout, pThemeWrapper, pSlideWrapper, pSlide); CShapeElement* pShape = dynamic_cast(pElement.get()); -// LoadBulletBlip(pShape); + // LoadBulletBlip(pShape); LoadAutoNumBullet(pShape, pSlide ? pSlide->m_lSlideID : -1); if (NULL != pElement) { @@ -1127,7 +1144,7 @@ void CPPTUserInfo::LoadGroupShapeContainer(CRecordGroupShapeContainer* pGroupCon if (NULL != pShape) pShape->SetupProperties(pSlide, pTheme, pLayout); - if ( pElement->m_lPlaceholderType > 0) + if (pElement->m_lPlaceholderType > 0) { if (pSlide) { @@ -1141,9 +1158,9 @@ void CPPTUserInfo::LoadGroupShapeContainer(CRecordGroupShapeContainer* pGroupCon { if (pElement->m_lPlaceholderID >= 0) { - if (pElement->m_lPlaceholderType == PT_MasterSlideNumber) pLayout->m_bHasSlideNumber = true; - if (pElement->m_lPlaceholderType == PT_MasterDate) pLayout->m_bHasDate = true; - if (pElement->m_lPlaceholderType == PT_MasterFooter) pLayout->m_bHasFooter = true; + if (pElement->m_lPlaceholderType == PT_MasterSlideNumber) pLayout->m_bHasSlideNumber = true; + if (pElement->m_lPlaceholderType == PT_MasterDate) pLayout->m_bHasDate = true; + if (pElement->m_lPlaceholderType == PT_MasterFooter) pLayout->m_bHasFooter = true; } pLayout->m_mapPlaceholders.insert(std::make_pair(pElement->m_lPlaceholderType, pElement)); } @@ -1161,22 +1178,22 @@ void CPPTUserInfo::LoadGroupShapeContainer(CRecordGroupShapeContainer* pGroupCon if (false == m_current_elements->empty()) { - m_current_elements = m_current_elements->front()->m_pParentElements; + m_current_elements = m_current_elements->front()->m_pParentElements; } } -CElementPtr CPPTUserInfo::AddLayoutSlidePlaceholder (CSlide *pSlide, int placeholderType, CLayout *pLayout, bool idx_only) +CElementPtr CPPTUserInfo::AddLayoutSlidePlaceholder(CSlide* pSlide, int placeholderType, CLayout* pLayout, bool idx_only) { CElementPtr pElement; for (std::multimap::iterator it = pLayout->m_mapPlaceholders.begin(); it != pLayout->m_mapPlaceholders.end(); ++it) { CElementPtr pElementPlaceholder = it->second; - if (it->first == placeholderType ) + if (it->first == placeholderType) { if (idx_only == false) { - if (pElementPlaceholder->m_lPlaceholderID >= 0 ) continue; + if (pElementPlaceholder->m_lPlaceholderID >= 0) continue; pElement = pElementPlaceholder->CreateDublicate(); @@ -1185,7 +1202,7 @@ CElementPtr CPPTUserInfo::AddLayoutSlidePlaceholder (CSlide *pSlide, int placeho } else { - if (pElementPlaceholder->m_lPlaceholderID < 0 ) continue; + if (pElementPlaceholder->m_lPlaceholderID < 0) continue; for (std::multimap::iterator it1 = pSlide->m_mapPlaceholders.begin(); it1 != pSlide->m_mapPlaceholders.end(); it1++) { @@ -1209,7 +1226,7 @@ CElementPtr CPPTUserInfo::AddLayoutSlidePlaceholder (CSlide *pSlide, int placeho return pElement; } -CElementPtr CPPTUserInfo::AddThemeLayoutPlaceholder (CLayout *pLayout, int placeholderType, CTheme* pTheme, bool idx_only) +CElementPtr CPPTUserInfo::AddThemeLayoutPlaceholder(CLayout* pLayout, int placeholderType, CTheme* pTheme, bool idx_only) { CElementPtr pElement; @@ -1217,7 +1234,7 @@ CElementPtr CPPTUserInfo::AddThemeLayoutPlaceholder (CLayout *pLayout, int plac { CElementPtr pElementPlaceholder = it->second; - if (it->first == placeholderType ) + if (it->first == placeholderType) { if (idx_only && pElementPlaceholder->m_lPlaceholderID < 0) continue; @@ -1236,19 +1253,19 @@ CElementPtr CPPTUserInfo::AddThemeLayoutPlaceholder (CLayout *pLayout, int plac return pElement; //last added } -CElementPtr CPPTUserInfo::AddNewLayoutPlaceholder (CLayout *pLayout, int placeholderType, int placeholderSizePreset) +CElementPtr CPPTUserInfo::AddNewLayoutPlaceholder(CLayout* pLayout, int placeholderType, int placeholderSizePreset) { if (placeholderType < 1) return CElementPtr(); CShapeElement* pShape = new CShapeElement(NSBaseShape::ppt, PPTShapes::sptCRect); - pShape->m_lPlaceholderType = placeholderType; - pShape->m_lPlaceholderSizePreset = placeholderSizePreset; + pShape->m_lPlaceholderType = placeholderType; + pShape->m_lPlaceholderSizePreset = placeholderSizePreset; - pShape->m_bPlaceholderSet = false; - pShape->m_bLine = false; - pShape->m_bAnchorEnabled = false; - pShape->m_bChildAnchorEnabled = false; + pShape->m_bPlaceholderSet = false; + pShape->m_bLine = false; + pShape->m_bAnchorEnabled = false; + pShape->m_bChildAnchorEnabled = false; CorrectPlaceholderType(pShape->m_lPlaceholderType); @@ -1262,23 +1279,23 @@ CElementPtr CPPTUserInfo::AddNewLayoutPlaceholder (CLayout *pLayout, int placeho int CPPTUserInfo::AddNewLayout(CTheme* pTheme, CRecordSlide* pRecordSlide, bool addShapes, bool bMasterObjects) { - if (pTheme == NULL) return -1; - if (pRecordSlide == NULL) return -1; + if (pTheme == NULL) return -1; + if (pRecordSlide == NULL) return -1; std::vector oArraySlideAtoms; pRecordSlide->GetRecordsByType(&oArraySlideAtoms, true); if (0 == oArraySlideAtoms.size()) return -1; - SSlideLayoutAtom & layoutRecord = oArraySlideAtoms[0]->m_oLayout; + SSlideLayoutAtom& layoutRecord = oArraySlideAtoms[0]->m_oLayout; int ind = pTheme->m_arLayouts.size(); pTheme->m_arLayouts.push_back(boost::make_shared()); - CLayout *pLayout = pTheme->m_arLayouts.back().get(); + CLayout* pLayout = pTheme->m_arLayouts.back().get(); pLayout->m_bUseThemeColorScheme = true; - pLayout->m_bShowMasterShapes = true; + pLayout->m_bShowMasterShapes = true; ConvertLayoutType(layoutRecord, pLayout->m_strLayoutType, pLayout->m_sName); @@ -1309,15 +1326,15 @@ int CPPTUserInfo::AddNewLayout(CTheme* pTheme, CRecordSlide* pRecordSlide, bool case 0x11: //SL_VerticalTitleBody case 0x12: //SL_VerticalTwoRows defObjSize = 0; break; - case 0x10 : // SL_Blank + case 0x10: // SL_Blank break; } - for (int i = 0 ; i < 8; i ++) + for (int i = 0; i < 8; i++) { if (layoutRecord.m_pPlaceHolderID[i] == 0) break; - switch(layoutRecord.m_pPlaceHolderID[i]) + switch (layoutRecord.m_pPlaceHolderID[i]) { case PT_MasterTitle: case PT_MasterBody: @@ -1382,33 +1399,33 @@ int CPPTUserInfo::AddNewLayout(CTheme* pTheme, CRecordSlide* pRecordSlide, bool } } - pLayout->m_bHasDate = pTheme->m_bHasDate; - pLayout->m_bHasFooter = pTheme->m_bHasFooter; - pLayout->m_bHasSlideNumber = pTheme->m_bHasSlideNumber; - pLayout->m_nFormatDate = pTheme->m_nFormatDate; + pLayout->m_bHasDate = pTheme->m_bHasDate; + pLayout->m_bHasFooter = pTheme->m_bHasFooter; + pLayout->m_bHasSlideNumber = pTheme->m_bHasSlideNumber; + pLayout->m_nFormatDate = pTheme->m_nFormatDate; for (int i = 0; i < 3; i++) pLayout->m_PlaceholdersReplaceString[i] = pTheme->m_PlaceholdersReplaceString[i]; - if (pLayout->m_bHasSlideNumber) AddThemeLayoutPlaceholder(pLayout, PT_MasterSlideNumber, pTheme, true); - if (pLayout->m_bHasDate) AddThemeLayoutPlaceholder(pLayout, PT_MasterDate, pTheme, true); - if (pLayout->m_bHasFooter) AddThemeLayoutPlaceholder(pLayout, PT_MasterFooter, pTheme, true); + if (pLayout->m_bHasSlideNumber) AddThemeLayoutPlaceholder(pLayout, PT_MasterSlideNumber, pTheme, true); + if (pLayout->m_bHasDate) AddThemeLayoutPlaceholder(pLayout, PT_MasterDate, pTheme, true); + if (pLayout->m_bHasFooter) AddThemeLayoutPlaceholder(pLayout, PT_MasterFooter, pTheme, true); return ind; } -CElementPtr CPPTUserInfo::AddNewThemePlaceholder (CTheme* pTheme, int placeholderType, int placeholderSizePreset) +CElementPtr CPPTUserInfo::AddNewThemePlaceholder(CTheme* pTheme, int placeholderType, int placeholderSizePreset) { if (placeholderType < 1) return CElementPtr(); CShapeElement* pShape = new CShapeElement(NSBaseShape::ppt, PPTShapes::sptCRect); - pShape->m_lPlaceholderType = placeholderType; - pShape->m_lPlaceholderSizePreset = placeholderSizePreset; + pShape->m_lPlaceholderType = placeholderType; + pShape->m_lPlaceholderSizePreset = placeholderSizePreset; - pShape->m_bPlaceholderSet = false; - pShape->m_bLine = false; - pShape->m_bAnchorEnabled = false; - pShape->m_bChildAnchorEnabled = false; + pShape->m_bPlaceholderSet = false; + pShape->m_bLine = false; + pShape->m_bAnchorEnabled = false; + pShape->m_bChildAnchorEnabled = false; CorrectPlaceholderType(pShape->m_lPlaceholderType); @@ -1419,7 +1436,7 @@ CElementPtr CPPTUserInfo::AddNewThemePlaceholder (CTheme* pTheme, int placeholde return pElement; } -void CPPTUserInfo::LoadMainMaster(_UINT32 dwMasterID) +void CPPTUserInfo::LoadMainMaster(_UINT32 dwMasterID, bool alwaysLoad) { std::map<_UINT32, LONG>::iterator pPair = m_mapMasterToTheme.find(dwMasterID); if (pPair != m_mapMasterToTheme.end()) @@ -1455,17 +1472,18 @@ void CPPTUserInfo::LoadMainMaster(_UINT32 dwMasterID) } std::vector oArrayCompId; pMaster->GetRecordsByType(&oArrayCompId, false, true); - if (0 != oArrayCompId.size()) + if (0 != oArrayCompId.size() && !alwaysLoad) { // этот мастер - не main!!! // сначала загрузим все main, а потом - title // title нужно грузить как обычный слайд. - return; + // 第58课时 绘制频数直方图.ppt + return; } bool bMasterColorScheme = oArraySlideAtoms[0]->m_bMasterScheme; - bool bMasterBackGround = oArraySlideAtoms[0]->m_bMasterBackground; - bool bMasterObjects = oArraySlideAtoms[0]->m_bMasterObjects; + bool bMasterBackGround = oArraySlideAtoms[0]->m_bMasterBackground; + bool bMasterObjects = oArraySlideAtoms[0]->m_bMasterObjects; std::vector oArrayOrigId; pMaster->GetRecordsByType(&oArrayOrigId, false, true); @@ -1487,23 +1505,23 @@ void CPPTUserInfo::LoadMainMaster(_UINT32 dwMasterID) { if (oArrayHeadersFootersInfo[0]->m_oHeadersFootersAtom) { - pTheme->m_bHasDate = oArrayHeadersFootersInfo[0]->m_oHeadersFootersAtom->m_bHasDate || - oArrayHeadersFootersInfo[0]->m_oHeadersFootersAtom->m_bHasTodayDate || - oArrayHeadersFootersInfo[0]->m_oHeadersFootersAtom->m_bHasUserDate; - pTheme->m_bHasFooter = oArrayHeadersFootersInfo[0]->m_oHeadersFootersAtom->m_bHasFooter; - pTheme->m_bHasSlideNumber = oArrayHeadersFootersInfo[0]->m_oHeadersFootersAtom->m_bHasSlideNumber; + pTheme->m_bHasDate = oArrayHeadersFootersInfo[0]->m_oHeadersFootersAtom->m_bHasDate || + oArrayHeadersFootersInfo[0]->m_oHeadersFootersAtom->m_bHasTodayDate || + oArrayHeadersFootersInfo[0]->m_oHeadersFootersAtom->m_bHasUserDate; + pTheme->m_bHasFooter = oArrayHeadersFootersInfo[0]->m_oHeadersFootersAtom->m_bHasFooter; + pTheme->m_bHasSlideNumber = oArrayHeadersFootersInfo[0]->m_oHeadersFootersAtom->m_bHasSlideNumber; - if (oArrayHeadersFootersInfo[0]->m_oHeadersFootersAtom->m_bHasUserDate ) pTheme->m_nFormatDate = 2; + if (oArrayHeadersFootersInfo[0]->m_oHeadersFootersAtom->m_bHasUserDate) pTheme->m_nFormatDate = 2; } - for(int i = 0 ; i< 3; i++) pTheme->m_PlaceholdersReplaceString[i] = oArrayHeadersFootersInfo[0]->m_HeadersFootersString[i]; + for (int i = 0; i < 3; i++) pTheme->m_PlaceholdersReplaceString[i] = oArrayHeadersFootersInfo[0]->m_HeadersFootersString[i]; } else { - pTheme->m_bHasDate = m_bHasDate; - pTheme->m_bHasFooter = m_bHasFooter; - pTheme->m_bHasSlideNumber = m_bHasSlideNumber; - pTheme->m_nFormatDate = m_nFormatDate; - for (int i = 0 ; i < 3; i++) pTheme->m_PlaceholdersReplaceString[i] = m_PlaceholdersReplaceString[i]; + pTheme->m_bHasDate = m_bHasDate; + pTheme->m_bHasFooter = m_bHasFooter; + pTheme->m_bHasSlideNumber = m_bHasSlideNumber; + pTheme->m_nFormatDate = m_nFormatDate; + for (int i = 0; i < 3; i++) pTheme->m_PlaceholdersReplaceString[i] = m_PlaceholdersReplaceString[i]; } std::vector oArrayStrings; pMaster->GetRecordsByType(&oArrayStrings, false, false); @@ -1536,12 +1554,12 @@ void CPPTUserInfo::LoadMainMaster(_UINT32 dwMasterID) { if (0x01 == oArrayColors[i]->m_oHeader.RecInstance) { - if ( m_oSchemeColors.empty()) + if (m_oSchemeColors.empty()) { oArrayColors[i]->ToArray(&m_oSchemeColors); CorrectColorScheme(m_oSchemeColors);//?? } - if ( pTheme->m_arColorScheme.empty()) + if (pTheme->m_arColorScheme.empty()) { oArrayColors[i]->ToArray(&pTheme->m_arColorScheme); CorrectColorScheme(pTheme->m_arColorScheme); @@ -1569,18 +1587,18 @@ void CPPTUserInfo::LoadMainMaster(_UINT32 dwMasterID) if (pPairMaster1 != m_mapMasters.end()) { indexUser = pPairMaster1->second->m_IndexUser; -// pMasterWrapper->m_arTextPlaceHolders = pPairMaster1->second->m_oPersist.m_arTextAttrs; + // pMasterWrapper->m_arTextPlaceHolders = pPairMaster1->second->m_oPersist.m_arTextAttrs; pMasterWrapper->m_arTextPlaceHolders.clear(); - for (auto* pTextAttr : pPairMaster1->second->m_oPersist.m_arTextAttrs) - if (pTextAttr) - pMasterWrapper->m_arTextPlaceHolders.push_back(*pTextAttr); + for (auto* pTextAttr : pPairMaster1->second->m_oPersist.m_arTextAttrs) + if (pTextAttr) + pMasterWrapper->m_arTextPlaceHolders.push_back(*pTextAttr); } if (m_pDocumentInfo->m_arUsers[indexUser]->m_arOffsetPictures.empty() == false) - pMasterWrapper->m_parEmptyPictures = &m_pDocumentInfo->m_arUsers[indexUser]->m_arOffsetPictures; + pMasterWrapper->m_parEmptyPictures = &m_pDocumentInfo->m_arUsers[indexUser]->m_arOffsetPictures; else - pMasterWrapper->m_parEmptyPictures = &m_pDocumentInfo->m_arUsers[0]->m_arOffsetPictures; + pMasterWrapper->m_parEmptyPictures = &m_pDocumentInfo->m_arUsers[0]->m_arOffsetPictures; - pMasterWrapper->m_mapFilePictures = &m_pDocumentInfo->m_mapStoreImageFile; + pMasterWrapper->m_mapFilePictures = &m_pDocumentInfo->m_mapStoreImageFile; // читаем настройки текстовых стилей ----------------------------------------------- std::vector oArrayTextMasters; @@ -1663,22 +1681,31 @@ void CPPTUserInfo::LoadMainMaster(_UINT32 dwMasterID) if (lLayoutID >= 0 && false == pTheme->m_arLayouts.empty()) { - CLayout *pLayout_ = pTheme->m_arLayouts.back().get(); + CLayout* pLayout_ = pTheme->m_arLayouts.back().get(); //pLayout_->m_strLayoutType = L"obj"; } } void CPPTUserInfo::LoadMasters() { - for (size_t i = 0; i< m_arrMastersOrder.size(); i++) + for (size_t i = 0; i < m_arrMastersOrder.size(); i++) { std::map<_UINT32, CRecordSlide*>::iterator pPair = m_mapMasters.find(m_arrMastersOrder[i]); if (pPair == m_mapMasters.end())continue; - LoadMainMaster(pPair->first); + LoadMainMaster(pPair->first, false); } + if (m_mapMasterToTheme.empty()) + { + for (auto master : m_mapRealUsedMaster) + { + std::map<_UINT32, CRecordSlide*>::iterator pPair = m_mapMasters.find(master.first); + if (pPair == m_mapMasters.end())continue; - for (size_t i = 0; i< m_arrMastersOrder.size(); i++) + LoadMainMaster(pPair->first, true); + } + } + for (size_t i = 0; i < m_arrMastersOrder.size(); i++) { std::map<_UINT32, CRecordSlide*>::iterator pPair = m_mapMasters.find(m_arrMastersOrder[i]); if (pPair == m_mapMasters.end())continue; @@ -1702,14 +1729,14 @@ void CPPTUserInfo::LoadMasters() LoadMaster(typeHandoutMaster, pPair->second, m_pHandoutMasterWrapper, m_pHandoutMaster); } } -void CPPTUserInfo::LoadMaster(_typeMaster type, CRecordSlide* pMaster, CSlideInfo *& pMasterWrapper, CThemePtr & pTheme) +void CPPTUserInfo::LoadMaster(_typeMaster type, CRecordSlide* pMaster, CSlideInfo*& pMasterWrapper, CThemePtr& pTheme) { if (pMaster == NULL) return; bool bMasterColorScheme = false; - bool bMasterBackGround = false; - bool bMasterObjects = false; + bool bMasterBackGround = false; + bool bMasterObjects = false; _UINT32 dwID = 0; @@ -1720,9 +1747,9 @@ void CPPTUserInfo::LoadMaster(_typeMaster type, CRecordSlide* pMaster, CSlideInf { dwID = (_UINT32)oArraySlideAtoms[0]->m_nMasterIDRef; - bMasterColorScheme = oArraySlideAtoms[0]->m_bMasterScheme; - bMasterBackGround = oArraySlideAtoms[0]->m_bMasterBackground; - bMasterObjects = oArraySlideAtoms[0]->m_bMasterObjects; + bMasterColorScheme = oArraySlideAtoms[0]->m_bMasterScheme; + bMasterBackGround = oArraySlideAtoms[0]->m_bMasterBackground; + bMasterObjects = oArraySlideAtoms[0]->m_bMasterObjects; } else { @@ -1733,9 +1760,9 @@ void CPPTUserInfo::LoadMaster(_typeMaster type, CRecordSlide* pMaster, CSlideInf { dwID = (_UINT32)oArrayNotesAtoms[0]->m_nSlideIDRef; - bMasterColorScheme = oArrayNotesAtoms[0]->m_bMasterScheme; - bMasterBackGround = oArrayNotesAtoms[0]->m_bMasterBackground; - bMasterObjects = oArrayNotesAtoms[0]->m_bMasterObjects; + bMasterColorScheme = oArrayNotesAtoms[0]->m_bMasterScheme; + bMasterBackGround = oArrayNotesAtoms[0]->m_bMasterBackground; + bMasterObjects = oArrayNotesAtoms[0]->m_bMasterObjects; } } @@ -1748,23 +1775,23 @@ void CPPTUserInfo::LoadMaster(_typeMaster type, CRecordSlide* pMaster, CSlideInf { if (oArrayHeadersFootersInfo[0]->m_oHeadersFootersAtom) { - pTheme->m_bHasDate = oArrayHeadersFootersInfo[0]->m_oHeadersFootersAtom->m_bHasDate || - oArrayHeadersFootersInfo[0]->m_oHeadersFootersAtom->m_bHasTodayDate || - oArrayHeadersFootersInfo[0]->m_oHeadersFootersAtom->m_bHasUserDate; - pTheme->m_bHasFooter = oArrayHeadersFootersInfo[0]->m_oHeadersFootersAtom->m_bHasFooter; - pTheme->m_bHasSlideNumber = oArrayHeadersFootersInfo[0]->m_oHeadersFootersAtom->m_bHasSlideNumber; + pTheme->m_bHasDate = oArrayHeadersFootersInfo[0]->m_oHeadersFootersAtom->m_bHasDate || + oArrayHeadersFootersInfo[0]->m_oHeadersFootersAtom->m_bHasTodayDate || + oArrayHeadersFootersInfo[0]->m_oHeadersFootersAtom->m_bHasUserDate; + pTheme->m_bHasFooter = oArrayHeadersFootersInfo[0]->m_oHeadersFootersAtom->m_bHasFooter; + pTheme->m_bHasSlideNumber = oArrayHeadersFootersInfo[0]->m_oHeadersFootersAtom->m_bHasSlideNumber; - if (oArrayHeadersFootersInfo[0]->m_oHeadersFootersAtom->m_bHasUserDate ) pTheme->m_nFormatDate = 2; + if (oArrayHeadersFootersInfo[0]->m_oHeadersFootersAtom->m_bHasUserDate) pTheme->m_nFormatDate = 2; } - for(int i = 0 ; i< 3; i++) pTheme->m_PlaceholdersReplaceString[i] = oArrayHeadersFootersInfo[0]->m_HeadersFootersString[i]; + for (int i = 0; i < 3; i++) pTheme->m_PlaceholdersReplaceString[i] = oArrayHeadersFootersInfo[0]->m_HeadersFootersString[i]; } else { - pTheme->m_bHasDate = m_bHasDate; - pTheme->m_bHasFooter = m_bHasFooter; - pTheme->m_bHasSlideNumber = m_bHasSlideNumber; - pTheme->m_nFormatDate = m_nFormatDate; - for (int i = 0 ; i < 3; i++) pTheme->m_PlaceholdersReplaceString[i] = m_PlaceholdersReplaceString[i]; + pTheme->m_bHasDate = m_bHasDate; + pTheme->m_bHasFooter = m_bHasFooter; + pTheme->m_bHasSlideNumber = m_bHasSlideNumber; + pTheme->m_nFormatDate = m_nFormatDate; + for (int i = 0; i < 3; i++) pTheme->m_PlaceholdersReplaceString[i] = m_PlaceholdersReplaceString[i]; } std::vector oArrayStrings; pMaster->GetRecordsByType(&oArrayStrings, false, false); @@ -1795,12 +1822,12 @@ void CPPTUserInfo::LoadMaster(_typeMaster type, CRecordSlide* pMaster, CSlideInf { if (0x01 == oArrayColors[i]->m_oHeader.RecInstance) { - if ( m_oSchemeColors.empty()) + if (m_oSchemeColors.empty()) { oArrayColors[i]->ToArray(&m_oSchemeColors); CorrectColorScheme(m_oSchemeColors);//?? } - if ( pTheme->m_arColorScheme.empty()) + if (pTheme->m_arColorScheme.empty()) { oArrayColors[i]->ToArray(&pTheme->m_arColorScheme); CorrectColorScheme(pTheme->m_arColorScheme); @@ -1829,8 +1856,8 @@ void CPPTUserInfo::LoadMaster(_typeMaster type, CRecordSlide* pMaster, CSlideInf // indexUser = pPairMaster1->second->m_IndexUser; // pMasterWrapper->m_arTextPlaceHolders = pPairMaster1->second->m_oPersist.m_arTextAttrs; //} - pMasterWrapper->m_parEmptyPictures = &m_pDocumentInfo->m_arUsers[indexUser]->m_arOffsetPictures; - pMasterWrapper->m_mapFilePictures = &m_pDocumentInfo->m_mapStoreImageFile; + pMasterWrapper->m_parEmptyPictures = &m_pDocumentInfo->m_arUsers[indexUser]->m_arOffsetPictures; + pMasterWrapper->m_mapFilePictures = &m_pDocumentInfo->m_mapStoreImageFile; //настройки текстовых стилей ----------------------------------------------- @@ -1898,8 +1925,8 @@ void CPPTUserInfo::LoadNoMainMaster(_UINT32 dwMasterID) return; bool bMasterColorScheme = oArraySlideAtoms[0]->m_bMasterScheme; - bool bMasterBackGround = oArraySlideAtoms[0]->m_bMasterBackground; - bool bMasterObjects = oArraySlideAtoms[0]->m_bMasterObjects; + bool bMasterBackGround = oArraySlideAtoms[0]->m_bMasterBackground; + bool bMasterObjects = oArraySlideAtoms[0]->m_bMasterObjects; _UINT32 dwID = (_UINT32)oArraySlideAtoms[0]->m_nMasterIDRef; @@ -1928,20 +1955,20 @@ void CPPTUserInfo::LoadNoMainMaster(_UINT32 dwMasterID) CSlideInfo elm; m_arMasterWrapper.push_back(elm); - CSlideInfo* pMasterWrapper = &m_arMasterWrapper[m_arMasterWrapper.size() - 1]; + CSlideInfo* pMasterWrapper = &m_arMasterWrapper[m_arMasterWrapper.size() - 1]; -// pMasterWrapper->m_arTextPlaceHolders = pCurMaster->m_oPersist.m_arTextAttrs; + // pMasterWrapper->m_arTextPlaceHolders = pCurMaster->m_oPersist.m_arTextAttrs; pMasterWrapper->m_arTextPlaceHolders.clear(); - for (auto* pTextAttr : pCurMaster->m_oPersist.m_arTextAttrs) - if (pTextAttr) - pMasterWrapper->m_arTextPlaceHolders.push_back(*pTextAttr); + for (auto* pTextAttr : pCurMaster->m_oPersist.m_arTextAttrs) + if (pTextAttr) + pMasterWrapper->m_arTextPlaceHolders.push_back(*pTextAttr); - pMasterWrapper->m_mapFilePictures = &m_pDocumentInfo->m_mapStoreImageFile; + pMasterWrapper->m_mapFilePictures = &m_pDocumentInfo->m_mapStoreImageFile; if (m_pDocumentInfo->m_arUsers[pCurMaster->m_IndexUser]->m_arOffsetPictures.empty() == false) - pMasterWrapper->m_parEmptyPictures = &m_pDocumentInfo->m_arUsers[pCurMaster->m_IndexUser]->m_arOffsetPictures; + pMasterWrapper->m_parEmptyPictures = &m_pDocumentInfo->m_arUsers[pCurMaster->m_IndexUser]->m_arOffsetPictures; else - pMasterWrapper->m_parEmptyPictures = &m_pDocumentInfo->m_arUsers[0]->m_arOffsetPictures; + pMasterWrapper->m_parEmptyPictures = &m_pDocumentInfo->m_arUsers[0]->m_arOffsetPictures; std::map<_UINT32, LONG>::iterator pPairTheme = m_mapMasterToTheme.find(dwID); @@ -1950,8 +1977,8 @@ void CPPTUserInfo::LoadNoMainMaster(_UINT32 dwMasterID) m_mapMasterToTheme.insert(std::pair<_UINT32, LONG>(dwMasterID, pPairTheme->second)); - CSlideInfo * pThemeWrapper = &m_arMasterWrapper[pPairTheme->second]; - CTheme * pTheme = m_arThemes [pPairTheme->second].get(); + CSlideInfo* pThemeWrapper = &m_arMasterWrapper[pPairTheme->second]; + CTheme* pTheme = m_arThemes[pPairTheme->second].get(); std::wstring strLayoutType, strLayoutName; ConvertLayoutType(oArraySlideAtoms[0]->m_oLayout, strLayoutType, strLayoutName); @@ -1960,9 +1987,9 @@ void CPPTUserInfo::LoadNoMainMaster(_UINT32 dwMasterID) int lLayoutID = AddNewLayout(pTheme, pCurMaster, false, false); - pLayout = pTheme->m_arLayouts[lLayoutID].get(); - pLayout->m_bShowMasterShapes = false; - pLayout->m_bIsTitleMaster = true; + pLayout = pTheme->m_arLayouts[lLayoutID].get(); + pLayout->m_bShowMasterShapes = false; + pLayout->m_bIsTitleMaster = true; pTheme->m_mapTitleLayout[dwMasterID] = lLayoutID; @@ -2011,24 +2038,24 @@ void CPPTUserInfo::LoadNoMainMaster(_UINT32 dwMasterID) { if (oArrayHeadersFootersInfo[0]->m_oHeadersFootersAtom) { - pLayout->m_bHasDate = oArrayHeadersFootersInfo[0]->m_oHeadersFootersAtom->m_bHasDate || - oArrayHeadersFootersInfo[0]->m_oHeadersFootersAtom->m_bHasTodayDate || - oArrayHeadersFootersInfo[0]->m_oHeadersFootersAtom->m_bHasUserDate; - pLayout->m_bHasFooter = oArrayHeadersFootersInfo[0]->m_oHeadersFootersAtom->m_bHasFooter; - pLayout->m_bHasSlideNumber = oArrayHeadersFootersInfo[0]->m_oHeadersFootersAtom->m_bHasSlideNumber; + pLayout->m_bHasDate = oArrayHeadersFootersInfo[0]->m_oHeadersFootersAtom->m_bHasDate || + oArrayHeadersFootersInfo[0]->m_oHeadersFootersAtom->m_bHasTodayDate || + oArrayHeadersFootersInfo[0]->m_oHeadersFootersAtom->m_bHasUserDate; + pLayout->m_bHasFooter = oArrayHeadersFootersInfo[0]->m_oHeadersFootersAtom->m_bHasFooter; + pLayout->m_bHasSlideNumber = oArrayHeadersFootersInfo[0]->m_oHeadersFootersAtom->m_bHasSlideNumber; if (oArrayHeadersFootersInfo[0]->m_oHeadersFootersAtom->m_bHasUserDate) pLayout->m_nFormatDate = 2; - for (int i = 0 ; i < 3; i++) pLayout->m_PlaceholdersReplaceString[i] = oArrayHeadersFootersInfo[0]->m_HeadersFootersString[i]; + for (int i = 0; i < 3; i++) pLayout->m_PlaceholdersReplaceString[i] = oArrayHeadersFootersInfo[0]->m_HeadersFootersString[i]; } } else {//???? - pLayout->m_bHasDate = m_bHasDate; - pLayout->m_bHasFooter = m_bHasFooter; - pLayout->m_bHasSlideNumber = m_bHasSlideNumber; - pLayout->m_nFormatDate = m_nFormatDate; - for (int i = 0 ; i < 3; i++) pLayout->m_PlaceholdersReplaceString[i] = m_PlaceholdersReplaceString[i]; + pLayout->m_bHasDate = m_bHasDate; + pLayout->m_bHasFooter = m_bHasFooter; + pLayout->m_bHasSlideNumber = m_bHasSlideNumber; + pLayout->m_nFormatDate = m_nFormatDate; + for (int i = 0; i < 3; i++) pLayout->m_PlaceholdersReplaceString[i] = m_PlaceholdersReplaceString[i]; } std::vector oArrayStrings; @@ -2074,7 +2101,7 @@ void CPPTUserInfo::LoadNoMainMaster(_UINT32 dwMasterID) pShape->SetupProperties(NULL, pTheme, pLayout); pLayout->m_bIsBackground = true; - pLayout->m_oBackground = pShape->m_oBrush; + pLayout->m_oBackground = pShape->m_oBrush; } } } @@ -2328,9 +2355,10 @@ void CPPTUserInfo::LoadExternal(CRecordExObjListContainer* pExObjects) { PPT::CExFilesInfo oInfo; - oInfo.m_strFilePath = m_oExMedia.m_strPresentationDirectory + FILE_SEPARATOR_STR + oArrayStrings[0]->m_strText + _T(".audio"); - oInfo.m_dwID = (_UINT32)XmlUtils::GetInteger(oArrayStrings[2]->m_strText.c_str()); - oInfo.m_name = oArrayStrings[0]->m_strText; + oInfo.m_strFilePath = m_oExMedia.m_strPresentationDirectory + FILE_SEPARATOR_STR + L"audio" + std::to_wstring(m_oExMedia.m_arAudioCollection.size() + 1) + L".audio"; + oInfo.m_dwID = (_UINT32)XmlUtils::GetInteger(oArrayStrings[2]->m_strText.c_str()); + oInfo.m_name = oArrayStrings[0]->m_strText; + oInfo.m_strFileExt = oArrayStrings[1]->m_strText; m_oExMedia.m_arAudioCollection.push_back(oInfo); oArrayData[0]->SaveToFile(oInfo.m_strFilePath); @@ -2342,15 +2370,22 @@ void CPPTUserInfo::LoadExternal(CRecordExObjListContainer* pExObjects) return; // читаем видео ---------------------------------------------- - std::vector oArray; - pExObjects->GetRecordsByType(&oArray, true); + std::vector oArrayVideo; + pExObjects->GetRecordsByType(&oArrayVideo, true); - for (size_t nIndex = 0; nIndex < oArray.size(); ++nIndex) + for (size_t nIndex = 0; nIndex < oArrayVideo.size(); ++nIndex) { - LoadExVideo(oArray[nIndex]); + LoadExVideo(oArrayVideo[nIndex]); } + // читаем ole ---------------------------------------------- + std::vector oArrayObj; + pExObjects->GetRecordsByType(&oArrayObj, true); - oArray.clear(); + for (size_t nIndex = 0; nIndex < oArrayObj.size(); ++nIndex) + { + LoadExOleObject(oArrayObj[nIndex]); + } + oArrayObj.clear(); // ----------------------------------------------------------- // читаем аудио ---------------------------------------------- @@ -2359,10 +2394,10 @@ void CPPTUserInfo::LoadExternal(CRecordExObjListContainer* pExObjects) std::vector oArrayWAVLink; std::vector oArrayAudioEmbedded; - pExObjects->GetRecordsByType(&oArrayAudioCD , true); - pExObjects->GetRecordsByType(&oArrayAudioMIDI , true); - pExObjects->GetRecordsByType(&oArrayWAVLink , true); - pExObjects->GetRecordsByType(&oArrayAudioEmbedded , true); + pExObjects->GetRecordsByType(&oArrayAudioCD, true); + pExObjects->GetRecordsByType(&oArrayAudioMIDI, true); + pExObjects->GetRecordsByType(&oArrayWAVLink, true); + pExObjects->GetRecordsByType(&oArrayAudioEmbedded, true); for (size_t nIndex = 0; nIndex < oArrayAudioMIDI.size(); ++nIndex) { @@ -2374,39 +2409,39 @@ void CPPTUserInfo::LoadExternal(CRecordExObjListContainer* pExObjects) } for (size_t nIndex = 0; nIndex < oArrayAudioEmbedded.size(); ++nIndex) { - _UINT32 dwKeySound = oArrayAudioEmbedded[nIndex]->m_nSoundID; - _UINT32 dwKeyObj = oArrayAudioEmbedded[nIndex]->m_oMedia.m_nExObjID; + _UINT32 dwKeySound = oArrayAudioEmbedded[nIndex]->m_nSoundID; + _UINT32 dwKeyObj = oArrayAudioEmbedded[nIndex]->m_oMedia.m_nExObjID; PPT::CExFilesInfo* pInfo = m_oExMedia.LockAudioFromCollection(dwKeySound); if (NULL != pInfo) { PPT::CExFilesInfo oAudio; - oAudio.m_dwID = dwKeyObj; - oAudio.m_strFilePath = pInfo->m_strFilePath; - oAudio.m_bLoop = oArrayAudioEmbedded[nIndex]->m_oMedia.m_bLoop; + oAudio.m_dwID = dwKeyObj; + oAudio.m_strFilePath = pInfo->m_strFilePath; + oAudio.m_bLoop = oArrayAudioEmbedded[nIndex]->m_oMedia.m_bLoop; m_oExMedia.m_arAudios.push_back(oAudio); } } for (size_t nIndex = 0; nIndex < oArrayAudioCD.size(); ++nIndex) { - _UINT32 dwKeyObj = oArrayAudioCD[nIndex]->m_oMedia.m_nExObjID; + _UINT32 dwKeyObj = oArrayAudioCD[nIndex]->m_oMedia.m_nExObjID; - PPT::CExFilesInfo* pInfo = m_oExMedia.LockAudio(dwKeyObj); + PPT::CExFilesInfo* pInfo = m_oExMedia.LockAudio(dwKeyObj); if (NULL != pInfo) { - pInfo->m_dStartTime = oArrayAudioCD[nIndex]->m_dStartTime; - pInfo->m_dEndTime = oArrayAudioCD[nIndex]->m_dEndTime; - pInfo->m_bLoop = oArrayAudioCD[nIndex]->m_oMedia.m_bLoop; + pInfo->m_dStartTime = oArrayAudioCD[nIndex]->m_dStartTime; + pInfo->m_dEndTime = oArrayAudioCD[nIndex]->m_dEndTime; + pInfo->m_bLoop = oArrayAudioCD[nIndex]->m_oMedia.m_bLoop; } } //-------------------------------------------------------------------- std::vector oArrayHyperlinkContainer; - pExObjects->GetRecordsByType(&oArrayHyperlinkContainer , true); + pExObjects->GetRecordsByType(&oArrayHyperlinkContainer, true); for (const auto* pExHyperlink : oArrayHyperlinkContainer) { @@ -2422,11 +2457,11 @@ void CPPTUserInfo::LoadExternal(CRecordExObjListContainer* pExObjects) // it isn't normal that here we should catch slide number. if (pExHyperlink->m_friendlyNameAtom.IsInit()) { - std::wstring& recStr =pExHyperlink->m_friendlyNameAtom->m_strText; + std::wstring& recStr = pExHyperlink->m_friendlyNameAtom->m_strText; int slideNum = oInfo.GetSlideNumber(recStr); if (slideNum != -1) { - oInfo.m_strFilePath = recStr; + oInfo.m_strFilePath = recStr; oInfo.m_type = CExFilesInfo::ExFilesType::eftSlide; m_oExMedia.m_arSlides.push_back(oInfo); wasSlide = true; @@ -2439,17 +2474,19 @@ void CPPTUserInfo::LoadExternal(CRecordExObjListContainer* pExObjects) if (pExHyperlink->m_targetAtom.IsInit()) { - std::wstring& recStr =pExHyperlink->m_targetAtom->m_strText; - oInfo.m_strFilePath = recStr; + std::wstring& recStr = pExHyperlink->m_targetAtom->m_strText; + oInfo.m_strFilePath = recStr; if (oInfo.isAudioLink(recStr)) { oInfo.m_type = CExFilesInfo::ExFilesType::eftAudio; m_oExMedia.m_arAudioCollection.push_back(oInfo); - }else if (oInfo.isHTTPLink(recStr)) + } + else if (oInfo.isHTTPLink(recStr)) { oInfo.m_type = CExFilesInfo::ExFilesType::eftHyperlink; m_oExMedia.m_arHyperlinks.push_back(oInfo); - }else{ + } + else { oInfo.m_type = CExFilesInfo::ExFilesType::eftHyperlink; m_oExMedia.m_arHyperlinks.push_back(oInfo); } @@ -2459,12 +2496,13 @@ void CPPTUserInfo::LoadExternal(CRecordExObjListContainer* pExObjects) { // Here we need to write some records like file's path and slides std::wstring& recStr = pExHyperlink->m_locationAtom->m_strText; - oInfo.m_strFilePath = recStr; + oInfo.m_strFilePath = recStr; if (!wasSlide) { oInfo.m_type = CExFilesInfo::ExFilesType::eftSlide; m_oExMedia.m_arSlides.push_back(oInfo); - } else if (!m_oExMedia.m_arSlides.empty()) + } + else if (!m_oExMedia.m_arSlides.empty()) { oInfo.m_type = CExFilesInfo::ExFilesType::eftSlide; m_oExMedia.m_arSlides.back().m_strFilePath = recStr; @@ -2473,8 +2511,44 @@ void CPPTUserInfo::LoadExternal(CRecordExObjListContainer* pExObjects) } } +void CPPTUserInfo::LoadExOleObject(CRecordsContainer* pExObject) +{ + //exOleEmbedAtom + //exOleObjAtom + //menuNameAtom + //progIdAtom + //clipboardNameAtom + //metafile(variable) + + std::vector oArrayExOleEmbed; + std::vector oArrayExOleObj; + std::vector oArrayCString; + + pExObject->GetRecordsByType(&oArrayExOleEmbed, false); + pExObject->GetRecordsByType(&oArrayExOleObj, false); + pExObject->GetRecordsByType(&oArrayCString, false); + if (1 == oArrayExOleObj.size()) + { + PPT::CExFilesInfo oInfo; + oInfo.m_dwID = oArrayExOleObj[0]->m_nExObjID; + + if (oArrayCString.size() > 0) + oInfo.m_name = oArrayCString[0]->m_strText; + + if (oArrayCString.size() > 1) + oInfo.m_progName = oArrayCString[1]->m_strText; + + oInfo.m_strFilePath = m_pDocumentInfo->GetBinFromStg(L"", oArrayExOleObj[0]->m_nPersistID); // ExOleObjStg || ExControlStg + + m_oExMedia.m_arOleObjects.push_back(oInfo); + } + + oArrayExOleEmbed.clear(); + oArrayExOleObj.clear(); + oArrayCString.clear(); +} void CPPTUserInfo::LoadExVideo(CRecordsContainer* pExObject) { @@ -2488,10 +2562,10 @@ void CPPTUserInfo::LoadExVideo(CRecordsContainer* pExObject) { PPT::CExFilesInfo oInfo; - oInfo.m_dwID = oArrayExMedia[0]->m_nExObjID; - oInfo.m_strFilePath = oArrayCString[0]->m_strText; + oInfo.m_dwID = oArrayExMedia[0]->m_nExObjID; + oInfo.m_strFilePath = oArrayCString[0]->m_strText; - oInfo.m_bLoop = oArrayExMedia[0]->m_bLoop; + oInfo.m_bLoop = oArrayExMedia[0]->m_bLoop; m_oExMedia.m_arVideos.push_back(oInfo); } @@ -2511,13 +2585,13 @@ void CPPTUserInfo::LoadExAudio(CRecordsContainer* pExObject) { PPT::CExFilesInfo oInfo; - oInfo.m_dwID = oArrayExMedia[0]->m_nExObjID; - oInfo.m_strFilePath = oArrayCString[0]->m_strText; + oInfo.m_dwID = oArrayExMedia[0]->m_nExObjID; + oInfo.m_strFilePath = oArrayCString[0]->m_strText; - oInfo.m_bLoop = oArrayExMedia[0]->m_bLoop; + oInfo.m_bLoop = oArrayExMedia[0]->m_bLoop; - oInfo.m_fNarration = oArrayExMedia[0]->m_bNarration; - oInfo.m_fRewind = oArrayExMedia[0]->m_bRewind; + oInfo.m_fNarration = oArrayExMedia[0]->m_bNarration; + oInfo.m_fRewind = oArrayExMedia[0]->m_bRewind; m_oExMedia.m_arAudios.push_back(oInfo); } @@ -2568,14 +2642,14 @@ void CPPTUserInfo::LoadExAudio(CRecordsContainer* pExObject) // } //} -void CPPTUserInfo::AddAudioTransition (_UINT32 refID, CTransition* pTransition, const std::wstring& strFilePath) +void CPPTUserInfo::AddAudioTransition(_UINT32 refID, CTransition* pTransition, const std::wstring& strFilePath) { - if (NULL==pTransition) + if (NULL == pTransition) return; std::vector sound; m_oDocument.GetRecordsByType(&sound, false); - if (sound.empty() || sound[0]->m_arRecords.size() < refID) + if (sound.empty() || sound[0]->m_arRecords.size() <= refID) return; auto audio = dynamic_cast(sound[0]->m_arRecords[refID]); @@ -2602,15 +2676,15 @@ void CPPTUserInfo::CreateDefaultStyle(PPT::CTextStyles& pStyle, PPT::CTheme* pTh PPT::CTextPFRun* pPF = &pStyle.m_pLevels[i]->m_oPFRun; PPT::CTextCFRun* pCF = &pStyle.m_pLevels[i]->m_oCFRun; - pCF->Language = m_wLanguage; + pCF->Language = m_wLanguage; - pCF->Size = 18; + pCF->Size = 18; pCF->font.font = new PPT::CFontProperty(pTheme->m_arFonts.size() > 1 ? pTheme->m_arFonts[1] : pTheme->m_arFonts[0]); } } -void CPPTUserInfo::CorrectColorScheme(std::vector &oScheme) +void CPPTUserInfo::CorrectColorScheme(std::vector& oScheme) { if (oScheme.size() < 1) return; @@ -2642,10 +2716,10 @@ void CPPTUserInfo::CorrectColorScheme(std::vector &oScheme) //0x06 //Accent 2 color //0x07 //Accent 3 color - oScheme = oArrayMem; + oScheme = oArrayMem; } -void CPPTUserInfo::ConvertLayoutType(SSlideLayoutAtom &layoutRecord, std::wstring &type, std::wstring &name) +void CPPTUserInfo::ConvertLayoutType(SSlideLayoutAtom& layoutRecord, std::wstring& type, std::wstring& name) { name = L"Blank Slide"; type = L"blank"; @@ -2683,7 +2757,7 @@ void CPPTUserInfo::ConvertLayoutType(SSlideLayoutAtom &layoutRecord, std::wstrin }break; case SL_TwoColumns: { - PlaceholderEnum leftType = (PlaceholderEnum)layoutRecord.m_pPlaceHolderID[1]; + PlaceholderEnum leftType = (PlaceholderEnum)layoutRecord.m_pPlaceHolderID[1]; PlaceholderEnum rightType = (PlaceholderEnum)layoutRecord.m_pPlaceHolderID[2]; name = L"Two Objects Slide"; @@ -2732,7 +2806,7 @@ void CPPTUserInfo::ConvertLayoutType(SSlideLayoutAtom &layoutRecord, std::wstrin }break; case SL_TwoRows: { - PlaceholderEnum topType = (PlaceholderEnum)layoutRecord.m_pPlaceHolderID[1]; + PlaceholderEnum topType = (PlaceholderEnum)layoutRecord.m_pPlaceHolderID[1]; PlaceholderEnum bottomType = (PlaceholderEnum)layoutRecord.m_pPlaceHolderID[2]; if (topType == PT_Body && bottomType == PT_Object) @@ -2799,7 +2873,7 @@ void CPPTUserInfo::ConvertLayoutType(SSlideLayoutAtom &layoutRecord, std::wstrin } } -void CPPTUserInfo::LoadAutoNumbering(CRecordGroupShapeContainer *pGroupContainer, CTheme *pTheme) +void CPPTUserInfo::LoadAutoNumbering(CRecordGroupShapeContainer* pGroupContainer, CTheme* pTheme) { std::vector arrOfficeArtClientData; @@ -2829,7 +2903,7 @@ void CPPTUserInfo::LoadAutoNumbering(CRecordGroupShapeContainer *pGroupContainer } } -void CPPTUserInfo::LoadBulletBlip(CShapeElement *pShape) +void CPPTUserInfo::LoadBulletBlip(CShapeElement* pShape) { if (pShape == nullptr || pShape->m_pShape == nullptr) return; std::vector arrDocInfoCont; @@ -2847,7 +2921,7 @@ void CPPTUserInfo::LoadBulletBlip(CShapeElement *pShape) const auto& arrBlipEntity = pProgBinaryTag->m_blipCollectionContainer.get().m_rgBlipEntityAtom; // const auto& arrAutoNum = pProgBinaryTag->m_outlineTextPropsContainer.get() - if(arrBlipEntity.empty()) + if (arrBlipEntity.empty()) return; for (auto& par : arrPars) @@ -2864,7 +2938,7 @@ void CPPTUserInfo::LoadBulletBlip(CShapeElement *pShape) } } -void CPPTUserInfo::LoadAutoNumBullet(CShapeElement *pShape, int slideID) +void CPPTUserInfo::LoadAutoNumBullet(CShapeElement* pShape, int slideID) { if (pShape == nullptr || pShape->m_pShape == nullptr) return; std::vector arrDocInfoCont; @@ -2911,7 +2985,7 @@ void CPPTUserInfo::LoadAutoNumBullet(CShapeElement *pShape, int slideID) auto& prop9 = (*arrStyleTextProp9)[pp9rt]; if (prop9.m_pf9.m_optBulletAutoNumberScheme.is_init() && - prop9.m_pf9.m_optfBulletHasAutoNumber.get_value_or(false)) + prop9.m_pf9.m_optfBulletHasAutoNumber.get_value_or(false)) { auto* pBuAutoNum = new CBulletAutoNum; pBuAutoNum->type = prop9.m_pf9.m_optBulletAutoNumberScheme->SchemeToStr(); diff --git a/MsBinaryFile/PptFile/Reader/PPTDocumentInfoOneUser.h b/MsBinaryFile/PptFile/Reader/PPTDocumentInfoOneUser.h index 5bccb898361..3812682dffa 100644 --- a/MsBinaryFile/PptFile/Reader/PPTDocumentInfoOneUser.h +++ b/MsBinaryFile/PptFile/Reader/PPTDocumentInfoOneUser.h @@ -76,6 +76,8 @@ class CPPTUserInfo : public CDocument // перевод id мастера в индекс темы/шаблона std::map<_UINT32, LONG> m_mapMasterToTheme; + std::map<_UINT32, LONG> m_mapRealUsedMaster; + // original id -> natural id std::map<_UINT32, _UINT32> m_mapMasterOriginalIds; @@ -98,8 +100,7 @@ class CPPTUserInfo : public CDocument bool m_bHasFooter; int m_nFormatDate; - CRecordVbaProjectStg* m_VbaProjectStg; - int m_lIndexThisUser; + int m_lIndexThisUser; double m_nWriteSlideTimeOffset; double m_nWriteSlideTime; @@ -140,10 +141,12 @@ class CPPTUserInfo : public CDocument void LoadSlide(_UINT32 dwSlideID, CSlide* pSlide); void LoadNotes(_UINT32 dwNotesID, CSlide* pSlide); + void TestSlide(_UINT32 dwSlideID); + void LoadMasters(); void LoadNoMainMaster (_UINT32 dwMasterID); - void LoadMainMaster (_UINT32 dwMasterID); + void LoadMainMaster (_UINT32 dwMasterID, bool alwaysLoad); void LoadMaster(_typeMaster type, CRecordSlide* pMaster, CSlideInfo *& pMasterWrapper, CThemePtr & pTheme); @@ -157,6 +160,7 @@ class CPPTUserInfo : public CDocument void LoadExVideo(CRecordsContainer* pExObject); void LoadExAudio(CRecordsContainer* pExObject); + void LoadExOleObject(CRecordsContainer* pExObject); void LoadAutoNumbering(CRecordGroupShapeContainer* pGroupContainer, CTheme* pTheme); void LoadBulletBlip(CShapeElement* pShape); diff --git a/MsBinaryFile/PptFile/Reader/ReadStructures.cpp b/MsBinaryFile/PptFile/Reader/ReadStructures.cpp index e56c26a5be3..d2c78da6258 100644 --- a/MsBinaryFile/PptFile/Reader/ReadStructures.cpp +++ b/MsBinaryFile/PptFile/Reader/ReadStructures.cpp @@ -906,6 +906,28 @@ void CMetaFileBuffer::SetData(BYTE *pCompress, LONG lCompressSize, LONG lUncompr } } } +int CMetaFileBuffer::ToBuffer(BYTE*& Data) +{ + int sz = 0; + + if (NULL != m_pMetaHeader) sz += m_lMetaHeaderSize; + if (NULL != m_pMetaFile) sz += m_lMetaFileSize; + + Data = new BYTE[sz]; + int pos = 0; + + if (NULL != m_pMetaHeader) + { + memcpy(Data, (BYTE*)m_pMetaHeader, m_lMetaHeaderSize); + pos += m_lMetaHeaderSize; + } + if (NULL != m_pMetaFile) + { + memcpy(Data + pos, (BYTE*)m_pMetaFile, m_lMetaFileSize); + } + + return sz; +} void CMetaFileBuffer::ToFile(NSFile::CFileBinary *pFile) { diff --git a/MsBinaryFile/PptFile/Reader/ReadStructures.h b/MsBinaryFile/PptFile/Reader/ReadStructures.h index 26f47beb2fe..3fcb30a3496 100644 --- a/MsBinaryFile/PptFile/Reader/ReadStructures.h +++ b/MsBinaryFile/PptFile/Reader/ReadStructures.h @@ -180,6 +180,7 @@ class CMetaFileBuffer void SetData(BYTE* pCompress, LONG lCompressSize, LONG lUncompressSize, bool bIsCompressed); + int ToBuffer(BYTE*& Data); void ToFile(NSFile::CFileBinary* pFile); }; diff --git a/MsBinaryFile/PptFile/Reader/Records.cpp b/MsBinaryFile/PptFile/Reader/Records.cpp index b8769b8018e..c8cf143fa57 100644 --- a/MsBinaryFile/PptFile/Reader/Records.cpp +++ b/MsBinaryFile/PptFile/Reader/Records.cpp @@ -624,8 +624,10 @@ IRecord* CreateByType(SRecordHeader oHeader, _commonInfo* commonInfo) //CREATE_BY_TYPE(RECORD_TYPE_METAFILE , CRecordMetafileBlob) CREATE_BY_TYPE(RT_CString, CRecordCString) CREATE_BY_TYPE(RT_SoundCollectionAtom, CRecordSoundCollAtom) + CREATE_BY_TYPE(RT_ExternalOleObjectAtom, CRecordExOleObjAtom) CREATE_BY_TYPE(RT_ExternalOleEmbedAtom, CRecordExOleEmbedAtom) + CREATE_BY_TYPE(RT_ExternalOleEmbed, CRecordExOleEmbedContainer) //CREATE_BY_TYPE(RECORD_TYPE_BOOKMARK_ENTITY_ATOM , CRecordBookmarkEntityAtom) //CREATE_BY_TYPE(RECORD_TYPE_EXLINK_ATOM , CRecordExOleLinkAtom) @@ -672,7 +674,6 @@ IRecord* CreateByType(SRecordHeader oHeader, _commonInfo* commonInfo) CREATE_BY_TYPE(RTE_CLIENTDATA, CRecordOfficeArtClientData) CREATE_BY_TYPE(RTE_CLIENTTEXTBOX, CRecordOfficeArtClientTextbox) - CREATE_BY_TYPE(RT_ExternalCdAudio, CRecordExCDAudioContainer) CREATE_BY_TYPE(RT_ExternalWavAudioLink, CRecordWAVAudioLinkContainer) CREATE_BY_TYPE(RT_ExternalWavAudioEmbedded, CRecordWAVAudioEmbeddedContainer) diff --git a/MsBinaryFile/PptFile/Reader/RoundTripExtractor.cpp b/MsBinaryFile/PptFile/Reader/RoundTripExtractor.cpp index b97e3129237..dbf0dc2c835 100644 --- a/MsBinaryFile/PptFile/Reader/RoundTripExtractor.cpp +++ b/MsBinaryFile/PptFile/Reader/RoundTripExtractor.cpp @@ -38,13 +38,12 @@ using namespace PPT; RoundTripExtractor::RoundTripExtractor(const CUnknownRoundTrip* rt, const std::wstring& tempPath) : m_roundTripRecord(rt), m_hasError(false) { - m_tempPath = NSDirectory::CreateDirectoryWithUniqueName(tempPath) + FILE_SEPARATOR_STR; + m_tempPath = tempPath; m_hasError = !extract(); } RoundTripExtractor::~RoundTripExtractor() { - NSDirectory::DeleteDirectory(m_tempPath); } vector_string RoundTripExtractor::find(const std::wstring& strRegEx) const @@ -77,7 +76,7 @@ bool RoundTripExtractor::extract() if (!m_roundTripRecord) return false; - std::wstring tempZipPath = m_tempPath + FILE_SEPARATOR_STR + L"RoundTrip.zip"; + std::wstring tempZipPath = NSFile::CFileBinary::CreateTempFileWithUniqueName(m_tempPath, L"RndT") + L".zip"; BYTE* zipData = m_roundTripRecord->data.first.get(); ULONG zipDataLen = m_roundTripRecord->data.second; diff --git a/MsBinaryFile/PptFile/Reader/SlideInfo.cpp b/MsBinaryFile/PptFile/Reader/SlideInfo.cpp index 998220f384d..af999e29bdd 100644 --- a/MsBinaryFile/PptFile/Reader/SlideInfo.cpp +++ b/MsBinaryFile/PptFile/Reader/SlideInfo.cpp @@ -104,7 +104,7 @@ std::wstring CSlideInfo::GetFileNamePicture(_UINT32 lIndex) { return pic->second; } - return _T(""); + return L""; } int CSlideInfo::GetIndexPicture(int lIndex) diff --git a/MsBinaryFile/PptFile/Reader/SlidePersist.cpp b/MsBinaryFile/PptFile/Reader/SlidePersist.cpp index cbfca2186f6..5e1e9ab320e 100644 --- a/MsBinaryFile/PptFile/Reader/SlidePersist.cpp +++ b/MsBinaryFile/PptFile/Reader/SlidePersist.cpp @@ -46,8 +46,8 @@ namespace PPT //std::wstring SSlidePersist::ToString() //{ - // std::wstring str = _T(""); - // str.Format(_T(""), m_nPsrRef, m_nSlideID); + // std::wstring str = L""); + // str.Format(L""), m_nPsrRef, m_nSlideID); // return str; //} diff --git a/MsBinaryFile/PptFile/Records/Animations/TimePropertyList4TimeNodeContainer.cpp b/MsBinaryFile/PptFile/Records/Animations/TimePropertyList4TimeNodeContainer.cpp index efaa8e233b6..97889330cec 100644 --- a/MsBinaryFile/PptFile/Records/Animations/TimePropertyList4TimeNodeContainer.cpp +++ b/MsBinaryFile/PptFile/Records/Animations/TimePropertyList4TimeNodeContainer.cpp @@ -87,11 +87,12 @@ void CRecordTimePropertyList4TimeNodeContainer::ReadFromStream(SRecordHeader &oH default : break; } - - pRecord->ReadFromStream ( ReadHeader, pStream ); + if (pRecord) + { + pRecord->ReadFromStream(ReadHeader, pStream); + m_arrElements.push_back(pRecord); + } lCurLen += 8 + ReadHeader.RecLen; - - m_arrElements.push_back ( pRecord ); } StreamUtils::StreamSeek ( lPos + m_oHeader.RecLen, pStream ); diff --git a/MsBinaryFile/PptFile/Records/Drawing/ArtBlip.cpp b/MsBinaryFile/PptFile/Records/Drawing/ArtBlip.cpp index 22ea809e869..1a2d8d2e89a 100644 --- a/MsBinaryFile/PptFile/Records/Drawing/ArtBlip.cpp +++ b/MsBinaryFile/PptFile/Records/Drawing/ArtBlip.cpp @@ -122,7 +122,7 @@ void CRecordOfficeArtBlip::ReadFromStream(SRecordHeader & oHeader, POLE::Stream* oMetaFile.SetData(pData, oMetaHeader.cbSave, oMetaHeader.cbSize, (bool)(oMetaHeader.compression != 0xFE) ); }break; - case RECORD_TYPE_ESCHER_BLIP_PICT://Medwoche.ppt , (483) + case RECORD_TYPE_ESCHER_BLIP_PICT://Medwoche.ppt , (483), synergieInspiratie.ppt { if (0x0542 == oHeader.RecInstance) lOffset = 16; else if (0x0543 == oHeader.RecInstance) lOffset = 32; @@ -131,11 +131,10 @@ void CRecordOfficeArtBlip::ReadFromStream(SRecordHeader & oHeader, POLE::Stream* lOffset += 34; - oMetaFile.m_bIsValid = TRUE; - oMetaFile.m_sExtension = L".wmf";//L".pct"; - ВРЕМЕННО пока не сделана конвертация pct(pic) хоть во что нито !!! - + sExt = L".pct"; + CMetaHeader oMetaHeader; - oMetaHeader.FromStream(pStream, pDecryptor); //отдельно вынесенный заголовок.. "форматный" находится в блоке данных + oMetaHeader.FromStream(pStream, pDecryptor); BYTE* pData = new BYTE[oHeader.RecLen - lOffset]; pStream->read(pData, oHeader.RecLen - lOffset); @@ -152,7 +151,7 @@ void CRecordOfficeArtBlip::ReadFromStream(SRecordHeader & oHeader, POLE::Stream* StreamUtils::StreamSkip(lOffset, pStream); - sExt = _T(".jpg"); + sExt = L".jpg"; break; } case RECORD_TYPE_ESCHER_BLIP_PNG: @@ -162,7 +161,7 @@ void CRecordOfficeArtBlip::ReadFromStream(SRecordHeader & oHeader, POLE::Stream* StreamUtils::StreamSkip(lOffset, pStream); - sExt = _T(".png"); + sExt = L".png"; break; } case RECORD_TYPE_ESCHER_BLIP_DIB: @@ -172,7 +171,7 @@ void CRecordOfficeArtBlip::ReadFromStream(SRecordHeader & oHeader, POLE::Stream* StreamUtils::StreamSkip(lOffset, pStream); - sExt = _T(".bmp"); + sExt = L".bmp"; break; } case RECORD_TYPE_ESCHER_BLIP_TIFF: @@ -182,7 +181,7 @@ void CRecordOfficeArtBlip::ReadFromStream(SRecordHeader & oHeader, POLE::Stream* StreamUtils::StreamSkip(lOffset, pStream); - sExt = _T(".tif"); + sExt = L".tif"; break; } default: @@ -210,6 +209,37 @@ void CRecordOfficeArtBlip::ReadFromStream(SRecordHeader & oHeader, POLE::Stream* } m_fileName = strFile; } + else if (oHeader.RecType == RECORD_TYPE_ESCHER_BLIP_PICT) + { + unsigned char* newData = NULL; + unsigned int newDataSize = oMetaFile.ToBuffer(newData); + + std::wstring strFile = L"Image " + std::to_wstring(nImagesCount + 1) + sExt; + + NSFile::CFileBinary fileImage; + if (newData && fileImage.CreateFileW(m_pCommonInfo->tempPath + FILE_SEPARATOR_STR + strFile)) + { + fileImage.WriteFile(newData, newDataSize); + fileImage.CloseFile(); + } + if (newData) + delete[]newData; + try + { + CBgraFrame bgraFrame; + if (bgraFrame.OpenFile(m_pCommonInfo->tempPath + FILE_SEPARATOR_STR + strFile)) + { + NSFile::CFileBinary::Remove(m_pCommonInfo->tempPath + FILE_SEPARATOR_STR + strFile); + + strFile = L"Image " + std::to_wstring(nImagesCount + 1) + L".png"; + bgraFrame.SaveFile(m_pCommonInfo->tempPath + FILE_SEPARATOR_STR + strFile, 4); // png + } + } + catch (...) + { + } + m_fileName = strFile; + } else { BYTE* pImage = new BYTE[oHeader.RecLen - lOffset]; @@ -219,6 +249,7 @@ void CRecordOfficeArtBlip::ReadFromStream(SRecordHeader & oHeader, POLE::Stream* { pDecryptor->Decrypt((char*)pImage, oHeader.RecLen - lOffset, 0); } + size_t lOffset2 = 0; if (oHeader.RecType == RECORD_TYPE_ESCHER_BLIP_PNG) { diff --git a/MsBinaryFile/PptFile/Records/Drawing/ShapeContainer.cpp b/MsBinaryFile/PptFile/Records/Drawing/ShapeContainer.cpp index cbc884cd892..943c00f3349 100644 --- a/MsBinaryFile/PptFile/Records/Drawing/ShapeContainer.cpp +++ b/MsBinaryFile/PptFile/Records/Drawing/ShapeContainer.cpp @@ -222,34 +222,42 @@ void CPPTElement::SetUpProperties(CElementPtr pElement, CTheme* pTheme, CSlideIn for (size_t i = 0; i < lCount; ++i) { SetUpPropertyVideo(pElement, pTheme, pWrapper, pSlide, &pProperties->m_arProperties[i]); - } - break; - } + } + }break; case PPT::etPicture: + case PPT::etOleObject: { if (reset_default) { - pElement->m_oBrush.Type = c_BrushTypeTexture; + pElement->m_bIsFilled = false; pElement->m_bLine = false; + pElement->m_oBrush.Type = c_BrushTypeTexture; // or 3000 set ??? } for (size_t i = 0; i < lCount; ++i) { SetUpPropertyImage(pElement, pTheme, pWrapper, pSlide, &pProperties->m_arProperties[i]); } - break; - } + if (false == pElement->m_bIsFilled) + { + pElement->m_oBrush.Type = c_BrushTypeNoFill; + } + else if (pElement->m_oBrush.Type == c_BrushTypeTexture) + { + pElement->m_oBrush.Type = c_BrushTypeSolid; + } + }break; case PPT::etAudio: { if (reset_default) { + pElement->m_bIsFilled = false; pElement->m_bLine = false; } for (size_t i = 0; i < lCount; ++i) { SetUpPropertyAudio(pElement, pTheme, pWrapper, pSlide, &pProperties->m_arProperties[i]); - } - break; - } + } + }break; case PPT::etGroup: { if (reset_default) @@ -282,7 +290,7 @@ void CPPTElement::SetUpProperties(CElementPtr pElement, CTheme* pTheme, CSlideIn pElement->m_oBrush.Type = c_BrushTypeNoFill; } else if (pElement->m_oBrush.Type == c_BrushTypeNotSet && - (pElement->m_lPlaceholderType == 0 && pElement->m_lPlaceholderID < 0 )) + (pElement->m_lPlaceholderType == 0 && pElement->m_lPlaceholderID < 0)) { pElement->m_oBrush.Type = c_BrushTypeSolid; } @@ -292,8 +300,7 @@ void CPPTElement::SetUpProperties(CElementPtr pElement, CTheme* pTheme, CSlideIn pPPTShape->m_oCustomVML.ToCustomShape(pPPTShape, pPPTShape->m_oManager); pPPTShape->ReCalculate(); } - break; - } + }break; default: break; } @@ -548,7 +555,12 @@ void CPPTElement::SetUpProperty(CElementPtr pElement, CTheme* pTheme, CSlideInfo bool bUsebRecolorFillAsPictures = (0x40 == (0x40 & flag2)); if (bUsebFilled) + { pElement->m_bIsFilled = bFilled; + if (pElement->m_oBrush.Type == c_BrushTypeNotSet) + pElement->m_oBrush.Type = c_BrushTypeSolid; + } + break; } @@ -923,9 +935,7 @@ void CPPTElement::SetUpPropertyShape(CElementPtr pElement, CTheme* pTheme, CSlid case ODRAW::metroBlob: { NSFile::CFileBinary file; - - std::wstring tempPath = NSDirectory::CreateDirectoryWithUniqueName(m_tempPath); - std::wstring tempFileName = tempPath + FILE_SEPARATOR_STR + L"tempMetroBlob.zip"; + std::wstring tempFileName = NSFile::CFileBinary::CreateTempFileWithUniqueName(m_tempPath, L"Blob") + L".zip"; if (file.CreateFileW(tempFileName)) { @@ -952,7 +962,6 @@ void CPPTElement::SetUpPropertyShape(CElementPtr pElement, CTheme* pTheme, CSlid delete []utf8Data; } NSFile::CFileBinary::Remove(tempFileName); - NSDirectory::DeleteDirectory(tempPath); }break; case ODRAW::geoRight: { @@ -1641,10 +1650,10 @@ CElementPtr CRecordShapeContainer::GetElement (bool inGroup, CExMedia* pMapIDs, if (CExFilesInfo::eftVideo == exType) { - CVideoElement* pVideoElem = new CVideoElement(); + CVideoElement* pVideoElem = new CVideoElement(); - pVideoElem->m_strVideoFileName = oInfo.m_strFilePath ; - pVideoElem->m_strImageFileName = oInfoDefault.m_strFilePath + FILE_SEPARATOR_STR; + pVideoElem->m_strVideoFileName = oInfo.m_strFilePath ; + pVideoElem->m_strImageFileName = oInfoDefault.m_strFilePath + FILE_SEPARATOR_STR; pElement = CElementPtr(pVideoElem); } @@ -1674,9 +1683,20 @@ CElementPtr CRecordShapeContainer::GetElement (bool inGroup, CExMedia* pMapIDs, } } + else if (CExFilesInfo::eftOleObject == exType) + { + COleObjectElement* pOleObjectElem = new COleObjectElement(); + pOleObjectElem->m_strBinFileName = oInfo.m_strFilePath; + pOleObjectElem->m_strImageFileName = oInfoDefault.m_strFilePath + FILE_SEPARATOR_STR; + + pOleObjectElem->m_strProgId = oInfo.m_progName; + pOleObjectElem->m_strOleName = oInfo.m_name; + + pElement = CElementPtr(pOleObjectElem); + } else { - CImageElement* pImageElem = new CImageElement(); + CImageElement* pImageElem = new CImageElement(); pImageElem->m_strImageFileName = oInfo.m_strFilePath + FILE_SEPARATOR_STR; pElement = CElementPtr(pImageElem); @@ -1778,7 +1798,7 @@ CElementPtr CRecordShapeContainer::GetElement (bool inGroup, CExMedia* pMapIDs, GetRecordsByType(&oArrayFooterMeta, true, true); if (0 < oArrayFooterMeta.size()) { - pElement->m_lPlaceholderType = PT_MasterFooter; + pElement->m_lPlaceholderType = PT_MasterFooter; pElement->m_lPlaceholderUserStr = oArrayFooterMeta[0]->m_nPosition; } std::vector oArraySlideNumberMeta; @@ -2508,7 +2528,7 @@ void CRecordShapeContainer::SetUpTextStyle(std::wstring& strText, CTheme* pTheme } } - if ((_T("") != strText) && 0 == pTextSettings->m_arParagraphs.size()) + if ((L"" != strText) && 0 == pTextSettings->m_arParagraphs.size()) { // значит никаких своих настроек нету. Значит просто пустые свои настройки std::vector oArrayPF; diff --git a/MsBinaryFile/PptFile/Records/ExObjListContainer.cpp b/MsBinaryFile/PptFile/Records/ExObjListContainer.cpp index a104ea3a112..cb00e755444 100644 --- a/MsBinaryFile/PptFile/Records/ExObjListContainer.cpp +++ b/MsBinaryFile/PptFile/Records/ExObjListContainer.cpp @@ -37,3 +37,63 @@ void CRecordExObjListContainer::ReadFromStream(SRecordHeader &oHeader, POLE::Str { CRecordsContainer::ReadFromStream(oHeader, pStream); } + +CRecordExObjStg::CRecordExObjStg(const std::wstring& name, const std::wstring& tempPath) +{ + if (name.empty()) + { + m_sFileName = NSFile::CFileBinary::CreateTempFileWithUniqueName(tempPath, L"bin"); + } + else + { + m_sFileName = tempPath + FILE_SEPARATOR_STR + name; + } +} + +CRecordExObjStg::~CRecordExObjStg() +{ +} + +void CRecordExObjStg::ReadFromStream(SRecordHeader& oHeader, POLE::Stream* pStream) +{ + m_oHeader = oHeader; + + ULONG decompressedSize = m_oHeader.RecLen, compressedSize = m_oHeader.RecLen; + + BYTE* pData = new BYTE[compressedSize]; + if (!pData) return; + + if (m_oHeader.RecInstance == 0x01) + { + decompressedSize = StreamUtils::ReadDWORD(pStream) + 64; + compressedSize -= 4; + } + pStream->read(pData, compressedSize); + + //if (pDecryptor) + //{ + // pDecryptor->Decrypt((char*)pData, compressedSize, 0); + //} + + if (m_oHeader.RecInstance == 0x01) + { + BYTE* pDataUncompress = new BYTE[decompressedSize]; + NSZip::Decompress(pData, compressedSize, pDataUncompress, decompressedSize); + + delete[]pData; + pData = pDataUncompress; + } + + NSFile::CFileBinary file; + if (file.CreateFileW(m_sFileName)) + { + file.WriteFile(pData, decompressedSize); + file.CloseFile(); + } + else + { + m_sFileName.clear(); + } + delete[] pData; + pData = NULL; +} diff --git a/MsBinaryFile/PptFile/Records/ExObjListContainer.h b/MsBinaryFile/PptFile/Records/ExObjListContainer.h index c7194504d56..03ebd9bd366 100644 --- a/MsBinaryFile/PptFile/Records/ExObjListContainer.h +++ b/MsBinaryFile/PptFile/Records/ExObjListContainer.h @@ -39,4 +39,16 @@ class CRecordExObjListContainer : public CRecordsContainer public: virtual void ReadFromStream(SRecordHeader & oHeader, POLE::Stream* pStream) override; }; + + +class CRecordExObjStg : public CUnknownRecord +{ +public: + std::wstring m_sFileName; + + CRecordExObjStg(const std::wstring& name, const std::wstring& tempPath); + ~CRecordExObjStg(); + + virtual void ReadFromStream(SRecordHeader& oHeader, POLE::Stream* pStream) override; +}; } diff --git a/MsBinaryFile/PptFile/Records/ExOleEmbedAtom.cpp b/MsBinaryFile/PptFile/Records/ExOleEmbedAtom.cpp index 5f84e0ab3ac..db9d45029c0 100644 --- a/MsBinaryFile/PptFile/Records/ExOleEmbedAtom.cpp +++ b/MsBinaryFile/PptFile/Records/ExOleEmbedAtom.cpp @@ -43,3 +43,8 @@ void CRecordExOleEmbedAtom::ReadFromStream(SRecordHeader &oHeader, POLE::Stream m_nIsTable = StreamUtils::ReadBYTE(pStream); StreamUtils::StreamSkip(1, pStream); } + +void CRecordExOleEmbedContainer::ReadFromStream(SRecordHeader& oHeader, POLE::Stream* pStream) +{ + CRecordsContainer::ReadFromStream(oHeader, pStream); +} \ No newline at end of file diff --git a/MsBinaryFile/PptFile/Records/ExOleEmbedAtom.h b/MsBinaryFile/PptFile/Records/ExOleEmbedAtom.h index 683e56c5905..ec5d5bcea8a 100644 --- a/MsBinaryFile/PptFile/Records/ExOleEmbedAtom.h +++ b/MsBinaryFile/PptFile/Records/ExOleEmbedAtom.h @@ -41,8 +41,12 @@ class CRecordExOleEmbedAtom : public CUnknownRecord BOOL1 m_nCantLockServer; BOOL1 m_nNoSizeToServer; BOOL1 m_nIsTable; - - virtual void ReadFromStream(SRecordHeader & oHeader, POLE::Stream* pStream) override; }; + +class CRecordExOleEmbedContainer : public CRecordsContainer +{ +public: + virtual void ReadFromStream(SRecordHeader& oHeader, POLE::Stream* pStream) override; +}; } diff --git a/MsBinaryFile/PptFile/Records/VBAInfoAtom.cpp b/MsBinaryFile/PptFile/Records/VBAInfoAtom.cpp index 28139b6b77c..31f73d3b401 100644 --- a/MsBinaryFile/PptFile/Records/VBAInfoAtom.cpp +++ b/MsBinaryFile/PptFile/Records/VBAInfoAtom.cpp @@ -61,53 +61,3 @@ void CRecordVBAInfoContainer::ReadFromStream(SRecordHeader &oHeader, POLE::Strea m_oHeader = oHeader; CRecordsContainer::ReadFromStream(oHeader, pStream); } - -CRecordVbaProjectStg::CRecordVbaProjectStg(std::wstring strTemp) : m_strTmpDirectory(strTemp) -{ -} - -CRecordVbaProjectStg::~CRecordVbaProjectStg() -{ -} - -void CRecordVbaProjectStg::ReadFromStream(SRecordHeader &oHeader, POLE::Stream *pStream) -{ - m_oHeader = oHeader; - - ULONG decompressedSize = m_oHeader.RecLen, compressedSize = m_oHeader.RecLen; - - BYTE* pData = new BYTE[compressedSize]; - if (!pData) return; - - if (m_oHeader.RecInstance == 0x01) - { - decompressedSize = StreamUtils::ReadDWORD(pStream) + 64; - compressedSize -= 4; - } - pStream->read(pData, compressedSize); - - //if (pDecryptor) - //{ - // pDecryptor->Decrypt((char*)pData, compressedSize, 0); - //} - - if (m_oHeader.RecInstance == 0x01) - { - BYTE* pDataUncompress = new BYTE[decompressedSize]; - NSZip::Decompress(pData, compressedSize, pDataUncompress, decompressedSize); - - delete []pData; - pData = pDataUncompress; - } - - m_sFileName = m_strTmpDirectory + FILE_SEPARATOR_STR + L"vbaProject.bin"; - - NSFile::CFileBinary file; - if (file.CreateFileW(m_sFileName)) - { - file.WriteFile(pData, decompressedSize); - file.CloseFile(); - } - delete[] pData; - pData = NULL; -} diff --git a/MsBinaryFile/PptFile/Records/VBAInfoAtom.h b/MsBinaryFile/PptFile/Records/VBAInfoAtom.h index 68c477b2d87..b71d2dea601 100644 --- a/MsBinaryFile/PptFile/Records/VBAInfoAtom.h +++ b/MsBinaryFile/PptFile/Records/VBAInfoAtom.h @@ -57,16 +57,4 @@ class CRecordVBAInfoContainer : public CRecordsContainer virtual void ReadFromStream(SRecordHeader & oHeader, POLE::Stream* pStream); }; -class CRecordVbaProjectStg : public CUnknownRecord -{ -public: - std::wstring m_sFileName; - std::wstring m_strTmpDirectory; - - - CRecordVbaProjectStg(std::wstring strTemp); - ~CRecordVbaProjectStg(); - - virtual void ReadFromStream(SRecordHeader & oHeader, POLE::Stream* pStream) override; -}; } diff --git a/MsBinaryFile/Projects/DocFormatLib/Linux/DocFormatLib.pro b/MsBinaryFile/Projects/DocFormatLib/Linux/DocFormatLib.pro index 1ec2f9ca834..e0b2b884cb3 100644 --- a/MsBinaryFile/Projects/DocFormatLib/Linux/DocFormatLib.pro +++ b/MsBinaryFile/Projects/DocFormatLib/Linux/DocFormatLib.pro @@ -31,8 +31,9 @@ SOURCES += \ ../../../DocFile/EncryptionHeader.cpp \ ../../../DocFile/DrawingPrimitives.cpp \ ../../../DocFile/Spa.cpp \ - ../../../DocFile/OleObject.cpp \ - ../../../Common/Base/XmlTools.cpp + ../../../DocFile/OleObject.cpp \ + ../../../Common/Base/FormatUtils.cpp \ + ../../../Common/Base/XmlTools.cpp core_release { SOURCES += \ diff --git a/MsBinaryFile/Projects/DocFormatLib/Windows/DocFormatLib.vcxproj b/MsBinaryFile/Projects/DocFormatLib/Windows/DocFormatLib.vcxproj index 7ecd663c84a..1d3bed4ce5d 100644 --- a/MsBinaryFile/Projects/DocFormatLib/Windows/DocFormatLib.vcxproj +++ b/MsBinaryFile/Projects/DocFormatLib/Windows/DocFormatLib.vcxproj @@ -141,6 +141,7 @@ + @@ -308,6 +309,7 @@ + diff --git a/MsBinaryFile/Projects/DocFormatLib/Windows/DocFormatLib.vcxproj.filters b/MsBinaryFile/Projects/DocFormatLib/Windows/DocFormatLib.vcxproj.filters index a3f79cb0fd9..5e1465669ce 100644 --- a/MsBinaryFile/Projects/DocFormatLib/Windows/DocFormatLib.vcxproj.filters +++ b/MsBinaryFile/Projects/DocFormatLib/Windows/DocFormatLib.vcxproj.filters @@ -505,6 +505,7 @@ Converter + @@ -870,5 +871,6 @@ OfficeDrawing + \ No newline at end of file diff --git a/MsBinaryFile/Projects/XlsFormatLib/Windows/XlsFormat.vcxproj b/MsBinaryFile/Projects/XlsFormatLib/Windows/XlsFormat.vcxproj index 0f248841880..48d1e40588a 100644 --- a/MsBinaryFile/Projects/XlsFormatLib/Windows/XlsFormat.vcxproj +++ b/MsBinaryFile/Projects/XlsFormatLib/Windows/XlsFormat.vcxproj @@ -501,6 +501,7 @@ + @@ -1315,6 +1316,7 @@ + diff --git a/MsBinaryFile/Projects/XlsFormatLib/Windows/XlsFormat.vcxproj.filters b/MsBinaryFile/Projects/XlsFormatLib/Windows/XlsFormat.vcxproj.filters index 94eeff77a5c..ef84b54866c 100644 --- a/MsBinaryFile/Projects/XlsFormatLib/Windows/XlsFormat.vcxproj.filters +++ b/MsBinaryFile/Projects/XlsFormatLib/Windows/XlsFormat.vcxproj.filters @@ -2440,6 +2440,9 @@ Logic\Biff_structures\BIFF12 + + Logic\Biff_structures + @@ -4893,5 +4896,8 @@ Logic\Biff_structures\BIFF12 + + Logic\Biff_structures + \ No newline at end of file diff --git a/MsBinaryFile/XlsFile/Converter/XlsConverter.cpp b/MsBinaryFile/XlsFile/Converter/XlsConverter.cpp index 99ac3447698..9a28d8681c4 100644 --- a/MsBinaryFile/XlsFile/Converter/XlsConverter.cpp +++ b/MsBinaryFile/XlsFile/Converter/XlsConverter.cpp @@ -138,6 +138,7 @@ XlsConverter::XlsConverter() is_older_version = false; is_encrypted = false; } + XlsConverter::XlsConverter(const std::wstring & xlsFileName, const std::wstring & xlsxFilePath, const std::wstring & password, const std::wstring & fontsPath, const std::wstring & tempPath, const int lcid_user, bool & bMacros) { xlsx_path = xlsxFilePath; @@ -188,7 +189,7 @@ XlsConverter::XlsConverter(const std::wstring & xlsFileName, const std::wstring if (globals) { globals->m_Formating = worksheet->m_Formating; - globals->UpdateXFC(); + globals->UpdateXFC(); } } } @@ -224,8 +225,38 @@ XlsConverter::XlsConverter(const std::wstring & xlsFileName, const std::wstring XLS::StreamCacheReaderPtr workbook_stream(new XLS::CFStreamCacheReader(xls_file->getWorkbookStream(), xls_global_info)); xls_document = boost::shared_ptr(new XLS::WorkbookStreamObject(workbook_code_page)); - XLS::BinReaderProcessor proc(workbook_stream, xls_document.get() , true); - proc.mandatory(*xls_document.get()); + XLS::BinReaderProcessor workbook_proc(workbook_stream, xls_document.get() , true); + if (false == workbook_proc.mandatory(*xls_document.get())) + { + // test open list + xls_file->getWorkbookStream()->seekFromBegin(0); + XLS::StreamCacheReaderPtr worksheet_stream(new XLS::CFStreamCacheReader(xls_file->getWorkbookStream(), xls_global_info)); + + XLS::BaseObjectPtr worksheet_object = XLS::BaseObjectPtr(new XLS::WorksheetSubstream(0)); + XLS::BinReaderProcessor worksheet_proc(worksheet_stream, xls_document.get(), true); + if (worksheet_proc.mandatory(*worksheet_object.get())) + { + XLS::WorksheetSubstream* worksheet = dynamic_cast(worksheet_object.get()); + XLS::WorkbookStreamObject* workbook = dynamic_cast(xls_document.get()); + if (workbook) + { + workbook->m_arWorksheetSubstream.push_back(worksheet_object); + + workbook->m_GlobalsSubstream = XLS::BaseObjectPtr(new XLS::GlobalsSubstream(0)); + + XLS::GlobalsSubstream* globals = dynamic_cast(workbook->m_GlobalsSubstream.get()); + if (globals) + { + globals->m_Formating = worksheet->m_Formating; + globals->UpdateXFC(); + } + } + } + else + { + return; //error + } + } if (xls_global_info->decryptor) { @@ -608,7 +639,8 @@ void XlsConverter::convert_common (XLS::CommonSubstream* sheet) void XlsConverter::convert (XLS::WorksheetSubstream* sheet) { if (sheet == NULL) return; - + if (xls_global_info->sheets_info.empty()) return; + std::wstring name = xls_global_info->sheets_info[sheet->ws_index_].name; if (name.empty()) name = L"Sheet_" + std::to_wstring(sheet->ws_index_ + 1); @@ -761,7 +793,7 @@ void XlsConverter::convert(XLS::GlobalsSubstream* globals) for (size_t i = 0 ; i < globals->m_arHFPictureDrawing.size(); i++) { - convert((ODRAW::OfficeArtDgContainer*)globals->m_arHFPictureDrawing[i].get()); + convert((ODRAW::OfficeArtDggContainer*)globals->m_arHFPictureDrawing[i].get()); } globals->serialize_protection(xlsx_context->workbook_protection()); @@ -833,10 +865,10 @@ void XlsConverter::convert(XLS::FORMATTING* formating) CP_XML_NODE(L"numFmts") { - CP_XML_ATTR(L"count", xls_global_info->m_arNumFormats.size()); - for (size_t i = 0; i < xls_global_info->m_arNumFormats.size(); i++) + CP_XML_ATTR(L"count", xls_global_info->m_mapNumFormats.size()); + for (std::map<_UINT16, XLS::BaseObjectPtr>::iterator it = xls_global_info->m_mapNumFormats.begin(); it != xls_global_info->m_mapNumFormats.end(); ++it) { - XLS::Format* fmt = dynamic_cast(xls_global_info->m_arNumFormats[i].get()); + XLS::Format* fmt = dynamic_cast(it->second.get()); if (fmt->ifmt < 5 || (fmt->ifmt > 8 && fmt->ifmt < 23) || (fmt->ifmt > 36 && fmt->ifmt < 41) || (fmt->ifmt > 44 && fmt->ifmt < 50)) continue; @@ -1047,6 +1079,24 @@ std::wstring XlsConverter::WriteMediaFile(char *data, int size, std::wstring typ } } } + else if (type_ext == L"pict") + { + //NSFile::CFileBinary file; + //std::wstring tempPICT = file.CreateTempFileWithUniqueName(xls_global_info->tempDirectory, L"pct"); + //if (file.CreateFileW(tempPICT)) + //{ + // file.WriteFile((BYTE*)data, size); + // file.CloseFile(); + //} + CBgraFrame bgraFrame; + + if (bgraFrame.Decode((BYTE*)data, size)) + { + file_name += L".png"; + bgraFrame.SaveFile(xlsx_context->get_mediaitems().media_path() + file_name, 4); // png + } + //NSFile::CFileBinary::Remove(tempPICT); + } else { file_name += type_ext; @@ -1144,7 +1194,7 @@ void XlsConverter::convert(XLS::IMDATA * imdata) if (imdata->cf == 0x09 && imdata->env == 0x01) type_image = L".wmf"; if ((imdata->cf == 0x09 || imdata->cf == 0x02) - && imdata->env == 0x02) type_image = L".pict"; + && imdata->env == 0x02) type_image = L"pict"; if (imdata->cf == 0x09) type_image = L"dib_data"; if (imdata->cf == 0x0e) type_image = L""; //native aka unknown @@ -1410,14 +1460,21 @@ void XlsConverter::convert(ODRAW::OfficeArtSpgrContainer * spgr) for (size_t i = 0; i < spgr->child_records.size(); i++) { - int type_object = 2;//rect - - if (xlsx_context->get_drawing_context().start_drawing(type_object)) + ODRAW::OfficeArtSpContainer* SpContainer = dynamic_cast(spgr->child_records[i].get()); + if (SpContainer) { - xlsx_context->get_drawing_context().set_mode_HF(true); - convert(spgr->child_records[i].get()); + ODRAW::OfficeArtFSP* fsp = dynamic_cast(SpContainer->m_OfficeArtFSP.get()); + if ((fsp) && (fsp->fHaveSpt)) + { + int type_object = 2;//rect + if (xlsx_context->get_drawing_context().start_drawing(type_object)) + { + xlsx_context->get_drawing_context().set_mode_HF(true); + convert(spgr->child_records[i].get()); - xlsx_context->get_drawing_context().end_drawing(); + xlsx_context->get_drawing_context().end_drawing(); + } + } } } } @@ -1516,6 +1573,12 @@ void XlsConverter::convert(ODRAW::OfficeArtRecord * art) convert(dg->m_OfficeArtSpgrContainer.get()); }break; + case XLS::typeOfficeArtDggContainer: + { + ODRAW::OfficeArtDggContainer* dg = dynamic_cast(art); + + convert(dg->m_OfficeArtBStoreContainer.get()); + }break; default: break; } diff --git a/MsBinaryFile/XlsFile/Converter/xlsx_drawing_context.cpp b/MsBinaryFile/XlsFile/Converter/xlsx_drawing_context.cpp index df591751dfd..c22f4b5b851 100644 --- a/MsBinaryFile/XlsFile/Converter/xlsx_drawing_context.cpp +++ b/MsBinaryFile/XlsFile/Converter/xlsx_drawing_context.cpp @@ -81,13 +81,7 @@ namespace oox { 0x00666666, 0x00C0C0C0, 0x00DDDDDD, 0x00C0C0C0, 0x00888888, 0x00FFFFFF, 0x00CCCCCC, 0x00000000 }; - void _color::SetRGB(unsigned char nR, unsigned char nG, unsigned char nB) - { - nRGB = (nR<<16) | (nG<<8) | nB; - sRGB = STR::toRGB(nR, nG, nB); - index = -1; - } //----------------------------------------------------------------------------------------------------- class xlsx_drawing_context_handle::Impl { @@ -879,32 +873,42 @@ void xlsx_drawing_context::end_drawing(_drawing_state_ptr & drawing_state) current_drawing_states->back()->child_anchor.cy = bottom - top; } - if ( drawing_state->type == external_items::typeImage || - ( drawing_state->type == external_items::typeShape && drawing_state->shape_id == msosptPictureFrame )) + if ( drawing_state->type == external_items::typeImage || drawing_state->type == external_items::typeShape ) { - drawing_state->type = external_items::typeImage; + if (drawing_state->shape_id == msosptPictureFrame) + { + drawing_state->type = external_items::typeImage; + } if (!drawing_state->fill.picture_target.empty()) drawing_state->fill.texture_target = drawing_state->fill.picture_target; + bool isIternal = false; if (!drawing_state->fill.texture_target.empty()) { - bool isIternal = false; - drawing_state->objectId = handle_.impl_->get_mediaitems().find_image( drawing_state->fill.texture_target, isIternal); - + drawing_state->objectId = handle_.impl_->get_mediaitems().find_image(drawing_state->fill.texture_target, isIternal); + } + + if (drawing_state->type == external_items::typeImage) + { serialize_pic(drawing_state); + } + else + { + serialize_shape(drawing_state); + } + if (!drawing_state->fill.texture_target.empty()) + { if (drawing_state->vml_HF_mode_) { - vml_HF_rels_->add(isIternal, drawing_state->objectId , drawing_state->fill.texture_target, drawing_state->type); + vml_HF_rels_->add(isIternal, drawing_state->objectId, drawing_state->fill.texture_target, drawing_state->type); } else { - rels_->add(isIternal, drawing_state->objectId , drawing_state->fill.texture_target, drawing_state->type); + rels_->add(isIternal, drawing_state->objectId, drawing_state->fill.texture_target, drawing_state->type); } } - else - drawing_state->type = external_items::typeShape; } if ( drawing_state->type == external_items::typeChart ) { @@ -926,10 +930,10 @@ void xlsx_drawing_context::end_drawing(_drawing_state_ptr & drawing_state) context_.get_comments_context().end_comment(); } - if ( drawing_state->type == external_items::typeShape) - { - serialize_shape(drawing_state); - } + //if ( drawing_state->type == external_items::typeShape) + //{ + // serialize_shape(drawing_state); + //} if ( drawing_state->type == external_items::typeOleObject ) { serialize_shape(drawing_state); @@ -987,7 +991,7 @@ void xlsx_drawing_context::serialize_group() if (!drawing_state->description.empty()) { - CP_XML_ATTR(L"descr", drawing_state->description); + CP_XML_ATTR(L"descr", XmlUtils::EncodeXmlString(drawing_state->description)); } if (drawing_state->hidden) { @@ -1111,9 +1115,9 @@ void xlsx_drawing_context::serialize_vml_shape(_drawing_state_ptr & drawing_stat CP_XML_NODE(L"v:fill") { CP_XML_ATTR(L"color", std::wstring(L"#") + drawing_state->fill.color.sRGB); - if (drawing_state->fill.opacity > 0.00001) + if (drawing_state->fill.color.opacity > 0.00001) { - CP_XML_ATTR(L"opacity", drawing_state->fill.opacity * 65536); + CP_XML_ATTR(L"opacity", drawing_state->fill.color.opacity * 65536); } bool isIternal = false; std::wstring rId = handle_.impl_->get_mediaitems().find_image( drawing_state->fill.texture_target, isIternal); @@ -1134,9 +1138,9 @@ void xlsx_drawing_context::serialize_vml_shape(_drawing_state_ptr & drawing_stat else if (drawing_state->fill.type == fillGradient || drawing_state->fill.type == fillGradientOne) { CP_XML_ATTR(L"color2", std::wstring(L"#") + drawing_state->fill.color2.sRGB); - if (drawing_state->fill.opacity2 > 0.00001) + if (drawing_state->fill.color2.opacity > 0.00001) { - CP_XML_ATTR(L"opacity2", drawing_state->fill.opacity2 * 65536); + CP_XML_ATTR(L"opacity2", drawing_state->fill.color2.opacity * 65536); } CP_XML_ATTR(L"type", L"gradient"); } @@ -1358,12 +1362,12 @@ void xlsx_drawing_context::serialize_pic(_drawing_state_ptr & drawing_state) { CP_XML_ATTR(L"id", drawing_state->id); if (drawing_state->name.empty()) - drawing_state->name = L"Picture_" + drawing_state->objectId.substr(5); + drawing_state->name = L"Picture_" + (drawing_state->objectId.size() > 5 ? drawing_state->objectId.substr(5) : std::to_wstring(drawing_state->id)); CP_XML_ATTR(L"name", drawing_state->name); if (!drawing_state->description.empty()) { - CP_XML_ATTR(L"descr", drawing_state->description); + CP_XML_ATTR(L"descr", XmlUtils::EncodeXmlString(drawing_state->description)); } if (drawing_state->hidden) { @@ -1438,7 +1442,7 @@ void xlsx_drawing_context::serialize_chart(_drawing_state_ptr & drawing_state) CP_XML_ATTR(L"name", drawing_state->name); if (!drawing_state->description.empty()) { - CP_XML_ATTR(L"descr", drawing_state->description); + CP_XML_ATTR(L"descr", XmlUtils::EncodeXmlString(drawing_state->description)); } if (drawing_state->hidden) { @@ -1490,7 +1494,7 @@ void xlsx_drawing_context::serialize_control(_drawing_state_ptr & drawing_state) if (!drawing_state->description.empty()) { - CP_XML_ATTR(L"descr", drawing_state->description); + CP_XML_ATTR(L"descr", XmlUtils::EncodeXmlString(drawing_state->description)); } CP_XML_ATTR(L"hidden", 1); @@ -1591,7 +1595,7 @@ void xlsx_drawing_context::serialize_shape(_drawing_state_ptr & drawing_state) if (!drawing_state->description.empty()) { - CP_XML_ATTR(L"descr", drawing_state->description); + CP_XML_ATTR(L"descr", XmlUtils::EncodeXmlString(drawing_state->description)); } if (drawing_state->hidden) { @@ -1686,7 +1690,8 @@ void xlsx_drawing_context::serialize_shape(_drawing_state_ptr & drawing_state) } if (!is_lined_shape(drawing_state)) { - if (false == drawing_state->xmlFillAlternative.empty()) //Family budget (monthly)1.xls + if (false == drawing_state->xmlFillAlternative.empty() && + std::wstring::npos == drawing_state->xmlFillAlternative.find(L"r:emb")) //Family budget (monthly)1.xls { CP_XML_STREAM() << drawing_state->xmlFillAlternative; } @@ -1972,7 +1977,7 @@ void xlsx_drawing_context::serialize_fill(std::wostream & stream, _drawing_state //------------ if (fill.color.index >= 0 || !fill.color.sRGB.empty()) { - serialize_solid_fill(stream, fill.color, fill.opacity); + serialize_solid_fill(stream, fill.color, fill.color.opacity); } else serialize_none_fill(stream); } @@ -2062,7 +2067,7 @@ void xlsx_drawing_context::serialize_gradient_fill(std::wostream & stream, _draw CP_XML_NODE(L"a:gs") { CP_XML_ATTR(L"pos", (int)(fill.colorsPosition[i].first * 100000)); - serialize_color(CP_XML_STREAM(), fill.colorsPosition[i].second); + serialize_color(CP_XML_STREAM(), fill.colorsPosition[i].second, fill.colorsPosition[i].second.opacity); //проверить что если тут индексы то они берутся с программных а не с юзерских (см как ниже) } } @@ -2073,13 +2078,13 @@ void xlsx_drawing_context::serialize_gradient_fill(std::wostream & stream, _draw { fill.color.bScheme = false; // по общим индексам CP_XML_ATTR(L"pos", 0); - serialize_color(CP_XML_STREAM(), fill.color, fill.opacity); + serialize_color(CP_XML_STREAM(), fill.color, fill.color.opacity); } CP_XML_NODE(L"a:gs") { fill.color2.bScheme = false; // по общим индексам CP_XML_ATTR(L"pos", 100000); - serialize_color(CP_XML_STREAM(), fill.color2, fill.opacity2); + serialize_color(CP_XML_STREAM(), fill.color2, fill.color2.opacity); } } } @@ -2948,7 +2953,7 @@ void xlsx_drawing_context::set_picture_crop_right (double val) } void xlsx_drawing_context::set_picture_name(const std::wstring & str) { - //.... + current_drawing_states->back()->fill.name = str; } void xlsx_drawing_context::set_picture_grayscale(bool val) { @@ -3143,8 +3148,8 @@ void xlsx_drawing_context::set_fill_opacity (double val, bool background) if (current_drawing_states == NULL) return; if (current_drawing_states->empty()) return; - if (background) current_drawing_states->back()->fill.opacity2 = val; - else current_drawing_states->back()->fill.opacity = val; + if (background) current_drawing_states->back()->fill.color2.opacity = val; + else current_drawing_states->back()->fill.color.opacity = val; } void xlsx_drawing_context::add_fill_colors(double position, const std::wstring & col) { diff --git a/MsBinaryFile/XlsFile/Converter/xlsx_drawing_context.h b/MsBinaryFile/XlsFile/Converter/xlsx_drawing_context.h index 02bdc132d81..71799029986 100644 --- a/MsBinaryFile/XlsFile/Converter/xlsx_drawing_context.h +++ b/MsBinaryFile/XlsFile/Converter/xlsx_drawing_context.h @@ -94,12 +94,19 @@ struct _color int index = -1; bool bScheme = false; - void SetRGB(unsigned char nR, unsigned char nG, unsigned char nB); + void SetRGB(unsigned char nR, unsigned char nG, unsigned char nB) + { + nRGB = (nR << 16) | (nG << 8) | nB; + sRGB = STR::toRGB(nR, nG, nB); + + index = -1; + } unsigned char GetB() { return (unsigned char )(nRGB);} unsigned char GetG() { return (unsigned char )(nRGB>>8);} unsigned char GetR() { return (unsigned char )(nRGB>>16);} + double opacity = 0; }; struct _rect @@ -272,8 +279,6 @@ class _drawing_state } _color color; _color color2; - double opacity = 0; - double opacity2 = 0; _fill_type type = fillSolid; int focus = 0; @@ -290,6 +295,8 @@ class _drawing_state _CP_OPT(bool) grayscale; _CP_OPT(int) biLevel; + std::wstring name; + std::vector> colorsPosition; }fill; @@ -297,7 +304,8 @@ class _drawing_state { fill.type = fillSolid; fill.color.SetRGB(0xff, 0xff, 0xff); - fill.angle = fill.opacity = fill.opacity2 = fill.focus = 0; + fill.color.opacity = 0; + fill.angle = fill.focus = 0; memset(fill.texture_crop, 0, 4 * sizeof(double)); fill.texture_crop_enabled = false; fill.colorsPosition.clear(); diff --git a/MsBinaryFile/XlsFile/Converter/xlsx_sheet_context.cpp b/MsBinaryFile/XlsFile/Converter/xlsx_sheet_context.cpp index b461090d29b..03d15ac70ca 100644 --- a/MsBinaryFile/XlsFile/Converter/xlsx_sheet_context.cpp +++ b/MsBinaryFile/XlsFile/Converter/xlsx_sheet_context.cpp @@ -47,7 +47,14 @@ table_state::table_state(xlsx_conversion_context & Context) : drawing_context_(C table_state_ptr & xlsx_sheet_context::state() { - return tables_state_.back(); + if (false == tables_state_.empty()) + { + return tables_state_.back(); + } + else + { + throw; + } } xlsx_sheet_context::xlsx_sheet_context(xlsx_conversion_context & Context) : context_(Context) @@ -114,38 +121,57 @@ void xlsx_sheet_context::end_table() xlsx_drawing_context & xlsx_sheet_context::get_drawing_context() { - return state()->drawing_context_; + if (state()) + return state()->drawing_context_; + else + { + throw; + } } xlsx_comments_context & xlsx_sheet_context::get_comments_context() { - return state()->comments_context_; + if (state()) + return state()->comments_context_; + else + { + throw; + } } std::wstring xlsx_sheet_context::add_hyperlink(std::wstring const & ref, std::wstring const & target, std::wstring const & display, bool bExternal) { - return state()->hyperlinks_.add( ref, target, display, bExternal); + if (state()) + return state()->hyperlinks_.add(ref, target, display, bExternal); + else return L""; } void xlsx_sheet_context::dump_rels_hyperlinks(rels & Rels) { - state()->hyperlinks_.dump_rels(Rels); + if (state()) + state()->hyperlinks_.dump_rels(Rels); } void xlsx_sheet_context::serialize_hyperlinks(std::wostream & _Wostream) { - state()->hyperlinks_.serialize(_Wostream); + if (state()) + state()->hyperlinks_.serialize(_Wostream); } void xlsx_sheet_context::dump_rels_drawing(rels & Rels) { - xlsx_drawings_rels_ptr drawing_rels = state()->drawing_context_.get_sheet_rels(); - - drawing_rels->dump_rels(Rels); + if (state()) + { + xlsx_drawings_rels_ptr drawing_rels = state()->drawing_context_.get_sheet_rels(); + + drawing_rels->dump_rels(Rels); + } } void xlsx_sheet_context::serialize_ole_objects(std::wostream & strm) { - state()->drawing_context_.serialize_objects(strm); + if (state()) + state()->drawing_context_.serialize_objects(strm); } void xlsx_sheet_context::serialize_controls(std::wostream & strm) { - state()->drawing_context_.serialize_controls(strm); + if (state()) + state()->drawing_context_.serialize_controls(strm); } } diff --git a/MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.cpp b/MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.cpp index 88bfd184ea7..379449bd1a2 100644 --- a/MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.cpp +++ b/MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.cpp @@ -48,31 +48,34 @@ namespace AUX { -const int normalizeColumn(const int column) +const int normalizeColumn(const int column, const bool xlsb) { - if ((column & 0x00004000) == 0x00004000) - { - return 0x00004000 - 1; - } - else - { - int norm_col = column; - while (norm_col > 16383) - { - norm_col -= 16384; - } - while (norm_col < 0) - { - norm_col += 16384; // It is correct. must be on the second place after 16383 - } - return norm_col; - } + int maxCol = 0; + if(xlsb) + { + maxCol = 16383; + } + else + { + maxCol = 255; + } + int norm_col = column; + while (norm_col > maxCol) + { + norm_col -= (maxCol+1); + } + while (norm_col < 0) + { + norm_col += (maxCol+1); // It is correct. must be on the second place after maxCol(16383 or 255) + } + return norm_col; + } -const std::wstring column2str(const int column, const bool col_rel) +const std::wstring column2str(const int column, const bool col_rel, const bool xlsb) { - int column_value = normalizeColumn(column); + int column_value = normalizeColumn(column, xlsb); const int radix = L'Z' - L'A' + 1; std::wstring ret_val; ++column_value; @@ -87,31 +90,40 @@ const std::wstring column2str(const int column, const bool col_rel) } -const int normalizeRow(const int row) +const int normalizeRow(const int row, const bool xlsb) { + int maxRow = 0; + if(xlsb) + { + maxRow = 1048576; + } + else + { + maxRow = 65536; + } int norm_row = row; - while(norm_row > 1048576) + while(norm_row >= maxRow) { - norm_row -= 0x100000; + norm_row -= maxRow; } while(norm_row < 0) { - norm_row += 0x100000; // It is correct. must be on the second place after 1048576 + norm_row += maxRow; // It is correct. must be on the second place after 1048576 } return norm_row; } -const std::wstring row2str(const int row, const bool row_rel) +const std::wstring row2str(const int row, const bool row_rel, const bool xlsb) { - int row_value = normalizeRow(row); + int row_value = normalizeRow(row, xlsb); return (row_rel ? L"" : L"$") + STR::int2wstr(row_value + 1, 10); } -const std::wstring loc2str(const int row, const bool row_rel, const int column, const bool col_rel) +const std::wstring loc2str(const int row, const bool row_rel, const int column, const bool col_rel, const bool xlsb) { - return column2str(column, col_rel) + row2str(row, row_rel); + return column2str(column, col_rel, xlsb) + row2str(row, row_rel, xlsb); } @@ -130,9 +142,9 @@ const int str2column(std::wstring::const_iterator& str_begin, std::wstring::cons column = (column + 1) * radix + (symb - L'A'); } - if(column > 255) + if(column > 16383) { - column = 255; + column = 16383; } return column; @@ -152,9 +164,9 @@ const int str2row(std::wstring::const_iterator& str_begin, std::wstring::const_i row = row * 10 + (symb - L'0'); } --row; - if(row > 65535) + if(row > 1048575) { - row = 65535; + row = 1048575; } return row; } @@ -692,6 +704,34 @@ unsigned short sheetsnames2ixti(std::wstring name) return 0xFFFF; } + unsigned short AddMultysheetXti(const std::wstring& name, const _INT32& firstIxti, const _INT32& secondIxti) + { + auto pos1 = std::find_if(XLS::GlobalWorkbookInfo::arXti_External_static.cbegin(), XLS::GlobalWorkbookInfo::arXti_External_static.cend(), + [&](XLS::GlobalWorkbookInfo::_xti i) { + return i.iSup == firstIxti; + }); + + auto pos2 = std::find_if(XLS::GlobalWorkbookInfo::arXti_External_static.cbegin(), XLS::GlobalWorkbookInfo::arXti_External_static.cend(), + [&](XLS::GlobalWorkbookInfo::_xti i) { + return i.iSup == secondIxti; + }); + if (pos1 == XLS::GlobalWorkbookInfo::arXti_External_static.cend() || pos2 == XLS::GlobalWorkbookInfo::arXti_External_static.cend()) + return 0; + XLS::GlobalWorkbookInfo::_xti newXti; + newXti.iSup = XLS::GlobalWorkbookInfo::arXti_External_static.size(); + newXti.itabFirst = pos1->itabFirst; + newXti.itabLast = pos2->itabFirst; + newXti.link = name; + XLS::GlobalWorkbookInfo::arXti_External_static.push_back(newXti); + return newXti.iSup; + } + + unsigned int AddDefinedName(const std::wstring& name) + { + XLS::GlobalWorkbookInfo::arDefineNames_static.push_back(name); + return (XLS::GlobalWorkbookInfo::arDefineNames_static.size()); + } + unsigned int definenames2index(std::wstring name) { unsigned int index; @@ -725,10 +765,13 @@ bool isColumn(const std::wstring& columnName, _UINT32 listIndex, _UINT16& indexC if(arrColumn != XLS::GlobalWorkbookInfo::mapTableColumnNames_static.end()) { indexColumn = -1; + auto unqotedName = columnName; + if(!unqotedName.empty() && unqotedName.at(0) == '\'') + unqotedName = unqotedName.substr(1, unqotedName.size() - 1); for (const auto& itemColumn : arrColumn->second) { ++indexColumn; - if (columnName == itemColumn) + if (unqotedName == itemColumn) { return true; } @@ -736,6 +779,20 @@ bool isColumn(const std::wstring& columnName, _UINT32 listIndex, _UINT16& indexC } return false; } - +unsigned int getColumnsCount(_UINT32 listIndex) +{ + auto arrColumn = XLS::GlobalWorkbookInfo::mapTableColumnNames_static.find(listIndex); + if(arrColumn != XLS::GlobalWorkbookInfo::mapTableColumnNames_static.end()) + { + auto counter = 0; + for(auto i:arrColumn->second) + { + if(!i.empty()) + counter++; + } + return counter; + } + return 0; +} } //namespace XMLSTUFF diff --git a/MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.h b/MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.h index e1d902b868f..bf9abf6a922 100644 --- a/MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.h +++ b/MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.h @@ -42,12 +42,12 @@ namespace XLS namespace AUX { - const int normalizeColumn (const int column); - const int normalizeRow (const int row); + const int normalizeColumn (const int column, const bool xlsb = false); + const int normalizeRow (const int row, const bool xlsb = false); - const std::wstring column2str (const int column, const bool col_rel); - const std::wstring row2str (const int row, const bool row_rel); - const std::wstring loc2str (const int row, const bool row_rel, const int column, const bool col_rel); + const std::wstring column2str (const int column, const bool col_rel, const bool xlsb = false); + const std::wstring row2str (const int row, const bool row_rel, const bool xlsb = false); + const std::wstring loc2str (const int row, const bool row_rel, const int column, const bool col_rel, const bool xlsb = false); void str2loc (const std::wstring& str, int& row, bool& row_rel, int& column, bool& col_rel); void str2loc (std::wstring::const_iterator& str_begin, std::wstring::const_iterator& str_end, int& row, bool& row_rel, int& column, bool& col_rel); @@ -95,5 +95,8 @@ unsigned short sheetsnames2ixti(std::wstring name); unsigned int definenames2index(std::wstring name); bool isTableFmla(const std::wstring& tableName, _UINT32& listIndex); bool isColumn(const std::wstring& columnName, _UINT32 listIndex, _UINT16& indexColumn); +unsigned int getColumnsCount(_UINT32 listIndex); +unsigned short AddMultysheetXti(const std::wstring& name, const _INT32& firstIxti, const _INT32& secondIxti); +unsigned int AddDefinedName(const std::wstring& name); } diff --git a/MsBinaryFile/XlsFile/Format/Binary/CFRecord.cpp b/MsBinaryFile/XlsFile/Format/Binary/CFRecord.cpp index c78373892d5..2015a5dd947 100644 --- a/MsBinaryFile/XlsFile/Format/Binary/CFRecord.cpp +++ b/MsBinaryFile/XlsFile/Format/Binary/CFRecord.cpp @@ -37,7 +37,7 @@ namespace XLS { -char CFRecord::intData[MAX_RECORD_SIZE]; +char CFRecord::intData[MAX_RECORD_SIZE_XLSB]; // Create a record and read its data from the stream CFRecord::CFRecord(CFStreamPtr stream, GlobalWorkbookInfoPtr global_info) @@ -90,11 +90,12 @@ CFRecord::CFRecord(NSFile::CFileBinary &file, GlobalWorkbookInfoPtr global_info) : rdPtr(0), size_(0), data_(NULL), + type_id_(rt_EOF), global_info_(global_info) { file_ptr = file.GetFilePosition(); - if (file.GetFilePosition() + 4 < file.GetFileSize()) + if (file.GetFilePosition() + 4 <= file.GetFileSize()) { unsigned short size_short; DWORD size_read = 0; @@ -133,7 +134,8 @@ CFRecord::CFRecord(NSBinPptxRW::CBinaryFileReader &reader, GlobalWorkbookInfoPtr : rdPtr(0), size_(0), data_(NULL), - global_info_(global_info) + type_id_(rt_EOF), + global_info_(global_info) { file_ptr = reinterpret_cast(reader.GetPointer(0)) ; BYTE lenght = 0; @@ -260,6 +262,10 @@ const BYTE CFRecord::getSizeOfRecordTypeRecordLength() const const size_t CFRecord::getMaxRecordSize() const { + if(global_info_ && (global_info_.get()->Version == 0x0800)) + { + return MAX_RECORD_SIZE_XLSB; + } return MAX_RECORD_SIZE; } @@ -300,6 +306,11 @@ void CFRecord::appendRawDataToStatic(const unsigned char *raw_data, const size_t memcpy(&intData[rdPtr], raw_data, size); rdPtr += size; } + else if(global_info_ && (global_info_.get()->Version == 0x0800) && (MAX_RECORD_SIZE_XLSB - rdPtr > size)) + { + memcpy(&intData[rdPtr], raw_data, size); + rdPtr += size; + } } void CFRecord::appendRawDataToStatic(const wchar_t *raw_data, const size_t size) @@ -309,6 +320,11 @@ void CFRecord::appendRawDataToStatic(const wchar_t *raw_data, const size_t size) for(int i = 0; i < size; ++i) storeAnyData(raw_data[i]); } + else if(global_info_ && (global_info_.get()->Version == 0x0800) && (MAX_RECORD_SIZE_XLSB - rdPtr > size)) + { + for(int i = 0; i < size; ++i) + storeAnyData(raw_data[i]); + } } @@ -385,6 +401,8 @@ const bool CFRecord::checkFitReadSafe(const size_t size) const const bool CFRecord::checkFitWriteSafe(const size_t size) const { + if(global_info_ && (global_info_.get()->Version == 0x0800)) + return (rdPtr + size <= MAX_RECORD_SIZE_XLSB); return (rdPtr + size <= MAX_RECORD_SIZE); } @@ -430,6 +448,12 @@ void CFRecord::reserveNunBytes(const size_t n) if (rdPtr + n < MAX_RECORD_SIZE) for (size_t i = 0; i < n; ++i) intData[rdPtr++] = 0; + else if(global_info_ && (global_info_.get()->Version == 0x0800) && (rdPtr + n < MAX_RECORD_SIZE_XLSB)) + { + for (size_t i = 0; i < n; ++i) + intData[rdPtr++] = 0; + } + } diff --git a/MsBinaryFile/XlsFile/Format/Binary/CFRecord.h b/MsBinaryFile/XlsFile/Format/Binary/CFRecord.h index c01e4bd6a5f..8ad0ee56f3a 100644 --- a/MsBinaryFile/XlsFile/Format/Binary/CFRecord.h +++ b/MsBinaryFile/XlsFile/Format/Binary/CFRecord.h @@ -131,6 +131,12 @@ class CFRecord rdPtr += sizeof(T); return true; } + else if(global_info_ && (global_info_.get()->Version == 0x0800) && (rdPtr + sizeof(T) < MAX_RECORD_SIZE_XLSB)) + { + memcpy(&intData[rdPtr], &val, sizeof(T)); + rdPtr += sizeof(T); + return true; + } return false; } @@ -161,7 +167,8 @@ class CFRecord CFRecord& operator << (bool& val); private: - static const size_t MAX_RECORD_SIZE = 8224; + static const size_t MAX_RECORD_SIZE = 8224; + static const size_t MAX_RECORD_SIZE_XLSB = 0xFFFFFFF; CFStream::ReceiverItems receiver_items; CFStream::SourceItems source_items; @@ -172,7 +179,7 @@ class CFRecord char* data_; BYTE sizeOfRecordTypeRecordLength; //размер RecordType и RecordLength size_t rdPtr; - static char intData[MAX_RECORD_SIZE]; + static char intData[MAX_RECORD_SIZE_XLSB]; GlobalWorkbookInfoPtr global_info_; }; diff --git a/MsBinaryFile/XlsFile/Format/Crypt/XORCrypt.cpp b/MsBinaryFile/XlsFile/Format/Crypt/XORCrypt.cpp index bd308ae8919..8359c608b4c 100644 --- a/MsBinaryFile/XlsFile/Format/Crypt/XORCrypt.cpp +++ b/MsBinaryFile/XlsFile/Format/Crypt/XORCrypt.cpp @@ -117,13 +117,15 @@ XORCrypt::XORCrypt(int type, unsigned short key, unsigned short hash, std::wstri m_nKey(0), m_nHash(0) { + m_VerifyPassword = false; + + if (password.empty()) return; + if (type == 1) m_nRotateDistance = 7; //doc else if (type == 2) m_nRotateDistance = 2; //xls memset( m_pnKey, 0, sizeof( m_pnKey ) ); - m_VerifyPassword = false; - size_t nLen = password.length(); if (nLen > 16) return; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/AxcExt.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/AxcExt.cpp index b18a1d35f72..184b91c4b90 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/AxcExt.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/AxcExt.cpp @@ -105,20 +105,26 @@ int AxcExt::serialize(std::wostream & _stream) CP_XML_ATTR(L"val", catMinor); } } - if ( fAutoBase == false) + if ( fAutoBase == false && duBase < 3) { CP_XML_NODE(L"c:baseTimeUnit") { CP_XML_ATTR(L"val", DateUnit[duBase]); } } - CP_XML_NODE(L"c:majorTimeUnit") + if ( duMajor < 3) { - CP_XML_ATTR(L"val", DateUnit[duMajor]); + CP_XML_NODE(L"c:majorTimeUnit") + { + CP_XML_ATTR(L"val", DateUnit[duMajor]); + } } - CP_XML_NODE(L"c:minorTimeUnit") + if (duMinor < 3) { - CP_XML_ATTR(L"val", DateUnit[duMinor]); + CP_XML_NODE(L"c:minorTimeUnit") + { + CP_XML_ATTR(L"val", DateUnit[duMinor]); + } } } return 0; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/BOF.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/BOF.cpp index 777ab4d89c0..e7066f62b1e 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/BOF.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/BOF.cpp @@ -74,6 +74,8 @@ void BOF::readFields(CFRecord& record) if (type_id_ == rt_BOF_BIFF8) { + if (vers > 0x0700) vers = 0x0600; + record >> rupBuild >> rupYear; // biff 5 - 8 if ( record.checkFitReadSafe(8)) // biff 8 @@ -112,9 +114,9 @@ void BOF::readFields(CFRecord& record) } else { + short not_used = 0; if (type_id_ == rt_BOF_BIFF3 || type_id_ == rt_BOF_BIFF4) { - short not_used; record >> not_used; } diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/DVal.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/DVal.cpp index c65c93fd14b..c44852c18d5 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/DVal.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/DVal.cpp @@ -62,9 +62,13 @@ void DVal::readFields(CFRecord& record) void DVal::writeFields(CFRecord& record) { _UINT16 flags = 0; + _UINT32 reserved = 0; SETBIT(flags, 0, fWnClosed); - record << flags << xLeft << yTop << idObj << idvMac; + if(record.getGlobalWorkbookInfo()->Version < 0x0800) + record << flags << xLeft << yTop << idObj << idvMac; + else + record << flags << xLeft << yTop << reserved << idvMac; } } // namespace XLS diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Dv.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Dv.cpp index e55f2caebf3..825d8c5af48 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Dv.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Dv.cpp @@ -142,20 +142,33 @@ void Dv::writeFields(CFRecord& record) record << FRTheader; _UINT32 flags = 0; - - SETBITS(flags, 0, 3, valType) - SETBITS(flags, 4, 6, errStyle) - - SETBIT(flags, 7, fStrLookup) - SETBIT(flags, 8, fAllowBlank) - SETBIT(flags, 9, fSuppressCombo) - SETBITS(flags, 10, 17, mdImeMode) - SETBIT(flags, 18, fShowInputMsg) - SETBIT(flags, 19, fShowErrorMsg) - SETBITS(flags, 20, 23, typOperator) - SETBIT(flags, 24, fDVMinFmla) - SETBIT(flags, 25, fDVMaxFmla) - + if(record.getGlobalWorkbookInfo()->Version < 0x0800) + { + SETBITS(flags, 0, 3, valType) + SETBITS(flags, 4, 6, errStyle) + + SETBIT(flags, 7, fStrLookup) + SETBIT(flags, 8, fAllowBlank) + SETBIT(flags, 9, fSuppressCombo) + SETBITS(flags, 10, 17, mdImeMode) + SETBIT(flags, 18, fShowInputMsg) + SETBIT(flags, 19, fShowErrorMsg) + SETBITS(flags, 20, 23, typOperator) + SETBIT(flags, 24, fDVMinFmla) + SETBIT(flags, 25, fDVMaxFmla) + } + else + { + SETBITS(flags, 0, 3, valType) + SETBITS(flags, 4, 6, errStyle) + + SETBIT(flags, 8, fAllowBlank) + SETBIT(flags, 9, fSuppressCombo) + SETBITS(flags, 10, 17, mdImeMode) + SETBIT(flags, 18, fShowInputMsg) + SETBIT(flags, 19, fShowErrorMsg) + SETBITS(flags, 20, 23, typOperator) + } record << flags; if (record.getGlobalWorkbookInfo()->Version < 0x0800) @@ -174,10 +187,17 @@ void Dv::writeFields(CFRecord& record) XLSB::DValStrings dvalstr; dvalstr.strPromptTitle = PromptTitle; - dvalstr.strErrorTitle = ErrorTitle; + if(!PromptTitle.size()) + dvalstr.strPromptTitle.setSize(0xFFFFFFFF); + dvalstr.strErrorTitle = ErrorTitle; + if(!ErrorTitle.size()) + dvalstr.strErrorTitle.setSize(0xFFFFFFFF); dvalstr.strPrompt = Prompt; + if(!Prompt.size()) + dvalstr.strPrompt.setSize(0xFFFFFFFF); dvalstr.strError = Error; - + if(!Error.size()) + dvalstr.strError.setSize(0xFFFFFFFF); record << dvalstr; } diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/FileSharing.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/FileSharing.cpp index c9ded9db072..a0fe84b4c2c 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/FileSharing.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/FileSharing.cpp @@ -70,5 +70,31 @@ void FileSharing::readFields(CFRecord& record) } } +void FileSharing::writeFields(CFRecord& record) +{ + if(record.getGlobalWorkbookInfo()->Version == 0x0800) + { + auto readOnlyrec = fReadOnlyRec.value(); + if(readOnlyrec.is_initialized() &&(readOnlyrec.get() == 1 || readOnlyrec.get() == 0)) + record << fReadOnlyRec; + else + { + _UINT16 defaulTRec = 0; + record << defaulTRec; + } + if(!wResPass.empty()) + { + try + { + wResPassNum = std::stoi(wResPass, nullptr, 16); + } + catch(const std::exception&) + { + wResPassNum = 0; + } + } + record << wResPassNum << stUserName; + } +} } // namespace XLS diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/FileSharing.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/FileSharing.h index d2d31729e23..080f5a6d5df 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/FileSharing.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/FileSharing.h @@ -51,6 +51,7 @@ class FileSharing: public BiffRecord BaseObjectPtr clone(); void readFields(CFRecord& record); + void writeFields(CFRecord& record) override; static const ElementType type = typeFileSharing; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Format.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Format.h index bdfe5355537..e4d4455c62f 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Format.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Format.h @@ -53,8 +53,8 @@ class Format: public BiffRecord int serialize(std::wostream & stream); //----------------------------- - _UINT16 ifmt_used; - _UINT16 ifmt; + _UINT16 ifmt_used = 0xFFFF; + _UINT16 ifmt = 0xFFFF; std::wstring stFormat; }; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Formula.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Formula.cpp index f2b3198e782..351d22e0beb 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Formula.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Formula.cpp @@ -61,8 +61,14 @@ void Formula::readFields(CFRecord& record) fShrFmla = GETBIT(flags, 3); fClearErrors = GETBIT(flags, 5); - _UINT32 chn = 0; - record >> chn; // cache + if (bBiff_3_4 && record.getGlobalWorkbookInfo()->Version < 0x0600) + { + } + else + { + _UINT32 chn = 0; + record >> chn; // cache + } formula.load(record); } diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Label.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Label.cpp index 937691a8da9..4d8070ccbe5 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Label.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Label.cpp @@ -66,13 +66,37 @@ void Label::readFields(CFRecord& record) } else if (global_info_->Version < 0x0600) { - LPAnsiString name; - record >> name; + unsigned short test; + record >> test; + record.RollRdPtrBack(2); - st = name; + if (test > record.getDataSize()) + { + //wrong version !! + record.RollRdPtrBack(record.getRdPtr()); + + int store = global_info_->Version; + global_info_->Version = 0x0200; + + ShortXLAnsiString name; + + record >> cell >> name; + st = name; + + global_info_->Version = store; + } + else + { + LPAnsiString name; + record >> name; + + st = name; + } } else + { record >> st; + } isst_ = global_info_->startAddedSharedStrings + global_info_->arAddedSharedStrings.size() ; global_info_->arAddedSharedStrings.push_back(st.value()); diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Number.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Number.cpp index 18c975d9a26..5c25ca8a639 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Number.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Number.cpp @@ -58,7 +58,21 @@ void Number::readFields(CFRecord& record) { global_info_ = record.getGlobalWorkbookInfo(); - record >> cell >> num; + if (record.getDataSize() == 15) + { + //wrong version !! + int store = global_info_->Version; + global_info_->Version = 0x0200; + + record >> cell >> num; + + global_info_->Version = store; + } + else + { // sizeof record == 14 + record >> cell >> num; + } + _INT32 val = 0; if (record.getDataSize() >= 18)//SchetPrintForm.xls @@ -94,7 +108,7 @@ int Number::serialize(std::wostream & stream) return 0; } //--------------------------------------------------------------------------------- -Integer_BIFF2::Integer_BIFF2() +Integer_BIFF2::Integer_BIFF2() : num(0) {} Integer_BIFF2::~Integer_BIFF2() {} @@ -103,10 +117,26 @@ BaseObjectPtr Integer_BIFF2::clone() return BaseObjectPtr(new Integer_BIFF2(*this)); } void Integer_BIFF2::readFields(CFRecord& record) -{ +{//only version 0x0200 global_info_ = record.getGlobalWorkbookInfo(); - record >> cell >> num; + int store = global_info_->Version; + global_info_->Version = 0x0200; + + record >> cell; + + if (record.getRdPtr() + 2 < record.getDataSize()) + { + record >> num; + } + else + { + _INT16 num_2byte = 0; + record >> num_2byte; + num = num_2byte; + } + + global_info_->Version = store; } const CellRef Integer_BIFF2::getLocation() const { diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Pane.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Pane.cpp index c179c24269a..1974a6fcd3e 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Pane.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Pane.cpp @@ -69,7 +69,7 @@ void Pane::readFields(CFRecord& record) else { record >> xnumXSplit >> xnumYSplit >> rwTop >> colLeft >> pnnAcct_xlsb; - topLeftCell = static_cast(CellRef(rwTop, colLeft, true, true)); + topLeftCell = CellRef(rwTop, colLeft, true, true).toString(true); unsigned char flags; record >> flags; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Selection.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Selection.cpp index 73068028fdc..356bc7b5701 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Selection.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Selection.cpp @@ -80,12 +80,12 @@ void Selection::readFields(CFRecord& record) { XLSB::UncheckedSqRfX sqrfx; record >> pnn_xlsb >> rwAct >> colAct >> irefAct >> sqrfx; - activeCell = static_cast(CellRef(rwAct, colAct, true, true)); + activeCell = CellRef(rwAct, colAct, true, true).toString(true); std::wstring sqref_str; int i = 0, cref = sqrfx.rgrfx.size(); std::for_each(sqrfx.rgrfx.begin(), sqrfx.rgrfx.end(), [&](XLSB::UncheckedRfX &refu) { - sqref_str += std::wstring (refu.toString(false).c_str()) + ((i == cref - 1) ? L"" : L" "); + sqref_str += std::wstring (refu.toString(false, true).c_str()) + ((i == cref - 1) ? L"" : L" "); }); sqref = sqref_str; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/UserSViewBegin.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/UserSViewBegin.h index 2a4eb40b0f0..8a1a81d6d0b 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/UserSViewBegin.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/UserSViewBegin.h @@ -56,7 +56,7 @@ class UserSViewBegin: public BiffRecord std::wstring guid; TabId iTabid; _UINT32 wScale; - Icv icvHdr; + Icv icvHdr = 64; PaneType pnnSel; bool fShowBrks; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Window1.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Window1.cpp index 6eb69b27b9f..ceafce00a6e 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Window1.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Window1.cpp @@ -55,16 +55,21 @@ void Window1::readFields(CFRecord& record) { if (record.getGlobalWorkbookInfo()->Version < 0x0800) { - unsigned short flags; - _INT16 xWn_2b; - _INT16 yWn_2b; - _INT16 dxWn_2b; - _INT16 dyWn_2b; - _UINT16 itabCur_2b; - _UINT16 itabFirst_2b; - _UINT16 wTabRatio_2b; - - record >> xWn_2b >> yWn_2b >> dxWn_2b >> dyWn_2b >> flags >> itabCur_2b >> itabFirst_2b >> ctabSel >> wTabRatio_2b; + BYTE flags = 0, reserved; + _INT16 xWn_2b = 0; + _INT16 yWn_2b = 0; + _INT16 dxWn_2b = 0; + _INT16 dyWn_2b = 0; + _UINT16 itabCur_2b = 0; + _UINT16 itabFirst_2b = 0; + _UINT16 wTabRatio_2b = 0; + + record >> xWn_2b >> yWn_2b >> dxWn_2b >> dyWn_2b >> flags; + + if (record.getGlobalWorkbookInfo()->Version > 0x0400) + { + record >> reserved >> itabCur_2b >> itabFirst_2b >> ctabSel >> wTabRatio_2b; + } fHidden = GETBIT(flags, 0); fIconic = GETBIT(flags, 1); diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Window2.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Window2.cpp index 1e71f16379e..bc278788964 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Window2.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Window2.cpp @@ -152,7 +152,7 @@ void Window2::readFields(CFRecord& record) record >> xlView >> rwTop >> colLeft; - topLeftCell = static_cast(CellRef(rwTop, colLeft, true, true)); + topLeftCell = CellRef(rwTop, colLeft, true, true).toString(true); BYTE icvHdr_1b; record >> icvHdr_1b; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Window2.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Window2.h index aa449376bc0..e839e43363e 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Window2.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Window2.h @@ -51,47 +51,44 @@ class Window2: public BiffRecord void readFields(CFRecord& record) override; void writeFields(CFRecord& record) override; - static const ElementType type = typeWindow2; - - bool fDspFmlaRt; //fDspFmla in biff12 - bool fDspGridRt; //fDspGrid in biff12 - bool fDspRwColRt; //fDspRwCol in biff12 - bool fFrozenRt; - bool fDspZerosRt; // fDspZeros in biff12 - bool fDefaultHdr; // * - bool fRightToLeft; // * - bool fDspGuts; // * - bool fFrozenNoSplit; - bool fSelected; // * - bool fPaged; - bool fSLV; + static const ElementType type = typeWindow2; + + bool fDspFmlaRt = false; //fDspFmla in biff12 + bool fDspGridRt = false; //fDspGrid in biff12 + bool fDspRwColRt = false; //fDspRwCol in biff12 + bool fFrozenRt = false; + bool fDspZerosRt = false; // fDspZeros in biff12 + bool fDefaultHdr = false; // * + bool fRightToLeft = false; // * + bool fDspGuts = false; // * + bool fFrozenNoSplit = false; + bool fSelected = false; // * + bool fPaged = false; + bool fSLV = false; bool is_contained_in_chart_substream; - //_UINT16 rwTop; - UncheckedRw rwTop; - //_UINT16 colLeft; - UncheckedCol colLeft; + UncheckedRw rwTop; + UncheckedCol colLeft; - _UINT16 icvHdr; // 1 Byte in biff12 + _UINT16 icvHdr = 64; // 1 Byte in biff12 - _UINT16 wScaleSLV; - _UINT16 wScaleNormal; - std::wstring topLeftCell; + _UINT16 wScaleSLV; + _UINT16 wScaleNormal; + std::wstring topLeftCell; //biff12 - bool fWnProt; - bool fDspRuler; - bool fWhitespaceHidden; - - _UINT32 xlView; + bool fWnProt = false; + bool fDspRuler = false; + bool fWhitespaceHidden = false; - _UINT16 wScale; - _UINT16 wScalePLV; - _UINT32 iWbkView; + _UINT32 xlView; - bool _isChart; + _UINT16 wScale; + _UINT16 wScalePLV; + _UINT32 iWbkView; + bool _isChart = false; }; } // namespace XLS diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/XF.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/XF.cpp index 81985857674..04d81c56224 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/XF.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/XF.cpp @@ -74,15 +74,9 @@ namespace XLS fill.fls = GETBIT(flags2, 7) ? 1 : 0; //--------------------------------------------------------------------------------------------------- - - if (ifmt_index < global_info->m_arNumFormats.size() && ifmt_index != 0xff) + if (ifmt_index != 0xff) { - Format* fmt = dynamic_cast(global_info->m_arNumFormats[ifmt_index].get()); - if (fmt) - { - format_code = fmt->stFormat; - ifmt = fmt->ifmt_used = global_info->RegisterNumFormat(fmt->ifmt, format_code); // return update - } + ifmt = global_info->RegisterNumFormat(ifmt_index, L""); // return update } if (font_index >= 0 && font_index < global_info->m_arFonts.size()) @@ -144,14 +138,9 @@ namespace XLS border.dgRight = static_cast(GETBITS(flags5, 24, 26)); border.icvRight = (0 != border.dgRight) ? static_cast(GETBITS(flags5, 27, 31)) : 0; //--------------------------------------------------------------------------------------------------- - if (ifmt_index < global_info->m_arNumFormats.size() && ifmt_index != 0xff) + if (ifmt_index != 0xff) { - Format* fmt = dynamic_cast(global_info->m_arNumFormats[ifmt_index].get()); - if (fmt) - { - format_code = fmt->stFormat; - ifmt = fmt->ifmt_used = global_info->RegisterNumFormat(fmt->ifmt, format_code); // return update - } + ifmt = global_info->RegisterNumFormat(ifmt_index, L""); } if (font_index >= 0 && font_index < global_info->m_arFonts.size()) @@ -186,6 +175,8 @@ namespace XLS ixfParent = 0; font_index = 0xffff; + + ifmt = 0xffff; } XF::~XF() { @@ -230,8 +221,8 @@ void XF::readFields(CFRecord& record) fill.fls = static_cast(GETBITS(flags4, 0, 5)); - fill.icvFore = GETBITS(flags4, 0, 6); - fill.icvBack = GETBITS(flags4, 7, 13); + fill.icvFore = GETBITS(flags4, 6, 10); + fill.icvBack = GETBITS(flags4, 11, 15); border.dgTop = static_cast(GETBITS(flags5, 0, 2)); border.icvTop = (0 != border.dgTop) ? static_cast(GETBITS(flags5, 3, 7)) : 0; @@ -389,14 +380,9 @@ void XF::readFields(CFRecord& record) case 2: trot = 90; break; // Text orientation: 90 deg counterclockwise. case 3: trot = 270; break; // Text orientation: 90 deg clockwise. } - if (ifmt_index < global_info->m_arNumFormats.size() && ifmt_index != 0xff) + if (ifmt_index != 0xff) { - Format* fmt = dynamic_cast(global_info->m_arNumFormats[ifmt_index].get()); - if (fmt) - { - format_code = fmt->stFormat; - ifmt = fmt->ifmt_used = global_info->RegisterNumFormat(fmt->ifmt, format_code); // return update - } + ifmt = global_info->RegisterNumFormat(ifmt_index, L""); } if (font_index >= 0 && font_index < global_info->m_arFonts.size()) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/BIFF12/CellRef.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/BIFF12/CellRef.h index 06edcc88e3c..cef90e84850 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/BIFF12/CellRef.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/BIFF12/CellRef.h @@ -40,9 +40,9 @@ namespace XLSB DEFINE_NAME_CLASS(RgceLoc) DEFINE_NAME_CLASS(RgceLocRel) - typedef XLS::CellRef_T RgceLoc; - typedef XLS::CellRef_T RgceLocRel; - //typedef CellRef_T RgceElfLocExtra; - //typedef CellRef_T RgceElfLoc; + typedef XLS::CellRef_T RgceLoc; + typedef XLS::CellRef_T RgceLocRel; + //typedef CellRef_T RgceElfLocExtra; + //typedef CellRef_T RgceElfLoc; } // namespace XLSB diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/BIFF12/FRTHeader.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/BIFF12/FRTHeader.h index 74e704dd213..31a88a2d049 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/BIFF12/FRTHeader.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/BIFF12/FRTHeader.h @@ -55,10 +55,10 @@ namespace XLSB void load(XLS::CFRecord& record) override; void save(XLS::CFRecord& record) override; - bool fRef; - bool fSqref; - bool fFormula; - bool fRelID; + bool fRef = false; + bool fSqref = false; + bool fFormula = false; + bool fRelID = false; FRTRefs rgRefs; FRTSqrefs rgSqrefs; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/BIFF12/FRTParsedFormula.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/BIFF12/FRTParsedFormula.cpp index a37efd97a36..c71657be8e8 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/BIFF12/FRTParsedFormula.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/BIFF12/FRTParsedFormula.cpp @@ -81,6 +81,7 @@ void FRTParsedFormula::save(XLS::CFRecord& record) record.RollRdPtrBack(cce + 8); record << cce; record.skipNunBytes(cce + 4); + this->cce = cce; } diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/BIFF12/FRTSqref.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/BIFF12/FRTSqref.h index dcbdecd96f0..a33ad988f03 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/BIFF12/FRTSqref.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/BIFF12/FRTSqref.h @@ -53,10 +53,10 @@ namespace XLSB void load(XLS::CFRecord& record) override; void save(XLS::CFRecord& record) override; - bool fAdjDelete; - bool fDoAdjust; - bool fAdjChange; - bool fEdit; + bool fAdjDelete = false; + bool fDoAdjust = false; + bool fAdjChange = false; + bool fEdit = false; UncheckedSqRfX sqrfx; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/BIFF12/UncheckedSqRfX.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/BIFF12/UncheckedSqRfX.cpp index 9335b60f95d..cb6b6d78b79 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/BIFF12/UncheckedSqRfX.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/BIFF12/UncheckedSqRfX.cpp @@ -60,11 +60,13 @@ namespace XLSB { record >> crfx; UncheckedRfX rfx; + bool isXlsb = (record.getGlobalWorkbookInfo()->Version) >= 0x0800; for(size_t i = 0; i < crfx; i++) { record >> rfx; rgrfx.push_back(rfx); - strValue += std::wstring (rfx.toString(false).c_str()) + ((i == crfx - 1) ? L"" : L" "); + strValue += std::wstring (rfx.toString(false, isXlsb).c_str()) + ((i == crfx - 1) ? L"" : L" "); + rfx.to_string_cache.clear(); } } diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/BiffString.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/BiffString.cpp index 369e8aef72e..4443acc6c2d 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/BiffString.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/BiffString.cpp @@ -36,329 +36,318 @@ namespace XLS { -BiffString::BiffString() -: struct_size(0), - bDeleteZero(false) -{ -} - - -BiffString::BiffString(const size_t size) -: struct_size(0), - cch_(size), - bDeleteZero(false) -{ -} - - -BiffString::BiffString(const std::wstring & str) -: struct_size(0), - str_(str), - cch_(str.length()), - bDeleteZero(false) -{ -} - - -BiffString::~BiffString() -{ -} - - - - -BiffString::operator std::wstring () const -{ - return str_; -} - - -BiffString BiffString::operator=(const std::wstring & str) -{ - str_ = str; - cch_ = str_.length(); - return *this; -} + BiffString::BiffString() + : struct_size(0), + bDeleteZero(false) + { + } + BiffString::BiffString(const size_t size) + : struct_size(0), + cch_(size), + bDeleteZero(false) + { + } -BiffStructurePtr BiffString::clone() -{ - return BiffStructurePtr(new BiffString(*this)); -} + BiffString::BiffString(const std::wstring & str) + : struct_size(0), + str_(str), + cch_(str.length()), + bDeleteZero(false) + { + } -void BiffString::load(CFRecord& record) -{ - // EXCEPT::LE::WhatIsTheFuck("Wrong usage of BiffString. Stack overflow stopped.", __FUNCTION__); - // record >> *this; // :-) -} -void BiffString::load(IBinaryReader* reader) -{ -} -void BiffString::load(IBinaryReader* reader, const size_t cch1, const bool is_wide1) -{ - bool is_wide = is_wide1; - - size_t cch = cch1; - if ((cch_) && (*cch_ != cch1) && cch1 < 1) + BiffString::~BiffString() { - cch = cch_.get(); } - size_t raw_length = cch << (is_wide ? 1 : 0); - - if (reader->GetPosition() + cch > reader->GetSize()) + + BiffString::operator std::wstring () const { - //ОШИБКА - нехватило Continue records - нужно найти место где именно и подзагрузить - return; + return str_; } - unsigned char* pData = reader->ReadBytes(cch, true); - - if(is_wide) + + BiffString BiffString::operator=(const std::wstring & str) { -#if defined(_WIN32) || defined(_WIN64) - str_ = std::wstring((wchar_t*)pData, cch); -#else - str_ = convertUtf16ToWString((UTF16*)pData, cch); -#endif + str_ = str; + cch_ = str_.length(); + return *this; } - else + + BiffStructurePtr BiffString::clone() { + return BiffStructurePtr(new BiffString(*this)); } - delete []pData; -} -void BiffString::load(CFRecord& record, const size_t cch1, const bool is_wide1) -{ - bool is_wide = is_wide1; - - size_t cch = cch1; - if ((cch_) && (*cch_ != cch1) && cch1 < 1) + void BiffString::load(CFRecord& record) { - cch = cch_.get(); + // EXCEPT::LE::WhatIsTheFuck("Wrong usage of BiffString. Stack overflow stopped.", __FUNCTION__); + // record >> *this; // :-) } - size_t raw_length = cch << (is_wide ? 1 : 0); - - if (record.checkFitRead(raw_length)==false) + void BiffString::load(IBinaryReader* reader) { - //ОШИБКА - нехватило Continue records - нужно найти место где именно и подзагрузить - return; } - if(is_wide) + void BiffString::load(IBinaryReader* reader, const size_t cch1, const bool is_wide1) { - if (false == bDeleteZero) + bool is_wide = is_wide1; + + size_t cch = cch1; + if ((cch_) && (*cch_ != cch1) && cch1 < 1) { -#if defined(_WIN32) || defined(_WIN64) - str_ = std::wstring(record.getCurData(), cch); -#else - str_= convertUtf16ToWString(record.getCurData(), cch); -#endif - record.skipNunBytes(raw_length); + cch = cch_.get(); + } + size_t raw_length = cch << (is_wide ? 1 : 0); + + if (reader->GetPosition() + cch > reader->GetSize()) + { + //ОШИБКА - нехватило Continue records - нужно найти место где именно и подзагрузить + return; + } + unsigned char* pData = reader->ReadBytes(cch, true); + + if(is_wide) + { + #if defined(_WIN32) || defined(_WIN64) + str_ = std::wstring((wchar_t*)pData, cch); + #else + str_ = convertUtf16ToWString((UTF16*)pData, cch); + #endif } else { - //5804543.xls - font name in dx for table - c a l i 0 0 0 0 b r i - !!!! - UTF16 *buf_read = new UTF16[cch]; + } + delete []pData; + } + + void BiffString::load(CFRecord& record, const size_t cch1, const bool is_wide1) + { + bool is_wide = is_wide1; + + size_t cch = cch1; + if ((cch_) && (*cch_ != cch1) && cch1 < 1) + { + cch = cch_.get(); + } + size_t raw_length = cch << (is_wide ? 1 : 0); + + if (record.checkFitRead(raw_length)==false) + { + //ОШИБКА - нехватило Continue records - нужно найти место где именно и подзагрузить + return; + } - for (size_t i = 0; i < cch; i++) + if(is_wide) + { + if (false == bDeleteZero) { - unsigned short val; - do + #if defined(_WIN32) || defined(_WIN64) + str_ = std::wstring(record.getCurData(), cch); + #else + str_= convertUtf16ToWString(record.getCurData(), cch); + #endif + record.skipNunBytes(raw_length); + } + else + { + //5804543.xls - font name in dx for table - c a l i 0 0 0 0 b r i - !!!! + UTF16 *buf_read = new UTF16[cch]; + + for (size_t i = 0; i < cch; i++) { - record >> val; - }while(val == 0); - buf_read[i] = val; + unsigned short val; + do + { + record >> val; + }while(val == 0); + buf_read[i] = val; + } + #if defined(_WIN32) || defined(_WIN64) + str_ = std::wstring((wchar_t*)buf_read, cch); + #else + str_= convertUtf16ToWString(buf_read, cch); + #endif + delete []buf_read; } + } + else + { + std::string inp_str(record.getCurData(), cch); + + if (record.getGlobalWorkbookInfo()->CodePage == 1200) + { + int inp_str_size = inp_str.length(); + UTF16 *out_str = new UTF16[inp_str_size + 1]; + char* out_str_char = (char*) out_str; + for (int i = 0; i < inp_str_size; i++) + { + out_str_char[2*i+0] = inp_str.c_str()[i]; + out_str_char[2*i+1] = 0; + } + out_str[inp_str_size] = 0; + #if defined(_WIN32) || defined(_WIN64) - str_ = std::wstring((wchar_t*)buf_read, cch); + str_ = std::wstring((wchar_t*)out_str, inp_str_size); #else - str_= convertUtf16ToWString(buf_read, cch); + str_ = convertUtf16ToWString(out_str, inp_str_size); #endif - delete []buf_read; + delete []out_str; + } + else + { + str_ = STR::toStdWString(inp_str, record.getGlobalWorkbookInfo()->CodePage).c_str(); + } + record.skipNunBytes(raw_length); } } - else + + void BiffString::save(CFRecord& record, const size_t cch1, const bool is_wide1) { - std::string inp_str(record.getCurData(), cch); + bool is_wide = is_wide1; - if (record.getGlobalWorkbookInfo()->CodePage == 1200) + size_t cch = cch1; + if ((cch_) && (*cch_ != cch1) && cch1 < 1) { - int inp_str_size = inp_str.length(); - UTF16 *out_str = new UTF16[inp_str_size + 1]; - char* out_str_char = (char*) out_str; - for (int i = 0; i < inp_str_size; i++) - { - out_str_char[2*i+0] = inp_str.c_str()[i]; - out_str_char[2*i+1] = 0; - } - out_str[inp_str_size] = 0; - -#if defined(_WIN32) || defined(_WIN64) - str_ = std::wstring((wchar_t*)out_str, inp_str_size); -#else - str_ = convertUtf16ToWString(out_str, inp_str_size); -#endif - delete []out_str; + cch = cch_.get(); + } + + if (is_wide) + { + unsigned char *out_str = nullptr; + int out_size = 0; + + #if defined(_WIN32) || defined(_WIN64) + record.appendRawDataToStatic(str_.c_str(), str_.size()); + #else + convertWStringToUtf16(str_, out_str, out_size); + record.appendRawDataToStatic(out_str, out_size); + #endif + } else { - str_ = STR::toStdWString(inp_str, record.getGlobalWorkbookInfo()->CodePage).c_str(); + //stub } - record.skipNunBytes(raw_length); } -} -void BiffString::save(CFRecord& record, const size_t cch1, const bool is_wide1) -{ - bool is_wide = is_wide1; - - size_t cch = cch1; - if ((cch_) && (*cch_ != cch1) && cch1 < 1) + const size_t BiffString::getSize() const { - cch = cch_.get(); + if(!cch_) + { + // EXCEPT::LE::StructureSizeNotSet("BiffString", __FUNCTION__/*__FUNCDNAME__*/); + } + return *cch_; } - if (is_wide) - { - unsigned char *out_str = nullptr; - int out_size = 0; -#if defined(_WIN32) || defined(_WIN64) - record.appendRawDataToStatic(str_.c_str(), str_.size()); -#else - convertWStringToUtf16(str_, out_str, out_size); - record.appendRawDataToStatic(out_str, out_size); -#endif - - } - else + void BiffString::setSize(const size_t size) { - //stub + cch_ = size; } -} -const size_t BiffString::getSize() const -{ - if(!cch_) + const size_t BiffString::getStructSize() const { - // EXCEPT::LE::StructureSizeNotSet("BiffString", __FUNCTION__/*__FUNCDNAME__*/); + return struct_size; } - return *cch_; -} - - -void BiffString::setSize(const size_t size) -{ - cch_ = size; -} - - -const size_t BiffString::getStructSize() const -{ - return struct_size; -} - - -// Set number of unsigned chars read while loading. Must be used by >> operator only -void BiffString::setStructSize(const size_t size) -{ - struct_size = size; -} -const std::wstring BiffString::getEscaped_ST_Xstring() const -{ - if(!str_.length()) + // Set number of unsigned chars read while loading. Must be used by >> operator only + void BiffString::setStructSize(const size_t size) { - return str_; + struct_size = size; } - std::wstring copy_str(str_); - return STR::escape_ST_Xstring(copy_str).c_str(); -} - - -void BiffString::Escape_ST_Xstring() -{ - str_ = getEscaped_ST_Xstring(); -} - -const bool BiffString::getWideRecommendation() const -{ - std::wstring str(str_); - for(std::wstring::const_iterator it = str.begin(), itEnd = str.end(); it != itEnd; ++it) + const std::wstring BiffString::getEscaped_ST_Xstring() const { - if(0xff00 & *it) + if(!str_.length()) { - return true; + return str_; } + std::wstring copy_str(str_); + return STR::escape_ST_Xstring(copy_str).c_str(); } - return false; -} -//----------------------------------------------------------------- -BiffStructurePtr XLUnicodeStringSegmented::clone() -{ - return BiffStructurePtr(new XLUnicodeStringSegmented(*this)); -} -void XLUnicodeStringSegmented::load(CFRecord& record) -{ - record >> cchTotal; - if (cchTotal < 1) return; - - if (cchTotal > record.getDataSize() - record.getRdPtr()) + void BiffString::Escape_ST_Xstring() { - cchTotal = cchTotal >> 8; + str_ = getEscaped_ST_Xstring(); } - _UINT32 cchTotal_test = 0; - while(true) + const bool BiffString::getWideRecommendation() const + { + std::wstring str(str_); + for(std::wstring::const_iterator it = str.begin(), itEnd = str.end(); it != itEnd; ++it) + { + if(0xff00 & *it) + { + return true; + } + } + return false; + } + //----------------------------------------------------------------- + BiffStructurePtr XLUnicodeStringSegmented::clone() + { + return BiffStructurePtr(new XLUnicodeStringSegmented(*this)); + } + void XLUnicodeStringSegmented::load(CFRecord& record) { - if (record.isEOF()) - break; + record >> cchTotal; + + if (cchTotal < 1) return; + + if (cchTotal > record.getDataSize() - record.getRdPtr()) + { + cchTotal = cchTotal >> 8; + } - if (cchTotal_test >= cchTotal) - break; + _UINT32 cchTotal_test = 0; + while(true) + { + if (record.isEOF()) + break; + + if (cchTotal_test >= cchTotal) + break; - _UINT32 max_string_size = cchTotal - cchTotal_test; + _UINT32 max_string_size = cchTotal - cchTotal_test; - XLUnicodeString string; - record >> string; + XLUnicodeString string; + record >> string; - arStrings.push_back(string.value()); + arStrings.push_back(string.value()); - cchTotal_test += arStrings.back().length(); - strTotal += arStrings.back(); + cchTotal_test += arStrings.back().length(); + strTotal += arStrings.back(); + } } -} -void XLUnicodeStringSegmented::load(IBinaryReader* reader) -{ - cchTotal = reader->ReadUInt32(); + void XLUnicodeStringSegmented::load(IBinaryReader* reader) + { + cchTotal = reader->ReadUInt32(); - if (cchTotal < 1) return; + if (cchTotal < 1) return; - if (cchTotal > reader->GetSize() - reader->GetPosition()) - { - cchTotal = cchTotal >> 8; - } + if (cchTotal > reader->GetSize() - reader->GetPosition()) + { + cchTotal = cchTotal >> 8; + } - _UINT32 cchTotal_test = 0; - while(true) - { - if (reader->GetPosition() >= reader->GetSize()) - break; + _UINT32 cchTotal_test = 0; + while(true) + { + if (reader->GetPosition() >= reader->GetSize()) + break; - if (cchTotal_test >= cchTotal) - break; + if (cchTotal_test >= cchTotal) + break; - _UINT32 max_string_size = cchTotal - cchTotal_test; + _UINT32 max_string_size = cchTotal - cchTotal_test; - XLUnicodeString string; - string.load(reader); + XLUnicodeString string; + string.load(reader); - arStrings.push_back(string.value()); + arStrings.push_back(string.value()); - cchTotal_test += arStrings.back().length(); - strTotal += arStrings.back(); + cchTotal_test += arStrings.back().length(); + strTotal += arStrings.back(); + } } -} } // namespace XLS diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/BiffString.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/BiffString.h index 0be5d56720f..b7c74f9efcd 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/BiffString.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/BiffString.h @@ -116,6 +116,11 @@ class XLUnicodeString_T : public BiffString cch_ = str.length(); return *this; } + XLUnicodeString_T operator=(const bool& boolVal) + { + cch_ = 0; + return *this; + } const size_t getStructSizeWouldWritten() const // Number of unsigned chars that would be written { return recalculateStructSize(); @@ -136,6 +141,7 @@ class XLUnicodeString_T : public BiffString case cch_READ_FROM_RECORD: cchType cch_l; // Just to conform size read. record >> cch_l; + cch = cch_l; struct_size += sizeof(cchType); break; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/BorderFillInfo.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/BorderFillInfo.cpp index 708512df934..17177f4fe20 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/BorderFillInfo.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/BorderFillInfo.cpp @@ -293,7 +293,7 @@ int FontInfo::serialize(std::wostream & stream) } } - if (uls > 0) + if (uls > 0 && uls < 0xff) { CP_XML_NODE(L"u") { diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/BorderFillInfo.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/BorderFillInfo.h index 72cf83a28d9..2aa39e73ba8 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/BorderFillInfo.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/BorderFillInfo.h @@ -141,7 +141,7 @@ struct FontInfo unsigned short bls = 0; unsigned short sss = 0; unsigned short scheme = 0; - unsigned char uls; + unsigned char uls = 0xff; unsigned char bFamily = 0; unsigned char bCharSet = 0; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFParsedFormula.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFParsedFormula.cpp index ec714649e16..b9074b5586e 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFParsedFormula.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFParsedFormula.cpp @@ -42,7 +42,12 @@ CFParsedFormula::CFParsedFormula(const CellRef& cell_base_ref) : ParsedFormula(c CFParsedFormula& CFParsedFormula::operator=(const std::wstring& value) { - ParsedFormula::operator = (value); + parseStringFormula(value, L"CFParsedFormulaNoCCE"); + auto ptgType = GETBITS(rgce.sequence.back()->getPtgId(),5,6); + if(ptgType == 1) + { + SETBITS(rgce.sequence.back()->ptg_id.get(),5,6,2); + } return *this; } diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFVOParsedFormula.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFVOParsedFormula.cpp index 36de0127471..d9a124c7493 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFVOParsedFormula.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFVOParsedFormula.cpp @@ -112,6 +112,7 @@ void CFVOParsedFormula::save(CFRecord& record) }; saving(rgce); + cce = size; saving(rgcb); } } diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CellRangeRef.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CellRangeRef.cpp index dd5354f3ce6..f8a324f2436 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CellRangeRef.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CellRangeRef.cpp @@ -116,45 +116,57 @@ BiffStructurePtr CellRangeRef::clone() return BiffStructurePtr(new CellRangeRef(*this)); } -const std::wstring CellRangeRef::toString(const bool useShortForm) const +const std::wstring CellRangeRef::toString(const bool useShortForm, const bool xlsb) const { if(to_string_cache.empty()) { - int rowLast_norm = AUX::normalizeRow (rowLast); - int rowFirst_norm = AUX::normalizeRow (rowFirst); - int columnFirst_norm = AUX::normalizeColumn (columnFirst); - int columnLast_norm = AUX::normalizeColumn (columnLast); + int rowLast_norm = AUX::normalizeRow (rowLast, xlsb); + int rowFirst_norm = AUX::normalizeRow (rowFirst, xlsb); + int columnFirst_norm = AUX::normalizeColumn (columnFirst, xlsb); + int columnLast_norm = AUX::normalizeColumn (columnLast, xlsb); + int maxCol = 0; + int maxRow = 0; + if(xlsb) + { + maxCol = 16383; + maxRow = 1048575; + } + else + { + maxCol = 255; + maxRow = 65535; + } - if(0 == rowFirst_norm && 65535 == rowLast_norm ) // whole column or range of columns + if(0 == rowFirst_norm && maxRow == rowLast_norm ) // whole column or range of columns { if(useShortForm) { - return to_string_cache = AUX::column2str(columnFirst_norm, columnFirstRelative) + L':' + AUX::column2str(columnLast_norm, columnLastRelative); + return to_string_cache = AUX::column2str(columnFirst_norm, columnFirstRelative, xlsb) + L':' + AUX::column2str(columnLast_norm, columnLastRelative, xlsb); } else { - rowLast_norm = 1048575; + rowLast_norm = maxRow; } } - if(0 == columnFirst_norm && 255 == columnLast_norm) // whole row or range of rows + if(0 == columnFirst_norm && maxCol == columnLast_norm) // whole row or range of rows { if(useShortForm) { - return to_string_cache = AUX::row2str(rowFirst_norm, rowFirstRelative) + L':' + AUX::row2str(rowLast_norm, rowLastRelative); + return to_string_cache = AUX::row2str(rowFirst_norm, rowFirstRelative, xlsb) + L':' + AUX::row2str(rowLast_norm, rowLastRelative, xlsb); } else { - columnLast_norm = 16383; + columnLast_norm = maxCol; } } if(columnLast_norm == columnFirst_norm && rowFirst_norm == rowLast_norm) // single cell { - return to_string_cache = AUX::loc2str(rowFirst_norm, rowFirstRelative, columnFirst_norm, columnFirstRelative); + return to_string_cache = AUX::loc2str(rowFirst_norm, rowFirstRelative, columnFirst_norm, columnFirstRelative, xlsb); } else { - return to_string_cache = AUX::loc2str(rowFirst_norm, rowFirstRelative, columnFirst_norm, columnFirstRelative) + - L':' + AUX::loc2str(rowLast_norm, rowLastRelative, columnLast_norm, columnLastRelative); + return to_string_cache = AUX::loc2str(rowFirst_norm, rowFirstRelative, columnFirst_norm, columnFirstRelative, xlsb) + + L':' + AUX::loc2str(rowLast_norm, rowLastRelative, columnLast_norm, columnLastRelative, xlsb); } } return to_string_cache; @@ -186,12 +198,16 @@ void CellRangeRef::fromString(const std::wstring& str) } rowFirst = 0; - rowLast = 65535; + rowLast = 1048575; + rowFirstRelative = false; + rowLastRelative = false; } if(-1 == columnFirst || -1 == columnLast) // no column specified - means whole row or range of rows { columnFirst = 0; - columnLast = 255; + columnLast = 16383; + columnFirstRelative = false; + columnLastRelative = false; } to_string_cache.clear(); } diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CellRangeRef.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CellRangeRef.h index d8342821693..6c9fa24d274 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CellRangeRef.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CellRangeRef.h @@ -58,7 +58,7 @@ class CellRangeRef : public BiffStructure static const ElementType type = typeCellRangeRef; - const std::wstring toString(const bool useShortForm = true) const; + const std::wstring toString(const bool useShortForm = true, const bool xlsb = false) const; void fromString(const std::wstring& str); operator std::wstring () const; @@ -110,7 +110,16 @@ template @@ -160,44 +169,69 @@ class CellRangeRef_T : public CellRangeRef switch(rel_info) { case rel_Present: - columnFirst = (colFirst << 2) >> 2; - columnLast = (colLast << 2) >> 2; - rowFirstRelative = 0 != (colFirst & (1 << (sizeof(ColType) * 8 - 1))); - columnFirstRelative = 0 != (colFirst & (1 << (sizeof(ColType) * 8 - 2))); - rowLastRelative = 0 != (colLast & (1 << (sizeof(ColType) * 8 - 1))); - columnLastRelative = 0 != (colLast & (1 << (sizeof(ColType) * 8 - 2))); - break; + { + columnFirst = GETBITS(colFirst, 0, sizeof(ColType) * 8 - 3); + columnLast = GETBITS(colLast, 0, sizeof(ColType) * 8 - 3); + + columnFirstRelative = GETBIT(colFirst, sizeof(ColType) * 8 - 2); + rowFirstRelative = GETBIT(colFirst, sizeof(ColType) * 8 - 1); + + columnLastRelative = GETBIT(colLast, sizeof(ColType) * 8 - 2); + rowLastRelative = GETBIT(colLast, sizeof(ColType) * 8 - 1); + }break; case rel_Absent: + { columnFirst = colFirst; columnLast = colLast; + rowFirstRelative = true; columnFirstRelative = true; rowLastRelative = true; columnLastRelative = true; - break; + }break; } } void save(CFRecord& record) override { - RwType rwFirst; - RwType rwLast; - ColType colFirst; - ColType colLast; - - rwFirst = rowFirst; - rwLast = rowLast; + RwType rwFirst = rowFirst; + RwType rwLast = rowLast; + ColType colFirst = 0; + ColType colLast = 0; + + auto version = record.getGlobalWorkbookInfo()->Version; - switch (rel_info) + if (version < 0x0800) + { + switch (rel_info) + { + case rel_Present: + colFirst = (columnFirst >> 2) << 2; + colLast = (columnLast >> 2) << 2; + break; + case rel_Absent: + colFirst = columnFirst; + colLast = columnLast; + break; + } + } + else { - case rel_Present: - colFirst = (columnFirst >> 2) << 2; - colLast = (columnLast >> 2) << 2; - break; - case rel_Absent: - colFirst = columnFirst; - colLast = columnLast; - break; + if(rel_info == rel_Present) + { + SETBITS(colFirst, 0, 13, columnFirst); + SETBIT(colFirst, 14, columnFirstRelative); + SETBIT(colFirst, 15, rowFirstRelative); + + SETBITS(colLast, 0, 13, columnLast); + SETBIT(colLast, 14, columnLastRelative); + SETBIT(colLast, 15, rowLastRelative); + } + else if(rel_info == rel_Absent) + { + colFirst = columnFirst; + colLast = columnLast; + } } record << rwFirst << rwLast << colFirst << colLast; } @@ -209,8 +243,10 @@ typedef CellRangeRef_T Ref; typedef CellRangeRef_T Ref8; typedef CellRangeRef_T Ref8U; typedef CellRangeRef_T RefU; -typedef CellRangeRef_T Ref8U2007; -typedef CellRangeRef_T RFX; + +typedef CellRangeRef_T Ref8U2007; +typedef CellRangeRef_T RFX; + typedef CellRangeRef_T RgceArea; typedef CellRangeRef_T RgceAreaRel; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CellRef.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CellRef.cpp index d88b6b68528..8573903da10 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CellRef.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CellRef.cpp @@ -73,22 +73,34 @@ BiffStructurePtr CellRef::clone() return BiffStructurePtr(new CellRef(*this)); } -const std::wstring CellRef::toString() const +const std::wstring CellRef::toString(const bool xlsb) const { if (to_string_cache.empty()) - { - int row_norm = AUX::normalizeRow(row); - int column_norm = AUX::normalizeColumn(column); + { + int maxRow = 0; + int maxCol = 0; + if(xlsb) + { + maxRow = 1048575; + maxCol = 16383; + } + else + { + maxRow = 65535; + maxCol = 255; + } + int row_norm = AUX::normalizeRow(row, xlsb); + int column_norm = AUX::normalizeColumn(column, xlsb); - if (0 == row_norm && 65535 == row_norm) // whole column or range of columns + if (0 == row_norm && maxRow == row_norm) // whole column or range of columns { - row_norm = 1048575; + row_norm = maxRow; } - if (0 == column_norm && 255 == column_norm) // whole row or range of rows + if (0 == column_norm && maxCol == column_norm) // whole row or range of rows { - column_norm = 16383; + column_norm = maxCol; } - return to_string_cache = AUX::loc2str(row_norm, rowRelative, column_norm, colRelative); + return to_string_cache = AUX::loc2str(row_norm, rowRelative, column_norm, colRelative, xlsb); } return to_string_cache; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CellRef.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CellRef.h index d8db6fa170f..21a93f67a5c 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CellRef.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CellRef.h @@ -49,7 +49,7 @@ class CellRef : public BiffStructure static const ElementType type = typeCellRef; - const std::wstring toString() const; + const std::wstring toString(const bool xlsb = false) const; void fromString(const std::wstring& str); operator std::wstring () const; @@ -106,7 +106,14 @@ template> rw >> col; row = rw; + fQuoted = false; switch(rel_info) { case rel_Present: - column = (col << 2) >> 2; - rowRelative = 0 != (col & (1 << (sizeof(ColType) * 8 - 1))); - colRelative = 0 != (col & (1 << (sizeof(ColType) * 8 - 2))); - break; + { + column = GETBITS(col, 0, sizeof(ColType) * 8 - 3); + + colRelative = GETBIT(col, sizeof(ColType) * 8 - 2); + rowRelative = GETBIT(col, sizeof(ColType) * 8 - 1); + }break; case rel_Absent: + { column = col; + rowRelative = true; colRelative = true; - break; + }break; case rel_PresentQuoted: - column = (col << 2) >> 2; - colRelative = rowRelative = 0 != (col & (1 << (sizeof(ColType) * 8 - 1))); - fQuoted = 0 != (col & (1 << (sizeof(ColType) * 8 - 2))); - break; + { + column = GETBITS(col, 0, sizeof(ColType) * 8 - 3); + + fQuoted = GETBIT(col, sizeof(ColType) * 8 - 2); + colRelative = rowRelative = GETBIT(col, sizeof(ColType) * 8 - 1); + }break; } } void save(CFRecord& record) override { RwType rw; - ColType col; - + ColType col = 0; rw = row; - col = column; + auto version = record.getGlobalWorkbookInfo()->Version; + + if (version < 0x0800) + { + col = column; + } + else + { + SETBITS(col, 0, 13, column); + SETBIT(col, 14, colRelative); + SETBIT(col, 15, rowRelative); + } record << rw << col; } diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DVParsedFormula.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DVParsedFormula.cpp index ca52fba9e92..7d0cb4d56e1 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DVParsedFormula.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DVParsedFormula.cpp @@ -93,31 +93,51 @@ void DVParsedFormula::save(CFRecord& record, bool bSave) else { cce = 0; - record << cce; + _UINT32 cb = 0; + record << cce << cb; } } void DVParsedFormula::save(CFRecord& record) { - auto saving = [&](BiffStructure& rgceORrgb) + if (record.getGlobalWorkbookInfo()->Version < 0x0800) { - record << cce; + auto saving = [&](BiffStructure& rgceORrgb) + { + record << cce; - auto rdPtr = record.getRdPtr(); + auto rdPtr = record.getRdPtr(); - rgceORrgb.save(record); + rgceORrgb.save(record); - cce = record.getRdPtr() - rdPtr; + cce = record.getRdPtr() - rdPtr; - record.RollRdPtrBack(cce + 4); - record << cce; - record.skipNunBytes(cce); - }; + record.RollRdPtrBack(cce + 4); + record << cce; + record.skipNunBytes(cce); + }; - saving(rgce); - - if (record.getGlobalWorkbookInfo()->Version == 0x0800) + saving(rgce); + } + else { + _UINT32 size = 0; + auto saving = [&](BiffStructure& rgceORrgb) + { + record << size; + + auto rdPtr = record.getRdPtr(); + + rgceORrgb.save(record); + + size = record.getRdPtr() - rdPtr; + + record.RollRdPtrBack(size + 4); + record << size; + record.skipNunBytes(size); + }; + + saving(rgce); saving(rgcb); } } diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFFntD.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFFntD.cpp index 7a15dcc92ac..cca859c48c3 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFFntD.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFFntD.cpp @@ -69,48 +69,52 @@ void DXFFntD::load(CFRecord& record) record >> ich >> cch >> iFnt; } -int DXFFntD::serialize(std::wostream & stream) +int DXFFntD::serialize(std::wostream & stream, bool extOnly) { std::map::iterator pFind; + if (parent && parent->xfext) + pFind = parent->xfext->mapRgExt.find(ExtProp::FontScheme); + CP_XML_WRITER(stream) { CP_XML_NODE(L"font") - { - if (!stFontName.value().empty()) + { + std::wstring name = stFontName.value(); + + if (parent && parent->xfext) { - std::wstring name = stFontName.value(); - - if (parent->xfext) - pFind = parent->xfext->mapRgExt.find(ExtProp::FontScheme); - - BYTE font_scheme = (parent->xfext && pFind != parent->xfext->mapRgExt.end()) ? pFind->second.extPropData.font_scheme : 0; + BYTE font_scheme = (pFind != parent->xfext->mapRgExt.end()) ? pFind->second.extPropData.font_scheme : 0; - if (global_info->m_pTheme && font_scheme == 0x01) + if (global_info && global_info->m_pTheme && font_scheme == 0x01) { name = global_info->m_pTheme->themeElements.fontScheme.majorFont.latin.typeface; } - else if (global_info->m_pTheme && font_scheme == 0x02) + else if (global_info && global_info->m_pTheme && font_scheme == 0x02) { name = global_info->m_pTheme->themeElements.fontScheme.minorFont.latin.typeface; } + } + if (!name.empty()) + { CP_XML_NODE(L"name") { CP_XML_ATTR(L"val", name.substr(0, 31)); } } - if (stxp.twpHeight > 20) + + if (!extOnly && stxp.twpHeight > 20) { CP_XML_NODE(L"sz") { CP_XML_ATTR(L"val", stxp.twpHeight/20.f); } } - if (parent->xfext) + if ((parent && parent->xfext) && (pFind == parent->xfext->mapRgExt.end())) pFind = parent->xfext->mapRgExt.find(ExtProp::ForeColor); - if (parent->xfext && pFind != parent->xfext->mapRgExt.end()) + if ((parent && parent->xfext) && pFind != parent->xfext->mapRgExt.end()) { pFind->second.extPropData.color.serialize(CP_XML_STREAM(), L"color"); } @@ -121,68 +125,71 @@ int DXFFntD::serialize(std::wostream & stream) CP_XML_ATTR(L"indexed", icvFore); } } - CP_XML_NODE(L"charset") - { - CP_XML_ATTR(L"val", stxp.bCharSet); - } - //CP_XML_NODE(L"condense") - //{ - // CP_XML_ATTR(L"val", 1); - //} - //CP_XML_NODE(L"extend") - //{ - // CP_XML_ATTR(L"val", stxp.fExtend); - //} - CP_XML_NODE(L"family") - { - CP_XML_ATTR(L"val", stxp.bFamily); - } - if (tsNinch.ftsItalic == 0) + if (!extOnly) { - CP_XML_NODE(L"i") + CP_XML_NODE(L"charset") { - CP_XML_ATTR(L"val", stxp.ts.ftsItalic); + CP_XML_ATTR(L"val", stxp.bCharSet); } - } - if (fBlsNinch == 0) - { - CP_XML_NODE(L"b") + //CP_XML_NODE(L"condense") + //{ + // CP_XML_ATTR(L"val", 1); + //} + //CP_XML_NODE(L"extend") + //{ + // CP_XML_ATTR(L"val", stxp.fExtend); + //} + CP_XML_NODE(L"family") { - CP_XML_ATTR(L"val", stxp.bls == 700 ? 1 : 0); - } - } - if (tsNinch.ftsStrikeout == 0) - { - CP_XML_NODE(L"strike") + CP_XML_ATTR(L"val", stxp.bFamily); + } + if (tsNinch.ftsItalic == 0) { - CP_XML_ATTR(L"val", stxp.ts.ftsStrikeout); - } - } - if (fUlsNinch == 0) - { - CP_XML_NODE(L"u") + CP_XML_NODE(L"i") + { + CP_XML_ATTR(L"val", stxp.ts.ftsItalic); + } + } + if (fBlsNinch == 0) + { + CP_XML_NODE(L"b") + { + CP_XML_ATTR(L"val", stxp.bls == 700 ? 1 : 0); + } + } + if (tsNinch.ftsStrikeout == 0) { - switch(stxp.uls) + CP_XML_NODE(L"strike") { + CP_XML_ATTR(L"val", stxp.ts.ftsStrikeout); + } + } + if (fUlsNinch == 0) + { + CP_XML_NODE(L"u") + { + switch (stxp.uls) + { case 0: CP_XML_ATTR(L"val", L"none"); break; case 1: CP_XML_ATTR(L"val", L"single"); break; case 2: CP_XML_ATTR(L"val", L"double"); break; - case 33: CP_XML_ATTR(L"val", L"singleAccounting");break; - case 34: CP_XML_ATTR(L"val", L"doubleAccounting");break; + case 33: CP_XML_ATTR(L"val", L"singleAccounting"); break; + case 34: CP_XML_ATTR(L"val", L"doubleAccounting"); break; + } } } - } - if (fSssNinch == 0) - { - CP_XML_NODE(L"vertAlign") + if (fSssNinch == 0) { - switch(stxp.sss) + CP_XML_NODE(L"vertAlign") { + switch (stxp.sss) + { case 0: CP_XML_ATTR(L"val", L"baseline"); break; - case 1: CP_XML_ATTR(L"val", L"superscript");break; + case 1: CP_XML_ATTR(L"val", L"superscript"); break; case 2: CP_XML_ATTR(L"val", L"subscript"); break; + } + } - } } } diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFFntD.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFFntD.h index c04f7b7da51..49e238b7560 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFFntD.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFFntD.h @@ -50,26 +50,25 @@ class DXFFntD : public BiffStructure public: BiffStructurePtr clone(); - static const ElementType type = typeDXFFntD; + static const ElementType type = typeDXFFntD; virtual void load(CFRecord& record); - int serialize(std::wostream & stream); + int serialize(std::wostream & stream, bool extOnly = false); XLUnicodeStringNoCch stFontName; Stxp stxp; - _INT32 icvFore; + _INT32 icvFore = 0; Ts tsNinch; - _UINT32 fSssNinch; - _UINT32 fUlsNinch; - _UINT32 fBlsNinch; - - _INT32 ich; - _INT32 cch; - _UINT16 iFnt; + _UINT32 fSssNinch = 0; + _UINT32 fUlsNinch = 0; + _UINT32 fBlsNinch = 0; + _INT32 ich = 0; + _INT32 cch = 0; + _UINT16 iFnt = 0; //------------------------------------------------ GlobalWorkbookInfoPtr global_info; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFN.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFN.cpp index f3e48b2d9f4..0c3bad5a250 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFN.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFN.cpp @@ -122,9 +122,9 @@ int DXFN::serialize(std::wostream & stream) { CP_XML_NODE(L"dxf") { - if(ibitAtrFnt) + if (ibitAtrFnt || (xfext && (xfext->mapRgExt.end() != xfext->mapRgExt.find(ExtProp::FontScheme)))) { - dxffntd.serialize(CP_XML_STREAM()); + dxffntd.serialize(CP_XML_STREAM(), ibitAtrFnt == false); } if(ibitAtrNum) { diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ExtProp.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ExtProp.h index 3a92ac9dfdb..f601576bc3d 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ExtProp.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ExtProp.h @@ -48,7 +48,7 @@ class ExtProp : public BiffStructure virtual void load(CFRecord& record); - static const ElementType type = typeExtProp; + static const ElementType type = typeExtProp; unsigned short cb; @@ -72,8 +72,8 @@ class ExtProp : public BiffStructure { FullColorExt color; XFExtGradient gradient_fill; - unsigned char font_scheme; - unsigned short indent_level; + unsigned char font_scheme = 0; + unsigned short indent_level = 0; } extPropData; }; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ExtPtgArea3D.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ExtPtgArea3D.cpp index 8a878792835..0b885ee1158 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ExtPtgArea3D.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ExtPtgArea3D.cpp @@ -60,7 +60,11 @@ void ExtPtgArea3D::assemble(AssemblerStack& ptg_stack, PtgQueue& extra_data, boo { std::wstring strRange; - std::wstring range_ref = area.toString(); + std::wstring range_ref; + if (global_info->Version < 0x0800) + range_ref = area.toString(); + else + range_ref = area.toString(true, true); if(-1 == iTabs.itabFirst) { diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/Ftab_Cetab.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/Ftab_Cetab.cpp index c0927f95141..d5b5b4be7a3 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/Ftab_Cetab.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/Ftab_Cetab.cpp @@ -521,15 +521,15 @@ Ftab_Cetab::ValuesDetermination::ValuesDetermination() params_fixed.insert(ParamsFixed(0x01D6, 4, L"ACCRINTM")); params_fixed.insert(ParamsFixed(0x01D7, 2, L"WORKDAY")); params_fixed.insert(ParamsFixed(0x01D8, 2, L"NETWORKDAYS")); - params_fixed.insert(ParamsFixed(0x01D9, 1, L"GCD")); + params_fixed.insert(ParamsFixed(0x01D9, -1, L"GCD")); params_fixed.insert(ParamsFixed(0x01DA, 1, L"MULTINOMIAL")); - params_fixed.insert(ParamsFixed(0x01DB, 1, L"LCM")); + params_fixed.insert(ParamsFixed(0x01DB, -1, L"LCM")); params_fixed.insert(ParamsFixed(0x01DC, 2, L"FVSCHEDULE")); params_fixed.insert(ParamsFixed(0x01DD, 3, L"CUBEKPIMEMBER")); params_fixed.insert(ParamsFixed(0x01DE, 1, L"CUBESET")); params_fixed.insert(ParamsFixed(0x01DF, 1, L"CUBESETCOUNT")); params_fixed.insert(ParamsFixed(0x01E0, 2, L"IFERROR")); - params_fixed.insert(ParamsFixed(0x01E1, 2, L"COUNTIFS")); + params_fixed.insert(ParamsFixed(0x01E1, -1, L"COUNTIFS")); params_fixed.insert(ParamsFixed(0x01E2, 3, L"SUMIFS")); params_fixed.insert(ParamsFixed(0x01E3, 2, L"AVERAGEIF")); params_fixed.insert(ParamsFixed(0x01E4, 3, L"AVERAGEIFS")); diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/FullColorExt.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/FullColorExt.cpp index 1c7f8b1194a..1dc16fc1779 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/FullColorExt.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/FullColorExt.cpp @@ -62,8 +62,14 @@ int FullColorExt::serialize(std::wostream & stream, const std::wstring &node_nam case 0: CP_XML_ATTR(L"auto", 1); break; case 1: CP_XML_ATTR(L"indexed", xclrValue); break; case 3: CP_XML_ATTR(L"theme", xclrValue); break; - default: - CP_XML_ATTR(L"rgb", xclrValue); break; + default: + { + BYTE r = GETBITS(xclrValue, 0, 7); + BYTE g = GETBITS(xclrValue, 8, 15); + BYTE b = GETBITS(xclrValue, 16, 23); + BYTE a = GETBITS(xclrValue, 24, 31); + CP_XML_ATTR(L"rgb", STR::toARGB(r, g, b, a)); + }break; } if (nTintShade != 0) { diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/FullColorExt.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/FullColorExt.h index e29191fc84c..d707b102fa8 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/FullColorExt.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/FullColorExt.h @@ -49,11 +49,11 @@ class FullColorExt : public BiffStructure virtual void load(CFRecord& record); int serialize(std::wostream & stream, const std::wstring &sNode); - static const ElementType type = typeFullColorExt; + static const ElementType type = typeFullColorExt; - unsigned short xclrType; - short nTintShade; - _UINT32 xclrValue; + unsigned short xclrType = 0; + short nTintShade = 0; + _UINT32 xclrValue = 0; }; } // namespace XLS diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/FutureFunctionParser.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/FutureFunctionParser.cpp new file mode 100644 index 00000000000..3c1bed7ce28 --- /dev/null +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/FutureFunctionParser.cpp @@ -0,0 +1,281 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2024 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ + +#include "FutureFunctionParser.h" +#include + +namespace XLS +{ + + const bool FutureFunctionParser::GetFutureFunction(std::wstring& functionName) + { + std::wstring tempName = functionName; + if(tempName.substr(0, 6) != L"_xlfn.") + { + tempName = L"_xlfn." + tempName; + } + auto functions = init(); + if(functions.FutureFunctions.find(tempName) != functions.FutureFunctions.end()) + { + functionName = tempName; + return true; + } + return false; + } + + std::vector FutureFunctionParser::GetArgumentList( const std::wstring& functionName) + { + std::vector argVector; + auto functions = init(); + auto findedFunc = functions.FutureFunctions.find(functionName); + if(findedFunc != functions.FutureFunctions.end()) + { + argVector = findedFunc->second; + } + return argVector; + } + + FutureFunctionParser& FutureFunctionParser::init() + { + static FutureFunctionParser parser; + return parser; + } + + FutureFunctionParser::FutureFunctionParser() + { + std::vector tempVector; + FutureFunctions.emplace (L"_xlfn.DAYS", std::vector{0,1,1}); + FutureFunctions.emplace(L"_xlfn.ACOT", std::vector{0, 1}); + FutureFunctions.emplace(L"_xlfn.ACOTH", std::vector{0, 1}); + FutureFunctions.emplace(L"_xlfn.AGGREGATE", std::vector{0, 1, 1, 1, 0}); + FutureFunctions.emplace(L"_xlfn.ARABIC", std::vector{0, 1}); + FutureFunctions.emplace(L"_xlfn.BASE", std::vector{0, 1, 1, 1}); + FutureFunctions.emplace(L"_xlfn.BETA.DIST", std::vector{0, 1, 1, 1, 1, 1, 1}); + FutureFunctions.emplace(L"_xlfn.BETA.INV", std::vector{0, 1, 1, 1, 1, 1}); + FutureFunctions.emplace(L"_xlfn.BINOM.DIST", std::vector{0, 1, 1, 1, 1}); + FutureFunctions.emplace(L"_xlfn.BINOM.DIST.RANGE", std::vector{0, 1, 1, 1, 1}); + FutureFunctions.emplace(L"_xlfn.BINOM.INV", std::vector{0, 1, 1, 1}); + FutureFunctions.emplace(L"_xlfn.BITAND", std::vector{0, 1, 1}); + FutureFunctions.emplace(L"_xlfn.BITLSHIFT", std::vector{0, 1, 1}); + FutureFunctions.emplace(L"_xlfn.BITOR", std::vector{0, 1, 1}); + FutureFunctions.emplace(L"_xlfn.BITRSHIFT", std::vector{0, 1, 1}); + FutureFunctions.emplace(L"_xlfn.BITXOR", std::vector{0, 1, 1}); + FutureFunctions.emplace(L"_xlfn.BYCOL", std::vector{0, 0, 0}); + FutureFunctions.emplace(L"_xlfn.BYROW", std::vector{0, 0, 0}); + FutureFunctions.emplace(L"_xlfn.CEILING.MATH", std::vector{0, 1, 1, 1}); + FutureFunctions.emplace(L"_xlfn.CEILING.PRECISE", std::vector{0, 1, 1}); + FutureFunctions.emplace(L"_xlfn.CHISQ.DIST", std::vector{0, 1, 1, 1}); + FutureFunctions.emplace(L"_xlfn.CHISQ.DIST.RT", std::vector{0, 1, 1}); + FutureFunctions.emplace(L"_xlfn.CHISQ.INV", std::vector{0, 1, 1}); + FutureFunctions.emplace(L"_xlfn.CHISQ.INV.RT", std::vector{0, 1, 1}); + FutureFunctions.emplace(L"_xlfn.CHISQ.TEST", std::vector{0, 1, 1}); + tempVector = std::vector{0}; + for (auto i = 0; i<508; i++) + { + tempVector.push_back(1); + } + FutureFunctions.emplace(L"_xlfn.CHOOSECOLS", tempVector); + FutureFunctions.emplace(L"_xlfn.CHOOSEROWS", tempVector); + FutureFunctions.emplace(L"_xlfn.COMBINA", std::vector{0, 1, 1}); + FutureFunctions.emplace(L"_xlfn.CONCAT", std::vector{0, 0}); + FutureFunctions.emplace(L"_xlfn.CONFIDENCE.NORM", std::vector{0, 1, 1, 1}); + FutureFunctions.emplace(L"_xlfn.CONFIDENCE.T", std::vector{0, 1, 1, 1}); + FutureFunctions.emplace(L"_xlfn.COT", std::vector{0, 1}); + FutureFunctions.emplace(L"_xlfn.COTH", std::vector{0, 1}); + FutureFunctions.emplace(L"_xlfn.COVARIANCE.P", std::vector{0, 1, 1}); + FutureFunctions.emplace(L"_xlfn.COVARIANCE.S", std::vector{0, 1, 1}); + FutureFunctions.emplace(L"_xlfn.CSC", std::vector{0, 1}); + FutureFunctions.emplace(L"_xlfn.CSCH", std::vector{0, 1}); + FutureFunctions.emplace(L"_xlfn.DECIMAL", std::vector{0, 1, 1}); + FutureFunctions.emplace(L"_xlfn.DROP", std::vector{0, 1, 1, 1, 1, 1, 1}); + FutureFunctions.emplace(L"_xlfn.ECMA.CEILING", std::vector{0, 1, 1}); + FutureFunctions.emplace(L"_xlfn.ERF.PRECISE", std::vector{0, 0}); + FutureFunctions.emplace(L"_xlfn.ERFC.PRECISE", std::vector{0, 0}); + FutureFunctions.emplace(L"_xlfn.EXPAND", std::vector{0, 1, 1, 1, 1, 1, 1, 1, 1}); + FutureFunctions.emplace(L"_xlfn.EXPON.DIST", std::vector{0, 1, 1, 1}); + FutureFunctions.emplace(L"_xlfn.F.DIST", std::vector{0, 1, 1, 1, 1}); + FutureFunctions.emplace(L"_xlfn.F.DIST.RT", std::vector{0, 1, 1, 1}); + FutureFunctions.emplace(L"_xlfn.F.INV", std::vector{0, 1, 1, 1}); + FutureFunctions.emplace(L"_xlfn.F.INV.RT", std::vector{0, 1, 1, 1}); + FutureFunctions.emplace(L"_xlfn.FIELDVALUE", std::vector{0, 1, 1}); + FutureFunctions.emplace(L"_xlfn.FILTERXML", std::vector{0, 1, 1}); + FutureFunctions.emplace(L"_xlfn.FLOOR.MATH", std::vector{0, 1, 1, 1}); + FutureFunctions.emplace(L"_xlfn.FLOOR.PRECISE", std::vector{0, 1, 1}); + FutureFunctions.emplace(L"_xlfn.FORMULATEXT", std::vector{0, 0}); + FutureFunctions.emplace(L"_xlfn.GAMMA", std::vector{0, 1}); + FutureFunctions.emplace(L"_xlfn.GAMMA.DIST", std::vector{0, 1, 1, 1, 1}); + FutureFunctions.emplace(L"_xlfn.GAMMA.INV", std::vector{0, 1, 1, 1}); + FutureFunctions.emplace(L"_xlfn.GAMMALN.PRECISE", std::vector{0, 1}); + FutureFunctions.emplace(L"_xlfn.GAUSS", std::vector{0, 1}); + tempVector = std::vector{0}; + for (auto i = 0; i<254; i++) + { + tempVector.push_back(1); + } + FutureFunctions.emplace(L"_xlfn.HSTACK", tempVector); + + FutureFunctions.emplace(L"_xlfn.HYPGEOM.DIST", std::vector{0, 1, 1, 1, 1, 1}); + FutureFunctions.emplace(L"_xlfn.IFNA", std::vector{0, 1, 0}); + tempVector = std::vector{0, 1, 0}; + for (auto i = 0; i<126; i++) + { + tempVector.push_back(1); + tempVector.push_back(0); + } + FutureFunctions.emplace(L"_xlfn.", std::vector{0, 1}); + FutureFunctions.emplace(L"_xlfn.IMCOSH", std::vector{0, 1}); + FutureFunctions.emplace(L"_xlfn.IMCOT", std::vector{0, 1}); + FutureFunctions.emplace(L"_xlfn.IMCSC", std::vector{0, 1}); + FutureFunctions.emplace(L"_xlfn.IMCSCH", std::vector{0, 1}); + FutureFunctions.emplace(L"_xlfn.IMSEC", std::vector{0, 1}); + FutureFunctions.emplace(L"_xlfn.IMSECH", std::vector{0, 1}); + FutureFunctions.emplace(L"_xlfn.IMSINH", std::vector{0, 1}); + FutureFunctions.emplace(L"_xlfn.IMTAN", std::vector{0, 1}); + FutureFunctions.emplace(L"_xlfn.ISFORMULA", std::vector{0, 0}); + FutureFunctions.emplace(L"_xlfn.ISO.CEILING", std::vector{0, 1, 1}); + FutureFunctions.emplace(L"_xlfn.ISOMITTED", std::vector{0, 0}); + FutureFunctions.emplace(L"_xlfn.ISOWEEKNUM", std::vector{0, 1}); + FutureFunctions.emplace(L"_xlfn.EXPON.DIST", std::vector{0, 1, 1, 1, 1}); + FutureFunctions.emplace(L"_xlfn.LOGNORM.INV", std::vector{0, 1, 1, 1}); + FutureFunctions.emplace(L"_xlfn.MAKEARRAY", std::vector{0, 0, 0, 0}); + FutureFunctions.emplace(L"_xlfn.MAP", std::vector{0, 0}); + tempVector = std::vector{0, 0, 0, 1}; + for (auto i = 0; i<125; i++) + { + tempVector.push_back(0); + tempVector.push_back(1); + } + FutureFunctions.emplace(L"_xlfn.MAXIFS", tempVector); + FutureFunctions.emplace(L"_xlfn.MINIFS", tempVector); + tempVector = std::vector{0}; + for (auto i = 0; i<254; i++) + { + tempVector.push_back(0); + tempVector.push_back(1); + } + FutureFunctions.emplace(L"_xlfn.MODE.MULT", tempVector); + FutureFunctions.emplace(L"_xlfn.MODE.SNGL", tempVector); + + FutureFunctions.emplace(L"_xlfn.MUNIT", std::vector{0, 1}); + FutureFunctions.emplace(L"_xlfn.NEGBINOM.DIST", std::vector{0, 1, 1, 1, 1}); + FutureFunctions.emplace(L"_xlfn.NETWORKDAYS.INTL", std::vector{0, 0, 0, 1, 0}); + FutureFunctions.emplace(L"_xlfn.NORM.DIST", std::vector{0, 1, 1, 1, 1}); + FutureFunctions.emplace(L"_xlfn.NORM.INV", std::vector{0, 1, 1, 1}); + FutureFunctions.emplace(L"_xlfn.NORM.S.DIST", std::vector{0, 1, 1}); + FutureFunctions.emplace(L"_xlfn.NORM.S.INV", std::vector{0, 1}); + FutureFunctions.emplace(L"_xlfn.NUMBERVALUE", std::vector{0, 1, 1, 1}); + FutureFunctions.emplace(L"_xlfn.PDURATION", std::vector{0, 1, 1, 1}); + FutureFunctions.emplace(L"_xlfn.PERCENTILE.EXC", std::vector{0, 0, 1}); + FutureFunctions.emplace(L"_xlfn.PERCENTILE.INC", std::vector{0, 0, 1}); + FutureFunctions.emplace(L"_xlfn.PERCENTRANK.EXC", std::vector{0, 0, 1, 1}); + FutureFunctions.emplace(L"_xlfn.PERCENTRANK.INC", std::vector{0, 0, 1, 1}); + FutureFunctions.emplace(L"_xlfn.PERMUTATIONA", std::vector{0, 1, 1}); + FutureFunctions.emplace(L"_xlfn.PHI", std::vector{0, 1}); + FutureFunctions.emplace(L"_xlfn.POISSON.DIST", std::vector{0, 1, 1, 1}); + FutureFunctions.emplace(L"_xlfn.PYTHON_STR", std::vector{0, 1}); + FutureFunctions.emplace(L"_xlfn.PYTHON_TYPE", std::vector{0, 1}); + FutureFunctions.emplace(L"_xlfn.PYTHON_TYPENAME", std::vector{0, 1}); + FutureFunctions.emplace(L"_xlfn.QUARTILE.EXC", std::vector{0, 0, 1}); + FutureFunctions.emplace(L"_xlfn.QUARTILE.INC", std::vector{0, 0, 1}); + tempVector = std::vector{0, 1, 1}; + for (auto i = 0; i<126; i++) + { + tempVector.push_back(1); + tempVector.push_back(1); + } + FutureFunctions.emplace(L"_xlfn.QUERYSTRING", tempVector); + FutureFunctions.emplace(L"_xlfn.RANDARRAY", std::vector{0, 1, 1, 1, 1, 1}); + FutureFunctions.emplace(L"_xlfn.RANK.AVG", std::vector{0, 1, 0, 1}); + FutureFunctions.emplace(L"_xlfn.RANK.EQ", std::vector{0, 1, 0, 1}); + FutureFunctions.emplace(L"_xlfn.RRI", std::vector{0, 1, 1, 1}); + FutureFunctions.emplace(L"_xlfn.SEC", std::vector{0, 1}); + FutureFunctions.emplace(L"_xlfn.SECH", std::vector{0, 1}); + FutureFunctions.emplace(L"_xlfn.SEQUENCE", std::vector{0, 1, 1, 1, 1}); + FutureFunctions.emplace(L"_xlfn.SHEET", std::vector{0, 0}); + FutureFunctions.emplace(L"_xlfn.SHEETS", std::vector{0, 0}); + FutureFunctions.emplace(L"_xlfn.SKEW.P", std::vector{0, 0}); + tempVector = std::vector{0, 1, 1, 1}; + for (auto i = 0; i<125; i++) + { + tempVector.push_back(1); + tempVector.push_back(1); + } + FutureFunctions.emplace(L"_xlfn.SORTBY", tempVector); + FutureFunctions.emplace(L"_xlfn.STDEV.P", std::vector{0, 0}); + FutureFunctions.emplace(L"_xlfn.STDEV.S", std::vector{0, 0}); + FutureFunctions.emplace(L"_xlfn.SWITCH", std::vector{0, 1, 0, 0}); + FutureFunctions.emplace(L"_xlfn.T.DIST", std::vector{0, 1, 1, 1}); + FutureFunctions.emplace(L"_xlfn.T.DIST.2T", std::vector{0, 1, 1}); + FutureFunctions.emplace(L"_xlfn.T.DIST.RT", std::vector{0, 1, 1}); + FutureFunctions.emplace(L"_xlfn.T.INV", std::vector{0, 1, 1}); + FutureFunctions.emplace(L"_xlfn.T.INV.2T", std::vector{0, 1, 1}); + FutureFunctions.emplace(L"_xlfn.T.TEST", std::vector{0, 1, 1, 1, 1}); + FutureFunctions.emplace(L"_xlfn.TAKE", std::vector{0, 1, 1, 1, 1, 1, 1}); + FutureFunctions.emplace(L"_xlfn.TEXTAFTER", std::vector{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}); + FutureFunctions.emplace(L"_xlfn.TEXTBEFORE", std::vector{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}); + FutureFunctions.emplace(L"_xlfn.TEXTJOIN", std::vector{0, 0, 1, 0}); + FutureFunctions.emplace(L"_xlfn.TEXTSPLIT", std::vector{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}); + FutureFunctions.emplace(L"_xlfn.TOCOL", std::vector{0, 1, 1, 1}); + FutureFunctions.emplace(L"_xlfn.TOROW", std::vector{0, 1, 1, 1}); + FutureFunctions.emplace(L"_xlfn.UNICHAR", std::vector{0, 1}); + FutureFunctions.emplace(L"_xlfn.UNICODE", std::vector{0, 1}); + FutureFunctions.emplace(L"_xlfn.UNIQUE", std::vector{0, 1, 1, 1}); + FutureFunctions.emplace(L"_xlfn.VAR.P", std::vector{0, 0, 0}); + FutureFunctions.emplace(L"_xlfn.VAR.S", std::vector{0, 0, 0}); + tempVector = std::vector{0}; + for (auto i = 0; i<254; i++) + { + tempVector.push_back(1); + } + FutureFunctions.emplace(L"_xlfn.VSTACK", std::vector{0, 1}); + FutureFunctions.emplace(L"_xlfn.WEBSERVICE", std::vector{0, 1, 1}); + FutureFunctions.emplace(L"_xlfn.WEIBULL.DIST", std::vector{0, 1, 1, 1, 1}); + FutureFunctions.emplace(L"_xlfn.WORKDAY.INTL", std::vector{0, 0, 1, 0}); + FutureFunctions.emplace(L"_xlfn.WRAPCOLS", std::vector{0, 1, 1, 1, 1, 1, 1}); + FutureFunctions.emplace(L"_xlfn.WRAPROWS", std::vector{0, 1, 1, 1, 1, 1, 1}); + FutureFunctions.emplace(L"_xlfn.XLOOKUP", std::vector{0, 1, 0, 0, 0, 1, 1}); + FutureFunctions.emplace(L"_xlfn.XOR", std::vector{0, 0, 0}); + FutureFunctions.emplace(L"_xlfn.Z.TEST", std::vector{0, 0, 1, 1}); + FutureFunctions.emplace(L"_xlfn.FORECAST.ETS", std::vector{0, 1, 0, 0, 1, 1, 1}); + FutureFunctions.emplace(L"_xlfn.", std::vector{0, 1}); + FutureFunctions.emplace(L"_xlfn.FORECAST.ETS.CONFINT", std::vector{0, 0, 0, 1, 1}); + FutureFunctions.emplace(L"_xlfn.FORECAST.ETS.SEASONALITY", std::vector{0, 0, 0, 1, 1}); + FutureFunctions.emplace(L"_xlfn.FORECAST.ETS.STAT", std::vector{0, 1, 0, 0, 1, 1, 1}); + FutureFunctions.emplace(L"_xlfn.FORECAST.LINEAR", std::vector{0, 1, 1, 1}); + + FutureFunctions.emplace(L"_xlfn.PQSOURCE", std::vector{0, 1}); + FutureFunctions.emplace(L"_xlfn.LET", std::vector{0, 0, 0, 0}); + FutureFunctions.emplace(L"_xlfn.LAMBDA", std::vector{0, 0, 0, 0}); + + } + +} // namespace XLS diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/FutureFunctionParser.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/FutureFunctionParser.h new file mode 100644 index 00000000000..edd993fbaf3 --- /dev/null +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/FutureFunctionParser.h @@ -0,0 +1,57 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2024 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ + +#pragma once + +#include +#include +#include + +namespace XLS +{ + + +class FutureFunctionParser +{ +public: + static const bool GetFutureFunction(std::wstring& functionName); + static std::vector GetArgumentList( const std::wstring& functionName); + +private: + FutureFunctionParser(); + static FutureFunctionParser& init(); + std::map> FutureFunctions; + +}; + + +} // namespace XLS \ No newline at end of file diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ListParsedFormula.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ListParsedFormula.cpp index 24d9e811307..e0b11daa652 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ListParsedFormula.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ListParsedFormula.cpp @@ -31,6 +31,7 @@ */ #include "ListParsedFormula.h" +#include "PtgList.h" namespace XLS { @@ -42,6 +43,19 @@ ListParsedFormula::ListParsedFormula() : ParsedFormula(CellRef()) ListParsedFormula& ListParsedFormula::operator=(const std::wstring& value) { ParsedFormula::operator = (value); + if(!rgce.sequence.empty()) + { + auto lastValType = GETBITS(rgce.sequence.rbegin()->get()->ptg_id.get(),5,6); + if(lastValType == 1 || lastValType == 3) + { + SETBITS(rgce.sequence.rbegin()->get()->ptg_id.get(),5,6,2); + } + else if(rgce.sequence.rbegin()->get()->ptg_id.get() == 6424) + { + auto list = static_cast(rgce.sequence.rbegin()->get()); + list->type_ = 1; + } + } return *this; } @@ -127,6 +141,19 @@ ListParsedArrayFormula::ListParsedArrayFormula() : ArrayParsedFormula(false, Cel ListParsedArrayFormula& ListParsedArrayFormula::operator=(const std::wstring& value) { ArrayParsedFormula::operator = (value); + if(!rgce.sequence.empty()) + { + auto lastValType = GETBITS(rgce.sequence.rbegin()->get()->ptg_id.get(),5,6); + if(lastValType == 1 || lastValType == 3) + { + SETBITS(rgce.sequence.rbegin()->get()->ptg_id.get(),5,6,2); + } + else if(rgce.sequence.rbegin()->get()->ptg_id.get() == 6424) + { + auto list = static_cast(rgce.sequence.rbegin()->get()); + list->type_ = 1; + } + } return *this; } diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/MOper.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/MOper.cpp index 914b1612d0e..5a06a1d3504 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/MOper.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/MOper.cpp @@ -45,15 +45,21 @@ void MOper::load(CFRecord& record) { record >> colLast >> rowLast; - for(int i = 0; i < (colLast + 1) * (rowLast + 1); ++i) + for (int i = 0; i < (colLast + 1) * (rowLast + 1); ++i) { unsigned char rec_type; record >> rec_type; SerArPtr ser(SerAr::createSerAr(rec_type)); - record >> *ser; - - extOper.push_back(ser); + if (ser) + { + record >> *ser; + extOper.push_back(ser); + } + else + { + break; + } } } diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ODRAW/OfficeArtBStoreContainerFileBlock.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ODRAW/OfficeArtBStoreContainerFileBlock.cpp index bde4c2d8e55..f942807ce30 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ODRAW/OfficeArtBStoreContainerFileBlock.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ODRAW/OfficeArtBStoreContainerFileBlock.cpp @@ -106,68 +106,68 @@ void OfficeArtBStoreContainerFileBlock::load(XLS::CFRecord& record) switch (rc_header.recType) { case OfficeArtRecord::BlipEMF: + { + pict_type = L".emf"; + if (rc_header.recInstance == 0x3D4) + rgbUid1 = ReadMD4Digest(record); + else { - pict_type = L".emf"; - if (rc_header.recInstance == 0x3D4) - rgbUid1 = ReadMD4Digest(record); - else - { - rgbUid1 = ReadMD4Digest(record); - rgbUid2 = ReadMD4Digest(record); - } + rgbUid1 = ReadMD4Digest(record); + rgbUid2 = ReadMD4Digest(record); + } - OfficeArtMetafileHeader metafileHeader; - record >> metafileHeader; + OfficeArtMetafileHeader metafileHeader; + record >> metafileHeader; - if (metafileHeader.compression == 0) - { - isCompressed = true; - readCompressedData(record, metafileHeader); - } + if (metafileHeader.compression == 0) + { + isCompressed = true; + readCompressedData(record, metafileHeader); } - break; + } + break; case OfficeArtRecord::BlipWMF: + { + pict_type = L".wmf"; + if (rc_header.recInstance == 0x216) + rgbUid1 = ReadMD4Digest(record); + else { - pict_type = L".wmf"; - if (rc_header.recInstance == 0x216) - rgbUid1 = ReadMD4Digest(record); - else - { - rgbUid1 = ReadMD4Digest(record); - rgbUid2 = ReadMD4Digest(record); - } + rgbUid1 = ReadMD4Digest(record); + rgbUid2 = ReadMD4Digest(record); + } - OfficeArtMetafileHeader metafileHeader; - record >> metafileHeader; + OfficeArtMetafileHeader metafileHeader; + record >> metafileHeader; - if (metafileHeader.compression == 0) - { - isCompressed = true; - readCompressedData(record, metafileHeader); - } + if (metafileHeader.compression == 0) + { + isCompressed = true; + readCompressedData(record, metafileHeader); } - break; + } + break; case OfficeArtRecord::BlipPICT: + { + pict_type = L".pcz"; + if (rc_header.recInstance == 0x542) + rgbUid1 = ReadMD4Digest(record); + else { - pict_type = L".pcz"; - if (rc_header.recInstance == 0x542) - rgbUid1 = ReadMD4Digest(record); - else - { - rgbUid1 = ReadMD4Digest(record); - rgbUid2 = ReadMD4Digest(record); - } + rgbUid1 = ReadMD4Digest(record); + rgbUid2 = ReadMD4Digest(record); + } - OfficeArtMetafileHeader metafileHeader; - record >> metafileHeader; + OfficeArtMetafileHeader metafileHeader; + record >> metafileHeader; - if (metafileHeader.compression == 0) - { - isCompressed = true; - readCompressedData(record, metafileHeader); - } + if (metafileHeader.compression == 0) + { + isCompressed = true; + readCompressedData(record, metafileHeader); } - break; + } + break; case OfficeArtRecord::BlipJPEG: pict_type = L".jpeg"; if ((rc_header.recInstance == 0x46A) || (rc_header.recInstance == 0x6E2)) @@ -232,7 +232,12 @@ void OfficeArtBStoreContainerFileBlock::load(XLS::CFRecord& record) record.RollRdPtrBack(32); } break; - default: + case 0xf018: + { + record.skipNunBytes(rc_header.recLen); + return; + }break; + default: //0xf007 record.RollRdPtrBack(rc_header.size()); return; } diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ODRAW/OfficeArtContainer.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ODRAW/OfficeArtContainer.h index c23debe0b8f..107dbe65c3e 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ODRAW/OfficeArtContainer.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ODRAW/OfficeArtContainer.h @@ -54,8 +54,8 @@ class OfficeArtContainer : public OfficeArtRecord static OfficeArtRecordPtr loadAnyArtRecord(XLS::CFRecord& record); - OfficeArtClientAnchorType anchor_type_; - std::vector child_records; + OfficeArtClientAnchorType anchor_type_; + std::vector child_records; private: OfficeArtRecordPtr CreateOfficeArt(unsigned short type); diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ODRAW/OfficeArtDgContainer.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ODRAW/OfficeArtDgContainer.cpp index 56c357fc644..8e858ffb725 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ODRAW/OfficeArtDgContainer.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ODRAW/OfficeArtDgContainer.cpp @@ -86,9 +86,14 @@ void OfficeArtDgContainer::loadFields(XLS::CFRecord& record) for (size_t i = 0 ; i < child_records.size(); i++) { + //Log::warning("ArtRecord : " + STR::int2str(child_records[i]->rh_own.recType, 16)); + switch(child_records[i]->rh_own.recType) { - case ODRAW::OfficeArtRecord::DgContainer: + case ODRAW::OfficeArtRecord::DggContainer: + { + }break; + case ODRAW::OfficeArtRecord::DgContainer: { OfficeArtDgContainer * dg = dynamic_cast(child_records[i].get()); if (dg) @@ -107,22 +112,22 @@ void OfficeArtDgContainer::loadFields(XLS::CFRecord& record) } child_records.erase(child_records.begin() + i, child_records.begin() + i + 1); i--; }break; - case ODRAW::OfficeArtRecord::FDG: + case ODRAW::OfficeArtRecord::FDG: { m_OfficeArtFDG = child_records[i]; child_records.erase(child_records.begin() + i, child_records.begin() + i + 1); i--; }break; - case ODRAW::OfficeArtRecord::FRITContainer: + case ODRAW::OfficeArtRecord::FRITContainer: { m_OfficeArtFRITContainer = child_records[i]; child_records.erase(child_records.begin() + i, child_records.begin() + i + 1); i--; }break; - case ODRAW::OfficeArtRecord::SpgrContainer: + case ODRAW::OfficeArtRecord::SpgrContainer: { m_OfficeArtSpgrContainer = child_records[i]; child_records.erase(child_records.begin() + i, child_records.begin() + i + 1); i--; }break; - case ODRAW::OfficeArtRecord::SpContainer: + case ODRAW::OfficeArtRecord::SpContainer: { m_OfficeArtSpContainer.push_back(child_records[i]); child_records.erase(child_records.begin() + i,child_records.begin() + i + 1); i--; @@ -132,8 +137,8 @@ void OfficeArtDgContainer::loadFields(XLS::CFRecord& record) // m_OfficeArtSpgrContainerFileBlock = OfficeArtContainerPtr(art_container); // child_records.erase(child_records.begin() + i,child_records.begin() + i + 1); // }break; - default: - break; + default: + break; } } diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ODRAW/OfficeArtDgContainer.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ODRAW/OfficeArtDgContainer.h index 9da95fb4b47..fbf36357169 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ODRAW/OfficeArtDgContainer.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ODRAW/OfficeArtDgContainer.h @@ -52,7 +52,7 @@ class OfficeArtDgContainer : public OfficeArtContainer static const bool CheckIfContainerStartFound(XLS::CFRecord& record); static const bool CheckIfContainerSizeOK(XLS::CFRecord& record); - static const XLS::ElementType type = XLS::typeOfficeArtDgContainer; + static const XLS::ElementType type = XLS::typeOfficeArtDgContainer; void loadFields(XLS::CFRecord& record); diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ODRAW/OfficeArtFOPTE.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ODRAW/OfficeArtFOPTE.cpp index c0015b22e93..64994ee8e1d 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ODRAW/OfficeArtFOPTE.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ODRAW/OfficeArtFOPTE.cpp @@ -1275,24 +1275,28 @@ void MSOPATHINFO::load(IBinaryReader* reader) case 0x09: { m_eRuler = ODRAW::rtQuadrBesier; - break; - } + + }break; case 0x0A: { m_eRuler = ODRAW::rtNoFill; - break; - } + + }break; case 0x0B: { m_eRuler = ODRAW::rtNoStroke; - break; - } - case 0x0C: - case 0x10: + + }break; + case 0x0C: //msopathEscapeAutoLine { m_eRuler = ODRAW::rtLineTo; - break; - } + mem = 2; + }break; + case 0x10: // msopathEscapeSmoothLine + { + m_eRuler = ODRAW::rtLineTo; + + }break; case 0x0D: case 0x0E: case 0x0F: @@ -1301,9 +1305,8 @@ void MSOPATHINFO::load(IBinaryReader* reader) case 0x13: case 0x14: { - m_eRuler = ODRAW::rtCurveTo; - break; - } + m_eRuler = ODRAW::rtCurveTo; + }break; case 0x15: { m_eRuler = ODRAW::rtFillColor; @@ -1504,6 +1507,9 @@ XLS::BiffStructurePtr ADJH::clone() void ADJH::load(IBinaryReader* reader) { + unsigned long pos = reader->GetPosition(); + unsigned long pos_end = reader->GetPosition() + cbElement; + _UINT32 flag = reader->ReadUInt32(); fahInverseX = GETBIT(flag, 31); @@ -1549,6 +1555,8 @@ void ADJH::load(IBinaryReader* reader) if (fahxMax) xMax = reader->ReadInt16(); if (fahyMin) yMin = reader->ReadInt16(); if (fahyMax) yMax = reader->ReadInt16(); + + reader->Seek(pos_end, 0); } void ADJH::load(XLS::CFRecord& record) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ODRAW/SimpleOfficeArtContainers.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ODRAW/SimpleOfficeArtContainers.cpp index 9bd730ffcb1..eb32e155408 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ODRAW/SimpleOfficeArtContainers.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ODRAW/SimpleOfficeArtContainers.cpp @@ -71,31 +71,42 @@ void OfficeArtSolverContainer::loadFields(XLS::CFRecord& record) void OfficeArtDggContainer::loadFields(XLS::CFRecord& record) { OfficeArtContainer::loadFields(record); - - for (size_t i = 0 ; i < child_records.size(); i++) + + for (size_t i = 0; i < child_records.size(); i++) { - switch(child_records[i]->rh_own.recType) + switch (child_records[i]->rh_own.recType) { - case ODRAW::OfficeArtRecord::BStoreContainer: + case ODRAW::OfficeArtRecord::DggContainer: + { + OfficeArtDggContainer* dggContainer = dynamic_cast(child_records[i].get()); + if (dggContainer) { - m_OfficeArtBStoreContainer = child_records[i]; - child_records.erase(child_records.begin() + i,child_records.begin() + i + 1); i--; - }break; + if (!m_OfficeArtBStoreContainer) m_OfficeArtBStoreContainer = dggContainer->m_OfficeArtBStoreContainer; + if (!m_OfficeArtColorMRUContainer) m_OfficeArtColorMRUContainer = dggContainer->m_OfficeArtColorMRUContainer; + if (!m_OfficeArtSplitMenuColorContainer) m_OfficeArtSplitMenuColorContainer = dggContainer->m_OfficeArtSplitMenuColorContainer; + if (!m_OfficeArtFDGGBlock) m_OfficeArtFDGGBlock = dggContainer->m_OfficeArtFDGGBlock; + } + }break; + case ODRAW::OfficeArtRecord::BStoreContainer: + { + m_OfficeArtBStoreContainer = child_records[i]; + child_records.erase(child_records.begin() + i, child_records.begin() + i + 1); i--; + }break; case ODRAW::OfficeArtRecord::ColorMRUContainer: - { - m_OfficeArtColorMRUContainer = child_records[i]; - child_records.erase(child_records.begin() + i,child_records.begin() + i + 1); i--; - }break; + { + m_OfficeArtColorMRUContainer = child_records[i]; + child_records.erase(child_records.begin() + i, child_records.begin() + i + 1); i--; + }break; case ODRAW::OfficeArtRecord::SplitMenuColorContainer: - { - m_OfficeArtSplitMenuColorContainer = child_records[i]; - child_records.erase(child_records.begin() + i,child_records.begin() + i + 1); i--; - }break; + { + m_OfficeArtSplitMenuColorContainer = child_records[i]; + child_records.erase(child_records.begin() + i, child_records.begin() + i + 1); i--; + }break; case ODRAW::OfficeArtRecord::FDGGBlock: - { - m_OfficeArtFDGGBlock = child_records[i]; - child_records.erase(child_records.begin() + i,child_records.begin() + i + 1); i--; - }break; + { + m_OfficeArtFDGGBlock = child_records[i]; + child_records.erase(child_records.begin() + i, child_records.begin() + i + 1); i--; + }break; //case ODRAW::OfficeArtRecord::SpgrContainerFileBlock: // { // m_OfficeArtSpgrContainerFileBlock = OfficeArtContainerPtr(art_container); diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ODRAW/SimpleOfficeArtContainers.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ODRAW/SimpleOfficeArtContainers.h index 59d043aabf4..b750b652dd7 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ODRAW/SimpleOfficeArtContainers.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ODRAW/SimpleOfficeArtContainers.h @@ -43,14 +43,18 @@ class OfficeArtDggContainer : public OfficeArtContainer OfficeArtDggContainer(const OfficeArtClientAnchorType anchor_type) : OfficeArtContainer(0x0F, DggContainer, anchor_type) {} XLS::BiffStructurePtr clone() { return XLS::BiffStructurePtr(new OfficeArtDggContainer(*this)); } + static const XLS::ElementType type = XLS::typeOfficeArtDggContainer; + void loadFields(XLS::CFRecord& record); OfficeArtRecordPtr m_OfficeArtBStoreContainer; OfficeArtRecordPtr m_OfficeArtColorMRUContainer; OfficeArtRecordPtr m_OfficeArtSplitMenuColorContainer; OfficeArtRecordPtr m_OfficeArtFDGGBlock; + //+ OfficeArtFOPT + OfficeArtTertiaryFOPT }; +typedef boost::shared_ptr OfficeArtDggContainerPtr; class OfficeArtSpgrContainer : public OfficeArtContainer { @@ -61,9 +65,9 @@ class OfficeArtSpgrContainer : public OfficeArtContainer void loadFields(XLS::CFRecord& record); - static const XLS::ElementType type = XLS::typeOfficeArtSpgrContainer; + static const XLS::ElementType type = XLS::typeOfficeArtSpgrContainer; - std::vector m_OfficeArtSpgrContainerFileBlock; + std::vector m_OfficeArtSpgrContainerFileBlock; }; class OfficeArtSolverContainer : public OfficeArtRecord diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/Ptg.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/Ptg.cpp index 0e14f130b30..240ed8b59d5 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/Ptg.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/Ptg.cpp @@ -61,7 +61,10 @@ const size_t Ptg::getSizeOfStruct() const void Ptg::addFuncWrapper(AssemblerStack& ptg_stack, const std::wstring& func_name) { - ptg_stack.top() = func_name + L'(' + ptg_stack.top() + L')'; + if (false == ptg_stack.empty()) + { + ptg_stack.top() = func_name + L'(' + ptg_stack.top() + L')'; + } } void Ptg::assemble(AssemblerStack& ptg_stack, PtgQueue& extra_data, bool full_ref) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgArea.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgArea.cpp index 82067026678..04502bede0f 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgArea.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgArea.cpp @@ -148,7 +148,10 @@ void PtgArea::assemble(AssemblerStack& ptg_stack, PtgQueue& extra_data, bool ful } } } - ptg_stack.push(range.toString()); + if(global_info->Version < 0x0800) + ptg_stack.push(range.toString()); + else + ptg_stack.push(range.toString(true, true)); } diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgArea3d.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgArea3d.cpp index c30bc9c4a11..c66cc962d98 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgArea3d.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgArea3d.cpp @@ -153,7 +153,7 @@ void PtgArea3d::assemble(AssemblerStack& ptg_stack, PtgQueue& extra_data, bool f if(global_info->Version < 0x0800) range_ref = area.toString(); else - range_ref = areaXlsb.toString(); + range_ref = areaXlsb.toString(true, true); if (global_info->Version < 0x0600) { @@ -161,7 +161,8 @@ void PtgArea3d::assemble(AssemblerStack& ptg_stack, PtgQueue& extra_data, bool f if (ixals == 0xffff) { std::wstring strRange; - if(-1 == itabFirst) + if(-1 == itabFirst || global_info->sheets_info.size() <= itabFirst + || global_info->sheets_info.size() <= itabLast) { strRange = L"#REF"; } diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgAreaN.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgAreaN.cpp index 7bacafb091c..4d07224ec8f 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgAreaN.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgAreaN.cpp @@ -95,7 +95,6 @@ void PtgAreaN::loadFields(CFRecord& record) { record >> area; } - else { record >> areaXlsb; @@ -142,7 +141,7 @@ void PtgAreaN::assemble(AssemblerStack& ptg_stack, PtgQueue& extra_data, bool fu else { - ptg_stack.push((areaXlsb + cell_base_ref).toString()); + ptg_stack.push((areaXlsb + cell_base_ref).toString(true, true)); } } diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgArray.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgArray.cpp index 009c055daa5..32ab12c28a1 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgArray.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgArray.cpp @@ -55,7 +55,7 @@ void PtgArray::loadFields(CFRecord& record) if (record.getGlobalWorkbookInfo()->Version < 0x0800) record.skipNunBytes(7); // unused else - record.skipNunBytes(16); // unused + record.skipNunBytes(14); // unused } void PtgArray::writeFields(CFRecord& record) @@ -63,7 +63,7 @@ void PtgArray::writeFields(CFRecord& record) if (record.getGlobalWorkbookInfo()->Version < 0x0800) record.reserveNunBytes(7); // unused else - record.reserveNunBytes(16); // unused + record.reserveNunBytes(14); // unused } void PtgArray::assemble(AssemblerStack& ptg_stack, PtgQueue& extra_data, bool full_ref) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgErr.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgErr.cpp index ebf02c69898..48691468f28 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgErr.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgErr.cpp @@ -57,6 +57,10 @@ void PtgErr::loadFields(CFRecord& record) record >> err; } +void PtgErr::writeFields(CFRecord& record) +{ + record << err; +} void PtgErr::assemble(AssemblerStack& ptg_stack, PtgQueue& extra_data, bool full_ref) { diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgErr.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgErr.h index b83569a1a65..4abd32527d4 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgErr.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgErr.h @@ -49,6 +49,7 @@ class PtgErr: public OperandPtg virtual void loadFields(CFRecord& record); + void writeFields(CFRecord& record) override; virtual void assemble(AssemblerStack& ptg_stack, PtgQueue& extra_data, bool full_ref = false); diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgExp.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgExp.h index ef52ce58607..affb820df73 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgExp.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgExp.h @@ -53,7 +53,6 @@ class PtgExp : public Ptg static const unsigned short fixed_id = 0x01; -private: unsigned short row; unsigned short col; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgExtraArray.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgExtraArray.cpp index 62fa36eff86..3e6c96cea67 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgExtraArray.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgExtraArray.cpp @@ -60,6 +60,8 @@ BiffStructurePtr PtgExtraArray::clone() void PtgExtraArray::load(CFRecord& record) { + auto tempcols = 0; + auto temprows = 0; if (record.getGlobalWorkbookInfo()->Version < 0x0800) { DColunByteU cols_xls; @@ -67,17 +69,41 @@ void PtgExtraArray::load(CFRecord& record) record >> cols_xls >> rows_xls; cols = cols_xls; rows = rows_xls; + tempcols = cols_xls+1; + temprows = rows_xls+1; } else { record >> cols >> rows; + tempcols = cols; + temprows = rows; } - for(int i = 0; i < (cols + 1) * (rows + 1); ++i) + for(int i = 0; i < (tempcols) * (temprows); ++i) { if (record.getRdPtr() >= record.getDataSize()) break; unsigned char rec_type; record >> rec_type; + if (record.getGlobalWorkbookInfo()->Version >= 0x0800) + { + switch(rec_type) + { + case 0: + rec_type = SerAr::SerType::typeSerNum; + break; + case 1: + rec_type = SerAr::SerType::typeSerStr; + break; + case 2: + rec_type = SerAr::SerType::typeSerBool; + case 4: + rec_type = SerAr::SerType::typeSerErr; + break; + default: + rec_type = SerAr::SerType::typeSerNil; + break; + } + } SerArPtr ser(SerAr::createSerAr(rec_type)); if(ser.get()) { @@ -99,7 +125,9 @@ void PtgExtraArray::save(CFRecord& record) } else { - record << cols << rows; + cols++; + rows++; + record << rows << cols; } for (auto& item : array_) { @@ -110,7 +138,7 @@ void PtgExtraArray::save(CFRecord& record) const std::wstring PtgExtraArray::toString() const { std::wstring ret_val; - unsigned char col_cnt = cols + 1; + unsigned char col_cnt = cols + 1; if (array_.empty()) return L""; @@ -124,7 +152,7 @@ const std::wstring PtgExtraArray::toString() const else { ret_val += L';'; - col_cnt = cols + 1; + col_cnt = cols + 1; } } ret_val += array_.back()->toString(); diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgExtraCol.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgExtraCol.h index 7f9325f4a56..64cce73f710 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgExtraCol.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgExtraCol.h @@ -52,7 +52,7 @@ class PtgExtraCol : public Ptg // No type info const std::wstring toString() const; -private: + _INT32 col; }; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgExtraList.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgExtraList.h index 40ce1835033..ec82394d59e 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgExtraList.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgExtraList.h @@ -54,7 +54,7 @@ class PtgExtraList : public Ptg // No type info const std::wstring toString() const; -private: + Boolean hasColumns; unsigned char rowType; _UINT16 cch; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgFunc.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgFunc.cpp index ae940a2ec07..336b550962b 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgFunc.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgFunc.cpp @@ -103,6 +103,10 @@ const int PtgFunc::getParametersNum() const return iftab.getParamsNum(); } +const unsigned short PtgFunc::getFuncIndex() const +{ + return iftab.getIndex(); +} } // namespace XLS diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgFunc.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgFunc.h index 88762941bba..5bf52a2e646 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgFunc.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgFunc.h @@ -57,6 +57,8 @@ class PtgFunc : public OperandPtg const int getParametersNum() const; + const unsigned short getFuncIndex() const; + static const unsigned short fixed_id = 0x01; private: Ftab_Cetab iftab; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgFuncVar.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgFuncVar.cpp index e3017e2122a..8dc5ad0342c 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgFuncVar.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgFuncVar.cpp @@ -58,7 +58,7 @@ void PtgFuncVar::loadFields(CFRecord& record) { global_info_ = record.getGlobalWorkbookInfo(); - global_info_->bMacrosExist = true; + //global_info_->bMacrosExist = true; record >> cparams; record.loadAnyData(tab); @@ -69,8 +69,6 @@ void PtgFuncVar::writeFields(CFRecord& record) { global_info_ = record.getGlobalWorkbookInfo(); - global_info_->bMacrosExist = true; - record << cparams; record.storeAnyData(tab); } @@ -112,6 +110,8 @@ void PtgFuncVar::assemble(AssemblerStack& ptg_stack, PtgQueue& extra_data, bool func_name == L"YEARS") { func_name = L"_xll." + func_name; + + global_info_->bMacrosExist = true; } ptg_stack.pop(); } @@ -144,6 +144,34 @@ void PtgFuncVar::setParamsNum(const unsigned char num) } } +const unsigned char PtgFuncVar::getParamsNum() +{ + return cparams; +} + +const bool PtgFuncVar::getFCeFunc() +{ + return fCeFunc; +} + +const unsigned short PtgFuncVar::getFuncIndex() const +{ + return tab.getIndex(); +} + + +const std::wstring PtgFuncVar::getFutureFuncName() const +{ + if(futureFuncName.has_value()) + { + return futureFuncName.get(); + } + return L""; +} +void PtgFuncVar::setFutureFuncName(std::wstring name) +{ + futureFuncName = name; +} } // namespace XLS diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgFuncVar.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgFuncVar.h index e1680a9ebd1..8832e06b26d 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgFuncVar.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgFuncVar.h @@ -58,12 +58,21 @@ class PtgFuncVar : public OperandPtg void setParamsNum(const unsigned char num); + const unsigned char getParamsNum(); + + const bool getFCeFunc(); + + const unsigned short getFuncIndex() const; + + const std::wstring getFutureFuncName() const; + void setFutureFuncName(std::wstring name); + static const unsigned short fixed_id = 0x02; private: unsigned char cparams; Ftab_Cetab tab; bool fCeFunc; - + _CP_OPT(std::wstring) futureFuncName; GlobalWorkbookInfoPtr global_info_; }; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgList.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgList.cpp index fae7a7ed1cd..de5983cc906 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgList.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgList.cpp @@ -31,6 +31,7 @@ */ #include "PtgList.h" +#include "PtgExtraList.h" #include "../../../../../OOXML/Base/Unit.h" namespace XLS @@ -98,6 +99,11 @@ void PtgList::assemble(AssemblerStack& ptg_stack, PtgQueue& extra_data, bool ful { tableName = tableIndex->second; } + else if(nonresident && !extra_data.empty()) + { + auto extraList = static_cast(extra_data.front().get()); + tableName = extraList->table; + } else { tableName = XmlUtils::GenerateGuid(); @@ -117,7 +123,6 @@ void PtgList::assemble(AssemblerStack& ptg_stack, PtgQueue& extra_data, bool ful { switch (rowType) { - case 0x00: case 0x04: formula += L"[#Data]"; break; case 0x01: formula += L"[#All]"; break; case 0x02: formula += L"[#Headers]"; break; @@ -135,7 +140,14 @@ void PtgList::assemble(AssemblerStack& ptg_stack, PtgQueue& extra_data, bool ful case 0x00: break; case 0x01: case 0x02: - formula += L",['" + arrColumn->second[colFirst] + L"]"; if(columns == 0x01) break; + if(colFirst >= arrColumn->second.size()) + break; + if(rowType != 0x00) + formula += L","; + formula += L"['" + arrColumn->second[colFirst] + L"]"; + if(columns == 0x01) break; + if(colLast >= arrColumn->second.size()) + break; formula += L":[" + arrColumn->second[colLast] + L"]"; break; } } diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgName.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgName.cpp index 6bf66b4a28e..5c695229e0b 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgName.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgName.cpp @@ -80,7 +80,7 @@ void PtgName::writeFields(CFRecord& record) { record.reserveNunBytes(12); } - else + else if(record.getGlobalWorkbookInfo()->Version < 0x0800 ) { record.reserveNunBytes(2); } @@ -102,7 +102,7 @@ void PtgName::assemble(AssemblerStack& ptg_stack, PtgQueue& extra_data, bool ful std::wstring ptg; - if ((global_info) && (nameindex <= global_info->arDefineNames.size())) + if ((global_info) && (nameindex <= global_info->arDefineNames.size()) && nameindex) { ptg = global_info->arDefineNames[nameindex-1]; } diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgNameX.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgNameX.cpp index 3628c065a63..547e7bd2c9d 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgNameX.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgNameX.cpp @@ -126,7 +126,7 @@ void PtgNameX::assemble(AssemblerStack& ptg_stack, PtgQueue& extra_data, bool fu } if (name.empty()) { - if (nameindex <= global_info->arDefineNames.size()) + if (global_info && nameindex && nameindex <= global_info->arDefineNames.size()) { name = global_info->arDefineNames[nameindex - 1]; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgParen.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgParen.cpp index 23e26495310..adceb38459e 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgParen.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgParen.cpp @@ -51,7 +51,8 @@ BiffStructurePtr PtgParen::clone() void PtgParen::assemble(AssemblerStack& ptg_stack, PtgQueue& extra_data, bool full_ref) { - ptg_stack.top() = L'(' + ptg_stack.top() + L')'; + if(!ptg_stack.empty()) + ptg_stack.top() = L'(' + ptg_stack.top() + L')'; } diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgRef.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgRef.cpp index c598e654317..277ab3696fa 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgRef.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgRef.cpp @@ -113,7 +113,7 @@ void PtgRef::assemble(AssemblerStack& ptg_stack, PtgQueue& extra_data, bool full } else { - ptg_stack.push(loc_xlsb.toString()); + ptg_stack.push(loc_xlsb.toString(true)); } } diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgRef.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgRef.h index a10b730b563..fae265d3640 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgRef.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgRef.h @@ -56,7 +56,7 @@ class PtgRef: public OperandPtg static const unsigned short fixed_id = 0x04; -private: + RgceLoc loc; XLSB::RgceLoc loc_xlsb; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgRef3d.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgRef3d.cpp index c035265ac9b..b1f1a9b0045 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgRef3d.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgRef3d.cpp @@ -147,7 +147,7 @@ void PtgRef3d::assemble(AssemblerStack& ptg_stack, PtgQueue& extra_data, bool fu } else { - cell_ref = rgce_loc_xlsb.toString(); + cell_ref = rgce_loc_xlsb.toString(true); } if (global_info->Version < 0x0600) @@ -160,10 +160,10 @@ void PtgRef3d::assemble(AssemblerStack& ptg_stack, PtgQueue& extra_data, bool fu { strRange = L"#REF"; } - else + else if(global_info->sheets_info.size() > itabFirst) { strRange = XMLSTUFF::name2sheet_name(global_info->sheets_info[itabFirst].name, L""); - if (itabFirst != itabLast) + if (itabFirst != itabLast && global_info->sheets_info.size() > itabLast) { strRange += std::wstring(L":") + XMLSTUFF::name2sheet_name(global_info->sheets_info[itabLast].name, L""); } diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgRefErr3d.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgRefErr3d.cpp index 27a0749a50b..98747d53de4 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgRefErr3d.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgRefErr3d.cpp @@ -91,7 +91,7 @@ void PtgRefErr3d::assemble(AssemblerStack& ptg_stack, PtgQueue& extra_data, bool return; } - if (ixti != 0xffff) + if (ixti != 0xffff && global_info->arXti_External.size() > ixti) { std::wstring link = global_info->arXti_External[ixti].link; if (!link.empty()) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgRefN.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgRefN.cpp index 1bf92087bd9..bc133fd809d 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgRefN.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgRefN.cpp @@ -48,6 +48,7 @@ PtgRefN::PtgRefN(const std::wstring& word, const PtgDataType data_type, const Ce cell_base_ref(cell_base_ref_init) { loc -= cell_base_ref; + loc_xlsb -= cell_base_ref; bUseLocInit = true; } @@ -132,7 +133,7 @@ void PtgRefN::assemble(AssemblerStack& ptg_stack, PtgQueue& extra_data, bool ful } else { - ptg_stack.push((loc_xlsb + cell_base_ref).toString()); + ptg_stack.push((loc_xlsb + cell_base_ref).toString(true)); } } diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgStr.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgStr.cpp index db8f70884fd..cb399831ab8 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgStr.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgStr.cpp @@ -84,7 +84,7 @@ void PtgStr::loadFields(CFRecord& record) { string_ = string_.substr(1, string_.length() - 2); } - else if (pos1 > -1 && pos1 != pos2) + else if (pos1 > -1) {//012_JKH.OPEN.INFO.PRICE.VO... boost::algorithm::replace_all(string_, L"\"", L"\"\""); } diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgSxName.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgSxName.cpp index 1928b98c462..cacfbc3c18c 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgSxName.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgSxName.cpp @@ -39,6 +39,8 @@ #include "../Biff_records/SXFDB.h" #include "../Biff_records/SxName.h" #include "../Biff_records/SXPair.h" +#include "../../../../../OOXML/XlsbFormat/Biff12_records/BeginPName.h" + namespace XLS { @@ -127,6 +129,18 @@ void PtgSxName::assemble(AssemblerStack& ptg_stack, PtgQueue& extra_data, bool f } } } + else if(static_cast(global_info->arPivotSxNames[sxIndex].name.get())) + { + auto pname = static_cast(global_info->arPivotSxNames[sxIndex].name.get()); + if(pname->ifdb >=0 && pname->ifdb < global_info->arPivotCacheSxNames.size()) + { + _Name = global_info->arPivotCacheSxNames[pname->ifdb]; + if (std::wstring::npos != _Name.find(L" ")) + { + _Name = L"'" + _Name + L"'"; + } + } + } ptg_stack.push(_Name); } else diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SerBool.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SerBool.cpp index 43559b6b366..1e1dd8dd3a2 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SerBool.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SerBool.cpp @@ -60,7 +60,17 @@ void SerBool::load(CFRecord& record) if (record.getGlobalWorkbookInfo()->Version < 0x0800) record.skipNunBytes(7); // unused } - +void SerBool::save(CFRecord& record) +{ + char serType; + if (record.getGlobalWorkbookInfo()->Version < 0x0800) + serType = 4; + else + serType = 2; + record <Version < 0x0800) + record.reserveNunBytes(7); +} const std::wstring SerBool::toString() const { diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SerBool.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SerBool.h index 16c68e1296c..2e158cbb03a 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SerBool.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SerBool.h @@ -44,6 +44,7 @@ class SerBool : public SerAr SerBool(const std::wstring& word); // Accepts only "TRUE" or "FALSE" BiffStructurePtr clone(); virtual void load(CFRecord& record); + virtual void save(CFRecord& record); virtual const std::wstring toString() const; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SerErr.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SerErr.cpp index 3867e978274..89238584f60 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SerErr.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SerErr.cpp @@ -63,6 +63,21 @@ void SerErr::load(CFRecord& record) } +void SerErr::save(CFRecord& record) +{ + char serType; + if (record.getGlobalWorkbookInfo()->Version < 0x0800) + serType = 0x10; + else + serType = 4; + + record << serType << err; + + if (record.getGlobalWorkbookInfo()->Version < 0x0800) + record.reserveNunBytes(7); + else + record.reserveNunBytes(3); +} const std::wstring SerErr::toString() const { diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SerErr.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SerErr.h index 2354f7cd927..f68f474930c 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SerErr.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SerErr.h @@ -45,6 +45,7 @@ class SerErr : public SerAr SerErr(const std::wstring& word); BiffStructurePtr clone(); virtual void load(CFRecord& record); + virtual void save(CFRecord& record); virtual const std::wstring toString() const; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SerNil.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SerNil.cpp index 5d3bc2481e9..2eb32157ca6 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SerNil.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SerNil.cpp @@ -51,6 +51,12 @@ void SerNil::load(CFRecord& record) record.skipNunBytes(8); // reserved/unused } +void SerNil::save(CFRecord& record) +{ + record.reserveNunBytes(9); +} + + const std::wstring SerNil::toString() const { return L""; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SerNil.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SerNil.h index 0f8870169f5..06dc4b95601 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SerNil.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SerNil.h @@ -43,6 +43,8 @@ class SerNil : public SerAr SerNil(); BiffStructurePtr clone(); virtual void load(CFRecord& record); + virtual void save(CFRecord& record); + virtual const std::wstring toString() const; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SerNum.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SerNum.cpp index 123dec8be10..f01548f273f 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SerNum.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SerNum.cpp @@ -64,6 +64,16 @@ void SerNum::load(CFRecord& record) record >> xnum; } +void SerNum::save(CFRecord& record) +{ + char serType; + if (record.getGlobalWorkbookInfo()->Version < 0x0800) + serType = 1; + else + serType = 0; + + record << serType << xnum; +} const std::wstring SerNum::toString() const { diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SerNum.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SerNum.h index da683eaad06..fb156eb2a06 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SerNum.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SerNum.h @@ -44,6 +44,7 @@ class SerNum : public SerAr SerNum(const std::wstring& word); BiffStructurePtr clone(); virtual void load(CFRecord& record); + virtual void save(CFRecord& record); virtual const std::wstring toString() const; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SerStr.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SerStr.cpp index d895801ec32..491f06161a6 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SerStr.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SerStr.cpp @@ -71,10 +71,30 @@ void SerStr::load(CFRecord& record) } } +void SerStr::save(CFRecord& record) +{ + char serType; + if (record.getGlobalWorkbookInfo()->Version < 0x0800) + { + serType = 2; + record << serType << string_; + } + else + { + serType = 1; + rgch = string_; + cch = string_.getSize(); + record < @@ -70,6 +71,7 @@ const bool StringPtgParser::parseToPtgs(const std::wstring& assembled_formula, R { PtgPtr last_ptg; bool operand_expected = true; // This would help distinguish unary and binary and determine if an argument to a function is missed. + bool union_expected = false; for(std::wstring::const_iterator it = assembled_formula.begin(), itEnd = assembled_formula.end(); it != itEnd;) { @@ -217,7 +219,8 @@ const bool StringPtgParser::parseToPtgs(const std::wstring& assembled_formula, R { // EXCEPT::RT::WrongParenthesisSequence(assembled_formula); } - ptg_stack.pop(); // pop PtgParen that is now stored in left_p + if(!ptg_stack.empty()) + ptg_stack.pop(); // pop PtgParen that is now stored in left_p last_ptg = left_p; PtgFuncVarPtr func_var; if(ptg_stack.size() && boost::dynamic_pointer_cast(ptg_stack.top())) @@ -236,20 +239,22 @@ const bool StringPtgParser::parseToPtgs(const std::wstring& assembled_formula, R last_ptg = ptg_stack.top(); ptg_stack.pop(); // pop PtgFuncVar } - else // If there is no function name before the left parenthesis + else if(left_p)// If there is no function name before the left parenthesis { for (size_t i = 0; i < left_p->getParametersNum(); ++i) { rgce.addPtg(PtgPtr(new PtgUnion)); } } - rgce.addPtg(last_ptg); + if(last_ptg) + rgce.addPtg(last_ptg); operand_expected = false; } #pragma endregion #pragma region Comma and PtgUnion else if(SyntaxPtg::extract_comma(it, itEnd)) { + SyntaxPtg::remove_extraSymbols(it, itEnd); PtgParenPtr left_p; if(ptg_stack.size() && (left_p = boost::dynamic_pointer_cast(ptg_stack.top())) && operand_expected) { @@ -265,7 +270,9 @@ const bool StringPtgParser::parseToPtgs(const std::wstring& assembled_formula, R } if(!ptg_stack.size() || !left_p) { - // EXCEPT::RT::WrongParenthesisSequence(assembled_formula); + operand_expected = true; + union_expected = true; + continue;// EXCEPT::RT::WrongParenthesisSequence(assembled_formula); } left_p->incrementParametersNum(); // The count of parameters will be transferred to PtgFuncVar last_ptg = left_p; // PtgParen. Mostly to differ unary and binary minuses and pluses @@ -280,6 +287,7 @@ const bool StringPtgParser::parseToPtgs(const std::wstring& assembled_formula, R unsigned int number; unsigned short ixti; PtgList ptgList(PtgList::fixed_id); + ptgList.type_ = 0x00; if(SyntaxPtg::extract_PtgBool(it, itEnd, operand_str)) { @@ -301,11 +309,18 @@ const bool StringPtgParser::parseToPtgs(const std::wstring& assembled_formula, R { if(SyntaxPtg::extract_PtgArea(it, itEnd, operand_str)) { - rgce.addPtg(found_operand = OperandPtgPtr(new PtgArea3d(ixti, operand_str, OperandPtg::ptg_VALUE, rgce.getLocation()))); + rgce.addPtg(found_operand = OperandPtgPtr(new PtgArea3d(ixti, operand_str, OperandPtg::ptg_REFERENCE, rgce.getLocation()))); } else if(SyntaxPtg::extract_PtgRef(it, itEnd, operand_str)) { - rgce.addPtg(found_operand = OperandPtgPtr(new PtgRef3d(ixti, operand_str, OperandPtg::ptg_VALUE, rgce.getLocation()))); + auto pos = std::find_if(XLS::GlobalWorkbookInfo::arXti_External_static.cbegin(), XLS::GlobalWorkbookInfo::arXti_External_static.cend(), + [&](XLS::GlobalWorkbookInfo::_xti i) { + return i.iSup == ixti; + }); + if(pos->itabFirst == pos->itabLast) + rgce.addPtg(found_operand = OperandPtgPtr(new PtgRef3d(ixti, operand_str, OperandPtg::ptg_VALUE, rgce.getLocation()))); + else + rgce.addPtg(found_operand = OperandPtgPtr(new PtgRef3d(ixti, operand_str, OperandPtg::ptg_REFERENCE, rgce.getLocation()))); } else if(SyntaxPtg::extract_PtgRefErr(it, itEnd)) { @@ -313,11 +328,14 @@ const bool StringPtgParser::parseToPtgs(const std::wstring& assembled_formula, R } else if (SyntaxPtg::extract_PtgList(it, itEnd, ptgList, ixti))// Shall be placed strongly before PtgArea and PtgRef { + if((ptgList.rowType == 0x10 || ptgList.rowType == 0x08 || ptgList.rowType == 0x02) + && ptgList.columns == 0x01) + ptgList.type_ = 0x01; rgce.addPtg(found_operand = OperandPtgPtr(new PtgList(ptgList))); } else if (SyntaxPtg::extract_PtgName(it, itEnd, number))// Shall be placed strongly before PtgArea and PtgRef { - rgce.addPtg(found_operand = OperandPtgPtr(new PtgNameX(ixti, number, OperandPtg::ptg_VALUE))); + rgce.addPtg(found_operand = OperandPtgPtr(new PtgNameX(ixti, number, OperandPtg::ptg_REFERENCE))); } else { @@ -326,7 +344,7 @@ const bool StringPtgParser::parseToPtgs(const std::wstring& assembled_formula, R } else if(SyntaxPtg::extract_PtgName(it, itEnd, number))// Shall be placed strongly before PtgArea and PtgRef { - rgce.addPtg(found_operand = OperandPtgPtr(new PtgName(number, OperandPtg::ptg_VALUE))); + rgce.addPtg(found_operand = OperandPtgPtr(new PtgName(number, OperandPtg::ptg_REFERENCE))); } else if (SyntaxPtg::extract_PtgList(it, itEnd, ptgList))// Shall be placed strongly before PtgArea and PtgRef { @@ -336,11 +354,11 @@ const bool StringPtgParser::parseToPtgs(const std::wstring& assembled_formula, R { if(L"SharedParsedFormula" == tag_name || L"CFParsedFormulaNoCCE" == tag_name) { - found_operand = OperandPtgPtr(new PtgAreaN(operand_str, OperandPtg::ptg_VALUE, rgce.getLocation())); + found_operand = OperandPtgPtr(new PtgAreaN(operand_str, OperandPtg::ptg_REFERENCE, rgce.getLocation())); } else { - found_operand = OperandPtgPtr(new PtgArea(operand_str, OperandPtg::ptg_VALUE)); + found_operand = OperandPtgPtr(new PtgArea(operand_str, OperandPtg::ptg_REFERENCE)); } rgce.addPtg(found_operand); } @@ -348,11 +366,11 @@ const bool StringPtgParser::parseToPtgs(const std::wstring& assembled_formula, R { if(L"SharedParsedFormula" == tag_name || L"CFParsedFormulaNoCCE" == tag_name) { - found_operand = OperandPtgPtr(new PtgRefN(operand_str, OperandPtg::ptg_VALUE, rgce.getLocation())); + found_operand = OperandPtgPtr(new PtgRefN(operand_str, OperandPtg::ptg_REFERENCE, rgce.getLocation())); } else { - found_operand = OperandPtgPtr(new PtgRef(operand_str, OperandPtg::ptg_VALUE)); + found_operand = OperandPtgPtr(new PtgRef(operand_str, OperandPtg::ptg_REFERENCE)); } rgce.addPtg(found_operand); } @@ -364,42 +382,62 @@ const bool StringPtgParser::parseToPtgs(const std::wstring& assembled_formula, R { rgce.addPtg(found_operand = OperandPtgPtr(new PtgNum(operand_str))); } - - else if(SyntaxPtg::extract_UndefinedName(it, itEnd)) // Shall be placed strongly after extract_PtgName - { - rgce.addPtg(found_operand = OperandPtgPtr(new PtgErr(L"#REF!"))); - } - - else if(SyntaxPtg::extract_PtgArray(it, itEnd, operand_str)) - { - rgce.addPtg(found_operand = OperandPtgPtr(new PtgArray(OperandPtg::ptg_ARRAY))); - rgb.addPtg(PtgPtr(new PtgExtraArray(operand_str))); - } else if(SyntaxPtg::extract_PtgFunc(it, itEnd, operand_str)) { PtgPtr func; - if((func = PtgFunc::create(operand_str, OperandPtg::ptg_VALUE)) || - (func = PtgFuncVar::create(operand_str, OperandPtg::ptg_VALUE))) + if((func = PtgFunc::create(operand_str, OperandPtg::ptg_REFERENCE)) || + (func = PtgFuncVar::create(operand_str, OperandPtg::ptg_REFERENCE))) + { + ptg_stack.push(func); + } + else if(SyntaxPtg::extract_FutureFunction(operand_str, number)) { + func = PtgFuncVar::create(L"USER_DEFINED_FUNCTION", OperandPtg::ptg_REFERENCE); + auto funcPtr = dynamic_cast(func.get()); + funcPtr->setFutureFuncName(operand_str); + + PtgPtr FuncName = PtgPtr(new PtgName(number, OperandPtg::ptg_REFERENCE)); ptg_stack.push(func); + rgce.addPtg(FuncName); } else { - func = PtgFuncVar::create(L"USER_DEFINED_FUNCTION", OperandPtg::ptg_VALUE); + SyntaxPtg::extract_CustomFunction(operand_str, number); + func = PtgFuncVar::create(L"USER_DEFINED_FUNCTION", OperandPtg::ptg_REFERENCE); if(!func) { // EXCEPT::LE::WhatIsTheFuck("Ftab_Cetab doesn't contain info about user-defined function (0xFF).", __FUNCTION__); } ptg_stack.push(func); - rgce.addPtg(PtgPtr(new PtgNameX(operand_str, OperandPtg::ptg_VALUE))); + rgce.addPtg(PtgPtr(new PtgName(number, OperandPtg::ptg_REFERENCE))); } } + else if(SyntaxPtg::extract_UndefinedName(it, itEnd)) // Shall be placed strongly after extract_PtgName + { + rgce.addPtg(found_operand = OperandPtgPtr(new PtgErr(L"#REF!"))); + } + + else if(SyntaxPtg::extract_PtgArray(it, itEnd, operand_str)) + { + rgce.addPtg(found_operand = OperandPtgPtr(new PtgArray(OperandPtg::ptg_ARRAY))); + rgb.addPtg(PtgPtr(new PtgExtraArray(operand_str))); + } + else { + //add error name to prevent endless formula conversion + rgce.sequence.clear(); + rgce.addPtg(found_operand = OperandPtgPtr(new PtgErr(L"#NAME?"))); + break; // EXCEPT::RT::WrongFormulaString("Unknown operand format in formula.", assembled_formula); } last_ptg = found_operand; operand_expected = false; + if(union_expected) + { + rgce.addPtg(PtgPtr(new PtgUnion)); + union_expected = false; + } } #pragma endregion } @@ -417,10 +455,240 @@ const bool StringPtgParser::parseToPtgs(const std::wstring& assembled_formula, R return false; } } + parsePtgTypes(rgce); return true; } +void SetPtgType(PtgPtr ptg, const char type) +{ + if(ptg->ptg_id.get() > 0x1F && ptg->ptg_id.get() <= 0x7D ) + { + SETBITS(ptg->ptg_id.get(),5,6,type); + } + else if(ptg->ptg_id.get() == 0x1918) + { + auto list = static_cast(ptg.get()); + list->type_ = type - 1; + } +} + +const void StringPtgParser::parsePtgTypes(Rgce& rgce) +{ + PtgVector functionStack; + for(auto i:rgce.sequence) + { + if(!i->ptg_id.is_initialized()) + continue; + auto ptgId = i->ptg_id.get(); + + auto untypedId = GETBITS(ptgId, 0, 4); + if(ptgId > 21) + { + if(untypedId == 1) + { + auto funcPtr = dynamic_cast(i.get()); + auto paramsNum = funcPtr->getParametersNum(); + auto refArgs = PosValArgs(funcPtr->getFuncIndex()); + for(auto j = paramsNum-1; j >= 0; j--) + { + if(!functionStack.empty()) + { + if(refArgs.size() > j && refArgs.at(j)) + SetPtgType(functionStack.back(), 3); + functionStack.pop_back(); + } + } + ///check and change fixed num of args + } + else if(untypedId == 2) + { + auto funcPtr = dynamic_cast(i.get()); + auto paramsNum = funcPtr->getParamsNum(); + auto FuncIndex = funcPtr->getFuncIndex(); + std::vector refArgs; + if(FuncIndex != 0x00FF) + refArgs = PosValArgs(FuncIndex); + else if(funcPtr->getFutureFuncName() != L"") + { + auto futureFuncName = funcPtr->getFutureFuncName(); + XLS::FutureFunctionParser::GetFutureFunction(futureFuncName); + refArgs = XLS::FutureFunctionParser::GetArgumentList(futureFuncName); + } + for(auto j = paramsNum-1; j >= 0; j--) + { + if(!functionStack.empty()) + { + if(refArgs.size() > j && refArgs.at(j)) + SetPtgType(functionStack.back(), 3); + functionStack.pop_back(); + } + } + } + functionStack.push_back(i); + } + else if(ptgId > 1 && ptgId < 15) + { + if(!functionStack.empty()) + { + SetPtgType(functionStack.back(), 3); + functionStack.pop_back(); + } + if(!functionStack.empty()) + { + SetPtgType(functionStack.back(), 3); + } + } + else if(ptgId > 14 && ptgId < 18) + { + if(!functionStack.empty()) + { + SetPtgType(functionStack.back(), 1); + functionStack.pop_back(); + } + if(!functionStack.empty()) + { + SetPtgType(functionStack.back(), 1); + } + } + else if(ptgId > 17 && ptgId < 21 && !functionStack.empty()) + { + SetPtgType(functionStack.back(), 3); + } + else if(ptgId == 21) + { + continue; + } + else + { + functionStack.push_back(i); + } + + } +} +std::vector StringPtgParser::PosValArgs(const unsigned int &index) const +{ + std::vector argVector; + switch(index) + { + case 0x0001: case 0x0002: case 0x0003: case 0x000F: case 0x000B: + case 0x0010: case 0x0011: case 0x0012: case 0x0014: case 0x0015: case 0x0016: case 0x0017: case 0x0018: case 0x001A: case 0x001C: + case 0x0020: case 0x0021: case 0x0026: case 0x0036: + case 0x0040: case 0x0043: case 0x0044: case 0x0045: case 0x0047: case 0x0048: case 0x0049: case 0x004F: + case 0x0051: case 0x0053: case 0x0054: case 0x0056: case 0x0057: case 0x0058: + case 0x0060: case 0x0062: case 0x0063: case 0x0064: case 0x006F: + case 0x0070: case 0x0071: case 0x0072: case 0x0076: case 0x0079: case 0x007B:case 0x007D: case 0x007E:case 0x007F: + case 0x0080: case 0x0081: case 0x0085: case 0x0086: case 0x0087: case 0x008C: case 0x008D: + case 0x0096: case 0x0097: case 0x009D: + case 0x00A2: case 0x00A3: case 0x00A4: case 0x00AC: + case 0x00B1: case 0x00B3: case 0x00B4: case 0x00B5: case 0x00B8: case 0x00B9: case 0x00BA: case 0x00BE: + case 0x00C0: case 0x00C6: case 0x00C8: case 0x00C9: + case 0x00D6: case 0x00D7: + case 0x00E0: case 0x00E2: case 0x00E5: case 0x00E6: case 0x00E7: case 0x00E8: case 0x00E9: case 0x00EA: case 0x00EC: case 0x00ED: + case 0x00F1: case 0x00F4: case 0x00F8: case 0x00FB: case 0x00FE: + case 0x0100: case 0x0101: case 0x0105: case 0x0106: case 0x0107: case 0x010F: + case 0x0117: case 0x011B: case 0x011C: + case 0x0126: case 0x0128: case 0x012A: + case 0x0156: case 0x0157: case 0x0158: + case 0x0160: + case 0x0170: case 0x0171: case 0x0172: case 0x0173: case 0x0174: case 0x0175: case 0x0176: case 0x0177: case 0x0178: case 0x0179: case 0x017A: case 0x017C: + case 0x01DF: + case 0x01E0: + argVector = {true}; + break; + case 0x000D: case 0x001B: case 0x001E: case 0x0027: case 0x0030: case 0x0046: case 0x005B: case 0x005D: + case 0x0061: case 0x0067: case 0x006B: case 0x006D: case 0x0073: case 0x0074: case 0x0075: + case 0x0084: case 0x0088: case 0x0089: case 0x008A: case 0x008B: case 0x0093: case 0x0094: case 0x00A5: case 0x00AF: + case 0x00B0: case 0x00B2: case 0x00BB: case 0x00BC: case 0x00C5: case 0x00CC: + case 0x00D0: case 0x00D1: case 0x00D4: case 0x00D5: case 0x00EF: case 0x00FD: case 0x0102: case 0x0108: case 0x010C: + case 0x0112: case 0x0113: case 0x0114: case 0x011D: case 0x0120: case 0x012B: case 0x012F: + case 0x0130: case 0x0131: case 0x0132: case 0x0133: case 0x0134: case 0x0136: case 0x0137: case 0x013A: case 0x013B: + case 0x014C: case 0x0151: case 0x0153: case 0x015C: case 0x0161: case 0x0162: case 0x0165: case 0x0167: + argVector = {true, true}; + break; + case 0x000E: case 0x001F: case 0x0041: case 0x0042: case 0x0052: case 0x007A: case 0x007C: case 0x008E: case 0x0091: + case 0x009E: case 0x00A0: case 0x00CD: case 0x00CE: case 0x00D2: case 0x00D3: case 0x00DC: case 0x00F0: case 0x0103: + case 0x0104: case 0x0109: case 0x010A: case 0x010B: case 0x0115: case 0x0116: case 0x0118: case 0x0119: case 0x011A: case 0x011F: + case 0x0122: case 0x0123: case 0x0124: case 0x0127: case 0x0129: case 0x012C: case 0x012D: + case 0x0135: case 0x014F: case 0x0154: case 0x015F: case 0x017E: + argVector = {true, true, true}; + break; + case 0x006E: case 0x0077: case 0x0078: case 0x008F: case 0x009F: case 0x00AB: case 0x00B6: case 0x00CF: case 0x00F2: case 0x00F3: + case 0x0111: case 0x011E: case 0x0121: case 0x0125: case 0x012E: case 0x013C: case 0x013D: case 0x014E: case 0x0155: case 0x015E: + case 0x0163: case 0x017F: case 0x01DD: + argVector = {true, true, true, true}; + break; + case 0x0038: case 0x0039: case 0x003A: case 0x003B: case 0x0090: case 0x009A: case 0x009B: case 0x009C: case 0x00DB: + case 0x00F6: case 0x00F7: case 0x010E: case 0x0110: case 0x0164: + argVector = {true, true, true, true, true}; + break; + case 0x003C: case 0x00A7: case 0x00A8: + argVector = {true, true, true, true, true, true}; + break; + case 0x0068: case 0x00DE: + argVector = {true, true, true, true, true, true, true}; + break; + case 0x0152: + argVector = {true, true, true, true, true, true, true, true, true}; + break; + case 0x00D8: case 0x017D: + argVector = {true, false, true}; + break; + case 0x01DE: + argVector = {true, false, true, true, true}; + break; + case 0x0145: case 0x0146: case 0x0147: case 0x0148: case 0x0159: case 0x015A: case 0x003E: case 0x006C: case 0x0092: + case 0x014B: case 0x01E3: + argVector = {false, true}; + break; + case 0x003D: case 0x00BF: case 0x0144: case 0x0149: + argVector = {false, true, true}; + break; + case 0x001D: + argVector = {false, true, true, true}; + break; + case 0x004E: + argVector = {false, true, true, true, true}; + break; + case 0x0066: case 0x0065: case 0x0098: + argVector = {true, false, false, true}; + break; + case 0x0099: + argVector = {true, false, false, true}; + break; + case 0x01E1: + for(auto i = 0; i < 127; i++) + { + argVector.push_back(false); + argVector.push_back(true); + } + break; + case 0x01E2: case 0x01E4: + argVector = {false, false, true}; + for(auto i = 0; i < 126; i++) + { + argVector.push_back(false); + argVector.push_back(true); + } + break; + case 0x0095: case 0x00E4: case 0x014A: case 0x0150: case 0x017B: + for(auto i = 0; i < 255; i++) + { + argVector.push_back(true); + } + break; + case 0x0166: + argVector = {false, false}; + for(auto i = 0; i < 253; i++) + { + argVector.push_back(true); + } + break; + default: + break; + } + return argVector; +} } // namespace XLS diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/StringPtgParser.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/StringPtgParser.h index f3e744803d7..190d78c5763 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/StringPtgParser.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/StringPtgParser.h @@ -45,6 +45,8 @@ class StringPtgParser const bool parseToPtgs(const std::wstring& assembled_formula, Rgce& rgce, RgbExtra& rgb, const std::wstring & tag_name); private: + const void parsePtgTypes(Rgce& rgce); + std::vector PosValArgs(const unsigned int &index)const; PtgStack ptg_stack; }; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/Stxp.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/Stxp.h index d5eac707798..230b81b0b4a 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/Stxp.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/Stxp.h @@ -49,15 +49,14 @@ class Stxp : public BiffStructure virtual void load(CFRecord& record); - - int twpHeight; + int twpHeight = 0; Ts ts; - short bls; - short sss; + short bls = 0; + short sss = 0; - unsigned char uls; - unsigned char bFamily; - unsigned char bCharSet; + unsigned char uls = 0; + unsigned char bFamily = 0; + unsigned char bCharSet = 0; }; } // namespace XLS diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SyntaxPtg.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SyntaxPtg.cpp index 8dc53e4695e..a93b32f0a96 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SyntaxPtg.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SyntaxPtg.cpp @@ -38,6 +38,7 @@ #include #include #include "PtgList.h" +#include "FutureFunctionParser.h" #include "../../../../../OOXML/Base/Unit.h" @@ -296,8 +297,9 @@ const bool SyntaxPtg::extract_PtgUnion(std::wstring::const_iterator& first, std: const bool SyntaxPtg::is_PtgIsect(std::wstring::const_iterator& first, std::wstring::const_iterator last) { static boost::wregex reg_before_comma(L"^ *[,()]"); + static boost::wregex reg_before_space(L"[,(\\n] *$"); static boost::wregex reg_isect(L"^ "); - return !boost::regex_search(first, last, reg_before_comma) && + return !boost::regex_search(first, last, reg_before_comma) && !boost::regex_search(first, last, reg_before_space) && boost::regex_search(first, last, reg_isect); } @@ -427,7 +429,7 @@ const bool SyntaxPtg::extract_PtgStr(std::wstring::const_iterator& first, std::w // static const bool SyntaxPtg::extract_PtgName(std::wstring::const_iterator& first, std::wstring::const_iterator last, unsigned int& out_num) { - static boost::wregex reg_name(L"^(\\w[\\w\\d.]*)([-+*/^&%<=>: ;),]|$)"); + static boost::wregex reg_name(L"^([\\w[:Unicode:]][\\w[:Unicode:]\\d.]*)([-+*/^&%<=>: ;),]|$)"); boost::match_results results; if(boost::regex_search(first, last, results, reg_name)) @@ -447,7 +449,7 @@ const bool SyntaxPtg::extract_PtgName(std::wstring::const_iterator& first, std:: // static const bool SyntaxPtg::extract_PtgList(std::wstring::const_iterator& first, std::wstring::const_iterator last, PtgList& ptgList, unsigned short ixti) { - static boost::wregex reg_table_name(L"^(\\w[\\w\\d.]*)\\["); //tableName '=SUM(tblName[Total])' + static boost::wregex reg_table_name(L"^([\\w[:Unicode:]][[:Unicode:]\\w\\d.]*)\\["); //tableName '=SUM(tblName[Total])' boost::match_results results; if (boost::regex_search(first, last, results, reg_table_name)) @@ -458,15 +460,26 @@ const bool SyntaxPtg::extract_PtgList(std::wstring::const_iterator& first, std:: if (XMLSTUFF::isTableFmla(tableName, indexTable)) { + for(auto i:XLS::GlobalWorkbookInfo::mapXtiTables_static) + { + for(auto tablIndex:i.second) + { + if(tablIndex == indexTable) + ixti = i.first; + } + } ptgList.listIndex = indexTable; ptgList.squareBracketSpace = false; ptgList.commaSpace = false; ptgList.invalid = false; ptgList.nonresident = false; ptgList.ixti = ixti; - static boost::wregex reg_inside_table1(L"\\[#?[\\s\\w\\d.]+\\]"); - static boost::wregex reg_inside_table2(L"\\[#\\w[\\s\\w\\d.]*\\],\\[#\\w[\\s\\w\\d.]*\\]"); - static boost::wregex reg_inside_table3(L"^[,;:]?\\[#?[\\s\\w\\d.]+\\]"); + static boost::wregex reg_inside_table1(L"\\[#?[\\s\\w[:Unicode:]\\d.]+\\]"); + static boost::wregex reg_inside_table2(L"\\[#[\\w[:Unicode:]][\\s\\w[:Unicode:]\\d.]*\\],\\[#[\\w[:Unicode:]][[:Unicode:]\\s\\w\\d.]*\\]"); + static boost::wregex reg_inside_table3(L"^[,;:]?\\[#?[[:Unicode:]\\s\\w\\d.]+\\]"); + static boost::wregex reg_inside_table4(L"\\[#?(\\[.+?\\]\\,)?(\\[.+?\\])?.+?\\]"); + static boost::wregex reg_inside_table5(L"^[,;:]?\\[.+?\\]"); + static boost::wregex reg_inside_table6(L"\\[\\]"); first = results[1].second; @@ -518,7 +531,6 @@ const bool SyntaxPtg::extract_PtgList(std::wstring::const_iterator& first, std:: { ptgList.rowType = 0x10; } - else if (XMLSTUFF::isColumn(boost::algorithm::erase_last_copy(boost::algorithm::erase_first_copy(insider, L"["), L"]"), indexTable, indexColumn)) { ptgList.rowType = 0x00; @@ -531,7 +543,7 @@ const bool SyntaxPtg::extract_PtgList(std::wstring::const_iterator& first, std:: if (boost::regex_search(first, last, results_1, reg_inside_table3)) { - insider = results_1.str(0); + insider = results_1.str(0); if (!insider.empty() && insider[0] != '[') insider.erase(0, 1); @@ -543,11 +555,12 @@ const bool SyntaxPtg::extract_PtgList(std::wstring::const_iterator& first, std:: if (ptgList.colFirst == 65535) { ptgList.columns = 0x01; - ptgList.colFirst = indexColumn; + ptgList.colFirst = indexColumn; + ptgList.colLast = indexColumn; if (boost::regex_search(first, last, results_1, reg_inside_table3)) { - insider = results_1.str(0); + insider = results_1.str(0); if (!insider.empty() && insider[0] != '[') insider.erase(0, 1); @@ -559,6 +572,18 @@ const bool SyntaxPtg::extract_PtgList(std::wstring::const_iterator& first, std:: first = results_1[0].second; } } + else if(boost::regex_search(first, last, results_1, reg_inside_table5)) + { + insider = results_1.str(0); + insider = boost::algorithm::erase_first_copy(insider, L":"); + + if (XMLSTUFF::isColumn(boost::algorithm::erase_last_copy(boost::algorithm::erase_first_copy(insider, L"["), L"]"), indexTable, indexColumn)) + { + ptgList.columns = 0x02; + ptgList.colLast = indexColumn; + } + first = results_1[0].second; + } } else { @@ -567,6 +592,22 @@ const bool SyntaxPtg::extract_PtgList(std::wstring::const_iterator& first, std:: } } } + else if(boost::regex_search(first, last, results_1, reg_inside_table5)) + { + insider = results_1.str(0); + insider = boost::algorithm::erase_first_copy(insider, L","); + + if (XMLSTUFF::isColumn(boost::algorithm::erase_last_copy(boost::algorithm::erase_first_copy(insider, L"["), L"]"), indexTable, indexColumn)) + { + if (ptgList.colFirst == 65535) + { + ptgList.columns = 0x01; + ptgList.colFirst = indexColumn; + ptgList.colLast = indexColumn; + } + } + first = results_1[0].second; + } if (first != last && *first == ']') ++first; @@ -574,6 +615,43 @@ const bool SyntaxPtg::extract_PtgList(std::wstring::const_iterator& first, std:: return true; } + else if (boost::regex_search(first, last, results_1, reg_inside_table6)) + { + auto colCount = XMLSTUFF::getColumnsCount(indexTable); + if(colCount>1) + { + ptgList.columns = 0x02; + ptgList.colFirst = 0; + ptgList.colLast = colCount-1; + first = results_1[0].second; + } + else + { + ptgList.columns = 0x01; + ptgList.colFirst = 0; + ptgList.colLast = 0; + first = results_1[0].second; + } + return true; + } + else if(boost::regex_search(first, last, results_1, reg_inside_table4)) + { + _UINT16 indexColumn = -1; + ptgList.rowType = 0x00; + auto insider = results_1.str(0); + + if (XMLSTUFF::isColumn(boost::algorithm::erase_last_copy(boost::algorithm::erase_first_copy(insider, L"["), L"]"), indexTable, indexColumn)) + { + ptgList.columns = 0x01; + ptgList.colFirst = indexColumn; + ptgList.colLast = ptgList.colFirst; + first = results_1[0].second; + return true; + } + + if (first != last && *first == ']') + ++first; + } } } return false; @@ -645,30 +723,47 @@ const bool SyntaxPtg::extract_PtgRef(std::wstring::const_iterator& first, std::w // static const bool SyntaxPtg::extract_3D_part(std::wstring::const_iterator& first, std::wstring::const_iterator last, unsigned short& ixti) { - static boost::wregex reg_sheets(L"^(\\w[\\w\\d.]*(:\\w[\\w\\d.]*)?)!"); - static boost::wregex reg_quoted(L"^'((''|[^]['\\/*?])*)'!"); - boost::match_results results; - if (boost::regex_search(first, last, results, reg_sheets) || - boost::regex_search(first, last, results, reg_quoted)) - { - - std::wstring sheets_names = results.str(1); - - ixti = XMLSTUFF::sheetsnames2ixti(boost::algorithm::replace_all_copy(sheets_names, L"''", L"'")); - if(0xFFFF != ixti) - { - first = results[0].second; - return true; - } - } - return false; + static boost::wregex reg_sheets(L"^([\\w[:Unicode:]][[:Unicode:]\\w\\d.]*(:[\\w[:Unicode:]][[:Unicode:]\\w\\d.]*)?)!"); + static boost::wregex reg_sheet(L"^([^:]+):(.*)$"); + static boost::wregex reg_quoted(L"^'((''|[^]['\\/*?])*)'!"); + boost::match_results results; + if (boost::regex_search(first, last, results, reg_sheets) || + boost::regex_search(first, last, results, reg_quoted)) + { + + std::wstring sheets_names = results.str(1); + + ixti = XMLSTUFF::sheetsnames2ixti(boost::algorithm::replace_all_copy(sheets_names, L"''", L"'")); + if(0xFFFF != ixti) + { + first = results[0].second; + return true; + } + boost::match_results results2; + if (boost::regex_search(sheets_names, results2, reg_sheet)) + { + auto firstSheetName = results2.str(1); + auto secondSheetName = results2.str(2); + auto xti1 = XMLSTUFF::sheetsnames2ixti(boost::algorithm::replace_all_copy(firstSheetName, L"''", L"'")); + auto xti2 = XMLSTUFF::sheetsnames2ixti(boost::algorithm::replace_all_copy(secondSheetName, L"''", L"'")); + if(0xFFFF != xti1 && 0xFFFF != xti2) + { + ixti = XMLSTUFF::AddMultysheetXti(sheets_names, xti1, xti2); + if(!ixti) + return false; + first = results[0].second; + return true; + } + } + } + return false; } // static const bool SyntaxPtg::extract_UndefinedName(std::wstring::const_iterator& first, std::wstring::const_iterator last) { - static boost::wregex reg_undef(L"^([\\w\\d.]+)([-+*/^&%<=>: ;),]|$)"); + static boost::wregex reg_undef(L"^([[:Unicode:]\\w\\d.]+)([-+*/^&%<=>: ;),]|$)"); boost::match_results results; if(boost::regex_search(first, last, results, reg_undef)) { @@ -737,6 +832,49 @@ const bool SyntaxPtg::extract_PtgFunc(std::wstring::const_iterator& first, std:: return false; } +// static +const bool SyntaxPtg::extract_FutureFunction(const std::wstring &funcName, unsigned int& out_num) +{ + std::wstring tempName = funcName; + + if(XLS::FutureFunctionParser::GetFutureFunction(tempName)) + { + auto funcNum = XMLSTUFF::definenames2index(tempName); + if(funcNum != 0xFFFFFFFF) + { + out_num = funcNum; + } + else + { + out_num = XMLSTUFF::AddDefinedName(tempName); + } + return true; + } + return false; +} + +// static +const void SyntaxPtg::extract_CustomFunction(const std::wstring &funcName, unsigned int& out_num) +{ + auto funcNum = XMLSTUFF::definenames2index(funcName); + if(funcNum != 0xFFFFFFFF) + { + out_num = funcNum; + } + else + { + out_num = XMLSTUFF::AddDefinedName(funcName); + } +} + +// static +const void SyntaxPtg::remove_extraSymbols(std::wstring::const_iterator& first, std::wstring::const_iterator& last) +{ + while(first != last && (first[0] == L' ' || first[0] == L'\n')) + { + first++; + } +} } // namespace XLS diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SyntaxPtg.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SyntaxPtg.h index d2b9fb3f950..111e7416d0e 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SyntaxPtg.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SyntaxPtg.h @@ -86,6 +86,9 @@ class SyntaxPtg static const bool extract_RightParenthesis(std::wstring::const_iterator& first, std::wstring::const_iterator last); static const bool extract_PtgFunc(std::wstring::const_iterator& first, std::wstring::const_iterator last, std::wstring& out_str); + static const bool extract_FutureFunction(const std::wstring &funcName, unsigned int& out_num); + static const void extract_CustomFunction(const std::wstring &funcName, unsigned int& out_num); + static const void remove_extraSymbols(std::wstring::const_iterator& first, std::wstring::const_iterator& last); }; } // namespace XLS diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/XFExtGradient.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/XFExtGradient.h index 4ba604eb83c..23482a781e4 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/XFExtGradient.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/XFExtGradient.h @@ -53,7 +53,7 @@ class XFExtGradient : public BiffStructure static const ElementType type = typeXFExtGradient; XFPropGradient gradient; - _UINT32 cGradStops; + _UINT32 cGradStops = 0; std::vector rgGradStops; }; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/XFProp.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/XFProp.cpp index 9a7f8e38cd2..fe040d36bea 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/XFProp.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/XFProp.cpp @@ -85,7 +85,6 @@ void XFProp::load(CFRecord& record) case 0x000F: case 0x0010: case 0x0011: // XFPropTextRotation - case 0x0012: // indent case 0x0013: // ReadingOrder case 0x0014: case 0x0015: @@ -112,6 +111,7 @@ void XFProp::load(CFRecord& record) xfPropDataBlob = str; return; } + case 0x0012: // indent case 0x0019: case 0x001A: case 0x001B: @@ -141,17 +141,88 @@ void XFProp::load(CFRecord& record) } void XFProp::save(CFRecord& record) { + LPWideString* strData; if (xfPropDataBlob) { - cb = sizeof(cb) + sizeof(xfPropType) + sizeof(*xfPropDataBlob.get()); + cb = sizeof(cb) + sizeof(xfPropType); + auto blobSize = 0; + switch(xfPropType) + { + case 0x000D: + case 0x000E: + case 0x000F: + case 0x0010: + case 0x0011: // XFPropTextRotation + case 0x0013: // ReadingOrder + case 0x0014: + case 0x0015: + case 0x0016: + case 0x0017: + case 0x001C: + case 0x001D: + case 0x001E: + case 0x001F: + case 0x0020: + case 0x0021: + case 0x0022: + case 0x0023: + case 0x0025: + case 0x002B: + case 0x002C: + case 0x0000: + blobSize = 1; + break; + case 0x0001: + case 0x0002: + case 0x0005: + blobSize = 8; + break; + case 0x0003: + blobSize = 44; + break; + case 0x0004: + blobSize = 18; + break; + case 0x0006: + case 0x0007: + case 0x0008: + case 0x0009: + case 0x000A: + case 0x000B: + case 0x000C: + blobSize = 10; + break; + case 0x0026: + case 0x0018: + { + strData = dynamic_cast(xfPropDataBlob.get()); + if(strData) + blobSize = (strData->getSize() * 2) + 2; + } + break; + case 0x0012: // indent + case 0x0019: + case 0x001A: + case 0x001B: + case 0x0029: + case 0x002A: + blobSize = 2; + break; + case 0x0024: + blobSize = 4; + break; + default: + // EXCEPT::RT::WrongBiffRecord("Unsupported type of XFProp.", record.getTypeString()); + break; + } + cb += blobSize; record << xfPropType << cb; if (xfPropType == 0x0026 || xfPropType == 0x0018) { - LPWideString* string = dynamic_cast(xfPropDataBlob.get()); - if (string) - record << *string; + if (strData) + record << *strData; } else record << *xfPropDataBlob; @@ -276,6 +347,37 @@ static void deserialize_val_prop(XmlUtils::CXmlLiteReader& oReader, const std::w } } +static void deserialize_default_val(XmlUtils::CXmlLiteReader& oReader, const std::wstring & typeName, const _UINT32& value, BiffStructurePtr & val) +{ + BiffStructurePtr biffref; + deserialize_val_prop(oReader, typeName, biffref); + if (typeName == L"BIFF_WORD") + { + auto word = new BIFF_WORD; + if(biffref.get()) + { + *word = *(reinterpret_cast(biffref.get())); + } + else + { + *word = value; + } + val.reset(word); + } + else if(typeName == L"BIFF_BYTE") + { + auto word = new BIFF_BYTE; + if(biffref.get()) + { + *word = *(reinterpret_cast(biffref.get())); + } + else + { + *word = value; + } + val.reset(word); + } +} static void deserialize_prop(XmlUtils::CXmlLiteReader& oReader, const std::wstring & typeName, BiffStructurePtr & val) { auto value = oReader.GetText(); @@ -399,10 +501,46 @@ static XFPropBorder* deserialize_border_prop(XmlUtils::CXmlLiteReader& oReader) border->color.deserialize(oReader); } } + else + { + border->color.xclrType = 0; + border->color.fValidRGBA = false; + border->color.nTintShade = 0; + } return border; } - + static void deserialize_alignment(XmlUtils::CXmlLiteReader& oReader, const unsigned short & typeName, BiffStructurePtr & val) + { + BIFF_BYTE* byte_ = new BIFF_BYTE; + if (!byte_) return; + + auto value = oReader.GetText(); + if(typeName == 0x000F) + { + if (value == L"general") *byte_ = 0; + else if (value == L"left") *byte_ = 1; + else if (value == L"center") *byte_ = 2; + else if (value == L"right") *byte_ = 3; + else if (value == L"fill") *byte_ = 4; + else if (value == L"justify") *byte_ = 5; + else if (value == L"center-across-selection") *byte_ = 6; + else if (value == L"distributed") *byte_ = 7; + else *byte_ = 0xFF; + } + else if(typeName == 0x0010) + { + if (value == L"top") *byte_ = 0; + else if (value == L"center") *byte_ = 1; + else if (value == L"bottom") *byte_ = 2; + else if (value == L"justify") *byte_ = 3; + else if (value == L"distributed") *byte_ = 4; + else *byte_ = 0; + } + else + *byte_ = 0; + val.reset(byte_); + } void XFProp::serialize_attr(CP_ATTR_NODE) { switch(xfPropType) @@ -467,7 +605,8 @@ void XFProp::deserialize_attr(XmlUtils::CXmlLiteReader& oReader) if (value == L"none") *byte_ = 0; else if (value == L"solid") *byte_ = 1; else if (value == L"pct50") *byte_ = 2; - else if (value == L"pct75") *byte_ = 3; + else if (value == L"pct75" || value == L"darkGray") + *byte_ = 3; else if (value == L"pct25") *byte_ = 4; else if (value == L"horzStripe") *byte_ = 5; else if (value == L"vertStripe") *byte_ = 6; @@ -483,7 +622,8 @@ void XFProp::deserialize_attr(XmlUtils::CXmlLiteReader& oReader) else if (value == L"thinDiagCross") *byte_ = 16; else if (value == L"gray125") *byte_ = 17; else if (value == L"gray0625") *byte_ = 18; - + else *byte_ = 1; + xfPropDataBlob.reset(byte_); }break; @@ -516,25 +656,34 @@ void XFProp::deserialize_attr(XmlUtils::CXmlLiteReader& oReader) case 0x000C: xfPropDataBlob.reset(deserialize_border_prop(oReader)); break; + case 0x000F: + case 0x0010: + deserialize_alignment(oReader, xfPropType, xfPropDataBlob); + break; case 0x000D: case 0x000E: - case 0x000F: - case 0x0010: case 0x0011: // XFPropTextRotation - case 0x0012: // indent case 0x0013: // ReadingOrder case 0x0014: case 0x0015: case 0x0016: //case 0x0017: - xfPropDataBlob.reset(new BIFF_BYTE(XmlUtils::GetInteger(oReader.GetText()))); + xfPropDataBlob.reset(new BIFF_BYTE(XmlUtils::GetInteger(oReader.GetText()))); + break;// + case 0x0018: + deserialize_val_prop(oReader, L"LPWideString", xfPropDataBlob); break; - case 0x001C: - case 0x001D: - case 0x001E: - case 0x001F: - case 0x0020: - case 0x0021: + case 0x0019: + deserialize_default_val(oReader, L"BIFF_WORD", 0x02BC, xfPropDataBlob); + break; + case 0x0020: + case 0x0021: + case 0x001C: + case 0x001D: + case 0x001E: + case 0x001F: + deserialize_default_val(oReader, L"BIFF_BYTE", 0x01, xfPropDataBlob); + break; case 0x0022: case 0x0023: xfPropDataBlob.reset(new BIFF_BYTE(1)); @@ -545,21 +694,18 @@ void XFProp::deserialize_attr(XmlUtils::CXmlLiteReader& oReader) case 0x002C: deserialize_prop(oReader, L"BIFF_BYTE", xfPropDataBlob); break; - case 0x0018: - deserialize_val_prop(oReader, L"LPWideString", xfPropDataBlob); - break; + case 0x0012: // indent case 0x0029: + case 0x002A: xfPropDataBlob.reset(new BIFF_WORD(XmlUtils::GetInteger(oReader.GetText()))); break; - case 0x0019: case 0x001A: - xfPropDataBlob.reset(new BIFF_WORD(1)); + //xfPropDataBlob.reset(new BIFF_WORD(1)); case 0x001B: - case 0x002A: deserialize_val_prop(oReader, L"BIFF_WORD", xfPropDataBlob); break; case 0x0024: - xfPropDataBlob.reset(new BIFF_DWORD(XmlUtils::GetInteger(oReader.GetText()))); + deserialize_val_prop(oReader, L"BIFF_DWORD", xfPropDataBlob); break; case 0x0026: xfPropDataBlob.reset(new LPWideString(oReader.GetText())); @@ -568,7 +714,7 @@ void XFProp::deserialize_attr(XmlUtils::CXmlLiteReader& oReader) } int XFProp::serialize(std::wostream & stream) { - CP_XML_WRITER(stream) + CP_XML_WRITER(stream) { switch(xfPropType) { diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/XFPropColor.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/XFPropColor.cpp index d2630dc0c0c..a505a8d8d5b 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/XFPropColor.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/XFPropColor.cpp @@ -99,6 +99,7 @@ int XFPropColor::deserialize(XmlUtils::CXmlLiteReader& oReader) { std::wstring wsPropName = oReader.GetName(); nTintShade = 0; + fValidRGBA = false; while (!wsPropName.empty()) { if (wsPropName == L"auto" && oReader.GetText() == L"1") @@ -117,12 +118,16 @@ int XFPropColor::deserialize(XmlUtils::CXmlLiteReader& oReader) { xclrType = 2; dwRgba.Parse(oReader.GetText()); + fValidRGBA = true; } - else if (wsPropName == L"tint") + if (wsPropName == L"tint") { - nTintShade = XmlUtils::GetInteger(oReader.GetText()) * 32767.0; + nTintShade = XmlUtils::GetDouble(oReader.GetText()) * 32767.0; } - + else + { + nTintShade = 0; + } if (!oReader.MoveToNextAttribute()) break; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/AXES.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/AXES.cpp index 8d7d3cefe3a..2a9717249c2 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/AXES.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/AXES.cpp @@ -245,6 +245,9 @@ int AXES::serialize(std::wostream & _stream, bool secondary) { for (size_t i = 0 ; i < m_arAxes.size(); i++) { + if (!m_arAxes[i]) + continue; + IVAXIS * iv = dynamic_cast (m_arAxes[i].get()); DVAXIS * dv = dynamic_cast (m_arAxes[i].get()); SERIESAXIS * ser = dynamic_cast (m_arAxes[i].get()); @@ -272,6 +275,7 @@ int AXES::serialize(std::wostream & _stream, bool secondary) for ( size_t h = 0 ; h < m_arATTACHEDLABEL.size(); h++) { ATTACHEDLABEL *l_= dynamic_cast (m_arATTACHEDLABEL[h].get() ); + if (!l_) continue; if (l_->m_iLinkObject == 2 && l_->m_bUsed == false && (dv || ser)) { diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/CELLTABLE.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/CELLTABLE.cpp index de5672ed055..d13a8804143 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/CELLTABLE.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/CELLTABLE.cpp @@ -258,8 +258,8 @@ int CELLTABLE::serialize(std::wostream & stream) if (xf < global_info_->cellXfs_count && xf >= 0) { CP_XML_ATTR(L"s", xf); - CP_XML_ATTR(L"customFormat", true); } + CP_XML_ATTR(L"customFormat", true); } if (row->miyRw > 0 && row->miyRw < 0x8000 && row->bValid && ((row->fUnsynced && row->fGhostDirty) || !row->fGhostDirty)) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/COLUMNS.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/COLUMNS.cpp index da94f8bf283..744f0a0a6e0 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/COLUMNS.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/COLUMNS.cpp @@ -68,6 +68,11 @@ const bool COLUMNS::loadContent(BinProcessor& proc) } int count = (global_info_->Version == 0x0200) ? proc.repeated(0, 255) : proc.repeated(0, 255); + if (count < 1) + {//version 0x0400 ???? ColWidth + count = (global_info_->Version == 0x0200) ? proc.repeated(0, 255) : proc.repeated(0, 255); + } + int last_add = 0; for (std::list::iterator it = elements_.begin(); it != elements_.end(); ++it) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/DVAXIS.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/DVAXIS.cpp index 266e138d362..0c7a6a8f59e 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/DVAXIS.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/DVAXIS.cpp @@ -86,7 +86,11 @@ const bool DVAXIS::loadContent(BinProcessor& proc) m_Axis = elements_.back(); elements_.pop_back(); - proc.mandatory(); elements_.pop_back(); + if (!proc.mandatory()) + { + return true; + } + elements_.pop_back(); if (proc.optional()) { @@ -123,7 +127,7 @@ int DVAXIS::serialize(std::wostream & _stream) Axis *axis = dynamic_cast (m_Axis.get()); CRTMLFRT *crtMltFrt = dynamic_cast (m_CRTMLFRT.get()); - int axes_type = axis->wType + 1; + int axes_type = axis ? axis->wType + 1 : 1; bool bLogarithScale = false; @@ -186,7 +190,10 @@ int DVAXIS::serialize(std::wostream & _stream) } } //---------------------------------------------------------------------------------------------- - m_AXS->serialize(_stream); + if (m_AXS) + { + m_AXS->serialize(_stream); + } if (value_range) { diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/FDB.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/FDB.cpp index d4a767acfd2..c344ff0e340 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/FDB.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/FDB.cpp @@ -207,12 +207,14 @@ int FDB::serialize(std::wostream & strm, bool bSql, bool bDBB) if (m_SXVDTEx) { SXVDTEx *olap_info = dynamic_cast(m_SXVDTEx.get()); - if ((olap_info) && (olap_info->isxth >= 0)) + if ((olap_info) && (olap_info->isxth >= 0) && (olap_info->isxth < m_arPIVOTTH.size())) { PIVOTTH* ht = dynamic_cast(m_arPIVOTTH[olap_info->isxth].get()); - SXTH* sxTH = dynamic_cast(ht->m_SXTH.get()); - - CP_XML_ATTR(L"caption", sxTH->stDisplay.value()); + SXTH* sxTH = ht ? dynamic_cast(ht->m_SXTH.get()) : NULL; + if (sxTH) + { + CP_XML_ATTR(L"caption", sxTH->stDisplay.value()); + } CP_XML_ATTR(L"hierarchy", olap_info->isxth); CP_XML_ATTR(L"level", olap_info->isxtl); @@ -333,7 +335,8 @@ int FDB::serialize(std::wostream & strm, bool bSql, bool bDBB) for (size_t i = 0; i < m_arSRCSXOPER.size(); i++) { - m_arSRCSXOPER[i]->serialize(CP_XML_STREAM()); + if (m_arSRCSXOPER[i]) + m_arSRCSXOPER[i]->serialize(CP_XML_STREAM()); } } } @@ -352,12 +355,16 @@ int FDB::serialize(std::wostream & strm, bool bSql, bool bDBB) if (m_SXRANGE) m_SXRANGE->serialize(CP_XML_STREAM()); + CP_XML_NODE(L"groupItems") { CP_XML_ATTR(L"count", m_arGRPSXOPER.size()); for (size_t i = 0; i < m_arGRPSXOPER.size(); i++) { - m_arGRPSXOPER[i]->serialize(CP_XML_STREAM()); + if (m_arGRPSXOPER[i]) + { + m_arGRPSXOPER[i]->serialize(CP_XML_STREAM()); + } } } } @@ -382,6 +389,8 @@ int FDB::serialize_record(std::wostream & strm) for (size_t i = 0; i < m_arSRCSXOPER.size(); i++) { SXOPER* oper = dynamic_cast(m_arSRCSXOPER[i].get()); + if (!oper) continue; + oper->serialize_record(CP_XML_STREAM()); } } diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/FORMATTING.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/FORMATTING.cpp index 6906de5ec8a..11510a8d2b6 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/FORMATTING.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/FORMATTING.cpp @@ -94,24 +94,8 @@ const bool FORMATTING::loadContent(BinProcessor& proc) count = proc.repeated(0, 218); // Originally: proc.repeated(8, 218); while(count > 0) { - Format *fmt = dynamic_cast(elements_.back().get()); - if ((fmt) && (fmt->ifmt == 0xffff)) - { - std::map::iterator pFind = global_info->mapDefaultFormatCode.find(fmt->stFormat); - if (pFind != global_info->mapDefaultFormatCode.end()) - { - fmt->ifmt_used = fmt->ifmt = pFind->second; - } - else - { - fmt->ifmt_used = fmt->ifmt = global_info->last_User_NumFmt++; - } - } - else - { - fmt->ifmt_used = global_info->RegisterNumFormat(fmt->ifmt, fmt->stFormat); - } - global_info->m_arNumFormats.insert(global_info->m_arNumFormats.begin(), elements_.back()); + global_info->RegisterNumFormat(elements_.back()); + elements_.pop_back(); count--; } @@ -212,6 +196,9 @@ void FORMATTING::update_xfs() } } xfs->RegisterFillBorder(); + + global_info->cellXfs_count = xfs->m_arCellXFs.size(); + global_info->cellStyleXfs_count = xfs->m_arCellStyles.size(); } void FORMATTING::concatinate(FORMATTING* ext) { diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/IVAXIS.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/IVAXIS.cpp index 16cfab12c4f..c78db9ed93d 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/IVAXIS.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/IVAXIS.cpp @@ -134,7 +134,7 @@ int IVAXIS::serialize(std::wostream & _stream) Axis * axis = dynamic_cast (m_Axis.get()); AxcExt * axcExt = dynamic_cast (m_AxcExt.get()); - int axes_type = axis->wType + 1; + int axes_type = axis ? axis->wType + 1 : 1; CP_XML_WRITER(_stream) { @@ -145,7 +145,7 @@ int IVAXIS::serialize(std::wostream & _stream) CP_XML_NODE(L"c:scaling") { - if (cat_ser_range->fReversed) + if (cat_ser_range && cat_ser_range->fReversed) { CP_XML_NODE(L"c:orientation"){ CP_XML_ATTR(L"val", L"maxMin"); } }else @@ -175,7 +175,8 @@ int IVAXIS::serialize(std::wostream & _stream) } } //----------------------------------------------------------------------------------- - m_AXS->serialize(_stream); + if (m_AXS) + m_AXS->serialize(_stream); if (m_AxcExt) m_AxcExt->serialize(_stream); @@ -187,11 +188,25 @@ int IVAXIS::serialize(std::wostream & _stream) if (cat_ser_range->fMaxCross == true) CP_XML_ATTR(L"val", L"max"); else CP_XML_ATTR(L"val", L"autoZero"); } + + if (cat_ser_range->catLabel > 1 && cat_ser_range->catLabel < 32000) + { + CP_XML_NODE(L"c:tickLblSkip") + { + CP_XML_ATTR(L"val", cat_ser_range->catLabel); + } + } + if (cat_ser_range->catMark > 1 && cat_ser_range->catMark < 32000) + { + CP_XML_NODE(L"c:tickMarkSkip") + { + CP_XML_ATTR(L"val", cat_ser_range->catMark); + } + } } - if (m_CatLab) + CatLab* label = m_CatLab ? dynamic_cast(m_CatLab.get()) : NULL; + if (label) { - CatLab *label = dynamic_cast(m_CatLab.get()); - CP_XML_NODE(L"c:lblAlgn") { switch(label->at) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/PIVOTCACHEDEFINITION.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/PIVOTCACHEDEFINITION.cpp index 02e3dbe1cb6..b945e02fc1c 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/PIVOTCACHEDEFINITION.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/PIVOTCACHEDEFINITION.cpp @@ -168,7 +168,7 @@ int PIVOTCACHEDEFINITION::serialize_definitions(std::wostream & strm) FDB *field = dynamic_cast(pivot_cache->m_arFDB[i].get()); if (!field) continue; - if (olap_view) + if ((olap_view) && (i < olap_view->m_arPIVOTVDTEX.size())) { PIVOTVDTEX *ex = dynamic_cast(olap_view->m_arPIVOTVDTEX[i].get()); @@ -187,7 +187,10 @@ int PIVOTCACHEDEFINITION::serialize_definitions(std::wostream & strm) for (size_t i = 0; i < pivot_cache->m_arSXFORMULA.size(); i++) { - pivot_cache->m_arSXFORMULA[i]->serialize(CP_XML_STREAM()); + if (pivot_cache->m_arSXFORMULA[i]) + { + pivot_cache->m_arSXFORMULA[i]->serialize(CP_XML_STREAM()); + } } } } diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/PIVOTVIEW.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/PIVOTVIEW.cpp index ef3aaffb66e..80cb9bfd1cc 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/PIVOTVIEW.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/PIVOTVIEW.cpp @@ -100,7 +100,8 @@ const bool PIVOTVIEW::loadContent(BinProcessor& proc) elements_.pop_back(); } //------------------------------------------------------------------------------------------------- - PIVOTCACHEDEFINITION* pivot_cache = dynamic_cast(global_info_->arPIVOTCACHEDEFINITION[view->iCache].get()); + PIVOTCACHEDEFINITION* pivot_cache = view->iCache < global_info_->arPIVOTCACHEDEFINITION.size() ? + dynamic_cast(global_info_->arPIVOTCACHEDEFINITION[view->iCache].get()) : NULL; if (pivot_cache) { SXSRC* src = dynamic_cast (pivot_cache->m_SXSRC.get()); diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/PIVOTVIEWEX.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/PIVOTVIEWEX.cpp index 7a2c4d6fd55..432eb7e3bab 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/PIVOTVIEWEX.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/PIVOTVIEWEX.cpp @@ -103,8 +103,10 @@ int PIVOTVIEWEX::serialize_table_view(std::wostream & strm) for (size_t i = 0; i < m_arPIVOTTH.size(); i++) { + if (!m_arPIVOTTH[i]) continue; + PIVOTTH* th = dynamic_cast(m_arPIVOTTH[i].get()); - SXTH* sxTH = dynamic_cast(th->m_SXTH.get()); + SXTH* sxTH = th ? dynamic_cast(th->m_SXTH.get()) : NULL; SXAddl_SXCHierarchy_SXDId *id = NULL; SXAddl_SXCHierarchy_SXDVerUpdInv *verUpd = NULL; @@ -133,12 +135,14 @@ int PIVOTVIEWEX::serialize_table_view(std::wostream & strm) } CP_XML_NODE(L"pivotHierarchy") { - CP_XML_ATTR(L"multipleItemSelectionAllowed", sxTH->fEnableMultiplePageItems); - - CP_XML_ATTR(L"dragToRow", sxTH->fDragToRow); - CP_XML_ATTR(L"dragToCol", sxTH->fDragToColumn); - CP_XML_ATTR(L"dragToPage", sxTH->fDragToPage); - CP_XML_ATTR(L"dragToData", sxTH->fDragToData); + if (sxTH) + { + CP_XML_ATTR(L"multipleItemSelectionAllowed", sxTH->fEnableMultiplePageItems); + CP_XML_ATTR(L"dragToRow", sxTH->fDragToRow); + CP_XML_ATTR(L"dragToCol", sxTH->fDragToColumn); + CP_XML_ATTR(L"dragToPage", sxTH->fDragToPage); + CP_XML_ATTR(L"dragToData", sxTH->fDragToData); + } if (caption) { @@ -204,7 +208,7 @@ int PIVOTVIEWEX::serialize(std::wostream & strm) for (size_t i = 0; i < m_arPIVOTTH.size(); i++) { PIVOTTH* th = dynamic_cast(m_arPIVOTTH[i].get()); - SXTH* sxTH = dynamic_cast(th->m_SXTH.get()); + SXTH* sxTH = th ? dynamic_cast(th->m_SXTH.get()) : NULL; SXAddl_SXCHierarchy_SXDId *id = NULL; SXAddl_SXCHierarchy_SXDInfo12 *info12 = NULL; @@ -221,7 +225,10 @@ int PIVOTVIEWEX::serialize(std::wostream & strm) if (!user_caption) user_caption = dynamic_cast (addl->content.get()); if (!measure_grp) measure_grp = dynamic_cast (addl->content.get()); } - if (sxTH->fKPI) + if (!sxTH) + continue; + + if (sxTH->fKPI) { std::unordered_map::iterator pFind = mapKpis.find(sxTH->stUnique.value()); if (pFind == mapKpis.end()) @@ -449,7 +456,7 @@ int PIVOTVIEWEX::serialize(std::wostream & strm) CP_XML_ATTR(L"measureGroup", i); PIVOTTH* th = dynamic_cast(m_arPIVOTTH[it->second[j]].get()); - SXTH* sxTH = dynamic_cast(th->m_SXTH.get()); + SXTH* sxTH = th ? dynamic_cast(th->m_SXTH.get()) : NULL; CP_XML_ATTR(L"dimension", j + 1/*it->first*/); } diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/SERIESAXIS.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/SERIESAXIS.cpp index 36616973f83..4a20ed60325 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/SERIESAXIS.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/SERIESAXIS.cpp @@ -134,7 +134,7 @@ int SERIESAXIS::serialize(std::wostream & _stream) CatSerRange * cat_ser_range = dynamic_cast(m_CatSerRange.get()); Axis * axis = dynamic_cast (m_Axis.get()); - int axes_type = axis->wType + 1; + int axes_type = axis ? axis->wType + 1 : 0; CP_XML_WRITER(_stream) { @@ -145,7 +145,7 @@ int SERIESAXIS::serialize(std::wostream & _stream) CP_XML_NODE(L"c:scaling") { - if (cat_ser_range->fReversed) + if (cat_ser_range && cat_ser_range->fReversed) { CP_XML_NODE(L"c:orientation"){ CP_XML_ATTR(L"val", L"maxMin"); } }else @@ -175,8 +175,10 @@ int SERIESAXIS::serialize(std::wostream & _stream) } } //----------------------------------------------------------------------------------- - m_AXS->serialize(_stream); - + if (m_AXS) + { + m_AXS->serialize(_stream); + } if (cat_ser_range) { CP_XML_NODE(L"c:crosses") @@ -184,6 +186,20 @@ int SERIESAXIS::serialize(std::wostream & _stream) if (cat_ser_range->fMaxCross == true) CP_XML_ATTR(L"val", L"max"); else CP_XML_ATTR(L"val", L"autoZero"); } + if (cat_ser_range->catLabel > 1 && cat_ser_range->catLabel < 32000) + { + CP_XML_NODE(L"c:tickLblSkip") + { + CP_XML_ATTR(L"val", cat_ser_range->catLabel); + } + } + if (cat_ser_range->catMark > 1 && cat_ser_range->catMark < 32000) + { + CP_XML_NODE(L"c:tickMarkSkip") + { + CP_XML_ATTR(L"val", cat_ser_range->catMark); + } + } } } diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/SS.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/SS.cpp index 63c875378ed..f1b92062b86 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/SS.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/SS.cpp @@ -258,7 +258,7 @@ int SS::serialize_default(std::wostream & _stream, int series_type, int ind ) CP_XML_NODE(L"c:spPr") { - if (m_isAutoFill && series_type != CHART_TYPE_Line && series_type != CHART_TYPE_Scatter) //line & scatter + if (m_isAutoFill && series_type != CHART_TYPE_Line && series_type != CHART_TYPE_Scatter && ind < 57) //line & scatter { CP_XML_NODE(L"a:solidFill") { @@ -378,11 +378,14 @@ int SS::serialize(std::wostream & _stream, int series_type, int indPt) else { if ((m_isVaried) && (*m_isVaried == false)) ind = 0; - CP_XML_NODE(L"a:solidFill") + if (ind < 57) { - CP_XML_NODE(L"a:srgbClr") + CP_XML_NODE(L"a:solidFill") { - CP_XML_ATTR(L"val", default_series_fill_color[ind]); + CP_XML_NODE(L"a:srgbClr") + { + CP_XML_ATTR(L"val", default_series_fill_color[ind]); + } } } } diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/SUPBOOK_bu.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/SUPBOOK_bu.cpp index 9a1e0948cc5..e5032354dbe 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/SUPBOOK_bu.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/SUPBOOK_bu.cpp @@ -198,7 +198,7 @@ int SUPBOOK::serialize(std::wostream & strm) return 0; } - if (book->bOleLink) + if (book->bOleLink && book->ctab == 0) { serialize_dde(strm); } @@ -387,7 +387,8 @@ int SUPBOOK::serialize_dde(std::wostream & strm) { CP_XML_ATTR(L"xmlns:r", L"http://schemas.openxmlformats.org/officeDocument/2006/relationships"); CP_XML_ATTR(L"ddeService", book->virtPath[0]); - CP_XML_ATTR(L"ddeTopic", book->virtPath[1]); + if (book->virtPath.size() > 1) + CP_XML_ATTR(L"ddeTopic", book->virtPath[1]); CP_XML_NODE(L"ddeItems") { @@ -409,6 +410,15 @@ int SUPBOOK::serialize_dde(std::wostream & strm) } } //ole items in oleLink + ExternDocName* oleDocName = dynamic_cast(external_name->body.get()); + if (oleDocName) + { + CP_XML_NODE(L"ddeItem") + { + CP_XML_ATTR(L"name", oleDocName->extName.value()); + CP_XML_ATTR(L"advise", external_name->fWantAdvise); + } + } } } } diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/WINDOW.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/WINDOW.cpp index 6ed24c6d634..34d31cd4590 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/WINDOW.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/WINDOW.cpp @@ -136,7 +136,7 @@ int WINDOW::serialize(std::wostream & stream) { CP_XML_ATTR(L"view", L"pageLayout"); } - if (window2->topLeftCell != L"A1") + if (!window2->topLeftCell.empty() && window2->topLeftCell != L"A1") { CP_XML_ATTR(L"topLeftCell", window2->topLeftCell); } diff --git a/MsBinaryFile/XlsFile/Format/Logic/ChartSheetSubstream.cpp b/MsBinaryFile/XlsFile/Format/Logic/ChartSheetSubstream.cpp index c9eeb8e8525..e29eca04fb0 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/ChartSheetSubstream.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/ChartSheetSubstream.cpp @@ -428,7 +428,7 @@ void ChartSheetSubstream::recalc(CHARTFORMATS* charts) if (series == NULL) continue; SerParent *parent = dynamic_cast(series->m_SerParent.get()); - if ( parent ) + if ( (parent) && (parent->series > 0 && parent->series <= charts->m_arSERIESFORMAT.size())) { SERIESFORMAT *series_owner = dynamic_cast(charts->m_arSERIESFORMAT[parent->series - 1].get()); if (series_owner) @@ -817,7 +817,11 @@ int ChartSheetSubstream::serialize_legend (std::wostream & _stream, const std::w while (it != m_mapTypeChart.end()) { CRT * crt = dynamic_cast(parent0->m_arCRT[it->first].get()); - + if (crt == NULL) + { + ++it; + continue; + } LD * ld = dynamic_cast(crt->m_LD.get()); if (ld == NULL) { @@ -953,7 +957,10 @@ int ChartSheetSubstream::serialize_plot_area (std::wostream & _stream) CP_XML_NODE(L"c:idx") { CP_XML_ATTR (L"val" , series_id); } CP_XML_NODE(L"c:order") { CP_XML_ATTR (L"val" , series_order++); } - series->m_arAI[0]->serialize(CP_XML_STREAM()); + if (!series->m_arAI.empty()) + { + series->m_arAI[0]->serialize(CP_XML_STREAM()); + } series_ss->serialize(CP_XML_STREAM(), crt->m_iChartType, -1); @@ -962,23 +969,26 @@ int ChartSheetSubstream::serialize_plot_area (std::wostream & _stream) /* if (arPivotData.empty() == false) { series->set_ref(arPivotData, i * 2); - }*/ - - if (crt->m_iChartType == CHART_TYPE_Scatter || - crt->m_iChartType == CHART_TYPE_Bubble) - { - serialize_ser(L"c:xVal", CP_XML_STREAM(), series_id, series->m_arAI[2], ser->sdtX, ser->cValx); - serialize_ser(L"c:yVal", CP_XML_STREAM(), series_id, series->m_arAI[1], ser->sdtY, ser->cValy); + }*/ - if (crt->m_iChartType == CHART_TYPE_Bubble) - serialize_ser(L"c:bubbleSize", CP_XML_STREAM(), series_id, series->m_arAI[3], ser->sdtBSize, ser->cValBSize); - } - else + if (series->m_arAI.size() > 1) { + if (crt->m_iChartType == CHART_TYPE_Scatter || + crt->m_iChartType == CHART_TYPE_Bubble) + { + serialize_ser(L"c:xVal", CP_XML_STREAM(), series_id, series->m_arAI[2], ser->sdtX, ser->cValx); + serialize_ser(L"c:yVal", CP_XML_STREAM(), series_id, series->m_arAI[1], ser->sdtY, ser->cValy); + + if (crt->m_iChartType == CHART_TYPE_Bubble && series->m_arAI.size() > 2) + serialize_ser(L"c:bubbleSize", CP_XML_STREAM(), series_id, series->m_arAI[3], ser->sdtBSize, ser->cValBSize); + } + else + { - serialize_ser(L"c:cat", CP_XML_STREAM(), series_id, series->m_arAI[2], ser->sdtX, ser->cValx); - serialize_ser(L"c:val", CP_XML_STREAM(), series_id, series->m_arAI[1], ser->sdtY, ser->cValy); - } + serialize_ser(L"c:cat", CP_XML_STREAM(), series_id, series->m_arAI[2], ser->sdtX, ser->cValx); + serialize_ser(L"c:val", CP_XML_STREAM(), series_id, series->m_arAI[1], ser->sdtY, ser->cValy); + } + } //----------------------------------------------------------------------------------------------------------------------------------------- series->serialize_parent(CP_XML_STREAM(), chart_formats); //----------------------------------------------------------------------------------------------------------------------------------------- @@ -1046,12 +1056,12 @@ int ChartSheetSubstream::serialize_plot_area (std::wostream & _stream) for (size_t i = 0; i < chart_formats->m_arAXISPARENT.size(); i++) { AXISPARENT* parent = dynamic_cast (chart_formats->m_arAXISPARENT[i].get()); - AxisParent* ax_parent = dynamic_cast (parent->m_AxisParent.get()); - AXES* axes = dynamic_cast (parent->m_AXES.get()); + AxisParent* ax_parent = parent ? dynamic_cast(parent->m_AxisParent.get()) : NULL; + AXES* axes = parent ? dynamic_cast(parent->m_AXES.get()) : NULL; if (axes) { - axes->serialize(CP_XML_STREAM(), (ax_parent->iax!=0) ); //secondary + axes->serialize(CP_XML_STREAM(), ax_parent ? (ax_parent->iax != 0) : false); //secondary } //else error complex_29s.xls } diff --git a/MsBinaryFile/XlsFile/Format/Logic/CommonSubstream.h b/MsBinaryFile/XlsFile/Format/Logic/CommonSubstream.h index f2859c4e28e..41028236e2a 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/CommonSubstream.h +++ b/MsBinaryFile/XlsFile/Format/Logic/CommonSubstream.h @@ -48,7 +48,7 @@ class CommonSubstream GlobalWorkbookInfoPtr global_info_; size_t ws_index_; - std::vector m_arHFPictureDrawing; + std::vector m_arHFPictureDrawing; // тут OfficeArtDgContainer - описания шейпов ... BaseObjectPtr m_PAGESETUP; BaseObjectPtr m_PROTECTION; diff --git a/MsBinaryFile/XlsFile/Format/Logic/EncryptionStream.cpp b/MsBinaryFile/XlsFile/Format/Logic/EncryptionStream.cpp index 396bd55deef..9290f225a52 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/EncryptionStream.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/EncryptionStream.cpp @@ -78,15 +78,28 @@ namespace XLS BYTE fStream = ((BYTE*)(buf2 + pos))[0]; pos += 1; pos += 4; - std::wstring name = NSFile::CUtf8Converter::GetWStringFromUTF16((unsigned short*)(buf2 + pos), NameSize); pos += NameSize * 2; + std::wstring name; + + if (pos + NameSize < StreamDescriptorArraySize) + { + name = NSFile::CUtf8Converter::GetWStringFromUTF16((unsigned short*)(buf2 + pos), NameSize); + } + pos += NameSize * 2; + + if (pos + 1 < StreamDescriptorArraySize && buf2[pos] == 0 && buf2[pos + 1] == 0) + pos += 2; // padding??? std::pair, size_t> data; - data.first = boost::shared_array(new BYTE[StreamSize]); - data.second = StreamSize; - memcpy(data.first.get(), buf1 + StreamOffset - 8, StreamSize); // 8 = start stream offset + if (StreamSize + StreamOffset < StreamDescriptorArrayOffset) + { + data.first = boost::shared_array(new BYTE[StreamSize]); + data.second = StreamSize; + memcpy(data.first.get(), buf1 + StreamOffset - 8, StreamSize); // 8 = start stream offset + } streams.insert(std::make_pair(name, data)); + } delete[]buf1; diff --git a/MsBinaryFile/XlsFile/Format/Logic/GlobalWorkbookInfo.cpp b/MsBinaryFile/XlsFile/Format/Logic/GlobalWorkbookInfo.cpp index 6bde5e066c5..d331eb57836 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/GlobalWorkbookInfo.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/GlobalWorkbookInfo.cpp @@ -32,8 +32,10 @@ #include "GlobalWorkbookInfo.h" #include "Biff_records/Font.h" -#include "../../../../DesktopEditor/graphics/pro/Fonts.h" +#include "Biff_records/Format.h" +#include "../../../../DesktopEditor/graphics/pro/Fonts.h" +#include "../../../../OOXML/Base/Unit.h" namespace XLS { @@ -93,6 +95,8 @@ std::vector GlobalWorkbookInfo::arXti_External_stat std::unordered_map GlobalWorkbookInfo::mapTableNames_static; std::unordered_map> GlobalWorkbookInfo::mapTableColumnNames_static; std::vector GlobalWorkbookInfo::arDefineNames_static; +std::unordered_map> GlobalWorkbookInfo::mapXtiTables_static; + GlobalWorkbookInfo::GlobalWorkbookInfo(const unsigned short code_page, XlsConverter * converter) : CodePage(code_page), xls_converter(converter) { fill_x_ids[FillInfo(0, 0, 0)] = 0; @@ -125,7 +129,7 @@ GlobalWorkbookInfo::GlobalWorkbookInfo(const unsigned short code_page, XlsConver idPivotCache = 0; currentPivotCacheRecord = 0; - +// common for all lcid mapDefaultFormatCode.insert(std::make_pair(L"0", 1)); mapDefaultFormatCode.insert(std::make_pair(L"0.00", 2)); mapDefaultFormatCode.insert(std::make_pair(L"#,##0", 3)); @@ -154,6 +158,35 @@ GlobalWorkbookInfo::GlobalWorkbookInfo(const unsigned short code_page, XlsConver mapDefaultFormatCode.insert(std::make_pair(L"##0.0E+0", 48)); mapDefaultFormatCode.insert(std::make_pair(L"@", 49)); mapDefaultFormatCode.insert(std::make_pair(L"General", 0)); + + mapDefaultFormatCodeNum.insert(std::make_pair(0, L"General")); + mapDefaultFormatCodeNum.insert(std::make_pair(1, L"0")); + mapDefaultFormatCodeNum.insert(std::make_pair(2, L"0.00")); + mapDefaultFormatCodeNum.insert(std::make_pair(3, L"#,##0")); + mapDefaultFormatCodeNum.insert(std::make_pair(4, L"#,##0.00")); + mapDefaultFormatCodeNum.insert(std::make_pair(9, L"0%")); + mapDefaultFormatCodeNum.insert(std::make_pair(10,L"0.00%")); + mapDefaultFormatCodeNum.insert(std::make_pair(11, L"0.00E+00")); + mapDefaultFormatCodeNum.insert(std::make_pair(12, L"# ?/?")); + mapDefaultFormatCodeNum.insert(std::make_pair(13, L"# ??/??")); + mapDefaultFormatCodeNum.insert(std::make_pair(14, L"mm-dd-yy")); + mapDefaultFormatCodeNum.insert(std::make_pair(15, L"d-mmm-yy")); + mapDefaultFormatCodeNum.insert(std::make_pair(16, L"d-mmm")); + mapDefaultFormatCodeNum.insert(std::make_pair(17, L"mmm-yy")); + mapDefaultFormatCodeNum.insert(std::make_pair(18, L"h:mm AM/PM")); + mapDefaultFormatCodeNum.insert(std::make_pair(19, L"h:mm:ss AM/PM")); + mapDefaultFormatCodeNum.insert(std::make_pair(20, L"h:mm")); + mapDefaultFormatCodeNum.insert(std::make_pair(21, L"h:mm:ss")); + mapDefaultFormatCodeNum.insert(std::make_pair(22, L"m/d/yy h:mm")); + mapDefaultFormatCodeNum.insert(std::make_pair(37, L"#,##0 ;(#,##0)")); + mapDefaultFormatCodeNum.insert(std::make_pair(38, L"#,##0 ;[Red](#,##0)")); + mapDefaultFormatCodeNum.insert(std::make_pair(39, L"#,##0.00;(#,##0.00)")); + mapDefaultFormatCodeNum.insert(std::make_pair(40, L"#,##0.00;[Red](#,##0.00)")); + mapDefaultFormatCodeNum.insert(std::make_pair(45, L"mm:ss")); + mapDefaultFormatCodeNum.insert(std::make_pair(46, L"[h]:mm:ss")); + mapDefaultFormatCodeNum.insert(std::make_pair(47, L"mmss.0")); + mapDefaultFormatCodeNum.insert(std::make_pair(48, L"##0.0E+0")); + mapDefaultFormatCodeNum.insert(std::make_pair(49, L"@")); } GlobalWorkbookInfo::~GlobalWorkbookInfo() @@ -220,9 +253,57 @@ void GlobalWorkbookInfo::RegisterPaletteColor(int id, const std::wstring & rgb) { colors_palette.insert(std::make_pair(id, rgb)); } -_UINT16 GlobalWorkbookInfo::RegisterNumFormat(_UINT16 ifmt, const std::wstring & format_code) +void GlobalWorkbookInfo::RegisterNumFormat(BaseObjectPtr element) { - _UINT16 ifmt_used = ifmt; + Format* fmt = dynamic_cast(element.get()); + if (!fmt) return; + + if (fmt->ifmt == 0xffff) + { + std::map::iterator pFind = mapDefaultFormatCode.find(fmt->stFormat); + if (pFind != mapDefaultFormatCode.end()) + { + fmt->ifmt_used = fmt->ifmt = pFind->second; + } + else + { + fmt->ifmt_used = fmt->ifmt = last_User_NumFmt++; + } + } + else + { + std::map<_UINT16, _UINT16>::iterator pFindCode = mapUsedFormatCode.find(fmt->ifmt); + if (pFindCode != mapUsedFormatCode.end()) + { + fmt->ifmt_used = pFindCode->second; + } + else + { + if (fmt->ifmt > 49) + { + fmt->ifmt_used = last_User_NumFmt++; + } + else + { + fmt->ifmt_used = fmt->ifmt; + } + mapUsedFormatCode.insert(std::make_pair(fmt->ifmt, fmt->ifmt_used)); + } + } + std::map<_UINT16, BaseObjectPtr>::iterator pFindFormat = m_mapNumFormats.find(fmt->ifmt_used); + if (pFindFormat == m_mapNumFormats.end()) + { + m_mapNumFormats.insert(std::make_pair(fmt->ifmt_used, element)); + } + else + { + //меняем + pFindFormat->second = element; + } +} +_UINT16 GlobalWorkbookInfo::RegisterNumFormat(_UINT16 ifmt, const std::wstring & format_code_) +{ + std::wstring format_code = format_code_; std::map<_UINT16, _UINT16>::iterator pFind = mapUsedFormatCode.find(ifmt); if (pFind != mapUsedFormatCode.end()) @@ -231,17 +312,86 @@ _UINT16 GlobalWorkbookInfo::RegisterNumFormat(_UINT16 ifmt, const std::wstring & } else { + if (format_code.empty()) + { + if (59 <= ifmt && ifmt <= 78) + { + if (69 <= ifmt && ifmt <= 71) + { + ifmt += 1; + } + ifmt -= 58; + } + else if (79 <= ifmt && ifmt <= 81) + { + ifmt -= 34; + } + switch (ifmt) + { + case 23: + case 24: + case 25: + case 26: + ifmt = 0; + break; + case 27: + case 28: + case 29: + case 30: + case 31: + case 36: + case 50: + case 51: + case 52: + case 53: + case 54: + case 55: + case 56: + case 57: + case 58: + ifmt = 14; + break; + case 32: + case 33: + case 34: + case 35: + ifmt = 21; + break; + } + + std::map<_UINT16, std::wstring>::iterator pFindCode = mapDefaultFormatCodeNum.find(ifmt); + if (pFindCode != mapDefaultFormatCodeNum.end()) + { + format_code = pFindCode->second; + } + else + { + // ???? todooo + } + } + + _UINT16 ifmt_used = ifmt; if (ifmt > 49) { - ifmt_used = last_User_NumFmt++; + ifmt_used = last_User_NumFmt++; } - else + + std::map<_UINT16, BaseObjectPtr>::iterator pFindFormat = m_mapNumFormats.find(ifmt_used); + if (pFindFormat == m_mapNumFormats.end()) { - //todooo проверка по mapDefaultFormatCode -> ooxml fmtNum format code + // генерим хоть что то + Format* fmt = new Format(); + fmt->ifmt = ifmt; + fmt->ifmt_used = ifmt_used; + + fmt->stFormat = XmlUtils::EncodeXmlString(format_code, true); + + m_mapNumFormats.insert(std::make_pair(fmt->ifmt_used, BaseObjectPtr(fmt))); } mapUsedFormatCode.insert(std::make_pair(ifmt, ifmt_used)); + + return ifmt_used; } - return ifmt_used; } const int GlobalWorkbookInfo::RegistrDxfn(const std::wstring & dxfn) { diff --git a/MsBinaryFile/XlsFile/Format/Logic/GlobalWorkbookInfo.h b/MsBinaryFile/XlsFile/Format/Logic/GlobalWorkbookInfo.h index 9b6c9da4766..ebacd3e197d 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/GlobalWorkbookInfo.h +++ b/MsBinaryFile/XlsFile/Format/Logic/GlobalWorkbookInfo.h @@ -89,7 +89,7 @@ class GlobalWorkbookInfo const size_t RegisterFontId (const FontInfo& font); const int RegistrDxfn (const std::wstring& dx_style); _UINT16 RegisterNumFormat (_UINT16 ifmt, const std::wstring & format_code); - + void RegisterNumFormat (BaseObjectPtr element); void RegisterPaletteColor(int id, const std::wstring & argb); void GetDigitFontSizePixels(); @@ -114,7 +114,6 @@ class GlobalWorkbookInfo std::map fonts_charsets; std::map colors_palette; - std::vector m_arNumFormats; std::vector m_arFonts; PPTX::ThemePtr m_pTheme; @@ -202,8 +201,11 @@ class GlobalWorkbookInfo int cellStyleXfs_count; int cellStyleDxfs_count; - std::map mapDefaultFormatCode; + std::map mapDefaultFormatCode; + std::map<_UINT16, std::wstring> mapDefaultFormatCodeNum; + std::map<_UINT16, _UINT16> mapUsedFormatCode; //original, used + std::map<_UINT16, BaseObjectPtr> m_mapNumFormats; std::map mapUserDxfs; std::vector arrUserDxfs; @@ -219,6 +221,7 @@ class GlobalWorkbookInfo static std::unordered_map mapTableNames_static; static std::unordered_map> mapTableColumnNames_static; std::unordered_map mapTableGuidsIndex; + static std::unordered_map> mapXtiTables_static; std::unordered_map> pivotCacheRecordType; int currentPivotCacheRecord; diff --git a/MsBinaryFile/XlsFile/Format/Logic/GlobalsSubstream.cpp b/MsBinaryFile/XlsFile/Format/Logic/GlobalsSubstream.cpp index 25ebf8b11e8..eb8fa5c5da9 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/GlobalsSubstream.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/GlobalsSubstream.cpp @@ -105,7 +105,7 @@ //#include "Biff_records/XCT.h" //#include "Biff_records/CRN.h" -#include "Biff_structures/ODRAW/OfficeArtDgContainer.h" +#include "Biff_structures/ODRAW/SimpleOfficeArtContainers.h" namespace XLS {; @@ -170,7 +170,13 @@ const bool GlobalsSubstream::loadContent(BinProcessor& proc) { CFRecordType::TypeId type = proc.getNextRecordType(); - if (type == rt_NONE) break; + if (type == rt_NONE) + { + proc.SkipRecord(); + type = proc.getNextRecordType(); + if (type == rt_NONE) + break; + } if (type == rt_EOF) { proc.mandatory(); @@ -657,7 +663,7 @@ void GlobalsSubstream::LoadHFPicture() hf = dynamic_cast(m_arHFPicture[j].get()); record.appendRawData(hf->recordDrawingGroup); } - ODRAW::OfficeArtDgContainerPtr rgDrawing = ODRAW::OfficeArtDgContainerPtr(new ODRAW::OfficeArtDgContainer(ODRAW::OfficeArtRecord::CA_HF)); + ODRAW::OfficeArtDggContainerPtr rgDrawing = ODRAW::OfficeArtDggContainerPtr(new ODRAW::OfficeArtDggContainer(ODRAW::OfficeArtRecord::CA_HF)); rgDrawing->loadFields(record); m_arHFPictureDrawing.push_back(rgDrawing); current_size_hf = 0; @@ -674,7 +680,15 @@ void GlobalsSubstream::LoadHFPicture() HFPicture* hf = dynamic_cast(m_arHFPicture[j].get()); record.appendRawData(hf->recordDrawingGroup); } - ODRAW::OfficeArtDgContainerPtr rgDrawing = ODRAW::OfficeArtDgContainerPtr(new ODRAW::OfficeArtDgContainer(ODRAW::OfficeArtRecord::CA_HF)); + ODRAW::OfficeArtRecordHeader rh_test; + record >> rh_test; + record.RollRdPtrBack(8);//sizeof(OfficeArtRecordHeader) + + if ((rh_test.recType & 0xF000) != 0xF000) + { + return; + } + ODRAW::OfficeArtDggContainerPtr rgDrawing = ODRAW::OfficeArtDggContainerPtr(new ODRAW::OfficeArtDggContainer(ODRAW::OfficeArtRecord::CA_HF)); rgDrawing->loadFields(record); m_arHFPictureDrawing.push_back(rgDrawing); } @@ -699,6 +713,8 @@ void GlobalsSubstream::UpdateXti() XTI* xti = dynamic_cast(extern_sheet->rgXTI[i].get()); if (!xti) continue; + if (xti->iSupBook >= m_arSUPBOOK.size()) continue; + SUPBOOK* index_book = dynamic_cast(m_arSUPBOOK[xti->iSupBook].get()); if (!index_book) continue; @@ -797,8 +813,8 @@ void GlobalsSubstream::UpdateDefineNames() else { std::vector ar(ind_sheet + 1); - - ar[ind_sheet] = value; + if(ar.size() > ind_sheet) + ar[ind_sheet] = value; //ar.push_back(value); global_info_->mapDefineNames.insert(std::make_pair(name, ar)); diff --git a/MsBinaryFile/XlsFile/Format/Logic/GlobalsSubstream.h b/MsBinaryFile/XlsFile/Format/Logic/GlobalsSubstream.h index d9a96d3f96e..5a464cceee3 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/GlobalsSubstream.h +++ b/MsBinaryFile/XlsFile/Format/Logic/GlobalsSubstream.h @@ -88,7 +88,7 @@ class GlobalsSubstream: public CompositeObject //std::vector m_arPIVOTCACHEDEFINITION; -> GlobalWorkbookInfo std::vector m_arDConn; - std::vector m_arHFPictureDrawing; + std::vector m_arHFPictureDrawing; // тут OfficeArtDggContainer - картинки ... unsigned short code_page_; GlobalWorkbookInfoPtr global_info_; diff --git a/MsBinaryFile/XlsFile/Format/Logic/WorkbookStreamObject.cpp b/MsBinaryFile/XlsFile/Format/Logic/WorkbookStreamObject.cpp index 3609f8caafe..2050d91a63c 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/WorkbookStreamObject.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/WorkbookStreamObject.cpp @@ -92,16 +92,20 @@ const bool WorkbookStreamObject::loadContent(BinProcessor& proc) { if(GlobalsSubstream_found) { - Log::error("Multiple GLOBALS substreams found in intermediate XML."); - return false; + Log::error("Multiple GLOBALS substreams found"); + return true; + } + else + { + Log::event("Globals substream detected"); } - Log::event("Globals substream detected"); GlobalsSubstream global_substream(code_page_); if((proc.mandatory(global_substream)) && (elements_.size() > 0)) { GlobalsSubstream_found = true; - - m_GlobalsSubstream = elements_.back(); elements_.pop_back(); + m_GlobalsSubstream = elements_.back(); + + elements_.pop_back(); } if (!GlobalsSubstream_found) return false; } @@ -110,7 +114,7 @@ const bool WorkbookStreamObject::loadContent(BinProcessor& proc) { if(!GlobalsSubstream_found) { - Log::error("GLOBALS substream is not the first substream in intermediate XML."); + Log::error("GLOBALS substream is not the first substream"); return false; } Log::event("Worksheet or Dialog substream detected"); diff --git a/MsBinaryFile/XlsFile/Format/Logic/WorksheetSubstream.cpp b/MsBinaryFile/XlsFile/Format/Logic/WorksheetSubstream.cpp index 924608dfef6..e6d83c91c1b 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/WorksheetSubstream.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/WorksheetSubstream.cpp @@ -89,6 +89,7 @@ #include "Biff_records/XF.h" #include "Biff_records/Format.h" #include "Biff_records/Font.h" +#include "Biff_records/Palette.h" #include "Biff_structures/ODRAW/OfficeArtDgContainer.h" @@ -618,6 +619,7 @@ const bool WorksheetSubstream::loadContent(BinProcessor& proc) case rt_XF_BIFF2: case rt_XF_BIFF3: case rt_XF_BIFF4: + case rt_XF: { size_t cell_xf_current_id = 0; size_t style_xf_current_id = 0; @@ -638,6 +640,15 @@ const bool WorksheetSubstream::loadContent(BinProcessor& proc) XF_BIFF2 xf(cell_xf_current_id, style_xf_current_id); count = proc.repeated(xf, 0, 0); } + else + { + int store = global_info_->Version; + global_info_->Version = 0x0600; + XF xf(cell_xf_current_id, style_xf_current_id); + count = proc.repeated(xf, 0, 0); + + global_info_->Version = store; + } XFS* xfs = new XFS(); int ind = 0; while (count > 0 && !elements_.empty()) @@ -681,24 +692,7 @@ const bool WorksheetSubstream::loadContent(BinProcessor& proc) while (count > 0) { - Format *fmt = dynamic_cast(elements_.front().get()); - if ((fmt) && (fmt->ifmt == 0xffff)) - { - std::map::iterator pFind = global_info_->mapDefaultFormatCode.find(fmt->stFormat); - if (pFind != global_info_->mapDefaultFormatCode.end()) - { - fmt->ifmt_used = fmt->ifmt = pFind->second; - } - else - { - fmt->ifmt_used = fmt->ifmt = global_info_->last_User_NumFmt++; - } - } - else - { - fmt->ifmt_used = global_info_->RegisterNumFormat(fmt->ifmt, fmt->stFormat); - } - global_info_->m_arNumFormats.push_back(elements_.front()); + global_info_->RegisterNumFormat(elements_.front()); elements_.pop_front(); count--; } @@ -713,6 +707,16 @@ const bool WorksheetSubstream::loadContent(BinProcessor& proc) elements_.pop_back(); } }break; + case rt_Palette: + { + if (proc.optional()) + { + FORMATTING* fmts = dynamic_cast(m_Formating.get()); + if (fmts) + fmts->m_Palette = elements_.back(); + elements_.pop_back(); + } + }break; default://unknown .... skip { proc.SkipRecord(); diff --git a/MsBinaryFile/XlsFile/Format/Logic/XlsElementsType.h b/MsBinaryFile/XlsFile/Format/Logic/XlsElementsType.h index 225b9a43c74..3d93ea17f49 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/XlsElementsType.h +++ b/MsBinaryFile/XlsFile/Format/Logic/XlsElementsType.h @@ -717,6 +717,7 @@ enum ElementType typeOfficeArtRecord = 3000, typeOfficeArtBStoreContainerFileBlock, typeOfficeArtDgContainer, + typeOfficeArtDggContainer, typeOfficeArtCOLORREF, typeOfficeArtFOPTE, typeOfficeArtFRIT, @@ -929,6 +930,7 @@ enum ElementType typeTABLESLICERCACHEIDS, typeSLICERCACHEID, typeTABLESLICERCACHEID, + typeFMD }; diff --git a/MsBinaryFile/XlsFile/Format/Logic/pri/xls_format_logic.cpp b/MsBinaryFile/XlsFile/Format/Logic/pri/xls_format_logic.cpp index f91386f6f84..50e0b619f6e 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/pri/xls_format_logic.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/pri/xls_format_logic.cpp @@ -665,6 +665,7 @@ #include "../Biff_structures/BIFF12/UncheckedSqRfX.cpp" #include "../Biff_structures/BIFF12/SxOs.cpp" #include "../Biff_structures/BIFF12/SxSu.cpp" +#include "../Biff_structures/FutureFunctionParser.cpp" #include "../Biff_unions/AI.cpp" #include "../Biff_unions/ATTACHEDLABEL_bu.cpp" diff --git a/MsBinaryFile/XlsFile/Format/Logic/pri/xls_logic.pri b/MsBinaryFile/XlsFile/Format/Logic/pri/xls_logic.pri index c6296088a81..d6feddf7079 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/pri/xls_logic.pri +++ b/MsBinaryFile/XlsFile/Format/Logic/pri/xls_logic.pri @@ -420,6 +420,7 @@ SOURCES += \ $$LOGIC_DIR/Biff_structures/FrtRefHeaderNoGrbit.cpp \ $$LOGIC_DIR/Biff_structures/FrtRefHeaderU.cpp \ $$LOGIC_DIR/Biff_structures/Ftab_Cetab.cpp \ + $$LOGIC_DIR/Biff_structures/FutureFunctionParser.cpp \ $$LOGIC_DIR/Biff_structures/FtCblsData.cpp \ $$LOGIC_DIR/Biff_structures/FtCf.cpp \ $$LOGIC_DIR/Biff_structures/FtCmo.cpp \ diff --git a/OOXML/Base/Unit.cpp b/OOXML/Base/Unit.cpp index c4105c4dfc6..bbd808e890e 100644 --- a/OOXML/Base/Unit.cpp +++ b/OOXML/Base/Unit.cpp @@ -570,7 +570,26 @@ namespace XmlUtils } unsigned int GetUInteger(const std::wstring& string) { - return (unsigned int)GetInteger(string); + if (string.empty()) return 0; + + unsigned int iVal = 0; + try + { + iVal = std::stod(string); + } + catch(...) + { + try + { + iVal = std::wcstoll(string.c_str(), NULL, 10); + } + catch(...) + { + return 0; + } + } + + return iVal; } double GetDouble(const std::wstring& string) { diff --git a/OOXML/Binary/Document/BinReader/DocumentWriter.cpp b/OOXML/Binary/Document/BinReader/DocumentWriter.cpp index c79cc66f74a..536d75476f9 100644 --- a/OOXML/Binary/Document/BinReader/DocumentWriter.cpp +++ b/OOXML/Binary/Document/BinReader/DocumentWriter.cpp @@ -54,18 +54,23 @@ xmlns:o=\"urn:schemas-microsoft-com:office:office\" \ xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" \ xmlns:m=\"http://schemas.openxmlformats.org/officeDocument/2006/math\" \ xmlns:v=\"urn:schemas-microsoft-com:vml\" \ -xmlns:wp14=\"http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing\" \ xmlns:wp=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\" \ -xmlns:w10=\"urn:schemas-microsoft-com:office:word\" \ xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" \ -xmlns:w14=\"http://schemas.microsoft.com/office/word/2010/wordml\" \ -xmlns:w15=\"http://schemas.microsoft.com/office/word/2012/wordml\" \ xmlns:wpg=\"http://schemas.microsoft.com/office/word/2010/wordprocessingGroup\" \ xmlns:wpi=\"http://schemas.microsoft.com/office/word/2010/wordprocessingInk\" \ xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" \ xmlns:wne=\"http://schemas.microsoft.com/office/word/2006/wordml\" \ xmlns:wps=\"http://schemas.microsoft.com/office/word/2010/wordprocessingShape\" \ -mc:Ignorable=\"w14 w15 wp14\">")); +xmlns:w10=\"urn:schemas-microsoft-com:office:word\" \ +xmlns:wp14=\"http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing\" \ +xmlns:w14=\"http://schemas.microsoft.com/office/word/2010/wordml\" \ +xmlns:w15=\"http://schemas.microsoft.com/office/word/2012/wordml\" \ +xmlns:w16cex=\"http://schemas.microsoft.com/office/word/2018/wordml/cex\" \ +xmlns:w16cid=\"http://schemas.microsoft.com/office/word/2016/wordml/cid\" \ +xmlns:w16=\"http://schemas.microsoft.com/office/word/2018/wordml\" \ +xmlns:w16sdtdh=\"http://schemas.microsoft.com/office/word/2020/wordml/sdtdatahash\" \ +xmlns:w16se=\"http://schemas.microsoft.com/office/word/2015/wordml/symex\" \ +mc:Ignorable=\"w14 w15 w16se w16cid w16 w16cex w16sdtdh wp14\">")); oFile.WriteStringUTF8(m_oBackground.GetData()); @@ -88,18 +93,23 @@ xmlns:o=\"urn:schemas-microsoft-com:office:office\" \ xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" \ xmlns:m=\"http://schemas.openxmlformats.org/officeDocument/2006/math\" \ xmlns:v=\"urn:schemas-microsoft-com:vml\" \ -xmlns:wp14=\"http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing\" \ xmlns:wp=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\" \ -xmlns:w10=\"urn:schemas-microsoft-com:office:word\" \ xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" \ -xmlns:w14=\"http://schemas.microsoft.com/office/word/2010/wordml\" \ -xmlns:w15=\"http://schemas.microsoft.com/office/word/2012/wordml\" \ xmlns:wpg=\"http://schemas.microsoft.com/office/word/2010/wordprocessingGroup\" \ xmlns:wpi=\"http://schemas.microsoft.com/office/word/2010/wordprocessingInk\" \ xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" \ xmlns:wne=\"http://schemas.microsoft.com/office/word/2006/wordml\" \ xmlns:wps=\"http://schemas.microsoft.com/office/word/2010/wordprocessingShape\" \ -mc:Ignorable=\"w14 w15 wp14\">")); +xmlns:w10=\"urn:schemas-microsoft-com:office:word\" \ +xmlns:wp14=\"http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing\" \ +xmlns:w14=\"http://schemas.microsoft.com/office/word/2010/wordml\" \ +xmlns:w15=\"http://schemas.microsoft.com/office/word/2012/wordml\" \ +xmlns:w16cex=\"http://schemas.microsoft.com/office/word/2018/wordml/cex\" \ +xmlns:w16cid=\"http://schemas.microsoft.com/office/word/2016/wordml/cid\" \ +xmlns:w16=\"http://schemas.microsoft.com/office/word/2018/wordml\" \ +xmlns:w16sdtdh=\"http://schemas.microsoft.com/office/word/2020/wordml/sdtdatahash\" \ +xmlns:w16se=\"http://schemas.microsoft.com/office/word/2015/wordml/symex\" \ +mc:Ignorable=\"w14 w15 w16se w16cid w16 w16cex w16sdtdh wp14\">")); oFile.WriteStringUTF8(m_oBackground.GetData()); diff --git a/OOXML/Binary/Document/BinReader/ReaderClasses.cpp b/OOXML/Binary/Document/BinReader/ReaderClasses.cpp index cb770c58356..b7821ba0f7d 100644 --- a/OOXML/Binary/Document/BinReader/ReaderClasses.cpp +++ b/OOXML/Binary/Document/BinReader/ReaderClasses.cpp @@ -681,7 +681,7 @@ namespace BinDocxRW { { std::wstring sUserName = XmlUtils::EncodeXmlString(pComment->UserName); sRes += L" w:author=\""; - sRes += (sUserName); + sRes += XmlUtils::EncodeXmlString(sUserName); sRes += L"\""; } if (false == pComment->Date.empty()) diff --git a/OOXML/Binary/Document/BinReader/Readers.cpp b/OOXML/Binary/Document/BinReader/Readers.cpp index ed890a8654a..1c09e41e8ae 100644 --- a/OOXML/Binary/Document/BinReader/Readers.cpp +++ b/OOXML/Binary/Document/BinReader/Readers.cpp @@ -35,8 +35,6 @@ #include "../BinWriter/BinReaderWriterDefines.h" #include "../../Sheets/Writer/BinaryReader.h" -#include "../../../PPTXFormat/App.h" -#include "../../../PPTXFormat/Core.h" #include "../../../PPTXFormat/Logic/HeadingVariant.h" #include "../../../DocxFormat/Settings/Settings.h" @@ -875,7 +873,13 @@ int Binary_rPrReader::ReadContent(BYTE type, long length, void* poResult) pRPr->m_oSnapToGrid.Init(); pRPr->m_oSnapToGrid->m_oVal.FromBool(m_oBufferedStream.GetBool()); }break; - default: + case c_oSerProp_rPrType::Kern: + { + pRPr->m_oKern.Init(); pRPr->m_oKern->m_oVal.Init(); + pRPr->m_oKern->m_oVal->FromHps(m_oBufferedStream.GetLong()); + }break; + + default: res = c_oSerConstants::ReadUnknown; break; } @@ -1036,6 +1040,16 @@ int Binary_pPrReader::ReadContent(BYTE type, long length, void* poResult) pPPr->m_oCnfStyle.Init(); READ1_DEF(length, res, this->ReadCnfStyle, pPPr->m_oCnfStyle.GetPointer()); }break; + case c_oSerProp_pPrType::SnapToGrid: + { + pPPr->m_oSnapToGrid.Init(); + pPPr->m_oSnapToGrid->m_oVal.FromBool(m_oBufferedStream.GetBool()); + }break; + case c_oSerProp_pPrType::Bidi: + { + pPPr->m_oBidi.Init(); + pPPr->m_oBidi->m_oVal.FromBool(m_oBufferedStream.GetBool()); + }break; default: res = c_oSerConstants::ReadUnknown; break; @@ -1178,6 +1192,16 @@ int Binary_pPrReader::ReadSpacing(BYTE type, long length, void* poResult) pSpacing->m_oAfterAutospacing.Init(); pSpacing->m_oAfterAutospacing->FromBool(m_oBufferedStream.GetBool()); break; + case c_oSerProp_pPrType::Spacing_AfterLines: + { + pSpacing->m_oAfterLines.Init(); + pSpacing->m_oAfterLines->SetValue(m_oBufferedStream.GetLong()); + }break; + case c_oSerProp_pPrType::Spacing_BeforeLines: + { + pSpacing->m_oBeforeLines.Init(); + pSpacing->m_oBeforeLines->SetValue(m_oBufferedStream.GetLong()); + }break; default: res = c_oSerConstants::ReadUnknown; break; @@ -1340,11 +1364,17 @@ int Binary_pPrReader::ReadBorder(BYTE type, long length, void* poResult) else if ( c_oSerBorderType::Value == type ) { pBorder->m_oVal.Init(); - if (border_Single == m_oBufferedStream.GetUChar()) + + if (0 != m_oBufferedStream.GetUChar()) pBorder->m_oVal->SetValue(SimpleTypes::bordervalueSingle); else pBorder->m_oVal->SetValue(SimpleTypes::bordervalueNone); } + else if (c_oSerBorderType::ValueType == type) + { + pBorder->m_oVal.Init(); + pBorder->m_oVal->SetValue((SimpleTypes::EBorder)m_oBufferedStream.GetLong()); + } else if ( c_oSerBorderType::ColorTheme == type ) { CThemeColor ThemeColor; @@ -1528,6 +1558,11 @@ int Binary_pPrReader::Read_SecPr(BYTE type, long length, void* poResult) pSectPr->m_oRtlGutter.Init(); pSectPr->m_oRtlGutter->m_oVal.FromBool(m_oBufferedStream.GetBool()); } + else if (c_oSerProp_secPrType::docGrid == type) + { + pSectPr->m_oDocGrid.Init(); + READ1_DEF(length, res, this->ReadDocGrid, pSectPr->m_oDocGrid.GetPointer()); + } else res = c_oSerConstants::ReadUnknown; return res; @@ -1562,6 +1597,30 @@ int Binary_pPrReader::ReadFootnotePr(BYTE type, long length, void* poResult) res = c_oSerConstants::ReadUnknown; return res; } +int Binary_pPrReader::ReadDocGrid(BYTE type, long length, void* poResult) +{ + ComplexTypes::Word::CDocGrid* pDocGrid = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + + if (c_oSerProp_DocGrid::Type == type) + { + pDocGrid->m_oType.Init(); + pDocGrid->m_oType->SetValueFromByte(m_oBufferedStream.GetUChar()); + } + else if (c_oSerProp_DocGrid::CharSpace == type) + { + pDocGrid->m_oCharSpace.Init(); + pDocGrid->m_oCharSpace->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSerProp_DocGrid::LinePitch == type) + { + pDocGrid->m_oLinePitch.Init(); + pDocGrid->m_oLinePitch->SetValue(m_oBufferedStream.GetLong()); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} int Binary_pPrReader::ReadEndnotePr(BYTE type, long length, void* poResult) { OOX::Logic::CEdnProps* pEdnProps = static_cast(poResult); @@ -1707,7 +1766,7 @@ int Binary_pPrReader::Read_pgSz(BYTE type, long length, void* poResult) if ( c_oSer_pgSzType::Orientation == type ) { pPageSz->m_oOrient.Init(); - pPageSz->m_oOrient->SetValueFromByte( m_oBufferedStream.GetUChar()); + pPageSz->m_oOrient->SetValueFromByte( m_oBufferedStream.GetUChar() == 1 ? 0 : 1); } else if ( c_oSer_pgSzType::W == type ) { @@ -1872,6 +1931,21 @@ int Binary_pPrReader::Read_pageNumType(BYTE type, long length, void* poResult) pCPageNumber->m_oStart.Init(); pCPageNumber->m_oStart->SetValue(m_oBufferedStream.GetLong()); } + else if (c_oSerProp_secPrPageNumType::fmt == type) + { + pCPageNumber->m_oFmt.Init(); + pCPageNumber->m_oFmt->SetValueFromByte(m_oBufferedStream.GetUChar()); + } + else if (c_oSerProp_secPrPageNumType::chapStyle == type) + { + pCPageNumber->m_oChapStyle.Init(); + pCPageNumber->m_oChapStyle->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSerProp_secPrPageNumType::chapSep == type) + { + pCPageNumber->m_oChapSep.Init(); + pCPageNumber->m_oChapSep->SetValueFromByte(m_oBufferedStream.GetUChar()); + } else res = c_oSerConstants::ReadUnknown; return res; @@ -3598,13 +3672,13 @@ int Binary_CustomsTableReader::ReadCustom(BYTE type, long length, void* poResult int res = c_oSerConstants::ReadOk; READ1_DEF(length, res, this->ReadCustomContent, &oCustomXmlProps); - if (false == oCustomXmlProps.m_oCustomXmlContentA.empty()) + if (false == oCustomXmlProps.m_oCustomXmlContent.empty()) { - m_oFileWriter.m_oCustomXmlWriter.WriteCustomA(oCustomXmlProps.toXML(), oCustomXmlProps.m_oCustomXmlContentA, m_oFileWriter.m_bGlossaryMode); + m_oFileWriter.m_oCustomXmlWriter.WriteCustom(oCustomXmlProps.toXML(), oCustomXmlProps.m_oCustomXmlContent, m_oFileWriter.m_bGlossaryMode); } - else if (false == oCustomXmlProps.m_oCustomXmlContent.empty()) + else { - m_oFileWriter.m_oCustomXmlWriter.WriteCustom(oCustomXmlProps.toXML(), oCustomXmlProps.m_oCustomXmlContent, m_oFileWriter.m_bGlossaryMode); + m_oFileWriter.m_oCustomXmlWriter.WriteCustomA(oCustomXmlProps.toXML(), oCustomXmlProps.m_oCustomXmlContentA, m_oFileWriter.m_bGlossaryMode); } } else @@ -3995,6 +4069,40 @@ int Binary_SettingsTableReader::ReadSettings(BYTE type, long length, void* poRes pSettings->m_oConsecutiveHyphenLimit.Init(); pSettings->m_oConsecutiveHyphenLimit->m_oVal = m_oBufferedStream.GetLong(); } + else if (c_oSer_SettingsType::DrawingGridHorizontalOrigin == type) + { + pSettings->m_oDrawingGridHorizontalOrigin.Init(); + pSettings->m_oDrawingGridHorizontalOrigin->m_oVal.Init(); + pSettings->m_oDrawingGridHorizontalOrigin->m_oVal->FromTwips(m_oBufferedStream.GetLong()); + } + else if (c_oSer_SettingsType::DrawingGridHorizontalSpacing == type) + { + pSettings->m_oDrawingGridHorizontalSpacing.Init(); + pSettings->m_oDrawingGridHorizontalSpacing->m_oVal.Init(); + pSettings->m_oDrawingGridHorizontalSpacing->m_oVal->FromTwips(m_oBufferedStream.GetLong()); + } + else if (c_oSer_SettingsType::DrawingGridVerticalOrigin == type) + { + pSettings->m_oDrawingGridVerticalOrigin.Init(); + pSettings->m_oDrawingGridVerticalOrigin->m_oVal.Init(); + pSettings->m_oDrawingGridVerticalOrigin->m_oVal->FromTwips(m_oBufferedStream.GetLong()); + } + else if (c_oSer_SettingsType::DrawingGridVerticalSpacing == type) + { + pSettings->m_oDrawingGridVerticalSpacing.Init(); + pSettings->m_oDrawingGridVerticalSpacing->m_oVal.Init(); + pSettings->m_oDrawingGridVerticalSpacing->m_oVal->FromTwips(m_oBufferedStream.GetLong()); + } + else if (c_oSer_SettingsType::DisplayHorizontalDrawingGridEvery == type) + { + pSettings->m_oDisplayHorizontalDrawingGridEvery.Init(); + pSettings->m_oDisplayHorizontalDrawingGridEvery->m_oVal = m_oBufferedStream.GetLong(); + } + else if (c_oSer_SettingsType::DisplayVerticalDrawingGridEvery == type) + { + pSettings->m_oDisplayVerticalDrawingGridEvery.Init(); + pSettings->m_oDisplayVerticalDrawingGridEvery->m_oVal = m_oBufferedStream.GetLong(); + } else res = c_oSerConstants::ReadUnknown; return res; @@ -4871,6 +4979,18 @@ int Binary_DocumentTableReader::ReadDocumentContent(BYTE type, long length, void m_oFileWriter.m_pDrawingConverter->WriteRels(OOX::FileTypes::JsaProject.RelationType(), sJsaProject.GetPath(), L"", &lId); m_oFileWriter.m_pDrawingConverter->m_pImageManager->m_pContentTypes->AddDefault(sJsaProject.GetExtention(false)); } + else if (c_oSerParType::PermStart == type) + { + OOX::Logic::CPermStart oPerm; + READ1_DEF(length, res, this->ReadPermStart, &oPerm); + m_oDocumentWriter.m_oContent.WriteString(oPerm.toXML()); + } + else if (c_oSerParType::PermEnd == type) + { + OOX::Logic::CPermEnd oPerm; + READ1_DEF(length, res, this->ReadPermEnd, &oPerm); + m_oDocumentWriter.m_oContent.WriteString(oPerm.toXML()); + } else res = c_oSerConstants::ReadUnknown; return res; @@ -5647,8 +5767,8 @@ int Binary_DocumentTableReader::ReadPermStart(BYTE type, long length, void* poRe } else if (c_oSerPermission::Ed == type) { - pPerm->m_sId.Init(); - *pPerm->m_sId = m_oBufferedStream.GetString3(length); + pPerm->m_sEd.Init(); + *pPerm->m_sEd = m_oBufferedStream.GetString3(length); } else if (c_oSerPermission::EdGroup == type) { @@ -5925,11 +6045,24 @@ int Binary_DocumentTableReader::ReadMathArg(BYTE type, long length, void* poResu OOX::Logic::CMoveToRangeEnd oMoveToRangeEnd; READ1_DEF(length, res, this->ReadMoveToRangeEnd, &oMoveToRangeEnd); GetRunStringWriter().WriteString(oMoveToRangeEnd.toXML()); + } + else if (c_oSer_OMathContentType::PermStart == type) + { + OOX::Logic::CPermStart oPerm; + READ1_DEF(length, res, this->ReadPermStart, &oPerm); + GetRunStringWriter().WriteString(oPerm.toXML()); + } + else if (c_oSer_OMathContentType::PermEnd == type) + { + OOX::Logic::CPermEnd oPerm; + READ1_DEF(length, res, this->ReadPermEnd, &oPerm); + GetRunStringWriter().WriteString(oPerm.toXML()); } else res = c_oSerConstants::ReadUnknown; return res; } + int Binary_DocumentTableReader::ReadMathAcc(BYTE type, long length, void* poResult) { int res = c_oSerConstants::ReadOk; @@ -7409,6 +7542,75 @@ int Binary_DocumentTableReader::ReadMathMRun(BYTE type, long length, void* poRes READ1_DEF(length, res, this->ReadMathInsDel, &oTrackRevision); oTrackRevision.Write(&GetRunStringWriter(), _T("w:ins")); } + else if (c_oSer_OMathContentType::AnnotationRef == type) + { + OOX::Logic::CAnnotationRef oAnnotationRef; + GetRunStringWriter().WriteString(oAnnotationRef.toXML()); + } + else if (c_oSer_OMathContentType::CommentReference == type) + { + long nId = 0; + READ1_DEF(length, res, this->ReadComment, &nId); + if (NULL != m_oFileWriter.m_pComments) + { + CComment* pComment = m_oFileWriter.m_pComments->get(nId); + if (NULL != pComment) // могут быть и без start/end + { + GetRunStringWriter().WriteString(pComment->writeRef(std::wstring(_T("")), std::wstring(_T("w:commentReference")), std::wstring(_T("")))); + } + } + } + else if (c_oSer_OMathContentType::Cr == type) + { + OOX::Logic::CCr oCr; + GetRunStringWriter().WriteString(oCr.toXML()); + } + else if (c_oSer_OMathContentType::EndnoteRef == type) + { + OOX::Logic::CEndnoteRef oEndnoteRef; + GetRunStringWriter().WriteString(oEndnoteRef.toXML()); + } + else if (c_oSer_OMathContentType::FootnoteRef == type) + { + OOX::Logic::CFootnoteRef oFootnoteRef; + GetRunStringWriter().WriteString(oFootnoteRef.toXML()); + } + else if (c_oSer_OMathContentType::EndnoteReference == type) + { + OOX::Logic::CEndnoteReference oEndnoteReference; + READ1_DEF(length, res, this->ReadEndnoteRef, &oEndnoteReference); + GetRunStringWriter().WriteString(oEndnoteReference.toXML()); + } + else if (c_oSer_OMathContentType::FootnoteReference == type) + { + OOX::Logic::CFootnoteReference oFootnoteReference; + READ1_DEF(length, res, this->ReadFootnoteRef, &oFootnoteReference); + GetRunStringWriter().WriteString(oFootnoteReference.toXML()); + } + else if (c_oSer_OMathContentType::LastRenderedPageBreak == type) + { + OOX::Logic::CLastRenderedPageBreak oLastRenderedPageBreak; + GetRunStringWriter().WriteString(oLastRenderedPageBreak.toXML()); + } + else if (c_oSer_OMathContentType::NoBreakHyphen == type) + { + OOX::Logic::CNoBreakHyphen oNoBreakHyphen; + GetRunStringWriter().WriteString(oNoBreakHyphen.toXML()); + } + else if (c_oSer_OMathContentType::SoftHyphen == type) + { + OOX::Logic::CSoftHyphen oSoftHyphen; + GetRunStringWriter().WriteString(oSoftHyphen.toXML()); + } + else if (c_oSer_OMathContentType::Tab == type) + { + OOX::Logic::CTab oTab; + GetRunStringWriter().WriteString(oTab.toXML()); + } + else if (c_oSer_OMathContentType::Sym == type) + { + std::wstring sText = m_oBufferedStream.GetString3(length); + } else res = c_oSerConstants::ReadUnknown; return res; @@ -8475,6 +8677,18 @@ int Binary_DocumentTableReader::Read_TableContent(BYTE type, long length, void* READ1_DEF(length, res, this->ReadMoveToRangeEnd, &oMoveToRangeEnd); pCStringWriter->WriteString(oMoveToRangeEnd.toXML()); } + else if (c_oSerDocTableType::PermStart == type) + { + OOX::Logic::CPermStart oPerm; + READ1_DEF(length, res, this->ReadPermStart, &oPerm); + pCStringWriter->WriteString(oPerm.toXML()); + } + else if (c_oSerDocTableType::PermEnd == type) + { + OOX::Logic::CPermEnd oPerm; + READ1_DEF(length, res, this->ReadPermEnd, &oPerm); + pCStringWriter->WriteString(oPerm.toXML()); + } else res = c_oSerConstants::ReadUnknown; return res; @@ -8548,6 +8762,18 @@ int Binary_DocumentTableReader::ReadRowContent(BYTE type, long length, void* poR READ1_DEF(length, res, this->ReadMoveToRangeEnd, &oMoveToRangeEnd); pCStringWriter->WriteString(oMoveToRangeEnd.toXML()); } + else if (c_oSerDocTableType::PermStart == type) + { + OOX::Logic::CPermStart oPerm; + READ1_DEF(length, res, this->ReadPermStart, &oPerm); + pCStringWriter->WriteString(oPerm.toXML()); + } + else if (c_oSerDocTableType::PermEnd == type) + { + OOX::Logic::CPermEnd oPerm; + READ1_DEF(length, res, this->ReadPermEnd, &oPerm); + pCStringWriter->WriteString(oPerm.toXML()); + } else res = c_oSerConstants::ReadUnknown; return res; @@ -9590,18 +9816,19 @@ int Binary_DocumentTableReader::ReadSdtPrDataBinding(BYTE type, long length, voi ComplexTypes::Word::CDataBinding* pDataBinding = static_cast(poResult); if (c_oSerSdt::PrefixMappings == type) { - pDataBinding->m_sPrefixMappings.Init(); - pDataBinding->m_sPrefixMappings->append(m_oBufferedStream.GetString3(length)); + pDataBinding->m_sPrefixMappings = m_oBufferedStream.GetString3(length); } else if (c_oSerSdt::StoreItemID == type) { - pDataBinding->m_sStoreItemID.Init(); - pDataBinding->m_sStoreItemID->append(m_oBufferedStream.GetString3(length)); + pDataBinding->m_sStoreItemID = m_oBufferedStream.GetString3(length); } else if (c_oSerSdt::XPath == type) { - pDataBinding->m_sXPath.Init(); - pDataBinding->m_sXPath->append(m_oBufferedStream.GetString3(length)); + pDataBinding->m_sXPath = m_oBufferedStream.GetString3(length); + } + else if (c_oSerSdt::StoreItemChecksum == type) + { + pDataBinding->m_sStoreItemChecksum = m_oBufferedStream.GetString3(length); } else res = c_oSerConstants::ReadUnknown; @@ -9708,6 +9935,10 @@ int Binary_DocumentTableReader::ReadSdtPicture(BYTE type, long length, void* poR { pPicture->m_oShiftY = m_oBufferedStream.GetDoubleReal(); } + else if (c_oSerSdt::PictureFormPrSignature == type) + { + pPicture->m_oSignature = m_oBufferedStream.GetBool(); + } else res = c_oSerConstants::ReadUnknown; return res; @@ -10139,20 +10370,16 @@ int BinaryFileReader::ReadMainTable() // break; case c_oSerTableTypes::App: { - PPTX::App oApp(NULL); - oApp.fromPPTY(&m_oBufferedStream); OOX::CApp* pApp = new OOX::CApp(NULL); - pApp->FromPptxApp(&oApp); + pApp->fromPPTY(&m_oBufferedStream); pApp->SetRequiredDefaults(); m_oFileWriter.m_pApp = pApp; } break; case c_oSerTableTypes::Core: { - PPTX::Core oCore(NULL); - oCore.fromPPTY(&m_oBufferedStream); OOX::CCore* pCore = new OOX::CCore(NULL); - pCore->FromPptxCore(&oCore); + pCore->fromPPTY(&m_oBufferedStream); pCore->SetRequiredDefaults(); m_oFileWriter.m_pCore = pCore; } diff --git a/OOXML/Binary/Document/BinReader/Readers.h b/OOXML/Binary/Document/BinReader/Readers.h index d04c875f17e..a396a049311 100644 --- a/OOXML/Binary/Document/BinReader/Readers.h +++ b/OOXML/Binary/Document/BinReader/Readers.h @@ -141,6 +141,7 @@ class Binary_pPrReader : public Binary_CommonReader int ReadPageBorders(BYTE type, long length, void* poResult); int ReadPageBorder(BYTE type, long length, void* poResult); int ReadCnfStyle(BYTE type, long length, void* poResult); + int ReadDocGrid(BYTE type, long length, void* poResult); }; class Binary_tblPrReader : public Binary_CommonReader { @@ -509,9 +510,10 @@ class BinaryFileReader Writers::FileWriter& m_oFileWriter; std::wstring m_sFileInDir; bool m_bMacro = false; - bool m_bMacroRead = false; bool m_bOForm = false; public: + bool m_bMacroRead = false; + BinaryFileReader(std::wstring& sFileInDir, NSBinPptxRW::CBinaryFileReader& oBufferedStream, Writers::FileWriter& oFileWriter, bool bMacro = false, bool bOForm = false); int ReadFile(); int ReadMainTable(); diff --git a/OOXML/Binary/Document/BinWriter/BinReaderWriterDefines.h b/OOXML/Binary/Document/BinWriter/BinReaderWriterDefines.h index 465701e61c0..e3dd407c328 100644 --- a/OOXML/Binary/Document/BinWriter/BinReaderWriterDefines.h +++ b/OOXML/Binary/Document/BinWriter/BinReaderWriterDefines.h @@ -35,18 +35,6 @@ namespace BinDocxRW { const double eps = 0.001; -const int g_tabtype_left = 0; -const int g_tabtype_right = 1; -const int g_tabtype_center = 2; -const int g_tabtype_clear = 3; - -const int border_None = 0x0000; -const int border_Single = 0x0001; - -const int heightrule_AtLeast = 0x00; -const int heightrule_Auto = 0x01; -const int heightrule_Exact = 0x02; - const int align_Right = 0; const int align_Left = 1; const int align_Center = 2; @@ -66,38 +54,16 @@ const int linerule_Exact = 2; const int orientation_Portrait = 0x00; const int orientation_Landscape = 0x01; -const int numbering_numfmt_None = 0x0000; -const int numbering_numfmt_Bullet = 0x1001; -const int numbering_numfmt_Decimal = 0x2002; -const int numbering_numfmt_LowerRoman = 0x2003; -const int numbering_numfmt_UpperRoman = 0x2004; -const int numbering_numfmt_LowerLetter = 0x2005; -const int numbering_numfmt_UpperLetter = 0x2006; -const int numbering_numfmt_DecimalZero = 0x2007; - -const int numbering_suff_Tab = 1; -const int numbering_suff_Space = 2; -const int numbering_suff_Nothing = 3; - const int tblwidth_Auto = 0x00; const int tblwidth_Mm = 0x01; const int tblwidth_Nil = 0x02; const int tblwidth_Pct = 0x03; -const int fontstyle_mask_regular = 1; -const int fontstyle_mask_italic = 2; -const int fontstyle_mask_bold = 4; -const int fontstyle_mask_bolditalic = 8; - const int styletype_Character = 0x01; const int styletype_Numbering = 0x02; const int styletype_Paragraph = 0x03; const int styletype_Table = 0x04; -const int fieldstruct_none = 0; -const int fieldstruct_toc = 1; -const int fieldstruct_hyperlink = 2; - const double g_dKoef_mm_to_pt = 72 / (2.54 * 10); const double g_dKoef_mm_to_twips = 20 * g_dKoef_mm_to_pt; const double g_dKoef_mm_to_emu = 36000; @@ -105,9 +71,12 @@ const double g_dKoef_mm_to_eightpoint = 8 * g_dKoef_mm_to_pt; const double g_dKoef_mm_to_hps = 2 * g_dKoef_mm_to_pt; const static wchar_t* g_sFormatSignature = L"DOCY"; + const int g_nFormatVersion = 5; const int g_nFormatVersionNoBase64 = 10; + extern int g_nCurFormatVersion; + namespace c_oAscWrapStyle{enum c_oSerFormat { Inline = 0, @@ -384,7 +353,11 @@ extern int g_nCurFormatVersion; Tab_Item_PosTwips = 42, Tab_Item_Val = 43, SuppressLineNumbers = 44, - CnfStyle = 45 + CnfStyle = 45, + SnapToGrid = 46, + Bidi = 47, + Spacing_AfterLines = 48, + Spacing_BeforeLines = 49 };} namespace c_oSerProp_rPrType{enum c_oSerProp_rPrType { @@ -443,7 +416,8 @@ extern int g_nCurFormatVersion; Reflection = 52, Glow = 53, Props3d = 54, - Scene3d = 55 + Scene3d = 55, + Kern = 56 };} namespace c_oSerProp_rowPrType{enum c_oSerProp_rowPrType { @@ -504,7 +478,8 @@ extern int g_nCurFormatVersion; footnotePr = 10, endnotePr = 11, rtlGutter = 12, - lnNumType = 13 + lnNumType = 13, + docGrid = 14 };} namespace c_oSerProp_secPrSettingsType{enum c_oSerProp_secPrSettingsType { @@ -514,7 +489,10 @@ extern int g_nCurFormatVersion; };} namespace c_oSerProp_secPrPageNumType{enum c_oSerProp_secPrPageNumType { - start = 0 + start = 0, + fmt = 1, + chapStyle = 2, + chapSep = 3 };} namespace c_oSerProp_secPrLineNumType{enum c_oSerProp_secPrLineNumType { @@ -594,7 +572,9 @@ extern int g_nCurFormatVersion; MoveFromRangeStart = 14, MoveFromRangeEnd = 15, MoveToRangeStart = 16, - MoveToRangeEnd = 17 + MoveToRangeEnd = 17, + PermStart = 18, + PermEnd = 19 };} namespace c_oSerRunType{enum c_oSerRunType { @@ -631,7 +611,8 @@ extern int g_nCurFormatVersion; delInstrText = 31, linebreakClearAll = 32, linebreakClearLeft = 33, - linebreakClearRight = 34 + linebreakClearRight = 34, + pptxDrawingAlternative = 0x99 };} namespace c_oSerVbaProjectTypes{enum c_oSerVbaProjectType { @@ -782,7 +763,8 @@ extern int g_nCurFormatVersion; Value = 3, ColorTheme = 4, SpacePoint = 5, - Size8Point = 6 + Size8Point = 6, + ValueType = 7 };} namespace c_oSerShdType{enum c_oSerShdType { @@ -905,7 +887,13 @@ extern int g_nCurFormatVersion; AutoHyphenation = 21, HyphenationZone = 22, DoNotHyphenateCaps = 23, - ConsecutiveHyphenLimit = 24 + ConsecutiveHyphenLimit = 24, + DrawingGridHorizontalOrigin = 25, + DrawingGridHorizontalSpacing = 26, + DrawingGridVerticalOrigin = 27, + DrawingGridVerticalSpacing = 28, + DisplayHorizontalDrawingGridEvery = 29, + DisplayVerticalDrawingGridEvery = 30 };} namespace c_oSer_MathPrType{enum c_oSer_SettingsType { @@ -1076,7 +1064,22 @@ extern int g_nCurFormatVersion; MoveFromRangeStart = 68, MoveFromRangeEnd = 69, MoveToRangeStart = 70, - MoveToRangeEnd = 71 + MoveToRangeEnd = 71, + AnnotationRef = 72, + CommentReference = 73, + ContentPart = 74, + Cr = 75, + EndnoteRef = 76, + EndnoteReference = 77, + FootnoteRef = 78, + FootnoteReference = 79, + LastRenderedPageBreak = 80, + NoBreakHyphen = 81, + SoftHyphen = 82, + Sym = 83, + Tab = 84, + PermStart =85, + PermEnd = 86 };} namespace c_oSer_FramePrType{ enum c_oSer_FramePrType { @@ -1148,6 +1151,12 @@ extern int g_nCurFormatVersion; ColumnSpace = 5, ColumnW = 6 };} + namespace c_oSerProp_DocGrid {enum c_oSerProp_DocGrid + { + Type = 0, + CharSpace = 1, + LinePitch = 2 + };} namespace c_oSerPageBorders{enum c_oSerPageBorders { Display = 0, @@ -1269,7 +1278,7 @@ extern int g_nCurFormatVersion; FormPrLabel = 46, FormPrHelpText = 47, FormPrRequired = 48, - CheckboxGroupKey = 59, + CheckboxGroupKey = 49, TextFormPr = 50, TextFormPrComb = 51, TextFormPrCombWidth = 52, @@ -1286,12 +1295,14 @@ extern int g_nCurFormatVersion; PictureFormPrRespectBorders = 63, PictureFormPrShiftX = 64, PictureFormPrShiftY = 65, + PictureFormPrSignature = 66, FormPrBorder = 70, FormPrShd = 71, TextFormPrCombWRule = 72, TextFormPrFormatType = 80, TextFormPrFormatVal = 81, TextFormPrFormatSymbols = 82, + StoreItemChecksum = 85, ComplexFormPr = 90, ComplexFormPrType = 91, OformMaster = 92 diff --git a/OOXML/Binary/Document/BinWriter/BinWriters.cpp b/OOXML/Binary/Document/BinWriter/BinWriters.cpp index 695e1185800..a6767d5f4ca 100644 --- a/OOXML/Binary/Document/BinWriter/BinWriters.cpp +++ b/OOXML/Binary/Document/BinWriter/BinWriters.cpp @@ -36,8 +36,6 @@ #include "../../../../Common/OfficeFileFormatChecker.h" #include "../../Presentation/FontCutter.h" -#include "../../../PPTXFormat/App.h" -#include "../../../PPTXFormat/Core.h" #include "../../../PPTXFormat/Logic/HeadingVariant.h" #include "../../Sheets/Reader/BinaryWriter.h" #include "BinEquationWriter.h" @@ -159,7 +157,9 @@ void BinaryCommonWriter::WriteBorder(const ComplexTypes::Word::CBorder& border) { if (border.m_oColor.IsInit()) WriteColor(c_oSerBorderType::Color, border.m_oColor.get()); + WriteThemeColor(c_oSerBorderType::ColorTheme, border.m_oColor, border.m_oThemeColor, border.m_oThemeTint, border.m_oThemeShade); + if (border.m_oSpace.IsInit()) { m_oStream.WriteBYTE(c_oSerBorderType::SpacePoint); @@ -175,12 +175,17 @@ void BinaryCommonWriter::WriteBorder(const ComplexTypes::Word::CBorder& border) //Val m_oStream.WriteBYTE(c_oSerBorderType::Value); m_oStream.WriteBYTE(c_oSerPropLenType::Byte); - switch(border.m_oVal.get().GetValue()) + + switch (border.m_oVal.get().GetValue()) { - case SimpleTypes::bordervalueNone: - case SimpleTypes::bordervalueNil: m_oStream.WriteBYTE(border_None); break; - default: m_oStream.WriteBYTE(border_Single); break; + case SimpleTypes::bordervalueNone: + case SimpleTypes::bordervalueNil: m_oStream.WriteBYTE(0); break; + default: m_oStream.WriteBYTE(1); break; } + + m_oStream.WriteBYTE(c_oSerBorderType::ValueType); + m_oStream.WriteBYTE(c_oSerPropLenType::Long); + m_oStream.WriteLONG(border.m_oVal.get().GetValue()); } } void BinaryCommonWriter::WriteTblBorders(const OOX::Logic::CTblBorders& Borders) @@ -832,7 +837,7 @@ void Binary_rPrWriter::Write_rPr(OOX::Logic::CRunProperty* rPr) m_oBcw.WriteTrackRevision(rPr->m_oMoveTo.get()); m_oBcw.WriteItemWithLengthEnd(nCurPos); } - if (rPr->m_oW.IsInit()) + if (rPr->m_oW.IsInit() && rPr->m_oW->m_oVal.IsInit()) { m_oBcw.m_oStream.WriteBYTE(c_oSerProp_rPrType::CompressText); m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Long); @@ -913,6 +918,12 @@ void Binary_rPrWriter::Write_rPr(OOX::Logic::CRunProperty* rPr) m_oBcw.m_oStream.WriteRecord1(0, *rPr->m_oScene3d); m_oBcw.WriteItemWithLengthEnd(nCurPos); } + if (rPr->m_oKern.IsInit() && rPr->m_oKern->m_oVal.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerProp_rPrType::Kern); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Long); + m_oBcw.m_oStream.WriteLONG(rPr->m_oKern.get().m_oVal.get().ToHps()); + } } void Binary_rPrWriter::Write_rPrChange(const OOX::Logic::CRPrChange& rPrChange) { @@ -1132,7 +1143,18 @@ void Binary_pPrWriter::Write_pPr(const OOX::Logic::CParagraphProperty& pPr) WriteCnfStyle(pPr.m_oCnfStyle.GetPointer()); m_oBcw.WriteItemWithLengthEnd(nCurPos2); } -} + if (pPr.m_oSnapToGrid.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerProp_pPrType::SnapToGrid); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(pPr.m_oSnapToGrid->m_oVal.ToBool()); + } + if (pPr.m_oBidi.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerProp_pPrType::Bidi); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(pPr.m_oBidi->m_oVal.ToBool()); + }} void Binary_pPrWriter::WritePPrChange(const OOX::Logic::CPPrChange& pPrChange) { int nCurPos = 0; @@ -1223,6 +1245,18 @@ void Binary_pPrWriter::WriteSpacing(const ComplexTypes::Word::CSpacing& Spacing) m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Long); m_oBcw.m_oStream.WriteLONG(Spacing.m_oAfter->ToTwips()); } + if (false != Spacing.m_oAfterLines.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerProp_pPrType::Spacing_AfterLines); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Long); + m_oBcw.m_oStream.WriteLONG(Spacing.m_oAfterLines->GetValue()); + } + if (false != Spacing.m_oBeforeLines.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerProp_pPrType::Spacing_BeforeLines); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Long); + m_oBcw.m_oStream.WriteLONG(Spacing.m_oBeforeLines->GetValue()); + } } void Binary_pPrWriter::WriteTabs(const OOX::Logic::CTabs& Tab, const nullable& oInd) { @@ -1509,6 +1543,12 @@ void Binary_pPrWriter::WriteSectPr (OOX::Logic::CSectionProperty* pSectPr) m_oBcw.m_oStream.WriteBOOL(pSectPr->m_oRtlGutter->m_oVal.ToBool()); m_oBcw.WriteItemEnd(nCurPos); } + if (pSectPr->m_oDocGrid.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerProp_secPrType::docGrid); + WriteDocGrid(pSectPr->m_oDocGrid.get()); + m_oBcw.WriteItemEnd(nCurPos); + } } void Binary_pPrWriter::WritePageSettings(OOX::Logic::CSectionProperty* pSectPr) { @@ -1665,6 +1705,24 @@ void Binary_pPrWriter::WritePageNumType(const ComplexTypes::Word::CPageNumber& p m_oBcw.m_oStream.WriteLONG(pPageNumber.m_oStart->GetValue()); m_oBcw.WriteItemEnd(nCurPos); } + if (pPageNumber.m_oFmt.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerProp_secPrPageNumType::fmt); + m_oBcw.m_oStream.WriteBYTE(pPageNumber.m_oFmt->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (pPageNumber.m_oChapStyle.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerProp_secPrPageNumType::chapStyle); + m_oBcw.m_oStream.WriteLONG(pPageNumber.m_oChapStyle->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (pPageNumber.m_oChapSep.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerProp_secPrPageNumType::chapSep); + m_oBcw.m_oStream.WriteBYTE(pPageNumber.m_oChapSep->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } } void Binary_pPrWriter::WriteLineNumType(const ComplexTypes::Word::CLineNumber& pLineNumber) { @@ -1740,6 +1798,29 @@ void Binary_pPrWriter::WriteColumns(const OOX::Logic::CColumns& columns) m_oBcw.WriteItemWithLengthEnd(nCurPos); } } +void Binary_pPrWriter::WriteDocGrid(const ComplexTypes::Word::CDocGrid& docGrid) +{ + int nCurPos = 0; + + if (docGrid.m_oType.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerProp_DocGrid::Type); + m_oBcw.m_oStream.WriteBYTE(docGrid.m_oType->GetValue()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (docGrid.m_oCharSpace.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerProp_DocGrid::CharSpace); + m_oBcw.m_oStream.WriteLONG(docGrid.m_oCharSpace->GetValue()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (docGrid.m_oLinePitch.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerProp_DocGrid::LinePitch); + m_oBcw.m_oStream.WriteLONG(docGrid.m_oLinePitch->GetValue()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +} void Binary_pPrWriter::WriteColumn(const ComplexTypes::Word::CColumn& column) { int nCurPos = 0; @@ -2231,7 +2312,7 @@ void Binary_tblPrWriter::WriteRowPr(const OOX::Logic::CTableRowProperties& rowPr m_oBcw.WriteItemWithLengthEnd(nCurPos); } //Jc - if (rowPr.m_oJc.IsInit()) + if (rowPr.m_oJc.IsInit() && rowPr.m_oJc->m_oVal.IsInit()) { m_oBcw.m_oStream.WriteBYTE(c_oSerProp_rowPrType::Jc); m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); @@ -3122,13 +3203,7 @@ void BinaryNumberingTableWriter::WriteLevel(const OOX::Numbering::CLvl& lvl) { m_oBcw.m_oStream.WriteBYTE(c_oSerNumTypes::lvl_Suff); m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); - switch(oSuff.m_oVal.get().GetValue()) - { - case SimpleTypes::levelsuffixNothing: m_oBcw.m_oStream.WriteBYTE(numbering_suff_Nothing);break; - case SimpleTypes::levelsuffixSpace: m_oBcw.m_oStream.WriteBYTE(numbering_suff_Space);break; - case SimpleTypes::levelsuffixTab: m_oBcw.m_oStream.WriteBYTE(numbering_suff_Tab);break; - default: m_oBcw.m_oStream.WriteBYTE(numbering_suff_Tab);break; - } + m_oBcw.m_oStream.WriteBYTE((BYTE)oSuff.m_oVal->GetValue()); } } //PStyle @@ -3531,7 +3606,17 @@ void BinaryDocumentTableWriter::WriteDocumentContent(const std::vector(item)); m_oBcw.WriteItemWithLengthEnd(nCurPos); }break; - default: + case OOX::et_w_permStart: + { + OOX::Logic::CPermStart* pPermStart = static_cast(item); + WritePermission(c_oSerParType::PermStart, pPermStart); + }break; + case OOX::et_w_permEnd: + { + OOX::Logic::CPermEnd* pPermEnd = static_cast(item); + WritePermission(c_oSerParType::PermEnd, pPermEnd); + }break; + default: break; } } @@ -3821,12 +3906,12 @@ void BinaryDocumentTableWriter::WriteParagraphContent(const std::vector(item); - WritePermission(pPermStart); + WritePermission(c_oSerParType::PermStart, pPermStart); }break; case OOX::et_w_permEnd: { OOX::Logic::CPermEnd* pPermEnd = static_cast(item); - WritePermission(pPermEnd); + WritePermission(c_oSerParType::PermEnd, pPermEnd); }break; case OOX::et_w_fldSimple: { @@ -4122,11 +4207,11 @@ void BinaryDocumentTableWriter::WriteComment(OOX::EElementType eType, nullablem_sId.IsInit()) { @@ -4166,11 +4251,11 @@ void BinaryDocumentTableWriter::WritePermission(OOX::Logic::CPermStart* pPerm) } m_oBcw.WriteItemWithLengthEnd(nCurPos2); } -void BinaryDocumentTableWriter::WritePermission(OOX::Logic::CPermEnd* pPerm) +void BinaryDocumentTableWriter::WritePermission(unsigned char type, OOX::Logic::CPermEnd* pPerm) { if (!pPerm) return; - int nCurPos2 = m_oBcw.WriteItemStart(c_oSerParType::PermEnd); + int nCurPos2 = m_oBcw.WriteItemStart(type); if (pPerm->m_sId.IsInit()) { int nCurPos = m_oBcw.WriteItemStart(c_oSerPermission::Id); @@ -4613,184 +4698,170 @@ void BinaryDocumentTableWriter::WriteMathArgNodes(const std::vector(item); nCurPos = m_oBcw.WriteItemStart(c_oSer_OMathContentType::Acc); - if ( pAcc->m_oAccPr.IsInit() ) + if (pAcc->m_oAccPr.IsInit()) WriteMathAccPr(pAcc->m_oAccPr.get()); - if ( pAcc->m_oElement.IsInit() ) + if (pAcc->m_oElement.IsInit()) WriteMathElement(pAcc->m_oElement.get()); m_oBcw.WriteItemEnd(nCurPos); - break; - } - case OOX::et_m_argPr: + }break; + case OOX::et_m_argPr: { OOX::Logic::CArgPr* pArgPr = static_cast(item); nCurPos = m_oBcw.WriteItemStart(c_oSer_OMathContentType::ArgPr); - if ( pArgPr->m_oArgSz.IsInit() ) + if (pArgPr->m_oArgSz.IsInit()) WriteMathArgSz(pArgPr->m_oArgSz.get()); m_oBcw.WriteItemEnd(nCurPos); - break; - } - case OOX::et_m_bar: + }break; + case OOX::et_m_bar: { OOX::Logic::CBar* pBar = static_cast(item); nCurPos = m_oBcw.WriteItemStart(c_oSer_OMathContentType::Bar); - if ( pBar->m_oBarPr.IsInit() ) + if (pBar->m_oBarPr.IsInit()) WriteMathBarPr(pBar->m_oBarPr.get()); - if ( pBar->m_oElement.IsInit() ) + if (pBar->m_oElement.IsInit()) WriteMathElement(pBar->m_oElement.get()); m_oBcw.WriteItemEnd(nCurPos); - break; - } - case OOX::et_m_borderBox: + }break; + case OOX::et_m_borderBox: { OOX::Logic::CBorderBox* pBorderBox = static_cast(item); nCurPos = m_oBcw.WriteItemStart(c_oSer_OMathContentType::BorderBox); - if ( pBorderBox->m_oBorderBoxPr.IsInit() ) + if (pBorderBox->m_oBorderBoxPr.IsInit()) WriteMathBorderBoxPr(pBorderBox->m_oBorderBoxPr.get()); - if ( pBorderBox->m_oElement.IsInit() ) + if (pBorderBox->m_oElement.IsInit()) WriteMathElement(pBorderBox->m_oElement.get()); m_oBcw.WriteItemEnd(nCurPos); - break; - } - case OOX::et_m_box: + }break; + case OOX::et_m_box: { OOX::Logic::CBox* pBox = static_cast(item); nCurPos = m_oBcw.WriteItemStart(c_oSer_OMathContentType::Box); - if ( pBox->m_oBoxPr.IsInit() ) + if (pBox->m_oBoxPr.IsInit()) WriteMathBoxPr(pBox->m_oBoxPr.get()); - if ( pBox->m_oElement.IsInit() ) + if (pBox->m_oElement.IsInit()) WriteMathElement(pBox->m_oElement.get()); m_oBcw.WriteItemEnd(nCurPos); - break; - } - case OOX::et_m_ctrlPr: + }break; + case OOX::et_m_ctrlPr: { OOX::Logic::CCtrlPr* pCtrlPr = static_cast(item); WriteMathCtrlPr(*pCtrlPr, c_oSer_OMathContentType::CtrlPr); break; } - case OOX::et_m_d: + case OOX::et_m_d: { OOX::Logic::CDelimiter* pDelimiter = static_cast(item); nCurPos = m_oBcw.WriteItemStart(c_oSer_OMathContentType::Delimiter); WriteMathDelimiter(pDelimiter->m_arrItems, pDelimiter->m_lColumn); m_oBcw.WriteItemEnd(nCurPos); - break; - } - case OOX::et_w_del: + }break; + case OOX::et_w_del: { OOX::Logic::CDel* pDel = static_cast(item); nCurPos = m_oBcw.WriteItemStart(c_oSer_OMathContentType::Del); WriteDel(*pDel); m_oBcw.WriteItemEnd(nCurPos); - break; - } - case OOX::et_m_eqArr: + }break; + case OOX::et_m_eqArr: { OOX::Logic::CEqArr* pEqArr = static_cast(item); nCurPos = m_oBcw.WriteItemStart(c_oSer_OMathContentType::EqArr); WriteMathEqArr(pEqArr->m_arrItems, pEqArr->m_lRow); m_oBcw.WriteItemEnd(nCurPos); - break; - } - case OOX::et_m_f: + }break; + case OOX::et_m_f: { OOX::Logic::CFraction* pFraction = static_cast(item); nCurPos = m_oBcw.WriteItemStart(c_oSer_OMathContentType::Fraction); - if ( pFraction->m_oFPr.IsInit() ) + if (pFraction->m_oFPr.IsInit()) WriteMathFPr(pFraction->m_oFPr.get()); - if ( pFraction->m_oDen.IsInit() ) + if (pFraction->m_oDen.IsInit()) WriteMathDen(pFraction->m_oDen.get()); - if ( pFraction->m_oNum.IsInit() ) + if (pFraction->m_oNum.IsInit()) WriteMathNum(pFraction->m_oNum.get()); m_oBcw.WriteItemEnd(nCurPos); - break; - } - case OOX::et_m_func: + }break; + case OOX::et_m_func: { OOX::Logic::CFunc* pFunc = static_cast(item); nCurPos = m_oBcw.WriteItemStart(c_oSer_OMathContentType::Func); - if ( pFunc->m_oFuncPr.IsInit() ) + if (pFunc->m_oFuncPr.IsInit()) WriteMathFuncPr(pFunc->m_oFuncPr.get()); - if ( pFunc->m_oElement.IsInit() ) + if (pFunc->m_oElement.IsInit()) WriteMathElement(pFunc->m_oElement.get()); - if ( pFunc->m_oFName.IsInit() ) + if (pFunc->m_oFName.IsInit()) WriteMathFName(pFunc->m_oFName.get()); m_oBcw.WriteItemEnd(nCurPos); - break; - } - case OOX::et_m_groupChr: + }break; + case OOX::et_m_groupChr: { OOX::Logic::CGroupChr* pGroupChr = static_cast(item); nCurPos = m_oBcw.WriteItemStart(c_oSer_OMathContentType::GroupChr); - if ( pGroupChr->m_oGroupChrPr.IsInit() ) + if (pGroupChr->m_oGroupChrPr.IsInit()) WriteMathGroupChrPr(pGroupChr->m_oGroupChrPr.get()); - if ( pGroupChr->m_oElement.IsInit() ) + if (pGroupChr->m_oElement.IsInit()) WriteMathElement(pGroupChr->m_oElement.get()); m_oBcw.WriteItemEnd(nCurPos); - break; - } - case OOX::et_w_ins: + }break; + case OOX::et_w_ins: { OOX::Logic::CIns* pIns = static_cast(item); nCurPos = m_oBcw.WriteItemStart(c_oSer_OMathContentType::Ins); WriteIns(*pIns); m_oBcw.WriteItemEnd(nCurPos); - break; - } - case OOX::et_m_limLow: + }break; + case OOX::et_m_limLow: { OOX::Logic::CLimLow* pLimLow = static_cast(item); nCurPos = m_oBcw.WriteItemStart(c_oSer_OMathContentType::LimLow); - if ( pLimLow->m_oLimLowPr.IsInit() ) + if (pLimLow->m_oLimLowPr.IsInit()) WriteMathLimLowPr(pLimLow->m_oLimLowPr.get()); - if ( pLimLow->m_oElement.IsInit() ) + if (pLimLow->m_oElement.IsInit()) WriteMathElement(pLimLow->m_oElement.get()); - if ( pLimLow->m_oLim.IsInit() ) + if (pLimLow->m_oLim.IsInit()) WriteMathLim(pLimLow->m_oLim.get()); m_oBcw.WriteItemEnd(nCurPos); - break; - } - case OOX::et_m_limUpp: + }break; + case OOX::et_m_limUpp: { OOX::Logic::CLimUpp* pLimUpp = static_cast(item); nCurPos = m_oBcw.WriteItemStart(c_oSer_OMathContentType::LimUpp); - if ( pLimUpp->m_oLimUppPr.IsInit() ) + if (pLimUpp->m_oLimUppPr.IsInit()) WriteMathLimUppPr(pLimUpp->m_oLimUppPr.get()); - if ( pLimUpp->m_oElement.IsInit() ) + if (pLimUpp->m_oElement.IsInit()) WriteMathElement(pLimUpp->m_oElement.get()); - if ( pLimUpp->m_oLim.IsInit() ) + if (pLimUpp->m_oLim.IsInit()) WriteMathLim(pLimUpp->m_oLim.get()); m_oBcw.WriteItemEnd(nCurPos); - break; - } - case OOX::et_m_m: + }break; + case OOX::et_m_m: { OOX::Logic::CMatrix* pMatrix = static_cast(item); nCurPos = m_oBcw.WriteItemStart(c_oSer_OMathContentType::Matrix); LONG lCol = 0; -//TODO убрать, тк при отсутствии m:mcs, к-во столбцов должно разруливаться динамически в скрипте + //TODO убрать, тк при отсутствии m:mcs, к-во столбцов должно разруливаться динамически в скрипте for (std::vector::iterator jt = pMatrix->m_arrItems.begin(); jt != pMatrix->m_arrItems.end(); jt++) { OOX::WritingElement* item = *jt; @@ -4803,35 +4874,32 @@ void BinaryDocumentTableWriter::WriteMathArgNodes(const std::vectorm_arrItems, pMatrix->m_lRow, lCol); m_oBcw.WriteItemEnd(nCurPos); - break; - } - case OOX::et_m_nary: + }break; + case OOX::et_m_nary: { OOX::Logic::CNary* pNary = static_cast(item); nCurPos = m_oBcw.WriteItemStart(c_oSer_OMathContentType::Nary); - if ( pNary->m_oNaryPr.IsInit() ) + if (pNary->m_oNaryPr.IsInit()) WriteMathNaryPr(pNary->m_oNaryPr.get()); - if ( pNary->m_oSub.IsInit() ) + if (pNary->m_oSub.IsInit()) WriteMathSub(pNary->m_oSub.get()); - if ( pNary->m_oSup.IsInit() ) + if (pNary->m_oSup.IsInit()) WriteMathSup(pNary->m_oSup.get()); - if ( pNary->m_oElement.IsInit() ) + if (pNary->m_oElement.IsInit()) WriteMathElement(pNary->m_oElement.get()); m_oBcw.WriteItemEnd(nCurPos); - break; - } - case OOX::et_m_oMath: + }break; + case OOX::et_m_oMath: { OOX::Logic::COMath* pOMath = static_cast(item); nCurPos = m_oBcw.WriteItemStart(c_oSer_OMathContentType::OMath); - WriteMathArgNodes(pOMath->m_arrItems); + WriteMathArgNodes(pOMath->m_arrItems); m_oBcw.WriteItemEnd(nCurPos); - break; - } - case OOX::et_m_oMathPara: + }break; + case OOX::et_m_oMathPara: { OOX::Logic::COMathPara* pOMathPara = static_cast(item); nCurPos = m_oBcw.WriteItemStart(c_oSer_OMathContentType::OMathPara); @@ -4839,158 +4907,154 @@ void BinaryDocumentTableWriter::WriteMathArgNodes(const std::vectorm_arrItems); m_oBcw.WriteItemEnd(nCurPos); - break; - } - case OOX::et_m_phant: + }break; + case OOX::et_m_phant: { OOX::Logic::CPhant* pPhant = static_cast(item); nCurPos = m_oBcw.WriteItemStart(c_oSer_OMathContentType::Phant); - if ( pPhant->m_oPhantPr.IsInit() ) + if (pPhant->m_oPhantPr.IsInit()) WriteMathPhantPr(pPhant->m_oPhantPr.get()); - if ( pPhant->m_oElement.IsInit() ) + if (pPhant->m_oElement.IsInit()) WriteMathElement(pPhant->m_oElement.get()); - m_oBcw.WriteItemEnd(nCurPos); - break; - } - case OOX::et_m_r: + m_oBcw.WriteItemEnd(nCurPos); + }break; + case OOX::et_m_r: { OOX::Logic::CMRun* pMRun = static_cast(item); nCurPos = m_oBcw.WriteItemStart(c_oSer_OMathContentType::MRun); WriteMathRunContent(pMRun); - m_oBcw.WriteItemEnd(nCurPos); - break; - } - case OOX::et_m_rad: + m_oBcw.WriteItemEnd(nCurPos); + }break; + case OOX::et_m_rad: { OOX::Logic::CRad* pRad = static_cast(item); nCurPos = m_oBcw.WriteItemStart(c_oSer_OMathContentType::Rad); - if ( pRad->m_oRadPr.IsInit() ) + if (pRad->m_oRadPr.IsInit()) WriteMathRadPr(pRad->m_oRadPr.get()); - if ( pRad->m_oDeg.IsInit() ) + if (pRad->m_oDeg.IsInit()) WriteMathDeg(pRad->m_oDeg.get()); - if ( pRad->m_oElement.IsInit() ) + if (pRad->m_oElement.IsInit()) WriteMathElement(pRad->m_oElement.get()); - m_oBcw.WriteItemEnd(nCurPos); - break; - } - case OOX::et_m_sPre: + m_oBcw.WriteItemEnd(nCurPos); + }break; + case OOX::et_m_sPre: { OOX::Logic::CSPre* pSPre = static_cast(item); nCurPos = m_oBcw.WriteItemStart(c_oSer_OMathContentType::SPre); - if ( pSPre->m_oSPrePr.IsInit() ) + if (pSPre->m_oSPrePr.IsInit()) WriteMathSPrePr(pSPre->m_oSPrePr.get()); - if ( pSPre->m_oSub.IsInit() ) + if (pSPre->m_oSub.IsInit()) WriteMathSub(pSPre->m_oSub.get()); - if ( pSPre->m_oSup.IsInit() ) + if (pSPre->m_oSup.IsInit()) WriteMathSup(pSPre->m_oSup.get()); - if ( pSPre->m_oElement.IsInit() ) + if (pSPre->m_oElement.IsInit()) WriteMathElement(pSPre->m_oElement.get()); - m_oBcw.WriteItemEnd(nCurPos); - break; - } - case OOX::et_m_sSub: + m_oBcw.WriteItemEnd(nCurPos); + }break; + case OOX::et_m_sSub: { OOX::Logic::CSSub* pSSub = static_cast(item); int nCurPos = m_oBcw.WriteItemStart(c_oSer_OMathContentType::SSub); - if ( pSSub->m_oSSubPr.IsInit() ) + if (pSSub->m_oSSubPr.IsInit()) WriteMathSSubPr(pSSub->m_oSSubPr.get()); - if ( pSSub->m_oElement.IsInit() ) + if (pSSub->m_oElement.IsInit()) WriteMathElement(pSSub->m_oElement.get()); - if ( pSSub->m_oSub.IsInit() ) + if (pSSub->m_oSub.IsInit()) WriteMathSub(pSSub->m_oSub.get()); m_oBcw.WriteItemEnd(nCurPos); - break; - } - case OOX::et_m_sSubSup: + }break; + case OOX::et_m_sSubSup: { OOX::Logic::CSSubSup* pSSubSup = static_cast(item); nCurPos = m_oBcw.WriteItemStart(c_oSer_OMathContentType::SSubSup); - if ( pSSubSup->m_oSSubSupPr.IsInit() ) + if (pSSubSup->m_oSSubSupPr.IsInit()) WriteMathSSubSupPr(pSSubSup->m_oSSubSupPr.get()); - if ( pSSubSup->m_oElement.IsInit() ) + if (pSSubSup->m_oElement.IsInit()) WriteMathElement(pSSubSup->m_oElement.get()); - if ( pSSubSup->m_oSub.IsInit() ) + if (pSSubSup->m_oSub.IsInit()) WriteMathSub(pSSubSup->m_oSub.get()); - if ( pSSubSup->m_oSup.IsInit() ) + if (pSSubSup->m_oSup.IsInit()) WriteMathSup(pSSubSup->m_oSup.get()); m_oBcw.WriteItemEnd(nCurPos); - break; - } - case OOX::et_m_sSup: + }break; + case OOX::et_m_sSup: { OOX::Logic::CSSup* pSSup = static_cast(item); nCurPos = m_oBcw.WriteItemStart(c_oSer_OMathContentType::SSup); - if ( pSSup->m_oSSupPr.IsInit() ) + if (pSSup->m_oSSupPr.IsInit()) WriteMathSSupPr(pSSup->m_oSSupPr.get()); - if ( pSSup->m_oElement.IsInit() ) + if (pSSup->m_oElement.IsInit()) WriteMathElement(pSSup->m_oElement.get()); - if ( pSSup->m_oSup.IsInit() ) + if (pSSup->m_oSup.IsInit()) WriteMathSup(pSSup->m_oSup.get()); m_oBcw.WriteItemEnd(nCurPos); - break; - } - case OOX::et_w_bookmarkStart: + }break; + case OOX::et_w_bookmarkStart: { OOX::Logic::CBookmarkStart* pBookmarkStart = static_cast(item); nCurPos = m_oBcw.WriteItemStart(c_oSer_OMathContentType::BookmarkStart); WriteBookmarkStart(*pBookmarkStart); m_oBcw.WriteItemEnd(nCurPos); - break; - } - case OOX::et_w_bookmarkEnd: + }break; + case OOX::et_w_bookmarkEnd: { OOX::Logic::CBookmarkEnd* pBookmarkEnd = static_cast(item); nCurPos = m_oBcw.WriteItemStart(c_oSer_OMathContentType::BookmarkEnd); WriteBookmarkEnd(*pBookmarkEnd); m_oBcw.WriteItemEnd(nCurPos); - break; - } - case OOX::et_w_moveFromRangeStart: + }break; + case OOX::et_w_moveFromRangeStart: { OOX::Logic::CMoveFromRangeStart* pMoveFromRangeStart = static_cast(item); nCurPos = m_oBcw.WriteItemStart(c_oSer_OMathContentType::MoveFromRangeStart); WriteMoveRangeStart(*pMoveFromRangeStart); m_oBcw.WriteItemEnd(nCurPos); - break; - } - case OOX::et_w_moveFromRangeEnd: + }break; + case OOX::et_w_moveFromRangeEnd: { OOX::Logic::CMoveFromRangeEnd* pMoveFromRangeEnd = static_cast(item); nCurPos = m_oBcw.WriteItemStart(c_oSer_OMathContentType::MoveFromRangeEnd); WriteMoveRangeEnd(*pMoveFromRangeEnd); m_oBcw.WriteItemEnd(nCurPos); - break; - } - case OOX::et_w_moveToRangeStart: + }break; + case OOX::et_w_moveToRangeStart: { OOX::Logic::CMoveToRangeStart* pMoveToRangeStart = static_cast(item); nCurPos = m_oBcw.WriteItemStart(c_oSer_OMathContentType::MoveToRangeStart); WriteMoveRangeStart(*pMoveToRangeStart); m_oBcw.WriteItemEnd(nCurPos); - break; - } - case OOX::et_w_moveToRangeEnd: + }break; + case OOX::et_w_moveToRangeEnd: { OOX::Logic::CMoveToRangeEnd* pMoveToRangeEnd = static_cast(item); nCurPos = m_oBcw.WriteItemStart(c_oSer_OMathContentType::MoveToRangeEnd); WriteMoveRangeEnd(*pMoveToRangeEnd); m_oBcw.WriteItemEnd(nCurPos); + }break; + case OOX::et_w_permStart: + { + OOX::Logic::CPermStart* pPermStart = static_cast(item); + WritePermission(c_oSer_OMathContentType::PermStart, pPermStart); + }break; + case OOX::et_w_permEnd: + { + OOX::Logic::CPermEnd* pPermEnd = static_cast(item); + WritePermission(c_oSer_OMathContentType::PermEnd, pPermEnd); + }break; + default: break; - } - default: - break; } } } @@ -5040,6 +5104,73 @@ void BinaryDocumentTableWriter::WriteMathRunContent(OOX::Logic::CMRun* pMRun) WriteMathIns(pMRun->m_oIns.get()); m_oBcw.WriteItemEnd(nCurPos2); } + if (pMRun->m_oNoBreakHyphen.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_OMathContentType::NoBreakHyphen); + m_oBcw.m_oStream.WriteLONG(c_oSerPropLenType::Null); + } + if (pMRun->m_oSoftHyphen.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_OMathContentType::SoftHyphen); + m_oBcw.m_oStream.WriteLONG(c_oSerPropLenType::Null); + } + if (pMRun->m_oTab.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_OMathContentType::Tab); + m_oBcw.m_oStream.WriteLONG(c_oSerPropLenType::Null); + } + if (pMRun->m_oSym.IsInit()) + { + wchar_t ch = 0x0FFF & pMRun->m_oSym->m_oChar->GetValue(); + std::wstring sText(&ch, 1); + + int nCurPos2 = m_oBcw.WriteItemStart(c_oSer_OMathContentType::Sym); + m_oBcw.m_oStream.WriteStringW(sText); + m_oBcw.WriteItemEnd(nCurPos2); + } + if (pMRun->m_oAnnotationRef.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_OMathContentType::AnnotationRef); + m_oBcw.m_oStream.WriteLONG(c_oSerPropLenType::Null); + } + if (pMRun->m_oCommentReference.IsInit()) + { + int nCurPos2 = m_oBcw.WriteItemStart(c_oSer_OMathContentType::CommentReference); + WriteComment(OOX::et_w_commentReference, pMRun->m_oCommentReference->m_oId); + m_oBcw.WriteItemEnd(nCurPos2); + } + if (pMRun->m_oCr.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_OMathContentType::Cr); + m_oBcw.m_oStream.WriteLONG(c_oSerPropLenType::Null); + } + if (pMRun->m_oEndnoteRef.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_OMathContentType::EndnoteRef); + m_oBcw.m_oStream.WriteLONG(c_oSerPropLenType::Null); + } + if (pMRun->m_oEndnoteReference.IsInit()) + { + int nCurPos2 = m_oBcw.WriteItemStart(c_oSer_OMathContentType::EndnoteReference); + WriteNoteRef(pMRun->m_oEndnoteReference->m_oCustomMarkFollows, pMRun->m_oEndnoteReference->m_oId); + m_oBcw.WriteItemEnd(nCurPos2); + } + if (pMRun->m_oFootnoteRef.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_OMathContentType::FootnoteRef); + m_oBcw.m_oStream.WriteLONG(c_oSerPropLenType::Null); + } + if (pMRun->m_oFootnoteReference.IsInit()) + { + int nCurPos2 = m_oBcw.WriteItemStart(c_oSer_OMathContentType::FootnoteReference); + WriteNoteRef(pMRun->m_oFootnoteReference->m_oCustomMarkFollows, pMRun->m_oFootnoteReference->m_oId); + m_oBcw.WriteItemEnd(nCurPos2); + } + if (pMRun->m_oLastRenderedPageBreak.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_OMathContentType::LastRenderedPageBreak); + m_oBcw.m_oStream.WriteLONG(c_oSerPropLenType::Null); + } } void BinaryDocumentTableWriter::WriteMathAccPr(const OOX::Logic::CAccPr &pAccPr) { @@ -6424,7 +6555,7 @@ void BinaryDocumentTableWriter::WriteRunContent(std::vector(item); wchar_t ch = 0x0FFF & oSym->m_oChar->GetValue(); std::wstring sText(&ch, 1); - WriteText(sText, c_oSerRunType::run); + WriteText(sText, c_oSerRunType::run); // todooo определить что писать c_oSerRunType::run или c_oSerRunType::delText - 66333 break; } case OOX::et_w_delText: @@ -6563,7 +6694,7 @@ bool BinaryDocumentTableWriter::WriteDrawingPptx(OOX::WritingElement* item) } res = WriteDrawingPptx(we); - if (res == false || we == NULL) + if (res == false || we == NULL || m_oParamsWriter.bWriteAlternative) { if (false == pAlternateContent->m_arrFallbackItems.empty()) { @@ -6608,7 +6739,8 @@ bool BinaryDocumentTableWriter::WriteDrawingPptx(OOX::WritingElement* item) } else { - int nCurPos = m_oBcw.WriteItemStart(c_oSerRunType::pptxDrawing); + int nCurPos = m_oBcw.WriteItemStart(m_oParamsWriter.bWriteAlternative ? c_oSerRunType::pptxDrawingAlternative : c_oSerRunType::pptxDrawing); + m_oParamsWriter.bWriteAlternative = false; WriteDrawing(NULL, pGraphicDrawing, pGraphic); m_oBcw.WriteItemEnd(nCurPos); } @@ -6625,6 +6757,8 @@ void BinaryDocumentTableWriter::WriteDrawing(std::wstring* pXml, OOX::Logic::CDr int nCurPos = 0; bool bDeleteDrawing = false; + + m_oBcw.m_oStream.m_dCxCurShape = m_oBcw.m_oStream.m_dCyCurShape = 0; //pptxdata if (pXml) { @@ -6657,6 +6791,28 @@ void BinaryDocumentTableWriter::WriteDrawing(std::wstring* pXml, OOX::Logic::CDr } else if (pGraphic) { + if (NULL != pDrawing) + { + OOX::Logic::CDrawing& img = *pDrawing; + if (img.m_oInline.IsInit()) + { + const OOX::Drawing::CInline& pInline = img.m_oInline.get(); + if (pInline.m_oExtent.IsInit()) + { + m_oBcw.m_oStream.m_dCxCurShape = pInline.m_oExtent->m_oCx.GetValue(); + m_oBcw.m_oStream.m_dCyCurShape = pInline.m_oExtent->m_oCy.GetValue(); + } + } + else if (img.m_oAnchor.IsInit()) + { + const OOX::Drawing::CAnchor& pAnchor = img.m_oAnchor.get(); + if (pAnchor.m_oExtent.IsInit()) + { + m_oBcw.m_oStream.m_dCxCurShape = pAnchor.m_oExtent->m_oCx.GetValue(); + m_oBcw.m_oStream.m_dCyCurShape = pAnchor.m_oExtent->m_oCy.GetValue(); + } + } + } if (pGraphic->chartRec.IsInit() && pGraphic->chartRec->id_data.IsInit() ) { m_oBcw.m_oStream.WriteBYTE(pGraphic->chartRec->m_bChartEx ? c_oSerImageType2::ChartEx : c_oSerImageType2::Chart); @@ -6667,6 +6823,11 @@ void BinaryDocumentTableWriter::WriteDrawing(std::wstring* pXml, OOX::Logic::CDr pGraphic->chartRec->toPPTY(&m_oBcw.m_oStream); m_oBcw.WriteItemWithLengthEnd(nCurPos); + + if (pGraphic->chartRec->m_bChartEx) + { + m_oParamsWriter.bWriteAlternative = true; + } } else { @@ -6682,11 +6843,6 @@ void BinaryDocumentTableWriter::WriteDrawing(std::wstring* pXml, OOX::Logic::CDr { pGraphic->olePic->toPPTY(&m_oBcw.m_oStream); } - //else if (pGraphic->smartArt.is_init()) - //{ - // pGraphic->smartArt->LoadDrawing(&m_oBcw.m_oStream); - // pGraphic->smartArt->toPPTY(&m_oBcw.m_oStream); - //} else if (pGraphic->element.is_init()) { pGraphic->element.toPPTY(&m_oBcw.m_oStream); @@ -7501,7 +7657,7 @@ void BinaryDocumentTableWriter::WriteTableContent(std::vectorgetType()) + { + OOX::Logic::CPermStart* pPermStart = static_cast(item); + WritePermission(c_oSerDocTableType::PermStart, pPermStart); + } + else if (OOX::et_w_permEnd == item->getType()) + { + OOX::Logic::CPermEnd* pPermEnd = static_cast(item); + WritePermission(c_oSerDocTableType::PermEnd, pPermEnd); + } + } } void BinaryDocumentTableWriter::WriteRow(const OOX::Logic::CTr& Row, OOX::Logic::CTableProperty* pTblPr, int nCurRowIndex) @@ -7678,6 +7845,16 @@ void BinaryDocumentTableWriter::WriteRowContent(const std::vectorgetType()) + { + OOX::Logic::CPermStart* pPermStart = static_cast(item); + WritePermission(c_oSerDocTableType::PermStart, pPermStart); + } + else if (OOX::et_w_permEnd == item->getType()) + { + OOX::Logic::CPermEnd* pPermEnd = static_cast(item); + WritePermission(c_oSerDocTableType::PermEnd, pPermEnd); + } } } void BinaryDocumentTableWriter::WriteCell(OOX::Logic::CTc& tc, OOX::Logic::CTableProperty* pTblPr, int nCurRowIndex, int nCurColIndex) @@ -7932,6 +8109,12 @@ void BinaryDocumentTableWriter::WriteSdtPicture(const OOX::Logic::CSdtPicture& o m_oBcw.m_oStream.WriteDoubleReal(*oSdtPicture.m_oShiftY); m_oBcw.WriteItemEnd(nCurPos); } + if (oSdtPicture.m_oSignature.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerSdt::PictureFormPrSignature); + m_oBcw.m_oStream.WriteBOOL(*oSdtPicture.m_oSignature); + m_oBcw.WriteItemEnd(nCurPos); + } } void BinaryDocumentTableWriter::WriteSdtComplexFormPr(const OOX::Logic::CComplexFormPr& oComplexFormPr) { @@ -8048,6 +8231,12 @@ void BinaryDocumentTableWriter::WriteSdtPrDataBinding(const ComplexTypes::Word:: m_oBcw.m_oStream.WriteStringW3(oDataBinding.m_sXPath.get()); m_oBcw.WriteItemEnd(nCurPos); } + if (oDataBinding.m_sStoreItemChecksum.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerSdt::StoreItemChecksum); + m_oBcw.m_oStream.WriteStringW3(oDataBinding.m_sStoreItemChecksum.get()); + m_oBcw.WriteItemEnd(nCurPos); + } } void BinaryDocumentTableWriter::WriteSdtPrDate(const OOX::Logic::CDate& oDate) { @@ -8695,7 +8884,7 @@ void BinarySettingsTableWriter::WriteSettingsContent(OOX::CSettings& oSettings, m_oBcw.m_oStream.WriteBOOL(oSettings.m_oAutoHyphenation->m_oVal.ToBool()); m_oBcw.WriteItemEnd(nCurPos); } - if (oSettings.m_oHyphenationZone.IsInit()) + if (oSettings.m_oHyphenationZone.IsInit() && oSettings.m_oHyphenationZone->m_oVal.IsInit()) { nCurPos = m_oBcw.WriteItemStart(c_oSer_SettingsType::HyphenationZone); m_oBcw.m_oStream.WriteLONG(oSettings.m_oHyphenationZone->m_oVal->ToTwips()); @@ -8713,6 +8902,42 @@ void BinarySettingsTableWriter::WriteSettingsContent(OOX::CSettings& oSettings, m_oBcw.m_oStream.WriteLONG(*oSettings.m_oConsecutiveHyphenLimit->m_oVal); m_oBcw.WriteItemEnd(nCurPos); } + if ((oSettings.m_oDrawingGridHorizontalOrigin.IsInit()) && (oSettings.m_oDrawingGridHorizontalOrigin->m_oVal.IsInit())) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_SettingsType::DrawingGridHorizontalOrigin); + m_oBcw.m_oStream.WriteLONG(oSettings.m_oDrawingGridHorizontalOrigin->m_oVal->ToTwips()); + m_oBcw.WriteItemEnd(nCurPos); + } + if ((oSettings.m_oDrawingGridHorizontalSpacing.IsInit()) && (oSettings.m_oDrawingGridHorizontalSpacing->m_oVal.IsInit())) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_SettingsType::DrawingGridHorizontalSpacing); + m_oBcw.m_oStream.WriteLONG(oSettings.m_oDrawingGridHorizontalSpacing->m_oVal->ToTwips()); + m_oBcw.WriteItemEnd(nCurPos); + } + if ((oSettings.m_oDrawingGridVerticalOrigin.IsInit()) && (oSettings.m_oDrawingGridVerticalOrigin->m_oVal.IsInit())) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_SettingsType::DrawingGridVerticalOrigin); + m_oBcw.m_oStream.WriteLONG(oSettings.m_oDrawingGridVerticalOrigin->m_oVal->ToTwips()); + m_oBcw.WriteItemEnd(nCurPos); + } + if ((oSettings.m_oDrawingGridVerticalSpacing.IsInit()) && (oSettings.m_oDrawingGridVerticalSpacing->m_oVal.IsInit())) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_SettingsType::DrawingGridVerticalSpacing); + m_oBcw.m_oStream.WriteLONG(oSettings.m_oDrawingGridVerticalSpacing->m_oVal->ToTwips()); + m_oBcw.WriteItemEnd(nCurPos); + } + if ((oSettings.m_oDisplayHorizontalDrawingGridEvery.IsInit()) && (oSettings.m_oDisplayHorizontalDrawingGridEvery->m_oVal.IsInit())) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_SettingsType::DisplayHorizontalDrawingGridEvery); + m_oBcw.m_oStream.WriteLONG(*oSettings.m_oDisplayHorizontalDrawingGridEvery->m_oVal); + m_oBcw.WriteItemEnd(nCurPos); + } + if ((oSettings.m_oDisplayVerticalDrawingGridEvery.IsInit()) && (oSettings.m_oDisplayVerticalDrawingGridEvery->m_oVal.IsInit())) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_SettingsType::DisplayVerticalDrawingGridEvery); + m_oBcw.m_oStream.WriteLONG(*oSettings.m_oDisplayVerticalDrawingGridEvery->m_oVal); + m_oBcw.WriteItemEnd(nCurPos); + } }; void BinarySettingsTableWriter::WriteMathPr(const OOX::Logic::CMathPr &pMathPr) { @@ -9414,7 +9639,10 @@ void BinaryFileWriter::WriteMainTableStart(bool bSigTable) if (bSigTable) { //BinarySigTableWriter - int nCurPos = WriteTableStart(c_oSerTableTypes::Signature); + memset(m_oBcw.m_oStream.GetBuffer() + m_oBcw.m_oStream.GetPosition(), 0, 5 + nTableCount * nmtItemSize); + + int nCurPos = WriteTableStart(c_oSerTableTypes::Signature); + BinarySigTableWriter oBinarySigTableWriter(m_oParamsWriter); oBinarySigTableWriter.Write(); WriteTableEnd(nCurPos); @@ -9565,18 +9793,14 @@ void BinaryFileWriter::intoBindoc(const std::wstring& sSrcPath) if ((pDocx) && (pDocx->m_pApp)) { nCurPos = this->WriteTableStart(BinDocxRW::c_oSerTableTypes::App); - PPTX::App* pAppTmp = pDocx->m_pApp->ToPptxApp(); - pAppTmp->toPPTY(&oBufferedStream); - delete pAppTmp; + pDocx->m_pApp->toPPTY(&oBufferedStream); this->WriteTableEnd(nCurPos); } if ((pDocx) && (pDocx->m_pCore)) { nCurPos = this->WriteTableStart(BinDocxRW::c_oSerTableTypes::Core); - PPTX::Core* pCoreTmp = pDocx->m_pCore->ToPptxCore(); - pCoreTmp->toPPTY(&oBufferedStream); - delete pCoreTmp; + pDocx->m_pCore->toPPTY(&oBufferedStream); this->WriteTableEnd(nCurPos); } if (NULL != m_oParamsWriter.m_pTheme) diff --git a/OOXML/Binary/Document/BinWriter/BinWriters.h b/OOXML/Binary/Document/BinWriter/BinWriters.h index be02f129734..4bc17e52f72 100644 --- a/OOXML/Binary/Document/BinWriter/BinWriters.h +++ b/OOXML/Binary/Document/BinWriter/BinWriters.h @@ -98,6 +98,8 @@ namespace BinDocxRW NSFontCutter::CEmbeddedFontsManager* pEmbeddedFontsManager); std::wstring AddEmbeddedStyle(const std::wstring & styleId); + + bool bWriteAlternative = false; }; class ParamsDocumentWriter { @@ -209,6 +211,7 @@ namespace BinDocxRW nullable* endPos, std::vector* refs); void WriteNumFmt(const ComplexTypes::Word::CNumFmt& oNumFmt); void WriteCnfStyle(ComplexTypes::Word::CCnf *cnf); + void WriteDocGrid(const ComplexTypes::Word::CDocGrid& docGrid); }; class Binary_tblPrWriter { @@ -340,8 +343,8 @@ namespace BinDocxRW template void WriteMoveRangeEnd(const T& elem); void WriteComment(OOX::EElementType eType, nullable& oId); void WriteFldChar(OOX::Logic::CFldChar* pFldChar); - void WritePermission(OOX::Logic::CPermStart* pPerm); - void WritePermission(OOX::Logic::CPermEnd* pPerm); + void WritePermission(unsigned char type, OOX::Logic::CPermStart* pPerm); + void WritePermission(unsigned char type, OOX::Logic::CPermEnd* pPerm); void WriteFldSimple(OOX::Logic::CFldSimple* pFldSimple); void WriteFldSimpleContent(OOX::Logic::CFldSimple* pFldSimple); void WriteFFData(const OOX::Logic::CFFData& oFFData); diff --git a/OOXML/Binary/Document/DocWrapper/DocxSerializer.cpp b/OOXML/Binary/Document/DocWrapper/DocxSerializer.cpp index 0f48a2e1e74..20b1760ee03 100644 --- a/OOXML/Binary/Document/DocWrapper/DocxSerializer.cpp +++ b/OOXML/Binary/Document/DocWrapper/DocxSerializer.cpp @@ -320,165 +320,167 @@ bool BinDocxRW::CDocxSerializer::CreateDocxFolders(std::wstring strDirectory, st } bool BinDocxRW::CDocxSerializer::loadFromFile(const std::wstring& sSrcFileName, const std::wstring& sDstPath, const std::wstring& sXMLOptions, const std::wstring& sThemePath, const std::wstring& sMediaPath, const std::wstring& sEmbedPath) { - bool bResultOk = false; RELEASEOBJECT(m_pCurFileWriter); NSFile::CFileBinary oFile; - if(oFile.OpenFile(sSrcFileName)) - { - DWORD nBase64DataSize = 0; - BYTE* pBase64Data = new BYTE[oFile.GetFileSize()]; - oFile.ReadFile(pBase64Data, oFile.GetFileSize(), nBase64DataSize); - oFile.CloseFile(); + if (false == oFile.OpenFile(sSrcFileName)) return false; + + bool bResultOk = false; - //проверяем формат - bool bValidFormat = false; - std::wstring sSignature(g_sFormatSignature); - int nSigLength = (int)sSignature.length(); - - if ((int)nBase64DataSize > nSigLength) + DWORD nBase64DataSize = 0; + BYTE* pBase64Data = new BYTE[oFile.GetFileSize()]; + oFile.ReadFile(pBase64Data, oFile.GetFileSize(), nBase64DataSize); + oFile.CloseFile(); + + //проверяем формат + bool bValidFormat = false; + std::wstring sSignature(g_sFormatSignature); + int nSigLength = (int)sSignature.length(); + + if ((int)nBase64DataSize > nSigLength) + { + std::string sCurSig((char*)pBase64Data, nSigLength); + if (sSignature == std::wstring(sCurSig.begin(), sCurSig.end())) { - std::string sCurSig((char*)pBase64Data, nSigLength); - if(sSignature == std::wstring(sCurSig.begin(), sCurSig.end())) - { - bValidFormat = true; - } + bValidFormat = true; } - if(bValidFormat) - { - //Читаем из файла версию и длину base64 - int nIndex = nSigLength; - int nType = 0; - std::string version = ""; - std::string dst_len = ""; - - while (nIndex < nBase64DataSize) - { - nIndex++; - BYTE _c = pBase64Data[nIndex]; - if (_c == ';') - { - if(0 == nType) - { - nType = 1; - continue; - } - else - { - nIndex++; - break; - } - } - if(0 == nType) - version += _c; - else - dst_len += _c; - } - int nVersion = g_nFormatVersion; - if(!version.empty()) - { - version = version.substr(1); - g_nCurFormatVersion = nVersion = std::stoi(version.c_str()); - } - bool bIsNoBase64 = nVersion == g_nFormatVersionNoBase64; + } + if (bValidFormat) + { + //Читаем из файла версию и длину base64 + int nIndex = nSigLength; + int nType = 0; + std::string version = ""; + std::string dst_len = ""; - NSBinPptxRW::CDrawingConverter oDrawingConverter; - NSBinPptxRW::CBinaryFileReader& oBufferedStream = *oDrawingConverter.m_pReader; - int nDataSize = 0; - BYTE* pData = NULL; - if (!bIsNoBase64) + while (nIndex < nBase64DataSize) + { + nIndex++; + BYTE _c = pBase64Data[nIndex]; + if (_c == ';') { - nDataSize = atoi(dst_len.c_str()); - pData = new BYTE[nDataSize]; - if(Base64::Base64Decode((const char*)(pBase64Data + nIndex), nBase64DataSize - nIndex, pData, &nDataSize)) + if (0 == nType) { - oBufferedStream.Init(pData, 0, nDataSize); + nType = 1; + continue; } else { - RELEASEARRAYOBJECTS(pData); + nIndex++; + break; } } + if (0 == nType) + version += _c; else + dst_len += _c; + } + int nVersion = g_nFormatVersion; + if (!version.empty()) + { + version = version.substr(1); + g_nCurFormatVersion = nVersion = std::stoi(version.c_str()); + } + bool bIsNoBase64 = nVersion == g_nFormatVersionNoBase64; + + NSBinPptxRW::CDrawingConverter oDrawingConverter; + NSBinPptxRW::CBinaryFileReader& oBufferedStream = *oDrawingConverter.m_pReader; + int nDataSize = 0; + BYTE* pData = NULL; + if (!bIsNoBase64) + { + nDataSize = atoi(dst_len.c_str()); + pData = new BYTE[nDataSize]; + if (Base64::Base64Decode((const char*)(pBase64Data + nIndex), nBase64DataSize - nIndex, pData, &nDataSize)) { - nDataSize = nBase64DataSize; - pData = pBase64Data; oBufferedStream.Init(pData, 0, nDataSize); - oBufferedStream.Seek(nIndex); } - - - if (NULL != pData) + else { - oDrawingConverter.SetMainDocument(this); - oDrawingConverter.SetDstPath(sDstPath + FILE_SEPARATOR_STR + L"word"); + RELEASEARRAYOBJECTS(pData); + } + } + else + { + nDataSize = nBase64DataSize; + pData = pBase64Data; + oBufferedStream.Init(pData, 0, nDataSize); + oBufferedStream.Seek(nIndex); + } - oDrawingConverter.SetMediaDstPath(sMediaPath); - oDrawingConverter.SetEmbedDstPath(sEmbedPath); - - m_pCurFileWriter = new Writers::FileWriter(sDstPath, m_sFontDir, false, nVersion, &oDrawingConverter, sThemePath); + if (NULL != pData) + { + oDrawingConverter.SetMainDocument(this); + oDrawingConverter.SetDstPath(sDstPath + FILE_SEPARATOR_STR + L"word"); - //папка с картинками - std::wstring strFileInDir = NSSystemPath::GetDirectoryName(sSrcFileName); - std::wstring sFileInDir = strFileInDir.c_str(); + oDrawingConverter.SetMediaDstPath(sMediaPath); + oDrawingConverter.SetEmbedDstPath(sEmbedPath); - oDrawingConverter.SetSrcPath(sFileInDir); - - BinaryFileReader oBinaryFileReader(sFileInDir, oBufferedStream, *m_pCurFileWriter, m_bIsMacro, m_bIsOForm); - oBinaryFileReader.ReadFile(); -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - //themes - m_pCurFileWriter->m_oTheme.Write(sThemePath); + m_pCurFileWriter = new Writers::FileWriter(sDstPath, m_sFontDir, false, nVersion, &oDrawingConverter, sThemePath); - OOX::CContentTypes *pContentTypes = oDrawingConverter.GetContentTypes(); - //docProps - OOX::CPath pathDocProps = sDstPath + FILE_SEPARATOR_STR + _T("docProps"); - NSDirectory::CreateDirectory(pathDocProps.GetPath()); - - OOX::CPath DocProps = std::wstring(_T("docProps")); + //папка с картинками + std::wstring strFileInDir = NSSystemPath::GetDirectoryName(sSrcFileName); + std::wstring sFileInDir = strFileInDir.c_str(); - if (NULL != m_pCurFileWriter->m_pApp) - { - m_pCurFileWriter->m_pApp->write(pathDocProps + FILE_SEPARATOR_STR + _T("app.xml"), DocProps, *pContentTypes); - } - else - { - OOX::CApp pApp(NULL); - pApp.SetDefaults(); - pApp.write(pathDocProps + FILE_SEPARATOR_STR + _T("app.xml"), DocProps, *pContentTypes); - } + oDrawingConverter.SetSrcPath(sFileInDir); - if (NULL != m_pCurFileWriter->m_pCore) - { - m_pCurFileWriter->m_pCore->write(pathDocProps + FILE_SEPARATOR_STR + _T("core.xml"), DocProps, *pContentTypes); - } - else - { - OOX::CCore pCore(NULL); - pCore.SetDefaults(); - pCore.write(pathDocProps + FILE_SEPARATOR_STR + _T("core.xml"), DocProps, *pContentTypes); - } + BinaryFileReader oBinaryFileReader(sFileInDir, oBufferedStream, *m_pCurFileWriter, m_bIsMacro, m_bIsOForm); + oBinaryFileReader.ReadFile(); - if (NULL != m_pCurFileWriter->m_pCustomProperties) - { - m_pCurFileWriter->m_pCustomProperties->write(pathDocProps + FILE_SEPARATOR_STR + _T("custom.xml"), DocProps, *pContentTypes); - } + m_bIsMacro = m_bIsMacro && oBinaryFileReader.m_bMacroRead; + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + //themes + m_pCurFileWriter->m_oTheme.Write(sThemePath); -///////////////////////////////////////////////////////////////////////////////////// - m_pCurFileWriter->Write(); - pContentTypes->Write(sDstPath); + OOX::CContentTypes* pContentTypes = oDrawingConverter.GetContentTypes(); + //docProps + OOX::CPath pathDocProps = sDstPath + FILE_SEPARATOR_STR + _T("docProps"); + NSDirectory::CreateDirectory(pathDocProps.GetPath()); - bResultOk = true; + OOX::CPath DocProps = std::wstring(_T("docProps")); + if (NULL != m_pCurFileWriter->m_pApp) + { + m_pCurFileWriter->m_pApp->write(pathDocProps + FILE_SEPARATOR_STR + _T("app.xml"), DocProps, *pContentTypes); } - if (!bIsNoBase64) + else { - RELEASEARRAYOBJECTS(pData); + OOX::CApp pApp(NULL); + pApp.SetDefaults(); + pApp.write(pathDocProps + FILE_SEPARATOR_STR + _T("app.xml"), DocProps, *pContentTypes); } + if (NULL != m_pCurFileWriter->m_pCore) + { + m_pCurFileWriter->m_pCore->write(pathDocProps + FILE_SEPARATOR_STR + _T("core.xml"), DocProps, *pContentTypes); + } + else + { + OOX::CCore pCore(NULL); + pCore.SetDefaults(); + pCore.write(pathDocProps + FILE_SEPARATOR_STR + _T("core.xml"), DocProps, *pContentTypes); + } + + if (NULL != m_pCurFileWriter->m_pCustomProperties) + { + m_pCurFileWriter->m_pCustomProperties->write(pathDocProps + FILE_SEPARATOR_STR + _T("custom.xml"), DocProps, *pContentTypes); + } + + ///////////////////////////////////////////////////////////////////////////////////// + m_pCurFileWriter->Write(); + pContentTypes->Write(sDstPath); + + bResultOk = true; + } - RELEASEARRAYOBJECTS(pBase64Data); + if (!bIsNoBase64) + { + RELEASEARRAYOBJECTS(pData); + } + } + RELEASEARRAYOBJECTS(pBase64Data); + return bResultOk; } bool BinDocxRW::CDocxSerializer::getXmlContent(NSBinPptxRW::CBinaryFileReader& oBufferedStream, long lLength, std::wstring& sOutputXml) @@ -613,6 +615,10 @@ void BinDocxRW::CDocxSerializer::setMacroEnabled(bool val) { m_bIsMacro = val; } +bool BinDocxRW::CDocxSerializer::getMacroEnabled() +{ + return m_bIsMacro; +} void BinDocxRW::CDocxSerializer::setOFormEnabled(bool val) { m_bIsOForm = val; @@ -623,9 +629,12 @@ bool BinDocxRW::CDocxSerializer::unpackageFile(const std::wstring& sSrcFileName, return file.unpackage(sSrcFileName, sDstPath); } -bool BinDocxRW::CDocxSerializer::convertFlat(const std::wstring& sSrcFileName, const std::wstring& sDstPath) +bool BinDocxRW::CDocxSerializer::convertFlat(const std::wstring& sSrcFileName, const std::wstring& sDstPath, bool &bMacro, const std::wstring& sTempPath) { - OOX::CDocxFlat docxflat(sSrcFileName); + OOX::CDocxFlat docxflat; + + docxflat.m_sTempPath = sTempPath; + docxflat.read(sSrcFileName); if (false == docxflat.m_pDocument.IsInit()) return false; @@ -637,6 +646,8 @@ bool BinDocxRW::CDocxSerializer::convertFlat(const std::wstring& sSrcFileName, c NSCommon::smart_ptr file = docxflat.m_pDocument.GetPointer(); file.AddRef(); docx.Add(file); docx.m_oMain.document = docxflat.m_pDocument.GetPointer(); + + bMacro = bMacro && docxflat.m_pDocument->m_bMacroEnabled; } if (docxflat.m_pApp.IsInit()) { @@ -648,6 +659,7 @@ bool BinDocxRW::CDocxSerializer::convertFlat(const std::wstring& sSrcFileName, c NSCommon::smart_ptr file(docxflat.m_pCore.GetPointer()); file.AddRef(); docx.Add(file); } + //docxflat.m_oBgPict.GetPointer(); return docx.Write(sDstPath); diff --git a/OOXML/Binary/Document/DocWrapper/DocxSerializer.h b/OOXML/Binary/Document/DocWrapper/DocxSerializer.h index 9f0223cec62..bd03c346f1d 100644 --- a/OOXML/Binary/Document/DocWrapper/DocxSerializer.h +++ b/OOXML/Binary/Document/DocWrapper/DocxSerializer.h @@ -67,7 +67,7 @@ namespace BinDocxRW bool saveToFile (const std::wstring& sSrcFileName, const std::wstring& sDstPath, const std::wstring& sXMLOptions, const std::wstring& sTempPath); bool unpackageFile(const std::wstring& sSrcFileName, const std::wstring& sDstPath); - bool convertFlat(const std::wstring& sSrcFileName, const std::wstring& sDstPath); + bool convertFlat(const std::wstring& sSrcFileName, const std::wstring& sDstPath, bool& bMacro, const std::wstring& sTempPath); bool CreateDocxFolders(std::wstring strDirectory, std::wstring& sThemePath, std::wstring& sMediaPath, std::wstring& sEmbedPath); @@ -82,7 +82,9 @@ namespace BinDocxRW void setIsNoBase64Save (bool val); void setIsNoBase64 (bool val); void setSaveChartAsImg (bool val); - void setMacroEnabled (bool val); void setOFormEnabled (bool val); + + void setMacroEnabled (bool val); + bool getMacroEnabled(); }; } diff --git a/OOXML/Binary/Document/DocWrapper/XlsxSerializer.cpp b/OOXML/Binary/Document/DocWrapper/XlsxSerializer.cpp index 962160cd71c..8155853ffa6 100644 --- a/OOXML/Binary/Document/DocWrapper/XlsxSerializer.cpp +++ b/OOXML/Binary/Document/DocWrapper/XlsxSerializer.cpp @@ -286,6 +286,10 @@ namespace BinXlsxRW{ { m_bIsMacro = val; } + bool CXlsxSerializer::getMacroEnabled() + { + return m_bIsMacro; + } bool CXlsxSerializer::writeChartXlsx(const std::wstring& sDstFile, NSCommon::smart_ptr &file) { diff --git a/OOXML/Binary/Document/DocWrapper/XlsxSerializer.h b/OOXML/Binary/Document/DocWrapper/XlsxSerializer.h index d0b3c381c04..e0d4fc04173 100644 --- a/OOXML/Binary/Document/DocWrapper/XlsxSerializer.h +++ b/OOXML/Binary/Document/DocWrapper/XlsxSerializer.h @@ -71,7 +71,9 @@ namespace BinXlsxRW { void setEmbeddedFontsDir(const std::wstring& sEmbeddedFontsDir); void setDrawingConverter(NSBinPptxRW::CDrawingConverter* pDrawingConverter); void setIsNoBase64 (bool val); + void setMacroEnabled (bool val); + bool getMacroEnabled (); _UINT32 xml2Xlsx (const std::wstring& sSrcFileName, const std::wstring& sDstPath, const std::wstring& sXMLOptions); diff --git a/OOXML/Binary/Presentation/BinReaderWriterDefines.h b/OOXML/Binary/Presentation/BinReaderWriterDefines.h index cf1687bce83..28af712555d 100644 --- a/OOXML/Binary/Presentation/BinReaderWriterDefines.h +++ b/OOXML/Binary/Presentation/BinReaderWriterDefines.h @@ -197,22 +197,24 @@ namespace NSBinPptxRW #define SPTREE_TYPE_OLE 6 #define SPTREE_TYPE_VIDEO 7 #define SPTREE_TYPE_AUDIO 8 -#define SPTREE_TYPE_LOCKED_CANVAS 9 +#define SPTREE_TYPE_LOCKED_CANVAS 9 + +#define SPTREE_TYPE_ALTERNATIVE 0x99 #define DIAGRAM_LAYOUT_TYPE_NONE 0xB0 #define DIAGRAM_LAYOUT_TYPE_ALG 0xB1 #define DIAGRAM_LAYOUT_TYPE_CHOOSE 0xB2 -#define DIAGRAM_LAYOUT_TYPE_CONSTRLST 0xB3 +#define DIAGRAM_LAYOUT_TYPE_CONSTRLST 0xB3 #define DIAGRAM_LAYOUT_TYPE_FOREACH 0xB4 -#define DIAGRAM_LAYOUT_TYPE_LAYOUTNODE 0xB5 +#define DIAGRAM_LAYOUT_TYPE_LAYOUTNODE 0xB5 #define DIAGRAM_LAYOUT_TYPE_PRESOF 0xB6 #define DIAGRAM_LAYOUT_TYPE_RULELST 0xB7 #define DIAGRAM_LAYOUT_TYPE_SHAPE 0xB8 -#define DIAGRAM_LAYOUT_TYPE_VARIABLELIST 0xB9 +#define DIAGRAM_LAYOUT_TYPE_VARIABLELIST 0xB9 -#define SPTREE_TYPE_MACRO 0xA1 +#define SPTREE_TYPE_MACRO 0xA1 static BYTE SchemeClr_GetBYTECode(const std::wstring& sValue) diff --git a/OOXML/Binary/Presentation/BinaryFileReaderWriter.cpp b/OOXML/Binary/Presentation/BinaryFileReaderWriter.cpp index 816a20b5cf9..bbc786c582c 100644 --- a/OOXML/Binary/Presentation/BinaryFileReaderWriter.cpp +++ b/OOXML/Binary/Presentation/BinaryFileReaderWriter.cpp @@ -231,7 +231,7 @@ namespace NSBinPptxRW if (IsNeedDownload(strInput)) return DownloadImage(strInput); - std::map::const_iterator pPair = m_mapImages.find ((strBase64Image.empty()) ? strInput : strBase64Image); + std::map::const_iterator pPair = m_mapImages.find ((strBase64Image.empty()) ? strInput + oleData : strBase64Image + oleData); if (pPair != m_mapImages.end()) { @@ -386,9 +386,9 @@ namespace NSBinPptxRW } if (strBase64Image.empty()) - m_mapImages[strInput] = oImageManagerInfo; + m_mapImages[strInput + oleData] = oImageManagerInfo; else - m_mapImages [strBase64Image] = oImageManagerInfo; + m_mapImages [strBase64Image + oleData] = oImageManagerInfo; return oImageManagerInfo; } bool CImageManager2::WriteOleData(const std::wstring& sFilePath, const std::wstring& sData) @@ -479,23 +479,29 @@ namespace NSBinPptxRW }break; case _CXIMAGE_FORMAT_SVG: { - strExts = L".png"; - oPathOutput = m_strDstMedia + FILE_SEPARATOR_STR + strImage + strExts; - - NSFonts::IApplicationFonts* appFonts = NSFonts::NSApplication::Create(); - appFonts->Initialize(); + try + { + strExts = L".png"; + oPathOutput = m_strDstMedia + FILE_SEPARATOR_STR + strImage + strExts; + + NSFonts::IApplicationFonts* appFonts = NSFonts::NSApplication::Create(); + appFonts->Initialize(); + + MetaFile::IMetaFile* pSvg = MetaFile::Create(appFonts); + if (pSvg->LoadFromFile(strInput.c_str())) + { + double x = 0, y = 0, w = 0, h = 0; + pSvg->GetBounds(&x, &y, &w, &h); + pSvg->ConvertToRaster(oPathOutput.GetPath().c_str(), _CXIMAGE_FORMAT_PNG, w, h); + } + RELEASEOBJECT(pSvg); + RELEASEOBJECT(appFonts); - MetaFile::IMetaFile* pSvg= MetaFile::Create(appFonts); - if (pSvg->LoadFromFile(strInput.c_str())) + oImageManagerInfo.sFilepathImage = oPathOutput.GetPath(); + } + catch (...) { - double x = 0, y = 0, w = 0, h = 0; - pSvg->GetBounds(&x, &y, &w, &h); - pSvg->ConvertToRaster(oPathOutput.GetPath().c_str(), _CXIMAGE_FORMAT_PNG, w, h); } - RELEASEOBJECT(pSvg); - RELEASEOBJECT(appFonts); - - oImageManagerInfo.sFilepathImage = oPathOutput.GetPath(); }break; default: { @@ -689,31 +695,33 @@ namespace NSBinPptxRW } double CBinaryFileWriter::GetShapeHeight() { - if (m_lCyCurShape == 0) + if (m_dCyCurShape < 0.001) return -1; - return (double)m_lCyCurShape / 36000; //mm + return m_dCyCurShape / 36000; //mm } double CBinaryFileWriter::GetShapeWidth() { - if (m_lCyCurShape == 0) + if (m_dCyCurShape < 0.001) return -1; - return (double)m_lCxCurShape / 36000; + return m_dCxCurShape / 36000; } double CBinaryFileWriter::GetShapeY() { - return (double)m_lYCurShape / 36000; + return m_dYCurShape / 36000; } double CBinaryFileWriter::GetShapeX() { - return (double)m_lXCurShape / 36000; //mm + return m_dXCurShape / 36000; //mm } void CBinaryFileWriter::ClearCurShapePositionAndSizes() { - m_lXCurShape = 0; - m_lYCurShape = 0; + m_dXCurShape = 0; + m_dYCurShape = 0; - m_lCxCurShape = 0; - m_lCyCurShape = 0; + m_dCxCurShape = 0; + m_dCyCurShape = 0; + + m_bInGroup = false; } void CBinaryFileWriter::Clear() { @@ -726,11 +734,13 @@ namespace NSBinPptxRW m_lStackPosition = 0; memset(m_arStack, 0, MAX_STACK_SIZE * sizeof(_UINT32)); - m_lCxCurShape = 0; - m_lCyCurShape = 0; + m_dCxCurShape = 0; + m_dCyCurShape = 0; + + m_dXCurShape = 0; + m_dYCurShape = 0; - m_lXCurShape = 0; - m_lYCurShape = 0; + m_bInGroup = false; } void CBinaryFileWriter::SetMainDocument(BinDocxRW::CDocxSerializer* pMainDoc) @@ -1343,11 +1353,14 @@ namespace NSBinPptxRW { if (m_lPosition > 0) { - CFileBinary::WriteFile(m_pStreamData, m_lPosition); + bool result = CFileBinary::WriteFile(m_pStreamData, m_lPosition); + if (result) + { + m_lPositionFlushed += m_lPosition; + m_lPosition = 0; + m_pStreamCur = m_pStreamData; + } } - m_lPositionFlushed += m_lPosition; - m_lPosition = 0; - m_pStreamCur = m_pStreamData; } void CStreamBinaryWriter::WriteReserved(size_t lCount) { @@ -1390,7 +1403,7 @@ namespace NSBinPptxRW } - CRelsGenerator::CRelsGenerator(CImageManager2* pManager) : m_lNextRelsID(1), m_mapImages() + CRelsGenerator::CRelsGenerator(CImageManager2* pManager) : m_lNextRelsID(1), m_mapRelsImages() { m_pManager = pManager; m_pWriter = new NSStringUtils::CStringBuilder(); @@ -1403,7 +1416,7 @@ namespace NSBinPptxRW { m_pWriter->ClearNoAttack(); m_lNextRelsID = 1; - m_mapImages.clear(); + m_mapRelsImages.clear(); m_mapLinks.clear(); } @@ -1605,20 +1618,20 @@ namespace NSBinPptxRW { _imageManager2Info oImageManagerInfo = m_pManager->GenerateMedia(strImage); - std::wstring strImageRelsPath; + std::wstring strMediaRelsPath; - if (m_pManager->m_nDocumentType == XMLWRITER_DOC_TYPE_DOCX) strImageRelsPath = L"media/"; - else strImageRelsPath = L"../media/"; + if (m_pManager->m_nDocumentType == XMLWRITER_DOC_TYPE_DOCX) strMediaRelsPath = L"media/"; + else strMediaRelsPath = L"../media/"; _relsGeneratorInfo oRelsGeneratorInfo; if (!oImageManagerInfo.sFilepathImage.empty()) { - strImageRelsPath += OOX::CPath(oImageManagerInfo.sFilepathImage).GetFilename(); + strMediaRelsPath += OOX::CPath(oImageManagerInfo.sFilepathImage).GetFilename(); - std::map::iterator pPair = m_mapImages.find(strImageRelsPath); + std::map::iterator pPair = m_mapRelsImages.find(strMediaRelsPath); - if (m_mapImages.end() != pPair) + if (m_mapRelsImages.end() != pPair) { return pPair->second; } @@ -1631,16 +1644,16 @@ namespace NSBinPptxRW if (type == 0) { m_pWriter->WriteString( L""); + L"\" Type=\"http://schemas.microsoft.com/office/2007/relationships/media\" Target=\"" + strMediaRelsPath + L"\"/>"); } else if (type == 1) { m_pWriter->WriteString( L""); + L"\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/audio\" Target=\"" + strMediaRelsPath + L"\"/>"); } } - m_mapImages.insert(std::pair(strImageRelsPath, oRelsGeneratorInfo)); + m_mapRelsImages.insert(std::pair(strMediaRelsPath, oRelsGeneratorInfo)); return oRelsGeneratorInfo; } @@ -1659,9 +1672,9 @@ namespace NSBinPptxRW { strImageRelsPath += OOX::CPath(oImageManagerInfo.sFilepathImage).GetFilename(); - std::map::iterator pPair = m_mapImages.find(strImageRelsPath); + std::map::iterator pPair = m_mapRelsImages.find(strImageRelsPath); - if (m_mapImages.end() != pPair) + if (m_mapRelsImages.end() != pPair) { return pPair->second; } @@ -1725,24 +1738,29 @@ namespace NSBinPptxRW if (m_pManager->m_nDocumentType == XMLWRITER_DOC_TYPE_DOCX) strMediaRelsPath = L"media/"; else strMediaRelsPath = L"../media/"; - strMediaRelsPath += mediaFile->filename().GetFilename(); + const std::wstring filename = mediaFile->filename().GetFilename(); - if (additionalFile.is() || additionalFile.is()) + if (!filename.empty()) { - m_pWriter->WriteString(L"IsExternal() ? L" TargetMode=\"External\"" : L"") + L"/>"); - } - else - { - m_pWriter->WriteString(L"type().RelationType() + L"\" Target=\"" + - strMediaRelsPath + L"\"" + (mediaFile->IsExternal() ? L" TargetMode=\"External\"" : L"") + L"/>"); + strMediaRelsPath += filename; + + if (additionalFile.is() || additionalFile.is()) + { + m_pWriter->WriteString(L"IsExternal() ? L" TargetMode=\"External\"" : L"") + L"/>"); + } + else + { + m_pWriter->WriteString(L"type().RelationType() + L"\" Target=\"" + + strMediaRelsPath + L"\"" + (mediaFile->IsExternal() ? L" TargetMode=\"External\"" : L"") + L"/>"); + } } } } } - m_mapImages.insert(std::pair(strImageRelsPath, oRelsGeneratorInfo)); + m_mapRelsImages.insert(std::pair(strImageRelsPath, oRelsGeneratorInfo)); return oRelsGeneratorInfo; } diff --git a/OOXML/Binary/Presentation/BinaryFileReaderWriter.h b/OOXML/Binary/Presentation/BinaryFileReaderWriter.h index 8d4338d794b..5a14f63d265 100644 --- a/OOXML/Binary/Presentation/BinaryFileReaderWriter.h +++ b/OOXML/Binary/Presentation/BinaryFileReaderWriter.h @@ -273,11 +273,13 @@ namespace NSBinPptxRW std::vector m_arMainTables; public: - _INT32 m_lCxCurShape; //emu - _INT32 m_lCyCurShape; + double m_dCxCurShape; //emu + double m_dCyCurShape; - _INT32 m_lXCurShape; - _INT32 m_lYCurShape; + double m_dXCurShape; + double m_dYCurShape; + + bool m_bInGroup = false; BYTE* GetBuffer(); virtual _UINT32 GetPosition(); @@ -468,7 +470,7 @@ namespace NSBinPptxRW { private: NSStringUtils::CStringBuilder* m_pWriter; - std::map m_mapImages; + std::map m_mapRelsImages; std::map m_mapLinks; public: unsigned int m_lNextRelsID; @@ -533,6 +535,7 @@ namespace NSBinPptxRW _INT32 m_nCountCharts = 1; _INT32 m_nCountDiagram = 1; _INT32 m_nCountActiveX = 1; + _INT32 m_nThemeOverrideCount = 1; BinDocxRW::CDocxSerializer* m_pMainDocument; int m_nDocumentType; diff --git a/OOXML/Binary/Presentation/Converter.cpp b/OOXML/Binary/Presentation/Converter.cpp index 9d7698deec8..e63dbeeceac 100644 --- a/OOXML/Binary/Presentation/Converter.cpp +++ b/OOXML/Binary/Presentation/Converter.cpp @@ -254,7 +254,7 @@ namespace PPTX2EditorAdvanced oBinaryWriter.WriteULONG(0); // App - smart_ptr app = oFolder.Get(OOX::FileTypes::App).smart_dynamic_cast(); + smart_ptr app = oFolder.Get(OOX::FileTypes::App).smart_dynamic_cast(); if (app.is_init()) { oBinaryWriter.StartMainRecord(NSBinPptxRW::NSMainTables::App); @@ -262,7 +262,7 @@ namespace PPTX2EditorAdvanced } // Core - smart_ptr core = oFolder.Get(OOX::FileTypes::Core).smart_dynamic_cast(); + smart_ptr core = oFolder.Get(OOX::FileTypes::Core).smart_dynamic_cast(); if (core.is_init()) { oBinaryWriter.StartMainRecord(NSBinPptxRW::NSMainTables::Core); diff --git a/OOXML/Binary/Presentation/PPTXWriter.cpp b/OOXML/Binary/Presentation/PPTXWriter.cpp index 2d9fd164ffc..27a937c5576 100644 --- a/OOXML/Binary/Presentation/PPTXWriter.cpp +++ b/OOXML/Binary/Presentation/PPTXWriter.cpp @@ -57,6 +57,10 @@ namespace NSBinPptxRW CPPTXWriter::~CPPTXWriter() { } + bool CPPTXWriter::GetMacroEnabled() + { + return m_oPresentation.m_bMacroEnabled; + } void CPPTXWriter::Init(std::wstring strFolder, bool bMacro) { m_strDstFolder = strFolder; @@ -1105,7 +1109,7 @@ namespace NSBinPptxRW } void CPPTXWriter::SetRequiredDefaultsApp() { - m_oApp.AppVersion.reset(NULL); + m_oApp.m_sAppVersion.reset(NULL); std::wstring sApplication = NSSystemUtils::GetEnvVariable(NSSystemUtils::gc_EnvApplicationName); if (sApplication.empty()) sApplication = NSSystemUtils::gc_EnvApplicationNameDefault; @@ -1113,20 +1117,20 @@ namespace NSBinPptxRW std::string s = VALUE2STR(INTVER); sApplication += L"/" + std::wstring(s.begin(), s.end()); #endif - m_oApp.Application = sApplication; + m_oApp.m_sApplication = sApplication; } void CPPTXWriter::CreateDefaultApp() { - m_oApp.TotalTime = 0; - m_oApp.Words = 0; + m_oApp.m_nTotalTime = 0; + m_oApp.m_nWords = 0; SetRequiredDefaultsApp(); - m_oApp.PresentationFormat = L"On-screen Show (4:3)"; - m_oApp.Paragraphs = 0; - m_oApp.Slides = (int)m_arSlides.size(); - m_oApp.Notes = (int)m_arSlides.size(); - m_oApp.HiddenSlides = 0; - m_oApp.MMClips = 2; - m_oApp.ScaleCrop = false; + m_oApp.m_sPresentationForm = L"On-screen Show (4:3)"; + m_oApp.m_nParagraphs = 0; + m_oApp.m_nSlides = (int)m_arSlides.size(); + m_oApp.m_nNotes = (int)m_arSlides.size(); + m_oApp.m_nHiddenSlides = 0; + m_oApp.m_nMMClips = 2; + m_oApp.m_bScaleCrop = false; int nCountThemes = (int)m_arSlideMasters.size(); int nCountSlides = (int)m_arSlides.size(); @@ -1158,35 +1162,35 @@ namespace NSBinPptxRW m_oApp.TitlesOfParts[nCountThemes + i].m_title = s; } - m_oApp.LinksUpToDate = false; - m_oApp.SharedDoc = false; - m_oApp.HyperlinksChanged = false; + m_oApp.m_bLinksUpToDate = false; + m_oApp.m_bSharedDoc = false; + m_oApp.m_bHyperlinksChanged = false; } void CPPTXWriter::SetRequiredDefaultsCore() { - if (!m_oCore.creator.IsInit()) + if (!m_oCore.m_sCreator.IsInit()) { std::wstring sCreator = NSSystemUtils::GetEnvVariable(NSSystemUtils::gc_EnvCreator); if (!sCreator.empty()) - m_oCore.creator = sCreator; + m_oCore.m_sCreator = sCreator; } - if (!m_oCore.created.IsInit()) + if (!m_oCore.m_sCreated.IsInit()) { std::wstring sCreated = NSSystemUtils::GetEnvVariable(NSSystemUtils::gc_EnvCreated); if (!sCreated.empty()) - m_oCore.created = sCreated; + m_oCore.m_sCreated = sCreated; } std::wstring sLastModifiedBy = NSSystemUtils::GetEnvVariable(NSSystemUtils::gc_EnvLastModifiedBy); if (!sLastModifiedBy.empty()) - m_oCore.lastModifiedBy = sLastModifiedBy; + m_oCore.m_sLastModifiedBy = sLastModifiedBy; std::wstring sModified = NSSystemUtils::GetEnvVariable(NSSystemUtils::gc_EnvModified); if (!sModified.empty()) - m_oCore.modified = sModified; + m_oCore.m_sModified = sModified; } void CPPTXWriter::CreateDefaultCore() { // m_oCore.creator = _T(""); - m_oCore.lastModifiedBy = _T(""); + m_oCore.m_sLastModifiedBy = _T(""); } void CPPTXWriter::CreateDefaultViewProps() { diff --git a/OOXML/Binary/Presentation/PPTXWriter.h b/OOXML/Binary/Presentation/PPTXWriter.h index 51194a45a52..02429183f98 100644 --- a/OOXML/Binary/Presentation/PPTXWriter.h +++ b/OOXML/Binary/Presentation/PPTXWriter.h @@ -72,8 +72,8 @@ namespace NSBinPptxRW PPTX::Presentation m_oPresentation; PPTX::TableStyles m_oTableStyles; OOX::CVmlDrawing m_oVmlDrawing; - PPTX::App m_oApp; - PPTX::Core m_oCore; + OOX::CApp m_oApp; + OOX::CCore m_oCore; nullable m_oCustomProperties; PPTX::ViewProps m_oViewProps; PPTX::PresProps m_oPresProps; @@ -88,10 +88,13 @@ namespace NSBinPptxRW void Init(std::wstring strFolder, bool bMacro = false); void OpenPPTY(BYTE* pBuffer, int len, std::wstring srcFolder, std::wstring strThemesFolder); void ReadMasterInfo(LONG nIndexMaster); + void SetRequiredDefaultsApp(); - void CreateDefaultApp(); void SetRequiredDefaultsCore(); + bool GetMacroEnabled(); + + void CreateDefaultApp(); void CreateDefaultCore(); void CreateDefaultViewProps(); void CreateDefaultTableStyles(); diff --git a/OOXML/Binary/Presentation/imagemanager.cpp b/OOXML/Binary/Presentation/imagemanager.cpp index b058280f4af..d5013622143 100644 --- a/OOXML/Binary/Presentation/imagemanager.cpp +++ b/OOXML/Binary/Presentation/imagemanager.cpp @@ -47,12 +47,6 @@ #include "../../Base/Unit.h" -// как все протестируем - уберем -#define SUPPORT_OLD_SVG_CONVERTATION -#ifdef SUPPORT_OLD_SVG_CONVERTATION -#include "../../../HtmlRenderer/include/ASCSVGWriter.h" -#endif - namespace NSShapeImageGen { const long c_nMaxImageSize = 2000; @@ -527,10 +521,11 @@ namespace NSShapeImageGen CDirectory::CopyFile(strFileName, pathSaveItem.GetPath()); ::MetaFile::IMetaFile* pMetafile = MetaFile::Create(m_pFontManager->GetApplication()); + if (pMetafile->LoadFromFile(strFileName.c_str())) { // пробуем сохранить в svg напрямую из метафайлов - std::wstring sInternalSvg = pMetafile->ConvertToSvg(); + std::wstring sInternalSvg = pMetafile->ConvertToSvg(lWidth, lHeight); if (!sInternalSvg.empty()) { @@ -544,80 +539,8 @@ namespace NSShapeImageGen return oInfo; } - double x = 0, y = 0, w = 0, h = 0; - pMetafile->GetBounds(&x, &y, &w, &h); - - // ограничиваем размеры - int nMaxSize = 1000; - int nMinSize = 10; - double dKoef = (double)nMaxSize / ((w >= h) ? w : h); - - int nPixW = (int)(dKoef * w + 0.5); - int nPixH = (int)(dKoef * h + 0.5); - - #ifdef SUPPORT_OLD_SVG_CONVERTATION - // пробуем сохранить в svg. большие/сложные файлы - // сохраняем в растр - NSHtmlRenderer::CASCSVGWriter oWriterSVG; - oWriterSVG.SetFontManager(m_pFontManager); - oWriterSVG.put_Width(nPixW); - oWriterSVG.put_Height(nPixH); - - bool bRes = true; - try - { - bRes = pMetafile->DrawOnRenderer(&oWriterSVG, 0, 0, nPixW, nPixH); - } - catch (...) - { - bRes = false; - } - - if (bRes) - { - bool bIsComplex = false; - - // растровые - сложные - oWriterSVG.IsRaster(&bIsComplex); - - if (!bIsComplex) - { - LONG lSvgDataSize = 0; - oWriterSVG.GetSVGDataSize(&lSvgDataSize); - - // больше 5 метров - сложные - bIsComplex = (lSvgDataSize > 5 * 1024 * 1024); - } - - if (!bIsComplex) - { - oInfo.m_eType = itSVG; - - oWriterSVG.SaveFile(strSaveItemWE + L".svg"); - m_mapMediaFiles.insert(std::make_pair(sMapKey, oInfo)); - - RELEASEOBJECT(pMetafile); - return oInfo; - } - } - #endif - - // не смогли (или не захотели? (SUPPORT_OLD_SVG_CONVERTATION)) сконвертировать в svg. + // не смогли сконвертировать в svg. // пробуем в png - if (lWidth <= 0 || lHeight <= 0) - { - // ограничиваем размеры в растре. - if ((nMinSize <= w && w <= nMaxSize) && (nMinSize <= h && h <= nMaxSize)) - { - lWidth = -1; - lHeight = -1; - } - else - { - lWidth = nPixW; - lHeight = nPixH; - } - } std::wstring strSaveItem = strSaveItemWE + L".png"; pMetafile->ConvertToRaster(strSaveItem.c_str(), 4 /*CXIMAGE_FORMAT_PNG*/, lWidth, lHeight); diff --git a/OOXML/Binary/Sheets/Common/BinReaderWriterDefines.h b/OOXML/Binary/Sheets/Common/BinReaderWriterDefines.h index f720753505c..1b01b39012c 100644 --- a/OOXML/Binary/Sheets/Common/BinReaderWriterDefines.h +++ b/OOXML/Binary/Sheets/Common/BinReaderWriterDefines.h @@ -47,9 +47,9 @@ namespace BinXlsxRW namespace c_oFileTypes{enum c_oFileTypes { XLSX = 1, - CSV = 2, - JSON = 3, - XLSB = 4 + CSV = 2, + JSON = 3, + XLSB = 4 };} @@ -107,7 +107,9 @@ namespace BinXlsxRW CellStyles = 15, CellStyle = 16, SlicerStyles = 17, - ExtDxfs = 18 + ExtDxfs = 18, + TimelineStyles = 19 + };} namespace c_oSerBorderTypes{enum c_oSerBorderTypes { @@ -233,7 +235,10 @@ namespace BinXlsxRW ExternalFileKey = 23, ExternalInstanceId = 24, FileSharing = 25, - ExternalLinksAutoRefresh = 26 + ExternalLinksAutoRefresh = 26, + TimelineCaches = 27, + TimelineCache = 28, + Metadata = 29 };} namespace c_oSerWorkbookProtection {enum c_oSerWorkbookProtection{ AlgorithmName = 0, @@ -360,7 +365,19 @@ namespace BinXlsxRW };} namespace c_oSerWorkbookViewTypes{enum c_oSerWorkbookViewTypes { - ActiveTab = 0 + ActiveTab = 0, + AutoFilterDateGrouping = 1, + FirstSheet = 2, + Minimized = 3, + ShowHorizontalScroll = 4, + ShowSheetTabs = 5, + ShowVerticalScroll = 6, + TabRatio = 7, + Visibility = 8, + WindowHeight = 9, + WindowWidth = 10, + XWindow = 11, + YWindow = 12 };} namespace c_oSerDefinedNameTypes{enum c_oSerDefinedNameTypes { @@ -435,7 +452,11 @@ namespace BinXlsxRW CellWatches = 44, CellWatch = 45, CellWatchR = 46, - UserProtectedRanges = 47 + UserProtectedRanges = 47, + TimelinesList = 48, + Timelines = 49, + Timeline = 50, + };} namespace c_oSerWorksheetProtection {enum c_oSerWorksheetPropTypes { @@ -578,7 +599,9 @@ namespace BinXlsxRW Formula = 4, RefRowCol = 5, ValueText = 6, - ValueCache = 7 + ValueCache = 7, + CellMetadata = 8, + ValueMetadata = 9 };} namespace c_oSerFormulaTypes{enum c_oSerFormulaTypes { @@ -654,6 +677,172 @@ namespace BinXlsxRW ChildChain = 5, NewThread = 6 };} +//------------------------------------------------------------------------------------------------------------------------------ + namespace c_oSer_Timeline {enum c_oSer_Timeline + { + Name = 0, + Caption = 1, + Uid = 2, + Cache = 3, + ShowHeader = 4, + ShowTimeLevel = 5, + ShowSelectionLabel = 6, + ShowHorizontalScrollbar = 7, + Level = 8, + SelectionLevel = 9, + ScrollPosition = 10, + Style = 11 + };} + namespace c_oSer_TimelineCache {enum c_oSer_TimelineCache + { + Name = 0, + SourceName = 1, + Uid = 2, + PivotTables = 3, + PivotTable = 4, + State = 5, + PivotFilter = 6 + };} + namespace c_oSer_TimelineState {enum c_oSer_TimelineState + { + Name = 0, + FilterState = 1, + PivotCacheId = 2, + MinimalRefreshVersion = 3, + LastRefreshVersion = 4, + FilterType = 5, + Selection = 6, + Bounds = 7 + };} + namespace c_oSer_TimelinePivotFilter {enum c_oSer_TimelinePivotFilter + { + Name = 0, + Description = 1, + UseWholeDay = 2, + Id = 3, + Fld = 4, + AutoFilter = 5 + };} + namespace c_oSer_TimelineRange {enum c_oSer_TimelineRange + { + StartDate = 0, + EndDate = 1 + };} + namespace c_oSer_TimelineCachePivotTable {enum c_oSer_TimelineCachePivotTable + { + Name = 0, + TabId = 1 + };} +//------------------------------------------------------------------------------------------------------------------------------ + namespace c_oSer_Metadata { enum c_oSer_Metadata + { + MetadataTypes = 0, + MetadataStrings = 1, + MdxMetadata = 2, + CellMetadata = 3, + ValueMetadata = 4, + FutureMetadata = 5, + };} + namespace c_oSer_MetadataType { enum c_oSer_MetadataType + { + MetadataType = 0, + Name = 1, + MinSupportedVersion = 2, + GhostRow = 3, + GhostCol = 4, + Edit = 5, + Delete = 6, + Copy = 7, + PasteAll = 8, + PasteFormulas = 9, + PasteValues = 10, + PasteFormats = 11, + PasteComments = 12, + PasteDataValidation = 13, + PasteBorders = 14, + PasteColWidths = 15, + PasteNumberFormats = 16, + Merge = 17, + SplitFirst = 18, + SplitAll = 19, + RowColShift = 30, + ClearAll = 21, + ClearFormats = 22, + ClearContents = 23, + ClearComments = 24, + Assign = 25, + Coerce = 26, + CellMeta = 27, + };} + namespace c_oSer_MetadataString {enum c_oSer_MetadataString + { + MetadataString = 0, + + };} + namespace c_oSer_MetadataBlock {enum c_oSer_MetadataBlock + { + MetadataBlock = 0, + MetadataRecord = 1, + MetadataRecordType = 2, + MetadataRecordValue = 3, + };} + namespace c_oSer_FutureMetadataBlock {enum c_oSer_FutureMetadataBlock + { + Name = 0, + FutureMetadataBlock = 1, + RichValueBlock = 2, + DynamicArrayProperties = 3, + DynamicArray = 4, + CollapsedArray = 5 + };} + namespace c_oSer_MdxMetadata {enum c_oSer_MdxMetadata + { + Mdx = 0, + NameIndex = 1, + FunctionTag = 2, + MdxTuple = 3, + MdxSet = 4, + MdxKPI = 5, + MdxMemeberProp = 6 + };} + namespace c_oSer_MetadataMdxTuple { enum c_oSer_MetadataMdxTuple + { + IndexCount = 0, + CultureCurrency = 1, + StringIndex = 2, + NumFmtIndex = 3, + BackColor = 4, + ForeColor = 5, + Italic = 6, + Underline = 7, + Strike = 8, + Bold = 9, + MetadataStringIndex = 10 + };} + namespace c_oSer_MetadataStringIndex {enum c_oSer_MetadataStringIndex + { + StringIsSet = 0, + IndexValue = 1 + };} + namespace c_oSer_MetadataMdxSet {enum c_oSer_MetadataMdxSet + { + Count = 0, + Index = 1, + SortOrder = 2, + MetadataStringIndex = 3 + };} + namespace c_oSer_MetadataMdxKPI {enum c_oSer_MetadataMdxKPI + { + NameIndex = 0, + Index = 1, + Property = 2 + };} + namespace c_oSer_MetadataMemberProperty {enum c_oSer_MetadataMemberProperty + { + NameIndex = 0, + Index = 1 + };} +//------------------------------------------------------------------------------------------------------------------------------ namespace c_oSerCustoms {enum c_oSerCustoms { Custom = 0, @@ -1015,6 +1204,15 @@ namespace BinXlsxRW TableStyles = 2, TableStyle = 3 };} + namespace c_oSer_TimelineStyles {enum c_oSer_TimelineStyles + { + DefaultTimelineStyle = 0, + TimelineStyle = 2, + TimelineStyleName = 3, + TimelineStyleElement = 4, + TimelineStyleElementType = 5, + TimelineStyleElementDxfId = 6 + };} namespace c_oSer_TableStyle{enum c_oSer_TableStyle { Name = 0, @@ -1169,12 +1367,14 @@ namespace BinXlsxRW Name = 2, Text = 3, User = 4, - UsersGroup = 5 + UsersGroup = 5, + Type = 6 };} namespace c_oSer_UserProtectedRangeDesc {enum c_oSer_UserProtectedRangeDesc { Id = 0, - Name = 1 + Name = 1, + Type = 2 };} namespace c_oSer_DataValidation{enum c_oSer_DataValidation { @@ -1197,7 +1397,8 @@ namespace BinXlsxRW ShowInputMessage = 16, SqRef = 17, Formula1 = 18, - Formula2 = 19 + Formula2 = 19, + List = 20 };} namespace c_oSer_SheetView{enum c_oSer_SheetView { @@ -1342,7 +1543,8 @@ namespace BinXlsxRW AbsoluteUrl = 19, RelativeUrl = 20, ExternalAlternateUrlsDriveId = 21, - ExternalAlternateUrlsItemId = 22 + ExternalAlternateUrlsItemId = 22, + ValueMetadata = 23 };} namespace c_oSer_OleLinkTypes{enum c_oSer_OleLinkTypes { diff --git a/OOXML/Binary/Sheets/Common/Common.cpp b/OOXML/Binary/Sheets/Common/Common.cpp index e780c7f4b5d..5b62450540a 100644 --- a/OOXML/Binary/Sheets/Common/Common.cpp +++ b/OOXML/Binary/Sheets/Common/Common.cpp @@ -110,16 +110,18 @@ namespace SerializeCommon return sSourcePath.substr(0, nIndex + 1) + sTargetExt; return sSourcePath; } - void ReadFileType(const std::wstring& sXMLOptions, BYTE& result, UINT& nCodePage, std::wstring& sDelimiter, BYTE& cSaveFileType) + void ReadFileType(const std::wstring& sXMLOptions, BYTE& result, UINT& nCodePage, std::wstring& sDelimiter, BYTE& cSaveFileType, _INT32& Lcid) { result = BinXlsxRW::c_oFileTypes::XLSX; nCodePage = 46; //default 46 временно CP_UTF8 sDelimiter = L";"; // default cSaveFileType = BinXlsxRW::c_oFileTypes::XLSX;// default + Lcid = -1;// default nullable fileType; nullable codePage; nullable saveFileType; + nullable LcidParam; nullable delimiter; // Read options @@ -141,6 +143,7 @@ namespace SerializeCommon WritingElement_ReadAttributes_Read_if (oReader, L"fileType", fileType) WritingElement_ReadAttributes_Read_else_if (oReader, L"codePage", codePage) WritingElement_ReadAttributes_Read_else_if (oReader, L"delimiter", delimiter) + WritingElement_ReadAttributes_Read_else_if (oReader, L"Lcid", LcidParam) WritingElement_ReadAttributes_Read_else_if (oReader, L"saveFileType", saveFileType) WritingElement_ReadAttributes_End(oReader) @@ -150,6 +153,8 @@ namespace SerializeCommon nCodePage = (UINT)codePage->GetValue(); if (saveFileType.IsInit()) cSaveFileType = (BYTE)saveFileType->GetValue(); + if(LcidParam.IsInit()) + Lcid = LcidParam->GetValue(); if (delimiter.IsInit()) { sDelimiter = delimiter.get(); diff --git a/OOXML/Binary/Sheets/Common/Common.h b/OOXML/Binary/Sheets/Common/Common.h index c6156bef88b..d1216adabff 100644 --- a/OOXML/Binary/Sheets/Common/Common.h +++ b/OOXML/Binary/Sheets/Common/Common.h @@ -70,6 +70,6 @@ namespace SerializeCommon ~CommentData(); }; - void ReadFileType(const std::wstring& sXMLOptions, BYTE& result, UINT& nCodePage, std::wstring& wcDelimiter, BYTE& saveFileType); + void ReadFileType(const std::wstring& sXMLOptions, BYTE& result, UINT& nCodePage, std::wstring& wcDelimiter, BYTE& saveFileType, _INT32& Lcid); } diff --git a/OOXML/Binary/Sheets/Reader/BinaryWriter.cpp b/OOXML/Binary/Sheets/Reader/BinaryWriter.cpp index b60b9c3ec3d..13852b9d8df 100644 --- a/OOXML/Binary/Sheets/Reader/BinaryWriter.cpp +++ b/OOXML/Binary/Sheets/Reader/BinaryWriter.cpp @@ -38,8 +38,6 @@ #include "../../../../Common/OfficeFileErrorDescription.h" #include "../../Presentation/FontCutter.h" -#include "../../../PPTXFormat/App.h" -#include "../../../PPTXFormat/Core.h" #include "../../../PPTXFormat/Logic/HeadingVariant.h" #include "../../../XlsxFormat/Xlsx.h" @@ -70,8 +68,12 @@ #include "../../../XlsxFormat/Styles/CellStyles.h" #include "../../../XlsxFormat/Styles/dxf.h" #include "../../../XlsxFormat/Styles/TableStyles.h" +#include "../../../XlsxFormat/Timelines/Timeline.h" +#include "../../../XlsxFormat/Workbook/Metadata.h" #include "../../../../DesktopEditor/common/Directory.h" +#include "../../../../Common/OfficeFileFormatChecker.h" +#include "../../../../OfficeUtils/src/OfficeUtils.h" namespace BinXlsxRW { @@ -1129,13 +1131,71 @@ void BinaryStyleTableWriter::WriteStylesContent(OOX::Spreadsheet::CStyles& style m_oBcw.m_oStream.WriteRecord2(0, pExt->m_oSlicerStyles); m_oBcw.WriteItemWithLengthEnd(nCurPos); } + else if (pExt->m_oTimelineStyles.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerStylesTypes::TimelineStyles); + WriteTimelineStyles(pExt->m_oTimelineStyles.GetPointer()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } } } } +void BinaryStyleTableWriter::WriteTimelineStyles(OOX::Spreadsheet::CTimelineStyles* pTimelineStyles) +{ + if (!pTimelineStyles) return; + int nCurPos = 0; + if (pTimelineStyles->m_oDefaultTimelineStyle.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_TimelineStyles::DefaultTimelineStyle); + m_oBcw.m_oStream.WriteStringW3(*pTimelineStyles->m_oDefaultTimelineStyle); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + for (size_t i = 0; i < pTimelineStyles->m_arrItems.size(); ++i) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_TimelineStyles::TimelineStyle); + WriteTimelineStyle(pTimelineStyles->m_arrItems[i]); + m_oBcw.WriteItemEnd(nCurPos); + } +} +void BinaryStyleTableWriter::WriteTimelineStyle(OOX::Spreadsheet::CTimelineStyle* pTimelineStyle) +{ + if (!pTimelineStyle) return; + + int nCurPos = 0; + if (pTimelineStyle->m_oName.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_TimelineStyles::TimelineStyleName); + m_oBcw.m_oStream.WriteStringW3(*pTimelineStyle->m_oName); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + for (size_t i = 0; i < pTimelineStyle->m_arrItems.size(); ++i) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_TimelineStyles::TimelineStyleElement); + WriteTimelineStyleElement(pTimelineStyle->m_arrItems[i]); + m_oBcw.WriteItemEnd(nCurPos); + } +} +void BinaryStyleTableWriter::WriteTimelineStyleElement(OOX::Spreadsheet::CTimelineStyleElement* pTimelineStyleElement) +{ + if (!pTimelineStyleElement) return; + + if (pTimelineStyleElement->m_oType.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_TimelineStyles::TimelineStyleElementType); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBYTE((BYTE)pTimelineStyleElement->m_oType->GetValue()); + } + if (pTimelineStyleElement->m_oDxfId.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_TimelineStyles::TimelineStyleElementDxfId); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Long); + m_oBcw.m_oStream.WriteLONG(*pTimelineStyleElement->m_oDxfId); + } +} void BinaryStyleTableWriter::WriteBorders(const OOX::Spreadsheet::CBorders& borders, OOX::Spreadsheet::CIndexedColors* pIndexedColors, PPTX::Theme* pTheme) { int nCurPos = 0; - for(size_t i = 0, length = borders.m_arrItems.size(); i < length; ++i) + for (size_t i = 0, length = borders.m_arrItems.size(); i < length; ++i) { OOX::Spreadsheet::CBorder* pBorder = borders.m_arrItems[i]; nCurPos = m_oBcw.WriteItemStart(c_oSerStylesTypes::Border); @@ -2127,6 +2187,12 @@ void BinaryWorkbookTableWriter::WriteWorkbook(OOX::Spreadsheet::CWorkbook& workb m_oBcw.m_oStream.WriteBOOL(*pExt->m_oExternalLinksAutoRefresh); m_oBcw.WriteItemWithLengthEnd(nCurPos); } + else if (pExt->m_oTimelineCacheRefs.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerWorkbookTypes::TimelineCaches); + WriteTimelineCaches(workbook, pExt->m_oTimelineCacheRefs.get()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } } } //Write VbaProject @@ -2198,6 +2264,14 @@ void BinaryWorkbookTableWriter::WriteWorkbook(OOX::Spreadsheet::CWorkbook& workb m_oBcw.m_oStream.WriteStringW3(*workbook.m_oOleSize); m_oBcw.WriteItemWithLengthEnd(nCurPos); } + pFile = workbook.Find(OOX::Spreadsheet::FileTypes::Metadata); + OOX::Spreadsheet::CMetadataFile* pMetadataFile = dynamic_cast(pFile.GetPointer()); + if ((pMetadataFile) && (pMetadataFile->m_oMetadata.IsInit())) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerWorkbookTypes::Metadata); + WriteMetadata(pMetadataFile->m_oMetadata.GetPointer()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } } void BinaryWorkbookTableWriter::WriteFileSharing(const OOX::Spreadsheet::CFileSharing& fileSharing) { @@ -2321,7 +2395,7 @@ void BinaryWorkbookTableWriter::WriteWorkbookPr(const OOX::Spreadsheet::CWorkboo { m_oBcw.m_oStream.WriteBYTE(c_oSerWorkbookPrTypes::UpdateLinks); m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); - m_oBcw.m_oStream.WriteBOOL(workbookPr.m_oUpdateLinks->GetValue()); + m_oBcw.m_oStream.WriteBYTE(workbookPr.m_oUpdateLinks->GetValue()); } } void BinaryWorkbookTableWriter::WriteConnectionTextFields(const OOX::Spreadsheet::CTextFields& textFields) @@ -2366,12 +2440,84 @@ void BinaryWorkbookTableWriter::WriteBookViews(const OOX::Spreadsheet::CBookView void BinaryWorkbookTableWriter::WriteWorkbookView(const OOX::Spreadsheet::CWorkbookView& workbookView) { //ActiveTab - if(workbookView.m_oActiveTab.IsInit()) + if (workbookView.m_oActiveTab.IsInit()) { m_oBcw.m_oStream.WriteBYTE(c_oSerWorkbookViewTypes::ActiveTab); m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Long); m_oBcw.m_oStream.WriteLONG(workbookView.m_oActiveTab->GetValue()); } + if (workbookView.m_oAutoFilterDateGrouping.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerWorkbookViewTypes::AutoFilterDateGrouping); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(workbookView.m_oAutoFilterDateGrouping->ToBool()); + } + if (workbookView.m_oFirstSheet.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerWorkbookViewTypes::FirstSheet); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Long); + m_oBcw.m_oStream.WriteLONG(workbookView.m_oFirstSheet->GetValue()); + } + if (workbookView.m_oMinimized.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerWorkbookViewTypes::Minimized); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(workbookView.m_oMinimized->ToBool()); + } + if (workbookView.m_oShowHorizontalScroll.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerWorkbookViewTypes::ShowHorizontalScroll); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(workbookView.m_oShowHorizontalScroll->ToBool()); + } + if (workbookView.m_oShowSheetTabs.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerWorkbookViewTypes::ShowSheetTabs); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(workbookView.m_oShowSheetTabs->ToBool()); + } + if (workbookView.m_oShowVerticalScroll.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerWorkbookViewTypes::ShowVerticalScroll); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(workbookView.m_oShowVerticalScroll->ToBool()); + } + if (workbookView.m_oTabRatio.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerWorkbookViewTypes::TabRatio); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Long); + m_oBcw.m_oStream.WriteLONG(workbookView.m_oTabRatio->GetValue()); + } + if (workbookView.m_oVisibility.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerWorkbookViewTypes::Visibility); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBYTE(workbookView.m_oVisibility->GetValue()); + } + if (workbookView.m_oWindowHeight.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerWorkbookViewTypes::WindowHeight); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Long); + m_oBcw.m_oStream.WriteLONG(workbookView.m_oWindowHeight->GetValue()); + } + if (workbookView.m_oWindowWidth.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerWorkbookViewTypes::WindowWidth); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Long); + m_oBcw.m_oStream.WriteLONG(workbookView.m_oWindowWidth->GetValue()); + } + if (workbookView.m_oXWindow.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerWorkbookViewTypes::XWindow); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Long); + m_oBcw.m_oStream.WriteLONG(workbookView.m_oXWindow->GetValue()); + } + if (workbookView.m_oYWindow.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerWorkbookViewTypes::YWindow); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Long); + m_oBcw.m_oStream.WriteLONG(workbookView.m_oYWindow->GetValue()); + } } void BinaryWorkbookTableWriter::WriteDefinedNames(const OOX::Spreadsheet::CDefinedNames& definedNames) { @@ -2957,8 +3103,11 @@ void BinaryWorkbookTableWriter::WriteExternalReferences(const OOX::Spreadsheet:: smart_ptr pFile = pExternalLink->Find(OOX::RId(pExternalLink->m_oOleLink->m_oRid.get().GetValue())); if (pFile.IsInit() && OOX::FileTypes::OleObject == pFile->type()) { - OOX::OleObject* pLinkFile = static_cast(pFile.operator ->()); - sLink = pLinkFile->filename().GetPath(); + smart_ptr pLinkFile = pFile.smart_dynamic_cast(); + if (pLinkFile.IsInit()) + { + sLink = pLinkFile->filename().GetPath(); + } } } if (!sLink.empty()) @@ -3170,6 +3319,12 @@ void BinaryWorkbookTableWriter::WriteExternalCell(const OOX::Spreadsheet::CExter m_oBcw.m_oStream.WriteStringW3(cell.m_oValue->ToString()); m_oBcw.WriteItemWithLengthEnd(nCurPos); } + if (cell.m_oValueMetadata.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_ExternalLinkTypes::ValueMetadata); + m_oBcw.m_oStream.WriteULONG(*cell.m_oValueMetadata); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } } void BinaryWorkbookTableWriter::WriteOleLink(const OOX::Spreadsheet::COleLink& oleLink, const std::wstring& sLink) { @@ -3196,169 +3351,926 @@ void BinaryWorkbookTableWriter::WriteOleLink(const OOX::Spreadsheet::COleLink& o } void BinaryWorkbookTableWriter::WriteOleItem(const OOX::Spreadsheet::COleItem& oleItem) { - int nCurPos = 0; - if (oleItem.m_oName.IsInit()) + int nCurPos = 0; + if (oleItem.m_oName.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_OleLinkTypes::Name); + m_oBcw.m_oStream.WriteStringW3(oleItem.m_oName.get()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (oleItem.m_oIcon.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_OleLinkTypes::Icon); + m_oBcw.m_oStream.WriteBOOL(oleItem.m_oIcon->ToBool()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (oleItem.m_oAdvise.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_OleLinkTypes::Advise); + m_oBcw.m_oStream.WriteBOOL(oleItem.m_oAdvise->ToBool()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (oleItem.m_oPreferPic.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_OleLinkTypes::PreferPic); + m_oBcw.m_oStream.WriteBOOL(oleItem.m_oPreferPic->ToBool()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +} +void BinaryWorkbookTableWriter::WriteDdeLink(const OOX::Spreadsheet::CDdeLink& ddeLink) +{ + int nCurPos = 0; + if (ddeLink.m_oDdeService.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_DdeLinkTypes::DdeService); + m_oBcw.m_oStream.WriteStringW3(ddeLink.m_oDdeService.get()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (ddeLink.m_oDdeTopic.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_DdeLinkTypes::DdeTopic); + m_oBcw.m_oStream.WriteStringW3(ddeLink.m_oDdeTopic.get()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (ddeLink.m_oDdeItems.IsInit()) + { + for(size_t i = 0; i < ddeLink.m_oDdeItems->m_arrItems.size(); ++i) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_DdeLinkTypes::DdeItem); + WriteDdeItem(*ddeLink.m_oDdeItems->m_arrItems[i]); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + } +} +void BinaryWorkbookTableWriter::WriteDdeItem(const OOX::Spreadsheet::CDdeItem& ddeItem) +{ + int nCurPos = 0; + if (ddeItem.m_oName.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_DdeLinkTypes::Name); + m_oBcw.m_oStream.WriteStringW3(ddeItem.m_oName.get()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (ddeItem.m_oOle.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_DdeLinkTypes::Ole); + m_oBcw.m_oStream.WriteBOOL(ddeItem.m_oOle->ToBool()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (ddeItem.m_oAdvise.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_DdeLinkTypes::Advise); + m_oBcw.m_oStream.WriteBOOL(ddeItem.m_oAdvise->ToBool()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (ddeItem.m_oPreferPic.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_DdeLinkTypes::PreferPic); + m_oBcw.m_oStream.WriteBOOL(ddeItem.m_oPreferPic->ToBool()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (ddeItem.m_oDdeValues.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_DdeLinkTypes::DdeValues); + WriteDdeValues(ddeItem.m_oDdeValues.get()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +} +void BinaryWorkbookTableWriter::WriteDdeValues(const OOX::Spreadsheet::CDdeValues& ddeValues) +{ + int nCurPos = 0; + if (ddeValues.m_oRows.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_DdeLinkTypes::DdeValuesRows); + m_oBcw.m_oStream.WriteULONG(ddeValues.m_oRows->GetValue()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (ddeValues.m_oCols.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_DdeLinkTypes::DdeValuesCols); + m_oBcw.m_oStream.WriteULONG(ddeValues.m_oCols->GetValue()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + for(size_t i = 0; i < ddeValues.m_arrItems.size(); ++i) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_DdeLinkTypes::DdeValue); + WriteDdeValue(*ddeValues.m_arrItems[i]); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +} +void BinaryWorkbookTableWriter::WriteDdeValue(const OOX::Spreadsheet::CDdeValue& ddeValue) +{ + int nCurPos = 0; + if (ddeValue.m_oType.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_DdeLinkTypes::DdeValueType); + m_oBcw.m_oStream.WriteBYTE(ddeValue.m_oType->GetValue()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + for (size_t i = 0; i < ddeValue.m_arrItems.size(); ++i) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_DdeLinkTypes::DdeValueVal); + m_oBcw.m_oStream.WriteStringW3(ddeValue.m_arrItems[i]->ToString()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +} +void BinaryWorkbookTableWriter::WriteDefinedName(const OOX::Spreadsheet::CDefinedName& definedName) +{ + int nCurPos = 0; + //Name + if(definedName.m_oName.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerDefinedNameTypes::Name); + m_oBcw.m_oStream.WriteStringW(*definedName.m_oName); + } + //Ref + if(definedName.m_oRef.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerDefinedNameTypes::Ref); + m_oBcw.m_oStream.WriteStringW(*definedName.m_oRef); + } + //LocalSheetId + if(definedName.m_oLocalSheetId.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerDefinedNameTypes::LocalSheetId); + m_oBcw.m_oStream.WriteLONG(definedName.m_oLocalSheetId->GetValue()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + //Hidden + if(definedName.m_oHidden.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerDefinedNameTypes::Hidden); + m_oBcw.m_oStream.WriteBOOL(definedName.m_oHidden->ToBool()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + //Comment + if (definedName.m_oComment.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerDefinedNameTypes::Comment); + m_oBcw.m_oStream.WriteStringW(*definedName.m_oComment); + } +} +void BinaryWorkbookTableWriter::WriteTimelineCaches(OOX::Spreadsheet::CWorkbook& workbook, const OOX::Spreadsheet::CTimelineCacheRefs& oTimelineCacheRefs) +{ + int nCurPos = 0; + for (size_t i = 0; i < oTimelineCacheRefs.m_arrItems.size(); ++i) + { + if (oTimelineCacheRefs.m_arrItems[i] && oTimelineCacheRefs.m_arrItems[i]->m_oRId.IsInit()) + { + smart_ptr pFile = workbook.Find(OOX::RId(oTimelineCacheRefs.m_arrItems[i]->m_oRId->GetValue())); + if (pFile.IsInit() && OOX::Spreadsheet::FileTypes::TimelineCache == pFile->type()) + { + OOX::Spreadsheet::CTimelineCacheFile* pTimelineCacheFile = static_cast(pFile.GetPointer()); + if (pTimelineCacheFile->m_oTimelineCacheDefinition.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerWorkbookTypes::TimelineCache); + WriteTimelineCache(pTimelineCacheFile->m_oTimelineCacheDefinition.GetPointer()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + } + } + } + +} +void BinaryWorkbookTableWriter::WriteTimelineCache(OOX::Spreadsheet::CTimelineCacheDefinition* pTimelineCache) +{ + if (!pTimelineCache) return; + + int nCurPos = 0; + if (pTimelineCache->m_oName.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_TimelineCache::Name); + m_oBcw.m_oStream.WriteStringW3(*pTimelineCache->m_oName); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pTimelineCache->m_oSourceName.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_TimelineCache::SourceName); + m_oBcw.m_oStream.WriteStringW3(*pTimelineCache->m_oSourceName); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pTimelineCache->m_oUid.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_TimelineCache::Uid); + m_oBcw.m_oStream.WriteStringW3(*pTimelineCache->m_oUid); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pTimelineCache->m_oPivotTables.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_TimelineCache::PivotTables); + WriteTimelineCachePivotTables(pTimelineCache->m_oPivotTables.GetPointer()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pTimelineCache->m_oPivotFilter.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_TimelineCache::PivotFilter); + WriteTimelinePivotFilter(pTimelineCache->m_oPivotFilter.GetPointer()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pTimelineCache->m_oState.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_TimelineCache::State); + WriteTimelineState(pTimelineCache->m_oState.GetPointer()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +} +void BinaryWorkbookTableWriter::WriteTimelineState(OOX::Spreadsheet::CTimelineState* pState) +{ + if (!pState) return; + + int nCurPos = 0; + if (pState->m_oName.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_TimelineState::Name); + m_oBcw.m_oStream.WriteStringW3(*pState->m_oName); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pState->m_oSingleRangeFilterState.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_TimelineState::FilterState); + m_oBcw.m_oStream.WriteBOOL(*pState->m_oSingleRangeFilterState); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pState->m_oPivotCacheId.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_TimelineState::PivotCacheId); + m_oBcw.m_oStream.WriteLONG(*pState->m_oPivotCacheId); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pState->m_oMinimalRefreshVersion.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_TimelineState::MinimalRefreshVersion); + m_oBcw.m_oStream.WriteLONG(*pState->m_oMinimalRefreshVersion); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pState->m_oLastRefreshVersion.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_TimelineState::LastRefreshVersion); + m_oBcw.m_oStream.WriteLONG(*pState->m_oLastRefreshVersion); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pState->m_oFilterType.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_TimelineState::FilterType); + m_oBcw.m_oStream.WriteStringW3(*pState->m_oFilterType); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pState->m_oSelection.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_TimelineState::Selection); + WriteTimelineRange(pState->m_oSelection.GetPointer()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pState->m_oBounds.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_TimelineState::Bounds); + WriteTimelineRange(pState->m_oBounds.GetPointer()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +} +void BinaryWorkbookTableWriter::WriteMetadata(OOX::Spreadsheet::CMetadata* pMetadata) +{ + if (!pMetadata) return; + + int nCurPos = 0; + if (pMetadata->m_oMetadataTypes.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_Metadata::MetadataTypes); + WriteMetadataTypes(pMetadata->m_oMetadataTypes.GetPointer()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadata->m_oMetadataTypes.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_Metadata::MetadataStrings); + WriteMetadataStrings(pMetadata->m_oMetadataStrings.GetPointer()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadata->m_oMdxMetadata.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_Metadata::MdxMetadata); + WriteMdxMetadata(pMetadata->m_oMdxMetadata.GetPointer()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadata->m_oCellMetadata.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_Metadata::CellMetadata); + WriteMetadataBlocks(pMetadata->m_oCellMetadata.GetPointer()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadata->m_oValueMetadata.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_Metadata::ValueMetadata); + WriteMetadataBlocks(pMetadata->m_oValueMetadata.GetPointer()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + for (size_t i = 0; i < pMetadata->m_arFutureMetadata.size(); ++i) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_Metadata::FutureMetadata); + WriteFutureMetadata(pMetadata->m_arFutureMetadata[i]); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +} +void BinaryWorkbookTableWriter::WriteMetadataTypes(OOX::Spreadsheet::CMetadataTypes* pMetadataTypes) +{ + if (!pMetadataTypes) return; + + for (size_t i = 0; i < pMetadataTypes->m_arrItems.size(); ++i) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataType::MetadataType); + WriteMetadataType(pMetadataTypes->m_arrItems[i]); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +} +void BinaryWorkbookTableWriter::WriteMetadataType(OOX::Spreadsheet::CMetadataType* pMetadataType) +{ + if (!pMetadataType) return; + + if (pMetadataType->m_oName.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataType::Name); + m_oBcw.m_oStream.WriteStringW3(*pMetadataType->m_oName); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadataType->m_oMinSupportedVersion.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataType::MinSupportedVersion); + m_oBcw.m_oStream.WriteULONG(*pMetadataType->m_oMinSupportedVersion); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadataType->m_oGhostRow.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataType::GhostRow); + m_oBcw.m_oStream.WriteBOOL(*pMetadataType->m_oGhostRow); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadataType->m_oGhostCol.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataType::GhostCol); + m_oBcw.m_oStream.WriteBOOL(*pMetadataType->m_oGhostCol); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadataType->m_oEdit.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataType::Edit); + m_oBcw.m_oStream.WriteBOOL(*pMetadataType->m_oEdit); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadataType->m_oDelete.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataType::Delete); + m_oBcw.m_oStream.WriteBOOL(*pMetadataType->m_oDelete); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadataType->m_oCopy.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataType::Copy); + m_oBcw.m_oStream.WriteBOOL(*pMetadataType->m_oCopy); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadataType->m_oPasteAll.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataType::PasteAll); + m_oBcw.m_oStream.WriteBOOL(*pMetadataType->m_oPasteAll); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadataType->m_oPasteFormulas.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataType::PasteFormulas); + m_oBcw.m_oStream.WriteBOOL(*pMetadataType->m_oPasteFormulas); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadataType->m_oPasteValues.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataType::PasteValues); + m_oBcw.m_oStream.WriteBOOL(*pMetadataType->m_oPasteValues); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadataType->m_oPasteFormats.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataType::PasteFormats); + m_oBcw.m_oStream.WriteBOOL(*pMetadataType->m_oPasteFormats); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadataType->m_oPasteComments.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataType::PasteComments); + m_oBcw.m_oStream.WriteBOOL(*pMetadataType->m_oPasteComments); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadataType->m_oPasteDataValidation.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataType::PasteDataValidation); + m_oBcw.m_oStream.WriteBOOL(*pMetadataType->m_oPasteDataValidation); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadataType->m_oPasteBorders.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataType::PasteBorders); + m_oBcw.m_oStream.WriteBOOL(*pMetadataType->m_oPasteBorders); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadataType->m_oPasteColWidths.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataType::PasteColWidths); + m_oBcw.m_oStream.WriteBOOL(*pMetadataType->m_oPasteColWidths); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadataType->m_oPasteNumberFormats.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataType::PasteNumberFormats); + m_oBcw.m_oStream.WriteBOOL(*pMetadataType->m_oPasteNumberFormats); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadataType->m_oMerge.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataType::Merge); + m_oBcw.m_oStream.WriteBOOL(*pMetadataType->m_oMerge); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadataType->m_oSplitFirst.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataType::SplitFirst); + m_oBcw.m_oStream.WriteBOOL(*pMetadataType->m_oSplitFirst); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadataType->m_oSplitAll.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataType::SplitAll); + m_oBcw.m_oStream.WriteBOOL(*pMetadataType->m_oSplitAll); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadataType->m_oRowColShift.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataType::RowColShift); + m_oBcw.m_oStream.WriteBOOL(*pMetadataType->m_oRowColShift); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadataType->m_oClearAll.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataType::ClearAll); + m_oBcw.m_oStream.WriteBOOL(*pMetadataType->m_oClearAll); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadataType->m_oClearFormats.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataType::ClearFormats); + m_oBcw.m_oStream.WriteBOOL(*pMetadataType->m_oClearFormats); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadataType->m_oClearContents.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataType::ClearContents); + m_oBcw.m_oStream.WriteBOOL(*pMetadataType->m_oClearContents); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadataType->m_oClearComments.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataType::ClearComments); + m_oBcw.m_oStream.WriteBOOL(*pMetadataType->m_oClearComments); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadataType->m_oAssign.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataType::Assign); + m_oBcw.m_oStream.WriteBOOL(*pMetadataType->m_oAssign); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadataType->m_oCoerce.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataType::Coerce); + m_oBcw.m_oStream.WriteBOOL(*pMetadataType->m_oCoerce); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadataType->m_oCellMeta.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataType::CellMeta); + m_oBcw.m_oStream.WriteBOOL(*pMetadataType->m_oCellMeta); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +} +void BinaryWorkbookTableWriter::WriteMetadataStrings(OOX::Spreadsheet::CMetadataStrings* pMetadataStrings) +{ + if (!pMetadataStrings) return; + + for (size_t i = 0; i < pMetadataStrings->m_arrItems.size(); ++i) + { + if ((pMetadataStrings->m_arrItems[i]) && (pMetadataStrings->m_arrItems[i]->m_oV.IsInit())) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataString::MetadataString); + m_oBcw.m_oStream.WriteStringW3(pMetadataStrings->m_arrItems[i]->m_oV.get()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + } +} +void BinaryWorkbookTableWriter::WriteMdxMetadata(OOX::Spreadsheet::CMdxMetadata* pMdxMetadata) +{ + if (!pMdxMetadata) return; + + for (size_t i = 0; i < pMdxMetadata->m_arrItems.size(); ++i) + { + if (!pMdxMetadata->m_arrItems[i]) continue; + + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MdxMetadata::Mdx); + WriteMdx(pMdxMetadata->m_arrItems[i]); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +} +void BinaryWorkbookTableWriter::WriteMdx(OOX::Spreadsheet::CMdx* pMdx) +{ + if (!pMdx) return; + + if (pMdx->m_oN.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MdxMetadata::NameIndex); + m_oBcw.m_oStream.WriteULONG(*pMdx->m_oN); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMdx->m_oF.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MdxMetadata::FunctionTag); + m_oBcw.m_oStream.WriteBYTE(pMdx->m_oF->GetValue()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMdx->m_oMdxTuple.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MdxMetadata::MdxTuple); + WriteMdxTuple(pMdx->m_oMdxTuple.GetPointer()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMdx->m_oMdxSet.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MdxMetadata::MdxSet); + WriteMdxSet(pMdx->m_oMdxSet.GetPointer()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMdx->m_oCMdxKPI.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MdxMetadata::MdxKPI); + WriteMdxKPI(pMdx->m_oCMdxKPI.GetPointer()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMdx->m_oMdxMemeberProp.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MdxMetadata::MdxMemeberProp); + WriteMdxMemeberProp(pMdx->m_oMdxMemeberProp.GetPointer()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +} +void BinaryWorkbookTableWriter::WriteMdxTuple(OOX::Spreadsheet::CMdxTuple* pMdxTuple) +{ + if (!pMdxTuple) return; + + if (pMdxTuple->m_oC.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataMdxTuple::IndexCount); + m_oBcw.m_oStream.WriteULONG(*pMdxTuple->m_oC); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMdxTuple->m_oCt.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataMdxTuple::CultureCurrency); + m_oBcw.m_oStream.WriteStringW3(*pMdxTuple->m_oCt); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMdxTuple->m_oSi.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataMdxTuple::StringIndex); + m_oBcw.m_oStream.WriteULONG(*pMdxTuple->m_oSi); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMdxTuple->m_oFi.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataMdxTuple::NumFmtIndex); + m_oBcw.m_oStream.WriteULONG(*pMdxTuple->m_oFi); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMdxTuple->m_oBc.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataMdxTuple::BackColor); + m_oBcw.m_oStream.WriteULONG(*pMdxTuple->m_oBc); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMdxTuple->m_oFc.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataMdxTuple::ForeColor); + m_oBcw.m_oStream.WriteULONG(*pMdxTuple->m_oFc); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMdxTuple->m_oI.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataMdxTuple::Italic); + m_oBcw.m_oStream.WriteBOOL(*pMdxTuple->m_oI); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMdxTuple->m_oB.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataMdxTuple::Bold); + m_oBcw.m_oStream.WriteBOOL(*pMdxTuple->m_oB); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMdxTuple->m_oU.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataMdxTuple::Underline); + m_oBcw.m_oStream.WriteBOOL(*pMdxTuple->m_oU); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMdxTuple->m_oSt.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataMdxTuple::Strike); + m_oBcw.m_oStream.WriteBOOL(*pMdxTuple->m_oSt); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + for (size_t i = 0; i < pMdxTuple->m_arrItems.size(); ++i) + { + if (!pMdxTuple->m_arrItems[i]) continue; + + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataMdxTuple::MetadataStringIndex); + WriteMetadataStringIndex(pMdxTuple->m_arrItems[i]); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +} +void BinaryWorkbookTableWriter::WriteMetadataStringIndex(OOX::Spreadsheet::CMetadataStringIndex* pStringIndex) +{ + if (!pStringIndex) return; + + if (pStringIndex->m_oX.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataStringIndex::IndexValue); + m_oBcw.m_oStream.WriteULONG(*pStringIndex->m_oX); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pStringIndex->m_oS.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataStringIndex::StringIsSet); + m_oBcw.m_oStream.WriteULONG(*pStringIndex->m_oS); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +} +void BinaryWorkbookTableWriter::WriteMdxSet(OOX::Spreadsheet::CMdxSet* pMdxSet) +{ + if (!pMdxSet) return; + + if (pMdxSet->m_oC.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataMdxSet::Count); + m_oBcw.m_oStream.WriteULONG(*pMdxSet->m_oC); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMdxSet->m_oNs.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataMdxSet::Index); + m_oBcw.m_oStream.WriteULONG(*pMdxSet->m_oNs); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMdxSet->m_oO.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataMdxSet::SortOrder); + m_oBcw.m_oStream.WriteBYTE(pMdxSet->m_oO->GetValue()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + for (size_t i = 0; i < pMdxSet->m_arrItems.size(); ++i) + { + if (!pMdxSet->m_arrItems[i]) continue; + + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataMdxSet::MetadataStringIndex); + WriteMetadataStringIndex(pMdxSet->m_arrItems[i]); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +} +void BinaryWorkbookTableWriter::WriteMdxKPI(OOX::Spreadsheet::CMdxKPI* pMdxKPI) +{ + if (!pMdxKPI) return; + + if (pMdxKPI->m_oN.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataMdxKPI::NameIndex); + m_oBcw.m_oStream.WriteULONG(*pMdxKPI->m_oN); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMdxKPI->m_oNp.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataMdxKPI::Index); + m_oBcw.m_oStream.WriteULONG(*pMdxKPI->m_oNp); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMdxKPI->m_oP.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataMdxKPI::Property); + m_oBcw.m_oStream.WriteBYTE(pMdxKPI->m_oP->GetValue()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +} +void BinaryWorkbookTableWriter::WriteMdxMemeberProp(OOX::Spreadsheet::CMdxMemeberProp* pMdxMemeberProp) +{ + if (!pMdxMemeberProp) return; + + if (pMdxMemeberProp->m_oN.IsInit()) { - nCurPos = m_oBcw.WriteItemStart(c_oSer_OleLinkTypes::Name); - m_oBcw.m_oStream.WriteStringW3(oleItem.m_oName.get()); + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataMemberProperty::NameIndex); + m_oBcw.m_oStream.WriteULONG(*pMdxMemeberProp->m_oN); m_oBcw.WriteItemWithLengthEnd(nCurPos); } - if (oleItem.m_oIcon.IsInit()) + if (pMdxMemeberProp->m_oNp.IsInit()) { - nCurPos = m_oBcw.WriteItemStart(c_oSer_OleLinkTypes::Icon); - m_oBcw.m_oStream.WriteBOOL(oleItem.m_oIcon->ToBool()); + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataMemberProperty::Index); + m_oBcw.m_oStream.WriteULONG(*pMdxMemeberProp->m_oNp); m_oBcw.WriteItemWithLengthEnd(nCurPos); } - if (oleItem.m_oAdvise.IsInit()) +} +void BinaryWorkbookTableWriter::WriteMetadataBlocks(OOX::Spreadsheet::CMetadataBlocks* pMetadataBlocks) +{ + if (!pMetadataBlocks) return; + + for (size_t i = 0; i < pMetadataBlocks->m_arrItems.size(); ++i) { - nCurPos = m_oBcw.WriteItemStart(c_oSer_OleLinkTypes::Advise); - m_oBcw.m_oStream.WriteBOOL(oleItem.m_oAdvise->ToBool()); + if (!pMetadataBlocks->m_arrItems[i]) continue; + + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataBlock::MetadataBlock); + WriteMetadataBlock(pMetadataBlocks->m_arrItems[i]); m_oBcw.WriteItemWithLengthEnd(nCurPos); } - if (oleItem.m_oPreferPic.IsInit()) +} +void BinaryWorkbookTableWriter::WriteMetadataBlock(OOX::Spreadsheet::CMetadataBlock* pMetadataBlock) +{ + if (!pMetadataBlock) return; + + for (size_t i = 0; i < pMetadataBlock->m_arrItems.size(); ++i) { - nCurPos = m_oBcw.WriteItemStart(c_oSer_OleLinkTypes::PreferPic); - m_oBcw.m_oStream.WriteBOOL(oleItem.m_oPreferPic->ToBool()); + if (!pMetadataBlock->m_arrItems[i]) continue; + + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataBlock::MetadataRecord); + WriteMetadataRecord(pMetadataBlock->m_arrItems[i]); m_oBcw.WriteItemWithLengthEnd(nCurPos); } } -void BinaryWorkbookTableWriter::WriteDdeLink(const OOX::Spreadsheet::CDdeLink& ddeLink) +void BinaryWorkbookTableWriter::WriteMetadataRecord(OOX::Spreadsheet::CMetadataRecord* pMetadataRecord) { - int nCurPos = 0; - if (ddeLink.m_oDdeService.IsInit()) + if (!pMetadataRecord) return; + + if (pMetadataRecord->m_oT.IsInit()) { - nCurPos = m_oBcw.WriteItemStart(c_oSer_DdeLinkTypes::DdeService); - m_oBcw.m_oStream.WriteStringW3(ddeLink.m_oDdeService.get()); + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataBlock::MetadataRecordType); + m_oBcw.m_oStream.WriteULONG(*pMetadataRecord->m_oT); m_oBcw.WriteItemWithLengthEnd(nCurPos); } - if (ddeLink.m_oDdeTopic.IsInit()) + if (pMetadataRecord->m_oV.IsInit()) { - nCurPos = m_oBcw.WriteItemStart(c_oSer_DdeLinkTypes::DdeTopic); - m_oBcw.m_oStream.WriteStringW3(ddeLink.m_oDdeTopic.get()); + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataBlock::MetadataRecordValue); + m_oBcw.m_oStream.WriteULONG(*pMetadataRecord->m_oV); m_oBcw.WriteItemWithLengthEnd(nCurPos); } - if (ddeLink.m_oDdeItems.IsInit()) +} +void BinaryWorkbookTableWriter::WriteFutureMetadataBlock(OOX::Spreadsheet::CFutureMetadataBlock* pFutureMetadataBlock) +{ + if (!pFutureMetadataBlock) return; + if (false == pFutureMetadataBlock->m_oExtLst.IsInit()) return; + + for (size_t i = 0; i < pFutureMetadataBlock->m_oExtLst->m_arrExt.size(); ++i) { - for(size_t i = 0; i < ddeLink.m_oDdeItems->m_arrItems.size(); ++i) + if (!pFutureMetadataBlock->m_oExtLst->m_arrExt[i]) continue; + + if (pFutureMetadataBlock->m_oExtLst->m_arrExt[i]->m_oDynamicArrayProperties.IsInit()) { - nCurPos = m_oBcw.WriteItemStart(c_oSer_DdeLinkTypes::DdeItem); - WriteDdeItem(*ddeLink.m_oDdeItems->m_arrItems[i]); + int nCurPos = m_oBcw.WriteItemStart(c_oSer_FutureMetadataBlock::DynamicArrayProperties); + { + if (pFutureMetadataBlock->m_oExtLst->m_arrExt[i]->m_oDynamicArrayProperties->m_oFDynamic.IsInit()) + { + int nCurPos2 = m_oBcw.WriteItemStart(c_oSer_FutureMetadataBlock::DynamicArray); + m_oBcw.m_oStream.WriteBOOL(*pFutureMetadataBlock->m_oExtLst->m_arrExt[i]->m_oDynamicArrayProperties->m_oFDynamic); + m_oBcw.WriteItemWithLengthEnd(nCurPos2); + + } + if (pFutureMetadataBlock->m_oExtLst->m_arrExt[i]->m_oDynamicArrayProperties->m_oFCollapsed.IsInit()) + { + int nCurPos2 = m_oBcw.WriteItemStart(c_oSer_FutureMetadataBlock::CollapsedArray); + m_oBcw.m_oStream.WriteBOOL(*pFutureMetadataBlock->m_oExtLst->m_arrExt[i]->m_oDynamicArrayProperties->m_oFCollapsed); + m_oBcw.WriteItemWithLengthEnd(nCurPos2); + } + } + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if ((pFutureMetadataBlock->m_oExtLst->m_arrExt[i]->m_oRichValueBlock.IsInit()) && + (pFutureMetadataBlock->m_oExtLst->m_arrExt[i]->m_oRichValueBlock->m_oI.IsInit())) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_FutureMetadataBlock::RichValueBlock); + m_oBcw.m_oStream.WriteULONG(*pFutureMetadataBlock->m_oExtLst->m_arrExt[i]->m_oRichValueBlock->m_oI); m_oBcw.WriteItemWithLengthEnd(nCurPos); } } } -void BinaryWorkbookTableWriter::WriteDdeItem(const OOX::Spreadsheet::CDdeItem& ddeItem) +void BinaryWorkbookTableWriter::WriteFutureMetadata(OOX::Spreadsheet::CFutureMetadata* pFutureMetadata) { - int nCurPos = 0; - if (ddeItem.m_oName.IsInit()) - { - nCurPos = m_oBcw.WriteItemStart(c_oSer_DdeLinkTypes::Name); - m_oBcw.m_oStream.WriteStringW3(ddeItem.m_oName.get()); - m_oBcw.WriteItemWithLengthEnd(nCurPos); - } - if (ddeItem.m_oOle.IsInit()) + if (!pFutureMetadata) return; + + if (pFutureMetadata->m_oName.IsInit()) { - nCurPos = m_oBcw.WriteItemStart(c_oSer_DdeLinkTypes::Ole); - m_oBcw.m_oStream.WriteBOOL(ddeItem.m_oOle->ToBool()); + int nCurPos = m_oBcw.WriteItemStart(c_oSer_FutureMetadataBlock::Name); + m_oBcw.m_oStream.WriteStringW3(*pFutureMetadata->m_oName); m_oBcw.WriteItemWithLengthEnd(nCurPos); } - if (ddeItem.m_oAdvise.IsInit()) + for (size_t i = 0; i < pFutureMetadata->m_arrItems.size(); ++i) { - nCurPos = m_oBcw.WriteItemStart(c_oSer_DdeLinkTypes::Advise); - m_oBcw.m_oStream.WriteBOOL(ddeItem.m_oAdvise->ToBool()); + if (!pFutureMetadata->m_arrItems[i]) continue; + + int nCurPos = m_oBcw.WriteItemStart(c_oSer_FutureMetadataBlock::FutureMetadataBlock); + WriteFutureMetadataBlock(pFutureMetadata->m_arrItems[i]); m_oBcw.WriteItemWithLengthEnd(nCurPos); } - if (ddeItem.m_oPreferPic.IsInit()) +} + +void BinaryWorkbookTableWriter::WriteTimelineRange(OOX::Spreadsheet::CTimelineRange* pTimelineRange) +{ + if (!pTimelineRange) return; + + if (pTimelineRange->m_oStartDate.IsInit()) { - nCurPos = m_oBcw.WriteItemStart(c_oSer_DdeLinkTypes::PreferPic); - m_oBcw.m_oStream.WriteBOOL(ddeItem.m_oPreferPic->ToBool()); - m_oBcw.WriteItemWithLengthEnd(nCurPos); + m_oBcw.m_oStream.WriteBYTE(c_oSer_TimelineRange::StartDate); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Variable); + m_oBcw.m_oStream.WriteStringW(*pTimelineRange->m_oStartDate); } - if (ddeItem.m_oDdeValues.IsInit()) + if (pTimelineRange->m_oEndDate.IsInit()) { - nCurPos = m_oBcw.WriteItemStart(c_oSer_DdeLinkTypes::DdeValues); - WriteDdeValues(ddeItem.m_oDdeValues.get()); - m_oBcw.WriteItemWithLengthEnd(nCurPos); + m_oBcw.m_oStream.WriteBYTE(c_oSer_TimelineRange::EndDate); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Variable); + m_oBcw.m_oStream.WriteStringW(*pTimelineRange->m_oEndDate); } } -void BinaryWorkbookTableWriter::WriteDdeValues(const OOX::Spreadsheet::CDdeValues& ddeValues) +void BinaryWorkbookTableWriter::WriteTimelinePivotFilter(OOX::Spreadsheet::CTimelinePivotFilter* pPivotFilter) { + if (!pPivotFilter) return; + int nCurPos = 0; - if (ddeValues.m_oRows.IsInit()) + if (pPivotFilter->m_oName.IsInit()) { - nCurPos = m_oBcw.WriteItemStart(c_oSer_DdeLinkTypes::DdeValuesRows); - m_oBcw.m_oStream.WriteULONG(ddeValues.m_oRows->GetValue()); + nCurPos = m_oBcw.WriteItemStart(c_oSer_TimelinePivotFilter::Name); + m_oBcw.m_oStream.WriteStringW3(*pPivotFilter->m_oName); m_oBcw.WriteItemWithLengthEnd(nCurPos); } - if (ddeValues.m_oCols.IsInit()) + if (pPivotFilter->m_oDescription.IsInit()) { - nCurPos = m_oBcw.WriteItemStart(c_oSer_DdeLinkTypes::DdeValuesCols); - m_oBcw.m_oStream.WriteULONG(ddeValues.m_oCols->GetValue()); + nCurPos = m_oBcw.WriteItemStart(c_oSer_TimelinePivotFilter::Description); + m_oBcw.m_oStream.WriteStringW3(*pPivotFilter->m_oDescription); m_oBcw.WriteItemWithLengthEnd(nCurPos); } - for(size_t i = 0; i < ddeValues.m_arrItems.size(); ++i) + if (pPivotFilter->m_oUseWholeDay.IsInit()) { - nCurPos = m_oBcw.WriteItemStart(c_oSer_DdeLinkTypes::DdeValue); - WriteDdeValue(*ddeValues.m_arrItems[i]); + nCurPos = m_oBcw.WriteItemStart(c_oSer_TimelinePivotFilter::UseWholeDay); + m_oBcw.m_oStream.WriteBOOL(*pPivotFilter->m_oUseWholeDay); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pPivotFilter->m_oId.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_TimelinePivotFilter::Id); + m_oBcw.m_oStream.WriteLONG(*pPivotFilter->m_oId); m_oBcw.WriteItemWithLengthEnd(nCurPos); } -} -void BinaryWorkbookTableWriter::WriteDdeValue(const OOX::Spreadsheet::CDdeValue& ddeValue) -{ - int nCurPos = 0; - if (ddeValue.m_oType.IsInit()) + if (pPivotFilter->m_oFld.IsInit()) { - nCurPos = m_oBcw.WriteItemStart(c_oSer_DdeLinkTypes::DdeValueType); - m_oBcw.m_oStream.WriteBYTE(ddeValue.m_oType->GetValue()); + nCurPos = m_oBcw.WriteItemStart(c_oSer_TimelinePivotFilter::Fld); + m_oBcw.m_oStream.WriteLONG(*pPivotFilter->m_oFld); m_oBcw.WriteItemWithLengthEnd(nCurPos); } - for (size_t i = 0; i < ddeValue.m_arrItems.size(); ++i) + if (pPivotFilter->m_oAutoFilter.IsInit()) { - nCurPos = m_oBcw.WriteItemStart(c_oSer_DdeLinkTypes::DdeValueVal); - m_oBcw.m_oStream.WriteStringW3(ddeValue.m_arrItems[i]->ToString()); + nCurPos = m_oBcw.WriteItemStart(c_oSer_TimelinePivotFilter::AutoFilter); + BinaryTableWriter oBinaryTableWriter(m_oBcw.m_oStream); + oBinaryTableWriter.WriteAutoFilter(pPivotFilter->m_oAutoFilter.get()); m_oBcw.WriteItemWithLengthEnd(nCurPos); } } -void BinaryWorkbookTableWriter::WriteDefinedName(const OOX::Spreadsheet::CDefinedName& definedName) +void BinaryWorkbookTableWriter::WriteTimelineCachePivotTables(OOX::Spreadsheet::CTimelineCachePivotTables* pPivotTables) { + if (!pPivotTables) return; + int nCurPos = 0; - //Name - if(definedName.m_oName.IsInit()) - { - m_oBcw.m_oStream.WriteBYTE(c_oSerDefinedNameTypes::Name); - m_oBcw.m_oStream.WriteStringW(*definedName.m_oName); - } - //Ref - if(definedName.m_oRef.IsInit()) + for (size_t i = 0; i < pPivotTables->m_arrItems.size(); ++i) { - m_oBcw.m_oStream.WriteBYTE(c_oSerDefinedNameTypes::Ref); - m_oBcw.m_oStream.WriteStringW(*definedName.m_oRef); + nCurPos = m_oBcw.WriteItemStart(c_oSer_TimelineCache::PivotTable); + WriteTimelineCachePivotTable(pPivotTables->m_arrItems[i]); + m_oBcw.WriteItemWithLengthEnd(nCurPos); } - //LocalSheetId - if(definedName.m_oLocalSheetId.IsInit()) +} +void BinaryWorkbookTableWriter::WriteTimelineCachePivotTable(OOX::Spreadsheet::CTimelineCachePivotTable* pPivotTable) +{ + if (!pPivotTable) return; + + if (pPivotTable->m_oName.IsInit()) { - nCurPos = m_oBcw.WriteItemStart(c_oSerDefinedNameTypes::LocalSheetId); - m_oBcw.m_oStream.WriteLONG(definedName.m_oLocalSheetId->GetValue()); - m_oBcw.WriteItemWithLengthEnd(nCurPos); + m_oBcw.m_oStream.WriteBYTE(c_oSer_TimelineCachePivotTable::Name); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Variable); + m_oBcw.m_oStream.WriteStringW(*pPivotTable->m_oName); } - //Hidden - if(definedName.m_oHidden.IsInit()) - { - nCurPos = m_oBcw.WriteItemStart(c_oSerDefinedNameTypes::Hidden); - m_oBcw.m_oStream.WriteBOOL(definedName.m_oHidden->ToBool()); - m_oBcw.WriteItemWithLengthEnd(nCurPos); - } - //Comment - if (definedName.m_oComment.IsInit()) + if (pPivotTable->m_oTabId.IsInit()) { - m_oBcw.m_oStream.WriteBYTE(c_oSerDefinedNameTypes::Comment); - m_oBcw.m_oStream.WriteStringW(*definedName.m_oComment); + m_oBcw.m_oStream.WriteBYTE(c_oSer_TimelineCachePivotTable::TabId); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Long); + m_oBcw.m_oStream.WriteLONG(*pPivotTable->m_oTabId); } } void BinaryWorkbookTableWriter::WriteSlicerCaches(OOX::Spreadsheet::CWorkbook& workbook, const OOX::Spreadsheet::CSlicerCaches& oSlicerCaches) { int nCurPos = 0; - for(size_t i = 0; i < oSlicerCaches.m_oSlicerCache.size(); ++i) + for (size_t i = 0; i < oSlicerCaches.m_oSlicerCache.size(); ++i) { if(oSlicerCaches.m_oSlicerCache[i].m_oRId.IsInit()) { @@ -3595,6 +4507,12 @@ void BinaryWorksheetTableWriter::WriteWorksheet(OOX::Spreadsheet::CSheet* pSheet WriteUserProtectedRanges(pExt->m_oUserProtectedRanges.get()); m_oBcw.WriteItemWithLengthEnd(nCurPos); } + else if (pExt->m_oTimelineRefs.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerWorksheetsTypes::TimelinesList); + WriteTimelines(oWorksheet, pExt->m_oTimelineRefs.get()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } } } // DataValidations (with ext) @@ -3736,18 +4654,21 @@ void BinaryWorksheetTableWriter::WriteWorksheet(OOX::Spreadsheet::CSheet* pSheet smart_ptr pFile = oWorksheet.Find(oWorksheet.m_oPicture->m_oId->GetValue()); if (pFile.IsInit() && ( OOX::FileTypes::Image == pFile->type())) { - OOX::Image* pImageFileCache = static_cast(pFile.GetPointer()); - OOX::CPath pathImage = pImageFileCache->filename(); - std::wstring additionalPath; - int additionalType = 0; - double dX = -1.0; //mm - double dY = -1.0; - double dW = -1.0; //mm - double dH = -1.0; - NSShapeImageGen::CMediaInfo oId = m_pOfficeDrawingConverter->m_pBinaryWriter->m_pCommon->m_pMediaManager->WriteImage(pathImage.GetPath(), dX, dY, dW, dH, additionalPath, additionalType); - nCurPos = m_oBcw.WriteItemStart(c_oSerWorksheetsTypes::Picture); - m_oBcw.m_oStream.WriteStringW3(oId.GetPath2()); - m_oBcw.WriteItemEnd(nCurPos); + smart_ptr pImageFileCache = pFile.smart_dynamic_cast(); + if (pImageFileCache.IsInit()) + { + OOX::CPath pathImage = pImageFileCache->filename(); + std::wstring additionalPath; + int additionalType = 0; + double dX = -1.0; //mm + double dY = -1.0; + double dW = -1.0; //mm + double dH = -1.0; + NSShapeImageGen::CMediaInfo oId = m_pOfficeDrawingConverter->m_pBinaryWriter->m_pCommon->m_pMediaManager->WriteImage(pathImage.GetPath(), dX, dY, dW, dH, additionalPath, additionalType); + nCurPos = m_oBcw.WriteItemStart(c_oSerWorksheetsTypes::Picture); + m_oBcw.m_oStream.WriteStringW3(oId.GetPath2()); + m_oBcw.WriteItemEnd(nCurPos); + } } } if (oWorksheet.m_oSortState.IsInit()) @@ -4770,14 +5691,40 @@ void BinaryWorksheetTableWriter::WriteCell(const OOX::Spreadsheet::CCell& oCell) { double dValue = 0; - try - { - dValue = XmlUtils::GetDouble(oCell.m_oValue->ToString()); - } - catch(...) - { //1.3912059045063478e-310 - //Lighting Load Calculation.xls - } + if(oCell.m_oType.IsInit() && oCell.m_oType->m_eValue == SimpleTypes::Spreadsheet::celltypeError) + { + auto errorText = oCell.m_oValue->m_sText; + if(errorText == L"#NULL!") + dValue = 0x00; + else if(errorText == L"#DIV/0!") + dValue = 0x07; + else if(errorText == L"#VALUE!") + dValue = 0x0F; + else if(errorText == L"#REF!") + dValue = 0x17; + else if(errorText == L"#NAME?") + dValue = 0x1D; + else if(errorText == L"#NUM!") + dValue = 0x24; + else if(errorText == L"#N/A") + dValue = 0x2A; + else if(errorText == L"#GETTING_DATA") + dValue = 0x2B; + else + dValue = 0x0; + } + else + { + try + { + dValue = XmlUtils::GetDouble(oCell.m_oValue->ToString()); + } + catch(...) + { //1.3912059045063478e-310 + //Lighting Load Calculation.xls + } + } + nCurPos = m_oBcw.WriteItemStart(c_oSerCellTypes::Value); m_oBcw.m_oStream.WriteDoubleReal(dValue); @@ -4790,6 +5737,18 @@ void BinaryWorksheetTableWriter::WriteCell(const OOX::Spreadsheet::CCell& oCell) m_oBcw.m_oStream.WriteStringW3(*oCell.m_oCacheValue); m_oBcw.WriteItemEnd(nCurPos); } + if (oCell.m_oCellMetadata.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerCellTypes::CellMetadata); + m_oBcw.m_oStream.WriteULONG(*oCell.m_oCellMetadata); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oCell.m_oValueMetadata.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerCellTypes::ValueMetadata); + m_oBcw.m_oStream.WriteULONG(*oCell.m_oValueMetadata); + m_oBcw.WriteItemEnd(nCurPos); + } } void BinaryWorksheetTableWriter::WriteFormula(OOX::Spreadsheet::CFormula& oFormula) { @@ -4920,7 +5879,7 @@ void BinaryWorksheetTableWriter::WriteOleObjects(const OOX::Spreadsheet::CWorksh std::wstring sShapeId = L"_x0000_s" + std::to_wstring(pOleObject->m_oShapeId->GetValue()); if (pVmlDrawing) { - boost::unordered_map::iterator pFind = pVmlDrawing->m_mapShapes.find(sShapeId); + std::map::iterator pFind = pVmlDrawing->m_mapShapes.find(sShapeId); if (pFind != pVmlDrawing->m_mapShapes.end()) { @@ -4986,7 +5945,8 @@ void BinaryWorksheetTableWriter::WriteOleObjects(const OOX::Spreadsheet::CWorksh olePic->blipFill.blip->oleFilepathBin = olePic->oleObject->m_OleObjectFile->filename().GetPath(); } - OOX::Image* pImageFileCache = NULL; + smart_ptr pImageFileCache; + std::wstring sIdImageFileCache; if ((NULL != pShapeElem) && (OOX::et_v_shapetype != pShapeElem->getType())) { @@ -5017,23 +5977,23 @@ void BinaryWorksheetTableWriter::WriteOleObjects(const OOX::Spreadsheet::CWorksh if (pFile.IsInit() && (OOX::FileTypes::Image == pFile->type())) { - pImageFileCache = static_cast(pFile.GetPointer()); + pImageFileCache = pFile.smart_dynamic_cast(); } } } } } - if (pImageFileCache == NULL && pOleObject->m_oObjectPr.IsInit() && pOleObject->m_oObjectPr->m_oRid.IsInit()) + if (false == pImageFileCache.IsInit() && pOleObject->m_oObjectPr.IsInit() && pOleObject->m_oObjectPr->m_oRid.IsInit()) { sIdImageFileCache = pOleObject->m_oObjectPr->m_oRid->GetValue(); smart_ptr pFile = oWorksheet.Find(sIdImageFileCache); if (pFile.IsInit() && (OOX::FileTypes::Image == pFile->type())) { - pImageFileCache = static_cast(pFile.GetPointer()); + pImageFileCache = pFile.smart_dynamic_cast(); } } - if (pImageFileCache) + if (pImageFileCache.IsInit()) { OOX::CPath pathImage = pImageFileCache->filename(); @@ -5113,7 +6073,7 @@ void BinaryWorksheetTableWriter::WriteControls(const OOX::Spreadsheet::CWorkshee std::wstring sShapeId = L"_x0000_s" + std::to_wstring(pControl->m_oShapeId->GetValue()); OOX::Vml::CShape* pShape = NULL; - boost::unordered_map::iterator pFind; + std::map::iterator pFind; if (pVmlDrawing) { @@ -5202,257 +6162,256 @@ void BinaryWorksheetTableWriter::WriteControls(const OOX::Spreadsheet::CWorkshee void BinaryWorksheetTableWriter::WriteControlPr(OOX::Spreadsheet::CControlPr* pControlPr, OOX::Spreadsheet::CFormControlPr* pFormControlPr) { - if (!pControlPr) return; - if (!pFormControlPr) return; + if (!pControlPr && !pFormControlPr) return; int nCurPos = 0; - if (pFormControlPr->m_oObjectType.IsInit()) + if (pFormControlPr && pFormControlPr->m_oObjectType.IsInit()) { nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::ObjectType); m_oBcw.m_oStream.WriteBYTE(pFormControlPr->m_oObjectType->GetValue()); m_oBcw.WriteItemEnd(nCurPos); } - if (pControlPr->m_oAltText.IsInit()) + if (pControlPr && pControlPr->m_oAltText.IsInit()) { m_oBcw.m_oStream.WriteBYTE(c_oSerControlTypes::AltText); m_oBcw.m_oStream.WriteStringW(*pControlPr->m_oAltText); } - if (pControlPr->m_oAutoFill.IsInit()) + if (pControlPr && pControlPr->m_oAutoFill.IsInit()) { nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::AutoFill); m_oBcw.m_oStream.WriteBOOL(*pControlPr->m_oAutoFill); m_oBcw.WriteItemEnd(nCurPos); } - if (pControlPr->m_oAutoLine.IsInit()) + if (pControlPr && pControlPr->m_oAutoLine.IsInit()) { nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::AutoLine); m_oBcw.m_oStream.WriteBOOL(*pControlPr->m_oAutoLine); m_oBcw.WriteItemEnd(nCurPos); } - if (pControlPr->m_oAutoPict.IsInit()) + if (pControlPr && pControlPr->m_oAutoPict.IsInit()) { nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::AutoPict); m_oBcw.m_oStream.WriteBOOL(*pControlPr->m_oAutoPict); m_oBcw.WriteItemEnd(nCurPos); } - if (pControlPr->m_oDefaultSize.IsInit()) + if (pControlPr && pControlPr->m_oDefaultSize.IsInit()) { nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::DefaultSize); m_oBcw.m_oStream.WriteBOOL(*pControlPr->m_oDefaultSize); m_oBcw.WriteItemEnd(nCurPos); } - if (pControlPr->m_oDisabled.IsInit()) + if (pControlPr && pControlPr->m_oDisabled.IsInit()) { nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::Disabled); m_oBcw.m_oStream.WriteBOOL(*pControlPr->m_oDisabled); m_oBcw.WriteItemEnd(nCurPos); } - if (pControlPr->m_oLocked.IsInit()) + if (pControlPr && pControlPr->m_oLocked.IsInit()) { nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::Locked); m_oBcw.m_oStream.WriteBOOL(*pControlPr->m_oLocked); m_oBcw.WriteItemEnd(nCurPos); } - if (pControlPr->m_oPrint.IsInit()) + if (pControlPr && pControlPr->m_oPrint.IsInit()) { nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::Print); m_oBcw.m_oStream.WriteBOOL(*pControlPr->m_oPrint); m_oBcw.WriteItemEnd(nCurPos); } - if (pControlPr->m_oRecalcAlways.IsInit()) + if (pControlPr && pControlPr->m_oRecalcAlways.IsInit()) { nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::RecalcAlways); m_oBcw.m_oStream.WriteBOOL(*pControlPr->m_oRecalcAlways); m_oBcw.WriteItemEnd(nCurPos); } - if(pControlPr->m_oMacro.IsInit()) + if(pControlPr && pControlPr->m_oMacro.IsInit()) { m_oBcw.m_oStream.WriteBYTE(c_oSerControlTypes::Macro); m_oBcw.m_oStream.WriteStringW(*pControlPr->m_oMacro); } - if(pFormControlPr->m_oFmlaGroup.IsInit()) + if(pFormControlPr && pFormControlPr->m_oFmlaGroup.IsInit()) { m_oBcw.m_oStream.WriteBYTE(c_oSerControlTypes::FmlaGroup); m_oBcw.m_oStream.WriteStringW(*pFormControlPr->m_oFmlaGroup); } - if(pFormControlPr->m_oFmlaLink.IsInit()) + if(pFormControlPr && pFormControlPr->m_oFmlaLink.IsInit()) { m_oBcw.m_oStream.WriteBYTE(c_oSerControlTypes::FmlaLink); m_oBcw.m_oStream.WriteStringW(*pFormControlPr->m_oFmlaLink); } - if(pFormControlPr->m_oFmlaRange.IsInit()) + if(pFormControlPr && pFormControlPr->m_oFmlaRange.IsInit()) { m_oBcw.m_oStream.WriteBYTE(c_oSerControlTypes::FmlaRange); m_oBcw.m_oStream.WriteStringW(*pFormControlPr->m_oFmlaRange); } - if(pFormControlPr->m_oFmlaTxbx.IsInit()) + if(pFormControlPr && pFormControlPr->m_oFmlaTxbx.IsInit()) { m_oBcw.m_oStream.WriteBYTE(c_oSerControlTypes::FmlaTxbx); m_oBcw.m_oStream.WriteStringW(*pFormControlPr->m_oFmlaTxbx); } - if (pFormControlPr->m_oDropLines.IsInit()) + if (pFormControlPr && pFormControlPr->m_oDropLines.IsInit()) { nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::DropLines); m_oBcw.m_oStream.WriteLONG(pFormControlPr->m_oDropLines->GetValue()); m_oBcw.WriteItemEnd(nCurPos); } - if (pFormControlPr->m_oChecked.IsInit()) + if (pFormControlPr && pFormControlPr->m_oChecked.IsInit()) { nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::Checked); m_oBcw.m_oStream.WriteBYTE(pFormControlPr->m_oChecked->GetValue()); m_oBcw.WriteItemEnd(nCurPos); } - if (pFormControlPr->m_oDropStyle.IsInit()) + if (pFormControlPr && pFormControlPr->m_oDropStyle.IsInit()) { nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::DropStyle); m_oBcw.m_oStream.WriteBYTE(pFormControlPr->m_oDropStyle->GetValue()); m_oBcw.WriteItemEnd(nCurPos); } - if (pFormControlPr->m_oDx.IsInit()) + if (pFormControlPr && pFormControlPr->m_oDx.IsInit()) { nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::Dx); m_oBcw.m_oStream.WriteLONG(pFormControlPr->m_oDx->GetValue()); m_oBcw.WriteItemEnd(nCurPos); } - if (pFormControlPr->m_oInc.IsInit()) + if (pFormControlPr && pFormControlPr->m_oInc.IsInit()) { nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::Inc); m_oBcw.m_oStream.WriteLONG(pFormControlPr->m_oInc->GetValue()); m_oBcw.WriteItemEnd(nCurPos); } - if (pFormControlPr->m_oMin.IsInit()) + if (pFormControlPr && pFormControlPr->m_oMin.IsInit()) { nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::Min); m_oBcw.m_oStream.WriteLONG(pFormControlPr->m_oMin->GetValue()); m_oBcw.WriteItemEnd(nCurPos); } - if (pFormControlPr->m_oMax.IsInit()) + if (pFormControlPr && pFormControlPr->m_oMax.IsInit()) { nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::Max); m_oBcw.m_oStream.WriteLONG(pFormControlPr->m_oMax->GetValue()); m_oBcw.WriteItemEnd(nCurPos); } - if (pFormControlPr->m_oPage.IsInit()) + if (pFormControlPr && pFormControlPr->m_oPage.IsInit()) { nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::Page); m_oBcw.m_oStream.WriteLONG(pFormControlPr->m_oPage->GetValue()); m_oBcw.WriteItemEnd(nCurPos); } - if (pFormControlPr->m_oSel.IsInit()) + if (pFormControlPr && pFormControlPr->m_oSel.IsInit()) { nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::Sel); m_oBcw.m_oStream.WriteLONG(pFormControlPr->m_oSel->GetValue()); m_oBcw.WriteItemEnd(nCurPos); } - if (pFormControlPr->m_oSelType.IsInit()) + if (pFormControlPr && pFormControlPr->m_oSelType.IsInit()) { nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::SelType); m_oBcw.m_oStream.WriteBYTE(pFormControlPr->m_oSelType->GetValue()); m_oBcw.WriteItemEnd(nCurPos); } - if (pFormControlPr->m_oTextHAlign.IsInit()) + if (pFormControlPr && pFormControlPr->m_oTextHAlign.IsInit()) { nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::TextHAlign); m_oBcw.m_oStream.WriteBYTE(pFormControlPr->m_oTextHAlign->GetValue()); m_oBcw.WriteItemEnd(nCurPos); } - if (pFormControlPr->m_oTextVAlign.IsInit()) + if (pFormControlPr && pFormControlPr->m_oTextVAlign.IsInit()) { nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::TextVAlign); m_oBcw.m_oStream.WriteBYTE(pFormControlPr->m_oTextVAlign->GetValue()); m_oBcw.WriteItemEnd(nCurPos); } - if (pFormControlPr->m_oVal.IsInit()) + if (pFormControlPr && pFormControlPr->m_oVal.IsInit()) { nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::Val); m_oBcw.m_oStream.WriteLONG(*pFormControlPr->m_oVal); m_oBcw.WriteItemEnd(nCurPos); } - if (pFormControlPr->m_oWidthMin.IsInit()) + if (pFormControlPr && pFormControlPr->m_oWidthMin.IsInit()) { nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::WidthMin); m_oBcw.m_oStream.WriteLONG(pFormControlPr->m_oWidthMin->GetValue()); m_oBcw.WriteItemEnd(nCurPos); } - if (pFormControlPr->m_oEditVal.IsInit()) + if (pFormControlPr && pFormControlPr->m_oEditVal.IsInit()) { nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::EditVal); m_oBcw.m_oStream.WriteBYTE(pFormControlPr->m_oEditVal->GetValue()); m_oBcw.WriteItemEnd(nCurPos); } - if (pFormControlPr->m_oColored.IsInit()) + if (pFormControlPr && pFormControlPr->m_oColored.IsInit()) { nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::Colored); m_oBcw.m_oStream.WriteBOOL(*pFormControlPr->m_oColored); m_oBcw.WriteItemEnd(nCurPos); } - if (pFormControlPr->m_oFirstButton.IsInit()) + if (pFormControlPr && pFormControlPr->m_oFirstButton.IsInit()) { nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::FirstButton); m_oBcw.m_oStream.WriteBOOL(*pFormControlPr->m_oFirstButton); m_oBcw.WriteItemEnd(nCurPos); } - if (pFormControlPr->m_oHoriz.IsInit()) + if (pFormControlPr && pFormControlPr->m_oHoriz.IsInit()) { nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::Horiz); m_oBcw.m_oStream.WriteBOOL(*pFormControlPr->m_oHoriz); m_oBcw.WriteItemEnd(nCurPos); } - if (pFormControlPr->m_oJustLastX.IsInit()) + if (pFormControlPr && pFormControlPr->m_oJustLastX.IsInit()) { nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::JustLastX); m_oBcw.m_oStream.WriteBOOL(*pFormControlPr->m_oJustLastX); m_oBcw.WriteItemEnd(nCurPos); } - if (pFormControlPr->m_oLockText.IsInit()) + if (pFormControlPr && pFormControlPr->m_oLockText.IsInit()) { nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::LockText); m_oBcw.m_oStream.WriteBOOL(*pFormControlPr->m_oLockText); m_oBcw.WriteItemEnd(nCurPos); } - if (pFormControlPr->m_oNoThreeD.IsInit()) + if (pFormControlPr && pFormControlPr->m_oNoThreeD.IsInit()) { nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::NoThreeD); m_oBcw.m_oStream.WriteBOOL(*pFormControlPr->m_oNoThreeD); m_oBcw.WriteItemEnd(nCurPos); } - if (pFormControlPr->m_oNoThreeD2.IsInit()) + if (pFormControlPr && pFormControlPr->m_oNoThreeD2.IsInit()) { nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::NoThreeD2); m_oBcw.m_oStream.WriteBOOL(*pFormControlPr->m_oNoThreeD2); m_oBcw.WriteItemEnd(nCurPos); } - if(pFormControlPr->m_oMultiSel.IsInit()) + if(pFormControlPr && pFormControlPr->m_oMultiSel.IsInit()) { m_oBcw.m_oStream.WriteBYTE(c_oSerControlTypes::MultiSel); m_oBcw.m_oStream.WriteStringW(*pFormControlPr->m_oMultiSel); } - if (pFormControlPr->m_oMultiLine.IsInit()) + if (pFormControlPr && pFormControlPr->m_oMultiLine.IsInit()) { nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::MultiLine); m_oBcw.m_oStream.WriteBOOL(*pFormControlPr->m_oMultiLine); m_oBcw.WriteItemEnd(nCurPos); } - if (pFormControlPr->m_oVerticalBar.IsInit()) + if (pFormControlPr && pFormControlPr->m_oVerticalBar.IsInit()) { nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::VerticalBar); m_oBcw.m_oStream.WriteBOOL(*pFormControlPr->m_oVerticalBar); m_oBcw.WriteItemEnd(nCurPos); } - if (pFormControlPr->m_oPasswordEdit.IsInit()) + if (pFormControlPr && pFormControlPr->m_oPasswordEdit.IsInit()) { nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::PasswordEdit); m_oBcw.m_oStream.WriteBOOL(*pFormControlPr->m_oPasswordEdit); m_oBcw.WriteItemEnd(nCurPos); } - if (pFormControlPr->m_oText.IsInit()) + if (pFormControlPr && pFormControlPr->m_oText.IsInit()) { m_oBcw.m_oStream.WriteBYTE(c_oSerControlTypes::Text); m_oBcw.m_oStream.WriteStringW(*pFormControlPr->m_oText); } - if(pFormControlPr->m_oItemLst.IsInit()) + if(pFormControlPr && pFormControlPr->m_oItemLst.IsInit()) { nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::ItemLst); for (size_t i = 0; i < pFormControlPr->m_oItemLst->m_arrItems.size(); ++i) @@ -5505,7 +6464,7 @@ void BinaryWorksheetTableWriter::WriteDrawings(const OOX::Spreadsheet::CWorkshee if (NULL != pVmlDrawing) { - boost::unordered_map::iterator it = pVmlDrawing->m_mapShapes.begin(); + std::map::iterator it = pVmlDrawing->m_mapShapes.begin(); for (; it != pVmlDrawing->m_mapShapes.end(); it++) { @@ -5522,6 +6481,11 @@ void BinaryWorksheetTableWriter::WriteDrawings(const OOX::Spreadsheet::CWorkshee { //преобразуем ClientData в CellAnchor OOX::Vml::CClientData* pClientData = static_cast(pElemShape); + + if (pClientData->m_oObjectType.IsInit() && pClientData->m_oObjectType->GetValue() == SimpleTypes::Vml::vmlclientdataobjecttypeNote) + { + continue; + } SimpleTypes::Spreadsheet::CCellAnchorType eAnchorType; eAnchorType.SetValue(SimpleTypes::Spreadsheet::cellanchorTwoCell); @@ -5606,9 +6570,14 @@ void BinaryWorksheetTableWriter::WriteDrawing(const OOX::Spreadsheet::CWorksheet WriteCellAnchor(pCellAnchor); + if (pCellAnchor->m_oExt.IsInit()) + { + m_oBcw.m_oStream.m_dCxCurShape = pCellAnchor->m_oExt->m_oCx.IsInit() ? pCellAnchor->m_oExt->m_oCx->GetValue() : 0; + m_oBcw.m_oStream.m_dCyCurShape = pCellAnchor->m_oExt->m_oCy.IsInit() ? pCellAnchor->m_oExt->m_oCy->GetValue() : 0; + } if (pCellAnchor->m_sVmlSpId.IsInit() && pVmlDrawing) { - boost::unordered_map::iterator pFind = pVmlDrawing->m_mapShapes.find(pCellAnchor->m_sVmlSpId.get2()); + std::map::iterator pFind = pVmlDrawing->m_mapShapes.find(pCellAnchor->m_sVmlSpId.get2()); if (pFind != pVmlDrawing->m_mapShapes.end() && !pFind->second.bUsed) { @@ -5650,9 +6619,18 @@ void BinaryWorksheetTableWriter::WriteDrawing(const OOX::Spreadsheet::CWorksheet m_oBcw.m_oStream.WriteBYTE(c_oSer_DrawingType::pptxDrawing); int nCurPos = m_oBcw.WriteItemWithLengthStart(); + m_oBcw.m_oStream.StartRecord(0); m_oBcw.m_oStream.WriteRecord2(1, pCellAnchor->m_oElement->GetElem()); m_oBcw.m_oStream.EndRecord(); + + if (pCellAnchor->m_oElement->GetElemAlternative().IsInit()) + { + m_oBcw.m_oStream.StartRecord(0x99); + m_oBcw.m_oStream.WriteRecord2(1, pCellAnchor->m_oElement->GetElemAlternative()); + m_oBcw.m_oStream.EndRecord(); + } + m_oBcw.WriteItemWithLengthEnd(nCurPos); m_oBcw.m_oStream.SetRels(oldRels); @@ -5792,7 +6770,7 @@ void BinaryWorksheetTableWriter::WriteLegacyDrawingHFDrawings(OOX::CVmlDrawing* { m_pOfficeDrawingConverter->AddShapeType(pVmlDrawing->m_arrShapeTypes[i].sXml); } - boost::unordered_map::iterator it = pVmlDrawing->m_mapShapes.begin(); + std::map::iterator it = pVmlDrawing->m_mapShapes.begin(); for (; it != pVmlDrawing->m_mapShapes.end(); it++) { int nCurPos = m_oBcw.WriteItemStart(c_oSer_LegacyDrawingHF::Drawing); @@ -7159,25 +8137,37 @@ void BinaryWorksheetTableWriter::WriteUserProtectedRangeDesc(const OOX::Spreadsh m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Variable); m_oBcw.m_oStream.WriteStringW(*desc.name); } + if (desc.type.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_UserProtectedRangeDesc::Type); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBYTE(desc.type->GetValue()); + } } void BinaryWorksheetTableWriter::WriteUserProtectedRange(const OOX::Spreadsheet::CUserProtectedRange& oUserProtectedRange) { if (oUserProtectedRange.m_oName.IsInit()) { int nCurPos = m_oBcw.WriteItemStart(c_oSer_UserProtectedRange::Name); - m_oBcw.m_oStream.WriteStringW(*oUserProtectedRange.m_oName); + m_oBcw.m_oStream.WriteStringW3(*oUserProtectedRange.m_oName); m_oBcw.WriteItemEnd(nCurPos); } if (oUserProtectedRange.m_oSqref.IsInit()) { int nCurPos = m_oBcw.WriteItemStart(c_oSer_UserProtectedRange::Sqref); - m_oBcw.m_oStream.WriteStringW(*oUserProtectedRange.m_oSqref); + m_oBcw.m_oStream.WriteStringW3(*oUserProtectedRange.m_oSqref); m_oBcw.WriteItemEnd(nCurPos); } if (oUserProtectedRange.m_oText.IsInit()) { int nCurPos = m_oBcw.WriteItemStart(c_oSer_UserProtectedRange::Text); - m_oBcw.m_oStream.WriteStringW(*oUserProtectedRange.m_oText); + m_oBcw.m_oStream.WriteStringW3(*oUserProtectedRange.m_oText); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oUserProtectedRange.m_oType.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_UserProtectedRange::Type); + m_oBcw.m_oStream.WriteBYTE(oUserProtectedRange.m_oType->GetValue()); m_oBcw.WriteItemEnd(nCurPos); } for (size_t i = 0; i < oUserProtectedRange.m_arUsers.size(); ++i) @@ -7294,6 +8284,12 @@ void BinaryWorksheetTableWriter::WriteDataValidation(const OOX::Spreadsheet::CDa m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Variable); m_oBcw.m_oStream.WriteStringW(oDataValidation.m_oFormula2->m_sText); } + if (oDataValidation.m_oList.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_DataValidation::List); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Variable); + m_oBcw.m_oStream.WriteStringW(*oDataValidation.m_oList); + } } void BinaryWorksheetTableWriter::WriteSparklines(const OOX::Spreadsheet::CSparklines& oSparklines) { @@ -7319,6 +8315,120 @@ void BinaryWorksheetTableWriter::WriteSparkline(const OOX::Spreadsheet::CSparkli m_oBcw.m_oStream.WriteStringW (oSparkline.m_oSqRef.get()); } } +void BinaryWorksheetTableWriter::WriteTimelines(OOX::Spreadsheet::CWorksheet& oWorksheet, const OOX::Spreadsheet::CTimelineRefs& oTimelines) +{ + int nCurPos = 0; + for (size_t i = 0; i < oTimelines.m_arrItems.size(); ++i) + { + if (oTimelines.m_arrItems[i] && oTimelines.m_arrItems[i]->m_oRId.IsInit()) + { + smart_ptr pFile = oWorksheet.Find(OOX::RId(oTimelines.m_arrItems[i]->m_oRId->GetValue())); + if (pFile.IsInit() && OOX::Spreadsheet::FileTypes::Timeline == pFile->type()) + { + OOX::Spreadsheet::CTimelineFile* pTimelineFile = static_cast(pFile.GetPointer()); + if (pTimelineFile->m_oTimelines.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerWorksheetsTypes::Timelines); + WriteTimelines(pTimelineFile->m_oTimelines.GetPointer()); + m_oBcw.WriteItemEnd(nCurPos); + } + } + } + } +} +void BinaryWorksheetTableWriter::WriteTimelines(OOX::Spreadsheet::CTimelines* pTimelines) +{ + if (!pTimelines) return; + + int nCurPos = 0; + for (size_t i = 0; i < pTimelines->m_arrItems.size(); ++i) + { + if (pTimelines->m_arrItems[i]) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerWorksheetsTypes::Timeline); + WriteTimeline(pTimelines->m_arrItems[i]); + m_oBcw.WriteItemEnd(nCurPos); + } + } +} +void BinaryWorksheetTableWriter::WriteTimeline(OOX::Spreadsheet::CTimeline* pTimeline) +{ + if (!pTimeline) return; + + if (pTimeline->m_oName.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_Timeline::Name); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Variable); + m_oBcw.m_oStream.WriteStringW(*pTimeline->m_oName); + } + if (pTimeline->m_oCaption.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_Timeline::Caption); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Variable); + m_oBcw.m_oStream.WriteStringW(*pTimeline->m_oCaption); + } + if (pTimeline->m_oUid.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_Timeline::Uid); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Variable); + m_oBcw.m_oStream.WriteStringW(*pTimeline->m_oUid); + } + if (pTimeline->m_oScrollPosition.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_Timeline::ScrollPosition); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Variable); + m_oBcw.m_oStream.WriteStringW(*pTimeline->m_oScrollPosition); + } + if (pTimeline->m_oCache.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_Timeline::Cache); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Variable); + m_oBcw.m_oStream.WriteStringW(*pTimeline->m_oCache); + } + if (pTimeline->m_oSelectionLevel.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_Timeline::SelectionLevel); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Long); + m_oBcw.m_oStream.WriteLONG(*pTimeline->m_oSelectionLevel); + } + if (pTimeline->m_oLevel.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_Timeline::Level); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Long); + m_oBcw.m_oStream.WriteLONG(*pTimeline->m_oLevel); + } + if (pTimeline->m_oShowHeader.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_Timeline::ShowHeader); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(*pTimeline->m_oShowHeader); + } + if (pTimeline->m_oShowSelectionLabel.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_Timeline::ShowSelectionLabel); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(*pTimeline->m_oShowSelectionLabel); + } + if (pTimeline->m_oShowTimeLevel.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_Timeline::ShowTimeLevel); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(*pTimeline->m_oShowTimeLevel); + } + if (pTimeline->m_oShowHorizontalScrollbar.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_Timeline::ShowHorizontalScrollbar); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(*pTimeline->m_oShowHorizontalScrollbar); + } + if (pTimeline->m_oStyle.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_Timeline::Style); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteLONG(pTimeline->m_oStyle->GetValue()); + } +} + void BinaryWorksheetTableWriter::WriteSlicers(OOX::Spreadsheet::CWorksheet& oWorksheet, const OOX::Spreadsheet::CSlicerRefs& oSlicers) { int nCurPos = 0; @@ -7510,12 +8620,12 @@ _UINT32 BinaryFileWriter::Open(const std::wstring& sInputDir, const std::wstring { _UINT32 result = 0; - OOX::CPath path(sFileDst); + OOX::CPath pathDst(sFileDst); //создаем папку для media - std::wstring mediaDir = path.GetDirectory() + L"media"; + std::wstring mediaDir = pathDst.GetDirectory() + L"media"; NSDirectory::CreateDirectory(mediaDir); - pOfficeDrawingConverter->SetDstPath(path.GetDirectory() + FILE_SEPARATOR_STR + L"word"); + pOfficeDrawingConverter->SetDstPath(pathDst.GetDirectory() + FILE_SEPARATOR_STR + L"word"); pOfficeDrawingConverter->SetMediaDstPath(mediaDir); NSBinPptxRW::CBinaryFileWriter& oBufferedStream = *pOfficeDrawingConverter->m_pBinaryWriter; @@ -7527,7 +8637,8 @@ _UINT32 BinaryFileWriter::Open(const std::wstring& sInputDir, const std::wstring UINT nCodePage; std::wstring sDelimiter; BYTE saveFileType; - SerializeCommon::ReadFileType(sXMLOptions, fileType, nCodePage, sDelimiter, saveFileType); + _INT32 Lcid; + SerializeCommon::ReadFileType(sXMLOptions, fileType, nCodePage, sDelimiter, saveFileType, Lcid); m_nLastFilePosOffset = 0; OOX::Spreadsheet::CXlsx *pXlsx = NULL; @@ -7539,7 +8650,7 @@ _UINT32 BinaryFileWriter::Open(const std::wstring& sInputDir, const std::wstring CSVReader csvReader; pXlsx = new OOX::Spreadsheet::CXlsx(); - result = csvReader.Read(sInputDir, *pXlsx, nCodePage, sDelimiter); + result = csvReader.Read(sInputDir, *pXlsx, nCodePage, sDelimiter, Lcid); }break; case BinXlsxRW::c_oFileTypes::XLSX: case BinXlsxRW::c_oFileTypes::XLSB: @@ -7558,11 +8669,18 @@ _UINT32 BinaryFileWriter::Open(const std::wstring& sInputDir, const std::wstring //write dummy header and main table oXlsbWriter.WriteStringUtf8(WriteFileHeader(0, g_nFormatVersionNoBase64)); oXlsbWriter.WriteReserved(GetMainTableSize()); - int nDataStartPos = oXlsbWriter.GetPositionAbsolute(); + int nDataStartPos = oXlsbWriter.GetPositionAbsolute(); + + // retest fileType - 1 || 4 + COfficeFileFormatChecker checker; + if (checker.isOOXFormatFile(sInputDir, true)) + { + fileType = (checker.nFileType == AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSB) ? 4 : 1; + } if (fileType == 1) { - pXlsx->m_pXlsbWriter = &oXlsbWriter; + pXlsx->m_pXlsbWriter = &oXlsbWriter; // todooo xlsb -> xlst without xlsx write folder } //parse pXlsx->Read(OOX::CPath(sInputDir)); @@ -7577,7 +8695,7 @@ _UINT32 BinaryFileWriter::Open(const std::wstring& sInputDir, const std::wstring } }break; } - if (0 != result && AVS_FILEUTILS_ERROR_CONVERT_ROWLIMITS != result) + if (0 != result && AVS_FILEUTILS_ERROR_CONVERT_ROWLIMITS != result && AVS_FILEUTILS_ERROR_CONVERT_CELLLIMITS != result) { RELEASEOBJECT(pXlsx); return result; @@ -7615,7 +8733,7 @@ _UINT32 BinaryFileWriter::Open(const std::wstring& sInputDir, const std::wstring //todo 46 временно CP_UTF8 CSVWriter oCSVWriter; - oCSVWriter.Xlsx2Csv(sFileDst, *pXlsx, 46, std::wstring(L","), true); + oCSVWriter.Xlsx2Csv(sFileDst, *pXlsx, 46, std::wstring(L","), Lcid, true); } else { @@ -7655,7 +8773,7 @@ _UINT32 BinaryFileWriter::Open(const std::wstring& sInputDir, const std::wstring else { int nBase64BufferLen = Base64::Base64EncodeGetRequiredLength(nBinBufferLen, Base64::B64_BASE64_FLAG_NOCRLF); - BYTE* pbBase64Buffer = new BYTE[nBase64BufferLen+64]; + BYTE* pbBase64Buffer = new BYTE[nBase64BufferLen + 64]; if(true == Base64_1::Base64Encode(pbBinBuffer, nBinBufferLen, pbBase64Buffer, &nBase64BufferLen)) { NSFile::CFileBinary oFile; @@ -7670,6 +8788,23 @@ _UINT32 BinaryFileWriter::Open(const std::wstring& sInputDir, const std::wstring } RELEASEARRAYOBJECTS(pbBase64Buffer); } + + if (fileType == BinXlsxRW::c_oFileTypes::XLSB && pXlsx->hasPivot()) + { + std::wstring sDstFileXlsx = pathDst.GetDirectory() + FILE_SEPARATOR_STR + L"Editor.xlsx"; + std::wstring sTempUnpackedXLSX = pathDst.GetDirectory() + FILE_SEPARATOR_STR + L"xlsx_unpacked"; + NSDirectory::CreateDirectory(sTempUnpackedXLSX); + + OOX::CContentTypes oContentTypes; + dynamic_cast(pXlsx)->SetPropForWriteSheet(sTempUnpackedXLSX, oContentTypes); + + if (true == pXlsx->WriteNative(sTempUnpackedXLSX, oContentTypes)) + { + COfficeUtils oOfficeUtils(NULL); + oOfficeUtils.CompressFileOrDirectory(sTempUnpackedXLSX, sDstFileXlsx, true); + } + NSDirectory::DeleteDirectory(sTempUnpackedXLSX); + } } RELEASEOBJECT(pXlsx); @@ -7722,14 +8857,14 @@ void BinaryFileWriter::WriteContent(OOX::Document *pDocument, NSFontCutter::CEmb if(pXlsx && pXlsx->m_pApp) { nCurPos = this->WriteTableStart(c_oSerTableTypes::App); - pXlsx->m_pApp->ToPptxApp()->toPPTY(&m_oBcw->m_oStream); + pXlsx->m_pApp->toPPTY(&m_oBcw->m_oStream); this->WriteTableEnd(nCurPos); } if(pXlsx && pXlsx->m_pCore) { nCurPos = this->WriteTableStart(c_oSerTableTypes::Core); - pXlsx->m_pCore->ToPptxCore()->toPPTY(&m_oBcw->m_oStream); + pXlsx->m_pCore->toPPTY(&m_oBcw->m_oStream); this->WriteTableEnd(nCurPos); } diff --git a/OOXML/Binary/Sheets/Reader/BinaryWriter.h b/OOXML/Binary/Sheets/Reader/BinaryWriter.h index 4bd8fb92fec..f07dd9d740a 100644 --- a/OOXML/Binary/Sheets/Reader/BinaryWriter.h +++ b/OOXML/Binary/Sheets/Reader/BinaryWriter.h @@ -73,6 +73,34 @@ namespace OOX class CTableStyle; class CCellStyle; class CProtection; + class CTimelines; + class CTimeline; + class CTimelineCacheDefinition; + class CTimelinePivotFilter; + class CTimelineState; + class CTimelineRange; + class CTimelineCachePivotTables; + class CTimelineCachePivotTable; + class CTimelineStyle; + class CTimelineStyles; + class CTimelineStyleElement; + + class CMetadata; + class CFutureMetadata; + class CFutureMetadataBlock; + class CMetadataBlocks; + class CMetadataBlock; + class CMetadataRecord; + class CMetadataTypes; + class CMetadataType; + class CMdxMetadata; + class CMdxKPI; + class CMdxMemeberProp; + class CMdxTuple; + class CMdx; + class CMdxSet; + class CMetadataStrings; + class CMetadataStringIndex; } } @@ -145,6 +173,9 @@ namespace BinXlsxRW void WriteTableStyle(const OOX::Spreadsheet::CTableStyle& oTableStyle); void WriteTableStyleElements(const std::vector& aTableStyles); void WriteTableStyleElement(const OOX::Spreadsheet::CTableStyleElement& oTableStyleElement); + void WriteTimelineStyles(OOX::Spreadsheet::CTimelineStyles* pTimelineStyles); + void WriteTimelineStyle(OOX::Spreadsheet::CTimelineStyle* pTimelineStyle); + void WriteTimelineStyleElement(OOX::Spreadsheet::CTimelineStyleElement* pTimelineStyleElement); }; class BinarySharedStringTableWriter { @@ -174,6 +205,7 @@ namespace BinXlsxRW void WriteWorkbookView(const OOX::Spreadsheet::CWorkbookView& workbookView); void WriteDefinedNames(const OOX::Spreadsheet::CDefinedNames& definedNames); void WriteCalcPr(const OOX::Spreadsheet::CCalcPr& CCalcPr); + void WriteConnections(const OOX::Spreadsheet::CConnections& connections); void WriteConnection(const OOX::Spreadsheet::CConnection& connection); void WriteConnectionDbPr(const OOX::Spreadsheet::CDbPr& dbPr); @@ -183,6 +215,7 @@ namespace BinXlsxRW void WriteConnectionTextField(const OOX::Spreadsheet::CTextField& textField); void WriteConnectionWebPr(const OOX::Spreadsheet::CWebPr& webPr); void WriteConnectionRangePr(const OOX::Spreadsheet::CRangePr& rangePr); + void WriteExternalReferences(const OOX::Spreadsheet::CExternalReferences& externalReferences, OOX::Spreadsheet::CWorkbook& workbook); void WriteExternalBook(const OOX::Spreadsheet::CExternalBook& externalBook, OOX::Spreadsheet::CExternalLink* pExternalLink); void WriteExternalAlternateUrls(const OOX::Spreadsheet::CAlternateUrls& alternateUrls, OOX::Spreadsheet::CExternalLink* pExternalLink); @@ -193,6 +226,7 @@ namespace BinXlsxRW void WriteExternalSheetData(const OOX::Spreadsheet::CExternalSheetData& sheetData); void WriteExternalRow(const OOX::Spreadsheet::CExternalRow& row); void WriteExternalCell(const OOX::Spreadsheet::CExternalCell& cell); + void WriteOleLink(const OOX::Spreadsheet::COleLink& oleLink, const std::wstring& sLink); void WriteOleItem(const OOX::Spreadsheet::COleItem& oleItem); void WriteDdeLink(const OOX::Spreadsheet::CDdeLink& ddeLink); @@ -202,6 +236,31 @@ namespace BinXlsxRW void WriteDefinedName(const OOX::Spreadsheet::CDefinedName& definedName); void WriteSlicerCaches(OOX::Spreadsheet::CWorkbook& workbook, const OOX::Spreadsheet::CSlicerCaches& oSlicerCaches); void WriteFileSharing(const OOX::Spreadsheet::CFileSharing& fileSharing); + + void WriteTimelineCaches(OOX::Spreadsheet::CWorkbook& workbook, const OOX::Spreadsheet::CTimelineCacheRefs& oTimelineCacheRefs); + void WriteTimelineCache(OOX::Spreadsheet::CTimelineCacheDefinition* pTimelineCache); + void WriteTimelineState(OOX::Spreadsheet::CTimelineState* pState); + void WriteTimelinePivotFilter(OOX::Spreadsheet::CTimelinePivotFilter* pPivotFilter); + void WriteTimelineCachePivotTables(OOX::Spreadsheet::CTimelineCachePivotTables* pPivotTables); + void WriteTimelineCachePivotTable(OOX::Spreadsheet::CTimelineCachePivotTable* pPivotTable); + void WriteTimelineRange(OOX::Spreadsheet::CTimelineRange* pTimelineRange); + + void WriteMetadata(OOX::Spreadsheet::CMetadata* pMetadata); + void WriteMetadataTypes(OOX::Spreadsheet::CMetadataTypes* pMetadataTypes); + void WriteMetadataType(OOX::Spreadsheet::CMetadataType* pMetadataType); + void WriteMetadataStrings(OOX::Spreadsheet::CMetadataStrings* pMetadataStrings); + void WriteMdxMetadata(OOX::Spreadsheet::CMdxMetadata* pMdxMetadata); + void WriteMdx(OOX::Spreadsheet::CMdx* pMdx); + void WriteMetadataBlocks(OOX::Spreadsheet::CMetadataBlocks* pMetadataBlocks); + void WriteMetadataBlock(OOX::Spreadsheet::CMetadataBlock* pMetadataBlock); + void WriteMetadataRecord(OOX::Spreadsheet::CMetadataRecord* pMetadataRecord); + void WriteFutureMetadata(OOX::Spreadsheet::CFutureMetadata* pMetadata); + void WriteFutureMetadataBlock(OOX::Spreadsheet::CFutureMetadataBlock* pMetadataBlock); + void WriteMdxTuple(OOX::Spreadsheet::CMdxTuple* pMdxTuple); + void WriteMdxSet(OOX::Spreadsheet::CMdxSet* pMdxSet); + void WriteMdxKPI(OOX::Spreadsheet::CMdxKPI* pMdxKPI); + void WriteMdxMemeberProp(OOX::Spreadsheet::CMdxMemeberProp* pMdxMemeberProp); + void WriteMetadataStringIndex(OOX::Spreadsheet::CMetadataStringIndex* pStringIndex); }; class BinaryPersonTableWriter { @@ -306,6 +365,9 @@ namespace BinXlsxRW void WriteUserProtectedRanges(const OOX::Spreadsheet::CUserProtectedRanges& oUserProtectedRanges); void WriteUserProtectedRange(const OOX::Spreadsheet::CUserProtectedRange& oUserProtectedRange); void WriteUserProtectedRangeDesc(const OOX::Spreadsheet::CUserProtectedRange::_UsersGroupsDesc& desc); + void WriteTimelines(OOX::Spreadsheet::CWorksheet& oWorksheet, const OOX::Spreadsheet::CTimelineRefs& oTimelines); + void WriteTimelines(OOX::Spreadsheet::CTimelines* pTimelines); + void WriteTimeline(OOX::Spreadsheet::CTimeline* pTimeline); }; class BinaryCustomsTableWriter { diff --git a/OOXML/Binary/Sheets/Reader/CSVReader.cpp b/OOXML/Binary/Sheets/Reader/CSVReader.cpp index e9f32647fce..0dd68887aed 100644 --- a/OOXML/Binary/Sheets/Reader/CSVReader.cpp +++ b/OOXML/Binary/Sheets/Reader/CSVReader.cpp @@ -54,9 +54,9 @@ class CSVReader::Impl { public: Impl() {} - _UINT32 Read(const std::wstring &sFileName, OOX::Spreadsheet::CXlsx &oXlsx, _UINT32 nCodePage, const std::wstring& wcDelimiter); + _UINT32 Read(const std::wstring &sFileName, OOX::Spreadsheet::CXlsx &oXlsx, _UINT32 nCodePage, const std::wstring& wcDelimiter, _INT32 lcid); private: - void AddCell(std::wstring &sText, INT nStartCell, std::stack &oDeleteChars, OOX::Spreadsheet::CRow &oRow, INT nRow, INT nCol, bool bIsWrap); + int AddCell(std::wstring &sText, INT nStartCell, std::stack &oDeleteChars, OOX::Spreadsheet::CRow &oRow, INT nRow, INT nCol, bool bIsWrap); std::shared_ptr cellFormatController_ = NULL; //--------------------------------------------------------------------------------------------------------- @@ -181,8 +181,10 @@ class CSVReader::Impl } }; //----------------------------------------------------------------------------------------------- -void CSVReader::Impl::AddCell(std::wstring &sText, INT nStartCell, std::stack &oDeleteChars, OOX::Spreadsheet::CRow &oRow, INT nRow, INT nCol, bool bIsWrap) +int CSVReader::Impl::AddCell(std::wstring &sText, INT nStartCell, std::stack &oDeleteChars, OOX::Spreadsheet::CRow &oRow, INT nRow, INT nCol, bool bIsWrap) { + int result = 0; + while (!oDeleteChars.empty()) { INT nIndex = oDeleteChars.top() - nStartCell; @@ -193,19 +195,21 @@ void CSVReader::Impl::AddCell(std::wstring &sText, INT nStartCell, std::stackm_oType.Init(); pCell->m_oCacheValue = sText; // как есть - cellFormatController_->ProcessCellType(pCell, sText, bIsWrap); + result = cellFormatController_->ProcessCellType(pCell, sText, bIsWrap); pCell->setRowCol(nRow, nCol); oRow.m_arrItems.push_back(pCell); + + return result; } -_UINT32 CSVReader::Impl::Read(const std::wstring &sFileName, OOX::Spreadsheet::CXlsx &oXlsx, _UINT32 nCodePage, const std::wstring& sDelimiter) +_UINT32 CSVReader::Impl::Read(const std::wstring &sFileName, OOX::Spreadsheet::CXlsx &oXlsx, _UINT32 nCodePage, const std::wstring& sDelimiter, _INT32 lcid) { NSFile::CFileBinary oFile; if (false == oFile.OpenFile(sFileName)) return AVS_FILEUTILS_ERROR_CONVERT; @@ -215,10 +219,12 @@ _UINT32 CSVReader::Impl::Read(const std::wstring &sFileName, OOX::Spreadsheet::C // Создадим стили oXlsx.CreateStyles(); - cellFormatController_ = std::make_shared(oXlsx.m_pStyles); + cellFormatController_ = std::make_shared(oXlsx.m_pStyles, lcid); smart_ptr pWorksheet(new OOX::Spreadsheet::CWorksheet(NULL)); pWorksheet->m_oSheetData.Init(); + pWorksheet->m_oSheetFormatPr.Init(); + pWorksheet->m_oSheetFormatPr->m_oBaseColWidth = 9; //----------------------------------------------------------------------------------- DWORD nFileSize = 0; @@ -284,8 +290,26 @@ _UINT32 CSVReader::Impl::Read(const std::wstring &sFileName, OOX::Spreadsheet::C WCHAR wcDelimiterLeading = L'\0'; WCHAR wcDelimiterTrailing = L'\0'; int nDelimiterSize = 0; - - if (sDelimiter.length() > 0) + if(sFileDataW.size() > 7 && sFileDataW.substr(0, 4) == L"sep=") + { + wcDelimiterLeading = sFileDataW[4]; + nDelimiterSize = 1; + if (2 == sizeof(wchar_t) && 0xD800 <= wcDelimiterLeading && wcDelimiterLeading <= 0xDBFF &&( sFileDataW[5] != L'\r' || sFileDataW[5] != L'\n')) + { + wcDelimiterTrailing = sFileDataW[5]; + nDelimiterSize = 2; + } + auto newPos = 4 + nDelimiterSize; + if(sFileDataW[newPos] == L'\r' || sFileDataW[newPos] == L'\n') + { + newPos++; + if(sFileDataW[newPos] == L'\r' || sFileDataW[newPos] == L'\n') + newPos++; + } + sFileDataW.erase(0, newPos); + nSize = sFileDataW.length(); + } + else if (sDelimiter.length() > 0) { wcDelimiterLeading = sDelimiter[0]; nDelimiterSize = 1; @@ -307,10 +331,14 @@ _UINT32 CSVReader::Impl::Read(const std::wstring &sFileName, OOX::Spreadsheet::C std::stack oDeleteChars; bool bMsLimit = false; + bool bMsLimitCell = false; + bool bInQuote = false; + INT nIndexRow = 0; INT nIndexCol = 0; OOX::Spreadsheet::CRow *pRow = new OOX::Spreadsheet::CRow(); + pRow->m_oR.Init(); pRow->m_oR->SetValue(nIndexRow + 1); @@ -325,7 +353,11 @@ _UINT32 CSVReader::Impl::Read(const std::wstring &sFileName, OOX::Spreadsheet::C // New Cell std::wstring sCellText(pTemp + nStartCell, nIndex - nStartCell); - AddCell(sCellText, nStartCell, oDeleteChars, *pRow, nIndexRow, nIndexCol++, bIsWrap); + if (1 == AddCell(sCellText, nStartCell, oDeleteChars, *pRow, nIndexRow, nIndexCol++, bIsWrap)) + { + bMsLimitCell = true; + } + oDeleteChars = std::stack(); bIsWrap = false; @@ -357,7 +389,10 @@ _UINT32 CSVReader::Impl::Read(const std::wstring &sFileName, OOX::Spreadsheet::C if (nStartCell != nIndex) { std::wstring sCellText(pTemp + nStartCell, nIndex - nStartCell); - AddCell(sCellText, nStartCell, oDeleteChars, *pRow, nIndexRow, nIndexCol++, bIsWrap); + if (1 == AddCell(sCellText, nStartCell, oDeleteChars, *pRow, nIndexRow, nIndexCol++, bIsWrap)) + { + bMsLimitCell = true; + } bIsWrap = false; } @@ -427,7 +462,10 @@ _UINT32 CSVReader::Impl::Read(const std::wstring &sFileName, OOX::Spreadsheet::C else nSize--; } std::wstring sCellText(pTemp + nStartCell, nSize - nStartCell); - AddCell(sCellText, nStartCell, oDeleteChars, *pRow, nIndexRow, nIndexCol++, bIsWrap); + if (1 == AddCell(sCellText, nStartCell, oDeleteChars, *pRow, nIndexRow, nIndexCol++, bIsWrap)) + { + bMsLimitCell = true; + } pWorksheet->m_oSheetData->m_arrItems.push_back(pRow); } else @@ -452,7 +490,7 @@ _UINT32 CSVReader::Impl::Read(const std::wstring &sFileName, OOX::Spreadsheet::C oXlsx.m_pWorkbook->m_oSheets.Init(); oXlsx.m_pWorkbook->m_oSheets->m_arrItems.push_back(pSheet); - return bMsLimit ? AVS_FILEUTILS_ERROR_CONVERT_ROWLIMITS : 0; + return bMsLimit ? AVS_FILEUTILS_ERROR_CONVERT_ROWLIMITS : (bMsLimitCell ? AVS_FILEUTILS_ERROR_CONVERT_CELLLIMITS : 0); } //---------------------------------------------------------------------------------- CSVReader::CSVReader() : impl_(new CSVReader::Impl()) @@ -461,7 +499,7 @@ CSVReader::CSVReader() : impl_(new CSVReader::Impl()) CSVReader::~CSVReader() { } -_UINT32 CSVReader::Read(const std::wstring &sFileName, OOX::Spreadsheet::CXlsx &oXlsx, _UINT32 nCodePage, const std::wstring& sDelimiter) +_UINT32 CSVReader::Read(const std::wstring &sFileName, OOX::Spreadsheet::CXlsx &oXlsx, _UINT32 nCodePage, const std::wstring& sDelimiter, _INT32 lcid) { - return impl_->Read(sFileName, oXlsx, nCodePage, sDelimiter); + return impl_->Read(sFileName, oXlsx, nCodePage, sDelimiter, lcid); } diff --git a/OOXML/Binary/Sheets/Reader/CSVReader.h b/OOXML/Binary/Sheets/Reader/CSVReader.h index ac8b013a453..c2a2da9b9bf 100644 --- a/OOXML/Binary/Sheets/Reader/CSVReader.h +++ b/OOXML/Binary/Sheets/Reader/CSVReader.h @@ -49,7 +49,7 @@ class CSVReader public: CSVReader(); ~CSVReader(); - _UINT32 Read(const std::wstring &sFileName, OOX::Spreadsheet::CXlsx &oXlsx, _UINT32 nCodePage, const std::wstring& wcDelimiter); + _UINT32 Read(const std::wstring &sFileName, OOX::Spreadsheet::CXlsx &oXlsx, _UINT32 nCodePage, const std::wstring& wcDelimiter, _INT32 lcid); private: class Impl; boost::shared_ptr impl_; diff --git a/OOXML/Binary/Sheets/Reader/CellFormatController/CellFormatController.cpp b/OOXML/Binary/Sheets/Reader/CellFormatController/CellFormatController.cpp index 265c6ae7f89..5618d69ab91 100644 --- a/OOXML/Binary/Sheets/Reader/CellFormatController/CellFormatController.cpp +++ b/OOXML/Binary/Sheets/Reader/CellFormatController/CellFormatController.cpp @@ -41,13 +41,64 @@ #include #include #include +#include const std::wstring DefaultDateFormat = L"dd.mm.yyyy"; +const std::wstring DefaultTimeFormat = L"h:mm"; +const std::wstring DefaultDateTimeFormat = L"m/d/yy h:mm"; const std::wstring DefaultPercentFormat = L"0.0%"; const std::wstring DefaultDollarFormat = L"#,##0.00$"; -CellFormatController::CellFormatController(OOX::Spreadsheet::CStyles *styles): - m_pStyles{styles} +std::map defaultDataFormats +{ + {DefaultDateFormat, 14}, + {L"d-mmm-yy", 15}, + {L"d-mmm", 16}, + {L"mmm-yy", 17}, + {DefaultDateTimeFormat, 22}, + {DefaultTimeFormat, 20} +}; + +class FormulaController +{ +public: + static std::wstring shielding_text(boost::wsmatch const& what); + static std::vector> mapReplacements; + + static void replace_text_back(std::wstring& expr) + { + for (auto key : mapReplacements.back()) + { + XmlUtils::replace_all(expr, key.first, key.second); + } + return; + } + static void replace_text(std::wstring& expr) + { + //std::random_device genSource; + //std::uniform_int_distribution<> generator(0, 23); + //for (int index = 0; index < 5; index++) + //{ + // key += wchar_t(L'a' + generator(genSource)); + //} + + std::wstring key = L"aaaaaaaaaaaaaaaaaaaaaaaa"; + for (unsigned i = 0; i < 23; ++i) + { + unsigned j = rand() % (i + 1); + key[i] = key[j]; + key[j] = wchar_t(L'a' + i); + } + mapReplacements.back().insert(std::make_pair(key, expr)); + expr = key; + } +}; +std::vector> FormulaController::mapReplacements; + +//--------------------------------------------------------------------------------------------------------------------- + +CellFormatController::CellFormatController(OOX::Spreadsheet::CStyles *styles, _INT32 lcid): + m_pStyles{styles}, lcid_{lcid} { // Добавим стили для wrap-а m_pStyles->m_oCellXfs.Init(); @@ -76,11 +127,14 @@ CellFormatController::CellFormatController(OOX::Spreadsheet::CStyles *styles): m_pStyles->m_oCellXfs->m_arrItems.push_back(pXfs); createFormatStyle(DefaultDateFormat); + createFormatStyle(DefaultDateTimeFormat); + createFormatStyle(DefaultTimeFormat); createFormatStyle(DefaultPercentFormat); } -void CellFormatController::ProcessCellType(OOX::Spreadsheet::CCell *pCell, const std::wstring &value, bool bIsWrap) +int CellFormatController::ProcessCellType(OOX::Spreadsheet::CCell *pCell, const std::wstring &value, bool bIsWrap) { + int result = 0; // ok pCell_ = pCell; /// формат для булева значения в верхнем регистре @@ -92,19 +146,52 @@ void CellFormatController::ProcessCellType(OOX::Spreadsheet::CCell *pCell, const auto tempValue = value; std::transform(tempValue.begin(), tempValue.end(), tempValue.begin(), [](unsigned char c) { return std::toupper(c); }); + pText->m_sText = tempValue; pCell_->m_oRichText->m_arrItems.push_back(pText); - return; + + return result; } DigitReader digits = {}; std::wstring digitFormat = {}; std::wstring digitValue = {}; - if(digits.ReadDigit(value, digitValue, digitFormat)) + + if(digits.ReadScientific(value, digitValue, digitFormat)) { if(!pCell_->m_oValue.IsInit()) { pCell_->m_oValue.Init(); + }// + pCell_->m_oValue->m_sText = digitValue; + std::map::iterator pFind = mapDataNumber_.find(digitFormat); + if (pFind != mapDataNumber_.end()) + { + pCell_->m_oStyle = pFind->second; + } + else + { + if (!m_pStyles->m_oNumFmts.IsInit()) + { + m_pStyles->m_oNumFmts.Init(); + } + if(!digitFormat.empty()) + { + createFormatStyle(digitFormat); + pCell_->m_oStyle = mapDataNumber_.at(digitFormat); + } + } + if (bIsWrap) + { + pCell_->m_oStyle = 1; } + return result; + } + else if(digits.ReadDigit(value, digitValue, digitFormat)) + { + if(!pCell_->m_oValue.IsInit()) + { + pCell_->m_oValue.Init(); + } pCell_->m_oValue->m_sText = digitValue; std::map::iterator pFind = mapDataNumber_.find(digitFormat); if (pFind != mapDataNumber_.end()) @@ -128,35 +215,67 @@ void CellFormatController::ProcessCellType(OOX::Spreadsheet::CCell *pCell, const { pCell_->m_oStyle = 1; } - return; + return result; } - DateReader dateReader = {}; - _INT32 digitalDate = 0; - auto validDate = dateReader.GetDigitalDate(value, digitalDate); - if(validDate) + DateReader dateReader = {lcid_}; + double digitalDate = 0; + bool hasDate = false; + bool hasTime = false; + + auto validDate = dateReader.GetDigitalDate(value, digitalDate, hasDate, hasTime); + if (validDate) { if(!pCell_->m_oValue.IsInit()) { pCell_->m_oValue.Init(); } - pCell_->m_oValue->m_sText = std::to_wstring(digitalDate); - std::map::iterator pFind = mapDataNumber_.find(DefaultDateFormat); - pCell_->m_oStyle = pFind->second; + if(hasDate && !hasTime) + { + pCell_->m_oValue->m_sText = std::to_wstring((_INT32)digitalDate); + std::map::iterator pFind = mapDataNumber_.find(DefaultDateFormat); + pCell_->m_oStyle = pFind->second; + } + else if(!hasDate && hasTime) + { + pCell_->m_oValue->m_sText = std::to_wstring(digitalDate); + std::map::iterator pFind = mapDataNumber_.find(DefaultTimeFormat); + pCell_->m_oStyle = pFind->second; + } + else if(hasDate && hasTime) + { + pCell_->m_oValue->m_sText = std::to_wstring(digitalDate); + std::map::iterator pFind = mapDataNumber_.find(DefaultDateTimeFormat); + pCell_->m_oStyle = pFind->second; + } } else { + std::wstring sFormula; if (value[0] == L'='/* && bCalcFormulas*/) { - pCell_->m_oFormula.Init(); - pCell_->m_oFormula->m_sText = value; + sFormula = ConvertFormulaArguments(value.substr(1)); + } + if (false == sFormula.empty()) + { + pCell_->m_oFormula.Init(); + pCell_->m_oFormula->m_sText = sFormula; } else { pCell_->m_oType->SetValue(SimpleTypes::Spreadsheet::celltypeInlineStr); pCell_->m_oRichText.Init(); OOX::Spreadsheet::CText *pText = new OOX::Spreadsheet::CText(); - pText->m_sText = value; + + if (value.length() > 32767) + { + pText->m_sText = value.substr(0, 32767); + result = 1; // limit + } + else + { + pText->m_sText = value; + } pCell_->m_oRichText->m_arrItems.push_back(pText); } } @@ -165,28 +284,83 @@ void CellFormatController::ProcessCellType(OOX::Spreadsheet::CCell *pCell, const { pCell_->m_oStyle = 1; } + return result; +} +std::wstring FormulaController::shielding_text(boost::wsmatch const& what) +{ + if (what[1].matched) + { + std::wstring inner = what[1].str(); + replace_text(inner); + return inner; + } + else if (what[2].matched) + { + std::wstring inner = what[2].str(); + replace_text(inner); + return inner; + } + else if (what[3].matched) + return what[3].str(); + return L""; } +bool CellFormatController::isFormula(const std::wstring& formula) +{ + if (std::wstring::npos != formula.find(L"=")) return false; -void CellFormatController::createFormatStyle(const std::wstring &format) + // ... + return true; +} +std::wstring CellFormatController::ConvertFormulaArguments(const std::wstring& formula) { - if (!m_pStyles->m_oNumFmts.IsInit()) + FormulaController controller; + controller.mapReplacements.emplace_back(); + + std::wstring res = boost::regex_replace( + formula, + boost::wregex(L"('.*?')|(\".*?\")"), + &FormulaController::shielding_text, boost::match_default | boost::format_all); + + if (true == isFormula(res)) + { + XmlUtils::replace_all(res, L";", L","); // in {} ? ->shielding + + controller.replace_text_back(res); + } + else { - m_pStyles->m_oNumFmts.Init(); + res.clear(); } - m_pStyles->m_oNumFmts->m_arrItems.push_back(new OOX::Spreadsheet::CNumFmt()); - m_pStyles->m_oNumFmts->m_arrItems.back()->m_oFormatCode = format; - m_pStyles->m_oNumFmts->m_arrItems.back()->m_oNumFmtId.Init(); - m_pStyles->m_oNumFmts->m_arrItems.back()->m_oNumFmtId->SetValue(164 + m_pStyles->m_oNumFmts->m_arrItems.size()); + controller.mapReplacements.pop_back(); + return res; +} +void CellFormatController::createFormatStyle(const std::wstring &format) +{ + auto prepareFormat = defaultDataFormats.find(format); + if(prepareFormat == defaultDataFormats.end()) + { + if (!m_pStyles->m_oNumFmts.IsInit()) + { + m_pStyles->m_oNumFmts.Init(); + } + m_pStyles->m_oNumFmts->m_arrItems.push_back(new OOX::Spreadsheet::CNumFmt()); + m_pStyles->m_oNumFmts->m_arrItems.back()->m_oFormatCode = format; + m_pStyles->m_oNumFmts->m_arrItems.back()->m_oNumFmtId.Init(); + m_pStyles->m_oNumFmts->m_arrItems.back()->m_oNumFmtId->SetValue(164 + m_pStyles->m_oNumFmts->m_arrItems.size()); + } // Normal + data format OOX::Spreadsheet::CXfs* pXfs = new OOX::Spreadsheet::CXfs(); pXfs->m_oBorderId.Init(); pXfs->m_oBorderId->SetValue(0); pXfs->m_oFillId.Init(); pXfs->m_oFillId->SetValue(0); pXfs->m_oFontId.Init(); pXfs->m_oFontId->SetValue(0); - pXfs->m_oNumFmtId.Init(); pXfs->m_oNumFmtId->SetValue(m_pStyles->m_oNumFmts->m_arrItems.back()->m_oNumFmtId->GetValue()); - + pXfs->m_oNumFmtId.Init(); + if(prepareFormat == defaultDataFormats.end()) + pXfs->m_oNumFmtId->SetValue(m_pStyles->m_oNumFmts->m_arrItems.back()->m_oNumFmtId->GetValue()); + else + pXfs->m_oNumFmtId->SetValue(prepareFormat->second); m_pStyles->m_oCellXfs->m_arrItems.push_back(pXfs); auto styleNum = (unsigned int)(m_pStyles->m_oCellXfs->m_arrItems.size() - 1); diff --git a/OOXML/Binary/Sheets/Reader/CellFormatController/CellFormatController.h b/OOXML/Binary/Sheets/Reader/CellFormatController/CellFormatController.h index 2028f4fae1b..a13418c4486 100644 --- a/OOXML/Binary/Sheets/Reader/CellFormatController/CellFormatController.h +++ b/OOXML/Binary/Sheets/Reader/CellFormatController/CellFormatController.h @@ -44,15 +44,16 @@ class CellFormatController public: /// @brief конструктор /// @param styles стили из таблицы - CellFormatController(OOX::Spreadsheet::CStyles *styles); + CellFormatController(OOX::Spreadsheet::CStyles *styles, _INT32 lcid); /// @brief обрабатывает вставляемые в ячейку таблицы данные, переводя их в нужный тип, и заполняет ими ячейку /// @param pCell указатель на ячейку /// @param value вставляемые в ячейку данные в строковом типе - void ProcessCellType(OOX::Spreadsheet::CCell *pCell, const std::wstring &value, bool bIsWrap = false); + int ProcessCellType(OOX::Spreadsheet::CCell *pCell, const std::wstring &value, bool bIsWrap = false); private: - + bool isFormula(const std::wstring& formula); + std::wstring ConvertFormulaArguments(const std::wstring& formula); /// @brief создание стиля для указанного формата /// @param format формат значения void createFormatStyle(const std::wstring &format); @@ -69,4 +70,6 @@ class CellFormatController /// @brief указатель на полученное строковое значение const std::wstring *value_; + /// @brief идентификатор локали + _INT32 lcid_; }; diff --git a/OOXML/Binary/Sheets/Reader/CellFormatController/CurrencyReader.cpp b/OOXML/Binary/Sheets/Reader/CellFormatController/CurrencyReader.cpp index 3d7c3793437..ac62a5a1347 100644 --- a/OOXML/Binary/Sheets/Reader/CellFormatController/CurrencyReader.cpp +++ b/OOXML/Binary/Sheets/Reader/CellFormatController/CurrencyReader.cpp @@ -50,7 +50,82 @@ const std::set CurrencySymbols = { L"\u20B1", // Филиппинское песо L"\u20B9", // Индийская рупия L"\u20AA", // Израильский новый шекель - L"\u20A7" // Испанская песета + L"\u20A7", // Испанская песета + L"\u0631.\u0633.", //Саудовский риал + L"kr.", + L"Ft", + L"\u20A9", // Корейская вона + L"\u007a\u0142",// Польский злотый + L"R\u0024", + L"kr", + L"\u20BA", //Турецкая лира + L"\u20B4",//Украинская гривна + L"\u20AB", //Вьетнамский донг + L"\u20BC", //Азербайджанский манат + L"\u20AE", //Монгольский тугрик + L"\u043B\u0432.", //Болгарский лев + L"NT\u0024", + L"\u004B\u010D", //Чешская крона + L"Rp", + L"\u062F.\u0639.‏", //Иракский динар + L"L", + L"\u062C.\u0645.‏", // Египетский фунт + L"HK\u0024", + L"\u062F.\u0644.‏", // Ливийский динар + L"Q", + L"KM", + L"\u062F.\u062C.‏", // Алжирский динар + L"\u20A1", //Колон Сальвадора и Коста-рики + L"B/.", + L"\u062F.\u062A.‏", //Тунисский динар + L"R", + L"EC\u0024", + L"\u0631.\u0639.‏", //Оманский риал + L"Bs.S", + L"\u0631.\u064A.‏", //Йеменский риал + L"FC", + L"RSD", + L"\u0434\u0438\u043D.", //сирийский динар + L"\u062F.\u0627.‏", //Дирхам ОАЭ + L"FCFA", + L"\u0644.\u0644.‏", //Ливанский фунт + L"US\u0024", + L"CFA", + L"\u062F.\u0643.‏", //Кувейтский динар + L"\u20B1", // Филлипинское песо + L"\u062F.\u0625.‏", //Иорданский динар + L"DH", + L"\u062F.\u0628.‏", //Бахрейнский динар + L"\u20B2", //Парагвайский гуарани + L"G", + L"\u0631.\u0648.‏", //Катарский риал + L"Bs", + L"RM", + L"C\u0024", + + /// additional symbols + L"ADP", L"AED", L"AFA", L"AFN", L"ALL", L"AMD", L"ANG", L"AOA", L"ARS", L"ATS", L"AUD", + L"AWG", L"AZM", L"AZN", L"BAM", L"BBD", L"BDT", L"BEF", L"BGL", L"BGN", L"BHD", L"BIF", + L"BMD", L"BND", L"BOB", L"BOV", L"BRL", L"BSD", L"BTN", L"BWP", L"BYB", L"BYN", L"BYR", + L"BZD", L"CAD", L"CDF", L"CHE", L"CHF", L"CHW", L"CLF", L"CLP", L"CNY", L"COP", L"COU", + L"CRC", L"CSD", L"CUC", L"CUP", L"CVE", L"CYP", L"CZK", L"DEM", L"DJF", L"DKK", L"DOP", + L"DZD", L"ECS", L"ECV", L"EEK", L"EGP", L"ERN", L"ESP", L"ETB", L"EUR", L"FIM", L"FJD", + L"FKP", L"FRF", L"GBP", L"GEL", L"GHC", L"GHS", L"GIP", L"GMD", L"GNF", L"GRD", L"GTQ", + L"GYD", L"HKD", L"HNL", L"HRK", L"HTG", L"HUF", L"IDR", L"IEP", L"ILS", L"INR", L"IQD", + L"IRR", L"ISK", L"ITL", L"JMD", L"JOD", L"JPY", L"KAF", L"KES", L"KGS", L"KHR", L"KMF", + L"KPW", L"KRW", L"KWD", L"KYD", L"KZT", L"LAK", L"LBP", L"LKR", L"LRD", L"LSL", L"LTL", + L"LUF", L"LVL", L"LYD", L"MAD", L"MDL", L"MGA", L"MGF", L"MKD", L"MMK", L"MNT", L"MOP", + L"MRO", L"MRU", L"MTL", L"MUR", L"MVR", L"MWK", L"MXN", L"MXV", L"MYR", L"MZM", L"MZN", + L"NAD", L"NGN", L"NIO", L"NLG", L"NOK", L"NPR", L"NTD", L"NZD", L"OMR", L"PAB", L"PEN", + L"PGK", L"PHP", L"PKR", L"PLN", L"PTE", L"PYG", L"QAR", L"ROL", L"RON", L"RSD", L"RUB", + L"RUR", L"RWF", L"SAR", L"SBD", L"SCR", L"SDD", L"SDG", L"SDP", L"SEK", L"SGD", L"SHP", + L"SIT", L"SKK", L"SLL", L"SOS", L"SPL", L"SRD", L"SRG", L"STD", L"SVC", L"SYP", L"SZL", + L"THB", L"TJR", L"TJS", L"TMM", L"TMT", L"TND", L"TOP", L"TRL", L"TRY", L"TTD", L"TWD", + L"TZS", L"UAH", L"UGX", L"USD", L"USN", L"USS", L"UYI", L"UYU", L"UZS", L"VEB", L"VEF", + L"VES", L"VND", L"VUV", L"WST", L"XAF", L"XAG", L"XAU", L"XB5", L"XBA", L"XBB", L"XBC", + L"XBD", L"XCD", L"XDR", L"XFO", L"XFU", L"XOF", L"XPD", L"XPF", L"XPT", L"XTS", L"XXX", + L"YER", L"YUM", L"ZAR", L"ZMK", L"ZMW", L"ZWD", L"ZWL", L"ZWN", L"ZWR" + }; bool CurrencyReader::CheckPostfix(const std::wstring &postfix) @@ -64,11 +139,29 @@ std::wstring CurrencyReader::GetCurrencyFormat(const std::wstring &inputFormat,c std::wstring format; if(!inputFormat.empty()) { - format = inputFormat + currency; + format = inputFormat; + if(currency.at(0) >= L'\u0600' && currency.at(0) <= L'\u06FF') + { + + format += + L'\u200E'; + format += currency + L'\u200F'; + //format+= L'\u200E'; + } + else + format += currency; } else { - format = CurrencyFormatTemplate + currency; + format = CurrencyFormatTemplate; + if(currency.at(0) >= L'\u0600' && currency.at(0) <= L'\u06FF') + { + + format += + L'\u200E'; + format += currency + L'\u200F'; + //format+= L'\u200E'; + } + else + format += currency; } return format; -} \ No newline at end of file +} diff --git a/OOXML/Binary/Sheets/Reader/CellFormatController/DateReader.cpp b/OOXML/Binary/Sheets/Reader/CellFormatController/DateReader.cpp index 41db554ed56..d20f6af7a5d 100644 --- a/OOXML/Binary/Sheets/Reader/CellFormatController/DateReader.cpp +++ b/OOXML/Binary/Sheets/Reader/CellFormatController/DateReader.cpp @@ -1,4 +1,4 @@ -/* +/* * (c) Copyright Ascensio System SIA 2010-2023 * * This program is a free software product. You can redistribute it and/or @@ -31,57 +31,480 @@ */ #include "DateReader.h" +#include "LocalInfo.h" -#include +#include #include -#include -#include -#include -#include #include #include +#include - // Определение основных форматов даты -std::vector DateFormats = { - L"%d.%m.%Y", L"%d.%m.%y", L"%Y-%m-%d", L"%m/%d/%Y", - L"%m/%d/%y", L"%d %B %Y", L"%d %B, %Y", L"%d %b %Y", - L"%d %b, %Y", L"%B %d %Y", L"%B %d, %Y", L"%b %d %Y", - L"%b %d, %Y", L"%Y/%m/%d", L"%Y/%d/%m", L"%m-%d-%Y", - L"%m-%d-%y", L"%d-%m-%Y", L"%d-%m-%y" +DateReader::DateReader(_INT32 lcid):lcid_{lcid} +{} + +bool DateReader::GetDigitalDate(const std::wstring &date, double &result, bool &Hasdate, bool &Hastime) +{ + + tm time = {}; + if(!parseIsoDate(date,time)) + { + if(!parseLocalDate(date, time, Hasdate, Hastime )) + return false; + } + else + { + Hasdate = true; + Hastime = true; + } + + //дата без времени + if(time.tm_year > 0 && time.tm_hour == 0 && time.tm_min == 0 && time.tm_sec == 0) + { + //определяем стандартная ли дата + if(time.tm_year >= 70) + result = getStandartDate(time); + else + result = getNonUnixDate(time); + Hasdate = true; + Hastime = false; + return true; + } + //время без даты + else if(time.tm_year == 0 && time.tm_mday == 0 && time.tm_mon == 0) + { + result = getStandartTime(time); + Hasdate = false; + Hastime = true; + return true; + } + else //дата и время + { + + if(time.tm_year >= 70) + result = getStandartDate(time); + else + result = getNonUnixDate(time); + result += getStandartTime(time); + Hasdate = true; + Hastime = true; + return true; + } + } + +bool tryGetInt(std::vector &data, _INT32 &value) +{ + try + { + value = std::stoi(std::wstring(data.begin(), data.end())); + return true; + } + catch (std::exception) + { + return false; + } +} + + +enum class DateElemTypes +{ + none = 0, + letter, + digit, + delimeter, + space }; -bool DateReader::GetDigitalDate(const std::wstring &date, _INT32 &result) +enum class ParsingElem { - // Перебор форматов даты, пока не найдется подходящий - for (const auto& format : DateFormats) { - std::wistringstream ss(date); + none = 0, + date, + time +}; - tm time = {}; - ss >> std::get_time(&time, format.c_str()); - if (ss.fail()) { - continue; +void SetDateElem(tm &result, _INT32 value, const std::wstring datePattern, bool &day, bool &month, bool &year, bool &Berror) +{ + for(auto dateFmtPart : datePattern) + { + if((dateFmtPart == L'0' || dateFmtPart == L'1') && !day && value <= 31) + { + day = true; + result.tm_mday = value; + return; + } + else if((dateFmtPart == L'2' || dateFmtPart == L'3') && !month && value <= 12) + { + month = true; + result.tm_mon = value; + return; + } + else if((dateFmtPart == L'4' || dateFmtPart == L'5') && !year) + { + year = true; + result.tm_year = value; + return; } + } + Berror = true; +} - //определяем стандартная ли дата +void SetTimeElem(tm &result, _INT32 value, bool &BHour, bool &bMin, bool &bSec, bool &Berror) +{ + if(!BHour) + { + result.tm_hour = value; + BHour = true; + } + else if (!bMin) + { + result.tm_min = value; + bMin = true; + } + else if (!bSec) + { + result.tm_sec = value; + bSec = true; + } + else + Berror = true; +} + +std::wstring spaceCut(const std::wstring &str) +{ + auto first = str.find_first_not_of(L' '); + if (first == std::wstring::npos) return L""; + auto last = str.find_last_not_of(' '); + return str.substr(first, last - first + 1); +} + +std::set separators = {L'.', L'/', L'-', L':'}; - if(time.tm_year > 0) +bool DateReader::parseLocalDate(const std::wstring &date, tm &result, bool &Hasdate, bool &Hastime) +{ + bool bError = false; + auto locInf = lcInfo::getLocalInfo(lcid_); + ParsingElem parsingNow = ParsingElem::none; + auto cutteddateStr = spaceCut(date); + + //разделитель времени отличается только в нескольких локалях + wchar_t timeSeparator = L':'; + if(lcid_ == 1035 || lcid_ == 11) + timeSeparator = L'.'; + + //флаги собранных частей даты + bool bSec = false; + bool bMin = false; + bool bHour = false; + bool BDay = false; + bool Bmonth = false; + bool Byear = false; + + DateElemTypes CurrentElementType = DateElemTypes::none; + DateElemTypes PrevType = DateElemTypes::none; + std::vector StringBuf; + + //посимвольно парсим дату + for(auto i = 0; i < cutteddateStr.length(); i++) + { + auto charElement = cutteddateStr.at(i); + DateElemTypes elementType; + if(charElement == L' ' || charElement == L' ') + elementType = DateElemTypes::space; + else if(charElement >= L'0' && charElement<= L'9') + elementType = DateElemTypes::digit; + else if(separators.find(charElement) != separators.end()) + elementType = DateElemTypes::delimeter; + else + elementType = DateElemTypes::letter; + if(CurrentElementType == DateElemTypes::none)//первый проход { - result = getStandartDate(time); - return true; + StringBuf.push_back(charElement); } - return false; + else + { + if(CurrentElementType == elementType) + { + //проверяем валидность размеров элементов даты + if(elementType == DateElemTypes::digit && StringBuf.size() < 4) + { + StringBuf.push_back(charElement); + } + else if(elementType == DateElemTypes::letter && StringBuf.size() < 9) + { + StringBuf.push_back(charElement); + } + else if(elementType == DateElemTypes::space) + { + } + else + { + bError = true; + } + } + else + { + if(CurrentElementType == DateElemTypes::digit && elementType == DateElemTypes::delimeter) + { + if(timeSeparator != locInf.DateSeparator[0]) + { + //парсим часть даты + _INT32 datePart; + if(!tryGetInt(StringBuf, datePart)) + { + return false; + } + StringBuf.clear(); + if(charElement == timeSeparator) + { + Hastime = true; + parsingNow = ParsingElem::time; + SetTimeElem(result, datePart, bHour, bMin, bSec, bError); + } + else + { + Hasdate = true; + parsingNow = ParsingElem::date; + SetDateElem(result, datePart, locInf.ShortDatePattern, BDay, Bmonth, Byear, bError); + } + + } + ///todo вариант когда и дата и время разделяются "." + } + if(CurrentElementType == DateElemTypes::letter && elementType == DateElemTypes::delimeter) + { + if(!parseAmPm(StringBuf, result)) + { + if(parseMonthName(StringBuf, result)) + Bmonth = true; + else + bError = true; + } + StringBuf.clear(); + } + else if((CurrentElementType == DateElemTypes::delimeter || CurrentElementType == DateElemTypes::space) && elementType != DateElemTypes::space) + { + //просто добавляем в буфер то что было за разделителем + StringBuf.push_back(charElement); + } + else if(elementType== DateElemTypes::space) + { + if(CurrentElementType == DateElemTypes::digit) + { + _INT32 datePart; + if(!tryGetInt(StringBuf, datePart)) + { + return false; + } + StringBuf.clear(); + if(parsingNow == ParsingElem::time) + { + SetTimeElem(result, datePart, bHour, bMin, bSec, bError); + parsingNow = ParsingElem::none; + } + else if (parsingNow == ParsingElem::date) + SetDateElem(result, datePart, locInf.ShortDatePattern, BDay, Bmonth, Byear, bError); + else + { + Hasdate = true; + parsingNow = ParsingElem::date; + SetDateElem(result, datePart, locInf.ShortDatePattern, BDay, Bmonth, Byear, bError); + } + } + if(CurrentElementType == DateElemTypes::letter) + { + // если это не am pm то в дате может быть буквенным только имя месяца + if(!parseAmPm(StringBuf, result)) + { + if(parseMonthName(StringBuf, result)) + Bmonth = true; + else + bError = true; + } + StringBuf.clear(); + } + } + //анализируем собранный элемент + PrevType = CurrentElementType; + } + } + CurrentElementType = elementType; + + if(bError) + return false; + } + //анализируем последний элемент в буфере + if(parsingNow == ParsingElem::date) + { + if(CurrentElementType == DateElemTypes::digit) + { + _INT32 datePart; + if(!tryGetInt(StringBuf, datePart)) + { + return false; + } + SetDateElem(result, datePart, locInf.ShortDatePattern, BDay, Bmonth, Byear, bError); + } + } + else + { + if(CurrentElementType == DateElemTypes::digit) + { + _INT32 datePart; + if(!tryGetInt(StringBuf, datePart)) + { + return false; + } + SetTimeElem(result, datePart, bHour, bMin, bSec, bError); + } + else if(CurrentElementType == DateElemTypes::letter) + { + if(!parseAmPm(StringBuf, result)) + { + if(parseMonthName(StringBuf, result)) + Bmonth = true; + } + StringBuf.clear(); + } + } + //нормализуем год если он есть + if(Hasdate) + { + result.tm_mon--; + result.tm_year = normalizeYear(result.tm_year); } + if(!Hasdate && !Hastime) + return false; - // Если не найден подходящий формат даты, возвращаем false - return false; + return true; } - -_INT32 DateReader::getStandartDate(tm &date) +bool DateReader::parseIsoDate(const std::wstring &date, tm &result) +{ + //проверка размера строки и разделителей + if(date.size() != 20 || date[4] != L'-' || date[7] != L'-' || + date[10] != L'T' || date[13] != L':' || + date[16] != L':' || date[19] != L'Z') + return false; + //проверка того что между разделителями стоят только цифры + for(auto i = 0; i < 4; i++) + if(!std::iswdigit(date[i])) + return false; + for(auto i = 5; i < 7; i++) + if(!std::iswdigit(date[i])) + return false; + for(auto i = 8; i < 10; i++) + if(!std::iswdigit(date[i])) + return false; + for(auto i = 11; i < 13; i++) + if(!std::iswdigit(date[i])) + return false; + for(auto i = 14; i < 16; i++) + if(!std::iswdigit(date[i])) + return false; + for(auto i = 17; i < 19; i++) + if(!std::iswdigit(date[i])) + return false; + _INT16 year = std::stoi(date.substr(0,4)); + result.tm_year = normalizeYear(year); + result.tm_mon = std::stoi(date.substr(5,2)) - 1; + result.tm_mday = std::stoi(date.substr(8,2)); + result.tm_hour = std::stoi(date.substr(11,2)); + result.tm_min = std::stoi(date.substr(14,2)); + result.tm_sec = std::stoi(date.substr(17,2)); + return true; +} +_INT32 DateReader::getStandartDate(tm date) { + // обнуление времени, чтобы оно не влияло на дату + date.tm_hour = 0; + date.tm_min = 0; + date.tm_sec = 0; // Преобразование даты в формат excel - auto tp = std::chrono::system_clock::from_time_t(mktime(&date)); - auto excelTime = (tp.time_since_epoch().count() / 10000000) + 2209161600; + auto timeT = mktime(&date); + auto tp = std::chrono::system_clock::from_time_t(timeT); + auto excelTime = std::chrono::duration_cast(tp.time_since_epoch()).count(); + excelTime += 2209161600; _INT32 tempTime = round(excelTime / 86400.0); return tempTime; -} \ No newline at end of file +} + +double DateReader::getStandartTime(tm date) +{ + if(date.tm_hour == 24) + date.tm_hour = 0; + double result = ((date.tm_sec + (60 * date.tm_min) + (3600*date.tm_hour))/ 86400.0); + return result; +} + + +// Функция для определения високосного года +bool isLeapYear(int year) { + return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0); +} + +_INT32 DateReader::getNonUnixDate(tm date) +{ + const int daysInMonth[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; + + long days = 1; + + // Добавляем количество дней за предыдущие годы + for (int year = 1900; year < date.tm_year + 1900; ++year) { + days += isLeapYear(year) ? 366 : 365; + } + + // Добавляем количество дней до начала текущего года + for (int month = 0; month < date.tm_mon; ++month) { + days += daysInMonth[month]; + if (month == 1 && isLeapYear(date.tm_year + 1900)) + days++; // добавляем 1 день для февраля в високосном году + } + + // Добавляем количество дней текущего месяца + days += date.tm_mday; + + return days; +} + +_INT32 DateReader::normalizeYear(_INT32 year) +{ + // год полностью + if(year > 1900) + return year - 1900; + else if (year < 69) + return 100 + year; + else + return year; +} + +bool DateReader::parseAmPm(std::vector &stringBuf, tm &date) +{ + for(auto bufelemPos = 0; bufelemPos < stringBuf.size(); bufelemPos++) + stringBuf[bufelemPos] = std::towlower(stringBuf[bufelemPos]); + std::wstring timePostfix(stringBuf.begin(), stringBuf.end()); + if(timePostfix == L"pm") + { + date.tm_hour += 12; + } + if(timePostfix== L"am" || timePostfix == L"pm") + return true; + return false; +} + +bool DateReader::parseMonthName(std::vector &stringBuf, tm &date) +{ + auto locInf = lcInfo::getLocalInfo(lcid_); + if(stringBuf.at(stringBuf.size()-1) == '.') + stringBuf.pop_back(); + std::wstring monthName(stringBuf.begin(), stringBuf.end()); + + bool isShort = false; + if(monthName.size() <= locInf.MonthAbrvLen) + isShort = true; + auto monthindex = locInf.GetMonthNumber(monthName, isShort)+ 1; + if(monthindex <= 0) + return false; + if(date.tm_mon != 0 && date.tm_mday == 0) + date.tm_mday = date.tm_mon; + date.tm_mon = monthindex; + return true; +} diff --git a/OOXML/Binary/Sheets/Reader/CellFormatController/DateReader.h b/OOXML/Binary/Sheets/Reader/CellFormatController/DateReader.h index 7a79f827e97..1dea73d43f9 100644 --- a/OOXML/Binary/Sheets/Reader/CellFormatController/DateReader.h +++ b/OOXML/Binary/Sheets/Reader/CellFormatController/DateReader.h @@ -1,4 +1,4 @@ -/* +/* * (c) Copyright Ascensio System SIA 2010-2023 * * This program is a free software product. You can redistribute it and/or @@ -36,20 +36,68 @@ #include #include +#include class DateReader { public: + /// @brief создание считывателя с указанным id локали + /// @param lcid идентификатор локали в зависимости от которой будет читаться дата + DateReader(_INT32 lcid); + /// @brief получение даты в виде числа в формате excel /// @param date дата в строковом формате /// @param result результат в формате excel /// @param return true в случае успешной конвертации, иначе false - bool GetDigitalDate(const std::wstring &date, _INT32 &result); + bool GetDigitalDate(const std::wstring &date, double &result, bool &Hasdate, bool &Hastime); private: + + /// @brief парсинг стандартизированной даты + /// @param date дата в строковом формате + /// @param result в формате tm + /// @param return true в случае успешной конвертации, иначе false + bool parseIsoDate(const std::wstring &date, tm &result); + + /// @brief парсинг строковой даты с известной локалью + /// @param date дата в строковом формате + /// @param result в формате tm + /// @param return true в случае успешной конвертации, иначе false + bool parseLocalDate(const std::wstring &date, tm &result, bool &Hasdate, bool &Hastime); + + /// @brief получение даты в виде числа в формате excel из дат позднее 1900 года /// @param datetime структура с датой /// @return дата в формате excel - _INT32 getStandartDate(tm &date); + _INT32 getStandartDate(tm date); + + /// @brief получение времени в виде десятичной части double + /// @param datetime структура с датой и временем + /// @return время в виде десятичной части double числа + double getStandartTime(tm date); + + /// @brief получение даты в виде числа в формате excel из дат от 1900 года и до 1970 + /// @param datetime структура с датой + /// @return дата в формате excel + _INT32 getNonUnixDate(tm date); + + /// @brief нормализация года под стандарт excel + /// @param year год либо в формате yyyy - 2021 либо в формате yy - 21 + /// @return количество лет прошедших с 1900 года + _INT32 normalizeYear(_INT32 year); + + /// @brief парсинг am и pm частей времени + /// @param буфер с символами + /// @param date структура с датой + /// @return true если строка является частью am или pm + bool parseAmPm(std::vector &stringBuf, tm &date); + + /// @brief парсинг имени месяца и внесение его в дату + /// @param буфер с символами + /// @param date структура с датой + /// @return true если строка является именем месяца + bool parseMonthName(std::vector &stringBuf, tm &date); + + _INT32 lcid_; }; diff --git a/OOXML/Binary/Sheets/Reader/CellFormatController/DigitReader.cpp b/OOXML/Binary/Sheets/Reader/CellFormatController/DigitReader.cpp index fcccb0ca1d9..65ae59396e3 100644 --- a/OOXML/Binary/Sheets/Reader/CellFormatController/DigitReader.cpp +++ b/OOXML/Binary/Sheets/Reader/CellFormatController/DigitReader.cpp @@ -1,4 +1,4 @@ -/* +/* * (c) Copyright Ascensio System SIA 2010-2023 * * This program is a free software product. You can redistribute it and/or @@ -34,6 +34,8 @@ #include "CurrencyReader.h" #include +#include +#include const std::wstring DefaultPercentFormat = L"0.0%"; @@ -49,7 +51,7 @@ bool DigitReader::ReadDigit(const std::wstring &value, std::wstring &digit, std: return false; } - if ((0 == *pEndPtr) || (pEndPtr != value.c_str() && (value.c_str() + length - pEndPtr) < 3)) + if ((0 == *pEndPtr) || (pEndPtr != value.c_str() && (value.c_str() + length - pEndPtr) <= 4)) { std::wstring postfix; auto length = value.length(); @@ -71,7 +73,7 @@ bool DigitReader::ReadDigit(const std::wstring &value, std::wstring &digit, std: } } - auto data_format = createFractionFormat(value, pEndPtr); + auto data_format = createFractionFormat(value, postfix); double fractionValue = 0; if (0 != *pEndPtr) @@ -103,10 +105,10 @@ bool DigitReader::ReadDigit(const std::wstring &value, std::wstring &digit, std: if (dotPos != std::wstring::npos) { size_t lastNonZeroPos = digit.find_last_not_of(L'0'); - digit.erase(lastNonZeroPos + 2); + if(lastNonZeroPos+3 < digit.size()) + digit.erase(lastNonZeroPos + 2); } - - data_format = createFractionFormat(digit, pEndPtr); + data_format = createFractionFormat(digit, L""); for (size_t i = 0; i < postfix.size(); ++i) { data_format += std::wstring(L"\\") + postfix[i]; @@ -114,10 +116,17 @@ bool DigitReader::ReadDigit(const std::wstring &value, std::wstring &digit, std: format = data_format; } } + else + { + digit = std::to_wstring(dValue); + format = data_format; + } } else - { - digit = std::to_wstring(dValue); + { if(value.find(L'.') == std::wstring::npos) + digit = std::to_wstring((_INT64)dValue); + else + digit = std::to_wstring(dValue); format = data_format; } return true; @@ -125,19 +134,19 @@ bool DigitReader::ReadDigit(const std::wstring &value, std::wstring &digit, std: return false; } -std::wstring DigitReader::createFractionFormat(const std::wstring &value, wchar_t *pEndPtr) +std::wstring DigitReader::createFractionFormat(const std::wstring &value, const std::wstring &postfix) { size_t pos = value.find(L"."); auto length = value.length(); std::wstring data_format = L""; - if (pos != std::wstring::npos) + if (pos != std::wstring::npos && pos < (value.size() - postfix.size() - 1)) { - size_t fraction = length - pos - ((0 != *pEndPtr) ? 2 : 1); + size_t fraction = length - pos - 1 - postfix.size(); for (size_t i = 0; i < fraction && fraction != std::wstring::npos; ++i) data_format += L"0"; } if (false == data_format.empty()) data_format = L"." + data_format; - if(pos != std::string::npos) + if(pos != std::string::npos && pos < (value.size() - postfix.size() - 1)) { std::wstring wholePart(pos, '0'); data_format = wholePart + data_format; @@ -162,3 +171,37 @@ bool DigitReader::checkCommonFractionFormat(const double &numerator, const std:: format = L"?/?"; dvalue = numerator/denominator; } + +bool DigitReader::ReadScientific(const std::wstring &value, std::wstring &digit, std::wstring &format) +{ + std::wregex scientificRegex(L"(^[+-]?(\\d+\\.?\\d*)([eE][+-]?\\d+))$"); + if(std::regex_search(value, scientificRegex)) + { + try + { + auto doubleVal = std::stod(value); + + std::wstringstream ss; + _INT32 MainPartSize = value.find(L"E"); + if(MainPartSize < 1) + MainPartSize = value.find(L"e"); + ss.precision(MainPartSize); // Установить точность + ss.setf(std::ios::scientific); + ss << doubleVal; + digit = ss.str(); + + format = L"0.0"; + if(MainPartSize > 3) + format += std::wstring(MainPartSize - 3, L'0'); + format +=L"E+00"; + return true; + + } + catch (std::exception) + { + return false; + } + + } + return false; +} diff --git a/OOXML/Binary/Sheets/Reader/CellFormatController/DigitReader.h b/OOXML/Binary/Sheets/Reader/CellFormatController/DigitReader.h index 8eaf89848b5..18846633c91 100644 --- a/OOXML/Binary/Sheets/Reader/CellFormatController/DigitReader.h +++ b/OOXML/Binary/Sheets/Reader/CellFormatController/DigitReader.h @@ -1,4 +1,4 @@ -/* +/* * (c) Copyright Ascensio System SIA 2010-2023 * * This program is a free software product. You can redistribute it and/or @@ -40,15 +40,22 @@ class DigitReader { public: - /// @brief проверка постфикса на валидность валюте + /// @brief считывание числа /// @param value считываемое текстовое значение /// @param digit строка с числовым значением /// @param format строка с форматом числа - /// @return true значение преобразуется в число, иначе falsew + /// @return true значение преобразуется в число, иначе false bool ReadDigit(const std::wstring &value, std::wstring &digit, std::wstring &format); + /// @brief считывание числа в формате scientific + /// @param value считываемое текстовое значение + /// @param digit строка с числовым значением + /// @param format строка с форматом числа + /// @return true значение преобразуется в число, иначе false + bool ReadScientific(const std::wstring &value, std::wstring &digit, std::wstring &format); + private: - std::wstring createFractionFormat(const std::wstring &value, wchar_t *endPtr); + std::wstring createFractionFormat(const std::wstring &value, const std::wstring &postfix); bool checkCommonFractionFormat(const double &numerator, const std::wstring &postfix, double &dvalue, std::wstring &format); }; diff --git a/OOXML/Binary/Sheets/Reader/CellFormatController/LocalInfo.cpp b/OOXML/Binary/Sheets/Reader/CellFormatController/LocalInfo.cpp new file mode 100644 index 00000000000..389154d8e35 --- /dev/null +++ b/OOXML/Binary/Sheets/Reader/CellFormatController/LocalInfo.cpp @@ -0,0 +1,367 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2024 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ + +#pragma once + +#include "LocalInfo.h" +#include + +namespace lcInfo +{ + +std::vector> MonthNames{}; +std::vector> ShortMonthNames{}; +std::map<_INT32, LocalInfo> InfoMap {}; + +//инициализируем большие переменные только при необходимости +void InitLocalInfo() +{ + InfoMap = std::map<_INT32, LocalInfo> + { + {-1, LocalInfo{-1, L"default", L"-", L"215", 0, 3}}, + {1, LocalInfo{1, L"ar", L"/", L"134", 28, 13}}, + {4, LocalInfo{4, L"zh-Hans", L"/", L"520", 3, 3}}, + {5, LocalInfo{5, L"cs", L".", L"135", 4, 3}}, + {6, LocalInfo{6, L"da", L"-", L"135", 5, 3}}, + {7, LocalInfo{7, L"de", L".", L"135", 6, 3}}, + {8, LocalInfo{8, L"el", L"/", L"025", 7, 3}}, + {9, LocalInfo{9, L"en", L"/", L"205", 0, 3}}, + {10, LocalInfo{10, L"es", L"/", L"135", 2, 3}}, + {11, LocalInfo{11, L"fi", L".", L"025", 8, 6}}, + {12, LocalInfo{12, L"fr", L"/", L"135", 9, 4}}, + {14, LocalInfo{14, L"hu", L".", L"531", 10, 5}}, + {16, LocalInfo{16, L"it", L"/", L"135", 11, 3}}, + {17, LocalInfo{17, L"ja", L"/", L"531", 12, 2}}, + {18, LocalInfo{18, L"ko", L"-", L"531", 13, 2}}, + {21, LocalInfo{21, L"pl", L".", L"135", 14, 3}}, + {22, LocalInfo{22, L"pt", L"/", L"135", 15, 3}}, + {25, LocalInfo{25, L"ru", L".", L"135", 1, 3}}, + {29, LocalInfo{29, L"sv", L"-", L"531", 16, 3}}, + {31, LocalInfo{31, L"tr", L".", L"035", 17, 3}}, + {33, LocalInfo{33, L"id", L"/", L"135", 18, 3}}, + {34, LocalInfo{34, L"uk", L".", L"135", 19, 3}}, + {36, LocalInfo{36, L"sl", L".", L"035", 20, 3}}, + {38, LocalInfo{38, L"lv", L".", L"135", 21, 5}}, + {39, LocalInfo{39, L"lt", L"-", L"531", 22, 5}}, + {42, LocalInfo{42, L"vi", L"/", L"135", 23, 5}}, + {44, LocalInfo{44, L"az", L".", L"135", 24, 3}}, + {63, LocalInfo{63, L"kk", L".", L"135", 25, 3}}, + {80, LocalInfo{80, L"mn", L".", L"531", 26, 8}}, + {1025, LocalInfo{1025, L"ar-SA", L"/", L"134", 28, 13}}, + {1026, LocalInfo{1026, L"bg-BG", L".", L"025", 27, 3}}, + {1028, LocalInfo{1028, L"zh-TW", L"/", L"520", 3, 2}}, + {1029, LocalInfo{1029, L"cs-CZ", L",", L"135", 4, 3}}, + {1030, LocalInfo{1030, L"da-DK", L"-", L"135", 5, 3}}, + {1031, LocalInfo{1031, L"de-DE", L"-", L"135", 6, 3}}, + {1032, LocalInfo{1032, L"el-GR", L"/", L"025", 7, 3}}, + {1033, LocalInfo{1033, L"en-US", L"/", L"205", 0, 3}}, + {1035, LocalInfo{1035, L"fi-FI", L".", L"025", 8, 3}}, + {1036, LocalInfo{1036, L"fr-FR", L"/", L"135", 9, 4}}, + {1038, LocalInfo{1038, L"hu-HU", L".", L"531", 10, 3}}, + {1040, LocalInfo{1040, L"it-IT", L"/", L"135", 11, 3}}, + {1041, LocalInfo{1041, L"ja-JP", L"/", L"135", 12, 2}}, + {1042, LocalInfo{1042, L"ko-KR", L"-", L"531", 13, 2}}, + {1043, LocalInfo{1043, L"nl-NL", L"-", L"025", 29, 3}}, + {1045, LocalInfo{1045, L"pl-PL", L".", L"135", 14, 3}}, + {1046, LocalInfo{1046, L"pt-BR", L"/", L"135", 15, 3}}, + {1049, LocalInfo{1049, L"ru-RU", L".", L"135", 1, 3}}, + {1050, LocalInfo{1050, L"hr-HR", L".", L"025", 30, 3}}, + {1051, LocalInfo{1051, L"sk-SK", L".", L"025", 31, 3}}, + {1053, LocalInfo{1053, L"sv-SE", L"-", L"531", 16, 3}}, + {1055, LocalInfo{1055, L"tr-TR", L".", L"035", 17, 3}}, + {1057, LocalInfo{1057, L"id-ID", L"/", L"135", 18, 3}}, + {1058, LocalInfo{1058, L"uk-UA", L".", L"135", 19, 3}}, + {1060, LocalInfo{1060, L"sl-SI", L".", L"035", 20, 3}}, + {1062, LocalInfo{1062, L"lv-LV", L".", L"135", 21, 5}}, + {1063, LocalInfo{1063, L"lt-LT", L"-", L"531", 22, 5}}, + {1066, LocalInfo{1066, L"vi-VN", L"/", L"135", 23, 5}}, + {1068, LocalInfo{1068, L"az-Latn-AZ", L".", L"135", 24, 3}}, + {1087, LocalInfo{1087, L"kk-KZ", L".", L"135", 25, 3}}, + {1104, LocalInfo{1104, L"mn-MN", L".", L"531", 26, 3}}, + {2049, LocalInfo{2049, L"ar-IQ", L"/", L"135", 32, 12}}, + {2052, LocalInfo{2052, L"zh-CN", L"/", L"520", 3, 3}}, + {2055, LocalInfo{2055, L"de-CH", L".", L"135", 6, 3}}, + {2057, LocalInfo{2057, L"en-GB", L"/", L"135", 0, 3}}, + {2058, LocalInfo{2058, L"es-MX", L"/", L"135", 2, 3}}, + {2060, LocalInfo{2060, L"fr-BE", L"-", L"134", 9, 4}}, + {2064, LocalInfo{2064, L"it-CH", L".", L"135", 11, 3}}, + {2070, LocalInfo{2070, L"pt-PT", L"/", L"135", 15, 3}}, + {2073, LocalInfo{2073, L"ru-MD", L".", L"135", 1, 3}}, + {2077, LocalInfo{2077, L"sv-FI", L"-", L"135", 16, 3}}, + {2092, LocalInfo{2092, L"az-Cyrl-AZ", L".", L"135", 33, 4}}, + {2128, LocalInfo{2128, L"mn-Mong-CN", L"/", L"520", 34, 22}}, + {3073, LocalInfo{3073, L"ar-EG", L"/", L"135", 35, 3}}, + {3076, LocalInfo{3076, L"zh-HK", L"/", L"025", 3, 3}}, + {3079, LocalInfo{3079, L"de-AT", L".", L"135", 6, 3}}, + {3081, LocalInfo{3081, L"en-AU", L"/", L"035", 0, 3}}, + {3082, LocalInfo{3082, L"es-ES", L"/", L"135", 2, 3}}, + {3084, LocalInfo{3084, L"fr-CA", L"-", L"531", 9, 4}}, + {3152, LocalInfo{3152, L"mn-Mong-MN", L"/", L"520", 34, 22}}, + {4097, LocalInfo{4097, L"ar-LY", L"/", L"135", 35, 3}}, + {4100, LocalInfo{4100, L"zh-SG", L"/", L"025", 3, 3}}, + {4103, LocalInfo{4103, L"de-LU", L".", L"135", 6, 3}}, + {4105, LocalInfo{4105, L"en-CA", L"-", L"531", 0, 3}}, + {4106, LocalInfo{4106, L"es-GT", L"/", L"035", 2, 3}}, + {4108, LocalInfo{4108, L"fr-CH", L"/", L"035", 9, 4}}, + {4122, LocalInfo{4122, L"hr-BA", L".", L"025", 30, 3}}, + {5121, LocalInfo{5121, L"ar-DZ", L"-", L"135", 35, 3}}, + {5124, LocalInfo{5124, L"zh-MO", L"/", L"025", 3, 3}}, + {5127, LocalInfo{5127, L"de-LI", L".", L"135", 6, 3}}, + {5129, LocalInfo{5129, L"en-NZ", L"/", L"035", 0, 3}}, + {5130, LocalInfo{5130, L"es-CR", L"/", L"025", 2, 3}}, + {5132, LocalInfo{5132, L"fr-LU", L"/", L"025", 9, 4}}, + {6153, LocalInfo{6153, L"en-IE", L"/", L"135", 0, 3}}, + {6154, LocalInfo{6154, L"es-PA", L"/", L"315", 2, 3}}, + {6156, LocalInfo{6156, L"fr-MC", L"/", L"135", 9, 4}}, + {7169, LocalInfo{7169, L"ar-TN", L"-", L"135", 35, 3}}, + {7177, LocalInfo{7177, L"en-ZA", L"/", L"531", 0, 3}}, + {7178, LocalInfo{7178, L"es-DO", L"/", L"025", 2, 3}}, + {7180, LocalInfo{7180, L"fr-029", L"/", L"135", 9, 4}}, + {8193, LocalInfo{8193, L"ar-OM", L"/", L"135", 35, 4}}, + {8201, LocalInfo{8201, L"en-JM", L"/", L"025", 0, 3}}, + {8202, LocalInfo{8202, L"es-VE", L"/", L"025", 2, 3}}, + {8204, LocalInfo{8204, L"fr-RE", L"/", L"135", 9, 4}}, + {9217, LocalInfo{9217, L"ar-YE", L"/", L"135", 35, 3}}, + {9225, LocalInfo{9225, L"en-029", L"/", L"135", 0, 3}}, + {9226, LocalInfo{9226, L"es-CO", L"/", L"035", 2, 3}}, + {9228, LocalInfo{9228, L"fr-CD", L"/", L"135", 9, 4}}, + {9242, LocalInfo{9242, L"sr-Latn-RS", L".", L"025", 36, 4}}, + {10250, LocalInfo{10250, L"es-PE", L"/", L"035", 2, 3}}, + {10252, LocalInfo{10252, L"fr-SN", L"/", L"135", 9, 4}}, + {10266, LocalInfo{10266, L"sr-Cyrl-RS", L".", L"135", 37, 4}}, + {11265, LocalInfo{11265, L"ar-JO", L"/", L"135", 32, 4}}, + {11273, LocalInfo{11273, L"en-TT", L"/", L"135", 0, 3}}, + {11274, LocalInfo{11274, L"es-AR", L"/", L"025", 2, 3}}, + {11276, LocalInfo{11276, L"fr-CM", L"/", L"135", 9, 4}}, + {12289, LocalInfo{12289, L"ar-LB", L"/", L"135", 32, 4}}, + {12297, LocalInfo{12297, L"en-ZW", L"/", L"025", 0, 3}}, + {12298, LocalInfo{12298, L"es-EC", L"/", L"025", 2, 3}}, + {12300, LocalInfo{12300, L"fr-CI", L"/", L"135", 9, 4}}, + {13313, LocalInfo{13313, L"ar-KW", L"/", L"135", 35, 4}}, + {13321, LocalInfo{13321, L"en-PH", L"/", L"135", 0, 3}}, + {13322, LocalInfo{13322, L"es-EC", L"-", L"135", 2, 3}}, + {13324, LocalInfo{13324, L"fr-ML", L"/", L"135", 9, 4}}, + {14337, LocalInfo{14337, L"ar-AE", L"/", L"135", 35, 4}}, + {14345, LocalInfo{14345, L"en-ID", L"/", L"135", 0, 3}}, + {14346, LocalInfo{14346, L"es-UY", L"/", L"025", 2, 3}}, + {14348, LocalInfo{14348, L"fr-MA", L"/", L"135", 9, 4}}, + {15361, LocalInfo{15361, L"ar-BH", L"/", L"135", 35, 4}}, + {15369, LocalInfo{15369, L"en-HK", L"/", L"025", 0, 3}}, + {15370, LocalInfo{15370, L"es-PY", L"/", L"025", 2, 3}}, + {15372, LocalInfo{15372, L"fr-HT", L"/", L"135", 9, 4}}, + {16385, LocalInfo{16385, L"ar-QA", L"/", L"135", 35, 4}}, + {16393, LocalInfo{16393, L"en-IN", L"-", L"135", 0, 3}}, + {16394, LocalInfo{16394, L"es-BO", L"/", L"025", 2, 3}}, + {17417, LocalInfo{17417, L"en-MY", L"/", L"025", 0, 3}}, + {17418, LocalInfo{17418, L"es-SV", L"/", L"025", 2, 3}}, + {18441, LocalInfo{18441, L"en-SG", L"/", L"025", 0, 3}}, + {18442, LocalInfo{18442, L"es-HN", L"/", L"025", 2, 3}}, + {19466, LocalInfo{19466, L"es-NI", L"/", L"025", 2, 3}}, + {20490, LocalInfo{20490, L"es-PR", L"/", L"315", 2, 3}}, + {21514, LocalInfo{21514, L"es-US", L"/", L"205", 2, 3}}, + {22538, LocalInfo{22538, L"es-419", L"/", L"025", 2, 3}}, + {23562, LocalInfo{23562, L"es-CU", L"/", L"025", 2, 3}}, + {27674, LocalInfo{27674, L"sr-Cyrl", L".", L"135", 37, 4}}, + {27674, LocalInfo{27674, L"sr-Latn", L".", L"025", 36, 4}}, + {29740, LocalInfo{29740, L"az-Cyrl", L".", L"135", 33, 4}}, + {30724, LocalInfo{30724, L"zh", L"/", L"520", 3, 3}}, + {30764, LocalInfo{30764, L"az-Latn", L".", L"135", 24, 3}}, + {30800, LocalInfo{30800, L"mn-Cyrl", L".", L"531", 26, 8}}, + {31748, LocalInfo{31748, L"zh-Hant", L"/", L"025", 3, 3}}, + {31824, LocalInfo{31824, L"mn-Mong", L"/", L"520", 34, 22}} + }; + MonthNames = std::vector> + { + {L"january", L"jebruary", L"march", L"april", L"may", L"june", L"july", L"august", L"september", L"october", L"november", L"december"}, + {L"январь", L"февраль", L"март", L"апрель", L"май", L"июнь", L"июль", L"август", L"сентябрь", L"октябрь", L"ноябрь", L"декабрь"}, + {L"enero", L"febrero", L"marzo", L"abril", L"mayo", L"junio", L"julio", L"agosto", L"septiembre", L"octubre", L"noviembre", L"diciembre"}, + {L"一月", L"二月", L"三月", L"四月", L"五月", L"六月", L"七月", L"八月", L"九月", L"十月", L"十一月", L"十二月"}, + {L"leden", L"únor", L"březen", L"duben", L"květen", L"červen", L"červenec", L"srpen", L"září", L"říjen", L"listopad", L"prosinec"}, + {L"januar", L"februar", L"marts", L"april", L"maj", L"juni", L"juli", L"august", L"september", L"oktober", L"november", L"december"}, + {L"Januar", L"Februar", L"März", L"April", L"Mai", L"Juni", L"Juli", L"August", L"September", L"Oktober", L"November", L"Dezember"}, + {L"Ιανουάριος", L"Φεβρουάριος", L"Μάρτιος", L"Απρίλιος", L"Μάιος", L"Ιούνιος", L"Ιούλιος", L"Αύγουστος", L"Σεπτέμβριος", L"Οκτώβριος", L"Νοέμβριος", L"Δεκέμβριος"}, + {L"tammikuu", L"helmikuu", L"maaliskuu", L"huhtikuu", L"toukokuu", L"kesäkuu", L"heinäkuu", L"elokuu", L"syyskuu", L"lokakuu", L"marraskuu", L"joulukuu"}, + {L"janvier", L"février", L"mars", L"avril", L"mai", L"juin", L"juillet", L"août", L"septembre", L"octobre", L"novembre", L"décembre"}, + {L"január", L"február", L"március", L"április", L"május", L"június", L"július", L"augusztus", L"szeptember", L"október", L"november", L"december"}, + {L"gennaio", L"febbraio", L"marzo", L"aprile", L"maggio", L"giugno", L"luglio", L"agosto", L"settembre", L"ottobre", L"novembre", L"dicembre"}, + {L"1月", L"2月", L"3月", L"4月", L"5月", L"6月", L"7月", L"8月", L"9月", L"10月", L"11月", L"12月"}, + {L"1월", L"2월", L"3월", L"4월", L"5월", L"6월", L"7월", L"8월", L"9월", L"10월", L"11월", L"12월"}, + {L"styczeń", L"luty", L"marzec", L"kwiecień", L"maj", L"czerwiec", L"lipiec", L"sierpień", L"wrzesień", L"październik", L"listopad", L"grudzień"}, + {L"janeiro", L"fevereiro", L"março", L"abril", L"maio", L"junho", L"julho", L"agosto", L"setembro", L"outubro", L"novembro", L"dezembro"}, + {L"januari", L"februari", L"mars", L"april", L"maj", L"juni", L"juli", L"augusti", L"september", L"oktober", L"november", L"december"}, + {L"Ocak", L"Şubat", L"Mart", L"Nisan", L"Mayıs", L"Haziran", L"Temmuz", L"Ağustos", L"Eylül", L"Ekim", L"Kasım", L"Aralık"}, + {L"Januari", L"Februari", L"Maret", L"April", L"Mei", L"Juni", L"Juli", L"Agustus", L"September", L"Oktober", L"November", L"Desember"}, + {L"січень", L"лютий", L"березень", L"квітень", L"травень", L"червень", L"липень", L"серпень", L"вересень", L"жовтень", L"листопад", L"грудень"}, + {L"januar", L"februar", L"marec", L"april", L"maj", L"junij", L"julij", L"avgust", L"september", L"oktober", L"november", L"december"}, + {L"janvāris", L"februāris", L"marts", L"aprīlis", L"maijs", L"jūnijs", L"jūlijs", L"augusts", L"septembris", L"oktobris", L"novembris", L"decembris"}, + {L"sausis", L"vasaris", L"kovas", L"balandis", L"gegužė", L"birželis", L"liepa", L"rugpjūtis", L"rugsėjis", L"spalis", L"lapkritis", L"gruodis"}, + {L"Tháng Giêng", L"Tháng Hai", L"Tháng Ba", L"Tháng Tư", L"Tháng Năm", L"Tháng Sáu", L"Tháng Bảy", L"Tháng Tám", L"Tháng Chín", L"Tháng Mười", L"Tháng Mười Một", L"Tháng Mười Hai"}, + {L"Yanvar", L"Fevral", L"Mart", L"Aprel", L"May", L"İyun", L"İyul", L"Avqust", L"Sentyabr", L"Oktyabr", L"Noyabr", L"Dekabr"}, + {L"Қаңтар", L"Ақпан", L"Наурыз", L"Сәуір", L"Мамыр", L"Маусым", L"Шілде", L"Тамыз", L"Қыркүйек", L"Қазан", L"Қараша", L"Желтоқсан"}, + {L"Нэгдүгээр сар", L"Хоёрдугаар сар", L"Гуравдугаар сар", L"Дөрөвдүгээр сар", L"Тавдугаар сар", L"Зургаадугаар сар", L"Долоодугаар сар", L"Наймдугаар сар", L"Есдүгээр сар", L"Аравдугаар сар", L"Арван нэгдүгээр сар", L"Арван хоёрдугаар сар"}, + {L"януари", L"февруари", L"март", L"април", L"май", L"юни", L"юли", L"август", L"септември", L"октомври", L"ноември", L"декември"}, + {L"ذو الحجة", L"ذو القعدة", L"شوال", L"رمضان", L"شعبان", L"رجب", L"جمادى الثانية", L"جمادى الأولى", L"ربيع الثاني", L"ربيع الأول", L"صفر", L"محرم"}, + {L"januari", L"februari", L"maart", L"april", L"mei", L"juni", L"juli", L"augustus", L"september", L"oktober", L"november", L"december"}, + {L"siječanj", L"veljača", L"ožujak", L"travanj", L"svibanj", L"lipanj", L"srpanj", L"kolovoz", L"rujan", L"listopad", L"studeni", L"prosinac"}, + {L"január", L"február", L"marec", L"apríl", L"máj", L"jún", L"júl", L"august", L"september", L"október", L"november", L"december"}, + {L"كانون الأول", L"تشرين الثاني", L"تشرين الأول", L"أيلول", L"آب", L"تموز", L"حزيران", L"أيار", L"نيسان", L"آذار", L"شباط", L"كانون الثاني"}, + {L"jанвар", L"феврал", L"март", L"апрел", L"мај", L"ијун", L"ијул", L"август", L"сентјабр", L"октјабр", L"нојабр", L"декабр"}, + {L"ᠨᠢᠭᠡᠳᠦᠭᠡᠷ ᠰᠠᠷ᠎ᠠ", L"ᠬᠤᠶ᠋ᠠᠳᠤᠭᠠᠷ ᠰᠠᠷ᠎ᠠ", L"ᠭᠤᠷᠪᠠᠳᠤᠭᠠᠷ ᠰᠠᠷ᠎ᠠ", L"ᠲᠦᠷᠪᠡᠳᠦᠭᠡᠷ ᠰᠠᠷ᠎ᠠ", L"ᠲᠠᠪᠤᠳᠤᠭᠠᠷ ᠰᠠᠷ᠎ᠠ", L"ᠵᠢᠷᠭᠤᠳᠤᠭᠠᠷ ᠰᠠᠷ᠎ᠠ", L"ᠲᠤᠯᠤᠳᠤᠭᠠᠷ ᠰᠠᠷ᠎ᠠ", L"ᠨᠠᠢᠮᠠᠳᠤᠭᠠᠷ ᠰᠠᠷ᠎ᠠ", L"ᠶᠢᠰᠦᠳᠦᠭᠡᠷ ᠰᠠᠷ᠎ᠠ", L"ᠠᠷᠪᠠᠳᠤᠭᠠᠷ ᠰᠠᠷ᠎ᠠ", L"ᠠᠷᠪᠠᠨ ᠨᠢᠭᠡᠳᠦᠭᠡᠷ ᠰᠠᠷ᠎ᠠ", L"ᠠᠷᠪᠠᠨ ᠬᠤᠶ᠋ᠠᠳᠤᠭᠠᠷ ᠰᠠᠷ᠎ᠠ"}, + {L"ديسمبر", L"نوفمبر", L"أكتوبر", L"سبتمبر", L"أغسطس", L"يوليو", L"يونيو", L"مايو", L"أبريل", L"مارس", L"فبراير", L"يناير"}, + {L"januar", L"februar", L"mart", L"april", L"maj", L"jun", L"jul", L"avgust", L"septembar", L"oktobar", L"novembar", L"decembar"}, + {L"јануар", L"фебруар", L"март", L"април", L"мај", L"јун", L"јул", L"август", L"септембар", L"октобар", L"новембар", L"децембар"} + }; + ShortMonthNames = std::vector> + { + {L"jan", L"feb", L"mar", L"apr", L"may", L"jun", L"jul", L"aug", L"sep", L"oct", L"nov", L"dec"}, + {L"янв", L"фев", L"мар", L"апр", L"май", L"июн", L"июл", L"авг", L"сен", L"окт", L"ноя", L"дек"}, + {L"ene", L"feb", L"mar", L"abr", L"may", L"jun", L"jul", L"ago", L"sep", L"oct", L"nov", L"dic"}, + {L"1月", L"2月", L"3月", L"4月", L"5月", L"6月", L"7月", L"8月", L"9月", L"10月", L"11月", L"12月"}, + {L"led", L"úno", L"bře", L"dub", L"kvě", L"čvn", L"čvc", L"srp", L"zář", L"říj", L"lis", L"pro"}, + {L"jan", L"feb", L"mar", L"apr", L"maj", L"jun", L"jul", L"aug", L"sep", L"okt", L"nov", L"dec"}, + {L"Jan", L"Feb", L"Mrz", L"Apr", L"Mai", L"Jun", L"Jul", L"Aug", L"Sep", L"Okt", L"Nov", L"Dez"}, + {L"Ιαν", L"Φεβ", L"Μαρ", L"Απρ", L"Μαϊ", L"Ιουν", L"Ιουλ", L"Αυγ", L"Σεπ", L"Οκτ", L"Νοε", L"Δεκ"}, + {L"tammi", L"helmi", L"maalis", L"huhti", L"touko", L"kesä", L"heinä", L"elo", L"syys", L"loka", L"marras", L"joulu"}, + {L"janv", L"févr", L"mars", L"avr", L"mai", L"juin", L"juil", L"août", L"sept", L"oct", L"nov", L"déc"}, + {L"jan", L"febr", L"márc", L"ápr", L"máj", L"jún", L"júl", L"aug", L"szept", L"okt", L"nov", L"dec"}, + {L"gen", L"feb", L"mar", L"apr", L"mag", L"giu", L"lug", L"ago", L"set", L"ott", L"nov", L"dic"}, + {L"1", L"2", L"3", L"4", L"5", L"6", L"7", L"8", L"9", L"10", L"11", L"12"}, + {L"1", L"2", L"3", L"4", L"5", L"6", L"7", L"8", L"9", L"10", L"11", L"12"}, + {L"sty", L"lut", L"mar", L"kwi", L"maj", L"cze", L"lip", L"sie", L"wrz", L"paź", L"lis", L"gru"}, + {L"jan", L"fev", L"mar", L"abr", L"mai", L"jun", L"jul", L"ago", L"set", L"out", L"nov", L"dez"}, + {L"jan", L"feb", L"mar", L"apr", L"maj", L"jun", L"jul", L"aug", L"sep", L"okt", L"nov", L"dec"}, + {L"Oca", L"Şub", L"Mar", L"Nis", L"May", L"Haz", L"Tem", L"Ağu", L"Eyl", L"Eki", L"Kas", L"Ara"}, + {L"Jan", L"Feb", L"Mar", L"Apr", L"Mei", L"Jun", L"Jul", L"Agu", L"Sep", L"Okt", L"Nov", L"Des"}, + {L"Січ", L"Лют", L"Бер", L"Кві", L"Тра", L"Чер", L"Лип", L"Сер", L"Вер", L"Жов", L"Лис", L"Гру"}, + {L"jan", L"feb", L"mar", L"apr", L"maj", L"jun", L"jul", L"avg", L"sep", L"okt", L"nov", L"dec"}, + {L"janv", L"febr", L"marts", L"apr", L"maijs", L"jūn", L"jūl", L"aug", L"sept", L"okt", L"nov", L"dec"}, + {L"saus", L"vas", L"kov", L"bal", L"geg", L"birž", L"liep", L"rugp", L"rugs", L"spal", L"lapkr", L"gruod"}, + {L"Thg1", L"Thg2", L"Thg3", L"Thg4", L"Thg5", L"Thg6", L"Thg7", L"Thg8", L"Thg9", L"Thg10", L"Thg11", L"Thg12"}, + {L"yan", L"fev", L"mar", L"apr", L"may", L"iyn", L"iyl", L"avq", L"sen", L"okt", L"noy", L"dek"}, + {L"қаң", L"ақп", L"нау", L"сәу", L"мам", L"мау", L"шіл", L"там", L"қыр", L"қаз", L"қар", L"жел"}, + {L"1-р сар", L"2-р сар", L"3-р сар", L"4-р сар", L"5-р сар", L"6-р сар", L"7-р сар", L"8-р сар", L"9-р сар", L"10-р сар", L"11-р сар", L"12-р сар"}, + {L"яну", L"фев", L"мар", L"апр", L"май", L"юни", L"юли", L"авг", L"сеп", L"окт", L"ное", L"дек"}, + {L"ذو الحجة", L"ذو القعدة", L"شوال", L"رمضان", L"شعبان", L"رجب", L"جمادى الثانية", L"جمادى الأولى", L"ربيع الثاني", L"ربيع الأول", L"صفر", L"محرم"}, + {L"jan", L"feb", L"mrt", L"apr", L"mei", L"jun", L"jul", L"aug", L"sep", L"okt", L"nov", L"dec"}, + {L"sij", L"vlj", L"ožu", L"tra", L"svi", L"lip", L"srp", L"kol", L"ruj", L"lis", L"stu", L"pro"}, + {L"jan", L"feb", L"mar", L"apr", L"máj", L"jún", L"júl", L"aug", L"sep", L"okt", L"nov", L"dec"}, + {L"كانون الأول", L"تشرين الثاني", L"تشرين الأول", L"أيلول", L"آب", L"تموز", L"حزيران", L"أيار", L"نيسان", L"آذار", L"شباط", L"كانون الثاني"}, + {L"Јан", L"Фев", L"Мар", L"Апр", L"Мај", L"Ијун", L"Ијул", L"Авг", L"Сен", L"Окт", L"Ноя", L"Дек"}, + {L"ᠨᠢᠭᠡᠳᠦᠭᠡᠷ ᠰᠠᠷ᠎ᠠ", L"ᠬᠤᠶ᠋ᠠᠳᠤᠭᠠᠷ ᠰᠠᠷ᠎ᠠ", L"ᠭᠤᠷᠪᠠᠳᠤᠭᠠᠷ ᠰᠠᠷ᠎ᠠ", L"ᠲᠦᠷᠪᠡᠳᠦᠭᠡᠷ ᠰᠠᠷ᠎ᠠ", L"ᠲᠠᠪᠤᠳᠤᠭᠠᠷ ᠰᠠᠷ᠎ᠠ", L"ᠵᠢᠷᠭᠤᠳᠤᠭᠠᠷ ᠰᠠᠷ᠎ᠠ", L"ᠲᠤᠯᠤᠳᠤᠭᠠᠷ ᠰᠠᠷ᠎ᠠ", L"ᠨᠠᠢᠮᠠᠳᠤᠭᠠᠷ ᠰᠠᠷ᠎ᠠ", L"ᠶᠢᠰᠦᠳᠦᠭᠡᠷ ᠰᠠᠷ᠎ᠠ", L"ᠠᠷᠪᠠᠳᠤᠭᠠᠷ ᠰᠠᠷ᠎ᠠ", L"ᠠᠷᠪᠠᠨ ᠨᠢᠭᠡᠳᠦᠭᠡᠷ ᠰᠠᠷ᠎ᠠ", L"ᠠᠷᠪᠠᠨ ᠬᠤᠶ᠋ᠠᠳᠤᠭᠠᠷ ᠰᠠᠷ᠎ᠠ"}, + {L"ديسمبر", L"نوفمبر", L"أكتوبر", L"سبتمبر", L"أغسطس", L"يوليو", L"يونيو", L"مايو", L"أبريل", L"مارس", L"فبراير", L"يناير"}, + {L"jan", L"feb", L"mar", L"apr", L"maj", L"jun", L"jul", L"avg", L"sep", L"okt", L"nov", L"dec"}, + {L"јан.", L"феб.", L"март", L"апр.", L"мај", L"јун", L"јул", L"авг.", L"септ.", L"окт.", L"нов.", L"дец."} + }; +} + +LocalInfo getLocalInfo(const _INT32 lcid) +{ + if(InfoMap.empty()) + InitLocalInfo(); + auto result = InfoMap.find(lcid); + if(result == InfoMap.end()) + return InfoMap.at(-1); + return InfoMap.at(lcid); +} + + +//LocalInfo methods + +//todo сборка кода формата из сокращенного формата и разделителя +std::wstring LocalInfo::GetShortDateFormat() +{ + std::wstring result; + for(auto i = 0; i < ShortDatePattern.size(); i++ ) + { + switch (ShortDatePattern[i]) + { + case L'0': + result+= L"d"; + break; + case L'1': + result+= L"dd"; + break; + case L'2': + result+= L"m"; + break; + case L'3': + result+= L"mm"; + break; + case L'4': + result+= L"yy"; + break; + case L'5': + result+= L"yyyy"; + break; + }; + if (i != ShortDatePattern.size() - 1) + result+= DateSeparator; + } + return result; +} + +std::vector LocalInfo::GetMonthNames(const _INT16 &index, const bool isShortName) +{ + if(isShortName) + { + if(index < ShortMonthNames.size() && index >= 0) + return ShortMonthNames.at(index); + return std::vector{}; + } + if(index < MonthNames.size() && index >= 0) + return MonthNames.at(index); + return std::vector{}; +} + +_INT16 LocalInfo::GetMonthNumber(const std::wstring &monthName, const bool isShortName) +{ + auto months = GetMonthNames(MonthNamesIndex, isShortName); + for(auto i = 0; i < months.size(); i++) + if(months.at(i) == monthName) + return i; + return -1; +} +std::wstring LocalInfo::GetLocMonthName(const _INT16 &index, bool shortName) +{ + std::vector months; + std::wstring monthName = L""; + months = GetMonthNames(MonthNamesIndex, shortName); + if(months.size() > index) + monthName = months.at(index); + if(shortName) + { + if (MonthNamesIndex == 2 || MonthNamesIndex == 10 || MonthNamesIndex == 20|| MonthNamesIndex == 22 || MonthNamesIndex == 25) + monthName+= L"."; + } + return monthName; +} +} diff --git a/OOXML/Binary/Sheets/Reader/CellFormatController/LocalInfo.h b/OOXML/Binary/Sheets/Reader/CellFormatController/LocalInfo.h new file mode 100644 index 00000000000..3ba7c08bee2 --- /dev/null +++ b/OOXML/Binary/Sheets/Reader/CellFormatController/LocalInfo.h @@ -0,0 +1,90 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2024 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ + +#pragma once + +#include "../../../../Base/Base.h" + +#include +#include + +namespace lcInfo +{ + +/// @brief класс содержащий в себе информацию о локали и используемых в ней стандартах +class LocalInfo +{ +public: + + /// @brief собрать короткий формат даты из шаблона + /// @return шаблон из номеров определяющих порядок элементов даты где 0-1 дни 2-3 месяцы 4-5 годы + std::wstring GetShortDateFormat(); + + /// @brief получить имена месяцев в этой локали + /// @param index номер из списка месяцев + /// @param shortName запрашивается ли сокращенное имя + /// @return вектор имен месяцев начинающихся с января + std::vector GetMonthNames(const _INT16 &index, const bool isShortName = false); + + /// @brief собрать короткий формат даты из шаблона + /// @return номер месяца начиная от нуля, в случае успеха, отрицательное число в случае неудачи + _INT16 GetMonthNumber(const std::wstring &monthName, const bool isShortName = false); + + /// @brief получить строковое имя месяца в этой локали + /// @param index номер запрашиваемого месяца + /// @param shortName запрашивается ли сокращенное имя + /// @return имя месяца + std::wstring GetLocMonthName(const _INT16 &index, bool shortName = false); + + /// @brief id локали + _INT32 lcid; + + /// @brief название локали + std::wstring Name; + + /// @brief разделитель даты + std::wstring DateSeparator; + + /// @brief сокращенная дата + std::wstring ShortDatePattern; + + /// @brief локальные имена месяцев + _INT16 MonthNamesIndex; + + /// @brief максимум символов в сокращенной длине месяца + _INT16 MonthAbrvLen; +}; + +/// @brief получение информации о локали по её id +LocalInfo getLocalInfo(const _INT32 lcid); + +} diff --git a/OOXML/Binary/Sheets/Reader/ChartFromToBinary.cpp b/OOXML/Binary/Sheets/Reader/ChartFromToBinary.cpp index 4fd8c8a60ce..c076daa70b3 100644 --- a/OOXML/Binary/Sheets/Reader/ChartFromToBinary.cpp +++ b/OOXML/Binary/Sheets/Reader/ChartFromToBinary.cpp @@ -47,16 +47,10 @@ using namespace OOX::Spreadsheet; namespace BinXlsxRW { - SaveParams::SaveParams(const std::wstring& _sDrawingsPath, const std::wstring& _sEmbeddingsPath, const std::wstring& _sThemePath, OOX::CContentTypes* _pContentTypes, CSVWriter* _pCSVWriter, bool bMacro) + SaveParams::SaveParams(const std::wstring& _sDrawingsPath, const std::wstring& _sEmbeddingsPath, const std::wstring& _sThemePath, OOX::CContentTypes* _pContentTypes, CSVWriter* _pCSVWriter, bool bMacro) : + bMacroEnabled(bMacro), pContentTypes(_pContentTypes), sThemePath(_sThemePath), + sDrawingsPath(_sDrawingsPath), sEmbeddingsPath(_sEmbeddingsPath), pCSVWriter(_pCSVWriter) { - bMacroEnabled = bMacro; - pContentTypes = _pContentTypes; - sThemePath = _sThemePath; - sDrawingsPath = _sDrawingsPath; - sEmbeddingsPath = _sEmbeddingsPath; - - nThemeOverrideCount = 1; - pCSVWriter = _pCSVWriter; } const BYTE c_oserct_extlstEXT = 0; @@ -80,6 +74,7 @@ namespace BinXlsxRW const BYTE c_oserct_chartspaceSTYLES = 17; const BYTE c_oserct_chartspaceCOLORS = 18; const BYTE c_oserct_chartspaceXLSXEXTERNAL = 19; + const BYTE c_oserct_chartspaceXLSXZIP = 20; const BYTE c_oserct_usershapes_COUNT = 0; const BYTE c_oserct_usershapes_SHAPE_REL = 1; @@ -836,6 +831,7 @@ namespace BinXlsxRW const BYTE c_oserct_chartExSpaceSTYLES = c_oserct_chartspaceSTYLES;/* = 17*/ const BYTE c_oserct_chartExSpaceCOLORS = c_oserct_chartspaceCOLORS;/* = 18*/ const BYTE c_oserct_chartExSpaceXLSXEXTERNAL = c_oserct_chartspaceXLSXEXTERNAL;/* = 19*/ + const BYTE c_oserct_chartExSpaceXLSXZIP = c_oserct_chartspaceXLSXZIP;/* = 19*/ const BYTE c_oserct_chartExDATA = 0; const BYTE c_oserct_chartExEXTERNALDATA = 1; @@ -1132,7 +1128,7 @@ namespace BinXlsxRW } else if (c_oserct_chartspaceTHEMEOVERRIDE == type) { - std::wstring sThemeOverrideName = L"themeOverride" + std::to_wstring(m_oSaveParams.nThemeOverrideCount++) + L".xml"; + std::wstring sThemeOverrideName = L"themeOverride" + std::to_wstring(m_oBufferedStream.m_nThemeOverrideCount++) + L".xml"; std::wstring sThemeOverrideRelsPath = L"../theme/" + sThemeOverrideName; OOX::CPath pathThemeOverrideFile = m_oSaveParams.sThemePath + FILE_SEPARATOR_STR + sThemeOverrideName; @@ -1174,14 +1170,14 @@ namespace BinXlsxRW OOX::CChartDrawing* pChartDrawing = new OOX::CChartDrawing(NULL); READ1_DEF(length, res, this->ReadCT_userShapes, pChartDrawing); - OOX::CPath pathDrawingsRels = pathDrawingsRelsDir.GetPath() + FILE_SEPARATOR_STR + pChartDrawing->m_sOutputFilename + _T(".rels"); - m_pOfficeDrawingConverter->SaveDstContentRels(pathDrawingsRels.GetPath()); - if (res == c_oSerConstants::ReadOk) { NSCommon::smart_ptr pDrawingFile(pChartDrawing); pChart->Add(pDrawingFile); + OOX::CPath pathDrawingsRels = pathDrawingsRelsDir.GetPath() + FILE_SEPARATOR_STR + pChartDrawing->m_sOutputFilename + _T(".rels"); + m_pOfficeDrawingConverter->SaveDstContentRels(pathDrawingsRels.GetPath()); + unsigned int rId = 0; m_pOfficeDrawingConverter->WriteRels(L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/chartUserShapes", L"../drawings/" + pChartDrawing->m_sOutputFilename, std::wstring(), &rId); @@ -1211,7 +1207,8 @@ namespace BinXlsxRW pChart->m_oChartSpace.m_externalData->m_id = new std::wstring; *pChart->m_oChartSpace.m_externalData->m_id = OOX::RId(rId).ToString(); } - else if (c_oserct_chartspaceXLSX == type) + else if (c_oserct_chartspaceXLSX == type || + c_oserct_chartspaceXLSXZIP == type) { OOX::CSystemUtility::CreateDirectories(m_oSaveParams.sEmbeddingsPath); @@ -1221,8 +1218,15 @@ namespace BinXlsxRW m_pOfficeDrawingConverter->SetDstContentRels(); NSCommon::smart_ptr pXlsxFile; - ReadCT_Xlsx(m_oBufferedStream.GetPointer(0), length, pXlsxFile); - + + if (c_oserct_chartspaceXLSXZIP == type) + { + ReadCT_XlsxZip(m_oBufferedStream.GetPointer(0), length, pXlsxFile); + } + else + { + ReadCT_XlsxBin(m_oBufferedStream.GetPointer(0), length, pXlsxFile); + } m_oBufferedStream.Skip(length); if (pXlsxFile.IsInit()) @@ -1277,7 +1281,30 @@ namespace BinXlsxRW res = c_oSerConstants::ReadUnknown; return res; } - int BinaryChartReader::ReadCT_Xlsx(BYTE *pData, long length, NSCommon::smart_ptr & file) + int BinaryChartReader::ReadCT_XlsxZip(BYTE* pData, long length, NSCommon::smart_ptr& fileOut) + { + if (length < 1 || !pData) + return c_oSerConstants::ReadUnknown; + + fileOut = new OOX::OleObject(NULL, true, m_pOfficeDrawingConverter->m_pReader->m_nDocumentType == XMLWRITER_DOC_TYPE_DOCX); + + int id = m_pOfficeDrawingConverter->m_pReader->m_nCountEmbedded++; + + bool bMacroEnabled = false; //todooo detect + std::wstring sXlsxFilename = L"Microsoft_Excel_Worksheet" + std::to_wstring(id) + (bMacroEnabled ? L".xlsm" : L".xlsx"); + + NSFile::CFileBinary file; + if (file.CreateFileW(m_oSaveParams.sEmbeddingsPath + FILE_SEPARATOR_STR + sXlsxFilename)) + { + file.WriteFile(pData, length); + file.WriteFile(pData, length); + file.CloseFile(); + } + fileOut->set_filename(m_oSaveParams.sEmbeddingsPath + FILE_SEPARATOR_STR + sXlsxFilename, false); + + m_pOfficeDrawingConverter->m_pReader->m_pRels->m_pManager->m_pContentTypes->AddDefault(bMacroEnabled ? L"xlsm" : L"xlsx"); + } + int BinaryChartReader::ReadCT_XlsxBin(BYTE *pData, long length, NSCommon::smart_ptr & file) { if (length < 1 || !pData) return c_oSerConstants::ReadUnknown; @@ -6243,7 +6270,8 @@ namespace BinXlsxRW pChart->m_oChartSpace.m_chartData.m_externalData->m_id = OOX::RId(rId).ToString(); } - else if (c_oserct_chartspaceXLSX == type) + else if (c_oserct_chartspaceXLSX == type || + c_oserct_chartspaceXLSXZIP == type) { OOX::CSystemUtility::CreateDirectories(m_oSaveParams.sEmbeddingsPath); @@ -6253,7 +6281,15 @@ namespace BinXlsxRW m_pOfficeDrawingConverter->SetDstContentRels(); NSCommon::smart_ptr pXlsxFile; - ReadCT_Xlsx(m_oBufferedStream.GetPointer(0), length, pXlsxFile); + + if (c_oserct_chartspaceXLSXZIP == type) + { + ReadCT_XlsxZip(m_oBufferedStream.GetPointer(0), length, pXlsxFile); + } + else + { + ReadCT_XlsxBin(m_oBufferedStream.GetPointer(0), length, pXlsxFile); + } m_oBufferedStream.Skip(length); @@ -6991,11 +7027,13 @@ namespace BinXlsxRW if (c_oserct_chartExBinningBINSIZE == type) { - pBinning->m_binSize = m_oBufferedStream.GetDoubleReal(); + pBinning->m_binSize.Init(); + pBinning->m_binSize->m_oVal = m_oBufferedStream.GetDoubleReal(); } else if (c_oserct_chartExBinningBINCOUNT == type) { - pBinning->m_binCount = m_oBufferedStream.GetLong(); + pBinning->m_binCount.Init(); + pBinning->m_binCount->m_oVal = m_oBufferedStream.GetLong(); } else if (c_oserct_chartExBinningINTERVAL == type) { @@ -7349,6 +7387,7 @@ namespace BinXlsxRW int nCurPos = m_oBcw.WriteItemStart(c_oserct_chartspaceCHART); WriteCT_Chart(*oVal.m_chart); m_oBcw.WriteItemEnd(nCurPos); + } if (oVal.m_spPr.IsInit()) { @@ -12562,16 +12601,16 @@ namespace BinXlsxRW } void BinaryChartWriter::WriteCT_ChartExBinning(OOX::Spreadsheet::ChartEx::CBinning *pVal) { - if (pVal->m_binSize.IsInit()) + if ((pVal->m_binSize.IsInit()) && (pVal->m_binSize->m_oVal.IsInit())) { int nCurPos = m_oBcw.WriteItemStart(c_oserct_chartExBinningBINSIZE); - m_oBcw.m_oStream.WriteDoubleReal(*pVal->m_binSize); + m_oBcw.m_oStream.WriteDoubleReal(pVal->m_binSize->m_oVal->GetValue()); m_oBcw.WriteItemEnd(nCurPos); } - if (pVal->m_binCount.IsInit()) + if ((pVal->m_binCount.IsInit()) && (pVal->m_binCount->m_oVal.IsInit())) { int nCurPos = m_oBcw.WriteItemStart(c_oserct_chartExBinningBINCOUNT); - m_oBcw.m_oStream.WriteLONG(*pVal->m_binCount); + m_oBcw.m_oStream.WriteLONG(*pVal->m_binCount->m_oVal); m_oBcw.WriteItemEnd(nCurPos); } if (pVal->m_intervalClosed.IsInit()) @@ -12597,7 +12636,7 @@ namespace BinXlsxRW } if (pVal->m_overflow.IsInit()) { - if (pVal->m_underflow->GetValue() == SimpleTypes::Spreadsheet::typeAuto) + if (pVal->m_overflow->GetValue() == SimpleTypes::Spreadsheet::typeAuto) { int nCurPos = m_oBcw.WriteItemStart(c_oserct_chartExBinningOVERAUTO); m_oBcw.m_oStream.WriteBYTE(pVal->m_overflow->GetValue()); diff --git a/OOXML/Binary/Sheets/Reader/ChartFromToBinary.h b/OOXML/Binary/Sheets/Reader/ChartFromToBinary.h index 304c5792202..153a4330543 100644 --- a/OOXML/Binary/Sheets/Reader/ChartFromToBinary.h +++ b/OOXML/Binary/Sheets/Reader/ChartFromToBinary.h @@ -99,14 +99,13 @@ namespace BinXlsxRW { struct SaveParams { - SaveParams (const std::wstring& _sDrawingsPath, const std::wstring& _sEmbeddingsPath, const std::wstring& _sThemePath, OOX::CContentTypes *pContentTypes, CSVWriter* pCSVWriter = NULL, bool bMacro = false); + SaveParams(const std::wstring& _sDrawingsPath, const std::wstring& _sEmbeddingsPath, const std::wstring& _sThemePath, OOX::CContentTypes *pContentTypes, CSVWriter* pCSVWriter = NULL, bool bMacro = false); smart_ptr pTheme; std::wstring sThemePath; std::wstring sDrawingsPath; std::wstring sEmbeddingsPath; OOX::CContentTypes* pContentTypes = NULL; - int nThemeOverrideCount = 0; CSVWriter* pCSVWriter = NULL; bool bMacroEnabled = false; }; @@ -114,9 +113,9 @@ namespace BinXlsxRW class BinaryChartReader : public Binary_CommonReader { NSBinPptxRW::CDrawingConverter* m_pOfficeDrawingConverter; - SaveParams& m_oSaveParams; + SaveParams& m_oSaveParams; public: - BinaryChartReader (NSBinPptxRW::CBinaryFileReader& oBufferedStream, SaveParams& oSaveParams, NSBinPptxRW::CDrawingConverter* pOfficeDrawingConverter); + BinaryChartReader (NSBinPptxRW::CBinaryFileReader& oBufferedStream, SaveParams& oSaveParams, NSBinPptxRW::CDrawingConverter* pOfficeDrawingConverter); int ReadCT_ChartFile (long length, OOX::Spreadsheet::CChartFile* poResult); int ReadCT_ChartExFile (long length, OOX::Spreadsheet::CChartExFile* poResult); @@ -261,7 +260,8 @@ namespace BinXlsxRW int ReadCT_FromTo (BYTE type, long length, void* poResult); int ReadCT_Ext (BYTE type, long length, void* poResult); - int ReadCT_Xlsx (BYTE *pData, long length, NSCommon::smart_ptr & file); + int ReadCT_XlsxBin (BYTE *pData, long length, NSCommon::smart_ptr & file); + int ReadCT_XlsxZip (BYTE* pData, long length, NSCommon::smart_ptr& file); int ReadCT_ChartExFileContent (BYTE type, long length, void* poResult); int ReadCT_ChartExChart (BYTE type, long length, void* poResult); diff --git a/OOXML/Binary/Sheets/Reader/XMLReader/XLSXTableController.cpp b/OOXML/Binary/Sheets/Reader/XMLReader/XLSXTableController.cpp index 58ced62c369..8300ec7a24d 100644 --- a/OOXML/Binary/Sheets/Reader/XMLReader/XLSXTableController.cpp +++ b/OOXML/Binary/Sheets/Reader/XMLReader/XLSXTableController.cpp @@ -41,7 +41,7 @@ constexpr auto SheetName = L"Sheet"; -XLSXTableController::XLSXTableController(OOX::Spreadsheet::CXlsx &book) +XLSXTableController::XLSXTableController(OOX::Spreadsheet::CXlsx &book, _INT32 lcid) : book_{&book} { book_->CreateWorkbook(); @@ -51,7 +51,7 @@ XLSXTableController::XLSXTableController(OOX::Spreadsheet::CXlsx &book) // Создадим стили book_->CreateStyles(); - formates_ = std::make_shared(book_->m_pStyles); + formates_ = std::make_shared(book_->m_pStyles, lcid); } diff --git a/OOXML/Binary/Sheets/Reader/XMLReader/XLSXTableController.h b/OOXML/Binary/Sheets/Reader/XMLReader/XLSXTableController.h index 162a15b939a..115d3021cbc 100644 --- a/OOXML/Binary/Sheets/Reader/XMLReader/XLSXTableController.h +++ b/OOXML/Binary/Sheets/Reader/XMLReader/XLSXTableController.h @@ -47,7 +47,8 @@ class XLSXTableController public: /// @brief инициализация полей объекта /// @param book объект который будет заполнен данными с помощью метода FormBook - XLSXTableController(OOX::Spreadsheet::CXlsx &book); + /// @param lcid идентификатор локлаи + XLSXTableController(OOX::Spreadsheet::CXlsx &book, _INT32 lcid); /// @brief добавление ячейки /// @param sText вставляемый текст @@ -79,4 +80,4 @@ class XLSXTableController /// @brief контроллер форматов std::shared_ptr formates_; -}; \ No newline at end of file +}; diff --git a/OOXML/Binary/Sheets/Reader/XMLReader/XMLReader.cpp b/OOXML/Binary/Sheets/Reader/XMLReader/XMLReader.cpp index 047a5229246..8fde0f42e25 100644 --- a/OOXML/Binary/Sheets/Reader/XMLReader/XMLReader.cpp +++ b/OOXML/Binary/Sheets/Reader/XMLReader/XMLReader.cpp @@ -49,7 +49,7 @@ _UINT32 XMLReader::Read(const std::wstring &sFileName, OOX::Spreadsheet::CXlsx & } XML2TableConverter converter = {reader}; - XLSXTableController table = {oXlsx}; + XLSXTableController table = {oXlsx, -1}; // map хранящий текущий номер колонки для записи std::map<_UINT32, _UINT32> rowNumbers = {}; std::map<_UINT32, std::wstring> stringData = {}; diff --git a/OOXML/Binary/Sheets/Reader/XMLReader/XMLReader.h b/OOXML/Binary/Sheets/Reader/XMLReader/XMLReader.h index 54bca09e3c1..5d32597058b 100644 --- a/OOXML/Binary/Sheets/Reader/XMLReader/XMLReader.h +++ b/OOXML/Binary/Sheets/Reader/XMLReader/XMLReader.h @@ -47,6 +47,7 @@ class XMLReader /// @brief Вторая версия считывающего метода /// @param FileName имя xml файла который будет считан /// @param oXlsx объект Xlsx таблицы в которую считается xml + /// @param идентификатор локали для определения форматов дат /// @return код выполнения операции - _UINT32 Read2(const std::wstring &sFileName, OOX::Spreadsheet::CXlsx &oXlsx); + _UINT32 Read2(const std::wstring &sFileName, OOX::Spreadsheet::CXlsx &oXlsx, _INT32 lcid = -1); }; diff --git a/OOXML/Binary/Sheets/Reader/XMLReader/XMLReader2.cpp b/OOXML/Binary/Sheets/Reader/XMLReader/XMLReader2.cpp index d0fded47fd7..e9ed9cb4e95 100644 --- a/OOXML/Binary/Sheets/Reader/XMLReader/XMLReader2.cpp +++ b/OOXML/Binary/Sheets/Reader/XMLReader/XMLReader2.cpp @@ -43,7 +43,7 @@ #include -_UINT32 XMLReader::Read2(const std::wstring &sFileName, OOX::Spreadsheet::CXlsx &oXlsx) +_UINT32 XMLReader::Read2(const std::wstring &sFileName, OOX::Spreadsheet::CXlsx &oXlsx, _INT32 lcid) { XmlUtils::CXmlLiteReader reader = {}; if(!reader.FromFile(sFileName)) @@ -60,7 +60,7 @@ _UINT32 XMLReader::Read2(const std::wstring &sFileName, OOX::Spreadsheet::CXlsx reader.MoveToStart(); ///создаем таблицу - XLSXTableController table = {oXlsx}; + XLSXTableController table = {oXlsx, lcid}; ///заполняем первый ряд таблицы именами столбцов auto colNames = nameController.GetColumnNames(); std::map<_UINT32, std::wstring> namesMap; diff --git a/OOXML/Binary/Sheets/Writer/BinaryReader.cpp b/OOXML/Binary/Sheets/Writer/BinaryReader.cpp index 71ffe30c187..83c72dcd7e0 100644 --- a/OOXML/Binary/Sheets/Writer/BinaryReader.cpp +++ b/OOXML/Binary/Sheets/Writer/BinaryReader.cpp @@ -47,8 +47,6 @@ #include "../../../PPTXFormat/Theme.h" #include "../../../../MsBinaryFile/Common/Vml/toVmlConvert.h" -#include "../../../PPTXFormat/App.h" -#include "../../../PPTXFormat/Core.h" #include "../../../PPTXFormat/Logic/HeadingVariant.h" #include "../../../PPTXFormat/Logic/Shape.h" @@ -72,6 +70,8 @@ #include "../../../XlsxFormat/WorkbookComments.h" #include "../../../XlsxFormat/Table/Connections.h" #include "../../../XlsxFormat/Controls/Controls.h" +#include "../../../XlsxFormat/Timelines/Timeline.h" +#include "../../../XlsxFormat/Workbook/Metadata.h" #include "../../../DocxFormat/Media/VbaProject.h" #include "../../../DocxFormat/Media/JsaProject.h" @@ -1169,7 +1169,9 @@ int BinarySharedStringTableReader::ReadRun(BYTE type, long length, void* poResul std::wstring sText(m_oBufferedStream.GetString4(length)); OOX::Spreadsheet::CText* pText = new OOX::Spreadsheet::CText(); pText->m_sText = sText; - if (std::wstring::npos != sText.find(_T(" "))) + + bool bHHHH = std::wstring::npos != sText.find('\xA') || std::wstring::npos != sText.find('\x9'); + if (std::wstring::npos != sText.find(L" ") || bHHHH) { pText->m_oSpace.Init(); pText->m_oSpace->SetValue(SimpleTypes::xmlspacePreserve); @@ -1360,10 +1362,78 @@ int BinaryStyleTableReader::ReadStyleTableContent(BYTE type, long length, void* m_oStyles.m_oExtLst.Init(); m_oStyles.m_oExtLst->m_arrExt.push_back(pOfficeArtExtension); } + else if (c_oSerStylesTypes::TimelineStyles == type) + { + OOX::Drawing::COfficeArtExtension* pOfficeArtExtension = new OOX::Drawing::COfficeArtExtension(); + pOfficeArtExtension->m_oTimelineStyles.Init(); + pOfficeArtExtension->m_sUri = L"{9260A510-F301-46a8-8635-F512D64BE5F5}"; + pOfficeArtExtension->m_sAdditionalNamespace = L"xmlns:x15=\"http://schemas.microsoft.com/office/spreadsheetml/2010/11/main\""; + + READ1_DEF(length, res, this->ReadTimelineStyles, pOfficeArtExtension->m_oTimelineStyles.GetPointer()); + + if (m_oStyles.m_oExtLst.IsInit() == false) + m_oStyles.m_oExtLst.Init(); + m_oStyles.m_oExtLst->m_arrExt.push_back(pOfficeArtExtension); + } else res = c_oSerConstants::ReadUnknown; return res; -}; +} +int BinaryStyleTableReader::ReadTimelineStyles(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CTimelineStyles* pTimelineStyles = static_cast(poResult); + + int res = c_oSerConstants::ReadOk; + if (c_oSer_TimelineStyles::DefaultTimelineStyle == type) + { + pTimelineStyles->m_oDefaultTimelineStyle = m_oBufferedStream.GetString4(length); + } + else if (c_oSer_TimelineStyles::TimelineStyle == type) + { + pTimelineStyles->m_arrItems.push_back(new OOX::Spreadsheet::CTimelineStyle()); + READ1_DEF(length, res, this->ReadTimelineStyle, pTimelineStyles->m_arrItems.back()); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryStyleTableReader::ReadTimelineStyle(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CTimelineStyle* pTimelineStyle = static_cast(poResult); + + int res = c_oSerConstants::ReadOk; + if (c_oSer_TimelineStyles::TimelineStyleName == type) + { + pTimelineStyle->m_oName = m_oBufferedStream.GetString4(length); + } + else if (c_oSer_TimelineStyles::TimelineStyle == type) + { + pTimelineStyle->m_arrItems.push_back(new OOX::Spreadsheet::CTimelineStyleElement()); + READ2_DEF_SPREADSHEET(length, res, this->ReadTimelineStyleElement, pTimelineStyle->m_arrItems.back()); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryStyleTableReader::ReadTimelineStyleElement(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CTimelineStyleElement* pTimelineStyleElement = static_cast(poResult); + + int res = c_oSerConstants::ReadOk; + if (c_oSer_TimelineStyles::TimelineStyleElementType == type) + { + pTimelineStyleElement->m_oType.Init(); + pTimelineStyleElement->m_oType->SetValueFromByte(m_oBufferedStream.GetUChar()); + } + else if (c_oSer_TimelineStyles::TimelineStyleElementDxfId == type) + { + pTimelineStyleElement->m_oDxfId = m_oBufferedStream.GetLong(); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} + int BinaryStyleTableReader::ReadBorders(BYTE type, long length, void* poResult) { int res = c_oSerConstants::ReadOk; @@ -2137,7 +2207,7 @@ int BinaryWorkbookTableReader::ReadWorkbookTableContent(BYTE type, long length, else if (c_oSerWorkbookTypes::FileSharing == type) { m_oWorkbook.m_oFileSharing.Init(); - READ1_DEF(length, res, this->ReadFileSharing, m_oWorkbook.m_oFileSharing.GetPointer()); + READ2_DEF_SPREADSHEET(length, res, this->ReadFileSharing, m_oWorkbook.m_oFileSharing.GetPointer()); } else if (c_oSerWorkbookTypes::ExternalLinksAutoRefresh == type) { @@ -2211,6 +2281,20 @@ int BinaryWorkbookTableReader::ReadWorkbookTableContent(BYTE type, long length, smart_ptr oFile = oConnection.smart_dynamic_cast(); m_oWorkbook.Add(oFile); } + else if (c_oSerWorkbookTypes::TimelineCaches == type) + { + OOX::Drawing::COfficeArtExtension* pOfficeArtExtension = new OOX::Drawing::COfficeArtExtension(); + pOfficeArtExtension->m_oTimelineCacheRefs.Init(); + + READ1_DEF(length, res, this->ReadTimelineCaches, pOfficeArtExtension->m_oTimelineCacheRefs.GetPointer()); + + pOfficeArtExtension->m_sUri = L"{D0CA8CA8-9F24-4464-BF8E-62219DCF47F9}"; + pOfficeArtExtension->m_sAdditionalNamespace = L"xmlns:x15=\"http://schemas.microsoft.com/office/spreadsheetml/2010/11/main\""; + + if (m_oWorkbook.m_oExtLst.IsInit() == false) + m_oWorkbook.m_oExtLst.Init(); + m_oWorkbook.m_oExtLst->m_arrExt.push_back(pOfficeArtExtension); + } else if (c_oSerWorkbookTypes::SlicerCaches == type) { OOX::Drawing::COfficeArtExtension* pOfficeArtExtension = new OOX::Drawing::COfficeArtExtension(); @@ -2239,6 +2323,15 @@ int BinaryWorkbookTableReader::ReadWorkbookTableContent(BYTE type, long length, m_oWorkbook.m_oExtLst.Init(); m_oWorkbook.m_oExtLst->m_arrExt.push_back(pOfficeArtExtension); } + else if (c_oSerWorkbookTypes::Metadata == type) + { + smart_ptr oMetadataFile(new OOX::Spreadsheet::CMetadataFile(NULL)); + oMetadataFile->m_oMetadata.Init(); + READ1_DEF(length, res, this->ReadMetadata, oMetadataFile->m_oMetadata.GetPointer()); + + smart_ptr oFile = oMetadataFile.smart_dynamic_cast(); + m_oWorkbook.Add(oFile); + } else res = c_oSerConstants::ReadUnknown; return res; @@ -2763,6 +2856,66 @@ int BinaryWorkbookTableReader::ReadWorkbookView(BYTE type, long length, void* po pWorkbookView->m_oActiveTab.Init(); pWorkbookView->m_oActiveTab->SetValue(m_oBufferedStream.GetLong()); } + else if (c_oSerWorkbookViewTypes::AutoFilterDateGrouping == type) + { + pWorkbookView->m_oAutoFilterDateGrouping.Init(); + pWorkbookView->m_oAutoFilterDateGrouping->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSerWorkbookViewTypes::FirstSheet == type) + { + pWorkbookView->m_oActiveTab.Init(); + pWorkbookView->m_oActiveTab->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSerWorkbookViewTypes::Minimized == type) + { + pWorkbookView->m_oMinimized.Init(); + pWorkbookView->m_oMinimized->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSerWorkbookViewTypes::ShowHorizontalScroll == type) + { + pWorkbookView->m_oShowHorizontalScroll.Init(); + pWorkbookView->m_oShowHorizontalScroll->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSerWorkbookViewTypes::ShowSheetTabs == type) + { + pWorkbookView->m_oShowSheetTabs.Init(); + pWorkbookView->m_oShowSheetTabs->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSerWorkbookViewTypes::ShowVerticalScroll == type) + { + pWorkbookView->m_oShowVerticalScroll.Init(); + pWorkbookView->m_oShowVerticalScroll->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSerWorkbookViewTypes::TabRatio == type) + { + pWorkbookView->m_oTabRatio.Init(); + pWorkbookView->m_oTabRatio->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSerWorkbookViewTypes::Visibility == type) + { + pWorkbookView->m_oVisibility.Init(); + pWorkbookView->m_oVisibility->SetValueFromByte(m_oBufferedStream.GetUChar()); + } + else if (c_oSerWorkbookViewTypes::WindowHeight == type) + { + pWorkbookView->m_oWindowHeight.Init(); + pWorkbookView->m_oWindowHeight->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSerWorkbookViewTypes::WindowWidth == type) + { + pWorkbookView->m_oWindowWidth.Init(); + pWorkbookView->m_oWindowWidth->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSerWorkbookViewTypes::XWindow == type) + { + pWorkbookView->m_oXWindow.Init(); + pWorkbookView->m_oXWindow->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSerWorkbookViewTypes::YWindow == type) + { + pWorkbookView->m_oYWindow.Init(); + pWorkbookView->m_oYWindow->SetValue(m_oBufferedStream.GetLong()); + } else res = c_oSerConstants::ReadUnknown; return res; @@ -3136,8 +3289,7 @@ int BinaryWorkbookTableReader::ReadExternalCell(BYTE type, long length, void* po int res = c_oSerConstants::ReadOk; if (c_oSer_ExternalLinkTypes::SheetDataRowCellRef == type) { - pCell->m_oRef.Init(); - pCell->m_oRef->append(m_oBufferedStream.GetString3(length)); + pCell->m_oRef = m_oBufferedStream.GetString3(length); } else if (c_oSer_ExternalLinkTypes::SheetDataRowCellType == type) { @@ -3149,6 +3301,10 @@ int BinaryWorkbookTableReader::ReadExternalCell(BYTE type, long length, void* po pCell->m_oValue.Init(); pCell->m_oValue->m_sText.append(m_oBufferedStream.GetString3(length)); } + else if (c_oSer_ExternalLinkTypes::ValueMetadata == type) + { + pCell->m_oValueMetadata = m_oBufferedStream.GetULong(); + } else res = c_oSerConstants::ReadUnknown; return res; @@ -3404,7 +3560,192 @@ int BinaryWorkbookTableReader::ReadSlicerCaches(BYTE type, long length, void* po res = c_oSerConstants::ReadUnknown; return res; } +int BinaryWorkbookTableReader::ReadTimelineCaches(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CTimelineCacheRefs* pTimelineCacheRefs = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSerWorkbookTypes::TimelineCache == type) + { + OOX::Spreadsheet::CTimelineCacheFile* pTimelineCacheFile = new OOX::Spreadsheet::CTimelineCacheFile(NULL); + pTimelineCacheFile->m_oTimelineCacheDefinition.Init(); + + READ1_DEF(length, res, this->ReadTimelineCache, pTimelineCacheFile->m_oTimelineCacheDefinition.GetPointer()); + + NSCommon::smart_ptr pFile(pTimelineCacheFile); + const OOX::RId oRId = m_oWorkbook.Add(pFile); + + OOX::Spreadsheet::CTimelineCacheRef* pTimelineCacheRef = new OOX::Spreadsheet::CTimelineCacheRef(); + pTimelineCacheRef->m_oRId.Init(); + pTimelineCacheRef->m_oRId->SetValue(oRId.get()); + + pTimelineCacheRefs->m_arrItems.push_back(pTimelineCacheRef); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadTimelineCache(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CTimelineCacheDefinition* pTimelineCache = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSer_TimelineCache::Name == type) + { + pTimelineCache->m_oName = m_oBufferedStream.GetString3(length); + } + else if (c_oSer_TimelineCache::SourceName == type) + { + pTimelineCache->m_oSourceName = m_oBufferedStream.GetString3(length); + } + else if (c_oSer_TimelineCache::Uid == type) + { + pTimelineCache->m_oUid = m_oBufferedStream.GetString3(length); + } + else if (c_oSer_TimelineCache::PivotTables == type) + { + pTimelineCache->m_oPivotTables.Init(); + READ1_DEF(length, res, this->ReadTimelineCachePivotTables, pTimelineCache->m_oPivotTables.GetPointer()); + } + else if (c_oSer_TimelineCache::State == type) + { + pTimelineCache->m_oState.Init(); + READ1_DEF(length, res, this->ReadTimelineState, pTimelineCache->m_oState.GetPointer()); + } + else if (c_oSer_TimelineCache::PivotFilter == type) + { + pTimelineCache->m_oPivotFilter.Init(); + READ1_DEF(length, res, this->ReadTimelinePivotFilter, pTimelineCache->m_oPivotFilter.GetPointer()); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadTimelineCachePivotTables(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CTimelineCachePivotTables* pPivotTables = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + + if (c_oSer_TimelineCache::PivotTable == type) + { + OOX::Spreadsheet::CTimelineCachePivotTable* pPivotTable = new OOX::Spreadsheet::CTimelineCachePivotTable(); + READ2_DEF_SPREADSHEET(length, res, this->ReadTimelineCachePivotTable, pPivotTable); + pPivotTables->m_arrItems.push_back(pPivotTable); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadTimelineState(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CTimelineState* pState = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + + if (c_oSer_TimelineState::Name == type) + { + pState->m_oName = m_oBufferedStream.GetString3(length); + } + else if (c_oSer_TimelineState::FilterState == type) + { + pState->m_oSingleRangeFilterState = m_oBufferedStream.GetBool(); + } + else if (c_oSer_TimelineState::PivotCacheId == type) + { + pState->m_oPivotCacheId = m_oBufferedStream.GetLong(); + } + else if (c_oSer_TimelineState::MinimalRefreshVersion == type) + { + pState->m_oMinimalRefreshVersion = m_oBufferedStream.GetLong(); + } + else if (c_oSer_TimelineState::LastRefreshVersion == type) + { + pState->m_oLastRefreshVersion = m_oBufferedStream.GetLong(); + } + else if (c_oSer_TimelineState::FilterType == type) + { + pState->m_oFilterType = m_oBufferedStream.GetString3(length); + } + else if (c_oSer_TimelineState::Selection == type) + { + pState->m_oSelection.Init(); + READ2_DEF_SPREADSHEET(length, res, this->ReadTimelineRange, pState->m_oSelection.GetPointer()); + } + else if (c_oSer_TimelineState::Bounds == type) + { + pState->m_oBounds.Init(); + READ2_DEF_SPREADSHEET(length, res, this->ReadTimelineRange, pState->m_oBounds.GetPointer()); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadTimelineRange(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CTimelineRange* pTimelineRange = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + + if (c_oSer_TimelineRange::StartDate == type) + { + pTimelineRange->m_oStartDate = m_oBufferedStream.GetString3(length); + } + else if (c_oSer_TimelineRange::EndDate == type) + { + pTimelineRange->m_oEndDate = m_oBufferedStream.GetString3(length); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadTimelinePivotFilter(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CTimelinePivotFilter* pPivotFilter = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + + if (c_oSer_TimelinePivotFilter::Name == type) + { + pPivotFilter->m_oName = m_oBufferedStream.GetString3(length); + } + else if (c_oSer_TimelinePivotFilter::Description == type) + { + pPivotFilter->m_oDescription = m_oBufferedStream.GetString3(length); + } + else if (c_oSer_TimelinePivotFilter::UseWholeDay == type) + { + pPivotFilter->m_oUseWholeDay = m_oBufferedStream.GetBool(); + } + else if (c_oSer_TimelinePivotFilter::Id == type) + { + pPivotFilter->m_oId = m_oBufferedStream.GetLong(); + } + else if (c_oSer_TimelinePivotFilter::Fld == type) + { + pPivotFilter->m_oFld = m_oBufferedStream.GetLong(); + } + else if (c_oSer_TimelinePivotFilter::AutoFilter == type) + { + pPivotFilter->m_oAutoFilter.Init(); + BinaryTableReader oBinaryTableReader(m_oBufferedStream, NULL); + READ1_DEF(length, res, oBinaryTableReader.ReadAutoFilter, pPivotFilter->m_oAutoFilter.GetPointer()); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadTimelineCachePivotTable(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CTimelineCachePivotTable* pPivotTable = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSer_TimelineCachePivotTable::Name == type) + { + pPivotTable->m_oName = m_oBufferedStream.GetString3(length); + } + else if (c_oSer_TimelineCachePivotTable::TabId == type) + { + pPivotTable->m_oTabId = m_oBufferedStream.GetLong(); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} BinaryCommentReader::BinaryCommentReader(NSBinPptxRW::CBinaryFileReader& oBufferedStream, OOX::Spreadsheet::CWorksheet* pCurWorksheet) : Binary_CommonReader(oBufferedStream), m_pCurWorksheet(pCurWorksheet) { @@ -3875,19 +4216,19 @@ int BinaryWorksheetsTableReader::ReadWorksheet(boost::unordered_mapReadSheetPr, &oSheetPr); SEEK_TO_POS_END(oSheetPr); //------------------------------------------------------------------------------------------------------------- - OOX::Spreadsheet::CSheetViews oSheetViews; + m_pCurWorksheet->m_oSheetViews.Init(); SEEK_TO_POS_START(c_oSerWorksheetsTypes::SheetViews); - READ1_DEF(length, res, this->ReadSheetViews, &oSheetViews); + READ1_DEF(length, res, this->ReadSheetViews, m_pCurWorksheet->m_oSheetViews.GetPointer()); SEEK_TO_POS_END2(); - if (oSheetViews.m_arrItems.empty()) - oSheetViews.m_arrItems.push_back(new OOX::Spreadsheet::CSheetView()); - OOX::Spreadsheet::CSheetView* pSheetView = oSheetViews.m_arrItems.front(); + if (m_pCurWorksheet->m_oSheetViews->m_arrItems.empty()) + m_pCurWorksheet->m_oSheetViews->m_arrItems.push_back(new OOX::Spreadsheet::CSheetView()); + OOX::Spreadsheet::CSheetView* pSheetView = m_pCurWorksheet->m_oSheetViews->m_arrItems.front(); if (false == pSheetView->m_oWorkbookViewId.IsInit()) { pSheetView->m_oWorkbookViewId.Init(); pSheetView->m_oWorkbookViewId->SetValue(0); } - oSheetViews.toXML(oStreamWriter); + m_pCurWorksheet->m_oSheetViews->toXML(oStreamWriter); //------------------------------------------------------------------------------------------------------------- OOX::Spreadsheet::CSheetFormatPr oSheetFormatPr; SEEK_TO_POS_START(c_oSerWorksheetsTypes::SheetFormatPr); @@ -4241,6 +4582,19 @@ int BinaryWorksheetsTableReader::ReadWorksheet(boost::unordered_mapm_oExtLst->m_arrExt.push_back(pOfficeArtExtension); SEEK_TO_POS_END2(); + SEEK_TO_POS_START(c_oSerWorksheetsTypes::TimelinesList); + OOX::Drawing::COfficeArtExtension* pOfficeArtExtension = new OOX::Drawing::COfficeArtExtension(); + pOfficeArtExtension->m_oTimelineRefs.Init(); + READ1_DEF(length, res, this->ReadTimelinesList, pOfficeArtExtension->m_oTimelineRefs.GetPointer()); + + pOfficeArtExtension->m_sUri = L"{7E03D99C-DC04-49d9-9315-930204A7B6E9}"; + pOfficeArtExtension->m_sAdditionalNamespace = L"xmlns:x15=\"http://schemas.microsoft.com/office/spreadsheetml/2010/11/main\""; + + if (m_pCurWorksheet->m_oExtLst.IsInit() == false) + m_pCurWorksheet->m_oExtLst.Init(); + m_pCurWorksheet->m_oExtLst->m_arrExt.push_back(pOfficeArtExtension); + SEEK_TO_POS_END2(); + if (m_pCurWorksheet->m_oExtLst.IsInit()) { oStreamWriter.WriteString(m_pCurWorksheet->m_oExtLst->toXMLWithNS(L"")); @@ -6005,7 +6359,7 @@ int BinaryWorksheetsTableReader::ReadCells(BYTE type, long length, void* poResul bMoveText = true; oCell.m_oType->SetValue(SimpleTypes::Spreadsheet::celltypeStr); } - if (bMoveText) + if (bMoveText && SimpleTypes::Spreadsheet::celltypeSharedString == eCellType) { int nValue = XmlUtils::GetInteger(oCell.m_oValue->ToString()); @@ -6024,6 +6378,26 @@ int BinaryWorksheetsTableReader::ReadCells(BYTE type, long length, void* poResul } } } + else if(bMoveText && SimpleTypes::Spreadsheet::celltypeError == eCellType) + { + int nValue = XmlUtils::GetInteger(oCell.m_oValue->ToString()); + std::wstring errText; + switch(nValue) + { + case 0x00: errText = L"#NULL!"; break; + case 0x07: errText = L"#DIV/0!"; break; + case 0x0F: errText = L"#VALUE!"; break; + case 0x17: errText = L"#REF!"; break; + case 0x1D: errText = L"#NAME?"; break; + case 0x24: errText = L"#NUM!"; break; + case 0x2A: errText = L"#N/A"; break; + case 0x2B: errText = L"#GETTING_DATA"; break; + default: + errText = L"#NULL!"; + break; + }; + oCell.m_oValue->m_sText = errText; + } } if (NULL == m_oSaveParams.pCSVWriter) { @@ -6082,6 +6456,14 @@ int BinaryWorksheetsTableReader::ReadCell(BYTE type, long length, void* poResult { pCell->m_oCacheValue = m_oBufferedStream.GetString4(length); } + else if (c_oSerCellTypes::CellMetadata == type) + { + pCell->m_oCellMetadata = m_oBufferedStream.GetULong(); + } + else if (c_oSerCellTypes::ValueMetadata == type) + { + pCell->m_oValueMetadata = m_oBufferedStream.GetULong(); + } else res = c_oSerConstants::ReadUnknown; return res; @@ -6551,6 +6933,11 @@ int BinaryWorksheetsTableReader::ReadUserProtectedRangeDesc(BYTE type, long leng { desc->id = m_oBufferedStream.GetString4(length); } + else if (c_oSer_UserProtectedRangeDesc::Type == type) + { + desc->type.Init(); + desc->type->SetValueFromByte(m_oBufferedStream.GetUChar()); + } else res = c_oSerConstants::ReadUnknown; return res; @@ -6571,6 +6958,11 @@ int BinaryWorksheetsTableReader::ReadUserProtectedRange(BYTE type, long length, { pUserProtectedRange->m_oText = m_oBufferedStream.GetString4(length); } + else if (c_oSer_UserProtectedRange::Type == type) + { + pUserProtectedRange->m_oType.Init(); + pUserProtectedRange->m_oType->SetValueFromByte(m_oBufferedStream.GetUChar()); + } else if (c_oSer_UserProtectedRange::User == type) { OOX::Spreadsheet::CUserProtectedRange::_UsersGroupsDesc desc; @@ -7187,51 +7579,150 @@ int BinaryWorksheetsTableReader::ReadDataValidation(BYTE type, long length, void pDataValidation->m_oFormula2.Init(); pDataValidation->m_oFormula2->m_sText = m_oBufferedStream.GetString4(length); } + else if (c_oSer_DataValidation::List == type) + { + pDataValidation->m_oList = m_oBufferedStream.GetString4(length); + } else res = c_oSerConstants::ReadUnknown; return res; } -int BinaryWorksheetsTableReader::ReadSparklines(BYTE type, long length, void* poResult) -{ - OOX::Spreadsheet::CSparklines* pSparklines = static_cast(poResult); - int res = c_oSerConstants::ReadOk; - if (c_oSer_Sparkline::Sparkline == type) - { - OOX::Spreadsheet::CSparkline* pSparkline = new OOX::Spreadsheet::CSparkline(); - READ1_DEF(length, res, this->ReadSparkline, pSparkline); - pSparklines->m_arrItems.push_back(pSparkline); - } - else - res = c_oSerConstants::ReadUnknown; - return res; -} -int BinaryWorksheetsTableReader::ReadSparkline(BYTE type, long length, void* poResult) +int BinaryWorksheetsTableReader::ReadTimelines(BYTE type, long length, void* poResult) { - OOX::Spreadsheet::CSparkline* pSparkline = static_cast(poResult); - int res = c_oSerConstants::ReadOk; - if (c_oSer_Sparkline::SparklineRef == type) - { - pSparkline->m_oRef.Init(); - pSparkline->m_oRef->append(m_oBufferedStream.GetString4(length)); - } - else if (c_oSer_Sparkline::SparklineSqRef == type) - { - pSparkline->m_oSqRef.Init(); - pSparkline->m_oSqRef->append(m_oBufferedStream.GetString4(length)); - } - else - res = c_oSerConstants::ReadUnknown; - return res; + OOX::Spreadsheet::CTimelines* pTimelines = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSerWorksheetsTypes::Timeline == type) + { + OOX::Spreadsheet::CTimeline* pTimeline = new OOX::Spreadsheet::CTimeline(); + READ2_DEF_SPREADSHEET(length, res, this->ReadTimeline, pTimeline); + pTimelines->m_arrItems.push_back(pTimeline); + } + else + res = c_oSerConstants::ReadUnknown; + return res; } -int BinaryWorksheetsTableReader::ReadSlicers(BYTE type, long length, void* poResult) +int BinaryWorksheetsTableReader::ReadTimelinesList(BYTE type, long length, void* poResult) { - OOX::Spreadsheet::CSlicerRefs* pSlicerRefs = static_cast(poResult); - int res = c_oSerConstants::ReadOk; - if (c_oSerWorksheetsTypes::Slicer == type) - { - OOX::Spreadsheet::CSlicerFile* pSlicer = new OOX::Spreadsheet::CSlicerFile(NULL); - pSlicer->m_oSlicers.Init(); - + OOX::Spreadsheet::CTimelineRefs* pTimelineRefs = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSerWorksheetsTypes::Timelines == type) + { + OOX::Spreadsheet::CTimelineFile* pTimelineFile = new OOX::Spreadsheet::CTimelineFile(NULL); + pTimelineFile->m_oTimelines.Init(); + + READ1_DEF(length, res, this->ReadTimelines, pTimelineFile->m_oTimelines.GetPointer()); + + NSCommon::smart_ptr pFile(pTimelineFile); + const OOX::RId oRId = m_pCurWorksheet->Add(pFile); + + OOX::Spreadsheet::CTimelineRef* pTimelineRef = new OOX::Spreadsheet::CTimelineRef(); + pTimelineRef->m_oRId.Init(); + pTimelineRef->m_oRId->SetValue(oRId.get()); + + pTimelineRefs->m_arrItems.push_back(pTimelineRef); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorksheetsTableReader::ReadTimeline(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CTimeline* pTimeline = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSer_Timeline::Name == type) + { + pTimeline->m_oName = m_oBufferedStream.GetString4(length); + } + else if (c_oSer_Timeline::Cache == type) + { + pTimeline->m_oCache = m_oBufferedStream.GetString4(length); + } + else if (c_oSer_Timeline::Caption == type) + { + pTimeline->m_oCaption = m_oBufferedStream.GetString4(length); + } + else if (c_oSer_Timeline::ScrollPosition == type) + { + pTimeline->m_oScrollPosition = m_oBufferedStream.GetString4(length); + } + else if (c_oSer_Timeline::Uid == type) + { + pTimeline->m_oUid = m_oBufferedStream.GetString4(length); + } + else if (c_oSer_Timeline::Level == type) + { + pTimeline->m_oLevel = m_oBufferedStream.GetULong(); + } + else if (c_oSer_Timeline::SelectionLevel == type) + { + pTimeline->m_oSelectionLevel = m_oBufferedStream.GetULong(); + } + else if (c_oSer_Timeline::ShowHeader == type) + { + pTimeline->m_oShowHeader = m_oBufferedStream.GetBool(); + } + else if (c_oSer_Timeline::ShowHorizontalScrollbar == type) + { + pTimeline->m_oShowHorizontalScrollbar = m_oBufferedStream.GetBool(); + } + else if (c_oSer_Timeline::ShowSelectionLabel == type) + { + pTimeline->m_oShowSelectionLabel = m_oBufferedStream.GetBool(); + } + else if (c_oSer_Timeline::ShowTimeLevel == type) + { + pTimeline->m_oShowTimeLevel = m_oBufferedStream.GetBool(); + } + else if (c_oSer_Timeline::Style == type) + { + pTimeline->m_oStyle.Init(); + pTimeline->m_oStyle->SetValueFromByte(m_oBufferedStream.GetUChar()); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorksheetsTableReader::ReadSparklines(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CSparklines* pSparklines = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSer_Sparkline::Sparkline == type) + { + OOX::Spreadsheet::CSparkline* pSparkline = new OOX::Spreadsheet::CSparkline(); + READ1_DEF(length, res, this->ReadSparkline, pSparkline); + pSparklines->m_arrItems.push_back(pSparkline); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorksheetsTableReader::ReadSparkline(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CSparkline* pSparkline = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSer_Sparkline::SparklineRef == type) + { + pSparkline->m_oRef.Init(); + pSparkline->m_oRef->append(m_oBufferedStream.GetString4(length)); + } + else if (c_oSer_Sparkline::SparklineSqRef == type) + { + pSparkline->m_oSqRef.Init(); + pSparkline->m_oSqRef->append(m_oBufferedStream.GetString4(length)); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorksheetsTableReader::ReadSlicers(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CSlicerRefs* pSlicerRefs = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSerWorksheetsTypes::Slicer == type) + { + OOX::Spreadsheet::CSlicerFile* pSlicer = new OOX::Spreadsheet::CSlicerFile(NULL); + pSlicer->m_oSlicers.Init(); + m_oBufferedStream.GetUChar();//type pSlicer->m_oSlicers->fromPPTY(&m_oBufferedStream); @@ -7534,6 +8025,501 @@ int BinaryCustomsReader::ReadCustomContent(BYTE type, long length, void* poResul res = c_oSerConstants::ReadUnknown; return res; } +int BinaryWorkbookTableReader::ReadMetadata(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CMetadata* pMetadata = static_cast(poResult); + + int res = c_oSerConstants::ReadOk; + if (c_oSer_Metadata::MetadataTypes == type) + { + pMetadata->m_oMetadataTypes.Init(); + READ1_DEF(length, res, this->ReadMetadataTypes, pMetadata->m_oMetadataTypes.GetPointer()); + } + else if (c_oSer_Metadata::MetadataStrings == type) + { + pMetadata->m_oMetadataStrings.Init(); + READ1_DEF(length, res, this->ReadMetadataStrings, pMetadata->m_oMetadataStrings.GetPointer()); + } + else if (c_oSer_Metadata::MdxMetadata == type) + { + pMetadata->m_oMdxMetadata.Init(); + READ1_DEF(length, res, this->ReadMdxMetadata, pMetadata->m_oMdxMetadata.GetPointer()); + } + else if (c_oSer_Metadata::CellMetadata == type) + { + pMetadata->m_oCellMetadata.Init(); + READ1_DEF(length, res, this->ReadMetadataBlocks, pMetadata->m_oCellMetadata.GetPointer()); + } + else if (c_oSer_Metadata::ValueMetadata == type) + { + pMetadata->m_oValueMetadata.Init(); + READ1_DEF(length, res, this->ReadMetadataBlocks, pMetadata->m_oValueMetadata.GetPointer()); + } + else if (c_oSer_Metadata::FutureMetadata == type) + { + OOX::Spreadsheet::CFutureMetadata* pFutureMetadata = new OOX::Spreadsheet::CFutureMetadata(); + READ1_DEF(length, res, this->ReadFutureMetadata, pFutureMetadata); + pMetadata->m_arFutureMetadata.push_back(pFutureMetadata); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadMetadataTypes(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CMetadataTypes* pMetadataTypes = static_cast(poResult); + + int res = c_oSerConstants::ReadOk; + if (c_oSer_MetadataType::MetadataType == type) + { + OOX::Spreadsheet::CMetadataType* pMetadataType = new OOX::Spreadsheet::CMetadataType(); + READ1_DEF(length, res, this->ReadMetadataType, pMetadataType); + pMetadataTypes->m_arrItems.push_back(pMetadataType); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadMetadataType(BYTE type, long length, void* poResult) +{ + int res = c_oSerConstants::ReadOk; + OOX::Spreadsheet::CMetadataType* pMetadataType = static_cast(poResult); + + if (c_oSer_MetadataType::Name == type) + { + pMetadataType->m_oName = m_oBufferedStream.GetString3(length); + } + else if (c_oSer_MetadataType::MinSupportedVersion == type) + { + pMetadataType->m_oMinSupportedVersion = m_oBufferedStream.GetULong(); + } + else if (c_oSer_MetadataType::GhostRow == type) + { + pMetadataType->m_oGhostRow = m_oBufferedStream.GetBool(); + } + else if (c_oSer_MetadataType::GhostCol == type) + { + pMetadataType->m_oGhostCol = m_oBufferedStream.GetBool(); + } + else if (c_oSer_MetadataType::Edit == type) + { + pMetadataType->m_oEdit = m_oBufferedStream.GetBool(); + } + else if (c_oSer_MetadataType::Delete == type) + { + pMetadataType->m_oDelete = m_oBufferedStream.GetBool(); + } + else if (c_oSer_MetadataType::Copy == type) + { + pMetadataType->m_oCopy = m_oBufferedStream.GetBool(); + } + else if (c_oSer_MetadataType::PasteAll == type) + { + pMetadataType->m_oPasteAll = m_oBufferedStream.GetBool(); + } + else if (c_oSer_MetadataType::PasteFormulas == type) + { + pMetadataType->m_oPasteFormulas = m_oBufferedStream.GetBool(); + } + else if (c_oSer_MetadataType::PasteValues == type) + { + pMetadataType->m_oPasteValues = m_oBufferedStream.GetBool(); + } + else if (c_oSer_MetadataType::PasteFormats == type) + { + pMetadataType->m_oPasteFormats = m_oBufferedStream.GetBool(); + } + else if (c_oSer_MetadataType::PasteComments == type) + { + pMetadataType->m_oPasteComments = m_oBufferedStream.GetBool(); + } + else if (c_oSer_MetadataType::PasteDataValidation == type) + { + pMetadataType->m_oPasteDataValidation = m_oBufferedStream.GetBool(); + } + else if (c_oSer_MetadataType::PasteBorders == type) + { + pMetadataType->m_oPasteBorders = m_oBufferedStream.GetBool(); + } + else if (c_oSer_MetadataType::PasteColWidths == type) + { + pMetadataType->m_oPasteColWidths = m_oBufferedStream.GetBool(); + } + else if (c_oSer_MetadataType::PasteNumberFormats == type) + { + pMetadataType->m_oPasteNumberFormats = m_oBufferedStream.GetBool(); + } + else if (c_oSer_MetadataType::Merge == type) + { + pMetadataType->m_oMerge = m_oBufferedStream.GetBool(); + } + else if (c_oSer_MetadataType::SplitFirst == type) + { + pMetadataType->m_oSplitFirst = m_oBufferedStream.GetBool(); + } + else if (c_oSer_MetadataType::SplitAll == type) + { + pMetadataType->m_oSplitAll = m_oBufferedStream.GetBool(); + } + else if (c_oSer_MetadataType::RowColShift == type) + { + pMetadataType->m_oRowColShift = m_oBufferedStream.GetBool(); + } + else if (c_oSer_MetadataType::ClearAll == type) + { + pMetadataType->m_oClearAll = m_oBufferedStream.GetBool(); + } + else if (c_oSer_MetadataType::ClearFormats == type) + { + pMetadataType->m_oClearFormats = m_oBufferedStream.GetBool(); + } + else if (c_oSer_MetadataType::ClearContents == type) + { + pMetadataType->m_oClearContents = m_oBufferedStream.GetBool(); + } + else if (c_oSer_MetadataType::ClearComments == type) + { + pMetadataType->m_oClearComments = m_oBufferedStream.GetBool(); + } + else if (c_oSer_MetadataType::Assign == type) + { + pMetadataType->m_oAssign = m_oBufferedStream.GetBool(); + } + else if (c_oSer_MetadataType::Coerce == type) + { + pMetadataType->m_oCoerce = m_oBufferedStream.GetBool(); + } + else if (c_oSer_MetadataType::CellMeta == type) + { + pMetadataType->m_oCellMeta = m_oBufferedStream.GetBool(); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadMetadataStrings(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CMetadataStrings* pMetadataStrings = static_cast(poResult); + + int res = c_oSerConstants::ReadOk; + if (c_oSer_MetadataString::MetadataString == type) + { + OOX::Spreadsheet::CMetadataString* pMetadataString = new OOX::Spreadsheet::CMetadataString(); + pMetadataString->m_oV = m_oBufferedStream.GetString3(length); + pMetadataStrings->m_arrItems.push_back(pMetadataString); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadMdxMetadata(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CMdxMetadata* pMdxMetadata = static_cast(poResult); + + int res = c_oSerConstants::ReadOk; + if (c_oSer_MdxMetadata::Mdx == type) + { + OOX::Spreadsheet::CMdx* pMdx = new OOX::Spreadsheet::CMdx(); + READ1_DEF(length, res, this->ReadMdx, pMdx); + pMdxMetadata->m_arrItems.push_back(pMdx); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadMdx(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CMdx* pMdx = static_cast(poResult); + + int res = c_oSerConstants::ReadOk; + if (c_oSer_MdxMetadata::NameIndex == type) + { + pMdx->m_oN = m_oBufferedStream.GetULong(); + } + else if (c_oSer_MdxMetadata::FunctionTag == type) + { + pMdx->m_oF.Init(); + pMdx->m_oF->SetValueFromByte(m_oBufferedStream.GetUChar()); + } + else if (c_oSer_MdxMetadata::MdxTuple == type) + { + pMdx->m_oMdxTuple.Init(); + READ1_DEF(length, res, this->ReadMdxTuple, pMdx->m_oMdxTuple.GetPointer()); + } + else if (c_oSer_MdxMetadata::MdxSet == type) + { + pMdx->m_oMdxSet.Init(); + READ1_DEF(length, res, this->ReadMdxSet, pMdx->m_oMdxSet.GetPointer()); + } + else if (c_oSer_MdxMetadata::MdxKPI == type) + { + pMdx->m_oCMdxKPI.Init(); + READ1_DEF(length, res, this->ReadMdxKPI, pMdx->m_oCMdxKPI.GetPointer()); + } + else if (c_oSer_MdxMetadata::MdxMemeberProp == type) + { + pMdx->m_oMdxMemeberProp.Init(); + READ1_DEF(length, res, this->ReadMdxMemeberProp, pMdx->m_oMdxMemeberProp.GetPointer()); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadMetadataBlocks(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CMetadataBlocks* pMetadataBlocks = static_cast(poResult); + + int res = c_oSerConstants::ReadOk; + if (c_oSer_MetadataBlock::MetadataBlock == type) + { + OOX::Spreadsheet::CMetadataBlock* pMetadataBlock = new OOX::Spreadsheet::CMetadataBlock(); + READ1_DEF(length, res, this->ReadMetadataBlock, pMetadataBlock); + pMetadataBlocks->m_arrItems.push_back(pMetadataBlock); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadMetadataBlock(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CMetadataBlock* pMetadataBlock = static_cast(poResult); + + int res = c_oSerConstants::ReadOk; + if (c_oSer_MetadataBlock::MetadataRecord == type) + { + OOX::Spreadsheet::CMetadataRecord* pMetadataRecord = new OOX::Spreadsheet::CMetadataRecord(); + READ1_DEF(length, res, this->ReadMetadataRecord, pMetadataRecord); + pMetadataBlock->m_arrItems.push_back(pMetadataRecord); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadMetadataRecord(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CMetadataRecord* pMetadataRecord = static_cast(poResult); + + int res = c_oSerConstants::ReadOk; + if (c_oSer_MetadataBlock::MetadataRecordType == type) + { + pMetadataRecord->m_oT = m_oBufferedStream.GetULong(); + } + else if (c_oSer_MetadataBlock::MetadataRecordValue == type) + { + pMetadataRecord->m_oV = m_oBufferedStream.GetULong(); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadDynamicArrayProperties(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CDynamicArrayProperties* pDynamicArrayProperties = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + + if (c_oSer_FutureMetadataBlock::DynamicArray == type) + { + pDynamicArrayProperties->m_oFDynamic = m_oBufferedStream.GetBool(); + } + else if (c_oSer_FutureMetadataBlock::CollapsedArray == type) + { + pDynamicArrayProperties->m_oFCollapsed = m_oBufferedStream.GetBool(); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadMetadataStringIndex(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CMetadataStringIndex* pStringIndex = static_cast(poResult); + + int res = c_oSerConstants::ReadOk; + if (c_oSer_MetadataStringIndex::StringIsSet == type) + { + pStringIndex->m_oS = m_oBufferedStream.GetULong(); + } + else if (c_oSer_MetadataStringIndex::IndexValue == type) + { + pStringIndex->m_oX = m_oBufferedStream.GetULong(); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadMdxMemeberProp(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CMdxMemeberProp* pMdxMemeberProp = static_cast(poResult); + + int res = c_oSerConstants::ReadOk; + if (c_oSer_MetadataMemberProperty::NameIndex == type) + { + pMdxMemeberProp->m_oN = m_oBufferedStream.GetULong(); + } + else if (c_oSer_MetadataMemberProperty::Index == type) + { + pMdxMemeberProp->m_oNp = m_oBufferedStream.GetULong(); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadMdxKPI(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CMdxKPI* pMdxKPI = static_cast(poResult); + + int res = c_oSerConstants::ReadOk; + if (c_oSer_MetadataMdxKPI::NameIndex == type) + { + pMdxKPI->m_oN = m_oBufferedStream.GetULong(); + } + else if (c_oSer_MetadataMdxKPI::Index == type) + { + pMdxKPI->m_oNp = m_oBufferedStream.GetULong(); + } + else if (c_oSer_MetadataMdxKPI::Property == type) + { + pMdxKPI->m_oP.Init(); + pMdxKPI->m_oP->SetValueFromByte(m_oBufferedStream.GetUChar()); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadMdxSet(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CMdxSet* pMdxSet = static_cast(poResult); + + int res = c_oSerConstants::ReadOk; + if (c_oSer_MetadataMdxSet::Count == type) + { + pMdxSet->m_oC = m_oBufferedStream.GetULong(); + } + else if (c_oSer_MetadataMdxSet::Index == type) + { + pMdxSet->m_oNs = m_oBufferedStream.GetULong(); + } + else if (c_oSer_MetadataMdxSet::SortOrder == type) + { + pMdxSet->m_oO.Init(); + pMdxSet->m_oO->SetValueFromByte(m_oBufferedStream.GetUChar()); + } + else if (c_oSer_MetadataMdxSet::MetadataStringIndex == type) + { + OOX::Spreadsheet::CMetadataStringIndex* pMetadataStringIndex = new OOX::Spreadsheet::CMetadataStringIndex(); + READ1_DEF(length, res, this->ReadMetadataStringIndex, pMetadataStringIndex); + pMdxSet->m_arrItems.push_back(pMetadataStringIndex); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadMdxTuple(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CMdxTuple* pMdxTuple = static_cast(poResult); + + int res = c_oSerConstants::ReadOk; + if (c_oSer_MetadataMdxTuple::IndexCount == type) + { + pMdxTuple->m_oC = m_oBufferedStream.GetULong(); + } + else if (c_oSer_MetadataMdxTuple::StringIndex == type) + { + pMdxTuple->m_oSi = m_oBufferedStream.GetULong(); + } + else if (c_oSer_MetadataMdxTuple::CultureCurrency == type) + { + pMdxTuple->m_oCt = m_oBufferedStream.GetString3(length); + } + else if (c_oSer_MetadataMdxTuple::NumFmtIndex == type) + { + pMdxTuple->m_oFi = m_oBufferedStream.GetULong(); + } + else if (c_oSer_MetadataMdxTuple::BackColor == type) + { + pMdxTuple->m_oBc = m_oBufferedStream.GetULong(); + } + else if (c_oSer_MetadataMdxTuple::ForeColor == type) + { + pMdxTuple->m_oFc = m_oBufferedStream.GetULong(); + } + else if (c_oSer_MetadataMdxTuple::Italic == type) + { + pMdxTuple->m_oI = m_oBufferedStream.GetBool(); + } + else if (c_oSer_MetadataMdxTuple::Bold == type) + { + pMdxTuple->m_oB = m_oBufferedStream.GetBool(); + } + else if (c_oSer_MetadataMdxTuple::Underline == type) + { + pMdxTuple->m_oU = m_oBufferedStream.GetBool(); + } + else if (c_oSer_MetadataMdxTuple::Strike == type) + { + pMdxTuple->m_oSt = m_oBufferedStream.GetBool(); + } + else if (c_oSer_MetadataMdxTuple::MetadataStringIndex == type) + { + OOX::Spreadsheet::CMetadataStringIndex* pMetadataStringIndex = new OOX::Spreadsheet::CMetadataStringIndex(); + READ1_DEF(length, res, this->ReadMetadataStringIndex, pMetadataStringIndex); + pMdxTuple->m_arrItems.push_back(pMetadataStringIndex); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadFutureMetadata(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CFutureMetadata* pCFutureMetadata = static_cast(poResult); + + int res = c_oSerConstants::ReadOk; + + if (c_oSer_FutureMetadataBlock::Name == type) + { + pCFutureMetadata->m_oName = m_oBufferedStream.GetString3(length); + } + else if (c_oSer_FutureMetadataBlock::FutureMetadataBlock == type) + { + OOX::Spreadsheet::CFutureMetadataBlock* pFutureMetadataBlock = new OOX::Spreadsheet::CFutureMetadataBlock(); + READ1_DEF(length, res, this->ReadFutureMetadataBlock, pFutureMetadataBlock); + pCFutureMetadata->m_arrItems.push_back(pFutureMetadataBlock); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadFutureMetadataBlock(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CFutureMetadataBlock* pFutureMetadataBlock = static_cast(poResult); + + int res = c_oSerConstants::ReadOk; + if (c_oSer_FutureMetadataBlock::RichValueBlock == type) + { + if (false == pFutureMetadataBlock->m_oExtLst.IsInit()) pFutureMetadataBlock->m_oExtLst.Init(); + + OOX::Drawing::COfficeArtExtension* pExt = new OOX::Drawing::COfficeArtExtension(); + pExt->m_sUri = L"{3e2802c4-a4d2-4d8b-9148-e3be6c30e623}"; + pExt->m_oRichValueBlock.Init(); + pExt->m_oRichValueBlock->m_oI = m_oBufferedStream.GetULong(); + + pFutureMetadataBlock->m_oExtLst->m_arrExt.push_back(pExt); + } + else if (c_oSer_FutureMetadataBlock::DynamicArrayProperties == type) + { + if (false == pFutureMetadataBlock->m_oExtLst.IsInit()) pFutureMetadataBlock->m_oExtLst.Init(); + + OOX::Drawing::COfficeArtExtension* pExt = new OOX::Drawing::COfficeArtExtension(); + pExt->m_sUri = L"{bdbb8cdc-fa1e-496e-a857-3c3f30c029c3}"; + pExt->m_oDynamicArrayProperties.Init(); + + READ1_DEF(length, res, this->ReadDynamicArrayProperties, pExt->m_oDynamicArrayProperties.GetPointer()); + pFutureMetadataBlock->m_oExtLst->m_arrExt.push_back(pExt); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} + //------------------------------------------------------------------------------------------------------------------------------------ BinaryFileReader::BinaryFileReader() { @@ -7644,7 +8630,7 @@ int BinaryFileReader::Xml2Xlsx(const std::wstring& sSrcFileName, std::wstring sD delete pXlsxFlat; return 0; } -int BinaryFileReader::ReadFile(const std::wstring& sSrcFileName, std::wstring sDstPath, NSBinPptxRW::CDrawingConverter* pOfficeDrawingConverter, const std::wstring& sXMLOptions, bool bMacro) +int BinaryFileReader::ReadFile(const std::wstring& sSrcFileName, std::wstring sDstPath, NSBinPptxRW::CDrawingConverter* pOfficeDrawingConverter, const std::wstring& sXMLOptions, bool &bMacro) { bool bResultOk = false; @@ -7737,16 +8723,17 @@ int BinaryFileReader::ReadFile(const std::wstring& sSrcFileName, std::wstring sD if (NULL != pData) { - // File Type + // File Type std::wstring sDstPathCSV = sDstPath; BYTE fileType; UINT nCodePage; std::wstring sDelimiter; BYTE saveFileType; + _INT32 Lcid; + + SerializeCommon::ReadFileType(sXMLOptions, fileType, nCodePage, sDelimiter, saveFileType, Lcid); + // Делаем для CSV перебивку пути, иначе создается папка с одинаковым имеем (для rels) и файл не создается. - SerializeCommon::ReadFileType(sXMLOptions, fileType, nCodePage, sDelimiter, saveFileType); - // Делаем для CSV перебивку пути, иначе создается папка с одинаковым имеем (для rels) и файл не создается. - if (BinXlsxRW::c_oFileTypes::CSV == fileType) { sDstPath = pOfficeDrawingConverter->GetTempPath(); @@ -7755,44 +8742,67 @@ int BinaryFileReader::ReadFile(const std::wstring& sSrcFileName, std::wstring sD sDstPath = NSDirectory::CreateDirectoryWithUniqueName(sDstPath); } - - OOX::Spreadsheet::CXlsx oXlsx; - + std::wstring themePath = sDstPath + FILE_SEPARATOR_STR + OOX::Spreadsheet::FileTypes::Workbook.DefaultDirectory().GetPath() + FILE_SEPARATOR_STR + OOX::FileTypes::Theme.DefaultDirectory().GetPath(); std::wstring drawingsPath = sDstPath + FILE_SEPARATOR_STR + OOX::Spreadsheet::FileTypes::Workbook.DefaultDirectory().GetPath() + FILE_SEPARATOR_STR + OOX::Spreadsheet::FileTypes::Drawings.DefaultDirectory().GetPath(); std::wstring embeddingsPath = sDstPath + FILE_SEPARATOR_STR + OOX::Spreadsheet::FileTypes::Workbook.DefaultDirectory().GetPath() + FILE_SEPARATOR_STR + OOX::FileTypes::MicrosoftOfficeUnknown.DefaultDirectory().GetPath(); std::wstring chartsPath = sDstPath + FILE_SEPARATOR_STR + OOX::Spreadsheet::FileTypes::Workbook.DefaultDirectory().GetPath() + FILE_SEPARATOR_STR + OOX::FileTypes::Chart.DefaultDirectory().GetPath(); oBufferedStream.m_pRels->m_pManager->SetDstCharts(chartsPath); - + bResultOk = true; - + if (BinXlsxRW::c_oFileTypes::XLSX == fileType) { + OOX::Spreadsheet::CXlsx oXlsx; SaveParams oSaveParams(drawingsPath, embeddingsPath, themePath, pOfficeDrawingConverter->GetContentTypes(), NULL, bMacro); - + try { ReadMainTable(oXlsx, oBufferedStream, OOX::CPath(sSrcFileName).GetDirectory(), sDstPath, oSaveParams, pOfficeDrawingConverter); } - catch(...) + catch (...) { bResultOk = false; } - + oXlsx.PrepareToWrite(); oXlsx.Write(sDstPath, *oSaveParams.pContentTypes); + + bMacro = oSaveParams.bMacroEnabled; + } + else if (BinXlsxRW::c_oFileTypes::XLSB == fileType) + { + OOX::Spreadsheet::CXlsb oXlsb; + oXlsb.m_bWriteToXlsb = true; + + SaveParams oSaveParams(drawingsPath, embeddingsPath, themePath, pOfficeDrawingConverter->GetContentTypes(), NULL, bMacro); + + try + { + ReadMainTable(oXlsb, oBufferedStream, OOX::CPath(sSrcFileName).GetDirectory(), sDstPath, oSaveParams, pOfficeDrawingConverter); + } + catch (...) + { + bResultOk = false; + } + + oXlsb.PrepareToWrite(); + oXlsb.WriteBin(sDstPath, *oSaveParams.pContentTypes); + + bMacro = oSaveParams.bMacroEnabled; } else { + OOX::Spreadsheet::CXlsx oXlsx; CSVWriter oCSVWriter; - oCSVWriter.Init(oXlsx, nCodePage, sDelimiter, false); + oCSVWriter.Init(oXlsx, nCodePage, sDelimiter, Lcid, false); bResultOk = oCSVWriter.Start(sDstPathCSV); if (!bResultOk) return AVS_FILEUTILS_ERROR_CONVERT; - SaveParams oSaveParams(drawingsPath, embeddingsPath, themePath, pOfficeDrawingConverter->GetContentTypes(), &oCSVWriter); + SaveParams oSaveParams(drawingsPath, embeddingsPath, themePath, pOfficeDrawingConverter->GetContentTypes(), &oCSVWriter, false); try { @@ -7913,11 +8923,8 @@ int BinaryFileReader::ReadMainTable(OOX::Spreadsheet::CXlsx& oXlsx, NSBinPptxRW: { case c_oSerTableTypes::App: { - PPTX::App oApp(NULL); - oApp.fromPPTY(&oBufferedStream); - OOX::CApp* pApp = new OOX::CApp(NULL); - pApp->FromPptxApp(&oApp); + pApp->fromPPTY(&oBufferedStream); pApp->SetRequiredDefaults(); oXlsx.m_pApp = pApp; smart_ptr oCurFile(pApp); @@ -7925,11 +8932,8 @@ int BinaryFileReader::ReadMainTable(OOX::Spreadsheet::CXlsx& oXlsx, NSBinPptxRW: }break; case c_oSerTableTypes::Core: { - PPTX::Core oCore(NULL); - oCore.fromPPTY(&oBufferedStream); - OOX::CCore* pCore = new OOX::CCore(NULL); - pCore->FromPptxCore(&oCore); + pCore->fromPPTY(&oBufferedStream); pCore->SetRequiredDefaults(); oXlsx.m_pCore = pCore; smart_ptr oCurFile(pCore); diff --git a/OOXML/Binary/Sheets/Writer/BinaryReader.h b/OOXML/Binary/Sheets/Writer/BinaryReader.h index 1ff1f1920c8..d1551af149a 100644 --- a/OOXML/Binary/Sheets/Writer/BinaryReader.h +++ b/OOXML/Binary/Sheets/Writer/BinaryReader.h @@ -193,6 +193,9 @@ namespace BinXlsxRW int ReadTableCustomStyle(BYTE type, long length, void* poResult); int ReadTableCustomStyleElements(BYTE type, long length, void* poResult); int ReadTableCustomStyleElement(BYTE type, long length, void* poResult); + int ReadTimelineStyles(BYTE type, long length, void* poResult); + int ReadTimelineStyle(BYTE type, long length, void* poResult); + int ReadTimelineStyleElement(BYTE type, long length, void* poResult); }; class BinaryWorkbookTableReader : public Binary_CommonReader { @@ -216,6 +219,7 @@ namespace BinXlsxRW int ReadDefinedNames(BYTE type, long length, void* poResult); int ReadDefinedName(BYTE type, long length, void* poResult); int ReadCalcPr(BYTE type, long length, void* poResult); + int ReadExternalBook(BYTE type, long length, void* poResult); int ReadExternalSheetNames(BYTE type, long length, void* poResult); int ReadExternalDefinedNames(BYTE type, long length, void* poResult); @@ -225,6 +229,7 @@ namespace BinXlsxRW int ReadExternalRow(BYTE type, long length, void* poResult); int ReadExternalCell(BYTE type, long length, void* poResult); int ReadExternalAlternateUrls(BYTE type, long length, void* poResult); + int ReadOleLink(BYTE type, long length, void* poResult); int ReadOleItem(BYTE type, long length, void* poResult); int ReadDdeLink(BYTE type, long length, void* poResult); @@ -233,6 +238,7 @@ namespace BinXlsxRW int ReadDdeValue(BYTE type, long length, void* poResult); int ReadPivotCaches(BYTE type, long length, void* poResult); int ReadPivotCache(BYTE type, long length, void* poResult); + int ReadConnections(BYTE type, long length, void* poResult); int ReadConnection(BYTE type, long length, void* poResult); int ReadConnectionDbPr(BYTE type, long length, void* poResult); @@ -242,7 +248,34 @@ namespace BinXlsxRW int ReadConnectionRangePr(BYTE type, long length, void* poResult); int ReadConnectionTextFields(BYTE type, long length, void* poResult); int ReadConnectionTextField(BYTE type, long length, void* poResult); + int ReadSlicerCaches(BYTE type, long length, void* poResult); + + int ReadTimelineCaches(BYTE type, long length, void* poResult); + int ReadTimelineCache(BYTE type, long length, void* poResult); + int ReadTimelineState(BYTE type, long length, void* poResult); + int ReadTimelinePivotFilter(BYTE type, long length, void* poResult); + int ReadTimelineCachePivotTables(BYTE type, long length, void* poResult); + int ReadTimelineCachePivotTable(BYTE type, long length, void* poResult); + int ReadTimelineRange(BYTE type, long length, void* poResult); + + int ReadMetadata(BYTE type, long length, void* poResult); + int ReadMetadataTypes(BYTE type, long length, void* poResult); + int ReadMetadataType(BYTE type, long length, void* poResult); + int ReadMetadataStrings(BYTE type, long length, void* poResult); + int ReadMdxMetadata(BYTE type, long length, void* poResult); + int ReadMdx(BYTE type, long length, void* poResult); + int ReadMetadataBlocks(BYTE type, long length, void* poResult); + int ReadMetadataBlock(BYTE type, long length, void* poResult); + int ReadMetadataRecord(BYTE type, long length, void* poResult); + int ReadFutureMetadata(BYTE type, long length, void* poResult); + int ReadFutureMetadataBlock(BYTE type, long length, void* poResult); + int ReadMdxTuple(BYTE type, long length, void* poResult); + int ReadMdxSet(BYTE type, long length, void* poResult); + int ReadMdxKPI(BYTE type, long length, void* poResult); + int ReadMdxMemeberProp(BYTE type, long length, void* poResult); + int ReadMetadataStringIndex(BYTE type, long length, void* poResult); + int ReadDynamicArrayProperties(BYTE type, long length, void* poResult); }; class BinaryCommentReader : public Binary_CommonReader { @@ -363,6 +396,9 @@ namespace BinXlsxRW int ReadUserProtectedRanges(BYTE type, long length, void* poResult); int ReadUserProtectedRange(BYTE type, long length, void* poResult); int ReadUserProtectedRangeDesc(BYTE type, long length, void* poResult); + int ReadTimelinesList(BYTE type, long length, void* poResult); + int ReadTimelines(BYTE type, long length, void* poResult); + int ReadTimeline(BYTE type, long length, void* poResult); void WriteComments(); void AddLineBreak(OOX::Spreadsheet::CSi& oSi); @@ -412,7 +448,7 @@ namespace BinXlsxRW { public: BinaryFileReader(); - int ReadFile(const std::wstring& sSrcFileName, std::wstring sDstPath, NSBinPptxRW::CDrawingConverter* pOfficeDrawingConverter, const std::wstring& sXMLOptions, bool bMacro = false); + int ReadFile(const std::wstring& sSrcFileName, std::wstring sDstPath, NSBinPptxRW::CDrawingConverter* pOfficeDrawingConverter, const std::wstring& sXMLOptions, bool &bMacro); int ReadMainTable(OOX::Spreadsheet::CXlsx& oXlsx, NSBinPptxRW::CBinaryFileReader& oBufferedStream, const std::wstring& sFileInDir, const std::wstring& sOutDir, SaveParams& oSaveParams, NSBinPptxRW::CDrawingConverter* pOfficeDrawingConverter); void initWorkbook(OOX::Spreadsheet::CWorkbook* pWorkbook); diff --git a/OOXML/Binary/Sheets/Writer/CSVWriter.cpp b/OOXML/Binary/Sheets/Writer/CSVWriter.cpp index 923e11874c1..1d16861eefe 100644 --- a/OOXML/Binary/Sheets/Writer/CSVWriter.cpp +++ b/OOXML/Binary/Sheets/Writer/CSVWriter.cpp @@ -30,6 +30,7 @@ * */ #include "CSVWriter.h" +#include "../Reader/CellFormatController/LocalInfo.h" #include "../../../../UnicodeConverter/UnicodeConverter.h" #include "../../../../UnicodeConverter/UnicodeConverter_Encodings.h" #include "../../../../DesktopEditor/common/StringBuilder.h" @@ -57,7 +58,7 @@ class CSVWriter::Impl { public: - Impl(OOX::Spreadsheet::CXlsx &oXlsx, unsigned int m_nCodePage, const std::wstring& sDelimiter, bool m_bJSON); + Impl(OOX::Spreadsheet::CXlsx &oXlsx, unsigned int m_nCodePage, const std::wstring& sDelimiter, int Lcid, bool m_bJSON); ~Impl(); bool Start(const std::wstring &sFileDst); @@ -73,8 +74,10 @@ class CSVWriter::Impl NSFile::CFileBinary m_oFile; OOX::Spreadsheet::CXlsx& m_oXlsx; unsigned int m_nCodePage; + int m_nLcid; const std::wstring& m_sDelimiter; - bool m_bJSON; + bool m_bJSON = false; + bool m_bShowFormulas = false; MS_LCID_converter m_lcidConverter; @@ -120,13 +123,13 @@ CSVWriter::CSVWriter() CSVWriter::~CSVWriter() { } -void CSVWriter::Init(OOX::Spreadsheet::CXlsx &oXlsx, unsigned int nCodePage, const std::wstring& sDelimiter, bool bJSON) +void CSVWriter::Init(OOX::Spreadsheet::CXlsx &oXlsx, unsigned int nCodePage, const std::wstring& sDelimiter, int Lcid, bool bJSON) { - impl_ = boost::shared_ptr(new CSVWriter::Impl(oXlsx, nCodePage, sDelimiter, bJSON)); + impl_ = boost::shared_ptr(new CSVWriter::Impl(oXlsx, nCodePage, sDelimiter, Lcid, bJSON)); } -void CSVWriter::Xlsx2Csv(const std::wstring &sFileDst, OOX::Spreadsheet::CXlsx &oXlsx, unsigned int nCodePage, const std::wstring& sDelimiter, bool bJSON) +void CSVWriter::Xlsx2Csv(const std::wstring &sFileDst, OOX::Spreadsheet::CXlsx &oXlsx, unsigned int nCodePage, const std::wstring& sDelimiter, int Lcid, bool bJSON) { - Init(oXlsx, nCodePage, sDelimiter, bJSON); + Init(oXlsx, nCodePage, sDelimiter, Lcid, bJSON); impl_->Start(sFileDst); @@ -332,21 +335,77 @@ std::wstring CSVWriter::Impl::convert_date_time(const std::wstring & sValue, std if (bDate) { - std::wstringstream wss; - wss.imbue(loc_); - + //std::wstringstream wss; + //wss.imbue(loc_); std::time_t now = std::time(nullptr); std::tm* currentTime = std::localtime(&now); - - currentTime->tm_year = date_.year() - 1900; // Устанавливаем год - currentTime->tm_mon = date_.month() - 1; // Устанавливаем месяц (от 0 до 11) - currentTime->tm_mday = date_.day(); // Устанавливаем день - - - wss << std::put_time(currentTime, L"%x"); // Формат "%x" - формат даты для текущей локали - - date_str = wss.str(); + currentTime->tm_year = date_.year(); + currentTime->tm_mon = date_.month(); + currentTime->tm_mday = date_.day(); + + auto locInf = lcInfo::getLocalInfo(m_nLcid); + for(auto part: locInf.ShortDatePattern) + { + switch(part) + { + case L'0': + { + date_str += std::to_wstring(currentTime->tm_mday); + break; + } + case L'1': + { + if(currentTime->tm_mday < 10) + date_str+= L'0'; + date_str += std::to_wstring(currentTime->tm_mday); + break; + } + case L'2': + { + date_str += std::to_wstring(currentTime->tm_mon); + break; + } + case L'3': + { + if(currentTime->tm_mon < 10) + date_str+= L'0'; + date_str += std::to_wstring(currentTime->tm_mon); + break; + } + case L'4': + { + if (currentTime->tm_year >= 1000) + { + auto sringYear = std::to_wstring(currentTime->tm_year); + auto lastTwoChars = sringYear.substr(sringYear.length() - 2); + date_str += sringYear; + } + else + date_str += std::to_wstring(currentTime->tm_year); + break; + } + case L'5': + { + date_str += std::to_wstring(currentTime->tm_year); + break; + } + default: + break; + } + if(part != locInf.ShortDatePattern.back()) + date_str += locInf.DateSeparator; + + } + + //currentTime->tm_year = date_.year() - 1900; // Устанавливаем год + //currentTime->tm_mon = date_.month() - 1; // Устанавливаем месяц (от 0 до 11) + //currentTime->tm_mday = date_.day(); // Устанавливаем день + + + //wss << std::put_time(currentTime, L"%x"); // Формат "%x" - формат даты для текущей локали + + //date_str = wss.str(); } if (bTime) @@ -411,8 +470,8 @@ std::wstring CSVWriter::Impl::convert_date_time(const std::wstring & sValue, std switch (format_code[i]) { - case L'\\': continue; - case L'/': output += L"."; break; + case L'\\': continue;// + //case L'/': output += L"."; break; case L'a': output += sAferTime; break; case L'd': case L'D': @@ -454,6 +513,20 @@ std::wstring CSVWriter::Impl::convert_date_time(const std::wstring & sValue, std { output += std::to_wstring(month); } + else if(m_nLcid > 0) + { + + auto locInf = lcInfo::getLocalInfo(m_nLcid); + if(symbol_size == 3) + { + output+= locInf.GetLocMonthName(month-1, true); + + } + else + { + output+= locInf.GetLocMonthName(month-1); + } + } else { std::shared_ptr df; @@ -616,7 +689,7 @@ void WriteFile(NSFile::CFileBinary *pFile, wchar_t **pWriteBuffer, int &nCurrent nCurrentIndex += (int)nCountChars; } } -CSVWriter::Impl::Impl(OOX::Spreadsheet::CXlsx &m_oXlsx, unsigned int m_nCodePage, const std::wstring& m_sDelimiter, bool m_bJSON) : m_oXlsx(m_oXlsx), m_nCodePage(m_nCodePage), m_sDelimiter(m_sDelimiter), m_bJSON(m_bJSON), loc_("") +CSVWriter::Impl::Impl(OOX::Spreadsheet::CXlsx &m_oXlsx, unsigned int m_nCodePage, const std::wstring& m_sDelimiter, int Lcid, bool m_bJSON) : m_oXlsx(m_oXlsx), m_nCodePage(m_nCodePage), m_sDelimiter(m_sDelimiter), m_bJSON(m_bJSON), loc_(""), m_nLcid(Lcid) { m_pWriteBuffer = NULL; m_nCurrentIndex = 0; @@ -628,6 +701,8 @@ CSVWriter::Impl::Impl(OOX::Spreadsheet::CXlsx &m_oXlsx, unsigned int m_nCodePage m_bStartRow = true; m_bStartCell = true; + m_bShowFormulas = false; + m_nColDimension = 1; } CSVWriter::Impl::~Impl() @@ -665,6 +740,15 @@ void CSVWriter::Impl::WriteSheetStart(OOX::Spreadsheet::CWorksheet* pWorksheet) { WriteFile(&m_oFile, &m_pWriteBuffer, m_nCurrentIndex, g_sBkt, m_nCodePage); } + + if (pWorksheet && pWorksheet->m_oSheetViews.IsInit() && false == pWorksheet->m_oSheetViews->m_arrItems.empty()) + { + if (pWorksheet->m_oSheetViews->m_arrItems[0]->m_oShowFormulas.IsInit() && + pWorksheet->m_oSheetViews->m_arrItems[0]->m_oShowFormulas->ToBool()) + { + m_bShowFormulas = true; + } + } } void CSVWriter::Impl::WriteRowStart(OOX::Spreadsheet::CRow *pRow) { @@ -731,7 +815,12 @@ void CSVWriter::Impl::WriteCell(OOX::Spreadsheet::CCell *pCell) //} //else bool bString = false; - if (pCell->m_oValue.IsInit()) + + if (m_bShowFormulas && pCell->m_oFormula.IsInit()) + { + sCellValue = L"=" + pCell->m_oFormula->m_sText; + } + else if (pCell->m_oValue.IsInit()) { sCellValue = pCell->m_oValue->ToString(); @@ -793,9 +882,12 @@ void CSVWriter::Impl::WriteCell(OOX::Spreadsheet::CCell *pCell) } } sCellValue = ConvertValueCellToString(sCellValue, format_type, format_code); - } } + if (pCell->m_oFormula.IsInit() && sCellValue.empty()) + { + sCellValue = L"=" + pCell->m_oFormula->m_sText; + } // Escape cell value if (m_bJSON) @@ -870,16 +962,63 @@ void CSVWriter::Impl::GetDefaultFormatCode(int numFmt, std::wstring & format_cod case 12: format_code = L"# ?/?"; format_type = SimpleTypes::Spreadsheet::celltypeFraction; break; case 13: format_code = L"# ??/??"; format_type = SimpleTypes::Spreadsheet::celltypeFraction; break; - case 14: format_code = L"mm-dd-yy"; format_type = SimpleTypes::Spreadsheet::celltypeDate; break; - case 15: format_code = L"d-mmm-yy"; format_type = SimpleTypes::Spreadsheet::celltypeDate; break; - case 16: format_code = L"d-mmm"; format_type = SimpleTypes::Spreadsheet::celltypeDate; break; - case 17: format_code = L"mmm-yy"; format_type = SimpleTypes::Spreadsheet::celltypeDate; break; + case 14: + if(m_nLcid <= 0) + format_code = L"mm-dd-yy"; + else + { + auto locInf = lcInfo::getLocalInfo(m_nLcid); + format_code = locInf.GetShortDateFormat(); + } + format_type = SimpleTypes::Spreadsheet::celltypeDate; break; + + case 15: + if(m_nLcid <= 0) + format_code = L"d-mmm-yy"; + else + { + auto locInf = lcInfo::getLocalInfo(m_nLcid); + format_code = L"d"; + if(locInf.ShortDatePattern.find(L"1") != std::wstring::npos) + format_code += L"d"; + format_code += locInf.DateSeparator + L"mmm" + locInf.DateSeparator + L"yy"; + } + format_type = SimpleTypes::Spreadsheet::celltypeDate; break; + case 16: + if(m_nLcid <= 0) + format_code = L"d-mmm"; + else + { + auto locInf = lcInfo::getLocalInfo(m_nLcid); + format_code = L"d"; + if(locInf.ShortDatePattern.find(L"1") != std::wstring::npos) + format_code += L"d"; + format_code += locInf.DateSeparator + L"mmm"; + } + format_type = SimpleTypes::Spreadsheet::celltypeDate; break; + case 17: + if(m_nLcid <= 0) + format_code = L"mmm-yy"; + else + { + auto locInf = lcInfo::getLocalInfo(m_nLcid); + format_code = L"mmm" + locInf.DateSeparator + L"yy"; + } + format_type = SimpleTypes::Spreadsheet::celltypeDate; break; case 18: format_code = L"h:mm AM/PM"; format_type = SimpleTypes::Spreadsheet::celltypeTime; break; case 19: format_code = L"h:mm:ss AM/PM"; format_type = SimpleTypes::Spreadsheet::celltypeTime; break; case 20: format_code = L"h:mm"; format_type = SimpleTypes::Spreadsheet::celltypeTime; break; case 21: format_code = L"h:mm:ss"; format_type = SimpleTypes::Spreadsheet::celltypeTime; break; - case 22: format_code = L"m/d/yy h:mm"; format_type = SimpleTypes::Spreadsheet::celltypeDateTime; break; + case 22: + if(m_nLcid <= 0) + format_code = L"m/d/yy h:mm"; + else + { + auto locInf = lcInfo::getLocalInfo(m_nLcid); + format_code = locInf.GetShortDateFormat() + L" h:mm"; + } + format_type = SimpleTypes::Spreadsheet::celltypeDateTime; break; case 37: format_code = L"#,##0 ;(#,##0)"; format_type = SimpleTypes::Spreadsheet::celltypeNumber; break; case 38: format_code = L"#,##0 ;[Red](#,##0)"; format_type = SimpleTypes::Spreadsheet::celltypeNumber; break; diff --git a/OOXML/Binary/Sheets/Writer/CSVWriter.h b/OOXML/Binary/Sheets/Writer/CSVWriter.h index 2c1ba37b143..827c424bd33 100644 --- a/OOXML/Binary/Sheets/Writer/CSVWriter.h +++ b/OOXML/Binary/Sheets/Writer/CSVWriter.h @@ -53,9 +53,9 @@ class CSVWriter CSVWriter(); ~CSVWriter(); - void Xlsx2Csv(const std::wstring &sFileDst, OOX::Spreadsheet::CXlsx &oXlsx, unsigned int nCodePage, const std::wstring& wcDelimiter, bool bJSON); + void Xlsx2Csv(const std::wstring &sFileDst, OOX::Spreadsheet::CXlsx &oXlsx, unsigned int nCodePage, const std::wstring& wcDelimiter, int Lcid, bool bJSON); - void Init(OOX::Spreadsheet::CXlsx &oXlsx, unsigned int nCodePage, const std::wstring& wcDelimiter, bool bJSON); + void Init(OOX::Spreadsheet::CXlsx &oXlsx, unsigned int nCodePage, const std::wstring& wcDelimiter, int Lcid, bool bJSON); bool Start(const std::wstring &sFileDst); void WriteSheetStart(OOX::Spreadsheet::CWorksheet* pWorksheet); diff --git a/OOXML/Binary/XlsbFormat/FileTypes_SpreadsheetBin.h b/OOXML/Binary/XlsbFormat/FileTypes_SpreadsheetBin.h index e6e53f35b39..2757d347137 100644 --- a/OOXML/Binary/XlsbFormat/FileTypes_SpreadsheetBin.h +++ b/OOXML/Binary/XlsbFormat/FileTypes_SpreadsheetBin.h @@ -31,7 +31,7 @@ */ #pragma once -#include "../DocxFormat/FileType.h" +#include "../../DocxFormat/FileType.h" namespace OOX @@ -39,10 +39,10 @@ namespace OOX namespace SpreadsheetBin { namespace FileTypes - { + { const FileType WorkbookBin (L"xl", L"workbook.bin", - L"application/vnd.ms-excel.main", + L"application/vnd.ms-excel.sheet.binary.macroEnabled.main", L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument"); const FileType SharedStringsBin (L"", L"sharedStrings.bin", @@ -112,6 +112,10 @@ namespace OOX L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/pivotCacheRecords", L"pivotCache/pivotCacheRecords", true, true); + const FileType MetadataBin (L"", L"metadata.bin", + L"application/vnd.ms-excel.sheetMetadata", + L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/sheetMetadata"); + } // namespace FileTypes } } // namespace OOX diff --git a/OOXML/Common/ComplexTypes.cpp b/OOXML/Common/ComplexTypes.cpp index 6fd06ffebe8..e31d7ad1b15 100644 --- a/OOXML/Common/ComplexTypes.cpp +++ b/OOXML/Common/ComplexTypes.cpp @@ -2366,6 +2366,15 @@ namespace Word WritingElement_ReadAttributes_Read_else_if(oReader, L"w:xAlign", m_oXAlign) WritingElement_ReadAttributes_Read_else_if(oReader, L"w:y", m_oY) WritingElement_ReadAttributes_Read_else_if(oReader, L"w:yAlign", m_oYAlign) +//2003 + WritingElement_ReadAttributes_Read_else_if(oReader, L"w:x-align", m_oXAlign) + WritingElement_ReadAttributes_Read_else_if(oReader, L"w:y-align", m_oYAlign) + WritingElement_ReadAttributes_Read_else_if(oReader, L"w:hanchor", m_oHAnchor) + WritingElement_ReadAttributes_Read_else_if(oReader, L"w:vanchor", m_oVAnchor) + WritingElement_ReadAttributes_Read_else_if(oReader, L"w:hspace", m_oHSpace) + WritingElement_ReadAttributes_Read_else_if(oReader, L"w:vspace", m_oVSpace) + WritingElement_ReadAttributes_Read_else_if(oReader, L"w:hrule", m_oHRule) + WritingElement_ReadAttributes_End(oReader) } diff --git a/OOXML/Common/ComplexTypes.h b/OOXML/Common/ComplexTypes.h index 885118e0015..b8e3b5dd2f2 100644 --- a/OOXML/Common/ComplexTypes.h +++ b/OOXML/Common/ComplexTypes.h @@ -1073,21 +1073,21 @@ namespace ComplexTypes void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); public: - nullable m_oAnchorLock; - nullable m_oDropCap; - nullable m_oH; - nullable m_oHAnchor; - nullable m_oHRule; - nullable m_oHSpace; - nullable m_oLines; - nullable m_oVAnchor; - nullable m_oVSpace; - nullable m_oW; - nullable m_oWrap; - nullable m_oX; - nullable m_oXAlign; - nullable m_oY; - nullable m_oYAlign; + nullable m_oAnchorLock; + nullable m_oDropCap; + nullable m_oH; + nullable m_oHAnchor; + nullable m_oHRule; + nullable m_oHSpace; + nullable m_oLines; + nullable m_oVAnchor; + nullable m_oVSpace; + nullable m_oW; + nullable m_oWrap; + nullable m_oX; + nullable m_oXAlign; + nullable m_oY; + nullable m_oYAlign; }; //-------------------------------------------------------------------------------- diff --git a/OOXML/Common/SimpleTypes_Drawing.cpp b/OOXML/Common/SimpleTypes_Drawing.cpp index e237d1fc05c..d7e04c99aac 100644 --- a/OOXML/Common/SimpleTypes_Drawing.cpp +++ b/OOXML/Common/SimpleTypes_Drawing.cpp @@ -5025,6 +5025,7 @@ namespace SimpleTypes else if (L"w" == sValue) this->m_eValue = constraintType_w; else if (L"wArH" == sValue) this->m_eValue = constraintType_wArH; else if (L"wOff" == sValue) this->m_eValue = constraintType_wOff; + else if (L"hOff" == sValue) this->m_eValue = constraintType_hOff; else this->m_eValue = constraintType_none; return this->m_eValue; @@ -5097,6 +5098,7 @@ namespace SimpleTypes case constraintType_w: return L"w"; case constraintType_wArH: return L"wArH"; case constraintType_wOff: return L"wOff"; + case constraintType_hOff: return L"hOff"; default: return L"none"; } } @@ -5324,13 +5326,13 @@ namespace SimpleTypes EHierBranch CHierBranch::FromString(const std::wstring &sValue) { - if (L"none" == sValue) this->m_eValue = hierBranch_hang; + if (L"hang" == sValue) this->m_eValue = hierBranch_hang; else if (L"init" == sValue) this->m_eValue = hierBranch_init; else if (L"l" == sValue) this->m_eValue = hierBranch_l; else if (L"r" == sValue) this->m_eValue = hierBranch_r; else if (L"l" == sValue) this->m_eValue = hierBranch_l; else if (L"std" == sValue) this->m_eValue = hierBranch_std; - else this->m_eValue = hierBranch_hang; + else this->m_eValue = hierBranch_std; return this->m_eValue; } diff --git a/OOXML/Common/SimpleTypes_Drawing.h b/OOXML/Common/SimpleTypes_Drawing.h index ac3002d996f..c86195de3d5 100644 --- a/OOXML/Common/SimpleTypes_Drawing.h +++ b/OOXML/Common/SimpleTypes_Drawing.h @@ -2111,7 +2111,8 @@ namespace SimpleTypes constraintType_userZ = 59, constraintType_w = 60, constraintType_wArH = 61, - constraintType_wOff = 62 + constraintType_wOff = 62, + constraintType_hOff = 63 }; DEFINE_SIMPLE_TYPE(CConstraintType, EConstraintType, constraintType_none) @@ -2255,7 +2256,7 @@ namespace SimpleTypes hierBranch_std = 4 }; - DEFINE_SIMPLE_TYPE(CHierBranch, EHierBranch, hierBranch_hang) + DEFINE_SIMPLE_TYPE(CHierBranch, EHierBranch, hierBranch_std) //-------------------------------------------------------------------------------- // ResizeHandles diff --git a/OOXML/Common/SimpleTypes_Shared.cpp b/OOXML/Common/SimpleTypes_Shared.cpp index ba172acf451..8b13bbfbadb 100644 --- a/OOXML/Common/SimpleTypes_Shared.cpp +++ b/OOXML/Common/SimpleTypes_Shared.cpp @@ -722,7 +722,7 @@ namespace SimpleTypes { try { - this->m_eValue = XmlUtils::GetInteger(sValue); + this->m_eValue = XmlUtils::GetUInteger(sValue); return this->m_eValue; } catch(...) diff --git a/OOXML/Common/SimpleTypes_Shared.h b/OOXML/Common/SimpleTypes_Shared.h index d8b2f24c2a4..58141167a12 100644 --- a/OOXML/Common/SimpleTypes_Shared.h +++ b/OOXML/Common/SimpleTypes_Shared.h @@ -259,7 +259,7 @@ namespace SimpleTypes CPanose(); std::wstring GetValue() const; - void SetValue(std::wstring &sValue); + void SetValue(std::wstring &sValue); std::wstring FromString(const std::wstring &sValue); std::wstring ToString () const; @@ -398,7 +398,6 @@ namespace SimpleTypes void SetRGB(); void ByColorName(const std::wstring& sValue); - private: std::wstring m_sValue; unsigned char m_unR; diff --git a/OOXML/Common/SimpleTypes_Spreadsheet.cpp b/OOXML/Common/SimpleTypes_Spreadsheet.cpp index 26bea1c9913..24d91f3e28f 100644 --- a/OOXML/Common/SimpleTypes_Spreadsheet.cpp +++ b/OOXML/Common/SimpleTypes_Spreadsheet.cpp @@ -2172,6 +2172,45 @@ namespace SimpleTypes } } + ETimelineStyle CTimelineStyle::FromString(const std::wstring& sValue) + { + if (L"TimelineStyleLight1" == sValue) this->m_eValue = TimelineStyleLight1; + else if (L"TimelineStyleLight2" == sValue) this->m_eValue = TimelineStyleLight2; + else if (L"TimelineStyleLight3" == sValue) this->m_eValue = TimelineStyleLight3; + else if (L"TimelineStyleLight4" == sValue) this->m_eValue = TimelineStyleLight4; + else if (L"TimelineStyleLight5" == sValue) this->m_eValue = TimelineStyleLight5; + else if (L"TimelineStyleLight6" == sValue) this->m_eValue = TimelineStyleLight6; + else if (L"TimelineStyleDark1" == sValue) this->m_eValue = TimelineStyleDark1; + else if (L"TimelineStyleDark2" == sValue) this->m_eValue = TimelineStyleDark2; + else if (L"TimelineStyleDark3" == sValue) this->m_eValue = TimelineStyleDark3; + else if (L"TimelineStyleDark4" == sValue) this->m_eValue = TimelineStyleDark4; + else if (L"TimelineStyleDark5" == sValue) this->m_eValue = TimelineStyleDark5; + else if (L"TimelineStyleDark6" == sValue) this->m_eValue = TimelineStyleDark6; + else this->m_eValue = TimelineStyleLight1; + + return this->m_eValue; + } + + std::wstring CTimelineStyle::ToString() const + { + switch (this->m_eValue) + { + case TimelineStyleLight1: return L"TimelineStyleLight1"; break; + case TimelineStyleLight2: return L"TimelineStyleLight2"; break; + case TimelineStyleLight3: return L"TimelineStyleLight3"; break; + case TimelineStyleLight4: return L"TimelineStyleLight4"; break; + case TimelineStyleLight5: return L"TimelineStyleLight5"; break; + case TimelineStyleLight6: return L"TimelineStyleLight6"; break; + case TimelineStyleDark1: return L"TimelineStyleDark1"; break; + case TimelineStyleDark2: return L"TimelineStyleDark2"; break; + case TimelineStyleDark3: return L"TimelineStyleDark3"; break; + case TimelineStyleDark4: return L"TimelineStyleDark4"; break; + case TimelineStyleDark5: return L"TimelineStyleDark5"; break; + case TimelineStyleDark6: return L"TimelineStyleDark6"; break; + default: return L"A1"; + + } + } template<> CDoubleOrAutomatic::CDoubleOrAutomatic() : m_dValue(0){} @@ -3195,6 +3234,186 @@ namespace SimpleTypes } return L"unselectedItemWithData"; } + + ETimelineStyleType CTimelineStyleType::FromString(const std::wstring& sValue) + { + if (L"selectionLabel" == sValue) + this->m_eValue = timelineStyle_selectionLabel; + else if (L"timeLevel" == sValue) + this->m_eValue = timelineStyle_timeLevel; + else if (L"periodLabel1" == sValue) + this->m_eValue = timelineStyle_periodLabel1; + else if (L"periodLabel2" == sValue) + this->m_eValue = timelineStyle_periodLabel2; + else if (L"selectedTimeBlock" == sValue) + this->m_eValue = timelineStyle_selectedTimeBlock; + else if (L"unselectedTimeBlock" == sValue) + this->m_eValue = timelineStyle_unselectedTimeBlock; + else if (L"selectedTimeBlockSpace" == sValue) + this->m_eValue = timelineStyle_selectedTimeBlockSpace; + else + this->m_eValue = timelineStyle_selectionLabel; + return this->m_eValue; + } + + ETimelineStyleType CTimelineStyleType::FromStringA(const char* sValue) + { + if (strcmp("selectionLabel", sValue) == 0) + this->m_eValue = timelineStyle_selectionLabel; + else if (strcmp("timeLevel", sValue) == 0) + this->m_eValue = timelineStyle_timeLevel; + else if (strcmp("periodLabel1", sValue) == 0) + this->m_eValue = timelineStyle_periodLabel1; + else if (strcmp("periodLabel2", sValue) == 0) + this->m_eValue = timelineStyle_periodLabel2; + else if (strcmp("selectedTimeBlock", sValue) == 0) + this->m_eValue = timelineStyle_selectedTimeBlock; + else if (strcmp("unselectedTimeBlock", sValue) == 0) + this->m_eValue = timelineStyle_unselectedTimeBlock; + else if (strcmp("selectedTimeBlockSpace", sValue) == 0) + this->m_eValue = timelineStyle_selectedTimeBlockSpace; + else + this->m_eValue = timelineStyle_selectionLabel; + return this->m_eValue; + } + + std::wstring CTimelineStyleType::ToString() const + { + switch (this->m_eValue) + { + case timelineStyle_selectionLabel: return L"selectionLabel"; break; + case timelineStyle_timeLevel: return L"timeLevel"; break; + case timelineStyle_periodLabel1: return L"periodLabel1"; break; + case timelineStyle_periodLabel2: return L"periodLabel2"; break; + case timelineStyle_selectedTimeBlock: return L"selectedTimeBlock"; break; + case timelineStyle_unselectedTimeBlock: return L"unselectedTimeBlock"; break; + case timelineStyle_selectedTimeBlockSpace: return L"selectedTimeBlockSpace"; break; + } + return L"unselectedItemWithData"; + } + EMdxKPIProperty CMdxKPIProperty::FromString(const std::wstring& sValue) + { + if (L"v" == sValue) + this->m_eValue = mdxKPIProperty_v; + else if (L"g" == sValue) + this->m_eValue = mdxKPIProperty_g; + else if (L"s" == sValue) + this->m_eValue = mdxKPIProperty_s; + else if (L"t" == sValue) + this->m_eValue = mdxKPIProperty_t; + else if (L"w" == sValue) + this->m_eValue = mdxKPIProperty_w; + else if (L"m" == sValue) + this->m_eValue = mdxKPIProperty_m; + else + this->m_eValue = mdxKPIProperty_v; + return this->m_eValue; + } + std::wstring CMdxKPIProperty::ToString() const + { + switch (this->m_eValue) + { + case mdxKPIProperty_v: return L"v"; break; + case mdxKPIProperty_g: return L"g"; break; + case mdxKPIProperty_s: return L"s"; break; + case mdxKPIProperty_t: return L"t"; break; + case mdxKPIProperty_w: return L"w"; break; + case mdxKPIProperty_m: return L"m"; break; + } + return L"v"; + } + + EMdxSetOrder CMdxSetOrder::FromString(const std::wstring& sValue) + { + if (L"u" == sValue) + this->m_eValue = mdxSetOrder_u; + else if (L"a" == sValue) + this->m_eValue = mdxSetOrder_a; + else if (L"d" == sValue) + this->m_eValue = mdxSetOrder_d; + else if (L"aa" == sValue) + this->m_eValue = mdxSetOrder_aa; + else if (L"ad" == sValue) + this->m_eValue = mdxSetOrder_ad; + else if (L"na" == sValue) + this->m_eValue = mdxSetOrder_na; + else if (L"nd" == sValue) + this->m_eValue = mdxSetOrder_nd; + else + this->m_eValue = mdxSetOrder_u; + return this->m_eValue; + } + std::wstring CMdxSetOrder::ToString() const + { + switch (this->m_eValue) + { + case mdxSetOrder_u: return L"u"; break; + case mdxSetOrder_a: return L"a"; break; + case mdxSetOrder_d: return L"d"; break; + case mdxSetOrder_aa: return L"aa"; break; + case mdxSetOrder_ad: return L"ad"; break; + case mdxSetOrder_na: return L"na"; break; + case mdxSetOrder_nd: return L"nd"; break; + } + return L"v"; + } + + EMdxFunctionType CMdxFunctionType::FromString(const std::wstring& sValue) + { + if (L"m" == sValue) + this->m_eValue = mdxFunctionType_m; + else if (L"v" == sValue) + this->m_eValue = mdxFunctionType_v; + else if (L"s" == sValue) + this->m_eValue = mdxFunctionType_s; + else if (L"c" == sValue) + this->m_eValue = mdxFunctionType_c; + else if (L"r" == sValue) + this->m_eValue = mdxFunctionType_r; + else if (L"p" == sValue) + this->m_eValue = mdxFunctionType_p; + else if (L"k" == sValue) + this->m_eValue = mdxFunctionType_k; + else + this->m_eValue = mdxFunctionType_m; + return this->m_eValue; + } + std::wstring CMdxFunctionType::ToString() const + { + switch (this->m_eValue) + { + case mdxFunctionType_m: return L"m"; break; + case mdxFunctionType_v: return L"v"; break; + case mdxFunctionType_s: return L"s"; break; + case mdxFunctionType_c: return L"c"; break; + case mdxFunctionType_r: return L"r"; break; + case mdxFunctionType_p: return L"p"; break; + case mdxFunctionType_k: return L"k"; break; + } + return L"v"; + } + EUserProtectedRangeType CUserProtectedRangeType::FromString(const std::wstring& sValue) + { + if (L"notView" == sValue) + this->m_eValue = typeNotView; + else if (L"view" == sValue) + this->m_eValue = typeView; + else if (L"edit" == sValue) + this->m_eValue = typeEdit; + else + this->m_eValue = typeEdit; + return this->m_eValue; + } + std::wstring CUserProtectedRangeType::ToString() const + { + switch (this->m_eValue) + { + case typeNotView: return L"notView"; break; + case typeView: return L"view"; break; + case typeEdit: return L"edit"; break; + } + return L"edit"; + } }// Spreadsheet } // SimpleTypes diff --git a/OOXML/Common/SimpleTypes_Spreadsheet.h b/OOXML/Common/SimpleTypes_Spreadsheet.h index 9153e9add3c..70de28e5933 100644 --- a/OOXML/Common/SimpleTypes_Spreadsheet.h +++ b/OOXML/Common/SimpleTypes_Spreadsheet.h @@ -808,18 +808,18 @@ namespace SimpleTypes //---------------------------------------------------- // 18.18.82 ST_TimePeriod (Conditional Format Value Object Type) //---------------------------------------------------- - enum ETimePeriod + enum ETimePeriod { - last7Days = 0, - lastMonth = 1, - lastWeek = 2, - nextMonth = 3, - nextWeek = 4, - thisMonth = 5, - thisWeek = 6, - today = 7, - tomorrow = 8, - yesterday = 9 + last7Days = 0, + lastMonth = 1, + lastWeek = 2, + nextMonth = 3, + nextWeek = 4, + thisMonth = 5, + thisWeek = 6, + today = 7, + tomorrow = 8, + yesterday = 9 }; DEFINE_SIMPLE_TYPE(ST_TimePeriod, ETimePeriod, last7Days) @@ -955,6 +955,23 @@ namespace SimpleTypes typeDouble = 1 }; + enum ETimelineStyle + { + TimelineStyleLight1 = 0, + TimelineStyleLight2 = 1, + TimelineStyleLight3 = 2, + TimelineStyleLight4 = 3, + TimelineStyleLight5 = 4, + TimelineStyleLight6 = 5, + TimelineStyleDark1 = 6, + TimelineStyleDark2 = 7, + TimelineStyleDark3 = 8, + TimelineStyleDark4 = 9, + TimelineStyleDark5 = 10, + TimelineStyleDark6 = 11 + }; + DEFINE_SIMPLE_TYPE(CTimelineStyle, ETimelineStyle, TimelineStyleLight1) + template class CDoubleOrAutomatic : public CSimpleType { @@ -1375,6 +1392,62 @@ namespace SimpleTypes }; DEFINE_SIMPLE_TYPE(CSlicerStyleType, ESlicerStyleType, cslicerstyletypeUnselectedItemWithData) + + enum ETimelineStyleType + { + timelineStyle_selectionLabel = 0, + timelineStyle_timeLevel = 1, + timelineStyle_periodLabel1 = 2, + timelineStyle_periodLabel2 = 3, + timelineStyle_selectedTimeBlock = 4, + timelineStyle_unselectedTimeBlock = 5, + timelineStyle_selectedTimeBlockSpace = 6 + }; + + DEFINE_SIMPLE_TYPE(CTimelineStyleType, ETimelineStyleType, timelineStyle_selectionLabel) + + enum EMdxKPIProperty + { + mdxKPIProperty_v = 0, + mdxKPIProperty_g = 1, + mdxKPIProperty_s = 2, + mdxKPIProperty_t = 3, + mdxKPIProperty_w = 4, + mdxKPIProperty_m = 5 + }; + DEFINE_SIMPLE_TYPE(CMdxKPIProperty, EMdxKPIProperty, mdxKPIProperty_v) + + enum EMdxSetOrder + { + mdxSetOrder_u = 0, + mdxSetOrder_a = 1, + mdxSetOrder_d = 2, + mdxSetOrder_aa = 3, + mdxSetOrder_ad = 4, + mdxSetOrder_na = 5, + mdxSetOrder_nd = 6 + }; + DEFINE_SIMPLE_TYPE(CMdxSetOrder, EMdxSetOrder, mdxSetOrder_u) + + enum EMdxFunctionType + { + mdxFunctionType_m = 0, + mdxFunctionType_v = 1, + mdxFunctionType_s = 2, + mdxFunctionType_c = 3, + mdxFunctionType_r = 4, + mdxFunctionType_p = 5, + mdxFunctionType_k = 6 + }; + DEFINE_SIMPLE_TYPE(CMdxFunctionType, EMdxFunctionType, mdxFunctionType_m) + + enum EUserProtectedRangeType + { + typeNotView = 0, + typeView = 1, + typeEdit = 2 + }; + DEFINE_SIMPLE_TYPE(CUserProtectedRangeType, EUserProtectedRangeType, typeView) }// Spreadsheet } // SimpleTypes diff --git a/OOXML/Common/SimpleTypes_Vml.cpp b/OOXML/Common/SimpleTypes_Vml.cpp index 7c530164e81..a88d23fd14e 100644 --- a/OOXML/Common/SimpleTypes_Vml.cpp +++ b/OOXML/Common/SimpleTypes_Vml.cpp @@ -1224,9 +1224,9 @@ namespace SimpleTypes { switch (this->m_eValue) { - case oletypeEmbed : return L"embed"; - case oletypeLink : return L"link"; - default : return L"embed"; + case oletypeEmbed : return L"Embed"; + case oletypeLink : return L"Link"; + default : return L"Embed"; } } diff --git a/OOXML/Common/SimpleTypes_Vml.h b/OOXML/Common/SimpleTypes_Vml.h index 1352dcc842a..7f8eaaeea8b 100644 --- a/OOXML/Common/SimpleTypes_Vml.h +++ b/OOXML/Common/SimpleTypes_Vml.h @@ -1503,9 +1503,8 @@ namespace SimpleTypes SimpleTypes_DefaultString(CVml_Vector2D_Units) - private: - - double m_dX; // В пунктах + private: + double m_dX; // В пунктах double m_dY; // В пунктах }; @@ -1529,8 +1528,8 @@ namespace SimpleTypes SimpleTypes_DefaultString(CVml_Vector2D_Percentage) - private: - double m_dX; // + private: + double m_dX; // double m_dY; // }; @@ -1554,8 +1553,8 @@ namespace SimpleTypes SimpleTypes_DefaultString(CVml_Vector2D_1_65536) - private: - double m_dX; // + private: + double m_dX; // double m_dY; // }; @@ -1639,8 +1638,8 @@ namespace SimpleTypes std::wstring m_sIdX; // Значение для типа Formula иди AdjValue std::wstring m_sIdY; // - double m_dX; // Значение для типа Constant - double m_dY; // + double m_dX; // Значение для типа Constant + double m_dY; // }; //-------------------------------------------------------------------------------- @@ -1698,12 +1697,11 @@ namespace SimpleTypes void SetPercentage(double dValue); virtual double FromString(const std::wstring &sValue); - virtual std::wstring ToString () const; + virtual std::wstring ToString() const; SimpleTypes_DefaultD(CVml_1_65536_Or_Percentage) - private: - double m_dValue; + double m_dValue; }; //-------------------------------------------------------------------------------- @@ -1789,8 +1787,8 @@ namespace SimpleTypes SimpleTypes_DefaultString(CVml_TextBoxInset) - private: - double m_dLeft; + private: + double m_dLeft; double m_dTop; double m_dRight; double m_dBottom; diff --git a/OOXML/Common/SimpleTypes_Word.cpp b/OOXML/Common/SimpleTypes_Word.cpp index 6fc785b7f3e..2233a9926f6 100644 --- a/OOXML/Common/SimpleTypes_Word.cpp +++ b/OOXML/Common/SimpleTypes_Word.cpp @@ -1680,10 +1680,11 @@ namespace SimpleTypes EHeightRule CHeightRule::FromString(const std::wstring &sValue) { - if ( (L"atLeast") == sValue ) this->m_eValue = heightruleAtLeast; - else if ( (L"auto") == sValue ) this->m_eValue = heightruleAuto; - else if ( (L"exact") == sValue ) this->m_eValue = heightruleExact; - else this->m_eValue = heightruleAuto; + if (L"atLeast" == sValue) this->m_eValue = heightruleAtLeast; + else if (L"at-least" == sValue) this->m_eValue = heightruleAtLeast; + else if (L"auto" == sValue) this->m_eValue = heightruleAuto; + else if (L"exact" == sValue) this->m_eValue = heightruleExact; + else this->m_eValue = heightruleAuto; return this->m_eValue; } @@ -1820,6 +1821,12 @@ namespace SimpleTypes m_unG = oPresetColorVal.Get_G(); m_unB = oPresetColorVal.Get_B(); } + else if (8 <= sValue.length()) + { + this->m_eValue = hexcolorRGB; + m_sValue = sValue.substr(2, 6); + Parse(); + } else if ( 6 <= sValue.length() ) { this->m_eValue = hexcolorRGB; @@ -3742,9 +3749,9 @@ namespace SimpleTypes ETblLayoutType CTblLayoutType::FromString(const std::wstring &sValue) { - if ( (L"autofit") == sValue ) this->m_eValue = tbllayouttypeAutofit; - else if ( (L"fixed") == sValue ) this->m_eValue = tbllayouttypeFixed; - else this->m_eValue = tbllayouttypeAutofit; + if (L"autofit" == sValue) this->m_eValue = tbllayouttypeAutofit; + else if (L"fixed" == sValue || L"Fixed" == sValue) this->m_eValue = tbllayouttypeFixed; + else this->m_eValue = tbllayouttypeAutofit; return this->m_eValue; } @@ -4327,12 +4334,13 @@ namespace SimpleTypes EWrap CWrap::FromString(const std::wstring &sValue) { - if ( (L"around") == sValue ) this->m_eValue = wrapAround; - else if ( (L"auto") == sValue ) this->m_eValue = wrapAuto; - else if ( (L"none") == sValue ) this->m_eValue = wrapNone; - else if ( (L"notBeside") == sValue ) this->m_eValue = wrapNotBeside; - else if ( (L"through") == sValue ) this->m_eValue = wrapThrough; - else if ( (L"tight") == sValue ) this->m_eValue = wrapTight; + if (L"around" == sValue ) this->m_eValue = wrapAround; + else if (L"auto" == sValue ) this->m_eValue = wrapAuto; + else if (L"none" == sValue ) this->m_eValue = wrapNone; + else if (L"notBeside" == sValue ) this->m_eValue = wrapNotBeside; + else if (L"not-beside" == sValue) this->m_eValue = wrapNotBeside; + else if (L"through" == sValue ) this->m_eValue = wrapThrough; + else if (L"tight" == sValue ) this->m_eValue = wrapTight; else this->m_eValue = wrapAuto; return this->m_eValue; @@ -4681,16 +4689,17 @@ namespace SimpleTypes ECryptAlgoritmName CCryptAlgoritmName::FromString(const std::wstring &sValue) { - if ( L"MD2" == sValue || L"1" == sValue ) this->m_eValue = cryptalgoritmnameMD2; - else if ( L"MD4" == sValue || L"2" == sValue ) this->m_eValue = cryptalgoritmnameMD4; - else if ( L"MD5" == sValue || L"3" == sValue ) this->m_eValue = cryptalgoritmnameMD5; - else if ( L"RIPEMD-128" == sValue || L"6" == sValue ) this->m_eValue = cryptalgoritmnameRIPEMD128; - else if ( L"RIPEMD-160" == sValue || L"7" == sValue ) this->m_eValue = cryptalgoritmnameRIPEMD160; - else if ( L"SHA-1" == sValue || L"4" == sValue ) this->m_eValue = cryptalgoritmnameSHA1; - else if ( L"SHA-256" == sValue || L"12" == sValue ) this->m_eValue = cryptalgoritmnameSHA256; - else if ( L"SHA-384" == sValue || L"13" == sValue ) this->m_eValue = cryptalgoritmnameSHA384; - else if ( L"SHA-512" == sValue || L"14" == sValue ) this->m_eValue = cryptalgoritmnameSHA512; - else if ( L"WHIRLPOOL" == sValue ) this->m_eValue = cryptalgoritmnameWHIRLPOOL; + if (L"MD2" == sValue || L"1" == sValue) this->m_eValue = cryptalgoritmnameMD2; + else if (L"MD4" == sValue || L"2" == sValue) this->m_eValue = cryptalgoritmnameMD4; + else if (L"MD5" == sValue || L"3" == sValue) this->m_eValue = cryptalgoritmnameMD5; + else if (L"RIPEMD-128" == sValue || L"6" == sValue) this->m_eValue = cryptalgoritmnameRIPEMD128; + else if (L"RIPEMD-160" == sValue || L"7" == sValue) this->m_eValue = cryptalgoritmnameRIPEMD160; + else if (L"SHA-1" == sValue || L"4" == sValue) this->m_eValue = cryptalgoritmnameSHA1; + else if (L"SHA-256" == sValue || L"12" == sValue) this->m_eValue = cryptalgoritmnameSHA256; + else if (L"SHA-384" == sValue || L"13" == sValue) this->m_eValue = cryptalgoritmnameSHA384; + else if (L"SHA-512" == sValue || L"14" == sValue) this->m_eValue = cryptalgoritmnameSHA512; + else if (L"WHIRLPOOL" == sValue) this->m_eValue = cryptalgoritmnameWHIRLPOOL; + else if (L"PBKDF2" == sValue) this->m_eValue = cryptalgoritmnamePBKDF2; else this->m_eValue = cryptalgoritmnameUnknown; @@ -4711,6 +4720,7 @@ namespace SimpleTypes case cryptalgoritmnameSHA384 : return (L"SHA-384"); case cryptalgoritmnameSHA512 : return (L"SHA-512"); case cryptalgoritmnameWHIRLPOOL : return (L"WHIRLPOOL"); + case cryptalgoritmnamePBKDF2 : return (L"PBKDF2"); default : return (L""); } } diff --git a/OOXML/Common/SimpleTypes_Word.h b/OOXML/Common/SimpleTypes_Word.h index 46052feff27..e882f736108 100644 --- a/OOXML/Common/SimpleTypes_Word.h +++ b/OOXML/Common/SimpleTypes_Word.h @@ -639,7 +639,7 @@ namespace SimpleTypes CFFName(); std::wstring GetValue() const; - void SetValue(std::wstring &sValue); + void SetValue(std::wstring &sValue); std::wstring FromString(const std::wstring &sValue); std::wstring ToString () const; @@ -894,7 +894,6 @@ namespace SimpleTypes void Parse3(); int HexToInt(int nHex); - private: std::wstring m_sValue; unsigned char m_unR = 0; @@ -2115,6 +2114,7 @@ namespace SimpleTypes cryptalgoritmnameSHA384 = 8, cryptalgoritmnameSHA512 = 9, cryptalgoritmnameWHIRLPOOL = 10, + cryptalgoritmnamePBKDF2 = 11 }; DEFINE_SIMPLE_TYPE(CCryptAlgoritmName, ECryptAlgoritmName, cryptalgoritmnameUnknown) diff --git a/OOXML/DocxFormat/App.cpp b/OOXML/DocxFormat/App.cpp index d2fe46c880a..703e046c8ae 100644 --- a/OOXML/DocxFormat/App.cpp +++ b/OOXML/DocxFormat/App.cpp @@ -32,9 +32,9 @@ #include "App.h" #include "Docx.h" #include "../XlsxFormat/Xlsx.h" -#include "../PPTXFormat/App.h" #include "../Common/SimpleTypes_Word.h" #include "../../DesktopEditor/common/SystemUtils.h" +#include "../../DesktopEditor/xml/include/xmlutils.h" namespace OOX { @@ -57,106 +57,6 @@ namespace OOX CApp::~CApp() { } - PPTX::App* CApp::ToPptxApp() - { - PPTX::App* res = new PPTX::App(NULL); - if(m_sTemplate.IsInit()) - res->Template = m_sTemplate.get(); - if(m_nTotalTime.IsInit()) - res->TotalTime = m_nTotalTime.get(); - if(m_nWords.IsInit()) - res->Words = m_nWords.get(); - if(m_sApplication.IsInit()) - res->Application = m_sApplication.get(); - if(m_sPresentationForm.IsInit()) - res->PresentationFormat = m_sPresentationForm.get(); - if(m_nParagraphs.IsInit()) - res->Paragraphs = m_nParagraphs.get(); - if(m_nSlides.IsInit()) - res->Slides = m_nSlides.get(); - if(m_nNotes.IsInit()) - res->Notes = m_nNotes.get(); - if(m_nHiddenSlides.IsInit()) - res->HiddenSlides = m_nHiddenSlides.get(); - if(m_nMMClips.IsInit()) - res->MMClips = m_nMMClips.get(); - if(m_bScaleCrop.IsInit()) - res->ScaleCrop = m_bScaleCrop.get(); - if(m_sCompany.IsInit()) - res->Company = m_sCompany.get(); - if(m_bLinksUpToDate.IsInit()) - res->LinksUpToDate = m_bLinksUpToDate.get(); - if(m_bSharedDoc.IsInit()) - res->SharedDoc = m_bSharedDoc.get(); - if(m_bHyperlinksChanged.IsInit()) - res->HyperlinksChanged = m_bHyperlinksChanged.get(); - if(m_sAppVersion.IsInit()) - res->AppVersion = m_sAppVersion.get(); - if(m_nCharacters.IsInit()) - res->Characters = m_nCharacters.get(); - if(m_nCharactersWithSpaces.IsInit()) - res->CharactersWithSpaces = m_nCharactersWithSpaces.get(); - if(m_nDocSecurity.IsInit()) - res->DocSecurity = m_nDocSecurity.get(); - if(m_sHyperlinkBase.IsInit()) - res->HyperlinkBase = m_sHyperlinkBase.get(); - if(m_nLines.IsInit()) - res->Lines = m_nLines.get(); - if(m_sManager.IsInit()) - res->Manager = m_sManager.get(); - if(m_nPages.IsInit()) - res->Pages = m_nPages.get(); - return res; - } - void CApp::FromPptxApp(PPTX::App* pApp) - { - if(pApp->Template.IsInit()) - m_sTemplate = pApp->Template.get(); - if(pApp->TotalTime.IsInit()) - m_nTotalTime = pApp->TotalTime.get(); - if(pApp->Words.IsInit()) - m_nWords = pApp->Words.get(); - if(pApp->Application.IsInit()) - m_sApplication = pApp->Application.get(); - if(pApp->PresentationFormat.IsInit()) - m_sPresentationForm = pApp->PresentationFormat.get(); - if(pApp->Paragraphs.IsInit()) - m_nParagraphs = pApp->Paragraphs.get(); - if(pApp->Slides.IsInit()) - m_nSlides = pApp->Slides.get(); - if(pApp->Notes.IsInit()) - m_nNotes = pApp->Notes.get(); - if(pApp->HiddenSlides.IsInit()) - m_nHiddenSlides = pApp->HiddenSlides.get(); - if(pApp->MMClips.IsInit()) - m_nMMClips = pApp->MMClips.get(); - if(pApp->ScaleCrop.IsInit()) - m_bScaleCrop = pApp->ScaleCrop.get(); - if(pApp->Company.IsInit()) - m_sCompany = pApp->Company.get(); - if(pApp->LinksUpToDate.IsInit()) - m_bLinksUpToDate = pApp->LinksUpToDate.get(); - if(pApp->SharedDoc.IsInit()) - m_bSharedDoc = pApp->SharedDoc.get(); - if(pApp->HyperlinksChanged.IsInit()) - m_bHyperlinksChanged = pApp->HyperlinksChanged.get(); - if(pApp->AppVersion.IsInit()) - m_sAppVersion = pApp->AppVersion.get(); - if(pApp->Characters.IsInit()) - m_nCharacters = pApp->Characters.get(); - if(pApp->CharactersWithSpaces.IsInit()) - m_nCharactersWithSpaces = pApp->CharactersWithSpaces.get(); - if(pApp->DocSecurity.IsInit()) - m_nDocSecurity = pApp->DocSecurity.get(); - if(pApp->HyperlinkBase.IsInit()) - m_sHyperlinkBase = pApp->HyperlinkBase.get(); - if(pApp->Lines.IsInit()) - m_nLines = pApp->Lines.get(); - if(pApp->Manager.IsInit()) - m_sManager = pApp->Manager.get(); - if(pApp->Pages.IsInit()) - m_nPages = pApp->Pages.get(); - } void CApp::read(const CPath& oPath) { XmlUtils::CXmlNode oProperties; @@ -231,176 +131,33 @@ namespace OOX if ( oProperties.GetNode( _T("Words"), oItem ) ) m_nWords = oItem.GetText(); + + XmlUtils::CXmlNode oHP = oProperties.ReadNode(_T("HeadingPairs")); + XmlUtils::CXmlNode oNodeVector1; + if (oHP.GetNode(_T("vt:vector"), oNodeVector1)) + { + XmlMacroReadAttributeBase(oNodeVector1, _T("size"), m_Headings); + XmlMacroLoadArray(oNodeVector1, _T("vt:variant"), HeadingPairs, PPTX::Logic::HeadingVariant); + } + + XmlUtils::CXmlNode oTP = oProperties.ReadNode(_T("TitlesOfParts")); + XmlUtils::CXmlNode oNodeVector2; + if (oTP.GetNode(_T("vt:vector"), oNodeVector2)) + { + XmlMacroReadAttributeBase(oNodeVector2, _T("size"), m_VectorSize); + XmlMacroLoadArray(oNodeVector2, _T("vt:variant"), TitlesOfParts, PPTX::Logic::PartTitle); + } } } void CApp::write(const CPath& oPath, const CPath& oDirectory, CContentTypes& oContent) const { std::wstring sXml; - sXml = _T(""); + sXml = _T(""); - if ( m_sApplication.IsInit() ) - { - sXml += _T(""); - sXml += XmlUtils::EncodeXmlString(m_sApplication.get()); - if ( m_sAppVersion.IsInit() ) - { - sXml += L"/"; - sXml += XmlUtils::EncodeXmlString(m_sAppVersion.get()); - } - sXml += _T(""); - } + NSBinPptxRW::CXmlWriter oWriter; + toXmlWriter(&oWriter); - //if ( m_sAppVersion.IsInit() ) - only for ms editors versions - //{ - // sXml += _T(""); - // sXml += m_sAppVersion.get(); // error in ms editors - "2.4.510.0" - // sXml += _T(""); - //} - - if ( m_nCharacters.IsInit() ) - { - sXml += _T(""); - sXml += std::to_wstring(*m_nCharacters); - sXml += _T(""); - } - - if ( m_nCharactersWithSpaces.IsInit() ) - { - sXml += _T(""); - sXml += std::to_wstring(*m_nCharactersWithSpaces); - sXml += _T(""); - } - - if ( m_sCompany.IsInit() ) - { - sXml += _T(""); - sXml += XmlUtils::EncodeXmlString(m_sCompany.get()); - sXml += _T(""); - } - - if ( m_nDocSecurity.IsInit() ) - { - sXml += _T(""); - sXml += std::to_wstring(*m_nDocSecurity); - sXml += _T(""); - } - - if ( m_nHiddenSlides.IsInit() ) - { - sXml += _T(""); - sXml += std::to_wstring(*m_nHiddenSlides); - sXml += _T(""); - } - - if ( m_sHyperlinkBase.IsInit() ) - { - sXml += _T(""); - sXml += XmlUtils::EncodeXmlString(m_sHyperlinkBase.get()); - sXml += _T(""); - } - - if ( m_bHyperlinksChanged.IsInit() ) - { - sXml += _T(""); - sXml += *m_bHyperlinksChanged ? L"true" : L"false"; - sXml += _T(""); - } - - if ( m_nLines.IsInit() ) - { - sXml += _T(""); - sXml += std::to_wstring(*m_nLines); - sXml += _T(""); - } - - if ( m_bLinksUpToDate.IsInit() ) - { - sXml += _T(""); - sXml += *m_bLinksUpToDate ? L"true" : L"false";; - sXml += _T(""); - } - - if ( m_sManager.IsInit() ) - { - sXml += _T(""); - sXml += XmlUtils::EncodeXmlString(m_sManager.get()); - sXml += _T(""); - } - - if ( m_nMMClips.IsInit() ) - { - sXml += _T(""); - sXml += std::to_wstring(*m_nMMClips); - sXml += _T(""); - } - - if ( m_nNotes.IsInit() ) - { - sXml += _T(""); - sXml += std::to_wstring(*m_nNotes); - sXml += _T(""); - } - - if ( m_nPages.IsInit() ) - { - sXml += _T(""); - sXml += std::to_wstring(*m_nPages); - sXml += _T(""); - } - - if ( m_nParagraphs.IsInit() ) - { - sXml += _T(""); - sXml += std::to_wstring(*m_nParagraphs); - sXml += _T(""); - } - - if ( m_bScaleCrop.IsInit() ) - { - sXml += _T(""); - sXml += *m_bScaleCrop ? L"true" : L"false";; - sXml += _T(""); - } - - if ( m_bSharedDoc.IsInit() ) - { - sXml += _T(""); - sXml += *m_bSharedDoc ? L"true" : L"false";; - sXml += _T(""); - } - - if ( m_nSlides.IsInit() ) - { - SimpleTypes::CDecimalNumber oNum; - oNum.SetValue( m_nSlides.get() ); - - sXml += _T(""); - sXml += std::to_wstring(*m_nSlides); - sXml += _T(""); - } - - if ( m_sTemplate.IsInit() ) - { - sXml += _T(""); - } - - if ( m_nTotalTime.IsInit() ) - { - sXml += _T(""); - sXml += std::to_wstring(*m_nTotalTime); - sXml += _T(""); - } - - if ( m_nWords.IsInit() ) - { - sXml += _T(""); - sXml += std::to_wstring(*m_nWords); - sXml += _T(""); - } - - sXml += _T(""); + sXml += oWriter.GetXmlString(); NSFile::CFileBinary::SaveToFile( oPath.GetPath(), sXml ); oContent.Registration( type().OverrideType(), oDirectory, oPath.GetFilename() ); @@ -440,4 +197,191 @@ namespace OOX m_sApplication = sApplication; } + void CApp::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + pWriter->StartRecord(NSBinPptxRW::NSMainTables::App); + + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeStart); + + pWriter->WriteString2(0, m_sTemplate); + pWriter->WriteString2(1, m_sApplication); + pWriter->WriteString2(2, m_sPresentationForm); + pWriter->WriteString2(3, m_sCompany); + pWriter->WriteString2(4, m_sAppVersion); + + pWriter->WriteInt2(5, m_nTotalTime); + pWriter->WriteInt2(6, m_nWords); + pWriter->WriteInt2(7, m_nParagraphs); + pWriter->WriteInt2(8, m_nSlides); + pWriter->WriteInt2(9, m_nNotes); + pWriter->WriteInt2(10, m_nHiddenSlides); + pWriter->WriteInt2(11, m_nMMClips); + + pWriter->WriteBool2(12, m_bScaleCrop); + pWriter->WriteBool2(13, m_bLinksUpToDate); + pWriter->WriteBool2(14, m_bSharedDoc); + pWriter->WriteBool2(15, m_bHyperlinksChanged); + + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd); + + //start new record because new attributes is incompatible with previous versions + pWriter->StartRecord(0); + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeStart); + + pWriter->WriteInt2(16, m_nCharacters); + pWriter->WriteInt2(17, m_nCharactersWithSpaces); + pWriter->WriteInt2(18, m_nDocSecurity); + pWriter->WriteString2(19, m_sHyperlinkBase); + pWriter->WriteInt2(20, m_nLines); + pWriter->WriteString2(21, m_sManager); + pWriter->WriteInt2(22, m_nPages); + + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd); + pWriter->EndRecord(); + + pWriter->EndRecord(); + } + void CApp::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + pReader->Skip(1); // type + LONG _end_rec = pReader->GetPos() + pReader->GetRecordSize() + 4; + + pReader->Skip(1); // start attributes + + while (true) + { + BYTE _at = pReader->GetUChar_TypeNode(); + if (_at == NSBinPptxRW::g_nodeAttributeEnd) + break; + + switch (_at) + { + case 0: m_sTemplate = pReader->GetString2(); break; + case 1: m_sApplication = pReader->GetString2(); break; + case 2: m_sPresentationForm = pReader->GetString2(); break; + case 3: m_sCompany = pReader->GetString2(); break; + case 4: m_sAppVersion = pReader->GetString2(); break; + case 5: m_nTotalTime = pReader->GetULong(); break; + case 6: m_nWords = pReader->GetULong(); break; + case 7: m_nParagraphs = pReader->GetULong(); break; + case 8: m_nSlides = pReader->GetULong(); break; + case 9: m_nNotes = pReader->GetULong(); break; + case 10: m_nHiddenSlides = pReader->GetULong(); break; + case 11: m_nMMClips = pReader->GetULong(); break; + case 12: m_bScaleCrop = pReader->GetBool(); break; + case 13: m_bLinksUpToDate = pReader->GetBool(); break; + case 14: m_bSharedDoc = pReader->GetBool(); break; + case 15: m_bHyperlinksChanged = pReader->GetBool(); break; + default: break; + } + } + while (pReader->GetPos() < _end_rec) + { + BYTE _at = pReader->GetUChar(); + switch (_at) + { + case 0: + { + LONG _end_rec2 = pReader->GetPos() + pReader->GetRecordSize() + 4; + + pReader->Skip(1); // start attributes + + while (true) + { + BYTE _at = pReader->GetUChar_TypeNode(); + if (_at == NSBinPptxRW::g_nodeAttributeEnd) + break; + + switch (_at) + { + case 16: m_nCharacters = pReader->GetULong(); break; + case 17: m_nCharactersWithSpaces = pReader->GetULong(); break; + case 18: m_nDocSecurity = pReader->GetULong(); break; + case 19: m_sHyperlinkBase = pReader->GetString2(); break; + case 20: m_nLines = pReader->GetULong(); break; + case 21: m_sManager = pReader->GetString2(); break; + case 22: m_nPages = pReader->GetULong(); break; + default: break; + } + } + + pReader->Seek(_end_rec2); + } + break; + default: + { + pReader->SkipRecord(); + break; + } + } + } + + pReader->Seek(_end_rec); + } + void CApp::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(_T("Properties")); + + pWriter->StartAttributes(); + + pWriter->WriteAttribute(_T("xmlns"), PPTX::g_Namespaces.xmlns.m_strLink); + pWriter->WriteAttribute(_T("xmlns:vt"), PPTX::g_Namespaces.vt.m_strLink); + + pWriter->EndAttributes(); + + pWriter->WriteNodeValue2(_T("Template"), m_sTemplate); + pWriter->WriteNodeValue(_T("TotalTime"), m_nTotalTime); + pWriter->WriteNodeValue(_T("Pages"), m_nPages); + pWriter->WriteNodeValue(_T("Words"), m_nWords); + pWriter->WriteNodeValue(_T("Characters"), m_nCharacters); + pWriter->WriteNodeValue(_T("CharactersWithSpaces"), m_nCharactersWithSpaces); + pWriter->WriteNodeValue2(_T("Application"), m_sApplication); + pWriter->WriteNodeValue(_T("DocSecurity"), m_nDocSecurity); + pWriter->WriteNodeValue2(_T("PresentationFormat"), m_sPresentationForm); + pWriter->WriteNodeValue(_T("Lines"), m_nLines); + pWriter->WriteNodeValue(_T("Paragraphs"), m_nParagraphs); + pWriter->WriteNodeValue(_T("Slides"), m_nSlides); + pWriter->WriteNodeValue(_T("Notes"), m_nNotes); + pWriter->WriteNodeValue(_T("HiddenSlides"), m_nHiddenSlides); + pWriter->WriteNodeValue(_T("MMClips"), m_nMMClips); + pWriter->WriteNodeValue(_T("ScaleCrop"), m_bScaleCrop); + + pWriter->StartNode(_T("HeadingPairs")); + pWriter->EndAttributes(); + + pWriter->StartNode(_T("vt:vector")); + pWriter->StartAttributes(); + pWriter->WriteAttribute(_T("size"), (int)HeadingPairs.size()); + pWriter->WriteAttribute(_T("baseType"), (std::wstring)_T("variant")); + pWriter->EndAttributes(); + + pWriter->WriteArray2(HeadingPairs); + + pWriter->EndNode(_T("vt:vector")); + pWriter->EndNode(_T("HeadingPairs")); + + pWriter->StartNode(_T("TitlesOfParts")); + pWriter->EndAttributes(); + + pWriter->StartNode(_T("vt:vector")); + pWriter->StartAttributes(); + pWriter->WriteAttribute(_T("size"), (int)TitlesOfParts.size()); + pWriter->WriteAttribute(_T("baseType"), (std::wstring)_T("lpstr")); + pWriter->EndAttributes(); + + pWriter->WriteArray2(TitlesOfParts); + + pWriter->EndNode(_T("vt:vector")); + pWriter->EndNode(_T("TitlesOfParts")); + + pWriter->WriteNodeValue2(_T("Manager"), m_sManager); + pWriter->WriteNodeValue2(_T("Company"), m_sCompany); + pWriter->WriteNodeValue(_T("LinksUpToDate"), m_bLinksUpToDate); + pWriter->WriteNodeValue(_T("SharedDoc"), m_bSharedDoc); + pWriter->WriteNodeValue2(_T("HyperlinkBase"), m_sHyperlinkBase); + pWriter->WriteNodeValue(_T("HyperlinksChanged"), m_bHyperlinksChanged); + pWriter->WriteNodeValue2(_T("AppVersion"), m_sAppVersion); + + pWriter->EndNode(_T("Properties")); + } } // namespace OOX diff --git a/OOXML/DocxFormat/App.h b/OOXML/DocxFormat/App.h index f844045502a..6d368953343 100644 --- a/OOXML/DocxFormat/App.h +++ b/OOXML/DocxFormat/App.h @@ -32,12 +32,12 @@ #pragma once #include "File.h" +#include "WritingElement.h" #include "../Base/Nullable.h" -namespace PPTX -{ - class App; -} +#include "../PPTXFormat/Logic/PartTitle.h" +#include "../PPTXFormat/Logic/HeadingVariant.h" + namespace OOX { class CApp : public OOX::File @@ -58,37 +58,43 @@ namespace OOX void SetDefaults(); void SetRequiredDefaults(); - PPTX::App* ToPptxApp(); - void FromPptxApp(PPTX::App* pApp); + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; // TO DO: DigSig - // HeadingPairs // HLinks - // TitlesOfParts - nullable_string m_sApplication; + nullable_string m_sApplication; nullable_string m_sAppVersion; nullable_int m_nCharacters; nullable_int m_nCharactersWithSpaces; - nullable_string m_sCompany; + nullable_string m_sCompany; nullable_int m_nDocSecurity; nullable_int m_nHiddenSlides; - nullable_string m_sHyperlinkBase; + nullable_string m_sHyperlinkBase; nullable_bool m_bHyperlinksChanged; nullable_int m_nLines; nullable_bool m_bLinksUpToDate; - nullable_string m_sManager; + nullable_string m_sManager; nullable_int m_nMMClips; nullable_int m_nNotes; nullable_int m_nPages; nullable_int m_nParagraphs; - nullable_string m_sPresentationForm; + nullable_string m_sPresentationForm; nullable_bool m_bScaleCrop; nullable_bool m_bSharedDoc; nullable_int m_nSlides; - nullable_string m_sTemplate; + nullable_string m_sTemplate; nullable_int m_nTotalTime; nullable_int m_nWords; + + std::vector HeadingPairs; + std::vector TitlesOfParts; + private: + nullable_int m_VectorSize; + nullable_int m_Headings; }; + } // namespace OOX diff --git a/OOXML/DocxFormat/Comments.cpp b/OOXML/DocxFormat/Comments.cpp index 138c6557988..b929ac77ebd 100644 --- a/OOXML/DocxFormat/Comments.cpp +++ b/OOXML/DocxFormat/Comments.cpp @@ -74,72 +74,72 @@ namespace OOX int nParentDepth = oReader.GetDepth(); while( oReader.ReadNextSiblingNode( nParentDepth ) ) { - std::wstring sName = oReader.GetName(); + std::wstring sName = oReader.GetNameNoNS(); WritingElement *pItem = NULL; - if ( L"w:altChunk" ==sName ) + if ( L"altChunk" ==sName ) AssignPtrXmlContent(pItem, Logic::CAltChunk, oReader) - else if ( L"w:bookmarkEnd" ==sName ) + else if ( L"bookmarkEnd" ==sName ) AssignPtrXmlContent(pItem, Logic::CBookmarkEnd, oReader) - else if ( L"w:bookmarkStart" ==sName ) + else if ( L"bookmarkStart" ==sName ) AssignPtrXmlContent(pItem, Logic::CBookmarkStart, oReader) - else if ( L"w:commentRangeEnd" ==sName ) + else if ( L"commentRangeEnd" ==sName ) AssignPtrXmlContent(pItem, Logic::CCommentRangeEnd, oReader) - else if ( L"w:commentRangeStart" ==sName ) + else if ( L"commentRangeStart" ==sName ) AssignPtrXmlContent(pItem, Logic::CCommentRangeStart, oReader) - //else if ( L"w:customXml" ==sName ) + //else if ( L"customXml" ==sName ) // pItem = new Logic::CCustomXml( oReader ); - else if ( L"w:customXmlDelRangeEnd" ==sName ) + else if ( L"customXmlDelRangeEnd" ==sName ) AssignPtrXmlContent(pItem, Logic::CCustomXmlDelRangeEnd, oReader) - else if ( L"w:customXmlDelRangeStart" ==sName ) + else if ( L"customXmlDelRangeStart" ==sName ) AssignPtrXmlContent(pItem, Logic::CCustomXmlDelRangeStart, oReader) - else if ( L"w:customXmlInsRangeEnd" ==sName ) + else if ( L"customXmlInsRangeEnd" ==sName ) AssignPtrXmlContent(pItem, Logic::CCustomXmlInsRangeEnd, oReader) - else if ( L"w:customXmlInsRangeStart" ==sName ) + else if ( L"customXmlInsRangeStart" ==sName ) AssignPtrXmlContent(pItem, Logic::CCustomXmlInsRangeStart, oReader) - else if ( L"w:customXmlMoveFromRangeEnd" ==sName ) + else if ( L"customXmlMoveFromRangeEnd" ==sName ) AssignPtrXmlContent(pItem, Logic::CCustomXmlMoveFromRangeEnd, oReader) - else if ( L"w:customXmlMoveFromRangeStart" ==sName ) + else if ( L"customXmlMoveFromRangeStart" ==sName ) AssignPtrXmlContent(pItem, Logic::CCustomXmlMoveFromRangeStart, oReader) - else if ( L"w:customXmlMoveToRangeEnd" ==sName ) + else if ( L"customXmlMoveToRangeEnd" ==sName ) AssignPtrXmlContent(pItem, Logic::CCustomXmlMoveToRangeEnd, oReader) - else if ( L"w:customXmlMoveToRangeStart" ==sName ) + else if ( L"customXmlMoveToRangeStart" ==sName ) AssignPtrXmlContent(pItem, Logic::CCustomXmlMoveToRangeStart, oReader) - else if ( L"w:del" ==sName ) + else if ( L"del" ==sName ) AssignPtrXmlContent(pItem, Logic::CDel, oReader) - else if ( L"w:ins" ==sName ) + else if ( L"ins" ==sName ) AssignPtrXmlContent(pItem, Logic::CIns, oReader) - else if ( L"w:moveFrom" ==sName ) + else if ( L"moveFrom" ==sName ) AssignPtrXmlContent(pItem, Logic::CMoveFrom, oReader) - else if ( L"w:moveFromRangeEnd" ==sName ) + else if ( L"moveFromRangeEnd" ==sName ) AssignPtrXmlContent(pItem, Logic::CMoveFromRangeEnd, oReader) - else if ( L"w:moveFromRangeStart" ==sName ) + else if ( L"moveFromRangeStart" ==sName ) AssignPtrXmlContent(pItem, Logic::CMoveFromRangeStart, oReader) - else if ( L"w:moveTo" ==sName ) + else if ( L"moveTo" ==sName ) AssignPtrXmlContent(pItem, Logic::CMoveTo, oReader) - else if ( L"w:moveToRangeEnd" ==sName ) + else if ( L"moveToRangeEnd" ==sName ) AssignPtrXmlContent(pItem, Logic::CMoveToRangeEnd, oReader) - else if ( L"w:moveToRangeStart" ==sName ) + else if ( L"moveToRangeStart" ==sName ) AssignPtrXmlContent(pItem, Logic::CMoveToRangeStart, oReader) - else if ( L"m:oMath" ==sName ) + else if ( L"oMath" ==sName ) AssignPtrXmlContent(pItem, Logic::COMath, oReader) - else if ( L"m:oMathPara" ==sName ) + else if ( L"oMathPara" ==sName ) AssignPtrXmlContent(pItem, Logic::COMathPara, oReader) - else if ( L"w:p" ==sName ) + else if ( L"p" ==sName ) AssignPtrXmlContent(pItem, Logic::CParagraph, oReader) - else if ( L"w:permEnd" ==sName ) + else if ( L"permEnd" ==sName ) AssignPtrXmlContent(pItem, Logic::CPermEnd, oReader) - else if ( L"w:permStart" ==sName ) + else if ( L"permStart" ==sName ) AssignPtrXmlContent(pItem, Logic::CPermStart, oReader) - else if ( L"w:proofErr" ==sName ) + else if ( L"proofErr" ==sName ) AssignPtrXmlContent(pItem, Logic::CProofErr, oReader) - else if ( L"w:sdt" ==sName ) + else if ( L"sdt" ==sName ) AssignPtrXmlContent(pItem, Logic::CSdt, oReader) - else if ( L"w:tbl" ==sName ) + else if ( L"tbl" ==sName ) AssignPtrXmlContent(pItem, Logic::CTbl, oReader) - else if ( L"w:tbl" ==sName ) + else if ( L"tbl" ==sName ) AssignPtrXmlContent(pItem, Logic::CTbl, oReader) - else if ( L"aml:content" ==sName ) + else if ( L"content" ==sName ) { fromXML2(oReader); break; @@ -277,18 +277,13 @@ namespace OOX } void CComment::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) { - WritingElement_ReadAttributes_Start( oReader ) - WritingElement_ReadAttributes_Read_if ( oReader, L"w:author", m_oAuthor ) - WritingElement_ReadAttributes_Read_else_if( oReader, L"w:date", m_oDate ) - WritingElement_ReadAttributes_Read_else_if( oReader, L"oodata", m_oOOData ) - WritingElement_ReadAttributes_Read_else_if( oReader, L"w:id", m_oId ) - WritingElement_ReadAttributes_Read_else_if( oReader, L"w:initials", m_oInitials ) - - WritingElement_ReadAttributes_Read_if ( oReader, L"aml:author", m_oAuthor ) - WritingElement_ReadAttributes_Read_else_if( oReader, L"aml:createdate", m_oDate ) - WritingElement_ReadAttributes_Read_else_if( oReader, L"aml:id", m_oId ) - WritingElement_ReadAttributes_Read_else_if( oReader, L"aml:initials", m_oInitials ) - WritingElement_ReadAttributes_End( oReader ) + WritingElement_ReadAttributes_Start_No_NS( oReader ) + WritingElement_ReadAttributes_Read_if ( oReader, L"author", m_oAuthor ) + WritingElement_ReadAttributes_Read_else_if( oReader, L"date", m_oDate ) + WritingElement_ReadAttributes_Read_else_if( oReader, L"oodata", m_oOOData ) + WritingElement_ReadAttributes_Read_else_if( oReader, L"id", m_oId ) + WritingElement_ReadAttributes_Read_else_if( oReader, L"initials", m_oInitials ) + WritingElement_ReadAttributes_End_No_NS( oReader ) } CComments::CComments(OOX::Document *pMain) : OOX::File(pMain), OOX::IFileContainer(pMain) @@ -354,14 +349,14 @@ namespace OOX if ( !oReader.ReadNextNode() ) return; - std::wstring sName = oReader.GetName(); - if ( L"w:comments" == sName && !oReader.IsEmptyNode() ) + std::wstring sName = oReader.GetNameNoNS(); + if ( L"comments" == sName && !oReader.IsEmptyNode() ) { int nNumberingDepth = oReader.GetDepth(); while ( oReader.ReadNextSiblingNode( nNumberingDepth ) ) { - sName = oReader.GetName(); - if ( L"w:comment" == sName ) + sName = oReader.GetNameNoNS(); + if ( L"comment" == sName ) { CComment* pComment = new CComment(); *pComment = oReader; @@ -427,11 +422,11 @@ namespace OOX } void CCommentExt::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) { - WritingElement_ReadAttributes_Start( oReader ) - WritingElement_ReadAttributes_Read_if ( oReader, L"w15:paraId", m_oParaId ) - WritingElement_ReadAttributes_Read_else_if( oReader, L"w15:paraIdParent", m_oParaIdParent ) - WritingElement_ReadAttributes_Read_else_if( oReader, L"w15:done", m_oDone ) - WritingElement_ReadAttributes_End( oReader ) + WritingElement_ReadAttributes_Start_No_NS( oReader ) + WritingElement_ReadAttributes_Read_if ( oReader, L"paraId", m_oParaId ) + WritingElement_ReadAttributes_Read_else_if( oReader, L"paraIdParent", m_oParaIdParent ) + WritingElement_ReadAttributes_Read_else_if( oReader, L"done", m_oDone ) + WritingElement_ReadAttributes_End_No_NS( oReader ) } CCommentsExt::CCommentsExt(OOX::Document *pMain) : OOX::File(pMain)//, OOX::IFileContainer(pMain) @@ -699,10 +694,10 @@ namespace OOX } void CCommentId::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) { - WritingElement_ReadAttributes_Start( oReader ) - WritingElement_ReadAttributes_Read_if ( oReader, L"w16cid:paraId", m_oParaId ) - WritingElement_ReadAttributes_Read_else_if( oReader, L"w16cid:durableId", m_oDurableId ) - WritingElement_ReadAttributes_End( oReader ) + WritingElement_ReadAttributes_Start_No_NS( oReader ) + WritingElement_ReadAttributes_Read_if ( oReader, L"paraId", m_oParaId ) + WritingElement_ReadAttributes_Read_else_if( oReader, L"durableId", m_oDurableId ) + WritingElement_ReadAttributes_End_No_NS( oReader ) } CCommentsIds::CCommentsIds(OOX::Document *pMain) : OOX::File(pMain) @@ -742,8 +737,8 @@ namespace OOX int nNumberingDepth = oReader.GetDepth(); while ( oReader.ReadNextSiblingNode( nNumberingDepth ) ) { - sName = oReader.GetName(); - if ( L"w16cid:commentId" == sName ) + sName = oReader.GetNameNoNS(); + if ( L"commentId" == sName ) { CCommentId* pCommentExt = new CCommentId(); *pCommentExt = oReader; @@ -855,9 +850,9 @@ namespace OOX } void CPerson::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) { - WritingElement_ReadAttributes_Start( oReader ) - WritingElement_ReadAttributes_Read_if ( oReader, L"w15:author", m_oAuthor ) - WritingElement_ReadAttributes_End( oReader ) + WritingElement_ReadAttributes_Start_No_NS( oReader ) + WritingElement_ReadAttributes_Read_if ( oReader, L"author", m_oAuthor ) + WritingElement_ReadAttributes_End_No_NS( oReader ) } CPeople::CPeople(OOX::Document *pMain) : OOX::File(pMain) diff --git a/OOXML/DocxFormat/Core.cpp b/OOXML/DocxFormat/Core.cpp index 2b8b76ebbb1..24d54078e06 100644 --- a/OOXML/DocxFormat/Core.cpp +++ b/OOXML/DocxFormat/Core.cpp @@ -33,7 +33,6 @@ #include "Core.h" #include "Docx.h" #include "../XlsxFormat/Xlsx.h" -#include "../PPTXFormat/Core.h" #include "../../DesktopEditor/common/SystemUtils.h" @@ -270,73 +269,152 @@ xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">"); { m_sLastModifiedBy = sVal; } + void CCore::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + pWriter->StartRecord(NSBinPptxRW::NSMainTables::Core); + + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeStart); + + pWriter->WriteString2(0, m_sTitle); + pWriter->WriteString2(1, m_sCreator); + pWriter->WriteString2(2, m_sLastModifiedBy); + pWriter->WriteString2(3, m_sRevision); + pWriter->WriteString2(4, m_sCreated); + pWriter->WriteString2(5, m_sModified); + + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd); + + //start new record because new attributes is incompatible with previous versions + pWriter->StartRecord(0); + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeStart); - PPTX::Core* CCore::ToPptxCore() + pWriter->WriteString2(6, m_sCategory); + pWriter->WriteString2(7, m_sContentStatus); + pWriter->WriteString2(8, m_sDescription); + pWriter->WriteString2(9, m_sIdentifier); + pWriter->WriteString2(10, m_sKeywords); + pWriter->WriteString2(11, m_sLanguage); + pWriter->WriteString2(12, m_sLastPrinted); + pWriter->WriteString2(13, m_sSubject); + pWriter->WriteString2(14, m_sVersion); + + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd); + pWriter->EndRecord(); + + pWriter->EndRecord(); + } + void CCore::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) { - PPTX::Core* res = new PPTX::Core(NULL); - if (m_sCategory.IsInit()) - res->category = m_sCategory.get(); - if (m_sContentStatus.IsInit()) - res->contentStatus = m_sContentStatus.get(); - if (m_sCreated.IsInit()) - res->created = m_sCreated.get(); - if (m_sCreator.IsInit()) - res->creator = m_sCreator.get(); - if (m_sDescription.IsInit()) - res->description = m_sDescription.get(); - if (m_sIdentifier.IsInit()) - res->identifier = m_sIdentifier.get(); - if (m_sKeywords.IsInit()) - res->keywords = m_sKeywords.get(); - if (m_sLanguage.IsInit()) - res->language = m_sLanguage.get(); - if (m_sLastModifiedBy.IsInit()) - res->lastModifiedBy = m_sLastModifiedBy.get(); - if (m_sLastPrinted.IsInit()) - res->lastPrinted = m_sLastPrinted.get(); - if (m_sModified.IsInit()) - res->modified = m_sModified.get(); - if (m_sRevision.IsInit()) - res->revision = m_sRevision.get(); - if (m_sSubject.IsInit()) - res->subject = m_sSubject.get(); - if (m_sTitle.IsInit()) - res->title = m_sTitle.get(); - if (m_sVersion.IsInit()) - res->version = m_sVersion.get(); - return res; + pReader->Skip(1); // type + LONG _end_rec = pReader->GetPos() + pReader->GetRecordSize() + 4; + + pReader->Skip(1); // start attributes + + while (true) + { + BYTE _at = pReader->GetUChar_TypeNode(); + if (_at == NSBinPptxRW::g_nodeAttributeEnd) + break; + + switch (_at) + { + case 0: m_sTitle = pReader->GetString2(); break; + case 1: m_sCreator = pReader->GetString2(); break; + case 2: m_sLastModifiedBy = pReader->GetString2(); break; + case 3: m_sRevision = pReader->GetString2(); break; + case 4: m_sCreated = pReader->GetString2(); break; + case 5: m_sModified = pReader->GetString2(); break; + default: break; + } + } + while (pReader->GetPos() < _end_rec) + { + BYTE _at = pReader->GetUChar(); + switch (_at) + { + case 0: + { + LONG _end_rec2 = pReader->GetPos() + pReader->GetRecordSize() + 4; + + pReader->Skip(1); // start attributes + + while (true) + { + BYTE _at = pReader->GetUChar_TypeNode(); + if (_at == NSBinPptxRW::g_nodeAttributeEnd) + break; + + switch (_at) + { + case 6: m_sCategory = pReader->GetString2(); break; + case 7: m_sContentStatus = pReader->GetString2(); break; + case 8: m_sDescription = pReader->GetString2(); break; + case 9: m_sIdentifier = pReader->GetString2(); break; + case 10: m_sKeywords = pReader->GetString2(); break; + case 11: m_sLanguage = pReader->GetString2(); break; + case 12: m_sLastPrinted = pReader->GetString2(); break; + case 13: m_sSubject = pReader->GetString2(); break; + case 14: m_sVersion = pReader->GetString2(); break; + } + } + + pReader->Seek(_end_rec2); + } + break; + default: + { + pReader->SkipRecord(); + break; + } + } + } + + pReader->Seek(_end_rec); } - void CCore::FromPptxCore(PPTX::Core* pCore) + void CCore::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const { - if(pCore->category.IsInit()) - m_sCategory = pCore->category.get(); - if(pCore->contentStatus.IsInit()) - m_sContentStatus = pCore->contentStatus.get(); - if(pCore->created.IsInit()) - m_sCreated = pCore->created.get(); - if(pCore->creator.IsInit()) - m_sCreator = pCore->creator.get(); - if(pCore->description.IsInit()) - m_sDescription = pCore->description.get(); - if(pCore->identifier.IsInit()) - m_sIdentifier = pCore->identifier.get(); - if(pCore->keywords.IsInit()) - m_sKeywords = pCore->keywords.get(); - if(pCore->language.IsInit()) - m_sLanguage = pCore->language.get(); - if(pCore->lastModifiedBy.IsInit()) - m_sLastModifiedBy = pCore->lastModifiedBy.get(); - if(pCore->lastPrinted.IsInit()) - m_sLastPrinted = pCore->lastPrinted.get(); - if(pCore->modified.IsInit()) - m_sModified = pCore->modified.get(); - if(pCore->revision.IsInit()) - m_sRevision = pCore->revision.get(); - if(pCore->subject.IsInit()) - m_sSubject = pCore->subject.get(); - if(pCore->title.IsInit()) - m_sTitle = pCore->title.get(); - if(pCore->version.IsInit()) - m_sVersion = pCore->version.get(); + pWriter->StartNode(_T("cp:coreProperties")); + + pWriter->StartAttributes(); + + pWriter->WriteAttribute(_T("xmlns:cp"), PPTX::g_Namespaces.cp.m_strLink); + pWriter->WriteAttribute(_T("xmlns:dc"), PPTX::g_Namespaces.dc.m_strLink); + pWriter->WriteAttribute(_T("xmlns:dcterms"), PPTX::g_Namespaces.dcterms.m_strLink); + pWriter->WriteAttribute(_T("xmlns:dcmitype"), PPTX::g_Namespaces.dcmitype.m_strLink); + pWriter->WriteAttribute(_T("xmlns:xsi"), PPTX::g_Namespaces.xsi.m_strLink); + + pWriter->EndAttributes(); + + pWriter->WriteNodeValue2(_T("dc:title"), m_sTitle); + pWriter->WriteNodeValue2(_T("dc:subject"), m_sSubject); + pWriter->WriteNodeValue2(_T("dc:creator"), m_sCreator); + pWriter->WriteNodeValue2(_T("cp:keywords"), m_sKeywords); + pWriter->WriteNodeValue2(_T("dc:description"), m_sDescription); + pWriter->WriteNodeValue2(_T("dc:identifier"), m_sIdentifier); + pWriter->WriteNodeValue2(_T("dc:language"), m_sLanguage); + pWriter->WriteNodeValue2(_T("cp:lastModifiedBy"), m_sLastModifiedBy); + pWriter->WriteNodeValue2(_T("cp:revision"), m_sRevision); + + if ((m_sLastPrinted.IsInit()) && (false == m_sLastPrinted->empty())) + { + pWriter->WriteNodeValue2(_T("cp:lastPrinted"), m_sLastPrinted); + } + if ((m_sCreated.IsInit()) && (false == m_sCreated->empty())) + { + pWriter->WriteNodeBegin(_T("dcterms:created xsi:type=\"dcterms:W3CDTF\"")); + pWriter->WriteStringXML(*m_sCreated); + pWriter->WriteNodeEnd(_T("dcterms:created")); + } + if ((m_sModified.IsInit()) && (false == m_sModified->empty())) + { + pWriter->WriteNodeBegin(_T("dcterms:modified xsi:type=\"dcterms:W3CDTF\"")); + pWriter->WriteStringXML(*m_sModified); + pWriter->WriteNodeEnd(_T("dcterms:modified")); + } + pWriter->WriteNodeValue2(_T("cp:category"), m_sCategory); + pWriter->WriteNodeValue2(_T("cp:contentStatus"), m_sContentStatus); + pWriter->WriteNodeValue2(_T("cp:version"), m_sVersion); + + pWriter->EndNode(_T("cp:coreProperties")); } } // namespace OOX diff --git a/OOXML/DocxFormat/Core.h b/OOXML/DocxFormat/Core.h index bb1872c86a2..44e971c1181 100644 --- a/OOXML/DocxFormat/Core.h +++ b/OOXML/DocxFormat/Core.h @@ -60,8 +60,9 @@ namespace OOX void SetCreator(std::wstring sVal); void SetLastModifiedBy(std::wstring sVal); - PPTX::Core* ToPptxCore(); - void FromPptxCore(PPTX::Core* pCore); + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; nullable_string m_sCategory; nullable_string m_sContentStatus; diff --git a/OOXML/DocxFormat/CustomXml.cpp b/OOXML/DocxFormat/CustomXml.cpp index 49f96d5e5ca..0abb012daf1 100644 --- a/OOXML/DocxFormat/CustomXml.cpp +++ b/OOXML/DocxFormat/CustomXml.cpp @@ -155,7 +155,7 @@ namespace OOX CCustomXMLProps::CCustomXMLProps(OOX::Document *pMain) : OOX::FileGlobalEnumerated(pMain) { } - CCustomXMLProps::CCustomXMLProps(OOX::Document *pMain, const OOX::CPath& oFilePath): OOX::FileGlobalEnumerated(pMain) + CCustomXMLProps::CCustomXMLProps(OOX::Document *pMain, const OOX::CPath& oFilePath) : OOX::FileGlobalEnumerated(pMain) { read( oFilePath ); } diff --git a/OOXML/DocxFormat/Diagram/DiagramColors.cpp b/OOXML/DocxFormat/Diagram/DiagramColors.cpp index 6880951fda5..a4e9d901368 100644 --- a/OOXML/DocxFormat/Diagram/DiagramColors.cpp +++ b/OOXML/DocxFormat/Diagram/DiagramColors.cpp @@ -34,11 +34,56 @@ #include "DiagramColors.h" #include "../../Common/SimpleTypes_Drawing.h" +#include "../Document.h" +#include "../../XlsxFormat/Xlsx.h" + #include "../Drawing/DrawingExt.h" #include "../../Binary/Presentation/BinaryFileReaderWriter.h" namespace OOX { + CDiagramColors::CDiagramColors(OOX::Document* pMain, bool bDocument) : OOX::IFileContainer(pMain), OOX::FileGlobalEnumerated(pMain) + { + m_bDocument = bDocument; + m_bSpreadsheets = (NULL != dynamic_cast(pMain)); + } + CDiagramColors::CDiagramColors(OOX::Document* pMain, const CPath& uri) : OOX::IFileContainer(pMain), OOX::FileGlobalEnumerated(pMain) + { + m_bDocument = (NULL != dynamic_cast(pMain)); + m_bSpreadsheets = (NULL != dynamic_cast(pMain)); + + read(uri.GetDirectory(), uri); + } + CDiagramColors::CDiagramColors(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath) : OOX::IFileContainer(pMain), OOX::FileGlobalEnumerated(pMain) + { + m_bDocument = (NULL != dynamic_cast(pMain)); + m_bSpreadsheets = (NULL != dynamic_cast(pMain)); + + read(oRootPath, oPath); + } + CDiagramColors::~CDiagramColors() + { + } + const OOX::FileType CDiagramColors::type() const + { + return FileTypes::DiagramColors; + } + const CPath CDiagramColors::DefaultDirectory() const + { + if (m_bDocument) + return type().DefaultDirectory(); + else + return L"../" + type().DefaultDirectory(); + } + const CPath CDiagramColors::DefaultFileName() const + { + return type().DefaultFileName(); + } + void CDiagramColors::read(const CPath& oFilePath) + { + CPath oRootPath; + read(oRootPath, oFilePath); + } void CDiagramColors::read(const CPath& oRootPath, const CPath& oFilePath) { IFileContainer::Read(oRootPath, oFilePath); @@ -204,6 +249,8 @@ namespace OOX } void Diagram::CClrLst::fromXML(XmlUtils::CXmlLiteReader& oReader) { + node_name = oReader.GetName(); + ReadAttributes(oReader); if (oReader.IsEmptyNode()) diff --git a/OOXML/DocxFormat/Diagram/DiagramColors.h b/OOXML/DocxFormat/Diagram/DiagramColors.h index a5400568c53..83ab66995e5 100644 --- a/OOXML/DocxFormat/Diagram/DiagramColors.h +++ b/OOXML/DocxFormat/Diagram/DiagramColors.h @@ -114,40 +114,19 @@ namespace OOX class CDiagramColors : public OOX::FileGlobalEnumerated, public OOX::IFileContainer { public: - CDiagramColors(OOX::Document* pMain) : OOX::IFileContainer(pMain), OOX::FileGlobalEnumerated(pMain) - { - } - CDiagramColors(OOX::Document* pMain, const CPath& uri) : OOX::IFileContainer(pMain), OOX::FileGlobalEnumerated(pMain) - { - read(uri.GetDirectory(), uri); - } - CDiagramColors(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath) : OOX::IFileContainer(pMain), OOX::FileGlobalEnumerated(pMain) - { - read(oRootPath, oPath); - } - virtual ~CDiagramColors() - { - } - virtual void read(const CPath& oFilePath) - { - CPath oRootPath; - read(oRootPath, oFilePath); - } + CDiagramColors(OOX::Document* pMain, bool bDocument = true); + CDiagramColors(OOX::Document* pMain, const CPath& uri); + CDiagramColors(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath); + virtual ~CDiagramColors(); + + virtual void read(const CPath& oFilePath); virtual void read(const CPath& oRootPath, const CPath& oFilePath); virtual void write(const CPath& oFilePath, const CPath& oDirectory, CContentTypes& oContent) const; - virtual const OOX::FileType type() const - { - return FileTypes::DiagramColors; - } - virtual const CPath DefaultDirectory() const - { - return type().DefaultDirectory(); - } - virtual const CPath DefaultFileName() const - { - return type().DefaultFileName(); - } + virtual const OOX::FileType type() const; + virtual const CPath DefaultDirectory() const; + virtual const CPath DefaultFileName() const; + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; @@ -163,5 +142,6 @@ namespace OOX nullable m_oExtLst; private: void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + bool m_bDocument = true; //for upper/lower level rels (defaultDirectory) }; } // namespace OOX diff --git a/OOXML/DocxFormat/Diagram/DiagramData.cpp b/OOXML/DocxFormat/Diagram/DiagramData.cpp index 3e127a4c4a9..018e09761e2 100644 --- a/OOXML/DocxFormat/Diagram/DiagramData.cpp +++ b/OOXML/DocxFormat/Diagram/DiagramData.cpp @@ -37,8 +37,11 @@ #include "../../Common/SimpleTypes_Shared.h" #include "../Drawing/DrawingExt.h" -#include "../../../OOXML/PPTXFormat/Logic/SpTree.h" +#include "../Document.h" +#include "../../XlsxFormat/Xlsx.h" + +#include "../../PPTXFormat/Logic/SpTree.h" #include "../../Binary/Presentation/BinaryFileReaderWriter.h" namespace OOX @@ -181,7 +184,7 @@ namespace OOX void Diagram::CAnimLvl::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const { - WriteByteToPPTY(m_oVal.IsInit() ? (BYTE)m_oVal->GetValue() : 0, pWriter); + WriteByteToPPTY(m_oVal.IsInit() ? (BYTE)m_oVal->GetValue() : SimpleTypes::EAnimLvlStr::animLvlStr_none, pWriter); } //------------------------------------------------------------------------------------------------------ @@ -211,7 +214,7 @@ namespace OOX void Diagram::CAnimOne::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const { - WriteByteToPPTY(m_oVal.IsInit() ? (BYTE)m_oVal->GetValue() : 0, pWriter); + WriteByteToPPTY(m_oVal.IsInit() ? (BYTE)m_oVal->GetValue() : SimpleTypes::EAnimOneStr::animOneStr_none, pWriter); } //------------------------------------------------------------------------------------------------------ @@ -241,7 +244,7 @@ namespace OOX void Diagram::CBulletEnabled::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const { - WriteByteToPPTY(m_oVal.IsInit() ? (BYTE)m_oVal->GetValue() : 0, pWriter); + WriteByteToPPTY(m_oVal.IsInit() ? (BYTE)m_oVal->GetValue() : SimpleTypes::onoffFalse, pWriter); } //------------------------------------------------------------------------------------------------------ @@ -331,7 +334,7 @@ namespace OOX void Diagram::CDirection::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const { - WriteByteToPPTY(m_oVal.IsInit() ? (BYTE)m_oVal->GetValue() : 0, pWriter); + WriteByteToPPTY(m_oVal.IsInit() ? (BYTE)m_oVal->GetValue() : SimpleTypes::EDirectionDraw::direction_norm, pWriter); } //------------------------------------------------------------------------------------------------------ @@ -360,7 +363,7 @@ namespace OOX void Diagram::CHierBranch::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const { - WriteByteToPPTY(m_oVal.IsInit() ? (BYTE)m_oVal->GetValue() : 0, pWriter); + WriteByteToPPTY(m_oVal.IsInit() ? (BYTE)m_oVal->GetValue() : SimpleTypes::EHierBranch::hierBranch_std, pWriter); } //------------------------------------------------------------------------------------------------------ @@ -390,7 +393,7 @@ namespace OOX void Diagram::COrgChart::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const { - WriteByteToPPTY(m_oVal.IsInit() ? (BYTE)m_oVal->GetValue() : 0, pWriter); + WriteByteToPPTY(m_oVal.IsInit() ? (BYTE)m_oVal->GetValue() : SimpleTypes::EOnOff::onoffFalse, pWriter); } //------------------------------------------------------------------------------------------------------ @@ -420,7 +423,7 @@ namespace OOX void Diagram::CResizeHandles::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const { - WriteByteToPPTY(m_oVal.IsInit() ? (BYTE)m_oVal->GetValue() : 0, pWriter); + WriteByteToPPTY(m_oVal.IsInit() ? (BYTE)m_oVal->GetValue() : SimpleTypes::EResizeHandles::resizeHandles_exact, pWriter); } //------------------------------------------------------------------------------------------------------ @@ -443,6 +446,8 @@ namespace OOX void Diagram::CVariableList::fromXML(XmlUtils::CXmlLiteReader& oReader) { + node_name = oReader.GetName(); + if (oReader.IsEmptyNode()) return; @@ -1701,6 +1706,8 @@ namespace OOX void Diagram::CText::fromXML(XmlUtils::CXmlLiteReader& oReader) { + node_name = oReader.GetName(); + ReadAttributes(oReader); if (oReader.IsEmptyNode()) @@ -1751,17 +1758,25 @@ namespace OOX //------------------------------------------------------------------------------------------- - CDiagramData::CDiagramData(OOX::Document* pMain) : OOX::IFileContainer(pMain), OOX::FileGlobalEnumerated(pMain) + CDiagramData::CDiagramData(OOX::Document* pMain, bool bDocument) : OOX::IFileContainer(pMain), OOX::FileGlobalEnumerated(pMain) { + m_bDocument = bDocument; + m_bSpreadsheets = (NULL != dynamic_cast(pMain)); } CDiagramData::CDiagramData(OOX::Document* pMain, const CPath& uri) : OOX::IFileContainer(pMain), OOX::FileGlobalEnumerated(pMain) { + m_bDocument = (NULL != dynamic_cast(pMain)); + m_bSpreadsheets = (NULL != dynamic_cast(pMain)); + read(uri.GetDirectory(), uri); } CDiagramData::CDiagramData(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath) : OOX::IFileContainer(pMain), OOX::FileGlobalEnumerated(pMain) { + m_bDocument = (NULL != dynamic_cast(pMain)); + m_bSpreadsheets = (NULL != dynamic_cast(pMain)); + read( oRootPath, oPath ); } @@ -1828,7 +1843,10 @@ namespace OOX const CPath CDiagramData::DefaultDirectory() const { - return type().DefaultDirectory(); + if (m_bDocument) + return type().DefaultDirectory(); + else + return L"../" + type().DefaultDirectory(); } const CPath CDiagramData::DefaultFileName() const diff --git a/OOXML/DocxFormat/Diagram/DiagramData.h b/OOXML/DocxFormat/Diagram/DiagramData.h index 7613f782ff9..7f33e3e0766 100644 --- a/OOXML/DocxFormat/Diagram/DiagramData.h +++ b/OOXML/DocxFormat/Diagram/DiagramData.h @@ -609,7 +609,7 @@ namespace OOX class CDiagramData : public OOX::IFileContainer, public OOX::FileGlobalEnumerated { public: - CDiagramData(OOX::Document* pMain); + CDiagramData(OOX::Document* pMain, bool bDocument = true); CDiagramData(OOX::Document* pMain, const CPath& uri); CDiagramData(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath); virtual ~CDiagramData(); @@ -632,6 +632,8 @@ namespace OOX nullable m_oDataModel; nullable id_drawing; + private: + bool m_bDocument = true; //for upper/lower level rels (defaultDirectory) }; } // namespace OOX diff --git a/OOXML/DocxFormat/Diagram/DiagramDrawing.cpp b/OOXML/DocxFormat/Diagram/DiagramDrawing.cpp index eb1fbe76d48..dce0503fac9 100644 --- a/OOXML/DocxFormat/Diagram/DiagramDrawing.cpp +++ b/OOXML/DocxFormat/Diagram/DiagramDrawing.cpp @@ -33,23 +33,34 @@ #include "DiagramDrawing.h" +#include "../Document.h" +#include "../../XlsxFormat/Xlsx.h" + #include "../../PPTXFormat/Logic/SpTree.h" #include "../../Binary/Presentation/BinaryFileReaderWriter.h" #include "../Logic/Pict.h" namespace OOX { - CDiagramDrawing::CDiagramDrawing(OOX::Document* pMain) : OOX::FileGlobalEnumerated(pMain), OOX::IFileContainer(pMain) + CDiagramDrawing::CDiagramDrawing(OOX::Document* pMain, bool bDocument) : OOX::FileGlobalEnumerated(pMain), OOX::IFileContainer(pMain) { + m_bDocument = bDocument; + m_bSpreadsheets = (NULL != dynamic_cast(pMain)); } CDiagramDrawing::CDiagramDrawing(OOX::Document* pMain, const CPath& uri) : OOX::FileGlobalEnumerated(pMain), OOX::IFileContainer(pMain) { + m_bDocument = (NULL != dynamic_cast(pMain)); + m_bSpreadsheets = (NULL != dynamic_cast(pMain)); + read(uri.GetDirectory(), uri); } CDiagramDrawing::CDiagramDrawing(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath) : OOX::FileGlobalEnumerated(pMain), OOX::IFileContainer(pMain) { + m_bDocument = (NULL != dynamic_cast(pMain)); + m_bSpreadsheets = (NULL != dynamic_cast(pMain)); + read( oRootPath, oPath ); } @@ -95,7 +106,10 @@ namespace OOX } const CPath CDiagramDrawing::DefaultDirectory() const { - return type().DefaultDirectory(); + if (m_bDocument) + return type().DefaultDirectory(); + else + return L"../" + type().DefaultDirectory(); } const CPath CDiagramDrawing::DefaultFileName() const { diff --git a/OOXML/DocxFormat/Diagram/DiagramDrawing.h b/OOXML/DocxFormat/Diagram/DiagramDrawing.h index 6effd5568b6..d3620766340 100644 --- a/OOXML/DocxFormat/Diagram/DiagramDrawing.h +++ b/OOXML/DocxFormat/Diagram/DiagramDrawing.h @@ -48,7 +48,7 @@ namespace OOX class CDiagramDrawing : public OOX::IFileContainer, public OOX::FileGlobalEnumerated { public: - CDiagramDrawing(OOX::Document* pMain); + CDiagramDrawing(OOX::Document* pMain, bool bDocument = true); CDiagramDrawing(OOX::Document* pMain, const CPath& uri); CDiagramDrawing(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath); @@ -73,6 +73,7 @@ namespace OOX CPath m_oReadPath; nullable m_oShapeTree; - + private: + bool m_bDocument = true; //for upper/lower level rels (defaultDirectory) }; } // namespace OOX diff --git a/OOXML/DocxFormat/Diagram/DiagramLayout.cpp b/OOXML/DocxFormat/Diagram/DiagramLayout.cpp index f8205c07a29..6277d0b4375 100644 --- a/OOXML/DocxFormat/Diagram/DiagramLayout.cpp +++ b/OOXML/DocxFormat/Diagram/DiagramLayout.cpp @@ -34,6 +34,9 @@ #include "DiagramLayout.h" #include "../Drawing/DrawingExt.h" +#include "../Document.h" +#include "../../XlsxFormat/Xlsx.h" + #include "../../Common/SimpleTypes_Shared.h" #include "../../Common/SimpleTypes_Drawing.h" @@ -124,15 +127,23 @@ for (size_t i = 0; i < m_arrItems.size(); ++i)\ //------------------------------------------------------------------------------------------------------------------ namespace OOX { - CDiagramLayout::CDiagramLayout(OOX::Document* pMain) : OOX::IFileContainer(pMain), OOX::FileGlobalEnumerated(pMain) + CDiagramLayout::CDiagramLayout(OOX::Document* pMain, bool bDocument) : OOX::IFileContainer(pMain), OOX::FileGlobalEnumerated(pMain) { + m_bDocument = bDocument; + m_bSpreadsheets = (NULL != dynamic_cast(pMain)); } CDiagramLayout::CDiagramLayout(OOX::Document* pMain, const CPath& uri) : OOX::IFileContainer(pMain), OOX::FileGlobalEnumerated(pMain) { + m_bDocument = (NULL != dynamic_cast(pMain)); + m_bSpreadsheets = (NULL != dynamic_cast(pMain)); + read(uri.GetDirectory(), uri); } CDiagramLayout::CDiagramLayout(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath) : OOX::IFileContainer(pMain), OOX::FileGlobalEnumerated(pMain) { + m_bDocument = (NULL != dynamic_cast(pMain)); + m_bSpreadsheets = (NULL != dynamic_cast(pMain)); + read(oRootPath, oPath); } CDiagramLayout::~CDiagramLayout() @@ -232,7 +243,10 @@ namespace OOX } const CPath CDiagramLayout::DefaultDirectory() const { - return type().DefaultDirectory(); + if (m_bDocument) + return type().DefaultDirectory(); + else + return L"../" + type().DefaultDirectory(); } const CPath CDiagramLayout::DefaultFileName() const { @@ -361,10 +375,13 @@ namespace OOX } void Diagram::CDiferentData::fromXML(XmlUtils::CXmlLiteReader& oReader) { + node_name = oReader.GetName(); + ReadAttributes(oReader); if (oReader.IsEmptyNode()) return; + int nParentDepth = oReader.GetDepth(); while (oReader.ReadNextSiblingNode(nParentDepth)) { diff --git a/OOXML/DocxFormat/Diagram/DiagramLayout.h b/OOXML/DocxFormat/Diagram/DiagramLayout.h index 047aec82121..24d147a726b 100644 --- a/OOXML/DocxFormat/Diagram/DiagramLayout.h +++ b/OOXML/DocxFormat/Diagram/DiagramLayout.h @@ -504,7 +504,7 @@ namespace OOX class CDiagramLayout : public OOX::FileGlobalEnumerated, public OOX::IFileContainer { public: - CDiagramLayout(OOX::Document* pMain); + CDiagramLayout(OOX::Document* pMain, bool bDocument = true); CDiagramLayout(OOX::Document* pMain, const CPath& uri); CDiagramLayout(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath); virtual ~CDiagramLayout(); @@ -538,6 +538,7 @@ namespace OOX nullable m_oExtLst; private: void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + bool m_bDocument = true; //for upper/lower level rels (defaultDirectory) }; } // namespace OOX diff --git a/OOXML/DocxFormat/Diagram/DiagramQuickStyle.cpp b/OOXML/DocxFormat/Diagram/DiagramQuickStyle.cpp index 94cc1e7c993..26daa2eb8b0 100644 --- a/OOXML/DocxFormat/Diagram/DiagramQuickStyle.cpp +++ b/OOXML/DocxFormat/Diagram/DiagramQuickStyle.cpp @@ -34,21 +34,32 @@ #include "DiagramQuickStyle.h" #include "../Drawing/DrawingExt.h" +#include "../Document.h" +#include "../../XlsxFormat/Xlsx.h" + #include "../../Binary/Presentation/BinaryFileReaderWriter.h" namespace OOX { - CDiagramQuickStyle::CDiagramQuickStyle(OOX::Document* pMain) : OOX::IFileContainer(pMain), OOX::FileGlobalEnumerated(pMain) + CDiagramQuickStyle::CDiagramQuickStyle(OOX::Document* pMain, bool bDocument) : OOX::IFileContainer(pMain), OOX::FileGlobalEnumerated(pMain) { + m_bDocument = bDocument; + m_bSpreadsheets = (NULL != dynamic_cast(pMain)); } CDiagramQuickStyle::CDiagramQuickStyle(OOX::Document* pMain, const CPath& uri) : OOX::IFileContainer(pMain), OOX::FileGlobalEnumerated(pMain) { + m_bDocument = (NULL != dynamic_cast(pMain)); + m_bSpreadsheets = (NULL != dynamic_cast(pMain)); + read(uri.GetDirectory(), uri); } CDiagramQuickStyle::CDiagramQuickStyle(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath) : OOX::IFileContainer(pMain), OOX::FileGlobalEnumerated(pMain) { + m_bDocument = (NULL != dynamic_cast(pMain)); + m_bSpreadsheets = (NULL != dynamic_cast(pMain)); + read(oRootPath, oPath); } @@ -148,7 +159,10 @@ namespace OOX const CPath CDiagramQuickStyle::DefaultDirectory() const { - return type().DefaultDirectory(); + if (m_bDocument) + return type().DefaultDirectory(); + else + return L"../" + type().DefaultDirectory(); } const CPath CDiagramQuickStyle::DefaultFileName() const diff --git a/OOXML/DocxFormat/Diagram/DiagramQuickStyle.h b/OOXML/DocxFormat/Diagram/DiagramQuickStyle.h index 0ded760a569..c6fcc894f29 100644 --- a/OOXML/DocxFormat/Diagram/DiagramQuickStyle.h +++ b/OOXML/DocxFormat/Diagram/DiagramQuickStyle.h @@ -74,7 +74,7 @@ namespace OOX class CDiagramQuickStyle : public OOX::FileGlobalEnumerated, public OOX::IFileContainer { public: - CDiagramQuickStyle(OOX::Document* pMain); + CDiagramQuickStyle(OOX::Document* pMain, bool bDocument = true); CDiagramQuickStyle(OOX::Document* pMain, const CPath& uri); CDiagramQuickStyle(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath); @@ -107,6 +107,7 @@ namespace OOX private: void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + bool m_bDocument = true; //for upper/lower level rels (defaultDirectory) }; } // namespace OOX diff --git a/OOXML/DocxFormat/Document.cpp b/OOXML/DocxFormat/Document.cpp index a9fb5368820..d887148c67e 100644 --- a/OOXML/DocxFormat/Document.cpp +++ b/OOXML/DocxFormat/Document.cpp @@ -144,7 +144,42 @@ namespace OOX WritingElement_ReadAttributes_Read_else_if(oReader, L"w:themeTint", m_oThemeTint) WritingElement_ReadAttributes_End(oReader) } +//------------------------------------------------------------------------------------------------------------------------------------------------ + CDocSuppData::CDocSuppData(OOX::Document* pMain) : WritingElement(pMain) + { + } + CDocSuppData::~CDocSuppData() + { + } + void CDocSuppData::fromXML(XmlUtils::CXmlNode& oNode) + { + } + std::wstring CDocSuppData::toXML() const + { + return L""; + } + EElementType CDocSuppData::getType() const + { + return et_w_docSuppData; + } + void CDocSuppData::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + if (oReader.IsEmptyNode()) + return; + + int nCurDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nCurDepth)) + { + std::wstring sName = XmlUtils::GetNameNoNS(oReader.GetName()); + if (L"binData" == sName) + m_oBinData = oReader; + } + } + void CDocSuppData::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + } +//------------------------------------------------------------------------------------------------------------------------------------------------ CBgPict::CBgPict(OOX::Document *pMain) : WritingElement(pMain) { } @@ -229,25 +264,34 @@ namespace OOX if (pos != std::wstring::npos) fileName = fileName.substr(0, pos); CDocx* docx = dynamic_cast(pMain); - if (docx && fileName == L"document") + if (docx) { - if (type == OOX::FileTypes::Document) + OOX::CDocument* current = NULL; + if (type == OOX::FileTypes::Document || type == FileTypes::DocumentMacro) { - docx->m_oMain.document = this; - } - else if (type == FileTypes::DocumentMacro) - { - docx->m_oMain.document = this; - m_bMacroEnabled = true; + current = docx->m_oMain.document; } else if (type == OOX::FileTypes::GlossaryDocument) { - docx->m_oGlossary.document = this; - docx->m_bGlossaryRead = true; + current = docx->m_oGlossary.document; } - else + + if (/*std::wstring::npos != fileName.find(L"document")*/ fileName == L"document" || !current) { - //??? + if (type == OOX::FileTypes::Document) + { + docx->m_oMain.document = this; + } + else if (type == FileTypes::DocumentMacro) + { + docx->m_oMain.document = this; + m_bMacroEnabled = true; + } + else if (type == OOX::FileTypes::GlossaryDocument) + { + docx->m_oGlossary.document = this; + docx->m_bGlossaryRead = true; + } } } @@ -392,7 +436,6 @@ namespace OOX pItem->fromXML(oReader); m_arrItems.push_back(pItem); } - if ( pItem ) { pItem->fromXML(oReader); diff --git a/OOXML/DocxFormat/Document.h b/OOXML/DocxFormat/Document.h index 206ac8e45ed..bc804c04c59 100644 --- a/OOXML/DocxFormat/Document.h +++ b/OOXML/DocxFormat/Document.h @@ -80,10 +80,28 @@ namespace OOX nullable m_oDrawing; nullable m_oBackground; }; + + class CDocSuppData : public WritingElement + {//Word 2003 XML Reference + public: + WritingElement_AdditionMethods(CDocSuppData) + CDocSuppData(OOX::Document* pMain = NULL); + virtual ~CDocSuppData(); + + virtual void fromXML(XmlUtils::CXmlNode& oNode); + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + + virtual std::wstring toXML() const; + virtual EElementType getType() const; - //Word 2003 XML Reference + private: + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + + public: + nullable m_oBinData; + }; class CBgPict : public WritingElement - { + {//Word 2003 XML Reference public: WritingElement_AdditionMethods(CBgPict) CBgPict(OOX::Document *pMain = NULL); @@ -104,7 +122,6 @@ namespace OOX nullable_string m_oBackgroundType; nullable m_oBackground; }; - } //-------------------------------------------------------------------------------- diff --git a/OOXML/DocxFormat/DocxFlat.cpp b/OOXML/DocxFormat/DocxFlat.cpp index 75037c6a832..9496e53909a 100644 --- a/OOXML/DocxFormat/DocxFlat.cpp +++ b/OOXML/DocxFormat/DocxFlat.cpp @@ -46,6 +46,8 @@ #include "Settings/Settings.h" #include "Logic/SectionProperty.h" +#include "../../OfficeUtils/src/OfficeUtils.h" + namespace OOX { CDocxFlat::CDocxFlat() : File(dynamic_cast(this)) @@ -53,19 +55,21 @@ namespace OOX } CDocxFlat::CDocxFlat(const CPath& oFilePath) : File(dynamic_cast(this)) { - read( oFilePath ); + read(oFilePath); } CDocxFlat::~CDocxFlat() { } void CDocxFlat::read(const CPath& oFilePath) { + m_sDocumentPath = oFilePath.GetPath(); + XmlUtils::CXmlLiteReader oReader; - if ( !oReader.FromFile( oFilePath.GetPath() ) ) + if (!oReader.FromFile(oFilePath.GetPath())) return; - if ( !oReader.ReadNextNode() ) + if (!oReader.ReadNextNode()) return; fromXML(oReader); @@ -96,15 +100,15 @@ namespace OOX } void CDocxFlat::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) { - WritingElement_ReadAttributes_Start( oReader ) - WritingElement_ReadAttributes_Read_if ( oReader, L"xml:space", m_oSpace ) - WritingElement_ReadAttributes_End( oReader ) + WritingElement_ReadAttributes_Start(oReader) + WritingElement_ReadAttributes_Read_if(oReader, L"xml:space", m_oSpace) + WritingElement_ReadAttributes_End(oReader) } void CDocxFlat::fromXML(XmlUtils::CXmlLiteReader& oReader) { - ReadAttributes( oReader ); + ReadAttributes(oReader); - if ( oReader.IsEmptyNode() ) + if (oReader.IsEmptyNode()) return; m_pComments = new OOX::CComments(this); @@ -112,24 +116,25 @@ namespace OOX m_pEndnotes = new OOX::CEndnotes(this); int nDepth = oReader.GetDepth(); - while ( oReader.ReadNextSiblingNode(nDepth) ) + while (oReader.ReadNextSiblingNode(nDepth)) { std::wstring sName = oReader.GetName(); - if ( L"w:body" == sName ) + if (L"w:body" == sName) { m_pDocument = new CDocument(dynamic_cast(this)); m_currentContainer = dynamic_cast(m_pDocument.GetPointer()); m_pDocument->fromXML(oReader); + m_pDocument->m_bMacroEnabled = false; } - else if ( L"w:fonts" == sName ) + else if (L"w:fonts" == sName) m_pFontTable = oReader; else if (L"w:lists" == sName) { m_pNumbering = new CNumbering(dynamic_cast(this)); m_pNumbering->fromXML(oReader); } - else if ( L"w:styles" == sName ) + else if (L"w:styles" == sName) m_pStyles = oReader; else if (L"w:docPr" == sName) { @@ -145,8 +150,39 @@ namespace OOX { ReadDocumentProperties(oReader); } + else if (L"w:docOleData" == sName && !oReader.IsEmptyNode()) + { + m_oDocOleData = new OOX::Logic::CDocSuppData(WritingElement::m_pMainDocument); + m_oDocOleData->fromXML(oReader); + + ParsingOleData(); + } + else if (L"w:docSuppData" == sName && !oReader.IsEmptyNode()) + { + //m_oDocSuppData = new OOX::Logic::CDocSuppData(WritingElement::m_pMainDocument); + //m_oDocSuppData->fromXML(oReader); + // + //ParsingSuppData(); + } + //CustomDocumentProperties } + if (!m_sCompatibilityMode.IsInit() && m_pCore.IsInit() && (m_pCore->m_sVersion.IsInit())) + { + if (false == m_pSettings.IsInit()) m_pSettings = new CSettings(this); + if (m_pSettings->m_oCompat.IsInit()) m_pSettings->m_oCompat.Init(); + + Settings::CCompatSetting* pSett = new Settings::CCompatSetting(); + pSett->m_sName = L"compatibilityMode"; + pSett->m_sUri = L"http://schemas.microsoft.com/office/word"; + pSett->m_sVal = m_pCore->m_sVersion; + m_pSettings->m_oCompat->m_arrCompatSettings.push_back(pSett); + } + + if ((m_oDocSuppData.IsInit()) && (m_oDocSuppData->m_oBinData.IsInit()) && (m_pDocument.IsInit())) + { + m_pDocument->m_bMacroEnabled = true; + } if (false == m_pStyles->m_oDocDefaults.IsInit()) m_pStyles->m_oDocDefaults.Init(); @@ -211,7 +247,7 @@ namespace OOX { if (oReader.IsEmptyNode()) return; - + m_pApp = new OOX::CApp(this); m_pCore = new OOX::CCore(this); @@ -296,7 +332,7 @@ namespace OOX m_pApp->m_nWords = oReader.GetText2(); } } - OOX::CHdrFtr *CDocxFlat::GetHeaderOrFooter(const OOX::RId& rId) const + OOX::CHdrFtr* CDocxFlat::GetHeaderOrFooter(const OOX::RId& rId) const { OOX::IFileContainer* pDocumentContainer = (OOX::IFileContainer*)m_pDocument.GetPointer(); @@ -307,4 +343,68 @@ namespace OOX return NULL; } + void CDocxFlat::ParsingOleData() + { + if (false == m_oDocOleData.IsInit()) return; + if (false == m_oDocOleData->m_oBinData.IsInit()) return; + + std::vector pData = m_oDocOleData->m_oBinData->GetBytes(); + + NSFile::CFileBinary fileTest; + + std::wstring tempOleData = m_sTempPath + FILE_SEPARATOR_STR + L"DocOleData.bin"; + + if (false == fileTest.CreateFileW(tempOleData)) return; + + fileTest.WriteFile(pData.data(), pData.size()); + fileTest.CloseFile(); + + POLE::Storage storage(tempOleData.c_str()); + if (false == storage.open()) return; + + std::list msoStores = storage.entries(); + + int index = 0; + for (std::list::iterator it = msoStores.begin(); it != msoStores.end(); ++it) + { + POLE::Stream stream(&storage, *it); + if (stream.fail()) continue; + + smart_ptr pOleObjectFile = smart_ptr(new OOX::OleObject(this, false, true)); + OOX::CPath filename(L"oleObject.bin"); + pOleObjectFile->set_filename(filename, false, true); + + pOleObjectFile->m_Data.resize(stream.size()); + _UINT64 size = stream.read(pOleObjectFile->m_Data.data(), stream.size()); + pOleObjectFile->m_Data.resize(size); + + COfficeUtils oCOfficeUtils(NULL); + if (oCOfficeUtils.IsArchive(pOleObjectFile->m_Data.data(), pOleObjectFile->m_Data.size())) + {//gzip + ULONG nBytesUncompress = (std::max)((_UINT32)pOleObjectFile->m_Data.size() * 10, ((_UINT32*)pOleObjectFile->m_Data.data())[0]); + BYTE* pDataUncompress = new BYTE[nBytesUncompress]; + + if (S_OK == oCOfficeUtils.Uncompress(pDataUncompress, &nBytesUncompress, pOleObjectFile->m_Data.data() + 4, pOleObjectFile->m_Data.size() - 4)) + { + pOleObjectFile->m_Data.resize(nBytesUncompress); + memcpy(pOleObjectFile->m_Data.data(), pDataUncompress, nBytesUncompress); + delete[]pDataUncompress; + } + } + + NSCommon::smart_ptr file = pOleObjectFile.smart_dynamic_cast(); + m_mapOleData[*it] = file; + } + + } + void CDocxFlat::ParsingSuppData() + { + if (false == m_oDocSuppData.IsInit()) return; + if (false == m_oDocSuppData->m_oBinData.IsInit()) return; + + std::vector pData = m_oDocSuppData->m_oBinData->GetBytes(); + //COfficeUtils oCOfficeUtils(NULL); + + + } } diff --git a/OOXML/DocxFormat/DocxFlat.h b/OOXML/DocxFormat/DocxFlat.h index aaa04e5bc73..2bc52d14cfb 100644 --- a/OOXML/DocxFormat/DocxFlat.h +++ b/OOXML/DocxFormat/DocxFlat.h @@ -52,12 +52,12 @@ namespace OOX namespace Logic { class CBgPict; + class CDocSuppData; } class CDocxFlat : public Document, public File, public WritingElement { public: - CDocxFlat(); CDocxFlat(const CPath& oFilePath); virtual ~CDocxFlat(); @@ -89,6 +89,8 @@ namespace OOX nullable m_pNumbering; nullable m_pSettings; nullable m_pBgPict; + nullable m_oDocSuppData; + nullable m_oDocOleData; nullable m_pComments; nullable m_pFootnotes; @@ -96,9 +98,15 @@ namespace OOX nullable m_pApp; nullable m_pCore; //----------------------------------------------------------- + nullable_string m_sCompatibilityMode; + std::map> m_mapImages; + std::map> m_mapOleData; OOX::IFileContainer *m_currentContainer = NULL; + private: + void ParsingOleData(); + void ParsingSuppData(); }; diff --git a/OOXML/DocxFormat/Drawing/DrawingExt.cpp b/OOXML/DocxFormat/Drawing/DrawingExt.cpp index 6f1bb4d323a..ccbeff71854 100644 --- a/OOXML/DocxFormat/Drawing/DrawingExt.cpp +++ b/OOXML/DocxFormat/Drawing/DrawingExt.cpp @@ -46,6 +46,9 @@ #include "../../XlsxFormat/Styles/dxf.h" #include "../../XlsxFormat/Chart/ChartSerialize.h" #include "../../XlsxFormat/Worksheets/WorksheetChildOther.h" +#include "../../XlsxFormat/Timelines/Timeline.h" +#include "../../XlsxFormat/Workbook/Metadata.h" +#include "../../XlsxFormat/Workbook/Workbook.h" #include "../Comments.h" @@ -67,6 +70,10 @@ #include "../../XlsbFormat/Biff12_unions/TABLESLICERSEX.h" #include "../../XlsbFormat/Biff12_unions/FRTWORKBOOK.h" #include "../../XlsbFormat/Biff12_unions/FRTPIVOTCACHEDEF.h" +#include "../../XlsbFormat/Biff12_unions/FMD.h" +#include "../../XlsbFormat/Biff12_unions/DYNAMICARRAYMETADATA.h" +#include "../../XlsbFormat/Biff12_unions/RICHDATAMETADATA.h" +#include "../../XlsbFormat/Biff12_records/FRTBegin.h" namespace OOX { @@ -167,6 +174,8 @@ namespace OOX m_oUserProtectedRanges.reset(); m_oChartDataLabel.reset(); m_oChartFiltering.reset(); + m_oTimelineRefs.reset(); + m_oTimelineCacheRefs.reset(); for (size_t nIndex = 0; nIndex < m_arrConditionalFormatting.size(); ++nIndex) { @@ -218,7 +227,13 @@ namespace OOX *m_sUri == L"{231B7EB2-2AFC-4442-B178-5FFDF5851E7C}" || *m_sUri == L"{FCE6A71B-6B00-49CD-AB44-F6B1AE7CDE65}" || *m_sUri == L"{56B9EC1D-385E-4148-901F-78D8002777C0}" || - *m_sUri == L"http://schemas.microsoft.com/office/drawing/2008/diagram")) + *m_sUri == L"{7E03D99C-DC04-49d9-9315-930204A7B6E9}" || + *m_sUri == L"{D0CA8CA8-9F24-4464-BF8E-62219DCF47F9}" || + *m_sUri == L"{9260A510-F301-46a8-8635-F512D64BE5F5}" || + *m_sUri == L"{3e2802c4-a4d2-4d8b-9148-e3be6c30e623}" || + *m_sUri == L"{bdbb8cdc-fa1e-496e-a857-3c3f30c029c3}" || + *m_sUri == L"{876F7934-8845-4945-9796-88D515C7AA90}" || + *m_sUri == L"http://schemas.microsoft.com/office/drawing/2008/diagram")) { int nCurDepth = oReader.GetDepth(); while (oReader.ReadNextSiblingNode(nCurDepth)) @@ -258,6 +273,18 @@ namespace OOX { m_oConnection = oReader; } + else if (sName == L"timelineRefs") + { + m_oTimelineRefs = oReader; + } + else if (sName == L"timelineCacheRefs") + { + m_oTimelineCacheRefs = oReader; + } + else if (sName == L"timelineStyles") + { + m_oTimelineStyles = oReader; + } else if (sName == L"slicerList") { if (L"{A8765BA9-456A-4dab-B4F3-ACF838C121DE}" == *m_sUri) @@ -337,6 +364,7 @@ namespace OOX } else if ((sName == L"dataDisplayOptions16") && (false == oReader.IsEmptyNode())) { + m_sAdditionalNamespace = L"xmlns:c16r3=\"http://schemas.microsoft.com/office/drawing/2017/03/chart\""; int nCurDepth1 = oReader.GetDepth(); while (oReader.ReadNextSiblingNode(nCurDepth1)) { @@ -349,6 +377,19 @@ namespace OOX } } } + else if (sName == L"dynamicArrayProperties") + { + m_oDynamicArrayProperties = oReader; + } + else if (sName == L"rvb") + { + m_oRichValueBlock = oReader; + } + else if (sName == L"pivotCaches") + { + m_oWorkbookPivotCaches = oReader; + m_oWorkbookPivotCaches->pivotCaches14 = true; + } } } else @@ -406,8 +447,26 @@ namespace OOX { NSStringUtils::CStringBuilder writer; m_oSparklineGroups->toXML(writer); + sResult += writer.GetData().c_str(); + } + if (m_oTimelineRefs.IsInit()) + { + NSStringUtils::CStringBuilder writer; + m_oTimelineRefs->toXML(writer); sResult += writer.GetData().c_str(); } + if (m_oTimelineCacheRefs.IsInit()) + { + NSStringUtils::CStringBuilder writer; + m_oTimelineCacheRefs->toXML(writer); + sResult += writer.GetData().c_str(); + } + if (m_oTimelineStyles.IsInit()) + { + NSStringUtils::CStringBuilder writer; + m_oTimelineStyles->toXML(writer); + sResult += writer.GetData().c_str(); + } if (m_oAltTextTable.IsInit()) { NSStringUtils::CStringBuilder writer; @@ -549,11 +608,28 @@ namespace OOX writer.StartNode(L"c16r3:dispNaAsBlank"); writer.StartAttributes(); writer.WriteAttribute(L"val", *m_oDataDisplayNaAsBlank); - writer.EndAttributes(); - writer.EndNode(L"c16r3:dispNaAsBlank"); + writer.EndAttributesAndNode(); writer.EndNode(L"c16r3:dataDisplayOptions16"); sResult += writer.GetData().c_str(); } + if (m_oDynamicArrayProperties.IsInit()) + { + NSStringUtils::CStringBuilder writer; + m_oDynamicArrayProperties->toXML(writer); + sResult += writer.GetData().c_str(); + } + if (m_oRichValueBlock.IsInit()) + { + NSStringUtils::CStringBuilder writer; + m_oRichValueBlock->toXML(writer); + sResult += writer.GetData().c_str(); + } + if(m_oWorkbookPivotCaches.IsInit()) + { + NSStringUtils::CStringBuilder writer; + m_oWorkbookPivotCaches->toXML(writer); + sResult += writer.GetData().c_str(); + } sResult += L""; return sResult; @@ -645,6 +721,241 @@ namespace OOX return sResult; } + XLS::BaseObjectPtr COfficeArtExtensionList::toBinConnections() + { + auto ptr(new XLSB::FRTEXTCONNECTIONS); + for(auto i:m_arrExt) + { + if(i->m_sUri == L"{DE250136-89BD-433C-8126-D09CA5730AF9}") + { + ptr->m_EXTCONN15 = i->m_oConnection->toBin15(); + } + } + return XLS::BaseObjectPtr{ptr}; + } + XLS::BaseObjectPtr COfficeArtExtensionList::toBinWorkBook() + { + auto ptr(new XLSB::FRTWORKBOOK); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_arrExt.empty()) + return objectPtr; + for(auto i:m_arrExt) + { + + if(i->m_sUri == L"{46BE6895-7355-4a93-B00E-2C351335B9C9}") + { + ptr->m_TABLESLICERCACHEIDS = i->m_oSlicerCachesExt->toBinTable(); + } + else if(i->m_sUri == L"{BBE1A952-AA13-448e-AADC-164F8A28A991}") + { + ptr->m_SLICERCACHEIDS = i->m_oSlicerCaches->toBin(); + } + else if(i->m_sUri == L"{876F7934-8845-4945-9796-88D515C7AA90}") + { + if(i->m_oWorkbookPivotCaches.IsInit()) + ptr->m_SLICERCACHESPIVOTCACHEIDS = i->m_oWorkbookPivotCaches->toBin14(); + } + + } + return objectPtr; + } + XLS::BaseObjectPtr COfficeArtExtensionList::toBinStyles() + { + auto ptr(new XLSB::FRTSTYLESHEET); + XLS::BaseObjectPtr objectPtr(ptr); + + if (!m_arrExt.empty()) + { + + for(auto i:m_arrExt) + { + + if(i->m_sUri == L"{EB79DEF2-80B8-43e5-95BD-54CBDDF9020C}") + { + ptr->m_STYLESHEET14 = i->m_oSlicerStyles->toBin(); + } + else if(i->m_sUri == L"{46F421CA-312F-682F-3DD2-61675219B42D}") + { + ptr->m_DXF14S = i->m_oDxfs->toBin(); + } + } + + } + return objectPtr; + } + XLS::BaseObjectPtr COfficeArtExtensionList::toBinPivotCache() + { + auto ptr(new XLSB::FRTPIVOTCACHEDEF); + + auto ptr1(new XLSB::FRTBegin); + XLSB::FRTProductVersion version; + version.product = 0; + version.version = 0x0F03; + ptr1->productVersion = version; + ptr->m_BrtFRTBegin = XLS::BaseObjectPtr{ptr1}; + + XLS::BaseObjectPtr objectPtr(ptr); + + if (!m_arrExt.empty()) + { + for(auto i:m_arrExt) + { + + if(i->m_sUri == L"{725AE2AE-9491-48be-B2B4-4EB974FC3084}") + { + ptr->m_PCD14 = i->m_oPivotCacheDefinitionExt->toBin(); + } + + } + } + return objectPtr; + } + XLS::BaseObjectPtr COfficeArtExtensionList::toBinSlicerCache() + { + auto ptr(new XLSB::FRTSLICERCACHE); + XLS::BaseObjectPtr objectPtr(ptr); + if (!m_arrExt.empty()) + { + for(auto i:m_arrExt) + { + if(i->m_sUri == L"{03082B11-2C62-411c-B77F-237D8FCFBE4C}") + { + auto ptr1(new XLSB::SLICERCACHEBOOKPIVOTTABLES); + ptr->m_SLICERCACHEBOOKPIVOTTABLES = XLS::BaseObjectPtr{ptr1}; + auto ptr2(new XLSB::SlicerCacheBookPivotTables); + ptr1->m_BrtSlicerCacheBookPivotTables = XLS::BaseObjectPtr{ptr2}; + + auto ptr3(new XLSB::FRTBegin); + ptr1->m_BrtFRTBegin = XLS::BaseObjectPtr{ptr3}; + XLSB::FRTProductVersion version; + version.product = 0; + version.version = 0x0F03; + ptr3->productVersion = version; + + + + for(auto j:i->m_oSlicerCachePivotTables) + { + XLSB::SlicerCachePivotTable table; + j->toBin(&table); + ptr2->pivotTables.push_back(table); + } + } + if(i->m_sUri == L"{2F2917AC-EB37-4324-AD4E-5DD8C200BD13}") + { + auto ptr1(new XLSB::TABLESLICERCACHE); + + auto ptr2(new XLSB::FRTBegin); + ptr1->m_BrtFRTBegin = XLS::BaseObjectPtr{ptr2}; + XLSB::FRTProductVersion version; + version.product = 0; + version.version = 0x0F03; + ptr2->productVersion = version; + + ptr->m_TABLESLICERCACHE = XLS::BaseObjectPtr{ptr1}; + ptr1->m_BrtBeginTableSlicerCache = i->m_oTableSlicerCache->toBin(); + } + if(i->m_sUri == L"{470722E0-AACD-4C17-9CDC-17EF765DBC7E}") + { + auto ptr1(new XLSB::SLICERCACHECROSSFILTEREXT); + + auto ptr2(new XLSB::FRTBegin); + ptr1->m_BrtFRTBegin = XLS::BaseObjectPtr{ptr2}; + XLSB::FRTProductVersion version; + version.product = 0; + version.version = 0; + ptr2->productVersion = version; + + ptr->m_SLICERCACHECROSSFILTEREXT = XLS::BaseObjectPtr{ptr1}; + ptr1->m_BrtSlicerCacheHideItemsWithNoData = i->m_oSlicerCacheHideItemsWithNoData->toBin(); + } + } + } + return objectPtr; + } + XLS::BaseObjectPtr COfficeArtExtensionList::toBinTable() + { + auto ptr(new XLSB::FRTTABLE); + XLS::BaseObjectPtr objectPtr(ptr); + auto frtBegin(new XLSB::FRTBegin); + ptr->m_BrtFRTBegin = XLS::BaseObjectPtr{frtBegin}; + if (!m_arrExt.empty()) + { + for(auto i:m_arrExt) + { + + if(i->m_sUri == L"{504A1905-F514-4f6f-8877-14C23A59335A}") + { + ptr->m_BrtList14 = i->m_oAltTextTable->toBin(); + } + + } + } + return objectPtr; + } + XLS::BaseObjectPtr COfficeArtExtensionList::toBinWorksheet() + { + auto ptr(new XLSB::FRTWORKSHEET); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_arrExt.empty()) + return objectPtr; + for(auto i:m_arrExt) + { + if(i->m_sUri == L"{78C0D931-6437-407d-A8EE-F0AAD7539E65}") + { + auto formatPtr(new XLSB::CONDITIONALFORMATTINGS); + ptr->m_CONDITIONALFORMATTINGS = XLS::BaseObjectPtr{formatPtr}; + for(auto j:i->m_arrConditionalFormatting) + { + formatPtr->m_arCONDITIONALFORMATTING14.push_back(j->toBin14()); + } + } + else if(i->m_sUri == L"{CCE6A557-97BC-4B89-ADB6-D9C93CAAB3DF}") + { + ptr->m_DVALS14 = i->m_oDataValidations->toBin(); + } + else if(i->m_sUri == L"{05C60535-1F16-4fd2-B633-F4F36F0B64E0}") + { + ptr->m_SPARKLINEGROUPS = i->m_oSparklineGroups->toBin(); + } + else if(i->m_sUri == L"{A8765BA9-456A-4dab-B4F3-ACF838C121DE}") + { + ptr->m_SLICERSEX = i->m_oSlicerList->toBin(); + } + else if(i->m_sUri == L"{3A4CF648-6AED-40f4-86FF-DC5316D8AED3}") + { + if(i->m_oSlicerListExt.IsInit()) + ptr->m_TABLESLICERSEX = i->m_oSlicerListExt->toBinTable(); + } + } + return objectPtr; + } + XLS::BaseObjectPtr COfficeArtExtensionList::toBinMetadata() + { + XLS::BaseObjectPtr objectPtr; + if(m_arrExt.empty()) + return objectPtr; + for(auto i:m_arrExt) + { + if(i->m_sUri == L"{bdbb8cdc-fa1e-496e-a857-3c3f30c029c3}") + { + auto ptr(new XLSB::FMD); + objectPtr = XLS::BaseObjectPtr(ptr); + auto ptr1(new XLSB::DYNAMICARRAYMETADATA); + ptr->m_DYNAMICARRAYMETADATA = XLS::BaseObjectPtr{ptr1}; + ptr1->m_EndDynamicArrayPr = i->m_oDynamicArrayProperties->toBin(); + } + else if(i->m_sUri == L"{3E2802C4-A4D2-4D8B-9148-E3BE6C30E623}" + || i->m_sUri == L"{3e2802c4-a4d2-4d8b-9148-e3be6c30e623}") + { + auto ptr(new XLSB::FMD); + objectPtr = XLS::BaseObjectPtr(ptr); + auto ptr1(new XLSB::RICHDATAMETADATA); + ptr1->m_BeginRichValueBlock = i->m_oRichValueBlock->toBin(); + } + } + return objectPtr; + } void COfficeArtExtensionList::fromBin(XLS::BaseObjectPtr& obj) { if (obj->get_type() == XLS::typeFRTWORKBOOK) @@ -658,6 +969,7 @@ namespace OOX OOX::Drawing::COfficeArtExtension *oExt = new OOX::Drawing::COfficeArtExtension(); oExt->m_sUri = L"{46BE6895-7355-4a93-B00E-2C351335B9C9}"; oExt->m_oSlicerCachesExt = ptr->m_TABLESLICERCACHEIDS; + oExt->m_sAdditionalNamespace = L"xmlns:x15=\"http://schemas.microsoft.com/office/spreadsheetml/2010/11/main\""; if (oExt) m_arrExt.push_back( oExt ); @@ -672,6 +984,19 @@ namespace OOX if (oExt) m_arrExt.push_back( oExt ); } + + if (ptr->m_SLICERCACHESPIVOTCACHEIDS != nullptr) + { + + OOX::Drawing::COfficeArtExtension *oExt = new OOX::Drawing::COfficeArtExtension(); + oExt->m_sUri = L"{876F7934-8845-4945-9796-88D515C7AA90}"; + oExt->m_sAdditionalNamespace = L"xmlns:x14=\"http://schemas.microsoft.com/office/spreadsheetml/2009/9/main\""; + oExt->m_oWorkbookPivotCaches.Init(); + oExt->m_oWorkbookPivotCaches->pivotCaches14 = true; + oExt->m_oWorkbookPivotCaches->fromBin14(ptr->m_SLICERCACHESPIVOTCACHEIDS); + if (oExt) + m_arrExt.push_back( oExt ); + } } } @@ -776,6 +1101,7 @@ namespace OOX { OOX::Drawing::COfficeArtExtension *oExt = new OOX::Drawing::COfficeArtExtension(); oExt->m_sUri = L"{504A1905-F514-4f6f-8877-14C23A59335A}"; + oExt->m_sAdditionalNamespace = L"xmlns:x14=\"http://schemas.microsoft.com/office/spreadsheetml/2009/9/main\""; oExt->m_oAltTextTable = ptr->m_BrtList14; if (oExt) @@ -893,6 +1219,32 @@ namespace OOX m_arrExt.push_back( oExt ); } } + } + else if (obj->get_type() == XLS::typeFMD) + { + auto ptr = static_cast(obj.get()); + + if (ptr != nullptr) + { + if (ptr->m_DYNAMICARRAYMETADATA != nullptr) + { + OOX::Drawing::COfficeArtExtension *oExt = new OOX::Drawing::COfficeArtExtension(); + oExt->m_sUri = L"{bdbb8cdc-fa1e-496e-a857-3c3f30c029c3}"; + oExt->m_sAdditionalNamespace = L"xmlns:xda=\"http://schemas.microsoft.com/office/spreadsheetml/2017/dynamicarray\""; + oExt->m_oDynamicArrayProperties = ptr->m_DYNAMICARRAYMETADATA; + if (oExt) + m_arrExt.push_back( oExt ); + } + else if(ptr->m_RICHDATAMETADATA != nullptr) + { + OOX::Drawing::COfficeArtExtension *oExt = new OOX::Drawing::COfficeArtExtension(); + oExt->m_sUri = L"{3E2802C4-A4D2-4D8B-9148-E3BE6C30E623}"; + oExt->m_sAdditionalNamespace = L"xmlns:xlrd=\"http://schemas.microsoft.com/office/spreadsheetml/2017/richdata\""; + oExt->m_oRichValueBlock = ptr->m_RICHDATAMETADATA; + if (oExt) + m_arrExt.push_back( oExt ); + } + } } } EElementType COfficeArtExtensionList::getType() const diff --git a/OOXML/DocxFormat/Drawing/DrawingExt.h b/OOXML/DocxFormat/Drawing/DrawingExt.h index 09d95883353..1d98eee14b7 100644 --- a/OOXML/DocxFormat/Drawing/DrawingExt.h +++ b/OOXML/DocxFormat/Drawing/DrawingExt.h @@ -57,6 +57,12 @@ namespace OOX class CT_DLbl; class CSeriesFiltering; class CUserProtectedRanges; + class CTimelineRefs; + class CTimelineCacheRefs; + class CTimelineStyles; + class CDynamicArrayProperties; + class CRichValueBlock; + class CWorkbookPivotCaches; } namespace Drawing @@ -105,7 +111,7 @@ namespace OOX //-------------------------------------------------------------------------------- // COfficeArtExtension 20.1.2.2.14 (Part 1) - //-------------------------------------------------------------------------------- + //-------------------------------------------------------------------------------- class COfficeArtExtension : public WritingElement { @@ -145,14 +151,22 @@ namespace OOX nullable m_oSlicerCachesExt; nullable m_oSlicerStyles; + nullable m_oTimelineRefs; + nullable m_oTimelineCacheRefs; + nullable m_oTimelineStyles; + nullable m_oPivotCacheDefinitionExt; + nullable m_oWorkbookPivotCaches; std::vector m_oSlicerCachePivotTables; nullable m_oTableSlicerCache; nullable m_oSlicerCacheHideItemsWithNoData; - + std::vector m_arrConditionalFormatting; + nullable < OOX::Spreadsheet::CDynamicArrayProperties> m_oDynamicArrayProperties; + nullable < OOX::Spreadsheet::CRichValueBlock> m_oRichValueBlock; + nullable m_oPresenceInfo; nullable_string m_oFileKey; @@ -169,7 +183,7 @@ namespace OOX //-------------------------------------------------------------------------------- // COfficeArtExtensionList 20.1.2.2.15 (Part 1) - //-------------------------------------------------------------------------------- + //-------------------------------------------------------------------------------- class COfficeArtExtensionList : public WritingElement { @@ -187,6 +201,14 @@ namespace OOX virtual std::wstring toXML() const; std::wstring toXMLWithNS(const std::wstring& sNamespace) const; void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBinWorksheet(); + XLS::BaseObjectPtr toBinWorkBook(); + XLS::BaseObjectPtr toBinStyles(); + XLS::BaseObjectPtr toBinTable(); + XLS::BaseObjectPtr toBinSlicerCache(); + XLS::BaseObjectPtr toBinPivotCache(); + XLS::BaseObjectPtr toBinConnections(); + XLS::BaseObjectPtr toBinMetadata(); virtual EElementType getType() const; std::vector m_arrExt; diff --git a/OOXML/DocxFormat/FileTypes.cpp b/OOXML/DocxFormat/FileTypes.cpp index 6edef1f6614..103b3fc628b 100644 --- a/OOXML/DocxFormat/FileTypes.cpp +++ b/OOXML/DocxFormat/FileTypes.cpp @@ -167,23 +167,23 @@ namespace OOX const FileType Image (L"media", L"image", L"", - L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image", L"image", true); + L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image", L"image", true, true); const FileType Audio (L"media", L"audio", L"", - L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/audio", L"audio", true); + L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/audio", L"audio", true, true); const FileType Video (L"media", L"video", L"", - L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/video", L"video", true); + L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/video", L"video", true, true); const FileType Media (L"media", L"media", L"", - L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/media", L"media", true); + L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/media", L"media", true, true); const FileType SvgBlip (L"media", L"image", L"", - L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image", L"image", true); + L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image", L"image", true, true); const FileType DiagramData (L"diagrams", L"data.xml", @@ -279,7 +279,7 @@ namespace OOX const FileType MicrosoftOfficeUnknown(L"embeddings", L"", L"", - L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/package"); + L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/package", L"embeddings/package", true, true); const FileType MicrosoftOfficeExcelWorksheet(L"embeddings", L"Microsoft_Office_Excel_Worksheet.xlsx", L"", @@ -346,7 +346,7 @@ namespace OOX const FileType OleObject (L"embeddings", L"oleObject.bin", L"", - L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/oleObject"); + L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/oleObject", L"embeddings/oleObject", true, true); const FileType VmlDrawing (L"drawings", L"vmlDrawing.vml", L"application/vnd.openxmlformats-officedocument.vmlDrawing", diff --git a/OOXML/DocxFormat/HeaderFooter.cpp b/OOXML/DocxFormat/HeaderFooter.cpp index cb2ceb77025..7d255f08248 100644 --- a/OOXML/DocxFormat/HeaderFooter.cpp +++ b/OOXML/DocxFormat/HeaderFooter.cpp @@ -91,139 +91,176 @@ namespace OOX } void CHdrFtr::fromXML(XmlUtils::CXmlLiteReader& oReader) { - std::wstring sName = oReader.GetName(); + std::wstring sName = XmlUtils::GetNameNoNS(oReader.GetName()); - if ( _T("w:ftr") == sName ) + if (L"ftr" == sName) m_eType = et_w_ftr; - else if ( _T("w:hdr") == sName ) + else if (L"hdr" == sName) m_eType = et_w_hdr; else return; - OOX::Document* document = WritingElement::m_pMainDocument; - ReadAttributes(oReader); - if ( !oReader.IsEmptyNode() ) - { - int nDocumentDepth = oReader.GetDepth(); - while ( oReader.ReadNextSiblingNode( nDocumentDepth ) ) - { - std::wstring sName = oReader.GetName(); - WritingElement *pItem = NULL; + if (oReader.IsEmptyNode()) + return; - if ( _T("w:altChunk") == sName ) - pItem = new Logic::CAltChunk( document ); - else if ( _T("w:bookmarkEnd") == sName ) - pItem = new Logic::CBookmarkEnd( document ); - else if ( _T("w:bookmarkStart") == sName ) - pItem = new Logic::CBookmarkStart( document ); - else if ( _T("w:commentRangeEnd") == sName ) - pItem = new Logic::CCommentRangeEnd( document ); - else if ( _T("w:commentRangeStart") == sName ) - pItem = new Logic::CCommentRangeStart( document ); - //else if ( _T("w:customXml") == sName ) - // pItem = new Logic::CCustomXml( document ); - else if ( _T("w:customXmlDelRangeEnd") == sName ) - pItem = new Logic::CCustomXmlDelRangeEnd( document ); - else if ( _T("w:customXmlDelRangeStart") == sName ) - pItem = new Logic::CCustomXmlDelRangeStart( document ); - else if ( _T("w:customXmlInsRangeEnd") == sName ) - pItem = new Logic::CCustomXmlInsRangeEnd( document ); - else if ( _T("w:customXmlInsRangeStart") == sName ) - pItem = new Logic::CCustomXmlInsRangeStart( document ); - else if ( _T("w:customXmlMoveFromRangeEnd") == sName ) - pItem = new Logic::CCustomXmlMoveFromRangeEnd( document ); - else if ( _T("w:customXmlMoveFromRangeStart") == sName ) - pItem = new Logic::CCustomXmlMoveFromRangeStart( document ); - else if ( _T("w:customXmlMoveToRangeEnd") == sName ) - pItem = new Logic::CCustomXmlMoveToRangeEnd( document ); - else if ( _T("w:customXmlMoveToRangeStart") == sName ) - pItem = new Logic::CCustomXmlMoveToRangeStart( document ); - else if ( _T("w:del") == sName ) - pItem = new Logic::CDel( document ); - else if ( _T("w:ins") == sName ) - pItem = new Logic::CIns( document ); - else if ( _T("w:moveFrom") == sName ) - pItem = new Logic::CMoveFrom( document ); - else if ( _T("w:moveFromRangeEnd") == sName ) - pItem = new Logic::CMoveFromRangeEnd( document ); - else if ( _T("w:moveFromRangeStart") == sName ) - pItem = new Logic::CMoveFromRangeStart( document ); - else if ( _T("w:moveTo") == sName ) - pItem = new Logic::CMoveTo( document ); - else if ( _T("w:moveToRangeEnd") == sName ) - pItem = new Logic::CMoveToRangeEnd( document ); - else if ( _T("w:moveToRangeStart") == sName ) - pItem = new Logic::CMoveToRangeStart( document ); - else if ( _T("m:oMath") == sName ) - pItem = new Logic::COMath( document ); - else if ( _T("m:oMathPara") == sName ) - pItem = new Logic::COMathPara( document ); - else if ( _T("w:p") == sName ) - pItem = new Logic::CParagraph( document, this ); - else if ( _T("w:permEnd") == sName ) - pItem = new Logic::CPermEnd( document ); - else if ( _T("w:permStart") == sName ) - pItem = new Logic::CPermStart( document ); - else if ( _T("w:proofErr") == sName ) - pItem = new Logic::CProofErr( document ); - else if ( _T("w:sdt") == sName ) - pItem = new Logic::CSdt( document ); - else if ( _T("w:tbl") == sName ) - pItem = new Logic::CTbl( document ); + int nHdrFtrDepth = oReader.GetDepth(); + CreateElements(oReader, nHdrFtrDepth); + } + void CHdrFtr::CreateElements(XmlUtils::CXmlLiteReader& oReader, int Depth) + { + OOX::Document* document = WritingElement::m_pMainDocument; + + while (oReader.ReadNextSiblingNode(Depth)) + { + std::wstring sName = XmlUtils::GetNameNoNS(oReader.GetName()); + WritingElement* pItem = NULL; - if ( pItem ) - { - pItem->fromXML(oReader); - m_arrItems.push_back( pItem ); - } + if (L"altChunk" == sName) + pItem = new Logic::CAltChunk(document); + else if (L"bookmarkEnd" == sName) + pItem = new Logic::CBookmarkEnd(document); + else if (L"bookmarkStart" == sName) + pItem = new Logic::CBookmarkStart(document); + else if (L"commentRangeEnd" == sName) + pItem = new Logic::CCommentRangeEnd(document); + else if (L"commentRangeStart" == sName) + pItem = new Logic::CCommentRangeStart(document); + //else if ( L"customXml") == sName ) + // pItem = new Logic::CCustomXml( document ); + else if (L"customXmlDelRangeEnd" == sName) + pItem = new Logic::CCustomXmlDelRangeEnd(document); + else if (L"customXmlDelRangeStart" == sName) + pItem = new Logic::CCustomXmlDelRangeStart(document); + else if (L"customXmlInsRangeEnd" == sName) + pItem = new Logic::CCustomXmlInsRangeEnd(document); + else if (L"customXmlInsRangeStart" == sName) + pItem = new Logic::CCustomXmlInsRangeStart(document); + else if (L"customXmlMoveFromRangeEnd" == sName) + pItem = new Logic::CCustomXmlMoveFromRangeEnd(document); + else if (L"customXmlMoveFromRangeStart" == sName) + pItem = new Logic::CCustomXmlMoveFromRangeStart(document); + else if (L"customXmlMoveToRangeEnd" == sName) + pItem = new Logic::CCustomXmlMoveToRangeEnd(document); + else if (L"customXmlMoveToRangeStart" == sName) + pItem = new Logic::CCustomXmlMoveToRangeStart(document); + else if (L"del" == sName) + pItem = new Logic::CDel(document); + else if (L"ins" == sName) + pItem = new Logic::CIns(document); + else if (L"moveFrom" == sName) + pItem = new Logic::CMoveFrom(document); + else if (L"moveFromRangeEnd" == sName) + pItem = new Logic::CMoveFromRangeEnd(document); + else if (L"moveFromRangeStart" == sName) + pItem = new Logic::CMoveFromRangeStart(document); + else if (L"moveTo" == sName) + pItem = new Logic::CMoveTo(document); + else if (L"moveToRangeEnd" == sName) + pItem = new Logic::CMoveToRangeEnd(document); + else if (L"moveToRangeStart" == sName) + pItem = new Logic::CMoveToRangeStart(document); + else if (L"oMath" == sName) + pItem = new Logic::COMath(document); + else if (L"oMathPara" == sName) + pItem = new Logic::COMathPara(document); + else if (L"p" == sName) + pItem = new Logic::CParagraph(document, this); + else if (L"permEnd" == sName) + pItem = new Logic::CPermEnd(document); + else if (L"permStart" == sName) + pItem = new Logic::CPermStart(document); + else if (L"proofErr" == sName) + pItem = new Logic::CProofErr(document); + else if (L"sdt" == sName) + pItem = new Logic::CSdt(document); + else if (L"tbl" == sName) + pItem = new Logic::CTbl(document); + else if (L"body" == sName && !oReader.IsEmptyNode()) + { + int nWBodyDepth = oReader.GetDepth(); + CreateElements(oReader, nWBodyDepth); + } + else if (L"sect" == sName && !oReader.IsEmptyNode()) + { + int nWxSectDepth = oReader.GetDepth(); + CreateElements(oReader, nWxSectDepth); + } + else if (L"sub-section" == sName && !oReader.IsEmptyNode()) + { + int nWxSubSectDepth = oReader.GetDepth(); + CreateElements(oReader, nWxSubSectDepth); + } + else if (L"pBdrGroup" == sName && !oReader.IsEmptyNode()) + { + int nWxBdrGroupDepth = oReader.GetDepth(); + CreateElements(oReader, nWxBdrGroupDepth); + } + if (pItem) + { + pItem->fromXML(oReader); + m_arrItems.push_back(pItem); } } } std::wstring CHdrFtr::toXML() const { std::wstring sXml; - if ( et_w_ftr == m_eType ) - sXml = _T(""); - - else if ( et_w_hdr == m_eType ) - sXml = _T(""); + } + else if (et_w_hdr == m_eType) + { + sXml = _T(""); - +xmlns:w10=\"urn:schemas-microsoft-com:office:word\" \ +xmlns:wp14=\"http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing\" \ +xmlns:w14=\"http://schemas.microsoft.com/office/word/2010/wordml\" \ +xmlns:w15=\"http://schemas.microsoft.com/office/word/2012/wordml\" \ +xmlns:w16cex=\"http://schemas.microsoft.com/office/word/2018/wordml/cex\" \ +xmlns:w16cid=\"http://schemas.microsoft.com/office/word/2016/wordml/cid\" \ +xmlns:w16=\"http://schemas.microsoft.com/office/word/2018/wordml\" \ +xmlns:w16sdtdh=\"http://schemas.microsoft.com/office/word/2020/wordml/sdtdatahash\" \ +xmlns:w16se=\"http://schemas.microsoft.com/office/word/2015/wordml/symex\" \ +mc:Ignorable=\"w14 w15 w16se w16cid w16 w16cex w16sdtdh wp14\">"); + } else return sXml; @@ -278,10 +315,10 @@ mc:Ignorable=\"w14 w15 wp14\">"); return m_eType; } void CHdrFtr::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) -{ - WritingElement_ReadAttributes_Start( oReader ) - WritingElement_ReadAttributes_ReadSingle( oReader, _T("w:type"), m_oType ) - WritingElement_ReadAttributes_End( oReader ) -} + { + WritingElement_ReadAttributes_Start_No_NS(oReader) + WritingElement_ReadAttributes_ReadSingle(oReader, L"type", m_oType ) + WritingElement_ReadAttributes_End_No_NS(oReader) + } } // namespace OOX diff --git a/OOXML/DocxFormat/HeaderFooter.h b/OOXML/DocxFormat/HeaderFooter.h index ac893eedd78..53991cbcd0b 100644 --- a/OOXML/DocxFormat/HeaderFooter.h +++ b/OOXML/DocxFormat/HeaderFooter.h @@ -63,6 +63,8 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlNode& oNode); virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + void CreateElements(XmlUtils::CXmlLiteReader& oReader, int Depth); + virtual std::wstring toXML() const; virtual void write(const CPath& oFilePath, const CPath& oDirectory, CContentTypes& oContent) const; diff --git a/OOXML/DocxFormat/IFileContainer.cpp b/OOXML/DocxFormat/IFileContainer.cpp index 7e90c57dc6c..342c58e712c 100644 --- a/OOXML/DocxFormat/IFileContainer.cpp +++ b/OOXML/DocxFormat/IFileContainer.cpp @@ -128,7 +128,7 @@ namespace OOX { const OOX::File* pFileOwner = dynamic_cast(this); - for (boost::unordered_map>::const_iterator pPair = m_mapContainer.begin(); pPair != m_mapContainer.end(); ++pPair) + for (std::map>::const_iterator pPair = m_mapContainer.begin(); pPair != m_mapContainer.end(); ++pPair) { smart_ptr pFile = pPair->second; @@ -232,7 +232,7 @@ namespace OOX { std::map mNamepair; - for (boost::unordered_map>::const_iterator pPair = m_mapContainer.begin(); pPair != m_mapContainer.end(); ++pPair) + for (std::map>::const_iterator pPair = m_mapContainer.begin(); pPair != m_mapContainer.end(); ++pPair) { smart_ptr pFile = pPair->second; @@ -283,7 +283,7 @@ namespace OOX const bool IFileContainer::IsExist(const RId& rId) const { - boost::unordered_map>::const_iterator pFind = m_mapContainer.find(rId.get()); + std::map>::const_iterator pFind = m_mapContainer.find(rId.get()); return (pFind != m_mapContainer.end()); } @@ -306,7 +306,7 @@ namespace OOX } const bool IFileContainer::IsExternal(const OOX::RId& rId) const { - boost::unordered_map>::const_iterator pFind = m_mapContainer.find(rId.get()); + std::map>::const_iterator pFind = m_mapContainer.find(rId.get()); if (pFind != m_mapContainer.end()) { @@ -416,7 +416,7 @@ namespace OOX smart_ptr IFileContainer::Find(const OOX::RId& rId) const { - boost::unordered_map>::const_iterator pPair = m_mapContainer.find(rId.get()); + std::map>::const_iterator pPair = m_mapContainer.find(rId.get()); if ( pPair != m_mapContainer.end()) return pPair->second; @@ -426,7 +426,7 @@ namespace OOX smart_ptr IFileContainer::Find(const FileType& oType) const { - for (boost::unordered_map>::const_iterator pPair = m_mapContainer.begin(); pPair != m_mapContainer.end(); ++pPair) + for (std::map>::const_iterator pPair = m_mapContainer.begin(); pPair != m_mapContainer.end(); ++pPair) { if (pPair->second->type() == oType) return pPair->second; @@ -441,7 +441,7 @@ namespace OOX } smart_ptr IFileContainer::operator [](const OOX::RId rId) { - boost::unordered_map>::const_iterator pFind = m_mapContainer.find(rId.get()); + std::map>::const_iterator pFind = m_mapContainer.find(rId.get()); if ( pFind != m_mapContainer.end()) return pFind->second; diff --git a/OOXML/DocxFormat/IFileContainer.h b/OOXML/DocxFormat/IFileContainer.h index cdb8bfcaa48..6d92a3df2b2 100644 --- a/OOXML/DocxFormat/IFileContainer.h +++ b/OOXML/DocxFormat/IFileContainer.h @@ -63,7 +63,7 @@ namespace OOX template smart_ptr Get (const RId& rId) const { - boost::unordered_map>::const_iterator pFind = m_mapContainer.find(rId.get()); + std::map>::const_iterator pFind = m_mapContainer.find(rId.get()); if (pFind == m_mapContainer.end ()) return smart_ptr(); return pFind->second.smart_dynamic_cast(); @@ -98,12 +98,12 @@ namespace OOX const RId GetMaxRId(); protected: - static UnknowTypeFile m_oUnknown; - std::vector> m_arContainer; - boost::unordered_map> m_mapContainer; + static UnknowTypeFile m_oUnknown; + std::vector> m_arContainer; + std::map> m_mapContainer; - boost::unordered_map m_mNoWriteContainer; - unsigned int m_lMaxRid; + boost::unordered_map m_mNoWriteContainer; + unsigned int m_lMaxRid; void Read (const OOX::CRels& oRels, const OOX::CPath& oRootPath, const CPath& oPath); void Write (const OOX::CPath& oFileName, const CPath& oDir, OOX::CContentTypes& oContent) const; diff --git a/OOXML/DocxFormat/Logic/ParagraphProperty.cpp b/OOXML/DocxFormat/Logic/ParagraphProperty.cpp index cc53b9a5a71..5f4d01af359 100644 --- a/OOXML/DocxFormat/Logic/ParagraphProperty.cpp +++ b/OOXML/DocxFormat/Logic/ParagraphProperty.cpp @@ -310,7 +310,7 @@ namespace OOX if ( m_sAuthor.IsInit() ) { sResult += L"w:author=\""; - sResult += m_sAuthor.get2(); + sResult += XmlUtils::EncodeXmlString(m_sAuthor.get2()); sResult += L"\" "; } @@ -654,10 +654,10 @@ namespace OOX doc->m_arrSections.push_back(section); } doc->m_arrSections.back().sect = m_oSectPr.GetPointer(); - doc->m_arrSections.back().end_elm = doc->m_arrItems.size(); + doc->m_arrSections.back().end_elm = doc->m_arrItems.size() + 1; // порядок выше - сначала читаем, потом добавляем OOX::CDocument::_section section; - section.start_elm = doc->m_arrItems.size(); + section.start_elm = doc->m_arrItems.size() + 1; doc->m_arrSections.push_back(section); } //------------------------------------------------------------------------------------ diff --git a/OOXML/DocxFormat/Logic/Pict.cpp b/OOXML/DocxFormat/Logic/Pict.cpp index 6280d493623..11368b18811 100644 --- a/OOXML/DocxFormat/Logic/Pict.cpp +++ b/OOXML/DocxFormat/Logic/Pict.cpp @@ -37,6 +37,7 @@ //#include "Vml.h" #include "VmlOfficeDrawing.h" +#include "../../../OfficeUtils/src/OfficeUtils.h" #include "../../../DesktopEditor/raster/ImageFileFormatChecker.h" #include "../../../OOXML/PPTXFormat/DrawingConverter/ASCOfficeDrawingConverter.h" @@ -104,6 +105,31 @@ namespace OOX oReader.MoveToElement(); } + std::vector CBinData::GetBytes() + { + std::vector result; + if (!m_sData.IsInit()) return result; + + int dstLen = Base64::Base64DecodeGetRequiredLength((int)m_sData->size()); + result.resize(dstLen); + Base64::Base64Decode(m_sData->c_str(), (int)m_sData->size(), result.data(), &dstLen); + result.resize(dstLen); + + //COfficeUtils oCOfficeUtils(NULL); + //if (oCOfficeUtils.IsArchive(result.data(), result.size())) + //{//gzip + // ULONG nBytesUncompress = result.size() * 10; + // BYTE* pDataUncompress = new BYTE[nBytesUncompress]; + // if (S_OK == oCOfficeUtils.Uncompress(pDataUncompress, &nBytesUncompress, result.data(), result.size())) + // { + // result.resize(nBytesUncompress); + // memcpy(result.data(), pDataUncompress, nBytesUncompress); + // delete[]pDataUncompress; + // } + //} + + return result; + } CControl::CControl(OOX::Document *pMain) : WritingElement(pMain) {} CControl::~CControl() {} @@ -206,84 +232,84 @@ namespace OOX switch (wChar2) { case 'b': - if (_T("o:bottom") == sName) + if (L"o:bottom" == sName) pItem = new OOX::VmlOffice::CStrokeChild(m_pMainDocument); break; case 'c': - if (_T("o:callout") == sName) + if (L"o:callout" == sName) pItem = new OOX::VmlOffice::CCallout(m_pMainDocument); - else if (_T("o:clippath") == sName) + else if (L"o:clippath" == sName) pItem = new OOX::VmlOffice::CClipPath(m_pMainDocument); - else if (_T("o:column") == sName) + else if (L"o:column" == sName) pItem = new OOX::VmlOffice::CStrokeChild(m_pMainDocument); - else if (_T("o:complex") == sName) + else if (L"o:complex" == sName) pItem = new OOX::VmlOffice::CComplex(m_pMainDocument); break; case 'd': - if (_T("o:diagram") == sName) + if (L"o:diagram" == sName) pItem = new OOX::VmlOffice::CDiagram(m_pMainDocument); break; case 'e': - if (_T("o:equationxml") == sName) + if (L"o:equationxml" == sName) pItem = new OOX::VmlOffice::CEquationXml(m_pMainDocument); - else if (_T("o:extrusion") == sName) + else if (L"o:extrusion" == sName) pItem = new OOX::VmlOffice::CExtrusion(m_pMainDocument); break; case 'f': - if (_T("o:fill") == sName) + if (L"o:fill" == sName) pItem = new OOX::VmlOffice::CFill(m_pMainDocument); break; case 'i': - if (_T("o:ink") == sName) + if (L"o:ink" == sName) pItem = new OOX::VmlOffice::CInk(m_pMainDocument); break; case 'l': - if (_T("o:left") == sName) + if (L"o:left" == sName) pItem = new OOX::VmlOffice::CStrokeChild(m_pMainDocument); - else if (_T("o:lock") == sName) + else if (L"o:lock" == sName) pItem = new OOX::VmlOffice::CLock(m_pMainDocument); break; case 'O': - if (_T("o:OLEObject") == sName) + if (L"o:OLEObject" == sName) { m_oOLEObject = new OOX::VmlOffice::COLEObject(m_pMainDocument); m_oOLEObject->fromXML(oSubReader); }break; case 'r': - if (_T("o:right") == sName) + if (L"o:right" == sName) pItem = new OOX::VmlOffice::CStrokeChild(m_pMainDocument); break; case 's': - if (_T("o:shapedefaults") == sName) + if (L"o:shapedefaults" == sName) pItem = new OOX::VmlOffice::CShapeDefaults(m_pMainDocument); - else if (_T("o:shapelayout") == sName) + else if (L"o:shapelayout" == sName) pItem = new OOX::VmlOffice::CShapeLayout(m_pMainDocument); - else if (_T("o:signatureline") == sName) + else if (L"o:signatureline" == sName) pItem = new OOX::VmlOffice::CSignatureLine(m_pMainDocument); - else if (_T("o:skew") == sName) + else if (L"o:skew" == sName) pItem = new OOX::VmlOffice::CSkew(m_pMainDocument); break; case 't': - if (_T("o:top") == sName) + if (L"o:top" == sName) pItem = new OOX::VmlOffice::CStrokeChild(m_pMainDocument); break; @@ -298,59 +324,59 @@ namespace OOX switch (wChar2) { case 'a': - if (_T("v:arc") == sName) + if (L"v:arc" == sName) { m_oShapeElement = new OOX::Vml::CArc(m_pMainDocument); m_oShapeElement->fromXML(oSubReader); }break; case 'b': - if (_T("v:background") == sName) + if (L"v:background" == sName) pItem = new OOX::Vml::CBackground(m_pMainDocument); break; case 'c': - if (_T("v:curve") == sName) + if (L"v:curve" == sName) { m_oShapeElement = new OOX::Vml::CCurve(m_pMainDocument);//??? m_oShapeElement->fromXML(oSubReader); }break; case 'f': - if (_T("v:fill") == sName) + if (L"v:fill" == sName) pItem = new OOX::Vml::CFill(m_pMainDocument); - else if (_T("v:formulas") == sName) + else if (L"v:formulas" == sName) pItem = new OOX::Vml::CFormulas(m_pMainDocument); break; case 'g': - if (_T("v:group") == sName) + if (L"v:group" == sName) { m_oShapeElement = new OOX::Vml::CGroup(m_pMainDocument); m_oShapeElement->fromXML(oSubReader); }break; case 'h': - if (_T("v:handles") == sName) + if (L"v:handles" == sName) pItem = new OOX::Vml::CHandles(m_pMainDocument); break; case 'i': - if (_T("v:image") == sName) + if (L"v:image" == sName) { m_oShapeElement = new OOX::Vml::CImage(m_pMainDocument); m_oShapeElement->fromXML(oSubReader); } - else if (_T("v:imagedata") == sName) + else if (L"v:imagedata" == sName) { pItem = pImageData = new OOX::Vml::CImageData(m_pMainDocument); } break; case 'l': - if (_T("v:line") == sName) + if (L"v:line" == sName) { m_oShapeElement = new OOX::Vml::CLine(m_pMainDocument); m_oShapeElement->fromXML(oSubReader); @@ -358,7 +384,7 @@ namespace OOX break; case 'o': - if (_T("v:oval") == sName) + if (L"v:oval" == sName) { m_oShapeElement = new OOX::Vml::COval(m_pMainDocument); m_oShapeElement->fromXML(oSubReader); @@ -366,9 +392,9 @@ namespace OOX break; case 'p': - if (_T("v:path") == sName) + if (L"v:path" == sName) pItem = new OOX::Vml::CPath(m_pMainDocument); - else if (_T("v:polyline") == sName) + else if (L"v:polyline" == sName) { m_oShapeElement = new OOX::Vml::CPolyLine(m_pMainDocument); m_oShapeElement->fromXML(oSubReader); @@ -377,12 +403,12 @@ namespace OOX break; case 'r': - if (_T("v:rect") == sName) + if (L"v:rect" == sName) { m_oShapeElement = new OOX::Vml::CRect(m_pMainDocument); m_oShapeElement->fromXML(oSubReader); } - else if (_T("v:roundrect") == sName) + else if (L"v:roundrect" == sName) { m_oShapeElement = new OOX::Vml::CRoundRect(m_pMainDocument); m_oShapeElement->fromXML(oSubReader); @@ -390,27 +416,27 @@ namespace OOX break; case 's': - if (_T("v:shadow") == sName) + if (L"v:shadow" == sName) pItem = new OOX::Vml::CShadow(m_pMainDocument); - else if (_T("v:shape") == sName) + else if (L"v:shape" == sName) { m_oShapeElement = new OOX::Vml::CShape(m_pMainDocument); m_oShapeElement->fromXML(oSubReader); } - else if (_T("v:shapetype") == sName) + else if (L"v:shapetype" == sName) { m_oShapeType = new OOX::Vml::CShapeType(m_pMainDocument); m_oShapeType->fromXML(oSubReader); } - else if (_T("v:stroke") == sName) + else if (L"v:stroke" == sName) pItem = new OOX::Vml::CStroke(m_pMainDocument); break; case 't': - if (_T("v:textbox") == sName) + if (L"v:textbox" == sName) pItem = new OOX::Vml::CTextbox(m_pMainDocument); - else if (_T("v:textpath") == sName) + else if (L"v:textpath" == sName) pItem = new OOX::Vml::CTextPath(m_pMainDocument); break; @@ -434,19 +460,36 @@ namespace OOX if (docx_flat) { smart_ptr pImageFile = smart_ptr(new OOX::Image(m_pMainDocument, true)); - - int dstLen = Base64::Base64DecodeGetRequiredLength((int)m_oBinData->m_sData->size()); - pImageFile->m_Data.resize(dstLen); - Base64::Base64Decode(m_oBinData->m_sData->c_str(), (int)m_oBinData->m_sData->size(), pImageFile->m_Data.data(), &dstLen); - pImageFile->m_Data.resize(dstLen); + pImageFile->m_Data = m_oBinData->GetBytes(); CImageFileFormatChecker fileChecker; - std::wstring ext = fileChecker.DetectFormatByData(pImageFile->m_Data.data(), dstLen); + std::wstring ext = fileChecker.DetectFormatByData(pImageFile->m_Data.data(), pImageFile->m_Data.size()); + + if (ext.empty()) + { + COfficeUtils oCOfficeUtils(NULL); + if (oCOfficeUtils.IsArchive(pImageFile->m_Data.data(), pImageFile->m_Data.size())) + {//gzip + ULONG nBytesUncompress = pImageFile->m_Data.size() * 10; + BYTE* pDataUncompress = new BYTE[nBytesUncompress]; + if (S_OK == oCOfficeUtils.Uncompress(pDataUncompress, &nBytesUncompress, pImageFile->m_Data.data(), pImageFile->m_Data.size())) + { + ext = fileChecker.DetectFormatByData(pDataUncompress, nBytesUncompress); + + if (false == ext.empty()) + { + pImageFile->m_Data.resize(nBytesUncompress); + memcpy(pImageFile->m_Data.data(), pDataUncompress, nBytesUncompress); + delete []pDataUncompress; + } + } + } + } if (false == ext.empty()) { OOX::CPath filename(L"image." + ext); pImageFile->set_filename(filename, false, true); - + NSCommon::smart_ptr file = pImageFile.smart_dynamic_cast(); const OOX::RId rId = docx_flat->m_currentContainer->Add(file); @@ -458,7 +501,6 @@ namespace OOX } } } - break; } @@ -471,7 +513,7 @@ namespace OOX } std::wstring CPicture::toXML() const { - std::wstring sResult = _T(""); + std::wstring sResult = m_oOLEObject.IsInit() ? L"" : L""; for (size_t i = 0; i < m_arrItems.size(); ++i) { @@ -489,10 +531,12 @@ namespace OOX if (m_oControl.IsInit()) sResult += m_oControl->toXML(); - //if (m_oBinData.IsInit()) - // sResult += m_oBinData->toXML(); + if (m_oOLEObject.IsInit()) + { + sResult += m_oOLEObject->toXML(); + } - sResult += _T(""); + sResult += m_oOLEObject.IsInit() ? L"" : L""; return sResult; } @@ -518,9 +562,24 @@ namespace OOX //альтернатива pptx std::wstring sXml; //??? + ole наверно что то (лень ...) - sXml += _T(""); + sXml += L""; sXml += m_sXml.get(); - sXml += _T(""); + sXml += L""; XmlUtils::CXmlLiteReader oSubReader; oSubReader.FromString(sXml); @@ -545,79 +604,79 @@ namespace OOX switch (wChar2) { case 'b': - if (_T("o:bottom") == sName) + if (L"o:bottom" == sName) AssignPtrXmlContent(pItem, OOX::VmlOffice::CStrokeChild, oSubReader) break; case 'c': - if (_T("o:callout") == sName) + if (L"o:callout" == sName) AssignPtrXmlContent(pItem, OOX::VmlOffice::CCallout, oSubReader) - else if (_T("o:clippath") == sName) + else if (L"o:clippath" == sName) AssignPtrXmlContent(pItem, OOX::VmlOffice::CClipPath, oSubReader) - else if (_T("o:column") == sName) + else if (L"o:column" == sName) AssignPtrXmlContent(pItem, OOX::VmlOffice::CStrokeChild, oSubReader) - else if (_T("o:complex") == sName) + else if (L"o:complex" == sName) AssignPtrXmlContent(pItem, OOX::VmlOffice::CComplex, oSubReader) break; case 'd': - if (_T("o:diagram") == sName) + if (L"o:diagram" == sName) AssignPtrXmlContent(pItem, OOX::VmlOffice::CDiagram, oSubReader) break; case 'e': - if (_T("o:equationxml") == sName) + if (L"o:equationxml" == sName) AssignPtrXmlContent(pItem, OOX::VmlOffice::CEquationXml, oSubReader) - else if (_T("o:extrusion") == sName) + else if (L"o:extrusion" == sName) AssignPtrXmlContent(pItem, OOX::VmlOffice::CExtrusion, oSubReader) break; case 'f': - if (_T("o:fill") == sName) + if (L"o:fill" == sName) AssignPtrXmlContent(pItem, OOX::VmlOffice::CFill, oSubReader) break; case 'i': - if (_T("o:ink") == sName) + if (L"o:ink" == sName) AssignPtrXmlContent(pItem, OOX::VmlOffice::CInk, oSubReader) break; case 'l': - if (_T("o:left") == sName) + if (L"o:left" == sName) AssignPtrXmlContent(pItem, OOX::VmlOffice::CStrokeChild, oSubReader) - else if (_T("o:lock") == sName) + else if (L"o:lock" == sName) AssignPtrXmlContent(pItem, OOX::VmlOffice::CLock, oSubReader) break; case 'O':// собственно это и есть самый главный под-объект - if (_T("o:OLEObject") == sName) + if (L"o:OLEObject" == sName) m_oOleObject = oSubReader; break; case 'r': - if (_T("o:right") == sName) + if (L"o:right" == sName) AssignPtrXmlContent(pItem, OOX::VmlOffice::CStrokeChild, oSubReader) break; case 's': - if (_T("o:shapedefaults") == sName) + if (L"o:shapedefaults" == sName) AssignPtrXmlContent(pItem, OOX::VmlOffice::CShapeDefaults, oSubReader) - else if (_T("o:shapelayout") == sName) + else if (L"o:shapelayout" == sName) AssignPtrXmlContent(pItem, OOX::VmlOffice::CShapeLayout, oSubReader) - else if (_T("o:signatureline") == sName) + else if (L"o:signatureline" == sName) AssignPtrXmlContent(pItem, OOX::VmlOffice::CSignatureLine, oSubReader) - else if (_T("o:skew") == sName) + else if (L"o:skew" == sName) AssignPtrXmlContent(pItem, OOX::VmlOffice::CSkew, oSubReader) break; case 't': - if (_T("o:top") == sName) + if (L"o:top" == sName) AssignPtrXmlContent(pItem, OOX::VmlOffice::CStrokeChild, oSubReader) break; } @@ -631,51 +690,51 @@ namespace OOX switch (wChar2) { case 'b': - if (_T("v:background") == sName) + if (L"v:background" == sName) AssignPtrXmlContent(pItem, OOX::Vml::CBackground, oSubReader) break; case 'f': - if (_T("v:fill") == sName) + if (L"v:fill" == sName) AssignPtrXmlContent(pItem, OOX::Vml::CFill, oSubReader) - else if (_T("v:formulas") == sName) + else if (L"v:formulas" == sName) AssignPtrXmlContent(pItem, OOX::Vml::CFormulas, oSubReader) break; case 'h': - if (_T("v:handles") == sName) + if (L"v:handles" == sName) AssignPtrXmlContent(pItem, OOX::Vml::CHandles, oSubReader) break; case 'i': - if (_T("v:image") == sName) + if (L"v:image" == sName) AssignPtrXmlContent(pItem, OOX::Vml::CImage, oSubReader) - else if (_T("v:imagedata") == sName) + else if (L"v:imagedata" == sName) AssignPtrXmlContent(pItem, OOX::Vml::CImageData, oSubReader) break; case 'p': - if (_T("v:path") == sName) + if (L"v:path" == sName) AssignPtrXmlContent(pItem, OOX::Vml::CPath, oSubReader) break; case 'r': - if (_T("v:rect") == sName) + if (L"v:rect" == sName) m_oShape = oSubReader; break; case 's': - if (_T("v:shadow") == sName) + if (L"v:shadow" == sName) AssignPtrXmlContent(pItem, OOX::Vml::CShadow, oSubReader) - else if (_T("v:shape") == sName) + else if (L"v:shape" == sName) m_oShape = oSubReader; - else if (_T("v:shapetype") == sName) + else if (L"v:shapetype" == sName) m_oShapeType = oSubReader; - else if (_T("v:stroke") == sName) + else if (L"v:stroke" == sName) AssignPtrXmlContent(pItem, OOX::Vml::CStroke, oSubReader) break; case 't': - if (_T("v:textbox") == sName) + if (L"v:textbox" == sName) AssignPtrXmlContent(pItem, OOX::Vml::CTextbox, oSubReader) - else if (_T("v:textpath") == sName) + else if (L"v:textpath" == sName) AssignPtrXmlContent(pItem, OOX::Vml::CTextPath, oSubReader) break; } @@ -700,7 +759,7 @@ namespace OOX } std::wstring CObject::toXML() const { - return _T(""); + return L""; } EElementType CObject::getType() const { diff --git a/OOXML/DocxFormat/Logic/Pict.h b/OOXML/DocxFormat/Logic/Pict.h index 44f4c367e40..a0973e18feb 100644 --- a/OOXML/DocxFormat/Logic/Pict.h +++ b/OOXML/DocxFormat/Logic/Pict.h @@ -62,9 +62,9 @@ namespace OOX virtual std::wstring toXML() const; virtual EElementType getType() const; + std::vector GetBytes(); private: void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); - public: nullable m_sName; nullable m_sData; diff --git a/OOXML/DocxFormat/Logic/RunContent.cpp b/OOXML/DocxFormat/Logic/RunContent.cpp index 871f5afbfda..22795eeb273 100644 --- a/OOXML/DocxFormat/Logic/RunContent.cpp +++ b/OOXML/DocxFormat/Logic/RunContent.cpp @@ -72,7 +72,7 @@ namespace OOX sResult += _T("w:type=\""); sResult += m_oType.ToString(); - sResult += _T("\" />"); + sResult += _T("\"/>"); return sResult; } @@ -153,7 +153,7 @@ namespace OOX sResult += L"\" "; } - sResult += L" />"; + sResult += L"/>"; return sResult; } @@ -184,7 +184,7 @@ namespace OOX } std::wstring CCr::toXML() const { - return _T(""); + return _T(""); } EElementType CCr::getType() const { @@ -207,7 +207,7 @@ namespace OOX } std::wstring CDayLong::toXML() const { - return _T(""); + return _T(""); } EElementType CDayLong::getType() const { @@ -230,7 +230,7 @@ namespace OOX } std::wstring CDayShort::toXML() const { - return _T(""); + return _T(""); } EElementType CDayShort::getType() const { @@ -318,7 +318,7 @@ namespace OOX } std::wstring CLastRenderedPageBreak::toXML() const { - return _T(""); + return _T(""); } EElementType CLastRenderedPageBreak::getType() const { @@ -341,7 +341,7 @@ namespace OOX } std::wstring CMonthLong::toXML() const { - return _T(""); + return _T(""); } EElementType CMonthLong::getType() const { @@ -364,7 +364,7 @@ namespace OOX } std::wstring CMonthShort::toXML() const { - return _T(""); + return _T(""); } EElementType CMonthShort::getType() const { @@ -387,7 +387,7 @@ namespace OOX } std::wstring CNoBreakHyphen::toXML() const { - return _T(""); + return _T(""); } EElementType CNoBreakHyphen::getType() const { @@ -410,7 +410,7 @@ namespace OOX } std::wstring CPgNum::toXML() const { - return _T(""); + return _T(""); } EElementType CPgNum::getType() const { @@ -494,7 +494,7 @@ namespace OOX } std::wstring CRuby::toXML() const { - return _T(""); + return _T(""); } EElementType CRuby::getType() const { @@ -517,7 +517,7 @@ namespace OOX } std::wstring CSoftHyphen::toXML() const { - return _T(""); + return _T(""); } EElementType CSoftHyphen::getType() const { @@ -672,7 +672,7 @@ namespace OOX } std::wstring CTab::toXML() const { - return _T(""); + return _T(""); } EElementType CTab::getType() const { @@ -695,7 +695,7 @@ namespace OOX } std::wstring CYearLong::toXML() const { - return _T(""); + return _T(""); } EElementType CYearLong::getType() const { @@ -718,7 +718,7 @@ namespace OOX } std::wstring CYearShort::toXML() const { - return _T(""); + return _T(""); } EElementType CYearShort::getType() const { @@ -741,7 +741,7 @@ namespace OOX } std::wstring CAnnotationRef::toXML() const { - return _T(""); + return _T(""); } EElementType CAnnotationRef::getType() const { @@ -821,7 +821,7 @@ namespace OOX } std::wstring CContinuationSeparator::toXML() const { - return _T(""); + return _T(""); } EElementType CContinuationSeparator::getType() const { @@ -909,7 +909,7 @@ namespace OOX } std::wstring CEndnoteRef::toXML() const { - return _T(""); + return _T(""); } EElementType CEndnoteRef::getType() const { @@ -995,7 +995,7 @@ namespace OOX } std::wstring CFootnoteRef::toXML() const { - return _T(""); + return _T(""); } EElementType CFootnoteRef::getType() const { @@ -1146,7 +1146,7 @@ namespace OOX } std::wstring CSeparator::toXML() const { - return _T(""); + return _T(""); } EElementType CSeparator::getType() const diff --git a/OOXML/DocxFormat/Logic/RunProperty.cpp b/OOXML/DocxFormat/Logic/RunProperty.cpp index fbee069b42d..aa1fac8740b 100644 --- a/OOXML/DocxFormat/Logic/RunProperty.cpp +++ b/OOXML/DocxFormat/Logic/RunProperty.cpp @@ -170,7 +170,7 @@ namespace OOX if ( m_sAuthor.IsInit() ) { sResult += L"w:author=\""; - sResult += m_sAuthor.get2(); + sResult += XmlUtils::EncodeXmlString(m_sAuthor.get2()); sResult += L"\" "; } if ( m_oDate.IsInit() ) diff --git a/OOXML/DocxFormat/Logic/Sdt.cpp b/OOXML/DocxFormat/Logic/Sdt.cpp index 27cb1208a13..0d7d3fee859 100644 --- a/OOXML/DocxFormat/Logic/Sdt.cpp +++ b/OOXML/DocxFormat/Logic/Sdt.cpp @@ -335,33 +335,30 @@ namespace ComplexTypes if ( m_sPrefixMappings.IsInit() ) { - sResult += L"w:prefixMappings=\""; - sResult += m_sPrefixMappings.get2(); - sResult += L"\" "; + sResult += L" w:prefixMappings=\"" + *m_sPrefixMappings + L"\""; } - if ( m_sXPath.IsInit() ) { - sResult += L"w:xpath=\""; - sResult += m_sXPath.get2(); - sResult += L"\" "; + sResult += L" w:xpath=\"" + *m_sXPath + L"\""; } - if ( m_sStoreItemID.IsInit() ) { - sResult += L"w:storeItemID=\""; - sResult += m_sStoreItemID.get2(); - sResult += L"\" "; + sResult += L" w:storeItemID=\"" + *m_sStoreItemID + L"\""; + } + if (m_sStoreItemChecksum.IsInit()) + { + sResult += L" w16sdtdh:storeItemChecksum=\"" + *m_sStoreItemChecksum + L"\""; } return sResult; } void CDataBinding::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) { - WritingElement_ReadAttributes_Start( oReader ) - WritingElement_ReadAttributes_Read_if ( oReader, L"w:prefixMappings", m_sPrefixMappings ) - WritingElement_ReadAttributes_Read_else_if( oReader, L"w:storeItemID", m_sStoreItemID ) - WritingElement_ReadAttributes_Read_else_if( oReader, L"w:xpath", m_sXPath ) - WritingElement_ReadAttributes_End( oReader ) + WritingElement_ReadAttributes_Start_No_NS(oReader ) + WritingElement_ReadAttributes_Read_if ( oReader, L"prefixMappings", m_sPrefixMappings ) + WritingElement_ReadAttributes_Read_else_if (oReader, L"storeItemID", m_sStoreItemID ) + WritingElement_ReadAttributes_Read_else_if (oReader, L"xpath", m_sXPath ) + WritingElement_ReadAttributes_Read_else_if (oReader, L"storeItemChecksum", m_sStoreItemChecksum) + WritingElement_ReadAttributes_End_No_NS(oReader ) } //---------------------------------------------------------------------------------------------------- CSdtListItem::CSdtListItem() @@ -1420,36 +1417,36 @@ namespace OOX int nParentDepth = oReader.GetDepth(); while (oReader.ReadNextSiblingNode(nParentDepth)) { - std::wstring sName = oReader.GetName(); + std::wstring sName = oReader.GetNameNoNS(); - if (L"w:alias" == sName) + if (L"alias" == sName) m_oAlias = oReader; - else if (L"w15:appearance" == sName) + else if (L"appearance" == sName) m_oAppearance = oReader; - else if (L"w:bibliography" == sName) + else if (L"bibliography" == sName) m_eType = sdttypeBibliography; - else if (sdttypeUnknown == m_eType && L"w:citation" == sName) + else if (sdttypeUnknown == m_eType && L"citation" == sName) m_eType = sdttypeCitation; - else if (sdttypeUnknown == m_eType && L"w:comboBox" == sName) + else if (sdttypeUnknown == m_eType && L"comboBox" == sName) { m_oComboBox = oReader; m_eType = sdttypeComboBox; } - else if (L"w15:color" == sName) + else if (L"color" == sName) m_oColor = oReader; - else if (L"w:dataBinding" == sName) + else if (L"dataBinding" == sName) m_oDataBinding = oReader; - else if (sdttypeUnknown == m_eType && L"w:date" == sName) + else if (sdttypeUnknown == m_eType && L"date" == sName) { m_oDate = oReader; m_eType = sdttypeDate; } - else if (sdttypeUnknown == m_eType && L"w:docPartList" == sName) + else if (sdttypeUnknown == m_eType && L"docPartList" == sName) { m_oDocPartList = oReader; m_eType = sdttypeDocPartList; } - else if (sdttypeUnknown == m_eType && L"w:docPartObj" == sName) + else if (sdttypeUnknown == m_eType && L"docPartObj" == sName) { m_oDocPartObj = oReader; m_eType = sdttypeDocPartObj; @@ -1460,55 +1457,55 @@ namespace OOX m_eType = sdttypeBibliography; } } - else if (sdttypeUnknown == m_eType && L"w:dropDownList" == sName) + else if (sdttypeUnknown == m_eType && L"dropDownList" == sName) { m_oDropDownList = oReader; m_eType = sdttypeDropDownList; } - else if (sdttypeUnknown == m_eType && L"w:equation" == sName) + else if (sdttypeUnknown == m_eType && L"equation" == sName) m_eType = sdttypeEquation; - else if (sdttypeUnknown == m_eType && L"w:group" == sName) + else if (sdttypeUnknown == m_eType && L"group" == sName) m_eType = sdttypeGroup; - else if (L"w:id" == sName) + else if (L"id" == sName) m_oId = oReader; - else if (L"w:label" == sName) + else if (L"label" == sName) m_oLabel = oReader; - else if (L"w:lock" == sName) + else if (L"lock" == sName) m_oLock = oReader; - else if (sdttypeUnknown == m_eType && L"w:picture" == sName) + else if (sdttypeUnknown == m_eType && L"picture" == sName) { m_oPicture = oReader; m_eType = sdttypePicture; } - else if (L"w:placeholder" == sName) + else if (L"placeholder" == sName) m_oPlaceHolder = oReader; - else if (sdttypeUnknown == m_eType && L"w:richText" == sName) + else if (sdttypeUnknown == m_eType && L"richText" == sName) m_eType = sdttypeRichText; - else if (L"w:rPr" == sName) + else if (L"rPr" == sName) m_oRPr = oReader; - else if (L"w:showingPlcHdr" == sName) + else if (L"showingPlcHdr" == sName) m_oShowingPlcHdr = oReader; - else if (L"w:tabIndex" == sName) + else if (L"tabIndex" == sName) m_oTabIndex = oReader; - else if (L"w:tag" == sName) + else if (L"tag" == sName) m_oTag = oReader; - else if (L"w:temporary" == sName) + else if (L"temporary" == sName) m_oTemporary = oReader; - else if (L"w:formPr" == sName) + else if (L"formPr" == sName) m_oFormPr = oReader; - else if (L"w:textFormPr" == sName) + else if (L"textFormPr" == sName) m_oTextFormPr = oReader; - else if (sdttypeUnknown == m_eType && L"w:text" == sName) + else if (sdttypeUnknown == m_eType && L"text" == sName) { m_oText = oReader; m_eType = sdttypeText; } - else if (sdttypeUnknown == m_eType && L"w14:checkbox" == sName) + else if (sdttypeUnknown == m_eType && L"checkbox" == sName) { m_oCheckbox = oReader; m_eType = sdttypeCheckBox; } - else if (L"w:complexFormPr" == sName) + else if (L"complexFormPr" == sName) m_oComplexFormPr = oReader; } } @@ -1526,7 +1523,18 @@ namespace OOX WritingElement_WriteNode_1(L"m_sStoreItemChecksum.IsInit()) + { + WritingElement_WriteNode_1(L""; return sResult; } @@ -1785,7 +1799,7 @@ namespace OOX void CSdt::fromXML(XmlUtils::CXmlLiteReader& oReader) { if ( oReader.IsEmptyNode() ) - return; + return; int nParentDepth = oReader.GetDepth(); diff --git a/OOXML/DocxFormat/Logic/Sdt.h b/OOXML/DocxFormat/Logic/Sdt.h index 4b5e969f704..b1918cc36f1 100644 --- a/OOXML/DocxFormat/Logic/Sdt.h +++ b/OOXML/DocxFormat/Logic/Sdt.h @@ -81,9 +81,12 @@ namespace ComplexTypes void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); public: - nullable m_sPrefixMappings; - nullable m_sStoreItemID; - nullable m_sXPath; + nullable_string m_sPrefixMappings; + nullable_string m_sStoreItemID; + nullable_string m_sXPath; +//ext w15 + nullable_string m_sStoreItemChecksum; + }; //-------------------------------------------------------------------------------- @@ -513,6 +516,7 @@ namespace OOX nullable_bool m_oRespectBorders; nullable_double m_oShiftX; nullable_double m_oShiftY; + nullable_bool m_oSignature; }; //-------------------------------------------------------------------------------- @@ -552,8 +556,6 @@ namespace OOX virtual std::wstring toXML() const; virtual EElementType getType() const; - public: - ESdtType m_eType; nullable m_oAlias; diff --git a/OOXML/DocxFormat/Logic/SectionProperty.cpp b/OOXML/DocxFormat/Logic/SectionProperty.cpp index 9c8e661353c..7b285e12f08 100644 --- a/OOXML/DocxFormat/Logic/SectionProperty.cpp +++ b/OOXML/DocxFormat/Logic/SectionProperty.cpp @@ -1438,9 +1438,9 @@ namespace OOX if ( m_sAuthor.IsInit() ) { - sResult += _T("w:author=\""); - sResult += m_sAuthor.get2(); - sResult += _T("\" "); + sResult += L"w:author=\""; + sResult += XmlUtils::EncodeXmlString(m_sAuthor.get2()); + sResult += L"\" "; } if ( m_oDate.IsInit() ) diff --git a/OOXML/DocxFormat/Logic/SectionProperty.h b/OOXML/DocxFormat/Logic/SectionProperty.h index 2d2fdeb8dc4..ef2907f7c2b 100644 --- a/OOXML/DocxFormat/Logic/SectionProperty.h +++ b/OOXML/DocxFormat/Logic/SectionProperty.h @@ -281,10 +281,10 @@ namespace ComplexTypes void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); public: - nullable m_oChapSep; - nullable m_oChapStyle; - nullable m_oFmt; - nullable m_oStart; + nullable m_oChapSep; + nullable m_oChapStyle; + nullable m_oFmt; + nullable m_oStart; }; //-------------------------------------------------------------------------------- diff --git a/OOXML/DocxFormat/Logic/Table.cpp b/OOXML/DocxFormat/Logic/Table.cpp index 3928acf049e..0ffabd11e57 100644 --- a/OOXML/DocxFormat/Logic/Table.cpp +++ b/OOXML/DocxFormat/Logic/Table.cpp @@ -228,9 +228,9 @@ namespace OOX if ( m_sAuthor.IsInit() ) { - sResult += _T("w:author=\""); - sResult += m_sAuthor.get2(); - sResult += _T("\" "); + sResult += L"w:author=\""; + sResult += XmlUtils::EncodeXmlString(m_sAuthor.get2()); + sResult += L"\" "; } if ( m_oDate.IsInit() ) diff --git a/OOXML/DocxFormat/Logic/TableProperty.cpp b/OOXML/DocxFormat/Logic/TableProperty.cpp index a9ea47665fb..5ee91e757f2 100644 --- a/OOXML/DocxFormat/Logic/TableProperty.cpp +++ b/OOXML/DocxFormat/Logic/TableProperty.cpp @@ -68,7 +68,7 @@ namespace ComplexTypes if ( m_sAuthor.IsInit() ) { sResult += L"w:author=\""; - sResult += m_sAuthor.get2(); + sResult += XmlUtils::EncodeXmlString(m_sAuthor.get2()); sResult += L"\" "; } @@ -1004,7 +1004,7 @@ namespace OOX if ( m_sAuthor.IsInit() ) { sResult += _T("w:author=\""); - sResult += m_sAuthor.get2(); + sResult += XmlUtils::EncodeXmlString(m_sAuthor.get2()); sResult += _T("\" "); } @@ -1263,9 +1263,9 @@ namespace OOX if ( m_sAuthor.IsInit() ) { - sResult += _T("w:author=\""); - sResult += m_sAuthor.get2(); - sResult += _T("\" "); + sResult += L"w:author=\""; + sResult += XmlUtils::EncodeXmlString(m_sAuthor.get2()); + sResult += L"\" "; } if ( m_oDate.IsInit() ) @@ -1742,9 +1742,9 @@ namespace OOX if ( m_sAuthor.IsInit() ) { - sResult += _T("w:author=\""); - sResult += m_sAuthor.get2(); - sResult += _T("\" "); + sResult += L"w:author=\""; + sResult += XmlUtils::EncodeXmlString(m_sAuthor.get2()); + sResult += L"\" "; } if ( m_oDate.IsInit() ) diff --git a/OOXML/DocxFormat/Logic/Vml.cpp b/OOXML/DocxFormat/Logic/Vml.cpp index 1e22b501d45..d74c50b61ab 100644 --- a/OOXML/DocxFormat/Logic/Vml.cpp +++ b/OOXML/DocxFormat/Logic/Vml.cpp @@ -195,14 +195,10 @@ namespace OOX if (docx_flat) { smart_ptr pImageFile = smart_ptr(new OOX::Image(document, true)); - - int dstLen = Base64::Base64DecodeGetRequiredLength((int)oBinData.m_sData->size()); - pImageFile->m_Data.resize(dstLen); - Base64::Base64Decode(oBinData.m_sData->c_str(), (int)oBinData.m_sData->size(), pImageFile->m_Data.data(), &dstLen); - pImageFile->m_Data.resize(dstLen); + pImageFile->m_Data = oBinData.GetBytes(); CImageFileFormatChecker fileChecker; - std::wstring ext = fileChecker.DetectFormatByData(pImageFile->m_Data.data(), dstLen); + std::wstring ext = fileChecker.DetectFormatByData(pImageFile->m_Data.data(), pImageFile->m_Data.size()); if (false == ext.empty()) { OOX::CPath filename(L"image." + ext); @@ -314,7 +310,7 @@ namespace OOX else if (L"o:bullet" == wsName ) m_oBullet = oReader.GetText(); else if (L"o:button" == wsName ) m_oButton = oReader.GetText(); else if (L"o:bwmode" == wsName ) m_oBwMode = oReader.GetText(); - else if (L"o:bwnormal" == wsName ) m_oBwNormal = oReader.GetText(); + else if (L"o:bwnormal" == wsName ) m_oBwNormal = oReader.GetText(); else if (L"o:bwpure" == wsName ) m_oBwPure = oReader.GetText(); break; case 'c': @@ -557,7 +553,7 @@ namespace OOX if (m_oOleIcon.get_value_or(false)) sResult += L"o:oleicon=\"t\" "; - if (m_oOle.get_value_or(false)) + if (m_oOle.IsInit()) sResult += L"o:ole=\"t\" "; if (m_oPreferRelative.get_value_or(false)) @@ -2026,9 +2022,6 @@ namespace OOX } void CFill::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) { - std::wstring sColors; - - // Читаем атрибуты if ( oReader.GetAttributesCount() <= 0 ) return; @@ -2050,7 +2043,7 @@ namespace OOX case 'c': if (L"color" == wsName ) m_oColor = oReader.GetText(); else if (L"color2" == wsName ) m_oColor2 = oReader.GetText(); - else if (L"colors" == wsName ) sColors = oReader.GetText(); + else if (L"colors" == wsName ) m_oColors = oReader.GetText(); break; case 'i': @@ -2106,8 +2099,6 @@ namespace OOX wsName = oReader.GetName(); } oReader.MoveToElement(); - - // TO DO: сделать парсер цветов CFill::m_arrColors } std::wstring CFill::toXML() const { @@ -2123,18 +2114,19 @@ namespace OOX sResult += L"opacity=\"" + m_oOpacity->ToString() + L"\" "; ComplexTypes_WriteAttribute (L"color=\"", m_oColor); - ComplexTypes_WriteAttribute (L"color2=\"", m_oColor2); - ComplexTypes_WriteAttribute3(L"src=\"", m_sSrc ); - ComplexTypes_WriteAttribute3(L"o:href=\"", m_sHref ); + ComplexTypes_WriteAttribute (L"color2=\"", m_oColor2); + ComplexTypes_WriteAttribute3(L"src=\"", m_sSrc ); + ComplexTypes_WriteAttribute3(L"o:href=\"", m_sHref ); ComplexTypes_WriteAttribute3(L"o:althref=\"", m_sAltHref ); - ComplexTypes_WriteAttribute (L"size=\"", m_oSize ); - ComplexTypes_WriteAttribute (L"origin=\"", m_oOrigin ); - ComplexTypes_WriteAttribute (L"position=\"", m_oPosition ); + ComplexTypes_WriteAttribute (L"size=\"", m_oSize ); + ComplexTypes_WriteAttribute (L"origin=\"", m_oOrigin ); + ComplexTypes_WriteAttribute (L"position=\"", m_oPosition ); if ((m_oAspect.IsInit()) && (SimpleTypes::imageaspectIgnore != m_oAspect->GetValue() )) sResult += L"aspect=\"" + m_oAspect->ToString() + L"\" "; - // TO DO: Сделать запись m_arrColors + if (m_oColors.IsInit()) + sResult += L"colors=\"" + *m_oColors + L"\" "; ComplexTypes_WriteAttribute (L"angle=\"", m_oAngle ); @@ -2154,7 +2146,7 @@ namespace OOX sResult += L"method=\"" + m_oMethod->ToString() + L"\" "; ComplexTypes_WriteAttribute (L"o:detectmouseclick=\"", m_oDetectMouseClick ); - ComplexTypes_WriteAttribute3(L"o:title=\"", m_sTitle ); + ComplexTypes_WriteAttribute3(L"o:title=\"", m_sTitle ); if ( m_oOpacity2.IsInit() ) sResult += L"o:opacity2=\"" + m_oOpacity2->ToString() + L"\" "; @@ -2165,7 +2157,7 @@ namespace OOX if (( m_oRotate.IsInit()) && m_oRotate->GetBool()) sResult += L"rotate=\"true\" "; - ComplexTypes_WriteAttribute (L"r:id=\"", m_rId ); + ComplexTypes_WriteAttribute (L"r:id=\"", m_rId ); ComplexTypes_WriteAttribute (L"o:relid=\"", m_oRelId ); sResult += L">"; diff --git a/OOXML/DocxFormat/Logic/Vml.h b/OOXML/DocxFormat/Logic/Vml.h index ec1348a4986..a16a640c126 100644 --- a/OOXML/DocxFormat/Logic/Vml.h +++ b/OOXML/DocxFormat/Logic/Vml.h @@ -254,7 +254,8 @@ namespace OOX nullable m_oAspect; nullable m_oColor; nullable m_oColor2; - std::vector m_arrColors; + nullable_string m_oColors; + std::vector m_arrColors; // parsing m_oColors - todooo nullable m_oDetectMouseClick; nullable m_oFocus; nullable m_oFocusPosition; diff --git a/OOXML/DocxFormat/Logic/VmlOfficeDrawing.cpp b/OOXML/DocxFormat/Logic/VmlOfficeDrawing.cpp index 96ba90ad761..7434f5faf8b 100644 --- a/OOXML/DocxFormat/Logic/VmlOfficeDrawing.cpp +++ b/OOXML/DocxFormat/Logic/VmlOfficeDrawing.cpp @@ -30,6 +30,7 @@ * */ +#include "../DocxFlat.h" #include "VmlOfficeDrawing.h" namespace OOX @@ -1268,19 +1269,32 @@ namespace OOX { ReadAttributes( oReader ); - if ( oReader.IsEmptyNode() ) - return; - - int nCurDepth = oReader.GetDepth(); - while ( oReader.ReadNextSiblingNode( nCurDepth ) ) + if (false == oReader.IsEmptyNode()) { - std::wstring sName = oReader.GetName(); - if ( L"o:FieldCodes" == sName ) - m_oFieldCodes = oReader; - else if ( L"o:LinkType" == sName ) - m_oLinkType = oReader; - else if ( L"o:LockedField" == sName ) - m_oLockedField = oReader; + int nCurDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nCurDepth)) + { + std::wstring sName = oReader.GetName(); + if (L"o:FieldCodes" == sName) + m_oFieldCodes = oReader; + else if (L"o:LinkType" == sName) + m_oLinkType = oReader; + else if (L"o:LockedField" == sName) + m_oLockedField = oReader; + } + } + + OOX::CDocxFlat* docx_flat = dynamic_cast(m_pMainDocument); + if (docx_flat && false == m_oId.IsInit() && m_sObjectId.IsInit()) + { + std::map>::iterator pFind = docx_flat->m_mapOleData.find(*m_sObjectId); + + if (pFind != docx_flat->m_mapOleData.end()) + { + const OOX::RId rId = docx_flat->m_currentContainer->Add(pFind->second); + m_oId.Init(); + m_oId->SetValue(rId.get()); + } } } std::wstring COLEObject::toXML() const diff --git a/OOXML/DocxFormat/Media/ActiveX.cpp b/OOXML/DocxFormat/Media/ActiveX.cpp index 6f27a41e54e..b18dae358d3 100644 --- a/OOXML/DocxFormat/Media/ActiveX.cpp +++ b/OOXML/DocxFormat/Media/ActiveX.cpp @@ -484,6 +484,20 @@ xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"" NSFile::CFileBinary::SaveToFile(sPath, sXml.GetData()); oContent.Registration(type().OverrideType(), oDirectory, oPath.GetFilename()); + if(m_oId.IsInit()) + { + smart_ptr pFileControlBin; + pFileControlBin = this->Find(OOX::RId(m_oId->GetValue())); + + smart_ptr pActiveX_bin = pFileControlBin.smart_dynamic_cast(); + + if (pActiveX_bin.IsInit()) + { + oContent.Registration(pActiveX_bin->type().OverrideType(), oDirectory, pActiveX_bin->filename().GetFilename()); + } + } + + IFileContainer::Write(oPath, oDirectory, oContent); } //--------------------------------------------------------------------------------------------------------- @@ -551,6 +565,8 @@ xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"" bool fCompressed = GETBIT(CountOfCharsWithCompressionFlag, 31); size_t size = GETBITS(CountOfCharsWithCompressionFlag, 0, 30); + + if (size > 0xfff0) return L""; if (stream->GetPosition() + size > stream->GetSize()) { diff --git a/OOXML/DocxFormat/Numbering.cpp b/OOXML/DocxFormat/Numbering.cpp index aa133538dce..f0cfb1a518b 100644 --- a/OOXML/DocxFormat/Numbering.cpp +++ b/OOXML/DocxFormat/Numbering.cpp @@ -112,7 +112,7 @@ namespace ComplexTypes if ( m_sVal.IsInit() ) { - sResult += L"w:val=\"" + *m_sVal + L"\" "; + sResult += L"w:val=\"" + XmlUtils::EncodeXmlString(*m_sVal, false) + L"\" "; } return sResult; } diff --git a/OOXML/DocxFormat/Numbering.h b/OOXML/DocxFormat/Numbering.h index 3becb5a0928..5f1bb1dc62b 100644 --- a/OOXML/DocxFormat/Numbering.h +++ b/OOXML/DocxFormat/Numbering.h @@ -87,9 +87,8 @@ namespace ComplexTypes void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); public: - - nullable m_oNull; - nullable_string m_sVal; + nullable m_oNull; + nullable_string m_sVal; }; //-------------------------------------------------------------------------------- diff --git a/OOXML/DocxFormat/Settings/Settings.cpp b/OOXML/DocxFormat/Settings/Settings.cpp index 26f088d2b12..91072ee0d09 100644 --- a/OOXML/DocxFormat/Settings/Settings.cpp +++ b/OOXML/DocxFormat/Settings/Settings.cpp @@ -516,7 +516,6 @@ namespace Settings } void CCompatSetting::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) { - // Читаем атрибуты if ( oReader.GetAttributesCount() <= 0 ) return; @@ -554,6 +553,15 @@ namespace Settings wsName = oReader.GetName(); } oReader.MoveToElement(); + + if (m_sName.IsInit() && (*m_sName == L"compatibilityMode") && m_sVal.IsInit()) + { + CDocxFlat* flat_docx = dynamic_cast(m_pMainDocument); + if (flat_docx) + { + flat_docx->m_sCompatibilityMode = *m_sVal; + } + } } //-------------------------------------------------------------------------------- @@ -669,24 +677,49 @@ namespace Settings m_oLayoutRawTableWidth = oReader; else if ( L"w:layoutTableRowsApart" == sName ) m_oLayoutTableRowsApart = oReader; - else if ( L"w:useWord97LineBreakRules" == sName ) + else if ( L"w:useWord97LineBreakRules" == sName ) m_oUseWord97LineBreakRules = oReader; + else if (L"w:breakWrappedTables" == sName) + { + m_oDoNotBreakWrappedTables = oReader; + m_oDoNotBreakWrappedTables->m_oVal.FromBool(!m_oDoNotBreakWrappedTables->m_oVal.ToBool()); + } else if ( L"w:doNotBreakWrappedTables" == sName ) m_oDoNotBreakWrappedTables = oReader; + else if (L"w:snapToGridInCell" == sName) + { + m_oDoNotSnapToGridInCell = oReader; + m_oDoNotSnapToGridInCell->m_oVal.FromBool(!m_oDoNotSnapToGridInCell->m_oVal.ToBool()); + } else if ( L"w:doNotSnapToGridInCell" == sName ) m_oDoNotSnapToGridInCell = oReader; else if ( L"w:selectFldWithFirstOrLastChar" == sName ) m_oSelectFldWithFirstOrLastChar = oReader; else if ( L"w:applyBreakingRules" == sName ) m_oApplyBreakingRules = oReader; + else if (L"w:wrapTextWithPunct" == sName) + { + m_oDoNotWrapTextWithPunct = oReader; + m_oDoNotWrapTextWithPunct->m_oVal.FromBool(!m_oDoNotWrapTextWithPunct->m_oVal.ToBool()); + } else if ( L"w:doNotWrapTextWithPunct" == sName ) m_oDoNotWrapTextWithPunct = oReader; + else if (L"w:useAsianBreakRules" == sName) + { + m_oDoNotUseEastAsianBreakRules = oReader; + m_oDoNotUseEastAsianBreakRules->m_oVal.FromBool(!m_oDoNotUseEastAsianBreakRules->m_oVal.ToBool()); + } else if ( L"w:doNotUseEastAsianBreakRules" == sName ) m_oDoNotUseEastAsianBreakRules = oReader; else if ( L"w:useWord2002TableStyleRules" == sName ) m_oUseWord2002TableStyleRules = oReader; else if ( L"w:growAutofit" == sName ) m_oGrowAutofit = oReader; + else if (L"w:dontGrowAutofit" == sName) + { + m_oGrowAutofit = oReader; + m_oGrowAutofit->m_oVal.FromBool(!m_oGrowAutofit->m_oVal.ToBool()); + } else if ( L"w:useFELayout" == sName ) m_oUseFELayout = oReader; else if ( L"w:useNormalStyleForList" == sName ) @@ -724,7 +757,7 @@ namespace Settings OOX::Settings::CCompatSetting *oCS = new OOX::Settings::CCompatSetting(); *oCS = oReader; - if (oCS)m_arrCompatSettings.push_back( oCS ); + if (oCS) m_arrCompatSettings.push_back( oCS ); } } } diff --git a/OOXML/DocxFormat/VmlDrawing.cpp b/OOXML/DocxFormat/VmlDrawing.cpp index b764439b039..85bf3a1c8e0 100644 --- a/OOXML/DocxFormat/VmlDrawing.cpp +++ b/OOXML/DocxFormat/VmlDrawing.cpp @@ -58,7 +58,7 @@ namespace OOX return; std::wstring sName1 = XmlUtils::GetNameNoNS(oReader.GetName()); - if ( _T("xml") == sName1 ) + if ( L"xml" == sName1 ) { ReadAttributes( oReader ); @@ -96,7 +96,7 @@ namespace OOX switch ( wChar2 ) { case 'a': - if ( _T("v:arc") == sName ) + if ( L"v:arc" == sName ) { AssignPtrXmlContent(pItem, OOX::Vml::CArc, oSubReader) bReadyElement = true; @@ -104,66 +104,66 @@ namespace OOX } break; case 'c': - if ( _T("v:curve") == sName ) + if ( L"v:curve" == sName ) { AssignPtrXmlContent(pItem, OOX::Vml::CCurve, oSubReader) bReadyElement = true; } break; case 'g': - if ( _T("v:group") == sName ) + if ( L"v:group" == sName ) { AssignPtrXmlContent(pItem, OOX::Vml::CGroup, oSubReader) bReadyElement = true; } break; case 'i': - if ( _T("v:image") == sName ) + if ( L"v:image" == sName ) { AssignPtrXmlContent(pItem, OOX::Vml::CImage, oSubReader) bReadyElement = true; } break; case 'l': - if ( _T("v:line") == sName ) + if ( L"v:line" == sName ) { AssignPtrXmlContent(pItem, OOX::Vml::CLine, oSubReader) bReadyElement = true; } break; case 'o': - if ( _T("v:oval") == sName ) + if ( L"v:oval" == sName ) { AssignPtrXmlContent(pItem, OOX::Vml::COval, oSubReader) bReadyElement = true; } break; case 'p': - if ( _T("v:polyline") == sName ) + if ( L"v:polyline" == sName ) { AssignPtrXmlContent(pItem, OOX::Vml::CPolyLine, oSubReader) bReadyElement = true; } break; case 'r': - if ( _T("v:rect") == sName ) + if ( L"v:rect" == sName ) { AssignPtrXmlContent(pItem, OOX::Vml::CRect, oSubReader) bReadyElement = true; } - else if ( _T("v:roundrect") == sName ) + else if ( L"v:roundrect" == sName ) { AssignPtrXmlContent(pItem, OOX::Vml::CRoundRect, oSubReader) bReadyElement = true; } break; case 's': - if ( _T("v:shape") == sName ) + if ( L"v:shape" == sName ) { AssignPtrXmlContent(pItem, OOX::Vml::CShape, oSubReader) bReadyElement = true; } - else if ( _T("v:shapetype") == sName ) + else if ( L"v:shapetype" == sName ) { AssignPtrXmlContent(pItem, OOX::Vml::CShapeType, oSubReader) } @@ -204,10 +204,10 @@ namespace OOX { _vml_shape element; - element.nId = (int)m_arrItems.size()-1; - element.sXml = elementContent; - element.pElement = pItem; - element.bUsed = bComment; + element.nId = (int)m_arrItems.size()-1; + element.sXml = elementContent; + element.pElement = pItem; + element.bComment = bComment; m_mapShapes.insert(std::make_pair(sSpid, element)); } @@ -257,21 +257,21 @@ namespace OOX { // элементы вида
без
// test_vml4.xlsx - XmlUtils::replace_all(m_sFileContent, _T("
"), _T("")); + XmlUtils::replace_all(m_sFileContent, L"
", L""); // элементы вида , // Zigmunds.pptx while(true) { - int res1 = (int)m_sFileContent.find(_T(""), res1); + size_t res2 = m_sFileContent.find(L">", res1); - if (res1 >=0 && res2>=0) + if (res1 != std::wstring::npos && res2 != std::wstring::npos) { - m_sFileContent = m_sFileContent.erase(res1 ,res2 - res1 + 1); + m_sFileContent = m_sFileContent.erase(res1, res2 - res1 + 1); } } read(m_sFileContent); @@ -419,7 +419,7 @@ xmlns:x=\"urn:schemas-microsoft-com:office:excel\">"); { smart_ptr oElement; - boost::unordered_map::iterator pFind = m_mapShapes.find(spid); + std::map::iterator pFind = m_mapShapes.find(spid); if (pFind != m_mapShapes.end()) { diff --git a/OOXML/DocxFormat/VmlDrawing.h b/OOXML/DocxFormat/VmlDrawing.h index 171c0364283..1c4021fa2d3 100644 --- a/OOXML/DocxFormat/VmlDrawing.h +++ b/OOXML/DocxFormat/VmlDrawing.h @@ -47,12 +47,13 @@ namespace OOX public: struct _vml_shape { - _vml_shape() : bUsed(false), pElement(NULL), nId(0) {} + _vml_shape() : bUsed(false), pElement(NULL), nId(0), bComment(false) {} int nId; // for comments std::wstring sXml; // for pptx OOX::WritingElement* pElement; // for docx/xlsx bool bUsed; // for single drawing + bool bComment; }; CVmlDrawing(OOX::Document* pMain, bool bDocument = true) : OOX::FileGlobalEnumerated(pMain), OOX::IFileContainer(pMain) { @@ -115,16 +116,16 @@ namespace OOX public: //reading - CPath m_oReadPath; - boost::unordered_map m_mapShapes; - std::vector<_vml_shape> m_arrShapeTypes; + CPath m_oReadPath; + std::map m_mapShapes; + std::vector<_vml_shape> m_arrShapeTypes; - std::wstring m_sFileContent; + std::wstring m_sFileContent; //writing - std::map* m_mapComments; - std::vector m_arObjectXml; - std::vector m_arControlXml; + std::map* m_mapComments; + std::vector m_arObjectXml; + std::vector m_arControlXml; - long m_lObjectIdVML; + long m_lObjectIdVML; }; } // namespace OOX \ No newline at end of file diff --git a/OOXML/DocxFormat/WritingElement.h b/OOXML/DocxFormat/WritingElement.h index 312b93aefc0..9a941aeeae5 100644 --- a/OOXML/DocxFormat/WritingElement.h +++ b/OOXML/DocxFormat/WritingElement.h @@ -788,6 +788,7 @@ namespace OOX et_w_bdo, // et_w_binData, // et_w_bgPict, // + et_w_docSuppData, // et_w_bookmarkEnd, // et_w_bookmarkStart, // et_w_br, // @@ -1496,7 +1497,46 @@ namespace OOX et_x_SparklineGroup, et_x_Sparklines, et_x_Sparkline, - et_x_Style2003 + + et_x_Style2003, + + et_x_TimelineCachePivotTable, + et_x_TimelineRange, + et_x_TimelineCachePivotTables, + et_x_Timeline, + et_x_Timelines, + et_x_TimelineCacheDefinition, + et_x_TimelinePivotFilter, + et_x_TimelineState, + et_x_TimelineRefs, + et_x_TimelineRef, + et_x_TimelineCacheRefs, + et_x_TimelineCacheRef, + et_x_Timeslicer, + et_x_TimelineStyles, + et_x_TimelineStyle, + et_x_TimelineStyleElement, + + et_x_Metadata, + et_x_FutureMetadata, + et_x_FutureMetadataBlock, + et_x_MetadataType, + et_x_MetadataTypes, + et_x_MetadataBlocks, + et_x_MetadataBlock, + et_x_MetadataRecord, + et_x_MetadataString, + et_x_MetadataStrings, + et_x_MdxMetadata, + et_x_Mdx, + et_x_MdxTuple, + et_x_MetadataStringIndex, + et_x_MdxSet, + et_x_MdxMemeberProp, + et_x_MdxKPI, + + et_x_DynamicArrayProperties, + et_x_RichValueBlock }; class File; @@ -1508,6 +1548,7 @@ namespace OOX virtual ~Document(); std::wstring m_sDocumentPath; + std::wstring m_sTempPath; std::map> m_mapContent; }; diff --git a/OOXML/PPTXFormat/Core.cpp b/OOXML/PPTXFormat/Core.cpp deleted file mode 100644 index 010f767eb38..00000000000 --- a/OOXML/PPTXFormat/Core.cpp +++ /dev/null @@ -1,236 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2023 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ - -#include "Core.h" - -namespace PPTX -{ - Core::Core(OOX::Document* pMain) : WrapperFile(pMain) - { - } - Core::Core(OOX::Document* pMain, const OOX::CPath& filename, FileMap& map) : WrapperFile(pMain) - { - read(filename, map); - } - Core::~Core() - { - } - void Core::read(const OOX::CPath& filename, FileMap& map) - { - XmlUtils::CXmlNode oNode; - oNode.FromXmlFile(filename.m_strFilename); - - XmlMacroReadNodeValueBase(oNode, _T("cp:category"), category); - XmlMacroReadNodeValueBase(oNode, _T("cp:contentStatus"), contentStatus); - XmlMacroReadNodeValueBase(oNode, _T("dcterms:created"), created); - //created = PPTX::DateTime::Parse(document.Root.element("created").text().ToString()); - XmlMacroReadNodeValueBase(oNode, _T("dc:creator"), creator); - XmlMacroReadNodeValueBase(oNode, _T("dc:description"), description); - XmlMacroReadNodeValueBase(oNode, _T("dc:identifier"), identifier); - //todo keywords is complex by spec there is no real example - XmlMacroReadNodeValueBase(oNode, _T("cp:keywords"), keywords); - XmlMacroReadNodeValueBase(oNode, _T("dc:language"), language); - XmlMacroReadNodeValueBase(oNode, _T("cp:lastModifiedBy"), lastModifiedBy); - XmlMacroReadNodeValueBase(oNode, _T("cp:lastPrinted"), lastPrinted); - //lastPrinted = PPTX::DateTime::Parse(document.Root.element("lastPrinted").text().ToString()); - XmlMacroReadNodeValueBase(oNode, _T("dcterms:modified"), modified); - //modified = PPTX::DateTime::Parse(document.Root.element("modified").text().ToString()); - XmlMacroReadNodeValueBase(oNode, _T("cp:revision"), revision); - XmlMacroReadNodeValueBase(oNode, _T("dc:subject"), subject); - XmlMacroReadNodeValueBase(oNode, _T("dc:title"), title); - XmlMacroReadNodeValueBase(oNode, _T("cp:version"), version); - } - void Core::write(const OOX::CPath& filename, const OOX::CPath& directory, OOX::CContentTypes& content)const - { - WrapperFile::write(filename, directory, content); - } - const OOX::FileType Core::type() const - { - return OOX::FileTypes::Core; - } - const OOX::CPath Core::DefaultDirectory() const - { - return type().DefaultDirectory(); - } - const OOX::CPath Core::DefaultFileName() const - { - return type().DefaultFileName(); - } - void Core::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const - { - pWriter->StartRecord(NSBinPptxRW::NSMainTables::Core); - - pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeStart); - - pWriter->WriteString2(0, title); - pWriter->WriteString2(1, creator); - pWriter->WriteString2(2, lastModifiedBy); - pWriter->WriteString2(3, revision); - pWriter->WriteString2(4, created); - pWriter->WriteString2(5, modified); - - pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd); - - //start new record because new attributes is incompatible with previous versions - pWriter->StartRecord(0); - pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeStart); - - pWriter->WriteString2(6, category); - pWriter->WriteString2(7, contentStatus); - pWriter->WriteString2(8, description); - pWriter->WriteString2(9, identifier); - pWriter->WriteString2(10, keywords); - pWriter->WriteString2(11, language); - pWriter->WriteString2(12, lastPrinted); - pWriter->WriteString2(13, subject); - pWriter->WriteString2(14, version); - - pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd); - pWriter->EndRecord(); - - pWriter->EndRecord(); - } - void Core::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) - { - pReader->Skip(1); // type - LONG _end_rec = pReader->GetPos() + pReader->GetRecordSize() + 4; - - pReader->Skip(1); // start attributes - - while (true) - { - BYTE _at = pReader->GetUChar_TypeNode(); - if (_at == NSBinPptxRW::g_nodeAttributeEnd) - break; - - switch (_at) - { - case 0: title = pReader->GetString2(); break; - case 1: creator = pReader->GetString2(); break; - case 2: lastModifiedBy = pReader->GetString2(); break; - case 3: revision = pReader->GetString2(); break; - case 4: created = pReader->GetString2(); break; - case 5: modified = pReader->GetString2(); break; - default: break; - } - } - while (pReader->GetPos() < _end_rec) - { - BYTE _at = pReader->GetUChar(); - switch (_at) - { - case 0: - { - LONG _end_rec2 = pReader->GetPos() + pReader->GetRecordSize() + 4; - - pReader->Skip(1); // start attributes - - while (true) - { - BYTE _at = pReader->GetUChar_TypeNode(); - if (_at == NSBinPptxRW::g_nodeAttributeEnd) - break; - - switch (_at) - { - case 6: category = pReader->GetString2(); break; - case 7: contentStatus = pReader->GetString2(); break; - case 8: description = pReader->GetString2(); break; - case 9: identifier = pReader->GetString2(); break; - case 10: keywords = pReader->GetString2(); break; - case 11: language = pReader->GetString2(); break; - case 12: lastPrinted = pReader->GetString2(); break; - case 13: subject = pReader->GetString2(); break; - case 14: version = pReader->GetString2(); break; - } - } - - pReader->Seek(_end_rec2); - } - break; - default: - { - pReader->SkipRecord(); - break; - } - } - } - - pReader->Seek(_end_rec); - } - void Core::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const - { - pWriter->StartNode(_T("cp:coreProperties")); - - pWriter->StartAttributes(); - - pWriter->WriteAttribute(_T("xmlns:cp"), PPTX::g_Namespaces.cp.m_strLink); - pWriter->WriteAttribute(_T("xmlns:dc"), PPTX::g_Namespaces.dc.m_strLink); - pWriter->WriteAttribute(_T("xmlns:dcterms"), PPTX::g_Namespaces.dcterms.m_strLink); - pWriter->WriteAttribute(_T("xmlns:dcmitype"), PPTX::g_Namespaces.dcmitype.m_strLink); - pWriter->WriteAttribute(_T("xmlns:xsi"), PPTX::g_Namespaces.xsi.m_strLink); - - pWriter->EndAttributes(); - - pWriter->WriteNodeValue2(_T("dc:title"), title); - pWriter->WriteNodeValue2(_T("dc:subject"), subject); - pWriter->WriteNodeValue2(_T("dc:creator"), creator); - pWriter->WriteNodeValue2(_T("cp:keywords"), keywords); - pWriter->WriteNodeValue2(_T("dc:description"), description); - pWriter->WriteNodeValue2(_T("dc:identifier"), identifier); - pWriter->WriteNodeValue2(_T("dc:language"), language); - pWriter->WriteNodeValue2(_T("cp:lastModifiedBy"), lastModifiedBy); - pWriter->WriteNodeValue2(_T("cp:revision"), revision); - - if ((lastPrinted.IsInit()) && (false == lastPrinted->empty())) - { - pWriter->WriteNodeValue2(_T("cp:lastPrinted"), lastPrinted); - } - if ((created.IsInit()) && (false == created->empty())) - { - pWriter->WriteNodeBegin(_T("dcterms:created xsi:type=\"dcterms:W3CDTF\"")); - pWriter->WriteStringXML(*created); - pWriter->WriteNodeEnd(_T("dcterms:created")); - } - if ((modified.IsInit()) && (false == modified->empty())) - { - pWriter->WriteNodeBegin(_T("dcterms:modified xsi:type=\"dcterms:W3CDTF\"")); - pWriter->WriteStringXML(*modified); - pWriter->WriteNodeEnd(_T("dcterms:modified")); - } - pWriter->WriteNodeValue2(_T("cp:category"), category); - pWriter->WriteNodeValue2(_T("cp:contentStatus"), contentStatus); - pWriter->WriteNodeValue2(_T("cp:version"), version); - - pWriter->EndNode(_T("cp:coreProperties")); - } -} // namespace PPTX diff --git a/OOXML/PPTXFormat/Core.h b/OOXML/PPTXFormat/Core.h deleted file mode 100644 index 709993b5aeb..00000000000 --- a/OOXML/PPTXFormat/Core.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2023 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#pragma once - -#include "WrapperFile.h" -#include "../DocxFormat/WritingElement.h" - -#include "Limit/ContentStatus.h" -#include "FileTypes.h" - -namespace PPTX -{ - class Core : public WrapperFile - { - public: - Core(OOX::Document* pMain); - Core(OOX::Document* pMain, const OOX::CPath& filename, FileMap& map); - virtual ~Core(); - - public: - virtual void read(const OOX::CPath& filename, FileMap& map); - virtual void write(const OOX::CPath& filename, const OOX::CPath& directory, OOX::CContentTypes& content) const; - - public: - virtual const OOX::FileType type() const; - - virtual const OOX::CPath DefaultDirectory() const; - virtual const OOX::CPath DefaultFileName() const; - - virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; - virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); - virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; - - public: - nullable_string category; - nullable_string contentStatus; - //nullable_property contentStatus; - nullable_string created; - //nullable_property created; - nullable_string creator; - nullable_string description; - nullable_string identifier; - nullable_string keywords; - nullable_string language; - nullable_string lastModifiedBy; - nullable_string lastPrinted; - nullable_string modified; - //nullable_property modified; - nullable_string revision; - nullable_string subject; - nullable_string title; - nullable_string version; - }; -} // namespace PPTX diff --git a/OOXML/PPTXFormat/DrawingConverter/ASCOfficeDrawingConverter.cpp b/OOXML/PPTXFormat/DrawingConverter/ASCOfficeDrawingConverter.cpp index 87f092b4ac4..a65dc818453 100644 --- a/OOXML/PPTXFormat/DrawingConverter/ASCOfficeDrawingConverter.cpp +++ b/OOXML/PPTXFormat/DrawingConverter/ASCOfficeDrawingConverter.cpp @@ -45,6 +45,7 @@ #include "../../PPTXFormat/Logic/Colors/SchemeClr.h" #include "../../PPTXFormat/Logic/Colors/SysClr.h" #include "../../PPTXFormat/Logic/Effects/AlphaModFix.h" +#include "../../PPTXFormat/Logic/Effects/Duotone.h" #include "../../PPTXFormat/PPTX.h" #include "../../PPTXFormat/LegacyDiagramText.h" @@ -427,18 +428,27 @@ namespace NS_DWC_Common BYTE getOpacityFromString(const std::wstring opacityStr) { - BYTE alpha; - if (opacityStr.find(L"f") != -1) + BYTE alpha = 0xff; + + if (opacityStr.find(L"f") != std::wstring::npos) + { alpha = (BYTE)(XmlUtils::GetDouble(opacityStr) / 65536 * 256); + } else { - if (0 == opacityStr.find(L".")) + if (opacityStr.find(L"%") != std::wstring::npos) + { + alpha = (BYTE)(XmlUtils::GetDouble(opacityStr.substr(0, opacityStr.length() - 1)) / 100. * 256); + } + else if (0 == opacityStr.find(L".")) { std::wstring str = L"0" + opacityStr; alpha = (BYTE)(XmlUtils::GetDouble(str) * 256); } else + { alpha = (BYTE)(XmlUtils::GetDouble(opacityStr) * 256); + } } return alpha; } @@ -2065,10 +2075,16 @@ bool CDrawingConverter::ParceObject(const std::wstring& strXml, std::wstring** p pPicture->spPr.Fill = PPTX::Logic::UniFill(); pShape = NULL; - pElem->InitElem(pPicture); + pElem->InitElem(pPicture); + } if ((pPicture) && (pPicture->blipFill.blip.IsInit())) { + if (pPicture->spPr.xfrm.IsInit()) + {// for bad replacemant image for ole + m_pBinaryWriter->m_dCxCurShape = pPicture->spPr.xfrm->extX.get_value_or(0); + m_pBinaryWriter->m_dCyCurShape = pPicture->spPr.xfrm->extY.get_value_or(0); + } if (pOle->m_OleObjectFile.IsInit()) { pPicture->blipFill.blip->oleFilepathBin = pOle->m_OleObjectFile->filename().GetPath(); @@ -2191,26 +2207,26 @@ void CDrawingConverter::ConvertDiagram(PPTX::Logic::SpTreeElem *result, XmlUtils { _pElem.grpSpPr.xfrm = new PPTX::Logic::Xfrm(); - _pElem.grpSpPr.xfrm->offX = m_pBinaryWriter->m_lXCurShape; - _pElem.grpSpPr.xfrm->offY = m_pBinaryWriter->m_lYCurShape; - _pElem.grpSpPr.xfrm->extX = m_pBinaryWriter->m_lCxCurShape; - _pElem.grpSpPr.xfrm->extY = m_pBinaryWriter->m_lCyCurShape; + _pElem.grpSpPr.xfrm->offX = m_pBinaryWriter->m_dXCurShape; + _pElem.grpSpPr.xfrm->offY = m_pBinaryWriter->m_dYCurShape; + _pElem.grpSpPr.xfrm->extX = m_pBinaryWriter->m_dCxCurShape; + _pElem.grpSpPr.xfrm->extY = m_pBinaryWriter->m_dCyCurShape; _pElem.grpSpPr.xfrm->chOffX = (int)0; _pElem.grpSpPr.xfrm->chOffY = (int)0; - _pElem.grpSpPr.xfrm->chExtX = m_pBinaryWriter->m_lCxCurShape; - _pElem.grpSpPr.xfrm->chExtY = m_pBinaryWriter->m_lCyCurShape; + _pElem.grpSpPr.xfrm->chExtX = m_pBinaryWriter->m_dCxCurShape; + _pElem.grpSpPr.xfrm->chExtY = m_pBinaryWriter->m_dCyCurShape; } else { - if (!_pElem.grpSpPr.xfrm->offX.is_init()) _pElem.grpSpPr.xfrm->offX = m_pBinaryWriter->m_lXCurShape; - if (!_pElem.grpSpPr.xfrm->offY.is_init()) _pElem.grpSpPr.xfrm->offY = m_pBinaryWriter->m_lYCurShape; - if (!_pElem.grpSpPr.xfrm->extX.is_init()) _pElem.grpSpPr.xfrm->extX = m_pBinaryWriter->m_lCxCurShape; - if (!_pElem.grpSpPr.xfrm->extY.is_init()) _pElem.grpSpPr.xfrm->extY = m_pBinaryWriter->m_lCyCurShape; + if (!_pElem.grpSpPr.xfrm->offX.is_init()) _pElem.grpSpPr.xfrm->offX = m_pBinaryWriter->m_dXCurShape; + if (!_pElem.grpSpPr.xfrm->offY.is_init()) _pElem.grpSpPr.xfrm->offY = m_pBinaryWriter->m_dYCurShape; + if (!_pElem.grpSpPr.xfrm->extX.is_init()) _pElem.grpSpPr.xfrm->extX = m_pBinaryWriter->m_dCxCurShape; + if (!_pElem.grpSpPr.xfrm->extY.is_init()) _pElem.grpSpPr.xfrm->extY = m_pBinaryWriter->m_dCyCurShape; if (!_pElem.grpSpPr.xfrm->chOffX.is_init()) _pElem.grpSpPr.xfrm->chOffX = (int)0; if (!_pElem.grpSpPr.xfrm->chOffY.is_init()) _pElem.grpSpPr.xfrm->chOffY = (int)0; - if (!_pElem.grpSpPr.xfrm->chExtX.is_init()) _pElem.grpSpPr.xfrm->chExtX = m_pBinaryWriter->m_lCxCurShape; - if (!_pElem.grpSpPr.xfrm->chExtY.is_init()) _pElem.grpSpPr.xfrm->chExtY = m_pBinaryWriter->m_lCyCurShape; + if (!_pElem.grpSpPr.xfrm->chExtX.is_init()) _pElem.grpSpPr.xfrm->chExtX = m_pBinaryWriter->m_dCxCurShape; + if (!_pElem.grpSpPr.xfrm->chExtY.is_init()) _pElem.grpSpPr.xfrm->chExtY = m_pBinaryWriter->m_dCyCurShape; } } @@ -2229,13 +2245,13 @@ void CDrawingConverter::ConvertDrawing(PPTX::Logic::SpTreeElem *elem, XmlUtils:: { XmlUtils::CXmlNode oNodeExt; - m_pBinaryWriter->m_lXCurShape = 0; - m_pBinaryWriter->m_lYCurShape = 0; + m_pBinaryWriter->m_dXCurShape = 0; + m_pBinaryWriter->m_dYCurShape = 0; if (oNodeAnchorInline.GetNode(L"wp:extent", oNodeExt)) { - m_pBinaryWriter->m_lCxCurShape = oNodeExt.ReadAttributeInt(L"cx"); - m_pBinaryWriter->m_lCyCurShape = oNodeExt.ReadAttributeInt(L"cy"); + m_pBinaryWriter->m_dCxCurShape = oNodeExt.ReadAttributeInt(L"cx"); + m_pBinaryWriter->m_dCyCurShape = oNodeExt.ReadAttributeInt(L"cy"); } XmlUtils::CXmlNode oNodeDocPr; if (oNodeAnchorInline.GetNode(L"wp:docPr", oNodeDocPr)) @@ -2266,10 +2282,10 @@ void CDrawingConverter::ConvertDrawing(PPTX::Logic::SpTreeElem *elem, XmlUtils:: PPTX::Logic::SpTree* pTree = new PPTX::Logic::SpTree(); pTree->grpSpPr.xfrm = new PPTX::Logic::Xfrm(); - pTree->grpSpPr.xfrm->offX = m_pBinaryWriter->m_lXCurShape; - pTree->grpSpPr.xfrm->offY = m_pBinaryWriter->m_lYCurShape; - pTree->grpSpPr.xfrm->extX = m_pBinaryWriter->m_lCxCurShape; - pTree->grpSpPr.xfrm->extY = m_pBinaryWriter->m_lCyCurShape; + pTree->grpSpPr.xfrm->offX = m_pBinaryWriter->m_dXCurShape; + pTree->grpSpPr.xfrm->offY = m_pBinaryWriter->m_dYCurShape; + pTree->grpSpPr.xfrm->extX = m_pBinaryWriter->m_dCxCurShape; + pTree->grpSpPr.xfrm->extY = m_pBinaryWriter->m_dCyCurShape; pTree->fromXML(oNodeContent); elem->InitElem(pTree); @@ -2282,7 +2298,7 @@ void CDrawingConverter::ConvertDrawing(PPTX::Logic::SpTreeElem *elem, XmlUtils:: } } } -void CDrawingConverter::ConvertShape(PPTX::Logic::SpTreeElem *elem, XmlUtils::CXmlNode& oNodeShape, std::wstring**& pMainProps,bool bIsTop) +void CDrawingConverter::ConvertShape(PPTX::Logic::SpTreeElem *elem, XmlUtils::CXmlNode& oNodeShape, std::wstring**& pMainProps, bool bIsTop) { if (!elem) return; @@ -2638,21 +2654,51 @@ void CDrawingConverter::ConvertShape(PPTX::Logic::SpTreeElem *elem, XmlUtils::CX std::wstring sTextInsetMode = oNodeTextBox.GetAttribute(L"o:insetmode"); sTextboxStyle = oNodeTextBox.GetAttribute(L"style"); - if (L"" != sTextInset && ((L"" == sTextInsetMode) || (L"custom" == sTextInsetMode))) + //if (L"" != sTextInset && ((L"" == sTextInsetMode) || (L"custom" == sTextInsetMode))) + if (sTextInsetMode.empty() || L"custom" == sTextInsetMode) { - PPTX::CStringTrimmer oTrimmer; - oTrimmer.m_Separator = (wchar_t)','; - oTrimmer.LoadFromString(sTextInset); - - double dTextMarginLeft = oTrimmer.GetParameter(0, 0.1); - double dTextMarginTop = oTrimmer.GetParameter(1, 0.05); - double dTextMarginRight = oTrimmer.GetParameter(2, 0.1); - double dTextMarginBottom = oTrimmer.GetParameter(3, 0.05); - - pShape->oTextBoxBodyPr->lIns = (int)(12700 * dTextMarginLeft + 0.5); - pShape->oTextBoxBodyPr->tIns = (int)(12700 * dTextMarginTop + 0.5); - pShape->oTextBoxBodyPr->rIns = (int)(12700 * dTextMarginRight + 0.5); - pShape->oTextBoxBodyPr->bIns = (int)(12700 * dTextMarginBottom + 0.5); + if (!sTextInset.empty()) + { + PPTX::CStringTrimmer oTrimmer; + oTrimmer.m_Separator = (wchar_t)','; + oTrimmer.LoadFromString(sTextInset); + + double dTextMarginLeft = oTrimmer.GetParameter(0, 0.1); + double dTextMarginTop = oTrimmer.GetParameter(1, 0.05); + double dTextMarginRight = oTrimmer.GetParameter(2, 0.1); + double dTextMarginBottom = oTrimmer.GetParameter(3, 0.05); + + pShape->oTextBoxBodyPr->lIns = (int)(12700 * dTextMarginLeft + 0.5); + pShape->oTextBoxBodyPr->tIns = (int)(12700 * dTextMarginTop + 0.5); + pShape->oTextBoxBodyPr->rIns = (int)(12700 * dTextMarginRight + 0.5); + pShape->oTextBoxBodyPr->bIns = (int)(12700 * dTextMarginBottom + 0.5); + } + else + { + if (pPPTShape->m_eType == PPTShapes::sptCTextBox || + pPPTShape->m_eType == PPTShapes::sptCRect || + pPPTShape->m_eType == PPTShapes::sptCRoundRect || + pPPTShape->m_eType == PPTShapes::sptCEllipse || + pPPTShape->m_eType == PPTShapes::sptCWedgeRectCallout || + pPPTShape->m_eType == PPTShapes::sptCWedgeRoundRectCallout || + pPPTShape->m_eType == PPTShapes::sptCWedgeEllipseCallout || + pPPTShape->m_eType == PPTShapes::sptCCloudCallout || + pPPTShape->m_eType == PPTShapes::sptCFlowChartConnector || + pPPTShape->m_eType == PPTShapes::sptCFlowChartProcess) + { + pShape->oTextBoxBodyPr->lIns = 91440; + pShape->oTextBoxBodyPr->tIns = 45720; + pShape->oTextBoxBodyPr->rIns = 91440; + pShape->oTextBoxBodyPr->bIns = 45720; + } + else + { + pShape->oTextBoxBodyPr->lIns = 12700; + pShape->oTextBoxBodyPr->tIns = 12700; + pShape->oTextBoxBodyPr->rIns = 12700; + pShape->oTextBoxBodyPr->bIns = 12700; + } + } } if (!sTextboxStyle.empty()) @@ -2829,7 +2875,7 @@ void CDrawingConverter::ConvertShape(PPTX::Logic::SpTreeElem *elem, XmlUtils::CX { pCNvPr->hidden = true; } - + CSpTreeElemProps oProps; oProps.IsTop = bIsTop; std::wstring strMainPos = GetDrawingMainProps(oNodeShape, oCSSParser, oProps); @@ -2913,11 +2959,11 @@ void CDrawingConverter::ConvertShape(PPTX::Logic::SpTreeElem *elem, XmlUtils::CX } else { - m_pBinaryWriter->m_lXCurShape = 0; - m_pBinaryWriter->m_lYCurShape = 0; + m_pBinaryWriter->m_dXCurShape = 0; + m_pBinaryWriter->m_dYCurShape = 0; - m_pBinaryWriter->m_lCxCurShape = 0; - m_pBinaryWriter->m_lCyCurShape = 0; + m_pBinaryWriter->m_dCxCurShape = 0; + m_pBinaryWriter->m_dCyCurShape = 0; pSpPr->xfrm = new PPTX::Logic::Xfrm(); pSpPr->xfrm->offX = oProps.X; @@ -2970,6 +3016,13 @@ void CDrawingConverter::ConvertShape(PPTX::Logic::SpTreeElem *elem, XmlUtils::CX CheckBrushShape(elem, oNodeShape, pPPTShape); CheckBorderShape(elem, oNodeShape, pPPTShape); + +////test + NSBinPptxRW::CXmlWriter oXml; + elem->toXmlWriter(&oXml); + std::wstring test = oXml.GetXmlString(); + + } } void CDrawingConverter::ConvertWordArtShape(PPTX::Logic::SpTreeElem* elem, XmlUtils::CXmlNode& oNodeShape, CPPTShape* pPPTShape) @@ -3070,7 +3123,7 @@ void CDrawingConverter::ConvertWordArtShape(PPTX::Logic::SpTreeElem* elem, XmlUt std::vector arColorsNew; std::vector arPos; std::vector arPosNew; - std::map arGradMap; + std::map arGradMap; int R = 255, G = 255, B = 255; @@ -3209,13 +3262,13 @@ void CDrawingConverter::ConvertWordArtShape(PPTX::Logic::SpTreeElem* elem, XmlUt XmlMacroReadAttributeBase(oNodeP, L"angle", sAngle); XmlMacroReadAttributeBase(oNodeP, L"colors", sColors); - if (sType.is_init()) + if (sType.is_init()) { - if (*sType == L"gradient") eFillType = etGradFill; - else if (*sType == L"gradientradial") eFillType = etGradFill; - else if (*sType == L"pattern") eFillType = etPattFill; - else if (*sType == L"tile") eFillType = etBlipFill; - else if (*sType == L"frame") eFillType = etBlipFill; + if (*sType == L"gradient") eFillType = etGradFill; + else if (*sType == L"gradientradial") eFillType = etGradFill; + else if (*sType == L"pattern") eFillType = etPattFill; + else if (*sType == L"tile") eFillType = etBlipFill; + else if (*sType == L"frame") eFillType = etBlipFill; } else { @@ -3351,7 +3404,9 @@ void CDrawingConverter::ConvertWordArtShape(PPTX::Logic::SpTreeElem* elem, XmlUt for (size_t i = 0; i < arSplit.size(); i++) { - int p = (int)arSplit[i].find(L" "); + size_t p = arSplit[i].find(L" "); + if (p == std::wstring::npos) + continue; std::wstring strPos = arSplit[i].substr(0, p); std::wstring strColor = arSplit[i].substr(p + 1); @@ -3372,7 +3427,7 @@ void CDrawingConverter::ConvertWordArtShape(PPTX::Logic::SpTreeElem* elem, XmlUt arColors.push_back(oColor); arPos.push_back((int)pos); - arGradMap.insert(std::pair(oColor, (int)pos)); + arGradMap.insert(std::make_pair((int)pos, oColor)); } } } @@ -3421,11 +3476,11 @@ void CDrawingConverter::ConvertWordArtShape(PPTX::Logic::SpTreeElem* elem, XmlUt strRPr += L""; nullable_string sStrokeColor; - nullable_string sStrokeWeight; + nullable oStrokeWeight; nullable_string sStroked; XmlMacroReadAttributeBase(oNodeShape, L"strokecolor", sStrokeColor); - XmlMacroReadAttributeBase(oNodeShape, L"strokeweight", sStrokeWeight); + XmlMacroReadAttributeBase(oNodeShape, L"strokeweight", oStrokeWeight); XmlMacroReadAttributeBase(oNodeShape, L"stroked", sStroked); XmlUtils::CXmlNode oNodeStroke = oNodeShape.ReadNode(L"v:stroke"); @@ -3565,18 +3620,13 @@ void CDrawingConverter::ConvertWordArtShape(PPTX::Logic::SpTreeElem* elem, XmlUt strRPr += L""; //textOutline - double m_dValue = 1; - if (sStrokeWeight.is_init()) + double m_dValuePt = 1; + if (oStrokeWeight.is_init()) { - std::wstring strW(*sStrokeWeight); - int p = (int)strW.find(L"pt"); - if (p >= 0) - strW.erase(p); - - m_dValue = XmlUtils::GetDouble(strW); + m_dValuePt = oStrokeWeight->GetValue(); } - std::wstring strStrokeW = std::to_wstring((int)Pt_To_Emu(m_dValue)); + std::wstring strStrokeW = std::to_wstring((int)Pt_To_Emu(m_dValuePt)); strRPr += L""; smart_ptr pSolid = new PPTX::Logic::SolidFill(); @@ -3894,7 +3944,6 @@ void CDrawingConverter::LoadCoordPos(XmlUtils::CXmlNode& oNode, CShapePtr pShape } } } - pShape->getBaseShape()->m_oPath.SetCoordpos((LONG)pShape->m_dXLogic, (LONG)pShape->m_dYLogic); } @@ -4113,11 +4162,11 @@ std::wstring CDrawingConverter::GetDrawingMainProps(XmlUtils::CXmlNode& oNode, P oProps.Width = width; oProps.Height = height; - m_pBinaryWriter->m_lXCurShape = left; - m_pBinaryWriter->m_lYCurShape = top; + m_pBinaryWriter->m_dXCurShape = left; + m_pBinaryWriter->m_dYCurShape = top; - m_pBinaryWriter->m_lCxCurShape = width; - m_pBinaryWriter->m_lCyCurShape = height; + m_pBinaryWriter->m_dCxCurShape = width; + m_pBinaryWriter->m_dCyCurShape = height; bool bExtendedSize = false; XmlUtils::CXmlNode oNodeShadow = oNode.ReadNode(L"v:shadow"); @@ -4536,8 +4585,14 @@ std::wstring CDrawingConverter::GetDrawingMainProps(XmlUtils::CXmlNode& oNode, P oWriter.EndNode(L"wp14:pctHeight"); oWriter.EndNode(L"wp14:sizeRelV"); } + nullable_string alt_content; + XmlMacroReadAttributeBase(oNode, L"alt", alt_content); - std::wstring strId = L"
"); + for ( size_t i = 0; i < m_arrItems.size(); ++i) + { + if ( m_arrItems[i] ) + { + m_arrItems[i]->toXML(writer); + } + } + writer.WriteString(L""); + } + else + writer.WriteString(L"/>"); } void CPivotCharacterValue::fromXML(XmlUtils::CXmlLiteReader& oReader) { @@ -3432,6 +5311,53 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" m_arrItems.push_back(PPTX::CreatePtrXmlContent(oReader)); } } + XLS::BaseObjectPtr CPivotCharacterValue::toBin() + { + if(m_oCalculated.IsInit() || m_oUnused.IsInit() || m_oCount.IsInit() || !m_arrItems.empty() || m_oCaption.IsInit()) + { + auto ptr(new XLSB::PCDIAString); + auto ptr1(new XLSB::PCDIA); + ptr1->m_source = XLS::BaseObjectPtr{ptr1}; + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oValue.IsInit()) + ptr->st = m_oValue.get(); + else + ptr->st.setSize(0); + if(m_oCaption.IsInit()) + ptr->info.stCaption = m_oCaption.get(); + else + ptr->info.fCaption = false; + if(m_oCalculated.IsInit()) + ptr->info.fFmla = m_oCalculated.get(); + else + ptr->info.fFmla = false; + if(m_oUnused.IsInit()) + ptr->info.fGhost = m_oUnused.get(); + else + ptr->info.fGhost = false; + if(m_oCount.IsInit()) + ptr->info.cIMemProps = m_oCount->GetValue(); + else + ptr->info.cIMemProps = m_arrItems.size(); + if(m_oValue.IsInit()) + ptr->st = m_oValue.get(); + else + ptr->st.setSize(0); + for(auto i:m_arrItems) + ptr->info.rgIMemProps.push_back(i->m_oV.get()); + return objectPtr; + } + else + { + auto ptr(new XLSB::PCDIString); + auto ptr1(new XLSB::PCDI); + ptr1->m_source = XLS::BaseObjectPtr{ptr}; + XLS::BaseObjectPtr objectPtr(ptr1); + if(m_oValue.IsInit()) + ptr->st = m_oValue.get(); + return objectPtr; + } + } void CPivotCharacterValue::fromBin(XLS::BaseObjectPtr& obj) { ReadAttributes(obj); @@ -3491,8 +5417,8 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" if(!ptr->info.stCaption.value().empty()) m_oCaption = ptr->info.stCaption.value(); - - m_oCalculated = ptr->info.fFmla; + if(ptr->info.fFmla) + m_oCalculated = ptr->info.fFmla; m_oUnused = ptr->info.fGhost; m_oCount = ptr->info.cIMemProps; @@ -3525,16 +5451,23 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" WritingStringNullableAttrInt(L"bc", m_oBackColor, m_oBackColor->GetValue()); WritingStringNullableAttrInt(L"fc", m_oForeColor, m_oForeColor->GetValue()); WritingStringNullableAttrInt(L"in", m_oFormatIndex, m_oFormatIndex->GetValue()); - writer.WriteString(L">"); + if(!m_arrItems.empty()) + { + writer.WriteString(L">"); - for ( size_t i = 0; i < m_arrItems.size(); ++i) - { - if ( m_arrItems[i] ) - { - m_arrItems[i]->toXML(writer); - } - } - writer.WriteString(L""); + for ( size_t i = 0; i < m_arrItems.size(); ++i) + { + if ( m_arrItems[i] ) + { + m_arrItems[i]->toXML(writer); + } + } + writer.WriteString(L""); + } + else + { + writer.WriteString(L"/>"); + } } void CPivotErrorValue::fromXML(XmlUtils::CXmlLiteReader& oReader) { @@ -3552,6 +5485,65 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" m_arrItems.push_back(PPTX::CreatePtrXmlContent(oReader)); } } + XLS::BaseObjectPtr CPivotErrorValue::toBin() + { + if(m_oCalculated.IsInit() || m_oUnused.IsInit() || m_oCount.IsInit() || !m_arrItems.empty() || m_oCaption.IsInit()) + { + auto ptr(new XLSB::PCDIAError); + auto ptr1(new XLSB::PCDIA); + ptr1->m_source = XLS::BaseObjectPtr{ptr}; + XLS::BaseObjectPtr objectPtr(ptr1); + if(m_oValue.IsInit()) + { + if (m_oValue == L"#NULL!") ptr->err = 0x00; + else if (m_oValue == L"#DIV/0!") ptr->err = 0x07; + else if (m_oValue == L"#VALUE!") ptr->err = 0x0F; + else if (m_oValue == L"#REF!") ptr->err = 0x17; + else if (m_oValue == L"#NAME?") ptr->err = 0x1D; + else if (m_oValue == L"#NUM!") ptr->err = 0x24; + else if (m_oValue == L"#N/A") ptr->err = 0x2A; + else if (m_oValue == L"#GETTING_DATA") ptr->err = 0x2B; + } + if(m_oCaption.IsInit()) + ptr->info.stCaption = m_oCaption.get(); + else + ptr->info.fCaption = false; + if(m_oCalculated.IsInit()) + ptr->info.fFmla = m_oCalculated.get(); + else + ptr->info.fFmla = false; + if(m_oUnused.IsInit()) + ptr->info.fGhost = m_oUnused.get(); + else + ptr->info.fGhost = false; + if(m_oCount.IsInit()) + ptr->info.cIMemProps = m_oCount->GetValue(); + else + ptr->info.cIMemProps = m_arrItems.size(); + for(auto i:m_arrItems) + ptr->info.rgIMemProps.push_back(i->m_oV.get()); + return objectPtr; + } + else + { + auto ptr(new XLSB::PCDIError); + auto ptr1(new XLSB::PCDI); + ptr1->m_source = XLS::BaseObjectPtr{ptr}; + XLS::BaseObjectPtr objectPtr(ptr1); + if(m_oValue.IsInit()) + { + if (m_oValue == L"#NULL!") ptr->err = 0x00; + else if (m_oValue == L"#DIV/0!") ptr->err = 0x07; + else if (m_oValue == L"#VALUE!") ptr->err = 0x0F; + else if (m_oValue == L"#REF!") ptr->err = 0x17; + else if (m_oValue == L"#NAME?") ptr->err = 0x1D; + else if (m_oValue == L"#NUM!") ptr->err = 0x24; + else if (m_oValue == L"#N/A") ptr->err = 0x2A; + else if (m_oValue == L"#GETTING_DATA") ptr->err = 0x2B; + } + return objectPtr; + } + } void CPivotErrorValue::fromBin(XLS::BaseObjectPtr& obj) { ReadAttributes(obj); @@ -3631,7 +5623,7 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" if(!ptr->info.stCaption.value().empty()) m_oCaption = ptr->info.stCaption.value(); - + if(ptr->info.fFmla) m_oCalculated = ptr->info.fFmla; m_oUnused = ptr->info.fGhost; m_oCount = ptr->info.cIMemProps; @@ -3665,16 +5657,21 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" WritingStringNullableAttrInt(L"bc", m_oBackColor, m_oBackColor->GetValue()); WritingStringNullableAttrInt(L"fc", m_oForeColor, m_oForeColor->GetValue()); WritingStringNullableAttrInt(L"in", m_oFormatIndex, m_oFormatIndex->GetValue()); - writer.WriteString(L">"); + if(!m_arrItems.empty()) + { + writer.WriteString(L">"); - for ( size_t i = 0; i < m_arrItems.size(); ++i) - { - if ( m_arrItems[i] ) - { - m_arrItems[i]->toXML(writer); - } - } - writer.WriteString(L""); + for ( size_t i = 0; i < m_arrItems.size(); ++i) + { + if ( m_arrItems[i] ) + { + m_arrItems[i]->toXML(writer); + } + } + writer.WriteString(L""); + } + else + writer.WriteString(L"/>"); } void CPivotNumericValue::fromXML(XmlUtils::CXmlLiteReader& oReader) { @@ -3696,6 +5693,47 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" { ReadAttributes(obj); } + XLS::BaseObjectPtr CPivotNumericValue::toBin() + { + if(m_oCalculated.IsInit() || m_oUnused.IsInit() || m_oCount.IsInit() || !m_arrItems.empty() || m_oCaption.IsInit()) + { + auto ptr(new XLSB::PCDIANumber); + auto ptr1(new XLSB::PCDIA); + ptr1->m_source = XLS::BaseObjectPtr{ptr}; + XLS::BaseObjectPtr objectPtr(ptr1); + if(m_oCaption.IsInit()) + ptr->info.stCaption = m_oCaption.get(); + else + ptr->info.fCaption = false; + if(m_oCalculated.IsInit()) + ptr->info.fFmla = m_oCalculated.get(); + else + ptr->info.fFmla = false; + if(m_oUnused.IsInit()) + ptr->info.fGhost = m_oUnused.get(); + else + ptr->info.fGhost = false; + if(m_oCount.IsInit()) + ptr->info.cIMemProps = m_oCount->GetValue(); + else + ptr->info.cIMemProps = m_arrItems.size(); + if(m_oValue.IsInit()) + ptr->xnum.data.value = m_oValue.get(); + for(auto i:m_arrItems) + ptr->info.rgIMemProps.push_back(i->m_oV.get()); + return objectPtr; + } + else + { + auto ptr(new XLSB::PCDINumber); + auto ptr1(new XLSB::PCDI); + ptr1->m_source = XLS::BaseObjectPtr{ptr}; + XLS::BaseObjectPtr objectPtr(ptr1); + if(m_oValue.IsInit()) + ptr->xnum.data.value = m_oValue.get(); + return objectPtr; + } + } void CPivotNumericValue::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) { WritingElement_ReadAttributes_Start( oReader ) @@ -3752,8 +5790,8 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" if(!ptr->info.stCaption.value().empty()) m_oCaption = ptr->info.stCaption.value(); - - m_oCalculated = ptr->info.fFmla; + if(ptr->info.fFmla) + m_oCalculated = ptr->info.fFmla; m_oUnused = ptr->info.fGhost; m_oCount = ptr->info.cIMemProps; @@ -3805,6 +5843,50 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" m_arrItems.push_back(PPTX::CreatePtrXmlContent(oReader)); } } + XLS::BaseObjectPtr CPivotDateTimeValue::toBin() + { + if(m_oCalculated.IsInit() || m_oUnused.IsInit() || m_oCount.IsInit() || !m_arrItems.empty() || m_oCaption.IsInit()) + { + auto ptr(new XLSB::PCDIADatetime); + auto ptr1(new XLSB::PCDIA); + ptr1->m_source = XLS::BaseObjectPtr{ptr}; + XLS::BaseObjectPtr objectPtr(ptr1); + if(m_oCaption.IsInit()) + ptr->info.stCaption = m_oCaption.get(); + else + ptr->info.fCaption = false; + if(m_oCalculated.IsInit()) + ptr->info.fFmla = m_oCalculated.get(); + else + ptr->info.fFmla = false; + if(m_oUnused.IsInit()) + ptr->info.fGhost = m_oUnused.get(); + else + ptr->info.fGhost = false; + if(m_oCount.IsInit()) + ptr->info.cIMemProps = m_oCount->GetValue(); + if(m_oValue.IsInit()) + ptr->datetime.fromString(m_oValue->GetValue()); + ptr->datetime.yr += 1900; + ptr->datetime.mon += 1; + for(auto i:m_arrItems) + ptr->info.rgIMemProps.push_back(i->m_oV.get()); + return objectPtr; + } + else + { + auto ptr(new XLSB::PCDIDatetime); + auto ptr1(new XLSB::PCDI); + ptr1->m_source = XLS::BaseObjectPtr{ptr}; + XLS::BaseObjectPtr objectPtr(ptr1); + if(m_oValue.IsInit()) + ptr->datetime.fromString(m_oValue->GetValue()); + ptr->datetime.yr += 1900; + ptr->datetime.mon += 1; + + return objectPtr; + } + } void CPivotDateTimeValue::fromBin(XLS::BaseObjectPtr& obj) { ReadAttributes(obj); @@ -3840,7 +5922,7 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" if(!ptr->info.stCaption.value().empty()) m_oCaption = ptr->info.stCaption.value(); - + if(ptr->info.fFmla) m_oCalculated = ptr->info.fFmla; m_oUnused = ptr->info.fGhost; m_oCount = ptr->info.cIMemProps; @@ -3893,6 +5975,52 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" m_arrItems.push_back(PPTX::CreatePtrXmlContent(oReader)); } } + XLS::BaseObjectPtr CPivotBooleanValue::toBin() + { + if(m_oCalculated.IsInit() || m_oUnused.IsInit() || m_oCount.IsInit() || !m_arrItems.empty() || m_oCaption.IsInit()) + { + auto ptr(new XLSB::PCDIABoolean); + auto ptr1(new XLSB::PCDIA); + ptr1->m_source = XLS::BaseObjectPtr{ptr}; + XLS::BaseObjectPtr objectPtr(ptr1); + if(m_oValue.IsInit()) + ptr->f = m_oValue.get(); + if(m_oCalculated.IsInit()) + ptr->info.fFmla = m_oCalculated.get(); + else + ptr->info.fFmla = false; + if(m_oCaption.IsInit()) + ptr->info.stCaption = m_oCaption.get(); + else + ptr->info.fCaption = false; + if(m_oUnused.IsInit()) + ptr->info.fGhost = m_oUnused.get(); + else + ptr->info.fGhost = false; + if(m_oCount.IsInit()) + ptr->info.cIMemProps = m_oCount->GetValue(); + else + ptr->info.cIMemProps = m_arrItems.size(); + for(auto i:m_arrItems) + ptr->info.rgIMemProps.push_back(i->m_oV.get()); + return objectPtr; + } + else + { + auto ptr(new XLSB::PCDIBoolean); + auto ptr1(new XLSB::PCDI); + ptr1->m_source = XLS::BaseObjectPtr{ptr}; + XLS::BaseObjectPtr objectPtr(ptr1); + nullable_bool boolVal; + if(m_oValue.IsInit()) + boolVal = m_oValue.get(); + if(boolVal.IsInit()) + ptr->f = boolVal.get(); + else + ptr->f = false; + return objectPtr; + } + } void CPivotBooleanValue::fromBin(XLS::BaseObjectPtr& obj) { ReadAttributes(obj); @@ -3928,8 +6056,8 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" if(!ptr->info.stCaption.value().empty()) m_oCaption = ptr->info.stCaption.value(); - - m_oCalculated = ptr->info.fFmla; + if(ptr->info.fFmla) + m_oCalculated = ptr->info.fFmla; m_oUnused = ptr->info.fGhost; m_oCount = ptr->info.cIMemProps; @@ -3961,16 +6089,21 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" WritingStringNullableAttrInt(L"bc", m_oBackColor, m_oBackColor->GetValue()); WritingStringNullableAttrInt(L"fc", m_oForeColor, m_oForeColor->GetValue()); WritingStringNullableAttrInt(L"in", m_oFormatIndex, m_oFormatIndex->GetValue()); - writer.WriteString(L">"); + if(!m_arrItems.empty()) + { + writer.WriteString(L">"); - for ( size_t i = 0; i < m_arrItems.size(); ++i) - { - if ( m_arrItems[i] ) - { - m_arrItems[i]->toXML(writer); - } - } - writer.WriteString(L""); + for ( size_t i = 0; i < m_arrItems.size(); ++i) + { + if ( m_arrItems[i] ) + { + m_arrItems[i]->toXML(writer); + } + } + writer.WriteString(L""); + } + else + writer.WriteString(L"/>"); } void CPivotNoValue::fromXML(XmlUtils::CXmlLiteReader& oReader) { @@ -3992,7 +6125,36 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" { ReadAttributes(obj); } - + XLS::BaseObjectPtr CPivotNoValue::toBin() + { + if(m_arrItems.empty() || m_oBold.IsInit() || m_oItalic.IsInit() || m_oStrike.IsInit() || m_oUnderline.IsInit() || m_oFormatIndex.IsInit() + || m_oBackColor.IsInit() || m_oForeColor.IsInit()) + { + auto ptr(new XLSB::PCDIMissing); + auto ptr1(new XLSB::PCDI); + ptr1->m_source = XLS::BaseObjectPtr{ptr}; + XLS::BaseObjectPtr objectPtr(ptr1); + return objectPtr; + } + else + { + auto ptr(new XLSB::PCDIAMissing); + auto ptr1(new XLSB::PCDIA); + ptr1->m_source = XLS::BaseObjectPtr{ptr}; + XLS::BaseObjectPtr objectPtr(ptr1); + if(m_oCaption.IsInit()) + ptr->info.stCaption = m_oCaption.get(); + if(m_oCalculated.IsInit()) + ptr->info.fFmla = m_oCalculated.get(); + if(m_oUnused.IsInit()) + ptr->info.fGhost = m_oUnused.get(); + if(m_oCount.IsInit()) + ptr->info.cIMemProps = m_oCount->GetValue(); + for(auto i:m_arrItems) + ptr->info.rgIMemProps.push_back(i->m_oV.get()); + return objectPtr; + } + } void CPivotNoValue::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) { WritingElement_ReadAttributes_Start( oReader ) @@ -4044,8 +6206,8 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" { if(!ptr->info.stCaption.value().empty()) m_oCaption = ptr->info.stCaption.value(); - - m_oCalculated = ptr->info.fFmla; + if(ptr->info.fFmla) + m_oCalculated = ptr->info.fFmla; m_oUnused = ptr->info.fGhost; m_oCount = ptr->info.cIMemProps; @@ -4062,8 +6224,13 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" void CPivotCacheSource::toXML(NSStringUtils::CStringBuilder& writer) const { writer.WriteString(L"GetValue()); WritingStringNullableAttrString(L"type", m_oType, m_oType->ToString()); + WritingStringNullableAttrInt(L"connectionId", m_oConnectionId, m_oConnectionId->GetValue()); + if(!m_oWorksheetSource.IsInit() && !m_oConsolidation.IsInit()) + { + writer.WriteString(L"/>"); + return; + } writer.WriteString(L">"); if(m_oWorksheetSource.IsInit()) @@ -4110,6 +6277,34 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" m_oConsolidation = ptr->m_PCDSCONSOL; } } + XLS::BaseObjectPtr CPivotCacheSource::toBin() + { + auto ptr(new XLSB::PCDSOURCE); + XLS::BaseObjectPtr objectPtr(ptr); + auto ptr1(new XLSB::BeginPCDSource); + ptr->m_BrtBeginPCDSource = XLS::BaseObjectPtr{ptr1}; + if(m_oType.IsInit()) + { + if(m_oType == SimpleTypes::Spreadsheet::ESourceCacheType::typeSourceWorksheet) + ptr1->iSrcType = 0x00000000; + if(m_oType == SimpleTypes::Spreadsheet::ESourceCacheType::typeSourceExternal) + ptr1->iSrcType = 0x00000001; + if(m_oType == SimpleTypes::Spreadsheet::ESourceCacheType::typeSourceConsolidation) + ptr1->iSrcType = 0x00000002; + if(m_oType == SimpleTypes::Spreadsheet::ESourceCacheType::typeSourceScenario) + ptr1->iSrcType = 0x00000003; + } + if(m_oConnectionId.IsInit()) + ptr1->dwConnID = m_oConnectionId->GetValue(); + else + ptr1->dwConnID = 0; + + if(m_oWorksheetSource.IsInit()) + ptr->m_PCDSRANGE = m_oWorksheetSource->toBin(); + if(m_oConsolidation.IsInit()) + ptr->m_PCDSCONSOL = m_oConsolidation->toBin(); + return objectPtr; + } void CPivotCacheSource::ReadAttributes(XLS::BaseObjectPtr& obj) { auto ptr = static_cast(obj.get()); @@ -4160,6 +6355,30 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" if ( oReader.IsEmptyNode() ) return; } + XLS::BaseObjectPtr CWorksheetSource::toBin() + { + auto ptr1(new XLSB::PCDSRANGE); + XLS::BaseObjectPtr objectPtr(ptr1); + auto ptr(new XLSB::BeginPCDSRange); + ptr1->m_BrtBeginPCDSRange = XLS::BaseObjectPtr{ptr}; + + if(m_oSheet.IsInit()) + ptr->sheetName = m_oSheet.get(); + else + ptr->fLoadSheet = false; + if(m_oRef.IsInit()) + ptr->range.fromString(m_oRef.get()); + if(m_oName.IsInit()) + ptr->namedRange = m_oName.get(); + else + ptr->fName = false; + if(m_oRid.IsInit()) + ptr->relId.value = m_oRid->GetValue(); + else + ptr->fLoadRelId = false; + ptr->fBuiltIn = false; + return objectPtr; + } void CWorksheetSource::fromBin(XLS::BaseObjectPtr& obj) { auto ptr = static_cast(obj.get()); @@ -4178,8 +6397,8 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" if(!ptr->sheetName.value().empty()) m_oSheet = ptr->sheetName.value(); - if(!ptr->range.toString().empty() && ptr->range.toString() != L"A1") - m_oRef = ptr->range.toString(); + if(!ptr->range.toString().empty() && ptr->range.toString(true, true) != L"A1") + m_oRef = ptr->range.toString(true, true); if(!ptr->namedRange.value().empty()) m_oName = ptr->namedRange.value(); @@ -4233,6 +6452,14 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" } } } + XLS::BaseObjectPtr CPageItemValues::toBin() + { + auto ptr(new XLSB::PCDSCPAGES); + XLS::BaseObjectPtr objectPtr(ptr); + for(auto i:m_arrItems) + ptr->m_arPCDSCPAGE.push_back(i->toBin()); + return objectPtr; + } void CPageItemValues::fromBin(XLS::BaseObjectPtr& obj) { auto ptr = static_cast(obj.get()); @@ -4289,6 +6516,14 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" } } } + XLS::BaseObjectPtr CPageItems::toBin() + { + auto ptr(new XLSB::PCDSCPAGE); + XLS::BaseObjectPtr objectPtr(ptr); + for(auto i:m_arrItems) + ptr->m_arPCDSCPITEM.push_back(i->toBin()); + return objectPtr; + } void CPageItems::fromBin(XLS::BaseObjectPtr& obj) { auto ptr = static_cast(obj.get()); @@ -4323,6 +6558,17 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" if ( oReader.IsEmptyNode() ) return; } + XLS::BaseObjectPtr CPageItem::toBin() + { + auto ptr(new XLSB::PCDSCPITEM); + XLS::BaseObjectPtr objectPtr(ptr); + auto ptr1(new XLSB::BeginPCDSCPItem); + ptr->m_BrtBeginPCDSCPItem = XLS::BaseObjectPtr{ptr1}; + if(m_oName.IsInit()) + ptr1->stName = m_oName.get(); + + return objectPtr; + } void CPageItem::fromBin(XLS::BaseObjectPtr& obj) { auto ptr = static_cast(obj.get()); @@ -4384,6 +6630,14 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" } } } + XLS::BaseObjectPtr CRangeSets::toBin() + { + auto ptr(new XLSB::PCDSCSETS); + XLS::BaseObjectPtr objectPtr(ptr); + for(auto i:m_arrItems) + ptr->m_arPCDSCSET.push_back(i->toBin()); + return objectPtr; + } void CRangeSets::fromBin(XLS::BaseObjectPtr& obj) { auto ptr = static_cast(obj.get()); @@ -4425,6 +6679,43 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" if ( oReader.IsEmptyNode() ) return; } + XLS::BaseObjectPtr CRangeSet::toBin() + { + auto ptr(new XLSB::BeginPCDSCSet); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oSheet.IsInit()) + { + ptr->fLoadSheet = true; + ptr->irstSheet = m_oSheet.get(); + } + else + ptr->fLoadSheet = false; + if(m_oRef.IsInit()) + ptr->rfx = m_oRef.get(); + if(m_oName.IsInit()) + { + ptr->irstName = m_oName.get(); + ptr->fName = true; + } + else + ptr->fName = false; + if(m_oRid.IsInit()) + { + ptr->fLoadRelId = true; + ptr->irstRelId.value = m_oRid->GetValue(); + } + else + ptr->fLoadRelId = false; + if(m_oI1.IsInit()) + ptr->rgiItem[0] = m_oI1->GetValue(); + if(m_oI2.IsInit()) + ptr->rgiItem[1] = m_oI2->GetValue(); + if(m_oI3.IsInit()) + ptr->rgiItem[2] = m_oI3->GetValue(); + if(m_oI4.IsInit()) + ptr->rgiItem[3] = m_oI4->GetValue(); + return objectPtr; + } void CRangeSet::fromBin(XLS::BaseObjectPtr& obj) { auto ptr = static_cast(obj.get()); @@ -4444,7 +6735,7 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" m_oSheet = ptr->irstSheet.value(); if(!ptr->rfx.toString().empty()) - m_oRef = ptr->rfx.toString(); + m_oRef = ptr->rfx.toString(true, true); if(!ptr->irstName.value().empty()) m_oName = ptr->irstName.value(); @@ -4505,6 +6796,20 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" m_oRangeSets = oReader; } } + XLS::BaseObjectPtr CConsolidationSource::toBin() + { + auto ptr(new XLSB::PCDSCONSOL); + XLS::BaseObjectPtr objectPtr(ptr); + auto ptr1(new XLSB::BeginPCDSConsol); + ptr->m_BrtBeginPCDSConsol = XLS::BaseObjectPtr{ptr1}; + if(m_oAutoPage.IsInit()) + ptr1->fAutoPage = m_oAutoPage.get(); + if(m_oPages.IsInit()) + ptr->m_PCDSCPAGES = m_oPages->toBin(); + if(m_oRangeSets.IsInit()) + ptr->m_PCDSCSETS = m_oRangeSets->toBin(); + return objectPtr; + } void CConsolidationSource::fromBin(XLS::BaseObjectPtr& obj) { auto ptr = static_cast(obj.get()); @@ -4577,6 +6882,30 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" m_oGroupItems = oReader; } } + XLS::BaseObjectPtr CFieldGroupProperties::toBin() + { + auto ptr(new XLSB::PCDFGROUP); + XLS::BaseObjectPtr objectPtr(ptr); + + auto ptr1(new XLSB::BeginPCDFGroup); + ptr->m_BrtBeginPCDFGroup = XLS::BaseObjectPtr{ptr1}; + if(m_oPar.IsInit()) + ptr1->ifdbParent = m_oPar->GetValue(); + else + ptr1->ifdbParent = -1; + if(m_oBase.IsInit()) + ptr1->ifdbBase = m_oBase->GetValue(); + else + ptr1->ifdbBase = -1; + + if(m_oDiscretePr.IsInit()) + ptr->m_PCDFGDISCRETE = m_oDiscretePr->toBin(); + if(m_oRangePr.IsInit()) + ptr->m_PCDFGRANGE = m_oRangePr->toBin(); + if(m_oGroupItems.IsInit()) + ptr->m_PCDFGITEMS = m_oGroupItems->toBin(); + return objectPtr; + } void CFieldGroupProperties::fromBin(XLS::BaseObjectPtr& obj) { auto ptr = static_cast(obj.get()); @@ -4618,7 +6947,13 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" CXlsb* xlsb = dynamic_cast(File::m_pMainDocument); if (xlsb) { - XLSB::PivotCacheRecordsStreamPtr pivotCacheRecordsStream(new XLSB::PivotCacheRecordsStream); + BYTE* fileStream = 0; + auto fileReader = xlsb->GetFileReader(oPath, fileStream); + ///todo чтение записей из стрима + m_oPivotCacheRecords.Init(); + m_oPivotCacheRecords->fromBin(fileReader); + delete[] fileStream; + /*XLSB::PivotCacheRecordsStreamPtr pivotCacheRecordsStream(new XLSB::PivotCacheRecordsStream); xlsb->ReadBin(oPath, pivotCacheRecordsStream.get()); @@ -4626,11 +6961,28 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" { if (pivotCacheRecordsStream->m_PIVOTCACHERECORDS != nullptr) m_oPivotCacheRecords = pivotCacheRecordsStream->m_PIVOTCACHERECORDS; - } + }*/ //pivotCacheRecordsStream.reset(); } } + XLS::BaseObjectPtr CPivotCacheRecordsFile::WriteBin() const + { + auto pivotCacheRecordsStream(new XLSB::PivotCacheRecordsStream); + if(m_oPivotCacheRecords.IsInit()) + pivotCacheRecordsStream->m_PIVOTCACHERECORDS = m_oPivotCacheRecords->toBin(); + else if(m_nDataLength > 0 && m_pData) + { + CPivotCacheRecords records; + XmlUtils::CXmlLiteReader reader; + auto wstringData = prepareData(); + reader.FromString(wstringData); + reader.ReadNextNode(); + records.fromXML(reader); + pivotCacheRecordsStream->m_PIVOTCACHERECORDS = records.toBin(); + } + return XLS::BaseObjectPtr{pivotCacheRecordsStream}; + } void CPivotCacheRecordsFile::read(const CPath& oRootPath, const CPath& oPath) { m_oReadPath = oPath; @@ -4657,34 +7009,59 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" } void CPivotCacheRecordsFile::write(const CPath& oPath, const CPath& oDirectory, CContentTypes& oContent) const { - if(m_oPivotCacheRecords.IsInit()) + CXlsb* xlsb = dynamic_cast(File::m_pMainDocument); + if ((xlsb) && (xlsb->m_bWriteToXlsb)) + { + XLS::BaseObjectPtr object = WriteBin(); + xlsb->WriteBin(oPath, object.get()); + } + else { - std::wstring sPath = oPath.GetPath(); - - if (false == m_oPivotCacheRecords->m_strOutputXml.empty()) + if(m_oPivotCacheRecords.IsInit()) { - NSFile::CFileBinary::SaveToFile(sPath, m_oPivotCacheRecords->m_strOutputXml); + std::wstring sPath = oPath.GetPath(); + + if (false == m_oPivotCacheRecords->m_strOutputXml.empty()) + { + NSFile::CFileBinary::SaveToFile(sPath, m_oPivotCacheRecords->m_strOutputXml); + } + else + { + NSStringUtils::CStringBuilder sXml; + sXml.WriteString(L""); + m_oPivotCacheRecords->toXML(sXml); + NSFile::CFileBinary::SaveToFile(sPath, sXml.GetData()); + } + } - else + else if(m_nDataLength > 0 && m_pData) { - NSStringUtils::CStringBuilder sXml; - sXml.WriteString(L""); - m_oPivotCacheRecords->toXML(sXml); - NSFile::CFileBinary::SaveToFile(sPath, sXml.GetData()); + NSFile::CFileBinary oFile; + oFile.CreateFileW(oPath.GetPath()); + oFile.WriteFile(m_pData, m_nDataLength); + oFile.CloseFile(); + } - oContent.Registration( type().OverrideType(), oDirectory, oPath.GetFilename() ); - IFileContainer::Write( oPath, oDirectory, oContent ); } - else if(m_nDataLength > 0 && m_pData) + oContent.Registration( type().OverrideType(), oDirectory, oPath.GetFilename() ); + IFileContainer::Write( oPath, oDirectory, oContent ); + } + const OOX::FileType CPivotCacheRecordsFile::type() const + { + CXlsb* xlsb = dynamic_cast(File::m_pMainDocument); + if ((xlsb) && (xlsb->m_bWriteToXlsb)) { - NSFile::CFileBinary oFile; - oFile.CreateFileW(oPath.GetPath()); - oFile.WriteFile(m_pData, m_nDataLength); - oFile.CloseFile(); - - oContent.Registration( type().OverrideType(), oDirectory, oPath.GetFilename() ); - IFileContainer::Write( oPath, oDirectory, oContent ); + return OOX::SpreadsheetBin::FileTypes::PivotCacheRecordsBin; } + return OOX::Spreadsheet::FileTypes::PivotCacheRecords; + } + std::wstring CPivotCacheRecordsFile::prepareData() const + { + + std::string stringData(reinterpret_cast(m_pData), m_nDataLength); + std::wstring_convert> converter; + + return converter.from_bytes(stringData); } //------------------------------------ void CPivotCacheRecords::toXML(NSStringUtils::CStringBuilder& writer) const @@ -4764,6 +7141,53 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" writer.Clear(); } } + void CPivotCacheRecords::fromBin(XLS::StreamCacheReaderPtr& reader) + { + auto type = reader->getNextRecordType(); + if(type == XLSB::rt_BeginPivotCacheRecords) + { + _UINT32 recordsCount; + { + auto BeginRecords = reader->getNextRecord(XLSB::rt_BeginPivotCacheRecords); + *BeginRecords >> recordsCount; + m_oCount = recordsCount; + } + + NSStringUtils::CStringBuilder writer; + writer.WriteString(L""); + writer.WriteString(L""); + + while(recordsCount > 0) + { + type = reader->getNextRecordType(); + if(type!= XLSB::rt_PCRRecord && type != XLSB::rt_PCRRecordDt) + break; + CPivotCacheRecord xmlItem; + xmlItem.fromBin(reader); + xmlItem.toXML(writer); + recordsCount--; + } + } + } + XLS::BaseObjectPtr CPivotCacheRecords::toBin() + { + auto ptr(new XLSB::PIVOTCACHERECORDS); + XLS::BaseObjectPtr objectPtr(ptr); + auto ptr1(new XLSB::BeginPivotCacheRecords); + ptr1->crecords = m_arrItems.size(); + ptr->m_BrtBeginPivotCacheRecords = XLS::BaseObjectPtr{ptr1}; + for(auto i:m_arrItems) + ptr->m_arPIVOTCACHERECORD.push_back(i->toBin()); + + return objectPtr; + } void CPivotCacheRecords::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) { WritingElement_ReadAttributes_Start( oReader ) @@ -4837,6 +7261,75 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" m_arrItems.push_back(PPTX::CreatePtrXmlContent(oReader)); } } + XLS::BaseObjectPtr CPivotCacheRecord::toBin() + { + auto ptr(new XLSB::PIVOTCACHERECORD); + auto ptr1(new XLSB::PIVOTCACHERECORDDT); + XLS::BaseObjectPtr objectPtr(ptr); + ptr->m_source = XLS::BaseObjectPtr{ptr1}; + for(auto i:m_arrItems) + { + auto ptrPCDIDT(new XLSB::PCDIDT); + + + if(i->getType() == et_x_PivotBooleanValue) + { + auto boolValue = static_cast(i); + ptrPCDIDT->m_source = boolValue->toBin(); + ptr1->m_arPCDIDT.push_back(XLS::BaseObjectPtr{ptrPCDIDT}); + continue; + } + + else if(i->getType() == et_x_PivotDateTimeValue) + { + auto dataValue = static_cast(i); + ptrPCDIDT->m_source = dataValue->toBin(); + ptr1->m_arPCDIDT.push_back(XLS::BaseObjectPtr{ptrPCDIDT}); + continue; + } + + else if(i->getType() == et_x_PivotErrorValue) + { + auto errorValue = static_cast(i); + ptrPCDIDT->m_source = errorValue->toBin(); + ptr1->m_arPCDIDT.push_back(XLS::BaseObjectPtr{ptrPCDIDT}); + continue; + } + + else if(i->getType() == et_x_PivotNoValue) + { + auto noValue = static_cast(i); + ptrPCDIDT->m_source = noValue->toBin(); + ptr1->m_arPCDIDT.push_back(XLS::BaseObjectPtr{ptrPCDIDT}); + continue; + } + + else if(i->getType() == et_x_PivotNumericValue) + { + auto numValue = static_cast(i); + ptrPCDIDT->m_source = numValue->toBin(); + ptr1->m_arPCDIDT.push_back(XLS::BaseObjectPtr{ptrPCDIDT}); + continue; + } + + else if(i->getType() == et_x_PivotCharacterValue) + { + auto charValue = static_cast(i); + ptrPCDIDT->m_source = charValue->toBin(); + ptr1->m_arPCDIDT.push_back(XLS::BaseObjectPtr{ptrPCDIDT}); + continue; + } + + else if(i->getType() == et_x_SharedItemsIndex) + { + auto itemIndex = static_cast(i); + ptrPCDIDT->m_source = itemIndex->toBinItemIndex(); + ptr1->m_arPCDIDT.push_back(XLS::BaseObjectPtr{ptrPCDIDT}); + continue; + } + } + return objectPtr; + } void CPivotCacheRecord::fromBin(XLS::BaseObjectPtr& obj) { auto ptr = static_cast(obj.get()); @@ -4927,6 +7420,154 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" } } } + void CPivotCacheRecord::fromBin(XLS::StreamCacheReaderPtr& reader) + { + auto recordType = reader->getNextRecordType(); + if(recordType == XLSB::rt_PCRRecordDt) + { + reader->SkipRecord(false); + recordType = reader->getNextRecordType(); + while(1) + { + switch(recordType) + { + case XLSB::rt_PCDIMissing: + { + reader->SkipRecord(false); + recordType = reader->getNextRecordType(); + m_arrItems.push_back(new CPivotNoValue); + break; + } + case XLSB::rt_PCDINumber: + { + auto record = reader->getNextRecord(XLSB::rt_PCDINumber); + XLS::Xnum number; + *record >>number; + auto numValue = new CPivotNumericValue; + numValue->m_oValue = number.data.value; + m_arrItems.push_back(numValue); + break; + } + case XLSB::rt_PCDIBoolean: + { + auto record = reader->getNextRecord(XLSB::rt_PCDIBoolean); + BYTE boolval; + *record >>boolval; + auto BoleanValue = new CPivotBooleanValue; + BoleanValue->m_oValue = boolval; + m_arrItems.push_back(BoleanValue); + break; + } + case XLSB::rt_PCDIString: + { + auto record = reader->getNextRecord(XLSB::rt_PCDIString); + XLSB::XLWideString StringVal; + *record >>StringVal; + auto CharacterValue = new CPivotCharacterValue; + CharacterValue->m_oValue = StringVal; + m_arrItems.push_back(CharacterValue); + break; + } + case XLSB::rt_PCDIDatetime: + { + auto record = reader->getNextRecord(XLSB::rt_PCDIDatetime); + XLSB::PCDIDateTime DateVal; + *record >>DateVal; + auto DatetimeValue = new CPivotDateTimeValue; + DatetimeValue->m_oValue = DateVal.value(); + m_arrItems.push_back(DatetimeValue); + break; + } + case XLSB::rt_PCDIIndex: + { + auto record = reader->getNextRecord(XLSB::rt_PCDIIndex); + _UINT32 iitem; + *record >>iitem; + auto IndexValue = new CSharedItemsIndex; + IndexValue->m_oV = iitem; + m_arrItems.push_back(IndexValue); + break; + } + case XLSB::rt_PCDIError: + { + auto record = reader->getNextRecord(XLSB::rt_PCDIError); + BYTE erorIndex; + *record >>erorIndex; + auto ErrValue = new CPivotErrorValue; + switch(erorIndex) + { + case 0x00: ErrValue->m_oValue = L"#NULL!"; break; + case 0x07: ErrValue->m_oValue = L"#DIV/0!"; break; + case 0x0F: ErrValue->m_oValue = L"#VALUE!"; break; + case 0x17: ErrValue->m_oValue = L"#REF!"; break; + case 0x1D: ErrValue->m_oValue = L"#NAME?"; break; + case 0x24: ErrValue->m_oValue = L"#NUM!"; break; + case 0x2A: ErrValue->m_oValue = L"#N/A"; break; + case 0x2B: ErrValue->m_oValue = L"#GETTING_DATA"; break; + } + m_arrItems.push_back(ErrValue); + break; + } + default: + return; + } + recordType = reader->getNextRecordType(); + } + } + else if(recordType == XLSB::rt_PCRRecord) + { + auto record = reader->getNextRecord(XLSB::rt_PCRRecord); + if (record->checkFitReadSafe(1)) + { + auto arrPivotCacheRecordType = record->getGlobalWorkbookInfo()->pivotCacheRecordType.find(record->getGlobalWorkbookInfo()->currentPivotCacheRecord - 1); + if (arrPivotCacheRecordType != record->getGlobalWorkbookInfo()->pivotCacheRecordType.end()) + { + for(const auto& item : arrPivotCacheRecordType->second) + switch (item) + { + case XLS::typePCDIIndex: + { + _UINT32 iitem; + *record >>iitem; + auto IndexValue = new CSharedItemsIndex; + IndexValue->m_oV = iitem; + m_arrItems.push_back(IndexValue); + break; + } + case XLS::typePCDINumber: + { + XLS::Xnum number; + *record >>number; + auto numValue = new CPivotNumericValue; + numValue->m_oValue = number.data.value; + m_arrItems.push_back(numValue); + break; + } + case XLS::typePCDIDatetime: + { + XLSB::PCDIDateTime DateVal; + *record >>DateVal; + auto DatetimeValue = new CPivotDateTimeValue; + DatetimeValue->m_oValue = DateVal.value(); + m_arrItems.push_back(DatetimeValue); + break; + } + case XLS::typePCDIString: + { + XLSB::XLWideString StringVal; + *record >>StringVal; + auto CharacterValue = new CPivotCharacterValue; + CharacterValue->m_oValue = StringVal; + m_arrItems.push_back(CharacterValue); + break; + } + default: + break; + } + } + } + } + } void CSharedItemsIndex::ReadAttributes(XLS::BaseObjectPtr& obj) { if(obj->get_type() == XLS::typePCDIIndex) @@ -4948,5 +7589,23 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" } } } + + XLS::BaseObjectPtr CSharedItemsIndex::toBinItemIndex() + { + auto ptr(new XLSB::PCDIIndex); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oV.IsInit()) + ptr->iitem = m_oV->GetValue(); + return objectPtr; + } + + XLS::BaseObjectPtr CSharedItemsIndex::toBinPrfItem() + { + auto ptr(new XLSB::BeginPRFItem); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oV.IsInit()) + ptr->iitem = m_oV->GetValue(); + return objectPtr; + } } //Spreadsheet } // namespace OOX diff --git a/OOXML/XlsxFormat/RichData/RdRichValue.cpp b/OOXML/XlsxFormat/RichData/RdRichValue.cpp new file mode 100644 index 00000000000..c0a11484934 --- /dev/null +++ b/OOXML/XlsxFormat/RichData/RdRichValue.cpp @@ -0,0 +1,233 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#include "RdRichValue.h" + +#include "../FileTypes_Spreadsheet.h" + +#include "../../Common/SimpleTypes_Shared.h" +#include "../../Common/SimpleTypes_Spreadsheet.h" + +#include "../../DocxFormat/Drawing/DrawingExt.h" +#include "../../../DesktopEditor/common/File.h" + +#include "../../Binary/Presentation/XmlWriter.h" +#include "../../Binary/Presentation/BinaryFileReaderWriter.h" + +namespace OOX +{ +namespace Spreadsheet +{ + CRdRichValueFile::CRdRichValueFile(OOX::Document* pMain) : OOX::File(pMain) + { + } + CRdRichValueFile::CRdRichValueFile(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath) : OOX::File(pMain) + { + read(oRootPath, oPath); + } + CRdRichValueFile::~CRdRichValueFile() + { + } + void CRdRichValueFile::read(const CPath& oPath) + { + //don't use this. use read(const CPath& oRootPath, const CPath& oFilePath) + CPath oRootPath; + read(oRootPath, oPath); + } + const OOX::FileType CRdRichValueFile::type() const + { + return OOX::Spreadsheet::FileTypes::RdRichValue; + } + const CPath CRdRichValueFile::DefaultDirectory() const + { + return type().DefaultDirectory(); + } + const CPath CRdRichValueFile::DefaultFileName() const + { + return type().DefaultFileName(); + } + const CPath& CRdRichValueFile::GetReadPath() + { + return m_oReadPath; + } + void CRdRichValueFile::read(const CPath& oRootPath, const CPath& oPath) + { + m_oReadPath = oPath; + + XmlUtils::CXmlLiteReader oReader; + + if (!oReader.FromFile(oPath.GetPath())) + return; + + if (!oReader.ReadNextNode()) + return; + + //m_oMetadata = oReader; + } + void CRdRichValueFile::write(const CPath& oPath, const CPath& oDirectory, CContentTypes& oContent) const + { + //if (false == m_oMetadata.IsInit()) return; + + NSStringUtils::CStringBuilder sXml; + + sXml.WriteString(L""); + //m_oMetadata->toXML(sXml); + + std::wstring sPath = oPath.GetPath(); + NSFile::CFileBinary::SaveToFile(sPath, sXml.GetData()); + + oContent.Registration(type().OverrideType(), oDirectory, oPath.GetFilename()); + } +//--------------------------------------------------------------------------------------------------------------------------- + CRdRichValueStructureFile::CRdRichValueStructureFile(OOX::Document* pMain) : OOX::File(pMain) + { + } + CRdRichValueStructureFile::CRdRichValueStructureFile(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath) : OOX::File(pMain) + { + read(oRootPath, oPath); + } + CRdRichValueStructureFile::~CRdRichValueStructureFile() + { + } + void CRdRichValueStructureFile::read(const CPath& oPath) + { + //don't use this. use read(const CPath& oRootPath, const CPath& oFilePath) + CPath oRootPath; + read(oRootPath, oPath); + } + const OOX::FileType CRdRichValueStructureFile::type() const + { + return OOX::Spreadsheet::FileTypes::RdRichValueStructure; + } + const CPath CRdRichValueStructureFile::DefaultDirectory() const + { + return type().DefaultDirectory(); + } + const CPath CRdRichValueStructureFile::DefaultFileName() const + { + return type().DefaultFileName(); + } + const CPath& CRdRichValueStructureFile::GetReadPath() + { + return m_oReadPath; + } + void CRdRichValueStructureFile::read(const CPath& oRootPath, const CPath& oPath) + { + m_oReadPath = oPath; + + XmlUtils::CXmlLiteReader oReader; + + if (!oReader.FromFile(oPath.GetPath())) + return; + + if (!oReader.ReadNextNode()) + return; + + //m_oMetadata = oReader; + } + void CRdRichValueStructureFile::write(const CPath& oPath, const CPath& oDirectory, CContentTypes& oContent) const + { + //if (false == m_oMetadata.IsInit()) return; + + NSStringUtils::CStringBuilder sXml; + + sXml.WriteString(L""); + //m_oMetadata->toXML(sXml); + + std::wstring sPath = oPath.GetPath(); + NSFile::CFileBinary::SaveToFile(sPath, sXml.GetData()); + + oContent.Registration(type().OverrideType(), oDirectory, oPath.GetFilename()); + } +//--------------------------------------------------------------------------------------------------------------------------- + CRdRichValueTypesFile::CRdRichValueTypesFile(OOX::Document* pMain) : OOX::File(pMain) + { + } + CRdRichValueTypesFile::CRdRichValueTypesFile(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath) : OOX::File(pMain) + { + read(oRootPath, oPath); + } + CRdRichValueTypesFile::~CRdRichValueTypesFile() + { + } + void CRdRichValueTypesFile::read(const CPath& oPath) + { + //don't use this. use read(const CPath& oRootPath, const CPath& oFilePath) + CPath oRootPath; + read(oRootPath, oPath); + } + const OOX::FileType CRdRichValueTypesFile::type() const + { + return OOX::Spreadsheet::FileTypes::RdRichValueTypes; + } + const CPath CRdRichValueTypesFile::DefaultDirectory() const + { + return type().DefaultDirectory(); + } + const CPath CRdRichValueTypesFile::DefaultFileName() const + { + return type().DefaultFileName(); + } + const CPath& CRdRichValueTypesFile::GetReadPath() + { + return m_oReadPath; + } + void CRdRichValueTypesFile::read(const CPath& oRootPath, const CPath& oPath) + { + m_oReadPath = oPath; + + XmlUtils::CXmlLiteReader oReader; + + if (!oReader.FromFile(oPath.GetPath())) + return; + + if (!oReader.ReadNextNode()) + return; + + //m_oMetadata = oReader; + } + void CRdRichValueTypesFile::write(const CPath& oPath, const CPath& oDirectory, CContentTypes& oContent) const + { + //if (false == m_oMetadata.IsInit()) return; + + NSStringUtils::CStringBuilder sXml; + + sXml.WriteString(L""); + //m_oMetadata->toXML(sXml); + + std::wstring sPath = oPath.GetPath(); + NSFile::CFileBinary::SaveToFile(sPath, sXml.GetData()); + + oContent.Registration(type().OverrideType(), oDirectory, oPath.GetFilename()); + } +} +} + diff --git a/OOXML/XlsxFormat/RichData/RdRichValue.h b/OOXML/XlsxFormat/RichData/RdRichValue.h new file mode 100644 index 00000000000..1b94966a352 --- /dev/null +++ b/OOXML/XlsxFormat/RichData/RdRichValue.h @@ -0,0 +1,108 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#pragma once + +#include "../Table/Autofilter.h" +#include "../../DocxFormat/IFileContainer.h" +#include "../../Common/SimpleTypes_Spreadsheet.h" + +namespace OOX +{ + namespace Spreadsheet + { + class CRdRichValueFile : public OOX::File + { + public: + CRdRichValueFile(OOX::Document* pMain); + CRdRichValueFile(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath); + virtual ~CRdRichValueFile(); + + virtual void read(const CPath& oPath); + virtual void read(const CPath& oRootPath, const CPath& oPath); + + virtual void write(const CPath& oPath, const CPath& oDirectory, CContentTypes& oContent) const; + virtual const OOX::FileType type() const; + + virtual const CPath DefaultDirectory() const; + virtual const CPath DefaultFileName() const; + + const CPath& GetReadPath(); + + //nullable m_oTimelines; + private: + CPath m_oReadPath; + }; +//------------------------------------------------------------------------------------------------------------------------ + class CRdRichValueStructureFile : public OOX::File + { + public: + CRdRichValueStructureFile(OOX::Document* pMain); + CRdRichValueStructureFile(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath); + virtual ~CRdRichValueStructureFile(); + + virtual void read(const CPath& oPath); + virtual void read(const CPath& oRootPath, const CPath& oPath); + + virtual void write(const CPath& oPath, const CPath& oDirectory, CContentTypes& oContent) const; + virtual const OOX::FileType type() const; + + virtual const CPath DefaultDirectory() const; + virtual const CPath DefaultFileName() const; + + const CPath& GetReadPath(); + + private: + CPath m_oReadPath; + }; +//------------------------------------------------------------------------------------------------------------------------ + class CRdRichValueTypesFile : public OOX::File + { + public: + CRdRichValueTypesFile(OOX::Document* pMain); + CRdRichValueTypesFile(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath); + virtual ~CRdRichValueTypesFile(); + + virtual void read(const CPath& oPath); + virtual void read(const CPath& oRootPath, const CPath& oPath); + + virtual void write(const CPath& oPath, const CPath& oDirectory, CContentTypes& oContent) const; + virtual const OOX::FileType type() const; + + virtual const CPath DefaultDirectory() const; + virtual const CPath DefaultFileName() const; + + const CPath& GetReadPath(); + private: + CPath m_oReadPath; + }; + } //Spreadsheet +} // namespace OOX diff --git a/OOXML/XlsxFormat/SharedStrings/PhoneticPr.cpp b/OOXML/XlsxFormat/SharedStrings/PhoneticPr.cpp index ec4a8136fd0..1f0b6bae304 100644 --- a/OOXML/XlsxFormat/SharedStrings/PhoneticPr.cpp +++ b/OOXML/XlsxFormat/SharedStrings/PhoneticPr.cpp @@ -67,6 +67,53 @@ namespace OOX { ReadAttributes(obj); } + void CPhonetic::toBin(XLS::BiffStructure* obj) + { + auto ptr = static_cast(obj); + if(m_oAlignment.IsInit()) + { + if(m_oAlignment == SimpleTypes::Spreadsheet::phoneticalignmentNoControl) + { + ptr->alcH = 0; + } + else if(m_oAlignment == SimpleTypes::Spreadsheet::phoneticalignmentLeft) + { + ptr->alcH = 1; + } + else if(m_oAlignment == SimpleTypes::Spreadsheet::phoneticalignmentCenter) + { + ptr->alcH = 2; + } + else if(m_oAlignment == SimpleTypes::Spreadsheet::phoneticalignmentDistributed) + { + ptr->alcH = 3; + } + } + if(m_oType.IsInit()) + { + if(m_oType == SimpleTypes::Spreadsheet::phonetictypeHalfwidthKatakana) + { + ptr->phType = 0; + } + else if(m_oType == SimpleTypes::Spreadsheet::phonetictypeFullwidthKatakana) + { + ptr->phType = 1; + } + else if(m_oType == SimpleTypes::Spreadsheet::phonetictypeHiragana) + { + ptr->phType = 2; + } + else if(m_oType == SimpleTypes::Spreadsheet::phonetictypeNoConversion) + { + ptr->phType = 3; + } + } + + if(m_oFontId.IsInit()) + { + ptr->ifnt = m_oFontId->GetValue(); + } + } EElementType CPhonetic::getType () const { return et_x_PhoneticPr; @@ -167,6 +214,20 @@ namespace OOX m_arrItems.push_back(ptr); ReadAttributes(obj); } + std::wstring CRPh::toBin(XLS::BiffStructure* obj) + { + auto ptr = static_cast(obj); + std::wstring result; + if(!m_arrItems.empty()) + { + result = m_arrItems.back()->ToString(); + } + if(m_oEb.IsInit()) + ptr->ichMom = m_oEb->GetValue(); + if(m_oSb.IsInit()) + ptr->ichFirst = m_oSb->GetValue(); + return result; + } EElementType CRPh::getType () const { return et_x_rPh; diff --git a/OOXML/XlsxFormat/SharedStrings/PhoneticPr.h b/OOXML/XlsxFormat/SharedStrings/PhoneticPr.h index 5185461cc10..2c63de3ae1b 100644 --- a/OOXML/XlsxFormat/SharedStrings/PhoneticPr.h +++ b/OOXML/XlsxFormat/SharedStrings/PhoneticPr.h @@ -62,6 +62,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BiffStructure& obj); + void toBin(XLS::BiffStructure* obj); virtual EElementType getType () const; private: @@ -88,6 +89,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BiffStructure& obj, std::wstring& str); + std::wstring toBin(XLS::BiffStructure* obj); virtual EElementType getType () const; private: diff --git a/OOXML/XlsxFormat/SharedStrings/Run.h b/OOXML/XlsxFormat/SharedStrings/Run.h index 3f6e9831222..6cd18133c59 100644 --- a/OOXML/XlsxFormat/SharedStrings/Run.h +++ b/OOXML/XlsxFormat/SharedStrings/Run.h @@ -53,6 +53,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(std::wstring& str, unsigned short fontindex); + std::wstring toBin(unsigned short &fontindex); virtual EElementType getType () const; private: diff --git a/OOXML/XlsxFormat/SharedStrings/SharedStrings.cpp b/OOXML/XlsxFormat/SharedStrings/SharedStrings.cpp index a47ea14445e..136a189d72b 100644 --- a/OOXML/XlsxFormat/SharedStrings/SharedStrings.cpp +++ b/OOXML/XlsxFormat/SharedStrings/SharedStrings.cpp @@ -38,6 +38,8 @@ #include "../../XlsbFormat/Biff12_unions/SHAREDSTRINGS.h" #include "../../XlsbFormat/Biff12_records/SSTItem.h" +#include "../../Binary/XlsbFormat/FileTypes_SpreadsheetBin.h" + namespace OOX { namespace Spreadsheet @@ -102,6 +104,25 @@ namespace OOX } } + XLS::BaseObjectPtr CSharedStrings::WriteBin() const + { + XLSB::SharedStringsStreamPtr sharedStringsStream(new XLSB::SharedStringsStream); + auto ptr(new XLSB::SHAREDSTRINGS); + XLS::BaseObjectPtr objectPtr(ptr); + + auto atribPtr(new XLSB::BeginSst); + ptr->m_BrtBeginSst = XLS::BaseObjectPtr{atribPtr}; + if(m_oCount.IsInit()) + atribPtr->cstTotal = m_oCount->GetValue(); + if(m_oUniqueCount.IsInit()) + atribPtr->cstUnique = m_oUniqueCount->GetValue(); + + for(auto i:m_arrItems) + { + ptr->m_arBrtSSTItem.push_back(i->toBin()); + } + return objectPtr; + } void CSharedStrings::read(const CPath& oPath) { //don't use this. use read(const CPath& oRootPath, const CPath& oFilePath) @@ -161,25 +182,38 @@ namespace OOX } void CSharedStrings::write(const CPath& oPath, const CPath& oDirectory, CContentTypes& oContent) const { - NSStringUtils::CStringBuilder writer; - writer.WriteString(_T("GetValue()); - WritingStringNullableAttrInt(L"uniqueCount", m_oUniqueCount, m_oUniqueCount->GetValue()); - writer.WriteString(_T(">")); - - for(size_t i = 0; i < m_arrItems.size(); i++) + CXlsb* xlsb = dynamic_cast(File::m_pMainDocument); + if ((xlsb) && (xlsb->m_bWriteToXlsb)) { - m_arrItems[i]->toXML(writer); + XLS::BaseObjectPtr object = WriteBin(); + xlsb->WriteBin(oPath, object.get()); } + else + { + NSStringUtils::CStringBuilder writer; + writer.WriteString(_T("GetValue()); + WritingStringNullableAttrInt(L"uniqueCount", m_oUniqueCount, m_oUniqueCount->GetValue()); + writer.WriteString(_T(">")); - writer.WriteString(_T("")); - std::wstring sPath = oPath.GetPath(); - NSFile::CFileBinary::SaveToFile(sPath.c_str(), writer.GetData()); + for(size_t i = 0; i < m_arrItems.size(); i++) + { + m_arrItems[i]->toXML(writer); + } + writer.WriteString(_T("")); + std::wstring sPath = oPath.GetPath(); + NSFile::CFileBinary::SaveToFile(sPath.c_str(), writer.GetData()); + } oContent.Registration( type().OverrideType(), oDirectory, oPath.GetFilename() ); } const OOX::FileType CSharedStrings::type() const { + CXlsb* xlsb = dynamic_cast(File::m_pMainDocument); + if ((xlsb) && (xlsb->m_bWriteToXlsb)) + { + return OOX::SpreadsheetBin::FileTypes::SharedStringsBin; + } return OOX::Spreadsheet::FileTypes::SharedStrings; } const CPath CSharedStrings::DefaultDirectory() const @@ -188,7 +222,18 @@ namespace OOX } const CPath CSharedStrings::DefaultFileName() const { - return type().DefaultFileName(); + CXlsb* xlsb = dynamic_cast(File::m_pMainDocument); + if ((xlsb) && (xlsb->m_bWriteToXlsb)) + { + CPath name = type().DefaultFileName(); + + name.SetExtention(L"bin"); + return name; + } + else + { + return type().DefaultFileName(); + } } const CPath& CSharedStrings::GetReadPath() { diff --git a/OOXML/XlsxFormat/SharedStrings/SharedStrings.h b/OOXML/XlsxFormat/SharedStrings/SharedStrings.h index 19e99b05b7a..e8c7b7d513f 100644 --- a/OOXML/XlsxFormat/SharedStrings/SharedStrings.h +++ b/OOXML/XlsxFormat/SharedStrings/SharedStrings.h @@ -54,6 +54,7 @@ namespace OOX virtual ~CSharedStrings(); void readBin(const CPath& oPath); + XLS::BaseObjectPtr WriteBin() const; virtual void read(const CPath& oPath); virtual void read(const CPath& oRootPath, const CPath& oPath); virtual void write(const CPath& oPath, const CPath& oDirectory, CContentTypes& oContent) const; diff --git a/OOXML/XlsxFormat/SharedStrings/Si.cpp b/OOXML/XlsxFormat/SharedStrings/Si.cpp index d41c636df46..e3335860a23 100644 --- a/OOXML/XlsxFormat/SharedStrings/Si.cpp +++ b/OOXML/XlsxFormat/SharedStrings/Si.cpp @@ -130,6 +130,61 @@ namespace OOX m_arrItems.push_back( pItem ); } } + XLS::BaseObjectPtr CSi::toBin() const + { + auto sString(new XLSB::SSTItem); + XLS::BaseObjectPtr objectPtr(sString); + auto ptr = &sString->richStr; + ptr->fExtStr = false; + ptr->fRichStr = false; + for(auto i = 0; i < m_arrItems.size(); i++) + { + + + if(m_arrItems[i]->getType() == OOX::et_x_t) + { + auto text = static_cast(m_arrItems[i]); + ptr->str = text->ToString(); + continue; + } + + if(m_arrItems[i]->getType() == OOX::et_x_r) + { + auto crunPtr = static_cast(m_arrItems[i]); + ptr->fRichStr = true; + USHORT ind = 0; + XLSB::StrRun run; + run.ich = ptr->str.value().size(); + ptr->str = ptr->str.value() + crunPtr->toBin(ind); + run.ifnt = ind; + ptr->rgsStrRun.push_back(run); + continue; + } + auto phonPtr = static_cast(m_arrItems[i]); + if(phonPtr) + { + ptr->fExtStr = true; + ptr->phoneticStr = L""; + XLSB::PhRun phRun; + phonPtr->toBin(&phRun); + if(i < m_arrItems.size() - 1) + { + auto ph = static_cast(m_arrItems[i+1]); + if(ph) + { + auto phoneticStr = ph->toBin(&phRun); + if(!phoneticStr.empty()) + ptr->phoneticStr = phoneticStr; + } + i++; + } + + ptr->rgsPhRun.push_back(phRun); + } + } + + return objectPtr; + } void CSi::fromBin(XLS::BiffStructure& obj, bool flagIsComment) { auto ptr = static_cast(&obj); diff --git a/OOXML/XlsxFormat/SharedStrings/Si.h b/OOXML/XlsxFormat/SharedStrings/Si.h index d641677d11b..efdc78f6ce7 100644 --- a/OOXML/XlsxFormat/SharedStrings/Si.h +++ b/OOXML/XlsxFormat/SharedStrings/Si.h @@ -63,6 +63,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BiffStructure& obj, bool flagIsComment = false); + XLS::BaseObjectPtr toBin() const; void fromXLSBExt (NSBinPptxRW::CBinaryFileReader& oStream); void toXLSBExt (NSBinPptxRW::CXlsbBinaryWriter& oStream); diff --git a/OOXML/XlsxFormat/SharedStrings/Text.cpp b/OOXML/XlsxFormat/SharedStrings/Text.cpp index 8e892f7e7c4..26d69a53d12 100644 --- a/OOXML/XlsxFormat/SharedStrings/Text.cpp +++ b/OOXML/XlsxFormat/SharedStrings/Text.cpp @@ -211,20 +211,22 @@ namespace OOX void CText::toXML(NSStringUtils::CStringBuilder& writer) const { writer.WriteString(_T("")); - writer.WriteEncodeXmlStringHHHH(m_sText); + if (!m_sText.empty()) + writer.WriteEncodeXmlStringHHHH(m_sText); writer.WriteString(_T("
")); } void CText::toXML2(NSStringUtils::CStringBuilder& writer, const wchar_t* name) const { writer.WriteString(_T("<")); writer.WriteString(name); - if(std::wstring::npos != m_sText.find(' ') || std::wstring::npos != m_sText.find('\n')) + if ((std::wstring::npos != m_sText.find('\x20') || std::wstring::npos != m_sText.find('\n') || std::wstring::npos != m_sText.find('\x9'))) writer.WriteString(_T(" xml:space=\"preserve\"")); writer.WriteString(_T(">")); - writer.WriteEncodeXmlStringHHHH(m_sText); + if (!m_sText.empty()) + writer.WriteEncodeXmlStringHHHH(m_sText); writer.WriteString(_T("")); @@ -297,7 +299,7 @@ namespace OOX } void CText::trimString(std::wstring& sVal, SimpleTypes::EXmlSpace eSpace) { - NSStringExt::Replace(sVal, L"\t", L""); + //NSStringExt::Replace(sVal, L"\t", L""); if(SimpleTypes::xmlspacePreserve != eSpace) { //trim ' ', '\r', '\n' @@ -308,7 +310,7 @@ namespace OOX for(int i = nStartIndex; i < nLength; ++i) { wchar_t cElem = sVal[i]; - if(' ' == cElem || '\n' == cElem || '\r' == cElem) + if(' ' == cElem || '\n' == cElem || '\r' == cElem || '\t' == cElem) nStartIndex++; else break; diff --git a/OOXML/XlsxFormat/SharedStrings/XlsxRun.cpp b/OOXML/XlsxFormat/SharedStrings/XlsxRun.cpp index 53509a026a6..f9bfb95c114 100644 --- a/OOXML/XlsxFormat/SharedStrings/XlsxRun.cpp +++ b/OOXML/XlsxFormat/SharedStrings/XlsxRun.cpp @@ -97,6 +97,20 @@ namespace OOX m_oRPr->m_nFontIndex.Init(); m_oRPr->m_nFontIndex = fontindex; } + std::wstring CRun::toBin(unsigned short &fontindex) + { + if(m_oRPr.IsInit()) + { + if(m_oRPr->m_nFontIndex.IsInit()) + fontindex = m_oRPr->m_nFontIndex->GetValue(); + } + if(!m_arrItems.empty()) + { + auto textPtr = m_arrItems.back(); + return textPtr->ToString(); + } + return L""; + } EElementType CRun::getType () const { return et_x_r; diff --git a/OOXML/XlsxFormat/Slicer/Slicer.cpp b/OOXML/XlsxFormat/Slicer/Slicer.cpp index 4ffeb31420a..915cd4ad9c5 100644 --- a/OOXML/XlsxFormat/Slicer/Slicer.cpp +++ b/OOXML/XlsxFormat/Slicer/Slicer.cpp @@ -38,6 +38,8 @@ #include "../../DocxFormat/Drawing/DrawingExt.h" +#include "../../Binary/XlsbFormat/FileTypes_SpreadsheetBin.h" + namespace OOX { namespace Spreadsheet @@ -72,6 +74,14 @@ void CSlicers::fromBin(XLS::BaseObjectPtr& obj) m_oSlicer.push_back(CSlicer(slicer)); } } +XLS::BaseObjectPtr CSlicers::toBin() +{ + auto ptr(new XLSB::SLICERS); + XLS::BaseObjectPtr objectPtr(ptr); + for(auto i:m_oSlicer) + ptr->m_arSLICER.push_back(i.toBin()); + return objectPtr; +} void CSlicers::toXML(NSStringUtils::CStringBuilder& writer, const std::wstring& sName) const { writer.StartNode(sName); @@ -170,6 +180,62 @@ void CSlicer::fromBin(XLS::BaseObjectPtr& obj) ReadAttributes(ptr->m_BrtBeginSlicer); } } +XLS::BaseObjectPtr CSlicer::toBin() +{ + auto ptr1(new XLSB::SLICER); + XLS::BaseObjectPtr objectPtr(ptr1); + auto ptr(new XLSB::BeginSlicer); + ptr1->m_BrtBeginSlicer = XLS::BaseObjectPtr{ptr}; + + if(m_oStartItem.IsInit()) + ptr->dwStartSlicerItem = m_oStartItem.get(); + else + ptr->dwStartSlicerItem = 0; + if(m_oColumnCount.IsInit()) + ptr->dwColumnCount = m_oColumnCount.get(); + else + ptr->dwColumnCount = 1; + if(m_oShowCaption.IsInit()) + ptr->fCaptionVisible = m_oShowCaption.get(); + if(m_oLevel.IsInit()) + ptr->dwLevel = m_oLevel.get(); + else + ptr->dwLevel = 0; + if(m_oLockedPosition.IsInit()) + ptr->fLockedPosition = m_oLockedPosition.get(); + else + ptr->fLockedPosition = false; + if(m_oRowHeight.IsInit()) + ptr->dxRowHeight = m_oRowHeight.get(); + + if(m_oName.IsInit()) + ptr->stName = m_oName.get(); + else if(m_oUid.IsInit()) + ptr->stName = m_oUid.get(); + else + ptr->stName = 0xFFFFFFFF; + if(m_oCache.IsInit()) + ptr->stSlicerCacheName = m_oCache.get(); + else + ptr->stSlicerCacheName = 0xFFFFFFFF; + if(m_oCaption.IsInit()) + ptr->stCaption = m_oCaption.get(); + else + { + ptr->stCaption = 0xFFFFFFFF; + ptr->fCaptionVisible = false; + ptr->fHasCaption = false; + } + + if(m_oStyle.IsInit()) + ptr->stStyle = m_oStyle.get(); + else + { + ptr->stStyle = 0xFFFFFFFF; + ptr->fHasStyle = false; + } + return objectPtr; +} void CSlicer::ReadAttributes(XLS::BaseObjectPtr& obj) { auto ptr = static_cast(obj.get()); @@ -345,6 +411,15 @@ void CSlicerFile::readBin(const CPath& oPath) } } +XLS::BaseObjectPtr CSlicerFile::WriteBin() const +{ + XLSB::SlicersStreamPtr slicersStream(new XLSB::SlicersStream); + XLS::BaseObjectPtr objectPtr(slicersStream); + if(m_oSlicers.IsInit()) + slicersStream->m_SLICERS = m_oSlicers->toBin(); + return objectPtr; +} + void CSlicerFile::read(const CPath& oRootPath, const CPath& oPath) { m_oReadPath = oPath; @@ -370,18 +445,35 @@ void CSlicerFile::write(const CPath& oPath, const CPath& oDirectory, CContentTyp { if(!m_oSlicers.IsInit()) return; + CXlsb* xlsb = dynamic_cast(File::m_pMainDocument); + if ((xlsb) && (xlsb->m_bWriteToXlsb)) + { + XLS::BaseObjectPtr object = WriteBin(); + xlsb->WriteBin(oPath, object.get()); + } + else + { + NSStringUtils::CStringBuilder sXml; - NSStringUtils::CStringBuilder sXml; - - sXml.WriteString(L""); - m_oSlicers->toXML(sXml, L"slicers"); - - std::wstring sPath = oPath.GetPath(); - NSFile::CFileBinary::SaveToFile(sPath, sXml.GetData()); + sXml.WriteString(L""); + m_oSlicers->toXML(sXml, L"slicers"); + std::wstring sPath = oPath.GetPath(); + NSFile::CFileBinary::SaveToFile(sPath, sXml.GetData()); + } oContent.Registration( type().OverrideType(), oDirectory, oPath.GetFilename() ); IFileContainer::Write( oPath, oDirectory, oContent ); } +const OOX::FileType CSlicerFile::type() const +{ + CXlsb* xlsb = dynamic_cast(File::m_pMainDocument); + if ((xlsb) && (xlsb->m_bWriteToXlsb)) + { + return OOX::SpreadsheetBin::FileTypes::SlicerBin; + } + return OOX::Spreadsheet::FileTypes::Slicer; +} + } //Spreadsheet } // namespace OOX diff --git a/OOXML/XlsxFormat/Slicer/Slicer.h b/OOXML/XlsxFormat/Slicer/Slicer.h index ad66ce73e08..b605fd4e60b 100644 --- a/OOXML/XlsxFormat/Slicer/Slicer.h +++ b/OOXML/XlsxFormat/Slicer/Slicer.h @@ -59,6 +59,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer, const std::wstring& sName) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); void ReadAttributes(XLS::BaseObjectPtr& obj); void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; @@ -96,6 +97,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer, const std::wstring& sName) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); @@ -121,6 +123,7 @@ namespace OOX read( oRootPath, oPath ); } void readBin(const CPath& oPath); + XLS::BaseObjectPtr WriteBin() const; virtual void read(const CPath& oPath) { //don't use this. use read(const CPath& oRootPath, const CPath& oFilePath) @@ -129,10 +132,7 @@ namespace OOX } virtual void read(const CPath& oRootPath, const CPath& oPath); virtual void write(const CPath& oPath, const CPath& oDirectory, CContentTypes& oContent) const; - virtual const OOX::FileType type() const - { - return OOX::Spreadsheet::FileTypes::Slicer; - } + virtual const OOX::FileType type() const; virtual const CPath DefaultDirectory() const { return type().DefaultDirectory(); diff --git a/OOXML/XlsxFormat/Slicer/SlicerCache.cpp b/OOXML/XlsxFormat/Slicer/SlicerCache.cpp index 092ffb02e92..cf5b7c49b49 100644 --- a/OOXML/XlsxFormat/Slicer/SlicerCache.cpp +++ b/OOXML/XlsxFormat/Slicer/SlicerCache.cpp @@ -59,6 +59,7 @@ #include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_structures/BiffStructure.h" +#include "../../Binary/XlsbFormat/FileTypes_SpreadsheetBin.h" namespace OOX { namespace Spreadsheet @@ -77,6 +78,25 @@ void COlapSlicerCacheItem::fromBin(XLS::BaseObjectPtr& obj) } } } +XLS::BaseObjectPtr COlapSlicerCacheItem::toBin() +{ + auto ptr(new XLSB::SlicerCacheOlapItem); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oNd.IsInit()) + ptr->fNoData = m_oNd.get(); + if(m_oN.IsInit()) + ptr->stName = m_oN.get(); + else + ptr->stName.setSize(0xFFFFFFFF); + if(m_oC.IsInit()) + ptr->stTitle = m_oC.get(); + else + ptr->stTitle.setSize(0xFFFFFFFF); + for(auto i:m_oP) + if(i.m_oN.IsInit()) + ptr->parents.push_back(i.m_oN.get()); + return objectPtr; +} void COlapSlicerCacheItem::ReadAttributes(XLS::BaseObjectPtr& obj) { auto ptr = static_cast(obj.get()); @@ -256,6 +276,24 @@ void COlapSlicerCacheItemParent::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReade } pReader->Seek(_end_rec); } +XLS::BaseObjectPtr COlapSlicerCacheRange::toBin() +{ + auto ptr(new XLSB::SLICERCACHESIRANGE); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oStartItem.IsInit()) + { + auto ptr1(new XLSB::BeginSlicerCacheSiRange); + if(m_oStartItem.IsInit()) + ptr1->iitemstart = m_oStartItem.get(); + else + ptr1->iitemstart = 0; + ptr1->crange = m_oI.size(); + ptr->m_BrtBeginSlicerCacheSiRange = XLS::BaseObjectPtr{ptr1}; + } + for(auto i:m_oI) + ptr->m_arBrtSlicerCacheOlapItem.push_back(i.toBin()); + return objectPtr; +} void COlapSlicerCacheRange::fromBin(XLS::BaseObjectPtr& obj) { auto ptr = static_cast(obj.get()); @@ -372,6 +410,17 @@ void CTabularSlicerCacheItem::fromBin(XLS::BiffStructure& obj) { ReadAttributes(obj); } +void CTabularSlicerCacheItem::toBin(XLS::BiffStructure *obj) +{ + auto ptr = static_cast(obj); + + if(m_oX.IsInit()) + ptr->iCache = m_oX.get(); + if(m_oS.IsInit()) + ptr->fSelected = m_oS.get(); + if(m_oNd.IsInit()) + ptr->fNoData = m_oNd.get(); +} void CTabularSlicerCacheItem::ReadAttributes(XLS::BiffStructure& obj) { auto ptr = static_cast(&obj); @@ -473,6 +522,23 @@ void COlapSlicerCacheSelection::fromBin(XLS::BaseObjectPtr& obj) } } } +XLS::BaseObjectPtr COlapSlicerCacheSelection::toBin() +{ + auto ptr(new XLSB::SlicerCacheSelection); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oN.IsInit()) + ptr->stUniqueName = m_oN.get(); + else + ptr->stUniqueName = L""; + + for(auto i:m_oP) + { + if(i.m_oN.IsInit()) + ptr->parents.push_back(i.m_oN.get()); + } + + return objectPtr; +} void COlapSlicerCacheSelection::ReadAttributes(XLS::BaseObjectPtr& obj) { auto ptr = static_cast(obj.get()); @@ -590,6 +656,42 @@ void COlapSlicerCacheLevelData::fromBin(XLS::BaseObjectPtr& obj) } } } +XLS::BaseObjectPtr COlapSlicerCacheLevelData::toBin() +{ + auto ptr(new XLSB::SLICERCACHELEVELDATA); + XLS::BaseObjectPtr objectPtr(ptr); + auto ptr1(new XLSB::BeginSlicerCacheLevelData); + ptr->m_BrtBeginSlicerCacheLevelData = XLS::BaseObjectPtr{ptr1}; + + if(m_oCount.IsInit()) + ptr1->citem = m_oCount.get(); + else + ptr1->citem = 0; + if(m_oSortOrder.IsInit()) + ptr1->fSortOrder = m_oSortOrder->GetValue(); + else + ptr1->fSortOrder = false; + if(m_oUniqueName.IsInit()) + ptr1->stUniqueName = m_oUniqueName.get(); + else + ptr1->stUniqueName.setSize(0xFFFFFFFF); + if(m_oSourceCaption.IsInit()) + ptr1->stSourceCaption = m_oSourceCaption.get(); + else + ptr1->stSourceCaption.setSize(0xFFFFFFFF); + if(m_oCrossFilter.IsInit()) + ptr1->fCrossFilter = m_oCrossFilter->GetValue(); + else + ptr1->fCrossFilter = false; + + auto ptr2(new XLSB::SLICERCACHESIRANGES); + ptr->m_SLICERCACHESIRANGES = XLS::BaseObjectPtr{ptr2}; + for(auto i:m_oRanges) + { + ptr2->m_arSLICERCACHESIRANGE.push_back(i.toBin()); + } + return objectPtr; +} void COlapSlicerCacheLevelData::ReadAttributes(XLS::BaseObjectPtr& obj) { auto ptr = static_cast(obj.get()); @@ -763,7 +865,20 @@ void CTabularSlicerCacheItems::fromBin(XLS::BaseObjectPtr& obj) } } } - +XLS::BaseObjectPtr CTabularSlicerCacheItems::toBin() +{ + auto ptr(new XLSB::SlicerCacheNativeItem); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oCount.IsInit()) + ptr->cItems = m_oCount.get(); + for(auto i:m_oI) + { + XLSB::SlicerCacheNativeItemStruct object; + i.toBin(&object); + ptr->rgItems.push_back(object); + } + return objectPtr; +} void CTabularSlicerCacheItems::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) { WritingElement_ReadAttributes_StartChar_No_NS(oReader) @@ -853,7 +968,14 @@ void CTabularSlicerCacheItems::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) } pReader->Seek(_end_rec); } - +XLS::BaseObjectPtr COlapSlicerCacheSelections::toBin() +{ + auto ptr(new XLSB::SLICERCACHESELECTIONS); + XLS::BaseObjectPtr objectPtr(ptr); + for(auto i:m_oSelection) + ptr->m_arBrtSlicerCacheSelection.push_back(i.toBin()); + return objectPtr; +} void COlapSlicerCacheSelections::fromBin(XLS::BaseObjectPtr& obj) { auto ptr = static_cast(obj.get()); @@ -975,6 +1097,17 @@ void COlapSlicerCacheLevelsData::fromBin(XLS::BaseObjectPtr& obj) } } +XLS::BaseObjectPtr COlapSlicerCacheLevelsData::toBin() +{ + auto ptr(new XLSB::SLICERCACHELEVELSDATA); + XLS::BaseObjectPtr objectPtr(ptr); + if(!m_oLevel.empty()) + { + for(auto i:m_oLevel) + ptr->m_arSLICERCACHELEVELDATA.push_back(i.toBin()); + } + return objectPtr; +} void COlapSlicerCacheLevelsData::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) { WritingElement_ReadAttributes_StartChar_No_NS(oReader) @@ -1075,6 +1208,26 @@ void CTabularSlicerCache::fromBin(XLS::BaseObjectPtr& obj) m_oItems = ptr->m_BrtSlicerCacheNativeItem; } } +XLS::BaseObjectPtr CTabularSlicerCache::toBin() +{ + auto ptr(new XLSB::SLICERCACHENATIVEITEMS); + XLS::BaseObjectPtr objectPtr(ptr); + auto ptr1(new XLSB::BeginSlicerCacheNative); + ptr->m_BrtBeginSlicerCacheNative= XLS::BaseObjectPtr{ptr1}; + if(m_oPivotCacheId.IsInit()) + ptr1->dwcacheId = m_oPivotCacheId.get(); + if(m_oSortOrder.IsInit()) + ptr1->fSortOrder = m_oSortOrder->GetValue() + 1; + if(m_oCustomListSort.IsInit()) + ptr1->fSortUsingCustomLists = m_oCustomListSort.get(); + if(m_oShowMissing.IsInit()) + ptr1->fShowAllItems = m_oShowMissing.get(); + if(m_oCrossFilter.IsInit()) + ptr1->fCrossFilter = m_oCrossFilter->GetValue(); + + ptr->m_BrtSlicerCacheNativeItem = m_oItems->toBin(); + return objectPtr; +} void CTabularSlicerCache::ReadAttributes(XLS::BaseObjectPtr& obj) { auto ptr = static_cast(obj.get()); @@ -1227,6 +1380,22 @@ void COlapSlicerCache::fromBin(XLS::BaseObjectPtr& obj) m_oSelections = ptr->m_SLICERCACHESELECTIONS; } } +XLS::BaseObjectPtr COlapSlicerCache::toBin() +{ + auto ptr(new XLSB::SLICERCACHEOLAPIMPL); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oPivotCacheId.IsInit()) + { + auto ptr1(new XLSB::BeginSlicerCacheOlapImpl); + ptr->m_BrtBeginSlicerCacheOlapImpl = XLS::BaseObjectPtr{ptr1}; + ptr1->ipivotcacheid = m_oPivotCacheId.get(); + } + if(m_oLevels.IsInit()) + ptr->m_SLICERCACHELEVELSDATA = m_oLevels->toBin(); + if(m_oSelections.IsInit()) + ptr->m_SLICERCACHESELECTIONS = m_oSelections->toBin(); + return objectPtr; +} void COlapSlicerCache::ReadAttributes(XLS::BaseObjectPtr& obj) { auto ptr = static_cast(obj.get()); @@ -1343,6 +1512,15 @@ void CSlicerCacheData::fromBin(XLS::BaseObjectPtr& obj) m_oTabular = obj; } } +XLS::BaseObjectPtr CSlicerCacheData::toBin() +{ + XLS::BaseObjectPtr objectPtr; + if(m_oOlap.IsInit()) + objectPtr = m_oOlap->toBin(); + else if(m_oTabular.IsInit()) + objectPtr = m_oTabular->toBin(); + return objectPtr; +} void CSlicerCacheData::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) { WritingElement_ReadAttributes_StartChar_No_NS(oReader) @@ -1435,7 +1613,16 @@ void CSlicerCachePivotTable::ReadAttributes(XLS::BiffStructure& obj) m_oName = ptr->stPivotTable.value(); } } - +void CSlicerCachePivotTable::toBin(XLS::BiffStructure* obj) +{ + auto ptr = static_cast(obj); + if(m_oTabId.IsInit()) + ptr->iTabId = m_oTabId.get(); + if(m_oName.IsInit()) + ptr->stPivotTable = m_oName.get(); + else + ptr->stPivotTable = 0xFFFFFFFF; +} void CSlicerCachePivotTable::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) { WritingElement_ReadAttributes_StartChar_No_NS(oReader) @@ -1529,6 +1716,38 @@ void CSlicerCacheDefinition::fromBin(XLS::BaseObjectPtr& obj) m_oExtLst = ptr->m_FRTSLICERCACHE; } } +XLS::BaseObjectPtr CSlicerCacheDefinition::toBin() +{ + auto ptr(new XLSB::SLICERCACHE); + auto ptr1(new XLSB::BeginSlicerCacheDef); + ptr->m_BrtBeginSlicerCacheDef = XLS::BaseObjectPtr{ptr1}; + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oName.IsInit()) + ptr1->stName = m_oName.get(); + else + ptr1->stName = 0xFFFFFFFF; + if(m_oSourceName.IsInit()) + ptr1->stHierarchy = m_oSourceName.get(); + else + ptr1->stHierarchy = 0xFFFFFFFF; + if(!m_oPivotTables.empty()) + { + auto ptr2(new XLSB::SlicerCachePivotTables); + ptr->m_BrtSlicerCachePivotTables = XLS::BaseObjectPtr{ptr2}; + for(auto i:m_oPivotTables) + { + XLSB::SlicerCachePivotTable table; + i.toBin(&table); + ptr2->pivotTables.push_back(table); + } + } + if(m_oData.IsInit()) + ptr->m_slicerCacheData = m_oData->toBin(); + if(m_oExtLst.IsInit()) + ptr->m_FRTSLICERCACHE = m_oExtLst->toBinSlicerCache(); + + return objectPtr; +} void CSlicerCacheDefinition::ReadAttributes(XLS::BaseObjectPtr& obj) { auto ptr = static_cast(obj.get()); @@ -1769,7 +1988,15 @@ void CSlicerCacheFile::readBin(const CPath& oPath) //slicerCachesStream.reset(); } } +XLS::BaseObjectPtr CSlicerCacheFile::WriteBin() const +{ + XLSB::SlicerCachesStreamPtr slicerCachesStream(new XLSB::SlicerCachesStream); + XLS::BaseObjectPtr objectPtr(slicerCachesStream); + if(m_oSlicerCacheDefinition.IsInit()) + slicerCachesStream->m_SLICERCACHE = m_oSlicerCacheDefinition->toBin(); + return objectPtr; +} void CSlicerCacheFile::read(const CPath& oRootPath, const CPath& oPath) { m_oReadPath = oPath; @@ -1796,18 +2023,35 @@ void CSlicerCacheFile::write(const CPath& oPath, const CPath& oDirectory, CConte { if(!m_oSlicerCacheDefinition.IsInit()) return; + CXlsb* xlsb = dynamic_cast(File::m_pMainDocument); + if ((xlsb) && (xlsb->m_bWriteToXlsb)) + { + XLS::BaseObjectPtr object = WriteBin(); + xlsb->WriteBin(oPath, object.get()); + } + else + { + NSStringUtils::CStringBuilder sXml; - NSStringUtils::CStringBuilder sXml; - - sXml.WriteString(L""); - m_oSlicerCacheDefinition->toXML(sXml, L"slicerCacheDefinition"); - - std::wstring sPath = oPath.GetPath(); - NSFile::CFileBinary::SaveToFile(sPath, sXml.GetData()); + sXml.WriteString(L""); + m_oSlicerCacheDefinition->toXML(sXml, L"slicerCacheDefinition"); + std::wstring sPath = oPath.GetPath(); + NSFile::CFileBinary::SaveToFile(sPath, sXml.GetData()); + } oContent.Registration( type().OverrideType(), oDirectory, oPath.GetFilename() ); IFileContainer::Write( oPath, oDirectory, oContent ); } +const OOX::FileType CSlicerCacheFile::type() const +{ + CXlsb* xlsb = dynamic_cast(File::m_pMainDocument); + if ((xlsb) && (xlsb->m_bWriteToXlsb)) + { + return OOX::SpreadsheetBin::FileTypes::SlicerCacheBin; + } + return OOX::Spreadsheet::FileTypes::SlicerCache; +} + } //Spreadsheet } // namespace OOX diff --git a/OOXML/XlsxFormat/Slicer/SlicerCache.h b/OOXML/XlsxFormat/Slicer/SlicerCache.h index b44b6ceb298..595e0e39ccb 100644 --- a/OOXML/XlsxFormat/Slicer/SlicerCache.h +++ b/OOXML/XlsxFormat/Slicer/SlicerCache.h @@ -97,6 +97,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer, const std::wstring& sName) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); void ReadAttributes(XLS::BaseObjectPtr& obj); void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; @@ -125,6 +126,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer, const std::wstring& sName) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); void ReadAttributes(XLS::BaseObjectPtr& obj); void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; @@ -151,6 +153,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer, const std::wstring& sName) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BiffStructure& obj); + void toBin(XLS::BiffStructure* obj); void ReadAttributes(XLS::BiffStructure& obj); void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; @@ -177,6 +180,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer, const std::wstring& sName) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); void ReadAttributes(XLS::BaseObjectPtr& obj); void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; @@ -203,6 +207,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer, const std::wstring& sName) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); void ReadAttributes(XLS::BaseObjectPtr& obj); void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; @@ -234,6 +239,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer, const std::wstring& sName) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); @@ -260,6 +266,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer, const std::wstring& sName) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); @@ -285,6 +292,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const{} virtual void toXML(NSStringUtils::CStringBuilder& writer, const std::wstring& sName) const; void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; @@ -312,6 +320,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer, const std::wstring& sName) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); void ReadAttributes(XLS::BaseObjectPtr& obj); void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; @@ -344,6 +353,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer, const std::wstring& sName) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); void ReadAttributes(XLS::BaseObjectPtr& obj); void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; @@ -373,6 +383,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer, const std::wstring& sName) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); @@ -397,6 +408,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer, const std::wstring& sName) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BiffStructure& obj); + void toBin(XLS::BiffStructure* obj); void ReadAttributes(XLS::BiffStructure& obj); void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; @@ -423,6 +435,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer, const std::wstring& sName) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); void ReadAttributes(XLS::BaseObjectPtr& obj); void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; @@ -455,6 +468,7 @@ namespace OOX read( oRootPath, oPath ); } void readBin(const CPath& oPath); + XLS::BaseObjectPtr WriteBin() const; virtual void read(const CPath& oPath) { //don't use this. use read(const CPath& oRootPath, const CPath& oFilePath) @@ -463,10 +477,7 @@ namespace OOX } virtual void read(const CPath& oRootPath, const CPath& oPath); virtual void write(const CPath& oPath, const CPath& oDirectory, CContentTypes& oContent) const; - virtual const OOX::FileType type() const - { - return OOX::Spreadsheet::FileTypes::SlicerCache; - } + virtual const OOX::FileType type() const; virtual const CPath DefaultDirectory() const { return type().DefaultDirectory(); diff --git a/OOXML/XlsxFormat/Slicer/SlicerCacheExt.cpp b/OOXML/XlsxFormat/Slicer/SlicerCacheExt.cpp index 492a1591e3d..578f31ed573 100644 --- a/OOXML/XlsxFormat/Slicer/SlicerCacheExt.cpp +++ b/OOXML/XlsxFormat/Slicer/SlicerCacheExt.cpp @@ -47,6 +47,11 @@ #include "../../XlsbFormat/Biff12_unions/SLICERCACHEIDS.h" #include "../../XlsbFormat/Biff12_unions/SLICERCACHEID.h" #include "../../XlsbFormat/Biff12_records/BeginSlicerCacheID.h" +#include "../../XlsbFormat/Biff12_unions/TABLESLICERCACHEIDS.h" +#include "../../XlsbFormat/Biff12_unions/TABLESLICERCACHEID.h" +#include "../../XlsbFormat/Biff12_records/TableSlicerCacheID.h" +#include "../../XlsbFormat/Biff12_records/FRTBegin.h" +#include "../../XlsbFormat/Biff12_structures/FRTProductVersion.h" #include "../../Binary/Presentation/XmlWriter.h" #include "../../Binary/Presentation/BinReaderWriterDefines.h" @@ -66,6 +71,16 @@ void CSlicerCacheOlapLevelName::fromBin(XLS::BiffStructure& obj) { ReadAttributes(obj); } +void CSlicerCacheOlapLevelName::toBin(XLS::BiffStructure* obj) +{ + auto ptr = static_cast(obj); + if(m_oCount.IsInit()) + ptr->cHiddenItems = m_oCount.get(); + if(m_oUniqueName.IsInit()) + ptr->stUniqueName = m_oUniqueName.get(); + else + ptr->stUniqueName = 0xFFFFFFFF; +} void CSlicerCacheOlapLevelName::ReadAttributes(XLS::BiffStructure& obj) { auto ptr = static_cast(&obj); @@ -161,6 +176,20 @@ void CSlicerCacheHideNoData::fromBin(XLS::BaseObjectPtr &obj) } } +XLS::BaseObjectPtr CSlicerCacheHideNoData::toBin() +{ + auto ptr(new XLSB::SlicerCacheHideItemsWithNoData); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oCount.IsInit()) + ptr->cHideItemLevelsCount = m_oCount.get(); + for(auto i:m_oSlicerCacheOlapLevelName) + { + XLSB::SlicerCacheLevelData levelData; + i.toBin(&levelData); + ptr->rgLevels.push_back(levelData); + } + return objectPtr; +} void CSlicerCacheHideNoData::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) { WritingElement_ReadAttributes_StartChar_No_NS(oReader) @@ -254,6 +283,22 @@ void CTableSlicerCache::fromBin(XLS::BaseObjectPtr& obj) { ReadAttributes(obj); } +XLS::BaseObjectPtr CTableSlicerCache::toBin() +{ + auto ptr(new XLSB::BeginTableSlicerCache); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oTableId.IsInit()) + ptr->dwLstd = m_oTableId.get(); + if(m_oColumn.IsInit()) + ptr->dwColumn = m_oColumn.get(); + if(m_oSortOrder.IsInit()) + ptr->fSortOrder = m_oSortOrder->GetValue() + 1; + if(m_oCustomListSort.IsInit()) + ptr->fSortUsingCustomLists = m_oCustomListSort.get(); + if(m_oCrossFilter.IsInit()) + ptr->iCrossFilter = m_oCrossFilter->GetValue(); + return objectPtr; +} void CTableSlicerCache::ReadAttributes(XLS::BaseObjectPtr& obj) { auto ptr = static_cast(obj.get()); @@ -453,6 +498,35 @@ void CSlicerStyleElement::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) } pReader->Seek(_end_rec); } +XLS::BaseObjectPtr CSlicerStyleElement::toBin() +{ + auto ptr(new XLSB::SlicerStyleElement); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oDxfId.IsInit()); + ptr->dxfId = m_oDxfId.get(); + if( m_oType->GetValue() == SimpleTypes::Spreadsheet::ESlicerStyleType::cslicerstyletypeUnselectedItemWithData) + ptr->tseType = 0x0000001C; + if(m_oType.IsInit()) + { + if (m_oType->GetValue() == SimpleTypes::Spreadsheet::ESlicerStyleType::cslicerstyletypeUnselectedItemWithData) + ptr->tseType = 0x0000001C; + else if (m_oType->GetValue() == SimpleTypes::Spreadsheet::ESlicerStyleType::cslicerstyletypeUnselectedItemWithNoData) + ptr->tseType = 0x0000001D; + else if (m_oType->GetValue() == SimpleTypes::Spreadsheet::ESlicerStyleType::cslicerstyletypeSelectedItemWithData) + ptr->tseType = 0x0000001E; + else if (m_oType->GetValue() == SimpleTypes::Spreadsheet::ESlicerStyleType::cslicerstyletypeSelectedItemWithNoData) + ptr->tseType = 0x0000001F; + else if (m_oType->GetValue() == SimpleTypes::Spreadsheet::ESlicerStyleType::cslicerstyletypeHoveredUnselectedItemWithData) + ptr->tseType = 0x00000020; + else if (m_oType->GetValue() == SimpleTypes::Spreadsheet::ESlicerStyleType::cslicerstyletypeHoveredSelectedItemWithData) + ptr->tseType = 0x00000021; + else if (m_oType->GetValue() == SimpleTypes::Spreadsheet::ESlicerStyleType::cslicerstyletypeHoveredUnselectedItemWithNoData) + ptr->tseType = 0x00000022; + else if (m_oType->GetValue() == SimpleTypes::Spreadsheet::ESlicerStyleType::cslicerstyletypeHoveredSelectedItemWithNoData) + ptr->tseType = 0x00000023; + } + return objectPtr; +} void CSlicerStyleElement::fromBin(XLS::BaseObjectPtr &obj) { ReadAttributes(obj); @@ -493,6 +567,38 @@ void CSlicerStyleElement::ReadAttributes(XLS::BaseObjectPtr &obj) } } +XLS::BaseObjectPtr CSlicerCache::toBin() +{ + auto ptr(new XLSB::SLICERCACHEID); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oRId.IsInit()) + { + auto ptr1(new XLSB::BeginSlicerCacheID); + ptr->m_BrtBeginSlicerCacheID = XLS::BaseObjectPtr{ptr1}; + ptr1->FRTheader.relID.relId = m_oRId->GetValue(); + ptr1->FRTheader.fRef = false; + ptr1->FRTheader.fSqref = false; + ptr1->FRTheader.fFormula = false; + ptr1->FRTheader.fRelID = true; + } + return objectPtr; +} +XLS::BaseObjectPtr CSlicerCache::toBinTable() +{ + auto ptr(new XLSB::TABLESLICERCACHEID); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oRId.IsInit()) + { + auto ptr1(new XLSB::TableSlicerCacheID); + ptr->m_BrtTableSlicerCacheID = XLS::BaseObjectPtr{ptr1}; + ptr1->FRTheader.relID.relId = m_oRId->GetValue(); + ptr1->FRTheader.fRef = false; + ptr1->FRTheader.fSqref = false; + ptr1->FRTheader.fFormula = false; + ptr1->FRTheader.fRelID = true; + } + return objectPtr; +} void CSlicerCache::fromBin(XLS::BaseObjectPtr &obj) { ReadAttributes(obj); @@ -529,8 +635,7 @@ void CSlicerCache::toXML(NSStringUtils::CStringBuilder& writer, const std::wstri writer.StartNode(sName); writer.StartAttributes(); WritingNullable(m_oRId, writer.WriteAttribute(L"r:id", m_oRId->ToString());); - writer.EndAttributes(); - writer.EndNode(sName); + writer.EndAttributesAndNode(); } void CSlicerCache::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const { @@ -540,6 +645,34 @@ void CSlicerCache::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) { pReader->SkipRecord(); } +XLS::BaseObjectPtr CSlicerRef::toBin() +{ + auto ptr(new XLSB::SLICEREX); + XLS::BaseObjectPtr objectPtr(ptr); + auto ptr1(new XLSB::BeginSlicerEx); + ptr1->FRTheader.relID.relId = m_oRId->GetValue(); + ptr1->FRTheader.fRelID = true; + ptr1->FRTheader.fRef = false; + ptr1->FRTheader.fSqref = false; + ptr1->FRTheader.fFormula = false; + ptr->m_BrtBeginSlicerEx = XLS::BaseObjectPtr{ptr1}; + + return objectPtr; +} +XLS::BaseObjectPtr CSlicerRef::toBinTable() +{ + auto ptr(new XLSB::TABLESLICEREX); + XLS::BaseObjectPtr objectPtr(ptr); + auto ptr1(new XLSB::BeginSlicerEx); + ptr1->FRTheader.relID.relId = m_oRId->GetValue(); + ptr1->FRTheader.fRelID = true; + ptr1->FRTheader.fRef = false; + ptr1->FRTheader.fSqref = false; + ptr1->FRTheader.fFormula = false; + ptr->m_BrtBeginSlicerEx = XLS::BaseObjectPtr{ptr1}; + + return objectPtr; +} void CSlicerRef::fromBin(XLS::BaseObjectPtr &obj) { ReadAttributes(obj); @@ -557,7 +690,6 @@ void CSlicerRef::ReadAttributes(XLS::BaseObjectPtr &obj) if(!ptr1->FRTheader.relID.relId.value().empty()) m_oRId = ptr1->FRTheader.relID.relId.value(); } - } } else if(obj->get_type() == XLS::typeTABLESLICEREX) @@ -718,6 +850,24 @@ void CSlicerStyle::fromBin(XLS::BaseObjectPtr &obj) } } +XLS::BaseObjectPtr CSlicerStyle::toBin() +{ + auto ptr(new XLSB::SLICERSTYLE); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oName.IsInit()) + { + auto ptr1(new XLSB::BeginSlicerStyle); + ptr->m_BrtBeginSlicerStyle = XLS::BaseObjectPtr{ptr1}; + ptr1->stName = m_oName.get(); + } + for(auto i: m_oSlicerStyleElements) + { + ptr->m_arBrtSlicerStyleElement.push_back(i.toBin()); + } + + + return objectPtr; +} void CSlicerStyle::ReadAttributes(XLS::BaseObjectPtr &obj) { auto ptr = static_cast(obj.get()); @@ -725,6 +875,34 @@ void CSlicerStyle::ReadAttributes(XLS::BaseObjectPtr &obj) m_oName = ptr->stName.value(); } +XLS::BaseObjectPtr CSlicerCaches::toBin() +{ + auto ptr(new XLSB::SLICERCACHEIDS); + XLS::BaseObjectPtr objectPtr(ptr); + for(auto i:m_oSlicerCache) + { + ptr->m_arSLICERCACHEID.push_back(i.toBin()); + } + return objectPtr; +} + +XLS::BaseObjectPtr CSlicerCaches::toBinTable() +{ + auto ptr(new XLSB::TABLESLICERCACHEIDS); + auto ptr1(new XLSB::FRTBegin); + ptr->m_BrtFRTBegin = XLS::BaseObjectPtr{ptr1}; + XLSB::FRTProductVersion version; + version.product = 0; + version.version = 0; + ptr1->productVersion = version; + XLS::BaseObjectPtr objectPtr(ptr); + for(auto i:m_oSlicerCache) + { + ptr->m_arTABLESLICERCACHEID.push_back(i.toBinTable()); + } + return objectPtr; +} + void CSlicerCaches::fromBin(XLS::BaseObjectPtr &obj) { auto ptr = static_cast(obj.get()); @@ -778,6 +956,40 @@ void CSlicerCaches::toXML(NSStringUtils::CStringBuilder& writer, const std::wstr } writer.EndNode(sPrefix + sName); } +XLS::BaseObjectPtr CSlicerRefs::toBin() +{ + auto ptr(new XLSB::SLICERSEX); + XLS::BaseObjectPtr objectPtr(ptr); + auto ptr1(new XLSB::FRTBegin); + ptr->m_BrtFRTBegin = XLS::BaseObjectPtr{ptr1}; + XLSB::FRTProductVersion version; + version.product = 0; + version.version = 0; + ptr1->productVersion = version; + + for(auto i:m_oSlicer) + { + ptr->m_arSLICEREX.push_back(i.toBin()); + } + return objectPtr; +} +XLS::BaseObjectPtr CSlicerRefs::toBinTable() +{ + auto ptr(new XLSB::TABLESLICERSEX); + XLS::BaseObjectPtr objectPtr(ptr); + auto ptr1(new XLSB::FRTBegin); + ptr->m_BrtFRTBegin = XLS::BaseObjectPtr{ptr1}; + XLSB::FRTProductVersion version; + version.product = 0; + version.version = 0; + ptr1->productVersion = version; + + for(auto i:m_oSlicer) + { + ptr->m_arTABLESLICEREX.push_back(i.toBinTable()); + } + return objectPtr; +} void CSlicerRefs::fromBin(XLS::BaseObjectPtr &obj) { if(obj->get_type() == XLS::typeSLICERSEX) @@ -949,6 +1161,30 @@ void CSlicerStyles::fromBin(XLS::BaseObjectPtr &obj) } } } +XLS::BaseObjectPtr CSlicerStyles::toBin() +{ + auto ptr(new XLSB::STYLESHEET14); + auto ptr1(new XLSB::FRTBegin); + ptr->m_BrtFRTBegin = XLS::BaseObjectPtr{ptr1}; + XLSB::FRTProductVersion version; + version.product = 0; + version.version = 0; + ptr1->productVersion = version; + XLS::BaseObjectPtr objectPtr(ptr); + auto slicerStyle(new XLSB::SLICERSTYLES); + ptr->m_SLICERSTYLES = XLS::BaseObjectPtr {slicerStyle}; + + auto beginStyles(new XLSB::BeginSlicerStyles); + slicerStyle->m_BrtBeginSlicerStyles = XLS::BaseObjectPtr{beginStyles}; + if(m_oDefaultSlicerStyle.IsInit()) + beginStyles->stDefSlicer = m_oDefaultSlicerStyle.get(); + for(auto i:m_oSlicerStyle) + { + slicerStyle->m_arSLICERSTYLE.push_back(i.toBin()); + } + + return objectPtr; +} void CSlicerStyles::ReadAttributes(XLS::BaseObjectPtr &obj) { auto ptr = static_cast(obj.get()); diff --git a/OOXML/XlsxFormat/Slicer/SlicerCacheExt.h b/OOXML/XlsxFormat/Slicer/SlicerCacheExt.h index a94ddcd7a10..e2992f220c3 100644 --- a/OOXML/XlsxFormat/Slicer/SlicerCacheExt.h +++ b/OOXML/XlsxFormat/Slicer/SlicerCacheExt.h @@ -72,6 +72,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer, const std::wstring& sName) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BiffStructure& obj); + void toBin(XLS::BiffStructure* obj); void ReadAttributes(XLS::BiffStructure& obj); void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; @@ -98,6 +99,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer, const std::wstring& sName) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); @@ -124,6 +126,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer, const std::wstring& sName) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); void ReadAttributes(XLS::BaseObjectPtr& obj); void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; @@ -159,6 +162,7 @@ namespace OOX virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType() const { return et_x_SlicerStyleElement; @@ -181,6 +185,8 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer, const std::wstring& sName) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); + XLS::BaseObjectPtr toBinTable(); void ReadAttributes(XLS::BaseObjectPtr& obj); void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; @@ -206,6 +212,8 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer, const std::wstring& sName) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); + XLS::BaseObjectPtr toBinTable(); void ReadAttributes(XLS::BaseObjectPtr& obj); void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; @@ -235,6 +243,7 @@ namespace OOX virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType() const { return et_x_SlicerStyle; @@ -257,7 +266,10 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const{} virtual void toXML(NSStringUtils::CStringBuilder& writer, const std::wstring& sName, const std::wstring& sPrefix) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + XLS::BaseObjectPtr toBin(); + XLS::BaseObjectPtr toBinTable(); void fromBin(XLS::BaseObjectPtr& obj); + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); virtual EElementType getType() const { @@ -280,6 +292,8 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer, const std::wstring& sName) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); + XLS::BaseObjectPtr toBinTable(); void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); virtual EElementType getType() const { @@ -306,6 +320,7 @@ namespace OOX virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType() const { return et_x_SlicerStyles; diff --git a/OOXML/XlsxFormat/Styles/Borders.cpp b/OOXML/XlsxFormat/Styles/Borders.cpp index c3b94bbdf38..47f085bc528 100644 --- a/OOXML/XlsxFormat/Styles/Borders.cpp +++ b/OOXML/XlsxFormat/Styles/Borders.cpp @@ -36,8 +36,11 @@ #include "../../Common/SimpleTypes_Spreadsheet.h" #include "../../XlsbFormat/Biff12_records/Border.h" +#include "../../XlsbFormat/Biff12_records/BeginBorders.h" #include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_structures/BiffStructure.h" +#include "../../XlsbFormat/Biff12_unions/BORDERS.h" + namespace OOX { namespace Spreadsheet @@ -134,6 +137,60 @@ namespace OOX } } + void CBorderProp::toBin(XLS::BiffStructure* obj) + { + auto ptr = static_cast(obj); + if(this == nullptr) + { + CColor color; + ptr->brtColor = color.GetDefaultColor(); + ptr->dg = 0x00; + return; + } + if(m_oColor.IsInit()) + ptr->brtColor = m_oColor->toColor(); + else + { + ptr->brtColor = m_oColor->GetDefaultColor(); + } + + if(!m_oStyle.IsInit()) + { + ptr->dg = 0x00; + return; + } + + if (m_oStyle == SimpleTypes::Spreadsheet::EBorderStyle::borderstyleNone) + ptr->dg = 0x00; + else if (m_oStyle == SimpleTypes::Spreadsheet::EBorderStyle::borderstyleThin) + ptr->dg = 0x01; + else if (m_oStyle == SimpleTypes::Spreadsheet::EBorderStyle::borderstyleMedium) + ptr->dg = 0x02; + else if (m_oStyle == SimpleTypes::Spreadsheet::EBorderStyle::borderstyleDashed) + ptr->dg = 0x03; + else if (m_oStyle == SimpleTypes::Spreadsheet::EBorderStyle::borderstyleDotted) + ptr->dg = 0x04; + else if (m_oStyle == SimpleTypes::Spreadsheet::EBorderStyle::borderstyleThick) + ptr->dg = 0x05; + else if (m_oStyle == SimpleTypes::Spreadsheet::EBorderStyle::borderstyleDouble) + ptr->dg = 0x06; + else if (m_oStyle == SimpleTypes::Spreadsheet::EBorderStyle::borderstyleHair) + ptr->dg = 0x07; + else if (m_oStyle == SimpleTypes::Spreadsheet::EBorderStyle::borderstyleMediumDashed) + ptr->dg = 0x08; + else if (m_oStyle == SimpleTypes::Spreadsheet::EBorderStyle::borderstyleDashDot) + ptr->dg = 0x09; + else if (m_oStyle == SimpleTypes::Spreadsheet::EBorderStyle::borderstyleMediumDashDot) + ptr->dg = 0x0A; + else if (m_oStyle == SimpleTypes::Spreadsheet::EBorderStyle::borderstyleDashDotDot) + ptr->dg = 0x0B; + else if (m_oStyle == SimpleTypes::Spreadsheet::EBorderStyle::borderstyleMediumDashDotDot) + ptr->dg = 0x0C; + else if (m_oStyle == SimpleTypes::Spreadsheet::EBorderStyle::borderstyleSlantDashDot) + ptr->dg = 0x0D; + else + ptr->dg = 0x00; + } bool CBorderProp::IsEmpty() { return !(m_oStyle.IsInit() || m_oColor.IsInit()); @@ -150,7 +207,7 @@ namespace OOX WritingElement_ReadAttributes_Read_else_if(oReader, L"ss:Position", m_oType) WritingElement_ReadAttributes_Read_else_if(oReader, L"ss:Weight", iWeight) WritingElement_ReadAttributes_End(oReader) - + if (sColor.IsInit()) { m_oColor.Init(); m_oColor->m_oRgb.Init(); @@ -162,13 +219,21 @@ namespace OOX m_oStyle.reset(new SimpleTypes::Spreadsheet::CBorderStyle(SimpleTypes::Spreadsheet::borderstyleDotted)); else if (*sLineStyle == L"Dash") m_oStyle.reset(new SimpleTypes::Spreadsheet::CBorderStyle(SimpleTypes::Spreadsheet::borderstyleDashed)); - else if (*sLineStyle == L"None") - m_oStyle.reset(new SimpleTypes::Spreadsheet::CBorderStyle(SimpleTypes::Spreadsheet::borderstyleNone)); + else if (*sLineStyle == L"DashDot") + m_oStyle.reset(new SimpleTypes::Spreadsheet::CBorderStyle(SimpleTypes::Spreadsheet::borderstyleDashDot)); + else if (*sLineStyle == L"DashDotDot") + m_oStyle.reset(new SimpleTypes::Spreadsheet::CBorderStyle(SimpleTypes::Spreadsheet::borderstyleDashDotDot)); else if (*sLineStyle == L"Double") m_oStyle.reset(new SimpleTypes::Spreadsheet::CBorderStyle(SimpleTypes::Spreadsheet::borderstyleDouble)); + else if (*sLineStyle == L"None") + m_oStyle.reset(new SimpleTypes::Spreadsheet::CBorderStyle(SimpleTypes::Spreadsheet::borderstyleNone)); + else if (*sLineStyle == L"SlantDashDot") + m_oStyle.reset(new SimpleTypes::Spreadsheet::CBorderStyle(SimpleTypes::Spreadsheet::borderstyleSlantDashDot)); else if (*sLineStyle == L"Continuous") { - m_oStyle.reset(new SimpleTypes::Spreadsheet::CBorderStyle(SimpleTypes::Spreadsheet::borderstyleThin)); + if (iWeight.IsInit()) m_oStyle.reset(); + else + m_oStyle.reset(new SimpleTypes::Spreadsheet::CBorderStyle(SimpleTypes::Spreadsheet::borderstyleHair)); bBorderContinuous = true; } } @@ -178,16 +243,28 @@ namespace OOX { case 1: //Thin { - if (false == sLineStyle.IsInit()) + if (false == m_oStyle.IsInit()) m_oStyle.reset(new SimpleTypes::Spreadsheet::CBorderStyle(SimpleTypes::Spreadsheet::borderstyleThin)); }break; case 3: //Thick { - if (false == sLineStyle.IsInit()) + if (false == m_oStyle.IsInit()) m_oStyle.reset(new SimpleTypes::Spreadsheet::CBorderStyle(SimpleTypes::Spreadsheet::borderstyleThick)); }break; - default://2: //Medium + case 2: + default: //Medium { + if (false == m_oStyle.IsInit()) + m_oStyle.reset(new SimpleTypes::Spreadsheet::CBorderStyle(SimpleTypes::Spreadsheet::borderstyleMedium)); + else + { + switch (m_oStyle->GetValue()) + { + case SimpleTypes::Spreadsheet::borderstyleDashed: m_oStyle.reset(new SimpleTypes::Spreadsheet::CBorderStyle(SimpleTypes::Spreadsheet::borderstyleMediumDashed)); break; + case SimpleTypes::Spreadsheet::borderstyleDashDot: m_oStyle.reset(new SimpleTypes::Spreadsheet::CBorderStyle(SimpleTypes::Spreadsheet::borderstyleMediumDashDot)); break; + case SimpleTypes::Spreadsheet::borderstyleDashDotDot: m_oStyle.reset(new SimpleTypes::Spreadsheet::CBorderStyle(SimpleTypes::Spreadsheet::borderstyleMediumDashDotDot)); break; + } + } }break; } } @@ -282,10 +359,26 @@ namespace OOX if ((border) && (border->m_oType.IsInit())) { - if (*border->m_oType == L"Bottom") m_oBottom = border; - else if (*border->m_oType == L"Top") m_oTop = border; - else if (*border->m_oType == L"Left") m_oStart = border; - else if (*border->m_oType == L"Right") m_oEnd = border; + if (*border->m_oType == L"Bottom") m_oBottom = border; + else if (*border->m_oType == L"Top") m_oTop = border; + else if (*border->m_oType == L"Left") m_oStart = border; + else if (*border->m_oType == L"Right") m_oEnd = border; + else if (*border->m_oType == L"DiagonalLeft") + { + if (false == m_oDiagonal.IsInit()) + { + m_oDiagonal = border; + } + m_oDiagonalUp = true; + } + else if (*border->m_oType == L"DiagonalRight") + { + if (false == m_oDiagonal.IsInit()) + { + m_oDiagonal = border; + } + m_oDiagonalDown = true; + } if (border->bBorderContinuous) bBorderContinuous = true; @@ -295,13 +388,33 @@ namespace OOX delete border; } } - } } void CBorder::fromBin(XLS::BaseObjectPtr& obj) { ReadAttributes(obj); } + XLS::BaseObjectPtr CBorder::toBin() + { + auto ptr(new XLSB::Border); + XLS::BaseObjectPtr objectPtr(ptr); + + m_oBottom->toBin(&ptr->blxfBottom); + m_oDiagonal->toBin(&ptr->blxfDiag); + m_oTop->toBin(&ptr->blxfTop); + m_oStart->toBin(&ptr->blxfLeft); + m_oEnd->toBin(&ptr->blxfRight); + + if(m_oDiagonalDown.IsInit()) + ptr->fBdrDiagDown = m_oDiagonalDown->GetValue(); + else + ptr->fBdrDiagDown = false; + if(m_oDiagonalUp.IsInit()) + ptr->fBdrDiagUp = m_oDiagonalUp->GetValue(); + else + ptr->fBdrDiagUp = false; + return objectPtr; + } EElementType CBorder::getType () const { return et_x_Border; @@ -401,6 +514,17 @@ namespace OOX m_mapBorders.insert(std::make_pair(index++, pBorder)); } } + XLS::BaseObjectPtr CBorders::toBin() + { + auto ptr(new XLSB::BORDERS); + auto ptr1(new XLSB::BeginBorders); + ptr->m_BrtBeginBorders = XLS::BaseObjectPtr{ptr1}; + XLS::BaseObjectPtr objectPtr(ptr); + for(auto i:m_arrItems) + ptr->m_arBrtBorder.push_back(i->toBin()); + ptr1->cborders = ptr->m_arBrtBorder.size(); + return objectPtr; + } EElementType CBorders::getType () const { return et_x_Borders; diff --git a/OOXML/XlsxFormat/Styles/Borders.h b/OOXML/XlsxFormat/Styles/Borders.h index f8b0ddd0173..21f65cc26a3 100644 --- a/OOXML/XlsxFormat/Styles/Borders.h +++ b/OOXML/XlsxFormat/Styles/Borders.h @@ -68,6 +68,7 @@ namespace OOX virtual EElementType getType () const; void fromBin(XLS::BiffStructure* obj); + void toBin(XLS::BiffStructure* obj); bool IsEmpty(); private: @@ -98,6 +99,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; private: @@ -135,6 +137,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(std::vector& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; private: diff --git a/OOXML/XlsxFormat/Styles/CellStyles.cpp b/OOXML/XlsxFormat/Styles/CellStyles.cpp index b8074e2e25b..4563abeac8f 100644 --- a/OOXML/XlsxFormat/Styles/CellStyles.cpp +++ b/OOXML/XlsxFormat/Styles/CellStyles.cpp @@ -34,6 +34,9 @@ #include "../../Common/SimpleTypes_Shared.h" #include "../../XlsbFormat/Biff12_records/Style.h" +#include "../../XlsbFormat/Biff12_records/BeginStyles.h" + +#include "../../XlsbFormat/Biff12_unions/STYLES.h" namespace OOX { @@ -71,6 +74,39 @@ namespace OOX { ReadAttributes(obj); } + XLS::BaseObjectPtr CCellStyle::toBin() + { + auto ptr(new XLSB::Style); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oBuiltinId.IsInit()) + { + ptr->fBuiltIn = true; + ptr->iStyBuiltIn = m_oBuiltinId->GetValue(); + } + else + ptr->fBuiltIn = false; + if (m_oCustomBuiltin.IsInit()) + ptr->fCustom = m_oCustomBuiltin->GetValue(); + else + ptr->fCustom = false; + if (m_oHidden.IsInit()) + ptr->fHidden = m_oHidden->GetValue(); + else + ptr->fHidden = false; + if (m_oILevel.IsInit()) + ptr->iLevel = m_oILevel->GetValue(); + else + ptr->iLevel = 0; + if (m_oName.IsInit()) + ptr->stName = m_oName.get(); + else + ptr->stName = L""; + if (m_oXfId.IsInit()) + ptr->ixf = m_oXfId->GetValue(); + else + ptr->ixf = 0; + return objectPtr; + } EElementType CCellStyle::getType () const { return et_x_CellStyle; @@ -159,6 +195,18 @@ namespace OOX m_arrItems.push_back(pXfs); } } + XLS::BaseObjectPtr CCellStyles::toBin() + { + auto ptr(new XLSB::STYLES); + auto ptr1(new XLSB::BeginStyles); + ptr->m_BrtBeginStyles = XLS::BaseObjectPtr{ptr1}; + XLS::BaseObjectPtr objectPtr(ptr); + + for(auto i:m_arrItems) + ptr->m_arBrtStyle.push_back(i->toBin()); + ptr1->cstyles = ptr->m_arBrtStyle.size(); + return objectPtr; + } EElementType CCellStyles::getType () const { return et_x_CellStyles; diff --git a/OOXML/XlsxFormat/Styles/CellStyles.h b/OOXML/XlsxFormat/Styles/CellStyles.h index b62b65c3d5b..d69e44c085f 100644 --- a/OOXML/XlsxFormat/Styles/CellStyles.h +++ b/OOXML/XlsxFormat/Styles/CellStyles.h @@ -60,6 +60,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + XLS::BaseObjectPtr toBin(); void fromBin(XLS::BaseObjectPtr& obj); virtual EElementType getType () const; @@ -90,6 +91,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + XLS::BaseObjectPtr toBin(); void fromBin(std::vector& obj); virtual EElementType getType () const; diff --git a/OOXML/XlsxFormat/Styles/Colors.cpp b/OOXML/XlsxFormat/Styles/Colors.cpp index 7adcbffdf74..5b9d98cfe09 100644 --- a/OOXML/XlsxFormat/Styles/Colors.cpp +++ b/OOXML/XlsxFormat/Styles/Colors.cpp @@ -98,6 +98,27 @@ namespace OOX } } } + XLS::BaseObjectPtr CColors::toBin() + { + auto ptr(new XLSB::COLORPALETTE); + XLS::BaseObjectPtr objectPtr(ptr); + + if(m_oIndexedColors.IsInit()) + { + auto indexColors(new XLSB::INDEXEDCOLORS); + ptr->m_INDEXEDCOLORS = XLS::BaseObjectPtr{indexColors}; + indexColors->m_arIndexedColor = m_oIndexedColors->toBin(); + } + + if(m_oMruColors.IsInit()) + { + auto mruColors(new XLSB::MRUCOLORS); + ptr->m_MRUCOLORS = XLS::BaseObjectPtr{mruColors}; + mruColors->m_arMRUColor = m_oMruColors->toBin(); + } + + return objectPtr; + } EElementType CColors::getType () const { return et_x_Colors; diff --git a/OOXML/XlsxFormat/Styles/Colors.h b/OOXML/XlsxFormat/Styles/Colors.h index a8d92c0621b..f593ae4fab6 100644 --- a/OOXML/XlsxFormat/Styles/Colors.h +++ b/OOXML/XlsxFormat/Styles/Colors.h @@ -52,6 +52,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; private: diff --git a/OOXML/XlsxFormat/Styles/Fills.cpp b/OOXML/XlsxFormat/Styles/Fills.cpp index 608dba331f8..7b123660f51 100644 --- a/OOXML/XlsxFormat/Styles/Fills.cpp +++ b/OOXML/XlsxFormat/Styles/Fills.cpp @@ -36,8 +36,11 @@ #include "../../Common/SimpleTypes_Spreadsheet.h" #include "../../XlsbFormat/Biff12_records/Fill.h" +#include "../../XlsbFormat/Biff12_records/BeginFills.h" #include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_structures/BiffStructure.h" +#include "../../XlsbFormat/Biff12_unions/FILLS.h" + namespace OOX { namespace Spreadsheet @@ -75,11 +78,9 @@ namespace OOX else if(m_oFgColor.IsInit()) { m_oFgColor->toXMLWithNS(writer, child_ns, L"fgColor", child_ns); - m_oFgColor->toXMLWithNS(writer, child_ns, L"bgColor", child_ns); } else if(m_oBgColor.IsInit()) { - m_oBgColor->toXMLWithNS(writer, child_ns, L"fgColor", child_ns); m_oBgColor->toXMLWithNS(writer, child_ns, L"bgColor", child_ns); } @@ -110,6 +111,69 @@ namespace OOX { ReadAttributes(obj); } + void CPatternFill::toBin(XLS::BaseObjectPtr obj) + { + auto ptr = static_cast(obj.get()); + if(m_oPatternType.IsInit()) + { + if (m_oPatternType == SimpleTypes::Spreadsheet::EPatternType::patterntypeNone) + ptr->fls = 0x00; + else if (m_oPatternType == SimpleTypes::Spreadsheet::EPatternType::patterntypeSolid) + ptr->fls = 0x01; + else if (m_oPatternType == SimpleTypes::Spreadsheet::EPatternType::patterntypeMediumGray) + ptr->fls = 0x02; + else if (m_oPatternType == SimpleTypes::Spreadsheet::EPatternType::patterntypeDarkGray) + ptr->fls = 0x03; + else if (m_oPatternType == SimpleTypes::Spreadsheet::EPatternType::patterntypeLightGray) + ptr->fls = 0x04; + else if (m_oPatternType == SimpleTypes::Spreadsheet::EPatternType::patterntypeDarkHorizontal) + ptr->fls = 0x05; + else if (m_oPatternType == SimpleTypes::Spreadsheet::EPatternType::patterntypeDarkVertical) + ptr->fls = 0x06; + else if (m_oPatternType == SimpleTypes::Spreadsheet::EPatternType::patterntypeDarkDown) + ptr->fls = 0x07; + else if (m_oPatternType == SimpleTypes::Spreadsheet::EPatternType::patterntypeDarkUp) + ptr->fls = 0x08; + else if (m_oPatternType == SimpleTypes::Spreadsheet::EPatternType::patterntypeDarkGrid) + ptr->fls = 0x09; + else if (m_oPatternType == SimpleTypes::Spreadsheet::EPatternType::patterntypeDarkTrellis) + ptr->fls = 0x0A; + else if (m_oPatternType == SimpleTypes::Spreadsheet::EPatternType::patterntypeLightHorizontal) + ptr->fls = 0x0B; + else if (m_oPatternType == SimpleTypes::Spreadsheet::EPatternType::patterntypeLightVertical) + ptr->fls = 0x0C; + else if (m_oPatternType == SimpleTypes::Spreadsheet::EPatternType::patterntypeLightDown) + ptr->fls = 0x0D; + else if (m_oPatternType == SimpleTypes::Spreadsheet::EPatternType::patterntypeLightUp) + ptr->fls = 0x0E; + else if (m_oPatternType == SimpleTypes::Spreadsheet::EPatternType::patterntypeLightGrid) + ptr->fls = 0x0F; + else if (m_oPatternType == SimpleTypes::Spreadsheet::EPatternType::patterntypeLightTrellis) + ptr->fls = 0x10; + else if (m_oPatternType == SimpleTypes::Spreadsheet::EPatternType::patterntypeGray125) + ptr->fls = 0x11; + else if (m_oPatternType == SimpleTypes::Spreadsheet::EPatternType::patterntypeGray0625) + ptr->fls = 0x12; + else + ptr->fls = 0x00; + } + else + ptr->fls = 0x00; + + if(m_oBgColor.IsInit()) + ptr->brtColorBack = m_oBgColor->toColor(); + else + { m_oBgColor.Init(); + ptr->brtColorBack = m_oBgColor->GetDefaultColor(); + } + if(m_oFgColor.IsInit()) + ptr->brtColorFore = m_oFgColor->toColor(); + else + { + m_oFgColor.Init(); + ptr->brtColorFore = m_oFgColor->GetDefaultColor(); + } + } EElementType CPatternFill::getType () const { return et_x_PatternFill; @@ -230,6 +294,21 @@ namespace OOX m_oColor->fromBin(dynamic_cast(&ptr->brtColor)); } } + void CGradientStop::toBin(XLS::BaseObjectPtr obj) + { + auto ptr = static_cast(obj.get()); + XLSB::GradientStop stop; + if(m_oPosition.IsInit()) + stop.xnumPosition.data.value = m_oPosition->GetValue(); + else + stop.xnumPosition.data.value = 0; + if(m_oColor.IsInit()) + { + stop.brtColor = m_oColor->toColor(); + } + ptr->xfillGradientStop.push_back(stop); + } + EElementType CGradientStop::getType () const { return et_x_GradientStop; @@ -310,6 +389,40 @@ namespace OOX m_arrItems.push_back(ptrGradStop); } } + } + void CGradientFill::toBin(XLS::BaseObjectPtr obj) + { + auto ptr = static_cast(obj.get()); + + if(m_oType.IsInit()) + ptr->iGradientType = m_oType->GetValue(); + else + ptr->iGradientType = 0; + if(m_oDegree.IsInit()) + ptr->xnumDegree.data.value = m_oDegree->GetValue(); + else + ptr->xnumDegree.data.value = 0; + if(m_oLeft.IsInit()) + ptr->xnumFillToLeft.data.value = m_oLeft->GetValue(); + else + ptr->xnumFillToLeft.data.value = 0; + if(m_oRight.IsInit()) + ptr->xnumFillToRight.data.value = m_oRight->GetValue(); + else + ptr->xnumFillToRight.data.value = 0; + if(m_oTop .IsInit()) + ptr->xnumFillToTop.data.value = m_oTop->GetValue(); + else + ptr->xnumFillToTop.data.value = 0; + if(m_oBottom.IsInit()) + ptr->xnumFillToBottom.data.value = m_oBottom->GetValue(); + else + ptr->xnumFillToBottom.data.value = 0; + + for(auto i:m_arrItems) + { + i->toBin(obj); + } } @@ -397,6 +510,34 @@ namespace OOX if ((m_oGradientFill.IsInit()) && (false == m_oGradientFill->m_oType.IsInit())) m_oGradientFill.reset(); } + XLS::BaseObjectPtr CFill::toBin() + { + auto ptr(new XLSB::Fill); + XLS::BaseObjectPtr objectPtr(ptr); + + if(m_oPatternFill.IsInit()) + { + m_oPatternFill->toBin(objectPtr); + } + else + { + CColor color; + ptr->fls = 0; + ptr->brtColorBack = color.GetDefaultColor(); + ptr->brtColorFore = color.GetDefaultColor(); + } + + if(m_oGradientFill.IsInit()) + { + m_oGradientFill->toBin(objectPtr); + } + else + { + ptr->iGradientType = 0; + } + ptr->cNumStop = 0; + return objectPtr; + } EElementType CFill::getType () const { return et_x_Fill; @@ -500,6 +641,19 @@ namespace OOX m_mapFills.insert(std::make_pair(index++, pFill)); } } + XLS::BaseObjectPtr CFills::toBin() + { + auto ptr(new XLSB::FILLS); + auto ptr1(new XLSB::BeginFills); + ptr->m_BrtBeginFills = XLS::BaseObjectPtr{ptr1}; + + XLS::BaseObjectPtr objectPtr(ptr); + for(auto i : m_arrItems) + ptr->m_arBrtFill.push_back(i->toBin()); + ptr1->cfills = ptr->m_arBrtFill.size(); + return objectPtr; + + } EElementType CFills::getType () const { return et_x_Fills; diff --git a/OOXML/XlsxFormat/Styles/Fills.h b/OOXML/XlsxFormat/Styles/Fills.h index 7294079c861..278d2576811 100644 --- a/OOXML/XlsxFormat/Styles/Fills.h +++ b/OOXML/XlsxFormat/Styles/Fills.h @@ -67,6 +67,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + void toBin(XLS::BaseObjectPtr obj); virtual EElementType getType () const; @@ -95,6 +96,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BiffStructure* obj); + void toBin(XLS::BaseObjectPtr obj); virtual EElementType getType () const; @@ -122,6 +124,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + void toBin(XLS::BaseObjectPtr obj); virtual EElementType getType () const; @@ -154,6 +157,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; @@ -180,6 +184,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(std::vector& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; private: diff --git a/OOXML/XlsxFormat/Styles/Fonts.cpp b/OOXML/XlsxFormat/Styles/Fonts.cpp index 8a0efa5cabc..47d0dbb12c8 100644 --- a/OOXML/XlsxFormat/Styles/Fonts.cpp +++ b/OOXML/XlsxFormat/Styles/Fonts.cpp @@ -34,6 +34,9 @@ #include "../ComplexTypes_Spreadsheet.h" #include "../../XlsbFormat/Biff12_records/CommonRecords.h" +#include "../../XlsbFormat/Biff12_records/BeginFonts.h" + +#include "../../XlsbFormat/Biff12_unions/FONTS.h" namespace OOX { @@ -179,6 +182,116 @@ namespace OOX { ReadAttributes(obj); } + XLS::BaseObjectPtr CFont::toBin() + { + auto ptr(new XLSB::Font); + XLS::BaseObjectPtr objectPtr(ptr); + + if(m_oSz.IsInit()) + ptr->dyHeight = m_oSz->m_oVal->GetValue() * 20; + + if(m_oItalic.IsInit()) + ptr->fItalic = m_oItalic->ToBool(); + else + ptr->fItalic = false; + + if(m_oStrike.IsInit()) + ptr->fStrikeOut = m_oStrike->ToBool(); + else + ptr->fStrikeOut = false; + + if(m_oOutline.IsInit()) + ptr->fOutline = m_oOutline->ToBool(); + else + ptr->fOutline = false; + + if(m_oShadow.IsInit()) + ptr->fShadow = m_oShadow->ToBool(); + else + ptr->fShadow = false; + + if(m_oCondense.IsInit()) + ptr->fCondense = m_oCondense->ToBool(); + else + ptr->fCondense = false; + + if(m_oExtend.IsInit()) + ptr->fExtend = m_oExtend->ToBool(); + else + ptr->fExtend = false; + if(m_oBold.IsInit()) + { + if(m_oBold->ToBool()) + ptr->bls = 0x02BC; + } + else + { + ptr->bls = 0x0190; + } + if(m_oUnderline.IsInit()) + { + if(m_oUnderline->m_oUnderline.IsInit()) + { + if(m_oUnderline->m_oUnderline == SimpleTypes::Spreadsheet::EUnderline::underlineNone) + ptr->uls = 0; + else if(m_oUnderline->m_oUnderline == SimpleTypes::Spreadsheet::EUnderline::underlineSingle) + ptr->uls = 1; + else if(m_oUnderline->m_oUnderline == SimpleTypes::Spreadsheet::EUnderline::underlineDouble) + ptr->uls = 2; + else if(m_oUnderline->m_oUnderline == SimpleTypes::Spreadsheet::EUnderline::underlineSingleAccounting) + ptr->uls = 33; + else if(m_oUnderline->m_oUnderline == SimpleTypes::Spreadsheet::EUnderline::underlineDoubleAccounting) + ptr->uls = 34; + } + } + else + ptr->uls = 0; + + if(m_oFamily.IsInit()) + ptr->bFamily = m_oFamily->m_oFontFamily->GetValue(); + + if(m_oCharset.IsInit()) + ptr->bCharSet = m_oCharset->m_oCharset->GetValue(); + + if(m_oColor.IsInit()) + ptr->brtColor = m_oColor->toColor(); + else + { + m_oColor.Init(); + ptr->brtColor = m_oColor->GetDefaultColor(); + } + + if(m_oScheme.IsInit()) + { + if(m_oScheme->m_oFontScheme.IsInit()) + { + if(m_oScheme->m_oFontScheme == SimpleTypes::Spreadsheet::EFontScheme::fontschemeNone) + ptr->bFontScheme = 0; + else if(m_oScheme->m_oFontScheme == SimpleTypes::Spreadsheet::EFontScheme::fontschemeMajor) + ptr->bFontScheme = 1; + else if(m_oScheme->m_oFontScheme == SimpleTypes::Spreadsheet::EFontScheme::fontschemeMinor) + ptr->bFontScheme = 2; + } + } + + + if(m_oRFont.IsInit()) + ptr->fontName = m_oRFont->m_sVal.get(); + if(m_oVertAlign.IsInit()) + { + if(m_oVertAlign->m_oVerticalAlign.IsInit()) + { + if(m_oVertAlign->m_oVerticalAlign->GetValue() == SimpleTypes::EVerticalAlignRun::verticalalignrunBaseline) + ptr->sss = 0; + else if(m_oVertAlign->m_oVerticalAlign->GetValue() == SimpleTypes::EVerticalAlignRun::verticalalignrunSuperscript) + ptr->sss = 1; + else if(m_oVertAlign->m_oVerticalAlign->GetValue() == SimpleTypes::EVerticalAlignRun::verticalalignrunSubscript) + ptr->sss = 2; + } + } + + return objectPtr; + } EElementType CFont::getType () const { return et_x_Font; @@ -406,6 +519,20 @@ namespace OOX m_mapFonts.insert(std::make_pair(index++, pFont)); } } + XLS::BaseObjectPtr CFonts::toBin() + { + auto ptr(new XLSB::FONTS); + auto ptr1(new XLSB::BeginFonts); + ptr->m_BrtBeginFonts = XLS::BaseObjectPtr{ptr1}; + XLS::BaseObjectPtr objectPtr(ptr); + + for(auto i:m_arrItems) + { + ptr->m_arBrtFont.push_back(i->toBin()); + } + ptr1->cfonts = ptr->m_arBrtFont.size(); + return objectPtr; + } EElementType CFonts::getType () const { return et_x_Fonts; diff --git a/OOXML/XlsxFormat/Styles/Fonts.h b/OOXML/XlsxFormat/Styles/Fonts.h index f629aee2719..1f8050fcb85 100644 --- a/OOXML/XlsxFormat/Styles/Fonts.h +++ b/OOXML/XlsxFormat/Styles/Fonts.h @@ -55,6 +55,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; @@ -95,6 +96,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(std::vector& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; void AddFont (CFont* pFont); diff --git a/OOXML/XlsxFormat/Styles/NumFmts.cpp b/OOXML/XlsxFormat/Styles/NumFmts.cpp index 431f9583d69..f141813c4b1 100644 --- a/OOXML/XlsxFormat/Styles/NumFmts.cpp +++ b/OOXML/XlsxFormat/Styles/NumFmts.cpp @@ -36,6 +36,8 @@ #include "../../XlsbFormat/Biff12_unions/ACFMT.h" #include "../../Common/SimpleTypes_Shared.h" +#include "../../XlsbFormat/Biff12_unions/FMTS.h" +#include "../../XlsbFormat/Biff12_records/BeginFmts.h" namespace OOX { @@ -83,6 +85,21 @@ namespace OOX { ReadAttributes(obj); } + XLS::BaseObjectPtr CNumFmt::toBin() + { + auto ptr(new XLSB::Fmt); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oFormatCode.IsInit()) + ptr->stFmtCode = m_oFormatCode.get(); + else + ptr->stFmtCode = L""; + if(m_oNumFmtId.IsInit()) + ptr->ifmt = m_oNumFmtId->GetValue(); + else + ptr->ifmt = 5; + + return objectPtr; + } EElementType CNumFmt::getType () const { return et_x_NumFmt; @@ -187,6 +204,20 @@ namespace OOX } } + XLS::BaseObjectPtr CNumFmts::toBin() + { + auto fmts(new XLSB::FMTS); + auto beginfmt(new XLSB::BeginFmts); + fmts->m_BrtBeginFmts = XLS::BaseObjectPtr{beginfmt}; + XLS::BaseObjectPtr objectPtr(fmts); + std::vector objectVector; + for(auto i:m_arrItems) + { + fmts->m_arBrtFmt.push_back(i->toBin()); + } + beginfmt->cfmts = fmts->m_arBrtFmt.size(); + return objectPtr; + } EElementType CNumFmts::getType () const { return et_x_NumFmts; diff --git a/OOXML/XlsxFormat/Styles/NumFmts.h b/OOXML/XlsxFormat/Styles/NumFmts.h index 70974a26b4f..fa3bc7371b8 100644 --- a/OOXML/XlsxFormat/Styles/NumFmts.h +++ b/OOXML/XlsxFormat/Styles/NumFmts.h @@ -61,6 +61,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; @@ -90,6 +91,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(std::vector& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; private: diff --git a/OOXML/XlsxFormat/Styles/Styles.h b/OOXML/XlsxFormat/Styles/Styles.h index e9d94ff37ad..83ec20520f1 100644 --- a/OOXML/XlsxFormat/Styles/Styles.h +++ b/OOXML/XlsxFormat/Styles/Styles.h @@ -105,6 +105,7 @@ namespace OOX virtual ~CStyles(); void readBin(const CPath& oPath); + XLS::BaseObjectPtr WriteBin() const; virtual void read(const CPath& oPath); virtual void read(const CPath& oRootPath, const CPath& oPath); diff --git a/OOXML/XlsxFormat/Styles/TableStyles.cpp b/OOXML/XlsxFormat/Styles/TableStyles.cpp index e65ec236635..7975c44ff27 100644 --- a/OOXML/XlsxFormat/Styles/TableStyles.cpp +++ b/OOXML/XlsxFormat/Styles/TableStyles.cpp @@ -80,6 +80,85 @@ namespace OOX { ReadAttributes(obj); } + XLS::BaseObjectPtr CTableStyleElement::toBin() + { + auto ptr(new XLSB::TableStyleElement); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oDxfId.IsInit()) + ptr->index = m_oDxfId->GetValue(); + else + ptr->index = 0; + if(m_oSize.IsInit()) + ptr->size = m_oSize->GetValue(); + else + ptr->size = 1; + + if(m_oType.IsInit()) + { + if (m_oType == SimpleTypes::Spreadsheet::ETableStyleType::tablestyletypeWholeTable) + ptr->tseType = 0; + else if (m_oType == SimpleTypes::Spreadsheet::ETableStyleType::tablestyletypeHeaderRow) + ptr->tseType = 1; + else if (m_oType == SimpleTypes::Spreadsheet::ETableStyleType::tablestyletypeTotalRow) + ptr->tseType = 2; + else if (m_oType == SimpleTypes::Spreadsheet::ETableStyleType::tablestyletypeFirstColumn) + ptr->tseType = 3; + else if (m_oType == SimpleTypes::Spreadsheet::ETableStyleType::tablestyletypeLastColumn) + ptr->tseType = 4; + else if (m_oType == SimpleTypes::Spreadsheet::ETableStyleType::tablestyletypeFirstRowStripe) + ptr->tseType = 5; + else if (m_oType == SimpleTypes::Spreadsheet::ETableStyleType::tablestyletypeSecondRowStripe) + ptr->tseType = 6; + else if (m_oType == SimpleTypes::Spreadsheet::ETableStyleType::tablestyletypeFirstColumnStripe) + ptr->tseType = 7; + else if (m_oType == SimpleTypes::Spreadsheet::ETableStyleType::tablestyletypeSecondColumnStripe) + ptr->tseType = 8; + else if (m_oType == SimpleTypes::Spreadsheet::ETableStyleType::tablestyletypeFirstHeaderCell) + ptr->tseType = 9; + else if (m_oType == SimpleTypes::Spreadsheet::ETableStyleType::tablestyletypeLastHeaderCell) + ptr->tseType = 10; + else if (m_oType == SimpleTypes::Spreadsheet::ETableStyleType::tablestyletypeFirstTotalCell) + ptr->tseType = 11; + else if (m_oType == SimpleTypes::Spreadsheet::ETableStyleType::tablestyletypeLastTotalCell) + ptr->tseType = 12; + else if (m_oType == SimpleTypes::Spreadsheet::ETableStyleType::tablestyletypeFirstSubtotalColumn) + ptr->tseType = 13; + else if (m_oType == SimpleTypes::Spreadsheet::ETableStyleType::tablestyletypeSecondSubtotalColumn) + ptr->tseType = 14; + else if (m_oType == SimpleTypes::Spreadsheet::ETableStyleType::tablestyletypeThirdSubtotalColumn) + ptr->tseType = 15; + else if (m_oType == SimpleTypes::Spreadsheet::ETableStyleType::tablestyletypeFirstSubtotalRow) + ptr->tseType = 16; + else if (m_oType == SimpleTypes::Spreadsheet::ETableStyleType::tablestyletypeSecondSubtotalRow) + ptr->tseType = 17; + else if (m_oType == SimpleTypes::Spreadsheet::ETableStyleType::tablestyletypeThirdSubtotalRow) + ptr->tseType = 18; + else if (m_oType == SimpleTypes::Spreadsheet::ETableStyleType::tablestyletypeBlankRow) + ptr->tseType = 19; + else if (m_oType == SimpleTypes::Spreadsheet::ETableStyleType::tablestyletypeFirstColumnSubheading) + ptr->tseType = 20; + else if (m_oType == SimpleTypes::Spreadsheet::ETableStyleType::tablestyletypeSecondColumnSubheading) + ptr->tseType = 21; + else if (m_oType == SimpleTypes::Spreadsheet::ETableStyleType::tablestyletypeThirdColumnSubheading) + ptr->tseType = 22; + else if (m_oType == SimpleTypes::Spreadsheet::ETableStyleType::tablestyletypeFirstRowSubheading) + ptr->tseType = 23; + else if (m_oType == SimpleTypes::Spreadsheet::ETableStyleType::tablestyletypeSecondRowSubheading) + ptr->tseType = 24; + else if (m_oType == SimpleTypes::Spreadsheet::ETableStyleType::tablestyletypeThirdRowSubheading) + ptr->tseType = 25; + else if (m_oType == SimpleTypes::Spreadsheet::ETableStyleType::tablestyletypePageFieldLabels) + ptr->tseType = 26; + else if (m_oType == SimpleTypes::Spreadsheet::ETableStyleType::tablestyletypePageFieldValues) + ptr->tseType = 27; + else + ptr->tseType = 19; + } + else + ptr->tseType = 19; + + return objectPtr; + } EElementType CTableStyleElement::getType () const { return et_x_TableStyleElement; @@ -236,6 +315,33 @@ namespace OOX } } + XLS::BaseObjectPtr CTableStyle::toBin() + { + auto ptr(new XLSB::TABLESTYLE); + XLS::BaseObjectPtr objectPtr(ptr); + auto beginStyle(new XLSB::BeginTableStyle); + ptr->m_BrtBeginTableStyle = XLS::BaseObjectPtr{beginStyle}; + + beginStyle->ctse = m_arrItems.size(); + if(m_oPivot.IsInit()) + beginStyle->fIsPivot = m_oPivot->GetValue(); + else + beginStyle->fIsPivot = false; + if(m_oTable.IsInit()) + beginStyle->fIsTable = m_oTable->GetValue(); + else + beginStyle->fIsTable = true; + if(m_oName.IsInit()) + beginStyle->rgchName = m_oName.get(); + else if(m_oDisplayName.IsInit()) + beginStyle->rgchName = m_oDisplayName.get(); + else + beginStyle->rgchName = L""; + + for(auto i:m_arrItems) + ptr->m_arBrtTableStyleElement.push_back(i->toBin()); + return objectPtr; + } EElementType CTableStyle::getType () const { return et_x_TableStyle; @@ -333,6 +439,25 @@ namespace OOX } } + XLS::BaseObjectPtr CTableStyles::toBin() + { + auto ptr(new XLSB::TABLESTYLES); + XLS::BaseObjectPtr objectPtr(ptr); + auto ptr1(new XLSB::BeginTableStyles); + ptr->m_BrtBeginTableStyles = XLS::BaseObjectPtr{ptr1}; + for(auto i:m_arrItems) + ptr->m_arTABLESTYLE.push_back(i->toBin()); + ptr1->cts = ptr->m_arTABLESTYLE.size(); + if(m_oDefaultTableStyle.IsInit()) + ptr1->rgchDefTableStyle = m_oDefaultTableStyle.get(); + else + ptr1->rgchDefTableStyle = L""; + if(m_oDefaultPivotStyle.IsInit()) + ptr1->rgchDefPivotStyle = m_oDefaultPivotStyle.get(); + else + ptr1->rgchDefPivotStyle = L""; + return objectPtr; + } EElementType CTableStyles::getType () const { return et_x_TableStyles; diff --git a/OOXML/XlsxFormat/Styles/TableStyles.h b/OOXML/XlsxFormat/Styles/TableStyles.h index 6c618606c71..e5d8900b5a5 100644 --- a/OOXML/XlsxFormat/Styles/TableStyles.h +++ b/OOXML/XlsxFormat/Styles/TableStyles.h @@ -63,6 +63,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; private: @@ -89,6 +90,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; private: @@ -118,6 +120,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; private: diff --git a/OOXML/XlsxFormat/Styles/Xfs.cpp b/OOXML/XlsxFormat/Styles/Xfs.cpp index 846a31af9fa..960e5db3ddd 100644 --- a/OOXML/XlsxFormat/Styles/Xfs.cpp +++ b/OOXML/XlsxFormat/Styles/Xfs.cpp @@ -36,6 +36,11 @@ #include "../../Common/SimpleTypes_Spreadsheet.h" #include "../../XlsbFormat/Biff12_records/CommonRecords.h" +#include "../../XlsbFormat/Biff12_records/BeginCellStyleXFs.h" +#include "../../XlsbFormat/Biff12_records/BeginCellXFs.h" + +#include "../../XlsbFormat/Biff12_unions/CELLSTYLEXFS.h" +#include "../../XlsbFormat/Biff12_unions/CELLXFS.h" namespace OOX { @@ -83,6 +88,66 @@ namespace OOX void CAligment::fromBin(XLS::BaseObjectPtr& obj) { ReadAttributes(obj); + } + void CAligment::toBin(XLS::BaseObjectPtr& obj) + { + auto ptr = static_cast(obj.get()); + if(m_oIndent.IsInit()) + ptr->cIndent = m_oIndent.get(); + if(m_oJustifyLastLine.IsInit()) + ptr->fJustLast = m_oJustifyLastLine->GetValue(); + else + ptr->fJustLast = false; + if(m_oReadingOrder.IsInit()) + ptr->iReadOrder = m_oReadingOrder.get(); + else if(m_oRelativeIndent.IsInit()) + ptr->iReadOrder = m_oRelativeIndent.get(); + else + ptr->iReadOrder = 0; + if(m_oShrinkToFit.IsInit()) + ptr->fShrinkToFit = m_oShrinkToFit->GetValue(); + else + ptr->fShrinkToFit = false; + if(m_oTextRotation.IsInit()) + ptr->trot = m_oTextRotation.get(); + else + ptr->trot = 0; + if(m_oWrapText.IsInit()) + ptr->fWrap = m_oWrapText->GetValue(); + else + ptr->fWrap = false; + if (m_oHorizontal == SimpleTypes::Spreadsheet::EHorizontalAlignment::horizontalalignmentGeneral) + ptr->alc = 0; + else if (m_oHorizontal == SimpleTypes::Spreadsheet::EHorizontalAlignment::horizontalalignmentLeft) + ptr->alc = 1; + else if (m_oHorizontal == SimpleTypes::Spreadsheet::EHorizontalAlignment::horizontalalignmentCenter) + ptr->alc = 2; + else if (m_oHorizontal == SimpleTypes::Spreadsheet::EHorizontalAlignment::horizontalalignmentRight) + ptr->alc = 3; + else if (m_oHorizontal == SimpleTypes::Spreadsheet::EHorizontalAlignment::horizontalalignmentFill) + ptr->alc = 4; + else if (m_oHorizontal == SimpleTypes::Spreadsheet::EHorizontalAlignment::horizontalalignmentJustify) + ptr->alc = 5; + else if (m_oHorizontal == SimpleTypes::Spreadsheet::EHorizontalAlignment::horizontalalignmentCenterContinuous) + ptr->alc = 6; + else if (m_oHorizontal == SimpleTypes::Spreadsheet::EHorizontalAlignment::horizontalalignmentDistributed) + ptr->alc = 7; + else + ptr->alc = 0; + + if (m_oVertical == SimpleTypes::Spreadsheet::EVerticalAlignment::verticalalignmentTop) + ptr->alcV = 0; + else if (m_oVertical == SimpleTypes::Spreadsheet::EVerticalAlignment::verticalalignmentCenter) + ptr->alcV = 1; + else if (m_oVertical == SimpleTypes::Spreadsheet::EVerticalAlignment::verticalalignmentBottom) + ptr->alcV = 2; + else if (m_oVertical == SimpleTypes::Spreadsheet::EVerticalAlignment::verticalalignmentJustify) + ptr->alcV = 3; + else if (m_oVertical == SimpleTypes::Spreadsheet::EVerticalAlignment::verticalalignmentDistributed) + ptr->alcV = 4; + else + ptr->alcV = 2; + } EElementType CAligment::getType () const { @@ -220,6 +285,18 @@ namespace OOX { ReadAttributes(obj); } + void CProtection::toBin(XLS::BaseObjectPtr& obj) + { + auto ptr = static_cast(obj.get()); + if(m_oHidden.IsInit()) + ptr->fHidden = m_oHidden->GetValue(); + else + ptr->fHidden = false; + if(m_oLocked.IsInit()) + ptr->fLocked = m_oLocked->GetValue(); + else + ptr->fLocked = true; + } EElementType CProtection::getType () const { return et_x_Protection; @@ -310,6 +387,69 @@ namespace OOX m_oAligment = obj; m_oProtection = obj; } + XLS::BaseObjectPtr CXfs::toBin() + { + size_t id = 0; + auto ptr(new XLSB::XF(id, id)); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oBorderId.IsInit()) + ptr->ixBorder = m_oBorderId->GetValue(); + if(m_oFillId.IsInit()) + ptr->iFill = m_oFillId->GetValue(); + if(m_oFontId.IsInit()) + ptr->font_index = m_oFontId->GetValue(); + if(m_oNumFmtId.IsInit()) + ptr->ifmt = m_oNumFmtId->GetValue(); + if(m_oPivotButton.IsInit()) + ptr->fsxButton = m_oPivotButton->GetValue(); + if(m_oQuotePrefix.IsInit()) + ptr->f123Prefix = m_oQuotePrefix->GetValue(); + + if (m_oXfId.IsInit()) + ptr->ixfParent = m_oXfId->GetValue(); + else + ptr->ixfParent = 65535; + + if(m_oAligment.IsInit()) + { + m_oAligment->toBin(objectPtr); + } + else + { + ptr->alc = 0; + ptr->alcV = 2; + } + if(!m_oProtection.IsInit()) + m_oProtection.Init(); + m_oProtection->toBin(objectPtr); + + if(m_oApplyAlignment.IsInit()) + ptr->fAtrAlc = m_oApplyAlignment->GetValue(); + else + ptr->fAtrAlc = false; + if(m_oApplyBorder.IsInit()) + ptr->fAtrBdr = m_oApplyBorder->GetValue(); + else + ptr->fAtrBdr = false; + if(m_oApplyFill.IsInit()) + ptr->fAtrPat = m_oApplyFill->GetValue(); + else + ptr->fAtrPat = false; + if(m_oApplyFont.IsInit()) + ptr->fAtrFnt = m_oApplyFont->GetValue(); + else + ptr->fAtrFnt = false; + if(m_oApplyNumberFormat.IsInit()) + ptr->fAtrNum = m_oApplyNumberFormat->GetValue(); + else + ptr->fAtrNum = false; + if(m_oApplyProtection.IsInit()) + ptr->fAtrProt = m_oApplyProtection->GetValue(); + else + ptr->fAtrProt = false; + + return objectPtr; + } void CXfs::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) { WritingElement_ReadAttributes_Start( oReader ) @@ -410,6 +550,17 @@ namespace OOX m_arrItems.push_back(pXfs); } } + XLS::BaseObjectPtr CCellXfs::toBin() + { + auto ptr(new XLSB::CELLXFS); + auto ptr1(new XLSB::BeginCellXFs); + ptr->m_BrtBeginCellXFs = XLS::BaseObjectPtr{ptr1}; + XLS::BaseObjectPtr objectPtr(ptr); + for(auto i:m_arrItems) + ptr->m_arBrtXF.push_back(i->toBin()); + ptr1->cxfs = ptr->m_arBrtXF.size(); + return objectPtr; + } EElementType CCellXfs::getType () const { return et_x_CellXfs; @@ -491,6 +642,18 @@ namespace OOX m_arrItems.push_back(pXfs); } } + XLS::BaseObjectPtr CCellStyleXfs::toBin() + { + auto ptr(new XLSB::CELLSTYLEXFS); + auto ptr1(new XLSB::BeginCellStyleXFs); + ptr->m_BrtBeginCellStyleXFs = XLS::BaseObjectPtr{ptr1}; + XLS::BaseObjectPtr objectPtr(ptr); + + for(auto i:m_arrItems) + ptr->m_arBrtXF.push_back(i->toBin()); + ptr1->cxfs = ptr->m_arBrtXF.size(); + return objectPtr; + } void CCellStyleXfs::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) { WritingElement_ReadAttributes_Start( oReader ) diff --git a/OOXML/XlsxFormat/Styles/Xfs.h b/OOXML/XlsxFormat/Styles/Xfs.h index 7ab94d1308a..480f460ca73 100644 --- a/OOXML/XlsxFormat/Styles/Xfs.h +++ b/OOXML/XlsxFormat/Styles/Xfs.h @@ -66,6 +66,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + void toBin(XLS::BaseObjectPtr& obj); virtual EElementType getType () const; @@ -103,6 +104,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + void toBin(XLS::BaseObjectPtr& obj); virtual EElementType getType () const; @@ -134,6 +136,7 @@ namespace OOX virtual EElementType getType () const; void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); private: void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); @@ -157,7 +160,7 @@ namespace OOX nullable m_oAligment; nullable m_oProtection; - + }; class CCellXfs : public WritingElementWithChilds @@ -174,6 +177,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(std::vector& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; @@ -202,6 +206,7 @@ namespace OOX virtual EElementType getType () const; void fromBin(std::vector& obj); + XLS::BaseObjectPtr toBin(); private: void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); diff --git a/OOXML/XlsxFormat/Styles/XlsxStyles.cpp b/OOXML/XlsxFormat/Styles/XlsxStyles.cpp index c4c32202bab..f0a974d7b07 100644 --- a/OOXML/XlsxFormat/Styles/XlsxStyles.cpp +++ b/OOXML/XlsxFormat/Styles/XlsxStyles.cpp @@ -61,6 +61,8 @@ #include "../../XlsbFormat/Biff12_unions/STYLES.h" #include "../../XlsbFormat/Biff12_unions/DXFS.h" +#include "../../Binary/XlsbFormat/FileTypes_SpreadsheetBin.h" + namespace OOX { namespace Spreadsheet @@ -123,7 +125,7 @@ namespace OOX WritingElement_ReadAttributes_Read_if(oReader, L"ss:ID", m_sId) WritingElement_ReadAttributes_Read_if(oReader, L"ss:Name", m_sName) WritingElement_ReadAttributes_Read_if(oReader, L"ss:Parent", m_sParentId) - WritingElement_ReadAttributes_End(oReader) + WritingElement_ReadAttributes_End(oReader) } //---------------------------------------------------------------------------------------------------------------------- @@ -210,6 +212,44 @@ namespace OOX } } + XLS::BaseObjectPtr CStyles::WriteBin() const + { + XLSB::StylesStreamPtr stylesStream(new XLSB::StylesStream); + XLS::BaseObjectPtr objectPtr(stylesStream); + if (m_oNumFmts.IsInit()) + stylesStream->m_FMTS = m_oNumFmts->toBin(); + + if (m_oFonts.IsInit()) + stylesStream->m_FONTS = m_oFonts->toBin(); + + if (m_oFills.IsInit()) + stylesStream->m_FILLS = m_oFills->toBin(); + + if (m_oBorders.IsInit()) + stylesStream->m_BORDERS = m_oBorders->toBin(); + + if (m_oCellStyleXfs.IsInit()) + stylesStream->m_CELLSTYLEXFS = m_oCellStyleXfs->toBin(); + + if (m_oCellXfs.IsInit()) + stylesStream->m_CELLXFS = m_oCellXfs->toBin(); + + if (m_oCellStyles.IsInit()) + stylesStream->m_STYLES = m_oCellStyles->toBin(); + + if (m_oDxfs.IsInit()) + stylesStream->m_DXFS = m_oDxfs->toBin(); + + if (m_oTableStyles.IsInit()) + stylesStream->m_TABLESTYLES = m_oTableStyles->toBin(); + + if (m_oColors.IsInit()) + stylesStream->m_COLORPALETTE = m_oColors->toBin(); + + if (m_oExtLst.IsInit()) + stylesStream->m_FRTSTYLESHEET = m_oExtLst->toBinStyles(); + return objectPtr; + } void CStyles::read(const CPath& oPath) { //don't use this. use read(const CPath& oRootPath, const CPath& oFilePath) @@ -324,6 +364,14 @@ namespace OOX } void CStyles::write(const CPath& oPath, const CPath& oDirectory, CContentTypes& oContent) const { + CXlsb* xlsb = dynamic_cast(File::m_pMainDocument); + if ((xlsb) && (xlsb->m_bWriteToXlsb)) + { + XLS::BaseObjectPtr object = WriteBin(); + xlsb->WriteBin(oPath, object.get()); + } + else + { NSStringUtils::CStringBuilder sXml; sXml.WriteString(L"\ @@ -341,7 +389,7 @@ xmlns:x16r2=\"http://schemas.microsoft.com/office/spreadsheetml/2015/02/main\">" std::wstring sPath = oPath.GetPath(); NSFile::CFileBinary::SaveToFile(sPath.c_str(), sXml.GetData()); - + } oContent.Registration(type().OverrideType(), oDirectory, oPath.GetFilename()); } void CStyles::AfterRead() @@ -395,7 +443,7 @@ xmlns:x16r2=\"http://schemas.microsoft.com/office/spreadsheetml/2015/02/main\">" cell_style->m_oName = L"Normal"; m_oCellStyles->m_arrItems.push_back(cell_style); - + CXfs *cell_xfs = new CXfs(); cell_xfs->m_oXfId = iXfs; @@ -758,6 +806,11 @@ xmlns:x16r2=\"http://schemas.microsoft.com/office/spreadsheetml/2015/02/main\">" } const OOX::FileType CStyles::type() const { + CXlsb* xlsb = dynamic_cast(File::m_pMainDocument); + if ((xlsb) && (xlsb->m_bWriteToXlsb)) + { + return OOX::SpreadsheetBin::FileTypes::StylesBin; + } return OOX::Spreadsheet::FileTypes::Styles; } const CPath CStyles::DefaultDirectory() const @@ -766,7 +819,18 @@ xmlns:x16r2=\"http://schemas.microsoft.com/office/spreadsheetml/2015/02/main\">" } const CPath CStyles::DefaultFileName() const { - return type().DefaultFileName(); + CXlsb* xlsb = dynamic_cast(File::m_pMainDocument); + if ((xlsb) && (xlsb->m_bWriteToXlsb)) + { + CPath name = type().DefaultFileName(); + + name.SetExtention(L"bin"); + return name; + } + else + { + return type().DefaultFileName(); + } } const CPath& CStyles::GetReadPath() { diff --git a/OOXML/XlsxFormat/Styles/dxf.cpp b/OOXML/XlsxFormat/Styles/dxf.cpp index 7a655abf889..d34afbdcd02 100644 --- a/OOXML/XlsxFormat/Styles/dxf.cpp +++ b/OOXML/XlsxFormat/Styles/dxf.cpp @@ -41,10 +41,13 @@ #include "../../XlsbFormat/Biff12_unions/DXF.h" #include "../../XlsbFormat/Biff12_unions/FRTDXF.h" #include "../../XlsbFormat/Biff12_records/CommonRecords.h" +#include "../../XlsbFormat/Biff12_records/BeginDXFs.h" #include "../../Common/SimpleTypes_Shared.h" #include +#include "../../XlsbFormat/Biff12_unions/DXFS.h" + namespace OOX { namespace Spreadsheet @@ -196,6 +199,23 @@ namespace OOX } } + XLS::BaseObjectPtr CDxf::toBin() + { + auto ptr(new XLSB::DXF); + auto ptr1(new XLSB::FRTDXF); + ptr1->m_BrtDXF = XLS::BaseObjectPtr{ptr}; + XLS::BaseObjectPtr objectPtr(ptr1); + NSStringUtils::CStringBuilder writer; + toXML(writer); + XmlUtils::CXmlLiteReader oReader; + auto stringData = writer.GetData(); + + if ( !oReader.FromString(stringData)) + return objectPtr; + ptr->deserialize(oReader); + + return objectPtr; + } EElementType CDxf::getType () const { return et_x_Dxf; @@ -300,6 +320,21 @@ namespace OOX m_arrItems.push_back(new CDxf(dxf)); } } + XLS::BaseObjectPtr CDxfs::toBin() + { + auto ptr(new XLSB::DXFS); + XLS::BaseObjectPtr objectPtr(ptr); + auto ptr1(new XLSB::BeginDXFs); + ptr->m_BrtBeginDXFs = XLS::BaseObjectPtr{ptr1}; + for(auto i:m_arrItems) + { + auto udxf(new XLSB::uDXF); + udxf->m_BrtFRTDXF = i->toBin(); + ptr->m_aruDXF.push_back(XLS::BaseObjectPtr{udxf}); + } + ptr1->cdxfs = ptr->m_aruDXF.size(); + return objectPtr; + } void CDxfs::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) { // Читаем атрибуты diff --git a/OOXML/XlsxFormat/Styles/dxf.h b/OOXML/XlsxFormat/Styles/dxf.h index 62a9d518f2e..79b6679a8fd 100644 --- a/OOXML/XlsxFormat/Styles/dxf.h +++ b/OOXML/XlsxFormat/Styles/dxf.h @@ -67,6 +67,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; @@ -100,6 +101,7 @@ namespace OOX virtual EElementType getType () const; void fromBin(std::vector& obj); + XLS::BaseObjectPtr toBin(); private: void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); diff --git a/OOXML/XlsxFormat/Styles/rPr.cpp b/OOXML/XlsxFormat/Styles/rPr.cpp index 192199119e1..98bddcca44f 100644 --- a/OOXML/XlsxFormat/Styles/rPr.cpp +++ b/OOXML/XlsxFormat/Styles/rPr.cpp @@ -37,6 +37,7 @@ #include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_structures/BIFF12/Color.h" #include "../../XlsbFormat/Biff12_records/IndexedColor.h" #include "../../XlsbFormat/Biff12_records/MRUColor.h" +#include "../../XlsbFormat/Biff12_records/Color14.h" #include "../ComplexTypes_Spreadsheet.h" @@ -68,6 +69,24 @@ namespace OOX m_oRgb = SimpleTypes::Spreadsheet::CHexColor(ptr->bRed, ptr->bGreen, ptr->bBlue); } } + XLS::BaseObjectPtr CRgbColor::toBin() + { + auto ptr(new XLSB::IndexedColor); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oRgb.IsInit()) + { + ptr->bRed = m_oRgb->Get_R(); + ptr->bGreen = m_oRgb->Get_G(); + ptr->bBlue = m_oRgb->Get_B(); + } + else + { + ptr->bRed = 0; + ptr->bGreen = 0; + ptr->bBlue = 0; + } + return objectPtr; + } EElementType CRgbColor::getType () const { return et_x_RgbColor; @@ -136,6 +155,13 @@ namespace OOX m_arrItems.push_back(pRgbColor); } } + std::vector CIndexedColors::toBin() + { + std::vector objectVector; + for(auto i : m_arrItems) + objectVector.push_back(i->toBin()); + return objectVector; + } EElementType CIndexedColors::getType () const { return et_x_IndexedColors; @@ -429,6 +455,161 @@ namespace OOX { ReadAttributes(obj); } + XLSB::Color CColor::GetDefaultColor() + { + XLSB::Color ptr; + + ptr.bAlpha = 0; + ptr.bBlue = 0; + ptr.bGreen = 0; + ptr.bRed = 0; + + ptr.xColorType = 0; + ptr.nTintAndShade = 0; + ptr.index = 0; + ptr.fValidRGB = 0; + + return ptr; + } + XLSB::Color CColor::toColor() + { + XLSB::Color ptr; + + ptr.bAlpha = 255; + ptr.bBlue = 0; + ptr.bGreen = 0; + ptr.bRed = 0; + ptr.fValidRGB = false; + ptr.index = 0; + + if(m_oAuto.IsInit()) + { + if(m_oAuto->GetValue()) + ptr.xColorType = 0; + } + else if(m_oIndexed.IsInit()) + { + ptr.index = m_oIndexed->GetValue(); + ptr.xColorType = 1; + } + else if(m_oThemeColor.IsInit()) + { + ptr.index = m_oThemeColor->GetValue(); + ptr.xColorType = 3; + } + else if(m_oRgb.IsInit()) + { + ptr.bAlpha = m_oRgb->Get_A(); + ptr.bBlue = m_oRgb->Get_B(); + ptr.bGreen = m_oRgb->Get_G(); + ptr.bRed = m_oRgb->Get_R(); + ptr.xColorType = 2; + ptr.fValidRGB = true; + } + else + ptr.xColorType = 0; + + + if ( m_oTint.IsInit()) + { + ptr.nTintAndShade = m_oTint->GetValue() * 32767.0; + } + else + ptr.nTintAndShade = 0; + return ptr; + } + XLS::BaseObjectPtr CColor::toBin() + { + auto ptr(new XLSB::Color); + + XLS::BaseObjectPtr objectPtr(ptr); + + ptr->bAlpha = 0; + ptr->bRed = 0; + ptr->bGreen = 0; + ptr->bBlue = 0; + ptr->index = 0; + ptr->fValidRGB = false; + + if(m_oAuto.IsInit()) + { + if(m_oAuto->GetValue()) + ptr->xColorType = 0; + } + else if(m_oIndexed.IsInit()) + { + ptr->index = m_oIndexed->GetValue(); + ptr->xColorType = 1; + } + else if(m_oThemeColor.IsInit()) + { + ptr->index = m_oThemeColor->GetValue(); + ptr->xColorType = 3; + } + else + { + ptr->bAlpha = m_oRgb->Get_A(); + ptr->bBlue = m_oRgb->Get_B(); + ptr->bGreen = m_oRgb->Get_G(); + ptr->bRed = m_oRgb->Get_R(); + ptr->xColorType = 2; + ptr->fValidRGB = true; + } + + if ( m_oTint.IsInit()) + { + ptr->nTintAndShade = m_oTint->GetValue() * 32767.0; + } + else + ptr->nTintAndShade = 0; + return objectPtr; + } + XLS::BaseObjectPtr CColor::toBin14() + { + auto ptr(new XLSB::Color14); + + XLS::BaseObjectPtr objectPtr(ptr); + + ptr->color.bAlpha = 0; + ptr->color.bRed = 0; + ptr->color.bGreen = 0; + ptr->color.bBlue = 0; + ptr->color.index = 0; + ptr->color.fValidRGB = false; + + if(m_oAuto.IsInit()) + { + if(m_oAuto->GetValue()) + ptr->color.xColorType = 0; + } + else if(m_oIndexed.IsInit()) + { + ptr->color.index = m_oIndexed->GetValue(); + ptr->color.xColorType = 1; + } + else if(m_oThemeColor.IsInit()) + { + ptr->color.index = m_oThemeColor->GetValue(); + ptr->color.xColorType = 3; + } + else + { + ptr->color.bAlpha = m_oRgb->Get_A(); + ptr->color.bBlue = m_oRgb->Get_B(); + ptr->color.bGreen = m_oRgb->Get_G(); + ptr->color.bRed = m_oRgb->Get_R(); + ptr->color.xColorType = 2; + ptr->color.fValidRGB = true; + } + + if ( m_oTint.IsInit()) + { + ptr->color.nTintAndShade = m_oTint->GetValue() * 32767.0; + } + else + ptr->color.nTintAndShade = 0; + return objectPtr; + } EElementType CColor::getType () const { return et_x_Color; @@ -567,6 +748,13 @@ namespace OOX m_arrItems.push_back(color); } } + std::vector CMruColors::toBin() + { + std::vector objectVector; + for(auto i:m_arrItems) + objectVector.push_back(i->toBin()); + return objectVector; + } EElementType CMruColors::getType () const { return et_x_MruColors; @@ -702,6 +890,10 @@ namespace OOX if ( !oReader.IsEmptyNode() ) oReader.ReadTillEnd(); + if(!m_oUnderline.IsInit()) + { + m_oUnderline.Init(); + } } std::wstring CUnderline::toXML() const { @@ -1296,6 +1488,26 @@ namespace OOX m_oVertAlign = font->m_oVertAlign; } + CFont* CRPr::toFont() + { + auto font(new CFont); + font->m_oBold = m_oBold; + font->m_oCharset = m_oCharset; + font->m_oColor = m_oColor; + font->m_oCondense = m_oCondense; + font->m_oExtend = m_oExtend; + font->m_oFamily = m_oFamily; + font->m_oItalic = m_oItalic; + font->m_oOutline = m_oOutline; + font->m_oRFont = m_oRFont; + font->m_oScheme = m_oScheme; + font->m_oShadow = m_oShadow; + font->m_oStrike = m_oStrike; + font->m_oSz = m_oSz; + font->m_oUnderline = m_oUnderline; + font->m_oVertAlign = m_oVertAlign; + return font; + } } //Spreadsheet } // OOX diff --git a/OOXML/XlsxFormat/Styles/rPr.h b/OOXML/XlsxFormat/Styles/rPr.h index f0ec51018ae..3c5babadb07 100644 --- a/OOXML/XlsxFormat/Styles/rPr.h +++ b/OOXML/XlsxFormat/Styles/rPr.h @@ -33,6 +33,7 @@ #include "../WritingElement.h" #include "../../Base/Nullable.h" +#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_structures/BIFF12/Color.h" namespace NSBinPptxRW { @@ -55,7 +56,7 @@ namespace SimpleTypes class CFontCharset; class CFontFamily; class CFontScheme; - class CUnderline; + class CUnderline; } } @@ -65,7 +66,7 @@ namespace ComplexTypes { class COnOff2; class String; - class CDouble; + class CDouble; } } @@ -87,6 +88,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; private: @@ -98,7 +100,7 @@ namespace OOX public: nullable m_oRgb; }; - + class CIndexedColors : public WritingElementWithChilds { public: @@ -114,6 +116,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(std::vector& obj); + std::vector toBin(); virtual EElementType getType () const; static bool GetDefaultRGBAByIndex(int index, unsigned char& unR, unsigned char& unG, unsigned char& unB, unsigned char& unA); @@ -144,6 +147,10 @@ namespace OOX void fromBin(XLS::BaseObjectPtr& obj); void fromBin(XLS::BaseObject* obj); + XLS::BaseObjectPtr toBin(); + XLS::BaseObjectPtr toBin14(); + XLSB::Color toColor(); + XLSB::Color GetDefaultColor(); virtual EElementType getType () const; @@ -175,6 +182,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(std::vector& obj); + std::vector toBin(); virtual EElementType getType () const; private: @@ -296,6 +304,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromFont(CFont* font); + CFont* toFont(); void fromXLSB (NSBinPptxRW::CBinaryFileReader& oStream, _UINT16 nType); void toXLSB (NSBinPptxRW::CXlsbBinaryWriter& oStream) const; _UINT32 getXLSBSize() const; diff --git a/OOXML/XlsxFormat/Table/Autofilter.cpp b/OOXML/XlsxFormat/Table/Autofilter.cpp index 908052d894a..593d1bd39ad 100644 --- a/OOXML/XlsxFormat/Table/Autofilter.cpp +++ b/OOXML/XlsxFormat/Table/Autofilter.cpp @@ -104,6 +104,49 @@ namespace OOX { ReadAttributes(obj); } + XLS::BaseObjectPtr CSortCondition::toBin() + { + auto ptr(new XLSB::BeginSortCond); + auto ptr1(new XLSB::SORTCOND); + ptr1->m_BrtBeginSortCond = XLS::BaseObjectPtr{ptr}; + XLS::BaseObjectPtr objectPtr(ptr1); + + if(m_oDescending.IsInit()) + ptr->fSortDes = m_oDescending->GetValue(); + else + ptr->fSortDes = 0; + if(m_oRef.IsInit()) + ptr->rfx = m_oRef->GetValue(); + if(m_oSortBy.IsInit()) + { + if(m_oSortBy == SimpleTypes::Spreadsheet::ESortBy::sortbyValue) + { + ptr->sortOn = 0; + } + else if(m_oSortBy == SimpleTypes::Spreadsheet::ESortBy::sortbyCellColor) + { + ptr->sortOn = 1; + ptr->condDataValue.condDataValue = m_oDxfId->GetValue(); + } + else if(m_oSortBy == SimpleTypes::Spreadsheet::ESortBy::sortbyFontColor) + { + ptr->sortOn = 2; + ptr->condDataValue.condDataValue = m_oDxfId->GetValue(); + } + else if(m_oSortBy == SimpleTypes::Spreadsheet::ESortBy::sortbyIcon) + { + ptr->sortOn = 3; + } + else + ptr->sortOn = 0; + } + else + ptr->sortOn = 0; + + + ptr->stSslist = L""; + return objectPtr; + } EElementType CSortCondition::getType () const { return et_x_SortCondition; @@ -130,7 +173,7 @@ namespace OOX if(ptr != nullptr) { m_oDescending = ptr->fSortDes; - m_oRef = ptr->rfx.toString(); + m_oRef = ptr->rfx.toString(true, true); switch (ptr->sortOn) { case 0: @@ -158,7 +201,7 @@ namespace OOX if(ptr != nullptr) { m_oDescending = ptr->fSortDes; - m_oRef = ptr->rfx.toString(); + m_oRef = ptr->rfx.toString(true, true); switch (ptr->sortOn) { case 0: @@ -254,8 +297,38 @@ namespace OOX for(auto &pSORTCOND14 : ptrACSORTCONDS->m_arSORTCOND14) m_arrItems.push_back(new CSortCondition(static_cast(pSORTCOND14.get())->m_BrtBeginSortCond14)); } + } + XLS::BaseObjectPtr CSortState::toBin() + { + auto ptr(new XLSB::SORTSTATE); + XLS::BaseObjectPtr objectPtr(ptr); + auto beginSortState(new XLSB::BeginSortState); + ptr->m_BrtBeginSortState = XLS::BaseObjectPtr{beginSortState}; + if(m_oRef.IsInit()) + beginSortState->rfx = m_oRef->GetValue(); + if(m_oCaseSensitive.IsInit()) + beginSortState->fCaseSensitive = m_oCaseSensitive->GetValue(); + else + beginSortState->fCaseSensitive = false; + if(m_oColumnSort.IsInit()) + beginSortState->fCol = m_oColumnSort->GetValue(); + else + beginSortState->fCol = false; + if(m_oSortMethod == SimpleTypes::Spreadsheet::ESortMethod::sortmethodStroke) + beginSortState->fAltMethod = true; + else + beginSortState->fAltMethod = false; + + auto sortConds(new XLSB::SORTCONDS); + ptr->m_source = XLS::BaseObjectPtr{sortConds}; + for(auto i:m_arrItems) + { + sortConds->m_arSORTCOND.push_back(i->toBin()); + } + beginSortState->cconditions = sortConds->m_arSORTCOND.size(); + return objectPtr; } EElementType CSortState::getType () const { @@ -328,6 +401,20 @@ namespace OOX { ReadAttributes(obj); } + XLS::BaseObjectPtr CColorFilter::toBin() + { + auto ptr(new XLSB::ColorFilter); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oCellColor.IsInit()) + ptr->fCellColor = m_oCellColor->GetValue(); + else + ptr->fCellColor = false; + if(m_oDxfId.IsInit()) + ptr->dxfid = m_oDxfId->GetValue(); + else + ptr->dxfid = 0; + return objectPtr; + } EElementType CColorFilter::getType () const { return et_x_ColorFilter; @@ -392,6 +479,100 @@ namespace OOX { ReadAttributes(obj); } + XLS::BaseObjectPtr CDynamicFilter::toBin() + { + auto ptr(new XLSB::DynamicFilter); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oType.IsInit()) + { + if (m_oType == SimpleTypes::Spreadsheet::EDynamicFilterType::dynamicfiltertypeNull) + ptr->cft = 0x00000000; + else if (m_oType == SimpleTypes::Spreadsheet::EDynamicFilterType::dynamicfiltertypeAboveAverage) + ptr->cft = 0x00000001; + else if (m_oType == SimpleTypes::Spreadsheet::EDynamicFilterType::dynamicfiltertypeBelowAverage) + ptr->cft = 0x00000002; + else if (m_oType == SimpleTypes::Spreadsheet::EDynamicFilterType::dynamicfiltertypeTomorrow) + ptr->cft = 0x00000008; + else if (m_oType == SimpleTypes::Spreadsheet::EDynamicFilterType::dynamicfiltertypeToday) + ptr->cft = 0x00000009; + else if (m_oType == SimpleTypes::Spreadsheet::EDynamicFilterType::dynamicfiltertypeYesterday) + ptr->cft = 0x0000000A; + else if (m_oType == SimpleTypes::Spreadsheet::EDynamicFilterType::dynamicfiltertypeNextWeek) + ptr->cft = 0x0000000B; + else if (m_oType == SimpleTypes::Spreadsheet::EDynamicFilterType::dynamicfiltertypeThisWeek) + ptr->cft = 0x0000000C; + else if (m_oType == SimpleTypes::Spreadsheet::EDynamicFilterType::dynamicfiltertypeLastWeek) + ptr->cft = 0x0000000D; + else if (m_oType == SimpleTypes::Spreadsheet::EDynamicFilterType::dynamicfiltertypeNextMonth) + ptr->cft = 0x0000000E; + else if (m_oType == SimpleTypes::Spreadsheet::EDynamicFilterType::dynamicfiltertypeThisMonth) + ptr->cft = 0x0000000F; + else if (m_oType == SimpleTypes::Spreadsheet::EDynamicFilterType::dynamicfiltertypeLastMonth) + ptr->cft = 0x00000010; + else if (m_oType == SimpleTypes::Spreadsheet::EDynamicFilterType::dynamicfiltertypeNextQuarter) + ptr->cft = 0x00000011; + else if (m_oType == SimpleTypes::Spreadsheet::EDynamicFilterType::dynamicfiltertypeThisQuarter) + ptr->cft = 0x00000012; + else if (m_oType == SimpleTypes::Spreadsheet::EDynamicFilterType::dynamicfiltertypeLastQuarter) + ptr->cft = 0x00000013; + else if (m_oType == SimpleTypes::Spreadsheet::EDynamicFilterType::dynamicfiltertypeNextYear) + ptr->cft = 0x00000014; + else if (m_oType == SimpleTypes::Spreadsheet::EDynamicFilterType::dynamicfiltertypeThisYear) + ptr->cft = 0x00000015; + else if (m_oType == SimpleTypes::Spreadsheet::EDynamicFilterType::dynamicfiltertypeLastYear) + ptr->cft = 0x00000016; + else if (m_oType == SimpleTypes::Spreadsheet::EDynamicFilterType::dynamicfiltertypeYearToDate) + ptr->cft = 0x00000017; + else if (m_oType == SimpleTypes::Spreadsheet::EDynamicFilterType::dynamicfiltertypeQ1) + ptr->cft = 0x00000018; + else if (m_oType == SimpleTypes::Spreadsheet::EDynamicFilterType::dynamicfiltertypeQ2) + ptr->cft = 0x00000019; + else if (m_oType == SimpleTypes::Spreadsheet::EDynamicFilterType::dynamicfiltertypeQ3) + ptr->cft = 0x0000001A; + else if (m_oType == SimpleTypes::Spreadsheet::EDynamicFilterType::dynamicfiltertypeQ4) + ptr->cft = 0x0000001B; + else if (m_oType == SimpleTypes::Spreadsheet::EDynamicFilterType::dynamicfiltertypeM1) + ptr->cft = 0x0000001C; + else if (m_oType == SimpleTypes::Spreadsheet::EDynamicFilterType::dynamicfiltertypeM2) + ptr->cft = 0x0000001D; + else if (m_oType == SimpleTypes::Spreadsheet::EDynamicFilterType::dynamicfiltertypeM3) + ptr->cft = 0x0000001E; + else if (m_oType == SimpleTypes::Spreadsheet::EDynamicFilterType::dynamicfiltertypeM4) + ptr->cft = 0x0000001F; + else if (m_oType == SimpleTypes::Spreadsheet::EDynamicFilterType::dynamicfiltertypeM5) + ptr->cft = 0x00000020; + else if (m_oType == SimpleTypes::Spreadsheet::EDynamicFilterType::dynamicfiltertypeM6) + ptr->cft = 0x00000021; + else if (m_oType == SimpleTypes::Spreadsheet::EDynamicFilterType::dynamicfiltertypeM7) + ptr->cft = 0x00000022; + else if (m_oType == SimpleTypes::Spreadsheet::EDynamicFilterType::dynamicfiltertypeM8) + ptr->cft = 0x00000023; + else if (m_oType == SimpleTypes::Spreadsheet::EDynamicFilterType::dynamicfiltertypeM9) + ptr->cft = 0x00000024; + else if (m_oType == SimpleTypes::Spreadsheet::EDynamicFilterType::dynamicfiltertypeM10) + ptr->cft = 0x00000025; + else if (m_oType == SimpleTypes::Spreadsheet::EDynamicFilterType::dynamicfiltertypeM11) + ptr->cft = 0x00000026; + else if (m_oType == SimpleTypes::Spreadsheet::EDynamicFilterType::dynamicfiltertypeM12) + ptr->cft = 0x00000027; + } + else + ptr->cft = 0x00000000; + if (m_oVal.IsInit()) + { + ptr->xNumValue.data.value = m_oVal->GetValue(); + } + else + ptr->xNumValue.data.value = 0; + + if (m_oMaxVal.IsInit()) + { + ptr->xNumValueMax.data.value = m_oMaxVal->GetValue(); + } + else + ptr->xNumValueMax.data.value = 0; + return objectPtr; + } EElementType CDynamicFilter::getType () const { return et_x_DynamicFilter; @@ -531,6 +712,40 @@ namespace OOX { ReadAttributes(obj); } + XLS::BaseObjectPtr CCustomFilter::toBin() + { + auto ptr(new XLSB::CustomFilter); + XLS::BaseObjectPtr objectPtr(ptr); + + if (m_oOperator == SimpleTypes::Spreadsheet::ECustomFilter::customfilterLessThan) + { + ptr->grbitSgn = 0x01; + } + else if (m_oOperator == SimpleTypes::Spreadsheet::ECustomFilter::customfilterEqual) + { + ptr->grbitSgn = 0x02; + } + else if (m_oOperator == SimpleTypes::Spreadsheet::ECustomFilter::customfilterLessThanOrEqual) + { + ptr->grbitSgn = 0x03; + } + else if (m_oOperator == SimpleTypes::Spreadsheet::ECustomFilter::customfilterGreaterThan) + { + ptr->grbitSgn = 0x04; + } + else if (m_oOperator == SimpleTypes::Spreadsheet::ECustomFilter::customfilterNotEqual) + { + ptr->grbitSgn = 0x05; + } + else if (m_oOperator == SimpleTypes::Spreadsheet::ECustomFilter::customfilterGreaterThanOrEqual) + { + ptr->grbitSgn = 0x06; + } + ptr->vts = 0x00000006; + ptr->vtsStringXls = m_oVal.get(); + + return objectPtr; + } EElementType CCustomFilter::getType () const { return et_x_CustomFilters; @@ -647,6 +862,21 @@ namespace OOX } } } + XLS::BaseObjectPtr CCustomFilters::toBin() + { + auto ptr(new XLSB::CUSTOMFILTERS); + XLS::BaseObjectPtr objectPtr(ptr); + auto customFilters(new XLSB::BeginCustomFilters); + ptr->m_BrtBeginCustomFilters = XLS::BaseObjectPtr{customFilters}; + + customFilters->fAnd = m_oAnd->GetValue(); + + for(auto i:m_arrItems) + { + ptr->m_arBrtCustomFilter.push_back(i->toBin()); + } + return objectPtr; + } EElementType CCustomFilters::getType () const { return et_x_CustomFilters; @@ -707,6 +937,13 @@ namespace OOX { ReadAttributes(obj); } + XLS::BaseObjectPtr CFilter::toBin() + { + auto ptr(new XLSB::Filter); + XLS::BaseObjectPtr objectPtr(ptr); + ptr->rgch = m_oVal.get(); + return objectPtr; + } EElementType CFilter::getType () const { return et_x_Filter; @@ -773,6 +1010,63 @@ namespace OOX { ReadAttributes(obj); } + XLS::BaseObjectPtr CDateGroupItem::toBin() + { + auto ptr(new XLSB::AFilterDateGroupItem); + XLS::BaseObjectPtr objectPtr(ptr); + + if (m_oDateTimeGrouping == SimpleTypes::Spreadsheet::EDateTimeGroup::datetimegroupYear) + { + ptr->dntChecked = 0x00000000; + } + else if (m_oDateTimeGrouping == SimpleTypes::Spreadsheet::EDateTimeGroup::datetimegroupMonth) + { + ptr->dntChecked = 0x00000001; + } + else if (m_oDateTimeGrouping == SimpleTypes::Spreadsheet::EDateTimeGroup::datetimegroupDay) + { + ptr->dntChecked = 0x00000002; + } + else if (m_oDateTimeGrouping == SimpleTypes::Spreadsheet::EDateTimeGroup::datetimegroupHour) + { + ptr->dntChecked = 0x00000003; + } + else if (m_oDateTimeGrouping == SimpleTypes::Spreadsheet::EDateTimeGroup::datetimegroupMinute) + { + ptr->dntChecked = 0x00000004; + } + else if (m_oDateTimeGrouping == SimpleTypes::Spreadsheet::EDateTimeGroup::datetimegroupSecond) + { + ptr->dntChecked = 0x00000005; + } + else + ptr->dntChecked = 0x00000000; + if(m_oDay.IsInit()) + ptr->dom = m_oDay->GetValue(); + else + ptr->dom = 0; + if(m_oHour.IsInit()) + ptr->hour = m_oHour->GetValue(); + else + ptr->hour = 0; + if(m_oMinute.IsInit()) + ptr->min = m_oMinute->GetValue(); + else + ptr->min = 0; + if(m_oMonth.IsInit()) + ptr->mon = m_oMonth->GetValue(); + else + ptr->mon = 0; + if(m_oSecond.IsInit()) + ptr->sec = m_oSecond->GetValue(); + else + ptr->sec = 0; + if(m_oYear.IsInit()) + ptr->yr = m_oYear->GetValue(); + else + ptr->yr = 0; + return objectPtr; + } EElementType CDateGroupItem::getType () const { return et_x_DateGroupItem; @@ -911,6 +1205,27 @@ namespace OOX } } } + XLS::BaseObjectPtr CFilters::toBin() + { + auto ptr(new XLSB::FILTERS); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oBlank.IsInit()) + { + auto beginFilters(new XLSB::BeginFilters); + beginFilters->fBlank = m_oBlank->GetValue(); + } + for(auto i: m_arrItems) + { + if (CFilter* cfilter = dynamic_cast(i)) { + // Элемент является экземпляром класса CFilter + ptr->m_arBrtFilter.push_back(cfilter->toBin()); + } else if (CDateGroupItem* groupItem = dynamic_cast(i)) { + // Элемент является экземпляром класса CDateGroupItem + ptr->m_arBrtAFilterDateGroupItem.push_back(groupItem->toBin()); + } + } + return objectPtr; + } EElementType CFilters::getType () const { return et_x_Filters; @@ -976,6 +1291,29 @@ namespace OOX { ReadAttributes(obj); } + XLS::BaseObjectPtr CTop10::toBin() + { + auto ptr(new XLSB::Top10Filter); + XLS::BaseObjectPtr objectPtr(ptr); + + if (m_oFilterVal.IsInit()) + ptr->xNumValue.data.value = m_oFilterVal->GetValue(); + else + ptr->xNumValue.data.value = 0; + if (m_oPercent.IsInit()) + ptr->fPercent = m_oPercent->GetValue(); + else + ptr->fPercent = false; + if (m_oTop.IsInit()) + ptr->fTop = m_oTop->GetValue(); + else + ptr->fTop = 0; + if (m_oVal.IsInit()) + ptr->xNumFilter.data.value = m_oVal->GetValue(); + else + ptr->xNumFilter.data.value = 0; + return objectPtr; + } EElementType CTop10::getType () const { return et_x_ColorFilter; @@ -1092,6 +1430,38 @@ namespace OOX } } } + XLS::BaseObjectPtr CFilterColumn::toBin() + { + auto ptr(new XLSB::FILTERCOLUMN); + XLS::BaseObjectPtr objectPtr(ptr); + auto beginfilter(new XLSB::BeginFilterColumn); + ptr->m_BrtBeginFilterColumn = XLS::BaseObjectPtr{beginfilter}; + + if(m_oColId.IsInit()) + beginfilter->dwCol = m_oColId->GetValue(); + else + beginfilter->dwCol = 0; + if(m_oHiddenButton.IsInit()) + beginfilter->fHideArrow = m_oHiddenButton->GetValue(); + else + beginfilter->fHideArrow = false; + if(m_oShowButton.IsInit()) + beginfilter->fNoBtn = m_oShowButton->GetValue(); + else + beginfilter->fNoBtn = false; + if(m_oColorFilter.IsInit()) + ptr->m_source = m_oColorFilter->toBin(); + else if(m_oDynamicFilter.IsInit()) + ptr->m_source = m_oDynamicFilter->toBin(); + else if(m_oCustomFilters.IsInit()) + ptr->m_source = m_oCustomFilters->toBin(); + else if(m_oFilters.IsInit()) + ptr->m_source = m_oFilters->toBin(); + else if(m_oTop10.IsInit()) + ptr->m_source = m_oTop10->toBin(); + + return objectPtr; + } EElementType CFilterColumn::getType () const { return et_x_FilterColumn; @@ -1190,6 +1560,21 @@ namespace OOX } } } + XLS::BaseObjectPtr CAutofilter::toBin() + { + auto ptr(new XLSB::AUTOFILTER); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oRef.IsInit()) + { + auto beginFilter(new XLSB::BeginAFilter); + beginFilter->rfx = m_oRef->GetValue(); + ptr->m_BrtBeginAFilter = XLS::BaseObjectPtr{beginFilter}; + } + if(m_oSortState.IsInit()) + ptr->m_SORTSTATE = m_oSortState->toBin(); + + return objectPtr; + } EElementType CAutofilter::getType () const { return et_x_Autofilter; @@ -1205,7 +1590,7 @@ namespace OOX auto ptr = static_cast(obj.get()); if(ptr != nullptr) { - m_oRef = ptr->rfx.toString(); + m_oRef = ptr->rfx.toString(true, true); } } diff --git a/OOXML/XlsxFormat/Table/Autofilter.h b/OOXML/XlsxFormat/Table/Autofilter.h index 4a4ab8d6abb..ce6d0fd1279 100644 --- a/OOXML/XlsxFormat/Table/Autofilter.h +++ b/OOXML/XlsxFormat/Table/Autofilter.h @@ -71,6 +71,7 @@ namespace OOX void toXMLWithNS(NSStringUtils::CStringBuilder& writer, const std::wstring &node_ns, const std::wstring &node_name, const std::wstring &child_ns) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + XLS::BaseObjectPtr toBin(); void fromBin(XLS::BaseObjectPtr& obj); virtual EElementType getType () const; @@ -101,6 +102,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; private: @@ -131,6 +133,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; @@ -159,6 +162,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; @@ -188,6 +192,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; @@ -216,6 +221,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; @@ -242,7 +248,8 @@ namespace OOX void toXMLWithNS(NSStringUtils::CStringBuilder& writer, const std::wstring &node_ns, const std::wstring &node_name, const std::wstring &child_ns) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); - void fromBin(XLS::BaseObjectPtr& obj);; + void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; @@ -270,6 +277,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; @@ -303,6 +311,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; @@ -330,6 +339,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; @@ -360,6 +370,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; @@ -393,6 +404,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + XLS::BaseObjectPtr toBin(); void fromBin(XLS::BaseObjectPtr& obj); virtual EElementType getType () const; diff --git a/OOXML/XlsxFormat/Table/Connections.cpp b/OOXML/XlsxFormat/Table/Connections.cpp index bcf807f5d28..8a4d9ca565f 100644 --- a/OOXML/XlsxFormat/Table/Connections.cpp +++ b/OOXML/XlsxFormat/Table/Connections.cpp @@ -55,6 +55,8 @@ #include "../../Common/SimpleTypes_Shared.h" #include "../../Common/SimpleTypes_Spreadsheet.h" +#include "../../Binary/XlsbFormat/FileTypes_SpreadsheetBin.h" + namespace OOX { namespace Spreadsheet @@ -85,6 +87,19 @@ namespace OOX { ReadAttributes(obj); } + XLS::BaseObjectPtr CTextField::toBin() + { + auto ptr(new XLSB::BeginECTwFldInfo); + if(m_oPosition.IsInit()) + ptr->data.fieldStart = m_oPosition.get(); + else + ptr->data.fieldStart = 0; + if(m_oType.IsInit()) + ptr->data.fieldType = m_oType->GetValue(); + else + ptr->data.fieldType = 0; + return XLS::BaseObjectPtr{ptr}; + } EElementType CTextField::getType() const { return et_x_textField; @@ -158,6 +173,14 @@ namespace OOX m_arrItems.push_back(new CTextField(textField)); } } + XLS::BaseObjectPtr CTextFields::toBin() + { + auto ptr(new XLSB::ECTWFLDINFOLST); + for(auto i:m_arrItems) + ptr->m_arBrtBeginECTwFldInfo.push_back(i->toBin()); + + return XLS::BaseObjectPtr{ptr}; + } EElementType CTextFields::getType() const { return et_x_textFields; @@ -295,6 +318,17 @@ namespace OOX { ReadAttributes(obj); } + XLS::BaseObjectPtr CRangePr::toBin() + { + auto ptr(new XLSB::RangePr15); + if(m_oSourceName.IsInit()) + { + ptr->irstSourceName = m_oSourceName.get(); + } + else + ptr->irstSourceName.setSize(0xFFFFFFFF); + return XLS::BaseObjectPtr{ptr}; + } EElementType CRangePr::getType() const { return et_x_rangePr; @@ -348,6 +382,35 @@ namespace OOX ReadAttributes(ptr->m_BrtBeginECDbProps); } } + XLS::BaseObjectPtr CDbPr::toBin() + { + auto ptr1(new XLSB::ECDBPROPS); + auto ptr(new XLSB::BeginECDbProps); + ptr1->m_BrtBeginECDbProps = XLS::BaseObjectPtr{ptr}; + if(m_oConnection.IsInit()) + ptr->stConn = m_oConnection.get(); + else + ptr->stConn = false; + if(m_oCommand.IsInit()) + ptr->stCmd = m_oCommand.get(); + else + { + ptr->stCmd = false; + ptr->fLoadCmd = false; + } + if(m_oServerCommand.IsInit()) + ptr->stCmdSvr = m_oServerCommand.get(); + else + { + ptr->fLoadCmdSvr = false; + ptr->stCmdSvr = false; + } + if(m_oCommandType.IsInit()) + ptr->icmdtype = m_oCommandType.get(); + else + ptr->icmdtype = 0; + return XLS::BaseObjectPtr{ptr1}; + } EElementType CDbPr::getType() const { return et_x_dbPr; @@ -416,6 +479,52 @@ namespace OOX ReadAttributes(ptr->m_BrtBeginECOlapProps); } } + XLS::BaseObjectPtr COlapPr::toBin() + { + auto ptr1(new XLSB::ECOLAPPROPS); + auto ptr(new XLSB::BeginECOlapProps); + ptr1->m_BrtBeginECOlapProps = XLS::BaseObjectPtr{ptr}; + + if(m_oLocalConnection.IsInit()) + ptr->stConnLocal = m_oLocalConnection.get(); + else + { + ptr->bLoadConnLocal = false; + ptr->stConnLocal = L""; + } + if(m_oRowDrillCount.IsInit()) + ptr->nDrillthroughRows = m_oRowDrillCount.get(); + else + ptr->nDrillthroughRows = 0; + if(m_oLocal.IsInit()) + ptr->fLocalConn = m_oLocal.get(); + else + { + ptr->fLocalConn = false; + ptr->bLoadConnLocal = false; + } + if(m_oLocalRefresh.IsInit()) + ptr->fNoRefreshCube = m_oLocalRefresh.get(); + else + ptr->fNoRefreshCube = false; + if(m_oSendLocale.IsInit()) + ptr->fUseOfficeLcid = m_oSendLocale.get(); + else + ptr->fUseOfficeLcid = false; + if(m_oServerNumberFormat.IsInit()) + ptr->fSrvFmtNum = m_oServerNumberFormat.get(); + else + ptr->fSrvFmtNum = true; + if(m_oServerFont.IsInit()) + ptr->fSrvFmtFlags = m_oServerFont.get(); + else + ptr->fSrvFmtFlags = true; + if(m_oServerFontColor.IsInit()) + ptr->fSrvFmtFore = m_oServerFontColor.get(); + else + ptr->fSrvFmtFore = true; + return XLS::BaseObjectPtr{ptr1}; + } EElementType COlapPr::getType() const { return et_x_olapPr; @@ -510,6 +619,62 @@ namespace OOX ReadAttributes(ptr->m_BrtBeginECWebProps); } } + XLS::BaseObjectPtr CWebPr::toBin() + { + auto ptr1(new XLSB::ECWEBPROPS); + auto ptr(new XLSB::BeginECWebProps); + ptr1->m_BrtBeginECWebProps = XLS::BaseObjectPtr{ptr}; + + if(m_oUrl.IsInit()) + ptr->stURL = m_oUrl.get(); + else + ptr->fLoadURL = false; + if(m_oPost.IsInit()) + ptr->stWebPost = m_oPost.get(); + else + ptr->fLoadWebPost = false; + if(m_oEditPage.IsInit()) + ptr->stEditWebPage = m_oEditPage.get(); + else + ptr->fLoadEditWebPage = false; + if(m_oXml.IsInit()) + ptr->fSrcIsXML = m_oXml.get(); + else + ptr->fSrcIsXML = false; + if(m_oSourceData.IsInit()) + ptr->fImportSourceData = m_oSourceData.get(); + else + ptr->fImportSourceData = false; + if(m_oConsecutive.IsInit()) + ptr->fConsecDelim = m_oConsecutive.get(); + else + ptr->fConsecDelim = false; + if(m_oFirstRow.IsInit()) + ptr->fSameSettings = m_oFirstRow.get(); + else + ptr->fSameSettings = false; + if(m_oXl97.IsInit()) + ptr->fXL97Format = m_oXl97.get(); + else + ptr->fXL97Format = false; + if(m_oTextDates.IsInit()) + ptr->fNoDateRecog = m_oTextDates.get(); + else + ptr->fNoDateRecog = false; + if(m_oXl2000.IsInit()) + ptr->fRefreshedInXL9 = m_oXl2000.get(); + else + ptr->fRefreshedInXL9 = false; + if(m_oHtmlTables.IsInit()) + ptr->fTablesOnlyHTML = m_oHtmlTables.get(); + else + ptr->fRefreshedInXL9 = false; + if(m_oHtmlFormat.IsInit()) + ptr->wHTMLFmt = m_oHtmlFormat->GetValue(); + else + ptr->wHTMLFmt = false; + return XLS::BaseObjectPtr{ptr1}; + } EElementType CWebPr::getType() const { return et_x_webPr; @@ -623,6 +788,78 @@ namespace OOX m_oTextFields = ptr->m_ECTWFLDINFOLST; } } + XLS::BaseObjectPtr CTextPr::toBin() + { + auto ptr1(new XLSB::ECTXTWIZ); + auto ptr(new XLSB::BeginECTxtWiz); + ptr1->m_BrtBeginECTxtWiz = XLS::BaseObjectPtr{ptr}; + + if(m_oSourceFile.IsInit()) + ptr->stFile = m_oSourceFile.get(); + else + ptr->stFile.setSize(0); + if(m_oFileType.IsInit()) + { + ptr->data.iCpid = m_oFileType->m_eValue; + ptr->data.iCpidNew = m_oFileType->m_eValue; + } + else + { + ptr->data.iCpid = 1; + ptr->data.iCpidNew = 0; + } + if(m_oDecimal.IsInit()) + ptr->data.chDecimal = m_oDecimal.get()[0]; + else + ptr->data.chDecimal = '.'; + if(m_oDelimiter.IsInit()) + ptr->data.chCustom = m_oDelimiter.get()[0]; + else + { + ptr->data.chCustom = 0; + ptr->data.fCustom = false; + } + if(m_oThousands.IsInit()) + ptr->data.chThousSep = m_oThousands.get()[0]; + else + ptr->data.chThousSep = ' '; + if(m_oFirstRow.IsInit()) + ptr->data.rowStartAt = m_oFirstRow.get(); + if(m_oQualifier.IsInit()) + ptr->data.fTextDelim = m_oQualifier->GetValue(); + else + ptr->data.fTextDelim = 0; + if(m_oPrompt.IsInit()) + ptr->data.fPromptForFile = m_oPrompt.get(); + if(m_oDelimited.IsInit()) + ptr->data.fDelimited = m_oDelimited.get(); + else + ptr->data.fDelimited = false; + if(m_oTab.IsInit()) + ptr->data.fTab = m_oTab.get(); + else + ptr->data.fTab = false; + if(m_oSpace.IsInit()) + ptr->data.fSpace = m_oSpace.get(); + else + ptr->data.fSpace = false; + if(m_oComma.IsInit()) + ptr->data.fComma = m_oComma.get(); + else + ptr->data.fComma = false; + if(m_oSemicolon.IsInit()) + ptr->data.fSemiColon = m_oSemicolon.get(); + else + ptr->data.fSemiColon = false; + if(m_oConsecutive.IsInit()) + ptr->data.fConsecutive = m_oConsecutive.get(); + else + ptr->data.fConsecutive = false; + + if(m_oTextFields.IsInit()) + ptr1->m_ECTWFLDINFOLST = m_oTextFields->toBin(); + return XLS::BaseObjectPtr{ptr1}; + } EElementType CTextPr::getType() const { return et_x_textPr; @@ -788,7 +1025,7 @@ namespace OOX auto ptr = static_cast(obj.get()); if (ptr != nullptr) { - //ReadAttributes(ptr->m_BrtBeginExtConn15); + ReadAttributes(ptr->m_BrtBeginExtConn15); if (ptr->m_source != nullptr) { @@ -798,6 +1035,142 @@ namespace OOX } } } + XLS::BaseObjectPtr CConnection::toBin15() + { + XLS::BaseObjectPtr objectPtr; + + auto ptr(new XLSB::EXTCONN15); + objectPtr = XLS::BaseObjectPtr{ptr}; + auto ptr1(new XLSB::BeginExtConn15); + + if(m_oIdExt.IsInit() && !m_oIdExt.get().empty()) + ptr1->irstId = m_oIdExt.get(); + else + { + ptr1->fSandbox = true; + ptr1->irstId.setSize(0xFFFFFFFF); + } + + ptr->m_BrtBeginExtConn15 = XLS::BaseObjectPtr{ptr1}; + if(m_oRangePr.IsInit()) + ptr->m_source = m_oRangePr->toBin(); + return objectPtr; + + } + XLS::BaseObjectPtr CConnection::toBin() + { + XLS::BaseObjectPtr objectPtr; + if(m_oRangePr.IsInit()) + { + auto ptr(new XLSB::EXTCONN15); + objectPtr = XLS::BaseObjectPtr{ptr}; + auto ptr1(new XLSB::BeginExtConn15); + ptr1->fAutoDelete = false; + ptr1->fExcludeFromRefreshAll = false; + ptr1->fSandbox = false; + ptr1->fUsedByAddin = false; + if(m_oId.IsInit()) + ptr1->irstId = m_oId->GetValue(); + else + ptr1->irstId = false; + + ptr->m_BrtBeginExtConn15 = XLS::BaseObjectPtr{ptr1}; + ptr->m_source = m_oRangePr->toBin(); + } + else + { + auto ptr(new XLSB::EXTCONNECTION); + objectPtr = XLS::BaseObjectPtr{ptr}; + auto ptr1(new XLSB::BeginExtConnection); + ptr->m_BrtBeginExtConnection = XLS::BaseObjectPtr{ptr1}; + + if(m_oType.IsInit()) + ptr1->idbtype = m_oType.get(); + else + ptr1->idbtype = 0; + if(m_oName.IsInit()) + ptr1->stConnName = m_oName.get(); + else + ptr1->stConnName = L""; + + if(m_oId.IsInit()) + ptr1->dwConnID = m_oId->GetValue(); + if(m_oCredentials.IsInit()) + ptr1->iCredMethod = m_oCredentials->GetValue(); + + if(m_oBackground.IsInit()) + ptr1->fBackgroundQuery = m_oBackground.get(); + if(m_oDeleted.IsInit()) + ptr1->fDeleted = m_oDeleted.get(); + + if(m_oDescription.IsInit()) + { + ptr1->stConnDesc = m_oDescription.get(); + ptr1->fLoadConnectionDesc = true; + } + if(m_oInterval.IsInit()) + ptr1->wInterval = m_oInterval.get(); + + if(m_oKeepAlive.IsInit()) + ptr1->fMaintain = m_oKeepAlive.get(); + + if(m_oMinRefreshableVersion.IsInit()) + ptr1->bVerRefreshableMin = m_oMinRefreshableVersion.get(); + else if(m_oRefreshedVersion.IsInit()) + ptr1->bVerRefreshableMin = m_oRefreshedVersion.get(); + else + ptr1->bVerRefreshableMin = 0; + + if(m_oNew.IsInit()) + ptr1->fNewQuery = m_oNew.get(); + + if(m_oOdcFile.IsInit()) + { + ptr1->stConnectionFile = m_oOdcFile.get(); + ptr1->fLoadSourceConnectionFile = true; + } + if(m_oOnlyUseConnectionFile.IsInit()) + ptr1->fAlwaysUseConnectionFile = m_oOnlyUseConnectionFile.get(); + + if(m_oReconnectionMethod.IsInit()) + ptr1->irecontype = m_oReconnectionMethod.get(); + + if(m_oRefreshedVersion.IsInit()) + ptr1->bVerRefreshed = m_oRefreshedVersion.get(); + if(m_oRefreshOnLoad.IsInit()) + ptr1->fRefreshOnLoad = m_oRefreshOnLoad.get(); + + if(m_oSaveData.IsInit()) + ptr1->fSaveData = m_oSaveData.get(); + + if(m_oSavePassword.IsInit()) + ptr1->pc = m_oSavePassword.get(); + + if(m_oSingleSignOnId.IsInit()) + { + ptr1->stSso = m_oSingleSignOnId.get(); + ptr1->fLoadSSOApplicationID = true; + } + if(m_oSourceFile.IsInit()) + { + ptr1->stDataFile = m_oSourceFile.get(); + ptr1->fLoadSourceDataFile = true; + } + + if(m_oDbPr.IsInit()) + ptr->m_ECDBPROPS = m_oDbPr->toBin(); + if(m_oOlapPr.IsInit()) + ptr->m_ECOLAPPROPS = m_oOlapPr->toBin(); + if(m_oTextPr.IsInit()) + ptr->m_ECTXTWIZ = m_oTextPr->toBin(); + if(m_oWebPr.IsInit()) + ptr->m_ECWEBPROPS = m_oWebPr->toBin(); + if(m_oExtLst.IsInit()) + ptr->m_FRTEXTCONNECTIONS = m_oExtLst->toBinConnections(); + } + + return objectPtr; + } EElementType CConnection::getType() const { return et_x_Connection; @@ -942,9 +1315,23 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" m_oCount = ptr->m_arEXTCONNECTION.size(); for (auto &connection : ptr->m_arEXTCONNECTION) + { auto connPtr = new CConnection(connection); + if(connPtr->m_oType.IsInit() &&(connPtr->m_oType.get() == 0x66)) + { + delete connPtr; + continue; + } m_arrItems.push_back(new CConnection(connection)); + } } } + XLS::BaseObjectPtr CConnections::toBin() + { + auto ptr(new XLSB::EXTCONNECTIONS); + for(auto i:m_arrItems) + ptr->m_arEXTCONNECTION.push_back(i->toBin()); + return XLS::BaseObjectPtr{ptr}; + } EElementType CConnections::getType() const { return et_x_Connections; @@ -974,6 +1361,13 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" CPath oRootPath; read(oRootPath, oPath); } + XLS::BaseObjectPtr CConnectionsFile::WriteBin() const + { + XLSB::ConnectionsStreamPtr connectionsStream(new XLSB::ConnectionsStream); + if(m_oConnections.IsInit()) + connectionsStream->m_EXTCONNECTIONS = m_oConnections->toBin(); + return XLS::BaseObjectPtr{connectionsStream}; + } void CConnectionsFile::readBin(const CPath& oPath) { CXlsb* xlsb = dynamic_cast(File::m_pMainDocument); @@ -1014,21 +1408,34 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" } void CConnectionsFile::write(const CPath& oPath, const CPath& oDirectory, CContentTypes& oContent) const { - if (false == m_oConnections.IsInit()) return; + if (false == m_oConnections.IsInit() || !m_oConnections.get().m_arrItems.size()) return; - NSStringUtils::CStringBuilder sXml; - - sXml.WriteString(L""); - m_oConnections->toXML(sXml); + CXlsb* xlsb = dynamic_cast(File::m_pMainDocument); + if ((xlsb) && (xlsb->m_bWriteToXlsb)) + { + XLS::BaseObjectPtr object = WriteBin(); + xlsb->WriteBin(oPath, object.get()); + } + else + { + NSStringUtils::CStringBuilder sXml; - std::wstring sPath = oPath.GetPath(); - NSFile::CFileBinary::SaveToFile(sPath, sXml.GetData()); + sXml.WriteString(L""); + m_oConnections->toXML(sXml); + std::wstring sPath = oPath.GetPath(); + NSFile::CFileBinary::SaveToFile(sPath, sXml.GetData()); + } oContent.Registration(type().OverrideType(), oDirectory, oPath.GetFilename()); IFileContainer::Write(oPath, oDirectory, oContent); } const OOX::FileType CConnectionsFile::type() const { + CXlsb* xlsb = dynamic_cast(File::m_pMainDocument); + if ((xlsb) && (xlsb->m_bWriteToXlsb)) + { + return OOX::SpreadsheetBin::FileTypes::ConnectionsBin; + } return OOX::Spreadsheet::FileTypes::Connections; } const CPath CConnectionsFile::DefaultDirectory() const diff --git a/OOXML/XlsxFormat/Table/Connections.h b/OOXML/XlsxFormat/Table/Connections.h index 6fa2dc9f048..5a903fbb620 100644 --- a/OOXML/XlsxFormat/Table/Connections.h +++ b/OOXML/XlsxFormat/Table/Connections.h @@ -73,6 +73,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType() const; void ReadAttributes(XLS::BaseObjectPtr& obj); @@ -95,6 +96,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType() const; void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); @@ -161,6 +163,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType() const; @@ -184,6 +187,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType() const; @@ -212,6 +216,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType() const; void ReadAttributes(XLS::BaseObjectPtr& obj); @@ -241,6 +246,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType() const; @@ -277,6 +283,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType() const; @@ -320,6 +327,8 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); + XLS::BaseObjectPtr toBin15(); virtual EElementType getType() const; @@ -372,6 +381,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType() const; @@ -389,6 +399,7 @@ namespace OOX virtual void read(const CPath& oPath); void readBin(const CPath& oPath); + XLS::BaseObjectPtr WriteBin() const; virtual void read(const CPath& oRootPath, const CPath& oPath); virtual void write(const CPath& oPath, const CPath& oDirectory, CContentTypes& oContent) const; diff --git a/OOXML/XlsxFormat/Table/QueryTable.h b/OOXML/XlsxFormat/Table/QueryTable.h index 9967417ab1c..23ce2196540 100644 --- a/OOXML/XlsxFormat/Table/QueryTable.h +++ b/OOXML/XlsxFormat/Table/QueryTable.h @@ -61,6 +61,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const { return et_x_QueryTableField; @@ -99,6 +100,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const { return et_x_QueryTableFields; @@ -126,6 +128,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const { return et_x_QueryTableDeletedField; @@ -154,6 +157,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const { return et_x_QueryTableFields; @@ -181,6 +185,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const { return et_x_QueryTableRefresh; @@ -224,6 +229,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const { return et_x_QueryTable; @@ -280,6 +286,7 @@ namespace OOX { } void readBin(const CPath& oPath); + XLS::BaseObjectPtr WriteBin() const; virtual void read(const CPath& oPath) { //don't use this. use read(const CPath& oRootPath, const CPath& oFilePath) @@ -288,10 +295,7 @@ namespace OOX } virtual void read(const CPath& oRootPath, const CPath& oPath); virtual void write(const CPath& oPath, const CPath& oDirectory, CContentTypes& oContent) const; - virtual const OOX::FileType type() const - { - return OOX::Spreadsheet::FileTypes::QueryTable; - } + virtual const OOX::FileType type() const; virtual const CPath DefaultDirectory() const { return type().DefaultDirectory(); diff --git a/OOXML/XlsxFormat/Table/Table.h b/OOXML/XlsxFormat/Table/Table.h index b5be81fa45b..585eb7dcad7 100644 --- a/OOXML/XlsxFormat/Table/Table.h +++ b/OOXML/XlsxFormat/Table/Table.h @@ -74,6 +74,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const { @@ -111,6 +112,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const { return et_x_TableStyleInfo; @@ -149,6 +151,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const { return et_x_TableColumn; @@ -201,6 +204,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const { @@ -238,6 +242,7 @@ namespace OOX virtual void toXML2(NSStringUtils::CStringBuilder& writer, int nIndex); virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const { return et_x_Table; @@ -300,6 +305,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const { return et_x_TablePart; @@ -334,6 +340,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const { @@ -366,6 +373,7 @@ namespace OOX { } void readBin(const CPath& oPath); + XLS::BaseObjectPtr WriteBin() const; virtual void read(const CPath& oPath) { //don't use this. use read(const CPath& oRootPath, const CPath& oFilePath) @@ -374,10 +382,7 @@ namespace OOX } virtual void read(const CPath& oRootPath, const CPath& oPath); virtual void write(const CPath& oPath, const CPath& oDirectory, CContentTypes& oContent) const; - virtual const OOX::FileType type() const - { - return OOX::Spreadsheet::FileTypes::Table; - } + virtual const OOX::FileType type() const; virtual const CPath DefaultDirectory() const { return type().DefaultDirectory(); diff --git a/OOXML/XlsxFormat/Table/Tables.cpp b/OOXML/XlsxFormat/Table/Tables.cpp index 79b4b0764f3..4b4f996af4e 100644 --- a/OOXML/XlsxFormat/Table/Tables.cpp +++ b/OOXML/XlsxFormat/Table/Tables.cpp @@ -42,24 +42,30 @@ #include "../../XlsbFormat/Biff12_unions/LISTCOLS.h" #include "../../XlsbFormat/Biff12_unions/LISTCOL.h" #include "../../XlsbFormat/Biff12_records/BeginListCol.h" +#include "../../XlsbFormat/Biff12_records/BeginListCols.h" #include "../../XlsbFormat/Biff12_records/ListCCFmla.h" #include "../../XlsbFormat/Biff12_records/ListTrFmla.h" #include "../../XlsbFormat/Biff12_records/List14.h" +#include "../../XlsbFormat/Biff12_records/BeginDeletedName.h" +#include "../../XlsbFormat/Biff12_records/BeginDeletedNames.h" #include "../../XlsbFormat/QueryTableStream.h" #include "../../XlsbFormat/Biff12_unions/QSI.h" #include "../../XlsbFormat/Biff12_records/CommonRecords.h" #include "../../XlsbFormat/Biff12_unions/QSIR.h" #include "../../XlsbFormat/Biff12_unions/QSIFS.h" +#include "../../XlsbFormat/Biff12_records/BeginQSIFs.h" #include "../../XlsbFormat/Biff12_unions/QSIF.h" #include "../../XlsbFormat/Biff12_unions/DELETEDNAMES.h" #include "../../XlsbFormat/Biff12_unions/DELETEDNAME.h" -#include "../../XlsbFormat/Biff12_records/BeginDeletedName.h" +#include "../../XlsbFormat/Biff12_unions/FRTTABLE.h" #include "../../Common/SimpleTypes_Shared.h" #include "../../Common/SimpleTypes_Spreadsheet.h" #include "../../DocxFormat/Drawing/DrawingExt.h" +#include "../../Binary/XlsbFormat/FileTypes_SpreadsheetBin.h" + namespace OOX { namespace Spreadsheet @@ -82,6 +88,20 @@ namespace Spreadsheet { ReadAttributes(obj); } + XLS::BaseObjectPtr CAltTextTable::toBin() + { + auto ptr(new XLSB::List14); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oAltText.IsInit()) + ptr->stAltText = m_oAltText.get(); + else + ptr->stAltText.setSize(0xFFFFFFFF); + if(m_oAltTextSummary.IsInit()) + ptr->stAltTextSummary = m_oAltTextSummary.get(); + else + ptr->stAltTextSummary.setSize(0xFFFFFFFF); + return objectPtr; + } void CAltTextTable::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) { WritingElement_ReadAttributes_Start( oReader ) @@ -133,6 +153,32 @@ namespace Spreadsheet { ReadAttributes(obj); } + XLS::BaseObjectPtr CTableStyleInfo::toBin() + { + auto ptr(new XLSB::TableStyleClient); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oName.IsInit()) + ptr->stStyleName = m_oName.get(); + else + ptr->stStyleName.setSize(0xFFFFFFFF); + if(m_oShowColumnStripes.IsInit()) + ptr->fColumnStripes = m_oShowColumnStripes->GetValue(); + else + ptr->fColumnStripes = false; + if(m_oShowFirstColumn.IsInit()) + ptr->fFirstColumn = m_oShowFirstColumn->GetValue(); + else + ptr->fFirstColumn = false; + if(m_oShowLastColumn.IsInit()) + ptr->fLastColumn = m_oShowLastColumn->GetValue(); + else + ptr->fLastColumn = false; + if(m_oShowRowStripes.IsInit()) + ptr->fRowStripes = m_oShowRowStripes->GetValue(); + else + ptr->fRowStripes = false; + return objectPtr; + } void CTableStyleInfo::ReadAttributes(XLS::BaseObjectPtr& obj) { auto ptr = static_cast(obj.get()); @@ -169,11 +215,11 @@ namespace Spreadsheet //есть такой баг: при сохранениии "sum" и названия таблицы "Table1" (русский excel), выдается ошибка в формулах WritingStringNullableAttrString(L"totalsRowFunction", m_oTotalsRowFunction, m_oTotalsRowFunction->ToString()); WritingStringNullableAttrInt(L"queryTableFieldId", m_oQueryTableFieldId, m_oQueryTableFieldId->GetValue()); - WritingStringNullableAttrString(L"dataCellStyle", m_oDataCellStyle, *m_oDataCellStyle); + WritingStringNullableAttrString(L"dataCellStyle", m_oDataCellStyle, *m_oDataCellStyle); WritingStringNullableAttrInt(L"dataDxfId", m_oDataDxfId, m_oDataDxfId->GetValue()); - WritingStringNullableAttrString(L"headerRowCellStyle", m_oHeaderRowCellStyle, *m_oHeaderRowCellStyle); + WritingStringNullableAttrString(L"headerRowCellStyle", m_oHeaderRowCellStyle, *m_oHeaderRowCellStyle); WritingStringNullableAttrInt(L"headerRowDxfId", m_oHeaderRowDxfId, m_oHeaderRowDxfId->GetValue()); - WritingStringNullableAttrString(L"totalsRowCellStyle", m_oTotalsRowCellStyle, *m_oTotalsRowCellStyle); + WritingStringNullableAttrString(L"totalsRowCellStyle", m_oTotalsRowCellStyle, *m_oTotalsRowCellStyle); WritingStringNullableAttrInt(L"totalsRowDxfId", m_oTotalsRowDxfId, m_oTotalsRowDxfId->GetValue()); if(m_oTotalsRowFormula.IsInit() || m_oCalculatedColumnFormula.IsInit()) { @@ -238,6 +284,101 @@ namespace Spreadsheet m_oTotalsRowFormula = ptrListTrFmla->formula.getAssembledFormula(); } } + } + XLS::BaseObjectPtr CTableColumn::toBin() + { + auto ptr(new XLSB::LISTCOL); + XLS::BaseObjectPtr objectPtr(ptr); + + auto ptr1(new XLSB::BeginListCol); + ptr->m_BrtBeginListCol = XLS::BaseObjectPtr{ptr1}; + if(m_oDataCellStyle.IsInit()) + ptr1->stStyleInsertRow = m_oDataCellStyle.get(); + else + ptr1->stStyleInsertRow.setSize(0xFFFFFFFF); + if(m_oTotalsRowDxfId.IsInit()) + ptr1->nDxfInsertRow = m_oTotalsRowDxfId->GetValue(); + else + ptr1->nDxfInsertRow = 0xFFFFFFFF; + + if(m_oHeaderRowCellStyle.IsInit()) + ptr1->stStyleHeader = m_oHeaderRowCellStyle.get(); + else + ptr1->stStyleHeader.setSize(0xFFFFFFFF); + if(m_oHeaderRowDxfId.IsInit()) + ptr1->nDxfHdr = m_oHeaderRowDxfId->GetValue(); + else + ptr1->nDxfHdr = 0xFFFFFFFF; + if(m_oTotalsRowCellStyle.IsInit()) + ptr1->stStyleAgg = m_oTotalsRowCellStyle.get(); + else + ptr1->stStyleAgg.setSize(0xFFFFFFFF); + + if(m_oDataDxfId.IsInit()) + ptr1->nDxfAgg = m_oDataDxfId->GetValue(); + else + ptr1->nDxfAgg = 0xFFFFFFFF; + if(m_oId.IsInit()) + ptr1->idField = m_oId->GetValue(); + else + ptr1->idField = 0; + + if(m_oName.IsInit()) + ptr1->stCaption = m_oName.get(); + else + ptr1->stCaption.setSize(0xFFFFFFFF); + if(m_oQueryTableFieldId.IsInit()) + ptr1->idqsif = m_oQueryTableFieldId->GetValue(); + else + ptr1->idqsif = 0; + + if(m_oTotalsRowLabel.IsInit()) + ptr1->stTotal = m_oTotalsRowLabel.get(); + else + ptr1->stTotal.setSize(0xFFFFFFFF); + + if(m_oUniqueName.IsInit()) + ptr1->stName = m_oUniqueName.get(); + else + ptr1->stName.setSize(0xFFFFFFFF); + if (m_oTotalsRowFunction == SimpleTypes::Spreadsheet::ETotalsRowFunction::totalrowfunctionNone) + ptr1->ilta = XLSB::ListTotalRowFunction::ILTA_NONE; + else if (m_oTotalsRowFunction == SimpleTypes::Spreadsheet::ETotalsRowFunction::totalrowfunctionAverage) + ptr1->ilta = XLSB::ListTotalRowFunction::ILTA_AVERAGE; + else if (m_oTotalsRowFunction == SimpleTypes::Spreadsheet::ETotalsRowFunction::totalrowfunctionCount) + ptr1->ilta = XLSB::ListTotalRowFunction::ILTA_COUNT; + else if (m_oTotalsRowFunction == SimpleTypes::Spreadsheet::ETotalsRowFunction::totalrowfunctionCountNums) + ptr1->ilta = XLSB::ListTotalRowFunction::ILTA_COUNTNUMS; + else if (m_oTotalsRowFunction == SimpleTypes::Spreadsheet::ETotalsRowFunction::totalrowfunctionMax) + ptr1->ilta = XLSB::ListTotalRowFunction::ILTA_MAX; + else if (m_oTotalsRowFunction == SimpleTypes::Spreadsheet::ETotalsRowFunction::totalrowfunctionMin) + ptr1->ilta = XLSB::ListTotalRowFunction::ILTA_MIN; + else if (m_oTotalsRowFunction == SimpleTypes::Spreadsheet::ETotalsRowFunction::totalrowfunctionSum) + ptr1->ilta = XLSB::ListTotalRowFunction::ILTA_SUM; + else if (m_oTotalsRowFunction == SimpleTypes::Spreadsheet::ETotalsRowFunction::totalrowfunctionStdDev) + ptr1->ilta = XLSB::ListTotalRowFunction::ILTA_STDDEV; + else if (m_oTotalsRowFunction == SimpleTypes::Spreadsheet::ETotalsRowFunction::totalrowfunctionVar) + ptr1->ilta = XLSB::ListTotalRowFunction::ILTA_VAR; + else if (m_oTotalsRowFunction == SimpleTypes::Spreadsheet::ETotalsRowFunction::totalrowfunctionCustom) + ptr1->ilta = XLSB::ListTotalRowFunction::ILTA_CUSTOM; + else + ptr1->ilta = XLSB::ListTotalRowFunction::ILTA_NONE; + + if(m_oCalculatedColumnFormula.IsInit()) + { + auto fmla(new XLSB::ListCCFmla); + fmla->fArray = false; + fmla->formula = m_oCalculatedColumnFormula.get(); + ptr->m_BrtListCCFmla = XLS::BaseObjectPtr{fmla}; + } + if(m_oTotalsRowFormula.IsInit()) + { + auto fmla(new XLSB::ListTrFmla); + fmla->fArray = false; + fmla->formula = m_oTotalsRowFormula.get(); + ptr->m_BrtListTrFmla = XLS::BaseObjectPtr{fmla}; + } + return objectPtr; } void CTableColumn::ReadAttributes(XLS::BaseObjectPtr& obj) { @@ -326,7 +467,7 @@ namespace Spreadsheet writer.WriteString(L""); - + for ( size_t i = 0; i < m_arrItems.size(); ++i) { if ( m_arrItems[i] ) @@ -334,7 +475,7 @@ namespace Spreadsheet m_arrItems[i]->toXML(writer); } } - + writer.WriteString(L""); } void CTableColumns::fromXML(XmlUtils::CXmlLiteReader& oReader) @@ -368,6 +509,14 @@ namespace Spreadsheet m_arrItems.push_back(new CTableColumn(listcol)); } } + XLS::BaseObjectPtr CTableColumns::toBin() + { + auto ptr(new XLSB::LISTCOLS); + XLS::BaseObjectPtr objectPtr(ptr); + for(auto i:m_arrItems) + ptr->m_arLISTCOL.push_back(i->toBin()); + return objectPtr; + } void CTableColumns::ReadAttributes(std::vector& obj) { if(!obj.empty()) @@ -405,17 +554,17 @@ xmlns:xr3=\"http://schemas.microsoft.com/office/spreadsheetml/2016/revision3\"") WritingStringNullableAttrString(L"totalsRowCellStyle", m_oTotalsRowCellStyle, *m_oTotalsRowCellStyle); WritingStringNullableAttrInt(L"totalsRowDxfId", m_oTotalsRowDxfId, m_oTotalsRowDxfId->GetValue()); WritingStringNullableAttrInt(L"totalsRowBorderDxfId", m_oTotalsRowBorderDxfId, m_oTotalsRowBorderDxfId->GetValue()); - + //if (m_oHeaderRowCount.IsInit() && 0 == m_oHeaderRowCount->GetValue()) // WritingStringAttrString(L"headerRowCount", L"1"); //if (m_oTotalsRowCount.IsInit() && m_oTotalsRowCount->GetValue() > 0) // WritingStringAttrString(L"totalsRowCount", L"1"); // else - // WritingStringAttrString(L"totalsRowShown", L"0");//m_oTotalsRowShown + // WritingStringAttrString(L"totalsRowShown", L"0");//m_oTotalsRowShown WritingStringNullableAttrInt(L"headerRowCount", m_oHeaderRowCount, m_oHeaderRowCount->GetValue()); WritingStringNullableAttrInt(L"totalsRowCount", m_oTotalsRowCount, m_oTotalsRowCount->GetValue()); WritingStringNullableAttrBool2(L"totalsRowShown", m_oTotalsRowShown); - + WritingStringNullableAttrBool2(L"insertRow", m_oInsertRow); WritingStringNullableAttrBool2(L"insertRowShift", m_oInsertRowShift); WritingStringNullableAttrBool2(L"published", m_oPublished); @@ -439,7 +588,7 @@ xmlns:xr3=\"http://schemas.microsoft.com/office/spreadsheetml/2016/revision3\"") void CTable::toXML2(NSStringUtils::CStringBuilder& writer, int nIndex) { if(false == m_oRef.IsInit() || false == m_oDisplayName.IsInit()) return; - + if(!m_oId.IsInit()) { m_oId.Init(); @@ -471,6 +620,32 @@ xmlns:xr3=\"http://schemas.microsoft.com/office/spreadsheetml/2016/revision3\"") else if ((L"extLst") == sName) m_oExtLst = oReader; } + if(!m_oName.IsInit() && m_oDisplayName.IsInit()) + m_oName = m_oDisplayName.get(); + + if(m_oTableColumns.IsInit() && !m_oTableColumns->m_arrItems.empty()) + { + XLS::GlobalWorkbookInfo::mapTableColumnNames_static.emplace(m_oId->GetValue(), + std::vector(m_oTableColumns->m_arrItems.size())); + auto colInd = 0; + for(auto i:m_oTableColumns->m_arrItems) + { + if(i->m_oName.IsInit()) + { + i->m_oName = boost::algorithm::replace_all_copy(i->m_oName.get(), L"_x000a_", L"\n"); + std::unordered_map>::iterator pFind = XLS::GlobalWorkbookInfo::mapTableColumnNames_static.find(m_oId->GetValue()); + if (pFind != XLS::GlobalWorkbookInfo::mapTableColumnNames_static.end()) + { + if (colInd < pFind->second.size()) + { + pFind->second[colInd] = i->m_oName.get(); + } + } + } + colInd++; + } + } + XLS::GlobalWorkbookInfo::mapTableNames_static.emplace(m_oId->GetValue(), m_oName.get()); } void CTable::fromBin(XLS::BaseObjectPtr& obj) { @@ -496,6 +671,141 @@ xmlns:xr3=\"http://schemas.microsoft.com/office/spreadsheetml/2016/revision3\"") m_oExtLst = ptr->m_FRTTABLE; } } + XLS::BaseObjectPtr CTable::toBin() + { + auto ptr(new XLSB::TABLE); + auto ptr1(new XLSB::BeginList); + ptr->m_BrtBeginList = XLS::BaseObjectPtr{ptr1}; + XLS::BaseObjectPtr objectPtr(ptr); + + if(m_oRef.IsInit()) + { + ptr1->rfxList = m_oRef->GetValue(); + } + if(m_oName.IsInit()) + ptr1->stName = m_oName.get(); + else if(m_oDisplayName.IsInit()) + ptr1->stName = m_oDisplayName.get(); + else + ptr1->stName.setSize(0xFFFFFFFF); + if(m_oTotalsRowCount.IsInit()) + ptr1->crwTotals = m_oTotalsRowCount->GetValue(); + else + ptr1->crwTotals = false; + + if(m_oHeaderRowCount.IsInit()) + ptr1->crwHeader = m_oHeaderRowCount->GetValue(); + else + ptr1->crwHeader = true; + + if(m_oDisplayName.IsInit()) + ptr1->stDisplayName = m_oDisplayName.get(); + else + ptr1->stDisplayName.setSize(0xFFFFFFFF); + + if(m_oTableBorderDxfId.IsInit()) + ptr1->nDxfBorder = m_oTableBorderDxfId->GetValue(); + else + ptr1->nDxfBorder = 0xFFFFFFFF; + + if(m_oComment.IsInit()) + ptr1->stComment = m_oComment.get(); + else + ptr1->stComment.setSize(0xFFFFFFFF); + + if(m_oConnectionId.IsInit()) + ptr1->dwConnID = m_oConnectionId->GetValue(); + else + ptr1->dwConnID = 0; + + if(m_oDataDxfId.IsInit()) + ptr1->nDxfData = m_oDataDxfId->GetValue(); + else + ptr1->nDxfData = 0xFFFFFFFF; + + if(m_oDataCellStyle.IsInit()) + ptr1->stStyleData = m_oDataCellStyle.get(); + else + ptr1->stStyleData.setSize(0xFFFFFFFF); + + if(m_oHeaderRowBorderDxfId.IsInit()) + ptr1->nDxfHeaderBorder = m_oHeaderRowBorderDxfId->GetValue(); + else + ptr1->nDxfHeaderBorder = 0xFFFFFFFF; + + if(m_oHeaderRowCellStyle.IsInit()) + ptr1->stStyleHeader = m_oHeaderRowCellStyle.get(); + else + ptr1->stStyleHeader.setSize(0xFFFFFFFF); + + if(m_oHeaderRowDxfId.IsInit()) + ptr1->nDxfHeader = m_oHeaderRowDxfId->GetValue(); + else + ptr1->nDxfHeader = 0xFFFFFFFF; + if(m_oInsertRow.IsInit()) + ptr1->fForceInsertToBeVisible = m_oInsertRow.get(); + else + ptr1->fForceInsertToBeVisible = false; + if(m_oInsertRowShift.IsInit()) + ptr1->fInsertRowInsCells = m_oInsertRowShift.get(); + else + ptr1->fInsertRowInsCells = false; + if(m_oPublished.IsInit()) + ptr1->fPublished = m_oPublished.get(); + else + ptr1->fPublished = false; + if(m_oId.IsInit()) + ptr1->idList = m_oId->GetValue(); + else + ptr1->idList = 0; + + if(m_oTableType.IsInit()) + { + if(m_oTableType == SimpleTypes::Spreadsheet::ETableType::typeWorksheet) + ptr1->lt = XLSB::ListType::LTRANGE; + if(m_oTableType == SimpleTypes::Spreadsheet::ETableType::typeXml) + ptr1->lt = XLSB::ListType::LTXML; + if(m_oTableType == SimpleTypes::Spreadsheet::ETableType::typeQueryTable) + ptr1->lt = XLSB::ListType::LTEXTDATA; + } + else + { + ptr1->lt = XLSB::ListType::LTRANGE; + } + + if(m_oTotalsRowBorderDxfId.IsInit()) + ptr1->nDxfAggBorder = m_oTotalsRowBorderDxfId->GetValue(); + else + ptr1->nDxfAggBorder = 0xFFFFFFFF; + if(m_oTotalsRowCellStyle.IsInit()) + ptr1->stStyleAgg = m_oTotalsRowCellStyle.get(); + else + ptr1->stStyleAgg.setSize(0xFFFFFFFF); + + if(m_oTotalsRowDxfId.IsInit()) + ptr1->nDxfAgg = m_oTotalsRowDxfId->GetValue(); + else + ptr1->nDxfAgg = 0xFFFFFFFF; + + if(m_oTotalsRowShown.IsInit()) + ptr1->fShownTotalRow = m_oTotalsRowShown.get(); + else if(m_oTotalsRowCount.IsInit() && m_oTotalsRowCount->GetValue() > 0) + ptr1->fShownTotalRow = true; + else + ptr1->fShownTotalRow = false; + ptr1->fSingleCell = false; + if(m_oAutoFilter.IsInit()) + ptr->m_AUTOFILTER = m_oAutoFilter->toBin(); + if(m_oSortState.IsInit()) + ptr->m_SORTSTATE = m_oSortState->toBin(); + if(m_oTableColumns.IsInit()) + ptr->m_LISTCOLS = m_oTableColumns->toBin(); + if(m_oTableStyleInfo.IsInit()) + ptr->m_BrtTableStyleClient = m_oTableStyleInfo->toBin(); + if(m_oExtLst.IsInit()) + ptr->m_FRTTABLE = m_oExtLst->toBinTable(); + return objectPtr; + } void CTable::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) { WritingElement_ReadAttributes_Start( oReader ) @@ -508,7 +818,7 @@ xmlns:xr3=\"http://schemas.microsoft.com/office/spreadsheetml/2016/revision3\"") WritingElement_ReadAttributes_Read_else_if ( oReader, L"comment", m_oComment ) WritingElement_ReadAttributes_Read_else_if ( oReader, L"connectionId", m_oConnectionId ) WritingElement_ReadAttributes_Read_else_if ( oReader, L"dataDxfId", m_oDataDxfId ) - WritingElement_ReadAttributes_Read_else_if ( oReader, L"dataCellStyle", m_oDataCellStyle ) + WritingElement_ReadAttributes_Read_else_if ( oReader, L"dataCellStyle", m_oDataCellStyle ) WritingElement_ReadAttributes_Read_else_if ( oReader, L"headerRowBorderDxfId", m_oHeaderRowBorderDxfId ) WritingElement_ReadAttributes_Read_else_if ( oReader, L"headerRowCellStyle", m_oHeaderRowCellStyle ) WritingElement_ReadAttributes_Read_else_if ( oReader, L"headerRowDxfId", m_oHeaderRowDxfId ) @@ -528,7 +838,7 @@ xmlns:xr3=\"http://schemas.microsoft.com/office/spreadsheetml/2016/revision3\"") auto ptr = static_cast(obj.get()); if(ptr != nullptr) { - m_oRef = ptr->rfxList.toString(); + m_oRef = ptr->rfxList.toString(true, true); if(!ptr->stName.value().empty()) m_oName = ptr->stName.value(); @@ -624,6 +934,14 @@ xmlns:xr3=\"http://schemas.microsoft.com/office/spreadsheetml/2016/revision3\"") { ReadAttributes(obj); } + XLS::BaseObjectPtr CTablePart::toBin() + { + auto ptr(new XLSB::ListPart); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oRId.IsInit()) + ptr->stRelID.value = m_oRId->GetValue(); + return objectPtr; + } void CTablePart::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) { WritingElement_ReadAttributes_Start_No_NS( oReader ) @@ -644,7 +962,7 @@ xmlns:xr3=\"http://schemas.microsoft.com/office/spreadsheetml/2016/revision3\"") writer.WriteString(L""); - + for ( size_t i = 0; i < m_arrItems.size(); ++i) { if ( m_arrItems[i] ) @@ -652,8 +970,8 @@ xmlns:xr3=\"http://schemas.microsoft.com/office/spreadsheetml/2016/revision3\"") m_arrItems[i]->toXML(writer); } } - - writer.WriteString(L""); + + writer.WriteString(L""); } void CTableParts::fromXML(XmlUtils::CXmlLiteReader& oReader) { @@ -689,6 +1007,23 @@ xmlns:xr3=\"http://schemas.microsoft.com/office/spreadsheetml/2016/revision3\"") } } } + XLS::BaseObjectPtr CTableParts::toBin() + { + auto ptr(new XLSB::LISTPARTS); + XLS::BaseObjectPtr objectPtr(ptr); + + if(m_oCount.IsInit()) + { + auto beginlistParts(new XLSB::BeginListParts); + ptr->m_BrtBeginListParts = XLS::BaseObjectPtr{beginlistParts}; + beginlistParts->cParts = m_oCount->m_eValue; + } + for(auto i:m_arrItems) + { + ptr->m_arBrtListPart.push_back(i->toBin()); + } + return objectPtr; + } void CTableParts::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) { WritingElement_ReadAttributes_Start( oReader ) @@ -721,6 +1056,15 @@ xmlns:xr3=\"http://schemas.microsoft.com/office/spreadsheetml/2016/revision3\"") } } + XLS::BaseObjectPtr CTableFile::WriteBin() const + { + XLSB::TableStreamPtr tableStream(new XLSB::TableStream); + XLS::BaseObjectPtr objectPtr(tableStream); + + tableStream->m_TABLE = m_oTable->toBin(); + + return objectPtr; + } void CTableFile::read(const CPath& oRootPath, const CPath& oPath) { m_oReadPath = oPath; @@ -746,18 +1090,35 @@ xmlns:xr3=\"http://schemas.microsoft.com/office/spreadsheetml/2016/revision3\"") { if(false == m_oTable.IsInit()) return; - NSStringUtils::CStringBuilder sXml; - int nGlobalNumber = OOX::FileGlobalEnumerated::GetGlobalNumber(); - - sXml.WriteString(L""); - m_oTable->toXML2(sXml, nGlobalNumber); + CXlsb* xlsb = dynamic_cast(File::m_pMainDocument); + if ((xlsb) && (xlsb->m_bWriteToXlsb)) + { + XLS::BaseObjectPtr object = WriteBin(); + xlsb->WriteBin(oPath, object.get()); + } + else + { + NSStringUtils::CStringBuilder sXml; + int nGlobalNumber = OOX::FileGlobalEnumerated::GetGlobalNumber(); - std::wstring sPath = oPath.GetPath(); - NSFile::CFileBinary::SaveToFile(sPath, sXml.GetData()); + sXml.WriteString(L""); + m_oTable->toXML2(sXml, nGlobalNumber); + std::wstring sPath = oPath.GetPath(); + NSFile::CFileBinary::SaveToFile(sPath, sXml.GetData()); + } oContent.Registration( type().OverrideType(), oDirectory, oPath.GetFilename() ); IFileContainer::Write( oPath, oDirectory, oContent ); } + const OOX::FileType CTableFile::type() const + { + CXlsb* xlsb = dynamic_cast(File::m_pMainDocument); + if ((xlsb) && (xlsb->m_bWriteToXlsb)) + { + return OOX::SpreadsheetBin::FileTypes::TableBin; + } + return OOX::Spreadsheet::FileTypes::Table; + } //--------------------------------------------------------------------------------------------------------------------- @@ -790,6 +1151,39 @@ xmlns:xr3=\"http://schemas.microsoft.com/office/spreadsheetml/2016/revision3\"") m_oExtLst = oReader; } } + XLS::BaseObjectPtr CQueryTableField::toBin() + { + auto ptr1(new XLSB::QSIF); + auto ptr(new XLSB::BeginQSIF); + ptr1->m_BrtBeginQSIF = XLS::BaseObjectPtr{ptr}; + + if(m_oId.IsInit()) + ptr->idField = m_oId->GetValue(); + else + ptr->idField = 0; + if(m_oTableColumnId.IsInit()) + ptr->idList = m_oTableColumnId->GetValue(); + else + ptr->idList = 0; + if(m_oName.IsInit()) + ptr->name = m_oName.get(); + if(m_oRowNumbers.IsInit()) + ptr->fRowNums = m_oRowNumbers.get(); + if(m_oFillFormulas.IsInit()) + ptr->fFillDown = m_oFillFormulas.get(); + else + ptr->fFillDown = false; + if(m_oDataBound.IsInit()) + ptr->fUserIns = m_oDataBound.get(); + else + ptr->fUserIns = false; + if(m_oClipped.IsInit()) + ptr->fClipped = m_oClipped.get(); + else + ptr->fClipped = false; + + return XLS::BaseObjectPtr{ptr1}; + } void CQueryTableField::fromBin(XLS::BaseObjectPtr& obj) { auto ptr = static_cast(obj.get()); @@ -837,7 +1231,7 @@ xmlns:xr3=\"http://schemas.microsoft.com/office/spreadsheetml/2016/revision3\"") writer.WriteString(L""); - + for ( size_t i = 0; i < m_arrItems.size(); ++i) { if ( m_arrItems[i] ) @@ -845,7 +1239,7 @@ xmlns:xr3=\"http://schemas.microsoft.com/office/spreadsheetml/2016/revision3\"") m_arrItems[i]->toXML(writer); } } - + writer.WriteString(L""); } void CQueryTableFields::fromXML(XmlUtils::CXmlLiteReader& oReader) @@ -868,6 +1262,16 @@ xmlns:xr3=\"http://schemas.microsoft.com/office/spreadsheetml/2016/revision3\"") } } } + XLS::BaseObjectPtr CQueryTableFields::toBin() + { + auto ptr(new XLSB::QSIFS); + auto ptr1(new XLSB::BeginQSIFs); + ptr->m_BrtBeginQSIFs = XLS::BaseObjectPtr{ptr1}; + for(auto i:m_arrItems) + ptr->m_arQSIF.push_back(i->toBin()); + ptr1->nCols = m_arrItems.size(); + return XLS::BaseObjectPtr{ptr}; + } void CQueryTableFields::fromBin(XLS::BaseObjectPtr& obj) { auto ptr = static_cast(obj.get()); @@ -899,6 +1303,16 @@ xmlns:xr3=\"http://schemas.microsoft.com/office/spreadsheetml/2016/revision3\"") if ( !oReader.IsEmptyNode() ) oReader.ReadTillEnd(); } + XLS::BaseObjectPtr CQueryTableDeletedField::toBin() + { + auto ptr1(new XLSB::DELETEDNAME); + auto ptr(new XLSB::BeginDeletedName); + ptr1->m_BrtBeginDeletedName = XLS::BaseObjectPtr{ptr}; + if(m_oName.IsInit()) + ptr->rgb = m_oName.get(); + + return XLS::BaseObjectPtr{ptr1}; + } void CQueryTableDeletedField::fromBin(XLS::BaseObjectPtr& obj) { auto ptr = static_cast(obj.get()); @@ -931,7 +1345,7 @@ xmlns:xr3=\"http://schemas.microsoft.com/office/spreadsheetml/2016/revision3\"") writer.WriteString(L""); - + for ( size_t i = 0; i < m_arrItems.size(); ++i) { if ( m_arrItems[i] ) @@ -961,6 +1375,18 @@ xmlns:xr3=\"http://schemas.microsoft.com/office/spreadsheetml/2016/revision3\"") } } } + XLS::BaseObjectPtr CQueryTableDeletedFields::toBin() + { + auto ptr(new XLSB::DELETEDNAMES); + auto ptr1(new XLSB::BeginDeletedNames); + ptr->m_BrtBeginDeletedNames = XLS::BaseObjectPtr{ptr1}; + + for(auto i:m_arrItems) + ptr->m_arDELETEDNAME.push_back(i->toBin()); + + ptr1->nCols = ptr->m_arDELETEDNAME.size(); + return XLS::BaseObjectPtr{ptr}; + } void CQueryTableDeletedFields::fromBin(XLS::BaseObjectPtr& obj) { auto ptr = static_cast(obj.get()); @@ -1026,6 +1452,50 @@ xmlns:xr3=\"http://schemas.microsoft.com/office/spreadsheetml/2016/revision3\"") m_oExtLst = oReader; } } + XLS::BaseObjectPtr CQueryTableRefresh::toBin() + { + auto ptr1(new XLSB::QSIR); + auto ptr(new XLSB::BeginQSIR); + ptr1->m_BrtBeginQSIR = XLS::BaseObjectPtr{ptr}; + + if(m_oNextId.IsInit()) + ptr->idFieldNext = m_oNextId->GetValue(); + else + ptr->idFieldNext = 0; + if(m_oMinimumVersion.IsInit()) + ptr->wVerBeforeRefreshAlert = m_oMinimumVersion->GetValue(); + else + ptr->wVerBeforeRefreshAlert = 0; + if(m_FieldIdWrapped.IsInit()) + ptr->fidWrapped = m_FieldIdWrapped.get(); + else + ptr->fidWrapped = false; + if(m_HeadersInLastRefresh.IsInit()) + ptr->fTitlesOld = m_HeadersInLastRefresh.get(); + else + ptr->fTitlesOld = false;; + if(m_PreserveSortFilterLayout.IsInit()) + ptr->fPersist = m_PreserveSortFilterLayout.get(); + else + ptr->fPersist = false; + if(m_UnboundColumnsLeft.IsInit()) + ptr->ccolExtraLeft = m_UnboundColumnsLeft->GetValue(); + else + ptr->ccolExtraLeft = 0; + if(m_UnboundColumnsRight.IsInit()) + ptr->ccolExtraRight = m_UnboundColumnsRight->GetValue(); + else + ptr->ccolExtraRight = 0; + + if(m_oQueryTableFields.IsInit()) + ptr1->m_QSIFS = m_oQueryTableFields->toBin(); + if(m_oQueryTableDeletedFields.IsInit()) + ptr1->m_DELETEDNAMES = m_oQueryTableDeletedFields->toBin(); + if(m_oSortState.IsInit()) + ptr1->m_SORTSTATE = m_oSortState->toBin(); + + return XLS::BaseObjectPtr{ptr1}; + } void CQueryTableRefresh::fromBin(XLS::BaseObjectPtr& obj) { auto ptr = static_cast(obj.get()); @@ -1071,7 +1541,7 @@ xmlns:xr3=\"http://schemas.microsoft.com/office/spreadsheetml/2016/revision3\"") WritingElement_ReadAttributes_Read_else_if ( oReader, (L"unboundColumnsRight"), m_UnboundColumnsRight ) WritingElement_ReadAttributes_End( oReader ) } - + void CQueryTable::toXML(NSStringUtils::CStringBuilder& writer) const { if(false == m_oName.IsInit()) return; @@ -1107,7 +1577,7 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" WritingStringNullableAttrBool2(L"refreshOnLoad", m_oRefreshOnLoad); WritingStringNullableAttrBool2(L"removeDataOnSave", m_oRemoveDataOnSave); WritingStringNullableAttrBool2(L"rowNumbers", m_oRowNumbers); - + writer.WriteString(L">"); if(m_oQueryTableRefresh.IsInit()) @@ -1136,6 +1606,105 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" m_oExtLst = oReader; } } + XLS::BaseObjectPtr CQueryTable::toBin() + { + auto ptr1(new XLSB::QSI); + auto ptr(new XLSB::BeginQSI); + ptr1->m_BrtBeginQSI = XLS::BaseObjectPtr{ptr}; + + if(m_oAdjustColumnWidth.IsInit()) + ptr->fAutoFit = m_oAdjustColumnWidth.get(); + else + ptr->fAutoFit = true; + if(m_oApplyAlignmentFormats.IsInit()) + ptr->fibitAtrAlc = m_oApplyAlignmentFormats.get(); + else + ptr->fibitAtrAlc = false; + if(m_oApplyBorderFormats.IsInit()) + ptr->fibitAtrBdr = m_oApplyBorderFormats.get(); + else + ptr->fibitAtrBdr = false; + if(m_oApplyFontFormats.IsInit()) + ptr->fibitAtrFnt = m_oApplyFontFormats.get(); + else + ptr->fibitAtrFnt = false; + if(m_oApplyNumberFormats.IsInit()) + ptr->fibitAtrNum = m_oApplyNumberFormats.get(); + else + ptr->fibitAtrNum = false; + if(m_oApplyPatternFormats.IsInit()) + ptr->fibitAtrPat = m_oApplyPatternFormats.get(); + else + ptr->fibitAtrPat = false; + if(m_oApplyWidthHeightFormats.IsInit()) + ptr->fibitAtrProt = m_oApplyWidthHeightFormats.get(); + else + ptr->fibitAtrProt = false; + if(m_oBackgroundRefresh.IsInit()) + ptr->fAsync = m_oBackgroundRefresh.get(); + else + ptr->fAsync = true; + + if(m_oAutoFormatId.IsInit()) + ptr->itblAutoFmt = m_oAutoFormatId->GetValue(); + else + ptr->itblAutoFmt = 0; + if(m_oConnectionId.IsInit()) + ptr->dwConnID = m_oConnectionId->GetValue(); + else + ptr->dwConnID = 0; + if(m_oDisableEdit.IsInit()) + ptr->fDisableEdit = m_oDisableEdit.get(); + else + ptr->fDisableEdit = false; + if(m_oDisableRefresh.IsInit()) + ptr->fDisableRefresh = m_oDisableRefresh.get(); + else + ptr->fDisableRefresh = false; + if(m_oFillFormulas.IsInit()) + ptr->fFill = m_oFillFormulas.get(); + else + ptr->fFill = false; + if(m_oFirstBackgroundRefresh.IsInit()) + ptr->fNewAsync = m_oFirstBackgroundRefresh.get(); + else + ptr->fNewAsync = true; + ptr->fOverwrite = false; + ptr->fShrink = false; + + if(m_oGrowShrinkType == L"overwriteClear" ) + ptr->fOverwrite = true; + else if(m_oGrowShrinkType == L"insertDelete") + ptr->fShrink = true; + if(m_oHeaders.IsInit()) + ptr->fTitles = m_oHeaders.get(); + if(m_oIntermediate.IsInit()) + ptr->fDummyList = m_oIntermediate.get(); + else + ptr->fDummyList = 0; + + if(m_oName.IsInit()) + ptr->name = m_oName.get(); + if(m_oPreserveFormatting.IsInit()) + ptr->fPreserveFmt = m_oPreserveFormatting.get(); + if(m_oRefreshOnLoad.IsInit()) + ptr->fAutoRefresh = m_oRefreshOnLoad.get(); + else + ptr->fAutoRefresh = false; + if(m_oRemoveDataOnSave.IsInit()) + ptr->fSaveData = !m_oRemoveDataOnSave.get(); + else + ptr->fSaveData = true; + if(m_oRowNumbers.IsInit()) + ptr->fRowNums = m_oRowNumbers.get(); + else + ptr->fRowNums = false; + + if(m_oQueryTableRefresh.IsInit()) + ptr1->m_QSIR = m_oQueryTableRefresh->toBin(); + + return XLS::BaseObjectPtr{ptr1}; + } void CQueryTable::fromBin(XLS::BaseObjectPtr& obj) { auto ptr = static_cast(obj.get()); @@ -1203,10 +1772,10 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" WritingElement_ReadAttributes_Read_else_if ( oReader, L"applyFontFormats", m_oApplyFontFormats ) WritingElement_ReadAttributes_Read_else_if ( oReader, L"applyNumberFormats", m_oApplyNumberFormats ) WritingElement_ReadAttributes_Read_else_if ( oReader, L"applyPatternFormats", m_oApplyPatternFormats ) - WritingElement_ReadAttributes_Read_else_if ( oReader, L"applyWidthHeightFormats", m_oApplyWidthHeightFormats ) + WritingElement_ReadAttributes_Read_else_if ( oReader, L"applyWidthHeightFormats", m_oApplyWidthHeightFormats ) WritingElement_ReadAttributes_Read_else_if ( oReader, L"autoFormatId", m_oAutoFormatId ) WritingElement_ReadAttributes_Read_else_if ( oReader, L"backgroundRefresh", m_oBackgroundRefresh ) - WritingElement_ReadAttributes_Read_else_if ( oReader, L"connectionId", m_oConnectionId ) + WritingElement_ReadAttributes_Read_else_if ( oReader, L"connectionId", m_oConnectionId ) WritingElement_ReadAttributes_Read_else_if ( oReader, L"disableEdit", m_oDisableEdit ) WritingElement_ReadAttributes_Read_else_if ( oReader, L"disableRefresh", m_oDisableRefresh ) WritingElement_ReadAttributes_Read_else_if ( oReader, L"fillFormulas", m_oFillFormulas ) @@ -1241,6 +1810,13 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" } } + XLS::BaseObjectPtr CQueryTableFile::WriteBin() const + { + XLSB::QueryTableStreamPtr querytableStream(new XLSB::QueryTableStream); + if(m_oQueryTable.IsInit()) + querytableStream->m_QSI = m_oQueryTable->toBin(); + return XLS::BaseObjectPtr{querytableStream}; + } void CQueryTableFile::read(const CPath& oRootPath, const CPath& oPath) { m_oReadPath = oPath; @@ -1266,17 +1842,34 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" { if(false == m_oQueryTable.IsInit()) return; - NSStringUtils::CStringBuilder sXml; - - sXml.WriteString(L""); - m_oQueryTable->toXML(sXml); + CXlsb* xlsb = dynamic_cast(File::m_pMainDocument); + if ((xlsb) && (xlsb->m_bWriteToXlsb)) + { + XLS::BaseObjectPtr object = WriteBin(); + xlsb->WriteBin(oPath, object.get()); + } + else + { + NSStringUtils::CStringBuilder sXml; - std::wstring sPath = oPath.GetPath(); - NSFile::CFileBinary::SaveToFile(sPath, sXml.GetData()); + sXml.WriteString(L""); + m_oQueryTable->toXML(sXml); + std::wstring sPath = oPath.GetPath(); + NSFile::CFileBinary::SaveToFile(sPath, sXml.GetData()); + } oContent.Registration( type().OverrideType(), oDirectory, oPath.GetFilename() ); IFileContainer::Write( oPath, oDirectory, oContent ); } + const OOX::FileType CQueryTableFile::type() const + { + CXlsb* xlsb = dynamic_cast(File::m_pMainDocument); + if ((xlsb) && (xlsb->m_bWriteToXlsb)) + { + return OOX::SpreadsheetBin::FileTypes::QueryTableBin; + } + return OOX::Spreadsheet::FileTypes::QueryTable; + } } //Spreadsheet } // namespace OOX diff --git a/OOXML/XlsxFormat/Timelines/Timeline.cpp b/OOXML/XlsxFormat/Timelines/Timeline.cpp new file mode 100644 index 00000000000..cf5b6085d1a --- /dev/null +++ b/OOXML/XlsxFormat/Timelines/Timeline.cpp @@ -0,0 +1,998 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#include "Timeline.h" + +#include "../FileTypes_Spreadsheet.h" + +#include "../../Common/SimpleTypes_Shared.h" +#include "../../Common/SimpleTypes_Spreadsheet.h" + +#include "../../DocxFormat/Drawing/DrawingExt.h" +#include "../../../DesktopEditor/common/File.h" + +#include "../../Binary/Presentation/XmlWriter.h" +#include "../../Binary/Presentation/BinaryFileReaderWriter.h" + +namespace OOX +{ + namespace Spreadsheet + { + CTimelineCachePivotTable::CTimelineCachePivotTable() {} + CTimelineCachePivotTable::~CTimelineCachePivotTable() {} + void CTimelineCachePivotTable::fromXML(XmlUtils::CXmlNode& node) + { + } + std::wstring CTimelineCachePivotTable::toXML() const + { + return L""; + } + EElementType CTimelineCachePivotTable::getType() const + { + return et_x_TimelineCachePivotTable; + } + void CTimelineCachePivotTable::toXML(NSStringUtils::CStringBuilder& writer) const + { + writer.WriteString(L""); + } + void CTimelineCachePivotTable::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + + if (oReader.IsEmptyNode()) + return; + } + void CTimelineCachePivotTable::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_Start(oReader) + WritingElement_ReadAttributes_Read_if(oReader, L"name", m_oName) + WritingElement_ReadAttributes_Read_else_if(oReader, L"tabId", m_oTabId) + WritingElement_ReadAttributes_End(oReader) + } +//------------------------------------------------------------------------------------- + CTimelineRange::CTimelineRange() {} + CTimelineRange::~CTimelineRange() {} + void CTimelineRange::fromXML(XmlUtils::CXmlNode& node) + { + } + std::wstring CTimelineRange::toXML() const + { + return L""; + } + EElementType CTimelineRange::getType() const + { + return et_x_TimelineRange; + } + void CTimelineRange::toXML(NSStringUtils::CStringBuilder& writer) const + { + writer.WriteString(L"<" + m_name); + WritingStringNullableAttrEncodeXmlString2(L"startDate", m_oStartDate); + WritingStringNullableAttrEncodeXmlString2(L"endDate", m_oEndDate); + writer.WriteString(L"/>"); + } + void CTimelineRange::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + m_name = oReader.GetName(); + + ReadAttributes(oReader); + + if (oReader.IsEmptyNode()) + return; + } + void CTimelineRange::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_Start(oReader) + WritingElement_ReadAttributes_Read_if(oReader, L"startDate", m_oStartDate) + WritingElement_ReadAttributes_Read_else_if(oReader, L"endDate", m_oEndDate) + WritingElement_ReadAttributes_End(oReader) + } +//------------------------------------------------------------------------------------- + CTimelineCachePivotTables::CTimelineCachePivotTables() {} + CTimelineCachePivotTables::~CTimelineCachePivotTables() {} + void CTimelineCachePivotTables::fromXML(XmlUtils::CXmlNode& node) + { + } + std::wstring CTimelineCachePivotTables::toXML() const + { + return L""; + } + EElementType CTimelineCachePivotTables::getType() const + { + return et_x_TimelineCachePivotTables; + } + void CTimelineCachePivotTables::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + if (oReader.IsEmptyNode()) + return; + + int nCurDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nCurDepth)) + { + std::wstring sName = XmlUtils::GetNameNoNS(oReader.GetName()); + + if (L"pivotTable" == sName) + { + CTimelineCachePivotTable* pPivotTable = new CTimelineCachePivotTable(); + *pPivotTable = oReader; + m_arrItems.push_back(pPivotTable); + } + } + } + void CTimelineCachePivotTables::toXML(NSStringUtils::CStringBuilder& writer) const + { + if (m_arrItems.empty()) return; + + writer.WriteString(L""); + + for (size_t i = 0; i < m_arrItems.size(); ++i) + { + if (m_arrItems[i]) + { + m_arrItems[i]->toXML(writer); + } + } + writer.WriteString(L""); + } +//-------------------------------------------------------------------------------------------------------------------------- + CTimeline::CTimeline() {} + CTimeline::~CTimeline() {} + void CTimeline::fromXML(XmlUtils::CXmlNode& node) + { + } + std::wstring CTimeline::toXML() const + { + return L""; + } + EElementType CTimeline::getType () const + { + return et_x_Timeline; + } + void CTimeline::toXML(NSStringUtils::CStringBuilder& writer) const + { + writer.WriteString(L"ToString()); + writer.WriteString(L"/>"); + } + void CTimeline::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + + if (oReader.IsEmptyNode()) + return; + + int nCurDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nCurDepth)) + { + std::wstring sName = XmlUtils::GetNameNoNS(oReader.GetName()); + + if (L"extLst" == sName) + m_oExtLst = oReader; + } + } + void CTimeline::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_Start( oReader ) + WritingElement_ReadAttributes_Read_if(oReader, L"name", m_oName) + WritingElement_ReadAttributes_Read_else_if(oReader, L"caption", m_oCaption) + WritingElement_ReadAttributes_Read_else_if(oReader, L"xr10:uid", m_oUid) + WritingElement_ReadAttributes_Read_else_if(oReader, L"cache", m_oCache) + WritingElement_ReadAttributes_Read_else_if(oReader, L"showHeader", m_oShowHeader) + WritingElement_ReadAttributes_Read_else_if(oReader, L"showTimeLevel", m_oShowTimeLevel) + WritingElement_ReadAttributes_Read_else_if(oReader, L"showSelectionLabel", m_oShowSelectionLabel) + WritingElement_ReadAttributes_Read_else_if(oReader, L"showHorizontalScrollbar", m_oShowHorizontalScrollbar) + WritingElement_ReadAttributes_Read_else_if(oReader, L"level", m_oLevel) + WritingElement_ReadAttributes_Read_else_if(oReader, L"selectionLevel", m_oSelectionLevel) + WritingElement_ReadAttributes_Read_else_if(oReader, L"scrollPosition", m_oScrollPosition) + WritingElement_ReadAttributes_Read_else_if(oReader, L"style", m_oStyle) + WritingElement_ReadAttributes_End( oReader ) + } +//------------------------------------------------------------------------------------- + CTimelines::CTimelines() {} + CTimelines::~CTimelines() {} + void CTimelines::fromXML(XmlUtils::CXmlNode& node) + { + } + std::wstring CTimelines::toXML() const + { + return L""; + } + EElementType CTimelines::getType() const + { + return et_x_Timelines; + } + void CTimelines::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + if (oReader.IsEmptyNode()) + return; + + int nCurDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nCurDepth)) + { + std::wstring sName = XmlUtils::GetNameNoNS(oReader.GetName()); + + if (L"timeline" == sName) + { + CTimeline* pTimeline = new CTimeline(); + *pTimeline = oReader; + m_arrItems.push_back(pTimeline); + } + } + } + void CTimelines::toXML(NSStringUtils::CStringBuilder& writer) const + { + if (m_arrItems.empty()) return; + + writer.WriteString(L""); + + for (size_t i = 0; i < m_arrItems.size(); ++i) + { + if (m_arrItems[i]) + { + m_arrItems[i]->toXML(writer); + } + } + writer.WriteString(L""); + } +//------------------------------------------------------------------------------------------------------- + CTimelineState::CTimelineState() + { + } + CTimelineState::~CTimelineState() + { + } + void CTimelineState::fromXML(XmlUtils::CXmlNode& node) + { + } + std::wstring CTimelineState::toXML() const + { + return L""; + } + EElementType CTimelineState::getType() const + { + return et_x_TimelineState; + } + void CTimelineState::toXML(NSStringUtils::CStringBuilder& writer) const + { + writer.WriteString(L""); + + if (m_oSelection.IsInit()) + { + m_oSelection->m_name = L"selection"; + m_oSelection->toXML(writer); + } + if (m_oBounds.IsInit()) + { + m_oBounds->m_name = L"bounds"; + m_oBounds->toXML(writer); + } + writer.WriteString(L""); + } + void CTimelineState::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + + if (oReader.IsEmptyNode()) + return; + + int nCurDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nCurDepth)) + { + std::wstring sName = XmlUtils::GetNameNoNS(oReader.GetName()); + + if (L"selection" == sName) + m_oSelection = oReader; + else if (L"bounds" == sName) + m_oBounds = oReader; + else if (L"extLst" == sName) + m_oExtLst = oReader; + } + } + void CTimelineState::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_Start(oReader) + WritingElement_ReadAttributes_Read_if(oReader, L"name", m_oName) + WritingElement_ReadAttributes_Read_else_if(oReader, L"singleRangeFilterState", m_oSingleRangeFilterState) + WritingElement_ReadAttributes_Read_else_if(oReader, L"pivotCacheId", m_oPivotCacheId) + WritingElement_ReadAttributes_Read_else_if(oReader, L"minimalRefreshVersion", m_oMinimalRefreshVersion) + WritingElement_ReadAttributes_Read_else_if(oReader, L"lastRefreshVersion", m_oLastRefreshVersion) + WritingElement_ReadAttributes_Read_else_if(oReader, L"filterType", m_oFilterType) + WritingElement_ReadAttributes_End(oReader) + } +//------------------------------------------------------------------------------------------------------- + CTimelinePivotFilter::CTimelinePivotFilter() + { + } + CTimelinePivotFilter::~CTimelinePivotFilter() + { + } + void CTimelinePivotFilter::fromXML(XmlUtils::CXmlNode& node) + { + } + std::wstring CTimelinePivotFilter::toXML() const + { + return L""; + } + EElementType CTimelinePivotFilter::getType() const + { + return et_x_TimelinePivotFilter; + } + void CTimelinePivotFilter::toXML(NSStringUtils::CStringBuilder& writer) const + { + writer.WriteString(L""); + + if (m_oAutoFilter.IsInit()) + { + m_oAutoFilter->toXML(writer); + } + writer.WriteString(L""); + } + void CTimelinePivotFilter::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + + if (oReader.IsEmptyNode()) + return; + + int nCurDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nCurDepth)) + { + std::wstring sName = XmlUtils::GetNameNoNS(oReader.GetName()); + + if (L"autoFilter" == sName) + m_oAutoFilter = oReader; + } + } + void CTimelinePivotFilter::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_Start(oReader) + WritingElement_ReadAttributes_Read_if(oReader, L"name", m_oName) + WritingElement_ReadAttributes_Read_else_if(oReader, L"description", m_oDescription) + WritingElement_ReadAttributes_Read_else_if(oReader, L"useWholeDay", m_oUseWholeDay) + WritingElement_ReadAttributes_Read_else_if(oReader, L"id", m_oId) + WritingElement_ReadAttributes_Read_else_if(oReader, L"fld", m_oFld) + WritingElement_ReadAttributes_End(oReader) + } +//---------------------------------------------------------------------------------------------------------------------- + CTimelineCacheDefinition::CTimelineCacheDefinition() + { + } + CTimelineCacheDefinition::~CTimelineCacheDefinition() + { + } + void CTimelineCacheDefinition::fromXML(XmlUtils::CXmlNode& node) + { + } + std::wstring CTimelineCacheDefinition::toXML() const + { + return L""; + } + EElementType CTimelineCacheDefinition::getType () const + { + return et_x_TimelineCacheDefinition; + } + void CTimelineCacheDefinition::toXML(NSStringUtils::CStringBuilder& writer) const + { + writer.WriteString(L""); + + if(m_oPivotTables.IsInit()) + { + m_oPivotTables->toXML(writer); + } + if(m_oState.IsInit()) + { + m_oState->toXML(writer); + } + if (m_oPivotFilter.IsInit()) + { + m_oPivotFilter->toXML(writer); + } + writer.WriteString(L""); + } + void CTimelineCacheDefinition::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes( oReader ); + + if ( oReader.IsEmptyNode() ) + return; + + int nCurDepth = oReader.GetDepth(); + while( oReader.ReadNextSiblingNode( nCurDepth ) ) + { + std::wstring sName = XmlUtils::GetNameNoNS(oReader.GetName()); + + if ( L"pivotTables" == sName ) + m_oPivotTables = oReader; + else if ( L"state" == sName ) + m_oState = oReader; + else if (L"pivotFilter" == sName) + m_oPivotFilter = oReader; + else if (L"pivotFilter" == sName) + m_oPivotFilter = oReader; + else if (L"extLst" == sName) + m_oExtLst = oReader; + } + } + void CTimelineCacheDefinition::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_Start( oReader ) + WritingElement_ReadAttributes_Read_if ( oReader, L"name", m_oName) + WritingElement_ReadAttributes_Read_else_if ( oReader, L"sourceName", m_oSourceName) + WritingElement_ReadAttributes_Read_else_if ( oReader, L"xr10:uid", m_oUid) + WritingElement_ReadAttributes_End( oReader ) + } +//----------------------------------------------------------------------------------------------------------------------------------------------------- + CTimelineFile::CTimelineFile(OOX::Document* pMain) : OOX::FileGlobalEnumerated(pMain), OOX::IFileContainer(pMain) + { + m_bSpreadsheets = true; + } + CTimelineFile::CTimelineFile(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath) : OOX::FileGlobalEnumerated(pMain), OOX::IFileContainer(pMain) + { + m_bSpreadsheets = true; + read( oRootPath, oPath ); + } + CTimelineFile::~CTimelineFile() + { + } + void CTimelineFile::read(const CPath& oPath) + { + //don't use this. use read(const CPath& oRootPath, const CPath& oFilePath) + CPath oRootPath; + read(oRootPath, oPath); + } + const OOX::FileType CTimelineFile::type() const + { + return OOX::Spreadsheet::FileTypes::Timeline; + } + const CPath CTimelineFile::DefaultDirectory() const + { + return type().DefaultDirectory(); + } + const CPath CTimelineFile::DefaultFileName() const + { + return type().DefaultFileName(); + } + const CPath& CTimelineFile::GetReadPath() + { + return m_oReadPath; + } + void CTimelineFile::read(const CPath& oRootPath, const CPath& oPath) + { + m_oReadPath = oPath; + IFileContainer::Read( oRootPath, oPath ); + + XmlUtils::CXmlLiteReader oReader; + + if ( !oReader.FromFile( oPath.GetPath() ) ) + return; + + if ( !oReader.ReadNextNode() ) + return; + + m_oTimelines = oReader; + } + void CTimelineFile::write(const CPath& oPath, const CPath& oDirectory, CContentTypes& oContent) const + { + if(false == m_oTimelines.IsInit()) return; + + NSStringUtils::CStringBuilder sXml; + + sXml.WriteString(L""); + m_oTimelines->toXML(sXml); + + std::wstring sPath = oPath.GetPath(); + NSFile::CFileBinary::SaveToFile(sPath, sXml.GetData()); + + oContent.Registration( type().OverrideType(), oDirectory, oPath.GetFilename() ); + IFileContainer::Write( oPath, oDirectory, oContent ); + } +//----------------------------------------------------------------------------------------------------------------------------------------------------- + CTimelineCacheFile::CTimelineCacheFile(OOX::Document* pMain) : OOX::FileGlobalEnumerated(pMain), OOX::IFileContainer(pMain) + { + m_bSpreadsheets = true; + } + CTimelineCacheFile::CTimelineCacheFile(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath) : OOX::FileGlobalEnumerated(pMain), OOX::IFileContainer(pMain) + { + m_bSpreadsheets = true; + read(oRootPath, oPath); + } + CTimelineCacheFile::~CTimelineCacheFile() + { + } + void CTimelineCacheFile::read(const CPath& oPath) + { + //don't use this. use read(const CPath& oRootPath, const CPath& oFilePath) + CPath oRootPath; + read(oRootPath, oPath); + } + const OOX::FileType CTimelineCacheFile::type() const + { + return OOX::Spreadsheet::FileTypes::TimelineCache; + } + const CPath CTimelineCacheFile::DefaultDirectory() const + { + return type().DefaultDirectory(); + } + const CPath CTimelineCacheFile::DefaultFileName() const + { + return type().DefaultFileName(); + } + const CPath& CTimelineCacheFile::GetReadPath() + { + return m_oReadPath; + } + void CTimelineCacheFile::read(const CPath& oRootPath, const CPath& oPath) + { + m_oReadPath = oPath; + IFileContainer::Read(oRootPath, oPath); + + XmlUtils::CXmlLiteReader oReader; + + if (!oReader.FromFile(oPath.GetPath())) + return; + + if (!oReader.ReadNextNode()) + return; + + m_oTimelineCacheDefinition = oReader; + } + void CTimelineCacheFile::write(const CPath& oPath, const CPath& oDirectory, CContentTypes& oContent) const + { + if (false == m_oTimelineCacheDefinition.IsInit()) return; + + NSStringUtils::CStringBuilder sXml; + + sXml.WriteString(L""); + m_oTimelineCacheDefinition->toXML(sXml); + + std::wstring sPath = oPath.GetPath(); + NSFile::CFileBinary::SaveToFile(sPath, sXml.GetData()); + + oContent.Registration(type().OverrideType(), oDirectory, oPath.GetFilename()); + IFileContainer::Write(oPath, oDirectory, oContent); + } +//------------------------------------------------------------------------------------- + CTimelineRefs::CTimelineRefs() {} + CTimelineRefs::~CTimelineRefs() {} + void CTimelineRefs::fromXML(XmlUtils::CXmlNode& node) + { + } + std::wstring CTimelineRefs::toXML() const + { + return L""; + } + EElementType CTimelineRefs::getType() const + { + return et_x_TimelineRefs; + } + void CTimelineRefs::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + if (oReader.IsEmptyNode()) + return; + + int nCurDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nCurDepth)) + { + std::wstring sName = XmlUtils::GetNameNoNS(oReader.GetName()); + + if (L"timelineRef" == sName) + { + CTimelineRef* pTimelineRef = new CTimelineRef(); + *pTimelineRef = oReader; + m_arrItems.push_back(pTimelineRef); + } + } + } + void CTimelineRefs::toXML(NSStringUtils::CStringBuilder& writer) const + { + if (m_arrItems.empty()) return; + + writer.WriteString(L""); + + for (size_t i = 0; i < m_arrItems.size(); ++i) + { + if (m_arrItems[i]) + { + m_arrItems[i]->toXML(writer); + } + } + writer.WriteString(L""); + } +//-------------------------------------------------------------------------------------------------------------------------- + CTimelineRef::CTimelineRef() {} + CTimelineRef::~CTimelineRef() {} + void CTimelineRef::fromXML(XmlUtils::CXmlNode& node) + { + } + std::wstring CTimelineRef::toXML() const + { + return L""; + } + EElementType CTimelineRef::getType() const + { + return et_x_TimelineRef; + } + void CTimelineRef::toXML(NSStringUtils::CStringBuilder& writer) const + { + writer.WriteString(L"ToString()); + writer.WriteString(L"/>"); + } + void CTimelineRef::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + } + void CTimelineRef::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_Start(oReader) + WritingElement_ReadAttributes_Read_if(oReader, L"r:id", m_oRId) + WritingElement_ReadAttributes_End(oReader) + } +//------------------------------------------------------------------------------------- + CTimelineCacheRefs::CTimelineCacheRefs() {} + CTimelineCacheRefs::~CTimelineCacheRefs() {} + void CTimelineCacheRefs::fromXML(XmlUtils::CXmlNode& node) + { + } + std::wstring CTimelineCacheRefs::toXML() const + { + return L""; + } + EElementType CTimelineCacheRefs::getType() const + { + return et_x_TimelineCacheRefs; + } + void CTimelineCacheRefs::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + if (oReader.IsEmptyNode()) + return; + + int nCurDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nCurDepth)) + { + std::wstring sName = XmlUtils::GetNameNoNS(oReader.GetName()); + + if (L"timelineCacheRef" == sName) + { + CTimelineCacheRef* pTimelineCacheRef = new CTimelineCacheRef(); + *pTimelineCacheRef = oReader; + m_arrItems.push_back(pTimelineCacheRef); + } + } + } + void CTimelineCacheRefs::toXML(NSStringUtils::CStringBuilder& writer) const + { + if (m_arrItems.empty()) return; + + writer.WriteString(L""); + + for (size_t i = 0; i < m_arrItems.size(); ++i) + { + if (m_arrItems[i]) + { + m_arrItems[i]->toXML(writer); + } + } + writer.WriteString(L""); + } +//-------------------------------------------------------------------------------------------------------------------------- + CTimelineCacheRef::CTimelineCacheRef() {} + CTimelineCacheRef::~CTimelineCacheRef() {} + void CTimelineCacheRef::fromXML(XmlUtils::CXmlNode& node) + { + } + std::wstring CTimelineCacheRef::toXML() const + { + return L""; + } + EElementType CTimelineCacheRef::getType() const + { + return et_x_TimelineCacheRef; + } + void CTimelineCacheRef::toXML(NSStringUtils::CStringBuilder& writer) const + { + writer.WriteString(L"ToString()); + writer.WriteString(L"/>"); + } + void CTimelineCacheRef::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + } + void CTimelineCacheRef::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_Start(oReader) + WritingElement_ReadAttributes_Read_if(oReader, L"r:id", m_oRId) + WritingElement_ReadAttributes_End(oReader) + } +//------------------------------------------------------------------------------------- + CTimelineStyles::CTimelineStyles() {} + CTimelineStyles::~CTimelineStyles() {} + void CTimelineStyles::fromXML(XmlUtils::CXmlNode& node) + { + } + std::wstring CTimelineStyles::toXML() const + { + return L""; + } + EElementType CTimelineStyles::getType() const + { + return et_x_TimelineStyles; + } + void CTimelineStyles::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_Start(oReader) + WritingElement_ReadAttributes_Read_if(oReader, L"defaultTimelineStyle", m_oDefaultTimelineStyle) + WritingElement_ReadAttributes_End(oReader) + } + void CTimelineStyles::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + + if (oReader.IsEmptyNode()) + return; + + int nCurDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nCurDepth)) + { + std::wstring sName = XmlUtils::GetNameNoNS(oReader.GetName()); + + if (L"timelineStyle" == sName) + { + CTimelineStyle* pStyle = new CTimelineStyle(); + *pStyle = oReader; + m_arrItems.push_back(pStyle); + } + } + } + void CTimelineStyles::toXML(NSStringUtils::CStringBuilder& writer) const + { + writer.WriteString(L""); + return; + } + else + writer.WriteString(L">"); + + for (size_t i = 0; i < m_arrItems.size(); ++i) + { + if (m_arrItems[i]) + { + m_arrItems[i]->toXML(writer); + } + } + writer.WriteString(L""); + } +//------------------------------------------------------------------------------------- + CTimelineStyle::CTimelineStyle() {} + CTimelineStyle::~CTimelineStyle() {} + void CTimelineStyle::fromXML(XmlUtils::CXmlNode& node) + { + } + std::wstring CTimelineStyle::toXML() const + { + return L""; + } + EElementType CTimelineStyle::getType() const + { + return et_x_TimelineStyle; + } + void CTimelineStyle::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_Start(oReader) + WritingElement_ReadAttributes_Read_if(oReader, L"name", m_oName) + WritingElement_ReadAttributes_End(oReader) + } + void CTimelineStyle::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + + if (oReader.IsEmptyNode()) + return; + + int nCurDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nCurDepth)) + { + std::wstring sName = XmlUtils::GetNameNoNS(oReader.GetName()); + + if (L"timelineStyleElement" == sName) + { + CTimelineStyleElement* pStyle = new CTimelineStyleElement(); + *pStyle = oReader; + m_arrItems.push_back(pStyle); + } + } + } + void CTimelineStyle::toXML(NSStringUtils::CStringBuilder& writer) const + { + writer.WriteString(L""); + return; + } + else + writer.WriteString(L">"); + + for (size_t i = 0; i < m_arrItems.size(); ++i) + { + if (m_arrItems[i]) + { + m_arrItems[i]->toXML(writer); + } + } + writer.WriteString(L""); + } +//-------------------------------------------------------------------------------------------------------------------------- + CTimelineStyleElement::CTimelineStyleElement() {} + CTimelineStyleElement::~CTimelineStyleElement() {} + void CTimelineStyleElement::fromXML(XmlUtils::CXmlNode& node) + { + } + std::wstring CTimelineStyleElement::toXML() const + { + return L""; + } + EElementType CTimelineStyleElement::getType() const + { + return et_x_TimelineStyleElement; + } + void CTimelineStyleElement::toXML(NSStringUtils::CStringBuilder& writer) const + { + writer.WriteString(L"ToString()); + WritingStringNullableAttrInt2(L"dxfId", m_oDxfId); + writer.WriteString(L"/>"); + } + void CTimelineStyleElement::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + } + void CTimelineStyleElement::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_Start(oReader) + WritingElement_ReadAttributes_Read_if(oReader, L"type", m_oType) + WritingElement_ReadAttributes_Read_else_if(oReader, L"dxfId", m_oDxfId) + WritingElement_ReadAttributes_End(oReader) + } +//-------------------------------------------------------------------------------------------------------------------------- + CDrawingTimeslicer::CDrawingTimeslicer() {} + CDrawingTimeslicer::~CDrawingTimeslicer() {} + void CDrawingTimeslicer::fromXML(XmlUtils::CXmlNode& node) + { + } + std::wstring CDrawingTimeslicer::toXML() const + { + return L""; + } + EElementType CDrawingTimeslicer::getType() const + { + return et_x_Timeslicer; + } + void CDrawingTimeslicer::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + if (!pWriter) return; + + pWriter->StartNode(L"tsle:timeslicer"); + pWriter->StartAttributes(); + pWriter->WriteString(L" xmlns:tsle=\"http://schemas.microsoft.com/office/drawing/2012/timeslicer\""); + if (m_oName.IsInit()) + pWriter->WriteAttribute2(L"name", *m_oName); + pWriter->EndAttributes(); + pWriter->EndNode(L"tsle:timeslicer"); + } + void CDrawingTimeslicer::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + } + void CDrawingTimeslicer::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_Start(oReader) + WritingElement_ReadAttributes_Read_if(oReader, L"name", m_oName) + WritingElement_ReadAttributes_End(oReader) + } + void CDrawingTimeslicer::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeStart); + pWriter->WriteString2(0, m_oName); + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd); + } + void CDrawingTimeslicer::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG _end_rec = pReader->GetPos() + pReader->GetRecordSize() + 4; + pReader->Skip(1); // start attributes + while (true) + { + BYTE _at = pReader->GetUChar_TypeNode(); + if (_at == NSBinPptxRW::g_nodeAttributeEnd) + break; + switch (_at) + { + case 0: + { + m_oName = pReader->GetString2(); + }break; + } + } + pReader->Seek(_end_rec); + } + } //Spreadsheet +} // namespace OOX + diff --git a/OOXML/XlsxFormat/Timelines/Timeline.h b/OOXML/XlsxFormat/Timelines/Timeline.h new file mode 100644 index 00000000000..6f66aca6d76 --- /dev/null +++ b/OOXML/XlsxFormat/Timelines/Timeline.h @@ -0,0 +1,461 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#pragma once + +#include "../Table/Autofilter.h" +#include "../../DocxFormat/IFileContainer.h" +#include "../../Common/SimpleTypes_Spreadsheet.h" + +namespace OOX +{ + namespace Drawing + { + class COfficeArtExtensionList; + } + + namespace Spreadsheet + { +//------------------------------------------------------------------------------------------------------------------------ + class CTimelineCachePivotTable : public WritingElement + { + public: + WritingElement_AdditionMethods(CTimelineCachePivotTable) + + CTimelineCachePivotTable(); + virtual ~CTimelineCachePivotTable(); + + virtual void fromXML(XmlUtils::CXmlNode& node); + virtual std::wstring toXML() const; + + virtual void toXML(NSStringUtils::CStringBuilder& writer) const; + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + + virtual EElementType getType() const; + + private: + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + public: + nullable_string m_oName; + nullable_uint m_oTabId; + }; +//------------------------------------------------------------------------------------------------------------------------ + class CTimelineRange : public WritingElement + { + public: + WritingElement_AdditionMethods(CTimelineRange) + + CTimelineRange(); + virtual ~CTimelineRange(); + + virtual void fromXML(XmlUtils::CXmlNode& node); + virtual std::wstring toXML() const; + + virtual void toXML(NSStringUtils::CStringBuilder& writer) const; + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + + virtual EElementType getType() const; + + private: + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + public: + nullable_string m_oStartDate; + nullable_string m_oEndDate; + + std::wstring m_name; + }; +//------------------------------------------------------------------------------------------------------------------------ + class CTimelineCachePivotTables : public WritingElementWithChilds + { + public: + WritingElement_AdditionMethods(CTimelineCachePivotTables) + CTimelineCachePivotTables(); + virtual ~CTimelineCachePivotTables(); + + virtual void fromXML(XmlUtils::CXmlNode& node); + virtual std::wstring toXML() const; + + virtual void toXML(NSStringUtils::CStringBuilder& writer) const; + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + + virtual EElementType getType() const; + }; +//-------------------------------------------------------------------------------------------------------------- + class CTimelineState : public WritingElement + { + public: + WritingElement_AdditionMethods(CTimelineState) + CTimelineState(); + virtual ~CTimelineState(); + + virtual void fromXML(XmlUtils::CXmlNode& node); + virtual std::wstring toXML() const; + + virtual void toXML(NSStringUtils::CStringBuilder& writer) const; + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + + virtual EElementType getType() const; + + private: + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + + public: + nullable_string m_oName; + nullable_bool m_oSingleRangeFilterState; + nullable_uint m_oPivotCacheId; + nullable_uint m_oMinimalRefreshVersion; + nullable_uint m_oLastRefreshVersion; + nullable_string m_oFilterType; + + nullable m_oSelection; + nullable m_oBounds; + nullable m_oExtLst; + }; +//-------------------------------------------------------------------------------------------------------------- + class CTimelinePivotFilter : public WritingElement + { + public: + WritingElement_AdditionMethods(CTimelinePivotFilter) + CTimelinePivotFilter(); + virtual ~CTimelinePivotFilter(); + + virtual void fromXML(XmlUtils::CXmlNode& node); + virtual std::wstring toXML() const; + + virtual void toXML(NSStringUtils::CStringBuilder& writer) const; + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + + virtual EElementType getType() const; + + private: + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + + public: + nullable_string m_oName; + nullable_string m_oDescription; + nullable_bool m_oUseWholeDay; + nullable_uint m_oId; + nullable_uint m_oFld; + + nullable m_oAutoFilter; + }; +//-------------------------------------------------------------------------------------------------------------- + class CTimelineCacheDefinition : public WritingElement + { + public: + WritingElement_AdditionMethods(CTimelineCacheDefinition) + CTimelineCacheDefinition(); + virtual ~CTimelineCacheDefinition(); + + virtual void fromXML(XmlUtils::CXmlNode& node); + virtual std::wstring toXML() const; + + virtual void toXML(NSStringUtils::CStringBuilder& writer) const; + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + + virtual EElementType getType() const; + + private: + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + + public: + nullable_string m_oName; + nullable_string m_oSourceName; + nullable_string m_oUid; + + nullable m_oPivotTables; + nullable m_oState; + nullable m_oPivotFilter; + nullable m_oExtLst; + }; +//------------------------------------------------------------------------------------------------------------------------ + class CTimeline : public WritingElement + { + public: + WritingElement_AdditionMethods(CTimeline) + + CTimeline(); + virtual ~CTimeline(); + + virtual void fromXML(XmlUtils::CXmlNode& node); + virtual std::wstring toXML() const; + + virtual void toXML(NSStringUtils::CStringBuilder& writer) const; + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + + virtual EElementType getType () const; + + private: + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + public: + nullable_string m_oName; + nullable_string m_oCaption; + nullable_string m_oUid; + nullable_string m_oScrollPosition; + nullable_string m_oCache; + nullable_uint m_oSelectionLevel; + nullable_uint m_oLevel; + nullable_bool m_oShowHeader; + nullable_bool m_oShowSelectionLabel; + nullable_bool m_oShowTimeLevel; + nullable_bool m_oShowHorizontalScrollbar; + nullable m_oStyle; + + nullable m_oExtLst; + }; +//------------------------------------------------------------------------------------------------------------------------ + class CTimelines : public WritingElementWithChilds + { + public: + WritingElement_AdditionMethods(CTimelines) + CTimelines(); + virtual ~CTimelines(); + + virtual void fromXML(XmlUtils::CXmlNode& node); + virtual std::wstring toXML() const; + + virtual void toXML(NSStringUtils::CStringBuilder& writer) const; + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + + virtual EElementType getType () const; + }; +//------------------------------------------------------------------------------------------------------------------------ + class CTimelineFile : public OOX::FileGlobalEnumerated, public OOX::IFileContainer + { + public: + CTimelineFile(OOX::Document* pMain); + CTimelineFile(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath); + virtual ~CTimelineFile(); + + virtual void read(const CPath& oPath); + virtual void read(const CPath& oRootPath, const CPath& oPath); + + virtual void write(const CPath& oPath, const CPath& oDirectory, CContentTypes& oContent) const; + virtual const OOX::FileType type() const; + + virtual const CPath DefaultDirectory() const; + virtual const CPath DefaultFileName() const; + + const CPath& GetReadPath(); + + nullable m_oTimelines; + private: + CPath m_oReadPath; + }; +//------------------------------------------------------------------------------------------------------------------------ + class CTimelineCacheFile : public OOX::FileGlobalEnumerated, public OOX::IFileContainer + { + public: + CTimelineCacheFile(OOX::Document* pMain); + CTimelineCacheFile(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath); + virtual ~CTimelineCacheFile(); + + virtual void read(const CPath& oPath); + virtual void read(const CPath& oRootPath, const CPath& oPath); + + virtual void write(const CPath& oPath, const CPath& oDirectory, CContentTypes& oContent) const; + virtual const OOX::FileType type() const; + + virtual const CPath DefaultDirectory() const; + virtual const CPath DefaultFileName() const; + + const CPath& GetReadPath(); + + nullable m_oTimelineCacheDefinition; + private: + CPath m_oReadPath; + }; +//------------------------------------------------------------------------------------------------------------------------ + class CTimelineRef : public WritingElement + { + public: + WritingElement_AdditionMethods(CTimelineRef) + + CTimelineRef(); + virtual ~CTimelineRef(); + + virtual void fromXML(XmlUtils::CXmlNode& node); + virtual std::wstring toXML() const; + + virtual void toXML(NSStringUtils::CStringBuilder& writer) const; + + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + + virtual EElementType getType() const; + private: + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + public: + nullable m_oRId; + }; +//------------------------------------------------------------------------------------------------------------------------ + class CTimelineRefs : public WritingElementWithChilds + { + public: + WritingElement_AdditionMethods(CTimelineRefs) + CTimelineRefs(); + virtual ~CTimelineRefs(); + + virtual void fromXML(XmlUtils::CXmlNode& node); + virtual std::wstring toXML() const; + + virtual void toXML(NSStringUtils::CStringBuilder& writer) const; + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + + virtual EElementType getType() const; + }; +//------------------------------------------------------------------------------------------------------------------------ + class CTimelineCacheRef : public WritingElement + { + public: + WritingElement_AdditionMethods(CTimelineCacheRef) + + CTimelineCacheRef(); + virtual ~CTimelineCacheRef(); + + virtual void fromXML(XmlUtils::CXmlNode& node); + virtual std::wstring toXML() const; + + virtual void toXML(NSStringUtils::CStringBuilder& writer) const; + + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + + virtual EElementType getType() const; + private: + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + public: + nullable m_oRId; + }; +//------------------------------------------------------------------------------------------------------------------------ + class CTimelineCacheRefs : public WritingElementWithChilds + { + public: + WritingElement_AdditionMethods(CTimelineCacheRefs) + CTimelineCacheRefs(); + virtual ~CTimelineCacheRefs(); + + virtual void fromXML(XmlUtils::CXmlNode& node); + virtual std::wstring toXML() const; + + virtual void toXML(NSStringUtils::CStringBuilder& writer) const; + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + + virtual EElementType getType() const; + }; +//--------------------------------------------------------------------------------------------------------------------------- + class CDrawingTimeslicer : public WritingElement + { + public: + WritingElement_AdditionMethods(CDrawingTimeslicer) + CDrawingTimeslicer(); + virtual ~CDrawingTimeslicer(); + + virtual void fromXML(XmlUtils::CXmlNode& node); + virtual std::wstring toXML() const; + + virtual void toXML(NSStringUtils::CStringBuilder& writer) const {} + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + + virtual EElementType getType() const; + + private: + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + public: + nullable_string m_oName; + }; +//---------------------------------------------------------------------------------------------------------------------------- + class CTimelineStyleElement : public WritingElement + { + public: + WritingElement_AdditionMethods(CTimelineStyleElement) + CTimelineStyleElement(); + virtual ~CTimelineStyleElement(); + + virtual void fromXML(XmlUtils::CXmlNode& node); + virtual std::wstring toXML() const; + + virtual void toXML(NSStringUtils::CStringBuilder& writer) const; + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + + virtual EElementType getType() const; + + private: + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + public: + nullable m_oType; + nullable_uint m_oDxfId; + }; + class CTimelineStyle : public WritingElementWithChilds + { + public: + WritingElement_AdditionMethods(CTimelineStyle) + + CTimelineStyle(); + virtual ~CTimelineStyle(); + + virtual void fromXML(XmlUtils::CXmlNode& node); + virtual std::wstring toXML() const; + + virtual void toXML(NSStringUtils::CStringBuilder& writer) const; + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + + virtual EElementType getType() const; + + private: + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + public: + nullable_string m_oName; + }; + class CTimelineStyles : public WritingElementWithChilds + { + public: + WritingElement_AdditionMethods(CTimelineStyles) + CTimelineStyles(); + virtual ~CTimelineStyles(); + + virtual void fromXML(XmlUtils::CXmlNode& node); + virtual std::wstring toXML() const; + + virtual void toXML(NSStringUtils::CStringBuilder& writer) const; + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + + virtual EElementType getType() const; + + private: + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + public: + nullable_string m_oDefaultTimelineStyle; + }; + } //Spreadsheet +} // namespace OOX diff --git a/OOXML/XlsxFormat/Workbook/BookViews.cpp b/OOXML/XlsxFormat/Workbook/BookViews.cpp index b960837f4da..8ce08ea6a50 100644 --- a/OOXML/XlsxFormat/Workbook/BookViews.cpp +++ b/OOXML/XlsxFormat/Workbook/BookViews.cpp @@ -61,6 +61,14 @@ namespace OOX WritingStringNullableAttrInt(L"windowWidth", m_oWindowWidth, m_oWindowWidth->GetValue()); WritingStringNullableAttrInt(L"windowHeight", m_oWindowHeight, m_oWindowHeight->GetValue()); WritingStringNullableAttrInt(L"activeTab", m_oActiveTab, m_oActiveTab->GetValue()); + WritingStringNullableAttrInt(L"firstSheet", m_oFirstSheet, m_oFirstSheet->GetValue()); + WritingStringNullableAttrInt(L"tabRatio", m_oTabRatio, m_oTabRatio->GetValue()); + WritingStringNullableAttrBool(L"autoFilterDateGrouping", m_oAutoFilterDateGrouping); + WritingStringNullableAttrBool(L"showSheetTabs", m_oShowSheetTabs); + WritingStringNullableAttrBool(L"minimized", m_oMinimized); + WritingStringNullableAttrBool(L"showHorizontalScroll", m_oShowHorizontalScroll); + WritingStringNullableAttrBool(L"showVerticalScroll", m_oShowVerticalScroll); + WritingStringNullableAttrString(L"visibility", m_oVisibility, m_oVisibility->ToString()); writer.WriteString(_T("/>")); } void CWorkbookView::fromXML(XmlUtils::CXmlLiteReader& oReader) @@ -74,30 +82,98 @@ namespace OOX { ReadAttributes(obj); } + XLS::BaseObjectPtr CWorkbookView::toBin() + { + auto ptr(new XLSB::BookView); + XLS::BaseObjectPtr objectPtr(ptr); + + if (m_oActiveTab.IsInit()) + { + ptr->itabCur = m_oActiveTab->GetValue(); + } + else + { + ptr->itabCur = 0; + } + + if (m_oAutoFilterDateGrouping.IsInit()) + ptr->fNoAFDateGroup = m_oAutoFilterDateGrouping->GetValue(); + else + ptr->fNoAFDateGroup = false; + if (m_oFirstSheet.IsInit()) + ptr->itabFirst = m_oFirstSheet->GetValue(); + else + ptr->itabFirst = 0; + if (m_oMinimized.IsInit()) + ptr->fIconic = m_oMinimized->GetValue(); + else + ptr->fIconic = false; + if (m_oShowHorizontalScroll.IsInit()) + ptr->fDspHScroll = m_oShowHorizontalScroll->GetValue(); + if (m_oShowSheetTabs.IsInit()) + ptr->fBotAdornment = m_oShowSheetTabs->GetValue(); + if (m_oShowVerticalScroll.IsInit()) + ptr->fDspVScroll = m_oShowVerticalScroll->GetValue(); + if (m_oTabRatio.IsInit()) + ptr->wTabRatio = m_oTabRatio->GetValue(); + else + ptr->wTabRatio = 600; + if (m_oWindowHeight.IsInit()) + ptr->dyWn = m_oWindowHeight->GetValue(); + else + ptr->dyWn = 12750; + if (m_oWindowWidth.IsInit()) + ptr->dxWn = m_oWindowWidth->GetValue(); + else + ptr->dxWn = 21240; + if (m_oXWindow.IsInit()) + ptr->xWn = m_oXWindow->GetValue() * 6; + else + ptr->xWn = 2280; + if (m_oYWindow.IsInit()) + ptr->yWn = m_oYWindow->GetValue() * 110; + else + ptr->yWn = 1650; + + if (m_oVisibility == SimpleTypes::Spreadsheet::EVisibleType::visibleHidden) + { + ptr->fHidden = true; + ptr->fVeryHidden = false; + } + else if (m_oVisibility == SimpleTypes::Spreadsheet::EVisibleType::visibleVeryHidden) + { + ptr->fHidden = false; + ptr->fVeryHidden = true; + } + else + { + ptr->fHidden = false; + ptr->fVeryHidden = false; + } + + return objectPtr; + } EElementType CWorkbookView::getType () const { return et_x_WorkbookView; } void CWorkbookView::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) { - // Читаем атрибуты WritingElement_ReadAttributes_Start( oReader ) - - WritingElement_ReadAttributes_Read_if ( oReader, _T("activeTab"), m_oActiveTab ) - WritingElement_ReadAttributes_Read_if ( oReader, _T("autoFilterDateGrouping"), m_oAutoFilterDateGrouping ) - WritingElement_ReadAttributes_Read_if ( oReader, _T("firstSheet"), m_oFirstSheet ) - WritingElement_ReadAttributes_Read_if ( oReader, _T("minimized"), m_oMinimized ) - WritingElement_ReadAttributes_Read_if ( oReader, _T("showHorizontalScroll"), m_oShowHorizontalScroll ) - WritingElement_ReadAttributes_Read_if ( oReader, _T("showSheetTabs"), m_oShowSheetTabs ) - WritingElement_ReadAttributes_Read_if ( oReader, _T("showVerticalScroll"), m_oShowVerticalScroll ) - WritingElement_ReadAttributes_Read_if ( oReader, _T("tabRatio"), m_oTabRatio ) - WritingElement_ReadAttributes_Read_if ( oReader, _T("visibility"), m_oVisibility ) - WritingElement_ReadAttributes_Read_if ( oReader, _T("windowHeight"), m_oWindowHeight ) - WritingElement_ReadAttributes_Read_if ( oReader, _T("windowWidth"), m_oWindowWidth ) - WritingElement_ReadAttributes_Read_if ( oReader, _T("xWindow"), m_oXWindow ) - WritingElement_ReadAttributes_Read_if ( oReader, _T("yWindow"), m_oYWindow ) - - WritingElement_ReadAttributes_End( oReader ) + WritingElement_ReadAttributes_Read_if ( oReader, _T("activeTab"), m_oActiveTab ) + WritingElement_ReadAttributes_Read_if ( oReader, _T("autoFilterDateGrouping"), m_oAutoFilterDateGrouping ) + WritingElement_ReadAttributes_Read_if ( oReader, _T("firstSheet"), m_oFirstSheet ) + WritingElement_ReadAttributes_Read_if ( oReader, _T("minimized"), m_oMinimized ) + WritingElement_ReadAttributes_Read_if ( oReader, _T("showHorizontalScroll"), m_oShowHorizontalScroll ) + WritingElement_ReadAttributes_Read_if ( oReader, _T("showSheetTabs"), m_oShowSheetTabs ) + WritingElement_ReadAttributes_Read_if ( oReader, _T("showVerticalScroll"), m_oShowVerticalScroll ) + WritingElement_ReadAttributes_Read_if ( oReader, _T("tabRatio"), m_oTabRatio ) + WritingElement_ReadAttributes_Read_if ( oReader, _T("visibility"), m_oVisibility ) + WritingElement_ReadAttributes_Read_if ( oReader, _T("windowHeight"), m_oWindowHeight ) + WritingElement_ReadAttributes_Read_if ( oReader, _T("windowWidth"), m_oWindowWidth ) + WritingElement_ReadAttributes_Read_if ( oReader, _T("xWindow"), m_oXWindow ) + WritingElement_ReadAttributes_Read_if ( oReader, _T("yWindow"), m_oYWindow ) + WritingElement_ReadAttributes_End( oReader ) } void CWorkbookView::ReadAttributes(XLS::BaseObjectPtr& obj) { @@ -183,6 +259,14 @@ namespace OOX m_arrItems.push_back(new CWorkbookView(workbookView)); } } + std::vector CBookViews::toBin() + { + std::vector ptrVector{}; + for(auto i:m_arrItems) + ptrVector.push_back(i->toBin()); + + return ptrVector; + } EElementType CBookViews::getType () const { return et_x_BookViews; diff --git a/OOXML/XlsxFormat/Workbook/BookViews.h b/OOXML/XlsxFormat/Workbook/BookViews.h index 5083d26c156..bd5c418df5e 100644 --- a/OOXML/XlsxFormat/Workbook/BookViews.h +++ b/OOXML/XlsxFormat/Workbook/BookViews.h @@ -67,6 +67,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; private: @@ -104,6 +105,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(std::vector& obj); + std::vector toBin(); virtual EElementType getType () const; private: diff --git a/OOXML/XlsxFormat/Workbook/CalcPr.cpp b/OOXML/XlsxFormat/Workbook/CalcPr.cpp index 1cfd708051a..739b5cb9ddc 100644 --- a/OOXML/XlsxFormat/Workbook/CalcPr.cpp +++ b/OOXML/XlsxFormat/Workbook/CalcPr.cpp @@ -82,6 +82,64 @@ namespace OOX { ReadAttributes(obj); } + XLS::BaseObjectPtr CCalcPr::toBin() + { + auto ptr(new XLSB::CalcProp); + XLS::BaseObjectPtr objectPtr(ptr); + + if(m_oCalcId.IsInit()) + ptr->recalcID = m_oCalcId->GetValue(); + else + ptr->recalcID = 0; + if(m_oCalcMode.IsInit()) + ptr->fAutoRecalc = m_oCalcMode->GetValue(); + else + ptr->fAutoRecalc = 1; + if(m_oFullCalcOnLoad.IsInit()) + ptr->fFullCalcOnLoad = m_oFullCalcOnLoad->GetValue(); + else + ptr->fFullCalcOnLoad = false; + if(m_oRefMode.IsInit()) + ptr->fRefA1 = !m_oRefMode->GetValue(); + if(m_oIterate.IsInit()) + ptr->fIter = m_oIterate->GetValue(); + else + ptr->fIter = 0; + if(m_oIterateCount.IsInit()) + ptr->cCalcCount = m_oIterateCount->GetValue(); + else + ptr->cCalcCount = 0; + if(m_oIterateDelta.IsInit()) + ptr->xnumDelta.data.value = m_oIterateDelta->GetValue(); + else + ptr->xnumDelta.data.value = 0; + if(m_oFullPrecision.IsInit()) + ptr->fFullPrec = m_oFullPrecision->GetValue(); + else + ptr->fFullPrec = true; + if(m_oCalcCompleted.IsInit()) + ptr->fSomeUncalced = m_oCalcCompleted->GetValue(); + else + ptr->fSomeUncalced = false; + if(m_oCalcOnSave.IsInit()) + ptr->fSaveRecalc = m_oCalcOnSave->GetValue(); + else + ptr->fSaveRecalc = true; + if(m_oConcurrentCalc.IsInit()) + ptr->fMTREnabled = m_oConcurrentCalc->GetValue(); + else + ptr->fMTREnabled = true; + if(m_oConcurrentManualCount.IsInit()) + ptr->cUserThreadCount = m_oConcurrentManualCount->GetValue(); + else + ptr->cUserThreadCount = 1; + if(m_oForceFullCalc.IsInit()) + ptr->fNoDeps = m_oForceFullCalc->GetValue(); + else + ptr->fNoDeps = false; + + return objectPtr; + } EElementType CCalcPr::getType () const { return et_x_CalcPr; diff --git a/OOXML/XlsxFormat/Workbook/CalcPr.h b/OOXML/XlsxFormat/Workbook/CalcPr.h index 821d0adb0b0..2e193e766f8 100644 --- a/OOXML/XlsxFormat/Workbook/CalcPr.h +++ b/OOXML/XlsxFormat/Workbook/CalcPr.h @@ -66,6 +66,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; private: diff --git a/OOXML/XlsxFormat/Workbook/DefinedNames.cpp b/OOXML/XlsxFormat/Workbook/DefinedNames.cpp index ce46f599281..e3060654224 100644 --- a/OOXML/XlsxFormat/Workbook/DefinedNames.cpp +++ b/OOXML/XlsxFormat/Workbook/DefinedNames.cpp @@ -73,6 +73,82 @@ namespace OOX return; m_oRef = oReader.GetText3(); + if(m_oName.IsInit()) + XLS::GlobalWorkbookInfo::arDefineNames_static.push_back(m_oName.get()); + } + XLS::BaseObjectPtr CDefinedName::toBin() + { + auto ptr(new XLSB::Name); + XLS::BaseObjectPtr objectPtr(ptr); + + if(m_oComment.IsInit()) + ptr->comment = m_oComment.get(); + else + ptr->comment.setSize(0xFFFFFFFF); + + if(m_oDescription.IsInit()) + ptr->description = m_oDescription.get(); + else + ptr->description.setSize(0xFFFFFFFF); + if(m_oFunction.IsInit()) + ptr->fFunc = m_oFunction->GetValue(); + else + ptr->fFunc = false; + if(m_oFunctionGroupId.IsInit()) + ptr->fGrp = m_oFunctionGroupId->GetValue(); + + if(m_oHelp.IsInit()) + ptr->helpTopic = m_oHelp.get(); + else + ptr->helpTopic.setSize(0xFFFFFFFF); + if(m_oHidden.IsInit()) + ptr->fHidden = m_oHidden->GetValue(); + else + ptr->fHidden = false; + + if (m_oLocalSheetId.IsInit()) + ptr->itab = m_oLocalSheetId->GetValue(); + else + ptr->itab = 0xFFFFFFFF; + + if (m_oName.IsInit()) + ptr->name = m_oName.get(); + else + ptr->name.setSize(0xFFFFFFFF); + if (m_oPublishToServer.IsInit()) + ptr->fPublished = m_oPublishToServer->GetValue(); + else + ptr->fPublished = false; + if (m_oShortcutKey.IsInit()) + ptr->chKey = std::stoi(m_oShortcutKey.get()); + else + ptr->chKey = 0; + + if (m_oVbProcedure.IsInit()) + ptr->fOB = m_oVbProcedure->GetValue(); + else + ptr->fOB = false; + if(!ptr->fOB) + ptr->fProc = false; + if(!ptr->fProc) + { + ptr->unusedstring1.setSize(0xFFFFFFFF); + ptr->unusedstring2.setSize(0xFFFFFFFF); + } + + if (m_oWorkbookParameter.IsInit()) + ptr->fWorkbookParam = m_oWorkbookParameter->GetValue(); + else + ptr->fWorkbookParam = false; + if (m_oXlm.IsInit()) + ptr->fFutureFunction = m_oXlm->GetValue(); + else + ptr->fFutureFunction = false; + if (m_oRef.IsInit()) + ptr->rgce = m_oRef.get(); + ptr->fCalcExp = true; + ptr->fBuiltin = false; + return objectPtr; } void CDefinedName::fromBin(XLS::BaseObjectPtr& obj) { @@ -165,6 +241,39 @@ namespace OOX } } } + std::vector CDefinedNames::AddFutureFunctions(const _UINT32 namesStart) + { + std::vector FunctionsVector; + if(XLS::GlobalWorkbookInfo::arDefineNames_static.empty()) + return FunctionsVector; + for(auto i = namesStart; i < XLS::GlobalWorkbookInfo::arDefineNames_static.size(); i++) + { + if(XLS::GlobalWorkbookInfo::arDefineNames_static[i].substr(0, 6) == L"_xlfn.") + { + FunctionsVector.push_back(createFutureFunction(XLS::GlobalWorkbookInfo::arDefineNames_static[i])); + } + else + { + FunctionsVector.push_back(createCustomFunction(XLS::GlobalWorkbookInfo::arDefineNames_static[i])); + } + } + return FunctionsVector; + } + std::vector CDefinedNames::toBin() + { + std::vector objectVector; + + for(auto i:m_arrItems) + objectVector.push_back(i->toBin()); + + auto functionsVector = AddFutureFunctions(m_arrItems.size()); + if(!functionsVector.empty()) + { + std::copy(functionsVector.begin(), functionsVector.end(), std::back_inserter(objectVector)); + } + + return objectVector; + } void CDefinedNames::fromBin(std::vector& obj) { //ReadAttributes(obj); @@ -187,6 +296,61 @@ namespace OOX void CDefinedNames::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) { } + XLS::BaseObjectPtr CDefinedNames::createFutureFunction(const std::wstring& funcName) + { + auto ptr(new XLSB::Name); + XLS::BaseObjectPtr objectPtr(ptr); + + ptr->chKey = 0; + ptr->fHidden = true; + ptr->fFunc = true; + ptr->fOB = false; + ptr->fProc = true; + ptr->fCalcExp = false; + ptr->fGrp = true; + ptr->fPublished = false; + ptr->fBuiltin = false; + ptr->fWorkbookParam = false; + ptr->comment.setSize(0xFFFFFFFF); + ptr->itab = 0xFFFFFFFF; + + ptr->fFutureFunction = true; + ptr->name = funcName; + ptr->rgce.parseStringFormula(L"#NAME?", L""); + ptr->description.setSize(0xFFFFFFFF); + ptr->helpTopic.setSize(0xFFFFFFFF); + ptr->unusedstring1.setSize(0xFFFFFFFF); + ptr->unusedstring2.setSize(0xFFFFFFFF); + return objectPtr; + } + + XLS::BaseObjectPtr CDefinedNames::createCustomFunction(const std::wstring& funcName) + { + auto ptr(new XLSB::Name); + XLS::BaseObjectPtr objectPtr(ptr); + + ptr->chKey = 0; + ptr->fHidden = false; + ptr->fFunc = true; + ptr->fOB = true; + ptr->fProc = true; + ptr->fCalcExp = false; + ptr->fGrp = false; + ptr->fPublished = false; + ptr->fBuiltin = false; + ptr->fWorkbookParam = false; + ptr->itab = 0xFFFFFFFF; + ptr->comment.setSize(0xFFFFFFFF); + + ptr->description.setSize(0xFFFFFFFF); + ptr->helpTopic.setSize(0xFFFFFFFF); + ptr->unusedstring1.setSize(0xFFFFFFFF); + ptr->unusedstring2.setSize(0xFFFFFFFF); + + ptr->fFutureFunction = false; + ptr->name = funcName; + return objectPtr; + } } //Spreadsheet } // namespace OOX diff --git a/OOXML/XlsxFormat/Workbook/DefinedNames.h b/OOXML/XlsxFormat/Workbook/DefinedNames.h index 971c6ebc969..d612f0c67d0 100644 --- a/OOXML/XlsxFormat/Workbook/DefinedNames.h +++ b/OOXML/XlsxFormat/Workbook/DefinedNames.h @@ -60,6 +60,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; private: @@ -102,9 +103,13 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(std::vector& obj); + std::vector toBin(); + std::vector AddFutureFunctions(const _UINT32 namesStart); virtual EElementType getType () const; private: + XLS::BaseObjectPtr createFutureFunction(const std::wstring& funcName); + XLS::BaseObjectPtr createCustomFunction(const std::wstring& custom); void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); }; diff --git a/OOXML/XlsxFormat/Workbook/ExternalReferences.cpp b/OOXML/XlsxFormat/Workbook/ExternalReferences.cpp index 4e86b9a9811..c9b42ac0af6 100644 --- a/OOXML/XlsxFormat/Workbook/ExternalReferences.cpp +++ b/OOXML/XlsxFormat/Workbook/ExternalReferences.cpp @@ -39,7 +39,7 @@ namespace OOX { namespace Spreadsheet - { + { CExternalReference::CExternalReference() { } @@ -66,6 +66,20 @@ namespace OOX if ( !oReader.IsEmptyNode() ) oReader.ReadTillEnd(); } + XLS::BaseObjectPtr CExternalReference::toBin() + { + auto ptr(new XLSB::SUP); + XLS::BaseObjectPtr objectPtr(ptr); + auto ptr1(new XLSB::SupBookSrc); + ptr->m_source = XLS::BaseObjectPtr{ptr1}; + if(m_oRid.IsInit()) + ptr1->strRelID.value = m_oRid->GetValue(); + else + ptr1->strRelID.value.setSize(0xFFFFFFFF); + + return objectPtr; + } + void CExternalReference::fromBin(XLS::BaseObjectPtr& obj) { ReadAttributes(obj); @@ -156,6 +170,13 @@ namespace OOX m_arrItems.push_back(reference); } } + std::vector CExternalReferences::toBin() + { + std::vector objectVector; + for(auto i:m_arrItems) + objectVector.push_back(i->toBin()); + return objectVector; + } EElementType CExternalReferences::getType () const { return et_x_ExternalReferences; diff --git a/OOXML/XlsxFormat/Workbook/ExternalReferences.h b/OOXML/XlsxFormat/Workbook/ExternalReferences.h index 557ef3a8763..55a4813638c 100644 --- a/OOXML/XlsxFormat/Workbook/ExternalReferences.h +++ b/OOXML/XlsxFormat/Workbook/ExternalReferences.h @@ -57,6 +57,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; @@ -83,6 +84,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(std::vector& obj); + std::vector toBin(); virtual EElementType getType () const; diff --git a/OOXML/XlsxFormat/Workbook/Metadata.cpp b/OOXML/XlsxFormat/Workbook/Metadata.cpp new file mode 100644 index 00000000000..af68d8fb6ca --- /dev/null +++ b/OOXML/XlsxFormat/Workbook/Metadata.cpp @@ -0,0 +1,1703 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#include "Metadata.h" + +#include "../../XlsbFormat/Xlsb.h" +#include "../../XlsbFormat/MetadataStream.h" +#include "../../XlsbFormat/Biff12_unions/ESSTR.h" +#include "../../XlsbFormat/Biff12_unions/ESMDTINFO.h" +#include "../../XlsbFormat/Biff12_unions/ESMDB.h" +#include "../../XlsbFormat/Biff12_unions/ESFMD.h" +#include "../../XlsbFormat/Biff12_unions/FMD.h" +#include "../../XlsbFormat/Biff12_unions/ESMDX.h" +#include "../../XlsbFormat/Biff12_unions/MDX.h" +#include "../../XlsbFormat/Biff12_unions/MDXKPI.h" +#include "../../XlsbFormat/Biff12_unions/MDXMBRPROP.h" +#include "../../XlsbFormat/Biff12_unions/MDXSET.h" +#include "../../XlsbFormat/Biff12_unions/MDXTUPLE.h" +#include "../../XlsbFormat/Biff12_unions/DYNAMICARRAYMETADATA.h" +#include "../../XlsbFormat/Biff12_unions/RICHDATAMETADATA.h" + +#include "../../XlsbFormat/Biff12_records/Str.h" +#include "../../XlsbFormat/Biff12_records/Mdtinfo.h" +#include "../../XlsbFormat/Biff12_records/Mdb.h" +#include "../../XlsbFormat/Biff12_records/BeginEsmdb.h" +#include "../../XlsbFormat/Biff12_records/BeginEsfmd.h" +#include "../../XlsbFormat/Biff12_records/EndDynamicArrayPr.h" +#include "../../XlsbFormat/Biff12_records/BeginRichValueBlock.h" +#include "../../XlsbFormat/Biff12_records/BeginMdx.h" +#include "../../XlsbFormat/Biff12_records/BeginMdxKpi.h" +#include "../../XlsbFormat/Biff12_records/BeginMdxMbrProp.h" +#include "../../XlsbFormat/Biff12_records/BeginMdxSet.h" +#include "../../XlsbFormat/Biff12_records/BeginMdxTuple.h" +#include "../../XlsbFormat/Biff12_records/MdxMbrIstr.h" + +#include "../FileTypes_Spreadsheet.h" + +#include "../../Common/SimpleTypes_Shared.h" +#include "../../Common/SimpleTypes_Spreadsheet.h" + +#include "../../DocxFormat/Drawing/DrawingExt.h" +#include "../../../DesktopEditor/common/File.h" + +#include "../../Binary/Presentation/XmlWriter.h" +#include "../../Binary/Presentation/BinaryFileReaderWriter.h" + +#include "../../Binary/XlsbFormat/FileTypes_SpreadsheetBin.h" + +namespace OOX +{ + namespace Spreadsheet + { + CMdxKPI::CMdxKPI() {} + CMdxKPI::~CMdxKPI() {} + void CMdxKPI::fromXML(XmlUtils::CXmlNode& node) + { + } + std::wstring CMdxKPI::toXML() const + { + return L""; + } + EElementType CMdxKPI::getType() const + { + return et_x_MdxKPI; + } + void CMdxKPI::toXML(NSStringUtils::CStringBuilder& writer) const + { + writer.WriteString(L"ToString()); + writer.WriteString(L"/>"); + } + void CMdxKPI::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + + if (oReader.IsEmptyNode()) + return; + } + void CMdxKPI::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_Start(oReader) + WritingElement_ReadAttributes_Read_if(oReader, L"n", m_oN) + WritingElement_ReadAttributes_Read_else_if(oReader, L"np", m_oNp) + WritingElement_ReadAttributes_Read_else_if(oReader, L"p", m_oP) + WritingElement_ReadAttributes_End(oReader) + } + XLS::BaseObjectPtr CMdxKPI::toBin() const + { + auto ptr(new XLSB::MDXKPI); + XLS::BaseObjectPtr objectPtr(ptr); + auto ptr1(new XLSB::BeginMdxKpi); + ptr->m_BrtBeginMdxKpi = XLS::BaseObjectPtr{ptr1}; + ptr1->istrKPIName = 0; + ptr1->istrMbrKPI = 0; + ptr1->kpiprop = XLSB::KPIProp::KPIPROPVALUE; + if(m_oN.IsInit()) + ptr1->istrKPIName = m_oN.get(); + if(m_oNp.IsInit()) + ptr1->istrMbrKPI = m_oNp.get(); + if(m_oP.IsInit()) + { + auto numProp = static_cast<_UINT32>(m_oP.get().GetValue()) + 1; + if(numProp > 0 && numProp <= 6) + ptr1->kpiprop = static_cast(numProp); + } + return objectPtr; + } + void CMdxKPI::fromBin(XLS::BaseObjectPtr& obj) + { + auto ptr = static_cast(obj.get()); + if(ptr->m_BrtBeginMdxKpi == nullptr) + return; + auto beginPtr = static_cast(ptr->m_BrtBeginMdxKpi.get()); + m_oN = beginPtr->istrKPIName; + m_oNp = beginPtr->istrMbrKPI; + auto numProp = static_cast<_INT32>(beginPtr->kpiprop) - 1; + m_oP.Init(); + m_oP->SetValueFromByte(numProp); + } + //-------------------------------------------------------------------------------------------------------- + CMdxMemeberProp::CMdxMemeberProp() {} + CMdxMemeberProp::~CMdxMemeberProp() {} + void CMdxMemeberProp::fromXML(XmlUtils::CXmlNode& node) + { + } + std::wstring CMdxMemeberProp::toXML() const + { + return L""; + } + EElementType CMdxMemeberProp::getType() const + { + return et_x_MdxMemeberProp; + } + void CMdxMemeberProp::toXML(NSStringUtils::CStringBuilder& writer) const + { + writer.WriteString(L""); + } + void CMdxMemeberProp::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + + if (oReader.IsEmptyNode()) + return; + } + void CMdxMemeberProp::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_Start(oReader) + WritingElement_ReadAttributes_Read_if(oReader, L"n", m_oN) + WritingElement_ReadAttributes_Read_else_if(oReader, L"np", m_oNp) + WritingElement_ReadAttributes_End(oReader) + } + XLS::BaseObjectPtr CMdxMemeberProp::toBin() const + { + auto ptr(new XLSB::MDXMBRPROP); + auto ptr1(new XLSB::BeginMdxMbrProp); + XLS::BaseObjectPtr objectPtr(ptr); + ptr->m_BrtBeginMdxMbrProp = XLS::BaseObjectPtr(ptr1); + ptr1->istrMbr = 0; + ptr1->istrProp = 0; + if(m_oN.IsInit()) + ptr1->istrMbr = m_oN.get(); + if(m_oNp.IsInit()) + ptr1->istrProp = m_oNp.get(); + return objectPtr; + } + void CMdxMemeberProp::fromBin(XLS::BaseObjectPtr& obj) + { + auto ptr = static_cast(obj.get()); + if(ptr->m_BrtBeginMdxMbrProp == nullptr) + return; + auto ptr1 = static_cast(ptr->m_BrtBeginMdxMbrProp.get()); + m_oN = ptr1->istrMbr; + m_oNp = ptr1->istrProp; + } + //-------------------------------------------------------------------------------------------------------- + CMdxSet::CMdxSet() {} + CMdxSet::~CMdxSet() {} + void CMdxSet::fromXML(XmlUtils::CXmlNode& node) + { + } + std::wstring CMdxSet::toXML() const + { + return L""; + } + EElementType CMdxSet::getType() const + { + return et_x_MdxSet; + } + void CMdxSet::toXML(NSStringUtils::CStringBuilder& writer) const + { + writer.WriteString(L""); + WritingStringNullableAttrInt2(L"ns", m_oNs); + WritingStringNullableAttrInt2(L"c", m_oC); + WritingStringNullableAttrString(L"o", m_oO, m_oO->ToString()); + writer.WriteString(L">"); + for (size_t i = 0; i < m_arrItems.size(); ++i) + { + if (m_arrItems[i]) + { + m_arrItems[i]->toXML(writer); + } + } + writer.WriteString(L""); + } + void CMdxSet::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + + if (oReader.IsEmptyNode()) + return; + + int nCurDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nCurDepth)) + { + std::wstring sName = XmlUtils::GetNameNoNS(oReader.GetName()); + + if (L"n" == sName) + { + CMetadataStringIndex* ind = new CMetadataStringIndex(); + *ind = oReader; + m_arrItems.push_back(ind); + } + } + } + void CMdxSet::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_Start(oReader) + WritingElement_ReadAttributes_Read_if(oReader, L"ns", m_oNs) + WritingElement_ReadAttributes_Read_else_if(oReader, L"c", m_oC) + WritingElement_ReadAttributes_Read_else_if(oReader, L"o", m_oO) + WritingElement_ReadAttributes_End(oReader) + } + XLS::BaseObjectPtr CMdxSet::toBin() const + { + auto ptr(new XLSB::MDXSET); + XLS::BaseObjectPtr objectPtr(ptr); + auto ptr1(new XLSB::BeginMdxSet); + ptr->m_BrtBeginMdxSet = XLS::BaseObjectPtr{ptr1}; + + ptr1->istrSetDef = 0; + ptr1->cMbrsSortBy = 0; + ptr1->sso = XLSB::SdSetSortOrderMdx::SSONONE; + + if(m_oNs.IsInit()) + ptr1->istrSetDef = m_oNs.get(); + if(m_oC.IsInit()) + ptr1->cMbrsSortBy = m_oC.get(); + if(m_oO.IsInit()) + { + auto orderNum = static_cast<_UINT32>(m_oO->GetValue()); + if(orderNum >= 0 && orderNum <=6) + ptr1->sso = static_cast(orderNum); + } + for(auto i:m_arrItems) + ptr->MdxMbrIstrs.push_back(i->toBin()); + return objectPtr; + } + void CMdxSet::fromBin(XLS::BaseObjectPtr& obj) + { + auto ptr = static_cast(obj.get()); + if(ptr->m_BrtBeginMdxSet != nullptr) + { + auto ptr1 = static_cast(ptr->m_BrtBeginMdxSet.get()); + m_oNs = ptr1->istrSetDef; + m_oC = ptr1->cMbrsSortBy; + auto orderNum = static_cast<_INT32>(ptr1->sso); + m_oO.Init(); + m_oO->SetValueFromByte(orderNum); + } + for(auto i : ptr->MdxMbrIstrs) + m_arrItems.push_back(new CMetadataStringIndex(i)); + } + //-------------------------------------------------------------------------------------------------------- + CMetadataStringIndex::CMetadataStringIndex() {} + CMetadataStringIndex::~CMetadataStringIndex() {} + void CMetadataStringIndex::fromXML(XmlUtils::CXmlNode& node) + { + } + std::wstring CMetadataStringIndex::toXML() const + { + return L""; + } + EElementType CMetadataStringIndex::getType() const + { + return et_x_MetadataStringIndex; + } + void CMetadataStringIndex::toXML(NSStringUtils::CStringBuilder& writer) const + { + writer.WriteString(L""); + } + void CMetadataStringIndex::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + + if (oReader.IsEmptyNode()) + return; + } + void CMetadataStringIndex::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_Start(oReader) + WritingElement_ReadAttributes_Read_if(oReader, L"x", m_oX) + WritingElement_ReadAttributes_Read_else_if(oReader, L"s", m_oS) + WritingElement_ReadAttributes_End(oReader) + } + XLS::BaseObjectPtr CMetadataStringIndex::toBin() const + { + auto ptr(new XLSB::MdxMbrIstr); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oX.IsInit()) + ptr->istr = m_oX.get(); + if(m_oS.IsInit()) + ptr->fCubeSet = m_oS.get(); + return objectPtr; + } + void CMetadataStringIndex::fromBin(XLS::BaseObjectPtr& obj) + { + auto ptr = static_cast(obj.get()); + m_oX = ptr->istr; + m_oS = ptr->fCubeSet; + } + //-------------------------------------------------------------------------------------------------------- + CMdxTuple::CMdxTuple() {} + CMdxTuple::~CMdxTuple() {} + void CMdxTuple::fromXML(XmlUtils::CXmlNode& node) + { + } + std::wstring CMdxTuple::toXML() const + { + return L""; + } + EElementType CMdxTuple::getType() const + { + return et_x_MdxTuple; + } + void CMdxTuple::toXML(NSStringUtils::CStringBuilder& writer) const + { + writer.WriteString(L""); + WritingStringNullableAttrInt2(L"c", m_oC); + WritingStringNullableAttrEncodeXmlString2(L"o", m_oCt); + WritingStringNullableAttrInt2(L"si", m_oSi); + WritingStringNullableAttrInt2(L"fi", m_oFi); + WritingStringNullableAttrInt2(L"bc", m_oBc); + WritingStringNullableAttrInt2(L"fc", m_oFc); + WritingStringNullableAttrBool2(L"i", m_oI); + WritingStringNullableAttrBool2(L"u", m_oU); + WritingStringNullableAttrBool2(L"st", m_oSt); + WritingStringNullableAttrBool2(L"b", m_oB); + writer.WriteString(L">"); + for (size_t i = 0; i < m_arrItems.size(); ++i) + { + if (m_arrItems[i]) + { + m_arrItems[i]->toXML(writer); + } + } + writer.WriteString(L""); + } + void CMdxTuple::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + + if (oReader.IsEmptyNode()) + return; + + int nCurDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nCurDepth)) + { + std::wstring sName = XmlUtils::GetNameNoNS(oReader.GetName()); + + if (L"n" == sName) + { + CMetadataStringIndex* ind = new CMetadataStringIndex(); + *ind = oReader; + m_arrItems.push_back(ind); + } + } + } + void CMdxTuple::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_Start(oReader) + WritingElement_ReadAttributes_Read_if(oReader, L"c", m_oC) + WritingElement_ReadAttributes_Read_else_if(oReader, L"ct", m_oCt) + WritingElement_ReadAttributes_Read_else_if(oReader, L"si", m_oSi) + WritingElement_ReadAttributes_Read_else_if(oReader, L"fi", m_oFi) + WritingElement_ReadAttributes_Read_else_if(oReader, L"bc", m_oBc) + WritingElement_ReadAttributes_Read_else_if(oReader, L"fc", m_oFc) + WritingElement_ReadAttributes_Read_else_if(oReader, L"i", m_oI) + WritingElement_ReadAttributes_Read_else_if(oReader, L"u", m_oU) + WritingElement_ReadAttributes_Read_else_if(oReader, L"st", m_oSt) + WritingElement_ReadAttributes_Read_else_if(oReader, L"b", m_oB) + WritingElement_ReadAttributes_End(oReader) + } + XLS::BaseObjectPtr CMdxTuple::toBin() const + { + auto ptr(new XLSB::MDXTUPLE); + XLS::BaseObjectPtr objectPtr(ptr); + auto ptr1(new XLSB::BeginMdxTuple); + ptr->m_BrtBeginMdxTuple = XLS::BaseObjectPtr{ptr1}; + + if(m_oC.IsInit()) + ptr1->cMbrs = m_oC.get(); + if(m_oI.IsInit()) + ptr1->fSrvFmtItalic = m_oI.get(); + if(m_oB.IsInit()) + ptr1->fSrvFmtBold = m_oB.get(); + if(m_oU.IsInit()) + ptr1->fSrvFmtUnderline = m_oU.get(); + if(m_oSt.IsInit()) + ptr1->fSrvFmtStrikethrough = m_oSt.get(); + + if(m_oBc.IsInit()) + { + ptr1->fSrvFmtBack = true; + ptr1->dwSrvFmtBack.fromHex(m_oBc.get()); + } + if(m_oFc.IsInit()) + { + ptr1->fSrvFmtFore = true; + ptr1->dwSrvFmtFore.fromHex(m_oFc.get()); + } + if(m_oCt.IsInit()) + { + ptr1->fSrvFmtNum = true; + ptr1->fSrvFmtNumCurrency = true; + ptr1->stSfnum = m_oCt.get(); + } + + for(auto i : m_arrItems) + ptr->MdxMbrIstrs.push_back(i->toBin()); + return objectPtr; + } + void CMdxTuple::fromBin(XLS::BaseObjectPtr& obj) + { + auto ptr = static_cast(obj.get()); + if(ptr->m_BrtBeginMdxTuple != nullptr) + { + auto ptr1 = static_cast(ptr->m_BrtBeginMdxTuple.get()); + m_oC = ptr1->cMbrs; + m_oI = ptr1->fSrvFmtItalic; + m_oB = ptr1->fSrvFmtBold; + m_oU = ptr1->fSrvFmtUnderline; + m_oSt = ptr1->fSrvFmtStrikethrough; + if(ptr1->fSrvFmtBack) + m_oBc = ptr1->dwSrvFmtBack.toHex(); + if(ptr1->fSrvFmtFore) + m_oFc = ptr1->dwSrvFmtFore.toHex(); + if(ptr1->fSrvFmtNum && ptr1->fSrvFmtNumCurrency) + m_oCt = ptr1->stSfnum; + } + for(auto i : ptr->MdxMbrIstrs) + m_arrItems.push_back(new CMetadataStringIndex(i)); + } + //-------------------------------------------------------------------------------------------------------- + CMdx::CMdx() {} + CMdx::~CMdx() {} + void CMdx::fromXML(XmlUtils::CXmlNode& node) + { + } + std::wstring CMdx::toXML() const + { + return L""; + } + EElementType CMdx::getType() const + { + return et_x_Mdx; + } + void CMdx::toXML(NSStringUtils::CStringBuilder& writer) const + { + writer.WriteString(L""); + WritingStringNullableAttrInt2(L"n", m_oN); + WritingStringNullableAttrString(L"f", m_oF, m_oF->ToString()); + + if (m_oMdxTuple.IsInit()) + { + m_oMdxTuple->toXML(writer); + } + if (m_oMdxSet.IsInit()) + { + m_oMdxSet->toXML(writer); + } + if (m_oCMdxKPI.IsInit()) + { + m_oCMdxKPI->toXML(writer); + } + if (m_oMdxMemeberProp.IsInit()) + { + m_oMdxMemeberProp->toXML(writer); + } + writer.WriteString(L""); + } + void CMdx::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + + if (oReader.IsEmptyNode()) + return; + int nCurDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nCurDepth)) + { + std::wstring sName = XmlUtils::GetNameNoNS(oReader.GetName()); + + if (L"t" == sName) + m_oMdxTuple = oReader; + else if (L"ms" == sName) + m_oMdxSet = oReader; + else if (L"p" == sName) + m_oMdxMemeberProp = oReader; + else if (L"k" == sName) + m_oCMdxKPI = oReader; + } + } + void CMdx::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_Start(oReader) + WritingElement_ReadAttributes_Read_if(oReader, L"n", m_oN) + WritingElement_ReadAttributes_Read_else_if(oReader, L"f", m_oF) + WritingElement_ReadAttributes_End(oReader) + } + XLS::BaseObjectPtr CMdx::toBin() const + { + auto ptr(new XLSB::MDX); + XLS::BaseObjectPtr objectPtr(ptr); + auto ptr1(new XLSB::BeginMdx); + ptr->m_BrtBeginMdx = XLS::BaseObjectPtr{ptr1}; + ptr1->istrConnName = 0; + ptr1->tfnSrc = XLSB::TagFnMdx::CUBEKPIMEMBER; + if(m_oN.IsInit()) + ptr1->istrConnName = m_oN.get(); + if(m_oF.IsInit()) + { + auto funcNum = static_cast<_UINT32>(m_oF.get().GetValue()) + 1; + if(funcNum > 0 && funcNum <= 7) + ptr1->tfnSrc = static_cast(funcNum); + } + if(m_oCMdxKPI.IsInit()) + { + ptr->m_MDXKPI = m_oCMdxKPI->toBin(); + } + if(m_oMdxMemeberProp.IsInit()) + { + ptr->m_MDXMBRPROP = m_oMdxMemeberProp->toBin(); + } + if(m_oMdxSet.IsInit()) + { + ptr->m_MDXSET = m_oMdxSet->toBin(); + } + if(m_oMdxTuple.IsInit()) + { + ptr->m_MDXTUPLE = m_oMdxTuple->toBin(); + } + return objectPtr; + } + void CMdx::fromBin(XLS::BaseObjectPtr& obj) + { + auto ptr = static_cast(obj.get()); + if(ptr->m_BrtBeginMdx != nullptr) + { + auto beginPtr = static_cast(ptr->m_BrtBeginMdx.get()); + m_oN = beginPtr->istrConnName; + auto numFunc = static_cast<_INT32>(beginPtr->tfnSrc) - 1; + m_oF.Init(); + m_oF->SetValueFromByte(numFunc); + } + if(ptr->m_MDXKPI != nullptr) + m_oCMdxKPI = ptr->m_MDXKPI; + + if(ptr->m_MDXMBRPROP != nullptr) + m_oMdxMemeberProp = ptr->m_MDXMBRPROP; + + if(ptr->m_MDXSET != nullptr) + m_oMdxSet = ptr->m_MDXSET; + + if(ptr->m_MDXTUPLE != nullptr) + m_oMdxTuple = ptr->m_MDXTUPLE; + } + //------------------------------------------------------------------------------------- + CMdxMetadata::CMdxMetadata() {} + CMdxMetadata::~CMdxMetadata() {} + void CMdxMetadata::fromXML(XmlUtils::CXmlNode& node) + { + } + std::wstring CMdxMetadata::toXML() const + { + return L""; + } + EElementType CMdxMetadata::getType() const + { + return et_x_MdxMetadata; + } + void CMdxMetadata::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + if (oReader.IsEmptyNode()) + return; + + int nCurDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nCurDepth)) + { + std::wstring sName = XmlUtils::GetNameNoNS(oReader.GetName()); + + if (L"mdx" == sName) + { + CMdx* mdx = new CMdx(); + *mdx = oReader; + m_arrItems.push_back(mdx); + } + } + } + void CMdxMetadata::toXML(NSStringUtils::CStringBuilder& writer) const + { + if (m_arrItems.empty()) return; + + writer.WriteString(L""); + + for (size_t i = 0; i < m_arrItems.size(); ++i) + { + if (m_arrItems[i]) + { + m_arrItems[i]->toXML(writer); + } + } + writer.WriteString(L""); + } + XLS::BaseObjectPtr CMdxMetadata::toBin() const + { + auto ptr(new XLSB::ESMDX); + XLS::BaseObjectPtr objectPtr(ptr); + for(auto i:m_arrItems) + ptr->MDXs.push_back(i->toBin()); + return objectPtr; + } + void CMdxMetadata::fromBin(XLS::BaseObjectPtr& obj) + { + auto ptr = static_cast(obj.get()); + for(auto i : ptr->MDXs) + m_arrItems.push_back(new CMdx(i)); + m_oCount = m_arrItems.size(); + } + //------------------------------------------------------------------------------------- + CMetadataStrings::CMetadataStrings() {} + CMetadataStrings::~CMetadataStrings() {} + void CMetadataStrings::fromXML(XmlUtils::CXmlNode& node) + { + } + std::wstring CMetadataStrings::toXML() const + { + return L""; + } + EElementType CMetadataStrings::getType() const + { + return et_x_MetadataStrings; + } + void CMetadataStrings::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + if (oReader.IsEmptyNode()) + return; + + int nCurDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nCurDepth)) + { + std::wstring sName = XmlUtils::GetNameNoNS(oReader.GetName()); + + if (L"s" == sName) + { + CMetadataString* pS = new CMetadataString(); + *pS = oReader; + m_arrItems.push_back(pS); + } + } + } + void CMetadataStrings::toXML(NSStringUtils::CStringBuilder& writer) const + { + if (m_arrItems.empty()) return; + + writer.WriteString(L""); + + for (size_t i = 0; i < m_arrItems.size(); ++i) + { + if (m_arrItems[i]) + { + m_arrItems[i]->toXML(writer); + } + } + writer.WriteString(L""); + } + XLS::BaseObjectPtr CMetadataStrings::toBin() const + { + auto ptr(new XLSB::ESSTR); + for(auto str:m_arrItems) + ptr->m_BrtStrs.push_back(str->toBin()); + XLS::BaseObjectPtr objectPtr(ptr); + return objectPtr; + } + void CMetadataStrings::fromBin(XLS::BaseObjectPtr& obj) + { + auto ptr = static_cast(obj.get()); + m_oCount = ptr->m_BrtStrs.size(); + for(auto i:ptr->m_BrtStrs) + m_arrItems.push_back(new CMetadataString(i)); + } + //-------------------------------------------------------------------------------------------------------- + CMetadataString::CMetadataString() {} + CMetadataString::~CMetadataString() {} + void CMetadataString::fromXML(XmlUtils::CXmlNode& node) + { + } + std::wstring CMetadataString::toXML() const + { + return L""; + } + EElementType CMetadataString::getType() const + { + return et_x_MetadataString; + } + XLS::BaseObjectPtr CMetadataString::toBin() const + { + auto ptr(new XLSB::Str); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oV.IsInit()) + ptr->stText = m_oV.get(); + else + ptr->stText = L""; + return objectPtr; + } + void CMetadataString::fromBin(XLS::BaseObjectPtr& obj) + { + if(obj == nullptr) + return; + auto ptr = static_cast(obj.get()); + m_oV = ptr->stText; + } + void CMetadataString::toXML(NSStringUtils::CStringBuilder& writer) const + { + writer.WriteString(L""); + } + void CMetadataString::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + + if (oReader.IsEmptyNode()) + return; + } + void CMetadataString::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_Start(oReader) + WritingElement_ReadAttributes_Read_if(oReader, L"v", m_oV) + WritingElement_ReadAttributes_End(oReader) + } + // -------------------------------------------------------------------------------------------------------- + CMetadataRecord::CMetadataRecord() {} + CMetadataRecord::~CMetadataRecord() {} + void CMetadataRecord::fromXML(XmlUtils::CXmlNode& node) + { + } + std::wstring CMetadataRecord::toXML() const + { + return L""; + } + EElementType CMetadataRecord::getType() const + { + return et_x_MetadataRecord; + } + void CMetadataRecord::toXML(NSStringUtils::CStringBuilder& writer) const + { + writer.WriteString(L""); + } + void CMetadataRecord::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + + if (oReader.IsEmptyNode()) + return; + } + void CMetadataRecord::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_Start(oReader) + WritingElement_ReadAttributes_Read_if(oReader, L"t", m_oT) + WritingElement_ReadAttributes_Read_else_if(oReader, L"v", m_oV) + WritingElement_ReadAttributes_End(oReader) + } + //------------------------------------------------------------------------------------- + CMetadataBlock::CMetadataBlock() {} + CMetadataBlock::~CMetadataBlock() {} + void CMetadataBlock::fromXML(XmlUtils::CXmlNode& node) + { + } + std::wstring CMetadataBlock::toXML() const + { + return L""; + } + EElementType CMetadataBlock::getType() const + { + return et_x_MetadataBlock; + } + void CMetadataBlock::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + if (oReader.IsEmptyNode()) + return; + + int nCurDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nCurDepth)) + { + std::wstring sName = XmlUtils::GetNameNoNS(oReader.GetName()); + + if (L"rc" == sName) + { + CMetadataRecord* pR = new CMetadataRecord(); + *pR = oReader; + m_arrItems.push_back(pR); + } + } + } + void CMetadataBlock::toXML(NSStringUtils::CStringBuilder& writer) const + { + if (m_arrItems.empty()) return; + + writer.WriteString(L""); + + for (size_t i = 0; i < m_arrItems.size(); ++i) + { + if (m_arrItems[i]) + { + m_arrItems[i]->toXML(writer); + } + } + writer.WriteString(L""); + } + XLS::BaseObjectPtr CMetadataBlock::toBin() const + { + auto ptr(new XLSB::Mdb); + XLS::BaseObjectPtr objectPtr(ptr); + ptr->cMdir = m_arrItems.size(); + for(auto item : m_arrItems) + { + XLSB::Mdir dir; + if(item->m_oT.IsInit()) + dir.imdt = item->m_oT.get(); + else + dir.imdt = 0; + if(item->m_oV.IsInit()) + dir.mdd = item->m_oV.get(); + else + dir.mdd = 0; + ptr->rgMdir.push_back(dir); + } + return objectPtr; + } + void CMetadataBlock::fromBin(XLS::BaseObjectPtr& obj) + { + auto ptr = static_cast(obj.get()); + for(auto i : ptr->rgMdir) + { + auto record(new CMetadataRecord); + record->m_oT = i.imdt; + record->m_oV = i.mdd; + m_arrItems.push_back(record); + } + } + //------------------------------------------------------------------------------------- + CMetadataBlocks::CMetadataBlocks() {} + CMetadataBlocks::~CMetadataBlocks() {} + void CMetadataBlocks::fromXML(XmlUtils::CXmlNode& node) + { + } + std::wstring CMetadataBlocks::toXML() const + { + return L""; + } + EElementType CMetadataBlocks::getType() const + { + return et_x_MetadataBlocks; + } + void CMetadataBlocks::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + m_sName = XmlUtils::GetNameNoNS(oReader.GetName()); + + if (oReader.IsEmptyNode()) + return; + + int nCurDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nCurDepth)) + { + std::wstring sName = XmlUtils::GetNameNoNS(oReader.GetName()); + + if (L"bk" == sName) + { + CMetadataBlock* pB = new CMetadataBlock(); + *pB = oReader; + m_arrItems.push_back(pB); + } + } + } + void CMetadataBlocks::toXML(NSStringUtils::CStringBuilder& writer) const + { + if (m_arrItems.empty()) return; + + writer.WriteString(L"<" + m_sName + L" count=\"" + std::to_wstring(m_arrItems.size()) + L"\">"); + + for (size_t i = 0; i < m_arrItems.size(); ++i) + { + if (m_arrItems[i]) + { + m_arrItems[i]->toXML(writer); + } + } + writer.WriteString(L""); + } + XLS::BaseObjectPtr CMetadataBlocks::toBin(const bool cellMeta) const + { + auto ptr(new XLSB::ESMDB); + XLS::BaseObjectPtr objectPtr(ptr); + auto ptr1(new XLSB::BeginEsmdb); + ptr->m_BrtBeginEsmdb = XLS::BaseObjectPtr(ptr1); + ptr1->fCellMeta = cellMeta; + + for(auto i:m_arrItems) + ptr->m_BrtMdbs.push_back(i->toBin()); + ptr1->CMdb = ptr->m_BrtMdbs.size(); + + return objectPtr; + } + void CMetadataBlocks::fromBin(XLS::BaseObjectPtr& obj) + { + auto ptr = static_cast(obj.get()); + m_oCount = ptr->m_BrtMdbs.size(); + for(auto i: ptr->m_BrtMdbs) + m_arrItems.push_back(new CMetadataBlock(i)); + } + //------------------------------------------------------------------------------------- + CMetadataTypes::CMetadataTypes() {} + CMetadataTypes::~CMetadataTypes() {} + void CMetadataTypes::fromXML(XmlUtils::CXmlNode& node) + { + } + std::wstring CMetadataTypes::toXML() const + { + return L""; + } + EElementType CMetadataTypes::getType() const + { + return et_x_MetadataTypes; + } + void CMetadataTypes::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + if (oReader.IsEmptyNode()) + return; + + int nCurDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nCurDepth)) + { + std::wstring sName = XmlUtils::GetNameNoNS(oReader.GetName()); + + if (L"metadataType" == sName) + { + CMetadataType* pT = new CMetadataType(); + *pT = oReader; + m_arrItems.push_back(pT); + } + } + } + void CMetadataTypes::toXML(NSStringUtils::CStringBuilder& writer) const + { + if (m_arrItems.empty()) return; + + writer.WriteString(L""); + + for (size_t i = 0; i < m_arrItems.size(); ++i) + { + if (m_arrItems[i]) + { + m_arrItems[i]->toXML(writer); + } + } + writer.WriteString(L""); + } + XLS::BaseObjectPtr CMetadataTypes::toBin() const + { + auto ptr(new XLSB::ESMDTINFO); + XLS::BaseObjectPtr objectPtr(ptr); + for(auto i :m_arrItems) + { + ptr->BrtMdtinfos.push_back(i->toBin()); + } + return objectPtr; + } + void CMetadataTypes::fromBin(XLS::BaseObjectPtr& obj) + { + auto ptr = static_cast(obj.get()); + m_oCount = ptr->BrtMdtinfos.size(); + + for(auto i : ptr->BrtMdtinfos) + { + m_arrItems.push_back(new CMetadataType(i)); + } + } + //-------------------------------------------------------------------------------------------------------- + CMetadataType::CMetadataType() {} + CMetadataType::~CMetadataType() {} + void CMetadataType::fromXML(XmlUtils::CXmlNode& node) + { + } + std::wstring CMetadataType::toXML() const + { + return L""; + } + EElementType CMetadataType::getType() const + { + return et_x_MetadataType; + } + void CMetadataType::toXML(NSStringUtils::CStringBuilder& writer) const + { + writer.WriteString(L""); + } + void CMetadataType::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + + if (oReader.IsEmptyNode()) + return; + } + void CMetadataType::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_Start(oReader) + WritingElement_ReadAttributes_Read_if(oReader, L"name", m_oName) + WritingElement_ReadAttributes_Read_else_if(oReader, L"minSupportedVersion", m_oMinSupportedVersion) + WritingElement_ReadAttributes_Read_else_if(oReader, L"ghostRow", m_oGhostRow) + WritingElement_ReadAttributes_Read_else_if(oReader, L"ghostCol", m_oGhostCol) + WritingElement_ReadAttributes_Read_else_if(oReader, L"edit", m_oEdit) + WritingElement_ReadAttributes_Read_else_if(oReader, L"delete", m_oDelete) + WritingElement_ReadAttributes_Read_else_if(oReader, L"copy", m_oCopy) + WritingElement_ReadAttributes_Read_else_if(oReader, L"pasteAll", m_oPasteAll) + WritingElement_ReadAttributes_Read_else_if(oReader, L"pasteFormulas", m_oPasteFormulas) + WritingElement_ReadAttributes_Read_else_if(oReader, L"pasteValues", m_oPasteValues) + WritingElement_ReadAttributes_Read_else_if(oReader, L"pasteFormats", m_oPasteFormats) + WritingElement_ReadAttributes_Read_else_if(oReader, L"pasteComments", m_oPasteComments) + WritingElement_ReadAttributes_Read_else_if(oReader, L"pasteDataValidation", m_oPasteDataValidation) + WritingElement_ReadAttributes_Read_else_if(oReader, L"pasteBorders", m_oPasteBorders) + WritingElement_ReadAttributes_Read_else_if(oReader, L"pasteColWidths", m_oPasteColWidths) + WritingElement_ReadAttributes_Read_else_if(oReader, L"pasteNumberFormats", m_oPasteNumberFormats) + WritingElement_ReadAttributes_Read_else_if(oReader, L"merge", m_oMerge) + WritingElement_ReadAttributes_Read_else_if(oReader, L"splitFirst", m_oSplitFirst) + WritingElement_ReadAttributes_Read_else_if(oReader, L"splitAll", m_oSplitAll) + WritingElement_ReadAttributes_Read_else_if(oReader, L"rowColShift", m_oRowColShift) + WritingElement_ReadAttributes_Read_else_if(oReader, L"clearAll", m_oClearAll) + WritingElement_ReadAttributes_Read_else_if(oReader, L"clearFormats", m_oClearFormats) + WritingElement_ReadAttributes_Read_else_if(oReader, L"clearContents", m_oClearContents) + WritingElement_ReadAttributes_Read_else_if(oReader, L"clearComments", m_oClearComments) + WritingElement_ReadAttributes_Read_else_if(oReader, L"assign", m_oAssign) + WritingElement_ReadAttributes_Read_else_if(oReader, L"coerce", m_oCoerce) + WritingElement_ReadAttributes_Read_else_if(oReader, L"cellMeta", m_oCellMeta) + WritingElement_ReadAttributes_End(oReader) + } + XLS::BaseObjectPtr CMetadataType::toBin() const + { + auto ptr(new XLSB::Mdtinfo); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oMinSupportedVersion.IsInit()) + ptr->metadataID = m_oMinSupportedVersion.get(); + else + ptr->metadataID = 0; + if(m_oName.IsInit()) + ptr->stName = m_oName.get(); + else + ptr->stName = L""; + + if(m_oGhostRow.IsInit()) + ptr->fGhostRw = m_oGhostRow.get(); + if(m_oGhostCol.IsInit()) + ptr->fGhostCol = m_oGhostCol.get(); + if(m_oEdit.IsInit()) + ptr->fEdit = m_oEdit.get(); + if(m_oDelete.IsInit()) + ptr->fDelete = m_oDelete.get(); + if(m_oCopy.IsInit()) + ptr->fCopy = m_oCopy.get(); + if(m_oPasteAll.IsInit()) + ptr->fPasteAll = m_oPasteAll.get(); + if(m_oPasteFormulas.IsInit()) + ptr->fPasteFmlas = m_oPasteFormulas.get(); + if(m_oPasteValues.IsInit()) + ptr->fPasteValues = m_oPasteValues.get(); + if(m_oPasteFormats.IsInit()) + ptr->fPasteFmts = m_oPasteFormats.get(); + if(m_oPasteComments.IsInit()) + ptr->fPasteComments = m_oPasteComments.get(); + if(m_oPasteDataValidation.IsInit()) + ptr->fPasteDv = m_oPasteDataValidation.get(); + if(m_oPasteBorders.IsInit()) + ptr->fPasteBorders = m_oPasteBorders.get(); + if(m_oPasteColWidths.IsInit()) + ptr->fPasteColWidths = m_oPasteColWidths.get(); + if(m_oPasteNumberFormats.IsInit()) + ptr->fPasteNumFmts = m_oPasteNumberFormats.get(); + if(m_oMerge.IsInit()) + ptr->fMerge = m_oMerge.get(); + if(m_oSplitFirst.IsInit()) + ptr->fSplitFirst = m_oSplitFirst.get(); + if(m_oSplitAll.IsInit()) + ptr->fSplitAll = m_oSplitAll.get(); + if(m_oRowColShift.IsInit()) + ptr->fRwColShift = m_oRowColShift.get(); + if(m_oClearAll.IsInit()) + ptr->fClearAll = m_oClearAll.get(); + if(m_oClearFormats.IsInit()) + ptr->fClearFmts = m_oClearFormats.get(); + if(m_oClearContents.IsInit()) + ptr->fClearContents = m_oClearContents.get(); + if(m_oClearComments.IsInit()) + ptr->fClearComments = m_oClearComments.get(); + if(m_oAssign.IsInit()) + ptr->fAssign = m_oAssign.get(); + if(m_oCoerce.IsInit()) + ptr->fCanCoerce = m_oCoerce.get(); + if(m_oCellMeta.IsInit()) + ptr->fCellMeta = m_oCellMeta.get(); + return objectPtr; + } + void CMetadataType::fromBin(XLS::BaseObjectPtr& obj) + { + auto ptr = static_cast(obj.get()); + m_oName = ptr->stName; + m_oMinSupportedVersion = ptr->metadataID; + m_oGhostRow = ptr->fGhostRw; + m_oGhostCol = ptr->fGhostCol; + m_oEdit = ptr->fEdit; + m_oDelete = ptr->fDelete; + m_oCopy = ptr->fCopy; + m_oPasteAll = ptr->fPasteAll; + m_oPasteFormulas = ptr->fPasteFmlas; + m_oPasteValues = ptr->fPasteValues; + m_oPasteFormats = ptr->fPasteFmts; + m_oPasteComments = ptr->fPasteComments; + m_oPasteDataValidation = ptr->fPasteDv; + m_oPasteBorders = ptr->fPasteBorders; + m_oPasteColWidths = ptr->fPasteColWidths; + m_oPasteNumberFormats = ptr->fPasteNumFmts; + m_oMerge = ptr->fMerge; + m_oSplitFirst = ptr->fSplitFirst; + m_oSplitAll = ptr->fSplitAll; + m_oRowColShift = ptr->fRwColShift; + m_oClearAll = ptr->fClearAll; + m_oClearFormats = ptr->fClearFmts; + m_oClearContents = ptr->fClearContents; + m_oClearComments = ptr->fClearComments; + m_oAssign = ptr->fAssign; + m_oCoerce = ptr->fCanCoerce; + m_oCellMeta = ptr->fCellMeta; + } + //-------------------------------------------------------------------------------------------------------- + CFutureMetadataBlock::CFutureMetadataBlock() {} + CFutureMetadataBlock::~CFutureMetadataBlock() {} + void CFutureMetadataBlock::fromXML(XmlUtils::CXmlNode& node) + { + } + std::wstring CFutureMetadataBlock::toXML() const + { + return L""; + } + EElementType CFutureMetadataBlock::getType() const + { + return et_x_FutureMetadataBlock; + } + void CFutureMetadataBlock::toXML(NSStringUtils::CStringBuilder& writer) const + { + writer.WriteString(L""); + + if (m_oExtLst.IsInit()) + { + writer.WriteString(m_oExtLst->toXMLWithNS(L"")); + } + writer.WriteString(L""); + } + void CFutureMetadataBlock::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + if (oReader.IsEmptyNode()) + return; + + int nCurDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nCurDepth)) + { + std::wstring sName = XmlUtils::GetNameNoNS(oReader.GetName()); + + if (L"extLst" == sName) + m_oExtLst = oReader; + } + } + XLS::BaseObjectPtr CFutureMetadataBlock::toBin() const + { + return m_oExtLst->toBinMetadata(); + } + void CFutureMetadataBlock::fromBin(XLS::BaseObjectPtr& obj) + { + m_oExtLst = OOX::Drawing::COfficeArtExtensionList(); + m_oExtLst->fromBin(obj); + } + //------------------------------------------------------------------------------------- + CFutureMetadata::CFutureMetadata() {} + CFutureMetadata::~CFutureMetadata() + { + } + void CFutureMetadata::fromXML(XmlUtils::CXmlNode& node) + { + } + std::wstring CFutureMetadata::toXML() const + { + return L""; + } + EElementType CFutureMetadata::getType() const + { + return et_x_FutureMetadata; + } + void CFutureMetadata::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + + if (oReader.IsEmptyNode()) + return; + + int nCurDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nCurDepth)) + { + std::wstring sName = XmlUtils::GetNameNoNS(oReader.GetName()); + + if (L"bk" == sName) + { + CFutureMetadataBlock* pT = new CFutureMetadataBlock(); + *pT = oReader; + m_arrItems.push_back(pT); + } + } + } + void CFutureMetadata::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_Start(oReader) + WritingElement_ReadAttributes_Read_if(oReader, L"name", m_oName) + WritingElement_ReadAttributes_End(oReader) + } + void CFutureMetadata::toXML(NSStringUtils::CStringBuilder& writer) const + { + if (m_arrItems.empty()) return; + + writer.WriteString(L""); + + for (size_t i = 0; i < m_arrItems.size(); ++i) + { + if (m_arrItems[i]) + { + m_arrItems[i]->toXML(writer); + } + } + writer.WriteString(L""); + } + XLS::BaseObjectPtr CFutureMetadata::toBin() const + { + auto ptr(new XLSB::ESFMD); + XLS::BaseObjectPtr objectPtr(ptr); + auto ptr1(new XLSB::BeginEsfmd); + ptr->m_BrtBeginEsfmd = XLS::BaseObjectPtr(ptr1); + if(m_oName.IsInit()) + ptr1->stName = m_oName.get(); + else + ptr1->stName = L""; + for(auto i:m_arrItems) + { + auto fmd = i->toBin(); + if(fmd) + ptr->FMDs.push_back(fmd); + } + ptr1->cFmd = ptr->FMDs.size(); + return objectPtr; + } + void CFutureMetadata::fromBin(XLS::BaseObjectPtr& obj) + { + auto ptr = static_cast(obj.get()); + if(ptr->m_BrtBeginEsfmd != nullptr) + { + auto beginPtr = static_cast(ptr->m_BrtBeginEsfmd.get()); + m_oName = beginPtr->stName; + } + for(auto i : ptr->FMDs) + { + m_arrItems.push_back(new CFutureMetadataBlock(i)); + } + m_oCount = m_arrItems.size(); + } + //-------------------------------------------------------------------------------------------------------- + CMetadata::CMetadata() {} + CMetadata::~CMetadata() + { + for (size_t i = 0; i < m_arFutureMetadata.size(); ++i) + { + if (m_arFutureMetadata[i]) delete m_arFutureMetadata[i]; + } + m_arFutureMetadata.clear(); + } + void CMetadata::fromXML(XmlUtils::CXmlNode& node) + { + } + std::wstring CMetadata::toXML() const + { + return L""; + } + EElementType CMetadata::getType() const + { + return et_x_Metadata; + } + void CMetadata::fromBin(XLS::BaseObjectPtr& obj) + { + auto streamPtr = static_cast(obj.get()); + if(streamPtr->m_ESSTR != nullptr) + m_oMetadataStrings = streamPtr->m_ESSTR; + if(streamPtr->m_ESMDTINFO != nullptr) + m_oMetadataTypes = streamPtr->m_ESMDTINFO; + if(streamPtr->m_ValueMetadataBlocks != nullptr) + m_oValueMetadata = streamPtr->m_ValueMetadataBlocks; + if(streamPtr->m_CellMetadataBlocks != nullptr) + m_oCellMetadata = streamPtr->m_CellMetadataBlocks; + if(streamPtr->m_ESMDX != nullptr) + m_oMdxMetadata = streamPtr->m_ESMDX; + for(auto i : streamPtr->m_ESFMDs) + m_arFutureMetadata.push_back(new CFutureMetadata(i)); + } + XLS::BaseObjectPtr CMetadata::toBin() const + { + XLSB::MetadataStreamPtr streamPtr(new XLSB::MetadataStream); + + if(m_oMetadataStrings.IsInit()) + streamPtr->m_ESSTR = m_oMetadataStrings->toBin(); + if(m_oMetadataTypes.IsInit()) + streamPtr->m_ESMDTINFO = m_oMetadataTypes->toBin(); + if(m_oCellMetadata.IsInit()) + streamPtr->m_CellMetadataBlocks = m_oCellMetadata->toBin(true); + if(m_oValueMetadata.IsInit()) + streamPtr->m_ValueMetadataBlocks = m_oValueMetadata->toBin(false); + for(auto i : m_arFutureMetadata) + { + streamPtr->m_ESFMDs.push_back(i->toBin()); + } + if(m_oMdxMetadata.IsInit()) + streamPtr->m_ESMDX = m_oMdxMetadata->toBin(); + return streamPtr; + } + void CMetadata::toXML(NSStringUtils::CStringBuilder& writer) const + { + writer.WriteString(L""); + + if (m_oMetadataTypes.IsInit()) + { + m_oMetadataTypes->toXML(writer); + } + if (m_oMetadataStrings.IsInit()) + { + m_oMetadataStrings->toXML(writer); + } + if (m_oMdxMetadata.IsInit()) + { + m_oMdxMetadata->toXML(writer); + } + for (size_t i = 0; i < m_arFutureMetadata.size(); ++i) + { + if (m_arFutureMetadata[i]) + { + m_arFutureMetadata[i]->toXML(writer); + } + } + if (m_oCellMetadata.IsInit()) + { + m_oCellMetadata->m_sName = L"cellMetadata"; + m_oCellMetadata->toXML(writer); + } + if (m_oValueMetadata.IsInit()) + { + m_oValueMetadata->m_sName = L"valueMetadata"; + m_oValueMetadata->toXML(writer); + } + if (m_oExtLst.IsInit()) + { + writer.WriteString(m_oExtLst->toXMLWithNS(L"")); + } + writer.WriteString(L""); + } + void CMetadata::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + if (oReader.IsEmptyNode()) + return; + + int nCurDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nCurDepth)) + { + std::wstring sName = XmlUtils::GetNameNoNS(oReader.GetName()); + + if (L"metadataTypes" == sName) + m_oMetadataTypes = oReader; + else if (L"metadataStrings" == sName) + m_oMetadataStrings = oReader; + else if (L"mdxMetadata" == sName) + m_oMdxMetadata = oReader; + else if (L"cellMetadata" == sName) + m_oCellMetadata = oReader; + else if (L"valueMetadata" == sName) + m_oValueMetadata = oReader; + else if (L"futureMetadata" == sName) + { + CFutureMetadata* pF = new CFutureMetadata(); + *pF = oReader; + m_arFutureMetadata.push_back(pF); + } + else if (L"extLst" == sName) + m_oExtLst = oReader; + } + } + //----------------------------------------------------------------------------------------------------------------------------------------------------- + CMetadataFile::CMetadataFile(OOX::Document* pMain) : OOX::File(pMain) + { + } + CMetadataFile::CMetadataFile(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath) : OOX::File(pMain) + { + read(oRootPath, oPath); + } + CMetadataFile::~CMetadataFile() + { + } + void CMetadataFile::read(const CPath& oPath) + { + //don't use this. use read(const CPath& oRootPath, const CPath& oFilePath) + CPath oRootPath; + read(oRootPath, oPath); + } + const OOX::FileType CMetadataFile::type() const + { + CXlsb* xlsb = dynamic_cast(File::m_pMainDocument); + if ((xlsb) && (xlsb->m_bWriteToXlsb)) + { + return OOX::SpreadsheetBin::FileTypes::MetadataBin; + } + return OOX::Spreadsheet::FileTypes::Metadata; + } + const CPath CMetadataFile::DefaultDirectory() const + { + return type().DefaultDirectory(); + } + const CPath CMetadataFile::DefaultFileName() const + { + CXlsb* xlsb = dynamic_cast(File::m_pMainDocument); + if ((xlsb) && (xlsb->m_bWriteToXlsb)) + { + CPath name = type().DefaultFileName(); + name.SetExtention(L"bin"); + return name; + } + else + { + return type().DefaultFileName(); + } + } + const CPath& CMetadataFile::GetReadPath() + { + return m_oReadPath; + } + void CMetadataFile::read(const CPath& oRootPath, const CPath& oPath) + { + m_oReadPath = oPath; + + if (m_oReadPath.GetExtention() == _T(".bin")) + { + readBin(m_oReadPath); + } + else + { + XmlUtils::CXmlLiteReader oReader; + + if (!oReader.FromFile(oPath.GetPath())) + return; + + if (!oReader.ReadNextNode()) + return; + + m_oMetadata = oReader; + } + } + void CMetadataFile::readBin(const CPath& oPath) + { + CXlsb* xlsb = dynamic_cast(File::m_pMainDocument); + if (xlsb) + { + XLSB::MetadataStreamPtr streamPtr(new XLSB::MetadataStream); + + xlsb->ReadBin(oPath, streamPtr.get()); + XLS::BaseObjectPtr objectPtr(streamPtr); + m_oMetadata = CMetadata(); + m_oMetadata->fromBin(objectPtr); + } + } + XLS::BaseObjectPtr CMetadataFile::WriteBin() const + { + return m_oMetadata->toBin(); + } + void CMetadataFile::write(const CPath& oPath, const CPath& oDirectory, CContentTypes& oContent) const + { + if (false == m_oMetadata.IsInit()) return; + + CXlsb* xlsb = dynamic_cast(File::m_pMainDocument); + if ((xlsb) && (xlsb->m_bWriteToXlsb)) + { + auto object = WriteBin(); + xlsb->WriteBin(oPath, object.get()); + } + else + { + NSStringUtils::CStringBuilder sXml; + + sXml.WriteString(L""); + m_oMetadata->toXML(sXml); + + std::wstring sPath = oPath.GetPath(); + NSFile::CFileBinary::SaveToFile(sPath, sXml.GetData()); + } + + oContent.Registration(type().OverrideType(), oDirectory, oPath.GetFilename()); + } +//------------------------------------------------------------------------------------------------------------------------------------- + CDynamicArrayProperties::CDynamicArrayProperties() {} + CDynamicArrayProperties::~CDynamicArrayProperties() {} + void CDynamicArrayProperties::fromXML(XmlUtils::CXmlNode& node) + { + } + std::wstring CDynamicArrayProperties::toXML() const + { + return L""; + } + EElementType CDynamicArrayProperties::getType() const + { + return et_x_DynamicArrayProperties; + } + void CDynamicArrayProperties::toXML(NSStringUtils::CStringBuilder& writer) const + { + writer.WriteString(L""); + } + void CDynamicArrayProperties::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + + if (oReader.IsEmptyNode()) + return; + } + void CDynamicArrayProperties::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_Start(oReader) + WritingElement_ReadAttributes_Read_if(oReader, L"fDynamic", m_oFDynamic) + WritingElement_ReadAttributes_Read_else_if(oReader, L"fCollapsed", m_oFCollapsed) + WritingElement_ReadAttributes_End(oReader) + } + XLS::BaseObjectPtr CDynamicArrayProperties::toBin() + { + auto ptr(new XLSB::EndDynamicArrayPr); + XLS::BaseObjectPtr objectPtr(ptr); + ptr->fDynamic = false; + ptr->fCollapsed = false; + if(m_oFDynamic.IsInit()) + ptr->fDynamic = m_oFDynamic.get(); + if(m_oFCollapsed.IsInit()) + ptr->fCollapsed = m_oFCollapsed.get(); + return objectPtr; + } + void CDynamicArrayProperties::fromBin(XLS::BaseObjectPtr& obj) + { + auto ptr = static_cast(obj.get()); + auto endPtr = static_cast(ptr->m_EndDynamicArrayPr.get()); + m_oFDynamic = endPtr->fDynamic; + m_oFCollapsed = endPtr->fCollapsed; + } +//------------------------------------------------------------------------------------------------------------------------------------- + CRichValueBlock::CRichValueBlock() {} + CRichValueBlock::~CRichValueBlock() {} + void CRichValueBlock::fromXML(XmlUtils::CXmlNode& node) + { + } + std::wstring CRichValueBlock::toXML() const + { + return L""; + } + EElementType CRichValueBlock::getType() const + { + return et_x_RichValueBlock; + } + void CRichValueBlock::toXML(NSStringUtils::CStringBuilder& writer) const + { + writer.WriteString(L""); + } + void CRichValueBlock::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + + if (oReader.IsEmptyNode()) + return; + } + void CRichValueBlock::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_Start(oReader) + WritingElement_ReadAttributes_Read_if(oReader, L"i", m_oI) + WritingElement_ReadAttributes_End(oReader) + } + XLS::BaseObjectPtr CRichValueBlock::toBin() + { + auto ptr(new XLSB::BeginRichValueBlock); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oI.IsInit()) + ptr->irv = m_oI.get(); + else + ptr->irv = 0; + return objectPtr; + } + void CRichValueBlock::fromBin(XLS::BaseObjectPtr& obj) + { + auto ptr = static_cast(obj.get()); + if(ptr->m_BeginRichValueBlock == nullptr) + return; + auto ptr1 = static_cast(ptr->m_BeginRichValueBlock.get()); + m_oI = ptr1->irv; + } + } + +} // namespace OOX + diff --git a/OOXML/XlsxFormat/Workbook/Metadata.h b/OOXML/XlsxFormat/Workbook/Metadata.h new file mode 100644 index 00000000000..ef63c0483b9 --- /dev/null +++ b/OOXML/XlsxFormat/Workbook/Metadata.h @@ -0,0 +1,559 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#pragma once + +#include "../Table/Autofilter.h" +#include "../../DocxFormat/IFileContainer.h" +#include "../../Common/SimpleTypes_Spreadsheet.h" + +namespace OOX +{ + namespace Drawing + { + class COfficeArtExtensionList; + } + + namespace Spreadsheet + { +//----------------------------------------------------------------------------------------------------------------------- + class CMdxKPI : public WritingElement + { + public: + WritingElement_XlsbConstructors(CMdxKPI) + WritingElement_AdditionMethods(CMdxKPI) + CMdxKPI(); + virtual ~CMdxKPI(); + + virtual void fromXML(XmlUtils::CXmlNode& node); + virtual std::wstring toXML() const; + + void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin() const; + virtual void toXML(NSStringUtils::CStringBuilder& writer) const; + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + + virtual EElementType getType() const; + + nullable_uint m_oN; + nullable_uint m_oNp; + nullable m_oP; + private: + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + }; +//----------------------------------------------------------------------------------------------------------------------- + class CMdxMemeberProp : public WritingElement + { + public: + WritingElement_XlsbConstructors(CMdxMemeberProp) + WritingElement_AdditionMethods(CMdxMemeberProp) + CMdxMemeberProp(); + virtual ~CMdxMemeberProp(); + + virtual void fromXML(XmlUtils::CXmlNode& node); + virtual std::wstring toXML() const; + + void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin() const; + virtual void toXML(NSStringUtils::CStringBuilder& writer) const; + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + + virtual EElementType getType() const; + + nullable_uint m_oN; + nullable_uint m_oNp; + private: + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + }; +//----------------------------------------------------------------------------------------------------------------------- + class CMetadataStringIndex : public WritingElement + { + public: + WritingElement_XlsbConstructors(CMetadataStringIndex) + WritingElement_AdditionMethods(CMetadataStringIndex) + CMetadataStringIndex(); + virtual ~CMetadataStringIndex(); + + virtual void fromXML(XmlUtils::CXmlNode& node); + virtual std::wstring toXML() const; + + void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin() const; + virtual void toXML(NSStringUtils::CStringBuilder& writer) const; + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + + virtual EElementType getType() const; + + nullable_uint m_oX; + nullable_bool m_oS; + private: + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + }; +//------------------------------------------------------------------------------------------------------------------------ + class CMdxSet : public WritingElementWithChilds + { + public: + WritingElement_XlsbConstructors(CMdxSet) + WritingElement_AdditionMethods(CMdxSet) + CMdxSet(); + virtual ~CMdxSet(); + + virtual void fromXML(XmlUtils::CXmlNode& node); + virtual std::wstring toXML() const; + + void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin() const; + virtual void toXML(NSStringUtils::CStringBuilder& writer) const; + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + + virtual EElementType getType() const; + + nullable_uint m_oNs; + nullable_uint m_oC; + nullable m_oO; + private: + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + }; +//------------------------------------------------------------------------------------------------------------------------ + class CMdxTuple : public WritingElementWithChilds + { + public: + WritingElement_XlsbConstructors(CMdxTuple) + WritingElement_AdditionMethods(CMdxTuple) + CMdxTuple(); + virtual ~CMdxTuple(); + + virtual void fromXML(XmlUtils::CXmlNode& node); + virtual std::wstring toXML() const; + + void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin() const; + virtual void toXML(NSStringUtils::CStringBuilder& writer) const; + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + + virtual EElementType getType() const; + + nullable_uint m_oC; + nullable_string m_oCt; + nullable_uint m_oSi; + nullable_uint m_oFi; + nullable_uint m_oBc; + nullable_uint m_oFc; + nullable_bool m_oI; + nullable_bool m_oU; + nullable_bool m_oSt; + nullable_bool m_oB; + private: + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + }; +//------------------------------------------------------------------------------------------------------------------------ + class CMdx : public WritingElement + { + public: + WritingElement_XlsbConstructors(CMdx) + WritingElement_AdditionMethods(CMdx) + CMdx(); + virtual ~CMdx(); + + virtual void fromXML(XmlUtils::CXmlNode& node); + virtual std::wstring toXML() const; + + void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin() const; + virtual void toXML(NSStringUtils::CStringBuilder& writer) const; + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + + virtual EElementType getType() const; + + private: + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + public: + nullable m_oMdxTuple; + nullable m_oMdxSet; + nullable m_oCMdxKPI; + nullable m_oMdxMemeberProp; + + nullable_uint m_oN; + nullable m_oF; + }; +//------------------------------------------------------------------------------------------------------------------------ + class CMdxMetadata : public WritingElementWithChilds + { + public: + WritingElement_XlsbConstructors(CMdxMetadata) + WritingElement_AdditionMethods(CMdxMetadata) + CMdxMetadata(); + virtual ~CMdxMetadata(); + + virtual void fromXML(XmlUtils::CXmlNode& node); + virtual std::wstring toXML() const; + + void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin() const; + virtual void toXML(NSStringUtils::CStringBuilder& writer) const; + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + + virtual EElementType getType() const; + + nullable_uint m_oCount; + }; +//------------------------------------------------------------------------------------------------------------------------ + class CMetadataString : public WritingElement + { + public: + WritingElement_XlsbConstructors(CMetadataString) + WritingElement_AdditionMethods(CMetadataString) + CMetadataString(); + virtual ~CMetadataString(); + + virtual void fromXML(XmlUtils::CXmlNode& node); + virtual std::wstring toXML() const; + + void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin() const; + virtual void toXML(NSStringUtils::CStringBuilder& writer) const; + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + + virtual EElementType getType() const; + + private: + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + public: + nullable_string m_oV; + }; +//------------------------------------------------------------------------------------------------------------------------ + class CMetadataRecord : public WritingElement + { + public: + WritingElement_AdditionMethods(CMetadataRecord) + CMetadataRecord(); + virtual ~CMetadataRecord(); + + virtual void fromXML(XmlUtils::CXmlNode& node); + virtual std::wstring toXML() const; + + virtual void toXML(NSStringUtils::CStringBuilder& writer) const; + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + + virtual EElementType getType() const; + + private: + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + public: + nullable_uint m_oT; + nullable_uint m_oV; + }; +//------------------------------------------------------------------------------------------------------------------------ + class CFutureMetadataBlock : public WritingElement + { + public: + WritingElement_XlsbConstructors(CFutureMetadataBlock) + WritingElement_AdditionMethods(CFutureMetadataBlock) + CFutureMetadataBlock(); + virtual ~CFutureMetadataBlock(); + + virtual void fromXML(XmlUtils::CXmlNode& node); + virtual std::wstring toXML() const; + + void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin() const; + virtual void toXML(NSStringUtils::CStringBuilder& writer) const; + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + + virtual EElementType getType() const; + + nullable m_oExtLst; + }; +//------------------------------------------------------------------------------------------------------------------------ + class CMetadataType : public WritingElement + { + public: + WritingElement_XlsbConstructors(CMetadataType) + WritingElement_AdditionMethods(CMetadataType) + CMetadataType(); + virtual ~CMetadataType(); + + virtual void fromXML(XmlUtils::CXmlNode& node); + virtual std::wstring toXML() const; + + void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin() const; + virtual void toXML(NSStringUtils::CStringBuilder& writer) const; + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + + virtual EElementType getType() const; + + private: + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + public: + nullable_string m_oName; + nullable_uint m_oMinSupportedVersion; + nullable_bool m_oGhostRow; + nullable_bool m_oGhostCol; + nullable_bool m_oEdit; + nullable_bool m_oDelete; + nullable_bool m_oCopy; + nullable_bool m_oPasteAll; + nullable_bool m_oPasteFormulas; + nullable_bool m_oPasteValues; + nullable_bool m_oPasteFormats; + nullable_bool m_oPasteComments; + nullable_bool m_oPasteDataValidation; + nullable_bool m_oPasteBorders; + nullable_bool m_oPasteColWidths; + nullable_bool m_oPasteNumberFormats; + nullable_bool m_oMerge; + nullable_bool m_oSplitFirst; + nullable_bool m_oSplitAll; + nullable_bool m_oRowColShift; + nullable_bool m_oClearAll; + nullable_bool m_oClearFormats; + nullable_bool m_oClearContents; + nullable_bool m_oClearComments; + nullable_bool m_oAssign; + nullable_bool m_oCoerce; + nullable_bool m_oCellMeta; + }; +//------------------------------------------------------------------------------------------------------------------------ + class CMetadataTypes : public WritingElementWithChilds + { + public: + WritingElement_XlsbConstructors(CMetadataTypes) + WritingElement_AdditionMethods(CMetadataTypes) + CMetadataTypes(); + virtual ~CMetadataTypes(); + + virtual void fromXML(XmlUtils::CXmlNode& node); + virtual std::wstring toXML() const; + + void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin() const; + virtual void toXML(NSStringUtils::CStringBuilder& writer) const; + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + + virtual EElementType getType() const; + + nullable_uint m_oCount; + }; +//------------------------------------------------------------------------------------------------------------------------ + class CMetadataBlock : public WritingElementWithChilds + { + public: + WritingElement_XlsbConstructors(CMetadataBlock) + WritingElement_AdditionMethods(CMetadataBlock) + CMetadataBlock(); + virtual ~CMetadataBlock(); + + virtual void fromXML(XmlUtils::CXmlNode& node); + virtual std::wstring toXML() const; + + void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin() const; + virtual void toXML(NSStringUtils::CStringBuilder& writer) const; + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + + virtual EElementType getType() const; + }; +//------------------------------------------------------------------------------------------------------------------------ + class CMetadataBlocks : public WritingElementWithChilds + { + public: + WritingElement_XlsbConstructors(CMetadataBlocks) + WritingElement_AdditionMethods(CMetadataBlocks) + CMetadataBlocks(); + virtual ~CMetadataBlocks(); + + virtual void fromXML(XmlUtils::CXmlNode& node); + virtual std::wstring toXML() const; + + void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(const bool cellMeta) const; + virtual void toXML(NSStringUtils::CStringBuilder& writer) const; + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + + virtual EElementType getType() const; + + nullable_uint m_oCount; + + std::wstring m_sName; + }; +//------------------------------------------------------------------------------------------------------------------------ + class CMetadataStrings : public WritingElementWithChilds + { + public: + WritingElement_XlsbConstructors(CMetadataStrings) + WritingElement_AdditionMethods(CMetadataStrings) + CMetadataStrings(); + virtual ~CMetadataStrings(); + + virtual void fromXML(XmlUtils::CXmlNode& node); + virtual std::wstring toXML() const; + + void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin() const; + virtual void toXML(NSStringUtils::CStringBuilder& writer) const; + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + + virtual EElementType getType() const; + + nullable_uint m_oCount; + }; +//------------------------------------------------------------------------------------------------------------------------ + class CFutureMetadata : public WritingElementWithChilds + { + public: + WritingElement_XlsbConstructors(CFutureMetadata) + WritingElement_AdditionMethods(CFutureMetadata) + CFutureMetadata(); + virtual ~CFutureMetadata(); + + virtual void fromXML(XmlUtils::CXmlNode& node); + virtual std::wstring toXML() const; + + void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin() const; + virtual void toXML(NSStringUtils::CStringBuilder& writer) const; + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + + virtual EElementType getType() const; + + nullable_string m_oName; + nullable_uint m_oCount; + + nullable m_oExtLst; + private: + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + }; +//-------------------------------------------------------------------------------------------------------------- + class CMetadata : public WritingElement + { + public: + WritingElement_AdditionMethods(CMetadata) + CMetadata(); + virtual ~CMetadata(); + + virtual void fromXML(XmlUtils::CXmlNode& node); + virtual std::wstring toXML() const; + + void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin() const; + virtual void toXML(NSStringUtils::CStringBuilder& writer) const; + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + + virtual EElementType getType() const; + + public: + nullable m_oMetadataTypes; + nullable m_oMetadataStrings; + nullable m_oMdxMetadata; + nullable m_oCellMetadata; + nullable m_oValueMetadata; + + std::vector m_arFutureMetadata; + + nullable m_oExtLst; + }; +//------------------------------------------------------------------------------------------------------------------------ + class CMetadataFile : public OOX::File + { + public: + CMetadataFile(OOX::Document* pMain); + CMetadataFile(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath); + virtual ~CMetadataFile(); + + void readBin(const CPath& oPath); + XLS::BaseObjectPtr WriteBin() const; + virtual void read(const CPath& oPath); + virtual void read(const CPath& oRootPath, const CPath& oPath); + + virtual void write(const CPath& oPath, const CPath& oDirectory, CContentTypes& oContent) const; + virtual const OOX::FileType type() const; + + virtual const CPath DefaultDirectory() const; + virtual const CPath DefaultFileName() const; + + const CPath& GetReadPath(); + + nullable m_oMetadata; + private: + CPath m_oReadPath; + }; +//----------------------------------------------------------------------------------------------------------------------- + class CDynamicArrayProperties : public WritingElement + { + public: + WritingElement_XlsbConstructors(CDynamicArrayProperties) + WritingElement_AdditionMethods(CDynamicArrayProperties) + CDynamicArrayProperties(); + virtual ~CDynamicArrayProperties(); + + virtual void fromXML(XmlUtils::CXmlNode& node); + virtual std::wstring toXML() const; + + void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); + virtual void toXML(NSStringUtils::CStringBuilder& writer) const; + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + + virtual EElementType getType() const; + + nullable_bool m_oFDynamic; + nullable_bool m_oFCollapsed; + + nullable m_oExtLst; + private: + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + }; +//----------------------------------------------------------------------------------------------------------------------- + class CRichValueBlock : public WritingElement + { + public: + WritingElement_XlsbConstructors(CRichValueBlock) + WritingElement_AdditionMethods(CRichValueBlock) + CRichValueBlock(); + virtual ~CRichValueBlock(); + + virtual void fromXML(XmlUtils::CXmlNode& node); + virtual std::wstring toXML() const; + + void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); + virtual void toXML(NSStringUtils::CStringBuilder& writer) const; + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + + virtual EElementType getType() const; + + nullable_uint m_oI; + private: + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + }; + } //Spreadsheet +} // namespace OOX diff --git a/OOXML/XlsxFormat/Workbook/Sheets.cpp b/OOXML/XlsxFormat/Workbook/Sheets.cpp index bcb06ac25e8..6ab6c8bebda 100644 --- a/OOXML/XlsxFormat/Workbook/Sheets.cpp +++ b/OOXML/XlsxFormat/Workbook/Sheets.cpp @@ -69,6 +69,35 @@ namespace OOX if ( !oReader.IsEmptyNode() ) oReader.ReadTillEnd(); } + XLS::BaseObjectPtr CSheet::toBin() + { + auto ptr(new XLSB::BundleSh); + XLS::BaseObjectPtr objectPtr(ptr); + + if(m_oRid.IsInit()) + ptr->strRelID.value = m_oRid->GetValue(); + else + ptr->strRelID.value.setSize(0xFFFFFFFF); + if(m_oName.IsInit()) + ptr->strName = m_oName.get(); + else + ptr->strName = L""; + if(m_oSheetId.IsInit()) + ptr->iTabID = m_oSheetId->GetValue(); + else + ptr->iTabID = 0; + + if(m_oState == SimpleTypes::Spreadsheet::EVisibleType::visibleVisible) + ptr->hsState = XLSB::BundleSh::ST_SheetState::VISIBLE; + else if(m_oState == SimpleTypes::Spreadsheet::EVisibleType::visibleHidden) + ptr->hsState = XLSB::BundleSh::ST_SheetState::HIDDEN; + else if(m_oState == SimpleTypes::Spreadsheet::EVisibleType::visibleVeryHidden) + ptr->hsState = XLSB::BundleSh::ST_SheetState::VERYHIDDEN; + else + ptr->hsState = XLSB::BundleSh::ST_SheetState::VISIBLE; + + return objectPtr; + } void CSheet::fromBin(XLS::BaseObjectPtr& obj) { ReadAttributes(obj); @@ -79,13 +108,12 @@ namespace OOX } void CSheet::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) { - WritingElement_ReadAttributes_Start( oReader ) - WritingElement_ReadAttributes_Read_if ( oReader, (L"r:id"), m_oRid ) - WritingElement_ReadAttributes_Read_else_if( oReader, (L"relationships:id"), m_oRid ) - WritingElement_ReadAttributes_Read_else_if( oReader, (L"name"), m_oName ) - WritingElement_ReadAttributes_Read_else_if( oReader, (L"sheetId"), m_oSheetId ) - WritingElement_ReadAttributes_Read_else_if( oReader, (L"state"), m_oState ) - WritingElement_ReadAttributes_End( oReader ) + WritingElement_ReadAttributes_Start_No_NS( oReader ) + WritingElement_ReadAttributes_Read_if ( oReader, L"id", m_oRid ) + WritingElement_ReadAttributes_Read_else_if( oReader, L"name", m_oName ) + WritingElement_ReadAttributes_Read_else_if( oReader, L"sheetId", m_oSheetId ) + WritingElement_ReadAttributes_Read_else_if( oReader, L"state", m_oState ) + WritingElement_ReadAttributes_End_No_NS( oReader ) } void CSheet::ReadAttributes(XLS::BaseObjectPtr& obj) { @@ -158,6 +186,12 @@ namespace OOX } } + auto sheetIndex = 0; + for(auto i:m_arrItems) + { if(i->m_oName.IsInit()) + AddSheetRef(i->m_oName.get(), sheetIndex); + sheetIndex++; + } } void CSheets::fromBin(std::vector& obj) { @@ -171,6 +205,13 @@ namespace OOX m_arrItems.push_back(new CSheet(sheet)); } } + std::vector CSheets::toBin() + { + std::vector objectVector; + for(auto i: m_arrItems) + objectVector.push_back(i->toBin()); + return objectVector; + } EElementType CSheets::getType () const { return et_x_Sheets; @@ -178,6 +219,16 @@ namespace OOX void CSheets::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) { } + void CSheets::AddSheetRef(const std::wstring& link, const _INT32& sheetIndex) + { + XLS::GlobalWorkbookInfo::_xti val_1; + val_1.iSup = sheetIndex; + val_1.itabFirst = sheetIndex; + val_1.itabLast = sheetIndex; + val_1.link = link; + + XLS::GlobalWorkbookInfo::arXti_External_static.push_back(val_1); + } } //Spreadsheet } // namespace OOX diff --git a/OOXML/XlsxFormat/Workbook/Sheets.h b/OOXML/XlsxFormat/Workbook/Sheets.h index 7cee9f7af05..fcb5b5af0a8 100644 --- a/OOXML/XlsxFormat/Workbook/Sheets.h +++ b/OOXML/XlsxFormat/Workbook/Sheets.h @@ -66,6 +66,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; private: @@ -95,9 +96,11 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(std::vector& obj); + std::vector toBin(); virtual EElementType getType () const; private: + void AddSheetRef(const std::wstring& link, const _INT32& sheetIndex); void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); }; diff --git a/OOXML/XlsxFormat/Workbook/Workbook.cpp b/OOXML/XlsxFormat/Workbook/Workbook.cpp index 8c6c71b1b07..38179fbd5e5 100644 --- a/OOXML/XlsxFormat/Workbook/Workbook.cpp +++ b/OOXML/XlsxFormat/Workbook/Workbook.cpp @@ -32,6 +32,9 @@ #pragma once #include "Workbook.h" +#include "../Worksheets/Worksheet.h" + +#include "../../XlsbFormat/Xlsb.h" #include "../../XlsbFormat/WorkBookStream.h" @@ -40,18 +43,29 @@ #include "../../XlsbFormat/Biff12_unions/EXTERNALS.h" #include "../../XlsbFormat/Biff12_unions/PIVOTCACHEIDS.h" #include "../../XlsbFormat/Biff12_unions/PIVOTCACHEID.h" +#include "../../XlsbFormat/Biff12_unions/SLICERCACHESPIVOTCACHEIDS.h" +#include "../../XlsbFormat/Biff12_unions/SLICERCACHESPIVOTCACHEID.h" #include "../../XlsbFormat/Biff12_records/FileVersion.h" #include "../../XlsbFormat/Biff12_records/BeginPivotCacheID.h" +#include "../../XlsbFormat/Biff12_unions/SUP.h" +#include "../../XlsbFormat/Biff12_records/SupSelf.h" +#include "../../XlsbFormat/Biff12_records/CommonRecords.h" +#include "../../XlsbFormat/Biff12_records/BundleSh.h" +#include "../../XlsbFormat/Biff12_records/BeginSlicerCachesPivotCacheID.h" +#include "../../XlsbFormat/Biff12_unions/FRTWORKBOOK.h" + #include "../../../MsBinaryFile/XlsFile/Format/Logic/GlobalWorkbookInfo.h" #include "../../Common/SimpleTypes_Shared.h" #include "../../Common/SimpleTypes_Spreadsheet.h" #include "../../DocxFormat/Drawing/DrawingExt.h" +#include "../../Binary/XlsbFormat/FileTypes_SpreadsheetBin.h" + namespace OOX { namespace Spreadsheet - { + { CWorkbookPivotCache::CWorkbookPivotCache() { } @@ -84,6 +98,47 @@ namespace OOX ReadAttributes(ptr->m_BrtBeginPivotCacheID); } } + void CWorkbookPivotCache::fromBin14(XLS::BaseObjectPtr& obj) + { + auto ptr1 = static_cast(obj.get()); + if(ptr1 == nullptr) + return; + auto ptr = static_cast(ptr1->m_BrtBeginSlicerCachesPivotCacheID.get()); + m_oRid = ptr->FRTheader.relID.relId.value(); + } + XLS::BaseObjectPtr CWorkbookPivotCache::toBin() + { + auto ptr(new XLSB::PIVOTCACHEID); + XLS::BaseObjectPtr objectPtr(ptr); + auto ptr1(new XLSB::BeginPivotCacheID); + ptr->m_BrtBeginPivotCacheID = XLS::BaseObjectPtr{ptr1}; + + if(m_oCacheId.IsInit()) + ptr1->idSx = m_oCacheId->GetValue(); + else + ptr1->idSx = 0; + if(m_oRid.IsInit()) + ptr1->irstcacheRelID.value = m_oRid->GetValue(); + else + ptr1->irstcacheRelID.value.setSize(0xFFFFFFFF); + return objectPtr; + } + XLS::BaseObjectPtr CWorkbookPivotCache::toBin14() + { + auto ptr(new XLSB::SLICERCACHESPIVOTCACHEID); + XLS::BaseObjectPtr objectPtr(ptr); + auto ptr1(new XLSB::BeginSlicerCachesPivotCacheID); + ptr->m_BrtBeginSlicerCachesPivotCacheID = XLS::BaseObjectPtr{ptr1}; + + if(m_oRid.IsInit()) + { + ptr1->FRTheader.relID.relId = m_oRid->GetValue(); + ptr1->FRTheader.fRelID = true; + } + else + ptr1->FRTheader.relID.relId.setSize(0xFFFFFFFF); + return objectPtr; + } EElementType CWorkbookPivotCache::getType() const { return et_x_WorkbookPivotCache; @@ -125,7 +180,10 @@ namespace OOX { if (m_arrItems.empty()) return; - writer.WriteString(L""); + if(!pivotCaches14) + writer.WriteString(L""); + else + writer.WriteString(L""); for (size_t i = 0; i < m_arrItems.size(); ++i) { @@ -134,20 +192,21 @@ namespace OOX m_arrItems[i]->toXML(writer); } } - - writer.WriteString(L""); + if(!pivotCaches14) + writer.WriteString(L""); + else + writer.WriteString(L""); } void CWorkbookPivotCaches::fromXML(XmlUtils::CXmlLiteReader& oReader) { if (oReader.IsEmptyNode()) return; - int nCurDepth = oReader.GetDepth(); while (oReader.ReadNextSiblingNode(nCurDepth)) { std::wstring sName = XmlUtils::GetNameNoNS(oReader.GetName()); - if (L"pivotCaches" == sName) + if (L"pivotCache" == sName) { CWorkbookPivotCache *pPivotCache = new CWorkbookPivotCache(); m_arrItems.push_back(pPivotCache); @@ -166,6 +225,40 @@ namespace OOX } } + void CWorkbookPivotCaches::fromBin14(XLS::BaseObjectPtr& obj) + { + auto ptr = static_cast(obj.get()); + if(ptr != nullptr) + { + for(auto &item : ptr->m_arSLICERCACHESPIVOTCACHEID) + { + auto bookPivotCache = new CWorkbookPivotCache; + bookPivotCache->fromBin14(item); + m_arrItems.push_back(bookPivotCache); + } + } + + } + XLS::BaseObjectPtr CWorkbookPivotCaches::toBin() + { + auto ptr(new XLSB::PIVOTCACHEIDS); + XLS::BaseObjectPtr objectPtr(ptr); + + for(auto i:m_arrItems) + ptr->m_arPIVOTCACHEID.push_back(i->toBin()); + + return objectPtr; + } + XLS::BaseObjectPtr CWorkbookPivotCaches::toBin14() + { + auto ptr(new XLSB::SLICERCACHESPIVOTCACHEIDS); + XLS::BaseObjectPtr objectPtr(ptr); + + for(auto i:m_arrItems) + ptr->m_arSLICERCACHESPIVOTCACHEID.push_back(i->toBin14()); + + return objectPtr; + } EElementType CWorkbookPivotCaches::getType() const { return et_x_WorkbookPivotCaches; @@ -237,8 +330,34 @@ namespace OOX m_oAppName = static_cast(workBookStream->m_BrtFileVersion.get())->stAppName.value(); if (workBookStream->m_FRTWORKBOOK != nullptr) + { m_oExtLst = workBookStream->m_FRTWORKBOOK; - + auto frtWorkbook = static_cast(workBookStream->m_FRTWORKBOOK.get()); + if(frtWorkbook->m_SLICERCACHESPIVOTCACHEIDS!= nullptr && m_oExtLst.IsInit()) + { + auto pivotCacheid = 0; + if(m_oPivotCaches.IsInit()) + { + for(auto i:m_oPivotCaches->m_arrItems) + { + if(i->m_oCacheId.IsInit() && i->m_oCacheId->GetValue() >= pivotCacheid) + pivotCacheid = i->m_oCacheId->GetValue() + 1; + } + } + for(auto ext : m_oExtLst->m_arrExt) + { + if(ext->m_oWorkbookPivotCaches.IsInit()) + { + for( auto cache : ext->m_oWorkbookPivotCaches->m_arrItems) + { + cache->m_oCacheId = pivotCacheid; + pivotCacheid++; + } + } + + } + } + } if (workBookStream->m_BrtFileSharingIso != nullptr) m_oFileSharing = workBookStream->m_BrtFileSharingIso; else if (workBookStream->m_BrtFileSharing != nullptr) @@ -249,6 +368,69 @@ namespace OOX } } + + XLS::BaseObjectPtr CWorkbook::WriteBin() const + { + XLSB::WorkBookStreamPtr workBookStream(new XLSB::WorkBookStream); + + if (m_oBookViews.IsInit()) + { + auto viewPtr(new XLSB::BOOKVIEWS); + viewPtr->m_arBrtBookView = m_oBookViews->toBin(); + workBookStream->m_BOOKVIEWS = XLS::BaseObjectPtr{viewPtr}; + } + if (m_oCalcPr.IsInit()) + workBookStream->m_BrtCalcProp = m_oCalcPr->toBin(); + if (m_oSheets.IsInit()) + { + auto ptr(new XLSB::BUNDLESHS); + ptr->m_arBrtBundleSh = m_oSheets->toBin(); + workBookStream->m_BUNDLESHS = XLS::BaseObjectPtr{ptr}; + } + if (m_oWorkbookPr.IsInit()) + workBookStream->m_BrtWbProp = m_oWorkbookPr->toBin(); + if (m_oPivotCaches.IsInit()) + workBookStream->m_PIVOTCACHEIDS = m_oPivotCaches->toBin(); + if (m_oDefinedNames.IsInit()) + { + workBookStream->m_arBrtName = m_oDefinedNames->toBin(); + } + else + { + workBookStream->m_arBrtName = m_oDefinedNames->AddFutureFunctions(0); + } + if (m_oWorkbookProtection.IsInit()) + workBookStream->m_BrtBookProtection = m_oWorkbookProtection->toBin(); + + workBookStream->m_EXTERNALS = WriteXtiRefs(); + if (m_oExternalReferences.IsInit()) + { + auto ptr = static_cast(workBookStream->m_EXTERNALS.get()); + auto sups = m_oExternalReferences->toBin(); + if(!sups.empty()) + ptr->m_arSUP.insert(ptr->m_arSUP.end(), sups.begin(), sups.end()); + } + + + /* + if (m_oAppName.IsInit()) + { + auto ptr(new XLSB::FileVersion); + ptr->stAppName = m_oAppName.get(); + ptr->stLastEdited = L""; + ptr->stLowestEdited = L""; + ptr->stRupBuild = L""; + workBookStream->m_BrtFileVersion = XLS::BaseObjectPtr{ptr}; + }*/ + + if (m_oExtLst.IsInit()) + workBookStream->m_FRTWORKBOOK = m_oExtLst->toBinWorkBook(); + + if (m_oFileSharing.IsInit()) + workBookStream->m_BrtFileSharing = m_oFileSharing->toBin(); + + return workBookStream; + } void CWorkbook::read(const CPath& oPath) { //don't use this. use read(const CPath& oRootPath, const CPath& oFilePath) @@ -292,15 +474,43 @@ namespace OOX IFileContainer::Read(oRootPath, oPath); //в данном случае порядок считывания важен для xlsb CXlsx* xlsx = dynamic_cast(File::m_pMainDocument); - if ((xlsx) && (xlsx->m_pVbaProject)) + if (xlsx) { - m_bMacroEnabled = true; + if (xlsx->m_pVbaProject) + { + m_bMacroEnabled = true; + } + //дубли листов + for (auto elm : this->m_mapContainer) + { + if (elm.second->type() == OOX::Spreadsheet::FileTypes::Chartsheets || elm.second->type() == OOX::Spreadsheet::FileTypes::Worksheet) + { + if (xlsx->m_mapWorksheets.end() == xlsx->m_mapWorksheets.find(elm.first)) + { + CWorksheet* sheet = dynamic_cast(elm.second.GetPointer()); + xlsx->m_arWorksheets.push_back(sheet); + xlsx->m_mapWorksheets.insert(std::make_pair(elm.first, sheet)); + } + + } + } } + } void CWorkbook::toXML(NSStringUtils::CStringBuilder& writer) const { - writer.WriteString(L""); + writer.WriteString(L""); if (m_oFileSharing.IsInit()) m_oFileSharing->toXML(writer); @@ -371,7 +581,7 @@ xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"> WritingElement_ReadAttributes_Start(oReader) WritingElement_ReadAttributes_Read_if(oReader, L"appName", m_oAppName) WritingElement_ReadAttributes_End(oReader) - } + } else if (L"WindowHeight" == sName) { } @@ -388,20 +598,33 @@ xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"> } void CWorkbook::write(const CPath& oPath, const CPath& oDirectory, CContentTypes& oContent) const { - NSStringUtils::CStringBuilder sXml; - - sXml.WriteString(L""); + CXlsb* xlsb = dynamic_cast(File::m_pMainDocument); + if ((xlsb) && (xlsb->m_bWriteToXlsb)) + { + XLS::BaseObjectPtr object = WriteBin(); + xlsb->WriteBin(oPath, object.get()); + } + else + { + NSStringUtils::CStringBuilder sXml; - toXML(sXml); + sXml.WriteString(L""); - std::wstring sPath = oPath.GetPath(); - NSFile::CFileBinary::SaveToFile(sPath.c_str(), sXml.GetData()); + toXML(sXml); + std::wstring sPath = oPath.GetPath(); + NSFile::CFileBinary::SaveToFile(sPath.c_str(), sXml.GetData()); + } oContent.Registration(type().OverrideType(), oDirectory, oPath.GetFilename()); IFileContainer::Write(oPath, oDirectory, oContent); } const OOX::FileType CWorkbook::type() const { + CXlsb* xlsb = dynamic_cast(File::m_pMainDocument); + if ((xlsb) && (xlsb->m_bWriteToXlsb)) + { + return OOX::SpreadsheetBin::FileTypes::WorkbookBin; + } if (m_bMacroEnabled) return OOX::Spreadsheet::FileTypes::WorkbookMacro; else return OOX::Spreadsheet::FileTypes::Workbook; } @@ -411,7 +634,17 @@ xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"> } const CPath CWorkbook::DefaultFileName() const { - return type().DefaultFileName(); + CXlsb* xlsb = dynamic_cast(File::m_pMainDocument); + if ((xlsb) && (xlsb->m_bWriteToXlsb)) + { + CPath name = type().DefaultFileName(); + name.SetExtention(L"bin"); + return name; + } + else + { + return type().DefaultFileName(); + } } EElementType CWorkbook::getType () const { @@ -480,6 +713,33 @@ xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"> return lActiveSheet; } + XLS::BaseObjectPtr CWorkbook::WriteXtiRefs() const + { + auto ptr(new XLSB::EXTERNALS); + + + auto externSheet(new XLSB::ExternSheet); + ptr->m_BrtExternSheet = XLS::BaseObjectPtr{externSheet}; + + for(auto i:XLS::GlobalWorkbookInfo::arXti_External_static) + { + auto sup(new XLSB::SUP); + auto supSelf(new XLSB::SupSelf); + sup->m_source = XLS::BaseObjectPtr{supSelf}; + ptr->m_arSUP.push_back(XLS::BaseObjectPtr{sup}); + + auto xti(new XLS::XTI); + xti->iSupBook = i.iSup; + xti->itabFirst = i.itabFirst; + xti->itabLast = i.itabLast; + + auto biffStructPtr = XLS::BiffStructurePtr(xti); + externSheet->rgXTI.push_back(biffStructPtr); + } + externSheet->cXTI = externSheet->rgXTI.size(); + return XLS::BaseObjectPtr{ptr}; + } + } //Spreadsheet } // namespace OOX diff --git a/OOXML/XlsxFormat/Workbook/Workbook.h b/OOXML/XlsxFormat/Workbook/Workbook.h index 59d4a11399a..7d21038013c 100644 --- a/OOXML/XlsxFormat/Workbook/Workbook.h +++ b/OOXML/XlsxFormat/Workbook/Workbook.h @@ -81,7 +81,10 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + XLS::BaseObjectPtr toBin(); + XLS::BaseObjectPtr toBin14(); void fromBin(XLS::BaseObjectPtr& obj); + void fromBin14(XLS::BaseObjectPtr& obj); virtual EElementType getType() const; void ReadAttributes(XLS::BaseObjectPtr& obj); @@ -106,8 +109,13 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + XLS::BaseObjectPtr toBin(); + XLS::BaseObjectPtr toBin14(); + void fromBin14(XLS::BaseObjectPtr& obj); void fromBin(XLS::BaseObjectPtr& obj); virtual EElementType getType() const; + + bool pivotCaches14 = false; }; //----------------------------------------------------------------------------------------------------------- @@ -120,6 +128,7 @@ namespace OOX virtual ~CWorkbook(); void readBin(const CPath& oPath); + XLS::BaseObjectPtr WriteBin() const; virtual void read(const CPath& oPath); virtual void read(const CPath& oRootPath, const CPath& oPath); virtual void fromXML(XmlUtils::CXmlNode& node); @@ -138,6 +147,7 @@ namespace OOX void PrepareToWrite(); LONG GetActiveSheetIndex(); + XLS::BaseObjectPtr WriteXtiRefs() const; CPath m_oReadPath; @@ -154,7 +164,7 @@ namespace OOX nullablem_oPivotCaches; nullable m_oPivotCachesXml; nullable m_oFileSharing; - + CPersonList* m_pPersonList; bool m_bMacroEnabled; }; diff --git a/OOXML/XlsxFormat/Workbook/WorkbookPr.cpp b/OOXML/XlsxFormat/Workbook/WorkbookPr.cpp index 658fe94eb41..0b71a56d264 100644 --- a/OOXML/XlsxFormat/Workbook/WorkbookPr.cpp +++ b/OOXML/XlsxFormat/Workbook/WorkbookPr.cpp @@ -89,6 +89,82 @@ namespace OOX if ( !oReader.IsEmptyNode() ) oReader.ReadTillEnd(); } + XLS::BaseObjectPtr CWorkbookPr::toBin() + { + auto ptr(new XLSB::WbProp); + XLS::BaseObjectPtr objectPtr(ptr); + + if(m_oAllowRefreshQuery.IsInit()) + ptr->fNoSaveSup = m_oAllowRefreshQuery->GetValue(); + else + ptr->fNoSaveSup = false; + if(m_oAutoCompressPictures.IsInit()) + ptr->fAutoCompressPictures = m_oAutoCompressPictures->GetValue(); + if(m_oBackupFile.IsInit()) + ptr->fBackup = m_oBackupFile->GetValue(); + else + ptr->fBackup = false; + if(m_oCheckCompatibility.IsInit()) + ptr->fCheckCompat = m_oCheckCompatibility->GetValue(); + else + ptr->fCheckCompat = false; + if(m_oCodeName.IsInit()) + ptr->strName.value = m_oCodeName->GetValue(); + else + ptr->strName.value = false; + if(m_oDate1904.IsInit()) + ptr->f1904 = m_oDate1904->GetValue(); + else + ptr->f1904 = false; + if(m_oDateCompatibility.IsInit()) + ptr->fNoSaveSup = m_oDateCompatibility->GetValue(); + else + ptr->fNoSaveSup = false; + if(m_oDefaultThemeVersion.IsInit()) + ptr->dwThemeVersion = m_oDefaultThemeVersion->GetValue(); + else + ptr->dwThemeVersion = 0; + if(m_oFilterPrivacy.IsInit()) + ptr->fFilterPrivacy = m_oFilterPrivacy->GetValue(); + else + ptr->fFilterPrivacy = false; + if(m_oHidePivotFieldList.IsInit()) + ptr->fHidePivotTableFList = m_oHidePivotFieldList->GetValue(); + else + ptr->fHidePivotTableFList = false; + if(m_oPromptedSolutions.IsInit()) + ptr->fBuggedUserAboutSolution = m_oPromptedSolutions->GetValue(); + else + ptr->fBuggedUserAboutSolution = false; + if(m_oPublishItems.IsInit()) + ptr->fPublishedBookItems = m_oPublishItems->GetValue(); + else + ptr->fPublishedBookItems = false; + if(m_oRefreshAllConnections.IsInit()) + ptr->fRefreshAll = m_oRefreshAllConnections->GetValue(); + else + ptr->fRefreshAll = false; + if(m_oShowBorderUnselectedTables.IsInit()) + ptr->fHideBorderUnselLists = m_oShowBorderUnselectedTables->GetValue(); + else + ptr->fHideBorderUnselLists = false; + if(m_oShowInkAnnotation.IsInit()) + ptr->fShowInkAnnotation = m_oShowInkAnnotation->GetValue(); + if(m_oShowObjects.IsInit()) + ptr->mdDspObj = m_oShowObjects->GetValue() ? 1 : 2; + else + ptr->mdDspObj = 0; + if(m_oShowPivotChartFilter.IsInit()) + ptr->fShowPivotChartFilter = m_oShowPivotChartFilter->GetValue(); + else + ptr->fShowPivotChartFilter = false; + if(m_oUpdateLinks.IsInit()) + ptr->grbitUpdateLinks = m_oUpdateLinks->GetValue(); + else + ptr->grbitUpdateLinks = 0; + + return objectPtr; + } void CWorkbookPr::fromBin(XLS::BaseObjectPtr& obj) { ReadAttributes(obj); @@ -176,6 +252,96 @@ namespace OOX if (!oReader.IsEmptyNode()) oReader.ReadTillEnd(); } + XLS::BaseObjectPtr CWorkbookProtection::toBin() + { + XLS::BaseObjectPtr objectPtr; + if(m_oWorkbookAlgorithmName.IsInit() || m_oWorkbookSpinCount.IsInit() || m_oRevisionsAlgorithmName.IsInit() || + m_oRevisionsSpinCount.IsInit()) + { + auto ptr(new XLSB::BookProtectionIso); + objectPtr = XLS::BaseObjectPtr{ptr}; + + if(m_oLockRevision.IsInit()) + ptr->wFlags.fLockRevision = m_oLockRevision->GetValue(); + else + ptr->wFlags.fLockRevision = false; + if(m_oLockStructure.IsInit()) + ptr->wFlags.fLockStructure = m_oLockStructure->GetValue(); + else + ptr->wFlags.fLockStructure = false; + if(m_oLockWindows.IsInit()) + ptr->wFlags.fLockWindow = m_oLockWindows->GetValue(); + else + ptr->wFlags.fLockWindow = false; + if(m_oWorkbookAlgorithmName.IsInit()) + ptr->ipdBookPasswordData.szAlgName = m_oWorkbookAlgorithmName->GetValue(); + else + ptr->ipdBookPasswordData.szAlgName.setSize(0xFFFFFFFF); + if(m_oWorkbookSpinCount.IsInit()) + ptr->dwBookSpinCount = m_oWorkbookSpinCount->GetValue(); + else + ptr->dwBookSpinCount = 100000; + + if(m_oWorkbookHashValue.IsInit()) + { + auto len = 0; + auto bytes = ptr->ipdBookPasswordData.rgbHash.rgbData.data(); + std::string strData = {m_oWorkbookHashValue.get().begin(), m_oWorkbookHashValue.get().end()}; + NSFile::CBase64Converter::Decode(strData.c_str(), strData.size(), + bytes, len); + ptr->ipdBookPasswordData.rgbHash.cbLength = len; + } + + if(m_oWorkbookSaltValue.IsInit()) + { + auto len1 = 0; + auto bytes1 = ptr->ipdBookPasswordData.rgbHash.rgbData.data(); + std::string strData1 = {m_oWorkbookSaltValue.get().begin(), m_oWorkbookSaltValue.get().end()}; + NSFile::CBase64Converter::Decode(strData1.c_str(), strData1.size(), + bytes1, len1); + ptr->ipdBookPasswordData.rgbSalt.cbLength = len1; + } + if(m_oRevisionsAlgorithmName.IsInit()) + ptr->ipdRevPasswordData.szAlgName = m_oRevisionsAlgorithmName->GetValue(); + else + ptr->ipdRevPasswordData.szAlgName.setSize(0xFFFFFFFF); + if(m_oRevisionsSpinCount.IsInit()) + ptr->dwRevSpinCount = m_oRevisionsSpinCount->GetValue(); + else + ptr->dwRevSpinCount = 100000; + + if(m_oRevisionsHashValue.IsInit()) + { + auto len2 = 0; + auto bytes2 = ptr->ipdRevPasswordData.rgbHash.rgbData.data(); + std::string strData2 = {m_oRevisionsHashValue.get().begin(), m_oRevisionsHashValue.get().end()}; + NSFile::CBase64Converter::Decode(strData2.c_str(), strData2.size(), + bytes2, len2); + ptr->ipdRevPasswordData.rgbHash.cbLength = len2; + } + if(m_oRevisionsSaltValue.IsInit()) + { + auto len3 = 0; + auto bytes3 = ptr->ipdRevPasswordData.rgbSalt.rgbData.data(); + std::string strData3 = {m_oRevisionsSaltValue.get().begin(), m_oRevisionsSaltValue.get().end()}; + NSFile::CBase64Converter::Decode(strData3.c_str(), strData3.size(), + bytes3, len3); + ptr->ipdRevPasswordData.rgbSalt.cbLength = len3; + } + } + else + { + auto ptr(new XLSB::BookProtection); + objectPtr = XLS::BaseObjectPtr{ptr}; + if(m_oLockRevision.IsInit()) + ptr->wFlags.fLockRevision = m_oLockRevision->GetValue(); + if(m_oLockStructure.IsInit()) + ptr->wFlags.fLockStructure = m_oLockStructure->GetValue(); + if(m_oLockWindows.IsInit()) + ptr->wFlags.fLockWindow = m_oLockWindows->GetValue(); + } + return objectPtr; + } void CWorkbookProtection::fromBin(XLS::BaseObjectPtr& obj) { ReadAttributes(obj); @@ -262,6 +428,71 @@ namespace OOX if (!oReader.IsEmptyNode()) oReader.ReadTillEnd(); } + XLS::BaseObjectPtr CFileSharing::toBin() + { + XLS::BaseObjectPtr objectPtr; + if(m_oSpinCount.IsInit() || m_oAlgorithmName.IsInit() || m_oHashValue.IsInit()) + { + auto ptr(new XLSB::FileSharingIso); + objectPtr = XLS::BaseObjectPtr{ptr}; + + if (m_oReadOnlyRecommended.IsInit()) + ptr->fReadOnlyRec = m_oReadOnlyRecommended.get(); + else + ptr->fReadOnlyRec = false; + if(m_oUserName.IsInit()) + ptr->stUserName = m_oUserName.get(); + else + ptr->stUserName = L""; + if(m_oAlgorithmName.IsInit()) + ptr->ipdPasswordData.szAlgName = m_oAlgorithmName->GetValue(); + else + ptr->ipdPasswordData.szAlgName = L""; + if(m_oSpinCount.IsInit()) + ptr->dwSpinCount = m_oSpinCount->GetValue(); + else + ptr->dwSpinCount = 0; + + auto len = 0; + if(m_oHashValue.IsInit()) + { + auto bytes = ptr->ipdPasswordData.rgbHash.rgbData.data(); + std::string strData = {m_oHashValue.get().begin(), m_oHashValue.get().end()}; + NSFile::CBase64Converter::Decode(strData.c_str(), strData.size(), + bytes, len); + } + ptr->ipdPasswordData.rgbHash.cbLength = len; + + auto len1 = 0; + if(m_oSaltValue.IsInit()) + { + auto bytes1 = ptr->ipdPasswordData.rgbSalt.rgbData.data(); + std::string strData1 = {m_oSaltValue.get().begin(), m_oSaltValue.get().end()}; + NSFile::CBase64Converter::Decode(strData1.c_str(), strData1.size(), + bytes1, len1); + } + ptr->ipdPasswordData.rgbSalt.cbLength = len1; + + } + else + { + auto ptr(new XLSB::FileSharing); + objectPtr = XLS::BaseObjectPtr{ptr}; + if (m_oReadOnlyRecommended.IsInit()) + ptr->fReadOnlyRec = m_oReadOnlyRecommended.get(); + else + ptr->fReadOnlyRec = false; + if(m_oUserName.IsInit()) + ptr->stUserName = m_oUserName.get(); + else + ptr->stUserName.setSize(0xFFFFFFFF); + if(m_oPassword.IsInit()) + ptr->wResPass = m_oPassword.get(); + else + ptr->wResPass = L""; + } + return objectPtr; + } void CFileSharing::fromBin(XLS::BaseObjectPtr& obj) { ReadAttributes(obj); diff --git a/OOXML/XlsxFormat/Workbook/WorkbookPr.h b/OOXML/XlsxFormat/Workbook/WorkbookPr.h index db7b068222b..3f32c987bf6 100644 --- a/OOXML/XlsxFormat/Workbook/WorkbookPr.h +++ b/OOXML/XlsxFormat/Workbook/WorkbookPr.h @@ -56,7 +56,7 @@ namespace OOX public: WritingElement_AdditionMethods(CWorkbookPr) WritingElement_XlsbConstructors(CWorkbookPr) - + CWorkbookPr(); virtual ~CWorkbookPr(); @@ -67,6 +67,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; private: @@ -98,7 +99,7 @@ namespace OOX public: WritingElement_AdditionMethods(CWorkbookProtection) WritingElement_XlsbConstructors(CWorkbookProtection) - + CWorkbookProtection(); virtual ~CWorkbookProtection(); @@ -109,6 +110,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType() const; void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); @@ -135,7 +137,7 @@ namespace OOX public: WritingElement_AdditionMethods(CFileSharing) WritingElement_XlsbConstructors(CFileSharing) - + CFileSharing(); virtual ~CFileSharing(); @@ -146,6 +148,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType() const; void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); @@ -153,7 +156,7 @@ namespace OOX nullable_bool m_oReadOnlyRecommended; nullable_string m_oUserName; - + nullable m_oAlgorithmName; nullable m_oSpinCount; nullable_string m_oHashValue; diff --git a/OOXML/XlsxFormat/Worksheets/Cols.cpp b/OOXML/XlsxFormat/Worksheets/Cols.cpp index df7739a53fd..0028780aa81 100644 --- a/OOXML/XlsxFormat/Worksheets/Cols.cpp +++ b/OOXML/XlsxFormat/Worksheets/Cols.cpp @@ -81,6 +81,56 @@ namespace OOX { ReadAttributes(obj); } + XLS::BaseObjectPtr CCol::toBin() + { + auto castedPtr = new XLSB::ColInfo; + XLS::BaseObjectPtr ptr(castedPtr); + if(m_oBestFit.IsInit()) + castedPtr->fBestFit = m_oBestFit->ToBool(); + else + castedPtr->fBestFit = false; + if(m_oCollapsed.IsInit()) + castedPtr->fCollapsed = m_oCollapsed->ToBool(); + else + castedPtr->fCollapsed = false; + if(m_oCustomWidth.IsInit()) + castedPtr->fUserSet = m_oCustomWidth->ToBool(); + else + castedPtr->fUserSet = false; + if(m_oHidden.IsInit()) + castedPtr->fHidden = m_oHidden->ToBool(); + else + castedPtr->fHidden = false; + if(m_oMax.IsInit()) + castedPtr->colLast = m_oMax->m_eValue - 1; + else + castedPtr->colLast = 16383; + if(m_oMin.IsInit()) + castedPtr->colFirst = m_oMin->m_eValue - 1; + else + castedPtr->colFirst = 0; + if(m_oOutlineLevel.IsInit()) + castedPtr->iOutLevel = m_oOutlineLevel->m_eValue; + else + castedPtr->iOutLevel = false; + if(m_oPhonetic.IsInit()) + castedPtr->fPhonetic = m_oPhonetic->ToBool(); + else + castedPtr->fPhonetic = false; + if(m_oStyle.IsInit()) + castedPtr->ixfeXLSB = m_oStyle->m_eValue; + else + castedPtr->ixfeXLSB = 0; + + if (m_oWidth.IsInit()) + { + if(m_oWidth->GetValue() > 0) + castedPtr->coldx = m_oWidth->GetValue() * 256; + } + else + castedPtr->coldx = 2304; ///standart col width(9) * 256 + return ptr; + } EElementType CCol::getType() const { return et_x_Col; @@ -230,6 +280,15 @@ namespace OOX } } } + std::vector CCols::toBin() + { + std::vector ptrVector; + for(auto i:m_arrItems) + { + ptrVector.push_back(i->toBin()); + } + return ptrVector; + } EElementType CCols::getType () const { return et_x_Cols; diff --git a/OOXML/XlsxFormat/Worksheets/Cols.h b/OOXML/XlsxFormat/Worksheets/Cols.h index 7c000a45f96..5d2dbba6154 100644 --- a/OOXML/XlsxFormat/Worksheets/Cols.h +++ b/OOXML/XlsxFormat/Worksheets/Cols.h @@ -61,6 +61,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType() const; private: @@ -95,6 +96,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(std::vector& obj); + std::vector toBin(); virtual EElementType getType () const; private: diff --git a/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.cpp b/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.cpp index 3ae020f2a2b..385a48c40b9 100644 --- a/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.cpp +++ b/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.cpp @@ -47,6 +47,7 @@ #include "../../XlsbFormat/Biff12_records/BeginConditionalFormatting.h" #include "../../XlsbFormat/Biff12_records/BeginConditionalFormatting14.h" +#include "../../XlsbFormat/Biff12_records/FRTBegin.h" #include "../../XlsbFormat/Biff12_records/BeginCFRule.h" #include "../../XlsbFormat/Biff12_records/BeginCFRule14.h" #include "../../XlsbFormat/Biff12_records/BeginDatabar.h" @@ -108,7 +109,7 @@ EElementType CFormulaCF::getType () const void CFormulaCF::toXML2(NSStringUtils::CStringBuilder& writer, bool bExtendedWrite) const { std::wstring node_name = bExtendedWrite ? L"xm:f" : L"formula"; - + writer.WriteString(L"<" + node_name + L">"); writer.WriteEncodeXmlString(m_sText); writer.WriteString(L""); @@ -125,7 +126,7 @@ void CFormulaCF::fromXML(XmlUtils::CXmlLiteReader& oReader) const CFormulaCF CFormulaCF::Merge(const CFormulaCF& oPrev, const CFormulaCF& oCurrent) { CFormulaCF oFormula; - + if (oCurrent.m_sText.empty() == false) { oFormula.m_sText = oCurrent.m_sText; @@ -180,11 +181,11 @@ void CConditionalFormatValueObject::ReadAttributes(XmlUtils::CXmlLiteReader& oRe void CConditionalFormatValueObject::toXML2(NSStringUtils::CStringBuilder& writer, bool bExtendedWrite) const { if (false == m_oType.IsInit()) return; - + if (bExtendedWrite == false) { if (m_oType->GetValue() == SimpleTypes::Spreadsheet::autoMin) m_oType->SetValue(SimpleTypes::Spreadsheet::Minimum); - if (m_oType->GetValue() == SimpleTypes::Spreadsheet::autoMax) m_oType->SetValue(SimpleTypes::Spreadsheet::Maximum); + if (m_oType->GetValue() == SimpleTypes::Spreadsheet::autoMax) m_oType->SetValue(SimpleTypes::Spreadsheet::Maximum); } std::wstring node_name = bExtendedWrite ? L"x14:cfvo" : L"cfvo"; @@ -220,7 +221,7 @@ void CConditionalFormatValueObject::toXML2(NSStringUtils::CStringBuilder& writer CFormulaCF formla; formla.m_sText = m_oVal.get(); formla.toXML2(writer, true); } - + } writer.WriteString(L""); @@ -228,7 +229,7 @@ void CConditionalFormatValueObject::toXML2(NSStringUtils::CStringBuilder& writer void CConditionalFormatValueObject::fromXML(XmlUtils::CXmlLiteReader& oReader) { ReadAttributes(oReader); - + if (oReader.IsEmptyNode()) return; @@ -240,6 +241,135 @@ void CConditionalFormatValueObject::fromXML(XmlUtils::CXmlLiteReader& oReader) m_oFormula = oReader; } } +XLS::BaseObjectPtr CConditionalFormatValueObject::toBin(bool isIcon) +{ + auto ptr(new XLSB::uCFVO); + XLS::BaseObjectPtr objectPtr(ptr); + + auto ptr1(new XLSB::CFVO); + ptr->m_BrtCFVO = XLS::BaseObjectPtr{ptr1}; + ptr1->fSaveGTE = isIcon; + if(m_oGte.IsInit()) + ptr1->fGTE = m_oGte->GetValue(); + else + ptr1->fGTE = true; + if (m_oType == SimpleTypes::Spreadsheet::ECfvoType::Number) + ptr1->iType = XLSB::CFVOtype::CFVONUM; + else if (m_oType == SimpleTypes::Spreadsheet::ECfvoType::Minimum) + ptr1->iType = XLSB::CFVOtype::CFVOMIN; + else if (m_oType == SimpleTypes::Spreadsheet::ECfvoType::Maximum) + ptr1->iType = XLSB::CFVOtype::CFVOMAX; + else if (m_oType == SimpleTypes::Spreadsheet::ECfvoType::Percent) + ptr1->iType = XLSB::CFVOtype::CFVOPERCENT; + else if (m_oType == SimpleTypes::Spreadsheet::ECfvoType::Percentile) + ptr1->iType = XLSB::CFVOtype::CFVOPERCENTILE; + else if (m_oType == SimpleTypes::Spreadsheet::ECfvoType::Formula) + ptr1->iType = XLSB::CFVOtype::CFVOFMLA; + else + ptr1->iType = XLSB::CFVOtype::CFVONUM; + + if(m_oVal.IsInit() && ptr1->iType != XLSB::CFVOtype::CFVOFMLA) + try + { + ptr1->numParam.data.value = std::stod(m_oVal.get()); + } + catch (std::exception) + { + ptr1->formula = m_oVal.get(); + auto lastValType = GETBITS(ptr1->formula.rgce.sequence.rbegin()->get()->ptg_id.get(),5,6); + if(lastValType == 1 || lastValType == 3) + { + SETBITS(ptr1->formula.rgce.sequence.rbegin()->get()->ptg_id.get(),5,6,2); + } + + ptr1->cbFmla = 1; + } + if(ptr1->iType.get_type() == XLSB::CFVOtype::CFVOMIN) + ptr1->numParam.data.value = 0; + else if(ptr1->iType.get_type() == XLSB::CFVOtype::CFVOMAX) + ptr1->numParam.data.value = 0; + + if(static_cast<_UINT32>(ptr1->iType) == XLSB::CFVOtype::CFVOFMLA && m_oVal.IsInit()) + { + ptr1->formula = m_oVal.get(); + auto lastValType = GETBITS(ptr1->formula.rgce.sequence.rbegin()->get()->ptg_id.get(),5,6); + if(lastValType == 1 || lastValType == 3) + { + SETBITS(ptr1->formula.rgce.sequence.rbegin()->get()->ptg_id.get(),5,6,2); + } + + ptr1->cbFmla = 1; + } + else + { + ptr1->cbFmla = 0; + } + + return objectPtr; +} +XLS::BaseObjectPtr CConditionalFormatValueObject::toBin14(bool isIcon) +{ + auto ptr(new XLSB::uCFVO14); + XLS::BaseObjectPtr objectPtr(ptr); + + auto ptr1(new XLSB::CFVO14); + ptr->m_BrtCFVO14 = XLS::BaseObjectPtr{ptr1}; + ptr1->fSaveGTE = isIcon; + if(m_oGte.IsInit()) + ptr1->fGTE = m_oGte->GetValue(); + else + ptr1->fGTE = true; + if (m_oType == SimpleTypes::Spreadsheet::ECfvoType::Number) + ptr1->iType = XLSB::CFVOtype::CFVONUM; + else if (m_oType == SimpleTypes::Spreadsheet::ECfvoType::Minimum) + ptr1->iType = XLSB::CFVOtype::CFVOMIN; + else if (m_oType == SimpleTypes::Spreadsheet::ECfvoType::Maximum) + ptr1->iType = XLSB::CFVOtype::CFVOMAX; + else if (m_oType == SimpleTypes::Spreadsheet::ECfvoType::Percent) + ptr1->iType = XLSB::CFVOtype::CFVOPERCENT; + else if (m_oType == SimpleTypes::Spreadsheet::ECfvoType::Percentile) + ptr1->iType = XLSB::CFVOtype::CFVOPERCENTILE; + else if (m_oType == SimpleTypes::Spreadsheet::ECfvoType::Formula) + ptr1->iType = XLSB::CFVOtype::CFVOFMLA; + else + ptr1->iType = XLSB::CFVOtype::CFVONUM; + + if(ptr1->iType.get_type() == XLSB::CFVOtype::CFVOMIN) + ptr1->numParam.data.value = 0; + else if(ptr1->iType.get_type() == XLSB::CFVOtype::CFVOMAX) + ptr1->numParam.data.value = 0; + + if(static_cast<_UINT32>(ptr1->iType) == XLSB::CFVOtype::CFVOFMLA && m_oVal.IsInit()) + { + XLSB::FRTFormula tempFmla; + tempFmla.formula = m_oVal.get(); + ptr1->FRTheader.rgFormulas.array.push_back(tempFmla); + ptr1->FRTheader.fFormula = true; + ptr1->cbFmla = 1; + } + else if (static_cast<_UINT32>(ptr1->iType) == XLSB::CFVOtype::CFVOFMLA && m_oFormula.IsInit() && !m_oFormula->m_sText.empty()) + { + XLSB::FRTFormula tempFmla; + tempFmla.formula = m_oFormula->m_sText; + ptr1->FRTheader.rgFormulas.array.push_back(tempFmla); + ptr1->FRTheader.fFormula = true; + ptr1->cbFmla = 1; + } + else + { + ptr1->cbFmla = 0; + } + if(ptr1->cbFmla == 0 && m_oFormula.IsInit() && !m_oFormula->m_sText.empty()) + { + try + { + ptr1->numParam.data.value = std::stod(m_oFormula->m_sText); + } + catch(std::exception) + {} + } + return objectPtr; +} void CConditionalFormatValueObject::fromBin(XLS::BaseObjectPtr& obj) { ReadAttributes(obj); @@ -619,6 +749,26 @@ void CColorScale::fromBin(XLS::BaseObjectPtr& obj) } } } +XLS::BaseObjectPtr CColorScale::toBin() +{ + auto ptr(new XLSB::COLORSCALE); + XLS::BaseObjectPtr objectPtr(ptr); + for(auto i:m_arrValues) + ptr->m_arCFVO.push_back(i->toBin()); + for(auto i:m_arrColors) + ptr->m_arBrtColor.push_back(i->toBin()); + return objectPtr; +} +XLS::BaseObjectPtr CColorScale::toBin14() +{ + auto ptr(new XLSB::COLORSCALE14); + XLS::BaseObjectPtr objectPtr(ptr); + for(auto i:m_arrValues) + ptr->m_arCFVO14.push_back(i->toBin14()); + for(auto i:m_arrColors) + ptr->m_arBrtColor14.push_back(i->toBin14()); + return objectPtr; +} EElementType CColorScale::getType () const { return et_x_ColorScale; @@ -637,7 +787,7 @@ nullable CColorScale::Merge(const nullable &oPrev, const nullablem_BrtBeginDatabar = XLS::BaseObjectPtr{ptr1}; + if(m_oMaxLength.IsInit()) + ptr1->bLenMax = m_oMaxLength->GetValue(); + + if(m_oMinLength.IsInit()) + ptr1->bLenMin = m_oMinLength->GetValue(); + + if(m_oShowValue.IsInit()) + ptr1->fShowValue = m_oShowValue->GetValue(); + + for(auto i:m_arrValues) + ptr->m_arCFVO.push_back(i->toBin()); + if(m_oColor.IsInit()) + ptr->m_BrtColor = m_oColor->toBin(); + + return objectPtr; +} + +XLS::BaseObjectPtr CDataBar::toBin14() +{ + auto ptr(new XLSB::DATABAR14); + XLS::BaseObjectPtr objectPtr(ptr); + + auto ptr1(new XLSB::BeginDatabar14); + ptr->m_BrtBeginDatabar14 = XLS::BaseObjectPtr{ptr1}; + if(m_oMaxLength.IsInit()) + ptr1->bLenMax = m_oMaxLength->GetValue(); + else + ptr1->bLenMax = 100; + if(m_oMinLength.IsInit()) + ptr1->bLenMin = m_oMinLength->GetValue(); + else + ptr1->bLenMin = 0; + if(m_oShowValue.IsInit()) + ptr1->fShowValue = m_oShowValue->GetValue(); + if(m_oGradient.IsInit()) + ptr1->fGradient = m_oGradient->GetValue(); + if(m_oDirection.IsInit()) + ptr1->bDirection = m_oDirection->GetValue(); + if(m_oAxisPosition.IsInit()) + ptr1->bAxisPosType = m_oAxisPosition->GetValue(); + if(m_oBorder.IsInit()) + ptr1->fBorder = m_oBorder->GetValue(); + if(m_oNegativeBarColorSameAsPositive.IsInit()) + ptr1->fCustomNegativeFillColor = !m_oNegativeBarColorSameAsPositive->GetValue(); + if(m_oNegativeBarBorderColorSameAsPositive.IsInit()) + ptr1->fCustomNegativeBorderColor = !m_oNegativeBarBorderColorSameAsPositive->GetValue(); + + for(auto i:m_arrValues) + ptr->m_arCFVO14.push_back(i->toBin14()); + if(m_oColor.IsInit()) + ptr->m_arBrtColor14.push_back(m_oColor->toBin14()); + if(m_oAxisColor.IsInit()) + ptr->m_arBrtColor14.push_back(m_oAxisColor->toBin14()); + if(m_oBorderColor.IsInit()) + ptr->m_arBrtColor14.push_back(m_oBorderColor->toBin14()); + if(m_oNegativeFillColor.IsInit()) + ptr->m_arBrtColor14.push_back(m_oNegativeFillColor->toBin14()); + if(m_oNegativeBorderColor.IsInit()) + ptr->m_arBrtColor14.push_back(m_oNegativeBorderColor->toBin14()); + + return objectPtr; +} + void CDataBar::ReadAttributes(XLS::BaseObjectPtr& obj) { if(obj->get_type() == XLS::typeBeginDatabar) @@ -898,13 +1118,13 @@ const CDataBar CDataBar::Merge(const CDataBar& oPrev, const CDataBar& oCurrent) oDataBar.m_oDirection = Merge( oPrev.m_oDirection, oCurrent.m_oDirection ); oDataBar.m_oNegativeBarColorSameAsPositive = Merge( oPrev.m_oNegativeBarColorSameAsPositive, oCurrent.m_oNegativeBarColorSameAsPositive ); oDataBar.m_oNegativeBarBorderColorSameAsPositive = Merge( oPrev.m_oNegativeBarBorderColorSameAsPositive, oCurrent.m_oNegativeBarBorderColorSameAsPositive ); - + oDataBar.m_oColor = Merge( oPrev.m_oColor, oCurrent.m_oColor ); oDataBar.m_oAxisColor = Merge( oPrev.m_oAxisColor, oCurrent.m_oAxisColor ); oDataBar.m_oBorderColor = Merge( oPrev.m_oBorderColor, oCurrent.m_oBorderColor ); oDataBar.m_oNegativeFillColor = Merge( oPrev.m_oNegativeFillColor, oCurrent.m_oNegativeFillColor ); oDataBar.m_oNegativeBorderColor = Merge( oPrev.m_oNegativeBorderColor, oCurrent.m_oNegativeBorderColor ); - + for (size_t i = 0; i < oPrev.m_arrValues.size(); i++) { if (i < oCurrent.m_arrValues.size()) @@ -1061,6 +1281,323 @@ void CIconSet::fromBin(XLS::BaseObjectPtr& obj) } } } +XLS::BaseObjectPtr CIconSet::toBin() +{ + auto ptr(new XLSB::ICONSET); + XLS::BaseObjectPtr objectPtr(ptr); + + auto beginPtr(new XLSB::BeginIconSet); + ptr->m_BrtBeginIconSet = XLS::BaseObjectPtr{beginPtr}; + if(m_oShowValue.IsInit()) + beginPtr->fIcon = !m_oShowValue->GetValue(); + else + beginPtr->fIcon = false; + if(m_oReverse.IsInit()) + beginPtr->fReverse = m_oReverse->GetValue(); + else + beginPtr->fReverse = false; + if(m_oIconSet.IsInit()) + { + switch (m_oIconSet->GetValue()) + { + case SimpleTypes::Spreadsheet::EIconSetType::NoIcons: + { + beginPtr->iSet.set = KPISets::KPINIL; + break; + } + case SimpleTypes::Spreadsheet::EIconSetType::Arrows3: + { + beginPtr->iSet.set = KPISets::KPI3ARROWS; + break; + } + case SimpleTypes::Spreadsheet::EIconSetType::Arrows3Gray: + { + beginPtr->iSet.set = KPISets::KPI3ARROWSGRAY; + break; + } + case SimpleTypes::Spreadsheet::EIconSetType::Flags3: + { + beginPtr->iSet.set = KPISets::KPI3FLAGS; + break; + } + case SimpleTypes::Spreadsheet::EIconSetType::Traffic3Lights1: + { + beginPtr->iSet.set = KPISets::KPI3TRAFFICLIGHTS1; + break; + } + case SimpleTypes::Spreadsheet::EIconSetType::Traffic3Lights2: + { + beginPtr->iSet.set = KPISets::KPI3TRAFFICLIGHTS2; + break; + } + case SimpleTypes::Spreadsheet::EIconSetType::Signs3: + { + beginPtr->iSet.set = KPISets::KPI3SIGNS; + break; + } + case SimpleTypes::Spreadsheet::EIconSetType::Symbols3: + { + beginPtr->iSet.set = KPISets::KPI3SYMBOLS; + break; + } + case SimpleTypes::Spreadsheet::EIconSetType::Symbols3_2: + { + beginPtr->iSet.set = KPISets::KPI3SYMBOLS2; + break; + } + case SimpleTypes::Spreadsheet::EIconSetType::Arrows4: + { + beginPtr->iSet.set = KPISets::KPI4ARROWS; + break; + } + case SimpleTypes::Spreadsheet::EIconSetType::Arrows4Gray: + { + beginPtr->iSet.set = KPISets::KPI4ARROWSGRAY; + break; + } + case SimpleTypes::Spreadsheet::EIconSetType::RedToBlack4: + { + beginPtr->iSet.set = KPISets::KPI4REDTOBLACK; + break; + } + case SimpleTypes::Spreadsheet::EIconSetType::Rating4: + { + beginPtr->iSet.set = KPISets::KPI4RATING; + break; + } + case SimpleTypes::Spreadsheet::EIconSetType::Traffic4Lights: + { + beginPtr->iSet.set = KPISets::KPI4TRAFFICLIGHTS; + break; + } + case SimpleTypes::Spreadsheet::EIconSetType::Arrows5: + { + beginPtr->iSet.set = KPISets::KPI5ARROWS; + break; + } + case SimpleTypes::Spreadsheet::EIconSetType::Arrows5Gray: + { + beginPtr->iSet.set = KPISets::KPI5ARROWSGRAY; + break; + } + case SimpleTypes::Spreadsheet::EIconSetType::Rating5: + { + beginPtr->iSet.set = KPISets::KPI5RATING; + break; + } + case SimpleTypes::Spreadsheet::EIconSetType::Quarters5: + { + beginPtr->iSet.set = KPISets::KPI5QUARTERS; + break; + } + default: + { + beginPtr->iSet.set = KPISets::KPINIL; + break; + } + } + } + else + { + switch(m_arrValues.size()) + { + case 0: + { + beginPtr->iSet.set = KPISets::KPINIL; + break; + } + case 3: + { + beginPtr->iSet.set = KPISets::KPI3TRAFFICLIGHTS1; + break; + } + case 4: + { + beginPtr->iSet.set = KPISets::KPI4TRAFFICLIGHTS; + break; + } + case 5: + { + beginPtr->iSet.set = KPISets::KPI5QUARTERS; + break; + } + default: + { + beginPtr->iSet.set = KPISets::KPINIL; + break; + } + } + + } + + for(auto i:m_arrValues) + ptr->m_arCFVO.push_back(i->toBin(true)); + return objectPtr; +} +XLS::BaseObjectPtr CIconSet::toBin14() +{ + auto ptr(new XLSB::ICONSET14); + XLS::BaseObjectPtr objectPtr(ptr); + + auto beginPtr(new XLSB::BeginIconSet14); + ptr->m_BrtBeginIconSet14 = XLS::BaseObjectPtr{beginPtr}; + if(m_oShowValue.IsInit()) + beginPtr->fIcon = !m_oShowValue->GetValue(); + if(m_oReverse.IsInit()) + beginPtr->fReverse = m_oReverse->GetValue(); + if(m_oIconSet.IsInit()) + { + switch (m_oIconSet->GetValue()) + { + case SimpleTypes::Spreadsheet::EIconSetType::NoIcons: + { + beginPtr->iSet.set = KPISets14::KPINIL_14; + break; + } + case SimpleTypes::Spreadsheet::EIconSetType::Arrows3: + { + beginPtr->iSet.set = KPISets14::KPI3ARROWS_14; + break; + } + case SimpleTypes::Spreadsheet::EIconSetType::Arrows3Gray: + { + beginPtr->iSet.set = KPISets14::KPI3ARROWSGRAY_14; + break; + } + case SimpleTypes::Spreadsheet::EIconSetType::Flags3: + { + beginPtr->iSet.set = KPISets14::KPI3FLAGS_14; + break; + } + case SimpleTypes::Spreadsheet::EIconSetType::Traffic3Lights1: + { + beginPtr->iSet.set = KPISets14::KPI3TRAFFICLIGHTS1_14; + break; + } + case SimpleTypes::Spreadsheet::EIconSetType::Traffic3Lights2: + { + beginPtr->iSet.set = KPISets14::KPI3TRAFFICLIGHTS2_14; + break; + } + case SimpleTypes::Spreadsheet::EIconSetType::Signs3: + { + beginPtr->iSet.set = KPISets14::KPI3SIGNS_14; + break; + } + case SimpleTypes::Spreadsheet::EIconSetType::Symbols3: + { + beginPtr->iSet.set = KPISets14::KPI3SYMBOLS_14; + break; + } + case SimpleTypes::Spreadsheet::EIconSetType::Symbols3_2: + { + beginPtr->iSet.set = KPISets14::KPI3SYMBOLS2_14; + break; + } + case SimpleTypes::Spreadsheet::EIconSetType::Arrows4: + { + beginPtr->iSet.set = KPISets14::KPI4ARROWS_14; + break; + } + case SimpleTypes::Spreadsheet::EIconSetType::Arrows4Gray: + { + beginPtr->iSet.set = KPISets14::KPI4ARROWSGRAY_14; + break; + } + case SimpleTypes::Spreadsheet::EIconSetType::RedToBlack4: + { + beginPtr->iSet.set = KPISets14::KPI4REDTOBLACK_14; + break; + } + case SimpleTypes::Spreadsheet::EIconSetType::Rating4: + { + beginPtr->iSet.set = KPISets14::KPI4RATING_14; + break; + } + case SimpleTypes::Spreadsheet::EIconSetType::Traffic4Lights: + { + beginPtr->iSet.set = KPISets14::KPI4TRAFFICLIGHTS_14; + break; + } + case SimpleTypes::Spreadsheet::EIconSetType::Arrows5: + { + beginPtr->iSet.set = KPISets14::KPI5ARROWS_14; + break; + } + case SimpleTypes::Spreadsheet::EIconSetType::Arrows5Gray: + { + beginPtr->iSet.set = KPISets14::KPI5ARROWSGRAY_14; + break; + } + case SimpleTypes::Spreadsheet::EIconSetType::Rating5: + { + beginPtr->iSet.set = KPISets14::KPI5RATING_14; + break; + } + case SimpleTypes::Spreadsheet::EIconSetType::Quarters5: + { + beginPtr->iSet.set = KPISets14::KPI5QUARTERS_14; + break; + } + case SimpleTypes::Spreadsheet::EIconSetType::Stars3: + { + beginPtr->iSet.set = KPISets14::KPI3STARS_14; + break; + } + case SimpleTypes::Spreadsheet::EIconSetType::Triangles3: + { + beginPtr->iSet.set = KPISets14::KPI3TRIANGLES_14; + break; + } + case SimpleTypes::Spreadsheet::EIconSetType::Boxes5: + { + beginPtr->iSet.set = KPISets14::KPI5BOXES_14; + break; + } + default: + { + beginPtr->iSet.set = KPISets14::KPINIL_14; + break; + } + } + } + else + { + switch(m_arrValues.size()) + { + case 0: + { + beginPtr->iSet.set = KPISets14::KPINIL_14; + break; + } + case 3: + { + beginPtr->iSet.set = KPISets14::KPI3TRAFFICLIGHTS1_14; + break; + } + case 4: + { + beginPtr->iSet.set = KPISets14::KPI4TRAFFICLIGHTS_14; + break; + } + case 5: + { + beginPtr->iSet.set = KPISets14::KPI5QUARTERS_14; + break; + } + default: + { + beginPtr->iSet.set = KPISets14::KPINIL_14; + break; + } + } + + } + + for(auto i:m_arrValues) + ptr->m_arCFVO14.push_back(i->toBin14(true)); + return objectPtr; +} void CIconSet::ReadAttributes(XLS::BaseObjectPtr& obj) { if(obj->get_type() == XLS::typeBeginIconSet) @@ -1309,7 +1846,7 @@ const CIconSet CIconSet::Merge(const CIconSet& oPrev, const CIconSet& oCurrent) oIconSet.m_oReverse = Merge( oPrev.m_oReverse, oCurrent.m_oReverse ); oIconSet.m_oShowValue = Merge( oPrev.m_oShowValue, oCurrent.m_oShowValue ); oIconSet.m_oCustom = Merge( oPrev.m_oCustom, oCurrent.m_oCustom ); - + for (size_t i = 0; i < oPrev.m_arrValues.size(); i++) { if (i < oCurrent.m_arrValues.size()) @@ -1383,7 +1920,7 @@ bool CConditionalFormattingRule::isExtended() if (m_oDataBar.IsInit()) return m_oDataBar->isExtended(); if (m_oIconSet.IsInit()) return m_oIconSet->isExtended(); if (m_oColorScale.IsInit()) return m_oColorScale->isExtended(); - + for (size_t i = 0; i < m_arrFormula.size(); i++) { if ((m_arrFormula[i].IsInit()) && m_arrFormula[i]->isExtended()) @@ -1396,7 +1933,7 @@ void CConditionalFormattingRule::toXML2(NSStringUtils::CStringBuilder& writer, b if (false == isValid()) return; std::wstring node_name = bExtendedWrite ? L"x14:cfRule" : L"cfRule"; - + writer.WriteString(L"<" + node_name); WritingStringNullableAttrString(L"type", m_oType, m_oType->ToString()); WritingStringNullableAttrInt(L"priority", m_oPriority, m_oPriority->GetValue()); @@ -1434,7 +1971,7 @@ void CConditionalFormattingRule::toXML2(NSStringUtils::CStringBuilder& writer, b m_oColorScale->toXML2(writer, bExtendedWrite); if (m_oDataBar.IsInit()) m_oDataBar->toXML2(writer, bExtendedWrite); - + for (size_t i = 0; i < m_arrFormula.size(); i++) { if (m_arrFormula[i].IsInit()) @@ -1460,7 +1997,7 @@ void CConditionalFormattingRule::fromXML(XmlUtils::CXmlLiteReader& oReader) while (oReader.ReadNextSiblingNode(nCurDepth)) { std::wstring sName = XmlUtils::GetNameNoNS(oReader.GetName()); - + if (L"colorScale" == sName ) m_oColorScale = oReader; else if ( L"dataBar" == sName) @@ -1559,6 +2096,538 @@ void CConditionalFormattingRule::fromBin(XLS::BaseObjectPtr& obj) } } } + +XLS::BaseObjectPtr CConditionalFormattingRule::toBin(const XLS::CellRef &cellRef) +{ + auto ptr(new XLSB::CFRULE(cellRef)); + XLS::BaseObjectPtr objPtr(ptr); + + ptr->m_BrtBeginCFRule = WriteAttributes(cellRef); + + if(m_oColorScale.IsInit()) + { + ptr->m_source = m_oColorScale->toBin(); + } + else if(m_oDataBar.IsInit()) + { + ptr->m_source = m_oDataBar->toBin(); + } + else if(m_oIconSet.IsInit()) + { + ptr->m_source = m_oIconSet->toBin(); + } + if(m_oExtId.IsInit()) + { + auto extPtr(new XLSB::FRTCFRULE); + auto beginExt(new XLSB::CFRuleExt); + extPtr->m_BrtCFRuleExt = XLS::BaseObjectPtr{beginExt}; + ptr->m_FRTCFRULE = XLS::BaseObjectPtr{extPtr}; + + beginExt->guid = m_oExtId.get(); + auto ruleBegin(new XLSB::FRTBegin); + ruleBegin->productVersion.product = 0; + ruleBegin->productVersion.version = 0; + extPtr->m_BrtFRTBegin = XLS::BaseObjectPtr{ruleBegin}; + } + return objPtr; +} + +XLS::BaseObjectPtr CConditionalFormattingRule::WriteAttributes(const XLS::CellRef &cellRef) +{ + + auto ptr(new XLSB::BeginCFRule(cellRef)); + BaseObjectPtr objectPtr(ptr); + + if(m_oDxfId.IsInit()) + { + ptr->dxfId = m_oDxfId->GetValue(); + } + else + ptr->dxfId = 0; + if(m_oPriority.IsInit()) + ptr->iPri = m_oPriority->GetValue(); + else + ptr->iPri = 1; + if(m_oStopIfTrue.IsInit()) + ptr->fStopTrue = m_oStopIfTrue->GetValue(); + else + ptr->fStopTrue = false; + if(m_oAboveAverage.IsInit()) + ptr->fAbove = m_oAboveAverage->GetValue(); + else + ptr->fAbove = false; + if(m_oBottom.IsInit()) + ptr->fBottom = m_oBottom->GetValue(); + else + ptr->fBottom = false; + if(m_oPercent.IsInit()) + ptr->fPercent = m_oPercent->GetValue(); + else + ptr->fPercent = false; + if(m_oText.IsInit()) + ptr->strParam = m_oText.get(); + else + ptr->strParam.setSize(0xFFFFFFFF); + + if(!m_arrFormula.empty() && !m_arrFormula.front()->m_sText.empty()) + { + ptr->rgce1 = m_arrFormula.front()->m_sText; + m_arrFormula.erase(m_arrFormula.begin()); + ptr->cbFmla1 = 1; + } + else + { + ptr->cbFmla1 = 0; + } + if(!m_arrFormula.empty() && !m_arrFormula.front()->m_sText.empty()) + { + ptr->rgce2 = m_arrFormula.front()->m_sText; + m_arrFormula.erase(m_arrFormula.begin()); + ptr->cbFmla2 = 1; + } + else + { + ptr->cbFmla2 = 0; + } + if(!m_arrFormula.empty() && !m_arrFormula.front()->m_sText.empty()) + { + ptr->rgce3 = m_arrFormula.front()->m_sText; + m_arrFormula.erase(m_arrFormula.begin()); + ptr->cbFmla3 = 1; + } + else + { + ptr->cbFmla3 = 0; + } + + ptr->iType = XLSB::CFType::CF_TYPE_EXPRIS; + ptr->iParam =0; + + if (m_oType == SimpleTypes::Spreadsheet::ECfType::cellIs) + { + if (m_oOperator == SimpleTypes::Spreadsheet::ECfOperator::Operator_between) + ptr->iParam = XLSB::CFOper::CF_OPER_BN; + else if (m_oOperator == SimpleTypes::Spreadsheet::ECfOperator::Operator_notBetween) + ptr->iParam = XLSB::CFOper::CF_OPER_NB; + else if (m_oOperator == SimpleTypes::Spreadsheet::ECfOperator::Operator_equal) + ptr->iParam = XLSB::CFOper::CF_OPER_EQ; + else if (m_oOperator == SimpleTypes::Spreadsheet::ECfOperator::Operator_notEqual) + ptr->iParam = XLSB::CFOper::CF_OPER_NE; + else if (m_oOperator == SimpleTypes::Spreadsheet::ECfOperator::Operator_greaterThan) + ptr->iParam = XLSB::CFOper::CF_OPER_GT; + else if (m_oOperator == SimpleTypes::Spreadsheet::ECfOperator::Operator_lessThan) + ptr->iParam = XLSB::CFOper::CF_OPER_LT; + else if (m_oOperator == SimpleTypes::Spreadsheet::ECfOperator::Operator_greaterThanOrEqual) + ptr->iParam = XLSB::CFOper::CF_OPER_GE; + else if (m_oOperator == SimpleTypes::Spreadsheet::ECfOperator::Operator_lessThanOrEqual) + ptr->iParam = XLSB::CFOper::CF_OPER_LE; + ptr->iType = XLSB::CFType::CF_TYPE_CELLIS; + ptr->iTemplate = XLSB::CFTemp::CF_TEMPLATE_EXPR; + } + + if (m_oType == SimpleTypes::Spreadsheet::ECfType::expression) + { + ptr->iTemplate = XLSB::CFTemp::CF_TEMPLATE_FMLA; + } + else if (m_oType == SimpleTypes::Spreadsheet::ECfType::uniqueValues) + { + ptr->iTemplate = XLSB::CFTemp::CF_TEMPLATE_UNIQUEVALUES; + } + else if (m_oType == SimpleTypes::Spreadsheet::ECfType::containsText) + { + ptr->iTemplate = XLSB::CFTemp::CF_TEMPLATE_CONTAINSTEXT; + ptr->iParam = XLSB::CFTextOper::CF_TEXTOPER_CONTAINS; + } + else if (m_oType == SimpleTypes::Spreadsheet::ECfType::notContainsText) + { + ptr->iTemplate = XLSB::CFTemp::CF_TEMPLATE_CONTAINSTEXT; + ptr->iParam = XLSB::CFTextOper::CF_TEXTOPER_NOTCONTAINS; + } + else if (m_oType == SimpleTypes::Spreadsheet::ECfType::beginsWith) + { + ptr->iTemplate = XLSB::CFTemp::CF_TEMPLATE_CONTAINSTEXT; + ptr->iParam = XLSB::CFTextOper::CF_TEXTOPER_BEGINSWITH; + } + else if (m_oType == SimpleTypes::Spreadsheet::ECfType::endsWith) + { + ptr->iTemplate = XLSB::CFTemp::CF_TEMPLATE_CONTAINSTEXT; + ptr->iParam = XLSB::CFTextOper::CF_TEXTOPER_ENDSWITH; + } + else if (m_oType == SimpleTypes::Spreadsheet::ECfType::containsBlanks) + { + ptr->iTemplate = XLSB::CFTemp::CF_TEMPLATE_CONTAINSBLANKS; + } + else if (m_oType == SimpleTypes::Spreadsheet::ECfType::notContainsBlanks) + { + ptr->iTemplate = XLSB::CFTemp::CF_TEMPLATE_CONTAINSNOBLANKS; + } + else if (m_oType == SimpleTypes::Spreadsheet::ECfType::containsErrors) + { + ptr->iTemplate = XLSB::CFTemp::CF_TEMPLATE_CONTAINSERRORS; + } + else if (m_oType == SimpleTypes::Spreadsheet::ECfType::notContainsErrors) + { + ptr->iTemplate = XLSB::CFTemp::CF_TEMPLATE_CONTAINSNOERRORS; + } + + else if (m_oType == SimpleTypes::Spreadsheet::ECfType::timePeriod) + { + if (m_oTimePeriod == SimpleTypes::Spreadsheet::ETimePeriod::today) + { + ptr->iTemplate = XLSB::CFTemp::CF_TEMPLATE_TIMEPERIODTODAY; + ptr->iParam = XLSB::CFDateOper::CF_TIMEPERIOD_TODAY; + } + else if (m_oTimePeriod == SimpleTypes::Spreadsheet::ETimePeriod::tomorrow) + { + ptr->iTemplate = XLSB::CFTemp::CF_TEMPLATE_TIMEPERIODTOMORROW; + ptr->iParam = XLSB::CFDateOper::CF_TIMEPERIOD_TOMORROW; + } + else if (m_oTimePeriod == SimpleTypes::Spreadsheet::ETimePeriod::yesterday) + { + ptr->iTemplate = XLSB::CFTemp::CF_TEMPLATE_TIMEPERIODYESTERDAY; + ptr->iParam = XLSB::CFDateOper::CF_TIMEPERIOD_YESTERDAY; + } + else if (m_oTimePeriod == SimpleTypes::Spreadsheet::ETimePeriod::last7Days) + { + ptr->iTemplate = XLSB::CFTemp::CF_TEMPLATE_TIMEPERIODLAST7DAYS; + ptr->iParam = XLSB::CFDateOper::CF_TIMEPERIOD_LAST7DAYS; + } + else if (m_oTimePeriod == SimpleTypes::Spreadsheet::ETimePeriod::lastMonth) + { + ptr->iTemplate = XLSB::CFTemp::CF_TEMPLATE_TIMEPERIODLASTMONTH; + ptr->iParam = XLSB::CFDateOper::CF_TIMEPERIOD_LASTMONTH; + } + else if (m_oTimePeriod == SimpleTypes::Spreadsheet::ETimePeriod::nextMonth) + { + ptr->iTemplate = XLSB::CFTemp::CF_TEMPLATE_TIMEPERIODNEXTMONTH; + ptr->iParam = XLSB::CFDateOper::CF_TIMEPERIOD_NEXTMONTH; + } + else if (m_oTimePeriod == SimpleTypes::Spreadsheet::ETimePeriod::thisWeek) + { + ptr->iTemplate = XLSB::CFTemp::CF_TEMPLATE_TIMEPERIODTHISWEEK; + ptr->iParam = XLSB::CFDateOper::CF_TIMEPERIOD_THISWEEK; + } + else if (m_oTimePeriod == SimpleTypes::Spreadsheet::ETimePeriod::nextWeek) + { + ptr->iTemplate = XLSB::CFTemp::CF_TEMPLATE_TIMEPERIODNEXTWEEK; + ptr->iParam = XLSB::CFDateOper::CF_TIMEPERIOD_NEXTWEEK; + } + else if (m_oTimePeriod == SimpleTypes::Spreadsheet::ETimePeriod::lastWeek) + { + ptr->iTemplate = XLSB::CFTemp::CF_TEMPLATE_TIMEPERIODLASTWEEK; + ptr->iParam = XLSB::CFDateOper::CF_TIMEPERIOD_LASTWEEK; + } + else if (m_oTimePeriod == SimpleTypes::Spreadsheet::ETimePeriod::thisMonth) + { + ptr->iTemplate = XLSB::CFTemp::CF_TEMPLATE_TIMEPERIODTHISMONTH; + ptr->iParam = XLSB::CFDateOper::CF_TIMEPERIOD_THISMONTH; + } + } + + else if (m_oType == SimpleTypes::Spreadsheet::ECfType::aboveAverage) + { + ptr->iTemplate = XLSB::CFTemp::CF_TEMPLATE_ABOVEAVERAGE; + if(m_oStdDev.IsInit()) + ptr->iParam = m_oStdDev->GetValue(); + else + ptr->iParam = 0; + } + else if (m_oType == SimpleTypes::Spreadsheet::ECfType::duplicateValues) + { + ptr->iTemplate = XLSB::CFTemp::CF_TEMPLATE_DUPLICATEVALUES; + } + else if (m_oType == SimpleTypes::Spreadsheet::ECfType::colorScale) + { + ptr->iType = XLSB::CFType::CF_TYPE_GRADIENT; + ptr->iTemplate = XLSB::CFTemp::CF_TEMPLATE_GRADIENT; + ptr->dxfId = 0xFFFFFFFF; + } + else if (m_oType == SimpleTypes::Spreadsheet::ECfType::dataBar) + { + ptr->iType = XLSB::CFType::CF_TYPE_DATABAR; + ptr->iTemplate = XLSB::CFTemp::CF_TEMPLATE_DATABAR; + ptr->dxfId = 0xFFFFFFFF; + } + else if (m_oType == SimpleTypes::Spreadsheet::ECfType::iconSet) + { + ptr->iType = XLSB::CFType::CF_TYPE_MULTISTATE; + ptr->iTemplate = XLSB::CFTemp::CF_TEMPLATE_MULTISTATE; + } + else if (m_oType == SimpleTypes::Spreadsheet::ECfType::top10) + { + ptr->iType = XLSB::CFType::CF_TYPE_FILTER; + if(m_oRank.IsInit()) + ptr->iParam = m_oRank->GetValue(); + else + ptr->iParam = 1; + ptr->iTemplate = XLSB::CFTemp::CF_TEMPLATE_FILTER; + } + return objectPtr; +} +XLS::BaseObjectPtr CConditionalFormattingRule::toBin14(const XLS::CellRef &cellRef) +{ + auto ptr(new XLSB::CFRULE14()); + XLS::BaseObjectPtr objPtr(ptr); + ptr->m_BrtBeginCFRule14 = WriteAttributes14(cellRef); + if(m_oColorScale.IsInit()) + { + ptr->m_source = m_oColorScale->toBin14(); + } + else if(m_oDataBar.IsInit()) + { + ptr->m_source = m_oDataBar->toBin14(); + } + else if(m_oIconSet.IsInit()) + { + ptr->m_source = m_oIconSet->toBin14(); + } + return objPtr; +} + +XLS::BaseObjectPtr CConditionalFormattingRule::WriteAttributes14(const XLS::CellRef &cellRef) +{ + auto ptr(new XLSB::BeginCFRule14); + XLS::BaseObjectPtr objPtr(ptr); + if(m_oDxfId.IsInit()) + { + ptr->dxfId = m_oDxfId->GetValue(); + } + + if(m_oPriority.IsInit()) + ptr->iPri = m_oPriority->GetValue(); + if(m_oStopIfTrue.IsInit()) + ptr->fStopTrue = m_oStopIfTrue->GetValue(); + if(m_oAboveAverage.IsInit()) + ptr->fAbove = m_oAboveAverage->GetValue(); + if(m_oBottom.IsInit()) + ptr->fBottom = m_oBottom->GetValue(); + if(m_oPercent.IsInit()) + ptr->fPercent = m_oPercent->GetValue(); + if(m_oId.IsInit()) + { + ptr->fGuid = true; + ptr->guid = m_oId.get(); + } + if(m_oText.IsInit()) + ptr->strParam = m_oText.get(); + else + ptr->strParam.setSize(0xFFFFFFFF); + if(!m_arrFormula.empty()) + { + for(auto i:m_arrFormula) + { + if(i.IsInit()) + { + XLSB::FRTFormula tempFmla; + tempFmla.formula.set_base_ref(cellRef); + tempFmla.formula = i->m_sText; + ptr->FRTheader.rgFormulas.array.push_back(tempFmla); + } + } + if(!ptr->FRTheader.rgFormulas.array.empty()) + ptr->FRTheader.fFormula = true; + + if(m_oType == SimpleTypes::Spreadsheet::ECfType::colorScale || m_oType == SimpleTypes::Spreadsheet::ECfType::dataBar + || m_oType == SimpleTypes::Spreadsheet::ECfType::iconSet) + ptr->cbFmla3 = 1; + else + ptr->cbFmla1 = 1; + if(m_arrFormula.size() > 1) + ptr->cbFmla2 = 1; + } + + if(!m_arrFormula.empty() && !m_arrFormula.front()->m_sText.empty()) + { + ptr->cbFmla1 = 1; + } + else + { + ptr->cbFmla1 = 0; + } + if(!m_arrFormula.empty() && !m_arrFormula.front()->m_sText.empty()) + { + ptr->cbFmla2 = 1; + } + else + { + ptr->cbFmla2 = 0; + } + if(!m_arrFormula.empty() && !m_arrFormula.front()->m_sText.empty()) + { + ptr->cbFmla3 = 1; + } + else + { + ptr->cbFmla3 = 0; + } + + ptr->iType = XLSB::CFType::CF_TYPE_EXPRIS; + ptr->iParam =0; + ptr->iTemplate = XLSB::CFTemp::CF_TEMPLATE_EXPR; + if(!m_oType.IsInit()) + return objPtr; + if (m_oType == SimpleTypes::Spreadsheet::ECfType::cellIs) + { + if (m_oOperator == SimpleTypes::Spreadsheet::ECfOperator::Operator_between) + ptr->iParam = XLSB::CFOper::CF_OPER_BN; + else if (m_oOperator == SimpleTypes::Spreadsheet::ECfOperator::Operator_notBetween) + ptr->iParam = XLSB::CFOper::CF_OPER_NB; + else if (m_oOperator == SimpleTypes::Spreadsheet::ECfOperator::Operator_equal) + ptr->iParam = XLSB::CFOper::CF_OPER_EQ; + else if (m_oOperator == SimpleTypes::Spreadsheet::ECfOperator::Operator_notEqual) + ptr->iParam = XLSB::CFOper::CF_OPER_NE; + else if (m_oOperator == SimpleTypes::Spreadsheet::ECfOperator::Operator_greaterThan) + ptr->iParam = XLSB::CFOper::CF_OPER_GT; + else if (m_oOperator == SimpleTypes::Spreadsheet::ECfOperator::Operator_lessThan) + ptr->iParam = XLSB::CFOper::CF_OPER_LT; + else if (m_oOperator == SimpleTypes::Spreadsheet::ECfOperator::Operator_greaterThanOrEqual) + ptr->iParam = XLSB::CFOper::CF_OPER_GE; + else if (m_oOperator == SimpleTypes::Spreadsheet::ECfOperator::Operator_lessThanOrEqual) + ptr->iParam = XLSB::CFOper::CF_OPER_LE; + ptr->iType = XLSB::CFType::CF_TYPE_CELLIS; + ptr->iTemplate = XLSB::CFTemp::CF_TEMPLATE_EXPR; + } + + if (m_oType == SimpleTypes::Spreadsheet::ECfType::expression) + { + ptr->iTemplate = XLSB::CFTemp::CF_TEMPLATE_FMLA; + } + else if (m_oType == SimpleTypes::Spreadsheet::ECfType::uniqueValues) + { + ptr->iTemplate = XLSB::CFTemp::CF_TEMPLATE_UNIQUEVALUES; + } + else if (m_oType == SimpleTypes::Spreadsheet::ECfType::containsText) + { + ptr->iTemplate = XLSB::CFTemp::CF_TEMPLATE_CONTAINSTEXT; + ptr->iParam = XLSB::CFTextOper::CF_TEXTOPER_CONTAINS; + } + else if (m_oType == SimpleTypes::Spreadsheet::ECfType::notContainsText) + { + ptr->iTemplate = XLSB::CFTemp::CF_TEMPLATE_CONTAINSTEXT; + ptr->iParam = XLSB::CFTextOper::CF_TEXTOPER_NOTCONTAINS; + } + else if (m_oType == SimpleTypes::Spreadsheet::ECfType::beginsWith) + { + ptr->iTemplate = XLSB::CFTemp::CF_TEMPLATE_CONTAINSTEXT; + ptr->iParam = XLSB::CFTextOper::CF_TEXTOPER_BEGINSWITH; + } + else if (m_oType == SimpleTypes::Spreadsheet::ECfType::endsWith) + { + ptr->iTemplate = XLSB::CFTemp::CF_TEMPLATE_CONTAINSTEXT; + ptr->iParam = XLSB::CFTextOper::CF_TEXTOPER_ENDSWITH; + } + else if (m_oType == SimpleTypes::Spreadsheet::ECfType::containsBlanks) + { + ptr->iTemplate = XLSB::CFTemp::CF_TEMPLATE_CONTAINSBLANKS; + } + else if (m_oType == SimpleTypes::Spreadsheet::ECfType::notContainsBlanks) + { + ptr->iTemplate = XLSB::CFTemp::CF_TEMPLATE_CONTAINSNOBLANKS; + } + else if (m_oType == SimpleTypes::Spreadsheet::ECfType::containsErrors) + { + ptr->iTemplate = XLSB::CFTemp::CF_TEMPLATE_CONTAINSERRORS; + } + else if (m_oType == SimpleTypes::Spreadsheet::ECfType::notContainsErrors) + { + ptr->iTemplate = XLSB::CFTemp::CF_TEMPLATE_CONTAINSNOERRORS; + } + + else if (m_oType == SimpleTypes::Spreadsheet::ECfType::timePeriod) + { + if (m_oTimePeriod == SimpleTypes::Spreadsheet::ETimePeriod::today) + { + ptr->iTemplate = XLSB::CFTemp::CF_TEMPLATE_TIMEPERIODTODAY; + ptr->iParam = XLSB::CFDateOper::CF_TIMEPERIOD_TODAY; + } + else if (m_oTimePeriod == SimpleTypes::Spreadsheet::ETimePeriod::tomorrow) + { + ptr->iTemplate = XLSB::CFTemp::CF_TEMPLATE_TIMEPERIODTOMORROW; + ptr->iParam = XLSB::CFDateOper::CF_TIMEPERIOD_TOMORROW; + } + else if (m_oTimePeriod == SimpleTypes::Spreadsheet::ETimePeriod::yesterday) + { + ptr->iTemplate = XLSB::CFTemp::CF_TEMPLATE_TIMEPERIODYESTERDAY; + ptr->iParam = XLSB::CFDateOper::CF_TIMEPERIOD_YESTERDAY; + } + else if (m_oTimePeriod == SimpleTypes::Spreadsheet::ETimePeriod::last7Days) + { + ptr->iTemplate = XLSB::CFTemp::CF_TEMPLATE_TIMEPERIODLAST7DAYS; + ptr->iParam = XLSB::CFDateOper::CF_TIMEPERIOD_LAST7DAYS; + } + else if (m_oTimePeriod == SimpleTypes::Spreadsheet::ETimePeriod::lastMonth) + { + ptr->iTemplate = XLSB::CFTemp::CF_TEMPLATE_TIMEPERIODLASTMONTH; + ptr->iParam = XLSB::CFDateOper::CF_TIMEPERIOD_LASTMONTH; + } + else if (m_oTimePeriod == SimpleTypes::Spreadsheet::ETimePeriod::nextMonth) + { + ptr->iTemplate = XLSB::CFTemp::CF_TEMPLATE_TIMEPERIODNEXTMONTH; + ptr->iParam = XLSB::CFDateOper::CF_TIMEPERIOD_NEXTMONTH; + } + else if (m_oTimePeriod == SimpleTypes::Spreadsheet::ETimePeriod::thisWeek) + { + ptr->iTemplate = XLSB::CFTemp::CF_TEMPLATE_TIMEPERIODTHISWEEK; + ptr->iParam = XLSB::CFDateOper::CF_TIMEPERIOD_THISWEEK; + } + else if (m_oTimePeriod == SimpleTypes::Spreadsheet::ETimePeriod::nextWeek) + { + ptr->iTemplate = XLSB::CFTemp::CF_TEMPLATE_TIMEPERIODNEXTWEEK; + ptr->iParam = XLSB::CFDateOper::CF_TIMEPERIOD_NEXTWEEK; + } + else if (m_oTimePeriod == SimpleTypes::Spreadsheet::ETimePeriod::lastWeek) + { + ptr->iTemplate = XLSB::CFTemp::CF_TEMPLATE_TIMEPERIODLASTWEEK; + ptr->iParam = XLSB::CFDateOper::CF_TIMEPERIOD_LASTWEEK; + } + else if (m_oTimePeriod == SimpleTypes::Spreadsheet::ETimePeriod::thisMonth) + { + ptr->iTemplate = XLSB::CFTemp::CF_TEMPLATE_TIMEPERIODTHISMONTH; + ptr->iParam = XLSB::CFDateOper::CF_TIMEPERIOD_THISMONTH; + } + } + + else if (m_oType == SimpleTypes::Spreadsheet::ECfType::aboveAverage) + { + ptr->iTemplate = XLSB::CFTemp::CF_TEMPLATE_ABOVEAVERAGE; + if(m_oStdDev.IsInit()) + ptr->iParam = m_oStdDev->GetValue(); + else + ptr->iParam = 0; + } + else if (m_oType == SimpleTypes::Spreadsheet::ECfType::duplicateValues) + { + ptr->iTemplate = XLSB::CFTemp::CF_TEMPLATE_DUPLICATEVALUES; + } + else if (m_oType == SimpleTypes::Spreadsheet::ECfType::colorScale) + { + ptr->iType = XLSB::CFType::CF_TYPE_GRADIENT; + ptr->iTemplate = XLSB::CFTemp::CF_TEMPLATE_GRADIENT; + ptr->dxfId = 0xFFFFFFFF; + } + else if (m_oType == SimpleTypes::Spreadsheet::ECfType::dataBar) + { + ptr->iType = XLSB::CFType::CF_TYPE_DATABAR; + ptr->iTemplate = XLSB::CFTemp::CF_TEMPLATE_DATABAR; + ptr->dxfId = 0xFFFFFFFF; + } + else if (m_oType == SimpleTypes::Spreadsheet::ECfType::iconSet) + { + ptr->iType = XLSB::CFType::CF_TYPE_MULTISTATE; + ptr->iTemplate = XLSB::CFTemp::CF_TEMPLATE_MULTISTATE; + } + else if (m_oType == SimpleTypes::Spreadsheet::ECfType::top10) + { + ptr->iType = XLSB::CFType::CF_TYPE_FILTER; + if(m_oRank.IsInit()) + ptr->iParam = m_oRank->GetValue(); + else + ptr->iParam = 1; + ptr->iTemplate = XLSB::CFTemp::CF_TEMPLATE_FILTER; + } + return objPtr; +} + template nullable CConditionalFormattingRule::Merge(const nullable &oPrev, const nullable &oCurrent) { @@ -1572,7 +2641,7 @@ nullable CConditionalFormattingRule::Merge(const nullable &oPrev, co const CConditionalFormattingRule CConditionalFormattingRule::Merge(const CConditionalFormattingRule& oPrev, const CConditionalFormattingRule& oCurrent) { CConditionalFormattingRule oRule; - + oRule.m_oAboveAverage = Merge( oPrev.m_oAboveAverage, oCurrent.m_oAboveAverage ); oRule.m_oBottom = Merge( oPrev.m_oBottom, oCurrent.m_oBottom ); oRule.m_oDxfId = Merge( oPrev.m_oDxfId, oCurrent.m_oDxfId ); @@ -1604,7 +2673,7 @@ const CConditionalFormattingRule CConditionalFormattingRule::Merge(const CCondit oRule.m_oColorScale = Merge( oPrev.m_oColorScale, oCurrent.m_oColorScale ); if (oPrev.m_oDataBar.IsInit() && oCurrent.m_oDataBar.IsInit()) - oRule.m_oDataBar = CDataBar::Merge ( oPrev.m_oDataBar.get(), oCurrent.m_oDataBar.get()); + oRule.m_oDataBar = CDataBar::Merge ( oPrev.m_oDataBar.get(), oCurrent.m_oDataBar.get()); else oRule.m_oDataBar = Merge( oPrev.m_oDataBar, oCurrent.m_oDataBar ); @@ -2129,7 +3198,7 @@ bool CConditionalFormatting::IsExtended() { m_bIsExtended = false; m_bIsValid = false; - + if (m_oSqRef.IsInit() == false) return m_bIsExtended; m_bIsValid = true; @@ -2137,7 +3206,7 @@ bool CConditionalFormatting::IsExtended() for ( size_t i = 0; i < m_arrItems.size(); ++i) { if ( !m_arrItems[i]) continue; - + if (m_arrItems[i]->isValid() == false) m_bIsValid = false; if (m_arrItems[i]->isExtended() == true) @@ -2146,7 +3215,7 @@ bool CConditionalFormatting::IsExtended() return m_bIsExtended; } void CConditionalFormatting::toXML2(NSStringUtils::CStringBuilder& writer, bool bExtendedWrite) const -{ +{ std::wstring node_name = bExtendedWrite ? L"x14:conditionalFormatting" : L"conditionalFormatting"; writer.WriteString(L"<" + node_name); @@ -2163,7 +3232,7 @@ void CConditionalFormatting::toXML2(NSStringUtils::CStringBuilder& writer, bool writer.WriteString(L" pivot=\"1\""); } writer.WriteString(L">"); - + for ( size_t i = 0; i < m_arrItems.size(); ++i) { if ( m_arrItems[i] ) @@ -2225,7 +3294,74 @@ void CConditionalFormatting::fromBin(XLS::BaseObjectPtr& obj) for(auto &pCFRULE14: ptr->m_arCFRULE14) m_arrItems.push_back(new CConditionalFormattingRule(pCFRULE14)); } + IsExtended(); } + +XLS::BaseObjectPtr CConditionalFormatting::toBin() +{ + XLS::BaseObjectPtr objectPtr; + if(m_arrItems.empty()) + { + return objectPtr; + } + auto ptr(new XLSB::CONDITIONALFORMATTING); + objectPtr = XLS::BaseObjectPtr{ptr}; + XLS::CellRef formatingfirstCell; + + auto conditionPtr(new XLSB::BeginConditionalFormatting); + ptr->m_BrtBeginConditionalFormatting = XLS::BaseObjectPtr{conditionPtr}; + conditionPtr->ccf = m_arrItems.size(); + if(m_oSqRef.IsInit()) + { + conditionPtr->sqrfx.strValue = m_oSqRef.get(); + } + else + conditionPtr->sqrfx.crfx = 0; + if(m_oPivot.IsInit()) + conditionPtr->fPivot = m_oPivot->GetValue(); + else + conditionPtr->fPivot = false; + formatingfirstCell = conditionPtr->sqrfx.getLocationFirstCell(); + + for(auto i: m_arrItems) + { + ptr->m_arCFRULE.push_back(i->toBin(formatingfirstCell)); + } + return objectPtr; +} + +XLS::BaseObjectPtr CConditionalFormatting::toBin14() +{ + auto ptr(new XLSB::CONDITIONALFORMATTING14); + auto ptr1(new XLSB::BeginConditionalFormatting14); + ptr->m_BrtBeginConditionalFormatting14 = XLS::BaseObjectPtr{ptr1}; + XLS::BaseObjectPtr objectPtr = XLS::BaseObjectPtr{ptr}; + + ptr1->FRTheader.fFormula = false; + ptr1->FRTheader.fRelID = false; + ptr1->FRTheader.fRef = false; + ptr1->FRTheader.fSqref = true; + XLS::CellRef formatingfirstCell; + if(m_oSqRef.IsInit()) + { + XLSB::FRTSqref sqref; + sqref.sqrfx.strValue = m_oSqRef.get(); + ptr1->FRTheader.rgSqrefs.array.push_back(sqref); + formatingfirstCell = sqref.sqrfx.getLocationFirstCell(); + } + ptr1->ccf = m_arrItems.size(); + if(m_oPivot.IsInit()) + ptr1->fPivot = m_oPivot->GetValue(); + else + ptr1->fPivot = false; + + for(auto i: m_arrItems) + { + ptr->m_arCFRULE14.push_back(i->toBin14(formatingfirstCell)); + } + return objectPtr; +} + bool CConditionalFormatting::IsUsage() { for ( size_t i = 0; i < m_arrItems.size(); ++i) diff --git a/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.h b/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.h index 14d011972b7..ac850d2fdd7 100644 --- a/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.h +++ b/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.h @@ -33,6 +33,7 @@ #include "../WritingElement.h" #include "../../Base/Nullable.h" +#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CellRef.h" namespace SimpleTypes { @@ -106,6 +107,8 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(const bool isIcon = false); + XLS::BaseObjectPtr toBin14(const bool isIcon = false); virtual EElementType getType () const; bool isExtended (); @@ -166,6 +169,8 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); + XLS::BaseObjectPtr toBin14(); virtual EElementType getType () const; @@ -199,6 +204,8 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); + XLS::BaseObjectPtr toBin14(); virtual EElementType getType () const; @@ -214,7 +221,7 @@ namespace OOX nullable m_oMaxLength; nullable m_oMinLength; nullable m_oShowValue; - + nullable m_oColor; std::vector> m_arrValues; @@ -229,7 +236,7 @@ namespace OOX nullable m_oAxisColor; nullable m_oBorderColor; - + nullable m_oNegativeFillColor; nullable m_oNegativeBorderColor; }; @@ -251,6 +258,8 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); + XLS::BaseObjectPtr toBin14(); virtual EElementType getType () const; @@ -295,6 +304,8 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(const XLS::CellRef &cellRef); + XLS::BaseObjectPtr toBin14(const XLS::CellRef &cellRef); virtual EElementType getType () const; bool isValid () const; @@ -306,6 +317,8 @@ namespace OOX private: void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); void ReadAttributes(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr WriteAttributes(const XLS::CellRef &cellRef); + XLS::BaseObjectPtr WriteAttributes14(const XLS::CellRef &cellRef); public: nullable m_oDxf; @@ -323,7 +336,7 @@ namespace OOX nullable m_oText; nullable m_oTimePeriod; nullable m_oType; - + nullable m_oExtLst; nullable_string m_oExtId; @@ -353,10 +366,13 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); + XLS::BaseObjectPtr toBin14(); + virtual EElementType getType () const; bool IsUsage(); - + private: void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); void ReadAttributes(XLS::BaseObjectPtr& obj); diff --git a/OOXML/XlsxFormat/Worksheets/DataValidation.cpp b/OOXML/XlsxFormat/Worksheets/DataValidation.cpp index 2f4679f6de7..75f165dbd26 100644 --- a/OOXML/XlsxFormat/Worksheets/DataValidation.cpp +++ b/OOXML/XlsxFormat/Worksheets/DataValidation.cpp @@ -155,23 +155,42 @@ namespace OOX } else { + if (m_oList.IsInit()) + { + writer.WriteString(L""); + + writer.WriteString(L""); + writer.WriteString(L"" + *m_oList + L""); + writer.WriteString(L""); + + writer.WriteString(L""); + } if (m_oFormula1.IsInit()) { writer.WriteString(L""); - writer.WriteString(m_oFormula1->m_sText); + writer.WriteEncodeXmlString(m_oFormula1->m_sText); writer.WriteString(L""); } if (m_oFormula2.IsInit()) { writer.WriteString(L""); - writer.WriteString(m_oFormula2->m_sText); + writer.WriteEncodeXmlString(m_oFormula2->m_sText); writer.WriteString(L""); } + if (m_oList.IsInit()) + { + writer.WriteString(L""); + writer.WriteString(L""); + } } writer.WriteString(L""); } bool CDataValidation::IsExtended() { + if (m_oList.IsInit()) return false; + bool result1 = true, result2 = true; if (m_oFormula1.IsInit()) { @@ -193,6 +212,123 @@ namespace OOX return result1 || result2; } + XLS::BaseObjectPtr CDataValidation::toBin() + { + auto ptr(new XLSB::DVal); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oType.IsInit()) + { + if (m_oType->GetValue() == SimpleTypes::Spreadsheet::EDataValidationType::validationTypeNone) + ptr->valType = XLS::typeDvNone; + else if (m_oType->GetValue() == SimpleTypes::Spreadsheet::EDataValidationType::validationTypeWhole) + ptr->valType = XLS::typeDvWhole; + else if (m_oType->GetValue() == SimpleTypes::Spreadsheet::EDataValidationType::validationTypeDecimal) + ptr->valType = XLS::typeDvDecimal; + else if (m_oType->GetValue() == SimpleTypes::Spreadsheet::EDataValidationType::validationTypeList) + ptr->valType = XLS::typeDvList; + else if (m_oType->GetValue() == SimpleTypes::Spreadsheet::EDataValidationType::validationTypeDate) + ptr->valType = XLS::typeDvDate; + else if (m_oType->GetValue() == SimpleTypes::Spreadsheet::EDataValidationType::validationTypeTime) + ptr->valType = XLS::typeDvTime; + else if (m_oType->GetValue() == SimpleTypes::Spreadsheet::EDataValidationType::validationTypeTextLength) + ptr->valType = XLS::typeDvTextLength; + else if (m_oType->GetValue() == SimpleTypes::Spreadsheet::EDataValidationType::validationTypeCustom) + ptr->valType = XLS::typeDvCustom; + else + ptr->valType = XLS::typeDvNone; + } + else + ptr->valType = XLS::typeDvNone; + if(m_oAllowBlank.IsInit()) + ptr->fAllowBlank = m_oAllowBlank->GetValue(); + else + ptr->fAllowBlank = false; + if(m_oError.IsInit()) + ptr->Error = m_oError.get(); + else + ptr->Error = L""; + + if (m_oErrorTitle.IsInit()) + ptr->ErrorTitle = m_oErrorTitle.get(); + else + ptr->ErrorTitle = L""; + + if (m_oPrompt.IsInit()) + ptr->Prompt = m_oPrompt.get(); + else + ptr->Prompt = L""; + + if (m_oPromptTitle.IsInit()) + ptr->PromptTitle = m_oPromptTitle.get(); + else + ptr->PromptTitle = L""; + if(m_oErrorStyle.IsInit()) + ptr->errStyle = m_oErrorStyle->GetValue(); + else + ptr->errStyle = 0; + if(m_oImeMode.IsInit()) + { + if(m_oImeMode == SimpleTypes::Spreadsheet::EDataValidationImeMode::imeModeOn) + { + ptr->mdImeMode = 0x01; + } + else if(m_oImeMode == SimpleTypes::Spreadsheet::EDataValidationImeMode::imeModeOff) + { + ptr->mdImeMode = 0x02; + } + else + { + ptr->mdImeMode = m_oImeMode->GetValue(); + } + } + else + ptr->mdImeMode = 0; + if(m_oOperator.IsInit()) + { + if (m_oOperator->GetValue() == SimpleTypes::Spreadsheet::EDataValidationOperator::operatorBetween) + ptr->typOperator = XLS::_typOperatorDv::operatorDvBetween; + else if (m_oOperator->GetValue() == SimpleTypes::Spreadsheet::EDataValidationOperator::operatorNotBetween) + ptr->typOperator = XLS::_typOperatorDv::operatorDvNotBetween; + else if (m_oOperator->GetValue() == SimpleTypes::Spreadsheet::EDataValidationOperator::operatorEqual) + ptr->typOperator = XLS::_typOperatorDv::operatorDvEquals; + else if (m_oOperator->GetValue() == SimpleTypes::Spreadsheet::EDataValidationOperator::operatorNotEqual) + ptr->typOperator = XLS::_typOperatorDv::operatorDvNotEquals; + else if (m_oOperator->GetValue() == SimpleTypes::Spreadsheet::EDataValidationOperator::operatorGreaterThan) + ptr->typOperator = XLS::_typOperatorDv::operatorDvGreaterThan; + else if (m_oOperator->GetValue() == SimpleTypes::Spreadsheet::EDataValidationOperator::operatorLessThan) + ptr->typOperator = XLS::_typOperatorDv::operatorDvLessThan; + else if (m_oOperator->GetValue() == SimpleTypes::Spreadsheet::EDataValidationOperator::operatorGreaterThanOrEqual) + ptr->typOperator = XLS::_typOperatorDv::operatorDvGreaterThanOrEqual; + else if (m_oOperator->GetValue() == SimpleTypes::Spreadsheet::EDataValidationOperator::operatorLessThanOrEqual) + ptr->typOperator = XLS::_typOperatorDv::operatorDvLessThanOrEqual; + else + ptr->typOperator = XLS::_typOperatorDv::operatorDvBetween; + } + else + ptr->typOperator = XLS::_typOperatorDv::operatorDvBetween; + + if(m_oShowDropDown.IsInit()) + ptr->fSuppressCombo = m_oShowDropDown->GetValue(); + else + ptr->fSuppressCombo = false; + if(m_oShowErrorMessage.IsInit()) + ptr->fShowErrorMsg = m_oShowErrorMessage->GetValue(); + else + ptr->fShowErrorMsg = false; + if(m_oShowInputMessage.IsInit()) + ptr->fShowInputMsg = m_oShowInputMessage->GetValue(); + else + ptr->fShowInputMsg = false; + if(m_oSqRef.IsInit()) + ptr->sqrfx.strValue = m_oSqRef.get(); + + if(m_oFormula1.IsInit()) + ptr->formula1 = m_oFormula1->m_sText; + if(m_oFormula2.IsInit()) + ptr->formula2 = m_oFormula2->m_sText; + + return objectPtr; + } void CDataValidation::fromBin(XLS::BaseObjectPtr& obj) { ReadAttributes(obj); @@ -497,6 +633,35 @@ namespace OOX } m_oCount = m_arrItems.size(); } + XLS::BaseObjectPtr CDataValidations::toBin() + { + XLS::BaseObjectPtr objectPtr; + auto ptr(new XLSB::DVALS); + objectPtr = XLS::BaseObjectPtr{ptr}; + + auto beginPtr(new XLSB::BeginDVals); + ptr->m_BrtBeginDVals = XLS::BaseObjectPtr{beginPtr}; + if(m_oDisablePrompts.IsInit()) + beginPtr->dVals.fWnClosed = m_oDisablePrompts->GetValue(); + else + beginPtr->dVals.fWnClosed = false; + if(m_oXWindow.IsInit()) + beginPtr->dVals.xLeft = m_oXWindow->GetValue(); + else + beginPtr->dVals.xLeft = 0; + if(m_oYWindow.IsInit()) + beginPtr->dVals.yTop = m_oYWindow->GetValue(); + else + beginPtr->dVals.yTop = false; + + for(auto i:m_arrItems) + { + ptr->m_arBrtDVal.push_back(i->toBin()); + } + beginPtr->dVals.idvMac = ptr->m_arBrtDVal.size(); + + return objectPtr; + } void CDataValidations::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) { WritingElement_ReadAttributes_Start( oReader ) diff --git a/OOXML/XlsxFormat/Worksheets/DataValidation.h b/OOXML/XlsxFormat/Worksheets/DataValidation.h index bc46c90b068..ef29895d7f0 100644 --- a/OOXML/XlsxFormat/Worksheets/DataValidation.h +++ b/OOXML/XlsxFormat/Worksheets/DataValidation.h @@ -63,10 +63,10 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlNode& node); virtual std::wstring toXML() const; - void toXML2(NSStringUtils::CStringBuilder& writer, bool bExtendedWrite) const; + void toXML2(NSStringUtils::CStringBuilder& writer, bool bExtendedWrite) const; virtual void toXML(NSStringUtils::CStringBuilder& writer) const; - virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); virtual EElementType getType () const; std::wstring m_sNodeName; @@ -84,12 +84,15 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlNode& node); virtual std::wstring toXML() const; + void CreateElements(XmlUtils::CXmlLiteReader& oReader, int Depth); virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + virtual void toXML(NSStringUtils::CStringBuilder& writer) const; void toXML2(NSStringUtils::CStringBuilder& writer, bool bExtendedWrite) const; bool IsExtended(); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); @@ -111,7 +114,7 @@ namespace OOX nullable m_oShowInputMessage; nullable_string m_oSqRef; // ToDo переделать на тип "sqref" (18.18.76) - последовательность "ref", разделенные пробелом - + nullable_string m_oList; mutable nullable_string m_oUuid; nullable m_oFormula1; nullable m_oFormula2; @@ -133,6 +136,7 @@ namespace OOX void toXML2(NSStringUtils::CStringBuilder& writer, bool bExtendedWrite) const; void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; private: diff --git a/OOXML/XlsxFormat/Worksheets/Hyperlinks.h b/OOXML/XlsxFormat/Worksheets/Hyperlinks.h index a04c61a30bc..1e548d960da 100644 --- a/OOXML/XlsxFormat/Worksheets/Hyperlinks.h +++ b/OOXML/XlsxFormat/Worksheets/Hyperlinks.h @@ -59,6 +59,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; private: @@ -90,6 +91,8 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(std::vector& obj); + XLS::BaseObjectPtr toBin(); + virtual EElementType getType () const; }; diff --git a/OOXML/XlsxFormat/Worksheets/MergeCells.cpp b/OOXML/XlsxFormat/Worksheets/MergeCells.cpp index 4d0cfd34462..911b6499df6 100644 --- a/OOXML/XlsxFormat/Worksheets/MergeCells.cpp +++ b/OOXML/XlsxFormat/Worksheets/MergeCells.cpp @@ -34,6 +34,8 @@ #include "../../Common/SimpleTypes_Shared.h" #include "../../XlsbFormat/Biff12_records/MergeCell.h" +#include "../../XlsbFormat/Biff12_records/BeginMergeCells.h" +#include "../../XlsbFormat/Biff12_unions/MERGECELLS.h" namespace OOX { @@ -69,6 +71,13 @@ namespace OOX { ReadAttributes(obj); } + XLS::BaseObjectPtr CMergeCell::toBin() + { + auto castedPtr(new XLSB::MergeCell); + XLS::BaseObjectPtr ptr(castedPtr); + castedPtr->rfx = m_oRef.get(); + return ptr; + } EElementType CMergeCell::getType () const { return et_x_MergeCell; @@ -82,7 +91,7 @@ namespace OOX void CMergeCell::ReadAttributes(XLS::BaseObjectPtr& obj) { auto ptr = static_cast(obj.get()); - m_oRef = ptr->rfx.toString(); + m_oRef = ptr->rfx.toString(true, true); } CMergeCells::CMergeCells(OOX::Document *pMain) : WritingElementWithChilds(pMain) @@ -152,6 +161,19 @@ namespace OOX pMergeCell->fromBin(mergeCell); } } + XLS::BaseObjectPtr CMergeCells::toBin() + { + auto castedPtr(new XLSB::MERGECELLS); + auto beginCells(new XLSB::BeginMergeCells); + castedPtr->m_BrtBeginMergeCells = XLS::BaseObjectPtr{beginCells}; + XLS::BaseObjectPtr ptr(castedPtr); + for(auto i:m_arrItems) + { + castedPtr->m_arBrtMergeCell.push_back(i->toBin()); + } + beginCells->cmcs = castedPtr->m_arBrtMergeCell.size(); + return ptr; + } EElementType CMergeCells::getType () const { return et_x_MergeCells; diff --git a/OOXML/XlsxFormat/Worksheets/MergeCells.h b/OOXML/XlsxFormat/Worksheets/MergeCells.h index c761e0ea755..ce9064f602d 100644 --- a/OOXML/XlsxFormat/Worksheets/MergeCells.h +++ b/OOXML/XlsxFormat/Worksheets/MergeCells.h @@ -59,6 +59,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; private: @@ -83,6 +84,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + XLS::BaseObjectPtr toBin(); void fromBin(std::vector& obj); virtual EElementType getType () const; diff --git a/OOXML/XlsxFormat/Worksheets/SheetData.cpp b/OOXML/XlsxFormat/Worksheets/SheetData.cpp index e8f9f4f1e32..c35f014fb2f 100644 --- a/OOXML/XlsxFormat/Worksheets/SheetData.cpp +++ b/OOXML/XlsxFormat/Worksheets/SheetData.cpp @@ -38,6 +38,7 @@ #include "../../DocxFormat/VmlDrawing.h" #include "../Styles/Styles.h" #include "../Styles/Xfs.h" +#include "../Styles/NumFmts.h" #include "../SharedStrings/SharedStrings.h" #include "DataValidation.h" #include "../Comments/ThreadedComments.h" @@ -61,35 +62,49 @@ #include "../../XlsbFormat/Biff12_records/ValueMeta.h" #include "../../XlsbFormat/Biff12_records/Cell.h" #include "../../XlsbFormat/Biff12_records/Fmla.h" +#include "../../XlsbFormat/Biff12_structures/GrbitFmla.h" #include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_structures/BIFF12/CellRef.h" +#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgArea.h" +#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgRef.h" +#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgExp.h" +#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgExtraCol.h" +#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgList.h" #include #include #include +#include + +#ifndef MININT32 +#define MAXUINT32 ((uint32_t)~((uint32_t)0)) +#define MAXINT32 ((int32_t)(MAXUINT32 >> 1)) +#define MININT32 ((int32_t)~MAXINT32) +#endif + using namespace XLS; namespace OOX { namespace Spreadsheet { - static const wchar_t* m_aLetters[] = - { - L"A", L"B", L"C", L"D", L"E", L"F", L"G", L"H", L"I", L"J", L"K", L"L", L"M", L"N", L"O", L"P", L"Q", L"R", L"S", L"T", L"U", L"V", L"W", L"X", L"Y", L"Z", L"AA", L"AB", L"AC", L"AD", L"AE", L"AF", L"AG", L"AH", L"AI", L"AJ", L"AK", L"AL", L"AM", L"AN", L"AO", L"AP", L"AQ", L"AR", L"AS", L"AT", L"AU", L"AV", L"AW", L"AX", L"AY", L"AZ", L"BA", L"BB", L"BC", L"BD", L"BE", L"BF", L"BG", L"BH", L"BI", L"BJ", L"BK", L"BL", L"BM", L"BN", L"BO", L"BP", L"BQ", L"BR", L"BS", L"BT", L"BU", L"BV", L"BW", L"BX", L"BY", L"BZ", L"CA", L"CB", L"CC", L"CD", L"CE", L"CF", L"CG", L"CH", L"CI", L"CJ", L"CK", L"CL", L"CM", L"CN", L"CO", L"CP", L"CQ", L"CR", L"CS", L"CT", L"CU", L"CV", L"CW", L"CX", L"CY", L"CZ", L"DA", L"DB", L"DC", L"DD", L"DE", L"DF", L"DG", L"DH", L"DI", L"DJ", L"DK", L"DL", L"DM", L"DN", L"DO", L"DP", L"DQ", L"DR", L"DS", L"DT", L"DU", L"DV", L"DW", L"DX", L"DY", L"DZ", L"EA", L"EB", L"EC", L"ED", L"EE", L"EF", L"EG", L"EH", L"EI", L"EJ", L"EK", L"EL", L"EM", L"EN", L"EO", L"EP", L"EQ", L"ER", L"ES", L"ET", L"EU", L"EV", L"EW", L"EX", L"EY", L"EZ", L"FA", L"FB", L"FC", L"FD", L"FE", L"FF", L"FG", L"FH", L"FI", L"FJ", L"FK", L"FL", L"FM", L"FN", L"FO", L"FP", L"FQ", L"FR", L"FS", L"FT", L"FU", L"FV", L"FW", L"FX", L"FY", L"FZ", L"GA", L"GB", L"GC", L"GD", L"GE", L"GF", L"GG", L"GH", L"GI", L"GJ", L"GK", L"GL", L"GM", L"GN", L"GO", L"GP", L"GQ", L"GR", L"GS", L"GT", L"GU", L"GV", L"GW", L"GX", L"GY", L"GZ", L"HA", L"HB", L"HC", L"HD", L"HE", L"HF", L"HG", L"HH", L"HI", L"HJ", L"HK", L"HL", L"HM", L"HN", L"HO", L"HP", L"HQ", L"HR", L"HS", L"HT", L"HU", L"HV", L"HW", L"HX", L"HY", L"HZ", L"IA", L"IB", L"IC", L"ID", L"IE", L"IF", L"IG", L"IH", L"II", L"IJ", L"IK", L"IL", L"IM", L"IN", L"IO", L"IP", L"IQ", L"IR", L"IS", L"IT", L"IU", L"IV", L"IW", L"IX", L"IY", L"IZ", L"JA", L"JB", L"JC", L"JD", L"JE", L"JF", L"JG", L"JH", L"JI", L"JJ", L"JK", L"JL", L"JM", L"JN", L"JO", L"JP", L"JQ", L"JR", L"JS", L"JT", L"JU", L"JV", L"JW", L"JX", L"JY", L"JZ", L"KA", L"KB", L"KC", L"KD", L"KE", L"KF", L"KG", L"KH", L"KI", L"KJ", L"KK", L"KL", L"KM", L"KN", L"KO", L"KP", L"KQ", L"KR", L"KS", L"KT", L"KU", L"KV", L"KW", L"KX", L"KY", L"KZ", L"LA", L"LB", L"LC", L"LD", L"LE", L"LF", L"LG", L"LH", L"LI", L"LJ", L"LK", L"LL", L"LM", L"LN", L"LO", L"LP", L"LQ", L"LR", L"LS", L"LT", L"LU", L"LV", L"LW", L"LX", L"LY", L"LZ", L"MA", L"MB", L"MC", L"MD", L"ME", L"MF", L"MG", L"MH", L"MI", L"MJ", L"MK", L"ML", L"MM", L"MN", L"MO", L"MP", L"MQ", L"MR", L"MS", L"MT", L"MU", L"MV", L"MW", L"MX", L"MY", L"MZ", L"NA", L"NB", L"NC", L"ND", L"NE", L"NF", L"NG", L"NH", L"NI", L"NJ", L"NK", L"NL", L"NM", L"NN", L"NO", L"NP", L"NQ", L"NR", L"NS", L"NT", L"NU", L"NV", L"NW", L"NX", L"NY", L"NZ", L"OA", L"OB", L"OC", L"OD", L"OE", L"OF", L"OG", L"OH", L"OI", L"OJ", L"OK", L"OL", L"OM", L"ON", L"OO", L"OP", L"OQ", L"OR", L"OS", L"OT", L"OU", L"OV", L"OW", L"OX", L"OY", L"OZ", L"PA", L"PB", L"PC", L"PD", L"PE", L"PF", L"PG", L"PH", L"PI", L"PJ", L"PK", L"PL", L"PM", L"PN", L"PO", L"PP", L"PQ", L"PR", L"PS", L"PT", L"PU", L"PV", L"PW", L"PX", L"PY", L"PZ", L"QA", L"QB", L"QC", L"QD", L"QE", L"QF", L"QG", L"QH", L"QI", L"QJ", L"QK", L"QL", L"QM", L"QN", L"QO", L"QP", L"QQ", L"QR", L"QS", L"QT", L"QU", L"QV", L"QW", L"QX", L"QY", L"QZ", L"RA", L"RB", L"RC", L"RD", L"RE", L"RF", L"RG", L"RH", L"RI", L"RJ", L"RK", L"RL", L"RM", L"RN", L"RO", L"RP", L"RQ", L"RR", L"RS", L"RT", L"RU", L"RV", L"RW", L"RX", L"RY", L"RZ", L"SA", L"SB", L"SC", L"SD", L"SE", L"SF", L"SG", L"SH", L"SI", L"SJ", L"SK", L"SL", L"SM", L"SN", L"SO", L"SP", L"SQ", L"SR", L"SS", L"ST", L"SU", L"SV", L"SW", L"SX", L"SY", L"SZ", L"TA", L"TB", L"TC", L"TD", L"TE", L"TF", L"TG", L"TH", L"TI", L"TJ", L"TK", L"TL", L"TM", L"TN", L"TO", L"TP", L"TQ", L"TR", L"TS", L"TT", L"TU", L"TV", L"TW", L"TX", L"TY", L"TZ", L"UA", L"UB", L"UC", L"UD", L"UE", L"UF", L"UG", L"UH", L"UI", L"UJ", L"UK", L"UL", L"UM", L"UN", L"UO", L"UP", L"UQ", L"UR", L"US", L"UT", L"UU", L"UV", L"UW", L"UX", L"UY", L"UZ", L"VA", L"VB", L"VC", L"VD", L"VE", L"VF", L"VG", L"VH", L"VI", L"VJ", L"VK", L"VL", L"VM", L"VN", L"VO", L"VP", L"VQ", L"VR", L"VS", L"VT", L"VU", L"VV", L"VW", L"VX", L"VY", L"VZ", L"WA", L"WB", L"WC", L"WD", L"WE", L"WF", L"WG", L"WH", L"WI", L"WJ", L"WK", L"WL", L"WM", L"WN", L"WO", L"WP", L"WQ", L"WR", L"WS", L"WT", L"WU", L"WV", L"WW", L"WX", L"WY", - L"WZ", L"XA", L"XB", L"XC", L"XD", L"XE", L"XF", L"XG", L"XH", L"XI", L"XJ", L"XK", L"XL", L"XM", L"XN", L"XO", L"XP", L"XQ", L"XR", L"XS", L"XT", L"XU", L"XV", L"XW", L"XX", L"XY", L"XZ", L"YA", L"YB", L"YC", L"YD", L"YE", L"YF", L"YG", L"YH", L"YI", L"YJ", L"YK", L"YL", L"YM", L"YN", L"YO", L"YP", L"YQ", L"YR", L"YS", L"YT", L"YU", L"YV", L"YW", L"YX", L"YY", L"YZ", L"ZA", L"ZB", L"ZC", L"ZD", L"ZE", L"ZF", L"ZG", L"ZH", L"ZI", L"ZJ", L"ZK", L"ZL", L"ZM", L"ZN", L"ZO", L"ZP", L"ZQ", L"ZR", L"ZS", L"ZT", L"ZU", L"ZV", L"ZW", L"ZX", L"ZY", L"ZZ", L"AAA", L"AAB", L"AAC", L"AAD", L"AAE", L"AAF", L"AAG", L"AAH", L"AAI", L"AAJ", L"AAK", L"AAL", L"AAM", L"AAN", L"AAO", L"AAP", L"AAQ", L"AAR", L"AAS", L"AAT", L"AAU", L"AAV", L"AAW", L"AAX", L"AAY", L"AAZ", L"ABA", L"ABB", L"ABC", L"ABD", L"ABE", L"ABF", L"ABG", L"ABH", L"ABI", L"ABJ", L"ABK", L"ABL", L"ABM", L"ABN", L"ABO", L"ABP", L"ABQ", L"ABR", L"ABS", L"ABT", L"ABU", L"ABV", L"ABW", L"ABX", L"ABY", L"ABZ", L"ACA", L"ACB", L"ACC", L"ACD", L"ACE", L"ACF", L"ACG", L"ACH", L"ACI", L"ACJ", L"ACK", L"ACL", L"ACM", L"ACN", L"ACO", L"ACP", L"ACQ", L"ACR", L"ACS", L"ACT", L"ACU", L"ACV", L"ACW", L"ACX", L"ACY", L"ACZ", L"ADA", L"ADB", L"ADC", L"ADD", L"ADE", L"ADF", L"ADG", L"ADH", L"ADI", L"ADJ", L"ADK", L"ADL", L"ADM", L"ADN", L"ADO", L"ADP", L"ADQ", L"ADR", L"ADS", L"ADT", L"ADU", L"ADV", L"ADW", L"ADX", L"ADY", L"ADZ", L"AEA", L"AEB", L"AEC", L"AED", L"AEE", L"AEF", L"AEG", L"AEH", L"AEI", L"AEJ", L"AEK", L"AEL", L"AEM", L"AEN", L"AEO", L"AEP", L"AEQ", L"AER", L"AES", L"AET", L"AEU", L"AEV", L"AEW", L"AEX", L"AEY", L"AEZ", L"AFA", L"AFB", L"AFC", L"AFD", L"AFE", L"AFF", L"AFG", L"AFH", L"AFI", L"AFJ", L"AFK", L"AFL", L"AFM", L"AFN", L"AFO", L"AFP", L"AFQ", L"AFR", L"AFS", L"AFT", L"AFU", L"AFV", L"AFW", L"AFX", L"AFY", L"AFZ", L"AGA", L"AGB", L"AGC", L"AGD", L"AGE", L"AGF", L"AGG", L"AGH", L"AGI", L"AGJ", L"AGK", L"AGL", L"AGM", L"AGN", L"AGO", L"AGP", L"AGQ", L"AGR", L"AGS", L"AGT", L"AGU", L"AGV", L"AGW", L"AGX", L"AGY", L"AGZ", L"AHA", L"AHB", L"AHC", L"AHD", L"AHE", L"AHF", L"AHG", L"AHH", L"AHI", L"AHJ", L"AHK", L"AHL", L"AHM", L"AHN", L"AHO", L"AHP", L"AHQ", L"AHR", L"AHS", L"AHT", L"AHU", L"AHV", + static const wchar_t* m_aLetters[] = + { + L"A", L"B", L"C", L"D", L"E", L"F", L"G", L"H", L"I", L"J", L"K", L"L", L"M", L"N", L"O", L"P", L"Q", L"R", L"S", L"T", L"U", L"V", L"W", L"X", L"Y", L"Z", L"AA", L"AB", L"AC", L"AD", L"AE", L"AF", L"AG", L"AH", L"AI", L"AJ", L"AK", L"AL", L"AM", L"AN", L"AO", L"AP", L"AQ", L"AR", L"AS", L"AT", L"AU", L"AV", L"AW", L"AX", L"AY", L"AZ", L"BA", L"BB", L"BC", L"BD", L"BE", L"BF", L"BG", L"BH", L"BI", L"BJ", L"BK", L"BL", L"BM", L"BN", L"BO", L"BP", L"BQ", L"BR", L"BS", L"BT", L"BU", L"BV", L"BW", L"BX", L"BY", L"BZ", L"CA", L"CB", L"CC", L"CD", L"CE", L"CF", L"CG", L"CH", L"CI", L"CJ", L"CK", L"CL", L"CM", L"CN", L"CO", L"CP", L"CQ", L"CR", L"CS", L"CT", L"CU", L"CV", L"CW", L"CX", L"CY", L"CZ", L"DA", L"DB", L"DC", L"DD", L"DE", L"DF", L"DG", L"DH", L"DI", L"DJ", L"DK", L"DL", L"DM", L"DN", L"DO", L"DP", L"DQ", L"DR", L"DS", L"DT", L"DU", L"DV", L"DW", L"DX", L"DY", L"DZ", L"EA", L"EB", L"EC", L"ED", L"EE", L"EF", L"EG", L"EH", L"EI", L"EJ", L"EK", L"EL", L"EM", L"EN", L"EO", L"EP", L"EQ", L"ER", L"ES", L"ET", L"EU", L"EV", L"EW", L"EX", L"EY", L"EZ", L"FA", L"FB", L"FC", L"FD", L"FE", L"FF", L"FG", L"FH", L"FI", L"FJ", L"FK", L"FL", L"FM", L"FN", L"FO", L"FP", L"FQ", L"FR", L"FS", L"FT", L"FU", L"FV", L"FW", L"FX", L"FY", L"FZ", L"GA", L"GB", L"GC", L"GD", L"GE", L"GF", L"GG", L"GH", L"GI", L"GJ", L"GK", L"GL", L"GM", L"GN", L"GO", L"GP", L"GQ", L"GR", L"GS", L"GT", L"GU", L"GV", L"GW", L"GX", L"GY", L"GZ", L"HA", L"HB", L"HC", L"HD", L"HE", L"HF", L"HG", L"HH", L"HI", L"HJ", L"HK", L"HL", L"HM", L"HN", L"HO", L"HP", L"HQ", L"HR", L"HS", L"HT", L"HU", L"HV", L"HW", L"HX", L"HY", L"HZ", L"IA", L"IB", L"IC", L"ID", L"IE", L"IF", L"IG", L"IH", L"II", L"IJ", L"IK", L"IL", L"IM", L"IN", L"IO", L"IP", L"IQ", L"IR", L"IS", L"IT", L"IU", L"IV", L"IW", L"IX", L"IY", L"IZ", L"JA", L"JB", L"JC", L"JD", L"JE", L"JF", L"JG", L"JH", L"JI", L"JJ", L"JK", L"JL", L"JM", L"JN", L"JO", L"JP", L"JQ", L"JR", L"JS", L"JT", L"JU", L"JV", L"JW", L"JX", L"JY", L"JZ", L"KA", L"KB", L"KC", L"KD", L"KE", L"KF", L"KG", L"KH", L"KI", L"KJ", L"KK", L"KL", L"KM", L"KN", L"KO", L"KP", L"KQ", L"KR", L"KS", L"KT", L"KU", L"KV", L"KW", L"KX", L"KY", L"KZ", L"LA", L"LB", L"LC", L"LD", L"LE", L"LF", L"LG", L"LH", L"LI", L"LJ", L"LK", L"LL", L"LM", L"LN", L"LO", L"LP", L"LQ", L"LR", L"LS", L"LT", L"LU", L"LV", L"LW", L"LX", L"LY", L"LZ", L"MA", L"MB", L"MC", L"MD", L"ME", L"MF", L"MG", L"MH", L"MI", L"MJ", L"MK", L"ML", L"MM", L"MN", L"MO", L"MP", L"MQ", L"MR", L"MS", L"MT", L"MU", L"MV", L"MW", L"MX", L"MY", L"MZ", L"NA", L"NB", L"NC", L"ND", L"NE", L"NF", L"NG", L"NH", L"NI", L"NJ", L"NK", L"NL", L"NM", L"NN", L"NO", L"NP", L"NQ", L"NR", L"NS", L"NT", L"NU", L"NV", L"NW", L"NX", L"NY", L"NZ", L"OA", L"OB", L"OC", L"OD", L"OE", L"OF", L"OG", L"OH", L"OI", L"OJ", L"OK", L"OL", L"OM", L"ON", L"OO", L"OP", L"OQ", L"OR", L"OS", L"OT", L"OU", L"OV", L"OW", L"OX", L"OY", L"OZ", L"PA", L"PB", L"PC", L"PD", L"PE", L"PF", L"PG", L"PH", L"PI", L"PJ", L"PK", L"PL", L"PM", L"PN", L"PO", L"PP", L"PQ", L"PR", L"PS", L"PT", L"PU", L"PV", L"PW", L"PX", L"PY", L"PZ", L"QA", L"QB", L"QC", L"QD", L"QE", L"QF", L"QG", L"QH", L"QI", L"QJ", L"QK", L"QL", L"QM", L"QN", L"QO", L"QP", L"QQ", L"QR", L"QS", L"QT", L"QU", L"QV", L"QW", L"QX", L"QY", L"QZ", L"RA", L"RB", L"RC", L"RD", L"RE", L"RF", L"RG", L"RH", L"RI", L"RJ", L"RK", L"RL", L"RM", L"RN", L"RO", L"RP", L"RQ", L"RR", L"RS", L"RT", L"RU", L"RV", L"RW", L"RX", L"RY", L"RZ", L"SA", L"SB", L"SC", L"SD", L"SE", L"SF", L"SG", L"SH", L"SI", L"SJ", L"SK", L"SL", L"SM", L"SN", L"SO", L"SP", L"SQ", L"SR", L"SS", L"ST", L"SU", L"SV", L"SW", L"SX", L"SY", L"SZ", L"TA", L"TB", L"TC", L"TD", L"TE", L"TF", L"TG", L"TH", L"TI", L"TJ", L"TK", L"TL", L"TM", L"TN", L"TO", L"TP", L"TQ", L"TR", L"TS", L"TT", L"TU", L"TV", L"TW", L"TX", L"TY", L"TZ", L"UA", L"UB", L"UC", L"UD", L"UE", L"UF", L"UG", L"UH", L"UI", L"UJ", L"UK", L"UL", L"UM", L"UN", L"UO", L"UP", L"UQ", L"UR", L"US", L"UT", L"UU", L"UV", L"UW", L"UX", L"UY", L"UZ", L"VA", L"VB", L"VC", L"VD", L"VE", L"VF", L"VG", L"VH", L"VI", L"VJ", L"VK", L"VL", L"VM", L"VN", L"VO", L"VP", L"VQ", L"VR", L"VS", L"VT", L"VU", L"VV", L"VW", L"VX", L"VY", L"VZ", L"WA", L"WB", L"WC", L"WD", L"WE", L"WF", L"WG", L"WH", L"WI", L"WJ", L"WK", L"WL", L"WM", L"WN", L"WO", L"WP", L"WQ", L"WR", L"WS", L"WT", L"WU", L"WV", L"WW", L"WX", L"WY", + L"WZ", L"XA", L"XB", L"XC", L"XD", L"XE", L"XF", L"XG", L"XH", L"XI", L"XJ", L"XK", L"XL", L"XM", L"XN", L"XO", L"XP", L"XQ", L"XR", L"XS", L"XT", L"XU", L"XV", L"XW", L"XX", L"XY", L"XZ", L"YA", L"YB", L"YC", L"YD", L"YE", L"YF", L"YG", L"YH", L"YI", L"YJ", L"YK", L"YL", L"YM", L"YN", L"YO", L"YP", L"YQ", L"YR", L"YS", L"YT", L"YU", L"YV", L"YW", L"YX", L"YY", L"YZ", L"ZA", L"ZB", L"ZC", L"ZD", L"ZE", L"ZF", L"ZG", L"ZH", L"ZI", L"ZJ", L"ZK", L"ZL", L"ZM", L"ZN", L"ZO", L"ZP", L"ZQ", L"ZR", L"ZS", L"ZT", L"ZU", L"ZV", L"ZW", L"ZX", L"ZY", L"ZZ", L"AAA", L"AAB", L"AAC", L"AAD", L"AAE", L"AAF", L"AAG", L"AAH", L"AAI", L"AAJ", L"AAK", L"AAL", L"AAM", L"AAN", L"AAO", L"AAP", L"AAQ", L"AAR", L"AAS", L"AAT", L"AAU", L"AAV", L"AAW", L"AAX", L"AAY", L"AAZ", L"ABA", L"ABB", L"ABC", L"ABD", L"ABE", L"ABF", L"ABG", L"ABH", L"ABI", L"ABJ", L"ABK", L"ABL", L"ABM", L"ABN", L"ABO", L"ABP", L"ABQ", L"ABR", L"ABS", L"ABT", L"ABU", L"ABV", L"ABW", L"ABX", L"ABY", L"ABZ", L"ACA", L"ACB", L"ACC", L"ACD", L"ACE", L"ACF", L"ACG", L"ACH", L"ACI", L"ACJ", L"ACK", L"ACL", L"ACM", L"ACN", L"ACO", L"ACP", L"ACQ", L"ACR", L"ACS", L"ACT", L"ACU", L"ACV", L"ACW", L"ACX", L"ACY", L"ACZ", L"ADA", L"ADB", L"ADC", L"ADD", L"ADE", L"ADF", L"ADG", L"ADH", L"ADI", L"ADJ", L"ADK", L"ADL", L"ADM", L"ADN", L"ADO", L"ADP", L"ADQ", L"ADR", L"ADS", L"ADT", L"ADU", L"ADV", L"ADW", L"ADX", L"ADY", L"ADZ", L"AEA", L"AEB", L"AEC", L"AED", L"AEE", L"AEF", L"AEG", L"AEH", L"AEI", L"AEJ", L"AEK", L"AEL", L"AEM", L"AEN", L"AEO", L"AEP", L"AEQ", L"AER", L"AES", L"AET", L"AEU", L"AEV", L"AEW", L"AEX", L"AEY", L"AEZ", L"AFA", L"AFB", L"AFC", L"AFD", L"AFE", L"AFF", L"AFG", L"AFH", L"AFI", L"AFJ", L"AFK", L"AFL", L"AFM", L"AFN", L"AFO", L"AFP", L"AFQ", L"AFR", L"AFS", L"AFT", L"AFU", L"AFV", L"AFW", L"AFX", L"AFY", L"AFZ", L"AGA", L"AGB", L"AGC", L"AGD", L"AGE", L"AGF", L"AGG", L"AGH", L"AGI", L"AGJ", L"AGK", L"AGL", L"AGM", L"AGN", L"AGO", L"AGP", L"AGQ", L"AGR", L"AGS", L"AGT", L"AGU", L"AGV", L"AGW", L"AGX", L"AGY", L"AGZ", L"AHA", L"AHB", L"AHC", L"AHD", L"AHE", L"AHF", L"AHG", L"AHH", L"AHI", L"AHJ", L"AHK", L"AHL", L"AHM", L"AHN", L"AHO", L"AHP", L"AHQ", L"AHR", L"AHS", L"AHT", L"AHU", L"AHV", L"AHW", L"AHX", L"AHY", L"AHZ", L"AIA", L"AIB", L"AIC", L"AID", L"AIE", L"AIF", L"AIG", L"AIH", L"AII", L"AIJ", L"AIK", L"AIL", L"AIM", L"AIN", L"AIO", L"AIP", L"AIQ", L"AIR", L"AIS", L"AIT", L"AIU", L"AIV", L"AIW", L"AIX", L"AIY", L"AIZ", L"AJA", L"AJB", L"AJC", L"AJD", L"AJE", L"AJF", L"AJG", L"AJH", L"AJI", L"AJJ", L"AJK", L"AJL", L"AJM", L"AJN", L"AJO", L"AJP", L"AJQ", L"AJR", L"AJS", L"AJT", L"AJU", L"AJV", L"AJW", L"AJX", L"AJY", L"AJZ", L"AKA", L"AKB", L"AKC", L"AKD", L"AKE", L"AKF", L"AKG", L"AKH", L"AKI", L"AKJ", L"AKK", L"AKL", L"AKM", L"AKN", L"AKO", L"AKP", L"AKQ", L"AKR", L"AKS", L"AKT", L"AKU", L"AKV", L"AKW", L"AKX", L"AKY", L"AKZ", L"ALA", L"ALB", L"ALC", L"ALD", L"ALE", L"ALF", L"ALG", L"ALH", L"ALI", L"ALJ", L"ALK", L"ALL", L"ALM", L"ALN", L"ALO", L"ALP", L"ALQ", L"ALR", L"ALS", L"ALT", L"ALU", L"ALV", L"ALW", L"ALX", L"ALY", L"ALZ", L"AMA", L"AMB", L"AMC", L"AMD", L"AME", L"AMF", L"AMG", L"AMH", L"AMI", L"AMJ", L"AMK", L"AML", L"AMM", L"AMN", L"AMO", L"AMP", L"AMQ", L"AMR", L"AMS", L"AMT", L"AMU", L"AMV", L"AMW", L"AMX", L"AMY", L"AMZ", L"ANA", L"ANB", L"ANC", L"AND", L"ANE", L"ANF", L"ANG", L"ANH", L"ANI", L"ANJ", L"ANK", L"ANL", L"ANM", L"ANN", L"ANO", L"ANP", L"ANQ", L"ANR", L"ANS", L"ANT", L"ANU", L"ANV", L"ANW", L"ANX", L"ANY", L"ANZ", L"AOA", L"AOB", L"AOC", L"AOD", L"AOE", L"AOF", L"AOG", L"AOH", L"AOI", L"AOJ", L"AOK", L"AOL", L"AOM", L"AON", L"AOO", L"AOP", L"AOQ", L"AOR", L"AOS", L"AOT", L"AOU", L"AOV", L"AOW", L"AOX", L"AOY", L"AOZ", L"APA", L"APB", L"APC", L"APD", L"APE", L"APF", L"APG", L"APH", L"API", L"APJ", L"APK", L"APL", L"APM", L"APN", L"APO", L"APP", L"APQ", L"APR", L"APS", L"APT", L"APU", L"APV", L"APW", L"APX", L"APY", L"APZ", L"AQA", L"AQB", L"AQC", L"AQD", L"AQE", L"AQF", L"AQG", L"AQH", L"AQI", L"AQJ", L"AQK", L"AQL", L"AQM", L"AQN", L"AQO", L"AQP", L"AQQ", L"AQR", L"AQS", L"AQT", L"AQU", L"AQV", L"AQW", L"AQX", L"AQY", L"AQZ", L"ARA", L"ARB", L"ARC", L"ARD", L"ARE", L"ARF", L"ARG", L"ARH", L"ARI", L"ARJ", L"ARK", L"ARL", L"ARM", L"ARN", L"ARO", L"ARP", L"ARQ", L"ARR", L"ARS", L"ART", L"ARU", L"ARV", L"ARW", L"ARX", L"ARY", L"ARZ", L"ASA", L"ASB", L"ASC", L"ASD", L"ASE", L"ASF", L"ASG", L"ASH", L"ASI", L"ASJ", L"ASK", L"ASL", L"ASM", L"ASN", L"ASO", L"ASP", L"ASQ", L"ASR", L"ASS", L"AST", L"ASU", L"ASV", L"ASW", L"ASX", L"ASY", L"ASZ", L"ATA", L"ATB", L"ATC", L"ATD", L"ATE", L"ATF", L"ATG", L"ATH", L"ATI", L"ATJ", L"ATK", L"ATL", L"ATM", L"ATN", L"ATO", L"ATP", L"ATQ", L"ATR", L"ATS", L"ATT", L"ATU", L"ATV", L"ATW", L"ATX", L"ATY", L"ATZ", L"AUA", L"AUB", L"AUC", L"AUD", L"AUE", L"AUF", L"AUG", L"AUH", L"AUI", L"AUJ", L"AUK", L"AUL", L"AUM", L"AUN", L"AUO", L"AUP", L"AUQ", L"AUR", L"AUS", L"AUT", L"AUU", L"AUV", L"AUW", L"AUX", L"AUY", L"AUZ", L"AVA", L"AVB", L"AVC", L"AVD", L"AVE", L"AVF", L"AVG", L"AVH", L"AVI", L"AVJ", L"AVK", L"AVL", L"AVM", L"AVN", L"AVO", L"AVP", L"AVQ", L"AVR", L"AVS", L"AVT", L"AVU", L"AVV", L"AVW", L"AVX", L"AVY", L"AVZ", L"AWA", L"AWB", L"AWC", L"AWD", L"AWE", L"AWF", L"AWG", L"AWH", L"AWI", L"AWJ", L"AWK", L"AWL", L"AWM", L"AWN", L"AWO", L"AWP", L"AWQ", L"AWR", L"AWS", L"AWT", L"AWU", L"AWV", L"AWW", L"AWX", L"AWY", L"AWZ", L"AXA", L"AXB", L"AXC", L"AXD", L"AXE", L"AXF", L"AXG", L"AXH", L"AXI", L"AXJ", L"AXK", L"AXL", L"AXM", L"AXN", L"AXO", L"AXP", L"AXQ", L"AXR", L"AXS", L"AXT", L"AXU", L"AXV", L"AXW", L"AXX", L"AXY", L"AXZ", L"AYA", L"AYB", L"AYC", L"AYD", L"AYE", L"AYF", L"AYG", L"AYH", L"AYI", L"AYJ", L"AYK", L"AYL", L"AYM", L"AYN", L"AYO", L"AYP", L"AYQ", L"AYR", L"AYS", L"AYT", L"AYU", L"AYV", L"AYW", L"AYX", L"AYY", L"AYZ", L"AZA", L"AZB", L"AZC", L"AZD", L"AZE", L"AZF", L"AZG", L"AZH", L"AZI", L"AZJ", L"AZK", L"AZL", L"AZM", L"AZN", L"AZO", L"AZP", L"AZQ", L"AZR", L"AZS", L"AZT", L"AZU", L"AZV", L"AZW", L"AZX", L"AZY", L"AZZ", L"BAA", L"BAB", L"BAC", L"BAD", L"BAE", L"BAF", L"BAG", L"BAH", L"BAI", L"BAJ", L"BAK", L"BAL", L"BAM", L"BAN", L"BAO", L"BAP", L"BAQ", L"BAR", L"BAS", L"BAT", L"BAU", L"BAV", L"BAW", L"BAX", L"BAY", L"BAZ", L"BBA", L"BBB", L"BBC", L"BBD", L"BBE", L"BBF", L"BBG", L"BBH", L"BBI", L"BBJ", L"BBK", L"BBL", L"BBM", L"BBN", L"BBO", L"BBP", L"BBQ", L"BBR", L"BBS", L"BBT", L"BBU", L"BBV", L"BBW", L"BBX", L"BBY", L"BBZ", L"BCA", L"BCB", L"BCC", L"BCD", L"BCE", L"BCF", L"BCG", L"BCH", L"BCI", L"BCJ", L"BCK", L"BCL", L"BCM", L"BCN", L"BCO", L"BCP", L"BCQ", L"BCR", L"BCS", L"BCT", L"BCU", L"BCV", L"BCW", L"BCX", L"BCY", L"BCZ", L"BDA", L"BDB", L"BDC", L"BDD", L"BDE", L"BDF", L"BDG", L"BDH", L"BDI", L"BDJ", L"BDK", L"BDL", L"BDM", L"BDN", L"BDO", L"BDP", L"BDQ", L"BDR", L"BDS", L"BDT", L"BDU", L"BDV", L"BDW", L"BDX", L"BDY", L"BDZ", L"BEA", L"BEB", L"BEC", L"BED", L"BEE", L"BEF", L"BEG", L"BEH", L"BEI", L"BEJ", L"BEK", L"BEL", L"BEM", L"BEN", L"BEO", L"BEP", L"BEQ", L"BER", L"BES", L"BET", L"BEU", L"BEV", L"BEW", L"BEX", L"BEY", L"BEZ", L"BFA", L"BFB", L"BFC", L"BFD", L"BFE", L"BFF", L"BFG", L"BFH", L"BFI", L"BFJ", L"BFK", L"BFL", L"BFM", L"BFN", L"BFO", L"BFP", L"BFQ", L"BFR", L"BFS", L"BFT", L"BFU", L"BFV", L"BFW", L"BFX", L"BFY", L"BFZ", L"BGA", L"BGB", L"BGC", L"BGD", L"BGE", L"BGF", L"BGG", L"BGH", L"BGI", L"BGJ", L"BGK", L"BGL", L"BGM", L"BGN", L"BGO", L"BGP", L"BGQ", L"BGR", L"BGS", L"BGT", L"BGU", L"BGV", L"BGW", L"BGX", L"BGY", L"BGZ", L"BHA", L"BHB", L"BHC", L"BHD", L"BHE", L"BHF", L"BHG", L"BHH", L"BHI", L"BHJ", L"BHK", L"BHL", L"BHM", L"BHN", L"BHO", L"BHP", L"BHQ", L"BHR", L"BHS", L"BHT", L"BHU", L"BHV", L"BHW", L"BHX", L"BHY", L"BHZ", L"BIA", L"BIB", L"BIC", L"BID", L"BIE", L"BIF", L"BIG", L"BIH", L"BII", L"BIJ", L"BIK", L"BIL", L"BIM", L"BIN", L"BIO", L"BIP", L"BIQ", L"BIR", L"BIS", L"BIT", L"BIU", L"BIV", L"BIW", L"BIX", L"BIY", L"BIZ", L"BJA", L"BJB", L"BJC", L"BJD", L"BJE", L"BJF", L"BJG", L"BJH", L"BJI", L"BJJ", L"BJK", L"BJL", L"BJM", L"BJN", L"BJO", L"BJP", L"BJQ", L"BJR", L"BJS", L"BJT", L"BJU", L"BJV", L"BJW", L"BJX", L"BJY", L"BJZ", L"BKA", L"BKB", L"BKC", L"BKD", L"BKE", L"BKF", L"BKG", L"BKH", L"BKI", L"BKJ", L"BKK", L"BKL", L"BKM", L"BKN", L"BKO", L"BKP", L"BKQ", L"BKR", L"BKS", L"BKT", L"BKU", L"BKV", L"BKW", L"BKX", L"BKY", L"BKZ", L"BLA", L"BLB", L"BLC", L"BLD", L"BLE", L"BLF", L"BLG", L"BLH", L"BLI", L"BLJ", L"BLK", L"BLL", L"BLM", L"BLN", L"BLO", L"BLP", L"BLQ", L"BLR", L"BLS", L"BLT", L"BLU", L"BLV", L"BLW", L"BLX", L"BLY", L"BLZ", L"BMA", L"BMB", L"BMC", L"BMD", L"BME", L"BMF", L"BMG", L"BMH", L"BMI", L"BMJ", L"BMK", L"BML", L"BMM", L"BMN", L"BMO", L"BMP", L"BMQ", L"BMR", L"BMS", L"BMT", L"BMU", L"BMV", L"BMW", L"BMX", L"BMY", L"BMZ", L"BNA", L"BNB", L"BNC", L"BND", L"BNE", L"BNF", L"BNG", L"BNH", L"BNI", L"BNJ", L"BNK", L"BNL", L"BNM", L"BNN", L"BNO", L"BNP", L"BNQ", L"BNR", L"BNS", L"BNT", L"BNU", L"BNV", L"BNW", L"BNX", L"BNY", L"BNZ", L"BOA", L"BOB", L"BOC", L"BOD", L"BOE", L"BOF", L"BOG", L"BOH", L"BOI", L"BOJ", L"BOK", L"BOL", L"BOM", L"BON", L"BOO", L"BOP", L"BOQ", L"BOR", L"BOS", L"BOT", L"BOU", L"BOV", L"BOW", L"BOX", L"BOY", L"BOZ", L"BPA", L"BPB", L"BPC", L"BPD", L"BPE", L"BPF", L"BPG", L"BPH", L"BPI", L"BPJ", L"BPK", L"BPL", L"BPM", L"BPN", L"BPO", L"BPP", L"BPQ", L"BPR", L"BPS", L"BPT", L"BPU", L"BPV", L"BPW", L"BPX", L"BPY", L"BPZ", L"BQA", L"BQB", L"BQC", L"BQD", L"BQE", L"BQF", L"BQG", L"BQH", L"BQI", L"BQJ", L"BQK", L"BQL", L"BQM", L"BQN", L"BQO", L"BQP", L"BQQ", L"BQR", L"BQS", L"BQT", L"BQU", L"BQV", L"BQW", L"BQX", L"BQY", L"BQZ", L"BRA", L"BRB", L"BRC", L"BRD", L"BRE", L"BRF", L"BRG", L"BRH", L"BRI", L"BRJ", L"BRK", L"BRL", L"BRM", L"BRN", L"BRO", L"BRP", L"BRQ", L"BRR", L"BRS", L"BRT", L"BRU", L"BRV", L"BRW", L"BRX", L"BRY", L"BRZ", L"BSA", L"BSB", L"BSC", L"BSD", L"BSE", L"BSF", L"BSG", L"BSH", L"BSI", L"BSJ", L"BSK", L"BSL", L"BSM", L"BSN", L"BSO", L"BSP", L"BSQ", L"BSR", L"BSS", L"BST", L"BSU", L"BSV", L"BSW", L"BSX", L"BSY", L"BSZ", L"BTA", L"BTB", L"BTC", L"BTD", L"BTE", L"BTF", L"BTG", L"BTH", L"BTI", L"BTJ", L"BTK", L"BTL", L"BTM", L"BTN", L"BTO", L"BTP", L"BTQ", L"BTR", L"BTS", L"BTT", L"BTU", L"BTV", L"BTW", L"BTX", L"BTY", L"BTZ", L"BUA", L"BUB", L"BUC", L"BUD", L"BUE", L"BUF", L"BUG", L"BUH", L"BUI", L"BUJ", L"BUK", L"BUL", L"BUM", L"BUN", L"BUO", L"BUP", L"BUQ", L"BUR", L"BUS", L"BUT", L"BUU", L"BUV", L"BUW", L"BUX", L"BUY", L"BUZ", L"BVA", L"BVB", L"BVC", L"BVD", L"BVE", L"BVF", L"BVG", L"BVH", L"BVI", L"BVJ", L"BVK", L"BVL", L"BVM", L"BVN", L"BVO", L"BVP", L"BVQ", L"BVR", L"BVS", L"BVT", L"BVU", L"BVV", L"BVW", L"BVX", L"BVY", L"BVZ", L"BWA", L"BWB", L"BWC", L"BWD", L"BWE", L"BWF", L"BWG", L"BWH", L"BWI", L"BWJ", L"BWK", L"BWL", L"BWM", L"BWN", L"BWO", L"BWP", L"BWQ", L"BWR", L"BWS", L"BWT", L"BWU", L"BWV", L"BWW", L"BWX", L"BWY", L"BWZ", L"BXA", L"BXB", L"BXC", L"BXD", L"BXE", L"BXF", L"BXG", L"BXH", L"BXI", L"BXJ", L"BXK", L"BXL", L"BXM", L"BXN", L"BXO", L"BXP", L"BXQ", L"BXR", L"BXS", L"BXT", L"BXU", L"BXV", L"BXW", L"BXX", L"BXY", L"BXZ", L"BYA", L"BYB", L"BYC", L"BYD", L"BYE", L"BYF", L"BYG", L"BYH", L"BYI", L"BYJ", L"BYK", L"BYL", L"BYM", L"BYN", L"BYO", L"BYP", L"BYQ", L"BYR", L"BYS", L"BYT", L"BYU", L"BYV", L"BYW", L"BYX", L"BYY", L"BYZ", L"BZA", L"BZB", L"BZC", L"BZD", L"BZE", L"BZF", L"BZG", L"BZH", L"BZI", L"BZJ", L"BZK", L"BZL", L"BZM", L"BZN", L"BZO", L"BZP", L"BZQ", L"BZR", L"BZS", L"BZT", L"BZU", L"BZV", L"BZW", L"BZX", L"BZY", L"BZZ", L"CAA", L"CAB", L"CAC", L"CAD", L"CAE", L"CAF", L"CAG", L"CAH", L"CAI", L"CAJ", L"CAK", L"CAL", L"CAM", L"CAN", L"CAO", L"CAP", L"CAQ", L"CAR", L"CAS", L"CAT", L"CAU", L"CAV", L"CAW", L"CAX", L"CAY", L"CAZ", L"CBA", L"CBB", L"CBC", L"CBD", L"CBE", L"CBF", L"CBG", L"CBH", L"CBI", L"CBJ", L"CBK", L"CBL", L"CBM", L"CBN", L"CBO", L"CBP", L"CBQ", L"CBR", L"CBS", L"CBT", L"CBU", L"CBV", L"CBW", L"CBX", L"CBY", L"CBZ", L"CCA", L"CCB", L"CCC", L"CCD", L"CCE", L"CCF", L"CCG", L"CCH", L"CCI", L"CCJ", L"CCK", L"CCL", L"CCM", L"CCN", L"CCO", L"CCP", L"CCQ", L"CCR", L"CCS", L"CCT", L"CCU", L"CCV", L"CCW", L"CCX", L"CCY", L"CCZ", L"CDA", L"CDB", L"CDC", L"CDD", L"CDE", L"CDF", L"CDG", L"CDH", L"CDI", L"CDJ", L"CDK", L"CDL", L"CDM", L"CDN", L"CDO", L"CDP", L"CDQ", L"CDR", L"CDS", L"CDT", L"CDU", L"CDV", L"CDW", L"CDX", L"CDY", L"CDZ", L"CEA", L"CEB", L"CEC", L"CED", L"CEE", L"CEF", L"CEG", L"CEH", L"CEI", L"CEJ", L"CEK", L"CEL", L"CEM", L"CEN", L"CEO", L"CEP", L"CEQ", L"CER", L"CES", L"CET", L"CEU", L"CEV", L"CEW", L"CEX", L"CEY", L"CEZ", L"CFA", L"CFB", L"CFC", L"CFD", L"CFE", L"CFF", L"CFG", L"CFH", L"CFI", L"CFJ", L"CFK", L"CFL", L"CFM", L"CFN", L"CFO", L"CFP", L"CFQ", L"CFR", L"CFS", L"CFT", L"CFU", L"CFV", L"CFW", L"CFX", L"CFY", L"CFZ", L"CGA", L"CGB", L"CGC", L"CGD", L"CGE", L"CGF", L"CGG", L"CGH", L"CGI", L"CGJ", L"CGK", L"CGL", L"CGM", L"CGN", L"CGO", L"CGP", L"CGQ", L"CGR", L"CGS", L"CGT", L"CGU", L"CGV", L"CGW", L"CGX", L"CGY", L"CGZ", L"CHA", L"CHB", L"CHC", L"CHD", L"CHE", L"CHF", L"CHG", L"CHH", L"CHI", L"CHJ", L"CHK", L"CHL", L"CHM", L"CHN", L"CHO", L"CHP", L"CHQ", L"CHR", L"CHS", L"CHT", L"CHU", L"CHV", L"CHW", L"CHX", L"CHY", L"CHZ", L"CIA", L"CIB", L"CIC", L"CID", L"CIE", L"CIF", L"CIG", L"CIH", L"CII", L"CIJ", L"CIK", L"CIL", L"CIM", L"CIN", L"CIO", L"CIP", L"CIQ", L"CIR", L"CIS", L"CIT", L"CIU", L"CIV", L"CIW", L"CIX", L"CIY", L"CIZ", L"CJA", L"CJB", L"CJC", L"CJD", L"CJE", L"CJF", L"CJG", L"CJH", L"CJI", L"CJJ", L"CJK", L"CJL", L"CJM", L"CJN", L"CJO", L"CJP", L"CJQ", L"CJR", L"CJS", L"CJT", L"CJU", L"CJV", L"CJW", L"CJX", L"CJY", L"CJZ", L"CKA", L"CKB", L"CKC", L"CKD", L"CKE", L"CKF", L"CKG", L"CKH", L"CKI", L"CKJ", L"CKK", L"CKL", L"CKM", L"CKN", L"CKO", L"CKP", L"CKQ", L"CKR", L"CKS", L"CKT", L"CKU", L"CKV", L"CKW", L"CKX", L"CKY", L"CKZ", L"CLA", L"CLB", L"CLC", L"CLD", L"CLE", L"CLF", L"CLG", L"CLH", L"CLI", L"CLJ", L"CLK", L"CLL", L"CLM", L"CLN", L"CLO", L"CLP", L"CLQ", L"CLR", L"CLS", L"CLT", L"CLU", L"CLV", L"CLW", L"CLX", L"CLY", L"CLZ", L"CMA", L"CMB", L"CMC", L"CMD", L"CME", L"CMF", L"CMG", L"CMH", L"CMI", L"CMJ", L"CMK", L"CML", L"CMM", L"CMN", L"CMO", L"CMP", L"CMQ", L"CMR", L"CMS", L"CMT", L"CMU", L"CMV", L"CMW", L"CMX", L"CMY", L"CMZ", L"CNA", L"CNB", L"CNC", L"CND", L"CNE", L"CNF", L"CNG", L"CNH", L"CNI", L"CNJ", L"CNK", L"CNL", L"CNM", L"CNN", L"CNO", L"CNP", L"CNQ", L"CNR", L"CNS", L"CNT", L"CNU", L"CNV", L"CNW", L"CNX", L"CNY", L"CNZ", L"COA", L"COB", L"COC", L"COD", L"COE", L"COF", L"COG", L"COH", L"COI", L"COJ", L"COK", L"COL", L"COM", L"CON", L"COO", L"COP", L"COQ", L"COR", L"COS", L"COT", L"COU", L"COV", L"COW", L"COX", L"COY", L"COZ", L"CPA", L"CPB", L"CPC", L"CPD", L"CPE", L"CPF", L"CPG", L"CPH", L"CPI", L"CPJ", L"CPK", L"CPL", L"CPM", L"CPN", L"CPO", L"CPP", L"CPQ", L"CPR", L"CPS", L"CPT", L"CPU", L"CPV", L"CPW", L"CPX", L"CPY", L"CPZ", L"CQA", L"CQB", L"CQC", L"CQD", L"CQE", L"CQF", L"CQG", L"CQH", L"CQI", L"CQJ", L"CQK", L"CQL", L"CQM", L"CQN", L"CQO", L"CQP", L"CQQ", L"CQR", L"CQS", L"CQT", L"CQU", L"CQV", L"CQW", L"CQX", L"CQY", L"CQZ", L"CRA", L"CRB", L"CRC", L"CRD", L"CRE", L"CRF", L"CRG", L"CRH", L"CRI", L"CRJ", L"CRK", L"CRL", L"CRM", L"CRN", L"CRO", L"CRP", L"CRQ", L"CRR", L"CRS", L"CRT", L"CRU", L"CRV", L"CRW", L"CRX", L"CRY", L"CRZ", L"CSA", L"CSB", L"CSC", L"CSD", L"CSE", L"CSF", L"CSG", L"CSH", L"CSI", L"CSJ", L"CSK", L"CSL", L"CSM", L"CSN", L"CSO", L"CSP", L"CSQ", L"CSR", L"CSS", L"CST", L"CSU", L"CSV", L"CSW", L"CSX", L"CSY", L"CSZ", L"CTA", L"CTB", L"CTC", L"CTD", L"CTE", L"CTF", L"CTG", L"CTH", L"CTI", L"CTJ", L"CTK", L"CTL", L"CTM", L"CTN", L"CTO", L"CTP", L"CTQ", L"CTR", L"CTS", L"CTT", L"CTU", L"CTV", L"CTW", L"CTX", L"CTY", L"CTZ", L"CUA", L"CUB", L"CUC", L"CUD", L"CUE", L"CUF", L"CUG", L"CUH", L"CUI", L"CUJ", L"CUK", L"CUL", L"CUM", L"CUN", L"CUO", L"CUP", L"CUQ", L"CUR", L"CUS", L"CUT", L"CUU", L"CUV", L"CUW", L"CUX", L"CUY", L"CUZ", L"CVA", L"CVB", L"CVC", L"CVD", L"CVE", L"CVF", L"CVG", L"CVH", L"CVI", L"CVJ", L"CVK", L"CVL", L"CVM", L"CVN", L"CVO", L"CVP", L"CVQ", L"CVR", L"CVS", L"CVT", L"CVU", L"CVV", L"CVW", L"CVX", L"CVY", L"CVZ", L"CWA", L"CWB", L"CWC", L"CWD", L"CWE", L"CWF", L"CWG", L"CWH", L"CWI", L"CWJ", L"CWK", L"CWL", L"CWM", L"CWN", L"CWO", L"CWP", L"CWQ", L"CWR", L"CWS", L"CWT", L"CWU", L"CWV", L"CWW", L"CWX", L"CWY", L"CWZ", L"CXA", L"CXB", L"CXC", L"CXD", L"CXE", L"CXF", L"CXG", L"CXH", L"CXI", L"CXJ", L"CXK", L"CXL", L"CXM", L"CXN", L"CXO", L"CXP", L"CXQ", L"CXR", L"CXS", L"CXT", L"CXU", L"CXV", L"CXW", L"CXX", L"CXY", L"CXZ", L"CYA", L"CYB", L"CYC", L"CYD", L"CYE", L"CYF", L"CYG", L"CYH", L"CYI", L"CYJ", L"CYK", L"CYL", L"CYM", L"CYN", L"CYO", L"CYP", L"CYQ", L"CYR", L"CYS", L"CYT", L"CYU", L"CYV", L"CYW", L"CYX", L"CYY", L"CYZ", L"CZA", L"CZB", L"CZC", L"CZD", L"CZE", L"CZF", L"CZG", L"CZH", L"CZI", L"CZJ", L"CZK", L"CZL", L"CZM", L"CZN", L"CZO", L"CZP", L"CZQ", L"CZR", L"CZS", L"CZT", L"CZU", L"CZV", L"CZW", L"CZX", L"CZY", L"CZZ", L"DAA", L"DAB", L"DAC", L"DAD", L"DAE", L"DAF", L"DAG", L"DAH", L"DAI", L"DAJ", L"DAK", L"DAL", L"DAM", L"DAN", L"DAO", L"DAP", L"DAQ", L"DAR", L"DAS", L"DAT", L"DAU", L"DAV", L"DAW", L"DAX", L"DAY", L"DAZ", L"DBA", L"DBB", L"DBC", L"DBD", L"DBE", L"DBF", L"DBG", L"DBH", L"DBI", L"DBJ", L"DBK", L"DBL", L"DBM", L"DBN", L"DBO", L"DBP", L"DBQ", L"DBR", L"DBS", L"DBT", L"DBU", L"DBV", L"DBW", L"DBX", L"DBY", L"DBZ", L"DCA", L"DCB", L"DCC", L"DCD", L"DCE", L"DCF", L"DCG", L"DCH", L"DCI", L"DCJ", L"DCK", L"DCL", L"DCM", L"DCN", L"DCO", L"DCP", L"DCQ", L"DCR", L"DCS", L"DCT", L"DCU", L"DCV", L"DCW", L"DCX", L"DCY", L"DCZ", L"DDA", - L"DDB", L"DDC", L"DDD", L"DDE", L"DDF", L"DDG", L"DDH", L"DDI", L"DDJ", L"DDK", L"DDL", L"DDM", L"DDN", L"DDO", L"DDP", L"DDQ", L"DDR", L"DDS", L"DDT", L"DDU", L"DDV", L"DDW", L"DDX", L"DDY", L"DDZ", L"DEA", L"DEB", L"DEC", L"DED", L"DEE", L"DEF", L"DEG", L"DEH", L"DEI", L"DEJ", L"DEK", L"DEL", L"DEM", L"DEN", L"DEO", L"DEP", L"DEQ", L"DER", L"DES", L"DET", L"DEU", L"DEV", L"DEW", L"DEX", L"DEY", L"DEZ", L"DFA", L"DFB", L"DFC", L"DFD", L"DFE", L"DFF", L"DFG", L"DFH", L"DFI", L"DFJ", L"DFK", L"DFL", L"DFM", L"DFN", L"DFO", L"DFP", L"DFQ", L"DFR", L"DFS", L"DFT", L"DFU", L"DFV", L"DFW", L"DFX", L"DFY", L"DFZ", L"DGA", L"DGB", L"DGC", L"DGD", L"DGE", L"DGF", L"DGG", L"DGH", L"DGI", L"DGJ", L"DGK", L"DGL", L"DGM", L"DGN", L"DGO", L"DGP", L"DGQ", L"DGR", L"DGS", L"DGT", L"DGU", L"DGV", L"DGW", L"DGX", L"DGY", L"DGZ", L"DHA", L"DHB", L"DHC", L"DHD", L"DHE", L"DHF", L"DHG", L"DHH", L"DHI", L"DHJ", L"DHK", L"DHL", L"DHM", L"DHN", L"DHO", L"DHP", L"DHQ", L"DHR", L"DHS", L"DHT", L"DHU", L"DHV", L"DHW", L"DHX", L"DHY", L"DHZ", L"DIA", L"DIB", L"DIC", L"DID", L"DIE", L"DIF", L"DIG", L"DIH", L"DII", L"DIJ", L"DIK", L"DIL", L"DIM", L"DIN", L"DIO", L"DIP", L"DIQ", L"DIR", L"DIS", L"DIT", L"DIU", L"DIV", L"DIW", L"DIX", L"DIY", L"DIZ", L"DJA", L"DJB", L"DJC", L"DJD", L"DJE", L"DJF", L"DJG", L"DJH", L"DJI", L"DJJ", L"DJK", L"DJL", L"DJM", L"DJN", L"DJO", L"DJP", L"DJQ", L"DJR", L"DJS", L"DJT", L"DJU", L"DJV", L"DJW", L"DJX", L"DJY", L"DJZ", L"DKA", L"DKB", L"DKC", L"DKD", L"DKE", L"DKF", L"DKG", L"DKH", L"DKI", L"DKJ", L"DKK", L"DKL", L"DKM", L"DKN", L"DKO", L"DKP", L"DKQ", L"DKR", L"DKS", L"DKT", L"DKU", L"DKV", L"DKW", L"DKX", L"DKY", L"DKZ", L"DLA", L"DLB", L"DLC", L"DLD", L"DLE", L"DLF", L"DLG", L"DLH", L"DLI", L"DLJ", L"DLK", L"DLL", L"DLM", L"DLN", L"DLO", L"DLP", L"DLQ", L"DLR", L"DLS", L"DLT", L"DLU", L"DLV", L"DLW", L"DLX", L"DLY", L"DLZ", L"DMA", L"DMB", L"DMC", L"DMD", L"DME", L"DMF", L"DMG", L"DMH", L"DMI", L"DMJ", L"DMK", L"DML", L"DMM", L"DMN", L"DMO", L"DMP", L"DMQ", L"DMR", L"DMS", L"DMT", L"DMU", L"DMV", L"DMW", L"DMX", L"DMY", L"DMZ", L"DNA", L"DNB", L"DNC", L"DND", L"DNE", L"DNF", L"DNG", L"DNH", L"DNI", L"DNJ", L"DNK", L"DNL", L"DNM", L"DNN", L"DNO", L"DNP", L"DNQ", L"DNR", L"DNS", L"DNT", L"DNU", L"DNV", L"DNW", L"DNX", L"DNY", L"DNZ", L"DOA", L"DOB", L"DOC", L"DOD", L"DOE", L"DOF", L"DOG", L"DOH", L"DOI", L"DOJ", L"DOK", L"DOL", L"DOM", L"DON", L"DOO", L"DOP", L"DOQ", L"DOR", L"DOS", L"DOT", L"DOU", L"DOV", L"DOW", L"DOX", L"DOY", L"DOZ", L"DPA", L"DPB", L"DPC", L"DPD", L"DPE", L"DPF", L"DPG", L"DPH", L"DPI", L"DPJ", L"DPK", L"DPL", L"DPM", L"DPN", L"DPO", L"DPP", L"DPQ", L"DPR", L"DPS", L"DPT", L"DPU", L"DPV", L"DPW", L"DPX", L"DPY", L"DPZ", L"DQA", L"DQB", L"DQC", L"DQD", L"DQE", L"DQF", L"DQG", L"DQH", L"DQI", L"DQJ", L"DQK", L"DQL", L"DQM", L"DQN", L"DQO", L"DQP", L"DQQ", L"DQR", L"DQS", L"DQT", L"DQU", L"DQV", L"DQW", L"DQX", L"DQY", L"DQZ", L"DRA", L"DRB", L"DRC", L"DRD", L"DRE", L"DRF", L"DRG", L"DRH", L"DRI", L"DRJ", L"DRK", L"DRL", L"DRM", L"DRN", L"DRO", L"DRP", L"DRQ", L"DRR", L"DRS", L"DRT", L"DRU", L"DRV", L"DRW", L"DRX", L"DRY", L"DRZ", L"DSA", L"DSB", L"DSC", L"DSD", L"DSE", L"DSF", L"DSG", L"DSH", L"DSI", L"DSJ", L"DSK", L"DSL", L"DSM", L"DSN", L"DSO", L"DSP", L"DSQ", L"DSR", L"DSS", L"DST", L"DSU", L"DSV", L"DSW", L"DSX", L"DSY", L"DSZ", L"DTA", L"DTB", L"DTC", L"DTD", L"DTE", L"DTF", L"DTG", L"DTH", L"DTI", L"DTJ", L"DTK", L"DTL", L"DTM", L"DTN", L"DTO", L"DTP", L"DTQ", L"DTR", L"DTS", L"DTT", L"DTU", L"DTV", L"DTW", L"DTX", L"DTY", L"DTZ", L"DUA", L"DUB", L"DUC", L"DUD", L"DUE", L"DUF", L"DUG", L"DUH", L"DUI", L"DUJ", L"DUK", L"DUL", L"DUM", L"DUN", L"DUO", L"DUP", L"DUQ", L"DUR", L"DUS", L"DUT", L"DUU", L"DUV", L"DUW", L"DUX", L"DUY", L"DUZ", L"DVA", L"DVB", L"DVC", L"DVD", L"DVE", L"DVF", L"DVG", L"DVH", L"DVI", L"DVJ", L"DVK", L"DVL", L"DVM", L"DVN", L"DVO", L"DVP", L"DVQ", L"DVR", L"DVS", L"DVT", L"DVU", L"DVV", L"DVW", L"DVX", L"DVY", L"DVZ", L"DWA", L"DWB", L"DWC", L"DWD", L"DWE", L"DWF", L"DWG", L"DWH", L"DWI", L"DWJ", L"DWK", L"DWL", L"DWM", L"DWN", L"DWO", L"DWP", L"DWQ", L"DWR", L"DWS", L"DWT", L"DWU", L"DWV", L"DWW", L"DWX", L"DWY", L"DWZ", L"DXA", L"DXB", L"DXC", L"DXD", L"DXE", L"DXF", L"DXG", L"DXH", L"DXI", L"DXJ", L"DXK", L"DXL", L"DXM", L"DXN", L"DXO", L"DXP", L"DXQ", L"DXR", L"DXS", - L"DXT", L"DXU", L"DXV", L"DXW", L"DXX", L"DXY", L"DXZ", L"DYA", L"DYB", L"DYC", L"DYD", L"DYE", L"DYF", L"DYG", L"DYH", L"DYI", L"DYJ", L"DYK", L"DYL", L"DYM", L"DYN", L"DYO", L"DYP", L"DYQ", L"DYR", L"DYS", L"DYT", L"DYU", L"DYV", L"DYW", L"DYX", L"DYY", L"DYZ", L"DZA", L"DZB", L"DZC", L"DZD", L"DZE", L"DZF", L"DZG", L"DZH", L"DZI", L"DZJ", L"DZK", L"DZL", L"DZM", L"DZN", L"DZO", L"DZP", L"DZQ", L"DZR", L"DZS", L"DZT", L"DZU", L"DZV", L"DZW", L"DZX", L"DZY", L"DZZ", L"EAA", L"EAB", L"EAC", L"EAD", L"EAE", L"EAF", L"EAG", L"EAH", L"EAI", L"EAJ", L"EAK", L"EAL", L"EAM", L"EAN", L"EAO", L"EAP", L"EAQ", L"EAR", L"EAS", L"EAT", L"EAU", L"EAV", L"EAW", L"EAX", L"EAY", L"EAZ", L"EBA", L"EBB", L"EBC", L"EBD", L"EBE", L"EBF", L"EBG", L"EBH", L"EBI", L"EBJ", L"EBK", L"EBL", L"EBM", L"EBN", L"EBO", L"EBP", L"EBQ", L"EBR", L"EBS", L"EBT", L"EBU", L"EBV", L"EBW", L"EBX", L"EBY", L"EBZ", L"ECA", L"ECB", L"ECC", L"ECD", L"ECE", L"ECF", L"ECG", L"ECH", L"ECI", L"ECJ", L"ECK", L"ECL", L"ECM", L"ECN", L"ECO", L"ECP", L"ECQ", L"ECR", L"ECS", L"ECT", L"ECU", L"ECV", L"ECW", L"ECX", L"ECY", L"ECZ", L"EDA", L"EDB", L"EDC", L"EDD", L"EDE", L"EDF", L"EDG", L"EDH", L"EDI", L"EDJ", L"EDK", L"EDL", L"EDM", L"EDN", L"EDO", L"EDP", L"EDQ", L"EDR", L"EDS", L"EDT", L"EDU", L"EDV", L"EDW", L"EDX", L"EDY", L"EDZ", L"EEA", L"EEB", L"EEC", L"EED", L"EEE", L"EEF", L"EEG", L"EEH", L"EEI", L"EEJ", L"EEK", L"EEL", L"EEM", L"EEN", L"EEO", L"EEP", L"EEQ", L"EER", L"EES", L"EET", L"EEU", L"EEV", L"EEW", L"EEX", L"EEY", L"EEZ", L"EFA", L"EFB", L"EFC", L"EFD", L"EFE", L"EFF", L"EFG", L"EFH", L"EFI", L"EFJ", L"EFK", L"EFL", L"EFM", L"EFN", L"EFO", L"EFP", L"EFQ", L"EFR", L"EFS", L"EFT", L"EFU", L"EFV", L"EFW", L"EFX", L"EFY", L"EFZ", L"EGA", L"EGB", L"EGC", L"EGD", L"EGE", L"EGF", L"EGG", L"EGH", L"EGI", L"EGJ", L"EGK", L"EGL", L"EGM", L"EGN", L"EGO", L"EGP", L"EGQ", L"EGR", L"EGS", L"EGT", L"EGU", L"EGV", L"EGW", L"EGX", L"EGY", L"EGZ", L"EHA", L"EHB", L"EHC", L"EHD", L"EHE", L"EHF", L"EHG", L"EHH", L"EHI", L"EHJ", L"EHK", L"EHL", L"EHM", L"EHN", L"EHO", L"EHP", L"EHQ", L"EHR", L"EHS", L"EHT", L"EHU", L"EHV", L"EHW", L"EHX", L"EHY", L"EHZ", L"EIA", L"EIB", L"EIC", L"EID", L"EIE", L"EIF", L"EIG", L"EIH", L"EII", L"EIJ", L"EIK", L"EIL", L"EIM", L"EIN", L"EIO", L"EIP", L"EIQ", L"EIR", L"EIS", L"EIT", L"EIU", L"EIV", L"EIW", L"EIX", L"EIY", L"EIZ", L"EJA", L"EJB", L"EJC", L"EJD", L"EJE", L"EJF", L"EJG", L"EJH", L"EJI", L"EJJ", L"EJK", L"EJL", L"EJM", L"EJN", L"EJO", L"EJP", L"EJQ", L"EJR", L"EJS", L"EJT", L"EJU", L"EJV", L"EJW", L"EJX", L"EJY", L"EJZ", L"EKA", L"EKB", L"EKC", L"EKD", L"EKE", L"EKF", L"EKG", L"EKH", L"EKI", L"EKJ", L"EKK", L"EKL", L"EKM", L"EKN", L"EKO", L"EKP", L"EKQ", L"EKR", L"EKS", L"EKT", L"EKU", L"EKV", L"EKW", L"EKX", L"EKY", L"EKZ", L"ELA", L"ELB", L"ELC", L"ELD", L"ELE", L"ELF", L"ELG", L"ELH", L"ELI", L"ELJ", L"ELK", L"ELL", L"ELM", L"ELN", L"ELO", L"ELP", L"ELQ", L"ELR", L"ELS", L"ELT", L"ELU", L"ELV", L"ELW", L"ELX", L"ELY", L"ELZ", L"EMA", L"EMB", L"EMC", L"EMD", L"EME", L"EMF", L"EMG", L"EMH", L"EMI", L"EMJ", L"EMK", L"EML", L"EMM", L"EMN", L"EMO", L"EMP", L"EMQ", L"EMR", L"EMS", L"EMT", L"EMU", L"EMV", L"EMW", L"EMX", L"EMY", L"EMZ", L"ENA", L"ENB", L"ENC", L"END", L"ENE", L"ENF", L"ENG", L"ENH", L"ENI", L"ENJ", L"ENK", L"ENL", L"ENM", L"ENN", L"ENO", L"ENP", L"ENQ", L"ENR", L"ENS", L"ENT", L"ENU", L"ENV", L"ENW", L"ENX", L"ENY", L"ENZ", L"EOA", L"EOB", L"EOC", L"EOD", L"EOE", L"EOF", L"EOG", L"EOH", L"EOI", L"EOJ", L"EOK", L"EOL", L"EOM", L"EON", L"EOO", L"EOP", L"EOQ", L"EOR", L"EOS", L"EOT", L"EOU", L"EOV", L"EOW", L"EOX", L"EOY", L"EOZ", L"EPA", L"EPB", L"EPC", L"EPD", L"EPE", L"EPF", L"EPG", L"EPH", L"EPI", L"EPJ", L"EPK", L"EPL", L"EPM", L"EPN", L"EPO", L"EPP", L"EPQ", L"EPR", L"EPS", L"EPT", L"EPU", L"EPV", L"EPW", L"EPX", L"EPY", L"EPZ", L"EQA", L"EQB", L"EQC", L"EQD", L"EQE", L"EQF", L"EQG", L"EQH", L"EQI", L"EQJ", L"EQK", L"EQL", L"EQM", L"EQN", L"EQO", L"EQP", L"EQQ", L"EQR", L"EQS", L"EQT", L"EQU", L"EQV", L"EQW", L"EQX", L"EQY", L"EQZ", L"ERA", L"ERB", L"ERC", L"ERD", L"ERE", L"ERF", L"ERG", L"ERH", L"ERI", L"ERJ", L"ERK", L"ERL", L"ERM", L"ERN", L"ERO", L"ERP", L"ERQ", L"ERR", L"ERS", L"ERT", L"ERU", L"ERV", L"ERW", L"ERX", L"ERY", L"ERZ", L"ESA", L"ESB", L"ESC", L"ESD", L"ESE", L"ESF", L"ESG", L"ESH", L"ESI", L"ESJ", L"ESK", + L"DDB", L"DDC", L"DDD", L"DDE", L"DDF", L"DDG", L"DDH", L"DDI", L"DDJ", L"DDK", L"DDL", L"DDM", L"DDN", L"DDO", L"DDP", L"DDQ", L"DDR", L"DDS", L"DDT", L"DDU", L"DDV", L"DDW", L"DDX", L"DDY", L"DDZ", L"DEA", L"DEB", L"DEC", L"DED", L"DEE", L"DEF", L"DEG", L"DEH", L"DEI", L"DEJ", L"DEK", L"DEL", L"DEM", L"DEN", L"DEO", L"DEP", L"DEQ", L"DER", L"DES", L"DET", L"DEU", L"DEV", L"DEW", L"DEX", L"DEY", L"DEZ", L"DFA", L"DFB", L"DFC", L"DFD", L"DFE", L"DFF", L"DFG", L"DFH", L"DFI", L"DFJ", L"DFK", L"DFL", L"DFM", L"DFN", L"DFO", L"DFP", L"DFQ", L"DFR", L"DFS", L"DFT", L"DFU", L"DFV", L"DFW", L"DFX", L"DFY", L"DFZ", L"DGA", L"DGB", L"DGC", L"DGD", L"DGE", L"DGF", L"DGG", L"DGH", L"DGI", L"DGJ", L"DGK", L"DGL", L"DGM", L"DGN", L"DGO", L"DGP", L"DGQ", L"DGR", L"DGS", L"DGT", L"DGU", L"DGV", L"DGW", L"DGX", L"DGY", L"DGZ", L"DHA", L"DHB", L"DHC", L"DHD", L"DHE", L"DHF", L"DHG", L"DHH", L"DHI", L"DHJ", L"DHK", L"DHL", L"DHM", L"DHN", L"DHO", L"DHP", L"DHQ", L"DHR", L"DHS", L"DHT", L"DHU", L"DHV", L"DHW", L"DHX", L"DHY", L"DHZ", L"DIA", L"DIB", L"DIC", L"DID", L"DIE", L"DIF", L"DIG", L"DIH", L"DII", L"DIJ", L"DIK", L"DIL", L"DIM", L"DIN", L"DIO", L"DIP", L"DIQ", L"DIR", L"DIS", L"DIT", L"DIU", L"DIV", L"DIW", L"DIX", L"DIY", L"DIZ", L"DJA", L"DJB", L"DJC", L"DJD", L"DJE", L"DJF", L"DJG", L"DJH", L"DJI", L"DJJ", L"DJK", L"DJL", L"DJM", L"DJN", L"DJO", L"DJP", L"DJQ", L"DJR", L"DJS", L"DJT", L"DJU", L"DJV", L"DJW", L"DJX", L"DJY", L"DJZ", L"DKA", L"DKB", L"DKC", L"DKD", L"DKE", L"DKF", L"DKG", L"DKH", L"DKI", L"DKJ", L"DKK", L"DKL", L"DKM", L"DKN", L"DKO", L"DKP", L"DKQ", L"DKR", L"DKS", L"DKT", L"DKU", L"DKV", L"DKW", L"DKX", L"DKY", L"DKZ", L"DLA", L"DLB", L"DLC", L"DLD", L"DLE", L"DLF", L"DLG", L"DLH", L"DLI", L"DLJ", L"DLK", L"DLL", L"DLM", L"DLN", L"DLO", L"DLP", L"DLQ", L"DLR", L"DLS", L"DLT", L"DLU", L"DLV", L"DLW", L"DLX", L"DLY", L"DLZ", L"DMA", L"DMB", L"DMC", L"DMD", L"DME", L"DMF", L"DMG", L"DMH", L"DMI", L"DMJ", L"DMK", L"DML", L"DMM", L"DMN", L"DMO", L"DMP", L"DMQ", L"DMR", L"DMS", L"DMT", L"DMU", L"DMV", L"DMW", L"DMX", L"DMY", L"DMZ", L"DNA", L"DNB", L"DNC", L"DND", L"DNE", L"DNF", L"DNG", L"DNH", L"DNI", L"DNJ", L"DNK", L"DNL", L"DNM", L"DNN", L"DNO", L"DNP", L"DNQ", L"DNR", L"DNS", L"DNT", L"DNU", L"DNV", L"DNW", L"DNX", L"DNY", L"DNZ", L"DOA", L"DOB", L"DOC", L"DOD", L"DOE", L"DOF", L"DOG", L"DOH", L"DOI", L"DOJ", L"DOK", L"DOL", L"DOM", L"DON", L"DOO", L"DOP", L"DOQ", L"DOR", L"DOS", L"DOT", L"DOU", L"DOV", L"DOW", L"DOX", L"DOY", L"DOZ", L"DPA", L"DPB", L"DPC", L"DPD", L"DPE", L"DPF", L"DPG", L"DPH", L"DPI", L"DPJ", L"DPK", L"DPL", L"DPM", L"DPN", L"DPO", L"DPP", L"DPQ", L"DPR", L"DPS", L"DPT", L"DPU", L"DPV", L"DPW", L"DPX", L"DPY", L"DPZ", L"DQA", L"DQB", L"DQC", L"DQD", L"DQE", L"DQF", L"DQG", L"DQH", L"DQI", L"DQJ", L"DQK", L"DQL", L"DQM", L"DQN", L"DQO", L"DQP", L"DQQ", L"DQR", L"DQS", L"DQT", L"DQU", L"DQV", L"DQW", L"DQX", L"DQY", L"DQZ", L"DRA", L"DRB", L"DRC", L"DRD", L"DRE", L"DRF", L"DRG", L"DRH", L"DRI", L"DRJ", L"DRK", L"DRL", L"DRM", L"DRN", L"DRO", L"DRP", L"DRQ", L"DRR", L"DRS", L"DRT", L"DRU", L"DRV", L"DRW", L"DRX", L"DRY", L"DRZ", L"DSA", L"DSB", L"DSC", L"DSD", L"DSE", L"DSF", L"DSG", L"DSH", L"DSI", L"DSJ", L"DSK", L"DSL", L"DSM", L"DSN", L"DSO", L"DSP", L"DSQ", L"DSR", L"DSS", L"DST", L"DSU", L"DSV", L"DSW", L"DSX", L"DSY", L"DSZ", L"DTA", L"DTB", L"DTC", L"DTD", L"DTE", L"DTF", L"DTG", L"DTH", L"DTI", L"DTJ", L"DTK", L"DTL", L"DTM", L"DTN", L"DTO", L"DTP", L"DTQ", L"DTR", L"DTS", L"DTT", L"DTU", L"DTV", L"DTW", L"DTX", L"DTY", L"DTZ", L"DUA", L"DUB", L"DUC", L"DUD", L"DUE", L"DUF", L"DUG", L"DUH", L"DUI", L"DUJ", L"DUK", L"DUL", L"DUM", L"DUN", L"DUO", L"DUP", L"DUQ", L"DUR", L"DUS", L"DUT", L"DUU", L"DUV", L"DUW", L"DUX", L"DUY", L"DUZ", L"DVA", L"DVB", L"DVC", L"DVD", L"DVE", L"DVF", L"DVG", L"DVH", L"DVI", L"DVJ", L"DVK", L"DVL", L"DVM", L"DVN", L"DVO", L"DVP", L"DVQ", L"DVR", L"DVS", L"DVT", L"DVU", L"DVV", L"DVW", L"DVX", L"DVY", L"DVZ", L"DWA", L"DWB", L"DWC", L"DWD", L"DWE", L"DWF", L"DWG", L"DWH", L"DWI", L"DWJ", L"DWK", L"DWL", L"DWM", L"DWN", L"DWO", L"DWP", L"DWQ", L"DWR", L"DWS", L"DWT", L"DWU", L"DWV", L"DWW", L"DWX", L"DWY", L"DWZ", L"DXA", L"DXB", L"DXC", L"DXD", L"DXE", L"DXF", L"DXG", L"DXH", L"DXI", L"DXJ", L"DXK", L"DXL", L"DXM", L"DXN", L"DXO", L"DXP", L"DXQ", L"DXR", L"DXS", + L"DXT", L"DXU", L"DXV", L"DXW", L"DXX", L"DXY", L"DXZ", L"DYA", L"DYB", L"DYC", L"DYD", L"DYE", L"DYF", L"DYG", L"DYH", L"DYI", L"DYJ", L"DYK", L"DYL", L"DYM", L"DYN", L"DYO", L"DYP", L"DYQ", L"DYR", L"DYS", L"DYT", L"DYU", L"DYV", L"DYW", L"DYX", L"DYY", L"DYZ", L"DZA", L"DZB", L"DZC", L"DZD", L"DZE", L"DZF", L"DZG", L"DZH", L"DZI", L"DZJ", L"DZK", L"DZL", L"DZM", L"DZN", L"DZO", L"DZP", L"DZQ", L"DZR", L"DZS", L"DZT", L"DZU", L"DZV", L"DZW", L"DZX", L"DZY", L"DZZ", L"EAA", L"EAB", L"EAC", L"EAD", L"EAE", L"EAF", L"EAG", L"EAH", L"EAI", L"EAJ", L"EAK", L"EAL", L"EAM", L"EAN", L"EAO", L"EAP", L"EAQ", L"EAR", L"EAS", L"EAT", L"EAU", L"EAV", L"EAW", L"EAX", L"EAY", L"EAZ", L"EBA", L"EBB", L"EBC", L"EBD", L"EBE", L"EBF", L"EBG", L"EBH", L"EBI", L"EBJ", L"EBK", L"EBL", L"EBM", L"EBN", L"EBO", L"EBP", L"EBQ", L"EBR", L"EBS", L"EBT", L"EBU", L"EBV", L"EBW", L"EBX", L"EBY", L"EBZ", L"ECA", L"ECB", L"ECC", L"ECD", L"ECE", L"ECF", L"ECG", L"ECH", L"ECI", L"ECJ", L"ECK", L"ECL", L"ECM", L"ECN", L"ECO", L"ECP", L"ECQ", L"ECR", L"ECS", L"ECT", L"ECU", L"ECV", L"ECW", L"ECX", L"ECY", L"ECZ", L"EDA", L"EDB", L"EDC", L"EDD", L"EDE", L"EDF", L"EDG", L"EDH", L"EDI", L"EDJ", L"EDK", L"EDL", L"EDM", L"EDN", L"EDO", L"EDP", L"EDQ", L"EDR", L"EDS", L"EDT", L"EDU", L"EDV", L"EDW", L"EDX", L"EDY", L"EDZ", L"EEA", L"EEB", L"EEC", L"EED", L"EEE", L"EEF", L"EEG", L"EEH", L"EEI", L"EEJ", L"EEK", L"EEL", L"EEM", L"EEN", L"EEO", L"EEP", L"EEQ", L"EER", L"EES", L"EET", L"EEU", L"EEV", L"EEW", L"EEX", L"EEY", L"EEZ", L"EFA", L"EFB", L"EFC", L"EFD", L"EFE", L"EFF", L"EFG", L"EFH", L"EFI", L"EFJ", L"EFK", L"EFL", L"EFM", L"EFN", L"EFO", L"EFP", L"EFQ", L"EFR", L"EFS", L"EFT", L"EFU", L"EFV", L"EFW", L"EFX", L"EFY", L"EFZ", L"EGA", L"EGB", L"EGC", L"EGD", L"EGE", L"EGF", L"EGG", L"EGH", L"EGI", L"EGJ", L"EGK", L"EGL", L"EGM", L"EGN", L"EGO", L"EGP", L"EGQ", L"EGR", L"EGS", L"EGT", L"EGU", L"EGV", L"EGW", L"EGX", L"EGY", L"EGZ", L"EHA", L"EHB", L"EHC", L"EHD", L"EHE", L"EHF", L"EHG", L"EHH", L"EHI", L"EHJ", L"EHK", L"EHL", L"EHM", L"EHN", L"EHO", L"EHP", L"EHQ", L"EHR", L"EHS", L"EHT", L"EHU", L"EHV", L"EHW", L"EHX", L"EHY", L"EHZ", L"EIA", L"EIB", L"EIC", L"EID", L"EIE", L"EIF", L"EIG", L"EIH", L"EII", L"EIJ", L"EIK", L"EIL", L"EIM", L"EIN", L"EIO", L"EIP", L"EIQ", L"EIR", L"EIS", L"EIT", L"EIU", L"EIV", L"EIW", L"EIX", L"EIY", L"EIZ", L"EJA", L"EJB", L"EJC", L"EJD", L"EJE", L"EJF", L"EJG", L"EJH", L"EJI", L"EJJ", L"EJK", L"EJL", L"EJM", L"EJN", L"EJO", L"EJP", L"EJQ", L"EJR", L"EJS", L"EJT", L"EJU", L"EJV", L"EJW", L"EJX", L"EJY", L"EJZ", L"EKA", L"EKB", L"EKC", L"EKD", L"EKE", L"EKF", L"EKG", L"EKH", L"EKI", L"EKJ", L"EKK", L"EKL", L"EKM", L"EKN", L"EKO", L"EKP", L"EKQ", L"EKR", L"EKS", L"EKT", L"EKU", L"EKV", L"EKW", L"EKX", L"EKY", L"EKZ", L"ELA", L"ELB", L"ELC", L"ELD", L"ELE", L"ELF", L"ELG", L"ELH", L"ELI", L"ELJ", L"ELK", L"ELL", L"ELM", L"ELN", L"ELO", L"ELP", L"ELQ", L"ELR", L"ELS", L"ELT", L"ELU", L"ELV", L"ELW", L"ELX", L"ELY", L"ELZ", L"EMA", L"EMB", L"EMC", L"EMD", L"EME", L"EMF", L"EMG", L"EMH", L"EMI", L"EMJ", L"EMK", L"EML", L"EMM", L"EMN", L"EMO", L"EMP", L"EMQ", L"EMR", L"EMS", L"EMT", L"EMU", L"EMV", L"EMW", L"EMX", L"EMY", L"EMZ", L"ENA", L"ENB", L"ENC", L"END", L"ENE", L"ENF", L"ENG", L"ENH", L"ENI", L"ENJ", L"ENK", L"ENL", L"ENM", L"ENN", L"ENO", L"ENP", L"ENQ", L"ENR", L"ENS", L"ENT", L"ENU", L"ENV", L"ENW", L"ENX", L"ENY", L"ENZ", L"EOA", L"EOB", L"EOC", L"EOD", L"EOE", L"EOF", L"EOG", L"EOH", L"EOI", L"EOJ", L"EOK", L"EOL", L"EOM", L"EON", L"EOO", L"EOP", L"EOQ", L"EOR", L"EOS", L"EOT", L"EOU", L"EOV", L"EOW", L"EOX", L"EOY", L"EOZ", L"EPA", L"EPB", L"EPC", L"EPD", L"EPE", L"EPF", L"EPG", L"EPH", L"EPI", L"EPJ", L"EPK", L"EPL", L"EPM", L"EPN", L"EPO", L"EPP", L"EPQ", L"EPR", L"EPS", L"EPT", L"EPU", L"EPV", L"EPW", L"EPX", L"EPY", L"EPZ", L"EQA", L"EQB", L"EQC", L"EQD", L"EQE", L"EQF", L"EQG", L"EQH", L"EQI", L"EQJ", L"EQK", L"EQL", L"EQM", L"EQN", L"EQO", L"EQP", L"EQQ", L"EQR", L"EQS", L"EQT", L"EQU", L"EQV", L"EQW", L"EQX", L"EQY", L"EQZ", L"ERA", L"ERB", L"ERC", L"ERD", L"ERE", L"ERF", L"ERG", L"ERH", L"ERI", L"ERJ", L"ERK", L"ERL", L"ERM", L"ERN", L"ERO", L"ERP", L"ERQ", L"ERR", L"ERS", L"ERT", L"ERU", L"ERV", L"ERW", L"ERX", L"ERY", L"ERZ", L"ESA", L"ESB", L"ESC", L"ESD", L"ESE", L"ESF", L"ESG", L"ESH", L"ESI", L"ESJ", L"ESK", L"ESL", L"ESM", L"ESN", L"ESO", L"ESP", L"ESQ", L"ESR", L"ESS", L"EST", L"ESU", L"ESV", L"ESW", L"ESX", L"ESY", L"ESZ", L"ETA", L"ETB", L"ETC", L"ETD", L"ETE", L"ETF", L"ETG", L"ETH", L"ETI", L"ETJ", L"ETK", L"ETL", L"ETM", L"ETN", L"ETO", L"ETP", L"ETQ", L"ETR", L"ETS", L"ETT", L"ETU", L"ETV", L"ETW", L"ETX", L"ETY", L"ETZ", L"EUA", L"EUB", L"EUC", L"EUD", L"EUE", L"EUF", L"EUG", L"EUH", L"EUI", L"EUJ", L"EUK", L"EUL", L"EUM", L"EUN", L"EUO", L"EUP", L"EUQ", L"EUR", L"EUS", L"EUT", L"EUU", L"EUV", L"EUW", L"EUX", L"EUY", L"EUZ", L"EVA", L"EVB", L"EVC", L"EVD", L"EVE", L"EVF", L"EVG", L"EVH", L"EVI", L"EVJ", L"EVK", L"EVL", L"EVM", L"EVN", L"EVO", L"EVP", L"EVQ", L"EVR", L"EVS", L"EVT", L"EVU", L"EVV", L"EVW", L"EVX", L"EVY", L"EVZ", L"EWA", L"EWB", L"EWC", L"EWD", L"EWE", L"EWF", L"EWG", L"EWH", L"EWI", L"EWJ", L"EWK", L"EWL", L"EWM", L"EWN", L"EWO", L"EWP", L"EWQ", L"EWR", L"EWS", L"EWT", L"EWU", L"EWV", L"EWW", L"EWX", L"EWY", L"EWZ", L"EXA", L"EXB", L"EXC", L"EXD", L"EXE", L"EXF", L"EXG", L"EXH", L"EXI", L"EXJ", L"EXK", L"EXL", L"EXM", L"EXN", L"EXO", L"EXP", L"EXQ", L"EXR", L"EXS", L"EXT", L"EXU", L"EXV", L"EXW", L"EXX", L"EXY", L"EXZ", L"EYA", L"EYB", L"EYC", L"EYD", L"EYE", L"EYF", L"EYG", L"EYH", L"EYI", L"EYJ", L"EYK", L"EYL", L"EYM", L"EYN", L"EYO", L"EYP", L"EYQ", L"EYR", L"EYS", L"EYT", L"EYU", L"EYV", L"EYW", L"EYX", L"EYY", L"EYZ", L"EZA", L"EZB", L"EZC", L"EZD", L"EZE", L"EZF", L"EZG", L"EZH", L"EZI", L"EZJ", L"EZK", L"EZL", L"EZM", L"EZN", L"EZO", L"EZP", L"EZQ", L"EZR", L"EZS", L"EZT", L"EZU", L"EZV", L"EZW", L"EZX", L"EZY", L"EZZ", L"FAA", L"FAB", L"FAC", L"FAD", L"FAE", L"FAF", L"FAG", L"FAH", L"FAI", L"FAJ", L"FAK", L"FAL", L"FAM", L"FAN", L"FAO", L"FAP", L"FAQ", L"FAR", L"FAS", L"FAT", L"FAU", L"FAV", L"FAW", L"FAX", L"FAY", L"FAZ", L"FBA", L"FBB", L"FBC", L"FBD", L"FBE", L"FBF", L"FBG", L"FBH", L"FBI", L"FBJ", L"FBK", L"FBL", L"FBM", L"FBN", L"FBO", L"FBP", L"FBQ", L"FBR", L"FBS", L"FBT", L"FBU", L"FBV", L"FBW", L"FBX", L"FBY", L"FBZ", L"FCA", L"FCB", L"FCC", L"FCD", L"FCE", L"FCF", L"FCG", L"FCH", L"FCI", L"FCJ", L"FCK", L"FCL", L"FCM", L"FCN", L"FCO", L"FCP", L"FCQ", L"FCR", L"FCS", L"FCT", L"FCU", L"FCV", L"FCW", L"FCX", L"FCY", L"FCZ", L"FDA", L"FDB", L"FDC", L"FDD", L"FDE", L"FDF", - L"FDG", L"FDH", L"FDI", L"FDJ", L"FDK", L"FDL", L"FDM", L"FDN", L"FDO", L"FDP", L"FDQ", L"FDR", L"FDS", L"FDT", L"FDU", L"FDV", L"FDW", L"FDX", L"FDY", L"FDZ", L"FEA", L"FEB", L"FEC", L"FED", L"FEE", L"FEF", L"FEG", L"FEH", L"FEI", L"FEJ", L"FEK", L"FEL", L"FEM", L"FEN", L"FEO", L"FEP", L"FEQ", L"FER", L"FES", L"FET", L"FEU", L"FEV", L"FEW", L"FEX", L"FEY", L"FEZ", L"FFA", L"FFB", L"FFC", L"FFD", L"FFE", L"FFF", L"FFG", L"FFH", L"FFI", L"FFJ", L"FFK", L"FFL", L"FFM", L"FFN", L"FFO", L"FFP", L"FFQ", L"FFR", L"FFS", L"FFT", L"FFU", L"FFV", L"FFW", L"FFX", L"FFY", L"FFZ", L"FGA", L"FGB", L"FGC", L"FGD", L"FGE", L"FGF", L"FGG", L"FGH", L"FGI", L"FGJ", L"FGK", L"FGL", L"FGM", L"FGN", L"FGO", L"FGP", L"FGQ", L"FGR", L"FGS", L"FGT", L"FGU", L"FGV", L"FGW", L"FGX", L"FGY", L"FGZ", L"FHA", L"FHB", L"FHC", L"FHD", L"FHE", L"FHF", L"FHG", L"FHH", L"FHI", L"FHJ", L"FHK", L"FHL", L"FHM", L"FHN", L"FHO", L"FHP", L"FHQ", L"FHR", L"FHS", L"FHT", L"FHU", L"FHV", L"FHW", L"FHX", L"FHY", L"FHZ", L"FIA", L"FIB", L"FIC", L"FID", L"FIE", L"FIF", L"FIG", L"FIH", L"FII", L"FIJ", L"FIK", L"FIL", L"FIM", L"FIN", L"FIO", L"FIP", L"FIQ", L"FIR", L"FIS", L"FIT", L"FIU", L"FIV", L"FIW", L"FIX", L"FIY", L"FIZ", L"FJA", L"FJB", L"FJC", L"FJD", L"FJE", L"FJF", L"FJG", L"FJH", L"FJI", L"FJJ", L"FJK", L"FJL", L"FJM", L"FJN", L"FJO", L"FJP", L"FJQ", L"FJR", L"FJS", L"FJT", L"FJU", L"FJV", L"FJW", L"FJX", L"FJY", L"FJZ", L"FKA", L"FKB", L"FKC", L"FKD", L"FKE", L"FKF", L"FKG", L"FKH", L"FKI", L"FKJ", L"FKK", L"FKL", L"FKM", L"FKN", L"FKO", L"FKP", L"FKQ", L"FKR", L"FKS", L"FKT", L"FKU", L"FKV", L"FKW", L"FKX", L"FKY", L"FKZ", L"FLA", L"FLB", L"FLC", L"FLD", L"FLE", L"FLF", L"FLG", L"FLH", L"FLI", L"FLJ", L"FLK", L"FLL", L"FLM", L"FLN", L"FLO", L"FLP", L"FLQ", L"FLR", L"FLS", L"FLT", L"FLU", L"FLV", L"FLW", L"FLX", L"FLY", L"FLZ", L"FMA", L"FMB", L"FMC", L"FMD", L"FME", L"FMF", L"FMG", L"FMH", L"FMI", L"FMJ", L"FMK", L"FML", L"FMM", L"FMN", L"FMO", L"FMP", L"FMQ", L"FMR", L"FMS", L"FMT", L"FMU", L"FMV", L"FMW", L"FMX", L"FMY", L"FMZ", L"FNA", L"FNB", L"FNC", L"FND", L"FNE", L"FNF", L"FNG", L"FNH", L"FNI", L"FNJ", L"FNK", L"FNL", L"FNM", L"FNN", L"FNO", L"FNP", L"FNQ", L"FNR", L"FNS", L"FNT", L"FNU", L"FNV", L"FNW", L"FNX", L"FNY", L"FNZ", L"FOA", L"FOB", L"FOC", L"FOD", L"FOE", L"FOF", L"FOG", L"FOH", L"FOI", L"FOJ", L"FOK", L"FOL", L"FOM", L"FON", L"FOO", L"FOP", L"FOQ", L"FOR", L"FOS", L"FOT", L"FOU", L"FOV", L"FOW", L"FOX", L"FOY", L"FOZ", L"FPA", L"FPB", L"FPC", L"FPD", L"FPE", L"FPF", L"FPG", L"FPH", L"FPI", L"FPJ", L"FPK", L"FPL", L"FPM", L"FPN", L"FPO", L"FPP", L"FPQ", L"FPR", L"FPS", L"FPT", L"FPU", L"FPV", L"FPW", L"FPX", L"FPY", L"FPZ", L"FQA", L"FQB", L"FQC", L"FQD", L"FQE", L"FQF", L"FQG", L"FQH", L"FQI", L"FQJ", L"FQK", L"FQL", L"FQM", L"FQN", L"FQO", L"FQP", L"FQQ", L"FQR", L"FQS", L"FQT", L"FQU", L"FQV", L"FQW", L"FQX", L"FQY", L"FQZ", L"FRA", L"FRB", L"FRC", L"FRD", L"FRE", L"FRF", L"FRG", L"FRH", L"FRI", L"FRJ", L"FRK", L"FRL", L"FRM", L"FRN", L"FRO", L"FRP", L"FRQ", L"FRR", L"FRS", L"FRT", L"FRU", L"FRV", L"FRW", L"FRX", L"FRY", L"FRZ", L"FSA", L"FSB", L"FSC", L"FSD", L"FSE", L"FSF", L"FSG", L"FSH", L"FSI", L"FSJ", L"FSK", L"FSL", L"FSM", L"FSN", L"FSO", L"FSP", L"FSQ", L"FSR", L"FSS", L"FST", L"FSU", L"FSV", L"FSW", L"FSX", L"FSY", L"FSZ", L"FTA", L"FTB", L"FTC", L"FTD", L"FTE", L"FTF", L"FTG", L"FTH", L"FTI", L"FTJ", L"FTK", L"FTL", L"FTM", L"FTN", L"FTO", L"FTP", L"FTQ", L"FTR", L"FTS", L"FTT", L"FTU", L"FTV", L"FTW", L"FTX", L"FTY", L"FTZ", L"FUA", L"FUB", L"FUC", L"FUD", L"FUE", L"FUF", L"FUG", L"FUH", L"FUI", L"FUJ", L"FUK", L"FUL", L"FUM", L"FUN", L"FUO", L"FUP", L"FUQ", L"FUR", L"FUS", L"FUT", L"FUU", L"FUV", L"FUW", L"FUX", L"FUY", L"FUZ", L"FVA", L"FVB", L"FVC", L"FVD", L"FVE", L"FVF", L"FVG", L"FVH", L"FVI", L"FVJ", L"FVK", L"FVL", L"FVM", L"FVN", L"FVO", L"FVP", L"FVQ", L"FVR", L"FVS", L"FVT", L"FVU", L"FVV", L"FVW", L"FVX", L"FVY", L"FVZ", L"FWA", L"FWB", L"FWC", L"FWD", L"FWE", L"FWF", L"FWG", L"FWH", L"FWI", L"FWJ", L"FWK", L"FWL", L"FWM", L"FWN", L"FWO", L"FWP", L"FWQ", L"FWR", L"FWS", L"FWT", L"FWU", L"FWV", L"FWW", L"FWX", L"FWY", L"FWZ", L"FXA", L"FXB", L"FXC", L"FXD", L"FXE", L"FXF", L"FXG", L"FXH", L"FXI", L"FXJ", L"FXK", L"FXL", L"FXM", L"FXN", L"FXO", L"FXP", L"FXQ", L"FXR", L"FXS", L"FXT", L"FXU", L"FXV", L"FXW", L"FXX", + L"FDG", L"FDH", L"FDI", L"FDJ", L"FDK", L"FDL", L"FDM", L"FDN", L"FDO", L"FDP", L"FDQ", L"FDR", L"FDS", L"FDT", L"FDU", L"FDV", L"FDW", L"FDX", L"FDY", L"FDZ", L"FEA", L"FEB", L"FEC", L"FED", L"FEE", L"FEF", L"FEG", L"FEH", L"FEI", L"FEJ", L"FEK", L"FEL", L"FEM", L"FEN", L"FEO", L"FEP", L"FEQ", L"FER", L"FES", L"FET", L"FEU", L"FEV", L"FEW", L"FEX", L"FEY", L"FEZ", L"FFA", L"FFB", L"FFC", L"FFD", L"FFE", L"FFF", L"FFG", L"FFH", L"FFI", L"FFJ", L"FFK", L"FFL", L"FFM", L"FFN", L"FFO", L"FFP", L"FFQ", L"FFR", L"FFS", L"FFT", L"FFU", L"FFV", L"FFW", L"FFX", L"FFY", L"FFZ", L"FGA", L"FGB", L"FGC", L"FGD", L"FGE", L"FGF", L"FGG", L"FGH", L"FGI", L"FGJ", L"FGK", L"FGL", L"FGM", L"FGN", L"FGO", L"FGP", L"FGQ", L"FGR", L"FGS", L"FGT", L"FGU", L"FGV", L"FGW", L"FGX", L"FGY", L"FGZ", L"FHA", L"FHB", L"FHC", L"FHD", L"FHE", L"FHF", L"FHG", L"FHH", L"FHI", L"FHJ", L"FHK", L"FHL", L"FHM", L"FHN", L"FHO", L"FHP", L"FHQ", L"FHR", L"FHS", L"FHT", L"FHU", L"FHV", L"FHW", L"FHX", L"FHY", L"FHZ", L"FIA", L"FIB", L"FIC", L"FID", L"FIE", L"FIF", L"FIG", L"FIH", L"FII", L"FIJ", L"FIK", L"FIL", L"FIM", L"FIN", L"FIO", L"FIP", L"FIQ", L"FIR", L"FIS", L"FIT", L"FIU", L"FIV", L"FIW", L"FIX", L"FIY", L"FIZ", L"FJA", L"FJB", L"FJC", L"FJD", L"FJE", L"FJF", L"FJG", L"FJH", L"FJI", L"FJJ", L"FJK", L"FJL", L"FJM", L"FJN", L"FJO", L"FJP", L"FJQ", L"FJR", L"FJS", L"FJT", L"FJU", L"FJV", L"FJW", L"FJX", L"FJY", L"FJZ", L"FKA", L"FKB", L"FKC", L"FKD", L"FKE", L"FKF", L"FKG", L"FKH", L"FKI", L"FKJ", L"FKK", L"FKL", L"FKM", L"FKN", L"FKO", L"FKP", L"FKQ", L"FKR", L"FKS", L"FKT", L"FKU", L"FKV", L"FKW", L"FKX", L"FKY", L"FKZ", L"FLA", L"FLB", L"FLC", L"FLD", L"FLE", L"FLF", L"FLG", L"FLH", L"FLI", L"FLJ", L"FLK", L"FLL", L"FLM", L"FLN", L"FLO", L"FLP", L"FLQ", L"FLR", L"FLS", L"FLT", L"FLU", L"FLV", L"FLW", L"FLX", L"FLY", L"FLZ", L"FMA", L"FMB", L"FMC", L"FMD", L"FME", L"FMF", L"FMG", L"FMH", L"FMI", L"FMJ", L"FMK", L"FML", L"FMM", L"FMN", L"FMO", L"FMP", L"FMQ", L"FMR", L"FMS", L"FMT", L"FMU", L"FMV", L"FMW", L"FMX", L"FMY", L"FMZ", L"FNA", L"FNB", L"FNC", L"FND", L"FNE", L"FNF", L"FNG", L"FNH", L"FNI", L"FNJ", L"FNK", L"FNL", L"FNM", L"FNN", L"FNO", L"FNP", L"FNQ", L"FNR", L"FNS", L"FNT", L"FNU", L"FNV", L"FNW", L"FNX", L"FNY", L"FNZ", L"FOA", L"FOB", L"FOC", L"FOD", L"FOE", L"FOF", L"FOG", L"FOH", L"FOI", L"FOJ", L"FOK", L"FOL", L"FOM", L"FON", L"FOO", L"FOP", L"FOQ", L"FOR", L"FOS", L"FOT", L"FOU", L"FOV", L"FOW", L"FOX", L"FOY", L"FOZ", L"FPA", L"FPB", L"FPC", L"FPD", L"FPE", L"FPF", L"FPG", L"FPH", L"FPI", L"FPJ", L"FPK", L"FPL", L"FPM", L"FPN", L"FPO", L"FPP", L"FPQ", L"FPR", L"FPS", L"FPT", L"FPU", L"FPV", L"FPW", L"FPX", L"FPY", L"FPZ", L"FQA", L"FQB", L"FQC", L"FQD", L"FQE", L"FQF", L"FQG", L"FQH", L"FQI", L"FQJ", L"FQK", L"FQL", L"FQM", L"FQN", L"FQO", L"FQP", L"FQQ", L"FQR", L"FQS", L"FQT", L"FQU", L"FQV", L"FQW", L"FQX", L"FQY", L"FQZ", L"FRA", L"FRB", L"FRC", L"FRD", L"FRE", L"FRF", L"FRG", L"FRH", L"FRI", L"FRJ", L"FRK", L"FRL", L"FRM", L"FRN", L"FRO", L"FRP", L"FRQ", L"FRR", L"FRS", L"FRT", L"FRU", L"FRV", L"FRW", L"FRX", L"FRY", L"FRZ", L"FSA", L"FSB", L"FSC", L"FSD", L"FSE", L"FSF", L"FSG", L"FSH", L"FSI", L"FSJ", L"FSK", L"FSL", L"FSM", L"FSN", L"FSO", L"FSP", L"FSQ", L"FSR", L"FSS", L"FST", L"FSU", L"FSV", L"FSW", L"FSX", L"FSY", L"FSZ", L"FTA", L"FTB", L"FTC", L"FTD", L"FTE", L"FTF", L"FTG", L"FTH", L"FTI", L"FTJ", L"FTK", L"FTL", L"FTM", L"FTN", L"FTO", L"FTP", L"FTQ", L"FTR", L"FTS", L"FTT", L"FTU", L"FTV", L"FTW", L"FTX", L"FTY", L"FTZ", L"FUA", L"FUB", L"FUC", L"FUD", L"FUE", L"FUF", L"FUG", L"FUH", L"FUI", L"FUJ", L"FUK", L"FUL", L"FUM", L"FUN", L"FUO", L"FUP", L"FUQ", L"FUR", L"FUS", L"FUT", L"FUU", L"FUV", L"FUW", L"FUX", L"FUY", L"FUZ", L"FVA", L"FVB", L"FVC", L"FVD", L"FVE", L"FVF", L"FVG", L"FVH", L"FVI", L"FVJ", L"FVK", L"FVL", L"FVM", L"FVN", L"FVO", L"FVP", L"FVQ", L"FVR", L"FVS", L"FVT", L"FVU", L"FVV", L"FVW", L"FVX", L"FVY", L"FVZ", L"FWA", L"FWB", L"FWC", L"FWD", L"FWE", L"FWF", L"FWG", L"FWH", L"FWI", L"FWJ", L"FWK", L"FWL", L"FWM", L"FWN", L"FWO", L"FWP", L"FWQ", L"FWR", L"FWS", L"FWT", L"FWU", L"FWV", L"FWW", L"FWX", L"FWY", L"FWZ", L"FXA", L"FXB", L"FXC", L"FXD", L"FXE", L"FXF", L"FXG", L"FXH", L"FXI", L"FXJ", L"FXK", L"FXL", L"FXM", L"FXN", L"FXO", L"FXP", L"FXQ", L"FXR", L"FXS", L"FXT", L"FXU", L"FXV", L"FXW", L"FXX", L"FXY", L"FXZ", L"FYA", L"FYB", L"FYC", L"FYD", L"FYE", L"FYF", L"FYG", L"FYH", L"FYI", L"FYJ", L"FYK", L"FYL", L"FYM", L"FYN", L"FYO", L"FYP", L"FYQ", L"FYR", L"FYS", L"FYT", L"FYU", L"FYV", L"FYW", L"FYX", L"FYY", L"FYZ", L"FZA", L"FZB", L"FZC", L"FZD", L"FZE", L"FZF", L"FZG", L"FZH", L"FZI", L"FZJ", L"FZK", L"FZL", L"FZM", L"FZN", L"FZO", L"FZP", L"FZQ", L"FZR", L"FZS", L"FZT", L"FZU", L"FZV", L"FZW", L"FZX", L"FZY", L"FZZ", L"GAA", L"GAB", L"GAC", L"GAD", L"GAE", L"GAF", L"GAG", L"GAH", L"GAI", L"GAJ", L"GAK", L"GAL", L"GAM", L"GAN", L"GAO", L"GAP", L"GAQ", L"GAR", L"GAS", L"GAT", L"GAU", L"GAV", L"GAW", L"GAX", L"GAY", L"GAZ", L"GBA", L"GBB", L"GBC", L"GBD", L"GBE", L"GBF", L"GBG", L"GBH", L"GBI", L"GBJ", L"GBK", L"GBL", L"GBM", L"GBN", L"GBO", L"GBP", L"GBQ", L"GBR", L"GBS", L"GBT", L"GBU", L"GBV", L"GBW", L"GBX", L"GBY", L"GBZ", L"GCA", L"GCB", L"GCC", L"GCD", L"GCE", L"GCF", L"GCG", L"GCH", L"GCI", L"GCJ", L"GCK", L"GCL", L"GCM", L"GCN", L"GCO", L"GCP", L"GCQ", L"GCR", L"GCS", L"GCT", L"GCU", L"GCV", L"GCW", L"GCX", L"GCY", L"GCZ", L"GDA", L"GDB", L"GDC", L"GDD", L"GDE", L"GDF", L"GDG", L"GDH", L"GDI", L"GDJ", L"GDK", L"GDL", L"GDM", L"GDN", L"GDO", L"GDP", L"GDQ", L"GDR", L"GDS", L"GDT", L"GDU", L"GDV", L"GDW", L"GDX", L"GDY", L"GDZ", L"GEA", L"GEB", L"GEC", L"GED", L"GEE", L"GEF", L"GEG", L"GEH", L"GEI", L"GEJ", L"GEK", L"GEL", L"GEM", L"GEN", L"GEO", L"GEP", L"GEQ", L"GER", L"GES", L"GET", L"GEU", L"GEV", L"GEW", L"GEX", L"GEY", L"GEZ", L"GFA", L"GFB", L"GFC", L"GFD", L"GFE", L"GFF", L"GFG", L"GFH", L"GFI", L"GFJ", L"GFK", L"GFL", L"GFM", L"GFN", L"GFO", L"GFP", L"GFQ", L"GFR", L"GFS", L"GFT", L"GFU", L"GFV", L"GFW", L"GFX", L"GFY", L"GFZ", L"GGA", L"GGB", L"GGC", L"GGD", L"GGE", L"GGF", L"GGG", L"GGH", L"GGI", L"GGJ", L"GGK", L"GGL", L"GGM", L"GGN", L"GGO", L"GGP", L"GGQ", L"GGR", L"GGS", L"GGT", L"GGU", L"GGV", L"GGW", L"GGX", L"GGY", L"GGZ", L"GHA", L"GHB", L"GHC", L"GHD", L"GHE", L"GHF", L"GHG", L"GHH", L"GHI", L"GHJ", L"GHK", L"GHL", L"GHM", L"GHN", L"GHO", L"GHP", L"GHQ", L"GHR", L"GHS", L"GHT", L"GHU", L"GHV", L"GHW", L"GHX", L"GHY", L"GHZ", L"GIA", L"GIB", L"GIC", L"GID", L"GIE", L"GIF", L"GIG", L"GIH", L"GII", L"GIJ", L"GIK", L"GIL", L"GIM", L"GIN", L"GIO", L"GIP", L"GIQ", L"GIR", L"GIS", - L"GIT", L"GIU", L"GIV", L"GIW", L"GIX", L"GIY", L"GIZ", L"GJA", L"GJB", L"GJC", L"GJD", L"GJE", L"GJF", L"GJG", L"GJH", L"GJI", L"GJJ", L"GJK", L"GJL", L"GJM", L"GJN", L"GJO", L"GJP", L"GJQ", L"GJR", L"GJS", L"GJT", L"GJU", L"GJV", L"GJW", L"GJX", L"GJY", L"GJZ", L"GKA", L"GKB", L"GKC", L"GKD", L"GKE", L"GKF", L"GKG", L"GKH", L"GKI", L"GKJ", L"GKK", L"GKL", L"GKM", L"GKN", L"GKO", L"GKP", L"GKQ", L"GKR", L"GKS", L"GKT", L"GKU", L"GKV", L"GKW", L"GKX", L"GKY", L"GKZ", L"GLA", L"GLB", L"GLC", L"GLD", L"GLE", L"GLF", L"GLG", L"GLH", L"GLI", L"GLJ", L"GLK", L"GLL", L"GLM", L"GLN", L"GLO", L"GLP", L"GLQ", L"GLR", L"GLS", L"GLT", L"GLU", L"GLV", L"GLW", L"GLX", L"GLY", L"GLZ", L"GMA", L"GMB", L"GMC", L"GMD", L"GME", L"GMF", L"GMG", L"GMH", L"GMI", L"GMJ", L"GMK", L"GML", L"GMM", L"GMN", L"GMO", L"GMP", L"GMQ", L"GMR", L"GMS", L"GMT", L"GMU", L"GMV", L"GMW", L"GMX", L"GMY", L"GMZ", L"GNA", L"GNB", L"GNC", L"GND", L"GNE", L"GNF", L"GNG", L"GNH", L"GNI", L"GNJ", L"GNK", L"GNL", L"GNM", L"GNN", L"GNO", L"GNP", L"GNQ", L"GNR", L"GNS", L"GNT", L"GNU", L"GNV", L"GNW", L"GNX", L"GNY", L"GNZ", L"GOA", L"GOB", L"GOC", L"GOD", L"GOE", L"GOF", L"GOG", L"GOH", L"GOI", L"GOJ", L"GOK", L"GOL", L"GOM", L"GON", L"GOO", L"GOP", L"GOQ", L"GOR", L"GOS", L"GOT", L"GOU", L"GOV", L"GOW", L"GOX", L"GOY", L"GOZ", L"GPA", L"GPB", L"GPC", L"GPD", L"GPE", L"GPF", L"GPG", L"GPH", L"GPI", L"GPJ", L"GPK", L"GPL", L"GPM", L"GPN", L"GPO", L"GPP", L"GPQ", L"GPR", L"GPS", L"GPT", L"GPU", L"GPV", L"GPW", L"GPX", L"GPY", L"GPZ", L"GQA", L"GQB", L"GQC", L"GQD", L"GQE", L"GQF", L"GQG", L"GQH", L"GQI", L"GQJ", L"GQK", L"GQL", L"GQM", L"GQN", L"GQO", L"GQP", L"GQQ", L"GQR", L"GQS", L"GQT", L"GQU", L"GQV", L"GQW", L"GQX", L"GQY", L"GQZ", L"GRA", L"GRB", L"GRC", L"GRD", L"GRE", L"GRF", L"GRG", L"GRH", L"GRI", L"GRJ", L"GRK", L"GRL", L"GRM", L"GRN", L"GRO", L"GRP", L"GRQ", L"GRR", L"GRS", L"GRT", L"GRU", L"GRV", L"GRW", L"GRX", L"GRY", L"GRZ", L"GSA", L"GSB", L"GSC", L"GSD", L"GSE", L"GSF", L"GSG", L"GSH", L"GSI", L"GSJ", L"GSK", L"GSL", L"GSM", L"GSN", L"GSO", L"GSP", L"GSQ", L"GSR", L"GSS", L"GST", L"GSU", L"GSV", L"GSW", L"GSX", L"GSY", L"GSZ", L"GTA", L"GTB", L"GTC", L"GTD", L"GTE", L"GTF", - L"GTG", L"GTH", L"GTI", L"GTJ", L"GTK", L"GTL", L"GTM", L"GTN", L"GTO", L"GTP", L"GTQ", L"GTR", L"GTS", L"GTT", L"GTU", L"GTV", L"GTW", L"GTX", L"GTY", L"GTZ", L"GUA", L"GUB", L"GUC", L"GUD", L"GUE", L"GUF", L"GUG", L"GUH", L"GUI", L"GUJ", L"GUK", L"GUL", L"GUM", L"GUN", L"GUO", L"GUP", L"GUQ", L"GUR", L"GUS", L"GUT", L"GUU", L"GUV", L"GUW", L"GUX", L"GUY", L"GUZ", L"GVA", L"GVB", L"GVC", L"GVD", L"GVE", L"GVF", L"GVG", L"GVH", L"GVI", L"GVJ", L"GVK", L"GVL", L"GVM", L"GVN", L"GVO", L"GVP", L"GVQ", L"GVR", L"GVS", L"GVT", L"GVU", L"GVV", L"GVW", L"GVX", L"GVY", L"GVZ", L"GWA", L"GWB", L"GWC", L"GWD", L"GWE", L"GWF", L"GWG", L"GWH", L"GWI", L"GWJ", L"GWK", L"GWL", L"GWM", L"GWN", L"GWO", L"GWP", L"GWQ", L"GWR", L"GWS", L"GWT", L"GWU", L"GWV", L"GWW", L"GWX", L"GWY", L"GWZ", L"GXA", L"GXB", L"GXC", L"GXD", L"GXE", L"GXF", L"GXG", L"GXH", L"GXI", L"GXJ", L"GXK", L"GXL", L"GXM", L"GXN", L"GXO", L"GXP", L"GXQ", L"GXR", L"GXS", L"GXT", L"GXU", L"GXV", L"GXW", L"GXX", L"GXY", L"GXZ", L"GYA", L"GYB", L"GYC", L"GYD", L"GYE", L"GYF", L"GYG", L"GYH", L"GYI", L"GYJ", L"GYK", L"GYL", L"GYM", L"GYN", L"GYO", L"GYP", L"GYQ", L"GYR", L"GYS", L"GYT", L"GYU", L"GYV", L"GYW", L"GYX", L"GYY", L"GYZ", L"GZA", L"GZB", L"GZC", L"GZD", L"GZE", L"GZF", L"GZG", L"GZH", L"GZI", L"GZJ", L"GZK", L"GZL", L"GZM", L"GZN", L"GZO", L"GZP", L"GZQ", L"GZR", L"GZS", L"GZT", L"GZU", L"GZV", L"GZW", L"GZX", L"GZY", L"GZZ", L"HAA", L"HAB", L"HAC", L"HAD", L"HAE", L"HAF", L"HAG", L"HAH", L"HAI", L"HAJ", L"HAK", L"HAL", L"HAM", L"HAN", L"HAO", L"HAP", L"HAQ", L"HAR", L"HAS", L"HAT", L"HAU", L"HAV", L"HAW", L"HAX", L"HAY", L"HAZ", L"HBA", L"HBB", L"HBC", L"HBD", L"HBE", L"HBF", L"HBG", L"HBH", L"HBI", L"HBJ", L"HBK", L"HBL", L"HBM", L"HBN", L"HBO", L"HBP", L"HBQ", L"HBR", L"HBS", L"HBT", L"HBU", L"HBV", L"HBW", L"HBX", L"HBY", L"HBZ", L"HCA", L"HCB", L"HCC", L"HCD", L"HCE", L"HCF", L"HCG", L"HCH", L"HCI", L"HCJ", L"HCK", L"HCL", L"HCM", L"HCN", L"HCO", L"HCP", L"HCQ", L"HCR", L"HCS", L"HCT", L"HCU", L"HCV", L"HCW", L"HCX", L"HCY", L"HCZ", L"HDA", L"HDB", L"HDC", L"HDD", L"HDE", L"HDF", L"HDG", L"HDH", L"HDI", L"HDJ", L"HDK", L"HDL", L"HDM", L"HDN", L"HDO", L"HDP", L"HDQ", L"HDR", L"HDS", - L"HDT", L"HDU", L"HDV", L"HDW", L"HDX", L"HDY", L"HDZ", L"HEA", L"HEB", L"HEC", L"HED", L"HEE", L"HEF", L"HEG", L"HEH", L"HEI", L"HEJ", L"HEK", L"HEL", L"HEM", L"HEN", L"HEO", L"HEP", L"HEQ", L"HER", L"HES", L"HET", L"HEU", L"HEV", L"HEW", L"HEX", L"HEY", L"HEZ", L"HFA", L"HFB", L"HFC", L"HFD", L"HFE", L"HFF", L"HFG", L"HFH", L"HFI", L"HFJ", L"HFK", L"HFL", L"HFM", L"HFN", L"HFO", L"HFP", L"HFQ", L"HFR", L"HFS", L"HFT", L"HFU", L"HFV", L"HFW", L"HFX", L"HFY", L"HFZ", L"HGA", L"HGB", L"HGC", L"HGD", L"HGE", L"HGF", L"HGG", L"HGH", L"HGI", L"HGJ", L"HGK", L"HGL", L"HGM", L"HGN", L"HGO", L"HGP", L"HGQ", L"HGR", L"HGS", L"HGT", L"HGU", L"HGV", L"HGW", L"HGX", L"HGY", L"HGZ", L"HHA", L"HHB", L"HHC", L"HHD", L"HHE", L"HHF", L"HHG", L"HHH", L"HHI", L"HHJ", L"HHK", L"HHL", L"HHM", L"HHN", L"HHO", L"HHP", L"HHQ", L"HHR", L"HHS", L"HHT", L"HHU", L"HHV", L"HHW", L"HHX", L"HHY", L"HHZ", L"HIA", L"HIB", L"HIC", L"HID", L"HIE", L"HIF", L"HIG", L"HIH", L"HII", L"HIJ", L"HIK", L"HIL", L"HIM", L"HIN", L"HIO", L"HIP", L"HIQ", L"HIR", L"HIS", L"HIT", L"HIU", L"HIV", L"HIW", L"HIX", L"HIY", L"HIZ", L"HJA", L"HJB", L"HJC", L"HJD", L"HJE", L"HJF", L"HJG", L"HJH", L"HJI", L"HJJ", L"HJK", L"HJL", L"HJM", L"HJN", L"HJO", L"HJP", L"HJQ", L"HJR", L"HJS", L"HJT", L"HJU", L"HJV", L"HJW", L"HJX", L"HJY", L"HJZ", L"HKA", L"HKB", L"HKC", L"HKD", L"HKE", L"HKF", L"HKG", L"HKH", L"HKI", L"HKJ", L"HKK", L"HKL", L"HKM", L"HKN", L"HKO", L"HKP", L"HKQ", L"HKR", L"HKS", L"HKT", L"HKU", L"HKV", L"HKW", L"HKX", L"HKY", L"HKZ", L"HLA", L"HLB", L"HLC", L"HLD", L"HLE", L"HLF", L"HLG", L"HLH", L"HLI", L"HLJ", L"HLK", L"HLL", L"HLM", L"HLN", L"HLO", L"HLP", L"HLQ", L"HLR", L"HLS", L"HLT", L"HLU", L"HLV", L"HLW", L"HLX", L"HLY", L"HLZ", L"HMA", L"HMB", L"HMC", L"HMD", L"HME", L"HMF", L"HMG", L"HMH", L"HMI", L"HMJ", L"HMK", L"HML", L"HMM", L"HMN", L"HMO", L"HMP", L"HMQ", L"HMR", L"HMS", L"HMT", L"HMU", L"HMV", L"HMW", L"HMX", L"HMY", L"HMZ", L"HNA", L"HNB", L"HNC", L"HND", L"HNE", L"HNF", L"HNG", L"HNH", L"HNI", L"HNJ", L"HNK", L"HNL", L"HNM", L"HNN", L"HNO", L"HNP", L"HNQ", L"HNR", L"HNS", L"HNT", L"HNU", L"HNV", L"HNW", L"HNX", L"HNY", L"HNZ", L"HOA", L"HOB", L"HOC", L"HOD", L"HOE", L"HOF", + L"GIT", L"GIU", L"GIV", L"GIW", L"GIX", L"GIY", L"GIZ", L"GJA", L"GJB", L"GJC", L"GJD", L"GJE", L"GJF", L"GJG", L"GJH", L"GJI", L"GJJ", L"GJK", L"GJL", L"GJM", L"GJN", L"GJO", L"GJP", L"GJQ", L"GJR", L"GJS", L"GJT", L"GJU", L"GJV", L"GJW", L"GJX", L"GJY", L"GJZ", L"GKA", L"GKB", L"GKC", L"GKD", L"GKE", L"GKF", L"GKG", L"GKH", L"GKI", L"GKJ", L"GKK", L"GKL", L"GKM", L"GKN", L"GKO", L"GKP", L"GKQ", L"GKR", L"GKS", L"GKT", L"GKU", L"GKV", L"GKW", L"GKX", L"GKY", L"GKZ", L"GLA", L"GLB", L"GLC", L"GLD", L"GLE", L"GLF", L"GLG", L"GLH", L"GLI", L"GLJ", L"GLK", L"GLL", L"GLM", L"GLN", L"GLO", L"GLP", L"GLQ", L"GLR", L"GLS", L"GLT", L"GLU", L"GLV", L"GLW", L"GLX", L"GLY", L"GLZ", L"GMA", L"GMB", L"GMC", L"GMD", L"GME", L"GMF", L"GMG", L"GMH", L"GMI", L"GMJ", L"GMK", L"GML", L"GMM", L"GMN", L"GMO", L"GMP", L"GMQ", L"GMR", L"GMS", L"GMT", L"GMU", L"GMV", L"GMW", L"GMX", L"GMY", L"GMZ", L"GNA", L"GNB", L"GNC", L"GND", L"GNE", L"GNF", L"GNG", L"GNH", L"GNI", L"GNJ", L"GNK", L"GNL", L"GNM", L"GNN", L"GNO", L"GNP", L"GNQ", L"GNR", L"GNS", L"GNT", L"GNU", L"GNV", L"GNW", L"GNX", L"GNY", L"GNZ", L"GOA", L"GOB", L"GOC", L"GOD", L"GOE", L"GOF", L"GOG", L"GOH", L"GOI", L"GOJ", L"GOK", L"GOL", L"GOM", L"GON", L"GOO", L"GOP", L"GOQ", L"GOR", L"GOS", L"GOT", L"GOU", L"GOV", L"GOW", L"GOX", L"GOY", L"GOZ", L"GPA", L"GPB", L"GPC", L"GPD", L"GPE", L"GPF", L"GPG", L"GPH", L"GPI", L"GPJ", L"GPK", L"GPL", L"GPM", L"GPN", L"GPO", L"GPP", L"GPQ", L"GPR", L"GPS", L"GPT", L"GPU", L"GPV", L"GPW", L"GPX", L"GPY", L"GPZ", L"GQA", L"GQB", L"GQC", L"GQD", L"GQE", L"GQF", L"GQG", L"GQH", L"GQI", L"GQJ", L"GQK", L"GQL", L"GQM", L"GQN", L"GQO", L"GQP", L"GQQ", L"GQR", L"GQS", L"GQT", L"GQU", L"GQV", L"GQW", L"GQX", L"GQY", L"GQZ", L"GRA", L"GRB", L"GRC", L"GRD", L"GRE", L"GRF", L"GRG", L"GRH", L"GRI", L"GRJ", L"GRK", L"GRL", L"GRM", L"GRN", L"GRO", L"GRP", L"GRQ", L"GRR", L"GRS", L"GRT", L"GRU", L"GRV", L"GRW", L"GRX", L"GRY", L"GRZ", L"GSA", L"GSB", L"GSC", L"GSD", L"GSE", L"GSF", L"GSG", L"GSH", L"GSI", L"GSJ", L"GSK", L"GSL", L"GSM", L"GSN", L"GSO", L"GSP", L"GSQ", L"GSR", L"GSS", L"GST", L"GSU", L"GSV", L"GSW", L"GSX", L"GSY", L"GSZ", L"GTA", L"GTB", L"GTC", L"GTD", L"GTE", L"GTF", + L"GTG", L"GTH", L"GTI", L"GTJ", L"GTK", L"GTL", L"GTM", L"GTN", L"GTO", L"GTP", L"GTQ", L"GTR", L"GTS", L"GTT", L"GTU", L"GTV", L"GTW", L"GTX", L"GTY", L"GTZ", L"GUA", L"GUB", L"GUC", L"GUD", L"GUE", L"GUF", L"GUG", L"GUH", L"GUI", L"GUJ", L"GUK", L"GUL", L"GUM", L"GUN", L"GUO", L"GUP", L"GUQ", L"GUR", L"GUS", L"GUT", L"GUU", L"GUV", L"GUW", L"GUX", L"GUY", L"GUZ", L"GVA", L"GVB", L"GVC", L"GVD", L"GVE", L"GVF", L"GVG", L"GVH", L"GVI", L"GVJ", L"GVK", L"GVL", L"GVM", L"GVN", L"GVO", L"GVP", L"GVQ", L"GVR", L"GVS", L"GVT", L"GVU", L"GVV", L"GVW", L"GVX", L"GVY", L"GVZ", L"GWA", L"GWB", L"GWC", L"GWD", L"GWE", L"GWF", L"GWG", L"GWH", L"GWI", L"GWJ", L"GWK", L"GWL", L"GWM", L"GWN", L"GWO", L"GWP", L"GWQ", L"GWR", L"GWS", L"GWT", L"GWU", L"GWV", L"GWW", L"GWX", L"GWY", L"GWZ", L"GXA", L"GXB", L"GXC", L"GXD", L"GXE", L"GXF", L"GXG", L"GXH", L"GXI", L"GXJ", L"GXK", L"GXL", L"GXM", L"GXN", L"GXO", L"GXP", L"GXQ", L"GXR", L"GXS", L"GXT", L"GXU", L"GXV", L"GXW", L"GXX", L"GXY", L"GXZ", L"GYA", L"GYB", L"GYC", L"GYD", L"GYE", L"GYF", L"GYG", L"GYH", L"GYI", L"GYJ", L"GYK", L"GYL", L"GYM", L"GYN", L"GYO", L"GYP", L"GYQ", L"GYR", L"GYS", L"GYT", L"GYU", L"GYV", L"GYW", L"GYX", L"GYY", L"GYZ", L"GZA", L"GZB", L"GZC", L"GZD", L"GZE", L"GZF", L"GZG", L"GZH", L"GZI", L"GZJ", L"GZK", L"GZL", L"GZM", L"GZN", L"GZO", L"GZP", L"GZQ", L"GZR", L"GZS", L"GZT", L"GZU", L"GZV", L"GZW", L"GZX", L"GZY", L"GZZ", L"HAA", L"HAB", L"HAC", L"HAD", L"HAE", L"HAF", L"HAG", L"HAH", L"HAI", L"HAJ", L"HAK", L"HAL", L"HAM", L"HAN", L"HAO", L"HAP", L"HAQ", L"HAR", L"HAS", L"HAT", L"HAU", L"HAV", L"HAW", L"HAX", L"HAY", L"HAZ", L"HBA", L"HBB", L"HBC", L"HBD", L"HBE", L"HBF", L"HBG", L"HBH", L"HBI", L"HBJ", L"HBK", L"HBL", L"HBM", L"HBN", L"HBO", L"HBP", L"HBQ", L"HBR", L"HBS", L"HBT", L"HBU", L"HBV", L"HBW", L"HBX", L"HBY", L"HBZ", L"HCA", L"HCB", L"HCC", L"HCD", L"HCE", L"HCF", L"HCG", L"HCH", L"HCI", L"HCJ", L"HCK", L"HCL", L"HCM", L"HCN", L"HCO", L"HCP", L"HCQ", L"HCR", L"HCS", L"HCT", L"HCU", L"HCV", L"HCW", L"HCX", L"HCY", L"HCZ", L"HDA", L"HDB", L"HDC", L"HDD", L"HDE", L"HDF", L"HDG", L"HDH", L"HDI", L"HDJ", L"HDK", L"HDL", L"HDM", L"HDN", L"HDO", L"HDP", L"HDQ", L"HDR", L"HDS", + L"HDT", L"HDU", L"HDV", L"HDW", L"HDX", L"HDY", L"HDZ", L"HEA", L"HEB", L"HEC", L"HED", L"HEE", L"HEF", L"HEG", L"HEH", L"HEI", L"HEJ", L"HEK", L"HEL", L"HEM", L"HEN", L"HEO", L"HEP", L"HEQ", L"HER", L"HES", L"HET", L"HEU", L"HEV", L"HEW", L"HEX", L"HEY", L"HEZ", L"HFA", L"HFB", L"HFC", L"HFD", L"HFE", L"HFF", L"HFG", L"HFH", L"HFI", L"HFJ", L"HFK", L"HFL", L"HFM", L"HFN", L"HFO", L"HFP", L"HFQ", L"HFR", L"HFS", L"HFT", L"HFU", L"HFV", L"HFW", L"HFX", L"HFY", L"HFZ", L"HGA", L"HGB", L"HGC", L"HGD", L"HGE", L"HGF", L"HGG", L"HGH", L"HGI", L"HGJ", L"HGK", L"HGL", L"HGM", L"HGN", L"HGO", L"HGP", L"HGQ", L"HGR", L"HGS", L"HGT", L"HGU", L"HGV", L"HGW", L"HGX", L"HGY", L"HGZ", L"HHA", L"HHB", L"HHC", L"HHD", L"HHE", L"HHF", L"HHG", L"HHH", L"HHI", L"HHJ", L"HHK", L"HHL", L"HHM", L"HHN", L"HHO", L"HHP", L"HHQ", L"HHR", L"HHS", L"HHT", L"HHU", L"HHV", L"HHW", L"HHX", L"HHY", L"HHZ", L"HIA", L"HIB", L"HIC", L"HID", L"HIE", L"HIF", L"HIG", L"HIH", L"HII", L"HIJ", L"HIK", L"HIL", L"HIM", L"HIN", L"HIO", L"HIP", L"HIQ", L"HIR", L"HIS", L"HIT", L"HIU", L"HIV", L"HIW", L"HIX", L"HIY", L"HIZ", L"HJA", L"HJB", L"HJC", L"HJD", L"HJE", L"HJF", L"HJG", L"HJH", L"HJI", L"HJJ", L"HJK", L"HJL", L"HJM", L"HJN", L"HJO", L"HJP", L"HJQ", L"HJR", L"HJS", L"HJT", L"HJU", L"HJV", L"HJW", L"HJX", L"HJY", L"HJZ", L"HKA", L"HKB", L"HKC", L"HKD", L"HKE", L"HKF", L"HKG", L"HKH", L"HKI", L"HKJ", L"HKK", L"HKL", L"HKM", L"HKN", L"HKO", L"HKP", L"HKQ", L"HKR", L"HKS", L"HKT", L"HKU", L"HKV", L"HKW", L"HKX", L"HKY", L"HKZ", L"HLA", L"HLB", L"HLC", L"HLD", L"HLE", L"HLF", L"HLG", L"HLH", L"HLI", L"HLJ", L"HLK", L"HLL", L"HLM", L"HLN", L"HLO", L"HLP", L"HLQ", L"HLR", L"HLS", L"HLT", L"HLU", L"HLV", L"HLW", L"HLX", L"HLY", L"HLZ", L"HMA", L"HMB", L"HMC", L"HMD", L"HME", L"HMF", L"HMG", L"HMH", L"HMI", L"HMJ", L"HMK", L"HML", L"HMM", L"HMN", L"HMO", L"HMP", L"HMQ", L"HMR", L"HMS", L"HMT", L"HMU", L"HMV", L"HMW", L"HMX", L"HMY", L"HMZ", L"HNA", L"HNB", L"HNC", L"HND", L"HNE", L"HNF", L"HNG", L"HNH", L"HNI", L"HNJ", L"HNK", L"HNL", L"HNM", L"HNN", L"HNO", L"HNP", L"HNQ", L"HNR", L"HNS", L"HNT", L"HNU", L"HNV", L"HNW", L"HNX", L"HNY", L"HNZ", L"HOA", L"HOB", L"HOC", L"HOD", L"HOE", L"HOF", L"HOG", L"HOH", L"HOI", L"HOJ", L"HOK", L"HOL", L"HOM", L"HON", L"HOO", L"HOP", L"HOQ", L"HOR", L"HOS", L"HOT", L"HOU", L"HOV", L"HOW", L"HOX", L"HOY", L"HOZ", L"HPA", L"HPB", L"HPC", L"HPD", L"HPE", L"HPF", L"HPG", L"HPH", L"HPI", L"HPJ", L"HPK", L"HPL", L"HPM", L"HPN", L"HPO", L"HPP", L"HPQ", L"HPR", L"HPS", L"HPT", L"HPU", L"HPV", L"HPW", L"HPX", L"HPY", L"HPZ", L"HQA", L"HQB", L"HQC", L"HQD", L"HQE", L"HQF", L"HQG", L"HQH", L"HQI", L"HQJ", L"HQK", L"HQL", L"HQM", L"HQN", L"HQO", L"HQP", L"HQQ", L"HQR", L"HQS", L"HQT", L"HQU", L"HQV", L"HQW", L"HQX", L"HQY", L"HQZ", L"HRA", L"HRB", L"HRC", L"HRD", L"HRE", L"HRF", L"HRG", L"HRH", L"HRI", L"HRJ", L"HRK", L"HRL", L"HRM", L"HRN", L"HRO", L"HRP", L"HRQ", L"HRR", L"HRS", L"HRT", L"HRU", L"HRV", L"HRW", L"HRX", L"HRY", L"HRZ", L"HSA", L"HSB", L"HSC", L"HSD", L"HSE", L"HSF", L"HSG", L"HSH", L"HSI", L"HSJ", L"HSK", L"HSL", L"HSM", L"HSN", L"HSO", L"HSP", L"HSQ", L"HSR", L"HSS", L"HST", L"HSU", L"HSV", L"HSW", L"HSX", L"HSY", L"HSZ", L"HTA", L"HTB", L"HTC", L"HTD", L"HTE", L"HTF", L"HTG", L"HTH", L"HTI", L"HTJ", L"HTK", L"HTL", L"HTM", L"HTN", L"HTO", L"HTP", L"HTQ", L"HTR", L"HTS", L"HTT", L"HTU", L"HTV", L"HTW", L"HTX", L"HTY", L"HTZ", L"HUA", L"HUB", L"HUC", L"HUD", L"HUE", L"HUF", L"HUG", L"HUH", L"HUI", L"HUJ", L"HUK", L"HUL", L"HUM", L"HUN", L"HUO", L"HUP", L"HUQ", L"HUR", L"HUS", L"HUT", L"HUU", L"HUV", L"HUW", L"HUX", L"HUY", L"HUZ", L"HVA", L"HVB", L"HVC", L"HVD", L"HVE", L"HVF", L"HVG", L"HVH", L"HVI", L"HVJ", L"HVK", L"HVL", L"HVM", L"HVN", L"HVO", L"HVP", L"HVQ", L"HVR", L"HVS", L"HVT", L"HVU", L"HVV", L"HVW", L"HVX", L"HVY", L"HVZ", L"HWA", L"HWB", L"HWC", L"HWD", L"HWE", L"HWF", L"HWG", L"HWH", L"HWI", L"HWJ", L"HWK", L"HWL", L"HWM", L"HWN", L"HWO", L"HWP", L"HWQ", L"HWR", L"HWS", L"HWT", L"HWU", L"HWV", L"HWW", L"HWX", L"HWY", L"HWZ", L"HXA", L"HXB", L"HXC", L"HXD", L"HXE", L"HXF", L"HXG", L"HXH", L"HXI", L"HXJ", L"HXK", L"HXL", L"HXM", L"HXN", L"HXO", L"HXP", L"HXQ", L"HXR", L"HXS", L"HXT", L"HXU", L"HXV", L"HXW", L"HXX", L"HXY", L"HXZ", L"HYA", L"HYB", L"HYC", L"HYD", L"HYE", L"HYF", L"HYG", L"HYH", L"HYI", L"HYJ", L"HYK", L"HYL", L"HYM", L"HYN", L"HYO", L"HYP", L"HYQ", L"HYR", L"HYS", L"HYT", L"HYU", L"HYV", L"HYW", L"HYX", L"HYY", L"HYZ", L"HZA", L"HZB", L"HZC", L"HZD", L"HZE", L"HZF", L"HZG", L"HZH", L"HZI", L"HZJ", L"HZK", L"HZL", L"HZM", L"HZN", L"HZO", L"HZP", L"HZQ", L"HZR", L"HZS", L"HZT", L"HZU", L"HZV", L"HZW", L"HZX", L"HZY", L"HZZ", L"IAA", L"IAB", L"IAC", L"IAD", L"IAE", L"IAF", L"IAG", L"IAH", L"IAI", L"IAJ", L"IAK", L"IAL", L"IAM", L"IAN", L"IAO", L"IAP", L"IAQ", L"IAR", L"IAS", L"IAT", L"IAU", L"IAV", L"IAW", L"IAX", L"IAY", L"IAZ", L"IBA", L"IBB", L"IBC", L"IBD", L"IBE", L"IBF", L"IBG", L"IBH", L"IBI", L"IBJ", L"IBK", L"IBL", L"IBM", L"IBN", L"IBO", L"IBP", L"IBQ", L"IBR", L"IBS", L"IBT", L"IBU", L"IBV", L"IBW", L"IBX", L"IBY", L"IBZ", L"ICA", L"ICB", L"ICC", L"ICD", L"ICE", L"ICF", L"ICG", L"ICH", L"ICI", L"ICJ", L"ICK", L"ICL", L"ICM", L"ICN", L"ICO", L"ICP", L"ICQ", L"ICR", L"ICS", L"ICT", L"ICU", L"ICV", L"ICW", L"ICX", L"ICY", L"ICZ", L"IDA", L"IDB", L"IDC", L"IDD", L"IDE", L"IDF", L"IDG", L"IDH", L"IDI", L"IDJ", L"IDK", L"IDL", L"IDM", L"IDN", L"IDO", L"IDP", L"IDQ", L"IDR", L"IDS", L"IDT", L"IDU", L"IDV", L"IDW", L"IDX", L"IDY", L"IDZ", L"IEA", L"IEB", L"IEC", L"IED", L"IEE", L"IEF", L"IEG", L"IEH", L"IEI", L"IEJ", L"IEK", L"IEL", L"IEM", L"IEN", L"IEO", L"IEP", L"IEQ", L"IER", L"IES", L"IET", L"IEU", L"IEV", L"IEW", L"IEX", L"IEY", L"IEZ", L"IFA", L"IFB", L"IFC", L"IFD", L"IFE", L"IFF", L"IFG", L"IFH", L"IFI", L"IFJ", L"IFK", L"IFL", L"IFM", L"IFN", L"IFO", L"IFP", L"IFQ", L"IFR", L"IFS", L"IFT", L"IFU", L"IFV", L"IFW", L"IFX", L"IFY", L"IFZ", L"IGA", L"IGB", L"IGC", L"IGD", L"IGE", L"IGF", L"IGG", L"IGH", L"IGI", L"IGJ", L"IGK", L"IGL", L"IGM", L"IGN", L"IGO", L"IGP", L"IGQ", L"IGR", L"IGS", L"IGT", L"IGU", L"IGV", L"IGW", L"IGX", L"IGY", L"IGZ", L"IHA", L"IHB", L"IHC", L"IHD", L"IHE", L"IHF", L"IHG", L"IHH", L"IHI", L"IHJ", L"IHK", L"IHL", L"IHM", L"IHN", L"IHO", L"IHP", L"IHQ", L"IHR", L"IHS", L"IHT", L"IHU", L"IHV", L"IHW", L"IHX", L"IHY", L"IHZ", L"IIA", L"IIB", L"IIC", L"IID", L"IIE", L"IIF", L"IIG", L"IIH", L"III", L"IIJ", L"IIK", L"IIL", L"IIM", L"IIN", L"IIO", L"IIP", L"IIQ", L"IIR", L"IIS", L"IIT", L"IIU", L"IIV", L"IIW", L"IIX", L"IIY", L"IIZ", L"IJA", L"IJB", L"IJC", L"IJD", L"IJE", L"IJF", L"IJG", L"IJH", L"IJI", L"IJJ", L"IJK", L"IJL", L"IJM", L"IJN", L"IJO", L"IJP", L"IJQ", L"IJR", L"IJS", L"IJT", L"IJU", L"IJV", L"IJW", L"IJX", L"IJY", L"IJZ", L"IKA", L"IKB", L"IKC", L"IKD", L"IKE", L"IKF", L"IKG", L"IKH", L"IKI", L"IKJ", L"IKK", L"IKL", L"IKM", L"IKN", L"IKO", L"IKP", L"IKQ", L"IKR", L"IKS", L"IKT", L"IKU", L"IKV", L"IKW", L"IKX", L"IKY", L"IKZ", L"ILA", L"ILB", L"ILC", L"ILD", L"ILE", L"ILF", L"ILG", L"ILH", L"ILI", L"ILJ", L"ILK", L"ILL", L"ILM", L"ILN", L"ILO", L"ILP", L"ILQ", L"ILR", L"ILS", L"ILT", L"ILU", L"ILV", L"ILW", L"ILX", L"ILY", L"ILZ", L"IMA", L"IMB", L"IMC", L"IMD", L"IME", L"IMF", L"IMG", L"IMH", L"IMI", L"IMJ", L"IMK", L"IML", L"IMM", L"IMN", L"IMO", L"IMP", L"IMQ", L"IMR", L"IMS", L"IMT", L"IMU", L"IMV", L"IMW", L"IMX", L"IMY", L"IMZ", L"INA", L"INB", L"INC", L"IND", L"INE", L"INF", L"ING", L"INH", L"INI", L"INJ", L"INK", L"INL", L"INM", L"INN", L"INO", L"INP", L"INQ", L"INR", L"INS", L"INT", L"INU", L"INV", L"INW", L"INX", L"INY", L"INZ", L"IOA", L"IOB", L"IOC", L"IOD", L"IOE", L"IOF", L"IOG", L"IOH", L"IOI", L"IOJ", L"IOK", L"IOL", L"IOM", L"ION", L"IOO", L"IOP", L"IOQ", L"IOR", L"IOS", L"IOT", L"IOU", L"IOV", L"IOW", L"IOX", L"IOY", L"IOZ", L"IPA", L"IPB", L"IPC", L"IPD", L"IPE", L"IPF", L"IPG", L"IPH", L"IPI", L"IPJ", L"IPK", L"IPL", L"IPM", L"IPN", L"IPO", L"IPP", L"IPQ", L"IPR", L"IPS", L"IPT", L"IPU", L"IPV", L"IPW", L"IPX", L"IPY", L"IPZ", L"IQA", L"IQB", L"IQC", L"IQD", L"IQE", L"IQF", L"IQG", L"IQH", L"IQI", L"IQJ", L"IQK", L"IQL", L"IQM", L"IQN", L"IQO", L"IQP", L"IQQ", L"IQR", L"IQS", L"IQT", L"IQU", L"IQV", L"IQW", L"IQX", L"IQY", L"IQZ", L"IRA", L"IRB", L"IRC", L"IRD", L"IRE", L"IRF", L"IRG", L"IRH", L"IRI", L"IRJ", L"IRK", L"IRL", L"IRM", L"IRN", L"IRO", L"IRP", L"IRQ", L"IRR", L"IRS", L"IRT", L"IRU", L"IRV", L"IRW", L"IRX", L"IRY", L"IRZ", L"ISA", L"ISB", L"ISC", L"ISD", L"ISE", L"ISF", L"ISG", L"ISH", L"ISI", L"ISJ", L"ISK", L"ISL", L"ISM", L"ISN", L"ISO", L"ISP", L"ISQ", L"ISR", L"ISS", L"IST", L"ISU", L"ISV", L"ISW", L"ISX", L"ISY", L"ISZ", L"ITA", L"ITB", L"ITC", L"ITD", L"ITE", L"ITF", L"ITG", L"ITH", L"ITI", L"ITJ", L"ITK", @@ -97,37 +112,37 @@ namespace OOX L"JDY", L"JDZ", L"JEA", L"JEB", L"JEC", L"JED", L"JEE", L"JEF", L"JEG", L"JEH", L"JEI", L"JEJ", L"JEK", L"JEL", L"JEM", L"JEN", L"JEO", L"JEP", L"JEQ", L"JER", L"JES", L"JET", L"JEU", L"JEV", L"JEW", L"JEX", L"JEY", L"JEZ", L"JFA", L"JFB", L"JFC", L"JFD", L"JFE", L"JFF", L"JFG", L"JFH", L"JFI", L"JFJ", L"JFK", L"JFL", L"JFM", L"JFN", L"JFO", L"JFP", L"JFQ", L"JFR", L"JFS", L"JFT", L"JFU", L"JFV", L"JFW", L"JFX", L"JFY", L"JFZ", L"JGA", L"JGB", L"JGC", L"JGD", L"JGE", L"JGF", L"JGG", L"JGH", L"JGI", L"JGJ", L"JGK", L"JGL", L"JGM", L"JGN", L"JGO", L"JGP", L"JGQ", L"JGR", L"JGS", L"JGT", L"JGU", L"JGV", L"JGW", L"JGX", L"JGY", L"JGZ", L"JHA", L"JHB", L"JHC", L"JHD", L"JHE", L"JHF", L"JHG", L"JHH", L"JHI", L"JHJ", L"JHK", L"JHL", L"JHM", L"JHN", L"JHO", L"JHP", L"JHQ", L"JHR", L"JHS", L"JHT", L"JHU", L"JHV", L"JHW", L"JHX", L"JHY", L"JHZ", L"JIA", L"JIB", L"JIC", L"JID", L"JIE", L"JIF", L"JIG", L"JIH", L"JII", L"JIJ", L"JIK", L"JIL", L"JIM", L"JIN", L"JIO", L"JIP", L"JIQ", L"JIR", L"JIS", L"JIT", L"JIU", L"JIV", L"JIW", L"JIX", L"JIY", L"JIZ", L"JJA", L"JJB", L"JJC", L"JJD", L"JJE", L"JJF", L"JJG", L"JJH", L"JJI", L"JJJ", L"JJK", L"JJL", L"JJM", L"JJN", L"JJO", L"JJP", L"JJQ", L"JJR", L"JJS", L"JJT", L"JJU", L"JJV", L"JJW", L"JJX", L"JJY", L"JJZ", L"JKA", L"JKB", L"JKC", L"JKD", L"JKE", L"JKF", L"JKG", L"JKH", L"JKI", L"JKJ", L"JKK", L"JKL", L"JKM", L"JKN", L"JKO", L"JKP", L"JKQ", L"JKR", L"JKS", L"JKT", L"JKU", L"JKV", L"JKW", L"JKX", L"JKY", L"JKZ", L"JLA", L"JLB", L"JLC", L"JLD", L"JLE", L"JLF", L"JLG", L"JLH", L"JLI", L"JLJ", L"JLK", L"JLL", L"JLM", L"JLN", L"JLO", L"JLP", L"JLQ", L"JLR", L"JLS", L"JLT", L"JLU", L"JLV", L"JLW", L"JLX", L"JLY", L"JLZ", L"JMA", L"JMB", L"JMC", L"JMD", L"JME", L"JMF", L"JMG", L"JMH", L"JMI", L"JMJ", L"JMK", L"JML", L"JMM", L"JMN", L"JMO", L"JMP", L"JMQ", L"JMR", L"JMS", L"JMT", L"JMU", L"JMV", L"JMW", L"JMX", L"JMY", L"JMZ", L"JNA", L"JNB", L"JNC", L"JND", L"JNE", L"JNF", L"JNG", L"JNH", L"JNI", L"JNJ", L"JNK", L"JNL", L"JNM", L"JNN", L"JNO", L"JNP", L"JNQ", L"JNR", L"JNS", L"JNT", L"JNU", L"JNV", L"JNW", L"JNX", L"JNY", L"JNZ", L"JOA", L"JOB", L"JOC", L"JOD", L"JOE", L"JOF", L"JOG", L"JOH", L"JOI", L"JOJ", L"JOK", L"JOL", L"JOM", L"JON", L"JOO", L"JOP", L"JOQ", L"JOR", L"JOS", L"JOT", L"JOU", L"JOV", L"JOW", L"JOX", L"JOY", L"JOZ", L"JPA", L"JPB", L"JPC", L"JPD", L"JPE", L"JPF", L"JPG", L"JPH", L"JPI", L"JPJ", L"JPK", L"JPL", L"JPM", L"JPN", L"JPO", L"JPP", L"JPQ", L"JPR", L"JPS", L"JPT", L"JPU", L"JPV", L"JPW", L"JPX", L"JPY", L"JPZ", L"JQA", L"JQB", L"JQC", L"JQD", L"JQE", L"JQF", L"JQG", L"JQH", L"JQI", L"JQJ", L"JQK", L"JQL", L"JQM", L"JQN", L"JQO", L"JQP", L"JQQ", L"JQR", L"JQS", L"JQT", L"JQU", L"JQV", L"JQW", L"JQX", L"JQY", L"JQZ", L"JRA", L"JRB", L"JRC", L"JRD", L"JRE", L"JRF", L"JRG", L"JRH", L"JRI", L"JRJ", L"JRK", L"JRL", L"JRM", L"JRN", L"JRO", L"JRP", L"JRQ", L"JRR", L"JRS", L"JRT", L"JRU", L"JRV", L"JRW", L"JRX", L"JRY", L"JRZ", L"JSA", L"JSB", L"JSC", L"JSD", L"JSE", L"JSF", L"JSG", L"JSH", L"JSI", L"JSJ", L"JSK", L"JSL", L"JSM", L"JSN", L"JSO", L"JSP", L"JSQ", L"JSR", L"JSS", L"JST", L"JSU", L"JSV", L"JSW", L"JSX", L"JSY", L"JSZ", L"JTA", L"JTB", L"JTC", L"JTD", L"JTE", L"JTF", L"JTG", L"JTH", L"JTI", L"JTJ", L"JTK", L"JTL", L"JTM", L"JTN", L"JTO", L"JTP", L"JTQ", L"JTR", L"JTS", L"JTT", L"JTU", L"JTV", L"JTW", L"JTX", L"JTY", L"JTZ", L"JUA", L"JUB", L"JUC", L"JUD", L"JUE", L"JUF", L"JUG", L"JUH", L"JUI", L"JUJ", L"JUK", L"JUL", L"JUM", L"JUN", L"JUO", L"JUP", L"JUQ", L"JUR", L"JUS", L"JUT", L"JUU", L"JUV", L"JUW", L"JUX", L"JUY", L"JUZ", L"JVA", L"JVB", L"JVC", L"JVD", L"JVE", L"JVF", L"JVG", L"JVH", L"JVI", L"JVJ", L"JVK", L"JVL", L"JVM", L"JVN", L"JVO", L"JVP", L"JVQ", L"JVR", L"JVS", L"JVT", L"JVU", L"JVV", L"JVW", L"JVX", L"JVY", L"JVZ", L"JWA", L"JWB", L"JWC", L"JWD", L"JWE", L"JWF", L"JWG", L"JWH", L"JWI", L"JWJ", L"JWK", L"JWL", L"JWM", L"JWN", L"JWO", L"JWP", L"JWQ", L"JWR", L"JWS", L"JWT", L"JWU", L"JWV", L"JWW", L"JWX", L"JWY", L"JWZ", L"JXA", L"JXB", L"JXC", L"JXD", L"JXE", L"JXF", L"JXG", L"JXH", L"JXI", L"JXJ", L"JXK", L"JXL", L"JXM", L"JXN", L"JXO", L"JXP", L"JXQ", L"JXR", L"JXS", L"JXT", L"JXU", L"JXV", L"JXW", L"JXX", L"JXY", L"JXZ", L"JYA", L"JYB", L"JYC", L"JYD", L"JYE", L"JYF", L"JYG", L"JYH", L"JYI", L"JYJ", L"JYK", L"JYL", L"JYM", L"JYN", L"JYO", L"JYP", L"JYQ", L"JYR", L"JYS", L"JYT", L"JYU", L"JYV", L"JYW", L"JYX", L"JYY", L"JYZ", L"JZA", L"JZB", L"JZC", L"JZD", L"JZE", L"JZF", L"JZG", L"JZH", L"JZI", L"JZJ", L"JZK", L"JZL", L"JZM", L"JZN", L"JZO", L"JZP", L"JZQ", L"JZR", L"JZS", L"JZT", L"JZU", L"JZV", L"JZW", L"JZX", L"JZY", L"JZZ", L"KAA", L"KAB", L"KAC", L"KAD", L"KAE", L"KAF", L"KAG", L"KAH", L"KAI", L"KAJ", L"KAK", L"KAL", L"KAM", L"KAN", L"KAO", L"KAP", L"KAQ", L"KAR", L"KAS", L"KAT", L"KAU", L"KAV", L"KAW", L"KAX", L"KAY", L"KAZ", L"KBA", L"KBB", L"KBC", L"KBD", L"KBE", L"KBF", L"KBG", L"KBH", L"KBI", L"KBJ", L"KBK", L"KBL", L"KBM", L"KBN", L"KBO", L"KBP", L"KBQ", L"KBR", L"KBS", L"KBT", L"KBU", L"KBV", L"KBW", L"KBX", L"KBY", L"KBZ", L"KCA", L"KCB", L"KCC", L"KCD", L"KCE", L"KCF", L"KCG", L"KCH", L"KCI", L"KCJ", L"KCK", L"KCL", L"KCM", L"KCN", L"KCO", L"KCP", L"KCQ", L"KCR", L"KCS", L"KCT", L"KCU", L"KCV", L"KCW", L"KCX", L"KCY", L"KCZ", L"KDA", L"KDB", L"KDC", L"KDD", L"KDE", L"KDF", L"KDG", L"KDH", L"KDI", L"KDJ", L"KDK", L"KDL", L"KDM", L"KDN", L"KDO", L"KDP", L"KDQ", L"KDR", L"KDS", L"KDT", L"KDU", L"KDV", L"KDW", L"KDX", L"KDY", L"KDZ", L"KEA", L"KEB", L"KEC", L"KED", L"KEE", L"KEF", L"KEG", L"KEH", L"KEI", L"KEJ", L"KEK", L"KEL", L"KEM", L"KEN", L"KEO", L"KEP", L"KEQ", L"KER", L"KES", L"KET", L"KEU", L"KEV", L"KEW", L"KEX", L"KEY", L"KEZ", L"KFA", L"KFB", L"KFC", L"KFD", L"KFE", L"KFF", L"KFG", L"KFH", L"KFI", L"KFJ", L"KFK", L"KFL", L"KFM", L"KFN", L"KFO", L"KFP", L"KFQ", L"KFR", L"KFS", L"KFT", L"KFU", L"KFV", L"KFW", L"KFX", L"KFY", L"KFZ", L"KGA", L"KGB", L"KGC", L"KGD", L"KGE", L"KGF", L"KGG", L"KGH", L"KGI", L"KGJ", L"KGK", L"KGL", L"KGM", L"KGN", L"KGO", L"KGP", L"KGQ", L"KGR", L"KGS", L"KGT", L"KGU", L"KGV", L"KGW", L"KGX", L"KGY", L"KGZ", L"KHA", L"KHB", L"KHC", L"KHD", L"KHE", L"KHF", L"KHG", L"KHH", L"KHI", L"KHJ", L"KHK", L"KHL", L"KHM", L"KHN", L"KHO", L"KHP", L"KHQ", L"KHR", L"KHS", L"KHT", L"KHU", L"KHV", L"KHW", L"KHX", L"KHY", L"KHZ", L"KIA", L"KIB", L"KIC", L"KID", L"KIE", L"KIF", L"KIG", L"KIH", L"KII", L"KIJ", L"KIK", L"KIL", L"KIM", L"KIN", L"KIO", L"KIP", L"KIQ", L"KIR", L"KIS", L"KIT", L"KIU", L"KIV", L"KIW", L"KIX", L"KIY", L"KIZ", L"KJA", L"KJB", L"KJC", L"KJD", L"KJE", L"KJF", L"KJG", L"KJH", L"KJI", L"KJJ", L"KJK", - L"KJL", L"KJM", L"KJN", L"KJO", L"KJP", L"KJQ", L"KJR", L"KJS", L"KJT", L"KJU", L"KJV", L"KJW", L"KJX", L"KJY", L"KJZ", L"KKA", L"KKB", L"KKC", L"KKD", L"KKE", L"KKF", L"KKG", L"KKH", L"KKI", L"KKJ", L"KKK", L"KKL", L"KKM", L"KKN", L"KKO", L"KKP", L"KKQ", L"KKR", L"KKS", L"KKT", L"KKU", L"KKV", L"KKW", L"KKX", L"KKY", L"KKZ", L"KLA", L"KLB", L"KLC", L"KLD", L"KLE", L"KLF", L"KLG", L"KLH", L"KLI", L"KLJ", L"KLK", L"KLL", L"KLM", L"KLN", L"KLO", L"KLP", L"KLQ", L"KLR", L"KLS", L"KLT", L"KLU", L"KLV", L"KLW", L"KLX", L"KLY", L"KLZ", L"KMA", L"KMB", L"KMC", L"KMD", L"KME", L"KMF", L"KMG", L"KMH", L"KMI", L"KMJ", L"KMK", L"KML", L"KMM", L"KMN", L"KMO", L"KMP", L"KMQ", L"KMR", L"KMS", L"KMT", L"KMU", L"KMV", L"KMW", L"KMX", L"KMY", L"KMZ", L"KNA", L"KNB", L"KNC", L"KND", L"KNE", L"KNF", L"KNG", L"KNH", L"KNI", L"KNJ", L"KNK", L"KNL", L"KNM", L"KNN", L"KNO", L"KNP", L"KNQ", L"KNR", L"KNS", L"KNT", L"KNU", L"KNV", L"KNW", L"KNX", L"KNY", L"KNZ", L"KOA", L"KOB", L"KOC", L"KOD", L"KOE", L"KOF", L"KOG", L"KOH", L"KOI", L"KOJ", L"KOK", L"KOL", L"KOM", L"KON", L"KOO", L"KOP", L"KOQ", L"KOR", L"KOS", L"KOT", L"KOU", L"KOV", L"KOW", L"KOX", L"KOY", L"KOZ", L"KPA", L"KPB", L"KPC", L"KPD", L"KPE", L"KPF", L"KPG", L"KPH", L"KPI", L"KPJ", L"KPK", L"KPL", L"KPM", L"KPN", L"KPO", L"KPP", L"KPQ", L"KPR", L"KPS", L"KPT", L"KPU", L"KPV", L"KPW", L"KPX", L"KPY", L"KPZ", L"KQA", L"KQB", L"KQC", L"KQD", L"KQE", L"KQF", L"KQG", L"KQH", L"KQI", L"KQJ", L"KQK", L"KQL", L"KQM", L"KQN", L"KQO", L"KQP", L"KQQ", L"KQR", L"KQS", L"KQT", L"KQU", L"KQV", L"KQW", L"KQX", L"KQY", L"KQZ", L"KRA", L"KRB", L"KRC", L"KRD", L"KRE", L"KRF", L"KRG", L"KRH", L"KRI", L"KRJ", L"KRK", L"KRL", L"KRM", L"KRN", L"KRO", L"KRP", L"KRQ", L"KRR", L"KRS", L"KRT", L"KRU", L"KRV", L"KRW", L"KRX", L"KRY", L"KRZ", L"KSA", L"KSB", L"KSC", L"KSD", L"KSE", L"KSF", L"KSG", L"KSH", L"KSI", L"KSJ", L"KSK", L"KSL", L"KSM", L"KSN", L"KSO", L"KSP", L"KSQ", L"KSR", L"KSS", L"KST", L"KSU", L"KSV", L"KSW", L"KSX", L"KSY", L"KSZ", L"KTA", L"KTB", L"KTC", L"KTD", L"KTE", L"KTF", L"KTG", L"KTH", L"KTI", L"KTJ", L"KTK", L"KTL", L"KTM", L"KTN", L"KTO", L"KTP", L"KTQ", L"KTR", L"KTS", L"KTT", L"KTU", L"KTV", L"KTW", L"KTX", - L"KTY", L"KTZ", L"KUA", L"KUB", L"KUC", L"KUD", L"KUE", L"KUF", L"KUG", L"KUH", L"KUI", L"KUJ", L"KUK", L"KUL", L"KUM", L"KUN", L"KUO", L"KUP", L"KUQ", L"KUR", L"KUS", L"KUT", L"KUU", L"KUV", L"KUW", L"KUX", L"KUY", L"KUZ", L"KVA", L"KVB", L"KVC", L"KVD", L"KVE", L"KVF", L"KVG", L"KVH", L"KVI", L"KVJ", L"KVK", L"KVL", L"KVM", L"KVN", L"KVO", L"KVP", L"KVQ", L"KVR", L"KVS", L"KVT", L"KVU", L"KVV", L"KVW", L"KVX", L"KVY", L"KVZ", L"KWA", L"KWB", L"KWC", L"KWD", L"KWE", L"KWF", L"KWG", L"KWH", L"KWI", L"KWJ", L"KWK", L"KWL", L"KWM", L"KWN", L"KWO", L"KWP", L"KWQ", L"KWR", L"KWS", L"KWT", L"KWU", L"KWV", L"KWW", L"KWX", L"KWY", L"KWZ", L"KXA", L"KXB", L"KXC", L"KXD", L"KXE", L"KXF", L"KXG", L"KXH", L"KXI", L"KXJ", L"KXK", L"KXL", L"KXM", L"KXN", L"KXO", L"KXP", L"KXQ", L"KXR", L"KXS", L"KXT", L"KXU", L"KXV", L"KXW", L"KXX", L"KXY", L"KXZ", L"KYA", L"KYB", L"KYC", L"KYD", L"KYE", L"KYF", L"KYG", L"KYH", L"KYI", L"KYJ", L"KYK", L"KYL", L"KYM", L"KYN", L"KYO", L"KYP", L"KYQ", L"KYR", L"KYS", L"KYT", L"KYU", L"KYV", L"KYW", L"KYX", L"KYY", L"KYZ", L"KZA", L"KZB", L"KZC", L"KZD", L"KZE", L"KZF", L"KZG", L"KZH", L"KZI", L"KZJ", L"KZK", L"KZL", L"KZM", L"KZN", L"KZO", L"KZP", L"KZQ", L"KZR", L"KZS", L"KZT", L"KZU", L"KZV", L"KZW", L"KZX", L"KZY", L"KZZ", L"LAA", L"LAB", L"LAC", L"LAD", L"LAE", L"LAF", L"LAG", L"LAH", L"LAI", L"LAJ", L"LAK", L"LAL", L"LAM", L"LAN", L"LAO", L"LAP", L"LAQ", L"LAR", L"LAS", L"LAT", L"LAU", L"LAV", L"LAW", L"LAX", L"LAY", L"LAZ", L"LBA", L"LBB", L"LBC", L"LBD", L"LBE", L"LBF", L"LBG", L"LBH", L"LBI", L"LBJ", L"LBK", L"LBL", L"LBM", L"LBN", L"LBO", L"LBP", L"LBQ", L"LBR", L"LBS", L"LBT", L"LBU", L"LBV", L"LBW", L"LBX", L"LBY", L"LBZ", L"LCA", L"LCB", L"LCC", L"LCD", L"LCE", L"LCF", L"LCG", L"LCH", L"LCI", L"LCJ", L"LCK", L"LCL", L"LCM", L"LCN", L"LCO", L"LCP", L"LCQ", L"LCR", L"LCS", L"LCT", L"LCU", L"LCV", L"LCW", L"LCX", L"LCY", L"LCZ", L"LDA", L"LDB", L"LDC", L"LDD", L"LDE", L"LDF", L"LDG", L"LDH", L"LDI", L"LDJ", L"LDK", L"LDL", L"LDM", L"LDN", L"LDO", L"LDP", L"LDQ", L"LDR", L"LDS", L"LDT", L"LDU", L"LDV", L"LDW", L"LDX", L"LDY", L"LDZ", L"LEA", L"LEB", L"LEC", L"LED", L"LEE", L"LEF", L"LEG", L"LEH", L"LEI", L"LEJ", L"LEK", - L"LEL", L"LEM", L"LEN", L"LEO", L"LEP", L"LEQ", L"LER", L"LES", L"LET", L"LEU", L"LEV", L"LEW", L"LEX", L"LEY", L"LEZ", L"LFA", L"LFB", L"LFC", L"LFD", L"LFE", L"LFF", L"LFG", L"LFH", L"LFI", L"LFJ", L"LFK", L"LFL", L"LFM", L"LFN", L"LFO", L"LFP", L"LFQ", L"LFR", L"LFS", L"LFT", L"LFU", L"LFV", L"LFW", L"LFX", L"LFY", L"LFZ", L"LGA", L"LGB", L"LGC", L"LGD", L"LGE", L"LGF", L"LGG", L"LGH", L"LGI", L"LGJ", L"LGK", L"LGL", L"LGM", L"LGN", L"LGO", L"LGP", L"LGQ", L"LGR", L"LGS", L"LGT", L"LGU", L"LGV", L"LGW", L"LGX", L"LGY", L"LGZ", L"LHA", L"LHB", L"LHC", L"LHD", L"LHE", L"LHF", L"LHG", L"LHH", L"LHI", L"LHJ", L"LHK", L"LHL", L"LHM", L"LHN", L"LHO", L"LHP", L"LHQ", L"LHR", L"LHS", L"LHT", L"LHU", L"LHV", L"LHW", L"LHX", L"LHY", L"LHZ", L"LIA", L"LIB", L"LIC", L"LID", L"LIE", L"LIF", L"LIG", L"LIH", L"LII", L"LIJ", L"LIK", L"LIL", L"LIM", L"LIN", L"LIO", L"LIP", L"LIQ", L"LIR", L"LIS", L"LIT", L"LIU", L"LIV", L"LIW", L"LIX", L"LIY", L"LIZ", L"LJA", L"LJB", L"LJC", L"LJD", L"LJE", L"LJF", L"LJG", L"LJH", L"LJI", L"LJJ", L"LJK", L"LJL", L"LJM", L"LJN", L"LJO", L"LJP", L"LJQ", L"LJR", L"LJS", L"LJT", L"LJU", L"LJV", L"LJW", L"LJX", L"LJY", L"LJZ", L"LKA", L"LKB", L"LKC", L"LKD", L"LKE", L"LKF", L"LKG", L"LKH", L"LKI", L"LKJ", L"LKK", L"LKL", L"LKM", L"LKN", L"LKO", L"LKP", L"LKQ", L"LKR", L"LKS", L"LKT", L"LKU", L"LKV", L"LKW", L"LKX", L"LKY", L"LKZ", L"LLA", L"LLB", L"LLC", L"LLD", L"LLE", L"LLF", L"LLG", L"LLH", L"LLI", L"LLJ", L"LLK", L"LLL", L"LLM", L"LLN", L"LLO", L"LLP", L"LLQ", L"LLR", L"LLS", L"LLT", L"LLU", L"LLV", L"LLW", L"LLX", L"LLY", L"LLZ", L"LMA", L"LMB", L"LMC", L"LMD", L"LME", L"LMF", L"LMG", L"LMH", L"LMI", L"LMJ", L"LMK", L"LML", L"LMM", L"LMN", L"LMO", L"LMP", L"LMQ", L"LMR", L"LMS", L"LMT", L"LMU", L"LMV", L"LMW", L"LMX", L"LMY", L"LMZ", L"LNA", L"LNB", L"LNC", L"LND", L"LNE", L"LNF", L"LNG", L"LNH", L"LNI", L"LNJ", L"LNK", L"LNL", L"LNM", L"LNN", L"LNO", L"LNP", L"LNQ", L"LNR", L"LNS", L"LNT", L"LNU", L"LNV", L"LNW", L"LNX", L"LNY", L"LNZ", L"LOA", L"LOB", L"LOC", L"LOD", L"LOE", L"LOF", L"LOG", L"LOH", L"LOI", L"LOJ", L"LOK", L"LOL", L"LOM", L"LON", L"LOO", L"LOP", L"LOQ", L"LOR", L"LOS", L"LOT", L"LOU", L"LOV", L"LOW", L"LOX", + L"KJL", L"KJM", L"KJN", L"KJO", L"KJP", L"KJQ", L"KJR", L"KJS", L"KJT", L"KJU", L"KJV", L"KJW", L"KJX", L"KJY", L"KJZ", L"KKA", L"KKB", L"KKC", L"KKD", L"KKE", L"KKF", L"KKG", L"KKH", L"KKI", L"KKJ", L"KKK", L"KKL", L"KKM", L"KKN", L"KKO", L"KKP", L"KKQ", L"KKR", L"KKS", L"KKT", L"KKU", L"KKV", L"KKW", L"KKX", L"KKY", L"KKZ", L"KLA", L"KLB", L"KLC", L"KLD", L"KLE", L"KLF", L"KLG", L"KLH", L"KLI", L"KLJ", L"KLK", L"KLL", L"KLM", L"KLN", L"KLO", L"KLP", L"KLQ", L"KLR", L"KLS", L"KLT", L"KLU", L"KLV", L"KLW", L"KLX", L"KLY", L"KLZ", L"KMA", L"KMB", L"KMC", L"KMD", L"KME", L"KMF", L"KMG", L"KMH", L"KMI", L"KMJ", L"KMK", L"KML", L"KMM", L"KMN", L"KMO", L"KMP", L"KMQ", L"KMR", L"KMS", L"KMT", L"KMU", L"KMV", L"KMW", L"KMX", L"KMY", L"KMZ", L"KNA", L"KNB", L"KNC", L"KND", L"KNE", L"KNF", L"KNG", L"KNH", L"KNI", L"KNJ", L"KNK", L"KNL", L"KNM", L"KNN", L"KNO", L"KNP", L"KNQ", L"KNR", L"KNS", L"KNT", L"KNU", L"KNV", L"KNW", L"KNX", L"KNY", L"KNZ", L"KOA", L"KOB", L"KOC", L"KOD", L"KOE", L"KOF", L"KOG", L"KOH", L"KOI", L"KOJ", L"KOK", L"KOL", L"KOM", L"KON", L"KOO", L"KOP", L"KOQ", L"KOR", L"KOS", L"KOT", L"KOU", L"KOV", L"KOW", L"KOX", L"KOY", L"KOZ", L"KPA", L"KPB", L"KPC", L"KPD", L"KPE", L"KPF", L"KPG", L"KPH", L"KPI", L"KPJ", L"KPK", L"KPL", L"KPM", L"KPN", L"KPO", L"KPP", L"KPQ", L"KPR", L"KPS", L"KPT", L"KPU", L"KPV", L"KPW", L"KPX", L"KPY", L"KPZ", L"KQA", L"KQB", L"KQC", L"KQD", L"KQE", L"KQF", L"KQG", L"KQH", L"KQI", L"KQJ", L"KQK", L"KQL", L"KQM", L"KQN", L"KQO", L"KQP", L"KQQ", L"KQR", L"KQS", L"KQT", L"KQU", L"KQV", L"KQW", L"KQX", L"KQY", L"KQZ", L"KRA", L"KRB", L"KRC", L"KRD", L"KRE", L"KRF", L"KRG", L"KRH", L"KRI", L"KRJ", L"KRK", L"KRL", L"KRM", L"KRN", L"KRO", L"KRP", L"KRQ", L"KRR", L"KRS", L"KRT", L"KRU", L"KRV", L"KRW", L"KRX", L"KRY", L"KRZ", L"KSA", L"KSB", L"KSC", L"KSD", L"KSE", L"KSF", L"KSG", L"KSH", L"KSI", L"KSJ", L"KSK", L"KSL", L"KSM", L"KSN", L"KSO", L"KSP", L"KSQ", L"KSR", L"KSS", L"KST", L"KSU", L"KSV", L"KSW", L"KSX", L"KSY", L"KSZ", L"KTA", L"KTB", L"KTC", L"KTD", L"KTE", L"KTF", L"KTG", L"KTH", L"KTI", L"KTJ", L"KTK", L"KTL", L"KTM", L"KTN", L"KTO", L"KTP", L"KTQ", L"KTR", L"KTS", L"KTT", L"KTU", L"KTV", L"KTW", L"KTX", + L"KTY", L"KTZ", L"KUA", L"KUB", L"KUC", L"KUD", L"KUE", L"KUF", L"KUG", L"KUH", L"KUI", L"KUJ", L"KUK", L"KUL", L"KUM", L"KUN", L"KUO", L"KUP", L"KUQ", L"KUR", L"KUS", L"KUT", L"KUU", L"KUV", L"KUW", L"KUX", L"KUY", L"KUZ", L"KVA", L"KVB", L"KVC", L"KVD", L"KVE", L"KVF", L"KVG", L"KVH", L"KVI", L"KVJ", L"KVK", L"KVL", L"KVM", L"KVN", L"KVO", L"KVP", L"KVQ", L"KVR", L"KVS", L"KVT", L"KVU", L"KVV", L"KVW", L"KVX", L"KVY", L"KVZ", L"KWA", L"KWB", L"KWC", L"KWD", L"KWE", L"KWF", L"KWG", L"KWH", L"KWI", L"KWJ", L"KWK", L"KWL", L"KWM", L"KWN", L"KWO", L"KWP", L"KWQ", L"KWR", L"KWS", L"KWT", L"KWU", L"KWV", L"KWW", L"KWX", L"KWY", L"KWZ", L"KXA", L"KXB", L"KXC", L"KXD", L"KXE", L"KXF", L"KXG", L"KXH", L"KXI", L"KXJ", L"KXK", L"KXL", L"KXM", L"KXN", L"KXO", L"KXP", L"KXQ", L"KXR", L"KXS", L"KXT", L"KXU", L"KXV", L"KXW", L"KXX", L"KXY", L"KXZ", L"KYA", L"KYB", L"KYC", L"KYD", L"KYE", L"KYF", L"KYG", L"KYH", L"KYI", L"KYJ", L"KYK", L"KYL", L"KYM", L"KYN", L"KYO", L"KYP", L"KYQ", L"KYR", L"KYS", L"KYT", L"KYU", L"KYV", L"KYW", L"KYX", L"KYY", L"KYZ", L"KZA", L"KZB", L"KZC", L"KZD", L"KZE", L"KZF", L"KZG", L"KZH", L"KZI", L"KZJ", L"KZK", L"KZL", L"KZM", L"KZN", L"KZO", L"KZP", L"KZQ", L"KZR", L"KZS", L"KZT", L"KZU", L"KZV", L"KZW", L"KZX", L"KZY", L"KZZ", L"LAA", L"LAB", L"LAC", L"LAD", L"LAE", L"LAF", L"LAG", L"LAH", L"LAI", L"LAJ", L"LAK", L"LAL", L"LAM", L"LAN", L"LAO", L"LAP", L"LAQ", L"LAR", L"LAS", L"LAT", L"LAU", L"LAV", L"LAW", L"LAX", L"LAY", L"LAZ", L"LBA", L"LBB", L"LBC", L"LBD", L"LBE", L"LBF", L"LBG", L"LBH", L"LBI", L"LBJ", L"LBK", L"LBL", L"LBM", L"LBN", L"LBO", L"LBP", L"LBQ", L"LBR", L"LBS", L"LBT", L"LBU", L"LBV", L"LBW", L"LBX", L"LBY", L"LBZ", L"LCA", L"LCB", L"LCC", L"LCD", L"LCE", L"LCF", L"LCG", L"LCH", L"LCI", L"LCJ", L"LCK", L"LCL", L"LCM", L"LCN", L"LCO", L"LCP", L"LCQ", L"LCR", L"LCS", L"LCT", L"LCU", L"LCV", L"LCW", L"LCX", L"LCY", L"LCZ", L"LDA", L"LDB", L"LDC", L"LDD", L"LDE", L"LDF", L"LDG", L"LDH", L"LDI", L"LDJ", L"LDK", L"LDL", L"LDM", L"LDN", L"LDO", L"LDP", L"LDQ", L"LDR", L"LDS", L"LDT", L"LDU", L"LDV", L"LDW", L"LDX", L"LDY", L"LDZ", L"LEA", L"LEB", L"LEC", L"LED", L"LEE", L"LEF", L"LEG", L"LEH", L"LEI", L"LEJ", L"LEK", + L"LEL", L"LEM", L"LEN", L"LEO", L"LEP", L"LEQ", L"LER", L"LES", L"LET", L"LEU", L"LEV", L"LEW", L"LEX", L"LEY", L"LEZ", L"LFA", L"LFB", L"LFC", L"LFD", L"LFE", L"LFF", L"LFG", L"LFH", L"LFI", L"LFJ", L"LFK", L"LFL", L"LFM", L"LFN", L"LFO", L"LFP", L"LFQ", L"LFR", L"LFS", L"LFT", L"LFU", L"LFV", L"LFW", L"LFX", L"LFY", L"LFZ", L"LGA", L"LGB", L"LGC", L"LGD", L"LGE", L"LGF", L"LGG", L"LGH", L"LGI", L"LGJ", L"LGK", L"LGL", L"LGM", L"LGN", L"LGO", L"LGP", L"LGQ", L"LGR", L"LGS", L"LGT", L"LGU", L"LGV", L"LGW", L"LGX", L"LGY", L"LGZ", L"LHA", L"LHB", L"LHC", L"LHD", L"LHE", L"LHF", L"LHG", L"LHH", L"LHI", L"LHJ", L"LHK", L"LHL", L"LHM", L"LHN", L"LHO", L"LHP", L"LHQ", L"LHR", L"LHS", L"LHT", L"LHU", L"LHV", L"LHW", L"LHX", L"LHY", L"LHZ", L"LIA", L"LIB", L"LIC", L"LID", L"LIE", L"LIF", L"LIG", L"LIH", L"LII", L"LIJ", L"LIK", L"LIL", L"LIM", L"LIN", L"LIO", L"LIP", L"LIQ", L"LIR", L"LIS", L"LIT", L"LIU", L"LIV", L"LIW", L"LIX", L"LIY", L"LIZ", L"LJA", L"LJB", L"LJC", L"LJD", L"LJE", L"LJF", L"LJG", L"LJH", L"LJI", L"LJJ", L"LJK", L"LJL", L"LJM", L"LJN", L"LJO", L"LJP", L"LJQ", L"LJR", L"LJS", L"LJT", L"LJU", L"LJV", L"LJW", L"LJX", L"LJY", L"LJZ", L"LKA", L"LKB", L"LKC", L"LKD", L"LKE", L"LKF", L"LKG", L"LKH", L"LKI", L"LKJ", L"LKK", L"LKL", L"LKM", L"LKN", L"LKO", L"LKP", L"LKQ", L"LKR", L"LKS", L"LKT", L"LKU", L"LKV", L"LKW", L"LKX", L"LKY", L"LKZ", L"LLA", L"LLB", L"LLC", L"LLD", L"LLE", L"LLF", L"LLG", L"LLH", L"LLI", L"LLJ", L"LLK", L"LLL", L"LLM", L"LLN", L"LLO", L"LLP", L"LLQ", L"LLR", L"LLS", L"LLT", L"LLU", L"LLV", L"LLW", L"LLX", L"LLY", L"LLZ", L"LMA", L"LMB", L"LMC", L"LMD", L"LME", L"LMF", L"LMG", L"LMH", L"LMI", L"LMJ", L"LMK", L"LML", L"LMM", L"LMN", L"LMO", L"LMP", L"LMQ", L"LMR", L"LMS", L"LMT", L"LMU", L"LMV", L"LMW", L"LMX", L"LMY", L"LMZ", L"LNA", L"LNB", L"LNC", L"LND", L"LNE", L"LNF", L"LNG", L"LNH", L"LNI", L"LNJ", L"LNK", L"LNL", L"LNM", L"LNN", L"LNO", L"LNP", L"LNQ", L"LNR", L"LNS", L"LNT", L"LNU", L"LNV", L"LNW", L"LNX", L"LNY", L"LNZ", L"LOA", L"LOB", L"LOC", L"LOD", L"LOE", L"LOF", L"LOG", L"LOH", L"LOI", L"LOJ", L"LOK", L"LOL", L"LOM", L"LON", L"LOO", L"LOP", L"LOQ", L"LOR", L"LOS", L"LOT", L"LOU", L"LOV", L"LOW", L"LOX", L"LOY", L"LOZ", L"LPA", L"LPB", L"LPC", L"LPD", L"LPE", L"LPF", L"LPG", L"LPH", L"LPI", L"LPJ", L"LPK", L"LPL", L"LPM", L"LPN", L"LPO", L"LPP", L"LPQ", L"LPR", L"LPS", L"LPT", L"LPU", L"LPV", L"LPW", L"LPX", L"LPY", L"LPZ", L"LQA", L"LQB", L"LQC", L"LQD", L"LQE", L"LQF", L"LQG", L"LQH", L"LQI", L"LQJ", L"LQK", L"LQL", L"LQM", L"LQN", L"LQO", L"LQP", L"LQQ", L"LQR", L"LQS", L"LQT", L"LQU", L"LQV", L"LQW", L"LQX", L"LQY", L"LQZ", L"LRA", L"LRB", L"LRC", L"LRD", L"LRE", L"LRF", L"LRG", L"LRH", L"LRI", L"LRJ", L"LRK", L"LRL", L"LRM", L"LRN", L"LRO", L"LRP", L"LRQ", L"LRR", L"LRS", L"LRT", L"LRU", L"LRV", L"LRW", L"LRX", L"LRY", L"LRZ", L"LSA", L"LSB", L"LSC", L"LSD", L"LSE", L"LSF", L"LSG", L"LSH", L"LSI", L"LSJ", L"LSK", L"LSL", L"LSM", L"LSN", L"LSO", L"LSP", L"LSQ", L"LSR", L"LSS", L"LST", L"LSU", L"LSV", L"LSW", L"LSX", L"LSY", L"LSZ", L"LTA", L"LTB", L"LTC", L"LTD", L"LTE", L"LTF", L"LTG", L"LTH", L"LTI", L"LTJ", L"LTK", L"LTL", L"LTM", L"LTN", L"LTO", L"LTP", L"LTQ", L"LTR", L"LTS", L"LTT", L"LTU", L"LTV", L"LTW", L"LTX", L"LTY", L"LTZ", L"LUA", L"LUB", L"LUC", L"LUD", L"LUE", L"LUF", L"LUG", L"LUH", L"LUI", L"LUJ", L"LUK", L"LUL", L"LUM", L"LUN", L"LUO", L"LUP", L"LUQ", L"LUR", L"LUS", L"LUT", L"LUU", L"LUV", L"LUW", L"LUX", L"LUY", L"LUZ", L"LVA", L"LVB", L"LVC", L"LVD", L"LVE", L"LVF", L"LVG", L"LVH", L"LVI", L"LVJ", L"LVK", L"LVL", L"LVM", L"LVN", L"LVO", L"LVP", L"LVQ", L"LVR", L"LVS", L"LVT", L"LVU", L"LVV", L"LVW", L"LVX", L"LVY", L"LVZ", L"LWA", L"LWB", L"LWC", L"LWD", L"LWE", L"LWF", L"LWG", L"LWH", L"LWI", L"LWJ", L"LWK", L"LWL", L"LWM", L"LWN", L"LWO", L"LWP", L"LWQ", L"LWR", L"LWS", L"LWT", L"LWU", L"LWV", L"LWW", L"LWX", L"LWY", L"LWZ", L"LXA", L"LXB", L"LXC", L"LXD", L"LXE", L"LXF", L"LXG", L"LXH", L"LXI", L"LXJ", L"LXK", L"LXL", L"LXM", L"LXN", L"LXO", L"LXP", L"LXQ", L"LXR", L"LXS", L"LXT", L"LXU", L"LXV", L"LXW", L"LXX", L"LXY", L"LXZ", L"LYA", L"LYB", L"LYC", L"LYD", L"LYE", L"LYF", L"LYG", L"LYH", L"LYI", L"LYJ", L"LYK", L"LYL", L"LYM", L"LYN", L"LYO", L"LYP", L"LYQ", L"LYR", L"LYS", L"LYT", L"LYU", L"LYV", L"LYW", L"LYX", L"LYY", L"LYZ", L"LZA", L"LZB", L"LZC", L"LZD", L"LZE", L"LZF", L"LZG", L"LZH", L"LZI", L"LZJ", L"LZK", L"LZL", L"LZM", L"LZN", L"LZO", L"LZP", L"LZQ", L"LZR", L"LZS", L"LZT", L"LZU", L"LZV", L"LZW", L"LZX", L"LZY", L"LZZ", L"MAA", L"MAB", L"MAC", L"MAD", L"MAE", L"MAF", L"MAG", L"MAH", L"MAI", L"MAJ", L"MAK", L"MAL", L"MAM", L"MAN", L"MAO", L"MAP", L"MAQ", L"MAR", L"MAS", L"MAT", L"MAU", L"MAV", L"MAW", L"MAX", L"MAY", L"MAZ", L"MBA", L"MBB", L"MBC", L"MBD", L"MBE", L"MBF", L"MBG", L"MBH", L"MBI", L"MBJ", L"MBK", L"MBL", L"MBM", L"MBN", L"MBO", L"MBP", L"MBQ", L"MBR", L"MBS", L"MBT", L"MBU", L"MBV", L"MBW", L"MBX", L"MBY", L"MBZ", L"MCA", L"MCB", L"MCC", L"MCD", L"MCE", L"MCF", L"MCG", L"MCH", L"MCI", L"MCJ", L"MCK", L"MCL", L"MCM", L"MCN", L"MCO", L"MCP", L"MCQ", L"MCR", L"MCS", L"MCT", L"MCU", L"MCV", L"MCW", L"MCX", L"MCY", L"MCZ", L"MDA", L"MDB", L"MDC", L"MDD", L"MDE", L"MDF", L"MDG", L"MDH", L"MDI", L"MDJ", L"MDK", L"MDL", L"MDM", L"MDN", L"MDO", L"MDP", L"MDQ", L"MDR", L"MDS", L"MDT", L"MDU", L"MDV", L"MDW", L"MDX", L"MDY", L"MDZ", L"MEA", L"MEB", L"MEC", L"MED", L"MEE", L"MEF", L"MEG", L"MEH", L"MEI", L"MEJ", L"MEK", L"MEL", L"MEM", L"MEN", L"MEO", L"MEP", L"MEQ", L"MER", L"MES", L"MET", L"MEU", L"MEV", L"MEW", L"MEX", L"MEY", L"MEZ", L"MFA", L"MFB", L"MFC", L"MFD", L"MFE", L"MFF", L"MFG", L"MFH", L"MFI", L"MFJ", L"MFK", L"MFL", L"MFM", L"MFN", L"MFO", L"MFP", L"MFQ", L"MFR", L"MFS", L"MFT", L"MFU", L"MFV", L"MFW", L"MFX", L"MFY", L"MFZ", L"MGA", L"MGB", L"MGC", L"MGD", L"MGE", L"MGF", L"MGG", L"MGH", L"MGI", L"MGJ", L"MGK", L"MGL", L"MGM", L"MGN", L"MGO", L"MGP", L"MGQ", L"MGR", L"MGS", L"MGT", L"MGU", L"MGV", L"MGW", L"MGX", L"MGY", L"MGZ", L"MHA", L"MHB", L"MHC", L"MHD", L"MHE", L"MHF", L"MHG", L"MHH", L"MHI", L"MHJ", L"MHK", L"MHL", L"MHM", L"MHN", L"MHO", L"MHP", L"MHQ", L"MHR", L"MHS", L"MHT", L"MHU", L"MHV", L"MHW", L"MHX", L"MHY", L"MHZ", L"MIA", L"MIB", L"MIC", L"MID", L"MIE", L"MIF", L"MIG", L"MIH", L"MII", L"MIJ", L"MIK", L"MIL", L"MIM", L"MIN", L"MIO", L"MIP", L"MIQ", L"MIR", L"MIS", L"MIT", L"MIU", L"MIV", L"MIW", L"MIX", L"MIY", L"MIZ", L"MJA", L"MJB", L"MJC", L"MJD", L"MJE", L"MJF", L"MJG", L"MJH", L"MJI", L"MJJ", L"MJK", L"MJL", L"MJM", L"MJN", L"MJO", L"MJP", L"MJQ", L"MJR", L"MJS", L"MJT", L"MJU", L"MJV", L"MJW", L"MJX", L"MJY", L"MJZ", L"MKA", L"MKB", L"MKC", L"MKD", L"MKE", L"MKF", L"MKG", L"MKH", L"MKI", L"MKJ", L"MKK", L"MKL", L"MKM", L"MKN", L"MKO", L"MKP", L"MKQ", L"MKR", L"MKS", L"MKT", L"MKU", L"MKV", L"MKW", L"MKX", L"MKY", L"MKZ", L"MLA", L"MLB", L"MLC", L"MLD", L"MLE", L"MLF", L"MLG", L"MLH", L"MLI", L"MLJ", L"MLK", L"MLL", L"MLM", L"MLN", L"MLO", L"MLP", L"MLQ", L"MLR", L"MLS", L"MLT", L"MLU", L"MLV", L"MLW", L"MLX", L"MLY", L"MLZ", L"MMA", L"MMB", L"MMC", L"MMD", L"MME", L"MMF", L"MMG", L"MMH", L"MMI", L"MMJ", L"MMK", L"MML", L"MMM", L"MMN", L"MMO", L"MMP", L"MMQ", L"MMR", L"MMS", L"MMT", L"MMU", L"MMV", L"MMW", L"MMX", L"MMY", L"MMZ", L"MNA", L"MNB", L"MNC", L"MND", L"MNE", L"MNF", L"MNG", L"MNH", L"MNI", L"MNJ", L"MNK", L"MNL", L"MNM", L"MNN", L"MNO", L"MNP", L"MNQ", L"MNR", L"MNS", L"MNT", L"MNU", L"MNV", L"MNW", L"MNX", L"MNY", L"MNZ", L"MOA", L"MOB", L"MOC", L"MOD", L"MOE", L"MOF", L"MOG", L"MOH", L"MOI", L"MOJ", L"MOK", L"MOL", L"MOM", L"MON", L"MOO", L"MOP", L"MOQ", L"MOR", L"MOS", L"MOT", L"MOU", L"MOV", L"MOW", L"MOX", L"MOY", L"MOZ", L"MPA", L"MPB", L"MPC", L"MPD", L"MPE", L"MPF", L"MPG", L"MPH", L"MPI", L"MPJ", L"MPK", L"MPL", L"MPM", L"MPN", L"MPO", L"MPP", L"MPQ", L"MPR", L"MPS", L"MPT", L"MPU", L"MPV", L"MPW", L"MPX", L"MPY", L"MPZ", L"MQA", L"MQB", L"MQC", L"MQD", L"MQE", L"MQF", L"MQG", L"MQH", L"MQI", L"MQJ", L"MQK", L"MQL", L"MQM", L"MQN", L"MQO", L"MQP", L"MQQ", L"MQR", L"MQS", L"MQT", L"MQU", L"MQV", L"MQW", L"MQX", L"MQY", L"MQZ", L"MRA", L"MRB", L"MRC", L"MRD", L"MRE", L"MRF", L"MRG", L"MRH", L"MRI", L"MRJ", L"MRK", L"MRL", L"MRM", L"MRN", L"MRO", L"MRP", L"MRQ", L"MRR", L"MRS", L"MRT", L"MRU", L"MRV", L"MRW", L"MRX", L"MRY", L"MRZ", L"MSA", L"MSB", L"MSC", L"MSD", L"MSE", L"MSF", L"MSG", L"MSH", L"MSI", L"MSJ", L"MSK", L"MSL", L"MSM", L"MSN", L"MSO", L"MSP", L"MSQ", L"MSR", L"MSS", L"MST", L"MSU", L"MSV", L"MSW", L"MSX", L"MSY", L"MSZ", L"MTA", L"MTB", L"MTC", L"MTD", L"MTE", L"MTF", L"MTG", L"MTH", L"MTI", L"MTJ", L"MTK", L"MTL", L"MTM", L"MTN", L"MTO", L"MTP", L"MTQ", L"MTR", L"MTS", L"MTT", L"MTU", L"MTV", L"MTW", L"MTX", L"MTY", L"MTZ", L"MUA", L"MUB", L"MUC", - L"MUD", L"MUE", L"MUF", L"MUG", L"MUH", L"MUI", L"MUJ", L"MUK", L"MUL", L"MUM", L"MUN", L"MUO", L"MUP", L"MUQ", L"MUR", L"MUS", L"MUT", L"MUU", L"MUV", L"MUW", L"MUX", L"MUY", L"MUZ", L"MVA", L"MVB", L"MVC", L"MVD", L"MVE", L"MVF", L"MVG", L"MVH", L"MVI", L"MVJ", L"MVK", L"MVL", L"MVM", L"MVN", L"MVO", L"MVP", L"MVQ", L"MVR", L"MVS", L"MVT", L"MVU", L"MVV", L"MVW", L"MVX", L"MVY", L"MVZ", L"MWA", L"MWB", L"MWC", L"MWD", L"MWE", L"MWF", L"MWG", L"MWH", L"MWI", L"MWJ", L"MWK", L"MWL", L"MWM", L"MWN", L"MWO", L"MWP", L"MWQ", L"MWR", L"MWS", L"MWT", L"MWU", L"MWV", L"MWW", L"MWX", L"MWY", L"MWZ", L"MXA", L"MXB", L"MXC", L"MXD", L"MXE", L"MXF", L"MXG", L"MXH", L"MXI", L"MXJ", L"MXK", L"MXL", L"MXM", L"MXN", L"MXO", L"MXP", L"MXQ", L"MXR", L"MXS", L"MXT", L"MXU", L"MXV", L"MXW", L"MXX", L"MXY", L"MXZ", L"MYA", L"MYB", L"MYC", L"MYD", L"MYE", L"MYF", L"MYG", L"MYH", L"MYI", L"MYJ", L"MYK", L"MYL", L"MYM", L"MYN", L"MYO", L"MYP", L"MYQ", L"MYR", L"MYS", L"MYT", L"MYU", L"MYV", L"MYW", L"MYX", L"MYY", L"MYZ", L"MZA", L"MZB", L"MZC", L"MZD", L"MZE", L"MZF", L"MZG", L"MZH", L"MZI", L"MZJ", L"MZK", L"MZL", L"MZM", L"MZN", L"MZO", L"MZP", L"MZQ", L"MZR", L"MZS", L"MZT", L"MZU", L"MZV", L"MZW", L"MZX", L"MZY", L"MZZ", L"NAA", L"NAB", L"NAC", L"NAD", L"NAE", L"NAF", L"NAG", L"NAH", L"NAI", L"NAJ", L"NAK", L"NAL", L"NAM", L"NAN", L"NAO", L"NAP", L"NAQ", L"NAR", L"NAS", L"NAT", L"NAU", L"NAV", L"NAW", L"NAX", L"NAY", L"NAZ", L"NBA", L"NBB", L"NBC", L"NBD", L"NBE", L"NBF", L"NBG", L"NBH", L"NBI", L"NBJ", L"NBK", L"NBL", L"NBM", L"NBN", L"NBO", L"NBP", L"NBQ", L"NBR", L"NBS", L"NBT", L"NBU", L"NBV", L"NBW", L"NBX", L"NBY", L"NBZ", L"NCA", L"NCB", L"NCC", L"NCD", L"NCE", L"NCF", L"NCG", L"NCH", L"NCI", L"NCJ", L"NCK", L"NCL", L"NCM", L"NCN", L"NCO", L"NCP", L"NCQ", L"NCR", L"NCS", L"NCT", L"NCU", L"NCV", L"NCW", L"NCX", L"NCY", L"NCZ", L"NDA", L"NDB", L"NDC", L"NDD", L"NDE", L"NDF", L"NDG", L"NDH", L"NDI", L"NDJ", L"NDK", L"NDL", L"NDM", L"NDN", L"NDO", L"NDP", L"NDQ", L"NDR", L"NDS", L"NDT", L"NDU", L"NDV", L"NDW", L"NDX", L"NDY", L"NDZ", L"NEA", L"NEB", L"NEC", L"NED", L"NEE", L"NEF", L"NEG", L"NEH", L"NEI", L"NEJ", L"NEK", L"NEL", L"NEM", L"NEN", L"NEO", L"NEP", - L"NEQ", L"NER", L"NES", L"NET", L"NEU", L"NEV", L"NEW", L"NEX", L"NEY", L"NEZ", L"NFA", L"NFB", L"NFC", L"NFD", L"NFE", L"NFF", L"NFG", L"NFH", L"NFI", L"NFJ", L"NFK", L"NFL", L"NFM", L"NFN", L"NFO", L"NFP", L"NFQ", L"NFR", L"NFS", L"NFT", L"NFU", L"NFV", L"NFW", L"NFX", L"NFY", L"NFZ", L"NGA", L"NGB", L"NGC", L"NGD", L"NGE", L"NGF", L"NGG", L"NGH", L"NGI", L"NGJ", L"NGK", L"NGL", L"NGM", L"NGN", L"NGO", L"NGP", L"NGQ", L"NGR", L"NGS", L"NGT", L"NGU", L"NGV", L"NGW", L"NGX", L"NGY", L"NGZ", L"NHA", L"NHB", L"NHC", L"NHD", L"NHE", L"NHF", L"NHG", L"NHH", L"NHI", L"NHJ", L"NHK", L"NHL", L"NHM", L"NHN", L"NHO", L"NHP", L"NHQ", L"NHR", L"NHS", L"NHT", L"NHU", L"NHV", L"NHW", L"NHX", L"NHY", L"NHZ", L"NIA", L"NIB", L"NIC", L"NID", L"NIE", L"NIF", L"NIG", L"NIH", L"NII", L"NIJ", L"NIK", L"NIL", L"NIM", L"NIN", L"NIO", L"NIP", L"NIQ", L"NIR", L"NIS", L"NIT", L"NIU", L"NIV", L"NIW", L"NIX", L"NIY", L"NIZ", L"NJA", L"NJB", L"NJC", L"NJD", L"NJE", L"NJF", L"NJG", L"NJH", L"NJI", L"NJJ", L"NJK", L"NJL", L"NJM", L"NJN", L"NJO", L"NJP", L"NJQ", L"NJR", L"NJS", L"NJT", L"NJU", L"NJV", L"NJW", L"NJX", L"NJY", L"NJZ", L"NKA", L"NKB", L"NKC", L"NKD", L"NKE", L"NKF", L"NKG", L"NKH", L"NKI", L"NKJ", L"NKK", L"NKL", L"NKM", L"NKN", L"NKO", L"NKP", L"NKQ", L"NKR", L"NKS", L"NKT", L"NKU", L"NKV", L"NKW", L"NKX", L"NKY", L"NKZ", L"NLA", L"NLB", L"NLC", L"NLD", L"NLE", L"NLF", L"NLG", L"NLH", L"NLI", L"NLJ", L"NLK", L"NLL", L"NLM", L"NLN", L"NLO", L"NLP", L"NLQ", L"NLR", L"NLS", L"NLT", L"NLU", L"NLV", L"NLW", L"NLX", L"NLY", L"NLZ", L"NMA", L"NMB", L"NMC", L"NMD", L"NME", L"NMF", L"NMG", L"NMH", L"NMI", L"NMJ", L"NMK", L"NML", L"NMM", L"NMN", L"NMO", L"NMP", L"NMQ", L"NMR", L"NMS", L"NMT", L"NMU", L"NMV", L"NMW", L"NMX", L"NMY", L"NMZ", L"NNA", L"NNB", L"NNC", L"NND", L"NNE", L"NNF", L"NNG", L"NNH", L"NNI", L"NNJ", L"NNK", L"NNL", L"NNM", L"NNN", L"NNO", L"NNP", L"NNQ", L"NNR", L"NNS", L"NNT", L"NNU", L"NNV", L"NNW", L"NNX", L"NNY", L"NNZ", L"NOA", L"NOB", L"NOC", L"NOD", L"NOE", L"NOF", L"NOG", L"NOH", L"NOI", L"NOJ", L"NOK", L"NOL", L"NOM", L"NON", L"NOO", L"NOP", L"NOQ", L"NOR", L"NOS", L"NOT", L"NOU", L"NOV", L"NOW", L"NOX", L"NOY", L"NOZ", L"NPA", L"NPB", L"NPC", - L"NPD", L"NPE", L"NPF", L"NPG", L"NPH", L"NPI", L"NPJ", L"NPK", L"NPL", L"NPM", L"NPN", L"NPO", L"NPP", L"NPQ", L"NPR", L"NPS", L"NPT", L"NPU", L"NPV", L"NPW", L"NPX", L"NPY", L"NPZ", L"NQA", L"NQB", L"NQC", L"NQD", L"NQE", L"NQF", L"NQG", L"NQH", L"NQI", L"NQJ", L"NQK", L"NQL", L"NQM", L"NQN", L"NQO", L"NQP", L"NQQ", L"NQR", L"NQS", L"NQT", L"NQU", L"NQV", L"NQW", L"NQX", L"NQY", L"NQZ", L"NRA", L"NRB", L"NRC", L"NRD", L"NRE", L"NRF", L"NRG", L"NRH", L"NRI", L"NRJ", L"NRK", L"NRL", L"NRM", L"NRN", L"NRO", L"NRP", L"NRQ", L"NRR", L"NRS", L"NRT", L"NRU", L"NRV", L"NRW", L"NRX", L"NRY", L"NRZ", L"NSA", L"NSB", L"NSC", L"NSD", L"NSE", L"NSF", L"NSG", L"NSH", L"NSI", L"NSJ", L"NSK", L"NSL", L"NSM", L"NSN", L"NSO", L"NSP", L"NSQ", L"NSR", L"NSS", L"NST", L"NSU", L"NSV", L"NSW", L"NSX", L"NSY", L"NSZ", L"NTA", L"NTB", L"NTC", L"NTD", L"NTE", L"NTF", L"NTG", L"NTH", L"NTI", L"NTJ", L"NTK", L"NTL", L"NTM", L"NTN", L"NTO", L"NTP", L"NTQ", L"NTR", L"NTS", L"NTT", L"NTU", L"NTV", L"NTW", L"NTX", L"NTY", L"NTZ", L"NUA", L"NUB", L"NUC", L"NUD", L"NUE", L"NUF", L"NUG", L"NUH", L"NUI", L"NUJ", L"NUK", L"NUL", L"NUM", L"NUN", L"NUO", L"NUP", L"NUQ", L"NUR", L"NUS", L"NUT", L"NUU", L"NUV", L"NUW", L"NUX", L"NUY", L"NUZ", L"NVA", L"NVB", L"NVC", L"NVD", L"NVE", L"NVF", L"NVG", L"NVH", L"NVI", L"NVJ", L"NVK", L"NVL", L"NVM", L"NVN", L"NVO", L"NVP", L"NVQ", L"NVR", L"NVS", L"NVT", L"NVU", L"NVV", L"NVW", L"NVX", L"NVY", L"NVZ", L"NWA", L"NWB", L"NWC", L"NWD", L"NWE", L"NWF", L"NWG", L"NWH", L"NWI", L"NWJ", L"NWK", L"NWL", L"NWM", L"NWN", L"NWO", L"NWP", L"NWQ", L"NWR", L"NWS", L"NWT", L"NWU", L"NWV", L"NWW", L"NWX", L"NWY", L"NWZ", L"NXA", L"NXB", L"NXC", L"NXD", L"NXE", L"NXF", L"NXG", L"NXH", L"NXI", L"NXJ", L"NXK", L"NXL", L"NXM", L"NXN", L"NXO", L"NXP", L"NXQ", L"NXR", L"NXS", L"NXT", L"NXU", L"NXV", L"NXW", L"NXX", L"NXY", L"NXZ", L"NYA", L"NYB", L"NYC", L"NYD", L"NYE", L"NYF", L"NYG", L"NYH", L"NYI", L"NYJ", L"NYK", L"NYL", L"NYM", L"NYN", L"NYO", L"NYP", L"NYQ", L"NYR", L"NYS", L"NYT", L"NYU", L"NYV", L"NYW", L"NYX", L"NYY", L"NYZ", L"NZA", L"NZB", L"NZC", L"NZD", L"NZE", L"NZF", L"NZG", L"NZH", L"NZI", L"NZJ", L"NZK", L"NZL", L"NZM", L"NZN", L"NZO", L"NZP", - L"NZQ", L"NZR", L"NZS", L"NZT", L"NZU", L"NZV", L"NZW", L"NZX", L"NZY", L"NZZ", L"OAA", L"OAB", L"OAC", L"OAD", L"OAE", L"OAF", L"OAG", L"OAH", L"OAI", L"OAJ", L"OAK", L"OAL", L"OAM", L"OAN", L"OAO", L"OAP", L"OAQ", L"OAR", L"OAS", L"OAT", L"OAU", L"OAV", L"OAW", L"OAX", L"OAY", L"OAZ", L"OBA", L"OBB", L"OBC", L"OBD", L"OBE", L"OBF", L"OBG", L"OBH", L"OBI", L"OBJ", L"OBK", L"OBL", L"OBM", L"OBN", L"OBO", L"OBP", L"OBQ", L"OBR", L"OBS", L"OBT", L"OBU", L"OBV", L"OBW", L"OBX", L"OBY", L"OBZ", L"OCA", L"OCB", L"OCC", L"OCD", L"OCE", L"OCF", L"OCG", L"OCH", L"OCI", L"OCJ", L"OCK", L"OCL", L"OCM", L"OCN", L"OCO", L"OCP", L"OCQ", L"OCR", L"OCS", L"OCT", L"OCU", L"OCV", L"OCW", L"OCX", L"OCY", L"OCZ", L"ODA", L"ODB", L"ODC", L"ODD", L"ODE", L"ODF", L"ODG", L"ODH", L"ODI", L"ODJ", L"ODK", L"ODL", L"ODM", L"ODN", L"ODO", L"ODP", L"ODQ", L"ODR", L"ODS", L"ODT", L"ODU", L"ODV", L"ODW", L"ODX", L"ODY", L"ODZ", L"OEA", L"OEB", L"OEC", L"OED", L"OEE", L"OEF", L"OEG", L"OEH", L"OEI", L"OEJ", L"OEK", L"OEL", L"OEM", L"OEN", L"OEO", L"OEP", L"OEQ", L"OER", L"OES", L"OET", L"OEU", L"OEV", L"OEW", L"OEX", L"OEY", L"OEZ", L"OFA", L"OFB", L"OFC", L"OFD", L"OFE", L"OFF", L"OFG", L"OFH", L"OFI", L"OFJ", L"OFK", L"OFL", L"OFM", L"OFN", L"OFO", L"OFP", L"OFQ", L"OFR", L"OFS", L"OFT", L"OFU", L"OFV", L"OFW", L"OFX", L"OFY", L"OFZ", L"OGA", L"OGB", L"OGC", L"OGD", L"OGE", L"OGF", L"OGG", L"OGH", L"OGI", L"OGJ", L"OGK", L"OGL", L"OGM", L"OGN", L"OGO", L"OGP", L"OGQ", L"OGR", L"OGS", L"OGT", L"OGU", L"OGV", L"OGW", L"OGX", L"OGY", L"OGZ", L"OHA", L"OHB", L"OHC", L"OHD", L"OHE", L"OHF", L"OHG", L"OHH", L"OHI", L"OHJ", L"OHK", L"OHL", L"OHM", L"OHN", L"OHO", L"OHP", L"OHQ", L"OHR", L"OHS", L"OHT", L"OHU", L"OHV", L"OHW", L"OHX", L"OHY", L"OHZ", L"OIA", L"OIB", L"OIC", L"OID", L"OIE", L"OIF", L"OIG", L"OIH", L"OII", L"OIJ", L"OIK", L"OIL", L"OIM", L"OIN", L"OIO", L"OIP", L"OIQ", L"OIR", L"OIS", L"OIT", L"OIU", L"OIV", L"OIW", L"OIX", L"OIY", L"OIZ", L"OJA", L"OJB", L"OJC", L"OJD", L"OJE", L"OJF", L"OJG", L"OJH", L"OJI", L"OJJ", L"OJK", L"OJL", L"OJM", L"OJN", L"OJO", L"OJP", L"OJQ", L"OJR", L"OJS", L"OJT", L"OJU", L"OJV", L"OJW", L"OJX", L"OJY", L"OJZ", L"OKA", L"OKB", L"OKC", - L"OKD", L"OKE", L"OKF", L"OKG", L"OKH", L"OKI", L"OKJ", L"OKK", L"OKL", L"OKM", L"OKN", L"OKO", L"OKP", L"OKQ", L"OKR", L"OKS", L"OKT", L"OKU", L"OKV", L"OKW", L"OKX", L"OKY", L"OKZ", L"OLA", L"OLB", L"OLC", L"OLD", L"OLE", L"OLF", L"OLG", L"OLH", L"OLI", L"OLJ", L"OLK", L"OLL", L"OLM", L"OLN", L"OLO", L"OLP", L"OLQ", L"OLR", L"OLS", L"OLT", L"OLU", L"OLV", L"OLW", L"OLX", L"OLY", L"OLZ", L"OMA", L"OMB", L"OMC", L"OMD", L"OME", L"OMF", L"OMG", L"OMH", L"OMI", L"OMJ", L"OMK", L"OML", L"OMM", L"OMN", L"OMO", L"OMP", L"OMQ", L"OMR", L"OMS", L"OMT", L"OMU", L"OMV", L"OMW", L"OMX", L"OMY", L"OMZ", L"ONA", L"ONB", L"ONC", L"OND", L"ONE", L"ONF", L"ONG", L"ONH", L"ONI", L"ONJ", L"ONK", L"ONL", L"ONM", L"ONN", L"ONO", L"ONP", L"ONQ", L"ONR", L"ONS", L"ONT", L"ONU", L"ONV", L"ONW", L"ONX", L"ONY", L"ONZ", L"OOA", L"OOB", L"OOC", L"OOD", L"OOE", L"OOF", L"OOG", L"OOH", L"OOI", L"OOJ", L"OOK", L"OOL", L"OOM", L"OON", L"OOO", L"OOP", L"OOQ", L"OOR", L"OOS", L"OOT", L"OOU", L"OOV", L"OOW", L"OOX", L"OOY", L"OOZ", L"OPA", L"OPB", L"OPC", L"OPD", L"OPE", L"OPF", L"OPG", L"OPH", L"OPI", L"OPJ", L"OPK", L"OPL", L"OPM", L"OPN", L"OPO", L"OPP", L"OPQ", L"OPR", L"OPS", L"OPT", L"OPU", L"OPV", L"OPW", L"OPX", L"OPY", L"OPZ", L"OQA", L"OQB", L"OQC", L"OQD", L"OQE", L"OQF", L"OQG", L"OQH", L"OQI", L"OQJ", L"OQK", L"OQL", L"OQM", L"OQN", L"OQO", L"OQP", L"OQQ", L"OQR", L"OQS", L"OQT", L"OQU", L"OQV", L"OQW", L"OQX", L"OQY", L"OQZ", L"ORA", L"ORB", L"ORC", L"ORD", L"ORE", L"ORF", L"ORG", L"ORH", L"ORI", L"ORJ", L"ORK", L"ORL", L"ORM", L"ORN", L"ORO", L"ORP", L"ORQ", L"ORR", L"ORS", L"ORT", L"ORU", L"ORV", L"ORW", L"ORX", L"ORY", L"ORZ", L"OSA", L"OSB", L"OSC", L"OSD", L"OSE", L"OSF", L"OSG", L"OSH", L"OSI", L"OSJ", L"OSK", L"OSL", L"OSM", L"OSN", L"OSO", L"OSP", L"OSQ", L"OSR", L"OSS", L"OST", L"OSU", L"OSV", L"OSW", L"OSX", L"OSY", L"OSZ", L"OTA", L"OTB", L"OTC", L"OTD", L"OTE", L"OTF", L"OTG", L"OTH", L"OTI", L"OTJ", L"OTK", L"OTL", L"OTM", L"OTN", L"OTO", L"OTP", L"OTQ", L"OTR", L"OTS", L"OTT", L"OTU", L"OTV", L"OTW", L"OTX", L"OTY", L"OTZ", L"OUA", L"OUB", L"OUC", L"OUD", L"OUE", L"OUF", L"OUG", L"OUH", L"OUI", L"OUJ", L"OUK", L"OUL", L"OUM", L"OUN", L"OUO", L"OUP", - L"OUQ", L"OUR", L"OUS", L"OUT", L"OUU", L"OUV", L"OUW", L"OUX", L"OUY", L"OUZ", L"OVA", L"OVB", L"OVC", L"OVD", L"OVE", L"OVF", L"OVG", L"OVH", L"OVI", L"OVJ", L"OVK", L"OVL", L"OVM", L"OVN", L"OVO", L"OVP", L"OVQ", L"OVR", L"OVS", L"OVT", L"OVU", L"OVV", L"OVW", L"OVX", L"OVY", L"OVZ", L"OWA", L"OWB", L"OWC", L"OWD", L"OWE", L"OWF", L"OWG", L"OWH", L"OWI", L"OWJ", L"OWK", L"OWL", L"OWM", L"OWN", L"OWO", L"OWP", L"OWQ", L"OWR", L"OWS", L"OWT", L"OWU", L"OWV", L"OWW", L"OWX", L"OWY", L"OWZ", L"OXA", L"OXB", L"OXC", L"OXD", L"OXE", L"OXF", L"OXG", L"OXH", L"OXI", L"OXJ", L"OXK", L"OXL", L"OXM", L"OXN", L"OXO", L"OXP", L"OXQ", L"OXR", L"OXS", L"OXT", L"OXU", L"OXV", L"OXW", L"OXX", L"OXY", L"OXZ", L"OYA", L"OYB", L"OYC", L"OYD", L"OYE", L"OYF", L"OYG", L"OYH", L"OYI", L"OYJ", L"OYK", L"OYL", L"OYM", L"OYN", L"OYO", L"OYP", L"OYQ", L"OYR", L"OYS", L"OYT", L"OYU", L"OYV", L"OYW", L"OYX", L"OYY", L"OYZ", L"OZA", L"OZB", L"OZC", L"OZD", L"OZE", L"OZF", L"OZG", L"OZH", L"OZI", L"OZJ", L"OZK", L"OZL", L"OZM", L"OZN", L"OZO", L"OZP", L"OZQ", L"OZR", L"OZS", L"OZT", L"OZU", L"OZV", L"OZW", L"OZX", L"OZY", L"OZZ", L"PAA", L"PAB", L"PAC", L"PAD", L"PAE", L"PAF", L"PAG", L"PAH", L"PAI", L"PAJ", L"PAK", L"PAL", L"PAM", L"PAN", L"PAO", L"PAP", L"PAQ", L"PAR", L"PAS", L"PAT", L"PAU", L"PAV", L"PAW", L"PAX", L"PAY", L"PAZ", L"PBA", L"PBB", L"PBC", L"PBD", L"PBE", L"PBF", L"PBG", L"PBH", L"PBI", L"PBJ", L"PBK", L"PBL", L"PBM", L"PBN", L"PBO", L"PBP", L"PBQ", L"PBR", L"PBS", L"PBT", L"PBU", L"PBV", L"PBW", L"PBX", L"PBY", L"PBZ", L"PCA", L"PCB", L"PCC", L"PCD", L"PCE", L"PCF", L"PCG", L"PCH", L"PCI", L"PCJ", L"PCK", L"PCL", L"PCM", L"PCN", L"PCO", L"PCP", L"PCQ", L"PCR", L"PCS", L"PCT", L"PCU", L"PCV", L"PCW", L"PCX", L"PCY", L"PCZ", L"PDA", L"PDB", L"PDC", L"PDD", L"PDE", L"PDF", L"PDG", L"PDH", L"PDI", L"PDJ", L"PDK", L"PDL", L"PDM", L"PDN", L"PDO", L"PDP", L"PDQ", L"PDR", L"PDS", L"PDT", L"PDU", L"PDV", L"PDW", L"PDX", L"PDY", L"PDZ", L"PEA", L"PEB", L"PEC", L"PED", L"PEE", L"PEF", L"PEG", L"PEH", L"PEI", L"PEJ", L"PEK", L"PEL", L"PEM", L"PEN", L"PEO", L"PEP", L"PEQ", L"PER", L"PES", L"PET", L"PEU", L"PEV", L"PEW", L"PEX", L"PEY", L"PEZ", L"PFA", L"PFB", L"PFC", + L"MUD", L"MUE", L"MUF", L"MUG", L"MUH", L"MUI", L"MUJ", L"MUK", L"MUL", L"MUM", L"MUN", L"MUO", L"MUP", L"MUQ", L"MUR", L"MUS", L"MUT", L"MUU", L"MUV", L"MUW", L"MUX", L"MUY", L"MUZ", L"MVA", L"MVB", L"MVC", L"MVD", L"MVE", L"MVF", L"MVG", L"MVH", L"MVI", L"MVJ", L"MVK", L"MVL", L"MVM", L"MVN", L"MVO", L"MVP", L"MVQ", L"MVR", L"MVS", L"MVT", L"MVU", L"MVV", L"MVW", L"MVX", L"MVY", L"MVZ", L"MWA", L"MWB", L"MWC", L"MWD", L"MWE", L"MWF", L"MWG", L"MWH", L"MWI", L"MWJ", L"MWK", L"MWL", L"MWM", L"MWN", L"MWO", L"MWP", L"MWQ", L"MWR", L"MWS", L"MWT", L"MWU", L"MWV", L"MWW", L"MWX", L"MWY", L"MWZ", L"MXA", L"MXB", L"MXC", L"MXD", L"MXE", L"MXF", L"MXG", L"MXH", L"MXI", L"MXJ", L"MXK", L"MXL", L"MXM", L"MXN", L"MXO", L"MXP", L"MXQ", L"MXR", L"MXS", L"MXT", L"MXU", L"MXV", L"MXW", L"MXX", L"MXY", L"MXZ", L"MYA", L"MYB", L"MYC", L"MYD", L"MYE", L"MYF", L"MYG", L"MYH", L"MYI", L"MYJ", L"MYK", L"MYL", L"MYM", L"MYN", L"MYO", L"MYP", L"MYQ", L"MYR", L"MYS", L"MYT", L"MYU", L"MYV", L"MYW", L"MYX", L"MYY", L"MYZ", L"MZA", L"MZB", L"MZC", L"MZD", L"MZE", L"MZF", L"MZG", L"MZH", L"MZI", L"MZJ", L"MZK", L"MZL", L"MZM", L"MZN", L"MZO", L"MZP", L"MZQ", L"MZR", L"MZS", L"MZT", L"MZU", L"MZV", L"MZW", L"MZX", L"MZY", L"MZZ", L"NAA", L"NAB", L"NAC", L"NAD", L"NAE", L"NAF", L"NAG", L"NAH", L"NAI", L"NAJ", L"NAK", L"NAL", L"NAM", L"NAN", L"NAO", L"NAP", L"NAQ", L"NAR", L"NAS", L"NAT", L"NAU", L"NAV", L"NAW", L"NAX", L"NAY", L"NAZ", L"NBA", L"NBB", L"NBC", L"NBD", L"NBE", L"NBF", L"NBG", L"NBH", L"NBI", L"NBJ", L"NBK", L"NBL", L"NBM", L"NBN", L"NBO", L"NBP", L"NBQ", L"NBR", L"NBS", L"NBT", L"NBU", L"NBV", L"NBW", L"NBX", L"NBY", L"NBZ", L"NCA", L"NCB", L"NCC", L"NCD", L"NCE", L"NCF", L"NCG", L"NCH", L"NCI", L"NCJ", L"NCK", L"NCL", L"NCM", L"NCN", L"NCO", L"NCP", L"NCQ", L"NCR", L"NCS", L"NCT", L"NCU", L"NCV", L"NCW", L"NCX", L"NCY", L"NCZ", L"NDA", L"NDB", L"NDC", L"NDD", L"NDE", L"NDF", L"NDG", L"NDH", L"NDI", L"NDJ", L"NDK", L"NDL", L"NDM", L"NDN", L"NDO", L"NDP", L"NDQ", L"NDR", L"NDS", L"NDT", L"NDU", L"NDV", L"NDW", L"NDX", L"NDY", L"NDZ", L"NEA", L"NEB", L"NEC", L"NED", L"NEE", L"NEF", L"NEG", L"NEH", L"NEI", L"NEJ", L"NEK", L"NEL", L"NEM", L"NEN", L"NEO", L"NEP", + L"NEQ", L"NER", L"NES", L"NET", L"NEU", L"NEV", L"NEW", L"NEX", L"NEY", L"NEZ", L"NFA", L"NFB", L"NFC", L"NFD", L"NFE", L"NFF", L"NFG", L"NFH", L"NFI", L"NFJ", L"NFK", L"NFL", L"NFM", L"NFN", L"NFO", L"NFP", L"NFQ", L"NFR", L"NFS", L"NFT", L"NFU", L"NFV", L"NFW", L"NFX", L"NFY", L"NFZ", L"NGA", L"NGB", L"NGC", L"NGD", L"NGE", L"NGF", L"NGG", L"NGH", L"NGI", L"NGJ", L"NGK", L"NGL", L"NGM", L"NGN", L"NGO", L"NGP", L"NGQ", L"NGR", L"NGS", L"NGT", L"NGU", L"NGV", L"NGW", L"NGX", L"NGY", L"NGZ", L"NHA", L"NHB", L"NHC", L"NHD", L"NHE", L"NHF", L"NHG", L"NHH", L"NHI", L"NHJ", L"NHK", L"NHL", L"NHM", L"NHN", L"NHO", L"NHP", L"NHQ", L"NHR", L"NHS", L"NHT", L"NHU", L"NHV", L"NHW", L"NHX", L"NHY", L"NHZ", L"NIA", L"NIB", L"NIC", L"NID", L"NIE", L"NIF", L"NIG", L"NIH", L"NII", L"NIJ", L"NIK", L"NIL", L"NIM", L"NIN", L"NIO", L"NIP", L"NIQ", L"NIR", L"NIS", L"NIT", L"NIU", L"NIV", L"NIW", L"NIX", L"NIY", L"NIZ", L"NJA", L"NJB", L"NJC", L"NJD", L"NJE", L"NJF", L"NJG", L"NJH", L"NJI", L"NJJ", L"NJK", L"NJL", L"NJM", L"NJN", L"NJO", L"NJP", L"NJQ", L"NJR", L"NJS", L"NJT", L"NJU", L"NJV", L"NJW", L"NJX", L"NJY", L"NJZ", L"NKA", L"NKB", L"NKC", L"NKD", L"NKE", L"NKF", L"NKG", L"NKH", L"NKI", L"NKJ", L"NKK", L"NKL", L"NKM", L"NKN", L"NKO", L"NKP", L"NKQ", L"NKR", L"NKS", L"NKT", L"NKU", L"NKV", L"NKW", L"NKX", L"NKY", L"NKZ", L"NLA", L"NLB", L"NLC", L"NLD", L"NLE", L"NLF", L"NLG", L"NLH", L"NLI", L"NLJ", L"NLK", L"NLL", L"NLM", L"NLN", L"NLO", L"NLP", L"NLQ", L"NLR", L"NLS", L"NLT", L"NLU", L"NLV", L"NLW", L"NLX", L"NLY", L"NLZ", L"NMA", L"NMB", L"NMC", L"NMD", L"NME", L"NMF", L"NMG", L"NMH", L"NMI", L"NMJ", L"NMK", L"NML", L"NMM", L"NMN", L"NMO", L"NMP", L"NMQ", L"NMR", L"NMS", L"NMT", L"NMU", L"NMV", L"NMW", L"NMX", L"NMY", L"NMZ", L"NNA", L"NNB", L"NNC", L"NND", L"NNE", L"NNF", L"NNG", L"NNH", L"NNI", L"NNJ", L"NNK", L"NNL", L"NNM", L"NNN", L"NNO", L"NNP", L"NNQ", L"NNR", L"NNS", L"NNT", L"NNU", L"NNV", L"NNW", L"NNX", L"NNY", L"NNZ", L"NOA", L"NOB", L"NOC", L"NOD", L"NOE", L"NOF", L"NOG", L"NOH", L"NOI", L"NOJ", L"NOK", L"NOL", L"NOM", L"NON", L"NOO", L"NOP", L"NOQ", L"NOR", L"NOS", L"NOT", L"NOU", L"NOV", L"NOW", L"NOX", L"NOY", L"NOZ", L"NPA", L"NPB", L"NPC", + L"NPD", L"NPE", L"NPF", L"NPG", L"NPH", L"NPI", L"NPJ", L"NPK", L"NPL", L"NPM", L"NPN", L"NPO", L"NPP", L"NPQ", L"NPR", L"NPS", L"NPT", L"NPU", L"NPV", L"NPW", L"NPX", L"NPY", L"NPZ", L"NQA", L"NQB", L"NQC", L"NQD", L"NQE", L"NQF", L"NQG", L"NQH", L"NQI", L"NQJ", L"NQK", L"NQL", L"NQM", L"NQN", L"NQO", L"NQP", L"NQQ", L"NQR", L"NQS", L"NQT", L"NQU", L"NQV", L"NQW", L"NQX", L"NQY", L"NQZ", L"NRA", L"NRB", L"NRC", L"NRD", L"NRE", L"NRF", L"NRG", L"NRH", L"NRI", L"NRJ", L"NRK", L"NRL", L"NRM", L"NRN", L"NRO", L"NRP", L"NRQ", L"NRR", L"NRS", L"NRT", L"NRU", L"NRV", L"NRW", L"NRX", L"NRY", L"NRZ", L"NSA", L"NSB", L"NSC", L"NSD", L"NSE", L"NSF", L"NSG", L"NSH", L"NSI", L"NSJ", L"NSK", L"NSL", L"NSM", L"NSN", L"NSO", L"NSP", L"NSQ", L"NSR", L"NSS", L"NST", L"NSU", L"NSV", L"NSW", L"NSX", L"NSY", L"NSZ", L"NTA", L"NTB", L"NTC", L"NTD", L"NTE", L"NTF", L"NTG", L"NTH", L"NTI", L"NTJ", L"NTK", L"NTL", L"NTM", L"NTN", L"NTO", L"NTP", L"NTQ", L"NTR", L"NTS", L"NTT", L"NTU", L"NTV", L"NTW", L"NTX", L"NTY", L"NTZ", L"NUA", L"NUB", L"NUC", L"NUD", L"NUE", L"NUF", L"NUG", L"NUH", L"NUI", L"NUJ", L"NUK", L"NUL", L"NUM", L"NUN", L"NUO", L"NUP", L"NUQ", L"NUR", L"NUS", L"NUT", L"NUU", L"NUV", L"NUW", L"NUX", L"NUY", L"NUZ", L"NVA", L"NVB", L"NVC", L"NVD", L"NVE", L"NVF", L"NVG", L"NVH", L"NVI", L"NVJ", L"NVK", L"NVL", L"NVM", L"NVN", L"NVO", L"NVP", L"NVQ", L"NVR", L"NVS", L"NVT", L"NVU", L"NVV", L"NVW", L"NVX", L"NVY", L"NVZ", L"NWA", L"NWB", L"NWC", L"NWD", L"NWE", L"NWF", L"NWG", L"NWH", L"NWI", L"NWJ", L"NWK", L"NWL", L"NWM", L"NWN", L"NWO", L"NWP", L"NWQ", L"NWR", L"NWS", L"NWT", L"NWU", L"NWV", L"NWW", L"NWX", L"NWY", L"NWZ", L"NXA", L"NXB", L"NXC", L"NXD", L"NXE", L"NXF", L"NXG", L"NXH", L"NXI", L"NXJ", L"NXK", L"NXL", L"NXM", L"NXN", L"NXO", L"NXP", L"NXQ", L"NXR", L"NXS", L"NXT", L"NXU", L"NXV", L"NXW", L"NXX", L"NXY", L"NXZ", L"NYA", L"NYB", L"NYC", L"NYD", L"NYE", L"NYF", L"NYG", L"NYH", L"NYI", L"NYJ", L"NYK", L"NYL", L"NYM", L"NYN", L"NYO", L"NYP", L"NYQ", L"NYR", L"NYS", L"NYT", L"NYU", L"NYV", L"NYW", L"NYX", L"NYY", L"NYZ", L"NZA", L"NZB", L"NZC", L"NZD", L"NZE", L"NZF", L"NZG", L"NZH", L"NZI", L"NZJ", L"NZK", L"NZL", L"NZM", L"NZN", L"NZO", L"NZP", + L"NZQ", L"NZR", L"NZS", L"NZT", L"NZU", L"NZV", L"NZW", L"NZX", L"NZY", L"NZZ", L"OAA", L"OAB", L"OAC", L"OAD", L"OAE", L"OAF", L"OAG", L"OAH", L"OAI", L"OAJ", L"OAK", L"OAL", L"OAM", L"OAN", L"OAO", L"OAP", L"OAQ", L"OAR", L"OAS", L"OAT", L"OAU", L"OAV", L"OAW", L"OAX", L"OAY", L"OAZ", L"OBA", L"OBB", L"OBC", L"OBD", L"OBE", L"OBF", L"OBG", L"OBH", L"OBI", L"OBJ", L"OBK", L"OBL", L"OBM", L"OBN", L"OBO", L"OBP", L"OBQ", L"OBR", L"OBS", L"OBT", L"OBU", L"OBV", L"OBW", L"OBX", L"OBY", L"OBZ", L"OCA", L"OCB", L"OCC", L"OCD", L"OCE", L"OCF", L"OCG", L"OCH", L"OCI", L"OCJ", L"OCK", L"OCL", L"OCM", L"OCN", L"OCO", L"OCP", L"OCQ", L"OCR", L"OCS", L"OCT", L"OCU", L"OCV", L"OCW", L"OCX", L"OCY", L"OCZ", L"ODA", L"ODB", L"ODC", L"ODD", L"ODE", L"ODF", L"ODG", L"ODH", L"ODI", L"ODJ", L"ODK", L"ODL", L"ODM", L"ODN", L"ODO", L"ODP", L"ODQ", L"ODR", L"ODS", L"ODT", L"ODU", L"ODV", L"ODW", L"ODX", L"ODY", L"ODZ", L"OEA", L"OEB", L"OEC", L"OED", L"OEE", L"OEF", L"OEG", L"OEH", L"OEI", L"OEJ", L"OEK", L"OEL", L"OEM", L"OEN", L"OEO", L"OEP", L"OEQ", L"OER", L"OES", L"OET", L"OEU", L"OEV", L"OEW", L"OEX", L"OEY", L"OEZ", L"OFA", L"OFB", L"OFC", L"OFD", L"OFE", L"OFF", L"OFG", L"OFH", L"OFI", L"OFJ", L"OFK", L"OFL", L"OFM", L"OFN", L"OFO", L"OFP", L"OFQ", L"OFR", L"OFS", L"OFT", L"OFU", L"OFV", L"OFW", L"OFX", L"OFY", L"OFZ", L"OGA", L"OGB", L"OGC", L"OGD", L"OGE", L"OGF", L"OGG", L"OGH", L"OGI", L"OGJ", L"OGK", L"OGL", L"OGM", L"OGN", L"OGO", L"OGP", L"OGQ", L"OGR", L"OGS", L"OGT", L"OGU", L"OGV", L"OGW", L"OGX", L"OGY", L"OGZ", L"OHA", L"OHB", L"OHC", L"OHD", L"OHE", L"OHF", L"OHG", L"OHH", L"OHI", L"OHJ", L"OHK", L"OHL", L"OHM", L"OHN", L"OHO", L"OHP", L"OHQ", L"OHR", L"OHS", L"OHT", L"OHU", L"OHV", L"OHW", L"OHX", L"OHY", L"OHZ", L"OIA", L"OIB", L"OIC", L"OID", L"OIE", L"OIF", L"OIG", L"OIH", L"OII", L"OIJ", L"OIK", L"OIL", L"OIM", L"OIN", L"OIO", L"OIP", L"OIQ", L"OIR", L"OIS", L"OIT", L"OIU", L"OIV", L"OIW", L"OIX", L"OIY", L"OIZ", L"OJA", L"OJB", L"OJC", L"OJD", L"OJE", L"OJF", L"OJG", L"OJH", L"OJI", L"OJJ", L"OJK", L"OJL", L"OJM", L"OJN", L"OJO", L"OJP", L"OJQ", L"OJR", L"OJS", L"OJT", L"OJU", L"OJV", L"OJW", L"OJX", L"OJY", L"OJZ", L"OKA", L"OKB", L"OKC", + L"OKD", L"OKE", L"OKF", L"OKG", L"OKH", L"OKI", L"OKJ", L"OKK", L"OKL", L"OKM", L"OKN", L"OKO", L"OKP", L"OKQ", L"OKR", L"OKS", L"OKT", L"OKU", L"OKV", L"OKW", L"OKX", L"OKY", L"OKZ", L"OLA", L"OLB", L"OLC", L"OLD", L"OLE", L"OLF", L"OLG", L"OLH", L"OLI", L"OLJ", L"OLK", L"OLL", L"OLM", L"OLN", L"OLO", L"OLP", L"OLQ", L"OLR", L"OLS", L"OLT", L"OLU", L"OLV", L"OLW", L"OLX", L"OLY", L"OLZ", L"OMA", L"OMB", L"OMC", L"OMD", L"OME", L"OMF", L"OMG", L"OMH", L"OMI", L"OMJ", L"OMK", L"OML", L"OMM", L"OMN", L"OMO", L"OMP", L"OMQ", L"OMR", L"OMS", L"OMT", L"OMU", L"OMV", L"OMW", L"OMX", L"OMY", L"OMZ", L"ONA", L"ONB", L"ONC", L"OND", L"ONE", L"ONF", L"ONG", L"ONH", L"ONI", L"ONJ", L"ONK", L"ONL", L"ONM", L"ONN", L"ONO", L"ONP", L"ONQ", L"ONR", L"ONS", L"ONT", L"ONU", L"ONV", L"ONW", L"ONX", L"ONY", L"ONZ", L"OOA", L"OOB", L"OOC", L"OOD", L"OOE", L"OOF", L"OOG", L"OOH", L"OOI", L"OOJ", L"OOK", L"OOL", L"OOM", L"OON", L"OOO", L"OOP", L"OOQ", L"OOR", L"OOS", L"OOT", L"OOU", L"OOV", L"OOW", L"OOX", L"OOY", L"OOZ", L"OPA", L"OPB", L"OPC", L"OPD", L"OPE", L"OPF", L"OPG", L"OPH", L"OPI", L"OPJ", L"OPK", L"OPL", L"OPM", L"OPN", L"OPO", L"OPP", L"OPQ", L"OPR", L"OPS", L"OPT", L"OPU", L"OPV", L"OPW", L"OPX", L"OPY", L"OPZ", L"OQA", L"OQB", L"OQC", L"OQD", L"OQE", L"OQF", L"OQG", L"OQH", L"OQI", L"OQJ", L"OQK", L"OQL", L"OQM", L"OQN", L"OQO", L"OQP", L"OQQ", L"OQR", L"OQS", L"OQT", L"OQU", L"OQV", L"OQW", L"OQX", L"OQY", L"OQZ", L"ORA", L"ORB", L"ORC", L"ORD", L"ORE", L"ORF", L"ORG", L"ORH", L"ORI", L"ORJ", L"ORK", L"ORL", L"ORM", L"ORN", L"ORO", L"ORP", L"ORQ", L"ORR", L"ORS", L"ORT", L"ORU", L"ORV", L"ORW", L"ORX", L"ORY", L"ORZ", L"OSA", L"OSB", L"OSC", L"OSD", L"OSE", L"OSF", L"OSG", L"OSH", L"OSI", L"OSJ", L"OSK", L"OSL", L"OSM", L"OSN", L"OSO", L"OSP", L"OSQ", L"OSR", L"OSS", L"OST", L"OSU", L"OSV", L"OSW", L"OSX", L"OSY", L"OSZ", L"OTA", L"OTB", L"OTC", L"OTD", L"OTE", L"OTF", L"OTG", L"OTH", L"OTI", L"OTJ", L"OTK", L"OTL", L"OTM", L"OTN", L"OTO", L"OTP", L"OTQ", L"OTR", L"OTS", L"OTT", L"OTU", L"OTV", L"OTW", L"OTX", L"OTY", L"OTZ", L"OUA", L"OUB", L"OUC", L"OUD", L"OUE", L"OUF", L"OUG", L"OUH", L"OUI", L"OUJ", L"OUK", L"OUL", L"OUM", L"OUN", L"OUO", L"OUP", + L"OUQ", L"OUR", L"OUS", L"OUT", L"OUU", L"OUV", L"OUW", L"OUX", L"OUY", L"OUZ", L"OVA", L"OVB", L"OVC", L"OVD", L"OVE", L"OVF", L"OVG", L"OVH", L"OVI", L"OVJ", L"OVK", L"OVL", L"OVM", L"OVN", L"OVO", L"OVP", L"OVQ", L"OVR", L"OVS", L"OVT", L"OVU", L"OVV", L"OVW", L"OVX", L"OVY", L"OVZ", L"OWA", L"OWB", L"OWC", L"OWD", L"OWE", L"OWF", L"OWG", L"OWH", L"OWI", L"OWJ", L"OWK", L"OWL", L"OWM", L"OWN", L"OWO", L"OWP", L"OWQ", L"OWR", L"OWS", L"OWT", L"OWU", L"OWV", L"OWW", L"OWX", L"OWY", L"OWZ", L"OXA", L"OXB", L"OXC", L"OXD", L"OXE", L"OXF", L"OXG", L"OXH", L"OXI", L"OXJ", L"OXK", L"OXL", L"OXM", L"OXN", L"OXO", L"OXP", L"OXQ", L"OXR", L"OXS", L"OXT", L"OXU", L"OXV", L"OXW", L"OXX", L"OXY", L"OXZ", L"OYA", L"OYB", L"OYC", L"OYD", L"OYE", L"OYF", L"OYG", L"OYH", L"OYI", L"OYJ", L"OYK", L"OYL", L"OYM", L"OYN", L"OYO", L"OYP", L"OYQ", L"OYR", L"OYS", L"OYT", L"OYU", L"OYV", L"OYW", L"OYX", L"OYY", L"OYZ", L"OZA", L"OZB", L"OZC", L"OZD", L"OZE", L"OZF", L"OZG", L"OZH", L"OZI", L"OZJ", L"OZK", L"OZL", L"OZM", L"OZN", L"OZO", L"OZP", L"OZQ", L"OZR", L"OZS", L"OZT", L"OZU", L"OZV", L"OZW", L"OZX", L"OZY", L"OZZ", L"PAA", L"PAB", L"PAC", L"PAD", L"PAE", L"PAF", L"PAG", L"PAH", L"PAI", L"PAJ", L"PAK", L"PAL", L"PAM", L"PAN", L"PAO", L"PAP", L"PAQ", L"PAR", L"PAS", L"PAT", L"PAU", L"PAV", L"PAW", L"PAX", L"PAY", L"PAZ", L"PBA", L"PBB", L"PBC", L"PBD", L"PBE", L"PBF", L"PBG", L"PBH", L"PBI", L"PBJ", L"PBK", L"PBL", L"PBM", L"PBN", L"PBO", L"PBP", L"PBQ", L"PBR", L"PBS", L"PBT", L"PBU", L"PBV", L"PBW", L"PBX", L"PBY", L"PBZ", L"PCA", L"PCB", L"PCC", L"PCD", L"PCE", L"PCF", L"PCG", L"PCH", L"PCI", L"PCJ", L"PCK", L"PCL", L"PCM", L"PCN", L"PCO", L"PCP", L"PCQ", L"PCR", L"PCS", L"PCT", L"PCU", L"PCV", L"PCW", L"PCX", L"PCY", L"PCZ", L"PDA", L"PDB", L"PDC", L"PDD", L"PDE", L"PDF", L"PDG", L"PDH", L"PDI", L"PDJ", L"PDK", L"PDL", L"PDM", L"PDN", L"PDO", L"PDP", L"PDQ", L"PDR", L"PDS", L"PDT", L"PDU", L"PDV", L"PDW", L"PDX", L"PDY", L"PDZ", L"PEA", L"PEB", L"PEC", L"PED", L"PEE", L"PEF", L"PEG", L"PEH", L"PEI", L"PEJ", L"PEK", L"PEL", L"PEM", L"PEN", L"PEO", L"PEP", L"PEQ", L"PER", L"PES", L"PET", L"PEU", L"PEV", L"PEW", L"PEX", L"PEY", L"PEZ", L"PFA", L"PFB", L"PFC", L"PFD", L"PFE", L"PFF", L"PFG", L"PFH", L"PFI", L"PFJ", L"PFK", L"PFL", L"PFM", L"PFN", L"PFO", L"PFP", L"PFQ", L"PFR", L"PFS", L"PFT", L"PFU", L"PFV", L"PFW", L"PFX", L"PFY", L"PFZ", L"PGA", L"PGB", L"PGC", L"PGD", L"PGE", L"PGF", L"PGG", L"PGH", L"PGI", L"PGJ", L"PGK", L"PGL", L"PGM", L"PGN", L"PGO", L"PGP", L"PGQ", L"PGR", L"PGS", L"PGT", L"PGU", L"PGV", L"PGW", L"PGX", L"PGY", L"PGZ", L"PHA", L"PHB", L"PHC", L"PHD", L"PHE", L"PHF", L"PHG", L"PHH", L"PHI", L"PHJ", L"PHK", L"PHL", L"PHM", L"PHN", L"PHO", L"PHP", L"PHQ", L"PHR", L"PHS", L"PHT", L"PHU", L"PHV", L"PHW", L"PHX", L"PHY", L"PHZ", L"PIA", L"PIB", L"PIC", L"PID", L"PIE", L"PIF", L"PIG", L"PIH", L"PII", L"PIJ", L"PIK", L"PIL", L"PIM", L"PIN", L"PIO", L"PIP", L"PIQ", L"PIR", L"PIS", L"PIT", L"PIU", L"PIV", L"PIW", L"PIX", L"PIY", L"PIZ", L"PJA", L"PJB", L"PJC", L"PJD", L"PJE", L"PJF", L"PJG", L"PJH", L"PJI", L"PJJ", L"PJK", L"PJL", L"PJM", L"PJN", L"PJO", L"PJP", L"PJQ", L"PJR", L"PJS", L"PJT", L"PJU", L"PJV", L"PJW", L"PJX", L"PJY", L"PJZ", L"PKA", L"PKB", L"PKC", L"PKD", L"PKE", L"PKF", L"PKG", L"PKH", L"PKI", L"PKJ", L"PKK", L"PKL", L"PKM", L"PKN", L"PKO", L"PKP", L"PKQ", L"PKR", L"PKS", L"PKT", L"PKU", L"PKV", L"PKW", L"PKX", L"PKY", L"PKZ", L"PLA", L"PLB", L"PLC", L"PLD", L"PLE", L"PLF", L"PLG", L"PLH", L"PLI", L"PLJ", L"PLK", L"PLL", L"PLM", L"PLN", L"PLO", L"PLP", L"PLQ", L"PLR", L"PLS", L"PLT", L"PLU", L"PLV", L"PLW", L"PLX", L"PLY", L"PLZ", L"PMA", L"PMB", L"PMC", L"PMD", L"PME", L"PMF", L"PMG", L"PMH", L"PMI", L"PMJ", L"PMK", L"PML", L"PMM", L"PMN", L"PMO", L"PMP", L"PMQ", L"PMR", L"PMS", L"PMT", L"PMU", L"PMV", L"PMW", L"PMX", L"PMY", L"PMZ", L"PNA", L"PNB", L"PNC", L"PND", L"PNE", L"PNF", L"PNG", L"PNH", L"PNI", L"PNJ", L"PNK", L"PNL", L"PNM", L"PNN", L"PNO", L"PNP", L"PNQ", L"PNR", L"PNS", L"PNT", L"PNU", L"PNV", L"PNW", L"PNX", L"PNY", L"PNZ", L"POA", L"POB", L"POC", L"POD", L"POE", L"POF", L"POG", L"POH", L"POI", L"POJ", L"POK", L"POL", L"POM", L"PON", L"POO", L"POP", L"POQ", L"POR", L"POS", L"POT", L"POU", L"POV", L"POW", L"POX", L"POY", L"POZ", L"PPA", L"PPB", L"PPC", L"PPD", L"PPE", L"PPF", L"PPG", L"PPH", - L"PPI", L"PPJ", L"PPK", L"PPL", L"PPM", L"PPN", L"PPO", L"PPP", L"PPQ", L"PPR", L"PPS", L"PPT", L"PPU", L"PPV", L"PPW", L"PPX", L"PPY", L"PPZ", L"PQA", L"PQB", L"PQC", L"PQD", L"PQE", L"PQF", L"PQG", L"PQH", L"PQI", L"PQJ", L"PQK", L"PQL", L"PQM", L"PQN", L"PQO", L"PQP", L"PQQ", L"PQR", L"PQS", L"PQT", L"PQU", L"PQV", L"PQW", L"PQX", L"PQY", L"PQZ", L"PRA", L"PRB", L"PRC", L"PRD", L"PRE", L"PRF", L"PRG", L"PRH", L"PRI", L"PRJ", L"PRK", L"PRL", L"PRM", L"PRN", L"PRO", L"PRP", L"PRQ", L"PRR", L"PRS", L"PRT", L"PRU", L"PRV", L"PRW", L"PRX", L"PRY", L"PRZ", L"PSA", L"PSB", L"PSC", L"PSD", L"PSE", L"PSF", L"PSG", L"PSH", L"PSI", L"PSJ", L"PSK", L"PSL", L"PSM", L"PSN", L"PSO", L"PSP", L"PSQ", L"PSR", L"PSS", L"PST", L"PSU", L"PSV", L"PSW", L"PSX", L"PSY", L"PSZ", L"PTA", L"PTB", L"PTC", L"PTD", L"PTE", L"PTF", L"PTG", L"PTH", L"PTI", L"PTJ", L"PTK", L"PTL", L"PTM", L"PTN", L"PTO", L"PTP", L"PTQ", L"PTR", L"PTS", L"PTT", L"PTU", L"PTV", L"PTW", L"PTX", L"PTY", L"PTZ", L"PUA", L"PUB", L"PUC", L"PUD", L"PUE", L"PUF", L"PUG", L"PUH", L"PUI", L"PUJ", L"PUK", L"PUL", L"PUM", L"PUN", L"PUO", L"PUP", L"PUQ", L"PUR", L"PUS", L"PUT", L"PUU", L"PUV", L"PUW", L"PUX", L"PUY", L"PUZ", L"PVA", L"PVB", L"PVC", L"PVD", L"PVE", L"PVF", L"PVG", L"PVH", L"PVI", L"PVJ", L"PVK", L"PVL", L"PVM", L"PVN", L"PVO", L"PVP", L"PVQ", L"PVR", L"PVS", L"PVT", L"PVU", L"PVV", L"PVW", L"PVX", L"PVY", L"PVZ", L"PWA", L"PWB", L"PWC", L"PWD", L"PWE", L"PWF", L"PWG", L"PWH", L"PWI", L"PWJ", L"PWK", L"PWL", L"PWM", L"PWN", L"PWO", L"PWP", L"PWQ", L"PWR", L"PWS", L"PWT", L"PWU", L"PWV", L"PWW", L"PWX", L"PWY", L"PWZ", L"PXA", L"PXB", L"PXC", L"PXD", L"PXE", L"PXF", L"PXG", L"PXH", L"PXI", L"PXJ", L"PXK", L"PXL", L"PXM", L"PXN", L"PXO", L"PXP", L"PXQ", L"PXR", L"PXS", L"PXT", L"PXU", L"PXV", L"PXW", L"PXX", L"PXY", L"PXZ", L"PYA", L"PYB", L"PYC", L"PYD", L"PYE", L"PYF", L"PYG", L"PYH", L"PYI", L"PYJ", L"PYK", L"PYL", L"PYM", L"PYN", L"PYO", L"PYP", L"PYQ", L"PYR", L"PYS", L"PYT", L"PYU", L"PYV", L"PYW", L"PYX", L"PYY", L"PYZ", L"PZA", L"PZB", L"PZC", L"PZD", L"PZE", L"PZF", L"PZG", L"PZH", L"PZI", L"PZJ", L"PZK", L"PZL", L"PZM", L"PZN", L"PZO", L"PZP", L"PZQ", L"PZR", L"PZS", L"PZT", L"PZU", + L"PPI", L"PPJ", L"PPK", L"PPL", L"PPM", L"PPN", L"PPO", L"PPP", L"PPQ", L"PPR", L"PPS", L"PPT", L"PPU", L"PPV", L"PPW", L"PPX", L"PPY", L"PPZ", L"PQA", L"PQB", L"PQC", L"PQD", L"PQE", L"PQF", L"PQG", L"PQH", L"PQI", L"PQJ", L"PQK", L"PQL", L"PQM", L"PQN", L"PQO", L"PQP", L"PQQ", L"PQR", L"PQS", L"PQT", L"PQU", L"PQV", L"PQW", L"PQX", L"PQY", L"PQZ", L"PRA", L"PRB", L"PRC", L"PRD", L"PRE", L"PRF", L"PRG", L"PRH", L"PRI", L"PRJ", L"PRK", L"PRL", L"PRM", L"PRN", L"PRO", L"PRP", L"PRQ", L"PRR", L"PRS", L"PRT", L"PRU", L"PRV", L"PRW", L"PRX", L"PRY", L"PRZ", L"PSA", L"PSB", L"PSC", L"PSD", L"PSE", L"PSF", L"PSG", L"PSH", L"PSI", L"PSJ", L"PSK", L"PSL", L"PSM", L"PSN", L"PSO", L"PSP", L"PSQ", L"PSR", L"PSS", L"PST", L"PSU", L"PSV", L"PSW", L"PSX", L"PSY", L"PSZ", L"PTA", L"PTB", L"PTC", L"PTD", L"PTE", L"PTF", L"PTG", L"PTH", L"PTI", L"PTJ", L"PTK", L"PTL", L"PTM", L"PTN", L"PTO", L"PTP", L"PTQ", L"PTR", L"PTS", L"PTT", L"PTU", L"PTV", L"PTW", L"PTX", L"PTY", L"PTZ", L"PUA", L"PUB", L"PUC", L"PUD", L"PUE", L"PUF", L"PUG", L"PUH", L"PUI", L"PUJ", L"PUK", L"PUL", L"PUM", L"PUN", L"PUO", L"PUP", L"PUQ", L"PUR", L"PUS", L"PUT", L"PUU", L"PUV", L"PUW", L"PUX", L"PUY", L"PUZ", L"PVA", L"PVB", L"PVC", L"PVD", L"PVE", L"PVF", L"PVG", L"PVH", L"PVI", L"PVJ", L"PVK", L"PVL", L"PVM", L"PVN", L"PVO", L"PVP", L"PVQ", L"PVR", L"PVS", L"PVT", L"PVU", L"PVV", L"PVW", L"PVX", L"PVY", L"PVZ", L"PWA", L"PWB", L"PWC", L"PWD", L"PWE", L"PWF", L"PWG", L"PWH", L"PWI", L"PWJ", L"PWK", L"PWL", L"PWM", L"PWN", L"PWO", L"PWP", L"PWQ", L"PWR", L"PWS", L"PWT", L"PWU", L"PWV", L"PWW", L"PWX", L"PWY", L"PWZ", L"PXA", L"PXB", L"PXC", L"PXD", L"PXE", L"PXF", L"PXG", L"PXH", L"PXI", L"PXJ", L"PXK", L"PXL", L"PXM", L"PXN", L"PXO", L"PXP", L"PXQ", L"PXR", L"PXS", L"PXT", L"PXU", L"PXV", L"PXW", L"PXX", L"PXY", L"PXZ", L"PYA", L"PYB", L"PYC", L"PYD", L"PYE", L"PYF", L"PYG", L"PYH", L"PYI", L"PYJ", L"PYK", L"PYL", L"PYM", L"PYN", L"PYO", L"PYP", L"PYQ", L"PYR", L"PYS", L"PYT", L"PYU", L"PYV", L"PYW", L"PYX", L"PYY", L"PYZ", L"PZA", L"PZB", L"PZC", L"PZD", L"PZE", L"PZF", L"PZG", L"PZH", L"PZI", L"PZJ", L"PZK", L"PZL", L"PZM", L"PZN", L"PZO", L"PZP", L"PZQ", L"PZR", L"PZS", L"PZT", L"PZU", L"PZV", L"PZW", L"PZX", L"PZY", L"PZZ", L"QAA", L"QAB", L"QAC", L"QAD", L"QAE", L"QAF", L"QAG", L"QAH", L"QAI", L"QAJ", L"QAK", L"QAL", L"QAM", L"QAN", L"QAO", L"QAP", L"QAQ", L"QAR", L"QAS", L"QAT", L"QAU", L"QAV", L"QAW", L"QAX", L"QAY", L"QAZ", L"QBA", L"QBB", L"QBC", L"QBD", L"QBE", L"QBF", L"QBG", L"QBH", L"QBI", L"QBJ", L"QBK", L"QBL", L"QBM", L"QBN", L"QBO", L"QBP", L"QBQ", L"QBR", L"QBS", L"QBT", L"QBU", L"QBV", L"QBW", L"QBX", L"QBY", L"QBZ", L"QCA", L"QCB", L"QCC", L"QCD", L"QCE", L"QCF", L"QCG", L"QCH", L"QCI", L"QCJ", L"QCK", L"QCL", L"QCM", L"QCN", L"QCO", L"QCP", L"QCQ", L"QCR", L"QCS", L"QCT", L"QCU", L"QCV", L"QCW", L"QCX", L"QCY", L"QCZ", L"QDA", L"QDB", L"QDC", L"QDD", L"QDE", L"QDF", L"QDG", L"QDH", L"QDI", L"QDJ", L"QDK", L"QDL", L"QDM", L"QDN", L"QDO", L"QDP", L"QDQ", L"QDR", L"QDS", L"QDT", L"QDU", L"QDV", L"QDW", L"QDX", L"QDY", L"QDZ", L"QEA", L"QEB", L"QEC", L"QED", L"QEE", L"QEF", L"QEG", L"QEH", L"QEI", L"QEJ", L"QEK", L"QEL", L"QEM", L"QEN", L"QEO", L"QEP", L"QEQ", L"QER", L"QES", L"QET", L"QEU", L"QEV", L"QEW", L"QEX", L"QEY", L"QEZ", L"QFA", L"QFB", L"QFC", L"QFD", L"QFE", L"QFF", L"QFG", L"QFH", L"QFI", L"QFJ", L"QFK", L"QFL", L"QFM", L"QFN", L"QFO", L"QFP", L"QFQ", L"QFR", L"QFS", L"QFT", L"QFU", L"QFV", L"QFW", L"QFX", L"QFY", L"QFZ", L"QGA", L"QGB", L"QGC", L"QGD", L"QGE", L"QGF", L"QGG", L"QGH", L"QGI", L"QGJ", L"QGK", L"QGL", L"QGM", L"QGN", L"QGO", L"QGP", L"QGQ", L"QGR", L"QGS", L"QGT", L"QGU", L"QGV", L"QGW", L"QGX", L"QGY", L"QGZ", L"QHA", L"QHB", L"QHC", L"QHD", L"QHE", L"QHF", L"QHG", L"QHH", L"QHI", L"QHJ", L"QHK", L"QHL", L"QHM", L"QHN", L"QHO", L"QHP", L"QHQ", L"QHR", L"QHS", L"QHT", L"QHU", L"QHV", L"QHW", L"QHX", L"QHY", L"QHZ", L"QIA", L"QIB", L"QIC", L"QID", L"QIE", L"QIF", L"QIG", L"QIH", L"QII", L"QIJ", L"QIK", L"QIL", L"QIM", L"QIN", L"QIO", L"QIP", L"QIQ", L"QIR", L"QIS", L"QIT", L"QIU", L"QIV", L"QIW", L"QIX", L"QIY", L"QIZ", L"QJA", L"QJB", L"QJC", L"QJD", L"QJE", L"QJF", L"QJG", L"QJH", L"QJI", L"QJJ", L"QJK", L"QJL", L"QJM", L"QJN", L"QJO", L"QJP", L"QJQ", L"QJR", L"QJS", L"QJT", L"QJU", L"QJV", L"QJW", L"QJX", L"QJY", L"QJZ", L"QKA", L"QKB", L"QKC", L"QKD", L"QKE", L"QKF", L"QKG", L"QKH", - L"QKI", L"QKJ", L"QKK", L"QKL", L"QKM", L"QKN", L"QKO", L"QKP", L"QKQ", L"QKR", L"QKS", L"QKT", L"QKU", L"QKV", L"QKW", L"QKX", L"QKY", L"QKZ", L"QLA", L"QLB", L"QLC", L"QLD", L"QLE", L"QLF", L"QLG", L"QLH", L"QLI", L"QLJ", L"QLK", L"QLL", L"QLM", L"QLN", L"QLO", L"QLP", L"QLQ", L"QLR", L"QLS", L"QLT", L"QLU", L"QLV", L"QLW", L"QLX", L"QLY", L"QLZ", L"QMA", L"QMB", L"QMC", L"QMD", L"QME", L"QMF", L"QMG", L"QMH", L"QMI", L"QMJ", L"QMK", L"QML", L"QMM", L"QMN", L"QMO", L"QMP", L"QMQ", L"QMR", L"QMS", L"QMT", L"QMU", L"QMV", L"QMW", L"QMX", L"QMY", L"QMZ", L"QNA", L"QNB", L"QNC", L"QND", L"QNE", L"QNF", L"QNG", L"QNH", L"QNI", L"QNJ", L"QNK", L"QNL", L"QNM", L"QNN", L"QNO", L"QNP", L"QNQ", L"QNR", L"QNS", L"QNT", L"QNU", L"QNV", L"QNW", L"QNX", L"QNY", L"QNZ", L"QOA", L"QOB", L"QOC", L"QOD", L"QOE", L"QOF", L"QOG", L"QOH", L"QOI", L"QOJ", L"QOK", L"QOL", L"QOM", L"QON", L"QOO", L"QOP", L"QOQ", L"QOR", L"QOS", L"QOT", L"QOU", L"QOV", L"QOW", L"QOX", L"QOY", L"QOZ", L"QPA", L"QPB", L"QPC", L"QPD", L"QPE", L"QPF", L"QPG", L"QPH", L"QPI", L"QPJ", L"QPK", L"QPL", L"QPM", L"QPN", L"QPO", L"QPP", L"QPQ", L"QPR", L"QPS", L"QPT", L"QPU", L"QPV", L"QPW", L"QPX", L"QPY", L"QPZ", L"QQA", L"QQB", L"QQC", L"QQD", L"QQE", L"QQF", L"QQG", L"QQH", L"QQI", L"QQJ", L"QQK", L"QQL", L"QQM", L"QQN", L"QQO", L"QQP", L"QQQ", L"QQR", L"QQS", L"QQT", L"QQU", L"QQV", L"QQW", L"QQX", L"QQY", L"QQZ", L"QRA", L"QRB", L"QRC", L"QRD", L"QRE", L"QRF", L"QRG", L"QRH", L"QRI", L"QRJ", L"QRK", L"QRL", L"QRM", L"QRN", L"QRO", L"QRP", L"QRQ", L"QRR", L"QRS", L"QRT", L"QRU", L"QRV", L"QRW", L"QRX", L"QRY", L"QRZ", L"QSA", L"QSB", L"QSC", L"QSD", L"QSE", L"QSF", L"QSG", L"QSH", L"QSI", L"QSJ", L"QSK", L"QSL", L"QSM", L"QSN", L"QSO", L"QSP", L"QSQ", L"QSR", L"QSS", L"QST", L"QSU", L"QSV", L"QSW", L"QSX", L"QSY", L"QSZ", L"QTA", L"QTB", L"QTC", L"QTD", L"QTE", L"QTF", L"QTG", L"QTH", L"QTI", L"QTJ", L"QTK", L"QTL", L"QTM", L"QTN", L"QTO", L"QTP", L"QTQ", L"QTR", L"QTS", L"QTT", L"QTU", L"QTV", L"QTW", L"QTX", L"QTY", L"QTZ", L"QUA", L"QUB", L"QUC", L"QUD", L"QUE", L"QUF", L"QUG", L"QUH", L"QUI", L"QUJ", L"QUK", L"QUL", L"QUM", L"QUN", L"QUO", L"QUP", L"QUQ", L"QUR", L"QUS", L"QUT", L"QUU", - L"QUV", L"QUW", L"QUX", L"QUY", L"QUZ", L"QVA", L"QVB", L"QVC", L"QVD", L"QVE", L"QVF", L"QVG", L"QVH", L"QVI", L"QVJ", L"QVK", L"QVL", L"QVM", L"QVN", L"QVO", L"QVP", L"QVQ", L"QVR", L"QVS", L"QVT", L"QVU", L"QVV", L"QVW", L"QVX", L"QVY", L"QVZ", L"QWA", L"QWB", L"QWC", L"QWD", L"QWE", L"QWF", L"QWG", L"QWH", L"QWI", L"QWJ", L"QWK", L"QWL", L"QWM", L"QWN", L"QWO", L"QWP", L"QWQ", L"QWR", L"QWS", L"QWT", L"QWU", L"QWV", L"QWW", L"QWX", L"QWY", L"QWZ", L"QXA", L"QXB", L"QXC", L"QXD", L"QXE", L"QXF", L"QXG", L"QXH", L"QXI", L"QXJ", L"QXK", L"QXL", L"QXM", L"QXN", L"QXO", L"QXP", L"QXQ", L"QXR", L"QXS", L"QXT", L"QXU", L"QXV", L"QXW", L"QXX", L"QXY", L"QXZ", L"QYA", L"QYB", L"QYC", L"QYD", L"QYE", L"QYF", L"QYG", L"QYH", L"QYI", L"QYJ", L"QYK", L"QYL", L"QYM", L"QYN", L"QYO", L"QYP", L"QYQ", L"QYR", L"QYS", L"QYT", L"QYU", L"QYV", L"QYW", L"QYX", L"QYY", L"QYZ", L"QZA", L"QZB", L"QZC", L"QZD", L"QZE", L"QZF", L"QZG", L"QZH", L"QZI", L"QZJ", L"QZK", L"QZL", L"QZM", L"QZN", L"QZO", L"QZP", L"QZQ", L"QZR", L"QZS", L"QZT", L"QZU", L"QZV", L"QZW", L"QZX", L"QZY", L"QZZ", L"RAA", L"RAB", L"RAC", L"RAD", L"RAE", L"RAF", L"RAG", L"RAH", L"RAI", L"RAJ", L"RAK", L"RAL", L"RAM", L"RAN", L"RAO", L"RAP", L"RAQ", L"RAR", L"RAS", L"RAT", L"RAU", L"RAV", L"RAW", L"RAX", L"RAY", L"RAZ", L"RBA", L"RBB", L"RBC", L"RBD", L"RBE", L"RBF", L"RBG", L"RBH", L"RBI", L"RBJ", L"RBK", L"RBL", L"RBM", L"RBN", L"RBO", L"RBP", L"RBQ", L"RBR", L"RBS", L"RBT", L"RBU", L"RBV", L"RBW", L"RBX", L"RBY", L"RBZ", L"RCA", L"RCB", L"RCC", L"RCD", L"RCE", L"RCF", L"RCG", L"RCH", L"RCI", L"RCJ", L"RCK", L"RCL", L"RCM", L"RCN", L"RCO", L"RCP", L"RCQ", L"RCR", L"RCS", L"RCT", L"RCU", L"RCV", L"RCW", L"RCX", L"RCY", L"RCZ", L"RDA", L"RDB", L"RDC", L"RDD", L"RDE", L"RDF", L"RDG", L"RDH", L"RDI", L"RDJ", L"RDK", L"RDL", L"RDM", L"RDN", L"RDO", L"RDP", L"RDQ", L"RDR", L"RDS", L"RDT", L"RDU", L"RDV", L"RDW", L"RDX", L"RDY", L"RDZ", L"REA", L"REB", L"REC", L"RED", L"REE", L"REF", L"REG", L"REH", L"REI", L"REJ", L"REK", L"REL", L"REM", L"REN", L"REO", L"REP", L"REQ", L"RER", L"RES", L"RET", L"REU", L"REV", L"REW", L"REX", L"REY", L"REZ", L"RFA", L"RFB", L"RFC", L"RFD", L"RFE", L"RFF", L"RFG", L"RFH", - L"RFI", L"RFJ", L"RFK", L"RFL", L"RFM", L"RFN", L"RFO", L"RFP", L"RFQ", L"RFR", L"RFS", L"RFT", L"RFU", L"RFV", L"RFW", L"RFX", L"RFY", L"RFZ", L"RGA", L"RGB", L"RGC", L"RGD", L"RGE", L"RGF", L"RGG", L"RGH", L"RGI", L"RGJ", L"RGK", L"RGL", L"RGM", L"RGN", L"RGO", L"RGP", L"RGQ", L"RGR", L"RGS", L"RGT", L"RGU", L"RGV", L"RGW", L"RGX", L"RGY", L"RGZ", L"RHA", L"RHB", L"RHC", L"RHD", L"RHE", L"RHF", L"RHG", L"RHH", L"RHI", L"RHJ", L"RHK", L"RHL", L"RHM", L"RHN", L"RHO", L"RHP", L"RHQ", L"RHR", L"RHS", L"RHT", L"RHU", L"RHV", L"RHW", L"RHX", L"RHY", L"RHZ", L"RIA", L"RIB", L"RIC", L"RID", L"RIE", L"RIF", L"RIG", L"RIH", L"RII", L"RIJ", L"RIK", L"RIL", L"RIM", L"RIN", L"RIO", L"RIP", L"RIQ", L"RIR", L"RIS", L"RIT", L"RIU", L"RIV", L"RIW", L"RIX", L"RIY", L"RIZ", L"RJA", L"RJB", L"RJC", L"RJD", L"RJE", L"RJF", L"RJG", L"RJH", L"RJI", L"RJJ", L"RJK", L"RJL", L"RJM", L"RJN", L"RJO", L"RJP", L"RJQ", L"RJR", L"RJS", L"RJT", L"RJU", L"RJV", L"RJW", L"RJX", L"RJY", L"RJZ", L"RKA", L"RKB", L"RKC", L"RKD", L"RKE", L"RKF", L"RKG", L"RKH", L"RKI", L"RKJ", L"RKK", L"RKL", L"RKM", L"RKN", L"RKO", L"RKP", L"RKQ", L"RKR", L"RKS", L"RKT", L"RKU", L"RKV", L"RKW", L"RKX", L"RKY", L"RKZ", L"RLA", L"RLB", L"RLC", L"RLD", L"RLE", L"RLF", L"RLG", L"RLH", L"RLI", L"RLJ", L"RLK", L"RLL", L"RLM", L"RLN", L"RLO", L"RLP", L"RLQ", L"RLR", L"RLS", L"RLT", L"RLU", L"RLV", L"RLW", L"RLX", L"RLY", L"RLZ", L"RMA", L"RMB", L"RMC", L"RMD", L"RME", L"RMF", L"RMG", L"RMH", L"RMI", L"RMJ", L"RMK", L"RML", L"RMM", L"RMN", L"RMO", L"RMP", L"RMQ", L"RMR", L"RMS", L"RMT", L"RMU", L"RMV", L"RMW", L"RMX", L"RMY", L"RMZ", L"RNA", L"RNB", L"RNC", L"RND", L"RNE", L"RNF", L"RNG", L"RNH", L"RNI", L"RNJ", L"RNK", L"RNL", L"RNM", L"RNN", L"RNO", L"RNP", L"RNQ", L"RNR", L"RNS", L"RNT", L"RNU", L"RNV", L"RNW", L"RNX", L"RNY", L"RNZ", L"ROA", L"ROB", L"ROC", L"ROD", L"ROE", L"ROF", L"ROG", L"ROH", L"ROI", L"ROJ", L"ROK", L"ROL", L"ROM", L"RON", L"ROO", L"ROP", L"ROQ", L"ROR", L"ROS", L"ROT", L"ROU", L"ROV", L"ROW", L"ROX", L"ROY", L"ROZ", L"RPA", L"RPB", L"RPC", L"RPD", L"RPE", L"RPF", L"RPG", L"RPH", L"RPI", L"RPJ", L"RPK", L"RPL", L"RPM", L"RPN", L"RPO", L"RPP", L"RPQ", L"RPR", L"RPS", L"RPT", L"RPU", - L"RPV", L"RPW", L"RPX", L"RPY", L"RPZ", L"RQA", L"RQB", L"RQC", L"RQD", L"RQE", L"RQF", L"RQG", L"RQH", L"RQI", L"RQJ", L"RQK", L"RQL", L"RQM", L"RQN", L"RQO", L"RQP", L"RQQ", L"RQR", L"RQS", L"RQT", L"RQU", L"RQV", L"RQW", L"RQX", L"RQY", L"RQZ", L"RRA", L"RRB", L"RRC", L"RRD", L"RRE", L"RRF", L"RRG", L"RRH", L"RRI", L"RRJ", L"RRK", L"RRL", L"RRM", L"RRN", L"RRO", L"RRP", L"RRQ", L"RRR", L"RRS", L"RRT", L"RRU", L"RRV", L"RRW", L"RRX", L"RRY", L"RRZ", L"RSA", L"RSB", L"RSC", L"RSD", L"RSE", L"RSF", L"RSG", L"RSH", L"RSI", L"RSJ", L"RSK", L"RSL", L"RSM", L"RSN", L"RSO", L"RSP", L"RSQ", L"RSR", L"RSS", L"RST", L"RSU", L"RSV", L"RSW", L"RSX", L"RSY", L"RSZ", L"RTA", L"RTB", L"RTC", L"RTD", L"RTE", L"RTF", L"RTG", L"RTH", L"RTI", L"RTJ", L"RTK", L"RTL", L"RTM", L"RTN", L"RTO", L"RTP", L"RTQ", L"RTR", L"RTS", L"RTT", L"RTU", L"RTV", L"RTW", L"RTX", L"RTY", L"RTZ", L"RUA", L"RUB", L"RUC", L"RUD", L"RUE", L"RUF", L"RUG", L"RUH", L"RUI", L"RUJ", L"RUK", L"RUL", L"RUM", L"RUN", L"RUO", L"RUP", L"RUQ", L"RUR", L"RUS", L"RUT", L"RUU", L"RUV", L"RUW", L"RUX", L"RUY", L"RUZ", L"RVA", L"RVB", L"RVC", L"RVD", L"RVE", L"RVF", L"RVG", L"RVH", L"RVI", L"RVJ", L"RVK", L"RVL", L"RVM", L"RVN", L"RVO", L"RVP", L"RVQ", L"RVR", L"RVS", L"RVT", L"RVU", L"RVV", L"RVW", L"RVX", L"RVY", L"RVZ", L"RWA", L"RWB", L"RWC", L"RWD", L"RWE", L"RWF", L"RWG", L"RWH", L"RWI", L"RWJ", L"RWK", L"RWL", L"RWM", L"RWN", L"RWO", L"RWP", L"RWQ", L"RWR", L"RWS", L"RWT", L"RWU", L"RWV", L"RWW", L"RWX", L"RWY", L"RWZ", L"RXA", L"RXB", L"RXC", L"RXD", L"RXE", L"RXF", L"RXG", L"RXH", L"RXI", L"RXJ", L"RXK", L"RXL", L"RXM", L"RXN", L"RXO", L"RXP", L"RXQ", L"RXR", L"RXS", L"RXT", L"RXU", L"RXV", L"RXW", L"RXX", L"RXY", L"RXZ", L"RYA", L"RYB", L"RYC", L"RYD", L"RYE", L"RYF", L"RYG", L"RYH", L"RYI", L"RYJ", L"RYK", L"RYL", L"RYM", L"RYN", L"RYO", L"RYP", L"RYQ", L"RYR", L"RYS", L"RYT", L"RYU", L"RYV", L"RYW", L"RYX", L"RYY", L"RYZ", L"RZA", L"RZB", L"RZC", L"RZD", L"RZE", L"RZF", L"RZG", L"RZH", L"RZI", L"RZJ", L"RZK", L"RZL", L"RZM", L"RZN", L"RZO", L"RZP", L"RZQ", L"RZR", L"RZS", L"RZT", L"RZU", L"RZV", L"RZW", L"RZX", L"RZY", L"RZZ", L"SAA", L"SAB", L"SAC", L"SAD", L"SAE", L"SAF", L"SAG", L"SAH", - L"SAI", L"SAJ", L"SAK", L"SAL", L"SAM", L"SAN", L"SAO", L"SAP", L"SAQ", L"SAR", L"SAS", L"SAT", L"SAU", L"SAV", L"SAW", L"SAX", L"SAY", L"SAZ", L"SBA", L"SBB", L"SBC", L"SBD", L"SBE", L"SBF", L"SBG", L"SBH", L"SBI", L"SBJ", L"SBK", L"SBL", L"SBM", L"SBN", L"SBO", L"SBP", L"SBQ", L"SBR", L"SBS", L"SBT", L"SBU", L"SBV", L"SBW", L"SBX", L"SBY", L"SBZ", L"SCA", L"SCB", L"SCC", L"SCD", L"SCE", L"SCF", L"SCG", L"SCH", L"SCI", L"SCJ", L"SCK", L"SCL", L"SCM", L"SCN", L"SCO", L"SCP", L"SCQ", L"SCR", L"SCS", L"SCT", L"SCU", L"SCV", L"SCW", L"SCX", L"SCY", L"SCZ", L"SDA", L"SDB", L"SDC", L"SDD", L"SDE", L"SDF", L"SDG", L"SDH", L"SDI", L"SDJ", L"SDK", L"SDL", L"SDM", L"SDN", L"SDO", L"SDP", L"SDQ", L"SDR", L"SDS", L"SDT", L"SDU", L"SDV", L"SDW", L"SDX", L"SDY", L"SDZ", L"SEA", L"SEB", L"SEC", L"SED", L"SEE", L"SEF", L"SEG", L"SEH", L"SEI", L"SEJ", L"SEK", L"SEL", L"SEM", L"SEN", L"SEO", L"SEP", L"SEQ", L"SER", L"SES", L"SET", L"SEU", L"SEV", L"SEW", L"SEX", L"SEY", L"SEZ", L"SFA", L"SFB", L"SFC", L"SFD", L"SFE", L"SFF", L"SFG", L"SFH", L"SFI", L"SFJ", L"SFK", L"SFL", L"SFM", L"SFN", L"SFO", L"SFP", L"SFQ", L"SFR", L"SFS", L"SFT", L"SFU", L"SFV", L"SFW", L"SFX", L"SFY", L"SFZ", L"SGA", L"SGB", L"SGC", L"SGD", L"SGE", L"SGF", L"SGG", L"SGH", L"SGI", L"SGJ", L"SGK", L"SGL", L"SGM", L"SGN", L"SGO", L"SGP", L"SGQ", L"SGR", L"SGS", L"SGT", L"SGU", L"SGV", L"SGW", L"SGX", L"SGY", L"SGZ", L"SHA", L"SHB", L"SHC", L"SHD", L"SHE", L"SHF", L"SHG", L"SHH", L"SHI", L"SHJ", L"SHK", L"SHL", L"SHM", L"SHN", L"SHO", L"SHP", L"SHQ", L"SHR", L"SHS", L"SHT", L"SHU", L"SHV", L"SHW", L"SHX", L"SHY", L"SHZ", L"SIA", L"SIB", L"SIC", L"SID", L"SIE", L"SIF", L"SIG", L"SIH", L"SII", L"SIJ", L"SIK", L"SIL", L"SIM", L"SIN", L"SIO", L"SIP", L"SIQ", L"SIR", L"SIS", L"SIT", L"SIU", L"SIV", L"SIW", L"SIX", L"SIY", L"SIZ", L"SJA", L"SJB", L"SJC", L"SJD", L"SJE", L"SJF", L"SJG", L"SJH", L"SJI", L"SJJ", L"SJK", L"SJL", L"SJM", L"SJN", L"SJO", L"SJP", L"SJQ", L"SJR", L"SJS", L"SJT", L"SJU", L"SJV", L"SJW", L"SJX", L"SJY", L"SJZ", L"SKA", L"SKB", L"SKC", L"SKD", L"SKE", L"SKF", L"SKG", L"SKH", L"SKI", L"SKJ", L"SKK", L"SKL", L"SKM", L"SKN", L"SKO", L"SKP", L"SKQ", L"SKR", L"SKS", L"SKT", L"SKU", - L"SKV", L"SKW", L"SKX", L"SKY", L"SKZ", L"SLA", L"SLB", L"SLC", L"SLD", L"SLE", L"SLF", L"SLG", L"SLH", L"SLI", L"SLJ", L"SLK", L"SLL", L"SLM", L"SLN", L"SLO", L"SLP", L"SLQ", L"SLR", L"SLS", L"SLT", L"SLU", L"SLV", L"SLW", L"SLX", L"SLY", L"SLZ", L"SMA", L"SMB", L"SMC", L"SMD", L"SME", L"SMF", L"SMG", L"SMH", L"SMI", L"SMJ", L"SMK", L"SML", L"SMM", L"SMN", L"SMO", L"SMP", L"SMQ", L"SMR", L"SMS", L"SMT", L"SMU", L"SMV", L"SMW", L"SMX", L"SMY", L"SMZ", L"SNA", L"SNB", L"SNC", L"SND", L"SNE", L"SNF", L"SNG", L"SNH", L"SNI", L"SNJ", L"SNK", L"SNL", L"SNM", L"SNN", L"SNO", L"SNP", L"SNQ", L"SNR", L"SNS", L"SNT", L"SNU", L"SNV", L"SNW", L"SNX", L"SNY", L"SNZ", L"SOA", L"SOB", L"SOC", L"SOD", L"SOE", L"SOF", L"SOG", L"SOH", L"SOI", L"SOJ", L"SOK", L"SOL", L"SOM", L"SON", L"SOO", L"SOP", L"SOQ", L"SOR", L"SOS", L"SOT", L"SOU", L"SOV", L"SOW", L"SOX", L"SOY", L"SOZ", L"SPA", L"SPB", L"SPC", L"SPD", L"SPE", L"SPF", L"SPG", L"SPH", L"SPI", L"SPJ", L"SPK", L"SPL", L"SPM", L"SPN", L"SPO", L"SPP", L"SPQ", L"SPR", L"SPS", L"SPT", L"SPU", L"SPV", L"SPW", L"SPX", L"SPY", L"SPZ", L"SQA", L"SQB", L"SQC", L"SQD", L"SQE", L"SQF", L"SQG", L"SQH", L"SQI", L"SQJ", L"SQK", L"SQL", L"SQM", L"SQN", L"SQO", L"SQP", L"SQQ", L"SQR", L"SQS", L"SQT", L"SQU", L"SQV", L"SQW", L"SQX", L"SQY", L"SQZ", L"SRA", L"SRB", L"SRC", L"SRD", L"SRE", L"SRF", L"SRG", L"SRH", L"SRI", L"SRJ", L"SRK", L"SRL", L"SRM", L"SRN", L"SRO", L"SRP", L"SRQ", L"SRR", L"SRS", L"SRT", L"SRU", L"SRV", L"SRW", L"SRX", L"SRY", L"SRZ", L"SSA", L"SSB", L"SSC", L"SSD", L"SSE", L"SSF", L"SSG", L"SSH", L"SSI", L"SSJ", L"SSK", L"SSL", L"SSM", L"SSN", L"SSO", L"SSP", L"SSQ", L"SSR", L"SSS", L"SST", L"SSU", L"SSV", L"SSW", L"SSX", L"SSY", L"SSZ", L"STA", L"STB", L"STC", L"STD", L"STE", L"STF", L"STG", L"STH", L"STI", L"STJ", L"STK", L"STL", L"STM", L"STN", L"STO", L"STP", L"STQ", L"STR", L"STS", L"STT", L"STU", L"STV", L"STW", L"STX", L"STY", L"STZ", L"SUA", L"SUB", L"SUC", L"SUD", L"SUE", L"SUF", L"SUG", L"SUH", L"SUI", L"SUJ", L"SUK", L"SUL", L"SUM", L"SUN", L"SUO", L"SUP", L"SUQ", L"SUR", L"SUS", L"SUT", L"SUU", L"SUV", L"SUW", L"SUX", L"SUY", - L"SUZ", L"SVA", L"SVB", L"SVC", L"SVD", L"SVE", L"SVF", L"SVG", L"SVH", L"SVI", L"SVJ", L"SVK", L"SVL", L"SVM", L"SVN", L"SVO", L"SVP", L"SVQ", L"SVR", L"SVS", L"SVT", L"SVU", L"SVV", L"SVW", L"SVX", L"SVY", L"SVZ", L"SWA", L"SWB", L"SWC", L"SWD", L"SWE", L"SWF", L"SWG", L"SWH", L"SWI", L"SWJ", L"SWK", L"SWL", L"SWM", L"SWN", L"SWO", L"SWP", L"SWQ", L"SWR", L"SWS", L"SWT", L"SWU", L"SWV", L"SWW", L"SWX", L"SWY", L"SWZ", L"SXA", L"SXB", L"SXC", L"SXD", L"SXE", L"SXF", L"SXG", L"SXH", L"SXI", L"SXJ", L"SXK", L"SXL", L"SXM", L"SXN", L"SXO", L"SXP", L"SXQ", L"SXR", L"SXS", L"SXT", L"SXU", L"SXV", L"SXW", L"SXX", L"SXY", L"SXZ", L"SYA", L"SYB", L"SYC", L"SYD", L"SYE", L"SYF", L"SYG", L"SYH", L"SYI", L"SYJ", L"SYK", L"SYL", L"SYM", L"SYN", L"SYO", L"SYP", L"SYQ", L"SYR", L"SYS", L"SYT", L"SYU", L"SYV", L"SYW", L"SYX", L"SYY", L"SYZ", L"SZA", L"SZB", L"SZC", L"SZD", L"SZE", L"SZF", L"SZG", L"SZH", L"SZI", L"SZJ", L"SZK", L"SZL", L"SZM", L"SZN", L"SZO", L"SZP", L"SZQ", L"SZR", L"SZS", L"SZT", L"SZU", L"SZV", L"SZW", L"SZX", L"SZY", L"SZZ", L"TAA", L"TAB", L"TAC", L"TAD", L"TAE", L"TAF", L"TAG", L"TAH", L"TAI", L"TAJ", L"TAK", L"TAL", L"TAM", L"TAN", L"TAO", L"TAP", L"TAQ", L"TAR", L"TAS", L"TAT", L"TAU", L"TAV", L"TAW", L"TAX", L"TAY", L"TAZ", L"TBA", L"TBB", L"TBC", L"TBD", L"TBE", L"TBF", L"TBG", L"TBH", L"TBI", L"TBJ", L"TBK", L"TBL", L"TBM", L"TBN", L"TBO", L"TBP", L"TBQ", L"TBR", L"TBS", L"TBT", L"TBU", L"TBV", L"TBW", L"TBX", L"TBY", L"TBZ", L"TCA", L"TCB", L"TCC", L"TCD", L"TCE", L"TCF", L"TCG", L"TCH", L"TCI", L"TCJ", L"TCK", L"TCL", L"TCM", L"TCN", L"TCO", L"TCP", L"TCQ", L"TCR", L"TCS", L"TCT", L"TCU", L"TCV", L"TCW", L"TCX", L"TCY", L"TCZ", L"TDA", L"TDB", L"TDC", L"TDD", L"TDE", L"TDF", L"TDG", L"TDH", L"TDI", L"TDJ", L"TDK", L"TDL", L"TDM", L"TDN", L"TDO", L"TDP", L"TDQ", L"TDR", L"TDS", L"TDT", L"TDU", L"TDV", L"TDW", L"TDX", L"TDY", L"TDZ", L"TEA", L"TEB", L"TEC", L"TED", L"TEE", L"TEF", L"TEG", L"TEH", L"TEI", L"TEJ", L"TEK", L"TEL", L"TEM", L"TEN", L"TEO", L"TEP", L"TEQ", L"TER", L"TES", L"TET", L"TEU", L"TEV", L"TEW", L"TEX", L"TEY", L"TEZ", L"TFA", L"TFB", L"TFC", L"TFD", L"TFE", L"TFF", L"TFG", L"TFH", L"TFI", L"TFJ", L"TFK", L"TFL", + L"QKI", L"QKJ", L"QKK", L"QKL", L"QKM", L"QKN", L"QKO", L"QKP", L"QKQ", L"QKR", L"QKS", L"QKT", L"QKU", L"QKV", L"QKW", L"QKX", L"QKY", L"QKZ", L"QLA", L"QLB", L"QLC", L"QLD", L"QLE", L"QLF", L"QLG", L"QLH", L"QLI", L"QLJ", L"QLK", L"QLL", L"QLM", L"QLN", L"QLO", L"QLP", L"QLQ", L"QLR", L"QLS", L"QLT", L"QLU", L"QLV", L"QLW", L"QLX", L"QLY", L"QLZ", L"QMA", L"QMB", L"QMC", L"QMD", L"QME", L"QMF", L"QMG", L"QMH", L"QMI", L"QMJ", L"QMK", L"QML", L"QMM", L"QMN", L"QMO", L"QMP", L"QMQ", L"QMR", L"QMS", L"QMT", L"QMU", L"QMV", L"QMW", L"QMX", L"QMY", L"QMZ", L"QNA", L"QNB", L"QNC", L"QND", L"QNE", L"QNF", L"QNG", L"QNH", L"QNI", L"QNJ", L"QNK", L"QNL", L"QNM", L"QNN", L"QNO", L"QNP", L"QNQ", L"QNR", L"QNS", L"QNT", L"QNU", L"QNV", L"QNW", L"QNX", L"QNY", L"QNZ", L"QOA", L"QOB", L"QOC", L"QOD", L"QOE", L"QOF", L"QOG", L"QOH", L"QOI", L"QOJ", L"QOK", L"QOL", L"QOM", L"QON", L"QOO", L"QOP", L"QOQ", L"QOR", L"QOS", L"QOT", L"QOU", L"QOV", L"QOW", L"QOX", L"QOY", L"QOZ", L"QPA", L"QPB", L"QPC", L"QPD", L"QPE", L"QPF", L"QPG", L"QPH", L"QPI", L"QPJ", L"QPK", L"QPL", L"QPM", L"QPN", L"QPO", L"QPP", L"QPQ", L"QPR", L"QPS", L"QPT", L"QPU", L"QPV", L"QPW", L"QPX", L"QPY", L"QPZ", L"QQA", L"QQB", L"QQC", L"QQD", L"QQE", L"QQF", L"QQG", L"QQH", L"QQI", L"QQJ", L"QQK", L"QQL", L"QQM", L"QQN", L"QQO", L"QQP", L"QQQ", L"QQR", L"QQS", L"QQT", L"QQU", L"QQV", L"QQW", L"QQX", L"QQY", L"QQZ", L"QRA", L"QRB", L"QRC", L"QRD", L"QRE", L"QRF", L"QRG", L"QRH", L"QRI", L"QRJ", L"QRK", L"QRL", L"QRM", L"QRN", L"QRO", L"QRP", L"QRQ", L"QRR", L"QRS", L"QRT", L"QRU", L"QRV", L"QRW", L"QRX", L"QRY", L"QRZ", L"QSA", L"QSB", L"QSC", L"QSD", L"QSE", L"QSF", L"QSG", L"QSH", L"QSI", L"QSJ", L"QSK", L"QSL", L"QSM", L"QSN", L"QSO", L"QSP", L"QSQ", L"QSR", L"QSS", L"QST", L"QSU", L"QSV", L"QSW", L"QSX", L"QSY", L"QSZ", L"QTA", L"QTB", L"QTC", L"QTD", L"QTE", L"QTF", L"QTG", L"QTH", L"QTI", L"QTJ", L"QTK", L"QTL", L"QTM", L"QTN", L"QTO", L"QTP", L"QTQ", L"QTR", L"QTS", L"QTT", L"QTU", L"QTV", L"QTW", L"QTX", L"QTY", L"QTZ", L"QUA", L"QUB", L"QUC", L"QUD", L"QUE", L"QUF", L"QUG", L"QUH", L"QUI", L"QUJ", L"QUK", L"QUL", L"QUM", L"QUN", L"QUO", L"QUP", L"QUQ", L"QUR", L"QUS", L"QUT", L"QUU", + L"QUV", L"QUW", L"QUX", L"QUY", L"QUZ", L"QVA", L"QVB", L"QVC", L"QVD", L"QVE", L"QVF", L"QVG", L"QVH", L"QVI", L"QVJ", L"QVK", L"QVL", L"QVM", L"QVN", L"QVO", L"QVP", L"QVQ", L"QVR", L"QVS", L"QVT", L"QVU", L"QVV", L"QVW", L"QVX", L"QVY", L"QVZ", L"QWA", L"QWB", L"QWC", L"QWD", L"QWE", L"QWF", L"QWG", L"QWH", L"QWI", L"QWJ", L"QWK", L"QWL", L"QWM", L"QWN", L"QWO", L"QWP", L"QWQ", L"QWR", L"QWS", L"QWT", L"QWU", L"QWV", L"QWW", L"QWX", L"QWY", L"QWZ", L"QXA", L"QXB", L"QXC", L"QXD", L"QXE", L"QXF", L"QXG", L"QXH", L"QXI", L"QXJ", L"QXK", L"QXL", L"QXM", L"QXN", L"QXO", L"QXP", L"QXQ", L"QXR", L"QXS", L"QXT", L"QXU", L"QXV", L"QXW", L"QXX", L"QXY", L"QXZ", L"QYA", L"QYB", L"QYC", L"QYD", L"QYE", L"QYF", L"QYG", L"QYH", L"QYI", L"QYJ", L"QYK", L"QYL", L"QYM", L"QYN", L"QYO", L"QYP", L"QYQ", L"QYR", L"QYS", L"QYT", L"QYU", L"QYV", L"QYW", L"QYX", L"QYY", L"QYZ", L"QZA", L"QZB", L"QZC", L"QZD", L"QZE", L"QZF", L"QZG", L"QZH", L"QZI", L"QZJ", L"QZK", L"QZL", L"QZM", L"QZN", L"QZO", L"QZP", L"QZQ", L"QZR", L"QZS", L"QZT", L"QZU", L"QZV", L"QZW", L"QZX", L"QZY", L"QZZ", L"RAA", L"RAB", L"RAC", L"RAD", L"RAE", L"RAF", L"RAG", L"RAH", L"RAI", L"RAJ", L"RAK", L"RAL", L"RAM", L"RAN", L"RAO", L"RAP", L"RAQ", L"RAR", L"RAS", L"RAT", L"RAU", L"RAV", L"RAW", L"RAX", L"RAY", L"RAZ", L"RBA", L"RBB", L"RBC", L"RBD", L"RBE", L"RBF", L"RBG", L"RBH", L"RBI", L"RBJ", L"RBK", L"RBL", L"RBM", L"RBN", L"RBO", L"RBP", L"RBQ", L"RBR", L"RBS", L"RBT", L"RBU", L"RBV", L"RBW", L"RBX", L"RBY", L"RBZ", L"RCA", L"RCB", L"RCC", L"RCD", L"RCE", L"RCF", L"RCG", L"RCH", L"RCI", L"RCJ", L"RCK", L"RCL", L"RCM", L"RCN", L"RCO", L"RCP", L"RCQ", L"RCR", L"RCS", L"RCT", L"RCU", L"RCV", L"RCW", L"RCX", L"RCY", L"RCZ", L"RDA", L"RDB", L"RDC", L"RDD", L"RDE", L"RDF", L"RDG", L"RDH", L"RDI", L"RDJ", L"RDK", L"RDL", L"RDM", L"RDN", L"RDO", L"RDP", L"RDQ", L"RDR", L"RDS", L"RDT", L"RDU", L"RDV", L"RDW", L"RDX", L"RDY", L"RDZ", L"REA", L"REB", L"REC", L"RED", L"REE", L"REF", L"REG", L"REH", L"REI", L"REJ", L"REK", L"REL", L"REM", L"REN", L"REO", L"REP", L"REQ", L"RER", L"RES", L"RET", L"REU", L"REV", L"REW", L"REX", L"REY", L"REZ", L"RFA", L"RFB", L"RFC", L"RFD", L"RFE", L"RFF", L"RFG", L"RFH", + L"RFI", L"RFJ", L"RFK", L"RFL", L"RFM", L"RFN", L"RFO", L"RFP", L"RFQ", L"RFR", L"RFS", L"RFT", L"RFU", L"RFV", L"RFW", L"RFX", L"RFY", L"RFZ", L"RGA", L"RGB", L"RGC", L"RGD", L"RGE", L"RGF", L"RGG", L"RGH", L"RGI", L"RGJ", L"RGK", L"RGL", L"RGM", L"RGN", L"RGO", L"RGP", L"RGQ", L"RGR", L"RGS", L"RGT", L"RGU", L"RGV", L"RGW", L"RGX", L"RGY", L"RGZ", L"RHA", L"RHB", L"RHC", L"RHD", L"RHE", L"RHF", L"RHG", L"RHH", L"RHI", L"RHJ", L"RHK", L"RHL", L"RHM", L"RHN", L"RHO", L"RHP", L"RHQ", L"RHR", L"RHS", L"RHT", L"RHU", L"RHV", L"RHW", L"RHX", L"RHY", L"RHZ", L"RIA", L"RIB", L"RIC", L"RID", L"RIE", L"RIF", L"RIG", L"RIH", L"RII", L"RIJ", L"RIK", L"RIL", L"RIM", L"RIN", L"RIO", L"RIP", L"RIQ", L"RIR", L"RIS", L"RIT", L"RIU", L"RIV", L"RIW", L"RIX", L"RIY", L"RIZ", L"RJA", L"RJB", L"RJC", L"RJD", L"RJE", L"RJF", L"RJG", L"RJH", L"RJI", L"RJJ", L"RJK", L"RJL", L"RJM", L"RJN", L"RJO", L"RJP", L"RJQ", L"RJR", L"RJS", L"RJT", L"RJU", L"RJV", L"RJW", L"RJX", L"RJY", L"RJZ", L"RKA", L"RKB", L"RKC", L"RKD", L"RKE", L"RKF", L"RKG", L"RKH", L"RKI", L"RKJ", L"RKK", L"RKL", L"RKM", L"RKN", L"RKO", L"RKP", L"RKQ", L"RKR", L"RKS", L"RKT", L"RKU", L"RKV", L"RKW", L"RKX", L"RKY", L"RKZ", L"RLA", L"RLB", L"RLC", L"RLD", L"RLE", L"RLF", L"RLG", L"RLH", L"RLI", L"RLJ", L"RLK", L"RLL", L"RLM", L"RLN", L"RLO", L"RLP", L"RLQ", L"RLR", L"RLS", L"RLT", L"RLU", L"RLV", L"RLW", L"RLX", L"RLY", L"RLZ", L"RMA", L"RMB", L"RMC", L"RMD", L"RME", L"RMF", L"RMG", L"RMH", L"RMI", L"RMJ", L"RMK", L"RML", L"RMM", L"RMN", L"RMO", L"RMP", L"RMQ", L"RMR", L"RMS", L"RMT", L"RMU", L"RMV", L"RMW", L"RMX", L"RMY", L"RMZ", L"RNA", L"RNB", L"RNC", L"RND", L"RNE", L"RNF", L"RNG", L"RNH", L"RNI", L"RNJ", L"RNK", L"RNL", L"RNM", L"RNN", L"RNO", L"RNP", L"RNQ", L"RNR", L"RNS", L"RNT", L"RNU", L"RNV", L"RNW", L"RNX", L"RNY", L"RNZ", L"ROA", L"ROB", L"ROC", L"ROD", L"ROE", L"ROF", L"ROG", L"ROH", L"ROI", L"ROJ", L"ROK", L"ROL", L"ROM", L"RON", L"ROO", L"ROP", L"ROQ", L"ROR", L"ROS", L"ROT", L"ROU", L"ROV", L"ROW", L"ROX", L"ROY", L"ROZ", L"RPA", L"RPB", L"RPC", L"RPD", L"RPE", L"RPF", L"RPG", L"RPH", L"RPI", L"RPJ", L"RPK", L"RPL", L"RPM", L"RPN", L"RPO", L"RPP", L"RPQ", L"RPR", L"RPS", L"RPT", L"RPU", + L"RPV", L"RPW", L"RPX", L"RPY", L"RPZ", L"RQA", L"RQB", L"RQC", L"RQD", L"RQE", L"RQF", L"RQG", L"RQH", L"RQI", L"RQJ", L"RQK", L"RQL", L"RQM", L"RQN", L"RQO", L"RQP", L"RQQ", L"RQR", L"RQS", L"RQT", L"RQU", L"RQV", L"RQW", L"RQX", L"RQY", L"RQZ", L"RRA", L"RRB", L"RRC", L"RRD", L"RRE", L"RRF", L"RRG", L"RRH", L"RRI", L"RRJ", L"RRK", L"RRL", L"RRM", L"RRN", L"RRO", L"RRP", L"RRQ", L"RRR", L"RRS", L"RRT", L"RRU", L"RRV", L"RRW", L"RRX", L"RRY", L"RRZ", L"RSA", L"RSB", L"RSC", L"RSD", L"RSE", L"RSF", L"RSG", L"RSH", L"RSI", L"RSJ", L"RSK", L"RSL", L"RSM", L"RSN", L"RSO", L"RSP", L"RSQ", L"RSR", L"RSS", L"RST", L"RSU", L"RSV", L"RSW", L"RSX", L"RSY", L"RSZ", L"RTA", L"RTB", L"RTC", L"RTD", L"RTE", L"RTF", L"RTG", L"RTH", L"RTI", L"RTJ", L"RTK", L"RTL", L"RTM", L"RTN", L"RTO", L"RTP", L"RTQ", L"RTR", L"RTS", L"RTT", L"RTU", L"RTV", L"RTW", L"RTX", L"RTY", L"RTZ", L"RUA", L"RUB", L"RUC", L"RUD", L"RUE", L"RUF", L"RUG", L"RUH", L"RUI", L"RUJ", L"RUK", L"RUL", L"RUM", L"RUN", L"RUO", L"RUP", L"RUQ", L"RUR", L"RUS", L"RUT", L"RUU", L"RUV", L"RUW", L"RUX", L"RUY", L"RUZ", L"RVA", L"RVB", L"RVC", L"RVD", L"RVE", L"RVF", L"RVG", L"RVH", L"RVI", L"RVJ", L"RVK", L"RVL", L"RVM", L"RVN", L"RVO", L"RVP", L"RVQ", L"RVR", L"RVS", L"RVT", L"RVU", L"RVV", L"RVW", L"RVX", L"RVY", L"RVZ", L"RWA", L"RWB", L"RWC", L"RWD", L"RWE", L"RWF", L"RWG", L"RWH", L"RWI", L"RWJ", L"RWK", L"RWL", L"RWM", L"RWN", L"RWO", L"RWP", L"RWQ", L"RWR", L"RWS", L"RWT", L"RWU", L"RWV", L"RWW", L"RWX", L"RWY", L"RWZ", L"RXA", L"RXB", L"RXC", L"RXD", L"RXE", L"RXF", L"RXG", L"RXH", L"RXI", L"RXJ", L"RXK", L"RXL", L"RXM", L"RXN", L"RXO", L"RXP", L"RXQ", L"RXR", L"RXS", L"RXT", L"RXU", L"RXV", L"RXW", L"RXX", L"RXY", L"RXZ", L"RYA", L"RYB", L"RYC", L"RYD", L"RYE", L"RYF", L"RYG", L"RYH", L"RYI", L"RYJ", L"RYK", L"RYL", L"RYM", L"RYN", L"RYO", L"RYP", L"RYQ", L"RYR", L"RYS", L"RYT", L"RYU", L"RYV", L"RYW", L"RYX", L"RYY", L"RYZ", L"RZA", L"RZB", L"RZC", L"RZD", L"RZE", L"RZF", L"RZG", L"RZH", L"RZI", L"RZJ", L"RZK", L"RZL", L"RZM", L"RZN", L"RZO", L"RZP", L"RZQ", L"RZR", L"RZS", L"RZT", L"RZU", L"RZV", L"RZW", L"RZX", L"RZY", L"RZZ", L"SAA", L"SAB", L"SAC", L"SAD", L"SAE", L"SAF", L"SAG", L"SAH", + L"SAI", L"SAJ", L"SAK", L"SAL", L"SAM", L"SAN", L"SAO", L"SAP", L"SAQ", L"SAR", L"SAS", L"SAT", L"SAU", L"SAV", L"SAW", L"SAX", L"SAY", L"SAZ", L"SBA", L"SBB", L"SBC", L"SBD", L"SBE", L"SBF", L"SBG", L"SBH", L"SBI", L"SBJ", L"SBK", L"SBL", L"SBM", L"SBN", L"SBO", L"SBP", L"SBQ", L"SBR", L"SBS", L"SBT", L"SBU", L"SBV", L"SBW", L"SBX", L"SBY", L"SBZ", L"SCA", L"SCB", L"SCC", L"SCD", L"SCE", L"SCF", L"SCG", L"SCH", L"SCI", L"SCJ", L"SCK", L"SCL", L"SCM", L"SCN", L"SCO", L"SCP", L"SCQ", L"SCR", L"SCS", L"SCT", L"SCU", L"SCV", L"SCW", L"SCX", L"SCY", L"SCZ", L"SDA", L"SDB", L"SDC", L"SDD", L"SDE", L"SDF", L"SDG", L"SDH", L"SDI", L"SDJ", L"SDK", L"SDL", L"SDM", L"SDN", L"SDO", L"SDP", L"SDQ", L"SDR", L"SDS", L"SDT", L"SDU", L"SDV", L"SDW", L"SDX", L"SDY", L"SDZ", L"SEA", L"SEB", L"SEC", L"SED", L"SEE", L"SEF", L"SEG", L"SEH", L"SEI", L"SEJ", L"SEK", L"SEL", L"SEM", L"SEN", L"SEO", L"SEP", L"SEQ", L"SER", L"SES", L"SET", L"SEU", L"SEV", L"SEW", L"SEX", L"SEY", L"SEZ", L"SFA", L"SFB", L"SFC", L"SFD", L"SFE", L"SFF", L"SFG", L"SFH", L"SFI", L"SFJ", L"SFK", L"SFL", L"SFM", L"SFN", L"SFO", L"SFP", L"SFQ", L"SFR", L"SFS", L"SFT", L"SFU", L"SFV", L"SFW", L"SFX", L"SFY", L"SFZ", L"SGA", L"SGB", L"SGC", L"SGD", L"SGE", L"SGF", L"SGG", L"SGH", L"SGI", L"SGJ", L"SGK", L"SGL", L"SGM", L"SGN", L"SGO", L"SGP", L"SGQ", L"SGR", L"SGS", L"SGT", L"SGU", L"SGV", L"SGW", L"SGX", L"SGY", L"SGZ", L"SHA", L"SHB", L"SHC", L"SHD", L"SHE", L"SHF", L"SHG", L"SHH", L"SHI", L"SHJ", L"SHK", L"SHL", L"SHM", L"SHN", L"SHO", L"SHP", L"SHQ", L"SHR", L"SHS", L"SHT", L"SHU", L"SHV", L"SHW", L"SHX", L"SHY", L"SHZ", L"SIA", L"SIB", L"SIC", L"SID", L"SIE", L"SIF", L"SIG", L"SIH", L"SII", L"SIJ", L"SIK", L"SIL", L"SIM", L"SIN", L"SIO", L"SIP", L"SIQ", L"SIR", L"SIS", L"SIT", L"SIU", L"SIV", L"SIW", L"SIX", L"SIY", L"SIZ", L"SJA", L"SJB", L"SJC", L"SJD", L"SJE", L"SJF", L"SJG", L"SJH", L"SJI", L"SJJ", L"SJK", L"SJL", L"SJM", L"SJN", L"SJO", L"SJP", L"SJQ", L"SJR", L"SJS", L"SJT", L"SJU", L"SJV", L"SJW", L"SJX", L"SJY", L"SJZ", L"SKA", L"SKB", L"SKC", L"SKD", L"SKE", L"SKF", L"SKG", L"SKH", L"SKI", L"SKJ", L"SKK", L"SKL", L"SKM", L"SKN", L"SKO", L"SKP", L"SKQ", L"SKR", L"SKS", L"SKT", L"SKU", + L"SKV", L"SKW", L"SKX", L"SKY", L"SKZ", L"SLA", L"SLB", L"SLC", L"SLD", L"SLE", L"SLF", L"SLG", L"SLH", L"SLI", L"SLJ", L"SLK", L"SLL", L"SLM", L"SLN", L"SLO", L"SLP", L"SLQ", L"SLR", L"SLS", L"SLT", L"SLU", L"SLV", L"SLW", L"SLX", L"SLY", L"SLZ", L"SMA", L"SMB", L"SMC", L"SMD", L"SME", L"SMF", L"SMG", L"SMH", L"SMI", L"SMJ", L"SMK", L"SML", L"SMM", L"SMN", L"SMO", L"SMP", L"SMQ", L"SMR", L"SMS", L"SMT", L"SMU", L"SMV", L"SMW", L"SMX", L"SMY", L"SMZ", L"SNA", L"SNB", L"SNC", L"SND", L"SNE", L"SNF", L"SNG", L"SNH", L"SNI", L"SNJ", L"SNK", L"SNL", L"SNM", L"SNN", L"SNO", L"SNP", L"SNQ", L"SNR", L"SNS", L"SNT", L"SNU", L"SNV", L"SNW", L"SNX", L"SNY", L"SNZ", L"SOA", L"SOB", L"SOC", L"SOD", L"SOE", L"SOF", L"SOG", L"SOH", L"SOI", L"SOJ", L"SOK", L"SOL", L"SOM", L"SON", L"SOO", L"SOP", L"SOQ", L"SOR", L"SOS", L"SOT", L"SOU", L"SOV", L"SOW", L"SOX", L"SOY", L"SOZ", L"SPA", L"SPB", L"SPC", L"SPD", L"SPE", L"SPF", L"SPG", L"SPH", L"SPI", L"SPJ", L"SPK", L"SPL", L"SPM", L"SPN", L"SPO", L"SPP", L"SPQ", L"SPR", L"SPS", L"SPT", L"SPU", L"SPV", L"SPW", L"SPX", L"SPY", L"SPZ", L"SQA", L"SQB", L"SQC", L"SQD", L"SQE", L"SQF", L"SQG", L"SQH", L"SQI", L"SQJ", L"SQK", L"SQL", L"SQM", L"SQN", L"SQO", L"SQP", L"SQQ", L"SQR", L"SQS", L"SQT", L"SQU", L"SQV", L"SQW", L"SQX", L"SQY", L"SQZ", L"SRA", L"SRB", L"SRC", L"SRD", L"SRE", L"SRF", L"SRG", L"SRH", L"SRI", L"SRJ", L"SRK", L"SRL", L"SRM", L"SRN", L"SRO", L"SRP", L"SRQ", L"SRR", L"SRS", L"SRT", L"SRU", L"SRV", L"SRW", L"SRX", L"SRY", L"SRZ", L"SSA", L"SSB", L"SSC", L"SSD", L"SSE", L"SSF", L"SSG", L"SSH", L"SSI", L"SSJ", L"SSK", L"SSL", L"SSM", L"SSN", L"SSO", L"SSP", L"SSQ", L"SSR", L"SSS", L"SST", L"SSU", L"SSV", L"SSW", L"SSX", L"SSY", L"SSZ", L"STA", L"STB", L"STC", L"STD", L"STE", L"STF", L"STG", L"STH", L"STI", L"STJ", L"STK", L"STL", L"STM", L"STN", L"STO", L"STP", L"STQ", L"STR", L"STS", L"STT", L"STU", L"STV", L"STW", L"STX", L"STY", L"STZ", L"SUA", L"SUB", L"SUC", L"SUD", L"SUE", L"SUF", L"SUG", L"SUH", L"SUI", L"SUJ", L"SUK", L"SUL", L"SUM", L"SUN", L"SUO", L"SUP", L"SUQ", L"SUR", L"SUS", L"SUT", L"SUU", L"SUV", L"SUW", L"SUX", L"SUY", + L"SUZ", L"SVA", L"SVB", L"SVC", L"SVD", L"SVE", L"SVF", L"SVG", L"SVH", L"SVI", L"SVJ", L"SVK", L"SVL", L"SVM", L"SVN", L"SVO", L"SVP", L"SVQ", L"SVR", L"SVS", L"SVT", L"SVU", L"SVV", L"SVW", L"SVX", L"SVY", L"SVZ", L"SWA", L"SWB", L"SWC", L"SWD", L"SWE", L"SWF", L"SWG", L"SWH", L"SWI", L"SWJ", L"SWK", L"SWL", L"SWM", L"SWN", L"SWO", L"SWP", L"SWQ", L"SWR", L"SWS", L"SWT", L"SWU", L"SWV", L"SWW", L"SWX", L"SWY", L"SWZ", L"SXA", L"SXB", L"SXC", L"SXD", L"SXE", L"SXF", L"SXG", L"SXH", L"SXI", L"SXJ", L"SXK", L"SXL", L"SXM", L"SXN", L"SXO", L"SXP", L"SXQ", L"SXR", L"SXS", L"SXT", L"SXU", L"SXV", L"SXW", L"SXX", L"SXY", L"SXZ", L"SYA", L"SYB", L"SYC", L"SYD", L"SYE", L"SYF", L"SYG", L"SYH", L"SYI", L"SYJ", L"SYK", L"SYL", L"SYM", L"SYN", L"SYO", L"SYP", L"SYQ", L"SYR", L"SYS", L"SYT", L"SYU", L"SYV", L"SYW", L"SYX", L"SYY", L"SYZ", L"SZA", L"SZB", L"SZC", L"SZD", L"SZE", L"SZF", L"SZG", L"SZH", L"SZI", L"SZJ", L"SZK", L"SZL", L"SZM", L"SZN", L"SZO", L"SZP", L"SZQ", L"SZR", L"SZS", L"SZT", L"SZU", L"SZV", L"SZW", L"SZX", L"SZY", L"SZZ", L"TAA", L"TAB", L"TAC", L"TAD", L"TAE", L"TAF", L"TAG", L"TAH", L"TAI", L"TAJ", L"TAK", L"TAL", L"TAM", L"TAN", L"TAO", L"TAP", L"TAQ", L"TAR", L"TAS", L"TAT", L"TAU", L"TAV", L"TAW", L"TAX", L"TAY", L"TAZ", L"TBA", L"TBB", L"TBC", L"TBD", L"TBE", L"TBF", L"TBG", L"TBH", L"TBI", L"TBJ", L"TBK", L"TBL", L"TBM", L"TBN", L"TBO", L"TBP", L"TBQ", L"TBR", L"TBS", L"TBT", L"TBU", L"TBV", L"TBW", L"TBX", L"TBY", L"TBZ", L"TCA", L"TCB", L"TCC", L"TCD", L"TCE", L"TCF", L"TCG", L"TCH", L"TCI", L"TCJ", L"TCK", L"TCL", L"TCM", L"TCN", L"TCO", L"TCP", L"TCQ", L"TCR", L"TCS", L"TCT", L"TCU", L"TCV", L"TCW", L"TCX", L"TCY", L"TCZ", L"TDA", L"TDB", L"TDC", L"TDD", L"TDE", L"TDF", L"TDG", L"TDH", L"TDI", L"TDJ", L"TDK", L"TDL", L"TDM", L"TDN", L"TDO", L"TDP", L"TDQ", L"TDR", L"TDS", L"TDT", L"TDU", L"TDV", L"TDW", L"TDX", L"TDY", L"TDZ", L"TEA", L"TEB", L"TEC", L"TED", L"TEE", L"TEF", L"TEG", L"TEH", L"TEI", L"TEJ", L"TEK", L"TEL", L"TEM", L"TEN", L"TEO", L"TEP", L"TEQ", L"TER", L"TES", L"TET", L"TEU", L"TEV", L"TEW", L"TEX", L"TEY", L"TEZ", L"TFA", L"TFB", L"TFC", L"TFD", L"TFE", L"TFF", L"TFG", L"TFH", L"TFI", L"TFJ", L"TFK", L"TFL", L"TFM", L"TFN", L"TFO", L"TFP", L"TFQ", L"TFR", L"TFS", L"TFT", L"TFU", L"TFV", L"TFW", L"TFX", L"TFY", L"TFZ", L"TGA", L"TGB", L"TGC", L"TGD", L"TGE", L"TGF", L"TGG", L"TGH", L"TGI", L"TGJ", L"TGK", L"TGL", L"TGM", L"TGN", L"TGO", L"TGP", L"TGQ", L"TGR", L"TGS", L"TGT", L"TGU", L"TGV", L"TGW", L"TGX", L"TGY", L"TGZ", L"THA", L"THB", L"THC", L"THD", L"THE", L"THF", L"THG", L"THH", L"THI", L"THJ", L"THK", L"THL", L"THM", L"THN", L"THO", L"THP", L"THQ", L"THR", L"THS", L"THT", L"THU", L"THV", L"THW", L"THX", L"THY", L"THZ", L"TIA", L"TIB", L"TIC", L"TID", L"TIE", L"TIF", L"TIG", L"TIH", L"TII", L"TIJ", L"TIK", L"TIL", L"TIM", L"TIN", L"TIO", L"TIP", L"TIQ", L"TIR", L"TIS", L"TIT", L"TIU", L"TIV", L"TIW", L"TIX", L"TIY", L"TIZ", L"TJA", L"TJB", L"TJC", L"TJD", L"TJE", L"TJF", L"TJG", L"TJH", L"TJI", L"TJJ", L"TJK", L"TJL", L"TJM", L"TJN", L"TJO", L"TJP", L"TJQ", L"TJR", L"TJS", L"TJT", L"TJU", L"TJV", L"TJW", L"TJX", L"TJY", L"TJZ", L"TKA", L"TKB", L"TKC", L"TKD", L"TKE", L"TKF", L"TKG", L"TKH", L"TKI", L"TKJ", L"TKK", L"TKL", L"TKM", L"TKN", L"TKO", L"TKP", L"TKQ", L"TKR", L"TKS", L"TKT", L"TKU", L"TKV", L"TKW", L"TKX", L"TKY", L"TKZ", L"TLA", L"TLB", L"TLC", L"TLD", L"TLE", L"TLF", L"TLG", L"TLH", L"TLI", L"TLJ", L"TLK", L"TLL", L"TLM", L"TLN", L"TLO", L"TLP", L"TLQ", L"TLR", L"TLS", L"TLT", L"TLU", L"TLV", L"TLW", L"TLX", L"TLY", L"TLZ", L"TMA", L"TMB", L"TMC", L"TMD", L"TME", L"TMF", L"TMG", L"TMH", L"TMI", L"TMJ", L"TMK", L"TML", L"TMM", L"TMN", L"TMO", L"TMP", L"TMQ", L"TMR", L"TMS", L"TMT", L"TMU", L"TMV", L"TMW", L"TMX", L"TMY", L"TMZ", L"TNA", L"TNB", L"TNC", L"TND", L"TNE", L"TNF", L"TNG", L"TNH", L"TNI", L"TNJ", L"TNK", L"TNL", L"TNM", L"TNN", L"TNO", L"TNP", L"TNQ", L"TNR", L"TNS", L"TNT", L"TNU", L"TNV", L"TNW", L"TNX", L"TNY", L"TNZ", L"TOA", L"TOB", L"TOC", L"TOD", L"TOE", L"TOF", L"TOG", L"TOH", L"TOI", L"TOJ", L"TOK", L"TOL", L"TOM", L"TON", L"TOO", L"TOP", L"TOQ", L"TOR", L"TOS", L"TOT", L"TOU", L"TOV", L"TOW", L"TOX", L"TOY", L"TOZ", L"TPA", L"TPB", L"TPC", L"TPD", L"TPE", L"TPF", L"TPG", L"TPH", L"TPI", L"TPJ", L"TPK", L"TPL", L"TPM", L"TPN", L"TPO", L"TPP", L"TPQ", L"TPR", L"TPS", L"TPT", L"TPU", L"TPV", L"TPW", L"TPX", L"TPY", L"TPZ", - L"TQA", L"TQB", L"TQC", L"TQD", L"TQE", L"TQF", L"TQG", L"TQH", L"TQI", L"TQJ", L"TQK", L"TQL", L"TQM", L"TQN", L"TQO", L"TQP", L"TQQ", L"TQR", L"TQS", L"TQT", L"TQU", L"TQV", L"TQW", L"TQX", L"TQY", L"TQZ", L"TRA", L"TRB", L"TRC", L"TRD", L"TRE", L"TRF", L"TRG", L"TRH", L"TRI", L"TRJ", L"TRK", L"TRL", L"TRM", L"TRN", L"TRO", L"TRP", L"TRQ", L"TRR", L"TRS", L"TRT", L"TRU", L"TRV", L"TRW", L"TRX", L"TRY", L"TRZ", L"TSA", L"TSB", L"TSC", L"TSD", L"TSE", L"TSF", L"TSG", L"TSH", L"TSI", L"TSJ", L"TSK", L"TSL", L"TSM", L"TSN", L"TSO", L"TSP", L"TSQ", L"TSR", L"TSS", L"TST", L"TSU", L"TSV", L"TSW", L"TSX", L"TSY", L"TSZ", L"TTA", L"TTB", L"TTC", L"TTD", L"TTE", L"TTF", L"TTG", L"TTH", L"TTI", L"TTJ", L"TTK", L"TTL", L"TTM", L"TTN", L"TTO", L"TTP", L"TTQ", L"TTR", L"TTS", L"TTT", L"TTU", L"TTV", L"TTW", L"TTX", L"TTY", L"TTZ", L"TUA", L"TUB", L"TUC", L"TUD", L"TUE", L"TUF", L"TUG", L"TUH", L"TUI", L"TUJ", L"TUK", L"TUL", L"TUM", L"TUN", L"TUO", L"TUP", L"TUQ", L"TUR", L"TUS", L"TUT", L"TUU", L"TUV", L"TUW", L"TUX", L"TUY", L"TUZ", L"TVA", L"TVB", L"TVC", L"TVD", L"TVE", L"TVF", L"TVG", L"TVH", L"TVI", L"TVJ", L"TVK", L"TVL", L"TVM", L"TVN", L"TVO", L"TVP", L"TVQ", L"TVR", L"TVS", L"TVT", L"TVU", L"TVV", L"TVW", L"TVX", L"TVY", L"TVZ", L"TWA", L"TWB", L"TWC", L"TWD", L"TWE", L"TWF", L"TWG", L"TWH", L"TWI", L"TWJ", L"TWK", L"TWL", L"TWM", L"TWN", L"TWO", L"TWP", L"TWQ", L"TWR", L"TWS", L"TWT", L"TWU", L"TWV", L"TWW", L"TWX", L"TWY", L"TWZ", L"TXA", L"TXB", L"TXC", L"TXD", L"TXE", L"TXF", L"TXG", L"TXH", L"TXI", L"TXJ", L"TXK", L"TXL", L"TXM", L"TXN", L"TXO", L"TXP", L"TXQ", L"TXR", L"TXS", L"TXT", L"TXU", L"TXV", L"TXW", L"TXX", L"TXY", L"TXZ", L"TYA", L"TYB", L"TYC", L"TYD", L"TYE", L"TYF", L"TYG", L"TYH", L"TYI", L"TYJ", L"TYK", L"TYL", L"TYM", L"TYN", L"TYO", L"TYP", L"TYQ", L"TYR", L"TYS", L"TYT", L"TYU", L"TYV", L"TYW", L"TYX", L"TYY", L"TYZ", L"TZA", L"TZB", L"TZC", L"TZD", L"TZE", L"TZF", L"TZG", L"TZH", L"TZI", L"TZJ", L"TZK", L"TZL", L"TZM", L"TZN", L"TZO", L"TZP", L"TZQ", L"TZR", L"TZS", L"TZT", L"TZU", L"TZV", L"TZW", L"TZX", L"TZY", L"TZZ", L"UAA", L"UAB", L"UAC", L"UAD", L"UAE", L"UAF", L"UAG", L"UAH", L"UAI", L"UAJ", L"UAK", L"UAL", L"UAM", - L"UAN", L"UAO", L"UAP", L"UAQ", L"UAR", L"UAS", L"UAT", L"UAU", L"UAV", L"UAW", L"UAX", L"UAY", L"UAZ", L"UBA", L"UBB", L"UBC", L"UBD", L"UBE", L"UBF", L"UBG", L"UBH", L"UBI", L"UBJ", L"UBK", L"UBL", L"UBM", L"UBN", L"UBO", L"UBP", L"UBQ", L"UBR", L"UBS", L"UBT", L"UBU", L"UBV", L"UBW", L"UBX", L"UBY", L"UBZ", L"UCA", L"UCB", L"UCC", L"UCD", L"UCE", L"UCF", L"UCG", L"UCH", L"UCI", L"UCJ", L"UCK", L"UCL", L"UCM", L"UCN", L"UCO", L"UCP", L"UCQ", L"UCR", L"UCS", L"UCT", L"UCU", L"UCV", L"UCW", L"UCX", L"UCY", L"UCZ", L"UDA", L"UDB", L"UDC", L"UDD", L"UDE", L"UDF", L"UDG", L"UDH", L"UDI", L"UDJ", L"UDK", L"UDL", L"UDM", L"UDN", L"UDO", L"UDP", L"UDQ", L"UDR", L"UDS", L"UDT", L"UDU", L"UDV", L"UDW", L"UDX", L"UDY", L"UDZ", L"UEA", L"UEB", L"UEC", L"UED", L"UEE", L"UEF", L"UEG", L"UEH", L"UEI", L"UEJ", L"UEK", L"UEL", L"UEM", L"UEN", L"UEO", L"UEP", L"UEQ", L"UER", L"UES", L"UET", L"UEU", L"UEV", L"UEW", L"UEX", L"UEY", L"UEZ", L"UFA", L"UFB", L"UFC", L"UFD", L"UFE", L"UFF", L"UFG", L"UFH", L"UFI", L"UFJ", L"UFK", L"UFL", L"UFM", L"UFN", L"UFO", L"UFP", L"UFQ", L"UFR", L"UFS", L"UFT", L"UFU", L"UFV", L"UFW", L"UFX", L"UFY", L"UFZ", L"UGA", L"UGB", L"UGC", L"UGD", L"UGE", L"UGF", L"UGG", L"UGH", L"UGI", L"UGJ", L"UGK", L"UGL", L"UGM", L"UGN", L"UGO", L"UGP", L"UGQ", L"UGR", L"UGS", L"UGT", L"UGU", L"UGV", L"UGW", L"UGX", L"UGY", L"UGZ", L"UHA", L"UHB", L"UHC", L"UHD", L"UHE", L"UHF", L"UHG", L"UHH", L"UHI", L"UHJ", L"UHK", L"UHL", L"UHM", L"UHN", L"UHO", L"UHP", L"UHQ", L"UHR", L"UHS", L"UHT", L"UHU", L"UHV", L"UHW", L"UHX", L"UHY", L"UHZ", L"UIA", L"UIB", L"UIC", L"UID", L"UIE", L"UIF", L"UIG", L"UIH", L"UII", L"UIJ", L"UIK", L"UIL", L"UIM", L"UIN", L"UIO", L"UIP", L"UIQ", L"UIR", L"UIS", L"UIT", L"UIU", L"UIV", L"UIW", L"UIX", L"UIY", L"UIZ", L"UJA", L"UJB", L"UJC", L"UJD", L"UJE", L"UJF", L"UJG", L"UJH", L"UJI", L"UJJ", L"UJK", L"UJL", L"UJM", L"UJN", L"UJO", L"UJP", L"UJQ", L"UJR", L"UJS", L"UJT", L"UJU", L"UJV", L"UJW", L"UJX", L"UJY", L"UJZ", L"UKA", L"UKB", L"UKC", L"UKD", L"UKE", L"UKF", L"UKG", L"UKH", L"UKI", L"UKJ", L"UKK", L"UKL", L"UKM", L"UKN", L"UKO", L"UKP", L"UKQ", L"UKR", L"UKS", L"UKT", L"UKU", L"UKV", L"UKW", L"UKX", L"UKY", L"UKZ", - L"ULA", L"ULB", L"ULC", L"ULD", L"ULE", L"ULF", L"ULG", L"ULH", L"ULI", L"ULJ", L"ULK", L"ULL", L"ULM", L"ULN", L"ULO", L"ULP", L"ULQ", L"ULR", L"ULS", L"ULT", L"ULU", L"ULV", L"ULW", L"ULX", L"ULY", L"ULZ", L"UMA", L"UMB", L"UMC", L"UMD", L"UME", L"UMF", L"UMG", L"UMH", L"UMI", L"UMJ", L"UMK", L"UML", L"UMM", L"UMN", L"UMO", L"UMP", L"UMQ", L"UMR", L"UMS", L"UMT", L"UMU", L"UMV", L"UMW", L"UMX", L"UMY", L"UMZ", L"UNA", L"UNB", L"UNC", L"UND", L"UNE", L"UNF", L"UNG", L"UNH", L"UNI", L"UNJ", L"UNK", L"UNL", L"UNM", L"UNN", L"UNO", L"UNP", L"UNQ", L"UNR", L"UNS", L"UNT", L"UNU", L"UNV", L"UNW", L"UNX", L"UNY", L"UNZ", L"UOA", L"UOB", L"UOC", L"UOD", L"UOE", L"UOF", L"UOG", L"UOH", L"UOI", L"UOJ", L"UOK", L"UOL", L"UOM", L"UON", L"UOO", L"UOP", L"UOQ", L"UOR", L"UOS", L"UOT", L"UOU", L"UOV", L"UOW", L"UOX", L"UOY", L"UOZ", L"UPA", L"UPB", L"UPC", L"UPD", L"UPE", L"UPF", L"UPG", L"UPH", L"UPI", L"UPJ", L"UPK", L"UPL", L"UPM", L"UPN", L"UPO", L"UPP", L"UPQ", L"UPR", L"UPS", L"UPT", L"UPU", L"UPV", L"UPW", L"UPX", L"UPY", L"UPZ", L"UQA", L"UQB", L"UQC", L"UQD", L"UQE", L"UQF", L"UQG", L"UQH", L"UQI", L"UQJ", L"UQK", L"UQL", L"UQM", L"UQN", L"UQO", L"UQP", L"UQQ", L"UQR", L"UQS", L"UQT", L"UQU", L"UQV", L"UQW", L"UQX", L"UQY", L"UQZ", L"URA", L"URB", L"URC", L"URD", L"URE", L"URF", L"URG", L"URH", L"URI", L"URJ", L"URK", L"URL", L"URM", L"URN", L"URO", L"URP", L"URQ", L"URR", L"URS", L"URT", L"URU", L"URV", L"URW", L"URX", L"URY", L"URZ", L"USA", L"USB", L"USC", L"USD", L"USE", L"USF", L"USG", L"USH", L"USI", L"USJ", L"USK", L"USL", L"USM", L"USN", L"USO", L"USP", L"USQ", L"USR", L"USS", L"UST", L"USU", L"USV", L"USW", L"USX", L"USY", L"USZ", L"UTA", L"UTB", L"UTC", L"UTD", L"UTE", L"UTF", L"UTG", L"UTH", L"UTI", L"UTJ", L"UTK", L"UTL", L"UTM", L"UTN", L"UTO", L"UTP", L"UTQ", L"UTR", L"UTS", L"UTT", L"UTU", L"UTV", L"UTW", L"UTX", L"UTY", L"UTZ", L"UUA", L"UUB", L"UUC", L"UUD", L"UUE", L"UUF", L"UUG", L"UUH", L"UUI", L"UUJ", L"UUK", L"UUL", L"UUM", L"UUN", L"UUO", L"UUP", L"UUQ", L"UUR", L"UUS", L"UUT", L"UUU", L"UUV", L"UUW", L"UUX", L"UUY", L"UUZ", L"UVA", L"UVB", L"UVC", L"UVD", L"UVE", L"UVF", L"UVG", L"UVH", L"UVI", L"UVJ", L"UVK", L"UVL", L"UVM", - L"UVN", L"UVO", L"UVP", L"UVQ", L"UVR", L"UVS", L"UVT", L"UVU", L"UVV", L"UVW", L"UVX", L"UVY", L"UVZ", L"UWA", L"UWB", L"UWC", L"UWD", L"UWE", L"UWF", L"UWG", L"UWH", L"UWI", L"UWJ", L"UWK", L"UWL", L"UWM", L"UWN", L"UWO", L"UWP", L"UWQ", L"UWR", L"UWS", L"UWT", L"UWU", L"UWV", L"UWW", L"UWX", L"UWY", L"UWZ", L"UXA", L"UXB", L"UXC", L"UXD", L"UXE", L"UXF", L"UXG", L"UXH", L"UXI", L"UXJ", L"UXK", L"UXL", L"UXM", L"UXN", L"UXO", L"UXP", L"UXQ", L"UXR", L"UXS", L"UXT", L"UXU", L"UXV", L"UXW", L"UXX", L"UXY", L"UXZ", L"UYA", L"UYB", L"UYC", L"UYD", L"UYE", L"UYF", L"UYG", L"UYH", L"UYI", L"UYJ", L"UYK", L"UYL", L"UYM", L"UYN", L"UYO", L"UYP", L"UYQ", L"UYR", L"UYS", L"UYT", L"UYU", L"UYV", L"UYW", L"UYX", L"UYY", L"UYZ", L"UZA", L"UZB", L"UZC", L"UZD", L"UZE", L"UZF", L"UZG", L"UZH", L"UZI", L"UZJ", L"UZK", L"UZL", L"UZM", L"UZN", L"UZO", L"UZP", L"UZQ", L"UZR", L"UZS", L"UZT", L"UZU", L"UZV", L"UZW", L"UZX", L"UZY", L"UZZ", L"VAA", L"VAB", L"VAC", L"VAD", L"VAE", L"VAF", L"VAG", L"VAH", L"VAI", L"VAJ", L"VAK", L"VAL", L"VAM", L"VAN", L"VAO", L"VAP", L"VAQ", L"VAR", L"VAS", L"VAT", L"VAU", L"VAV", L"VAW", L"VAX", L"VAY", L"VAZ", L"VBA", L"VBB", L"VBC", L"VBD", L"VBE", L"VBF", L"VBG", L"VBH", L"VBI", L"VBJ", L"VBK", L"VBL", L"VBM", L"VBN", L"VBO", L"VBP", L"VBQ", L"VBR", L"VBS", L"VBT", L"VBU", L"VBV", L"VBW", L"VBX", L"VBY", L"VBZ", L"VCA", L"VCB", L"VCC", L"VCD", L"VCE", L"VCF", L"VCG", L"VCH", L"VCI", L"VCJ", L"VCK", L"VCL", L"VCM", L"VCN", L"VCO", L"VCP", L"VCQ", L"VCR", L"VCS", L"VCT", L"VCU", L"VCV", L"VCW", L"VCX", L"VCY", L"VCZ", L"VDA", L"VDB", L"VDC", L"VDD", L"VDE", L"VDF", L"VDG", L"VDH", L"VDI", L"VDJ", L"VDK", L"VDL", L"VDM", L"VDN", L"VDO", L"VDP", L"VDQ", L"VDR", L"VDS", L"VDT", L"VDU", L"VDV", L"VDW", L"VDX", L"VDY", L"VDZ", L"VEA", L"VEB", L"VEC", L"VED", L"VEE", L"VEF", L"VEG", L"VEH", L"VEI", L"VEJ", L"VEK", L"VEL", L"VEM", L"VEN", L"VEO", L"VEP", L"VEQ", L"VER", L"VES", L"VET", L"VEU", L"VEV", L"VEW", L"VEX", L"VEY", L"VEZ", L"VFA", L"VFB", L"VFC", L"VFD", L"VFE", L"VFF", L"VFG", L"VFH", L"VFI", L"VFJ", L"VFK", L"VFL", L"VFM", L"VFN", L"VFO", L"VFP", L"VFQ", L"VFR", L"VFS", L"VFT", L"VFU", L"VFV", L"VFW", L"VFX", L"VFY", L"VFZ", - L"VGA", L"VGB", L"VGC", L"VGD", L"VGE", L"VGF", L"VGG", L"VGH", L"VGI", L"VGJ", L"VGK", L"VGL", L"VGM", L"VGN", L"VGO", L"VGP", L"VGQ", L"VGR", L"VGS", L"VGT", L"VGU", L"VGV", L"VGW", L"VGX", L"VGY", L"VGZ", L"VHA", L"VHB", L"VHC", L"VHD", L"VHE", L"VHF", L"VHG", L"VHH", L"VHI", L"VHJ", L"VHK", L"VHL", L"VHM", L"VHN", L"VHO", L"VHP", L"VHQ", L"VHR", L"VHS", L"VHT", L"VHU", L"VHV", L"VHW", L"VHX", L"VHY", L"VHZ", L"VIA", L"VIB", L"VIC", L"VID", L"VIE", L"VIF", L"VIG", L"VIH", L"VII", L"VIJ", L"VIK", L"VIL", L"VIM", L"VIN", L"VIO", L"VIP", L"VIQ", L"VIR", L"VIS", L"VIT", L"VIU", L"VIV", L"VIW", L"VIX", L"VIY", L"VIZ", L"VJA", L"VJB", L"VJC", L"VJD", L"VJE", L"VJF", L"VJG", L"VJH", L"VJI", L"VJJ", L"VJK", L"VJL", L"VJM", L"VJN", L"VJO", L"VJP", L"VJQ", L"VJR", L"VJS", L"VJT", L"VJU", L"VJV", L"VJW", L"VJX", L"VJY", L"VJZ", L"VKA", L"VKB", L"VKC", L"VKD", L"VKE", L"VKF", L"VKG", L"VKH", L"VKI", L"VKJ", L"VKK", L"VKL", L"VKM", L"VKN", L"VKO", L"VKP", L"VKQ", L"VKR", L"VKS", L"VKT", L"VKU", L"VKV", L"VKW", L"VKX", L"VKY", L"VKZ", L"VLA", L"VLB", L"VLC", L"VLD", L"VLE", L"VLF", L"VLG", L"VLH", L"VLI", L"VLJ", L"VLK", L"VLL", L"VLM", L"VLN", L"VLO", L"VLP", L"VLQ", L"VLR", L"VLS", L"VLT", L"VLU", L"VLV", L"VLW", L"VLX", L"VLY", L"VLZ", L"VMA", L"VMB", L"VMC", L"VMD", L"VME", L"VMF", L"VMG", L"VMH", L"VMI", L"VMJ", L"VMK", L"VML", L"VMM", L"VMN", L"VMO", L"VMP", L"VMQ", L"VMR", L"VMS", L"VMT", L"VMU", L"VMV", L"VMW", L"VMX", L"VMY", L"VMZ", L"VNA", L"VNB", L"VNC", L"VND", L"VNE", L"VNF", L"VNG", L"VNH", L"VNI", L"VNJ", L"VNK", L"VNL", L"VNM", L"VNN", L"VNO", L"VNP", L"VNQ", L"VNR", L"VNS", L"VNT", L"VNU", L"VNV", L"VNW", L"VNX", L"VNY", L"VNZ", L"VOA", L"VOB", L"VOC", L"VOD", L"VOE", L"VOF", L"VOG", L"VOH", L"VOI", L"VOJ", L"VOK", L"VOL", L"VOM", L"VON", L"VOO", L"VOP", L"VOQ", L"VOR", L"VOS", L"VOT", L"VOU", L"VOV", L"VOW", L"VOX", L"VOY", L"VOZ", L"VPA", L"VPB", L"VPC", L"VPD", L"VPE", L"VPF", L"VPG", L"VPH", L"VPI", L"VPJ", L"VPK", L"VPL", L"VPM", L"VPN", L"VPO", L"VPP", L"VPQ", L"VPR", L"VPS", L"VPT", L"VPU", L"VPV", L"VPW", L"VPX", L"VPY", L"VPZ", L"VQA", L"VQB", L"VQC", L"VQD", L"VQE", L"VQF", L"VQG", L"VQH", L"VQI", L"VQJ", L"VQK", L"VQL", L"VQM", - L"VQN", L"VQO", L"VQP", L"VQQ", L"VQR", L"VQS", L"VQT", L"VQU", L"VQV", L"VQW", L"VQX", L"VQY", L"VQZ", L"VRA", L"VRB", L"VRC", L"VRD", L"VRE", L"VRF", L"VRG", L"VRH", L"VRI", L"VRJ", L"VRK", L"VRL", L"VRM", L"VRN", L"VRO", L"VRP", L"VRQ", L"VRR", L"VRS", L"VRT", L"VRU", L"VRV", L"VRW", L"VRX", L"VRY", L"VRZ", L"VSA", L"VSB", L"VSC", L"VSD", L"VSE", L"VSF", L"VSG", L"VSH", L"VSI", L"VSJ", L"VSK", L"VSL", L"VSM", L"VSN", L"VSO", L"VSP", L"VSQ", L"VSR", L"VSS", L"VST", L"VSU", L"VSV", L"VSW", L"VSX", L"VSY", L"VSZ", L"VTA", L"VTB", L"VTC", L"VTD", L"VTE", L"VTF", L"VTG", L"VTH", L"VTI", L"VTJ", L"VTK", L"VTL", L"VTM", L"VTN", L"VTO", L"VTP", L"VTQ", L"VTR", L"VTS", L"VTT", L"VTU", L"VTV", L"VTW", L"VTX", L"VTY", L"VTZ", L"VUA", L"VUB", L"VUC", L"VUD", L"VUE", L"VUF", L"VUG", L"VUH", L"VUI", L"VUJ", L"VUK", L"VUL", L"VUM", L"VUN", L"VUO", L"VUP", L"VUQ", L"VUR", L"VUS", L"VUT", L"VUU", L"VUV", L"VUW", L"VUX", L"VUY", L"VUZ", L"VVA", L"VVB", L"VVC", L"VVD", L"VVE", L"VVF", L"VVG", L"VVH", L"VVI", L"VVJ", L"VVK", L"VVL", L"VVM", L"VVN", L"VVO", L"VVP", L"VVQ", L"VVR", L"VVS", L"VVT", L"VVU", L"VVV", L"VVW", L"VVX", L"VVY", L"VVZ", L"VWA", L"VWB", L"VWC", L"VWD", L"VWE", L"VWF", L"VWG", L"VWH", L"VWI", L"VWJ", L"VWK", L"VWL", L"VWM", L"VWN", L"VWO", L"VWP", L"VWQ", L"VWR", L"VWS", L"VWT", L"VWU", L"VWV", L"VWW", L"VWX", L"VWY", L"VWZ", L"VXA", L"VXB", L"VXC", L"VXD", L"VXE", L"VXF", L"VXG", L"VXH", L"VXI", L"VXJ", L"VXK", L"VXL", L"VXM", L"VXN", L"VXO", L"VXP", L"VXQ", L"VXR", L"VXS", L"VXT", L"VXU", L"VXV", L"VXW", L"VXX", L"VXY", L"VXZ", L"VYA", L"VYB", L"VYC", L"VYD", L"VYE", L"VYF", L"VYG", L"VYH", L"VYI", L"VYJ", L"VYK", L"VYL", L"VYM", L"VYN", L"VYO", L"VYP", L"VYQ", L"VYR", L"VYS", L"VYT", L"VYU", L"VYV", L"VYW", L"VYX", L"VYY", L"VYZ", L"VZA", L"VZB", L"VZC", L"VZD", L"VZE", L"VZF", L"VZG", L"VZH", L"VZI", L"VZJ", L"VZK", L"VZL", L"VZM", L"VZN", L"VZO", L"VZP", L"VZQ", L"VZR", L"VZS", L"VZT", L"VZU", L"VZV", L"VZW", L"VZX", L"VZY", L"VZZ", L"WAA", L"WAB", L"WAC", L"WAD", L"WAE", L"WAF", L"WAG", L"WAH", L"WAI", L"WAJ", L"WAK", L"WAL", L"WAM", L"WAN", L"WAO", L"WAP", L"WAQ", L"WAR", L"WAS", L"WAT", L"WAU", L"WAV", L"WAW", L"WAX", L"WAY", L"WAZ", - L"WBA", L"WBB", L"WBC", L"WBD", L"WBE", L"WBF", L"WBG", L"WBH", L"WBI", L"WBJ", L"WBK", L"WBL", L"WBM", L"WBN", L"WBO", L"WBP", L"WBQ", L"WBR", L"WBS", L"WBT", L"WBU", L"WBV", L"WBW", L"WBX", L"WBY", L"WBZ", L"WCA", L"WCB", L"WCC", L"WCD", L"WCE", L"WCF", L"WCG", L"WCH", L"WCI", L"WCJ", L"WCK", L"WCL", L"WCM", L"WCN", L"WCO", L"WCP", L"WCQ", L"WCR", L"WCS", L"WCT", L"WCU", L"WCV", L"WCW", L"WCX", L"WCY", L"WCZ", L"WDA", L"WDB", L"WDC", L"WDD", L"WDE", L"WDF", L"WDG", L"WDH", L"WDI", L"WDJ", L"WDK", L"WDL", L"WDM", L"WDN", L"WDO", L"WDP", L"WDQ", L"WDR", L"WDS", L"WDT", L"WDU", L"WDV", L"WDW", L"WDX", L"WDY", L"WDZ", L"WEA", L"WEB", L"WEC", L"WED", L"WEE", L"WEF", L"WEG", L"WEH", L"WEI", L"WEJ", L"WEK", L"WEL", L"WEM", L"WEN", L"WEO", L"WEP", L"WEQ", L"WER", L"WES", L"WET", L"WEU", L"WEV", L"WEW", L"WEX", L"WEY", L"WEZ", L"WFA", L"WFB", L"WFC", L"WFD", L"WFE", L"WFF", L"WFG", L"WFH", L"WFI", L"WFJ", L"WFK", L"WFL", L"WFM", L"WFN", L"WFO", L"WFP", L"WFQ", L"WFR", L"WFS", L"WFT", L"WFU", L"WFV", L"WFW", L"WFX", L"WFY", L"WFZ", L"WGA", L"WGB", L"WGC", L"WGD", L"WGE", L"WGF", L"WGG", L"WGH", L"WGI", L"WGJ", L"WGK", L"WGL", L"WGM", L"WGN", L"WGO", L"WGP", L"WGQ", L"WGR", L"WGS", L"WGT", L"WGU", L"WGV", L"WGW", L"WGX", L"WGY", L"WGZ", L"WHA", L"WHB", L"WHC", L"WHD", L"WHE", L"WHF", L"WHG", L"WHH", L"WHI", L"WHJ", L"WHK", L"WHL", L"WHM", L"WHN", L"WHO", L"WHP", L"WHQ", L"WHR", L"WHS", L"WHT", L"WHU", L"WHV", L"WHW", L"WHX", L"WHY", L"WHZ", L"WIA", L"WIB", L"WIC", L"WID", L"WIE", L"WIF", L"WIG", L"WIH", L"WII", L"WIJ", L"WIK", L"WIL", L"WIM", L"WIN", L"WIO", L"WIP", L"WIQ", L"WIR", L"WIS", L"WIT", L"WIU", L"WIV", L"WIW", L"WIX", L"WIY", L"WIZ", L"WJA", L"WJB", L"WJC", L"WJD", L"WJE", L"WJF", L"WJG", L"WJH", L"WJI", L"WJJ", L"WJK", L"WJL", L"WJM", L"WJN", L"WJO", L"WJP", L"WJQ", L"WJR", L"WJS", L"WJT", L"WJU", L"WJV", L"WJW", L"WJX", L"WJY", L"WJZ", L"WKA", L"WKB", L"WKC", L"WKD", L"WKE", L"WKF", L"WKG", L"WKH", L"WKI", L"WKJ", L"WKK", L"WKL", L"WKM", L"WKN", L"WKO", L"WKP", L"WKQ", L"WKR", L"WKS", L"WKT", L"WKU", L"WKV", L"WKW", L"WKX", L"WKY", L"WKZ", L"WLA", L"WLB", L"WLC", L"WLD", L"WLE", L"WLF", L"WLG", L"WLH", L"WLI", L"WLJ", L"WLK", L"WLL", L"WLM", - L"WLN", L"WLO", L"WLP", L"WLQ", L"WLR", L"WLS", L"WLT", L"WLU", L"WLV", L"WLW", L"WLX", L"WLY", L"WLZ", L"WMA", L"WMB", L"WMC", L"WMD", L"WME", L"WMF", L"WMG", L"WMH", L"WMI", L"WMJ", L"WMK", L"WML", L"WMM", L"WMN", L"WMO", L"WMP", L"WMQ", L"WMR", L"WMS", L"WMT", L"WMU", L"WMV", L"WMW", L"WMX", L"WMY", L"WMZ", L"WNA", L"WNB", L"WNC", L"WND", L"WNE", L"WNF", L"WNG", L"WNH", L"WNI", L"WNJ", L"WNK", L"WNL", L"WNM", L"WNN", L"WNO", L"WNP", L"WNQ", L"WNR", L"WNS", L"WNT", L"WNU", L"WNV", L"WNW", L"WNX", L"WNY", L"WNZ", L"WOA", L"WOB", L"WOC", L"WOD", L"WOE", L"WOF", L"WOG", L"WOH", L"WOI", L"WOJ", L"WOK", L"WOL", L"WOM", L"WON", L"WOO", L"WOP", L"WOQ", L"WOR", L"WOS", L"WOT", L"WOU", L"WOV", L"WOW", L"WOX", L"WOY", L"WOZ", L"WPA", L"WPB", L"WPC", L"WPD", L"WPE", L"WPF", L"WPG", L"WPH", L"WPI", L"WPJ", L"WPK", L"WPL", L"WPM", L"WPN", L"WPO", L"WPP", L"WPQ", L"WPR", L"WPS", L"WPT", L"WPU", L"WPV", L"WPW", L"WPX", L"WPY", L"WPZ", L"WQA", L"WQB", L"WQC", L"WQD", L"WQE", L"WQF", L"WQG", L"WQH", L"WQI", L"WQJ", L"WQK", L"WQL", L"WQM", L"WQN", L"WQO", L"WQP", L"WQQ", L"WQR", L"WQS", L"WQT", L"WQU", L"WQV", L"WQW", L"WQX", L"WQY", L"WQZ", L"WRA", L"WRB", L"WRC", L"WRD", L"WRE", L"WRF", L"WRG", L"WRH", L"WRI", L"WRJ", L"WRK", L"WRL", L"WRM", L"WRN", L"WRO", L"WRP", L"WRQ", L"WRR", L"WRS", L"WRT", L"WRU", L"WRV", L"WRW", L"WRX", L"WRY", L"WRZ", L"WSA", L"WSB", L"WSC", L"WSD", L"WSE", L"WSF", L"WSG", L"WSH", L"WSI", L"WSJ", L"WSK", L"WSL", L"WSM", L"WSN", L"WSO", L"WSP", L"WSQ", L"WSR", L"WSS", L"WST", L"WSU", L"WSV", L"WSW", L"WSX", L"WSY", L"WSZ", L"WTA", L"WTB", L"WTC", L"WTD", L"WTE", L"WTF", L"WTG", L"WTH", L"WTI", L"WTJ", L"WTK", L"WTL", L"WTM", L"WTN", L"WTO", L"WTP", L"WTQ", L"WTR", L"WTS", L"WTT", L"WTU", L"WTV", L"WTW", L"WTX", L"WTY", L"WTZ", L"WUA", L"WUB", L"WUC", L"WUD", L"WUE", L"WUF", L"WUG", L"WUH", L"WUI", L"WUJ", L"WUK", L"WUL", L"WUM", L"WUN", L"WUO", L"WUP", L"WUQ", L"WUR", L"WUS", L"WUT", L"WUU", L"WUV", L"WUW", L"WUX", L"WUY", L"WUZ", L"WVA", L"WVB", L"WVC", L"WVD", L"WVE", L"WVF", L"WVG", L"WVH", L"WVI", L"WVJ", L"WVK", L"WVL", L"WVM", L"WVN", L"WVO", L"WVP", L"WVQ", L"WVR", L"WVS", L"WVT", L"WVU", L"WVV", L"WVW", L"WVX", L"WVY", L"WVZ", + L"TQA", L"TQB", L"TQC", L"TQD", L"TQE", L"TQF", L"TQG", L"TQH", L"TQI", L"TQJ", L"TQK", L"TQL", L"TQM", L"TQN", L"TQO", L"TQP", L"TQQ", L"TQR", L"TQS", L"TQT", L"TQU", L"TQV", L"TQW", L"TQX", L"TQY", L"TQZ", L"TRA", L"TRB", L"TRC", L"TRD", L"TRE", L"TRF", L"TRG", L"TRH", L"TRI", L"TRJ", L"TRK", L"TRL", L"TRM", L"TRN", L"TRO", L"TRP", L"TRQ", L"TRR", L"TRS", L"TRT", L"TRU", L"TRV", L"TRW", L"TRX", L"TRY", L"TRZ", L"TSA", L"TSB", L"TSC", L"TSD", L"TSE", L"TSF", L"TSG", L"TSH", L"TSI", L"TSJ", L"TSK", L"TSL", L"TSM", L"TSN", L"TSO", L"TSP", L"TSQ", L"TSR", L"TSS", L"TST", L"TSU", L"TSV", L"TSW", L"TSX", L"TSY", L"TSZ", L"TTA", L"TTB", L"TTC", L"TTD", L"TTE", L"TTF", L"TTG", L"TTH", L"TTI", L"TTJ", L"TTK", L"TTL", L"TTM", L"TTN", L"TTO", L"TTP", L"TTQ", L"TTR", L"TTS", L"TTT", L"TTU", L"TTV", L"TTW", L"TTX", L"TTY", L"TTZ", L"TUA", L"TUB", L"TUC", L"TUD", L"TUE", L"TUF", L"TUG", L"TUH", L"TUI", L"TUJ", L"TUK", L"TUL", L"TUM", L"TUN", L"TUO", L"TUP", L"TUQ", L"TUR", L"TUS", L"TUT", L"TUU", L"TUV", L"TUW", L"TUX", L"TUY", L"TUZ", L"TVA", L"TVB", L"TVC", L"TVD", L"TVE", L"TVF", L"TVG", L"TVH", L"TVI", L"TVJ", L"TVK", L"TVL", L"TVM", L"TVN", L"TVO", L"TVP", L"TVQ", L"TVR", L"TVS", L"TVT", L"TVU", L"TVV", L"TVW", L"TVX", L"TVY", L"TVZ", L"TWA", L"TWB", L"TWC", L"TWD", L"TWE", L"TWF", L"TWG", L"TWH", L"TWI", L"TWJ", L"TWK", L"TWL", L"TWM", L"TWN", L"TWO", L"TWP", L"TWQ", L"TWR", L"TWS", L"TWT", L"TWU", L"TWV", L"TWW", L"TWX", L"TWY", L"TWZ", L"TXA", L"TXB", L"TXC", L"TXD", L"TXE", L"TXF", L"TXG", L"TXH", L"TXI", L"TXJ", L"TXK", L"TXL", L"TXM", L"TXN", L"TXO", L"TXP", L"TXQ", L"TXR", L"TXS", L"TXT", L"TXU", L"TXV", L"TXW", L"TXX", L"TXY", L"TXZ", L"TYA", L"TYB", L"TYC", L"TYD", L"TYE", L"TYF", L"TYG", L"TYH", L"TYI", L"TYJ", L"TYK", L"TYL", L"TYM", L"TYN", L"TYO", L"TYP", L"TYQ", L"TYR", L"TYS", L"TYT", L"TYU", L"TYV", L"TYW", L"TYX", L"TYY", L"TYZ", L"TZA", L"TZB", L"TZC", L"TZD", L"TZE", L"TZF", L"TZG", L"TZH", L"TZI", L"TZJ", L"TZK", L"TZL", L"TZM", L"TZN", L"TZO", L"TZP", L"TZQ", L"TZR", L"TZS", L"TZT", L"TZU", L"TZV", L"TZW", L"TZX", L"TZY", L"TZZ", L"UAA", L"UAB", L"UAC", L"UAD", L"UAE", L"UAF", L"UAG", L"UAH", L"UAI", L"UAJ", L"UAK", L"UAL", L"UAM", + L"UAN", L"UAO", L"UAP", L"UAQ", L"UAR", L"UAS", L"UAT", L"UAU", L"UAV", L"UAW", L"UAX", L"UAY", L"UAZ", L"UBA", L"UBB", L"UBC", L"UBD", L"UBE", L"UBF", L"UBG", L"UBH", L"UBI", L"UBJ", L"UBK", L"UBL", L"UBM", L"UBN", L"UBO", L"UBP", L"UBQ", L"UBR", L"UBS", L"UBT", L"UBU", L"UBV", L"UBW", L"UBX", L"UBY", L"UBZ", L"UCA", L"UCB", L"UCC", L"UCD", L"UCE", L"UCF", L"UCG", L"UCH", L"UCI", L"UCJ", L"UCK", L"UCL", L"UCM", L"UCN", L"UCO", L"UCP", L"UCQ", L"UCR", L"UCS", L"UCT", L"UCU", L"UCV", L"UCW", L"UCX", L"UCY", L"UCZ", L"UDA", L"UDB", L"UDC", L"UDD", L"UDE", L"UDF", L"UDG", L"UDH", L"UDI", L"UDJ", L"UDK", L"UDL", L"UDM", L"UDN", L"UDO", L"UDP", L"UDQ", L"UDR", L"UDS", L"UDT", L"UDU", L"UDV", L"UDW", L"UDX", L"UDY", L"UDZ", L"UEA", L"UEB", L"UEC", L"UED", L"UEE", L"UEF", L"UEG", L"UEH", L"UEI", L"UEJ", L"UEK", L"UEL", L"UEM", L"UEN", L"UEO", L"UEP", L"UEQ", L"UER", L"UES", L"UET", L"UEU", L"UEV", L"UEW", L"UEX", L"UEY", L"UEZ", L"UFA", L"UFB", L"UFC", L"UFD", L"UFE", L"UFF", L"UFG", L"UFH", L"UFI", L"UFJ", L"UFK", L"UFL", L"UFM", L"UFN", L"UFO", L"UFP", L"UFQ", L"UFR", L"UFS", L"UFT", L"UFU", L"UFV", L"UFW", L"UFX", L"UFY", L"UFZ", L"UGA", L"UGB", L"UGC", L"UGD", L"UGE", L"UGF", L"UGG", L"UGH", L"UGI", L"UGJ", L"UGK", L"UGL", L"UGM", L"UGN", L"UGO", L"UGP", L"UGQ", L"UGR", L"UGS", L"UGT", L"UGU", L"UGV", L"UGW", L"UGX", L"UGY", L"UGZ", L"UHA", L"UHB", L"UHC", L"UHD", L"UHE", L"UHF", L"UHG", L"UHH", L"UHI", L"UHJ", L"UHK", L"UHL", L"UHM", L"UHN", L"UHO", L"UHP", L"UHQ", L"UHR", L"UHS", L"UHT", L"UHU", L"UHV", L"UHW", L"UHX", L"UHY", L"UHZ", L"UIA", L"UIB", L"UIC", L"UID", L"UIE", L"UIF", L"UIG", L"UIH", L"UII", L"UIJ", L"UIK", L"UIL", L"UIM", L"UIN", L"UIO", L"UIP", L"UIQ", L"UIR", L"UIS", L"UIT", L"UIU", L"UIV", L"UIW", L"UIX", L"UIY", L"UIZ", L"UJA", L"UJB", L"UJC", L"UJD", L"UJE", L"UJF", L"UJG", L"UJH", L"UJI", L"UJJ", L"UJK", L"UJL", L"UJM", L"UJN", L"UJO", L"UJP", L"UJQ", L"UJR", L"UJS", L"UJT", L"UJU", L"UJV", L"UJW", L"UJX", L"UJY", L"UJZ", L"UKA", L"UKB", L"UKC", L"UKD", L"UKE", L"UKF", L"UKG", L"UKH", L"UKI", L"UKJ", L"UKK", L"UKL", L"UKM", L"UKN", L"UKO", L"UKP", L"UKQ", L"UKR", L"UKS", L"UKT", L"UKU", L"UKV", L"UKW", L"UKX", L"UKY", L"UKZ", + L"ULA", L"ULB", L"ULC", L"ULD", L"ULE", L"ULF", L"ULG", L"ULH", L"ULI", L"ULJ", L"ULK", L"ULL", L"ULM", L"ULN", L"ULO", L"ULP", L"ULQ", L"ULR", L"ULS", L"ULT", L"ULU", L"ULV", L"ULW", L"ULX", L"ULY", L"ULZ", L"UMA", L"UMB", L"UMC", L"UMD", L"UME", L"UMF", L"UMG", L"UMH", L"UMI", L"UMJ", L"UMK", L"UML", L"UMM", L"UMN", L"UMO", L"UMP", L"UMQ", L"UMR", L"UMS", L"UMT", L"UMU", L"UMV", L"UMW", L"UMX", L"UMY", L"UMZ", L"UNA", L"UNB", L"UNC", L"UND", L"UNE", L"UNF", L"UNG", L"UNH", L"UNI", L"UNJ", L"UNK", L"UNL", L"UNM", L"UNN", L"UNO", L"UNP", L"UNQ", L"UNR", L"UNS", L"UNT", L"UNU", L"UNV", L"UNW", L"UNX", L"UNY", L"UNZ", L"UOA", L"UOB", L"UOC", L"UOD", L"UOE", L"UOF", L"UOG", L"UOH", L"UOI", L"UOJ", L"UOK", L"UOL", L"UOM", L"UON", L"UOO", L"UOP", L"UOQ", L"UOR", L"UOS", L"UOT", L"UOU", L"UOV", L"UOW", L"UOX", L"UOY", L"UOZ", L"UPA", L"UPB", L"UPC", L"UPD", L"UPE", L"UPF", L"UPG", L"UPH", L"UPI", L"UPJ", L"UPK", L"UPL", L"UPM", L"UPN", L"UPO", L"UPP", L"UPQ", L"UPR", L"UPS", L"UPT", L"UPU", L"UPV", L"UPW", L"UPX", L"UPY", L"UPZ", L"UQA", L"UQB", L"UQC", L"UQD", L"UQE", L"UQF", L"UQG", L"UQH", L"UQI", L"UQJ", L"UQK", L"UQL", L"UQM", L"UQN", L"UQO", L"UQP", L"UQQ", L"UQR", L"UQS", L"UQT", L"UQU", L"UQV", L"UQW", L"UQX", L"UQY", L"UQZ", L"URA", L"URB", L"URC", L"URD", L"URE", L"URF", L"URG", L"URH", L"URI", L"URJ", L"URK", L"URL", L"URM", L"URN", L"URO", L"URP", L"URQ", L"URR", L"URS", L"URT", L"URU", L"URV", L"URW", L"URX", L"URY", L"URZ", L"USA", L"USB", L"USC", L"USD", L"USE", L"USF", L"USG", L"USH", L"USI", L"USJ", L"USK", L"USL", L"USM", L"USN", L"USO", L"USP", L"USQ", L"USR", L"USS", L"UST", L"USU", L"USV", L"USW", L"USX", L"USY", L"USZ", L"UTA", L"UTB", L"UTC", L"UTD", L"UTE", L"UTF", L"UTG", L"UTH", L"UTI", L"UTJ", L"UTK", L"UTL", L"UTM", L"UTN", L"UTO", L"UTP", L"UTQ", L"UTR", L"UTS", L"UTT", L"UTU", L"UTV", L"UTW", L"UTX", L"UTY", L"UTZ", L"UUA", L"UUB", L"UUC", L"UUD", L"UUE", L"UUF", L"UUG", L"UUH", L"UUI", L"UUJ", L"UUK", L"UUL", L"UUM", L"UUN", L"UUO", L"UUP", L"UUQ", L"UUR", L"UUS", L"UUT", L"UUU", L"UUV", L"UUW", L"UUX", L"UUY", L"UUZ", L"UVA", L"UVB", L"UVC", L"UVD", L"UVE", L"UVF", L"UVG", L"UVH", L"UVI", L"UVJ", L"UVK", L"UVL", L"UVM", + L"UVN", L"UVO", L"UVP", L"UVQ", L"UVR", L"UVS", L"UVT", L"UVU", L"UVV", L"UVW", L"UVX", L"UVY", L"UVZ", L"UWA", L"UWB", L"UWC", L"UWD", L"UWE", L"UWF", L"UWG", L"UWH", L"UWI", L"UWJ", L"UWK", L"UWL", L"UWM", L"UWN", L"UWO", L"UWP", L"UWQ", L"UWR", L"UWS", L"UWT", L"UWU", L"UWV", L"UWW", L"UWX", L"UWY", L"UWZ", L"UXA", L"UXB", L"UXC", L"UXD", L"UXE", L"UXF", L"UXG", L"UXH", L"UXI", L"UXJ", L"UXK", L"UXL", L"UXM", L"UXN", L"UXO", L"UXP", L"UXQ", L"UXR", L"UXS", L"UXT", L"UXU", L"UXV", L"UXW", L"UXX", L"UXY", L"UXZ", L"UYA", L"UYB", L"UYC", L"UYD", L"UYE", L"UYF", L"UYG", L"UYH", L"UYI", L"UYJ", L"UYK", L"UYL", L"UYM", L"UYN", L"UYO", L"UYP", L"UYQ", L"UYR", L"UYS", L"UYT", L"UYU", L"UYV", L"UYW", L"UYX", L"UYY", L"UYZ", L"UZA", L"UZB", L"UZC", L"UZD", L"UZE", L"UZF", L"UZG", L"UZH", L"UZI", L"UZJ", L"UZK", L"UZL", L"UZM", L"UZN", L"UZO", L"UZP", L"UZQ", L"UZR", L"UZS", L"UZT", L"UZU", L"UZV", L"UZW", L"UZX", L"UZY", L"UZZ", L"VAA", L"VAB", L"VAC", L"VAD", L"VAE", L"VAF", L"VAG", L"VAH", L"VAI", L"VAJ", L"VAK", L"VAL", L"VAM", L"VAN", L"VAO", L"VAP", L"VAQ", L"VAR", L"VAS", L"VAT", L"VAU", L"VAV", L"VAW", L"VAX", L"VAY", L"VAZ", L"VBA", L"VBB", L"VBC", L"VBD", L"VBE", L"VBF", L"VBG", L"VBH", L"VBI", L"VBJ", L"VBK", L"VBL", L"VBM", L"VBN", L"VBO", L"VBP", L"VBQ", L"VBR", L"VBS", L"VBT", L"VBU", L"VBV", L"VBW", L"VBX", L"VBY", L"VBZ", L"VCA", L"VCB", L"VCC", L"VCD", L"VCE", L"VCF", L"VCG", L"VCH", L"VCI", L"VCJ", L"VCK", L"VCL", L"VCM", L"VCN", L"VCO", L"VCP", L"VCQ", L"VCR", L"VCS", L"VCT", L"VCU", L"VCV", L"VCW", L"VCX", L"VCY", L"VCZ", L"VDA", L"VDB", L"VDC", L"VDD", L"VDE", L"VDF", L"VDG", L"VDH", L"VDI", L"VDJ", L"VDK", L"VDL", L"VDM", L"VDN", L"VDO", L"VDP", L"VDQ", L"VDR", L"VDS", L"VDT", L"VDU", L"VDV", L"VDW", L"VDX", L"VDY", L"VDZ", L"VEA", L"VEB", L"VEC", L"VED", L"VEE", L"VEF", L"VEG", L"VEH", L"VEI", L"VEJ", L"VEK", L"VEL", L"VEM", L"VEN", L"VEO", L"VEP", L"VEQ", L"VER", L"VES", L"VET", L"VEU", L"VEV", L"VEW", L"VEX", L"VEY", L"VEZ", L"VFA", L"VFB", L"VFC", L"VFD", L"VFE", L"VFF", L"VFG", L"VFH", L"VFI", L"VFJ", L"VFK", L"VFL", L"VFM", L"VFN", L"VFO", L"VFP", L"VFQ", L"VFR", L"VFS", L"VFT", L"VFU", L"VFV", L"VFW", L"VFX", L"VFY", L"VFZ", + L"VGA", L"VGB", L"VGC", L"VGD", L"VGE", L"VGF", L"VGG", L"VGH", L"VGI", L"VGJ", L"VGK", L"VGL", L"VGM", L"VGN", L"VGO", L"VGP", L"VGQ", L"VGR", L"VGS", L"VGT", L"VGU", L"VGV", L"VGW", L"VGX", L"VGY", L"VGZ", L"VHA", L"VHB", L"VHC", L"VHD", L"VHE", L"VHF", L"VHG", L"VHH", L"VHI", L"VHJ", L"VHK", L"VHL", L"VHM", L"VHN", L"VHO", L"VHP", L"VHQ", L"VHR", L"VHS", L"VHT", L"VHU", L"VHV", L"VHW", L"VHX", L"VHY", L"VHZ", L"VIA", L"VIB", L"VIC", L"VID", L"VIE", L"VIF", L"VIG", L"VIH", L"VII", L"VIJ", L"VIK", L"VIL", L"VIM", L"VIN", L"VIO", L"VIP", L"VIQ", L"VIR", L"VIS", L"VIT", L"VIU", L"VIV", L"VIW", L"VIX", L"VIY", L"VIZ", L"VJA", L"VJB", L"VJC", L"VJD", L"VJE", L"VJF", L"VJG", L"VJH", L"VJI", L"VJJ", L"VJK", L"VJL", L"VJM", L"VJN", L"VJO", L"VJP", L"VJQ", L"VJR", L"VJS", L"VJT", L"VJU", L"VJV", L"VJW", L"VJX", L"VJY", L"VJZ", L"VKA", L"VKB", L"VKC", L"VKD", L"VKE", L"VKF", L"VKG", L"VKH", L"VKI", L"VKJ", L"VKK", L"VKL", L"VKM", L"VKN", L"VKO", L"VKP", L"VKQ", L"VKR", L"VKS", L"VKT", L"VKU", L"VKV", L"VKW", L"VKX", L"VKY", L"VKZ", L"VLA", L"VLB", L"VLC", L"VLD", L"VLE", L"VLF", L"VLG", L"VLH", L"VLI", L"VLJ", L"VLK", L"VLL", L"VLM", L"VLN", L"VLO", L"VLP", L"VLQ", L"VLR", L"VLS", L"VLT", L"VLU", L"VLV", L"VLW", L"VLX", L"VLY", L"VLZ", L"VMA", L"VMB", L"VMC", L"VMD", L"VME", L"VMF", L"VMG", L"VMH", L"VMI", L"VMJ", L"VMK", L"VML", L"VMM", L"VMN", L"VMO", L"VMP", L"VMQ", L"VMR", L"VMS", L"VMT", L"VMU", L"VMV", L"VMW", L"VMX", L"VMY", L"VMZ", L"VNA", L"VNB", L"VNC", L"VND", L"VNE", L"VNF", L"VNG", L"VNH", L"VNI", L"VNJ", L"VNK", L"VNL", L"VNM", L"VNN", L"VNO", L"VNP", L"VNQ", L"VNR", L"VNS", L"VNT", L"VNU", L"VNV", L"VNW", L"VNX", L"VNY", L"VNZ", L"VOA", L"VOB", L"VOC", L"VOD", L"VOE", L"VOF", L"VOG", L"VOH", L"VOI", L"VOJ", L"VOK", L"VOL", L"VOM", L"VON", L"VOO", L"VOP", L"VOQ", L"VOR", L"VOS", L"VOT", L"VOU", L"VOV", L"VOW", L"VOX", L"VOY", L"VOZ", L"VPA", L"VPB", L"VPC", L"VPD", L"VPE", L"VPF", L"VPG", L"VPH", L"VPI", L"VPJ", L"VPK", L"VPL", L"VPM", L"VPN", L"VPO", L"VPP", L"VPQ", L"VPR", L"VPS", L"VPT", L"VPU", L"VPV", L"VPW", L"VPX", L"VPY", L"VPZ", L"VQA", L"VQB", L"VQC", L"VQD", L"VQE", L"VQF", L"VQG", L"VQH", L"VQI", L"VQJ", L"VQK", L"VQL", L"VQM", + L"VQN", L"VQO", L"VQP", L"VQQ", L"VQR", L"VQS", L"VQT", L"VQU", L"VQV", L"VQW", L"VQX", L"VQY", L"VQZ", L"VRA", L"VRB", L"VRC", L"VRD", L"VRE", L"VRF", L"VRG", L"VRH", L"VRI", L"VRJ", L"VRK", L"VRL", L"VRM", L"VRN", L"VRO", L"VRP", L"VRQ", L"VRR", L"VRS", L"VRT", L"VRU", L"VRV", L"VRW", L"VRX", L"VRY", L"VRZ", L"VSA", L"VSB", L"VSC", L"VSD", L"VSE", L"VSF", L"VSG", L"VSH", L"VSI", L"VSJ", L"VSK", L"VSL", L"VSM", L"VSN", L"VSO", L"VSP", L"VSQ", L"VSR", L"VSS", L"VST", L"VSU", L"VSV", L"VSW", L"VSX", L"VSY", L"VSZ", L"VTA", L"VTB", L"VTC", L"VTD", L"VTE", L"VTF", L"VTG", L"VTH", L"VTI", L"VTJ", L"VTK", L"VTL", L"VTM", L"VTN", L"VTO", L"VTP", L"VTQ", L"VTR", L"VTS", L"VTT", L"VTU", L"VTV", L"VTW", L"VTX", L"VTY", L"VTZ", L"VUA", L"VUB", L"VUC", L"VUD", L"VUE", L"VUF", L"VUG", L"VUH", L"VUI", L"VUJ", L"VUK", L"VUL", L"VUM", L"VUN", L"VUO", L"VUP", L"VUQ", L"VUR", L"VUS", L"VUT", L"VUU", L"VUV", L"VUW", L"VUX", L"VUY", L"VUZ", L"VVA", L"VVB", L"VVC", L"VVD", L"VVE", L"VVF", L"VVG", L"VVH", L"VVI", L"VVJ", L"VVK", L"VVL", L"VVM", L"VVN", L"VVO", L"VVP", L"VVQ", L"VVR", L"VVS", L"VVT", L"VVU", L"VVV", L"VVW", L"VVX", L"VVY", L"VVZ", L"VWA", L"VWB", L"VWC", L"VWD", L"VWE", L"VWF", L"VWG", L"VWH", L"VWI", L"VWJ", L"VWK", L"VWL", L"VWM", L"VWN", L"VWO", L"VWP", L"VWQ", L"VWR", L"VWS", L"VWT", L"VWU", L"VWV", L"VWW", L"VWX", L"VWY", L"VWZ", L"VXA", L"VXB", L"VXC", L"VXD", L"VXE", L"VXF", L"VXG", L"VXH", L"VXI", L"VXJ", L"VXK", L"VXL", L"VXM", L"VXN", L"VXO", L"VXP", L"VXQ", L"VXR", L"VXS", L"VXT", L"VXU", L"VXV", L"VXW", L"VXX", L"VXY", L"VXZ", L"VYA", L"VYB", L"VYC", L"VYD", L"VYE", L"VYF", L"VYG", L"VYH", L"VYI", L"VYJ", L"VYK", L"VYL", L"VYM", L"VYN", L"VYO", L"VYP", L"VYQ", L"VYR", L"VYS", L"VYT", L"VYU", L"VYV", L"VYW", L"VYX", L"VYY", L"VYZ", L"VZA", L"VZB", L"VZC", L"VZD", L"VZE", L"VZF", L"VZG", L"VZH", L"VZI", L"VZJ", L"VZK", L"VZL", L"VZM", L"VZN", L"VZO", L"VZP", L"VZQ", L"VZR", L"VZS", L"VZT", L"VZU", L"VZV", L"VZW", L"VZX", L"VZY", L"VZZ", L"WAA", L"WAB", L"WAC", L"WAD", L"WAE", L"WAF", L"WAG", L"WAH", L"WAI", L"WAJ", L"WAK", L"WAL", L"WAM", L"WAN", L"WAO", L"WAP", L"WAQ", L"WAR", L"WAS", L"WAT", L"WAU", L"WAV", L"WAW", L"WAX", L"WAY", L"WAZ", + L"WBA", L"WBB", L"WBC", L"WBD", L"WBE", L"WBF", L"WBG", L"WBH", L"WBI", L"WBJ", L"WBK", L"WBL", L"WBM", L"WBN", L"WBO", L"WBP", L"WBQ", L"WBR", L"WBS", L"WBT", L"WBU", L"WBV", L"WBW", L"WBX", L"WBY", L"WBZ", L"WCA", L"WCB", L"WCC", L"WCD", L"WCE", L"WCF", L"WCG", L"WCH", L"WCI", L"WCJ", L"WCK", L"WCL", L"WCM", L"WCN", L"WCO", L"WCP", L"WCQ", L"WCR", L"WCS", L"WCT", L"WCU", L"WCV", L"WCW", L"WCX", L"WCY", L"WCZ", L"WDA", L"WDB", L"WDC", L"WDD", L"WDE", L"WDF", L"WDG", L"WDH", L"WDI", L"WDJ", L"WDK", L"WDL", L"WDM", L"WDN", L"WDO", L"WDP", L"WDQ", L"WDR", L"WDS", L"WDT", L"WDU", L"WDV", L"WDW", L"WDX", L"WDY", L"WDZ", L"WEA", L"WEB", L"WEC", L"WED", L"WEE", L"WEF", L"WEG", L"WEH", L"WEI", L"WEJ", L"WEK", L"WEL", L"WEM", L"WEN", L"WEO", L"WEP", L"WEQ", L"WER", L"WES", L"WET", L"WEU", L"WEV", L"WEW", L"WEX", L"WEY", L"WEZ", L"WFA", L"WFB", L"WFC", L"WFD", L"WFE", L"WFF", L"WFG", L"WFH", L"WFI", L"WFJ", L"WFK", L"WFL", L"WFM", L"WFN", L"WFO", L"WFP", L"WFQ", L"WFR", L"WFS", L"WFT", L"WFU", L"WFV", L"WFW", L"WFX", L"WFY", L"WFZ", L"WGA", L"WGB", L"WGC", L"WGD", L"WGE", L"WGF", L"WGG", L"WGH", L"WGI", L"WGJ", L"WGK", L"WGL", L"WGM", L"WGN", L"WGO", L"WGP", L"WGQ", L"WGR", L"WGS", L"WGT", L"WGU", L"WGV", L"WGW", L"WGX", L"WGY", L"WGZ", L"WHA", L"WHB", L"WHC", L"WHD", L"WHE", L"WHF", L"WHG", L"WHH", L"WHI", L"WHJ", L"WHK", L"WHL", L"WHM", L"WHN", L"WHO", L"WHP", L"WHQ", L"WHR", L"WHS", L"WHT", L"WHU", L"WHV", L"WHW", L"WHX", L"WHY", L"WHZ", L"WIA", L"WIB", L"WIC", L"WID", L"WIE", L"WIF", L"WIG", L"WIH", L"WII", L"WIJ", L"WIK", L"WIL", L"WIM", L"WIN", L"WIO", L"WIP", L"WIQ", L"WIR", L"WIS", L"WIT", L"WIU", L"WIV", L"WIW", L"WIX", L"WIY", L"WIZ", L"WJA", L"WJB", L"WJC", L"WJD", L"WJE", L"WJF", L"WJG", L"WJH", L"WJI", L"WJJ", L"WJK", L"WJL", L"WJM", L"WJN", L"WJO", L"WJP", L"WJQ", L"WJR", L"WJS", L"WJT", L"WJU", L"WJV", L"WJW", L"WJX", L"WJY", L"WJZ", L"WKA", L"WKB", L"WKC", L"WKD", L"WKE", L"WKF", L"WKG", L"WKH", L"WKI", L"WKJ", L"WKK", L"WKL", L"WKM", L"WKN", L"WKO", L"WKP", L"WKQ", L"WKR", L"WKS", L"WKT", L"WKU", L"WKV", L"WKW", L"WKX", L"WKY", L"WKZ", L"WLA", L"WLB", L"WLC", L"WLD", L"WLE", L"WLF", L"WLG", L"WLH", L"WLI", L"WLJ", L"WLK", L"WLL", L"WLM", + L"WLN", L"WLO", L"WLP", L"WLQ", L"WLR", L"WLS", L"WLT", L"WLU", L"WLV", L"WLW", L"WLX", L"WLY", L"WLZ", L"WMA", L"WMB", L"WMC", L"WMD", L"WME", L"WMF", L"WMG", L"WMH", L"WMI", L"WMJ", L"WMK", L"WML", L"WMM", L"WMN", L"WMO", L"WMP", L"WMQ", L"WMR", L"WMS", L"WMT", L"WMU", L"WMV", L"WMW", L"WMX", L"WMY", L"WMZ", L"WNA", L"WNB", L"WNC", L"WND", L"WNE", L"WNF", L"WNG", L"WNH", L"WNI", L"WNJ", L"WNK", L"WNL", L"WNM", L"WNN", L"WNO", L"WNP", L"WNQ", L"WNR", L"WNS", L"WNT", L"WNU", L"WNV", L"WNW", L"WNX", L"WNY", L"WNZ", L"WOA", L"WOB", L"WOC", L"WOD", L"WOE", L"WOF", L"WOG", L"WOH", L"WOI", L"WOJ", L"WOK", L"WOL", L"WOM", L"WON", L"WOO", L"WOP", L"WOQ", L"WOR", L"WOS", L"WOT", L"WOU", L"WOV", L"WOW", L"WOX", L"WOY", L"WOZ", L"WPA", L"WPB", L"WPC", L"WPD", L"WPE", L"WPF", L"WPG", L"WPH", L"WPI", L"WPJ", L"WPK", L"WPL", L"WPM", L"WPN", L"WPO", L"WPP", L"WPQ", L"WPR", L"WPS", L"WPT", L"WPU", L"WPV", L"WPW", L"WPX", L"WPY", L"WPZ", L"WQA", L"WQB", L"WQC", L"WQD", L"WQE", L"WQF", L"WQG", L"WQH", L"WQI", L"WQJ", L"WQK", L"WQL", L"WQM", L"WQN", L"WQO", L"WQP", L"WQQ", L"WQR", L"WQS", L"WQT", L"WQU", L"WQV", L"WQW", L"WQX", L"WQY", L"WQZ", L"WRA", L"WRB", L"WRC", L"WRD", L"WRE", L"WRF", L"WRG", L"WRH", L"WRI", L"WRJ", L"WRK", L"WRL", L"WRM", L"WRN", L"WRO", L"WRP", L"WRQ", L"WRR", L"WRS", L"WRT", L"WRU", L"WRV", L"WRW", L"WRX", L"WRY", L"WRZ", L"WSA", L"WSB", L"WSC", L"WSD", L"WSE", L"WSF", L"WSG", L"WSH", L"WSI", L"WSJ", L"WSK", L"WSL", L"WSM", L"WSN", L"WSO", L"WSP", L"WSQ", L"WSR", L"WSS", L"WST", L"WSU", L"WSV", L"WSW", L"WSX", L"WSY", L"WSZ", L"WTA", L"WTB", L"WTC", L"WTD", L"WTE", L"WTF", L"WTG", L"WTH", L"WTI", L"WTJ", L"WTK", L"WTL", L"WTM", L"WTN", L"WTO", L"WTP", L"WTQ", L"WTR", L"WTS", L"WTT", L"WTU", L"WTV", L"WTW", L"WTX", L"WTY", L"WTZ", L"WUA", L"WUB", L"WUC", L"WUD", L"WUE", L"WUF", L"WUG", L"WUH", L"WUI", L"WUJ", L"WUK", L"WUL", L"WUM", L"WUN", L"WUO", L"WUP", L"WUQ", L"WUR", L"WUS", L"WUT", L"WUU", L"WUV", L"WUW", L"WUX", L"WUY", L"WUZ", L"WVA", L"WVB", L"WVC", L"WVD", L"WVE", L"WVF", L"WVG", L"WVH", L"WVI", L"WVJ", L"WVK", L"WVL", L"WVM", L"WVN", L"WVO", L"WVP", L"WVQ", L"WVR", L"WVS", L"WVT", L"WVU", L"WVV", L"WVW", L"WVX", L"WVY", L"WVZ", L"WWA", L"WWB", L"WWC", L"WWD", L"WWE", L"WWF", L"WWG", L"WWH", L"WWI", L"WWJ", L"WWK", L"WWL", L"WWM", L"WWN", L"WWO", L"WWP", L"WWQ", L"WWR", L"WWS", L"WWT", L"WWU", L"WWV", L"WWW", L"WWX", L"WWY", L"WWZ", L"WXA", L"WXB", L"WXC", L"WXD", L"WXE", L"WXF", L"WXG", L"WXH", L"WXI", L"WXJ", L"WXK", L"WXL", L"WXM", L"WXN", L"WXO", L"WXP", L"WXQ", L"WXR", L"WXS", L"WXT", L"WXU", L"WXV", L"WXW", L"WXX", L"WXY", L"WXZ", L"WYA", L"WYB", L"WYC", L"WYD", L"WYE", L"WYF", L"WYG", L"WYH", L"WYI", L"WYJ", L"WYK", L"WYL", L"WYM", L"WYN", L"WYO", L"WYP", L"WYQ", L"WYR", L"WYS", L"WYT", L"WYU", L"WYV", L"WYW", L"WYX", L"WYY", L"WYZ", L"WZA", L"WZB", L"WZC", L"WZD", L"WZE", L"WZF", L"WZG", L"WZH", L"WZI", L"WZJ", L"WZK", L"WZL", L"WZM", L"WZN", L"WZO", L"WZP", L"WZQ", L"WZR", L"WZS", L"WZT", L"WZU", L"WZV", L"WZW", L"WZX", L"WZY", L"WZZ", L"XAA", L"XAB", L"XAC", L"XAD", L"XAE", L"XAF", L"XAG", L"XAH", L"XAI", L"XAJ", L"XAK", L"XAL", L"XAM", L"XAN", L"XAO", L"XAP", L"XAQ", L"XAR", L"XAS", L"XAT", L"XAU", L"XAV", L"XAW", L"XAX", L"XAY", L"XAZ", L"XBA", L"XBB", L"XBC", L"XBD", L"XBE", L"XBF", L"XBG", L"XBH", L"XBI", L"XBJ", L"XBK", L"XBL", L"XBM", L"XBN", L"XBO", L"XBP", L"XBQ", L"XBR", L"XBS", L"XBT", L"XBU", L"XBV", L"XBW", L"XBX", L"XBY", L"XBZ", L"XCA", L"XCB", L"XCC", L"XCD", L"XCE", L"XCF", L"XCG", L"XCH", L"XCI", L"XCJ", L"XCK", L"XCL", L"XCM", L"XCN", L"XCO", L"XCP", L"XCQ", L"XCR", L"XCS", L"XCT", L"XCU", L"XCV", L"XCW", L"XCX", L"XCY", L"XCZ", L"XDA", L"XDB", L"XDC", L"XDD", L"XDE", L"XDF", L"XDG", L"XDH", L"XDI", L"XDJ", L"XDK", L"XDL", L"XDM", L"XDN", L"XDO", L"XDP", L"XDQ", L"XDR", L"XDS", L"XDT", L"XDU", L"XDV", L"XDW", L"XDX", L"XDY", L"XDZ", L"XEA", L"XEB", L"XEC", L"XED", L"XEE", L"XEF", L"XEG", L"XEH", L"XEI", L"XEJ", L"XEK", L"XEL", L"XEM", L"XEN", L"XEO", L"XEP", L"XEQ", L"XER", L"XES", L"XET", L"XEU", L"XEV", L"XEW", L"XEX", L"XEY", L"XEZ", L"XFA", L"XFB", L"XFC", L"XFD" }; //------------------------------------------------------------------------------ @@ -184,14 +199,15 @@ namespace OOX return (bAbsoluteCol ? "$" : "") + getColAddressA(col) + (bAbsoluteRow ? "$" : "") + getRowAddressA(row); } //------------------------------------------------------------------------------ - static bool parseDate(const std::wstring & Date, double & Value) + static bool parseDate(const std::wstring & Date, double & Value, bool & bTime) { // for example, "1899-12-31T05:37:46.665696" + bTime = false; try { boost::wregex r(L"([\\d]+)-([\\d]+)-([\\d]+)(?:T([\\d]+):([\\d]+):([\\d]+)(?:\\.([\\d]+))?)?"); boost::match_results res; - + if (boost::regex_match(Date, res, r)) { Value = 0; @@ -237,13 +253,15 @@ namespace OOX if (Hours > 0 || Sec > 0 || Minutes > 0) { + bTime = true; + boost::posix_time::time_duration t(Hours, Minutes, 0); t += boost::posix_time::millisec(static_cast(Sec * 1000)); boost::posix_time::time_duration day(24, 0, 0); const boost::uint64_t m1 = t.total_milliseconds(); const boost::uint64_t m2 = day.total_milliseconds(); - Value += 1.0 * m1 / m2; + Value += 1.0 * m1 / m2; } return true; @@ -608,6 +626,8 @@ namespace OOX { m_oShowPhonetic.FromStringA(oReader.GetTextChar()); } + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "cm", m_oCellMetadata) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "vm", m_oValueMetadata) WritingElement_ReadAttributes_EndChar( oReader ) } @@ -681,12 +701,20 @@ namespace OOX oStream.XlsbStartRecord(nType, nLen); oStream.WriteULONG(m_nCol & 0x3FFF); - _UINT32 nStyle = m_nStyle; + _UINT32 nFlags2 = m_nStyle; if (m_oShowPhonetic.ToBool()) { - nStyle |= 0x1000000; - } - oStream.WriteULONG(nStyle); + nFlags2 |= 0x1000000; + } + //if (m_oCellMetadata.IsInit()) + //{ + // nFlags2 |= 0x2000000; + //} + //if (m_oValueMetadata.IsInit()) + //{ + // nFlags2 |= 0x4000000; + //} + oStream.WriteULONG(nFlags2); //todo RkNumber switch(nType) { @@ -714,7 +742,6 @@ namespace OOX { nFlags = m_oFormula.toXLSB(oStream, bIsBlankFormula); } - if(m_oRichText.IsInit()) { nFlags |= 0x2000; @@ -728,6 +755,15 @@ namespace OOX { m_oRichText->toXLSBExt(oStream); } + //it's not by XLSB format + //if (m_oCellMetadata.IsInit()) + //{ + // oStream.WriteULONG(*m_oCellMetadata); + //} + //if (m_oValueMetadata.IsInit()) + //{ + // oStream.WriteULONG(*m_oValueMetadata); + //} oStream.XlsbEndRecord(); } @@ -922,9 +958,16 @@ namespace OOX WritingStringNullableAttrBool(L"ca", m_oCa); WritingStringNullableAttrInt(L"si", m_oSi, m_oSi->GetValue()); WritingStringNullableAttrBool(L"bx", m_oBx); - writer.WriteString(_T(">")); - writer.WriteEncodeXmlString(m_sText); - writer.WriteString(_T("")); + if(!m_sText.empty()) + { + writer.WriteString(_T(">")); + writer.WriteEncodeXmlStringHHHH(m_sText); + writer.WriteString(_T("")); + } + else + { + writer.WriteString(_T("/>")); + } } void CFormula::fromXLSB (NSBinPptxRW::CBinaryFileReader& oStream) { @@ -1021,7 +1064,7 @@ namespace OOX auto formula = dynamic_cast(obj.get()); m_sText = formula->formula.getAssembledFormula(); m_oRef.Init(); - m_oRef = formula->rfx.toString(); + m_oRef = formula->rfx.toString(true, true); } break; case SimpleTypes::Spreadsheet::ECellFormulaType::cellformulatypeArray: @@ -1034,7 +1077,7 @@ namespace OOX m_oAca = formula->fAlwaysCalc; } m_oRef.Init(); - m_oRef = formula->rfx.toString(); + m_oRef = formula->rfx.toString(true, true); } break; case SimpleTypes::Spreadsheet::ECellFormulaType::cellformulatypeDataTable: @@ -1049,7 +1092,7 @@ namespace OOX } m_oRef.Init(); - m_oRef = dataTable->rfx.toString(); + m_oRef = dataTable->rfx.toString(true, true); if(dataTable->fRw) { @@ -1085,6 +1128,214 @@ namespace OOX } } + namespace SharedFormulasRef + { + std::unique_ptr>> sharedRefsLocations; + } + void CFormula::fromBin(XLS::StreamCacheReaderPtr& reader, XLS::CFRecordPtr& record) + { + //читаем остатки данных в записи ячейки + { + XLSB::GrbitFmla flags; + *record >> flags; + if(flags.fAlwaysCalc) + m_oAca = true; + } + + auto recordType = reader->getNextRecordType(); + recordType = reader->getNextRecordType(); + if(recordType == XLSB::rt_ShrFmla) + { + _INT32 rowRef = 0; + _INT32 ColumnRef = 0; + { + XLS::CellParsedFormula BinFmla(false); + *record >> BinFmla; + if(!BinFmla.rgce.isEmpty() && BinFmla.rgce.sequence.begin()->get()->ptg_id.get() == 1 && !BinFmla.rgcb.isEmpty()) + { + rowRef = static_cast(BinFmla.rgce.sequence.begin()->get())->rowXlsb; + ColumnRef = static_cast(BinFmla.rgcb.getPtgs().back().get())->col; + if(!SharedFormulasRef::sharedRefsLocations) + SharedFormulasRef::sharedRefsLocations = std::unique_ptr>>(new std::vector>); + SharedFormulasRef::sharedRefsLocations->push_back(std::make_pair(rowRef, ColumnRef)); + m_oSi = (unsigned int)SharedFormulasRef::sharedRefsLocations->size() - 1; + } + } + auto fmlaRecord = reader->getNextRecord(XLSB::rt_ShrFmla); + { + XLSB::UncheckedRfX fmlaRef; + *fmlaRecord >>fmlaRef; + m_oRef = fmlaRef.toString(true, true); + } + XLS::CellParsedFormula BinFmla(false); + BinFmla.rgce.cell_base_ref.column = ColumnRef; + BinFmla.rgce.cell_base_ref.row = rowRef; + *fmlaRecord >> BinFmla; + m_sText = BinFmla.getAssembledFormula(); + m_oT = SimpleTypes::Spreadsheet::ECellFormulaType::cellformulatypeShared; + return; + } + else if(recordType == XLSB::rt_ArrFmla) + { + auto fmlaRecord = reader->getNextRecord(XLSB::rt_ArrFmla); + { + XLSB::UncheckedRfX fmlaRef; + *fmlaRecord >>fmlaRef; + m_oRef = fmlaRef.toString(true, true); + } + BYTE flags; + *fmlaRecord >>flags; + if(GETBIT(flags,0)) + m_oAca = true; + XLS::CellParsedFormula BinFmla(false); + *fmlaRecord >> BinFmla; + m_sText = BinFmla.getAssembledFormula(); + m_oT = SimpleTypes::Spreadsheet::ECellFormulaType::cellformulatypeArray; + return; + } + { + XLS::CellParsedFormula BinFmla(false); + *record >> BinFmla; + //случай если в формуле есть ссылка на другую + if(!BinFmla.rgce.isEmpty() && BinFmla.rgce.sequence.begin()->get()->ptg_id.get() == 1 && !BinFmla.rgcb.isEmpty()) + { + auto rowPart = static_cast(BinFmla.rgce.sequence.begin()->get()); + auto ColumnPart = static_cast(BinFmla.rgcb.getPtgs().back().get()); + if(!SharedFormulasRef::sharedRefsLocations) + return; + for(auto i = 0; i size(); i++) + { + if(SharedFormulasRef::sharedRefsLocations->at(i).first == rowPart->rowXlsb && + SharedFormulasRef::sharedRefsLocations->at(i).second == ColumnPart->col) + { + m_oSi = i; + m_oT = SimpleTypes::Spreadsheet::ECellFormulaType::cellformulatypeShared; + } + } + } + else + m_sText = BinFmla.getAssembledFormula(); + } + + } + void CFormula::toBin(XLS::BaseObjectPtr& obj) + { + switch(m_oT->GetValue()) + { + case SimpleTypes::Spreadsheet::ECellFormulaType::cellformulatypeNormal: + { + auto formula = dynamic_cast(obj.get()); + formula->formula = m_sText; + if(!formula->formula.rgce.sequence.empty()) + { + auto lastValType = GETBITS(formula->formula.rgce.sequence.rbegin()->get()->ptg_id.get(),5,6); + if(lastValType == 1 || lastValType == 3) + { + SETBITS(formula->formula.rgce.sequence.rbegin()->get()->ptg_id.get(),5,6,2); + } + else if(formula->formula.rgce.sequence.rbegin()->get()->ptg_id.get() == 6424) + { + auto list = static_cast(formula->formula.rgce.sequence.rbegin()->get()); + list->type_ = 1; + } + } + } + break; + case SimpleTypes::Spreadsheet::ECellFormulaType::cellformulatypeShared: + { + auto formula = dynamic_cast(obj.get()); + formula->formula = m_sText; + if(m_oRef.IsInit()) + formula->rfx = m_oRef.get(); + if(!formula->formula.rgce.sequence.empty()) + { + auto lastValType = GETBITS(formula->formula.rgce.sequence.rbegin()->get()->ptg_id.get(),5,6); + if(lastValType == 1 || lastValType == 3) + { + SETBITS(formula->formula.rgce.sequence.rbegin()->get()->ptg_id.get(),5,6,2); + } + else if(formula->formula.rgce.sequence.rbegin()->get()->ptg_id.get() == 6424) + { + auto list = static_cast(formula->formula.rgce.sequence.rbegin()->get()); + list->type_ = 1; + } + } + + } + break; + case SimpleTypes::Spreadsheet::ECellFormulaType::cellformulatypeArray: + { + auto formula = dynamic_cast(obj.get()); + formula->formula = m_sText; + if(m_oAca.IsInit()) + { + formula->fAlwaysCalc = m_oAca->GetValue(); + } + if(m_oRef.IsInit()) + formula->rfx = m_oRef.get(); + if(!formula->formula.rgce.sequence.empty()) + { + auto lastValType = GETBITS(formula->formula.rgce.sequence.rbegin()->get()->ptg_id.get(),5,6); + if(lastValType == 1) + { + SETBITS(formula->formula.rgce.sequence.rbegin()->get()->ptg_id.get(),5,6,2); + } + else if(formula->formula.rgce.sequence.rbegin()->get()->ptg_id.get() == 6424) + { + auto list = static_cast(formula->formula.rgce.sequence.rbegin()->get()); + list->type_ = 1; + } + + } + } + break; + case SimpleTypes::Spreadsheet::ECellFormulaType::cellformulatypeDataTable: + { + auto dataTable = dynamic_cast(obj.get()); + + if(m_oCa.IsInit()) + { + + dataTable->fAlwaysCalc = m_oCa->GetValue(); + } + if(m_oRef.IsInit()) + { + dataTable->rfx = m_oRef.get(); + } + + if(m_oDtr.IsInit()) + { + dataTable->fRw = m_oDtr->GetValue(); + } + + if(m_oDt2D.IsInit()) + { + dataTable->fTbl2 = m_oDt2D->GetValue(); + } + + if(m_oDel1.IsInit()) + { + dataTable->fDeleted1 = m_oDel1->GetValue(); + } + + if(m_oDel2.IsInit()) + { + dataTable->fDeleted2 = m_oDel2->GetValue(); + } + + if(m_oR1.IsInit()) + { + dataTable->r1 = m_oR1.get(); + } + + if(m_oR2.IsInit()) + { + dataTable->r2 = m_oR2.get(); + } + } + break; + } + } EElementType CFormula::getType () const { return et_x_Formula; @@ -1199,8 +1450,8 @@ namespace OOX writer.WriteString(m_oType->ToString()); writer.WriteString(L"\""); } - WritingStringNullableAttrInt(L"cm", m_oCellMetadata, m_oCellMetadata->GetValue()); - WritingStringNullableAttrInt(L"vm", m_oValueMetadata, m_oValueMetadata->GetValue()); + WritingStringNullableAttrInt2(L"cm", m_oCellMetadata); + WritingStringNullableAttrInt2(L"vm", m_oValueMetadata); WritingStringNullableAttrBool(L"ph", m_oShowPhonetic); if(m_oFormula.IsInit() || m_oRichText.IsInit() || m_oValue.IsInit()) { @@ -1240,7 +1491,7 @@ namespace OOX m_oValue = oReader; else if (strcmp("Data", sName) == 0) { - CData data; + CData data(m_oFormula.IsInit()); data = oReader; m_oType = data.m_oType; @@ -1286,20 +1537,32 @@ namespace OOX const char* sName = XmlUtils::GetNameNoNS(oReader.GetNameChar()); if ( strcmp("Data", sName) == 0) { - CData data_comment; + CData data_comment(false); data_comment.fromXML2(oReader); - + pComment->m_oText = data_comment.m_oRichText.GetPointerEmptyNullable(); } } } + bool CCell::checkArrayCell(XLS::CellRef &cellref, const sharedFormula& ArrFmlas) + { + for(auto i:ArrFmlas.arrfmla) + { + if(i.first.inRange(cellref)) + { + cellref = i.second; + return true; + } + } + return false; + } void CCell::After2003Read() { CXlsxFlat* xlsx_flat = dynamic_cast(m_pMainDocument); if (!xlsx_flat) return; - + CWorksheet* sheet = xlsx_flat->m_arWorksheets.back(); - + std::map>::iterator pFindRow = sheet->m_oSheetData->m_mapStyleMerges2003.find(xlsx_flat->m_nLastReadRow); std::map::iterator pFind; @@ -1309,8 +1572,8 @@ namespace OOX } else { - int newCol = *iColIndex; - + int newCol = *iColIndex; + if (pFindRow != sheet->m_oSheetData->m_mapStyleMerges2003.end()) { CCell *pCurrentCell = sheet->m_oSheetData->m_arrItems.back()->m_arrItems.back(); // == this @@ -1383,7 +1646,37 @@ namespace OOX m_oStyle = pFind->second; } } + if (m_oType.IsInit() && (m_oType->GetValue() == SimpleTypes::Spreadsheet::celltypeDate || m_oType->GetValue() == SimpleTypes::Spreadsheet::celltypeDateTime)) + { + bool bTime = (m_oType->GetValue() == SimpleTypes::Spreadsheet::celltypeDateTime); + if (false == m_oStyle.IsInit()) + { + std::wstring tempCommonName = bTime ? L"UnsetDateTime" : L"UnsetDate"; + std::map::iterator pFind = xlsx_flat->m_pStyles->m_mapStyles2003.find(tempCommonName); + if (pFind != xlsx_flat->m_pStyles->m_mapStyles2003.end()) + { + m_oStyle = pFind->second; + } + else + { + CXfs* pCellXfs = new CXfs(); + pCellXfs->m_oApplyNumberFormat.Init(); + pCellXfs->m_oApplyNumberFormat->FromBool(true); + + pCellXfs->m_oNumFmtId = bTime ? 22 : 14; + + int iXfs = xlsx_flat->m_pStyles->m_oCellXfs->m_arrItems.size(); + + pCellXfs->m_oXfId.Init(); pCellXfs->m_oXfId->SetValue(0); + xlsx_flat->m_pStyles->m_oCellXfs->m_arrItems.push_back(pCellXfs); + xlsx_flat->m_pStyles->m_mapStyles2003.insert(std::make_pair(tempCommonName, iXfs)); + + m_oStyle = iXfs; + } + } + m_oType.reset(); + } if (sHyperlink.IsInit()) { if (false == sheet->m_oHyperlinks.IsInit()) @@ -1438,7 +1731,7 @@ namespace OOX { std::map mapColsStyle; mapColsStyle.insert(std::make_pair(xlsx_flat->m_nLastReadCol, *m_oStyle)); - + sheet->m_oSheetData->m_mapStyleMerges2003.insert(std::make_pair(xlsx_flat->m_nLastReadRow + i + 1, mapColsStyle)); } else @@ -1450,13 +1743,13 @@ namespace OOX for (int i = 0; i < iAcross.get_value_or(0); ++i) { xlsx_flat->m_nLastReadCol++; - + CCell *pCell = new CCell(this->m_pMainDocument); pCell->m_oRef = getCellAddressA(xlsx_flat->m_nLastReadRow, xlsx_flat->m_nLastReadCol); pCell->m_oStyle = pFindContinues->first; pCell->m_oCol = xlsx_flat->m_nLastReadCol - 1; pCell->m_oRow = xlsx_flat->m_nLastReadRow; - + sheet->m_oSheetData->m_arrItems.back()->m_arrItems.push_back(pCell); } } @@ -1482,10 +1775,10 @@ namespace OOX void CCell::AfterRead() { CSharedStrings *pSharedStrings = NULL; - + CXlsx* xlsx = dynamic_cast(m_pMainDocument); CXlsxFlat* xlsx_flat = dynamic_cast(m_pMainDocument); - + if (xlsx) { if (false == xlsx->m_arWorksheets.back()->m_bPrepareForBinaryWriter) return; @@ -1525,7 +1818,7 @@ namespace OOX m_oType->SetValue(SimpleTypes::Spreadsheet::celltypeSharedString); } } - else if (SimpleTypes::Spreadsheet::celltypeStr == m_oType->GetValue() || SimpleTypes::Spreadsheet::celltypeError == m_oType->GetValue()) + else if ((SimpleTypes::Spreadsheet::celltypeStr == m_oType->GetValue() || SimpleTypes::Spreadsheet::celltypeError == m_oType->GetValue()) && !m_oFormula.IsInit()) { if (m_oValue.IsInit()) { @@ -1582,13 +1875,14 @@ namespace OOX m_oRow = nRow; m_oCol = (oStream.GetULong() & 0x3FFF); - _UINT32 nStyleRef = oStream.GetULong(); - if(0 != (nStyleRef & 0xFFFFFF)) + + _UINT32 nFlags2 = oStream.GetULong(); + if (0 != (nFlags2 & 0xFFFFFF)) { - m_oStyle = (nStyleRef & 0xFFFFFF); + m_oStyle = (nFlags2 & 0xFFFFFF); } - if(0 != (nStyleRef & 0x1000000)) + if (0 != (nFlags2 & 0x1000000)) { m_oShowPhonetic.Init(); m_oShowPhonetic->FromBool(true); @@ -1673,112 +1967,765 @@ namespace OOX m_oRichText.Init(); m_oRichText->fromXLSBExt(oStream); } - + if (0 != (nFlags2 & 0x2000000)) + { + m_oCellMetadata = oStream.GetULong(); + } + if (0 != (nFlags2 & 0x4000000)) + { + m_oValueMetadata = oStream.GetULong(); + } oStream.Seek(nEnd); } - void CCell::fromBin(XLS::BaseObjectPtr& obj) - { - ReadAttributes(obj); - } - void CCell::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + XLS::BaseObjectPtr CCell::toBin(sharedFormula &sharedFormulas) { - WritingElement_ReadAttributes_StartChar( oReader ) - - if (strcmp("r", wsName) == 0) + std::vector shared_formulas_locations_ref; + auto ptr(new XLSB::CELL(0, shared_formulas_locations_ref)); + if(m_oRow.IsInit()) + { + ptr->m_Row = m_oRow.get(); + } + XLS::BaseObjectPtr objectPtr(ptr); + if((m_oCellMetadata.IsInit() || m_oValueMetadata.IsInit())) + { + auto pCellMeta(new XLSB::CELLMETA); + ptr->m_CELLMETA = XLS::BaseObjectPtr{pCellMeta}; + if(m_oCellMetadata.IsInit()) { - m_oRef = oReader.GetTextA(); + auto metadata(new XLSB::CellMeta); + pCellMeta->m_BrtCellMeta = XLS::BaseObjectPtr{metadata}; + metadata->icmb = *m_oCellMetadata; } - else if (strcmp("ss:Formula", wsName) == 0) + + if(m_oValueMetadata.IsInit()) { - m_oFormula.Init(); - m_oFormula->m_sText = oReader.GetText(); - m_oFormula->m_sText = m_oFormula->m_sText.substr(1); - //convert R1C1 to .. + auto metadata(new XLSB::ValueMeta); + pCellMeta->m_BrtValueMeta = XLS::BaseObjectPtr{metadata}; + metadata->ivmb = *m_oValueMetadata; } - WritingElement_ReadAttributes_Read_else_ifChar ( oReader, "ss:Index", iColIndex ) - WritingElement_ReadAttributes_Read_else_ifChar ( oReader, "ss:MergeAcross", iAcross ) - WritingElement_ReadAttributes_Read_else_ifChar ( oReader, "ss:MergeDown", iDown ) - WritingElement_ReadAttributes_Read_else_ifChar ( oReader, "ss:ArrayRange", sArrayRange ) - WritingElement_ReadAttributes_Read_else_ifChar ( oReader, "ss:StyleID", sStyleId ) - WritingElement_ReadAttributes_Read_else_ifChar ( oReader, "ss:HRef", sHyperlink ) - - WritingElement_ReadAttributes_Read_else_ifChar ( oReader, "s", m_oStyle ) - WritingElement_ReadAttributes_Read_else_ifChar ( oReader, "t", m_oType ) - WritingElement_ReadAttributes_Read_else_ifChar ( oReader, "cm", m_oCellMetadata ) - WritingElement_ReadAttributes_Read_else_ifChar ( oReader, "vm", m_oValueMetadata ) - WritingElement_ReadAttributes_Read_else_ifChar ( oReader, "ph", m_oShowPhonetic ) - - WritingElement_ReadAttributes_EndChar( oReader ) - - } - void CCell::ReadAttributes(BaseObjectPtr& obj) - { - auto ptr = static_cast(obj.get()); - if(ptr != nullptr) - { - m_oRow = ptr->m_Row; - auto pCELLMETA = static_cast(ptr->m_CELLMETA.get()); - if(pCELLMETA != nullptr) - { - auto pCellMeta = static_cast(pCELLMETA->m_BrtCellMeta.get()); - if(pCellMeta != nullptr && pCellMeta->icmb) - m_oCellMetadata = pCellMeta->icmb; - - auto pValueMeta = static_cast(pCELLMETA->m_BrtValueMeta.get()); - if(pValueMeta != nullptr && pValueMeta->ivmb) - m_oValueMetadata = pValueMeta->ivmb; - } + } - XLSB::DATACELL* pDATACELL = nullptr; - XLSB::TABLECELL* pTABLECELL = nullptr; - XLSB::FMLACELL* pFMLACELL = nullptr; - XLSB::SHRFMLACELL* pSHRFMLACELL = nullptr; + XLSB::DATACELL* pDATACELL = nullptr; + XLSB::TABLECELL* pTABLECELL = nullptr; + XLSB::FMLACELL* pFMLACELL = nullptr; + XLSB::SHRFMLACELL* pSHRFMLACELL = nullptr; + BiffRecord* pSource = nullptr; + XLSB::Cell* oCell; + bool isReal = false; + _INT32 intCache = 0; + double realCache = 0; - switch(ptr->m_source->get_type()) - { - case XLS::typeDATACELL: - pDATACELL = static_cast(ptr->m_source.get()); - break; - case XLS::typeTABLECELL: - pTABLECELL = static_cast(ptr->m_source.get()); - break; - case XLS::typeFMLACELL: - pFMLACELL = static_cast(ptr->m_source.get()); - break; - case XLS::typeSHRFMLACELL: - pSHRFMLACELL = static_cast(ptr->m_source.get()); - pFMLACELL = static_cast(pSHRFMLACELL->_fmlacell.get()); - break; - } + XLS::CellRef cellref; + if(m_oRow.IsInit() && m_oCol.IsInit()) + cellref = XLS::CellRef(m_oRow.get() -1, m_oCol.get(), 0, 0); + else if(m_oRef.IsInit()) + { + std::wstring wstringRef(m_oRef.get().begin(), m_oRef.get().end()); + cellref = XLS::CellRef(wstringRef); + } + else + cellref = XLS::CellRef(0, 0, 0, 0); + auto sourceCellRef = cellref; + if(!sharedFormulas.arrfmla.empty()) + { + if(checkArrayCell(sourceCellRef, sharedFormulas)) + { + if(!m_oFormula.IsInit() || m_oFormula->m_sText.empty()) + { + m_oFormula.Init(); + m_oFormula->m_oT = SimpleTypes::Spreadsheet::cellformulatypeArray; + } + } + } - if(pDATACELL != nullptr || pTABLECELL != nullptr || pFMLACELL != nullptr) - { - BiffRecord* pSource = nullptr; - XLSB::Cell oCell; - if(pDATACELL != nullptr) - { - m_oCol = pDATACELL->m_Col; - pSource = static_cast(pDATACELL->m_source.get()); - if(pSource != nullptr) - oCell = dynamic_cast(pSource)->cell; - } - else if(pTABLECELL != nullptr) - { - m_oCol = pTABLECELL->m_Col; - pSource = static_cast(pTABLECELL->m_source.get()); - if(pSource != nullptr) - oCell = dynamic_cast(pSource)->cell; - if(pTABLECELL->m_BrtTable != nullptr) - { - m_oFormula.Init(); - m_oFormula->fromBin(pTABLECELL->m_BrtTable, SimpleTypes::Spreadsheet::cellformulatypeDataTable); - } - } - else if(pFMLACELL != nullptr) - { - m_oCol = pFMLACELL->m_Col; - pSource = static_cast(pFMLACELL->m_source.get()); + if(!m_oType.IsInit()) + { + m_oType.Init(); + m_oType->SetValue(SimpleTypes::Spreadsheet::celltypeStr); + if(m_oValue.IsInit()) + { + if(m_oValue->m_sText == L"TRUE" || m_oValue->m_sText == L"FALSE") + m_oType->SetValue(SimpleTypes::Spreadsheet::celltypeBool); + else if(std::all_of(m_oValue->m_sText.begin(), m_oValue->m_sText.end(), [](const char c) { return std::isdigit(c); }) && m_oValue->m_sText.size() <= 10 && m_oValue->m_sText.size() > 0) + { + if(m_oValue->m_sText.size() < 10 ) + { + intCache = std::stoi(m_oValue->m_sText); + m_oType->SetValue(SimpleTypes::Spreadsheet::celltypeNumber); + } + else if(m_oValue->m_sText.size() == 10) + { + _INT64 tempVal = std::stoll(m_oValue->m_sText); + if(tempVal < MAXINT32 && tempVal > MININT32) + { + intCache = tempVal; + m_oType->SetValue(SimpleTypes::Spreadsheet::celltypeNumber); + } + } + } + + if((m_oValue->m_sText.find(L".") == std::string::npos || m_oValue->m_sText.find(L".") == m_oValue->m_sText.rfind(L".")) + && m_oValue->m_sText.size() <=17 && m_oValue->m_sText.size() > 0) + { + if(m_oValue->m_sText.size() < 17) + { + wchar_t *tail; + double tempVal = std::wcstod(m_oValue->m_sText.c_str(), &tail); + if(*tail == L'\0') + { + m_oType->SetValue(SimpleTypes::Spreadsheet::celltypeNumber); + isReal = true; + realCache = tempVal; + } + } + else + { + wchar_t *tail; + long double tempVal = std::wcstold(m_oValue->m_sText.c_str(), &tail); + if(*tail == L'\0') + if(tempVal <= DBL_MAX && tempVal >= -DBL_MAX) + { + m_oType->SetValue(SimpleTypes::Spreadsheet::celltypeNumber); + realCache = tempVal; + isReal = true; + } + } + } + else if((m_oValue->m_sText.find(L"E") == std::string::npos || m_oValue->m_sText.find(L"E") == m_oValue->m_sText.rfind(L"E"))) + { + wchar_t *tail; + long double tempVal = std::wcstold(m_oValue->m_sText.c_str(), &tail); + if(*tail == L'\0') + if(tempVal <= DBL_MAX && tempVal >= -DBL_MAX) + { + m_oType->SetValue(SimpleTypes::Spreadsheet::celltypeNumber); + realCache = tempVal; + isReal = true; + } + } + + } + } + switch (m_oType->GetValue()) + { + case SimpleTypes::Spreadsheet::celltypeNumber: + { + if(!isReal) + { + if(!m_oFormula.IsInit()) + { + auto pCellRk = new(XLSB::CellRk); + pCellRk->value.fInt = 1; + pCellRk->value.fX100 = 0; + pCellRk->value.num = intCache; + oCell = &pCellRk->cell; + pSource = pCellRk; + } + else + { + auto pCellRk = new(XLSB::FmlaNum); + if(m_oFormula->m_oAca.IsInit()) + pCellRk->grbitFlags.fAlwaysCalc = m_oFormula->m_oAca->GetValue(); + else + pCellRk->grbitFlags.fAlwaysCalc = false; + pCellRk->value.data.value = intCache; + oCell = &pCellRk->cell; + pSource = pCellRk; + } + + + + } + else if(isReal) + { + if(!m_oFormula.IsInit()) + { + auto pCellReal = new(XLSB::CellReal); + + pCellReal->value.data.value = realCache; + + oCell = &pCellReal->cell; + pSource = pCellReal; + } + else + { + auto pCellRk = new(XLSB::FmlaNum); + + pCellRk->value.data.value = realCache; + oCell = &pCellRk->cell; + pSource = pCellRk; + if(m_oFormula->m_oAca.IsInit()) + pCellRk->grbitFlags.fAlwaysCalc = m_oFormula->m_oAca->GetValue(); + else + pCellRk->grbitFlags.fAlwaysCalc = false; + } + } + } + break; + case SimpleTypes::Spreadsheet::celltypeError: + { + if(!m_oValue.IsInit()) + { + auto error = new XLSB::CellError; + error->value = 0x00; + oCell = &error->cell; + pSource = error; + } + else if (m_oValue->m_sText == L"#NULL!") + { if(m_oFormula.IsInit()) + { + auto error = new XLSB::FmlaError; + error->value = 0x00; + oCell = &error->cell; + pSource = error; + } + else + { + auto error = new XLSB::CellError; + error->value = 0x00; + oCell = &error->cell; + pSource = error; + } + } + else if (m_oValue->m_sText == L"#DIV/0!") + { + if(m_oFormula.IsInit()) + { + auto error = new XLSB::FmlaError; + error->value = 0x07; + oCell = &error->cell; + pSource = error; + } + else + { + auto error = new XLSB::CellError; + error->value = 0x07; + oCell = &error->cell; + pSource = error; + } + } + else if (m_oValue->m_sText == L"#REF!") + { + if(m_oFormula.IsInit()) + { + auto error = new XLSB::FmlaError; + error->value = 0x17; + oCell = &error->cell; + pSource = error; + } + else + { + auto error = new XLSB::CellError; + error->value = 0x17; + oCell = &error->cell; + pSource = error; + } + } + else if (m_oValue->m_sText == L"#NAME?") + { + if(m_oFormula.IsInit()) + { + auto error = new XLSB::FmlaError; + error->value = 0x1D; + oCell = &error->cell; + pSource = error; + } + else + { + auto error = new XLSB::CellError; + error->value = 0x1D; + oCell = &error->cell; + pSource = error; + } + } + else if (m_oValue->m_sText == L"#NUM!") + { + if(m_oFormula.IsInit()) + { + auto error = new XLSB::FmlaError; + error->value = 0x24; + oCell = &error->cell; + pSource = error; + } + else + { + auto error = new XLSB::CellError; + error->value = 0x24; + oCell = &error->cell; + pSource = error; + } + } + else if (m_oValue->m_sText == L"#N/A") + { + if(m_oFormula.IsInit()) + { + auto error = new XLSB::FmlaError; + error->value = 0x2A; + oCell = &error->cell; + pSource = error; + } + else + { + auto error = new XLSB::CellError; + error->value = 0x2A; + oCell = &error->cell; + pSource = error; + } + } + else if (m_oValue->m_sText == L"#GETTING_DATA") + { + if(m_oFormula.IsInit()) + { + auto error = new XLSB::FmlaError; + error->value = 0x2B; + oCell = &error->cell; + pSource = error; + } + else + { + auto error = new XLSB::CellError; + error->value = 0x2B; + oCell = &error->cell; + pSource = error; + } + } + else if (m_oValue->m_sText == L"#VALUE!") + { + if(m_oFormula.IsInit()) + { + auto error = new XLSB::FmlaError; + error->value = 0x0F; + oCell = &error->cell; + pSource = error; + } + else + { + auto error = new XLSB::CellError; + error->value = 0x0F; + oCell = &error->cell; + pSource = error; + } + } + else + { + if(m_oFormula.IsInit()) + { + auto error = new XLSB::FmlaError; + error->value = 0x0F; + oCell = &error->cell; + pSource = error; + } + else + { + auto error = new XLSB::CellError; + error->value = 0x0F; + oCell = &error->cell; + pSource = error; + } + } + } + break; + case SimpleTypes::Spreadsheet::celltypeBool: + { + if(m_oFormula.IsInit()) + { + auto cellBool(new XLSB::FmlaBool); + cellBool->value = m_oValue->m_sText == L"1" ? true : false; + oCell = &cellBool->cell; + pSource = cellBool; + } + else + { + auto cellBool(new XLSB::CellBool); + cellBool->value = m_oValue->m_sText == L"1" ? true : false; + oCell = &cellBool->cell; + pSource = cellBool; + } + } + break; + case SimpleTypes::Spreadsheet::celltypeSharedString: + { + if(m_oValue.IsInit() && !m_oFormula.IsInit()) + { + auto pCellIsst(new XLSB::CellIsst); + pCellIsst->value = std::stoi(m_oValue->m_sText); + oCell = &pCellIsst->cell; + pSource = pCellIsst; + } + else if(m_oFormula.IsInit()) + { + auto str(new XLSB::FmlaString); + str->value = L""; + oCell = &str->cell; + pSource = str; + if(m_oFormula->m_oAca.IsInit()) + str->grbitFlags.fAlwaysCalc = m_oFormula->m_oAca->GetValue(); + else + str->grbitFlags.fAlwaysCalc = false; + + } + else + { + auto pCellblank = new(XLSB::CellBlank); + oCell = &pCellblank->cell; + oCell->fPhShow = false; + pSource = pCellblank; + } + } + break; + case SimpleTypes::Spreadsheet::celltypeInlineStr: + case SimpleTypes::Spreadsheet::celltypeStr: + { + if(m_oValue.IsInit()) + { + if(m_oFormula.IsInit()) + { + auto str(new XLSB::FmlaString); + if(m_oValue.IsInit()) + str->value = m_oValue->m_sText; + oCell = &str->cell; + if(m_oFormula->m_oAca.IsInit()) + str->grbitFlags.fAlwaysCalc = m_oFormula->m_oAca->GetValue(); + else + str->grbitFlags.fAlwaysCalc = false; + pSource = str; + + } + else + { + auto str(new XLSB::CellSt); + if(m_oValue.IsInit()) + str->value = m_oValue->m_sText; + oCell = &str->cell; + pSource = str; + } + } + else if(m_oRichText.IsInit()) + { + if(m_oFormula.IsInit()) + { + auto str(new XLSB::FmlaString); + if(m_oValue.IsInit()) + str->value = m_oRichText->ToString(); + oCell = &str->cell; + if(m_oFormula->m_oAca.IsInit()) + str->grbitFlags.fAlwaysCalc = m_oFormula->m_oAca->GetValue(); + else + str->grbitFlags.fAlwaysCalc = false; + pSource = str; + + } + else + { + auto str(new XLSB::CellSt); + str->value = m_oRichText->ToString(); + oCell = &str->cell; + pSource = str; + } + } + else if(m_oFormula.IsInit()) + { + auto str(new XLSB::FmlaString); + str->value = L""; + oCell = &str->cell; + if(m_oFormula->m_oAca.IsInit()) + str->grbitFlags.fAlwaysCalc = m_oFormula->m_oAca->GetValue(); + else + str->grbitFlags.fAlwaysCalc = false; + pSource = str; + } + else + { + auto pCellblank = new(XLSB::CellBlank); + oCell = &pCellblank->cell; + oCell->fPhShow = false; + pSource = pCellblank; + } + } + break; + } + + if(!m_oFormula.IsInit()) + { + pDATACELL = new(XLSB::DATACELL); + ptr->m_source = XLS::BaseObjectPtr{pDATACELL}; + pDATACELL->m_source = XLS::BaseObjectPtr{pSource}; + } + else + { + if(!m_oFormula->m_oT.IsInit()) + { + m_oFormula->m_oT.Init(); + m_oFormula->m_oT = SimpleTypes::Spreadsheet::cellformulatypeNormal; + } + if(m_oFormula->m_oT.get() == SimpleTypes::Spreadsheet::cellformulatypeDataTable) + { + pTABLECELL = new(XLSB::TABLECELL); + ptr->m_source = XLS::BaseObjectPtr{pTABLECELL}; + pTABLECELL->m_source = XLS::BaseObjectPtr{pSource}; + auto table(new XLSB::Table); + pTABLECELL->m_BrtTable = XLS::BaseObjectPtr{table}; + m_oFormula->toBin(pTABLECELL->m_BrtTable); + + } + else + { + std::vector refs; + pFMLACELL = new XLSB::FMLACELL(0, refs); + + if(m_oFormula->m_oT.get() == SimpleTypes::Spreadsheet::cellformulatypeNormal) + { + ptr->m_source = XLS::BaseObjectPtr{pFMLACELL}; + pFMLACELL->m_source = XLS::BaseObjectPtr{pSource}; + m_oFormula->toBin(pFMLACELL->m_source); + } + if(m_oFormula->m_oT.get() == SimpleTypes::Spreadsheet::cellformulatypeShared) + { + + pSHRFMLACELL = new XLSB::SHRFMLACELL(0,0, refs); + ptr->m_source = XLS::BaseObjectPtr{pSHRFMLACELL}; + pFMLACELL->m_source = XLS::BaseObjectPtr{pSource}; + pSHRFMLACELL->_fmlacell = XLS::BaseObjectPtr{pFMLACELL}; + + if(!m_oFormula->m_sText.empty()) + { + auto shrFmla(new XLSB::ShrFmla(cellref)); + pSHRFMLACELL->m_source = XLS::BaseObjectPtr{shrFmla}; + m_oFormula->toBin(pSHRFMLACELL->m_source); + + sharedFormulas.shrFmla.push_back(cellref); + + } + if(m_oFormula->m_oSi.IsInit() && sharedFormulas.shrFmla.size() > m_oFormula->m_oSi->GetValue() ) + { + sourceCellRef = sharedFormulas.shrFmla[m_oFormula->m_oSi->GetValue()]; + } + + auto rowPos = new XLS::PtgExp; + rowPos->rowXlsb = sourceCellRef.row; + auto colPos = new XLS::PtgExtraCol; + colPos->col = sourceCellRef.column; + auto cellFmla = dynamic_cast(pSource); + cellFmla->formula.rgce.addPtg(PtgPtr{rowPos}); + cellFmla->formula.rgcb.addPtg(PtgPtr{colPos}); + + + } + else if(m_oFormula->m_oT.get() == SimpleTypes::Spreadsheet::cellformulatypeArray) + { + pSHRFMLACELL = new XLSB::SHRFMLACELL(0,0, refs); + ptr->m_source = XLS::BaseObjectPtr{pSHRFMLACELL}; + pSHRFMLACELL->_fmlacell = XLS::BaseObjectPtr{pFMLACELL}; + pFMLACELL->m_source = XLS::BaseObjectPtr{pSource}; + if(!m_oFormula->m_sText.empty()) + { + auto arrfmla(new XLSB::ArrFmla(XLS::CellRef())); + pSHRFMLACELL->m_source = XLS::BaseObjectPtr{arrfmla}; + m_oFormula->toBin(pSHRFMLACELL->m_source); + + auto rowPos = new XLS::PtgExp; + rowPos->rowXlsb = cellref.row; + auto colPos = new XLS::PtgExtraCol; + colPos->col = cellref.column; + auto cellFmla = dynamic_cast(pSource); + cellFmla->formula.rgce.addPtg(PtgPtr{rowPos}); + cellFmla->formula.rgcb.addPtg(PtgPtr{colPos}); + if(m_oFormula->m_oRef.IsInit()) + { + XLS::CellRangeRef arrRange(m_oFormula->m_oRef.get()); + sharedFormulas.arrfmla.push_back(std::make_pair(arrRange, cellref)); + } + } + else + { + auto rowPos = new XLS::PtgExp; + rowPos->rowXlsb = sourceCellRef.row; + auto colPos = new XLS::PtgExtraCol; + colPos->col = sourceCellRef.column; + auto cellFmla = dynamic_cast(pSource); + cellFmla->formula.rgce.addPtg(PtgPtr{rowPos}); + cellFmla->formula.rgcb.addPtg(PtgPtr{colPos}); + } + + } + + } + } + + oCell->column = cellref.column; + if(m_oShowPhonetic.IsInit()) + oCell->fPhShow = m_oShowPhonetic->GetValue(); + else + oCell->fPhShow = false; + if(m_oStyle.IsInit()) + oCell->iStyleRef = m_oStyle.get(); + else + oCell->iStyleRef = 0; + return objectPtr; + } + void CCell::fromBin(XLS::BaseObjectPtr& obj) + { + ReadAttributes(obj); + } + bool CCell::fromBin(XLS::StreamCacheReaderPtr& reader) + { + auto recordType = reader->getNextRecordType(); + if(recordType == XLSB::rt_Table) + { + ReadTableBinPart(reader); + recordType = reader->getNextRecordType(); + } + if(recordType == XLSB::rt_CellMeta) + { + auto metaRecord = reader->getNextRecord(XLSB::rt_CellMeta); + _INT32 metavalue; + *metaRecord >> metavalue; + m_oCellMetadata = metavalue; + recordType = reader->getNextRecordType(); + } + if(recordType == XLSB::rt_ValueMeta) + { + auto metaRecord = reader->getNextRecord(XLSB::rt_ValueMeta); + _INT32 metavalue; + *metaRecord >> metavalue; + m_oValueMetadata = metavalue; + recordType = reader->getNextRecordType(); + } + if(recordType >= XLSB::rt_CellBlank && recordType <= XLSB::rt_CellIsst) + { + auto cellRecord = reader->getNextRecord(recordType); + ReadCellInfo(cellRecord); + ReadValue(cellRecord, recordType); + + } + else if(recordType >= XLSB::rt_FmlaString && recordType <= XLSB::rt_FmlaError) + { + auto cellRecord = reader->getNextRecord(recordType); + ReadCellInfo(cellRecord); + ReadValue(cellRecord, recordType); + m_oFormula.Init(); + m_oFormula->fromBin(reader, cellRecord); + } + else + return false; + recordType = reader->getNextRecordType(); + if(recordType == XLSB::rt_FRTBegin) + { + reader->SkipRecord(false); + recordType = reader->getNextRecordType(); + reader->SkipRecord(false); + } + return true; + } + void CCell::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + std::wstring sFormula; + + WritingElement_ReadAttributes_StartChar( oReader ) + + if (strcmp("r", wsName) == 0) + { + m_oRef = oReader.GetTextA(); + std::wstring wstringRef(m_oRef.get().begin(), m_oRef.get().end()); + XLS::CellRef cellref = XLS::CellRef(wstringRef); + m_oCol = cellref.column; + m_oRow = cellref.row; + } + else if (strcmp("ss:Formula", wsName) == 0) + { + sFormula = oReader.GetText(); + } + WritingElement_ReadAttributes_Read_else_ifChar ( oReader, "ss:Index", iColIndex ) + WritingElement_ReadAttributes_Read_else_ifChar ( oReader, "ss:MergeAcross", iAcross ) + WritingElement_ReadAttributes_Read_else_ifChar ( oReader, "ss:MergeDown", iDown ) + WritingElement_ReadAttributes_Read_else_ifChar ( oReader, "ss:ArrayRange", sArrayRange ) + WritingElement_ReadAttributes_Read_else_ifChar ( oReader, "ss:StyleID", sStyleId ) + WritingElement_ReadAttributes_Read_else_ifChar ( oReader, "ss:HRef", sHyperlink ) + + WritingElement_ReadAttributes_Read_else_ifChar ( oReader, "s", m_oStyle ) + WritingElement_ReadAttributes_Read_else_ifChar ( oReader, "t", m_oType ) + WritingElement_ReadAttributes_Read_else_ifChar ( oReader, "cm", m_oCellMetadata ) + WritingElement_ReadAttributes_Read_else_ifChar ( oReader, "vm", m_oValueMetadata ) + WritingElement_ReadAttributes_Read_else_ifChar ( oReader, "ph", m_oShowPhonetic ) + + WritingElement_ReadAttributes_EndChar( oReader ) + + if (false == sFormula.empty()) + { + m_oFormula.Init(); + m_oFormula->m_sText = sFormula; + m_oFormula->m_sText = m_oFormula->m_sText.substr(1); + } + } + void CCell::ReadAttributes(BaseObjectPtr& obj) + { + auto ptr = static_cast(obj.get()); + if(ptr != nullptr) + { + m_oRow = ptr->m_Row; + auto pCELLMETA = static_cast(ptr->m_CELLMETA.get()); + if(pCELLMETA != nullptr) + { + auto pCellMeta = static_cast(pCELLMETA->m_BrtCellMeta.get()); + if(pCellMeta != nullptr && pCellMeta->icmb) + m_oCellMetadata = pCellMeta->icmb; + + auto pValueMeta = static_cast(pCELLMETA->m_BrtValueMeta.get()); + if(pValueMeta != nullptr && pValueMeta->ivmb) + m_oValueMetadata = pValueMeta->ivmb; + } + + XLSB::DATACELL* pDATACELL = nullptr; + XLSB::TABLECELL* pTABLECELL = nullptr; + XLSB::FMLACELL* pFMLACELL = nullptr; + XLSB::SHRFMLACELL* pSHRFMLACELL = nullptr; + + switch(ptr->m_source->get_type()) + { + case XLS::typeDATACELL: + pDATACELL = static_cast(ptr->m_source.get()); + break; + case XLS::typeTABLECELL: + pTABLECELL = static_cast(ptr->m_source.get()); + break; + case XLS::typeFMLACELL: + pFMLACELL = static_cast(ptr->m_source.get()); + break; + case XLS::typeSHRFMLACELL: + pSHRFMLACELL = static_cast(ptr->m_source.get()); + pFMLACELL = static_cast(pSHRFMLACELL->_fmlacell.get()); + break; + } + + + if(pDATACELL != nullptr || pTABLECELL != nullptr || pFMLACELL != nullptr) + { + BiffRecord* pSource = nullptr; + XLSB::Cell oCell; + if(pDATACELL != nullptr) + { + m_oCol = pDATACELL->m_Col; + pSource = static_cast(pDATACELL->m_source.get()); + if(pSource != nullptr) + oCell = dynamic_cast(pSource)->cell; + } + else if(pTABLECELL != nullptr) + { + m_oCol = pTABLECELL->m_Col; + pSource = static_cast(pTABLECELL->m_source.get()); + if(pSource != nullptr) + oCell = dynamic_cast(pSource)->cell; + if(pTABLECELL->m_BrtTable != nullptr) + { + m_oFormula.Init(); + m_oFormula->fromBin(pTABLECELL->m_BrtTable, SimpleTypes::Spreadsheet::cellformulatypeDataTable); + } + } + else if(pFMLACELL != nullptr) + { + m_oCol = pFMLACELL->m_Col; + pSource = static_cast(pFMLACELL->m_source.get()); if(pSource != nullptr) oCell = dynamic_cast(pSource)->cell; if(pFMLACELL->m_source != nullptr) @@ -1813,7 +2760,7 @@ namespace OOX } - auto wRef = XLSB::RgceLoc(m_oRow.get(), m_oCol.get(), true, true).toString(); + auto wRef = XLSB::RgceLoc(m_oRow.get(), m_oCol.get(), true, true).toString(true); m_oRef = std::string(wRef.begin(), wRef.end()); if(pSource != nullptr) @@ -1905,7 +2852,146 @@ namespace OOX } } } - } + } + } + void CCell::ReadTableBinPart(XLS::StreamCacheReaderPtr& reader) + { + auto cellRecord = reader->getNextRecord(XLSB::rt_Table); + m_oFormula.Init(); + m_oFormula->m_oT.Init(); + m_oFormula->m_oT->SetValue(SimpleTypes::Spreadsheet::ECellFormulaType::cellformulatypeDataTable); + { + XLS::RFX ref; + *cellRecord >> ref; + m_oFormula->m_oRef = ref.toString(); + } + { + UncheckedRw rwInput1; + UncheckedCol colInput1; + UncheckedRw rwInput2; + UncheckedCol colInput2; + BYTE flags; + *cellRecord >> rwInput1 >> colInput1 >> rwInput2 >> colInput2 >> flags; + + if(GETBIT(flags, 0)) + m_oFormula->m_oDtr = true; + if(GETBIT(flags, 1)) + { + m_oFormula->m_oDt2D = true; + rwInput2 = colInput2 = 0; + } + if(GETBIT(flags, 2)) + { + m_oFormula->m_oDel1 = true; + rwInput1 = colInput1 = 0; + } + if(GETBIT(flags, 3)) + { + m_oFormula->m_oDel2 = true; + rwInput2 = colInput2 = 0; + } + if(GETBIT(flags, 4)) + m_oFormula->m_oAca = true; + + m_oFormula->m_oR1 = static_cast(CellRef(rwInput1, colInput1, true, true)); + m_oFormula->m_oR2 = static_cast(CellRef(rwInput2, colInput2, true, true)); + } + } + void CCell::ReadCellInfo(XLS::CFRecordPtr& record) + { + { + _INT32 col; + *record >> col; + m_oCol = col; + } + _UINT32 flags; + *record >> flags; + if(GETBITS(flags, 0, 23)) + m_oStyle = GETBITS(flags, 0, 23); + if(GETBIT(flags, 24)) + m_oShowPhonetic = true; + } + void CCell::ReadValue(XLS::CFRecordPtr& record, XLS::CFRecordType::TypeId typeId) + { + switch(typeId) + { + case XLSB::rt_CellBlank: + break; + case XLSB::rt_CellRk: + { + m_oValue.Init(); + XLS::RkNumber number; + *record >> number; + m_oValue->m_sText = number.value(); + break; + } + case XLSB::rt_FmlaNum: + case XLSB::rt_CellReal: + { + m_oValue.Init(); + XLS::Xnum number; + *record >> number; + m_oValue->m_sText = OOX::Spreadsheet::SpreadsheetCommon::WriteDouble(number.data.value); + break; + } + case XLSB::rt_CellIsst: + { + m_oType.Init(); + m_oType->SetValue(SimpleTypes::Spreadsheet::celltypeSharedString); + m_oValue.Init(); + + _UINT32 number; + *record >> number; + m_oValue->m_sText = std::to_wstring(number); + break; + } + case XLSB::rt_FmlaString: + case XLSB::rt_CellSt: + { + m_oType.Init(); + m_oType->SetValue(XLSB::rt_CellSt == typeId ? SimpleTypes::Spreadsheet::celltypeInlineStr : SimpleTypes::Spreadsheet::celltypeStr); + m_oValue.Init(); + + XLSB::XLWideString wstr; + *record >> wstr; + m_oValue->m_sText = wstr; + break; + } + case XLSB::rt_FmlaBool: + case XLSB::rt_CellBool: + { + m_oType.Init(); + m_oType->SetValue(SimpleTypes::Spreadsheet::celltypeBool); + m_oValue.Init(); + BYTE value; + *record >> value; + m_oValue->m_sText = value ? L"1" : L"0"; + break; + } + case XLSB::rt_FmlaError: + case XLSB::rt_CellError: + { + BYTE errCode; + *record >> errCode; + m_oType.Init(); + m_oType->SetValue(SimpleTypes::Spreadsheet::celltypeError); + m_oValue.Init(); + switch(errCode) + { + case 0x00: m_oValue->m_sText = L"#NULL!"; break; + case 0x07: m_oValue->m_sText = L"#DIV/0!"; break; + case 0x0F: m_oValue->m_sText = L"#VALUE!"; break; + case 0x17: m_oValue->m_sText = L"#REF!"; break; + case 0x1D: m_oValue->m_sText = L"#NAME?"; break; + case 0x24: m_oValue->m_sText = L"#NUM!"; break; + case 0x2A: m_oValue->m_sText = L"#N/A"; break; + case 0x2B: m_oValue->m_sText = L"#GETTING_DATA"; break; + } + break; + } + default: + break; + } } EElementType CCell::getType () const { @@ -1951,7 +3037,7 @@ namespace OOX if (parseRefA(m_oRef->c_str(), nRow, nCol)) { bRes = true; - nRow--; + //nRow--; nCol--; } } @@ -2016,7 +3102,7 @@ namespace OOX return bRes; } - CData::CData() + CData::CData(bool bFormulaPresent) : bFormula(bFormulaPresent) { } CData::~CData() @@ -2048,16 +3134,19 @@ namespace OOX { ReadAttributes( oReader ); - if(SimpleTypes::Spreadsheet::celltypeStr != m_oType->GetValue()) + if (SimpleTypes::Spreadsheet::celltypeStr != m_oType->GetValue() || bFormula) { m_oValue = oReader; if (SimpleTypes::Spreadsheet::celltypeDate == m_oType->GetValue()) { double value = 0; - if (parseDate(m_oValue->m_sText, value)) + bool bTime = false; + if (parseDate(m_oValue->m_sText, value, bTime)) { m_oValue->m_sText = std::to_wstring(value); - m_oType.reset(); // по стилю + + m_oType.Init(); + m_oType->SetValue(bTime ? SimpleTypes::Spreadsheet::ECellTypeType::celltypeDateTime : SimpleTypes::Spreadsheet::ECellTypeType::celltypeDate); } } return; @@ -2208,6 +3297,19 @@ namespace OOX if ( m_arrItems[i] ) { m_arrItems[i]->toXML(writer); + if(m_arrItems[i]->m_oRepeated.IsInit()) + { + _INT32 cellTimes = m_arrItems[i]->m_oRepeated.get() - 1; + auto originalCol = m_arrItems[i]->m_oCol; + while(cellTimes > 0) + { + if(m_arrItems[i]->m_oCol.IsInit()) + m_arrItems[i]->m_oCol = m_arrItems[i]->m_oCol.get() + 1; + m_arrItems[i]->toXML(writer); + cellTimes--; + } + m_arrItems[i]->m_oCol = originalCol; + } } } @@ -2252,8 +3354,12 @@ namespace OOX CCell *pCell = new CCell(m_pMainDocument); if (pCell) { - m_arrItems.push_back(pCell); + //пытаемся сжать пустые клетки pCell->fromXML(oReader); + if(!compressCell(pCell)) + m_arrItems.push_back(pCell); + else + delete pCell; } } } @@ -2263,7 +3369,7 @@ namespace OOX if (xlsx_flat) { CWorksheet* sheet = xlsx_flat->m_arWorksheets.back(); - + std::map>::iterator pFind = sheet->m_oSheetData->m_mapStyleMerges2003.find(xlsx_flat->m_nLastReadRow); if (pFind != sheet->m_oSheetData->m_mapStyleMerges2003.end()) @@ -2296,6 +3402,134 @@ namespace OOX m_arrItems.push_back(pCell); }*/ } + void CRow::fromBin(XLS::StreamCacheReaderPtr & reader) + { + auto type = reader->getNextRecordType(); + if(type == XLSB::rt_ACBegin) + { + reader->SkipRecord(false); + type = reader->getNextRecordType(); + reader->SkipRecord(false); + type = reader->getNextRecordType(); + reader->SkipRecord(false); + type = reader->getNextRecordType(); + } + if(type != XLSB::rt_RowHdr) + return; + { + auto rowHeaderRecord = reader->getNextRecord(XLSB::rt_RowHdr); + ReadAttributes(rowHeaderRecord); + } + while(1) + { + CCell *pCell = new CCell(m_pMainDocument); + pCell->m_oRow = m_oR->GetValue(); + if(pCell->fromBin(reader)) + { + //пытаемся сжать пустые клетки + if(!compressCell(pCell)) + m_arrItems.push_back(pCell); + else + delete pCell; + } + else + { + delete pCell; + break; + } + } + type = reader->getNextRecordType(); + if(type == XLSB::rt_FRTBegin) + { + reader->SkipRecord(false); + reader->getNextRecordType(); + reader->SkipRecord(false); + } + } + XLS::BaseObjectPtr CRow::toBin(sharedFormula &sharedFormulas) + { + std::vector shared_formulas_locations_ref; + auto ptr(new XLSB::Parenthesis_CELLTABLE(shared_formulas_locations_ref)); + XLS::BaseObjectPtr objectPtr(ptr); + + for(auto it = m_arrItems.begin(); it != m_arrItems.end();) + { + ptr->m_arCELL.push_back((*it)->toBin(sharedFormulas)); + if((*it)->m_oRepeated.IsInit()) + { + auto pcell =*it; + _INT32 cellTimes = pcell->m_oRepeated.get() - 1; + _INT32 originalCol = 0; + if(pcell->m_oCol.IsInit()) + originalCol = pcell->m_oCol.get(); + while(cellTimes > 0) + { + if(pcell->m_oCol.IsInit()) + pcell->m_oCol = pcell->m_oCol.get() + 1; + ptr->m_arCELL.push_back(pcell->toBin(sharedFormulas)); + cellTimes--; + } + if(pcell->m_oCol.IsInit()) + pcell->m_oCol = originalCol; + + } + it++; + } + + if(m_oCollapsed.IsInit() || m_oCustomFormat.IsInit() || m_oCustomHeight.IsInit() || m_oHidden.IsInit() || m_oHt.IsInit() + || m_oOutlineLevel.IsInit() || m_oPh.IsInit() || m_oR.IsInit() || m_oS.IsInit() || m_oThickBot.IsInit() || m_oThickTop.IsInit()) + { + auto hdrPtr(new XLSB::RowHdr); + ptr->m_BrtRowHdr = XLS::BaseObjectPtr{hdrPtr}; + + if(m_oCollapsed.IsInit()) + hdrPtr->fCollapsed = m_oCollapsed->GetValue(); + + if(m_oCustomFormat.IsInit()) + hdrPtr->fGhostDirty = m_oCustomFormat->GetValue(); + + if(m_oCustomHeight.IsInit()) + hdrPtr->fUnsynced = m_oCustomHeight->GetValue(); + + if(m_oHidden.IsInit()) + hdrPtr->fDyZero = m_oHidden->GetValue(); + + if(m_oHt.IsInit()) + hdrPtr->miyRw = m_oHt->GetValue() * 20.; + else + hdrPtr->miyRw = 240; + + if(m_oOutlineLevel.IsInit()) + hdrPtr->iOutLevel = m_oOutlineLevel->GetValue(); + + if(m_oPh.IsInit()) + hdrPtr->fPhonetic = m_oPh->GetValue(); + + if(m_oR.IsInit()) + hdrPtr->rw = m_oR->GetValue() - 1; + + if(m_oS.IsInit()) + hdrPtr->ixfe_val = m_oS->GetValue(); + + if(m_oThickBot.IsInit()) + hdrPtr->fExDes = m_oThickBot->GetValue(); + + if(m_oThickTop.IsInit()) + hdrPtr->fExAsc = m_oThickTop->GetValue(); + hdrPtr->ccolspan = 0; + } + + //if(m_oDyDescent.IsInit()) + //{ + //auto ptrAccel(new XLSB::ACCELLTABLE); + //ptr->m_ACCELLTABLE = XLS::BaseObjectPtr{ptrAccel}; + //auto ptrdescent(new XLSB::RwDescent); + // ptrAccel->m_BrtRwDescent = XLS::BaseObjectPtr{ptrdescent}; + // ptrdescent->dyDescent = m_oDyDescent->GetValue(); + //} + + return objectPtr; + } void CRow::fromXLSB (NSBinPptxRW::CBinaryFileReader& oStream, _UINT16 nType) { LONG nEnd = oStream.XlsbReadRecordLength() + oStream.GetPos(); @@ -2397,18 +3631,18 @@ namespace OOX { CRow *pCurrentRow = sheet->m_oSheetData->m_arrItems.back(); // == this sheet->m_oSheetData->m_arrItems.pop_back(); - + while (xlsx_flat->m_nLastReadRow < newRow) { xlsx_flat->m_nLastReadRow++; - + CRow *pRow = new CRow(m_pMainDocument); pRow->m_oR = xlsx_flat->m_nLastReadRow; sheet->m_oSheetData->m_arrItems.push_back(pRow); std::map>::iterator pFind = sheet->m_oSheetData->m_mapStyleMerges2003.find(xlsx_flat->m_nLastReadRow); - + if (pFind != sheet->m_oSheetData->m_mapStyleMerges2003.end()) { sheet->m_oSheetData->StyleFromMapStyleMerges2003(pFind->second); @@ -2417,7 +3651,7 @@ namespace OOX } sheet->m_oSheetData->m_arrItems.push_back(pCurrentRow); pCurrentRow = NULL; - } + } xlsx_flat->m_nLastReadRow = newRow; } xlsx_flat->m_nLastReadCol = -1; @@ -2450,7 +3684,7 @@ namespace OOX { m_oHt.Init(); m_oHt->SetValue(atof(oReader.GetTextChar())); - + m_oCustomHeight.Init(); m_oCustomHeight->SetValue(SimpleTypes::onoffTrue); } @@ -2543,6 +3777,73 @@ namespace OOX m_oDyDescent = ptrRwDescent->dyDescent; } } + } + void CRow::ReadAttributes(XLS::CFRecordPtr& record) + { + { + _INT32 row; + *record >> row; + m_oR = row +1; + } + { + _UINT32 style; + *record >> style; + m_oS = style; + } + { + _INT16 miyRw; + *record >> miyRw; + m_oHt = miyRw/20.; + } + _UINT16 flags; + BYTE flags2; + *record >> flags >> flags2; + + if(GETBIT(flags, 0)) + m_oThickTop = true; + if(GETBIT(flags, 1)) + m_oThickBot = true; + if(GETBITS(flags, 8, 10)) + m_oOutlineLevel = GETBITS(flags, 8, 10); + if(GETBIT(flags, 11)) + m_oCollapsed = true; + if(GETBIT(flags, 12)) + m_oHidden = true; + if(GETBIT(flags, 13)) + m_oCustomHeight = true; + if(GETBIT(flags, 14)) + m_oCustomFormat = true; + if(GETBIT(flags2, 0)) + m_oPh = true; + + } + bool CRow::compressCell(CCell* pCell) + { + if(!pCell->m_oValue.IsInit() && !m_arrItems.empty()) + { + auto prevCell = m_arrItems.back(); + if(!prevCell->m_oRepeated.IsInit()) + { + prevCell->m_oRepeated = 1; + } + + if(!prevCell->m_oValue.IsInit()) + { + if((!prevCell->m_oCol.IsInit()&& !pCell->m_oCol.IsInit()) + ||(prevCell->m_oCol.IsInit()&& pCell->m_oCol.IsInit() && (prevCell->m_oCol.get() + prevCell->m_oRepeated.get()) == pCell->m_oCol.get())) + { + if((!prevCell->m_oStyle.IsInit() && !pCell->m_oStyle.IsInit()) + || (prevCell->m_oStyle.IsInit() && pCell->m_oStyle.IsInit() && prevCell->m_oStyle.get() == pCell->m_oStyle.get())) + { + prevCell->m_oRepeated = prevCell->m_oRepeated.get() + 1; + return true; + } + } + } + if(prevCell->m_oRepeated.get() == 1) + prevCell->m_oRepeated.reset(); + } + return false; } EElementType CRow::getType () const { @@ -2570,6 +3871,20 @@ namespace OOX if ( m_arrItems[i] ) { m_arrItems[i]->toXML(writer); + if(m_arrItems[i]->m_oRepeated.IsInit()) + { + _INT32 rowTimes = m_arrItems[i]->m_oRepeated.get() - 1; + while(rowTimes > 0) + { + if(m_arrItems[i]->m_oR.IsInit()) + m_arrItems[i]->m_oR = m_arrItems[i]->m_oR->GetValue() + 1; + if(!m_arrItems[i]->m_arrItems.empty() && m_arrItems[i]->m_arrItems.at(0)->m_oRow.IsInit()) + m_arrItems[i]->m_arrItems.at(0)->m_oRow = m_arrItems[i]->m_oR->GetValue(); + m_arrItems[i]->toXML(writer); + rowTimes--; + } + + } } } toXMLEnd(writer); @@ -2602,7 +3917,7 @@ namespace OOX return; CXlsx* xlsx = dynamic_cast(m_pMainDocument); CXlsxFlat* xlsx_flat = dynamic_cast(m_pMainDocument); - + if(xlsx) { xlsx->m_nLastReadRow = 0; @@ -2653,8 +3968,11 @@ namespace OOX CRow *pRow = new CRow(m_pMainDocument); if (pRow) { - m_arrItems.push_back(pRow); pRow->fromXML(oReader); + if(!compressRow(pRow)) + m_arrItems.push_back(pRow); + else + delete pRow; } } else if (strcmp("Column", sName) == 0) @@ -2671,11 +3989,11 @@ namespace OOX pWorksheet->m_oCols.Init(); } - pWorksheet->m_oCols->m_arrItems.push_back(pColumn); + pWorksheet->m_oCols->m_arrItems.push_back(pColumn); pColumn->m_oMin.Init(); pColumn->m_oMin->SetValue(pWorksheet->m_oCols->m_arrItems.size()); - + pColumn->m_oMax.Init(); pColumn->m_oMax->SetValue(pWorksheet->m_oCols->m_arrItems.size()); } @@ -2687,7 +4005,7 @@ namespace OOX { CXlsxFlat* xlsx_flat = dynamic_cast(m_pMainDocument); if (!xlsx_flat) return; - + CWorksheet* pWorksheet = xlsx_flat->m_arWorksheets.back(); pWorksheet->m_oSheetFormatPr.Init(); @@ -2848,337 +4166,459 @@ namespace OOX m_arrItems.push_back(pRow); }*/ } + void CSheetData::fromBin(XLS::StreamCacheReaderPtr & reader) + { + if(reader->getNextRecordType() == XLSB::rt_BeginSheetData) + reader->SkipRecord(false); + else + return; + while (reader->getNextRecordType() == XLSB::rt_ACBegin || reader->getNextRecordType() == XLSB::rt_RowHdr) + { + CRow *pRow = new CRow(m_pMainDocument); + pRow->fromBin(reader); + //проверяем можно ли сжать пустые строки + if(!compressRow(pRow)) + m_arrItems.push_back(pRow); + else + delete pRow; + } + if(SharedFormulasRef::sharedRefsLocations) + SharedFormulasRef::sharedRefsLocations.reset(); + } + XLS::BaseObjectPtr CSheetData::toBin() + { + auto ptr(new XLSB::CELLTABLE); + XLS::BaseObjectPtr objectPtr(ptr); + sharedFormula fmlaStruct; + + for(auto it = m_arrItems.begin(); it != m_arrItems.end();) + { + ptr->m_arParenthesis_CELLTABLE.push_back((*it)->toBin(fmlaStruct)); + if((*it)->m_oRepeated.IsInit()) + { + auto prow = *it; + _INT32 rowTimes = prow->m_oRepeated.get() - 1; + while(rowTimes > 0) + { + if(prow->m_oR.IsInit()) + prow->m_oR = prow->m_oR->GetValue() + 1; + if(!prow->m_arrItems.empty() && prow->m_arrItems.at(0)->m_oRow.IsInit()) + prow->m_arrItems.at(0)->m_oRow = prow->m_oR->GetValue(); + ptr->m_arParenthesis_CELLTABLE.push_back(prow->toBin(fmlaStruct)); + rowTimes--; + } + + } + it = m_arrItems.erase(it); + } + + return objectPtr; + } + bool CSheetData::compressRow(CRow* pRow) + { + if((pRow->m_arrItems.empty() || (pRow->m_arrItems.size() == 1 && pRow->m_arrItems.back()->m_oRepeated.IsInit())) && !m_arrItems.empty()) + { + auto prevRow = m_arrItems.back(); + if((!prevRow->m_oS.IsInit() && !pRow->m_oS.IsInit()) || (prevRow->m_oS.IsInit() && pRow->m_oS.IsInit() + && prevRow->m_oS->GetValue() == pRow->m_oS->GetValue())) + { + if(!prevRow->m_oRepeated.IsInit()) + prevRow->m_oRepeated = 1; + if(prevRow->m_oR->GetValue() + prevRow->m_oRepeated.get() == pRow->m_oR->GetValue() && prevRow->m_oHt == pRow->m_oHt) + { + //случай с пустыми строками + if(prevRow->m_arrItems.empty() && pRow->m_arrItems.empty()) + { + prevRow->m_oRepeated = prevRow->m_oRepeated.get() + 1; + return true; + } + //случай со строками заполненными однотипными сжатыми клетками + if(prevRow->m_arrItems.size() == 1 && pRow->m_arrItems.size() == 1 && prevRow->m_arrItems.back()->m_oRepeated.IsInit() + && pRow->m_arrItems.back()->m_oRepeated.get() == prevRow->m_arrItems.back()->m_oRepeated.get()) + { + auto nullvalue = 0; + auto pcell = pRow->m_arrItems.back(); + auto prevCell = prevRow->m_arrItems.back(); + if(pcell->m_oStyle.get_value_or(nullvalue) == prevCell->m_oStyle.get_value_or(nullvalue) + && pcell->m_oCol.get_value_or(nullvalue) == prevCell->m_oCol.get_value_or(nullvalue)) + { + prevRow->m_oRepeated = prevRow->m_oRepeated.get() + 1; + return true; + } + } + } + if(prevRow->m_oRepeated.get() == 1) + prevRow->m_oRepeated.reset(); + } + } + return false; + } EElementType CSheetData::getType () const { return et_x_SheetData; } //----------------------------------------------------------------------------------------- - void CWorksheet::ReadWorksheetOptions(XmlUtils::CXmlLiteReader& oReader) - { - if ( oReader.IsEmptyNode() ) - return; - - CXlsxFlat* xlsx_flat = dynamic_cast(WritingElement::m_pMainDocument); + void CWorksheet::ReadWorksheetOptions(XmlUtils::CXmlLiteReader& oReader) + { + if (oReader.IsEmptyNode()) + return; - if (!xlsx_flat) return; + CXlsxFlat* xlsx_flat = dynamic_cast(WritingElement::m_pMainDocument); - if (false == m_oSheetViews.IsInit()) - { - m_oSheetViews.Init(); - m_oSheetViews->m_arrItems.push_back(new CSheetView()); - } - nullable_int active_pane; - nullable_bool bFreeze; - nullable_int xSplit, ySplit; + if (!xlsx_flat) return; - nullable_int active_pane_number; - nullable_int left_column_visible; - nullable_int page_break_zoom; - std::map> mapPanes; + if (false == m_oSheetViews.IsInit()) + { + m_oSheetViews.Init(); + m_oSheetViews->m_arrItems.push_back(new CSheetView()); + } + CSheet* pSheet = xlsx_flat->m_pWorkbook->m_oSheets->m_arrItems.back(); - nullable_string sDataHeader, sDataFooter; + nullable_int active_pane; + nullable_bool bFreeze; + nullable_int xSplit, ySplit; - int nDocumentDepth = oReader.GetDepth(); - while ( oReader.ReadNextSiblingNode( nDocumentDepth ) ) - { - std::wstring sName = XmlUtils::GetNameNoNS(oReader.GetName()); + nullable_int active_pane_number, topRowBottom_pane, leftColumnRight_pane; + nullable_int left_column_visible; + nullable_int page_break_zoom; + std::map> mapPanes; - if (L"PageSetup" == sName) - { - if (false == m_oPageSetup.IsInit()) m_oPageSetup.Init(); + nullable_string sDataHeader, sDataFooter; - int nDocumentDepth1 = oReader.GetDepth(); - while (oReader.ReadNextSiblingNode(nDocumentDepth1)) - { - std::wstring sName1 = XmlUtils::GetNameNoNS(oReader.GetName()); + int nDocumentDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nDocumentDepth)) + { + std::wstring sName = XmlUtils::GetNameNoNS(oReader.GetName()); - if (L"Header" == sName1) - { - if (false == m_oPageMargins.IsInit()) m_oPageMargins.Init(); + if (L"PageSetup" == sName) + { + if (false == m_oPageSetup.IsInit()) m_oPageSetup.Init(); - WritingElement_ReadAttributes_Start_No_NS(oReader) - WritingElement_ReadAttributes_Read_if(oReader, L"Margin", m_oPageMargins->m_oHeader) - WritingElement_ReadAttributes_Read_else_if(oReader, L"Data", sDataHeader) - WritingElement_ReadAttributes_End_No_NS(oReader) - } - else if (L"Footer" == sName1) - { - if (false == m_oPageMargins.IsInit()) m_oPageMargins.Init(); + int nDocumentDepth1 = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nDocumentDepth1)) + { + std::wstring sName1 = XmlUtils::GetNameNoNS(oReader.GetName()); - WritingElement_ReadAttributes_Start_No_NS(oReader) - WritingElement_ReadAttributes_Read_if(oReader, L"Margin", m_oPageMargins->m_oFooter) - WritingElement_ReadAttributes_Read_else_if(oReader, L"Data", sDataFooter) - WritingElement_ReadAttributes_End_No_NS(oReader) - } - else if (L"Layout" == sName1) - { - WritingElement_ReadAttributes_Start_No_NS(oReader) - WritingElement_ReadAttributes_Read_if(oReader, L"x:Orientation", m_oPageSetup->m_oOrientation) - WritingElement_ReadAttributes_End_No_NS(oReader) - } - else if (L"PageMargins" == sName1) - { - if (false == m_oPageMargins.IsInit()) m_oPageMargins.Init(); - - WritingElement_ReadAttributes_Start_No_NS(oReader) - WritingElement_ReadAttributes_Read_if(oReader, L"Top", m_oPageMargins->m_oTop) - WritingElement_ReadAttributes_Read_else_if(oReader, L"Left", m_oPageMargins->m_oLeft) - WritingElement_ReadAttributes_Read_else_if(oReader, L"Right", m_oPageMargins->m_oRight) - WritingElement_ReadAttributes_Read_else_if(oReader, L"Bottom", m_oPageMargins->m_oBottom) - WritingElement_ReadAttributes_End_No_NS(oReader) - } - } - } - else if (L"Panes" == sName) - { - int nDocumentDepth1 = oReader.GetDepth(); - while (oReader.ReadNextSiblingNode(nDocumentDepth1)) - { - std::wstring sName1 = XmlUtils::GetNameNoNS(oReader.GetName()); + if (L"Header" == sName1) + { + if (false == m_oPageMargins.IsInit()) m_oPageMargins.Init(); - if (L"Pane" == sName1) - { - nullable pane; pane.Init(); - nullable_int number; + WritingElement_ReadAttributes_Start_No_NS(oReader) + WritingElement_ReadAttributes_Read_if(oReader, L"Margin", m_oPageMargins->m_oHeader) + WritingElement_ReadAttributes_Read_else_if(oReader, L"Data", sDataHeader) + WritingElement_ReadAttributes_End_No_NS(oReader) + } + else if (L"Footer" == sName1) + { + if (false == m_oPageMargins.IsInit()) m_oPageMargins.Init(); - int nDocumentDepth2 = oReader.GetDepth(); - nullable_int col, row; - while (oReader.ReadNextSiblingNode(nDocumentDepth2)) - { - std::wstring sName2 = XmlUtils::GetNameNoNS(oReader.GetName()); - if (L"Number" == sName2) - { - number = oReader.GetText2(); - } - else if (L"ActiveRow" == sName2) - { - row = oReader.GetText2(); - } - else if (L"ActiveCol" == sName2) - { - col = oReader.GetText2(); - } - else if (L"RangeSelection" == sName2) - { - r1c1_formula_convert::base_row = xlsx_flat->m_nLastReadRow; - r1c1_formula_convert::base_col = xlsx_flat->m_nLastReadCol; + WritingElement_ReadAttributes_Start_No_NS(oReader) + WritingElement_ReadAttributes_Read_if(oReader, L"Margin", m_oPageMargins->m_oFooter) + WritingElement_ReadAttributes_Read_else_if(oReader, L"Data", sDataFooter) + WritingElement_ReadAttributes_End_No_NS(oReader) + } + else if (L"Layout" == sName1) + { + WritingElement_ReadAttributes_Start_No_NS(oReader) + WritingElement_ReadAttributes_Read_if(oReader, L"x:Orientation", m_oPageSetup->m_oOrientation) + WritingElement_ReadAttributes_End_No_NS(oReader) + } + else if (L"PageMargins" == sName1) + { + if (false == m_oPageMargins.IsInit()) m_oPageMargins.Init(); + + WritingElement_ReadAttributes_Start_No_NS(oReader) + WritingElement_ReadAttributes_Read_if(oReader, L"Top", m_oPageMargins->m_oTop) + WritingElement_ReadAttributes_Read_else_if(oReader, L"Left", m_oPageMargins->m_oLeft) + WritingElement_ReadAttributes_Read_else_if(oReader, L"Right", m_oPageMargins->m_oRight) + WritingElement_ReadAttributes_Read_else_if(oReader, L"Bottom", m_oPageMargins->m_oBottom) + WritingElement_ReadAttributes_End_No_NS(oReader) + } + } + } + else if (L"Panes" == sName) + { + int nDocumentDepth1 = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nDocumentDepth1)) + { + std::wstring sName1 = XmlUtils::GetNameNoNS(oReader.GetName()); - r1c1_formula_convert convert; + if (L"Pane" == sName1) + { + nullable pane; pane.Init(); + nullable_int number; - std::wstring ref = convert.convert(oReader.GetText2()); + int nDocumentDepth2 = oReader.GetDepth(); + nullable_int col, row; + while (oReader.ReadNextSiblingNode(nDocumentDepth2)) + { + std::wstring sName2 = XmlUtils::GetNameNoNS(oReader.GetName()); + if (L"Number" == sName2) + { + number = oReader.GetText2(); + } + else if (L"ActiveRow" == sName2) + { + row = oReader.GetText2(); + } + else if (L"ActiveCol" == sName2) + { + col = oReader.GetText2(); + } + else if (L"RangeSelection" == sName2) + { + r1c1_formula_convert::base_row = xlsx_flat->m_nLastReadRow; + r1c1_formula_convert::base_col = xlsx_flat->m_nLastReadCol; - m_oSheetViews->m_arrItems.back()->m_arrItems.push_back(new CSelection()); - m_oSheetViews->m_arrItems.back()->m_arrItems.back()->m_oSqref = ref; + r1c1_formula_convert convert; - size_t pos_split = ref.find(L":"); - m_oSheetViews->m_arrItems.back()->m_arrItems.back()->m_oActiveCell = - pos_split != std::wstring::npos ? ref.substr(0, pos_split) : ref; - } - } - if (col.IsInit() && row.IsInit()) - { - if (m_oSheetViews->m_arrItems.back()->m_arrItems.empty()) - m_oSheetViews->m_arrItems.back()->m_arrItems.push_back(new CSelection()); + std::wstring ref = convert.convert(oReader.GetText2()); - m_oSheetViews->m_arrItems.back()->m_arrItems.back()->m_oActiveCell = getCellAddress(*row + 1, *col + 1); + m_oSheetViews->m_arrItems.back()->m_arrItems.push_back(new CSelection()); + m_oSheetViews->m_arrItems.back()->m_arrItems.back()->m_oSqref = ref; - if (false == m_oSheetViews->m_arrItems.back()->m_arrItems.back()->m_oSqref.IsInit()) - { - m_oSheetViews->m_arrItems.back()->m_arrItems.back()->m_oSqref = m_oSheetViews->m_arrItems.back()->m_arrItems.back()->m_oActiveCell; - } - } - if (number.IsInit()) - { - mapPanes.insert(std::make_pair(*number, pane)); - } - } - } - } - else if (L"SplitHorizontal" == sName) - { - ySplit = oReader.GetText2(); - } - else if (L"SplitVertical" == sName) - { - xSplit = oReader.GetText2(); - } - else if (L"DoNotDisplayGridlines" == sName) - { - m_oSheetViews->m_arrItems.back()->m_oShowGridLines.Init(); - m_oSheetViews->m_arrItems.back()->m_oShowGridLines->FromBool(false); - } - else if (L"Selected" == sName) - { - m_oSheetViews->m_arrItems.back()->m_oTabSelected.Init(); - m_oSheetViews->m_arrItems.back()->m_oTabSelected->FromBool(true); - } - else if (L"FreezePanes" == sName) - { - bFreeze = true; - } - else if (L"ActivePane" == sName) - { - active_pane_number = oReader.GetText2(); - } - else if (L"Print" == sName) - { - if (false == m_oPageSetup.IsInit()) m_oPageSetup.Init(); - if (false == m_oPrintOptions.IsInit()) m_oPrintOptions.Init(); + size_t pos_split = ref.find(L":"); + m_oSheetViews->m_arrItems.back()->m_arrItems.back()->m_oActiveCell = + pos_split != std::wstring::npos ? ref.substr(0, pos_split) : ref; + } + } + if (col.IsInit() || row.IsInit()) + { + if (m_oSheetViews->m_arrItems.back()->m_arrItems.empty()) + m_oSheetViews->m_arrItems.back()->m_arrItems.push_back(new CSelection()); - int nDocumentDepth1 = oReader.GetDepth(); - while (oReader.ReadNextSiblingNode(nDocumentDepth1)) - { - std::wstring sName1 = XmlUtils::GetNameNoNS(oReader.GetName()); + m_oSheetViews->m_arrItems.back()->m_arrItems.back()->m_oActiveCell = getCellAddress(row.IsInit() ? *row + 1 : 1, col.IsInit() ? *col + 1 : 1); - if (L"FitHeight" == sName1) - { - m_oPageSetup->m_oFitToHeight = oReader.GetText2(); - } - else if (L"DraftQuality" == sName1) - { - m_oPageSetup->m_oDraft.Init(); - } - else if (L"Gridlines" == sName1) - { - m_oPrintOptions->m_oGridLines = true; - } - else if (L"Scale" == sName1) - { - m_oPageSetup->m_oScale = oReader.GetText2(); - } - else if (L"HorizontalResolution" == sName1) - { - m_oPageSetup->m_oHorizontalDpi = oReader.GetText2(); - } - else if (L"VerticalResolution" == sName1) - { - m_oPageSetup->m_oVerticalDpi = oReader.GetText2(); - } - else if (L"PaperSizeIndex" == sName1) - { - m_oPageSetup->m_oPaperSize = oReader.GetText2(); - } - } - } - else if (L"FitToPage" == sName) - { - if (!m_oSheetPr.IsInit()) m_oSheetPr.Init(); - if (!m_oSheetPr->m_oPageSetUpPr.IsInit()) m_oSheetPr->m_oPageSetUpPr.Init(); + if (false == m_oSheetViews->m_arrItems.back()->m_arrItems.back()->m_oSqref.IsInit()) + { + m_oSheetViews->m_arrItems.back()->m_arrItems.back()->m_oSqref = m_oSheetViews->m_arrItems.back()->m_arrItems.back()->m_oActiveCell; + } + } + if (number.IsInit()) + { + mapPanes.insert(std::make_pair(*number, pane)); + } + } + } + } + else if (L"SplitHorizontal" == sName) + { + ySplit = oReader.GetText2(); + } + else if (L"SplitVertical" == sName) + { + xSplit = oReader.GetText2(); + } + else if (L"DoNotDisplayGridlines" == sName) + { + m_oSheetViews->m_arrItems.back()->m_oShowGridLines.Init(); + m_oSheetViews->m_arrItems.back()->m_oShowGridLines->FromBool(false); + } + else if (L"DoNotDisplayZeros" == sName) + { + m_oSheetViews->m_arrItems.back()->m_oShowZeros.Init(); + m_oSheetViews->m_arrItems.back()->m_oShowZeros->FromBool(false); + } + else if (L"Selected" == sName) + { + m_oSheetViews->m_arrItems.back()->m_oTabSelected.Init(); + m_oSheetViews->m_arrItems.back()->m_oTabSelected->FromBool(true); + } + else if (L"Zoom" == sName) + { + m_oSheetViews->m_arrItems.back()->m_oZoomScale = oReader.GetText2(); + } + else if (L"FreezePanes" == sName) + { + bFreeze = true; + } + else if (L"ActivePane" == sName) + { + active_pane_number = oReader.GetText2(); + } + else if (L"TopRowBottomPane" == sName) + { + topRowBottom_pane = oReader.GetText2(); + } + else if (L"LeftColumnRightPane" == sName) + { + leftColumnRight_pane = oReader.GetText2(); + } + else if (L"Print" == sName) + { + if (false == m_oPageSetup.IsInit()) m_oPageSetup.Init(); + if (false == m_oPrintOptions.IsInit()) m_oPrintOptions.Init(); - m_oSheetPr->m_oPageSetUpPr->m_oFitToPage.Init(); - m_oSheetPr->m_oPageSetUpPr->m_oFitToPage->FromBool(true); - } - else if (L"ProtectObjects" == sName) - { + int nDocumentDepth1 = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nDocumentDepth1)) + { + std::wstring sName1 = XmlUtils::GetNameNoNS(oReader.GetName()); - } - else if (L"ProtectScenarios" == sName) - { + if (L"FitHeight" == sName1) + { + m_oPageSetup->m_oFitToHeight = oReader.GetText2(); + } + else if (L"DraftQuality" == sName1) + { + m_oPageSetup->m_oDraft.Init(); + } + else if (L"Gridlines" == sName1) + { + m_oPrintOptions->m_oGridLines = true; + } + else if (L"Scale" == sName1) + { + m_oPageSetup->m_oScale = oReader.GetText2(); + } + else if (L"HorizontalResolution" == sName1) + { + m_oPageSetup->m_oHorizontalDpi = oReader.GetText2(); + } + else if (L"VerticalResolution" == sName1) + { + m_oPageSetup->m_oVerticalDpi = oReader.GetText2(); + } + else if (L"PaperSizeIndex" == sName1) + { + m_oPageSetup->m_oPaperSize = oReader.GetText2(); + } + } + } + else if (L"FitToPage" == sName) + { + if (!m_oSheetPr.IsInit()) m_oSheetPr.Init(); + if (!m_oSheetPr->m_oPageSetUpPr.IsInit()) m_oSheetPr->m_oPageSetUpPr.Init(); - } - else if (L"ProtectContents" == sName) - { + m_oSheetPr->m_oPageSetUpPr->m_oFitToPage.Init(); + m_oSheetPr->m_oPageSetUpPr->m_oFitToPage->FromBool(true); + } + else if (L"ProtectObjects" == sName) + { - } - else if (L"LeftColumnVisible" == sName) - { - left_column_visible = oReader.GetText2(); - } - else if (L"PageBreakZoom" == sName) - { - page_break_zoom = oReader.GetText2(); - } - else if (L"DoNotDisplayColHeaders" == sName) - { + } + else if (L"ProtectScenarios" == sName) + { - } - else if (L"ViewableRange" == sName) - { + } + else if (L"ProtectContents" == sName) + { - } - else if (L"GridlineColor" == sName) - { + } + else if (L"LeftColumnVisible" == sName) + { + left_column_visible = oReader.GetText2(); + } + else if (L"PageBreakZoom" == sName) + { + page_break_zoom = oReader.GetText2(); + } + else if (L"DoNotDisplayColHeaders" == sName) + { - } - else if (L"Unsynced" == sName) - { + } + else if (L"ViewableRange" == sName) + { - } - else if (L"DisplayPageBreak" == sName) - { + } + else if (L"GridlineColor" == sName) + { - } - else if (L"ShowPageBreakZoom" == sName) - { - m_oSheetViews->m_arrItems.back()->m_oView = SimpleTypes::Spreadsheet::sheetviewPageBreakPreview; - } - else if (L"DefaultRowHeight" == sName) - { + } + else if (L"Unsynced" == sName) + { - } - else if (L"DefaultColumnWidth" == sName) - { + } + else if (L"DisplayPageBreak" == sName) + { - } - else if (L"Visible" == sName) - { + } + else if (L"ShowPageBreakZoom" == sName) + { + m_oSheetViews->m_arrItems.back()->m_oView = SimpleTypes::Spreadsheet::sheetviewPageBreakPreview; + } + else if (L"DefaultRowHeight" == sName) + { - } - else if (L"DisplayRightToLeft" == sName) - { + } + else if (L"DefaultColumnWidth" == sName) + { - } - else if (L"DisplayFormulas" == sName) - { - m_oSheetViews->m_arrItems.back()->m_oShowFormulas = true; - } - else if (L"ActiveRow" == sName) - { + } + else if (L"Visible" == sName) + { + std::wstring sVisible = oReader.GetText2(); + if (sVisible == L"SheetHidden") + { + pSheet->m_oState.Init(); + pSheet->m_oState->SetValue(SimpleTypes::Spreadsheet::EVisibleType::visibleHidden); + } + } + else if (L"DisplayRightToLeft" == sName) + { - } - else if (L"ActiveColumn" == sName) - { + } + else if (L"DisplayFormulas" == sName) + { + m_oSheetViews->m_arrItems.back()->m_oShowFormulas = true; + } + else if (L"ActiveRow" == sName) + { - } - else if (L"TabColorIndex" == sName) - { - if (false == m_oSheetPr.IsInit()) m_oSheetPr.Init(); - m_oSheetPr->m_oTabColor.Init(); m_oSheetPr->m_oTabColor->m_oIndexed = oReader.GetText2(); - } - } + } + else if (L"ActiveColumn" == sName) + { - if (m_oPageMargins.IsInit()) - { - if (!m_oPageMargins->m_oFooter.IsInit()) - { - m_oPageMargins->m_oFooter.Init(); - m_oPageMargins->m_oFooter->SetValue(0.5); - } - if (!m_oPageMargins->m_oHeader.IsInit()) - { - m_oPageMargins->m_oHeader.Init(); - m_oPageMargins->m_oHeader->SetValue(0.5); - } - } + } + else if (L"TabColorIndex" == sName) + { + if (false == m_oSheetPr.IsInit()) m_oSheetPr.Init(); + m_oSheetPr->m_oTabColor.Init(); m_oSheetPr->m_oTabColor->m_oIndexed = oReader.GetText2(); + } + } - if (active_pane_number.IsInit()) - { - std::map>::iterator pFind = mapPanes.find(*active_pane_number); - if (pFind != mapPanes.end()) - { - m_oSheetViews->m_arrItems.back()->m_oPane = pFind->second; - } - } - if (m_oSheetViews->m_arrItems.back()->m_oPane.IsInit()) - { - m_oSheetViews->m_arrItems.back()->m_oPane->m_oActivePane.Init(); - m_oSheetViews->m_arrItems.back()->m_oPane->m_oActivePane->SetValue(SimpleTypes::Spreadsheet::activepaneBottomLeft); - if (bFreeze.IsInit()) - { - m_oSheetViews->m_arrItems.back()->m_oPane->m_oState.Init(); - m_oSheetViews->m_arrItems.back()->m_oPane->m_oState->SetValue(SimpleTypes::Spreadsheet::panestateFrozen); - } - if (ySplit.IsInit()) + if (m_oPageMargins.IsInit()) + { + if (!m_oPageMargins->m_oFooter.IsInit()) + { + m_oPageMargins->m_oFooter.Init(); + m_oPageMargins->m_oFooter->SetValue(0.5); + } + if (!m_oPageMargins->m_oHeader.IsInit()) + { + m_oPageMargins->m_oHeader.Init(); + m_oPageMargins->m_oHeader->SetValue(0.5); + } + } + + if (active_pane_number.IsInit()) + { + std::map>::iterator pFind = mapPanes.find(*active_pane_number); + if (pFind != mapPanes.end()) + { + m_oSheetViews->m_arrItems.back()->m_oPane = pFind->second; + } + } + if (m_oSheetViews->m_arrItems.back()->m_oPane.IsInit()) + { + m_oSheetViews->m_arrItems.back()->m_oPane->m_oActivePane.Init(); + m_oSheetViews->m_arrItems.back()->m_oPane->m_oActivePane->SetValue(SimpleTypes::Spreadsheet::activepaneBottomLeft); + if (bFreeze.IsInit()) + { + m_oSheetViews->m_arrItems.back()->m_oPane->m_oState.Init(); + m_oSheetViews->m_arrItems.back()->m_oPane->m_oState->SetValue(SimpleTypes::Spreadsheet::panestateFrozen); + } + if (topRowBottom_pane.IsInit() || leftColumnRight_pane.IsInit()) + { + m_oSheetViews->m_arrItems.back()->m_oPane->m_oTopLeftCell = getCellAddress( topRowBottom_pane.IsInit() ? *topRowBottom_pane + 1 : 1, + leftColumnRight_pane.IsInit() ? *leftColumnRight_pane + 1 : 1); + + if (false == m_oSheetViews->m_arrItems.back()->m_arrItems.empty()) + { + m_oSheetViews->m_arrItems.back()->m_arrItems.back()->m_oPane.Init(); + m_oSheetViews->m_arrItems.back()->m_arrItems.back()->m_oPane->SetValue(SimpleTypes::Spreadsheet::activepaneBottomLeft); + } + } + if (ySplit.IsInit()) { m_oSheetViews->m_arrItems.back()->m_oPane->m_oYSplit.Init(); m_oSheetViews->m_arrItems.back()->m_oPane->m_oYSplit->SetValue(*ySplit); @@ -3191,7 +4631,97 @@ namespace OOX } } //---------------------------------------------------------------------------------------- - void CDataValidation::fromXML(XmlUtils::CXmlLiteReader& oReader) + void CDataValidation::CreateElements(XmlUtils::CXmlLiteReader& oReader, int nDepth) + { + if (oReader.IsEmptyNode()) + return; + + while (oReader.ReadNextSiblingNode(nDepth)) + { + std::wstring sName = XmlUtils::GetNameNoNS(oReader.GetName()); + if (L"formula1" == sName) + { + m_oFormula1 = oReader; + } + else if (L"formula2" == sName) + { + m_oFormula2 = oReader; + } + else if (L"list" == sName) + { + m_oList = oReader.GetText2(); + } + else if (L"sqref" == sName) + { + m_oSqRef = oReader.GetText2(); + } + //--------------------------------------------------- xml spreadsheet 2002 + else if (L"Range" == sName) + { + r1c1_formula_convert::base_row = 1; + r1c1_formula_convert::base_col = 1; + + r1c1_formula_convert convert; + + m_oSqRef = convert.convert(oReader.GetText2()); + } + else if (L"Type" == sName) + { + m_oType = oReader.GetText2(); + + m_oAllowBlank.Init(); + m_oAllowBlank->FromBool(true); + + m_oShowInputMessage.Init(); + m_oShowInputMessage->FromBool(true); + } + else if (L"Value" == sName) + { + r1c1_formula_convert::base_row = 1; + r1c1_formula_convert::base_col = 1; + + r1c1_formula_convert convert; + + m_oFormula1 = new CDataValidationFormula(m_pMainDocument); + m_oFormula1->m_sText = convert.convert(oReader.GetText3()); + + //if (m_oFormula1->m_sText.find(L"!") == std::wstring::npos) + //{ + // CXlsxFlat* xlsx_flat = dynamic_cast(m_pMainDocument); + // if (xlsx_flat) + // { + // CSheet *pSheet = xlsx_flat->m_pWorkbook->m_oSheets->m_arrItems.back(); + // if (pSheet->m_oName.IsInit()) + // { + // m_oFormula1->m_sText = *pSheet->m_oName + L"!" + m_oFormula1->m_sText; + // } + // } + //} + } + else if (L"AlternateContent" == sName) + { + int nCurDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nCurDepth)) + { + std::wstring sName1 = oReader.GetName(); + + if (oReader.IsEmptyNode()) + continue; + + if (sName1 == L"mc:Choice") + { + CreateElements(oReader, oReader.GetDepth()); + } + else if (sName1 == L"mc:Fallback") + { + CreateElements(oReader, oReader.GetDepth()); + } + } + + } + } + } + void CDataValidation::fromXML(XmlUtils::CXmlLiteReader& oReader) { ReadAttributes( oReader ); @@ -3199,65 +4729,8 @@ namespace OOX return; int nCurDepth = oReader.GetDepth(); - while (oReader.ReadNextSiblingNode(nCurDepth)) - { - std::wstring sName = XmlUtils::GetNameNoNS(oReader.GetName()); - if (L"formula1" == sName) - { - m_oFormula1 = oReader; - } - else if (L"formula2" == sName) - { - m_oFormula2 = oReader; - } - else if (L"sqref" == sName) - { - m_oSqRef = oReader.GetText2(); - } - //--------------------------------------------------- xml spreadsheet 2002 - else if (L"Range" == sName) - { - r1c1_formula_convert::base_row = 1; - r1c1_formula_convert::base_col = 1; - - r1c1_formula_convert convert; - m_oSqRef = convert.convert(oReader.GetText2()); - } - else if (L"Type" == sName) - { - m_oType = oReader.GetText2(); - - m_oAllowBlank.Init(); - m_oAllowBlank->FromBool(true); - - m_oShowInputMessage.Init(); - m_oShowInputMessage->FromBool(true); - } - else if (L"Value" == sName) - { - r1c1_formula_convert::base_row = 1; - r1c1_formula_convert::base_col = 1; - - r1c1_formula_convert convert; - - m_oFormula1 = new CDataValidationFormula(m_pMainDocument); - m_oFormula1->m_sText = convert.convert(oReader.GetText3()); - - //if (m_oFormula1->m_sText.find(L"!") == std::wstring::npos) - //{ - // CXlsxFlat* xlsx_flat = dynamic_cast(m_pMainDocument); - // if (xlsx_flat) - // { - // CSheet *pSheet = xlsx_flat->m_pWorkbook->m_oSheets->m_arrItems.back(); - // if (pSheet->m_oName.IsInit()) - // { - // m_oFormula1->m_sText = *pSheet->m_oName + L"!" + m_oFormula1->m_sText; - // } - // } - //} - } - } + CreateElements(oReader, nCurDepth); } //----------------------------------------------------------------------------------------- void CDefinedName::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) @@ -3418,9 +4891,10 @@ namespace OOX if (pShape->m_sId.IsInit()) {//mark shape as used - boost::unordered_map::iterator pFind = pVmlDrawing->m_mapShapes.find(pShape->m_sId.get()); + std::map::iterator pFind = pVmlDrawing->m_mapShapes.find(pShape->m_sId.get()); if (pFind != pVmlDrawing->m_mapShapes.end()) { + if (!pFind->second.bComment) continue; pFind->second.bUsed = true; } } diff --git a/OOXML/XlsxFormat/Worksheets/SheetData.h b/OOXML/XlsxFormat/Worksheets/SheetData.h index 89cc1773636..8125888eada 100644 --- a/OOXML/XlsxFormat/Worksheets/SheetData.h +++ b/OOXML/XlsxFormat/Worksheets/SheetData.h @@ -33,6 +33,8 @@ #include "../SharedStrings/Si.h" #include "../../Common/SimpleTypes_Shared.h" +#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CellRef.h" +#include "../../../MsBinaryFile/XlsFile/Format/Binary/CFStreamCacheReader.h" namespace NSBinPptxRW { @@ -97,7 +99,9 @@ namespace OOX CTextXLSB m_oValue; CFormulaXLSB m_oFormula; nullable m_oRichText; - + + nullable_uint m_oCellMetadata; + nullable_uint m_oValueMetadata; protected: void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); }; @@ -125,6 +129,11 @@ namespace OOX void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); }; + struct sharedFormula + { + std::vector shrFmla; + std::vector> arrfmla; + }; class CFormula : public WritingElement { public: @@ -140,7 +149,9 @@ namespace OOX void fromXLSB (NSBinPptxRW::CBinaryFileReader& oStream); void fromXLSBExt (NSBinPptxRW::CBinaryFileReader& oStream, _UINT16 nFlags); + void fromBin(XLS::StreamCacheReaderPtr& reader, XLS::CFRecordPtr& record); void fromBin(XLS::BaseObjectPtr& obj, SimpleTypes::Spreadsheet::ECellFormulaType eType); + void toBin(XLS::BaseObjectPtr& obj); virtual EElementType getType () const; @@ -168,7 +179,7 @@ namespace OOX { public: WritingElement_AdditionMethods(CData) - CData(); + CData(bool bFormulaPresent); virtual ~CData(); virtual void fromXML(XmlUtils::CXmlNode& node); @@ -192,7 +203,7 @@ namespace OOX nullable_bool bSuperscript; nullable_string sColor; nullable_int nFontSize; - + bool bFormula = false; public: nullable m_oType; @@ -215,6 +226,8 @@ namespace OOX void fromXLSB (NSBinPptxRW::CBinaryFileReader& oStream, _UINT16 nType, _UINT32 nRow); void fromBin(XLS::BaseObjectPtr& obj); + bool fromBin(XLS::StreamCacheReaderPtr& reader); + XLS::BaseObjectPtr toBin(sharedFormula &sharedFormulas); virtual EElementType getType () const; @@ -233,10 +246,14 @@ namespace OOX void PrepareForBinaryWriter(); void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); void ReadAttributes(XLS::BaseObjectPtr& obj); - void ReadComment(XmlUtils::CXmlLiteReader& oReader, CCommentItem* pComment); + void ReadTableBinPart(XLS::StreamCacheReaderPtr& reader); + void ReadCellInfo(XLS::CFRecordPtr& record); + void ReadValue(XLS::CFRecordPtr& record, XLS::CFRecordType::TypeId typeId); + void ReadComment(XmlUtils::CXmlLiteReader& oReader, CCommentItem* pComment); + bool checkArrayCell(XLS::CellRef &cellref, const sharedFormula& ArrFmlas); void AfterRead(); - //----------- 2003 + //----------- 2003 void After2003Read(); nullable pCommentItem; @@ -247,11 +264,11 @@ namespace OOX nullable_int iAcross; nullable_int iDown; public: - nullable m_oCellMetadata; - nullable m_oShowPhonetic; - nullable_uint m_oStyle; nullable m_oType; - nullable m_oValueMetadata; + nullable m_oShowPhonetic; + nullable_uint m_oStyle; + nullable_uint m_oCellMetadata; + nullable_uint m_oValueMetadata; nullable m_oRef; nullable_uint m_oRow; @@ -259,7 +276,9 @@ namespace OOX nullable m_oFormula; nullable m_oRichText; nullable m_oValue; -//----------------------------- +//----------------------------- + //число повторов чтобы хранить одинаковые в одной + nullable_uint m_oRepeated; nullable_string m_oCacheValue; }; @@ -281,15 +300,19 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromXMLToXLSB(XmlUtils::CXmlLiteReader& oReader, NSBinPptxRW::CXlsbBinaryWriter& oStream, CCellXLSB& oCell); void fromXLSB (NSBinPptxRW::CBinaryFileReader& oStream, _UINT16 nType); - void toXLSB (NSBinPptxRW::CXlsbBinaryWriter& oStream) const; + void toXLSB (NSBinPptxRW::CXlsbBinaryWriter& oStream) const; void fromBin(XLS::BaseObjectPtr& obj); + void fromBin(XLS::StreamCacheReaderPtr& reader); + XLS::BaseObjectPtr toBin(sharedFormula &sharedFormulas); virtual EElementType getType () const; private: void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + void ReadAttributes(XLS::CFRecordPtr& oReader); void ReadAttributes(XLS::BaseObjectPtr& obj); void CheckIndex(); + bool compressCell(CCell* pCell); public: nullable m_oCollapsed; @@ -304,6 +327,8 @@ namespace OOX nullable m_oThickBot; nullable m_oThickTop; nullable m_oDyDescent; + //число повторов для сжатия пустых строк + nullable_uint m_oRepeated; }; class CSheetData : public WritingElementWithChilds @@ -324,11 +349,13 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromXLSB (NSBinPptxRW::CBinaryFileReader& oStream, _UINT16 nType, CSVWriter* pCSVWriter, NSFile::CStreamWriter& oStreamWriter); void fromBin(XLS::BaseObjectPtr& obj); + void fromBin(XLS::StreamCacheReaderPtr& reader); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; - + nullable m_oXlsbPos; - + std::map> m_mapStyleMerges2003; // map(row, map(col, style)) void StyleFromMapStyleMerges2003(std::map &mapStyleMerges); void AfterRead(); @@ -337,8 +364,8 @@ namespace OOX void fromXLSBToXmlCell (CCell& pCell, CSVWriter* pCSVWriter, NSFile::CStreamWriter& oStreamWriter); void fromXLSBToXmlRowStart (CRow* pRow, CSVWriter* pCSVWriter, NSFile::CStreamWriter& oStreamWriter); void fromXLSBToXmlRowEnd (CRow* pRow, CSVWriter* pCSVWriter, NSFile::CStreamWriter& oStreamWriter, bool bLastRow = false); - void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + bool compressRow(CRow* pRow); // spreadsheets 2003 diff --git a/OOXML/XlsxFormat/Worksheets/Sparkline.cpp b/OOXML/XlsxFormat/Worksheets/Sparkline.cpp index 9263752056f..aa3bb6433b8 100644 --- a/OOXML/XlsxFormat/Worksheets/Sparkline.cpp +++ b/OOXML/XlsxFormat/Worksheets/Sparkline.cpp @@ -39,6 +39,7 @@ #include "../../XlsbFormat/Biff12_unions/SPARKLINEGROUP.h" #include "../../XlsbFormat/Biff12_records/BeginSparklineGroup.h" #include "../../XlsbFormat/Biff12_records/Sparkline.h" +#include "../../XlsbFormat/Biff12_records/FRTBegin.h" namespace OOX { @@ -92,6 +93,36 @@ namespace OOX m_oSqRef = oReader.GetText3(); } } + XLS::BaseObjectPtr CSparkline::toBin() + { + auto ptr(new XLSB::Sparkline); + XLS::BaseObjectPtr objectPtr(ptr); + ptr->FRTheader.fFormula = false; + ptr->FRTheader.fRef = false; + ptr->FRTheader.fRelID = false; + ptr->FRTheader.fSqref = false; + + if(m_oRef.IsInit()) + { + XLSB::FRTFormula formula; + formula.formula = m_oRef.get(); + ptr->FRTheader.rgFormulas.array.push_back(formula); + ptr->FRTheader.fFormula = true; + } + if(m_oSqRef.IsInit()) + { + XLSB::FRTSqref sqref; + sqref.fAdjDelete = false; + sqref.fDoAdjust = false; + sqref.fAdjChange = false; + sqref.fEdit = false; + sqref.sqrfx.strValue = m_oSqRef.get(); + ptr->FRTheader.rgSqrefs.array.push_back(sqref); + ptr->FRTheader.fSqref = true; + } + + return objectPtr; + } void CSparkline::fromBin(XLS::BaseObjectPtr& obj) { ReadAttributes(obj); @@ -175,6 +206,17 @@ namespace OOX m_arrItems.push_back(new CSparkline(sparkline)); } } + std::vector CSparklines::toBin() + { + std::vector sparclineVector; + + for(auto i:m_arrItems) + { + sparclineVector.push_back(i->toBin()); + } + + return sparclineVector; + } EElementType CSparklines::getType () const { return et_x_Sparklines; @@ -393,6 +435,182 @@ namespace OOX m_oSparklines = obj; } } + XLS::BaseObjectPtr CSparklineGroup::toBin() + { + auto ptr1(new XLSB::SPARKLINEGROUP); + XLS::BaseObjectPtr objectPtr(ptr1); + + auto ptr(new XLSB::BeginSparklineGroup); + ptr1->m_BrtBeginSparklineGroup = XLS::BaseObjectPtr{ptr}; + + if(m_oManualMax.IsInit()) + ptr->dManualMax.data.value = m_oManualMax->GetValue(); + else + ptr->dManualMax.data.value = 0; + if(m_oManualMin.IsInit()) + ptr->dManualMin.data.value = m_oManualMin->GetValue(); + else + ptr->dManualMin.data.value = 0; + if(m_oLineWeight.IsInit()) + ptr->dLineWeight.data.value = m_oLineWeight->GetValue(); + else + ptr->dLineWeight.data.value = 0; + if(m_oType.IsInit()) + ptr->isltype = static_castisltype)>(m_oType->GetValue()); + else + ptr->isltype = 0; + if(m_oDateAxis.IsInit()) + ptr->fDateAxis = m_oDateAxis->GetValue(); + else + ptr->fDateAxis = 0; + if(m_oDisplayEmptyCellsAs.IsInit()) + { + switch(m_oDisplayEmptyCellsAs.get()) + { + case st_dispblanksasZERO: + ptr->fShowEmptyCellAsZero = 0; + break; + case st_dispblanksasSPAN: + ptr->fShowEmptyCellAsZero = 2; + break; + case st_dispblanksasGAP: + default: + ptr->fShowEmptyCellAsZero = 1; + break; + } + } + if(m_oMarkers.IsInit()) + ptr->fMarkers = m_oMarkers->GetValue(); + else + ptr->fMarkers = false; + if(m_oHigh.IsInit()) + ptr->fHigh = m_oHigh->GetValue(); + else + ptr->fHigh = false; + if(m_oLow.IsInit()) + ptr->fLow = m_oLow->GetValue(); + else + ptr->fLow = false; + if(m_oFirst.IsInit()) + ptr->fFirst = m_oFirst->GetValue(); + else + ptr->fFirst = false; + if(m_oLast.IsInit()) + ptr->fLast = m_oLast->GetValue(); + else + ptr->fLast = false; + if(m_oNegative.IsInit()) + ptr->fNegative = m_oNegative->GetValue(); + else + ptr->fNegative = false; + if(m_oDisplayXAxis.IsInit()) + ptr->fAxis = m_oDisplayXAxis->GetValue(); + else + ptr->fAxis = false; + if(m_oDisplayHidden.IsInit()) + ptr->fDisplayHidden = m_oDisplayHidden->GetValue(); + else + ptr->fDisplayHidden = false; + if(m_oRightToLeft.IsInit()) + ptr->fRTL = m_oRightToLeft->GetValue(); + else + ptr->fRTL = false; + if(m_oMaxAxisType.IsInit()) + { + + if(m_oMaxAxisType.get()== SimpleTypes::Spreadsheet::ESparklineAxisMinMax::Group) + { + ptr->fIndividualAutoMax = false; + ptr->fGroupAutoMax = true; + } + else + { + ptr->fIndividualAutoMax = true; + ptr->fGroupAutoMax = false; + } + } + else + { + ptr->fIndividualAutoMax = true; + ptr->fGroupAutoMax = false; + } + if(m_oMinAxisType.IsInit()) + { + if(m_oMinAxisType.get()== SimpleTypes::Spreadsheet::ESparklineAxisMinMax::Group) + { + ptr->fIndividualAutoMin = false; + ptr->fGroupAutoMin = true; + } + else + { + ptr->fIndividualAutoMin = true; + ptr->fGroupAutoMin = false; + } + } + else + { + ptr->fIndividualAutoMin = true; + ptr->fGroupAutoMin = false; + } + + if(m_oColorSeries.IsInit()) + ptr->brtcolorSeries = m_oColorSeries->toColor(); + else + ptr->brtcolorSeries = m_oColorSeries->GetDefaultColor(); + + if(m_oColorNegative.IsInit()) + ptr->brtcolorNegative = m_oColorNegative->toColor(); + else + ptr->brtcolorNegative = m_oColorSeries->GetDefaultColor(); + + if(m_oColorAxis.IsInit()) + ptr->brtcolorAxis = m_oColorAxis->toColor(); + else + ptr->brtcolorAxis = m_oColorSeries->GetDefaultColor(); + + if(m_oColorMarkers.IsInit()) + ptr->brtcolorMarkers = m_oColorMarkers->toColor(); + else + ptr->brtcolorMarkers = m_oColorSeries->GetDefaultColor(); + + if(m_oColorFirst.IsInit()) + ptr->brtcolorFirst = m_oColorFirst->toColor(); + else + ptr->brtcolorFirst = m_oColorSeries->GetDefaultColor(); + + if(m_oColorLast.IsInit()) + ptr->brtcolorLast = m_oColorLast->toColor(); + else + ptr->brtcolorLast = m_oColorSeries->GetDefaultColor(); + + if(m_oColorHigh.IsInit()) + ptr->brtcolorHigh = m_oColorHigh->toColor(); + else + ptr->brtcolorHigh = m_oColorHigh->GetDefaultColor(); + + if(m_oColorLow.IsInit()) + ptr->brtcolorLow = m_oColorLow->toColor(); + else + ptr->brtcolorLow = m_oColorLow->GetDefaultColor(); + + ptr->FRTheader.fFormula = false; + ptr->FRTheader.fRef = false; + ptr->FRTheader.fSqref = false; + ptr->FRTheader.fRelID = false; + if(m_oRef.IsInit()) + { + XLSB::FRTFormula fmla; + ptr->FRTheader.rgFormulas.array.push_back(fmla); + ptr->FRTheader.rgFormulas.array[0].formula = m_oRef.get(); + ptr->FRTheader.fFormula = true; + } + for(auto i:m_oSparklines->m_arrItems) + { + ptr1->m_arBrtSparkline.push_back(i->toBin()); + } + + return objectPtr; + } EElementType CSparklineGroup::getType () const { return et_x_SparklineGroup; @@ -556,6 +774,18 @@ namespace OOX m_arrItems.push_back(new CSparklineGroup(sparklineGroup)); } } + XLS::BaseObjectPtr CSparklineGroups::toBin() + { + auto ptr(new XLSB::SPARKLINEGROUPS); + XLS::BaseObjectPtr objectPtr(ptr); + auto sparklineVersion(new XLSB::FRTBegin); + sparklineVersion->productVersion.product = 0; + sparklineVersion->productVersion.version = 0; + ptr->m_BrtFRTBegin = XLS::BaseObjectPtr{sparklineVersion}; + for(auto i:m_arrItems) + ptr->m_arSPARKLINEGROUP.push_back(i->toBin()); + return objectPtr; + } EElementType CSparklineGroups::getType () const { return et_x_SparklineGroups; diff --git a/OOXML/XlsxFormat/Worksheets/Sparkline.h b/OOXML/XlsxFormat/Worksheets/Sparkline.h index c2968e768d8..7c1c8086f43 100644 --- a/OOXML/XlsxFormat/Worksheets/Sparkline.h +++ b/OOXML/XlsxFormat/Worksheets/Sparkline.h @@ -62,6 +62,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; private: @@ -88,6 +89,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + std::vector toBin(); virtual EElementType getType () const; private: @@ -109,6 +111,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; private: @@ -163,6 +166,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; private: diff --git a/OOXML/XlsxFormat/Worksheets/Worksheet.cpp b/OOXML/XlsxFormat/Worksheets/Worksheet.cpp index 4c62e56793c..8aa1070b25a 100644 --- a/OOXML/XlsxFormat/Worksheets/Worksheet.cpp +++ b/OOXML/XlsxFormat/Worksheets/Worksheet.cpp @@ -49,6 +49,8 @@ #include "../../XlsbFormat/Biff12_unions/HLINKS.h" #include "../../XlsbFormat/Biff12_unions/MERGECELLS.h" +#include "../../Binary/XlsbFormat/FileTypes_SpreadsheetBin.h" + namespace OOX { namespace Spreadsheet @@ -66,11 +68,11 @@ namespace OOX if (xlsx) { m_bPrepareForBinaryWriter = true; // подготовка для бинарника при чтении - + xlsx->m_arWorksheets.push_back( this ); //xlsx->m_mapWorksheets.insert( std::make_pair(rId, this) ); } - else + else m_bPrepareForBinaryWriter = false; } CWorksheet::CWorksheet(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath, const std::wstring & rId, bool isChartSheet) : OOX::File(pMain), OOX::IFileContainer(pMain), WritingElement(pMain) @@ -86,11 +88,11 @@ namespace OOX if (xlsx) { m_bPrepareForBinaryWriter = true; - + xlsx->m_arWorksheets.push_back( this ); xlsx->m_mapWorksheets.insert( std::make_pair(rId, this) ); } - else + else m_bPrepareForBinaryWriter = false; read( oRootPath, oPath ); @@ -229,6 +231,133 @@ namespace OOX } } + XLS::BaseObjectPtr CWorksheet::WriteBin() const + { + if(m_bIsChartSheet) + { + XLSB::ChartSheetStreamPtr chartSheetStream(new XLSB::ChartSheetStream); + + if (m_oPageMargins.IsInit()) + chartSheetStream->m_BrtMargins = m_oPageMargins->toBin(); + if (m_oHeaderFooter.IsInit()) + chartSheetStream->m_HEADERFOOTER = m_oHeaderFooter->toBin(); + if (m_oDrawing.IsInit()) + chartSheetStream->m_BrtDrawing = m_oDrawing->toBin(); + if (m_oLegacyDrawing.IsInit()) + chartSheetStream->m_BrtLegacyDrawing = m_oLegacyDrawing->toBin(); + if (m_oLegacyDrawingHF.IsInit()) + chartSheetStream->m_BrtLegacyDrawingHF = m_oLegacyDrawingHF->toBin(); + if (m_oPicture.IsInit()) + chartSheetStream->m_BrtBkHim = m_oPicture->toBin(); + + if (m_oSheetViews.IsInit()) + chartSheetStream->m_CSVIEWS = m_oSheetViews->toBin(); + + if (m_oPageSetup.IsInit()) + chartSheetStream->m_BrtCsPageSetup = m_oPageSetup->toBinCs(); + + if(m_oSheetProtection.IsInit()) + { + if (m_oSheetProtection->m_oAlgorithmName.IsInit()) + chartSheetStream->m_BrtCsProtectionIso = m_oSheetProtection->toBinCS(); + else if(m_oSheetProtection->m_oPassword.IsInit()) + chartSheetStream->m_BrtCsProtection = m_oSheetProtection->toBinCS(); + } + + if (m_oSheetPr.IsInit()) + { + if(m_oSheetPr->m_oCodeName.IsInit()) + chartSheetStream->m_BrtCsProp = m_oSheetPr->toBinCs(); + } + + return chartSheetStream; + } + else + { + XLSB::WorkSheetStreamPtr workSheetStream(new XLSB::WorkSheetStream); + + if (m_oCols.IsInit()) + workSheetStream->m_arCOLINFOS = m_oCols->toBin(); + if (m_oDimension.IsInit()) + workSheetStream->m_BrtWsDim = m_oDimension->toBin(); + if (m_oDrawing.IsInit()) + workSheetStream->m_BrtDrawing = m_oDrawing->toBin(); + if (m_oLegacyDrawing.IsInit()) + workSheetStream->m_BrtLegacyDrawing = m_oLegacyDrawing->toBin(); + if (m_oLegacyDrawingHF.IsInit()) + workSheetStream->m_BrtLegacyDrawingHF = m_oLegacyDrawingHF->toBin(); + if (m_oHyperlinks.IsInit()) + workSheetStream->m_HLINKS = m_oHyperlinks->toBin(); + if (m_oMergeCells.IsInit()) + workSheetStream->m_MERGECELLS = m_oMergeCells->toBin(); + + if ( m_oSheetData.IsInit()) + workSheetStream->m_CELLTABLE = m_oSheetData->toBin(); + + if (m_oSheetFormatPr.IsInit()) + workSheetStream->m_BrtWsFmtInfo = m_oSheetFormatPr->toBin(); + if (m_oSheetViews.IsInit()) + workSheetStream->m_WSVIEWS2 = m_oSheetViews->toBin(); + if (m_oPageMargins.IsInit()) + workSheetStream->m_BrtMargins = m_oPageMargins->toBin(); + if (m_oPageSetup.IsInit()) + workSheetStream->m_BrtPageSetup = m_oPageSetup->toBin(); + if (m_oPrintOptions.IsInit()) + workSheetStream->m_BrtPrintOptions = m_oPrintOptions->toBin(); + if (m_oHeaderFooter.IsInit()) + workSheetStream->m_HEADERFOOTER = m_oHeaderFooter->toBin(); + if(m_oSheetProtection.IsInit()) + { + if (m_oSheetProtection->m_oAlgorithmName.IsInit()) + workSheetStream->m_BrtSheetProtectionIso = m_oSheetProtection->toBin(); + else if(m_oSheetProtection->m_oPassword.IsInit()) + workSheetStream->m_BrtSheetProtection = m_oSheetProtection->toBin(); + } + if (m_oTableParts.IsInit()) + workSheetStream->m_LISTPARTS = m_oTableParts->toBin(); + if (m_oSortState.IsInit()) + workSheetStream->m_SORTSTATE = m_oSortState->toBin(); + if (!m_arrConditionalFormatting.empty()) + for(auto &item : m_arrConditionalFormatting) + workSheetStream->m_arCONDITIONALFORMATTING.push_back(item->toBin()); + + if (m_oAutofilter.IsInit()) + workSheetStream->m_AUTOFILTER = m_oAutofilter->toBin(); + if (m_oDataValidations.IsInit()) + workSheetStream->m_DVALS = m_oDataValidations->toBin(); + if (m_oOleObjects.IsInit()) + workSheetStream->m_OLEOBJECTS = m_oOleObjects->toBin(); + if (m_oControls.IsInit()) + workSheetStream->m_ACTIVEXCONTROLS = m_oControls->toBin(); + if (m_oSheetPr.IsInit()) + workSheetStream->m_BrtWsProp = m_oSheetPr->toBin(); + if (m_oPicture.IsInit()) + workSheetStream->m_BrtBkHim = m_oPicture->toBin(); + if (m_oRowBreaks.IsInit()) + workSheetStream->m_RWBRK = m_oRowBreaks->toBinRow(); + if (m_oColBreaks.IsInit()) + workSheetStream->m_COLBRK = m_oColBreaks->toBinColumn(); + if (m_oDataConsolidate.IsInit()) + workSheetStream->m_DCON = m_oDataConsolidate->toBin(); + + if (m_oProtectedRanges.IsInit()) + { + if(m_oProtectedRanges->m_arrItems.empty()) + { + auto arrayPtr = m_oProtectedRanges->m_arrItems.back(); + if(arrayPtr->m_oSpinCount.IsInit() || arrayPtr->m_oSpinCount.IsInit() || arrayPtr->m_oSpinCount.IsInit() || arrayPtr->m_oSaltValue.IsInit()) + workSheetStream->m_arBrtRangeProtectionIso = m_oProtectedRanges->toBin(); + else + workSheetStream->m_arBrtRangeProtection = m_oProtectedRanges->toBin(); + } + } + if (m_oExtLst.IsInit()) + workSheetStream->m_FRTWORKSHEET = m_oExtLst->toBinWorksheet(); + + return workSheetStream; + } + + } void CWorksheet::read(const CPath& oRootPath, const CPath& oPath) { m_oReadPath = oPath; @@ -255,7 +384,11 @@ namespace OOX } void CWorksheet::PrepareAfterRead() { - PrepareComments(m_pComments, m_pThreadedComments, m_oLegacyDrawing.GetPointer()); + CXlsb* xlsb = dynamic_cast(File::m_pMainDocument); + if (!xlsb || !xlsb->m_bWriteToXlsb) + { + PrepareComments(m_pComments, m_pThreadedComments, m_oLegacyDrawing.GetPointer()); + } PrepareConditionalFormatting(); PrepareDataValidations(); } @@ -265,7 +398,7 @@ namespace OOX if ( oReader.IsEmptyNode() ) return; - + int nDocumentDepth = oReader.GetDepth(); std::wstring sName; @@ -417,7 +550,7 @@ namespace OOX void CWorksheet::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) { nullable_string sName; - + WritingElement_ReadAttributes_Start( oReader ) WritingElement_ReadAttributes_Read_if ( oReader, L"ss:Name", sName ) WritingElement_ReadAttributes_End( oReader ) @@ -501,10 +634,10 @@ namespace OOX } if(false == m_oSheetViews.IsInit()) m_oSheetViews.Init(); - + if(m_oSheetViews->m_arrItems.empty()) m_oSheetViews->m_arrItems.push_back(new CSheetView()); - + CSheetView* pSheetView = m_oSheetViews->m_arrItems.front(); if(false == pSheetView->m_oWorkbookViewId.IsInit()) @@ -584,52 +717,61 @@ namespace OOX if (bIsWritten) return; bIsWritten = true; + if (!m_bWriteDirectlyToFile) { - NSStringUtils::CStringBuilder sXml; - - toXMLStart(sXml); - toXML(sXml); - toXMLEnd(sXml); - - //NSFile::CFileBinary::SaveToFile(oPath.GetPath(), sXml.GetData()); - //for memory optimization for large files - - wchar_t* pXmlData = sXml.GetBuffer(); - LONG lwcharLen = (LONG)sXml.GetCurSize(); - const LONG lcurrentLen = 10485760; //10 Mbyte - LONG nCycles = lwcharLen / lcurrentLen; - - LONG lLen = 0; - BYTE* pData = NULL; - NSFile::CFileBinary oFile; - oFile.CreateFileW(oPath.GetPath()); - - while(nCycles--) - { - NSFile::CUtf8Converter::GetUtf8StringFromUnicode(pXmlData, lcurrentLen, pData, lLen); + CXlsb* xlsb = dynamic_cast(File::m_pMainDocument); + if ((xlsb) && (xlsb->m_bWriteToXlsb)) + { + XLS::BaseObjectPtr object = WriteBin(); + xlsb->WriteBin(oPath, object.get()); + } + else + { + NSStringUtils::CStringBuilder sXml; - oFile.WriteFile(pData, lLen); + toXMLStart(sXml); + toXML(sXml); + toXMLEnd(sXml); - pXmlData += lcurrentLen; + //NSFile::CFileBinary::SaveToFile(oPath.GetPath(), sXml.GetData()); + //for memory optimization for large files - RELEASEARRAYOBJECTS(pData); - } + wchar_t* pXmlData = sXml.GetBuffer(); + LONG lwcharLen = (LONG)sXml.GetCurSize(); + const LONG lcurrentLen = 10485760; //10 Mbyte + LONG nCycles = lwcharLen / lcurrentLen; - if(lwcharLen % lcurrentLen > 0) - { - NSFile::CUtf8Converter::GetUtf8StringFromUnicode(pXmlData, lwcharLen % lcurrentLen, pData, lLen); + LONG lLen = 0; + BYTE* pData = NULL; + NSFile::CFileBinary oFile; + oFile.CreateFileW(oPath.GetPath()); - oFile.WriteFile(pData, lLen); + while(nCycles--) + { + NSFile::CUtf8Converter::GetUtf8StringFromUnicode(pXmlData, lcurrentLen, pData, lLen); - RELEASEARRAYOBJECTS(pData); - } + oFile.WriteFile(pData, lLen); - oFile.CloseFile(); + pXmlData += lcurrentLen; - oContent.Registration( type().OverrideType(), oDirectory, oPath.GetFilename() ); - IFileContainer::Write( oPath, oDirectory, oContent ); - } + RELEASEARRAYOBJECTS(pData); + } + + if(lwcharLen % lcurrentLen > 0) + { + NSFile::CUtf8Converter::GetUtf8StringFromUnicode(pXmlData, lwcharLen % lcurrentLen, pData, lLen); + + oFile.WriteFile(pData, lLen); + + RELEASEARRAYOBJECTS(pData); + } + + oFile.CloseFile(); + } + oContent.Registration( type().OverrideType(), oDirectory, oPath.GetFilename() ); + IFileContainer::Write( oPath, oDirectory, oContent ); + } else { CPath oRealPath(oPath.GetDirectory() + FILE_SEPARATOR_STR + m_sOutputFilename); @@ -695,14 +837,14 @@ mc:Ignorable=\"x14ac\">"); if (!m_oLegacyDrawing.IsInit()) return oElement; if (!m_oLegacyDrawing->m_oId.IsInit()) return oElement; - + smart_ptr oFile = this->Find(m_oLegacyDrawing->m_oId->GetValue()); smart_ptr oVmlDrawing = oFile.smart_dynamic_cast(); OOX::WritingElement* pShapeElem = NULL; if (oVmlDrawing.IsInit()) { - oElement = oVmlDrawing->FindVmlObject(spid); + oElement = oVmlDrawing->FindVmlObject(spid); } return oElement; } @@ -721,6 +863,13 @@ mc:Ignorable=\"x14ac\">"); } const OOX::FileType CWorksheet::type() const { + CXlsb* xlsb = dynamic_cast(File::m_pMainDocument); + if ((xlsb) && (xlsb->m_bWriteToXlsb)) + { + if(m_bIsChartSheet) + return OOX::SpreadsheetBin::FileTypes::ChartsheetsBin; + return OOX::SpreadsheetBin::FileTypes::WorksheetBin; + } return m_bIsChartSheet?OOX::Spreadsheet::FileTypes::Chartsheets:OOX::Spreadsheet::FileTypes::Worksheet; } const CPath CWorksheet::DefaultDirectory() const @@ -729,7 +878,18 @@ mc:Ignorable=\"x14ac\">"); } const CPath CWorksheet::DefaultFileName() const { - return type().DefaultFileName(); + CXlsb* xlsb = dynamic_cast(File::m_pMainDocument); + if ((xlsb) && (xlsb->m_bWriteToXlsb)) + { + CPath name = type().DefaultFileName(); + + name.SetExtention(L"bin"); + return name; + } + else + { + return type().DefaultFileName(); + } } const CPath& CWorksheet::GetReadPath() const { diff --git a/OOXML/XlsxFormat/Worksheets/Worksheet.h b/OOXML/XlsxFormat/Worksheets/Worksheet.h index 240696a9abe..38a3ed1f65c 100644 --- a/OOXML/XlsxFormat/Worksheets/Worksheet.h +++ b/OOXML/XlsxFormat/Worksheets/Worksheet.h @@ -76,6 +76,7 @@ namespace OOX virtual ~CWorksheet(); void readBin(const CPath& oPath); + XLS::BaseObjectPtr WriteBin() const; virtual void read(const CPath& oPath); virtual void read(const CPath& oRootPath, const CPath& oPath); @@ -85,9 +86,9 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); - + virtual void write(const CPath& oPath, const CPath& oDirectory, CContentTypes& oContent) const; - + void toXMLStart(NSStringUtils::CStringBuilder& writer) const; void toXMLEnd(NSStringUtils::CStringBuilder& writer) const; virtual const OOX::FileType type() const; @@ -107,7 +108,7 @@ namespace OOX void ReadWorksheetOptions(XmlUtils::CXmlLiteReader& oReader); CPath m_oReadPath; - + bool m_bPrepareForBinaryWriter; bool m_bWriteDirectlyToFile; bool m_bIsChartSheet; diff --git a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp index d84bc296286..da9d39d6fc5 100644 --- a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp +++ b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp @@ -55,6 +55,7 @@ #include "../../XlsbFormat/Biff12_unions/DCON.h" #include "../../XlsbFormat/Biff12_records/BeginDCon.h" #include "../../XlsbFormat/Biff12_unions/DREFS.h" +#include "../../XlsbFormat/Biff12_records/BeginDRefs.h" #include "../../XlsbFormat/Biff12_records/DRef.h" #include "../../XlsbFormat/Biff12_unions/CSVIEWS.h" #include "../../XlsbFormat/Biff12_unions/CSVIEW.h" @@ -134,6 +135,51 @@ namespace OOX } } + XLS::BaseObjectPtr CProtectedRange::toBin() + { + XLS::BaseObjectPtr objectPtr; + if(m_oSpinCount.IsInit() || m_oSpinCount.IsInit() || m_oSpinCount.IsInit() || m_oSaltValue.IsInit()) + { + auto ptr(new XLSB::RangeProtectionIso); + objectPtr = XLS::BaseObjectPtr{ptr}; + if(m_oSpinCount.IsInit()) + ptr->dwSpinCount = m_oSpinCount->GetValue(); + if(m_oSqref.IsInit()) + ptr->sqRfX.strValue = m_oSqref.get(); + + if (m_oAlgorithmName.IsInit()) + ptr->ipdPasswordData.szAlgName = m_oAlgorithmName->GetValue(); + + if (m_oName.IsInit()) + ptr->rangeProtectionTitleSDRel.rgchTitle = m_oName.get(); + + BYTE * temp; + auto tempSize = 0; + NSFile::CBase64Converter::CBase64Converter::Decode(std::string{m_oHashValue.get().begin(), + m_oHashValue.get().end()}.c_str(), m_oHashValue.get().size(), temp, tempSize); + ptr->ipdPasswordData.rgbHash.cbLength = tempSize; + ptr->ipdPasswordData.rgbHash.rgbData = std::vector(temp, temp + tempSize); + delete[] temp; + + NSFile::CBase64Converter::Decode(std::string{m_oSaltValue.get().begin(), + m_oSaltValue.get().end()}.c_str(), m_oSaltValue.get().size(), temp, tempSize); + ptr->ipdPasswordData.rgbSalt.cbLength = tempSize; + ptr->ipdPasswordData.rgbSalt.rgbData = std::vector(temp, temp + tempSize); + delete[] temp; + } + else + { + auto ptr(new XLSB::RangeProtection); + objectPtr = XLS::BaseObjectPtr{ptr}; + if(m_oSqref.IsInit()) + ptr->sqRfX.strValue = m_oSqref.get(); + + if (m_oName.IsInit()) + ptr->rangeProtectionTitleSDRel.rgchTitle = m_oName.get(); + + } + return objectPtr; + } void CProtectedRange::fromBin(XLS::BaseObjectPtr& obj) { ReadAttributes(obj); @@ -239,6 +285,15 @@ namespace OOX } } } + std::vector CProtectedRanges::toBin() + { + std::vector result; + for(auto i:m_arrItems) + { + result.push_back(i->toBin()); + } + return result; + } void CProtectedRanges::fromBin(std::vector& obj) { for (auto &protRange : obj) @@ -386,6 +441,38 @@ namespace OOX { ReadAttributes(obj); } + XLS::BaseObjectPtr CPageMargins::toBin() + { + auto ptr(new XLSB::Margins); + XLS::BaseObjectPtr objPtr(ptr); + + if(m_oLeft.IsInit()) + ptr->xnumLeft.data.value = std::round(m_oLeft->GetValue()) / 100; + else + ptr->xnumLeft.data.value = 0; + + if(m_oTop.IsInit()) + ptr->xnumTop.data.value = std::round(m_oTop->GetValue()) / 100; + else + ptr->xnumTop.data.value = 0; + if(m_oRight.IsInit()) + ptr->xnumRight.data.value = std::round(m_oRight->GetValue()) / 100; + else + ptr->xnumRight.data.value = 0; + if(m_oBottom.IsInit()) + ptr->xnumBottom.data.value = std::round(m_oBottom->GetValue()) / 100; + else + ptr->xnumBottom.data.value = 0; + if(m_oHeader.IsInit()) + ptr->xnumHeader.data.value = std::round(m_oHeader->GetValue()) / 100; + else + ptr->xnumHeader.data.value = 0; + if(m_oFooter.IsInit()) + ptr->xnumFooter.data.value = std::round(m_oFooter->GetValue()) / 100; + else + ptr->xnumFooter.data.value = 0; + return objPtr; + } EElementType CPageMargins::getType() const { return et_x_PageMargins; @@ -478,6 +565,170 @@ namespace OOX { ReadAttributes(obj); } + XLS::BaseObjectPtr CPageSetup::toBin() + { + auto ptr(new XLSB::PageSetup); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oBlackAndWhite.IsInit()) + ptr->fNoColor = m_oBlackAndWhite->m_eValue; + else + ptr->fNoColor = false; + if (ptr->fNoColor && m_oCellComments.IsInit()) + { + if (m_oCellComments == SimpleTypes::Spreadsheet::ECellComments::cellcommentsAtEnd) + ptr->fNotes = true; + else if(m_oCellComments == SimpleTypes::Spreadsheet::ECellComments::cellcommentsAsDisplayed) + ptr->fNotes = false; + } + + if (m_oCopies.IsInit()) + ptr->iCopies = m_oCopies->m_eValue; + else + ptr->iCopies = 1; + + if (m_oDraft.IsInit()) + ptr->fDraft = m_oDraft->m_eValue; + else + ptr->fDraft = false; + + if (m_oErrors.IsInit()) + ptr->iErrors = m_oErrors->m_eValue; + else + ptr->iErrors = 0; + + if (m_oFirstPageNumber.IsInit()) + ptr->iPageStart = m_oFirstPageNumber->m_eValue; + else + ptr->iPageStart = 1; + + if (m_oFitToHeight.IsInit()) + ptr->iFitHeight = m_oFitToHeight->m_eValue; + else + ptr->iFitHeight = 1; + + if (m_oFitToWidth.IsInit()) + ptr->iFitWidth = m_oFitToWidth->m_eValue; + else + ptr->iFitWidth = 1; + + if (m_oHorizontalDpi.IsInit()) + ptr->iRes = m_oHorizontalDpi->m_eValue; + else + ptr->iRes = 600; + + if (m_oRId.IsInit()) + ptr->szRelID = m_oRId->GetValue(); + + if (m_oOrientation.IsInit() && m_oOrientation->GetValue() == SimpleTypes::EPageOrientation::pageorientLandscape) + { + ptr->fPortrait = false; + ptr->fLandscape = true; + } + else if(m_oOrientation.IsInit()) + { + ptr->fLandscape = false; + ptr->fPortrait = true; + } + else + { + ptr->fPortrait = false; + ptr->fLandscape = false; + ptr->fNoOrient = true; + } + + if (m_oPageOrder.IsInit() && m_oPageOrder->GetValue() == SimpleTypes::Spreadsheet::EPageOrder::pageorderOverThenDown) + ptr->fLeftToRight = true; + else + ptr->fLeftToRight = false; + + if (m_oPaperSize.IsInit()) + ptr->iPaperSize = m_oPaperSize->m_eValue; + else + ptr->iPaperSize = 9; + + if (m_oScale.IsInit()) + ptr->iScale = m_oScale->m_eValue; + else + ptr->iScale = 100; + + if (m_oUseFirstPageNumber.IsInit()) + ptr->fUsePage = m_oUseFirstPageNumber->m_eValue; + else + ptr->fUsePage = true; + + if (m_oVerticalDpi.IsInit()) + ptr->iVRes = m_oVerticalDpi->m_eValue; + else + ptr->iVRes = 0; + ptr->fEndNotes = false; + return objectPtr; + } + XLS::BaseObjectPtr CPageSetup::toBinCs() + { + auto ptr(new XLSB::CsPageSetup); + XLS::BaseObjectPtr objectPtr(ptr); + + if(m_oBlackAndWhite.IsInit()) + ptr->fNoColor = m_oBlackAndWhite->m_eValue; + else + ptr->fNoColor = false; + if (ptr->fNoColor) + { + if (m_oCellComments == SimpleTypes::Spreadsheet::ECellComments::cellcommentsAtEnd) + ptr->fNotes = true; + else if(m_oCellComments == SimpleTypes::Spreadsheet::ECellComments::cellcommentsAsDisplayed) + ptr->fNotes = false; + } + ptr->fEndNotes = false; + if (m_oCopies.IsInit()) + ptr->iCopies = m_oCopies->m_eValue; + else + ptr->iCopies = 0; + + if (m_oDraft.IsInit()) + ptr->fDraft = m_oDraft->m_eValue; + else + ptr->fDraft = 0; + if (m_oFirstPageNumber.IsInit()) + ptr->iPageStart = m_oFirstPageNumber->m_eValue; + else + ptr->iPageStart = 0; + if (m_oHorizontalDpi.IsInit()) + ptr->iRes = m_oHorizontalDpi->m_eValue; + else + ptr->iRes = 0; + if (m_oRId.IsInit()) + ptr->szRelID = m_oRId->GetValue(); + + if (m_oOrientation.IsInit()) + { + if (m_oOrientation == SimpleTypes::EPageOrientation::pageorientLandscape) + ptr->fLandscape = true; + else + ptr->fLandscape = false; + } + + if (m_oPaperSize.IsInit()) + ptr->iPaperSize = m_oPaperSize->m_eValue; + else + ptr->iPaperSize = 9; + + if (m_oScale.IsInit()) + ptr->iScale = m_oScale->m_eValue; + else + ptr->iScale = 100; + + if (m_oUseFirstPageNumber.IsInit()) + ptr->fUsePage = m_oUseFirstPageNumber->m_eValue; + else + ptr->fUsePage = false; + if (m_oVerticalDpi.IsInit()) + ptr->iVRes = m_oVerticalDpi->m_eValue; + else + ptr->iVRes = 0; + return objectPtr; + } + EElementType CPageSetup::getType() const { return et_x_PageSetup; @@ -623,6 +874,30 @@ namespace OOX { ReadAttributes(obj); } + XLS::BaseObjectPtr CPrintOptions::toBin() + { + auto ptr(new XLSB::PrintOptions); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oGridLines.IsInit()) + ptr->fPrintGrid = m_oGridLines->m_eValue; + else + ptr->fPrintGrid = false; + if(m_oGridLinesSet.IsInit()) + ptr->fPrintGrid = m_oGridLinesSet->m_eValue; + if(m_oHeadings.IsInit()) + ptr->fPrintHeaders = m_oHeadings->m_eValue; + else + ptr->fPrintHeaders = false; + if(m_oHorizontalCentered.IsInit()) + ptr->fHCenter = m_oHorizontalCentered->m_eValue; + else + ptr->fHCenter = false; + if(m_oVerticalCentered.IsInit()) + ptr->fVCenter = m_oVerticalCentered->m_eValue; + else + ptr->fVCenter = false; + return objectPtr; + } EElementType CPrintOptions::getType() const { return et_x_PrintOptions; @@ -677,6 +952,14 @@ namespace OOX { ReadAttributes(obj); } + XLS::BaseObjectPtr CDimension::toBin() + { + auto castedPtr(new XLSB::WsDim); + XLS::BaseObjectPtr ptr(castedPtr); + if (m_oRef.IsInit()) + castedPtr->rfx = m_oRef.get(); + return ptr; + } EElementType CDimension::getType() const { return et_x_Dimension; @@ -691,7 +974,7 @@ namespace OOX { auto ptr = static_cast(obj.get()); if (ptr != nullptr) - m_oRef = ptr->rfx.toString(); + m_oRef = ptr->rfx.toString(true, true); } CSheetFormatPr::CSheetFormatPr() @@ -732,6 +1015,49 @@ namespace OOX { ReadAttributes(obj); } + XLS::BaseObjectPtr CSheetFormatPr::toBin() + { + auto ptr(new XLSB::WsFmtInfo); + XLS::BaseObjectPtr Castedptr(ptr); + if(m_oBaseColWidth.IsInit()) + ptr->dxGCol = m_oBaseColWidth.get() * 256.; + else + ptr->dxGCol = 2304; + if(m_oDefaultColWidth.IsInit()) + { + ptr->cchDefColWidth = m_oDefaultColWidth.get(); + if(!m_oBaseColWidth.IsInit()) + { + ptr->dxGCol = m_oDefaultColWidth.get() * 256; + } + } + else + { + ptr->cchDefColWidth = 9; + } + if (m_oDefaultRowHeight.IsInit()) + ptr->miyDefRwHeight = m_oDefaultRowHeight.get() * 20; + else + ptr->miyDefRwHeight = 290; + + if (m_oOutlineLevelCol.IsInit()) + ptr->iOutLevelCol = m_oOutlineLevelCol.get(); + else + ptr->iOutLevelCol = 0; + if (m_oOutlineLevelRow.IsInit()) + ptr->iOutLevelRw = m_oOutlineLevelRow.get(); + else + ptr->iOutLevelRw = 0; + + if (m_oThickBottom.IsInit()) ptr->fExDesc = m_oThickBottom.get(); + else ptr->fExDesc = false; + if (m_oThickTop.IsInit()) ptr->fExAsc = m_oThickTop.get(); + else ptr->fExAsc = false; + if (m_oZeroHeight.IsInit()) ptr->fDyZero = m_oZeroHeight.get(); + else ptr->fDyZero = false; + ptr->fUnsynced = false; + return Castedptr; + } EElementType CSheetFormatPr::getType() const { return et_x_SheetFormatPr; @@ -756,9 +1082,12 @@ namespace OOX if (ptr != nullptr) { if (ptr->dxGCol != 0xFFFFFFFF) - m_oBaseColWidth = ptr->dxGCol / 256.; - - m_oDefaultColWidth = ptr->cchDefColWidth; + { + m_oDefaultColWidth = ptr->dxGCol / 256.; + m_oBaseColWidth = m_oDefaultColWidth.get(); + } + else + m_oDefaultColWidth = ptr->cchDefColWidth; if (ptr->fUnsynced) m_oDefaultRowHeight = ptr->miyDefRwHeight; @@ -808,6 +1137,44 @@ namespace OOX { ReadAttributes(obj); } + XLS::BaseObjectPtr CPane::toBin() + { + auto ptr(new XLSB::Pane); + XLS::BaseObjectPtr objectPtr(ptr); + + if(m_oActivePane.IsInit()) + { + if(m_oActivePane == SimpleTypes::Spreadsheet::EActivePane::activepaneBottomRight) + ptr->pnnAcct_xlsb = 0; + else if(m_oActivePane == SimpleTypes::Spreadsheet::EActivePane::activepaneTopRight) + ptr->pnnAcct_xlsb = 1; + else if(m_oActivePane == SimpleTypes::Spreadsheet::EActivePane::activepaneBottomLeft) + ptr->pnnAcct_xlsb = 2; + else if(m_oActivePane == SimpleTypes::Spreadsheet::EActivePane::activepaneTopLeft) + ptr->pnnAcct_xlsb = 3; + } + ptr->fFrozen = false; + ptr->fFrozenNoSplit = false; + if(m_oState.IsInit()) + { + if(m_oState == SimpleTypes::Spreadsheet::EPaneState::panestateFrozenSplit) + ptr->fFrozen = true; + else if(m_oState == SimpleTypes::Spreadsheet::EPaneState::panestateFrozen) + ptr->fFrozenNoSplit = true; + } + if(m_oTopLeftCell.IsInit()) + ptr->topLeftCell = m_oTopLeftCell.get(); + if(m_oXSplit.IsInit()) + ptr->xnumXSplit.data.value = m_oXSplit->GetValue(); + else + ptr->xnumXSplit.data.value = 0; + if(m_oYSplit.IsInit()) + ptr->xnumYSplit.data.value = m_oYSplit->GetValue(); + else + ptr->xnumYSplit.data.value = 0; + + return objectPtr; + } EElementType CPane::getType() const { return et_x_Pane; @@ -881,6 +1248,40 @@ namespace OOX { ReadAttributes(obj); } + XLS::BaseObjectPtr CSelection::toBin() + { + auto ptr(new XLSB::Sel); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oActiveCell.IsInit()) + ptr->activeCell = m_oActiveCell.get(); + else + ptr->activeCell = L"A1"; + if(m_oActiveCellId.IsInit()) + ptr->irefAct = m_oActiveCellId->GetValue(); + else + ptr->irefAct = 0; + if(m_oSqref.IsInit()) + ptr->sqref = m_oSqref.get(); + else + ptr->sqref = L"A1"; + if(m_oPane.IsInit()) + { + if(m_oPane == SimpleTypes::Spreadsheet::EActivePane::activepaneBottomRight) + ptr->pnn_xlsb = 0; + else if(m_oPane == SimpleTypes::Spreadsheet::EActivePane::activepaneTopRight) + ptr->pnn_xlsb = 1; + else if(m_oPane == SimpleTypes::Spreadsheet::EActivePane::activepaneBottomLeft) + ptr->pnn_xlsb = 2; + else if(m_oPane == SimpleTypes::Spreadsheet::EActivePane::activepaneTopLeft) + ptr->pnn_xlsb = 3; + } + else + ptr->pnn_xlsb = 3; + ptr->rwAct = 0; + ptr->colAct = 0; + + return objectPtr; + } EElementType CSelection::getType() const { return et_x_Selection; @@ -1013,6 +1414,117 @@ namespace OOX ReadAttributes(pCSVIEW->m_BrtBeginCsView); } } + XLS::BaseObjectPtr CSheetView::toBin() + { + auto ptr(new XLSB::WSVIEW2); + XLS::BaseObjectPtr castedPtr(ptr); + auto pWsView(new XLSB::BeginWsView); + ptr->m_BrtBeginWsView = XLS::BaseObjectPtr{pWsView}; + + if (m_oColorId.IsInit()) + pWsView->icvHdr = m_oColorId->m_eValue; + else + pWsView->icvHdr = 64; + if (m_oDefaultGridColor.IsInit()) + pWsView->fDefaultHdr = m_oDefaultGridColor->m_eValue; + else + pWsView->fDefaultHdr = true; + if (m_oRightToLeft.IsInit()) + pWsView->fRightToLeft = m_oRightToLeft->m_eValue; + else + pWsView->fRightToLeft = false; + if (m_oShowFormulas.IsInit()) + pWsView->fDspFmlaRt = m_oShowFormulas->m_eValue; + else + pWsView->fDspFmlaRt = false; + if (m_oShowGridLines.IsInit()) + pWsView->fDspGridRt = m_oShowGridLines->m_eValue; + else + pWsView->fDspGridRt = true; + if (m_oShowOutlineSymbols.IsInit()) + pWsView->fDspGuts = m_oShowOutlineSymbols->m_eValue; + else + pWsView->fDspGuts = true; + if (m_oShowRowColHeaders.IsInit()) + pWsView->fDspRwColRt = m_oShowRowColHeaders->m_eValue; + else + pWsView->fDspRwColRt = true; + if (m_oShowRuler.IsInit()) + pWsView->fDspRuler = m_oShowRuler->m_eValue; + else + pWsView->fDspRuler = false; + if (m_oShowWhiteSpace.IsInit()) + pWsView->fWhitespaceHidden = !m_oShowWhiteSpace->m_eValue; + else + pWsView->fWhitespaceHidden = false; + if (m_oShowZeros.IsInit()) + pWsView->fDspZerosRt = m_oShowZeros->m_eValue; + else + pWsView->fDspZerosRt = true; + if (m_oTabSelected.IsInit()) + pWsView->fSelected = m_oTabSelected->m_eValue; + else + pWsView->fSelected = false; + if(m_oTopLeftCell.IsInit()) + pWsView->topLeftCell = m_oTopLeftCell.get(); + else + pWsView->topLeftCell = L"A1"; + if (m_oView.IsInit()) + pWsView->xlView = m_oView->m_eValue; + else + pWsView->xlView = 0; + if (m_oWindowProtection.IsInit()) + pWsView->fWnProt = m_oWindowProtection->m_eValue; + else + pWsView->fWnProt = false; + if (m_oWorkbookViewId.IsInit()) + pWsView->iWbkView = m_oWorkbookViewId->m_eValue; + if (m_oZoomScale.IsInit()) + pWsView->wScale = m_oZoomScale->m_eValue; + else + pWsView->wScale = 100; + if (m_oZoomScaleNormal.IsInit()) + pWsView->wScaleNormal = m_oZoomScaleNormal->m_eValue; + else + pWsView->wScaleNormal = 0; + if (m_oZoomScalePageLayoutView.IsInit()) + pWsView->wScalePLV = m_oZoomScalePageLayoutView->m_eValue; + else + pWsView->wScalePLV = 0; + if (m_oZoomScaleSheetLayoutView.IsInit()) + pWsView->wScaleSLV = m_oZoomScaleSheetLayoutView->m_eValue; + else + pWsView->wScaleSLV = 0; + pWsView->rwTop = 0; + pWsView->colLeft = 0; + if(m_oPane.IsInit()) + ptr->m_BrtPane = m_oPane->toBin(); + + for(auto i:m_arrItems) + { + ptr->m_arBrtSel.push_back(i->toBin()); + } + return castedPtr; + + } + XLS::BaseObjectPtr CSheetView::toBinCs() + { + auto pWsView(new XLSB::BeginCsView); + XLS::BaseObjectPtr castedPtr(pWsView); + if(m_oTabSelected.IsInit()) + pWsView->fSelected = m_oTabSelected->m_eValue; + else + pWsView->fSelected = false; + if(m_oWorkbookViewId.IsInit()) + pWsView->iWbkView = m_oWorkbookViewId->m_eValue; + else + pWsView->iWbkView = 0; + if(m_oZoomScale.IsInit()) + pWsView->wScale = m_oZoomScale->m_eValue; + else + pWsView->wScale = 100; + return castedPtr; + } EElementType CSheetView::getType() const { return et_x_SheetView; @@ -1056,7 +1568,7 @@ namespace OOX m_oShowOutlineSymbols = pWsView->fDspGuts; m_oShowRowColHeaders = pWsView->fDspRwColRt; m_oShowRuler = pWsView->fDspRuler; - m_oShowWhiteSpace = pWsView->fWhitespaceHidden; + m_oShowWhiteSpace = !pWsView->fWhitespaceHidden; m_oShowZeros = pWsView->fDspZerosRt; m_oTabSelected = pWsView->fSelected; m_oTopLeftCell = pWsView->topLeftCell; @@ -1152,6 +1664,21 @@ namespace OOX } } } + XLS::BaseObjectPtr CSheetViews::toBin() + { + auto castedPtr(new XLSB::WSVIEWS2); + XLS::BaseObjectPtr ptr(castedPtr); + for(auto i:m_arrItems) + castedPtr->m_arWSVIEW2.push_back(i->toBin()); + return ptr; + } + XLS::BaseObjectPtr CSheetViews::toBinCs() + { + auto ptr(new XLSB::CSVIEWS); + for(auto i:m_arrItems) + ptr->m_arCSVIEW.push_back(i->toBinCs()); + return XLS::BaseObjectPtr{ptr}; + } EElementType CSheetViews::getType() const { return et_x_SheetViews; @@ -1188,6 +1715,18 @@ namespace OOX { ReadAttributes(obj); } + void CPageSetUpPr::toBin(XLS::BaseObjectPtr& obj) + { + auto ptr = static_cast(obj.get()); + if(m_oAutoPageBreaks.IsInit()) + ptr->fShowAutoBreaks = m_oAutoPageBreaks->GetValue(); + else + ptr->fShowAutoBreaks = true; + if(m_oFitToPage.IsInit()) + ptr->fFitToPage = m_oFitToPage->GetValue(); + else + ptr->fFitToPage = false; + } EElementType CPageSetUpPr::getType() const { return et_x_PageSetUpPr; @@ -1198,7 +1737,7 @@ namespace OOX if (ptr != nullptr) { m_oAutoPageBreaks = ptr->fShowAutoBreaks; - m_oFitToPage = ptr->fFitToPage;; + m_oFitToPage = ptr->fFitToPage; } } void CPageSetUpPr::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) @@ -1242,6 +1781,26 @@ namespace OOX { ReadAttributes(obj); } + void COutlinePr::toBin(XLS::BaseObjectPtr& obj) + { + auto ptr = static_cast(obj.get()); + if(m_oApplyStyles.IsInit()) + ptr->fApplyStyles = m_oApplyStyles->GetValue(); + else + ptr->fApplyStyles = false; + if(m_oShowOutlineSymbols.IsInit()) + ptr->fShowOutlineSymbols = m_oShowOutlineSymbols->GetValue(); + else + ptr->fShowOutlineSymbols = true; + if(m_oSummaryBelow.IsInit()) + ptr->fRowSumsBelow = m_oSummaryBelow->GetValue(); + else + ptr->fRowSumsBelow = true; + if(m_oSummaryRight.IsInit()) + ptr->fColSumsRight = m_oSummaryRight->GetValue(); + else + ptr->fColSumsRight = true; + } EElementType COutlinePr::getType() const { return et_x_OutlinePr; @@ -1329,6 +1888,87 @@ namespace OOX m_oOutlinePr = oReader; } } + XLS::BaseObjectPtr CSheetPr::toBin() + { + auto ptr(new XLSB::WsProp); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oCodeName.IsInit()) + ptr->strName.value = m_oCodeName.get(); + else + ptr->strName.value = L""; + if(m_oEnableFormatConditionsCalculation.IsInit()) + ptr->fCondFmtCalc = m_oEnableFormatConditionsCalculation->GetValue(); + if(m_oFilterMode.IsInit()) + ptr->fFilterMode = m_oFilterMode->GetValue(); + else + ptr->fFilterMode = false; + if(m_oPublished.IsInit()) + ptr->fPublish = m_oPublished->GetValue(); + else + ptr->fPublish = true; + if(m_oSyncHorizontal.IsInit()) + ptr->fSyncHoriz = m_oSyncHorizontal->GetValue(); + else + ptr->fSyncHoriz = false; + if(m_oSyncVertical.IsInit()) + ptr->fSyncVert = m_oSyncVertical->GetValue(); + else + ptr->fSyncVert = false; + if(m_oTransitionEntry.IsInit()) + ptr->fAltFormulaEntry = m_oTransitionEntry->GetValue(); + else + ptr->fAltFormulaEntry = false; + if(m_oTransitionEvaluation.IsInit()) + ptr->fAltExprEval = m_oTransitionEvaluation->GetValue(); + else + ptr->fAltExprEval = false; + if (m_oSyncRef.IsInit()) + ptr->syncRef = m_oSyncRef.get(); + else + ptr->syncRef = L""; + if(m_oTabColor.IsInit()) + ptr->brtcolorTab = m_oTabColor->toColor(); + else + ptr->brtcolorTab = m_oTabColor->GetDefaultColor(); + if(m_oPageSetUpPr.IsInit()) + m_oPageSetUpPr->toBin(objectPtr); + else + { + ptr->fFitToPage = false; + ptr->fShowAutoBreaks = true; + } + if(m_oOutlinePr.IsInit()) + m_oOutlinePr->toBin(objectPtr); + else + { + ptr->fApplyStyles = false; + ptr->fColSumsRight = true; + ptr->fRowSumsBelow = true; + ptr->fShowOutlineSymbols = true; + } + ptr->fDialog = false; + ptr->fCondFmtCalc = false; + return objectPtr; + } + XLS::BaseObjectPtr CSheetPr::toBinCs() + { + auto ptr(new XLSB::CsProp); + + if(m_oCodeName.IsInit()) + ptr->strName = m_oCodeName.get(); + else + ptr->strName.value.setSize(0xFFFFFFFF); + if(m_oPublished.IsInit()) + ptr->fPublish = m_oPublished->GetValue(); + else + ptr->fPublish = false; + if(m_oTabColor.IsInit()) + ptr->brtcolorTab = m_oTabColor->toColor(); + else + ptr->brtcolorTab = m_oTabColor->GetDefaultColor(); + return XLS::BaseObjectPtr{ptr}; + } + void CSheetPr::fromBin(XLS::BaseObjectPtr& obj) { if (obj->get_type() == XLS::typeWsProp) @@ -1563,6 +2203,58 @@ namespace OOX } } } + XLS::BaseObjectPtr CHeaderFooter::toBin() + { + auto ptr(new XLSB::HEADERFOOTER); + + XLS::BaseObjectPtr objectPtr(ptr); + + auto castedBegin(new XLSB::BeginHeaderFooter); + ptr->m_BrtBeginHeaderFooter = XLS::BaseObjectPtr{castedBegin}; + + if(m_oAlignWithMargins.IsInit()) + castedBegin->fHFAlignMargins = m_oAlignWithMargins->m_eValue; + else + castedBegin->fHFAlignMargins = false; + if(m_oDifferentFirst.IsInit()) + castedBegin->fHFDiffFirst = m_oDifferentFirst->m_eValue; + else + castedBegin->fHFDiffFirst = false; + if(m_oDifferentOddEven.IsInit()) + castedBegin->fHFDiffOddEven = m_oDifferentOddEven->m_eValue; + else + castedBegin->fHFDiffOddEven = false; + if(m_oScaleWithDoc.IsInit()) + castedBegin->fHFScaleWithDoc = m_oScaleWithDoc->m_eValue; + else + castedBegin->fHFScaleWithDoc = false; + + if(m_oOddHeader.IsInit()) + castedBegin->stHeader = m_oOddHeader->m_sText; + else + castedBegin->stHeader = false; + if(m_oOddFooter.IsInit()) + castedBegin->stFooter = m_oOddFooter->m_sText; + else + castedBegin->stFooter = false; + if(m_oEvenHeader.IsInit()) + castedBegin->stHeaderEven = m_oEvenHeader->m_sText; + else + castedBegin->stHeaderEven = false; + if(m_oEvenFooter.IsInit()) + castedBegin->stFooterEven = m_oEvenFooter->m_sText; + else + castedBegin->stFooterEven = false; + if(m_oFirstHeader.IsInit()) + castedBegin->stHeaderFirst = m_oFirstHeader->m_sText; + else + castedBegin->stHeaderFirst = false; + if(m_oFirstFooter.IsInit()) + castedBegin->stFooterFirst = m_oFirstFooter->m_sText; + else + castedBegin->stFooterFirst = false; + return objectPtr; + } EElementType CHeaderFooter::getType() const { return et_x_HeaderFooterWorksheet; @@ -1639,6 +2331,14 @@ namespace OOX { ReadAttributes(obj); } + XLS::BaseObjectPtr CLegacyDrawingHFWorksheet::toBin() + { + auto castedPtr(new XLSB::LegacyDrawingHF); + XLS::BaseObjectPtr ptr(castedPtr); + if (m_oId.IsInit()) + castedPtr->stRelId.value = m_oId->GetValue(); + return ptr; + } EElementType CLegacyDrawingHFWorksheet::getType() const { return et_x_LegacyDrawingHFWorksheet; @@ -1705,6 +2405,18 @@ namespace OOX if (!oReader.IsEmptyNode()) oReader.ReadTillEnd(); } + XLS::BaseObjectPtr CPictureWorksheet::toBin() + { + auto ptr(new XLSB::BkHim); + XLS::BaseObjectPtr objectPtr(ptr); + + if(m_oId.IsInit()) + ptr->rgb.value = m_oId->GetValue(); + else + ptr->rgb.value.setSize(0XFFFFFFFF); + + return objectPtr; + } void CPictureWorksheet::fromBin(XLS::BaseObjectPtr& obj) { ReadAttributes(obj); @@ -1759,6 +2471,32 @@ namespace OOX if (!oReader.IsEmptyNode()) oReader.ReadTillEnd(); } + XLS::BaseObjectPtr CBreak::toBin() + { + auto ptr(new XLSB::Brk); + XLS::BaseObjectPtr objectPtr(ptr); + + if(m_oId.IsInit()) + ptr->unRwCol = m_oId->GetValue(); + if(m_oMan.IsInit()) + ptr->fMan = m_oMan->GetValue(); + else + ptr->fMan = false; + if(m_oMin.IsInit()) + ptr->unColRwStrt = m_oMin->GetValue(); + else + ptr->unColRwStrt = 0; + if(m_oMax.IsInit()) + ptr->unColRwEnd = m_oMax->GetValue(); + else + ptr->unColRwEnd = 0; + if(m_oPt.IsInit()) + ptr->fPivot = m_oPt->GetValue(); + else + ptr->fPivot = false; + + return objectPtr; + } void CBreak::fromBin(XLS::BaseObjectPtr& obj) { ReadAttributes(obj); @@ -1845,6 +2583,44 @@ namespace OOX } } } + XLS::BaseObjectPtr CRowColBreaks::toBinRow() + { + auto ptr(new XLSB::RWBRK); + XLS::BaseObjectPtr objectPtr(ptr); + auto rowPtr(new XLSB::BeginRwBrk); + ptr->m_BrtBeginRwBrk = XLS::BaseObjectPtr{rowPtr}; + if(m_oCount.IsInit()) + rowPtr->ibrkMac = m_oCount->GetValue(); + else + rowPtr->ibrkMac = m_arrItems.size(); + if(m_oManualBreakCount.IsInit()) + rowPtr->ibrkManMac = m_oManualBreakCount->GetValue(); + else + rowPtr->ibrkManMac = rowPtr->ibrkMac; + for(auto i:m_arrItems) + { + ptr->m_arBrtBrk.push_back(i->toBin()); + } + return objectPtr; + } + + XLS::BaseObjectPtr CRowColBreaks::toBinColumn() + { + auto ptr(new XLSB::COLBRK); + XLS::BaseObjectPtr objectPtr(ptr); + auto colPtr(new XLSB::BeginColBrk); + ptr->m_BrtBeginColBrk = XLS::BaseObjectPtr{colPtr}; + if(m_oCount.IsInit()) + colPtr->ibrkMac = m_oCount->GetValue(); + if(m_oManualBreakCount.IsInit()) + colPtr->ibrkManMac = m_oManualBreakCount->GetValue(); + for(auto i:m_arrItems) + { + ptr->m_arBrtBrk.push_back(i->toBin()); + } + return objectPtr; + } + void CRowColBreaks::fromBin(XLS::BaseObjectPtr& obj) { if (obj->get_type() == XLS::typeRWBRK) @@ -1954,6 +2730,279 @@ namespace OOX { ReadAttributes(obj); } + XLS::BaseObjectPtr CSheetProtection::toBin() + { + if(m_oPassword.IsInit()) + { + auto ptr(new XLSB::SheetProtection); + XLS::BaseObjectPtr castedPtr(ptr); + + if (m_oPassword.IsInit()) + ptr->protpwd = std::stoul(m_oPassword.get(),nullptr, 16); + else + ptr->protpwd = 0; + + if (m_oAutoFilter.IsInit()) + ptr->fAutoFilter = !m_oAutoFilter->GetValue(); + else + ptr->fAutoFilter = true; + + if (m_oDeleteColumns.IsInit()) + ptr->fDeleteColumns = !m_oDeleteColumns->GetValue(); + else + ptr->fDeleteColumns= true; + + if (m_oDeleteRows.IsInit()) + ptr->fDeleteRows = !m_oDeleteRows->GetValue(); + else + ptr->fDeleteRows = true; + + if (m_oFormatCells.IsInit()) + ptr->fFormatCells = !m_oFormatCells->GetValue(); + else + ptr->fFormatCells = true; + + if (m_oFormatColumns.IsInit()) + ptr->fFormatColumns = !m_oFormatColumns->GetValue(); + else + ptr->fFormatColumns = true; + + if (m_oFormatRows.IsInit()) + ptr->fFormatRows = !m_oFormatRows->GetValue(); + else + ptr->fFormatRows = true; + + if (m_oInsertColumns.IsInit()) + ptr->fInsertColumns = !m_oInsertColumns->GetValue(); + else + ptr->fInsertColumns = true; + + if (m_oInsertHyperlinks.IsInit()) + ptr->fInsertHyperlinks = !m_oInsertHyperlinks->GetValue(); + else + ptr->fInsertHyperlinks = true; + + if (m_oInsertRows.IsInit()) + ptr->fInsertRows = !m_oInsertRows->GetValue(); + else + ptr->fInsertRows = true; + + if (m_oObjects.IsInit()) + ptr->fObjects = !m_oObjects->GetValue(); + else + ptr->fObjects = true; + + if (m_oPivotTables.IsInit()) + ptr->fPivotTables = !m_oPivotTables->GetValue(); + else + ptr->fPivotTables = true; + + if (m_oScenarios.IsInit()) + ptr->fScenarios = !m_oScenarios->GetValue(); + else + ptr->fScenarios = true; + + if (m_oSelectLockedCells.IsInit()) + ptr->fSelLockedCells = !m_oSelectLockedCells->GetValue(); + else + ptr->fSelLockedCells = true; + + if (m_oSelectUnlockedCells.IsInit()) + ptr->fSelUnlockedCells = !m_oSelectUnlockedCells->GetValue(); + else + ptr->fSelUnlockedCells = true; + + if (m_oSheet.IsInit()) + ptr->fLocked = m_oSheet->GetValue(); + else + ptr->fLocked = false; + + if (m_oSort.IsInit()) + ptr->fSort = !m_oSort->GetValue(); + else + ptr->fSort = true; + + return castedPtr; + } + else + { + auto ptr(new XLSB::SheetProtectionIso); + XLS::BaseObjectPtr castedPtr(ptr); + if(m_oAlgorithmName.IsInit()) + ptr->ipdPasswordData.szAlgName = m_oAlgorithmName->ToString(); + if(m_oSpinCount.IsInit()) + ptr->dwSpinCount = m_oSpinCount->GetValue(); + if(m_oHashValue.IsInit()) + { + BYTE * temp; + auto tempSize = 0; + NSFile::CBase64Converter::CBase64Converter::Decode(std::string{m_oHashValue.get().begin(), + m_oHashValue.get().end()}.c_str(), m_oHashValue.get().size(), temp, tempSize); + ptr->ipdPasswordData.rgbHash.cbLength = tempSize; + ptr->ipdPasswordData.rgbHash.rgbData = std::vector(temp, temp + tempSize); + delete[] temp; + } + + if(m_oSaltValue.IsInit()) + { + BYTE * temp; + auto tempSize = 0; + NSFile::CBase64Converter::Decode(std::string{m_oSaltValue.get().begin(), + m_oSaltValue.get().end()}.c_str(), m_oSaltValue.get().size(), temp, tempSize); + ptr->ipdPasswordData.rgbSalt.cbLength = tempSize; + ptr->ipdPasswordData.rgbSalt.rgbData = std::vector(temp, temp + tempSize); + delete[] temp; + } + + if (m_oAutoFilter.IsInit()) + ptr->fAutoFilter = !m_oAutoFilter->GetValue(); + else + ptr->fAutoFilter = true; + + if (m_oDeleteColumns.IsInit()) + ptr->fDeleteColumns = !m_oDeleteColumns->GetValue(); + else + ptr->fDeleteColumns= true; + + if (m_oDeleteRows.IsInit()) + ptr->fDeleteRows = !m_oDeleteRows->GetValue(); + else + ptr->fDeleteRows = true; + + if (m_oFormatCells.IsInit()) + ptr->fFormatCells = !m_oFormatCells->GetValue(); + else + ptr->fFormatCells = true; + + if (m_oFormatColumns.IsInit()) + ptr->fFormatColumns = !m_oFormatColumns->GetValue(); + else + ptr->fFormatColumns = true; + + if (m_oFormatRows.IsInit()) + ptr->fFormatRows = !m_oFormatRows->GetValue(); + else + ptr->fFormatRows = true; + + if (m_oInsertColumns.IsInit()) + ptr->fInsertColumns = !m_oInsertColumns->GetValue(); + else + ptr->fInsertColumns = true; + + if (m_oInsertHyperlinks.IsInit()) + ptr->fInsertHyperlinks = !m_oInsertHyperlinks->GetValue(); + else + ptr->fInsertHyperlinks = true; + + if (m_oInsertRows.IsInit()) + ptr->fInsertRows = !m_oInsertRows->GetValue(); + else + ptr->fInsertRows = true; + + if (m_oObjects.IsInit()) + ptr->fObjects = !m_oObjects->GetValue(); + else + ptr->fObjects = true; + + if (m_oPivotTables.IsInit()) + ptr->fPivotTables = !m_oPivotTables->GetValue(); + else + ptr->fPivotTables = true; + + if (m_oScenarios.IsInit()) + ptr->fScenarios = !m_oScenarios->GetValue(); + else + ptr->fScenarios = true; + + if (m_oSelectLockedCells.IsInit()) + ptr->fSelLockedCells = !m_oSelectLockedCells->GetValue(); + else + ptr->fSelLockedCells = true; + + if (m_oSelectUnlockedCells.IsInit()) + ptr->fSelUnlockedCells = !m_oSelectUnlockedCells->GetValue(); + else + ptr->fSelUnlockedCells = true; + + if (m_oSheet.IsInit()) + ptr->fLocked = m_oSheet->GetValue(); + else + ptr->fLocked = false; + + if (m_oSort.IsInit()) + ptr->fSort = !m_oSort->GetValue(); + else + ptr->fSort = true; + + return castedPtr; + } + } + XLS::BaseObjectPtr CSheetProtection::toBinCS() + { + XLS::BaseObjectPtr objectPtr; + if(m_oPassword.IsInit()) + { + auto ptr(new XLSB::CsProtection); + objectPtr = XLS::BaseObjectPtr{ptr}; + ptr->protpwd = std::stoul(m_oPassword.get(), nullptr, 16); + if(m_oObjects.IsInit()) + ptr->fObjects = m_oObjects->GetValue(); + else + ptr->fObjects = false; + if(m_oSheet.IsInit()) + ptr->fLocked = m_oSheet->GetValue(); + else + ptr->fObjects = false; + } + else + { + auto ptr(new XLSB::CsProtectionIso); + objectPtr = XLS::BaseObjectPtr{ptr}; + + if(m_oAlgorithmName.IsInit()) + ptr->ipdPasswordData.szAlgName = m_oAlgorithmName->ToString(); + else + ptr->ipdPasswordData.szAlgName = false; + if(m_oSpinCount.IsInit()) + ptr->dwSpinCount = m_oSpinCount->GetValue(); + else + ptr->dwSpinCount = 0; + + if(m_oHashValue.IsInit()) + { + BYTE * temp; + auto tempSize = 0; + NSFile::CBase64Converter::CBase64Converter::Decode(std::string{m_oHashValue.get().begin(), + m_oHashValue.get().end()}.c_str(), m_oHashValue.get().size(), temp, tempSize); + ptr->ipdPasswordData.rgbHash.cbLength = tempSize; + ptr->ipdPasswordData.rgbHash.rgbData = std::vector(temp, temp + tempSize); + delete[] temp; + } + + if(m_oSaltValue.IsInit()) + { + BYTE * temp; + auto tempSize = 0; + NSFile::CBase64Converter::Decode(std::string{m_oSaltValue.get().begin(), + m_oSaltValue.get().end()}.c_str(), m_oSaltValue.get().size(), temp, tempSize); + ptr->ipdPasswordData.rgbSalt.cbLength = tempSize; + ptr->ipdPasswordData.rgbSalt.rgbData = std::vector(temp, temp + tempSize); + delete[] temp; + } + + if(m_oObjects.IsInit()) + ptr->fObjects = m_oObjects->GetValue(); + else + ptr->fObjects = false; + if(m_oSheet.IsInit()) + ptr->fLocked = m_oSheet->GetValue(); + else + ptr->fObjects = false; + + } + + return objectPtr; + } EElementType CSheetProtection::getType() const { return et_x_SheetProtection; @@ -2102,6 +3151,34 @@ namespace OOX { ReadAttributes(obj); } + XLS::BaseObjectPtr CDataRef::toBin() + { + auto ptr(new XLSB::DRef); + XLS::BaseObjectPtr objectPtr(ptr); + + if (m_oId.IsInit()) + ptr->relId.value = m_oId->GetValue(); + else + ptr->relId.value = L""; + + if (m_oName.IsInit()) + ptr->xstrName = m_oName.get(); + else + { + ptr->xstrName = L""; + ptr->fName = false; + ptr->fBuiltin = false; + } + if (m_oRef.IsInit()) + ptr->rfx = m_oRef.get(); + + if (m_oSheet.IsInit()) + ptr->xstrSheet = m_oSheet.get(); + else + ptr->xstrSheet = L""; + + return objectPtr; + } EElementType CDataRef::getType() const { return et_x_DataRef; @@ -2118,7 +3195,7 @@ namespace OOX m_oName = ptr->xstrName.value(); if (!ptr->rfx.toString().empty()) - m_oRef = ptr->rfx.toString(); + m_oRef = ptr->rfx.toString(true, true); if (!ptr->xstrSheet.value().empty()) m_oSheet = ptr->xstrSheet.value(); @@ -2193,6 +3270,20 @@ namespace OOX m_arrItems.push_back(new CDataRef(dref)); } } + XLS::BaseObjectPtr CDataRefs::toBin() + { + auto ptr(new XLSB::DREFS); + XLS::BaseObjectPtr objectPtr(ptr); + auto beginRefs(new XLSB::BeginDRefs); + ptr->m_BrtBeginDRefs = XLS::BaseObjectPtr{beginRefs}; + + for(auto i:m_arrItems) + { + ptr->m_arBrtDRef.push_back(i->toBin()); + } + beginRefs->cdref = ptr->m_arBrtDRef.size(); + return objectPtr; + } EElementType CDataRefs::getType() const { return et_x_DataRefs; @@ -2244,6 +3335,36 @@ namespace OOX m_oDataRefs = oReader; } } + XLS::BaseObjectPtr CDataConsolidate::toBin() + { + auto ptr(new XLSB::DCON); + XLS::BaseObjectPtr objectPtr(ptr); + auto beginPtr(new XLSB::BeginDCon); + ptr->m_BrtBeginDCon = XLS::BaseObjectPtr{beginPtr}; + + if(m_oFunction.IsInit()) + beginPtr->iiftab = m_oFunction->GetValue(); + else + beginPtr->iiftab = 0; + if(m_oLink.IsInit()) + beginPtr->fLinkConsol = m_oLink->GetValue(); + else + beginPtr->fLinkConsol = false; + if(m_oStartLabels.IsInit()) + beginPtr->fLeftCat = m_oStartLabels->GetValue(); + else + beginPtr->fLeftCat = false; + if(m_oTopLabels.IsInit()) + beginPtr->fTopCat = m_oTopLabels->GetValue(); + else + beginPtr->fTopCat = false; + + if(m_oDataRefs.IsInit()) + { + ptr->m_DREFS = m_oDataRefs->toBin(); + } + return objectPtr; + } void CDataConsolidate::fromBin(XLS::BaseObjectPtr& obj) { auto ptr = static_cast(obj.get()); @@ -2301,6 +3422,7 @@ namespace OOX WritingElement_ReadAttributes_Start(oReader) WritingElement_ReadAttributes_Read_if(oReader, L"name", m_oName) WritingElement_ReadAttributes_Read_else_if(oReader, L"sqref", m_oSqref) + WritingElement_ReadAttributes_Read_else_if(oReader, L"type", m_oType) WritingElement_ReadAttributes_End(oReader) } void CUserProtectedRange::fromXML(XmlUtils::CXmlLiteReader& oReader) @@ -2331,6 +3453,7 @@ namespace OOX WritingElement_ReadAttributes_Start(oReader) WritingElement_ReadAttributes_Read_if(oReader, L"id", desc.id) WritingElement_ReadAttributes_Read_else_if(oReader, L"name", desc.name) + WritingElement_ReadAttributes_Read_else_if(oReader, L"type", desc.type) WritingElement_ReadAttributes_End(oReader) m_arUsers.push_back(desc); } @@ -2348,6 +3471,7 @@ namespace OOX WritingElement_ReadAttributes_Start(oReader) WritingElement_ReadAttributes_Read_if(oReader, L"id", desc.id) WritingElement_ReadAttributes_Read_else_if(oReader, L"name", desc.name) + WritingElement_ReadAttributes_Read_else_if(oReader, L"type", desc.type) WritingElement_ReadAttributes_End(oReader) m_arUsersGroups.push_back(desc); } @@ -2360,6 +3484,7 @@ namespace OOX writer.WriteString(L"ToString()) writer.WriteString(L">"); if (m_oText.IsInit()) @@ -2376,6 +3501,7 @@ namespace OOX writer.WriteString(L"ToString()) writer.WriteString(L"/>"); } writer.WriteString(L""); @@ -2388,6 +3514,7 @@ namespace OOX writer.WriteString(L"ToString()) writer.WriteString(L"/>"); } writer.WriteString(L""); diff --git a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h index 5ad4d9a39ba..201fea20613 100644 --- a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h +++ b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h @@ -55,6 +55,7 @@ namespace SimpleTypes class CPaneState; class CSheetViewType; class CDataConsolidateFunction; + class CUserProtectedRangeType; } } @@ -79,6 +80,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType() const; void ReadAttributes(XLS::BaseObjectPtr& obj); @@ -108,6 +110,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(std::vector& obj); + std::vector toBin(); virtual EElementType getType() const; }; @@ -169,6 +172,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; private: @@ -199,6 +203,8 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); + XLS::BaseObjectPtr toBinCs(); virtual EElementType getType () const; void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); @@ -241,6 +247,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; private: @@ -269,6 +276,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + XLS::BaseObjectPtr toBin(); void fromBin(XLS::BaseObjectPtr& obj); virtual EElementType getType () const; @@ -295,6 +303,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; private: @@ -328,6 +337,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; private: @@ -357,6 +367,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; private: @@ -388,6 +399,8 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); + XLS::BaseObjectPtr toBinCs(); virtual EElementType getType () const; private: @@ -433,6 +446,8 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); + XLS::BaseObjectPtr toBinCs(); virtual EElementType getType () const; }; @@ -451,6 +466,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + void toBin(XLS::BaseObjectPtr& obj); virtual EElementType getType () const; private: @@ -477,6 +493,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + void toBin(XLS::BaseObjectPtr& obj); virtual EElementType getType () const; private: @@ -505,6 +522,8 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); + XLS::BaseObjectPtr toBinCs(); virtual EElementType getType () const; private: @@ -564,6 +583,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + XLS::BaseObjectPtr toBin(); void fromBin(XLS::BaseObjectPtr& obj); virtual EElementType getType () const; @@ -601,6 +621,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; private: @@ -644,6 +665,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; private: @@ -669,6 +691,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; private: @@ -699,6 +722,8 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBinColumn(); + XLS::BaseObjectPtr toBinRow(); virtual EElementType getType () const; @@ -726,6 +751,8 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); + XLS::BaseObjectPtr toBinCS(); virtual EElementType getType () const; void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); @@ -771,6 +798,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; void ReadAttributes(XLS::BaseObjectPtr& obj); @@ -797,6 +825,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; private: @@ -821,6 +850,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; void ReadAttributes(XLS::BaseObjectPtr& obj); @@ -841,6 +871,7 @@ namespace OOX { nullable_string id; nullable_string name; + nullable type; }; WritingElement_AdditionMethods(CUserProtectedRange) @@ -860,6 +891,7 @@ namespace OOX nullable_string m_oName; nullable_string m_oSqref; nullable_string m_oText; + nullable m_oType; std::vector<_UsersGroupsDesc> m_arUsers; std::vector<_UsersGroupsDesc> m_arUsersGroups; diff --git a/OOXML/XlsxFormat/Worksheets/XlsxHyperlinks.cpp b/OOXML/XlsxFormat/Worksheets/XlsxHyperlinks.cpp index 38782073a35..ca389ed65a0 100644 --- a/OOXML/XlsxFormat/Worksheets/XlsxHyperlinks.cpp +++ b/OOXML/XlsxFormat/Worksheets/XlsxHyperlinks.cpp @@ -35,6 +35,8 @@ #include "../../Common/SimpleTypes_Shared.h" +#include "../../XlsbFormat/Biff12_unions/HLINKS.h" + namespace OOX { namespace Spreadsheet @@ -73,6 +75,32 @@ namespace OOX { ReadAttributes(obj); } + XLS::BaseObjectPtr CHyperlink::toBin() + { + auto castedPtr(new XLSB::HLink); + XLS::BaseObjectPtr ptr(castedPtr); + + if(m_oDisplay.IsInit()) + castedPtr->display = m_oDisplay.get(); + else + castedPtr->display = L""; + if(m_oRid.IsInit()) + castedPtr->relId.value = m_oRid->GetValue(); + else + castedPtr->relId.value = L""; + if(m_oLocation.IsInit()) + castedPtr->location = m_oLocation.get(); + else + castedPtr->location = L""; + if(m_oRef.IsInit()) + castedPtr->rfx = m_oRef.get(); + if(m_oTooltip.IsInit()) + castedPtr->tooltip = m_oTooltip.get(); + else + castedPtr->tooltip = L""; + + return ptr; + } EElementType CHyperlink::getType () const { return et_x_Hyperlink; @@ -94,7 +122,7 @@ namespace OOX m_oDisplay = ptr->display.value(); m_oRid = ptr->relId.value.value(); m_oLocation = ptr->location.value(); - m_oRef = ptr->rfx.toString(); + m_oRef = ptr->rfx.toString(true, true); m_oTooltip = ptr->tooltip.value(); } @@ -160,6 +188,19 @@ namespace OOX pHyperlink->fromBin(hyperlink); } } + XLS::BaseObjectPtr CHyperlinks::toBin() + { + + auto castedPtr(new XLSB::HLINKS); + XLS::BaseObjectPtr ptr(castedPtr); + + for(auto i:m_arrItems) + { + castedPtr->m_arHlinks.push_back(i->toBin()); + } + return ptr; + } + EElementType CHyperlinks::getType () const { return et_x_Hyperlinks; diff --git a/OOXML/XlsxFormat/WritingElement.h b/OOXML/XlsxFormat/WritingElement.h index af4f1a8b1ee..c323648007d 100644 --- a/OOXML/XlsxFormat/WritingElement.h +++ b/OOXML/XlsxFormat/WritingElement.h @@ -1004,6 +1004,10 @@ namespace XLSB rt_SXDI15 = 2136, rt_Uid = 3072, rt_RevisionPtr = 3073, + rt_BeginRichValueBlock = 5002, + rt_EndRichValueBlock = 5003, + rt_BeginDynamicArrayPr = 4096, + rt_EndDynamicArrayPr = 4097, rt_BeginRichFilters = 5081, rt_EndRichFilters = 5082, rt_RichFilter = 5083, diff --git a/OOXML/XlsxFormat/Xlsx.cpp b/OOXML/XlsxFormat/Xlsx.cpp index 6d5a39c0a4a..dfaac70855d 100644 --- a/OOXML/XlsxFormat/Xlsx.cpp +++ b/OOXML/XlsxFormat/Xlsx.cpp @@ -251,7 +251,13 @@ void OOX::Spreadsheet::CXlsx::CreateStyles () m_pStyles = new CStyles(NULL); bDeleteStyles = true; } - +bool OOX::Spreadsheet::CXlsx::hasPivot() +{ + if (!m_pWorkbook) return false; + + smart_ptr filePivotCacheDefinition = m_pWorkbook->Find(FileTypes::PivotCacheDefinition.RelationType()); + return filePivotCacheDefinition.IsInit(); +} PPTX::Theme* OOX::Spreadsheet::CXlsx::GetTheme () const { return (PPTX::Theme *)(m_pTheme.GetPointer()); diff --git a/OOXML/XlsxFormat/Xlsx.h b/OOXML/XlsxFormat/Xlsx.h index 9d4ff3321fc..c5a782eaf63 100644 --- a/OOXML/XlsxFormat/Xlsx.h +++ b/OOXML/XlsxFormat/Xlsx.h @@ -73,6 +73,8 @@ namespace OOX void CreateWorkbook (); void CreateSharedStrings (); void CreateStyles (); + + bool hasPivot(); PPTX::Theme *GetTheme () const; diff --git a/OOXML/test/ExampleFiles/xlsb2xlsx/fmla.xlsb b/OOXML/test/ExampleFiles/xlsb2xlsx/fmla.xlsb new file mode 100644 index 00000000000..7126d603d01 Binary files /dev/null and b/OOXML/test/ExampleFiles/xlsb2xlsx/fmla.xlsb differ diff --git a/OOXML/test/ExampleFiles/xlsb2xlsx/fmla.xlsx b/OOXML/test/ExampleFiles/xlsb2xlsx/fmla.xlsx new file mode 100644 index 00000000000..7a6b0736966 Binary files /dev/null and b/OOXML/test/ExampleFiles/xlsb2xlsx/fmla.xlsx differ diff --git a/OOXML/test/ExampleFiles/xlsb2xlsx/simple1.xlsb b/OOXML/test/ExampleFiles/xlsb2xlsx/simple1.xlsb new file mode 100644 index 00000000000..c71a49e25f3 Binary files /dev/null and b/OOXML/test/ExampleFiles/xlsb2xlsx/simple1.xlsb differ diff --git a/OOXML/test/ExampleFiles/xlsb2xlsx/simple1.xlsx b/OOXML/test/ExampleFiles/xlsb2xlsx/simple1.xlsx new file mode 100644 index 00000000000..173807f5668 Binary files /dev/null and b/OOXML/test/ExampleFiles/xlsb2xlsx/simple1.xlsx differ diff --git a/OOXML/test/ExampleFiles/xlsb2xlsx/simple2.xlsb b/OOXML/test/ExampleFiles/xlsb2xlsx/simple2.xlsb new file mode 100644 index 00000000000..b6e5e04031d Binary files /dev/null and b/OOXML/test/ExampleFiles/xlsb2xlsx/simple2.xlsb differ diff --git a/OOXML/test/ExampleFiles/xlsb2xlsx/simple2.xlsx b/OOXML/test/ExampleFiles/xlsb2xlsx/simple2.xlsx new file mode 100644 index 00000000000..0d577fe0801 Binary files /dev/null and b/OOXML/test/ExampleFiles/xlsb2xlsx/simple2.xlsx differ diff --git a/OOXML/test/ExampleFiles/xlsx2xlsb/fmla.xlsb b/OOXML/test/ExampleFiles/xlsx2xlsb/fmla.xlsb new file mode 100644 index 00000000000..7126d603d01 Binary files /dev/null and b/OOXML/test/ExampleFiles/xlsx2xlsb/fmla.xlsb differ diff --git a/OOXML/test/ExampleFiles/xlsx2xlsb/fmla.xlsx b/OOXML/test/ExampleFiles/xlsx2xlsb/fmla.xlsx new file mode 100644 index 00000000000..7e76bb99c99 Binary files /dev/null and b/OOXML/test/ExampleFiles/xlsx2xlsb/fmla.xlsx differ diff --git a/OOXML/test/ExampleFiles/xlsx2xlsb/simple1.xlsb b/OOXML/test/ExampleFiles/xlsx2xlsb/simple1.xlsb new file mode 100644 index 00000000000..e4aea47f12f Binary files /dev/null and b/OOXML/test/ExampleFiles/xlsx2xlsb/simple1.xlsb differ diff --git a/OOXML/test/ExampleFiles/xlsx2xlsb/simple1.xlsx b/OOXML/test/ExampleFiles/xlsx2xlsb/simple1.xlsx new file mode 100644 index 00000000000..99714a52fd3 Binary files /dev/null and b/OOXML/test/ExampleFiles/xlsx2xlsb/simple1.xlsx differ diff --git a/OOXML/test/ExampleFiles/xlsx2xlsb/simple2.xlsb b/OOXML/test/ExampleFiles/xlsx2xlsb/simple2.xlsb new file mode 100644 index 00000000000..d05c3eaf061 Binary files /dev/null and b/OOXML/test/ExampleFiles/xlsx2xlsb/simple2.xlsb differ diff --git a/OOXML/test/ExampleFiles/xlsx2xlsb/simple2.xlsx b/OOXML/test/ExampleFiles/xlsx2xlsb/simple2.xlsx new file mode 100644 index 00000000000..1e0eb8a57a1 Binary files /dev/null and b/OOXML/test/ExampleFiles/xlsx2xlsb/simple2.xlsx differ diff --git a/OOXML/test/common.cpp b/OOXML/test/common.cpp new file mode 100644 index 00000000000..daac3751ae1 --- /dev/null +++ b/OOXML/test/common.cpp @@ -0,0 +1,131 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ + +#include "common.h" + +#include "../../../DesktopEditor/common/Directory.h" +#include "../../../DesktopEditor/common/Path.h" +#include "../../../OfficeUtils/src/OfficeUtils.h" +#include "../../../DesktopEditor/fontengine/ApplicationFontsWorker.h" +#include "../../../Common/OfficeFileFormatChecker.h" +#include "../../../DesktopEditor/common/StringBuilder.h" +#include "../../src/dylib/x2t.h" +#include "tchar.h" +#include +#include +#include +#include + + +std::wstring GetWorkDir() +{ + std::wstring curDir = NSFile::GetProcessDirectory(); + return NSDirectory::CreateDirectoryWithUniqueName(curDir); +} + +void RemoveWorkDir(const std::wstring &dir) +{ + NSDirectory::DeleteDirectory(dir); +} + +int ConvertFile(const std::wstring &fileName) +{ + x2tchar* args[2]; + args[0] = NULL; + args[1] = (x2tchar*)fileName.c_str(); + + int nResultCode = X2T_Convert(2, args); + return nResultCode; +} + +void PrepareFiles(const std::wstring &fileName, const std::wstring &exampleFileName, const std::wstring &tempDirName) +{ + std::wstring sTempUnpackedXLSB = tempDirName + FILE_SEPARATOR_STR + _T("result_unpacked"); + NSDirectory::CreateDirectory(sTempUnpackedXLSB); + COfficeUtils oCOfficeUtils(NULL); + _UINT32 nRes = oCOfficeUtils.ExtractToDirectory(fileName, sTempUnpackedXLSB, NULL, 0); + + std::wstring sTempUnpackedXLSX = tempDirName + FILE_SEPARATOR_STR + _T("example_unpacked"); + NSDirectory::CreateDirectory(sTempUnpackedXLSX); + nRes = oCOfficeUtils.ExtractToDirectory(exampleFileName, sTempUnpackedXLSX, NULL, 0); +} + +std::wstring CreateParamsFile(const std::wstring &pathFrom, const std::wstring &pathTo, const std::wstring &TempDir) +{ + NSStringUtils::CStringBuilder oBuilder; + + oBuilder.WriteString(L""); + oBuilder.WriteString(L""); + + // main + oBuilder.WriteString(L""); + oBuilder.WriteEncodeXmlString(pathFrom); + oBuilder.WriteString(L""); + + oBuilder.WriteString(L""); + oBuilder.WriteEncodeXmlString(pathTo); + oBuilder.WriteString(L""); + + // changes + oBuilder.WriteString(L"false"); + + oBuilder.WriteString(L"true"); + + // temp directory + oBuilder.WriteString(L""); + oBuilder.WriteEncodeXmlString(TempDir); + oBuilder.WriteString(L""); + + // txt/csv + oBuilder.WriteString(L""); + oBuilder.WriteEncodeXmlString(L"46"); + oBuilder.WriteString(L""); + + oBuilder.WriteString(L""); + oBuilder.WriteEncodeXmlString(L"4"); + oBuilder.WriteString(L""); + + oBuilder.WriteString(L""); + + auto xml = TempDir + FILE_SEPARATOR_STR + L"params.xml"; + // writing xml data into file + if(NSFile::CFileBinary::Exists(xml)) + NSFile::CFileBinary::Remove(xml); + + NSFile::CFileBinary xml_file; + xml_file.CreateFile(xml); + xml_file.WriteStringUTF8(oBuilder.GetData()); + xml_file.CloseFile(); + + return xml; +} + diff --git a/OOXML/test/common.h b/OOXML/test/common.h new file mode 100644 index 00000000000..2d2d6d6b0d7 --- /dev/null +++ b/OOXML/test/common.h @@ -0,0 +1,41 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#include "../../../OOXML/Base/Base.h" +#include +#include + +void PrepareFiles(const std::wstring &fileName, const std::wstring &exampleFileName, const std::wstring &tempDirName); +int ConvertFile(const std::wstring &fileName); +std::wstring GetWorkDir(); +void RemoveWorkDir(const std::wstring &dir); +std::wstring CreateParamsFile(const std::wstring &pathFrom, const std::wstring &pathTo, const std::wstring &TempDir); + diff --git a/OOXML/test/main.cpp b/OOXML/test/main.cpp new file mode 100644 index 00000000000..914a3a04e96 --- /dev/null +++ b/OOXML/test/main.cpp @@ -0,0 +1,14 @@ +#include "../../../DesktopEditor/common/Directory.h" +#include "../../../DesktopEditor/common/StringBuilder.h" +#include "../../../DesktopEditor/fontengine/ApplicationFontsWorker.h" +#include "../../../Common/OfficeFileFormatChecker.h" +#include "../../src/dylib/x2t.h" +#include "common.h" + +#include + +int main(int argc, char** argv) +{ + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/OOXML/test/test.pro b/OOXML/test/test.pro new file mode 100644 index 00000000000..d9ab1094cd3 --- /dev/null +++ b/OOXML/test/test.pro @@ -0,0 +1,25 @@ +TEMPLATE = app +CONFIG += console +CONFIG -= app_bundle + +DEFINES += BUILD_X2T_AS_LIBRARY_DYLIB + +X2T_DIR = $$PWD/../../X2tConverter + +include($$X2T_DIR/build/Qt/X2tConverter.pri) +include($$X2T_DIR/../Common/3dParty/googletest/googletest.pri) + +HEADERS += $$X2T_DIR/src/dylib/x2t.h +SOURCES += $$X2T_DIR/src/dylib/x2t.cpp + +SOURCES += main.cpp\ + common.cpp\ + xlsb2xlsx/conversion.cpp\ + xlsx2xlsb/conversion.cpp\ + +HEADERS += common.h + +DESTDIR = $$CORE_BUILDS_BINARY_PATH + + +SOURCES -= $$CORE_GTEST_PATH/src/gtest_main.cc diff --git a/OOXML/test/xlsb2xlsx/conversion.cpp b/OOXML/test/xlsb2xlsx/conversion.cpp new file mode 100644 index 00000000000..f5677e1ffc6 --- /dev/null +++ b/OOXML/test/xlsb2xlsx/conversion.cpp @@ -0,0 +1,328 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ + +#include "../common.h" +#include +#include +#include +#include "gtest/gtest.h" + +void processTestFile(const std::wstring &tempDir, const std::wstring &testFile, const std::wstring &resultFile, const std::wstring &exampleFile) +{ + + boost::filesystem::path rootPath = std::wstring{L".."} + FILE_SEPARATOR_STR; + rootPath =boost::filesystem::absolute(rootPath.wstring() + rootPath.wstring() + rootPath.wstring()+ rootPath.wstring()); + boost::filesystem::path filePath = rootPath.wstring() +L"OOXML" + FILE_SEPARATOR_STR + L"test" + FILE_SEPARATOR_STR +L"ExampleFiles" + + FILE_SEPARATOR_STR + L"xlsb2xlsx" + FILE_SEPARATOR_STR + testFile; + boost::filesystem::path examplePath = rootPath.wstring() +L"OOXML" + FILE_SEPARATOR_STR + L"test" + FILE_SEPARATOR_STR +L"ExampleFiles" + + FILE_SEPARATOR_STR + L"xlsb2xlsx" + FILE_SEPARATOR_STR + exampleFile; + + std::wstring resultPath = tempDir + FILE_SEPARATOR_STR + resultFile; + + auto paramsPath = CreateParamsFile(filePath.wstring(), resultPath, tempDir); + ConvertFile(paramsPath); + PrepareFiles(resultPath, examplePath.wstring(), tempDir); +} + +class SimpleTests1 : public ::testing::Test +{ +public: + + static void SetUpTestCase() + { + + tempDir = GetWorkDir(); + processTestFile(tempDir, L"simple1.xlsb", L"result.xlsx", L"simple1.xlsx"); + } + + + static void TearDownTestCase() + { + RemoveWorkDir(tempDir); + } + + static std::wstring tempDir; +}; +class SimpleTests2 : public ::testing::Test +{ +public: + + static void SetUpTestCase() + { + + tempDir = GetWorkDir(); + processTestFile(tempDir, L"simple2.xlsb", L"result.xlsx", L"simple2.xlsx"); + } + + + static void TearDownTestCase() + { + RemoveWorkDir(tempDir); + } + + static std::wstring tempDir; +}; + +class FmlaTest : public ::testing::Test +{ +public: + + static void SetUpTestCase() + { + + tempDir = GetWorkDir(); + processTestFile(tempDir, L"fmla.xlsb", L"result.xlsx", L"fmla.xlsx"); + } + + + static void TearDownTestCase() + { + RemoveWorkDir(tempDir); + } + + static std::wstring tempDir; +}; + +std::wstring SimpleTests1::tempDir = L""; +std::wstring SimpleTests2::tempDir = L""; +std::wstring FmlaTest::tempDir = L""; + +_UINT32 readFiles(const std::wstring &filePath, const std::wstring &examplePath, std::wstring &fileContent, std::wstring &exampleContent ) +{ + + boost::filesystem::path path1(filePath); + boost::filesystem::path path2(examplePath); + path1 = boost::filesystem::absolute(path1); + path2 = boost::filesystem::absolute(path2); + std::ifstream file1(path1.string()); + std::ifstream file2(path2.string()); + + if (!file1.is_open() || !file2.is_open()) + { + return 1; + } + fileContent = std::wstring((std::istreambuf_iterator(file1)), std::istreambuf_iterator()); + exampleContent = std::wstring((std::istreambuf_iterator(file2)), std::istreambuf_iterator()); + + return 0; +} + + + +TEST_F(SimpleTests1, ContentTypesTest) +{ + auto tempDir = SimpleTests1::tempDir; + std::wstring path1(tempDir + FILE_SEPARATOR_STR + L"result_unpacked"+ FILE_SEPARATOR_STR + L"[Content_Types].xml"); + std::wstring path2(tempDir + FILE_SEPARATOR_STR + L"example_unpacked"+ FILE_SEPARATOR_STR + L"[Content_Types].xml"); + std::wstring content1; + std::wstring content2; + ASSERT_EQ(readFiles(path1, path2, content1, content2), 0); + ASSERT_TRUE(boost::algorithm::equals(content1, content2)); +} + +TEST_F(SimpleTests1, WorkbookTest) +{ + auto tempDir = SimpleTests1::tempDir; + std::wstring path1(tempDir + FILE_SEPARATOR_STR + L"result_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"workbook.xml"); + std::wstring path2(tempDir + FILE_SEPARATOR_STR +L"example_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"workbook.xml"); + std::wstring content1; + std::wstring content2; + ASSERT_EQ(readFiles(path1, path2, content1, content2), 0); + ASSERT_TRUE(boost::algorithm::equals(content1, content2)); +} + +TEST_F(SimpleTests1, StylesTest) +{ + auto tempDir = SimpleTests1::tempDir; + std::wstring path1(tempDir + FILE_SEPARATOR_STR + L"result_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"styles.xml"); + std::wstring path2(tempDir + FILE_SEPARATOR_STR +L"example_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"styles.xml"); + std::wstring content1; + std::wstring content2; + ASSERT_EQ(readFiles(path1, path2, content1, content2), 0); + ASSERT_TRUE(boost::algorithm::equals(content1, content2)); +} + +TEST_F(SimpleTests1, SharedStringsTest) +{ + auto tempDir = SimpleTests1::tempDir; + std::wstring path1(tempDir + FILE_SEPARATOR_STR + L"result_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"sharedStrings.xml"); + std::wstring path2(tempDir + FILE_SEPARATOR_STR +L"example_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"sharedStrings.xml"); + std::wstring content1; + std::wstring content2; + ASSERT_EQ(readFiles(path1, path2, content1, content2), 0); + ASSERT_TRUE(boost::algorithm::equals(content1, content2)); +} + +TEST_F(SimpleTests1, WorksheetsTest) +{ + auto tempDir = SimpleTests1::tempDir; + std::wstring path1(tempDir + FILE_SEPARATOR_STR + L"result_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"worksheets" + FILE_SEPARATOR_STR + L"sheet1.xml"); + std::wstring path2(tempDir + FILE_SEPARATOR_STR +L"example_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"worksheets" + FILE_SEPARATOR_STR + L"sheet1.xml"); + std::wstring content1; + std::wstring content2; + ASSERT_EQ(readFiles(path1, path2, content1, content2), 0); + ASSERT_TRUE(boost::algorithm::equals(content1, content2)); +} + +TEST_F(SimpleTests2, ContentTypesTest) +{ + auto tempDir = SimpleTests2::tempDir; + std::wstring path1(tempDir + FILE_SEPARATOR_STR + L"result_unpacked"+ FILE_SEPARATOR_STR + L"[Content_Types].xml"); + std::wstring path2(tempDir + FILE_SEPARATOR_STR + L"example_unpacked"+ FILE_SEPARATOR_STR + L"[Content_Types].xml"); + std::wstring content1; + std::wstring content2; + ASSERT_EQ(readFiles(path1, path2, content1, content2), 0); + ASSERT_TRUE(boost::algorithm::equals(content1, content2)); +} + +TEST_F(SimpleTests2, WorkbookTest) +{ + auto tempDir = SimpleTests2::tempDir; + std::wstring path1(tempDir + FILE_SEPARATOR_STR + L"result_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"workbook.xml"); + std::wstring path2(tempDir + FILE_SEPARATOR_STR +L"example_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"workbook.xml"); + std::wstring content1; + std::wstring content2; + ASSERT_EQ(readFiles(path1, path2, content1, content2), 0); + ASSERT_TRUE(boost::algorithm::equals(content1, content2)); +} + +TEST_F(SimpleTests2, StylesTest) +{ + auto tempDir = SimpleTests2::tempDir; + std::wstring path1(tempDir + FILE_SEPARATOR_STR + L"result_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"styles.xml"); + std::wstring path2(tempDir + FILE_SEPARATOR_STR +L"example_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"styles.xml"); + std::wstring content1; + std::wstring content2; + ASSERT_EQ(readFiles(path1, path2, content1, content2), 0); + ASSERT_TRUE(boost::algorithm::equals(content1, content2)); +} + +TEST_F(SimpleTests2, SharedStringsTest) +{ + auto tempDir = SimpleTests2::tempDir; + std::wstring path1(tempDir + FILE_SEPARATOR_STR + L"result_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"sharedStrings.xml"); + std::wstring path2(tempDir + FILE_SEPARATOR_STR +L"example_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"sharedStrings.xml"); + std::wstring content1; + std::wstring content2; + ASSERT_EQ(readFiles(path1, path2, content1, content2), 0); + ASSERT_TRUE(boost::algorithm::equals(content1, content2)); +} + +TEST_F(SimpleTests2, WorksheetsTest) +{ + auto tempDir = SimpleTests2::tempDir; + std::wstring path1(tempDir + FILE_SEPARATOR_STR + L"result_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"worksheets" + FILE_SEPARATOR_STR + L"sheet1.xml"); + std::wstring path2(tempDir + FILE_SEPARATOR_STR +L"example_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"worksheets" + FILE_SEPARATOR_STR + L"sheet1.xml"); + std::wstring content1; + std::wstring content2; + ASSERT_EQ(readFiles(path1, path2, content1, content2), 0); + ASSERT_TRUE(boost::algorithm::equals(content1, content2)); +} + +TEST_F(FmlaTest, ContentTypesTest) +{ + auto tempDir = FmlaTest::tempDir; + std::wstring path1(tempDir + FILE_SEPARATOR_STR + L"result_unpacked"+ FILE_SEPARATOR_STR + L"[Content_Types].xml"); + std::wstring path2(tempDir + FILE_SEPARATOR_STR + L"example_unpacked"+ FILE_SEPARATOR_STR + L"[Content_Types].xml"); + std::wstring content1; + std::wstring content2; + ASSERT_EQ(readFiles(path1, path2, content1, content2), 0); + ASSERT_TRUE(boost::algorithm::equals(content1, content2)); +} + +TEST_F(FmlaTest, WorkbookTest) +{ + auto tempDir = FmlaTest::tempDir; + std::wstring path1(tempDir + FILE_SEPARATOR_STR + L"result_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"workbook.xml"); + std::wstring path2(tempDir + FILE_SEPARATOR_STR +L"example_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"workbook.xml"); + std::wstring content1; + std::wstring content2; + ASSERT_EQ(readFiles(path1, path2, content1, content2), 0); + ASSERT_TRUE(boost::algorithm::equals(content1, content2)); +} + +TEST_F(FmlaTest, StylesTest) +{ + auto tempDir = FmlaTest::tempDir; + std::wstring path1(tempDir + FILE_SEPARATOR_STR + L"result_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"styles.xml"); + std::wstring path2(tempDir + FILE_SEPARATOR_STR +L"example_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"styles.xml"); + std::wstring content1; + std::wstring content2; + ASSERT_EQ(readFiles(path1, path2, content1, content2), 0); + ASSERT_TRUE(boost::algorithm::equals(content1, content2)); +} + +TEST_F(FmlaTest, SharedStringsTest) +{ + auto tempDir = FmlaTest::tempDir; + std::wstring path1(tempDir + FILE_SEPARATOR_STR + L"result_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"sharedStrings.xml"); + std::wstring path2(tempDir + FILE_SEPARATOR_STR +L"example_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"sharedStrings.xml"); + std::wstring content1; + std::wstring content2; + ASSERT_EQ(readFiles(path1, path2, content1, content2), 0); + ASSERT_TRUE(boost::algorithm::equals(content1, content2)); +} + +TEST_F(FmlaTest, WorksheetsTest) +{ + auto tempDir = FmlaTest::tempDir; + std::wstring path1(tempDir + FILE_SEPARATOR_STR + L"result_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"worksheets" + FILE_SEPARATOR_STR + L"sheet1.xml"); + std::wstring path2(tempDir + FILE_SEPARATOR_STR +L"example_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"worksheets" + FILE_SEPARATOR_STR + L"sheet1.xml"); + std::wstring content1; + std::wstring content2; + ASSERT_EQ(readFiles(path1, path2, content1, content2), 0); + ASSERT_TRUE(boost::algorithm::equals(content1, content2)); +} \ No newline at end of file diff --git a/OOXML/test/xlsx2xlsb/conversion.cpp b/OOXML/test/xlsx2xlsb/conversion.cpp new file mode 100644 index 00000000000..64ec2e7a31c --- /dev/null +++ b/OOXML/test/xlsx2xlsb/conversion.cpp @@ -0,0 +1,475 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ + +#include "../common.h" +#include +#include +#include +#include "gtest/gtest.h" + +namespace xlsb2xlsxTests +{ +void processTestFile(const std::wstring &tempDir, const std::wstring &testFile, const std::wstring &resultFile, const std::wstring &exampleFile) +{ + + boost::filesystem::path rootPath = std::wstring{L".."} + FILE_SEPARATOR_STR; + rootPath =boost::filesystem::absolute(rootPath.wstring() + rootPath.wstring() + rootPath.wstring()+ rootPath.wstring()); + boost::filesystem::path filePath = rootPath.wstring() +L"OOXML" + FILE_SEPARATOR_STR + L"test" + FILE_SEPARATOR_STR +L"ExampleFiles" + + FILE_SEPARATOR_STR + L"xlsx2xlsb" + FILE_SEPARATOR_STR + testFile; + boost::filesystem::path examplePath = rootPath.wstring() +L"OOXML" + FILE_SEPARATOR_STR + L"test" + FILE_SEPARATOR_STR +L"ExampleFiles" + + FILE_SEPARATOR_STR + L"xlsx2xlsb" + FILE_SEPARATOR_STR + exampleFile; + + std::wstring resultPath = tempDir + FILE_SEPARATOR_STR + resultFile; + + auto paramsPath = CreateParamsFile(filePath.wstring(), resultPath, tempDir); + ConvertFile(paramsPath); + PrepareFiles(resultPath, examplePath.wstring(), tempDir); +} + +class XlsbSimpleTests1 : public ::testing::Test +{ +public: + + static void SetUpTestCase() + { + + tempDir = GetWorkDir(); + processTestFile(tempDir, L"simple1.xlsx", L"result.xlsb", L"simple1.xlsb"); + } + + + static void TearDownTestCase() + { + RemoveWorkDir(tempDir); + } + + static std::wstring tempDir; +}; +class XlsbSimpleTests2 : public ::testing::Test +{ +public: + + static void SetUpTestCase() + { + + tempDir = GetWorkDir(); + processTestFile(tempDir, L"simple2.xlsx", L"result.xlsb", L"simple2.xlsb"); + } + + + static void TearDownTestCase() + { + RemoveWorkDir(tempDir); + } + + static std::wstring tempDir; +}; +class XlsbFmlaTests : public ::testing::Test +{ +public: + + static void SetUpTestCase() + { + + tempDir = GetWorkDir(); + processTestFile(tempDir, L"fmla.xlsx", L"result.xlsb", L"fmla.xlsb"); + } + + + static void TearDownTestCase() + { + RemoveWorkDir(tempDir); + } + + static std::wstring tempDir; +}; + +std::wstring XlsbSimpleTests1::tempDir = L""; +std::wstring XlsbSimpleTests2::tempDir = L""; +std::wstring XlsbFmlaTests::tempDir = L""; + +_UINT32 readBinaryFiles(const std::wstring &filePath, const std::wstring &examplePath, std::vector &fileContent, std::vector &exampleContent) +{ + boost::filesystem::path path1(filePath); + boost::filesystem::path path2(examplePath); + path1 = boost::filesystem::absolute(path1); + path2 = boost::filesystem::absolute(path2); + std::ifstream file1(path1.string(), std::ios::binary); + std::ifstream file2(path2.string(), std::ios::binary); + + if (!file1.is_open() || !file2.is_open()) + { + return 1; + } + + fileContent = std::vector((std::istreambuf_iterator(file1)), std::istreambuf_iterator()); + exampleContent = std::vector((std::istreambuf_iterator(file2)), std::istreambuf_iterator()); + + return 0; +} + + +TEST_F(XlsbSimpleTests1, ContentTypesTest) +{ + auto tempDir = XlsbSimpleTests1::tempDir; + std::wstring path1(tempDir + FILE_SEPARATOR_STR + L"result_unpacked"+ FILE_SEPARATOR_STR + L"[Content_Types].xml"); + std::wstring path2(tempDir + FILE_SEPARATOR_STR + L"example_unpacked"+ FILE_SEPARATOR_STR + L"[Content_Types].xml"); + std::vector fileContent; + std::vector exampleContent; + ASSERT_EQ(readBinaryFiles(path1, path2, fileContent, exampleContent), 0); + ASSERT_EQ(fileContent, exampleContent); +} + +TEST_F(XlsbSimpleTests1, WorkbookTest) +{ + auto tempDir = XlsbSimpleTests1::tempDir; + std::wstring path1(tempDir + FILE_SEPARATOR_STR + L"result_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"workbook.bin"); + std::wstring path2(tempDir + FILE_SEPARATOR_STR +L"example_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"workbook.bin"); + std::vector fileContent; + std::vector exampleContent; + ASSERT_EQ(readBinaryFiles(path1, path2, fileContent, exampleContent), 0); + ASSERT_EQ(fileContent, exampleContent); +} + +TEST_F(XlsbSimpleTests1, StylesTest) +{ + auto tempDir = XlsbSimpleTests1::tempDir; + std::wstring path1(tempDir + FILE_SEPARATOR_STR + L"result_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"styles.bin"); + std::wstring path2(tempDir + FILE_SEPARATOR_STR +L"example_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"styles.bin"); + std::vector fileContent; + std::vector exampleContent; + ASSERT_EQ(readBinaryFiles(path1, path2, fileContent, exampleContent), 0); + ASSERT_EQ(fileContent, exampleContent); +} + +TEST_F(XlsbSimpleTests1, SharedStringsTest) +{ + auto tempDir = XlsbSimpleTests1::tempDir; + std::wstring path1(tempDir + FILE_SEPARATOR_STR + L"result_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"sharedStrings.bin"); + std::wstring path2(tempDir + FILE_SEPARATOR_STR +L"example_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"sharedStrings.bin"); + std::vector fileContent; + std::vector exampleContent; + ASSERT_EQ(readBinaryFiles(path1, path2, fileContent, exampleContent), 0); + ASSERT_EQ(fileContent, exampleContent); +} + +TEST_F(XlsbSimpleTests1, WorksheetsTest) +{ + auto tempDir = XlsbSimpleTests1::tempDir; + std::wstring path1(tempDir + FILE_SEPARATOR_STR + L"result_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"worksheets" + FILE_SEPARATOR_STR + L"sheet1.bin"); + std::wstring path2(tempDir + FILE_SEPARATOR_STR +L"example_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"worksheets" + FILE_SEPARATOR_STR + L"sheet1.bin"); + std::vector fileContent; + std::vector exampleContent; + ASSERT_EQ(readBinaryFiles(path1, path2, fileContent, exampleContent), 0); + ASSERT_EQ(fileContent, exampleContent); +} + +TEST_F(XlsbSimpleTests2, ContentTypesTest) +{ + auto tempDir = XlsbSimpleTests2::tempDir; + std::wstring path1(tempDir + FILE_SEPARATOR_STR + L"result_unpacked"+ FILE_SEPARATOR_STR + L"[Content_Types].xml"); + std::wstring path2(tempDir + FILE_SEPARATOR_STR + L"example_unpacked"+ FILE_SEPARATOR_STR + L"[Content_Types].xml"); + std::vector fileContent; + std::vector exampleContent; + ASSERT_EQ(readBinaryFiles(path1, path2, fileContent, exampleContent), 0); + ASSERT_EQ(fileContent, exampleContent); +} + +TEST_F(XlsbSimpleTests2, WorkbookTest) +{ + auto tempDir = XlsbSimpleTests2::tempDir; + std::wstring path1(tempDir + FILE_SEPARATOR_STR + L"result_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"workbook.bin"); + std::wstring path2(tempDir + FILE_SEPARATOR_STR +L"example_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"workbook.bin"); + std::vector fileContent; + std::vector exampleContent; + ASSERT_EQ(readBinaryFiles(path1, path2, fileContent, exampleContent), 0); + ASSERT_EQ(fileContent, exampleContent); +} + +TEST_F(XlsbSimpleTests2, StylesTest) +{ + auto tempDir = XlsbSimpleTests2::tempDir; + std::wstring path1(tempDir + FILE_SEPARATOR_STR + L"result_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"styles.bin"); + std::wstring path2(tempDir + FILE_SEPARATOR_STR +L"example_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"styles.bin"); + std::vector fileContent; + std::vector exampleContent; + ASSERT_EQ(readBinaryFiles(path1, path2, fileContent, exampleContent), 0); + ASSERT_EQ(fileContent, exampleContent); +} + +TEST_F(XlsbSimpleTests2, SharedStringsTest) +{ + auto tempDir = XlsbSimpleTests2::tempDir; + std::wstring path1(tempDir + FILE_SEPARATOR_STR + L"result_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"sharedStrings.bin"); + std::wstring path2(tempDir + FILE_SEPARATOR_STR +L"example_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"sharedStrings.bin"); + std::vector fileContent; + std::vector exampleContent; + ASSERT_EQ(readBinaryFiles(path1, path2, fileContent, exampleContent), 0); + ASSERT_EQ(fileContent, exampleContent); +} + +TEST_F(XlsbSimpleTests2, Worksheet1Test) +{ + auto tempDir = XlsbSimpleTests2::tempDir; + std::wstring path1(tempDir + FILE_SEPARATOR_STR + L"result_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"worksheets" + FILE_SEPARATOR_STR + L"sheet1.bin"); + std::wstring path2(tempDir + FILE_SEPARATOR_STR +L"example_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"worksheets" + FILE_SEPARATOR_STR + L"sheet1.bin"); + std::vector fileContent; + std::vector exampleContent; + ASSERT_EQ(readBinaryFiles(path1, path2, fileContent, exampleContent), 0); + ASSERT_EQ(fileContent, exampleContent); +} + +TEST_F(XlsbSimpleTests2, Worksheet2Test) +{ + auto tempDir = XlsbSimpleTests2::tempDir; + std::wstring path1(tempDir + FILE_SEPARATOR_STR + L"result_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"worksheets" + FILE_SEPARATOR_STR + L"sheet2.bin"); + std::wstring path2(tempDir + FILE_SEPARATOR_STR +L"example_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"worksheets" + FILE_SEPARATOR_STR + L"sheet2.bin"); + std::vector fileContent; + std::vector exampleContent; + ASSERT_EQ(readBinaryFiles(path1, path2, fileContent, exampleContent), 0); + ASSERT_EQ(fileContent, exampleContent); +} + +TEST_F(XlsbSimpleTests2, CommentsTest) +{ + auto tempDir = XlsbSimpleTests2::tempDir; + std::wstring path1(tempDir + FILE_SEPARATOR_STR + L"result_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"comments2.bin"); + std::wstring path2(tempDir + FILE_SEPARATOR_STR +L"example_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"comments2.bin"); + std::vector fileContent; + std::vector exampleContent; + ASSERT_EQ(readBinaryFiles(path1, path2, fileContent, exampleContent), 0); + ASSERT_EQ(fileContent, exampleContent); +} + +TEST_F(XlsbSimpleTests2, TablesTest) +{ + auto tempDir = XlsbSimpleTests2::tempDir; + std::wstring path1(tempDir + FILE_SEPARATOR_STR + L"result_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"tables" + FILE_SEPARATOR_STR + L"table2.bin"); + std::wstring path2(tempDir + FILE_SEPARATOR_STR +L"example_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"tables" + FILE_SEPARATOR_STR + L"table2.bin"); + std::vector fileContent; + std::vector exampleContent; + ASSERT_EQ(readBinaryFiles(path1, path2, fileContent, exampleContent), 0); + ASSERT_EQ(fileContent, exampleContent); +} + +TEST_F(XlsbSimpleTests2, SlicerTest) +{ + auto tempDir = XlsbSimpleTests2::tempDir; + std::wstring path1(tempDir + FILE_SEPARATOR_STR + L"result_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"slicers" + FILE_SEPARATOR_STR + L"slicer2.bin"); + std::wstring path2(tempDir + FILE_SEPARATOR_STR +L"example_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"slicers" + FILE_SEPARATOR_STR + L"slicer2.bin"); + std::vector fileContent; + std::vector exampleContent; + ASSERT_EQ(readBinaryFiles(path1, path2, fileContent, exampleContent), 0); + ASSERT_EQ(fileContent, exampleContent); +} + +TEST_F(XlsbSimpleTests2, SlicerCacheTest) +{ + auto tempDir = XlsbSimpleTests2::tempDir; + std::wstring path1(tempDir + FILE_SEPARATOR_STR + L"result_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"slicerCaches" + FILE_SEPARATOR_STR + L"slicerCache2.bin"); + std::wstring path2(tempDir + FILE_SEPARATOR_STR +L"example_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"slicerCaches" + FILE_SEPARATOR_STR + L"slicerCache2.bin"); + std::vector fileContent; + std::vector exampleContent; + ASSERT_EQ(readBinaryFiles(path1, path2, fileContent, exampleContent), 0); + ASSERT_EQ(fileContent, exampleContent); +} + +TEST_F(XlsbSimpleTests2, PivotTableTest) +{ + auto tempDir = XlsbSimpleTests2::tempDir; + std::wstring path1(tempDir + FILE_SEPARATOR_STR + L"result_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"pivotTables" + FILE_SEPARATOR_STR + L"pivotTable2.bin"); + std::wstring path2(tempDir + FILE_SEPARATOR_STR +L"example_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"pivotTables" + FILE_SEPARATOR_STR + L"pivotTable2.bin"); + std::vector fileContent; + std::vector exampleContent; + ASSERT_EQ(readBinaryFiles(path1, path2, fileContent, exampleContent), 0); + ASSERT_EQ(fileContent, exampleContent); +} + +TEST_F(XlsbSimpleTests2, PivotCacheDefTest) +{ + auto tempDir = XlsbSimpleTests2::tempDir; + std::wstring path1(tempDir + FILE_SEPARATOR_STR + L"result_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"pivotCache" + FILE_SEPARATOR_STR + L"pivotCacheDefinition2.bin"); + std::wstring path2(tempDir + FILE_SEPARATOR_STR +L"example_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"pivotCache" + FILE_SEPARATOR_STR + L"pivotCacheDefinition2.bin"); + std::vector fileContent; + std::vector exampleContent; + ASSERT_EQ(readBinaryFiles(path1, path2, fileContent, exampleContent), 0); + ASSERT_EQ(fileContent, exampleContent); +} + +TEST_F(XlsbSimpleTests2, PivotCacheRecordsTest) +{ + auto tempDir = XlsbSimpleTests2::tempDir; + std::wstring path1(tempDir + FILE_SEPARATOR_STR + L"result_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"pivotCache" + FILE_SEPARATOR_STR + L"pivotCacheRecords2.bin"); + std::wstring path2(tempDir + FILE_SEPARATOR_STR +L"example_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"pivotCache" + FILE_SEPARATOR_STR + L"pivotCacheRecords2.bin"); + std::vector fileContent; + std::vector exampleContent; + ASSERT_EQ(readBinaryFiles(path1, path2, fileContent, exampleContent), 0); + ASSERT_EQ(fileContent, exampleContent); +} + +TEST_F(XlsbSimpleTests2, ChartSheetTest) +{ + auto tempDir = XlsbSimpleTests2::tempDir; + std::wstring path1(tempDir + FILE_SEPARATOR_STR + L"result_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"chartsheets" + FILE_SEPARATOR_STR + L"sheet1.bin"); + std::wstring path2(tempDir + FILE_SEPARATOR_STR +L"example_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"chartsheets" + FILE_SEPARATOR_STR + L"sheet1.bin"); + std::vector fileContent; + std::vector exampleContent; + ASSERT_EQ(readBinaryFiles(path1, path2, fileContent, exampleContent), 0); + ASSERT_EQ(fileContent, exampleContent); +} + + +TEST_F(XlsbFmlaTests, ContentTypesTest) +{ + auto tempDir = XlsbFmlaTests::tempDir; + std::wstring path1(tempDir + FILE_SEPARATOR_STR + L"result_unpacked"+ FILE_SEPARATOR_STR + L"[Content_Types].xml"); + std::wstring path2(tempDir + FILE_SEPARATOR_STR + L"example_unpacked"+ FILE_SEPARATOR_STR + L"[Content_Types].xml"); + std::vector fileContent; + std::vector exampleContent; + ASSERT_EQ(readBinaryFiles(path1, path2, fileContent, exampleContent), 0); + ASSERT_EQ(fileContent, exampleContent); +} + +TEST_F(XlsbFmlaTests, WorkbookTest) +{ + auto tempDir = XlsbFmlaTests::tempDir; + std::wstring path1(tempDir + FILE_SEPARATOR_STR + L"result_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"workbook.bin"); + std::wstring path2(tempDir + FILE_SEPARATOR_STR +L"example_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"workbook.bin"); + std::vector fileContent; + std::vector exampleContent; + ASSERT_EQ(readBinaryFiles(path1, path2, fileContent, exampleContent), 0); + ASSERT_EQ(fileContent, exampleContent); +} + +TEST_F(XlsbFmlaTests, StylesTest) +{ + auto tempDir = XlsbFmlaTests::tempDir; + std::wstring path1(tempDir + FILE_SEPARATOR_STR + L"result_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"styles.bin"); + std::wstring path2(tempDir + FILE_SEPARATOR_STR +L"example_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"styles.bin"); + std::vector fileContent; + std::vector exampleContent; + ASSERT_EQ(readBinaryFiles(path1, path2, fileContent, exampleContent), 0); + ASSERT_EQ(fileContent, exampleContent); +} + +TEST_F(XlsbFmlaTests, SharedStringsTest) +{ + auto tempDir = XlsbFmlaTests::tempDir; + std::wstring path1(tempDir + FILE_SEPARATOR_STR + L"result_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"sharedStrings.bin"); + std::wstring path2(tempDir + FILE_SEPARATOR_STR +L"example_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"sharedStrings.bin"); + std::vector fileContent; + std::vector exampleContent; + ASSERT_EQ(readBinaryFiles(path1, path2, fileContent, exampleContent), 0); + ASSERT_EQ(fileContent, exampleContent); +} + +TEST_F(XlsbFmlaTests, WorksheetsTest1) +{ + auto tempDir = XlsbFmlaTests::tempDir; + std::wstring path1(tempDir + FILE_SEPARATOR_STR + L"result_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"worksheets" + FILE_SEPARATOR_STR + L"sheet1.bin"); + std::wstring path2(tempDir + FILE_SEPARATOR_STR +L"example_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"worksheets" + FILE_SEPARATOR_STR + L"sheet1.bin"); + std::vector fileContent; + std::vector exampleContent; + ASSERT_EQ(readBinaryFiles(path1, path2, fileContent, exampleContent), 0); + ASSERT_EQ(fileContent, exampleContent); +} + +TEST_F(XlsbFmlaTests, WorksheetsTest2) +{ + auto tempDir = XlsbFmlaTests::tempDir; + std::wstring path1(tempDir + FILE_SEPARATOR_STR + L"result_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"worksheets" + FILE_SEPARATOR_STR + L"sheet2.bin"); + std::wstring path2(tempDir + FILE_SEPARATOR_STR +L"example_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"worksheets" + FILE_SEPARATOR_STR + L"sheet2.bin"); + std::vector fileContent; + std::vector exampleContent; + ASSERT_EQ(readBinaryFiles(path1, path2, fileContent, exampleContent), 0); + ASSERT_EQ(fileContent, exampleContent); +} + +TEST_F(XlsbFmlaTests, WorksheetsTest3) +{ + auto tempDir = XlsbFmlaTests::tempDir; + std::wstring path1(tempDir + FILE_SEPARATOR_STR + L"result_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"worksheets" + FILE_SEPARATOR_STR + L"sheet3.bin"); + std::wstring path2(tempDir + FILE_SEPARATOR_STR +L"example_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"worksheets" + FILE_SEPARATOR_STR + L"sheet3.bin"); + std::vector fileContent; + std::vector exampleContent; + ASSERT_EQ(readBinaryFiles(path1, path2, fileContent, exampleContent), 0); + ASSERT_EQ(fileContent, exampleContent); +} + + +} \ No newline at end of file diff --git a/OdfFile/Common/odf_elements_type.h b/OdfFile/Common/odf_elements_type.h index 7214ec3f953..cc0aa85cd9a 100644 --- a/OdfFile/Common/odf_elements_type.h +++ b/OdfFile/Common/odf_elements_type.h @@ -307,6 +307,7 @@ enum ElementType typeStyleFontFace, + typeSvgTitle, typeSvgDesc, typeSvgFontFaceUri, typeSvgFontFaceFormat, @@ -533,6 +534,9 @@ enum ElementType typeFormItem, typeFormOption, + typeContentControl, + typeListItem, + typeDrawPage, typePresentationFooterDecl, typePresentationDateTimeDecl, @@ -544,6 +548,11 @@ enum ElementType typeAnimAudio, typeAnimCommand, typeAnimIterate, + typeAnimSet, + typeAnimAnimate, + typeAnimAnimateTransform, + typeAnimAnimateMotion, + typeAnimAnimateColor, typeStyleGraphicPropertis, typeStyleDrawGradient, @@ -566,6 +575,7 @@ enum ElementType typeOfficeScripts, typeOfficeScript, typeOfficePresentation, + typeOfficeDrawing, typeOfficeChart, typeOfficeEventListeners, diff --git a/OdfFile/Common/utils.cpp b/OdfFile/Common/utils.cpp index e50c0cd615b..65bfea54737 100644 --- a/OdfFile/Common/utils.cpp +++ b/OdfFile/Common/utils.cpp @@ -96,8 +96,8 @@ namespace _graphics_utils_ double dpi_x = file->GetHorizontalResolution(); double dpi_y = file->GetVerticalResolution(); - if (dpi_x <1 )dpi_x = 96; - if (dpi_y <1 )dpi_y = 96; + if (dpi_x <1 ) dpi_x = 96; + if (dpi_y <1 ) dpi_y = 96; Height = Height *72. / dpi_y; Width = Width * 72. /dpi_x; @@ -110,16 +110,17 @@ namespace _graphics_utils_ } return result; } - double calculate_size_symbol_win(std::wstring name, double size, bool italic, bool bold, std::wstring test_str) + std::pair calculate_size_symbol_win(std::wstring name, double size, bool italic, bool bold, std::wstring test_str) { - double result =0; + std::pair result = std::make_pair(7., 8.); + #if defined(_WIN32) || defined(_WIN64) Gdiplus::GdiplusStartupInput gdiplusStartupInput; ULONG_PTR gdiplusToken=0; Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL); //// bool to_one_char = false; - if (test_str.length() <1 ) + if (test_str.empty()) { test_str = L"0123456789"; to_one_char = true; @@ -142,13 +143,22 @@ namespace _graphics_utils_ Gdiplus::RectF bound; Gdiplus::Status res = gr->MeasureString(test_str.c_str(),test_str.length(),font,layout,&bound); - if (res==0)result = (bound.Width - 2); - if (to_one_char) result /= test_str.length(); + if (res == 0) + { + result.first = (bound.Width - 2); + result.second = (bound.Height - 2); + } + if (to_one_char) + { + result.first /= test_str.length(); + } //normalize to dpi = 96; - double dpi = gr->GetDpiX(); + double dpiX = gr->GetDpiX(); + double dpiY = gr->GetDpiY(); - result = result * 96./dpi; + result.first = result.first * 96./ dpiX; + result.second = result.second * 96. / dpiY; delete font; } @@ -158,12 +168,12 @@ namespace _graphics_utils_ #endif return result; } - std::pair calculate_size_symbol_asc(std::wstring name, double size, bool italic, bool bold , NSFonts::IApplicationFonts *appFonts) + std::pair calculate_size_symbol_asc(std::wstring name, double size, bool italic, bool bold , NSFonts::IApplicationFonts *appFonts) { if (name.empty()) name = L"Calibri"; - std::pair val = cpdoccore::utils::GetMaxDigitSizePixels(name, size, 96., 0 , appFonts); + std::pair val = cpdoccore::utils::GetMaxDigitSizePixels(name, size, 96., 0 , appFonts); return val; } diff --git a/OdfFile/Common/utils.h b/OdfFile/Common/utils.h index d1c269b3486..1e57a2eb80c 100644 --- a/OdfFile/Common/utils.h +++ b/OdfFile/Common/utils.h @@ -41,6 +41,6 @@ namespace NSFonts namespace _graphics_utils_ { bool GetResolution(const wchar_t* fileName, double & Width, double &Height); - double calculate_size_symbol_win(std::wstring name, double size, bool italic, bool bold, std::wstring test_str = L""); - std::pair calculate_size_symbol_asc(std::wstring name, double size, bool italic, bool bold , NSFonts::IApplicationFonts *appFonts); + std::pair calculate_size_symbol_win(std::wstring name, double size, bool italic, bool bold, std::wstring test_str = L""); + std::pair calculate_size_symbol_asc(std::wstring name, double size, bool italic, bool bold , NSFonts::IApplicationFonts *appFonts); }; diff --git a/OdfFile/DataTypes/animation_attlists.cpp b/OdfFile/DataTypes/animation_attlists.cpp new file mode 100644 index 00000000000..8b7f4a28388 --- /dev/null +++ b/OdfFile/DataTypes/animation_attlists.cpp @@ -0,0 +1,252 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ + +#include +#include "animation_attlists.h" + +#define _CP_APPLY_PROP(A, B) \ + if (B) \ + A = B; + +#define _CP_APPLY_PROP2(A) \ + if (Other.A) \ + A = Other.A; + +#define _CP_APPLY_PROP3(A) \ + if (Other->A) \ + A = Other->A; + +namespace cpdoccore { +namespace odf_types { + + + void anim_par_attlist::add_attributes(const xml::attributes_wc_ptr& Attributes) + { + CP_APPLY_ATTR(L"presentation:preset-class", presentation_preset_class_); + CP_APPLY_ATTR(L"presentation:preset-id", presentation_preset_id_); + CP_APPLY_ATTR(L"presentation:preset-sub-type", presentation_preset_sub_type_); + CP_APPLY_ATTR(L"smil:accelerate", smil_accelerate_); + CP_APPLY_ATTR(L"smil:decelerate", smil_decelerate_); + } + + void anim_par_attlist::apply_from(const anim_par_attlist& Other) + { + _CP_APPLY_PROP2(presentation_preset_class_); + _CP_APPLY_PROP2(presentation_preset_id_); + _CP_APPLY_PROP2(presentation_preset_sub_type_); + _CP_APPLY_PROP2(smil_accelerate_); + _CP_APPLY_PROP2(smil_decelerate_); + } + + void anim_par_attlist::serialize(CP_ATTR_NODE) + { + CP_XML_ATTR_OPT(L"presentation:preset-class", presentation_preset_class_); + CP_XML_ATTR_OPT(L"presentation:preset-id", presentation_preset_id_); + CP_XML_ATTR_OPT(L"presentation:preset-sub-type", presentation_preset_sub_type_); + CP_XML_ATTR_OPT(L"smil:accelerate", smil_accelerate_); + CP_XML_ATTR_OPT(L"smil:decelerate", smil_decelerate_); + } + + void anim_audio_attlist::add_attributes(const xml::attributes_wc_ptr& Attributes) + { + CP_APPLY_ATTR(L"xlink:href", xlink_href_); + CP_APPLY_ATTR(L"anim:audio-level", anim_audio_level_); + } + + void anim_audio_attlist::apply_from(const anim_audio_attlist& Other) + { + _CP_APPLY_PROP2(xlink_href_); + _CP_APPLY_PROP2(anim_audio_level_); + } + + void anim_audio_attlist::serialize(CP_ATTR_NODE) + { + CP_XML_ATTR_OPT(L"xlink:href", xlink_href_); + CP_XML_ATTR_OPT(L"anim:audio-level", anim_audio_level_); + } + + void anim_transition_filter_attlist::add_attributes(const xml::attributes_wc_ptr& Attributes) + { + CP_APPLY_ATTR(L"smil:subtype", smil_subtype_); + CP_APPLY_ATTR(L"smil:type", smil_type_); + CP_APPLY_ATTR(L"smil:fadeColor", smil_fadeColor_); + CP_APPLY_ATTR(L"smil:mode", smil_mode_); + CP_APPLY_ATTR(L"smil:direction", smil_direction_); + } + + void anim_transition_filter_attlist::apply_from(const anim_transition_filter_attlist& Other) + { + _CP_APPLY_PROP2(smil_subtype_); + _CP_APPLY_PROP2(smil_type_); + _CP_APPLY_PROP2(smil_mode_); + _CP_APPLY_PROP2(smil_fadeColor_); + _CP_APPLY_PROP2(smil_direction_); + } + + void anim_transition_filter_attlist::serialize(CP_ATTR_NODE) + { + CP_XML_ATTR_OPT(L"smil:subtype", smil_subtype_); + CP_XML_ATTR_OPT(L"smil:type", smil_type_); + CP_XML_ATTR_OPT(L"smil:mode", smil_mode_); + CP_XML_ATTR_OPT(L"smil:fadeColor", smil_fadeColor_); + CP_XML_ATTR_OPT(L"smil:direction", smil_direction_); + } + + void anim_set_attlist::add_attributes(const xml::attributes_wc_ptr& Attributes) + { + CP_APPLY_ATTR(L"smil:to", smil_to_); + } + + void anim_set_attlist::apply_from(const anim_set_attlist& Other) + { + _CP_APPLY_PROP2(smil_to_); + } + + void anim_set_attlist::serialize(CP_ATTR_NODE) + { + CP_XML_ATTR_OPT(L"smil:to", smil_to_); + } + + void anim_animate_motion_attlist::add_attributes(const xml::attributes_wc_ptr& Attributes) + { + CP_APPLY_ATTR(L"svg:path", svg_path_); + } + + void anim_animate_motion_attlist::apply_from(const anim_animate_motion_attlist& Other) + { + _CP_APPLY_PROP2(svg_path_); + } + + void anim_animate_motion_attlist::serialize(CP_ATTR_NODE) + { + CP_XML_ATTR_OPT(L"svg:path", svg_path_); + } + + void anim_animate_color_attlist::add_attributes(const xml::attributes_wc_ptr& Attributes) + { + CP_APPLY_ATTR(L"smil:to", smil_to_); + CP_APPLY_ATTR(L"smil:by", smil_by_); + CP_APPLY_ATTR(L"presentation:master-element", presentation_master_element_); + CP_APPLY_ATTR(L"anim:color-interpolation", anim_color_interpolation_); + CP_APPLY_ATTR(L"anim:color-interpolation-direction", anim_color_interpolation_direction); + } + + void anim_animate_color_attlist::apply_from(const anim_animate_color_attlist& Other) + { + _CP_APPLY_PROP2(smil_to_); + _CP_APPLY_PROP2(smil_by_); + _CP_APPLY_PROP2(presentation_master_element_); + _CP_APPLY_PROP2(anim_color_interpolation_); + _CP_APPLY_PROP2(anim_color_interpolation_direction); + } + + void anim_animate_color_attlist::serialize(CP_ATTR_NODE) + { + CP_XML_ATTR_OPT(L"smil:to", smil_to_); + CP_XML_ATTR_OPT(L"smil:by", smil_by_); + CP_XML_ATTR_OPT(L"presentation:master-element", presentation_master_element_); + CP_XML_ATTR_OPT(L"anim:color-interpolation", anim_color_interpolation_); + CP_XML_ATTR_OPT(L"anim:color-interpolation-direction", anim_color_interpolation_direction); + } + + void anim_animate_attlist::add_attributes(const xml::attributes_wc_ptr& Attributes) + { + CP_APPLY_ATTR(L"smil:values", smil_values_); + CP_APPLY_ATTR(L"smil:keyTimes", smil_key_times_); + CP_APPLY_ATTR(L"smil:calcMode", smil_calc_mode_); + CP_APPLY_ATTR(L"smil:from", smil_from_); + CP_APPLY_ATTR(L"smil:to", smil_to_); + CP_APPLY_ATTR(L"smil:by", smil_by_); + CP_APPLY_ATTR(L"smil:autoReverse", smil_auto_reverse_); + CP_APPLY_ATTR(L"smil:additive", smil_additive_); + CP_APPLY_ATTR(L"anim:formula", anim_formula_); + CP_APPLY_ATTR(L"svg:type", svg_type_); + } + + void anim_animate_attlist::apply_from(const anim_animate_attlist& Other) + { + _CP_APPLY_PROP2(smil_values_); + _CP_APPLY_PROP2(smil_key_times_); + _CP_APPLY_PROP2(anim_formula_); + _CP_APPLY_PROP2(smil_calc_mode_); + _CP_APPLY_PROP2(smil_from_); + _CP_APPLY_PROP2(smil_to_); + _CP_APPLY_PROP2(smil_by_); + _CP_APPLY_PROP2(smil_additive_); + _CP_APPLY_PROP2(smil_auto_reverse_); + _CP_APPLY_PROP2(svg_type_); + } + + void anim_animate_attlist::serialize(CP_ATTR_NODE) + { + CP_XML_ATTR_OPT(L"smil:values", smil_values_); + CP_XML_ATTR_OPT(L"smil:keyTimes", smil_key_times_); + CP_XML_ATTR_OPT(L"anim:formula", anim_formula_); + CP_XML_ATTR_OPT(L"smil:calcMode", smil_calc_mode_); + CP_XML_ATTR_OPT(L"smil:from", smil_from_); + CP_XML_ATTR_OPT(L"smil:to", smil_to_); + CP_XML_ATTR_OPT(L"smil:by", smil_by_); + CP_XML_ATTR_OPT(L"smil:additive", smil_additive_); + CP_XML_ATTR_OPT(L"smil:autoReverse", smil_auto_reverse_); + CP_XML_ATTR_OPT(L"svg:type", svg_type_); + } + + void anim_animate_transform_attlist::add_attributes(const xml::attributes_wc_ptr& Attributes) + { + CP_APPLY_ATTR(L"smil:autoReverse", smil_auto_reverse_); + CP_APPLY_ATTR(L"smil:from", smil_from_); + CP_APPLY_ATTR(L"smil:to", smil_to_); + CP_APPLY_ATTR(L"smil:by", smil_by_); + CP_APPLY_ATTR(L"svg:type", svg_type_); + } + + + void anim_animate_transform_attlist::apply_from(const anim_animate_transform_attlist& Other) + { + _CP_APPLY_PROP2(smil_auto_reverse_); + _CP_APPLY_PROP2(smil_from_); + _CP_APPLY_PROP2(smil_to_); + _CP_APPLY_PROP2(smil_by_); + _CP_APPLY_PROP2(svg_type_); + } + + void anim_animate_transform_attlist::serialize(CP_ATTR_NODE) + { + CP_XML_ATTR_OPT(L"smil:autoReverse", smil_auto_reverse_); + CP_XML_ATTR_OPT(L"smil:from", smil_from_); + CP_XML_ATTR_OPT(L"smil:to", smil_to_); + CP_XML_ATTR_OPT(L"smil:by", smil_by_); + CP_XML_ATTR_OPT(L"svg:type", svg_type_); + } + +} // namespace odf_types +} // namespace cpdoccore \ No newline at end of file diff --git a/OdfFile/DataTypes/animation_attlists.h b/OdfFile/DataTypes/animation_attlists.h new file mode 100644 index 00000000000..1c5241cee1d --- /dev/null +++ b/OdfFile/DataTypes/animation_attlists.h @@ -0,0 +1,158 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#pragma once + +#include "../Common/xml/simple_xml_writer.h" + +#include "presetclass.h" +#include "presetid.h" +#include "color.h" +#include "bool.h" +#include "svg_type.h" +#include "smil_transitiontype.h" +#include "smil_attributename.h" +#include "smil_additive.h" +#include "smil_keytimes.h" +#include "smil_values.h" + +namespace cpdoccore { +namespace odf_types { + +class anim_par_attlist +{ +public: + void add_attributes(const xml::attributes_wc_ptr& Attributes); + void apply_from(const anim_par_attlist& Other); + void serialize(CP_ATTR_NODE); + + _CP_OPT(preset_class) presentation_preset_class_; + _CP_OPT(preset_id) presentation_preset_id_; + _CP_OPT(std::wstring) presentation_preset_sub_type_; + _CP_OPT(float) smil_accelerate_; + _CP_OPT(float) smil_decelerate_; +}; + +class anim_audio_attlist +{ +public: + void add_attributes(const xml::attributes_wc_ptr& Attributes); + void apply_from(const anim_audio_attlist& Other); + void serialize(CP_ATTR_NODE); + + _CP_OPT(std::wstring) xlink_href_; + _CP_OPT(std::wstring) anim_audio_level_; +}; + +class anim_transition_filter_attlist +{ +public: + void add_attributes(const xml::attributes_wc_ptr& Attributes); + void apply_from(const anim_transition_filter_attlist& Other); + void serialize(CP_ATTR_NODE); + + _CP_OPT(std::wstring) smil_subtype_; + _CP_OPT(smil_transition_type) smil_type_; + _CP_OPT(std::wstring) smil_mode_; + _CP_OPT(color) smil_fadeColor_; + _CP_OPT(std::wstring) smil_direction_; +}; + +class anim_set_attlist +{ +public: + void add_attributes(const xml::attributes_wc_ptr& Attributes); + void apply_from(const anim_set_attlist& Other); + void serialize(CP_ATTR_NODE); + + _CP_OPT(std::wstring) smil_to_; +}; + +class anim_animate_motion_attlist +{ +public: + void add_attributes(const xml::attributes_wc_ptr& Attributes); + void apply_from(const anim_animate_motion_attlist& Other); + void serialize(CP_ATTR_NODE); + + _CP_OPT(std::wstring) svg_path_; +}; + +class anim_animate_color_attlist +{ +public: + void add_attributes(const xml::attributes_wc_ptr& Attributes); + void apply_from(const anim_animate_color_attlist& Other); + void serialize(CP_ATTR_NODE); + + _CP_OPT(std::wstring) smil_to_; + _CP_OPT(std::wstring) smil_by_; + _CP_OPT(std::wstring) presentation_master_element_; + _CP_OPT(std::wstring) anim_color_interpolation_; + _CP_OPT(std::wstring) anim_color_interpolation_direction; +}; + +class anim_animate_attlist +{ +public: + void add_attributes(const xml::attributes_wc_ptr& Attributes); + void apply_from(const anim_animate_attlist& Other); + void serialize(CP_ATTR_NODE); + + _CP_OPT(smil_values) smil_values_; + _CP_OPT(smil_key_times) smil_key_times_; + _CP_OPT(std::wstring) anim_formula_; + _CP_OPT(std::wstring) smil_calc_mode_; + _CP_OPT(std::wstring) smil_from_; + _CP_OPT(std::wstring) smil_to_; + _CP_OPT(std::wstring) smil_by_; + _CP_OPT(smil_additive) smil_additive_; + _CP_OPT(Bool) smil_auto_reverse_; + _CP_OPT(svg_type) svg_type_; + +}; + +class anim_animate_transform_attlist +{ +public: + void add_attributes(const xml::attributes_wc_ptr& Attributes); + void apply_from(const anim_animate_transform_attlist& Other); + void serialize(CP_ATTR_NODE); + + _CP_OPT(Bool) smil_auto_reverse_; + _CP_OPT(std::wstring) smil_from_; + _CP_OPT(std::wstring) smil_to_; + _CP_OPT(std::wstring) smil_by_; + _CP_OPT(svg_type) svg_type_; +}; + +} // namespace odf_types +} // namespace cpdoccore \ No newline at end of file diff --git a/OdfFile/DataTypes/borderstyle.cpp b/OdfFile/DataTypes/borderstyle.cpp index 7c37ae92421..77351635149 100644 --- a/OdfFile/DataTypes/borderstyle.cpp +++ b/OdfFile/DataTypes/borderstyle.cpp @@ -47,11 +47,14 @@ std::wostream & operator << (std::wostream & _Wostream, const border_style & bor switch (borderStyle.get_style()) { - case border_style::none: _Wostream << L" none "; break; - case border_style::double_: _Wostream << L" double "; break; - case border_style::dotted: _Wostream << L" dotted "; break; - case border_style::dashed: _Wostream << L" dashed "; break; - case border_style::dot_dashed: _Wostream << L" dot-dashed "; break; + case border_style::none: _Wostream << L" none "; break; + case border_style::double_: _Wostream << L" double "; break; + case border_style::dotted: _Wostream << L" dotted "; break; + case border_style::dash: _Wostream << L" dashed "; break; + case border_style::dot_dash: _Wostream << L" dash-dot "; break; + case border_style::dot_dot_dash: _Wostream << L" dash-dot-dot "; break; + case border_style::fine_dashed: _Wostream << L" fine-dashed "; break; + case border_style::double_thin: _Wostream << L" double-thin "; break; case border_style::solid: default: _Wostream << L" solid "; break; @@ -95,7 +98,11 @@ border_style& border_style::operator =(const border_style& Value) return *this; } -border_style::border_style(const std::wstring & Value) : initialized_(false), none_(false) +border_style::border_style() : initialized_(false), none_(true), style_(none) +{ +} + +border_style::border_style(const std::wstring & Value) : initialized_(false), none_(false), style_(none) { if (Value.empty()) return; @@ -124,8 +131,12 @@ border_style::border_style(const std::wstring & Value) : initialized_(false), no if (splitted[1] == L"solid") style_ = solid; if (splitted[1] == L"double") style_ = double_; if (splitted[1] == L"dotted") style_ = dotted; - if (splitted[1] == L"dashed") style_ = dashed; - if (splitted[1] == L"dot-dashed") style_ = dot_dashed; + if (splitted[1] == L"dashed") style_ = dash; + if (splitted[1] == L"dot-dashed") style_ = dot_dash; + if (splitted[1] == L"dash-dot") style_ = dot_dash; + if (splitted[1] == L"dash-dot-dot") style_ = dot_dot_dash; + if (splitted[1] == L"fine-dashed") style_ = fine_dashed; + if (splitted[1] == L"double-thin") style_ = double_thin; } if (splitted.size() > 2) @@ -157,6 +168,21 @@ border_style::border_style(const color & color_, const type & style_, const len initialized_ = true; } +bool border_style::initialized() const { return initialized_; } +bool border_style::is_none() const { return none_; } + +const length& border_style::get_length()const +{ + return length_; +} +const border_style::type& border_style::get_style() const +{ + return style_; +} +const color& border_style::get_color() const +{ + return color_; +} } diff --git a/OdfFile/DataTypes/borderstyle.h b/OdfFile/DataTypes/borderstyle.h index ec77b9f0c07..fa4a012c114 100644 --- a/OdfFile/DataTypes/borderstyle.h +++ b/OdfFile/DataTypes/borderstyle.h @@ -44,23 +44,21 @@ class border_style { none, solid, - double_, dotted, - dashed, - dot_dashed, + dash, long_dash, dot_dash, dot_dot_dash, - single, groove, + double_, ridge, inset, outset, - hidden - + hidden, + fine_dashed, + double_thin }; - - border_style(){none_ = true;} + border_style(); border_style(const std::wstring & Value); border_style(const border_style & Value); @@ -69,18 +67,18 @@ class border_style static border_style parse(const std::wstring & Str); border_style& operator=(const border_style& ob); public: - bool initialized() const { return initialized_; } - bool is_none() const { return none_; } + bool initialized() const; + bool is_none() const; - const length & get_length()const { return length_; } - const type & get_style() const { return style_; } - const color & get_color() const { return color_; } + const length & get_length()const; + const type & get_style() const; + const color & get_color() const; private: - bool none_; - bool initialized_; + bool none_ = true; + bool initialized_ = false; length length_; - type style_; + type style_ = none; color color_; }; diff --git a/OdfFile/DataTypes/borderwidths.cpp b/OdfFile/DataTypes/borderwidths.cpp index 2f3a7d1cdb4..c28403e6d1e 100644 --- a/OdfFile/DataTypes/borderwidths.cpp +++ b/OdfFile/DataTypes/borderwidths.cpp @@ -39,7 +39,7 @@ namespace cpdoccore { namespace odf_types { std::wostream & operator << (std::wostream & _Wostream, const border_widths & _Val) { - _Wostream << _Val.get_len1() << " " << _Val.get_len2() << " " << _Val.get_len3(); + _Wostream << _Val.get_len1() << L" " << _Val.get_len2() << L" " << _Val.get_len3(); return _Wostream; } diff --git a/OdfFile/DataTypes/clockvalue.cpp b/OdfFile/DataTypes/clockvalue.cpp index ccdb30fe81b..c6801ff8d4c 100644 --- a/OdfFile/DataTypes/clockvalue.cpp +++ b/OdfFile/DataTypes/clockvalue.cpp @@ -46,6 +46,7 @@ std::wostream & operator << (std::wostream & _Wostream, const clockvalue & _Val) _Wostream << L"indefinite"; else { +#if 0 int ms = _Val.get_value(); int sec = 0; int min = 0; @@ -80,6 +81,13 @@ std::wostream & operator << (std::wostream & _Wostream, const clockvalue & _Val) if (h == 0 && min == 0 && ms == 0 && sec == 0) _Wostream << "0s"; +#else + int ms = _Val.get_value(); + float sec = ms / 1000.0f; + + _Wostream << sec << L"s"; + +#endif } return _Wostream; } @@ -126,7 +134,7 @@ bool parseTime(std::wstring Time, double & Hours, double & Minutes, double & Sec boost::wregex r3 (L"([\\d+(\\.\\d{0,})?]+)([A-Za-z]+)"); if (boost::regex_split(std::back_inserter(values), Time, r3, boost::match_default | boost::format_all)) { - int val = -1; + double val = -1; for (size_t i = 0; i < values.size() ; i++ ) { if (values[i].empty()) continue; diff --git a/OdfFile/DataTypes/common_attlists.cpp b/OdfFile/DataTypes/common_attlists.cpp index 04484eb1390..8fcff8aa423 100644 --- a/OdfFile/DataTypes/common_attlists.cpp +++ b/OdfFile/DataTypes/common_attlists.cpp @@ -439,6 +439,7 @@ void common_value_and_type_attlist::apply_from(const common_value_and_type_attli void common_value_and_type_attlist::serialize(CP_ATTR_NODE) { CP_XML_ATTR_OPT(L"office:value-type", office_value_type_); + CP_XML_ATTR_OPT(L"calcext:value-type", office_value_type_); CP_XML_ATTR_OPT(L"office:value", office_value_); if (office_value_) { @@ -885,17 +886,28 @@ void common_anim_smil_attlist::add_attributes( const xml::attributes_wc_ptr & At CP_APPLY_ATTR(L"smil:end", smil_end_); CP_APPLY_ATTR(L"smil:restart", smil_restart_); CP_APPLY_ATTR(L"smil:dur", smil_dur_); - + CP_APPLY_ATTR(L"smil:targetElement", smil_target_element_); + CP_APPLY_ATTR(L"smil:attributeName", smil_attribute_name_); + CP_APPLY_ATTR(L"smil:fill", smil_fill_); + CP_APPLY_ATTR(L"smil:autoReverse", smil_auto_reverse_); + CP_APPLY_ATTR(L"smil:accelerate", smil_accelerate_); + CP_APPLY_ATTR(L"smil:decelerate", smil_decelerate_); } void common_anim_smil_attlist::apply_from(const common_anim_smil_attlist & Other) { _CP_APPLY_PROP(presentation_node_type_, Other.presentation_node_type_); - _CP_APPLY_PROP(smil_direction_, Other.smil_direction_); - _CP_APPLY_PROP(smil_begin_, Other.smil_begin_); - _CP_APPLY_PROP(smil_end_, Other.smil_end_); - _CP_APPLY_PROP(smil_restart_, Other.smil_restart_); - _CP_APPLY_PROP(smil_dur_, Other.smil_dur_); + _CP_APPLY_PROP(smil_direction_, Other.smil_direction_); + _CP_APPLY_PROP(smil_begin_, Other.smil_begin_); + _CP_APPLY_PROP(smil_end_, Other.smil_end_); + _CP_APPLY_PROP(smil_restart_, Other.smil_restart_); + _CP_APPLY_PROP(smil_dur_, Other.smil_dur_); + _CP_APPLY_PROP(smil_target_element_, Other.smil_target_element_); + _CP_APPLY_PROP(smil_attribute_name_, Other.smil_attribute_name_); + _CP_APPLY_PROP(smil_fill_, Other.smil_fill_); + _CP_APPLY_PROP(smil_auto_reverse_, Other.smil_auto_reverse_); + _CP_APPLY_PROP(smil_accelerate_, Other.smil_accelerate_); + _CP_APPLY_PROP(smil_decelerate_, Other.smil_decelerate_); } void common_anim_smil_attlist::serialize(CP_ATTR_NODE) { @@ -905,9 +917,16 @@ void common_anim_smil_attlist::serialize(CP_ATTR_NODE) CP_XML_ATTR_OPT(L"presentation:node-type", presentation_node_type_); CP_XML_ATTR_OPT(L"smil:begin", smil_begin_); CP_XML_ATTR_OPT(L"smil:end", smil_end_); + CP_XML_ATTR_OPT(L"smil:targetElement", smil_target_element_); + CP_XML_ATTR_OPT(L"smil:attributeName", smil_attribute_name_); + CP_XML_ATTR_OPT(L"smil:fill", smil_fill_); + CP_XML_ATTR_OPT(L"smil:autoReverse", smil_auto_reverse_); + CP_XML_ATTR_OPT(L"smil:accelerate", smil_accelerate_); + CP_XML_ATTR_OPT(L"smil:decelerate", smil_decelerate_); } void union_common_draw_attlists::serialize(CP_ATTR_NODE) { + //CP_XML_ATTR_OPT(L"xml:id", xml_id_); shape_with_text_and_styles_.serialize(CP_GET_XML_NODE()); rel_size_.serialize(CP_GET_XML_NODE()); position_.serialize(CP_GET_XML_NODE()); diff --git a/OdfFile/DataTypes/common_attlists.h b/OdfFile/DataTypes/common_attlists.h index 141a90029bd..0ca30b8195b 100644 --- a/OdfFile/DataTypes/common_attlists.h +++ b/OdfFile/DataTypes/common_attlists.h @@ -52,9 +52,12 @@ #include "anchortype.h" #include "linewidth.h" #include "presentationclass.h" +#include "presentationnodetype.h" #include "xlink.h" #include "drawfill.h" #include "clockvalue.h" +#include "smil_attributename.h" +#include "smil_fill.h" #include "stylerepeat.h" #include "officevaluetype.h" #include "fillimagerefpoint.h" @@ -578,6 +581,7 @@ class common_data_style_attlist struct union_common_draw_attlists { + //_CP_OPT(std::wstring) xml_id_; common_draw_shape_with_text_and_styles_attlist shape_with_text_and_styles_; common_draw_position_attlist position_; common_draw_rel_size_attlist rel_size_; @@ -592,14 +596,21 @@ class common_anim_smil_attlist void apply_from (const common_anim_smil_attlist & Other); void serialize (CP_ATTR_NODE); - _CP_OPT(std::wstring) presentation_node_type_; + _CP_OPT(odf_types::presentation_node_type) presentation_node_type_; - _CP_OPT(std::wstring) smil_direction_; - _CP_OPT(std::wstring) smil_restart_; - _CP_OPT(odf_types::clockvalue) smil_dur_; + _CP_OPT(std::wstring) smil_direction_; + _CP_OPT(std::wstring) smil_restart_; + _CP_OPT(odf_types::clockvalue) smil_dur_; + _CP_OPT(std::wstring) smil_target_element_; + _CP_OPT(odf_types::smil_attribute_name) smil_attribute_name_; + _CP_OPT(odf_types::smil_fill) smil_fill_; + _CP_OPT(odf_types::Bool) smil_auto_reverse_; - _CP_OPT(std::wstring) smil_begin_; - _CP_OPT(std::wstring) smil_end_; + _CP_OPT(std::wstring) smil_begin_; + _CP_OPT(std::wstring) smil_end_; + + _CP_OPT(double) smil_accelerate_; + _CP_OPT(double) smil_decelerate_; }; class section_attlists diff --git a/OdfFile/DataTypes/custom_shape_types_convert.h b/OdfFile/DataTypes/custom_shape_types_convert.h index b61cb447108..31a5c3b7733 100644 --- a/OdfFile/DataTypes/custom_shape_types_convert.h +++ b/OdfFile/DataTypes/custom_shape_types_convert.h @@ -30,6 +30,7 @@ * */ #pragma once +#include struct _shape_converter { @@ -54,7 +55,7 @@ static const _shape_converter _OO_OOX_custom_shapes[]= {L"star4" ,L"star4" ,1 ,0 ,50000 }, {L"star5" ,L"star5" ,0 ,0 ,50000 },//??? 19098 неверно {L"star8" ,L"star8" ,0 ,0 ,50000 }, -{L"star24" ,L"star24" ,1 ,0 ,50000 }, +{L"star24" ,L"star24" ,0 ,0 ,50000 }, {L"star6" ,L"star6" ,0 ,0 ,50000 }, {L"star12" ,L"star12" ,1 ,0 ,50000 }, {L"round-rectangle" ,L"roundRect" ,0 ,0 ,0 }, diff --git a/OdfFile/DataTypes/dropcaplength.cpp b/OdfFile/DataTypes/dropcaplength.cpp index 480143bee57..dd5873f735c 100644 --- a/OdfFile/DataTypes/dropcaplength.cpp +++ b/OdfFile/DataTypes/dropcaplength.cpp @@ -42,7 +42,7 @@ std::wostream & operator << (std::wostream & _Wostream, const drop_cap_length & switch(_Val.get_type()) { case drop_cap_length::Word: - _Wostream << "word"; + _Wostream << L"word"; break; case drop_cap_length::Integer: _Wostream << _Val.get_value(); diff --git a/OdfFile/DataTypes/iconset_type.cpp b/OdfFile/DataTypes/iconset_type.cpp index e33365eb071..b2b1b8ec903 100644 --- a/OdfFile/DataTypes/iconset_type.cpp +++ b/OdfFile/DataTypes/iconset_type.cpp @@ -92,8 +92,18 @@ std::wostream & operator << (std::wostream & _Wostream, const iconset_type & _Va case iconset_type::Rating5: _Wostream << L"5Rating"; break; - default: + case iconset_type::Boxes5: + _Wostream << L"5Boxes"; break; + case iconset_type::Triangles3: + _Wostream << L"3Triangles"; + break; + case iconset_type::Stars3: + _Wostream << L"3Stars"; + break; + default: + _Wostream << L"3Arrows"; + break; } return _Wostream; } @@ -137,7 +147,15 @@ iconset_type iconset_type::parse(const std::wstring & Str) return iconset_type( Quarters5 ); else if (tmp == L"5rating") return iconset_type( Rating5 ); - else + else if (tmp == L"5boxes") + return iconset_type( Boxes5 ); + else if (tmp == L"3stars") + return iconset_type(Stars3); + else if (tmp == L"3triangles") + return iconset_type(Triangles3); + else if (tmp == L"4rating") + return iconset_type(Rating4); + else { return iconset_type( Arrows3 ); } diff --git a/OdfFile/DataTypes/iconset_type.h b/OdfFile/DataTypes/iconset_type.h index 71f4dfd20cc..cfee13fb156 100644 --- a/OdfFile/DataTypes/iconset_type.h +++ b/OdfFile/DataTypes/iconset_type.h @@ -59,7 +59,10 @@ class iconset_type Arrows5, Arrows5Gray, Quarters5, - Rating5 + Rating5, + Triangles3, + Stars3, + Boxes5 }; iconset_type() {} diff --git a/OdfFile/DataTypes/linemode.cpp b/OdfFile/DataTypes/linemode.cpp index 0086dc48174..9c34af9bd7f 100644 --- a/OdfFile/DataTypes/linemode.cpp +++ b/OdfFile/DataTypes/linemode.cpp @@ -41,10 +41,10 @@ std::wostream & operator << (std::wostream & _Wostream, const line_mode & _Val) switch(_Val.get_type()) { case line_mode::Continuous: - _Wostream << "continuous"; + _Wostream << L"continuous"; break; case line_mode::SkipWhiteSpace: - _Wostream << "skip-white-space"; + _Wostream << L"skip-white-space"; break; default: break; diff --git a/OdfFile/DataTypes/linestyle.cpp b/OdfFile/DataTypes/linestyle.cpp index fb473b8b599..e428bd3a589 100644 --- a/OdfFile/DataTypes/linestyle.cpp +++ b/OdfFile/DataTypes/linestyle.cpp @@ -41,28 +41,28 @@ std::wostream & operator << (std::wostream & _Wostream, const line_style & _Val) switch(_Val.get_type()) { case line_style::None: - _Wostream << "none"; + _Wostream << L"none"; break; case line_style::Solid: - _Wostream << "solid"; + _Wostream << L"solid"; break; case line_style::Dotted: - _Wostream << "dotted"; + _Wostream << L"dotted"; break; case line_style::Dash: - _Wostream << "dash"; + _Wostream << L"dash"; break; case line_style::LongDash: - _Wostream << "long-dash"; + _Wostream << L"long-dash"; break; case line_style::DotDash: - _Wostream << "dot-dash"; + _Wostream << L"dot-dash"; break; case line_style::DotDotDash: - _Wostream << "dot-dot-dash"; + _Wostream << L"dot-dot-dash"; break; case line_style::Wave: - _Wostream << "wave"; + _Wostream << L"wave"; break; default: break; diff --git a/OdfFile/DataTypes/linestyle.h b/OdfFile/DataTypes/linestyle.h index e31c3244095..205c0ccde8e 100644 --- a/OdfFile/DataTypes/linestyle.h +++ b/OdfFile/DataTypes/linestyle.h @@ -41,7 +41,7 @@ namespace cpdoccore { namespace odf_types { class line_style { public: - enum style + enum style { None, Solid, @@ -50,7 +50,8 @@ class line_style LongDash, DotDash, DotDotDash, - Wave + Wave, + Double }; line_style() diff --git a/OdfFile/DataTypes/linetype.cpp b/OdfFile/DataTypes/linetype.cpp index 548cdbe43c3..7383c43ea58 100644 --- a/OdfFile/DataTypes/linetype.cpp +++ b/OdfFile/DataTypes/linetype.cpp @@ -41,13 +41,13 @@ std::wostream & operator << (std::wostream & _Wostream, const line_type & _Val) switch(_Val.get_type()) { case line_type::None: - _Wostream << "none"; + _Wostream << L"none"; break; case line_type::Single: - _Wostream << "single"; + _Wostream << L"single"; break; case line_type::Double: - _Wostream << "double"; + _Wostream << L"double"; break; default: break; diff --git a/OdfFile/DataTypes/linewidth.cpp b/OdfFile/DataTypes/linewidth.cpp index c5f5242239c..9c556e84b15 100644 --- a/OdfFile/DataTypes/linewidth.cpp +++ b/OdfFile/DataTypes/linewidth.cpp @@ -41,25 +41,25 @@ std::wostream & operator << (std::wostream & _Wostream, const line_width & _Val) switch(_Val.get_type()) { case line_width::Auto: - _Wostream << "auto"; + _Wostream << L"auto"; break; case line_width::Normal: - _Wostream << "normal"; + _Wostream << L"normal"; break; case line_width::Bold: - _Wostream << "bold"; + _Wostream << L"bold"; break; case line_width::Thin: - _Wostream << "thin"; + _Wostream << L"thin"; break; case line_width::Dash: - _Wostream << "dash"; + _Wostream << L"dash"; break; case line_width::Medium: - _Wostream << "medium"; + _Wostream << L"medium"; break; case line_width::Thick: - _Wostream << "thick"; + _Wostream << L"thick"; break; case line_width::PositiveInteger: _Wostream << _Val.get_positive_integer(); diff --git a/OdfFile/DataTypes/officevaluetype.cpp b/OdfFile/DataTypes/officevaluetype.cpp index ebfccd69661..a4d3b084a19 100644 --- a/OdfFile/DataTypes/officevaluetype.cpp +++ b/OdfFile/DataTypes/officevaluetype.cpp @@ -34,9 +34,12 @@ #include "officevaluetype.h" #include "../Common/errors.h" +#include +#include + namespace cpdoccore { namespace odf_types { -std::wostream & operator << (std::wostream & _Wostream, const office_value_type & _Val) +std::wostream& operator << (std::wostream& _Wostream, const office_value_type& _Val) { switch(_Val.get_type()) { @@ -46,27 +49,29 @@ std::wostream & operator << (std::wostream & _Wostream, const office_value_type case office_value_type::Float: case office_value_type::Scientific: case office_value_type::Fraction: - _Wostream << "float"; - break; + { + _Wostream << L"float"; + } break; case office_value_type::Currency: - _Wostream << "currency"; + _Wostream << L"currency"; break; case office_value_type::Percentage: - _Wostream << "percentage"; + _Wostream << L"percentage"; break; case office_value_type::Date: case office_value_type::DateTime: - _Wostream << "date"; + _Wostream << L"date"; break; case office_value_type::Time: - _Wostream << "time"; + _Wostream << L"time"; break; case office_value_type::Boolean: - _Wostream << "boolean"; + _Wostream << L"boolean"; break; case office_value_type::String: - _Wostream << "string"; - break; + { + _Wostream << L"string"; + }break; default: break; } diff --git a/OdfFile/DataTypes/presentationclass.cpp b/OdfFile/DataTypes/presentationclass.cpp index b1054b8dafd..36943976c0e 100644 --- a/OdfFile/DataTypes/presentationclass.cpp +++ b/OdfFile/DataTypes/presentationclass.cpp @@ -57,6 +57,7 @@ std::wostream & operator << (std::wostream & _Wostream, const presentation_class case presentation_class::handout: _Wostream << L"handout"; break; case presentation_class::outline: _Wostream << L"outline"; break; case presentation_class::text: _Wostream << L"text"; break; + case presentation_class::body: _Wostream << L"body"; break; } return _Wostream; } @@ -81,6 +82,7 @@ presentation_class presentation_class::parse(const std::wstring & Str) else if (tmp == L"footer") return presentation_class( footer ); else if (tmp == L"date-time") return presentation_class( date_time ); else if (tmp == L"page-number") return presentation_class( page_number ); + else if (tmp == L"body") return presentation_class( body ); else { return presentation_class( page ); @@ -95,14 +97,14 @@ std::wstring presentation_class::get_type_ms() case title: res = L"title"; break; - // case subtitle: - //res = L"subTitle"; + case subtitle: + res = L"body"; break; case graphic: res = L"body"; break; case object: - res = L"obj"; + res = L"body"; break; case chart: res = L"chart"; @@ -125,15 +127,15 @@ std::wstring presentation_class::get_type_ms() case page_number: res = L"sldNum"; break; - case subtitle: case notes: case handout: - case outline: + case outline: + case body: case text: res = L"body"; break; case page: - res = L"sldImg"; + res = L"pic"; break; } return res; diff --git a/OdfFile/DataTypes/presentationclass.h b/OdfFile/DataTypes/presentationclass.h index d91c067d63d..7521aa695e4 100644 --- a/OdfFile/DataTypes/presentationclass.h +++ b/OdfFile/DataTypes/presentationclass.h @@ -56,8 +56,9 @@ class presentation_class header, footer, date_time, - page_number + page_number, + body }; presentation_class() {} diff --git a/OdfFile/DataTypes/presentationnodetype.cpp b/OdfFile/DataTypes/presentationnodetype.cpp new file mode 100644 index 00000000000..86121e64996 --- /dev/null +++ b/OdfFile/DataTypes/presentationnodetype.cpp @@ -0,0 +1,69 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ + +#include "presentationnodetype.h" + +#include +#include + +namespace cpdoccore { namespace odf_types { + + std::wostream& operator << (std::wostream& _Wostream, const presentation_node_type& _Val) + { + switch (_Val.get_type()) + { + case presentation_node_type::default_ : _Wostream << L"default"; break; + case presentation_node_type::after_previous : _Wostream << L"after-previous"; break; + case presentation_node_type::interactive_sequence : _Wostream << L"interactive-sequence"; break; + case presentation_node_type::main_sequence : _Wostream << L"main-sequence"; break; + case presentation_node_type::on_click : _Wostream << L"on-click"; break; + case presentation_node_type::timing_root : _Wostream << L"timing-root"; break; + case presentation_node_type::with_previous : _Wostream << L"with-previous"; break; + } + return _Wostream; + } + + presentation_node_type presentation_node_type::parse(const std::wstring& Str) + { + if (Str == L"default") return presentation_node_type(default_); + else if (Str == L"after-previous") return presentation_node_type(after_previous); + else if (Str == L"interactive-sequence") return presentation_node_type(interactive_sequence); + else if (Str == L"main-sequence") return presentation_node_type(main_sequence); + else if (Str == L"on-click") return presentation_node_type(on_click); + else if (Str == L"timing-root") return presentation_node_type(timing_root); + else if (Str == L"with-previous") return presentation_node_type(with_previous); + + return presentation_node_type::none; + } + +} // namespace odf_types +} // namespace cpdoccore diff --git a/OdfFile/DataTypes/presentationnodetype.h b/OdfFile/DataTypes/presentationnodetype.h new file mode 100644 index 00000000000..c69fef87a57 --- /dev/null +++ b/OdfFile/DataTypes/presentationnodetype.h @@ -0,0 +1,74 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#pragma once + +#include +#include "odfattributes.h" + +namespace cpdoccore { namespace odf_types { + +class presentation_node_type +{ +public: + enum type + { + none, + default_, + after_previous, + interactive_sequence, + main_sequence, + on_click, + timing_root, + with_previous + }; + + presentation_node_type() {} + + presentation_node_type(type _Type) : type_(_Type) + {} + + type get_type() const + { + return type_; + }; + + static presentation_node_type parse(const std::wstring& Str); + +private: + type type_; +}; +std::wostream& operator << (std::wostream& _Wostream, const presentation_node_type& _Val); + + +} // namespace odf_types + APPLY_PARSE_XML_ATTRIBUTES(odf_types::presentation_node_type); +} // namespace cpdoccore diff --git a/OdfFile/DataTypes/presentationvisibility.cpp b/OdfFile/DataTypes/presentationvisibility.cpp new file mode 100644 index 00000000000..a20d8d71b68 --- /dev/null +++ b/OdfFile/DataTypes/presentationvisibility.cpp @@ -0,0 +1,72 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ + +#include "presentationvisibility.h" + +#include + +namespace cpdoccore { namespace odf_types { + + std::wostream& operator<<(std::wostream& _Wostream, const presentation_visibility& _Val) + { + switch (_Val.get_type()) + { + case presentation_visibility::hidden: + { + _Wostream << L"hidden"; + } break; + case presentation_visibility::visible: + { + _Wostream << L"visible"; + } break; + default: + break; + } + + return _Wostream; + } + + presentation_visibility presentation_visibility::parse(const std::wstring& Str) + { + std::wstring tmp = Str; + boost::algorithm::to_lower(tmp); + + if (tmp == L"hidden") + return presentation_visibility(hidden); + else if (tmp == L"visible") + return presentation_visibility(visible); + + return presentation_visibility(visible); + } + +} // namespace odf_types +} // namespace cpdoccore \ No newline at end of file diff --git a/OdfFile/DataTypes/presentationvisibility.h b/OdfFile/DataTypes/presentationvisibility.h new file mode 100644 index 00000000000..f90e77eb04b --- /dev/null +++ b/OdfFile/DataTypes/presentationvisibility.h @@ -0,0 +1,69 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#pragma once + +#include +#include "odfattributes.h" + +namespace cpdoccore { namespace odf_types { + +class presentation_visibility +{ +public: + enum type + { + hidden, + visible + }; + + presentation_visibility() {} + presentation_visibility(type _Type) : type_(_Type) + {} + + type get_type() const + { + return type_; + } + + static presentation_visibility parse(const std::wstring & Str); + +private: + type type_; +}; + +std::wostream& operator << (std::wostream& _Wostream, const presentation_visibility& _Val); + +} // namespace odf_types + +APPLY_PARSE_XML_ATTRIBUTES(odf_types::presentation_visibility); + +} // namespace cpdoccore \ No newline at end of file diff --git a/OdfFile/DataTypes/presetclass.cpp b/OdfFile/DataTypes/presetclass.cpp new file mode 100644 index 00000000000..5bc4b46acb5 --- /dev/null +++ b/OdfFile/DataTypes/presetclass.cpp @@ -0,0 +1,75 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ + +#include "presetclass.h" + +#include +#include + +namespace cpdoccore { namespace odf_types { + + preset_class preset_class::parse(const std::wstring& Str) + { + std::wstring tmp = Str; + boost::algorithm::to_lower(tmp); + + if (tmp == L"custom") return preset_class(custom); + else if (tmp == L"entrance") return preset_class(entrance); + else if (tmp == L"exit") return preset_class(exit); + else if (tmp == L"emphasis") return preset_class(emphasis); + else if (tmp == L"motion-path") return preset_class(motion_path); + else if (tmp == L"ole-action") return preset_class(ole_action); + else if (tmp == L"media-call") return preset_class(media_call); + else + { + return preset_class(custom); + } + } + + std::wostream& operator << (std::wostream& _Wostream, const preset_class& _Val) + { + switch (_Val.get_type()) + { + case preset_class::custom: _Wostream << L"custom"; break; + case preset_class::entrance: _Wostream << L"entrance"; break; + case preset_class::exit: _Wostream << L"exit"; break; + case preset_class::emphasis: _Wostream << L"emphasis"; break; + case preset_class::motion_path: _Wostream << L"motion-path"; break; + case preset_class::ole_action: _Wostream << L"ole-action"; break; + case preset_class::media_call: _Wostream << L"media-call"; break; + } + + return _Wostream; + } + +} +} \ No newline at end of file diff --git a/X2tConverter/build/Mac/OdfOfficeConverter/OdfOfficeConverter/OdfOfficeConverter.h b/OdfFile/DataTypes/presetclass.h similarity index 71% rename from X2tConverter/build/Mac/OdfOfficeConverter/OdfOfficeConverter/OdfOfficeConverter.h rename to OdfFile/DataTypes/presetclass.h index 54cb43e48ca..073ec396b86 100644 --- a/X2tConverter/build/Mac/OdfOfficeConverter/OdfOfficeConverter/OdfOfficeConverter.h +++ b/OdfFile/DataTypes/presetclass.h @@ -29,18 +29,47 @@ * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode * */ +#pragma once -#import +#include +#include "odfattributes.h" -@interface OdfOfficeConverter : NSObject +namespace cpdoccore { namespace odf_types { -- (int)odf2oox:(NSString*)nsFrom nsTo:(NSString*)nsTo nsTemp:(NSString*)nsTemp nsFontPath:(NSString*)nsFontPath; +class preset_class +{ +public: + enum type + { + custom, + entrance, + exit, + emphasis, + motion_path, + ole_action, + media_call + }; -- (int)odt2docx:(NSString*)nsFrom nsTo:(NSString*)nsTo nsTemp:(NSString*)nsTemp nsFontPath:(NSString*)nsFontPath; -- (int)ods2xlsx:(NSString*)nsFrom nsTo:(NSString*)nsTo nsTemp:(NSString*)nsTemp nsFontPath:(NSString*)nsFontPath; -- (int)odp2pptx:(NSString*)nsFrom nsTo:(NSString*)nsTo nsTemp:(NSString*)nsTemp nsFontPath:(NSString*)nsFontPath; + preset_class() {} -@property (strong) NSString* password; -@property (assign) BOOL isNoBase64; + preset_class(type _Type) : type_(_Type) + {} -@end + type get_type() const + { + return type_; + } + + static preset_class parse(const std::wstring& Str); + +private: + type type_; +}; + +std::wostream& operator << (std::wostream& _Wostream, const preset_class& _Val); + +} // namespace odf_types + +APPLY_PARSE_XML_ATTRIBUTES(odf_types::preset_class); + +} // namespace cpdoccore \ No newline at end of file diff --git a/OdfFile/DataTypes/presetid.cpp b/OdfFile/DataTypes/presetid.cpp new file mode 100644 index 00000000000..fd60310e249 --- /dev/null +++ b/OdfFile/DataTypes/presetid.cpp @@ -0,0 +1,484 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ + +#include "presetid.h" + +#include + +#include + +namespace cpdoccore { namespace odf_types { + + preset_id preset_id::parse(const std::wstring& Str) + { + std::wstring tmp = Str; + boost::algorithm::to_lower(tmp); + + if (boost::algorithm::starts_with(tmp, L"ooo-entrance-")) + { + std::wstring preset = tmp.substr(std::wstring(L"ooo-entrance-").size()); + + if (preset == L"appear") return preset_id::type::ooo_entrance_appear; + else if (preset == L"fly-in") return preset_id::type::ooo_entrance_fly_in; + else if (preset == L"venetian-blinds") return preset_id::type::ooo_entrance_venetian_blinds; + else if (preset == L"box") return preset_id::type::ooo_entrance_box; + else if (preset == L"checkerboard") return preset_id::type::ooo_entrance_checkerboard; + else if (preset == L"circle") return preset_id::type::ooo_entrance_circle; + else if (preset == L"fly-in-slow") return preset_id::type::ooo_entrance_fly_in_slow; + else if (preset == L"diamond") return preset_id::type::ooo_entrance_diamond; + else if (preset == L"dissolve-in") return preset_id::type::ooo_entrance_dissolve_in; + else if (preset == L"fade-in") return preset_id::type::ooo_entrance_fade_in; + else if (preset == L"flash-once") return preset_id::type::ooo_entrance_flash_once; + else if (preset == L"peek-in") return preset_id::type::ooo_entrance_peek_in; + else if (preset == L"plus") return preset_id::type::ooo_entrance_plus; + else if (preset == L"random-bars") return preset_id::type::ooo_entrance_random_bars; + else if (preset == L"spiral-in") return preset_id::type::ooo_entrance_spiral_in; + else if (preset == L"split") return preset_id::type::ooo_entrance_split; + else if (preset == L"stretchy") return preset_id::type::ooo_entrance_stretchy; + else if (preset == L"diagonal-squares") return preset_id::type::ooo_entrance_diagonal_squares; + else if (preset == L"swivel") return preset_id::type::ooo_entrance_swivel; + else if (preset == L"wedge") return preset_id::type::ooo_entrance_wedge; + else if (preset == L"wheel") return preset_id::type::ooo_entrance_wheel; + else if (preset == L"wipe") return preset_id::type::ooo_entrance_wipe; + else if (preset == L"zoom") return preset_id::type::ooo_entrance_zoom; + else if (preset == L"random") return preset_id::type::ooo_entrance_random; + else if (preset == L"boomerang") return preset_id::type::ooo_entrance_boomerang; + else if (preset == L"bounce") return preset_id::type::ooo_entrance_bounce; + else if (preset == L"colored-lettering") return preset_id::type::ooo_entrance_colored_lettering; + else if (preset == L"movie-credits") return preset_id::type::ooo_entrance_movie_credits; + else if (preset == L"ease-in") return preset_id::type::ooo_entrance_ease_in; + else if (preset == L"float") return preset_id::type::ooo_entrance_float; + else if (preset == L"turn-and-grow") return preset_id::type::ooo_entrance_turn_and_grow; + else if (preset == L"breaks") return preset_id::type::ooo_entrance_breaks; + else if (preset == L"pinwheel") return preset_id::type::ooo_entrance_pinwheel; + else if (preset == L"rise-up") return preset_id::type::ooo_entrance_rise_up; + else if (preset == L"falling-in") return preset_id::type::ooo_entrance_falling_in; + else if (preset == L"thread") return preset_id::type::ooo_entrance_thread; + else if (preset == L"unfold") return preset_id::type::ooo_entrance_unfold; + else if (preset == L"whip") return preset_id::type::ooo_entrance_whip; + else if (preset == L"ascend") return preset_id::type::ooo_entrance_ascend; + else if (preset == L"center-revolve") return preset_id::type::ooo_entrance_center_revolve; + else if (preset == L"fade-in-and-swivel") return preset_id::type::ooo_entrance_fade_in_and_swivel; + else if (preset == L"descend") return preset_id::type::ooo_entrance_descend; + else if (preset == L"sling") return preset_id::type::ooo_entrance_sling; + else if (preset == L"spin-in") return preset_id::type::ooo_entrance_spin_in; + else if (preset == L"compress") return preset_id::type::ooo_entrance_compress; + else if (preset == L"magnify") return preset_id::type::ooo_entrance_magnify; + else if (preset == L"curve-up") return preset_id::type::ooo_entrance_curve_up; + else if (preset == L"fade-in-and-zoom") return preset_id::type::ooo_entrance_fade_in_and_zoom; + else if (preset == L"glide") return preset_id::type::ooo_entrance_glide; + else if (preset == L"expand") return preset_id::type::ooo_entrance_expand; + else if (preset == L"flip") return preset_id::type::ooo_entrance_flip; + else if (preset == L"fold") return preset_id::type::ooo_entrance_fold; + } + else if (boost::algorithm::starts_with(tmp, L"ooo-emphasis-")) + { + std::wstring preset = tmp.substr(std::wstring(L"ooo-emphasis-").size()); + + if (preset == L"fill-color") return preset_id::type::ooo_emphasis_fill_color; + else if (preset == L"font") return preset_id::type::ooo_emphasis_font; + else if (preset == L"font-size") return preset_id::type::ooo_emphasis_font_size; + else if (preset == L"font-style") return preset_id::type::ooo_emphasis_font_style; + else if (preset == L"grow-and-shrink") return preset_id::type::ooo_emphasis_grow_and_shrink; + else if (preset == L"line-color") return preset_id::type::ooo_emphasis_line_color; + else if (preset == L"spin") return preset_id::type::ooo_emphasis_spin; + else if (preset == L"transparency") return preset_id::type::ooo_emphasis_transparency; + else if (preset == L"bold-flash") return preset_id::type::ooo_emphasis_bold_flash; + else if (preset == L"blast") return preset_id::type::ooo_emphasis_blast; + else if (preset == L"bold-reveal") return preset_id::type::ooo_emphasis_bold_reveal; + else if (preset == L"color-over-by-word") return preset_id::type::ooo_emphasis_color_over_by_word; + else if (preset == L"reveal-underline") return preset_id::type::ooo_emphasis_reveal_underline; + else if (preset == L"color-blend") return preset_id::type::ooo_emphasis_color_blend; + else if (preset == L"color-over-by-letter") return preset_id::type::ooo_emphasis_color_over_by_letter; + else if (preset == L"complementary-color") return preset_id::type::ooo_emphasis_complementary_color; + else if (preset == L"complementary-color-2") return preset_id::type::ooo_emphasis_complementary_color_2; + else if (preset == L"contrasting-color") return preset_id::type::ooo_emphasis_contrasting_color; + else if (preset == L"darken") return preset_id::type::ooo_emphasis_darken; + else if (preset == L"desaturate") return preset_id::type::ooo_emphasis_desaturate; + else if (preset == L"flash-bulb") return preset_id::type::ooo_emphasis_flash_bulb; + else if (preset == L"flicker") return preset_id::type::ooo_emphasis_flicker; + else if (preset == L"grow-with-color") return preset_id::type::ooo_emphasis_grow_with_color; + else if (preset == L"lighten") return preset_id::type::ooo_emphasis_lighten; + else if (preset == L"style-emphasis") return preset_id::type::ooo_emphasis_style_emphasis; + else if (preset == L"teeter") return preset_id::type::ooo_emphasis_teeter; + else if (preset == L"vertical-highlight") return preset_id::type::ooo_emphasis_vertical_highlight; + else if (preset == L"wave") return preset_id::type::ooo_emphasis_wave; + else if (preset == L"blink") return preset_id::type::ooo_emphasis_blink; + else if (preset == L"shimmer") return preset_id::type::ooo_emphasis_shimmer; + } + else if (boost::algorithm::starts_with(tmp, L"ooo-exit-")) + { + std::wstring preset = tmp.substr(std::wstring(L"ooo-exit-").size()); + + if (preset == L"disappear") return preset_id::type::ooo_exit_disappear; + else if (preset == L"fly-out") return preset_id::type::ooo_exit_fly_out; + else if (preset == L"venetian-blinds") return preset_id::type::ooo_exit_venetian_blinds; + else if (preset == L"box") return preset_id::type::ooo_exit_box; + else if (preset == L"checkerboard") return preset_id::type::ooo_exit_checkerboard; + else if (preset == L"circle") return preset_id::type::ooo_exit_circle; + else if (preset == L"crawl-out") return preset_id::type::ooo_exit_crawl_out; + else if (preset == L"diamond") return preset_id::type::ooo_exit_diamond; + else if (preset == L"dissolve") return preset_id::type::ooo_exit_dissolve; + else if (preset == L"fade-out") return preset_id::type::ooo_exit_fade_out; + else if (preset == L"flash-once") return preset_id::type::ooo_exit_flash_once; + else if (preset == L"peek-out") return preset_id::type::ooo_exit_peek_out; + else if (preset == L"plus") return preset_id::type::ooo_exit_plus; + else if (preset == L"random-bars") return preset_id::type::ooo_exit_random_bars; + else if (preset == L"spiral-out") return preset_id::type::ooo_exit_spiral_out; + else if (preset == L"split") return preset_id::type::ooo_exit_split; + else if (preset == L"collapse") return preset_id::type::ooo_exit_collapse; + else if (preset == L"diagonal-squares") return preset_id::type::ooo_exit_diagonal_squares; + else if (preset == L"swivel") return preset_id::type::ooo_exit_swivel; + else if (preset == L"wedge") return preset_id::type::ooo_exit_wedge; + else if (preset == L"wheel") return preset_id::type::ooo_exit_wheel; + else if (preset == L"wipe") return preset_id::type::ooo_exit_wipe; + else if (preset == L"zoom") return preset_id::type::ooo_exit_zoom; + else if (preset == L"random") return preset_id::type::ooo_exit_random; + else if (preset == L"boomerang") return preset_id::type::ooo_exit_boomerang; + else if (preset == L"bounce") return preset_id::type::ooo_exit_bounce; + else if (preset == L"colored-lettering") return preset_id::type::ooo_exit_colored_lettering; + else if (preset == L"movie-credits") return preset_id::type::ooo_exit_movie_credits; + else if (preset == L"ease-out") return preset_id::type::ooo_exit_ease_out; + else if (preset == L"float") return preset_id::type::ooo_exit_float; + else if (preset == L"turn-and-grow") return preset_id::type::ooo_exit_turn_and_grow; + else if (preset == L"breaks") return preset_id::type::ooo_exit_breaks; + else if (preset == L"pinwheel") return preset_id::type::ooo_exit_pinwheel; + else if (preset == L"sink-down") return preset_id::type::ooo_exit_sink_down; + else if (preset == L"swish") return preset_id::type::ooo_exit_swish; + else if (preset == L"thread") return preset_id::type::ooo_exit_thread; + else if (preset == L"unfold") return preset_id::type::ooo_exit_unfold; + else if (preset == L"whip") return preset_id::type::ooo_exit_whip; + else if (preset == L"descend") return preset_id::type::ooo_exit_descend; + else if (preset == L"center-revolve") return preset_id::type::ooo_exit_center_revolve; + else if (preset == L"fade-out-and-swivel") return preset_id::type::ooo_exit_fade_out_and_swivel; + else if (preset == L"ascend") return preset_id::type::ooo_exit_ascend; + else if (preset == L"sling") return preset_id::type::ooo_exit_sling; + else if (preset == L"fade-out-and-zoom") return preset_id::type::ooo_exit_fade_out_and_zoom; + else if (preset == L"contract") return preset_id::type::ooo_exit_contract; + else if (preset == L"spin-out") return preset_id::type::ooo_exit_spin_out; + else if (preset == L"stretchy") return preset_id::type::ooo_exit_stretchy; + else if (preset == L"magnify") return preset_id::type::ooo_exit_magnify; + else if (preset == L"curve-down") return preset_id::type::ooo_exit_curve_down; + else if (preset == L"glide") return preset_id::type::ooo_exit_glide; + else if (preset == L"flip") return preset_id::type::ooo_exit_flip; + else if (preset == L"fold") return preset_id::type::ooo_exit_fold; + } + else if (boost::algorithm::starts_with(tmp, L"ooo-motionpath-")) + { + std::wstring preset = tmp.substr(std::wstring(L"ooo-motionpath-").size()); + + if (preset == L"4-point-star") return preset_id::type::ooo_motionpath_4_point_star; + else if (preset == L"5-point-star") return preset_id::type::ooo_motionpath_5_point_star; + else if (preset == L"6-point-star") return preset_id::type::ooo_motionpath_6_point_star; + else if (preset == L"8-point-star") return preset_id::type::ooo_motionpath_8_point_star; + else if (preset == L"circle") return preset_id::type::ooo_motionpath_circle; + else if (preset == L"crescent-moon") return preset_id::type::ooo_motionpath_crescent_moon; + else if (preset == L"diamond") return preset_id::type::ooo_motionpath_diamond; + else if (preset == L"equal-triangle") return preset_id::type::ooo_motionpath_equal_triangle; + else if (preset == L"oval") return preset_id::type::ooo_motionpath_oval; + else if (preset == L"heart") return preset_id::type::ooo_motionpath_heart; + else if (preset == L"hexagon") return preset_id::type::ooo_motionpath_hexagon; + else if (preset == L"octagon") return preset_id::type::ooo_motionpath_octagon; + else if (preset == L"parallelogram") return preset_id::type::ooo_motionpath_parallelogram; + else if (preset == L"pentagon") return preset_id::type::ooo_motionpath_pentagon; + else if (preset == L"right-triangle") return preset_id::type::ooo_motionpath_right_triangle; + else if (preset == L"square") return preset_id::type::ooo_motionpath_square; + else if (preset == L"teardrop") return preset_id::type::ooo_motionpath_teardrop; + else if (preset == L"trapezoid") return preset_id::type::ooo_motionpath_trapezoid; + else if (preset == L"arc-down") return preset_id::type::ooo_motionpath_arc_down; + else if (preset == L"arc-left") return preset_id::type::ooo_motionpath_arc_left; + else if (preset == L"arc-right") return preset_id::type::ooo_motionpath_arc_right; + else if (preset == L"arc-up") return preset_id::type::ooo_motionpath_arc_up; + else if (preset == L"bounce-left") return preset_id::type::ooo_motionpath_bounce_left; + else if (preset == L"bounce-right") return preset_id::type::ooo_motionpath_bounce_right; + else if (preset == L"curvy-left") return preset_id::type::ooo_motionpath_curvy_left; + else if (preset == L"curvy-right") return preset_id::type::ooo_motionpath_curvy_right; + else if (preset == L"decaying-wave") return preset_id::type::ooo_motionpath_decaying_wave; + else if (preset == L"diagonal-down-right") return preset_id::type::ooo_motionpath_diagonal_down_right; + else if (preset == L"diagonal-up-right") return preset_id::type::ooo_motionpath_diagonal_up_right; + else if (preset == L"down") return preset_id::type::ooo_motionpath_down; + else if (preset == L"funnel") return preset_id::type::ooo_motionpath_funnel; + else if (preset == L"spring") return preset_id::type::ooo_motionpath_spring; + else if (preset == L"stairs-down") return preset_id::type::ooo_motionpath_stairs_down; + else if (preset == L"turn-down") return preset_id::type::ooo_motionpath_turn_down; + else if (preset == L"turn-down-right") return preset_id::type::ooo_motionpath_turn_down_right; + else if (preset == L"turn-up") return preset_id::type::ooo_motionpath_turn_up; + else if (preset == L"turn-up-right") return preset_id::type::ooo_motionpath_turn_up_right; + else if (preset == L"up") return preset_id::type::ooo_motionpath_up; + else if (preset == L"wave") return preset_id::type::ooo_motionpath_wave; + else if (preset == L"zigzag") return preset_id::type::ooo_motionpath_zigzag; + else if (preset == L"bean") return preset_id::type::ooo_motionpath_bean; + else if (preset == L"buzz-saw") return preset_id::type::ooo_motionpath_buzz_saw; + else if (preset == L"curved-square") return preset_id::type::ooo_motionpath_curved_square; + else if (preset == L"curved-x") return preset_id::type::ooo_motionpath_curved_x; + else if (preset == L"curvy-star") return preset_id::type::ooo_motionpath_curvy_star; + else if (preset == L"figure-8-four") return preset_id::type::ooo_motionpath_figure_8_four; + else if (preset == L"horizontal-figure-8") return preset_id::type::ooo_motionpath_horizontal_figure_8; + else if (preset == L"inverted-square") return preset_id::type::ooo_motionpath_inverted_square; + else if (preset == L"inverted-triangle") return preset_id::type::ooo_motionpath_inverted_triangle; + else if (preset == L"loop-de-loop") return preset_id::type::ooo_motionpath_loop_de_loop; + else if (preset == L"neutron") return preset_id::type::ooo_motionpath_neutron; + else if (preset == L"peanut") return preset_id::type::ooo_motionpath_peanut; + else if (preset == L"clover") return preset_id::type::ooo_motionpath_clover; + else if (preset == L"pointy-star") return preset_id::type::ooo_motionpath_pointy_star; + else if (preset == L"swoosh") return preset_id::type::ooo_motionpath_swoosh; + else if (preset == L"vertical-figure-8") return preset_id::type::ooo_motionpath_vertical_figure_8; + else if (preset == L"left") return preset_id::type::ooo_motionpath_left; + else if (preset == L"right") return preset_id::type::ooo_motionpath_right; + else if (preset == L"spiral-left") return preset_id::type::ooo_motionpath_spiral_left; + else if (preset == L"spiral-right") return preset_id::type::ooo_motionpath_spiral_right; + else if (preset == L"sine-wave") return preset_id::type::ooo_motionpath_sine_wave; + else if (preset == L"s-curve-1") return preset_id::type::ooo_motionpath_s_curve_1; + else if (preset == L"s-curve-2") return preset_id::type::ooo_motionpath_s_curve_2; + else if (preset == L"heartbeat") return preset_id::type::ooo_motionpath_heartbeat; + } + else if (tmp == L"libo-motionpath-curve") return preset_id::type::libo_motionpath_curve; + else if (tmp == L"libo-motionpath-polygon") return preset_id::type::libo_motionpath_polygon; + else if (tmp == L"libo-motionpath-freeform-line") return preset_id::type::libo_motionpath_freeform_line; + + + return preset_id::type::none; + } + + std::wostream& operator << (std::wostream& _Wostream, const preset_id& _Val) + { + switch (_Val.get_type()) + { + case preset_id::type::ooo_entrance_appear : _Wostream << L"ooo-entrance-appear" ; break; + case preset_id::type::ooo_entrance_fly_in : _Wostream << L"ooo-entrance-fly-in" ; break; + case preset_id::type::ooo_entrance_venetian_blinds : _Wostream << L"ooo-entrance-venetian-blinds" ; break; + case preset_id::type::ooo_entrance_box : _Wostream << L"ooo-entrance-box" ; break; + case preset_id::type::ooo_entrance_checkerboard : _Wostream << L"ooo-entrance-checkerboard" ; break; + case preset_id::type::ooo_entrance_circle : _Wostream << L"ooo-entrance-circle" ; break; + case preset_id::type::ooo_entrance_fly_in_slow : _Wostream << L"ooo-entrance-fly-in-slow" ; break; + case preset_id::type::ooo_entrance_diamond : _Wostream << L"ooo-entrance-diamond" ; break; + case preset_id::type::ooo_entrance_dissolve_in : _Wostream << L"ooo-entrance-dissolve-in" ; break; + case preset_id::type::ooo_entrance_fade_in : _Wostream << L"ooo-entrance-fade-in" ; break; + case preset_id::type::ooo_entrance_flash_once : _Wostream << L"ooo-entrance-flash-once" ; break; + case preset_id::type::ooo_entrance_peek_in : _Wostream << L"ooo-entrance-peek-in" ; break; + case preset_id::type::ooo_entrance_plus : _Wostream << L"ooo-entrance-plus" ; break; + case preset_id::type::ooo_entrance_random_bars : _Wostream << L"ooo-entrance-random-bars" ; break; + case preset_id::type::ooo_entrance_spiral_in : _Wostream << L"ooo-entrance-spiral-in" ; break; + case preset_id::type::ooo_entrance_split : _Wostream << L"ooo-entrance-split" ; break; + case preset_id::type::ooo_entrance_stretchy : _Wostream << L"ooo-entrance-stretchy" ; break; + case preset_id::type::ooo_entrance_diagonal_squares : _Wostream << L"ooo-entrance-diagonal-squares" ; break; + case preset_id::type::ooo_entrance_swivel : _Wostream << L"ooo-entrance-swivel" ; break; + case preset_id::type::ooo_entrance_wedge : _Wostream << L"ooo-entrance-wedge" ; break; + case preset_id::type::ooo_entrance_wheel : _Wostream << L"ooo-entrance-wheel" ; break; + case preset_id::type::ooo_entrance_wipe : _Wostream << L"ooo-entrance-wipe" ; break; + case preset_id::type::ooo_entrance_zoom : _Wostream << L"ooo-entrance-zoom" ; break; + case preset_id::type::ooo_entrance_random : _Wostream << L"ooo-entrance-random" ; break; + case preset_id::type::ooo_entrance_boomerang : _Wostream << L"ooo-entrance-boomerang" ; break; + case preset_id::type::ooo_entrance_bounce : _Wostream << L"ooo-entrance-bounce" ; break; + case preset_id::type::ooo_entrance_colored_lettering : _Wostream << L"ooo-entrance-colored-lettering" ; break; + case preset_id::type::ooo_entrance_movie_credits : _Wostream << L"ooo-entrance-movie-credits" ; break; + case preset_id::type::ooo_entrance_ease_in : _Wostream << L"ooo-entrance-ease-in" ; break; + case preset_id::type::ooo_entrance_float : _Wostream << L"ooo-entrance-float" ; break; + case preset_id::type::ooo_entrance_turn_and_grow : _Wostream << L"ooo-entrance-turn-and-grow" ; break; + case preset_id::type::ooo_entrance_breaks : _Wostream << L"ooo-entrance-breaks" ; break; + case preset_id::type::ooo_entrance_pinwheel : _Wostream << L"ooo-entrance-pinwheel" ; break; + case preset_id::type::ooo_entrance_rise_up : _Wostream << L"ooo-entrance-rise-up" ; break; + case preset_id::type::ooo_entrance_falling_in : _Wostream << L"ooo-entrance-falling-in" ; break; + case preset_id::type::ooo_entrance_thread : _Wostream << L"ooo-entrance-thread" ; break; + case preset_id::type::ooo_entrance_unfold : _Wostream << L"ooo-entrance-unfold" ; break; + case preset_id::type::ooo_entrance_whip : _Wostream << L"ooo-entrance-whip" ; break; + case preset_id::type::ooo_entrance_ascend : _Wostream << L"ooo-entrance-ascend" ; break; + case preset_id::type::ooo_entrance_center_revolve : _Wostream << L"ooo-entrance-center-revolve" ; break; + case preset_id::type::ooo_entrance_fade_in_and_swivel : _Wostream << L"ooo-entrance-fade-in-and-swivel" ; break; + case preset_id::type::ooo_entrance_descend : _Wostream << L"ooo-entrance-descend" ; break; + case preset_id::type::ooo_entrance_sling : _Wostream << L"ooo-entrance-sling" ; break; + case preset_id::type::ooo_entrance_spin_in : _Wostream << L"ooo-entrance-spin-in" ; break; + case preset_id::type::ooo_entrance_compress : _Wostream << L"ooo-entrance-compress" ; break; + case preset_id::type::ooo_entrance_magnify : _Wostream << L"ooo-entrance-magnify" ; break; + case preset_id::type::ooo_entrance_curve_up : _Wostream << L"ooo-entrance-curve-up" ; break; + case preset_id::type::ooo_entrance_fade_in_and_zoom : _Wostream << L"ooo-entrance-fade-in-and-zoom" ; break; + case preset_id::type::ooo_entrance_glide : _Wostream << L"ooo-entrance-glide" ; break; + case preset_id::type::ooo_entrance_expand : _Wostream << L"ooo-entrance-expand" ; break; + case preset_id::type::ooo_entrance_flip : _Wostream << L"ooo-entrance-flip" ; break; + case preset_id::type::ooo_entrance_fold : _Wostream << L"ooo-entrance-fold" ; break; + case preset_id::type::ooo_emphasis_fill_color : _Wostream << L"ooo-emphasis-fill-color" ; break; + case preset_id::type::ooo_emphasis_font : _Wostream << L"ooo-emphasis-font" ; break; + case preset_id::type::ooo_emphasis_font_color : _Wostream << L"ooo-emphasis-font-color" ; break; + case preset_id::type::ooo_emphasis_font_size : _Wostream << L"ooo-emphasis-font-size" ; break; + case preset_id::type::ooo_emphasis_font_style : _Wostream << L"ooo-emphasis-font-style" ; break; + case preset_id::type::ooo_emphasis_grow_and_shrink : _Wostream << L"ooo-emphasis-grow-and-shrink" ; break; + case preset_id::type::ooo_emphasis_line_color : _Wostream << L"ooo-emphasis-line-color" ; break; + case preset_id::type::ooo_emphasis_spin : _Wostream << L"ooo-emphasis-spin" ; break; + case preset_id::type::ooo_emphasis_transparency : _Wostream << L"ooo-emphasis-transparency" ; break; + case preset_id::type::ooo_emphasis_bold_flash : _Wostream << L"ooo-emphasis-bold-flash" ; break; + case preset_id::type::ooo_emphasis_blast : _Wostream << L"ooo-emphasis-blast" ; break; + case preset_id::type::ooo_emphasis_bold_reveal : _Wostream << L"ooo-emphasis-bold-reveal" ; break; + case preset_id::type::ooo_emphasis_color_over_by_word : _Wostream << L"ooo-emphasis-color-over-by-word" ; break; + case preset_id::type::ooo_emphasis_reveal_underline : _Wostream << L"ooo-emphasis-reveal-underline" ; break; + case preset_id::type::ooo_emphasis_color_blend : _Wostream << L"ooo-emphasis-color-blend" ; break; + case preset_id::type::ooo_emphasis_color_over_by_letter : _Wostream << L"ooo-emphasis-color-over-by-letter" ; break; + case preset_id::type::ooo_emphasis_complementary_color : _Wostream << L"ooo-emphasis-complementary-color" ; break; + case preset_id::type::ooo_emphasis_complementary_color_2: _Wostream << L"ooo-emphasis-complementary-color-2"; break; + case preset_id::type::ooo_emphasis_contrasting_color : _Wostream << L"ooo-emphasis-contrasting-color" ; break; + case preset_id::type::ooo_emphasis_darken : _Wostream << L"ooo-emphasis-darken" ; break; + case preset_id::type::ooo_emphasis_desaturate : _Wostream << L"ooo-emphasis-desaturate" ; break; + case preset_id::type::ooo_emphasis_flash_bulb : _Wostream << L"ooo-emphasis-flash-bulb" ; break; + case preset_id::type::ooo_emphasis_flicker : _Wostream << L"ooo-emphasis-flicker" ; break; + case preset_id::type::ooo_emphasis_grow_with_color : _Wostream << L"ooo-emphasis-grow-with-color" ; break; + case preset_id::type::ooo_emphasis_lighten : _Wostream << L"ooo-emphasis-lighten" ; break; + case preset_id::type::ooo_emphasis_style_emphasis : _Wostream << L"ooo-emphasis-style-emphasis" ; break; + case preset_id::type::ooo_emphasis_teeter : _Wostream << L"ooo-emphasis-teeter" ; break; + case preset_id::type::ooo_emphasis_vertical_highlight : _Wostream << L"ooo-emphasis-vertical-highlight" ; break; + case preset_id::type::ooo_emphasis_wave : _Wostream << L"ooo-emphasis-wave" ; break; + case preset_id::type::ooo_emphasis_blink : _Wostream << L"ooo-emphasis-blink" ; break; + case preset_id::type::ooo_emphasis_shimmer : _Wostream << L"ooo-emphasis-shimmer" ; break; + case preset_id::type::ooo_exit_disappear : _Wostream << L"ooo-exit-disappear" ; break; + case preset_id::type::ooo_exit_fly_out : _Wostream << L"ooo-exit-fly-out" ; break; + case preset_id::type::ooo_exit_venetian_blinds : _Wostream << L"ooo-exit-venetian-blinds" ; break; + case preset_id::type::ooo_exit_box : _Wostream << L"ooo-exit-box" ; break; + case preset_id::type::ooo_exit_checkerboard : _Wostream << L"ooo-exit-checkerboard" ; break; + case preset_id::type::ooo_exit_circle : _Wostream << L"ooo-exit-circle" ; break; + case preset_id::type::ooo_exit_crawl_out : _Wostream << L"ooo-exit-crawl-out" ; break; + case preset_id::type::ooo_exit_diamond : _Wostream << L"ooo-exit-diamond" ; break; + case preset_id::type::ooo_exit_dissolve : _Wostream << L"ooo-exit-dissolve" ; break; + case preset_id::type::ooo_exit_fade_out : _Wostream << L"ooo-exit-fade-out" ; break; + case preset_id::type::ooo_exit_flash_once : _Wostream << L"ooo-exit-flash-once" ; break; + case preset_id::type::ooo_exit_peek_out : _Wostream << L"ooo-exit-peek-out" ; break; + case preset_id::type::ooo_exit_plus : _Wostream << L"ooo-exit-plus" ; break; + case preset_id::type::ooo_exit_random_bars : _Wostream << L"ooo-exit-random-bars" ; break; + case preset_id::type::ooo_exit_spiral_out : _Wostream << L"ooo-exit-spiral-out" ; break; + case preset_id::type::ooo_exit_split : _Wostream << L"ooo-exit-split" ; break; + case preset_id::type::ooo_exit_collapse : _Wostream << L"ooo-exit-collapse" ; break; + case preset_id::type::ooo_exit_diagonal_squares : _Wostream << L"ooo-exit-diagonal-squares" ; break; + case preset_id::type::ooo_exit_swivel : _Wostream << L"ooo-exit-swivel" ; break; + case preset_id::type::ooo_exit_wedge : _Wostream << L"ooo-exit-wedge" ; break; + case preset_id::type::ooo_exit_wheel : _Wostream << L"ooo-exit-wheel" ; break; + case preset_id::type::ooo_exit_wipe : _Wostream << L"ooo-exit-wipe" ; break; + case preset_id::type::ooo_exit_zoom : _Wostream << L"ooo-exit-zoom" ; break; + case preset_id::type::ooo_exit_random : _Wostream << L"ooo-exit-random" ; break; + case preset_id::type::ooo_exit_boomerang : _Wostream << L"ooo-exit-boomerang" ; break; + case preset_id::type::ooo_exit_bounce : _Wostream << L"ooo-exit-bounce" ; break; + case preset_id::type::ooo_exit_colored_lettering : _Wostream << L"ooo-exit-colored-lettering" ; break; + case preset_id::type::ooo_exit_movie_credits : _Wostream << L"ooo-exit-movie-credits" ; break; + case preset_id::type::ooo_exit_ease_out : _Wostream << L"ooo-exit-ease-out" ; break; + case preset_id::type::ooo_exit_float : _Wostream << L"ooo-exit-float" ; break; + case preset_id::type::ooo_exit_turn_and_grow : _Wostream << L"ooo-exit-turn-and-grow" ; break; + case preset_id::type::ooo_exit_breaks : _Wostream << L"ooo-exit-breaks" ; break; + case preset_id::type::ooo_exit_pinwheel : _Wostream << L"ooo-exit-pinwheel" ; break; + case preset_id::type::ooo_exit_sink_down : _Wostream << L"ooo-exit-sink-down" ; break; + case preset_id::type::ooo_exit_swish : _Wostream << L"ooo-exit-swish" ; break; + case preset_id::type::ooo_exit_thread : _Wostream << L"ooo-exit-thread" ; break; + case preset_id::type::ooo_exit_unfold : _Wostream << L"ooo-exit-unfold" ; break; + case preset_id::type::ooo_exit_whip : _Wostream << L"ooo-exit-whip" ; break; + case preset_id::type::ooo_exit_descend : _Wostream << L"ooo-exit-descend" ; break; + case preset_id::type::ooo_exit_center_revolve : _Wostream << L"ooo-exit-center-revolve" ; break; + case preset_id::type::ooo_exit_fade_out_and_swivel : _Wostream << L"ooo-exit-fade-out-and-swivel" ; break; + case preset_id::type::ooo_exit_ascend : _Wostream << L"ooo-exit-ascend" ; break; + case preset_id::type::ooo_exit_sling : _Wostream << L"ooo-exit-sling" ; break; + case preset_id::type::ooo_exit_fade_out_and_zoom : _Wostream << L"ooo-exit-fade-out-and-zoom" ; break; + case preset_id::type::ooo_exit_contract : _Wostream << L"ooo-exit-contract" ; break; + case preset_id::type::ooo_exit_spin_out : _Wostream << L"ooo-exit-spin-out" ; break; + case preset_id::type::ooo_exit_stretchy : _Wostream << L"ooo-exit-stretchy" ; break; + case preset_id::type::ooo_exit_magnify : _Wostream << L"ooo-exit-magnify" ; break; + case preset_id::type::ooo_exit_curve_down : _Wostream << L"ooo-exit-curve-down" ; break; + case preset_id::type::ooo_exit_glide : _Wostream << L"ooo-exit-glide" ; break; + case preset_id::type::ooo_exit_flip : _Wostream << L"ooo-exit-flip" ; break; + case preset_id::type::ooo_exit_fold : _Wostream << L"ooo-exit-fold" ; break; + case preset_id::type::ooo_motionpath_4_point_star : _Wostream << L"ooo-motionpath-4-point-star" ; break; + case preset_id::type::ooo_motionpath_5_point_star : _Wostream << L"ooo-motionpath-5-point-star" ; break; + case preset_id::type::ooo_motionpath_6_point_star : _Wostream << L"ooo-motionpath-6-point-star" ; break; + case preset_id::type::ooo_motionpath_8_point_star : _Wostream << L"ooo-motionpath-8-point-star" ; break; + case preset_id::type::ooo_motionpath_circle : _Wostream << L"ooo-motionpath-circle" ; break; + case preset_id::type::ooo_motionpath_crescent_moon : _Wostream << L"ooo-motionpath-crescent-moon" ; break; + case preset_id::type::ooo_motionpath_diamond : _Wostream << L"ooo-motionpath-diamond" ; break; + case preset_id::type::ooo_motionpath_equal_triangle : _Wostream << L"ooo-motionpath-equal-triangle" ; break; + case preset_id::type::ooo_motionpath_oval : _Wostream << L"ooo-motionpath-oval" ; break; + case preset_id::type::ooo_motionpath_heart : _Wostream << L"ooo-motionpath-heart" ; break; + case preset_id::type::ooo_motionpath_hexagon : _Wostream << L"ooo-motionpath-hexagon" ; break; + case preset_id::type::ooo_motionpath_octagon : _Wostream << L"ooo-motionpath-octagon" ; break; + case preset_id::type::ooo_motionpath_parallelogram : _Wostream << L"ooo-motionpath-parallelogram" ; break; + case preset_id::type::ooo_motionpath_pentagon : _Wostream << L"ooo-motionpath-pentagon" ; break; + case preset_id::type::ooo_motionpath_right_triangle : _Wostream << L"ooo-motionpath-right-triangle" ; break; + case preset_id::type::ooo_motionpath_square : _Wostream << L"ooo-motionpath-square" ; break; + case preset_id::type::ooo_motionpath_teardrop : _Wostream << L"ooo-motionpath-teardrop" ; break; + case preset_id::type::ooo_motionpath_trapezoid : _Wostream << L"ooo-motionpath-trapezoid" ; break; + case preset_id::type::ooo_motionpath_arc_down : _Wostream << L"ooo-motionpath-arc-down" ; break; + case preset_id::type::ooo_motionpath_arc_left : _Wostream << L"ooo-motionpath-arc-left" ; break; + case preset_id::type::ooo_motionpath_arc_right : _Wostream << L"ooo-motionpath-arc-right" ; break; + case preset_id::type::ooo_motionpath_arc_up : _Wostream << L"ooo-motionpath-arc-up" ; break; + case preset_id::type::ooo_motionpath_bounce_left : _Wostream << L"ooo-motionpath-bounce-left" ; break; + case preset_id::type::ooo_motionpath_bounce_right : _Wostream << L"ooo-motionpath-bounce-right" ; break; + case preset_id::type::ooo_motionpath_curvy_left : _Wostream << L"ooo-motionpath-curvy-left" ; break; + case preset_id::type::ooo_motionpath_curvy_right : _Wostream << L"ooo-motionpath-curvy-right" ; break; + case preset_id::type::ooo_motionpath_decaying_wave : _Wostream << L"ooo-motionpath-decaying-wave" ; break; + case preset_id::type::ooo_motionpath_diagonal_down_right: _Wostream << L"ooo-motionpath-diagonal-down-right"; break; + case preset_id::type::ooo_motionpath_diagonal_up_right : _Wostream << L"ooo-motionpath-diagonal-up-right" ; break; + case preset_id::type::ooo_motionpath_down : _Wostream << L"ooo-motionpath-down" ; break; + case preset_id::type::ooo_motionpath_funnel : _Wostream << L"ooo-motionpath-funnel" ; break; + case preset_id::type::ooo_motionpath_spring : _Wostream << L"ooo-motionpath-spring" ; break; + case preset_id::type::ooo_motionpath_stairs_down : _Wostream << L"ooo-motionpath-stairs-down" ; break; + case preset_id::type::ooo_motionpath_turn_down : _Wostream << L"ooo-motionpath-turn-down" ; break; + case preset_id::type::ooo_motionpath_turn_down_right : _Wostream << L"ooo-motionpath-turn-down-right" ; break; + case preset_id::type::ooo_motionpath_turn_up : _Wostream << L"ooo-motionpath-turn-up" ; break; + case preset_id::type::ooo_motionpath_turn_up_right : _Wostream << L"ooo-motionpath-turn-up-right" ; break; + case preset_id::type::ooo_motionpath_up : _Wostream << L"ooo-motionpath-up" ; break; + case preset_id::type::ooo_motionpath_wave : _Wostream << L"ooo-motionpath-wave" ; break; + case preset_id::type::ooo_motionpath_zigzag : _Wostream << L"ooo-motionpath-zigzag" ; break; + case preset_id::type::ooo_motionpath_bean : _Wostream << L"ooo-motionpath-bean" ; break; + case preset_id::type::ooo_motionpath_buzz_saw : _Wostream << L"ooo-motionpath-buzz-saw" ; break; + case preset_id::type::ooo_motionpath_curved_square : _Wostream << L"ooo-motionpath-curved-square" ; break; + case preset_id::type::ooo_motionpath_curved_x : _Wostream << L"ooo-motionpath-curved-x" ; break; + case preset_id::type::ooo_motionpath_curvy_star : _Wostream << L"ooo-motionpath-curvy-star" ; break; + case preset_id::type::ooo_motionpath_figure_8_four : _Wostream << L"ooo-motionpath-figure-8-four" ; break; + case preset_id::type::ooo_motionpath_horizontal_figure_8: _Wostream << L"ooo-motionpath-horizontal-figure-8"; break; + case preset_id::type::ooo_motionpath_inverted_square : _Wostream << L"ooo-motionpath-inverted-square" ; break; + case preset_id::type::ooo_motionpath_inverted_triangle : _Wostream << L"ooo-motionpath-inverted-triangle" ; break; + case preset_id::type::ooo_motionpath_loop_de_loop : _Wostream << L"ooo-motionpath-loop-de-loop" ; break; + case preset_id::type::ooo_motionpath_neutron : _Wostream << L"ooo-motionpath-neutron" ; break; + case preset_id::type::ooo_motionpath_peanut : _Wostream << L"ooo-motionpath-peanut" ; break; + case preset_id::type::ooo_motionpath_clover : _Wostream << L"ooo-motionpath-clover" ; break; + case preset_id::type::ooo_motionpath_pointy_star : _Wostream << L"ooo-motionpath-pointy-star" ; break; + case preset_id::type::ooo_motionpath_swoosh : _Wostream << L"ooo-motionpath-swoosh" ; break; + case preset_id::type::ooo_motionpath_vertical_figure_8 : _Wostream << L"ooo-motionpath-vertical-figure-8" ; break; + case preset_id::type::ooo_motionpath_left : _Wostream << L"ooo-motionpath-left" ; break; + case preset_id::type::ooo_motionpath_right : _Wostream << L"ooo-motionpath-right" ; break; + case preset_id::type::ooo_motionpath_spiral_left : _Wostream << L"ooo-motionpath-spiral-left" ; break; + case preset_id::type::ooo_motionpath_spiral_right : _Wostream << L"ooo-motionpath-spiral-right" ; break; + case preset_id::type::ooo_motionpath_sine_wave : _Wostream << L"ooo-motionpath-sine-wave" ; break; + case preset_id::type::ooo_motionpath_s_curve_1 : _Wostream << L"ooo-motionpath-s-curve-1" ; break; + case preset_id::type::ooo_motionpath_s_curve_2 : _Wostream << L"ooo-motionpath-s-curve-2" ; break; + case preset_id::type::ooo_motionpath_heartbeat : _Wostream << L"ooo-motionpath-heartbeat" ; break; + case preset_id::type::libo_motionpath_curve : _Wostream << L"libo-motionpath-curve" ; break; + case preset_id::type::libo_motionpath_polygon : _Wostream << L"libo-motionpath-polygon" ; break; + case preset_id::type::libo_motionpath_freeform_line : _Wostream << L"libo-motionpath-freeform-line" ; break; + } + + return _Wostream; + } + +} // namespace odf_types +} // namespace cpdoccore \ No newline at end of file diff --git a/OdfFile/DataTypes/presetid.h b/OdfFile/DataTypes/presetid.h new file mode 100644 index 00000000000..b557a6680e6 --- /dev/null +++ b/OdfFile/DataTypes/presetid.h @@ -0,0 +1,276 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#pragma once + +#include +#include "odfattributes.h" + +namespace cpdoccore { namespace odf_types { + +class preset_id +{ +public: + enum type + { + none, + + ooo_entrance_appear, + ooo_entrance_fly_in, + ooo_entrance_venetian_blinds, + ooo_entrance_box, + ooo_entrance_checkerboard, + ooo_entrance_circle, + ooo_entrance_fly_in_slow, + ooo_entrance_diamond, + ooo_entrance_dissolve_in, + ooo_entrance_fade_in, + ooo_entrance_flash_once, + ooo_entrance_peek_in, + ooo_entrance_plus, + ooo_entrance_random_bars, + ooo_entrance_spiral_in, + ooo_entrance_split, + ooo_entrance_stretchy, + ooo_entrance_diagonal_squares, + ooo_entrance_swivel, + ooo_entrance_wedge, + ooo_entrance_wheel, + ooo_entrance_wipe, + ooo_entrance_zoom, + ooo_entrance_random, + ooo_entrance_boomerang, + ooo_entrance_bounce, + ooo_entrance_colored_lettering, + ooo_entrance_movie_credits, + ooo_entrance_ease_in, + ooo_entrance_float, + ooo_entrance_turn_and_grow, + ooo_entrance_breaks, + ooo_entrance_pinwheel, + ooo_entrance_rise_up, + ooo_entrance_falling_in, + ooo_entrance_thread, + ooo_entrance_unfold, + ooo_entrance_whip, + ooo_entrance_ascend, + ooo_entrance_center_revolve, + ooo_entrance_fade_in_and_swivel, + ooo_entrance_descend, + ooo_entrance_sling, + ooo_entrance_spin_in, + ooo_entrance_compress, + ooo_entrance_magnify, + ooo_entrance_curve_up, + ooo_entrance_fade_in_and_zoom, + ooo_entrance_glide, + ooo_entrance_expand, + ooo_entrance_flip, + ooo_entrance_fold, + + ooo_emphasis_fill_color, + ooo_emphasis_font, + ooo_emphasis_font_color, + ooo_emphasis_font_size, + ooo_emphasis_font_style, + ooo_emphasis_grow_and_shrink, + ooo_emphasis_line_color, + ooo_emphasis_spin, + ooo_emphasis_transparency, + ooo_emphasis_bold_flash, + ooo_emphasis_blast, + ooo_emphasis_bold_reveal, + ooo_emphasis_color_over_by_word, + ooo_emphasis_reveal_underline, + ooo_emphasis_color_blend, + ooo_emphasis_color_over_by_letter, + ooo_emphasis_complementary_color, + ooo_emphasis_complementary_color_2, + ooo_emphasis_contrasting_color, + ooo_emphasis_darken, + ooo_emphasis_desaturate, + ooo_emphasis_flash_bulb, + ooo_emphasis_flicker, + ooo_emphasis_grow_with_color, + ooo_emphasis_lighten, + ooo_emphasis_style_emphasis, + ooo_emphasis_teeter, + ooo_emphasis_vertical_highlight, + ooo_emphasis_wave, + ooo_emphasis_blink, + ooo_emphasis_shimmer, + + ooo_exit_disappear, + ooo_exit_fly_out, + ooo_exit_venetian_blinds, + ooo_exit_box, + ooo_exit_checkerboard, + ooo_exit_circle, + ooo_exit_crawl_out, + ooo_exit_diamond, + ooo_exit_dissolve, + ooo_exit_fade_out, + ooo_exit_flash_once, + ooo_exit_peek_out, + ooo_exit_plus, + ooo_exit_random_bars, + ooo_exit_spiral_out, + ooo_exit_split, + ooo_exit_collapse, + ooo_exit_diagonal_squares, + ooo_exit_swivel, + ooo_exit_wedge, + ooo_exit_wheel, + ooo_exit_wipe, + ooo_exit_zoom, + ooo_exit_random, + ooo_exit_boomerang, + ooo_exit_bounce, + ooo_exit_colored_lettering, + ooo_exit_movie_credits, + ooo_exit_ease_out, + ooo_exit_float, + ooo_exit_turn_and_grow, + ooo_exit_breaks, + ooo_exit_pinwheel, + ooo_exit_sink_down, + ooo_exit_swish, + ooo_exit_thread, + ooo_exit_unfold, + ooo_exit_whip, + ooo_exit_descend, + ooo_exit_center_revolve, + ooo_exit_fade_out_and_swivel, + ooo_exit_ascend, + ooo_exit_sling, + ooo_exit_fade_out_and_zoom, + ooo_exit_contract, + ooo_exit_spin_out, + ooo_exit_stretchy, + ooo_exit_magnify, + ooo_exit_curve_down, + ooo_exit_glide, + ooo_exit_flip, + ooo_exit_fold, + + ooo_motionpath_4_point_star, + ooo_motionpath_5_point_star, + ooo_motionpath_6_point_star, + ooo_motionpath_8_point_star, + ooo_motionpath_circle, + ooo_motionpath_crescent_moon, + ooo_motionpath_diamond, + ooo_motionpath_equal_triangle, + ooo_motionpath_oval, + ooo_motionpath_heart, + ooo_motionpath_hexagon, + ooo_motionpath_octagon, + ooo_motionpath_parallelogram, + ooo_motionpath_pentagon, + ooo_motionpath_right_triangle, + ooo_motionpath_square, + ooo_motionpath_teardrop, + ooo_motionpath_trapezoid, + ooo_motionpath_arc_down, + ooo_motionpath_arc_left, + ooo_motionpath_arc_right, + ooo_motionpath_arc_up, + ooo_motionpath_bounce_left, + ooo_motionpath_bounce_right, + ooo_motionpath_curvy_left, + ooo_motionpath_curvy_right, + ooo_motionpath_decaying_wave, + ooo_motionpath_diagonal_down_right, + ooo_motionpath_diagonal_up_right, + ooo_motionpath_down, + ooo_motionpath_funnel, + ooo_motionpath_spring, + ooo_motionpath_stairs_down, + ooo_motionpath_turn_down, + ooo_motionpath_turn_down_right, + ooo_motionpath_turn_up, + ooo_motionpath_turn_up_right, + ooo_motionpath_up, + ooo_motionpath_wave, + ooo_motionpath_zigzag, + ooo_motionpath_bean, + ooo_motionpath_buzz_saw, + ooo_motionpath_curved_square, + ooo_motionpath_curved_x, + ooo_motionpath_curvy_star, + ooo_motionpath_figure_8_four, + ooo_motionpath_horizontal_figure_8, + ooo_motionpath_inverted_square, + ooo_motionpath_inverted_triangle, + ooo_motionpath_loop_de_loop, + ooo_motionpath_neutron, + ooo_motionpath_peanut, + ooo_motionpath_clover, + ooo_motionpath_pointy_star, + ooo_motionpath_swoosh, + ooo_motionpath_vertical_figure_8, + ooo_motionpath_left, + ooo_motionpath_right, + ooo_motionpath_spiral_left, + ooo_motionpath_spiral_right, + ooo_motionpath_sine_wave, + ooo_motionpath_s_curve_1, + ooo_motionpath_s_curve_2, + ooo_motionpath_heartbeat, + + libo_motionpath_curve, + libo_motionpath_polygon, + libo_motionpath_freeform_line + }; + + preset_id() {} + + preset_id(type _Type) : type_(_Type) + {} + + type get_type() const + { + return type_; + }; + + static preset_id parse(const std::wstring& Str); + +private: + type type_; + +}; +std::wostream& operator << (std::wostream& _Wostream, const preset_id& _Val); + +} // namespace odf_types + +APPLY_PARSE_XML_ATTRIBUTES(odf_types::preset_id); + +} // namespace cpdoccore diff --git a/OdfFile/DataTypes/referenceformat.cpp b/OdfFile/DataTypes/referenceformat.cpp new file mode 100644 index 00000000000..c5795d8b19c --- /dev/null +++ b/OdfFile/DataTypes/referenceformat.cpp @@ -0,0 +1,104 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ + +#include "referenceformat.h" +#include +#include + +namespace cpdoccore { +namespace odf_types { +std::wostream & operator << (std::wostream & _Wostream, const reference_format & _Val) +{ + switch(_Val.get_type()) + { + case reference_format::chapter: + _Wostream << L"chapter"; + break; + case reference_format::direction: + _Wostream << L"direction"; + break; + case reference_format::caption: + _Wostream << L"caption"; + break; + case reference_format::category_and_value: + _Wostream << L"category-and-value"; + break; + case reference_format::value: + _Wostream << L"value"; + break; + case reference_format::number: + _Wostream << L"number"; + break; + case reference_format::number_all_superior: + _Wostream << L"number-all-superior"; + break; + case reference_format::number_no_superior: + _Wostream << L"number-no-superior"; + break; + default: + case reference_format::text: + _Wostream << L"text"; + break; + } + return _Wostream; +} + +reference_format reference_format::parse(const std::wstring & Str) +{ + std::wstring tmp = Str; + boost::algorithm::to_lower(tmp); + + if (tmp == L"chapter") + return reference_format(chapter); + else if (tmp == L"direction") + return reference_format(direction); + else if (tmp == L"text") + return reference_format(text); + else if (tmp == L"caption") + return reference_format(caption); + else if (tmp == L"category-and-value") + return reference_format(category_and_value); + else if (tmp == L"value") + return reference_format(value); + else if (tmp == L"number") + return reference_format(number); + else if (tmp == L"number-all-superior") + return reference_format(number_all_superior); + else if (tmp == L"number-no-superior") + return reference_format(number_no_superior); + else + { + return reference_format(text); + } +} +} +} diff --git a/OdfFile/DataTypes/referenceformat.h b/OdfFile/DataTypes/referenceformat.h new file mode 100644 index 00000000000..54e679f516b --- /dev/null +++ b/OdfFile/DataTypes/referenceformat.h @@ -0,0 +1,76 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#pragma once + +#include +#include +#include "odfattributes.h" + + +namespace cpdoccore { +namespace odf_types { + +class reference_format +{ +public: + enum type + { + chapter, + direction, + text, + caption, + category_and_value, + value, + number, + number_all_superior, + number_no_superior + }; + + reference_format() {} + reference_format(type _Type) : type_(_Type) + {} + + type get_type() const + { + return type_; + }; + static reference_format parse(const std::wstring & Str); + +private: + type type_; + +}; +std::wostream & operator << (std::wostream & _Wostream, const reference_format& _Val); +} +APPLY_PARSE_XML_ATTRIBUTES(odf_types::reference_format); + +} diff --git a/OdfFile/DataTypes/smil_additive.cpp b/OdfFile/DataTypes/smil_additive.cpp new file mode 100644 index 00000000000..5f23143b77c --- /dev/null +++ b/OdfFile/DataTypes/smil_additive.cpp @@ -0,0 +1,64 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ + +#include "smil_additive.h" + +#include +#include + +namespace cpdoccore { + namespace odf_types { + + std::wostream& operator << (std::wostream& _Wostream, const smil_additive& _Val) + { + switch (_Val.get_type()) + { + case smil_additive::replace: _Wostream << L"replace"; break; + case smil_additive::sum: _Wostream << L"sum"; break; + } + return _Wostream; + } + + smil_additive smil_additive::parse(const std::wstring& Str) + { + std::wstring tmp = Str; + boost::algorithm::to_lower(tmp); + + if (tmp == L"replace") return smil_additive(replace); + else if (tmp == L"sum") return smil_additive(sum); + else + { + return smil_additive(replace); + } + } + } +} diff --git a/X2tConverter/build/Mac/OfficeOdfConverter/OfficeOdfConverter/OfficeOdfConverter.h b/OdfFile/DataTypes/smil_additive.h similarity index 72% rename from X2tConverter/build/Mac/OfficeOdfConverter/OfficeOdfConverter/OfficeOdfConverter.h rename to OdfFile/DataTypes/smil_additive.h index 3242e7e50e4..269f67de2dc 100644 --- a/X2tConverter/build/Mac/OfficeOdfConverter/OfficeOdfConverter/OfficeOdfConverter.h +++ b/OdfFile/DataTypes/smil_additive.h @@ -29,16 +29,43 @@ * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode * */ +#pragma once -#import +#include +#include "odfattributes.h" -@interface OfficeOdfConverter : NSObject +namespace cpdoccore { namespace odf_types { -- (int)docx2odt:(NSString*)nsFrom nsTo:(NSString*)nsTo nsTemp:(NSString*)nsTemp nsFontPath:(NSString*)nsFontPath isTemplate:(bool)isTemplate; -- (int)xlsx2ods:(NSString*)nsFrom nsTo:(NSString*)nsTo nsTemp:(NSString*)nsTemp nsFontPath:(NSString*)nsFontPath isTemplate:(bool)isTemplate; -- (int)pptx2odp:(NSString*)nsFrom nsTo:(NSString*)nsTo nsTemp:(NSString*)nsTemp nsFontPath:(NSString*)nsFontPath isTemplate:(bool)isTemplate; +class smil_additive +{ +public: + enum type + { + replace, + sum + }; -@property (strong) NSString* password; -@property (assign) BOOL isNoBase64; + smil_additive() {} -@end + smil_additive(type _Type) : type_(_Type) + {} + + type get_type() const + { + return type_; + }; + + static smil_additive parse(const std::wstring& Str); + +private: + type type_; + +}; +std::wostream& operator << (std::wostream& _Wostream, const smil_additive& _Val); + + +} + +APPLY_PARSE_XML_ATTRIBUTES(odf_types::smil_additive); + +} diff --git a/OdfFile/DataTypes/smil_attributename.cpp b/OdfFile/DataTypes/smil_attributename.cpp new file mode 100644 index 00000000000..bf819b228e2 --- /dev/null +++ b/OdfFile/DataTypes/smil_attributename.cpp @@ -0,0 +1,110 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ + +#include "smil_attributename.h" + +#include +#include + +namespace cpdoccore { namespace odf_types { + + std::wostream& operator << (std::wostream& _Wostream, const smil_attribute_name& _Val) + { + switch (_Val.get_type()) + { + case smil_attribute_name::charColor : _Wostream << L"char-color" ; break; + case smil_attribute_name::charFontName : _Wostream << L"char-font-name"; break; + case smil_attribute_name::charHeight : _Wostream << L"char-height" ; break; + case smil_attribute_name::charPosture : _Wostream << L"char-posture" ; break; + case smil_attribute_name::charUnderline : _Wostream << L"char-underline"; break; + case smil_attribute_name::charWeight : _Wostream << L"char-weight" ; break; + case smil_attribute_name::color : _Wostream << L"color" ; break; + case smil_attribute_name::fill : _Wostream << L"fill" ; break; + case smil_attribute_name::fillColor : _Wostream << L"fill-color" ; break; + case smil_attribute_name::fillStyle : _Wostream << L"fill-style" ; break; + case smil_attribute_name::fillOn : _Wostream << L"FillOn" ; break; + case smil_attribute_name::height : _Wostream << L"height" ; break; + case smil_attribute_name::lineColor : _Wostream << L"lineColor" ; break; + case smil_attribute_name::lineStyle : _Wostream << L"lineStyle" ; break; + case smil_attribute_name::opacity : _Wostream << L"opacity" ; break; + case smil_attribute_name::stroke : _Wostream << L"stroke" ; break; + case smil_attribute_name::strokeColor : _Wostream << L"stroke-color" ; break; + case smil_attribute_name::rotate : _Wostream << L"rotate" ; break; + case smil_attribute_name::skewX : _Wostream << L"skewX" ; break; + case smil_attribute_name::skewY : _Wostream << L"skewY" ; break; + case smil_attribute_name::transform : _Wostream << L"transform" ; break; + case smil_attribute_name::visibility : _Wostream << L"visibility" ; break; + case smil_attribute_name::width : _Wostream << L"width" ; break; + case smil_attribute_name::x : _Wostream << L"x" ; break; + case smil_attribute_name::y : _Wostream << L"y" ; break; + case smil_attribute_name::dim : _Wostream << L"dim" ; break; + } + return _Wostream; + } + + smil_attribute_name smil_attribute_name::parse(const std::wstring& Str) + { + std::wstring tmp = boost::algorithm::to_lower_copy(Str); + boost::algorithm::erase_all(tmp, L"-"); + + if (tmp == L"charcolor") return smil_attribute_name(charColor); + else if (tmp == L"charfontname") return smil_attribute_name(charFontName); + else if (tmp == L"charheight") return smil_attribute_name(charHeight); + else if (tmp == L"charposture") return smil_attribute_name(charPosture); + else if (tmp == L"charunderline") return smil_attribute_name(charUnderline); + else if (tmp == L"charweight") return smil_attribute_name(charWeight); + else if (tmp == L"color") return smil_attribute_name(color); + else if (tmp == L"fill") return smil_attribute_name(fill); + else if (tmp == L"fillcolor") return smil_attribute_name(fillColor); + else if (tmp == L"fillstyle") return smil_attribute_name(fillStyle); + else if (tmp == L"fillon") return smil_attribute_name(fillOn); + else if (tmp == L"height") return smil_attribute_name(height); + else if (tmp == L"linecolor") return smil_attribute_name(lineColor); + else if (tmp == L"linestyle") return smil_attribute_name(lineStyle); + else if (tmp == L"opacity") return smil_attribute_name(opacity); + else if (tmp == L"stroke") return smil_attribute_name(stroke); + else if (tmp == L"strokecolor") return smil_attribute_name(strokeColor); + else if (tmp == L"rotate") return smil_attribute_name(rotate); + else if (tmp == L"skewx") return smil_attribute_name(skewX); + else if (tmp == L"skewx") return smil_attribute_name(skewY); + else if (tmp == L"transform") return smil_attribute_name(transform); + else if (tmp == L"visibility") return smil_attribute_name(visibility); + else if (tmp == L"width") return smil_attribute_name(width); + else if (tmp == L"x") return smil_attribute_name(x); + else if (tmp == L"y") return smil_attribute_name(y); + else if (tmp == L"dim") return smil_attribute_name(dim); + + return smil_attribute_name(none); + } + +} +} diff --git a/OdfFile/DataTypes/smil_attributename.h b/OdfFile/DataTypes/smil_attributename.h new file mode 100644 index 00000000000..268320c0e90 --- /dev/null +++ b/OdfFile/DataTypes/smil_attributename.h @@ -0,0 +1,95 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#pragma once + +#include +#include +#include "odfattributes.h" + +namespace cpdoccore { namespace odf_types { + +class smil_attribute_name +{ +public: + enum type + { + none, + + charColor, + charFontName, + charHeight, + charPosture, + charUnderline, + charWeight, + color, + fill, + fillColor, + fillStyle, + fillOn, + height, + lineColor, + lineStyle, + opacity, + rotate, + stroke, + strokeColor, + skewX, + skewY, + transform, + visibility, + width, + x, + y, + dim, + }; + + smil_attribute_name() {} + + smil_attribute_name(type _Type) : type_(_Type) + {} + + type get_type() const + { + return type_; + }; + + static smil_attribute_name parse(const std::wstring& Str); + +private: + type type_; +}; +std::wostream& operator << (std::wostream& _Wostream, const smil_attribute_name& _Val); + + +} // namespace odf_types + APPLY_PARSE_XML_ATTRIBUTES(odf_types::smil_attribute_name); +} // namespace cpdoccore diff --git a/OdfFile/DataTypes/smil_fill.cpp b/OdfFile/DataTypes/smil_fill.cpp new file mode 100644 index 00000000000..e97f576af85 --- /dev/null +++ b/OdfFile/DataTypes/smil_fill.cpp @@ -0,0 +1,69 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ + +#include "smil_fill.h" + +#include + +#include + +namespace cpdoccore { namespace odf_types { + + smil_fill smil_fill::parse(const std::wstring& Str) + { + if (Str == L"remove") return smil_fill::type::_remove; + else if (Str == L"freeze") return smil_fill::type::_freeze; + else if (Str == L"hold") return smil_fill::type::_hold; + else if (Str == L"transition") return smil_fill::type::_transition; + else if (Str == L"auto") return smil_fill::type::_auto; + else if (Str == L"default") return smil_fill::type::_default; + + return smil_fill::type::none; + } + + std::wostream& operator << (std::wostream& _Wostream, const smil_fill& _Val) + { + switch (_Val.get_type()) + { + case smil_fill::type::_remove : _Wostream << L"remove" ; break; + case smil_fill::type::_freeze : _Wostream << L"freeze" ; break; + case smil_fill::type::_hold : _Wostream << L"hold" ; break; + case smil_fill::type::_transition : _Wostream << L"transition"; break; + case smil_fill::type::_auto : _Wostream << L"auto" ; break; + case smil_fill::type::_default : _Wostream << L"default" ; break; + } + + return _Wostream; + } + +} // namespace odf_types +} // namespace cpdoccore \ No newline at end of file diff --git a/OdfFile/DataTypes/smil_fill.h b/OdfFile/DataTypes/smil_fill.h new file mode 100644 index 00000000000..c192f4f93fc --- /dev/null +++ b/OdfFile/DataTypes/smil_fill.h @@ -0,0 +1,77 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#pragma once + +#include +#include "odfattributes.h" + +namespace cpdoccore { + namespace odf_types { + + class smil_fill + { + public: + enum type + { + none, + + _remove, + _freeze, + _hold, + _transition, + _auto, + _default + }; + + smil_fill() {} + + smil_fill(type _Type) : type_(_Type) + {} + + type get_type() const + { + return type_; + }; + + static smil_fill parse(const std::wstring& Str); + + private: + type type_; + + }; + std::wostream& operator << (std::wostream& _Wostream, const smil_fill& _Val); + + } // namespace odf_types + + APPLY_PARSE_XML_ATTRIBUTES(odf_types::smil_fill); + +} // namespace cpdoccore diff --git a/OdfFile/DataTypes/smil_keytimes.cpp b/OdfFile/DataTypes/smil_keytimes.cpp new file mode 100644 index 00000000000..c9a43ee14d1 --- /dev/null +++ b/OdfFile/DataTypes/smil_keytimes.cpp @@ -0,0 +1,81 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#pragma once + +#include "smil_keytimes.h" + +#include +#include + +namespace cpdoccore { namespace odf_types { + + std::wostream& operator << (std::wostream& _Wostream, const smil_key_times& _Val) + { + const std::vector& values = _Val.get_values(); + + for (size_t i = 0; i < values.size(); i++) + { + if (i != 0) + _Wostream << L";"; + _Wostream << values[i]; + } + + return _Wostream; + } + + smil_key_times smil_key_times::parse(const std::wstring& Str) + { + std::vector values; + std::vector valuesStr; + + boost::split(valuesStr, Str, boost::is_any_of(";")); + + for (size_t i = 0; i < valuesStr.size(); i++) + { + try + { + float val = boost::lexical_cast(valuesStr[i]); + values.push_back(val); + } + catch (const boost::bad_lexical_cast& e) + { + continue; + } + } + + return smil_key_times(values); + } + +} // namespace odf_types +} // namesapce cpdoccore + + diff --git a/OdfFile/DataTypes/smil_keytimes.h b/OdfFile/DataTypes/smil_keytimes.h new file mode 100644 index 00000000000..646bcb90f04 --- /dev/null +++ b/OdfFile/DataTypes/smil_keytimes.h @@ -0,0 +1,66 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#pragma once + +#include +#include + +#include "odfattributes.h" + +namespace cpdoccore { namespace odf_types { + + class smil_key_times + { + public: + smil_key_times(const std::vector& values) : values_(values) + {} + public: + + const std::vector& get_values() const + { + return values_; + } + + static smil_key_times parse(const std::wstring& Str); + + private: + std::vector values_; + }; + + std::wostream& operator << (std::wostream& _Wostream, const smil_key_times& _Val); + +} // namespace odf_types + +APPLY_PARSE_XML_ATTRIBUTES(odf_types::smil_key_times); + +} // namespace cpdoccore + diff --git a/OdfFile/DataTypes/smil_transitiontype.cpp b/OdfFile/DataTypes/smil_transitiontype.cpp index df882fcb2bb..292e0436117 100644 --- a/OdfFile/DataTypes/smil_transitiontype.cpp +++ b/OdfFile/DataTypes/smil_transitiontype.cpp @@ -78,7 +78,7 @@ std::wostream & operator << (std::wostream & _Wostream, const smil_transition_ty case smil_transition_type::pushWipe : _Wostream << L"pushWipe" ; break; case smil_transition_type::slideWipe : _Wostream << L"slideWipe" ; break; case smil_transition_type::fade : _Wostream << L"fade" ; break; - case smil_transition_type::checkerBoardWipe : _Wostream << L"checkerboardWipe"; break; + case smil_transition_type::checkerBoardWipe : _Wostream << L"checkerBoardWipe"; break; case smil_transition_type::blindsWipe : _Wostream << L"blindsWipe" ; break; case smil_transition_type::dissolve : _Wostream << L"dissolve" ; break; case smil_transition_type::randomBarWipe : _Wostream << L"randomBarWipe" ; break; diff --git a/OdfFile/DataTypes/smil_values.cpp b/OdfFile/DataTypes/smil_values.cpp new file mode 100644 index 00000000000..5574a3711fa --- /dev/null +++ b/OdfFile/DataTypes/smil_values.cpp @@ -0,0 +1,64 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#pragma once + +#include "smil_values.h" + +#include + +namespace cpdoccore { namespace odf_types { + + std::wostream& operator << (std::wostream& _Wostream, const smil_values& _Val) + { + const std::vector& values = _Val.get_values(); + + for (size_t i = 0; i < values.size(); i++) + { + if (i != 0) + _Wostream << L";"; + _Wostream << values[i]; + } + + return _Wostream; + } + + smil_values smil_values::parse(const std::wstring& Str) + { + std::vector values; + boost::split(values, Str, boost::is_any_of(";")); + return smil_values(values); + } + +} // namespace odf_types +} // namesapce cpdoccore + + diff --git a/OdfFile/DataTypes/smil_values.h b/OdfFile/DataTypes/smil_values.h new file mode 100644 index 00000000000..089456d4750 --- /dev/null +++ b/OdfFile/DataTypes/smil_values.h @@ -0,0 +1,66 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#pragma once + +#include +#include + +#include "odfattributes.h" + +namespace cpdoccore { namespace odf_types { + + class smil_values + { + public: + smil_values(const std::vector& values) : values_(values) + {} + public: + + const std::vector& get_values() const + { + return values_; + } + + static smil_values parse(const std::wstring& Str); + + private: + std::vector values_; + }; + + std::wostream& operator << (std::wostream& _Wostream, const smil_values& _Val); + +} // namespace odf_types + +APPLY_PARSE_XML_ATTRIBUTES(odf_types::smil_values); + +} // namespace cpdoccore + diff --git a/OdfFile/DataTypes/svg_type.cpp b/OdfFile/DataTypes/svg_type.cpp new file mode 100644 index 00000000000..c2ba647c138 --- /dev/null +++ b/OdfFile/DataTypes/svg_type.cpp @@ -0,0 +1,70 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ + +#include "svg_type.h" + +#include +#include + +namespace cpdoccore { namespace odf_types { + + std::wostream& operator << (std::wostream& _Wostream, const svg_type& _Val) + { + switch (_Val.get_type()) + { + case svg_type::translate : _Wostream << L"translate" ; break; + case svg_type::scale : _Wostream << L"scale" ; break; + case svg_type::rotate : _Wostream << L"rotate" ; break; + case svg_type::skewX : _Wostream << L"skewX" ; break; + case svg_type::skewY : _Wostream << L"skewY" ; break; + } + return _Wostream; + } + + svg_type svg_type::parse(const std::wstring& Str) + { + std::wstring tmp = Str; + boost::algorithm::to_lower(tmp); + + if (tmp == L"translate") return svg_type(translate); + else if (tmp == L"scale") return svg_type(scale); + else if (tmp == L"rotate") return svg_type(rotate); + else if (tmp == L"skewX") return svg_type(skewX); + else if (tmp == L"skewY") return svg_type(skewY); + else + { + return svg_type(translate); + } + } + +} // namespace odf_types +} // namespace cpdoccore diff --git a/OdfFile/DataTypes/svg_type.h b/OdfFile/DataTypes/svg_type.h new file mode 100644 index 00000000000..83237827da2 --- /dev/null +++ b/OdfFile/DataTypes/svg_type.h @@ -0,0 +1,72 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#pragma once + +#include +#include "odfattributes.h" + +namespace cpdoccore { namespace odf_types { + +class svg_type +{ +public: + enum type + { + translate, + scale, + rotate, + skewX, + skewY + }; + + svg_type() {} + + svg_type(type _Type) : type_(_Type) + {} + + type get_type() const + { + return type_; + }; + + static svg_type parse(const std::wstring& Str); + +private: + type type_; + +}; +std::wostream& operator << (std::wostream& _Wostream, const svg_type& _Val); + + +} // namespace odf_types +APPLY_PARSE_XML_ATTRIBUTES(odf_types::svg_type); +} // namespace cpdoccore diff --git a/OdfFile/DataTypes/targetframename.cpp b/OdfFile/DataTypes/targetframename.cpp index d35c3e031fa..3743b9731a2 100644 --- a/OdfFile/DataTypes/targetframename.cpp +++ b/OdfFile/DataTypes/targetframename.cpp @@ -45,16 +45,16 @@ std::wostream & operator << (std::wostream & _Wostream, const target_frame_name { default: case target_frame_name::Self: - _Wostream << "_self"; + _Wostream << L"_self"; break; case target_frame_name::Blank: - _Wostream << "_blank"; + _Wostream << L"_blank"; break; case target_frame_name::Parent: - _Wostream << "_parent"; + _Wostream << L"_parent"; break; case target_frame_name::Top: - _Wostream << "_top"; + _Wostream << L"_top"; break; case target_frame_name::String: _Wostream << _Val.get_name(); diff --git a/OdfFile/DataTypes/xlink.cpp b/OdfFile/DataTypes/xlink.cpp index 5fedfc82237..153af9aaef5 100644 --- a/OdfFile/DataTypes/xlink.cpp +++ b/OdfFile/DataTypes/xlink.cpp @@ -55,11 +55,11 @@ std::wostream & operator << (std::wostream & _Wostream, const xlink_actuate & _A switch (_Actuate.get_type()) { case xlink_actuate::OnLoad: - _Wostream << "onLoad"; + _Wostream << L"onLoad"; break; default: case xlink_actuate::OnRequest: - _Wostream << "onRequest"; + _Wostream << L"onRequest"; break; } return _Wostream; diff --git a/OdfFile/Formulas/formulasconvert_odf.cpp b/OdfFile/Formulas/formulasconvert_odf.cpp index c9a4f56e0eb..12efd5f6dec 100644 --- a/OdfFile/Formulas/formulasconvert_odf.cpp +++ b/OdfFile/Formulas/formulasconvert_odf.cpp @@ -55,7 +55,7 @@ namespace formulasconvert { void split_distance_by(const std::wstring& expr, const std::wstring& by, std::vector& out); - void replace_cells_range(std::wstring& expr, bool withTableName, bool bAbsoluteAlways = false); + std::wstring replace_cells_range(std::wstring expr, bool withTableName, bool bAbsoluteAlways = false); bool check_formula(std::wstring& expr); void replace_semicolons(std::wstring& expr, bool del_quotes = false); void replace_tilda(std::wstring& expr); @@ -67,7 +67,7 @@ namespace formulasconvert { std::wstring convert_named_expr(const std::wstring& expr, bool withTableName, bool bAbsoluteAlways); static std::wstring replace_named_ref_formater(boost::wsmatch const & what); - static std::wstring replace_named_ref_formater1(boost::wsmatch const & what); + static std::wstring replace_named_ref_formater_2(boost::wsmatch const & what); //static std::wstring replace_cell_range_formater(boost::wsmatch const & what); void replace_named_formula(std::wstring & expr, bool w = true); @@ -79,7 +79,7 @@ namespace formulasconvert { static bool convert_with_absolute; static bool convert_with_TableName; static std::wstring table_name_; - + static std::vector> mapReplacements; //------------------------------------------------------------------------------------------------------------- static std::wstring replace_apersand_formater(boost::wsmatch const & what) { @@ -146,75 +146,29 @@ namespace formulasconvert { static void replace_tmp_back(std::wstring &expr) { - XmlUtils::replace_all( expr, L"ТОСHKA", L"."); - XmlUtils::replace_all( expr, L"VOSKL", L"!"); - - XmlUtils::replace_all( expr, L"SCOBCAIN", L"("); - XmlUtils::replace_all( expr, L"SCOBCAOUT", L")"); - - //XmlUtils::replace_all( expr, L"KVADRATIN", L"["); - //XmlUtils::replace_all( expr, L"KVADRATOUT", L"]"); - - XmlUtils::replace_all( expr, L"PROBEL", L" "); - //XmlUtils::replace_all( expr, L"APOSTROF", L"'"); - //XmlUtils::replace_all( expr, L"KAVYCHKA", L"\""); - XmlUtils::replace_all(expr, L"APERSAND", L"&"); + for (auto key : mapReplacements.back()) + { + XmlUtils::replace_all(expr, key.first, key.second); + } } static void replace_tmp(std::wstring &expr) { - // XmlUtils::replace_all( expr, L".", L"ТОСHKA"); - // XmlUtils::replace_all( expr, L"!", L"VOSKL"); - - // XmlUtils::replace_all( expr, L"(", L"SCOBCAIN"); - // XmlUtils::replace_all( expr, L")", L"SCOBCAOUT"); - - // //XmlUtils::replace_all( expr, L"[", L"KVADRATIN"); - // //XmlUtils::replace_all( expr, L"]", L"KVADRATOUT"); - // - // XmlUtils::replace_all( expr, L" ", L"PROBEL"); - //// XmlUtils::replace_all( expr, L"'", L"APOSTROF"); - //// XmlUtils::replace_all( expr, L"\"", L"KAVYCHKA"); - - std::wstring result; - - size_t pos = 0, size = expr.length(); - - while(pos < size) + //std::random_device genSource; + //std::uniform_int_distribution<> generator(0, 23); + //for (int index = 0; index < 5; index++) + //{ + // key += wchar_t(L'a' + generator(genSource)); + //} + + std::wstring key = L"aaaaaaaaaaaaaaaaaaaaaaaa"; + for (unsigned i = 0; i < 23; ++i) { - switch(expr[pos]) - { - case '.': - { - result += L"ТОСHKA"; - }break; - case '!': - { - result += L"VOSKL"; - }break; - case '(': - { - result += L"SCOBCAIN"; - }break; - case ')': - { - result += L"SCOBCAOUT"; - }break; - case ' ': - { - result += L"PROBEL"; - }break; - case '&': - { - result += L"APERSAND"; - }break; - default: - { - result += expr[pos]; - }break; - } - pos++; + unsigned j = rand() % (i + 1); + key[i] = key[j]; + key[j] = wchar_t(L'a' + i); } - expr = result; + mapReplacements.back().insert(std::make_pair(key, expr)); + expr = key; } static std::wstring convert_scobci(boost::wsmatch const & what) { @@ -278,12 +232,16 @@ namespace formulasconvert { bool odf2oox_converter::Impl::convert_with_TableName = true; std::wstring odf2oox_converter::Impl::table_name_ = L""; bool odf2oox_converter::Impl::convert_with_absolute = false; - + std::vector> odf2oox_converter::Impl::mapReplacements; + std::unordered_map &odf2oox_converter::Impl::mapExternalLink_ = oox::xlsx_conversion_context::mapExternalLink_; bool odf2oox_converter::Impl::find_first_last_ref(std::wstring const & expr, std::wstring & table,std::wstring & ref_first,std::wstring & ref_last) { std::wstring workstr = expr; + + mapReplacements.emplace_back(); + workstr = boost::regex_replace( workstr, boost::wregex(L"('.*?')|(\".*?\")"), @@ -317,6 +275,7 @@ namespace formulasconvert { } replace_tmp_back( table ); + mapReplacements.pop_back(); return res; } @@ -391,6 +350,9 @@ namespace formulasconvert { replace_tmp_back(external); int id = -1;//add_external_link(external); + + if (external[0] == L'\'') external = external.substr(1, external.size() - 2); + std::unordered_map::iterator pFind = mapExternalLink_.find(external); if ( pFind == mapExternalLink_.end()) { @@ -405,6 +367,9 @@ namespace formulasconvert { { sheet1 = sheet1.substr(1, sheet1.length() - 2); } + replace_tmp_back(sheet1); + if (sheet1[0] == L'\'') sheet1 = sheet1.substr(1, sheet1.size() - 2); + sheet1 = L"'[" + std::to_wstring(id) + L"]" + sheet1 + L"'"; } else if (std::wstring::npos != sheet1.find(L" ")) @@ -440,19 +405,54 @@ namespace formulasconvert { return ref1 + (ref2.empty() ? L"" : (L":" + ref2) ); } } - std::wstring odf2oox_converter::Impl::replace_named_ref_formater1(boost::wsmatch const & what) + std::wstring odf2oox_converter::Impl::replace_named_ref_formater_2(boost::wsmatch const & what) { - boost::wregex complexRef(L"(?:\'([^\']*)\'#){0,1}\\${0,1}([^\\.]+?){0,1}\\.(\\${0,1}[\\w^0-9]+\\${0,1}\\d+)(?::\\.(\\${0,1}[\\w^0-9]+\\${0,1}\\d+)){0,1}"); -// 'external'# $ Sheet2 . A1 : ( $ Sheet2)? . B5 - std::wstring expr = what[1].str(); - const std::wstring res = boost::regex_replace( - expr, - complexRef, - &replace_named_ref_formater, - boost::match_default | boost::format_all); - expr = res; + const size_t sz = what.size(); + + //if (sz < 6) return what[0].str(); + + std::wstring c0 = what[0].str(); + std::wstring sheet1 = what[1].str(); + std::wstring ref1 = what[2].str(); + std::wstring ref2 = what[3].str(); + + XmlUtils::replace_all(sheet1, L"$", L""); + XmlUtils::replace_all(ref2, L":", L""); + + std::wstring result; + + if (std::wstring::npos != sheet1.find(L" ")) + { + if (sheet1[0] != L'\'') + { + sheet1 = L"'" + sheet1 + L"'"; + } + } + + table_name_ = sheet1; + + if (convert_with_absolute) + { + size_t col = 0, row = 0; + oox::getCellAddressInv(ref1, col, row); - return expr; + ref1 = oox::getCellAddress(col, row, true); + + if (false == ref2.empty()) + { + oox::getCellAddressInv(ref2, col, row); + ref2 = oox::getCellAddress(col, row, true); + } + } + + if (convert_with_TableName) + { + return (sheet1.empty() ? L"" : (sheet1 + L"!")) + ref1 + (ref2.empty() ? L"" : (L":" + ref2)); + } + else + { + return ref1 + (ref2.empty() ? L"" : (L":" + ref2)); + } } @@ -462,8 +462,10 @@ namespace formulasconvert { // [Sheet2.A1:B5] -> Sheet2!A1:B5 // [Sheet2.A1] -> Sheet2!A1 // [$'Sheet2 A'.$B2] -> 'Sheet2 A'!$B2 - void odf2oox_converter::Impl::replace_cells_range(std::wstring& expr, bool withTableName, bool bAbsoluteAlways) + std::wstring odf2oox_converter::Impl::replace_cells_range(std::wstring expr, bool withTableName, bool bAbsoluteAlways) { + if (expr.empty()) return L""; + XmlUtils::replace_all( expr, L"#REF !", L"#REF!"); XmlUtils::replace_all( expr, L"#REF!#REF!", L"#REF!"); XmlUtils::replace_all( expr, L"$#REF!$#REF!", L"#REF!"); @@ -472,18 +474,34 @@ namespace formulasconvert { convert_with_absolute = bAbsoluteAlways; //boost::wregex complexRef(L"\\[(?:\'([^\']*)\'#){0,1}\\[{0,1}(?:\\$){0,1}([^\\.]+?){0,1}\\.(\\${0,1}[\\w^0-9]*\\${0,1}\\d*)(?::(\\${0,1}[^\\.]+?){0,1}\\.(\\${0,1}[\\w^0-9]*\\${0,1}\\d*)){0,1}\\]{0,1}"); - boost::wregex complexRef(L"(?:(?:(?:(?:\\[\'([^\']*)\'#)|(?:\'([^\']*)\'#\\[)))|(?:\\[))\ + boost::wregex complexRef(L"(?:(?:(?:(?:\\[(.*)#)|(?:(.*)#\\[)))|(?:\\[))\ (?:\\$){0,1}([^\\.]+?){0,1}\\.(\\${0,1}[\\w^0-9]*\\${0,1}\\d*)(?::(\\${0,1}[^\\.]+?){0,1}\\.(\\${0,1}[\\w^0-9]*\\${0,1}\\d*)){0,1}\\]"); -// [ 'external'# [ $ Sheet2 . A1 : ( $ Sheet2)? . B5 ] +// [ external# [ $ Sheet2 . A1 : ( $ Sheet2)? . B5 ] - expr = boost::regex_replace( + std::wstring result = boost::regex_replace( expr, complexRef, &replace_named_ref_formater, boost::match_default | boost::format_all); + + if (result == expr) + { + //bad formula ??? + boost::wregex complexRef_2(L"\\$([^\\.]+?)?\\.(\\$[a-zA-Z]*\\d*)(\\:\\$[a-zA-Z]*\\d*)?"); + // $ Sheet2 . $ A1 : ( $ Sheet2)? . $ B5 + + result = boost::regex_replace( + expr, + complexRef_2, + &replace_named_ref_formater_2, + boost::match_default | boost::format_all); + } + return result; } void odf2oox_converter::Impl::replace_named_ref(std::wstring & expr, bool withTableName, bool bAbsoluteAlways) { + if (expr.empty()) return; + XmlUtils::replace_all( expr, L"#REF !", L"#REF!"); XmlUtils::replace_all( expr, L"#REF!#REF!", L"#REF!"); XmlUtils::replace_all( expr, L"$#REF!$#REF!", L"#REF!"); @@ -492,8 +510,8 @@ namespace formulasconvert { convert_with_absolute = bAbsoluteAlways; //boost::wregex complexRef(L"\\${0,1}([^\\.]+?){0,1}\\.(\\${0,1}[a-zA-Z]+\\${0,1}\\d+)(?::\\.(\\${0,1}[a-zA-Z]+\\${0,1}\\d+)){0,1}"); - boost::wregex complexRef(L"\\[{0,1}(?:\'([^\']*)\'#){0,1}\\${0,1}([^\\.\\s]+?){0,1}\\.(\\${0,1}[\\w^0-9]*\\${0,1}\\d*)(?::\\${0,1}([^\\.\\s]+?){0,1}\\.(\\${0,1}[\\w^0-9]*\\${0,1}\\d*)){0,1}\\]{0,1}"); -// 'external'# $ Sheet2 . A1 : ( $ Sheet2)? . B5 + boost::wregex complexRef(L"\\[{0,1}(?:(.*)#){0,1}\\${0,1}([^\\.\\s]+?){0,1}\\.(\\${0,1}[\\w^0-9]*\\${0,1}\\d*)(?::\\${0,1}([^\\.\\s]+?){0,1}\\.(\\${0,1}[\\w^0-9]*\\${0,1}\\d*)){0,1}\\]{0,1}"); +// external# $ Sheet2 . A1 : ( $ Sheet2)? . B5 const std::wstring res = boost::regex_replace( expr, @@ -507,6 +525,8 @@ namespace formulasconvert { // of:=(Formula) -> (Formula) bool odf2oox_converter::Impl::check_formula(std::wstring& expr) { + if (expr.empty()) return false; + boost::match_results res; if (boost::regex_search(expr, res, boost::wregex(L"^(?:[\\w]+:)?=(.+)"), boost::match_default)) { @@ -582,11 +602,13 @@ namespace formulasconvert { bool isFormula = check_formula(workstr); //экранирование - workstr = boost::regex_replace(workstr, + mapReplacements.emplace_back(); + + workstr = boost::regex_replace(workstr, boost::wregex(L"('.*?')|(\".*?\")"), &convert_scobci, boost::match_default | boost::format_all); - replace_cells_range (workstr, true); + workstr = replace_cells_range (workstr, true); replace_semicolons (workstr); replace_tilda (workstr); replace_vertical (workstr); @@ -616,11 +638,14 @@ namespace formulasconvert { //----------------------------------------------------------- replace_tmp_back(workstr); + mapReplacements.pop_back(); return workstr; } void odf2oox_converter::Impl::split_distance_by(const std::wstring& expr, const std::wstring& by, std::vector& out) { + mapReplacements.emplace_back(); + std::wstring workstr = boost::regex_replace( expr, boost::wregex(L"('.*?')|(\".*?\")"), @@ -632,6 +657,7 @@ namespace formulasconvert { { replace_tmp_back(out[i]); } + mapReplacements.pop_back(); } //Sheet2.C3:Sheet2.C19 Sheet2.L29:Sheet2.L36 @@ -646,6 +672,8 @@ namespace formulasconvert { std::wstring odf2oox_converter::Impl::convert_chart_distance(const std::wstring& expr) { + mapReplacements.emplace_back(); + std::wstring workstr = boost::regex_replace( is_forbidden(expr), boost::wregex(L"('.*?')|(\".*?\")"), @@ -703,6 +731,7 @@ namespace formulasconvert { } replace_tmp_back( result ); + mapReplacements.pop_back(); return result.substr(0, result.size() - 1);// минус последняя лишняя запятая } std::wstring odf2oox_converter::Impl::convert_named_ref(const std::wstring& expr, bool withTableName, std::wstring separator, bool bAbsoluteAlways) @@ -711,6 +740,8 @@ namespace formulasconvert { std::wstring workstr = expr; + mapReplacements.emplace_back(); + workstr = boost::regex_replace( workstr, boost::wregex(L"('.*?')|(\".*?\")"), @@ -729,6 +760,7 @@ namespace formulasconvert { { replace_tmp_back( table_name_ ); } + mapReplacements.pop_back(); return workstr; } std::wstring odf2oox_converter::Impl::convert_named_expr(const std::wstring& expr, bool withTableName, bool bAbsoluteAlways) @@ -743,14 +775,14 @@ namespace formulasconvert { } else { + mapReplacements.emplace_back(); workstr = boost::regex_replace( workstr, boost::wregex(L"('.*?')|(\".*?\")"), &convert_scobci, boost::match_default | boost::format_all); - - replace_cells_range(workstr, withTableName, bAbsoluteAlways); + workstr = replace_cells_range(workstr, withTableName, bAbsoluteAlways); replace_semicolons(workstr); replace_vertical(workstr); @@ -767,6 +799,7 @@ namespace formulasconvert { { replace_tmp_back(table_name_); } + mapReplacements.pop_back(); } return workstr; } @@ -812,8 +845,7 @@ namespace formulasconvert { std::wstring odf2oox_converter::convert_ref(std::wstring const & expr) { std::wstring workstr = L"[" + expr + L"]"; - impl_->replace_cells_range(workstr, true); - return workstr; + return impl_->replace_cells_range(workstr, true); } std::wstring odf2oox_converter::convert_spacechar(std::wstring expr) { diff --git a/OdfFile/Formulas/formulasconvert_oox.cpp b/OdfFile/Formulas/formulasconvert_oox.cpp index ab1bae259ec..27c81ea306a 100644 --- a/OdfFile/Formulas/formulasconvert_oox.cpp +++ b/OdfFile/Formulas/formulasconvert_oox.cpp @@ -36,6 +36,7 @@ #include"../../OOXML/Base/Unit.h" #include "boost/lexical_cast.hpp" +//#include namespace cpdoccore { namespace formulasconvert { @@ -76,6 +77,8 @@ class oox2odf_converter::Impl static std::wstring replace_arguments(boost::wsmatch const & what); static std::wstring convert_scobci(boost::wsmatch const & what); + static std::vector> mapReplacements; + static std::wstring replace_tilda_formater(boost::wsmatch const & what) { if (what[1].matched) @@ -132,227 +135,37 @@ class oox2odf_converter::Impl return L""; } - static void oox_replace_tmp_back(std::wstring &expr) + static void oox_replace_tmp_back(std::wstring& expr) { - std::wstring result; - - size_t pos = 0, size = expr.length(); - - while(pos < size) + for (auto key : mapReplacements.back()) { - if (pos + 5 >= size) - { - result += expr[pos++]; - continue; - } - switch(expr[pos]) - { - case 'M': - { - if ((pos + 5 <= size) && (expr.substr(pos, 5) == L"MINYS")) - { - result += L"-"; pos += 5; - } - else - { - result += expr[pos++]; - } - }break; - case 'T': - { - if ((pos + 6 <= size) && (expr.substr(pos, 6) == L"TОСHKA")) - { - result += L"."; pos += 6; - } - else - { - result += expr[pos++]; - } - }break; - case 'V': - { - if ((pos + 5 <= size) && (expr.substr(pos, 5) == L"VOSKL")) - { - result += L"!"; pos += 5; - } - else - { - result += expr[pos++]; - } - }break; - case 'S': - { - if ((pos + 8 <= size) && (expr.substr(pos, 8) == L"SCOBCAIN")) - { - result += L"("; pos += 8; - } - else if ((pos + 9 <= size) && (expr.substr(pos, 9) == L"SCOBCAOUT")) - { - result += L")"; pos += 9; - } - else - { - result += expr[pos++]; - } - }break; - case 'K': - { - if ((pos + 9 <= size) && (expr.substr(pos, 9) == L"KVADRATIN")) - { - result += L"["; pos += 9; - } - else if ((pos + 10 <= size) && (expr.substr(pos, 10) == L"KVADRATOUT")) - { - result += L"]"; pos += 10; - } - else if ((pos + 8 <= size) && (expr.substr(pos, 8) == L"KAVYCHKA")) - { - result += L"\""; pos += 8; - } - else - { - result += expr[pos++]; - } - }break; - case 'P': - { - if ((pos + 6 <= size) && (expr.substr(pos, 6) == L"PROBEL")) - { - result += L" "; pos += 6; - } - else - { - result += expr[pos++]; - } - }break; - case 'A': - { - if ((pos + 8 <= size) && (expr.substr(pos, 8) == L"APOSTROF")) - { - result += L"'"; pos += 8; - } - else if ((pos + 8 <= size) && (expr.substr(pos, 8) == L"APERSAND")) - { - result += L"&"; pos += 8; - } - else - { - result += expr[pos++]; - } - }break; - case 'Z': - { - if ((pos + 9 <= size) && (expr.substr(pos, 9) == L"ZAPYATAYA")) - { - result += L","; pos += 9; - } - else - { - result += expr[pos++]; - } - }break; - default: - { - result += expr[pos++]; - }break; - } + XmlUtils::replace_all(expr, key.first, key.second); } - expr = result; - //XmlUtils::replace_all( expr, L"MINYS", L"-"); - //XmlUtils::replace_all( expr, L"TОСHKA", L"."); - //XmlUtils::replace_all( expr, L"VOSKL", L"!"); - - //XmlUtils::replace_all( expr, L"SCOBCAIN", L"("); - //XmlUtils::replace_all( expr, L"SCOBCAOUT", L")"); - - //XmlUtils::replace_all( expr, L"KVADRATIN", L"["); - //XmlUtils::replace_all( expr, L"KVADRATOUT", L"]"); - // - //XmlUtils::replace_all( expr, L"PROBEL", L" "); - //XmlUtils::replace_all( expr, L"APOSTROF", L"'"); - //XmlUtils::replace_all( expr, L"KAVYCHKA", L"\""); + + XmlUtils::replace_all(expr, L"KVADRATIN", L"["); + XmlUtils::replace_all(expr, L"KVADRATOUT", L"]"); + + return; } static void oox_replace_tmp(std::wstring &expr) { - std::wstring result; - - size_t pos = 0, size = expr.length(); - - while(pos < size) + //std::random_device genSource; + //std::uniform_int_distribution<> generator(0, 23); + //for (int index = 0; index < 5; index++) + //{ + // key += wchar_t(L'a' + generator(genSource)); + //} + + std::wstring key = L"aaaaaaaaaaaaaaaaaaaaaaaa"; + for (unsigned i = 0; i < 23; ++i) { - switch(expr[pos]) - { - case '-': - { - result += L"MINYS"; - }break; - case '.': - { - result += L"TОСHKA"; - }break; - case ',': - { - result += L"ZAPYATAYA"; - }break; - case '!': - { - result += L"VOSKL"; - }break; - case '(': - { - result += L"SCOBCAIN"; - }break; - case ')': - { - result += L"SCOBCAOUT"; - }break; - case '[': - { - result += L"KVADRATIN"; - }break; - case ']': - { - result += L"KVADRATOUT"; - }break; - case ' ': - { - result += L"PROBEL"; - }break; - case '\'': - { - result += L"APOSTROF"; - }break; - case '\"': - { - result += L"KAVYCHKA"; - }break; - case '&': - { - result += L"APERSAND"; - }break; - default: - { - result += expr[pos]; - }break; - } - pos++; + unsigned j = rand() % (i + 1); + key[i] = key[j]; + key[j] = wchar_t(L'a' + i); } - expr = result; - - //XmlUtils::replace_all( expr, L"-", L"MINYS"); - //XmlUtils::replace_all( expr, L".", L"TОСHKA"); - //XmlUtils::replace_all( expr, L"!", L"VOSKL"); - - //XmlUtils::replace_all( expr, L"(", L"SCOBCAIN"); - //XmlUtils::replace_all( expr, L")", L"SCOBCAOUT"); - - //XmlUtils::replace_all( expr, L"[", L"KVADRATIN"); - //XmlUtils::replace_all( expr, L"]", L"KVADRATOUT"); - // - //XmlUtils::replace_all( expr, L" ", L"PROBEL"); - //XmlUtils::replace_all( expr, L"'", L"APOSTROF"); - //XmlUtils::replace_all( expr, L"\"", L"KAVYCHKA"); + mapReplacements.back().insert(std::make_pair(key, expr)); + expr = key; } static bool is_forbidden1(const std::wstring & formula) @@ -375,12 +188,10 @@ class oox2odf_converter::Impl bool oox2odf_converter::Impl::isFindBaseCell_ = false; std::wstring oox2odf_converter::Impl::table_name_ = L""; +std::vector> oox2odf_converter::Impl::mapReplacements; void oox2odf_converter::Impl::replace_cells_range(std::wstring& expr, bool bSelect) { - if ((0 == expr.find(L"KAVYCHKA")) && (expr.length() - 8 == expr.rfind(L"KAVYCHKA") )) - return; - boost::wregex re(L"(([:$!])+)|(\\S+\\d+)"); boost::wsmatch result; @@ -493,11 +304,7 @@ std::wstring oox2odf_converter::Impl::replace_cells_range_formater1(boost::wsmat std::wstring c1 = what[2].str(); std::wstring c2 = what[3].str(); - if ((0 == c1.find(L"KAVYCHKA")) && (c1.length() - 8 == c1.rfind(L"KAVYCHKA") )) - { - return c1; - } - else if (!c1.empty() || !c2.empty() || !sheet.empty()) + if (!c1.empty() || !c2.empty() || !sheet.empty()) { XmlUtils::replace_all( sheet, L"!", L""); @@ -551,11 +358,7 @@ std::wstring oox2odf_converter::Impl::replace_cells_range_formater2(boost::wsmat std::wstring c1 = what[2].str(); std::wstring c2 = what[3].str(); - if ((0 == c1.find(L"KAVYCHKA")) && (c1.length() - 8 == c1.rfind(L"KAVYCHKA") )) - { - return c1; - } - else if (!c1.empty() || !c2.empty() || !sheet.empty()) + if (!c1.empty() || !c2.empty() || !sheet.empty()) { XmlUtils::replace_all( sheet, L"!", L""); @@ -612,7 +415,9 @@ void oox2odf_converter::Impl::replace_named_ref(std::wstring & expr) isFindBaseCell_ = true; std::wstring workstr = expr, out; - + + mapReplacements.emplace_back(); + replace_vertical(workstr); replace_semicolons(workstr); @@ -644,6 +449,7 @@ void oox2odf_converter::Impl::replace_named_ref(std::wstring & expr) { oox_replace_tmp_back(table_name_); } + mapReplacements.pop_back(); } @@ -699,7 +505,7 @@ std::wstring oox2odf_converter::Impl::convert_scobci(boost::wsmatch const & what if (what[1].matched) { std::wstring inner = what[1].str(); - oox_replace_tmp(inner); + oox_replace_tmp(inner); return inner; } else if (what[2].matched) @@ -761,19 +567,20 @@ std::wstring oox2odf_converter::Impl::convert(const std::wstring& expr) return workstr; } // (Formula) -> of:=(Formula) + std::wstring oox2odf_converter::Impl::convert_formula(const std::wstring & expr) -{ - +{ std::wstring workstr = expr; + mapReplacements.emplace_back(); std::wstring res1 = boost::regex_replace( - workstr, + workstr, boost::wregex(L"('.*?')|(\".*?\")"), &oox2odf_converter::Impl::convert_scobci, boost::match_default | boost::format_all); std::wstring res = boost::regex_replace( res1, - boost::wregex(L"(?!([А-Яа-яÀ-ÿ\\w^0-9]+\\d*\\())(([[А-Яа-яÀ-ÿ\\w^0-9]+\\!)?\\$?[\\w^0-9]*\\$?\\d*(\\:\\$?[\\w^0-9]*\\$?\\d*){0,1})"), + boost::wregex(L"(?!([[:Unicode:]\\w^0-9]+\\d*\\())(((\[[0-9]+\])?[[[:Unicode:]\\w^0-9]+\\!)?\\$?[\\w^0-9]*\\$?\\d*(\\:\\$?[\\w^0-9]*\\$?\\d*){0,1})"), &oox2odf_converter::Impl::replace_arguments, boost::match_default | boost::format_all); //SUBTOTAL(109,Expense31[Amount]) @@ -782,7 +589,7 @@ std::wstring oox2odf_converter::Impl::convert_formula(const std::wstring & expr) if (res1 == res) { - XmlUtils::replace_all( res1, L"KAVYCHKA", L"\""); //IMCONJUGATE_emb.xlsx + //IMCONJUGATE_emb.xlsx res = boost::regex_replace( res1, @@ -796,13 +603,13 @@ std::wstring oox2odf_converter::Impl::convert_formula(const std::wstring & expr) replace_vertical(res); replace_semicolons(res); - XmlUtils::replace_all( res, L"PROBEL", L" "); - if (table_name_.empty() == false) { oox_replace_tmp_back(table_name_); } + mapReplacements.pop_back(); + return std::wstring(L"of:=") + res; } @@ -810,6 +617,8 @@ std::wstring oox2odf_converter::Impl::convert_conditional_formula(const std::wst { std::wstring workstr = expr; + mapReplacements.emplace_back(); + std::wstring res1 = boost::regex_replace( workstr, boost::wregex(L"('.*?')|(\".*?\")"), @@ -829,13 +638,14 @@ std::wstring oox2odf_converter::Impl::convert_conditional_formula(const std::wst } - XmlUtils::replace_all(res, L"&", L"&"); + //XmlUtils::replace_all(res, L"&", L"&"); oox_replace_tmp_back( res); replace_vertical(res); replace_semicolons(res); - XmlUtils::replace_all( res, L"PROBEL", L" "); + mapReplacements.pop_back(); + //XmlUtils::replace_all( res, L"PROBEL", L" "); return res; diff --git a/OdfFile/Projects/Linux/OdfFormatLib.pro b/OdfFile/Projects/Linux/OdfFormatLib.pro index 6cd60c4550e..92d15aa039b 100644 --- a/OdfFile/Projects/Linux/OdfFormatLib.pro +++ b/OdfFile/Projects/Linux/OdfFormatLib.pro @@ -19,6 +19,8 @@ include(../../../Common/base.pri) #BOOST include($$PWD/../../../Common/3dParty/boost/boost.pri) +include($$PWD/../../Reader/Converter/StarMath2OOXML/StarMath2OOXML.pri) + DEFINES += UNICODE \ _UNICODE \ DONT_WRITE_EMBEDDED_FONTS @@ -40,8 +42,10 @@ SOURCES += \ core_debug { SOURCES += \ - ../../DataTypes/mathvariant.cpp \ + ../../DataTypes/referenceformat.cpp \ + ../../DataTypes/mathvariant.cpp \ ../../DataTypes/anchortype.cpp \ + ../../DataTypes/animation_attlists.cpp \ ../../DataTypes/backgroundcolor.cpp \ ../../DataTypes/bool.cpp \ ../../DataTypes/bordermodel.cpp \ @@ -95,12 +99,21 @@ SOURCES += \ ../../DataTypes/percent.cpp \ ../../DataTypes/percentorscale.cpp \ ../../DataTypes/presentationclass.cpp \ + ../../DataTypes/presentationnodetype.cpp \ + ../../DataTypes/presentationvisibility.cpp \ + ../../DataTypes/presetclass.cpp \ + ../../DataTypes/presetid.cpp \ ../../DataTypes/punctuationwrap.cpp \ ../../DataTypes/rotationalign.cpp \ ../../DataTypes/runthrough.cpp \ ../../DataTypes/scripttype.cpp \ ../../DataTypes/shadowtype.cpp \ + ../../DataTypes/smil_additive.cpp \ + ../../DataTypes/smil_attributename.cpp \ + ../../DataTypes/smil_fill.cpp \ + ../../DataTypes/smil_keytimes.cpp \ ../../DataTypes/smil_transitiontype.cpp \ + ../../DataTypes/smil_values.cpp \ ../../DataTypes/stylefamily.cpp \ ../../DataTypes/stylehorizontalpos.cpp \ ../../DataTypes/stylehorizontalrel.cpp \ @@ -113,6 +126,7 @@ SOURCES += \ ../../DataTypes/styleverticalrel.cpp \ ../../DataTypes/stylewrap.cpp \ ../../DataTypes/stylewrapcontourmode.cpp \ + ../../DataTypes/svg_type.cpp \ ../../DataTypes/stylenumformat.cpp \ ../../DataTypes/tablealign.cpp \ ../../DataTypes/tablecentering.cpp \ @@ -191,7 +205,8 @@ SOURCES += \ ../../Reader/Format/office_settings.cpp \ ../../Reader/Format/office_spreadsheet.cpp \ ../../Reader/Format/office_text.cpp \ - ../../Reader/Format/office_meta.cpp \ + ../../Reader/Format/office_drawing.cpp \ + ../../Reader/Format/office_meta.cpp \ ../../Reader/Format/paragraph_elements.cpp \ ../../Reader/Format/ruby.cpp \ ../../Reader/Format/search_table_cell.cpp \ @@ -258,6 +273,7 @@ SOURCES += \ ../../Reader/Converter/oox_title.cpp \ ../../Reader/Converter/oox_types_chart.cpp \ ../../Reader/Converter/oox_rels.cpp \ + ../../Reader/Converter/pptx_animation_context.cpp \ ../../Reader/Converter/pptx_comments.cpp \ ../../Reader/Converter/pptx_comments_context.cpp \ ../../Reader/Converter/pptx_conversion_context.cpp \ @@ -433,8 +449,10 @@ HEADERS += \ ../../Common/xml/xmlchar.h \ ../../Common/xml/xmlelement.h \ \ - ../../DataTypes/mathvariant.h \ + ../../DataTypes/referenceformat.h \ + ../../DataTypes/mathvariant.h \ ../../DataTypes/anchortype.h \ + ../../DataTypes/animation_attlists.h \ ../../DataTypes/backgroundcolor.h \ ../../DataTypes/bool.h \ ../../DataTypes/bordermodel.h \ @@ -489,12 +507,21 @@ HEADERS += \ ../../DataTypes/percent.h \ ../../DataTypes/percentorscale.h \ ../../DataTypes/presentationclass.h \ + ../../DataTypes/presentationnodetype.h \ + ../../DataTypes/presentationvisibility.h \ + ../../DataTypes/presetclass.h \ + ../../DataTypes/presetid.h \ ../../DataTypes/punctuationwrap.h \ ../../DataTypes/rotationalign.h \ ../../DataTypes/runthrough.h \ ../../DataTypes/scripttype.h \ ../../DataTypes/shadowtype.h \ + ../../DataTypes/smil_additive.h \ + ../../DataTypes/smil_attributename.h \ + ../../DataTypes/smil_fill.h \ + ../../DataTypes/smil_keytimes.h \ ../../DataTypes/smil_transitiontype.h \ + ../../DataTypes/smil_values.h \ ../../DataTypes/stylefamily.h \ ../../DataTypes/stylehorizontalpos.h \ ../../DataTypes/stylehorizontalrel.h \ @@ -508,6 +535,7 @@ HEADERS += \ ../../DataTypes/stylewrap.h \ ../../DataTypes/stylenumformat.h \ ../../DataTypes/stylewrapcontourmode.h \ + ../../DataTypes/svg_type.h \ ../../DataTypes/tablealign.h \ ../../DataTypes/tablecentering.h \ ../../DataTypes/tablemode.h \ @@ -569,6 +597,7 @@ HEADERS += \ ../../Reader/Format/office_elements_type.h \ ../../Reader/Format/office_event_listeners.h \ ../../Reader/Format/office_presentation.h \ + ../../Reader/Format/office_drawing.h \ ../../Reader/Format/office_scripts.h \ ../../Reader/Format/office_forms.h \ ../../Reader/Format/office_settings.h \ @@ -638,6 +667,7 @@ HEADERS += \ ../../Reader/Converter/oox_title.h \ ../../Reader/Converter/oox_types_chart.h \ ../../Reader/Converter/oox_rels.h \ + ../../Reader/Converter/pptx_animation_context.h \ ../../Reader/Converter/pptx_comments.h \ ../../Reader/Converter/pptx_comments_context.h \ ../../Reader/Converter/pptx_conversion_context.h \ diff --git a/OdfFile/Projects/Linux/odf_converter.cpp b/OdfFile/Projects/Linux/odf_converter.cpp index e6684233cc1..a2a0fe16ff5 100644 --- a/OdfFile/Projects/Linux/odf_converter.cpp +++ b/OdfFile/Projects/Linux/odf_converter.cpp @@ -59,6 +59,7 @@ #include "../../Reader/Converter/oox_title.cpp" #include "../../Reader/Converter/oox_types_chart.cpp" #include "../../Reader/Converter/oox_rels.cpp" +#include "../../Reader/Converter/pptx_animation_context.cpp" #include "../../Reader/Converter/pptx_comments.cpp" #include "../../Reader/Converter/pptx_comments_context.cpp" #include "../../Reader/Converter/pptx_conversion_context.cpp" diff --git a/OdfFile/Projects/Linux/odf_datatypes.cpp b/OdfFile/Projects/Linux/odf_datatypes.cpp index 34c8b84ef53..ca12641c14d 100644 --- a/OdfFile/Projects/Linux/odf_datatypes.cpp +++ b/OdfFile/Projects/Linux/odf_datatypes.cpp @@ -31,6 +31,7 @@ */ #include "../../DataTypes/anchortype.cpp" +#include "../../DataTypes/animation_attlists.cpp" #include "../../DataTypes/backgroundcolor.cpp" #include "../../DataTypes/bool.cpp" #include "../../DataTypes/bordermodel.cpp" @@ -84,12 +85,21 @@ #include "../../DataTypes/percent.cpp" #include "../../DataTypes/percentorscale.cpp" #include "../../DataTypes/presentationclass.cpp" +#include "../../DataTypes/presentationnodetype.cpp" +#include "../../DataTypes/presentationvisibility.cpp" +#include "../../DataTypes/presetclass.cpp" +#include "../../DataTypes/presetid.cpp" #include "../../DataTypes/punctuationwrap.cpp" #include "../../DataTypes/rotationalign.cpp" #include "../../DataTypes/runthrough.cpp" #include "../../DataTypes/scripttype.cpp" #include "../../DataTypes/shadowtype.cpp" +#include "../../DataTypes/smil_additive.cpp" +#include "../../DataTypes/smil_attributename.cpp" +#include "../../DataTypes/smil_fill.cpp" +#include "../../DataTypes/smil_keytimes.cpp" #include "../../DataTypes/smil_transitiontype.cpp" +#include "../../DataTypes/smil_values.cpp" #include "../../DataTypes/stylefamily.cpp" #include "../../DataTypes/stylehorizontalpos.cpp" #include "../../DataTypes/stylehorizontalrel.cpp" @@ -130,6 +140,7 @@ #include "../../DataTypes/tableorder.cpp" #include "../../DataTypes/dategroup.cpp" #include "../../DataTypes/commandtype.cpp" +#include "../../DataTypes/svg_type.cpp" #include "../../DataTypes/stylenumformat.cpp" #include "../../DataTypes/bibliography.cpp" #include "../../DataTypes/styleprint.cpp" @@ -142,3 +153,4 @@ #include "../../DataTypes/sparklines.cpp" #include "../../DataTypes/tabledatatype.cpp" #include "../../DataTypes/tableoperator.cpp" +#include "../../DataTypes/referenceformat.cpp" diff --git a/OdfFile/Projects/Linux/odf_reader.cpp b/OdfFile/Projects/Linux/odf_reader.cpp index ffb0063d209..3a465f4b4d6 100644 --- a/OdfFile/Projects/Linux/odf_reader.cpp +++ b/OdfFile/Projects/Linux/odf_reader.cpp @@ -62,6 +62,7 @@ #include "../../Reader/Format/office_elements_create.cpp" #include "../../Reader/Format/office_event_listeners.cpp" #include "../../Reader/Format/office_presentation.cpp" +#include "../../Reader/Format/office_drawing.cpp" #include "../../Reader/Format/office_scripts.cpp" #include "../../Reader/Format/office_forms.cpp" #include "../../Reader/Format/office_settings.cpp" diff --git a/OdfFile/Projects/Windows/OdfFormatW.vcxproj b/OdfFile/Projects/Windows/OdfFormatW.vcxproj index 2a11d476f35..c939187b7ef 100644 --- a/OdfFile/Projects/Windows/OdfFormatW.vcxproj +++ b/OdfFile/Projects/Windows/OdfFormatW.vcxproj @@ -19,6 +19,7 @@ + @@ -62,7 +63,9 @@ - + + /bigobj %(AdditionalOptions) + @@ -99,6 +102,7 @@ + diff --git a/OdfFile/Projects/Windows/OdfFormatW.vcxproj.filters b/OdfFile/Projects/Windows/OdfFormatW.vcxproj.filters index a8d205d1bba..f035eb66335 100644 --- a/OdfFile/Projects/Windows/OdfFormatW.vcxproj.filters +++ b/OdfFile/Projects/Windows/OdfFormatW.vcxproj.filters @@ -4,6 +4,9 @@ {2c07ccd6-b0a1-40b5-99b2-2c732a124cff} + + {b7620571-58c3-496f-ab28-245c69522663} + @@ -137,6 +140,9 @@ + + math + @@ -217,5 +223,8 @@ + + math + \ No newline at end of file diff --git a/OdfFile/Projects/Windows/cpcommon.vcxproj b/OdfFile/Projects/Windows/cpcommon.vcxproj index 8761c2330e6..e4890c3f57a 100644 --- a/OdfFile/Projects/Windows/cpcommon.vcxproj +++ b/OdfFile/Projects/Windows/cpcommon.vcxproj @@ -143,6 +143,7 @@ $(OutDir)$(ProjectName)-static.lib + $(SolutionDir)..\..\..\..\Common\3dParty\boost\build\win_32\lib;%(AdditionalLibraryDirectories) @@ -180,6 +181,7 @@ + @@ -246,12 +248,22 @@ + + + + + + + + + + @@ -268,6 +280,7 @@ + @@ -302,6 +315,7 @@ + @@ -365,12 +379,22 @@ + + + + + + + + + + @@ -387,6 +411,7 @@ + diff --git a/OdfFile/Projects/Windows/cpcommon.vcxproj.filters b/OdfFile/Projects/Windows/cpcommon.vcxproj.filters index dc5da928191..909e9e65ba4 100644 --- a/OdfFile/Projects/Windows/cpcommon.vcxproj.filters +++ b/OdfFile/Projects/Windows/cpcommon.vcxproj.filters @@ -1,9 +1,135 @@  - - {c5b21206-a811-4082-8df4-c8306b5518b0} - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -13,342 +139,7 @@ - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - - - datatypes odf - + @@ -356,15 +147,133 @@ - - datatypes odf - - - datatypes odf - - - datatypes odf - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -702,11 +611,5 @@ datatypes odf - - datatypes odf - - - datatypes odf - \ No newline at end of file diff --git a/OdfFile/Projects/Windows/cpodf.vcxproj b/OdfFile/Projects/Windows/cpodf.vcxproj index eb3c517ae8d..805181c0db9 100644 --- a/OdfFile/Projects/Windows/cpodf.vcxproj +++ b/OdfFile/Projects/Windows/cpodf.vcxproj @@ -251,6 +251,7 @@ /bigobj %(AdditionalOptions) + /bigobj %(AdditionalOptions) @@ -281,6 +282,8 @@ /bigobj %(AdditionalOptions) + + /bigobj %(AdditionalOptions) @@ -509,6 +512,7 @@ /bigobj %(AdditionalOptions) + /bigobj %(AdditionalOptions) @@ -550,6 +554,7 @@ /bigobj %(AdditionalOptions) + /bigobj %(AdditionalOptions) /bigobj %(AdditionalOptions) @@ -662,6 +667,7 @@ + @@ -673,6 +679,11 @@ + + + + + @@ -745,6 +756,7 @@ + diff --git a/OdfFile/Projects/Windows/cpodf.vcxproj.filters b/OdfFile/Projects/Windows/cpodf.vcxproj.filters index 582419ac863..d4afee8fee1 100644 --- a/OdfFile/Projects/Windows/cpodf.vcxproj.filters +++ b/OdfFile/Projects/Windows/cpodf.vcxproj.filters @@ -1,932 +1,338 @@  - - {e8d90800-7021-4032-8d17-274da4aa8e51} - - - {9727d03b-cbbc-4826-8201-33a7efbe18ae} - - - {be7ec2fb-7bd5-4d53-b95d-c8fdc54ce7e1} - - - {cd06f6d0-4dca-49f4-9dd1-f3ef8bc9ccad} - - - {364be721-ed85-4b58-a882-46ad3b9fa58e} - - - {deeff4dd-2ea3-4438-a021-54ddc8f67f16} - - - {ebc99137-74a5-4b8c-9e31-56190141e2bd} - - - {67b2bf43-5673-4a6f-82cb-fe4be01aee5f} - - - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - oox\docx - - - oox\docx - - - oox\docx - - - oox\docx - - - oox\docx - - - oox\docx - - - oox\docx - - - oox\docx - - - oox\oox - - - oox\oox - - - oox\oox - - - oox\oox - - - oox\oox - - - oox\oox - - - oox\oox - - - oox\oox - - - oox\oox - - - oox\oox\chart - - - oox\oox\chart - - - oox\oox\chart - - - oox\oox\chart - - - oox\oox\chart - - - oox\oox\chart - - - oox\oox\chart - - - oox\oox\chart - - - oox\oox\chart - - - oox\pptx - - - oox\pptx - - - oox\pptx - - - oox\pptx - - - oox\pptx - - - oox\pptx - - - oox\pptx - - - oox\pptx - - - oox\pptx - - - oox\pptx - - - oox\xlsx\styles - - - oox\xlsx\styles - - - oox\xlsx\styles - - - oox\xlsx\styles - - - oox\xlsx\styles - - - oox\xlsx\styles - - - oox\xlsx\styles - - - oox\xlsx\styles - - - oox\xlsx\styles - - - oox\xlsx\styles - - - oox\xlsx\styles - - - oox\xlsx\styles - - - oox\xlsx - - - oox\xlsx - - - oox\xlsx - - - oox\xlsx - - - oox\xlsx - - - oox\xlsx - - - oox\xlsx - - - oox\xlsx - - - oox\xlsx - - - oox\xlsx - - - oox\xlsx - - - oox\xlsx - - - oox\xlsx - - - oox\xlsx - - - oox\xlsx - - - oox\xlsx - - - oox\xlsx - - - oox\xlsx - - - oox\xlsx - - - oox\xlsx - - - oox\xlsx - - - oox\xlsx - - - oox\xlsx - - - oox\xlsx - - - oox\xlsx\styles - - - oox\xlsx\styles - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + math + + + math + - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - elements - - - oox\docx - - - oox\docx - - - oox\docx - - - oox\docx - - - oox\docx - - - oox\docx - - - oox\docx - - - oox\docx - - - oox\oox - - - oox\oox - - - oox\oox - - - oox\oox - - - oox\oox - - - oox\oox - - - oox\oox - - - oox\oox - - - oox\oox - - - oox\oox - - - oox\oox - - - oox\oox\chart - - - oox\oox\chart - - - oox\oox\chart - - - oox\oox\chart - - - oox\oox\chart - - - oox\oox\chart - - - oox\oox\chart - - - oox\oox\chart - - - oox\oox\chart - - - oox\oox\chart - - - oox\pptx - - - oox\pptx - - - oox\pptx - - - oox\pptx - - - oox\pptx - - - oox\pptx - - - oox\pptx - - - oox\pptx - - - oox\pptx - - - oox\pptx - - - oox\pptx - - - oox\xlsx\styles - - - oox\xlsx\styles - - - oox\xlsx\styles - - - oox\xlsx\styles - - - oox\xlsx\styles - - - oox\xlsx\styles - - - oox\xlsx\styles - - - oox\xlsx\styles - - - oox\xlsx\styles - - - oox\xlsx\styles - - - oox\xlsx\styles - - - oox\xlsx\styles - - - oox\xlsx - - - oox\xlsx - - - oox\xlsx - - - oox\xlsx - - - oox\xlsx - - - oox\xlsx - - - oox\xlsx - - - oox\xlsx - - - oox\xlsx - - - oox\xlsx - - - oox\xlsx - - - oox\xlsx - - - oox\xlsx - - - oox\xlsx - - - oox\xlsx - - - oox\xlsx - - - oox\xlsx - - - oox\xlsx - - - oox\xlsx - - - oox\xlsx - - - oox\xlsx - - - oox\xlsx - - - oox\xlsx - - - oox\xlsx - - - oox\xlsx - - - oox\xlsx - - - oox\xlsx - - - oox\xlsx\styles - - - oox\xlsx\styles - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + math + + + math + + + math + + + math + + + math + + + + + {36f1d987-256f-4be8-93b9-74cd74341f45} + \ No newline at end of file diff --git a/OdfFile/Reader/Converter/ConvertOO2OOX.cpp b/OdfFile/Reader/Converter/ConvertOO2OOX.cpp index 4403d1d907f..d51c204dccd 100644 --- a/OdfFile/Reader/Converter/ConvertOO2OOX.cpp +++ b/OdfFile/Reader/Converter/ConvertOO2OOX.cpp @@ -120,6 +120,7 @@ _UINT32 ConvertODF2OOXml(const std::wstring & srcPath, const std::wstring & dstP break; case 3: case 6: + case 7: nResult = ConvertOdp2Pptx(inputOdf, dstPath, fontsPath); break; } diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/.gitignore b/OdfFile/Reader/Converter/StarMath2OOXML/.gitignore new file mode 100644 index 00000000000..4a0b530afd2 --- /dev/null +++ b/OdfFile/Reader/Converter/StarMath2OOXML/.gitignore @@ -0,0 +1,74 @@ +# This file is used to ignore files which are generated +# ---------------------------------------------------------------------------- + +*~ +*.autosave +*.a +*.core +*.moc +*.o +*.obj +*.orig +*.rej +*.so +*.so.* +*_pch.h.cpp +*_resource.rc +*.qm +.#* +*.*# +core +!core/ +tags +.DS_Store +.directory +*.debug +Makefile* +*.prl +*.app +moc_*.cpp +ui_*.h +qrc_*.cpp +Thumbs.db +*.res +*.rc +/.qmake.cache +/.qmake.stash + +# qtcreator generated files +*.pro.user* +CMakeLists.txt.user* + +# xemacs temporary files +*.flc + +# Vim temporary files +.*.swp + +# Visual Studio generated files +*.ib_pdb_index +*.idb +*.ilk +*.pdb +*.sln +*.suo +*.vcproj +*vcproj.*.*.user +*.ncb +*.sdf +*.opensdf +*.vcxproj +*vcxproj.* + +# MinGW generated files +*.Debug +*.Release + +# Python byte code +*.pyc + +# Binaries +# -------- +*.dll +*.exe + diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/StarMath2OOXML.pri b/OdfFile/Reader/Converter/StarMath2OOXML/StarMath2OOXML.pri new file mode 100644 index 00000000000..bcf64bfd170 --- /dev/null +++ b/OdfFile/Reader/Converter/StarMath2OOXML/StarMath2OOXML.pri @@ -0,0 +1,22 @@ + +CORE_ROOT_DIR = $$PWD/../../../.. +PWD_ROOT_DIR = $$PWD + +include($$CORE_ROOT_DIR/Common/base.pri) +include($$CORE_ROOT_DIR/Common/3dParty/icu/icu.pri) +include($$CORE_ROOT_DIR/Common/3dParty/boost/boost.pri) +ADD_DEPENDENCY(UnicodeConverter, kernel) + + +SOURCES += $$PWD/cconversionsmtoooxml.cpp \ + $$PWD/cooxml2odf.cpp \ + $$PWD/cstarmathpars.cpp + +HEADERS += \ + $$PWD/cconversionsmtoooxml.h \ + $$PWD/cooxml2odf.h \ + $$PWD/cstarmathpars.h \ + $$PWD/fontType.h \ + $$PWD/typeConversion.h \ + $$PWD/typeselements.h + diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/Test.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/Test.cpp new file mode 100644 index 00000000000..4f9a843b9c2 --- /dev/null +++ b/OdfFile/Reader/Converter/StarMath2OOXML/Test.cpp @@ -0,0 +1,11 @@ +#include "cstarmathpars.h" +#include "cconversionsmtoooxml.h" + +//int main() +//{ +// std::wstring Temp = L"1 + 2 over 3"; +// StarMath::CStarMathPars TempO; +// TempO.Pars(Temp); +// StarMath::CConversionSMtoOOXML m_oTest; +// m_oTest.StartConversion(TempO.GetVector()); +//} diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/TestSMConverter/TestSMConverter.pro b/OdfFile/Reader/Converter/StarMath2OOXML/TestSMConverter/TestSMConverter.pro new file mode 100644 index 00000000000..788618500be --- /dev/null +++ b/OdfFile/Reader/Converter/StarMath2OOXML/TestSMConverter/TestSMConverter.pro @@ -0,0 +1,18 @@ +QT -= core gui + +TARGET = test +CONFIG += console +CONFIG -= app_bundle +TEMPLATE = app + +CORE_ROOT_DIR = $$PWD/../../../../.. +PWD_ROOT_DIR = $$PWD + +include($$CORE_ROOT_DIR/OdfFile/Reader/Converter/StarMath2OOXML/StarMath2OOXML.pri) +include($$CORE_ROOT_DIR/Common/3dParty/googletest/googletest.pri) + + + +SOURCES += main.cpp + +DESTDIR = $$PWD/build diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/TestSMConverter/main.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/TestSMConverter/main.cpp new file mode 100644 index 00000000000..cec1fcfaf80 --- /dev/null +++ b/OdfFile/Reader/Converter/StarMath2OOXML/TestSMConverter/main.cpp @@ -0,0 +1,1430 @@ +#include "../cstarmathpars.h" +#include "../cconversionsmtoooxml.h" +#include "gtest/gtest.h" + + + +TEST(SMConvectorTest, BinOperatorPlus) +{ + std::wstring wsBinOperator = L"2 + 3"; + StarMath::CParserStarMathString m_oTempO; + StarMath::CConversionSMtoOOXML m_oTest; + m_oTest.StartConversion(m_oTempO.Parse(wsBinOperator)); + std::wstring XmlString = L"2+3"; + EXPECT_EQ(m_oTest.GetOOXML(),XmlString); +} + +TEST(SMConvectorTest,BinOperatorOver) +{ + std::wstring wsBinOperator = L"2 over 3"; + StarMath::CParserStarMathString m_oTempO; + StarMath::CConversionSMtoOOXML m_oTest; + m_oTest.StartConversion(m_oTempO.Parse(wsBinOperator)); + std::wstring XmlString = L"23"; + EXPECT_EQ(m_oTest.GetOOXML(),XmlString); +} + +TEST(SMConvectorTest,BinOperatorCdot) +{ + std::wstring wsBinOperator = L"5 cdot 8"; + StarMath::CParserStarMathString m_oTempO; + StarMath::CConversionSMtoOOXML m_oTest; + m_oTest.StartConversion(m_oTempO.Parse(wsBinOperator)); + std::wstring XmlString = L"5\u00B78"; + EXPECT_EQ(m_oTest.GetOOXML(),XmlString); +} + +TEST(SMConvectorTest,BinOperatorTimes) +{ + std::wstring wsBinOperator = L"5 times 8"; + StarMath::CParserStarMathString m_oTempO; + StarMath::CConversionSMtoOOXML m_oTest; + m_oTest.StartConversion(m_oTempO.Parse(wsBinOperator)); + std::wstring XmlString = L"5\u00D78"; + EXPECT_EQ(m_oTest.GetOOXML(),XmlString); +} + +TEST(SMConvectorTest,BinOperatorMultipl) +{ + std::wstring wsBinOperator = L"4 * 2"; + StarMath::CParserStarMathString m_oTempO; + StarMath::CConversionSMtoOOXML m_oTest; + m_oTest.StartConversion(m_oTempO.Parse(wsBinOperator)); + std::wstring XmlString = L"4*2"; + EXPECT_EQ(m_oTest.GetOOXML(),XmlString); +} + +TEST(SMConvectorTest,BinOperatorDiv) +{ + std::wstring wsBinOperator = L"4div2"; + StarMath::CParserStarMathString m_oTempO; + StarMath::CConversionSMtoOOXML m_oTest; + m_oTest.StartConversion(m_oTempO.Parse(wsBinOperator)); + std::wstring XmlString = L"4\u00F72"; + EXPECT_EQ(m_oTest.GetOOXML(),XmlString); +} + +TEST(SMConvectorTest,BinOperatorDivision) +{ + std::wstring wsBinOperator = L"4/2"; + StarMath::CParserStarMathString m_oTempO; + StarMath::CConversionSMtoOOXML m_oTest; + m_oTest.StartConversion(m_oTempO.Parse(wsBinOperator)); + std::wstring XmlString = L"42"; + EXPECT_EQ(m_oTest.GetOOXML(),XmlString); +} + +TEST(SMConvectorTest,BinOperatorOplus) +{ + std::wstring wsBinOperator = L"226oplus179"; + StarMath::CParserStarMathString m_oTempO; + StarMath::CConversionSMtoOOXML m_oTest; + m_oTest.StartConversion(m_oTempO.Parse(wsBinOperator)); + std::wstring XmlString = L"226\u2295179"; + EXPECT_EQ(m_oTest.GetOOXML(),XmlString); +} + +TEST(SMConvectorTest,BinOperatorOdot) +{ + std::wstring wsBinOperator = L"226 odot 179"; + StarMath::CParserStarMathString m_oTempO; + StarMath::CConversionSMtoOOXML m_oTest; + m_oTest.StartConversion(m_oTempO.Parse(wsBinOperator)); + std::wstring XmlString = L"226\u2299179"; + EXPECT_EQ(m_oTest.GetOOXML(),XmlString); +} + +TEST(SMConvectorTest,BinOperatorOtimes) +{ + std::wstring wsBinOperator = L"226 otimes 179"; + StarMath::CParserStarMathString m_oTempO; + StarMath::CConversionSMtoOOXML m_oTest; + m_oTest.StartConversion(m_oTempO.Parse(wsBinOperator)); + std::wstring XmlString = L"226\u2297179"; + EXPECT_EQ(m_oTest.GetOOXML(),XmlString); +} + +TEST(SMConvectorTest,OperatorSum) +{ + std::wstring wsOperator = L"sum 5"; + StarMath::CParserStarMathString m_oTempO; + StarMath::CConversionSMtoOOXML m_oTest; + m_oTest.StartConversion(m_oTempO.Parse(wsOperator)); + std::wstring XmlString = L"5"; + EXPECT_EQ(m_oTest.GetOOXML(),XmlString); +} + +TEST(SMConvectorTest,OperatorSumFrom) +{ + std::wstring wsOperator = L"sum from 10 5"; + StarMath::CParserStarMathString m_oTempO; + StarMath::CConversionSMtoOOXML m_oTest; + m_oTest.StartConversion(m_oTempO.Parse(wsOperator)); + std::wstring XmlString = L"105"; + EXPECT_EQ(m_oTest.GetOOXML(),XmlString); +} + +TEST(SMConvectorTest,OperatorSumTo) +{ + std::wstring wsOperator = L"sum to 10 5"; + StarMath::CParserStarMathString m_oTempO; + StarMath::CConversionSMtoOOXML m_oTest; + m_oTest.StartConversion(m_oTempO.Parse(wsOperator)); + std::wstring XmlString = L"105"; + EXPECT_EQ(m_oTest.GetOOXML(),XmlString); +} + +TEST(SMConvectorTest,OperatorSumFromTo) +{ + std::wstring wsOperator = L"sum from 666 to 777 567"; + StarMath::CParserStarMathString m_oTempO; + StarMath::CConversionSMtoOOXML m_oTest; + m_oTest.StartConversion(m_oTempO.Parse(wsOperator)); + std::wstring XmlString = L"666777567"; + EXPECT_EQ(m_oTest.GetOOXML(),XmlString); +} + +TEST(SMConvectorTest,SetOperationUnion) +{ + std::wstring wsString = L"23 union 45"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"23\u22C345"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,SetOperationIntersection) +{ + std::wstring wsString = L"15 intersection 1234"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"15\u22C21234"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,SetOperationSetminus) +{ + std::wstring wsString = L"7 setminus 15745"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"7\u221615745"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,SetOperationSetquotient) +{ + std::wstring wsString = L"91 setquotient 45"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"91\u221545"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,SetOperationSubset) +{ + std::wstring wsString = L"1 subset 2"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"1\u22822"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,SetOperationSubseteq) +{ + std::wstring wsString = L"77subseteq66"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"77\u228666"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,SetOperationSupset) +{ + std::wstring wsString = L"11supset22"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"11\u228322"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,SetOperationSupseteq) +{ + std::wstring wsString = L"1 supseteq 2"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"1\u22872"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,SetOperationNsubset) +{ + std::wstring wsString = L"21nsubset2"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"21\u22842"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,SetOperationNsubseteq) +{ + std::wstring wsString = L"782nsubseteq250"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"782\u2288250"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,SetOperationNsupset) +{ + std::wstring wsString = L"1nsupset2"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"1\u22852"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,SetOperationNsupseteq) +{ + std::wstring wsString = L"1nsupseteq2"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"1\u22892"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,SetOperationIn) +{ + std::wstring wsString = L"1 in 2"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"1\u22082"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,SetOperationNotin) +{ + std::wstring wsString = L"3 notin 4"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"3\u22094"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,SetOperationOwns) +{ + std::wstring wsString = L"5owns6"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"5\u220B6"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,ConnectionDlarrow) +{ + std::wstring wsString = L"7 dlarrow 8"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"7\u21D08"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,ConnectionDlrarrow) +{ + std::wstring wsString = L"9 dlrarrow 10"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"9\u21D410"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,ConnectionDrarrow) +{ + std::wstring wsString = L"11drarrow12"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"11\u21D212"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,ConnectionEquals) +{ + std::wstring wsString = L"13=14"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"13=14"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,ConnectionNotequals) +{ + std::wstring wsString = L"15 <> 16"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"15\u226016"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,ConnectionLearrow) +{ + std::wstring wsString = L"17<18"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"17<18"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,ConnectionLearrowequals) +{ + std::wstring wsString = L"19<= 20"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"19\u226420"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,ConnectionRiarrow) +{ + std::wstring wsString = L"21 >22"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"21>22"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,ConnectionRiarrowequals) +{ + std::wstring wsString = L"23 >=24"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"23\u226524"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,ConnectionDllearrow) +{ + std::wstring wsString = L"25 <<26"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"25\u226A26"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,ConnectionDlriarrow) +{ + std::wstring wsString = L"27 >> 28"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"27\u226B28"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,ConnectionApprox) +{ + std::wstring wsString = L"29 approx30"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"29\u224830"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,ConnectionSim) +{ + std::wstring wsString = L"31sim 32"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"31\u223C32"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,ConnectionSimeq) +{ + std::wstring wsString = L"33 simeq 34"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"33\u224334"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,ConnectionEquiv) +{ + std::wstring wsString = L"35 equiv 36"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"35\u226136"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,ConnectionProp) +{ + std::wstring wsString = L"37 prop 38"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"37\u221D38"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,ConnectionParallel) +{ + std::wstring wsString = L"39 parallel 30"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"39\u222530"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,ConnectionOrtho) +{ + std::wstring wsString = L"41ortho42"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"41\u22A542"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,ConnectionDivides) +{ + std::wstring wsString = L"43 divides 44"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"43\u222344"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,ConnectionNdivides) +{ + std::wstring wsString = L"45 ndivides 46"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"45\u222446"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,ConnectionToward) +{ + std::wstring wsString = L"47 toward 48"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"47\u219248"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,ConnectionTransl) +{ + std::wstring wsString = L"49 transl 50"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"49\u22B750"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,ConnectionTransr) +{ + std::wstring wsString = L"51 transr 52"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"51\u22B652"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,ConnectionDef) +{ + std::wstring wsString = L"53def54"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"53\u225D54"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,ConnectionPrec) +{ + std::wstring wsString = L"55prec56"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"55\u227A56"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,ConnectionSucc) +{ + std::wstring wsString = L"57 succ 58"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"57\u227B58"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,ConnectionPreccurlyeq) +{ + std::wstring wsString = L"59 preccurlyeq 60"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"59\u227C60"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,ConnectionSucccurlyeq) +{ + std::wstring wsString = L"61 succcurlyeq 62"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"61\u227D62"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,ConnectionPrecsim) +{ + std::wstring wsString = L"63 precsim 64"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"63\u227E64"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,ConnectionSuccsim) +{ + std::wstring wsString = L"65 succsim 66"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"65\u227F66"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,ConnectionNprec) +{ + std::wstring wsString = L"67nprec68"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"67\u228068"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,ConnectionNsucc) +{ + std::wstring wsString = L"69nsucc70"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"69\u228170"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,BracketRound) +{ + std::wstring wsString = L"(2+3)"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"2+3"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,BracketSquare) +{ + std::wstring wsString = L"[4-5]"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"4-5"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,BracketLdbracket) +{ + std::wstring wsString = L"ldbracket 6+7 rdbracket"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"6+7"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,BracketLbrace) +{ + std::wstring wsString = L"lbrace 8 - 9 rbrace"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"8-9"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,BracketLangle) +{ + std::wstring wsString = L"langle 10 over 11 rangle"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"1011"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,BracketLceil) +{ + std::wstring wsString = L"lceil 12 ominus 13 rceil"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"12\u229613"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,BracketLfloor) +{ + std::wstring wsString = L"lfloor 14 union 15 rfloor"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"14\u22C315"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,BracketLline) +{ + std::wstring wsString = L"lline 16 / 17 rline"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"1617"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,BracketLdline) +{ + std::wstring wsString = L"ldline 18 oplus 19 rdline"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"18\u229519"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,FunctionCos) +{ + std::wstring wsString = L"cos{2+3}"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"cos2+3"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,FunctionSin) +{ + std::wstring wsString = L"sin 4 over 5"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"sin45"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,FunctionTan) +{ + std::wstring wsString = L"tan{6 / 7}"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"tan67"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,FunctionCot) +{ + std::wstring wsString = L"cot(8 over 9)"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"cot89"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,FunctionSinh) +{ + std::wstring wsString = L"sinh 2 supset 3"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"sinh2\u22833"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,FunctionCosh) +{ + std::wstring wsString = L"cosh 2 + 3"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"cosh2+3"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,FunctionTanh) +{ + std::wstring wsString = L"tanh(11otimes12)"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"tanh11\u229712"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,FunctionCoth222) +{ + std::wstring wsString = L"coth222"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"coth222"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,FunctionArcsin) +{ + std::wstring wsString = L"arcsin{13 ominus 14}"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"arcsin13\u229614"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,FunctionArccos) +{ + std::wstring wsString = L"arccos{15 - 16}"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"arccos15-16"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,FunctionArctan) +{ + std::wstring wsString = L"arctan 17 over 18"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"arctan1718"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,FunctionArccot) +{ + std::wstring wsString = L"arccot 20 + 30"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"arccot20+30"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,FunctionArsinh) +{ + std::wstring wsString = L"{arsinh{2/3}} over sum from 1 to 5 10"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"arsinh231510"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,FunctionArcosh) +{ + std::wstring wsString = L"35 + 27 over {arcosh binom 23 78}"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"35+27arcosh2378"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,FunctionArtanhArcoth) +{ + std::wstring wsString = L"arcoth 30 subset {artanh 27}"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"arcoth30\u2282artanh27"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,MatrixBinom) +{ + std::wstring wsString = L"binom{2 over 7 supset 277}{arcoth 89}"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"27\u2283277arcoth89"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,MatrixMatrix) +{ + std::wstring wsString = L"matrix{2 / 8 -5 # sum from 2 over 10 union 3 to 10*10 100 ## cosh(10) # 2 oplus 10over100 }"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"28-5210\u22C3310*10100cosh102\u229510100"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,MatrixStack) +{ + std::wstring wsString = L"stack{2 over 10 # binom 2 3 # matrix{1 # 2 ## 3 # 4}}"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"210231234"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,IndexLower) +{ + std::wstring wsString = L"25 over 1 _ 2 "; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"2512"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,IndexUpper) +{ + std::wstring wsString = L"{binom {cos 5} 2 over 4 }^ 10"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"cos52410"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,IndexLsup) +{ + std::wstring wsString = L"{2 over 7} lsup binom 2+3 {cos 15}"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"2+3cos1527"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,IndexLsub) +{ + std::wstring wsString = L"2222^10 lsub 2 over 3"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"22222103"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,BracketWithIndexOverbrace) +{ + std::wstring wsString = L"color red size 16 {2/3} overbrace color navy size 18 stack{10 # 100 # 10 }"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"231010010"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,OperatorLllint) +{ + std::wstring wsString = L"color red bold lllint from color navy bold 2 over color crimson 10 to color green (2 color orange bold + 3) 100"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"2102+3100"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,BracketLdlineAttribute) +{ + std::wstring wsString = L"color green left ldline color navy bold 10 over color purple dot underline 100 color orange bold ital + 3 right rdline + ital bold 10"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"10100+3+10"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,Example11) +{ + std::wstring wsString = L"f(x) = sum from { n=0 } to { infinity } { {f^{(n)}(x_0) } over { fact{n} } (x-x_0)^n }"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"fx=n=0\u221Efnx0n\u0021x-x0n"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,AttributeGrade) +{ + std::wstring wsString = L"color green bold evaluate {E = color black m c^ color yellow 2} from {color crimson b over color teal a} to color navy overstrike infinity"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"E=mc2ba\u221E"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,Example2) +{ + std::wstring wsString = L"C = %pi cdot d = 2 cdot %pi cdot r"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString =L"C=\u03C0\u00B7d=2\u00B7\u03C0\u00B7r"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,Example3) +{ + std::wstring wsString = L"c = sqrt{ a^2 + b^2 }"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString =L"c=a2+b2"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,Example4) +{ + std::wstring wsString = L"vec F = m times vec a"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString =L"F=m\u00D7a"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,Example5) +{ + std::wstring wsString = L"E = m c^2"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString =L"E=mc2"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,Example6) +{ + std::wstring wsString = L"G_{%mu %nu} + %LAMBDA g_{%mu %nu}= frac{8 %pi G}{c^4} T_{%mu %nu}"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString =L"G\u03BC\u03BD+\u039Bg\u03BC\u03BD=8\u03C0Gc4T\u03BC\u03BD"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,Example8) +{ + std::wstring wsString = L"d over dt left( {partial L}over{partial dot q} right) = {partial L}over{partial q}"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString =L"ddt\u2202L\u2202q=\u2202L\u2202q"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,Example9) +{ + std::wstring wsString = L"int from a to b f'(x) dx = f(b) - f(a)"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString =L"abf'xdx=fb-fa"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,Example10) +{ + std::wstring wsString = L"ldline %delta bold{r}(t) rdline approx e^{%lambda t} ldline %delta { bold{r} }_0 rdline"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString =L"\u03B4rt\u2248e\u03BBt\u03B4r0"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,LimAndCsub) +{ + std::wstring wsString = L"{lim from 2 over 10 to 1 5} csub 244"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString =L"lim21015244"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,LimSupAndCsup) +{ + std::wstring wsString = L"limsup from 10 to 2 csup 10 100"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString =L"lim sup10210100"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,OverWithoutLeft) +{ + std::wstring wsString = L"over +- 2_10 5"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString =L"\u00B12105"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,Newline) +{ + std::wstring wsString = L"2 over 3 newline 10 csup 2 "; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"23102"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,IndexAndBinOp) +{ + std::wstring wsString = L"2 union 3^4 over 10"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"2\u22C33410"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,Example7) +{ + std::wstring wsString = L" %DELTA t' = { %DELTA t } over sqrt{ 1 - v^2 over c^2 }"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"\u0394t'=\u0394t1-v2c2"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,UnarySign) +{ + std::wstring wsString = L"3+6 over 9 newline -+5 over 10"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"3+69\u2213510"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,Example13) +{ + std::wstring wsString = L"nroot{3}{x^3-7x^2+14x-8}+sqrt{7/8+4/9+nroot{3}{sqrt{7/8+4/9}}}"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"3x3-7x2+14x-8+78+49+378+49"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,Example14) +{ + std::wstring wsString = L"sum_{i=0}^{infinity} {(-1)^i over (2i+1)} x^{2i+1} = sin(x)"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"i=0\u221E-1i2i+1x2i+1=sinx"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,Example15) +{ + std::wstring wsString = L"lim_{x->0} {sin(x) over x} = 1"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"limx\u27940sinxx=1"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,Example16) +{ + std::wstring wsString = L"int_0^{infinity} x^2 e^{-x} dx = 2"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"0\u221Ex2e-xdx=2"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,Example17) +{ + std::wstring wsString = L"{a^{2} over b} + {b^{2} over a} >= 2 sqrt{a b}"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"a2b+b2a\u22652ab"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,Example18) +{ + std::wstring wsString = L"10^1_2lsub5lsup4"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"541021"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,IndexWithColor) +{ + std::wstring wsString = L"bold 2 ^ 3 _4 lsup color blue 5 csub color red 6 csup 7 lsub 8"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"5867243"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,FunctionWithColor) +{ + std::wstring wsString = L"func e^ 7_2 lsup 10 2over3"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"10e2723"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,IncorrectSizeAndFontInput) +{ + std::wstring wsString = L"size font bolt ital 2"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"bolt2"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,IncorrectRGBColorInput) +{ + std::wstring wsString = L"color rgb 255 0 257 2 color rgb 10"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"2550257210"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,IncorrectHexColorInput) +{ + std::wstring wsString = L"color hex 161616FF RGB color hex 66 RGB color hex RGB color hex FFAACCFF RGB color hex 99112288FF0000 RGB "; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"RGBRGBRGBRGBRGB"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,IndexWithoutElement) +{ + std::wstring wsString = L"2^_3 "; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"23"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,Neg) +{ + std::wstring wsString = L"-1 neg 10 over 5 or 7"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"-1\u00AC105\u22287"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,Frac) +{ + std::wstring wsString = L"sum_{n=1}^{ infty} frac{1}{n^2} + frac{1}{n^3} = frac{ pi^2}{6} + zeta(3)"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"n=1\u221E1n2+1n3=pi26+zeta3"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,BracketIndexOnTopAndOperationOnSet) +{ + std::wstring wsString = L"3 + 10 over 5 setminus 1 overbrace 2"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"3+105\u221612"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,SqrtWithIndex) +{ + std::wstring wsString = L"sqrt{2}^{ log_2{8}} = 4"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"2log28=4"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,Binom) +{ + std::wstring wsString = L"binom 2 = 4 3 binom 2+1abc 5"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"2=432+1abc5"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,UnarySignWithColor) +{ + std::wstring wsString = L"color green [color red 2 color blue + 10 setminus color red 5 over 9 underbrace 3 ]"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"2+10\u2216593"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,rSubrSup) +{ + std::wstring wsString = L"2 rSub 20 1 rSup 28"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"220128"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,DifferentRegisters) +{ + std::wstring wsString = L"2 OvEr 10 unION 5"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"210\x22C35"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,Quotes) +{ + std::wstring wsString = L"\"2 + 3\" over 10 2 \"+\" 5 over 3"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"2 + 3102+53"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,NumberWithDot) +{ + std::wstring wsString = L"goal.25 over 100"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"goal.25100"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,OperatorWithoutValue) +{ + std::wstring wsString = L"lim_{x->5}"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"limx\u27945"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,MatrixWithDifferentValues) +{ + std::wstring wsString = L"matrix{2} matrix 2 matrix"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"22"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,StackWithDifferentValues) +{ + std::wstring wsString = L"stack stack{2} stack 2"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"22"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,Partial) +{ + std::wstring wsString = L"{partial f(x)} over { partial x } = ln(x) + tan^-1(x^2)"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"\u2202fx\u2202x=lnx+tan-1x2"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,LimWithArrow) +{ + std::wstring wsString = L"lim from { x->1^-"" }{ {x^{2}-1 } over { x-1 }} = 2 "; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"limx\u27941-x2-1x-1=2"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,FuctionWithAttributeAndIndex) +{ + std::wstring wsString = L"{%sigma' = %sigma color red bold func e ^ color blue frac 2 3 }"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"\u03C3'=\u03C3e23"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,UnarPlusMinus) +{ + std::wstring wsString = L"2 color red + - 4 over 10"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"2+-410"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +//TEST(SMConvectorTest,AttributeMatrix) +//{ +// std::wstring wsString = L""; +// StarMath::CParserStarMathString oTemp; +// StarMath::CConversionSMtoOOXML oTest; +// oTest.StartConversion(oTemp.Parse(wsString)); +// std::wstring wsXmlString = L""; +// EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +//} + + + + + diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp new file mode 100644 index 00000000000..39496d6ca46 --- /dev/null +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp @@ -0,0 +1,497 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#include "cconversionsmtoooxml.h" +#include "../../../../DesktopEditor/common/File.h" +#include +namespace StarMath { + CConversionSMtoOOXML::CConversionSMtoOOXML(): m_pXmlWrite(nullptr) + { + } + CConversionSMtoOOXML::~CConversionSMtoOOXML() + { + if (m_pXmlWrite) + delete m_pXmlWrite; + } + //check XMLWrite(if not nullptr == delete) + void CConversionSMtoOOXML::StartConversion(std::vector arPars, const unsigned int& iAlignment) + { + m_pXmlWrite = new XmlUtils::CXmlWriter; + if(!arPars.empty()) + { + std::wstring wsNodeMath(L"m:oMath"),wsNodeMathPara(L"m:oMathPara"),wsAlignment; + switch(iAlignment) + { + case 0: + wsAlignment = L"left"; + break; + case 1: + wsAlignment = L"center"; + break; + case 2: + wsAlignment = L"right"; + break; + default: + wsAlignment = L"center"; + break; + } + if(arPars[0]->GetTypeConversion() == TypeConversion::pptx || arPars[0]->GetTypeConversion() == TypeConversion::xlsx) + { + wsNodeMath += L" xmlns:m=\"http://schemas.openxmlformats.org/officeDocument/2006/math\""; + wsNodeMathPara += L" xmlns:m=\"http://schemas.openxmlformats.org/officeDocument/2006/math\""; + wsAlignment += L"Group"; + } + m_pXmlWrite->WriteNodeBegin(wsNodeMathPara,false); + if(iAlignment>= 0 && iAlignment <= 2) + { + m_pXmlWrite->WriteNodeBegin(L"m:oMathParaPr",false); + m_pXmlWrite->WriteNodeBegin(L"m:jc",true); + m_pXmlWrite->WriteAttribute(L"m:val",wsAlignment); + m_pXmlWrite->WriteNodeEnd(L"",true,true); + m_pXmlWrite->WriteNodeEnd(L"m:oMathParaPr",false,false); + } + m_pXmlWrite->WriteNodeBegin(wsNodeMath,false); + for(CElement* oTempElement:arPars) + { + if(oTempElement != nullptr) + { + if(CParserStarMathString::CheckNewline(oTempElement)) + { + m_pXmlWrite->WriteNodeBegin(L"m:r",false); + m_pXmlWrite->WriteNodeBegin(L"w:br",true); + m_pXmlWrite->WriteNodeEnd(L"",true,true); + m_pXmlWrite->WriteNodeEnd(L"m:r",false,false); + m_pXmlWrite->WriteNodeEnd(L"m:oMath",false,false); + m_pXmlWrite->WriteNodeBegin(L"m:oMath",false); + } + else + oTempElement->ConversionToOOXML(m_pXmlWrite); + } + } + } + else + { + m_pXmlWrite->WriteNodeBegin(L"m:oMathPara",false); + m_pXmlWrite->WriteNodeBegin(L"m:oMath",false); + } + m_pXmlWrite->WriteNodeEnd(L"m:oMath",false,false); + m_pXmlWrite->WriteNodeEnd(L"m:oMathPara",false,false); + } + void CConversionSMtoOOXML::StandartProperties(XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute,const TypeConversion &enTypeConversion) + { + if(TypeConversion::docx == enTypeConversion || TypeConversion::undefine == enTypeConversion) + { + if(pAttribute == nullptr) + { + pXmlWrite->WriteNodeBegin(L"w:rPr",false); + pXmlWrite->WriteNodeBegin(L"w:rFonts",true); + pXmlWrite->WriteAttribute(L"w:hAnsi",L"Cambria Math"); + pXmlWrite->WriteAttribute(L"w:ascii",L"Cambria Math"); + pXmlWrite->WriteNodeEnd(L"w",true,true); + pXmlWrite->WriteNodeBegin(L"w:sz",true); + pXmlWrite->WriteAttribute(L"w:val",L"30"); + pXmlWrite->WriteNodeEnd(L"w",true,true); + pXmlWrite->WriteNodeBegin(L"w:szCs",true); + pXmlWrite->WriteAttribute(L"w:val",L"30"); + pXmlWrite->WriteNodeEnd(L"w",true,true); + pXmlWrite->WriteNodeEnd(L"w:rPr",false,false); + } + else + { + std::wstring wsNameFont = pAttribute->GetFontName(); + pXmlWrite->WriteNodeBegin(L"w:rPr",false); + pXmlWrite->WriteNodeBegin(L"w:rFonts",true); + if(!wsNameFont.empty()) + { + pXmlWrite->WriteAttribute(L"w:hAnsi",wsNameFont); + pXmlWrite->WriteAttribute(L"w:ascii",wsNameFont); + } + else + { + pXmlWrite->WriteAttribute(L"w:hAnsi",L"Cambria Math"); + pXmlWrite->WriteAttribute(L"w:ascii",L"Cambria Math"); + } + pXmlWrite->WriteNodeEnd(L"w",true,true); + if(pAttribute->GetSize() == 0) + { + pXmlWrite->WriteNodeBegin(L"w:sz",true); + pXmlWrite->WriteAttribute(L"w:val",L"30"); + pXmlWrite->WriteNodeEnd(L"w",true,true); + pXmlWrite->WriteNodeBegin(L"w:szCs",true); + pXmlWrite->WriteAttribute(L"w:val",L"30"); + pXmlWrite->WriteNodeEnd(L"w",true,true); + } + else if(pAttribute->GetSize() != 0) + { + pXmlWrite->WriteNodeBegin(L"w:sz",true); + pXmlWrite->WriteAttribute(L"w:val",std::to_wstring(pAttribute->GetSize())); + pXmlWrite->WriteNodeEnd(L"w",true,true); + pXmlWrite->WriteNodeBegin(L"w:szCs",true); + pXmlWrite->WriteAttribute(L"w:val",std::to_wstring(pAttribute->GetSize())); + pXmlWrite->WriteNodeEnd(L"w",true,true); + } + if(!pAttribute->EmptyColor()) + { + pXmlWrite->WriteNodeBegin(L"w:color",true); + pXmlWrite->WriteAttribute(L"w:val",pAttribute->GetColor()); + pXmlWrite->WriteNodeEnd(L"w",true,true); + } + if(pAttribute->GetBold() && pAttribute->GetItal()) + { + WriteStyNode(pXmlWrite,L"bi"); + } + else if(pAttribute->GetBold()) + { + pXmlWrite->WriteNodeBegin(L"m:sty", true); + pXmlWrite->WriteAttribute(L"m:val",L"b"); + pXmlWrite->WriteNodeEnd(L"w",true,true); + pXmlWrite->WriteNodeBegin(L"w:b",true); + pXmlWrite->WriteNodeEnd(L"w",true,true); + pXmlWrite->WriteNodeBegin(L"w:bCs",true); + pXmlWrite->WriteNodeEnd(L"w",true,true); + } + else if(pAttribute->GetItal()) + { + pXmlWrite->WriteNodeBegin(L"w:i",true); + pXmlWrite->WriteNodeEnd(L"w",true,true); + } + if(pAttribute->GetStrike()) + { + pXmlWrite->WriteNodeBegin(L"w:strike",true); + pXmlWrite->WriteNodeEnd(L"w",true,true); + } + pXmlWrite->WriteNodeEnd(L"w:rPr",false,false); + } + } + else if(TypeConversion::pptx == enTypeConversion || TypeConversion::xlsx == enTypeConversion) + { + if(pAttribute !=nullptr) + { + pXmlWrite->WriteNodeBegin(L"a:rPr",true); + if(pAttribute->GetSize()!=0) + { + int iSize = pAttribute->GetSize(); + iSize = iSize*50; + pXmlWrite->WriteAttribute(L"sz",iSize); + } + else + pXmlWrite->WriteAttribute(L"sz",L"1500"); + if(pAttribute->GetBold()) + pXmlWrite->WriteAttribute(L"b",L"1"); + if(pAttribute->GetItal()) + pXmlWrite->WriteAttribute(L"i",L"1"); + if(pAttribute->GetStrike()) + pXmlWrite->WriteAttribute(L"strike",L"sngStrike"); + pXmlWrite->WriteAttribute(L"spc", -150); + pXmlWrite->WriteNodeEnd(L"w",true,false); + if(!pAttribute->GetColor().empty()) + { + pXmlWrite->WriteNodeBegin(L"a:solidFill",false); + pXmlWrite->WriteNodeBegin(L"a:srgbClr",true); + pXmlWrite->WriteAttribute(L"val",pAttribute->GetColor()); + pXmlWrite->WriteNodeEnd(L"w",true,true); + pXmlWrite->WriteNodeEnd(L"a:solidFill",false,false); + } + pXmlWrite->WriteNodeBegin(L"a:latin",true); + if(!pAttribute->GetFontName().empty()) + pXmlWrite->WriteAttribute(L"typeface",pAttribute->GetFontName()); + else + pXmlWrite->WriteAttribute(L"typeface",L"Cambria Math"); + pXmlWrite->WriteNodeEnd(L"w",true,true); + pXmlWrite->WriteNodeEnd(L"a:rPr",false); + } + else + { + pXmlWrite->WriteNodeBegin(L"a:rPr",true); + pXmlWrite->WriteAttribute(L"sz",L"1500"); + pXmlWrite->WriteNodeEnd(L"w",true,false); + pXmlWrite->WriteNodeBegin(L"a:latin",true); + pXmlWrite->WriteAttribute(L"typeface",L"Cambria Math"); + pXmlWrite->WriteNodeEnd(L"w",true,true); + pXmlWrite->WriteNodeEnd(L"a:rPr",false); + } + } + } + void CConversionSMtoOOXML::PropertiesMFPR(const std::wstring &wsType, XmlUtils::CXmlWriter* pXmlWrite, CAttribute* pAttribute, const TypeConversion &enTypeConversion) + { + pXmlWrite->WriteNodeBegin(L"m:fPr",false); + if(!wsType.empty()) + { + pXmlWrite->WriteNodeBegin(L"m:type",true); + pXmlWrite->WriteAttribute(L"m:val",wsType); + pXmlWrite->WriteNodeEnd(L"w",true,true); + } + WriteCtrlPrNode(pXmlWrite,pAttribute,enTypeConversion); + pXmlWrite->WriteNodeEnd(L"m:fPr",false,false); + } + void CConversionSMtoOOXML::PropertiesNaryPr(const TypeElement& enTypeOp,bool bEmptySub,bool bEmptySup,XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute,const TypeConversion &enTypeConversion) + { + pXmlWrite->WriteNodeBegin(L"m:naryPr",false); + switch(enTypeOp) + { + case TypeElement::sum: + { + WriteChrNode(L"\u2211",pXmlWrite); + break; + } + case TypeElement::prod: + WriteChrNode(L"\u220F",pXmlWrite); + break; + case TypeElement::coprod: + WriteChrNode(L"\u2210",pXmlWrite); + break; + case TypeElement::iint: + WriteChrNode(L"\u222C",pXmlWrite); + break; + case TypeElement::iiint: + WriteChrNode(L"\u222D",pXmlWrite); + break; + case TypeElement::lint: + WriteChrNode(L"\u222E",pXmlWrite); + break; + case TypeElement::llint: + WriteChrNode(L"\u222F",pXmlWrite); + break; + case TypeElement::lllint: + WriteChrNode(L"\u2230",pXmlWrite); + break; + default: + break; + } + WriteLimLocNode(L"undOvr",pXmlWrite); + if(bEmptySub) + { + pXmlWrite->WriteNodeBegin(L"m:subHide",true); + pXmlWrite->WriteAttribute(L"m:val",L"1"); + pXmlWrite->WriteNodeEnd(L"w",true,true); + } + if(bEmptySup) + { + pXmlWrite->WriteNodeBegin(L"m:supHide",true); + pXmlWrite->WriteAttribute(L"m:val",L"1"); + pXmlWrite->WriteNodeEnd(L"w",true,true); + } + WriteCtrlPrNode(pXmlWrite,pAttribute,enTypeConversion); + pXmlWrite->WriteNodeEnd(L"m:naryPr",false,false); + } + void CConversionSMtoOOXML::WriteNodeConversion(const std::wstring &wsNameBlock, CElement *pValueBlock,XmlUtils::CXmlWriter* pXmlWrite) + { + if(pValueBlock != nullptr) + { + pXmlWrite->WriteNodeBegin(wsNameBlock,false); + pValueBlock->ConversionToOOXML(pXmlWrite); + pXmlWrite->WriteNodeEnd(wsNameBlock,false,false); + } + else + { + pXmlWrite->WriteNodeBegin(wsNameBlock,true); + pXmlWrite->WriteNodeEnd(L"",true,true); + } + } + std::wstring CConversionSMtoOOXML::GetOOXML() + { + return m_pXmlWrite->GetXmlString(); + } + void CConversionSMtoOOXML::EndConversion() + { + m_pXmlWrite->WriteNodeEnd(L"m:oMath",false,false); + m_pXmlWrite->WriteNodeEnd(L"m:oMathPara",false,false); + } + void CConversionSMtoOOXML::PropertiesFuncPr(XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute,const TypeConversion &enTypeConversion) + { + pXmlWrite->WriteNodeBegin(L"m:funcPr", false); + pXmlWrite->WriteNodeBegin(L"m:ctrlPr", false); + StandartProperties(pXmlWrite,pAttribute,enTypeConversion); + pXmlWrite->WriteNodeEnd(L"m:ctrlPr", false,false); + pXmlWrite->WriteNodeEnd(L"m:funcPr",false,false); + } + + void CConversionSMtoOOXML::PropertiesDPr(XmlUtils::CXmlWriter *pXmlWrite, const std::wstring &wsOpenBracket,const std::wstring &wsCloseBracket, CAttribute* pAttribute, const TypeConversion &enTypeConversion, const TypeElement &enTypeBracket) + { + pXmlWrite->WriteNodeBegin(L"m:dPr",false); + BracketTypeNotation(wsOpenBracket,wsCloseBracket,pXmlWrite); + pXmlWrite->WriteNodeBegin(L"m:ctrlPr"); + StandartProperties(pXmlWrite,pAttribute,enTypeConversion); + pXmlWrite->WriteNodeEnd(L"m:ctrlPr",false,false); + pXmlWrite->WriteNodeEnd(L"m:dPr",false,false); + } + void CConversionSMtoOOXML::BracketTypeNotation(const std::wstring &wsOpenBracket, const std::wstring &wsCloseBracket, XmlUtils::CXmlWriter *pXmlWrite) + { + if(!wsOpenBracket.empty()) + { + pXmlWrite->WriteNodeBegin(L"m:begChr", true); + if(wsOpenBracket == L"none") + pXmlWrite->WriteAttribute(L"m:val",L""); + else + pXmlWrite->WriteAttribute(L"m:val",wsOpenBracket); + pXmlWrite->WriteNodeEnd(L"w",true,true); + } + if(!wsCloseBracket.empty()) + { + pXmlWrite->WriteNodeBegin(L"m:endChr", true); + if(wsCloseBracket == L"none") + pXmlWrite->WriteAttribute(L"m:val",L""); + else + pXmlWrite->WriteAttribute(L"m:val", wsCloseBracket); + pXmlWrite->WriteNodeEnd(L"w",true,true); + } + } + void CConversionSMtoOOXML::PropertiesMPr(XmlUtils::CXmlWriter *pXmlWrite, const TypeElement &enTypeMatrix, CAttribute* pAttribute, const TypeConversion &enTypeConversion, const unsigned int &iDimension) + { + pXmlWrite->WriteNodeBegin(L"m:mPr",false); + pXmlWrite->WriteNodeBegin(L"m:mcs",false); + pXmlWrite->WriteNodeBegin(L"m:mc",false); + pXmlWrite->WriteNodeBegin(L"m:mcPr",false); + pXmlWrite->WriteNodeBegin(L"m:count",true); + const std::wstring wsNumber = std::to_wstring(iDimension); + pXmlWrite->WriteAttribute(L"m:val",wsNumber); + pXmlWrite->WriteNodeEnd(L"w",true,true); + pXmlWrite->WriteNodeBegin(L"m:mcJc",true); + pXmlWrite->WriteAttribute(L"m:val",L"center"); + pXmlWrite->WriteNodeEnd(L"w",true,true); + pXmlWrite->WriteNodeEnd(L"m:mcPr",false,false); + pXmlWrite->WriteNodeEnd(L"m:mc",false,false); + pXmlWrite->WriteNodeEnd(L"m:mcs",false,false); + pXmlWrite->WriteNodeBegin(L"m:ctrlPr",false); + StandartProperties(pXmlWrite,pAttribute,enTypeConversion); + pXmlWrite->WriteNodeEnd(L"m:ctrlPr",false,false); + pXmlWrite->WriteNodeEnd(L"m:mPr",false,false); + } + void CConversionSMtoOOXML::NodeGrade(XmlUtils::CXmlWriter *pXmlWrite,CElement* pValueGrade,CAttribute* pAttribute) + { + pXmlWrite->WriteNodeBegin(L"m:d",false); + pXmlWrite->WriteNodeBegin(L"m:dPr",false); + pXmlWrite->WriteNodeBegin(L"m:begChr",true); + pXmlWrite->WriteAttribute(L"m:val",L""); + pXmlWrite->WriteNodeEnd(L"w",true,true); + pXmlWrite->WriteNodeBegin(L"m:endChr",true); + pXmlWrite->WriteAttribute(L"m:val",L"\u23AA"); + pXmlWrite->WriteNodeEnd(L"w",true,true); + pXmlWrite->WriteNodeBegin(L"m:ctrlPr",false); + StandartProperties(pXmlWrite,pAttribute,pValueGrade->GetTypeConversion()); + pXmlWrite->WriteNodeEnd(L"m:ctrlPr",false); + pXmlWrite->WriteNodeEnd(L"m:dPr",false,false); + CConversionSMtoOOXML::WriteNodeConversion(L"m:e",pValueGrade,pXmlWrite); + pXmlWrite->WriteNodeEnd(L"m:d",false,false); + } + void CConversionSMtoOOXML::WriteCtrlPrNode(XmlUtils::CXmlWriter *pXmlWrite, CAttribute *pAttribute,const TypeConversion &enTypeConversion) + { + pXmlWrite->WriteNodeBegin(L"m:ctrlPr",false); + StandartProperties(pXmlWrite,pAttribute,enTypeConversion); + pXmlWrite->WriteNodeEnd(L"m:ctrlPr",false,false); + } + void CConversionSMtoOOXML::WriteChrNode(const std::wstring &wsTypeOp,XmlUtils::CXmlWriter* pXmlWrite) + { + pXmlWrite->WriteNodeBegin(L"m:chr",true); + pXmlWrite->WriteAttribute(L"m:val",wsTypeOp); + pXmlWrite->WriteNodeEnd(L"w",true,true); + } + void CConversionSMtoOOXML::WriteLimLocNode(const std::wstring &wsTypeLimLock,XmlUtils::CXmlWriter* pXmlWrite) + { + pXmlWrite->WriteNodeBegin(L"m:limLoc",true); + pXmlWrite->WriteAttribute(L"m:val",wsTypeLimLock); + pXmlWrite->WriteNodeEnd(L"w",true,true); + } + void CConversionSMtoOOXML::WriteRPrFName(const TypeElement &enTypeOp, XmlUtils::CXmlWriter *pXmlWrite,CAttribute* pAttribute,const std::wstring& wsNameOp,const TypeConversion &enTypeConversion) + { + pXmlWrite->WriteNodeBegin(L"m:r",false); + pXmlWrite->WriteNodeBegin(L"m:rPr",false); + pXmlWrite->WriteNodeBegin(L"m:sty",true); + pXmlWrite->WriteAttribute(L"m:val",L"p"); + pXmlWrite->WriteNodeEnd(L"w",true,true); + pXmlWrite->WriteNodeEnd(L"m:rPr",false,false); + CConversionSMtoOOXML::StandartProperties(pXmlWrite,pAttribute,enTypeConversion); + pXmlWrite->WriteNodeBegin(L"m:t",false); + switch(enTypeOp) + { + case TypeElement::lim: + pXmlWrite->WriteString(L"lim"); + break; + case TypeElement::liminf: + pXmlWrite->WriteString(L"lim inf"); + break; + case TypeElement::limsup: + pXmlWrite->WriteString(L"lim sup"); + break; + case TypeElement::oper: + pXmlWrite->WriteString(wsNameOp); + break; + default: + break; + } + pXmlWrite->WriteNodeEnd(L"m:t",false,false); + pXmlWrite->WriteNodeEnd(L"m:r",false,false); + } + void CConversionSMtoOOXML::WriteStyNode(XmlUtils::CXmlWriter *pXmlWrite, const std::wstring &wsAttributeNode) + { + pXmlWrite->WriteNodeBegin(L"m:sty", true); + pXmlWrite->WriteAttribute(L"m:val",wsAttributeNode); + pXmlWrite->WriteNodeEnd(L"w",true,true); + } + void CConversionSMtoOOXML::WritePreserveBlock(XmlUtils::CXmlWriter *pXmlWrite,CAttribute* pAttribute,const TypeConversion &enTypeConversion) + { + pXmlWrite->WriteNodeBegin(L"m:r",false); + StandartProperties(pXmlWrite,pAttribute,enTypeConversion); + pXmlWrite->WriteNodeBegin(L"m:t",true); + pXmlWrite->WriteAttribute(L"xml:space",L"preserve"); + pXmlWrite->WriteNodeEnd(L"w",true,false); + pXmlWrite->WriteNodeEnd(L"m:t",false,false); + pXmlWrite->WriteNodeEnd(L"m:r",false,false); + } + void CConversionSMtoOOXML::WriteLimUpOrLowNode(XmlUtils::CXmlWriter *pXmlWrite, const std::wstring& wsNameNode, CElement* pValue, const TypeElement& enType, CAttribute* pAttribute, const TypeConversion &enTypeConvers, const std::wstring& wsName, CElement* pIndex) + { + pXmlWrite->WriteNodeBegin(wsNameNode,false); + pXmlWrite->WriteNodeBegin(wsNameNode+L"Pr",false); + CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,nullptr,enTypeConvers); + pXmlWrite->WriteNodeEnd(wsNameNode+L"Pr",false,false); + pXmlWrite->WriteNodeBegin(L"m:e",false); + CConversionSMtoOOXML::WriteRPrFName(enType,pXmlWrite,pAttribute,wsName,enTypeConvers); + pXmlWrite->WriteNodeEnd(L"m:e",false,false); + if(pValue!= nullptr && pIndex != nullptr) + { + pXmlWrite->WriteNodeBegin(L"m:lim",false); + pIndex->ConversionToOOXML(pXmlWrite); + pValue->ConversionToOOXML(pXmlWrite); + pXmlWrite->WriteNodeEnd(L"m:lim",false,false); + } + else if(pValue!=nullptr && pIndex == nullptr) + WriteNodeConversion(L"m:lim",pValue,pXmlWrite); + else if(pValue == nullptr && pIndex !=nullptr) + WriteNodeConversion(L"m:lim",pIndex,pXmlWrite); + pXmlWrite->WriteNodeEnd(wsNameNode,false,false); + } + void CConversionSMtoOOXML::ElementConversion(XmlUtils::CXmlWriter *pXmlWrite, CElement *pElement) + { + if(pElement!= nullptr) + pElement->ConversionToOOXML(pXmlWrite); + } +} + diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h new file mode 100644 index 00000000000..f267e042797 --- /dev/null +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h @@ -0,0 +1,69 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ + +#ifndef CCONVERSIONSMTOOOXML_H +#define CCONVERSIONSMTOOOXML_H +#include "cstarmathpars.h" +#include "../../../../DesktopEditor/xml/include/xmlwriter.h" + +namespace StarMath { +//delete XmlWrite + class CConversionSMtoOOXML + { + public: + CConversionSMtoOOXML(); + ~CConversionSMtoOOXML(); + void StartConversion(std::vector arPars, const unsigned int& iAlignment = 1); + static void StandartProperties(XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute,const TypeConversion& enTypeConversion); + static void PropertiesMFPR(const std::wstring& wsType,XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute,const TypeConversion &enTypeConversion); + static void PropertiesNaryPr(const TypeElement& enTypeOp,bool bEmptySub,bool bEmptySup,XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute,const TypeConversion &enTypeConversion); + static void PropertiesFuncPr(XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute,const TypeConversion &enTypeConversion); + static void WriteNodeConversion(const std::wstring& wsNameBlock,CElement* pValueBlock,XmlUtils::CXmlWriter* pXmlWrite); + static void PropertiesDPr(XmlUtils::CXmlWriter* pXmlWrite,const std::wstring& wsOpenBracket,const std::wstring& wsCloseBracket,CAttribute* pAttribute,const TypeConversion &enTypeConversion,const TypeElement& enTypeBracket); + static void PropertiesMPr(XmlUtils::CXmlWriter* pXmlWrite,const TypeElement& enTypeMatrix,CAttribute* pAttribute,const TypeConversion &enTypeConversion,const unsigned int& iDimension); + static void NodeGrade(XmlUtils::CXmlWriter* pXmlWrite,CElement* pValueGrade,CAttribute* pAttribute); + static void WriteCtrlPrNode(XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute,const TypeConversion &enTypeConversion); + static void WriteChrNode(const std::wstring& wsTypeOp,XmlUtils::CXmlWriter* pXmlWrite); + static void WriteLimLocNode(const std::wstring& wsTypeLimLock,XmlUtils::CXmlWriter* pXmlWrite); + static void WriteRPrFName(const TypeElement& enTypeOp,XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute,const std::wstring& wsNameOp,const TypeConversion &enTypeConversion); + static void WriteStyNode(XmlUtils::CXmlWriter* pXmlWrite,const std::wstring& wsAttributeNode); + static void WritePreserveBlock(XmlUtils::CXmlWriter* pXmlWrite, CAttribute *pAttribute,const TypeConversion &enTypeConversion); + static void WriteLimUpOrLowNode(XmlUtils::CXmlWriter* pXmlWrite,const std::wstring& wsNameNode,CElement* pValue,const TypeElement& enType,CAttribute* pAttribute,const TypeConversion& enTypeConvers, const std::wstring& wsName = L"oper",CElement* pIndex = nullptr); + static void ElementConversion(XmlUtils::CXmlWriter* pXmlWrite,CElement* pElement); + void EndConversion(); + std::wstring GetOOXML(); + private: + static void BracketTypeNotation(const std::wstring& wsOpenBracket,const std::wstring& wsCloseBracket, XmlUtils::CXmlWriter* pXmlWrite); + XmlUtils::CXmlWriter* m_pXmlWrite; + }; +} +#endif // CCONVERSIONSMTOOOXML_H diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cooxml2odf.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/cooxml2odf.cpp new file mode 100644 index 00000000000..db5806bbcc8 --- /dev/null +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cooxml2odf.cpp @@ -0,0 +1,2317 @@ +#include "cooxml2odf.h" +#include + +namespace StarMath +{ +//class OOXml2Odf + COOXml2Odf::COOXml2Odf() + { + m_pXmlWrite = new XmlUtils::CXmlWriter; + } + COOXml2Odf::~COOXml2Odf() + { + delete m_pXmlWrite; + } + void COOXml2Odf::StartConversion(OOX::WritingElement *pNode) + { + m_pXmlWrite->WriteNodeBegin(L"math",true); + m_pXmlWrite->WriteAttribute(L"xmlns",L"http:\/\/www.w3.org/1998/Math/MathML"); + m_pXmlWrite->WriteAttribute(L"display",L"block"); + m_pXmlWrite->WriteNodeEnd(L"w",true,false); + m_pXmlWrite->WriteNodeBegin(L"semantics",false); + if(pNode == nullptr) + { + m_pXmlWrite->WriteNodeBegin(L"annotation",false); + EndOdf(); + return; + } + else + NodeDefinition(pNode); + m_wsSemantic = m_pXmlWrite->GetXmlString(); + m_pXmlWrite->WriteNodeBegin(L"annotation",true); + m_pXmlWrite->WriteAttribute(L"encoding",L"StarMath 5.0"); + m_pXmlWrite->WriteNodeEnd(L"w",true,false); + m_pXmlWrite->WriteString(m_wsAnnotationStarMath); + EndOdf(); + } + void COOXml2Odf::NodeDefinition(OOX::WritingElement *pNode,const bool& bMatrix) + { + if(pNode == nullptr) + return; + switch(pNode->getType()) + { + case OOX::EElementType::et_m_oMath: + { + ConversionMath(dynamic_cast(pNode)); + break; + } + case OOX::EElementType::et_m_rad: + { + ConversionRad(dynamic_cast(pNode)); + break; + } + case OOX::EElementType::et_m_f: + { + ConversionMF(dynamic_cast(pNode)); + break; + } + case OOX::EElementType::et_m_d: + { + ConversionMd(dynamic_cast(pNode)); + break; + } + case OOX::EElementType::et_m_nary: + { + ConversionNary(dynamic_cast(pNode)); + break; + } + case OOX::EElementType::et_m_oMathPara: + { + ConversionMathPara(dynamic_cast(pNode)); + break; + } + case OOX::EElementType::et_m_acc: + { + ConversionAcc(dynamic_cast(pNode)); + break; + } + case OOX::EElementType::et_m_box: + { + ConversionBox(dynamic_cast(pNode)); + break; + } + case OOX::EElementType::et_m_m: + { + ConversionMatrix(dynamic_cast(pNode)); + break; + } + case OOX::EElementType::et_m_e: + { + ConversionElement(dynamic_cast(pNode)); + break; + } + case OOX::EElementType::et_m_groupChr: + { + ConversionGroupChr(dynamic_cast(pNode)); + break; + } + case OOX::EElementType::et_m_bar: + { + ConversionBar(dynamic_cast(pNode)); + break; + } + case OOX::EElementType::et_m_sPre: + { + ConversionSPre(dynamic_cast(pNode)); + break; + } + case OOX::EElementType::et_m_sSub: + { + ConversionSsub(dynamic_cast(pNode)); + break; + } + case OOX::EElementType::et_m_sSup: + { + ConversionSsup(dynamic_cast(pNode)); + break; + } + case OOX::EElementType::et_m_eqArr: + { + ConversionEqArr(dynamic_cast(pNode)); + break; + } + case OOX::EElementType::et_m_limLow: + { + ConversionLimLow(dynamic_cast(pNode)); + break; + } + case OOX::EElementType::et_m_limUpp: + { + ConversionLimUpp(dynamic_cast(pNode)); + break; + } + case OOX::EElementType::et_m_func: + { + ConversionFunc(dynamic_cast(pNode)); + break; + } + case OOX::EElementType::et_m_sSubSup: + { + ConversionSubSup(dynamic_cast(pNode)); + break; + } + default: + break; + } + } + void COOXml2Odf::ConversionMath(OOX::Logic::COMath *pMath) + { + if(pMath == nullptr) + return; + bool bMrow(false); + if(pMath->m_arrItems.size() > 1) + { + bMrow = true; + m_pXmlWrite->WriteNodeBegin(L"mrow",false); + } + ConversionVectorWritingElement(pMath->m_arrItems); + if(bMrow == true) + m_pXmlWrite->WriteNodeEnd(L"mrow",false,false); + } + void COOXml2Odf::ConversionMathPara(OOX::Logic::COMathPara *pMathPara) + { + if(pMathPara == nullptr) + return; + bool bNewLine(false); + if(pMathPara->m_arrItems.size() > 1) + { + bNewLine = true; + m_pXmlWrite->WriteNodeBegin(L"mtable",false); + m_pXmlWrite->WriteNodeBegin(L"mtr",false); + m_pXmlWrite->WriteNodeBegin(L"mtd",false); + } + for(unsigned int i = 0; i < pMathPara->m_arrItems.size();i++) + { + switch (i) + { + case 0: + break; + case 1: + { + if(pMathPara->m_arrItems[0]->getType() != OOX::EElementType::et_m_oMathParaPr) + { + m_wsAnnotationStarMath += L"newline "; + m_pXmlWrite->WriteNodeEnd(L"mtd",false,false); + m_pXmlWrite->WriteNodeEnd(L"mtr",false,false); + m_pXmlWrite->WriteNodeBegin(L"mtr",false); + m_pXmlWrite->WriteNodeBegin(L"mtd",false); + } + break; + } + default: + { + m_wsAnnotationStarMath += L"newline "; + m_pXmlWrite->WriteNodeEnd(L"mtd",false,false); + m_pXmlWrite->WriteNodeEnd(L"mtr",false,false); + m_pXmlWrite->WriteNodeBegin(L"mtr",false); + m_pXmlWrite->WriteNodeBegin(L"mtd",false); + break; + } + } + NodeDefinition(pMathPara->m_arrItems[i]); + } + if(bNewLine) + { + m_pXmlWrite->WriteNodeEnd(L"mtd",false,false); + m_pXmlWrite->WriteNodeEnd(L"mtr",false,false); + m_pXmlWrite->WriteNodeEnd(L"mtable",false,false); + } + } + std::vector COOXml2Odf::ConversionMT(OOX::Logic::CMText *pMt, const StValuePr* pValue, const bool& bMRpr) + { + std::vector arLine; + if(pMt == nullptr) + return arLine; + std::wstring wsText = pMt->m_sText,wsElement,wsTextUTF16; + wsTextUTF16 = COOXml2Odf::TransformationUTF32(pMt->m_sText); + std::wstring::iterator itStart = wsTextUTF16.begin(),itEnd = wsTextUTF16.end(); + COneElement* pRightTempElement = nullptr; + while(itStart != itEnd) + { + COneElement* pTempElement; + if(pRightTempElement == nullptr) + { + wsElement = ParsingText(itStart,itEnd); + pTempElement = COneElement::CreateElement(wsElement); + } + else + { + pTempElement = pRightTempElement; + pRightTempElement = nullptr; + } + if(pTempElement != nullptr) + { + if(pTempElement->GetType() == TypeElement::BinOperator) + { + CBinOperator* pBinOp = dynamic_cast(pTempElement); + pBinOp->Parse(itStart,itEnd,pRightTempElement); + if(!arLine.empty() && pBinOp->GetTypeBinOp() != TypeElement::neg) + { + if(CBinOperator::CheckRightArg(arLine.back()) && !CBinOperator::UnaryCheck(pValue,pBinOp->GetTypeBinOp())) + { + pBinOp->SetLeftArg(arLine.back()); + arLine.pop_back(); + } + } + } + else if(pTempElement->GetType() == TypeElement::Connection) + { + CRelationsAndOperationsOnSets* pRelation = dynamic_cast(pTempElement); + pRelation->Parse(itStart,itEnd,pRightTempElement); + if(!arLine.empty() && CBinOperator::CheckRightArg(arLine.back())) + { + pRelation->SetLeftArg(arLine.back()); + arLine.pop_back(); + } + } + arLine.push_back(pTempElement); + } + } + return arLine; + } + std::wstring COOXml2Odf::ParsingText(std::wstring::iterator &itStart, std::wstring::iterator &itEnd) + { + std::wstring wsElement; + for(;itStart != itEnd;itStart++) + { + if(iswspace(*itStart)) + if(!wsElement.empty()) + return wsElement; + else + { + itStart++; + return L" "; + } + else if(iswdigit(*itStart)) + if(!wsElement.empty()) + { + if(iswdigit(wsElement.back())) + wsElement.push_back(*itStart); + else + return wsElement; + } + else + wsElement.push_back(*itStart); + else if(iswalpha(*itStart)) + if(!wsElement.empty()) + { + if(iswalpha(wsElement.back())) + wsElement.push_back(*itStart); + else + return wsElement; + } + else + wsElement.push_back(*itStart); + else if(wsElement.empty()) + { + wsElement.push_back(*itStart); + itStart++; + return wsElement; + } + else + return wsElement; + } + if(!wsElement.empty()) + return wsElement; + else return L""; + } + void COOXml2Odf::ConversionMF(OOX::Logic::CFraction *pMf) + { + if(pMf == nullptr) + return; + StValuePr stPr = ConversionFpr(dynamic_cast(pMf->m_oFPr.GetPointer())); + if(stPr.m_wsTypeName == L"noBar") + { + m_wsAnnotationStarMath += L"binom "; + m_pXmlWrite->WriteNodeBegin(L"mtable",false); + m_pXmlWrite->WriteNodeBegin(L"mtr",false); + m_pXmlWrite->WriteNodeBegin(L"mtd",false); + m_wsAnnotationStarMath += L"{ "; + ConversionVectorWritingElement(pMf->m_oNum.GetPointer()->m_arrItems); + m_wsAnnotationStarMath += L"} "; + m_pXmlWrite->WriteNodeEnd(L"mtd",false,false); + m_pXmlWrite->WriteNodeEnd(L"mtr",false,false); + m_pXmlWrite->WriteNodeBegin(L"mtr",false); + m_pXmlWrite->WriteNodeBegin(L"mtd",false); + m_wsAnnotationStarMath += L"{ "; + ConversionVectorWritingElement(pMf->m_oDen.GetPointer()->m_arrItems); + m_wsAnnotationStarMath += L"} "; + m_pXmlWrite->WriteNodeEnd(L"mtd",false,false); + m_pXmlWrite->WriteNodeEnd(L"mtr",false,false); + m_pXmlWrite->WriteNodeEnd(L"mtable",false,false); + } + else if(stPr.m_wsTypeName != L"lin") + { + m_pXmlWrite->WriteNodeBegin(L"mfrac",true); + if(stPr.m_wsTypeName == L"skw") + { + m_pXmlWrite->WriteAttribute(L"bevelled",L"true"); + m_pXmlWrite->WriteNodeEnd(L"w",true,true); + m_wsAnnotationStarMath += L"{ "; + ConversionVectorWritingElement(pMf->m_oNum.GetPointer()->m_arrItems); + m_wsAnnotationStarMath += L"} wideslash { "; + ConversionVectorWritingElement(pMf->m_oDen.GetPointer()->m_arrItems); + m_wsAnnotationStarMath += L"} "; + } + else + { + m_pXmlWrite->WriteNodeEnd(L"w",true,false); + m_wsAnnotationStarMath += L"{ "; + ConversionVectorWritingElement(pMf->m_oNum.GetPointer()->m_arrItems); + m_wsAnnotationStarMath += L"} over { "; + ConversionVectorWritingElement(pMf->m_oDen.GetPointer()->m_arrItems); + m_wsAnnotationStarMath += L"} "; + } + m_pXmlWrite->WriteNodeEnd(L"mfrac",false,false); + } + else + { + m_pXmlWrite->WriteNodeBegin(L"mrow",false); + ConversionVectorWritingElement(pMf->m_oNum.GetPointer()->m_arrItems); + RecordingMoNode(L"/",m_pXmlWrite); + m_wsAnnotationStarMath += L"/ "; + ConversionVectorWritingElement(pMf->m_oDen.GetPointer()->m_arrItems); + m_pXmlWrite->WriteNodeEnd(L"mrow",false,false); + } + } + StValuePr COOXml2Odf::ConversionFpr(OOX::Logic::CFPr *pFpr) + { + StValuePr stValue; + if(pFpr == nullptr) + return stValue; + stValue.m_wsTypeName = ConversionType(dynamic_cast(pFpr->m_oType.GetPointer())); + return stValue; + } + std::wstring COOXml2Odf::ConversionType(OOX::Logic::CType *pType) + { + if(pType == nullptr) + return L""; + std::wstring wsType = pType->m_val->ToString(); + return wsType; + } + void COOXml2Odf::ConversionMd(OOX::Logic::CDelimiter *pDel) + { + if(pDel == nullptr) + return; + StValuePr stDelPr; + StStyleMenClose stStyle; + if(pDel->m_arrItems[0] != nullptr && pDel->m_arrItems[0]->getType() == OOX::EElementType::et_m_dPr) + stDelPr = ConversionMdPr(dynamic_cast(pDel->m_arrItems[0]),stStyle); + m_pXmlWrite->WriteNodeBegin(L"mrow",false); + if(!stDelPr.m_wsBegBracket.empty()) + { + m_pXmlWrite->WriteNodeBegin(L"mo",true); + m_pXmlWrite->WriteAttribute(L"fence",L"true"); + m_pXmlWrite->WriteAttribute(L"form",L"prefix"); + m_pXmlWrite->WriteAttribute(L"stretchy",L"true"); + m_pXmlWrite->WriteNodeEnd(L"w",true,true); + m_pXmlWrite->WriteString(stDelPr.m_wsBegBracket); + } + m_wsAnnotationStarMath += L"left " + BracketForAnnotation(stDelPr.m_wsBegBracket,true) + L" "; + m_pXmlWrite->WriteNodeBegin(L"mrow",false); + for(int i = 1; im_arrItems.size();i++) + { + if(i >= 2) + { + RecordingMoNode(L"\u007C",m_pXmlWrite); + m_wsAnnotationStarMath += L"mline "; + } + NodeDefinition(pDel->m_arrItems[i]); + } + m_pXmlWrite->WriteNodeEnd(L"mrow",false,false); + if(!stDelPr.m_wsEndBracket.empty()) + { + m_pXmlWrite->WriteNodeBegin(L"mo",true); + m_pXmlWrite->WriteAttribute(L"fence",L"true"); + m_pXmlWrite->WriteAttribute(L"form",L"postfix"); + m_pXmlWrite->WriteAttribute(L"stretchy",L"true"); + m_pXmlWrite->WriteNodeEnd(L"w",true,true); + m_pXmlWrite->WriteString(stDelPr.m_wsEndBracket); + } + m_wsAnnotationStarMath += L"right " + BracketForAnnotation(stDelPr.m_wsEndBracket,false) + L" "; + m_pXmlWrite->WriteNodeEnd(L"mrow",false,false); + StyleClosing(stStyle,m_pXmlWrite); + if((stStyle.m_iStyle != 0 || stStyle.m_bMenClose) && !m_stAttribute.empty()) + { + m_stAttribute.top()->Release(); + m_stAttribute.pop(); + } + } + std::wstring COOXml2Odf::BracketForAnnotation(const std::wstring &wsBracket, const bool &bBeg) + { + if(wsBracket.empty()) return L"none"; + else if(wsBracket == L"\u007C" && bBeg) return L"lline"; + else if(wsBracket == L"\u007C" && !bBeg) return L"rline"; + else if(wsBracket == L"\u2016" && bBeg) return L"ldline"; + else if(wsBracket == L"\u2016" && !bBeg) return L"rdline"; + else if(wsBracket == L"\u27E6") return L"ldbracket"; + else if(wsBracket == L"\u27E7") return L"rdbracket"; + else if(wsBracket == L"\u007B") return L"lbrace"; + else if(wsBracket == L"\u007D") return L"rbrace"; + else if(wsBracket == L"\u2329" || L"\u27E8" == wsBracket) return L"langle"; + else if(wsBracket == L"\u232A" || L"\u27E9" == wsBracket) return L"rangle"; + else if(wsBracket == L"\u2308") return L"lceil"; + else if(wsBracket == L"\u2309") return L"rceil"; + else if(wsBracket == L"\u230A") return L"lfloor"; + else if(wsBracket == L"\u230B") return L"rfloor"; + else return wsBracket; + } + void COOXml2Odf::ConversionNary(OOX::Logic::CNary *pNary) + { + if(pNary == nullptr) return; + std::wstring wsTypeNary; + StStyleMenClose stStyle; + StValuePr stNaryPr = ConversionNaryPr(pNary->m_oNaryPr.GetPointer(),stStyle); + if(stNaryPr.m_bSubHide && stNaryPr.m_bSupHide) + wsTypeNary = L"munderover"; + else if(!stNaryPr.m_bSubHide && stNaryPr.m_bSupHide) + wsTypeNary = L"mover"; + else if(!stNaryPr.m_bSupHide && stNaryPr.m_bSubHide) + wsTypeNary = L"munder"; + else + wsTypeNary = L"mrow"; + m_pXmlWrite->WriteNodeBegin(wsTypeNary,false); + RecordingMoNode(stNaryPr.m_wsChr,m_pXmlWrite); + m_wsAnnotationStarMath += ToStringChr(stNaryPr.m_wsChr) + L" "; + if(stNaryPr.m_bSubHide) + { + m_wsAnnotationStarMath += L"from {"; + ConversionSub(pNary->m_oSub.GetPointer()); + m_wsAnnotationStarMath += L"} "; + } + if(stNaryPr.m_bSupHide) + { + m_wsAnnotationStarMath += L"to {"; + ConversionSup(pNary->m_oSup.GetPointer()); + m_wsAnnotationStarMath += L"} "; + } + m_pXmlWrite->WriteNodeEnd(wsTypeNary,false,false); + ConversionElement(pNary->m_oElement.GetPointer()); + StyleClosing(stStyle,m_pXmlWrite); + } + void COOXml2Odf::ConversionSsub(OOX::Logic::CSSub *pSsub) + { + if(pSsub == nullptr) return; + ConversionSub(pSsub->m_oSub.GetPointer(),pSsub->m_oElement.GetPointer()); + } + void COOXml2Odf::ConversionSub(OOX::Logic::CSub *pSub, OOX::Logic::CElement * pElement) + { + if(pSub == nullptr) return; + m_pXmlWrite->WriteNodeBegin(L"msub",false); + if(pElement != nullptr) + ConversionElement(pElement); + else + { + m_pXmlWrite->WriteNodeBegin(L"mspace",true); + m_pXmlWrite->WriteNodeEnd(L"w",true,true); + m_wsAnnotationStarMath += L"` "; + } + m_wsAnnotationStarMath += L"_ {"; + ConversionVectorWritingElement(pSub->m_arrItems); + m_wsAnnotationStarMath += L"} "; + m_pXmlWrite->WriteNodeEnd(L"msub",false,false); + } + void COOXml2Odf::ConversionSub(OOX::Logic::CSub *pSub) + { + if(pSub == nullptr) + return; + ConversionVectorWritingElement(pSub->m_arrItems); + } + void COOXml2Odf::ConversionSsup(OOX::Logic::CSSup *pSsup) + { + if(pSsup == nullptr) return; + ConversionSup(pSsup->m_oSup.GetPointer(),pSsup->m_oElement.GetPointer()); + } + void COOXml2Odf::ConversionSup(OOX::Logic::CSup *pSup, OOX::Logic::CElement *pElement) + { + if(pSup == nullptr) return; + m_pXmlWrite->WriteNodeBegin(L"msup",false); + if(pElement != nullptr) + ConversionElement(pElement); + else + { + m_pXmlWrite->WriteNodeBegin(L"mspace",true); + m_pXmlWrite->WriteNodeEnd(L"w",true,true); + m_wsAnnotationStarMath += L"` "; + } + m_wsAnnotationStarMath+= L"^ {"; + ConversionVectorWritingElement(pSup->m_arrItems); + m_wsAnnotationStarMath += L"} "; + m_pXmlWrite->WriteNodeEnd(L"msup",false,false); + } + void COOXml2Odf::ConversionSup(OOX::Logic::CSup *pSup) + { + if(pSup == nullptr) + return; + ConversionVectorWritingElement(pSup->m_arrItems); + } + void COOXml2Odf::ConversionElement(OOX::Logic::CElement *pElement) + { + if(pElement == nullptr) return; + ConversionVectorWritingElement(pElement->m_arrItems); + } + std::vector COOXml2Odf::ConversionMRun(OOX::Logic::CMRun *pMRun) + { + StValuePr* stRpr(nullptr); + std::vector arLine; + if(pMRun == nullptr) return arLine; + if(pMRun->m_oRPr.GetPointer() != nullptr) + stRpr = ConversionRunProperties(pMRun->m_oRPr.GetPointer()); + else if (pMRun->m_oARPr.GetPointer() != nullptr) + ConversionARpr(pMRun->m_oARPr.GetPointer(),stRpr); + if(pMRun->m_oMRPr.GetPointer() != nullptr) + ConversionMRunProperties(pMRun->m_oMRPr.GetPointer(),stRpr); + if(pMRun->m_oMText.GetPointer() != nullptr) + arLine = ConversionMT(pMRun->m_oMText.GetPointer(),stRpr,pMRun->m_oMRPr.GetPointer()); + if(stRpr != nullptr && !arLine.empty()) + { + if(!m_stAttribute.empty()) + AttributeCheck(m_stAttribute.top(),stRpr); + for(int i = 0; iSetAttribute(stRpr); + stRpr->AddRef(); + } + else if(i == 0 ) + arLine[i]->SetAttribute(stRpr); + } + } + return arLine; + } + StValuePr COOXml2Odf::ConversionMdPr(OOX::Logic::CDelimiterPr *pDelPr, StStyleMenClose &stStyle) + { + StValuePr pMdPr; + if(pDelPr == nullptr) + return pMdPr; + stStyle = ConversionCtrlPr(pDelPr->m_oCtrlPr.GetPointer(),true); + pMdPr.m_wsBegBracket = ConversionBegBracket(dynamic_cast(pDelPr->m_oBegChr.GetPointer())); + pMdPr.m_wsEndBracket = ConversionEndBracket(dynamic_cast(pDelPr->m_oEndChr.GetPointer())); + return pMdPr; + } + StValuePr COOXml2Odf::ConversionNaryPr(OOX::Logic::CNaryPr *pNaryPr, StStyleMenClose &stStyle) + { + StValuePr stNaryPr; + if(pNaryPr == nullptr) return stNaryPr; + stStyle = ConversionCtrlPr(pNaryPr->m_oCtrlPr.GetPointer()); + stNaryPr.m_wsChr = ConversionChr(pNaryPr->m_oChr.GetPointer()); + if(pNaryPr->m_oSubHide.GetPointer() == nullptr) + stNaryPr.m_bSubHide = true; + if(pNaryPr->m_oSupHide.GetPointer() == nullptr) + stNaryPr.m_bSupHide = true; + return stNaryPr; + } + std::wstring COOXml2Odf::ConversionBegBracket(OOX::Logic::CBegChr *pBegChr) + { + if(pBegChr == nullptr) + return L"("; + if(pBegChr->m_val.GetPointer() == nullptr) + return L"("; + return pBegChr->m_val->GetValue(); + } + std::wstring COOXml2Odf::ConversionEndBracket(OOX::Logic::CEndChr *pEndChr) + { + if(pEndChr == nullptr) + return L")"; + if(pEndChr->m_val.GetPointer() == nullptr) + return L")"; + return pEndChr->m_val->GetValue(); + } + //annotation? + std::wstring COOXml2Odf::ConversionChr(OOX::Logic::CChr *pChr) + { + if(pChr == nullptr) return L""; + return pChr->m_val->GetValue(); + } + std::wstring COOXml2Odf::ToStringChr(const std::wstring &wsChr) + { + if(wsChr == L"\u2211") return L"sum"; + else if(wsChr == L"\u220F") return L"prod"; + else if(wsChr == L"\u2210") return L"coprod"; + else if(wsChr.empty()) return L"int"; + else if(wsChr == L"\u222C") return L"iint"; + else if(wsChr == L"\u222D") return L"iiint"; + else if(wsChr == L"\u222E") return L"lint"; + else if(wsChr == L"\u222F") return L"llint"; + else if(wsChr == L"\u2230") return L"lllint"; + else return L"oper " + wsChr; + } + void COOXml2Odf::EndOdf() + { + m_pXmlWrite->WriteNodeEnd(L"annotation",false,false); + m_pXmlWrite->WriteNodeEnd(L"semantics",false,false); + m_pXmlWrite->WriteNodeEnd(L"math",false,false); + } + bool COOXml2Odf::IsDigit(const std::wstring &wsDigit) + { + if(wsDigit.empty()) + return false; + for(wchar_t cOneElement:wsDigit) + if(!iswdigit(cOneElement)) return false; + return true; + } + bool COOXml2Odf::IsAlpha(const std::wstring &wsAlpha) + { + for(wchar_t cOneElement:wsAlpha) + if(!iswalpha(cOneElement)) return false; + return true; + } + bool COOXml2Odf::ComparingAttributes(StValuePr *pRight, StValuePr *pLeft) + { + if(pRight == nullptr && pLeft == nullptr) + return true; + if(pRight != nullptr && pLeft != nullptr) + { + if(pRight->m_wsColor != pLeft->m_wsColor) + return false; + else if(pRight->m_iSize != pLeft->m_iSize) + return false; + else if(pRight->m_enStyle != pLeft->m_enStyle) + return false; + else if(pRight->m_enFont != pLeft->m_enFont) + return false; + else return true; + } + else + return false; + } + void COOXml2Odf::AttributeCheck(StValuePr *&pParent, StValuePr *&pChild) + { + if(pParent == nullptr || pChild == nullptr) + return; + else + { + if(pParent->m_wsColor == pChild->m_wsColor) + pChild->m_wsColor.clear(); + if(pParent->m_iSize == pChild->m_iSize) + pChild->m_iSize = 0; + if(pParent->m_enStyle == pChild->m_enStyle) + pChild->m_enStyle = SimpleTypes::EStyle::stylePlain; + if(pParent->m_enFont == pChild->m_enFont) + pChild->m_enFont = StarMath::TypeFont::empty; + } + } + void COOXml2Odf::ConversionAcc(OOX::Logic::CAcc *pAcc) + { + std::wstring wsSymbol = pAcc->m_oAccPr->m_oChr.IsInit() ? pAcc->m_oAccPr->m_oChr.get().m_val->GetValue() : L"",wsSign; + wsSign = TranslationDiacritSign(wsSymbol); + if(wsSign.empty()) + { + m_pXmlWrite->WriteNodeBegin(L"mover",false); + ConversionElement(pAcc->m_oElement.GetPointer()); + m_pXmlWrite->WriteNodeBegin(L"mtext",false); + m_pXmlWrite->WriteString(wsSymbol); + m_pXmlWrite->WriteNodeEnd(L"mtext",false,false); + m_wsAnnotationStarMath += L"csup "; + m_wsAnnotationStarMath += L"\u0026quot;" + wsSymbol + L"\u0026quot; "; + } + else + { + m_wsAnnotationStarMath += wsSign + L" "; + m_pXmlWrite->WriteNodeBegin(L"mover",true); + m_pXmlWrite->WriteAttribute(L"accent",L"true"); + m_pXmlWrite->WriteNodeEnd(L"w",true,false); + ConversionElement(pAcc->m_oElement.GetPointer()); + m_pXmlWrite->WriteNodeBegin(L"mo",true); + m_pXmlWrite->WriteAttribute(L"stretchy",L"false"); + m_pXmlWrite->WriteNodeEnd(L"w",true,false); + m_pXmlWrite->WriteString(wsSymbol); + m_pXmlWrite->WriteNodeEnd(L"mo",false,false); + } + m_pXmlWrite->WriteNodeEnd(L"mover",false,false); + } + void COOXml2Odf::ConversionFunc(OOX::Logic::CFunc *pFunc) + { + if(pFunc == nullptr) + return; + m_pXmlWrite->WriteNodeBegin(L"mrow",false); + if(pFunc->m_oFName.GetPointer() != nullptr) + ConversionVectorWritingElement(pFunc->m_oFName.GetPointer()->m_arrItems); + ConversionElement(pFunc->m_oElement.GetPointer()); + m_pXmlWrite->WriteNodeEnd(L"mrow",false,false); + } + StStyleMenClose COOXml2Odf::ConversionFuncPr(OOX::Logic::CFuncPr *pFuncPr) + { + StStyleMenClose stStyle; + if(pFuncPr == nullptr) + return stStyle; + return ConversionCtrlPr(pFuncPr->m_oCtrlPr.GetPointer()); + } + void COOXml2Odf::RecordingMoNode(const std::wstring &wsSymbol, XmlUtils::CXmlWriter *pXmlWrite) + { + pXmlWrite->WriteNodeBegin(L"mo",true); + pXmlWrite->WriteAttribute(L"stretchy",L"false"); + pXmlWrite->WriteNodeEnd(L"w",true,false); + if(!wsSymbol.empty()) + pXmlWrite->WriteString(wsSymbol); + else + pXmlWrite->WriteString(L"\u222B"); + pXmlWrite->WriteNodeEnd(L"mo",false,false); + } + void COOXml2Odf::ConversionBox(OOX::Logic::CBox *pBox) + { + if(pBox == nullptr) + return; + NodeDefinition(pBox->m_oElement.GetPointer()); + } + StValuePr* COOXml2Odf::ConversionRunProperties(OOX::Logic::CRunProperty *pRPr) + { + StValuePr* stTempPr = new StValuePr; + if(pRPr == nullptr) + { + stTempPr->Release(); + return nullptr; + } + bool bRpr(false); + if(pRPr->m_oColor.GetPointer() != nullptr) + { + std::wstring wsColor,wsUpperColor(L""); + wsColor = pRPr->m_oColor.GetPointer()->m_oVal.GetPointer()!= nullptr ? pRPr->m_oColor.GetPointer()->m_oVal.GetPointer()->ToStringNoAlpha():L""; + if(wsColor != L"") + { + for(wchar_t chToken: wsColor) + wsUpperColor += std::toupper(chToken); + if(wsUpperColor != L"000000") + { + stTempPr->m_wsColor = wsUpperColor; + bRpr = true; + } + } + } + if(pRPr->m_oSz.GetPointer() != nullptr) + { + stTempPr->m_iSize = pRPr->m_oSz.GetPointer()->m_oVal.GetPointer() != nullptr ? pRPr->m_oSz.GetPointer()->m_oVal.GetPointer()->GetValue():0; + if(stTempPr->m_iSize != 0) + bRpr = true; + } + if(pRPr->m_oRFonts.GetPointer()!= nullptr && pRPr->m_oRFonts.GetPointer()->m_sAscii.GetPointer()!= nullptr) + stTempPr->m_enFont = FontCheck(pRPr->m_oRFonts.GetPointer()->m_sAscii.get(),bRpr); + if(pRPr->m_oStrike.GetPointer()!=nullptr && pRPr->m_oStrike.GetPointer()->m_oVal.GetValue() == SimpleTypes::EOnOff::onoffTrue) + { + stTempPr->m_bStrike = true; + bRpr = true; + } + if(pRPr->m_oBold.GetPointer() != nullptr && pRPr->m_oBold.GetPointer()->m_oVal.GetValue() == SimpleTypes::EOnOff::onoffTrue) + { + if(pRPr->m_oItalic.GetPointer() != nullptr && pRPr->m_oItalic.GetPointer()->m_oVal.GetValue() == SimpleTypes::EOnOff::onoffTrue) + stTempPr->m_enStyle = SimpleTypes::EStyle::styleBoldItalic; + else + stTempPr->m_enStyle = SimpleTypes::EStyle::styleBold; + bRpr = true; + } + else if(pRPr->m_oItalic.GetPointer() != nullptr && pRPr->m_oItalic.GetPointer()->m_oVal.GetValue() == SimpleTypes::EOnOff::onoffTrue) + { + stTempPr->m_enStyle = SimpleTypes::EStyle::styleItalic; + bRpr = true; + } + if(bRpr == true) + return stTempPr; + else + { + stTempPr->Release(); + return nullptr; + } + } + void COOXml2Odf::ConversionMRunProperties(OOX::Logic::CMRPr *pMRpr, StValuePr*&pValue) + { + if(pMRpr == nullptr) + return ; + if(pMRpr->m_oSty.GetPointer() != nullptr && pMRpr->m_oSty.GetPointer()->m_val.GetPointer()->GetValue() != SimpleTypes::EStyle::stylePlain) + { + if(pValue == nullptr) + pValue = new StValuePr; + pValue->m_enStyle = pMRpr->m_oSty.GetPointer()->m_val.GetPointer()->GetValue(); + } + } + void COOXml2Odf::ConversionARpr(PPTX::Logic::RunProperties *pARpr, StValuePr *&pValue) + { + if(pARpr == nullptr) + return; + if(pValue == nullptr) + pValue = new StValuePr; + bool bAttribute{false}; + if(pARpr->b.IsInit() && pARpr->b.get()) + { + if(pARpr->i.IsInit() && pARpr->i.get()) + pValue->m_enStyle = SimpleTypes::EStyle::styleBoldItalic; + else + pValue->m_enStyle = SimpleTypes::EStyle::styleBold; + bAttribute = true; + } + else if(pARpr->i.IsInit() && pARpr->i.get()) + { + pValue->m_enStyle = SimpleTypes::EStyle::styleItalic; + bAttribute = true; + } + if(pARpr->sz.IsInit()) + { + pValue->m_iSize = pARpr->sz.get()/100; + bAttribute = true; + } + if(pARpr->latin.IsInit() && !pARpr->latin->typeface.empty()) + pValue->m_enFont = FontCheck(pARpr->latin->typeface,bAttribute); +// if(pARpr->Fill.is_init() && pARpr->Fill.Fill.m_pData->) + } + StarMath::TypeFont COOXml2Odf::FontCheck(const std::wstring &wsFont, bool &bAttribute) + { + if(!wsFont.empty()) + { + if(L"Liberation Serif" == wsFont) + { + bAttribute = true; + return StarMath::TypeFont::serif; + } + else if(L"Liberation Sans" == wsFont) + { + bAttribute = true; + return StarMath::TypeFont::sans; + } + else if(L"Liberation Mono" == wsFont) + { + bAttribute = true; + return StarMath::TypeFont::fixed; + } + else + return StarMath::TypeFont::empty; + } + else + return StarMath::TypeFont::empty; + } + bool COOXml2Odf::ColorCheck(const std::wstring &wsColor, std::wstring &wsRecordColor) + { + if(!wsColor.empty()) + { + if(L"0000FF" == wsColor) + wsRecordColor = L"blue"; + else if(L"00FF00" == wsColor) + wsRecordColor = L"lime"; + else if(L"008000" == wsColor) + wsRecordColor = L"green"; + else if(L"FF0000" == wsColor) + wsRecordColor = L"red"; + else if(L"ED0DD9" == wsColor) + wsRecordColor = L"fuchsia"; + else if(L"30D5C8" == wsColor) + wsRecordColor = L"aqua"; + else if(L"FFFF00" == wsColor) + wsRecordColor = L"yellow"; + else if(L"808080" == wsColor) + wsRecordColor = L"gray"; + else if(L"800000" == wsColor) + wsRecordColor = L"maroon"; + else if(L"000080" == wsColor) + wsRecordColor = L"navy"; + else if(L"808000" == wsColor) + wsRecordColor = L"olive"; + else if(L"800080" == wsColor) + wsRecordColor = L"purple"; + else if(L"C0C0C0" == wsColor) + wsRecordColor = L"silver"; + else if(L"008080" == wsColor) + wsRecordColor = L"teal"; + else if(L"FF7F50" == wsColor) + wsRecordColor = L"coral"; + else if(L"191970" == wsColor) + wsRecordColor = L"midnightblue"; + else if(L"DC143C" == wsColor) + wsRecordColor = L"crimson"; + else if(L"EE82EE" == wsColor) + wsRecordColor = L"violet"; + else if(L"FFA500" == wsColor) + wsRecordColor = L"orange"; + else if(L"FF4500" == wsColor) + wsRecordColor = L"orangered"; + else if(L"2E8B57" == wsColor) + wsRecordColor = L"seagreen"; + else if(L"4B0082" == wsColor) + wsRecordColor = L"indigo"; + else if(L"FF69B4" == wsColor) + wsRecordColor = L"hotpink"; + else if(L"FFF0F5" == wsColor) + wsRecordColor = L"lavender"; + else + return false; + return true; + } + else + return false; + } + void COOXml2Odf::ConversionTextVector(std::vector &arLine, std::vector &arNewLine) + { + if(!arLine.empty()) + { + COneElement* pTempElement = nullptr; + for(COneElement* pElement:arLine) + { + if(pElement->GetType() == TypeElement::String || pElement->GetType() == TypeElement::SpecialSymbol) + { + if(pTempElement == nullptr) + pTempElement = pElement; + else if(pTempElement->GetType() == TypeElement::BinOperator || pTempElement->GetType() == TypeElement::Connection) + { + if(!CBinOperator::SetRightArg(pTempElement,pElement)) + { + arNewLine.push_back(pTempElement); + pTempElement = pElement; + } + } + else if(pElement->GetType() ==TypeElement::String && pTempElement->GetType() == TypeElement::String && ComparingAttributes(pTempElement->GetAttribute(),pElement->GetAttribute())) + { + CNumberOrLetter* pFirst = dynamic_cast(pTempElement); + CNumberOrLetter* pSecond = dynamic_cast(pElement); + pFirst->AddingStrings(pSecond->GetString()); + } + else + { + arNewLine.push_back(pTempElement); + pTempElement = pElement; + } + } + else if(pElement->GetType() == TypeElement::BinOperator || pElement->GetType() == TypeElement::Connection) + { + if(pTempElement == nullptr) + pTempElement = pElement; + else if(pTempElement->GetType() != TypeElement::Empty) + { + if(!CBinOperator::SetLeftArg(pElement,pTempElement)) + { + arNewLine.push_back(pTempElement); + pTempElement = pElement; + } + else + pTempElement = pElement; + } + else + { + arNewLine.push_back(pTempElement); + pTempElement = pElement; + } + } + else + { + arNewLine.push_back(pTempElement); + pTempElement = pElement; + } + } + arNewLine.push_back(pTempElement); + } + if(!arNewLine.empty()) + { + arLine.clear(); + for(int i = 0;i< arNewLine.size();i++) + { + if(arNewLine[i] != nullptr) + arNewLine[i]->Conversion(m_pXmlWrite,m_wsAnnotationStarMath); + } + } + arLine.clear(); + arNewLine.clear(); + } + void COOXml2Odf::ConversionVectorWritingElement(std::vector arWrElements) + { + std::vector arLine,arNewLine; + for(int i = 0; i < arWrElements.size() ;i++) + { + if(arWrElements[i]->getType() == OOX::EElementType::et_m_r) + { + std::vector arTemp = ConversionMRun(dynamic_cast(arWrElements[i])); + arLine.insert(arLine.end(),arTemp.begin(),arTemp.end()); + } + else + { + if(!arLine.empty()) + ConversionTextVector(arLine,arNewLine); + NodeDefinition(arWrElements[i]); + } + } + if(!arLine.empty()) + { + ConversionTextVector(arLine,arNewLine); + } + } + std::wstring COOXml2Odf::TranslationDiacritSign(const std::wstring &wsSymbol) + { + if( L"\u0308" == wsSymbol) return L"ddot"; + else if(L"\u0307" == wsSymbol) return L"dot"; + else if(L"\u0301" == wsSymbol) return L"acute"; + else if(L"\u0300" == wsSymbol) return L"grave"; + else if(L"\u0306" == wsSymbol) return L"breve"; + else if(L"\u030A" == wsSymbol) return L"circle"; + else if(L"\u0304" == wsSymbol) return L"bar"; + else if(L"\u20DB" == wsSymbol) return L"dddot"; + else if(L"\u20D1" == wsSymbol) return L"harpoon"; + else if(L"\u20D7" == wsSymbol) return L"vec"; + else if(L"\u0342" == wsSymbol) return L"tilde"; + else if(L"\u0302" == wsSymbol) return L"hat"; + else if(L"\u030C" == wsSymbol) return L"check"; + else if(L"\u0305" == wsSymbol) return L"overline"; + else if(L"\u0332" == wsSymbol) return L"underline"; + else return L""; + } + void COOXml2Odf::ConversionMatrix(OOX::Logic::CMatrix* pMatrix) + { + if(pMatrix == nullptr) + return; + StStyleMenClose stStyle = ConversionCMPr(dynamic_cast(pMatrix->m_arrItems[0])); + m_wsAnnotationStarMath += L"matrix{"; + m_pXmlWrite->WriteNodeBegin(L"mtable",false); + for(int i = 1;im_arrItems.size();i++) + { + if(OOX::EElementType::et_m_mr == pMatrix->m_arrItems[i]->getType()) + ConversionMr(dynamic_cast(pMatrix->m_arrItems[i])); + if(i+1 < pMatrix->m_arrItems.size()) + m_wsAnnotationStarMath += L"## "; + } + m_pXmlWrite->WriteNodeEnd(L"mtable",false,false); + StyleClosing(stStyle,m_pXmlWrite); + if((stStyle.m_iStyle != 0 || stStyle.m_bMenClose) && !m_stAttribute.empty()) + { + m_stAttribute.top()->Release(); + m_stAttribute.pop(); + } + m_wsAnnotationStarMath += L"} "; + } + void COOXml2Odf::ConversionMr(OOX::Logic::CMr *pMr) + { + if(pMr == nullptr) + return; + m_pXmlWrite->WriteNodeBegin(L"mtr",false); + for(unsigned int i = 0;im_arrItems.size();i++) + { + if(pMr->m_arrItems[i]->getType() == OOX::EElementType::et_m_e) + { + m_pXmlWrite->WriteNodeBegin(L"mtd",false); + ConversionElement(dynamic_cast(pMr->m_arrItems[i])); + if(i+1 < pMr->m_arrItems.size()) + m_wsAnnotationStarMath += L"# "; + m_pXmlWrite->WriteNodeEnd(L"mtd",false,false); + } + } + m_pXmlWrite->WriteNodeEnd(L"mtr",false,false); + } + StStyleMenClose COOXml2Odf::ConversionCtrlPr(OOX::Logic::CCtrlPr *pCtrlPr, const bool &bDelimiter) + { + StStyleMenClose stStyle; + if(pCtrlPr == nullptr) + return stStyle; + StValuePr* pValue(nullptr); + if(pCtrlPr->m_oRPr.GetPointer() != nullptr) + pValue = ConversionRunProperties(pCtrlPr->m_oRPr.GetPointer()); + else if(pCtrlPr->m_oARPr.GetPointer() != nullptr) + ConversionARpr(pCtrlPr->m_oARPr.GetPointer(),pValue); + if(pValue != nullptr) + { + if(!m_stAttribute.empty()) + AttributeCheck(m_stAttribute.top(),pValue); + COneElement::ConversionAttribute(pValue,stStyle,m_pXmlWrite,m_wsAnnotationStarMath,bDelimiter); + if(bDelimiter) + m_stAttribute.push(pValue); + return stStyle; + } + return stStyle; + } + StStyleMenClose COOXml2Odf::ConversionCMPr(OOX::Logic::CMPr *pMPr) + { + StStyleMenClose stStyle; + if(pMPr == nullptr) + return stStyle; + return ConversionCtrlPr(dynamic_cast(pMPr->m_oCtrlPr.GetPointer()),true); + } + std::wstring COOXml2Odf::GetOdf() + { + return m_pXmlWrite->GetXmlString(); + } + std::wstring COOXml2Odf::GetAnnotation() + { + return m_wsAnnotationStarMath; + } + std::wstring COOXml2Odf::GetSemantic() + { + return m_wsSemantic; + } + void COOXml2Odf::ConversionRad(OOX::Logic::CRad *pRad) + { + if(pRad == nullptr) + return; + bool bDeg{false}; + StStyleMenClose stStyle = ConversionRadPr(pRad->m_oRadPr.GetPointer(),bDeg); + if(bDeg) + { + m_wsAnnotationStarMath += L"sqrt "; + m_pXmlWrite->WriteNodeBegin(L"sqrt",false); + m_wsAnnotationStarMath += L"{ "; + NodeDefinition(pRad->m_oElement.GetPointer()); + m_wsAnnotationStarMath += L"} "; + m_pXmlWrite->WriteNodeEnd(L"sqrt",false,false); + } + else if(!bDeg) + { + m_wsAnnotationStarMath += L"nroot "; + std::wstring wsStart = m_wsAnnotationStarMath,wsElement; + m_wsAnnotationStarMath.clear(); + m_pXmlWrite->WriteNodeBegin(L"mroot",false); + m_wsAnnotationStarMath += L"{ "; + NodeDefinition(pRad->m_oElement.GetPointer()); + m_wsAnnotationStarMath += L"} "; + wsElement = m_wsAnnotationStarMath; + m_wsAnnotationStarMath.clear(); + m_wsAnnotationStarMath += L"{ "; + ConversionDeg(pRad->m_oDeg.GetPointer()); + m_wsAnnotationStarMath += L"} "; + wsStart += m_wsAnnotationStarMath + wsElement; + m_wsAnnotationStarMath = wsStart; + m_pXmlWrite->WriteNodeEnd(L"mroot",false,false); + } + StyleClosing(stStyle,m_pXmlWrite); + } + StStyleMenClose COOXml2Odf::ConversionRadPr(OOX::Logic::CRadPr *pRadPr,bool&bDeg) + { + StStyleMenClose stStyle; + if(pRadPr == nullptr) + return stStyle; + bDeg = pRadPr->m_oDegHide.GetPointer() != nullptr ? true:false; + return ConversionCtrlPr(dynamic_cast(pRadPr->m_oCtrlPr.GetPointer())); + } + void COOXml2Odf::ConversionDeg(OOX::Logic::CDeg *pDeg) + { + if(pDeg == nullptr) + return; + ConversionVectorWritingElement(pDeg->m_arrItems); + } + void COOXml2Odf::ConversionGroupChr(OOX::Logic::CGroupChr *pGroup, const bool &bElement) + { + if(pGroup == nullptr) + return; + StValuePr stGroupPr; + stGroupPr = ConversionGroupChrPr(pGroup->m_oGroupChrPr.GetPointer()); + std::wstring wsNode(L""),wsAnnotation = GroupChrForAnnotation(stGroupPr.m_wsChr); + if(!wsAnnotation.empty()) + { + wsNode = stGroupPr.m_wsChr == L""? L"munder":L"mover"; + } + else + { + switch(stGroupPr.m_enPos) + { + case SimpleTypes::ETopBot::tbBot: + { + wsNode = L"munder"; + break; + } + case SimpleTypes::ETopBot::tbTop: + { + wsNode = L"mover"; + break; + } + } + } + if(!wsAnnotation.empty()) + { + if(bElement) + { + WritingbBracketsFromTopBottom(wsNode,stGroupPr.m_wsChr,wsAnnotation,pGroup->m_oElement.GetPointer()); + } + else + { + m_pXmlWrite->WriteNodeBegin(wsNode,false); + WritingbBracketsFromTopBottom(wsNode,stGroupPr.m_wsChr,wsAnnotation,pGroup->m_oElement.GetPointer()); + m_pXmlWrite->WriteNodeBegin(L"mspace",true); + m_pXmlWrite->WriteNodeEnd(L"w",true,true); + m_wsAnnotationStarMath += L"` "; + m_pXmlWrite->WriteNodeEnd(wsNode,false,false); + } + } + else + { + m_pXmlWrite->WriteNodeBegin(wsNode,false); + ConversionElement(pGroup->m_oElement.GetPointer()); + m_pXmlWrite->WriteNodeBegin(L"mtext",false); + m_pXmlWrite->WriteString(stGroupPr.m_wsChr); + m_pXmlWrite->WriteNodeEnd(L"mtext",false,false); + m_wsAnnotationStarMath += wsNode == L"mover"? L"csup ":L"csub "; + m_wsAnnotationStarMath += L"\u0026quot;" + stGroupPr.m_wsChr + L"\u0026quot; "; + m_pXmlWrite->WriteNodeEnd(wsNode,false,false); + } + } + void COOXml2Odf::WritingbBracketsFromTopBottom(const std::wstring &wsNode, const std::wstring &wsChr, const std::wstring &wsAnnotation, OOX::Logic::CElement *pElement) + { + m_pXmlWrite->WriteNodeBegin(wsNode,false); + ConversionElement(pElement); + if(!wsChr.empty()) + RecordingMoNode(wsChr,m_pXmlWrite); + else + RecordingMoNode(L"\u23DF",m_pXmlWrite); + m_wsAnnotationStarMath += wsAnnotation; + m_pXmlWrite->WriteNodeEnd(wsNode,false,false); + } + StValuePr COOXml2Odf::ConversionGroupChrPr(OOX::Logic::CGroupChrPr *pGroupPr) + { + StValuePr stGroupPr; + if(pGroupPr == nullptr) + return stGroupPr; + if(pGroupPr->m_oChr.GetPointer()!= nullptr) + stGroupPr.m_wsChr = pGroupPr->m_oChr.GetPointer()->m_val.GetPointer()->GetValue(); + if(pGroupPr->m_oPos.GetPointer() != nullptr) + stGroupPr.m_enPos = pGroupPr->m_oPos.GetPointer()->m_val.GetPointer()->GetValue(); + if(pGroupPr->m_oVertJc.GetPointer() != nullptr) + stGroupPr.m_enVert = pGroupPr->m_oVertJc.GetPointer()->m_val.GetPointer()->GetValue(); + return stGroupPr; + } + std::wstring COOXml2Odf::GroupChrForAnnotation(const std::wstring &wsChr) + { + if(wsChr == L"\u23DE") return L"overbrace "; + else if(L"" == wsChr) return L"underbrace "; + else return L""; + } + void COOXml2Odf::ConversionBar(OOX::Logic::CBar *pBar) + { + if(pBar == nullptr) + return; + StStyleMenClose stStyle; + std::wstring wsNode; + StValuePr pBarPr = ConversionBarPr(pBar->m_oBarPr.GetPointer(),stStyle); + if(pBarPr.m_enPos == SimpleTypes::ETopBot::tbTop) + { + wsNode = L"mover"; + m_wsAnnotationStarMath += L"overline "; + } + else + { + wsNode = L"munder"; + m_wsAnnotationStarMath += L"underline "; + } + m_pXmlWrite->WriteNodeBegin(wsNode,true); + pBarPr.m_enPos == SimpleTypes::ETopBot::tbTop ? m_pXmlWrite->WriteAttribute(L"accent",L"true"): m_pXmlWrite->WriteAttribute(L"accentunder",L"true"); + ConversionElement(pBar->m_oElement.GetPointer()); + m_pXmlWrite->WriteNodeEnd(L"w",true,false); + m_pXmlWrite->WriteNodeBegin(L"mo",false); + pBarPr.m_enPos == SimpleTypes::ETopBot::tbTop ? m_pXmlWrite->WriteString(L"\u203E"):m_pXmlWrite->WriteString(L"\u005F"); + m_pXmlWrite->WriteNodeEnd(L"mo",false,false); + m_pXmlWrite->WriteNodeEnd(wsNode,false,false); + StyleClosing(stStyle,m_pXmlWrite); + } + StValuePr COOXml2Odf::ConversionBarPr(OOX::Logic::CBarPr *pBarPr, StStyleMenClose &stStyle) + { + StValuePr stBarPr; + if(pBarPr == nullptr) + return stBarPr; + if(pBarPr->m_oPos.GetPointer() != nullptr && pBarPr->m_oPos->m_val.GetPointer() != nullptr) + stBarPr.m_enPos = pBarPr->m_oPos->m_val->GetValue(); + stStyle = ConversionCtrlPr(pBarPr->m_oCtrlPr.GetPointer()); + return stBarPr; + } + template + bool IsEmptyNode(T pNode) + { + if(pNode == nullptr) + return true; + if(pNode->m_arrItems.size() == 0) + return true; + return false; + } + void COOXml2Odf::ConversionSPre(OOX::Logic::CSPre *pSPre) + { + if(pSPre == nullptr) + return ; + m_pXmlWrite->WriteNodeBegin(L"mmultiscripts",false); + if(IsEmptyNode(pSPre->m_oElement.GetPointer())) + EmptyBlock(m_pXmlWrite,m_wsAnnotationStarMath); + else + ConversionElement(pSPre->m_oElement.GetPointer()); + m_pXmlWrite->WriteNodeBegin(L"mprescripts",true); + m_pXmlWrite->WriteNodeEnd(L"w",true,true); + if(IsEmptyNode(pSPre->m_oSup.GetPointer())) + { + m_pXmlWrite->WriteNodeBegin(L"none",true); + m_pXmlWrite->WriteNodeEnd(L"w",true,true); + } + else + { + m_wsAnnotationStarMath += L"lsup { "; + ConversionSup(pSPre->m_oSup.GetPointer()); + m_wsAnnotationStarMath += L"} "; + } + if(IsEmptyNode(pSPre->m_oSub.GetPointer())) + { + m_pXmlWrite->WriteNodeBegin(L"none",true); + m_pXmlWrite->WriteNodeEnd(L"w",true,true); + } + else + { + m_wsAnnotationStarMath += L"lsub { "; + ConversionSub(pSPre->m_oSub.GetPointer()); + m_wsAnnotationStarMath += L"} "; + } + m_pXmlWrite->WriteNodeEnd(L"mmultiscripts",false,false); + } + void COOXml2Odf::EmptyBlock(XmlUtils::CXmlWriter* pXmlWrite, std::wstring& wsAnnotation) + { + pXmlWrite->WriteNodeBegin(L"mi",true); + pXmlWrite->WriteAttribute(L"mathvariant",L"normal"); + pXmlWrite->WriteNodeEnd(L"w",true,false); + pXmlWrite->WriteString(L"\u2751"); + pXmlWrite->WriteNodeEnd(L"mi",false,false); + wsAnnotation += L"{\u0026lt;\u003F\u0026gt;} "; + } + void COOXml2Odf::ConversionLimLow(OOX::Logic::CLimLow *pLimLow) + { + if(pLimLow == nullptr) + return; + m_pXmlWrite->WriteNodeBegin(L"munder",false); + if(pLimLow->m_oElement.GetPointer()->m_arrItems.size() == 1 && pLimLow->m_oElement.GetPointer()->m_arrItems[0]->getType() == OOX::EElementType::et_m_groupChr) + ConversionGroupChr(dynamic_cast(pLimLow->m_oElement.GetPointer()->m_arrItems[0]),true); + else + { + ConversionElement(pLimLow->m_oElement.GetPointer()); + m_wsAnnotationStarMath += L"csub "; + } + ConversionLim(pLimLow->m_oLim.GetPointer()); + m_pXmlWrite->WriteNodeEnd(L"munder",false,false); + } + void COOXml2Odf::ConversionLimUpp(OOX::Logic::CLimUpp *pLimUpp) + { + if(pLimUpp == nullptr) + return; + m_pXmlWrite->WriteNodeBegin(L"mover",false); + if(pLimUpp->m_oElement.GetPointer()->m_arrItems.size() == 1 && pLimUpp->m_oElement.GetPointer()->m_arrItems[0]->getType() == OOX::EElementType::et_m_groupChr) + ConversionGroupChr(dynamic_cast(pLimUpp->m_oElement.GetPointer()->m_arrItems[0]),true); + else + { + ConversionElement(pLimUpp->m_oElement.GetPointer()); + m_wsAnnotationStarMath += L"csup "; + } + ConversionLim(pLimUpp->m_oLim.GetPointer()); + m_pXmlWrite->WriteNodeEnd(L"mover",false,false); + } + void COOXml2Odf::ConversionLim(OOX::Logic::CLim *pLim) + { + if(pLim == nullptr) + return; + m_wsAnnotationStarMath += L"{ "; + ConversionVectorWritingElement(pLim->m_arrItems); + m_wsAnnotationStarMath += L"} "; + } + void COOXml2Odf::ConversionEqArr(OOX::Logic::CEqArr *pEqArr) + { + if(pEqArr == nullptr) + return; + m_pXmlWrite->WriteNodeBegin(L"mtable",false); + m_wsAnnotationStarMath += L"stack{"; + for(int i = 1; im_arrItems.size();i++) + { + m_pXmlWrite->WriteNodeBegin(L"mtr",false); + m_pXmlWrite->WriteNodeBegin(L"mtd",false); + NodeDefinition(pEqArr->m_arrItems[i]); + m_pXmlWrite->WriteNodeEnd(L"mtd",false,false); + m_pXmlWrite->WriteNodeEnd(L"mtr",false,false); + if(pEqArr->m_arrItems.size()>1 && i+1 < pEqArr->m_arrItems.size()) + m_wsAnnotationStarMath += L"# "; + } + m_wsAnnotationStarMath += L"} "; + m_pXmlWrite->WriteNodeEnd(L"mtable",false,false); + } + void COOXml2Odf::ConversionSubSup(OOX::Logic::CSSubSup *pSubSup) + { + if(pSubSup == nullptr) + return; + m_pXmlWrite->WriteNodeBegin(L"msubsup",false); + ConversionElement(pSubSup->m_oElement.GetPointer()); + m_wsAnnotationStarMath += L"_ { "; + ConversionSub(pSubSup->m_oSub.GetPointer()); + m_wsAnnotationStarMath += L"} ^ { "; + ConversionSup(pSubSup->m_oSup.GetPointer()); + m_wsAnnotationStarMath += L"} "; + m_pXmlWrite->WriteNodeEnd(L"msubsup",false,false); + } + void COOXml2Odf::StyleClosing(const StStyleMenClose &stStyle, XmlUtils::CXmlWriter *pXmlWrite) + { + if(stStyle.m_bMenClose) + { + pXmlWrite->WriteNodeEnd(L"menclose",false,false); + } + if(stStyle.m_iStyle != 0) + { + unsigned int k(0); + while(k < stStyle.m_iStyle) + { + pXmlWrite->WriteNodeEnd(L"mstyle",false,false); + k++; + } + } + } + void COOXml2Odf::MTextRecording(XmlUtils::CXmlWriter *pXmlWrite, std::wstring &wsAnnotation, const std::wstring &wsText) + { + pXmlWrite->WriteNodeBegin(L"mtext",false); + pXmlWrite->WriteString(wsText); + pXmlWrite->WriteNodeEnd(L"mtext",false,false); + wsAnnotation += L"\u0026quot;" + wsText + L"\u0026quot; "; + } + std::wstring COOXml2Odf::TransformationUTF32(const std::wstring &wsText) + { + NSStringUtils::CStringUTF32 oString32(wsText); + std::wstring wsText16; + for(unsigned int i = 0;i < oString32.length();i++) + { + //Mathematical Bold Capital + if(oString32[i] >= 119808 && oString32[i] <= 119833) + wsText16.push_back((wchar_t)((unsigned int) oString32[i] - 119743)); + //Italic Small Dotless I + else if(oString32[i] == 120484) + wsText16.push_back((wchar_t)((unsigned int) oString32[i] - 120379)); + //Italic Small Dotless J + else if(oString32[i] == 120485) + wsText16.push_back((wchar_t)((unsigned int) oString32[i] - 120379)); + //Bold Nabla + else if(oString32[i] == 120513) + wsText16.push_back((wchar_t)((unsigned int) oString32[i] - 111802)); + //Italic Nabla + else if(oString32[i] == 120571) + wsText16.push_back((wchar_t)((unsigned int) oString32[i] - 111860)); + //Bold Italic Nabla + else if(oString32[i] == 120629) + wsText16.push_back((wchar_t)((unsigned int) oString32[i] - 111918)); + //Sans-Serif Bold Nabla + else if(oString32[i] == 120687) + wsText16.push_back((wchar_t)((unsigned int) oString32[i] - 111976)); + //Sans-Serif Bold Italic Nabla + else if(oString32[i] == 120745) + wsText16.push_back((wchar_t)((unsigned int) oString32[i] - 112034)); + //Mathematical Bold Small + else if(oString32[i] >= 119834 && oString32[i] <= 119859) + wsText16.push_back((wchar_t)((unsigned int) oString32[i] - 119737)); + //Italic Capital + else if(oString32[i] >= 119860 && oString32[i] <= 119885) + wsText16.push_back((wchar_t)((unsigned int) oString32[i] - 119795)); + //Italic Small + else if(oString32[i] >= 119886 && oString32[i] <= 119911) + wsText16.push_back((wchar_t)((unsigned int) oString32[i] - 119789)); + //Bold Italic Capital + else if(oString32[i] >= 119912 && oString32[i] <= 119937) + wsText16.push_back((wchar_t)((unsigned int) oString32[i] - 119847)); + //Bold Italic Small + else if(oString32[i] >= 119938 && oString32[i] <= 119963) + wsText16.push_back((wchar_t)((unsigned int) oString32[i] - 119841)); + //Script Capital + else if(oString32[i] >= 119964 && oString32[i] <= 119989) + wsText16.push_back((wchar_t)((unsigned int) oString32[i] - 119899)); + //Script Small + else if(oString32[i] >= 119990 && oString32[i] <= 120015) + wsText16.push_back((wchar_t)((unsigned int) oString32[i] - 119893)); + //Bold Script Capital + else if(oString32[i] >= 120016 && oString32[i] <= 120041) + wsText16.push_back((wchar_t)((unsigned int) oString32[i] - 119951)); + //Bold Script Small + else if(oString32[i] >= 120042 && oString32[i] <= 120067) + wsText16.push_back((wchar_t)((unsigned int) oString32[i] - 119945)); + //Fraktur Capital(120093?) + else if(oString32[i] >= 120068 && oString32[i] <= 120092) + wsText16.push_back((wchar_t)((unsigned int) oString32[i] - 112003)); + //Fraktur Small + else if(oString32[i] >= 120094 && oString32[i] <= 120119) + wsText16.push_back((wchar_t)((unsigned int) oString32[i] - 119997)); + //Double-Struck Capital(120145?) + else if(oString32[i] >= 120120 && oString32[i] <= 120144) + wsText16.push_back((wchar_t)((unsigned int) oString32[i] - 120055)); + //Double-Struck Small + else if(oString32[i] >= 120146 && oString32[i] <= 120171) + wsText16.push_back((wchar_t)((unsigned int) oString32[i] - 120049)); + //Bold Fraktur Capital + else if(oString32[i] >= 120172 && oString32[i] <= 120197) + wsText16.push_back((wchar_t)((unsigned int) oString32[i] - 120107)); + //Bold Fraktur Small + else if(oString32[i] >= 120198 && oString32[i] <= 120223) + wsText16.push_back((wchar_t)((unsigned int) oString32[i] - 120101)); + //Sans-Serif Capital + else if(oString32[i] >= 120224 && oString32[i] <= 120249) + wsText16.push_back((wchar_t)((unsigned int) oString32[i] - 120159)); + //Sans-Serif Small + else if(oString32[i] >= 120250 && oString32[i] <= 120275) + wsText16.push_back((wchar_t)((unsigned int) oString32[i] - 120153)); + //Sans-Serif Bold Capital + else if(oString32[i] >= 120276 && oString32[i] <= 120301) + wsText16.push_back((wchar_t)((unsigned int) oString32[i] - 120211)); + //Sans-Serif Bold Small + else if(oString32[i] >= 120302 && oString32[i] <= 120327) + wsText16.push_back((wchar_t)((unsigned int) oString32[i] - 120205)); + //Sans-Serif Italic Capital + else if(oString32[i] >= 120328 && oString32[i] <= 120353) + wsText16.push_back((wchar_t)((unsigned int) oString32[i] - 120263)); + //Sans-Serif Italic Small + else if(oString32[i] >= 120354 && oString32[i] <= 120379) + wsText16.push_back((wchar_t)((unsigned int) oString32[i] - 120257)); + //Sans-Serif Bold Italic Capital + else if(oString32[i] >= 120380 && oString32[i] <= 120405) + wsText16.push_back((wchar_t)((unsigned int) oString32[i] - 120315)); + //Sans-Serif Bold Italic Small + else if(oString32[i] >= 120406 && oString32[i] <= 120431) + wsText16.push_back((wchar_t)((unsigned int) oString32[i] - 120309)); + //Monospace Capital + else if(oString32[i] >= 120432 && oString32[i] <= 120457) + wsText16.push_back((wchar_t)((unsigned int) oString32[i] - 120367)); + //Monospace Small + else if(oString32[i] >= 120458 && oString32[i] <= 120483) + wsText16.push_back((wchar_t)((unsigned int) oString32[i] - 120361)); + //Bold Capital Alpha + else if(oString32[i] >= 120488 && oString32[i] <= 120512) + wsText16.push_back((wchar_t)((unsigned int) oString32[i] - 119575)); + //Bold Small Alpha + else if(oString32[i] >= 120514 && oString32[i] <= 120538) + wsText16.push_back((wchar_t)((unsigned int) oString32[i] - 119569)); + //Italic Capital Alpha + else if(oString32[i] >= 120546 && oString32[i] <= 120570) + wsText16.push_back((wchar_t)((unsigned int) oString32[i] - 119633)); + //Italic Small Alpha + else if(oString32[i] >= 120572 && oString32[i] <= 120596) + wsText16.push_back((wchar_t)((unsigned int) oString32[i] - 119627)); + //Bold Italic Capital Alpha + else if(oString32[i] >= 120604 && oString32[i] <= 120628) + wsText16.push_back((wchar_t)((unsigned int) oString32[i] - 119691)); + //Bold Italic Small Alpha + else if(oString32[i] >= 120630 && oString32[i] <= 120654) + wsText16.push_back((wchar_t)((unsigned int) oString32[i] - 119685)); + //Sans-Serif Bold Capital Alpha + else if(oString32[i] >= 120662 && oString32[i] <= 120686) + wsText16.push_back((wchar_t)((unsigned int) oString32[i] - 119749)); + //Sans-Serif Bold Small Alpha + else if(oString32[i] >= 120688 && oString32[i] <= 120712) + wsText16.push_back((wchar_t)((unsigned int) oString32[i] - 119743)); + //Sans-Serif Bold Italic Capital Alpha + else if(oString32[i] >= 120720 && oString32[i] <= 120744) + wsText16.push_back((wchar_t)((unsigned int) oString32[i] - 119807)); + //Sans-Serif Bold Italic Small Alpha + else if(oString32[i] >= 120746 && oString32[i] <= 120770) + wsText16.push_back((wchar_t)((unsigned int) oString32[i] - 119801)); + //Bold Digit Zero + else if(oString32[i] >= 120782 && oString32[i] <= 120791) + wsText16.push_back((wchar_t)((unsigned int) oString32[i] - 120734)); + //Double-Struck Digit Zero + else if(oString32[i] >= 120792 && oString32[i] <= 120801) + wsText16.push_back((wchar_t)((unsigned int) oString32[i] - 120744)); + //Sans-Serif Digit Zero + else if(oString32[i] >= 120802 && oString32[i] <= 120811) + wsText16.push_back((wchar_t)((unsigned int) oString32[i] - 120754)); + //Monospace Digit Zero + else if(oString32[i] >= 120822 && oString32[i] <= 120831) + wsText16.push_back((wchar_t)((unsigned int) oString32[i] - 120774)); + //Sans-Serif Bold Digit Zero + else if(oString32[i] >= 120812 && oString32[i] <= 120821) + wsText16.push_back((wchar_t)((unsigned int) oString32[i] - 120764)); + else + wsText16.push_back(oString32[i]); + } + return wsText16; + } +//class COneElement + COneElement::COneElement():m_stAttribute(nullptr),m_iStyle(0) + {} + COneElement::COneElement(std::wstring &wsOneElement):m_stAttribute(nullptr),m_iStyle(0) + { + } + COneElement::~COneElement() + {} + COneElement* COneElement::CreateElement(std::wstring &wsOneElement) + { + if(wsOneElement == L"") + return nullptr; + std::wstring wsAnnotation = CSpecialChar::DefinitionSpecialChar(wsOneElement); + if(COOXml2Odf::IsDigit(wsOneElement)) + return new CNumberOrLetter(wsOneElement,StarMath::TypeElement::number); + else if(!wsAnnotation.empty()) + return new CSpecialChar(wsOneElement,wsAnnotation); + else if(wsOneElement == L" ") + return new CSpace(); + wsAnnotation.clear(); + wsAnnotation = CBinOperator::BinOperatorSymbolForAnnotation(wsOneElement); + if(wsAnnotation != L"") + return new CBinOperator(wsOneElement,wsAnnotation); + else + wsAnnotation.clear(); + wsAnnotation = CRelationsAndOperationsOnSets::TransformationForAnnotation(wsOneElement); + if(wsAnnotation != L"") + return new CRelationsAndOperationsOnSets(wsOneElement,wsAnnotation); + if(COOXml2Odf::IsAlpha(wsOneElement)) + return new CNumberOrLetter(wsOneElement,StarMath::TypeElement::letter); + else + return new CSpecialChar(wsOneElement,L""); + } + void COneElement::SetType(const TypeElement &enType) + { + m_enType = enType; + } + TypeElement COneElement::GetType() + { + return m_enType; + } + void COneElement::SetAttribute(StValuePr *stAttribute) + { + if(m_stAttribute == nullptr) + m_stAttribute = stAttribute; + } + StValuePr* COneElement::GetAttribute() + { + return m_stAttribute; + } + void COneElement::ConversionAttribute(StValuePr* pAttribute, StStyleMenClose &stStyle, XmlUtils::CXmlWriter *pXmlWrite, std::wstring &wsAnnotation, const bool& bDelimiter) + { + if(pAttribute == nullptr) + return; + if(!pAttribute->m_wsColor.empty()) + { + pXmlWrite->WriteNodeBegin(L"mstyle",true); + std::wstring wsColor; + bool bColorName = COOXml2Odf::ColorCheck(pAttribute->m_wsColor,wsColor); + if(!bColorName) + wsColor = L"#" + pAttribute->m_wsColor; + pXmlWrite->WriteAttribute(L"mathcolor",wsColor); + pXmlWrite->WriteNodeEnd(L"w",true,false); + if(bColorName) + wsAnnotation += L"color " + wsColor + L" "; + else + wsAnnotation += L"color hex " + pAttribute->m_wsColor + L" "; + stStyle.m_iStyle++; + } + if(pAttribute->m_iSize != 0) + { + std::wstring wsSize = std::to_wstring(pAttribute->m_iSize); + pXmlWrite->WriteNodeBegin(L"mstyle",true); + pXmlWrite->WriteAttribute(L"mathsize",wsSize); + pXmlWrite->WriteNodeEnd(L"w",true,false); + wsAnnotation += L"size " + wsSize + L" "; + stStyle.m_iStyle++; + } + if(pAttribute->m_enStyle != SimpleTypes::EStyle::stylePlain) + { + std::wstring wsStyle; + switch(pAttribute->m_enStyle) + { + case SimpleTypes::EStyle::styleBold: + { + wsStyle = L"bold"; + wsAnnotation += L"bold "; + break; + } + case SimpleTypes::EStyle::styleItalic: + { + wsStyle = L"italic"; + wsAnnotation += L"ital "; + break; + } + case SimpleTypes::EStyle::styleBoldItalic: + { + wsStyle = L"bold-italic"; + wsAnnotation += L"bold ital "; + break; + } + } + pXmlWrite->WriteNodeBegin(L"mstyle",true); + pXmlWrite->WriteAttribute(L"mathvariant",wsStyle); + pXmlWrite->WriteNodeEnd(L"w",true,false); + stStyle.m_iStyle++; + } + if(pAttribute->m_enFont != StarMath::TypeFont::empty) + { + std::wstring wsFont; + switch(pAttribute->m_enFont) + { + case StarMath::TypeFont::fixed: + { + wsFont = L"monospace"; + break; + } + case StarMath::TypeFont::sans: + { + wsFont = L"sans-serif"; + break; + } + case StarMath::TypeFont::serif: + { + wsFont = L"normal"; + break; + } + } + pXmlWrite->WriteNodeBegin(L"mstyle",true); + pXmlWrite->WriteAttribute(L"mathvariant",wsFont); + pXmlWrite->WriteNodeEnd(L"w",true,false); + stStyle.m_iStyle++; + } + if(pAttribute->m_bStrike) + { + pXmlWrite->WriteNodeBegin(L"menclose",true); + pXmlWrite->WriteAttribute(L"notation",L"horizontalstrike"); + pXmlWrite->WriteNodeEnd(L"w",true,false); + wsAnnotation += L"overstrike "; + stStyle.m_bMenClose = true; + } + if(!bDelimiter) + pAttribute->Release(); + } + bool COneElement::CheckStyle() + { + return (m_iStyle != 0); + } + unsigned int COneElement::GetStyle() + { + return m_iStyle; + } +//class CNumberOrLetter + CNumberOrLetter::CNumberOrLetter(const std::wstring &wsElement, const TypeElement &enType) + { + m_wsElement = wsElement; + m_enTypeElement = enType; + SetType(TypeElement::String); + } + CNumberOrLetter::~CNumberOrLetter() + {} + void CNumberOrLetter::Conversion(XmlUtils::CXmlWriter *pXmlWrite, std::wstring &wsAnnotation) + { + StStyleMenClose stStyle; + bool bCloseBracket(false); + COneElement::ConversionAttribute(GetAttribute(),stStyle,pXmlWrite,wsAnnotation); + if(GetAttribute()!= nullptr && m_wsElement.size()>1) + { + switch(m_enTypeElement) + { + case StarMath::TypeElement::number: + { + if(!COOXml2Odf::IsDigit(m_wsElement)) + { + wsAnnotation += L"{ "; + bCloseBracket = true; + } + break; + } + case StarMath::TypeElement::letter: + { + if(!COOXml2Odf::IsAlpha(m_wsElement)) + { + wsAnnotation += L"{ "; + bCloseBracket = true; + } + break; + } + default: + break; + } + } + switch(m_enTypeElement) + { + case StarMath::TypeElement::number: + { + pXmlWrite->WriteNodeBegin(L"mn",false); + pXmlWrite->WriteString(XmlUtils::EncodeXmlString(m_wsElement)); + pXmlWrite->WriteNodeEnd(L"mn",false,false); + wsAnnotation += m_wsElement + L" "; + break; + } + case StarMath::TypeElement::letter: + { + pXmlWrite->WriteNodeBegin(L"mi",true); + pXmlWrite->WriteAttribute(L"mathvariant",L"italic"); + pXmlWrite->WriteNodeEnd(L"w",true,false); + pXmlWrite->WriteString(XmlUtils::EncodeXmlString(m_wsElement)); + pXmlWrite->WriteNodeEnd(L"mi",false,false); + wsAnnotation += m_wsElement + L" "; + break; + } + case StarMath::TypeElement::letter_u32: + { + COOXml2Odf::MTextRecording(pXmlWrite,wsAnnotation,m_wsElement); + break; + } + default: + break; + } + if(bCloseBracket) + wsAnnotation += L"} "; + COOXml2Odf::StyleClosing(stStyle,pXmlWrite); + } + void CNumberOrLetter::Parse(std::wstring::iterator &itStart, std::wstring::iterator &itEnd, COneElement *&pElement) + {} + const std::wstring& CNumberOrLetter::GetString() + { + return m_wsElement; + } + void CNumberOrLetter::AddingStrings(const std::wstring &wsString) + { + m_wsElement += wsString; + } +//class CBinOperator + CBinOperator::~CBinOperator() + { + delete m_pRightArg; + delete m_pLeftArg; + } + void CBinOperator::Parse(std::wstring::iterator &itStart, std::wstring::iterator &itEnd, COneElement*& pElement) + { + std::wstring wsTempElement = COOXml2Odf::ParsingText(itStart,itEnd); + COneElement* pointElement; + pointElement = COneElement::CreateElement(wsTempElement); + if(pointElement != nullptr && pointElement->GetType() == TypeElement::Connection && pointElement->GetType() == TypeElement::BinOperator) + pElement = pointElement; + else + m_pRightArg = pointElement; + } + void CBinOperator::Conversion(XmlUtils::CXmlWriter *pXmlWrite, std::wstring &wsAnnotation) + { + StStyleMenClose stStyle; + if(m_pLeftArg == nullptr && m_pRightArg == nullptr) + { + if(GetAttribute() != nullptr && m_enTypeBinOp != TypeElement::undefine) + { + COneElement::ConversionAttribute(GetAttribute(),stStyle,pXmlWrite,wsAnnotation); + pXmlWrite->WriteNodeBegin(L"mtext",false); + pXmlWrite->WriteString(m_wsAnnotation); + pXmlWrite->WriteNodeEnd(L"mtext",false,false); + wsAnnotation += L"\u0026quot;" + m_wsAnnotation + L"\u0026quot;"; + COOXml2Odf::StyleClosing(stStyle,pXmlWrite); + return; + } + } + pXmlWrite->WriteNodeBegin(L"mrow",false); + if(GetAttribute() != nullptr && m_enTypeBinOp != TypeElement::undefine) + COneElement::ConversionAttribute(GetAttribute(),stStyle,pXmlWrite,wsAnnotation); + else + { + if(m_pLeftArg != nullptr) + m_pLeftArg->Conversion(pXmlWrite,wsAnnotation); + } + COOXml2Odf::RecordingMoNode(m_wsSymbolBinOp,pXmlWrite); + wsAnnotation += m_wsAnnotation + L" "; + if(m_pRightArg != nullptr) + m_pRightArg->Conversion(pXmlWrite,wsAnnotation); + COOXml2Odf::StyleClosing(stStyle,pXmlWrite); + pXmlWrite->WriteNodeEnd(L"mrow",false,false); + } + void CBinOperator::SetLeftArg(COneElement *pElement) + { + m_pLeftArg = pElement; + } + void CBinOperator::SetRightArg(COneElement *pElement) + { + m_pRightArg = pElement; + } + bool CBinOperator::CheckRightArg() + { + return (m_pRightArg != nullptr); + } + bool CBinOperator::CheckRightArg(COneElement* pElement) + { + if(pElement == nullptr) + return false; + switch(pElement->GetType()) + { + case TypeElement::BinOperator: + { + CBinOperator* pTemp = dynamic_cast(pElement); + return pTemp->CheckRightArg(); + } + case TypeElement::Connection: + { + CRelationsAndOperationsOnSets* pTemp = dynamic_cast(pElement); + return pTemp->CheckRightArg(); + } + default: + return true; + } + } + bool CBinOperator::CheckLeftArg() + { + return (m_pLeftArg !=nullptr); + } + template + bool SetRightArg(T* pElement,COneElement* pRightArg) + { + if(!pElement->CheckRightArg()) + { + pElement->SetRightArg(pRightArg); + return true; + } + return false; + } + bool CBinOperator::SetRightArg(COneElement *pBinOp, COneElement *pRightArg) + { + switch(pBinOp->GetType()) + { + case TypeElement::BinOperator: + { + return StarMath::SetRightArg(dynamic_cast(pBinOp),pRightArg); + } + case TypeElement::Connection: + { + return StarMath::SetRightArg(dynamic_cast(pBinOp),pRightArg); + } + default: + return false; + } + } + bool CBinOperator::SetLeftArg(COneElement *pBinOp, COneElement *pLeftArg) + { + switch(pBinOp->GetType()) + { + case TypeElement::BinOperator: + { + CBinOperator* pTemp = dynamic_cast(pBinOp); + switch(pTemp->GetTypeBinOp()) + { + case TypeElement::neg: + return false; + case TypeElement::plus: + case TypeElement::minus: + case TypeElement::plus_minus: + case TypeElement::minus_plus: + { + if(pTemp->GetAttribute() == nullptr) + if(!pTemp->CheckLeftArg() && CBinOperator::CheckRightArg(pLeftArg)) + { + pTemp->SetLeftArg(pLeftArg); + return true; + } + return false; + } + default: + if(!pTemp->CheckLeftArg() && CBinOperator::CheckRightArg(pLeftArg)) + { + pTemp->SetLeftArg(pLeftArg); + return true; + } + else + return false; + } + } + case TypeElement::Connection: + { + CRelationsAndOperationsOnSets* pTemp = dynamic_cast(pBinOp); + if(!pTemp->CheckLeftArg() && CBinOperator::CheckRightArg(pLeftArg)) + { + pTemp->SetLeftArg(pLeftArg); + return true; + } + return false; + } + } + } + TypeElement CBinOperator::GetTypeBinOp() + { + return m_enTypeBinOp; + } + std::wstring CBinOperator::BinOperatorSymbolForAnnotation(const std::wstring &wsSymbol) + { + if(wsSymbol == L"+") return wsSymbol; + else if(wsSymbol == L"-") return wsSymbol; + else if(L"\u00B1" == wsSymbol) return L"+-"; + else if(L"\u2213" == wsSymbol) return L"-+"; + else if(L"*" == wsSymbol) return wsSymbol; + else if(L"\u00B7" == wsSymbol) return L"cdot"; + else if(L"\u00D7" == wsSymbol) return L"times"; + else if(L"\u00F7" == wsSymbol) return L"div"; + else if(L"\u2295" == wsSymbol) return L"oplus"; + else if(L"\u2296" == wsSymbol) return L"ominus"; + else if(L"\u2299" == wsSymbol) return L"odot"; + else if(L"\u2297" == wsSymbol) return L"otimes"; + else if(L"\u2298" == wsSymbol) return L"odivide"; + else if(L"\u2218" == wsSymbol) return L"circ"; + else if(L"\u2227" == wsSymbol) return L"and"; + else if(L"\u2228" == wsSymbol) return L"or"; + else if(L"\u00AC" == wsSymbol) return L"neg"; + else return L""; + } + bool CBinOperator::UnaryCheck(const StValuePr *pValue, const TypeElement &enType) + { + if(pValue != nullptr) + { + switch(enType) + { + case TypeElement::plus: + case TypeElement::plus_minus: + case TypeElement::minus: + case TypeElement::minus_plus: + return true; + default: + return false; + } + } + else + return false; + } +//class RelationAndOperation + CRelationsAndOperationsOnSets::~CRelationsAndOperationsOnSets() + { + delete m_pLeftArg; + delete m_pRightArg; + } + void CRelationsAndOperationsOnSets::Parse(std::wstring::iterator &itStart, std::wstring::iterator &itEnd, COneElement *&pElement) + { + std::wstring wsTempElement = COOXml2Odf::ParsingText(itStart,itEnd); + COneElement* pTempElement; + pTempElement = COneElement::CreateElement(wsTempElement); + if(pTempElement != nullptr && pTempElement->GetType() == TypeElement::Connection && pTempElement->GetType() == TypeElement::BinOperator) + pElement = pTempElement; + else + m_pRightArg = pTempElement; + } + void CRelationsAndOperationsOnSets::Conversion(XmlUtils::CXmlWriter *pXmlWrite, std::wstring &wsAnnotation) + { + if(m_pLeftArg == nullptr && m_pRightArg == nullptr) + COOXml2Odf::MTextRecording(pXmlWrite,wsAnnotation,m_wsSymbol); + else + { + pXmlWrite->WriteNodeBegin(L"mrow",false); + if(m_pLeftArg!= nullptr) + { + if(GetAttribute() != nullptr) + { + GetAttribute()->AddRef(); + m_pLeftArg->SetAttribute(GetAttribute()); + } + m_pLeftArg->Conversion(pXmlWrite,wsAnnotation); + } + if(m_wsAnnotationSymbol == L"\u0026lt;" || m_wsAnnotationSymbol == L"\u0026gt;") + COOXml2Odf::RecordingMoNode(m_wsAnnotationSymbol,pXmlWrite); + else + COOXml2Odf::RecordingMoNode(m_wsSymbol,pXmlWrite); + wsAnnotation += m_wsAnnotationSymbol + L" "; + if(m_pRightArg != nullptr) + { + if(GetAttribute() != nullptr) + { + GetAttribute()->AddRef(); + m_pRightArg->SetAttribute(GetAttribute()); + } + m_pRightArg->Conversion(pXmlWrite,wsAnnotation); + } + pXmlWrite->WriteNodeEnd(L"mrow",false,false); + } + } + void CRelationsAndOperationsOnSets::SetLeftArg(COneElement *pElement) + { + m_pLeftArg = pElement; + } + void CRelationsAndOperationsOnSets::SetRightArg(COneElement *pElement) + { + m_pRightArg = pElement; + } + bool CRelationsAndOperationsOnSets::CheckLeftArg() + { + return (m_pLeftArg != nullptr); + } + bool CRelationsAndOperationsOnSets::CheckRightArg() + { + return (m_pRightArg != nullptr); + } + std::wstring CRelationsAndOperationsOnSets::TransformationForAnnotation(std::wstring &wsSymbol) + { + if(wsSymbol == L"=") + return L"= "; + else if(wsSymbol == L"\u2260") + return L"\u0026lt;\u0026gt; "; + else if(wsSymbol == L"\u003C") + return L"\u0026lt;"; + else if(wsSymbol == L"\u2264") + return L"\u0026lt;= "; + else if(wsSymbol == L"\u2A7D") + return L"leslant "; + else if(wsSymbol == L"\u003E") + return L"\u0026gt;"; + else if(wsSymbol == L"\u2265") + return L"\u0026gt;= "; + else if(wsSymbol == L"\u2A7E") + return L"geslant "; + else if(wsSymbol == L"\u226A") + return L"\u0026lt;\u0026lt; "; + else if(wsSymbol == L"\u226B") + return L"\u0026gt;\u0026gt; "; + else if(wsSymbol == L"\u2248") + return L"approx "; + else if(wsSymbol == L"\u223C") + return L"sim "; + else if(wsSymbol == L"\u2243") + return L"simeq "; + else if(wsSymbol == L"\u2261") + return L"equiv "; + else if(wsSymbol == L"\u221D") + return L"prop "; + else if(wsSymbol == L"\u2225") + return L"parallel "; + else if(wsSymbol == L"\u22A5") + return L"ortho "; + else if(wsSymbol == L"\u2223") + return L"divides "; + else if(wsSymbol == L"\u2224") + return L"ndivides "; + else if(wsSymbol == L"\u2192") + return L"toward "; + else if(wsSymbol == L"\u22B7") + return L"transl "; + else if(wsSymbol == L"\u22B6") + return L"transr "; + else if(wsSymbol == L"\u225D") + return L"def "; + else if(wsSymbol == L"\u21D0") + return L"dlarrow "; + else if(wsSymbol == L"\u21D4") + return L"dlrarrow "; + else if(wsSymbol == L"\u21D2") + return L"drarrow "; + else if(wsSymbol == L"\u227A") + return L"prec "; + else if(wsSymbol == L"\u227B") + return L"succ "; + else if(wsSymbol == L"\u227C") + return L"preccurlyeq "; + else if(wsSymbol == L"\u227D") + return L"succcurlyeq "; + else if(wsSymbol == L"\u227E") + return L"precsim "; + else if(wsSymbol == L"\u227F") + return L"succsim "; + else if(wsSymbol == L"\u2280") + return L"nprec "; + else if(wsSymbol == L"\u2281") + return L"nsucc "; + else if(wsSymbol == L"\u2208") + return L"in "; + else if(wsSymbol == L"\u2209") + return L"notin "; + else if(wsSymbol == L"\u220B") + return L"owns "; + else if(wsSymbol == L"\u22C2") + return L"intersection "; + else if(wsSymbol == L"\u22C3") + return L"union "; + else if(wsSymbol == L"\u2216") + return L"setminus "; + else if(wsSymbol == L"\u2215") + return L"setquotient "; + else if(wsSymbol == L"\u2282") + return L"subset "; + else if(wsSymbol == L"\u2286") + return L"subseteq "; + else if(wsSymbol == L"\u2283") + return L"supset "; + else if(wsSymbol == L"\u2287") + return L"supseteq "; + else if(wsSymbol == L"\u2284") + return L"nsubset "; + else if(wsSymbol == L"\u2288") + return L"nsubseteq "; + else if(wsSymbol == L"\u2285") + return L"nsupset "; + else if(wsSymbol == L"\u2289") + return L"nsupseteq "; + else + return L""; + } +//class CSpace + CSpace::~CSpace() + {} + void CSpace::Parse(std::wstring::iterator &itStart, std::wstring::iterator &itEnd, COneElement *&pElement) + {} + void CSpace::Conversion(XmlUtils::CXmlWriter *pXmlWrite, std::wstring &wsAnnotation) + { + pXmlWrite->WriteNodeBegin(L"mspace",true); + pXmlWrite->WriteNodeEnd(L"w",true,true); + wsAnnotation += L"` "; + } +//class CSpecialChar + CSpecialChar::~CSpecialChar() + {} + void CSpecialChar::Parse(std::wstring::iterator &itStart, std::wstring::iterator &itEnd, COneElement *&pElement) + {} + void CSpecialChar::Conversion(XmlUtils::CXmlWriter *pXmlWrite, std::wstring &wsAnnotation) + { + StStyleMenClose stStyle; + if(GetAttribute() != nullptr) + COneElement::ConversionAttribute(GetAttribute(),stStyle,pXmlWrite,wsAnnotation); + if(!m_wsAnnotation.empty()) + { + pXmlWrite->WriteNodeBegin(L"mi",true); + pXmlWrite->WriteAttribute(L"mathvariant",L"normal"); + pXmlWrite->WriteNodeEnd(L"w",true,false); + pXmlWrite->WriteString(m_wsSymbol); + pXmlWrite->WriteNodeEnd(L"mi",false,false); + wsAnnotation += m_wsAnnotation + L" "; + } + else if(!m_wsSymbol.empty()) + COOXml2Odf::MTextRecording(pXmlWrite,wsAnnotation,m_wsSymbol); + COOXml2Odf::StyleClosing(stStyle,pXmlWrite); + } + std::wstring CSpecialChar::DefinitionSpecialChar(const std::wstring &wsSymbol) + { + if(L"\u2205" == wsSymbol) return L"emptyset"; + else if(L"\u2135" == wsSymbol) return L"aleph"; + else if(L"\u2115" == wsSymbol) return L"setN"; + else if(L"\u2124" == wsSymbol) return L"setZ"; + else if(L"\u211A" == wsSymbol) return L"setQ"; + else if(L"\u211D" == wsSymbol) return L"setR"; + else if(L"\u2102" == wsSymbol) return L"setC"; + else if(L"\u221E" == wsSymbol) return L"infinity"; + else if(L"\u2202" == wsSymbol) return L"partial"; + else if(L"\u2207" == wsSymbol) return L"nabla"; + else if(L"\u2203" == wsSymbol) return L"exists"; + else if(L"\u2204" == wsSymbol) return L"notexists"; + else if(L"\u2200" == wsSymbol) return L"forall"; + else if(L"\u0127" == wsSymbol) return L"hbar"; + else if(L"\u019B" == wsSymbol) return L"lambdabar"; + else if(L"\u211C" == wsSymbol) return L"Re"; + else if(L"\u2111" == wsSymbol) return L"Im"; + else if(L"\u2118" == wsSymbol) return L"wp"; + else if(L"\u2112" == wsSymbol) return L"laplace"; + else if(L"\u2131" == wsSymbol) return L"fourier"; + else if(L"\u03F6" == wsSymbol) return L"backepsilon"; + else if(L"\u2190" == wsSymbol) return L"leftarrow"; + else if(L"\u2794" == wsSymbol) return L"rightarrow"; + else if(L"\u2191" == wsSymbol) return L"uparrow"; + else if(L"\u2193" == wsSymbol) return L"downarrow"; + else if(L"\u2026" == wsSymbol) return L"dotslow"; + else if(L"\u22EF" == wsSymbol) return L"dotsaxis"; + else if(L"\u22EE" == wsSymbol) return L"dotsvert"; + else if(L"\u22F0" == wsSymbol) return L"dotsup"; + else if(L"\u22F1" == wsSymbol) return L"dotsdown"; + else if(L"\u0391" == wsSymbol) return L"%ALPHA"; + else if(L"\u03B1" == wsSymbol) return L"%alpha"; + else if(L"\u0396" == wsSymbol) return L"%ZETA"; + else if(L"\u03B6" == wsSymbol) return L"%zeta"; + else if(L"\u039B" == wsSymbol) return L"%LAMBDA"; + else if(L"\u03BB" == wsSymbol) return L"%lambda"; + else if(L"\u03A0" == wsSymbol) return L"%PI"; + else if(L"\u03C0" == wsSymbol) return L"%pi"; + else if(L"\u03A6" == wsSymbol) return L"%PHI"; + else if(L"\u03C6" == wsSymbol) return L"%phi"; + else if(L"\u03B5" == wsSymbol) return L"%varepsilon"; + else if(L"\u03B9" == wsSymbol) return L"%iota"; + else if(L"\u0399" == wsSymbol) return L"%IOTA"; + else if(L"\u03BE" == wsSymbol) return L"%xi"; + else if(L"\u039E" == wsSymbol) return L"%XI"; + else if(L"\u03F1" == wsSymbol) return L"%varrho"; + else if(L"\u0392" == wsSymbol) return L"%BETA"; + else if(L"\u03B2" == wsSymbol) return L"%beta"; + else if(L"\u0397" == wsSymbol) return L"%ETA"; + else if(L"\u03B7" == wsSymbol) return L"%eta"; + else if(L"\u039C" == wsSymbol) return L"%MU"; + else if(L"\u03BC" == wsSymbol) return L"%mu"; + else if(L"\u03A1" == wsSymbol) return L"%RHO"; + else if(L"\u03C1" == wsSymbol) return L"%rho"; + else if(L"\u03A7" == wsSymbol) return L"%CHI"; + else if( L"\u03C7" == wsSymbol) return L"%chi"; + else if(L"\u03BA" == wsSymbol) return L"%kappa"; + else if(L"\u039A" == wsSymbol) return L"%KAPPA"; + else if(L"\u039F" == wsSymbol) return L"%OMICRON"; + else if(L"\u03BF" == wsSymbol) return L"%omicron"; + else if(L"\u03A3" == wsSymbol) return L"%SIGMA"; + else if(L"\u03C3" == wsSymbol) return L"%sigma"; + else if(L"\u03C6" == wsSymbol) return L"%varphi"; + else if(L"\u0393" == wsSymbol) return L"%GAMMA"; + else if(L"\u03B3" == wsSymbol) return L"%gamma"; + else if(L"\u0398" == wsSymbol) return L"%THETA"; + else if(L"\u03B8" == wsSymbol) return L"%theta"; + else if(L"\u039D" == wsSymbol) return L"%NU"; + else if(L"\u03BD" == wsSymbol) return L"%nu"; + else if(L"\u03A8" == wsSymbol) return L"%PSI"; + else if(L"\u03C8" == wsSymbol) return L"%psi"; + else if(L"\u03DB" == wsSymbol) return L"%varsigma"; + else if(L"\u0394" == wsSymbol) return L"%DELTA"; + else if(L"\u03B4" == wsSymbol) return L"%delta"; + else if(L"\u03A4" == wsSymbol) return L"%TAU"; + else if(L"\u03C4" == wsSymbol) return L"%tau"; + else if(L"\u03A9" == wsSymbol) return L"%OMEGA"; + else if(L"\u03C9" == wsSymbol) return L"%omega"; + else if(L"\u03D6" == wsSymbol) return L"%varphi"; + else if(L"\u0395" == wsSymbol) return L"%EPSILON"; + else if(L"\u03B5" == wsSymbol) return L"%epsilon"; + else if(L"\u03A5" == wsSymbol) return L"%UPSILON"; + else if(L"\u03C5" == wsSymbol) return L"%upsilon"; + else if(L"\u03D1" == wsSymbol) return L"%vartheta"; + else return L""; + } +} diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cooxml2odf.h b/OdfFile/Reader/Converter/StarMath2OOXML/cooxml2odf.h new file mode 100644 index 00000000000..fa5e9d00333 --- /dev/null +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cooxml2odf.h @@ -0,0 +1,258 @@ +#ifndef COOXML2ODF_H +#define COOXML2ODF_H +#include"../../../Writer/Converter/Converter.h" +#include"../../../../OOXML/DocxFormat/Math/oMathPara.h" +#include "../../../../DesktopEditor/xml/include/xmlwriter.h" +#include "../../../../OOXML/Base/Unit.h" +#include "../../../../OOXML/Common/SimpleTypes_OMath.h" +#include "../../../../DesktopEditor/common/StringUTF32.h" +#include "typeselements.h" +#include "fontType.h" +#include +#include +#include +#include +#include + +namespace StarMath +{ + struct StValuePr + { + StValuePr():m_wsTypeName(L""),m_wsBegBracket(L""),m_wsEndBracket(L""),m_wsChr(L""),m_wsColor(L""),m_bSupHide(false),m_bSubHide(false),m_enStyle(SimpleTypes::EStyle::stylePlain),m_iSize(0),m_enPos(SimpleTypes::ETopBot::tbBot),m_enVert(SimpleTypes::ETopBot::tbBot),m_enFont(StarMath::TypeFont::empty),m_iCount(0),m_bStrike(false) + { + AddRef(); + } + std::wstring m_wsTypeName,m_wsChr; + std::wstring m_wsBegBracket,m_wsEndBracket; + std::wstring m_wsColor; + bool m_bSupHide,m_bSubHide; + SimpleTypes::EStyle m_enStyle; + int m_iSize; + SimpleTypes::ETopBot m_enPos,m_enVert; + StarMath::TypeFont m_enFont; + int m_iCount; + bool m_bStrike; + void AddRef() + { + m_iCount++; + } + void Release() + { + m_iCount--; + if(m_iCount == 0) + delete this; + } + }; + struct StStyleMenClose + { + StStyleMenClose():m_iStyle(0),m_bMenClose(false) + {} + unsigned int m_iStyle; + bool m_bMenClose; + }; + class COneElement; + class COOXml2Odf + { + public: + COOXml2Odf(); + ~COOXml2Odf(); + void StartConversion(OOX::WritingElement* pNode); + void ConversionMathPara(OOX::Logic::COMathPara* pMathPara); + void NodeDefinition(OOX::WritingElement* pNode, const bool &bMatrix = false); + void ConversionMath(OOX::Logic::COMath* pMath); + std::vector ConversionMT(OOX::Logic::CMText* pMt, const StValuePr* pValue, const bool &bMRpr = false); + void ConversionMF(OOX::Logic::CFraction* pMf); + StStyleMenClose ConversionCtrlPr(OOX::Logic::CCtrlPr* pCtrlPr, const bool& bDelimiter = false); + StStyleMenClose ConversionCMPr(OOX::Logic::CMPr* pMPr); + StValuePr ConversionFpr(OOX::Logic::CFPr* pFpr); + std::wstring ConversionType(OOX::Logic::CType* pType); + void ConversionMd(OOX::Logic::CDelimiter* pDel); + std::wstring BracketForAnnotation(const std::wstring& wsBracket,const bool& bBeg); + void ConversionNary(OOX::Logic::CNary* pNary); + void ConversionSsub(OOX::Logic::CSSub* pSsub); + void ConversionSub(OOX::Logic::CSub* pSub, OOX::Logic::CElement *pElement); + void ConversionSub(OOX::Logic::CSub* pSub); + void ConversionSsup(OOX::Logic::CSSup* pSsup); + void ConversionSup(OOX::Logic::CSup* pSup,OOX::Logic::CElement* pElement); + void ConversionSup(OOX::Logic::CSup* pSup); + void ConversionElement(OOX::Logic::CElement* pElement); + std::vector ConversionMRun(OOX::Logic::CMRun* pMRun); + void ConversionAcc(OOX::Logic::CAcc* pAcc); + void ConversionFunc(OOX::Logic::CFunc* pFunc); + StStyleMenClose ConversionFuncPr(OOX::Logic::CFuncPr* pFuncPr); + void ConversionBox(OOX::Logic::CBox* pBox); + void ConversionTextVector(std::vector& arLine, std::vector& arNewLine); + void ConversionVectorWritingElement(std::vector arWrElements); + void ConversionMatrix(OOX::Logic::CMatrix *pMatrix); + void ConversionMr(OOX::Logic::CMr* pMr); + void ConversionRad(OOX::Logic::CRad* pRad); + StStyleMenClose ConversionRadPr(OOX::Logic::CRadPr* pRadPr,bool& bDeg); + void ConversionDeg(OOX::Logic::CDeg* pDeg); + void ConversionGroupChr(OOX::Logic::CGroupChr* pGroup,const bool& bElement = false); + StValuePr ConversionGroupChrPr(OOX::Logic::CGroupChrPr* pGroupPr); + void WritingbBracketsFromTopBottom(const std::wstring& wsNode,const std::wstring& wsChr,const std::wstring& wsAnnotation,OOX::Logic::CElement* pElement); + void ConversionBar(OOX::Logic::CBar* pBar); + StValuePr ConversionBarPr(OOX::Logic::CBarPr* pBarPr, StStyleMenClose &stStyle); + void ConversionSPre(OOX::Logic::CSPre* pSPre); + static void EmptyBlock(XmlUtils::CXmlWriter* pXmlWrite, std::wstring& wsAnnotation); + void ConversionLimLow(OOX::Logic::CLimLow* pLimLow); + void ConversionLimUpp(OOX::Logic::CLimUpp* pLimUpp); + void ConversionLim(OOX::Logic::CLim* pLim); + void ConversionEqArr(OOX::Logic::CEqArr* pEqArr); + void ConversionSubSup(OOX::Logic::CSSubSup* pSubSup); + StValuePr *ConversionRunProperties(OOX::Logic::CRunProperty* pRPr); + void ConversionMRunProperties(OOX::Logic::CMRPr* pMRpr, StValuePr*&pValue); + void ConversionARpr(PPTX::Logic::RunProperties* pARpr, StValuePr*&pValue); + StValuePr ConversionMdPr(OOX::Logic::CDelimiterPr* pDelPr, StStyleMenClose &stStyle); + StValuePr ConversionNaryPr(OOX::Logic::CNaryPr* pNaryPr, StStyleMenClose &stStyle); + std::wstring ConversionBegBracket(OOX::Logic::CBegChr* pBegChr); + std::wstring ConversionEndBracket(OOX::Logic::CEndChr* pEndChr); + std::wstring TranslationDiacritSign(const std::wstring &wsSymbol); + static std::wstring ParsingText(std::wstring::iterator &itStart, std::wstring::iterator &itEnd); + std::wstring ConversionChr(OOX::Logic::CChr* pChr); + std::wstring ToStringChr(const std::wstring& wsChr); + std::wstring GroupChrForAnnotation(const std::wstring& wsChr); + static void RecordingMoNode(const std::wstring& wsSymbol,XmlUtils::CXmlWriter* pXmlWrite); + static bool IsDigit(const std::wstring& wsDigit); + static bool IsAlpha(const std::wstring& wsAlpha); + static void StyleClosing(const StStyleMenClose &stStyle, XmlUtils::CXmlWriter* pXmlWrite); + static void MTextRecording(XmlUtils::CXmlWriter* pXmlWrite, std::wstring& wsAnnotation,const std::wstring& wsText); + std::wstring TransformationUTF32(const std::wstring& wsText); + bool ComparingAttributes(StValuePr* pRight, StValuePr* pLeft); + void AttributeCheck(StValuePr*& pParent, StValuePr*& pChild); + StarMath::TypeFont FontCheck(const std::wstring& wsFont, bool& bAttribute); + static bool ColorCheck(const std::wstring& wsColor,std::wstring& wsRecordColor); + void EndOdf(); + std::wstring GetOdf(); + std::wstring GetAnnotation(); + std::wstring GetSemantic(); + private: + XmlUtils::CXmlWriter* m_pXmlWrite; + std::wstring m_wsAnnotationStarMath,m_wsSemantic; + std::stack m_stAttribute; + }; + class COneElement + { + public: + COneElement(); + COneElement(std::wstring& wsOneElement); + virtual ~COneElement(); + virtual void Parse(std::wstring::iterator& itStart,std::wstring::iterator& itEnd,COneElement*& pElement) = 0; + virtual void Conversion(XmlUtils::CXmlWriter* pXmlWrite,std::wstring& wsAnnotation) = 0; + static COneElement* CreateElement(std::wstring& wsOneElement); + void SetType(const TypeElement& enType); + TypeElement GetType(); + void SetAttribute(StValuePr* stAttribute); + StValuePr* GetAttribute(); + static void ConversionAttribute(StValuePr* pAttribute, StStyleMenClose & stStyle , XmlUtils::CXmlWriter* pXmlWrite, std::wstring& wsAnnotation, const bool &bDelimiter = false); + bool CheckStyle(); + unsigned int GetStyle(); + private: + TypeElement m_enType; + StValuePr* m_stAttribute; + unsigned int m_iStyle; + }; + class CNumberOrLetter: public COneElement + { + public: + CNumberOrLetter():m_wsElement(L""),m_enTypeElement(TypeElement::undefine) + { + SetType(TypeElement::String); + } + CNumberOrLetter(const std::wstring& wsElement,const TypeElement& enType); + virtual ~CNumberOrLetter(); + void Conversion(XmlUtils::CXmlWriter* pXmlWrite,std::wstring& wsAnnotation) override; + void Parse(std::wstring::iterator &itStart, std::wstring::iterator &itEnd,COneElement*& pElement) override; + const std::wstring& GetString(); + void AddingStrings(const std::wstring& wsString); + private: + std::wstring m_wsElement; + TypeElement m_enTypeElement; + }; + class CBinOperator:public COneElement + { + public: + CBinOperator(const std::wstring& wsSymbol,const std::wstring& wsAnnotation):m_pLeftArg(nullptr),m_pRightArg(nullptr),m_wsSymbolBinOp(wsSymbol),m_wsAnnotation(wsAnnotation),m_enTypeBinOp(TypeElement::undefine) + { + SetType(TypeElement::BinOperator); + if(wsSymbol == L"+") + m_enTypeBinOp = TypeElement::plus; + else if(wsSymbol == L"-") + m_enTypeBinOp = TypeElement::minus; + else if(wsSymbol == L"\u00B1") + m_enTypeBinOp = TypeElement::plus_minus; + else if(wsSymbol == L"\u2213") + m_enTypeBinOp = TypeElement::minus_plus; + else if(L"\u00AC" == wsSymbol) + m_enTypeBinOp = TypeElement::neg; + } + virtual ~CBinOperator(); + void Parse(std::wstring::iterator &itStart, std::wstring::iterator &itEnd, COneElement *&pElement) override; + void Conversion(XmlUtils::CXmlWriter* pXmlWrite,std::wstring& wsAnnotation) override; + bool CheckLeftArg(); + void SetLeftArg(COneElement* pElement); + bool CheckRightArg(); + void SetRightArg(COneElement* pElement); + TypeElement GetTypeBinOp(); + static bool SetLeftArg(COneElement* pBinOp,COneElement* pLeftArg); + static bool SetRightArg(COneElement* pBinOp,COneElement* pRightArg); + static bool CheckRightArg(COneElement* pElement); + static std::wstring BinOperatorSymbolForAnnotation(const std::wstring& wsSymbol); + static bool UnaryCheck(const StValuePr* pValue,const TypeElement& enType); + private: + COneElement* m_pLeftArg; + COneElement* m_pRightArg; + std::wstring m_wsSymbolBinOp; + std::wstring m_wsAnnotation; + TypeElement m_enTypeBinOp; + }; + class CRelationsAndOperationsOnSets: public COneElement + { + public: + CRelationsAndOperationsOnSets(const std::wstring& wsSymbol,const std::wstring& wsAnnotation):m_pLeftArg(nullptr),m_pRightArg(nullptr),m_wsSymbol(wsSymbol),m_wsAnnotationSymbol(wsAnnotation) + { + SetType(TypeElement::Connection); + } + virtual ~CRelationsAndOperationsOnSets(); + void Parse(std::wstring::iterator &itStart, std::wstring::iterator &itEnd,COneElement*& pElement) override; + void Conversion(XmlUtils::CXmlWriter* pXmlWrite,std::wstring& wsAnnotation) override; + void SetLeftArg(COneElement* pElement); + void SetRightArg(COneElement* pElement); + bool CheckRightArg(); + bool CheckLeftArg(); + static std::wstring TransformationForAnnotation(std::wstring& wsSymbol); + private: + COneElement* m_pLeftArg; + COneElement* m_pRightArg; + std::wstring m_wsSymbol; + std::wstring m_wsAnnotationSymbol; + }; + class CSpace:public COneElement + { + public: + CSpace() + { + SetType(TypeElement::Empty); + } + virtual ~CSpace(); + void Parse(std::wstring::iterator&itStart,std::wstring::iterator&itEnd,COneElement*& pElement) override; + void Conversion(XmlUtils::CXmlWriter* pXmlWrite,std::wstring& wsAnnotation) override; + }; + class CSpecialChar: public COneElement + { + public: + CSpecialChar(const std::wstring& wsSymbol,const std::wstring& wsAnnotation):m_wsSymbol(wsSymbol),m_wsAnnotation(wsAnnotation) + { + SetType(TypeElement::SpecialSymbol); + if(m_wsSymbol == L"\u0026") + m_wsSymbol = L"\u0026amp;"; + } + virtual ~CSpecialChar(); + void Parse(std::wstring::iterator&itStart,std::wstring::iterator&itEnd,COneElement*& pElement) override; + void Conversion(XmlUtils::CXmlWriter* pXmlWrite,std::wstring& wsAnnotation) override; + static std::wstring DefinitionSpecialChar(const std::wstring& wsSymbol); + private: + std::wstring m_wsSymbol,m_wsAnnotation; + }; +} +#endif // COOXML2ODF_H diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp new file mode 100644 index 00000000000..12e623341a2 --- /dev/null +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp @@ -0,0 +1,4061 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ + +#include "cstarmathpars.h" +#include "cconversionsmtoooxml.h" + +namespace StarMath +{ +//class methods CParsStarMath + CParserStarMathString::CParserStarMathString():m_iAlignment(1){} + CParserStarMathString::~CParserStarMathString() + { + for(CElement* pElement:m_arEquation) + delete pElement; + } + std::vector CParserStarMathString::Parse(std::wstring& wsParseString, int iTypeConversion) + { + TypeConversion enTypeConvers = (TypeConversion)iTypeConversion; + std::wstring::iterator itStart = wsParseString.begin(),itEnd = wsParseString.end(); + CStarMathReader* pReader = new CStarMathReader(itStart,itEnd,enTypeConvers); + pReader->SetBaseAttribute(m_stBaseAttribute); + while(pReader->CheckIteratorPosition()) + { + ParsElementAddingToArray(pReader,m_arEquation); + } + if(!pReader->EmptyString()) + { + if(pReader->GetLocalType() == TypeElement::newline) + { m_arEquation.push_back(new CElementSpecialSymbol(pReader->GetLocalType(),pReader->GetTypeConversion())); + pReader->ClearReader(); + } + CElement* pTempElement = ParseElement(pReader); + if(nullptr != pTempElement) + m_arEquation.push_back(pTempElement); + } + TFormulaSize tSize; + for(CElement* pElement:m_arEquation) + { + if(pElement->GetBaseType() == TypeElement::SpecialSymbol) + { + CElementSpecialSymbol* pSpecial = dynamic_cast(pElement); + if(pSpecial->GetType() == TypeElement::newline) + { + m_qSize.push(tSize); + tSize.Zeroing(); + } + else + ComparisonByHeight(tSize,pElement->GetSize()); + } + else + ComparisonByHeight(tSize,pElement->GetSize()); + } + if(tSize.m_iHeight != 0 && tSize.m_iWidth != 0) + m_qSize.push(tSize); + return m_arEquation; + } + + CElement* CParserStarMathString::ParseElement(CStarMathReader* pReader) + { + CElement* pElement; + pReader->ReadingTheNextToken(); + pElement = CElement::CreateElement(pReader); + if(pElement != nullptr) + { + + if(pReader->GetAttribute() != nullptr && !CheckForLeftArgument(pReader->GetGlobalType())) + pElement->SetBaseAttribute(pReader->GetAttribute()); + else if(pReader->GetAttribute() != nullptr && (pReader->GetLocalType() == TypeElement::plus || TypeElement::minus == pReader->GetLocalType() || TypeElement::frac == pReader->GetLocalType() || TypeElement::neg == pReader->GetLocalType())) + pElement->SetBaseAttribute(pReader->GetAttribute()); + pReader->ClearReader(); + pElement->Parse(pReader); + if(pReader->GetBaseAttribute()!=nullptr) + pElement->SetBaseAttribute(pReader->GetBaseAttribute()); + if(pElement->GetAttribute() != nullptr && TypeElement::Function != pElement->GetBaseType()) + pElement->SetAttribute(pElement->GetAttribute()); + return pElement; + } + else + { + pReader->ClearReader(); + return pElement; + } + } + template + bool SetLeft(CElement *pLeftArg, CElement *pElementWhichAdd) + { + T* pTempElement = dynamic_cast(pElementWhichAdd); + if(pTempElement->GetLeftArg() == nullptr) + { + if(CParserStarMathString::CheckNewline(pLeftArg) || CParserStarMathString::CheckGrid(pLeftArg)) + return false; + pTempElement->SetLeftArg(pLeftArg); + pElementWhichAdd = pTempElement; + if(pElementWhichAdd->GetBaseType() == TypeElement::Index) + pElementWhichAdd->SetAttribute(nullptr); + return true; + } + else return false; + } + + bool CParserStarMathString::AddLeftArgument(CElement *pLeftArg, CElement *pElementWhichAdd, CStarMathReader *pReader) + { + if(pElementWhichAdd!=nullptr) + { + switch(pElementWhichAdd->GetBaseType()) + { + case TypeElement::BinOperator: + { + CElementBinOperator* pBinOp = dynamic_cast(pElementWhichAdd); + if(pBinOp->GetType() == TypeElement::neg || (pBinOp->GetAttribute() != nullptr && pBinOp->GetAttribute() != pReader->GetBaseAttribute() && pBinOp->MixedOperators(pBinOp->GetType()))) + return false; + else + return SetLeft(pLeftArg, pElementWhichAdd); + } + case TypeElement::SetOperations: + { + return SetLeft(pLeftArg, pElementWhichAdd); + } + case TypeElement::Connection: + { + return SetLeft(pLeftArg,pElementWhichAdd); + } + case TypeElement::BracketWithIndex: + { + return SetLeft(pLeftArg,pElementWhichAdd); + } + case TypeElement::Index: + { + CElementIndex * pIndex = dynamic_cast(pElementWhichAdd); + if(pIndex->GetType() != TypeElement::sqrt && pIndex->GetType() != TypeElement::nroot) + return SetLeft(pLeftArg,pElementWhichAdd); + else return false; + } + default: + break; + } + } + else + return false; + } + CElement* CParserStarMathString::ReadingWithoutBracket(CStarMathReader *pReader, const bool& bConnection) + { + CElement* pFirstTempElement = CParserStarMathString::ParseElement(pReader); + pReader->ReadingTheNextToken(); + while(CheckForLeftArgument(pReader->GetGlobalType(),bConnection) && (pReader->GetLocalType() != TypeElement::neg && pReader->GetLocalType() != TypeElement::frac && pReader->GetLocalType()!=TypeElement::nroot && pReader->GetLocalType()!=TypeElement::sqrt)) + { + CParserStarMathString::ReadingElementsWithPriorities(pReader,pFirstTempElement); + } + return pFirstTempElement; + } + bool CParserStarMathString::CheckForLeftArgument(const TypeElement &enType,const bool& bConnection) + { + switch(enType) + { + case TypeElement::BinOperator: + case TypeElement::SetOperations: + case TypeElement::BracketWithIndex: + case TypeElement::Index: + return true; + case TypeElement::Connection: + return bConnection; + default: + return false; + } + } + bool CParserStarMathString::CheckNewline(CElement* pElement) + { + if(pElement == nullptr) + return false; + if(pElement->GetBaseType() == TypeElement::SpecialSymbol) + { + CElementSpecialSymbol* pSpecial = dynamic_cast(pElement); + return (pSpecial->GetType() == TypeElement::newline); + } + else + return false; + } + bool CParserStarMathString::CheckGrid(CElement *pElement) + { + if(pElement == nullptr) + return false; + if(pElement->GetBaseType() == TypeElement::SpecialSymbol) + { + CElementSpecialSymbol* pSpecial = dynamic_cast(pElement); + if(pSpecial->GetType() == TypeElement::grid || pSpecial->GetType() == TypeElement::transition) + return true; + else return false; + } + else return false; + } + void CParserStarMathString::AddingAnElementToAnArray(std::vector &arrEquation, CElement *pAddElement, CStarMathReader *pReader) + { + if(pAddElement !=nullptr) + { + if(!arrEquation.empty() && CheckForLeftArgument(pAddElement->GetBaseType())) + { + if(AddLeftArgument(arrEquation.back(),pAddElement,pReader)) + arrEquation.pop_back(); + } + arrEquation.push_back(pAddElement); + } + } + void CParserStarMathString::ReadingElementsWithPriorities(CStarMathReader *pReader, CElement *&pLeftElement) + { + CElement* pNextElement = ParseElement(pReader); + if(pLeftElement != nullptr) + AddLeftArgument(pLeftElement,pNextElement,pReader); + pLeftElement = pNextElement; + pReader->ReadingTheNextToken(); + } + void CParserStarMathString::ReadingElementsWithAttributes(CStarMathReader *pReader, CElement*& pSavingElement) + { + CElement* pElement = CParserStarMathString::ParseElement(pReader); + if(pElement->GetAttribute() != pReader->GetBaseAttribute()) + { + pReader->ReadingTheNextToken(); + if(CElementIndex::GetLowerIndex(pReader->GetLocalType()) || CElementIndex::GetUpperIndex(pReader->GetLocalType())) + { + CElement* pIndex = new CElementIndex(pReader->GetLocalType(),pReader->GetTypeConversion()); + pReader->ClearReader(); + pIndex->Parse(pReader); + AddLeftArgument(pElement,pIndex,pReader); + pSavingElement = pIndex; + } + else + pSavingElement = pElement; + } + else + pSavingElement = pElement; + } + void CParserStarMathString::SetAlignment(const unsigned int &iAlignment) + { + m_iAlignment = iAlignment; + } + const unsigned int& CParserStarMathString::GetAlignment() + { + return m_stBaseAttribute.base_alignment; + } + void CParserStarMathString::SetBaseFont(const std::wstring &wsNameFont) + { + m_stBaseAttribute.base_font_name = wsNameFont; + } + void CParserStarMathString::SetBaseSize(const unsigned int &iSize) + { + if(iSize < 130) + m_stBaseAttribute.base_font_size = iSize*2; + } + void CParserStarMathString::SetBaseAlignment(const unsigned int &iAlignment) + { + if(iAlignment >= 0 && iAlignment < 3) + m_stBaseAttribute.base_alignment = iAlignment; + } + void CParserStarMathString::SetBaseBold(const bool &bBold) + { + m_stBaseAttribute.base_font_bold = bBold; + } + void CParserStarMathString::SetBaseItalic(const bool &bItal) + { + m_stBaseAttribute.base_font_italic = bItal; + } + std::wstring CParserStarMathString::ConvertToLowerCase(const std::wstring& wsToken) + { + if(!wsToken.empty() && wsToken[0] == L'%') + return wsToken; + std::wstring wsLowerCase; + for(wchar_t cOneElement:wsToken) + wsLowerCase+= std::tolower(cOneElement); + if(wsLowerCase.empty()) + return wsToken; + else + return wsLowerCase; + } + void CParserStarMathString::ParsElementAddingToArray(CStarMathReader *pReader, std::vector &arElements) + { + if(!arElements.empty()) + CElementBinOperator::UnaryCheck(pReader,arElements.back()); + CElement* pTempElement = ParseElement(pReader); + AddingAnElementToAnArray(arElements,pTempElement,pReader); + } + std::queue CParserStarMathString::GetFormulaSize() + { + return m_qSize; + } + void CParserStarMathString::ComparisonByHeight(TFormulaSize &tLeftSize, const TFormulaSize &tRightSize) + { + if(tLeftSize.m_iHeight < tRightSize.m_iHeight) + tLeftSize.m_iHeight = tRightSize.m_iHeight; + if(tRightSize.m_iWidth != 0) + tLeftSize.m_iWidth += tRightSize.m_iWidth; + } + void CParserStarMathString::ComparisonByWidth(TFormulaSize &tLeftSize, const TFormulaSize &tRightSize) + { + if(tRightSize.m_iHeight != 0) + tLeftSize.m_iHeight += tRightSize.m_iHeight; + if(tLeftSize.m_iWidth < tRightSize.m_iWidth) + tLeftSize.m_iWidth = tRightSize.m_iWidth; + } +//class methods CAttribute + CAttribute::CAttribute(): m_bBold(false),m_bItal(false),m_bPhantom(false),m_bStrike(false),m_bParent(false),m_iSize(0),m_iAlignment(0),m_unCount(0) + { + } + CAttribute::~CAttribute() + {} + void CAttribute::SetSize(const unsigned int &iSize) + { + m_iSize = iSize; + } + void CAttribute::SetAlignment(const unsigned int &iAlignment) + { + m_iAlignment = iAlignment; + } + void CAttribute::SetBold() + { + m_bBold = true; + } + void CAttribute::SetItal() + { + m_bItal = true; + } + void CAttribute::SetPhantom() + { + m_bPhantom = true; + } + void CAttribute::SetStrike() + { + m_bStrike = true; + } + bool CAttribute::SetColor(const TypeElement &enColor) + { + if(enColor != TypeElement::undefine) + { + switch (enColor) { + case TypeElement::black: + m_wsColor = L"000000"; + return true; + case TypeElement::blue: + m_wsColor = L"0000ff"; + return true; + case TypeElement::green: + m_wsColor =L"00FF00"; + return true; + case TypeElement::red: + m_wsColor =L"FF0000"; + return true; + case TypeElement::fuchsia: + m_wsColor =L"ED0DD9"; + return true; + case TypeElement::aqua: + m_wsColor =L"30D5C8"; + return true; + case TypeElement::yellow: + m_wsColor =L"FFFF00"; + return true; + case TypeElement::gray: + m_wsColor =L"808080"; + return true; + case TypeElement::lime: + m_wsColor =L"00FF00"; + return true; + case TypeElement::maroon: + m_wsColor =L"800000"; + return true; + case TypeElement::navy: + m_wsColor =L"000080"; + return true; + case TypeElement::olive: + m_wsColor =L"808000"; + return true; + case TypeElement::purple: + m_wsColor =L"800080"; + return true; + case TypeElement::silver: + m_wsColor =L"C0C0C0"; + return true; + case TypeElement::teal: + m_wsColor =L"008080"; + return true; + case TypeElement::coral: + m_wsColor =L"FF7F50"; + return true; + case TypeElement::midnightblue: + m_wsColor =L"191970"; + return true; + case TypeElement::crimson: + m_wsColor =L"DC143C"; + return true; + case TypeElement::violet: + m_wsColor =L"EE82EE"; + return true; + case TypeElement::orange: + m_wsColor =L"FFA500"; + return true; + case TypeElement::orangered: + m_wsColor =L"FF4500"; + return true; + case TypeElement::seagreen: + m_wsColor =L"2E8B57"; + return true; + case TypeElement::indigo: + m_wsColor =L"4B0082"; + return true; + case TypeElement::hotpink: + m_wsColor =L"FF69B4"; + return true; + case TypeElement::lavender: + m_wsColor =L"FFF0F5"; + return true; + default: + return false; + } + } + else return false; + } + void CAttribute::SetColor(const std::wstring &wsColor) + { + m_wsColor = wsColor; + } + bool CAttribute::SetFont(const TypeElement &enFont) + { + switch (enFont) { + case TypeElement::ital: + m_bItal = true; + return true; + case TypeElement::bold: + m_bBold = true; + return true; + case TypeElement::phantom: + m_bPhantom = true; + return true; + case TypeElement::overstrike: + m_bStrike = true; + return true; + default: + return false; + } + } + void CAttribute::SetFontName(const std::wstring &wsNameFont) + { + m_wsNameFont = wsNameFont; + } + bool CAttribute::GetBold() + { + return m_bBold; + } + bool CAttribute::GetItal() + { + return m_bItal; + } + bool CAttribute::GetPhantom() + { + return m_bPhantom; + } + bool CAttribute::GetStrike() + { + return m_bStrike; + } + std::wstring CAttribute::GetColor() + { + return m_wsColor; + } + const std::wstring& CAttribute::GetFontName() + { + return m_wsNameFont; + } + unsigned int CAttribute::GetSize() + { + return m_iSize; + } + unsigned int CAttribute::GetAlignment() + { + return m_iAlignment; + } + bool CAttribute::EmptyColor() + { + return m_wsColor.empty(); + } + void CAttribute::SetParent() + { + m_bParent = true; + } + bool CAttribute::GetParent() + { + return m_bParent; + } + //hex current + bool CAttribute::ParseColorAttribute(const std::wstring &wsToken,CStarMathReader* pReader) + { + TypeElement enTempColor = GetTypeColorAttribute(wsToken); + switch(enTempColor) + { + case TypeElement::hex: + { + pReader->SetString(L""); + std::wstring wsTempToken; + wsTempToken = pReader->TakingElementForHex(); + if(wsTempToken.empty()) + return false; + if(!m_wsColor.empty()) + m_wsColor.clear(); + if(wsTempToken.size()< 6) + { + int iZero = 6 - wsTempToken.size(); + for(int i = 0;i 6) + { + m_wsColor += wsTempToken.substr(wsTempToken.size()-6); + return true; + } + } + case TypeElement::rgb: + { + pReader->SetString(L""); + const int iTempLen = 7; + wchar_t arTemp[iTempLen]; + int iRed(-1),iGreen(-1),iBlue(-1); + iRed = pReader->TakingElementForRGB(); + if(iRed == -1) + return false; + iGreen = pReader->TakingElementForRGB(); + if(iGreen == -1) + { + RefundOfTheAmountRGB(pReader,iRed,iGreen,iBlue); + return false; + } + iBlue = pReader->TakingElementForRGB(); + if(iBlue == -1) + { + RefundOfTheAmountRGB(pReader,iRed,iGreen,iBlue); + return false; + } + if(iRed > 255 || iGreen > 255 || iBlue > 255) + m_wsColor = L"000000"; + else + { + swprintf(arTemp,iTempLen,L"%02X%02X%02X",iRed,iGreen,iBlue); + m_wsColor = std::wstring(arTemp,6); + } + return true; + } + default: + return(SetColor(enTempColor)); + } + } + bool CAttribute::ParseFontAttribute(const TypeElement& enTypeFont, CStarMathReader *pReader) + { + switch(enTypeFont) + { + case TypeElement::size: + { + std::wstring wsSize = pReader->GetElement(); + pReader->TokenProcessing(wsSize); + int iTemp; + if(CElementString::GetDigit(wsSize) != TypeElement::undefine) + iTemp = std::stoi(wsSize); + else + { + return false; + } + if (iTemp > 0 && iTemp < 127) + m_iSize = iTemp*2; + else + m_iSize = 24; + return true; + } + case TypeElement::font: + { + pReader->TokenProcessing(); + if(pReader->GetLowerCaseString() == L"sans") + m_wsNameFont = L"Liberation Sans"; + else if(pReader->GetLowerCaseString() == L"serif") + m_wsNameFont = L"Liberation Serif"; + else if(pReader->GetLowerCaseString() == L"fixed") + m_wsNameFont = L"Liberation Mono"; + else + return false; + return true; + } + case TypeElement::alignl: + case TypeElement::alignr: + case TypeElement::alignc: + return true; + default: + return SetFont(enTypeFont); + } + } + +//нет phantom, rgb, 16 , гарнитуры и кегля + TypeElement CAttribute::GetTypeColorAttribute(const std::wstring &wsToken) + { + if(L"hex"==wsToken) return TypeElement::hex; + else if(L"rgb" == wsToken) return TypeElement::rgb; + else if(L"black" == wsToken) return TypeElement::black; + else if(L"green" == wsToken) return TypeElement::green; + else if(L"aqua" == wsToken) return TypeElement::aqua; + else if(L"yellow" == wsToken) return TypeElement::yellow; + else if(L"lime" == wsToken) return TypeElement::lime; + else if(L"navy" == wsToken) return TypeElement::navy; + else if(L"purple" == wsToken) return TypeElement::purple; + else if(L"teal" == wsToken) return TypeElement::teal; + else if(L"blue" == wsToken) return TypeElement::blue; + else if(L"red" == wsToken) return TypeElement::red; + else if(L"fuchsia" == wsToken) return TypeElement::fuchsia; + else if(L"gray" == wsToken) return TypeElement::gray; + else if(L"maroon" == wsToken) return TypeElement::maroon; + else if(L"olive" == wsToken) return TypeElement::olive; + else if(L"silver" == wsToken) return TypeElement::silver; + else if(L"coral" == wsToken) return TypeElement::coral; + else if(L"midnightblue" == wsToken) return TypeElement::midnightblue; + else if(L"crimson" == wsToken) return TypeElement::crimson; + else if(L"violet" == wsToken) return TypeElement::violet; + else if(L"orange" == wsToken) return TypeElement::orange; + else if(L"seagreen" == wsToken) return TypeElement::seagreen; + else if(L"hotpink" == wsToken) return TypeElement::hotpink; + else if(L"orangered" == wsToken) return TypeElement::orangered; + else if(L"indigo" == wsToken) return TypeElement::indigo; + else if(L"lavender" == wsToken) return TypeElement::lavender; + else return TypeElement::undefine; + } + TypeElement CAttribute::GetTypeFontAttribute(const std::wstring &wsToken) + { + if(L"bold" == wsToken) return TypeElement::bold; + else if(L"size" == wsToken) return TypeElement::size; + else if(L"font" == wsToken) return TypeElement::font; + else if(L"ital" == wsToken) return TypeElement::ital; + else if(L"phantom" == wsToken ) return TypeElement::phantom; + else if(L"overstrike" == wsToken) return TypeElement::overstrike; + else if(L"alignl" == wsToken) return TypeElement::alignl; + else if(L"alignr" == wsToken) return TypeElement::alignr; + else if(L"alignc" == wsToken) return TypeElement::alignc; + else return TypeElement::undefine; + } + bool CAttribute::CheckHexPosition(const wchar_t &cToken) + { + if(isdigit(cToken)) + return true; + if( L'A' == cToken) return true; + else if(L'B' == cToken) return true; + else if(L'C' == cToken) return true; + else if(L'D' == cToken) return true; + else if(L'E' == cToken) return true; + else if(L'F' == cToken) return true; + else + return false; + } + bool CAttribute::CheckAttribute() + { + if(m_bBold == true || m_bItal == true || m_bStrike == true || m_bPhantom == true) + return true; + else if(!m_wsColor.empty() || !m_wsNameFont.empty()) + return true; + else if(m_iSize != 0 || (m_iAlignment == 1 || m_iAlignment == 2)) + return true; + return false; + } + void CAttribute::RefundOfTheAmountRGB(CStarMathReader *pReader, const int &iRed, const int &iGreen, const int &iBlue) + { + std::wstring wsSum; + if(iRed != -1) + wsSum += std::to_wstring(iRed); + if(iGreen != -1) + wsSum += std::to_wstring(iGreen); + if(iBlue != -1) + wsSum += std::to_wstring(iBlue); + pReader->TokenProcessing(wsSum); + } + bool CAttribute::CheckingForEmptiness() + { + if(!m_wsNameFont.empty()) + return true; + if(!m_wsColor.empty()) + return true; + if(m_bBold) + return true; + if(m_bItal) + return true; + if(m_iAlignment > 0 && m_iAlignment<=2) + return true; + if(m_iSize > 0) + return true; + return false; + } + void CAttribute::AddRef() + { + m_unCount++; + } + void CAttribute::Release() + { + m_unCount--; + if(m_unCount == 0) + delete this; + } + unsigned int CAttribute::GetCount() + { + return m_unCount; + } + void CAttribute::ComparingAttributes(CAttribute *pAttributeParent, CAttribute *pAttributeChild) + { + if(!pAttributeChild->GetBold() && pAttributeParent->GetBold()) + pAttributeChild->SetBold(); + if(!pAttributeChild->GetItal() && pAttributeParent->GetItal()) + pAttributeChild->SetItal(); + if(!pAttributeChild->GetPhantom() && pAttributeParent->GetPhantom()) + pAttributeChild->SetPhantom(); + if(!pAttributeChild->GetStrike() && pAttributeParent->GetStrike()) + pAttributeChild->SetStrike(); + if(pAttributeChild->EmptyColor() && !pAttributeParent->EmptyColor()) + pAttributeChild->SetColor(pAttributeParent->GetColor()); + if(pAttributeChild->GetSize() == 0 && pAttributeParent->GetSize() != 0) + pAttributeChild->SetSize(pAttributeParent->GetSize()); + } +//class methods CElement + CElement::~CElement() + { + if(m_pAttribute != nullptr) + m_pAttribute->Release(); + } + CElement::CElement(): m_pAttribute(nullptr) + {} + CElement::CElement(const TypeElement &enTypeBase,const TypeConversion &enTypeConversion): m_pAttribute(nullptr),m_enBaseType(enTypeBase),m_enTypeConversion(enTypeConversion) + { + } + CElement* CElement::CreateElement(CStarMathReader* pReader) + { + switch (pReader->GetGlobalType()) { + case TypeElement::String: + return new CElementString(pReader->GetOriginalString(),pReader->GetTypeConversion()); + case TypeElement::BinOperator: + return new CElementBinOperator(pReader->GetLocalType(),pReader->GetTypeConversion()); + case TypeElement::SetOperations: + return new CElementSetOperations(pReader->GetLocalType(),pReader->GetTypeConversion()); + case TypeElement::Connection: + return new CElementConnection(pReader->GetLocalType(),pReader->GetTypeConversion()); + case TypeElement::Function: + { + if(pReader->GetLocalType() == TypeElement::func) + { + if (pReader->GetToken()) + return new CElementFunction(pReader->GetLocalType(),pReader->GetTypeConversion(),pReader->GetLowerCaseString()); + else + return nullptr; + } + else + return new CElementFunction(pReader->GetLocalType(),pReader->GetTypeConversion()); + } + case TypeElement::Bracket: + { + if(pReader->GetLocalType() == TypeElement::left) + return new CElementBracket(pReader->GetLocalType(),pReader->GetTypeConversion(),true); + else + return new CElementBracket(pReader->GetLocalType(),pReader->GetTypeConversion()); + } + case TypeElement::Operation: + { + if(pReader->GetLocalType() == TypeElement::oper) + { + if (pReader->GetToken()) + { + return new CElementOperator(pReader->GetLocalType(),pReader->GetTypeConversion(),pReader->GetLowerCaseString()); + } + else + return nullptr; + } + else + return new CElementOperator(pReader->GetLocalType(),pReader->GetTypeConversion()); + } + case TypeElement::BracketWithIndex: + return new CElementBracketWithIndex(pReader->GetLocalType(),pReader->GetTypeConversion()); + case TypeElement::Grade: + return new CElementGrade(pReader->GetTypeConversion()); + case TypeElement::Matrix: + return new CElementMatrix(pReader->GetLocalType(),pReader->GetTypeConversion()); + case TypeElement::SpecialSymbol: + return new CElementSpecialSymbol(pReader->GetLocalType(),pReader->GetTypeConversion()); + case TypeElement::Index: + return new CElementIndex(pReader->GetLocalType(),pReader->GetTypeConversion()); + case TypeElement::Mark: + return new CElementDiacriticalMark(pReader->GetLocalType(),pReader->GetTypeConversion()); + default: + return nullptr; + } + } + const TypeElement& CElement::GetBaseType() + { + return m_enBaseType; + } + void CElement::SetBaseType(const TypeElement &enType) + { + m_enBaseType = enType; + } + void CElement::SetBaseAttribute(CAttribute *pAttribute) + { + if(m_pAttribute == nullptr && pAttribute != nullptr) + { + m_pAttribute = pAttribute; + m_pAttribute->AddRef(); + } + else if(pAttribute != nullptr && m_pAttribute!=nullptr && pAttribute != m_pAttribute) + { + if(m_pAttribute->GetCount() <= 1 && !m_pAttribute->GetParent()) + CAttribute::ComparingAttributes(pAttribute,m_pAttribute); + else if(m_pAttribute->GetCount() > 1 || m_pAttribute->GetParent()) + { + CAttribute* pTempAttribute = m_pAttribute; + m_pAttribute = new CAttribute; + m_pAttribute->AddRef(); + CAttribute::ComparingAttributes(pTempAttribute,m_pAttribute); + CAttribute::ComparingAttributes(pAttribute,m_pAttribute); + } + } + } + CAttribute* CElement::GetAttribute() + { + return m_pAttribute; + } + const TypeConversion& CElement::GetTypeConversion() + { + return m_enTypeConversion; + } + void CElement::DeleteAttribute() + { + m_pAttribute->Release(); + m_pAttribute = nullptr; + } +//class methods CElementString + CElementString::CElementString(const std::wstring& wsTokenString,const TypeConversion &enTypeConversion) + :CElement(TypeElement::String,enTypeConversion),m_wsString(wsTokenString) + { + } + CElementString::~CElementString() + {} + void CElementString::SetString(const std::wstring& wsTokenString) + { + m_wsString = wsTokenString; + } + void CElementString::Parse(CStarMathReader* pReader) + { + if(m_wsString == L"\"") + { + m_wsString.clear(); + wchar_t wsOneToken = pReader->GetOneElement(); + while(wsOneToken !=L'"') + { + m_wsString+=wsOneToken; + if(pReader->CheckIteratorPosition()) + wsOneToken = pReader->GetOneElement(); + else + break; + } + } + pReader->ClearReader(); + } + void CElementString::ConversionToOOXML(XmlUtils::CXmlWriter* pXmlWrite) + { + if(m_wsString !=L"" && m_wsString!=L" ") + { + pXmlWrite->WriteNodeBegin(L"m:r",false); + CConversionSMtoOOXML::StandartProperties(pXmlWrite,GetAttribute(),GetTypeConversion()); + pXmlWrite->WriteNodeBegin(L"m:t",false); + pXmlWrite->WriteString(XmlUtils::EncodeXmlString(m_wsString)); + pXmlWrite->WriteNodeEnd(L"m:t",false,false); + pXmlWrite->WriteNodeEnd(L"m:r",false,false); + } + } + std::wstring CElementString::GetString() + { + return m_wsString; + } + TypeElement CElementString::GetDigit(const std::wstring &wsToken) + { + if(wsToken.empty()) return TypeElement::undefine; + + for(wchar_t cOneElement: wsToken) + { + if(!iswdigit(cOneElement) || L'\0' == cOneElement) return TypeElement::undefine; + } + return TypeElement::String; + } + TypeElement CElementString::GetWord(const std::wstring &wsToken) + { + if(wsToken.empty()) return TypeElement::undefine; + + for(wchar_t cOneElement: wsToken) + { + if(!iswalpha(cOneElement)) return TypeElement::undefine; + } + return TypeElement::String; + } + void CElementString::SetAttribute(CAttribute *pAttribute) + { + SetBaseAttribute(pAttribute); + } + TFormulaSize CElementString::GetSize() + { + TFormulaSize tSize; + if(!m_wsString.empty()) + { + tSize.m_iHeight = 1; + tSize.m_iWidth = m_wsString.size(); + } + return tSize; + } +//class methods CElementBinOperator + CElementBinOperator::CElementBinOperator(const TypeElement& enType,const TypeConversion &enTypeConversion) + :CElement(TypeElement::BinOperator,enTypeConversion),m_pLeftArgument(nullptr) , m_pRightArgument(nullptr),m_enTypeBinOp(enType) + { + } + CElementBinOperator::~CElementBinOperator() + { + delete m_pLeftArgument; + delete m_pRightArgument; + } + void CElementBinOperator::SetLeftArg(CElement *pElement) + { + m_pLeftArgument = pElement; + } + void CElementBinOperator::SetRightArg(CElement *pElement) + { + m_pRightArgument = pElement; + } + void CElementBinOperator::Parse(CStarMathReader* pReader) + { + if(m_enTypeBinOp == TypeElement::frac) + { + m_pLeftArgument = CParserStarMathString::ReadingWithoutBracket(pReader,false); + m_pRightArgument = CParserStarMathString::ReadingWithoutBracket(pReader,false); + if(GetAttribute() != nullptr) + SetAttribute(GetAttribute()); + } + else if(m_enTypeBinOp == TypeElement::neg) + { + m_pRightArgument = CParserStarMathString::ParseElement(pReader); + if(GetAttribute()!= nullptr) + SetAttribute(GetAttribute()); + } + else if((pReader->GetMarkForUnar() || GetAttribute()!=nullptr)&& MixedOperators(m_enTypeBinOp)) + { + m_pRightArgument = CParserStarMathString::ParseElement(pReader); + } + else + { + CElement* pTempElement = CParserStarMathString::ParseElement(pReader); + pReader->ReadingTheNextToken(); + while((IsBinOperatorLowPrior() && (pReader->GetGlobalType() == TypeElement::BinOperator || pReader->GetLocalType() == TypeElement::intersection || pReader->GetLocalType() == TypeElement::setminus || pReader->GetLocalType() == TypeElement::setquotient)) || pReader->GetGlobalType() == TypeElement::BracketWithIndex || (pReader->GetGlobalType() == TypeElement::Index && (pReader->GetLocalType() != TypeElement::nroot && pReader->GetLocalType() != TypeElement::sqrt))) + { + CParserStarMathString::ReadingElementsWithPriorities(pReader,pTempElement); + } + m_pRightArgument = pTempElement; + } + } + void CElementBinOperator::ConversionToOOXML(XmlUtils::CXmlWriter* pXmlWrite) + { + if(m_enTypeBinOp == TypeElement::over || m_enTypeBinOp ==TypeElement::division || TypeElement::frac == m_enTypeBinOp || TypeElement::wideslash == m_enTypeBinOp) + { + pXmlWrite->WriteNodeBegin(L"m:f",false); + if(m_enTypeBinOp == TypeElement::division) + CConversionSMtoOOXML::PropertiesMFPR(L"lin",pXmlWrite,GetAttribute(),GetTypeConversion()); + else if(m_enTypeBinOp == TypeElement::wideslash) + CConversionSMtoOOXML::PropertiesMFPR(L"skw",pXmlWrite,GetAttribute(),GetTypeConversion()); + else + CConversionSMtoOOXML::PropertiesMFPR(L"",pXmlWrite,GetAttribute(),GetTypeConversion()); + CConversionSMtoOOXML::WriteNodeConversion(L"m:num",m_pLeftArgument,pXmlWrite); + CConversionSMtoOOXML::WriteNodeConversion(L"m:den",m_pRightArgument,pXmlWrite); + pXmlWrite->WriteNodeEnd(L"m:f",false,false); + } + else + { + CConversionSMtoOOXML::ElementConversion(pXmlWrite,m_pLeftArgument); + pXmlWrite->WriteNodeBegin(L"m:r",false); + CConversionSMtoOOXML::StandartProperties(pXmlWrite,GetAttribute(),GetTypeConversion()); + pXmlWrite->WriteNodeBegin(L"m:t",false); + switch (m_enTypeBinOp) + { + case TypeElement::plus: + pXmlWrite->WriteString(L"+"); + break; + case TypeElement::minus: + pXmlWrite->WriteString(L"-"); + break; + case TypeElement::multipl: + pXmlWrite->WriteString(L"*"); + break; + case TypeElement::cdot: + pXmlWrite->WriteString(L"\u00B7"); + break; + case TypeElement::times: + pXmlWrite->WriteString(L"\u00D7"); + break; + case TypeElement::div: + pXmlWrite->WriteString(L"\u00F7"); + break; + case TypeElement::odivide: + pXmlWrite->WriteString(L"\u2298"); + break; + case TypeElement::oplus: + pXmlWrite->WriteString(L"\u2295"); + break; + case TypeElement::ominus: + pXmlWrite->WriteString(L"\u2296"); + break; + case TypeElement::odot: + pXmlWrite->WriteString(L"\u2299"); + break; + case TypeElement::otimes: + pXmlWrite->WriteString(L"\u2297"); + break; + case TypeElement::plus_minus: + pXmlWrite->WriteString(L"\u00B1"); + break; + case TypeElement::minus_plus: + pXmlWrite->WriteString(L"\u2213"); + break; + case TypeElement::Or: + pXmlWrite->WriteString(L"\u2228"); + break; + case TypeElement::And: + pXmlWrite->WriteString(L"\u2227"); + break; + case TypeElement::neg: + pXmlWrite->WriteString(L"\u00AC"); + break; + case TypeElement::circ: + pXmlWrite->WriteString(L"\u2218"); + break; + case TypeElement::widebslash: + pXmlWrite->WriteString(L"\u2216"); + break; + default: + break; + } + if(m_pRightArgument!=nullptr && m_pRightArgument->GetBaseType() == TypeElement::String && GetAttribute() == m_pRightArgument->GetAttribute()) + { + CElementString* oNumber = dynamic_cast (m_pRightArgument); + pXmlWrite->WriteString(oNumber->GetString()); + pXmlWrite->WriteNodeEnd(L"m:t",false,false); + pXmlWrite->WriteNodeEnd(L"m:r",false,false); + } + else + { + pXmlWrite->WriteNodeEnd(L"m:t",false,false); + pXmlWrite->WriteNodeEnd(L"m:r",false,false); + CConversionSMtoOOXML::ElementConversion(pXmlWrite,m_pRightArgument); + } + + } + } + void CElementBinOperator::SetTypeBinOP(const TypeElement &enType) + { + m_enTypeBinOp = enType; + } + TypeElement CElementBinOperator::GetBinOperator(const std::wstring& wsToken) + { + if(L"cdot" == wsToken) return TypeElement::cdot; + else if(L"+" == wsToken) return TypeElement::plus; + else if(L"-" == wsToken) return TypeElement::minus; + else if(L"oplus" == wsToken) return TypeElement::oplus; + else if(L"ominus" == wsToken) return TypeElement::ominus; + else if(L"circ" == wsToken) return TypeElement::circ; + else if(L"times" == wsToken) return TypeElement::times; + else if(L"over" == wsToken) return TypeElement::over; + else if(L"frac" == wsToken) return TypeElement::frac; + else if(L"div" == wsToken) return TypeElement::div; + else if(L"*" == wsToken) return TypeElement::multipl; + else if(L"/" == wsToken) return TypeElement::division; + else if(L"odot" == wsToken) return TypeElement::odot; + else if(L"otimes" == wsToken) return TypeElement::otimes; + else if(L"odivide" == wsToken) return TypeElement::odivide; + else if(L"wideslash" == wsToken) return TypeElement::wideslash; + else if(L"widebslash" == wsToken) return TypeElement::widebslash; + else if(L"+-" == wsToken) return TypeElement::plus_minus; + else if(L"-+" == wsToken) return TypeElement::minus_plus; + else if(L"neg" == wsToken) return TypeElement::neg; + else if(L"or" == wsToken) return TypeElement::Or; + else if(L"and" == wsToken) return TypeElement::And; + else if(L"&" == wsToken) return TypeElement::And; + else return TypeElement::undefine; + } + bool CElementBinOperator::MixedOperators(const TypeElement &enType) + { + switch (enType) + { + case TypeElement::plus: + return true; + case TypeElement::plus_minus: + return true; + case TypeElement::minus_plus: + return true; + case TypeElement::minus: + return true; + default: + return false; + } + } + void CElementBinOperator::UnaryCheck(CStarMathReader *pReader, CElement *pLastElement) + { + pReader->ReadingTheNextToken(); + if(MixedOperators(pReader->GetLocalType())) + { + if(CParserStarMathString::CheckNewline(pLastElement)) + pReader->SetMarkForUnar(true); + else if(pReader->GetAttribute() != nullptr) + pReader->SetMarkForUnar(true); + else + pReader->SetMarkForUnar(false); + } + else pReader->SetMarkForUnar(false); + } + bool CElementBinOperator::IsBinOperatorLowPrior() + { + switch (m_enTypeBinOp) { + case TypeElement::oplus: + return true; + case TypeElement::ominus: + return true; + case TypeElement::circ: + return true; + case TypeElement::Or: + return true; + default: + return MixedOperators(m_enTypeBinOp); + } + } + void CElementBinOperator::SetAttribute(CAttribute *pAttribute) + { + SetBaseAttribute(pAttribute); + if(m_pLeftArgument !=nullptr) + m_pLeftArgument->SetAttribute(pAttribute); + if(m_pRightArgument!=nullptr) + m_pRightArgument->SetAttribute(pAttribute); + } + CElement* CElementBinOperator::GetLeftArg() + { + return m_pLeftArgument; + } + CElement* CElementBinOperator::GetRightArg() + { + return m_pRightArgument; + } + const TypeElement& CElementBinOperator::GetType() + { + return m_enTypeBinOp; + } + TFormulaSize CElementBinOperator::GetSize() + { + TFormulaSize tSize; + if(m_pLeftArgument != nullptr) + tSize = m_pLeftArgument->GetSize(); + switch(m_enTypeBinOp) + { + case TypeElement::over: + case TypeElement::wideslash: + case TypeElement::frac: + { + if(m_pRightArgument!= nullptr) + CParserStarMathString::ComparisonByWidth(tSize,m_pRightArgument->GetSize()); + tSize.m_iHeight += 1; + return tSize; + } + default: + if(m_pRightArgument != nullptr) + CParserStarMathString::ComparisonByHeight(tSize,m_pRightArgument->GetSize()); + tSize.m_iWidth+= 1; + return tSize; + } + } +//class methods CElementBracket + CElementBracket::CElementBracket(const TypeElement& enType,const TypeConversion &enTypeConversion,const bool& bScalability) + :CElement(TypeElement::Bracket,enTypeConversion),m_enTypeBracket(enType),m_bScalability(bScalability) + { + } + CElementBracket::~CElementBracket() + { + for(CElement* pTemp:m_arBrecketValue) delete pTemp; + } + void CElementBracket::SetBracketValue(const std::vector &arValue) + { + m_arBrecketValue = arValue; + } + TypeElement CElementBracket::GetBracketOpen(const std::wstring &wsToken) + { + if(L"{" == wsToken) return TypeElement::brace; + else if(L"(" == wsToken) return TypeElement::round; + else if(L"[" == wsToken) return TypeElement::square; + else if(L"left" == wsToken) return TypeElement::left; + else if(L"ldbracket" == wsToken) return TypeElement::ldbracket; + else if(L"lbrace" == wsToken) return TypeElement::lbrace; + else if(L"langle" == wsToken) return TypeElement::langle; + else if(L"lceil" == wsToken) return TypeElement::lceil; + else if(L"lfloor" == wsToken) return TypeElement::lfloor; + else if(L"lline" == wsToken) return TypeElement::lline; + else if(L"ldline" == wsToken) return TypeElement::ldline; + else return TypeElement::undefine; + } + TypeElement CElementBracket::GetBracketClose(const std::wstring &wsToken) + { + if(L"}" == wsToken) return TypeElement::rwbrace; + else if(L")" == wsToken) return TypeElement::rround; + else if(L"]" == wsToken) return TypeElement::rsquare; + else if(L"rdbracket" == wsToken) return TypeElement::rdbracket; + else if(L"rbrace" == wsToken) return TypeElement::rbrace; + else if(L"rangle" == wsToken) return TypeElement::rangle; + else if(L"rceil" == wsToken) return TypeElement::rceil; + else if(L"rfloor" == wsToken) return TypeElement::rfloor; + else if(L"rline" == wsToken) return TypeElement::rline; + else if(L"rdline" == wsToken) return TypeElement::rdline; + else if(L"right" == wsToken) return TypeElement::right; + else if(L"none" == wsToken) return TypeElement::none; + else return TypeElement::undefine; + } + std::vector CElementBracket::GetBracketValue() + { + return m_arBrecketValue; + } + void CElementBracket::Parse(CStarMathReader* pReader) + { + TypeElement enOpen,enClose; + if(m_enTypeBracket == TypeElement::left) + { + pReader->ReadingTheNextToken(); + enOpen = GetBracketOpen(pReader->GetLowerCaseString()); + if(pReader->GetLowerCaseString() == L"none") + enOpen = TypeElement::none; + else + enClose = GetBracketClose(pReader->GetLowerCaseString()); + if(enOpen != TypeElement::undefine) + { + m_enLeftBracket = enOpen; + pReader->ClearReader(); + } + else if(enClose != TypeElement::undefine) + { + m_enLeftBracket = enClose; + pReader->ClearReader(); + } + } + pReader->FindingTheEndOfParentheses(); + while(pReader->CheckIteratorPosition()) + { + pReader->ReadingTheNextToken(); + if(pReader->GetLowerCaseString() == L"right") + { + pReader->ClearReader(); + continue; + } + CParserStarMathString::ParsElementAddingToArray(pReader,m_arBrecketValue); + } + if(!pReader->EmptyString() && pReader->GetLowerCaseString() != L"right") + { + if(pReader->GetLocalType() == TypeElement::newline) + { + m_arBrecketValue.push_back(new CElementSpecialSymbol(pReader->GetLocalType(),pReader->GetTypeConversion())); + pReader->ClearReader(); + } + else + { + CElement* pTempElement =CParserStarMathString::ParseElement(pReader); + if(nullptr != pTempElement) + m_arBrecketValue.push_back(pTempElement); + } + } + pReader->SettingTheIteratorToTheClosingBracket(); + pReader->ClearReader(); + pReader->ReadingTheNextToken(); + enOpen = GetBracketOpen(pReader->GetLowerCaseString()); + enClose = GetBracketClose(pReader->GetLowerCaseString()); + if(enOpen != TypeElement::undefine) + { + m_enRightBracket = enOpen; + pReader->ClearReader(); + } + else if(enClose != TypeElement::undefine) + { + m_enRightBracket = enClose; + pReader->ClearReader(); + } + pReader->IteratorNullification(); + } + void CElementBracket::ConversionToOOXML(XmlUtils::CXmlWriter *pXmlWrite) + { + std::wstring wsOpenBracket,wsCloseBracket; + if(m_bScalability) + { + wsOpenBracket = DefiningBracket(m_enLeftBracket); + wsCloseBracket = DefiningBracket(m_enRightBracket); + } + else + { + wsOpenBracket = DefiningBracket(m_enTypeBracket); + wsCloseBracket = DefiningBracket(m_enRightBracket); + } + if(m_enTypeBracket != TypeElement::brace) + { + pXmlWrite->WriteNodeBegin(L"m:d",false); + CConversionSMtoOOXML::PropertiesDPr(pXmlWrite,wsOpenBracket,wsCloseBracket,GetAttribute(),GetTypeConversion(),m_enTypeBracket); + pXmlWrite->WriteNodeBegin(L"m:e",false); + for(CElement* pTemp:m_arBrecketValue) + { + if(CParserStarMathString::CheckNewline(pTemp)) + continue; + if(CheckMline(pTemp)) + { + pXmlWrite->WriteNodeEnd(L"m:e",false,false); + pXmlWrite->WriteNodeBegin(L"m:e",false); + } + CConversionSMtoOOXML::ElementConversion(pXmlWrite,pTemp); + } + pXmlWrite->WriteNodeEnd(L"m:e",false,false); + pXmlWrite->WriteNodeEnd(L"m:d",false,false); + } + else + { + for(CElement* pTemp:m_arBrecketValue) + { + if(CParserStarMathString::CheckNewline(pTemp)) + continue; + CConversionSMtoOOXML::ElementConversion(pXmlWrite,pTemp); + } + } + + } + bool CElementBracket::CheckMline(CElement *pElement) + { + if(pElement == nullptr) + return false; + if(pElement->GetBaseType() == TypeElement::SpecialSymbol) + { + CElementSpecialSymbol* pSpecial = dynamic_cast(pElement); + return(pSpecial->GetType() == TypeElement::mline); + } + else + return false; + } + void CElementBracket::SetAttribute(CAttribute *pAttribute) + { + SetBaseAttribute(pAttribute); + for(CElement* pTempElement:m_arBrecketValue) + { + if(pTempElement!=nullptr) + pTempElement->SetAttribute(pAttribute); + } + } + std::wstring CElementBracket::DefiningBracket(const TypeElement &enTypeBracket) + { + switch(enTypeBracket) + { + case TypeElement::langle: + return L"\u27E8"; + case TypeElement::rangle: + return L"\u27E9"; + case TypeElement::square: + return L"\u005B"; + case TypeElement::rsquare: + return L"\u005D"; + case TypeElement::ldbracket: + return L"\u27E6"; + case TypeElement::rdbracket: + return L"\u27E7"; + case TypeElement::lbrace: + return L"\u007B"; + case TypeElement::rbrace: + return L"\u007D"; + case TypeElement::lceil: + return L"\u2308"; + case TypeElement::rceil: + return L"\u2309"; + case TypeElement::lfloor: + return L"\u230A"; + case TypeElement::rfloor: + return L"\u230B"; + case TypeElement::lline: + case TypeElement::rline: + return L"\u007C"; + case TypeElement::ldline: + case TypeElement::rdline: + return L"\u2016"; + case TypeElement::none: + return L"none"; + default: + return L""; + } + } + TFormulaSize CElementBracket::GetSize() + { + TFormulaSize tSize; + std::vector arSizeLine; + std::vector arSizeColumn; + for(CElement* pElement:m_arBrecketValue) + { + if(pElement != nullptr) + { + if(pElement->GetBaseType() == TypeElement::SpecialSymbol) + { + CElementSpecialSymbol* pSpecial = dynamic_cast(pElement); + if(pSpecial->GetType() == TypeElement::grid) + { + arSizeLine.push_back(tSize); + tSize.Zeroing(); + } + else if(pSpecial->GetType() == TypeElement::transition) + { + arSizeLine.push_back(tSize); + tSize.Zeroing(); + for(TFormulaSize tTempSize:arSizeLine) + CParserStarMathString::ComparisonByHeight(tSize,tTempSize); + tSize.m_iWidth += 0.5; + arSizeColumn.push_back(tSize); + arSizeLine.clear(); + tSize.Zeroing(); + } + else + CParserStarMathString::ComparisonByHeight(tSize,pElement->GetSize()); + } + else + CParserStarMathString::ComparisonByHeight(tSize,pElement->GetSize()); + } + } + if(tSize.m_iHeight != 0 && tSize.m_iWidth != 0 ) + { + if(!arSizeLine.empty()) + { + arSizeLine.push_back(tSize); + tSize.Zeroing(); + if(!arSizeColumn.empty()) + { + for(int i = 0 ; i < arSizeLine.size();i++) + { + CParserStarMathString::ComparisonByHeight(tSize,arSizeLine[i]); + if(i != 0) + tSize.m_iWidth += 1; + } + arSizeLine.clear(); + arSizeColumn.push_back(tSize); + tSize.Zeroing(); + for(int i = 0;i < arSizeColumn.size();i++) + { + CParserStarMathString::ComparisonByWidth(tSize,arSizeColumn[i]); + if(i != 0) + tSize.m_iHeight += 0.5; + } + arSizeColumn.clear(); + } + else + { + for(int i = 0;i < arSizeLine.size();i++) + { + CParserStarMathString::ComparisonByWidth(tSize,arSizeLine[i]); + if(i != 0) + tSize.m_iHeight += 0.5; + } + arSizeLine.clear(); + } + } + else if(!arSizeColumn.empty()) + { + arSizeColumn.push_back(tSize); + tSize.Zeroing(); + for(int i = 0; i < arSizeColumn.size();i++) + { + CParserStarMathString::ComparisonByWidth(tSize,arSizeColumn[i]); + if(i != 0) + tSize.m_iHeight += 0.5; + } + arSizeColumn.clear(); + } + } + if(m_enTypeBracket != TypeElement::brace) + tSize.m_iWidth += 1; + return tSize; + } +//class methods CElementSpecialSymbol + CElementSpecialSymbol::CElementSpecialSymbol(const TypeElement &enType,const TypeConversion &enTypeConversion) + :CElement(TypeElement::SpecialSymbol,enTypeConversion),m_pValue(nullptr),m_enTypeSpecial(enType),m_wsType(L"") + { + } + CElementSpecialSymbol::~CElementSpecialSymbol() + { + delete m_pValue; + } + void CElementSpecialSymbol::Parse(CStarMathReader* pReader) + { + switch(m_enTypeSpecial) + { + case TypeElement::fact: + case TypeElement::abs: + { + CElement* pTempElement = CParserStarMathString::ParseElement(pReader); + pReader->ReadingTheNextToken(); + while(pReader->GetGlobalType() == TypeElement::Index && (pReader->GetLocalType()!=TypeElement::nroot && pReader->GetLocalType()!=TypeElement::sqrt)) + { + CParserStarMathString::ReadingElementsWithPriorities(pReader,pTempElement); + } + m_pValue = pTempElement; + break; + } + default: + break; + } + } + void CElementSpecialSymbol::SetValue(CElement* pValue) + { + m_pValue = pValue; + } + const TypeElement CElementSpecialSymbol::GetType() + { + return m_enTypeSpecial; + } + TypeElement CElementSpecialSymbol::GetSpecialSymbol(std::wstring &wsToken) + { + if(wsToken[0] != L'%') + { + if(L"#" == wsToken) return TypeElement::grid; + else if(L"" == wsToken) return TypeElement::emptySquare; + else if(L"" == wsToken) return TypeElement::emptySquare; + else if(L"mline" == wsToken) return TypeElement::mline; + else if(L"##" == wsToken) return TypeElement::transition; + else if(L"emptyset" == wsToken) return TypeElement::emptyset; + else if(L"aleph" == wsToken) return TypeElement::aleph; + else if(L"setn" == wsToken) return TypeElement::setN; + else if(L"setz" == wsToken) return TypeElement::setZ; + else if(L"setq" == wsToken) return TypeElement::setQ; + else if(L"setr" == wsToken) return TypeElement::setR; + else if(L"setc" == wsToken) return TypeElement::setC; + else if(L"infinity" == wsToken) return TypeElement::infinity; + else if(L"infty" == wsToken) return TypeElement::infinity; + else if(L"fact" == wsToken) return TypeElement::fact; + else if(L"abs" == wsToken) return TypeElement::abs; + else if(L"`" == wsToken) return TypeElement::interval; + else if(L"~" == wsToken) return TypeElement::emptiness; + else if(L"partial" == wsToken) return TypeElement::partial; + else if(L"nabla" == wsToken) return TypeElement::nabla; + else if(L"exists" == wsToken) return TypeElement::exists; + else if(L"notexists" == wsToken) return TypeElement::notexists; + else if(L"forall" == wsToken) return TypeElement::forall; + else if(L"hbar" == wsToken) return TypeElement::hbar; + else if(L"lambdabar" == wsToken) return TypeElement::lambdabar; + else if(L"re" == wsToken) return TypeElement::Re; + else if(L"im" == wsToken) return TypeElement::Im; + else if(L"wp" == wsToken) return TypeElement::wp; + else if(L"laplace" == wsToken) return TypeElement::laplace; + else if(L"fourier" == wsToken) return TypeElement::fourier; + else if(L"backepsilon" == wsToken) return TypeElement::backepsilon; + else if(L"leftarrow" == wsToken || L"<-" == wsToken) return TypeElement::leftarrow; + else if(L"rightarrow" == wsToken || L"->" == wsToken) return TypeElement::rightarrow; + else if(L"uparrow" == wsToken) return TypeElement::uparrow; + else if(L"downarrow" == wsToken) return TypeElement::downarrow; + else if(L"dotslow" == wsToken) return TypeElement::dotslow; + else if(L"dotsaxis" == wsToken) return TypeElement::dotsaxis; + else if(L"dotsvert" == wsToken) return TypeElement::dotsvert; + else if(L"dotsup" == wsToken) return TypeElement::dotsup; + else if(L"dotsdown" == wsToken) return TypeElement::dotsdown; + else if(L"newline" == wsToken) return TypeElement::newline; + else if(L"\\" == wsToken) return TypeElement::slash; + } + else if(wsToken[0] == L'%') + { + wsToken = wsToken.substr(1,wsToken.size()-1); + if(L"ALPHA" == wsToken) return TypeElement::alpha; + else if(L"ZETA" == wsToken) return TypeElement::zeta; + else if(L"LAMBDA" == wsToken) return TypeElement::lambda; + else if(L"PI" == wsToken) return TypeElement::pi; + else if(L"PHI" == wsToken) return TypeElement::phi; + else if(L"alpha" == wsToken) return TypeElement::alpha_small; + else if(L"varepsilon" == wsToken) return TypeElement::varepsilon; + else if(L"iota" == wsToken) return TypeElement::iota_small; + else if(L"xi" == wsToken) return TypeElement::xi_small; + else if(L"varrho" == wsToken) return TypeElement::varrho; + else if(L"phi" == wsToken) return TypeElement::phi_small; + else if(L"BETA" == wsToken) return TypeElement::beta; + else if(L"ETA" == wsToken) return TypeElement::eta; + else if(L"MU" == wsToken) return TypeElement::mu; + else if(L"RHO" == wsToken) return TypeElement::rho; + else if(L"CHI" == wsToken) return TypeElement::chi; + else if(L"beta" == wsToken) return TypeElement::beta_small; + else if(L"zeta" == wsToken) return TypeElement::zeta_small; + else if(L"kappa" == wsToken) return TypeElement::kappa_small; + else if(L"omicron" == wsToken) return TypeElement::omicron_small; + else if(L"sigma" == wsToken) return TypeElement::sigma_small; + else if(L"varphi" == wsToken) return TypeElement::varphi; + else if(L"GAMMA" == wsToken) return TypeElement::gamma; + else if(L"THETA" == wsToken) return TypeElement::theta; + else if(L"NU" == wsToken) return TypeElement::nu; + else if(L"SIGMA" == wsToken) return TypeElement::sigma; + else if(L"PSI" == wsToken) return TypeElement::psi; + else if(L"gamma" == wsToken) return TypeElement::gamma_small; + else if(L"eta" == wsToken) return TypeElement::eta_small; + else if(L"lambda" == wsToken) return TypeElement::lambda_small; + else if(L"pi" == wsToken) return TypeElement::pi_small; + else if(L"varsigma" == wsToken) return TypeElement::varsigma; + else if(L"chi" == wsToken) return TypeElement::chi_small; + else if(L"DELTA" == wsToken) return TypeElement::delta; + else if(L"IOTA" == wsToken) return TypeElement::iota; + else if(L"XI" == wsToken) return TypeElement::xi; + else if(L"TAU" == wsToken) return TypeElement::tau; + else if(L"OMEGA" == wsToken) return TypeElement::omega; + else if(L"delta" == wsToken) return TypeElement::delta_small; + else if(L"theta" == wsToken) return TypeElement::theta_small; + else if(L"mu" == wsToken) return TypeElement::mu_small; + else if(L"varpi" == wsToken) return TypeElement::varpi; + else if(L"tau" == wsToken) return TypeElement::tau_small; + else if(L"psi" == wsToken) return TypeElement::psi_small; + else if(L"EPSILON" == wsToken) return TypeElement::epsilon; + else if(L"KAPPA" == wsToken) return TypeElement::kappa; + else if(L"OMICRON" == wsToken) return TypeElement::omicron; + else if(L"UPSILON" == wsToken) return TypeElement::upsilon; + else if(L"epsilon" == wsToken) return TypeElement::epsilon_small; + else if(L"vartheta" == wsToken) return TypeElement::vartheta; + else if(L"nu" == wsToken) return TypeElement::nu_small; + else if(L"rho" == wsToken) return TypeElement::rho_small; + else if(L"upsilon" == wsToken) return TypeElement::upsilon_small; + else if(L"omega" == wsToken) return TypeElement::omega_small; + else if(L"and" == wsToken) return TypeElement::And; + else if(L"infinite" == wsToken) return TypeElement::infinity; + else if(L"perthousand" == wsToken) return TypeElement::perthousand; + else if(L"angle" == wsToken) return TypeElement::notin; + else if(L"strictlygreaterthan" == wsToken) return TypeElement::dlriarrow; + else if(L"element" == wsToken) return TypeElement::in; + else if(L"notequal" == wsToken) return TypeElement::notequals; + else if(L"strictlylessthan" == wsToken) return TypeElement::dllearrow; + else if(L"identical" == wsToken) return TypeElement::equiv; + else if(L"or" == wsToken) return TypeElement::Or; + else if(L"tendto" == wsToken) return TypeElement::rightarrow; + } + return TypeElement::undefine; + } + void CElementSpecialSymbol::ConversionToOOXML(XmlUtils::CXmlWriter *pXmlWrite) + { + SetTypeSymbol(); + switch(m_enTypeSpecial) + { + case TypeElement::fact: + { + CConversionSMtoOOXML::ElementConversion(pXmlWrite,m_pValue); + pXmlWrite->WriteNodeBegin(L"m:r",false); + CConversionSMtoOOXML::StandartProperties(pXmlWrite,GetAttribute(),GetTypeConversion()); + pXmlWrite->WriteNodeBegin(L"m:t",false); + pXmlWrite->WriteString(L"\u0021"); + pXmlWrite->WriteNodeEnd(L"m:t",false,false); + pXmlWrite->WriteNodeEnd(L"m:r",false,false); + break; + } + case TypeElement::interval: + { + CConversionSMtoOOXML::WritePreserveBlock(pXmlWrite,GetAttribute(),GetTypeConversion()); + break; + } + case TypeElement::emptiness: + { + CConversionSMtoOOXML::WritePreserveBlock(pXmlWrite,GetAttribute(),GetTypeConversion()); + CConversionSMtoOOXML::WritePreserveBlock(pXmlWrite,GetAttribute(),GetTypeConversion()); + CConversionSMtoOOXML::WritePreserveBlock(pXmlWrite,GetAttribute(),GetTypeConversion()); + CConversionSMtoOOXML::WritePreserveBlock(pXmlWrite,GetAttribute(),GetTypeConversion()); + break; + } + case TypeElement::newline: + case TypeElement::slash: + { + break; + } + case TypeElement::abs: + { + pXmlWrite->WriteNodeBegin(L"m:d",false); + CConversionSMtoOOXML::PropertiesDPr(pXmlWrite,L"\u007C",L"\u007C",GetAttribute(),GetTypeConversion(),TypeElement::abs); + CConversionSMtoOOXML::WriteNodeConversion(L"m:e",m_pValue,pXmlWrite); + pXmlWrite->WriteNodeEnd(L"m:d",false,false); + break; + } + default: + { + if(!m_wsType.empty()) + { + pXmlWrite->WriteNodeBegin(L"m:r",false); + CConversionSMtoOOXML::StandartProperties(pXmlWrite,GetAttribute(),GetTypeConversion()); + pXmlWrite->WriteNodeBegin(L"m:t",false); + pXmlWrite->WriteString(XmlUtils::EncodeXmlString(m_wsType)); + pXmlWrite->WriteNodeEnd(L"m:t",false,false); + pXmlWrite->WriteNodeEnd(L"m:r",false,false); + } + break; + } + } + } + void CElementSpecialSymbol::SetAttribute(CAttribute *pAttribute) + { + SetBaseAttribute(pAttribute); + } + void CElementSpecialSymbol::SetTypeSymbol() + { + switch(m_enTypeSpecial) + { + case TypeElement::infinity: + m_wsType = L"\u221E"; + break; + case TypeElement::partial: + m_wsType = L"\u2202"; + break; + case TypeElement::nabla: + m_wsType = L"\u2207"; + break; + case TypeElement::exists: + m_wsType = L"\u2203"; + break; + case TypeElement::notexists: + m_wsType = L"\u2204"; + break; + case TypeElement::forall: + m_wsType = L"\u2200"; + break; + case TypeElement::hbar: + m_wsType = L"\u0127"; + break; + case TypeElement::lambdabar: + m_wsType = L"\u019B"; + break; + case TypeElement::Re: + m_wsType = L"\u211C"; + break; + case TypeElement::Im: + m_wsType = L"\u2111"; + break; + case TypeElement::wp: + m_wsType = L"\u2118"; + break; + case TypeElement::laplace: + m_wsType = L"\u2112"; + break; + case TypeElement::fourier: + m_wsType = L"\u2131"; + break; + case TypeElement::backepsilon: + m_wsType = L"\u03F6"; + break; + case TypeElement::alpha: + m_wsType = L"\u0391"; + break; + case TypeElement::alpha_small: + m_wsType = L"\u03B1"; + break; + case TypeElement::zeta: + m_wsType = L"\u0396"; + break; + case TypeElement::zeta_small: + m_wsType = L"\u03B6"; + break; + case TypeElement::lambda: + m_wsType = L"\u039B"; + break; + case TypeElement::lambda_small: + m_wsType = L"\u03BB"; + break; + case TypeElement::pi: + m_wsType = L"\u03A0"; + break; + case TypeElement::pi_small: + m_wsType = L"\u03C0"; + break; + case TypeElement::phi: + m_wsType = L"\u03A6"; + break; + case TypeElement::phi_small: + m_wsType = L"\u03C6"; + break; + case TypeElement::varepsilon: + m_wsType = L"\u03B5"; + break; + case TypeElement::iota_small: + m_wsType = L"\u03B9"; + break; + case TypeElement::iota: + m_wsType = L"\u0399"; + break; + case TypeElement::xi_small: + m_wsType = L"\u03BE"; + break; + case TypeElement::xi: + m_wsType = L"\u039E"; + break; + case TypeElement::varrho: + m_wsType = L"\u03F1"; + break; + case TypeElement::beta: + m_wsType = L"\u0392"; + break; + case TypeElement::beta_small: + m_wsType = L"\u03B2"; + break; + case TypeElement::eta: + m_wsType = L"\u0397"; + break; + case TypeElement::eta_small: + m_wsType = L"\u03B7"; + break; + case TypeElement::mu: + m_wsType = L"\u039C"; + break; + case TypeElement::mu_small: + m_wsType = L"\u03BC"; + break; + case TypeElement::rho: + m_wsType = L"\u03A1"; + break; + case TypeElement::rho_small: + m_wsType = L"\u03C1"; + break; + case TypeElement::chi: + m_wsType = L"\u03A7"; + break; + case TypeElement::chi_small: + m_wsType = L"\u03C7"; + break; + case TypeElement::kappa_small: + m_wsType = L"\u03BA"; + break; + case TypeElement::kappa: + m_wsType = L"\u039A"; + break; + case TypeElement::omicron: + m_wsType = L"\u039F"; + break; + case TypeElement::omicron_small: + m_wsType = L"\u03BF"; + break; + case TypeElement::sigma: + m_wsType = L"\u03A3"; + break; + case TypeElement::sigma_small: + m_wsType = L"\u03C3"; + break; + case TypeElement::varphi: + m_wsType = L"\u03C6"; + break; + case TypeElement::gamma: + m_wsType = L"\u0393"; + break; + case TypeElement::gamma_small: + m_wsType = L"\u03B3"; + break; + case TypeElement::theta: + m_wsType = L"\u0398"; + break; + case TypeElement::theta_small: + m_wsType = L"\u03B8"; + break; + case TypeElement::nu: + m_wsType = L"\u039D"; + break; + case TypeElement::nu_small: + m_wsType = L"\u03BD"; + break; + case TypeElement::psi: + m_wsType = L"\u03A8"; + break; + case TypeElement::psi_small: + m_wsType = L"\u03C8"; + break; + case TypeElement::varsigma: + m_wsType = L"\u03DB"; + break; + case TypeElement::delta: + m_wsType = L"\u0394"; + break; + case TypeElement::delta_small: + m_wsType = L"\u03B4"; + break; + case TypeElement::tau: + m_wsType = L"\u03A4"; + break; + case TypeElement::tau_small: + m_wsType = L"\u03C4"; + break; + case TypeElement::omega: + m_wsType = L"\u03A9"; + break; + case TypeElement::omega_small: + m_wsType = L"\u03C9"; + break; + case TypeElement::varpi: + m_wsType = L"\u03D6"; + break; + case TypeElement::epsilon: + m_wsType = L"\u0395"; + break; + case TypeElement::epsilon_small: + m_wsType = L"\u03B5"; + break; + case TypeElement::upsilon: + m_wsType = L"\u03A5"; + break; + case TypeElement::upsilon_small: + m_wsType = L"\u03C5"; + break; + case TypeElement::vartheta: + m_wsType = L"\u03D1"; + break; + case TypeElement::And: + m_wsType = L"\u2227"; + break; + case TypeElement::Or: + m_wsType = L"\u2228"; + break; + case TypeElement::perthousand: + m_wsType = L"\u2030"; + break; + case TypeElement::angle: + m_wsType = L"\u2222"; + break; + case TypeElement::notin: + m_wsType = L"\u2209"; + break; + case TypeElement::dlriarrow: + m_wsType = L"\u226B"; + break; + case TypeElement::dllearrow: + m_wsType = L"\u226A"; + break; + case TypeElement::in: + m_wsType = L"\u2208"; + break; + case TypeElement::notequals: + m_wsType = L"\u2260"; + break; + case TypeElement::equiv: + m_wsType = L"\u2261"; + break; + case TypeElement::rightarrow: + m_wsType = L"\u2794"; + break; + case TypeElement::leftarrow: + m_wsType = L"\u2190"; + break; + case TypeElement::uparrow: + m_wsType = L"\u2191"; + break; + case TypeElement::downarrow: + m_wsType = L"\u2193"; + break; + case TypeElement::dotsaxis: + m_wsType = L"\u22EF"; + break; + case TypeElement::dotsup: + m_wsType = L"\u22F0"; + break; + case TypeElement::dotsdown: + m_wsType = L"\u22F1"; + break; + case TypeElement::dotsvert: + m_wsType = L"\u22EE"; + break; + case TypeElement::dotslow: + m_wsType = L"\u2026"; + break; + case TypeElement::emptyset: + m_wsType = L"\u2205"; + break; + case TypeElement::aleph: + m_wsType = L"\u2135"; + break; + case TypeElement::setN: + m_wsType = L"\u2115"; + break; + case TypeElement::setZ: + m_wsType = L"\u2124"; + break; + case TypeElement::setQ: + m_wsType = L"\u211A"; + break; + case TypeElement::setR: + m_wsType = L"\u211D"; + break; + case TypeElement::setC: + m_wsType = L"\u2102"; + break; + case TypeElement::emptySquare: + m_wsType = L"\u2751"; + break; + default: + break; + } + } + TFormulaSize CElementSpecialSymbol::GetSize() + { + TFormulaSize tSize; + if(TypeElement::fact == m_enTypeSpecial || TypeElement::abs == m_enTypeSpecial) + { + if(m_pValue!= nullptr) + { + tSize = m_pValue->GetSize(); + tSize.m_iWidth += 1; + } + else + { + tSize.m_iHeight = 1; + tSize.m_iWidth = 1; + } + } + else if(TypeElement::emptiness == m_enTypeSpecial) + { + tSize.m_iHeight = 1; + tSize.m_iWidth = 4; + } + else if(TypeElement::newline != m_enTypeSpecial && TypeElement::grid != m_enTypeSpecial && TypeElement::mline != m_enTypeSpecial) + { + tSize.m_iHeight = 1; + tSize.m_iWidth = 1; + } + return tSize; + } +//class methods CElementSetOperations + CElementSetOperations::CElementSetOperations(const TypeElement &enType,const TypeConversion &enTypeConversion) + :CElement(TypeElement::SetOperations,enTypeConversion),m_pLeftArgument(nullptr), m_pRightArgument(nullptr),m_enTypeSet(enType) + { + } + CElementSetOperations::~CElementSetOperations() + { + delete m_pLeftArgument; + delete m_pRightArgument; + } + void CElementSetOperations::SetLeftArg(CElement *pElement) + { + m_pLeftArgument = pElement; + } + CElement* CElementSetOperations::GetLeftArg() + { + return m_pLeftArgument; + } + void CElementSetOperations::SetRightArg(CElement *pElement) + { + m_pRightArgument = pElement; + } + CElement* CElementSetOperations::GetRightArg() + { + return m_pRightArgument; + } + void CElementSetOperations::Parse(CStarMathReader* pReader) + { + CElement* pTempElement = CParserStarMathString::ParseElement(pReader); + pReader->ReadingTheNextToken(); + while(TypeElement::intersection != m_enTypeSet && TypeElement::setminus != m_enTypeSet && TypeElement::setquotient != m_enTypeSet && ((pReader->GetGlobalType() == TypeElement::BinOperator && pReader->GetLocalType()!=TypeElement::frac && pReader->GetLocalType()!= TypeElement::neg) || pReader->GetGlobalType() == TypeElement::BracketWithIndex || (pReader->GetGlobalType() == TypeElement::Index && pReader->GetLocalType()!=TypeElement::nroot && pReader->GetLocalType() != TypeElement::sqrt))) + { + CParserStarMathString::ReadingElementsWithPriorities(pReader,pTempElement); + } + SetRightArg(pTempElement); + } + void CElementSetOperations::ConversionToOOXML(XmlUtils::CXmlWriter *pXmlWrite) + { + CConversionSMtoOOXML::ElementConversion(pXmlWrite,m_pLeftArgument); + pXmlWrite->WriteNodeBegin(L"m:r", false); + CConversionSMtoOOXML::StandartProperties(pXmlWrite,GetAttribute(),GetTypeConversion()); + pXmlWrite->WriteNodeBegin(L"m:t",false); + switch(m_enTypeSet) + { + case TypeElement::Union: + pXmlWrite->WriteString(L"\u22C3"); + break; + case TypeElement::intersection: + pXmlWrite->WriteString(L"\u22C2"); + break; + case TypeElement::setminus: + pXmlWrite->WriteString(L"\u2216"); + break; + case TypeElement::setquotient: + pXmlWrite->WriteString(L"\u2215"); + break; + case TypeElement::subset: + pXmlWrite->WriteString(L"\u2282"); + break; + case TypeElement::subseteq: + pXmlWrite->WriteString(L"\u2286"); + break; + case TypeElement::supset: + pXmlWrite->WriteString(L"\u2283"); + break; + case TypeElement::supseteq: + pXmlWrite->WriteString(L"\u2287"); + break; + case TypeElement::nsubset: + pXmlWrite->WriteString(L"\u2284"); + break; + case TypeElement::nsubseteq: + pXmlWrite->WriteString(L"\u2288"); + break; + case TypeElement::nsupset: + pXmlWrite->WriteString(L"\u2285"); + break; + case TypeElement::nsupseteq: + pXmlWrite->WriteString(L"\u2289"); + break; + case TypeElement::in: + pXmlWrite->WriteString(L"\u2208"); + break; + case TypeElement::owns: + pXmlWrite->WriteString(L"\u220B"); + break; + case TypeElement::notin: + pXmlWrite->WriteString(L"\u2209"); + break; + default: + break; + } + pXmlWrite->WriteNodeEnd(L"m:t",false,false); + pXmlWrite->WriteNodeEnd(L"m:r",false,false); + CConversionSMtoOOXML::ElementConversion(pXmlWrite,m_pRightArgument); + } + TypeElement CElementSetOperations::GetSetOperation(const std::wstring &wsToken) + { + if(L"intersection" == wsToken) return TypeElement::intersection; + else if(L"union" == wsToken) return TypeElement::Union; + else if(L"setminus" == wsToken) return TypeElement::setminus; + else if(L"setquotient" == wsToken) return TypeElement::setquotient; + else if(L"subseteq" == wsToken) return TypeElement::subseteq; + else if(L"subset" == wsToken) return TypeElement::subset; + else if(L"supset" == wsToken) return TypeElement::supset; + else if(L"supseteq" == wsToken) return TypeElement::supseteq; + else if(L"nsubset" == wsToken) return TypeElement::nsubset; + else if(L"nsubseteq" == wsToken) return TypeElement::nsubseteq; + else if(L"nsupset" == wsToken) return TypeElement::nsupset; + else if(L"nsupseteq" == wsToken) return TypeElement::nsupseteq; + else if(L"in" == wsToken) return TypeElement::in; + else if(L"notin" == wsToken) return TypeElement::notin; + else if(L"owns" == wsToken) return TypeElement::owns; + else return TypeElement::undefine; + } + void CElementSetOperations::SetAttribute(CAttribute *pAttribute) + { + SetBaseAttribute(pAttribute); + if(m_pLeftArgument!= nullptr) + m_pLeftArgument->SetAttribute(pAttribute); + if(m_pRightArgument != nullptr) + m_pRightArgument->SetAttribute(pAttribute); + } + const TypeElement& CElementSetOperations::GetType() + { + return m_enTypeSet; + } + TFormulaSize CElementSetOperations::GetSize() + { + TFormulaSize tSize; + if(m_pLeftArgument != nullptr) + tSize = m_pLeftArgument->GetSize(); + if(m_pRightArgument != nullptr) + CParserStarMathString::ComparisonByHeight(tSize,m_pRightArgument->GetSize()); + tSize.m_iWidth += 1; + return tSize; + } +//class methods CElementConnection + CElementConnection::CElementConnection(const TypeElement& enType,const TypeConversion &enTypeConversion) + :CElement(TypeElement::Connection,enTypeConversion),m_pLeftArgument(nullptr), m_pRightArgument(nullptr),m_enTypeCon(enType) + { + } + CElementConnection::~CElementConnection() + { + delete m_pLeftArgument; + delete m_pRightArgument; + } + void CElementConnection::SetRightArg(CElement *pElement) + { + m_pRightArgument = pElement; + } + CElement* CElementConnection::GetRightArg() + { + return m_pRightArgument; + } + void CElementConnection::SetLeftArg(CElement *pElement) + { + m_pLeftArgument = pElement; + } + CElement* CElementConnection::GetLeftArg() + { + return m_pLeftArgument; + } + void CElementConnection::Parse(CStarMathReader *pReader) + { + CElement* pTempElement = CParserStarMathString::ParseElement(pReader); + pReader->ReadingTheNextToken(); + while((pReader->GetGlobalType() == TypeElement::BinOperator && pReader->GetLocalType()!=TypeElement::frac) || pReader->GetGlobalType() == TypeElement::BracketWithIndex || (pReader->GetGlobalType() == TypeElement::Index && (pReader->GetLocalType()!=TypeElement::nroot && pReader->GetLocalType()!=TypeElement::sqrt))) + { + + CParserStarMathString::ReadingElementsWithPriorities(pReader,pTempElement); + } + SetRightArg(pTempElement); + } + void CElementConnection::ConversionToOOXML(XmlUtils::CXmlWriter *pXmlWrite) + { + CConversionSMtoOOXML::ElementConversion(pXmlWrite,m_pLeftArgument); + pXmlWrite->WriteNodeBegin(L"m:r",false); + CConversionSMtoOOXML::StandartProperties(pXmlWrite,GetAttribute(),GetTypeConversion()); + pXmlWrite->WriteNodeBegin(L"m:t",false); + switch(m_enTypeCon) + { + case TypeElement::equals: + pXmlWrite->WriteString(L"\u003D"); + break; + case TypeElement::notequals: + pXmlWrite->WriteString(L"\u2260"); + break; + case TypeElement::learrow: + pXmlWrite->WriteString(L"\u0026lt;"); + break; + case TypeElement::learrowequals: + pXmlWrite->WriteString(L"\u2264"); + break; + case TypeElement::leslant: + pXmlWrite->WriteString(L"\u2A7D"); + break; + case TypeElement::riarrow: + pXmlWrite->WriteString(L"\u0026gt;"); + break; + case TypeElement::riarrowequals: + pXmlWrite->WriteString(L"\u2265"); + break; + case TypeElement::geslant: + pXmlWrite->WriteString(L"\u2A7E"); + break; + case TypeElement::dllearrow: + pXmlWrite->WriteString(L"\u226A"); + break; + case TypeElement::dlriarrow: + pXmlWrite->WriteString(L"\u226B"); + break; + case TypeElement::dlrarrow: + pXmlWrite->WriteString(L"\u21D4"); + break; + case TypeElement::drarrow: + pXmlWrite->WriteString(L"\u21D2"); + break; + case TypeElement::dlarrow: + pXmlWrite->WriteString(L"\u21D0"); + break; + case TypeElement::prec: + pXmlWrite->WriteString(L"\u227A"); + break; + case TypeElement::succ: + pXmlWrite->WriteString(L"\u227B"); + break; + case TypeElement::preccurlyeq: + pXmlWrite->WriteString(L"\u227C"); + break; + case TypeElement::succcurlyeq: + pXmlWrite->WriteString(L"\u227D"); + break; + case TypeElement::precsim: + pXmlWrite->WriteString(L"\u227E"); + break; + case TypeElement::succsim: + pXmlWrite->WriteString(L"\u227F"); + break; + case TypeElement::nprec: + pXmlWrite->WriteString(L"\u2280"); + break; + case TypeElement::nsucc: + pXmlWrite->WriteString(L"\u2281"); + break; + case TypeElement::approx: + pXmlWrite->WriteString(L"\u2248"); + break; + case TypeElement::sim: + pXmlWrite->WriteString(L"\u223C"); + break; + case TypeElement::simeq: + pXmlWrite->WriteString(L"\u2243"); + break; + case TypeElement::equiv: + pXmlWrite->WriteString(L"\u2261"); + break; + case TypeElement::prop: + pXmlWrite->WriteString(L"\u221D"); + break; + case TypeElement::parallel: + pXmlWrite->WriteString(L"\u2225"); + break; + case TypeElement::ortho: + pXmlWrite->WriteString(L"\u22A5"); + break; + case TypeElement::divides: + pXmlWrite->WriteString(L"\u2223"); + break; + case TypeElement::ndivides: + pXmlWrite->WriteString(L"\u2224"); + break; + case TypeElement::toward: + pXmlWrite->WriteString(L"\u2192"); + break; + case TypeElement::transl: + pXmlWrite->WriteString(L"\u22B7"); + break; + case TypeElement::transr: + pXmlWrite->WriteString(L"\u22B6"); + break; + case TypeElement::def: + pXmlWrite->WriteString(L"\u225D"); + break; + default: + break; + } + pXmlWrite->WriteNodeEnd(L"m:t", false, false); + pXmlWrite->WriteNodeEnd(L"m:r",false ,false); + CConversionSMtoOOXML::ElementConversion(pXmlWrite,m_pRightArgument); + } + TypeElement CElementConnection::GetConnection(const std::wstring& wsToken) + { + if(L"approx" == wsToken) return TypeElement::approx; + else if(L"sim" == wsToken) return TypeElement::sim; + else if(L"simeq" == wsToken) return TypeElement::simeq; + else if(L"equiv" == wsToken) return TypeElement::equiv; + else if(L"prop" == wsToken) return TypeElement::prop; + else if(L"parallel" == wsToken) return TypeElement::parallel; + else if(L"ortho" == wsToken) return TypeElement::ortho; + else if(L"divides" == wsToken) return TypeElement::divides; + else if(L"ndivides" == wsToken) return TypeElement::ndivides; + else if(L"toward" == wsToken) return TypeElement::toward; + else if(L"transl" == wsToken) return TypeElement::transl; + else if(L"transr" == wsToken) return TypeElement::transr; + else if(L"def" == wsToken) return TypeElement::def; + else if(L"=" == wsToken) return TypeElement::equals; + else if(L"<>" == wsToken) return TypeElement::notequals; + else if(L"<" == wsToken) return TypeElement::learrow; + else if(L"<=" == wsToken) return TypeElement::learrowequals; + else if(L"leslant" == wsToken) return TypeElement::leslant; + else if(L">" == wsToken) return TypeElement::riarrow; + else if(L">=" == wsToken) return TypeElement::riarrowequals; + else if(L"geslant" == wsToken) return TypeElement::geslant; + else if(L"<<" == wsToken) return TypeElement::dllearrow; + else if(L">>" == wsToken) return TypeElement::dlriarrow; + else if(L"prec" == wsToken) return TypeElement::prec; + else if(L"succ" == wsToken) return TypeElement::succ; + else if(L"preccurlyeq" == wsToken) return TypeElement::preccurlyeq; + else if(L"succcurlyeq" == wsToken) return TypeElement::succcurlyeq; + else if(L"precsim" == wsToken) return TypeElement::precsim; + else if(L"succsim" == wsToken) return TypeElement::succsim; + else if(L"nprec" == wsToken) return TypeElement::nprec; + else if(L"nsucc" == wsToken) return TypeElement::nsucc; + else if(L"dlarrow" == wsToken) return TypeElement::dlarrow; + else if(L"dlrarrow" == wsToken) return TypeElement::dlrarrow; + else if(L"drarrow" == wsToken) return TypeElement::drarrow; + else return TypeElement::undefine; +} + void CElementConnection::SetAttribute(CAttribute *pAttribute) + { + SetBaseAttribute(pAttribute); + if(m_pLeftArgument!= nullptr) + m_pLeftArgument->SetAttribute(pAttribute); + if(m_pRightArgument != nullptr) + m_pRightArgument->SetAttribute(pAttribute); + } + const TypeElement& CElementConnection::GetType() + { + return m_enTypeCon; + } + TFormulaSize CElementConnection::GetSize() + { + TFormulaSize tSize; + if(m_pLeftArgument != nullptr) + tSize = m_pLeftArgument->GetSize(); + if(m_pRightArgument != nullptr) + CParserStarMathString::ComparisonByHeight(tSize,m_pRightArgument->GetSize()); + tSize.m_iWidth += 1; + return tSize; + } +//class methods CIndex + CElementIndex::CElementIndex(const TypeElement& enType,const TypeConversion &enTypeConversion) + : CElement(TypeElement::Index,enTypeConversion),m_pValueIndex(nullptr),m_pUpperIndex(nullptr),m_pLowerIndex(nullptr),m_pLsubIndex(nullptr),m_pLsupIndex(nullptr),m_pCsubIndex(nullptr),m_pCsupIndex(nullptr),m_pLeftArg(nullptr),m_enTypeIndex(enType) + { + } + CElementIndex::~CElementIndex() + { + delete m_pValueIndex; + delete m_pLeftArg; + delete m_pUpperIndex; + delete m_pLowerIndex; + delete m_pLsubIndex; + delete m_pLsupIndex; + delete m_pCsubIndex; + delete m_pCsupIndex; + } + void CElementIndex::SetValueIndex(CElement *pElement) + { + m_pValueIndex = pElement; + } + void CElementIndex::SetLeftArg(CElement *pElement) + { + if(m_pLeftArg == nullptr) + m_pLeftArg = pElement; + } + CElement* CElementIndex::GetValueIndex() + { + return m_pValueIndex; + } + CElement* CElementIndex::GetLeftArg() + { + return m_pLeftArg; + } + TypeElement CElementIndex::GetIndex(const std::wstring &wsCheckToken) + { + if(L"^" == wsCheckToken) return TypeElement::upper; + else if(L"rsup" == wsCheckToken) return TypeElement::upper; + else if(L"rsub" == wsCheckToken) return TypeElement::lower; + else if(L"_" == wsCheckToken) return TypeElement::lower; + else if(L"lsup" == wsCheckToken) return TypeElement::lsup; + else if(L"lsub" == wsCheckToken) return TypeElement::lsub; + else if(L"csup" == wsCheckToken) return TypeElement::csup; + else if(L"csub" == wsCheckToken) return TypeElement::csub; + else if(L"nroot" == wsCheckToken) return TypeElement::nroot; + else if(L"sqrt" == wsCheckToken) return TypeElement::sqrt; + else return TypeElement::undefine; + } + bool CElementIndex::GetUpperIndex(const TypeElement &enType) + { + switch(enType) + { + case TypeElement::upper: + case TypeElement::csup: + case TypeElement::lsup: + return true; + default: + return false; + } + } + bool CElementIndex::GetLowerIndex(const TypeElement &enType) + { + switch(enType) + { + case TypeElement::lower: + case TypeElement::lsub: + case TypeElement::csub: + return true; + default: + return false; + } + } + void CElementIndex::Parse(CStarMathReader *pReader) + { + if(m_enTypeIndex == TypeElement::nroot) + { + m_pLeftArg = CParserStarMathString::ParseElement(pReader); + pReader->ReadingTheNextToken(); + if(CElementIndex::GetLowerIndex(pReader->GetLocalType()) || CElementIndex::GetUpperIndex(pReader->GetLocalType())) + { + CElement* pElement = CParserStarMathString::ParseElement(pReader); + CParserStarMathString::AddLeftArgument(m_pLeftArg,pElement,pReader); + m_pLeftArg = pElement; + } + m_pValueIndex = CParserStarMathString::ParseElement(pReader); + pReader->ReadingTheNextToken(); + if(CElementIndex::GetLowerIndex(pReader->GetLocalType()) || CElementIndex::GetUpperIndex(pReader->GetLocalType())) + { + CElement* pElement = CParserStarMathString::ParseElement(pReader); + CParserStarMathString::AddLeftArgument(m_pValueIndex,pElement,pReader); + m_pValueIndex = pElement; + } + } + else if(m_enTypeIndex == TypeElement::sqrt) + { + m_pValueIndex = CParserStarMathString::ParseElement(pReader); + pReader->ReadingTheNextToken(); + if(CElementIndex::GetLowerIndex(pReader->GetLocalType()) || CElementIndex::GetUpperIndex(pReader->GetLocalType())) + { + CElement* pElement = CParserStarMathString::ParseElement(pReader); + CParserStarMathString::AddLeftArgument(m_pValueIndex,pElement,pReader); + m_pValueIndex = pElement; + } + } + else + { + do + { + pReader->ClearReader(); + switch(m_enTypeIndex) + { + case TypeElement::upper: + CParserStarMathString::ReadingElementsWithAttributes(pReader,m_pUpperIndex); + break; + case TypeElement::lower: + CParserStarMathString::ReadingElementsWithAttributes(pReader,m_pLowerIndex); + break; + case TypeElement::lsub: + CParserStarMathString::ReadingElementsWithAttributes(pReader,m_pLsubIndex); + break; + case TypeElement::lsup: + CParserStarMathString::ReadingElementsWithAttributes(pReader,m_pLsupIndex); + break; + case TypeElement::csub: + CParserStarMathString::ReadingElementsWithAttributes(pReader,m_pCsubIndex); + break; + case TypeElement::csup: + CParserStarMathString::ReadingElementsWithAttributes(pReader,m_pCsupIndex); + break; + } + pReader->ReadingTheNextToken(); + m_enTypeIndex = pReader->GetLocalType(); + }while(GetUpperIndex(pReader->GetLocalType()) || GetLowerIndex(pReader->GetLocalType())); + } + } + void CElementIndex::ConversionToOOXML(XmlUtils::CXmlWriter *pXmlWrite) + { + if(TypeElement::sqrt == m_enTypeIndex || TypeElement::nroot == m_enTypeIndex) + { + pXmlWrite->WriteNodeBegin(L"m:rad",false); + pXmlWrite->WriteNodeBegin(L"m:radPr",false); + if(TypeElement::sqrt == m_enTypeIndex) + { + pXmlWrite->WriteNodeBegin(L"m:degHide",true); + pXmlWrite->WriteAttribute(L"m:val",1); + pXmlWrite->WriteNodeEnd(L"",true,true); + } + CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,GetAttribute(),GetTypeConversion()); + pXmlWrite->WriteNodeEnd(L"m:radPr",false,false); + if(m_pLeftArg != nullptr && m_enTypeIndex == TypeElement::nroot) + { + pXmlWrite->WriteNodeBegin(L"m:deg",false); + m_pLeftArg->ConversionToOOXML(pXmlWrite); + pXmlWrite->WriteNodeEnd(L"m:deg",false,false); + } + else + { + pXmlWrite->WriteNodeBegin(L"m:deg",true); + pXmlWrite->WriteNodeEnd(L"w",true,true); + } + CConversionSMtoOOXML::WriteNodeConversion(L"m:e",m_pValueIndex,pXmlWrite); + pXmlWrite->WriteNodeEnd(L"m:rad",false,false); + } + else if(m_pCsubIndex != nullptr || m_pCsupIndex != nullptr) + { + if(m_pCsubIndex != nullptr && m_pCsupIndex != nullptr) + { + pXmlWrite->WriteNodeBegin(L"m:limLow",false); + pXmlWrite->WriteNodeBegin(L"m:limLowPr",false); + CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,m_pCsubIndex->GetAttribute(),GetTypeConversion()); + pXmlWrite->WriteNodeEnd(L"m:limLowPr",false,false); + pXmlWrite->WriteNodeBegin(L"m:e",false); + pXmlWrite->WriteNodeBegin(L"m:limUpp",false); + pXmlWrite->WriteNodeBegin(L"m:limUppPr",false); + CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,m_pCsupIndex->GetAttribute(),GetTypeConversion()); + pXmlWrite->WriteNodeEnd(L"m:limUppPr",false,false); + pXmlWrite->WriteNodeBegin(L"m:e",false); + ConversionOfIndicesToValue(pXmlWrite); + pXmlWrite->WriteNodeEnd(L"m:e",false,false); + CConversionSMtoOOXML::WriteNodeConversion(L"m:lim",m_pCsupIndex,pXmlWrite); + pXmlWrite->WriteNodeEnd(L"m:limUpp",false,false); + pXmlWrite->WriteNodeEnd(L"m:e",false,false); + CConversionSMtoOOXML::WriteNodeConversion(L"m:lim",m_pCsubIndex,pXmlWrite); + pXmlWrite->WriteNodeEnd(L"m:limLow",false,false); + } + else + { + std::wstring wsNameLim; + if(m_pCsubIndex!= nullptr) + wsNameLim = L"m:limLow"; + else + wsNameLim = L"m:limUpp"; + pXmlWrite->WriteNodeBegin(wsNameLim,false); + pXmlWrite->WriteNodeBegin(wsNameLim+L"Pr",false); + CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,GetAttribute(),GetTypeConversion()); + pXmlWrite->WriteNodeEnd(wsNameLim+L"Pr",false,false); + pXmlWrite->WriteNodeBegin(L"m:e",false); + ConversionOfIndicesToValue(pXmlWrite); + pXmlWrite->WriteNodeEnd(L"m:e",false,false); + if(m_pCsubIndex != nullptr) + CConversionSMtoOOXML::WriteNodeConversion(L"m:lim",m_pCsubIndex,pXmlWrite); + else + CConversionSMtoOOXML::WriteNodeConversion(L"m:lim",m_pCsupIndex,pXmlWrite); + pXmlWrite->WriteNodeEnd(wsNameLim,false,false); + } + } + else + ConversionOfIndicesToValue(pXmlWrite); + } + void CElementIndex::SetAttribute(CAttribute *pAttribute) + { + if(m_pLeftArg != nullptr && m_pLeftArg->GetAttribute() == nullptr && pAttribute != nullptr) + m_pLeftArg->SetAttribute(pAttribute); + if(m_pLeftArg != nullptr && m_pLeftArg->GetAttribute() != nullptr) + { + m_pLeftArg->SetBaseAttribute(pAttribute); + this->SetBaseAttribute(m_pLeftArg->GetAttribute()); + } + if(m_pValueIndex != nullptr) + m_pValueIndex->SetAttribute(pAttribute); + if(m_pLeftArg != nullptr) + { + if(m_pLowerIndex != nullptr) + m_pLowerIndex->SetAttribute(m_pLeftArg->GetAttribute()); + if(m_pUpperIndex != nullptr) + m_pUpperIndex->SetAttribute(m_pLeftArg->GetAttribute()); + if(m_pLsubIndex != nullptr) + m_pLsubIndex->SetAttribute(m_pLeftArg->GetAttribute()); + if(m_pLsupIndex != nullptr) + m_pLsupIndex->SetAttribute(m_pLeftArg->GetAttribute()); + if(m_pCsubIndex != nullptr) + m_pCsubIndex->SetAttribute(m_pLeftArg->GetAttribute()); + if(m_pCsupIndex != nullptr) + m_pCsupIndex->SetAttribute(m_pLeftArg->GetAttribute()); + } + } + void CElementIndex::ConversionOfIndicesToValue(XmlUtils::CXmlWriter *pXmlWrite) + { + if(m_pLsubIndex != nullptr || m_pLsupIndex != nullptr) + { + pXmlWrite->WriteNodeBegin(L"m:sPre",false); + pXmlWrite->WriteNodeBegin(L"m:sPrePr",false); + CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,GetAttribute(),GetTypeConversion()); + pXmlWrite->WriteNodeEnd(L"m:sPrePr",false,false); + CConversionSMtoOOXML::WriteNodeConversion(L"m:sub",m_pLsubIndex,pXmlWrite); + CConversionSMtoOOXML::WriteNodeConversion(L"m:sup",m_pLsupIndex,pXmlWrite); + pXmlWrite->WriteNodeBegin(L"m:e",false); + ConversionOfIndicesAfterValue(pXmlWrite); + pXmlWrite->WriteNodeEnd(L"m:e",false,false); + pXmlWrite->WriteNodeEnd(L"m:sPre",false,false); + } + else + ConversionOfIndicesAfterValue(pXmlWrite); + } + void CElementIndex::ConversionOfIndicesAfterValue(XmlUtils::CXmlWriter *pXmlWrite) + { + if(m_pUpperIndex !=nullptr || m_pLowerIndex != nullptr) + { + std::wstring wsNameNodeIndex; + if(m_pUpperIndex != nullptr && m_pLowerIndex != nullptr) + wsNameNodeIndex = L"m:sSubSup"; + else if(m_pLowerIndex != nullptr && m_pUpperIndex == nullptr) + wsNameNodeIndex = L"m:sSub"; + else if(m_pLowerIndex == nullptr && m_pUpperIndex != nullptr) + wsNameNodeIndex = L"m:sSup"; + pXmlWrite->WriteNodeBegin(wsNameNodeIndex,false); + pXmlWrite->WriteNodeBegin(wsNameNodeIndex+L"Pr",false); + CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,GetAttribute(),GetTypeConversion()); + pXmlWrite->WriteNodeEnd(wsNameNodeIndex+L"Pr",false,false); + CConversionSMtoOOXML::WriteNodeConversion(L"m:e",m_pLeftArg,pXmlWrite); + if(m_pUpperIndex!=nullptr && m_pLowerIndex != nullptr) + { + CConversionSMtoOOXML::WriteNodeConversion(L"m:sub",m_pLowerIndex,pXmlWrite); + CConversionSMtoOOXML::WriteNodeConversion(L"m:sup",m_pUpperIndex,pXmlWrite); + } + else if(m_pLowerIndex!= nullptr) + CConversionSMtoOOXML::WriteNodeConversion(L"m:sub",m_pLowerIndex,pXmlWrite); + else if(m_pUpperIndex != nullptr) + CConversionSMtoOOXML::WriteNodeConversion(L"m:sup",m_pUpperIndex,pXmlWrite); + pXmlWrite->WriteNodeEnd(wsNameNodeIndex,false,false); + } + else + m_pLeftArg->ConversionToOOXML(pXmlWrite); + } + const TypeElement& CElementIndex::GetType() + { + return m_enTypeIndex; + } + TFormulaSize CElementIndex::GetSize() + { + TFormulaSize tSizeIndex,tLeftArgSize; + if(m_pLeftArg!= nullptr) + tLeftArgSize = m_pLeftArg->GetSize(); + if(m_pCsubIndex != nullptr) + CParserStarMathString::ComparisonByHeight(tSizeIndex,m_pCsubIndex->GetSize()); + else if(m_pCsupIndex != nullptr) + CParserStarMathString::ComparisonByHeight(tSizeIndex,m_pCsupIndex->GetSize()); + else if(m_pLowerIndex != nullptr) + CParserStarMathString::ComparisonByHeight(tSizeIndex,m_pLowerIndex->GetSize()); + else if(m_pUpperIndex != nullptr) + CParserStarMathString::ComparisonByHeight(tSizeIndex,m_pUpperIndex->GetSize()); + else if(m_pLsubIndex != nullptr) + CParserStarMathString::ComparisonByHeight(tSizeIndex,m_pLsubIndex->GetSize()); + else if(m_pLsupIndex != nullptr) + CParserStarMathString::ComparisonByHeight(tSizeIndex,m_pLsupIndex->GetSize()); + else if(m_pValueIndex != nullptr) + CParserStarMathString::ComparisonByHeight(tSizeIndex,m_pValueIndex->GetSize()); + tSizeIndex.m_iHeight += tLeftArgSize.m_iHeight; + tSizeIndex.m_iWidth += tLeftArgSize.m_iWidth; + return tSizeIndex; + } +//class methods CElementFunction + CElementFunction::CElementFunction(const TypeElement &enType, const TypeConversion &enTypeConversion ,const std::wstring &wsNameFunc) + :CElement(TypeElement::Function,enTypeConversion), m_pValue(nullptr),m_pIndex(nullptr),m_enTypeFunction(enType) + { + switch (m_enTypeFunction) { + case TypeElement::cos: + m_wsNameFunc = L"cos"; + break; + case TypeElement::sin: + m_wsNameFunc = L"sin"; + break; + case TypeElement::tan: + m_wsNameFunc = L"tan"; + break; + case TypeElement::cot: + m_wsNameFunc = L"cot"; + break; + case TypeElement::sinh: + m_wsNameFunc = L"sinh"; + break; + case TypeElement::cosh: + m_wsNameFunc = L"cosh"; + break; + case TypeElement::tanh: + m_wsNameFunc = L"tanh"; + break; + case TypeElement::coth: + m_wsNameFunc = L"coth"; + break; + case TypeElement::arcsin: + m_wsNameFunc = L"arcsin"; + break; + case TypeElement::arccos: + m_wsNameFunc = L"arccos"; + break; + case TypeElement::arctan: + m_wsNameFunc = L"arctan"; + break; + case TypeElement::arccot: + m_wsNameFunc = L"arccot"; + break; + case TypeElement::arsinh: + m_wsNameFunc = L"arsinh"; + break; + case TypeElement::arcosh: + m_wsNameFunc = L"arcosh"; + break; + case TypeElement::artanh: + m_wsNameFunc = L"artanh"; + break; + case TypeElement::arcoth: + m_wsNameFunc = L"arcoth"; + break; + case TypeElement::log: + m_wsNameFunc = L"log"; + break; + case TypeElement::ln: + m_wsNameFunc = L"ln"; + break; + case TypeElement::exp: + m_wsNameFunc = L"exp"; + break; + case TypeElement::func: + { + m_wsNameFunc = wsNameFunc; + break; + } + default: + break; + } + } + CElementFunction::~CElementFunction() + { + delete m_pValue; + delete m_pIndex; + } + void CElementFunction::SetValueFunction(CElement *pElement) + { + m_pValue = pElement; + } + CElement* CElementFunction::GetValueFunction() + { + return m_pValue; + } + void CElementFunction::SetNameFunc(const std::wstring &wsNameFunc) + { + m_wsNameFunc = wsNameFunc; + } + std::wstring CElementFunction::GetNameFuncInString() + { + return m_wsNameFunc; + } + void CElementFunction::Parse(CStarMathReader* pReader) + { + pReader->ReadingTheNextToken(); + if(CElementIndex::GetUpperIndex(pReader->GetLocalType()) || CElementIndex::GetLowerIndex(pReader->GetLocalType())) + { + m_pIndex = CParserStarMathString::ParseElement(pReader); + CElementString* pString = new CElementString(m_wsNameFunc,pReader->GetTypeConversion()); + if(this->GetAttribute() != nullptr && pReader->GetBaseAttribute()!=nullptr) + { + pString->SetAttribute(this->GetAttribute()); + pString->SetAttribute(pReader->GetBaseAttribute()); + } + else if(this->GetAttribute()!=nullptr) + pString->SetAttribute(this->GetAttribute()); + else if(pReader->GetBaseAttribute()!=nullptr) + pString->SetAttribute(pReader->GetBaseAttribute()); + + CParserStarMathString::AddLeftArgument(pString,m_pIndex,pReader); + return ; + } + CElement* pTempElement = CParserStarMathString::ParseElement(pReader); + pReader->ReadingTheNextToken(); + while(CParserStarMathString::CheckForLeftArgument(pReader->GetGlobalType())) + { + CParserStarMathString::ReadingElementsWithPriorities(pReader,pTempElement); + } + SetValueFunction(pTempElement); + } + void CElementFunction::ConversionToOOXML(XmlUtils::CXmlWriter *pXmlWrite) + { + if(m_pIndex !=nullptr) + m_pIndex->ConversionToOOXML(pXmlWrite); + else + { + pXmlWrite->WriteNodeBegin(L"m:func",false); + CConversionSMtoOOXML::PropertiesFuncPr(pXmlWrite,GetAttribute(),GetTypeConversion()); + pXmlWrite->WriteNodeBegin(L"m:fName",false); + pXmlWrite->WriteNodeBegin(L"m:r",false); + pXmlWrite->WriteNodeBegin(L"m:rPr",false); + pXmlWrite->WriteNodeBegin(L"m:sty",true); + pXmlWrite->WriteAttribute(L"m:val",L"p"); + pXmlWrite->WriteNodeEnd(L"w",true,true); + pXmlWrite->WriteNodeEnd(L"m:rPr",false,false); + CConversionSMtoOOXML::StandartProperties(pXmlWrite,GetAttribute(),GetTypeConversion()); + pXmlWrite->WriteNodeBegin(L"m:t",false); + if(!m_wsNameFunc.empty()) + pXmlWrite->WriteString(m_wsNameFunc); + pXmlWrite->WriteNodeEnd(L"m:t",false,false); + pXmlWrite->WriteNodeEnd(L"m:r",false,false); + pXmlWrite->WriteNodeEnd(L"m:fName",false,false); + if(m_pValue!=nullptr) + { + CConversionSMtoOOXML::WriteNodeConversion(L"m:e",m_pValue,pXmlWrite); + } + else + { + pXmlWrite->WriteNodeBegin(L"m:e",true); + pXmlWrite->WriteNodeEnd(L"",true,true); + } + pXmlWrite->WriteNodeEnd(L"m:func",false,false); + } + } + TypeElement CElementFunction::GetFunction(const std::wstring &wsToken) + { + if(L"sin" == wsToken) return TypeElement::sin; + else if(L"cos" == wsToken) return TypeElement::cos; + else if(L"tan" == wsToken) return TypeElement::tan; + else if(L"cot" == wsToken) return TypeElement::cot; + else if(L"sinh" == wsToken) return TypeElement::sinh; + else if(L"cosh" == wsToken) return TypeElement::cosh; + else if(L"tanh" == wsToken) return TypeElement::tanh; + else if(L"coth" == wsToken) return TypeElement::coth; + else if(L"arcsin" == wsToken) return TypeElement::arcsin; + else if(L"arccos" == wsToken) return TypeElement::arccos; + else if(L"arctan" == wsToken) return TypeElement::arctan; + else if(L"arccot" == wsToken) return TypeElement::arccot; + else if(L"arsinh" == wsToken) return TypeElement::arsinh; + else if(L"arcosh" == wsToken) return TypeElement::arcosh; + else if(L"artanh" == wsToken) return TypeElement::artanh; + else if(L"arcoth" == wsToken) return TypeElement::arcoth; + else if(L"ln" == wsToken) return TypeElement::ln; + else if(L"exp" == wsToken) return TypeElement::exp; + else if(L"log" == wsToken) return TypeElement::log; + else if(L"func" == wsToken) return TypeElement::func; + else return TypeElement::undefine; + } + void CElementFunction::SetAttribute(CAttribute *pAttribute) + { + SetBaseAttribute(pAttribute); + if(m_pValue != nullptr) + m_pValue->SetAttribute(pAttribute); + } + TFormulaSize CElementFunction::GetSize() + { + TFormulaSize tSize; + if(m_pValue != nullptr) + tSize = m_pValue->GetSize(); + if(m_pIndex != nullptr) + CParserStarMathString::ComparisonByHeight(tSize,m_pIndex->GetSize()); + if(!m_wsNameFunc.empty()) + tSize.m_iWidth += m_wsNameFunc.size(); + return tSize; + } +//class methods CElementOperation + CElementOperator::CElementOperator(const TypeElement &enType, const TypeConversion &enTypeConversion,const std::wstring& wsNameOp) + :CElement(TypeElement::Operator,enTypeConversion), m_pValueFrom(nullptr), m_pValueTo(nullptr), m_pValueOperator(nullptr),m_pUpperIndex(nullptr),m_pLowerIndex(nullptr),m_enTypeOperator(enType),m_wsName(wsNameOp) + { + } + CElementOperator::~CElementOperator() + { + delete m_pValueOperator; + delete m_pValueFrom; + delete m_pValueTo; + delete m_pLowerIndex; + delete m_pUpperIndex; + } + void CElementOperator::SetValueOperator(CElement *pElement) + { + m_pValueOperator = pElement; + } + CElement* CElementOperator::GetValueOperator() + { + return m_pValueOperator; + } + void CElementOperator::SetFromValue(CElement *pElement) + { + m_pValueFrom = pElement; + } + CElement* CElementOperator::GetFromValue() + { + return m_pValueFrom; + } + void CElementOperator::SetToValue(CElement *pElement) + { + m_pValueTo = pElement; + } + CElement* CElementOperator::GetToValue() + { + return m_pValueTo; + } + void CElementOperator::SetName(const std::wstring &wsNameOp) + { + m_wsName = wsNameOp; + } + std::wstring CElementOperator::GetName() + { + return m_wsName; + } + TypeElement CElementOperator::GetFromOrTo(const std::wstring &wsToken) + { + if(L"from" == wsToken) return TypeElement::from; + else if(L"to" == wsToken) return TypeElement::to; + else return TypeElement::undefine; + } + TypeElement CElementOperator::GetOperator(const std::wstring &wsToken) + { + if(L"lim" == wsToken) return TypeElement::lim; + else if(L"sum" == wsToken) return TypeElement::sum; + else if(L"liminf" == wsToken) return TypeElement::liminf; + else if(L"limsup" == wsToken) return TypeElement::limsup; + else if(L"prod" == wsToken) return TypeElement::prod; + else if(L"coprod" == wsToken) return TypeElement::coprod; + else if(L"int" == wsToken) return TypeElement::Int; + else if(L"iint" == wsToken) return TypeElement::iint; + else if(L"iiint" == wsToken) return TypeElement::iiint; + else if(L"lint" == wsToken) return TypeElement::lint; + else if(L"llint" == wsToken) return TypeElement::llint; + else if(L"lllint" == wsToken) return TypeElement::lllint; + else if(L"oper" == wsToken) return TypeElement::oper; + else return TypeElement::undefine; + } + void CElementOperator::Parse(CStarMathReader* pReader) + { + pReader->ReadingTheNextToken(); + while(CElementIndex::GetUpperIndex(pReader->GetLocalType()) || CElementIndex::GetLowerIndex(pReader->GetLocalType())) + { + if(CElementIndex::GetUpperIndex(pReader->GetLocalType())) + { + pReader->ClearReader(); + m_pUpperIndex = CParserStarMathString::ParseElement(pReader); + } + if(CElementIndex::GetLowerIndex(pReader->GetLocalType())) + { + pReader->ClearReader(); + m_pLowerIndex = CParserStarMathString::ParseElement(pReader); + } + pReader->ReadingTheNextToken(); + } + if(pReader->GetLocalType() == TypeElement::from) + { + pReader->ClearReader(); + SetFromValue(CParserStarMathString::ReadingWithoutBracket(pReader)); + } + if(pReader->GetLocalType() == TypeElement::to) + { + pReader->ClearReader(); + SetToValue(CParserStarMathString::ReadingWithoutBracket(pReader)); + } + m_pValueOperator = CParserStarMathString::ParseElement(pReader); + pReader->ReadingTheNextToken(); + while(pReader->GetGlobalType() == TypeElement::Index) + { + CParserStarMathString::ReadingElementsWithPriorities(pReader,m_pValueOperator); + } + } + void CElementOperator::ConversionToOOXML(XmlUtils::CXmlWriter* pXmlWrite) + { + if(m_enTypeOperator == TypeElement::lim || TypeElement::liminf == m_enTypeOperator || TypeElement::limsup == m_enTypeOperator || TypeElement::oper == m_enTypeOperator) + { + pXmlWrite->WriteNodeBegin(L"m:func",false); + CConversionSMtoOOXML::PropertiesFuncPr(pXmlWrite,GetAttribute(),GetTypeConversion()); + pXmlWrite->WriteNodeBegin(L"m:fName",false); + if((m_pValueFrom != nullptr || m_pLowerIndex != nullptr) && (m_pValueTo == nullptr && m_pUpperIndex == nullptr)) + CConversionSMtoOOXML::WriteLimUpOrLowNode(pXmlWrite,L"m:limLow",m_pValueFrom,m_enTypeOperator,GetAttribute(),this->GetTypeConversion(),m_wsName,m_pLowerIndex); + else if((m_pValueTo != nullptr || m_pUpperIndex != nullptr ) && (m_pValueFrom == nullptr && m_pLowerIndex == nullptr)) + CConversionSMtoOOXML::WriteLimUpOrLowNode(pXmlWrite,L"m:limUpp",m_pValueTo,m_enTypeOperator,GetAttribute(),this->GetTypeConversion(),m_wsName,m_pUpperIndex); + else if ((m_pValueFrom != nullptr || m_pLowerIndex != nullptr )&& (m_pValueTo != nullptr || m_pUpperIndex != nullptr)) + { + pXmlWrite->WriteNodeBegin(L"m:limUpp",false); + pXmlWrite->WriteNodeBegin(L"m:limUppPr",false); + CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,nullptr,GetTypeConversion()); + pXmlWrite->WriteNodeEnd(L"m:limUppPr",false,false); + pXmlWrite->WriteNodeBegin(L"m:e",false); + CConversionSMtoOOXML::WriteLimUpOrLowNode(pXmlWrite,L"m:limLow",m_pValueFrom,m_enTypeOperator,GetAttribute(),this->GetTypeConversion(),m_wsName,m_pLowerIndex); + pXmlWrite->WriteNodeEnd(L"m:e",false,false); + pXmlWrite->WriteNodeBegin(L"m:lim",false); + if(m_pUpperIndex !=nullptr) + m_pUpperIndex->ConversionToOOXML(pXmlWrite); + if(m_pValueTo !=nullptr) + m_pValueTo->ConversionToOOXML(pXmlWrite); + pXmlWrite->WriteNodeEnd(L"m:lim",false,false); + pXmlWrite->WriteNodeEnd(L"m:limUpp",false,false); + } + else if(m_pValueFrom == nullptr && m_pValueTo == nullptr) + CConversionSMtoOOXML::WriteRPrFName(m_enTypeOperator,pXmlWrite,GetAttribute(),GetName(),GetTypeConversion()); + pXmlWrite->WriteNodeEnd(L"m:fName",false,false); + CConversionSMtoOOXML::WriteNodeConversion(L"m:e",m_pValueOperator,pXmlWrite); + pXmlWrite->WriteNodeEnd(L"m:func",false,false); + } + else + { + pXmlWrite->WriteNodeBegin(L"m:nary",false); + CConversionSMtoOOXML::PropertiesNaryPr(m_enTypeOperator,(nullptr == m_pValueFrom && nullptr == m_pLowerIndex),(nullptr == m_pValueTo && nullptr == m_pUpperIndex),pXmlWrite,GetAttribute(),GetTypeConversion()); + if(m_pValueFrom != nullptr && m_pLowerIndex != nullptr) + { + pXmlWrite->WriteNodeBegin(L"m:sub",false); + m_pLowerIndex->ConversionToOOXML(pXmlWrite); + m_pValueFrom->ConversionToOOXML(pXmlWrite); + pXmlWrite->WriteNodeEnd(L"m:sub",false); + } + else if(m_pValueFrom == nullptr && m_pLowerIndex != nullptr) + CConversionSMtoOOXML::WriteNodeConversion(L"m:sub",m_pLowerIndex,pXmlWrite); + else if(m_pValueFrom != nullptr && m_pLowerIndex == nullptr) + CConversionSMtoOOXML::WriteNodeConversion(L"m:sub",m_pValueFrom,pXmlWrite); + else if(m_pValueFrom == nullptr && m_pLowerIndex == nullptr) + pXmlWrite->WriteNode(L"m:sub",L""); + if(m_pValueTo != nullptr && m_pUpperIndex != nullptr) + { + pXmlWrite->WriteNodeBegin(L"m:sup",false); + m_pUpperIndex->ConversionToOOXML(pXmlWrite); + m_pValueTo->ConversionToOOXML(pXmlWrite); + pXmlWrite->WriteNodeEnd(L"m:sup",false); + } + else if(m_pValueTo == nullptr && m_pUpperIndex != nullptr) + CConversionSMtoOOXML::WriteNodeConversion(L"m:sup",m_pUpperIndex,pXmlWrite); + else if(m_pValueTo != nullptr && m_pUpperIndex == nullptr) + CConversionSMtoOOXML::WriteNodeConversion(L"m:sup",m_pValueTo,pXmlWrite); + else if(m_pValueTo == nullptr && m_pUpperIndex == nullptr) + pXmlWrite->WriteNode(L"m:sup",L""); + CConversionSMtoOOXML::WriteNodeConversion(L"m:e",m_pValueOperator,pXmlWrite); + pXmlWrite->WriteNodeEnd(L"m:nary",false,false); + } + } + void CElementOperator::SetAttribute(CAttribute *pAttribute) + { + SetBaseAttribute(pAttribute); + if(m_pValueOperator!= nullptr) + m_pValueOperator->SetAttribute(pAttribute); + if(m_pValueFrom!= nullptr) + m_pValueFrom->SetAttribute(pAttribute); + if(m_pValueTo!=nullptr) + m_pValueTo->SetAttribute(pAttribute); + if(m_pLowerIndex!=nullptr) + m_pLowerIndex->SetAttribute(pAttribute); + if(m_pUpperIndex!=nullptr) + m_pUpperIndex->SetAttribute(pAttribute); + } + TFormulaSize CElementOperator::GetSize() + { + TFormulaSize tSizeTo,tSizeFrom; + if(m_pValueTo != nullptr && m_pUpperIndex != nullptr) + { + tSizeTo = m_pValueTo->GetSize(); + CParserStarMathString::ComparisonByHeight(tSizeTo,m_pUpperIndex->GetSize()); + } + else if(m_pUpperIndex != nullptr) + tSizeTo = m_pUpperIndex->GetSize(); + else if(m_pValueTo != nullptr) + tSizeTo = m_pValueTo->GetSize(); + if(m_pValueFrom != nullptr && m_pLowerIndex != nullptr) + { + tSizeFrom = m_pValueFrom->GetSize(); + CParserStarMathString::ComparisonByHeight(tSizeFrom,m_pLowerIndex->GetSize()); + } + else if(m_pLowerIndex != nullptr) + tSizeFrom = m_pLowerIndex->GetSize(); + else if(m_pValueFrom != nullptr) + tSizeFrom = m_pValueFrom->GetSize(); + CParserStarMathString::ComparisonByWidth(tSizeTo,tSizeFrom); + tSizeTo.m_iHeight += 1; + if(m_pValueOperator != nullptr) + CParserStarMathString::ComparisonByHeight(tSizeTo,m_pValueOperator->GetSize()); + return tSizeTo; + } +// class methods CStarMathReader + CStarMathReader::CStarMathReader(std::wstring::iterator& itStart, std::wstring::iterator& itEnd,const TypeConversion &enTypeConversion) + : m_enGlobalType(TypeElement::Empty),m_enUnderType(TypeElement::Empty),m_pAttribute(nullptr),m_bMarkForUnar(true),m_enTypeCon(enTypeConversion) + { + m_itStart = itStart; + m_itEnd = itEnd; + } + CStarMathReader::~CStarMathReader() + { + delete m_pAttribute; + } + //TODO :: ParseColor and ParseFont + bool CStarMathReader::GetToken() + { + if(CheckIteratorPosition()) + { + TokenProcessing(); + TypeElement enTypeFont = CAttribute::GetTypeFontAttribute(m_wsLowerCaseToken); + if(enTypeFont != TypeElement::undefine || L"color" == m_wsLowerCaseToken) + m_pAttribute = new CAttribute(); + while((enTypeFont != TypeElement::undefine || L"color" == m_wsLowerCaseToken) && m_itStart != m_itEnd) + { + if(L"color" == m_wsLowerCaseToken) + { + TokenProcessing(); + if(m_pAttribute->ParseColorAttribute(m_wsLowerCaseToken,this)) + m_wsLowerCaseToken.clear(); + } + else if(enTypeFont != TypeElement::undefine) + if(m_pAttribute->ParseFontAttribute(enTypeFont,this)) + m_wsLowerCaseToken.clear(); + else + enTypeFont = CAttribute::GetTypeFontAttribute(m_wsLowerCaseToken); + if((m_itStart != m_itEnd) && m_wsLowerCaseToken.empty()) + { + TokenProcessing(); + enTypeFont = CAttribute::GetTypeFontAttribute(m_wsLowerCaseToken); + } + } + if(m_pAttribute != nullptr && !m_pAttribute->CheckAttribute()) + m_pAttribute = nullptr; + return true; + } + return false; + } + void CStarMathReader::SetTypesToken() + { + m_enUnderType = CElementOperator::GetFromOrTo(m_wsLowerCaseToken); + if(m_enUnderType != TypeElement::undefine) + { + m_enGlobalType = TypeElement::String; + return; + } + m_enUnderType = CElementBracketWithIndex::GetBracketWithIndex(m_wsLowerCaseToken); + if(m_enUnderType != TypeElement::undefine) + { + m_enGlobalType = TypeElement::BracketWithIndex; + return; + } + m_enUnderType = CElementGrade::GetGrade(m_wsLowerCaseToken); + if(m_enUnderType != TypeElement::undefine) + { + m_enGlobalType = TypeElement::Grade; + return; + } + m_enUnderType = CElementIndex::GetIndex(m_wsLowerCaseToken); + if(m_enUnderType != TypeElement::undefine) + { + m_enGlobalType = TypeElement::Index; + return; + } + m_enUnderType=CElementMatrix::GetMatrix(m_wsLowerCaseToken); + if(m_enUnderType != TypeElement::undefine) + { + m_enGlobalType = TypeElement::Matrix; + return; + } + m_enUnderType = CElementDiacriticalMark::GetMark(m_wsLowerCaseToken); + if(m_enUnderType != TypeElement::undefine) + { + m_enGlobalType = TypeElement::Mark; + return; + } + m_enUnderType = CElementBracket::GetBracketOpen(m_wsLowerCaseToken); + if(m_enUnderType != TypeElement::undefine) + { + m_enGlobalType = TypeElement::Bracket; + return; + } + m_enUnderType = CElementString::GetDigit(m_wsLowerCaseToken); + if(m_enUnderType != TypeElement::undefine) + { + m_enGlobalType = TypeElement::String; + return; + } + m_enUnderType = CElementSpecialSymbol::GetSpecialSymbol(m_wsLowerCaseToken); + if(m_enUnderType != TypeElement::undefine) + { + m_enGlobalType = TypeElement::SpecialSymbol; + return; + } + m_enUnderType = CElementBinOperator::GetBinOperator(m_wsLowerCaseToken); + if(m_enUnderType != TypeElement::undefine) + { + m_enGlobalType = TypeElement::BinOperator; + return; + } + m_enUnderType = CElementSetOperations::GetSetOperation(m_wsLowerCaseToken); + if(m_enUnderType != TypeElement::undefine) + { + m_enGlobalType = TypeElement::SetOperations; + return; + } + m_enUnderType = CElementConnection::GetConnection(m_wsLowerCaseToken); + if(m_enUnderType != TypeElement::undefine) + { + m_enGlobalType = TypeElement::Connection; + return; + } + m_enUnderType = CElementFunction::GetFunction(m_wsLowerCaseToken); + if(m_enUnderType != TypeElement::undefine) + { + m_enGlobalType = TypeElement::Function; + return; + } + m_enUnderType = CElementOperator::GetOperator(m_wsLowerCaseToken); + if(m_enUnderType != TypeElement::undefine) + { + m_enGlobalType = TypeElement::Operation; + return; + } + if(m_enUnderType == TypeElement::undefine && !m_wsLowerCaseToken.empty()) + { + m_enGlobalType = TypeElement::String; + return; + } + } + void CStarMathReader::TokenProcessing(const std::wstring &wsToken) + { + if(wsToken.empty()) + m_wsOriginalToken = GetElement(); + else + m_wsOriginalToken = wsToken; + m_wsLowerCaseToken = CParserStarMathString::ConvertToLowerCase(m_wsOriginalToken); + } + TypeElement CStarMathReader::GetLocalType() + { + return m_enUnderType; + } + TypeElement CStarMathReader::GetGlobalType() + { + return m_enGlobalType; + } + std::wstring CStarMathReader::GetLowerCaseString() + { + return m_wsLowerCaseToken; + } + std::wstring CStarMathReader::GetOriginalString() + { + return m_wsOriginalToken; + } + void CStarMathReader::ClearReader() + { + m_wsLowerCaseToken.clear(); + m_wsOriginalToken.clear(); + m_enGlobalType = TypeElement::Empty; + m_enUnderType = TypeElement::Empty; + m_pAttribute = nullptr; + } + bool CStarMathReader::EmptyString() + { + return m_wsLowerCaseToken.empty(); + } + bool CStarMathReader::CheckIteratorPosition() + { + return (m_itStart != m_itEnd); + } + void CStarMathReader::SetAttribute(CAttribute *pAttribute) + { + m_pAttribute = pAttribute; + } + CAttribute* CStarMathReader::GetAttribute() + { + return m_pAttribute; + } + void CStarMathReader::SetBaseAttribute(const TBaseAttribute& pAttribute) + { + m_pBaseAttribute = new CAttribute; + if(pAttribute.base_font_italic) + m_pBaseAttribute->SetItal(); + if(pAttribute.base_font_bold) + m_pBaseAttribute->SetBold(); + if(!pAttribute.base_font_name.empty()) + m_pBaseAttribute->SetFontName(pAttribute.base_font_name); + if(pAttribute.base_font_size != 0) + m_pBaseAttribute->SetSize(pAttribute.base_font_size); + if(pAttribute.base_alignment >= 0 && pAttribute.base_alignment <=2) + m_pBaseAttribute->SetAlignment(pAttribute.base_alignment); + if(!m_pBaseAttribute->CheckingForEmptiness()) + m_pBaseAttribute = nullptr; + m_pBaseAttribute->SetParent(); + } + CAttribute* CStarMathReader::GetBaseAttribute() + { + return m_pBaseAttribute; + } + std::wstring CStarMathReader::GetElement() + { + std::wstring m_wsElement{}; + for(; m_itStart != m_itEnd;m_itStart++) + { + if(iswspace(*m_itStart) && m_wsElement.empty()) continue; + else if(iswspace(*m_itStart) && !m_wsElement.empty()) + { + m_itStart++; + break; + } + else if(!m_wsElement.empty() && (CheckTokenForGetElement(*m_itStart) ||(m_wsElement.back() == L'<' && (L'-' != *m_itStart && L'?' != *m_itStart && L'=' != *m_itStart && L'<' != *m_itStart && L'>' != *m_itStart)) || *m_itStart == L'(' || L')' == *m_itStart || L'(' == m_wsElement.back() || L')' == m_wsElement.back() || L'%' == *m_itStart||(L'#' == *m_itStart && L'#' != m_wsElement.back()) ||( L'+' == m_wsElement.back() && L'-' != *m_itStart ) || (L'-' == *m_itStart && L'+' != m_wsElement.back()) || (L'-' == m_wsElement.back() && L'+' != *m_itStart && L'>' != *m_itStart) || (L'+' == *m_itStart && L'-' != m_wsElement.back()) || (L'.' == *m_itStart && !iswdigit(m_wsElement.back())) || (iswdigit(*m_itStart) && !iswdigit(m_wsElement.back()) && L'.' != m_wsElement.back())|| (iswdigit(m_wsElement.back()) && !iswdigit(*m_itStart)) || ((m_wsElement.back() != L'<' && m_wsElement.back() != L'>') && (L'<' == *m_itStart || (L'>' == *m_itStart && L'-' !=m_wsElement.back() && L'?' != m_wsElement.back()) || L'=' == *m_itStart)))) + return m_wsElement; + else if((( CheckTokenForGetElement(*m_itStart) || L'=' == *m_itStart) && m_wsElement.empty()) || (!m_wsElement.empty() && ((L'#' == m_wsElement.back() && L'#' == *m_itStart) || (L'-' == *m_itStart && L'+' == m_wsElement.back()) || ((L'+' == *m_itStart || L'>' == *m_itStart) && L'-' == m_wsElement.back()) || (m_wsElement.back() == L'<' && (L'=' == *m_itStart || L'<' == *m_itStart || L'>' == *m_itStart || L'-' == *m_itStart)) ||(L'?' == m_wsElement.back() && L'>' == *m_itStart) || (m_wsElement.back() == L'>' && (L'>' == *m_itStart || L'=' == *m_itStart )) ) ) ) + { + m_wsElement.push_back(*m_itStart); + m_itStart++; + return m_wsElement; + } + else + { + m_wsElement.push_back(*m_itStart); + } + } + if(!m_wsElement.empty()) return m_wsElement; + else return {}; + } + wchar_t CStarMathReader::GetOneElement() + { + if(m_itStart!=m_itEnd) + { + wchar_t cOne = (*m_itStart); + m_itStart++; + return cOne; + } + else + return L' '; + } + std::wstring CStarMathReader::TakingElementForHex() + { + std::wstring wsTokenHex{}; + for(;m_itStart != m_itEnd;m_itStart++) + { + if(iswspace(*m_itStart)) + return wsTokenHex; + else if(CAttribute::CheckHexPosition(*m_itStart)) + wsTokenHex.push_back(*m_itStart); + else + return wsTokenHex; + } + return wsTokenHex; + } + int CStarMathReader::TakingElementForRGB() + { + int iTokenRGB{-1}; + std::wstring wsToken; + std::wstring::iterator itTempStart = m_itStart; + wsToken = GetElement(); + if(CElementString::GetDigit(wsToken) != TypeElement::undefine) + { + iTokenRGB = std::stoi(wsToken); + if(iTokenRGB >= 0 && iTokenRGB<256) + return iTokenRGB; + else + { + m_itStart = itTempStart; + return -1; + } + } + else + { + m_itStart = itTempStart; + return -1; + } + } + void CStarMathReader::SetString(const std::wstring &wsToken) + { + m_wsLowerCaseToken = wsToken; + } + void CStarMathReader::FindingTheEndOfParentheses() + { + std::wstring::iterator itStart = m_itStart,itStartBracketClose; + int inBracketInside = 0; + while(CheckIteratorPosition()) + { + itStartBracketClose = m_itStart; + bool res = GetToken(); + if (false == res) + { + break; + } + if(CElementBracket::GetBracketOpen(m_wsLowerCaseToken) != TypeElement::undefine) + { + if(CElementBracket::GetBracketOpen(m_wsLowerCaseToken) == TypeElement::left) + { + if(GetToken() && (m_wsLowerCaseToken == L"none" || (m_wsLowerCaseToken != L"left" && CElementBracket::GetBracketOpen(m_wsLowerCaseToken) != TypeElement::undefine))) + { + inBracketInside += 1; + continue; + } + } + else + inBracketInside +=1; + } + else if(CElementBracket::GetBracketClose(m_wsLowerCaseToken) == TypeElement::right) + continue; + else if(CElementBracket::GetBracketClose(m_wsLowerCaseToken) != TypeElement::undefine && inBracketInside == 0) + { + m_stBracket.push(m_itEnd); + m_stCloseBracket.push(m_itStart); + m_itEnd = itStartBracketClose; + break; + } + else if(CElementBracket::GetBracketClose(m_wsLowerCaseToken) != TypeElement::undefine && inBracketInside != 0) + { + inBracketInside -=1; + } + } + ClearReader(); + m_itStart = itStart; + } + void CStarMathReader::IteratorNullification() + { + if(!m_stBracket.empty()) + { + m_itEnd = m_stBracket.top(); + m_stBracket.pop(); + } + ClearReader(); + } + void CStarMathReader::SettingTheIteratorToTheClosingBracket() + { + if(!m_stCloseBracket.empty()) + { + m_itEnd = m_stCloseBracket.top(); + m_stCloseBracket.pop(); + } + ClearReader(); + } + void CStarMathReader::ReadingTheNextToken() + { + if(m_wsLowerCaseToken.empty()) + { + if (GetToken()) + SetTypesToken(); + else + { + ClearReader(); + } + } + } + bool CStarMathReader::CheckTokenForGetElement(const wchar_t &cToken) + { + switch(cToken) + { + case L'[': + case L']': + case L'{': + case L'}': + case L'_': + case L'^': + case L'*': + case L'/': + case L'`': + case L'~': + case L'"': + case L'\'': + return true; + default: + return false; + } + } + bool CStarMathReader::CheckIsalhpaForGetElement(const wchar_t &cToken, const wchar_t &cLastToken) + { + if(iswalpha(cToken)) + { + if(L'%' == cLastToken) + return false; +// else if(L'\u2030' == cLastToken) +// return false; + if(iswalpha(cLastToken)) + return false; + } + else + return false; + return true; + } + void CStarMathReader::SetMarkForUnar(const bool &bMark) + { + m_bMarkForUnar = bMark; + } + bool CStarMathReader::GetMarkForUnar() + { + return m_bMarkForUnar; + } + void CStarMathReader::SetTypeConversion(const TypeConversion &enTypeCon) + { + m_enTypeCon = enTypeCon; + } + TypeConversion CStarMathReader::GetTypeConversion() + { + return m_enTypeCon; + } +//class methods CElementBracketWithIndex + CElementBracketWithIndex::CElementBracketWithIndex(const TypeElement &enType,const TypeConversion &enTypeConversion) + :CElement(TypeElement::BracketWithIndex,enTypeConversion),m_pLeftArg(nullptr), m_pValue(nullptr),m_enTypeBracketWithIndex(enType) + { + } + CElementBracketWithIndex::~CElementBracketWithIndex() + { + delete m_pLeftArg; + delete m_pValue; + } + void CElementBracketWithIndex::SetLeftArg(CElement *pElement) + { + m_pLeftArg = pElement; + } + void CElementBracketWithIndex::SetBracketValue(CElement *pElement) + { + m_pValue = pElement; + } + CElement* CElementBracketWithIndex::GetLeftArg() + { + return m_pLeftArg; + } + void CElementBracketWithIndex::Parse(CStarMathReader *pReader) + { + m_pValue = CParserStarMathString::ParseElement(pReader); + pReader->ReadingTheNextToken(); + while(pReader->GetGlobalType() == TypeElement::Index) + { + CParserStarMathString::ReadingElementsWithPriorities(pReader,m_pValue); + } + } + void CElementBracketWithIndex::ConversionToOOXML(XmlUtils::CXmlWriter *pXmlWrite) + { + std::wstring wsNameNode; + switch (m_enTypeBracketWithIndex) { + case TypeElement::overbrace: + wsNameNode = L"m:limUpp"; + break; + case TypeElement::underbrace: + wsNameNode = L"m:limLow"; + break; + default: + break; + } + pXmlWrite->WriteNodeBegin(wsNameNode,false); + pXmlWrite->WriteNodeBegin(wsNameNode+L"Pr",false); + CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,GetAttribute(),GetTypeConversion()); + pXmlWrite->WriteNodeEnd(wsNameNode+L"Pr",false,false); + pXmlWrite->WriteNodeBegin(L"m:e",false); + pXmlWrite->WriteNodeBegin(L"m:groupChr",false); + pXmlWrite->WriteNodeBegin(L"m:groupChrPr",false); + if(TypeElement::overbrace == m_enTypeBracketWithIndex) + { + pXmlWrite->WriteNodeBegin(L"m:chr",true); + pXmlWrite->WriteAttribute(L"m:val",L"\u23DE"); + pXmlWrite->WriteNodeEnd(L"w",true,true); + pXmlWrite->WriteNodeBegin(L"m:pos",true); + pXmlWrite->WriteAttribute(L"m:val",L"top"); + pXmlWrite->WriteNodeEnd(L"w",true,true); + pXmlWrite->WriteNodeBegin(L"m:vertJc",true); + pXmlWrite->WriteAttribute(L"m:val",L"bot"); + pXmlWrite->WriteNodeEnd(L"w",true,true); + } + CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,GetAttribute(),GetTypeConversion()); + pXmlWrite->WriteNodeEnd(L"m:groupChrPr",false,false); + CConversionSMtoOOXML::WriteNodeConversion(L"m:e",m_pLeftArg,pXmlWrite); + pXmlWrite->WriteNodeEnd(L"m:groupChr",false,false); + pXmlWrite->WriteNodeEnd(L"m:e",false,false); + CConversionSMtoOOXML::WriteNodeConversion(L"m:lim",m_pValue,pXmlWrite); + pXmlWrite->WriteNodeEnd(wsNameNode,false,false); + } + TypeElement CElementBracketWithIndex::GetBracketWithIndex(const std::wstring &wsToken) + { + if(L"overbrace" == wsToken) return TypeElement::overbrace; + else if(L"underbrace" == wsToken) return TypeElement::underbrace; + else return TypeElement::undefine; + } + void CElementBracketWithIndex::SetAttribute(CAttribute *pAttribute) + { + SetBaseAttribute(pAttribute); + if(m_pValue!= nullptr) + m_pValue->SetAttribute(pAttribute); + if(m_pLeftArg != nullptr) + m_pLeftArg->SetAttribute(pAttribute); + } + const TypeElement& CElementBracketWithIndex::GetType() + { + return m_enTypeBracketWithIndex; + } + TFormulaSize CElementBracketWithIndex::GetSize() + { + TFormulaSize tSize,tSizeFrom; + if(m_pLeftArg != nullptr) + tSize = m_pLeftArg->GetSize(); + if(m_pValue != nullptr) + tSizeFrom = m_pValue->GetSize(); + CParserStarMathString::ComparisonByWidth(tSize,tSizeFrom); + return tSize; + } +//class methods CElementGrade + CElementGrade::CElementGrade(const TypeConversion &enTypeConversion) + :CElement(TypeElement::Grade,enTypeConversion),m_pValueGrade(nullptr), m_pValueFrom(nullptr), m_pValueTo(nullptr) + { + } + CElementGrade::~CElementGrade() + { + delete m_pValueFrom; + delete m_pValueTo; + delete m_pValueGrade; + } + void CElementGrade::SetValueFrom(CElement* pElement) + { + m_pValueFrom = pElement; + } + void CElementGrade::SetValueTo(CElement *pElement) + { + m_pValueTo = pElement; + } + void CElementGrade::SetValueGrade(CElement *pElement) + { + m_pValueGrade = pElement; + } + void CElementGrade::Parse(CStarMathReader *pReader) + { + m_pValueGrade = CParserStarMathString::ParseElement(pReader); + pReader->ReadingTheNextToken(); + if(pReader->GetLocalType() == TypeElement::from) + { + pReader->ClearReader(); + m_pValueFrom = CParserStarMathString::ParseElement(pReader); + pReader->ReadingTheNextToken(); + } + if(pReader->GetLocalType() == TypeElement::to) + { + pReader->ClearReader(); + m_pValueTo = CParserStarMathString::ParseElement(pReader); + } + if(GetAttribute() != nullptr) + SetAttribute(GetAttribute()); + } + void CElementGrade::ConversionToOOXML(XmlUtils::CXmlWriter *pXmlWrite) + { + if(m_pValueFrom == nullptr && m_pValueTo == nullptr) + { + CConversionSMtoOOXML::NodeGrade(pXmlWrite,m_pValueGrade,GetAttribute()); + } + else + { + std::wstring wsNodeGrade; + if(m_pValueFrom != nullptr && m_pValueTo == nullptr) + { + wsNodeGrade = L"m:sSub"; + } + else if(m_pValueFrom == nullptr && m_pValueTo != nullptr) + { + wsNodeGrade = L"m:sSup"; + } + else if(m_pValueFrom != nullptr && m_pValueTo != nullptr) + { + wsNodeGrade = L"m:sSubSup"; + } + pXmlWrite->WriteNodeBegin(wsNodeGrade,false); + pXmlWrite->WriteNodeBegin(wsNodeGrade + L"Pr",false); + pXmlWrite->WriteNodeBegin(L"m:ctrlPr",false); + CConversionSMtoOOXML::StandartProperties(pXmlWrite,GetAttribute(),GetTypeConversion()); + pXmlWrite->WriteNodeEnd(L"m:ctrlPr",false,false); + pXmlWrite->WriteNodeEnd(wsNodeGrade + L"Pr",false,false); + pXmlWrite->WriteNodeBegin(L"m:e",false); + CConversionSMtoOOXML::NodeGrade(pXmlWrite,m_pValueGrade,GetAttribute()); + pXmlWrite->WriteNodeEnd(L"m:e",false,false); + if(m_pValueFrom != nullptr) + { + CConversionSMtoOOXML::WriteNodeConversion(L"m:sub",m_pValueFrom,pXmlWrite); + } + if(m_pValueTo != nullptr) + { + CConversionSMtoOOXML::WriteNodeConversion(L"m:sup",m_pValueTo,pXmlWrite); + } + pXmlWrite->WriteNodeEnd(wsNodeGrade,false,false); + } + } + TypeElement CElementGrade::GetGrade(const std::wstring &wsToken) + { + if(L"evaluate" == wsToken) return TypeElement::evaluate; + else return TypeElement::undefine; + } + void CElementGrade::SetAttribute(CAttribute *pAttribute) + { + SetBaseAttribute(pAttribute); + if(m_pValueGrade!=nullptr) + m_pValueGrade->SetAttribute(pAttribute); + if(m_pValueFrom!=nullptr) + m_pValueFrom->SetAttribute(pAttribute); + if(m_pValueTo!=nullptr) + m_pValueTo->SetAttribute(pAttribute); + } + TFormulaSize CElementGrade::GetSize() + { + TFormulaSize tSizeTo,tSizeFrom; + if(m_pValueFrom != nullptr) + tSizeFrom = m_pValueFrom->GetSize(); + if(m_pValueTo != nullptr) + tSizeTo = m_pValueTo->GetSize(); + CParserStarMathString::ComparisonByWidth(tSizeTo,tSizeFrom); + tSizeTo.m_iHeight += 1; + if(m_pValueGrade != nullptr) + CParserStarMathString::ComparisonByHeight(tSizeTo,m_pValueGrade->GetSize()); + return tSizeTo; + } +//class methods CElementMatrix + CElementMatrix::CElementMatrix(const TypeElement &enType,const TypeConversion &enTypeConversion) + :CElement(TypeElement::Matrix,enTypeConversion), m_pFirstArgument(nullptr), m_pSecondArgument(nullptr), m_enTypeMatrix(enType),m_iDimension(1) + { + } + CElementMatrix::~CElementMatrix() + { + delete m_pFirstArgument; + delete m_pSecondArgument; + } + void CElementMatrix::SetFirstArgument(CElement *pElement) + { + m_pFirstArgument = pElement; + } + void CElementMatrix::SetSecondArgument(CElement *pElement) + { + m_pSecondArgument = pElement; + } + TypeElement CElementMatrix::GetMatrix(const std::wstring &wsToken) + { + if(L"binom" == wsToken) return TypeElement::binom; + else if(L"stack" == wsToken) return TypeElement::stack; + else if(L"matrix" == wsToken) return TypeElement::matrix; + else return TypeElement::undefine; + } + void CElementMatrix::Parse(CStarMathReader *pReader) + { + if(m_enTypeMatrix == TypeElement::binom) + { + SetFirstArgument(CParserStarMathString::ReadingWithoutBracket(pReader,false)); + SetSecondArgument(CParserStarMathString::ReadingWithoutBracket(pReader,false)); + } + else + { + SetFirstArgument(CParserStarMathString::ParseElement(pReader)); + } + if(GetAttribute() != nullptr) + SetAttribute(GetAttribute()); + DimensionCalculation(); + } + void CElementMatrix::ConversionToOOXML(XmlUtils::CXmlWriter *pXmlWrite) + { + pXmlWrite->WriteNodeBegin(L"m:m",false); + CConversionSMtoOOXML::PropertiesMPr(pXmlWrite,m_enTypeMatrix,GetAttribute(),GetTypeConversion(),m_iDimension); + pXmlWrite->WriteNodeBegin(L"m:mr",false); + bool bNormal(false); + switch(m_enTypeMatrix) + { + case TypeElement::matrix: + case TypeElement::stack: + { + if(m_pFirstArgument != nullptr) + { + if(m_pFirstArgument->GetBaseType() == TypeElement::Bracket) + { + CElementBracket* pTempBracket = dynamic_cast(m_pFirstArgument); + std::vector pTempValue = pTempBracket->GetBracketValue(); + pXmlWrite->WriteNodeBegin(L"m:e",false); + for(CElement* pOneElement:pTempValue) + { + if(pOneElement->GetBaseType() != TypeElement::undefine && pOneElement->GetBaseType() != TypeElement::SpecialSymbol) + pOneElement->ConversionToOOXML(pXmlWrite); + else if(pOneElement->GetBaseType()!= TypeElement::undefine && pOneElement->GetBaseType() == TypeElement::SpecialSymbol) + { + CElementSpecialSymbol* pTempSpecial = dynamic_cast(pOneElement); + if(pTempSpecial->GetType() == TypeElement::transition && m_enTypeMatrix == TypeElement::matrix) + { + pXmlWrite->WriteNodeEnd(L"m:e",false,false); + pXmlWrite->WriteNodeEnd(L"m:mr",false,false); + pXmlWrite->WriteNodeBegin(L"m:mr",false); + pXmlWrite->WriteNodeBegin(L"m:e",false); + } + else if(pTempSpecial->GetType() == TypeElement::grid) + { + switch(m_enTypeMatrix) + { + case TypeElement::stack: + { + pXmlWrite->WriteNodeEnd(L"m:e",false,false); + pXmlWrite->WriteNodeEnd(L"m:mr",false,false); + pXmlWrite->WriteNodeBegin(L"m:mr",false); + pXmlWrite->WriteNodeBegin(L"m:e",false); + break; + } + case TypeElement::matrix: + { + pXmlWrite->WriteNodeEnd(L"m:e",false,false); + pXmlWrite->WriteNodeBegin(L"m:e",false); + break; + } + default: + break; + } + } + else if(pTempSpecial->GetType() != TypeElement::grid && pTempSpecial->GetType() != TypeElement::transition) + pOneElement->ConversionToOOXML(pXmlWrite); + } + } + bNormal = true; + } + else if(m_enTypeMatrix == TypeElement::matrix) + { + CConversionSMtoOOXML::WriteNodeConversion(L"m:e",m_pFirstArgument,pXmlWrite); + CConversionSMtoOOXML::WriteNodeConversion(L"m:e",nullptr,pXmlWrite); + pXmlWrite->WriteNodeEnd(L"m:mr",false,false); + pXmlWrite->WriteNodeBegin(L"m:mr",false); + CConversionSMtoOOXML::WriteNodeConversion(L"m:e",nullptr,pXmlWrite); + CConversionSMtoOOXML::WriteNodeConversion(L"m:e",nullptr,pXmlWrite); + } + else if (m_enTypeMatrix == TypeElement::stack) + { + CConversionSMtoOOXML::WriteNodeConversion(L"m:e",m_pFirstArgument,pXmlWrite); + pXmlWrite->WriteNodeEnd(L"m:mr",false,false); + pXmlWrite->WriteNodeBegin(L"m:mr",false); + CConversionSMtoOOXML::WriteNodeConversion(L"m:e",nullptr,pXmlWrite); + } + break; + } + else if(m_pFirstArgument == nullptr && m_enTypeMatrix == TypeElement::matrix) + { + CConversionSMtoOOXML::WriteNodeConversion(L"m:e",nullptr,pXmlWrite); + CConversionSMtoOOXML::WriteNodeConversion(L"m:e",nullptr,pXmlWrite); + pXmlWrite->WriteNodeEnd(L"m:mr",false,false); + pXmlWrite->WriteNodeBegin(L"m:mr",false); + CConversionSMtoOOXML::WriteNodeConversion(L"m:e",nullptr,pXmlWrite); + CConversionSMtoOOXML::WriteNodeConversion(L"m:e",nullptr,pXmlWrite); + break; + } + else if(m_pFirstArgument == nullptr && m_enTypeMatrix == TypeElement::stack) + { + CConversionSMtoOOXML::WriteNodeConversion(L"m:e",nullptr,pXmlWrite); + pXmlWrite->WriteNodeEnd(L"m:mr",false,false); + pXmlWrite->WriteNodeBegin(L"m:mr",false); + CConversionSMtoOOXML::WriteNodeConversion(L"m:e",nullptr,pXmlWrite); + break; + } + } + case TypeElement::binom: + { + CConversionSMtoOOXML::WriteNodeConversion(L"m:e",m_pFirstArgument,pXmlWrite); + pXmlWrite->WriteNodeEnd(L"m:mr",false,false); + pXmlWrite->WriteNodeBegin(L"m:mr",false); + CConversionSMtoOOXML::WriteNodeConversion(L"m:e",m_pSecondArgument,pXmlWrite); + break; + } + } + if(bNormal) + pXmlWrite->WriteNodeEnd(L"m:e",false,false); + pXmlWrite->WriteNodeEnd(L"m:mr",false,false); + pXmlWrite->WriteNodeEnd(L"m:m",false,false); + } + void CElementMatrix::SetAttribute(CAttribute *pAttribute) + { + SetBaseAttribute(pAttribute); + if(m_pFirstArgument != nullptr) + m_pFirstArgument->SetAttribute(pAttribute); + if(m_pSecondArgument != nullptr) + m_pSecondArgument->SetAttribute(pAttribute); + } + TFormulaSize CElementMatrix::GetSize() + { + TFormulaSize tSize; + if(m_pFirstArgument!= nullptr) + tSize = m_pFirstArgument->GetSize(); + if(m_pSecondArgument != nullptr) + CParserStarMathString::ComparisonByWidth(tSize,m_pSecondArgument->GetSize()); + else if(m_pFirstArgument!= nullptr && m_pFirstArgument->GetBaseType() != TypeElement::Bracket) + { + tSize.m_iHeight += 1.5; + tSize.m_iWidth += 2; + } + return tSize; + } + void CElementMatrix::DimensionCalculation() + { + if(m_enTypeMatrix == TypeElement::matrix && m_pFirstArgument != nullptr && m_pFirstArgument->GetBaseType() == TypeElement::Bracket) + { + CElementBracket* pBracket = dynamic_cast(m_pFirstArgument); + std::vector arVec = pBracket->GetBracketValue(); + if(arVec.empty()) + return; + for(CElement* pElement:arVec) + { + if(pElement->GetBaseType() == TypeElement::SpecialSymbol) + { + CElementSpecialSymbol* pSpecial = dynamic_cast(pElement); + if(pSpecial->GetType() == TypeElement::grid) + m_iDimension ++; + else if(pSpecial->GetType() == TypeElement::transition) + return; + } + } + } + } +//class CElementDiacriticalMark + CElementDiacriticalMark::CElementDiacriticalMark(const TypeElement& enType,const TypeConversion &enTypeConversion) + :CElement(TypeElement::Mark,enTypeConversion),m_pValueMark(nullptr),m_enTypeMark(enType) + { + } + CElementDiacriticalMark::~CElementDiacriticalMark() + { + delete m_pValueMark; + } + void CElementDiacriticalMark::SetValueMark(CElement *pValue) + { + m_pValueMark = pValue; + } + TypeElement CElementDiacriticalMark::GetMark(const std::wstring &wsToken) + { + if(L"acute" == wsToken) return TypeElement::acute; + else if(L"breve" == wsToken) return TypeElement::breve; + else if(L"dot" == wsToken) return TypeElement::dot; + else if(L"dddot" == wsToken) return TypeElement::dddot; + else if(L"vec" == wsToken) return TypeElement::vec; + else if(L"tilde" == wsToken) return TypeElement::tilde; + else if(L"check" == wsToken) return TypeElement::check; + else if(L"grave" == wsToken) return TypeElement::grave; + else if(L"circle" == wsToken) return TypeElement::circle; + else if(L"ddot" == wsToken) return TypeElement::ddot; + else if(L"bar" == wsToken) return TypeElement::bar; + else if(L"harpoon" == wsToken) return TypeElement::harpoon; + else if(L"hat" == wsToken) return TypeElement::hat; + else if(L"widevec" == wsToken) return TypeElement::widevec; + else if(L"widetilde" == wsToken) return TypeElement::widetilde; + else if(L"overline" == wsToken) return TypeElement::overline; + else if(L"overstrike" == wsToken) return TypeElement::overstrike; + else if(L"wideharpoon" == wsToken) return TypeElement::wideharpoon; + else if(L"widehat" == wsToken) return TypeElement::widehat; + else if(L"underline" == wsToken) return TypeElement::underline; + else return TypeElement::undefine; + } + void CElementDiacriticalMark::Parse(CStarMathReader *pReader) + { + SetValueMark(CParserStarMathString::ParseElement(pReader)); + } + void CElementDiacriticalMark::ConversionToOOXML(XmlUtils::CXmlWriter *pXmlWrite) + { + std::wstring wsTypeMark; + switch(m_enTypeMark) + { + case TypeElement::dot: + wsTypeMark = L"\u0307"; + break; + case TypeElement::overline: + wsTypeMark = L"\u0305"; + break; + case TypeElement::vec: + wsTypeMark = L"\u20D7"; + break; + case TypeElement::acute: + wsTypeMark = L"\u0301"; + break; + case TypeElement::grave: + wsTypeMark = L"\u0300"; + break; + case TypeElement::breve: + wsTypeMark = L"\u0306"; + break; + case TypeElement::circle: + wsTypeMark = L"\u030A"; + break; + case TypeElement::ddot: + wsTypeMark = L"\u0308"; + break; + case TypeElement::bar: + wsTypeMark = L"\u0304"; + break; + case TypeElement::dddot: + wsTypeMark = L"\u20DB"; + break; + case TypeElement::harpoon: + wsTypeMark = L"\u20D1"; + break; + case TypeElement::tilde: + wsTypeMark = L"\u0342"; + break; + case TypeElement::hat: + wsTypeMark = L"\u0302"; + break; + case TypeElement::check: + wsTypeMark = L"\u030C"; + break; + case TypeElement::widevec: + wsTypeMark = L"\u20D7"; + break; + case TypeElement::widetilde: + wsTypeMark = L"\u0360"; + break; + case TypeElement::wideharpoon: + wsTypeMark = L"\u20D1"; + break; + case TypeElement::underline: + wsTypeMark = L"\u0332"; + break; + default: + break; + } + pXmlWrite->WriteNodeBegin(L"m:acc",false); + pXmlWrite->WriteNodeBegin(L"m:accPr",false); + switch(m_enTypeMark) + { + case TypeElement::widehat: + break; + default: + { + pXmlWrite->WriteNodeBegin(L"m:chr",true); + pXmlWrite->WriteAttribute(L"m:val",wsTypeMark); + pXmlWrite->WriteNodeEnd(L"w",true,true); + break; + } + } + CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,GetAttribute(),GetTypeConversion()); + pXmlWrite->WriteNodeEnd(L"m:accPr",false,false); + CConversionSMtoOOXML::WriteNodeConversion(L"m:e",m_pValueMark,pXmlWrite); + pXmlWrite->WriteNodeEnd(L"m:acc",false,false); + } + void CElementDiacriticalMark::SetAttribute(CAttribute *pAttribute) + { + SetBaseAttribute(pAttribute); + if(m_pValueMark != nullptr) + m_pValueMark->SetAttribute(pAttribute); + } + TFormulaSize CElementDiacriticalMark::GetSize() + { + TFormulaSize tSize; + tSize = m_pValueMark->GetSize(); + tSize.m_iHeight += 1; + return tSize; + } +} + + diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h new file mode 100644 index 00000000000..2d947765a36 --- /dev/null +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h @@ -0,0 +1,514 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ + +#ifndef CSTARMATHPARS_H +#define CSTARMATHPARS_H +#include "typeselements.h" +#include "typeConversion.h" +#include +#include +#include +#include +#include +#include +#include +#include "../../../../DesktopEditor/xml/include/xmlwriter.h" +#include "../../../../OOXML/Base/Unit.h" + +namespace StarMath +{ + class CStarMathReader; + + struct TBaseAttribute + { + TBaseAttribute():base_font_size(0),base_alignment(1),base_font_bold(false),base_font_italic(false){}; + unsigned int base_font_size; + std::wstring base_font_name; + unsigned int base_alignment; + bool base_font_bold; + bool base_font_italic; + }; + + struct TFormulaSize + { + TFormulaSize():m_iHeight(0),m_iWidth(0) {}; + TFormulaSize(const unsigned int& iHeight,const unsigned int& iwidth):m_iHeight(iHeight),m_iWidth(iwidth) {}; + float m_iHeight; + float m_iWidth; + void Zeroing() + { + this->m_iHeight = 0; + this->m_iWidth = 0; + } + }; + class CAttribute + { + public: + CAttribute(); + ~CAttribute(); + static TypeElement GetTypeColorAttribute(const std::wstring& wsToken); + static TypeElement GetTypeFontAttribute(const std::wstring& wsToken); + bool GetBold(); + bool GetItal(); + bool GetPhantom(); + bool GetStrike(); + unsigned int GetSize(); + unsigned int GetAlignment(); + std::wstring GetColor(); + const std::wstring& GetFontName(); + bool EmptyColor(); + bool ParseFontAttribute(const TypeElement& enTypeFont,CStarMathReader* pReader); + bool ParseColorAttribute(const std::wstring& wsToken,CStarMathReader* pReader); + void SetSize(const unsigned int& iSize); + void SetAlignment(const unsigned int& iAlignment); + void SetBold(); + void SetItal(); + void SetPhantom(); + void SetStrike(); + bool SetColor(const TypeElement& enColor); + void SetColor(const std::wstring& wsColor); + bool SetFont(const TypeElement& enFont); + void SetFontName(const std::wstring& wsNameFont); + void SetParent(); + bool GetParent(); + bool CheckAttribute(); + unsigned int GetCount(); + static void ComparingAttributes(CAttribute* pAttributeParent,CAttribute* pAttributeChild); + //checking an element for a number from 1 to 9 or from the letter A to F + static bool CheckHexPosition(const wchar_t& cToken); + bool CheckingForEmptiness(); + void AddRef(); + void Release(); + private: + void RefundOfTheAmountRGB(CStarMathReader* pReader,const int& iRed, const int& iGreen, const int& iBlue); + std::wstring m_wsColor,m_wsNameFont; + bool m_bBold,m_bItal,m_bPhantom,m_bStrike,m_bParent; + unsigned int m_iSize,m_iAlignment; + unsigned int m_unCount; + }; + //Сlass for working with tokens (reading, defining types, passing) + class CStarMathReader + { + public: + CStarMathReader(std::wstring::iterator& itStart, std::wstring::iterator& itEnd,const TypeConversion &enTypeConversion); + ~CStarMathReader(); + bool GetToken(); + //getting a subtype and setting the global type of a token to variables m_enUnderType and m_enGlobalType + void SetTypesToken(); + void TokenProcessing(const std::wstring& wsToken = L""); + TypeElement GetGlobalType(); + TypeElement GetLocalType(); + std::wstring GetLowerCaseString(); + std::wstring GetOriginalString(); + //clearing a variable m_wsToken + void ClearReader(); + bool CheckIteratorPosition(); + bool EmptyString(); + void SetAttribute(CAttribute* pAttribute); + CAttribute* GetAttribute(); + void SetBaseAttribute(const TBaseAttribute& pAttribute); + CAttribute* GetBaseAttribute(); + //The function returns a Token from a string (the iterator pointer m_itStart is on the next element) + std::wstring GetElement(); + wchar_t GetOneElement(); + //taking a token for a color in hex form + std::wstring TakingElementForHex(); + //taking a token for a color in rgb form + int TakingElementForRGB(); + void SetString(const std::wstring& wsToken); + void FindingTheEndOfParentheses(); + void IteratorNullification(); + void SettingTheIteratorToTheClosingBracket(); + void ReadingTheNextToken(); + void SetMarkForUnar(const bool& bMark); + bool GetMarkForUnar(); + void SetTypeConversion(const TypeConversion &enTypeCon); + TypeConversion GetTypeConversion(); + private: + bool CheckTokenForGetElement(const wchar_t& cToken); + bool CheckIsalhpaForGetElement(const wchar_t& cToken,const wchar_t& cLastToken); + bool m_bMarkForUnar; + std::wstring::iterator m_itStart,m_itEnd; + TypeElement m_enGlobalType,m_enUnderType; + std::wstring m_wsLowerCaseToken,m_wsOriginalToken; + CAttribute* m_pAttribute; + CAttribute* m_pBaseAttribute; + TypeConversion m_enTypeCon; + std::stack m_stBracket,m_stCloseBracket; + }; + + class CElement + { + public: + CElement(); + CElement(const TypeElement& enTypeBase, const TypeConversion& enTypeConversion); + virtual ~CElement(); + virtual void Parse(CStarMathReader* pReader) = 0; + //The function creates the class we need (by determining the class type by a variable m_enGlobalType from the class CStarMathReader) + static CElement* CreateElement(CStarMathReader* pReader); + virtual void ConversionToOOXML(XmlUtils::CXmlWriter* pXmlWrite) = 0; + virtual void SetAttribute(CAttribute* pAttribute) = 0; + virtual TFormulaSize GetSize() = 0; + void SetBaseAttribute(CAttribute* pAttribute); + void SetBaseType(const TypeElement& enType); + CAttribute* GetAttribute(); + const TypeElement& GetBaseType(); + const TypeConversion& GetTypeConversion(); + void DeleteAttribute(); + private: + CAttribute* m_pAttribute; + TypeElement m_enBaseType; + TypeConversion m_enTypeConversion; + }; + + class CElementIndex: public CElement + { + public: + CElementIndex(const TypeElement& enType,const TypeConversion &enTypeConversion); + virtual ~CElementIndex(); + void SetValueIndex(CElement* pElement); + void SetLeftArg(CElement* pElement); + CElement* GetValueIndex(); + CElement* GetLeftArg(); + static TypeElement GetIndex(const std::wstring& wsCheckToken); + static bool GetUpperIndex(const TypeElement& enType); + static bool GetLowerIndex(const TypeElement& enType); + const TypeElement& GetType(); + private: + void SetAttribute(CAttribute* pAttribute) override; + void Parse(CStarMathReader* pReader) override; + void ConversionToOOXML(XmlUtils::CXmlWriter* pXmlWrite) override; + TFormulaSize GetSize() override; + void ConversionOfIndicesToValue(XmlUtils::CXmlWriter* pXmlWrite); + void ConversionOfIndicesAfterValue(XmlUtils::CXmlWriter* pXmlWrite); + CElement* m_pValueIndex; + CElement* m_pUpperIndex; + CElement* m_pLowerIndex; + CElement* m_pLsubIndex; + CElement* m_pLsupIndex; + CElement* m_pCsubIndex; + CElement* m_pCsupIndex; + CElement* m_pLeftArg; + TypeElement m_enTypeIndex; + }; + + class CElementString: public CElement + { + public: + CElementString(const std::wstring& wsTokenString, const TypeConversion &enTypeConversion); + virtual ~CElementString(); + void SetString(const std::wstring& wsTokenString); + std::wstring GetString(); + static TypeElement GetDigit(const std::wstring& wsCheckToken); + static TypeElement GetWord(const std::wstring& wsToken); + void SetAttribute(CAttribute* pAttribute) override; + private: + void Parse(CStarMathReader* pReader) override; + void ConversionToOOXML(XmlUtils::CXmlWriter* pXmlWrite) override; + TFormulaSize GetSize() override; + std::wstring m_wsString; + }; + + class CElementBinOperator: public CElement + { + public: + CElementBinOperator(const TypeElement& enType,const TypeConversion &enTypeConversion); + virtual ~CElementBinOperator(); + void SetLeftArg(CElement* pElement); + void SetRightArg(CElement* pElement); + void SetTypeBinOP(const TypeElement& enType); + CElement* GetRightArg(); + CElement* GetLeftArg(); + static TypeElement GetBinOperator(const std::wstring& wsToken); + static void UnaryCheck(CStarMathReader* pReader,CElement* pLastElement); + const TypeElement& GetType(); + //checking for signs such as -,+,-+,+-. + static bool MixedOperators(const TypeElement& enType); + private: + void SetAttribute(CAttribute* pAttribute) override; + bool IsBinOperatorLowPrior(); + void Parse(CStarMathReader* pReader) override; + void ConversionToOOXML(XmlUtils::CXmlWriter* oXmlWrite) override; + TFormulaSize GetSize() override; + CElement* m_pLeftArgument; + CElement* m_pRightArgument; + TypeElement m_enTypeBinOp; + }; + + class CElementOperator: public CElement + { + public: + CElementOperator(const TypeElement& enType, const TypeConversion &enTypeConversion ,const std::wstring& wsNameOp = L""); + virtual ~CElementOperator(); + void SetValueOperator(CElement* pElement); + CElement* GetValueOperator(); + void SetFromValue(CElement* pElement); + CElement* GetFromValue(); + void SetToValue(CElement* pElement); + CElement* GetToValue(); + void SetName(const std::wstring& wsNameOp); + std::wstring GetName(); + static TypeElement GetOperator(const std::wstring& wsToken); + static TypeElement GetFromOrTo(const std::wstring& wsToken); + private: + void SetAttribute(CAttribute* pAttribute); + void Parse(CStarMathReader* pReader) override; + void ConversionToOOXML(XmlUtils::CXmlWriter* oXmlWrite) override; + TFormulaSize GetSize() override; + CElement* m_pValueOperator; + CElement* m_pValueFrom; + CElement* m_pValueTo; + CElement* m_pUpperIndex; + CElement* m_pLowerIndex; + TypeElement m_enTypeOperator; + std::wstring m_wsName; + }; + + class CElementGrade: public CElement + { + public: + CElementGrade(const TypeConversion &enTypeConversion); + virtual ~CElementGrade(); + void SetValueGrade(CElement* pElement); + void SetValueFrom(CElement* pElement); + void SetValueTo(CElement* pElement); + static TypeElement GetGrade(const std::wstring& wsToken); + private: + void SetAttribute(CAttribute* pAttribute) override; + void Parse(CStarMathReader* pReader) override; + void ConversionToOOXML(XmlUtils::CXmlWriter* pXmlWrite) override; + TFormulaSize GetSize() override; + CElement* m_pValueGrade; + CElement* m_pValueFrom; + CElement* m_pValueTo; + }; + + class CElementBracket: public CElement + { + public: + CElementBracket(const TypeElement& enType,const TypeConversion &enTypeConversion,const bool& bScalability = false); + virtual ~CElementBracket(); + void SetBracketValue(const std::vector& arValue); + static TypeElement GetBracketOpen(const std::wstring& wsToken); + static TypeElement GetBracketClose(const std::wstring& wsToken); + std::vector GetBracketValue(); + private: + void SetAttribute(CAttribute* pAttribute) override; + void Parse(CStarMathReader* pReader) override; + void ConversionToOOXML(XmlUtils::CXmlWriter* pXmlWrite) override; + TFormulaSize GetSize() override; + bool CheckMline(CElement* pElement); + std::wstring DefiningBracket(const TypeElement& enTypeBracket); + TypeElement m_enTypeBracket,m_enLeftBracket,m_enRightBracket; + std::vector m_arBrecketValue; + bool m_bScalability; + }; + + class CElementBracketWithIndex: public CElement + { + public: + CElementBracketWithIndex(const TypeElement& enType,const TypeConversion &enTypeConversion); + virtual ~CElementBracketWithIndex(); + void SetLeftArg(CElement* pElement); + void SetBracketValue(CElement* pElement); + CElement* GetLeftArg(); + static TypeElement GetBracketWithIndex(const std::wstring& wsToken); + const TypeElement& GetType(); + private: + void SetAttribute(CAttribute* pAttribute) override; + void Parse(CStarMathReader* pReader) override; + void ConversionToOOXML(XmlUtils::CXmlWriter* pXmlWrite) override; + TFormulaSize GetSize() override; + CElement* m_pLeftArg; + CElement* m_pValue; + TypeElement m_enTypeBracketWithIndex; + }; + + class CElementSetOperations: public CElement + { + public: + CElementSetOperations(const TypeElement& enType,const TypeConversion &enTypeConversion); + virtual ~CElementSetOperations(); + void SetLeftArg(CElement* pElement); + CElement* GetLeftArg(); + void SetRightArg(CElement* pElement); + CElement* GetRightArg(); + static TypeElement GetSetOperation(const std::wstring& wsToken); + const TypeElement& GetType(); + private: + void SetAttribute(CAttribute* pAttribute) override; + void Parse(CStarMathReader* pReader) override; + void ConversionToOOXML(XmlUtils::CXmlWriter* pXmlWrite) override; + TFormulaSize GetSize() override; + CElement* m_pLeftArgument; + CElement* m_pRightArgument; + TypeElement m_enTypeSet; + }; + + class CElementConnection: public CElement + { + public: + CElementConnection(const TypeElement& enType,const TypeConversion &enTypeConversion); + virtual ~CElementConnection(); + void SetRightArg(CElement* pElement); + CElement* GetRightArg(); + void SetLeftArg(CElement* pElement); + CElement* GetLeftArg(); + static TypeElement GetConnection(const std::wstring& wsToken); + const TypeElement& GetType(); + private: + void SetAttribute(CAttribute* pAttribute) override; + void Parse(CStarMathReader* pReader) override; + void ConversionToOOXML(XmlUtils::CXmlWriter* pXmlWrite) override; + TFormulaSize GetSize() override; + CElement* m_pLeftArgument; + CElement* m_pRightArgument; + TypeElement m_enTypeCon; + }; + + class CElementFunction: public CElement + { + public: + CElementFunction(const TypeElement& enType, const TypeConversion &enTypeConversion,const std::wstring& wsNameFunc = L""); + virtual ~CElementFunction(); + void SetValueFunction(CElement* pElement); + CElement* GetValueFunction(); + void SetNameFunc(const std::wstring& wsNameFunc); + std::wstring GetNameFuncInString(); + static TypeElement GetFunction(const std::wstring& wsToken); + private: + void SetAttribute(CAttribute* pAttribute) override; + void Parse(CStarMathReader* pReader) override; + void ConversionToOOXML(XmlUtils::CXmlWriter* pXmlWrite) override; + TFormulaSize GetSize() override; + CElement* m_pValue; + CElement* m_pIndex; + std::wstring m_wsNameFunc; + TypeElement m_enTypeFunction; + }; + + class CElementSpecialSymbol: public CElement + { + public: + CElementSpecialSymbol(const TypeElement& enType,const TypeConversion &enTypeConversion); + virtual ~CElementSpecialSymbol(); + static TypeElement GetSpecialSymbol(std::wstring& wsToken); + void SetValue(CElement* pValue); + const TypeElement GetType(); + private: + void SetTypeSymbol(); + void SetAttribute(CAttribute* pAttribute) override; + void Parse(CStarMathReader* pReader) override; + void ConversionToOOXML(XmlUtils::CXmlWriter* pXmlWrite) override; + TFormulaSize GetSize() override; + CElement* m_pValue; + TypeElement m_enTypeSpecial; + std::wstring m_wsType; + }; + + class CElementMatrix: public CElement + { + public: + CElementMatrix(const TypeElement& enType,const TypeConversion &enTypeConversion); + virtual ~CElementMatrix(); + void SetFirstArgument(CElement* pElement); + void SetSecondArgument(CElement* pElement); + static TypeElement GetMatrix(const std::wstring& wsToken); + private: + void SetAttribute(CAttribute* pAttribute) override; + void Parse(CStarMathReader *pReader) override; + void ConversionToOOXML(XmlUtils::CXmlWriter* pXmlWrite) override; + void DimensionCalculation(); + TFormulaSize GetSize() override; + CElement* m_pFirstArgument; + CElement* m_pSecondArgument; + TypeElement m_enTypeMatrix; + unsigned int m_iDimension; + }; + + class CElementDiacriticalMark: public CElement + { + public: + CElementDiacriticalMark(const TypeElement& enType,const TypeConversion &enTypeConversion); + virtual ~CElementDiacriticalMark(); + void SetValueMark(CElement* pValue); + static TypeElement GetMark(const std::wstring& wsToken); + private: + void SetAttribute(CAttribute* pAttribute) override; + void Parse(CStarMathReader* pReader) override; + void ConversionToOOXML(XmlUtils::CXmlWriter* pXmlWrite) override; + TFormulaSize GetSize() override; + CElement* m_pValueMark; + TypeElement m_enTypeMark; + }; + + class CParserStarMathString + { + public: + CParserStarMathString(); + ~CParserStarMathString(); + std::vector Parse(std::wstring& wsParseString,int iTypeConversion = 0); + static CElement* ParseElement(CStarMathReader* pReader); + //Function for adding a left argument (receives the argument itself and the element to which it needs to be added as input. Works with classes:CElementBinOperator,CElementConnection,CElementSetOperation). + static bool AddLeftArgument(CElement* pLeftArg,CElement* pElementWhichAdd,CStarMathReader* pReader); + static bool CheckForLeftArgument(const TypeElement& enType, const bool& bConnection = true); + static CElement* ReadingWithoutBracket(CStarMathReader* pReader,const bool& bConnection = true); + //checking the element (true if it is newline) + static bool CheckNewline(CElement* pElement); + static bool CheckGrid(CElement* pElement); + //adding an element to the array, checking that it is not empty and adding the left element, if there is one. + static void AddingAnElementToAnArray(std::vector& arrEquation,CElement* pAddElement,CStarMathReader* pReader); + //Receives the left element as input, reads the next one, if the next element has a higher priority and contains the left element, the element received at the input is passed to it. The entire structure is saved and returned. + static void ReadingElementsWithPriorities(CStarMathReader* pReader,CElement*& pLeftElement); + //method for parsing indexes with attributes. If there is an attribute present when indexes are read, then all subsequent indexes are applied to the index with the attribute. + static void ReadingElementsWithAttributes(CStarMathReader* pReader,CElement*& pSavingElement); + static void ParsElementAddingToArray(CStarMathReader* pReader, std::vector& arElements); + void SetAlignment(const unsigned int& iAlignment); + const unsigned int& GetAlignment(); + void SetBaseFont(const std::wstring& wsNameFont); + void SetBaseSize(const unsigned int& iSize); + void SetBaseAlignment(const unsigned int& iAlignment); + void SetBaseItalic(const bool& bItal); + void SetBaseBold(const bool& bBold); + std::queue GetFormulaSize(); + static void ComparisonByHeight(TFormulaSize& tLeftSize,const TFormulaSize& tRightSize); + static void ComparisonByWidth(TFormulaSize& tLeftSize, const TFormulaSize& tRightSize); + static std::wstring ConvertToLowerCase(const std::wstring& wsToken); + private: + TBaseAttribute m_stBaseAttribute; + std::vector m_arEquation; + unsigned int m_iAlignment; + std::queue m_qSize; + }; +} + +#endif // CSTARMATHPARS_H diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/fontType.h b/OdfFile/Reader/Converter/StarMath2OOXML/fontType.h new file mode 100644 index 00000000000..0583bc58622 --- /dev/null +++ b/OdfFile/Reader/Converter/StarMath2OOXML/fontType.h @@ -0,0 +1,13 @@ +#ifndef FONTTYPE_H +#define FONTTYPE_H +namespace StarMath +{ +enum class TypeFont +{ + sans, + serif, + fixed, + empty, +}; +} +#endif // FONTTYPE_H diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/typeConversion.h b/OdfFile/Reader/Converter/StarMath2OOXML/typeConversion.h new file mode 100644 index 00000000000..9e9ad4d3de3 --- /dev/null +++ b/OdfFile/Reader/Converter/StarMath2OOXML/typeConversion.h @@ -0,0 +1,14 @@ +#ifndef TYPECONVERSION_H +#define TYPECONVERSION_H +namespace StarMath +{ +enum class TypeConversion +{ + undefine, + pptx, + docx, + xlsx, +}; +} + +#endif // TYPECONVERSION_H diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/typeselements.h b/OdfFile/Reader/Converter/StarMath2OOXML/typeselements.h new file mode 100644 index 00000000000..fdb08eeb9ba --- /dev/null +++ b/OdfFile/Reader/Converter/StarMath2OOXML/typeselements.h @@ -0,0 +1,378 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ + +#ifndef TYPESELEMENTS_H +#define TYPESELEMENTS_H + +namespace StarMath +{ +enum class TypeElement{ + undefine, + //global + String, + BinOperator, + SetOperations, + Operator, + Bracket, + BracketWithIndex, + Grade, + Mark, + UnarSign, + Attribute, + SpecialSymbol, + Function, + Operation, + Index, + Matrix, + Connection, + Empty, + //binoop + cdot, + times, + over, + plus, + minus, + frac, + div, + multipl, + division, + oplus, + ominus, + odot, + otimes, + odivide, + circ, + wideslash, + widebslash, + //logic + And, + Or, + neg, + //unary + plus_minus, + minus_plus, + //op + lim, + sum, + liminf, + limsup, + prod, + coprod, + Int, + iint, + iiint, + lint, + llint, + lllint, + oper, + //brace + brace, + round, + square, + ldbracket, + lbrace, + langle, + lceil, + lfloor, + lline, + ldline, + left, + //attribute + ital, + bold, + phantom, + overstrike, + size, + font, + alignl, + alignc, + alignr, + //top element + acute, + breve, + dot, + dddot, + vec, + tilde, + check, + grave, + circle, + ddot, + bar, + harpoon, + hat, + widevec, + widetilde, + overline, + wideharpoon, + widehat, + underline,//top elements + color, + hex, + rgb, + black, + green, + aqua, + yellow, + lime, + navy, + purple, + teal, + blue, + red, + fuchsia, + gray, + maroon, + olive, + silver, + coral, + midnightblue, + crimson, + violet, + orange, + seagreen, + hotpink, + orangered, + indigo, + lavender, + //color(without rgb and hex) + mline, + dlgrid, + //setopetions + intersection, + Union, + setminus, + setquotient, + subseteq, + subset, + supset, + supseteq, + nsubset, + nsupseteq, + nsupset, + nsubseteq, + in, + notin, + owns, + //connection + approx, + sim, + simeq, + equiv, + prop, + parallel, + ortho, + divides, + ndivides, + toward, + transl, + transr, + def, + equals, + notequals, + learrow, + learrowequals, + leslant, + riarrow, + riarrowequals, + geslant, + dllearrow, + dlriarrow, + prec, + succ, + preccurlyeq, + succcurlyeq, + precsim, + succsim, + nprec, + nsucc, + dlarrow, + dlrarrow, + drarrow, + //SpecialSymbol + emptyset, + aleph, + setN, + setZ, + setQ, + setR, + setC, + grid, + transition, + emptiness, + interval, + infinity, + partial, + nabla, + exists, + notexists, + forall, + hbar, + lambdabar, + Re, + Im, + wp, + laplace, + fourier, + backepsilon, + alpha, + zeta, + lambda, + pi, + phi, + alpha_small, + varepsilon, + iota_small, + xi, + varrho, + phi_small, + beta, + eta, + mu, + rho, + chi, + beta_small, + zeta_small, + kappa, + omicron, + sigma, + varphi, + gamma, + theta, + nu, + sigma_small, + psi, + gamma_small, + eta_small, + lambda_small, + pi_small, + varsigma, + chi_small, + delta, + iota, + xi_small, + tau, + omega, + delta_small, + theta_small, + mu_small, + varpi, + tau_small, + psi_small, + epsilon, + kappa_small, + omicron_small, + upsilon, + epsilon_small, + vartheta, + nu_small, + rho_small, + upsilon_small, + omega_small, + perthousand, + angle, + rightarrow, + leftarrow, + uparrow, + downarrow, + dotsaxis, + dotsvert, + dotsup, + dotsdown, + dotslow, + newline, + emptySquare, + slash, + //function + abs, + fact, + sqrt, + nroot,//nroot? + sin, + cos, + tan, + cot, + sinh, + cosh, + tanh, + coth, + arcsin, + arccos, + arctan, + arccot, + arsinh, + arcosh, + artanh, + arcoth, + ln, + exp, + log, + func, + //index + upper, + lower, + lsup, + lsub, + csup, + csub, + // + binom, + stack, + matrix, + //bracket close + rwbrace, + rbrace, + rround, + rsquare, + rdbracket, + rangle, + rceil, + rfloor, + rline, + rdline, + right, + none, + //op + from, + to, + //bracketWithIndex + overbrace, + underbrace, + //grade + evaluate, + //string + letter, + number, + letter_u32, +}; +} +#endif // TYPESELEMENTS_H diff --git a/OdfFile/Reader/Converter/docx_conversion_context.cpp b/OdfFile/Reader/Converter/docx_conversion_context.cpp index 3f43a5fbd55..03f600d9b77 100644 --- a/OdfFile/Reader/Converter/docx_conversion_context.cpp +++ b/OdfFile/Reader/Converter/docx_conversion_context.cpp @@ -751,6 +751,15 @@ void docx_conversion_context::end_document() output_document_->get_docProps_files().set_app(package::simple_element::create(L"app.xml", dump_settings_app())); output_document_->get_docProps_files().set_core(package::simple_element::create(L"core.xml", dump_settings_core())); + std::wstring settings_custom = dump_settings_custom(); + if (false == settings_custom.empty()) + { + output_document_->get_docProps_files().set_custom(package::simple_element::create(L"custom.xml", settings_custom)); + output_document_->get_content_types_file().content()->add_override(L"/docProps/custom.xml", L"application/vnd.openxmlformats-officedocument.custom-properties+xml"); + output_document_->get_rels_files().add( + relationship(L"rCstmId", L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/custom-properties", L"docProps/custom.xml")); + } + for (size_t i = 0; i < charts_.size(); i++) { package::chart_content_ptr content = package::chart_content::create(); @@ -899,6 +908,24 @@ std::wstring docx_conversion_context::dump_settings_app() } return output.str(); } +std::wstring docx_conversion_context::dump_settings_custom() +{ + std::wstring user_defined = odf_document_->odf_context().DocProps().dump_user_defined(); + if (user_defined.empty()) return L""; + + std::wstringstream output; + CP_XML_WRITER(output) + { + CP_XML_NODE(L"Properties") + { + CP_XML_ATTR(L"xmlns", L"http://schemas.openxmlformats.org/officeDocument/2006/custom-properties"); + CP_XML_ATTR(L"xmlns:vt", L"http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes"); + + CP_XML_STREAM() << user_defined; + } + } + return output.str(); +} std::wstring docx_conversion_context::dump_settings_core() { std::wstringstream output; @@ -1015,6 +1042,52 @@ std::wstring docx_conversion_context::dump_settings_document() _CP_OPT(std::wstring) strVal; _CP_OPT(int) intVal; + strVal = root()->odf_context().Settings().find_by_name(L"modifyPasswordInfo"); + if (strVal) + { + CP_XML_NODE(L"w:writeProtection") + { + strVal = root()->odf_context().Settings().find_by_name(L"modify:crypt-name"); + if (strVal) + { + CP_XML_ATTR(L"w:cryptProviderType", *strVal); + CP_XML_ATTR(L"w:cryptAlgorithmClass", L"hash"); + CP_XML_ATTR(L"w:cryptAlgorithmType", L"typeAny"); + + strVal = root()->odf_context().Settings().find_by_name(L"modify:algorithm-name"); + if (strVal) + { + if (*strVal == L"SHA-512") CP_XML_ATTR(L"w:cryptAlgorithmSid", L"14"); + if (*strVal == L"SHA-386") CP_XML_ATTR(L"w:cryptAlgorithmSid", L"13"); + if (*strVal == L"SHA-256") CP_XML_ATTR(L"w:cryptAlgorithmSid", L"12"); + if (*strVal == L"SHA-1") CP_XML_ATTR(L"w:cryptAlgorithmSid", L"4"); + } + + strVal = root()->odf_context().Settings().find_by_name(L"modify:iteration-count"); + if (strVal) CP_XML_ATTR(L"w:cryptSpinCount", *strVal); + + strVal = root()->odf_context().Settings().find_by_name(L"modify:hash"); + if (strVal) CP_XML_ATTR(L"w:hash", *strVal); + + strVal = root()->odf_context().Settings().find_by_name(L"modify:salt"); + if (strVal) CP_XML_ATTR(L"w:salt", *strVal); + } + else + { + strVal = root()->odf_context().Settings().find_by_name(L"modify:algorithm-name"); + if (strVal) CP_XML_ATTR(L"w:algorithmName", *strVal); + + strVal = root()->odf_context().Settings().find_by_name(L"modify:hash"); + if (strVal) CP_XML_ATTR(L"w:hashValue", *strVal); + + strVal = root()->odf_context().Settings().find_by_name(L"modify:salt"); + if (strVal) CP_XML_ATTR(L"w:saltValue", *strVal); + + strVal = root()->odf_context().Settings().find_by_name(L"modify:iteration-count"); + if (strVal) CP_XML_ATTR(L"w:spinCount", *strVal); + } + } + } if (odf_reader::GetProperty(settings_properties_,L"evenAndOddHeaders", boolVal)) { CP_XML_NODE(L"w:evenAndOddHeaders"); @@ -1034,6 +1107,16 @@ std::wstring docx_conversion_context::dump_settings_document() { CP_XML_NODE(L"w:mirrorMargins"); } + + _CP_OPT(double) tabDistance = root()->odf_context().Settings().get_tab_distance(); + + if (tabDistance) + { + CP_XML_NODE(L"w:defaultTabStop") + { + CP_XML_ATTR(L"w:val", *tabDistance); + } + } CP_XML_NODE(L"w:compat") { @@ -1767,6 +1850,8 @@ void docx_conversion_context::start_list(const std::wstring & StyleName, bool Co list_style_stack_.push_back(list_style_stack_.back()); else list_style_stack_.push_back(L""); + + list_styles_occurances_[list_style_stack_.back()]++; } void docx_conversion_context::end_list() @@ -1782,6 +1867,32 @@ std::wstring docx_conversion_context::current_list_style() return L""; } +static _CP_PTR(odf_reader::text_list_style) create_restarted_list_style(docx_conversion_context& context, const std::wstring& curStyleName, const std::wstring& newStyleName) +{ + odf_reader::list_style_container& lists = context.root()->odf_context().listStyleContainer(); + + odf_reader::text_list_style* curStyle = lists.list_style_by_name(curStyleName); + _CP_PTR(odf_reader::text_list_style) newStyle = boost::make_shared(*curStyle); + + newStyle->attr_.style_name_ = newStyleName; + + const std::vector& style_stack = context.get_list_style_stack(); + + for (const std::wstring& s : style_stack) + { + for (size_t i = 0; i < newStyle->content_.size() && i < style_stack.size() - 1; i++) + { + odf_reader::text_list_level_style_number* level_style_number = + dynamic_cast(newStyle->content_[i].get()); + + if (level_style_number) + level_style_number->number_attr_.text_start_value_ = context.get_list_style_occurances(s) + 1; + } + } + + return newStyle; +} + void docx_conversion_context::start_list_item(bool restart) { first_element_list_item_ = true; @@ -1794,7 +1905,10 @@ void docx_conversion_context::start_list_item(bool restart) odf_reader::list_style_container & lists = root()->odf_context().listStyleContainer(); odf_reader::text_list_style * curStyle = lists.list_style_by_name(curStyleName); - lists.add_list_style(curStyle, newStyleName); + _CP_PTR(odf_reader::text_list_style) newStyle = create_restarted_list_style(*this, curStyleName, newStyleName); + restarted_list_styles.push_back(newStyle); + + lists.add_list_style(newStyle.get()); end_list(); start_list(newStyleName); } @@ -2312,9 +2426,12 @@ void docx_conversion_context::process_headers_footers() process_headers_footers_ = false; } -void docx_conversion_context::set_master_page_name(const std::wstring & MasterPageName) +bool docx_conversion_context::set_master_page_name(const std::wstring & MasterPageName) { + if (current_master_page_name_ == MasterPageName) return false; + current_master_page_name_ = MasterPageName; + return true; } const std::wstring & docx_conversion_context::get_master_page_name() const @@ -2377,7 +2494,7 @@ void docx_conversion_context::start_text_changes (const std::wstring &id) if (state_.in_paragraph_) { - std::wstring format_change = L" w:date=\"" + state.date + L"\" w:author=\"" + state.author + L"\""; + std::wstring format_change = L" w:date=\"" + state.date + L"\" w:author=\"" + XmlUtils::EncodeXmlString(state.author) + L"\""; finish_run(); state.in_drawing = get_drawing_state_content(); @@ -2438,7 +2555,7 @@ void docx_conversion_context::start_changes(bool in_para) std::wstring change_attr; change_attr += L" w:date=\"" + state.date + L"\""; - change_attr += L" w:author=\"" + state.author + L"\""; + change_attr += L" w:author=\"" + XmlUtils::EncodeXmlString(state.author) + L"\""; if (state.oox_id == 0) { diff --git a/OdfFile/Reader/Converter/docx_conversion_context.h b/OdfFile/Reader/Converter/docx_conversion_context.h index 895252b8e57..20becec3895 100644 --- a/OdfFile/Reader/Converter/docx_conversion_context.h +++ b/OdfFile/Reader/Converter/docx_conversion_context.h @@ -36,6 +36,7 @@ #include "../../DataTypes/noteclass.h" #include +#include #include #include @@ -66,6 +67,7 @@ namespace cpdoccore { class style_columns; class form_element; class text_linenumbering_configuration; + class text_list_style; namespace text { @@ -803,6 +805,7 @@ class docx_conversion_context : boost::noncopyable std::wstring dump_settings_document(); std::wstring dump_settings_app(); std::wstring dump_settings_core(); + std::wstring dump_settings_custom(); bool next_dump_page_properties_; bool next_dump_section_; @@ -882,7 +885,7 @@ class docx_conversion_context : boost::noncopyable void last_dump_page_properties (bool val); bool is_last_dump_page_properties (); - void set_master_page_name(const std::wstring & MasterPageName); + bool set_master_page_name(const std::wstring & MasterPageName); const std::wstring & get_master_page_name() const; void start_text_list_style (const std::wstring & StyleName); @@ -895,7 +898,11 @@ class docx_conversion_context : boost::noncopyable void end_list (); void start_list_item (bool restart = false); void end_list_item (); - + + size_t get_list_style_level() { return list_style_stack_.size(); } + size_t get_list_style_occurances(const std::wstring& styleName) { return list_styles_occurances_[styleName]; } + const std::vector& get_list_style_stack() const { return list_style_stack_; } + void serialize_list_properties(std::wostream & strm); void serialize_paragraph_style(std::wostream & strm, const std::wstring & ParentId, bool in_styles = false); @@ -1085,6 +1092,9 @@ class docx_conversion_context : boost::noncopyable std::map> mapAlphabeticals; std::vector arBibliography; + + std::vector<_CP_PTR(odf_reader::text_list_style)> restarted_list_styles; + std::unordered_map list_styles_occurances_; }; } diff --git a/OdfFile/Reader/Converter/docx_drawing.cpp b/OdfFile/Reader/Converter/docx_drawing.cpp index f4bdd4e3e28..84c9f51a3c1 100644 --- a/OdfFile/Reader/Converter/docx_drawing.cpp +++ b/OdfFile/Reader/Converter/docx_drawing.cpp @@ -288,9 +288,16 @@ void docx_serialize_image_child(std::wostream & strm, _docx_drawing & val) { CP_XML_NODE(L"pic:cNvPr") { + _CP_OPT(std::wstring) title, descr; + GetProperty(val.additional, L"svg:title", title); + GetProperty(val.additional, L"svg:desc", descr); + //CP_XML_ATTR(L"desc text",L""); CP_XML_ATTR(L"id", val.id + 1); CP_XML_ATTR(L"name", val.name); + + CP_XML_ATTR_OPT(L"title", title); + CP_XML_ATTR_OPT(L"descr", descr); //oox_serialize_action(CP_XML_STREAM(), val.action); } @@ -399,8 +406,15 @@ void docx_serialize_common(std::wostream & strm, _docx_drawing & val) { CP_XML_NODE(L"wp:docPr") { + _CP_OPT(std::wstring) title, descr; + GetProperty(val.additional, L"svg:title", title); + GetProperty(val.additional, L"svg:desc", descr); + CP_XML_ATTR(L"name", val.name); CP_XML_ATTR(L"id", 0xf000 + val.id + 1); + + CP_XML_ATTR_OPT(L"title", title); + CP_XML_ATTR_OPT(L"descr", descr); oox_serialize_action(CP_XML_STREAM(), val.action); } @@ -740,7 +754,8 @@ void _docx_drawing::serialize(std::wostream & strm/*, bool insideOtherDrawing*/) return docx_serialize_child(strm, *this); if (type == typeMsObject || - type == typeOleObject) + type == typeOleObject || + type == typePDF) { docx_serialize_object(strm, *this); } diff --git a/OdfFile/Reader/Converter/docx_drawing.h b/OdfFile/Reader/Converter/docx_drawing.h index c6107cffd35..5a5353c5cba 100644 --- a/OdfFile/Reader/Converter/docx_drawing.h +++ b/OdfFile/Reader/Converter/docx_drawing.h @@ -44,10 +44,11 @@ namespace oox { class _docx_drawing : public _oox_drawing { public: - _docx_drawing() : _oox_drawing(), parallel(0), isInline(false), number_wrapped_paragraphs(0), posOffsetV(0), posOffsetH(0) + _docx_drawing() : _oox_drawing(), parallel(0), isInline(false), inFrame(false), number_wrapped_paragraphs(0), posOffsetV(0), posOffsetH(0) { } bool isInline; + bool inFrame; unsigned int parallel; diff --git a/OdfFile/Reader/Converter/docx_package.cpp b/OdfFile/Reader/Converter/docx_package.cpp index 63570d4cf49..45916a33dc1 100644 --- a/OdfFile/Reader/Converter/docx_package.cpp +++ b/OdfFile/Reader/Converter/docx_package.cpp @@ -461,7 +461,7 @@ void comments_elements::write(const std::wstring & RootPath) { content << L"0) - content << L"w:author=\""<< elm.author << "\" "; + content << L"w:author=\""<< XmlUtils::EncodeXmlString(elm.author) << "\" "; if (elm.date.length()>0) content << L"w:date=\""<< elm.date << "\" "; content<< L">"; diff --git a/OdfFile/Reader/Converter/drawing_object_description.h b/OdfFile/Reader/Converter/drawing_object_description.h index 7f7c8576ca5..692fb11fd67 100644 --- a/OdfFile/Reader/Converter/drawing_object_description.h +++ b/OdfFile/Reader/Converter/drawing_object_description.h @@ -60,7 +60,8 @@ struct drawing_object_description bool bInner_; std::wstring name_; - std::wstring descriptor_; + std::wstring descriptor_; + std::wstring xml_id_; _CP_OPT(_rect) svg_rect_; @@ -75,6 +76,8 @@ struct drawing_object_description _action_desc action_; std::vector<_hlink_desc> hlinks_; + bool hidden_; + std::vector additional_; //shape properties std::wstring xlink_href_; //ссылка на внешний объект @@ -86,6 +89,11 @@ struct drawing_object_description bool lined_; bool connector_; int shape_type_; //default - frame + _CP_OPT(std::wstring) start_shape_id; + _CP_OPT(int) start_shape_glue_point; + _CP_OPT(std::wstring) end_shape_id; + _CP_OPT(int) end_shape_glue_point; + _CP_OPT(std::wstring) draw_type_; std::vector child_objects_; }; diff --git a/OdfFile/Reader/Converter/mediaitems.cpp b/OdfFile/Reader/Converter/mediaitems.cpp index beee3f8f71c..5de91800ed2 100644 --- a/OdfFile/Reader/Converter/mediaitems.cpp +++ b/OdfFile/Reader/Converter/mediaitems.cpp @@ -33,6 +33,7 @@ #include "mediaitems.h" #include +#include #include @@ -42,8 +43,13 @@ #include "../../../DesktopEditor/common/Directory.h" #include "../../../DesktopEditor/raster/ImageFileFormatChecker.h" +#include "../../../Common/OfficeFileFormatChecker.h" #include "../../../DesktopEditor/graphics/pro/Fonts.h" +#include "../../../DesktopEditor/graphics/MetafileToGraphicsRenderer.h" +#include "../../../DesktopEditor/graphics/Image.h" +#include "../../../PdfFile/PdfFile.h" + namespace cpdoccore { namespace oox { @@ -63,7 +69,7 @@ bool is_internal(const std::wstring & uri, const std::wstring & packetRoot) std::wstring testRoot = pathRoot.GetPath(); std::wstring testFile = pathFile.GetPath(); - return (NSFile::CFileBinary::Exists(resultPath) || NSDirectory::Exists(mediaPath)) && (std::wstring::npos != testFile.find(testRoot)); + return (NSFile::CFileBinary::Exists(testFile) || NSDirectory::Exists(testFile)) && (std::wstring::npos != testFile.find(testRoot)); } mediaitems::item::item(std::wstring const & _href,_rels_type _type, std::wstring const & _outputName, @@ -88,7 +94,7 @@ mediaitems::mediaitems(const std::wstring & odfPacket) : odf_packet_(odfPacket) count_activeX = 0; count_control = 0; - applicationFonts_ = NSFonts::NSApplication::Create(); + applicationFonts_ = NSFonts::NSApplication::Create(); } mediaitems::~mediaitems() { @@ -97,8 +103,17 @@ mediaitems::~mediaitems() } void mediaitems::set_font_directory(std::wstring pathFonts) { - if (applicationFonts_) - applicationFonts_->InitializeFromFolder(pathFonts); + if (applicationFonts_) + { + if (pathFonts.empty()) + applicationFonts_->Initialize(); + else + applicationFonts_->InitializeFromFolder(pathFonts); + } +} +bool mediaitems::is_internal_path(const std::wstring& uri, const std::wstring& packetRoot) +{ + return is_internal(uri, packetRoot); } std::wstring mediaitems::add_or_find(const std::wstring & href, _rels_type type, bool & isInternal, _rels_type_place type_place) @@ -107,6 +122,54 @@ std::wstring mediaitems::add_or_find(const std::wstring & href, _rels_type type, return add_or_find(href, type, isInternal, ref, type_place); } +std::wstring mediaitems::add_or_find_anim_audio(const std::wstring& href, bool& isInternal, std::wstring& ref) +{ + std::wstring sub_path = L"media/"; + int number = count_audio + 1; + + bool isAudioInternal; + const std::wstring inputFileName = create_file_name(href, _rels_type::typeAudio, isAudioInternal, number); + + isInternal = is_internal(href, odf_packet_); + + std::wstring inputPath = isInternal ? (odf_packet_ + FILE_SEPARATOR_STR + href) : href; + std::wstring outputPath = sub_path + inputFileName; + + std::wstring id; + for (size_t i = 0; i < items_.size(); i++) + { + if (items_[i].type_place != _rels_type_place::document_place) + continue; + + if ((items_[i].href == inputPath && !inputPath.empty()) || (items_[i].type == _rels_type::typeAudio && inputPath.empty())) + { + id = items_[i].Id; + outputPath = items_[i].outputName; + + items_[i].count_add++; + break; + } + } + + if (id.empty()) + { + id = std::wstring(L"aId") + std::to_wstring(count_audio + 1); + count_audio++; + + items_.push_back(item( + inputPath, + _rels_type::typeAudio, + XmlUtils::EncodeXmlString(outputPath), + false, + id, + _rels_type_place::document_place + )); + } + + ref = outputPath; + return id; +} + std::wstring static get_default_file_name(_rels_type type) { switch (type) @@ -118,6 +181,7 @@ std::wstring static get_default_file_name(_rels_type type) case typeMsObject: return L"msObject"; case typeOleObject: + case typePDF: return L"oleObject"; case typeMedia: return L"media"; @@ -130,7 +194,7 @@ std::wstring static get_default_file_name(_rels_type type) case typeControl: return L"control"; case typeControlProps: - return L"controlProps"; + return L"controlProps"; default: return L""; } @@ -174,6 +238,8 @@ std::wstring mediaitems::create_file_name(const std::wstring & uri, _rels_type t sExt = L".bin"; else if ( type == typeChart) sExt = L".xml"; + else if ( type == typePDF) + sExt = L".bin"; return get_default_file_name(type) + std::to_wstring(Num) + sExt; } @@ -193,6 +259,16 @@ std::wstring mediaitems::detectImageFileExtension(const std::wstring &fileName) CImageFileFormatChecker image_checker; sExt = image_checker.DetectFormatByData(buffer, buffer_size); + if (sExt.empty()) + { + std::wstring documentID; + COfficeFileFormatChecker office_checker; + + if (office_checker.isPdfFormatFile(buffer, buffer_size, documentID)) + { + sExt = L"pdf"; + } + } if (sExt.empty()) { size_t n = fileName.rfind(L"."); @@ -215,8 +291,9 @@ std::wstring mediaitems::add_or_find(const std::wstring & href, _rels_type type, { sub_path = L"charts/"; } - else if ( type == typeMsObject || type == typeOleObject) + else if ( type == typeMsObject || type == typeOleObject || type == typePDF) { + isMediaInternal = is_internal(href, odf_packet_); sub_path = L"embeddings/"; } else if ( type == typeControlProps) @@ -239,8 +316,9 @@ std::wstring mediaitems::add_or_find(const std::wstring & href, _rels_type type, else if ( type == typeAudio) number = count_audio + 1; else if ( type == typeVideo) number = count_video + 1; else if ( type == typeSlide) number = count_slide + 1; - else if ( type == typeMsObject || - type == typeOleObject) number = count_object + 1; + else if ( type == typeMsObject || + type == typeOleObject || + type == typePDF) number = count_object + 1; else if ( type == typeControl) number = count_control + 1; else number = items_.size() + 1; @@ -288,7 +366,7 @@ std::wstring mediaitems::add_or_find(const std::wstring & href, _rels_type type, id = std::wstring(L"picId") + std::to_wstring(count_image + 1); count_image++; } - else if ( type == typeMsObject || type == typeOleObject) + else if ( type == typeMsObject || type == typeOleObject || type == typePDF) { id = std::wstring(L"objId") + std::to_wstring(count_object + 1); count_object++; @@ -360,6 +438,71 @@ void mediaitems::dump_rels(rels & Rels, _rels_type_place type_place) items_[i].count_used++; } } +bool mediaitems::pdf2image(const std::wstring& pdf_file_name, const std::wstring& image_file_name) +{ + _UINT32 nRes = 0; + IOfficeDrawingFile* pReader = new CPdfFile(applicationFonts_); + if (!pReader) return false; + + bool bResult = pReader->LoadFromFile(pdf_file_name.c_str(), L""); + + if (bResult) + { + // default as in CMetafileToRenderterRaster + int nRasterFormat = 4; + int nSaveType = 2; + bool bIsOnlyFirst = true; + bool bIsZip = true; + int nRasterW = 100; + int nRasterH = 100; + + int nSaveFlags = (nSaveType & 0xF0) >> 4; + nSaveType = nSaveType & 0x0F; + + int nPagesCount = 1; + + { + int nRasterWCur = nRasterW; + int nRasterHCur = nRasterH; + + double dPageDpiX, dPageDpiY; + double dWidth, dHeight; + pReader->GetPageInfo(0, &dWidth, &dHeight, &dPageDpiX, &dPageDpiY); + + if (nSaveFlags & 0x0F) + { + if (((dWidth < dHeight) && (nRasterWCur > nRasterHCur)) || + ((dWidth > dHeight) && (nRasterWCur < nRasterHCur))) + { + int nTmp = nRasterWCur; + nRasterWCur = nRasterHCur; + nRasterHCur = nTmp; + } + } + + if (1 == nSaveType) + { + double dKoef1 = nRasterWCur / dWidth; + double dKoef2 = nRasterHCur / dHeight; + if (dKoef1 > dKoef2) + dKoef1 = dKoef2; + + nRasterWCur = (int)(dWidth * dKoef1 + 0.5); + nRasterHCur = (int)(dHeight * dKoef1 + 0.5); + } + else if (2 == nSaveType) + { + nRasterWCur = -1; + nRasterHCur = -1; + } + + pReader->ConvertToRaster(0, image_file_name, nRasterFormat, nRasterWCur, nRasterHCur); + } + } + + delete pReader; + return bResult; +} } diff --git a/OdfFile/Reader/Converter/mediaitems.h b/OdfFile/Reader/Converter/mediaitems.h index c3162ac5840..ac40bf2d6f7 100644 --- a/OdfFile/Reader/Converter/mediaitems.h +++ b/OdfFile/Reader/Converter/mediaitems.h @@ -83,11 +83,14 @@ class mediaitems size_t count_activeX; size_t count_control; + bool is_internal_path(const std::wstring& uri, const std::wstring& packetRoot); + void set_font_directory(std::wstring pathFonts); NSFonts::IApplicationFonts *applicationFonts() {return applicationFonts_;} std::wstring add_or_find(const std::wstring & href, _rels_type type, bool & isInternal, _rels_type_place type_place);//возможны ссылки на один и тот же объект std::wstring add_or_find(const std::wstring & href, _rels_type type, bool & isInternal, std::wstring & ref, _rels_type_place type_place); + std::wstring add_or_find_anim_audio(const std::wstring& href, bool& isInternal, std::wstring& ref); void add_rels(bool isInternal, std::wstring const & rid, std::wstring const & ref, _rels_type type, _rels_type_place type_place); std::wstring add_control_props (std::wstring & oox_target); @@ -103,6 +106,7 @@ class mediaitems case typeImage: return L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image"; case typeChart: return L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart"; case typeMsObject: return L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/package"; + case typePDF: case typeOleObject: return L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/oleObject"; case typeHyperlink: return L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink"; case typeMedia: return L"http://schemas.microsoft.com/office/2007/relationships/media"; @@ -143,6 +147,8 @@ class mediaitems return typeMedia; } + bool pdf2image(const std::wstring& pdf_file_name, const std::wstring& image_file_name); + private: std::wstring create_file_name (const std::wstring & uri, _rels_type type, bool & isInternal, size_t Num); std::wstring detectImageFileExtension (const std::wstring &fileName); diff --git a/OdfFile/Reader/Converter/oox_conversion_context.cpp b/OdfFile/Reader/Converter/oox_conversion_context.cpp index 9ec757fcee9..be80d22999f 100644 --- a/OdfFile/Reader/Converter/oox_conversion_context.cpp +++ b/OdfFile/Reader/Converter/oox_conversion_context.cpp @@ -261,23 +261,13 @@ math_context::math_context(odf_reader::fonts_container & fonts, bool graphic) : } void math_context::start() { + width = 0; + height = 0; + text_properties_ = odf_reader::style_text_properties_ptr(new odf_reader::style_text_properties()); text_properties_->content_.fo_font_family_ = base_font_name_.empty() ? L"Cambria Math" : base_font_name_; text_properties_->content_.fo_font_size_ = odf_types::length(base_font_size_, odf_types::length::pt); - - math_stream_ << L""; - - math_stream_ << L""; start_level(); } @@ -285,7 +275,6 @@ std::wstring math_context::end() { end_level(); - math_stream_ << L""; std::wstring math = math_stream_.str(); math_stream_.str( std::wstring() ); diff --git a/OdfFile/Reader/Converter/oox_conversion_context.h b/OdfFile/Reader/Converter/oox_conversion_context.h index d69c13cb2bd..95fd49a41f5 100644 --- a/OdfFile/Reader/Converter/oox_conversion_context.h +++ b/OdfFile/Reader/Converter/oox_conversion_context.h @@ -214,6 +214,9 @@ class styles_context : boost::noncopyable void start_level() { _state state; levels.push_back(state); } void end_level() { if (!levels.empty()) levels.pop_back(); } + + float width = 0; + float height = 0; private: std::wstringstream math_stream_; std::wstringstream math_style_stream_; diff --git a/OdfFile/Reader/Converter/oox_drawing.cpp b/OdfFile/Reader/Converter/oox_drawing.cpp index 677112f9ce6..56987f47626 100644 --- a/OdfFile/Reader/Converter/oox_drawing.cpp +++ b/OdfFile/Reader/Converter/oox_drawing.cpp @@ -75,18 +75,18 @@ namespace svg_path { CP_XML_NODE(val.command) { - if (val.command == L"a:ArcTo") + if (val.command == L"a:arcTo") { if (val.points.size() > 0) { CP_XML_ATTR(L"wR", val.points[0].x.get()); CP_XML_ATTR(L"hR", val.points[0].y.get()); } - //if (val.points.size() > 1) - //{ - // CP_XML_ATTR(L"stAng", (int)(val.points[1].x.get() * 60000)); - // CP_XML_ATTR(L"swAng", (int)(val.points[1].y.get() * 60000)); - //} + if (val.points.size() > 1) + { + CP_XML_ATTR(L"stAng", val.points[1].x.get()); + CP_XML_ATTR(L"swAng", val.points[1].y.get()); + } } else { @@ -198,6 +198,14 @@ static const std::wstring _ooxDashStyle[]= L"dash", L"dashDot", L"sysDashDotDot" + L"solid", + L"solid", + L"solid", + L"solid", + L"solid", + L"none", + L"dash", + L"solid" }; static const std::wstring _vmlDashStyle[]= { @@ -207,7 +215,15 @@ static const std::wstring _vmlDashStyle[]= L"dash", L"dash", L"dashdot", - L"shortdashdotdot" + L"shortdashdotdot", + L"solid", + L"solid", + L"solid", + L"solid", + L"solid", + L"none", + L"dash", + L"solid" }; void oox_serialize_effects(std::wostream & strm, const std::vector & prop) @@ -239,6 +255,7 @@ void oox_serialize_effects(std::wostream & strm, const std::vector= 0) && fill != ns + L":noFill") { int val = dStrokeWidth.get() * 12700; //in emu (1 pt = 12700) - if (val < 10) val = 12700; + if (val < 10) val = 0; CP_XML_ATTR2(ns_att + L"w", val); if (color.length()<1)color = L"729FCF"; @@ -578,21 +599,54 @@ void _oox_drawing::serialize_bodyPr(std::wostream & strm, const std::wstring & n CP_XML_NODE(namespace_ + L":bodyPr") { _CP_OPT(double)dPaddingLeft, dPaddingRight, dPaddingTop, dPaddingBottom; + _CP_OPT(int) numCol, spcCol; + _CP_OPT(bool) is_math_formula; + odf_reader::GetProperty(prop,L"text-padding-left" , dPaddingLeft); odf_reader::GetProperty(prop,L"text-padding-right" , dPaddingRight); odf_reader::GetProperty(prop,L"text-padding-top" , dPaddingTop); odf_reader::GetProperty(prop,L"text-padding-bottom" , dPaddingBottom); - if (dPaddingLeft) CP_XML_ATTR(L"lIns", (int)(*dPaddingLeft)); - if (dPaddingTop) CP_XML_ATTR(L"tIns", (int)(*dPaddingTop)); - if (dPaddingRight) CP_XML_ATTR(L"rIns", (int)(*dPaddingRight)); - if (dPaddingBottom) CP_XML_ATTR(L"bIns", (int)(*dPaddingBottom)); + odf_reader::GetProperty(prop, L"style_columns_count", numCol); + odf_reader::GetProperty(prop, L"style_columns_gap" , spcCol); + + odf_reader::GetProperty(prop, L"is-math-formula", is_math_formula); + + if (is_math_formula && *is_math_formula) + { + CP_XML_ATTR(L"lIns", 0); + CP_XML_ATTR(L"tIns", 0); + CP_XML_ATTR(L"rIns", 0); + CP_XML_ATTR(L"bIns", 0); + } + else + { + if (dPaddingLeft) CP_XML_ATTR(L"lIns", (int)(*dPaddingLeft)); + if (dPaddingTop) CP_XML_ATTR(L"tIns", (int)(*dPaddingTop)); + if (dPaddingRight) CP_XML_ATTR(L"rIns", (int)(*dPaddingRight)); + if (dPaddingBottom) CP_XML_ATTR(L"bIns", (int)(*dPaddingBottom)); + } + + CP_XML_ATTR_OPT(L"numCol" , numCol); + CP_XML_ATTR_OPT(L"spcCol" , spcCol); if (inGroup == false) { - _CP_OPT(int) iWrap; - odf_reader::GetProperty(prop, L"text-wrap" , iWrap); - if ((iWrap) && (*iWrap == 0)) CP_XML_ATTR(L"wrap", L"none"); + _CP_OPT(bool) bAutoGrowWidth; + odf_reader::GetProperty(prop, L"auto-grow-width", bAutoGrowWidth); + if (bAutoGrowWidth) + { + if (*bAutoGrowWidth == true) + CP_XML_ATTR(L"wrap", L"none"); + } + else + { + _CP_OPT(int) iWrap; + odf_reader::GetProperty(prop, L"text-wrap", iWrap); + + if (((iWrap) && (*iWrap == 0)) || ((is_math_formula) && (*is_math_formula))) + CP_XML_ATTR(L"wrap", L"none"); + } } _CP_OPT(int) iAlign, iVert; @@ -702,7 +756,7 @@ void _oox_drawing::serialize_shape(std::wostream & strm) CP_XML_WRITER(strm) { - if (sub_type == 6 || sub_type == 8 || sub_type == 14) + if ((sub_type == 6 || sub_type == 8 || sub_type == 14) && !connector) { CP_XML_NODE(L"a:custGeom") { @@ -758,9 +812,15 @@ void _oox_drawing::serialize_shape(std::wostream & strm) { if (shapeGeomPreset.empty()) { - shapeGeomPreset = L"rect"; - sub_type = 2; + shapeGeomPreset = L"rect"; + sub_type = 2; } + + if (connector) + { + shapeGeomPreset = connector_prst; + } + CP_XML_NODE(L"a:prstGeom")//автофигура { CP_XML_ATTR(L"prst", shapeGeomPreset); diff --git a/OdfFile/Reader/Converter/oox_drawing.h b/OdfFile/Reader/Converter/oox_drawing.h index bf7af994513..7c780face48 100644 --- a/OdfFile/Reader/Converter/oox_drawing.h +++ b/OdfFile/Reader/Converter/oox_drawing.h @@ -100,9 +100,15 @@ namespace oox bool inGroup; size_t id; bool lined; - bool connector; bool hidden; + bool connector; + std::wstring start_connection_shape_id; + std::wstring end_connection_shape_id; + size_t start_connection_index; + size_t end_connection_index; + std::wstring connector_prst; + std::wstring name; int sub_type; //odf diff --git a/OdfFile/Reader/Converter/oox_drawing_fills.cpp b/OdfFile/Reader/Converter/oox_drawing_fills.cpp index d449f471882..37729857f45 100644 --- a/OdfFile/Reader/Converter/oox_drawing_fills.cpp +++ b/OdfFile/Reader/Converter/oox_drawing_fills.cpp @@ -183,11 +183,12 @@ void oox_serialize_bitmap_fill(std::wostream & strm, const _oox_fill & val, cons else CP_XML_ATTR(L"r:link", val.bitmap->rId ); - if (val.opacity) + _CP_OPT(double) opacity = val.image_opacity ? val.image_opacity : val.opacity; + if (opacity) { CP_XML_NODE(ns + L":alphaModFix") { - CP_XML_ATTR2(ns_att + L"amt", (int)(*val.opacity * 1000)); + CP_XML_ATTR2(ns_att + L"amt", (int)(*opacity * 1000)); } } if (val.bitmap->bGrayscale) diff --git a/OdfFile/Reader/Converter/oox_drawing_fills.h b/OdfFile/Reader/Converter/oox_drawing_fills.h index e86cbe42a64..daae7a8dd04 100644 --- a/OdfFile/Reader/Converter/oox_drawing_fills.h +++ b/OdfFile/Reader/Converter/oox_drawing_fills.h @@ -129,11 +129,13 @@ namespace oox { oox_solid_fill_ptr solid; _CP_OPT(double) opacity; + _CP_OPT(double) image_opacity; void clear() { type = -1; opacity = boost::none; + image_opacity = boost::none; gradient.reset(); hatch.reset(); diff --git a/OdfFile/Reader/Converter/oox_package.cpp b/OdfFile/Reader/Converter/oox_package.cpp index ba25f31aa40..0bf7688fe46 100644 --- a/OdfFile/Reader/Converter/oox_package.cpp +++ b/OdfFile/Reader/Converter/oox_package.cpp @@ -40,8 +40,11 @@ #include "../../../DesktopEditor/common/File.h" #include "../../../DesktopEditor/common/SystemUtils.h" #include "../../../DesktopEditor/graphics/pro/Image.h" +#include "../../../DesktopEditor/raster/Metafile/MetaFileCommon.h" #include "../../../DesktopEditor/raster/ImageFileFormatChecker.h" #include "../../../OOXML/Base/Base.h" +#include "../../../Common/cfcpp/compoundfile.h" +#include "../../../Common/3dParty/pole/pole.h" namespace cpdoccore { namespace oox { @@ -52,12 +55,10 @@ static void ConvertSvmToImage(std::wstring &file_svm, std::wstring &file_png, NS MetaFile::IMetaFile* pMetaFile = MetaFile::Create(pAppFonts); if (pMetaFile->LoadFromFile(file_svm.c_str())) - { - double w, h, x, y; - pMetaFile->GetBounds(&x, &y, &w, &h); - pMetaFile->ConvertToRaster(file_png.c_str(), 4, w); + { + MetaFile::ConvertToRasterMaxSize(pMetaFile, file_png.c_str(), _CXIMAGE_FORMAT_PNG, 1000); pMetaFile->Close(); - } + } RELEASEOBJECT(pMetaFile); } @@ -134,6 +135,8 @@ content_type * content_types_file::content() bool content_types_file::add_or_find_default(const std::wstring & extension) { + if (extension.empty()) return true; + std::vector & defaults = content_type_content_.get_default(); for (size_t i = 0 ; i < defaults.size(); i++) @@ -314,7 +317,6 @@ simple_element_ptr simple_element::create(const std::wstring & FileName, const s //----------------------------------------------------------------------------------------------- docProps_files::docProps_files() { - } std::wstring docProps_files::create_core() { @@ -358,6 +360,10 @@ void docProps_files::set_core(element_ptr Element) { core_ = Element; } +void docProps_files::set_custom(element_ptr Element) +{ + custom_ = Element; +} void docProps_files::write(const std::wstring & RootPath) { std::wstring path = RootPath + FILE_SEPARATOR_STR + L"docProps"; @@ -368,6 +374,8 @@ void docProps_files::write(const std::wstring & RootPath) core_->write(path); app_->write(path); + + if (custom_) custom_->write(path); } //--------------------------------------------------------------------------------------------------- media::media(mediaitems_ptr & _mediaitems, NSFonts::IApplicationFonts *pAppFonts) : mediaItems_(_mediaitems), appFonts_(pAppFonts) @@ -382,10 +390,10 @@ void media::write(const std::wstring & RootPath) for (size_t i = 0; i < items.size(); i++ ) { - if (items[i].mediaInternal && items[i].valid && ( items[i].type == typeImage || - items[i].type == typeMedia || - items[i].type == typeAudio || - items[i].type == typeVideo )) + if (items[i].valid && ( items[i].type == typeImage || + items[i].type == typeMedia || + items[i].type == typeAudio || + items[i].type == typeVideo )) { std::wstring &file_name = items[i].href; std::wstring file_name_out = RootPath + FILE_SEPARATOR_STR + items[i].outputName; @@ -427,17 +435,151 @@ void embeddings::write(const std::wstring & RootPath) for (size_t i = 0; i < items.size(); i++ ) { - if ( items[i].mediaInternal && items[i].valid && - (items[i].type == typeMsObject || items[i].type == typeOleObject)) - { - int pos = items[i].outputName.rfind(L"."); + if (items[i].valid && (items[i].type == typeMsObject || + items[i].type == typeOleObject || + items[i].type == typeActiveX || + items[i].type == typePDF || + items[i].type == typePDF || + items[i].type == typeControlProps || + items[i].type == typeControl)) + { + + int pos = items[i].outputName.rfind(L"."); std::wstring extension = pos >= 0 ? items[i].outputName.substr(pos + 1) : L""; - + content_types.add_or_find_default(extension); std::wstring file_name_out = RootPath + FILE_SEPARATOR_STR + items[i].outputName; - - NSFile::CFileBinary::Copy(items[i].href, file_name_out); + + if (items[i].mediaInternal && items[i].valid && + (items[i].type == typeMsObject || items[i].type == typeOleObject)) + { + NSFile::CFileBinary::Copy(items[i].href, file_name_out); + } + else if (items[i].type == typePDF) + { + std::string name = "Acrobat Document"; + std::string class_name = "Acrobat.Document.DC"; + + _UINT32 name_size = name.size() + 1; + _UINT32 class_name_size = class_name.size() + 1; + + DWORD nativeDataSize = 0; + BYTE* nativeData = NULL; + + NSFile::CFileBinary file; + file.ReadAllBytes(items[i].href, &nativeData, nativeDataSize); + + CFCPP::CompoundFile* storageOut = new CFCPP::CompoundFile(CFCPP::Ver_3, CFCPP::Default); + if (storageOut && nativeData) + { + _UINT32 tmp = 0; + //CompObj + BYTE dataCompObjHeader[28] = { 0x01, 0x00, 0xfe, 0xff, 0x03, 0x0a, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, + 0x65, 0xca, 0x01, 0xb8, 0xfc, 0xa1, 0xd0, 0x11, 0x85, 0xad, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00 }; + + std::shared_ptr oStreamCompObj = storageOut->RootStorage()->AddStream(L"\001CompObj"); + long long posStreamCompObj = 0; + oStreamCompObj->Write((char*)dataCompObjHeader, 0, 28); posStreamCompObj += 28; + + oStreamCompObj->Write((char*)&name_size, posStreamCompObj, 4); posStreamCompObj += 4; + oStreamCompObj->Write((char*)name.c_str(), posStreamCompObj, name_size); posStreamCompObj += name_size; + + tmp = 0; + oStreamCompObj->Write((char*)&tmp, posStreamCompObj, 4); posStreamCompObj += 4; + + oStreamCompObj->Write((char*)&class_name_size, posStreamCompObj, 4); posStreamCompObj += 4; + oStreamCompObj->Write((char*)class_name.c_str(), posStreamCompObj, class_name_size); posStreamCompObj += class_name_size; + + tmp = 0x71B239F4; + oStreamCompObj->Write((char*)&tmp, posStreamCompObj, 4); posStreamCompObj += 4;// UnicodeMarker + + tmp = 0; + oStreamCompObj->Write((char*)&tmp, posStreamCompObj, 4); posStreamCompObj += 4;// UnicodeUserType + oStreamCompObj->Write((char*)&tmp, posStreamCompObj, 4); posStreamCompObj += 4;// UnicodeClipboardFormat + oStreamCompObj->Write((char*)&tmp, posStreamCompObj, 4); posStreamCompObj += 4;// + + //Ole + BYTE dataOleInfo[] = { 0x01, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; + + std::shared_ptr oStreamOle = storageOut->RootStorage()->AddStream(L"\001Ole"); + oStreamOle->Write((char*)dataOleInfo, 0, 20); + + //ObjInfo + std::shared_ptr oStreamObjInfo = storageOut->RootStorage()->AddStream(L"\003ObjInfo"); + + BYTE dataObjInfo[] = { 0x00, 0x00, 0x03, 0x00, 0x01, 0x00 }; + oStreamObjInfo->Write((char*)dataObjInfo, 0, 6); + + //CONTENTS + std::shared_ptr oStreamCONTENTS = storageOut->RootStorage()->AddStream(L"CONTENTS"); + oStreamCONTENTS->Write((char*)nativeData, 0, nativeDataSize); + + bool result = storageOut->Save(file_name_out); + storageOut->Close(); + + } + if (storageOut) delete storageOut; + + //POLE::Storage* storageOut = new POLE::Storage(file_name_out.c_str()); + //if ((storageOut) && (storageOut->open(true, true))) + //{ + // _UINT32 tmp = 0; + // std::string name = class_name; + // _UINT32 name_size = (_UINT32)name.length() + 1; + ////Ole + // BYTE dataOleInfo[] = { 0x01, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; + // POLE::Stream oStream3(storageOut, L"\001Ole", true, 20); + // oStream3.write(dataOleInfo, 20); + // oStream3.flush(); + ////CompObj + // BYTE dataCompObjHeader[28] = { 0x01, 0x00, 0xfe, 0xff, 0x03, 0x0a, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, + // 0x65, 0xca, 0x01, 0xb8, 0xfc, 0xa1, 0xd0, 0x11, 0x85, 0xad, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00 }; + + // POLE::Stream oStream1(storageOut, L"\001CompObj", true, 28 + (class_name_size + 4) + (class_name2_size + 4) + 4 * 4); + // oStream1.write(dataCompObjHeader, 28); + + // oStream1.write((BYTE*)&class_name_size, 4); + // oStream1.write((BYTE*)class_name.c_str(), class_name_size); + + // tmp = 0; + // oStream1.write((BYTE*)&tmp, 4); + + // oStream1.write((BYTE*)&class_name2_size, 4); + // oStream1.write((BYTE*)class_name2.c_str(), class_name2_size); + + // tmp = 0x71B239F4; + // oStream1.write((BYTE*)&tmp, 4); // UnicodeMarker + + // tmp = 0; + // oStream1.write((BYTE*)&tmp, 4); // UnicodeUserType + // oStream1.write((BYTE*)&tmp, 4); // UnicodeClipboardFormat + // oStream1.write((BYTE*)&tmp, 4); // + // oStream1.flush(); + + // //ObjInfo + // BYTE dataObjInfo[] = { 0x00,0x00,0x03,0x00,0x0D,0x00 }; + // POLE::Stream oStream2(storageOut, L"\003ObjInfo", true, 6); + // oStream2.write(dataObjInfo, 6); + // oStream2.flush(); + + // POLE::Stream streamData(storageOut, L"CONTENTS", true, nativeDataSize); + // _UINT32 sz_write = 0; + // _UINT32 sz = 4096; + // while (sz_write < nativeDataSize) + // { + // if (sz_write + sz > nativeDataSize) + // sz = nativeDataSize - sz_write; + // streamData.write(nativeData + sz_write, sz); + // sz_write += sz; + // } + // streamData.flush(); + + // storageOut->close(); + // delete storageOut; + //} + if (nativeData) delete[]nativeData; + } } } } diff --git a/OdfFile/Reader/Converter/oox_package.h b/OdfFile/Reader/Converter/oox_package.h index 314537181ab..38169628f68 100644 --- a/OdfFile/Reader/Converter/oox_package.h +++ b/OdfFile/Reader/Converter/oox_package.h @@ -203,6 +203,7 @@ class docProps_files : public element void set_app(element_ptr Element); void set_core(element_ptr Element); + void set_custom(element_ptr Element); virtual void write(const std::wstring & RootPath); @@ -212,6 +213,7 @@ class docProps_files : public element element_ptr core_; element_ptr app_; + element_ptr custom_; }; class document : public element { diff --git a/OdfFile/Reader/Converter/oox_plot_area.cpp b/OdfFile/Reader/Converter/oox_plot_area.cpp index 8abc6d61b0a..1c699d53d63 100644 --- a/OdfFile/Reader/Converter/oox_plot_area.cpp +++ b/OdfFile/Reader/Converter/oox_plot_area.cpp @@ -102,7 +102,7 @@ namespace cpdoccore { charts_.push_back(chart); } - void oox_plot_area::add_axis(int type, odf_reader::chart::axis & content) + void oox_plot_area::add_axis(int type, odf_reader::chart::axis& content) { unsigned int id = axis_id_++; oox_axis_content_ptr ax = oox_axis_content::create(type, id); @@ -114,7 +114,7 @@ namespace cpdoccore { { no_used_local_tables_ = val; } - void oox_plot_area::set_data_table(odf_reader::chart::simple & content) + void oox_plot_area::set_data_table(odf_reader::chart::simple& content) { data_table_content_ = content; } @@ -142,12 +142,14 @@ namespace cpdoccore { } } } - void oox_plot_area::oox_serialize_view3D(std::wostream & _Wostream) + void oox_plot_area::oox_serialize_view3D(std::wostream& _Wostream) { _CP_OPT(std::wstring) strVal; _CP_OPT(double) doubleVal; + _CP_OPT(bool) perspective; odf_reader::GetProperty(properties_, L"transform", strVal); + odf_reader::GetProperty(properties_, L"perspective", perspective); if (!strVal) return; @@ -202,13 +204,20 @@ namespace cpdoccore { theta_z /= DEG2RAD; + if (this->current_chart_->type_ == CHART_TYPE_RADAR || + this->current_chart_->type_ == CHART_TYPE_PIE || + this->current_chart_->type_ == CHART_TYPE_DOUGHNUT) + { + theta_x += 90; + } + else theta_x = (std::abs)(theta_x); CP_XML_WRITER(_Wostream) { CP_XML_NODE(L"c:view3D") { CP_XML_NODE(L"c:rotX") { - CP_XML_ATTR(L"val", (int)(theta_x + 90.5)); + CP_XML_ATTR(L"val", (int)(theta_x + 0.5)); } CP_XML_NODE(L"c:rotY") { @@ -218,25 +227,27 @@ namespace cpdoccore { { CP_XML_ATTR(L"val", 100); } - if (theta_z == 0) + if (theta_z > 0 || (perspective && *perspective)) { CP_XML_NODE(L"c:rAngAx") { - CP_XML_ATTR(L"val", 1); + CP_XML_ATTR(L"val", 0); + } + if (theta_z > 0) + { + CP_XML_NODE(L"c:perspective") + { + CP_XML_ATTR(L"val", (int)(theta_z * 2 + 0.5)); + } } } else { CP_XML_NODE(L"c:rAngAx") { - CP_XML_ATTR(L"val", 0); - } - CP_XML_NODE(L"c:perspective") - { - CP_XML_ATTR(L"val", (int)(theta_z * 2 + 0.5)); + CP_XML_ATTR(L"val", 1); } } - } } } diff --git a/OdfFile/Reader/Converter/oox_rels.cpp b/OdfFile/Reader/Converter/oox_rels.cpp index f51ca1710dc..d6fca2e5c46 100644 --- a/OdfFile/Reader/Converter/oox_rels.cpp +++ b/OdfFile/Reader/Converter/oox_rels.cpp @@ -52,7 +52,7 @@ std::wostream & relationship::xml_to_stream(std::wostream & _Wostream) const CP_XML_ATTR(L"Type", type()); CP_XML_ATTR(L"Target", target()); - if (!target_mode().empty()) + if (!target_mode().empty() && type() != L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/slide") CP_XML_ATTR(L"TargetMode", target_mode()); } } diff --git a/OdfFile/Reader/Converter/oox_rels.h b/OdfFile/Reader/Converter/oox_rels.h index be4c1c49037..7ed7f656502 100644 --- a/OdfFile/Reader/Converter/oox_rels.h +++ b/OdfFile/Reader/Converter/oox_rels.h @@ -61,7 +61,8 @@ enum _rels_type typeActiveX, typeControl, typeControlProps, - typeChartUserShapes + typeChartUserShapes, + typePDF }; enum _rels_type_place { diff --git a/OdfFile/Reader/Converter/pptx_animation_context.cpp b/OdfFile/Reader/Converter/pptx_animation_context.cpp new file mode 100644 index 00000000000..246724f8e89 --- /dev/null +++ b/OdfFile/Reader/Converter/pptx_animation_context.cpp @@ -0,0 +1,1381 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ + +#include "pptx_animation_context.h" + +#include +#include + +#include "../../DataTypes/clockvalue.h" + +#define SET_PAR_ANIMATION_ATTRIBUTE(attribute, value) \ + if(impl_->par_animation_levels_.size()) \ + { \ + Impl::_par_animation_ptr& back = impl_->par_animation_levels_.back(); \ + back->attribute = value; \ + } + +#define SET_SEQ_ANIMATION_ATTRIBUTE(attribute, value) \ + if (impl_->par_animation_levels_.size()) \ + { \ + Impl::_par_animation_ptr& back = impl_->par_animation_levels_.back(); \ + if (back->AnimSeq.size()) \ + back->AnimSeq.back()->attribute = value; \ + } + +#define END_BEHAVIOUR_ELEMENT(element_description) \ + if (impl_->par_animation_levels_.size()) \ + { \ + Impl::_par_animation_ptr& back = impl_->par_animation_levels_.back(); \ + if(impl_->element_description->ShapeID && \ + *impl_->element_description->ShapeID != 0) \ + back->AnimationActionArray.push_back(impl_->element_description); \ + } \ + impl_->element_description = nullptr + + +namespace cpdoccore { +namespace oox { + + pptx_animation_context::Impl::Impl() + { + clear(); + } + + void pptx_animation_context::Impl::clear() + { + par_animation_levels_.clear(); + root_animation_element_ = nullptr; + animate_motion_description_ = nullptr; + set_description_ = nullptr; + anim_effect_description_ = nullptr; + anim_description_ = nullptr; + anim_clr_description_ = nullptr; + anim_scale_description_ = nullptr; + anim_rotate_description_ = nullptr; + audio_description_ = nullptr; + } + + pptx_animation_context::pptx_animation_context() + : impl_(new pptx_animation_context::Impl()) + { + + } + + void pptx_animation_context::start_par_animation() + { + if (!impl_->root_animation_element_) + { + impl_->root_animation_element_ = boost::make_shared(); + impl_->par_animation_levels_.push_back(impl_->root_animation_element_); + } + else + { + impl_->par_animation_levels_.push_back(boost::make_shared()); + } + } + + void pptx_animation_context::set_par_animation_presentation_node_type(const std::wstring& value) + { + SET_PAR_ANIMATION_ATTRIBUTE(NodeType, value); + } + + void pptx_animation_context::set_par_animation_direction(const std::wstring& value) + { + SET_PAR_ANIMATION_ATTRIBUTE(Direction, value); + } + + void pptx_animation_context::set_par_animation_restart(const std::wstring& value) + { + SET_PAR_ANIMATION_ATTRIBUTE(Restart, value); + } + + void pptx_animation_context::set_par_animation_duration(int value) + { + SET_PAR_ANIMATION_ATTRIBUTE(Duration, value); + } + + void pptx_animation_context::set_par_animation_delay(const std::wstring& value) + { + SET_PAR_ANIMATION_ATTRIBUTE(Delay, value); + } + + void pptx_animation_context::set_par_animation_end(const std::wstring& value) + { + SET_PAR_ANIMATION_ATTRIBUTE(End, value); + } + + void pptx_animation_context::set_par_animation_preset_class(const std::wstring& value) + { + SET_PAR_ANIMATION_ATTRIBUTE(PresetClass, value); + } + + void pptx_animation_context::set_par_animation_preset_id(int value) + { + SET_PAR_ANIMATION_ATTRIBUTE(PresetID, value); + } + + void pptx_animation_context::set_par_animation_preset_subtype(int value) + { + SET_PAR_ANIMATION_ATTRIBUTE(PresetSubtype, value); + } + + void pptx_animation_context::set_par_animation_fill(const std::wstring& value) + { + SET_PAR_ANIMATION_ATTRIBUTE(Fill, value); + } + + void pptx_animation_context::set_par_animation_accelerate(int value) + { + SET_PAR_ANIMATION_ATTRIBUTE(Accelerate, value); + } + + void pptx_animation_context::set_par_animation_decelerate(int value) + { + SET_PAR_ANIMATION_ATTRIBUTE(Decelerate, value); + } + + void pptx_animation_context::end_par_animation() + { + if (impl_->par_animation_levels_.size()) + { + Impl::_par_animation_ptr end = impl_->par_animation_levels_.back(); + impl_->par_animation_levels_.pop_back(); + if (!impl_->par_animation_levels_.size()) + return; + + if (!end->AnimationActionArray.size() && + !end->AnimParArray.size() && + !end->AnimSeq.size()) + return; + + Impl::_par_animation_ptr back = impl_->par_animation_levels_.back(); + + if (back->AnimSeq.size()) + back->AnimSeq.back()->AnimParArray.push_back(end); + else + back->AnimParArray.push_back(end); + } + } + + ////////////////////////////////////////////////////////////////////////// + // p:seq + void pptx_animation_context::start_seq_animation() + { + if (impl_->par_animation_levels_.size()) + { + impl_->par_animation_levels_.back()->AnimSeq.push_back(boost::make_shared()); + } + } + + void pptx_animation_context::set_seq_animation_presentation_node_type(const std::wstring& value) + { + SET_SEQ_ANIMATION_ATTRIBUTE(PresentationNodeType, value); + } + + void pptx_animation_context::set_seq_animation_direction(const std::wstring& value) + { + SET_SEQ_ANIMATION_ATTRIBUTE(Direction, value); + } + + void pptx_animation_context::set_seq_animation_restart(const std::wstring& value) + { + SET_SEQ_ANIMATION_ATTRIBUTE(Restart, value); + } + + void pptx_animation_context::set_seq_animation_dur(int value) + { + SET_SEQ_ANIMATION_ATTRIBUTE(Duration, value); + } + + void pptx_animation_context::set_seq_animation_delay(const std::wstring& value) + { + SET_SEQ_ANIMATION_ATTRIBUTE(Delay, value); + } + + void pptx_animation_context::set_seq_animation_end(const std::wstring& value) + { + SET_SEQ_ANIMATION_ATTRIBUTE(End, value); + } + + void pptx_animation_context::set_seq_animation_target_element(const std::wstring& value) + { + SET_SEQ_ANIMATION_ATTRIBUTE(TargetEl, value); + } + + void pptx_animation_context::end_seq_animation() + { + } + + ////////////////////////////////////////////////////////////////////////// + // p:set + void pptx_animation_context::start_set() + { + impl_->set_description_ = boost::make_shared(); + } + + void pptx_animation_context::set_set_direction(const std::wstring& value) + { + impl_->set_description_->Direction = value; + } + + + void pptx_animation_context::set_set_restart(const std::wstring& value) + { + impl_->set_description_->Restart = value; + } + + void pptx_animation_context::set_set_duration(int value) + { + impl_->set_description_->Duration = value; + } + + void pptx_animation_context::set_set_delay(const std::wstring& value) + { + impl_->set_description_->Delay = value; + } + + void pptx_animation_context::set_set_end(const std::wstring& value) + { + impl_->set_description_->End = value; + } + + void pptx_animation_context::set_set_auto_rev(const std::wstring& value) + { + impl_->set_description_->AutoRev = value; + } + + void pptx_animation_context::set_set_fill(const std::wstring& value) + { + impl_->set_description_->Fill = value; + } + + void pptx_animation_context::set_set_shape_id(size_t value) + { + impl_->set_description_->ShapeID = value; + } + + void pptx_animation_context::set_set_attribute_name(const std::wstring& value) + { + impl_->set_description_->AttributeName = value; + } + + void pptx_animation_context::set_set_to_value(const std::wstring& value) + { + impl_->set_description_->ToValue = value; + } + + void pptx_animation_context::end_set() + { + END_BEHAVIOUR_ELEMENT(set_description_); + } + + ////////////////////////////////////////////////////////////////////////// + // p:animEffect + void pptx_animation_context::start_anim_effect() + { + impl_->anim_effect_description_ = boost::make_shared(); + } + + void pptx_animation_context::set_anim_effect_filter(const std::wstring& value) + { + impl_->anim_effect_description_->Filter = value; + } + + void pptx_animation_context::set_anim_effect_transition(const std::wstring& value) + { + impl_->anim_effect_description_->Transition = value; + } + + void pptx_animation_context::set_anim_effect_duration(int value) + { + impl_->anim_effect_description_->Duration = value; + } + + void pptx_animation_context::set_anim_effect_delay(const std::wstring& value) + { + impl_->anim_effect_description_->Delay = value; + } + + void pptx_animation_context::set_anim_effect_accel(int value) + { + impl_->anim_effect_description_->Accel = value; + } + + void pptx_animation_context::set_anim_effect_decel(int value) + { + impl_->anim_effect_description_->Decel = value; + } + + void pptx_animation_context::set_anim_effect_shape_id(size_t value) + { + impl_->anim_effect_description_->ShapeID = value; + } + + void pptx_animation_context::end_anim_effect() + { + + END_BEHAVIOUR_ELEMENT(anim_effect_description_); + } + + ////////////////////////////////////////////////////////////////////////// + // p:animMotion + void pptx_animation_context::start_animate_motion() + { + impl_->animate_motion_description_ = boost::make_shared(); + } + + void pptx_animation_context::set_animate_motion_presentation_node_type(const std::wstring& value) + { + impl_->animate_motion_description_->PresentationNodeType = value; + } + + void pptx_animation_context::set_animate_motion_direction(const std::wstring& value) + { + impl_->animate_motion_description_->SmilDirection = value; + } + + void pptx_animation_context::set_animate_motion_restart(const std::wstring& value) + { + impl_->animate_motion_description_->SmilRestart = value; + } + + void pptx_animation_context::set_animate_motion_dur(int value) + { + impl_->animate_motion_description_->SmilDurMs = value; + } + + void pptx_animation_context::set_animate_motion_delay(const std::wstring& value) + { + impl_->animate_motion_description_->SmilBegin = value; + } + + void pptx_animation_context::set_animate_motion_end(const std::wstring& value) + { + impl_->animate_motion_description_->SmilEnd = value; + } + + void pptx_animation_context::set_animate_motion_fill(const std::wstring& value) + { + impl_->animate_motion_description_->SmilFill = value; + } + + void pptx_animation_context::set_animate_motion_shape_id(size_t value) + { + impl_->animate_motion_description_->ShapeID = value; + } + + void pptx_animation_context::set_animate_motion_svg_path(const std::wstring& value) + { + impl_->animate_motion_description_->SvgPath = value; + } + + void pptx_animation_context::end_animate_motion() + { + END_BEHAVIOUR_ELEMENT(animate_motion_description_); + } + + ////////////////////////////////////////////////////////////////////////// + // p:anim + void pptx_animation_context::start_animate() + { + impl_->anim_description_ = boost::make_shared(); + impl_->anim_description_->KeypointArray = std::vector(); + } + + void pptx_animation_context::set_animate_calc_mode(const std::wstring& value) + { + impl_->anim_description_->CalcMode = value; + } + + void pptx_animation_context::set_animate_value_type(const std::wstring& value) + { + impl_->anim_description_->ValueType = value; + } + + void pptx_animation_context::set_animate_shape_id(size_t value) + { + impl_->anim_description_->ShapeID = value; + } + + void pptx_animation_context::set_animate_duration(int value) + { + impl_->anim_description_->Duration = value; + } + + void pptx_animation_context::set_animate_attribute_name(const std::wstring& value) + { + impl_->anim_description_->AttributeName = value; + } + + void pptx_animation_context::set_animate_from(const std::wstring& value) + { + impl_->anim_description_->From = value; + } + + void pptx_animation_context::set_animate_to(const std::wstring& value) + { + impl_->anim_description_->To = value; + } + + void pptx_animation_context::set_animate_by(const std::wstring& value) + { + impl_->anim_description_->By = value; + } + + void pptx_animation_context::set_animate_additive(const std::wstring& value) + { + impl_->anim_description_->Additive = value; + } + + void pptx_animation_context::set_animate_auto_reverse(bool value) + { + impl_->anim_description_->AutoReverse = value; + } + + void pptx_animation_context::set_animate_delay(const std::wstring& value) + { + impl_->anim_description_->Delay = value; + } + + void pptx_animation_context::add_animate_keypoint(int time, const std::wstring& value, _CP_OPT(std::wstring) formula) + { + impl_->anim_description_->KeypointArray->push_back(Impl::_anim::_keypoint(time, value, formula)); + } + + void pptx_animation_context::end_animate() + { + END_BEHAVIOUR_ELEMENT(anim_description_); + } + + ////////////////////////////////////////////////////////////////////////// + // p:animClr + void pptx_animation_context::start_animate_color() + { + impl_->anim_clr_description_ = boost::make_shared(); + } + + void pptx_animation_context::set_animate_color_color_space(const std::wstring& value) + { + impl_->anim_clr_description_->ColorSpace = value; + } + + void pptx_animation_context::set_animate_color_dir(const std::wstring& value) + { + impl_->anim_clr_description_->Direction = value; + } + + void pptx_animation_context::set_animate_color_duration(int value) + { + impl_->anim_clr_description_->Duration = value; + } + + void pptx_animation_context::set_animate_color_delay(const std::wstring& value) + { + impl_->anim_clr_description_->Delay = value; + } + + void pptx_animation_context::set_animate_color_fill(const std::wstring& value) + { + impl_->anim_clr_description_->Fill = value; + } + + void pptx_animation_context::set_animate_color_auto_rev(bool value) + { + impl_->anim_clr_description_->AutoRev = value; + } + + void pptx_animation_context::set_animate_color_attribute_name(const std::wstring& value) + { + impl_->anim_clr_description_->AttributeName = value; + } + + void pptx_animation_context::set_animate_color_to_value(const std::wstring& value) + { + impl_->anim_clr_description_->ToValue = value; + } + + void pptx_animation_context::set_animate_color_by_value(const std::wstring& value) + { + impl_->anim_clr_description_->ByValue = pptx_animation_context::Impl::_anim_clr::color(); + + if (boost::algorithm::starts_with(value, L"#")) + { + if (value.size() != std::wstring(L"#rrggbb").size()) + return; + + const std::wstring str = value.substr(1); // Remove # character + + int r = 0; + int g = 0; + int b = 0; + + std::wistringstream(str.substr(0, 2)) >> std::hex >> r; + std::wistringstream(str.substr(2, 2)) >> std::hex >> g; + std::wistringstream(str.substr(4, 2)) >> std::hex >> b; + + impl_->anim_clr_description_->ByValue->type_ = pptx_animation_context::Impl::_anim_clr::color::rgb; + impl_->anim_clr_description_->ByValue->v1 = r; + impl_->anim_clr_description_->ByValue->v2 = g; + impl_->anim_clr_description_->ByValue->v3 = b; + } + else if (boost::algorithm::starts_with(value, L"hsl")) + { + std::wstring str = value; + boost::algorithm::erase_all(str, L"hsl"); + boost::algorithm::erase_all(str, L"("); + boost::algorithm::erase_all(str, L")"); + boost::algorithm::erase_all(str, L"%"); + std::vector arr; + boost::algorithm::split(arr, str, boost::is_any_of(",")); + + int h = 0; + int s = 0; + int l = 0; + + std::wistringstream(arr[0]) >> h; + std::wistringstream(arr[1]) >> s; + std::wistringstream(arr[2]) >> l; + + impl_->anim_clr_description_->ByValue->type_ = pptx_animation_context::Impl::_anim_clr::color::hsl; + impl_->anim_clr_description_->ByValue->v1 = h * 60000; + impl_->anim_clr_description_->ByValue->v2 = s * 1000; + impl_->anim_clr_description_->ByValue->v3 = l * 1000; + } + } + + void pptx_animation_context::set_animate_color_shape_id(size_t value) + { + impl_->anim_clr_description_->ShapeID = value; + } + + void pptx_animation_context::end_animate_color() + { + END_BEHAVIOUR_ELEMENT(anim_clr_description_); + } + + ////////////////////////////////////////////////////////////////////////// + // p:animScale + void pptx_animation_context::start_animate_scale() + { + impl_->anim_scale_description_ = boost::make_shared(); + } + + void pptx_animation_context::set_animate_scale_shape_id(size_t value) + { + impl_->anim_scale_description_->ShapeID = value; + } + + void pptx_animation_context::set_animate_scale_duration(int value) + { + impl_->anim_scale_description_->Duration = value; + } + + void pptx_animation_context::set_animate_scale_fill(const std::wstring& value) + { + impl_->anim_scale_description_->Fill = value; + } + + void pptx_animation_context::set_animate_scale_from(int x, int y) + { + impl_->anim_scale_description_->From = Impl::_anim_scale::vec2(x, y); + } + + void pptx_animation_context::set_animate_scale_to(int x, int y) + { + impl_->anim_scale_description_->To = Impl::_anim_scale::vec2(x, y); + } + + void pptx_animation_context::set_animate_scale_by(int x, int y) + { + impl_->anim_scale_description_->By = Impl::_anim_scale::vec2(x, y); + } + + void pptx_animation_context::set_animate_scale_delay(const std::wstring& value) + { + impl_->anim_scale_description_->Delay = value; + } + + void pptx_animation_context::set_animate_scale_attribute_name(const std::wstring& value) + { + impl_->anim_scale_description_->AttributeName = value; + } + + void pptx_animation_context::set_animate_scale_auto_reverse(bool value) + { + impl_->anim_scale_description_->AutoReverse = value; + } + + void pptx_animation_context::end_animate_scale() + { + END_BEHAVIOUR_ELEMENT(anim_scale_description_); + } + + ////////////////////////////////////////////////////////////////////////// + // p:animRot + void pptx_animation_context::start_animate_rotate() + { + impl_->anim_rotate_description_ = boost::make_shared(); + } + + void pptx_animation_context::set_animate_rotate_shape_id(size_t value) + { + impl_->anim_rotate_description_->ShapeID = value; + } + + void pptx_animation_context::set_animate_rotate_duration(int value) + { + impl_->anim_rotate_description_->Duration = value; + } + + void pptx_animation_context::set_animate_rotate_fill(const std::wstring& value) + { + impl_->anim_rotate_description_->Fill = value; + } + + void pptx_animation_context::set_animate_rotate_by(int value) + { + impl_->anim_rotate_description_->By = value; + } + + void pptx_animation_context::set_animate_rotate_attribute_name(const std::wstring& value) + { + impl_->anim_rotate_description_->AttributeName = value; + } + + void pptx_animation_context::set_animate_rotate_delay(const std::wstring& value) + { + impl_->anim_rotate_description_->Delay = value; + } + + void pptx_animation_context::set_animate_rotate_auto_reverse(bool value) + { + impl_->anim_rotate_description_->AutoReverse = value; + } + + void pptx_animation_context::end_animate_rotate() + { + END_BEHAVIOUR_ELEMENT(anim_rotate_description_); + } + + ////////////////////////////////////////////////////////////////////////// + // p:audio + void pptx_animation_context::start_anim_audio() + { + impl_->audio_description_ = boost::make_shared(); + } + + void pptx_animation_context::end_anim_audio() + { + if (impl_->par_animation_levels_.size()) + { + Impl::_par_animation_ptr& back = impl_->par_animation_levels_.back(); + back->AnimationActionArray.push_back(impl_->audio_description_); + } + impl_->audio_description_ = nullptr; + } + + void pptx_animation_context::add_anim_audio(const std::wstring& rId, const std::wstring& name) + { + impl_->audio_description_->RId = rId; + impl_->audio_description_->Name = name; + } + + void pptx_animation_context::serialize(std::wostream& strm) + { + if (!impl_->root_animation_element_) + return; + + if (!impl_->root_animation_element_->AnimationActionArray.size() && + !impl_->root_animation_element_->AnimParArray.size()) + { + if (!impl_->root_animation_element_->AnimSeq.size() || + !impl_->root_animation_element_->AnimSeq.back()->AnimParArray.size()) + return; + } + + CP_XML_WRITER(strm) + { + CP_XML_NODE(L"p:timing") + { + if (impl_->root_animation_element_) + { + CP_XML_NODE(L"p:tnLst") + { + impl_->root_animation_element_->serialize(CP_XML_STREAM()); + } + } + } + } + } + + void pptx_animation_context::clear() + { + impl_->clear(); + } + + void pptx_animation_context::set_is_slide_animation(bool is_slide_animation) + { + impl_->IsSlideAnimation = is_slide_animation; + } + + bool pptx_animation_context::get_is_slide_animation() + { + return impl_->IsSlideAnimation; + } + + const pptx_animation_context::Impl::_par_animation_ptr& pptx_animation_context::get_root_par_animation() const + { + return impl_->root_animation_element_; + } + + static _CP_OPT(std::wstring) serialize_duration(const _CP_OPT(int) duration) + { + _CP_OPT(std::wstring) res = boost::none; + + if (duration) + { + if (*duration == -1) + res = L"indefinite"; + else + res = std::to_wstring(duration.value()); + } + + return res; + } + + void pptx_animation_context::Impl::_par_animation::serialize(std::wostream& strm) + { + CP_XML_WRITER(strm) + { + CP_XML_NODE(L"p:par") + { + CP_XML_NODE(L"p:cTn") + { + CP_XML_ATTR_OPT(L"presetClass" , PresetClass); + CP_XML_ATTR_OPT(L"presetID" , PresetID); + CP_XML_ATTR_OPT(L"presetSubtype", PresetSubtype); + CP_XML_ATTR_OPT(L"fill" , Fill); + CP_XML_ATTR_OPT(L"accel" , Accelerate); + CP_XML_ATTR_OPT(L"decel" , Decelerate); + + if (NodeType) + { + if (NodeType.value() == L"tmRoot") + { + CP_XML_ATTR(L"nodeType", L"tmRoot"); + CP_XML_ATTR(L"dur", L"indefinite"); + CP_XML_ATTR(L"restart", L"never"); + } + else + { + CP_XML_ATTR(L"nodeType", NodeType.value()); + } + } + + if (Delay) + { + CP_XML_NODE(L"p:stCondLst") + { + CP_XML_NODE(L"p:cond") + { + CP_XML_ATTR(L"delay", Delay.value()); + } + } + } + + if (AnimParArray.size() || AnimSeq.size() || AnimationActionArray.size()) + { + CP_XML_NODE(L"p:childTnLst") + { + for (size_t i = 0; i < AnimParArray.size(); i++) + AnimParArray[i]->serialize(CP_XML_STREAM()); + + for (size_t i = 0; i < AnimSeq.size(); i++) + AnimSeq[i]->serialize(CP_XML_STREAM()); + + for (size_t i = 0; i < AnimationActionArray.size(); i++) + AnimationActionArray[i]->serialize(CP_XML_STREAM()); + } + } + } + } + } + } + + void pptx_animation_context::Impl::_seq_animation::serialize(std::wostream& strm) + { + CP_XML_WRITER(strm) + { + CP_XML_NODE(L"p:seq") + { + CP_XML_ATTR(L"concurrent", 1); + CP_XML_ATTR(L"nextAc", L"seek"); + + CP_XML_NODE(L"p:cTn") + { + if (PresentationNodeType) + { + CP_XML_ATTR(L"nodeType", PresentationNodeType.value()); + CP_XML_ATTR(L"dur", L"indefinite"); + } + else + { + CP_XML_ATTR_OPT(L"dur", serialize_duration(Duration)); + } + + if (TargetEl) + { + CP_XML_NODE(L"p:stCondLst") + { + CP_XML_NODE(L"p:cond") + { + CP_XML_ATTR(L"evt", L"onClick"); + CP_XML_NODE(L"p:tgtEl") + { + CP_XML_NODE(L"p:spTgt") + { + CP_XML_ATTR(L"spid", TargetEl.value()); + } + } + } + } + } + + if (AnimParArray.size()) + { + CP_XML_NODE(L"p:childTnLst") + { + for (int i = 0; i < AnimParArray.size(); i++) + { + AnimParArray[i]->serialize(CP_XML_STREAM()); + } + } + } + } + CP_XML_NODE(L"p:prevCondLst") + { + CP_XML_NODE(L"p:cond") + { + CP_XML_ATTR(L"evt", L"onPrev"); + CP_XML_NODE(L"p:tgtEl") + { + CP_XML_NODE(L"p:sldTgt"); + } + } + } + CP_XML_NODE(L"p:nextCondLst") + { + CP_XML_NODE(L"p:cond") + { + CP_XML_ATTR(L"evt", L"onNext"); + CP_XML_NODE(L"p:tgtEl") + { + CP_XML_NODE(L"p:sldTgt"); + } + } + } + } + } + } + + + void pptx_animation_context::Impl::_set::serialize(std::wostream& strm) + { + CP_XML_WRITER(strm) + { + CP_XML_NODE(L"p:set") + { + CP_XML_NODE(L"p:cBhvr") + { + CP_XML_NODE(L"p:cTn") + { + CP_XML_ATTR_OPT(L"dur", serialize_duration(Duration)); + CP_XML_ATTR_OPT(L"fill", Fill); + CP_XML_ATTR_OPT(L"autoRev", AutoRev); + + if (Delay) + { + CP_XML_NODE(L"p:stCondLst") + { + CP_XML_NODE(L"p:cond") + { + CP_XML_ATTR(L"delay", Delay.value()); + } + } + } + } + + CP_XML_NODE(L"p:tgtEl") + { + CP_XML_NODE(L"p:spTgt") + { + size_t shapeId = ShapeID ? ShapeID.value() : 0; + CP_XML_ATTR(L"spid", shapeId); + } + } + + if (AttributeName) + { + CP_XML_NODE(L"p:attrNameLst") + { + CP_XML_NODE(L"p:attrName") + { + CP_XML_STREAM() << AttributeName.value(); + } + } + } + } + if (ToValue) + { + CP_XML_NODE(L"p:to") + { + CP_XML_NODE(L"p:strVal") + { + CP_XML_ATTR(L"val", ToValue.value()); + } + } + } + } + } + } + + + void pptx_animation_context::Impl::_anim_effect::serialize(std::wostream& strm) + { + CP_XML_WRITER(strm) + { + CP_XML_NODE(L"p:animEffect") + { + CP_XML_ATTR_OPT(L"filter" , Filter); + CP_XML_ATTR_OPT(L"transition" , Transition); + + CP_XML_NODE(L"p:cBhvr") + { + if (Duration) + { + CP_XML_NODE(L"p:cTn") + { + CP_XML_ATTR_OPT(L"dur", serialize_duration(Duration)); + CP_XML_ATTR_OPT(L"accel", Accel); + CP_XML_ATTR_OPT(L"decel", Decel); + + if (Delay) + { + CP_XML_NODE(L"p:stCondLst") + { + CP_XML_NODE(L"p:cond") + { + CP_XML_ATTR(L"delay", Delay.value()); + } + } + } + } + } + if (ShapeID) + { + CP_XML_NODE(L"p:tgtEl") + { + CP_XML_NODE(L"p:spTgt") + { + CP_XML_ATTR(L"spid", ShapeID.value()); + } + } + } + } + } + } + } + + void pptx_animation_context::Impl::_animate_motion::serialize(std::wostream& strm) + { + CP_XML_WRITER(strm) + { + CP_XML_NODE(L"p:animMotion") + { + CP_XML_ATTR(L"origin", L"layout"); + CP_XML_ATTR(L"path", SvgPath); + + CP_XML_NODE(L"p:cBhvr") + { + CP_XML_NODE(L"p:cTn") + { + CP_XML_ATTR_OPT(L"dur", SmilDurMs); + CP_XML_ATTR(L"fill", L"hold"); + } + CP_XML_NODE(L"p:tgtEl") + { + CP_XML_NODE(L"p:spTgt") + { + size_t shapeID = ShapeID ? ShapeID.value() : 0; + CP_XML_ATTR(L"spid", shapeID); + } + } + } + } + } + } + + void pptx_animation_context::Impl::_anim::serialize(std::wostream& strm) + { + CP_XML_WRITER(strm) + { + CP_XML_NODE(L"p:anim") + { + CP_XML_ATTR_OPT(L"calcmode", CalcMode); + CP_XML_ATTR_OPT(L"valueType", ValueType); + CP_XML_ATTR_OPT(L"from", From); + CP_XML_ATTR_OPT(L"to", To); + CP_XML_ATTR_OPT(L"by", By); + + CP_XML_NODE(L"p:cBhvr") + { + CP_XML_ATTR_OPT(L"additive", Additive); + + CP_XML_NODE(L"p:cTn") + { + CP_XML_ATTR_OPT(L"dur", serialize_duration(Duration)); + + if (AutoReverse) + { + int autoRev = AutoReverse.value() ? 1 : 0; + CP_XML_ATTR(L"autoRev", autoRev); + } + + if (Delay) + { + CP_XML_NODE(L"p:stCondLst") + { + CP_XML_NODE(L"p:cond") + { + CP_XML_ATTR(L"delay", Delay.value()); + } + } + } + } + CP_XML_NODE(L"p:tgtEl") + { + CP_XML_NODE(L"p:spTgt") + { + size_t shapeID = ShapeID ? ShapeID.value() : 0; + CP_XML_ATTR(L"spid", shapeID); + } + } + + if (AttributeName) + { + CP_XML_NODE(L"p:attrNameLst") + { + CP_XML_NODE(L"p:attrName") + { + CP_XML_STREAM() << AttributeName.value(); + } + } + } + } + CP_XML_NODE(L"p:tavLst") + { + if (KeypointArray) + { + for (size_t i = 0; i < KeypointArray->size(); i++) + { + const int& time = (*KeypointArray)[i].Time; + const std::wstring& value = (*KeypointArray)[i].Value; + const _CP_OPT(std::wstring) formula = (*KeypointArray)[i].Fmla; + + CP_XML_NODE(L"p:tav") + { + if (formula) + CP_XML_ATTR(L"fmla", formula.value()); + CP_XML_ATTR(L"tm", time); + + CP_XML_NODE(L"p:val") + { + CP_XML_NODE(L"p:strVal") + { + CP_XML_ATTR(L"val", value); + } + } + } + } + } + } + } + } + } + + void pptx_animation_context::Impl::_anim_clr::serialize(std::wostream& strm) + { + CP_XML_WRITER(strm) + { + CP_XML_NODE(L"p:animClr") + { + CP_XML_ATTR_OPT(L"clrSpc", ColorSpace); + + CP_XML_NODE(L"p:cBhvr") + { + CP_XML_NODE(L"p:cTn") + { + CP_XML_ATTR_OPT(L"dur", serialize_duration(Duration)); + CP_XML_ATTR_OPT(L"fill", Fill); + CP_XML_ATTR_OPT(L"autoRev", AutoRev); + CP_XML_ATTR_OPT(L"dir", Direction); + + if (Delay) + { + CP_XML_NODE(L"p:stCondLst") + { + CP_XML_NODE(L"p:cond") + { + CP_XML_ATTR(L"delay", Delay.value()); + } + } + } + } + CP_XML_NODE(L"p:tgtEl") + { + size_t shapeID = ShapeID ? ShapeID.value() : 0; + CP_XML_NODE(L"p:spTgt") + { + CP_XML_ATTR(L"spid", shapeID); + } + } + if (AttributeName) + { + CP_XML_NODE(L"p:attrNameLst") + { + CP_XML_NODE(L"p:attrName") + { + CP_XML_STREAM() << AttributeName.value(); + } + } + } + } + if (ToValue) + { + CP_XML_NODE(L"p:to") + { + CP_XML_NODE(L"a:srgbClr") + { + CP_XML_ATTR(L"val", ToValue.value()); + } + } + } + + if (ByValue) + { + CP_XML_NODE(L"p:by") + { + switch (ByValue->type_) + { + case color::rgb: + { + CP_XML_NODE(L"a:srgbClr") + { + std::wstringstream ss; + ss << std::hex + << ByValue->v1 + << ByValue->v2 + << ByValue->v3; + + CP_XML_ATTR(L"val", ss.str()); + } + } break; + case color::hsl: + { + CP_XML_NODE(L"p:hsl") + { + CP_XML_ATTR(L"h", ByValue->v1); + CP_XML_ATTR(L"s", ByValue->v2); + CP_XML_ATTR(L"l", ByValue->v3); + } + } break; + } + } + } + } + } + } + + void pptx_animation_context::Impl::_anim_scale::serialize(std::wostream& strm) + { + CP_XML_WRITER(strm) + { + CP_XML_NODE(L"p:animScale") + { + CP_XML_NODE(L"p:cBhvr") + { + CP_XML_NODE(L"p:cTn") + { + CP_XML_ATTR_OPT(L"dur", serialize_duration(Duration)); + + if (AutoReverse) CP_XML_ATTR(L"autoRev", AutoReverse.value()); + if (Fill) CP_XML_ATTR(L"fill", Fill.value()); + + CP_XML_NODE(L"p:stCondLst") + { + std::wstring delay = Delay ? Delay.value() : L"0"; + CP_XML_NODE(L"p:cond") + { + CP_XML_ATTR(L"delay", delay); + } + } + } + CP_XML_NODE(L"p:tgtEl") + { + CP_XML_NODE(L"p:spTgt") + { + size_t shapeID = ShapeID ? ShapeID.value() : 0; + CP_XML_ATTR(L"spid", shapeID); + } + } + + if (AttributeName) + { + CP_XML_NODE(L"p:attrNameLst") + { + CP_XML_NODE(L"p:attrName") + { + CP_XML_STREAM() << AttributeName.value(); + } + } + } + } + + if (From) + { + CP_XML_NODE(L"p:from") + { + CP_XML_ATTR(L"x", From->x); + CP_XML_ATTR(L"y", From->y); + } + } + + if (To) + { + CP_XML_NODE(L"p:to") + { + CP_XML_ATTR(L"x", To->x); + CP_XML_ATTR(L"y", To->y); + } + } + + if (By) + { + CP_XML_NODE(L"p:by") + { + CP_XML_ATTR(L"x", By->x); + CP_XML_ATTR(L"y", By->y); + } + } + } + } + } + + void pptx_animation_context::Impl::_anim_rotate::serialize(std::wostream& strm) + { + CP_XML_WRITER(strm) + { + CP_XML_NODE(L"p:animRot") + { + if (By) CP_XML_ATTR(L"by", By.value()); + + CP_XML_NODE(L"p:cBhvr") + { + CP_XML_NODE(L"p:cTn") + { + CP_XML_ATTR_OPT(L"dur", serialize_duration(Duration)); + + if (AutoReverse) CP_XML_ATTR(L"autoRev", AutoReverse.value()); + if (Fill) CP_XML_ATTR(L"fill", Fill.value()); + + CP_XML_NODE(L"p:stCondLst") + { + std::wstring delay = Delay ? Delay.value() : L"0"; + CP_XML_NODE(L"p:cond") + { + CP_XML_ATTR(L"delay", delay); + } + } + } + CP_XML_NODE(L"p:tgtEl") + { + CP_XML_NODE(L"p:spTgt") + { + size_t shapeID = ShapeID ? ShapeID.value() : 0; + CP_XML_ATTR(L"spid", shapeID); + } + } + + if (AttributeName) + { + CP_XML_NODE(L"p:attrNameLst") + { + CP_XML_NODE(L"p:attrName") + { + CP_XML_STREAM() << AttributeName.value(); + } + } + } + } + } + } + } + + void pptx_animation_context::Impl::_audio::serialize(std::wostream& strm) + { + CP_XML_WRITER(strm) + { + CP_XML_NODE(L"p:audio") + { + CP_XML_ATTR(L"isNarration", 0); + + CP_XML_NODE(L"p:cMediaNode") + { + CP_XML_ATTR(L"showWhenStopped", 1); + + CP_XML_NODE(L"p:cTn"); + CP_XML_NODE(L"p:tgtEl") + { + CP_XML_NODE(L"p:sndTgt") + { + CP_XML_ATTR_OPT(L"name", Name); + CP_XML_ATTR_OPT(L"r:embed", RId); + } + } + } + } + } + } + +} // namespace oox +} // namespace cpdoccore \ No newline at end of file diff --git a/OdfFile/Reader/Converter/pptx_animation_context.h b/OdfFile/Reader/Converter/pptx_animation_context.h new file mode 100644 index 00000000000..3f9003aefe4 --- /dev/null +++ b/OdfFile/Reader/Converter/pptx_animation_context.h @@ -0,0 +1,421 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#pragma once + +#include +#include +#include +#include + +namespace cpdoccore { +namespace oox { + + class pptx_animation_context + { + public: + class Impl + { + public: + struct _animation_element; + typedef shared_ptr<_animation_element>::Type _animation_element_ptr; + typedef std::vector<_animation_element_ptr> _animation_element_array; + struct _animation_element + { + virtual void serialize(std::wostream& strm) = 0; + }; + + struct _par_animation; + typedef shared_ptr<_par_animation>::Type _par_animation_ptr; + typedef std::vector<_par_animation_ptr> _par_animation_array; + + struct _seq_animation; + typedef shared_ptr<_seq_animation>::Type _seq_animation_ptr; + typedef std::vector<_seq_animation_ptr> _seq_animation_array; + + struct _par_animation : _animation_element + { + _CP_OPT(std::wstring) NodeType; + _CP_OPT(std::wstring) Direction; + _CP_OPT(std::wstring) Restart; + _CP_OPT(int) Duration; // in ms + _CP_OPT(std::wstring) Delay; + _CP_OPT(std::wstring) End; + _CP_OPT(std::wstring) PresetClass; + _CP_OPT(int) PresetID; + _CP_OPT(int) PresetSubtype; + _CP_OPT(std::wstring) Fill; + _CP_OPT(int) Accelerate; + _CP_OPT(int) Decelerate; + + _par_animation_array AnimParArray; + _seq_animation_array AnimSeq; + _animation_element_array AnimationActionArray; + + void serialize(std::wostream& strm) override; + }; + + struct _seq_animation : _animation_element + { + _CP_OPT(std::wstring) PresentationNodeType; + _CP_OPT(std::wstring) Direction; + _CP_OPT(std::wstring) Restart; + _CP_OPT(int) Duration; // in ms + _CP_OPT(std::wstring) Delay; + _CP_OPT(std::wstring) End; + _CP_OPT(std::wstring) TargetEl; + + _par_animation_array AnimParArray; + + void serialize(std::wostream& strm) override; + }; + + struct _set; + typedef shared_ptr<_set>::Type _set_ptr; + struct _set : _animation_element + { + _CP_OPT(std::wstring) Direction; + _CP_OPT(std::wstring) Restart; + _CP_OPT(int) Duration; // in ms + _CP_OPT(std::wstring) Delay; + _CP_OPT(std::wstring) End; + _CP_OPT(std::wstring) AutoRev; + _CP_OPT(std::wstring) Fill; + _CP_OPT(size_t) ShapeID; + _CP_OPT(std::wstring) AttributeName; + _CP_OPT(std::wstring) ToValue; + + void serialize(std::wostream& strm) override; + }; + + struct _anim_effect; + typedef shared_ptr<_anim_effect>::Type _anim_effect_ptr; + struct _anim_effect : _animation_element + { + _CP_OPT(std::wstring) Filter; + _CP_OPT(std::wstring) Transition; + _CP_OPT(std::wstring) Delay; + _CP_OPT(int) Accel; + _CP_OPT(int) Decel; + _CP_OPT(int) Duration; // in ms + _CP_OPT(size_t) ShapeID; + + void serialize(std::wostream& strm) override; + }; + + struct _animate_motion; + typedef shared_ptr<_animate_motion>::Type _animate_motion_ptr; + typedef std::vector<_animate_motion_ptr> _animate_motion_array; + struct _animate_motion : _animation_element + { + _CP_OPT(std::wstring) PresentationNodeType; + _CP_OPT(std::wstring) SmilDirection; + _CP_OPT(std::wstring) SmilRestart; + _CP_OPT(int) SmilDurMs; + _CP_OPT(std::wstring) SmilBegin; + _CP_OPT(std::wstring) SmilEnd; + + _CP_OPT(std::wstring) SmilFill; + _CP_OPT(std::wstring) AnimSubItem; + _CP_OPT(size_t) ShapeID; + _CP_OPT(std::wstring) SvgPath; + + void serialize(std::wostream& strm) override; + }; + + struct _anim_clr; + typedef shared_ptr<_anim_clr>::Type _anim_clr_ptr; + struct _anim_clr : _animation_element + { + struct color + { + enum type + { + rgb, + hsl + } type_; + + int v1, v2, v3; + }; + + + _CP_OPT(std::wstring) PresentationNodeType; + _CP_OPT(std::wstring) Direction; + _CP_OPT(std::wstring) Restart; + _CP_OPT(int) Duration; // in ms + _CP_OPT(std::wstring) Begin; + _CP_OPT(std::wstring) End; + + _CP_OPT(std::wstring) Fill; + _CP_OPT(bool) AutoRev; + _CP_OPT(size_t) ShapeID; + _CP_OPT(std::wstring) AttributeName; + _CP_OPT(std::wstring) Delay; + _CP_OPT(std::wstring) ToValue; + _CP_OPT(color) ByValue; + _CP_OPT(std::wstring) ColorSpace; + + void serialize(std::wostream& strm) override; + }; + + struct _anim; + typedef shared_ptr<_anim>::Type _anim_ptr; + struct _anim : _animation_element + { + struct _keypoint + { + int Time; + std::wstring Value; + _CP_OPT(std::wstring) Fmla; // Formula + + _keypoint(int time, const std::wstring& value, _CP_OPT(std::wstring) formula) + : Time(time), Value(value), Fmla(formula) + {} + }; + + _CP_OPT(std::wstring) CalcMode; + _CP_OPT(std::wstring) ValueType; + _CP_OPT(size_t) ShapeID; + _CP_OPT(int) Duration; // in ms + _CP_OPT(std::wstring) AttributeName; + _CP_OPT(std::wstring) From; + _CP_OPT(std::wstring) To; + _CP_OPT(std::wstring) By; + _CP_OPT(std::wstring) Additive; + _CP_OPT(bool) AutoReverse; + _CP_OPT(std::wstring) Delay; + _CP_OPT(std::vector<_keypoint>) KeypointArray; + + void serialize(std::wostream& strm) override; + }; + + struct _anim_scale; + typedef shared_ptr<_anim_scale>::Type _anim_scale_ptr; + struct _anim_scale : _animation_element + { + struct vec2 + { + int x, y; + + vec2(int x, int y) + : x(x), y(y) + {} + }; + + _CP_OPT(size_t) ShapeID; + _CP_OPT(int) Duration; // in ms + _CP_OPT(std::wstring) Fill; + _CP_OPT(vec2) From; + _CP_OPT(vec2) To; + _CP_OPT(vec2) By; + _CP_OPT(std::wstring) Delay; + _CP_OPT(std::wstring) AttributeName; + _CP_OPT(bool) AutoReverse; + + void serialize(std::wostream& strm) override; + }; + + struct _anim_rotate; + typedef shared_ptr<_anim_rotate>::Type _anim_rotate_ptr; + struct _anim_rotate : _animation_element + { + _CP_OPT(size_t) ShapeID; + _CP_OPT(int) Duration; // in ms + _CP_OPT(std::wstring) Fill; + _CP_OPT(int) By; + _CP_OPT(std::wstring) AttributeName; + _CP_OPT(std::wstring) Delay; + _CP_OPT(bool) AutoReverse; + + void serialize(std::wostream& strm) override; + }; + + struct _audio; + typedef shared_ptr<_audio>::Type _audio_ptr; + struct _audio : _animation_element + { + _CP_OPT(std::wstring) Name; + _CP_OPT(std::wstring) RId; + + void serialize(std::wostream& strm) override; + }; + + _par_animation_ptr root_animation_element_; + _par_animation_array par_animation_levels_; + + _animate_motion_ptr animate_motion_description_; + _set_ptr set_description_; + _anim_effect_ptr anim_effect_description_; + _anim_ptr anim_description_; + _anim_clr_ptr anim_clr_description_; + _anim_scale_ptr anim_scale_description_; + _anim_rotate_ptr anim_rotate_description_; + _audio_ptr audio_description_; + + void clear(); + + bool IsSlideAnimation; + + Impl(); + }; + + public: + pptx_animation_context(); + + void start_par_animation(); + void set_par_animation_presentation_node_type(const std::wstring& value); + void set_par_animation_direction(const std::wstring& value); + void set_par_animation_restart(const std::wstring& value); + void set_par_animation_duration(int value); + void set_par_animation_delay(const std::wstring& value); + void set_par_animation_end(const std::wstring& value); + void set_par_animation_preset_class(const std::wstring& value); + void set_par_animation_preset_id(int value); + void set_par_animation_preset_subtype(int value); + void set_par_animation_fill(const std::wstring& value); + void set_par_animation_accelerate(int value); + void set_par_animation_decelerate(int value); + void end_par_animation(); + + void start_seq_animation(); + void set_seq_animation_presentation_node_type(const std::wstring& value); + void set_seq_animation_direction(const std::wstring& value); + void set_seq_animation_restart(const std::wstring& value); + void set_seq_animation_dur(int value); + void set_seq_animation_delay(const std::wstring& value); + void set_seq_animation_end(const std::wstring& value); + void set_seq_animation_target_element(const std::wstring& value); + void end_seq_animation(); + + void start_set(); + void set_set_direction(const std::wstring& value); + void set_set_restart(const std::wstring& value); + void set_set_duration(int value); + void set_set_delay(const std::wstring& value); + void set_set_end(const std::wstring& value); + void set_set_auto_rev(const std::wstring& value); + void set_set_fill(const std::wstring& value); + void set_set_shape_id(size_t value); + void set_set_attribute_name(const std::wstring& value); + void set_set_to_value(const std::wstring& value); + void end_set(); + + void start_anim_effect(); + void set_anim_effect_filter(const std::wstring& value); + void set_anim_effect_transition(const std::wstring& value); + void set_anim_effect_duration(int value); + void set_anim_effect_delay(const std::wstring& value); + void set_anim_effect_accel(int value); + void set_anim_effect_decel(int value); + void set_anim_effect_shape_id(size_t value); + void end_anim_effect(); + + void start_animate_motion(); + void set_animate_motion_presentation_node_type(const std::wstring& value); + void set_animate_motion_direction(const std::wstring& value); + void set_animate_motion_restart(const std::wstring& value); + void set_animate_motion_dur(int value); + void set_animate_motion_delay(const std::wstring& value); + void set_animate_motion_end(const std::wstring& value); + void set_animate_motion_fill(const std::wstring& value); + void set_animate_motion_shape_id(size_t value); + void set_animate_motion_svg_path(const std::wstring& value); + void end_animate_motion(); + + void start_animate(); + void set_animate_calc_mode(const std::wstring& value); + void set_animate_value_type(const std::wstring& value); + void set_animate_shape_id(size_t value); + void set_animate_duration(int value); + void set_animate_attribute_name(const std::wstring& value); + void set_animate_from(const std::wstring& value); + void set_animate_to(const std::wstring& value); + void set_animate_by(const std::wstring& value); + void set_animate_additive(const std::wstring& value); + void set_animate_auto_reverse(bool value); + void set_animate_delay(const std::wstring& value); + void add_animate_keypoint(int time, const std::wstring& value, _CP_OPT(std::wstring) formula); + void end_animate(); + + void start_animate_color(); + void set_animate_color_color_space(const std::wstring& value); + void set_animate_color_dir(const std::wstring& value); + void set_animate_color_duration(int value); + void set_animate_color_delay(const std::wstring& value); + void set_animate_color_fill(const std::wstring& value); + void set_animate_color_auto_rev(bool value); + void set_animate_color_attribute_name(const std::wstring& value); + void set_animate_color_to_value(const std::wstring& value); + void set_animate_color_by_value(const std::wstring& value); + void set_animate_color_shape_id(size_t value); + void end_animate_color(); + + void start_animate_scale(); + void set_animate_scale_shape_id(size_t value); + void set_animate_scale_duration(int value); + void set_animate_scale_fill(const std::wstring& value); + void set_animate_scale_from(int x, int y); + void set_animate_scale_to(int x, int y); + void set_animate_scale_by(int x, int y); + void set_animate_scale_delay(const std::wstring& value); + void set_animate_scale_attribute_name(const std::wstring& value); + void set_animate_scale_auto_reverse(bool value); + void end_animate_scale(); + + void start_animate_rotate(); + void set_animate_rotate_shape_id(size_t value); + void set_animate_rotate_duration(int value); + void set_animate_rotate_fill(const std::wstring& value); + void set_animate_rotate_by(int value); + void set_animate_rotate_attribute_name(const std::wstring& value); + void set_animate_rotate_delay(const std::wstring& value); + void set_animate_rotate_auto_reverse(bool value); + void end_animate_rotate(); + + void start_anim_audio(); + void add_anim_audio(const std::wstring& rId, const std::wstring& name); + void end_anim_audio(); + + + + void serialize(std::wostream & strm); + void clear(); + + void set_is_slide_animation(bool is_slide_animation); + bool get_is_slide_animation(); + const Impl::_par_animation_ptr& get_root_par_animation() const; + + private: + _CP_PTR(Impl) impl_; + }; + +} // namespace oox +} // namespace cpdoccore \ No newline at end of file diff --git a/OdfFile/Reader/Converter/pptx_conversion_context.cpp b/OdfFile/Reader/Converter/pptx_conversion_context.cpp index f13fd75d8b7..fc5559ff97b 100644 --- a/OdfFile/Reader/Converter/pptx_conversion_context.cpp +++ b/OdfFile/Reader/Converter/pptx_conversion_context.cpp @@ -45,660 +45,688 @@ #include "pptx_default_serializes.h" -namespace cpdoccore { +namespace cpdoccore { -namespace odf_reader -{ - class odf_document; -} - -namespace oox { - -namespace package -{ - class pptx_document; -} + namespace odf_reader + { + class odf_document; + } -pptx_conversion_context::pptx_conversion_context( odf_reader::odf_document * odfDocument) - :output_document_ (NULL) - ,odf_document_ (odfDocument) - ,pptx_text_context_ (odf_document_->odf_context(), *this) - ,pptx_table_context_ (*this) - ,pptx_comments_context_ (comments_context_handle_) - ,pptx_slide_context_ (*this/*, pptx_text_context_*/) - ,math_context_ (odf_document_->odf_context().fontContainer(), true) - ,last_idx_placeHolder (1) - ,last_uniq_big_id (1) -{ -} + namespace oox { + namespace package + { + class pptx_document; + } -pptx_conversion_context::~pptx_conversion_context() -{ -} + pptx_conversion_context::pptx_conversion_context(odf_reader::odf_document* odfDocument) + :output_document_(NULL) + , odf_document_(odfDocument) + , pptx_text_context_(odf_document_->odf_context(), *this) + , pptx_table_context_(*this) + , pptx_comments_context_(comments_context_handle_) + , pptx_slide_context_(*this/*, pptx_text_context_*/) + , math_context_(odf_document_->odf_context().fontContainer(), true) + , last_idx_placeHolder(1) + , last_uniq_big_id(1) + { + } -void pptx_conversion_context::set_output_document(package::pptx_document * document) -{ - output_document_ = document; -} + pptx_conversion_context::~pptx_conversion_context() + { + } -void pptx_conversion_context::set_font_directory(std::wstring pathFonts) -{ - pptx_slide_context_.get_mediaitems()->set_font_directory(pathFonts); -} + void pptx_conversion_context::set_output_document(package::pptx_document* document) + { + output_document_ = document; + } -void pptx_conversion_context::process_layouts() -{ - odf_reader::presentation_layouts_instance & layouts = root()->odf_context().styleContainer().presentation_layouts(); + void pptx_conversion_context::set_font_directory(std::wstring pathFonts) + { + pptx_slide_context_.get_mediaitems()->set_font_directory(pathFonts); + } + void pptx_conversion_context::add_page_name(const std::wstring& page_name) + { + page_names_.push_back(page_name); + } - get_text_context().set_process_layouts(true); + const std::vector& pptx_conversion_context::get_page_names() const + { + return page_names_; + } - //актуальные - for (size_t layout_index =0; layout_index < layouts.content.size(); layout_index++) + void pptx_conversion_context::process_layouts() { - start_layout(layout_index); + odf_reader::presentation_layouts_instance& layouts = root()->odf_context().styleContainer().presentation_layouts(); - odf_reader::style_presentation_page_layout * layout = - root()->odf_context().pageLayoutContainer().presentation_page_layout_by_name(layouts.content[layout_index].layout_name); + get_text_context().set_process_layouts(true); - if (layout) + //актуальные + for (size_t layout_index = 0; layout_index < layouts.content.size(); layout_index++) { - layout->pptx_convert(*this); - } - //нужно вытащить footers - odf_reader::style_master_page * master = - root()->odf_context().pageLayoutContainer().master_page_by_name(layouts.content[layout_index].master_name); + start_layout(layout_index); - if (master) - { - for (size_t i = 0; i < master->content_.size(); i++) + odf_reader::style_presentation_page_layout* layout = + root()->odf_context().pageLayoutContainer().presentation_page_layout_by_name(layouts.content[layout_index].layout_name); + + if (layout) + { + layout->pptx_convert(*this); + } + //нужно вытащить footers + odf_reader::style_master_page* master = + root()->odf_context().pageLayoutContainer().master_page_by_name(layouts.content[layout_index].master_name); + + if (master) { - odf_reader::draw_frame* frame = dynamic_cast(master->content_[i].get()); - if (frame) + for (size_t i = 0; i < master->content_.size(); i++) { - odf_types::common_presentation_attlist &common_presentation_attlist_= frame->common_draw_attlists_.shape_with_text_and_styles_.common_presentation_attlist_; - - if (common_presentation_attlist_.presentation_class_) + odf_reader::draw_frame* frame = dynamic_cast(master->content_[i].get()); + if (frame) { - odf_types::presentation_class::type type = common_presentation_attlist_.presentation_class_->get_type(); + odf_types::common_presentation_attlist& common_presentation_attlist_ = frame->common_draw_attlists_.shape_with_text_and_styles_.common_presentation_attlist_; - if (type == odf_types::presentation_class::footer || - type == odf_types::presentation_class::date_time || - type == odf_types::presentation_class::header || - type == odf_types::presentation_class::page_number) + if (common_presentation_attlist_.presentation_class_) { - if (frame->idx_in_owner < 0) - frame->idx_in_owner = last_idx_placeHolder++; - - frame->pptx_convert_placeHolder(*this); + odf_types::presentation_class::type type = common_presentation_attlist_.presentation_class_->get_type(); + + if (type == odf_types::presentation_class::footer || + type == odf_types::presentation_class::date_time || + type == odf_types::presentation_class::header || + type == odf_types::presentation_class::page_number) + { + if (frame->idx_in_owner < 0) + frame->idx_in_owner = last_idx_placeHolder++; + + frame->pptx_convert_placeHolder(*this); + } } } } } + end_layout(); } - end_layout(); + get_text_context().set_process_layouts(false); } - get_text_context().set_process_layouts(false); -} -void pptx_conversion_context::process_master_pages() -{ - odf_reader::presentation_masters_instance & masters = root()->odf_context().styleContainer().presentation_masters(); + void pptx_conversion_context::process_master_pages() + { + odf_reader::presentation_masters_instance& masters = root()->odf_context().styleContainer().presentation_masters(); - process_masters_ = true; - get_text_context().set_process_layouts(true); + process_masters_ = true; + get_text_context().set_process_layouts(true); - //берем только актуальные - odf_reader::office_element_ptr master_notes_; - - for (size_t master_index = 0; master_index < masters.content.size(); master_index++) - { - start_master(master_index); - - odf_reader::style_master_page * master = - root()->odf_context().pageLayoutContainer().master_page_by_name(masters.content[master_index].master_name); + //берем только актуальные + odf_reader::office_element_ptr master_notes_; + + for (size_t master_index = 0; master_index < masters.content.size(); master_index++) + { + start_master(master_index); + + odf_reader::style_master_page* master = + root()->odf_context().pageLayoutContainer().master_page_by_name(masters.content[master_index].master_name); + + if (master) + { + master->pptx_convert(*this); + + if (!master_notes_ && master->presentation_notes_) + master_notes_ = master->presentation_notes_; + } - if (master) + + end_master(); + } + + if (master_notes_) { - master->pptx_convert(*this); - - if (!master_notes_ && master->presentation_notes_) - master_notes_ = master->presentation_notes_; + start_master_notes(); + master_notes_->pptx_convert(*this); + end_master_notes(); } + process_masters_ = false; + get_text_context().set_process_layouts(false); - - end_master(); } - if (master_notes_) + void pptx_conversion_context::process_styles() { - start_master_notes(); - master_notes_->pptx_convert(*this); - end_master_notes(); - } - process_masters_ = false; - get_text_context().set_process_layouts(false); -} + } + void pptx_conversion_context::process_theme(std::wstring name) + { + int current = themes_.size() + 1; -void pptx_conversion_context::process_styles() -{ - -} -void pptx_conversion_context::process_theme(std::wstring name) -{ - int current = themes_.size() + 1; + if (name.empty()) + { + name = L"User Theme: " + std::to_wstring(current); + } + start_theme(name); + // + pptx_serialize_clrScheme(current_theme().clrSchemeData()); + pptx_serialize_fmtScheme(current_theme().fmtSchemeData()); + pptx_serialize_fontScheme(current_theme().fontSchemeData()); + // + end_theme(); - if (name.empty()) - { - name = L"User Theme: " + std::to_wstring(current); } - start_theme(name); - // - pptx_serialize_clrScheme (current_theme().clrSchemeData()); - pptx_serialize_fmtScheme (current_theme().fmtSchemeData()); - pptx_serialize_fontScheme (current_theme().fontSchemeData()); - // - end_theme(); + void pptx_conversion_context::start_document() + { + odf_reader::odf_read_context& odfContext = root()->odf_context(); + std::vector instances; -} -void pptx_conversion_context::start_document() -{ - odf_reader::odf_read_context & odfContext = root()->odf_context(); - std::vector instances; - - instances.push_back(odfContext.styleContainer().style_default_by_type(odf_types::style_family::Presentation)); - instances.push_back(odfContext.styleContainer().style_by_name(L"Default", odf_types::style_family::Presentation, false)); - - odf_reader::text_format_properties_ptr textFormatProperties = calc_text_properties_content(instances); - odf_reader::paragraph_format_properties parFormatProperties = calc_paragraph_properties_content(instances); - - process_masters_ = false; -} + instances.push_back(odfContext.styleContainer().style_default_by_type(odf_types::style_family::Presentation)); + instances.push_back(odfContext.styleContainer().style_by_name(L"Default", odf_types::style_family::Presentation, false)); -void pptx_conversion_context::end_document() -{ - for (size_t i = 0; i < slideMasters_.size(); i++) - { - pptx_xml_slideMaster_ptr& slideM = slideMasters_[i]; + odf_reader::text_format_properties_ptr textFormatProperties = calc_text_properties_content(instances); + odf_reader::paragraph_format_properties parFormatProperties = calc_paragraph_properties_content(instances); - package::slide_content_ptr content = package::slide_content::create(); + process_masters_ = false; + } - slideM->write_to(content->content()); - content->add_rels(slideM->Rels());//media & links rels + void pptx_conversion_context::end_document() + { + for (size_t i = 0; i < slideMasters_.size(); i++) + { + pptx_xml_slideMaster_ptr& slideM = slideMasters_[i]; - output_document_->get_ppt_files().add_slideMaster(content);//slideMaster.xml + package::slide_content_ptr content = package::slide_content::create(); - CP_XML_WRITER(presentation_.slideMastersData())//presentation.xml - { - CP_XML_NODE(L"p:sldMasterId") - { - CP_XML_ATTR(L"id", 0x80000000 + last_uniq_big_id++); - CP_XML_ATTR(L"r:id", slideM->rId()); - } - } - } - if (!slideMasters_.empty()) - presentation_.slidesProperties() << slideMasters_[0]->Sizes().str(); + slideM->write_to(content->content()); + content->add_rels(slideM->Rels());//media & links rels -//////////////////////////////////////////////////////////////////////////////////////////////////// - for (size_t i = 0; i < slides_.size(); i++) - { - pptx_xml_slide_ptr& slide = slides_[i]; + output_document_->get_ppt_files().add_slideMaster(content);//slideMaster.xml - package::slide_content_ptr content = package::slide_content::create(); + CP_XML_WRITER(presentation_.slideMastersData())//presentation.xml + { + CP_XML_NODE(L"p:sldMasterId") + { + CP_XML_ATTR(L"id", 0x80000000 + last_uniq_big_id++); + CP_XML_ATTR(L"r:id", slideM->rId()); + } + } + } + if (!slideMasters_.empty()) + presentation_.slidesProperties() << slideMasters_[0]->Sizes().str(); - slide->write_to(content->content()); - content->add_rels(slide->Rels());//media & links rels + //////////////////////////////////////////////////////////////////////////////////////////////////// + for (size_t i = 0; i < slides_.size(); i++) + { + pptx_xml_slide_ptr& slide = slides_[i]; - output_document_->get_ppt_files().add_slide(content);//slide.xml + package::slide_content_ptr content = package::slide_content::create(); - CP_XML_WRITER(presentation_.slidesData())//presentation.xml - { - CP_XML_NODE(L"p:sldId") - { - CP_XML_ATTR(L"id", 0x100 + i); - CP_XML_ATTR(L"r:id", slide->rId()); - } - } - } -//---------------------------------------------------------------------------------- - for (size_t i = 0; i < slideLayouts_.size(); i++) - { - pptx_xml_slideLayout_ptr& slideL = slideLayouts_[i]; + slide->write_to(content->content()); + content->add_rels(slide->Rels());//media & links rels - package::slide_content_ptr content = package::slide_content::create(); + output_document_->get_ppt_files().add_slide(content);//slide.xml - slideL->write_to(content->content()); - content->add_rels(slideL->Rels());//media & links rels + CP_XML_WRITER(presentation_.slidesData())//presentation.xml + { + CP_XML_NODE(L"p:sldId") + { + CP_XML_ATTR(L"id", 0x100 + i); + CP_XML_ATTR(L"r:id", slide->rId()); + } + } + } + //---------------------------------------------------------------------------------- + for (size_t i = 0; i < slideLayouts_.size(); i++) + { + pptx_xml_slideLayout_ptr& slideL = slideLayouts_[i]; - output_document_->get_ppt_files().add_slideLayout(content);//slideMaster.xml - } -//---------------------------------------------------------------------------------- - for (size_t i = 0; i < notes_.size(); i++) - { - pptx_xml_slideNotes_ptr& slideN = notes_[i]; + package::slide_content_ptr content = package::slide_content::create(); - package::slide_content_ptr content = package::slide_content::create(); + slideL->write_to(content->content()); + content->add_rels(slideL->Rels());//media & links rels - slideN->write_to(content->content()); - content->add_rels(slideN->Rels());//media & links rels + output_document_->get_ppt_files().add_slideLayout(content);//slideMaster.xml + } + //---------------------------------------------------------------------------------- + for (size_t i = 0; i < notes_.size(); i++) + { + pptx_xml_slideNotes_ptr& slideN = notes_[i]; - output_document_->get_ppt_files().add_notes(content); - } - if (slideNotesMaster_) - { - package::slide_content_ptr content = package::slide_content::create(); + package::slide_content_ptr content = package::slide_content::create(); - slideNotesMaster_->write_to(content->content()); - content->add_rels(slideNotesMaster_->Rels());//media & links rels + slideN->write_to(content->content()); + content->add_rels(slideN->Rels());//media & links rels - output_document_->get_ppt_files().add_notesMaster(content); - - CP_XML_WRITER(presentation_.slideNotesMastersData())//presentation.xml + output_document_->get_ppt_files().add_notes(content); + } + if (slideNotesMaster_) { - CP_XML_NODE(L"p:notesMasterId") + package::slide_content_ptr content = package::slide_content::create(); + + slideNotesMaster_->write_to(content->content()); + content->add_rels(slideNotesMaster_->Rels());//media & links rels + + output_document_->get_ppt_files().add_notesMaster(content); + + CP_XML_WRITER(presentation_.slideNotesMastersData())//presentation.xml { - CP_XML_ATTR(L"r:id", slideNotesMaster_->rId()); + CP_XML_NODE(L"p:notesMasterId") + { + CP_XML_ATTR(L"r:id", slideNotesMaster_->rId()); + } } } - } - //else + //else pptx_serialize_size(current_presentation().slidesNotesProperties(), 6858000, 9144000, L"p:notesSz"); -//////////////////////////////////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////////////////////////////////// + + for (size_t i = 0; i < charts_.size(); i++) + { + package::chart_content_ptr content = package::chart_content::create(); + + charts_[i]->serialize(content->content()); + charts_[i]->dump_rels(content->get_rel_file()->get_rels()); + + output_document_->get_ppt_files().add_charts(content); + + } + //////////////////////////////////////////////////////////////////////////////////////////////////////////// + for (size_t i = 0; i < themes_.size(); i++) + { + output_document_->get_ppt_files().add_theme(themes_[i]); - for (size_t i = 0; i < charts_.size(); i++) - { - package::chart_content_ptr content = package::chart_content::create(); + } + package::ppt_comments_files_ptr comments = package::ppt_comments_files::create(comments_context_handle_.content()); - charts_[i]->serialize(content->content()); - charts_[i]->dump_rels(content->get_rel_file()->get_rels()); + output_document_->get_ppt_files().set_presentation(presentation_); + output_document_->get_ppt_files().set_comments(comments); + output_document_->get_ppt_files().set_authors_comments(authors_comments_); + output_document_->get_ppt_files().set_media(get_mediaitems()); - output_document_->get_ppt_files().add_charts(content); - + output_document_->get_content_types_file().set_media(get_mediaitems()); } -//////////////////////////////////////////////////////////////////////////////////////////////////////////// - for (size_t i=0; i < themes_.size(); i++) - { - output_document_->get_ppt_files().add_theme(themes_[i]); - + + void pptx_conversion_context::start_body() + { + } - package::ppt_comments_files_ptr comments = package::ppt_comments_files::create(comments_context_handle_.content()); - - output_document_->get_ppt_files().set_presentation (presentation_); - output_document_->get_ppt_files().set_comments (comments); - output_document_->get_ppt_files().set_authors_comments (authors_comments_); - output_document_->get_ppt_files().set_media (get_mediaitems()); - output_document_->get_content_types_file().set_media(get_mediaitems()); -} + void pptx_conversion_context::end_body() + { + } + pptx_xml_slideNotesMaster& pptx_conversion_context::current_notesMaster() + { + if (slideNotesMaster_) + { + return *slideNotesMaster_; + } + else + { + throw std::runtime_error("internal error"); + } + } + pptx_xml_slideNotes& pptx_conversion_context::current_notes() + { + if (!notes_.empty()) + { + return *notes_.back().get(); + } + else + { + throw std::runtime_error("internal error"); + } + } + pptx_xml_slide& pptx_conversion_context::current_slide() + { + if (!slides_.empty()) + { + return *slides_.back().get(); + } + else + { + throw std::runtime_error("internal error"); + } + } + pptx_xml_slideLayout& pptx_conversion_context::current_layout() + { + if (!slideLayouts_.empty()) + { + return *slideLayouts_.back().get(); + } + else + { + throw std::runtime_error("internal error"); + } + } + pptx_xml_theme& pptx_conversion_context::current_theme() + { + if (!themes_.empty()) + { + return *themes_.back().get(); + } + else + { + throw std::runtime_error("internal error"); + } + } + pptx_xml_presentation& pptx_conversion_context::current_presentation() + { + return presentation_; + } -void pptx_conversion_context::start_body() -{} - -void pptx_conversion_context::end_body() -{} -pptx_xml_slideNotesMaster & pptx_conversion_context::current_notesMaster() -{ - if (slideNotesMaster_) - { - return *slideNotesMaster_; - } - else - { - throw std::runtime_error("internal error"); - } -} -pptx_xml_slideNotes & pptx_conversion_context::current_notes() -{ - if (!notes_.empty()) - { - return *notes_.back().get(); - } - else - { - throw std::runtime_error("internal error"); - } -} -pptx_xml_slide & pptx_conversion_context::current_slide() -{ - if (!slides_.empty()) - { - return *slides_.back().get(); - } - else - { - throw std::runtime_error("internal error"); - } -} -pptx_xml_slideLayout & pptx_conversion_context::current_layout() -{ - if (!slideLayouts_.empty()) - { - return *slideLayouts_.back().get(); - } - else - { - throw std::runtime_error("internal error"); - } -} -pptx_xml_theme & pptx_conversion_context::current_theme() -{ - if (!themes_.empty()) - { - return *themes_.back().get(); - } - else - { - throw std::runtime_error("internal error"); - } -} -pptx_xml_presentation & pptx_conversion_context::current_presentation() -{ - return presentation_; -} + oox_chart_context& pptx_conversion_context::current_chart() + { + if (!charts_.empty()) + { + return *charts_.back().get(); + } + else + { + throw std::runtime_error("internal error"); + } + } + pptx_xml_slideMaster& pptx_conversion_context::current_master() + { + if (!slideMasters_.empty()) + { + return *slideMasters_.back().get(); + } + else + { + throw std::runtime_error("internal error"); + } + } + void pptx_conversion_context::create_new_slide(std::wstring const& name) + { + pptx_xml_slide_ptr s = pptx_xml_slide::create(name, slides_.size() + 1); + slides_.push_back(s); + } + void pptx_conversion_context::create_new_slideNotes() + { + pptx_xml_slideNotes_ptr s = pptx_xml_slideNotes::create(notes_.size() + 1); + notes_.push_back(s); + } + void pptx_conversion_context::create_new_slideNotesMaster() + { + slideNotesMaster_ = pptx_xml_slideNotesMaster::create(); + } + void pptx_conversion_context::create_new_slideLayout(int id) + { + pptx_xml_slideLayout_ptr s = pptx_xml_slideLayout::create(id); + slideLayouts_.push_back(s); + } + void pptx_conversion_context::create_new_slideMaster(int id) + { + pptx_xml_slideMaster_ptr s = pptx_xml_slideMaster::create(id); + slideMasters_.push_back(s); + } + bool pptx_conversion_context::start_page(const std::wstring& pageName, const std::wstring& pageStyleName, + const std::wstring& pageLayoutName, + const std::wstring& pageMasterName) + { + create_new_slide(pageName); + get_slide_context().start_slide();//pageName, pageStyleName); + get_slide_context().get_animation_context().clear(); -oox_chart_context & pptx_conversion_context::current_chart() -{ - if (!charts_.empty()) - { - return *charts_.back().get(); - } - else - { - throw std::runtime_error("internal error"); - } -} -pptx_xml_slideMaster & pptx_conversion_context::current_master() -{ - if (!slideMasters_.empty()) - { - return *slideMasters_.back().get(); - } - else - { - throw std::runtime_error("internal error"); - } -} -void pptx_conversion_context::create_new_slide(std::wstring const & name) -{ - pptx_xml_slide_ptr s = pptx_xml_slide::create(name,slides_.size() + 1); - slides_.push_back(s); -} -void pptx_conversion_context::create_new_slideNotes() -{ - pptx_xml_slideNotes_ptr s = pptx_xml_slideNotes::create( notes_.size() + 1); - notes_.push_back(s); -} -void pptx_conversion_context::create_new_slideNotesMaster() -{ - slideNotesMaster_ = pptx_xml_slideNotesMaster::create(); -} -void pptx_conversion_context::create_new_slideLayout(int id) -{ - pptx_xml_slideLayout_ptr s = pptx_xml_slideLayout::create(id); - slideLayouts_.push_back(s); -} -void pptx_conversion_context::create_new_slideMaster(int id) -{ - pptx_xml_slideMaster_ptr s = pptx_xml_slideMaster::create(id); - slideMasters_.push_back(s); -} -bool pptx_conversion_context::start_page(const std::wstring & pageName, const std::wstring & pageStyleName, - const std::wstring & pageLayoutName, - const std::wstring & pageMasterName) -{ - create_new_slide(pageName); - get_slide_context().start_slide();//pageName, pageStyleName); + current_master_page_name_ = pageMasterName; + current_layout_page_name_ = pageLayoutName; - current_master_page_name_ = pageMasterName; - current_layout_page_name_ = pageLayoutName; - - //const std::wstring masterPageNameLayout = root()->odf_context().pageLayoutContainer().page_layout_name_by_style(current_master_page_name_); + //const std::wstring masterPageNameLayout = root()->odf_context().pageLayoutContainer().page_layout_name_by_style(current_master_page_name_); - std::pair layout_id = - root()->odf_context().styleContainer().presentation_layouts().add_or_find(pageLayoutName,pageMasterName); + std::pair layout_id = + root()->odf_context().styleContainer().presentation_layouts().add_or_find(pageLayoutName, pageMasterName); - current_slide().Rels().add(relationship(layout_id.second, L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout", - std::wstring(L"../slideLayouts/slideLayout") + std::to_wstring(layout_id.first) + L".xml")); + current_slide().Rels().add(relationship(layout_id.second, L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout", + std::wstring(L"../slideLayouts/slideLayout") + std::to_wstring(layout_id.first) + L".xml")); - return true; -} + return true; + } -bool pptx_conversion_context::start_layout(int layout_index) -{ - if (layout_index >=0) + bool pptx_conversion_context::start_layout(int layout_index) { - odf_reader::presentation_layouts_instance & layouts = root()->odf_context().styleContainer().presentation_layouts(); + if (layout_index >= 0) + { + odf_reader::presentation_layouts_instance& layouts = root()->odf_context().styleContainer().presentation_layouts(); - create_new_slideLayout(layouts.content[layout_index].Id); - - get_slide_context().start_slide();//layouts.content[layout_index].layout_name, L"");//????? + create_new_slideLayout(layouts.content[layout_index].Id); - current_master_page_name_ = layouts.content[layout_index].master_name; - current_layout_page_name_ = L""; - - std::pair master_id = //std::pair(1,L"smId1"); + get_slide_context().start_slide();//layouts.content[layout_index].layout_name, L"");//????? + + current_master_page_name_ = layouts.content[layout_index].master_name; + current_layout_page_name_ = L""; + + current_layout().set_name(current_master_page_name_); + + std::pair master_id = //std::pair(1, L"smId1"); root()->odf_context().styleContainer().presentation_masters().add_or_find(layouts.content[layout_index].master_name); - root()->odf_context().styleContainer().presentation_masters().add_layout_to(layouts.content[layout_index].master_name,layouts.content[layout_index]); + root()->odf_context().styleContainer().presentation_masters().add_layout_to(layouts.content[layout_index].master_name, layouts.content[layout_index]); - current_layout().Rels().add(relationship(L"smId1"/*master_id.second*/, L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideMaster", - std::wstring(L"../slideMasters/slideMaster") + std::to_wstring(master_id.first) + L".xml")); + current_layout().Rels().add(relationship(L"smId1"/*master_id.second*/, L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideMaster", + std::wstring(L"../slideMasters/slideMaster") + std::to_wstring(master_id.first) + L".xml")); - // + // + } + else//общий шаблон (насильно пропишем к темам несоответствующие шалоны) + { + } + + //layout type + + // + //1375 + //1376 + //1377 + //1378 + //1379 + //1380 + //1381 + //1382 + //1383 + //1384 + //1385 + //1386 + //1387 + //1388 + //1389 + //1390 + //1391 + //1392 + //1393 + //1394 + //1395 + //1396 + //1397 + //1398 + //1399 + //1400 + //1401 + //1402 + //1403 + //1404 + //1405 ---------------------------------- !!!!!!!!!!!!! + //1406 + //1407 + //1408 + //1409 + + return true; } - else//общий шаблон (насильно пропишем к темам несоответствующие шалоны) - { - } - -//layout type - -// -//1375 -//1376 -//1377 -//1378 -//1379 -//1380 -//1381 -//1382 -//1383 -//1384 -//1385 -//1386 -//1387 -//1388 -//1389 -//1390 -//1391 -//1392 -//1393 -//1394 -//1395 -//1396 -//1397 -//1398 -//1399 -//1400 -//1401 -//1402 -//1403 -//1404 -//1405 ---------------------------------- !!!!!!!!!!!!! -//1406 -//1407 -//1408 -//1409 - - return true; -} -bool pptx_conversion_context::start_master(int master_index) -{ - odf_reader::presentation_masters_instance & masters = root()->odf_context().styleContainer().presentation_masters(); + bool pptx_conversion_context::start_master(int master_index) + { + odf_reader::presentation_masters_instance& masters = root()->odf_context().styleContainer().presentation_masters(); + + create_new_slideMaster(masters.content[master_index].Id); + + get_slide_context().start_slide(); - create_new_slideMaster(masters.content[master_index].Id); - - get_slide_context().start_slide(); + current_master_page_name_ = L""; + current_layout_page_name_ = L""; + + process_theme(masters.content[master_index].master_name);//add default theme - одинаковые но под разными именами + current_master().add_theme(current_theme().id(), L"tId1"); + + for (size_t i = 0; i < masters.content[master_index].layouts.size(); i++) + { + current_master().add_layout(masters.content[master_index].layouts[i].Id, masters.content[master_index].layouts[i].rId, 0x80000000 + last_uniq_big_id++); + } + + //---------------------------------------------------------------------------------- + //размеры страниц в презентации + const std::wstring pageProperties = root()->odf_context().pageLayoutContainer().page_layout_name_by_style(masters.content[master_index].master_name); - current_master_page_name_ = L""; - current_layout_page_name_ = L""; - - process_theme(masters.content[master_index].master_name);//add default theme - одинаковые но под разными именами - current_master().add_theme(current_theme().id(), L"tId1"); + odf_reader::page_layout_instance* pages_layouts = root()->odf_context().pageLayoutContainer().page_layout_by_name(pageProperties); - for (size_t i = 0; i < masters.content[master_index].layouts.size(); i++) + if (pages_layouts) + pages_layouts->pptx_serialize(current_master().Sizes(), *this); + + return true; + } + void pptx_conversion_context::end_page() { - current_master().add_layout(masters.content[master_index].layouts[i].Id, masters.content[master_index].layouts[i].rId, 0x80000000 + last_uniq_big_id++); + if (!get_comments_context().empty()) + { + std::wstringstream strm; + get_comments_context().serialize(strm); + + const std::pair commentsName = + comments_context_handle_.add_comments_xml(strm.str(), get_comments_context().get_comments()); + + get_slide_context().add_rels(false, commentsName.second, L"../comments/" + commentsName.first, typeComment); + } + + get_slide_context().serialize_background(current_slide().Background()); + get_slide_context().serialize_objects(current_slide().Data()); + get_slide_context().serialize_animations(current_slide().Timing()); + + { + // NOTE: При использовании operator<< потока буст пушит туда лишний пробел перед значением. + // С этим пробелом наш редактор onlyoffice на распознает значение. + // Example: + // ppt_y + // ppt_y + // TODO: Figure out how to push value without redundant space character + current_slide().remove_timing_redundant_space(); + } + + get_slide_context().dump_rels(current_slide().Rels());//hyperlinks, mediaitems, ... + + get_slide_context().end_slide(); } + bool pptx_conversion_context::start_page_notes() + { + create_new_slideNotes(); -//---------------------------------------------------------------------------------- -//размеры страниц в презентации - const std::wstring pageProperties = root()->odf_context().pageLayoutContainer().page_layout_name_by_style(masters.content[master_index].master_name); + current_slide().Rels().add(relationship(notes_.back()->rId(), L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/notesSlide", + L"../notesSlides/notesSlide" + std::to_wstring(notes_.size()) + L".xml")); - odf_reader::page_layout_instance *pages_layouts = root()->odf_context().pageLayoutContainer().page_layout_by_name(pageProperties); - - if (pages_layouts) - pages_layouts->pptx_serialize(current_master().Sizes(), *this); + get_slide_context().start_slide(); - return true; -} -void pptx_conversion_context::end_page() -{ - if (!get_comments_context().empty()) - { - std::wstringstream strm; - get_comments_context().serialize(strm); - - const std::pair commentsName = - comments_context_handle_.add_comments_xml(strm.str(), get_comments_context().get_comments() ); - - get_slide_context().add_rels(false, commentsName.second, L"../comments/" + commentsName.first, typeComment); - } - - get_slide_context().serialize_background(current_slide().Background()); - get_slide_context().serialize_objects (current_slide().Data()); - get_slide_context().serialize_animations(current_slide().Timing()); - - get_slide_context().dump_rels(current_slide().Rels());//hyperlinks, mediaitems, ... - - get_slide_context().end_slide(); -} -bool pptx_conversion_context::start_page_notes() -{ - create_new_slideNotes( ); - - current_slide().Rels().add(relationship(notes_.back()->rId(), L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/notesSlide", - L"../notesSlides/notesSlide" + std::to_wstring(notes_.size()) + L".xml")); - - get_slide_context().start_slide(); - - current_notes().Rels().add(relationship(L"nId1", L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/slide", - L"../slides/slide" + std::to_wstring(slides_.size()) + L".xml")); - - return true; -} + current_notes().Rels().add(relationship(L"nId1", L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/slide", + L"../slides/slide" + std::to_wstring(slides_.size()) + L".xml")); -void pptx_conversion_context::end_page_notes() -{ - get_slide_context().serialize_background(current_notes().Background()); - get_slide_context().serialize_objects(current_notes().Data()); + return true; + } - get_slide_context().dump_rels(current_notes().Rels());//hyperlinks, mediaitems, ... + void pptx_conversion_context::end_page_notes() + { + get_slide_context().serialize_background(current_notes().Background()); + get_slide_context().serialize_objects(current_notes().Data()); - get_slide_context().end_slide(); -} -bool pptx_conversion_context::start_master_notes() -{ - create_new_slideNotesMaster( ); - - get_slide_context().start_slide(); + get_slide_context().dump_rels(current_notes().Rels());//hyperlinks, mediaitems, ... - process_theme(L"");//add default theme - одинаковые но под разными именами - current_notesMaster().add_theme(current_theme().id(), L"tId1"); + get_slide_context().end_slide(); + } + bool pptx_conversion_context::start_master_notes() + { + create_new_slideNotesMaster(); - get_slide_context().start_slide(); - return true; -} + get_slide_context().start_slide(); -void pptx_conversion_context::end_master_notes() -{ - get_slide_context().serialize_background(current_notesMaster().Background()); - get_slide_context().serialize_objects(current_notesMaster().Data()); + process_theme(L"");//add default theme - одинаковые но под разными именами + current_notesMaster().add_theme(current_theme().id(), L"tId1"); - get_slide_context().dump_rels(current_notesMaster().Rels());//hyperlinks, mediaitems, ... + get_slide_context().start_slide(); + return true; + } - get_slide_context().end_slide(); - - for (size_t i = 0; i < notes_.size(); i++) + void pptx_conversion_context::end_master_notes() { - notes_[i]->Rels().add(relationship(L"nmId1", - L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/notesMaster", - L"../notesMasters/notesMaster1.xml")); + get_slide_context().serialize_background(current_notesMaster().Background()); + get_slide_context().serialize_objects(current_notesMaster().Data()); + + get_slide_context().dump_rels(current_notesMaster().Rels());//hyperlinks, mediaitems, ... + + get_slide_context().end_slide(); + + for (size_t i = 0; i < notes_.size(); i++) + { + notes_[i]->Rels().add(relationship(L"nmId1", + L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/notesMaster", + L"../notesMasters/notesMaster1.xml")); + } } -} -void pptx_conversion_context::end_layout() -{ - get_slide_context().serialize_objects(current_layout().Data()); - - get_slide_context().dump_rels(current_layout().Rels());//hyperlinks, mediaitems, ... + void pptx_conversion_context::end_layout() + { + get_slide_context().process_drawings(); - get_slide_context().end_slide(); -} + get_slide_context().serialize_objects(current_layout().Data()); + + get_slide_context().dump_rels(current_layout().Rels());//hyperlinks, mediaitems, ... + + get_slide_context().end_slide(); + } -std::pair pptx_conversion_context::add_author_comments(std::wstring author) -{ - if (!authors_comments_) + std::pair pptx_conversion_context::add_author_comments(std::wstring author) { - authors_comments_ = pptx_xml_authors_comments::create(); - if (!authors_comments_)return std::pair(-1,-1); + if (!authors_comments_) + { + authors_comments_ = pptx_xml_authors_comments::create(); + if (!authors_comments_)return std::pair(-1, -1); + } + + return authors_comments_->add_or_find(author); } - return authors_comments_->add_or_find(author); -} + void pptx_conversion_context::end_master() + { + get_slide_context().process_drawings(); -void pptx_conversion_context::end_master() -{ - get_slide_context().serialize_background (current_master().Background(),true); - get_slide_context().serialize_objects (current_master().Data()); - get_slide_context().serialize_HeaderFooter (current_master().DataExtra()); - - get_slide_context().dump_rels(current_master().Rels());//hyperlinks, mediaitems, ... + get_slide_context().serialize_background(current_master().Background(), true); + get_slide_context().serialize_objects(current_master().Data()); + get_slide_context().serialize_HeaderFooter(current_master().DataExtra()); - get_slide_context().end_slide(); -} -void pptx_conversion_context::start_theme(std::wstring & name) -{ - themes_.push_back(pptx_xml_theme::create(name,themes_.size()+1)); -} -void pptx_conversion_context::end_theme() -{ -} -void pptx_conversion_context::start_office_presentation() -{ -} + get_slide_context().dump_rels(current_master().Rels());//hyperlinks, mediaitems, ... -void pptx_conversion_context::end_office_presentation() -{ -} -void pptx_conversion_context::start_chart(std::wstring name) -{ - charts_.push_back(oox_chart_context_ptr(new oox_chart_context(get_mediaitems(), name))); - //добавляем новую форму для диаграммы - //в ней будет информационная часть - и она пишется каждый раз в свою xml (их - по числу диаграмм) - //этот контекст нужно передавать в файл + get_slide_context().end_slide(); + } + void pptx_conversion_context::start_theme(std::wstring& name) + { + themes_.push_back(pptx_xml_theme::create(name, themes_.size() + 1)); + } + void pptx_conversion_context::end_theme() + { + } + void pptx_conversion_context::start_office_presentation() + { + } -} -void pptx_conversion_context::end_chart() -{ - //current_chart().set_drawing_link(current_sheet().get_drawing_link()); - //излишняя инфа -} -void pptx_conversion_context::add_jsaProject(const std::string &content) -{ - if (content.empty()) return; - - output_document_->get_ppt_files().add_jsaProject(content); - output_document_->get_content_types_file().add_or_find_default(L"bin"); -} -} + void pptx_conversion_context::end_office_presentation() + { + } + void pptx_conversion_context::start_chart(std::wstring name) + { + charts_.push_back(oox_chart_context_ptr(new oox_chart_context(get_mediaitems(), name))); + //добавляем новую форму для диаграммы + //в ней будет информационная часть - и она пишется каждый раз в свою xml (их - по числу диаграмм) + //этот контекст нужно передавать в файл + + } + void pptx_conversion_context::end_chart() + { + //current_chart().set_drawing_link(current_sheet().get_drawing_link()); + //излишняя инфа + } + void pptx_conversion_context::add_jsaProject(const std::string& content) + { + if (content.empty()) return; + + output_document_->get_ppt_files().add_jsaProject(content); + output_document_->get_content_types_file().add_or_find_default(L"bin"); + } + } } diff --git a/OdfFile/Reader/Converter/pptx_conversion_context.h b/OdfFile/Reader/Converter/pptx_conversion_context.h index 5160e677ba3..6dcaf6e1169 100644 --- a/OdfFile/Reader/Converter/pptx_conversion_context.h +++ b/OdfFile/Reader/Converter/pptx_conversion_context.h @@ -133,6 +133,9 @@ class pptx_conversion_context : boost::noncopyable pptx_table_context & get_table_context() { return pptx_table_context_; } + void add_page_name(const std::wstring& page_name); + const std::vector& get_page_names() const; + mediaitems_ptr & get_mediaitems() { return pptx_slide_context_.get_mediaitems(); } //void start_hyperlink(const std::wstring & styleName); @@ -171,6 +174,8 @@ class pptx_conversion_context : boost::noncopyable std::vector slideMasters_; std::vector slideLayouts_; std::vector themes_; + + std::vector page_names_; pptx_xml_slideNotesMaster_ptr slideNotesMaster_; pptx_xml_authors_comments_ptr authors_comments_; @@ -180,8 +185,6 @@ class pptx_conversion_context : boost::noncopyable std::wstring current_layout_page_name_; pptx_comments_context_handle comments_context_handle_; - - }; } diff --git a/OdfFile/Reader/Converter/pptx_drawing.cpp b/OdfFile/Reader/Converter/pptx_drawing.cpp index 9bc2b09fe7e..144f0fa0f77 100644 --- a/OdfFile/Reader/Converter/pptx_drawing.cpp +++ b/OdfFile/Reader/Converter/pptx_drawing.cpp @@ -58,7 +58,31 @@ void pptx_serialize_text(std::wostream & strm, _pptx_drawing & val) { CP_XML_NODE(L"a:p")//empty a:p { - CP_XML_NODE(L"a:endParaRPr"); + CP_XML_NODE(L"a:endParaRPr") + { + _CP_OPT(double) font_size; + odf_reader::GetProperty(val.additional, L"placeholder-font-size", font_size); + if (font_size) + CP_XML_ATTR(L"sz", *font_size * 100); + + _CP_OPT(bool) bold_text; + odf_reader::GetProperty(val.additional, L"placeholder-font-bold", bold_text); + if (bold_text && *bold_text) + CP_XML_ATTR(L"b", 1); + + _CP_OPT(std::wstring) text_color; + odf_reader::GetProperty(val.additional, L"placeholder-text-color", text_color); + if (text_color) + { + CP_XML_NODE(L"a:solidFill") + { + CP_XML_NODE(L"a:srgbClr") + { + CP_XML_ATTR_OPT(L"val", text_color); + } + } + } + } } } } @@ -76,7 +100,8 @@ void pptx_serialize_image(std::wostream & strm, _pptx_drawing & val) { CP_XML_ATTR(L"id", val.id); CP_XML_ATTR(L"name", val.name); - + if (val.hidden) CP_XML_ATTR(L"hidden", true); + oox_serialize_action(CP_XML_STREAM(), val.action); } @@ -123,6 +148,7 @@ void pptx_serialize_media(std::wostream & strm, _pptx_drawing & val) { CP_XML_ATTR(L"id", val.id); CP_XML_ATTR(L"name", val.name); + if (val.hidden) CP_XML_ATTR(L"hidden", true); oox_serialize_action(CP_XML_STREAM(), val.action); @@ -210,6 +236,7 @@ void pptx_serialize_shape(std::wostream & strm, _pptx_drawing & val) { CP_XML_ATTR(L"id", val.id);//числовое значение val.rId CP_XML_ATTR(L"name", val.name); + if (val.hidden) CP_XML_ATTR(L"hidden", true); oox_serialize_action(CP_XML_STREAM(),val.action); } @@ -223,16 +250,24 @@ void pptx_serialize_shape(std::wostream & strm, _pptx_drawing & val) } CP_XML_NODE(L"p:nvPr") { - if (val.place_holder_type_.length()>0) + if (val.place_holder_type_.length() > 0) { CP_XML_NODE(L"p:ph") { - CP_XML_ATTR(L"type",val.place_holder_type_); - if (val.place_holder_idx_ > 0) CP_XML_ATTR(L"idx", val.place_holder_idx_); - - if (val.place_holder_type_ == L"dt") { CP_XML_ATTR(L"sz", L"half"); } - if (val.place_holder_type_ == L"ftr") { CP_XML_ATTR(L"sz", L"quarter"); } - if (val.place_holder_type_ == L"sldNum"){ CP_XML_ATTR(L"sz", L"quarter"); } + CP_XML_ATTR(L"type", val.place_holder_type_); + + if (val.place_holder_type_ == L"dt") { CP_XML_ATTR(L"sz", L"half"); } + if (val.place_holder_type_ == L"ftr") { CP_XML_ATTR(L"sz", L"quarter"); } + if (val.place_holder_type_ == L"sldNum") { CP_XML_ATTR(L"sz", L"quarter"); } + + CP_XML_ATTR(L"idx", (uint32_t)val.place_holder_idx_); + } + } + else if (val.place_holder_) + { + CP_XML_NODE(L"p:ph") + { + CP_XML_ATTR(L"idx", (uint32_t)val.place_holder_idx_); } } } @@ -242,19 +277,19 @@ void pptx_serialize_shape(std::wostream & strm, _pptx_drawing & val) _CP_OPT(bool) bNoRect; odf_reader::GetProperty(val.additional,L"no_rect",bNoRect); + if (val.cx != 0 || val.cy != 0) //layout + { + val.serialize_xfrm(CP_XML_STREAM(), L"a", true); + } if (!bNoRect) - { - if (val.cx != 0 || val.cy != 0) //layout - { - val.serialize_xfrm(CP_XML_STREAM(), L"a", true); - } + { val.serialize_shape(CP_XML_STREAM()); oox_serialize_ln(CP_XML_STREAM(), val.additional); oox_serialize_effects(CP_XML_STREAM(), val.additional); } } - pptx_serialize_text(CP_XML_STREAM(), val); + pptx_serialize_text(CP_XML_STREAM(), val); } } // CP_XML_WRITER } @@ -270,6 +305,7 @@ void pptx_serialize_connector(std::wostream & strm, _pptx_drawing & val) { CP_XML_ATTR(L"id", val.id);//числовое значение val.rId CP_XML_ATTR(L"name", val.name); + if (val.hidden) CP_XML_ATTR(L"hidden", true); oox_serialize_action(CP_XML_STREAM(), val.action); } @@ -280,10 +316,22 @@ void pptx_serialize_connector(std::wostream & strm, _pptx_drawing & val) //{ // CP_XML_ATTR(L"noGrp", 1); //} + + CP_XML_NODE(L"a:stCxn") + { + CP_XML_ATTR(L"id", val.start_connection_shape_id); + CP_XML_ATTR(L"idx", val.start_connection_index); + } + + CP_XML_NODE(L"a:endCxn") + { + CP_XML_ATTR(L"id", val.end_connection_shape_id); + CP_XML_ATTR(L"idx", val.end_connection_index); + } } CP_XML_NODE(L"p:nvPr") { - if (val.place_holder_type_.length()>0) + if (false == val.place_holder_type_.empty()) { CP_XML_NODE(L"p:ph") { @@ -314,7 +362,7 @@ void pptx_serialize_connector(std::wostream & strm, _pptx_drawing & val) oox_serialize_effects(CP_XML_STREAM(), val.additional); } } - pptx_serialize_text(CP_XML_STREAM(), val); + pptx_serialize_text(CP_XML_STREAM(), val); } } // CP_XML_WRITER } @@ -330,7 +378,8 @@ void pptx_serialize_chart(std::wostream & strm, _pptx_drawing & val) { CP_XML_ATTR(L"id", val.id); CP_XML_ATTR(L"name", val.name); - } + if (val.hidden) CP_XML_ATTR(L"hidden", true); + } CP_XML_NODE(L"p:cNvGraphicFramePr"); CP_XML_NODE(L"p:nvPr"); @@ -367,7 +416,8 @@ void pptx_serialize_table(std::wostream & strm, _pptx_drawing & val) { CP_XML_ATTR(L"id", val.id); CP_XML_ATTR(L"name", val.name); - } + if (val.hidden) CP_XML_ATTR(L"hidden", true); + } CP_XML_NODE(L"p:cNvGraphicFramePr"); CP_XML_NODE(L"p:nvPr"); @@ -408,7 +458,8 @@ void pptx_serialize_object(std::wostream & strm, _pptx_drawing & val) { CP_XML_ATTR(L"id", val.id); CP_XML_ATTR(L"name", val.name); - } + if (val.hidden) CP_XML_ATTR(L"hidden", true); + } CP_XML_NODE(L"p:cNvGraphicFramePr"); CP_XML_NODE(L"p:nvPr"); @@ -444,9 +495,9 @@ void _pptx_drawing::serialize(std::wostream & strm) { if (type == typeShape) { - //if (connector) only for ms prst connectors, but not custom!! - // pptx_serialize_connector(strm, *this); - //else + if (connector) // only for ms prst connectors, but not custom!! + pptx_serialize_connector(strm, *this); + else pptx_serialize_shape(strm, *this); } else if (type == typeImage) diff --git a/OdfFile/Reader/Converter/pptx_drawing.h b/OdfFile/Reader/Converter/pptx_drawing.h index cb734d7f117..05b3bb73714 100644 --- a/OdfFile/Reader/Converter/pptx_drawing.h +++ b/OdfFile/Reader/Converter/pptx_drawing.h @@ -45,6 +45,7 @@ class _pptx_drawing : public _oox_drawing public: _pptx_drawing(): _oox_drawing(), place_holder_idx_(-1) {} + bool place_holder_; std::wstring place_holder_type_; int place_holder_idx_; diff --git a/OdfFile/Reader/Converter/pptx_drawings.cpp b/OdfFile/Reader/Converter/pptx_drawings.cpp index d2441de4c3b..b60312ccc25 100644 --- a/OdfFile/Reader/Converter/pptx_drawings.cpp +++ b/OdfFile/Reader/Converter/pptx_drawings.cpp @@ -30,13 +30,12 @@ * */ -#include #include +#include #include "oox_rels.h" #include "pptx_drawings.h" -#include "pptx_drawing.h" namespace cpdoccore { namespace oox { @@ -66,12 +65,41 @@ class pptx_drawings::Impl } for (size_t i = 0; i < d.hlinks.size(); i++) { - pptx_drawing_rels_.push_back(_rel(false, d.hlinks[i].hId, d.hlinks[i].hRef, typeHyperlink)); + bool found = false; + for (size_t j = 0; j < pptx_drawing_rels_.size(); j++) + { + if (d.hlinks[i].hId == pptx_drawing_rels_[j].rid) + { + found = true; + break; + } + } + + if (!found) + { + oox::_rels_type type = boost::algorithm::starts_with(d.hlinks[i].hRef, L"slide") && + boost::algorithm::ends_with(d.hlinks[i].hRef, L".xml") ? typeSlide : typeHyperlink; + pptx_drawing_rels_.push_back(_rel(false, d.hlinks[i].hId, d.hlinks[i].hRef, type)); + } + } if (!d.action.hId.empty()) { - bool bInternal = (d.action.typeRels != typeHyperlink); - pptx_drawing_rels_.push_back(_rel(bInternal, d.action.hId, d.action.hRef, d.action.typeRels)); + bool found = false; + for (size_t i = 0; i < pptx_drawing_rels_.size(); i++) + { + if (pptx_drawing_rels_[i].rid == d.action.hId) + { + found = true; + break; + } + } + + if (!found) + { + bool bInternal = (d.action.typeRels != typeHyperlink); + pptx_drawing_rels_.push_back(_rel(bInternal, d.action.hId, d.action.hRef, d.action.typeRels)); + } } } @@ -135,6 +163,11 @@ class pptx_drawings::Impl } } + std::vector<_pptx_drawing>& get_drawings() + { + return pptx_drawings_; + } + private: std::vector<_pptx_drawing> pptx_drawings_; @@ -180,11 +213,16 @@ void pptx_drawings::dump_rels(rels & Rels) return impl_->dump_rels(Rels); } +std::vector<_pptx_drawing>& pptx_drawings::get_drawings() +{ + return impl_->get_drawings(); +} + pptx_drawings_ptr pptx_drawings::create() { return boost::make_shared(); } } -} + } diff --git a/OdfFile/Reader/Converter/pptx_drawings.h b/OdfFile/Reader/Converter/pptx_drawings.h index 190f83f0147..4e953b2e9b2 100644 --- a/OdfFile/Reader/Converter/pptx_drawings.h +++ b/OdfFile/Reader/Converter/pptx_drawings.h @@ -36,6 +36,8 @@ #include #include #include "mediaitems.h" +#include +#include "pptx_drawing.h" namespace cpdoccore { namespace oox { @@ -68,6 +70,8 @@ class pptx_drawings void dump_rels(rels & Rels); + std::vector<_pptx_drawing>& get_drawings(); + void serialize(std::wostream & _Wostream); static pptx_drawings_ptr create(); diff --git a/OdfFile/Reader/Converter/pptx_output_xml.cpp b/OdfFile/Reader/Converter/pptx_output_xml.cpp index 0ec92ea3582..c6f1c6af2bb 100644 --- a/OdfFile/Reader/Converter/pptx_output_xml.cpp +++ b/OdfFile/Reader/Converter/pptx_output_xml.cpp @@ -31,6 +31,7 @@ */ #include #include +#include #include @@ -56,10 +57,24 @@ pptx_xml_slide_ptr pptx_xml_slide::create(std::wstring const & name,int id) return boost::make_shared(name, rId); } +void pptx_xml_slide::remove_timing_redundant_space() +{ + std::wstring tmp = strmTiming_.str(); + boost::replace_all(tmp, L"> ", L">"); + strmTiming_.str(std::wstring()); + strmTiming_.str(tmp); +} + +void pptx_xml_slide::set_show(bool show_) +{ + show = show_; +} + pptx_xml_slide::pptx_xml_slide(std::wstring const & name,std::wstring const & id) { name_ = name; rId_ = id; + show = true; } pptx_xml_slide::~pptx_xml_slide() @@ -94,6 +109,7 @@ void pptx_xml_slide::write_to(std::wostream & strm) CP_XML_ATTR(L"xmlns:p14", L"http://schemas.microsoft.com/office/powerpoint/2010/main"); CP_XML_ATTR(L"xmlns:p15", L"http://schemas.microsoft.com/office/powerpoint/2012/main"); CP_XML_ATTR(L"xmlns:mc", L"http://schemas.openxmlformats.org/markup-compatibility/2006"); + CP_XML_ATTR(L"show", show); CP_XML_NODE(L"p:cSld") { @@ -163,6 +179,9 @@ void pptx_xml_slideLayout::write_to(std::wostream & strm) CP_XML_NODE(L"p:cSld") { + if (!name.empty()) + CP_XML_ATTR(L"name", name); + CP_XML_NODE(L"p:spTree") { CP_XML_STREAM() << strmData_.str(); @@ -188,6 +207,11 @@ void pptx_xml_slideLayout::write_to(std::wostream & strm) } } +void pptx_xml_slideLayout::set_name(const std::wstring& layout_name) +{ + name = layout_name; +} + //--------------------------------------------------------------------------------------------------------- std::wstring pptx_xml_slideMaster::rId() const { diff --git a/OdfFile/Reader/Converter/pptx_output_xml.h b/OdfFile/Reader/Converter/pptx_output_xml.h index 25a98da9698..69cbc813b19 100644 --- a/OdfFile/Reader/Converter/pptx_output_xml.h +++ b/OdfFile/Reader/Converter/pptx_output_xml.h @@ -63,12 +63,19 @@ class pptx_xml_slide: noncopyable static pptx_xml_slide_ptr create(std::wstring const & name,int id); + // NOTE: Temp solution + // TODO: remove this method + void remove_timing_redundant_space(); + + void set_show(bool show_); + private: std::wstring name_; std::wstringstream strmData_; std::wstringstream strmBackground_; std::wstringstream strmTiming_; std::wstring rId_; + bool show; rels rels_; }; @@ -144,12 +151,14 @@ class pptx_xml_slideLayout: noncopyable //slideTiming void write_to(std::wostream & strm); + void set_name(const std::wstring& layout_name); static pptx_xml_slideLayout_ptr create(int id); private: std::wstringstream strmData_; std::wstring rId_; + std::wstring name; rels rels_; }; diff --git a/OdfFile/Reader/Converter/pptx_package.cpp b/OdfFile/Reader/Converter/pptx_package.cpp index 9241b1a7db4..2f9a2c5df11 100644 --- a/OdfFile/Reader/Converter/pptx_package.cpp +++ b/OdfFile/Reader/Converter/pptx_package.cpp @@ -46,8 +46,11 @@ pptx_content_types_file::pptx_content_types_file() content()->add_default(L"rels", L"application/vnd.openxmlformats-package.relationships+xml"); content()->add_default(L"xml", L"application/xml"); - content()->add_default(L"jpg", L"image/jpeg"); - content()->add_default(L"png", L"image/png"); + content()->add_default(L"jpg", L"image/jpeg"); + content()->add_default(L"png", L"image/png"); + + content()->add_default(L"mp3", L"audio/mpeg"); + content()->add_default(L"wav", L"audio/wav"); content()->add_override(L"/_rels/.rels", L"application/vnd.openxmlformats-package.relationships+xml"); @@ -511,7 +514,9 @@ void ppt_files::add_notesMaster(slide_content_ptr slide) } void ppt_files::set_media(mediaitems_ptr & _mediaitems) { - if (_mediaitems->count_image + _mediaitems->count_media > 0) + if (_mediaitems->count_image + + _mediaitems->count_media + + _mediaitems->count_audio > 0) { media_ = element_ptr( new media(_mediaitems, _mediaitems->applicationFonts()) ); } diff --git a/OdfFile/Reader/Converter/pptx_slide_context.cpp b/OdfFile/Reader/Converter/pptx_slide_context.cpp index 705f4455fc8..af094880a00 100644 --- a/OdfFile/Reader/Converter/pptx_slide_context.cpp +++ b/OdfFile/Reader/Converter/pptx_slide_context.cpp @@ -32,6 +32,7 @@ #include +#include #include #include @@ -80,9 +81,16 @@ class pptx_slide_context::Impl _transition transition_; bool use_image_replacement_; + bool processing_notes; bool header, footer, date_time, slideNum; + // NOTE: Key - ODF draw:id(xml:id), value - OOX ShapeID + // NOTE: draw:id is deprecated. Instead prefer using xml:id. + // draw:id and xml:id MUST be equal to each other + typedef std::unordered_map id_map; + id_map id_map_; + void add_drawing(_pptx_drawing const & d, bool isInternal, std::wstring const & rid, std::wstring const & ref, _rels_type type) { pptx_drawings_->add(d, isInternal, rid, ref, type); @@ -101,6 +109,7 @@ class pptx_slide_context::Impl void clear() { objects_.clear(); + id_map_.clear(); background_fill_ = boost::none; @@ -109,13 +118,18 @@ class pptx_slide_context::Impl date_time = false; slideNum = false; - rId_ = 1; + // NOTE: In PowerPoint p:nvGrpSpPr MUST have id = 1 + // Otherwise animation are still working correctly but other element's IDs don't match to its animations in animation editor of PowerPoint + // Reserve "id = 1" for p:nvGrpSpPr + rId_ = 2; pptx_drawings_ = pptx_drawings::create(); transition_.Enabled = false; transition_.Speed = boost::none; transition_.onClick = true; + + processing_notes = false; } size_t next_rId() @@ -126,12 +140,40 @@ class pptx_slide_context::Impl { return pptx_drawings_; } + size_t generate_id(const std::wstring& id) + { + size_t result = next_rId(); + id_map_.insert(std::make_pair(id, result)); + + return result; + } + size_t get_id(const std::wstring& id) + { + if (id == L"") + return next_rId(); + + id_map::iterator it = id_map_.find(id); + if (it == id_map_.end()) + return generate_id(id); + + return it->second; + } + size_t find_id(const std::wstring& id) + { + id_map::iterator it = id_map_.find(id); + if (it == id_map_.end()) + return 0; + + return it->second; + } + std::wstring odfPacket_; void process_drawings(); private: void process_common_properties(drawing_object_description& obj, _pptx_drawing & drawing); + void process_crop(const drawing_object_description& obj, _pptx_drawing& drawing, const std::wstring& filename); void process_shape (drawing_object_description& obj, _pptx_drawing & drawing); void process_image (drawing_object_description& obj, _pptx_drawing & drawing); @@ -154,7 +196,7 @@ void pptx_slide_context::Impl::process_drawings() drawing.type = objects_[i].type_; drawing.name = objects_[i].name_; - drawing.id = next_rId(); + drawing.id = get_id(objects_[i].xml_id_); drawing.lined = objects_[i].lined_; drawing.connector = objects_[i].connector_; @@ -162,19 +204,31 @@ void pptx_slide_context::Impl::process_drawings() switch(objects_[i].type_) { - case typeImage: process_image(objects_[i], drawing); break; - case typeChart: process_chart(objects_[i], drawing); break; - case typeShape: process_shape(objects_[i], drawing); break; - case typeTable: process_table(objects_[i], drawing); break; - case typeMedia: process_media(objects_[i], drawing); break; + case typeImage: process_image(objects_[i], drawing); break; + case typeChart: process_chart(objects_[i], drawing); break; + case typeShape: process_shape(objects_[i], drawing); break; + case typeTable: process_table(objects_[i], drawing); break; + case typeMedia: process_media(objects_[i], drawing); break; case typeMsObject: - case typeOleObject: process_object(objects_[i], drawing); break; + case typeOleObject: process_object(objects_[i], drawing); break; } } + + for (size_t i = 0; i < pptx_drawings_->get_drawings().size(); i++) + { + _pptx_drawing& drawing = pptx_drawings_->get_drawings()[i]; + + if(!drawing.connector) + continue; + + drawing.start_connection_shape_id = std::to_wstring(find_id(drawing.start_connection_shape_id)); + drawing.end_connection_shape_id = std::to_wstring(find_id(drawing.end_connection_shape_id)); + } } pptx_slide_context::pptx_slide_context(pptx_conversion_context & Context) - : impl_(new pptx_slide_context::Impl(Context.root()->get_folder())) + : impl_(new pptx_slide_context::Impl(Context.root()->get_folder())), + pptx_animation_context_() { hlinks_size_ = 0; } @@ -229,6 +283,7 @@ void pptx_slide_context::default_set() impl_->object_description_.xlink_href_ = L""; impl_->object_description_.name_ = L""; impl_->object_description_.descriptor_ = L""; + impl_->object_description_.xml_id_ = L""; impl_->object_description_.anchor_ = L""; impl_->object_description_.additional_.clear(); @@ -238,6 +293,14 @@ void pptx_slide_context::default_set() impl_->object_description_.connector_ = false; impl_->object_description_.lined_ = false; + impl_->object_description_.hidden_ = false; + + impl_->object_description_.start_shape_id = boost::none; + impl_->object_description_.start_shape_glue_point = boost::none; + impl_->object_description_.end_shape_id = boost::none; + impl_->object_description_.end_shape_glue_point = boost::none; + impl_->object_description_.draw_type_ = boost::none; + impl_->object_description_.hlinks_.clear(); impl_->object_description_.action_.clear(); @@ -248,11 +311,21 @@ void pptx_slide_context::default_set() impl_->use_image_replacement_ = false; } +bool pptx_slide_context::is_slide_filepath(const std::wstring& filename) +{ + return boost::algorithm::contains(filename, L"slide") && boost::algorithm::ends_with(filename, L".xml"); +} + void pptx_slide_context::set_use_image_replacement() { impl_->use_image_replacement_ = true; } +void pptx_slide_context::set_is_placeHolder(bool is_placeholder) +{ + impl_->object_description_.additional_.push_back(odf_reader::_property(L"IsPlaceholder", is_placeholder)); +} + void pptx_slide_context::set_placeHolder_type(std::wstring typeHolder) { if (typeHolder == L"ftr") impl_->footer = true; @@ -260,11 +333,11 @@ void pptx_slide_context::set_placeHolder_type(std::wstring typeHolder) if (typeHolder == L"dt") impl_->date_time = true; if (typeHolder == L"sldNum")impl_->slideNum = true; - impl_->object_description_.additional_.push_back(odf_reader::_property(L"PlaceHolderType",typeHolder)); + impl_->object_description_.additional_.push_back(odf_reader::_property(L"PlaceHolderType", typeHolder)); } void pptx_slide_context::set_placeHolder_idx(int idx) { - impl_->object_description_.additional_.push_back(odf_reader::_property(L"PlaceHolderIdx",idx)); + impl_->object_description_.additional_.push_back(odf_reader::_property(L"PlaceHolderIdx", idx)); } void pptx_slide_context::set_rect(double width_pt, double height_pt, double x_pt, double y_pt) @@ -341,6 +414,42 @@ void pptx_slide_context::set_is_connector_shape(bool val) { impl_->object_description_.connector_ = val; } + +void pptx_slide_context::set_connector_start_shape(const std::wstring& startShape) +{ + impl_->object_description_.start_shape_id = startShape; +} + +void pptx_slide_context::set_connector_end_shape(const std::wstring& endShape) +{ + impl_->object_description_.end_shape_id = endShape; +} + +void pptx_slide_context::set_connector_start_glue_point(int gluePoint) +{ + impl_->object_description_.start_shape_glue_point = gluePoint; +} + +void pptx_slide_context::set_connector_end_glue_point(int gluePoint) +{ + impl_->object_description_.end_shape_glue_point = gluePoint; +} + +void pptx_slide_context::set_connector_draw_type(const std::wstring& drawType) +{ + impl_->object_description_.draw_type_ = drawType; +} + +void pptx_slide_context::processing_notes(bool processing_notes) +{ + impl_->processing_notes = processing_notes; +} + +bool pptx_slide_context::processing_notes() +{ + return impl_->processing_notes; +} + std::wstring pptx_slide_context::add_hyperlink(std::wstring const & href) { ++hlinks_size_; @@ -368,11 +477,22 @@ void pptx_slide_context::add_background(_oox_fill & fill) impl_->background_fill_ = fill; } -void pptx_slide_context::set_name(std::wstring const & name) +void pptx_slide_context::set_name(std::wstring name) { + boost::replace_all(name, L"&", L"&"); + impl_->object_description_.name_ = name; } +void pptx_slide_context::set_id(std::wstring const& id) +{ + impl_->object_description_.xml_id_ = id; +} +void pptx_slide_context::set_hidden(bool val) +{ + impl_->object_description_.hidden_ = val; +} + void pptx_slide_context::start_shape(int type) { if (impl_->object_description_.bInner_) return; @@ -380,13 +500,14 @@ void pptx_slide_context::start_shape(int type) impl_->object_description_.type_ = typeShape; impl_->object_description_.shape_type_ = type; //2,3... } + void pptx_slide_context::start_action(std::wstring action) { impl_->object_description_.action_.enabled = true; if (action == L"sound") { - impl_->object_description_.action_.action = L"ppaction://noaction"; + //impl_->object_description_.action_.action = L"ppaction://noaction"; impl_->object_description_.action_.typeRels = typeAudio; impl_->object_description_.action_.highlightClick = true; } @@ -417,6 +538,12 @@ void pptx_slide_context::start_action(std::wstring action) impl_->object_description_.action_.typeRels = typeHyperlink; impl_->object_description_.action_.highlightClick = true; } + else if (action == L"show") + { + impl_->object_description_.action_.action = L"ppaction://hlinksldjump"; + impl_->object_description_.action_.typeRels = typeSlide; + impl_->object_description_.action_.highlightClick = true; + } } void pptx_slide_context::set_link(std::wstring link, _rels_type typeRels) { @@ -443,6 +570,9 @@ void pptx_slide_context::set_link(std::wstring link, _rels_type typeRels) impl_->object_description_.action_.hId = hId; impl_->object_description_.action_.hRef = link; + + if (!is_slide_filepath(link)) + impl_->object_description_.action_.action = L""; } } void pptx_slide_context::end_action() @@ -585,8 +715,7 @@ void pptx_slide_context::Impl::process_image(drawing_object_description& obj, _p } std::wstring fileName = odfPacket_ + FILE_SEPARATOR_STR + obj.xlink_href_; - drawing.fill.bitmap->bCrop = odf_reader::parse_clipping(obj.clipping_string_, fileName, drawing.fill.bitmap->cropRect, get_mediaitems()->applicationFonts()); - drawing.fill.bitmap->bStretch = true; + process_crop(obj, drawing, fileName); if ((sColorMode) && (*sColorMode == L"greyscale")) drawing.fill.bitmap->luminance = true; @@ -645,6 +774,9 @@ void pptx_slide_context::Impl::process_shape(drawing_object_description & obj, _ drawing.fill.bitmap->rId = get_mediaitems()->add_or_find(drawing.fill.bitmap->xlink_href_, typeImage, isMediaInternal, ref, oox::document_place); add_additional_rels(isMediaInternal, drawing.fill.bitmap->rId, ref, typeImage); + + std::wstring fileName = odfPacket_ + FILE_SEPARATOR_STR + drawing.fill.bitmap->xlink_href_; + process_crop(obj, drawing, fileName); } std::wstring rId = get_mediaitems()->add_or_find(L"", typeShape, isMediaInternal, ref, oox::document_place); @@ -661,8 +793,22 @@ void pptx_slide_context::Impl::process_shape(drawing_object_description & obj, _ if (iPlaceHolderIdx) drawing.place_holder_idx_ = *iPlaceHolderIdx; } + _CP_OPT(bool) is_placeholder; + GetProperty(obj.additional_, L"IsPlaceholder", is_placeholder); + drawing.place_holder_ = is_placeholder.get_value_or(false); + drawing.sub_type = obj.shape_type_; + // NOTE: Все идентификаторы объектов могут быть неивестны на момент обрабоки коннектора. + // Идентификаторы начального и конечного объекта коннектора будут обновлены после обработки всех объектов на слайде. + drawing.start_connection_shape_id = obj.start_shape_id.get_value_or(L""); + drawing.end_connection_shape_id = obj.end_shape_id.get_value_or(L""); + + drawing.start_connection_index = obj.start_shape_glue_point.get_value_or(0); + drawing.end_connection_index = obj.end_shape_glue_point.get_value_or(0); + + drawing.connector_prst = obj.draw_type_.get_value_or(L"line"); + add_drawing(drawing, isMediaInternal, rId, ref, typeShape); } void pptx_slide_context::Impl::process_object(drawing_object_description& obj, _pptx_drawing & drawing) @@ -725,13 +871,20 @@ void pptx_slide_context::Impl::process_common_properties(drawing_object_descript val = (int)(0.5 + odf_types::length(pic.svg_rect_->cy, odf_types::length::pt).get_value_unit(odf_types::length::emu)); if ( val >=0 ) drawing.cy = val; } - + + drawing.hidden = pic.hidden_; drawing.additional = pic.additional_; drawing.hlinks = pic.hlinks_; drawing.action = pic.action_; drawing.fill = pic.fill_; } +void pptx_slide_context::Impl::process_crop(const drawing_object_description& obj, _pptx_drawing& drawing, const std::wstring& filename) +{ + drawing.fill.bitmap->bCrop = odf_reader::parse_clipping(obj.clipping_string_, filename, drawing.fill.bitmap->cropRect, get_mediaitems()->applicationFonts()); + drawing.fill.bitmap->bStretch = true; +} + void pptx_slide_context::dump_rels(rels & Rels) { impl_->get_drawings()->dump_rels(Rels); @@ -763,6 +916,21 @@ void pptx_slide_context::set_date_time() { impl_->slideNum = true; } + +void pptx_slide_context::generate_id(const std::wstring& id) +{ + impl_->generate_id(id); +} + +size_t pptx_slide_context::get_id(const std::wstring& id) +{ + Impl::id_map::iterator it = impl_->id_map_.find(id); + if (it == impl_->id_map_.end()) + return 0; + + return it->second; +} + void pptx_slide_context::serialize_background(std::wostream & strm, bool always) { if (!always && ( (!impl_->background_fill_) || (impl_->background_fill_->type == 0))) return; @@ -836,22 +1004,8 @@ void pptx_slide_context::serialize_animations(std::wostream & strm) //p:sndAc } } - CP_XML_NODE(L"p:timing") - { - CP_XML_NODE(L"p:tnLst") - { - CP_XML_NODE(L"p:par") - { - CP_XML_NODE(L"p:cTn") - { - CP_XML_ATTR(L"nodeType", L"tmRoot"); - CP_XML_ATTR(L"id", 1); - CP_XML_ATTR(L"dur", L"indefinite"); - CP_XML_ATTR(L"restart", L"never"); - } - } - } - } + + pptx_animation_context_.serialize(strm); } } @@ -872,7 +1026,7 @@ void pptx_slide_context::serialize_HeaderFooter(std::wostream & strm) } void pptx_slide_context::serialize_objects(std::wostream & strm) { - int next_id = impl_->next_rId(); + const int nextnvGrpSpPrId = 1; CP_XML_WRITER(strm) { @@ -882,7 +1036,7 @@ void pptx_slide_context::serialize_objects(std::wostream & strm) CP_XML_NODE(L"p:cNvPr") { CP_XML_ATTR(L"name", L"noGroup"); - CP_XML_ATTR(L"id", next_id); + CP_XML_ATTR(L"id", nextnvGrpSpPrId); } CP_XML_NODE(L"p:cNvGrpSpPr"); CP_XML_NODE(L"p:nvPr"); @@ -898,7 +1052,6 @@ void pptx_slide_context::serialize_objects(std::wostream & strm) } } } - process_drawings(); impl_->get_drawings()->serialize(strm); } diff --git a/OdfFile/Reader/Converter/pptx_slide_context.h b/OdfFile/Reader/Converter/pptx_slide_context.h index 679d7101b15..f7744d1e167 100644 --- a/OdfFile/Reader/Converter/pptx_slide_context.h +++ b/OdfFile/Reader/Converter/pptx_slide_context.h @@ -32,6 +32,7 @@ #pragma once #include "pptx_drawings.h" +#include "pptx_animation_context.h" #include namespace cpdoccore { @@ -65,18 +66,29 @@ class pptx_slide_context void set_scale (double cx_pt, double cy_pt); void set_rotate (double angle, bool translate = false); - void set_name (std::wstring const & name); + void set_name (std::wstring name); + void set_id (std::wstring const & id); void set_anchor (std::wstring anchor, double x_pt, double y_pt); void set_property (odf_reader::_property p); std::vector & get_properties(); void set_clipping (const std::wstring & str ); void set_fill (_oox_fill & fill); + void set_hidden (bool val); void set_is_line_shape(bool val); void set_is_connector_shape(bool val); + void set_connector_start_shape (const std::wstring& startShape); + void set_connector_end_shape (const std::wstring& endShape); + void set_connector_start_glue_point (int gluePoint); + void set_connector_end_glue_point (int gluePoint); + void set_connector_draw_type (const std::wstring& drawType); + + void set_is_placeHolder(bool is_placeholder); void set_placeHolder_type (std::wstring typeHolder); void set_placeHolder_idx (int idx); + void processing_notes (bool processing_notes); + bool processing_notes(); std::wstring add_hyperlink(std::wstring const & ref); @@ -131,10 +143,17 @@ class pptx_slide_context void set_page_number(); void set_date_time(); + + pptx_animation_context & get_animation_context() { return pptx_animation_context_; } + void generate_id(const std::wstring& id); + size_t get_id(const std::wstring& id); private: void default_set(); + bool is_slide_filepath(const std::wstring& filename); int hlinks_size_; + + pptx_animation_context pptx_animation_context_; class Impl; _CP_PTR(Impl) impl_; diff --git a/OdfFile/Reader/Converter/pptx_table_context.cpp b/OdfFile/Reader/Converter/pptx_table_context.cpp index 67202bf10e4..3ba4e2fe4b7 100644 --- a/OdfFile/Reader/Converter/pptx_table_context.cpp +++ b/OdfFile/Reader/Converter/pptx_table_context.cpp @@ -53,7 +53,10 @@ pptx_table_state::pptx_table_state(pptx_conversion_context & Context, const std::wstring & StyleName) : context_(Context), table_style_(StyleName), current_table_column_(-1), - columns_spanned_num_(0) + columns_spanned_num_(0), + rows_(0), + current_row_(0), + total_columns_(0) { } @@ -75,6 +78,18 @@ std::wstring pptx_table_state::get_default_cell_style_row() return default_row_cell_style_name_; } +void pptx_table_state::set_default_cell_style_row(const std::wstring& style_name) +{ + default_row_cell_style_name_ = style_name; +} + +void pptx_table_state::set_default_cell_style_col(unsigned int column, const std::wstring style_name) +{ + if (column >= columnsDefaultCellStyleName_.size()) + return; + + columnsDefaultCellStyleName_[column] = style_name; +} void pptx_table_state::start_row(const std::wstring & StyleName, const std::wstring & defaultCellStyleName) { @@ -82,6 +97,7 @@ void pptx_table_state::start_row(const std::wstring & StyleName, const std::wstr columns_spanned_style_ = L""; table_row_style_stack_.push_back(StyleName); default_row_cell_style_name_ = defaultCellStyleName; + current_row_++; } void pptx_table_state::end_row() @@ -225,6 +241,41 @@ unsigned int pptx_table_state::current_rows_spanned(unsigned int Column) const } } +void pptx_table_state::set_rows(int rows) +{ + rows_ = rows; +} + +int pptx_table_state::get_rows() const +{ + return rows_; +} + +int pptx_table_state::get_current_row() const +{ + return current_row_; +} + +void pptx_table_state::set_columns(int cols) +{ + total_columns_ = cols; +} + +int pptx_table_state::get_columns() const +{ + return total_columns_; +} + +void pptx_table_state::set_template_row_style_name(const std::wstring style_name) +{ + template_row_style_name_ = style_name; +} + +std::wstring pptx_table_state::get_template_row_style_name() const +{ + return template_row_style_name_; +} + struct pptx_border_edge { bool present = false; @@ -248,13 +299,13 @@ void convert_border_style(const odf_types::border_style& borderStyle, pptx_borde switch(borderStyle.get_style()) { - case odf_types::border_style::none: border.none = true; break; - case odf_types::border_style::double_: border.cmpd = L"dbl"; break; - case odf_types::border_style::dotted: border.prstDash = L"dot"; break; - case odf_types::border_style::dashed: border.prstDash = L"dash"; break; - case odf_types::border_style::long_dash: border.prstDash = L"lgDash"; break; - case odf_types::border_style::dot_dash: border.prstDash = L"dashDot"; break; - case odf_types::border_style::dot_dot_dash: border.prstDash = L"lgDashDotDot"; break; + case odf_types::border_style::none: border.none = true; break; + case odf_types::border_style::double_: border.cmpd = L"dbl"; break; + case odf_types::border_style::dotted: border.prstDash = L"dot"; break; + case odf_types::border_style::dash: border.prstDash = L"dash"; break; + case odf_types::border_style::long_dash: border.prstDash = L"lgDash"; break; + case odf_types::border_style::dot_dash: border.prstDash = L"dashDot"; break; + case odf_types::border_style::dot_dot_dash: border.prstDash = L"lgDashDotDot"; break; } } } @@ -265,17 +316,18 @@ void convert_border_style(const odf_types::border_style& borderStyle, pptx_borde //tri (Thin Thick Thin Triple Lines) Three lines: thin, thick, thin void process_border(pptx_border_edge & borderEdge, _CP_OPT(odf_types::border_style) & borderStyle) { - borderEdge.present = false; + borderEdge.present = true; if (borderStyle) { - borderEdge.present = true; - - borderEdge.color = borderStyle->get_color().get_hex_value(); borderEdge.width = boost::lexical_cast(borderStyle->get_length().get_value_unit(odf_types::length::emu)); convert_border_style(*borderStyle, borderEdge); - } + } + else + { + borderEdge.none = true; + } } void oox_serialize_border(std::wostream & strm, std::wstring Node, pptx_border_edge & content) { @@ -320,6 +372,7 @@ void oox_serialize_tcPr(std::wostream & strm, std::vector 0) { odf_reader::style_table_cell_properties_attlist style_cell_attlist = odf_reader::calc_table_cell_properties(instances); + odf_reader::graphic_format_properties_ptr graphic_props = odf_reader::calc_graphic_properties_content(instances); if (style_cell_attlist.style_vertical_align_) { @@ -343,6 +396,14 @@ void oox_serialize_tcPr(std::wostream & strm, std::vectorcommon_padding_attlist_.fo_padding_) + { + double padding = graphic_props->common_padding_attlist_.fo_padding_->get_value_unit(odf_types::length::emu); + CP_XML_ATTR(L"marT", (long)padding); + CP_XML_ATTR(L"marB", (long)padding); + CP_XML_ATTR(L"marL", (long)padding); + CP_XML_ATTR(L"marR", (long)padding); + } else { if (style_cell_attlist.common_padding_attlist_.fo_padding_top_) @@ -350,21 +411,44 @@ void oox_serialize_tcPr(std::wostream & strm, std::vectorget_value_unit(odf_types::length::emu); CP_XML_ATTR(L"marT", (long)padding); } + else if (graphic_props && graphic_props->common_padding_attlist_.fo_padding_top_) + { + double padding = graphic_props->common_padding_attlist_.fo_padding_top_->get_value_unit(odf_types::length::emu); + CP_XML_ATTR(L"marT", (long)padding); + } + if (style_cell_attlist.common_padding_attlist_.fo_padding_bottom_) { double padding = style_cell_attlist.common_padding_attlist_.fo_padding_bottom_->get_value_unit(odf_types::length::emu); CP_XML_ATTR(L"marB", (long)padding); } + else if (graphic_props && graphic_props->common_padding_attlist_.fo_padding_bottom_) + { + double padding = graphic_props->common_padding_attlist_.fo_padding_bottom_->get_value_unit(odf_types::length::emu); + CP_XML_ATTR(L"marB", (long)padding); + } + if (style_cell_attlist.common_padding_attlist_.fo_padding_left_) { double padding = style_cell_attlist.common_padding_attlist_.fo_padding_left_->get_value_unit(odf_types::length::emu); CP_XML_ATTR(L"marL", (long)padding); } + else if (graphic_props && graphic_props->common_padding_attlist_.fo_padding_left_) + { + double padding = graphic_props->common_padding_attlist_.fo_padding_left_->get_value_unit(odf_types::length::emu); + CP_XML_ATTR(L"marL", (long)padding); + } + if (style_cell_attlist.common_padding_attlist_.fo_padding_right_) { double padding = style_cell_attlist.common_padding_attlist_.fo_padding_right_->get_value_unit(odf_types::length::emu); CP_XML_ATTR(L"marR", (long)padding); } + else if (graphic_props && graphic_props->common_padding_attlist_.fo_padding_right_) + { + double padding = graphic_props->common_padding_attlist_.fo_padding_right_->get_value_unit(odf_types::length::emu); + CP_XML_ATTR(L"marR", (long)padding); + } } //vert // //style_cell_attlist.pptx_serialize(Context, CP_XML_STREAM()); //nodes @@ -385,8 +469,6 @@ void oox_serialize_tcPr(std::wostream & strm, std::vector columns_; std::vector columnsDefaultCellStyleName_; - + + unsigned int rows_; + unsigned int current_row_; + unsigned int total_columns_; }; class pptx_table_context : boost::noncopyable @@ -116,10 +137,10 @@ class pptx_table_context : boost::noncopyable table_states_.pop_back(); } - std::wstring current_style() const - { - return table_states_.back().current_style(); - } + std::wstring current_style() const + { + return table_states_.back().current_style(); + } size_t in_table() const { @@ -191,6 +212,11 @@ class pptx_table_context : boost::noncopyable return table_states_.back().current_rows_spanned(Column); } + void set_default_cell_style_col(unsigned int column, std::wstring style_name) + { + table_states_.back().set_default_cell_style_col(column, style_name); + } + std::wstring get_default_cell_style_col(unsigned int column) { return table_states_.back().get_default_cell_style_col(column); @@ -205,14 +231,173 @@ class pptx_table_context : boost::noncopyable { table_states_.back().default_cell_style_name_ = style_name; } + + void set_table_rows(int rows) + { + table_states_.back().set_rows(rows); + } + + int get_table_rows() const + { + return table_states_.back().get_rows(); + } + + void set_table_columns(int cols) + { + return table_states_.back().set_columns(cols); + } + + int get_table_columns() const + { + return table_states_.back().get_columns(); + } + + void set_first_row_style_name(std::wstring style_name) + { + table_states_.back().first_row_style_name_ = style_name; + } + + void set_last_row_style_name(std::wstring style_name) + { + table_states_.back().last_row_style_name_ = style_name; + } + + void set_odd_rows_style_name(std::wstring style_name) + { + table_states_.back().odd_rows_style_name_ = style_name; + } + + void set_first_column_style_name(std::wstring style_name) + { + table_states_.back().first_column_style_name_ = style_name; + } + + void set_last_column_style_name(std::wstring style_name) + { + table_states_.back().last_column_style_name_ = style_name; + } + + void set_odd_columns_style_name(std::wstring style_name) + { + table_states_.back().odd_columns_style_name = style_name; + } + + std::wstring get_first_row_style_name() + { + return table_states_.back().first_row_style_name_.get_value_or(L""); + } + + std::wstring get_last_row_style_name() + { + return table_states_.back().last_row_style_name_.get_value_or(L""); + } + + std::wstring get_odd_rows_style_name() + { + return table_states_.back().odd_rows_style_name_.get_value_or(L""); + } + + std::wstring get_first_column_style_name() + { + return table_states_.back().first_column_style_name_.get_value_or(L""); + } + + std::wstring get_last_column_style_name() + { + return table_states_.back().last_column_style_name_.get_value_or(L""); + } + + std::wstring get_odd_column_style_name() + { + return table_states_.back().odd_columns_style_name.get_value_or(L""); + } + std::wstring get_default_cell_style() { return table_states_.back().default_cell_style_name_; } + + void set_template_row_style_name(const std::wstring& style_name) + { + table_states_.back().set_template_row_style_name(style_name); + } + + std::wstring get_template_row_style_name() + { + return table_states_.back().get_template_row_style_name(); + } + + void set_template_use_styles( + bool use_first_row_styles, + bool use_last_row_styles, + bool use_banding_rows_styles, + bool use_first_column_styles, + bool use_last_column_styles, + bool use_banding_columns_styles) + { + template_use_styles_.use_first_row_styles = use_first_row_styles; + template_use_styles_.use_last_row_styles = use_last_row_styles; + template_use_styles_.use_banding_rows_styles = use_banding_rows_styles; + + template_use_styles_.use_first_column_styles = use_first_column_styles; + template_use_styles_.use_last_column_styles = use_last_column_styles; + template_use_styles_.use_banding_columns_styles = use_banding_columns_styles; + } + + bool template_is_first_row() + { + return table_states_.back().get_current_row() == 0 && template_use_styles_.use_first_row_styles; + } + + bool template_is_last_row() + { + return + table_states_.back().get_current_row() == table_states_.back().get_rows() - 1 && + template_use_styles_.use_last_row_styles; + } + + bool template_is_odd_row() + { + return + table_states_.back().get_current_row() % 2 == 1 && + template_use_styles_.use_banding_rows_styles; + } + + bool template_is_first_column() + { + return table_states_.back().current_column() == 0 && + template_use_styles_.use_first_column_styles; + } + + bool template_is_last_column() + { + return + table_states_.back().current_column() == table_states_.back().get_columns() - 1 && + template_use_styles_.use_last_column_styles; + } + + bool template_is_odd_column() + { + return + table_states_.back().current_column() % 2 == 1 && + template_use_styles_.use_banding_columns_styles; + } + private: std::wstringstream output_stream_; pptx_conversion_context & context_; std::vector table_states_; + + struct template_use_styles + { + bool use_first_row_styles = false; + bool use_last_row_styles = false; + bool use_banding_rows_styles = false; + + bool use_first_column_styles = false; + bool use_last_column_styles = false; + bool use_banding_columns_styles = false; + } template_use_styles_; }; void oox_serialize_tcPr(std::wostream & strm, std::vector & style_inst, oox::pptx_conversion_context & Context); diff --git a/OdfFile/Reader/Converter/pptx_text_context.cpp b/OdfFile/Reader/Converter/pptx_text_context.cpp index f57792a535b..6ecb4af5699 100644 --- a/OdfFile/Reader/Converter/pptx_text_context.cpp +++ b/OdfFile/Reader/Converter/pptx_text_context.cpp @@ -80,8 +80,12 @@ class pptx_text_context::Impl: boost::noncopyable void set_local_styles_container(odf_reader::styles_container* local_styles_);//это если стили объектов содержатся в другом документе - void end_hyperlink (std::wstring hId); + hyperlink_data get_hyperlink(); void start_hyperlink(); + void set_rel_id(const std::wstring& rId); + void set_action(const std::wstring& action); + void end_hyperlink (); + void start_list (const std::wstring & StyleName, bool Continue = false); void end_list (); @@ -94,6 +98,8 @@ class pptx_text_context::Impl: boost::noncopyable void start_comment (); std::wstring end_comment(); + std::wstring get_last_paragraph_style_name(); + bool in_list_; bool process_layouts_; @@ -102,10 +108,12 @@ class pptx_text_context::Impl: boost::noncopyable odf_reader::odf_read_context & odf_context_ ; std::wstring hyperlink_hId; + hyperlink_data hyperlink_; bool in_span; bool in_paragraph; bool in_comment; + bool is_predump; odf_reader::styles_container * local_styles_ptr_; @@ -123,14 +131,18 @@ class pptx_text_context::Impl: boost::noncopyable std::wstringstream paragraph_; //перманенто скидываемые параграфы std::wstringstream run_; //перманенто скидываемые куски с быть может разными свойствами + std::wstring last_paragraph_style_name_; std::wstring paragraph_style_name_; std::wstring span_style_name_; + std::wstring base_style_name_; odf_types::style_family::type base_style_family_;//Presentation Or SpreadSheet //------------------------------------------------------------------------------- std::vector list_style_stack_; bool first_element_list_item_; + + _CP_OPT(odf_types::length) last_run_font_size_; int new_list_style_number_; // счетчик для нумерации имен созданных в процессе конвертации стилей @@ -186,6 +198,7 @@ void pptx_text_context::Impl::start_paragraph(const std::wstring & styleName) //} //else/* (paragraph_style_name_ != styleName)*/ { + is_predump = true; dump_paragraph(); } }else @@ -193,8 +206,10 @@ void pptx_text_context::Impl::start_paragraph(const std::wstring & styleName) text_.str(std::wstring()); field_value_.str(std::wstring()); } - paragraph_style_name_ = styleName; - in_paragraph = true; + last_paragraph_style_name_ = paragraph_style_name_; + paragraph_style_name_ = styleName; + in_paragraph = true; + is_predump = false; } void pptx_text_context::Impl::end_paragraph() @@ -206,14 +221,13 @@ void pptx_text_context::Impl::start_span(const std::wstring & styleName)//кус { int text_size = text_.str().length(); - if ((span_style_name_ !=styleName && text_size > 0) || in_span) + if ((span_style_name_ != styleName && text_size > 0) || in_span) { dump_run(); } span_style_name_ = styleName; - - in_span=true; + in_span = true; } void pptx_text_context::Impl::end_span() @@ -237,11 +251,10 @@ void pptx_text_context::Impl::start_hyperlink() dump_run();//проверить } -void pptx_text_context::Impl::end_hyperlink(std::wstring hId) +void pptx_text_context::Impl::end_hyperlink() { - hyperlink_hId = hId; dump_run(); - hyperlink_hId = L""; + hyperlink_ = { L"", L"" }; } void pptx_text_context::Impl::ApplyTextProperties(std::wstring style_name, std::wstring para_style_name, odf_reader::text_format_properties & propertiesOut, bool inStyle) { @@ -376,6 +389,8 @@ void pptx_text_context::Impl::write_pPr(std::wostream & strm) get_styles_context().start(); int level = list_style_stack_.size() - 1; + if (is_predump) + level--; odf_reader::paragraph_format_properties paragraph_properties_; @@ -388,7 +403,7 @@ void pptx_text_context::Impl::write_pPr(std::wostream & strm) const std::wstring & paragraphNodes = get_styles_context().paragraph_nodes().str(); - if (level < 0 && paragraphAttr.length() < 1 && !paragraphNodes.empty()) return; + if (level < 0 && paragraphAttr.length() < 1 && paragraphNodes.empty()) return; strm << L"get_type() == odf_types::font_size::Length) + last_run_font_size_ = text_properties_.fo_font_size_->get_length(); + strm << get_styles_context().text_style().str(); } std::wstring pptx_text_context::Impl::dump_paragraph(/*bool last*/) { @@ -447,7 +464,7 @@ std::wstring pptx_text_context::Impl::dump_paragraph(/*bool last*/) std::wstring str_run = run_.str(); - if (str_run.length() > 0 || paragraph_style_name_.length() > 0) + if (false == str_run.empty() || false == paragraph_style_name_.empty() || (false == base_style_name_.empty() && process_layouts_)) { CP_XML_WRITER(paragraph_) { @@ -459,9 +476,20 @@ std::wstring pptx_text_context::Impl::dump_paragraph(/*bool last*/) { CP_XML_STREAM() << run_.str(); } - else + + CP_XML_NODE(L"a:endParaRPr") { - CP_XML_NODE(L"a:endParaRPr"); + odf_reader::paragraph_format_properties parap_props; + ApplyParagraphProperties(paragraph_style_name_, parap_props, false); + + if (last_run_font_size_ && !parap_props.fo_margin_top_) + { + int sz = last_run_font_size_->get_value_unit(odf_types::length::pt) * 100; + + CP_XML_ATTR(L"sz", sz); + } + + last_run_font_size_ = boost::none; } } } @@ -564,7 +592,7 @@ void pptx_text_context::Impl::dump_run() const std::wstring content = XmlUtils::EncodeXmlString(text_.str()); //if (content.length() <1 && span_style_name_.length()<1) return ; ... провеить с пустыми строками нужны ли ... - if (content .length() > 0) + if (content.length() > 0) { CP_XML_WRITER(run_) { @@ -581,6 +609,15 @@ void pptx_text_context::Impl::dump_run() text_.str(std::wstring()); } } + else + { + odf_reader::text_format_properties text_properties_; + ApplyTextProperties(span_style_name_, paragraph_style_name_, text_properties_); + + if (text_properties_.fo_font_size_ && text_properties_.fo_font_size_->get_type() == odf_types::font_size::Length) + last_run_font_size_ = text_properties_.fo_font_size_->get_length(); + } + hyperlink_hId =L""; } @@ -663,7 +700,7 @@ void pptx_text_context::Impl::start_list_item(bool restart) void pptx_text_context::Impl::start_list(const std::wstring & StyleName, bool Continue) { - if (paragraphs_cout_ > 0 && ( in_paragraph || list_style_stack_.empty())) + if (paragraphs_cout_ > 0 && ( in_paragraph || !list_style_stack_.empty())) { dump_paragraph(); } @@ -709,8 +746,9 @@ std::wstring pptx_text_context::Impl::find_list_rename(const std::wstring & List void pptx_text_context::Impl::end_list_item() { dump_paragraph(); - - paragraphs_cout_--; + + if (paragraphs_cout_ != 0) + paragraphs_cout_--; paragraph_style_name_ = L""; in_list_ = false; @@ -726,7 +764,7 @@ void pptx_text_context::Impl::start_comment() } std::wstring pptx_text_context::Impl::end_comment() { - std::wstring str_comment = text_.str(); + std::wstring str_comment = text_.str(); text_.str(std::wstring()); in_comment = false; @@ -775,6 +813,26 @@ void pptx_text_context::Impl::write_list_styles(std::wostream & strm)//defaults list_style_stack_.clear(); } +void pptx_text_context::Impl::set_rel_id(const std::wstring& rId) +{ + hyperlink_.rId = rId; +} + +void pptx_text_context::Impl::set_action(const std::wstring& action) +{ + hyperlink_.action = action; +} + +hyperlink_data pptx_text_context::Impl::get_hyperlink() +{ + return hyperlink_; +} + +std::wstring pptx_text_context::Impl::get_last_paragraph_style_name() +{ + return last_paragraph_style_name_; +} + ///////////////////////////////////////////////////////////////////////////////////////////////////// pptx_text_context::pptx_text_context(odf_reader::odf_read_context & odf_context_, pptx_conversion_context & pptx_context_): @@ -860,18 +918,33 @@ void pptx_text_context::start_hyperlink() { return impl_->start_hyperlink(); } -void pptx_text_context::end_hyperlink(std::wstring hId) +void pptx_text_context::set_rel_id(const std::wstring& rId) +{ + impl_->set_rel_id(rId); +} +void pptx_text_context::set_action(const std::wstring& action) { - return impl_->end_hyperlink(hId); + impl_->set_action(action); +} +void pptx_text_context::end_hyperlink() +{ + return impl_->end_hyperlink(); } std::wstring pptx_text_context::end_object() { return impl_->end_object(); } + +hyperlink_data pptx_text_context::get_hyperlink() +{ + return impl_->get_hyperlink(); +} + styles_context & pptx_text_context::get_styles_context() { return impl_->get_styles_context() ; } + void pptx_text_context::start_field(field_type type, const std::wstring & styleName) { impl_->start_field(type, styleName); @@ -894,5 +967,10 @@ void pptx_text_context::set_process_layouts(bool val) impl_->process_layouts_ = val; } +std::wstring pptx_text_context::get_last_paragraph_style_name() +{ + return impl_->get_last_paragraph_style_name(); +} + } } diff --git a/OdfFile/Reader/Converter/pptx_text_context.h b/OdfFile/Reader/Converter/pptx_text_context.h index a0aa4dc68ae..ffb9d306a2d 100644 --- a/OdfFile/Reader/Converter/pptx_text_context.h +++ b/OdfFile/Reader/Converter/pptx_text_context.h @@ -58,6 +58,12 @@ enum field_type datetime }; +struct hyperlink_data +{ + std::wstring rId; + std::wstring action; +}; + class pptx_text_context: boost::noncopyable { public: @@ -85,8 +91,11 @@ class pptx_text_context: boost::noncopyable void start_object(); std::wstring end_object(); + hyperlink_data get_hyperlink(); void start_hyperlink(); - void end_hyperlink(std::wstring hId); + void set_rel_id(const std::wstring& rId); + void set_action(const std::wstring& action); + void end_hyperlink(); void start_field(field_type type, const std::wstring & styleName);//1 - datetime, 2 -pagecount, 3 - pagenumber - void end_field(); @@ -102,6 +111,8 @@ class pptx_text_context: boost::noncopyable styles_context & get_styles_context(); void set_process_layouts(bool val); + + std::wstring get_last_paragraph_style_name(); private: diff --git a/OdfFile/Reader/Converter/xlsx_borders.cpp b/OdfFile/Reader/Converter/xlsx_borders.cpp index f8639ac6c42..0a4b17c8f37 100644 --- a/OdfFile/Reader/Converter/xlsx_borders.cpp +++ b/OdfFile/Reader/Converter/xlsx_borders.cpp @@ -55,19 +55,52 @@ std::wstring convert_border_style(const odf_types::border_style& borderStyle) { std::wstring retVal = L"none"; - if (borderStyle.initialized()) + if (borderStyle.initialized()) { + double pt = borderStyle.get_length().get_value_unit(odf_types::length::pt); + if (borderStyle.get_style() == odf_types::border_style::none || borderStyle.is_none()) - retVal = L"none"; + { + retVal = L"none"; + } else if (borderStyle.get_style() == odf_types::border_style::double_) + { retVal = L"double"; + } else if (borderStyle.get_style() == odf_types::border_style::dotted) + { retVal = L"dotted"; - else if (borderStyle.get_style() == odf_types::border_style::dashed) - retVal = L"dashed"; + } + else if (borderStyle.get_style() == odf_types::border_style::dash) + { + if (pt > 1.5) retVal = L"mediumDashed"; + else retVal = L"dashed"; + } + else if (borderStyle.get_style() == odf_types::border_style::dot_dash) + { + if (pt > 1.5) retVal = L"mediumDashDot"; + else retVal = L"dashDot"; + } + else if (borderStyle.get_style() == odf_types::border_style::dot_dot_dash) + { + if (pt > 1.5) retVal = L"mediumDashDotDot"; + else retVal = L"dashDotDot"; + } + else if (borderStyle.get_style() == odf_types::border_style::fine_dashed) + { + retVal = L"slantDashDot"; + } + else if (borderStyle.get_style() == odf_types::border_style::double_thin) + { + retVal = L"double"; + } else - - retVal = L"thin"; + { + if (pt > 2.) retVal = L"thick"; + else if (pt > 1.5) retVal = L"medium"; + else if (pt < 0.1) retVal = L"hair"; + else retVal = L"thin"; + } } return retVal; } diff --git a/OdfFile/Reader/Converter/xlsx_conditionalFormatting.cpp b/OdfFile/Reader/Converter/xlsx_conditionalFormatting.cpp index 8a1dada7bad..b8975d54e23 100644 --- a/OdfFile/Reader/Converter/xlsx_conditionalFormatting.cpp +++ b/OdfFile/Reader/Converter/xlsx_conditionalFormatting.cpp @@ -74,6 +74,34 @@ namespace oox { } } } + void serializeEx(std::wostream& _Wostream) + { + CP_XML_WRITER(_Wostream) + { + CP_XML_NODE(L"x14:cfvo") + { + switch (type) + { + case 0: CP_XML_ATTR(L"type", L"percent"); break; + case 1: CP_XML_ATTR(L"type", L"num"); break; + case 2: CP_XML_ATTR(L"type", L"max"); break; + case 3: CP_XML_ATTR(L"type", L"min"); break; + case 4: CP_XML_ATTR(L"type", L"autoMax"); break; + case 5: CP_XML_ATTR(L"type", L"autoMin"); break; + case 6: CP_XML_ATTR(L"type", L"formula"); break; + case 7: CP_XML_ATTR(L"type", L"percentile"); break;//BOA PARA ESTUDAR - JOGAR LOTOFACIL minha predileta 1.ods + + } + if (val) + { + CP_XML_NODE(L"xm:f") + { + CP_XML_CONTENT(*val); + } + } + } + } + } }; struct rule @@ -90,6 +118,9 @@ namespace oox { _CP_OPT(std::wstring) formula2; _CP_OPT(int) rank; _CP_OPT(bool) bottom; + _CP_OPT(bool) equal; + _CP_OPT(bool) above; + _CP_OPT(int) stdDev; //color scale icon set data_bar std::vector<_cfvo> cfvo; //color scale data_bar(1 element) @@ -97,11 +128,12 @@ namespace oox { //data bar icon_set _CP_OPT(bool) showValue; //data bar - _CP_OPT(int) minLength; - _CP_OPT(int) maxLength; + _CP_OPT(unsigned int) minLength; + _CP_OPT(unsigned int) maxLength; _CP_OPT(std::wstring) axis_position; _CP_OPT(std::wstring) axis_color; _CP_OPT(std::wstring) negative_color; + _CP_OPT(bool) gradient; //icon set _CP_OPT(int) icon_set_type; _CP_OPT(bool) reverse; @@ -109,9 +141,19 @@ namespace oox { _CP_OPT(int) iconset_type; //date is _CP_OPT(int) time_period; + + bool isExtended() + { + if (gradient || axis_color || axis_position || negative_color) + { + return true; + } + return false; + } }; struct conditionalFormatting { + bool bUsed = false; std::wstring ref; std::vector rules; }; @@ -122,159 +164,353 @@ class xlsx_conditionalFormatting_context::Impl void serialize(std::wostream & _Wostream) { - if (!conditionalFormattings_.empty()) - { - int priority = 1; - CP_XML_WRITER(_Wostream) - { - for (size_t i = 0 ; i < conditionalFormattings_.size(); i++) - { - conditionalFormatting & c = conditionalFormattings_[i]; - - if (c.rules.size() < 1) continue; - - CP_XML_NODE(L"conditionalFormatting") - { - CP_XML_ATTR(L"sqref", c.ref); + if (conditionalFormattings_.empty()) return; - for (size_t j = 0 ; j < c.rules.size(); j++) + int priority = 1; + CP_XML_WRITER(_Wostream) + { + for (size_t i = 0; i < conditionalFormattings_.size(); i++) + { + conditionalFormatting& c = conditionalFormattings_[i]; + + if (c.bUsed) continue; + if (c.rules.size() < 1) continue; + + CP_XML_NODE(L"conditionalFormatting") + { + CP_XML_ATTR(L"sqref", c.ref); + + for (size_t j = 0; j < c.rules.size(); j++) + { + if (c.rules[j].type < 1 || c.rules[j].type > 5) continue; + + CP_XML_NODE(L"cfRule") { - if (c.rules[j].type < 1 || c.rules[j].type > 5) continue; + CP_XML_ATTR(L"priority", priority++); - CP_XML_NODE(L"cfRule") - { - CP_XML_ATTR(L"priority", priority++); - - if (c.rules[j].dxfId) CP_XML_ATTR(L"dxfId", *c.rules[j].dxfId); - if (c.rules[j].percent) CP_XML_ATTR(L"percent", *c.rules[j].percent); - if (c.rules[j].operator_) CP_XML_ATTR(L"operator", *c.rules[j].operator_); - if (c.rules[j].stopIfTrue) CP_XML_ATTR(L"stopIfTrue", *c.rules[j].stopIfTrue); - if (c.rules[j].text) CP_XML_ATTR(L"text", *c.rules[j].text); - if (c.rules[j].rank) CP_XML_ATTR(L"rank", *c.rules[j].rank); - if (c.rules[j].bottom) CP_XML_ATTR(L"bottom", *c.rules[j].bottom); - //CP_XML_ATTR(L"equalAverage" , 0); - //CP_XML_ATTR(L"aboveAverage" , 0); - if (c.rules[j].type == 1) + if (c.rules[j].dxfId) CP_XML_ATTR(L"dxfId", *c.rules[j].dxfId); + if (c.rules[j].percent) CP_XML_ATTR(L"percent", *c.rules[j].percent); + if (c.rules[j].operator_) CP_XML_ATTR(L"operator", *c.rules[j].operator_); + if (c.rules[j].stopIfTrue) CP_XML_ATTR(L"stopIfTrue", *c.rules[j].stopIfTrue); + if (c.rules[j].text) CP_XML_ATTR(L"text", *c.rules[j].text); + if (c.rules[j].rank) CP_XML_ATTR(L"rank", *c.rules[j].rank); + if (c.rules[j].bottom) CP_XML_ATTR(L"bottom", *c.rules[j].bottom); + if (c.rules[j].above) CP_XML_ATTR(L"aboveAverage", *c.rules[j].above); + if (c.rules[j].equal) CP_XML_ATTR(L"equalAverage", *c.rules[j].equal); + if (c.rules[j].stdDev) CP_XML_ATTR(L"stdDev", *c.rules[j].stdDev); + + if (c.rules[j].type == 1) + { + if (c.rules[j].formula_type) + CP_XML_ATTR(L"type", *c.rules[j].formula_type); + else + CP_XML_ATTR(L"type", L"cellIs"); + if ((c.rules[j].formula) && (!c.rules[j].formula->empty())) + { + CP_XML_NODE(L"formula") + { + CP_XML_CONTENT(*c.rules[j].formula); + } + } + if ((c.rules[j].formula2) && (!c.rules[j].formula2->empty())) + { + CP_XML_NODE(L"formula") + { + CP_XML_CONTENT(*c.rules[j].formula2); + } + } + } + else if (c.rules[j].type == 2) + { + CP_XML_ATTR(L"type", L"dataBar"); + CP_XML_NODE(L"dataBar") + { + if (c.rules[j].showValue) CP_XML_ATTR(L"showValue", *c.rules[j].showValue); + if (c.rules[j].minLength) CP_XML_ATTR(L"minLength", *c.rules[j].minLength); + if (c.rules[j].maxLength) CP_XML_ATTR(L"maxLength", *c.rules[j].maxLength); + if (c.rules[j].gradient) CP_XML_ATTR(L"gradient", *c.rules[j].gradient); + + for (size_t k = 0; k < c.rules[j].cfvo.size(); k++) + { + c.rules[j].cfvo[k].serialize(CP_XML_STREAM()); + } + + CP_XML_NODE(L"color") + { + CP_XML_ATTR(L"rgb", !c.rules[j].color.empty() ? c.rules[j].color[0] : L"FF000000"); + } + } + } + else if (c.rules[j].type == 3) + { + CP_XML_ATTR(L"type", L"colorScale"); + CP_XML_NODE(L"colorScale") { - if (c.rules[j].formula_type) - CP_XML_ATTR(L"type", *c.rules[j].formula_type); - else - CP_XML_ATTR(L"type", L"cellIs"); - if ((c.rules[j].formula) && (!c.rules[j].formula->empty())) + for (size_t k = 0; k < c.rules[j].cfvo.size(); k++) { - CP_XML_NODE(L"formula") + c.rules[j].cfvo[k].serialize(CP_XML_STREAM()); + } + for (size_t k = 0; k < c.rules[j].color.size(); k++) + { + CP_XML_NODE(L"color") { - CP_XML_CONTENT(*c.rules[j].formula); + CP_XML_ATTR(L"rgb", c.rules[j].color[k]); } } - if ((c.rules[j].formula2) && (!c.rules[j].formula2->empty())) + } + } + else if (c.rules[j].type == 4) + { + CP_XML_ATTR(L"type", L"iconSet"); + CP_XML_NODE(L"iconSet") + { + if (c.rules[j].icon_set_type) { - CP_XML_NODE(L"formula") + int h = *c.rules[j].icon_set_type; + switch (*c.rules[j].icon_set_type) { - CP_XML_CONTENT(*c.rules[j].formula2); + case 1: CP_XML_ATTR(L"iconSet", L"3ArrowsGray"); break; + case 2: CP_XML_ATTR(L"iconSet", L"3Flags"); break; + case 3: CP_XML_ATTR(L"iconSet", L"3Signs"); break; + case 4: CP_XML_ATTR(L"iconSet", L"3Symbols"); break; + case 5: CP_XML_ATTR(L"iconSet", L"3Symbols2"); break; + case 6: CP_XML_ATTR(L"iconSet", L"3TrafficLights1"); break; + case 7: CP_XML_ATTR(L"iconSet", L"3TrafficLights2"); break; + case 8: CP_XML_ATTR(L"iconSet", L"4Arrows"); break; + case 9: CP_XML_ATTR(L"iconSet", L"4ArrowsGray"); break; + case 10: CP_XML_ATTR(L"iconSet", L"4Rating"); break; + case 11: CP_XML_ATTR(L"iconSet", L"4RedToBlack"); break; + case 12: CP_XML_ATTR(L"iconSet", L"4TrafficLights"); break; + case 13: CP_XML_ATTR(L"iconSet", L"5Arrows"); break; + case 14: CP_XML_ATTR(L"iconSet", L"5ArrowsGray"); break; + case 15: CP_XML_ATTR(L"iconSet", L"5Quarters"); break; + case 16: CP_XML_ATTR(L"iconSet", L"5Rating"); break; + case 17: CP_XML_ATTR(L"iconSet", L"3Triangles"); break; + case 18: CP_XML_ATTR(L"iconSet", L"3Stars"); break; + case 19: CP_XML_ATTR(L"iconSet", L"5Boxes"); break; //todooo to ext + case 0: + default: CP_XML_ATTR(L"iconSet", L"3Arrows"); break; + break; } } + if (c.rules[j].showValue) CP_XML_ATTR(L"showValue", *c.rules[j].showValue); + + for (size_t k = 0; k < c.rules[j].cfvo.size(); k++) + { + c.rules[j].cfvo[k].serialize(CP_XML_STREAM()); + } + } + } + else if (c.rules[j].type == 5) + { + CP_XML_ATTR(L"type", L"timePeriod"); + switch (*c.rules[j].time_period) + { + case 0: CP_XML_ATTR(L"timePeriod", L"today"); break; + case 1: CP_XML_ATTR(L"timePeriod", L"yesterday"); break; + case 2: CP_XML_ATTR(L"timePeriod", L"tomorrow"); break; + case 3: CP_XML_ATTR(L"timePeriod", L"last7Days"); break; + case 4: CP_XML_ATTR(L"timePeriod", L"thisMonth"); break; + case 5: CP_XML_ATTR(L"timePeriod", L"lastMonth"); break; + case 6: CP_XML_ATTR(L"timePeriod", L"nextMonth"); break; + case 7: CP_XML_ATTR(L"timePeriod", L"thisWeek"); break; + case 8: CP_XML_ATTR(L"timePeriod", L"lastWeek"); break; + case 9: CP_XML_ATTR(L"timePeriod", L"nextWeek"); break; + } + } + } + } + } + } + } + } + void serializeEx(std::wostream& _Wostream) + { + if (conditionalFormattings_.empty()) return; + + int priority = 1; + CP_XML_WRITER(_Wostream) + { + for (size_t i = 0; i < conditionalFormattings_.size(); i++) + { + conditionalFormatting& c = conditionalFormattings_[i]; + + if (c.bUsed) continue; + if (c.rules.size() < 1) continue; + + for (size_t j = 0; j < c.rules.size(); j++) + { + if (c.rules[j].isExtended()) + { + c.bUsed = true; + break; + } + } + if (!c.bUsed) continue; + + CP_XML_NODE(L"x14:conditionalFormatting") + { + CP_XML_ATTR(L"xmlns:xm", L"http://schemas.microsoft.com/office/excel/2006/main"); + + for (size_t j = 0; j < c.rules.size(); j++) + { + if (c.rules[j].type < 1 || c.rules[j].type > 5) continue; + + CP_XML_NODE(L"x14:cfRule") + { + CP_XML_ATTR(L"priority", priority++); + + if (c.rules[j].dxfId) CP_XML_ATTR(L"dxfId", *c.rules[j].dxfId); + if (c.rules[j].percent) CP_XML_ATTR(L"percent", *c.rules[j].percent); + if (c.rules[j].operator_) CP_XML_ATTR(L"operator", *c.rules[j].operator_); + if (c.rules[j].stopIfTrue) CP_XML_ATTR(L"stopIfTrue", *c.rules[j].stopIfTrue); + if (c.rules[j].text) CP_XML_ATTR(L"text", *c.rules[j].text); + if (c.rules[j].rank) CP_XML_ATTR(L"rank", *c.rules[j].rank); + if (c.rules[j].bottom) CP_XML_ATTR(L"bottom", *c.rules[j].bottom); + if (c.rules[j].above) CP_XML_ATTR(L"aboveAverage", *c.rules[j].above); + if (c.rules[j].equal) CP_XML_ATTR(L"equalAverage", *c.rules[j].equal); + if (c.rules[j].stdDev) CP_XML_ATTR(L"stdDev", *c.rules[j].stdDev); + + if (c.rules[j].type == 1) + { + if (c.rules[j].formula_type) + CP_XML_ATTR(L"type", *c.rules[j].formula_type); + else + CP_XML_ATTR(L"type", L"cellIs"); + if ((c.rules[j].formula) && (!c.rules[j].formula->empty())) + { + CP_XML_NODE(L"formula") + { + CP_XML_CONTENT(*c.rules[j].formula); + } } - else if (c.rules[j].type == 2) + if ((c.rules[j].formula2) && (!c.rules[j].formula2->empty())) { - CP_XML_ATTR(L"type", L"dataBar"); - CP_XML_NODE(L"dataBar") + CP_XML_NODE(L"formula") { - if (c.rules[j].showValue) CP_XML_ATTR(L"showValue", *c.rules[j].showValue); - if (c.rules[j].minLength) CP_XML_ATTR(L"minLength", *c.rules[j].minLength); - if (c.rules[j].maxLength) CP_XML_ATTR(L"maxLength", *c.rules[j].maxLength); + CP_XML_CONTENT(*c.rules[j].formula2); + } + } + } + else if (c.rules[j].type == 2) + { + CP_XML_ATTR(L"type", L"dataBar"); + CP_XML_NODE(L"x14:dataBar") + { + if (c.rules[j].showValue) CP_XML_ATTR(L"showValue", *c.rules[j].showValue); + if (c.rules[j].minLength) CP_XML_ATTR(L"minLength", *c.rules[j].minLength); + if (c.rules[j].maxLength) CP_XML_ATTR(L"maxLength", *c.rules[j].maxLength); + if (c.rules[j].gradient) CP_XML_ATTR(L"gradient", *c.rules[j].gradient); + if (c.rules[j].axis_position) CP_XML_ATTR(L"axisPosition", *c.rules[j].axis_position); - for (size_t k = 0; k < c.rules[j].cfvo.size(); k++) + for (size_t k = 0; k < c.rules[j].cfvo.size(); k++) + { + c.rules[j].cfvo[k].serializeEx(CP_XML_STREAM()); + } + CP_XML_NODE(L"x14:fillColor") + { + CP_XML_ATTR(L"rgb", !c.rules[j].color.empty() ? c.rules[j].color[0] : L"FF000000"); + } + if (c.rules[j].negative_color) + { + CP_XML_NODE(L"x14:negativeFillColor") { - c.rules[j].cfvo[k].serialize(CP_XML_STREAM()); + CP_XML_ATTR(L"rgb", *c.rules[j].negative_color); } - - CP_XML_NODE(L"color") + } + if (c.rules[j].axis_color) + { + CP_XML_NODE(L"x14:axisColor") { - CP_XML_ATTR(L"rgb", !c.rules[j].color.empty() ? c.rules[j].color[0] : L"FF000000"); + CP_XML_ATTR(L"rgb", *c.rules[j].axis_color); } } } - else if (c.rules[j].type == 3) + } + else if (c.rules[j].type == 3) + { + CP_XML_ATTR(L"type", L"colorScale"); + CP_XML_NODE(L"x14:colorScale") { - CP_XML_ATTR(L"type", L"colorScale"); - CP_XML_NODE(L"colorScale") + for (size_t k = 0; k < c.rules[j].cfvo.size(); k++) { - for (size_t k = 0; k < c.rules[j].cfvo.size(); k++) - { - c.rules[j].cfvo[k].serialize(CP_XML_STREAM()); - } - for (size_t k = 0; k < c.rules[j].color.size(); k++) + c.rules[j].cfvo[k].serialize(CP_XML_STREAM()); + } + for (size_t k = 0; k < c.rules[j].color.size(); k++) + { + CP_XML_NODE(L"x14:color") { - CP_XML_NODE(L"color") - { - CP_XML_ATTR(L"rgb", c.rules[j].color[k]); - } - } + CP_XML_ATTR(L"rgb", c.rules[j].color[k]); + } } } - else if (c.rules[j].type == 4) + } + else if (c.rules[j].type == 4) + { + CP_XML_ATTR(L"type", L"iconSet"); + CP_XML_NODE(L"x14:iconSet") { - CP_XML_ATTR(L"type", L"iconSet"); - CP_XML_NODE(L"iconSet") + if (c.rules[j].icon_set_type) { - if (c.rules[j].icon_set_type) + switch (*c.rules[j].icon_set_type) { - switch (*c.rules[j].icon_set_type) - { - case 1: CP_XML_ATTR(L"iconSet", L"3ArrowsGray"); break; - case 2: CP_XML_ATTR(L"iconSet", L"3Flags"); break; - case 3: CP_XML_ATTR(L"iconSet", L"3Signs"); break; - case 4: CP_XML_ATTR(L"iconSet", L"3Symbols"); break; - case 5: CP_XML_ATTR(L"iconSet", L"3Symbols2"); break; - case 6: CP_XML_ATTR(L"iconSet", L"3TrafficLights1"); break; - case 7: CP_XML_ATTR(L"iconSet", L"3TrafficLights2"); break; - case 8: CP_XML_ATTR(L"iconSet", L"4Arrows"); break; - case 9: CP_XML_ATTR(L"iconSet", L"4ArrowsGray"); break; - case 10: CP_XML_ATTR(L"iconSet", L"4Rating"); break; - case 11: CP_XML_ATTR(L"iconSet", L"4RedToBlack"); break; - case 12: CP_XML_ATTR(L"iconSet", L"4TrafficLights"); break; - case 13: CP_XML_ATTR(L"iconSet", L"5Arrows"); break; - case 14: CP_XML_ATTR(L"iconSet", L"5ArrowsGray"); break; - case 15: CP_XML_ATTR(L"iconSet", L"5Quarters"); break; - case 16: CP_XML_ATTR(L"iconSet", L"5Rating"); break; - case 0: - default: CP_XML_ATTR(L"iconSet", L"3Arrows"); break; - break; - } + case 1: CP_XML_ATTR(L"iconSet", L"3ArrowsGray"); break; + case 2: CP_XML_ATTR(L"iconSet", L"3Flags"); break; + case 3: CP_XML_ATTR(L"iconSet", L"3Signs"); break; + case 4: CP_XML_ATTR(L"iconSet", L"3Symbols"); break; + case 5: CP_XML_ATTR(L"iconSet", L"3Symbols2"); break; + case 6: CP_XML_ATTR(L"iconSet", L"3TrafficLights1"); break; + case 7: CP_XML_ATTR(L"iconSet", L"3TrafficLights2"); break; + case 8: CP_XML_ATTR(L"iconSet", L"4Arrows"); break; + case 9: CP_XML_ATTR(L"iconSet", L"4ArrowsGray"); break; + case 10: CP_XML_ATTR(L"iconSet", L"4Rating"); break; + case 11: CP_XML_ATTR(L"iconSet", L"4RedToBlack"); break; + case 12: CP_XML_ATTR(L"iconSet", L"4TrafficLights"); break; + case 13: CP_XML_ATTR(L"iconSet", L"5Arrows"); break; + case 14: CP_XML_ATTR(L"iconSet", L"5ArrowsGray"); break; + case 15: CP_XML_ATTR(L"iconSet", L"5Quarters"); break; + case 16: CP_XML_ATTR(L"iconSet", L"5Rating"); break; + case 0: + default: CP_XML_ATTR(L"iconSet", L"3Arrows"); break; + break; } - if (c.rules[j].showValue) CP_XML_ATTR(L"showValue", *c.rules[j].showValue); - - for (size_t k = 0; k < c.rules[j].cfvo.size(); k++) - { - c.rules[j].cfvo[k].serialize(CP_XML_STREAM()); - } } - } - else if (c.rules[j].type == 5) - { - CP_XML_ATTR(L"type", L"timePeriod"); - switch (*c.rules[j].time_period) + if (c.rules[j].showValue) CP_XML_ATTR(L"showValue", *c.rules[j].showValue); + + for (size_t k = 0; k < c.rules[j].cfvo.size(); k++) { - case 0: CP_XML_ATTR(L"timePeriod", L"today"); break; - case 1: CP_XML_ATTR(L"timePeriod", L"yesterday"); break; - case 2: CP_XML_ATTR(L"timePeriod", L"tomorrow"); break; - case 3: CP_XML_ATTR(L"timePeriod", L"last7Days"); break; - case 4: CP_XML_ATTR(L"timePeriod", L"thisMonth"); break; - case 5: CP_XML_ATTR(L"timePeriod", L"lastMonth"); break; - case 6: CP_XML_ATTR(L"timePeriod", L"nextMonth"); break; - case 7: CP_XML_ATTR(L"timePeriod", L"thisWeek"); break; - case 8: CP_XML_ATTR(L"timePeriod", L"lastWeek"); break; - case 9: CP_XML_ATTR(L"timePeriod", L"nextWeek"); break; + c.rules[j].cfvo[k].serialize(CP_XML_STREAM()); } } } + else if (c.rules[j].type == 5) + { + CP_XML_ATTR(L"type", L"timePeriod"); + switch (*c.rules[j].time_period) + { + case 0: CP_XML_ATTR(L"timePeriod", L"today"); break; + case 1: CP_XML_ATTR(L"timePeriod", L"yesterday"); break; + case 2: CP_XML_ATTR(L"timePeriod", L"tomorrow"); break; + case 3: CP_XML_ATTR(L"timePeriod", L"last7Days"); break; + case 4: CP_XML_ATTR(L"timePeriod", L"thisMonth"); break; + case 5: CP_XML_ATTR(L"timePeriod", L"lastMonth"); break; + case 6: CP_XML_ATTR(L"timePeriod", L"nextMonth"); break; + case 7: CP_XML_ATTR(L"timePeriod", L"thisWeek"); break; + case 8: CP_XML_ATTR(L"timePeriod", L"lastWeek"); break; + case 9: CP_XML_ATTR(L"timePeriod", L"nextWeek"); break; + } + } } - } - } - } - } - } + } + + CP_XML_NODE(L"xm:sqref") + { + CP_XML_CONTENT(c.ref); + } + } + } + } + } std::vector conditionalFormattings_; }; @@ -290,7 +526,10 @@ void xlsx_conditionalFormatting_context::serialize(std::wostream & _Wostream) { return impl_->serialize(_Wostream); } - +void xlsx_conditionalFormatting_context::serializeEx(std::wostream& _Wostream) +{ + return impl_->serializeEx(_Wostream); +} void xlsx_conditionalFormatting_context::start(std::wstring ref) { formulasconvert::odf2oox_converter converter; @@ -301,7 +540,15 @@ void xlsx_conditionalFormatting_context::start(std::wstring ref) void xlsx_conditionalFormatting_context::add_rule(int type) { - impl_->conditionalFormattings_.back().rules.push_back(rule()); + if (false == impl_->conditionalFormattings_.back().rules.empty()) + { + if (impl_->conditionalFormattings_.back().rules.back().type != type) + { + impl_->conditionalFormattings_.push_back(impl_->conditionalFormattings_.back()); + impl_->conditionalFormattings_.back().rules.clear(); + } + } + impl_->conditionalFormattings_.back().rules.emplace_back(); impl_->conditionalFormattings_.back().rules.back().type = type; } void xlsx_conditionalFormatting_context::set_formula(std::wstring f) @@ -324,6 +571,22 @@ void xlsx_conditionalFormatting_context::set_formula(std::wstring f) { impl_->conditionalFormattings_.back().rules.back().formula_type = L"aboveAverage"; } + else if (f == L"below-average") + { + impl_->conditionalFormattings_.back().rules.back().formula_type = L"aboveAverage"; + impl_->conditionalFormattings_.back().rules.back().above = false; + } + else if (f == L"above-equal-average") + { + impl_->conditionalFormattings_.back().rules.back().formula_type = L"aboveAverage"; + impl_->conditionalFormattings_.back().rules.back().equal = true; + } + else if (f == L"below-equal-average") + { + impl_->conditionalFormattings_.back().rules.back().formula_type = L"aboveAverage"; + impl_->conditionalFormattings_.back().rules.back().above = false; + impl_->conditionalFormattings_.back().rules.back().equal = true; + } else if ( 0 <= (pos = f.find(L"formula-is("))) { impl_->conditionalFormattings_.back().rules.back().formula_type = L"expression"; @@ -339,11 +602,13 @@ void xlsx_conditionalFormatting_context::set_formula(std::wstring f) } else if (0 <= (pos = f.find(L"is-between("))) { + val = f.substr(11, f.size() - 12); impl_->conditionalFormattings_.back().rules.back().formula_type = L"expression"; impl_->conditionalFormattings_.back().rules.back().formula = converter.convert_named_expr(val); } else if (0 <= (pos = f.find(L"is-time("))) { + val = f.substr(8, f.size() - 9); impl_->conditionalFormattings_.back().rules.back().formula_type = L"expression"; impl_->conditionalFormattings_.back().rules.back().formula = converter.convert_named_expr(val); } @@ -352,6 +617,10 @@ void xlsx_conditionalFormatting_context::set_formula(std::wstring f) impl_->conditionalFormattings_.back().rules.back().formula_type = L"containsErrors"; impl_->conditionalFormattings_.back().rules.back().formula = L"0"; } + else if (0 <= (pos = f.find(L"is-no-error"))) + { + impl_->conditionalFormattings_.back().rules.back().formula_type = L"notContainsErrors"; + } else if (0 <= (pos = f.find(L"duplicate"))) { impl_->conditionalFormattings_.back().rules.back().formula_type = L"duplicateValues"; @@ -382,7 +651,9 @@ void xlsx_conditionalFormatting_context::set_formula(std::wstring f) } else if (0 <= (pos = f.find(L"contains-text"))) { - impl_->conditionalFormattings_.back().rules.back().formula_type = L"containsText"; + if (std::wstring::npos != f.find(L"not-contains-text")) + impl_->conditionalFormattings_.back().rules.back().formula_type = L"notContainsText"; + else impl_->conditionalFormattings_.back().rules.back().formula_type = L"containsText"; std::wstring text = f.substr(pos + 14, f.length() - pos - 15); @@ -464,6 +735,28 @@ void xlsx_conditionalFormatting_context::set_formula(std::wstring f) { val = converter.convert_named_expr( f ); } + else if (0 <= (pos = f.find(L"between"))) + { + if (0 <= (pos = f.find(L"not-between"))) + { + impl_->conditionalFormattings_.back().rules.back().operator_ = L"notBetween"; + val = f.substr(12, f.length() - 13); + } + else + { + impl_->conditionalFormattings_.back().rules.back().operator_ = L"between"; + val = f.substr(8, f.length() - 9); + } + + XmlUtils::replace_all(val, L"(", L""); + XmlUtils::replace_all(val, L")", L""); + if (0 <= (pos = val.find(L","))) + { + impl_->conditionalFormattings_.back().rules.back().formula2 = converter.convert_named_expr(val.substr(pos + 1)); + val = val.substr(0, pos); + } + val = converter.convert_named_expr(val); + } else if (0 <= (pos = f.find(L"!="))) { impl_->conditionalFormattings_.back().rules.back().operator_ = L"notEqual"; @@ -494,20 +787,6 @@ void xlsx_conditionalFormatting_context::set_formula(std::wstring f) impl_->conditionalFormattings_.back().rules.back().operator_ = L"greaterThan"; val = converter.convert_named_expr( f.substr(1) ); } - else if (0 <= (pos = f.find(L"between"))) - { - impl_->conditionalFormattings_.back().rules.back().operator_ = L"between"; - val = f.substr(8, f.length() - 9); - - XmlUtils::replace_all(val, L"(", L""); - XmlUtils::replace_all(val, L")", L""); - if (0 <= (pos = val.find(L","))) - { - impl_->conditionalFormattings_.back().rules.back().formula2 = converter.convert_named_expr( val.substr(pos + 1) ); - val = val.substr(0, pos); - } - val = converter.convert_named_expr( val ); - } else { val = converter.convert( f ); @@ -517,7 +796,11 @@ void xlsx_conditionalFormatting_context::set_formula(std::wstring f) impl_->conditionalFormattings_.back().rules.back().formula = val; } } -void xlsx_conditionalFormatting_context::set_dataBar(_CP_OPT(int) min, _CP_OPT(int) max) +void xlsx_conditionalFormatting_context::set_gradient(bool val) +{ + impl_->conditionalFormattings_.back().rules.back().gradient = val; +} +void xlsx_conditionalFormatting_context::set_dataBar(_CP_OPT(unsigned int) min, _CP_OPT(unsigned int) max) { impl_->conditionalFormattings_.back().rules.back().minLength = min; impl_->conditionalFormattings_.back().rules.back().maxLength = max; @@ -574,5 +857,10 @@ void xlsx_conditionalFormatting_context::set_time_period(int val) { impl_->conditionalFormattings_.back().rules.back().time_period = val; } +void xlsx_conditionalFormatting_context::set_stdDev(int val) +{ + impl_->conditionalFormattings_.back().rules.back().stdDev = val; +} + } } diff --git a/OdfFile/Reader/Converter/xlsx_conditionalFormatting.h b/OdfFile/Reader/Converter/xlsx_conditionalFormatting.h index 91762255418..ae3183febe2 100644 --- a/OdfFile/Reader/Converter/xlsx_conditionalFormatting.h +++ b/OdfFile/Reader/Converter/xlsx_conditionalFormatting.h @@ -50,11 +50,14 @@ class xlsx_conditionalFormatting_context void add_rule(int type); void set_formula(std::wstring f); - void set_dataBar(_CP_OPT(int) min, _CP_OPT(int) max); + + void set_dataBar(_CP_OPT(unsigned int) min, _CP_OPT(unsigned int) max); + void set_gradient(bool val); void set_dxf (int dxf_id); void set_showVal(bool val); void set_time_period(int val); + void set_stdDev(int val); void add_sfv (int type, std::wstring value); void add_color (std::wstring col); @@ -66,6 +69,7 @@ class xlsx_conditionalFormatting_context void set_icon_set_type(int type); void serialize(std::wostream & _Wostream); + void serializeEx(std::wostream& _Wostream); private: class Impl; _CP_SCOPED_PTR(Impl) impl_; diff --git a/OdfFile/Reader/Converter/xlsx_drawing.cpp b/OdfFile/Reader/Converter/xlsx_drawing.cpp index 8648095719c..e673b5fd07a 100644 --- a/OdfFile/Reader/Converter/xlsx_drawing.cpp +++ b/OdfFile/Reader/Converter/xlsx_drawing.cpp @@ -174,6 +174,7 @@ void xml_serialize_image(std::wostream & strm, _xlsx_drawing & val, const std::w CP_XML_NODE(L"a:avLst"); } oox_serialize_ln(CP_XML_STREAM(), val.additional); + oox_serialize_effects(CP_XML_STREAM(), val.additional); } xml_serialize_text(CP_XML_STREAM(), val, ns); } @@ -209,6 +210,7 @@ void xml_serialize_shape(std::wostream & strm, _xlsx_drawing & val, const std::w val.serialize_shape(CP_XML_STREAM()); oox_serialize_ln(CP_XML_STREAM(),val.additional, val.lined); + oox_serialize_effects(CP_XML_STREAM(), val.additional); } // xdr:spPr xml_serialize_text(CP_XML_STREAM(), val, ns); diff --git a/OdfFile/Reader/Converter/xlsx_output_xml.cpp b/OdfFile/Reader/Converter/xlsx_output_xml.cpp index b5c4379d326..1be20e37dba 100644 --- a/OdfFile/Reader/Converter/xlsx_output_xml.cpp +++ b/OdfFile/Reader/Converter/xlsx_output_xml.cpp @@ -41,8 +41,10 @@ namespace oox { class xlsx_xml_worksheet::Impl { public: - Impl(std::wstring const & name, bool hidden) : name_(name), hidden_(hidden) {} - std::wstring name_; + Impl(std::wstring const & name, bool hidden, const std::wstring& external) : name_(name), hidden_(hidden), external_(external) {} + + std::wstring external_; + std::wstring name_; bool hidden_; void clear() @@ -78,6 +80,7 @@ class xlsx_xml_worksheet::Impl std::wstringstream tableParts_; std::wstringstream autofilter_; std::wstringstream conditionalFormatting_; + std::wstringstream conditionalFormattingEx_; std::wstringstream picture_background_; std::wstringstream dataValidations_; std::wstringstream dataValidationsX14_; @@ -109,21 +112,21 @@ bool xlsx_xml_worksheet::hidden() const { return impl_->hidden_; } - -xlsx_xml_worksheet_ptr xlsx_xml_worksheet::create(std::wstring const & name, bool hidden) +std::wstring xlsx_xml_worksheet::external_ref() const { - return boost::make_shared(name, hidden); + return impl_->external_; } - -xlsx_xml_worksheet::xlsx_xml_worksheet(std::wstring const & name, bool hidden) - : impl_(new xlsx_xml_worksheet::Impl(name, hidden)) +xlsx_xml_worksheet_ptr xlsx_xml_worksheet::create(std::wstring const & name, bool hidden, const std::wstring& external) +{ + return boost::make_shared(name, hidden, external); +} +xlsx_xml_worksheet::xlsx_xml_worksheet(std::wstring const & name, bool hidden, const std::wstring& external) + : impl_(new xlsx_xml_worksheet::Impl(name, hidden, external)) { } - xlsx_xml_worksheet::~xlsx_xml_worksheet() { } - std::wostream & xlsx_xml_worksheet::cols() { return impl_->cols_; @@ -148,6 +151,10 @@ std::wostream & xlsx_xml_worksheet::conditionalFormatting() { return impl_->conditionalFormatting_; } +std::wostream& xlsx_xml_worksheet::conditionalFormattingEx() +{ + return impl_->conditionalFormattingEx_; +} std::wostream & xlsx_xml_worksheet::sort() { return impl_->sort_; @@ -209,7 +216,14 @@ rels & xlsx_xml_worksheet::sheet_rels() { return impl_->sheet_rels_; } - +void xlsx_xml_worksheet::write_external_to(std::wostream& strm) +{ + if (impl_->sheetData_.rdbuf()->in_avail() != 0) + { + impl_->sheetData_.flush(); + strm << impl_->sheetData_.rdbuf(); + } +} void xlsx_xml_worksheet::write_to(std::wostream & strm) { CP_XML_WRITER(strm) @@ -312,8 +326,9 @@ void xlsx_xml_worksheet::write_to(std::wostream & strm) std::wstring dataValidations14 = impl_->dataValidationsX14_.str(); std::wstring sparklines = impl_->sparklines_.str(); + std::wstring condFormattings = impl_->conditionalFormattingEx_.str(); - if (false == dataValidations14.empty() || false == sparklines.empty()) + if (false == dataValidations14.empty() || false == sparklines.empty() || false == condFormattings.empty()) { CP_XML_NODE(L"extLst") { @@ -337,6 +352,19 @@ void xlsx_xml_worksheet::write_to(std::wostream & strm) CP_XML_STREAM() << sparklines; } } + if (false == condFormattings.empty()) + { + CP_XML_NODE(L"ext") + { + CP_XML_ATTR(L"uri", L"{78C0D931-6437-407d-A8EE-F0AAD7539E65}"); + CP_XML_ATTR(L"xmlns:x14", L"http://schemas.microsoft.com/office/spreadsheetml/2009/9/main"); + + CP_XML_NODE(L"x14:conditionalFormattings") + { + CP_XML_STREAM() << condFormattings; + } + } + } } } } diff --git a/OdfFile/Reader/Converter/xlsx_output_xml.h b/OdfFile/Reader/Converter/xlsx_output_xml.h index ba49392a979..5db3c5957c1 100644 --- a/OdfFile/Reader/Converter/xlsx_output_xml.h +++ b/OdfFile/Reader/Converter/xlsx_output_xml.h @@ -46,11 +46,12 @@ typedef _CP_PTR(xlsx_xml_worksheet) xlsx_xml_worksheet_ptr; class xlsx_xml_worksheet: noncopyable { public: - xlsx_xml_worksheet(std::wstring const & name, bool hidden); + xlsx_xml_worksheet(std::wstring const& name, bool hidden, const std::wstring& external); ~xlsx_xml_worksheet(); std::wstring name() const; bool hidden() const; + std::wstring external_ref() const; std::wostream & cols(); std::wostream & sheetFormat(); @@ -61,6 +62,7 @@ class xlsx_xml_worksheet: noncopyable std::wostream & autofilter(); std::wostream & tableParts(); std::wostream & conditionalFormatting(); + std::wostream & conditionalFormattingEx(); std::wostream & picture_background(); std::wostream & dataValidations(); std::wostream & dataValidationsX14(); @@ -76,6 +78,7 @@ class xlsx_xml_worksheet: noncopyable rels & sheet_rels(); //hyperlink, background image, external, media ... void write_to(std::wostream & strm); + void write_external_to(std::wostream& strm); void set_drawing_link (std::wstring const & fileName, std::wstring const & id); void set_vml_drawing_link (std::wstring const & fileName, std::wstring const & id); @@ -85,7 +88,7 @@ class xlsx_xml_worksheet: noncopyable std::pair get_vml_drawing_link() const; std::pair get_comments_link() const; - static xlsx_xml_worksheet_ptr create(std::wstring const & name, bool hidden); + static xlsx_xml_worksheet_ptr create(std::wstring const & name, bool hidden, const std::wstring& external); private: class Impl; diff --git a/OdfFile/Reader/Converter/xlsx_table_state.cpp b/OdfFile/Reader/Converter/xlsx_table_state.cpp index 1c3249a2d96..445c20d3538 100644 --- a/OdfFile/Reader/Converter/xlsx_table_state.cpp +++ b/OdfFile/Reader/Converter/xlsx_table_state.cpp @@ -794,10 +794,14 @@ void xlsx_table_state::serialize_hyperlinks(std::wostream & strm) { return xlsx_hyperlinks_.xlsx_serialize(strm); } -void xlsx_table_state::serialize_conditionalFormatting(std::wostream & strm) +void xlsx_table_state::serialize_condFormatting(std::wostream & strm) { return xlsx_conditionalFormatting_context_.serialize(strm); } +void xlsx_table_state::serialize_condFormattingEx(std::wostream& strm) +{ + return xlsx_conditionalFormatting_context_.serializeEx(strm); +} void xlsx_table_state::dump_rels_hyperlinks(rels & Rels) { return xlsx_hyperlinks_.dump_rels(Rels); diff --git a/OdfFile/Reader/Converter/xlsx_table_state.h b/OdfFile/Reader/Converter/xlsx_table_state.h index 69f48a37b4a..b0ca244f7b6 100644 --- a/OdfFile/Reader/Converter/xlsx_table_state.h +++ b/OdfFile/Reader/Converter/xlsx_table_state.h @@ -203,7 +203,8 @@ class xlsx_table_state void set_background (std::wstring rId) { tableBackground_ = rId; } - void serialize_conditionalFormatting (std::wostream & _Wostream); + void serialize_condFormatting (std::wostream & _Wostream); + void serialize_condFormattingEx (std::wostream& _Wostream); void serialize_table_format (std::wostream & _Wostream); void serialize_merge_cells (std::wostream & _Wostream); void serialize_hyperlinks (std::wostream & _Wostream); diff --git a/OdfFile/Reader/Converter/xlsx_tablecontext.cpp b/OdfFile/Reader/Converter/xlsx_tablecontext.cpp index ed345d18d95..86ca45dda73 100644 --- a/OdfFile/Reader/Converter/xlsx_tablecontext.cpp +++ b/OdfFile/Reader/Converter/xlsx_tablecontext.cpp @@ -346,7 +346,7 @@ namespace oox { { xlsx_conversion_context_->get_dataValidations_context().clear(); } - void xlsx_table_context::start_cell(const std::wstring& formula, size_t columnsSpanned, size_t rowsSpanned) + void xlsx_table_context::start_cell(size_t columnsSpanned, size_t rowsSpanned) { state()->start_cell(columnsSpanned, rowsSpanned); } @@ -621,9 +621,13 @@ namespace oox { { return state()->serialize_protection(_Wostream); } - void xlsx_table_context::serialize_conditionalFormatting(std::wostream& _Wostream) + void xlsx_table_context::serialize_condFormatting(std::wostream& _Wostream) { - return state()->serialize_conditionalFormatting(_Wostream); + return state()->serialize_condFormatting(_Wostream); + } + void xlsx_table_context::serialize_condFormattingEx(std::wostream& _Wostream) + { + return state()->serialize_condFormattingEx(_Wostream); } void xlsx_table_context::serialize_merge_cells(std::wostream& _Wostream) { diff --git a/OdfFile/Reader/Converter/xlsx_tablecontext.h b/OdfFile/Reader/Converter/xlsx_tablecontext.h index 86b14088413..a52a82fff46 100644 --- a/OdfFile/Reader/Converter/xlsx_tablecontext.h +++ b/OdfFile/Reader/Converter/xlsx_tablecontext.h @@ -52,8 +52,7 @@ class xlsx_table_context void set_protection(bool val, const std::wstring &key, const std::wstring &algorithm); void end_table(); - void start_cell(const std::wstring & formula, - size_t columnsSpanned, + void start_cell(size_t columnsSpanned, size_t rowsSpanned); void end_cell(); @@ -88,7 +87,8 @@ class xlsx_table_context void serialize_autofilter (std::wostream & _Wostream); void serialize_merge_cells (std::wostream & _Wostream); void serialize_table_format (std::wostream & _Wostream); - void serialize_conditionalFormatting(std::wostream & _Wostream); + void serialize_condFormatting (std::wostream & _Wostream); + void serialize_condFormattingEx (std::wostream& _Wostream); void serialize_hyperlinks (std::wostream & _Wostream); void serialize_ole_objects (std::wostream & _Wostream); void serialize_controls (std::wostream & _Wostream); diff --git a/OdfFile/Reader/Converter/xlsx_textcontext.h b/OdfFile/Reader/Converter/xlsx_textcontext.h index 21462212109..f36eab7282d 100644 --- a/OdfFile/Reader/Converter/xlsx_textcontext.h +++ b/OdfFile/Reader/Converter/xlsx_textcontext.h @@ -54,7 +54,7 @@ namespace oox { class xlsx_conversion_context; -class xlsx_text_context: boost::noncopyable +class xlsx_text_context { public: xlsx_text_context (odf_reader::odf_read_context & odfContext); diff --git a/OdfFile/Reader/Converter/xlsxconversioncontext.cpp b/OdfFile/Reader/Converter/xlsxconversioncontext.cpp index 5f970538464..79bad92535d 100644 --- a/OdfFile/Reader/Converter/xlsxconversioncontext.cpp +++ b/OdfFile/Reader/Converter/xlsxconversioncontext.cpp @@ -138,16 +138,41 @@ void xlsx_conversion_context::end_document() if (sheets_.empty()) { // owncloud new document ... oO - start_table(L"Sheet1", L""); + start_table(L"Sheet1", L"", L""); current_sheet().cols() << L""; end_table(); } + std::map>> map_external_sheets; + + int sheet_id = 1; for (size_t i = 0; i < sheets_.size(); i++) { xlsx_xml_worksheet_ptr& sheet = sheets_[i]; + + std::wstring external_ref = sheet->external_ref(); + + if (false == external_ref.empty()) + { + std::wstringstream external_content; + sheet->write_external_to(external_content); + + std::map>>::iterator pFind = map_external_sheets.find(external_ref); + if (pFind != map_external_sheets.end()) + { + + pFind->second.push_back(std::make_pair(sheet->name(), external_content.str())); + } + else + { + std::vector> ext_sheet; + ext_sheet.push_back(std::make_pair(sheet->name(), external_content.str())); + map_external_sheets.insert(std::make_pair(sheet->external_ref(), ext_sheet)); + } + continue; + } - const std::wstring id = std::wstring(L"sId") + std::to_wstring(i + 1); + const std::wstring id = std::wstring(L"sId") + std::to_wstring(sheet_id++); package::sheet_content_ptr content = package::sheet_content::create(); //////////////////////////////////////////////////////////////////////////////////////////// @@ -218,7 +243,7 @@ void xlsx_conversion_context::end_document() { std::wstringstream strm; - xlsx_text_context_.serialize_shared_strings(strm); + get_text_context()->serialize_shared_strings(strm); output_document_->get_xl_files().set_sharedStrings( package::simple_element::create(L"sharedStrings.xml", strm.str()) ); } @@ -299,10 +324,39 @@ void xlsx_conversion_context::end_document() CP_XML_NODE(L"externalLink") { CP_XML_ATTR(L"xmlns", L"http://schemas.openxmlformats.org/spreadsheetml/2006/main"); + CP_XML_ATTR(L"xmlns:mc", L"http://schemas.openxmlformats.org/markup-compatibility/2006"); + CP_XML_NODE(L"externalBook") { CP_XML_ATTR(L"xmlns:r", L"http://schemas.openxmlformats.org/officeDocument/2006/relationships"); CP_XML_ATTR(L"r:id", L"rId1"); + + std::map>>::iterator pFind = map_external_sheets.find(it->first); + + if (pFind != map_external_sheets.end()) + { + CP_XML_NODE(L"sheetNames") + { + for (auto ex : pFind->second) + { + CP_XML_NODE(L"sheetName") + { + CP_XML_ATTR(L"val", ex.first); + } + } + } + CP_XML_NODE(L"sheetDataSet") + { + for (size_t x = 0; x < pFind->second.size(); ++x) + { + CP_XML_NODE(L"sheetData") + { + CP_XML_ATTR(L"sheetId", x); + CP_XML_STREAM() << pFind->second[x].second; + } + } + } + } } } } @@ -409,7 +463,7 @@ void xlsx_conversion_context::serialize_bookViews(std::wostream & strm) { for (size_t i = 0; i < sheets_.size(); i++) { - if (sheets_[i]->name() == *sActiveTable) + if (false == sheets_[i]->external_ref().empty() && sheets_[i]->name() == *sActiveTable) { CP_XML_ATTR(L"activeTab", i); } @@ -474,23 +528,31 @@ int xlsx_conversion_context::find_sheet_by_name(std::wstring tableName) } for (size_t i = 0; i < sheets_.size(); i++) { - if (sheets_[i]->name() == tableName) + if (false == sheets_[i]->external_ref().empty() && sheets_[i]->name() == tableName) return i; } return -1; } -bool xlsx_conversion_context::start_table(std::wstring tableName, std::wstring tableStyleName) +bool xlsx_conversion_context::start_table(const std::wstring& tableName, const std::wstring& tableStyleName, const std::wstring& externalRef) { - get_table_context().start_table(tableName, tableStyleName, sheets_.size() - 1); + get_table_context().start_table(tableName, tableStyleName, sheets_.size()); - sheets_.push_back(xlsx_xml_worksheet::create(tableName, get_table_context().state()->get_table_hidden())); + sheets_.push_back(xlsx_xml_worksheet::create(tableName, get_table_context().state()->get_table_hidden(), externalRef)); current_sheet().cols() << L""; - return true; + + return true; } void xlsx_conversion_context::end_table() { + const std::wstring external_ref = current_sheet().external_ref(); + + if (false == external_ref.empty()) + { + return; + } + const double lastWidht = table_column_last_width(); if (lastWidht > 0.0) { @@ -520,7 +582,8 @@ void xlsx_conversion_context::end_table() get_table_context().serialize_table_format (current_sheet().sheetFormat()); get_table_context().serialize_page_properties (current_sheet().page_properties()); get_table_context().serialize_header_footer (current_sheet().header_footer()); - get_table_context().serialize_conditionalFormatting (current_sheet().conditionalFormatting()); + get_table_context().serialize_condFormattingEx (current_sheet().conditionalFormattingEx()); + get_table_context().serialize_condFormatting (current_sheet().conditionalFormatting()); get_table_context().serialize_tableParts (current_sheet().tableParts(), current_sheet().sheet_rels()); get_table_context().serialize_autofilter (current_sheet().autofilter()); get_table_context().serialize_sort (current_sheet().sort()); @@ -586,20 +649,7 @@ void xlsx_conversion_context::end_table() } get_table_context().end_table(); } -//int xlsx_conversion_context::add_external_link(const std::wstring & external) -//{ -// std::unordered_map::iterator pFind = mapExternalLink_.find(external); -// if ( pFind == mapExternalLink_.end()) -// { -// int id = (int)mapExternalLink_.size() + 1; -// mapExternalLink_.insert(std::make_pair(external, id)); -// return id; -// } -// else -// { -// return pFind->second; -// } -//} + void xlsx_conversion_context::add_control_props(const std::wstring & rid, const std::wstring & target, const std::wstring & props) { if (rid.empty()) return; @@ -660,12 +710,12 @@ void xlsx_conversion_context::end_office_spreadsheet() void xlsx_conversion_context::start_paragraph(const std::wstring & styleName) { - xlsx_text_context_.start_paragraph(styleName); + get_text_context()->start_paragraph(styleName); } void xlsx_conversion_context::end_paragraph() { - if (xlsx_text_context_.is_drawing_context()) + if (get_text_context()->is_drawing_context()) { get_drawing_context().process_objects(get_table_metrics()); @@ -674,25 +724,25 @@ void xlsx_conversion_context::end_paragraph() std::wstringstream strm; get_drawing_context().serialize(strm, L"a", true); - xlsx_text_context_.add_paragraph(strm.str()); + get_text_context()->add_paragraph(strm.str()); } } - xlsx_text_context_.end_paragraph(); + get_text_context()->end_paragraph(); } void xlsx_conversion_context::start_span(const std::wstring & styleName) { - xlsx_text_context_.start_span(styleName); + get_text_context()->start_span(styleName); } void xlsx_conversion_context::end_span() { - xlsx_text_context_.end_span(); + get_text_context()->end_span(); } -void xlsx_conversion_context::start_table_cell(const std::wstring & formula, size_t columnsSpanned, size_t rowsSpanned) +void xlsx_conversion_context::start_table_cell(size_t columnsSpanned, size_t rowsSpanned) { - get_table_context().start_cell(formula, columnsSpanned, rowsSpanned); + get_table_context().start_cell(columnsSpanned, rowsSpanned); } bool xlsx_conversion_context::in_table_cell() @@ -914,6 +964,29 @@ void xlsx_conversion_context::add_jsaProject(const std::string &content) output_document_->get_xl_files().add_jsaProject(content); output_document_->get_content_types_file().add_or_find_default(L"bin"); } +void xlsx_conversion_context::start_text_context() +{ + minor_text_contexts_.push_back(new xlsx_text_context(odf_document_->odf_context())); +} +void xlsx_conversion_context::end_text_context() +{ + if (false == minor_text_contexts_.empty()) + { + delete minor_text_contexts_.back(); + minor_text_contexts_.pop_back(); + } +} +xlsx_text_context* xlsx_conversion_context::get_text_context() +{ + if (false == minor_text_contexts_.empty()) + { + return minor_text_contexts_.back(); + } + else + { + return &xlsx_text_context_; + } +} } } diff --git a/OdfFile/Reader/Converter/xlsxconversioncontext.h b/OdfFile/Reader/Converter/xlsxconversioncontext.h index 5f92f5a73d8..9b09fbb9b95 100644 --- a/OdfFile/Reader/Converter/xlsxconversioncontext.h +++ b/OdfFile/Reader/Converter/xlsxconversioncontext.h @@ -102,7 +102,7 @@ class xlsx_conversion_context : boost::noncopyable void start_span (const std::wstring & styleName); void end_span (); - bool start_table (std::wstring tableName, std::wstring tableStyleName); + bool start_table (const std::wstring& tableName, const std::wstring& tableStyleName, const std::wstring& externalRef); void end_table (); int find_sheet_by_name(std::wstring tableName); @@ -115,7 +115,7 @@ class xlsx_conversion_context : boost::noncopyable bool in_table_cell(); - void start_table_cell (const std::wstring & formula, size_t columnsSpanned, size_t rowsSpanned); + void start_table_cell (size_t columnsSpanned, size_t rowsSpanned); void end_table_cell (); void start_table_covered_cell (); @@ -158,7 +158,10 @@ class xlsx_conversion_context : boost::noncopyable void process_styles(); - xlsx_text_context & get_text_context() { return xlsx_text_context_; } + void start_text_context(); + void end_text_context(); + xlsx_text_context* get_text_context(); + xlsx_table_context & get_table_context() { return xlsx_table_context_; } const xlsx_table_context & get_table_context() const { return xlsx_table_context_; } xlsx_style_manager & get_style_manager() { return xlsx_style_; } @@ -197,6 +200,7 @@ class xlsx_conversion_context : boost::noncopyable bool table_structure_protected_ = false; + std::vector external_sheets_; std::vector sheets_; std::vector charts_; std::vector table_parts_; @@ -213,7 +217,10 @@ class xlsx_conversion_context : boost::noncopyable xlsx_style_manager xlsx_style_; xlsx_defined_names xlsx_defined_names_; xlsx_table_context xlsx_table_context_; - xlsx_text_context xlsx_text_context_; + + xlsx_text_context xlsx_text_context_; // main + std::vector minor_text_contexts_; + xlsx_pivots_context xlsx_pivots_context_; xlsx_comments_context_handle xlsx_comments_context_handle_; xlsx_dataValidations_context xlsx_dataValidations_context_; diff --git a/OdfFile/Reader/Format/anim_elements.cpp b/OdfFile/Reader/Format/anim_elements.cpp index 6138428aded..6577dfee8d4 100644 --- a/OdfFile/Reader/Format/anim_elements.cpp +++ b/OdfFile/Reader/Format/anim_elements.cpp @@ -39,8 +39,17 @@ #include "draw_common.h" +#include "../Converter/pptx_animation_context.h" +#include "svg_parser.h" +#include "../Converter/oox_drawing.h" +#include "../../../Common/Network/FileTransporter/include/manager.h" + #include #include +#include +//#include +#include +#include namespace cpdoccore { @@ -48,49 +57,705 @@ namespace cpdoccore { namespace odf_reader { +struct preset_id_maping +{ + odf_types::preset_id::type ODF_PresetID; + int OOX_PresetID; +}; + +struct preset_subtype_maping +{ + int OOX_PresetID; + std::wstring ODF_PresetID; +}; + +static const preset_id_maping s_preset_id_map[] = { + { preset_id::type::ooo_entrance_appear , 1 }, + { preset_id::type::ooo_entrance_fly_in , 2 }, + { preset_id::type::ooo_entrance_venetian_blinds , 3 }, + { preset_id::type::ooo_entrance_box , 4 }, + { preset_id::type::ooo_entrance_checkerboard , 5 }, + { preset_id::type::ooo_entrance_circle , 6 }, + { preset_id::type::ooo_entrance_fly_in_slow , 7 }, + { preset_id::type::ooo_entrance_diamond , 8 }, + { preset_id::type::ooo_entrance_dissolve_in , 9 }, + { preset_id::type::ooo_entrance_fade_in , 10 }, + { preset_id::type::ooo_entrance_flash_once , 11 }, + { preset_id::type::ooo_entrance_peek_in , 12 }, + { preset_id::type::ooo_entrance_plus , 13 }, + { preset_id::type::ooo_entrance_random_bars , 14 }, + { preset_id::type::ooo_entrance_spiral_in , 15 }, + { preset_id::type::ooo_entrance_split , 16 }, + { preset_id::type::ooo_entrance_stretchy , 17 }, + { preset_id::type::ooo_entrance_diagonal_squares , 18 }, + { preset_id::type::ooo_entrance_swivel , 19 }, + { preset_id::type::ooo_entrance_wedge , 20 }, + { preset_id::type::ooo_entrance_wheel , 21 }, + { preset_id::type::ooo_entrance_wipe , 22 }, + { preset_id::type::ooo_entrance_zoom , 23 }, + { preset_id::type::ooo_entrance_random , 24 }, + { preset_id::type::ooo_entrance_boomerang , 25 }, + { preset_id::type::ooo_entrance_bounce , 26 }, + { preset_id::type::ooo_entrance_colored_lettering , 27 }, + { preset_id::type::ooo_entrance_movie_credits , 28 }, + { preset_id::type::ooo_entrance_ease_in , 29 }, + { preset_id::type::ooo_entrance_float , 30 }, + { preset_id::type::ooo_entrance_turn_and_grow , 31 }, + { preset_id::type::ooo_entrance_breaks , 34 }, + { preset_id::type::ooo_entrance_pinwheel , 35 }, + { preset_id::type::ooo_entrance_rise_up , 37 }, + { preset_id::type::ooo_entrance_falling_in , 38 }, + { preset_id::type::ooo_entrance_thread , 39 }, + { preset_id::type::ooo_entrance_unfold , 40 }, + { preset_id::type::ooo_entrance_whip , 41 }, + { preset_id::type::ooo_entrance_ascend , 42 }, + { preset_id::type::ooo_entrance_center_revolve , 43 }, + { preset_id::type::ooo_entrance_fade_in_and_swivel , 45 }, + { preset_id::type::ooo_entrance_descend , 47 }, + { preset_id::type::ooo_entrance_sling , 48 }, + { preset_id::type::ooo_entrance_spin_in , 49 }, + { preset_id::type::ooo_entrance_compress , 50 }, + { preset_id::type::ooo_entrance_magnify , 51 }, + { preset_id::type::ooo_entrance_curve_up , 52 }, + { preset_id::type::ooo_entrance_fade_in_and_zoom , 53 }, + { preset_id::type::ooo_entrance_glide , 54 }, + { preset_id::type::ooo_entrance_expand , 55 }, + { preset_id::type::ooo_entrance_flip , 56 }, + { preset_id::type::ooo_entrance_fold , 58 }, + + { preset_id::type::ooo_emphasis_fill_color , 1 }, + { preset_id::type::ooo_emphasis_font , 2 }, + { preset_id::type::ooo_emphasis_font_color , 3 }, + { preset_id::type::ooo_emphasis_font_size , 4 }, + { preset_id::type::ooo_emphasis_font_style , 5 }, + { preset_id::type::ooo_emphasis_grow_and_shrink , 6 }, + { preset_id::type::ooo_emphasis_line_color , 7 }, + { preset_id::type::ooo_emphasis_spin , 8 }, + { preset_id::type::ooo_emphasis_transparency , 9 }, + { preset_id::type::ooo_emphasis_bold_flash , 10 }, + { preset_id::type::ooo_emphasis_blast , 14 }, + { preset_id::type::ooo_emphasis_bold_reveal , 15 }, + { preset_id::type::ooo_emphasis_color_over_by_word , 16 }, + { preset_id::type::ooo_emphasis_reveal_underline , 18 }, + { preset_id::type::ooo_emphasis_color_blend , 19 }, + { preset_id::type::ooo_emphasis_color_over_by_letter, 20 }, + { preset_id::type::ooo_emphasis_complementary_color , 21 }, + { preset_id::type::ooo_emphasis_complementary_color_2, 22 }, + { preset_id::type::ooo_emphasis_contrasting_color , 23 }, + { preset_id::type::ooo_emphasis_darken , 24 }, + { preset_id::type::ooo_emphasis_desaturate , 25 }, + { preset_id::type::ooo_emphasis_flash_bulb , 26 }, + { preset_id::type::ooo_emphasis_flicker , 27 }, + { preset_id::type::ooo_emphasis_grow_with_color , 28 }, + { preset_id::type::ooo_emphasis_lighten , 30 }, + { preset_id::type::ooo_emphasis_style_emphasis , 31 }, + { preset_id::type::ooo_emphasis_teeter , 32 }, + { preset_id::type::ooo_emphasis_vertical_highlight , 33 }, + { preset_id::type::ooo_emphasis_wave , 34 }, + { preset_id::type::ooo_emphasis_blink , 35 }, + { preset_id::type::ooo_emphasis_shimmer , 36 }, + + { preset_id::type::ooo_exit_disappear , 1 }, + { preset_id::type::ooo_exit_fly_out , 2 }, + { preset_id::type::ooo_exit_venetian_blinds , 3 }, + { preset_id::type::ooo_exit_box , 4 }, + { preset_id::type::ooo_exit_checkerboard , 5 }, + { preset_id::type::ooo_exit_circle , 6 }, + { preset_id::type::ooo_exit_crawl_out , 7 }, + { preset_id::type::ooo_exit_diamond , 8 }, + { preset_id::type::ooo_exit_dissolve , 9 }, + { preset_id::type::ooo_exit_fade_out , 10 }, + { preset_id::type::ooo_exit_flash_once , 11 }, + { preset_id::type::ooo_exit_peek_out , 12 }, + { preset_id::type::ooo_exit_plus , 13 }, + { preset_id::type::ooo_exit_random_bars , 14 }, + { preset_id::type::ooo_exit_spiral_out , 15 }, + { preset_id::type::ooo_exit_split , 16 }, + { preset_id::type::ooo_exit_collapse , 17 }, + { preset_id::type::ooo_exit_diagonal_squares , 18 }, + { preset_id::type::ooo_exit_swivel , 19 }, + { preset_id::type::ooo_exit_wedge , 20 }, + { preset_id::type::ooo_exit_wheel , 21 }, + { preset_id::type::ooo_exit_wipe , 22 }, + { preset_id::type::ooo_exit_zoom , 23 }, + { preset_id::type::ooo_exit_random , 24 }, + { preset_id::type::ooo_exit_boomerang , 25 }, + { preset_id::type::ooo_exit_bounce , 26 }, + { preset_id::type::ooo_exit_colored_lettering , 27 }, + { preset_id::type::ooo_exit_movie_credits , 28 }, + { preset_id::type::ooo_exit_ease_out , 29 }, + { preset_id::type::ooo_exit_float , 30 }, + { preset_id::type::ooo_exit_turn_and_grow , 31 }, + { preset_id::type::ooo_exit_breaks , 34 }, + { preset_id::type::ooo_exit_pinwheel , 35 }, + { preset_id::type::ooo_exit_sink_down , 37 }, + { preset_id::type::ooo_exit_swish , 38 }, + { preset_id::type::ooo_exit_thread , 39 }, + { preset_id::type::ooo_exit_unfold , 40 }, + { preset_id::type::ooo_exit_whip , 41 }, + { preset_id::type::ooo_exit_descend , 42 }, + { preset_id::type::ooo_exit_center_revolve , 43 }, + { preset_id::type::ooo_exit_fade_out_and_swivel , 45 }, + { preset_id::type::ooo_exit_ascend , 47 }, + { preset_id::type::ooo_exit_sling , 48 }, + { preset_id::type::ooo_exit_fade_out_and_zoom , 53 }, + { preset_id::type::ooo_exit_contract , 55 }, + { preset_id::type::ooo_exit_spin_out , 49 }, + { preset_id::type::ooo_exit_stretchy , 50 }, + { preset_id::type::ooo_exit_magnify , 51 }, + { preset_id::type::ooo_exit_curve_down , 52 }, + { preset_id::type::ooo_exit_glide , 54 }, + { preset_id::type::ooo_exit_flip , 56 }, + { preset_id::type::ooo_exit_fold , 58 }, + + { preset_id::type::ooo_motionpath_4_point_star , 16 }, + { preset_id::type::ooo_motionpath_5_point_star , 5 }, + { preset_id::type::ooo_motionpath_6_point_star , 11 }, + { preset_id::type::ooo_motionpath_8_point_star , 17 }, + { preset_id::type::ooo_motionpath_circle , 1 }, + { preset_id::type::ooo_motionpath_crescent_moon , 6 }, + { preset_id::type::ooo_motionpath_diamond , 3 }, + { preset_id::type::ooo_motionpath_equal_triangle , 13 }, + { preset_id::type::ooo_motionpath_oval , 12 }, + { preset_id::type::ooo_motionpath_heart , 9 }, + { preset_id::type::ooo_motionpath_hexagon , 4 }, + { preset_id::type::ooo_motionpath_octagon , 10 }, + { preset_id::type::ooo_motionpath_parallelogram , 14 }, + { preset_id::type::ooo_motionpath_pentagon , 15 }, + { preset_id::type::ooo_motionpath_right_triangle , 2 }, + { preset_id::type::ooo_motionpath_square , 7 }, + { preset_id::type::ooo_motionpath_teardrop , 18 }, + { preset_id::type::ooo_motionpath_trapezoid , 8 }, + { preset_id::type::ooo_motionpath_arc_down , 37 }, + { preset_id::type::ooo_motionpath_arc_left , 51 }, + { preset_id::type::ooo_motionpath_arc_right , 58 }, + { preset_id::type::ooo_motionpath_arc_up , 44 }, + { preset_id::type::ooo_motionpath_bounce_left , 41 }, + { preset_id::type::ooo_motionpath_bounce_right , 54 }, + { preset_id::type::ooo_motionpath_curvy_left , 48 }, + { preset_id::type::ooo_motionpath_curvy_right , 61 }, + { preset_id::type::ooo_motionpath_decaying_wave , 60 }, + { preset_id::type::ooo_motionpath_diagonal_down_right, 49 }, + { preset_id::type::ooo_motionpath_diagonal_up_right , 56 }, + { preset_id::type::ooo_motionpath_down , 42 }, + { preset_id::type::ooo_motionpath_funnel , 52 }, + { preset_id::type::ooo_motionpath_spring , 53 }, + { preset_id::type::ooo_motionpath_stairs_down , 62 }, + { preset_id::type::ooo_motionpath_turn_down , 50 }, + { preset_id::type::ooo_motionpath_turn_down_right , 36 }, + { preset_id::type::ooo_motionpath_turn_up , 43 }, + { preset_id::type::ooo_motionpath_turn_up_right , 57 }, + { preset_id::type::ooo_motionpath_up , 64 }, + { preset_id::type::ooo_motionpath_wave , 47 }, + { preset_id::type::ooo_motionpath_zigzag , 38 }, + { preset_id::type::ooo_motionpath_bean , 31 }, + { preset_id::type::ooo_motionpath_buzz_saw , 25 }, + { preset_id::type::ooo_motionpath_curved_square , 20 }, + { preset_id::type::ooo_motionpath_curved_x , 21 }, + { preset_id::type::ooo_motionpath_curvy_star , 23 }, + { preset_id::type::ooo_motionpath_figure_8_four , 28 }, + { preset_id::type::ooo_motionpath_horizontal_figure_8, 26 }, + { preset_id::type::ooo_motionpath_inverted_square , 34 }, + { preset_id::type::ooo_motionpath_inverted_triangle , 33 }, + { preset_id::type::ooo_motionpath_loop_de_loop , 24 }, + { preset_id::type::ooo_motionpath_neutron , 29 }, + { preset_id::type::ooo_motionpath_peanut , 27 }, + { preset_id::type::ooo_motionpath_clover , 32 }, + { preset_id::type::ooo_motionpath_pointy_star , 19 }, + { preset_id::type::ooo_motionpath_swoosh , 30 }, + { preset_id::type::ooo_motionpath_vertical_figure_8 , 22 }, + { preset_id::type::ooo_motionpath_left , 35 }, + { preset_id::type::ooo_motionpath_right , 63 }, + { preset_id::type::ooo_motionpath_spiral_left , 55 }, + { preset_id::type::ooo_motionpath_spiral_right , 46 }, + { preset_id::type::ooo_motionpath_sine_wave , 40 }, + { preset_id::type::ooo_motionpath_s_curve_1 , 59 }, + { preset_id::type::ooo_motionpath_s_curve_2 , 39 }, + { preset_id::type::ooo_motionpath_heartbeat , 45 }, + + { preset_id::type::none , 0 }, +}; + +static const preset_subtype_maping s_preset_subtype_maping[] = +{ + { 1, L"from-top" }, + { 2, L"from-right" }, + { 3, L"from-top-right" }, + { 4, L"from-bottom" }, + { 5, L"horizontal" }, + { 6, L"from-bottom-right" }, + { 8, L"from-left" }, + { 9, L"from-top-left" }, + { 10, L"vertical" }, + { 12, L"from-bottom-left" }, + { 16, L"in" }, + { 21, L"vertical-in" }, + { 26, L"horizontal-in" }, + { 32, L"out" }, + { 36, L"out-from-screen-center" }, + { 37, L"vertical-out" }, + { 42, L"horizontal-out" }, + { 272, L"in-slightly" }, + { 288, L"out-slightly" }, + { 528, L"in-from-screen-center" }, + { 0, L""} +}; + +static _CP_OPT(std::wstring) pptx_convert_smil_attribute_name(const odf_types::smil_attribute_name& smil_attribute_name_) +{ + using namespace odf_types; + + _CP_OPT(std::wstring) result; + + switch (smil_attribute_name_.get_type()) + { + case smil_attribute_name::charColor: result = boost::none; break; + case smil_attribute_name::charFontName: result = boost::none; break; + case smil_attribute_name::charHeight: result = boost::none; break; + case smil_attribute_name::charPosture: result = boost::none; break; + case smil_attribute_name::charUnderline: result = boost::none; break; + case smil_attribute_name::charWeight: result = boost::none; break; + case smil_attribute_name::color: result = L"style.color"; break; + case smil_attribute_name::fill: result = L"fill.type"; break; + case smil_attribute_name::fillColor: result = L"fillcolor"; break; + case smil_attribute_name::fillStyle: result = boost::none; break; + case smil_attribute_name::fillOn: result = L"fill.on"; break; + case smil_attribute_name::height: result = L"ppt_h"; break; + case smil_attribute_name::lineColor: result = boost::none; break; + case smil_attribute_name::lineStyle: result = boost::none; break; + case smil_attribute_name::opacity: result = L"style.opacity"; break; + case smil_attribute_name::rotate: result = L"style.rotation"; break; + case smil_attribute_name::stroke: result = L"stroke.on"; break; + case smil_attribute_name::strokeColor: result = L"stroke.color"; break; + case smil_attribute_name::skewX: result = L"xshear"; break; + case smil_attribute_name::skewY: result = boost::none; break; + case smil_attribute_name::visibility: result = L"style.visibility"; break; + case smil_attribute_name::width: result = L"ppt_w"; break; + case smil_attribute_name::x: result = L"ppt_x"; break; + case smil_attribute_name::y: result = L"ppt_y"; break; + case smil_attribute_name::dim: result = L"ppt_c"; break; + } + + return result; +} + +static std::wstring pptx_convert_presentation_node_type(const odf_types::presentation_node_type& presentation_node_type_) +{ + using namespace odf_types; + + switch (presentation_node_type_.get_type()) + { + case presentation_node_type::default_ : return L"clickEffect"; + case presentation_node_type::after_previous : return L"afterEffect"; + case presentation_node_type::interactive_sequence : return L"interactiveSeq"; + case presentation_node_type::main_sequence : return L"mainSeq"; + case presentation_node_type::on_click : return L"clickEffect"; + case presentation_node_type::timing_root : return L"tmRoot"; + case presentation_node_type::with_previous : return L"withEffect"; + } + + return L"clickEffect"; +} + +static std::wstring pptx_convert_animation_function(std::wstring animation_function) +{ + boost::replace_all(animation_function, L"x", L"#ppt_x"); + boost::replace_all(animation_function, L"y", L"#ppt_y"); + boost::replace_all(animation_function, L"width", L"#ppt_w"); + boost::replace_all(animation_function, L"height", L"#ppt_h"); + + return animation_function; +} + +static std::wstring pptx_convert_smil_begin(const std::wstring& smil_begin) +{ + if (smil_begin == L"next") + return L"indefinite"; + else if (smil_begin == L"indefinite") + return L"indefinite"; + if (boost::ends_with(smil_begin, L"click")) + return smil_begin; + + std::wstring delay; + clockvalue delayClockvalue = clockvalue::parse(smil_begin); + if (delayClockvalue.get_value() != -1) + delay = boost::lexical_cast(delayClockvalue.get_value()); + + return delay; +} + +static std::wstring pptx_convert_svg_path(const std::vector<::svg_path::_polyline>& polylines) +{ + using namespace ::svg_path; + + std::wstringstream result; + + for (size_t i = 0; i < polylines.size(); i++) + { + const _polyline& polyline = polylines[i]; + + if (polyline.command == L"a:close") + result << L"Z "; + else if (polyline.command == L"a:moveTo") + result << L"M "; + else if (polyline.command == L"a:lnTo") + result << L"L "; + else if (polyline.command == L"a:cubicBezTo") + result << L"C "; + else if (polyline.command == L"a:ArcTo") + result << L"G "; + + for (size_t pointIndex = 0; pointIndex < polyline.points.size(); pointIndex++) + { + if (polyline.points[pointIndex].x) + result << polyline.points[pointIndex].x << L" "; + if (polyline.points[pointIndex].y) + result << polyline.points[pointIndex].y << L" "; + } + } + + result << L"E"; // end of svg path + + return result.str(); +} + +static std::vector pptx_convert_smil_key_times(const odf_types::smil_key_times& key_times) +{ + std::vector result; + + const int pptx_key_time_multiplier = 100000; + const std::vector values = key_times.get_values(); + + for (size_t i = 0; i < values.size(); i++) + { + result.push_back(values[i] * pptx_key_time_multiplier); + } + + return result; +} + +static std::vector pptx_convert_smil_values(const odf_types::smil_values& smil_values_) +{ + std::vector result; + + const std::vector& values = smil_values_.get_values(); + + for (size_t i = 0; i < values.size(); i++) + { + std::wstring value = values[i]; + + boost::replace_all(value, L"x", L"ppt_x"); + boost::replace_all(value, L"y", L"ppt_y"); + boost::replace_all(value, L"width", L"ppt_w"); + boost::replace_all(value, L"height", L"ppt_h"); + + result.push_back(value); + } + + return result; +} + +static std::wstring pptx_convert_smil_fill(const odf_types::smil_fill& smil_fill_, bool durationSpecified) +{ + switch (smil_fill_.get_type()) + { + case smil_fill::type::_remove: return L"remove"; + case smil_fill::type::_freeze: return L"freeze"; + case smil_fill::type::_hold: return L"hold"; + case smil_fill::type::_transition: return L"transition"; + case smil_fill::type::_auto: + default: + return durationSpecified ? L"remove" : L"freeze"; + } +} +static int pptx_convert_acceleration(double acceleration) +{ + const int pptx_multiplier = 100000; + return static_cast(acceleration * pptx_multiplier); +} /////////////////////////////////////////////////////////////////////////////////////////////////////// -const wchar_t * anim_par::ns = L"anim"; -const wchar_t * anim_par::name = L"par"; +const wchar_t* anim_par::ns = L"anim"; +const wchar_t* anim_par::name = L"par"; void anim_par::add_attributes( const xml::attributes_wc_ptr & Attributes ) { - attlist_.add_attributes(Attributes); + common_attlist_.add_attributes(Attributes); + par_attlist_.add_attributes(Attributes); +} + +static _CP_OPT(int) pptx_convert_preset_subtype(const std::wstring& preset_class_, const int preset_id_, const std::wstring& preset_subtype_) +{ + _CP_OPT(int) pptx_preset_subtype; + + if ((preset_class_ == L"entr") || (preset_class_ == L"exit")) + { + // skip "wheel" preset id + if (preset_id_ != 21) + { + switch (preset_id_) + { + case 5: + { + if (preset_subtype_ == L"downward") + pptx_preset_subtype = 5; + else if (preset_subtype_ == L"across") + pptx_preset_subtype = 10; + } + break; + case 6: + { + if (preset_subtype_ == L"out") + pptx_preset_subtype = 16; + else if (preset_subtype_ == L"in") + pptx_preset_subtype = 32; + } + break; + case 17: + { + if (preset_subtype_ == L"across") + pptx_preset_subtype = 10; + } + break; + case 18: + { + if (preset_subtype_ == L"right-to-top") + pptx_preset_subtype = 3; + else if (preset_subtype_ == L"right-to-bottom") + pptx_preset_subtype = 6; + else if (preset_subtype_ == L"left-to-top") + pptx_preset_subtype = 9; + else if (preset_subtype_ == L"left-to-bottom") + pptx_preset_subtype = 12; + } + break; + } + } + + if (!pptx_preset_subtype) + { + const preset_subtype_maping* p = s_preset_subtype_maping; + while (p->OOX_PresetID != 0) + { + if (preset_subtype_ == p->ODF_PresetID) + { + pptx_preset_subtype = p->OOX_PresetID; + break; + } + p++; + } + } + } + + if (!pptx_preset_subtype) + { + try + { + pptx_preset_subtype = boost::lexical_cast(preset_subtype_); + } + catch (const boost::bad_lexical_cast& e) + { + pptx_preset_subtype = 0; + } + } + + return pptx_preset_subtype; } void anim_par::pptx_convert(oox::pptx_conversion_context & Context) { - if (anim_par_) + oox::pptx_animation_context & animationContext = Context.get_slide_context().get_animation_context(); + + _CP_OPT(std::wstring) presentationNodeType; + _CP_OPT(std::wstring) direction; + _CP_OPT(std::wstring) restart; + _CP_OPT(int) duration; + _CP_OPT(std::wstring) delay; // NOTE: Comes from smil:begin + _CP_OPT(std::wstring) end; + _CP_OPT(std::wstring) fill; + + _CP_OPT(std::wstring) presentationPresetClass; + _CP_OPT(int) presentationPresetId; + _CP_OPT(int) presentationPresetPresetSubType; + + bool isSlideAnimation = false; // NOTE: Анимация применяется к самому слайду, а не элементу на слайде + + _CP_OPT(int) accelerate; + _CP_OPT(int) decelerate; + + if (common_attlist_.presentation_node_type_) + presentationNodeType = pptx_convert_presentation_node_type(common_attlist_.presentation_node_type_.value()); + + if (common_attlist_.smil_direction_) + { + if (common_attlist_.smil_direction_.value() == L"reverse") + direction = L"reverse"; + } + + if (common_attlist_.smil_restart_) + { + // smil:restart = "never", "always", "whenNotActive" or "default". + // NOTE: Hardcode for now + // TODO: Figure out correct value + restart = boost::none; + } + + if (common_attlist_.smil_dur_) + { + duration = common_attlist_.smil_dur_->get_value(); + } + + if (common_attlist_.smil_begin_) + { + const std::wstring& smil_begin = common_attlist_.smil_begin_.value(); + isSlideAnimation = boost::algorithm::ends_with(smil_begin, L".begin"); + + if (boost::algorithm::contains(smil_begin, L"click")) + { + std::wstring id = smil_begin.substr(0, smil_begin.find(L".click")); + std::wstring del = L""; + + if(boost::algorithm::contains(smil_begin, L"+")) + del = smil_begin.substr(smil_begin.find(L"+")); + + animationContext.set_seq_animation_delay(del); + animationContext.set_seq_animation_restart(L"whenNotActive"); + animationContext.set_seq_animation_target_element(std::to_wstring(Context.get_slide_context().get_id(id))); + } + else if(!isSlideAnimation) + delay = pptx_convert_smil_begin(common_attlist_.smil_begin_.value()); + } + + // TODO: Figure out correct value + end = boost::none; + + if (par_attlist_.presentation_preset_class_) + { + switch (par_attlist_.presentation_preset_class_.value().get_type()) + { + case preset_class::entrance: + presentationPresetClass = L"entr"; + presentationPresetId = pptx_convert_preset_id(); + break; + case preset_class::exit: + presentationPresetClass = L"exit"; + presentationPresetId = pptx_convert_preset_id(); + break; + case preset_class::emphasis: + presentationPresetClass = L"emph"; + presentationPresetId = pptx_convert_preset_id(); + break; + case preset_class::motion_path: + presentationPresetClass = L"path"; + presentationPresetId = pptx_convert_preset_id(); + break; + case preset_class::ole_action: + presentationPresetClass = L"verb"; + break; + case preset_class::media_call: + presentationPresetClass = L"mediacall"; + break; + default: + presentationPresetClass = L"custom"; + } + + if (par_attlist_.presentation_preset_sub_type_ && presentationPresetId) + presentationPresetPresetSubType = pptx_convert_preset_subtype( + *presentationPresetClass, + *presentationPresetId, + *par_attlist_.presentation_preset_sub_type_); + else + presentationPresetPresetSubType = 0; + } + + if (common_attlist_.smil_fill_) { - Context.get_slide_context().start_slide_animation(); - anim_par_->pptx_convert(Context); // это для самого слайда (то что и нужно) - Context.get_slide_context().end_slide_animation(); + bool durationSpecified = common_attlist_.smil_dur_.has_value() || common_attlist_.smil_end_.has_value(); + fill = pptx_convert_smil_fill(common_attlist_.smil_fill_.value(), durationSpecified); + } + else + fill = L"hold"; + + if (par_attlist_.smil_accelerate_) + { + const int pptx_multiplyer = 100000; + accelerate = par_attlist_.smil_accelerate_.value() * pptx_multiplyer; + } + + if (par_attlist_.smil_decelerate_) + { + const int pptx_multiplyer = 100000; + decelerate = par_attlist_.smil_decelerate_.value() * pptx_multiplyer; + } + + if (!isSlideAnimation) + { + animationContext.start_par_animation(); + + if (presentationNodeType) animationContext.set_par_animation_presentation_node_type(presentationNodeType.value()); + if (direction) animationContext.set_par_animation_direction(direction.value()); + if (restart) animationContext.set_par_animation_restart(restart.value()); + if (duration) animationContext.set_par_animation_duration(duration.value()); + if (delay) animationContext.set_par_animation_delay(delay.value()); + if (end) animationContext.set_par_animation_end(end.value()); + if (presentationPresetClass) animationContext.set_par_animation_preset_class(presentationPresetClass.value()); + if (presentationPresetId) animationContext.set_par_animation_preset_id(presentationPresetId.value()); + if (presentationPresetPresetSubType) animationContext.set_par_animation_preset_subtype(presentationPresetPresetSubType.value()); + if (fill) animationContext.set_par_animation_fill(fill.value()); + if (accelerate) animationContext.set_par_animation_accelerate(accelerate.value()); + if (decelerate) animationContext.set_par_animation_decelerate(decelerate.value()); + } + + animationContext.set_is_slide_animation(isSlideAnimation); + + if (anim_par_array_.size()) + { + for(size_t i = 0; i < anim_par_array_.size(); i++) + anim_par_array_[i]->pptx_convert(Context); // это для самого слайда (то что и нужно) } -///////////////////////// последовательности .. (если один элемент - основная последовательность, иное - взаимодействующая анимация) - //slide_context().animation_context().start_sequence(); for (size_t i = 0; i < anim_seq_array_.size(); i++) { anim_seq_array_[i]->pptx_convert(Context); } - //slide_context().animation_context().end_sequence(); ///////////////////////////////////////////////////////////////// //внутренние эффекты - те что внутри одной последовательности for (size_t i = 0; i < content_.size(); i++) { content_[i]->pptx_convert(Context); } + + if(!isSlideAnimation) + animationContext.end_par_animation(); } void anim_par::add_child_element( xml::sax * Reader, const std::wstring & Ns, const std::wstring & Name) { if CP_CHECK_NAME(L"anim", L"par") - CP_CREATE_ELEMENT(anim_par_); + CP_CREATE_ELEMENT(anim_par_array_); else if CP_CHECK_NAME(L"anim", L"seq") CP_CREATE_ELEMENT(anim_seq_array_);//более 1 элемента- взаимосвязанная анимация (между фигурами) else CP_CREATE_ELEMENT(content_); } +boost::optional anim_par::pptx_convert_preset_id() +{ + if (par_attlist_.presentation_preset_id_) + { + preset_id::type presetID = par_attlist_.presentation_preset_id_.value().get_type(); + + for (size_t i = 0; s_preset_id_map[i].ODF_PresetID != preset_id::type::none; i++) + { + if (s_preset_id_map[i].ODF_PresetID == presetID) + return s_preset_id_map[i].OOX_PresetID; + } + + return 0; + } + + return boost::none; +} + /////////////////////////////////////////////////////////////////////////////////////////////////////// const wchar_t * anim_seq::ns = L"anim"; const wchar_t * anim_seq::name = L"seq"; @@ -102,29 +767,38 @@ void anim_seq::add_attributes( const xml::attributes_wc_ptr & Attributes ) void anim_seq::pptx_convert(oox::pptx_conversion_context & Context) { + _CP_OPT(std::wstring) presentationNodeType; + _CP_OPT(int) duration; + + if (attlist_.presentation_node_type_) + presentationNodeType = pptx_convert_presentation_node_type(attlist_.presentation_node_type_.value()); + + if (attlist_.smil_dur_) + duration = attlist_.smil_dur_->get_value(); + + oox::pptx_animation_context& animationContext = Context.get_slide_context().get_animation_context(); + + animationContext.start_seq_animation(); + + if (presentationNodeType) animationContext.set_seq_animation_presentation_node_type(presentationNodeType.value()); + if (attlist_.smil_direction_) animationContext.set_seq_animation_direction(attlist_.smil_direction_.value()); + if (attlist_.smil_restart_) animationContext.set_seq_animation_restart(attlist_.smil_restart_.value()); + if (duration) animationContext.set_seq_animation_dur(duration.value()); + if (attlist_.smil_begin_) animationContext.set_seq_animation_delay(attlist_.smil_begin_.value()); + if (attlist_.smil_end_) animationContext.set_seq_animation_end(attlist_.smil_end_.value()); + for (size_t i = 0; i < anim_par_array_.size(); i++) { anim_par_array_[i]->pptx_convert(Context); } + animationContext.end_seq_animation(); } void anim_seq::add_child_element( xml::sax * Reader, const std::wstring & Ns, const std::wstring & Name) -{ +{ if CP_CHECK_NAME(L"anim", L"par") CP_CREATE_ELEMENT(anim_par_array_); } //////////////////////////////////////////////////////////////// -void anim_transition_filter_attlist::add_attributes( const xml::attributes_wc_ptr & Attributes ) -{ - CP_APPLY_ATTR(L"smil:subtype", smil_subtype_); - CP_APPLY_ATTR(L"smil:type", smil_type_); - CP_APPLY_ATTR(L"smil:fadeColor", smil_fadeColor_); - CP_APPLY_ATTR(L"smil:mode", smil_mode_); -} -void anim_audio_attlist::add_attributes( const xml::attributes_wc_ptr & Attributes ) -{ - CP_APPLY_ATTR(L"xlink:href", xlink_href_); - CP_APPLY_ATTR(L"anim:audio-level", anim_audio_level_); -} const wchar_t * anim_transitionFilter::ns = L"anim"; const wchar_t * anim_transitionFilter::name = L"transitionFilter"; @@ -135,191 +809,507 @@ void anim_transitionFilter::add_attributes( const xml::attributes_wc_ptr & Attri filter_attlist_.add_attributes(Attributes); } -void anim_transitionFilter::pptx_convert(oox::pptx_conversion_context & Context) +std::wstring anim_transitionFilter::convert_filter() { - _CP_OPT(std::wstring) color; - _CP_OPT(std::wstring) dir; - _CP_OPT(int) time; - std::wstring type; - - _CP_OPT(std::wstring) param; - - if (common_attlist_.smil_dur_) - { - time = common_attlist_.smil_dur_->get_value(); - } - if (filter_attlist_.smil_fadeColor_) - { - color = filter_attlist_.smil_fadeColor_->get_hex_value(); - } - - smil_transition_type::type transition_type; + std::wstring filter; + const _CP_OPT(std::wstring)& subtype = filter_attlist_.smil_subtype_; + _CP_OPT(std::wstring) pptx_subtype; if (filter_attlist_.smil_type_) { - transition_type = filter_attlist_.smil_type_->get_type(); - } - - switch(transition_type) - { - case smil_transition_type::barnVeeWipe: - type = L"split"; - break; - case smil_transition_type::irisWipe: - if ((filter_attlist_.smil_subtype_) && (filter_attlist_.smil_subtype_.get()==L"diamond")) - type = L"diamond"; + switch (filter_attlist_.smil_type_.value().get_type()) + { + case smil_transition_type::barWipe: + filter = L"wipe"; + if (subtype) + { + if (subtype.value() == L"topToBottom") pptx_subtype = L"down"; + else pptx_subtype = L"up"; + } + else + pptx_subtype = L"up"; + break; + case smil_transition_type::boxWipe: + filter = L"slide"; + if (subtype) + { + if (subtype.value() == L"topRight") pptx_subtype = L"fromTop"; + else if (subtype.value() == L"bottomRight") pptx_subtype = L"fromBottom"; + else if (subtype.value() == L"bottomLeft") pptx_subtype = L"fromBottom"; + else if (subtype.value() == L"topCenter") pptx_subtype = L"fromTop"; + else if (subtype.value() == L"rightCenter") pptx_subtype = L"fromRight"; + else if (subtype.value() == L"bottomCenter") pptx_subtype = L"fromBottom"; + else if (subtype.value() == L"leftCenter") pptx_subtype = L"fromLeft"; + else pptx_subtype = L"fromTop"; + } + else + pptx_subtype = L"fromTop"; + break; + case smil_transition_type::fourBoxWipe: + filter = L"plus"; + if (subtype) + { + if (subtype.value() == L"cornersOut") pptx_subtype = L"out"; + else pptx_subtype = L"in"; + } else - type = L"zoom"; - break; - case smil_transition_type::miscDiagonalWipe: - if ((filter_attlist_.smil_subtype_) && (filter_attlist_.smil_subtype_.get()==L"doubleDiamond")) - type = L"diamond"; + pptx_subtype = L"in"; + break; + case smil_transition_type::barnDoorWipe: + filter = L"barn"; + if (subtype) + { + if (subtype.value() == L"horizontal") pptx_subtype = L"inHorizontal"; + else pptx_subtype = L"inVertical"; + } else - type = L"zoom"; - break; - case smil_transition_type::ellipseWipe: - case smil_transition_type::eyeWipe: - type = L"circle"; - break; - case smil_transition_type::roundRectWipe: - type = L"zoom"; - break; - case smil_transition_type::fourBoxWipe: - case smil_transition_type::triangleWipe: - case smil_transition_type::arrowHeadWipe: - case smil_transition_type::pentagonWipe: - case smil_transition_type::hexagonWipe: - case smil_transition_type::starWipe: - case smil_transition_type::miscShapeWipe: - type = L"plus"; - break; - case smil_transition_type::pinWheelWipe: - param = L"2"; - case smil_transition_type::clockWipe: - case smil_transition_type::singleSweepWipe: // - case smil_transition_type::doubleFanWipe: // - type = L"wheel"; - if ((filter_attlist_.smil_subtype_) && (filter_attlist_.smil_subtype_.get()==L"oneBlade")) param = L"1"; - else if ((filter_attlist_.smil_subtype_) && (filter_attlist_.smil_subtype_.get()==L"threeBlade")) param = L"3"; - else if ((filter_attlist_.smil_subtype_) && (filter_attlist_.smil_subtype_.get()==L"fourBlade")) param = L"4"; - else if ((filter_attlist_.smil_subtype_) && (filter_attlist_.smil_subtype_.get()==L"eightBlade")) param = L"8"; - break; - case smil_transition_type::fanWipe: - type = L"wedge"; + pptx_subtype = L"inHorizontal"; break; - case smil_transition_type::fade: - type = L"fade"; - param = L"1"; + case smil_transition_type::irisWipe: + if (subtype) + { + if (subtype.value() == L"rectangle") + { + filter = L"box"; + pptx_subtype = L"out"; + } + else if (subtype.value() == L"diamond") + { + filter = L"diamond"; + pptx_subtype = L"out"; + } + else + { + filter = L"box"; + pptx_subtype = L"out"; + } + } + else + { + filter = L"box"; + pptx_subtype = L"out"; + } break; - case smil_transition_type::checkerBoardWipe: - type = L"checker"; - if (filter_attlist_.smil_subtype_.get()==L"across") dir = L"horz"; - if (filter_attlist_.smil_subtype_.get()==L"down") dir = L"vert"; + case smil_transition_type::ellipseWipe: + filter = L"circle"; + pptx_subtype = L"out"; + break; + case smil_transition_type::pinWheelWipe: + filter = L"wheel"; + if (subtype) + { + if (subtype.value() == L"oneBlade") pptx_subtype = L"1"; + else if (subtype.value() == L"twoBladeVertical") pptx_subtype = L"2"; + else if (subtype.value() == L"fourBlade") pptx_subtype = L"4"; + else pptx_subtype = L"2"; + } + else + pptx_subtype = L"2"; break; - case smil_transition_type::blindsWipe: - type = L"blinds"; - if (filter_attlist_.smil_subtype_.get()==L"vertical") dir = L"vert"; - else if (filter_attlist_.smil_subtype_.get()==L"horizontal") dir = L"horz"; + case smil_transition_type::fanWipe: + filter = L"wedge"; break; - case smil_transition_type::diagonalWipe: case smil_transition_type::waterfallWipe: - type = L"strips"; - if (filter_attlist_.smil_subtype_) + filter = L"strips"; + if (subtype) + { + if (subtype.value() == L"horizontalLeft") pptx_subtype = L"downRight"; + else if (subtype.value() == L"horizontalRight") pptx_subtype = L"downLeft"; + else if (subtype.value() == L"verticalLeft") pptx_subtype = L"upRight"; + else if (subtype.value() == L"verticalRight") pptx_subtype = L"upLeft"; + else pptx_subtype = L"upRight"; + } + else + pptx_subtype = L"upRight"; + break; + case smil_transition_type::slideWipe: + filter = L"wipe"; + if (subtype) + { + if (subtype.value() == L"fromLeft") pptx_subtype = L"left"; + else if (subtype.value() == L"fromTop") pptx_subtype = L"up"; + else if (subtype.value() == L"fromRight") pptx_subtype = L"right"; + else if (subtype.value() == L"fromBottom") pptx_subtype = L"down"; + } + break; + case smil_transition_type::fade: + filter = L"fade"; + break; + case smil_transition_type::checkerBoardWipe: + filter = L"checkerboard"; + if (subtype) { - if (filter_attlist_.smil_subtype_.get() == L"horizontalLeft") dir = L"rd"; - else if (filter_attlist_.smil_subtype_.get() == L"horizontalRight") dir = L"lu"; - else if (filter_attlist_.smil_subtype_.get() == L"verticalRight") dir = L"ld"; - else dir = L"ru"; + if (subtype.value() == L"across") pptx_subtype = L"across"; + else pptx_subtype = L"across"; } + else + pptx_subtype = L"across"; + break; + case smil_transition_type::blindsWipe: + filter = L"blinds"; + if (subtype) + { + if (subtype.value() == L"horizontal") pptx_subtype = L"horizontal"; + else pptx_subtype = L"vertical"; + } + else + pptx_subtype = L"vertical"; break; case smil_transition_type::dissolve: - type = L"dissolve"; - break; + filter = L"dissolve"; + break; case smil_transition_type::randomBarWipe: - type = L"randomBar"; - if (filter_attlist_.smil_subtype_.get() == L"vertical") dir = L"vert"; - else if (filter_attlist_.smil_subtype_.get() == L"horizontal") dir = L"horz"; - break; - case smil_transition_type::pushWipe: - type = L"push"; - if (filter_attlist_.smil_subtype_.get() == L"combVertical") {type = L"comb"; dir = L"vert";} - else if (filter_attlist_.smil_subtype_.get() == L"combHorizontal") {type = L"comb"; dir = L"horz";} - break; - case smil_transition_type::slideWipe: - type = L"pull"; - break; - case smil_transition_type::boxWipe: - type = L"cover"; - break; - case smil_transition_type::barnDoorWipe: - type = L"split"; - if (filter_attlist_.smil_subtype_.get() == L"vertical") param = L"vert"; - if (filter_attlist_.smil_subtype_.get() == L"horizontal") param = L"horz"; + filter = L"randombar"; + if (subtype) + { + if (subtype.value() == L"horizontal") pptx_subtype = L"horizontal"; + else pptx_subtype = L"vertical"; + } break; - case smil_transition_type::barWipe: - type = L"wipe"; - if (filter_attlist_.smil_subtype_) + case smil_transition_type::pushWipe: + filter = L"slide"; + if (subtype) + pptx_subtype = subtype.value(); // fromLeft, fromTop, fromRight, fromBottom + break; + case smil_transition_type::doubleSweepWipe: + case smil_transition_type::doubleFanWipe: + filter = L"wheel"; + pptx_subtype = L"2"; + break; + case smil_transition_type::saloonDoorWipe: + case smil_transition_type::windshieldWipe: + filter = L"slide"; + pptx_subtype = L"fromLeft"; + break; + case smil_transition_type::snakeWipe: + if (subtype) { - if (filter_attlist_.smil_subtype_.get()==L"fromTopLeft") {type = L"strips"; dir = L"rd";} - else if (filter_attlist_.smil_subtype_.get()==L"fromBottomLeft") {type = L"strips"; dir = L"ru";} - else if (filter_attlist_.smil_subtype_.get()==L"fromTopRight") {type = L"strips"; dir = L"ld";} - else if (filter_attlist_.smil_subtype_.get()==L"fromBottomRight") {type = L"strips"; dir = L"lu";} - - else if (filter_attlist_.smil_subtype_.get()==L"fadeOverColor") {type = L"fade"; param = L"0";} + if (subtype.value() == L"topLeftHorizontal") { filter = L"slide" ; pptx_subtype = L"fromLeft"; } + else if (subtype.value() == L"topLeftVertical") { filter = L"slide" ; pptx_subtype = L"fromTop"; } + else if (subtype.value() == L"topLeftDiagonal") { filter = L"strips"; pptx_subtype = L"downRight"; } + else if (subtype.value() == L"topRightDiagonal") { filter = L"strips"; pptx_subtype = L"downLeft"; } + else if (subtype.value() == L"bottomRightDiagonal") { filter = L"strips"; pptx_subtype = L"upLeft"; } + else if (subtype.value() == L"bottomLeftDiagonal") { filter = L"strips"; pptx_subtype = L"upRight"; } + else + filter = L"fade"; } break; -/////////////////////////////////////////////////////// - case smil_transition_type::bowTieWipe: - case smil_transition_type::veeWipe: - case smil_transition_type::zigZagWipe: - case smil_transition_type::barnZigZagWipe: - case smil_transition_type::doubleSweepWipe: - case smil_transition_type::saloonDoorWipe: - case smil_transition_type::windshieldWipe: - case smil_transition_type::snakeWipe: - case smil_transition_type::spiralWipe: - case smil_transition_type::parallelSnakesWipe: - case smil_transition_type::boxSnakesWipe: - break; -////////////////////////////////////////////////////// - } - if (filter_attlist_.smil_subtype_) - { - if (!dir) - { - if (filter_attlist_.smil_subtype_.get()==L"leftToRight") + case smil_transition_type::spiralWipe: + filter = L"circle"; + break; + case smil_transition_type::parallelSnakesWipe: + if (subtype) { - if ((common_attlist_.smil_direction_) && (common_attlist_.smil_direction_.get()==L"reverse"))dir = L"l"; - else dir = L"r"; + if (boost::starts_with(subtype.value(), L"vertical")) + { + filter = L"barn"; + pptx_subtype = L"inVertical"; + } + else if (boost::starts_with(subtype.value(), L"horizontal")) + { + filter = L"barn"; + pptx_subtype = L"inHorizontal"; + } + else + filter = L"fade"; // NOTE: This is no corresponding transition to "diagonalBottomLeftOpposite" and "diagonalTopLeftOpposite" } - if (filter_attlist_.smil_subtype_.get()==L"topToBottom") + break; + case smil_transition_type::boxSnakesWipe: + if (subtype) { - if ((common_attlist_.smil_direction_) && (common_attlist_.smil_direction_.get()==L"reverse"))dir = L"u"; - else dir = L"d"; + filter = L"barn"; + if (subtype.value() == L"twoBoxTop") pptx_subtype = L"inVertical"; + else if (subtype.value() == L"twoBoxBottom") pptx_subtype = L"inVertical"; + else if (subtype.value() == L"twoBoxLeft") pptx_subtype = L"inHorizontal"; + else if (subtype.value() == L"twoBoxRight") pptx_subtype = L"inHorizontal"; + else if (subtype.value() == L"fourBoxVertical") pptx_subtype = L"inVertical"; + else if (subtype.value() == L"fourBoxHorizontal") pptx_subtype = L"inVertical"; + else + pptx_subtype = L"inVertical"; } + break; - if (filter_attlist_.smil_subtype_.get()==L"fromTop") dir = L"d"; - else if (filter_attlist_.smil_subtype_.get()==L"fromLeft") dir = L"r"; - else if (filter_attlist_.smil_subtype_.get()==L"fromRight") dir = L"l"; - else if (filter_attlist_.smil_subtype_.get()==L"fromBottom") dir = L"u"; - - else if (filter_attlist_.smil_subtype_.get()==L"topRight") dir = L"ld"; - else if (filter_attlist_.smil_subtype_.get()==L"bottomLeft") dir = L"lu"; - else if (filter_attlist_.smil_subtype_.get()==L"bottomRight") dir = L"ru"; - else if (filter_attlist_.smil_subtype_.get()==L"topLeft") dir = L"rd"; - - else if (filter_attlist_.smil_subtype_.get()==L"fromTopLeft") dir = L"rd"; - else if (filter_attlist_.smil_subtype_.get()==L"fromBottomLeft")dir = L"ru"; - else if (filter_attlist_.smil_subtype_.get()==L"fromTopRight") dir = L"ld"; - else if (filter_attlist_.smil_subtype_.get()==L"fromBottomRight")dir = L"lu"; + // NOTE: Not implemented. There is no corresponding conversion. Set "fade" as default animation + case smil_transition_type::singleSweepWipe: + case smil_transition_type::eyeWipe: + case smil_transition_type::roundRectWipe: + case smil_transition_type::starWipe: + case smil_transition_type::miscShapeWipe: + case smil_transition_type::clockWipe: + case smil_transition_type::triangleWipe: + case smil_transition_type::arrowHeadWipe: + case smil_transition_type::pentagonWipe: + case smil_transition_type::hexagonWipe: + case smil_transition_type::diagonalWipe: + case smil_transition_type::bowTieWipe: + case smil_transition_type::miscDiagonalWipe: + case smil_transition_type::veeWipe: + case smil_transition_type::barnVeeWipe: + case smil_transition_type::zigZagWipe: + case smil_transition_type::barnZigZagWipe: + default: + filter = L"fade"; + break; + } + } + if (pptx_subtype) + { + if (filter_attlist_.smil_direction_ + && filter_attlist_.smil_direction_.value() == L"reverse") + { + if (pptx_subtype.value() == L"in") + pptx_subtype = L"out"; + else if (pptx_subtype.value() == L"out") + pptx_subtype = L"in"; + else if(pptx_subtype.value() == L"inHorizontal") + pptx_subtype = L"outHorizontal"; + else if (pptx_subtype.value() == L"outHorizontal") + pptx_subtype = L"inHorizontal"; } + filter += L"(" + pptx_subtype.value() + L")"; + } - if (!dir && (common_attlist_.smil_direction_) && (common_attlist_.smil_direction_.get()==L"reverse")) + + return filter; +} + +void anim_transitionFilter::convert_slide_transition_filter(oox::pptx_conversion_context& Context) +{ + _CP_OPT(std::wstring) color; + _CP_OPT(std::wstring) dir; + _CP_OPT(int) time; + std::wstring type; + + _CP_OPT(std::wstring) param; + + if (common_attlist_.smil_dur_) + { + time = common_attlist_.smil_dur_->get_value(); + } + if (filter_attlist_.smil_fadeColor_) + { + color = filter_attlist_.smil_fadeColor_->get_hex_value(); + } + + smil_transition_type::type transition_type; + + if (filter_attlist_.smil_type_) + { + transition_type = filter_attlist_.smil_type_->get_type(); + } + + switch (transition_type) + { + case smil_transition_type::barnVeeWipe: + type = L"split"; + break; + case smil_transition_type::irisWipe: + if ((filter_attlist_.smil_subtype_) && (filter_attlist_.smil_subtype_.get() == L"diamond")) + type = L"diamond"; + else + type = L"zoom"; + break; + case smil_transition_type::miscDiagonalWipe: + if ((filter_attlist_.smil_subtype_) && (filter_attlist_.smil_subtype_.get() == L"doubleDiamond")) + type = L"diamond"; + else + type = L"zoom"; + break; + case smil_transition_type::ellipseWipe: + case smil_transition_type::eyeWipe: + type = L"circle"; + break; + case smil_transition_type::roundRectWipe: + type = L"zoom"; + break; + case smil_transition_type::fourBoxWipe: + case smil_transition_type::triangleWipe: + case smil_transition_type::arrowHeadWipe: + case smil_transition_type::pentagonWipe: + case smil_transition_type::hexagonWipe: + case smil_transition_type::starWipe: + case smil_transition_type::miscShapeWipe: + type = L"plus"; + break; + case smil_transition_type::pinWheelWipe: + param = L"2"; + case smil_transition_type::clockWipe: + case smil_transition_type::singleSweepWipe: // + case smil_transition_type::doubleFanWipe: // + type = L"wheel"; + if ((filter_attlist_.smil_subtype_) && (filter_attlist_.smil_subtype_.get() == L"oneBlade")) param = L"1"; + else if ((filter_attlist_.smil_subtype_) && (filter_attlist_.smil_subtype_.get() == L"threeBlade")) param = L"3"; + else if ((filter_attlist_.smil_subtype_) && (filter_attlist_.smil_subtype_.get() == L"fourBlade")) param = L"4"; + else if ((filter_attlist_.smil_subtype_) && (filter_attlist_.smil_subtype_.get() == L"eightBlade")) param = L"8"; + break; + case smil_transition_type::fanWipe: + type = L"wedge"; + break; + case smil_transition_type::fade: + type = L"fade"; + param = L"1"; + break; + case smil_transition_type::checkerBoardWipe: + type = L"checker"; + if (filter_attlist_.smil_subtype_.get() == L"across") dir = L"horz"; + if (filter_attlist_.smil_subtype_.get() == L"down") dir = L"vert"; + break; + case smil_transition_type::blindsWipe: + type = L"blinds"; + if (filter_attlist_.smil_subtype_.get() == L"vertical") dir = L"vert"; + else if (filter_attlist_.smil_subtype_.get() == L"horizontal") dir = L"horz"; + break; + case smil_transition_type::diagonalWipe: + case smil_transition_type::waterfallWipe: + type = L"strips"; + if (filter_attlist_.smil_subtype_) + { + if (filter_attlist_.smil_subtype_.get() == L"horizontalLeft") dir = L"rd"; + else if (filter_attlist_.smil_subtype_.get() == L"horizontalRight") dir = L"lu"; + else if (filter_attlist_.smil_subtype_.get() == L"verticalRight") dir = L"ld"; + else dir = L"ru"; + } + break; + case smil_transition_type::dissolve: + type = L"dissolve"; + break; + case smil_transition_type::randomBarWipe: + type = L"randomBar"; + if (filter_attlist_.smil_subtype_) + { + if (filter_attlist_.smil_subtype_.get() == L"vertical") dir = L"vert"; + else if (filter_attlist_.smil_subtype_.get() == L"horizontal") dir = L"horz"; + } + break; + case smil_transition_type::pushWipe: + type = L"push"; + if (filter_attlist_.smil_subtype_.get() == L"combVertical") { type = L"comb"; dir = L"vert"; } + else if (filter_attlist_.smil_subtype_.get() == L"combHorizontal") { type = L"comb"; dir = L"horz"; } + break; + case smil_transition_type::slideWipe: + case smil_transition_type::boxWipe: + type = L"cover"; + break; + case smil_transition_type::barnDoorWipe: + type = L"split"; + if (filter_attlist_.smil_subtype_.get() == L"vertical") param = L"vert"; + if (filter_attlist_.smil_subtype_.get() == L"horizontal") param = L"horz"; + break; + case smil_transition_type::barWipe: + type = L"wipe"; + if (filter_attlist_.smil_subtype_) + { + if (filter_attlist_.smil_subtype_.get() == L"fromTopLeft") { type = L"strips"; dir = L"rd"; } + else if (filter_attlist_.smil_subtype_.get() == L"fromBottomLeft") { type = L"strips"; dir = L"ru"; } + else if (filter_attlist_.smil_subtype_.get() == L"fromTopRight") { type = L"strips"; dir = L"ld"; } + else if (filter_attlist_.smil_subtype_.get() == L"fromBottomRight") { type = L"strips"; dir = L"lu"; } + + else if (filter_attlist_.smil_subtype_.get() == L"fadeOverColor") { type = L"fade"; param = L"0"; } + } + break; + /////////////////////////////////////////////////////// + case smil_transition_type::bowTieWipe: + case smil_transition_type::veeWipe: + case smil_transition_type::zigZagWipe: + case smil_transition_type::barnZigZagWipe: + case smil_transition_type::doubleSweepWipe: + case smil_transition_type::saloonDoorWipe: + case smil_transition_type::windshieldWipe: + case smil_transition_type::snakeWipe: + case smil_transition_type::spiralWipe: + case smil_transition_type::parallelSnakesWipe: + case smil_transition_type::boxSnakesWipe: + break; + ////////////////////////////////////////////////////// + } + if (filter_attlist_.smil_subtype_) + { + if (!dir) + { + if (filter_attlist_.smil_subtype_.get() == L"leftToRight") + { + if ((common_attlist_.smil_direction_) && (common_attlist_.smil_direction_.get() == L"reverse"))dir = L"l"; + else dir = L"r"; + } + if (filter_attlist_.smil_subtype_.get() == L"topToBottom") + { + if ((common_attlist_.smil_direction_) && (common_attlist_.smil_direction_.get() == L"reverse"))dir = L"u"; + else dir = L"d"; + } + + if (filter_attlist_.smil_subtype_.get() == L"fromTop") dir = L"d"; + else if (filter_attlist_.smil_subtype_.get() == L"fromLeft") dir = L"r"; + else if (filter_attlist_.smil_subtype_.get() == L"fromRight") dir = L"l"; + else if (filter_attlist_.smil_subtype_.get() == L"fromBottom") dir = L"u"; + + else if (filter_attlist_.smil_subtype_.get() == L"topRight") dir = L"ld"; + else if (filter_attlist_.smil_subtype_.get() == L"bottomLeft") dir = L"lu"; + else if (filter_attlist_.smil_subtype_.get() == L"bottomRight") dir = L"ru"; + else if (filter_attlist_.smil_subtype_.get() == L"topLeft") dir = L"rd"; + + else if (filter_attlist_.smil_subtype_.get() == L"fromTopLeft") dir = L"rd"; + else if (filter_attlist_.smil_subtype_.get() == L"fromBottomLeft") dir = L"ru"; + else if (filter_attlist_.smil_subtype_.get() == L"fromTopRight") dir = L"ld"; + else if (filter_attlist_.smil_subtype_.get() == L"fromBottomRight") dir = L"lu"; + + } + + if (!dir && (common_attlist_.smil_direction_) && (common_attlist_.smil_direction_.get() == L"reverse")) dir = L"in"; } - Context.get_slide_context().set_transitionFilter(type , dir, param , time); + Context.get_slide_context().start_slide_animation(); + Context.get_slide_context().set_transitionFilter(type, dir, param, time); + Context.get_slide_context().end_slide_animation(); +} + +void anim_transitionFilter::pptx_convert(oox::pptx_conversion_context & Context) +{ + if (Context.get_slide_context().get_animation_context().get_is_slide_animation()) + { + convert_slide_transition_filter(Context); + return; + } + + std::wstring filter = convert_filter(); + _CP_OPT(std::wstring) transition; + _CP_OPT(int) time; + _CP_OPT(std::wstring) delay; + _CP_OPT(int) acceleration; + _CP_OPT(int) deceleration; + + size_t shapeId = 0; + + if (common_attlist_.smil_dur_) + time = common_attlist_.smil_dur_->get_value(); + + if (filter_attlist_.smil_mode_) + transition = filter_attlist_.smil_mode_.value(); + + if (common_attlist_.smil_target_element_) + shapeId = Context.get_slide_context().get_id(common_attlist_.smil_target_element_.value()); + + if (common_attlist_.smil_begin_) + delay = pptx_convert_smil_begin(common_attlist_.smil_begin_.value()); + + if (common_attlist_.smil_accelerate_) + acceleration = pptx_convert_acceleration(common_attlist_.smil_accelerate_.value()); + + if (common_attlist_.smil_decelerate_) + deceleration = pptx_convert_acceleration(common_attlist_.smil_decelerate_.value()); + + oox::pptx_animation_context& animationContext = Context.get_slide_context().get_animation_context(); + + animationContext.start_anim_effect(); + animationContext.set_anim_effect_filter(filter); + if(transition) animationContext.set_anim_effect_transition(transition.value()); + if (time) animationContext.set_anim_effect_duration(time.value()); + if (delay) animationContext.set_anim_effect_delay(delay.value()); + if (acceleration)animationContext.set_anim_effect_accel(acceleration.value()); + if (deceleration)animationContext.set_anim_effect_decel(deceleration.value()); + animationContext.set_anim_effect_shape_id(shapeId); + animationContext.end_anim_effect(); } const wchar_t * anim_audio::ns = L"anim"; @@ -331,10 +1321,566 @@ void anim_audio::add_attributes( const xml::attributes_wc_ptr & Attributes ) audio_attlist_.add_attributes(Attributes); } +//static bool is_absolute_path(const std::wstring& path) { +// boost::filesystem::path p(path); +// return p.is_absolute(); +//} + void anim_audio::pptx_convert(oox::pptx_conversion_context & Context) { + oox::pptx_slide_context& slideContext = Context.get_slide_context(); + oox::pptx_animation_context& animationContext = Context.get_slide_context().get_animation_context(); + + if (audio_attlist_.xlink_href_) + { + std::wstring href = audio_attlist_.xlink_href_.value(); + + if (boost::algorithm::starts_with(href, L"file:///")) + href = href.substr(std::wstring(L"file:///").size()); + //else if (boost::algorithm::starts_with(href, L"http")) + //{ + // const std::wstring mediaFolder = Context.root()->get_folder() + FILE_SEPARATOR_STR + L"Media"; + // if (!NSDirectory::Exists(mediaFolder)) + // NSDirectory::CreateDirectory(mediaFolder); + + // const std::wstring audioPath = mediaFolder + FILE_SEPARATOR_STR + NSFile::GetFileName(href); + // ASC::CDownloadManager::DownloadExternal(href, audioPath); + + // href = audioPath; + //} + + std::wstring relative_href = href; + if (slideContext.get_mediaitems()->is_internal_path(href, Context.root()->get_folder())) + { + relative_href = Context.root()->get_folder() + FILE_SEPARATOR_STR + href; + } + + if (NSFile::CFileBinary::Exists(relative_href)) + { + const std::wstring name = NSFile::GetFileName(href); + + std::wstring ref; + bool isInternal; + const std::wstring& rId = slideContext.get_mediaitems()->add_or_find_anim_audio(href, isInternal, ref); + + slideContext.add_rels(true, rId, ref, oox::_rels_type::typeAudio); + + animationContext.start_anim_audio(); + + animationContext.add_anim_audio(rId, name); + + animationContext.end_anim_audio(); + } + } + +} + +//////////////////////////////////////////////////////////////// + +const wchar_t* anim_set::ns = L"anim"; +const wchar_t* anim_set::name = L"set"; + +void anim_set::pptx_convert(oox::pptx_conversion_context& Context) +{ + _CP_OPT(std::wstring) direction; + _CP_OPT(std::wstring) restart; + _CP_OPT(int) duration; + _CP_OPT(std::wstring) delay; + _CP_OPT(std::wstring) end; + _CP_OPT(std::wstring) fill; + _CP_OPT(std::wstring) autoRev; + _CP_OPT(std::wstring) attribute_name; + _CP_OPT(std::wstring) to_value; + size_t shapeID = 0; + + if (common_attlist_.smil_direction_) + { + } + + if (common_attlist_.smil_auto_reverse_) + autoRev = common_attlist_.smil_auto_reverse_->get() == true ? L"1" : L"0"; + + if (common_attlist_.smil_restart_) + { + } + + if (common_attlist_.smil_dur_) + { + duration = common_attlist_.smil_dur_->get_value(); + } + + if (common_attlist_.smil_begin_) + { + delay = pptx_convert_smil_begin(common_attlist_.smil_begin_.value()); + } + + if (common_attlist_.smil_end_) + { + } + + if (common_attlist_.smil_fill_) + { + fill = pptx_convert_smil_fill(common_attlist_.smil_fill_.value(), false); + } + + if (common_attlist_.smil_target_element_) + { + shapeID = Context.get_slide_context().get_id(common_attlist_.smil_target_element_.value()); + } + + if (common_attlist_.smil_attribute_name_) + { + attribute_name = pptx_convert_smil_attribute_name(common_attlist_.smil_attribute_name_.value()); + } + + if (set_attlist_.smil_to_) + { + if (set_attlist_.smil_to_.value() == L"visible") + to_value = L"visible"; + else if (set_attlist_.smil_to_.value() == L"hidden") + to_value = L"hidden"; + else if (set_attlist_.smil_to_.value() == L"solid") + to_value = L"solid"; + else if (set_attlist_.smil_to_.value() == L"false") + to_value = L"false"; + else if (set_attlist_.smil_to_.value() == L"true") + to_value = L"true"; + else + { + try + { + to_value = std::to_wstring(boost::lexical_cast(set_attlist_.smil_to_.value())); + } + catch (const boost::bad_lexical_cast& e) + { + // Ignore + } + } + } + + oox::pptx_animation_context& animationContext = Context.get_slide_context().get_animation_context(); + + animationContext.start_set(); + if (direction) animationContext.set_set_direction(direction.value()); + if (restart) animationContext.set_set_restart(restart.value()); + if (duration) animationContext.set_set_duration(duration.value()); + if (delay) animationContext.set_set_delay(delay.value()); + if (end) animationContext.set_set_end(end.value()); + if (autoRev) animationContext.set_set_auto_rev(autoRev.value()); + if (fill) animationContext.set_set_fill(fill.value()); + if (attribute_name) animationContext.set_set_attribute_name(attribute_name.value()); + if (to_value) animationContext.set_set_to_value(to_value.value()); + animationContext.set_set_shape_id(shapeID); + animationContext.end_set(); +} + +void anim_set::add_attributes(const xml::attributes_wc_ptr& Attributes) +{ + common_attlist_.add_attributes(Attributes); + set_attlist_.add_attributes(Attributes); +} + +//////////////////////////////////////////////////////////////// + +const wchar_t* anim_animate_motion::ns = L"anim"; +const wchar_t* anim_animate_motion::name = L"animateMotion"; + +void anim_animate_motion::pptx_convert(oox::pptx_conversion_context& Context) +{ + oox::pptx_animation_context& animationContext = Context.get_slide_context().get_animation_context(); + + size_t shapeID = 0; + _CP_OPT(std::wstring) path; + _CP_OPT(std::wstring) fill; + + if (common_attlist_.smil_target_element_) + shapeID = Context.get_slide_context().get_id(common_attlist_.smil_target_element_.value()); + + if (animate_motion_attlist_.svg_path_) + { + std::vector<::svg_path::_polyline> polylines; + bool closed, stroked; + ::svg_path::parseSvgD(polylines, animate_motion_attlist_.svg_path_.value(), false, closed, stroked); + + path = pptx_convert_svg_path(polylines); + } + + if (common_attlist_.smil_fill_) + { + fill = pptx_convert_smil_fill(common_attlist_.smil_fill_.value(), false); + } + + animationContext.start_animate_motion(); + +// if (common_attlist_.presentation_node_type_) animationContext.set_animate_motion_presentation_node_type(common_attlist_.presentation_node_type_.value()); +// if (common_attlist_.smil_direction_) animationContext.set_animate_motion_direction(common_attlist_.smil_direction_.value()); +// if (common_attlist_.smil_restart_) animationContext.set_animate_motion_restart(common_attlist_.smil_restart_.value()); + if (common_attlist_.smil_dur_) animationContext.set_animate_motion_dur(common_attlist_.smil_dur_.value().get_value()); +// if (common_attlist_.smil_begin_) animationContext.set_animate_motion_delay(common_attlist_.smil_begin_.value()); +// if (common_attlist_.smil_end_) animationContext.set_animate_motion_end(common_attlist_.smil_end_.value()); + + if (fill) animationContext.set_animate_motion_fill(fill.value()); + if (path) animationContext.set_animate_motion_svg_path(path.value()); + + animationContext.set_animate_motion_shape_id(shapeID); + + animationContext.end_animate_motion(); +} + +void anim_animate_motion::add_attributes(const xml::attributes_wc_ptr& Attributes) +{ + common_attlist_.add_attributes(Attributes); + animate_motion_attlist_.add_attributes(Attributes); } //////////////////////////////////////////////////////////////// +const wchar_t* anim_animate_color::ns = L"anim"; +const wchar_t* anim_animate_color::name = L"animateColor"; + +void anim_animate_color::pptx_convert(oox::pptx_conversion_context& Context) +{ + _CP_OPT(std::wstring) colorSpace = std::wstring(L"rgb"); + _CP_OPT(int) duration; + _CP_OPT(std::wstring) delay; + _CP_OPT(std::wstring) attributeName; + _CP_OPT(std::wstring) toValue; + _CP_OPT(std::wstring) byValue; + _CP_OPT(std::wstring) fill = std::wstring(L"hold"); + _CP_OPT(bool) autoRev = false; + _CP_OPT(std::wstring) dir = std::wstring(L"cw"); // clockwise (cw) + size_t shapeID = 0; + + if (animate_color_attlist_.anim_color_interpolation_) + { + colorSpace = animate_color_attlist_.anim_color_interpolation_.value(); + } + + if (animate_color_attlist_.anim_color_interpolation_direction) + { + if (animate_color_attlist_.anim_color_interpolation_direction.value() == L"clockwise") + dir = L"cw"; + else if (animate_color_attlist_.anim_color_interpolation_direction.value() == L"counter-clockwise") + dir = L"ccw"; + } + + if (common_attlist_.smil_dur_) + duration = common_attlist_.smil_dur_->get_value(); + else + duration = 1; + + if (common_attlist_.smil_fill_) + { + bool durationSpecified = common_attlist_.smil_dur_.has_value() || common_attlist_.smil_end_.has_value(); + fill = pptx_convert_smil_fill(common_attlist_.smil_fill_.value(), durationSpecified); + } + + if (common_attlist_.smil_begin_) + delay = pptx_convert_smil_begin(common_attlist_.smil_begin_.value()); + + if (common_attlist_.smil_attribute_name_) + attributeName = pptx_convert_smil_attribute_name(common_attlist_.smil_attribute_name_.value()); + + if (animate_color_attlist_.smil_to_) + { + toValue = animate_color_attlist_.smil_to_.value(); + boost::erase_all(toValue.value(), L"#"); + } + + if (common_attlist_.smil_auto_reverse_) + autoRev = common_attlist_.smil_auto_reverse_->get(); + + if (animate_color_attlist_.smil_by_) + byValue = animate_color_attlist_.smil_by_.value(); + + if (common_attlist_.smil_target_element_) + shapeID = Context.get_slide_context().get_id(common_attlist_.smil_target_element_.value()); + + oox::pptx_animation_context& animationContext = Context.get_slide_context().get_animation_context(); + + animationContext.start_animate_color(); + if (colorSpace) animationContext.set_animate_color_color_space(colorSpace.value()); + if (duration) animationContext.set_animate_color_duration(duration.value()); + if (delay) animationContext.set_animate_color_delay(delay.value()); + if (attributeName) animationContext.set_animate_color_attribute_name(attributeName.value()); + if (toValue) animationContext.set_animate_color_to_value(toValue.value()); + if (byValue) animationContext.set_animate_color_by_value(byValue.value()); + if (autoRev) animationContext.set_animate_color_auto_rev(autoRev.value()); + if (dir) animationContext.set_animate_color_dir(dir.value()); + if (fill) animationContext.set_animate_color_fill(fill.value()); + animationContext.set_animate_color_shape_id(shapeID); + animationContext.end_animate_color(); +} + +void anim_animate_color::add_attributes(const xml::attributes_wc_ptr& Attributes) +{ + common_attlist_.add_attributes(Attributes); + animate_color_attlist_.add_attributes(Attributes); +} + +////////////////////////////////////////////////////////////////////////// +// anim:animate + +const wchar_t* anim_animate::ns = L"anim"; +const wchar_t* anim_animate::name = L"animate"; + +void anim_animate::pptx_convert(oox::pptx_conversion_context& Context) +{ + _CP_OPT(std::wstring) calcmode; + _CP_OPT(std::wstring) valueType; + _CP_OPT(int) duration; + _CP_OPT(std::wstring) attributeName; + size_t shapeID = 0; + _CP_OPT(std::wstring) from; + _CP_OPT(std::wstring) to; + _CP_OPT(std::wstring) by; + _CP_OPT(std::wstring) additive; + _CP_OPT(bool) autoRev; + _CP_OPT(std::wstring) delay; + _CP_OPT(std::wstring) formula; + std::vector values; + std::vector keyTimes; + + if (animate_attlist_.smil_calc_mode_) + { + if (animate_attlist_.smil_calc_mode_.value() == L"discrete") calcmode = L"discrete"; + else calcmode = L"lin"; + } + else + calcmode = L"lin"; + + valueType = L"num"; + duration = common_attlist_.smil_dur_ ? common_attlist_.smil_dur_->get_value() : 1; + + if (common_attlist_.smil_attribute_name_) + { + attributeName = pptx_convert_smil_attribute_name(common_attlist_.smil_attribute_name_.value()); + } + + if (common_attlist_.smil_target_element_) + shapeID = Context.get_slide_context().get_id(common_attlist_.smil_target_element_.value()); + + if (animate_attlist_.smil_values_) + values = pptx_convert_smil_values(animate_attlist_.smil_values_.value()); + + if (animate_attlist_.smil_key_times_) + keyTimes = pptx_convert_smil_key_times(animate_attlist_.smil_key_times_.value()); + + if (animate_attlist_.anim_formula_) + formula = pptx_convert_animation_function(animate_attlist_.anim_formula_.value()); + + if (animate_attlist_.smil_from_) + from = pptx_convert_animation_function(animate_attlist_.smil_from_.value()); + + if (animate_attlist_.smil_to_) + to = pptx_convert_animation_function(animate_attlist_.smil_to_.value()); + + if (animate_attlist_.smil_by_) + by = pptx_convert_animation_function(animate_attlist_.smil_by_.value()); + + if (animate_attlist_.smil_additive_) + { + switch (animate_attlist_.smil_additive_.value().get_type()) + { + case odf_types::smil_additive::replace: additive = L"repl"; + case odf_types::smil_additive::sum: additive = L"sum"; + default: additive = L"repl"; + } + } + else + additive = L"repl"; + + if (animate_attlist_.smil_auto_reverse_) + { + autoRev = animate_attlist_.smil_auto_reverse_.value().get(); + } + + if (common_attlist_.smil_begin_) + { + delay = pptx_convert_smil_begin(common_attlist_.smil_begin_.value()); + } + + oox::pptx_animation_context& animationContext = Context.get_slide_context().get_animation_context(); + animationContext.start_animate(); + if (calcmode) animationContext.set_animate_calc_mode(calcmode.value()); + if (valueType) animationContext.set_animate_value_type(valueType.value()); + if (duration) animationContext.set_animate_duration(duration.value()); + if (attributeName) animationContext.set_animate_attribute_name(attributeName.value()); + if (from) animationContext.set_animate_from(from.value()); + if (to) animationContext.set_animate_to(to.value()); + if (by) animationContext.set_animate_by(by.value()); + if (additive) animationContext.set_animate_additive(additive.value()); + if (autoRev) animationContext.set_animate_auto_reverse(autoRev.value()); + if (delay) animationContext.set_animate_delay(delay.value()); + animationContext.set_animate_shape_id(shapeID); + + if (keyTimes.size() == values.size()) + { + size_t size = keyTimes.size(); + + for (size_t i = 0; i < size; i++) + { + animationContext.add_animate_keypoint(keyTimes[i], values[i], formula); + } + } + + animationContext.end_animate(); +} + +void anim_animate::add_attributes(const xml::attributes_wc_ptr& Attributes) +{ + common_attlist_.add_attributes(Attributes); + animate_attlist_.add_attributes(Attributes); +} + +////////////////////////////////////////////////////////////////////////// +// anim:animateTransform + +const wchar_t* anim_animate_transform::ns = L"anim"; +const wchar_t* anim_animate_transform::name = L"animateTransform"; + +static std::vector smil_list_to_oox_vector(const std::wstring& list, int pptx_mulipier) +{ + std::vector oox_list; + std::vector list_str; + boost::split(list_str, list, boost::is_any_of(",")); + + for (const auto& el : list_str) + { + try + { + int num = boost::lexical_cast(el) * pptx_mulipier; + oox_list.push_back(num); + } + catch (boost::bad_lexical_cast e) + { + continue; + } + } + + return oox_list; +} + +void anim_animate_transform::pptx_convert(oox::pptx_conversion_context& Context) +{ + size_t shapeID = 0; + _CP_OPT(int) duration; + _CP_OPT(std::wstring) fill; + _CP_OPT(std::wstring) delay; + _CP_OPT(bool) autoRev; + _CP_OPT(int) by; + _CP_OPT(std::wstring) attributeName; + + if(common_attlist_.smil_target_element_) + shapeID = Context.get_slide_context().get_id(common_attlist_.smil_target_element_.value()); + + if (common_attlist_.smil_dur_) + duration = common_attlist_.smil_dur_.value().get_value(); + + if (common_attlist_.smil_fill_) + { + bool durationSpecified = common_attlist_.smil_dur_.has_value() || common_attlist_.smil_end_.has_value(); + fill = pptx_convert_smil_fill(common_attlist_.smil_fill_.value(), durationSpecified); + } + + if (common_attlist_.smil_attribute_name_) + attributeName = pptx_convert_smil_attribute_name(common_attlist_.smil_attribute_name_.value()); + + if (common_attlist_.smil_begin_) + delay = pptx_convert_smil_begin(common_attlist_.smil_begin_.value()); + + if (animate_transform_attlist_.smil_auto_reverse_) + autoRev = animate_transform_attlist_.smil_auto_reverse_.value().get(); + + + if (animate_transform_attlist_.svg_type_) + { + oox::pptx_animation_context& animationContext = Context.get_slide_context().get_animation_context(); + + switch (animate_transform_attlist_.svg_type_->get_type()) + { + case odf_types::svg_type::scale: + { + + animationContext.start_animate_scale(); + animationContext.set_animate_scale_shape_id(shapeID); + if (duration) animationContext.set_animate_scale_duration(duration.value()); + if (fill) animationContext.set_animate_scale_fill(fill.value()); + if (delay) animationContext.set_animate_scale_delay(delay.value()); + if (attributeName) animationContext.set_animate_scale_attribute_name(attributeName.value()); + if (autoRev) animationContext.set_animate_scale_auto_reverse(autoRev.value()); + + if (animate_transform_attlist_.smil_from_) + { + const int pptx_mulipier = 100000; + const std::vector oox_from = smil_list_to_oox_vector(animate_transform_attlist_.smil_from_.value(), pptx_mulipier); + + if (oox_from.size() >= 2) + animationContext.set_animate_scale_from(oox_from[0], oox_from[1]); + else + _CP_LOG << "[ warning ] cannot convert scale smil:from"; + } + + if (animate_transform_attlist_.smil_to_) + { + const int pptx_mulipier = 100000; + const std::vector oox_to = smil_list_to_oox_vector(animate_transform_attlist_.smil_to_.value(), pptx_mulipier); + + if (oox_to.size() >= 2) + animationContext.set_animate_scale_to(oox_to[0], oox_to[1]); + else + _CP_LOG << "[ warning ] cannot convert scale smil:to"; + } + + if (animate_transform_attlist_.smil_by_) + { + const int pptx_mulipier = 100000; + const std::vector oox_by = smil_list_to_oox_vector(animate_transform_attlist_.smil_by_.value(), pptx_mulipier); + + if (oox_by.size() >= 2) + animationContext.set_animate_scale_by(oox_by[0] + pptx_mulipier, oox_by[1] + pptx_mulipier); + else + _CP_LOG << "[ warning ] cannot convert scale smil:by"; + } + + animationContext.end_animate_scale(); + break; + } + case odf_types::svg_type::rotate: + { + if (animate_transform_attlist_.smil_by_) + { + try + { + const int pptx_muliplier = 60000; + by = boost::lexical_cast(animate_transform_attlist_.smil_by_.value()) * pptx_muliplier; + } + catch (...) + { + by = 0; + } + } + + animationContext.start_animate_rotate(); + animationContext.set_animate_rotate_shape_id(shapeID); + if (duration) animationContext.set_animate_rotate_duration(duration.value()); + if (fill) animationContext.set_animate_rotate_fill(fill.value()); + if (delay) animationContext.set_animate_rotate_delay(delay.value()); + if (autoRev) animationContext.set_animate_rotate_auto_reverse(autoRev.value()); + if (by) animationContext.set_animate_rotate_by(by.value()); + if (attributeName) animationContext.set_animate_rotate_attribute_name(attributeName.value()); + + animationContext.end_animate_rotate(); + break; + } + } + } +} + +void anim_animate_transform::add_attributes(const xml::attributes_wc_ptr& Attributes) +{ + common_attlist_.add_attributes(Attributes); + animate_transform_attlist_.add_attributes(Attributes); +} + } } diff --git a/OdfFile/Reader/Format/anim_elements.h b/OdfFile/Reader/Format/anim_elements.h index 20f478a0974..817d0436e66 100644 --- a/OdfFile/Reader/Format/anim_elements.h +++ b/OdfFile/Reader/Format/anim_elements.h @@ -35,12 +35,11 @@ #include "office_elements_create.h" #include "../../DataTypes/common_attlists.h" -#include "../../DataTypes/smil_transitiontype.h" +#include "../../DataTypes/animation_attlists.h" namespace cpdoccore { namespace odf_reader { - //anim:par class anim_par : public office_element_impl//Параллельные анимации { @@ -51,9 +50,11 @@ class anim_par : public office_element_impl//Параллельные static const ElementType type = typeAnimPar; CPDOCCORE_DEFINE_VISITABLE(); - odf_types::common_anim_smil_attlist attlist_; + odf_types::common_anim_smil_attlist common_attlist_; + odf_types::anim_par_attlist par_attlist_; + - office_element_ptr anim_par_; + office_element_ptr_array anim_par_array_; office_element_ptr_array anim_seq_array_; office_element_ptr_array content_; @@ -63,6 +64,7 @@ class anim_par : public office_element_impl//Параллельные virtual void add_attributes( const xml::attributes_wc_ptr & Attributes ); virtual void add_child_element( xml::sax * Reader, const std::wstring & Ns, const std::wstring & Name); + boost::optional pptx_convert_preset_id(); }; CP_REGISTER_OFFICE_ELEMENT2(anim_par); ////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -91,24 +93,7 @@ CP_REGISTER_OFFICE_ELEMENT2(anim_seq); /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //anim:iterate //------------------------------------------------------------------------------- -class anim_audio_attlist -{ -public: - void add_attributes( const xml::attributes_wc_ptr & Attributes ); - - _CP_OPT(std::wstring) xlink_href_; - _CP_OPT(std::wstring) anim_audio_level_; -}; -class anim_transition_filter_attlist -{ -public: - void add_attributes( const xml::attributes_wc_ptr & Attributes ); - - _CP_OPT(std::wstring) smil_subtype_; - _CP_OPT(odf_types::smil_transition_type) smil_type_; - _CP_OPT(std::wstring) smil_mode_; - _CP_OPT(odf_types::color) smil_fadeColor_; -}; + class anim_transitionFilter : public office_element_impl { public: @@ -120,12 +105,16 @@ class anim_transitionFilter : public office_element_impl virtual void pptx_convert(oox::pptx_conversion_context & Context); - odf_types::common_anim_smil_attlist common_attlist_; - anim_transition_filter_attlist filter_attlist_; + odf_types::common_anim_smil_attlist common_attlist_; + odf_types::anim_transition_filter_attlist filter_attlist_; + private: virtual void add_child_element( xml::sax * Reader, const std::wstring & Ns, const std::wstring & Name){} virtual void add_attributes( const xml::attributes_wc_ptr & Attributes ); + std::wstring convert_filter(); + void convert_slide_transition_filter(oox::pptx_conversion_context& Context); + }; CP_REGISTER_OFFICE_ELEMENT2(anim_transitionFilter); @@ -142,7 +131,7 @@ class anim_audio : public office_element_impl virtual void pptx_convert(oox::pptx_conversion_context & Context); odf_types::common_anim_smil_attlist common_attlist_; - anim_audio_attlist audio_attlist_; + odf_types::anim_audio_attlist audio_attlist_; private: virtual void add_child_element( xml::sax * Reader, const std::wstring & Ns, const std::wstring & Name){} virtual void add_attributes( const xml::attributes_wc_ptr & Attributes ); @@ -152,5 +141,112 @@ class anim_audio : public office_element_impl CP_REGISTER_OFFICE_ELEMENT2(anim_audio); //anim:command +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// anim:set + +class anim_set : public office_element_impl +{ +public: + static const wchar_t* ns; + static const wchar_t* name; + static const xml::NodeType xml_type = xml::typeElement; + static const ElementType type = typeAnimSet; + CPDOCCORE_DEFINE_VISITABLE(); + + virtual void pptx_convert(oox::pptx_conversion_context& Context); + + odf_types::common_anim_smil_attlist common_attlist_; + odf_types::anim_set_attlist set_attlist_; +private: + virtual void add_child_element(xml::sax* Reader, const std::wstring& Ns, const std::wstring& Name) {} + virtual void add_attributes(const xml::attributes_wc_ptr& Attributes); +}; +CP_REGISTER_OFFICE_ELEMENT2(anim_set); + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// anim:animateMotion +class anim_animate_motion : public office_element_impl +{ +public: + static const wchar_t* ns; + static const wchar_t* name; + static const xml::NodeType xml_type = xml::typeElement; + static const ElementType type = typeAnimAnimateMotion; + CPDOCCORE_DEFINE_VISITABLE(); + + virtual void pptx_convert(oox::pptx_conversion_context& Context); + + odf_types::common_anim_smil_attlist common_attlist_; + odf_types::anim_animate_motion_attlist animate_motion_attlist_; +private: + virtual void add_child_element(xml::sax* Reader, const std::wstring& Ns, const std::wstring& Name) {} + virtual void add_attributes(const xml::attributes_wc_ptr& Attributes); +}; +CP_REGISTER_OFFICE_ELEMENT2(anim_animate_motion); + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// anim:animateColor +class anim_animate_color : public office_element_impl +{ +public: + static const wchar_t* ns; + static const wchar_t* name; + static const xml::NodeType xml_type = xml::typeElement; + static const ElementType type = typeAnimAnimateColor; + CPDOCCORE_DEFINE_VISITABLE(); + + virtual void pptx_convert(oox::pptx_conversion_context& Context); + + odf_types::common_anim_smil_attlist common_attlist_; + odf_types::anim_animate_color_attlist animate_color_attlist_; +private: + virtual void add_child_element(xml::sax* Reader, const std::wstring& Ns, const std::wstring& Name) {} + virtual void add_attributes(const xml::attributes_wc_ptr& Attributes); +}; +CP_REGISTER_OFFICE_ELEMENT2(anim_animate_color); + +////////////////////////////////////////////////////////////////////////// +// anim:animate +class anim_animate : public office_element_impl +{ +public: + static const wchar_t* ns; + static const wchar_t* name; + static const xml::NodeType xml_type = xml::typeElement; + static const ElementType type = typeAnimAnimate; + CPDOCCORE_DEFINE_VISITABLE(); + + virtual void pptx_convert(oox::pptx_conversion_context& Context); + + odf_types::common_anim_smil_attlist common_attlist_; + odf_types::anim_animate_attlist animate_attlist_; + +private: + virtual void add_child_element(xml::sax* Reader, const std::wstring& Ns, const std::wstring& Name) {} + virtual void add_attributes(const xml::attributes_wc_ptr& Attributes); +}; +CP_REGISTER_OFFICE_ELEMENT2(anim_animate); + +////////////////////////////////////////////////////////////////////////// +// anim:animateTransform +class anim_animate_transform : public office_element_impl +{ +public: + static const wchar_t* ns; + static const wchar_t* name; + static const xml::NodeType xml_type = xml::typeElement; + static const ElementType type = typeAnimAnimateTransform; + CPDOCCORE_DEFINE_VISITABLE(); + + virtual void pptx_convert(oox::pptx_conversion_context& Context); + + odf_types::common_anim_smil_attlist common_attlist_; + odf_types::anim_animate_transform_attlist animate_transform_attlist_; + +private: + virtual void add_child_element(xml::sax* Reader, const std::wstring& Ns, const std::wstring& Name) {} + virtual void add_attributes(const xml::attributes_wc_ptr& Attributes); +}; +CP_REGISTER_OFFICE_ELEMENT2(anim_animate_transform); } } diff --git a/OdfFile/Reader/Format/calcext_elements.cpp b/OdfFile/Reader/Format/calcext_elements.cpp index d8b152833f0..2eee236ec80 100644 --- a/OdfFile/Reader/Format/calcext_elements.cpp +++ b/OdfFile/Reader/Format/calcext_elements.cpp @@ -60,6 +60,7 @@ void calcext_data_bar_attr::add_attributes( const xml::attributes_wc_ptr & Attri CP_APPLY_ATTR(L"calcext:min-length", min_length_); CP_APPLY_ATTR(L"calcext:max-length", max_length_); CP_APPLY_ATTR(L"calcext:axis-position", axis_position_); + CP_APPLY_ATTR(L"calcext:gradient", gradient_); } void calcext_icon_set_attr::add_attributes( const xml::attributes_wc_ptr & Attributes ) @@ -72,6 +73,7 @@ void calcext_condition_attr::add_attributes( const xml::attributes_wc_ptr & Attr CP_APPLY_ATTR(L"calcext:base-cell-address", base_cell_address_); CP_APPLY_ATTR(L"calcext:apply-style-name", apply_style_name_); CP_APPLY_ATTR(L"calcext:value", value_); + CP_APPLY_ATTR(L"loext:stdDev", loext_stdDev_); } void calcext_date_is_attr::add_attributes( const xml::attributes_wc_ptr & Attributes ) { @@ -180,6 +182,9 @@ void calcext_data_bar::xlsx_convert(oox::xlsx_conversion_context & Context) if (attr_.axis_position_) Context.get_conditionalFormatting_context().set_axis_position(*attr_.axis_position_); + if (attr_.gradient_) + Context.get_conditionalFormatting_context().set_gradient(*attr_.gradient_); + Context.get_conditionalFormatting_context().set_dataBar(attr_.min_length_, attr_.max_length_); for (size_t i = 0 ; i < content_.size(); i++) @@ -233,7 +238,7 @@ void calcext_icon_set::xlsx_convert(oox::xlsx_conversion_context & Context) } } -// calcext_formatting_entry +/// calcext:formatting-entry //--------------------------------------------------------------------------------------------------------- const wchar_t * calcext_formatting_entry::ns = L"calcext"; const wchar_t * calcext_formatting_entry::name = L"formatting-entry"; @@ -309,6 +314,9 @@ void calcext_condition::xlsx_convert(oox::xlsx_conversion_context & Context) if (dxfId >= 0) Context.get_conditionalFormatting_context().set_dxf(dxfId); + + if (attr_.loext_stdDev_) + Context.get_conditionalFormatting_context().set_stdDev(*attr_.loext_stdDev_); } // calcext_condition //--------------------------------------------------------------------------------------------------------- diff --git a/OdfFile/Reader/Format/calcext_elements.h b/OdfFile/Reader/Format/calcext_elements.h index 987d9150f7e..d0013593291 100644 --- a/OdfFile/Reader/Format/calcext_elements.h +++ b/OdfFile/Reader/Format/calcext_elements.h @@ -53,12 +53,13 @@ class calcext_data_bar_attr public: void add_attributes( const xml::attributes_wc_ptr & Attributes ); - _CP_OPT(odf_types::color) axis_color_; - _CP_OPT(odf_types::color) positive_color_; - _CP_OPT(odf_types::color) negative_color_; - _CP_OPT(std::wstring) axis_position_; - _CP_OPT(int) max_length_; - _CP_OPT(int) min_length_; + _CP_OPT(odf_types::color) axis_color_; + _CP_OPT(odf_types::color) positive_color_; + _CP_OPT(odf_types::color) negative_color_; + _CP_OPT(std::wstring) axis_position_; + _CP_OPT(bool) gradient_; + _CP_OPT(unsigned int) min_length_; + _CP_OPT(unsigned int) max_length_; }; class calcext_condition_attr @@ -69,6 +70,7 @@ class calcext_condition_attr _CP_OPT(std::wstring) base_cell_address_; _CP_OPT(std::wstring) apply_style_name_; _CP_OPT(std::wstring) value_; + _CP_OPT(int) loext_stdDev_; }; class calcext_icon_set_attr @@ -77,7 +79,6 @@ class calcext_icon_set_attr void add_attributes( const xml::attributes_wc_ptr & Attributes ); _CP_OPT(odf_types::iconset_type) icon_set_type_; - }; class calcext_date_is_attr diff --git a/OdfFile/Reader/Format/chart_build_oox.cpp b/OdfFile/Reader/Format/chart_build_oox.cpp index a0d364c7dd5..11d35aa9f0e 100644 --- a/OdfFile/Reader/Format/chart_build_oox.cpp +++ b/OdfFile/Reader/Format/chart_build_oox.cpp @@ -47,6 +47,7 @@ #include "number_style.h" #include "calcs_styles.h" #include "chart_build_oox.h" +#include "../Converter/measuredigits.h" #include "../../DataTypes/length.h" #include "../../DataTypes/borderstyle.h" @@ -74,6 +75,17 @@ typedef shared_ptr::Type office_element_ptr_const; VAL[ii]->accept(*this); \ } +static double convert_symbol_size(double val, double metrix, bool add_padding) +{ + //if (add_padding) + { + val = ((int)((val * metrix + 5) / metrix * 256)) / 256.; + } + + double pixels = (int)(((256. * val + ((int)(128. / metrix))) / 256.) * metrix); //in pixels + + return pixels * 0.75; //* 9525. * 72.0 / (360000.0 * 2.54); +} // Класс для конструирования чартов using namespace chart; @@ -209,7 +221,7 @@ void object_odf_context::xlsx_convert(oox::xlsx_conversion_context & Context) Context.get_math_context().base_font_bold_ = baseFontBold_; Context.get_math_context().start(); - office_math_->oox_convert(Context.get_math_context()); + office_math_->oox_convert(Context.get_math_context(),3); } else if(object_type_ == 4 && office_spreadsheet_) { @@ -247,6 +259,7 @@ void object_odf_context::docx_convert(oox::docx_conversion_context & Context) } else if (object_type_ == 3 && office_math_) { + bool in_draw_frame = Context.get_drawing_state_content(); oox::StreamsManPtr prev = Context.get_stream_man(); std::wstringstream temp_stream(Context.get_drawing_context().get_text_stream_frame()); @@ -256,14 +269,28 @@ void object_odf_context::docx_convert(oox::docx_conversion_context & Context) Context.get_math_context().base_font_size_ = baseFontHeight_; Context.get_math_context().base_font_name_ = baseFontName_; - Context.get_math_context().base_alignment_ = baseAlignment_; + Context.get_math_context().base_alignment_ = in_draw_frame ? 0 : baseAlignment_; Context.get_math_context().base_font_italic_ = baseFontItalic_; Context.get_math_context().base_font_bold_ = baseFontBold_; Context.start_math_formula(); - office_math_->oox_convert(Context.get_math_context()); + office_math_->oox_convert(Context.get_math_context(), 2); Context.end_math_formula(); + if (Context.get_drawing_context().get_current_frame() && + Context.get_drawing_context().get_current_frame()->oox_drawing_) + { + std::pair maxDigitSize_ = utils::GetMaxDigitSizePixels(baseFontName_, baseFontHeight_, 96., 0, Context.get_mediaitems()->applicationFonts()); + + double cx = get_value_emu(convert_symbol_size(1.76 * Context.get_math_context().width, maxDigitSize_.first, false)); + double cy = get_value_emu(convert_symbol_size(1.76 * Context.get_math_context().height, maxDigitSize_.second, false)); + + if (cx > Context.get_drawing_context().get_current_frame()->oox_drawing_->cx) + Context.get_drawing_context().get_current_frame()->oox_drawing_->cx = cx; + + if (cy > Context.get_drawing_context().get_current_frame()->oox_drawing_->cy) + Context.get_drawing_context().get_current_frame()->oox_drawing_->cy = cy; + } Context.get_drawing_context().get_text_stream_frame() = temp_stream.str(); Context.set_stream_man(prev); @@ -307,7 +334,7 @@ void object_odf_context::pptx_convert(oox::pptx_conversion_context & Context) Context.get_math_context().base_font_bold_ = baseFontBold_; Context.get_math_context().start(); - office_math_->oox_convert(Context.get_math_context()); + office_math_->oox_convert(Context.get_math_context(), 1); } else if(object_type_ == 4 && office_spreadsheet_) { @@ -967,6 +994,7 @@ void process_build_object::visit(chart_plot_area& val) if (attr_3d.transform_) object_odf_context_.plot_area_.properties_->push_back(_property(L"transform", attr_3d.transform_.get()) ); if (attr_3d.distance_) object_odf_context_.plot_area_.properties_->push_back(_property(L"distance", attr_3d.distance_->get_value_unit(length::pt)) ); if (attr_3d.focal_length_) object_odf_context_.plot_area_.properties_->push_back(_property(L"focal", attr_3d.focal_length_->get_value_unit(length::pt)) ); + if (attr_3d.projection_) object_odf_context_.plot_area_.properties_->push_back(_property(L"perspective", *attr_3d.projection_ == L"perspective")); } void process_build_object::visit(chart_axis& val) diff --git a/OdfFile/Reader/Format/documentcontext.cpp b/OdfFile/Reader/Format/documentcontext.cpp index a5549a30452..a74e4252058 100644 --- a/OdfFile/Reader/Format/documentcontext.cpp +++ b/OdfFile/Reader/Format/documentcontext.cpp @@ -36,7 +36,7 @@ namespace cpdoccore { namespace odf_reader { -document_context::document_context() : last_paragraph(NULL) +document_context::document_context() : last_paragraph(NULL), is_old_version(false) { } diff --git a/OdfFile/Reader/Format/documentcontext.h b/OdfFile/Reader/Format/documentcontext.h index 4e1bf4bcbb5..b37fde31630 100644 --- a/OdfFile/Reader/Format/documentcontext.h +++ b/OdfFile/Reader/Format/documentcontext.h @@ -49,6 +49,7 @@ class document_context office_element* get_last_element(); std::wstring office_class_; //openoffice xml 1.0 + bool is_old_version; //openoffice xml 1.0 std::vector levels; office_element* last_paragraph; diff --git a/OdfFile/Reader/Format/draw_common.cpp b/OdfFile/Reader/Format/draw_common.cpp index 768bac78f91..44e59f73806 100644 --- a/OdfFile/Reader/Format/draw_common.cpp +++ b/OdfFile/Reader/Format/draw_common.cpp @@ -298,10 +298,19 @@ void Compute_HatchFill(draw_hatch * image_style,oox::oox_hatch_fill_ptr fill) void Compute_GradientFill(draw_gradient* gradient_style, oox::oox_gradient_fill_ptr fill) { int style = 0; - if (gradient_style->draw_style_) style = gradient_style->draw_style_->get_type(); + if (gradient_style->draw_style_) + style = gradient_style->draw_style_->get_type(); - if (gradient_style->draw_angle_) fill->angle = 90 - gradient_style->draw_angle_->get_value(); - if (fill->angle < 0) fill->angle += 360; + if (gradient_style->draw_angle_) + fill->angle = -90 - gradient_style->draw_angle_->get_value(); + + if (fill->angle < 0) + { + int fullRotations = std::ceil(-fill->angle / 360.0f); + + fill->angle += 360 * fullRotations; + } + for (size_t i = 0; i < gradient_style->content_.size(); ++i) { @@ -381,7 +390,7 @@ void Compute_GradientFill(draw_gradient* gradient_style, oox::oox_gradient_fill_ } } - if (fill->style > 1) + if (fill->style >= 1) { fill->rect[0] = fill->rect[1] = 0; fill->rect[2] = fill->rect[3] = 100; @@ -437,9 +446,10 @@ void Compute_GraphicFill(const common_draw_fill_attlist & props, const office_el } } } - if (props.draw_image_opacity_) - fill.opacity = props.draw_image_opacity_->get_value(); - + if (props.draw_image_opacity_) + { + fill.image_opacity = props.draw_image_opacity_->get_value(); + } //////////////////////////////////////////////////////////// if (props.draw_fill_color_) { @@ -592,7 +602,9 @@ void Compute_GraphicFill(const common_draw_fill_attlist & props, const office_el } if ((fill.hatch) && (props.draw_fill_color_)) { - fill.hatch->color_back_ref = props.draw_fill_color_->get_hex_value(); + // NOTE: Do not use draw:fill-color for hatch + // fill.hatch->color_back_ref = props.draw_fill_color_->get_hex_value(); + fill.hatch->color_back_ref = L"FFFFFF"; } } if (props.draw_fill_) diff --git a/OdfFile/Reader/Format/draw_frame.cpp b/OdfFile/Reader/Format/draw_frame.cpp index 89eed08178e..ea19a7edbba 100644 --- a/OdfFile/Reader/Format/draw_frame.cpp +++ b/OdfFile/Reader/Format/draw_frame.cpp @@ -82,8 +82,9 @@ void draw_chart_attlist::add_attributes( const xml::attributes_wc_ptr & Attribut { //CP_APPLY_ATTR(L"draw:filter-name", draw_filter_name_); } +//------------------------------------------------------------------------------------------------------------ // draw:image -////////////////////////////////////////////////////////////////////////////////////////////////// +//------------------------------------------------------------------------------------------------------------ const wchar_t * draw_image::ns = L"draw"; const wchar_t * draw_image::name = L"image"; @@ -100,7 +101,6 @@ void draw_image::add_attributes( const xml::attributes_wc_ptr & Attributes ) draw_image_attlist_.add_attributes(Attributes); xlink_attlist_.add_attributes(Attributes); } - void draw_image::add_child_element( xml::sax * Reader, const std::wstring & Ns, const std::wstring & Name) { if CP_CHECK_NAME(L"office", L"binary-data") @@ -116,8 +116,9 @@ std::wostream & draw_image::text_to_stream(std::wostream & _Wostream, bool bXmlE { return _Wostream; } +//------------------------------------------------------------------------------------------------------------ // draw:chart -//////////////////////////////////////////////////////////////////////////////////////////////////// +//------------------------------------------------------------------------------------------------------------ const wchar_t * draw_chart::ns = L"draw"; const wchar_t * draw_chart::name = L"chart"; @@ -145,8 +146,9 @@ void draw_chart::add_child_element( xml::sax * Reader, const std::wstring & Ns, } +//------------------------------------------------------------------------------------------------------------ // draw:g -////////////////////////////////////////////////////////////////////////////////////////////////// +//------------------------------------------------------------------------------------------------------------ const wchar_t * draw_g::ns = L"draw"; const wchar_t * draw_g::name = L"g"; void draw_g::add_attributes( const xml::attributes_wc_ptr & Attributes ) @@ -242,8 +244,9 @@ std::wostream & draw_g::text_to_stream(std::wostream & _Wostream, bool bXmlEncod return _Wostream; } +//------------------------------------------------------------------------------------------------------------ // draw:frame -////////////////////////////////////////////////////////////////////////////////////////////////// +//------------------------------------------------------------------------------------------------------------ const wchar_t * draw_frame::ns = L"draw"; const wchar_t * draw_frame::name = L"frame"; @@ -252,7 +255,6 @@ std::wostream & draw_frame::text_to_stream(std::wostream & _Wostream, bool bXmlE CP_SERIALIZE_TEXT(content_, bXmlEncode); return _Wostream; } - void draw_frame::add_attributes( const xml::attributes_wc_ptr & Attributes ) { idx_in_owner = -1; @@ -263,7 +265,6 @@ void draw_frame::add_attributes( const xml::attributes_wc_ptr & Attributes ) draw_frame_attlist_.add_attributes(Attributes); } - void draw_frame::add_child_element( xml::sax * Reader, const std::wstring & Ns, const std::wstring & Name) { if (CP_CHECK_NAME(L"draw", L"text-box") || @@ -299,13 +300,20 @@ void draw_frame::add_child_element( xml::sax * Reader, const std::wstring & Ns, { CP_CREATE_ELEMENT(draw_contour_); } + else if (CP_CHECK_NAME(L"svg", L"title")) + { + CP_CREATE_ELEMENT(svg_title_); + } + else if (CP_CHECK_NAME(L"svg", L"desc")) + { + CP_CREATE_ELEMENT(svg_desc_); + } else { CP_NOT_APPLICABLE_ELM(); } } - /////////////////////// void draw_text_box_attlist::add_attributes( const xml::attributes_wc_ptr & Attributes ) @@ -318,8 +326,9 @@ void draw_text_box_attlist::add_attributes( const xml::attributes_wc_ptr & Attri CP_APPLY_ATTR(L"fo:max-height", fo_max_height_); } +//------------------------------------------------------------------------------------------------------------ // draw:text-box -////////////////////////////////////////////////////////////////////////////////////////////////// +//------------------------------------------------------------------------------------------------------------ const wchar_t * draw_text_box::ns = L"draw"; const wchar_t * draw_text_box::name = L"text-box"; @@ -345,8 +354,9 @@ void draw_text_box::add_child_element( xml::sax * Reader, const std::wstring & N CP_CREATE_ELEMENT(content_); } +//------------------------------------------------------------------------------------------------------------ // draw:object -////////////////////////////////////////////////////////////////////////////////////////////////// +//------------------------------------------------------------------------------------------------------------ const wchar_t * draw_object::ns = L"draw"; const wchar_t * draw_object::name = L"object"; @@ -372,8 +382,9 @@ void draw_object::add_child_element( xml::sax * Reader, const std::wstring & Ns, } } +//------------------------------------------------------------------------------------------------------------ // draw:object-ole -////////////////////////////////////////////////////////////////////////////////////////////////// +//------------------------------------------------------------------------------------------------------------ const wchar_t * draw_object_ole::ns = L"draw"; const wchar_t * draw_object_ole::name = L"object-ole"; @@ -437,7 +448,8 @@ void draw_object_ole::detectObject(const std::wstring &fileName, std::wstring &p COfficeFileFormatChecker checker(fileName); switch(checker.nFileType) { - case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOC: extension = L".doc"; prog = L"Word"; rels = oox::typeOleObject; break; + case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOC: + case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOC_FLAT: extension = L".doc"; prog = L"Word"; rels = oox::typeOleObject; break; case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX: extension = L".docx"; prog = L"Word"; rels = oox::typeMsObject; break; case AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLS: extension = L".xls"; prog = L"Excel"; rels = oox::typeOleObject; break; @@ -510,8 +522,9 @@ std::wstring draw_object::office_convert(odf_document_ptr odfDocument, int type) return href_result; } +//------------------------------------------------------------------------------------------------------------ // draw:param -////////////////////////////////////////////////////////////////////////////////////////////////// +//------------------------------------------------------------------------------------------------------------ const wchar_t * draw_param::ns = L"draw"; const wchar_t * draw_param::name = L"param"; @@ -525,8 +538,9 @@ void draw_param::add_child_element( xml::sax * Reader, const std::wstring & Ns, { CP_NOT_APPLICABLE_ELM(); } +//------------------------------------------------------------------------------------------------------------ // draw:plugin -////////////////////////////////////////////////////////////////////////////////////////////////// +//------------------------------------------------------------------------------------------------------------ const wchar_t * draw_plugin::ns = L"draw"; const wchar_t * draw_plugin::name = L"plugin"; diff --git a/OdfFile/Reader/Format/draw_frame.h b/OdfFile/Reader/Format/draw_frame.h index 0a8dbe524ee..1a17dfc805b 100644 --- a/OdfFile/Reader/Format/draw_frame.h +++ b/OdfFile/Reader/Format/draw_frame.h @@ -85,6 +85,8 @@ class draw_image : public office_element_impl office_element_ptr office_binary_data_; office_element_ptr draw_frame_ptr; //openoffice xml 1.0 + + bool convert_pdf2image(NSFonts::IApplicationFonts* applicationFonts, const std::wstring& pdf_file_name, const std::wstring& image_file_name); }; CP_REGISTER_OFFICE_ELEMENT2(draw_image); @@ -146,10 +148,10 @@ class draw_frame_attlist class draw_frame : public office_element_impl { public: - static const wchar_t * ns; - static const wchar_t * name; - static const xml::NodeType xml_type = xml::typeElement; - static const ElementType type = typeDrawFrame; + static const wchar_t *ns; + static const wchar_t *name; + static const xml::NodeType xml_type = xml::typeElement; + static const ElementType type = typeDrawFrame; CPDOCCORE_DEFINE_VISITABLE(); draw_frame() : oox_drawing_(), idx_in_owner(-1), is_object_(false) {} @@ -159,34 +161,39 @@ class draw_frame : public office_element_impl virtual void pptx_convert(oox::pptx_conversion_context & Context); virtual void pptx_convert_placeHolder(oox::pptx_conversion_context & Context); + void pptx_convert_placeHolder_styles(oox::pptx_conversion_context& Context, const graphic_format_properties* graphic_props, const paragraph_format_properties* paragraph_props, const text_format_properties* text_props); + virtual std::wostream & text_to_stream(std::wostream & _Wostream, bool bXmlEncode = true) const; int idx_in_owner ; - odf_types::union_common_draw_attlists common_draw_attlists_; + odf_types::union_common_draw_attlists common_draw_attlists_; - draw_frame_attlist draw_frame_attlist_; + draw_frame_attlist draw_frame_attlist_; // draw-text-box, draw-image, draw-object, draw-object-ole, draw-applet, draw-floating-frame, draw-plugin - office_element_ptr_array content_; + office_element_ptr_array content_; + + office_element_ptr office_event_listeners_; - office_element_ptr office_event_listeners_; + office_element_ptr draw_glue_point_; + office_element_ptr draw_image_map_; - office_element_ptr draw_glue_point_; - office_element_ptr draw_image_map_; + office_element_ptr draw_contour_; // draw-contour-polygon or draw-contour-path - office_element_ptr draw_contour_; // draw-contour-polygon or draw-contour-path + office_element_ptr svg_title_; + office_element_ptr svg_desc_; friend class odf_document; friend class draw_image; friend class draw_chart; - oox_drawing_ptr oox_drawing_; + oox_drawing_ptr oox_drawing_; - bool is_object_; + bool is_object_; private: - virtual void add_attributes ( const xml::attributes_wc_ptr & Attributes ); - virtual void add_child_element ( xml::sax * Reader, const std::wstring & Ns, const std::wstring & Name); + virtual void add_attributes( const xml::attributes_wc_ptr & Attributes ); + virtual void add_child_element( xml::sax * Reader, const std::wstring & Ns, const std::wstring & Name); void docx_convert_start(oox::docx_conversion_context & Context); void docx_convert_end(oox::docx_conversion_context & Context); diff --git a/OdfFile/Reader/Format/draw_frame_docx.cpp b/OdfFile/Reader/Format/draw_frame_docx.cpp index 64e4e50bf50..558a8a4baee 100644 --- a/OdfFile/Reader/Format/draw_frame_docx.cpp +++ b/OdfFile/Reader/Format/draw_frame_docx.cpp @@ -574,6 +574,11 @@ int ComputeMarginX(const style_page_layout_properties * pagePropertiesNode, svgX = *attlists_.position_.svg_x_; } } + else + { + if (attlists_.position_.svg_x_) + svgX = *attlists_.position_.svg_x_; + } return get_value_emu (svgX); } @@ -846,6 +851,15 @@ void common_draw_docx_convert(oox::docx_conversion_context & Context, union_comm drawing->styleHorizontalPos = graphicProperties->common_horizontal_pos_attlist_.style_horizontal_pos_; drawing->styleVerticalPos = graphicProperties->common_vertical_pos_attlist_.style_vertical_pos_; drawing->styleVerticalRel = graphicProperties->common_vertical_rel_attlist_.style_vertical_rel_; + + if (graphicProperties->style_mirror_) + { + bool flipV = graphicProperties->style_mirror_->find(L"vertical") != std::wstring::npos; + bool flipH = graphicProperties->style_mirror_->find(L"horizontal") != std::wstring::npos; + + drawing->additional.push_back(odf_reader::_property(L"flipV", flipV)); + drawing->additional.push_back(odf_reader::_property(L"flipH", flipH)); + } } if (!drawing->styleVerticalRel && anchor) { @@ -881,17 +895,17 @@ void common_draw_docx_convert(oox::docx_conversion_context & Context, union_comm drawing->relativeHeight = L"2"; drawing->behindDoc = L"0"; + if (!drawing->styleWrap) + drawing->styleWrap = style_wrap(style_wrap::Parallel);//у опен офис и мс разные дефолты + if (((drawing->styleWrap && drawing->styleWrap->get_type() == style_wrap::RunThrough) || !drawing->styleWrap) && ((styleRunThrough && styleRunThrough->get_type() == run_through::Background) || !styleRunThrough)) { drawing->behindDoc = L"1"; if (!drawing->styleWrap) drawing->styleWrap = style_wrap(style_wrap::RunThrough); - } - if (!drawing->styleWrap) - drawing->styleWrap = style_wrap(style_wrap::Parallel);//у опен офис и мс разные дефолты - + _CP_OPT(unsigned int) zIndex = attlists_.shape_with_text_and_styles_.common_shape_draw_attlist_.draw_z_index_; if (zIndex)//порядок отрисовки объектов @@ -955,9 +969,11 @@ void common_draw_docx_convert(oox::docx_conversion_context & Context, union_comm { if (graphicProperties->common_border_attlist_.fo_border_->is_none() == false) { - drawing->additional.push_back(_property(L"stroke-color", graphicProperties->common_border_attlist_.fo_border_->get_color().get_hex_value() )); - drawing->additional.push_back(_property(L"stroke-width", graphicProperties->common_border_attlist_.fo_border_->get_length().get_value_unit(odf_types::length::pt) )); + drawing->additional.push_back(_property(L"stroke-color", graphicProperties->common_border_attlist_.fo_border_->get_color().get_hex_value() )); + drawing->additional.push_back(_property(L"stroke-width", graphicProperties->common_border_attlist_.fo_border_->get_length().get_value_unit(odf_types::length::pt) )); + drawing->additional.push_back(_property(L"stroke", graphicProperties->common_border_attlist_.fo_border_->get_style())); + drawing->inFrame = true; } } //---------------------------------------------------- @@ -1031,34 +1047,6 @@ void common_draw_docx_convert(oox::docx_conversion_context & Context, union_comm int max_width = get_value_emu(pageProperties.fo_page_width_); int max_height = get_value_emu(pageProperties.fo_page_height_); - //это бред(типо подгонка) автоподбор под размер текста ... - //if (Context.process_headers_footers_ && pageLayoutInst) - //{ - // style_header_style * headerStyle = dynamic_cast(pageLayoutInst->style_page_layout_->style_header_style_.get()); - // style_footer_style * footerStyle = dynamic_cast(pageLayoutInst->style_page_layout_->style_footer_style_.get()); - - // style_header_footer_properties * headerProp = headerStyle ? dynamic_cast(headerStyle->style_header_footer_properties_.get()) : NULL; - // style_header_footer_properties * footerProp = footerStyle ? dynamic_cast(footerStyle->style_header_footer_properties_.get()) : NULL; - // - // if (headerProp) - // { - // size_t height = get_value_emu(headerProp->style_header_footer_properties_attlist_.svg_height_); - // if (height<1)height = get_value_emu(headerProp->style_header_footer_properties_attlist_.fo_min_height_); - // - // if (height >0 && height < max_height) - // max_height = height; - // } - // if (footerProp) - // { - // size_t height = get_value_emu(footerProp->style_header_footer_properties_attlist_.svg_height_); - // if (height<1)height = get_value_emu(footerProp->style_header_footer_properties_attlist_.fo_min_height_); - // - // if (height >0 && height < max_height) - // max_height = height; - - // } - //} - //if (drawing->cx<1 && max_width >0) //{ // drawing->cx = std::min(762000,max_width); @@ -1193,6 +1181,7 @@ void draw_image::docx_convert(oox::docx_conversion_context & Context) std::wstring href = xlink_attlist_.href_.get_value_or(L""); + oox::_rels_type type = oox::typeImage; if (true == href.empty()) { office_binary_data* binary_data = dynamic_cast(office_binary_data_.get()); @@ -1200,6 +1189,7 @@ void draw_image::docx_convert(oox::docx_conversion_context & Context) if (binary_data) { href = binary_data->write_to(Context.root()->get_folder()); + type = (oox::_rels_type)binary_data->type_binary_data; } } else @@ -1222,7 +1212,7 @@ void draw_image::docx_convert(oox::docx_conversion_context & Context) if (href[0] == L'#') href = href.substr(1); if (drawing->type == oox::typeUnknown) - drawing->type = oox::typeImage; + drawing->type = type; oox::StreamsManPtr prev = Context.get_stream_man(); @@ -1257,10 +1247,26 @@ void draw_image::docx_convert(oox::docx_conversion_context & Context) drawing->fill.bitmap = oox::oox_bitmap_fill::create(); drawing->fill.type = 2; drawing->fill.bitmap->isInternal = false; - drawing->fill.bitmap->rId = Context.get_mediaitems()->add_or_find(href, oox::typeImage, drawing->fill.bitmap->isInternal, href, Context.get_type_place()); drawing->fill.bitmap->bStretch = true; - const std::wstring styleName = frame->common_draw_attlists_.shape_with_text_and_styles_. + std::wstring href_out; + if (drawing->type == oox::typePDF) + { + drawing->objectProgId = L"Acrobat.Document.DC"; + drawing->objectId = Context.get_mediaitems()->add_or_find(href, type, drawing->fill.bitmap->isInternal, href_out, Context.get_type_place()); + + std::wstring image_file = NSFile::CFileBinary::CreateTempFileWithUniqueName(Context.root()->get_folder() + FILE_SEPARATOR_STR, L"img"); + + if (Context.get_mediaitems()->pdf2image(Context.root()->get_folder() + FILE_SEPARATOR_STR + href, image_file)) + { + int pos = image_file.rfind(FILE_SEPARATOR_STR); + href = image_file.substr(pos + 1); + } + } + + drawing->fill.bitmap->rId = Context.get_mediaitems()->add_or_find(href, oox::typeImage, drawing->fill.bitmap->isInternal, href_out, Context.get_type_place()); + + const std::wstring styleName = frame->common_draw_attlists_.shape_with_text_and_styles_. common_shape_draw_attlist_.draw_style_name_.get_value_or(L""); odf_reader::style_instance* styleInst = Context.root()->odf_context().styleContainer().style_by_name(styleName, odf_types::style_family::Graphic,Context.process_headers_footers_); @@ -1578,6 +1584,11 @@ void draw_frame::docx_convert(oox::docx_conversion_context & Context) drawing->id = Context.get_drawing_context().get_current_frame_id(); drawing->name = Context.get_drawing_context().get_current_object_name(); drawing->inGroup = Context.get_drawing_context().in_group(); + + if (svg_title_) + svg_title_->docx_convert(Context); + if(svg_desc_) + svg_desc_->docx_convert(Context); common_draw_docx_convert(Context, common_draw_attlists_, drawing); //----------------------------------------------------------------------------------------------------- @@ -1643,49 +1654,52 @@ void draw_object::docx_convert(oox::docx_conversion_context & Context) oox::_docx_drawing *drawing = dynamic_cast(frame->oox_drawing_.get()); try { - std::wstring href = xlink_attlist_.href_.get_value_or(L""); - std::wstring tempPath = Context.root()->get_temp_folder(); - std::wstring odfPath = Context.root()->get_folder(); + std::wstring href = xlink_attlist_.href_.get_value_or(L""); + std::wstring odfPath = Context.root()->get_folder(); + std::wstring tempPath = Context.root()->get_temp_folder(); if (!odf_document_ && false == href.empty()) { if (href[0] == L'#') href = href.substr(1); - std::wstring objectPath = odfPath + FILE_SEPARATOR_STR + href; - // normalize path ???? todooo - XmlUtils::replace_all( objectPath, FILE_SEPARATOR_STR + std::wstring(L"./"), FILE_SEPARATOR_STR); + if (Context.get_mediaitems()->is_internal_path(href, odfPath)) + { + std::wstring objectPath = odfPath + FILE_SEPARATOR_STR + href; + // normalize path ???? todooo - odf_document_ = odf_document_ptr(new odf_document(objectPath, tempPath, L"")); + XmlUtils::replace_all(objectPath, FILE_SEPARATOR_STR + std::wstring(L"./"), FILE_SEPARATOR_STR); + odf_document_ = odf_document_ptr(new odf_document(objectPath, tempPath, L"")); + } } -//--------------------------------------------------------------------------------------------------------------------- - office_element* contentSubDoc = odf_document_ ? odf_document_->get_impl()->get_content() : NULL; - - object_odf_context objectBuild (href); + //--------------------------------------------------------------------------------------------------------------------- + office_element* contentSubDoc = odf_document_ ? odf_document_->get_impl()->get_content() : NULL; + + object_odf_context objectBuild(href); if (contentSubDoc) { process_build_object process_build_object_(objectBuild, odf_document_.get()); - contentSubDoc->accept(process_build_object_); + contentSubDoc->accept(process_build_object_); if (objectBuild.table_table_) { oox::xlsx_conversion_context xlsx_context(odf_document_.get()); cpdoccore::oox::package::xlsx_document outputXlsx; - - xlsx_context.set_output_document (&outputXlsx); + + xlsx_context.set_output_document(&outputXlsx); xlsx_context.start_document(); - objectBuild.table_table_->xlsx_convert(xlsx_context); + objectBuild.table_table_->xlsx_convert(xlsx_context); xlsx_context.end_document(); - + std::wstring href_folder = tempPath + FILE_SEPARATOR_STR + L"temp_xlsx"; NSDirectory::CreateDirectory(href_folder); outputXlsx.write(href_folder); std::wstring href = L"Microsoft_Excel_Worksheet_" + std::to_wstring(Context.get_mediaitems()->count_object + 1) + L".xlsx"; - + COfficeUtils oCOfficeUtils(NULL); if (S_OK == oCOfficeUtils.CompressFileOrDirectory(href_folder, odfPath + FILE_SEPARATOR_STR + href, true)) - { + { objectBuild.embeddedData = href; } } @@ -1707,40 +1721,45 @@ void draw_object::docx_convert(oox::docx_conversion_context & Context) xlsx_context.get_table_context().end_table(); xlsx_context.get_drawing_context().process_objects(xlsx_context.get_table_metrics()); - + std::wstringstream strm; xlsx_context.get_drawing_context().serialize(strm, L"cdr"); - + const std::pair drawingName = - xlsx_context.get_drawing_context_handle()->add_drawing_xml(strm.str(), xlsx_context.get_drawing_context().get_drawings(), oox::typeChartUserShapes ); + xlsx_context.get_drawing_context_handle()->add_drawing_xml(strm.str(), xlsx_context.get_drawing_context().get_drawings(), oox::typeChartUserShapes); objectBuild.userShapes = drawingName; } - objectBuild.docx_convert(Context); - } -//------------------------------------------------------------------------------------------------------------ + bool state = Context.get_drawing_state_content(); + Context.set_drawing_state_content(!drawing->isInline || drawing->inFrame); + + objectBuild.docx_convert(Context); + + Context.set_drawing_state_content(state); + } + //------------------------------------------------------------------------------------------------------------ if (!frame || !drawing) { objectBuild.object_type_ = 0; } if (objectBuild.object_type_ == 1) //диаграмма - { + { drawing->type = oox::typeChart; - - bool isMediaInternal = true; + + bool isMediaInternal = true; drawing->objectId = Context.get_mediaitems()->add_or_find(href, drawing->type, isMediaInternal, href, Context.get_type_place()); } - else if (objectBuild.object_type_ == 2 ) //embedded text - { + else if (objectBuild.object_type_ == 2) //embedded text + { //text in text not support } else if (objectBuild.object_type_ == 3) //мат формулы { - const std::wstring & content = Context.get_drawing_context().get_text_stream_frame(); + const std::wstring& content = Context.get_drawing_context().get_text_stream_frame(); - bool in_frame = !drawing->isInline; + bool in_frame = !drawing->isInline || drawing->inFrame; bool runState = Context.get_run_state(); bool pState = Context.get_paragraph_state(); @@ -1752,9 +1771,11 @@ void draw_object::docx_convert(oox::docx_conversion_context & Context) { drawing->type = oox::typeShape; - drawing->additional.push_back(_property(L"fit-to-size", true)); - drawing->additional.push_back(_property(L"text-content", std::wstring(L"") + - content + std::wstring(L""))); + //drawing->additional.push_back(_property(L"auto-grow-width", true)); + drawing->additional.push_back(_property(L"auto-grow-height", true)); + + //drawing->additional.push_back(_property(L"fit-to-size", true)); + drawing->additional.push_back(_property(L"text-content", std::wstring(L"") + content + std::wstring(L""))); } else {//in text @@ -1762,9 +1783,7 @@ void draw_object::docx_convert(oox::docx_conversion_context & Context) if (runState) Context.finish_run(); - Context.output_stream() << L""; Context.output_stream() << content; - Context.output_stream() << L""; if (runState) Context.add_new_run(_T("")); } @@ -1807,25 +1826,35 @@ void draw_object_ole::docx_convert(oox::docx_conversion_context & Context) //------------------------------------------------ std::wstring href = xlink_attlist_.href_.get_value_or(L""); - std::wstring folderPath = Context.root()->get_folder(); - std::wstring objectPath = folderPath + FILE_SEPARATOR_STR + href; - if (href.empty()) return; draw_frame* frame = Context.get_drawing_context().get_current_frame(); //owner if (!frame) return; - oox::_docx_drawing * drawing = dynamic_cast(frame->oox_drawing_.get()); + if (href.empty()) return; + + oox::_docx_drawing* drawing = dynamic_cast(frame->oox_drawing_.get()); if (!drawing) return; - - std::wstring extension; - detectObject(objectPath, drawing->objectProgId, extension, drawing->type); - NSFile::CFileBinary::Copy(objectPath, objectPath + extension); + std::wstring folderPath = Context.root()->get_folder(); + if (Context.get_mediaitems()->is_internal_path(href, folderPath)) + { + std::wstring objectPath = folderPath + FILE_SEPARATOR_STR + href; + + std::wstring extension; + detectObject(objectPath, drawing->objectProgId, extension, drawing->type); + + NSFile::CFileBinary::Copy(objectPath, objectPath + extension); - bool isMediaInternal = true; - drawing->objectId = Context.get_mediaitems()->add_or_find(href + extension, drawing->type, isMediaInternal, href, Context.get_type_place()); + bool isMediaInternal = true; + drawing->objectId = Context.get_mediaitems()->add_or_find(href + extension, drawing->type, isMediaInternal, href, Context.get_type_place()); + } + else + { + bool isMediaInternal = false; + drawing->objectId = Context.get_mediaitems()->add_or_find(href, oox::typeOleObject, isMediaInternal, href, Context.get_type_place()); + } } void draw_control::docx_convert(oox::docx_conversion_context & Context) { diff --git a/OdfFile/Reader/Format/draw_frame_pptx.cpp b/OdfFile/Reader/Format/draw_frame_pptx.cpp index 8cf19e81c0d..179d3ab8f36 100644 --- a/OdfFile/Reader/Format/draw_frame_pptx.cpp +++ b/OdfFile/Reader/Format/draw_frame_pptx.cpp @@ -77,7 +77,7 @@ void draw_g::pptx_convert(oox::pptx_conversion_context & Context) } void draw_frame::pptx_convert_placeHolder(oox::pptx_conversion_context & Context) { - Context.get_slide_context().set_property(_property(L"no_rect",true)); + Context.get_slide_context().set_property(_property(L"no_rect", true)); pptx_convert(Context); } void draw_frame::pptx_convert(oox::pptx_conversion_context & Context) @@ -88,25 +88,36 @@ void draw_frame::pptx_convert(oox::pptx_conversion_context & Context) { common_shape_draw_attlist &common_draw_attlist_ = common_draw_attlists_.shape_with_text_and_styles_.common_shape_draw_attlist_; common_presentation_attlist &common_presentation_attlist_ = common_draw_attlists_.shape_with_text_and_styles_.common_presentation_attlist_; - + const unsigned int z_index = common_draw_attlist_.draw_z_index_.get_value_or(0); const std::wstring name = common_draw_attlist_.draw_name_.get_value_or(L""); const std::wstring textStyleName = common_draw_attlist_.draw_text_style_name_.get_value_or(L""); + const std::wstring drawId = common_draw_attlist_.draw_id_.get_value_or(L""); Context.get_slide_context().set_name(name); + Context.get_slide_context().set_id(drawId); ////////////////////////////////////////////////////////////////////////// const _CP_OPT(length) svg_widthVal = common_draw_attlists_.rel_size_.common_draw_size_attlist_.svg_width_; const _CP_OPT(length) svg_heightVal = common_draw_attlists_.rel_size_.common_draw_size_attlist_.svg_height_; double width_pt = 0, height_pt = 0; - if (svg_widthVal && svg_heightVal) { - const double width_pt = svg_widthVal.get_value_or(length(0)).get_value_unit(length::pt); - const double height_pt = svg_heightVal.get_value_or(length(0)).get_value_unit(length::pt); + double width_pt = svg_widthVal.get_value_or(length(0)).get_value_unit(length::pt); + double height_pt = svg_heightVal.get_value_or(length(0)).get_value_unit(length::pt); double x_pt = common_draw_attlists_.position_.svg_x_.get_value_or(length(0)).get_value_unit(length::pt); double y_pt = common_draw_attlists_.position_.svg_y_.get_value_or(length(0)).get_value_unit(length::pt); + if (width_pt <= 0) + { + width_pt = 1; + Context.get_slide_context().set_property(_property(L"auto-grow-width", true)); + } + if (height_pt <= 0) + { + height_pt = 1; + Context.get_slide_context().set_property(_property(L"auto-grow-height", true)); + } if (x_pt < 0) x_pt = 0; if (y_pt < 0) y_pt = 0; @@ -177,16 +188,49 @@ void draw_frame::pptx_convert(oox::pptx_conversion_context & Context) Context.get_slide_context().set_property(odf_reader::_property(L"border_width_top", Compute_BorderWidth(properties, sideTop))); Context.get_slide_context().set_property(odf_reader::_property(L"border_width_right", Compute_BorderWidth(properties, sideRight))); Context.get_slide_context().set_property(odf_reader::_property(L"border_width_bottom", Compute_BorderWidth(properties, sideBottom))); + + if (properties->style_columns_) + properties->style_columns_->pptx_convert(Context); } Context.get_slide_context().set_fill(fill); if (common_presentation_attlist_.presentation_class_) { - Context.get_slide_context().set_placeHolder_type(common_presentation_attlist_.presentation_class_->get_type_ms()); + std::wstring placeholder_type = common_presentation_attlist_.presentation_class_->get_type_ms(); + if (Context.get_slide_context().processing_notes() && placeholder_type == L"pic") + placeholder_type = L"sldImg"; + + if (!Context.process_masters_ && !Context.get_slide_context().processing_notes() && + common_presentation_attlist_.presentation_class_->get_type() == odf_types::presentation_class::outline) + Context.get_slide_context().set_is_placeHolder(true); + else + Context.get_slide_context().set_placeHolder_type(placeholder_type); if (idx_in_owner >= 0) Context.get_slide_context().set_placeHolder_idx(idx_in_owner); + + if (!Context.get_slide_context().processing_notes()) + { + bool is_placeholder = common_presentation_attlist_.presentation_placeholder_.get_value_or(Bool(false)).get(); + Context.get_slide_context().set_is_placeHolder(is_placeholder); + } + + if (!textStyleName.empty()) + { + odf_reader::style_instance* textStyleInst = + Context.root()->odf_context().styleContainer().style_by_name(textStyleName, odf_types::style_family::Paragraph, Context.process_masters_); + + paragraph_format_properties paragraph_properties = calc_paragraph_properties_content(textStyleInst); + text_format_properties_ptr text_properties = calc_text_properties_content(textStyleInst); + + pptx_convert_placeHolder_styles(Context, properties.get(), ¶graph_properties, text_properties.get()); + } + } + + if (common_draw_attlists_.shape_with_text_and_styles_.common_shape_draw_attlist_.drawooo_display_) + { + Context.get_slide_context().set_hidden(true); } if (!textStyleName.empty()) @@ -195,6 +239,21 @@ void draw_frame::pptx_convert(oox::pptx_conversion_context & Context) Context.root()->odf_context().styleContainer().style_by_name(textStyleName, odf_types::style_family::Paragraph, Context.process_masters_); paragraph_format_properties paragraph_properties = calc_paragraph_properties_content(textStyleInst); + + if (paragraph_properties.style_writing_mode_) + { + const odf_types::writing_mode& mode = *paragraph_properties.style_writing_mode_; + if (mode.get_type() == odf_types::writing_mode::TbRl) + { + _property vert = _property(L"text_vert", 1); + Context.get_slide_context().set_property(vert); + } + else if (mode.get_type() == odf_types::writing_mode::TbLr) + { + _property vert270 = _property(L"text_vert", 2); + Context.get_slide_context().set_property(vert270); + } + } } if (office_event_listeners_) office_event_listeners_->pptx_convert(Context); @@ -214,6 +273,37 @@ void draw_frame::pptx_convert(oox::pptx_conversion_context & Context) Context.get_slide_context().end_frame(); } +void draw_frame::pptx_convert_placeHolder_styles(oox::pptx_conversion_context& Context, const graphic_format_properties* graphic_props, const paragraph_format_properties* paragraph_props, const text_format_properties* text_props) +{ + if (graphic_props) + { + int vert_align; + + if (graphic_props->draw_textarea_vertical_align_) + vert_align = (int)graphic_props->draw_textarea_vertical_align_->get_type(); + else + vert_align = (int)odf_types::vertical_align::Auto; + + Context.get_slide_context().set_property(odf_reader::_property(L"textarea-vertical_align", vert_align)); + } + + if (text_props) + { + if (text_props->fo_color_) + Context.get_slide_context().set_property(odf_reader::_property(L"placeholder-text-color", text_props->fo_color_->get_hex_value())); + if (text_props->fo_font_size_) + Context.get_slide_context().set_property( + odf_reader::_property(L"placeholder-font-size", text_props->fo_font_size_->get_length().get_value_unit(odf_types::length::pt))); + if(text_props->fo_font_weight_ && text_props->fo_font_weight_->get_type() == odf_types::font_weight::WBold) + Context.get_slide_context().set_property(odf_reader::_property(L"placeholder-font-bold", true)); + } + + if (paragraph_props) + { + //if(paragraph_props->fo_text_align_) + } +} + void draw_image::pptx_convert(oox::pptx_conversion_context & Context) { if (draw_frame_ptr) @@ -292,7 +382,6 @@ void draw_text_box::pptx_convert(oox::pptx_conversion_context & Context) frame->content_.push_back(elm); frame->pptx_convert(Context); - } return; } @@ -339,12 +428,13 @@ void draw_object::pptx_convert(oox::pptx_conversion_context & Context) { if (href[0] == L'#') href = href.substr(1); - std::wstring objectPath = odfPath + FILE_SEPARATOR_STR + href; - - // normalize path ???? todooo - XmlUtils::replace_all( objectPath, FILE_SEPARATOR_STR + std::wstring(L"./"), FILE_SEPARATOR_STR); - - odf_document_ = odf_document_ptr(new odf_document(objectPath, tempPath, L"")); + if (Context.get_mediaitems()->is_internal_path(href, odfPath)) + { + std::wstring objectPath = odfPath + FILE_SEPARATOR_STR + href; + // normalize path ???? todooo + XmlUtils::replace_all(objectPath, FILE_SEPARATOR_STR + std::wstring(L"./"), FILE_SEPARATOR_STR); + odf_document_ = odf_document_ptr(new odf_document(objectPath, tempPath, L"")); + } } //--------------------------------------------------------------------------------------------------------------------- office_element *contentSubDoc = odf_document_ ? odf_document_->get_impl()->get_content() : NULL; @@ -418,14 +508,15 @@ void draw_object::pptx_convert(oox::pptx_conversion_context & Context) if (!math_content.empty()) { std::wstring text_content = L""; - text_content += L""; +// text_content += L""; text_content += math_content; - text_content += L""; + text_content += L""; if (bNewObject) { Context.get_slide_context().set_property(_property(L"fit-to-size", true)); Context.get_slide_context().set_property(_property(L"text-content", text_content)); + Context.get_slide_context().set_property(_property(L"is-math-formula", true)); // do not wrap math formulas } else { @@ -463,12 +554,18 @@ void draw_object_ole::pptx_convert(oox::pptx_conversion_context & Context) { Context.get_slide_context().set_use_image_replacement(); - std::wstring href = xlink_attlist_.href_.get_value_or(L""); - std::wstring folderPath = Context.root()->get_folder(); - std::wstring objectPath = folderPath + FILE_SEPARATOR_STR + href; + std::wstring href = xlink_attlist_.href_.get_value_or(L""); + if (href.empty()) return; - if (!href.empty()) + std::wstring folderPath = Context.root()->get_folder(); + if (Context.get_mediaitems()->is_internal_path(href, folderPath)) { + std::wstring objectPath = folderPath + FILE_SEPARATOR_STR + href; + NSFile::CFileBinary objectFile; + objectFile.OpenFile(objectPath); + if (objectFile.SizeFile() == 0) + return; + std::wstring prog, extension; oox::_rels_type relsType; detectObject(objectPath, prog, extension, relsType); @@ -480,6 +577,10 @@ void draw_object_ole::pptx_convert(oox::pptx_conversion_context & Context) else Context.get_slide_context().set_ole_object(href + extension, prog); } + else + { + Context.get_slide_context().set_ole_object(href, L""); + } } void draw_param::pptx_convert(oox::pptx_conversion_context & Context) diff --git a/OdfFile/Reader/Format/draw_frame_xlsx.cpp b/OdfFile/Reader/Format/draw_frame_xlsx.cpp index 4ae6cdcef1d..0a030d4bd4a 100644 --- a/OdfFile/Reader/Format/draw_frame_xlsx.cpp +++ b/OdfFile/Reader/Format/draw_frame_xlsx.cpp @@ -131,7 +131,7 @@ void draw_frame::xlsx_convert(oox::xlsx_conversion_context & Context) const std::wstring textStyleName = common_draw_attlist_.common_shape_draw_attlist_.draw_text_style_name_.get_value_or(L""); ////////////////////////////////////////////////////////////////////////// - if (Context.get_text_context().is_drawing_context()) + if (Context.get_text_context()->is_drawing_context()) { Context.get_drawing_context().set_text_box(); } @@ -258,14 +258,14 @@ void draw_image::xlsx_convert(oox::xlsx_conversion_context & Context) Context.get_drawing_context().set_image(href); ////////////////////////////////////в принципе достаточно общая часть ... - Context.get_text_context().start_drawing_content(); //... если в объекте есть текст он привяжется к объекту - иначе к ячейке + Context.get_text_context()->start_drawing_content(); //... если в объекте есть текст он привяжется к объекту - иначе к ячейке Context.start_drawing_context(); for (size_t i = 0 ; i < content_.size(); i++) { content_[i]->xlsx_convert(Context); } - std::wstring text_content_ = Context.get_text_context().end_drawing_content(); + std::wstring text_content_ = Context.get_text_context()->end_drawing_content(); Context.end_drawing_context(); if (!text_content_.empty()) @@ -304,7 +304,7 @@ void draw_text_box::xlsx_convert(oox::xlsx_conversion_context & Context) //--------------------------------------------------------------------------------------------------------------- Context.get_drawing_context().set_text_box(); - Context.get_text_context().start_drawing_content(); + Context.get_text_context()->start_drawing_content(); Context.start_drawing_context(); for (size_t i = 0 ; i < content_.size(); i++) @@ -312,7 +312,7 @@ void draw_text_box::xlsx_convert(oox::xlsx_conversion_context & Context) content_[i]->xlsx_convert(Context); } - std::wstring text_content_ = Context.get_text_context().end_drawing_content(); + std::wstring text_content_ = Context.get_text_context()->end_drawing_content(); Context.end_drawing_context(); if (!text_content_.empty()) @@ -340,19 +340,22 @@ void draw_object::xlsx_convert(oox::xlsx_conversion_context & Context) try { std::wstring href = xlink_attlist_.href_.get_value_or(L""); - + std::wstring tempPath = Context.root()->get_temp_folder(); + if (!odf_document_ && false == href.empty()) { if (href[0] == L'#') href = href.substr(1); - - std::wstring tempPath = Context.root()->get_temp_folder(); + std::wstring folderPath = Context.root()->get_folder(); - std::wstring objectPath = folderPath + FILE_SEPARATOR_STR + href; + if (Context.get_mediaitems()->is_internal_path(href, folderPath)) + { + std::wstring objectPath = folderPath + FILE_SEPARATOR_STR + href; - // normalize path ???? todooo - XmlUtils::replace_all( objectPath, FILE_SEPARATOR_STR + std::wstring(L"./"), FILE_SEPARATOR_STR); + // normalize path ???? todooo + XmlUtils::replace_all(objectPath, FILE_SEPARATOR_STR + std::wstring(L"./"), FILE_SEPARATOR_STR); - odf_document_ = odf_document_ptr(new odf_document(objectPath, tempPath, L"")); + odf_document_ = odf_document_ptr(new odf_document(objectPath, tempPath, L"")); + } } office_element *contentSubDoc = odf_document_ ? odf_document_->get_impl()->get_content() : NULL; if (!contentSubDoc) @@ -401,9 +404,9 @@ void draw_object::xlsx_convert(oox::xlsx_conversion_context & Context) if (!math_content.empty()) { std::wstring text_content = L""; - text_content += L""; +// text_content += L""; text_content += math_content; - text_content += L""; + text_content += L""; if (bNewObject) { @@ -412,7 +415,7 @@ void draw_object::xlsx_convert(oox::xlsx_conversion_context & Context) } else { - Context.get_text_context().add_paragraph(text_content); + Context.get_text_context()->add_paragraph(text_content); } } } @@ -439,11 +442,13 @@ void draw_object_ole::xlsx_convert(oox::xlsx_conversion_context & Context) Context.get_drawing_context().set_use_image_replacement(); std::wstring href = xlink_attlist_.href_.get_value_or(L""); - std::wstring folderPath = Context.root()->get_folder(); - std::wstring objectPath = folderPath + FILE_SEPARATOR_STR + href; + if (href.empty()) return; - if (!href.empty()) + std::wstring folderPath = Context.root()->get_folder(); + if (Context.get_mediaitems()->is_internal_path(href, folderPath)) { + std::wstring objectPath = folderPath + FILE_SEPARATOR_STR + href; + std::wstring prog, extension; oox::_rels_type relsType; detectObject(objectPath, prog, extension, relsType); @@ -455,6 +460,10 @@ void draw_object_ole::xlsx_convert(oox::xlsx_conversion_context & Context) else Context.get_drawing_context().set_ole_object(href + extension, prog); } + else + { + Context.get_drawing_context().set_ole_object(href, L""); + } } } diff --git a/OdfFile/Reader/Format/draw_page.cpp b/OdfFile/Reader/Format/draw_page.cpp index c6cd1b8c471..53bf71e9e73 100644 --- a/OdfFile/Reader/Format/draw_page.cpp +++ b/OdfFile/Reader/Format/draw_page.cpp @@ -88,9 +88,9 @@ void draw_page::pptx_convert_placeHolder(oox::pptx_conversion_context & Context, office_element_ptr elm = Context.root()->odf_context().drawStyles().find_by_style_name(styleName); //todooo если это элемент datatime -нужно вытащить формат поля - if (!elm)return; + if (!elm) return; - int index=-1; + int index = -1; const std::wstring masterName = attlist_.master_page_name_.get_value_or(L""); style_master_page * master = Context.root()->odf_context().pageLayoutContainer().master_page_by_name(masterName); @@ -98,9 +98,13 @@ void draw_page::pptx_convert_placeHolder(oox::pptx_conversion_context & Context, if (master) index = master->find_placeHolderIndex(PresentationClass, Context.last_idx_placeHolder); - Context.get_slide_context().start_shape(1); - Context.get_slide_context().set_placeHolder_type(presentation_class(PresentationClass).get_type_ms()); + + std::wstring placeholder_type = presentation_class(PresentationClass).get_type_ms(); + if (Context.get_slide_context().processing_notes() && placeholder_type == L"pic") + placeholder_type = L"sldImg"; + Context.get_slide_context().set_placeHolder_type(placeholder_type); + Context.get_slide_context().set_placeHolder_idx(index); Context.get_text_context().start_object(); @@ -114,11 +118,11 @@ void draw_page::pptx_convert_placeHolder(oox::pptx_conversion_context & Context, std::wstring text_content_ = Context.get_text_context().end_object(); - if (text_content_.length()>0) + if (false == text_content_.empty()) { - Context.get_slide_context().set_property(_property(L"text-content",text_content_)); + Context.get_slide_context().set_property(_property(L"text-content", text_content_)); } - Context.get_slide_context().set_property(_property(L"no_rect",true)); + Context.get_slide_context().set_property(_property(L"no_rect", true)); Context.get_slide_context().end_shape(); } @@ -132,11 +136,11 @@ void draw_page::pptx_convert(oox::pptx_conversion_context & Context) _CP_LOG << L"[info][pptx] process page(slide) \"" << pageName /*L"" */<< L"\"" << std::endl; - Context.start_page(pageName, pageStyleName, layoutName,masterName); + Context.start_page(pageName, pageStyleName, layoutName, masterName); if (attlist_.draw_style_name_) { - style_instance * style_inst = Context.root()->odf_context().styleContainer().style_by_name(pageStyleName,style_family::DrawingPage,false); + style_instance * style_inst = Context.root()->odf_context().styleContainer().style_by_name(pageStyleName,style_family::DrawingPage, false); if ((style_inst) && (style_inst->content())) { @@ -147,6 +151,9 @@ void draw_page::pptx_convert(oox::pptx_conversion_context & Context) oox::_oox_fill fill; Compute_GraphicFill(properties->content().common_draw_fill_attlist_, office_element_ptr(), Context.root(), fill); Context.get_slide_context().add_background(fill); + + bool is_page_visible = properties->content().presentation_visibility_.get_value_or(presentation_visibility::visible).get_type() == presentation_visibility::visible; + Context.current_slide().set_show(is_page_visible); //часть свойств переходов между слайдами тута @@ -179,12 +186,7 @@ void draw_page::pptx_convert(oox::pptx_conversion_context & Context) } } } - //сначала анимашки .. потому что объекты используют анимацию не нанапрямую (как бы ) а с общей кучи - //animation_context на slide_context завести - if (animation_) - { - animation_->pptx_convert(Context); - } + ///////////////////////// for (size_t i = 0; i < content_.size(); i++) { @@ -201,16 +203,30 @@ void draw_page::pptx_convert(oox::pptx_conversion_context & Context) std::wstring name = L"datetime:" + *attlist_.use_date_time_name_; pptx_convert_placeHolder(Context, name, presentation_class::date_time); } - + + Context.get_slide_context().process_drawings(); + + if (animation_) + { + animation_->pptx_convert(Context); + } + Context.end_page(); if (presentation_notes_) { Context.start_page_notes(); presentation_notes_->pptx_convert(Context); + Context.get_slide_context().process_drawings(); Context.end_page_notes(); } } + +std::wstring draw_page::get_draw_name() const +{ + return attlist_.draw_name_.get_value_or(L""); +} + ////////////////////////////////////////////////////////////////////////////////////////////////// const wchar_t * presentation_footer_decl::ns = L"presentation"; const wchar_t * presentation_footer_decl::name = L"footer-decl"; @@ -282,9 +298,12 @@ void presentation_notes::pptx_convert_placeHolder(oox::pptx_conversion_context & //if (master) // index = master->find_placeHolderIndex(PresentationClass, Context.last_idx_placeHolder); + std::wstring placeholder_type = presentation_class(PresentationClass).get_type_ms(); + if (Context.get_slide_context().processing_notes() && placeholder_type == L"pic") + placeholder_type = L"sldImg"; Context.get_slide_context().start_shape(1); - Context.get_slide_context().set_placeHolder_type(presentation_class(PresentationClass).get_type_ms()); + Context.get_slide_context().set_placeHolder_type(placeholder_type); Context.get_slide_context().set_placeHolder_idx(index); Context.get_text_context().start_object(); @@ -298,17 +317,19 @@ void presentation_notes::pptx_convert_placeHolder(oox::pptx_conversion_context & std::wstring text_content_ = Context.get_text_context().end_object(); - if (text_content_.length()>0) + if (false == text_content_.empty()) { - Context.get_slide_context().set_property(_property(L"text-content",text_content_)); + Context.get_slide_context().set_property(_property(L"text-content", text_content_)); } - Context.get_slide_context().set_property(_property(L"no_rect",true)); + Context.get_slide_context().set_property(_property(L"no_rect", true)); Context.get_slide_context().end_shape(); } void presentation_notes::pptx_convert(oox::pptx_conversion_context & Context) { + Context.get_slide_context().processing_notes(true); + const std::wstring pageStyleName = attlist_.draw_style_name_.get_value_or(L""); const std::wstring layoutName = attlist_.page_layout_name_.get_value_or(L""); const std::wstring masterName = attlist_.master_page_name_.get_value_or(L""); @@ -362,6 +383,8 @@ void presentation_notes::pptx_convert(oox::pptx_conversion_context & Context) pptx_convert_placeHolder(Context, name, presentation_class::date_time); } + Context.get_slide_context().processing_notes(false); + } } diff --git a/OdfFile/Reader/Format/draw_page.h b/OdfFile/Reader/Format/draw_page.h index 5d452a6dc14..448e0633419 100644 --- a/OdfFile/Reader/Format/draw_page.h +++ b/OdfFile/Reader/Format/draw_page.h @@ -69,6 +69,8 @@ class draw_page : public office_element_impl virtual void pptx_convert(oox::pptx_conversion_context & Context); + std::wstring get_draw_name() const; + private: void pptx_convert_placeHolder(oox::pptx_conversion_context & Context, std::wstring styleName, odf_types::presentation_class::type PresentationClass); diff --git a/OdfFile/Reader/Format/draw_shapes.cpp b/OdfFile/Reader/Format/draw_shapes.cpp index 2e10f13bbe9..9d52d2c104e 100644 --- a/OdfFile/Reader/Format/draw_shapes.cpp +++ b/OdfFile/Reader/Format/draw_shapes.cpp @@ -530,34 +530,46 @@ void draw_enhanced_geometry::add_child_element( xml::sax * Reader, const std::ws } } -std::wstring convert_equation(const std::wstring& formula) +bool convert_equation(std::wstring formula, std::wstring &result) { - std::wstring result; std::wstring operators; + std::wstring function; std::vector values; + boost::erase_all(formula, L" "); + + bool next_negative = false; + size_t pos = 0; - bool operator_prev = false; while (pos < formula.size()) { - if ((formula[pos] == L'+' || formula[pos] == L'/' || formula[pos] == L'*' || formula[pos] == L'-') - && pos > 0 && !operator_prev) + if ((formula[pos] == L'+' || formula[pos] == L'/' || formula[pos] == L'*') && pos > 0) { - if (operators.size() > 1) - return L""; - operator_prev = true; + if (operators.size() > 1 && !function.empty()) + { + return false; // ? todooo + } + operators += formula[pos++]; } + else if (formula[pos] == L'-') + { + if (pos > 0 && (formula[pos-1] == L'+' || formula[pos-1] == L'/' || formula[pos - 1] == L'*' || formula[pos - 1] == L',')) + { + next_negative = true; + pos++; + } + else + operators += formula[pos++]; + } else if (formula[pos] == L'i' && formula[pos + 1] == L'f') { if (false == operators.empty()) - return L""; - operator_prev = true; - operators += L"?:"; pos += 2; + return false; + function += L"?:"; pos += 2; } else if (formula[pos] == L'?') { - operator_prev = false; values.emplace_back(); values.back() = L"gd"; pos += 2; while (pos < formula.size() && formula[pos] >= L'0' && formula[pos] <= L'9') @@ -568,61 +580,83 @@ std::wstring convert_equation(const std::wstring& formula) else if (formula[pos] == L'c') { if (false == operators.empty()) - return L""; - operator_prev = true; - operators += L"cos"; pos += 3; + return false; + + if (pos + 2 < formula.size() && formula[pos + 1] == L'o') + { + function = L"cos"; pos += 3; + } + else if (pos + 3 < formula.size() && formula[pos + 1] == L'a' && formula[pos + 2] == L't') + { + function = L"cat2"; pos += 4; + } + else pos++; + } + else if (formula[pos] == 'a') + { + if (false == operators.empty()) + return false; + + if (pos + 2 < formula.size() && formula[pos + 1] == L'b' && formula[pos + 2] == L's') + { + function = L"abs"; pos += 3; + } + else if (pos + 2 < formula.size() && formula[pos + 1] == L't' && formula[pos + 2] == L'a' && formula[pos + 3] == L'n' && formula[pos + 4] == L'2') + { + function = L"atan2"; pos += 5; + } + else pos++; } else if (formula[pos] == L'b') {//bottom - operator_prev = false; values.emplace_back(); values.back() = L"h"; pos += 6; } else if (formula[pos] == L't') {//top - operator_prev = false; values.emplace_back(); values.back() = L"0"; pos += 3; } else if (formula[pos] == L'r') {//right - operator_prev = false; values.emplace_back(); values.back() = L"w"; pos += 5; } else if (formula[pos] == L's') { if (false == operators.empty()) - return L""; - operator_prev = true; + return false; if (pos + 2 < formula.size() && formula[pos + 1] == L'i') { - operators = L"sin"; pos += 3; + function = L"sin"; pos += 3; } else if (pos + 3 < formula.size() && formula[pos + 1] == L'q') { - operators = L"sqrt"; pos += 4; + function = L"sqrt"; pos += 4; } + else if (pos + 3 < formula.size() && formula[pos + 1] == L'a' && formula[pos + 2] == L't') + { + function = L"sat2"; pos += 4; + } + else pos++; } else if (formula[pos] == L'm') { if (false == operators.empty()) - return L""; - operator_prev = true; + return false; if (pos + 2 < formula.size() && formula[pos + 1] == L'a') { - operators = L"max"; pos += 3; + function = L"max"; pos += 3; } else if (pos + 2 < formula.size() && formula[pos + 1] == L'i') { - operators = L"min"; pos += 3; + function = L"min"; pos += 3; } else pos++; } else if (formula[pos] == L'l') { - operator_prev = false; - if (pos + 8 < formula.size() && formula[pos + 1] == L'o' && formula[pos + 2] == L'g') + if (pos + 8 <= formula.size() && formula[pos + 1] == L'o' && formula[pos + 2] == L'g') { if (formula[pos + 3] == L'w') { @@ -644,50 +678,74 @@ std::wstring convert_equation(const std::wstring& formula) } else if (formula[pos] == L'$') { - operator_prev = false; - if (pos + 1 < formula.size() && formula[pos + 1] >= L'0' && formula[pos + 1] <= L'9') { - int adj = XmlUtils::GetInteger(std::wstring(formula[pos + 1], 1)); + std::wstring strVal = formula.substr(pos + 1, 1); + int adj = XmlUtils::GetInteger(strVal); values.emplace_back(); values.back() = L"adj" + std::to_wstring(adj + 1); } pos += 2; } - else if (formula[pos] >= L'0' && formula[pos] <= L'9' || formula[pos] == L'-') + else if (formula[pos] >= L'0' && formula[pos] <= L'9' || formula[pos] == L'-' || formula[pos] == L'w' || formula[pos] == L'h') { - operator_prev = false; - values.emplace_back(); + + if (next_negative) + { + values.back() += L'-'; + next_negative = false; + } + size_t pos_start = pos; - while (pos < formula.size() && formula[pos] >= L'0' && formula[pos] <= L'9' || (formula[pos] == L'-' && pos_start == pos)) + while (pos < formula.size() && formula[pos] >= L'0' && formula[pos] <= L'9' || ((formula[pos] == L'-' || formula[pos] == L'w' || formula[pos] == L'h') && pos_start == pos)) { values.back() += formula[pos++]; } } + else if (formula[pos] == L',') + { + pos++; + } else pos++; } - if (operators.empty()) + if (operators.empty() && function.empty()) { result = L"val"; } - else if (operators.size() < 2) - { - return L""; - } else { - result = operators; + if (operators == L"+") + { + operators = L"+-"; + values.push_back(L"0"); + } + else if (operators == L"*") + { + operators = L"*/"; + values.push_back(L"1"); + } + else if (operators == L"/") + { + operators = L"*/"; + values.insert(values.begin(), L"1"); + } + else if (operators == L"-") + { + operators = L"+-"; + values.insert(values.begin(), L"0"); + } + result = function.empty() ? operators : function; } for (int i = 0; i < values.size(); ++i) { result += L" " + values[i]; } - return result; + return true; } void draw_enhanced_geometry::find_draw_type_oox() { @@ -759,6 +817,49 @@ void draw_enhanced_geometry::find_draw_type_oox() if (attlist_.drawooo_enhanced_path_) odf_path_ = attlist_.drawooo_enhanced_path_.get(); else if (attlist_.draw_enhanced_path_) odf_path_ = attlist_.draw_enhanced_path_.get(); } + +static void process_polylines(std::vector<::svg_path::_polylineS>& polylines, const std::vector>& equations) +{ + using namespace ::svg_path; + + for (size_t i = 0; i < polylines.size(); i++) + { + _polylineS& p = polylines[i]; + + if (p.command == L"a:arcTo" && p.points.size() > 1) + { + ::svg_path::_pointS& pt = p.points[1]; + + auto x_it = std::find_if(equations.begin(), equations.end(), + [&pt](const std::pair& eq) {return pt.x && eq.first == *pt.x;}); + auto y_it = std::find_if(equations.begin(), equations.end(), + [&pt](const std::pair& eq) {return pt.y && eq.first == *pt.y; }); + + if (x_it != equations.end()) + { + const std::wstring& formula = x_it->second; + + std::vector split; + boost::split(split, formula, boost::is_any_of("\t "), boost::token_compress_on); + + if (split.size() == 4 && split[0] == L"*/" && split[1] == L"1" && boost::starts_with(split[2], L"gd") && split[3] == L"60000") + pt.x = split[2]; + } + + if (y_it != equations.end()) + { + const std::wstring& formula = y_it->second; + + std::vector split; + boost::split(split, formula, boost::is_any_of("\t "), boost::token_compress_on); + + if (split.size() == 4 && split[0] == L"*/" && split[1] == L"1" && boost::starts_with(split[2], L"gd") && split[3] == L"60000") + pt.y = split[2]; + } + } + } +} + bool draw_enhanced_geometry::oox_convert(std::vector& props) { find_draw_type_oox(); @@ -792,7 +893,7 @@ bool draw_enhanced_geometry::oox_convert(std::vector& pro set_shape = true; } std::vector> equations; - if (false == draw_equations_.empty()) + if (false == draw_equations_.empty() && !draw_type_oox_index_) { for (size_t i = 0; i < draw_equations_.size(); i++) { @@ -803,19 +904,22 @@ bool draw_enhanced_geometry::oox_convert(std::vector& pro std::wstring value = eq->attlist_.draw_formula_.get_value_or(L""); XmlUtils::replace_all(name, L"f", L"gd"); - value = convert_equation(value); + + XmlUtils::replace_all(value, L"(bottom-top)", L"h"); + XmlUtils::replace_all(value, L"(right-left)", L"w"); - if (value.empty()) + std::wstring value_conv; + if (convert_equation(value, value_conv)) { + equations.push_back(std::make_pair(name, value_conv.empty() ? value : value_conv)); + } + else + {// if (!draw_type_oox_index_) set_shape = false; equations.clear(); break; } - else - {// - equations.push_back(std::make_pair(name, value)); - } } } @@ -850,6 +954,8 @@ bool draw_enhanced_geometry::oox_convert(std::vector& pro { set_shape = true; + process_polylines(o_Polyline, equations); + std::wstringstream output_; ::svg_path::oox_serialize(output_, o_Polyline); props.push_back(odf_reader::_property(L"custom_path", output_.str())); @@ -942,7 +1048,7 @@ bool draw_enhanced_geometry::oox_convert(std::vector& pro props.push_back(odf_reader::_property(L"custom_path_h", h)); } } - if (attlist_.draw_modifiers_ && set_shape && bOoxType_) + if (attlist_.draw_modifiers_ && ((set_shape && bOoxType_ && !draw_type_oox_index_) || (false == equations.empty()))) { props.push_back(_property(L"oox-draw-modifiers", attlist_.draw_modifiers_.get())); } @@ -978,6 +1084,11 @@ void draw_connector_attlist::add_attributes( const xml::attributes_wc_ptr & Attr CP_APPLY_ATTR(L"svg:d", svg_d_); CP_APPLY_ATTR(L"svg:viewBox", svg_viewbox_); CP_APPLY_ATTR(L"draw:type", draw_type_); + + CP_APPLY_ATTR(L"draw:start-shape" , draw_start_shape_); + CP_APPLY_ATTR(L"draw:end-shape" , draw_end_shape_); + CP_APPLY_ATTR(L"draw:start-glue-point" , draw_start_glue_point_); + CP_APPLY_ATTR(L"draw:end-glue-point" , draw_end_glue_point_); } //------------------------------------------------------------------------------------------- // draw:connector diff --git a/OdfFile/Reader/Format/draw_shapes.h b/OdfFile/Reader/Format/draw_shapes.h index a2fb3a29852..1ebbcd7eaba 100644 --- a/OdfFile/Reader/Format/draw_shapes.h +++ b/OdfFile/Reader/Format/draw_shapes.h @@ -536,9 +536,14 @@ class draw_connector_attlist { public: virtual void add_attributes( const xml::attributes_wc_ptr & Attributes ); - _CP_OPT(std::wstring) svg_d_; - _CP_OPT(std::wstring) svg_viewbox_; - _CP_OPT(std::wstring) draw_type_; + _CP_OPT(std::wstring) svg_d_; + _CP_OPT(std::wstring) svg_viewbox_; + _CP_OPT(std::wstring) draw_type_; + + _CP_OPT(std::wstring) draw_start_shape_; + _CP_OPT(std::wstring) draw_end_shape_; + _CP_OPT(int) draw_start_glue_point_; + _CP_OPT(int) draw_end_glue_point_; }; ///////////////////////////////////////////////////////////////////////// diff --git a/OdfFile/Reader/Format/draw_shapes_docx.cpp b/OdfFile/Reader/Format/draw_shapes_docx.cpp index 7107433a8b6..e5778bd9ac9 100644 --- a/OdfFile/Reader/Format/draw_shapes_docx.cpp +++ b/OdfFile/Reader/Format/draw_shapes_docx.cpp @@ -198,6 +198,14 @@ void draw_line::docx_convert(oox::docx_conversion_context & Context) void draw_path::docx_convert(oox::docx_conversion_context & Context) { + bool in_paragraph = !Context.get_paragraph_state(); + + if (in_paragraph) + { + Context.start_paragraph(); + Context.add_new_run(); + } + //if (Context.get_drawing_context().get_current_level() >0 )return; if (Context.get_drawing_context().get_current_level() > 0 && !Context.get_drawing_context().in_group() ) { @@ -209,6 +217,12 @@ void draw_path::docx_convert(oox::docx_conversion_context & Context) //... reset_svg_path(); draw_shape::docx_convert(Context); + + if (in_paragraph) + { + Context.finish_run(); + Context.finish_paragraph(); + } } void draw_connector::docx_convert(oox::docx_conversion_context & Context) diff --git a/OdfFile/Reader/Format/draw_shapes_pptx.cpp b/OdfFile/Reader/Format/draw_shapes_pptx.cpp index c61b218d0bb..04bc9eb8ed0 100644 --- a/OdfFile/Reader/Format/draw_shapes_pptx.cpp +++ b/OdfFile/Reader/Format/draw_shapes_pptx.cpp @@ -70,9 +70,11 @@ void draw_shape::common_pptx_convert(oox::pptx_conversion_context & Context) const unsigned int z_index = common_draw_attlist_.draw_z_index_.get_value_or(0); const std::wstring name = common_draw_attlist_.draw_name_.get_value_or(L""); const std::wstring textStyleName = common_draw_attlist_.draw_text_style_name_.get_value_or(L""); + const std::wstring xmlId = common_draw_attlist_.draw_id_.get_value_or(L""); /////////////////////////////////////////// Context.get_slide_context().set_name(name); + Context.get_slide_context().set_id(xmlId); const _CP_OPT(length) svg_widthVal = common_draw_attlists_.rel_size_.common_draw_size_attlist_.svg_width_; const _CP_OPT(length) svg_heightVal = common_draw_attlists_.rel_size_.common_draw_size_attlist_.svg_height_; @@ -137,6 +139,12 @@ void draw_shape::common_pptx_convert(oox::pptx_conversion_context & Context) { properties->apply_to(Context.get_slide_context().get_properties()); Compute_GraphicFill(properties->common_draw_fill_attlist_, properties->style_background_image_, Context.root(), fill); + + if (properties->fo_clip_) + { + std::wstring strRectClip = properties->fo_clip_.get(); + Context.get_slide_context().set_clipping(strRectClip.substr(5, strRectClip.length() - 6)); + } } for (size_t i = 0; i < additional_.size(); i++) { @@ -293,6 +301,8 @@ void draw_connector::reset_svg_attributes() { common_draw_attlists_.position_.svg_x_ = draw_line_attlist_.svg_x2_; common_draw_attlists_.rel_size_.common_draw_size_attlist_.svg_width_ = length(x1-x2, length::pt); + + additional_.push_back(_property(L"flipH", true)); }else { @@ -304,12 +314,23 @@ void draw_connector::reset_svg_attributes() common_draw_attlists_.position_.svg_y_ = draw_line_attlist_.svg_y2_; common_draw_attlists_.rel_size_.common_draw_size_attlist_.svg_height_ = length(y1-y2, length::pt); + additional_.push_back(_property(L"flipV", true)); + }else { common_draw_attlists_.position_.svg_y_ = draw_line_attlist_.svg_y1_; common_draw_attlists_.rel_size_.common_draw_size_attlist_.svg_height_ = length(y2-y1, length::pt); } } + +int pptx_convert_glue_point(int gluePoint) +{ + if (gluePoint < 4) + return 4 - gluePoint; + + return gluePoint - 4; +} + void draw_connector::pptx_convert(oox::pptx_conversion_context & Context) { if (draw_connector_attlist_.draw_type_) @@ -326,7 +347,47 @@ void draw_connector::pptx_convert(oox::pptx_conversion_context & Context) Context.get_slide_context().start_shape(sub_type_); common_pptx_convert(Context); + + if(draw_connector_attlist_.draw_start_shape_) + Context.get_slide_context().set_connector_start_shape(draw_connector_attlist_.draw_start_shape_.value()); + if (draw_connector_attlist_.draw_end_shape_) + Context.get_slide_context().set_connector_end_shape(draw_connector_attlist_.draw_end_shape_.value()); + if(draw_connector_attlist_.draw_start_glue_point_) + Context.get_slide_context().set_connector_start_glue_point(pptx_convert_glue_point(draw_connector_attlist_.draw_start_glue_point_.value())); + if (draw_connector_attlist_.draw_end_glue_point_) + Context.get_slide_context().set_connector_end_glue_point(pptx_convert_glue_point(draw_connector_attlist_.draw_end_glue_point_.value())); + + + int connector_size = 5; + if (draw_connector_attlist_.svg_d_) + { + std::vector<::svg_path::_polyline> polylines; + bool closed, stroked; + ::svg_path::parseSvgD(polylines, draw_connector_attlist_.svg_d_.value(), false, closed, stroked); + + const int v = polylines.size() - 1; + const int min = 2; + const int max = 5; + connector_size = v < min ? min : (v > max ? max : v); // clamp(v, min, max) + } + std::wstring drawType = draw_connector_attlist_.draw_type_.get_value_or(L"standart"); + std::wstring pptx_prst; + + if (drawType == L"curve") + pptx_prst = L"curvedConnector" + std::to_wstring(connector_size); + else if (drawType == L"lines") + pptx_prst = L"bentConnector" + std::to_wstring(connector_size); + else if (drawType == L"line") + pptx_prst = L"straightConnector1"; + else if (drawType == L"standart") + pptx_prst = L"bentConnector" + std::to_wstring(connector_size); + else + pptx_prst = L"straightConnector1"; + + Context.get_slide_context().set_connector_draw_type(pptx_prst); + + //перебъем заливку .. oox::_oox_fill fill; fill.type = 0; @@ -336,10 +397,7 @@ void draw_connector::pptx_convert(oox::pptx_conversion_context & Context) } void draw_enhanced_geometry::pptx_convert(oox::pptx_conversion_context & Context) { - find_draw_type_oox(); - - bool set_shape = oox_convert(Context.get_slide_context().get_properties()); - + bool set_shape = oox_convert(Context.get_slide_context().get_properties()); if (!set_shape) { diff --git a/OdfFile/Reader/Format/draw_shapes_xlsx.cpp b/OdfFile/Reader/Format/draw_shapes_xlsx.cpp index 0fde56a6d91..367b07a6057 100644 --- a/OdfFile/Reader/Format/draw_shapes_xlsx.cpp +++ b/OdfFile/Reader/Format/draw_shapes_xlsx.cpp @@ -145,7 +145,7 @@ void draw_shape::common_xlsx_convert(oox::xlsx_conversion_context & Context) Context.get_drawing_context().set_fill(fill); ////////////////////////////////////////////////////////////////////////////////////// - Context.get_text_context().start_drawing_content(); + Context.get_text_context()->start_drawing_content(); Context.start_drawing_context(); if (word_art_) @@ -157,7 +157,7 @@ void draw_shape::common_xlsx_convert(oox::xlsx_conversion_context & Context) { content_[i]->xlsx_convert(Context); } - std::wstring text_content_ = Context.get_text_context().end_drawing_content(); + std::wstring text_content_ = Context.get_text_context()->end_drawing_content(); Context.end_drawing_context(); if (!text_content_.empty()) diff --git a/OdfFile/Reader/Format/font_face.cpp b/OdfFile/Reader/Format/font_face.cpp index cc8982460aa..f2bbd64a754 100644 --- a/OdfFile/Reader/Format/font_face.cpp +++ b/OdfFile/Reader/Format/font_face.cpp @@ -32,15 +32,59 @@ #include "font_face.h" +#include "draw_frame.h" + #include #include "serialize_elements.h" namespace cpdoccore { namespace odf_reader { +// svg:title +//--------------------------------------------------------------------------------------- +const wchar_t* svg_title::ns = L"svg"; +const wchar_t* svg_title::name = L"title"; + +void svg_title::docx_convert(oox::docx_conversion_context& Context) +{ + odf_reader::draw_frame* current_frame = Context.get_drawing_context().get_current_frame(); + + if (current_frame && current_frame->oox_drawing_) + { + current_frame->oox_drawing_->additional.push_back(odf_reader::_property(L"svg:title", text_)); + } +} + +std::wostream& svg_title::text_to_stream(std::wostream& _Wostream, bool bXmlEncode) const +{ + _Wostream << text_; + return _Wostream; +} + +void svg_title::add_text(const std::wstring& Text) +{ + text_ += Text; +} +void svg_title::add_space(const std::wstring& Text) +{ + text_ += Text; +} +// svg:desc +//--------------------------------------------------------------------------------------- + const wchar_t * svg_desc::ns = L"svg"; const wchar_t * svg_desc::name = L"desc"; +void svg_desc::docx_convert(oox::docx_conversion_context& Context) +{ + odf_reader::draw_frame* current_frame = Context.get_drawing_context().get_current_frame(); + + if (current_frame && current_frame->oox_drawing_) + { + current_frame->oox_drawing_->additional.push_back(odf_reader::_property(L"svg:desc", text_)); + } +} + std::wostream & svg_desc::text_to_stream(std::wostream & _Wostream, bool bXmlEncode) const { _Wostream << text_ ; diff --git a/OdfFile/Reader/Format/font_face.h b/OdfFile/Reader/Format/font_face.h index 5c78d56b4bd..7ff84f9b132 100644 --- a/OdfFile/Reader/Format/font_face.h +++ b/OdfFile/Reader/Format/font_face.h @@ -78,6 +78,31 @@ class svg_font_face_uri : public office_element_impl }; CP_REGISTER_OFFICE_ELEMENT2(svg_font_face_uri); +// svg:title +class svg_title : public office_element_impl +{ +public: + static const wchar_t* ns; + static const wchar_t* name; + static const xml::NodeType xml_type = xml::typeElement; + static const ElementType type = typeSvgTitle; + + CPDOCCORE_DEFINE_VISITABLE(); + + void docx_convert(oox::docx_conversion_context& Context); + + virtual std::wostream& text_to_stream(std::wostream& _Wostream, bool bXmlEncode = true) const; + + std::wstring text_; + +private: + virtual void add_attributes(const xml::attributes_wc_ptr& Attributes) {} + virtual void add_child_element(xml::sax* Reader, const std::wstring& Ns, const std::wstring& Name) {} + virtual void add_text(const std::wstring& Text); + virtual void add_space(const std::wstring& Text); +}; +CP_REGISTER_OFFICE_ELEMENT2(svg_title); + // svg:desc class svg_desc : public office_element_impl { @@ -89,6 +114,8 @@ class svg_desc : public office_element_impl CPDOCCORE_DEFINE_VISITABLE(); + void docx_convert(oox::docx_conversion_context& Context); + virtual std::wostream & text_to_stream(std::wostream & _Wostream, bool bXmlEncode = true) const; std::wstring text_; diff --git a/OdfFile/Reader/Format/list.h b/OdfFile/Reader/Format/list.h index 721b841d886..58a2b47593b 100644 --- a/OdfFile/Reader/Format/list.h +++ b/OdfFile/Reader/Format/list.h @@ -67,10 +67,6 @@ CP_REGISTER_OFFICE_ELEMENT2(number); // text:list-item ////////////////////////////////////////////////////////////////////////////////////////////////// -class list_item; -typedef shared_ptr::Type list_item_ptr; -typedef std::vector list_item_ptr_array; - class list_item : public office_element_impl { public: @@ -102,9 +98,6 @@ CP_REGISTER_OFFICE_ELEMENT2(list_item); // text:list-header ////////////////////////////////////////////////////////////////////////////////////////////////// -class list_header; -typedef shared_ptr::Type list_header_ptr; - class list_header : public office_element_impl { public: diff --git a/OdfFile/Reader/Format/math_elements.cpp b/OdfFile/Reader/Format/math_elements.cpp index 7e68a62abf0..20117ce141e 100644 --- a/OdfFile/Reader/Format/math_elements.cpp +++ b/OdfFile/Reader/Format/math_elements.cpp @@ -31,6 +31,7 @@ */ #include "math_elements.h" +#include "../Converter/StarMath2OOXML/cconversionsmtoooxml.h" namespace cpdoccore { @@ -61,12 +62,12 @@ void office_math::add_child_element( xml::sax * Reader, const std::wstring & Ns, } -void office_math::oox_convert(oox::math_context & Context) +void office_math::oox_convert(oox::math_context & Context, int iTypeConversion) { if (semantics_) { office_math_element* math_element = dynamic_cast(semantics_.get()); - math_element->oox_convert(Context); + math_element->oox_convert(Context,iTypeConversion); } } @@ -93,10 +94,51 @@ void math_semantics::add_child_element( xml::sax * Reader, const std::wstring & void math_semantics::oox_convert(oox::math_context & Context) { - for (size_t i = 0 ; i < content_.size(); i++) + this->oox_convert(Context,0); +} +void math_semantics::oox_convert(oox::math_context &Context, int iTypeConversion) +{ + math_annotation* annotation = dynamic_cast(annotation_.get()); + math_annotation_xml* annotation_xml = dynamic_cast(annotation_.get()); + + std::wstring annotation_text; + if ((annotation) && (annotation->text_)) annotation_text = *annotation->text_; + else if ((annotation_xml) && (annotation_xml->text_)) annotation_text = *annotation_xml->text_; + + bool result = false; + if (!annotation_text.empty()) + { + result = true; + StarMath::CParserStarMathString parser; + StarMath::CConversionSMtoOOXML converter; + + parser.SetBaseFont(Context.base_font_name_); + parser.SetBaseSize(Context.base_font_size_); + parser.SetBaseAlignment(Context.base_alignment_); + parser.SetBaseItalic(Context.base_font_italic_); + parser.SetBaseBold(Context.base_font_bold_); + + /*result = */ converter.StartConversion(parser.Parse(annotation_text,iTypeConversion),parser.GetAlignment()); + + auto sizes = parser.GetFormulaSize(); + + for (;!sizes.empty(); sizes.pop()) + { + if (sizes.front().m_iWidth > Context.width) + Context.width = sizes.front().m_iWidth; + + Context.height += sizes.front().m_iHeight; + } + Context.output_stream() << converter.GetOOXML(); + } + + if (!result) { - office_math_element* math_element = dynamic_cast(content_[i].get()); - math_element->oox_convert(Context); + for (size_t i = 0; i < content_.size(); i++) + { + office_math_element* math_element = dynamic_cast(content_[i].get()); + math_element->oox_convert(Context); + } } } @@ -126,11 +168,6 @@ void math_annotation::add_text(const std::wstring & Text) text_ = Text; } -void math_annotation::oox_convert(oox::math_context & Context) -{ - -} - //---------------------------------------------------------------------------------------------------- const wchar_t * math_annotation_xml::ns = L"math"; const wchar_t * math_annotation_xml::name = L"annotation-xml"; @@ -157,10 +194,6 @@ void math_annotation_xml::add_text(const std::wstring & Text) text_ = Text; } -void math_annotation_xml::oox_convert(oox::math_context & Context) -{ - -} //---------------------------------------------------------------------------------------------------- } diff --git a/OdfFile/Reader/Format/math_elements.h b/OdfFile/Reader/Format/math_elements.h index e7691fa0d5a..077f6240414 100644 --- a/OdfFile/Reader/Format/math_elements.h +++ b/OdfFile/Reader/Format/math_elements.h @@ -55,6 +55,7 @@ class office_math_element : public office_element_impl virtual void pptx_convert (oox::pptx_conversion_context & Context) {} virtual void oox_convert (oox::math_context & Context) = 0; + virtual void oox_convert (oox::math_context &Context, int iTypeConversion) {oox_convert(Context);} CPDOCCORE_DEFINE_VISITABLE(); friend class odf_document; @@ -73,7 +74,7 @@ class office_math : public office_element_impl virtual void xlsx_convert (oox::xlsx_conversion_context & Context){} virtual void pptx_convert (oox::pptx_conversion_context & Context){} - void oox_convert (oox::math_context & Context); + void oox_convert (oox::math_context & Context,int iTypeConversion = 0); CPDOCCORE_DEFINE_VISITABLE(); friend class odf_document; @@ -98,6 +99,7 @@ class math_semantics : public office_math_element static const ElementType type = typeMathSemantics; virtual void oox_convert(oox::math_context & Context); + virtual void oox_convert(oox::math_context & Context, int iTypeConversion); private: virtual void add_attributes( const xml::attributes_wc_ptr & Attributes ); @@ -119,16 +121,16 @@ class math_annotation : public office_math_element static const xml::NodeType xml_type = xml::typeElement; static const ElementType type = typeMathAnnotation; - virtual void oox_convert(oox::math_context & Context); + virtual void oox_convert(oox::math_context& Context) {} + _CP_OPT(std::wstring) text_; private: virtual void add_attributes( const xml::attributes_wc_ptr & Attributes ); virtual void add_child_element( xml::sax * Reader, const std::wstring & Ns, const std::wstring & Name); virtual void add_text(const std::wstring & Text); - office_element_ptr_array content_; - _CP_OPT(std::wstring) text_; - _CP_OPT(std::wstring) encoding_; + office_element_ptr_array content_; + _CP_OPT(std::wstring) encoding_; }; CP_REGISTER_OFFICE_ELEMENT2(math_annotation); @@ -142,15 +144,15 @@ class math_annotation_xml : public office_math_element static const xml::NodeType xml_type = xml::typeElement; static const ElementType type = typeMathAnnotationXml; - virtual void oox_convert(oox::math_context & Context); + virtual void oox_convert(oox::math_context& Context) {} + _CP_OPT(std::wstring) text_; private: virtual void add_attributes( const xml::attributes_wc_ptr & Attributes ); virtual void add_child_element( xml::sax * Reader, const std::wstring & Ns, const std::wstring & Name); virtual void add_text(const std::wstring & Text); office_element_ptr_array content_; - _CP_OPT(std::wstring) text_; _CP_OPT(std::wstring) encoding_; }; diff --git a/OdfFile/Reader/Format/odf_document_impl.cpp b/OdfFile/Reader/Format/odf_document_impl.cpp index 953fc32f61a..934edc118fb 100644 --- a/OdfFile/Reader/Format/odf_document_impl.cpp +++ b/OdfFile/Reader/Format/odf_document_impl.cpp @@ -50,6 +50,7 @@ #include "office_text.h" #include "office_spreadsheet.h" #include "office_presentation.h" +#include "office_drawing.h" #include "office_chart.h" #include "office_annotation.h" #include "office_settings.h" @@ -61,6 +62,7 @@ #include "styles.h" #include "style_regions.h" #include "style_presentation.h" +#include "style_paragraph_properties.h" #include "templates.h" @@ -540,6 +542,10 @@ int odf_document::Impl::GetMimetype(std::wstring value) { return 6; } + else if (std::wstring::npos != value.find(L"application/vnd.oasis.opendocument.graphics")) + { + return 7; + } return 0; } void odf_document::Impl::parse_manifests(office_element *element) @@ -613,6 +619,8 @@ void odf_document::Impl::parse_settings(office_element *element) { if (conf_item_set->config_name_ == L"ModifyPasswordInfo") { + context_->Settings().add(L"modifyPasswordInfo", L""); + for (auto info_elm = conf_item_set->content_.begin(); info_elm != conf_item_set->content_.end(); ++info_elm) { settings_config_item *info = dynamic_cast(info_elm->get()); @@ -622,6 +630,19 @@ void odf_document::Impl::parse_settings(office_element *element) } } } + else if (conf_item_set->config_name_ == L"OOXMLModifyPasswordInfo") + { + context_->Settings().add(L"modifyPasswordInfo", L""); + + for (auto info_elm = conf_item_set->content_.begin(); info_elm != conf_item_set->content_.end(); ++info_elm) + { + settings_config_item* info = dynamic_cast(info_elm->get()); + if (info) + { + context_->Settings().add(L"modify:" + info->config_name_, info->content_); + } + } + } } } @@ -885,6 +906,16 @@ void odf_document::Impl::parse_styles(office_element *element) continue; } + if (styleInst->content_.style_family_.get_type() == odf_types::style_family::Paragraph) + { + style_paragraph_properties* para_props = styleInst->content_.get_style_paragraph_properties(); + + if (para_props && para_props->content_.style_tab_stop_distance_) + { + context_->Settings().set_tab_distance(para_props->content_.style_tab_stop_distance_->get_value_unit(odf_types::length::pt)); + } + } + context_->styleContainer().add_style(L"", L"", &(styleInst->content_), diff --git a/OdfFile/Reader/Format/odfcontext.cpp b/OdfFile/Reader/Format/odfcontext.cpp index 45cfde2b040..833815e0e0a 100644 --- a/OdfFile/Reader/Format/odfcontext.cpp +++ b/OdfFile/Reader/Format/odfcontext.cpp @@ -32,14 +32,14 @@ #include "odfcontext.h" -namespace cpdoccore { +namespace cpdoccore { using namespace odf_types; - - std::string DecodeBase64(const std::wstring & value1) + + std::string DecodeBase64(const std::wstring& value1) { int nLength = 0; - unsigned char *pData = NULL; + unsigned char* pData = NULL; std::string result; std::string value(value1.begin(), value1.end()); @@ -48,641 +48,623 @@ namespace cpdoccore { if (pData) { result = std::string((char*)pData, nLength); - delete []pData; pData = NULL; + delete[]pData; pData = NULL; } return result; } -namespace odf_reader { - -style_instance::style_instance( - styles_container *Container, - const std::wstring &Name, - const std::wstring &DisplayName, - style_family::type Type, - style_content *Content, - bool IsAutomatic, - bool IsDefault, - const std::wstring & ParentStyleName, - const std::wstring & NextStyleName, - const std::wstring & DataStyleName, - const std::wstring & PercentageDataStyleName, - const std::wstring & StyleClass, - _CP_OPT(std::wstring) ListStyleName, - _CP_OPT(int) ListLevel, - _CP_OPT(int) OutlineLevel - ) : - container_ (Container), - name_ (Name), - display_name_ (DisplayName), - style_type_ (Type), - content_ (Content), - is_automatic_ (IsAutomatic), - is_default_ (IsDefault), - next_name_ (NextStyleName), - style_class_ (StyleClass), - next_ (Container->style_by_name(NextStyleName, style_type_, false)), - data_style_name_(DataStyleName), - percentage_data_style_name_(PercentageDataStyleName), - list_style_name_(ListStyleName), - list_level_ (ListLevel), - outline_level_ (OutlineLevel) -{ - parent_name_ = ParentStyleName; - if (parent_name_ == L"Textformatvorlage")//http://ask.libreoffice.org/en/question/35136/textformatvorlage-style/ - { - parent_name_ = L"Standard"; - } - parent_ = Container->style_by_name(parent_name_, style_type_, false); -} - -style_instance * styles_container::hyperlink_style() -{ - if (hyperlink_style_pos_ > 0 && hyperlink_style_pos_ < (int)instances_.size()) - return instances_[hyperlink_style_pos_].get(); - else - return NULL; -} + namespace odf_reader { + + style_instance::style_instance( + styles_container* Container, + const std::wstring& Name, + const std::wstring& DisplayName, + style_family::type Type, + style_content* Content, + bool IsAutomatic, + bool IsDefault, + const std::wstring& ParentStyleName, + const std::wstring& NextStyleName, + const std::wstring& DataStyleName, + const std::wstring& PercentageDataStyleName, + const std::wstring& StyleClass, + _CP_OPT(std::wstring) ListStyleName, + _CP_OPT(int) ListLevel, + _CP_OPT(int) OutlineLevel + ) : + container_(Container), + name_(Name), + display_name_(DisplayName), + style_type_(Type), + content_(Content), + is_automatic_(IsAutomatic), + is_default_(IsDefault), + next_name_(NextStyleName), + style_class_(StyleClass), + next_(Container->style_by_name(NextStyleName, style_type_, false)), + data_style_name_(DataStyleName), + percentage_data_style_name_(PercentageDataStyleName), + list_style_name_(ListStyleName), + list_level_(ListLevel), + outline_level_(OutlineLevel) + { + parent_name_ = ParentStyleName; + if (parent_name_ == L"Textformatvorlage")//http://ask.libreoffice.org/en/question/35136/textformatvorlage-style/ + { + parent_name_ = L"Standard"; + } + parent_ = Container->style_by_name(parent_name_, style_type_, false); + } -void styles_container::add_style( const std::wstring & Name, - const std::wstring & DisplayName, - style_content * Content, - bool IsAutomatic, - bool IsDefault, - const std::wstring & ParentStyleName_, - const std::wstring & NextStyleName, - const std::wstring & DataStyleName, - const std::wstring & PercentageDataStyleName, - const std::wstring & StyleClass, - _CP_OPT(std::wstring) ListStyleName, - _CP_OPT(int) ListLevel, - _CP_OPT(int) OutlineLevel) -{ - std::wstring ParentStyleName = ParentStyleName_; - - style_family::type Type = Content ? Content->style_family_.get_type() : style_family::None; - - if (Name == ParentStyleName) - { - ParentStyleName = L"";//иначе в коде возможно зацикливание. - } - style_instance_ptr newStyle = style_instance_ptr( new style_instance(this, Name, DisplayName, Type, Content, IsAutomatic, IsDefault, - ParentStyleName, NextStyleName, DataStyleName, PercentageDataStyleName, StyleClass, ListStyleName, ListLevel, OutlineLevel)); - - instances_.push_back(newStyle); - int pos = static_cast(instances_.size() - 1); - - if (!Name.empty()) - { - std::wstring n = Name + L":" + boost::lexical_cast( style_family(Type) ); - map_[n] = pos; - - // TODO: как правильно?? - std::wstring lName = XmlUtils::GetLower(Name); - //if ( boost::algorithm::contains(lName, L"internet_20_link") ) - if (lName == L"internet_20_link")///??????????????? - hyperlink_style_pos_ = pos; - } - - if (!DisplayName.empty()) - { - std::wstring n = DisplayName + L":" + boost::lexical_cast( style_family(Type) ); - map2_[n] = pos; - } + style_instance* styles_container::hyperlink_style() + { + if (hyperlink_style_pos_ > 0 && hyperlink_style_pos_ < (int)instances_.size()) + return instances_[hyperlink_style_pos_].get(); + else + return NULL; + } - if (IsDefault) - default_map_[Type] = pos; - -} + void styles_container::add_style(const std::wstring& Name, + const std::wstring& DisplayName, + style_content* Content, + bool IsAutomatic, + bool IsDefault, + const std::wstring& ParentStyleName_, + const std::wstring& NextStyleName, + const std::wstring& DataStyleName, + const std::wstring& PercentageDataStyleName, + const std::wstring& StyleClass, + _CP_OPT(std::wstring) ListStyleName, + _CP_OPT(int) ListLevel, + _CP_OPT(int) OutlineLevel) + { + std::wstring ParentStyleName = ParentStyleName_; -const std::wstring & style_instance::name() const -{ - return name_; -} -const std::wstring & style_instance::display_name() const -{ - return display_name_; -} -style_family::type style_instance::type() const -{ - return style_type_; -} + style_family::type Type = Content ? Content->style_family_.get_type() : style_family::None; -style_content * style_instance::content() const -{ - return content_; -} + if (Name == ParentStyleName) + { + ParentStyleName = L"";//иначе в коде возможно зацикливание. + } + style_instance_ptr newStyle = style_instance_ptr(new style_instance(this, Name, DisplayName, Type, Content, IsAutomatic, IsDefault, + ParentStyleName, NextStyleName, DataStyleName, PercentageDataStyleName, StyleClass, ListStyleName, ListLevel, OutlineLevel)); -style_instance * style_instance::parent() const -{ - if (parent_) - return parent_; - else if (container_) - parent_ = container_->style_by_name(parent_name_, type(), false); - - return parent_; -} + instances_.push_back(newStyle); + int pos = static_cast(instances_.size() - 1); -const std::wstring & style_instance::parent_name() const -{ - return parent_name_; -} + if (!Name.empty()) + { + std::wstring n = Name + L":" + boost::lexical_cast(style_family(Type)); + map_[n] = pos; -style_instance * style_instance::next() const -{ - if (next_) - return next_; - else if (container_ && next_name_.empty() == false) - next_ = container_->style_by_name(next_name_, type(), false); - - return next_; -} + // TODO: как правильно?? + std::wstring lName = XmlUtils::GetLower(Name); + //if ( boost::algorithm::contains(lName, L"internet_20_link") ) + if (lName == L"internet_20_link")///??????????????? + hyperlink_style_pos_ = pos; + } -const std::wstring & style_instance::next_name() const -{ - return next_name_; -} + if (!DisplayName.empty()) + { + std::wstring n = DisplayName + L":" + boost::lexical_cast(style_family(Type)); + map2_[n] = pos; + } -bool style_instance::is_automatic() const -{ - return is_automatic_; -} + if (IsDefault) + default_map_[Type] = pos; -bool style_instance::is_default() const -{ - return is_default_; -} -const std::wstring & style_instance::percentage_data_style_name() const -{ - return percentage_data_style_name_; -} -const std::wstring & style_instance::data_style_name() const -{ - return data_style_name_; -} -_CP_OPT(std::wstring) style_instance::list_style_name() const -{ - return list_style_name_; -} -const std::wstring & style_instance::style_class() const -{ - return style_class_; -} -_CP_OPT(int) style_instance::list_level() const -{ - return list_level_; -} -_CP_OPT(int) style_instance::outline_level() const -{ - return outline_level_; -} + } -style_instance * styles_container::style_by_name(const std::wstring & Name, style_family::type Type, bool object_in_styles) const -{ - std::wstring n = L""; - if (object_in_styles) n = L"common:"; - n = n + Name + L":" + boost::lexical_cast( style_family(Type) ); - - map_wstring_int_t::const_iterator res = map_.find(n); - - if (res != map_.end()) - { - int index = res->second; - return instances_[index].get(); - } - else if (object_in_styles) - { - //try automatic - n = Name + L":" + boost::lexical_cast( style_family(Type) ); - - map_wstring_int_t::const_iterator res = map_.find(n); - - if (res != map_.end()) + const std::wstring& style_instance::name() const { - int index = res->second; - return instances_[index].get(); + return name_; + } + const std::wstring& style_instance::display_name() const + { + return display_name_; + } + style_family::type style_instance::type() const + { + return style_type_; } - } - return NULL; -} -style_instance * styles_container::style_by_display_name(const std::wstring & Name, style_family::type Type, bool object_in_styles) const -{ - std::wstring n = L""; - if (object_in_styles) n = L"common:"; - n = n + Name + L":" + boost::lexical_cast( style_family(Type) ); - - map_wstring_int_t::const_iterator res = map2_.find(n); - - if (res != map2_.end()) - { - int index = res->second; - return instances_[index].get(); - } - else - return NULL; -} -void styles_container::add_master_page_name(const std::wstring & StyleName, const std::wstring & MasterPageName) -{ - master_page_name_[StyleName] = MasterPageName; -} -std::pair presentation_layouts_instance::add_or_find(const std::wstring & layout_name,const std::wstring & master_name) -{ - bool find = false; - size_t index =0; - - for (index = 0; index < content.size(); index++) - { - if (content[index].layout_name == layout_name && content[index].master_name == master_name) + style_content* style_instance::content() const { - find = true; - break; + return content_; } - } - if (!find) - { - presentation_layouts_instance::_layout item; - item.layout_name = layout_name; - item.master_name = master_name; - item.Id = content.size() +1; - item.rId = std::wstring(L"lrId") + std::to_wstring(item.Id); - - content.push_back(item); - index = content.size()-1; - } - return std::pair(content[index].Id,content[index].rId); -} + style_instance* style_instance::parent() const + { + if (parent_) + return parent_; + else if (container_) + parent_ = container_->style_by_name(parent_name_, type(), false); -std::pair presentation_masters_instance::add_or_find(const std::wstring & master_name) -{ - bool find = false; - size_t index =0; - for (index = 0; index < content.size(); index++) - { - if (content[index].master_name == master_name) + return parent_; + } + + const std::wstring& style_instance::parent_name() const { - find = true; - break; + return parent_name_; } - } - if (!find) - { - presentation_masters_instance::_master item; - item.master_name = master_name; - item.Id = content.size() +1; - item.rId = std::wstring(L"smId") + std::to_wstring(item.Id); - - content.push_back(item); - index = content.size()-1; - } - return std::pair(content[index].Id,content[index].rId); -} + style_instance* style_instance::next() const + { + if (next_) + return next_; + else if (container_ && next_name_.empty() == false) + next_ = container_->style_by_name(next_name_, type(), false); -void presentation_masters_instance::add_layout_to(const std::wstring & master_name, presentation_layouts_instance::_layout & layout) -{ - bool find = false; - size_t index = 0; - for (index = 0; index < content.size(); index++) - { - if (content[index].master_name == master_name) + return next_; + } + + const std::wstring& style_instance::next_name() const { - find = true; - break; + return next_name_; } - } - if (find) - { - content[index].layouts.push_back(layout); - } -} -const _CP_OPT(std::wstring) styles_container::master_page_name_by_name(const std::wstring & StyleName) const -{ - _CP_OPT(std::wstring) master_page; + bool style_instance::is_automatic() const + { + return is_automatic_; + } - map_wstring_wstring::const_iterator res = master_page_name_.find(StyleName); - if (res != master_page_name_.end()) - master_page = res->second; - return master_page; -} + bool style_instance::is_default() const + { + return is_default_; + } + const std::wstring& style_instance::percentage_data_style_name() const + { + return percentage_data_style_name_; + } + const std::wstring& style_instance::data_style_name() const + { + return data_style_name_; + } + _CP_OPT(std::wstring) style_instance::list_style_name() const + { + return list_style_name_; + } + const std::wstring& style_instance::style_class() const + { + return style_class_; + } + _CP_OPT(int) style_instance::list_level() const + { + return list_level_; + } + _CP_OPT(int) style_instance::outline_level() const + { + return outline_level_; + } -style_instance * styles_container::style_default_by_type(style_family::type Type) const -{ - map_style_family_int::const_iterator res = default_map_.find(Type); - if (res != default_map_.end()) - return instances_[res->second].get(); - else - return NULL; -} + style_instance* styles_container::style_by_name(const std::wstring& Name, style_family::type Type, bool object_in_styles) const + { + std::wstring n = L""; + if (object_in_styles) n = L"common:"; + n = n + Name + L":" + boost::lexical_cast(style_family(Type)); + + map_wstring_int_t::const_iterator res = map_.find(n); + + if (res != map_.end()) + { + int index = res->second; + return instances_[index].get(); + } + else if (object_in_styles) + { + //try automatic + n = Name + L":" + boost::lexical_cast(style_family(Type)); + + map_wstring_int_t::const_iterator res = map_.find(n); + + if (res != map_.end()) + { + int index = res->second; + return instances_[index].get(); + } + } + return NULL; + } + style_instance* styles_container::style_by_display_name(const std::wstring& Name, style_family::type Type, bool object_in_styles) const + { + std::wstring n = L""; + if (object_in_styles) n = L"common:"; + n = n + Name + L":" + boost::lexical_cast(style_family(Type)); + + map_wstring_int_t::const_iterator res = map2_.find(n); + + if (res != map2_.end()) + { + int index = res->second; + return instances_[index].get(); + } + else + return NULL; + } + void styles_container::add_master_page_name(const std::wstring& StyleName, const std::wstring& MasterPageName) + { + master_page_name_[StyleName] = MasterPageName; + } -page_layout_instance::page_layout_instance(const style_page_layout * StylePageLayout) : style_page_layout_(StylePageLayout) -{ -} + std::pair presentation_layouts_instance::add_or_find(const std::wstring& layout_name, const std::wstring& master_name) + { + std::map::iterator pFind = mapUsed.find(master_name + layout_name); + + if (pFind == mapUsed.end()) + { + presentation_layouts_instance::_layout item; + item.layout_name = layout_name; + item.master_name = master_name; + item.Id = content.size() + 1; + item.rId = std::wstring(L"lrId") + std::to_wstring(item.Id); + + content.push_back(item); + + mapUsed.insert(std::make_pair(master_name + layout_name, content.size() - 1)); + return std::pair(item.Id, item.rId); + } + else + { + return std::pair(content[pFind->second].Id, content[pFind->second].rId); + } + } -const std::wstring & page_layout_instance::name() const -{ - return style_page_layout_->style_name_; -} + std::pair presentation_masters_instance::add_or_find(const std::wstring& master_name) + { + std::map::iterator pFind = mapUsed.find(master_name); + + if (pFind == mapUsed.end()) + { + presentation_masters_instance::_master item; + item.master_name = master_name; + item.Id = content.size() + 1; + item.rId = std::wstring(L"smId") + std::to_wstring(item.Id); + + content.push_back(item); + + mapUsed.insert(std::make_pair(master_name, content.size() - 1)); + return std::pair(item.Id, item.rId); + } + else + { + return std::pair(content[pFind->second].Id, content[pFind->second].rId); + } + } -style_page_layout_properties * page_layout_instance::properties() const -{ - return dynamic_cast(style_page_layout_->style_page_layout_properties_.get()); -} + void presentation_masters_instance::add_layout_to(const std::wstring& master_name, presentation_layouts_instance::_layout& layout) + { + std::map::iterator pFind = mapUsed.find(master_name); -void page_layout_instance::xlsx_serialize(std::wostream & strm, oox::xlsx_conversion_context & Context) -{ - const style_header_style * headerStyle = dynamic_cast(style_page_layout_->style_header_style_.get()); - const style_footer_style * footerStyle = dynamic_cast(style_page_layout_->style_footer_style_.get()); - - style_header_footer_properties * headerProp = headerStyle ? dynamic_cast(headerStyle->style_header_footer_properties_.get()) : NULL; - style_header_footer_properties * footerProp = footerStyle ? dynamic_cast(footerStyle->style_header_footer_properties_.get()) : NULL; - - if (headerProp) - { - const style_header_footer_properties_attlist & attr = headerProp->style_header_footer_properties_attlist_; - _CP_OPT(double) header; - - if (attr.fo_min_height_) header = attr.fo_min_height_->get_value_unit(length::pt); - else if (attr.svg_height_) header = attr.svg_height_->get_value_unit(length::pt); - - Context.get_table_context().set_header_page(header); - } - - if (footerProp) - { - const style_header_footer_properties_attlist & attr = footerProp->style_header_footer_properties_attlist_; - _CP_OPT(double) footer; - - if (attr.fo_min_height_) footer = attr.fo_min_height_->get_value_unit(length::pt); - else if (attr.svg_height_) footer = attr.svg_height_->get_value_unit(length::pt); - - Context.get_table_context().set_footer_page(footer); - } - - style_page_layout_properties * props = properties(); - if (props) - props->xlsx_serialize(strm, Context); -} + if (pFind != mapUsed.end()) + { + content[pFind->second].layouts.push_back(layout); -void page_layout_instance::docx_serialize(std::wostream & strm, oox::docx_conversion_context & Context) -{ - const style_header_style * headerStyle = dynamic_cast(style_page_layout_->style_header_style_.get()); - const style_footer_style * footerStyle = dynamic_cast(style_page_layout_->style_footer_style_.get()); + } + } - style_header_footer_properties * headerProp = headerStyle ? dynamic_cast(headerStyle->style_header_footer_properties_.get()) : NULL; - style_header_footer_properties * footerProp = footerStyle ? dynamic_cast(footerStyle->style_header_footer_properties_.get()) : NULL; + const _CP_OPT(std::wstring) styles_container::master_page_name_by_name(const std::wstring& StyleName) const + { + _CP_OPT(std::wstring) master_page; - Context.get_header_footer_context().reset(); + map_wstring_wstring::const_iterator res = master_page_name_.find(StyleName); + if (res != master_page_name_.end()) + master_page = res->second; + return master_page; + } - if (headerProp) - { - const style_header_footer_properties_attlist & attr = headerProp->style_header_footer_properties_attlist_; - _CP_OPT(length) top = attr.fo_min_height_ ? attr.fo_min_height_ : attr.svg_height_; - Context.get_header_footer_context().set_header(top); - } + style_instance* styles_container::style_default_by_type(style_family::type Type) const + { + map_style_family_int::const_iterator res = default_map_.find(Type); + if (res != default_map_.end()) + return instances_[res->second].get(); + else + return NULL; + } - if (footerProp) - { - const style_header_footer_properties_attlist & attr = footerProp->style_header_footer_properties_attlist_; - _CP_OPT(length) bottom = attr.fo_min_height_ ? attr.fo_min_height_ : attr.svg_height_; - Context.get_header_footer_context().set_footer(bottom); - } + page_layout_instance::page_layout_instance(const style_page_layout* StylePageLayout) : style_page_layout_(StylePageLayout) + { + } - if ( style_page_layout_->style_page_usage_.get_type() == page_usage::Mirrored ) - { - Context.set_settings_property(odf_reader::_property(L"mirrorMargins",true)); - } - - style_page_layout_properties * props = properties(); - if (props) - props->docx_serialize(strm, Context); -} -void page_layout_instance::pptx_serialize(std::wostream & strm, oox::pptx_conversion_context & Context) -{ - style_page_layout_properties * props = properties(); - if (props) - props->pptx_serialize(strm, Context); -} + const std::wstring& page_layout_instance::name() const + { + return style_page_layout_->style_name_; + } -void page_layout_container::add_page_layout(const style_page_layout * StylePageLayout) -{ - page_layout_instance_ptr instance = page_layout_instance_ptr( new page_layout_instance(StylePageLayout) ); - instances_.push_back(instance); - const int pos = static_cast(instances_.size() - 1); - - page_layout_names_[ instance->name() ] = pos; + style_page_layout_properties* page_layout_instance::properties() const + { + return dynamic_cast(style_page_layout_->style_page_layout_properties_.get()); + } -} + void page_layout_instance::xlsx_serialize(std::wostream& strm, oox::xlsx_conversion_context& Context) + { + const style_header_style* headerStyle = dynamic_cast(style_page_layout_->style_header_style_.get()); + const style_footer_style* footerStyle = dynamic_cast(style_page_layout_->style_footer_style_.get()); -void page_layout_container::add_master_page(const std::wstring & StyleName, const std::wstring & PageLayoutName, style_master_page* MasterPage) -{ - master_page_names_array_.push_back(StyleName); - master_page_names_[StyleName] = PageLayoutName; - - master_pages_.push_back(MasterPage); - const int pos = static_cast(master_pages_.size() - 1); - master_page_names_2_[StyleName] = pos; -} + style_header_footer_properties* headerProp = headerStyle ? dynamic_cast(headerStyle->style_header_footer_properties_.get()) : NULL; + style_header_footer_properties* footerProp = footerStyle ? dynamic_cast(footerStyle->style_header_footer_properties_.get()) : NULL; -void page_layout_container::add_presentation_page_layout(const std::wstring & StyleName, style_presentation_page_layout* StylePageLayout) -{ - presentation_page_layouts_.push_back(StylePageLayout); - - const int pos = static_cast(presentation_page_layouts_.size() - 1); - presentation_page_layout_names_[ StyleName ] = pos; + if (headerProp) + { + const style_header_footer_properties_attlist& attr = headerProp->style_header_footer_properties_attlist_; + _CP_OPT(double) header; -} + if (attr.fo_min_height_) header = attr.fo_min_height_->get_value_unit(length::pt); + else if (attr.svg_height_) header = attr.svg_height_->get_value_unit(length::pt); + Context.get_table_context().set_header_page(header); + } -const std::wstring page_layout_container::page_layout_name_by_style(const std::wstring & StyleName) const -{ - if (master_page_names_.count(StyleName) > 0) - return master_page_names_.at(StyleName); - return L""; -} + if (footerProp) + { + const style_header_footer_properties_attlist& attr = footerProp->style_header_footer_properties_attlist_; + _CP_OPT(double) footer; -const page_layout_instance * page_layout_container::page_layout_by_style(const std::wstring & StyleName) const -{ - if (master_page_names_.count(StyleName) > 0) - if (page_layout_names_.count(master_page_names_.at(StyleName)) ) - return instances_[ page_layout_names_.at( master_page_names_.at(StyleName) ) ].get(); - return NULL; -} + if (attr.fo_min_height_) footer = attr.fo_min_height_->get_value_unit(length::pt); + else if (attr.svg_height_) footer = attr.svg_height_->get_value_unit(length::pt); -page_layout_instance * page_layout_container::page_layout_by_name(const std::wstring & Name) const -{ - if (page_layout_names_.count(Name)) - return instances_[ page_layout_names_.at( Name ) ].get(); - return NULL; -} + Context.get_table_context().set_footer_page(footer); + } -const page_layout_instance * page_layout_container::page_layout_first() const -{ - if (master_page_names_array_.empty()) - return NULL; + style_page_layout_properties* props = properties(); + if (props) + props->xlsx_serialize(strm, Context); + } - return page_layout_by_style(master_page_names_array_[0]); -} -bool page_layout_container::compare_page_properties(const std::wstring & master1, const std::wstring & master2) -{ - const page_layout_instance *page_layout1 = page_layout_by_style(master1); - const page_layout_instance *page_layout2 = page_layout_by_style(master2); + void page_layout_instance::docx_serialize(std::wostream& strm, oox::docx_conversion_context& Context) + { + const style_header_style* headerStyle = dynamic_cast(style_page_layout_->style_header_style_.get()); + const style_footer_style* footerStyle = dynamic_cast(style_page_layout_->style_footer_style_.get()); + + style_header_footer_properties* headerProp = headerStyle ? dynamic_cast(headerStyle->style_header_footer_properties_.get()) : NULL; + style_header_footer_properties* footerProp = footerStyle ? dynamic_cast(footerStyle->style_header_footer_properties_.get()) : NULL; + + Context.get_header_footer_context().reset(); + + if (headerProp) + { + const style_header_footer_properties_attlist& attr = headerProp->style_header_footer_properties_attlist_; + _CP_OPT(length) top = attr.fo_min_height_ ? attr.fo_min_height_ : attr.svg_height_; + Context.get_header_footer_context().set_header(top); + } + + if (footerProp) + { + const style_header_footer_properties_attlist& attr = footerProp->style_header_footer_properties_attlist_; + _CP_OPT(length) bottom = attr.fo_min_height_ ? attr.fo_min_height_ : attr.svg_height_; + Context.get_header_footer_context().set_footer(bottom); + } + + if (style_page_layout_->style_page_usage_.get_type() == page_usage::Mirrored) + { + Context.set_settings_property(odf_reader::_property(L"mirrorMargins", true)); + } + + style_page_layout_properties* props = properties(); + if (props) + props->docx_serialize(strm, Context); + } + void page_layout_instance::pptx_serialize(std::wostream& strm, oox::pptx_conversion_context& Context) + { + style_page_layout_properties* props = properties(); + if (props) + props->pptx_serialize(strm, Context); + } - if (!page_layout1 || !page_layout2) return true; - if (!page_layout1->style_page_layout_ || !page_layout1->style_page_layout_) return true; + void page_layout_container::add_page_layout(const style_page_layout* StylePageLayout) + { + page_layout_instance_ptr instance = page_layout_instance_ptr(new page_layout_instance(StylePageLayout)); + instances_.push_back(instance); + const int pos = static_cast(instances_.size() - 1); - style_page_layout_properties *props1 = dynamic_cast(page_layout1->style_page_layout_->style_page_layout_properties_.get()); - style_page_layout_properties *props2 = dynamic_cast(page_layout2->style_page_layout_->style_page_layout_properties_.get()); - - if (!props1 || !props2) return true; + page_layout_names_[instance->name()] = pos; - if (props1 == props2) return true; + } - return props1->attlist_.compare(props2->attlist_); -} + void page_layout_container::add_master_page(const std::wstring& StyleName, const std::wstring& PageLayoutName, style_master_page* MasterPage) + { + master_page_names_array_.push_back(StyleName); + master_page_names_[StyleName] = PageLayoutName; -style_presentation_page_layout * page_layout_container::presentation_page_layout_by_name(const std::wstring & Name) -{ - style_presentation_page_layout * res = NULL; + master_pages_.push_back(MasterPage); + const int pos = static_cast(master_pages_.size() - 1); + master_page_names_2_[StyleName] = pos; + } - if (presentation_page_layout_names_.count(Name)) - { - int ind = presentation_page_layout_names_.at( Name ) ; - res = presentation_page_layouts_[ind]; - } - - return res; -} -style_master_page * page_layout_container::master_page_by_name(const std::wstring & Name) -{ - style_master_page * res = NULL; - - if (master_page_names_2_.count(Name)) - res = master_pages_[ master_page_names_2_.at( Name ) ]; - - return res; -} + void page_layout_container::add_presentation_page_layout(const std::wstring& StyleName, style_presentation_page_layout* StylePageLayout) + { + presentation_page_layouts_.push_back(StylePageLayout); -font_instance::font_instance( const std::wstring & StyleName, - const std::wstring & Name, - const std::wstring & Charset, - const std::wstring & Family, - const std::wstring & Pitch, - const std::wstring & AltName) : style_name_(StyleName), name_(Name), charset_(Charset), family_(Family), pitch_(Pitch), alt_name_(AltName) -{} - -const std::wstring & font_instance::style_name() const -{ - return style_name_; -} + const int pos = static_cast(presentation_page_layouts_.size() - 1); + presentation_page_layout_names_[StyleName] = pos; + } -const std::wstring & font_instance::name() const -{ - return name_; -} -const std::wstring & font_instance::charset() const -{ - return charset_; -} + const std::wstring page_layout_container::page_layout_name_by_style(const std::wstring& StyleName) const + { + if (master_page_names_.count(StyleName) > 0) + return master_page_names_.at(StyleName); + return L""; + } -const std::wstring & font_instance::family() const -{ - return family_; -} + const page_layout_instance* page_layout_container::page_layout_by_style(const std::wstring& StyleName) const + { + if (master_page_names_.count(StyleName) > 0) + if (page_layout_names_.count(master_page_names_.at(StyleName))) + return instances_[page_layout_names_.at(master_page_names_.at(StyleName))].get(); + return NULL; + } -const std::wstring & font_instance::pitch() const -{ - return pitch_; -} + page_layout_instance* page_layout_container::page_layout_by_name(const std::wstring& Name) const + { + if (page_layout_names_.count(Name)) + return instances_[page_layout_names_.at(Name)].get(); + return NULL; + } -const std::wstring & font_instance::alt_name() const -{ - return alt_name_; -} + const page_layout_instance* page_layout_container::page_layout_first() const + { + if (master_page_names_array_.empty()) + return NULL; -font_instance * fonts_container::font_by_style_name(const std::wstring & StyleName) -{ - if (font_style_names_.count(StyleName) > 0) - return instances_[font_style_names_.at(StyleName)].get(); - return NULL; -} + return page_layout_by_style(master_page_names_array_[0]); + } + bool page_layout_container::compare_page_properties(const std::wstring& master1, const std::wstring& master2) + { + const page_layout_instance* page_layout1 = page_layout_by_style(master1); + const page_layout_instance* page_layout2 = page_layout_by_style(master2); -font_instance * fonts_container::font_by_name(const std::wstring & Name) -{ - if (font_names_.count(Name) > 0) - return instances_[font_names_.at(Name)].get(); - return NULL; -} + if (!page_layout1 || !page_layout2) return true; + if (!page_layout1->style_page_layout_ || !page_layout1->style_page_layout_) return true; -void fonts_container::add_font( font_instance_ptr FontInstance ) -{ - instances_.push_back(FontInstance); - if (FontInstance) - { - font_style_names_[FontInstance->style_name()] = static_cast(instances_.size() - 1); - font_names_[FontInstance->name()] = static_cast(instances_.size() - 1); - } -} + style_page_layout_properties* props1 = dynamic_cast(page_layout1->style_page_layout_->style_page_layout_properties_.get()); + style_page_layout_properties* props2 = dynamic_cast(page_layout2->style_page_layout_->style_page_layout_properties_.get()); -void list_style_container::add_list_style(text_list_style * textListStyle) -{ - if (!textListStyle) return; - - instances_.push_back( list_style_instance_ptr(new list_style_instance(textListStyle)) ); - list_style_names_[ textListStyle->attr_.style_name_ ] = static_cast(instances_.size() - 1); -} + if (!props1 || !props2) return true; -void list_style_container::add_list_style(text_list_style * textListStyle, const std::wstring & NewName) -{ - if (!textListStyle) return; + if (props1 == props2) return true; - instances_.push_back( list_style_instance_ptr(new list_style_instance(textListStyle, NewName)) ); - list_style_names_[NewName] = static_cast(instances_.size() - 1); -} -void list_style_container::add_outline_style(text_outline_style *textOutlineStyle) -{ - if (!textOutlineStyle) return; + return props1->attlist_.compare(props2->attlist_); + } - outline_ = textOutlineStyle; - outline_id_ = instances_.size(); -} -text_list_style * list_style_container::list_style_by_name(const std::wstring & Name) -{ - if (list_style_names_.count(Name) > 0) - return instances_[list_style_names_.at(Name)]->get_text_list_style(); - return NULL; -} + style_presentation_page_layout* page_layout_container::presentation_page_layout_by_name(const std::wstring& Name) + { + style_presentation_page_layout* res = NULL; -text_outline_style * list_style_container::outline_style() -{ - return outline_; -} -int list_style_container::id_outline() -{ - return outline_id_ + 1; -} + if (presentation_page_layout_names_.count(Name)) + { + int ind = presentation_page_layout_names_.at(Name); + res = presentation_page_layouts_[ind]; + } -int list_style_container::id_by_name(const std::wstring & Name) -{ - if (list_style_names_.count(Name) > 0) - return list_style_names_.at(Name) + 1; - else - return 0; -} -const text_notes_configuration * notes_configuration::getConfiguration(odf_types::noteclass::type noteType) const -{ - if (type_to_name_.count(noteType)) - return type_to_name_.at(noteType); - else - return NULL; -} + return res; + } + style_master_page* page_layout_container::master_page_by_name(const std::wstring& Name) + { + style_master_page* res = NULL; -void notes_configuration::add(odf_types::noteclass::type noteType, const text_notes_configuration * conf) -{ - type_to_name_[noteType] = conf; -} + if (master_page_names_2_.count(Name)) + res = master_pages_[master_page_names_2_.at(Name)]; -} + return res; + } + + font_instance::font_instance(const std::wstring& StyleName, + const std::wstring& Name, + const std::wstring& Charset, + const std::wstring& Family, + const std::wstring& Pitch, + const std::wstring& AltName) : style_name_(StyleName), name_(Name), charset_(Charset), family_(Family), pitch_(Pitch), alt_name_(AltName) + {} + + const std::wstring& font_instance::style_name() const + { + return style_name_; + } + + const std::wstring& font_instance::name() const + { + return name_; + } + + const std::wstring& font_instance::charset() const + { + return charset_; + } + + const std::wstring& font_instance::family() const + { + return family_; + } + + const std::wstring& font_instance::pitch() const + { + return pitch_; + } + + const std::wstring& font_instance::alt_name() const + { + return alt_name_; + } + + font_instance* fonts_container::font_by_style_name(const std::wstring& StyleName) + { + if (font_style_names_.count(StyleName) > 0) + return instances_[font_style_names_.at(StyleName)].get(); + return NULL; + } + + font_instance* fonts_container::font_by_name(const std::wstring& Name) + { + if (font_names_.count(Name) > 0) + return instances_[font_names_.at(Name)].get(); + return NULL; + } + + void fonts_container::add_font(font_instance_ptr FontInstance) + { + instances_.push_back(FontInstance); + if (FontInstance) + { + font_style_names_[FontInstance->style_name()] = static_cast(instances_.size() - 1); + font_names_[FontInstance->name()] = static_cast(instances_.size() - 1); + } + } + + void list_style_container::add_list_style(text_list_style* textListStyle) + { + if (!textListStyle) return; + + instances_.push_back(list_style_instance_ptr(new list_style_instance(textListStyle))); + list_style_names_[textListStyle->attr_.style_name_] = static_cast(instances_.size() - 1); + } + + void list_style_container::add_list_style(text_list_style* textListStyle, const std::wstring& NewName) + { + if (!textListStyle) return; + + instances_.push_back(list_style_instance_ptr(new list_style_instance(textListStyle, NewName))); + list_style_names_[NewName] = static_cast(instances_.size() - 1); + } + void list_style_container::add_outline_style(text_outline_style* textOutlineStyle) + { + if (!textOutlineStyle) return; + + outline_ = textOutlineStyle; + } + text_list_style* list_style_container::list_style_by_name(const std::wstring& Name) + { + if (list_style_names_.count(Name) > 0) + return instances_[list_style_names_.at(Name)]->get_text_list_style(); + return NULL; + } + + text_outline_style* list_style_container::outline_style() + { + return outline_; + } + int list_style_container::id_outline() + { + return instances_.size() + 1; + } + + int list_style_container::id_by_name(const std::wstring& Name) + { + if (list_style_names_.count(Name) > 0) + return list_style_names_.at(Name) + 1; + else + return 0; + } + const text_notes_configuration* notes_configuration::getConfiguration(odf_types::noteclass::type noteType) const + { + if (type_to_name_.count(noteType)) + return type_to_name_.at(noteType); + else + return NULL; + } + + void notes_configuration::add(odf_types::noteclass::type noteType, const text_notes_configuration* conf) + { + type_to_name_[noteType] = conf; + } + + } } diff --git a/OdfFile/Reader/Format/odfcontext.h b/OdfFile/Reader/Format/odfcontext.h index 82e6a55c65a..b480b55fe16 100644 --- a/OdfFile/Reader/Format/odfcontext.h +++ b/OdfFile/Reader/Format/odfcontext.h @@ -131,6 +131,8 @@ class presentation_layouts_instance }; std::vector<_layout> content; + std::map mapUsed; + std::pair add_or_find(const std::wstring & layout_name,const std::wstring & master_name); }; class presentation_masters_instance @@ -145,6 +147,7 @@ class presentation_masters_instance std::vector layouts; }; std::vector<_master> content; + std::map mapUsed; void add_layout_to(const std::wstring & master_name,presentation_layouts_instance::_layout & layout); @@ -238,9 +241,9 @@ class page_layout_container public: typedef std::vector instances_array; - void add_page_layout(const style_page_layout * StylePageLayout); - void add_master_page(const std::wstring & StyleName, const std::wstring & PageLayoutName,style_master_page* MasterPage); - void add_presentation_page_layout(const std::wstring & StyleName, style_presentation_page_layout* StylePageLayout); + void add_page_layout(const style_page_layout *stylePageLayout); + void add_master_page(const std::wstring & StyleName, const std::wstring & PageLayoutName, style_master_page* MasterPage); + void add_presentation_page_layout(const std::wstring & styleName, style_presentation_page_layout *stylePageLayout); const std::wstring page_layout_name_by_style(const std::wstring & StyleName) const; @@ -265,13 +268,13 @@ class page_layout_container instances_array instances_; std::vector master_pages_; - boost::unordered_map page_layout_names_; + std::map page_layout_names_; std::vector master_page_names_array_; - boost::unordered_map master_page_names_; + std::map master_page_names_; - boost::unordered_map master_page_names_2_; + std::map master_page_names_2_; - boost::unordered_map presentation_page_layout_names_; + std::map presentation_page_layout_names_; odf_reader::text_linenumbering_configuration *linenumberingcConfiguration = NULL; }; @@ -377,7 +380,6 @@ class list_style_container instances_array instances_; text_outline_style *outline_ = NULL; - int outline_id_ = 0; }; class notes_configuration diff --git a/OdfFile/Reader/Format/office_annotation.cpp b/OdfFile/Reader/Format/office_annotation.cpp index 6d6e4423344..06029b5fa78 100644 --- a/OdfFile/Reader/Format/office_annotation.cpp +++ b/OdfFile/Reader/Format/office_annotation.cpp @@ -185,13 +185,16 @@ void office_annotation::xlsx_convert(oox::xlsx_conversion_context & Context) { } - Context.get_text_context().start_comment_content(); + Context.start_text_context(); + Context.get_text_context()->start_comment_content(); for (size_t i = 0; i < content_.size(); i++)//текст + текстовый стиль { content_[i]->xlsx_convert(Context); } Context.get_comments_context().add_author(author); - Context.get_comments_context().add_content(Context.get_text_context().end_comment_content()); + Context.get_comments_context().add_content(Context.get_text_context()->end_comment_content()); + Context.end_text_context(); + //----------- drawing part --------------- Context.get_drawing_context().start_comment(col, row); Context.get_drawing_context().start_drawing(L""); diff --git a/OdfFile/Reader/Format/office_binary_data.cpp b/OdfFile/Reader/Format/office_binary_data.cpp index 94752673b7a..4538a028aed 100644 --- a/OdfFile/Reader/Format/office_binary_data.cpp +++ b/OdfFile/Reader/Format/office_binary_data.cpp @@ -31,14 +31,12 @@ */ #include "office_binary_data.h" - -#include +#include "../../../DesktopEditor/raster/ImageFileFormatChecker.h" +#include "../../../Common/OfficeFileFormatChecker.h" namespace cpdoccore { namespace odf_reader { - - // office:binary-data ////////////////////////////////////////////////////////////////////////////////////////////////// const wchar_t * office_binary_data::ns = L"office"; @@ -72,9 +70,24 @@ std::wstring office_binary_data::write_to(const std::wstring & path) NSFile::CBase64Converter::Decode(base64Binary_.c_str(), base64Binary_.length(), pData, nLength); if (pData) { + CImageFileFormatChecker image_checker; + std::wstring sExt = image_checker.DetectFormatByData(pData, nLength); + + if (sExt.empty()) + { + std::wstring documentID; + COfficeFileFormatChecker office_checker; + + if (office_checker.isPdfFormatFile(pData, nLength, documentID)) + { + type_binary_data = 20; // oox::_rels_type = typePDF; + sExt = L"pdf"; + } + } + NSFile::CFileBinary file; - std::wstring bin_file = file.CreateTempFileWithUniqueName(path + FILE_SEPARATOR_STR, L"bin"); + std::wstring bin_file = file.CreateTempFileWithUniqueName(path + FILE_SEPARATOR_STR, sExt); if (file.CreateFileW(bin_file)) { file.WriteFile(pData, nLength); diff --git a/OdfFile/Reader/Format/office_binary_data.h b/OdfFile/Reader/Format/office_binary_data.h index d3a18e1c7b2..42a3725598a 100644 --- a/OdfFile/Reader/Format/office_binary_data.h +++ b/OdfFile/Reader/Format/office_binary_data.h @@ -53,6 +53,7 @@ class office_binary_data : public office_element_impl virtual std::wostream & text_to_stream(std::wostream & _Wostream, bool bXmlEncode = true) const; std::wstring write_to(const std::wstring & path); + int type_binary_data = 2; //_rels_type type = Image; private: virtual void add_attributes( const xml::attributes_wc_ptr & Attributes ); virtual void add_child_element( xml::sax * Reader, const std::wstring & Ns, const std::wstring & Name); diff --git a/OdfFile/Reader/Format/office_drawing.cpp b/OdfFile/Reader/Format/office_drawing.cpp new file mode 100644 index 00000000000..572e074a731 --- /dev/null +++ b/OdfFile/Reader/Format/office_drawing.cpp @@ -0,0 +1,160 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ + + +#include "office_drawing.h" +#include "draw_page.h" + +#include +#include "odf_document.h" +#include "odfcontext.h" + +#include "serialize_elements.h" + +namespace cpdoccore { +namespace odf_reader { + +const wchar_t* office_drawing::ns = L"office"; +const wchar_t* office_drawing::name = L"drawing"; + +void office_drawing::add_child_element(xml::sax* Reader, const std::wstring& Ns, const std::wstring& Name) +{ + if CP_CHECK_NAME(L"draw", L"page") + { + CP_CREATE_ELEMENT(pages_); + } + else if CP_CHECK_NAME(L"table", L"tracked-changes") + { + CP_CREATE_ELEMENT(tracked_changes_); + } + else if CP_CHECK_NAME(L"table", L"content-validations") + { + CP_CREATE_ELEMENT(content_validations_); + } + else if CP_CHECK_NAME(L"presentation", L"footer-decl") + { + CP_CREATE_ELEMENT(footer_decls_); + } + else if CP_CHECK_NAME(L"presentation", L"date-time-decl") + { + CP_CREATE_ELEMENT(date_time_decls_); + } + else if CP_CHECK_NAME(L"text", L"user-field-decls") + { + CP_CREATE_ELEMENT(user_fields_); + } + else if CP_CHECK_NAME(L"text", L"sequence-decls") + { + CP_CREATE_ELEMENT(sequences_); + } + else if CP_CHECK_NAME(L"text", L"variable-decls") + { + CP_CREATE_ELEMENT(variables_); + } +} + +void office_drawing::add_text(const std::wstring& Text) +{ +} + +void office_drawing::add_attributes(const xml::attributes_wc_ptr& Attributes) +{ +} + +void office_drawing::docx_convert(oox::docx_conversion_context& Context) +{ + Context.start_office_text(); + _CP_LOG << L"[info][docx] process pages (" << pages_.size() << L" elmements)" << std::endl; + + for (size_t i = 0; i < pages_.size(); i++) + { + pages_[i]->docx_convert(Context); + } + Context.end_office_text(); +} + +void office_drawing::xlsx_convert(oox::xlsx_conversion_context& Context) +{ + Context.start_office_spreadsheet(this); + _CP_LOG << L"[info][xlsx] process pages (" << pages_.size() << L" elmements)" << std::endl; + + for (size_t i = 0; i < pages_.size(); i++) + { + pages_[i]->xlsx_convert(Context); + } + Context.end_office_spreadsheet(); +} + +void office_drawing::pptx_convert(oox::pptx_conversion_context& Context) +{ + Context.start_office_presentation(); + + _CP_LOG << L"[info][pptx] process pages(" << pages_.size() << L" elmements)" << std::endl; + + for (size_t i = 0; i < footer_decls_.size(); i++) + { + presentation_footer_decl* style = dynamic_cast(footer_decls_[i].get()); + + if (!style) + continue; + + std::wstring style_name_ = L"footer:" + style->presentation_name_.get_value_or(L""); + Context.root()->odf_context().drawStyles().add(style_name_, footer_decls_[i]); + } + for (size_t i = 0; i < date_time_decls_.size(); i++) + { + presentation_date_time_decl* style = dynamic_cast(date_time_decls_[i].get()); + + if (!style) + continue; + + std::wstring style_name_ = L"datetime:" + style->presentation_name_.get_value_or(L""); + Context.root()->odf_context().drawStyles().add(style_name_, date_time_decls_[i]); + } + if (user_fields_) + user_fields_->pptx_convert(Context); + + if (variables_) + variables_->pptx_convert(Context); + + if (sequences_) + sequences_->pptx_convert(Context); + + for (size_t i = 0; i < pages_.size(); i++) + { + pages_[i]->pptx_convert(Context); + } + Context.end_office_presentation(); +} + +} +} diff --git a/OdfFile/Reader/Format/office_drawing.h b/OdfFile/Reader/Format/office_drawing.h new file mode 100644 index 00000000000..cb76f595b01 --- /dev/null +++ b/OdfFile/Reader/Format/office_drawing.h @@ -0,0 +1,79 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#pragma once + +#include + +#include "office_elements.h" +#include "office_elements_create.h" + +namespace cpdoccore { +namespace odf_reader { + +class office_drawing : public office_element_impl +{ +public: + static const wchar_t* ns; + static const wchar_t* name; + static const xml::NodeType xml_type = xml::typeElement; + static const ElementType type = typeOfficeDrawing; + CPDOCCORE_DEFINE_VISITABLE(); + + virtual void docx_convert(oox::docx_conversion_context& Context); + virtual void xlsx_convert(oox::xlsx_conversion_context& Context); + virtual void pptx_convert(oox::pptx_conversion_context& Context); + +private: + virtual void add_attributes(const xml::attributes_wc_ptr& Attributes); + virtual void add_child_element(xml::sax* Reader, const std::wstring& Ns, const std::wstring& Name); + virtual void add_text(const std::wstring& Text); + +public: + + office_element_ptr tracked_changes_; + office_element_ptr content_validations_; + + office_element_ptr_array date_time_decls_; + office_element_ptr_array footer_decls_; + + office_element_ptr_array pages_; + + office_element_ptr user_fields_; + office_element_ptr variables_; + office_element_ptr sequences_; + +}; + +CP_REGISTER_OFFICE_ELEMENT2(office_drawing); + +} // namespace odf_reader +} // namespace cpdoccore diff --git a/OdfFile/Reader/Format/office_event_listeners.cpp b/OdfFile/Reader/Format/office_event_listeners.cpp index 793d5f894bc..8ea1b4fec6e 100644 --- a/OdfFile/Reader/Format/office_event_listeners.cpp +++ b/OdfFile/Reader/Format/office_event_listeners.cpp @@ -33,6 +33,8 @@ #include "office_event_listeners.h" #include "serialize_elements.h" +#include "boost/algorithm/string.hpp" + #include namespace cpdoccore { @@ -96,17 +98,42 @@ void presentation_event_listener::add_child_element( xml::sax * Reader, const st CP_NOT_APPLICABLE_ELM(); } void presentation_event_listener::pptx_convert(oox::pptx_conversion_context & Context) -{ - Context.get_slide_context().start_action(attlist_.presentation_action_.get_value_or(L"")); - +{ if (attlist_.xlink_attlist_.href_) - Context.get_slide_context().set_link(*attlist_.xlink_attlist_.href_); - - if (presentation_sound_) { - presentation_sound_->pptx_convert(Context); + std::wstring href = *attlist_.xlink_attlist_.href_; + if (boost::algorithm::starts_with(href, L"#")) + href = href.substr(1); // Remove '#' character + + const std::vector& page_names = Context.get_page_names(); + + bool found = false; + for (size_t i = 0; i < page_names.size(); i++) + { + if (href == page_names[i]) + { + std::wstring pptx_slide_name = L"slides/slide" + std::to_wstring(i + 1) + L".xml"; + + Context.get_slide_context().set_link(pptx_slide_name, oox::_rels_type::typeSlide); + found = true; + break; + } + } + + if (!found) + { + Context.get_slide_context().start_action(attlist_.presentation_action_.get_value_or(L"")); + + if (boost::algorithm::starts_with(href, L"../")) + href = href.substr(std::wstring(L"../").size()); + Context.get_slide_context().set_link(href, oox::_rels_type::typeHyperlink); + + if (presentation_sound_) + presentation_sound_->pptx_convert(Context); + + Context.get_slide_context().end_action(); + } } - Context.get_slide_context().end_action(); } // script:event-listener diff --git a/OdfFile/Reader/Format/office_forms.cpp b/OdfFile/Reader/Format/office_forms.cpp index b9c9a98e379..29b57596a8f 100644 --- a/OdfFile/Reader/Format/office_forms.cpp +++ b/OdfFile/Reader/Format/office_forms.cpp @@ -1221,5 +1221,188 @@ void form_item::add_text(const std::wstring & Text) text_ = Text; } +// loext:content-control +//---------------------------------------------------------------------------------- +const wchar_t* loext_content_control::ns = L"loext"; +const wchar_t* loext_content_control::name = L"content-control"; + +void loext_content_control::add_attributes(const xml::attributes_wc_ptr& Attributes) +{ + CP_APPLY_ATTR(L"loext:alias", alias); + CP_APPLY_ATTR(L"loext:tag", tag); + CP_APPLY_ATTR(L"loext:lock", lock); + CP_APPLY_ATTR(L"loext:showing-place-holder", showing_place_holder); + CP_APPLY_ATTR(L"loext:id", id); + CP_APPLY_ATTR(L"loext:tab-index", tab_index); + CP_APPLY_ATTR(L"loext:checked", checked); + CP_APPLY_ATTR(L"loext:checkedState", checked_state); + CP_APPLY_ATTR(L"loext:uncheckedState", unchecked_state); + CP_APPLY_ATTR(L"loext:date-format", date_format); + CP_APPLY_ATTR(L"loext:date-language", date_language); + CP_APPLY_ATTR(L"loext:current-date", current_date); + CP_APPLY_ATTR(L"loext:date-rfc-language-tag", date_rfc_language); + + CP_APPLY_ATTR(L"loext:checkbox", checkbox); + CP_APPLY_ATTR(L"loext:picture", picture); + CP_APPLY_ATTR(L"loext:date", date); + CP_APPLY_ATTR(L"loext:dropdown", dropdown); + CP_APPLY_ATTR(L"loext:combobox", combobox); + CP_APPLY_ATTR(L"loext:plain-text", plain_text); +} +void loext_content_control::add_text(const std::wstring& Text) +{ + text = Text; +} +void loext_content_control::add_child_element(xml::sax* Reader, const std::wstring& Ns, const std::wstring& Name) +{ + CP_CREATE_ELEMENT(content); +} +void loext_content_control::docx_convert(oox::docx_conversion_context& Context) +{ + office_element_ptr_array content_text; + + Context.finish_run(); + Context.output_stream() << L""; + Context.output_stream() << L""; + { + if (alias) + { + Context.output_stream() << L""; + } + + Context.output_stream() << L""; + + if (lock) + { + Context.output_stream() << L""; + } + if (tag) + { + Context.output_stream() << L""; + } + if (id) + { + Context.output_stream() << L""; + } + if (tab_index) + { + Context.output_stream() << L""; + } + if (showing_place_holder) + { + Context.output_stream() << L""; + } + +//---------------------- + if (plain_text) + { + Context.output_stream() << L""; + } + else if (picture) + { + Context.output_stream() << L""; + content_text = content; + } + else if (dropdown || combobox) + { + if (dropdown) Context.output_stream() << L""; + else if (combobox) Context.output_stream() << L""; + + for (size_t i = 0; i < content.size(); i++) + { + loext_list_item* item = dynamic_cast(content[i].get()); + if (item) + { + Context.output_stream() << L"display_text) + { + Context.output_stream() << L" w:displayText=\"" << XmlUtils::EncodeXmlString(*item->display_text) + L"\""; + } + if (item->value) + { + Context.output_stream() << L" w:value=\"" << XmlUtils::EncodeXmlString(*item->value) << L"\""; + } + Context.output_stream() << L"/>"; + } + else + { + content_text.push_back(content[i]); + } + } + if (dropdown) Context.output_stream() << L""; + else if (combobox) Context.output_stream() << L""; + } + else if (checkbox) + { + Context.output_stream() << L""; + Context.output_stream() << L"") : L"/>"); + if (checked_state) + { + Context.output_stream() << L""; + } + if (unchecked_state) + { + Context.output_stream() << L""; + } + Context.output_stream() << L""; + content_text = content; + } + else if (date) + { + Context.output_stream() << L"") : L">"); + if (date_format) + { + Context.output_stream() << L""; + } + if (date_rfc_language) + { + Context.output_stream() << L""; + } + //Context.output_stream() << L""; + Context.output_stream() << L""; + + Context.output_stream() << L""; + content_text = content; + } + } + Context.output_stream() << L""; + Context.output_stream() << L""; + { + if (false == content_text.empty()) + { + for (size_t i = 0; i < content_text.size(); i++) + { + content_text[i]->docx_convert(Context); + } + } + else + { + Context.add_new_run(L""); + Context.output_stream() << L""; + if (false == text.empty()) + { + Context.output_stream() << XmlUtils::EncodeXmlString(text); + } + else + { + Context.output_stream() << L"Select item"; + } + Context.output_stream() << L""; + Context.finish_run(); + } + } + Context.output_stream() << L""; + Context.output_stream() << L""; +} +// loext:list-item +//---------------------------------------------------------------------------------- +const wchar_t* loext_list_item::ns = L"loext"; +const wchar_t* loext_list_item::name = L"list-item"; + +void loext_list_item::add_attributes(const xml::attributes_wc_ptr& Attributes) +{ + CP_APPLY_ATTR(L"loext:display-text", display_text); + CP_APPLY_ATTR(L"loext:value", value); +} } } diff --git a/OdfFile/Reader/Format/office_forms.h b/OdfFile/Reader/Format/office_forms.h index 9acbca54386..0bddaeffc1a 100644 --- a/OdfFile/Reader/Format/office_forms.h +++ b/OdfFile/Reader/Format/office_forms.h @@ -628,8 +628,6 @@ class form_item : public office_element_impl std::wstring text_; }; CP_REGISTER_OFFICE_ELEMENT2(form_item); -} -} //7.6.2, // 13.5.5, // 13.5.6, @@ -639,3 +637,72 @@ CP_REGISTER_OFFICE_ELEMENT2(form_item); // 13.5.16, // 13.5.7, // 13.5.4, +//----------------------------------------------------------------------------------------- +//----------------------------------------------------------------------------------------- +//----------------------------------------------------------------------------------------- +//----------------------------------------------------------------------------------------- +//----------------------------------------------------------------------------------------- +// loext:content-control +class loext_content_control : public office_element_impl +{ +public: + static const wchar_t* ns; + static const wchar_t* name; + + static const xml::NodeType xml_type = xml::typeElement; + static const ElementType type = typeContentControl; + CPDOCCORE_DEFINE_VISITABLE(); + + virtual void docx_convert(oox::docx_conversion_context& Context); +private: + virtual void add_attributes(const xml::attributes_wc_ptr& Attributes); + virtual void add_child_element(xml::sax* Reader, const std::wstring& Ns, const std::wstring& Name); + virtual void add_text(const std::wstring& Text); +public: + _CP_OPT(std::wstring) alias; + _CP_OPT(std::wstring) tag; + _CP_OPT(std::wstring) lock; + _CP_OPT(bool) showing_place_holder; + _CP_OPT(int) id; + _CP_OPT(unsigned int) tab_index; + _CP_OPT(bool) checked; + _CP_OPT(std::wstring) checked_state; + _CP_OPT(std::wstring) unchecked_state; + _CP_OPT(std::wstring) date_format; + _CP_OPT(std::wstring) date_language; + _CP_OPT(std::wstring) current_date; + _CP_OPT(std::wstring) date_rfc_language; + + _CP_OPT(bool) checkbox; + _CP_OPT(bool) picture; + _CP_OPT(bool) date; + _CP_OPT(bool) dropdown; + _CP_OPT(bool) combobox; + _CP_OPT(bool) plain_text; + + std::wstring text; + office_element_ptr_array content; +}; +CP_REGISTER_OFFICE_ELEMENT2(loext_content_control); +//---------------------------------------------------------------------------------- +// loext:list-item +//---------------------------------------------------------------------------------- +class loext_list_item : public office_element_impl +{ +public: + static const wchar_t* ns; + static const wchar_t* name; + static const xml::NodeType xml_type = xml::typeElement; + static const ElementType type = typeListItem; + CPDOCCORE_DEFINE_VISITABLE(); + +private: + virtual void add_attributes(const xml::attributes_wc_ptr& Attributes); + virtual void add_child_element(xml::sax* Reader, const std::wstring& Ns, const std::wstring& Name) {} +public: + _CP_OPT(std::wstring) display_text; + _CP_OPT(std::wstring) value; +}; +CP_REGISTER_OFFICE_ELEMENT2(loext_list_item); +} +} diff --git a/OdfFile/Reader/Format/office_meta.cpp b/OdfFile/Reader/Format/office_meta.cpp index 5252d8c638a..47b3ec52309 100644 --- a/OdfFile/Reader/Format/office_meta.cpp +++ b/OdfFile/Reader/Format/office_meta.cpp @@ -174,6 +174,7 @@ const wchar_t * meta_user_defined::name = L"user-defined"; void meta_user_defined::add_attributes( const xml::attributes_wc_ptr & Attributes ) { CP_APPLY_ATTR(L"meta:name", meta_name_, std::wstring(L"")); + CP_APPLY_ATTR(L"meta:value-type", meta_value_type_); } void meta_user_defined::add_text(const std::wstring & text) diff --git a/OdfFile/Reader/Format/office_meta.h b/OdfFile/Reader/Format/office_meta.h index 5bb06292d9a..2293ee0aa24 100644 --- a/OdfFile/Reader/Format/office_meta.h +++ b/OdfFile/Reader/Format/office_meta.h @@ -246,6 +246,7 @@ class meta_user_defined : public office_element_impl std::wstring meta_name_; std::wstring content_; + _CP_OPT(odf_types::office_value_type) meta_value_type_; private: virtual void add_attributes( const xml::attributes_wc_ptr & Attributes ); diff --git a/OdfFile/Reader/Format/office_presentation.cpp b/OdfFile/Reader/Format/office_presentation.cpp index 3d4f94c7c99..630985ee626 100644 --- a/OdfFile/Reader/Format/office_presentation.cpp +++ b/OdfFile/Reader/Format/office_presentation.cpp @@ -92,6 +92,18 @@ void office_presentation::add_attributes( const xml::attributes_wc_ptr & Attribu { } +void office_presentation::collect_page_names(oox::pptx_conversion_context& Context) +{ + for (size_t i = 0; i < pages_.size(); i++) + { + draw_page* page = dynamic_cast(pages_[i].get()); + if (!page) + continue; + + Context.add_page_name(page->get_draw_name()); + } +} + void office_presentation::docx_convert(oox::docx_conversion_context & Context) { Context.start_office_text(); @@ -151,6 +163,8 @@ void office_presentation::pptx_convert(oox::pptx_conversion_context & Context) if (sequences_) sequences_->pptx_convert(Context); + collect_page_names(Context); + for (size_t i = 0; i < pages_.size(); i++) { pages_[i]->pptx_convert(Context); diff --git a/OdfFile/Reader/Format/office_presentation.h b/OdfFile/Reader/Format/office_presentation.h index 11227a70f2a..f3a0b929c5d 100644 --- a/OdfFile/Reader/Format/office_presentation.h +++ b/OdfFile/Reader/Format/office_presentation.h @@ -58,6 +58,8 @@ class office_presentation : public office_element_impl virtual void add_child_element( xml::sax * Reader, const std::wstring & Ns, const std::wstring & Name); virtual void add_text(const std::wstring & Text); + void collect_page_names(oox::pptx_conversion_context& Context); + public: office_element_ptr tracked_changes_; diff --git a/OdfFile/Reader/Format/office_text.cpp b/OdfFile/Reader/Format/office_text.cpp index 5c024bf817a..fefac3793ba 100644 --- a/OdfFile/Reader/Format/office_text.cpp +++ b/OdfFile/Reader/Format/office_text.cpp @@ -39,6 +39,7 @@ #include "serialize_elements.h" #include "odfcontext.h" +#include "style_paragraph_properties.h" namespace cpdoccore { namespace odf_reader { @@ -165,22 +166,25 @@ void office_text::docx_convert(oox::docx_conversion_context & Context) Context.start_office_text(); + _CP_OPT(std::wstring) masterPageName_first; + if ((first_element_style_name) && (!first_element_style_name->empty())) { - std::wstring text___ = *first_element_style_name; + std::wstring style_name = *first_element_style_name; - const _CP_OPT(std::wstring) masterPageName = Context.root()->odf_context().styleContainer().master_page_name_by_name(text___); + masterPageName_first = Context.root()->odf_context().styleContainer().master_page_name_by_name(style_name); - if (masterPageName) + if (masterPageName_first) { - std::wstring masterPageNameLayout = Context.root()->odf_context().pageLayoutContainer().page_layout_name_by_style(*masterPageName); + std::wstring masterPageNameLayout = Context.root()->odf_context().pageLayoutContainer().page_layout_name_by_style(*masterPageName_first); if (false == masterPageNameLayout.empty()) { - Context.set_master_page_name(*masterPageName); //проверка на то что тема действительно существует???? - - Context.remove_page_properties(); - Context.add_page_properties(masterPageNameLayout); + if (true == Context.set_master_page_name(*masterPageName_first)) + { + Context.remove_page_properties(); + Context.add_page_properties(masterPageNameLayout); + } } } } @@ -188,22 +192,40 @@ void office_text::docx_convert(oox::docx_conversion_context & Context) { if (content_[i]->element_style_name) { - std::wstring text___ = *content_[i]->element_style_name; + std::wstring style_name = *content_[i]->element_style_name; - const _CP_OPT(std::wstring) masterPageName = Context.root()->odf_context().styleContainer().master_page_name_by_name(*content_[i]->element_style_name); + _CP_OPT(std::wstring) masterPageName = Context.root()->odf_context().styleContainer().master_page_name_by_name(*content_[i]->element_style_name); + if (!masterPageName) + { + style_instance* curr_style_instance = Context.root()->odf_context().styleContainer().style_by_name(style_name, odf_types::style_family::Paragraph, false); + + if (curr_style_instance && curr_style_instance->content()->get_style_paragraph_properties() && + curr_style_instance->content()->get_style_paragraph_properties()->content_.fo_break_before_) + { + if (curr_style_instance && false == curr_style_instance->parent_name().empty()) + { + masterPageName = Context.root()->odf_context().styleContainer().master_page_name_by_name(curr_style_instance->parent_name()); + } + if (!masterPageName && (style_name == L"Standard" || (curr_style_instance && curr_style_instance->parent_name() == L"Standard"))) + { + masterPageName = L"Standard"; + } + } + } if (masterPageName) - { + { std::wstring masterPageNameLayout = Context.root()->odf_context().pageLayoutContainer().page_layout_name_by_style(*masterPageName); if (false == masterPageNameLayout.empty()) { - Context.set_master_page_name(*masterPageName); //проверка на то что тема действительно существует???? - - Context.remove_page_properties(); - Context.add_page_properties(masterPageNameLayout); + if (true == Context.set_master_page_name(*masterPageName)) + { + Context.remove_page_properties(); + Context.add_page_properties(masterPageNameLayout); + } } - } + } } if (content_[i]->next_element_style_name) { @@ -222,6 +244,23 @@ void office_text::docx_convert(oox::docx_conversion_context & Context) //is_empty = false; } } + + style_instance* next_style_instance = Context.root()->odf_context().styleContainer().style_by_name(text___, odf_types::style_family::Paragraph, false); + if (next_style_instance) + { + style_content* next_style_content = next_style_instance->content(); + if (next_style_content) + { + style_paragraph_properties* next_para_props = next_style_content->get_style_paragraph_properties(); + if (next_para_props) + { + if (next_para_props->content_.fo_break_before_ && next_para_props->content_.fo_break_before_->get_type() == odf_types::fo_break::Page) + { + Context.next_dump_page_properties(true); + } + } + } + } } content_[i]->docx_convert(Context); } diff --git a/OdfFile/Reader/Format/paragraph_elements.cpp b/OdfFile/Reader/Format/paragraph_elements.cpp index 89aee4a9a22..0eb0d42d990 100644 --- a/OdfFile/Reader/Format/paragraph_elements.cpp +++ b/OdfFile/Reader/Format/paragraph_elements.cpp @@ -91,6 +91,31 @@ void paragraph_content_element::docx_serialize_field(const std::wstring & field_ strm << L""; } } + +void paragraph_content_element::docx_serialize_field(const std::wstring& field_name, office_element_ptr_array& content, + oox::docx_conversion_context& Context, bool bLock) +{ + std::wostream& strm = Context.output_stream(); + Context.finish_run(); + + if (false == field_name.empty()) + { + strm << L""; + strm << L"" << field_name << L""; + } + + docx_serialize_run(content, Context); + + if (false == field_name.empty()) + { + strm << L""; + } +} void paragraph_content_element::docx_serialize_sdt_placeholder(const std::wstring & name, office_element_ptr & text, oox::docx_conversion_context & Context) { std::wostream & strm = Context.output_stream(); @@ -105,7 +130,20 @@ void paragraph_content_element::docx_serialize_sdt_placeholder(const std::wstrin strm << L""; } +void paragraph_content_element::docx_serialize_sdt_placeholder(const std::wstring& name, office_element_ptr_array& content, oox::docx_conversion_context& Context) +{ + std::wostream& strm = Context.output_stream(); + Context.finish_run(); + strm << L""; + strm << L""; + + docx_serialize_run(content, Context); + + strm << L""; +} void paragraph_content_element::docx_serialize_run(office_element_ptr & text, oox::docx_conversion_context & Context) { Context.add_new_run(); @@ -115,7 +153,23 @@ void paragraph_content_element::docx_serialize_run(office_element_ptr & text, oo } Context.finish_run(); } - +void paragraph_content_element::docx_serialize_run(office_element_ptr_array& content, oox::docx_conversion_context& Context) +{ + for (size_t i = 0; i < content.size(); ++i) + { + docx_serialize_run(content[i], Context); + } +} +void paragraph_content_element::xlsx_serialize(std::wostream& _Wostream, oox::xlsx_conversion_context& Context) +{ + std::wstringstream val; + text_to_stream(val, true); + std::wstring val_text = val.str(); + if (val_text != L"???") + { + _Wostream << val_text; + } +} //------------------------------------------------------------------------------------------------------------ const wchar_t * text::ns = L""; const wchar_t * text::name = L""; @@ -196,11 +250,11 @@ void text::docx_convert(oox::docx_conversion_context & Context) void text::xlsx_convert(oox::xlsx_conversion_context & Context) { - Context.get_text_context().add_text(text_); + Context.get_text_context()->add_text(text_); } void text::pptx_convert(oox::pptx_conversion_context & Context) { - Context.get_text_context().add_text(text_); + Context.get_text_context().add_text(text_); } office_element_ptr text::create(const std::wstring & Text) { @@ -255,7 +309,7 @@ void s::xlsx_convert(oox::xlsx_conversion_context & Context) { std::wstringstream val; this->text_to_stream(val); - Context.get_text_context().add_text(val.str()); + Context.get_text_context()->add_text(val.str()); } void s::pptx_convert(oox::pptx_conversion_context & Context) { @@ -292,7 +346,7 @@ void tab::docx_convert(oox::docx_conversion_context & Context) void tab::xlsx_convert(oox::xlsx_conversion_context & Context) { - Context.get_text_context().add_text(L"\t"); + Context.get_text_context()->add_text(L"\t"); } void tab::pptx_convert(oox::pptx_conversion_context & Context) { @@ -329,7 +383,7 @@ void line_break::docx_convert(oox::docx_conversion_context & Context) } void line_break::xlsx_convert(oox::xlsx_conversion_context & Context) { - Context.get_text_context().add_text(L"\n"); + Context.get_text_context()->add_text(L"\n"); } void line_break::pptx_convert(oox::pptx_conversion_context & Context) { @@ -396,7 +450,26 @@ void bookmark_ref::add_attributes( const xml::attributes_wc_ptr & Attributes ) } void bookmark_ref::add_text(const std::wstring & Text) { - content_ = Text; + office_element_ptr elm = text::create(Text); + content_.push_back( elm ); +} +void bookmark_ref::add_child_element(xml::sax* Reader, const std::wstring& Ns, const std::wstring& Name) +{ + CP_CREATE_ELEMENT(content_); +} +void bookmark_ref::docx_convert(oox::docx_conversion_context& Context) +{ + std::wstring field_name = (ref_name_ ? L"REF " + *ref_name_ : L"REF") + L" \\h"; + + if (reference_format_) + { + switch (reference_format_->get_type()) + { + case reference_format::direction: field_name += L" \\p"; break; + case reference_format::number: field_name += L" \\n"; break; + } + } + docx_serialize_field(field_name, content_, Context); } // text:reference-ref ////////////////////////////////////////////////////////////////////////////////////////////////// @@ -676,16 +749,16 @@ void a::add_space(const std::wstring & Text) } void a::docx_convert(oox::docx_conversion_context & Context) { - bool pushed_style = false; + std::wstring ref = xlink_attlist_.href_.get_value_or(L""); + if (ref.empty()) return; + bool pushed_style = false; bool addNewRun = false; - Context.finish_run(); - - std::wostream & _Wostream = Context.output_stream(); - - std::wstring ref = xlink_attlist_.href_.get_value_or(L""); + + Context.finish_run(); - if (Context.is_table_content()) + std::wostream& _Wostream = Context.output_stream(); + if (Context.is_table_content() || office_target_frame_name_ || ref[0] == L'#') { size_t pos_outline = ref.find(L"|outline"); if (std::wstring::npos != pos_outline)//без # @@ -702,11 +775,14 @@ void a::docx_convert(oox::docx_conversion_context & Context) { ref = XmlUtils::EncodeXmlString(ref.substr(1)); } - _Wostream << L""; - int type = Context.get_table_content_context().get_type_current_content_template_index(); - //type == 3 (LinkStart) - Context.get_table_content_context().next_level_index(); + + if (Context.is_table_content()) + { + int type = Context.get_table_content_context().get_type_current_content_template_index(); + //type == 3 (LinkStart) + Context.get_table_content_context().next_level_index(); + } } else { @@ -778,6 +854,27 @@ void a::xlsx_convert(oox::xlsx_conversion_context & Context) } Context.end_hyperlink(xlink_attlist_.href_.get_value_or(L"")); } + +static std::wstring convert_href(oox::pptx_conversion_context& Context, const std::wstring& href) +{ + std::wstring result = href; + + if (boost::algorithm::starts_with(href, L"#")) + result = href.substr(1); + + const auto& page_names = Context.get_page_names(); + for (size_t i = 0; i < page_names.size(); i++) + { + if (result == page_names[i]) + { + result = std::wstring(L"slide") + std::to_wstring(i + 1) + std::wstring(L".xml"); + return result; + } + } + + return std::wstring(); +} + void a::pptx_convert(oox::pptx_conversion_context & Context) { Context.get_text_context().start_hyperlink(); @@ -786,9 +883,20 @@ void a::pptx_convert(oox::pptx_conversion_context & Context) content_[i]->pptx_convert(Context); } - std::wstring hId = Context.get_slide_context().add_hyperlink(xlink_attlist_.href_.get_value_or(L"")); - Context.get_text_context().end_hyperlink(hId); + std::wstring href = xlink_attlist_.href_.get_value_or(L""); + + if (boost::algorithm::starts_with(href, L"#")) + { + href = convert_href(Context, href); + if(!href.empty()) + Context.get_text_context().set_action(L"ppaction://hlinksldjump"); + } + + std::wstring hId = Context.get_slide_context().add_hyperlink(href); + + Context.get_text_context().set_rel_id(hId); + Context.get_text_context().end_hyperlink(); } //------------------------------------------------------------------------------------------------------------ const wchar_t * endnote::ns = L"text"; @@ -970,7 +1078,26 @@ void title::xlsx_convert(oox::xlsx_conversion_context & Context) { std::wstringstream val; text_to_stream(val); - Context.get_text_context().add_text(val.str()); + std::wstring _title = val.str(); + if (_title != L"???") + { + Context.get_text_context()->add_text(_title); + } +} +void title::xlsx_serialize(std::wostream& _Wostream, oox::xlsx_conversion_context& Context) +{ + std::wstringstream val; + text_to_stream(val); + std::wstring _title = val.str(); + + if (_title == L"???") + { + _Wostream << L"&F"; + } + else + { + _Wostream << _title; + } } void title::pptx_convert(oox::pptx_conversion_context & Context) { @@ -1004,11 +1131,15 @@ void subject::docx_convert(oox::docx_conversion_context & Context) docx_serialize_field(L"SUBJECT", text_, Context); } -void subject::xlsx_convert(oox::xlsx_conversion_context & Context) +void subject::xlsx_convert(oox::xlsx_conversion_context& Context) { - std::wstringstream val; - this->text_to_stream(val); - Context.get_text_context().add_text(val.str()); + std::wstringstream val; + this->text_to_stream(val); + std::wstring _subject = val.str(); + if (_subject != L"???") + { + Context.get_text_context()->add_text(_subject); + } } void subject::pptx_convert(oox::pptx_conversion_context & Context) { @@ -1043,7 +1174,11 @@ void chapter::xlsx_convert(oox::xlsx_conversion_context & Context) { std::wstringstream val; this->text_to_stream(val); - Context.get_text_context().add_text(val.str()); + std::wstring _chapter = val.str(); + if (_chapter != L"???") + { + Context.get_text_context()->add_text(_chapter); + } } void chapter::pptx_convert(oox::pptx_conversion_context & Context) { @@ -1056,30 +1191,32 @@ void chapter::pptx_convert(oox::pptx_conversion_context & Context) const wchar_t * text_placeholder::ns = L"text"; const wchar_t * text_placeholder::name = L"placeholder"; +void text_placeholder::add_attributes( const xml::attributes_wc_ptr & Attributes ) +{ +} std::wostream & text_placeholder::text_to_stream(std::wostream & _Wostream, bool bXmlEncode) const { - CP_SERIALIZE_TEXT(text_, bXmlEncode); - return _Wostream; + CP_SERIALIZE_TEXT(content_, bXmlEncode); + return _Wostream; } - -void text_placeholder::add_attributes( const xml::attributes_wc_ptr & Attributes ) +void text_placeholder::add_child_element(xml::sax* Reader, const std::wstring& Ns, const std::wstring& Name) { + CP_CREATE_ELEMENT(content_); } void text_placeholder::add_text(const std::wstring & Text) { - text_ = text::create(Text) ; + office_element_ptr text = text::create(Text) ; + content_.push_back(text); } - void text_placeholder::docx_convert(oox::docx_conversion_context & Context) { - docx_serialize_sdt_placeholder(L"Click placeholder and overwrite", text_, Context); + docx_serialize_sdt_placeholder(L"Click placeholder and overwrite", content_, Context); } - void text_placeholder::pptx_convert(oox::pptx_conversion_context & Context) { - if (text_) + for (size_t i = 0; i < content_.size(); ++i) { - text_->pptx_convert(Context); + content_[i]->pptx_convert(Context); } } @@ -1392,18 +1529,18 @@ void sequence::add_attributes( const xml::attributes_wc_ptr & Attributes ) } std::wostream & sequence::text_to_stream(std::wostream & _Wostream, bool bXmlEncode) const { - CP_SERIALIZE_TEXT(text_, bXmlEncode); + CP_SERIALIZE_TEXT(content_, bXmlEncode); return _Wostream; } void sequence::add_child_element( xml::sax * Reader, const std::wstring & Ns, const std::wstring & Name) { - CP_CREATE_ELEMENT(text_); + CP_CREATE_ELEMENT(content_); } void sequence::add_text(const std::wstring & Text) { office_element_ptr elm = text::create(Text) ; - text_.push_back( elm ); + content_.push_back( elm ); } void sequence::docx_convert(oox::docx_conversion_context & Context) @@ -1453,9 +1590,9 @@ void sequence::docx_convert(oox::docx_conversion_context & Context) Context.start_bookmark(name); Context.output_stream() << L""; Context.add_new_run(); - for (size_t i = 0; i < text_.size(); i++) + for (size_t i = 0; i < content_.size(); i++) { - text_[i]->docx_convert(Context); + content_[i]->docx_convert(Context); } Context.finish_run(); @@ -1470,9 +1607,9 @@ void sequence::docx_convert(oox::docx_conversion_context & Context) } void sequence::pptx_convert(oox::pptx_conversion_context & Context) { - for (size_t i = 0; i < text_.size(); i++) + for (size_t i = 0; i < content_.size(); i++) { - text_[i]->pptx_convert(Context); + content_[i]->pptx_convert(Context); } } //------------------------------------------------------------------------------------------------------------ @@ -1842,7 +1979,10 @@ void text_user_defined::docx_convert(oox::docx_conversion_context & Context) if (!value.empty()) text_ = text::create(value) ; - docx_serialize_run(text_, Context); + if (text_name_) + docx_serialize_field(XmlUtils::EncodeXmlString(L"DOCPROPERTY \"" + *text_name_ + L"\""), text_, Context, false); + else + docx_serialize_run(text_, Context); } //----------------------------------------------------------------------------------------------- // text:bibliography-mark diff --git a/OdfFile/Reader/Format/paragraph_elements.h b/OdfFile/Reader/Format/paragraph_elements.h index d690b77546e..2b0df588917 100644 --- a/OdfFile/Reader/Format/paragraph_elements.h +++ b/OdfFile/Reader/Format/paragraph_elements.h @@ -42,6 +42,7 @@ #include "../../DataTypes/noteclass.h" #include "../../DataTypes/bool.h" #include "../../DataTypes/bibliography.h" +#include "../../DataTypes/referenceformat.h" #include "../../Reader/Converter/docx_conversion_context.h" @@ -67,14 +68,17 @@ class paragraph_content_element : public office_element_implstyle_background_image_); + _CP_APPLY_PROP(style_columns_, Other->style_columns_); } @@ -263,10 +264,10 @@ void style_graphic_properties::add_attributes( const xml::attributes_wc_ptr & At void style_graphic_properties::add_child_element( xml::sax * Reader, const std::wstring & Ns, const std::wstring & Name) { - if (L"style" == Ns && L"background-image" == Name) - { + if (L"style" == Ns && L"background-image" == Name) CP_CREATE_ELEMENT(content_.style_background_image_); - } + else if(L"style" == Ns && L"columns" == Name) + CP_CREATE_ELEMENT(content_.style_columns_); //if (CP_CHECK_NAME(L"text", L"list-style") // styles_.add_child_element(Reader, Ns, Name, getContext()); он тут и не нужен по сути... описание есть и в другом сместе diff --git a/OdfFile/Reader/Format/style_graphic_properties.h b/OdfFile/Reader/Format/style_graphic_properties.h index dafe02a5bfa..5c23a515538 100644 --- a/OdfFile/Reader/Format/style_graphic_properties.h +++ b/OdfFile/Reader/Format/style_graphic_properties.h @@ -131,6 +131,7 @@ class graphic_format_properties _CP_OPT(odf_types::wrap_option) fo_wrap_option_; office_element_ptr style_background_image_; + office_element_ptr style_columns_; }; typedef boost::shared_ptr graphic_format_properties_ptr; diff --git a/OdfFile/Reader/Format/style_paragraph_properties_docx.cpp b/OdfFile/Reader/Format/style_paragraph_properties_docx.cpp index 6ad238048c5..0e6166a87c3 100644 --- a/OdfFile/Reader/Format/style_paragraph_properties_docx.cpp +++ b/OdfFile/Reader/Format/style_paragraph_properties_docx.cpp @@ -82,11 +82,10 @@ std::wstring process_border(const border_style & borderStyle, { case border_style::none: w_val = L"none"; break; case border_style::solid: - case border_style::single: w_val = L"single"; break; case border_style::double_: w_val = L"double"; break; case border_style::dotted: w_val = L"dotted"; break; - case border_style::dashed: w_val = L"dashed"; break; + case border_style::dash: w_val = L"dashed"; break; case border_style::groove: w_val = L"thinThickMediumGap"; break; case border_style::ridge: w_val = L"thickThinMediumGap"; break; case border_style::inset: w_val = L"inset"; break; @@ -399,31 +398,48 @@ void paragraph_format_properties::docx_convert(oox::docx_conversion_context & Co } } - if (fo_margin_left_ || //? + буквица + _CP_OPT(odf_types::length_or_percent) curr_margin_left_ = fo_margin_left_; + if (curr_margin_left_ || //? + буквица fo_margin_right_ || (fo_text_indent_ && Context.get_drop_cap_context().state() != 1)) { // TODO auto indent - std::wstring w_left, w_right, w_hanging, w_firstLine; + +#if 0 + if (Context.get_list_style_level() > 0) + { + int lvl = Context.get_list_style_stack().size() - 1; + odf_reader::list_style_container& lists = Context.root()->odf_context().listStyleContainer(); + odf_reader::text_list_style* curStyleList = lists.list_style_by_name(Context.get_list_style_stack().back()); + + if (lvl < curStyleList->content_.size()) + { + odf_reader::text_list_level_style* curStyleListLvl = dynamic_cast(curStyleList->content_[lvl].get()); + odf_reader::style_list_level_properties* curStyleListLvlProps = curStyleListLvl ? dynamic_cast(curStyleListLvl->list_level_properties_.get()) : NULL; + if (curStyleListLvlProps) + { + curr_margin_left_ = curStyleListLvlProps->text_space_before_; + } + } + } +#endif + std::wstring w_left, w_right, w_hanging; w_left = docx_process_margin(fo_margin_left_, 20.0); w_right = docx_process_margin(fo_margin_right_, 20.0); - w_firstLine = docx_process_margin(fo_text_indent_, 20.0); + w_hanging = docx_process_margin(fo_text_indent_, -20.0); - if (w_left.empty()) w_left = L"0"; - if (w_right.empty()) w_right = L"0"; - if (w_firstLine.empty()) w_hanging = L"0"; + if (w_left.empty()) w_left = L"0"; + if (w_right.empty()) w_right = L"0"; + if (w_hanging.empty()) w_hanging = L"0"; CP_XML_NODE(L"w:ind") { - CP_XML_ATTR(L"w:left", w_left); - CP_XML_ATTR(L"w:right", w_right); + CP_XML_ATTR(L"w:start", w_left); + CP_XML_ATTR(L"w:end", w_right); if (Context.get_drop_cap_context().state() != 1 )//состояние сразу после добавления буквицы - не нужны ни отступы, ни висячие { - if (!w_firstLine.empty()) - CP_XML_ATTR(L"w:firstLine", w_firstLine); - if (!w_hanging.empty()) CP_XML_ATTR(L"w:hanging", w_hanging); } @@ -501,7 +517,7 @@ void style_tab_stop::docx_convert(oox::docx_conversion_context & Context, bool c length def_tab = length(1.0, length::cm);// в ms значение 0.8 не корректно оО - double tab_pos = 20.0 * style_position_.get_value_unit(length::pt) + margin_left ; + double tab_pos = 20.0 * style_position_.get_value_unit(length::pt); double min_tab_pos = 20.0 * def_tab.get_value_unit(length::pt) ; if (tab_pos < min_tab_pos) diff --git a/OdfFile/Reader/Format/style_paragraph_properties_pptx.cpp b/OdfFile/Reader/Format/style_paragraph_properties_pptx.cpp index 12ca330a5bf..036de670e3a 100644 --- a/OdfFile/Reader/Format/style_paragraph_properties_pptx.cpp +++ b/OdfFile/Reader/Format/style_paragraph_properties_pptx.cpp @@ -35,6 +35,8 @@ #include #include "../../Reader/Converter/pptx_conversion_context.h" +#include "../../Reader/Format/odf_document.h" +#include "../../Reader/Format/odfcontext.h" #include "../../DataTypes/borderstyle.h" namespace cpdoccore { @@ -78,11 +80,10 @@ std::wstring process_border(border_style & borderStyle, switch(borderStyle.get_style()) { case border_style::none: w_val = L"none"; break; - case border_style::solid: - case border_style::single: w_val = L"single"; break; + case border_style::solid: w_val = L"single"; break; case border_style::double_: w_val = L"double"; break; case border_style::dotted: w_val = L"dotted"; break; - case border_style::dashed: w_val = L"dashed"; break; + case border_style::dash: w_val = L"dashed"; break; case border_style::groove: w_val = L"thinThickMediumGap"; break; case border_style::ridge: w_val = L"thickThinMediumGap"; break; case border_style::inset: w_val = L"inset"; break; @@ -452,16 +453,38 @@ void paragraph_format_properties::pptx_convert(oox::pptx_conversion_context & Co } } } - if (fo_margin_top_/* || fo_margin_*/) + if (fo_margin_top_) { + style_instance* last_paragraph_style = Context.root()->odf_context().styleContainer().style_by_name( + Context.get_text_context().get_last_paragraph_style_name(), + style_family::Paragraph, + false + ); + CP_XML_NODE(L"a:spcBef") { if (fo_margin_top_->get_type() == length_or_percent::Length) { - std::wstring w_before = pptx_process_margin(fo_margin_top_, length::pt, 100.0); + _CP_OPT(length_or_percent) margin_top = fo_margin_top_; + if (last_paragraph_style) + { + const style_paragraph_properties* last_style_paragraph_props = last_paragraph_style->content()->get_style_paragraph_properties(); + if (last_style_paragraph_props) + { + const paragraph_format_properties& last_paragraph_props = last_style_paragraph_props->content_; + length_or_percent last_margin_bottom = last_paragraph_props.fo_margin_bottom_.get_value_or(length_or_percent(length(0.0, length::cm))); + + if (fo_margin_top_->get_length().get_value_unit(length::cm) > last_margin_bottom.get_length().get_value_unit(length::cm)) + margin_top = _CP_OPT(length_or_percent)(length(fo_margin_top_->get_length().get_value_unit(length::cm) - last_margin_bottom.get_length().get_value_unit(length::cm), length::cm)); + else + margin_top = _CP_OPT(length_or_percent)(length(0.0, length::cm)); + } + } + + std::wstring w_before = pptx_process_margin(margin_top, length::pt, 100.0); CP_XML_NODE(L"a:spcPts") { - CP_XML_ATTR(L"val",w_before); + CP_XML_ATTR(L"val", w_before); } } else @@ -475,16 +498,16 @@ void paragraph_format_properties::pptx_convert(oox::pptx_conversion_context & Co } } } - if (fo_margin_bottom_/* || fo_margin_*/) + if (fo_margin_bottom_) { CP_XML_NODE(L"a:spcAft") { if (fo_margin_bottom_->get_type() == length_or_percent::Length) { - std::wstring w_after = pptx_process_margin(fo_margin_bottom_, length::pt, 100.0); + std::wstring w_after = pptx_process_margin(fo_margin_bottom_, length::pt, 100.0); CP_XML_NODE(L"a:spcPts") { - CP_XML_ATTR(L"val",w_after); + CP_XML_ATTR(L"val", w_after); } } else @@ -498,6 +521,7 @@ void paragraph_format_properties::pptx_convert(oox::pptx_conversion_context & Co } } } + //if (style_punctuation_wrap_) //{ // std::wstring w_val; diff --git a/OdfFile/Reader/Format/style_presentation.cpp b/OdfFile/Reader/Format/style_presentation.cpp index fe1218f215c..a11f5fecc4a 100644 --- a/OdfFile/Reader/Format/style_presentation.cpp +++ b/OdfFile/Reader/Format/style_presentation.cpp @@ -31,58 +31,74 @@ */ #include "style_presentation.h" +#include "odfcontext.h" +#include "odf_document.h" #include #include -namespace cpdoccore { +#include "calcs_styles.h" - using namespace odf_types; - -namespace odf_reader { - -const wchar_t * presentation_placeholder::ns = L"presentation"; -const wchar_t * presentation_placeholder::name = L"placeholder"; - -void presentation_placeholder::add_attributes( const xml::attributes_wc_ptr & Attributes ) -{ - CP_APPLY_ATTR(L"presentation:object", presentation_object_); - - CP_APPLY_ATTR(L"svg:height", svg_height_); - CP_APPLY_ATTR(L"svg:width", svg_width_); - CP_APPLY_ATTR(L"svg:x", svg_x_); - CP_APPLY_ATTR(L"svg:y", svg_y_); +namespace cpdoccore { -} - -void presentation_placeholder::add_child_element( xml::sax * Reader, const std::wstring & Ns, const std::wstring & Name) -{ - CP_NOT_APPLICABLE_ELM(); -} - -void presentation_placeholder::pptx_convert(oox::pptx_conversion_context & Context) -{ - double cx = svg_width_.get_value_or(length(0)).get_value_unit(length::pt); - double cy = svg_height_.get_value_or(length(0)).get_value_unit(length::pt); - - //пока не понятно что значит отрицательная ширина ... - cx = fabs(cx); - cy = fabs(cy); - - double x = svg_x_.get_value_or(length(0)).get_value_unit(length::pt); - double y = svg_y_.get_value_or(length(0)).get_value_unit(length::pt); - - Context.get_slide_context().start_shape(2);//rect - Context.get_slide_context().set_name(L"place_holder"); - - Context.get_slide_context().set_rect(cx,cy,x,y); - if (presentation_object_) - { - Context.get_slide_context().set_placeHolder_type(presentation_object_->get_type_ms()); - } + using namespace odf_types; - Context.get_slide_context().end_shape(); -} + namespace odf_reader { + + const wchar_t* presentation_placeholder::ns = L"presentation"; + const wchar_t* presentation_placeholder::name = L"placeholder"; + + void presentation_placeholder::add_attributes(const xml::attributes_wc_ptr& Attributes) + { + CP_APPLY_ATTR(L"presentation:object", presentation_object_); + + CP_APPLY_ATTR(L"svg:height", svg_height_); + CP_APPLY_ATTR(L"svg:width", svg_width_); + CP_APPLY_ATTR(L"svg:x", svg_x_); + CP_APPLY_ATTR(L"svg:y", svg_y_); + + CP_APPLY_ATTR(L"draw:text-style-name", text_style_name_); + } + + void presentation_placeholder::add_child_element(xml::sax* Reader, const std::wstring& Ns, const std::wstring& Name) + { + CP_NOT_APPLICABLE_ELM(); + } + + void presentation_placeholder::pptx_convert(oox::pptx_conversion_context& Context) + { + double cx = svg_width_.get_value_or(length(0)).get_value_unit(length::pt); + double cy = svg_height_.get_value_or(length(0)).get_value_unit(length::pt); + + //пока не понятно что значит отрицательная ширина ... + cx = fabs(cx); + cy = fabs(cy); + + double x = svg_x_.get_value_or(length(0)).get_value_unit(length::pt); + double y = svg_y_.get_value_or(length(0)).get_value_unit(length::pt); + + Context.get_slide_context().start_shape(2);//rect + Context.get_slide_context().set_name(L"place_holder"); + + if (text_style_name_ && !text_style_name_->empty()) + { + Context.get_text_context().start_base_style(*text_style_name_, odf_types::style_family::Paragraph); + } + Context.get_slide_context().set_rect(cx, cy, x, y); + if (presentation_object_) + { + Context.get_slide_context().set_placeHolder_type(presentation_object_->get_type_ms()); + Context.get_slide_context().set_property(_property(L"no_rect", true)); + } + std::wstring text_content_ = Context.get_text_context().end_object(); + + if (!text_content_.empty()) + { + Context.get_slide_context().set_property(_property(L"text-content", text_content_)); + } + Context.get_text_context().end_base_style(); + Context.get_slide_context().end_shape(); + } //------------------------------------------------------------------------------------------------- const wchar_t * presentation_sound::ns = L"presentation"; const wchar_t * presentation_sound::name = L"sound"; @@ -99,7 +115,7 @@ void presentation_sound::add_child_element( xml::sax * Reader, const std::wstrin void presentation_sound::pptx_convert(oox::pptx_conversion_context & Context) { - Context.get_slide_context().set_link(xlink_attlist_.href_.get_value_or(L""), oox::typeAudio); + Context.get_slide_context().set_link(xlink_attlist_.href_.get_value_or(L""), oox::typeHyperlink); } //------------------------------------------------------------------------------------------------- const wchar_t * style_drawing_page_properties::ns = L"style"; @@ -135,6 +151,8 @@ void drawing_page_properties::add_attributes( const xml::attributes_wc_ptr & Att CP_APPLY_ATTR(L"presentation:display-date-time", presentation_display_date_time_); CP_APPLY_ATTR(L"presentation:display-header", presentation_display_header_); CP_APPLY_ATTR(L"presentation:page-duration", presentation_page_duration_); + + CP_APPLY_ATTR(L"presentation:visibility", presentation_visibility_); } void drawing_page_properties::apply_from(const drawing_page_properties & Other) { @@ -156,6 +174,8 @@ void drawing_page_properties::apply_from(const drawing_page_properties & Other) _CP_APPLY_PROP2(presentation_page_duration_); + _CP_APPLY_PROP2(presentation_visibility_); + } } } diff --git a/OdfFile/Reader/Format/style_presentation.h b/OdfFile/Reader/Format/style_presentation.h index dc51d987285..0978abe2d74 100644 --- a/OdfFile/Reader/Format/style_presentation.h +++ b/OdfFile/Reader/Format/style_presentation.h @@ -38,6 +38,7 @@ #include "anim_elements.h" #include "../../DataTypes/presentationclass.h" +#include "../../DataTypes/presentationvisibility.h" #include "../../DataTypes/drawfill.h" @@ -68,6 +69,7 @@ class presentation_placeholder : public office_element_implodf_context().fontContainer(); - drawing_serialize(styles_context_.text_style(), styles_context_.extern_node(), fonts_, styles_context_.get_current_processed_style(), styles_context_.hlinkClick()); + oox::hyperlink_data link = Context.get_text_context().get_hyperlink(); + + drawing_serialize(styles_context_.text_style(), styles_context_.extern_node(), fonts_, styles_context_.get_current_processed_style(), link); // styles_context_.hlinkClick() } void text_format_properties::docx_convert(oox::docx_conversion_context & Context) diff --git a/OdfFile/Reader/Format/style_text_properties.h b/OdfFile/Reader/Format/style_text_properties.h index 5953eccc9ef..59e1b2ef7d3 100644 --- a/OdfFile/Reader/Format/style_text_properties.h +++ b/OdfFile/Reader/Format/style_text_properties.h @@ -78,7 +78,7 @@ class text_format_properties : public oox::conversion_element void oox_serialize (std::wostream & stream, bool graphic, fonts_container & fonts, bool default_ = false); void docx_serialize (std::wostream & stream, fonts_container & fonts); - void drawing_serialize (std::wostream & stream, std::wstring node, fonts_container & fonts, const odf_reader::style_instance *current_style = NULL, std::wstring hlink = L""); + void drawing_serialize (std::wostream & stream, std::wstring node, fonts_container & fonts, const odf_reader::style_instance *current_style = NULL, const oox::hyperlink_data link = {L"", L""}); void xlsx_serialize (std::wostream & strm, oox::xlsx_conversion_context & Context); diff --git a/OdfFile/Reader/Format/styles.cpp b/OdfFile/Reader/Format/styles.cpp index 6276981d8a3..574acb2aac2 100644 --- a/OdfFile/Reader/Format/styles.cpp +++ b/OdfFile/Reader/Format/styles.cpp @@ -41,6 +41,8 @@ #include "serialize_elements.h" #include "odfcontext.h" #include "draw_common.h" +#include "paragraph_elements.h" +#include "text_elements.h" namespace cpdoccore { @@ -86,12 +88,10 @@ std::wstring process_border(const border_style & borderStyle, switch(borderStyle.get_style()) { case border_style::none: w_val = L"none"; break; - case border_style::solid: - case border_style::single: - w_val = L"single"; break; + case border_style::solid: w_val = L"single"; break; case border_style::double_: w_val = L"double"; break; case border_style::dotted: w_val = L"dotted"; break; - case border_style::dashed: w_val = L"dashed"; break; + case border_style::dash: w_val = L"dashed"; break; case border_style::groove: w_val = L"thinThickMediumGap"; break; case border_style::ridge: w_val = L"thickThinMediumGap"; break; case border_style::inset: w_val = L"inset"; break; @@ -138,7 +138,14 @@ std::wstring process_margin(const _CP_OPT(length_or_percent) & margin, double Mu style_text_properties * style_content::get_style_text_properties() const { - return dynamic_cast(style_text_properties_.get()); + return dynamic_cast(style_text_properties_.get()); +} + +style_text_properties* style_content::get_style_text_properties(bool create) +{ + if (!style_text_properties_ && create) + style_text_properties_ = boost::make_shared(); + return dynamic_cast(style_text_properties_.get()); } style_paragraph_properties * style_content::get_style_paragraph_properties() const @@ -279,6 +286,8 @@ void style_content::add_child_element( xml::sax * Reader, const std::wstring & N } else if CP_CHECK_NAME(L"style", L"properties") { + Context->is_old_version = true; + office_element_ptr element; CP_CREATE_ELEMENT_SIMPLE(element); @@ -863,6 +872,15 @@ void style_columns::add_child_element( xml::sax * Reader, const std::wstring & N } } +void style_columns::pptx_convert(oox::pptx_conversion_context& Context) +{ + if(fo_column_count_) + Context.get_slide_context().set_property(odf_reader::_property(L"style_columns_count", (int)fo_column_count_.get())); + + if(fo_column_gap_) + Context.get_slide_context().set_property(odf_reader::_property(L"style_columns_gap", (int)fo_column_gap_->get_value_unit(length::emu))); +} + ////////////////////////////////////////////////////////////////////////////////////////////////// const wchar_t * style_column::ns = L"style"; const wchar_t * style_column::name = L"column"; @@ -1431,6 +1449,34 @@ bool style_page_layout_properties::docx_background_serialize(std::wostream & str return true; } +int style_page_layout_properties::DetectPageSize(double w, double h) +{ + int result = 0; + + if (w > 209.99) // A4 and more + { + if ( w < 211 && h > 296 && h < 298) result = 9; // pagesizeA4Paper; + else if (w > 279 && w < 280 && h > 431 && h < 433) result = 3; // pagesizeTabloidPaper; + else if (w > 215 && w < 217 && h > 354 && h < 356) result = 5; // pagesizeLegalPaper; + else if (w > 296 && w < 298 && h > 419 && h < 421) result = 8; // pagesizeA3Paper; + else if (w > 256 && w < 258 && h > 363 && h < 365) result = 12; // pagesizeB4Paper; + else if (w > 215 && w < 217 && h > 329 && h < 331) result = 14; // pagesizeFolioPaper; + else if (w > 228 && w < 230 && h > 323 && h < 325) result = 30; // pagesizeC4Envelope; + else if (w > 215 && w < 217 && h > 278 && h < 280) result = 1; // pagesizeLetterPaper; + } + else + { + if (w > 183 && w < 185 && h > 265 && h < 267) result = 7; // pagesizeExecutivePaper; + else if (w > 147 && w < 149 && h > 209 && h < 211) result = 11; // pagesizeA5Paper; + else if (w > 181 && w < 183 && h > 256 && h < 259) result = 13; // pagesizeB5Paper; + else if (w > 103 && w < 106 && h > 240 && h < 243) result = 20; // pagesize10Envelope; + else if (w > 109 && w < 111 && h > 219 && h < 221) result = 27; // pagesizeDLEnvelope; + else if (w > 161 && w < 164 && h > 228 && h < 230) result = 28; // pagesizeC5Envelope; + else if (w > 97 && w < 100 && h > 189 && h < 192) result = 37; // pagesizeMonarchEnvelope; + } + + return result; +} void style_page_layout_properties::xlsx_serialize(std::wostream & strm, oox::xlsx_conversion_context & Context) { @@ -1476,11 +1522,11 @@ void style_page_layout_properties::xlsx_serialize(std::wostream & strm, oox::xls { if (horizontal_margins.fo_margin_left_ && horizontal_margins.fo_margin_left_->get_type() == odf_types::length_or_percent::Length) CP_XML_ATTR(L"left" , horizontal_margins.fo_margin_left_->get_length().get_value_unit(odf_types::length::inch)); - else CP_XML_ATTR(L"left", 0); + else CP_XML_ATTR(L"left", 0.7875); if (horizontal_margins.fo_margin_right_ && horizontal_margins.fo_margin_right_->get_type() == odf_types::length_or_percent::Length) CP_XML_ATTR(L"right" , horizontal_margins.fo_margin_right_->get_length().get_value_unit(odf_types::length::inch)); - else CP_XML_ATTR(L"right", 0); + else CP_XML_ATTR(L"right", 0.7875); if (vertical_margins.fo_margin_top_ && vertical_margins.fo_margin_top_->get_type() == odf_types::length_or_percent::Length) { @@ -1523,14 +1569,26 @@ void style_page_layout_properties::xlsx_serialize(std::wostream & strm, oox::xls if (attlist_.fo_page_height_) { h = attlist_.fo_page_height_->get_value_unit(length::mm); - CP_XML_ATTR(L"paperHeight", (int)h); } if (attlist_.fo_page_width_) { w = attlist_.fo_page_width_->get_value_unit(length::mm); - CP_XML_ATTR(L"paperWidth", (int)w); } - CP_XML_ATTR(L"paperUnits", L"mm"); + + if (h > 0 && w > 0) + { + int paperSize = DetectPageSize(w, h); + if (0 < paperSize) + { + CP_XML_ATTR(L"paperSize", paperSize); + } + else + { + CP_XML_ATTR(L"paperHeight", (int)h); + CP_XML_ATTR(L"paperWidth", (int)w); + CP_XML_ATTR(L"paperUnits", L"mm"); + } + } if (attlist_.style_scale_to_) { @@ -1775,16 +1833,41 @@ void style_master_page::pptx_convert(oox::pptx_conversion_context & Context) if (attlist_.draw_style_name_) { std::wstring style_name = attlist_.draw_style_name_.get(); - style_instance * style_inst = Context.root()->odf_context().styleContainer().style_by_name(style_name, style_family::DrawingPage, true); + graphic_format_properties* default_properties = NULL; + + if (getContext()->is_old_version) + { + style_instance* style_inst_def = Context.root()->odf_context().styleContainer().style_by_name(L"standard", style_family::Graphic, true); + if ((style_inst_def) && (style_inst_def->content())) + { + default_properties = style_inst_def->content()->get_graphic_properties(); + } + } + else + { + style_instance* style_inst_def = Context.root()->odf_context().styleContainer().style_default_by_type(odf_types::style_family::Graphic); + if ((style_inst_def) && (style_inst_def->content())) + { + default_properties = style_inst_def->content()->get_graphic_properties(); + } + } + style_instance * style_inst = Context.root()->odf_context().styleContainer().style_by_name(style_name, style_family::DrawingPage, true); if ((style_inst) && (style_inst->content())) { style_drawing_page_properties * properties = style_inst->content()->get_style_drawing_page_properties(); if (properties) { + odf_types::common_draw_fill_attlist calc_props; + if (default_properties) + { + calc_props.apply_from(default_properties->common_draw_fill_attlist_); + } + calc_props.apply_from(properties->content().common_draw_fill_attlist_); + oox::_oox_fill fill; - Compute_GraphicFill(properties->content().common_draw_fill_attlist_, office_element_ptr(), Context.root(), fill); + Compute_GraphicFill(calc_props, office_element_ptr(), Context.root(), fill); Context.get_slide_context().add_background(fill); } } @@ -2023,11 +2106,27 @@ void header_footer_impl::xlsx_serialize(std::wostream & _Wostream, oox::xlsx_con { region->xlsx_serialize(_Wostream, Context); } + else if (typeTextP == content_[i]->get_type()) + { + text::p* p = dynamic_cast(content_[i].get()); + for (size_t j = 0; p && j < p->paragraph_.content_.size(); j++) + { + text::paragraph_content_element* paragraph_element = dynamic_cast(p->paragraph_.content_[j].get()); + if (paragraph_element) + { + paragraph_element->xlsx_serialize(_Wostream, Context); + } + else + { + CP_SERIALIZE_TEXT(content_[i], true); + } + } + } else { CP_SERIALIZE_TEXT(content_[i], true); } - } + } } // text:notes-configuration //------------------------------------------------------------------------------------------------------- @@ -2075,6 +2174,7 @@ void text_linenumbering_configuration::add_attributes(const xml::attributes_wc_p CP_APPLY_ATTR(L"text:number-position", text_number_position_); //inner, left, outer, right CP_APPLY_ATTR(L"text:offset", text_offset_); CP_APPLY_ATTR(L"text:restart-on-page", text_restart_on_page_); + CP_APPLY_ATTR(L"text:start", text_start_); } void text_linenumbering_configuration::add_child_element(xml::sax * Reader, const std::wstring & Ns, const std::wstring & Name) { @@ -2102,6 +2202,10 @@ void text_linenumbering_configuration::docx_serialize(std::wostream & strm, oox: { CP_XML_ATTR(L"w:restart", L"continuous"); } + if (text_start_) + { + CP_XML_ATTR(L"w:start", *text_start_); + } if (text_offset_) { CP_XML_ATTR(L"w:distance", 20. * text_offset_->get_value_unit(length::pt)); diff --git a/OdfFile/Reader/Format/styles.h b/OdfFile/Reader/Format/styles.h index 8b78ced093c..46a935ba779 100644 --- a/OdfFile/Reader/Format/styles.h +++ b/OdfFile/Reader/Format/styles.h @@ -93,6 +93,7 @@ class style_content : noncopyable graphic_format_properties* get_graphic_properties()const; style_text_properties* get_style_text_properties() const; + style_text_properties* get_style_text_properties(bool create); style_paragraph_properties* get_style_paragraph_properties()const; style_table_properties* get_style_table_properties()const; style_section_properties* get_style_section_properties()const; @@ -676,6 +677,8 @@ class style_columns : public office_element_impl static const ElementType type = typeStyleColumns; CPDOCCORE_DEFINE_VISITABLE(); + virtual void pptx_convert(oox::pptx_conversion_context& Context); + private: virtual void add_attributes( const xml::attributes_wc_ptr & Attributes ); virtual void add_child_element( xml::sax * Reader, const std::wstring & Ns, const std::wstring & Name); @@ -967,6 +970,8 @@ class style_page_layout_properties : public office_element_impl(val.get()); + text_list_level_style_bullet* style_bullet_ptr = dynamic_cast(val.get()); + + if (style_number_ptr) + { + boost::shared_ptr style_number = boost::make_shared(*style_number_ptr); + content_.push_back(style_number); + } + else if (style_bullet_ptr) + { + boost::shared_ptr style_bullet = boost::make_shared(*style_bullet_ptr); + content_.push_back(style_bullet); + } + } +} + void text_list_style::add_attributes( const xml::attributes_wc_ptr & Attributes ) { attr_.add_attributes(Attributes); @@ -94,6 +123,11 @@ void text_list_level_style_attr::add_attributes( const xml::attributes_wc_ptr & CP_APPLY_ATTR(L"text:level", text_level_, (unsigned int)0); } +void text_list_level_style_attr::apply_from(const text_list_level_style_attr& Other) +{ + text_level_ = Other.text_level_; +} + // text_list_level_style_number_attr ////////////////////////////////////////////////////////////////////////////////////////////////// @@ -106,6 +140,17 @@ void text_list_level_style_number_attr::add_attributes( const xml::attributes_wc CP_APPLY_ATTR(L"text:start-value", text_start_value_, (unsigned int)1); } +void text_list_level_style_number_attr::apply_from(const text_list_level_style_number_attr& Other) +{ + _CP_APPLY_PROP(text_style_name_, Other.text_style_name_); + + common_num_format_attlist_.apply_from(Other.common_num_format_attlist_); + common_num_format_prefix_suffix_attlist_.apply_from(Other.common_num_format_prefix_suffix_attlist_); + + text_display_levels_ = Other.text_display_levels_; + text_start_value_ = Other.text_start_value_; +} + // text_list_level_style_bullet_attr ////////////////////////////////////////////////////////////////////////////////////////////////// @@ -117,6 +162,14 @@ void text_list_level_style_bullet_attr::add_attributes( const xml::attributes_wc CP_APPLY_ATTR(L"text:bullet-relative-size", text_bullet_relative_size_); } +void text_list_level_style_bullet_attr::apply_from(const text_list_level_style_bullet_attr& Other) +{ + _CP_APPLY_PROP2(text_style_name_); + _CP_APPLY_PROP2(text_bullet_char_); + common_num_format_prefix_suffix_attlist_.apply_from(Other.common_num_format_prefix_suffix_attlist_); + _CP_APPLY_PROP2(text_bullet_relative_size_); +} + // text_list_level_style_image_attr ////////////////////////////////////////////////////////////////////////////////////////////////// @@ -131,10 +184,19 @@ void text_list_level_style_image_attr::add_attributes( const xml::attributes_wc_ const wchar_t * text_list_level_style_number::ns = L"text"; const wchar_t * text_list_level_style_number::name = L"list-level-style-number"; +text_list_level_style_number::text_list_level_style_number(const text_list_level_style_number& other) +{ + attr_.apply_from(other.attr_); + number_attr_.apply_from(other.number_attr_); + + list_level_properties_ = other.list_level_properties_; + text_properties_ = other.text_properties_; +} + void text_list_level_style_number::add_attributes( const xml::attributes_wc_ptr & Attributes ) { - text_list_level_style_attr_.add_attributes(Attributes); - text_list_level_style_number_attr_.add_attributes(Attributes); + attr_.add_attributes(Attributes); + number_attr_.add_attributes(Attributes); } void text_list_level_style_number::add_child_element(xml::sax * Reader, const std::wstring & Ns, const std::wstring & Name) @@ -149,7 +211,7 @@ void text_list_level_style_number::add_child_element(xml::sax * Reader, const st } else if (L"style" == Ns && L"text-properties" == Name) { - CP_CREATE_ELEMENT(style_text_properties_); + CP_CREATE_ELEMENT(text_properties_); } else { @@ -164,8 +226,8 @@ const wchar_t * text_list_level_style_image::name = L"list-level-style-image"; void text_list_level_style_image::add_attributes( const xml::attributes_wc_ptr & Attributes ) { - text_list_level_style_attr_.add_attributes(Attributes); - text_list_level_style_image_attr_.add_attributes(Attributes); + attr_.add_attributes(Attributes); + image_attr_.add_attributes(Attributes); } void text_list_level_style_image::add_child_element( xml::sax * Reader, const std::wstring & Ns, const std::wstring & Name) @@ -180,7 +242,7 @@ void text_list_level_style_image::add_child_element( xml::sax * Reader, const st } else if (L"style" == Ns && L"text-properties" == Name) { - CP_CREATE_ELEMENT(style_text_properties_); + CP_CREATE_ELEMENT(text_properties_); } else { @@ -243,10 +305,16 @@ void style_list_level_label_alignment::add_child_element( xml::sax * Reader, con const wchar_t * text_list_level_style_bullet::ns = L"text"; const wchar_t * text_list_level_style_bullet::name = L"list-level-style-bullet"; +text_list_level_style_bullet::text_list_level_style_bullet(const text_list_level_style_bullet& other) +{ + attr_.apply_from(other.attr_); + bullet_attr_.apply_from(other.bullet_attr_); +} + void text_list_level_style_bullet::add_attributes( const xml::attributes_wc_ptr & Attributes ) { - text_list_level_style_attr_.add_attributes(Attributes); - text_list_level_style_bullet_attr_.add_attributes(Attributes); + attr_.add_attributes(Attributes); + bullet_attr_.add_attributes(Attributes); } void text_list_level_style_bullet::add_child_element( xml::sax * Reader, const std::wstring & Ns, const std::wstring & Name) @@ -261,7 +329,7 @@ void text_list_level_style_bullet::add_child_element( xml::sax * Reader, const s } else if (L"style" == Ns && L"text-properties" == Name) { - CP_CREATE_ELEMENT(style_text_properties_); + CP_CREATE_ELEMENT(text_properties_); } else { @@ -348,7 +416,7 @@ void docx_serialize_level_justification(std::wostream & strm, style_list_level_p } void text_list_level_style_number::docx_convert(oox::docx_conversion_context & Context) { - if (text_list_level_style_attr_.get_text_level() - 1 > 10) + if (attr_.get_text_level() - 1 > 10) return; std::wostream & strm = Context.output_stream(); @@ -361,21 +429,21 @@ void text_list_level_style_number::docx_convert(oox::docx_conversion_context & C { CP_XML_NODE(L"w:lvl") { - CP_XML_ATTR(L"w:ilvl",(text_list_level_style_attr_.get_text_level() - 1)); + CP_XML_ATTR(L"w:ilvl",(attr_.get_text_level() - 1)); CP_XML_NODE(L"w:start") { - CP_XML_ATTR(L"w:val",text_list_level_style_number_attr_.text_start_value_); + CP_XML_ATTR(L"w:val", number_attr_.text_start_value_); } - if ((text_list_level_style_number_attr_.common_num_format_attlist_.style_num_format_) && - (text_list_level_style_number_attr_.common_num_format_attlist_.style_num_format_->get_type() != style_numformat::none)) + if ((number_attr_.common_num_format_attlist_.style_num_format_) && + (number_attr_.common_num_format_attlist_.style_num_format_->get_type() != style_numformat::none)) { CP_XML_NODE(L"w:numFmt") { std::wstring num_format = L"arabic"; { - switch(text_list_level_style_number_attr_.common_num_format_attlist_.style_num_format_->get_type()) + switch(number_attr_.common_num_format_attlist_.style_num_format_->get_type()) { case style_numformat::romanUc: num_format= L"upperRoman"; break; case style_numformat::romanLc: num_format= L"lowerRoman"; break; @@ -419,15 +487,15 @@ void text_list_level_style_number::docx_convert(oox::docx_conversion_context & C } std::wstring w_lvlText; - w_lvlText += text_list_level_style_number_attr_.common_num_format_prefix_suffix_attlist_.style_num_prefix_.get_value_or(L""); + w_lvlText += number_attr_.common_num_format_prefix_suffix_attlist_.style_num_prefix_.get_value_or(L""); //////////////////////////////////////////////////// - const unsigned int displayLevels = text_list_level_style_number_attr_.text_display_levels_; - const unsigned int textLevel = text_list_level_style_attr_.get_text_level(); + const unsigned int displayLevels = number_attr_.text_display_levels_; + const unsigned int textLevel = attr_.get_text_level(); w_lvlText += GetLevelText(displayLevels, textLevel, Context); - w_lvlText += text_list_level_style_number_attr_.common_num_format_prefix_suffix_attlist_.style_num_suffix_.get_value_or(L""); + w_lvlText += number_attr_.common_num_format_prefix_suffix_attlist_.style_num_suffix_.get_value_or(L""); if (!w_lvlText.empty()) { @@ -453,7 +521,7 @@ void text_list_level_style_number::docx_convert(oox::docx_conversion_context & C double minLabelDistanceTwip = 0.0; if (listLevelProperties && - text_list_level_style_number_attr_.common_num_format_attlist_.style_num_format_ && + number_attr_.common_num_format_attlist_.style_num_format_ && listLevelProperties->text_min_label_distance_) { minLabelDistanceTwip = 20.0 * listLevelProperties->text_min_label_distance_->get_value_unit(length::pt); @@ -497,7 +565,7 @@ void text_list_level_style_number::docx_convert(oox::docx_conversion_context & C } } - if (style_text_properties * textProperties = dynamic_cast(style_text_properties_.get())) + if (style_text_properties * textProperties = dynamic_cast(text_properties_.get())) { Context.get_styles_context().start(); //to style_context @@ -511,7 +579,7 @@ void text_list_level_style_number::docx_convert(oox::docx_conversion_context & C void text_list_level_style_number::pptx_convert(oox::pptx_conversion_context & Context) { - if (text_list_level_style_attr_.get_text_level() - 1 > 10) + if (attr_.get_text_level() - 1 > 10) return; std::wostream & strm = Context.get_text_context().get_styles_context().list_style(); @@ -525,10 +593,10 @@ void text_list_level_style_number::pptx_convert(oox::pptx_conversion_context & C std::wstring num_format; - if ((text_list_level_style_number_attr_.common_num_format_attlist_.style_num_format_ ) && - (text_list_level_style_number_attr_.common_num_format_attlist_.style_num_format_->get_type() != style_numformat::none)) + if ((number_attr_.common_num_format_attlist_.style_num_format_ ) && + (number_attr_.common_num_format_attlist_.style_num_format_->get_type() != style_numformat::none)) { - switch(text_list_level_style_number_attr_.common_num_format_attlist_.style_num_format_->get_type()) + switch(number_attr_.common_num_format_attlist_.style_num_format_->get_type()) { case style_numformat::romanUc: num_format= L"romanUc"; break; case style_numformat::romanLc: num_format= L"romanLc"; break; @@ -538,15 +606,15 @@ void text_list_level_style_number::pptx_convert(oox::pptx_conversion_context & C default: num_format= L"arabic"; break; } - if (text_list_level_style_number_attr_.common_num_format_prefix_suffix_attlist_.style_num_prefix_) + if (number_attr_.common_num_format_prefix_suffix_attlist_.style_num_prefix_) { num_format += L"ParenBoth"; } else { - if (text_list_level_style_number_attr_.common_num_format_prefix_suffix_attlist_.style_num_suffix_) + if (number_attr_.common_num_format_prefix_suffix_attlist_.style_num_suffix_) { - if (*text_list_level_style_number_attr_.common_num_format_prefix_suffix_attlist_.style_num_suffix_ == L".") + if (*number_attr_.common_num_format_prefix_suffix_attlist_.style_num_suffix_ == L".") num_format += L"Period"; else num_format += L"ParenR"; @@ -558,7 +626,7 @@ void text_list_level_style_number::pptx_convert(oox::pptx_conversion_context & C CP_XML_WRITER(strm) { - if (style_text_properties * textProperties = dynamic_cast(style_text_properties_.get()))///эти свойства относятся + if (style_text_properties * textProperties = dynamic_cast(text_properties_.get()))///эти свойства относятся // к отрисовки значков !!! а не самого текста { textProperties->content_.pptx_convert_as_list(Context); @@ -568,7 +636,7 @@ void text_list_level_style_number::pptx_convert(oox::pptx_conversion_context & C { CP_XML_NODE(L"a:buAutoNum")//ms козлы !! для них оказыается ВАЖЕН порядок .. если записать это поле первым, а потом свойства - нихера в мс2010 не отображается верно !!! { - CP_XML_ATTR(L"startAt",text_list_level_style_number_attr_.text_start_value_); + CP_XML_ATTR(L"startAt", number_attr_.text_start_value_); CP_XML_ATTR(L"type", num_format); } } @@ -611,7 +679,7 @@ std::wstring convert_bullet_char(std::wstring c) void text_list_level_style_bullet::docx_convert(oox::docx_conversion_context & Context) { - if (text_list_level_style_attr_.get_text_level() - 1 > 10) + if (attr_.get_text_level() - 1 > 10) return; std::wostream & strm = Context.output_stream(); @@ -624,7 +692,7 @@ void text_list_level_style_bullet::docx_convert(oox::docx_conversion_context & C { CP_XML_NODE(L"w:lvl") { - CP_XML_ATTR(L"w:ilvl",(text_list_level_style_attr_.get_text_level() - 1)); + CP_XML_ATTR(L"w:ilvl", (attr_.get_text_level() - 1)); CP_XML_NODE(L"w:numFmt"){CP_XML_ATTR(L"w:val",L"bullet");} if ((labelAlignment) && (labelAlignment->text_label_followed_by_)) @@ -635,7 +703,7 @@ void text_list_level_style_bullet::docx_convert(oox::docx_conversion_context & C } } - std::wstring bullet = text_list_level_style_bullet_attr_.text_bullet_char_.get_value_or(L"\x2022"); + std::wstring bullet = bullet_attr_.text_bullet_char_.get_value_or(L"\x2022"); CP_XML_NODE(L"w:lvlText") { std::wstring out = convert_bullet_char(bullet); @@ -696,7 +764,7 @@ void text_list_level_style_bullet::docx_convert(oox::docx_conversion_context & C } } - if (style_text_properties * textProperties = dynamic_cast(style_text_properties_.get())) + if (style_text_properties * textProperties = dynamic_cast(text_properties_.get())) { Context.get_styles_context().start(); textProperties->content_.docx_convert(Context); @@ -709,7 +777,7 @@ void text_list_level_style_bullet::docx_convert(oox::docx_conversion_context & C void text_list_level_style_bullet::pptx_convert(oox::pptx_conversion_context & Context) { - if (text_list_level_style_attr_.get_text_level() - 1 > 10) + if (attr_.get_text_level() - 1 > 10) return; std::wostream & strm = Context.get_text_context().get_styles_context().list_style(); @@ -723,8 +791,8 @@ void text_list_level_style_bullet::pptx_convert(oox::pptx_conversion_context & C CP_XML_WRITER(strm) { - style_text_properties * textProperties = dynamic_cast(style_text_properties_.get()); - std::wstring bullet = text_list_level_style_bullet_attr_.text_bullet_char_.get_value_or(L"\x2022"); + style_text_properties * textProperties = dynamic_cast(text_properties_.get()); + std::wstring bullet = bullet_attr_.text_bullet_char_.get_value_or(L"\x2022"); if (textProperties)///эти свойства относятся // к отрисовки значков !!! а не самого текста @@ -744,11 +812,9 @@ void text_list_level_style_bullet::pptx_convert(oox::pptx_conversion_context & C } } - - void text_list_level_style_image::docx_convert(oox::docx_conversion_context & Context) { - if (text_list_level_style_attr_.get_text_level() - 1 > 10) + if (attr_.get_text_level() - 1 > 10) return; std::wostream & strm = Context.output_stream(); @@ -761,7 +827,7 @@ void text_list_level_style_image::docx_convert(oox::docx_conversion_context & Co { CP_XML_NODE(L"w:lvl") { - CP_XML_ATTR(L"w:ilvl",(text_list_level_style_attr_.get_text_level() - 1)); + CP_XML_ATTR(L"w:ilvl", attr_.get_text_level() - 1); CP_XML_NODE(L"w:numFmt"){CP_XML_ATTR(L"w:val",L"bullet");} if ((labelAlignment) && (labelAlignment->text_label_followed_by_)) @@ -832,7 +898,7 @@ void text_list_level_style_image::docx_convert(oox::docx_conversion_context & Co } } - if (style_text_properties * textProperties = dynamic_cast(style_text_properties_.get())) + if (style_text_properties * textProperties = dynamic_cast(text_properties_.get())) { Context.get_styles_context().start(); textProperties->content_.docx_convert(Context); @@ -845,7 +911,7 @@ void text_list_level_style_image::docx_convert(oox::docx_conversion_context & Co void text_list_level_style_image::pptx_convert(oox::pptx_conversion_context & Context) { - if (text_list_level_style_attr_.get_text_level() - 1 > 10) + if (attr_.get_text_level() - 1 > 10) return; std::wostream & strm = Context.get_text_context().get_styles_context().list_style(); @@ -859,7 +925,7 @@ void text_list_level_style_image::pptx_convert(oox::pptx_conversion_context & Co CP_XML_WRITER(strm) { - style_text_properties * textProperties = dynamic_cast(style_text_properties_.get()); + style_text_properties * textProperties = dynamic_cast(text_properties_.get()); wchar_t bullet = L'\x2022'; if (textProperties)///эти свойства относятся diff --git a/OdfFile/Reader/Format/styles_list.h b/OdfFile/Reader/Format/styles_list.h index bc7fb9e720e..c26461e1678 100644 --- a/OdfFile/Reader/Format/styles_list.h +++ b/OdfFile/Reader/Format/styles_list.h @@ -47,6 +47,7 @@ class text_list_style_attr { public: void add_attributes( const xml::attributes_wc_ptr & Attributes ); + void apply_from(const text_list_style_attr& Other); std::wstring style_name_; optional::Type style_display_name_; @@ -58,6 +59,9 @@ class text_list_style_attr class text_list_style : public office_element_impl { public: + text_list_style() = default; + text_list_style(const text_list_style& other); + static const wchar_t * ns; static const wchar_t * name; static const xml::NodeType xml_type = xml::typeElement; @@ -69,25 +73,47 @@ class text_list_style : public office_element_impl virtual void add_child_element( xml::sax * Reader, const std::wstring & Ns, const std::wstring & Name); public: - text_list_style_attr attr_; - office_element_ptr_array content_; + text_list_style_attr attr_; + office_element_ptr_array content_; friend class odf_document; }; - CP_REGISTER_OFFICE_ELEMENT2(text_list_style); +/// text-list-level-style-attr +class text_list_level_style_attr +{ +public: + text_list_level_style_attr() : text_level_(0) {} + void add_attributes(const xml::attributes_wc_ptr& Attributes); + void apply_from(const text_list_level_style_attr& Other); + + unsigned int get_text_level() const { return text_level_; } + +private: + unsigned int text_level_; +}; + +class text_list_level_style +{ +public : + text_list_level_style_attr attr_; + office_element_ptr list_level_properties_; + office_element_ptr text_properties_; +}; + /// text-list-level-style-number-attr class text_list_level_style_number_attr { public: text_list_level_style_number_attr() : text_display_levels_(1), text_start_value_(1) {} void add_attributes( const xml::attributes_wc_ptr & Attributes ); + void apply_from(const text_list_level_style_number_attr& Other); -private: - _CP_OPT(std::wstring) text_style_name_; +public: + _CP_OPT(std::wstring) text_style_name_; - odf_types::common_num_format_attlist common_num_format_attlist_; - odf_types::common_num_format_prefix_suffix_attlist common_num_format_prefix_suffix_attlist_; + odf_types::common_num_format_attlist common_num_format_attlist_; + odf_types::common_num_format_prefix_suffix_attlist common_num_format_prefix_suffix_attlist_; unsigned int text_display_levels_; unsigned int text_start_value_; @@ -95,21 +121,6 @@ class text_list_level_style_number_attr friend class text_list_level_style_number; }; - -/// text-list-level-style-attr -class text_list_level_style_attr -{ -public: - text_list_level_style_attr() : text_level_(0) {} - void add_attributes( const xml::attributes_wc_ptr & Attributes ); - unsigned int get_text_level() const { return text_level_; } - -private: - unsigned int text_level_; - -}; - - /// style:list-level-properties (style-list-level-properties) class style_list_level_properties : public office_element_impl { @@ -141,7 +152,6 @@ class style_list_level_properties : public office_element_impl +class text_list_level_style_number : public office_element_impl, public text_list_level_style { public: static const wchar_t * ns; @@ -180,19 +189,17 @@ class text_list_level_style_number : public office_element_impl +class text_list_level_style_bullet : public office_element_impl, public text_list_level_style { public: static const wchar_t * ns; @@ -224,19 +228,18 @@ class text_list_level_style_bullet : public office_element_impl +class text_list_level_style_image : public office_element_impl, public text_list_level_style { public: static const wchar_t * ns; @@ -269,13 +270,8 @@ class text_list_level_style_image : public office_element_impl CP_REGISTER_OFFICE_ELEMENT2(text_outline_style); // text:outline-level-style -class text_outline_level_style : public office_element_impl +class text_outline_level_style : public office_element_impl, public text_list_level_style { public: static const wchar_t * ns; @@ -314,17 +310,14 @@ class text_outline_level_style : public office_element_implmap_user_defineds.end() ? pFind->second : L""; } +std::wstring doc_props_container::dump_user_defined() +{ + std::wstringstream output; + + CP_XML_WRITER(output) + { + int pid = 2; + for (std::map::iterator it = impl_->map_user_defineds.begin(); it != impl_->map_user_defineds.end(); ++it) + { + CP_XML_NODE(L"property") + { + CP_XML_ATTR(L"fmtid", L"{D5CDD505-2E9C-101B-9397-08002B2CF9AE}"); + CP_XML_ATTR(L"pid", pid++); + CP_XML_ATTR(L"name", XmlUtils::EncodeXmlString(it->first)); + CP_XML_NODE(L"vt:lpwstr") + { + CP_XML_STREAM() << XmlUtils::EncodeXmlString(it->second); + } + } + } + } + return output.str(); +} //---------------------------------------------------------------------------------- struct settings_value @@ -140,6 +164,8 @@ class settings_container::Impl bool inViewTable; bool inView; + _CP_OPT(double) tab_distance_; + std::map map_user_defineds; }; @@ -231,6 +257,17 @@ void settings_container::add_view(const std::wstring & name, const std::wstring impl_->common_view.map_[name] = impl_->common_view.array_.size() - 1; } } + +void settings_container::set_tab_distance(double pt) +{ + impl_->tab_distance_ = pt * 20; +} + +_CP_OPT(double) settings_container::get_tab_distance() +{ + return impl_->tab_distance_; +} + std::pair settings_container::get_table_view(int index_view, const std::wstring & table_name, int index) { std::pair value; diff --git a/OdfFile/Reader/Format/styles_lite_container.h b/OdfFile/Reader/Format/styles_lite_container.h index 3d5dedbb2cb..f3dc13a1350 100644 --- a/OdfFile/Reader/Format/styles_lite_container.h +++ b/OdfFile/Reader/Format/styles_lite_container.h @@ -64,6 +64,7 @@ class doc_props_container void add_user_defined(const std::wstring & name, const std::wstring & value); std::wstring get_user_defined(const std::wstring & name); + std::wstring dump_user_defined(); std::wstring dc_creator_; std::wstring dc_date_; @@ -110,6 +111,9 @@ class settings_container void add_view (const std::wstring & name, const std::wstring & value); + void set_tab_distance(double pt); + _CP_OPT(double) get_tab_distance(); + private: class Impl; _CP_SCOPED_PTR(Impl) impl_; diff --git a/OdfFile/Reader/Format/svg_parser.cpp b/OdfFile/Reader/Format/svg_parser.cpp index 7ae6135e8a6..1239871ab5e 100644 --- a/OdfFile/Reader/Format/svg_parser.cpp +++ b/OdfFile/Reader/Format/svg_parser.cpp @@ -567,6 +567,39 @@ namespace svg_path } }break; + case 'Q': + { + nPos++; + skipSpaces(nPos, rSvgDStatement, nLen); + + while (nPos < nLen && isOnNumberChar(rSvgDStatement, nPos)) + { + double nX, nY; + double nX1, nY1; + + if (!importDoubleAndSpaces(nX1, nPos, rSvgDStatement, nLen)) return false; + if (!importDoubleAndSpaces(nY1, nPos, rSvgDStatement, nLen)) return false; + if (!importDoubleAndSpaces(nX, nPos, rSvgDStatement, nLen)) return false; + if (!importDoubleAndSpaces(nY, nPos, rSvgDStatement, nLen)) return false; + + aCurrPoly.command = L"a:quadBezTo"; + + aCurrPoly.points.push_back(_point(nX1, nY1)); + aCurrPoly.points.push_back(_point(nX, nY)); + + Polyline.push_back(aCurrPoly); + aCurrPoly.points.clear(); + + // set last position + nLastX = nX; + nLastY = nY; + + //keep control point + nLastControlX = nX1; + nLastControlY = nY1; + } + }break; + case 'G': { nPos++; @@ -1100,7 +1133,7 @@ namespace svg_path nY += L"+" + nLastY; } - aCurrPoly.command = L"a:ArcTo"; + aCurrPoly.command = L"a:arcTo"; // append curved edge aCurrPoly.points.push_back(_pointS(nX, nY)); aCurrPoly.points.push_back(_pointS(A1, A2)); diff --git a/OdfFile/Reader/Format/table.cpp b/OdfFile/Reader/Format/table.cpp index b32801a2120..7155a077442 100644 --- a/OdfFile/Reader/Format/table.cpp +++ b/OdfFile/Reader/Format/table.cpp @@ -61,10 +61,13 @@ void table_table_attlist::add_attributes( const xml::attributes_wc_ptr & Attribu CP_APPLY_ATTR(L"table:print", table_print_, true); CP_APPLY_ATTR(L"table:print-ranges", table_print_ranges_); - CP_APPLY_ATTR(L"table:use-first-row-styles", table_use_first_row_styles_,false); - CP_APPLY_ATTR(L"table:use-banding-rows-styles", table_use_banding_rows_styles_,false); - CP_APPLY_ATTR(L"table:use-banding-columns-styles", table_use_banding_columns_styles_,false); - CP_APPLY_ATTR(L"table:use-first-column-styles", table_use_first_column_styles_,false); + + CP_APPLY_ATTR(L"table:use-first-row-styles", table_use_first_row_styles_, false); + CP_APPLY_ATTR(L"table:use-last-row-styles", table_use_last_row_styles_, false); + CP_APPLY_ATTR(L"table:use-banding-rows-styles", table_use_banding_rows_styles_, false); + CP_APPLY_ATTR(L"table:use-last-column-styles", table_use_last_column_styles_, false); + CP_APPLY_ATTR(L"table:use-banding-columns-styles", table_use_banding_columns_styles_, false); + CP_APPLY_ATTR(L"table:use-first-column-styles", table_use_first_column_styles_, false); CP_APPLY_ATTR(L"table:is-sub-table", table_is_sub_table_); } diff --git a/OdfFile/Reader/Format/table.h b/OdfFile/Reader/Format/table.h index 5987f7da4dd..783cb4707ab 100644 --- a/OdfFile/Reader/Format/table.h +++ b/OdfFile/Reader/Format/table.h @@ -67,7 +67,9 @@ class table_table_attlist _CP_OPT(std::wstring) table_print_ranges_; bool table_use_first_row_styles_; // default false; + bool table_use_last_row_styles_; // default false; bool table_use_banding_rows_styles_; // defualt false; + bool table_use_last_column_styles_; // default false; bool table_use_first_column_styles_; // defualt false; bool table_use_banding_columns_styles_; // defualt false; diff --git a/OdfFile/Reader/Format/table_pptx.cpp b/OdfFile/Reader/Format/table_pptx.cpp index b172bbac96a..8689f96959b 100644 --- a/OdfFile/Reader/Format/table_pptx.cpp +++ b/OdfFile/Reader/Format/table_pptx.cpp @@ -67,14 +67,25 @@ void table_table_row::pptx_convert(oox::pptx_conversion_context & Context) { std::wostream & _Wostream = Context.get_table_context().tableData(); - const std::wstring styleName = attlist_.table_style_name_.get_value_or(L""); - const std::wstring defaultCellStyle = attlist_.table_default_cell_style_name_.get_value_or(L""); + const std::wstring styleName = attlist_.table_style_name_.get_value_or(L""); + const std::wstring defaultCellStyle = attlist_.table_default_cell_style_name_.get_value_or(L""); + + std::wstring template_style_name = L""; + + if (Context.get_table_context().template_is_first_row()) + template_style_name = Context.get_table_context().get_first_row_style_name(); + else if (Context.get_table_context().template_is_last_row()) + template_style_name = Context.get_table_context().get_last_row_style_name(); + else if (Context.get_table_context().template_is_odd_row()) + template_style_name = Context.get_table_context().get_odd_rows_style_name(); + + Context.get_table_context().set_template_row_style_name(template_style_name); for (unsigned int i = 0; i < attlist_.table_number_rows_repeated_; ++i) { int height = 0; - const style_instance * inst = Context.root()->odf_context().styleContainer().style_by_name( styleName , style_family::TableRow,false); + const style_instance * inst = Context.root()->odf_context().styleContainer().style_by_name( styleName , style_family::TableRow,true); if ((inst) && (inst->content()) && (inst->content()->get_style_table_row_properties())) { @@ -94,6 +105,7 @@ void table_table_row::pptx_convert(oox::pptx_conversion_context & Context) Context.get_table_context().start_row(styleName, defaultCellStyle); + Context.get_table_context().set_table_columns(content_.size()); for (size_t i = 0; i < content_.size(); i++) { content_[i]->pptx_convert(Context); @@ -127,6 +139,7 @@ void table_rows::pptx_convert(oox::pptx_conversion_context & Context) table_table_rows_->pptx_convert(Context); else { + Context.get_table_context().set_table_rows(table_table_row_.size()); for (size_t i = 0; i < table_table_row_.size(); i++) { table_table_row_[i]->pptx_convert(Context); @@ -174,6 +187,45 @@ void table_table::pptx_convert(oox::pptx_conversion_context & Context) table_body_template* body_ = dynamic_cast(template_->table_body_.get()); Context.get_table_context().set_default_cell_style(body_->table_style_name_); } + if (template_->table_first_row_) + { + table_first_row_template* first_row_ = dynamic_cast(template_->table_first_row_.get()); + Context.get_table_context().set_first_row_style_name(first_row_->table_style_name_); + } + if (template_->table_last_row_) + { + table_last_row_template* last_row_ = dynamic_cast(template_->table_last_row_.get()); + Context.get_table_context().set_last_row_style_name(last_row_->table_style_name_); + } + if (template_->table_odd_rows_) + { + table_odd_rows_template* odd_rows_ = dynamic_cast(template_->table_odd_rows_.get()); + Context.get_table_context().set_odd_rows_style_name(odd_rows_->table_style_name_); + } + if (template_->table_first_column_) + { + table_first_column_template* first_column_ = dynamic_cast(template_->table_first_column_.get()); + Context.get_table_context().set_first_column_style_name(first_column_->table_style_name_); + } + if (template_->table_last_column_) + { + table_last_column_template* last_column = dynamic_cast(template_->table_last_column_.get()); + Context.get_table_context().set_last_column_style_name(last_column->table_style_name_); + } + if (template_->table_odd_columns_) + { + table_odd_columns_template* odd_columns = dynamic_cast(template_->table_odd_columns_.get()); + Context.get_table_context().set_odd_columns_style_name(odd_columns->table_style_name_); + } + + Context.get_table_context().set_template_use_styles( + attlist_.table_use_first_row_styles_, + attlist_.table_use_last_row_styles_, + attlist_.table_use_banding_rows_styles_, + attlist_.table_use_first_column_styles_, + attlist_.table_use_last_column_styles_, + attlist_.table_use_banding_columns_styles_); + } } } @@ -192,7 +244,7 @@ void table_table::pptx_convert(oox::pptx_conversion_context & Context) _Wostream << L" firstCol=\"1\""; _Wostream << ">"; - style_instance * inst = Context.root()->odf_context().styleContainer().style_by_name( tableStyleName , style_family::Table,false); + style_instance * inst = Context.root()->odf_context().styleContainer().style_by_name( tableStyleName , style_family::Table,true); if ((inst) && (inst->content())) { @@ -300,7 +352,8 @@ void table_table_column::pptx_convert(oox::pptx_conversion_context & Context) { const std::wstring colStyleName = attlist_.table_style_name_.get(); - style_instance * inst = Context.root()->odf_context().styleContainer().style_by_name( colStyleName , style_family::TableColumn,false ); + style_instance * inst = Context.root()->odf_context().styleContainer().style_by_name(colStyleName, style_family::TableColumn, true); + if ((inst) && (inst->content())) { //column properies @@ -322,6 +375,16 @@ void table_table_cell::pptx_convert(oox::pptx_conversion_context & Context) for (unsigned int r = 0; r < attlist_.table_number_columns_repeated_; ++r) { Context.get_table_context().start_cell(); + + unsigned int current_col = Context.get_table_context().current_column(); + + if (Context.get_table_context().template_is_first_column()) + Context.get_table_context().set_default_cell_style_col(current_col, Context.get_table_context().get_first_column_style_name()); + else if(Context.get_table_context().template_is_last_column()) + Context.get_table_context().set_default_cell_style_col(current_col, Context.get_table_context().get_last_column_style_name()); + else if (Context.get_table_context().template_is_odd_column()) + Context.get_table_context().set_default_cell_style_col(current_col, Context.get_table_context().get_odd_column_style_name()); + CP_XML_NODE(L"a:tc") { std::vector style_instances; @@ -333,25 +396,37 @@ void table_table_cell::pptx_convert(oox::pptx_conversion_context & Context) style_name = Context.get_table_context().get_default_cell_style(); if (!style_name.empty()) { - style_inst = Context.root()->odf_context().styleContainer().style_by_name(style_name, style_family::TableCell, false); + style_inst = Context.root()->odf_context().styleContainer().style_by_name(style_name, style_family::TableCell, true); if (style_inst) style_instances.push_back(style_inst); } + style_name = Context.get_table_context().get_default_cell_style_col(Context.get_table_context().current_column()); if (!style_name.empty()) { - style_inst = Context.root()->odf_context().styleContainer().style_by_name(style_name, style_family::TableCell, false); + style_inst = Context.root()->odf_context().styleContainer().style_by_name(style_name, style_family::TableCell, true); if (style_inst)style_instances.push_back(style_inst); } - style_name = Context.get_table_context().get_default_cell_style_row(); - if (!style_name.empty()) + style_name = Context.get_table_context().get_template_row_style_name(); + if (!style_name.empty() && !Context.get_table_context().template_is_first_column() && !Context.get_table_context().template_is_last_column()) { - style_inst = Context.root()->odf_context().styleContainer().style_by_name(style_name, style_family::TableCell, false); - if (style_inst) style_instances.push_back(style_inst); + style_inst = Context.root()->odf_context().styleContainer().style_by_name(style_name, style_family::TableCell, true); + if (style_inst)style_instances.push_back(style_inst); + } + + if (!attlist_.table_style_name_.has_value()) + { + style_name = Context.get_table_context().get_default_cell_style_row(); + if (!style_name.empty()) + { + style_inst = Context.root()->odf_context().styleContainer().style_by_name(style_name, style_family::TableCell, true); + if (style_inst) style_instances.push_back(style_inst); + } } + style_name = attlist_.table_style_name_.get_value_or(L""); if (!style_name.empty()) { - style_inst = Context.root()->odf_context().styleContainer().style_by_name(style_name, style_family::TableCell, false); + style_inst = Context.root()->odf_context().styleContainer().style_by_name(style_name, style_family::TableCell, true); if (style_inst) style_instances.push_back(style_inst); } diff --git a/OdfFile/Reader/Format/table_xlsx.cpp b/OdfFile/Reader/Format/table_xlsx.cpp index 0ad14882098..584f74fd8cb 100644 --- a/OdfFile/Reader/Format/table_xlsx.cpp +++ b/OdfFile/Reader/Format/table_xlsx.cpp @@ -62,18 +62,18 @@ int table_table_cell_content::xlsx_convert(oox::xlsx_conversion_context & Contex if (elements_.empty()) return -1; Context.get_table_context().start_cell_content(); - Context.get_text_context().set_cell_text_properties(text_properties); + Context.get_text_context()->set_cell_text_properties(text_properties); for (size_t i = 0 ; i < elements_.size(); i++) { elements_[i]->xlsx_convert(Context); if ((i < elements_.size() - 1) && (elements_[i + 1]->get_type() == typeTextP)) { - Context.get_text_context().start_paragraph(L""); - Context.get_text_context().start_span(L""); - Context.get_text_context().add_text(L"\n"); - Context.get_text_context().end_span(); - Context.get_text_context().end_paragraph(); + Context.get_text_context()->start_paragraph(L""); + Context.get_text_context()->start_span(L""); + Context.get_text_context()->add_text(L"\n"); + Context.get_text_context()->end_span(); + Context.get_text_context()->end_paragraph(); } } @@ -193,7 +193,9 @@ void table_table_row::xlsx_convert(oox::xlsx_conversion_context & Context) { //std::wstring str_spans = std::to_wstring(Context.get_table_context().state()->group_row_.count); //str_spans = str_spans + L":"; - std::wstring str_spans = L"1:" + std::to_wstring(Context.get_table_context().columns_count()); + int columns = Context.get_table_context().columns_count(); + if (columns > 0x4000) columns = 0x4000; + std::wstring str_spans = L"1:" + std::to_wstring(columns); ht = L""; CP_XML_ATTR(L"collapsed", Context.get_table_context().state()->group_rows_.back()); @@ -333,8 +335,8 @@ void table_table_row_group::xlsx_convert(oox::xlsx_conversion_context & Context) void table_table::xlsx_convert(oox::xlsx_conversion_context & Context) { - const std::wstring tableStyleName = attlist_.table_style_name_.get_value_or(L""); - const std::wstring tableName = attlist_.table_name_.get_value_or(L""); + std::wstring tableStyleName = attlist_.table_style_name_.get_value_or(L""); + std::wstring tableName = attlist_.table_name_.get_value_or(L""); _CP_LOG << L"[info][xlsx] process table \"" << tableName << L"\"\n" << std::endl; @@ -343,16 +345,30 @@ void table_table::xlsx_convert(oox::xlsx_conversion_context & Context) office_forms_->xlsx_convert(Context); } + std::wstring externalRef; + std::wstring externalRef2; + if (table_table_source_) { table_table_source* table_source = dynamic_cast( table_table_source_.get() ); if ( table_source) { - if (table_source->table_linked_source_attlist_.xlink_attlist_.href_)return; - } + if (table_source->table_linked_source_attlist_.xlink_attlist_.href_) + { + externalRef = *table_source->table_linked_source_attlist_.xlink_attlist_.href_; + } + if (table_source->attlist_.table_table_name_) + { + externalRef2 = tableName; // - used in formula + tableName = *table_source->attlist_.table_table_name_; // - only link to file + size_t pos = externalRef2.find(L"#"); + if (pos != std::wstring::npos) externalRef2 = externalRef2.substr(0, pos); + XmlUtils::replace_all(externalRef2, L"'", L""); + } + } } - Context.start_table(tableName, tableStyleName); + Context.start_table(tableName, tableStyleName, externalRef2); if (attlist_.table_protected_) { @@ -555,26 +571,29 @@ void table_table_column::xlsx_convert(oox::xlsx_conversion_context & Context) CP_XML_ATTR(L"customWidth", true); Context.table_column_last_width(*width); } - else if (prop->attlist_.style_column_width_) + if (prop->attlist_.style_column_width_) { pt_width = prop->attlist_.style_column_width_->get_value_unit(length::pt); cm_width = prop->attlist_.style_column_width_->get_value_unit(length::cm); in_width = prop->attlist_.style_column_width_->get_value_unit(length::inch); - if (hidden) - { - in_width = 0.0; - } - - const double pixDpi = in_width * 96.; - width = pixToSize(pixDpi, Context.getMaxDigitSize().first); + if (!width) + { + if (hidden) + { + in_width = 0.0; + } + + const double pixDpi = in_width * 96.; + width = pixToSize(pixDpi, Context.getMaxDigitSize().first); - // see ECMA-376 page 1768 - if (in_width > 0) - CP_XML_ATTR(L"width", *width); + // see ECMA-376 page 1768 + if (in_width > 0) + CP_XML_ATTR(L"width", *width); - CP_XML_ATTR(L"customWidth", true); - Context.table_column_last_width(*width); + CP_XML_ATTR(L"customWidth", true); + Context.table_column_last_width(*width); + } } if ((prop->attlist_.common_break_attlist_.fo_break_before_) && (prop->attlist_.common_break_attlist_.fo_break_before_->get_type() == odf_types::fo_break::Page)) @@ -600,8 +619,11 @@ void table_table_column::xlsx_convert(oox::xlsx_conversion_context & Context) } // col } // CP_XML_WRITER - + if (pt_width < 1) + { + pt_width = 2.26 * 28.34467120181406; // 2.26 cm default + } Context.get_table_metrics().add_cols(cMax - cMin, pt_width); Context.end_table_column(); } @@ -691,7 +713,9 @@ std::wstring CalcCellDataStyle(oox::xlsx_conversion_context & Context, void table_table_cell::xlsx_convert(oox::xlsx_conversion_context & Context) { - std::wostream & strm = Context.current_sheet().sheetData(); + bool bExternalTable = !Context.current_sheet().external_ref().empty(); + + std::wostream & strm = Context.current_sheet().sheetData(); const common_value_and_type_attlist & attr = attlist_.common_value_and_type_attlist_; std::wstring formula = attlist_.table_formula_.get_value_or(L""); @@ -916,30 +940,34 @@ void table_table_cell::xlsx_convert(oox::xlsx_conversion_context & Context) num_format.clear(); num_format_type = office_value_type::String; } -//---------------------------------------------------------------------------------------------------------------------------------- - oox::xlsx_cell_format cellFormat; - - cellFormat.set_cell_type(xlsx_value_type); - cellFormat.set_num_format(oox::odf_string_to_build_in(odf_value_type)); - + //---------------------------------------------------------------------------------------------------------------------------------- bool is_style_visible = (!cellStyleName.empty() || defaultColumnCellStyle || !num_format.empty()) ? true : false; + if (is_AligmentWrap_) + { + is_style_visible = true; + cellFormatProperties.fo_wrap_option_ = odf_types::wrap_option::Wrap; + } + if (bExternalTable) + { + is_style_visible = false; + xlsx_value_type = oox::XlsxCellType::str; + } + oox::xlsx_cell_format cellFormat; + cellFormat.set_cell_type(xlsx_value_type); + cellFormat.set_num_format(oox::odf_string_to_build_in(odf_value_type)); + bool is_data_visible = ( false == content_.elements_.empty() || attlist_.table_content_validation_name_ || !formula.empty() || !number_val.empty() || str_val || bool_val ); - if (attlist_.table_number_columns_repeated_ < 199 && last_cell_) last_cell_ = false; + if (attlist_.table_number_columns_repeated_ < 199 && last_cell_) last_cell_ = false; - int cell_repeated_max = Context.current_table_column() + attlist_.table_number_columns_repeated_ + 1; + unsigned int cell_repeated_max = Context.current_table_column() + attlist_.table_number_columns_repeated_ + 1; if (cell_repeated_max >= 1024 && cellStyleName.empty() && last_cell_ && !is_data_visible) {//Book 24.ods return; } - if (is_AligmentWrap_) - { - is_style_visible = true; - cellFormatProperties.fo_wrap_option_ = odf_types::wrap_option::Wrap; - } size_t xfId_last_set = 0; if (is_style_visible) { @@ -964,12 +992,22 @@ void table_table_cell::xlsx_convert(oox::xlsx_conversion_context & Context) for (unsigned int r = 0; r < attlist_.table_number_columns_repeated_; ++r) { - Context.start_table_cell ( formula, attlist_extra_.table_number_columns_spanned_ - 1 , - attlist_extra_.table_number_rows_spanned_ - 1 ); + Context.start_table_cell ( attlist_extra_.table_number_columns_spanned_ - 1 , + attlist_extra_.table_number_rows_spanned_ - 1 ); if (is_style_visible) Context.set_current_cell_style_id(xfId_last_set); //--------------------------------------------------------------------------------------------------------- - sharedStringId = content_.xlsx_convert(Context, textFormatProperties, need_cache_convert); + if (bExternalTable) + { + std::wstringstream str; + content_.text_to_stream(str); + str_val = str.str(); + } + else + { + sharedStringId = content_.xlsx_convert(Context, textFormatProperties, need_cache_convert); + } + if (xlsx_value_type == oox::XlsxCellType::str || xlsx_value_type == oox::XlsxCellType::inlineStr) { @@ -1007,16 +1045,19 @@ void table_table_cell::xlsx_convert(oox::xlsx_conversion_context & Context) } CP_XML_WRITER(strm) { - CP_XML_NODE(L"c") + CP_XML_NODE(bExternalTable ? L"cell" : L"c") { CP_XML_ATTR(L"r", ref); - CP_XML_ATTR(L"s", xfId_last_set); + if (false == bExternalTable) + { + CP_XML_ATTR(L"s", xfId_last_set); + } std::wstring type = oox::cellType2Str(xlsx_value_type); if (false == type.empty()) CP_XML_ATTR(L"t", type); - if (!formula.empty()) + if (false == bExternalTable && false == formula.empty()) { const std::wstring xlsxFormula = formulas_converter.convert(formula); if (!xlsxFormula.empty()) @@ -1084,6 +1125,8 @@ void table_table_cell::xlsx_convert(oox::xlsx_conversion_context & Context) void table_covered_table_cell::xlsx_convert(oox::xlsx_conversion_context & Context) { + bool bExternalTable = !Context.current_sheet().external_ref().empty(); + std::wostream & strm = Context.current_sheet().sheetData(); const common_value_and_type_attlist & attr = attlist_.common_value_and_type_attlist_; @@ -1153,9 +1196,9 @@ void table_covered_table_cell::xlsx_convert(oox::xlsx_conversion_context & Conte instances.push_back(cellStyle); } - text_format_properties_ptr textFormatProperties = calc_text_properties_content (instances); - paragraph_format_properties parFormatProperties = calc_paragraph_properties_content (instances); - style_table_cell_properties_attlist cellFormatProperties = calc_table_cell_properties (instances); + text_format_properties_ptr textFormatProperties = calc_text_properties_content (instances); + paragraph_format_properties parFormatProperties = calc_paragraph_properties_content (instances); + style_table_cell_properties_attlist cellFormatProperties = calc_table_cell_properties (instances); if (attr.office_value_type_) odf_value_type = attr.office_value_type_->get_type(); @@ -1258,14 +1301,18 @@ void table_covered_table_cell::xlsx_convert(oox::xlsx_conversion_context & Conte } } } - - oox::xlsx_cell_format cellFormat; + is_style_visible = (!cellStyleName.empty() || defaultColumnCellStyle) ? true : false; + if (bExternalTable) + { + is_style_visible = false; + xlsx_value_type = oox::XlsxCellType::inlineStr; + } + + oox::xlsx_cell_format cellFormat; cellFormat.set_cell_type(xlsx_value_type); cellFormat.set_num_format(oox::odf_string_to_build_in(odf_value_type)); - - is_style_visible = (!cellStyleName.empty() || defaultColumnCellStyle) ? true : false; - + if ( content_.elements_.size() > 0 || attlist_.table_content_validation_name_ || !formula.empty() || ( xlsx_value_type == oox::XlsxCellType::n && !number_val.empty()) || @@ -1302,7 +1349,7 @@ void table_covered_table_cell::xlsx_convert(oox::xlsx_conversion_context & Conte if (xlsx_value_type == oox::XlsxCellType::str && sharedStringId >= 0) xlsx_value_type = oox::XlsxCellType::s;//в случае текста, если он есть берем кэшированное значение - if (skip_next_cell)break; + if (skip_next_cell) break; // пустые ячейки пропускаем. if ( is_data_visible || ((cellStyle || defaultColumnCellStyle) && is_style_visible)) @@ -1393,12 +1440,12 @@ void table_content_validation::xlsx_convert(oox::xlsx_conversion_context & Conte { table_error_message* error = dynamic_cast(content_[i].get()); - Context.get_text_context().start_only_text(); + Context.get_text_context()->start_only_text(); for (size_t j = 0 ; j < error->content_.size(); j++) { error->content_[j]->xlsx_convert(Context); } - std::wstring content = Context.get_text_context().end_only_text(); + std::wstring content = Context.get_text_context()->end_only_text(); Context.get_dataValidations_context().add_error_msg(name, error->table_title_.get_value_or(L""), content, error->table_display_ ? error->table_display_->get() : true, @@ -1408,12 +1455,12 @@ void table_content_validation::xlsx_convert(oox::xlsx_conversion_context & Conte { table_help_message* help = dynamic_cast(content_[i].get()); - Context.get_text_context().start_only_text(); + Context.get_text_context()->start_only_text(); for (size_t j = 0 ; j < help->content_.size(); j++) { help->content_[j]->xlsx_convert(Context); } - std::wstring content = Context.get_text_context().end_only_text(); + std::wstring content = Context.get_text_context()->end_only_text(); Context.get_dataValidations_context().add_help_msg(name, help->table_title_.get_value_or(L""), content, help->table_display_ ? help->table_display_->get() : true); diff --git a/OdfFile/Reader/Format/text_content.cpp b/OdfFile/Reader/Format/text_content.cpp index efe94ab2191..f140e31d610 100644 --- a/OdfFile/Reader/Format/text_content.cpp +++ b/OdfFile/Reader/Format/text_content.cpp @@ -60,6 +60,10 @@ void paragraph_attrs::add_attributes( const xml::attributes_wc_ptr & Attributes text_cond_style_name_ = Attributes->get_val< std::wstring >(L"text:cond-style-name").get_value_or(L""); + xml_id_ = Attributes->get_val< std::wstring >(L"xml:id").get_value_or(L""); + if(!xml_id_) + xml_id_ = Attributes->get_val< std::wstring >(L"text:id").get_value_or(L""); + } diff --git a/OdfFile/Reader/Format/text_content.h b/OdfFile/Reader/Format/text_content.h index 502c4f2168d..81acdcb595d 100644 --- a/OdfFile/Reader/Format/text_content.h +++ b/OdfFile/Reader/Format/text_content.h @@ -64,6 +64,7 @@ class paragraph_attrs std::wstring text_cond_style_name_; _CP_OPT(int) outline_level_; + _CP_OPT(std::wstring) xml_id_; }; diff --git a/OdfFile/Reader/Format/text_elements.cpp b/OdfFile/Reader/Format/text_elements.cpp index 30eb2c3b83e..8e4677f9d78 100644 --- a/OdfFile/Reader/Format/text_elements.cpp +++ b/OdfFile/Reader/Format/text_elements.cpp @@ -252,6 +252,50 @@ size_t paragraph::drop_cap_docx_convert(oox::docx_conversion_context & Context) } return index; } + +void paragraph::process_list_bullet_style(oox::docx_conversion_context& Context) +{ + if (content_.size() <= 0) + return; + + span* first_span = dynamic_cast(content_[0].get()); + if (!first_span) + return; + + style_instance* span_style = Context.root()->odf_context().styleContainer().style_by_name(first_span->text_style_name_, style_family::Text, false); + if (!span_style) + return; + + style_content* span_style_content = span_style->content(); + if (!span_style_content) + return; + + std::wstringstream ss; + style_text_properties* text_props = span_style_content->get_style_text_properties(); + + if (text_props) + { + if (!attrs_.text_style_name_.empty()) + { + style_instance* paragraph_style = Context.root()->odf_context().styleContainer().style_by_name(attrs_.text_style_name_, style_family::Paragraph, false); + if (paragraph_style && paragraph_style->content()) + { + paragraph_style->content()->get_style_text_properties(true)->content_.apply_from(text_props->content_); + } + } + + const _CP_OPT(odf_types::font_weight)& font_weight = text_props->content_.fo_font_weight_; + const _CP_OPT(odf_types::font_style)& font_style = text_props->content_.fo_font_style_; + + if (font_weight && font_weight->get_type() == odf_types::font_weight::WBold) + ss << ""; + if (font_style && font_style->get_type() == odf_types::font_style::Italic) + ss << ""; + } + + Context.get_text_tracked_context().dumpRPrInsDel_ = ss.str(); +} + void paragraph::docx_convert(oox::docx_conversion_context & Context, _CP_OPT(std::wstring) next_element_style_name) { std::wstring styleName = attrs_.text_style_name_; @@ -347,6 +391,8 @@ void paragraph::docx_convert(oox::docx_conversion_context & Context, _CP_OPT(std } Context.start_paragraph_style(styleName); + + process_list_bullet_style(Context); int textStyle = Context.process_paragraph_attr(&attrs_); @@ -439,13 +485,15 @@ void paragraph::docx_convert(oox::docx_conversion_context & Context, _CP_OPT(std if (next_masterPageName) { - Context.set_master_page_name(*next_masterPageName); - std::wstring masterPageNameLayout = Context.root()->odf_context().pageLayoutContainer().page_layout_name_by_style(*next_masterPageName); - - if (false == masterPageNameLayout.empty()) + if (true == Context.set_master_page_name(*next_masterPageName)) { - Context.remove_page_properties(); - Context.add_page_properties(masterPageNameLayout); + std::wstring masterPageNameLayout = Context.root()->odf_context().pageLayoutContainer().page_layout_name_by_style(*next_masterPageName); + + if (false == masterPageNameLayout.empty()) + { + Context.remove_page_properties(); + Context.add_page_properties(masterPageNameLayout); + } } } } @@ -462,7 +510,10 @@ void paragraph::xlsx_convert(oox::xlsx_conversion_context & Context) void paragraph::pptx_convert(oox::pptx_conversion_context & Context) { Context.get_text_context().start_paragraph(attrs_.text_style_name_); - + + if (attrs_.xml_id_ && attrs_.xml_id_.value() != L"") + Context.get_slide_context().set_id(attrs_.xml_id_.value()); + for (size_t i = 0; i < content_.size(); i++) { content_[i]->pptx_convert(Context); @@ -612,6 +663,7 @@ void list::add_attributes( const xml::attributes_wc_ptr & Attributes ) { style_name_ = Attributes->get_val< std::wstring >(L"text:style-name").get_value_or(L""); continue_numbering_ = Attributes->get_val< bool >(L"text:continue-numbering"); + continue_list_ = Attributes->get_val< std::wstring >(L"text:continue-list"); // TODO } @@ -629,7 +681,7 @@ void list::add_child_element( xml::sax * Reader, const std::wstring & Ns, const void list::docx_convert(oox::docx_conversion_context & Context) { - bool continue_ = continue_numbering_.get_value_or(false); + bool continue_ = continue_numbering_.get_value_or(false) || !continue_list_.get_value_or(L"").empty(); Context.start_list(style_name_, continue_); if (list_header_) diff --git a/OdfFile/Reader/Format/text_elements.h b/OdfFile/Reader/Format/text_elements.h index bea032ab28a..7d35a745793 100644 --- a/OdfFile/Reader/Format/text_elements.h +++ b/OdfFile/Reader/Format/text_elements.h @@ -73,6 +73,8 @@ class paragraph void pptx_convert (oox::pptx_conversion_context & Context) ; size_t drop_cap_docx_convert(oox::docx_conversion_context & Context); + + void process_list_bullet_style(oox::docx_conversion_context& Context); paragraph_attrs attrs_; @@ -179,6 +181,7 @@ class list : public office_element_impl std::wstring style_name_; _CP_OPT(bool) continue_numbering_; + _CP_OPT(std::wstring) continue_list_; office_element_ptr list_header_; office_element_ptr_array list_items_; diff --git a/OdfFile/Test/ExampleFiles/audio.odp b/OdfFile/Test/ExampleFiles/audio.odp new file mode 100644 index 00000000000..d4c98d8a4d5 Binary files /dev/null and b/OdfFile/Test/ExampleFiles/audio.odp differ diff --git a/OdfFile/Test/ExampleFiles/audio.pptx b/OdfFile/Test/ExampleFiles/audio.pptx new file mode 100644 index 00000000000..9f087eaa8b8 Binary files /dev/null and b/OdfFile/Test/ExampleFiles/audio.pptx differ diff --git a/OdfFile/Test/ExampleFiles/entrance.odp b/OdfFile/Test/ExampleFiles/entrance.odp new file mode 100644 index 00000000000..7290230daaa Binary files /dev/null and b/OdfFile/Test/ExampleFiles/entrance.odp differ diff --git a/OdfFile/Test/ExampleFiles/entrance.pptx b/OdfFile/Test/ExampleFiles/entrance.pptx new file mode 100644 index 00000000000..020c477ca18 Binary files /dev/null and b/OdfFile/Test/ExampleFiles/entrance.pptx differ diff --git a/OdfFile/Test/ExampleFiles/interaction.pptx b/OdfFile/Test/ExampleFiles/interaction.pptx new file mode 100644 index 00000000000..aa984604ef4 Binary files /dev/null and b/OdfFile/Test/ExampleFiles/interaction.pptx differ diff --git a/OdfFile/Test/ExampleFiles/motion.odp b/OdfFile/Test/ExampleFiles/motion.odp new file mode 100644 index 00000000000..c50abe79d2a Binary files /dev/null and b/OdfFile/Test/ExampleFiles/motion.odp differ diff --git a/OdfFile/Test/ExampleFiles/openDocument.odp b/OdfFile/Test/ExampleFiles/openDocument.odp new file mode 100644 index 00000000000..473c9f314c2 Binary files /dev/null and b/OdfFile/Test/ExampleFiles/openDocument.odp differ diff --git a/OdfFile/Test/ExampleFiles/openDocument.pptx b/OdfFile/Test/ExampleFiles/openDocument.pptx new file mode 100644 index 00000000000..3eaeb25a119 Binary files /dev/null and b/OdfFile/Test/ExampleFiles/openDocument.pptx differ diff --git a/OdfFile/Test/ExampleFiles/playAudio.odp b/OdfFile/Test/ExampleFiles/playAudio.odp new file mode 100644 index 00000000000..30e0b44e0a8 Binary files /dev/null and b/OdfFile/Test/ExampleFiles/playAudio.odp differ diff --git a/OdfFile/Test/ExampleFiles/playAudio.pptx b/OdfFile/Test/ExampleFiles/playAudio.pptx new file mode 100644 index 00000000000..1cec7e4d5fe Binary files /dev/null and b/OdfFile/Test/ExampleFiles/playAudio.pptx differ diff --git a/OdfFile/Test/ExampleFiles/runProgram.odp b/OdfFile/Test/ExampleFiles/runProgram.odp new file mode 100644 index 00000000000..c8acb90ce9a Binary files /dev/null and b/OdfFile/Test/ExampleFiles/runProgram.odp differ diff --git a/OdfFile/Test/ExampleFiles/runProgram.pptx b/OdfFile/Test/ExampleFiles/runProgram.pptx new file mode 100644 index 00000000000..ccd9ea476ad Binary files /dev/null and b/OdfFile/Test/ExampleFiles/runProgram.pptx differ diff --git a/OdfFile/Test/audio.cpp b/OdfFile/Test/audio.cpp new file mode 100644 index 00000000000..b7df1b30d12 --- /dev/null +++ b/OdfFile/Test/audio.cpp @@ -0,0 +1,174 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ + +#include "audio.h" + + +#include "../../DesktopEditor/common/File.h" +#include "../../DesktopEditor/common/Directory.h" +#include "../../OfficeUtils/src/OfficeUtils.h" + +#include "Writer/Converter/Converter.h" +#include "Writer/Converter/PptxConverter.h" +#include "Writer/Format/office_elements.h" + +boost::shared_ptr ODP2OOX_AnimationAudioEnvironment::sInputOdf; +boost::shared_ptr ODP2OOX_AnimationAudioEnvironment::sConverionContext; + +ODP2OOX_AnimationAudioEnvironment::ODP2OOX_AnimationAudioEnvironment() + : ODP2OOX_AnimationEnvironment( + L"ExampleFiles" FILE_SEPARATOR_STR "audio.odp", + &sInputOdf, + &sConverionContext) +{ +} + +const cpdoccore::oox::pptx_animation_context& ODP2OOX_AnimationAudioEnvironment::GetAnimationContext() +{ + return sConverionContext->get_slide_context().get_animation_context(); +} + +void ODP2OOX_AnimationAudioTest::SetUp() +{ + mAnimationContext = &ODP2OOX_AnimationAudioEnvironment::GetAnimationContext(); +} + +const cpdoccore::oox::pptx_animation_context::Impl::_par_animation_ptr& ODP2OOX_AnimationAudioTest::GetInnerPar(const cpdoccore::oox::pptx_animation_context::Impl::_par_animation_ptr& par) +{ + return par->AnimParArray[0]; +} + +const cpdoccore::oox::pptx_animation_context::Impl::_seq_animation_ptr& ODP2OOX_AnimationAudioTest::GetMainSequence() +{ + if(mAnimationContext->get_root_par_animation()->AnimSeq.size()) + return mAnimationContext->get_root_par_animation()->AnimSeq[0]; + return nullptr; +} + +const cpdoccore::oox::pptx_animation_context::Impl::_par_animation_array& ODP2OOX_AnimationAudioTest::GetMainSequenceArray() +{ + return GetMainSequence()->AnimParArray; +} + +const cpdoccore::oox::pptx_animation_context::Impl::_animation_element_array& ODP2OOX_AnimationAudioTest::GetActionArray(const cpdoccore::oox::pptx_animation_context::Impl::_par_animation_ptr& par) +{ + return par->AnimationActionArray; +} + +const cpdoccore::oox::pptx_animation_context::Impl::_par_animation_ptr ODP2OOX_AnimationAudioTest::GetInnermostPar(const cpdoccore::oox::pptx_animation_context::Impl::_par_animation_ptr& par) +{ + using namespace cpdoccore::oox; + cpdoccore::oox::pptx_animation_context::Impl::_par_animation_ptr inner = par; + + while (inner->AnimParArray.size()) + inner = GetInnerPar(inner); + + return inner; +} + +const cpdoccore::oox::pptx_animation_context::Impl::_animation_element_array& ODP2OOX_AnimationAudioTest::GetAnimationActionsByIndex(size_t index) +{ + using namespace cpdoccore::oox; + const pptx_animation_context::Impl::_par_animation_array& main_seq = GetMainSequenceArray(); + const pptx_animation_context::Impl::_animation_element_array& actions = GetInnermostPar(main_seq[index])->AnimationActionArray; + + return actions; +} + +TEST_F(ODP2OOX_AnimationAudioTest, set) +{ + using namespace cpdoccore::oox; + + const auto& mainArray = GetMainSequenceArray(); + ASSERT_GE(mainArray.size(), 1); + const auto& actions = GetInnermostPar(mainArray[0])->AnimationActionArray; + ASSERT_EQ(actions.size(), 3); + const auto set = dynamic_cast(actions[0].get()); + ASSERT_NE(set, nullptr); +} + +TEST_F(ODP2OOX_AnimationAudioTest, anim_1) +{ + using namespace cpdoccore::oox; + + const auto& mainArray = GetMainSequenceArray(); + ASSERT_GE(mainArray.size(), 1); + const auto& actions = GetInnermostPar(mainArray[0])->AnimationActionArray; + ASSERT_EQ(actions.size(), 3); + const auto anim = dynamic_cast(actions[1].get()); + ASSERT_NE(anim, nullptr); +} + +TEST_F(ODP2OOX_AnimationAudioTest, anim_2) +{ + using namespace cpdoccore::oox; + + const auto& mainArray = GetMainSequenceArray(); + ASSERT_GE(mainArray.size(), 1); + const auto& actions = GetInnermostPar(mainArray[0])->AnimationActionArray; + ASSERT_EQ(actions.size(), 3); + const auto anim = dynamic_cast(actions[2].get()); + ASSERT_NE(anim, nullptr); +} + +////////////////////////////////////////////////////////////////////////// + +boost::shared_ptr OOX2ODP_AudioAnimationEnvironment::mConverter; +cpdoccore::odf_writer::odp_conversion_context* OOX2ODP_AudioAnimationEnvironment::mContext; + +OOX2ODP_AudioAnimationEnvironment::OOX2ODP_AudioAnimationEnvironment() + : OOX2ODP_AnimationEnvironment(L"audio.pptx", &mConverter, &mContext) +{ +} + +cpdoccore::odf_writer::odp_conversion_context* OOX2ODP_AudioAnimationEnvironment::GetContext() +{ + return mContext; +} + +void OOX2ODP_AudioAnimationTest::SetUp() +{ + mContext = OOX2ODP_AudioAnimationEnvironment::GetContext(); +} + +TEST_F(OOX2ODP_AudioAnimationTest, a_test) +{ + using namespace cpdoccore::odf_writer; + using namespace cpdoccore::odf_types; + + const anim_audio* audio = GetAnimationBehaviourByIndex(GetInnermostPar(GetMainSequenceParByIndex(0)), 1); + ASSERT_NE(audio, nullptr); + + const std::wstring xpathExp = L"Media/media1.wav"; + + EXPECT_EQ(audio->audio_attlist_.xlink_href_.value(), xpathExp); +} \ No newline at end of file diff --git a/OdfFile/Test/audio.h b/OdfFile/Test/audio.h new file mode 100644 index 00000000000..bc2d42b57f1 --- /dev/null +++ b/OdfFile/Test/audio.h @@ -0,0 +1,95 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#pragma once + +#include "common.h" + +#include "gtest/gtest.h" + +#include "Writer/Converter/Oox2OdfConverter.h" +#include "Writer/Format/odp_conversion_context.h" +#include "Writer/Format/anim_elements.h" +#include "Writer/Format/draw_page.h" + +#include "Reader/Format/odf_document.h" +#include "Reader/Converter/pptx_conversion_context.h" + +class ODP2OOX_AnimationAudioEnvironment : public ODP2OOX_AnimationEnvironment +{ +public: + ODP2OOX_AnimationAudioEnvironment(); + + static const cpdoccore::oox::pptx_animation_context& GetAnimationContext(); + +private: + static boost::shared_ptr sInputOdf; + static boost::shared_ptr sConverionContext; +}; + +class ODP2OOX_AnimationAudioTest : public testing::Test +{ +public: + void SetUp() override; + void TearDown() override + { } + + const cpdoccore::oox::pptx_animation_context::Impl::_par_animation_ptr& GetInnerPar(const cpdoccore::oox::pptx_animation_context::Impl::_par_animation_ptr& par); + const cpdoccore::oox::pptx_animation_context::Impl::_seq_animation_ptr& GetMainSequence(); + const cpdoccore::oox::pptx_animation_context::Impl::_par_animation_array& GetMainSequenceArray(); + const cpdoccore::oox::pptx_animation_context::Impl::_animation_element_array& GetActionArray(const cpdoccore::oox::pptx_animation_context::Impl::_par_animation_ptr& par); + const cpdoccore::oox::pptx_animation_context::Impl::_par_animation_ptr GetInnermostPar(const cpdoccore::oox::pptx_animation_context::Impl::_par_animation_ptr& par); + const cpdoccore::oox::pptx_animation_context::Impl::_animation_element_array& GetAnimationActionsByIndex(size_t index); + + +public: + const cpdoccore::oox::pptx_animation_context* mAnimationContext; +}; + +class OOX2ODP_AudioAnimationEnvironment : public OOX2ODP_AnimationEnvironment +{ +public: + OOX2ODP_AudioAnimationEnvironment(); + +public: + static cpdoccore::odf_writer::odp_conversion_context* GetContext(); + +private: + static boost::shared_ptr mConverter; + static cpdoccore::odf_writer::odp_conversion_context* mContext; +}; + +class OOX2ODP_AudioAnimationTest : public OOX2ODP_AnimationTest +{ +public: + void SetUp() override; + void TearDown() override {} +}; \ No newline at end of file diff --git a/OdfFile/Test/common.cpp b/OdfFile/Test/common.cpp new file mode 100644 index 00000000000..c62de29df65 --- /dev/null +++ b/OdfFile/Test/common.cpp @@ -0,0 +1,227 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ + +#include "common.h" + +#include "../../OfficeUtils/src/OfficeUtils.h" +#include "Reader/Converter/pptx_package.h" + +#include "Writer/Converter/Converter.h" +#include "Writer/Converter/PptxConverter.h" +#include "Writer/Format/office_elements.h" + +boost::shared_ptr ReadOdfDocument(const std::wstring& from, const std::wstring& temp, const std::wstring& tempUnpackedOdf) +{ + COfficeUtils oCOfficeUtils(NULL); + if (S_OK == oCOfficeUtils.ExtractToDirectory(from, tempUnpackedOdf, NULL, 0)) + return boost::make_shared(tempUnpackedOdf, temp, L""); + else + return nullptr; +} + +boost::shared_ptr Convert(boost::shared_ptr inputOdf) +{ + cpdoccore::oox::package::pptx_document outputPptx; + boost::shared_ptr conversionContext = boost::make_shared(inputOdf.get()); + + conversionContext->set_output_document(&outputPptx); + conversionContext->set_font_directory(L""); + + inputOdf->pptx_convert(*conversionContext); + + return conversionContext; +} + +ODP2OOX_AnimationEnvironment::ODP2OOX_AnimationEnvironment(const std::wstring& exampleFilename, boost::shared_ptr* doc, boost::shared_ptr* context) + : testing::Environment() +{ + sExampleFilename = NSFile::GetFileName(exampleFilename); + mDocument = doc; + mContext = context; +} + +ODP2OOX_AnimationEnvironment::~ODP2OOX_AnimationEnvironment() +{ +} + +void ODP2OOX_AnimationEnvironment::SetUp() +{ + std::wstring rootDir = NSFile::GetProcessDirectory() + CH_DIR(".."); + std::wstring sExampleFilesDirectory = rootDir + CH_DIR("ExampleFiles"); + + sFrom = sExampleFilesDirectory + FILE_SEPARATOR_STR + sExampleFilename; + sTemp = sFrom + _T(".tmp"); + sTempUnpackedOdf = sTemp + CH_DIR("odf_unpacked"); + + NSDirectory::CreateDirectory(sTemp); + NSDirectory::CreateDirectory(sTempUnpackedOdf); + + *mDocument = ReadOdfDocument(sFrom, sTemp, sTempUnpackedOdf); + *mContext = Convert(*mDocument); +} + +void ODP2OOX_AnimationEnvironment::TearDown() +{ + NSDirectory::DeleteDirectory(sTemp); +} + +////////////////////////////////////////////////////////////////////////// + +OOX2ODP_AnimationEnvironment::OOX2ODP_AnimationEnvironment(const std::wstring& exampleFilename, boost::shared_ptr* converter, cpdoccore::odf_writer::odp_conversion_context** context) +{ + mExampleFilename = exampleFilename; + mConverter = converter; + mContext = context; +} + +void OOX2ODP_AnimationEnvironment::SetUp() +{ + std::wstring rootDir = NSFile::GetProcessDirectory() + CH_DIR(".."); + std::wstring exampleFilesDirectory = rootDir + CH_DIR("ExampleFiles"); + + mFrom = exampleFilesDirectory + FILE_SEPARATOR_STR + mExampleFilename; + mTemp = mFrom + _T(".tmp"); + mTempUnpackedOox = mTemp + CH_DIR("pptx_unpacked"); + + NSDirectory::CreateDirectory(mTemp); + NSDirectory::CreateDirectory(mTempUnpackedOox); + + COfficeUtils oCOfficeUtils(NULL); + if (S_OK == oCOfficeUtils.ExtractToDirectory(mFrom, mTempUnpackedOox, NULL, 0)) + { + *mConverter = boost::make_shared(mTempUnpackedOox, _T("presentation"), L"", false, mTemp); + + try + { + (*mConverter)->convert(); + *mContext = dynamic_cast((*mConverter)->get_ooxConverter()->odf_context()); + } + catch (...) + { + _CP_LOG << L"[ error ]: Failed to setup OOX2ODP_EntranceAnimationTestEnvironment"; + } + } +} + +void OOX2ODP_AnimationEnvironment::TearDown() +{ + NSDirectory::DeleteDirectory(mTemp); +} + +const cpdoccore::odf_writer::anim_par* OOX2ODP_AnimationTest::GetTimingRoot() +{ + using namespace cpdoccore::odf_writer; + draw_page* page = dynamic_cast(mContext->current_slide().page_elm_.get()); + if (!page) + return nullptr; + + anim_par* timing_root = dynamic_cast(page->animation_.get()); + if (!timing_root) + return nullptr; + + return timing_root; + +} + +const cpdoccore::odf_writer::anim_seq* OOX2ODP_AnimationTest::GetMainSequence() +{ + using namespace cpdoccore::odf_writer; + const anim_par* timing_root = GetTimingRoot(); + if (!timing_root) + return nullptr; + + if (timing_root->anim_seq_array_.size() < 1) + return nullptr; + + const anim_seq* main_sequence = dynamic_cast(timing_root->anim_seq_array_.at(0).get()); + if (!main_sequence) + return nullptr; + + return main_sequence; +} + +const cpdoccore::odf_writer::anim_par* OOX2ODP_AnimationTest::GetMainSequenceParByIndex(size_t index) +{ + using namespace cpdoccore::odf_writer; + const anim_seq* main_sequence = GetMainSequence(); + + if (index >= main_sequence->anim_par_array_.size()) + return nullptr; + + const anim_par* par = dynamic_cast(main_sequence->anim_par_array_[index].get()); + if (!par) + return nullptr; + + return par; +} + +const cpdoccore::odf_writer::anim_par* OOX2ODP_AnimationTest::GetInnerPar(const cpdoccore::odf_writer::anim_par* par) +{ + using namespace cpdoccore::odf_writer; + + if (!par) + return nullptr; + + if (par->anim_par_.size() == 0) + return nullptr; + + const anim_par* inner_par = dynamic_cast(par->anim_par_[0].get()); + + if (!inner_par) + return nullptr; + + return inner_par; +} + +const cpdoccore::odf_writer::anim_par* OOX2ODP_AnimationTest::GetInnermostPar(const cpdoccore::odf_writer::anim_par* par) +{ + using namespace cpdoccore::odf_writer; + + if (!par) + return nullptr; + + const anim_par* innermost = GetInnerPar(par); + + while (innermost->anim_par_.size()) + { + innermost = dynamic_cast(innermost->anim_par_[0].get()); + if (!innermost) + return nullptr; + } + + return innermost; +} + +const cpdoccore::odf_writer::odp_conversion_context* OOX2ODP_AnimationTest::GetContext() const +{ + return mContext; +} diff --git a/OdfFile/Test/common.h b/OdfFile/Test/common.h new file mode 100644 index 00000000000..3a9e967dcde --- /dev/null +++ b/OdfFile/Test/common.h @@ -0,0 +1,123 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ + +#pragma once + +#include "gtest/gtest.h" +#include "Reader/Converter/pptx_conversion_context.h" +#include "Reader/Format/odf_document.h" + +#include "Writer/Converter/Oox2OdfConverter.h" +#include "Writer/Format/odp_conversion_context.h" +#include "Writer/Format/anim_elements.h" +#include "Writer/Format/draw_page.h" + +#include +#include + +#define CH_DIR(x) FILE_SEPARATOR_STR + _T(x) + +boost::shared_ptr ReadOdfDocument(const std::wstring& from, const std::wstring& temp, const std::wstring& tempUnpackedOdf); +boost::shared_ptr Convert(boost::shared_ptr inputOdf); + +class ODP2OOX_AnimationEnvironment : public ::testing::Environment +{ +public: + ODP2OOX_AnimationEnvironment(const std::wstring& exampleFilename, boost::shared_ptr* doc, boost::shared_ptr* context); + ~ODP2OOX_AnimationEnvironment(); + + void SetUp() override; + void TearDown() override; + +private: + std::wstring sExampleFilename; + std::wstring sFrom; + std::wstring sTemp; + std::wstring sTempUnpackedOdf; + + boost::shared_ptr* mDocument; + boost::shared_ptr* mContext; +}; + +class OOX2ODP_AnimationEnvironment : public testing::Environment +{ +public: + OOX2ODP_AnimationEnvironment(const std::wstring& exampleFilename, + boost::shared_ptr* converter, + cpdoccore::odf_writer::odp_conversion_context** context); + + void SetUp() override; + void TearDown() override; + +private: + std::wstring mExampleFilename; + std::wstring mFrom; + std::wstring mTemp; + std::wstring mTempUnpackedOox; + + boost::shared_ptr* mConverter; + cpdoccore::odf_writer::odp_conversion_context** mContext; +}; + +class OOX2ODP_AnimationTest : public testing::Test +{ +public: + const cpdoccore::odf_writer::anim_par* GetTimingRoot(); + const cpdoccore::odf_writer::anim_seq* GetMainSequence(); + const cpdoccore::odf_writer::anim_par* GetMainSequenceParByIndex(size_t index); + const cpdoccore::odf_writer::anim_par* GetInnerPar(const cpdoccore::odf_writer::anim_par* par); + const cpdoccore::odf_writer::anim_par* GetInnermostPar(const cpdoccore::odf_writer::anim_par* par); + + const cpdoccore::odf_writer::odp_conversion_context* GetContext() const; + + template + const T* GetAnimationBehaviourByIndex(const cpdoccore::odf_writer::anim_par* par, size_t index) + { + using namespace cpdoccore::odf_writer; + + if (!par) + return nullptr; + + if (par->content_.size() <= index) + return nullptr; + + T* behaviour = dynamic_cast(par->content_[index].get()); + if (!behaviour) + return nullptr; + + return behaviour; + } + +protected: + const Oox2Odf::Converter* mConverter; + cpdoccore::odf_writer::odp_conversion_context* mContext; +}; \ No newline at end of file diff --git a/OdfFile/Test/entrance.cpp b/OdfFile/Test/entrance.cpp new file mode 100644 index 00000000000..75001e91cb3 --- /dev/null +++ b/OdfFile/Test/entrance.cpp @@ -0,0 +1,1320 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ + +#include "entrance.h" + +#include "common.h" + +#include "../../DesktopEditor/common/File.h" +#include "../../DesktopEditor/common/Directory.h" +#include "../../OfficeUtils/src/OfficeUtils.h" + +#include "Writer/Converter/Converter.h" +#include "Writer/Converter/PptxConverter.h" +#include "Writer/Format/office_elements.h" + +boost::shared_ptr ODP2OOX_AnimationEntranceEnvironment::sConverionContext; +boost::shared_ptr ODP2OOX_AnimationEntranceEnvironment::sInputOdf; + +ODP2OOX_AnimationEntranceEnvironment::ODP2OOX_AnimationEntranceEnvironment() + : ODP2OOX_AnimationEnvironment( + L"ExampleFiles" FILE_SEPARATOR_STR "entrance.odp", + &sInputOdf, + &sConverionContext) +{ + +} + +const cpdoccore::oox::pptx_animation_context& ODP2OOX_AnimationEntranceEnvironment::GetAnimationContext() +{ + return sConverionContext->get_slide_context().get_animation_context(); +} + +void ODP2OOX_EntranceAnimationTest::SetUp() +{ + mAnimationContext = &ODP2OOX_AnimationEntranceEnvironment::GetAnimationContext(); +} + +const cpdoccore::oox::pptx_animation_context::Impl::_par_animation_ptr& ODP2OOX_EntranceAnimationTest::GetInnerPar(const cpdoccore::oox::pptx_animation_context::Impl::_par_animation_ptr& par) +{ + return par->AnimParArray[0]; +} + +const cpdoccore::oox::pptx_animation_context::Impl::_seq_animation_ptr& ODP2OOX_EntranceAnimationTest::GetMainSequence() +{ + if(mAnimationContext->get_root_par_animation()->AnimSeq.size()) + return mAnimationContext->get_root_par_animation()->AnimSeq[0]; + return nullptr; +} + +const cpdoccore::oox::pptx_animation_context::Impl::_par_animation_array& ODP2OOX_EntranceAnimationTest::GetMainSequenceArray() +{ + return mAnimationContext->get_root_par_animation()->AnimSeq[0]->AnimParArray; +} + +const cpdoccore::oox::pptx_animation_context::Impl::_animation_element_array& ODP2OOX_EntranceAnimationTest::GetActionArray(const cpdoccore::oox::pptx_animation_context::Impl::_par_animation_ptr& par) +{ + return par->AnimationActionArray; +} + +const cpdoccore::oox::pptx_animation_context::Impl::_par_animation_ptr ODP2OOX_EntranceAnimationTest::GetInnermostPar(const cpdoccore::oox::pptx_animation_context::Impl::_par_animation_ptr& par) +{ + using namespace cpdoccore::oox; + cpdoccore::oox::pptx_animation_context::Impl::_par_animation_ptr inner = par; + + while (inner->AnimParArray.size()) + { + inner = GetInnerPar(inner); + } + + return inner; +} + +const cpdoccore::oox::pptx_animation_context::Impl::_animation_element_array& ODP2OOX_EntranceAnimationTest::GetAnimationActionsByIndex(size_t index) +{ + using namespace cpdoccore::oox; + const pptx_animation_context::Impl::_par_animation_array& main_seq = GetMainSequenceArray(); + const pptx_animation_context::Impl::_animation_element_array& actions = GetInnermostPar(main_seq[index])->AnimationActionArray; + + return actions; +} + +TEST_F(ODP2OOX_EntranceAnimationTest, timing_root_par) +{ + using namespace cpdoccore::oox; + const pptx_animation_context::Impl::_par_animation_ptr& root = mAnimationContext->get_root_par_animation(); + + const std::wstring nodeTypeExp = L"tmRoot"; + + EXPECT_EQ(root->NodeType.value(), nodeTypeExp); +} + +TEST_F(ODP2OOX_EntranceAnimationTest, main_sequence) +{ + using namespace cpdoccore::oox; + const pptx_animation_context::Impl::_seq_animation_ptr& main_seq = GetMainSequence(); + + const std::wstring nodeTypeExp = L"mainSeq"; + + EXPECT_EQ(main_seq->PresentationNodeType.value(), nodeTypeExp); + EXPECT_FALSE(main_seq->Duration.has_value()); +} + +TEST_F(ODP2OOX_EntranceAnimationTest, main_sequence_par_animations) +{ + using namespace cpdoccore::oox; + const pptx_animation_context::Impl::_par_animation_array& par_animations = mAnimationContext->get_root_par_animation()->AnimSeq[0]->AnimParArray; + + const std::wstring delayExp = L"indefinite"; + + for (size_t i = 0; i < par_animations.size(); i++) + { + EXPECT_EQ(par_animations[i]->Delay.value(), delayExp); + } +} + +TEST_F(ODP2OOX_EntranceAnimationTest, main_sequence_inner_par_animation) +{ + using namespace cpdoccore::oox; + const pptx_animation_context::Impl::_par_animation_array& main_seq = GetMainSequenceArray(); + + std::wstring delayExp = L"0"; + + for (size_t i = 0; i < main_seq.size(); i++) + { + const pptx_animation_context::Impl::_par_animation_ptr& par = GetInnerPar(main_seq[i]); + + EXPECT_EQ(par->Delay.value(), delayExp); + } +} + +TEST_F(ODP2OOX_EntranceAnimationTest, main_sequence_innermost_par_animation) +{ + using namespace cpdoccore::oox; + const pptx_animation_context::Impl::_par_animation_array& main_seq = GetMainSequenceArray(); + + std::wstring delayExp = L"0"; + std::wstring fillExp = L"hold"; + std::wstring nodeTypeExp = L"clickEffect"; + std::wstring presetClassExp = L"entr"; + + for (size_t i = 0; i < main_seq.size(); i++) + { + const pptx_animation_context::Impl::_par_animation_ptr& par = GetInnermostPar(main_seq[i]); + + EXPECT_EQ(par->Delay.value(), delayExp); + EXPECT_EQ(par->Fill.value(), fillExp); + EXPECT_EQ(par->NodeType.value(), nodeTypeExp); + EXPECT_EQ(par->PresetClass.value(), presetClassExp); + } +} + +TEST_F(ODP2OOX_EntranceAnimationTest, entrance_appear_acitons_size) +{ + using namespace cpdoccore::oox; + const size_t animationIndex = 0; + const pptx_animation_context::Impl::_animation_element_array& actions = GetAnimationActionsByIndex(animationIndex); + + const size_t actionsSizeExp = 1; + + EXPECT_EQ(actions.size(), actionsSizeExp); +} + +TEST_F(ODP2OOX_EntranceAnimationTest, enerance_appear_actions_set) +{ + using namespace cpdoccore::oox; + const size_t animationIndex = 0; + const pptx_animation_context::Impl::_animation_element_array& actions = GetAnimationActionsByIndex(animationIndex); + + const pptx_animation_context::Impl::_set* set = dynamic_cast(actions[0].get()); + + EXPECT_TRUE(set != nullptr); +} + +TEST_F(ODP2OOX_EntranceAnimationTest, enerance_appear_action_set_duration) +{ + using namespace cpdoccore::oox; + const size_t animationIndex = 0; + const pptx_animation_context::Impl::_animation_element_array& actions = GetAnimationActionsByIndex(animationIndex); + const pptx_animation_context::Impl::_set* set = dynamic_cast(actions[0].get()); + + const int durationExp = 1; + + EXPECT_EQ(set->Duration.value(), durationExp); +} + +TEST_F(ODP2OOX_EntranceAnimationTest, enerance_appear_action_set_fill) +{ + using namespace cpdoccore::oox; + const size_t animationIndex = 0; + const pptx_animation_context::Impl::_animation_element_array& actions = GetAnimationActionsByIndex(animationIndex); + const pptx_animation_context::Impl::_set* set = dynamic_cast(actions[0].get()); + + const std::wstring fillExp = L"hold"; + + EXPECT_EQ(set->Fill.value(), fillExp); +} + +TEST_F(ODP2OOX_EntranceAnimationTest, enerance_appear_action_set_delay) +{ + using namespace cpdoccore::oox; + const size_t animationIndex = 0; + const pptx_animation_context::Impl::_animation_element_array& actions = GetAnimationActionsByIndex(animationIndex); + const pptx_animation_context::Impl::_set* set = dynamic_cast(actions[0].get()); + + const std::wstring fillExp = L"hold"; + + EXPECT_EQ(set->Fill.value(), fillExp); +} + +TEST_F(ODP2OOX_EntranceAnimationTest, enerance_appear_action_set_attribute_name) +{ + using namespace cpdoccore::oox; + const size_t animationIndex = 0; + const pptx_animation_context::Impl::_animation_element_array& actions = GetAnimationActionsByIndex(animationIndex); + const pptx_animation_context::Impl::_set* set = dynamic_cast(actions[0].get()); + + const std::wstring attributeNameExp = L"style.visibility"; + + EXPECT_EQ(set->AttributeName.value(), attributeNameExp); +} + +TEST_F(ODP2OOX_EntranceAnimationTest, enerance_appear_action_set_to_value) +{ + using namespace cpdoccore::oox; + const size_t animationIndex = 0; + const pptx_animation_context::Impl::_animation_element_array& actions = GetAnimationActionsByIndex(animationIndex); + const pptx_animation_context::Impl::_set* set = dynamic_cast(actions[0].get()); + + const std::wstring toValueExp = L"visible"; + + EXPECT_EQ(set->ToValue.value(), toValueExp); +} + +TEST_F(ODP2OOX_EntranceAnimationTest, entrance_fly_in_actions_size) +{ + using namespace cpdoccore::oox; + const size_t animationIndex = 1; + const pptx_animation_context::Impl::_animation_element_array& actions = GetAnimationActionsByIndex(animationIndex); + + const size_t actionsSizeExp = 3; + + EXPECT_EQ(actions.size(), actionsSizeExp); +} + +TEST_F(ODP2OOX_EntranceAnimationTest, entrance_fly_in_action_set) +{ + using namespace cpdoccore::oox; + const size_t animationIndex = 1; + const pptx_animation_context::Impl::_animation_element_array& actions = GetAnimationActionsByIndex(animationIndex); + + const pptx_animation_context::Impl::_set* set = dynamic_cast(actions[0].get()); + + EXPECT_TRUE(set != nullptr); +} + +TEST_F(ODP2OOX_EntranceAnimationTest, entrance_fly_in_action_animate_1) +{ + using namespace cpdoccore::oox; + const size_t animationIndex = 1; + const pptx_animation_context::Impl::_animation_element_array& actions = GetAnimationActionsByIndex(animationIndex); + + const pptx_animation_context::Impl::_anim* animate1 = dynamic_cast(actions[1].get()); + + EXPECT_TRUE(animate1 != nullptr); +} + +TEST_F(ODP2OOX_EntranceAnimationTest, entrance_fly_in_action_animate_2) +{ + using namespace cpdoccore::oox; + const size_t animationIndex = 1; + const pptx_animation_context::Impl::_animation_element_array& actions = GetAnimationActionsByIndex(animationIndex); + + const pptx_animation_context::Impl::_anim* animate2 = dynamic_cast(actions[2].get()); + + EXPECT_TRUE(animate2 != nullptr); +} + +TEST_F(ODP2OOX_EntranceAnimationTest, entrance_fly_in_action_set_duration) +{ + using namespace cpdoccore::oox; + const size_t animationIndex = 1; + const pptx_animation_context::Impl::_animation_element_array& actions = GetAnimationActionsByIndex(animationIndex); + + const pptx_animation_context::Impl::_set* set = dynamic_cast(actions[0].get()); + const int durationExp = 1; + + EXPECT_EQ(set->Duration.value(), durationExp); +} + +TEST_F(ODP2OOX_EntranceAnimationTest, entrance_fly_in_action_set_delay) +{ + using namespace cpdoccore::oox; + const size_t animationIndex = 1; + const pptx_animation_context::Impl::_animation_element_array& actions = GetAnimationActionsByIndex(animationIndex); + + const pptx_animation_context::Impl::_set* set = dynamic_cast(actions[0].get()); + const std::wstring delayExp = L"0"; + + EXPECT_EQ(set->Delay.value(), delayExp); +} + +TEST_F(ODP2OOX_EntranceAnimationTest, entrance_fly_in_action_set_fill) +{ + using namespace cpdoccore::oox; + const size_t animationIndex = 1; + const pptx_animation_context::Impl::_animation_element_array& actions = GetAnimationActionsByIndex(animationIndex); + + const pptx_animation_context::Impl::_set* set = dynamic_cast(actions[0].get()); + const std::wstring fillExp = L"hold"; + + EXPECT_EQ(set->Fill.value(), fillExp); +} + +TEST_F(ODP2OOX_EntranceAnimationTest, entrance_fly_in_action_set_attribute_name) +{ + using namespace cpdoccore::oox; + const size_t animationIndex = 1; + const pptx_animation_context::Impl::_animation_element_array& actions = GetAnimationActionsByIndex(animationIndex); + + const pptx_animation_context::Impl::_set* set = dynamic_cast(actions[0].get()); + const std::wstring attributeNameExp = L"style.visibility"; + + EXPECT_EQ(set->AttributeName.value(), attributeNameExp); +} + +TEST_F(ODP2OOX_EntranceAnimationTest, entrance_fly_in_action_set_to_value) +{ + using namespace cpdoccore::oox; + const size_t animationIndex = 1; + const pptx_animation_context::Impl::_animation_element_array& actions = GetAnimationActionsByIndex(animationIndex); + + const pptx_animation_context::Impl::_set* set = dynamic_cast(actions[0].get()); + const std::wstring toValueExp = L"visible"; + + EXPECT_EQ(set->ToValue.value(), toValueExp); +} + +TEST_F(ODP2OOX_EntranceAnimationTest, entrance_fly_in_action_animate_1_calc_mode) +{ + using namespace cpdoccore::oox; + const size_t animationIndex = 1; + const pptx_animation_context::Impl::_animation_element_array& actions = GetAnimationActionsByIndex(animationIndex); + + const pptx_animation_context::Impl::_anim* animate1 = dynamic_cast(actions[1].get()); + const std::wstring calcModeExp = L"lin"; + + EXPECT_EQ(animate1->CalcMode.value(), calcModeExp); +} + +TEST_F(ODP2OOX_EntranceAnimationTest, entrance_fly_in_action_animate_1_value_type) +{ + using namespace cpdoccore::oox; + const size_t animationIndex = 1; + const pptx_animation_context::Impl::_animation_element_array& actions = GetAnimationActionsByIndex(animationIndex); + + const pptx_animation_context::Impl::_anim* animate1 = dynamic_cast(actions[1].get()); + const std::wstring valueTypeExp = L"num"; + + EXPECT_EQ(animate1->ValueType.value(), valueTypeExp); +} + +TEST_F(ODP2OOX_EntranceAnimationTest, entrance_fly_in_action_animate_1_duration) +{ + using namespace cpdoccore::oox; + const size_t animationIndex = 1; + const pptx_animation_context::Impl::_animation_element_array& actions = GetAnimationActionsByIndex(animationIndex); + + const pptx_animation_context::Impl::_anim* animate1 = dynamic_cast(actions[1].get()); + const int durationExp = 500; + + EXPECT_EQ(animate1->Duration.value(), durationExp); +} + +TEST_F(ODP2OOX_EntranceAnimationTest, entrance_fly_in_action_animate_1_attribute_name) +{ + using namespace cpdoccore::oox; + const size_t animationIndex = 1; + const pptx_animation_context::Impl::_animation_element_array& actions = GetAnimationActionsByIndex(animationIndex); + + const pptx_animation_context::Impl::_anim* animate1 = dynamic_cast(actions[1].get()); + const std::wstring attributeNameExp = L"ppt_x"; + + EXPECT_EQ(animate1->AttributeName.value(), attributeNameExp); +} + +TEST_F(ODP2OOX_EntranceAnimationTest, entrance_fly_in_action_animate_1_additive) +{ + using namespace cpdoccore::oox; + const size_t animationIndex = 1; + const pptx_animation_context::Impl::_animation_element_array& actions = GetAnimationActionsByIndex(animationIndex); + + const pptx_animation_context::Impl::_anim* animate1 = dynamic_cast(actions[1].get()); + const std::wstring additiveExp = L"repl"; + + EXPECT_EQ(animate1->Additive.value(), additiveExp); +} + +TEST_F(ODP2OOX_EntranceAnimationTest, entrance_fly_in_action_animate_1_key_points) +{ + using namespace cpdoccore::oox; + const size_t animationIndex = 1; + const pptx_animation_context::Impl::_animation_element_array& actions = GetAnimationActionsByIndex(animationIndex); + + const pptx_animation_context::Impl::_anim* animate1 = dynamic_cast(actions[1].get()); + std::vector keypointsExp; + keypointsExp.push_back(pptx_animation_context::Impl::_anim::_keypoint(0, L"ppt_x", boost::none)); + keypointsExp.push_back(pptx_animation_context::Impl::_anim::_keypoint(100000, L"ppt_x", boost::none)); + + EXPECT_EQ(animate1->KeypointArray->size(), keypointsExp.size()); + for (size_t i = 0; i < animate1->KeypointArray->size(); i++) + { + EXPECT_EQ(animate1->KeypointArray->at(i).Time, keypointsExp[i].Time); + EXPECT_EQ(animate1->KeypointArray->at(i).Value, keypointsExp[i].Value); + EXPECT_EQ(animate1->KeypointArray->at(i).Fmla.has_value(), keypointsExp[i].Fmla.has_value()); + EXPECT_EQ(animate1->KeypointArray->at(i).Fmla.value_or(L""), keypointsExp[i].Fmla.value_or(L"")); + } +} + +TEST_F(ODP2OOX_EntranceAnimationTest, entrance_fly_in_action_animate_2_calc_mode) +{ + using namespace cpdoccore::oox; + const size_t animationIndex = 1; + const pptx_animation_context::Impl::_animation_element_array& actions = GetAnimationActionsByIndex(animationIndex); + + const pptx_animation_context::Impl::_anim* animate2 = dynamic_cast(actions[2].get()); + const std::wstring calcModeExp = L"lin"; + + EXPECT_EQ(animate2->CalcMode.value(), calcModeExp); +} + +TEST_F(ODP2OOX_EntranceAnimationTest, entrance_fly_in_action_animate_2_value_type) +{ + using namespace cpdoccore::oox; + const size_t animationIndex = 1; + const pptx_animation_context::Impl::_animation_element_array& actions = GetAnimationActionsByIndex(animationIndex); + + const pptx_animation_context::Impl::_anim* animate2 = dynamic_cast(actions[2].get()); + const std::wstring valueTypeExp = L"num"; + + EXPECT_EQ(animate2->ValueType.value(), valueTypeExp); +} + +TEST_F(ODP2OOX_EntranceAnimationTest, entrance_fly_in_action_animate_2_duration) +{ + using namespace cpdoccore::oox; + const size_t animationIndex = 1; + const pptx_animation_context::Impl::_animation_element_array& actions = GetAnimationActionsByIndex(animationIndex); + + const pptx_animation_context::Impl::_anim* animate2 = dynamic_cast(actions[2].get()); + const int durationExp = 500; + + EXPECT_EQ(animate2->Duration.value(), durationExp); +} + +TEST_F(ODP2OOX_EntranceAnimationTest, entrance_fly_in_action_animate_2_attribute_name) +{ + using namespace cpdoccore::oox; + const size_t animationIndex = 1; + const pptx_animation_context::Impl::_animation_element_array& actions = GetAnimationActionsByIndex(animationIndex); + + const pptx_animation_context::Impl::_anim* animate2 = dynamic_cast(actions[2].get()); + const std::wstring attributeNameExp = L"ppt_y"; + + EXPECT_EQ(animate2->AttributeName.value(), attributeNameExp); +} + +TEST_F(ODP2OOX_EntranceAnimationTest, entrance_fly_in_action_animate_2_additive) +{ + using namespace cpdoccore::oox; + const size_t animationIndex = 1; + const pptx_animation_context::Impl::_animation_element_array& actions = GetAnimationActionsByIndex(animationIndex); + + const pptx_animation_context::Impl::_anim* animate2 = dynamic_cast(actions[2].get()); + const std::wstring additiveExp = L"repl"; + + EXPECT_EQ(animate2->Additive.value(), additiveExp); +} + +TEST_F(ODP2OOX_EntranceAnimationTest, entrance_fly_in_action_animate_2_key_points) +{ + using namespace cpdoccore::oox; + const size_t animationIndex = 1; + const pptx_animation_context::Impl::_animation_element_array& actions = GetAnimationActionsByIndex(animationIndex); + + const pptx_animation_context::Impl::_anim* animate2 = dynamic_cast(actions[2].get()); + std::vector keypointsExp; + keypointsExp.push_back(pptx_animation_context::Impl::_anim::_keypoint(0, L"1+ppt_h/2", boost::none)); + keypointsExp.push_back(pptx_animation_context::Impl::_anim::_keypoint(100000, L"ppt_y", boost::none)); + + EXPECT_EQ(animate2->KeypointArray->size(), keypointsExp.size()); + for (size_t i = 0; i < animate2->KeypointArray->size(); i++) + { + EXPECT_EQ(animate2->KeypointArray->at(i).Time, keypointsExp[i].Time); + EXPECT_EQ(animate2->KeypointArray->at(i).Value, keypointsExp[i].Value); + EXPECT_EQ(animate2->KeypointArray->at(i).Fmla.has_value(), keypointsExp[i].Fmla.has_value()); + EXPECT_EQ(animate2->KeypointArray->at(i).Fmla.value_or(L""), keypointsExp[i].Fmla.value_or(L"")); + } +} + +TEST_F(ODP2OOX_EntranceAnimationTest, entrance_venetian_blinds_actions_size) +{ + using namespace cpdoccore::oox; + const size_t animationIndex = 2; + const pptx_animation_context::Impl::_animation_element_array& actions = GetAnimationActionsByIndex(animationIndex); + + const size_t actionsSizeExp = 2; + + EXPECT_EQ(actions.size(), actionsSizeExp); +} + +TEST_F(ODP2OOX_EntranceAnimationTest, entrance_venetian_blinds_set) +{ + using namespace cpdoccore::oox; + const size_t animationIndex = 2; + const pptx_animation_context::Impl::_animation_element_array& actions = GetAnimationActionsByIndex(animationIndex); + const pptx_animation_context::Impl::_set* set = dynamic_cast(actions[0].get()); + + EXPECT_TRUE(set != nullptr); +} + +TEST_F(ODP2OOX_EntranceAnimationTest, entrance_venetian_blinds_anim_effect) +{ + using namespace cpdoccore::oox; + const size_t animationIndex = 2; + const pptx_animation_context::Impl::_animation_element_array& actions = GetAnimationActionsByIndex(animationIndex); + const pptx_animation_context::Impl::_anim_effect* animEffect = dynamic_cast(actions[1].get()); + + EXPECT_TRUE(animEffect != nullptr); +} + +TEST_F(ODP2OOX_EntranceAnimationTest, entrance_venetian_blinds_anim_effect_filter) +{ + using namespace cpdoccore::oox; + const size_t animationIndex = 2; + const pptx_animation_context::Impl::_animation_element_array& actions = GetAnimationActionsByIndex(animationIndex); + const pptx_animation_context::Impl::_anim_effect* animEffect = dynamic_cast(actions[1].get()); + + const std::wstring filterExp = L"blinds(horizontal)"; + + EXPECT_EQ(animEffect->Filter.value(), filterExp); +} + +TEST_F(ODP2OOX_EntranceAnimationTest, entrance_venetian_blinds_anim_effect_transition) +{ + using namespace cpdoccore::oox; + const size_t animationIndex = 2; + const pptx_animation_context::Impl::_animation_element_array& actions = GetAnimationActionsByIndex(animationIndex); + const pptx_animation_context::Impl::_anim_effect* animEffect = dynamic_cast(actions[1].get()); + + EXPECT_FALSE(animEffect->Transition.has_value()); +} + +TEST_F(ODP2OOX_EntranceAnimationTest, entrance_venetian_blinds_anim_effect_duration) +{ + using namespace cpdoccore::oox; + const size_t animationIndex = 2; + const pptx_animation_context::Impl::_animation_element_array& actions = GetAnimationActionsByIndex(animationIndex); + const pptx_animation_context::Impl::_anim_effect* animEffect = dynamic_cast(actions[1].get()); + + const int durationExp = 500; + + EXPECT_EQ(animEffect->Duration.value(), durationExp); +} + +TEST_F(ODP2OOX_EntranceAnimationTest, entrance_transition_filter_blinds_wipe_horizontal) +{ + using namespace cpdoccore::oox; + const size_t animationIndex = 2; + const pptx_animation_context::Impl::_animation_element_array& actions = GetAnimationActionsByIndex(animationIndex); + const pptx_animation_context::Impl::_anim_effect* animEffect = dynamic_cast(actions[1].get()); + + const std::wstring filterExp = L"blinds(horizontal)"; + + EXPECT_EQ(animEffect->Filter.value(), filterExp); +} + +TEST_F(ODP2OOX_EntranceAnimationTest, entrance_transition_filter_iris_wipe_rectangle) +{ + using namespace cpdoccore::oox; + const size_t animationIndex = 3; + const pptx_animation_context::Impl::_animation_element_array& actions = GetAnimationActionsByIndex(animationIndex); + const pptx_animation_context::Impl::_anim_effect* animEffect = dynamic_cast(actions[1].get()); + + const std::wstring filterExp = L"box(in)"; + + EXPECT_EQ(animEffect->Filter.value(), filterExp); +} + +TEST_F(ODP2OOX_EntranceAnimationTest, entrance_transition_filter_checker_board_wipe_across) +{ + using namespace cpdoccore::oox; + const size_t animationIndex = 4; + const pptx_animation_context::Impl::_animation_element_array& actions = GetAnimationActionsByIndex(animationIndex); + const pptx_animation_context::Impl::_anim_effect* animEffect = dynamic_cast(actions[1].get()); + + const std::wstring filterExp = L"checkerboard(across)"; + + EXPECT_EQ(animEffect->Filter.value(), filterExp); +} + +TEST_F(ODP2OOX_EntranceAnimationTest, entrance_transition_filter_checker_iris_wipe_diamond) +{ + using namespace cpdoccore::oox; + const size_t animationIndex = 8; + const pptx_animation_context::Impl::_animation_element_array& actions = GetAnimationActionsByIndex(animationIndex); + const pptx_animation_context::Impl::_anim_effect* animEffect = dynamic_cast(actions[1].get()); + + const std::wstring filterExp = L"diamond(in)"; + + EXPECT_EQ(animEffect->Filter.value(), filterExp); +} + +////////////////////////////////////////////////////////////////////////// +// OOX2ODP + +boost::shared_ptr OOX2ODP_EntranceAnimationEnvironment::mConverter; +cpdoccore::odf_writer::odp_conversion_context* OOX2ODP_EntranceAnimationEnvironment::mContext; + +OOX2ODP_EntranceAnimationEnvironment::OOX2ODP_EntranceAnimationEnvironment() + : OOX2ODP_AnimationEnvironment(L"entrance.pptx", &mConverter, &mContext) +{ +} + +cpdoccore::odf_writer::odp_conversion_context* OOX2ODP_EntranceAnimationEnvironment::GetContext() +{ + return mContext; +} + +void OOX2ODP_EntranceAnimationTest::SetUp() +{ + mContext = OOX2ODP_EntranceAnimationEnvironment::GetContext(); +} + +TEST_F(OOX2ODP_EntranceAnimationTest, timing_root_node_type) +{ + using namespace cpdoccore::odf_writer; + using namespace cpdoccore::odf_types; + + const anim_par* timing_root = GetTimingRoot(); + ASSERT_NE(timing_root, nullptr); + + const presentation_node_type NodeTypeExp = presentation_node_type::timing_root; + + EXPECT_EQ(timing_root->attlist_.presentation_node_type_->get_type(), NodeTypeExp.get_type()); +} + +TEST_F(OOX2ODP_EntranceAnimationTest, main_sequence_node_type) +{ + using namespace cpdoccore::odf_writer; + using namespace cpdoccore::odf_types; + + const anim_seq* main_sequence = GetMainSequence(); + ASSERT_NE(main_sequence, nullptr); + + const presentation_node_type nodeTypeExp = presentation_node_type::main_sequence; + + EXPECT_EQ(main_sequence->attlist_.presentation_node_type_->get_type(), nodeTypeExp.get_type()); +} + +TEST_F(OOX2ODP_EntranceAnimationTest, main_sequence_duration) +{ + using namespace cpdoccore::odf_writer; + using namespace cpdoccore::odf_types; + + const anim_seq* main_sequence = GetMainSequence(); + ASSERT_NE(main_sequence, nullptr); + + const odf_types::clockvalue durationExp(-1); + + EXPECT_EQ(main_sequence->attlist_.smil_dur_->get_value(), durationExp.get_value()); +} + +TEST_F(OOX2ODP_EntranceAnimationTest, appear_outer_par_begin) +{ + using namespace cpdoccore::odf_writer; + using namespace cpdoccore::odf_types; + + const anim_par* par = GetMainSequenceParByIndex(0); + ASSERT_NE(par, nullptr); + + const std::wstring beginExp = L"next"; + + EXPECT_EQ(par->attlist_.smil_begin_.get_value_or(L"Empty"), beginExp); +} + +TEST_F(OOX2ODP_EntranceAnimationTest, appear_outer_par_fill) +{ + using namespace cpdoccore::odf_writer; + using namespace cpdoccore::odf_types; + + const anim_par* par = GetMainSequenceParByIndex(0); + ASSERT_NE(par, nullptr); + + const smil_fill fillExp = smil_fill::_hold; + + EXPECT_EQ(par->attlist_.smil_fill_.value_or(smil_fill::none).get_type(), fillExp.get_type()); +} + +TEST_F(OOX2ODP_EntranceAnimationTest, appear_inner_par_begin) +{ + using namespace cpdoccore::odf_writer; + using namespace cpdoccore::odf_types; + + const anim_par* par = GetInnerPar(GetMainSequenceParByIndex(0)); + ASSERT_NE(par, nullptr); + + const std::wstring beginExp = L"0s"; + + EXPECT_EQ(par->attlist_.smil_begin_.value_or(L"Empty"), beginExp); +} + +TEST_F(OOX2ODP_EntranceAnimationTest, appear_inner_par_fill) +{ + using namespace cpdoccore::odf_writer; + using namespace cpdoccore::odf_types; + + const anim_par* par = GetInnerPar(GetMainSequenceParByIndex(0)); + ASSERT_NE(par, nullptr); + + const smil_fill fillExp = smil_fill::_hold; + + EXPECT_EQ(par->attlist_.smil_fill_.value_or(smil_fill::none).get_type(), fillExp.get_type()); +} + +TEST_F(OOX2ODP_EntranceAnimationTest, appear_innermost_par_begin) +{ + using namespace cpdoccore::odf_writer; + using namespace cpdoccore::odf_types; + + const anim_par* par = GetInnermostPar(GetMainSequenceParByIndex(0)); + ASSERT_NE(par, nullptr); + + const std::wstring beginExp = L"0s"; + + EXPECT_EQ(par->attlist_.smil_begin_.value_or(L"Empty"), beginExp); +} + +TEST_F(OOX2ODP_EntranceAnimationTest, appear_innermost_par_fill) +{ + using namespace cpdoccore::odf_writer; + using namespace cpdoccore::odf_types; + + const anim_par* par = GetInnermostPar(GetMainSequenceParByIndex(0)); + ASSERT_NE(par, nullptr); + + const smil_fill fillExp = smil_fill::_hold; + + EXPECT_EQ(par->attlist_.smil_fill_.value_or(smil_fill::none).get_type(), fillExp.get_type()); +} + +TEST_F(OOX2ODP_EntranceAnimationTest, appear_innermost_par_node_type) +{ + using namespace cpdoccore::odf_writer; + using namespace cpdoccore::odf_types; + + const anim_par* par = GetInnermostPar(GetMainSequenceParByIndex(0)); + ASSERT_NE(par, nullptr); + + const presentation_node_type nodeTypeExp = presentation_node_type::on_click; + + EXPECT_EQ(par->attlist_.presentation_node_type_.value_or(presentation_node_type::none).get_type(), nodeTypeExp.get_type()); +} + +TEST_F(OOX2ODP_EntranceAnimationTest, appear_innermost_par_preset_class) +{ + using namespace cpdoccore::odf_writer; + using namespace cpdoccore::odf_types; + + const anim_par* par = GetInnermostPar(GetMainSequenceParByIndex(0)); + ASSERT_NE(par, nullptr); + + const preset_class presetClassExp = preset_class::entrance; + + EXPECT_EQ(par->par_attlist_.presentation_preset_class_.value_or(preset_class::custom).get_type(), presetClassExp.get_type()); +} + +TEST_F(OOX2ODP_EntranceAnimationTest, appear_innermost_par_preset_id) +{ + using namespace cpdoccore::odf_writer; + using namespace cpdoccore::odf_types; + + const anim_par* par = GetInnermostPar(GetMainSequenceParByIndex(0)); + ASSERT_NE(par, nullptr); + + const preset_id presetIdExp = preset_id::ooo_entrance_appear; + + EXPECT_EQ(par->par_attlist_.presentation_preset_id_.value_or(preset_id::none).get_type(), presetIdExp.get_type()); +} + +TEST_F(OOX2ODP_EntranceAnimationTest, appear_set_duration) +{ + using namespace cpdoccore::odf_writer; + using namespace cpdoccore::odf_types; + + const anim_set* set = GetAnimationBehaviourByIndex(GetInnermostPar(GetMainSequenceParByIndex(0)), 0); + ASSERT_NE(set, nullptr); + + const clockvalue durationExp = clockvalue(1); + + EXPECT_EQ(set->common_attlist_.smil_dur_->get_value(), durationExp.get_value()); +} + +TEST_F(OOX2ODP_EntranceAnimationTest, appear_set_attribute_name) +{ + using namespace cpdoccore::odf_writer; + using namespace cpdoccore::odf_types; + + const anim_set* set = GetAnimationBehaviourByIndex(GetInnermostPar(GetMainSequenceParByIndex(0)), 0); + ASSERT_NE(set, nullptr); + + const smil_attribute_name attributeNameExp = smil_attribute_name::visibility; + + EXPECT_EQ(set->common_attlist_.smil_attribute_name_->get_type(), attributeNameExp.get_type()); +} + +TEST_F(OOX2ODP_EntranceAnimationTest, appear_set_to) +{ + using namespace cpdoccore::odf_writer; + using namespace cpdoccore::odf_types; + + const anim_set* set = GetAnimationBehaviourByIndex(GetInnermostPar(GetMainSequenceParByIndex(0)), 0); + ASSERT_NE(set, nullptr); + + const std::wstring toExp = L"visible"; + + EXPECT_EQ(set->set_attlist_.smil_to_.value_or(L"Empty"), toExp); +} + +//////////////////////////////////////////////////////////// + +TEST_F(OOX2ODP_EntranceAnimationTest, fade_in_outer_par_begin) +{ + using namespace cpdoccore::odf_writer; + using namespace cpdoccore::odf_types; + + const anim_par* par = GetMainSequenceParByIndex(1); + ASSERT_NE(par, nullptr); + + const std::wstring beginExp = L"next"; + + EXPECT_EQ(par->attlist_.smil_begin_.get_value_or(L"Empty"), beginExp); +} + +TEST_F(OOX2ODP_EntranceAnimationTest, fade_in_outer_par_fill) +{ + using namespace cpdoccore::odf_writer; + using namespace cpdoccore::odf_types; + + const anim_par* par = GetMainSequenceParByIndex(1); + ASSERT_NE(par, nullptr); + + const smil_fill fillExp = smil_fill::_hold; + + EXPECT_EQ(par->attlist_.smil_fill_.value_or(smil_fill::none).get_type(), fillExp.get_type()); +} + +TEST_F(OOX2ODP_EntranceAnimationTest, fade_in_inner_par_begin) +{ + using namespace cpdoccore::odf_writer; + using namespace cpdoccore::odf_types; + + const anim_par* par = GetInnerPar(GetMainSequenceParByIndex(1)); + ASSERT_NE(par, nullptr); + + const std::wstring beginExp = L"0s"; + + EXPECT_EQ(par->attlist_.smil_begin_.value_or(L"Empty"), beginExp); +} + +TEST_F(OOX2ODP_EntranceAnimationTest, fade_in_inner_par_fill) +{ + using namespace cpdoccore::odf_writer; + using namespace cpdoccore::odf_types; + + const anim_par* par = GetInnerPar(GetMainSequenceParByIndex(1)); + ASSERT_NE(par, nullptr); + + const smil_fill fillExp = smil_fill::_hold; + + EXPECT_EQ(par->attlist_.smil_fill_.value_or(smil_fill::none).get_type(), fillExp.get_type()); +} + +TEST_F(OOX2ODP_EntranceAnimationTest, fade_in_innermost_par_begin) +{ + using namespace cpdoccore::odf_writer; + using namespace cpdoccore::odf_types; + + const anim_par* par = GetInnermostPar(GetMainSequenceParByIndex(1)); + ASSERT_NE(par, nullptr); + + const std::wstring beginExp = L"0s"; + + EXPECT_EQ(par->attlist_.smil_begin_.value_or(L"Empty"), beginExp); +} + +TEST_F(OOX2ODP_EntranceAnimationTest, fade_in_innermost_par_fill) +{ + using namespace cpdoccore::odf_writer; + using namespace cpdoccore::odf_types; + + const anim_par* par = GetInnermostPar(GetMainSequenceParByIndex(1)); + ASSERT_NE(par, nullptr); + + const smil_fill fillExp = smil_fill::_hold; + + EXPECT_EQ(par->attlist_.smil_fill_.value_or(smil_fill::none).get_type(), fillExp.get_type()); +} + +TEST_F(OOX2ODP_EntranceAnimationTest, fade_in_innermost_par_node_type) +{ + using namespace cpdoccore::odf_writer; + using namespace cpdoccore::odf_types; + + const anim_par* par = GetInnermostPar(GetMainSequenceParByIndex(1)); + ASSERT_NE(par, nullptr); + + const presentation_node_type nodeTypeExp = presentation_node_type::on_click; + + EXPECT_EQ(par->attlist_.presentation_node_type_.value_or(presentation_node_type::none).get_type(), nodeTypeExp.get_type()); +} + +TEST_F(OOX2ODP_EntranceAnimationTest, fade_in_innermost_par_preset_class) +{ + using namespace cpdoccore::odf_writer; + using namespace cpdoccore::odf_types; + + const anim_par* par = GetInnermostPar(GetMainSequenceParByIndex(1)); + ASSERT_NE(par, nullptr); + + const preset_class presetClassExp = preset_class::entrance; + + EXPECT_EQ(par->par_attlist_.presentation_preset_class_.value_or(preset_class::custom).get_type(), presetClassExp.get_type()); +} + +TEST_F(OOX2ODP_EntranceAnimationTest, fade_in_innermost_par_preset_id) +{ + using namespace cpdoccore::odf_writer; + using namespace cpdoccore::odf_types; + + const anim_par* par = GetInnermostPar(GetMainSequenceParByIndex(1)); + ASSERT_NE(par, nullptr); + + const preset_id presetIdExp = preset_id::ooo_entrance_fade_in; + + EXPECT_EQ(par->par_attlist_.presentation_preset_id_.value_or(preset_id::none).get_type(), presetIdExp.get_type()); +} + +TEST_F(OOX2ODP_EntranceAnimationTest, appear_transition_filter_duration) +{ + using namespace cpdoccore::odf_writer; + using namespace cpdoccore::odf_types; + + const anim_transitionFilter* transitionFilter = GetAnimationBehaviourByIndex(GetInnermostPar(GetMainSequenceParByIndex(1)), 1); + ASSERT_NE(transitionFilter, nullptr); + + const clockvalue durationExp = clockvalue(500); + + EXPECT_EQ(transitionFilter->common_attlist_.smil_dur_.value_or(clockvalue(-1)).get_value(), durationExp.get_value()); +} + +TEST_F(OOX2ODP_EntranceAnimationTest, appear_transition_filter_subtype) +{ + using namespace cpdoccore::odf_writer; + using namespace cpdoccore::odf_types; + + const anim_transitionFilter* transitionFilter = GetAnimationBehaviourByIndex(GetInnermostPar(GetMainSequenceParByIndex(1)), 1); + ASSERT_NE(transitionFilter, nullptr); + + const std::wstring subtypeExp = L"crossfade"; + + EXPECT_EQ(transitionFilter->filter_attlist_.smil_subtype_.value_or(L"Empty"), subtypeExp); +} + +TEST_F(OOX2ODP_EntranceAnimationTest, appear_transition_filter_type) +{ + using namespace cpdoccore::odf_writer; + using namespace cpdoccore::odf_types; + + const anim_transitionFilter* transitionFilter = GetAnimationBehaviourByIndex(GetInnermostPar(GetMainSequenceParByIndex(1)), 1); + ASSERT_NE(transitionFilter, nullptr); + + const smil_transition_type typeExp = smil_transition_type::fade; + + EXPECT_EQ(transitionFilter->filter_attlist_.smil_type_.value().get_type(), typeExp.get_type()); +} + +TEST_F(OOX2ODP_EntranceAnimationTest, appear_transition_filter_mode) +{ + using namespace cpdoccore::odf_writer; + using namespace cpdoccore::odf_types; + + const anim_transitionFilter* transitionFilter = GetAnimationBehaviourByIndex(GetInnermostPar(GetMainSequenceParByIndex(1)), 1); + ASSERT_NE(transitionFilter, nullptr); + + const std::wstring modeExp = L"in"; + + EXPECT_EQ(transitionFilter->filter_attlist_.smil_mode_.value_or(L"Empty"), modeExp); +} + +//////////////////////////////////////////////////////////// + +TEST_F(OOX2ODP_EntranceAnimationTest, fly_in_outer_par_begin) +{ + using namespace cpdoccore::odf_writer; + using namespace cpdoccore::odf_types; + + const anim_par* par = GetMainSequenceParByIndex(2); + ASSERT_NE(par, nullptr); + + const std::wstring beginExp = L"next"; + + EXPECT_EQ(par->attlist_.smil_begin_.get_value_or(L"Empty"), beginExp); +} + +TEST_F(OOX2ODP_EntranceAnimationTest, fly_in_outer_par_fill) +{ + using namespace cpdoccore::odf_writer; + using namespace cpdoccore::odf_types; + + const anim_par* par = GetMainSequenceParByIndex(2); + ASSERT_NE(par, nullptr); + + const smil_fill fillExp = smil_fill::_hold; + + EXPECT_EQ(par->attlist_.smil_fill_.value_or(smil_fill::none).get_type(), fillExp.get_type()); +} + +TEST_F(OOX2ODP_EntranceAnimationTest, fly_in_inner_par_begin) +{ + using namespace cpdoccore::odf_writer; + using namespace cpdoccore::odf_types; + + const anim_par* par = GetInnerPar(GetMainSequenceParByIndex(2)); + ASSERT_NE(par, nullptr); + + const std::wstring beginExp = L"0s"; + + EXPECT_EQ(par->attlist_.smil_begin_.value_or(L"Empty"), beginExp); +} + +TEST_F(OOX2ODP_EntranceAnimationTest, fly_in_inner_par_fill) +{ + using namespace cpdoccore::odf_writer; + using namespace cpdoccore::odf_types; + + const anim_par* par = GetInnerPar(GetMainSequenceParByIndex(2)); + ASSERT_NE(par, nullptr); + + const smil_fill fillExp = smil_fill::_hold; + + EXPECT_EQ(par->attlist_.smil_fill_.value_or(smil_fill::none).get_type(), fillExp.get_type()); +} + +TEST_F(OOX2ODP_EntranceAnimationTest, fly_in_innermost_par_begin) +{ + using namespace cpdoccore::odf_writer; + using namespace cpdoccore::odf_types; + + const anim_par* par = GetInnermostPar(GetMainSequenceParByIndex(2)); + ASSERT_NE(par, nullptr); + + const std::wstring beginExp = L"0s"; + + EXPECT_EQ(par->attlist_.smil_begin_.value_or(L"Empty"), beginExp); +} + +TEST_F(OOX2ODP_EntranceAnimationTest, fly_in_innermost_par_fill) +{ + using namespace cpdoccore::odf_writer; + using namespace cpdoccore::odf_types; + + const anim_par* par = GetInnermostPar(GetMainSequenceParByIndex(2)); + ASSERT_NE(par, nullptr); + + const smil_fill fillExp = smil_fill::_hold; + + EXPECT_EQ(par->attlist_.smil_fill_.value_or(smil_fill::none).get_type(), fillExp.get_type()); +} + +TEST_F(OOX2ODP_EntranceAnimationTest, fly_in_innermost_par_node_type) +{ + using namespace cpdoccore::odf_writer; + using namespace cpdoccore::odf_types; + + const anim_par* par = GetInnermostPar(GetMainSequenceParByIndex(2)); + ASSERT_NE(par, nullptr); + + const presentation_node_type nodeTypeExp = presentation_node_type::on_click; + + EXPECT_EQ(par->attlist_.presentation_node_type_.value_or(presentation_node_type::none).get_type(), nodeTypeExp.get_type()); +} + +TEST_F(OOX2ODP_EntranceAnimationTest, fly_in_innermost_par_preset_class) +{ + using namespace cpdoccore::odf_writer; + using namespace cpdoccore::odf_types; + + const anim_par* par = GetInnermostPar(GetMainSequenceParByIndex(2)); + ASSERT_NE(par, nullptr); + + const preset_class presetClassExp = preset_class::entrance; + + EXPECT_EQ(par->par_attlist_.presentation_preset_class_.value_or(preset_class::custom).get_type(), presetClassExp.get_type()); +} + +TEST_F(OOX2ODP_EntranceAnimationTest, fly_in_innermost_par_preset_id) +{ + using namespace cpdoccore::odf_writer; + using namespace cpdoccore::odf_types; + + const anim_par* par = GetInnermostPar(GetMainSequenceParByIndex(2)); + ASSERT_NE(par, nullptr); + + const preset_id presetIdExp = preset_id::ooo_entrance_fly_in; + + EXPECT_EQ(par->par_attlist_.presentation_preset_id_.value_or(preset_id::none).get_type(), presetIdExp.get_type()); +} + +TEST_F(OOX2ODP_EntranceAnimationTest, fly_in_animate_duration) +{ + using namespace cpdoccore::odf_writer; + using namespace cpdoccore::odf_types; + + const anim_animate* animate = GetAnimationBehaviourByIndex(GetInnermostPar(GetMainSequenceParByIndex(2)), 1); + ASSERT_NE(animate, nullptr); + + const clockvalue durationExp = clockvalue(500); + + EXPECT_EQ(animate->common_attlist_.smil_dur_.value_or(clockvalue(-1)).get_value(), durationExp.get_value()); +} + +TEST_F(OOX2ODP_EntranceAnimationTest, fly_in_animate_values) +{ + using namespace cpdoccore::odf_writer; + using namespace cpdoccore::odf_types; + + const anim_animate* animate = GetAnimationBehaviourByIndex(GetInnermostPar(GetMainSequenceParByIndex(2)), 1); + ASSERT_NE(animate, nullptr); + + const smil_values valuesExp = smil_values::parse(L"x;x"); + + ASSERT_EQ(animate->animate_attlist_.smil_values_->get_values().size(), valuesExp.get_values().size()); + + for (size_t i = 0; i < valuesExp.get_values().size(); i++) + { + EXPECT_EQ( + animate->animate_attlist_.smil_values_->get_values()[i], + valuesExp.get_values()[i] + ); + } +} + +TEST_F(OOX2ODP_EntranceAnimationTest, fly_in_animate_key_times) +{ + using namespace cpdoccore::odf_writer; + using namespace cpdoccore::odf_types; + + const anim_animate* animate = GetAnimationBehaviourByIndex(GetInnermostPar(GetMainSequenceParByIndex(2)), 1); + ASSERT_NE(animate, nullptr); + + const smil_key_times keyTimesExp = smil_key_times::parse(L"0;1"); + + ASSERT_EQ(animate->animate_attlist_.smil_key_times_->get_values().size(), keyTimesExp.get_values().size()); + + for (size_t i = 0; i < keyTimesExp.get_values().size(); i++) + { + EXPECT_EQ( + animate->animate_attlist_.smil_key_times_->get_values()[i], + keyTimesExp.get_values()[i] + ); + } +} + +//////////////////////////////////////////////////////////// + +TEST_F(OOX2ODP_EntranceAnimationTest, ascend_outer_par_begin) +{ + using namespace cpdoccore::odf_writer; + using namespace cpdoccore::odf_types; + + const anim_par* par = GetMainSequenceParByIndex(3); + ASSERT_NE(par, nullptr); + + const std::wstring beginExp = L"next"; + + EXPECT_EQ(par->attlist_.smil_begin_.get_value_or(L"Empty"), beginExp); +} + +TEST_F(OOX2ODP_EntranceAnimationTest, ascend_outer_par_fill) +{ + using namespace cpdoccore::odf_writer; + using namespace cpdoccore::odf_types; + + const anim_par* par = GetMainSequenceParByIndex(3); + ASSERT_NE(par, nullptr); + + const smil_fill fillExp = smil_fill::_hold; + + EXPECT_EQ(par->attlist_.smil_fill_.value_or(smil_fill::none).get_type(), fillExp.get_type()); +} + +TEST_F(OOX2ODP_EntranceAnimationTest, ascend_inner_par_begin) +{ + using namespace cpdoccore::odf_writer; + using namespace cpdoccore::odf_types; + + const anim_par* par = GetInnerPar(GetMainSequenceParByIndex(3)); + ASSERT_NE(par, nullptr); + + const std::wstring beginExp = L"0s"; + + EXPECT_EQ(par->attlist_.smil_begin_.value_or(L"Empty"), beginExp); +} + +TEST_F(OOX2ODP_EntranceAnimationTest, ascend_inner_par_fill) +{ + using namespace cpdoccore::odf_writer; + using namespace cpdoccore::odf_types; + + const anim_par* par = GetInnerPar(GetMainSequenceParByIndex(3)); + ASSERT_NE(par, nullptr); + + const smil_fill fillExp = smil_fill::_hold; + + EXPECT_EQ(par->attlist_.smil_fill_.value_or(smil_fill::none).get_type(), fillExp.get_type()); +} + +TEST_F(OOX2ODP_EntranceAnimationTest, ascend_innermost_par_begin) +{ + using namespace cpdoccore::odf_writer; + using namespace cpdoccore::odf_types; + + const anim_par* par = GetInnermostPar(GetMainSequenceParByIndex(3)); + ASSERT_NE(par, nullptr); + + const std::wstring beginExp = L"0s"; + + EXPECT_EQ(par->attlist_.smil_begin_.value_or(L"Empty"), beginExp); +} + +TEST_F(OOX2ODP_EntranceAnimationTest, ascend_innermost_par_fill) +{ + using namespace cpdoccore::odf_writer; + using namespace cpdoccore::odf_types; + + const anim_par* par = GetInnermostPar(GetMainSequenceParByIndex(3)); + ASSERT_NE(par, nullptr); + + const smil_fill fillExp = smil_fill::_hold; + + EXPECT_EQ(par->attlist_.smil_fill_.value_or(smil_fill::none).get_type(), fillExp.get_type()); +} + +TEST_F(OOX2ODP_EntranceAnimationTest, ascend_innermost_par_node_type) +{ + using namespace cpdoccore::odf_writer; + using namespace cpdoccore::odf_types; + + const anim_par* par = GetInnermostPar(GetMainSequenceParByIndex(3)); + ASSERT_NE(par, nullptr); + + const presentation_node_type nodeTypeExp = presentation_node_type::on_click; + + EXPECT_EQ(par->attlist_.presentation_node_type_.value_or(presentation_node_type::none).get_type(), nodeTypeExp.get_type()); +} + +TEST_F(OOX2ODP_EntranceAnimationTest, ascend_innermost_par_preset_class) +{ + using namespace cpdoccore::odf_writer; + using namespace cpdoccore::odf_types; + + const anim_par* par = GetInnermostPar(GetMainSequenceParByIndex(3)); + ASSERT_NE(par, nullptr); + + const preset_class presetClassExp = preset_class::entrance; + + EXPECT_EQ(par->par_attlist_.presentation_preset_class_.value_or(preset_class::custom).get_type(), presetClassExp.get_type()); +} + +TEST_F(OOX2ODP_EntranceAnimationTest, ascend_innermost_par_preset_id) +{ + using namespace cpdoccore::odf_writer; + using namespace cpdoccore::odf_types; + + const anim_par* par = GetInnermostPar(GetMainSequenceParByIndex(3)); + ASSERT_NE(par, nullptr); + + const preset_id presetIdExp = preset_id::ooo_entrance_ascend; + + EXPECT_EQ(par->par_attlist_.presentation_preset_id_.value_or(preset_id::none).get_type(), presetIdExp.get_type()); +} diff --git a/OdfFile/Test/entrance.h b/OdfFile/Test/entrance.h new file mode 100644 index 00000000000..0e22ff127aa --- /dev/null +++ b/OdfFile/Test/entrance.h @@ -0,0 +1,97 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ + +#include "gtest/gtest.h" +#include "common.h" + +#include + +#include "Reader/Format/odf_document.h" +#include "Reader/Converter/pptx_conversion_context.h" + +#include "Writer/Converter/Oox2OdfConverter.h" +#include "Writer/Format/odp_conversion_context.h" +#include "Writer/Format/anim_elements.h" +#include "Writer/Format/draw_page.h" + +class ODP2OOX_AnimationEntranceEnvironment : public ODP2OOX_AnimationEnvironment +{ +public: + ODP2OOX_AnimationEntranceEnvironment(); + + static const cpdoccore::oox::pptx_animation_context& GetAnimationContext(); + +private: + static boost::shared_ptr sConverionContext; + static boost::shared_ptr sInputOdf; +}; + +class ODP2OOX_EntranceAnimationTest : public testing::Test +{ +public: + void SetUp() override; + void TearDown() override + { } + + const cpdoccore::oox::pptx_animation_context::Impl::_par_animation_ptr& GetInnerPar(const cpdoccore::oox::pptx_animation_context::Impl::_par_animation_ptr& par); + const cpdoccore::oox::pptx_animation_context::Impl::_seq_animation_ptr& GetMainSequence(); + const cpdoccore::oox::pptx_animation_context::Impl::_par_animation_array& GetMainSequenceArray(); + const cpdoccore::oox::pptx_animation_context::Impl::_animation_element_array& GetActionArray(const cpdoccore::oox::pptx_animation_context::Impl::_par_animation_ptr& par); + const cpdoccore::oox::pptx_animation_context::Impl::_par_animation_ptr GetInnermostPar(const cpdoccore::oox::pptx_animation_context::Impl::_par_animation_ptr& par); + const cpdoccore::oox::pptx_animation_context::Impl::_animation_element_array& GetAnimationActionsByIndex(size_t index); + +public: + const cpdoccore::oox::pptx_animation_context* mAnimationContext; +}; + +////////////////////////////////////////////////////////////////////////// +// OOX2ODP + +class OOX2ODP_EntranceAnimationEnvironment : public OOX2ODP_AnimationEnvironment +{ +public: + OOX2ODP_EntranceAnimationEnvironment(); + +public: + static cpdoccore::odf_writer::odp_conversion_context* GetContext(); + +private: + static boost::shared_ptr mConverter; + static cpdoccore::odf_writer::odp_conversion_context* mContext; +}; + +class OOX2ODP_EntranceAnimationTest : public OOX2ODP_AnimationTest +{ +public: + void SetUp() override; + void TearDown() override {} +}; \ No newline at end of file diff --git a/OdfFile/Test/interactions.cpp b/OdfFile/Test/interactions.cpp new file mode 100644 index 00000000000..8247f9b8569 --- /dev/null +++ b/OdfFile/Test/interactions.cpp @@ -0,0 +1,543 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ + +#include "interactions.h" + +#include "Writer/Format/anim_elements.h" + +boost::shared_ptr OOX2ODP_InteractionAnimationEnvironment::mConverter; +cpdoccore::odf_writer::odp_conversion_context* OOX2ODP_InteractionAnimationEnvironment::mContext; + +OOX2ODP_InteractionAnimationEnvironment::OOX2ODP_InteractionAnimationEnvironment() + : OOX2ODP_AnimationEnvironment(L"interaction.pptx", &mConverter, &mContext) +{ +} + +cpdoccore::odf_writer::odp_conversion_context* OOX2ODP_InteractionAnimationEnvironment::GetContext() +{ + return mContext; +} + +void OOX2ODP_InteractionAnimationTest::SetUp() +{ + mContext = OOX2ODP_InteractionAnimationEnvironment::GetContext(); +} + +TEST_F(OOX2ODP_InteractionAnimationTest, timing_root) +{ + using namespace cpdoccore::odf_writer; + using namespace cpdoccore::odf_types; + + const anim_par* root = GetTimingRoot(); + EXPECT_NE(root, nullptr); +} + +TEST_F(OOX2ODP_InteractionAnimationTest, timing_root_duration) +{ + using namespace cpdoccore::odf_writer; + using namespace cpdoccore::odf_types; + + const anim_par* root = GetTimingRoot(); + ASSERT_NE(root, nullptr); + + const int durExp = -1; + + EXPECT_EQ(root->attlist_.smil_dur_.value().get_value(), durExp); +} + +TEST_F(OOX2ODP_InteractionAnimationTest, timing_root_node_type) +{ + using namespace cpdoccore::odf_writer; + using namespace cpdoccore::odf_types; + + const anim_par* root = GetTimingRoot(); + ASSERT_NE(root, nullptr); + + const presentation_node_type nodeTypeExp = presentation_node_type::parse(L"timing-root"); + + EXPECT_EQ(root->attlist_.presentation_node_type_.value().get_type(), nodeTypeExp.get_type()); +} + +TEST_F(OOX2ODP_InteractionAnimationTest, interactive_seq) +{ + using namespace cpdoccore::odf_writer; + using namespace cpdoccore::odf_types; + + const anim_par* root = GetTimingRoot(); + ASSERT_NE(root, nullptr); + const anim_seq* interactive = dynamic_cast(root->anim_seq_array_[0].get()); + + EXPECT_NE(interactive, nullptr); +} + +TEST_F(OOX2ODP_InteractionAnimationTest, interactive_seq_node_type) +{ + using namespace cpdoccore::odf_writer; + using namespace cpdoccore::odf_types; + + const anim_par* root = GetTimingRoot(); + ASSERT_NE(root, nullptr); + const anim_seq* interactive = dynamic_cast(root->anim_seq_array_[0].get()); + ASSERT_NE(interactive, nullptr); + + const presentation_node_type nodeTypeExp = presentation_node_type::parse(L"interactive-sequence"); + + EXPECT_NE(interactive, nullptr); +} + +TEST_F(OOX2ODP_InteractionAnimationTest, interactive_seq_restart) +{ + using namespace cpdoccore::odf_writer; + using namespace cpdoccore::odf_types; + + const anim_par* root = GetTimingRoot(); + ASSERT_NE(root, nullptr); + const anim_seq* interactive = dynamic_cast(root->anim_seq_array_[0].get()); + ASSERT_NE(interactive, nullptr); + + const std::wstring restartExp = L""; + + EXPECT_NE(interactive->attlist_.smil_restart_.value(), restartExp); +} + +TEST_F(OOX2ODP_InteractionAnimationTest, interactive_seq_fill) +{ + using namespace cpdoccore::odf_writer; + using namespace cpdoccore::odf_types; + + const anim_par* root = GetTimingRoot(); + ASSERT_NE(root, nullptr); + const anim_seq* interactive = dynamic_cast(root->anim_seq_array_[0].get()); + ASSERT_NE(interactive, nullptr); + + const smil_fill fillExp = smil_fill::_remove; + + EXPECT_NE(interactive->attlist_.smil_fill_.value().get_type(), fillExp.get_type()); +} + +TEST_F(OOX2ODP_InteractionAnimationTest, interactive_seq_begin) +{ + using namespace cpdoccore::odf_writer; + using namespace cpdoccore::odf_types; + + const anim_par* root = GetTimingRoot(); + ASSERT_NE(root, nullptr); + const anim_seq* interactive = dynamic_cast(root->anim_seq_array_[0].get()); + ASSERT_NE(interactive, nullptr); + + const std::wstring restartExp = L""; + + EXPECT_NE(interactive->attlist_.smil_begin_.value(), restartExp); +} + +////////////////////////////////////////////////////////////////////////// + +boost::shared_ptr ODP2OOX_AnimationPlayAudioEnvironment::sInputOdf; +boost::shared_ptr ODP2OOX_AnimationPlayAudioEnvironment::sConverionContext; + +ODP2OOX_AnimationPlayAudioEnvironment::ODP2OOX_AnimationPlayAudioEnvironment() + : ODP2OOX_AnimationEnvironment(L"ExampleFiles" FILE_SEPARATOR_STR "playAudio.odp", + &sInputOdf, + &sConverionContext) +{ + +} + +cpdoccore::oox::pptx_conversion_context& ODP2OOX_AnimationPlayAudioEnvironment::GetConversionContext() +{ + return *sConverionContext; +} + +void ODP2OOX_AnimationPlayAudioTest::SetUp() +{ + mConversionContext = &ODP2OOX_AnimationPlayAudioEnvironment::GetConversionContext(); +} + +TEST_F(ODP2OOX_AnimationPlayAudioTest, mediaitems_size) +{ + ASSERT_NE(mConversionContext, nullptr); + + auto items = mConversionContext->get_mediaitems()->items(); + const size_t itemsSizeExp = 1; + + EXPECT_EQ(items.size(), itemsSizeExp); +} + +TEST_F(ODP2OOX_AnimationPlayAudioTest, rels_size) +{ + ASSERT_NE(mConversionContext, nullptr); + + auto rels_ = mConversionContext->current_slide().Rels().relationships(); + const size_t relsSizeExp = 2; + + EXPECT_EQ(rels_.size(), relsSizeExp); +} + +TEST_F(ODP2OOX_AnimationPlayAudioTest, audio_slide_rel_type) +{ + ASSERT_NE(mConversionContext, nullptr); + + auto slideRel = mConversionContext->current_slide().Rels().relationships()[0]; + const std::wstring typeExp = L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout"; + + EXPECT_EQ(slideRel.type(), typeExp); +} + +TEST_F(ODP2OOX_AnimationPlayAudioTest, audio_slide_rel_target) +{ + ASSERT_NE(mConversionContext, nullptr); + + auto slideRel = mConversionContext->current_slide().Rels().relationships()[0]; + const std::wstring targetExp = L"../slideLayouts/slideLayout1.xml"; + + EXPECT_EQ(slideRel.target(), targetExp); +} + +TEST_F(ODP2OOX_AnimationPlayAudioTest, audio_slide_rel_target_mode) +{ + ASSERT_NE(mConversionContext, nullptr); + + auto slideRel = mConversionContext->current_slide().Rels().relationships()[0]; + const std::wstring targetModeExp = L""; + + EXPECT_EQ(slideRel.target_mode(), targetModeExp); +} + +TEST_F(ODP2OOX_AnimationPlayAudioTest, audio_notes_rel_type) +{ + ASSERT_NE(mConversionContext, nullptr); + + auto notesRel = mConversionContext->current_slide().Rels().relationships()[1]; + const std::wstring typeExp = L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/notesSlide"; + + EXPECT_EQ(notesRel.type(), typeExp); +} + +TEST_F(ODP2OOX_AnimationPlayAudioTest, audio_notes_rel_target) +{ + ASSERT_NE(mConversionContext, nullptr); + + auto notesRel = mConversionContext->current_slide().Rels().relationships()[1]; + const std::wstring targetExp = L"../notesSlides/notesSlide1.xml"; + + EXPECT_EQ(notesRel.target(), targetExp); +} + +TEST_F(ODP2OOX_AnimationPlayAudioTest, audio_notes_rel_target_mode) +{ + ASSERT_NE(mConversionContext, nullptr); + + auto notesRel = mConversionContext->current_slide().Rels().relationships()[1]; + const std::wstring targetModeExp = L""; + + EXPECT_EQ(notesRel.target_mode(), targetModeExp); +} + +////////////////////////////////////////////////////////////////////////// + +boost::shared_ptr ODP2OOX_AnimationOpenDocumentEnvironment::sInputOdf; +boost::shared_ptr ODP2OOX_AnimationOpenDocumentEnvironment::sConverionContext; + +ODP2OOX_AnimationOpenDocumentEnvironment::ODP2OOX_AnimationOpenDocumentEnvironment() + : ODP2OOX_AnimationEnvironment(L"ExampleFiles" FILE_SEPARATOR_STR "openDocument.odp", + &sInputOdf, + &sConverionContext) +{ +} + +cpdoccore::oox::pptx_conversion_context& ODP2OOX_AnimationOpenDocumentEnvironment::GetConversionContext() +{ + return *sConverionContext; +} + +void ODP2OOX_AnimationOpenDocumentTest::SetUp() +{ + mConversionContext = &ODP2OOX_AnimationOpenDocumentEnvironment::GetConversionContext(); +} + +TEST_F(ODP2OOX_AnimationOpenDocumentTest, mediaitems_size) +{ + ASSERT_NE(mConversionContext, nullptr); + + auto items = mConversionContext->get_mediaitems()->items(); + const size_t itemsSizeExp = 1; + + EXPECT_EQ(items.size(), itemsSizeExp); +} + +TEST_F(ODP2OOX_AnimationOpenDocumentTest, rels_size) +{ + ASSERT_NE(mConversionContext, nullptr); + + auto rels_ = mConversionContext->current_slide().Rels().relationships(); + const size_t relsSizeExp = 3; + + EXPECT_EQ(rels_.size(), 3); +} + +TEST_F(ODP2OOX_AnimationOpenDocumentTest, document_rel_id) +{ + ASSERT_NE(mConversionContext, nullptr); + + auto docRel = mConversionContext->current_slide().Rels().relationships()[1]; + const std::wstring idExp = L"hId1"; + + EXPECT_EQ(docRel.id(), idExp); +} + +TEST_F(ODP2OOX_AnimationOpenDocumentTest, document_rel_type) +{ + ASSERT_NE(mConversionContext, nullptr); + + auto docRel = mConversionContext->current_slide().Rels().relationships()[1]; + const std::wstring typeExp = L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink"; + + EXPECT_EQ(docRel.type(), typeExp); +} + +TEST_F(ODP2OOX_AnimationOpenDocumentTest, document_rel_target) +{ + ASSERT_NE(mConversionContext, nullptr); + + auto docRel = mConversionContext->current_slide().Rels().relationships()[1]; + const std::wstring targetExp = L"motion.odp"; + + EXPECT_EQ(docRel.target(), targetExp); +} + +TEST_F(ODP2OOX_AnimationOpenDocumentTest, document_rel_target_mode) +{ + ASSERT_NE(mConversionContext, nullptr); + + auto docRel = mConversionContext->current_slide().Rels().relationships()[1]; + const std::wstring targetModeExp = L"External"; + + EXPECT_EQ(docRel.target_mode(), targetModeExp); +} + +////////////////////////////////////////////////////////////////////////// + +boost::shared_ptr ODP2OOX_AnimationRunProgramEnvironment::sInputOdf; +boost::shared_ptr ODP2OOX_AnimationRunProgramEnvironment::sConverionContext; + +ODP2OOX_AnimationRunProgramEnvironment::ODP2OOX_AnimationRunProgramEnvironment() + : ODP2OOX_AnimationEnvironment(L"ExampleFiles" FILE_SEPARATOR_STR "runProgram.odp", + &sInputOdf, + &sConverionContext) +{ +} + +cpdoccore::oox::pptx_conversion_context& ODP2OOX_AnimationRunProgramEnvironment::GetConversionContext() +{ + return *sConverionContext; +} + +void ODP2OOX_AnimationRunProgramTest::SetUp() +{ + mConversionContext = &ODP2OOX_AnimationRunProgramEnvironment::GetConversionContext(); +} + +TEST_F(ODP2OOX_AnimationRunProgramTest, rels_size) +{ + ASSERT_NE(mConversionContext, nullptr); + + auto rels_ = mConversionContext->current_slide().Rels().relationships(); + const size_t relsSizeExp = 3; + + EXPECT_EQ(rels_.size(), 3); +} + +TEST_F(ODP2OOX_AnimationRunProgramTest, program_rel_id) +{ + ASSERT_NE(mConversionContext, nullptr); + + auto programRel = mConversionContext->current_slide().Rels().relationships()[1]; + const std::wstring idExp = L"hId1"; + + EXPECT_EQ(programRel.id(), idExp); +} + +TEST_F(ODP2OOX_AnimationRunProgramTest, program_rel_type) +{ + ASSERT_NE(mConversionContext, nullptr); + + auto programRel = mConversionContext->current_slide().Rels().relationships()[1]; + const std::wstring typeExp = L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink"; + + EXPECT_EQ(programRel.type(), typeExp); +} + +TEST_F(ODP2OOX_AnimationRunProgramTest, program_rel_target) +{ + ASSERT_NE(mConversionContext, nullptr); + + auto programRel = mConversionContext->current_slide().Rels().relationships()[1]; + const std::wstring targetExp = L"../../../../build_tools/out/win_64/onlyoffice/core/x2t.exe"; + + EXPECT_EQ(programRel.target(), targetExp); +} + +TEST_F(ODP2OOX_AnimationRunProgramTest, program_rel_target_mode) +{ + ASSERT_NE(mConversionContext, nullptr); + + auto programRel = mConversionContext->current_slide().Rels().relationships()[1]; + const std::wstring targetModeExp = L"External"; + + EXPECT_EQ(programRel.target_mode(), targetModeExp); +} + +////////////////////////////////////////////////////////////////////////// + +boost::shared_ptr OOX2ODP_PlayAudioAnimationEnvironment::mConverter; +cpdoccore::odf_writer::odp_conversion_context* OOX2ODP_PlayAudioAnimationEnvironment::mContext; + +OOX2ODP_PlayAudioAnimationEnvironment::OOX2ODP_PlayAudioAnimationEnvironment() + : OOX2ODP_AnimationEnvironment(L"playAudio.pptx", &mConverter, &mContext) +{ +} + +cpdoccore::odf_writer::odp_conversion_context* OOX2ODP_PlayAudioAnimationEnvironment::GetContext() +{ + return mContext; +} + +void OOX2ODP_PlayAudioAnimationTest::SetUp() +{ + mContext = OOX2ODP_PlayAudioAnimationEnvironment::GetContext(); +} + +TEST_F(OOX2ODP_PlayAudioAnimationTest, mediaitems_size) +{ + ASSERT_NE(mContext, nullptr); + + auto items = mContext->get_deferred_hyperlinks(); + const size_t mediaitemsSizeExp = 1; + + EXPECT_EQ(items.size(), mediaitemsSizeExp); +} + +TEST_F(OOX2ODP_PlayAudioAnimationTest, mediaitem_path) +{ + ASSERT_NE(mContext, nullptr); + auto items = mContext->get_deferred_hyperlinks(); + ASSERT_GE(items.size(), 1); + + auto audioItem = items[0]; + const std::wstring audioItemPath = L"../../../X2tConverter/test/win32Test/Res/media_example"; + + EXPECT_EQ(audioItem.second, audioItemPath); +} + +////////////////////////////////////////////////////////////////////////// + +boost::shared_ptr OOX2ODP_OpenDocumentAnimationEnvironment::mConverter; +cpdoccore::odf_writer::odp_conversion_context* OOX2ODP_OpenDocumentAnimationEnvironment::mContext; + +OOX2ODP_OpenDocumentAnimationEnvironment::OOX2ODP_OpenDocumentAnimationEnvironment() + : OOX2ODP_AnimationEnvironment(L"openDocument.pptx", &mConverter, &mContext) +{ +} + +cpdoccore::odf_writer::odp_conversion_context* OOX2ODP_OpenDocumentAnimationEnvironment::GetContext() +{ + return mContext; +} + +void OOX2ODP_OpenDocumentAnimationTest::SetUp() +{ + mContext = OOX2ODP_OpenDocumentAnimationEnvironment::GetContext(); +} + +TEST_F(OOX2ODP_OpenDocumentAnimationTest, mediaitems_size) +{ + ASSERT_NE(mContext, nullptr); + + auto items = mContext->get_deferred_hyperlinks(); + const size_t mediaitemsSizeExp = 1; + + EXPECT_EQ(items.size(), mediaitemsSizeExp); +} + +TEST_F(OOX2ODP_OpenDocumentAnimationTest, mediaitem_path) +{ + ASSERT_NE(mContext, nullptr); + auto items = mContext->get_deferred_hyperlinks(); + ASSERT_GE(items.size(), 1); + + auto audioItem = items[0]; + const std::wstring audioItemPath = L"entrance"; + + EXPECT_EQ(audioItem.second, audioItemPath); +} + +////////////////////////////////////////////////////////////////////////// + +boost::shared_ptr OOX2ODP_RunProgramAnimationEnvironment::mConverter; +cpdoccore::odf_writer::odp_conversion_context* OOX2ODP_RunProgramAnimationEnvironment::mContext; + +OOX2ODP_RunProgramAnimationEnvironment::OOX2ODP_RunProgramAnimationEnvironment() + : OOX2ODP_AnimationEnvironment(L"runProgram.pptx", &mConverter, &mContext) +{ +} + +cpdoccore::odf_writer::odp_conversion_context* OOX2ODP_RunProgramAnimationEnvironment::GetContext() +{ + return mContext; +} + +void OOX2ODP_RunProgramAnimationTest::SetUp() +{ + mContext = OOX2ODP_RunProgramAnimationEnvironment::GetContext(); +} + +TEST_F(OOX2ODP_RunProgramAnimationTest, mediaitems_size) +{ + ASSERT_NE(mContext, nullptr); + + auto items = mContext->get_deferred_hyperlinks(); + const size_t mediaitemsSizeExp = 1; + + EXPECT_EQ(items.size(), mediaitemsSizeExp); +} + +TEST_F(OOX2ODP_RunProgramAnimationTest, mediaitem_path) +{ + ASSERT_NE(mContext, nullptr); + auto items = mContext->get_deferred_hyperlinks(); + ASSERT_GE(items.size(), 1); + + auto audioItem = items[0]; + const std::wstring audioItemPath = L"../../../../build_tools/out/win_64/onlyoffice/core/x2t"; + + EXPECT_EQ(audioItem.second, audioItemPath); +} \ No newline at end of file diff --git a/OdfFile/Test/interactions.h b/OdfFile/Test/interactions.h new file mode 100644 index 00000000000..a4219b54f10 --- /dev/null +++ b/OdfFile/Test/interactions.h @@ -0,0 +1,197 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#pragma once + +#include "common.h" + +#include "gtest/gtest.h" + +class OOX2ODP_InteractionAnimationEnvironment : public OOX2ODP_AnimationEnvironment +{ +public: + OOX2ODP_InteractionAnimationEnvironment(); + +public: + static cpdoccore::odf_writer::odp_conversion_context* GetContext(); + +private: + static boost::shared_ptr mConverter; + static cpdoccore::odf_writer::odp_conversion_context* mContext; +}; + +class OOX2ODP_InteractionAnimationTest : public OOX2ODP_AnimationTest +{ +public: + void SetUp() override; + void TearDown() override {} +}; + +////////////////////////////////////////////////////////////////////////// + +class ODP2OOX_AnimationPlayAudioEnvironment : public ODP2OOX_AnimationEnvironment +{ +public: + ODP2OOX_AnimationPlayAudioEnvironment(); + + static cpdoccore::oox::pptx_conversion_context& GetConversionContext(); + +private: + static boost::shared_ptr sInputOdf; + static boost::shared_ptr sConverionContext; +}; + +class ODP2OOX_AnimationPlayAudioTest : public testing::Test +{ +public: + void SetUp() override; + void TearDown() override + { } + +public: + cpdoccore::oox::pptx_conversion_context* mConversionContext; +}; + +////////////////////////////////////////////////////////////////////////// + +class ODP2OOX_AnimationOpenDocumentEnvironment : public ODP2OOX_AnimationEnvironment +{ +public: + ODP2OOX_AnimationOpenDocumentEnvironment(); + + static cpdoccore::oox::pptx_conversion_context& GetConversionContext(); + +private: + static boost::shared_ptr sInputOdf; + static boost::shared_ptr sConverionContext; +}; + +class ODP2OOX_AnimationOpenDocumentTest : public testing::Test +{ +public: + void SetUp() override; + void TearDown() override + { } + +public: + cpdoccore::oox::pptx_conversion_context* mConversionContext; +}; + +////////////////////////////////////////////////////////////////////////// + +class ODP2OOX_AnimationRunProgramEnvironment : public ODP2OOX_AnimationEnvironment +{ +public: + ODP2OOX_AnimationRunProgramEnvironment(); + + static cpdoccore::oox::pptx_conversion_context& GetConversionContext(); + +private: + static boost::shared_ptr sInputOdf; + static boost::shared_ptr sConverionContext; +}; + +class ODP2OOX_AnimationRunProgramTest : public testing::Test +{ +public: + void SetUp() override; + void TearDown() override + { } + +public: + cpdoccore::oox::pptx_conversion_context* mConversionContext; +}; + +////////////////////////////////////////////////////////////////////////// + +class OOX2ODP_PlayAudioAnimationEnvironment : public OOX2ODP_AnimationEnvironment +{ +public: + OOX2ODP_PlayAudioAnimationEnvironment(); + +public: + static cpdoccore::odf_writer::odp_conversion_context* GetContext(); + +private: + static boost::shared_ptr mConverter; + static cpdoccore::odf_writer::odp_conversion_context* mContext; +}; + +class OOX2ODP_PlayAudioAnimationTest : public OOX2ODP_AnimationTest +{ +public: + void SetUp() override; + void TearDown() override {} +}; + +////////////////////////////////////////////////////////////////////////// + +class OOX2ODP_OpenDocumentAnimationEnvironment : public OOX2ODP_AnimationEnvironment +{ +public: + OOX2ODP_OpenDocumentAnimationEnvironment(); + +public: + static cpdoccore::odf_writer::odp_conversion_context* GetContext(); + +private: + static boost::shared_ptr mConverter; + static cpdoccore::odf_writer::odp_conversion_context* mContext; +}; + +class OOX2ODP_OpenDocumentAnimationTest : public OOX2ODP_AnimationTest +{ +public: + void SetUp() override; + void TearDown() override {} +}; + +////////////////////////////////////////////////////////////////////////// + +class OOX2ODP_RunProgramAnimationEnvironment : public OOX2ODP_AnimationEnvironment +{ +public: + OOX2ODP_RunProgramAnimationEnvironment(); + +public: + static cpdoccore::odf_writer::odp_conversion_context* GetContext(); + +private: + static boost::shared_ptr mConverter; + static cpdoccore::odf_writer::odp_conversion_context* mContext; +}; + +class OOX2ODP_RunProgramAnimationTest : public OOX2ODP_AnimationTest +{ +public: + void SetUp() override; + void TearDown() override {} +}; diff --git a/OdfFile/Test/motion.cpp b/OdfFile/Test/motion.cpp new file mode 100644 index 00000000000..e28438d06c3 --- /dev/null +++ b/OdfFile/Test/motion.cpp @@ -0,0 +1,402 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ + +#include "motion.h" + +boost::shared_ptr ODP2OOX_AnimationMotionEnvironment::sInputOdf; +boost::shared_ptr ODP2OOX_AnimationMotionEnvironment::sConverionContext; + +ODP2OOX_AnimationMotionEnvironment::ODP2OOX_AnimationMotionEnvironment() + : ODP2OOX_AnimationEnvironment(L"ExampleFiles" FILE_SEPARATOR_STR "motion.odp", + &sInputOdf, + &sConverionContext) +{ +} + +const cpdoccore::oox::pptx_animation_context& ODP2OOX_AnimationMotionEnvironment::GetAnimationContext() +{ + return sConverionContext->get_slide_context().get_animation_context(); +} + +void ODP2OOX_MotionAnimationTest::SetUp() +{ + mAnimationContext = &ODP2OOX_AnimationMotionEnvironment::GetAnimationContext(); +} + +const cpdoccore::oox::pptx_animation_context::Impl::_par_animation_ptr& ODP2OOX_MotionAnimationTest::GetInnerPar(const cpdoccore::oox::pptx_animation_context::Impl::_par_animation_ptr& par) +{ + return par->AnimParArray[0]; +} + +const cpdoccore::oox::pptx_animation_context::Impl::_seq_animation_ptr& ODP2OOX_MotionAnimationTest::GetMainSequence() +{ + if(mAnimationContext->get_root_par_animation()->AnimSeq.size()) + return mAnimationContext->get_root_par_animation()->AnimSeq[0]; + return nullptr; +} + +const cpdoccore::oox::pptx_animation_context::Impl::_par_animation_array& ODP2OOX_MotionAnimationTest::GetMainSequenceArray() +{ + return GetMainSequence()->AnimParArray; +} + +const cpdoccore::oox::pptx_animation_context::Impl::_animation_element_array& ODP2OOX_MotionAnimationTest::GetActionArray(const cpdoccore::oox::pptx_animation_context::Impl::_par_animation_ptr& par) +{ + return par->AnimationActionArray; +} + +const cpdoccore::oox::pptx_animation_context::Impl::_par_animation_ptr ODP2OOX_MotionAnimationTest::GetInnermostPar(const cpdoccore::oox::pptx_animation_context::Impl::_par_animation_ptr& par) +{ + using namespace cpdoccore::oox; + cpdoccore::oox::pptx_animation_context::Impl::_par_animation_ptr inner = par; + + while (inner->AnimParArray.size()) + inner = GetInnerPar(inner); + + return inner; +} + +const cpdoccore::oox::pptx_animation_context::Impl::_animation_element_array& ODP2OOX_MotionAnimationTest::GetAnimationActionsByIndex(size_t index) +{ + using namespace cpdoccore::oox; + const pptx_animation_context::Impl::_par_animation_array& main_seq = GetMainSequenceArray(); + const pptx_animation_context::Impl::_animation_element_array& actions = GetInnermostPar(main_seq[index])->AnimationActionArray; + + return actions; +} + +const std::vector ODP2OOX_MotionAnimationTest::ParseSvgPath(const std::wstring& path) +{ + std::vector polylines; + + bool closed, stroked; + svg_path::parseSvgD(polylines, path, false, closed, stroked); + + return polylines; +} + +void ODP2OOX_MotionAnimationTest::CompareSvgPath(const std::vector& left, const std::vector& right) +{ + ASSERT_EQ(left.size(), right.size()); + for (size_t i = 0; i < left.size(); i++) + { + EXPECT_EQ(left[i].command, right[i].command); + EXPECT_EQ(left[i].points.size(), right[i].points.size()); + for (size_t p = 0; p < left[i].points.size(); p++) + { + EXPECT_EQ(left[i].points[p].x.has_value(), right[i].points[p].x.has_value()); + EXPECT_EQ(left[i].points[p].y.has_value(), right[i].points[p].y.has_value()); + + double x = left[i].points[p].x.value_or(0.0); + double y = left[i].points[p].y.value_or(0.0); + double xExp = right[i].points[p].x.value_or(0.0); + double yExp = right[i].points[p].y.value_or(0.0); + + EXPECT_NEAR(x, xExp, mEpsilon); + EXPECT_NEAR(y, yExp, mEpsilon); + } + } +} + +TEST_F(ODP2OOX_MotionAnimationTest, motionpath_polygon_duration) +{ + using namespace cpdoccore::oox; + const size_t animationIndex = 0; + const pptx_animation_context::Impl::_animation_element_array& actions = GetAnimationActionsByIndex(animationIndex); + + const pptx_animation_context::Impl::_animate_motion* motion = dynamic_cast(actions[0].get()); + const int durationExp = 2000; + + EXPECT_EQ(motion->SmilDurMs.value(), durationExp); +} + +TEST_F(ODP2OOX_MotionAnimationTest, motionpath_polygon_fill) +{ + using namespace cpdoccore::oox; + const size_t animationIndex = 0; + const pptx_animation_context::Impl::_animation_element_array& actions = GetAnimationActionsByIndex(animationIndex); + + const pptx_animation_context::Impl::_animate_motion* motion = dynamic_cast(actions[0].get()); + const std::wstring fillExp = L"hold"; + + EXPECT_EQ(motion->SmilFill.value(), fillExp); +} + +TEST_F(ODP2OOX_MotionAnimationTest, motionpath_polygon_path) +{ + using namespace cpdoccore::oox; + const size_t animationIndex = 0; + const pptx_animation_context::Impl::_animation_element_array& actions = GetAnimationActionsByIndex(animationIndex); + + const pptx_animation_context::Impl::_animate_motion* motion = dynamic_cast(actions[0].get()); + const std::wstring pathExp = L"M -0.00978571428571429 0.000253968253968254 L 0.311285714285715 -0.423111111111111 L 0.299714285714286 -0.390539682539682 L 0.625607142857143 0.262539682539683 L 0.0596071428571431 0.355111111111111 L 0.282357142857143 -0.0340317460317456 E"; + + std::vector<::svg_path::_polyline> polylines = ParseSvgPath(motion->SvgPath.value()); + std::vector<::svg_path::_polyline> polylinesExp = ParseSvgPath(pathExp); + + CompareSvgPath(polylines, polylinesExp); +} + +TEST_F(ODP2OOX_MotionAnimationTest, motionpath_curve_duration) +{ + using namespace cpdoccore::oox; + const size_t animationIndex = 1; + const pptx_animation_context::Impl::_animation_element_array& actions = GetAnimationActionsByIndex(animationIndex); + + const pptx_animation_context::Impl::_animate_motion* motion = dynamic_cast(actions[0].get()); + const int durationExp = 2000; + + EXPECT_EQ(motion->SmilDurMs.value(), durationExp); +} + +TEST_F(ODP2OOX_MotionAnimationTest, motionpath_curve_fill) +{ + using namespace cpdoccore::oox; + const size_t animationIndex = 1; + const pptx_animation_context::Impl::_animation_element_array& actions = GetAnimationActionsByIndex(animationIndex); + + const pptx_animation_context::Impl::_animate_motion* motion = dynamic_cast(actions[0].get()); + const std::wstring fillExp = L"hold"; + + EXPECT_EQ(motion->SmilFill.value(), fillExp); +} + +TEST_F(ODP2OOX_MotionAnimationTest, motionpath_curve_path) +{ + using namespace cpdoccore::oox; + const size_t animationIndex = 1; + const pptx_animation_context::Impl::_animation_element_array& actions = GetAnimationActionsByIndex(animationIndex); + + const pptx_animation_context::Impl::_animate_motion* motion = dynamic_cast(actions[0].get()); + const std::wstring pathExp = L"M 0.0152857142857143 -0.0443174603174603 " + "C 0.571642857142857 -0.243174603174603 0.416392857142857 0.360253968253969 0.418321428571428 0.358539682539683 " + "C 0.420249999999999 0.356825396825397 0.214857142857142 0.392825396825397 0.116499999999999 0.205968253968254 " + "C 0.0181428571428562 0.0191111111111104 0.286214285714285 -0.0408888888888893 0.286214285714285 -0.0408888888888893 E"; + + std::vector<::svg_path::_polyline> polylines = ParseSvgPath(motion->SvgPath.value()); + std::vector<::svg_path::_polyline> polylinesExp = ParseSvgPath(pathExp); + + CompareSvgPath(polylines, polylinesExp); +} + +TEST_F(ODP2OOX_MotionAnimationTest, motionpath_freeform_path) +{ + using namespace cpdoccore::oox; + const size_t animationIndex = 2; + const pptx_animation_context::Impl::_animation_element_array& actions = GetAnimationActionsByIndex(animationIndex); + + const pptx_animation_context::Impl::_animate_motion* motion = dynamic_cast(actions[0].get()); + const std::wstring pathExp = L"M 0.212928571428571 -0.241460317460317 " + "C 0.278928571428571 -0.249142857142857 0.342073306897614 -0.198873917257616 0.405785714285714 -0.17631746031746 " + "C 0.44232330881459 -0.163381853086875 0.477388383258405 -0.136999684267748 0.510892857142857 -0.107746031746031 " + "C 0.543852671468436 -0.0789679360568993 0.580071048835442 -0.0793628025871184 0.614035714285714 -0.061460317460317 " + "C 0.634999620327278 -0.0504104216013913 0.666289460411191 -0.0693373484432591 0.677678571428571 -0.0357460317460313 " + "C 0.686610889491912 -0.00940083900463148 0.705793372667082 -0.0133203379587745 0.690214285714285 0.0156825396825401 " + "C 0.674757654936194 0.0444574462327262 0.67042353068495 0.0813244939972394 0.654535714285714 0.109968253968254 " + "C 0.640066386196015 0.136054655669317 0.624280246774309 0.157957406936567 0.609214285714285 0.181968253968254 " + "C 0.595994529846027 0.203036776227432 0.577179663378154 0.20064283022504 0.561035714285714 0.20768253968254 " + "C 0.546893947779404 0.21384918000395 0.532679106525073 0.21676565399386 0.518607142857143 0.223111111111112 " + "C 0.500857677670313 0.231114860470829 0.482430590382609 0.234300531367829 0.464607142857142 0.241968253968254 " + "C 0.440073444160649 0.25252275503761 0.414464853047089 0.254479463994283 0.390357142857142 0.26768253968254 " + "C 0.370179138607032 0.27873343233278 0.349960266692982 0.286387897422403 0.329607142857142 0.296825396825397 " + "C 0.301674544144156 0.3111498064218 0.272359084390281 0.315003059917242 0.243785714285714 0.324253968253969 " + "C 0.217644794521686 0.332717346976526 0.191821454417738 0.340186097907613 0.164714285714285 0.33968253968254 " + "C 0.1234643113752 0.338916256634328 0.0825701269502042 0.323878368626136 0.0451428571428562 0.295111111111112 " + "C 0.0258201265945204 0.280259320733704 0.0105099770831932 0.252181552551216 0.000821428571427633 0.217968253968254 " + "C -0.0287757389302364 0.113451387719954 0.108240869954766 0.223417983073443 0.132892857142857 0.156253968253969 " + "C 0.149419443176705 0.111227501996963 0.160327960399085 0.0562104066324277 0.187857142857142 0.0276825396825397 " + "C 0.223006535897276 -0.00874197853720813 0.26042803119238 -0.0400037203455829 0.299714285714285 -0.058031746031746 " + "C 0.317570888513603 -0.066225942649655 0.346455930353361 -0.113453411344393 0.354678571428571 -0.082031746031746 " + "C 0.364848789157456 -0.0431676907104916 0.321427082018808 -0.0417237090720452 0.302607142857142 -0.0323174603174603 " + "C 0.291319937170731 -0.0266760890293527 0.27925 -0.0337142857142857 0.267892857142857 -0.0271746031746032 " + "L 0.256321428571428 -0.0203174603174603 E"; + + std::vector<::svg_path::_polyline> polylines = ParseSvgPath(motion->SvgPath.value()); + std::vector<::svg_path::_polyline> polylinesExp = ParseSvgPath(pathExp); + + CompareSvgPath(polylines, polylinesExp); +} + +TEST_F(ODP2OOX_MotionAnimationTest, motionpath_4_point_star_preset_id) +{ + using namespace cpdoccore::oox; + const size_t animationIndex = 3; + const pptx_animation_context::Impl::_par_animation_ptr& par = GetInnermostPar(GetMainSequenceArray()[animationIndex]); + + const int presetIdExp = 16; + + EXPECT_EQ(par->PresetID.value(), presetIdExp); +} + +TEST_F(ODP2OOX_MotionAnimationTest, motionpath_4_point_star_path) +{ + using namespace cpdoccore::oox; + const size_t animationIndex = 3; + const pptx_animation_context::Impl::_animation_element_array& actions = GetAnimationActionsByIndex(animationIndex); + + const pptx_animation_context::Impl::_animate_motion* motion = dynamic_cast(actions[0].get()); + const std::wstring pathExp = L"M 0 0 L 0.091 -0.0453 L 0.125 -0.16655 L 0.158 -0.0453 L 0.249 0 L 0.158 0.0453 L 0.125 0.16655 L 0.091 0.0453 L 0 0 Z"; + + std::vector<::svg_path::_polyline> polylines = ParseSvgPath(motion->SvgPath.value()); + std::vector<::svg_path::_polyline> polylinesExp = ParseSvgPath(pathExp); + + CompareSvgPath(polylines, polylinesExp); +} + +TEST_F(ODP2OOX_MotionAnimationTest, motionpath_diamond_preset_id) +{ + using namespace cpdoccore::oox; + const size_t animationIndex = 4; + const pptx_animation_context::Impl::_par_animation_ptr& par = GetInnermostPar(GetMainSequenceArray()[animationIndex]); + + const int presetIdExp = 3; + + EXPECT_EQ(par->PresetID.value(), presetIdExp); +} + +TEST_F(ODP2OOX_MotionAnimationTest, motionpath_diamond_path) +{ + using namespace cpdoccore::oox; + const size_t animationIndex = 4; + const pptx_animation_context::Impl::_animation_element_array& actions = GetAnimationActionsByIndex(animationIndex); + + const pptx_animation_context::Impl::_animate_motion* motion = dynamic_cast(actions[0].get()); + const std::wstring pathExp = L"M 0 0 L 0.125 -0.11192 L 0.25 0 L 0.125 0.11192 L 0 0 Z"; + + std::vector<::svg_path::_polyline> polylines = ParseSvgPath(motion->SvgPath.value()); + std::vector<::svg_path::_polyline> polylinesExp = ParseSvgPath(pathExp); + + CompareSvgPath(polylines, polylinesExp); +} + +TEST_F(ODP2OOX_MotionAnimationTest, motionpath_buzz_saw_preset_id) +{ + using namespace cpdoccore::oox; + const size_t animationIndex = 5; + const pptx_animation_context::Impl::_par_animation_ptr& par = GetInnermostPar(GetMainSequenceArray()[animationIndex]); + + const int presetIdExp = 25; + + EXPECT_EQ(par->PresetID.value(), presetIdExp); +} + +TEST_F(ODP2OOX_MotionAnimationTest, motionpath_buzz_saw_path) +{ + using namespace cpdoccore::oox; + const size_t animationIndex = 5; + const pptx_animation_context::Impl::_animation_element_array& actions = GetAnimationActionsByIndex(animationIndex); + + const pptx_animation_context::Impl::_animate_motion* motion = dynamic_cast(actions[0].get()); + const std::wstring pathExp = L"M 0 0 C -0.022 -0.02265 -0.033 -0.06129 -0.027 -0.09993 " + "C -0.024 -0.11325 -0.02 -0.12658 -0.014 -0.13724 " + "C -0.01 -0.10659 0.004 -0.07861 0.025 -0.06129 " + "C 0.025 -0.0986 0.041 -0.13457 0.068 -0.15056 " + "C 0.077 -0.15722 0.087 -0.15989 0.097 -0.16122 " + "C 0.082 -0.13857 0.074 -0.10659 0.077 -0.07328 " + "C 0.099 -0.09727 0.13 -0.1026 0.157 -0.08527 " + "C 0.166 -0.07994 0.175 -0.07062 0.181 -0.06129 " + "C 0.158 -0.06396 0.134 -0.05196 0.117 -0.02798 " + "C 0.144 -0.01999 0.167 0.00799 0.174 0.04663 " + "C 0.176 0.05996 0.176 0.07328 0.174 0.08661 " + "C 0.161 0.06129 0.139 0.04397 0.115 0.0413 " + "C 0.127 0.07461 0.124 0.11592 0.106 0.14656 " + "C 0.099 0.15722 0.091 0.16655 0.082 0.17188 " + "C 0.089 0.14257 0.085 0.10926 0.072 0.08261 " + "C 0.06 0.11592 0.034 0.13857 0.004 0.13857 " + "C -0.007 0.13857 -0.017 0.13591 -0.026 0.13058 " + "C -0.004 0.11992 0.013 0.0946 0.021 0.06396 " + "C -0.007 0.07195 -0.036 0.05996 -0.055 0.02931 " + "C -0.062 0.01732 -0.066 0.00533 -0.069 -0.00799 " + "C -0.049 0.00933 -0.023 0.01199 0 0 Z"; + + std::vector<::svg_path::_polyline> polylines = ParseSvgPath(motion->SvgPath.value()); + std::vector<::svg_path::_polyline> polylinesExp = ParseSvgPath(pathExp); + + CompareSvgPath(polylines, polylinesExp); +} + +TEST_F(ODP2OOX_MotionAnimationTest, motionpath_spring_preset_id) +{ + using namespace cpdoccore::oox; + const size_t animationIndex = 6; + const pptx_animation_context::Impl::_par_animation_ptr& par = GetInnermostPar(GetMainSequenceArray()[animationIndex]); + + const int presetIdExp = 53; + + EXPECT_EQ(par->PresetID.value(), presetIdExp); +} + +TEST_F(ODP2OOX_MotionAnimationTest, motionpath_spring_path) +{ + using namespace cpdoccore::oox; + const size_t animationIndex = 6; + const pptx_animation_context::Impl::_animation_element_array& actions = GetAnimationActionsByIndex(animationIndex); + + const pptx_animation_context::Impl::_animate_motion* motion = dynamic_cast(actions[0].get()); + const std::wstring pathExp = L"M 0 0 C -0.066 0.00799 -0.115 0.02798 -0.115 0.04397 " + "C -0.115 0.05863 -0.067 0.06929 -0.003 0.06929 " + "C 0.061 0.06929 0.115 0.05863 0.115 0.04397 " + "C 0.115 0.02798 0.059 0.02398 -0.005 0.03464 " + "C -0.068 0.04663 -0.115 0.06662 -0.115 0.08128 " + "C -0.115 0.09593 -0.066 0.10793 -0.003 0.10793 " + "C 0.061 0.10793 0.115 0.09593 0.115 0.08128 " + "C 0.115 0.06662 0.059 0.06262 -0.004 0.07328 " + "C -0.068 0.08394 -0.115 0.10393 -0.115 0.11858 " + "C -0.115 0.13457 -0.066 0.14656 -0.002 0.14656 " + "C 0.061 0.14656 0.115 0.13457 0.115 0.11858 " + "C 0.115 0.10526 0.059 0.10126 -0.004 0.11059 " + "C -0.067 0.12125 -0.115 0.14257 -0.115 0.15722 " + "C -0.115 0.17188 -0.065 0.18387 -0.002 0.18387 " + "C 0.063 0.18387 0.115 0.17188 0.115 0.15722 " + "C 0.115 0.14257 0.06 0.13857 -0.003 0.14923 " + "C -0.066 0.15989 -0.115 0.17988 -0.115 0.19453 " + "C -0.115 0.21052 -0.065 0.22118 -0.001 0.22118 " + "C 0.063 0.22118 0.115 0.20919 0.115 0.19453 " + "C 0.115 0.17988 0.06 0.17588 -0.003 0.18654 " + "C -0.066 0.1972 -0.115 0.21851 -0.115 0.23184 " + "C -0.115 0.2465 -0.064 0.25849 -0.001 0.25849 " + "C 0.063 0.25849 0.115 0.2465 0.115 0.23184 " + "C 0.115 0.21851 0.061 0.21452 -0.003 0.22384 " + "C -0.066 0.2345 -0.115 0.25582 -0.115 0.27048 " + "C -0.115 0.2838 -0.064 0.29713 0 0.29713 " + "C 0.064 0.29713 0.115 0.28514 0.115 0.27048 " + "C 0.115 0.25582 0.061 0.25183 -0.002 0.26248 " + "C -0.065 0.27314 -0.116 0.29313 -0.115 0.30779 " + "C -0.114 0.32244 -0.064 0.3331 0 0.3331 " + "C 0.064 0.3331 0.115 0.32111 0.115 0.30645 " + "C 0.115 0.29313 0.063 0.28913 0 0.30112 E"; + + std::vector<::svg_path::_polyline> polylines = ParseSvgPath(motion->SvgPath.value()); + std::vector<::svg_path::_polyline> polylinesExp = ParseSvgPath(pathExp); + + CompareSvgPath(polylines, polylinesExp); +} diff --git a/OdfFile/Test/motion.h b/OdfFile/Test/motion.h new file mode 100644 index 00000000000..8db059aeef6 --- /dev/null +++ b/OdfFile/Test/motion.h @@ -0,0 +1,73 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ + +#pragma once + +#include "common.h" + +#include "gtest/gtest.h" + +class ODP2OOX_AnimationMotionEnvironment : public ODP2OOX_AnimationEnvironment +{ +public: + ODP2OOX_AnimationMotionEnvironment(); + + static const cpdoccore::oox::pptx_animation_context& GetAnimationContext(); + +private: + static boost::shared_ptr sInputOdf; + static boost::shared_ptr sConverionContext; +}; + +class ODP2OOX_MotionAnimationTest : public testing::Test +{ +public: + void SetUp() override; + + void TearDown() override + { } + + const cpdoccore::oox::pptx_animation_context::Impl::_par_animation_ptr& GetInnerPar(const cpdoccore::oox::pptx_animation_context::Impl::_par_animation_ptr& par); + const cpdoccore::oox::pptx_animation_context::Impl::_seq_animation_ptr& GetMainSequence(); + const cpdoccore::oox::pptx_animation_context::Impl::_par_animation_array& GetMainSequenceArray(); + const cpdoccore::oox::pptx_animation_context::Impl::_animation_element_array& GetActionArray(const cpdoccore::oox::pptx_animation_context::Impl::_par_animation_ptr& par); + const cpdoccore::oox::pptx_animation_context::Impl::_par_animation_ptr GetInnermostPar(const cpdoccore::oox::pptx_animation_context::Impl::_par_animation_ptr& par); + const cpdoccore::oox::pptx_animation_context::Impl::_animation_element_array& GetAnimationActionsByIndex(size_t index); + const std::vector ParseSvgPath(const std::wstring& path); + + void CompareSvgPath(const std::vector& left, const std::vector& right); + +public: + const cpdoccore::oox::pptx_animation_context* mAnimationContext; + const double mEpsilon = 0.00001; +}; + diff --git a/OdfFile/Test/test.cpp b/OdfFile/Test/test.cpp new file mode 100644 index 00000000000..46edbf35614 --- /dev/null +++ b/OdfFile/Test/test.cpp @@ -0,0 +1,59 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ + +#include "gtest/gtest.h" + +#include "entrance.h" +#include "motion.h" +#include "audio.h" +#include "interactions.h" + +int main(int argc, char* argv[]) +{ + ::testing::InitGoogleTest(&argc, argv); + + ::testing::AddGlobalTestEnvironment(new ODP2OOX_AnimationEntranceEnvironment); + ::testing::AddGlobalTestEnvironment(new ODP2OOX_AnimationMotionEnvironment); + ::testing::AddGlobalTestEnvironment(new ODP2OOX_AnimationAudioEnvironment); + ::testing::AddGlobalTestEnvironment(new ODP2OOX_AnimationPlayAudioEnvironment); + ::testing::AddGlobalTestEnvironment(new ODP2OOX_AnimationOpenDocumentEnvironment); + ::testing::AddGlobalTestEnvironment(new ODP2OOX_AnimationRunProgramEnvironment); + + ::testing::AddGlobalTestEnvironment(new OOX2ODP_EntranceAnimationEnvironment); + ::testing::AddGlobalTestEnvironment(new OOX2ODP_AudioAnimationEnvironment); + ::testing::AddGlobalTestEnvironment(new OOX2ODP_InteractionAnimationEnvironment); + ::testing::AddGlobalTestEnvironment(new OOX2ODP_PlayAudioAnimationEnvironment); + ::testing::AddGlobalTestEnvironment(new OOX2ODP_OpenDocumentAnimationEnvironment); + ::testing::AddGlobalTestEnvironment(new OOX2ODP_RunProgramAnimationEnvironment); + + return RUN_ALL_TESTS(); +} \ No newline at end of file diff --git a/OdfFile/Test/test_odf.pro b/OdfFile/Test/test_odf.pro new file mode 100644 index 00000000000..ddf5aaee5ea --- /dev/null +++ b/OdfFile/Test/test_odf.pro @@ -0,0 +1,69 @@ +QT -= core +QT -= gui + +TARGET = test +CONFIG += console +CONFIG -= app_bundle + +TEMPLATE = app + +CONFIG += core_static_link_libstd + +CORE_ROOT_DIR = $$PWD/../../../core +CORE_3DPARTY_DIR = $$CORE_ROOT_DIR/Common/3dParty +PWD_ROOT_DIR = $$PWD + +include($$CORE_ROOT_DIR/Common/base.pri) +include($$CORE_3DPARTY_DIR/googletest/googletest.pri) +include($$CORE_3DPARTY_DIR/boost/boost.pri) +include($$CORE_ROOT_DIR/Common/3dParty/icu/icu.pri) + +DESTDIR = $$PWD/build + +INCLUDEPATH += ../ +INCLUDEPATH += $$CORE_ROOT_DIR/OdfFile/Common/ + +LIBS += -L$$CORE_BUILDS_LIBRARIES_PATH -lCryptoPPLib +LIBS += -L$$CORE_BOOST_LIBS + +ADD_DEPENDENCY(kernel) +ADD_DEPENDENCY(kernel_network) +ADD_DEPENDENCY(graphics) + +ADD_DEPENDENCY(DocxFormatLib) +ADD_DEPENDENCY(OdfFormatLib) +ADD_DEPENDENCY(PPTXFormatLib) +ADD_DEPENDENCY(BinDocument) +ADD_DEPENDENCY(DocxFormatLib) +ADD_DEPENDENCY(XlsbFormatLib) +ADD_DEPENDENCY(RtfFormatLib) +ADD_DEPENDENCY(CompoundFileLib) + +ADD_DEPENDENCY(DocFormatLib XlsFormatLib PPTFormatLib VbaFormatLib) +ADD_DEPENDENCY(HtmlFile2) +ADD_DEPENDENCY(UnicodeConverter) + + + +core_linux { + LIBS += -Wl,-unresolved-symbols=ignore-in-shared-libs + LIBS += -ldl +} + +HEADERS += \ + common.h\ + entrance.h\ + motion.h\ + audio.h\ + interactions.h + +SOURCES += \ + test.cpp\ + common.cpp\ + entrance.cpp\ + motion.cpp\ + audio.cpp\ + interactions.cpp\ + $$CORE_ROOT_DIR/Common/OfficeFileFormatChecker2.cpp + +SOURCES -= $$CORE_GTEST_PATH/src/gtest_main.cc diff --git a/OdfFile/Writer/Converter/ConvertDrawing.cpp b/OdfFile/Writer/Converter/ConvertDrawing.cpp index ec9f6ac0de7..ec4d5ddf7fc 100644 --- a/OdfFile/Writer/Converter/ConvertDrawing.cpp +++ b/OdfFile/Writer/Converter/ConvertDrawing.cpp @@ -63,10 +63,12 @@ #include "../../../OOXML/Common/SimpleTypes_Word.h" #include "../Format/odf_conversion_context.h" +#include "../Format/odp_conversion_context.h" #include "../Format/odf_text_context.h" #include "../Format/odf_drawing_context.h" #include "../Format/style_text_properties.h" #include "../Format/style_paragraph_properties.h" +#include "../Format/style_graphic_properties.h" #include "../Format/styles_list.h" #define GETBITS(from, numL, numH) ((from & (((1 << (numH - numL + 1)) - 1) << numL)) >> numL) @@ -153,6 +155,7 @@ void OoxConverter::convert(PPTX::Logic::NvGraphicFramePr *oox_framePr) { if (oox_framePr == NULL) return; + convert(&oox_framePr->cNvPr); } void OoxConverter::RGB2HSL(DWORD argb, double& dH, double& dS, double& dL) { @@ -236,8 +239,8 @@ void OoxConverter::convert(PPTX::Logic::Xfrm *oox_xfrm) if (oox_xfrm->flipH.get_value_or(false)) odf_context()->drawing_context()->set_flip_H(true); if (oox_xfrm->flipV.get_value_or(false)) odf_context()->drawing_context()->set_flip_V(true); - if (oox_xfrm->rot.get_value_or(0) > 0) - odf_context()->drawing_context()->set_rotate(360. - oox_xfrm->rot.get_value_or(0)/60000.); + if (oox_xfrm->rot.IsInit()) + odf_context()->drawing_context()->set_rotate(oox_xfrm->rot.get_value_or(0)/60000.); } void OoxConverter::convert(PPTX::Logic::Xfrm *oox_txbx, PPTX::Logic::Xfrm *oox_xfrm) { @@ -395,7 +398,7 @@ void OoxConverter::convert(PPTX::Logic::Pic *oox_picture) { pathOle = find_link_by_id(oox_picture->oleObject->m_oId->get(), 4, bExternal); } - std::wstring odf_ref_ole = odf_context()->add_oleobject(pathOle); + std::wstring odf_ref_ole = odf_context()->add_oleobject(pathOle, bExternal); if (!odf_ref_ole.empty()) { @@ -416,7 +419,7 @@ void OoxConverter::convert(PPTX::Logic::Pic *oox_picture) if (pVml) { std::wstring sShapeId = oox_picture->oleObject->m_sShapeId.get(); - boost::unordered_map::iterator pFind = pVml->m_mapShapes.find(sShapeId); + std::map::iterator pFind = pVml->m_mapShapes.find(sShapeId); if (pVml->m_mapShapes.end() != pFind) { @@ -431,8 +434,7 @@ void OoxConverter::convert(PPTX::Logic::Pic *oox_picture) if (pFile.IsInit() && (OOX::FileTypes::Image == pFile->type())) { - OOX::Image* pImageFileCache = static_cast(pFile.GetPointer()); - + smart_ptr pImageFileCache = pFile.smart_dynamic_cast(); pathImage = pImageFileCache->filename().GetPath(); } } @@ -441,7 +443,7 @@ void OoxConverter::convert(PPTX::Logic::Pic *oox_picture) } - odf_ref_image = bExternal ? pathImage : odf_context()->add_imageobject(pathImage); + odf_ref_image = odf_context()->add_imageobject(pathImage, bExternal); odf_context()->drawing_context()->set_image_replacement(odf_ref_image); odf_context()->drawing_context()->end_object_ole(); @@ -450,6 +452,11 @@ void OoxConverter::convert(PPTX::Logic::Pic *oox_picture) } //-------------------------------------------------------------------------------------- odf_ref_image = bExternal ? pathImage : odf_context()->add_image(pathImage); + + if (bExternal && std::wstring::npos == odf_ref_image.find(L"\\") && std::wstring::npos == odf_ref_image.find(L"/")) + { + odf_ref_image = L"../" + odf_ref_image; + } odf_context()->drawing_context()->start_image(odf_ref_image); { @@ -530,6 +537,7 @@ void OoxConverter::convert(PPTX::Logic::SmartArt *oox_smart_art) odf_context()->drawing_context()->set_group_size (width, height, width, height); odf_context()->drawing_context()->set_group_position (x, y, cx, cy); +#if 0 odf_context()->drawing_context()->start_drawing(); odf_context()->drawing_context()->start_shape(SimpleTypes::shapetypeRect); @@ -552,6 +560,7 @@ void OoxConverter::convert(PPTX::Logic::SmartArt *oox_smart_art) } odf_context()->drawing_context()->end_shape(); odf_context()->drawing_context()->end_drawing(); +#endif oox_current_child_document = oox_smart_art->m_pDrawingContainer.GetPointer(); @@ -690,6 +699,17 @@ void OoxConverter::convert(PPTX::Logic::NvGrpSpPr *oox_nvGrpSpPr) if (oox_nvGrpSpPr->cNvPr.descr.IsInit()) odf_context()->drawing_context()->set_description(oox_nvGrpSpPr->cNvPr.descr.get()); + if (oox_nvGrpSpPr->cNvPr.id != -1) + { + cpdoccore::odf_writer::odp_conversion_context* odp_context = + dynamic_cast(odf_context()); + if (odp_context) + { + const std::wstring xml_id = odp_context->map_indentifier(std::to_wstring(oox_nvGrpSpPr->cNvPr.id)); + odf_context()->drawing_context()->set_group_xml_id(xml_id); + } + } + convert(&oox_nvGrpSpPr->cNvGrpSpPr); convert(&oox_nvGrpSpPr->nvPr); } @@ -829,6 +849,9 @@ void OoxConverter::convert(PPTX::Logic::Shape *oox_shape) if (type == SimpleTypes::shapetypeRect && (oox_shape->txBody.IsInit() || oox_shape->oTextBoxShape.IsInit())) type = 2000; + if (type == 63) // ellipse + type = 1000; // custom + if (type == 2000) { PPTX::Logic::BodyPr *bodyPr = NULL; @@ -850,6 +873,34 @@ void OoxConverter::convert(PPTX::Logic::Shape *oox_shape) if (type < 0)return; //----------------------------------------------------------------------------- odf_context()->drawing_context()->start_shape(type); + + if (oox_shape->nvSpPr.nvPr.ph.is_init()) + { + _CP_PTR(cpdoccore::odf_writer::paragraph_format_properties) paragraph_properties = boost::make_shared(); + _CP_PTR(cpdoccore::odf_writer::text_format_properties) text_properties = boost::make_shared(); + _CP_PTR(cpdoccore::odf_writer::graphic_format_properties) graphic_properties = boost::make_shared(); + + if(oox_shape->txBody.is_init()) + convert(oox_shape->txBody->lstStyle.GetPointer(), 0, paragraph_properties.get(), text_properties.get()); + + if (odf_context()->drawing_context()->placeholder_replacing()) + { + graphic_properties->draw_textarea_horizontal_align_ = odf_types::text_align(odf_types::text_align::Left); + graphic_properties->draw_textarea_vertical_align_ = odf_types::vertical_align(odf_types::vertical_align::Top); + } + + odf_context()->drawing_context()->set_text_properties(text_properties.get()); + odf_context()->drawing_context()->set_paragraph_properties(paragraph_properties.get()); + odf_context()->drawing_context()->set_graphic_properties(graphic_properties.get()); + + if (oox_shape->txBody.IsInit()) + { + odf_context()->start_text_context(); + convert(oox_shape->txBody->bodyPr.GetPointer()); + odf_context()->drawing_context()->set_text(odf_context()->text_context()); + odf_context()->end_text_context(); + } + } convert(&oox_shape->spPr, oox_shape->style.GetPointer()); @@ -1027,19 +1078,69 @@ void OoxConverter::convert(PPTX::Logic::PrstGeom *oox_geom) { if (!oox_geom) return; + if (oox_geom->prst.get() == L"ellipse") + { + odf_context()->drawing_context()->set_viewBox(21600, 21600); + odf_context()->drawing_context()->set_path(L"U 10800 10800 10800 10800 0 360 Z N"); + odf_context()->drawing_context()->set_draw_type(L"circle"); + return; + } + for (size_t i = 0; i < oox_geom->avLst.size(); i++) { odf_context()->drawing_context()->add_modifier(oox_geom->avLst[i].fmla.get_value_or(L"0")); } } + +static std::wstring process_gd_formula(const PPTX::Logic::Gd& gd, odf_writer::odf_drawing_context* drawing_context, size_t& last_gd_index) +{ + std::vector args; + boost::algorithm::split(args, gd.fmla.get_value_or(L""), boost::is_any_of("\t "), boost::token_compress_on); + + std::wstring fmla = gd.fmla.get_value_or(L""); + + if (args.size() >= 4 && gd.GetFormulaType(args.front()) == 0) // if formula is "('*/') - Multiply Divide Formula" + { + if (boost::algorithm::starts_with(args[3], L"gd")) + { + const std::wstring abs_name = std::wstring(L"gd") + std::to_wstring(last_gd_index + 1); + const std::wstring abs_fmla = L"abs " + args[3]; + + const std::wstring cmp_name = std::wstring(L"gd") + std::to_wstring(last_gd_index + 2); + const std::wstring cmp_fmla = L"?: " + abs_name + L" " + args[3] + L" 1"; + + last_gd_index += 2; + + drawing_context->add_formula(abs_name, abs_fmla); + drawing_context->add_formula(cmp_name, cmp_fmla); + + args[3] = cmp_name; + + fmla = boost::algorithm::join(args, L" "); + } + } + + return fmla; +} + void OoxConverter::convert(PPTX::Logic::CustGeom *oox_cust_geom) { if (!oox_cust_geom) return; - for (size_t i = 0; i < oox_cust_geom->gdLst.size(); i++) + if (oox_cust_geom->gdLst.size()) { - odf_context()->drawing_context()->add_formula(oox_cust_geom->gdLst[i].name.get_value_or(L""), oox_cust_geom->gdLst[i].fmla.get_value_or(L"")); + size_t last_gd_index = oox_cust_geom->gdLst.size() - 1; + + for (size_t i = 0; i < oox_cust_geom->gdLst.size(); i++) + { + const PPTX::Logic::Gd& gd = oox_cust_geom->gdLst[i]; + + const std::wstring fmla = process_gd_formula(gd, odf_context()->drawing_context(), last_gd_index); + + odf_context()->drawing_context()->add_formula(gd.name.get_value_or(L""), fmla); + } } + for (size_t i = 0; i < oox_cust_geom->pathLst.size(); i++) { convert(&oox_cust_geom->pathLst[i]); @@ -1226,35 +1327,17 @@ void OoxConverter::convert(PPTX::Logic::Path2D *oox_geom_path) odf_context()->drawing_context()->set_viewBox(oox_geom_path->w.get_value_or(0), oox_geom_path->h.get_value_or(0)); - if (oox_geom_path->fill.IsInit()) - { - odf_context()->drawing_context()->start_area_properties(); - switch(oox_geom_path->fill->GetBYTECode()) - { - case 0://darken - case 1://darkenLess - case 2://lighten - case 3://lightenLess - break; - case 4: - odf_context()->drawing_context()->set_no_fill(); - break; - case 5: - default: - break; - } - odf_context()->drawing_context()->end_area_properties(); - } for (size_t i = 0 ; i < oox_geom_path->Paths.size(); i++) { if (oox_geom_path->Paths[i].Path2D.is()) - { convert(&oox_geom_path->Paths[i].Path2D.as()); - } } if (oox_geom_path->stroke.IsInit() && *oox_geom_path->stroke == false) odf_context()->drawing_context()->add_path_element(std::wstring(L"S"), L""); + + if(oox_geom_path->fill.IsInit() && oox_geom_path->fill->GetBYTECode() == 4) // fill == "none" + odf_context()->drawing_context()->add_path_element(std::wstring(L"F"), L""); odf_context()->drawing_context()->add_path_element(std::wstring(L"N"), L""); } @@ -1276,8 +1359,6 @@ void OoxConverter::convert(PPTX::Logic::PathBase *oox_path) if (quadBezTo) convert(quadBezTo); if (arcTo) convert(arcTo); if (close) convert(close); - - } void OoxConverter::convert(PPTX::Logic::BlipFill *oox_bitmap_fill) @@ -1650,8 +1731,11 @@ void OoxConverter::convert(PPTX::Logic::BodyPr *oox_bodyPr) if ((oox_bodyPr->numCol.IsInit()) && (oox_bodyPr->numCol.get() > 1)) { - //+ style section - //+element text:section в котором параграфы + int cols = oox_bodyPr->numCol.get(); + int gap_cms = oox_bodyPr->spcCol.IsInit() ? oox_bodyPr->spcCol.get() / 360000 : 0; + + odf_context()->drawing_context()->start_style_columns(cols, gap_cms); + odf_context()->drawing_context()->end_style_columns(); } if (oox_bodyPr->rot.IsInit()) { @@ -1683,12 +1767,50 @@ void OoxConverter::convert(PPTX::Logic::NvSpPr *oox_nvSpPr) convert (&oox_nvSpPr->cNvSpPr); convert (&oox_nvSpPr->nvPr); } + +static bool is_sound_hlink(const std::wstring& hlink) +{ + const std::wstring ext = NSFile::GetFileExtention(hlink); + if (ext == L"wav" || + ext == L"wma" || + ext == L"mp3" || + ext == L"ogg") + return true; + + return false; +} + +static bool is_relative_path(const std::wstring& path) +{ + if (path.size() <= 0) + return false; + + if (path.find(L"://") != std::wstring::npos) + return false; + + if (path[0] == '/') + return false; + + return true; +} + void OoxConverter::convert(PPTX::Logic::CNvPr *oox_cnvPr) { if (!oox_cnvPr) return; odf_context()->drawing_context()->set_name(oox_cnvPr->name); + if (oox_cnvPr->id != -1) + { + cpdoccore::odf_writer::odp_conversion_context* odp_context = + dynamic_cast(odf_context()); + if (odp_context) + { + const std::wstring xml_id = odp_context->map_indentifier(std::to_wstring(oox_cnvPr->id)); + odf_context()->drawing_context()->set_xml_id(xml_id); + } + } + if (oox_cnvPr->descr.IsInit()) { odf_context()->drawing_context()->set_description(oox_cnvPr->descr.get()); @@ -1699,35 +1821,7 @@ void OoxConverter::convert(PPTX::Logic::CNvPr *oox_cnvPr) } if (oox_cnvPr->hlinkClick.IsInit()) { - bool bExternal = false; - if (odf_context()->drawing_context()->is_current_empty()) - { - if (oox_cnvPr->hlinkClick->id.IsInit()) - { - std::wstring hlink = find_link_by_id(oox_cnvPr->hlinkClick->id.get(), 2, bExternal); - - odf_context()->drawing_context()->start_link_object(hlink); - } - } - else - { - odf_context()->drawing_context()->start_action(oox_cnvPr->hlinkClick->action.get_value_or(L"")); - - if (oox_cnvPr->hlinkClick->snd.IsInit()) - { - std::wstring sound = find_link_by_id(oox_cnvPr->hlinkClick->snd->embed.get(), 3, bExternal); - - std::wstring href = odf_context()->add_media(sound, bExternal); - odf_context()->drawing_context()->add_sound(href); - } - if (oox_cnvPr->hlinkClick->id.IsInit()) - { - std::wstring hlink = find_link_by_id(oox_cnvPr->hlinkClick->id.get(), 2, bExternal); - - odf_context()->drawing_context()->add_link(hlink); - } - odf_context()->drawing_context()->end_action(); - } + convert(oox_cnvPr->hlinkClick.GetPointer()); } //nullable_string title; //nullable hlinkHover; @@ -1957,6 +2051,26 @@ void OoxConverter::convert_list_level(PPTX::Logic::TextParagraphPr *oox_para_pro odf_context()->styles_context()->lists_styles().end_style_level(); } +static bool is_empty_run_elems(const std::vector& runElems) +{ + using namespace PPTX::Logic; + + auto runIt = std::find_if_not(runElems.begin(), runElems.end(), + [](const RunElem& r) { + return !r.is(); + }); + if (runIt != runElems.end()) + { + const Run& run = runIt->as(); + if (!run.HasText()) + return true; + } + else + return true; + + return false; +} + void OoxConverter::convert(PPTX::Logic::Paragraph *oox_paragraph, PPTX::Logic::TextListStyle *oox_list_style) { if (!oox_paragraph)return; @@ -2000,6 +2114,8 @@ void OoxConverter::convert(PPTX::Logic::Paragraph *oox_paragraph, PPTX::Logic::T if (paraPr->ParagraphBullet.is()) list_present = false; } + else + list_present = false; //свойства могут быть приписаны не только к параграфу, но и к самому объекту odf_writer::paragraph_format_properties* paragraph_properties = odf_context()->text_context()->get_paragraph_properties(); odf_writer::text_format_properties* text_properties = odf_context()->text_context()->get_text_properties(); @@ -2017,8 +2133,17 @@ void OoxConverter::convert(PPTX::Logic::Paragraph *oox_paragraph, PPTX::Logic::T if (odf_context()->drawing_context()->is_wordart()) odf_context()->drawing_context()->set_paragraph_properties(paragraph_properties); + + if (styled && odf_context()->drawing_context()->is_placeholder()) + { + odf_writer::odf_style_state_ptr state = odf_context()->text_context()->get_styles_context()->last_state(odf_types::style_family::Paragraph); + odf_context()->drawing_context()->set_placeholder_style(state->get_name()); + } } + if (is_empty_run_elems(oox_paragraph->RunElems)) + list_present = false; + //if (oox_paragraph->RunElems.empty() && list_present) list_present = false; // ms не обозначает присутствие списка, libra - показывает значек while ((int)odf_context()->text_context()->list_state_.levels.size() > list_level) @@ -2070,10 +2195,21 @@ void OoxConverter::convert(PPTX::Logic::Paragraph *oox_paragraph, PPTX::Logic::T } odf_context()->text_context()->start_paragraph(styled); - for (size_t i=0; i< oox_paragraph->RunElems.size(); i++) + if (oox_paragraph->RunElems.size() > 0) + { + for (size_t i = 0; i < oox_paragraph->RunElems.size(); i++) + { + convert(&oox_paragraph->RunElems[i].as()); + } + } + else { - convert(&oox_paragraph->RunElems[i].as()); + bool styled = oox_paragraph->endParaRPr.IsInit() && oox_paragraph->endParaRPr->sz.IsInit(); + + odf_context()->text_context()->start_span(styled); + odf_context()->text_context()->end_span(); } + odf_context()->text_context()->end_paragraph(); //if(list_present) @@ -2435,7 +2571,33 @@ void OoxConverter::convert(PPTX::Logic::RunProperties *oox_run_pr, odf_writer::t { text_properties->fo_text_transform_ = odf_types::text_transform(odf_types::text_transform::Capitalize); } +} +static std::vector split_tabs(const std::wstring& text) +{ + std::vector result; + std::wstringstream ss; + const wchar_t tabChar = L'\t'; + + for (const auto& c : text) + { + if (c == tabChar) + { + if (!ss.str().empty()) + { + result.push_back(ss.str()); + ss.str(std::wstring()); + } + + result.push_back(L"\t"); + } + else + ss << c; + } + if(!ss.str().empty()) + result.push_back(ss.str()); + + return result; } void OoxConverter::convert(PPTX::Logic::Run *oox_run) { @@ -2483,11 +2645,43 @@ void OoxConverter::convert(PPTX::Logic::Run *oox_run) bool bExternal = false; std::wstring hlink = find_link_by_id(oox_run->rPr->hlinkClick->id.get(), 2, bExternal); std::wstring location; + + smart_ptr file = find_file_by_id(oox_run->rPr->hlinkClick->id.get()); + OOX::HyperLink* hyperlink = dynamic_cast(file.GetPointer()); + + if (hyperlink) + location = hyperlink->Uri().GetBasename(); + + if (oox_run->rPr->hlinkClick->action.IsInit() && location.empty()) + { + const std::wstring& action = *oox_run->rPr->hlinkClick->action; + + if (std::wstring::npos != action.find(L"previousslide")) + location = L"previous-page"; + else if (std::wstring::npos != action.find(L"nextslide")) + location = L"next-page"; + else if (std::wstring::npos != action.find(L"firstslide")) + location = L"first-page"; + else if (std::wstring::npos != action.find(L"lastslide")) + location = L"last-page"; + else if (std::wstring::npos != action.find(L"endshow")) + location = L"end"; + } + text_context->add_hyperlink(hlink, oox_run->GetText(), location); } else { - text_context->add_text_content( oox_run->GetText()); + const std::wstring& text = oox_run->GetText(); + std::vector tabSplit = split_tabs(text); + + for (const std::wstring& str : tabSplit) + { + if (str == L"\t") + text_context->add_tab(); + else + text_context->add_text_content(str); + } } text_context->end_span(); } @@ -2584,6 +2778,64 @@ void OoxConverter::convert(PPTX::Logic::TextListStyle *oox_list_style) } odf_context()->styles_context()->lists_styles().end_style(); } +void OoxConverter::convert(PPTX::Logic::Hyperlink* oox_hyperlink) +{ + if (!oox_hyperlink) + return; + + bool bExternal = false; + if (odf_context()->drawing_context()->is_current_empty()) + { + if (oox_hyperlink->id.IsInit()) + { + std::wstring hlink = find_link_by_id(oox_hyperlink->id.get(), 2, bExternal); + + odf_context()->drawing_context()->start_link_object(hlink); + } + } + else + { + odf_context()->drawing_context()->start_action(oox_hyperlink->action.get_value_or(L"")); + + if (oox_hyperlink->snd.IsInit()) + { + std::wstring sound = find_link_by_id(oox_hyperlink->snd->embed.get(), 3, bExternal); + + std::wstring href = odf_context()->add_media(sound, bExternal); + odf_context()->drawing_context()->add_sound(href); + } + if (oox_hyperlink->id.IsInit()) + { + std::wstring hlink = find_link_by_id(oox_hyperlink->id.get(), 2, bExternal); + boost::replace_all(hlink, L"\\", L"/"); // NOTE(Kamil Kerimov): Always use forward slash in odf for filepaths + + if (is_sound_hlink(hlink)) + { + std::wstring href = odf_context()->add_media(hlink, bExternal); + odf_context()->drawing_context()->add_sound(href); + } + else + { + if (is_relative_path(hlink)) + hlink = L"../" + hlink; + odf_context()->drawing_context()->add_link(hlink); + } + + + smart_ptr file = find_file_by_id(oox_hyperlink->id.get()); + OOX::HyperLink* hyperlink = dynamic_cast(file.GetPointer()); + + if (hyperlink) + { + odf_context()->add_hyperlink( + odf_context()->drawing_context()->get_current_element(), + hyperlink->Uri().GetBasename() + ); + } + } + odf_context()->drawing_context()->end_action(); + } +} void OoxConverter::convert(PPTX::Logic::TxBody *oox_txBody, PPTX::Logic::ShapeStyle* oox_style) { if (!oox_txBody) return; @@ -2627,14 +2879,32 @@ void OoxConverter::convert(PPTX::Logic::TxBody *oox_txBody, PPTX::Logic::ShapeSt odf_context()->end_text_context(); } + +static std::wstring convert_arc_angle(const std::wstring& angle, odf_writer::odf_drawing_context* dc) +{ + std::wstring result = L"0"; + + int angleInt = XmlUtils::GetInteger(angle); + + if (angleInt == 0 && angle != L"0") + { + result = std::wstring(L"gd") + std::to_wstring(dc->get_formulas_count()); + dc->add_formula(result, L"*/ 1 " + angle + L" 60000"); + } + else + result = std::to_wstring(angleInt / 60000); + + return result; +} + void OoxConverter::convert(PPTX::Logic::ArcTo *oox_geom_path) { if (!oox_geom_path) return; - int stAng = XmlUtils::GetInteger(oox_geom_path->stAng); - int swAng = XmlUtils::GetInteger(oox_geom_path->swAng); + const std::wstring stAng = convert_arc_angle(oox_geom_path->stAng, odf_context()->drawing_context()); + const std::wstring swAng = convert_arc_angle(oox_geom_path->swAng, odf_context()->drawing_context()); - std::wstring path_elm = oox_geom_path->wR + L" " + oox_geom_path->hR + L" " + std::to_wstring(stAng/60000) + L" " + std::to_wstring(swAng /60000); + std::wstring path_elm = oox_geom_path->wR + L" " + oox_geom_path->hR + L" " + stAng + L" " + swAng; odf_context()->drawing_context()->add_path_element(std::wstring(L"G"), path_elm); } diff --git a/OdfFile/Writer/Converter/ConvertVml.cpp b/OdfFile/Writer/Converter/ConvertVml.cpp index de66957c098..3fd42d093f7 100644 --- a/OdfFile/Writer/Converter/ConvertVml.cpp +++ b/OdfFile/Writer/Converter/ConvertVml.cpp @@ -332,7 +332,7 @@ namespace Oox2Odf { pathOle = find_link_by_id(vml_object->m_oId->GetValue(), 4, bExternal); } - std::wstring odf_ref_ole = odf_context()->add_oleobject(pathOle); + std::wstring odf_ref_ole = odf_context()->add_oleobject(pathOle, bExternal); if (!odf_ref_ole.empty()) { @@ -345,7 +345,7 @@ namespace Oox2Odf std::wstring sIdImageFileCache = GetImageIdFromVmlShape(vml_shape); std::wstring pathImage = find_link_by_id(sIdImageFileCache, 1, bExternal); - std::wstring odf_ref_image = odf_context()->add_imageobject(pathImage); + std::wstring odf_ref_image = odf_context()->add_imageobject(pathImage, bExternal); odf_context()->drawing_context()->set_image_replacement(odf_ref_image); diff --git a/OdfFile/Writer/Converter/Converter.cpp b/OdfFile/Writer/Converter/Converter.cpp index 0c78a1219e2..1fbd0119f24 100644 --- a/OdfFile/Writer/Converter/Converter.cpp +++ b/OdfFile/Writer/Converter/Converter.cpp @@ -70,6 +70,7 @@ #include "../../../OOXML/PPTXFormat/Logic/Effects/AlphaModFix.h" #include "../../../OOXML/PPTXFormat/Logic/Effects/Grayscl.h" #include "../../../OOXML/PPTXFormat/Logic/Effects/Duotone.h" +#include "../../../OOXML/PPTXFormat/Logic/HeadingVariant.h" #include "../../../OOXML/XlsxFormat/Worksheets/Sparkline.h" #include "../../../OfficeCryptReader/source/CryptTransform.h" @@ -360,6 +361,66 @@ void OoxConverter::convert_meta(OOX::CApp *app, OOX::CCore *core) odf_context()->add_meta(L"dc", L"language", *core->m_sLanguage); } } +void OoxConverter::convert_customs(OOX::IFileContainer* container) +{ + if (!container) return; + smart_ptr customProperties = container->Find(OOX::FileTypes::CustomProperties).smart_dynamic_cast(); + + if (false == customProperties.IsInit()) return; + + for (auto prop : customProperties->m_arProperties) + { + if (prop.m_strName.IsInit()) + { + std::wstring content; + if (prop.m_oContent.IsInit()) + { + switch (prop.m_oContent->getVariantType()) + { + case PPTX::Logic::vtLpstr: + case PPTX::Logic::vtLpwstr: + case PPTX::Logic::vtBstr: + { + if (prop.m_oContent->m_strContent.IsInit()) + content = *prop.m_oContent->m_strContent; + }break; + case PPTX::Logic::vtI1: + case PPTX::Logic::vtI2: + case PPTX::Logic::vtI4: + case PPTX::Logic::vtI8: + case PPTX::Logic::vtDecimal: + case PPTX::Logic::vtInt: + { + if (prop.m_oContent->m_iContent.IsInit()) + content = std::to_wstring(*prop.m_oContent->m_iContent); + }break; + case PPTX::Logic::vtUi1: + case PPTX::Logic::vtUi2: + case PPTX::Logic::vtUi4: + case PPTX::Logic::vtUi8: + { + if (prop.m_oContent->m_uContent.IsInit()) + content = std::to_wstring(*prop.m_oContent->m_uContent); + }break; + case PPTX::Logic::vtR4: + { + if (prop.m_oContent->m_dContent.IsInit()) + content = std::to_wstring(*prop.m_oContent->m_dContent); + }break; + case PPTX::Logic::vtBool: + { + if (prop.m_oContent->m_bContent.IsInit()) + content = std::to_wstring(*prop.m_oContent->m_bContent); + }break; + } + } + odf_context()->add_meta_user_define(*prop.m_strName, content); + + } + //nullable_string m_strFmtid; + //nullable_string m_strLinkTarget; + } +} void OoxConverter::convert(OOX::WritingElement *oox_unknown) { try diff --git a/OdfFile/Writer/Converter/Converter.h b/OdfFile/Writer/Converter/Converter.h index a7405866ad1..36c081a94d9 100644 --- a/OdfFile/Writer/Converter/Converter.h +++ b/OdfFile/Writer/Converter/Converter.h @@ -31,7 +31,8 @@ */ #pragma once -#include +#include "../../Common/CPOptional.h" + #include "../../../OOXML/Base/SmartPtr.h" #include "../../../OOXML/DocxFormat/Math/oMathContent.h" #include "../../../OOXML/DocxFormat/Logic/VmlWord.h" @@ -498,6 +499,7 @@ namespace Oox2Odf OOX::IFileContainer *oox_current_child_document; + void convert_customs(OOX::IFileContainer* container); void convert_meta(OOX::CApp *app, OOX::CCore *core); void convert (OOX::JsaProject *jsaProject); void convert (double oox_font_size, _CP_OPT(cpdoccore::odf_types::font_size) & odf_font_size); @@ -542,6 +544,7 @@ namespace Oox2Odf void convert(PPTX::Logic::NvPr *oox_nvPr); void convert(PPTX::Logic::Paragraph *oox_para, PPTX::Logic::TextListStyle *oox_list_style = NULL); void convert(PPTX::Logic::TextListStyle *oox_list_style); + void convert(PPTX::Logic::Hyperlink *oox_hyperlink); void convert_list_level (PPTX::Logic::TextParagraphPr *oox_para_props, int level); @@ -678,8 +681,7 @@ namespace Oox2Odf std::vector>& brackets(); int& lvl_of_me(); std::vector& end_counter(); - std::wstring& annotation(); - bool& annotation_flag(); + void lvl_up_counter_increace(double val); void lvl_up_counter_decreace(double val); void lvl_down_counter_increace(double val); diff --git a/OdfFile/Writer/Converter/ConverterChart.cpp b/OdfFile/Writer/Converter/ConverterChart.cpp index aa4ed633dff..a5a28efdb5d 100644 --- a/OdfFile/Writer/Converter/ConverterChart.cpp +++ b/OdfFile/Writer/Converter/ConverterChart.cpp @@ -129,11 +129,10 @@ void OoxConverter::convert(OOX::Spreadsheet::CT_ChartSpace *oox_chart) bool chart3D = (oox_chart->m_chart->m_view3D) ? true : false; convert(oox_chart->m_chart->m_floor, 1, chart3D); - if (chart3D) - { - convert(oox_chart->m_chart->m_backWall, 2, chart3D); - convert(oox_chart->m_chart->m_view3D); - } + convert(oox_chart->m_chart->m_backWall, 2, chart3D); + + convert(oox_chart->m_chart->m_view3D); + //convert(oox_chart->m_chart->m_sizeWall, 3, chart3D); } odf_context()->chart_context()->end_plot_area(); @@ -261,63 +260,55 @@ void OoxConverter::convert(OOX::Spreadsheet::CT_PlotArea* ct_plotArea) bool chart3D = false; convert(ct_plotArea->m_layout); -/////////////////////// + /////////////////////// - for (size_t i=0; i< ct_plotArea->m_Items.size(); i++)// + for (size_t i = 0; i < ct_plotArea->m_Items.size(); i++)// { if (!ct_plotArea->m_ItemsElementName0[i]) continue; - switch(*ct_plotArea->m_ItemsElementName0[i]) + switch (*ct_plotArea->m_ItemsElementName0[i]) { - case OOX::Spreadsheet::itemschoicetype5BAR3DCHART: convert_before((OOX::Spreadsheet::CT_Bar3DChart*) ct_plotArea->m_Items[i]); break; - case OOX::Spreadsheet::itemschoicetype5BARCHART: convert_before((OOX::Spreadsheet::CT_BarChart*) ct_plotArea->m_Items[i]); break; + case OOX::Spreadsheet::itemschoicetype5BAR3DCHART: convert_before((OOX::Spreadsheet::CT_Bar3DChart*)ct_plotArea->m_Items[i]); break; + case OOX::Spreadsheet::itemschoicetype5BARCHART: convert_before((OOX::Spreadsheet::CT_BarChart*)ct_plotArea->m_Items[i]); break; } } for (size_t i = 0; i < ct_plotArea->m_Items1.size(); i++) { if (!ct_plotArea->m_ItemsElementName1[i]) continue; - switch(*ct_plotArea->m_ItemsElementName1[i]) - { - case OOX::Spreadsheet::itemschoicetype6CATAX: convert((OOX::Spreadsheet::CT_CatAx*)ct_plotArea->m_Items1[i]);break; - case OOX::Spreadsheet::itemschoicetype6DATEAX: convert((OOX::Spreadsheet::CT_DateAx*)ct_plotArea->m_Items1[i]);break; - case OOX::Spreadsheet::itemschoicetype6SERAX: convert((OOX::Spreadsheet::CT_SerAx*)ct_plotArea->m_Items1[i]);break; - case OOX::Spreadsheet::itemschoicetype6VALAX: convert((OOX::Spreadsheet::CT_ValAx*)ct_plotArea->m_Items1[i]);break; + switch (*ct_plotArea->m_ItemsElementName1[i]) + { + case OOX::Spreadsheet::itemschoicetype6CATAX: convert((OOX::Spreadsheet::CT_CatAx*)ct_plotArea->m_Items1[i]); break; + case OOX::Spreadsheet::itemschoicetype6DATEAX: convert((OOX::Spreadsheet::CT_DateAx*)ct_plotArea->m_Items1[i]); break; + case OOX::Spreadsheet::itemschoicetype6SERAX: convert((OOX::Spreadsheet::CT_SerAx*)ct_plotArea->m_Items1[i]); break; + case OOX::Spreadsheet::itemschoicetype6VALAX: convert((OOX::Spreadsheet::CT_ValAx*)ct_plotArea->m_Items1[i]); break; } } - for (size_t i=0; i< ct_plotArea->m_Items.size(); i++)// + for (size_t i = 0; i < ct_plotArea->m_Items.size(); i++)// { if (!ct_plotArea->m_ItemsElementName0[i]) continue; - switch(*ct_plotArea->m_ItemsElementName0[i]) + switch (*ct_plotArea->m_ItemsElementName0[i]) { - case OOX::Spreadsheet::itemschoicetype5AREA3DCHART: convert((OOX::Spreadsheet::CT_Area3DChart*) ct_plotArea->m_Items[i]); chart3D = true; break; - case OOX::Spreadsheet::itemschoicetype5AREACHART: convert((OOX::Spreadsheet::CT_AreaChart*) ct_plotArea->m_Items[i]);break; - case OOX::Spreadsheet::itemschoicetype5BAR3DCHART: convert((OOX::Spreadsheet::CT_Bar3DChart*) ct_plotArea->m_Items[i]); chart3D = true; break; - case OOX::Spreadsheet::itemschoicetype5BARCHART: convert((OOX::Spreadsheet::CT_BarChart*) ct_plotArea->m_Items[i]);break; - case OOX::Spreadsheet::itemschoicetype5BUBBLECHART: convert((OOX::Spreadsheet::CT_BubbleChart*) ct_plotArea->m_Items[i]);break; - case OOX::Spreadsheet::itemschoicetype5DOUGHNUTCHART: convert((OOX::Spreadsheet::CT_DoughnutChart*) ct_plotArea->m_Items[i]);break; - case OOX::Spreadsheet::itemschoicetype5LINE3DCHART: convert((OOX::Spreadsheet::CT_Line3DChart*) ct_plotArea->m_Items[i]); chart3D = true; break; - case OOX::Spreadsheet::itemschoicetype5LINECHART: convert((OOX::Spreadsheet::CT_LineChart*) ct_plotArea->m_Items[i]);break; - case OOX::Spreadsheet::itemschoicetype5OFPIECHART: convert((OOX::Spreadsheet::CT_OfPieChart*) ct_plotArea->m_Items[i]);break; - case OOX::Spreadsheet::itemschoicetype5PIE3DCHART: convert((OOX::Spreadsheet::CT_Pie3DChart*) ct_plotArea->m_Items[i]); chart3D = true; break; - case OOX::Spreadsheet::itemschoicetype5PIECHART: convert((OOX::Spreadsheet::CT_PieChart*) ct_plotArea->m_Items[i]);break; - case OOX::Spreadsheet::itemschoicetype5RADARCHART: convert((OOX::Spreadsheet::CT_RadarChart*) ct_plotArea->m_Items[i]);break; - case OOX::Spreadsheet::itemschoicetype5SCATTERCHART: convert((OOX::Spreadsheet::CT_ScatterChart*) ct_plotArea->m_Items[i]);break; - case OOX::Spreadsheet::itemschoicetype5STOCKCHART: convert((OOX::Spreadsheet::CT_StockChart*) ct_plotArea->m_Items[i]);break; - case OOX::Spreadsheet::itemschoicetype5SURFACE3DCHART: convert((OOX::Spreadsheet::CT_Surface3DChart*) ct_plotArea->m_Items[i]); chart3D = true; break; - case OOX::Spreadsheet::itemschoicetype5SURFACECHART: convert((OOX::Spreadsheet::CT_SurfaceChart*) ct_plotArea->m_Items[i]);break; + case OOX::Spreadsheet::itemschoicetype5AREA3DCHART: convert((OOX::Spreadsheet::CT_Area3DChart*)ct_plotArea->m_Items[i]); chart3D = true; break; + case OOX::Spreadsheet::itemschoicetype5AREACHART: convert((OOX::Spreadsheet::CT_AreaChart*)ct_plotArea->m_Items[i]); break; + case OOX::Spreadsheet::itemschoicetype5BAR3DCHART: convert((OOX::Spreadsheet::CT_Bar3DChart*)ct_plotArea->m_Items[i]); chart3D = true; break; + case OOX::Spreadsheet::itemschoicetype5BARCHART: convert((OOX::Spreadsheet::CT_BarChart*)ct_plotArea->m_Items[i]); break; + case OOX::Spreadsheet::itemschoicetype5BUBBLECHART: convert((OOX::Spreadsheet::CT_BubbleChart*)ct_plotArea->m_Items[i]); break; + case OOX::Spreadsheet::itemschoicetype5DOUGHNUTCHART: convert((OOX::Spreadsheet::CT_DoughnutChart*)ct_plotArea->m_Items[i]); break; + case OOX::Spreadsheet::itemschoicetype5LINE3DCHART: convert((OOX::Spreadsheet::CT_Line3DChart*)ct_plotArea->m_Items[i]); chart3D = true; break; + case OOX::Spreadsheet::itemschoicetype5LINECHART: convert((OOX::Spreadsheet::CT_LineChart*)ct_plotArea->m_Items[i]); break; + case OOX::Spreadsheet::itemschoicetype5OFPIECHART: convert((OOX::Spreadsheet::CT_OfPieChart*)ct_plotArea->m_Items[i]); break; + case OOX::Spreadsheet::itemschoicetype5PIE3DCHART: convert((OOX::Spreadsheet::CT_Pie3DChart*)ct_plotArea->m_Items[i]); chart3D = true; break; + case OOX::Spreadsheet::itemschoicetype5PIECHART: convert((OOX::Spreadsheet::CT_PieChart*)ct_plotArea->m_Items[i]); break; + case OOX::Spreadsheet::itemschoicetype5RADARCHART: convert((OOX::Spreadsheet::CT_RadarChart*)ct_plotArea->m_Items[i]); break; + case OOX::Spreadsheet::itemschoicetype5SCATTERCHART: convert((OOX::Spreadsheet::CT_ScatterChart*)ct_plotArea->m_Items[i]); break; + case OOX::Spreadsheet::itemschoicetype5STOCKCHART: convert((OOX::Spreadsheet::CT_StockChart*)ct_plotArea->m_Items[i]); break; + case OOX::Spreadsheet::itemschoicetype5SURFACE3DCHART: convert((OOX::Spreadsheet::CT_Surface3DChart*)ct_plotArea->m_Items[i]); chart3D = true; break; + case OOX::Spreadsheet::itemschoicetype5SURFACECHART: convert((OOX::Spreadsheet::CT_SurfaceChart*)ct_plotArea->m_Items[i]); break; } } convert(ct_plotArea->m_dTable); convert(ct_plotArea->m_spPr.GetPointer()); - if (chart3D/* == false*/) - { - odf_context()->chart_context()->start_wall(); - { - convert(ct_plotArea->m_spPr.GetPointer()); - } - odf_context()->chart_context()->end_element(); - } } void OoxConverter::convert(OOX::Spreadsheet::CT_DTable *dTable) { @@ -1334,17 +1325,16 @@ void OoxConverter::convert(OOX::Spreadsheet::CT_NumDataSource* val) } void OoxConverter::convert(OOX::Spreadsheet::CT_Surface* ct_surface, int type, bool chart3D) { - if (ct_surface == NULL && chart3D == false)return; //floor, side, back - if (type == 1)odf_context()->chart_context()->start_floor(); - if (type == 2)odf_context()->chart_context()->start_wall(); + if (type == 1) odf_context()->chart_context()->start_floor(); + if (type == 2) odf_context()->chart_context()->start_wall(); //if (type == 3)odf_context()->chart_context()->start_back_wall(); if (ct_surface) { convert(ct_surface->m_spPr.GetPointer()); } - else if (chart3D)//тока для 3D так - хз почему + else { odf_context()->chart_context()->set_no_fill(true); } diff --git a/OdfFile/Writer/Converter/DocxConverter.cpp b/OdfFile/Writer/Converter/DocxConverter.cpp index 80f28e5b1ac..a8394c214de 100644 --- a/OdfFile/Writer/Converter/DocxConverter.cpp +++ b/OdfFile/Writer/Converter/DocxConverter.cpp @@ -211,6 +211,9 @@ bool DocxConverter::convertDocument() { if (!odt_context) return false; if (!docx_document && !docx_flat_document) return false; + + OOX::CApp* app = docx_document ? docx_document->m_pApp : docx_flat_document->m_pApp.GetPointer(); + OOX::CCore* core = docx_document ? docx_document->m_pCore : docx_flat_document->m_pCore.GetPointer(); odt_context->start_document(); @@ -218,7 +221,8 @@ bool DocxConverter::convertDocument() convert_styles(); convert_settings(); - convert_meta(docx_document->m_pApp, docx_document->m_pCore); + convert_meta(app, core); + convert_customs(docx_document); convert_document(); @@ -519,6 +523,8 @@ void DocxConverter::convert(OOX::Logic::CSdt *oox_sdt) _CP_OPT(double) x, y, width = 20, height = 20; + std::wstring parent_style = odf_context()->text_context()->get_current_style_name(); + if (oox_sdt->m_oSdtPr.IsInit()) { switch(oox_sdt->m_oSdtPr->m_eType) @@ -557,66 +563,72 @@ void DocxConverter::convert(OOX::Logic::CSdt *oox_sdt) } }break; } + if (bForm) { + _CP_OPT(double) zero = 0.; + odt_context->drawing_context()->set_parent_text_style(parent_style); odt_context->drawing_context()->set_vertical_rel(0); //baseline odt_context->drawing_context()->set_textarea_vertical_align(1);//middle - } - if (bForm && oox_sdt->m_oSdtPr->m_oDate.IsInit()) - { - odt_context->controls_context()->add_property(L"Dropdown", odf_types::office_value_type::Boolean, L"true"); - - if (oox_sdt->m_oSdtPr->m_oDate->m_oFullDate.IsInit()) + + odt_context->drawing_context()->set_textarea_padding(zero, zero, zero, zero); + + if (oox_sdt->m_oSdtPr->m_oDate.IsInit()) { odt_context->controls_context()->add_property(L"Dropdown", odf_types::office_value_type::Boolean, L"true"); - //odt_context->controls_context()->set_value(oox_sdt->m_oSdtPr->m_oDate->m_oFullDate->ToString()); + + if (oox_sdt->m_oSdtPr->m_oDate->m_oFullDate.IsInit()) + { + odt_context->controls_context()->add_property(L"Dropdown", odf_types::office_value_type::Boolean, L"true"); + //odt_context->controls_context()->set_value(oox_sdt->m_oSdtPr->m_oDate->m_oFullDate->ToString()); + } + if ((oox_sdt->m_oSdtPr->m_oDate->m_oDateFormat.IsInit()) && + (oox_sdt->m_oSdtPr->m_oDate->m_oDateFormat->m_sVal.IsInit())) + { + //odt_context->controls_context()->set_format(oox_sdt->m_oSdtPr->m_oDate->m_oDateFormat->m_sVal.get2()); + } } - if ((oox_sdt->m_oSdtPr->m_oDate->m_oDateFormat.IsInit()) && - (oox_sdt->m_oSdtPr->m_oDate->m_oDateFormat->m_sVal.IsInit())) + if (oox_sdt->m_oSdtPr->m_oDropDownList.IsInit()) { - //odt_context->controls_context()->set_format(oox_sdt->m_oSdtPr->m_oDate->m_oDateFormat->m_sVal.get2()); - } - } - if (bForm && oox_sdt->m_oSdtPr->m_oDropDownList.IsInit()) - { - odt_context->controls_context()->set_drop_down(true); + odt_context->controls_context()->set_drop_down(true); - size_t size = 0; - for ( size_t i = 0; i < oox_sdt->m_oSdtPr->m_oDropDownList->m_arrListItem.size(); i++ ) - { - if ( oox_sdt->m_oSdtPr->m_oDropDownList->m_arrListItem[i] ) + size_t size = 0; + for (size_t i = 0; i < oox_sdt->m_oSdtPr->m_oDropDownList->m_arrListItem.size(); i++) { - std::wstring val = oox_sdt->m_oSdtPr->m_oDropDownList->m_arrListItem[i]->m_sValue.get_value_or(L""); + if (oox_sdt->m_oSdtPr->m_oDropDownList->m_arrListItem[i]) + { + std::wstring val = oox_sdt->m_oSdtPr->m_oDropDownList->m_arrListItem[i]->m_sValue.get_value_or(L""); - if (val.length() > size) size = val.length(); - odt_context->controls_context()->add_item(val); + if (val.length() > size) size = val.length(); + odt_context->controls_context()->add_item(val); + } } - } - width = 10. * size; //todooo sizefont - odt_context->drawing_context()->set_size(width, height, true); - } - if (bForm && oox_sdt->m_oSdtPr->m_oComboBox.IsInit()) - { - size_t size = 0; - for ( size_t i = 0; i < oox_sdt->m_oSdtPr->m_oComboBox->m_arrListItem.size(); i++ ) + width = 10. * size; //todooo sizefont + odt_context->drawing_context()->set_size(width, height, true); + } + if (oox_sdt->m_oSdtPr->m_oComboBox.IsInit()) { - if ( oox_sdt->m_oSdtPr->m_oComboBox->m_arrListItem[i] ) + size_t size = 0; + for (size_t i = 0; i < oox_sdt->m_oSdtPr->m_oComboBox->m_arrListItem.size(); i++) { - std::wstring val = oox_sdt->m_oSdtPr->m_oComboBox->m_arrListItem[i]->m_sValue.get_value_or(L""); + if (oox_sdt->m_oSdtPr->m_oComboBox->m_arrListItem[i]) + { + std::wstring val = oox_sdt->m_oSdtPr->m_oComboBox->m_arrListItem[i]->m_sValue.get_value_or(L""); - if (val.length() > size) size = val.length(); - odt_context->controls_context()->add_item(val); + if (val.length() > size) size = val.length(); + odt_context->controls_context()->add_item(val); + } } - } - width = 10. * size; //todooo sizefont + width = 10. * size; //todooo sizefont - odt_context->drawing_context()->set_size(width, height, true); - } - if (bForm && oox_sdt->m_oSdtPr->m_oCheckbox.IsInit()) - { - if (oox_sdt->m_oSdtPr->m_oCheckbox->m_oChecked.IsInit()) + odt_context->drawing_context()->set_size(width, height, true); + } + if (oox_sdt->m_oSdtPr->m_oCheckbox.IsInit()) { - odt_context->controls_context()->set_check_state(oox_sdt->m_oSdtPr->m_oCheckbox->m_oChecked->m_oVal.ToBool() ? 1 : 0); + if (oox_sdt->m_oSdtPr->m_oCheckbox->m_oChecked.IsInit()) + { + odt_context->controls_context()->set_check_state(oox_sdt->m_oSdtPr->m_oCheckbox->m_oChecked->m_oVal.ToBool() ? 1 : 0); + } } } @@ -670,9 +682,18 @@ void DocxConverter::convert(OOX::Logic::CSdt *oox_sdt) } odt_context->controls_context()->set_value(value); + if (false == value.empty()) + { + odt_context->drawing_context()->set_textarea_fit_to_size(true); + } + if (!width) { - width = 10. * value.length(); //todooo sizefont + odf_context()->calculate_font_metrix(L"Arial", current_font_size.back(), false, false, true); + std::pair font_metrix = odf_context()->font_metrix(); + + width = font_metrix.first * value.length(); + height = font_metrix.second + 4; odt_context->drawing_context()->set_size(width, height, true); } } @@ -852,6 +873,9 @@ void DocxConverter::convert(OOX::Logic::CParagraph *oox_paragraph) list_style_name = odt_context->styles_context()->lists_styles().get_style_name(list_style_id); odt_context->styles_context()->last_state()->set_list_style_name(list_style_name); } + + if(oox_paragraph->m_oParagraphProperty) + convert(oox_paragraph->m_oParagraphProperty->m_oRPr.GetPointer(), text_properties); } if (odt_context->in_drop_cap()) { @@ -1849,38 +1873,38 @@ void DocxConverter::apply_HF_from(OOX::Logic::CSectionProperty *props, OOX::Logi } } } -void DocxConverter::convert(OOX::Logic::CSectionProperty *oox_section_pr, bool bSection, const std::wstring & master_name, bool bAlways) +void DocxConverter::convert(OOX::Logic::CSectionProperty* oox_section_pr, bool bSection, const std::wstring& master_name, bool bAlways) { if (oox_section_pr == NULL) return; current_section_properties = NULL; odt_context->text_context()->set_type_break(-1, 0); - + bool continuous = false; if (oox_section_pr->m_oType.IsInit() && oox_section_pr->m_oType->m_oVal.IsInit()) { - switch(oox_section_pr->m_oType->m_oVal->GetValue()) - { - case SimpleTypes::sectionmarkContinious : - continuous = true; + switch (oox_section_pr->m_oType->m_oVal->GetValue()) + { + case SimpleTypes::sectionmarkContinious: + continuous = true; break; - case SimpleTypes::sectionmarkNextColumn : - case SimpleTypes::sectionmarkEvenPage : - case SimpleTypes::sectionmarkNextPage : - case SimpleTypes::sectionmarkOddPage : + case SimpleTypes::sectionmarkNextColumn: + case SimpleTypes::sectionmarkEvenPage: + case SimpleTypes::sectionmarkNextPage: + case SimpleTypes::sectionmarkOddPage: // возможен разрыв break; } } - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool bDefault = (master_name == L"Standard"); - + if (!bDefault) { if (!last_section_properties && (!bSection || continuous == false || oox_section_pr->m_oTitlePg.IsInit())) - { + { last_section_properties = oox_section_pr; } else if (!bSection || continuous == false) @@ -1888,7 +1912,7 @@ void DocxConverter::convert(OOX::Logic::CSectionProperty *oox_section_pr, bool b apply_HF_from(last_section_properties, oox_section_pr); } } -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// if (!bSection || continuous == false) { odt_context->page_layout_context()->add_master_page(master_name); @@ -1898,14 +1922,14 @@ void DocxConverter::convert(OOX::Logic::CSectionProperty *oox_section_pr, bool b { _CP_OPT(odf_types::length) top, left, right, bottom, header, footer, gutter, header_min, footer_min; - convert(oox_section_pr->m_oPgMar->m_oBottom.GetPointer(), bottom); - convert(oox_section_pr->m_oPgMar->m_oLeft.GetPointer(), left); - convert(oox_section_pr->m_oPgMar->m_oRight.GetPointer(), right); - convert(oox_section_pr->m_oPgMar->m_oTop.GetPointer(), top); - convert(oox_section_pr->m_oPgMar->m_oHeader.GetPointer(), header); - convert(oox_section_pr->m_oPgMar->m_oFooter.GetPointer(), footer); - convert(oox_section_pr->m_oPgMar->m_oGutter.GetPointer(), gutter); - + convert(oox_section_pr->m_oPgMar->m_oBottom.GetPointer(), bottom); + convert(oox_section_pr->m_oPgMar->m_oLeft.GetPointer(), left); + convert(oox_section_pr->m_oPgMar->m_oRight.GetPointer(), right); + convert(oox_section_pr->m_oPgMar->m_oTop.GetPointer(), top); + convert(oox_section_pr->m_oPgMar->m_oHeader.GetPointer(), header); + convert(oox_section_pr->m_oPgMar->m_oFooter.GetPointer(), footer); + convert(oox_section_pr->m_oPgMar->m_oGutter.GetPointer(), gutter); + footer_min = footer; header_min = header; @@ -1914,8 +1938,8 @@ void DocxConverter::convert(OOX::Logic::CSectionProperty *oox_section_pr, bool b double bottom_cm = bottom->get_value_unit(length::cm); double footer_cm = footer ? footer->get_value_unit(length::cm) : 0; double length_cm = bottom_cm - footer_cm; - - if ( length_cm < 0 ) + + if (length_cm < 0) { footer_min = length(-length_cm, length::cm); footer.reset(); @@ -1932,18 +1956,34 @@ void DocxConverter::convert(OOX::Logic::CSectionProperty *oox_section_pr, bool b } if (top) { - double length_cm = top->get_value_unit(length::cm) - (header ? header->get_value_unit(length::cm) : 0); - - if ( length_cm > 2.4 ) + double length_cm = top->get_value_unit(length::cm); + + if (header) + { + double header_length_cm = header->get_value_unit(length::cm); + if (abs(length_cm - header_length_cm) > 0.001) + length_cm -= header_length_cm; + } + + if (length_cm > 2.4) { top = header; header = length(fabs(length_cm), length::cm); } - else if ( length_cm < 0 ) + else if (length_cm < 0) { header_min = length(-length_cm, length::cm); header.reset(); } + else if (length_cm < 0.) + { + header_min = length(-length_cm, length::cm); + header.reset(); + } + else + { + top = length(length_cm, length::cm); + } } else { @@ -1959,14 +1999,14 @@ void DocxConverter::convert(OOX::Logic::CSectionProperty *oox_section_pr, bool b std::wstring top, left, right, bottom; convert(oox_section_pr->m_oPgBorders->m_oBottom.GetPointer(), bottom); - convert(oox_section_pr->m_oPgBorders->m_oLeft.GetPointer() , left); - convert(oox_section_pr->m_oPgBorders->m_oRight.GetPointer() , right); - convert(oox_section_pr->m_oPgBorders->m_oTop.GetPointer() , top); - + convert(oox_section_pr->m_oPgBorders->m_oLeft.GetPointer(), left); + convert(oox_section_pr->m_oPgBorders->m_oRight.GetPointer(), right); + convert(oox_section_pr->m_oPgBorders->m_oTop.GetPointer(), top); + odt_context->page_layout_context()->set_page_border(top, left, bottom, right); - - if (oox_section_pr->m_oPgBorders->m_oOffsetFrom.IsInit() && + + if (oox_section_pr->m_oPgBorders->m_oOffsetFrom.IsInit() && (oox_section_pr->m_oPgBorders->m_oOffsetFrom->GetValue() == SimpleTypes::pageborderoffsetPage)) { odt_context->page_layout_context()->set_page_border_offset(2); @@ -1990,14 +2030,14 @@ void DocxConverter::convert(OOX::Logic::CSectionProperty *oox_section_pr, bool b if (oox_section_pr->m_oPgBorders->m_oLeft.IsInit()) { int type = (oox_section_pr->m_oPgBorders->m_oBottom->m_oVal.IsInit() ? oox_section_pr->m_oPgBorders->m_oLeft->m_oVal->GetValue() : SimpleTypes::bordervalueSingle); - + if (oox_section_pr->m_oPgBorders->m_oLeft->m_oSpace.IsInit()) odt_context->page_layout_context()->set_page_border_padding(3, oox_section_pr->m_oPgBorders->m_oLeft->m_oSpace->ToPoints()); } if (oox_section_pr->m_oPgBorders->m_oRight.IsInit()) { int type = (oox_section_pr->m_oPgBorders->m_oBottom->m_oVal.IsInit() ? oox_section_pr->m_oPgBorders->m_oRight->m_oVal->GetValue() : SimpleTypes::bordervalueSingle); - + if (oox_section_pr->m_oPgBorders->m_oRight->m_oSpace.IsInit()) odt_context->page_layout_context()->set_page_border_padding(4, oox_section_pr->m_oPgBorders->m_oRight->m_oSpace->ToPoints()); } @@ -2008,9 +2048,9 @@ void DocxConverter::convert(OOX::Logic::CSectionProperty *oox_section_pr, bool b if (oox_section_pr->m_oPgBorders->m_oTop.IsInit() && oox_section_pr->m_oPgBorders->m_oTop->m_oShadow.IsInit() && oox_section_pr->m_oPgBorders->m_oTop->m_oShadow->ToBool()) shadow = true; if (oox_section_pr->m_oPgBorders->m_oLeft.IsInit() && oox_section_pr->m_oPgBorders->m_oLeft->m_oShadow.IsInit() && oox_section_pr->m_oPgBorders->m_oLeft->m_oShadow->ToBool()) shadow = true; if (oox_section_pr->m_oPgBorders->m_oRight.IsInit() && oox_section_pr->m_oPgBorders->m_oRight->m_oShadow.IsInit() && oox_section_pr->m_oPgBorders->m_oRight->m_oShadow->ToBool()) shadow = true; - + if (shadow) odt_context->page_layout_context()->set_page_border_shadow(true); - + if (oox_section_pr->m_oPgBorders->m_oDisplay.IsInit()) { // todooo @@ -2045,9 +2085,9 @@ void DocxConverter::convert(OOX::Logic::CSectionProperty *oox_section_pr, bool b { convert(docx_flat_document->m_pBgPict.GetPointer(), 1); } - //nullable m_oTextDirection; - //nullable m_oRtlGutter; - //nullable m_oVAlign; + //nullable m_oTextDirection; + //nullable m_oRtlGutter; + //nullable m_oVAlign; if (oox_section_pr->m_oPgNumType.IsInit()) { @@ -2055,23 +2095,23 @@ void DocxConverter::convert(OOX::Logic::CSectionProperty *oox_section_pr, bool b _CP_OPT(int) start; if (oox_section_pr->m_oPgNumType->m_oFmt.IsInit()) format = oox_section_pr->m_oPgNumType->m_oFmt->GetValue(); - if (oox_section_pr->m_oPgNumType->m_oStart.IsInit()) start = oox_section_pr->m_oPgNumType->m_oStart->GetValue(); + if (oox_section_pr->m_oPgNumType->m_oStart.IsInit()) start = oox_section_pr->m_oPgNumType->m_oStart->GetValue(); - odt_context->page_layout_context()->set_page_number_format( format, start); - //nullable > m_oChapSep; - //nullable > m_oChapStyle; + odt_context->page_layout_context()->set_page_number_format(format, start); + //nullable > m_oChapSep; + //nullable > m_oChapStyle; } - + if (continuous == false || oox_section_pr->m_oTitlePg.IsInit() || bAlways) { - OOX::Logic::CSectionProperty* s = last_section_properties ? last_section_properties : oox_section_pr; - - bool present_title_page = s->m_oTitlePg.IsInit() ? true : false; - bool present_odd_even_pages = odt_context->page_layout_context()->even_and_left_headers_; - - bool add_title_header = false, add_title_footer = false; - bool add_odd_even_pages_header = false, add_odd_even_pages_footer = false; - bool add_default_header = false, add_default_footer = false; + OOX::Logic::CSectionProperty* s = last_section_properties ? last_section_properties : oox_section_pr; + + bool present_title_page = s->m_oTitlePg.IsInit() ? true : false; + bool present_odd_even_pages = odt_context->page_layout_context()->even_and_left_headers_; + + bool add_title_header = false, add_title_footer = false; + bool add_odd_even_pages_header = false, add_odd_even_pages_footer = false; + bool add_default_header = false, add_default_footer = false; std::vector types; @@ -2079,14 +2119,14 @@ void DocxConverter::convert(OOX::Logic::CSectionProperty *oox_section_pr, bool b { if (s->m_arrHeaderReference[i] == NULL) continue; - int type = s->m_arrHeaderReference[i]->m_oType.IsInit() ? s->m_arrHeaderReference[i]->m_oType->GetValue() : 0 ; + int type = s->m_arrHeaderReference[i]->m_oType.IsInit() ? s->m_arrHeaderReference[i]->m_oType->GetValue() : 0; if (type == 2 && !present_title_page) continue; if (type == 1 && !present_odd_even_pages) continue; - if (type == 2 && present_title_page) add_title_header = true; - if (type == 1 && present_odd_even_pages) add_odd_even_pages_header = true; //swap even & odd ? - if (type == 0) add_default_header = true; + if (type == 2 && present_title_page) add_title_header = true; + if (type == 1 && present_odd_even_pages) add_odd_even_pages_header = true; //swap even & odd ? + if (type == 0) add_default_header = true; if (odt_context->start_header(type)) { @@ -2102,22 +2142,22 @@ void DocxConverter::convert(OOX::Logic::CSectionProperty *oox_section_pr, bool b odt_context->end_header_footer(); } } - if (!add_title_header && present_title_page) odt_context->add_empty_header(2); - if (!add_odd_even_pages_header && present_odd_even_pages) odt_context->add_empty_header(1); - if (!add_default_header && (present_odd_even_pages || present_title_page)) odt_context->add_empty_header(0); + if (!add_title_header && present_title_page) odt_context->add_empty_header(2); + if (!add_odd_even_pages_header && present_odd_even_pages) odt_context->add_empty_header(1); + if (!add_default_header && (present_odd_even_pages || present_title_page)) odt_context->add_empty_header(0); - for (size_t i=0; i< s->m_arrFooterReference.size(); i++) + for (size_t i = 0; i < s->m_arrFooterReference.size(); i++) { if (s->m_arrFooterReference[i] == NULL) continue; - int type = s->m_arrFooterReference[i]->m_oType.IsInit() ? s->m_arrFooterReference[i]->m_oType->GetValue() :0 ; + int type = s->m_arrFooterReference[i]->m_oType.IsInit() ? s->m_arrFooterReference[i]->m_oType->GetValue() : 0; if (type == 2 && !present_title_page) continue; if (type == 1 && !present_odd_even_pages) continue; - if (type == 2 && present_title_page) add_title_footer = true; - if (type == 1 && present_odd_even_pages) add_odd_even_pages_footer = true; - if (type == 0) add_default_footer = true; + if (type == 2 && present_title_page) add_title_footer = true; + if (type == 1 && present_odd_even_pages) add_odd_even_pages_footer = true; + if (type == 0) add_default_footer = true; if (odt_context->start_footer(type)) { @@ -2130,12 +2170,12 @@ void DocxConverter::convert(OOX::Logic::CSectionProperty *oox_section_pr, bool b } } - odt_context->end_header_footer(); + odt_context->end_header_footer(); } } - if (!add_title_footer && present_title_page) odt_context->add_empty_footer(2); - if (!add_odd_even_pages_footer && present_odd_even_pages) odt_context->add_empty_footer(1); - if (!add_default_footer && (present_odd_even_pages || present_title_page)) odt_context->add_empty_footer(0); + if (!add_title_footer && present_title_page) odt_context->add_empty_footer(2); + if (!add_odd_even_pages_footer && present_odd_even_pages) odt_context->add_empty_footer(1); + if (!add_default_footer && (present_odd_even_pages || present_title_page)) odt_context->add_empty_footer(0); if (!bDefault) odt_context->is_paragraph_in_current_section_ = true; @@ -2144,16 +2184,17 @@ void DocxConverter::convert(OOX::Logic::CSectionProperty *oox_section_pr, bool b // odt_context->page_layout_context()->last_master()->get_name() : L""); } if (oox_section_pr->m_oLnNumType.IsInit()) - {//linenumbering-configuration один для всех секций и всех разметок страниц ((( - хуевый OpenOffice (также не начала нумерации) - //Ms Office тоже фуфло - нет нумерации алфавитами и римскими, нет разделителей + { odf_writer::office_element_ptr lnNum_elm; odf_writer::create_element(L"text", L"linenumbering-configuration", lnNum_elm, odf_context()); - odf_writer::text_linenumbering_configuration *linenumbering = dynamic_cast(lnNum_elm.get()); + odf_writer::text_linenumbering_configuration* linenumbering = dynamic_cast(lnNum_elm.get()); if (!linenumbering) return; linenumbering->text_style_name_ = odt_context->styles_context()->find_free_name(style_family::LineNumbering); linenumbering->text_number_lines_ = true; + linenumbering->style_num_format_ = odf_types::style_numformat::arabic; + linenumbering->text_number_position_ = L"left"; if (oox_section_pr->m_oLnNumType->m_oCountBy.IsInit()) { @@ -2162,19 +2203,20 @@ void DocxConverter::convert(OOX::Logic::CSectionProperty *oox_section_pr, bool b if (oox_section_pr->m_oLnNumType->m_oDistance.IsInit()) { linenumbering->text_offset_ = odf_types::length(oox_section_pr->m_oLnNumType->m_oDistance->ToPoints(), odf_types::length::pt); - } - if (oox_section_pr->m_oLnNumType->m_oRestart.IsInit()) + } + else { - if (oox_section_pr->m_oLnNumType->m_oRestart->GetValue() == SimpleTypes::linenumberrestartNewPage) - { - linenumbering->text_restart_on_page_ = true; - } - else - { - } + linenumbering->text_offset_ = odf_types::length(0.5, odf_types::length::cm); } - if (oox_section_pr->m_oLnNumType->m_oStart.IsInit()) + if ((oox_section_pr->m_oLnNumType->m_oRestart.IsInit() && (oox_section_pr->m_oLnNumType->m_oRestart->GetValue() == SimpleTypes::linenumberrestartNewPage)) + || false == oox_section_pr->m_oLnNumType->m_oRestart.IsInit()) { + linenumbering->text_restart_on_page_ = true; + } + + if (oox_section_pr->m_oLnNumType->m_oStart.IsInit()) + {//нет в формате ??? + linenumbering->text_start_ = oox_section_pr->m_oLnNumType->m_oStart->GetValue(); } odt_context->styles_context()->add_style(lnNum_elm, false, true, style_family::LineNumbering); @@ -3123,7 +3165,7 @@ void DocxConverter::convert(OOX::Logic::CObject* oox_obj) { pathOle = find_link_by_id(oox_obj->m_oOleObject->m_oId->GetValue(), 4, bExternal); } - std::wstring odf_ref_ole = odf_context()->add_oleobject(pathOle); + std::wstring odf_ref_ole = odf_context()->add_oleobject(pathOle, bExternal); if (!odf_ref_ole.empty()) { @@ -3136,7 +3178,7 @@ void DocxConverter::convert(OOX::Logic::CObject* oox_obj) std::wstring sIdImageFileCache = GetImageIdFromVmlShape(oox_obj->m_oShape.GetPointer()); std::wstring pathImage = find_link_by_id(sIdImageFileCache, 1, bExternal); - std::wstring odf_ref_image = odf_context()->add_imageobject(pathImage); + std::wstring odf_ref_image = odf_context()->add_imageobject(pathImage, bExternal); OoxConverter::convert(oox_obj->m_oShape.GetPointer(), NULL); odf_context()->drawing_context()->set_image_replacement(odf_ref_image); @@ -3548,6 +3590,57 @@ void DocxConverter::convert_settings() if (settings->m_oWriteProtection.IsInit()) { + std::wstring algorithm, crypt; + + if (settings->m_oWriteProtection->m_oAlgorithmName.IsInit()) algorithm = settings->m_oWriteProtection->m_oAlgorithmName->ToString(); + else if (settings->m_oWriteProtection->m_oCryptAlgorithmSid.IsInit()) + { + switch (*settings->m_oWriteProtection->m_oCryptAlgorithmSid) + { + case 1: algorithm = L"MD2"; break; + case 2: algorithm = L"MD4"; break; + case 3: algorithm = L"MD5"; break; + case 4: algorithm = L"SHA-1"; break; + case 5: algorithm = L"MAC"; break; + case 6: algorithm = L"RIPEMD"; break; + case 7: algorithm = L"RIPEMD-160"; break; + case 9: algorithm = L"HMAC"; break; + case 12: algorithm = L"SHA-256"; break; + case 13: algorithm = L"SHA-386"; break; + case 14: algorithm = L"SHA-512"; break; + } + } + if (settings->m_oWriteProtection->m_oCryptProviderType.IsInit()) crypt = settings->m_oWriteProtection->m_oCryptProviderType->ToString(); + + odt_context->settings_context()->set_modify_info(crypt, algorithm, settings->m_oWriteProtection->m_sSaltValue.get_value_or(L""), + settings->m_oWriteProtection->m_sHashValue.get_value_or(L""), settings->m_oWriteProtection->m_oSpinCount.get_value_or(1)); + } + if (settings->m_oDocumentProtection.IsInit()) + { + std::wstring algorithm, crypt; + + if (settings->m_oDocumentProtection->m_oAlgorithmName.IsInit()) algorithm = settings->m_oDocumentProtection->m_oAlgorithmName->ToString(); + else if (settings->m_oDocumentProtection->m_oCryptAlgorithmSid.IsInit()) + { + switch (*settings->m_oDocumentProtection->m_oCryptAlgorithmSid) + { + case 1: algorithm = L"MD2"; break; + case 2: algorithm = L"MD4"; break; + case 3: algorithm = L"MD5"; break; + case 4: algorithm = L"SHA-1"; break; + case 5: algorithm = L"MAC"; break; + case 6: algorithm = L"RIPEMD"; break; + case 7: algorithm = L"RIPEMD-160"; break; + case 9: algorithm = L"HMAC"; break; + case 12: algorithm = L"SHA-256"; break; + case 13: algorithm = L"SHA-386"; break; + case 14: algorithm = L"SHA-512"; break; + } + } + if (settings->m_oDocumentProtection->m_oCryptProviderType.IsInit()) crypt = settings->m_oDocumentProtection->m_oCryptProviderType->ToString(); + + odt_context->settings_context()->set_modify_info(crypt, algorithm, settings->m_oDocumentProtection->m_sSaltValue.get_value_or(L""), + settings->m_oDocumentProtection->m_sHashValue.get_value_or(L""), settings->m_oDocumentProtection->m_oSpinCount.get_value_or(1)); } if (settings->m_oZoom.IsInit()) { @@ -3712,6 +3805,7 @@ void DocxConverter::convert(OOX::CDocDefaults *def_style, OOX::CStyles *styles) std::map::iterator pFindParaDefault = styles->m_mapStyleDefaults.find(SimpleTypes::styletypeParagraph); std::map::iterator pFindRunDefault = styles->m_mapStyleDefaults.find(SimpleTypes::styletypeCharacter); + std::map::iterator pFindTableDefault = styles->m_mapStyleDefaults.find(SimpleTypes::styletypeTable); if (def_style->m_oParPr.IsInit() || pFindParaDefault != styles->m_mapStyleDefaults.end()) { @@ -3794,6 +3888,22 @@ void DocxConverter::convert(OOX::CDocDefaults *def_style, OOX::CStyles *styles) } } + if (pFindTableDefault != styles->m_mapStyleDefaults.end()) + { + OOX::CStyle* style = styles->m_arrStyle[pFindTableDefault->second]; + if (style->m_oTblPr.IsInit() && style->m_oTblPr->m_oTblCellMar.IsInit()) + { + _CP_OPT(odf_types::length) left, right, top, bottom; + + convert(style->m_oTblPr->m_oTblCellMar->m_oStart.GetPointer(), left); + convert(style->m_oTblPr->m_oTblCellMar->m_oEnd.GetPointer(), right); + convert(style->m_oTblPr->m_oTblCellMar->m_oTop.GetPointer(), top); + convert(style->m_oTblPr->m_oTblCellMar->m_oBottom.GetPointer(), bottom); + + odt_context->table_context()->set_default_cell_paddings(left, right, top, bottom); + } + } + /////////////////////////////////////////////////////////////////////////// odt_context->styles_context()->create_default_style(odf_types::style_family::Table); @@ -5257,6 +5367,21 @@ bool DocxConverter::convert(OOX::Logic::CTableCellProperties *oox_table_cell_pr, } cell_properties->apply_from(parent_cell_properties); + { + // Default table style from styles.xml + _CP_OPT(odf_types::length) left, right, top, bottom; + odt_context->table_context()->get_default_cell_paddings(left, right, top, bottom); + + if (!cell_properties->content_.common_padding_attlist_.fo_padding_left_) + cell_properties->content_.common_padding_attlist_.fo_padding_left_ = left; + if (!cell_properties->content_.common_padding_attlist_.fo_padding_right_) + cell_properties->content_.common_padding_attlist_.fo_padding_right_ = right; + if (!cell_properties->content_.common_padding_attlist_.fo_padding_top_) + cell_properties->content_.common_padding_attlist_.fo_padding_top_ = top; + if (!cell_properties->content_.common_padding_attlist_.fo_padding_bottom_) + cell_properties->content_.common_padding_attlist_.fo_padding_bottom_ = bottom; + } + //check for inside cell or not _CP_OPT(std::wstring) border_inside_v = odt_context->table_context()->get_table_inside_v(); diff --git a/OdfFile/Writer/Converter/MathConverter.cpp b/OdfFile/Writer/Converter/MathConverter.cpp index 775989c86d7..342ffaac12f 100644 --- a/OdfFile/Writer/Converter/MathConverter.cpp +++ b/OdfFile/Writer/Converter/MathConverter.cpp @@ -33,6 +33,8 @@ //#include "../utils.h" +#include "../../Reader/Converter/StarMath2OOXML/cooxml2odf.h" + #include "../../OOXML/DocxFormat/DocxFlat.h" #include "../../OOXML/DocxFormat/Math/OMath.h" #include "../../OOXML/DocxFormat/Math/oMathContent.h" @@ -97,56 +99,6 @@ namespace Oox2Odf lvl_down_counter += val; } - std::wstring& OoxConverter::annotation() - { - return odf_context()->math_context()->annotation; - } - - void annotaionReplaceAll(std::wstring& annotation, std::wstring substr1, std::wstring substr2) - { - size_t pos = annotation.find(substr1); - while (pos != std::wstring::npos) - { - annotation.replace(pos, substr1.size(), substr2); - pos = annotation.find(substr1, pos + substr2.size()); - } - } - - void annotationPostProd(std::wstring& annotation) - { - annotaionReplaceAll(annotation, L"=", L"\"=\""); - annotaionReplaceAll(annotation, L"+", L"\"+\""); - annotaionReplaceAll(annotation, L"-", L"\"-\""); - annotaionReplaceAll(annotation, L"{) }", L")"); - annotaionReplaceAll(annotation, L"{( }", L"("); - annotaionReplaceAll(annotation, L"*", L"\"*\""); - annotaionReplaceAll(annotation, L"|", L"\"|\""); - // ∥ - size_t pos = annotation.find(L"∥"); - std::vector positions; - //positions.push_back(pos); - while (pos != std::wstring::npos) - { - positions.push_back(pos); - pos = annotation.find(L"∥", pos + 1); - } - std::wstring str1 = L"ldline"; - std::wstring str2 = L"rdline"; - for (int i = positions.size() - 1; i >= 0; i--) - { - if (i % 2 == 0) - annotation.replace(positions[i], 1, str1); - else - annotation.replace(positions[i], 1, str2); - } - - //if (annotation[0] == L'=') - // annotation = L"\"\"" + annotation; - - //if ((annotation[annotation.size() - 1] == L'=') || (annotation[annotation.size() - 1] == L' ') && annotation[annotation.size() - 2] == L'=') - // annotation = annotation + L"\"\""; - } - std::vector hexToIntColor(std::wstring clr) { std::vector rgb; @@ -198,11 +150,6 @@ namespace Oox2Odf return arrColor[index]; } - bool& OoxConverter::annotation_flag() - { - return odf_context()->math_context()->annotation_flag; - } - void OoxConverter::mrow() // обертка для тега { CREATE_MATH_TAG(L"mrow"); @@ -227,35 +174,36 @@ namespace Oox2Odf brackets().resize(1); bool bStart = odf_context()->start_math(); - for (size_t i = 0; i < oox_math->m_arrItems.size(); ++i) { convert(oox_math->m_arrItems[i]); } - if (annotation_flag()) + + if (bStart) { - CREATE_MATH_TAG(L"annotation"); - typedef odf_writer::math_annotation* T; - T tmp = dynamic_cast(elm.get()); - if (tmp) + StarMath::COOXml2Odf starMathConverter; + starMathConverter.StartConversion(oox_math); + + std::wstring annotation_text = starMathConverter.GetAnnotation(); + + if (false == annotation_text.empty()) { - tmp->encoding_ = L"StarMath 5.0"; + CREATE_MATH_TAG(L"annotation"); + typedef odf_writer::math_annotation* T; + T tmp = dynamic_cast(elm.get()); + if (tmp) + { + tmp->encoding_ = L"StarMath 5.0"; + } + elm->add_text(annotation_text); + + OPEN_MATH_TAG(elm); + CLOSE_MATH_TAG; } - - annotationPostProd(annotation()); - elm->add_text(annotation()); - OPEN_MATH_TAG(elm); - CLOSE_MATH_TAG; + odf_context()->end_math(); } - else - annotation_flag() = true; - annotation().clear(); - - - - if (bStart) odf_context()->end_math(); } void OoxConverter::convert(OOX::Logic::CMathPr *oox_math_pr) @@ -294,9 +242,29 @@ namespace Oox2Odf { convert(oox_math_para->m_arrItems[i]); } - if (bStart) + { + StarMath::COOXml2Odf starMathConverter; + starMathConverter.StartConversion(oox_math_para); + + std::wstring annotation_text = starMathConverter.GetAnnotation(); + + if (false == annotation_text.empty()) + { + CREATE_MATH_TAG(L"annotation"); + typedef odf_writer::math_annotation* T; + T tmp = dynamic_cast(elm.get()); + if (tmp) + { + tmp->encoding_ = L"StarMath 5.0"; + } + elm->add_text(annotation_text); + + OPEN_MATH_TAG(elm); + CLOSE_MATH_TAG; + } odf_context()->end_math(); + } } void OoxConverter::convert(OOX::Logic::COMathParaPr *oox_math_para_pr) @@ -335,25 +303,9 @@ namespace Oox2Odf std::wstring symbol; symbol = (map[diakSymbol]); - std::map& annotation_map = odf_context()->math_context()->annotation_diak_symbols; - bool annotation_flag; - if (annotation_map.find(symbol) != annotation_map.end()) - { - annotation() += annotation_map[symbol] + L" "; - annotation_flag = true; - } - else - annotation_flag = false; - - annotation() += L"{"; convert(oox_acc->m_oElement.GetPointer()); - annotation() += L"}"; - if (!annotation_flag) - { - annotation() += L" csup "; - annotation() += L"\"" + symbol + L"\""; - } + { CREATE_MATH_TAG(L"mo"); elm->add_text(symbol); @@ -366,7 +318,6 @@ namespace Oox2Odf if (values.colorFlag) { CLOSE_MATH_TAG; - annotation() += L"}"; } } @@ -413,9 +364,6 @@ namespace Oox2Odf CREATE_MATH_TAG(tag.c_str()); OPEN_MATH_TAG(elm); { - if(values.auxFlag) annotation() += L"bar {"; - else annotation() += L"underline { "; - convert(oox_bar->m_oElement.GetPointer()); CREATE_MATH_TAG(L"mo"); if (values.auxFlag) elm->add_text(L"¯"); @@ -423,8 +371,6 @@ namespace Oox2Odf OPEN_MATH_TAG(elm); CLOSE_MATH_TAG; - - annotation() += L"} "; } CLOSE_MATH_TAG; if (values.auxFlag) @@ -434,7 +380,6 @@ namespace Oox2Odf if (values.colorFlag) { CLOSE_MATH_TAG; - annotation() += L"}"; } } @@ -461,7 +406,6 @@ namespace Oox2Odf if (values.colorFlag) { CLOSE_MATH_TAG; - annotation() += L"}"; } } @@ -499,7 +443,6 @@ namespace Oox2Odf if (val.colorFlag) { CLOSE_MATH_TAG; - annotation() += L"}"; } } @@ -529,6 +472,7 @@ namespace Oox2Odf bool OoxConverter::convert(OOX::Logic::COpEmu *oox_op_emu) { if (!oox_op_emu) return false; + if (!oox_op_emu->m_val.IsInit()) return false; if (oox_op_emu->m_val->ToBool())// == L"true") ||(oox_op_emu->m_val == L"1")) return true; @@ -570,10 +514,6 @@ namespace Oox2Odf } OPEN_MATH_TAG(elm); CLOSE_MATH_TAG; - if (values.begEndChrs.first == L"") - annotation() += L"left none "; //left none - else - annotation() += L"left " + odf_context()->math_context()->annotation_brackets_begin[values.begEndChrs.first] + L" "; } for (size_t i = 0; i < oox_del->m_arrItems.size(); ++i) @@ -596,17 +536,11 @@ namespace Oox2Odf } OPEN_MATH_TAG(elm); CLOSE_MATH_TAG; - if (values.begEndChrs.second == L"") - annotation() += L"right none "; //right none - else - annotation() += L"right " + odf_context()->math_context()->annotation_brackets_end[values.begEndChrs.second] + L" "; - } endOfMrow(); if (values.colorFlag) { CLOSE_MATH_TAG; - annotation() += L"}"; } } @@ -659,8 +593,6 @@ namespace Oox2Odf CREATE_MATH_TAG(L"mtable"); OPEN_MATH_TAG(elm); { - for (size_t i = 1; i < oox_eq_arr->m_arrItems.size() - 1; ++i) - annotation() += L" binom "; for (size_t i = 1; i < oox_eq_arr->m_arrItems.size(); ++i) { CREATE_MATH_TAG(L"mtr"); @@ -669,9 +601,7 @@ namespace Oox2Odf CREATE_MATH_TAG(L"mtd"); OPEN_MATH_TAG(elm); mrow(); - annotation() += L"{"; convert(oox_eq_arr->m_arrItems[i]); - annotation() += L"} "; endOfMrow(); CLOSE_MATH_TAG; } @@ -682,7 +612,6 @@ namespace Oox2Odf if(values.colorFlag) { CLOSE_MATH_TAG; - annotation() += L"}"; } } @@ -734,15 +663,10 @@ namespace Oox2Odf if (val.str == L"lin") { - - annotation() += L"{"; - mrow(); convert(oox_fraction->m_oNum.GetPointer()); endOfMrow(); - annotation() += L"} / {"; - CREATE_MATH_TAG(L"mo"); elm->add_text(L"/"); OPEN_MATH_TAG(elm); @@ -750,8 +674,6 @@ namespace Oox2Odf mrow(); convert(oox_fraction->m_oDen.GetPointer()); endOfMrow(); - - annotation() += L"}"; } else if (val.str == L"skw") { @@ -766,15 +688,12 @@ namespace Oox2Odf tmp->bevelled = true; } OPEN_MATH_TAG(elm); - annotation() += L"{"; mrow(); convert(oox_fraction->m_oNum.GetPointer()); endOfMrow(); - annotation() += L"} wideslash {"; mrow(); convert(oox_fraction->m_oDen.GetPointer()); endOfMrow(); - annotation() += L"}"; CLOSE_MATH_TAG; lvl_up_counter_decreace(1); lvl_down_counter_increace(1); @@ -789,12 +708,12 @@ namespace Oox2Odf { CREATE_MATH_TAG(L"mtd"); OPEN_MATH_TAG(elm); - annotation() += L"binom{"; + mrow(); convert(oox_fraction->m_oNum.GetPointer()); endOfMrow(); + CLOSE_MATH_TAG; - annotation() += L"} {"; } CLOSE_MATH_TAG; } @@ -808,7 +727,6 @@ namespace Oox2Odf convert(oox_fraction->m_oDen.GetPointer()); endOfMrow(); CLOSE_MATH_TAG; - annotation() += L"}"; } CLOSE_MATH_TAG; } @@ -819,23 +737,22 @@ namespace Oox2Odf CREATE_MATH_TAG(L"mfrac"); lvl_up_counter_increace(1); lvl_down_counter_decreace(1); - annotation() += L"{"; + OPEN_MATH_TAG(elm); mrow(); convert(oox_fraction->m_oNum.GetPointer()); endOfMrow(); - annotation() += L"} over {"; + mrow(); convert(oox_fraction->m_oDen.GetPointer()); endOfMrow(); - annotation() += L"}"; + CLOSE_MATH_TAG; lvl_up_counter_decreace(1); lvl_down_counter_increace(1); } if (val.colorFlag) { - annotation() += L"}"; CLOSE_MATH_TAG; } } @@ -854,6 +771,7 @@ namespace Oox2Odf std::wstring OoxConverter::convert(OOX::Logic::CType *oox_type) { if (!oox_type) return L""; + if (!oox_type->m_val.IsInit()) return L""; std::wstring val = oox_type->m_val->ToString(); @@ -893,7 +811,6 @@ namespace Oox2Odf if (values.colorFlag) { CLOSE_MATH_TAG; - annotation() += L"}"; } } @@ -967,16 +884,11 @@ namespace Oox2Odf { if (oox_lim) { - annotation() += L"overbrace {"; convert(oox_lim); - annotation() += L"}"; } - else - annotation() += L"overbrace \"\""; } else { - annotation() += L" csup "; convert(oox_group_ch->m_oGroupChrPr->m_oChr.GetPointer()); } } @@ -984,7 +896,6 @@ namespace Oox2Odf { if (oox_group_ch->m_oGroupChrPr->m_oChr.IsInit()) { - annotation() += L" csub "; convert(oox_group_ch->m_oGroupChrPr->m_oChr.GetPointer()); } else @@ -993,14 +904,11 @@ namespace Oox2Odf elm->add_text(L" ⏟ "); OPEN_MATH_TAG(elm); CLOSE_MATH_TAG; + if (oox_lim) { - annotation() += L"underbrace {"; convert(oox_lim); - annotation() += L"}"; } - else - annotation() += L"underbrace \"\""; } } CLOSE_MATH_TAG; @@ -1011,7 +919,6 @@ namespace Oox2Odf if (values.colorFlag) { CLOSE_MATH_TAG; - annotation() += L"}"; } } @@ -1031,6 +938,7 @@ namespace Oox2Odf bool OoxConverter::convert(OOX::Logic::CPos *oox_pos) { if (!oox_pos) return false; + if (!oox_pos->m_val.IsInit()) return false; if (oox_pos->m_val->ToString() == L"top") return true; else return false; @@ -1058,14 +966,11 @@ namespace Oox2Odf } else { - odf_context()->math_context()->annotation_oper_flag = true; mrow(); convert(oox_lim_low->m_oElement.GetPointer()); endOfMrow(); - annotation() += L"from {"; convert(oox_lim_low->m_oLim.GetPointer()); - annotation() += L"} "; } CLOSE_MATH_TAG; @@ -1077,7 +982,6 @@ namespace Oox2Odf if (values.colorFlag) { CLOSE_MATH_TAG; - annotation() += L"}"; } } @@ -1118,15 +1022,11 @@ namespace Oox2Odf } else { - annotation() += L"oper "; - mrow(); convert(oox_lim_upp->m_oElement.GetPointer()); endOfMrow(); - annotation() += L"to {"; convert(oox_lim_upp->m_oLim.GetPointer()); - annotation() += L"} "; } @@ -1136,7 +1036,6 @@ namespace Oox2Odf if (values.colorFlag) { CLOSE_MATH_TAG; - annotation() += L"}"; } } @@ -1170,7 +1069,7 @@ namespace Oox2Odf CREATE_MATH_TAG(L"mtable"); OPEN_MATH_TAG(elm); - annotation() += L"matrix{"; + for (size_t i = 0; i < oox_matrix->m_arrItems.size(); ++i) { if(oox_matrix->m_arrItems[i]->getType() != OOX::EElementType::et_m_mPr) @@ -1179,11 +1078,10 @@ namespace Oox2Odf CLOSE_MATH_TAG; odf_context()->math_context()->matrix_row_counter = 0; - annotation() += L"} "; + if (values.colorFlag) { CLOSE_MATH_TAG; - annotation() += L"}"; } } @@ -1290,18 +1188,14 @@ namespace Oox2Odf OPEN_MATH_TAG(elm); convert(oox_mr->m_arrItems[i]); CLOSE_MATH_TAG; - if( i != oox_mr->m_arrItems.size() - 1) - annotation() += L"# "; } CLOSE_MATH_TAG; matrix_row_counter--; - if(matrix_row_counter > 0) - annotation() += L"## "; + if(color_flag) { CLOSE_MATH_TAG; - annotation() += L"}"; } } @@ -1348,15 +1242,10 @@ namespace Oox2Odf convert(oox_mrun->m_oText.GetPointer()); convert(oox_mrun->m_oYearLong.GetPointer()); convert(oox_mrun->m_oYearShort.GetPointer()); + if (clrFlag) { CLOSE_MATH_TAG; - if(odf_context()->math_context()->annotation_oper_flag) - odf_context()->math_context()->annotation_oper_flag = false; - else - { - annotation() += L"}"; - } } } @@ -1371,10 +1260,13 @@ namespace Oox2Odf odf_context()->settings_context()->start_view(); if (oox_r_pr->m_oSz.IsInit() && oox_r_pr->m_oSz->m_oVal.IsInit()) { - odf_context()->math_context()->size = oox_r_pr->m_oSz->m_oVal->GetValue(); - - odf_context()->settings_context()->add_config_content_item(L"BaseFontHeight", L"short", std::to_wstring(odf_context()->math_context()->size)); - } + odf_context()->math_context()->size = oox_r_pr->m_oSz->m_oVal->GetValue(); + } + else + { + odf_context()->math_context()->size = 12; + } + odf_context()->settings_context()->add_config_content_item(L"BaseFontHeight", L"short", std::to_wstring(odf_context()->math_context()->size)); if (oox_r_pr->m_oRFonts.IsInit() && oox_r_pr->m_oRFonts->m_sAscii.IsInit()) { odf_context()->math_context()->font = *oox_r_pr->m_oRFonts->m_sAscii; @@ -1406,12 +1298,7 @@ namespace Oox2Odf clr2.erase(0, 1); std::vector rgb = hexToIntColor(clr2); boost::to_upper(clr2); - if (odf_context()->math_context()->annotation_oper_flag) - { - annotation() += L" color hex " + clr2 + L" oper "; - } - else - annotation() += L" color hex " + clr2 + L"{" ; + return true; } } @@ -1439,7 +1326,6 @@ namespace Oox2Odf elm->add_text(sub_s_val); OPEN_MATH_TAG(elm); CLOSE_MATH_TAG; - annotation() += XmlUtils::EncodeXmlString(sub_s_val); sub_s_val.clear(); } CREATE_MATH_TAG(L"mtext"); @@ -1448,7 +1334,6 @@ namespace Oox2Odf OPEN_MATH_TAG(elm); CLOSE_MATH_TAG; - annotation() += XmlUtils::EncodeXmlString(std::wstring(1, s_val[i])) + L" "; } else if (w_val <= 57 && w_val >= 48) @@ -1459,7 +1344,6 @@ namespace Oox2Odf elm->add_text(sub_s_val); OPEN_MATH_TAG(elm); CLOSE_MATH_TAG; - annotation() += XmlUtils::EncodeXmlString(sub_s_val) + L" "; sub_s_val.clear(); } @@ -1469,7 +1353,6 @@ namespace Oox2Odf OPEN_MATH_TAG(elm); CLOSE_MATH_TAG; - annotation() += XmlUtils::EncodeXmlString(std::wstring(1, s_val[i])) + L" "; } else if (mo.find(w_val) != mo.end()) { @@ -1479,7 +1362,6 @@ namespace Oox2Odf elm->add_text(sub_s_val); OPEN_MATH_TAG(elm); CLOSE_MATH_TAG; - annotation() += XmlUtils::EncodeXmlString(sub_s_val) + L" "; sub_s_val.clear(); } @@ -1489,7 +1371,6 @@ namespace Oox2Odf OPEN_MATH_TAG(elm); CLOSE_MATH_TAG; - annotation() += XmlUtils::EncodeXmlString(std::wstring(1, s_val[i])) + L" "; } else // { @@ -1502,7 +1383,6 @@ namespace Oox2Odf elm->add_text(sub_s_val); OPEN_MATH_TAG(elm); CLOSE_MATH_TAG; - annotation() += XmlUtils::EncodeXmlString(sub_s_val) + L" "; } } } @@ -1557,22 +1437,16 @@ std::wstring str1, str2; if (!values.narySubHide) { - - annotation() += str1; - //mrow(); convert(oox_nary->m_oSub.GetPointer()); //endOfMrow(); - annotation() += L"}"; } if (!values.narySupHide) { - annotation() += str2; //mrow(); convert(oox_nary->m_oSup.GetPointer()); //endOfMrow(); - annotation() += L"} "; } if (flag_nary) @@ -1588,15 +1462,12 @@ std::wstring str1, str2; else if (tag == L"munder") lvl_down_counter_increace(1); } - annotation() += L" {"; convert(oox_nary->m_oElement.GetPointer()); - annotation() += L"} "; endOfMrow(); if (values.colorFlag) { CLOSE_MATH_TAG; - annotation() += L"}"; } } @@ -1626,6 +1497,7 @@ std::wstring str1, str2; bool OoxConverter::convert(OOX::Logic::CSubHide *oox_subHide) { if (!oox_subHide) return false; + if (!oox_subHide->m_val.IsInit()) return false; bool result = oox_subHide->m_val->ToBool(); return result; @@ -1634,6 +1506,8 @@ std::wstring str1, str2; bool OoxConverter::convert(OOX::Logic::CSupHide *oox_supHide) { if (!oox_supHide) return false; + if (!oox_supHide->m_val.IsInit()) return false; + bool result = oox_supHide->m_val->ToBool(); return result; } @@ -1651,23 +1525,13 @@ std::wstring str1, str2; tmp->stretchy_ = false; } - if (!oox_chr) + if (!oox_chr || (oox_chr && !oox_chr->m_val.IsInit())) { - annotation() += L"int "; elm->add_text(L"∫"); } else { std::wstring val = oox_chr->m_val->GetValue(); - std::map& map = odf_context()->math_context()->annotation_operators; - if (map.count(val)) - { - flag = true; - annotation() += map[val]; - } - else - //annotation_flag() = false; - annotation() += (val + L" "); elm->add_text(val); } OPEN_MATH_TAG(elm); @@ -1714,11 +1578,11 @@ std::wstring str1, str2; { CREATE_MATH_TAG(L"msqrt"); OPEN_MATH_TAG(elm); - annotation() += L"sqrt {"; + mrow(); convert(oox_rad->m_oElement.GetPointer()); endOfMrow(); - annotation() += L"}"; + CLOSE_MATH_TAG; odf_context()->math_context()->symbol_counter++; } @@ -1728,7 +1592,6 @@ std::wstring str1, str2; if (val.colorFlag) { - annotation() += L"}"; CLOSE_MATH_TAG; } @@ -1747,7 +1610,8 @@ std::wstring str1, str2; bool OoxConverter::convert(OOX::Logic::CDegHide *oox_deg_hide) { if (!oox_deg_hide) return false; - + if (!oox_deg_hide->m_val.IsInit()) return false; + return oox_deg_hide->m_val->ToBool(); } @@ -1759,24 +1623,13 @@ std::wstring str1, str2; CREATE_MATH_TAG(L"mroot"); OPEN_MATH_TAG(elm); - size_t iterator = annotation().size(); - convert(oox_elm); - size_t rootSize = annotation().size() - iterator; - std::wstring root(&annotation()[iterator], rootSize); - mrow(); for (size_t i = 0; i < oox_deg->m_arrItems.size(); ++i) convert(oox_deg->m_arrItems[i]); endOfMrow(); - size_t degreeSize = annotation().size() - rootSize - iterator; - std::wstring degree(&annotation()[iterator + rootSize], degreeSize); - - annotation().erase(iterator); - annotation() += L"nroot {" + degree + L"} {" + root + L"}"; - CLOSE_MATH_TAG; } @@ -1790,13 +1643,10 @@ std::wstring str1, str2; OPEN_MATH_TAG(elm); lvl_up_counter_increace(0.4); lvl_down_counter_decreace(0.4); - annotation() += L"{"; mrow(); convert(oox_s_pre->m_oElement.GetPointer()); endOfMrow(); - annotation() += L"} lsub {"; - { CREATE_MATH_TAG(L"mprescripts"); OPEN_MATH_TAG(elm); @@ -1806,20 +1656,15 @@ std::wstring str1, str2; convert(oox_s_pre->m_oSub.GetPointer()); endOfMrow(); - annotation() += L"} lsup {"; - mrow(); convert(oox_s_pre->m_oSup.GetPointer()); endOfMrow(); - - annotation() += L"}"; } CLOSE_MATH_TAG; lvl_up_counter_decreace(0.4); lvl_down_counter_increace(0.4); if (values.colorFlag) { - annotation() += L"}"; CLOSE_MATH_TAG; } } @@ -1840,14 +1685,11 @@ std::wstring str1, str2; CREATE_MATH_TAG(L"msup"); OPEN_MATH_TAG(elm); lvl_up_counter_increace(0.4); - annotation() += L"{"; mrow(); convert(oox_elm); endOfMrow(); - annotation() += L"}^{"; - mrow(); for (size_t i = 0; i < oox_sup->m_arrItems.size(); ++i) { @@ -1855,7 +1697,6 @@ std::wstring str1, str2; } endOfMrow(); - annotation() += L"}"; CLOSE_MATH_TAG; lvl_up_counter_decreace(0.4); } @@ -1867,20 +1708,16 @@ std::wstring str1, str2; CREATE_MATH_TAG(L"msub"); OPEN_MATH_TAG(elm); lvl_down_counter_decreace(0.4); - annotation() += L"{"; mrow(); convert(oox_elm); endOfMrow(); - annotation() += L"}_{"; - for (size_t i = 0; i < oox_sub->m_arrItems.size(); ++i) { convert(oox_sub->m_arrItems[i]); } - annotation() += L"}"; CLOSE_MATH_TAG; lvl_down_counter_increace(0.4); } @@ -1914,7 +1751,6 @@ std::wstring str1, str2; if (values.colorFlag) { CLOSE_MATH_TAG; - annotation() += L"}"; } } @@ -1937,25 +1773,19 @@ std::wstring str1, str2; OPEN_MATH_TAG(elm); lvl_up_counter_increace(0.4); lvl_down_counter_decreace(0.4); - annotation() += L"{"; mrow(); convert(oox_ssub_sup->m_oElement.GetPointer()); endOfMrow(); - annotation() += L"}_{"; - mrow(); convert(oox_ssub_sup->m_oSub.GetPointer()); endOfMrow(); - annotation() += L"}^{"; - mrow(); convert(oox_ssub_sup->m_oSup.GetPointer()); endOfMrow(); - annotation() += L"}"; CLOSE_MATH_TAG; lvl_up_counter_decreace(0.4); lvl_down_counter_increace(0.4); @@ -1963,7 +1793,6 @@ std::wstring str1, str2; if (values.colorFlag) { CLOSE_MATH_TAG; - annotation() += L"}"; } } @@ -1993,7 +1822,6 @@ std::wstring str1, str2; if (values.colorFlag) { CLOSE_MATH_TAG; - annotation() += L"}"; } } @@ -2010,9 +1838,6 @@ std::wstring str1, str2; { if (!oox_elm) return; - if (oox_elm->m_arrItems.empty()) - annotation() += L"\"\""; - resizeBrackets(); if (!brackets()[lvl_of_me()].empty()) diff --git a/OdfFile/Writer/Converter/PptxConverter.cpp b/OdfFile/Writer/Converter/PptxConverter.cpp index 2689c491d91..4bc2d877efe 100644 --- a/OdfFile/Writer/Converter/PptxConverter.cpp +++ b/OdfFile/Writer/Converter/PptxConverter.cpp @@ -40,13 +40,20 @@ #include "../../../OOXML/PPTXFormat/NotesMaster.h" #include "../../../OOXML/PPTXFormat/NotesSlide.h" #include "../../../OOXML/PPTXFormat/TableStyles.h" -#include "../../../OOXML/PPTXFormat/App.h" -#include "../../../OOXML/PPTXFormat/Core.h" #include "../../../OOXML/PPTXFormat/Logic/Table/Table.h" #include "../../../OOXML/PPTXFormat/Logic/Timing/Par.h" #include "../../../OOXML/PPTXFormat/Logic/Timing/Seq.h" #include "../../../OOXML/PPTXFormat/Logic/Timing/CTn.h" +#include "../../../OOXML/PPTXFormat/Logic/Timing/Set.h" +#include "../../../OOXML/PPTXFormat/Logic/Timing/CBhvr.h" +#include "../../../OOXML/PPTXFormat/Logic/Timing/AnimEffect.h" +#include "../../../OOXML/PPTXFormat/Logic/Timing/AnimMotion.h" +#include "../../../OOXML/PPTXFormat/Logic/Timing/AnimClr.h" +#include "../../../OOXML/PPTXFormat/Logic/Timing/AnimRot.h" +#include "../../../OOXML/PPTXFormat/Logic/Timing/AnimScale.h" +#include "../../../OOXML/PPTXFormat/Logic/Timing/Anim.h" +#include "../../../OOXML/PPTXFormat/Logic/Timing/Audio.h" #include "../../../OOXML/PPTXFormat/Logic/Timing/Timing.h" #include "../../../OOXML/PPTXFormat/Logic/TcBdr.h" @@ -69,11 +76,15 @@ #include "../../../OOXML/PPTXFormat/Presentation/SldSz.h" #include "../../../OOXML/PPTXFormat/Presentation/NotesSz.h" +#include "../../../OOXML/DocxFormat/Core.h" +#include "../../../OOXML/DocxFormat/App.h" #include "../Format/odp_conversion_context.h" #include "../Format/odf_text_context.h" #include "../Format/odf_drawing_context.h" +#include "../Format/office_event_listeners.h" +#include "../Format/paragraph_elements.h" #include "../Format/styles.h" #include "../Format/style_presentation.h" @@ -201,11 +212,13 @@ bool PptxConverter::convertDocument() convert_styles(); convert_settings(); - smart_ptr app_ptr = pptx_document->Get(OOX::FileTypes::App).smart_dynamic_cast(); - smart_ptr core_ptr = pptx_document->Get(OOX::FileTypes::Core).smart_dynamic_cast(); + smart_ptr app_ptr = pptx_document->Get(OOX::FileTypes::App).smart_dynamic_cast(); + smart_ptr core_ptr = pptx_document->Get(OOX::FileTypes::Core).smart_dynamic_cast(); - //convert_meta(app_ptr.GetPointer(), core_ptr.GetPointer()); -> привести к OOX::... + convert_meta(app_ptr.GetPointer(), core_ptr.GetPointer()); + convert_customs(pptx_document); + convert_masters_and_layouts(); convert_slides(); //удалим уже ненужный документ pptx @@ -338,6 +351,9 @@ std::wstring PptxConverter::convert(PPTX::Logic::TablePartStyle* style, const st odp_context->drawing_context()->start_line_properties(); convert(style->tcStyle->tcBdr.GetPointer(), style_state->get_paragraph_properties()); odp_context->drawing_context()->end_line_properties(); + + convert(style_state->get_graphic_properties(), style_state->get_table_cell_properties()); + convert(style_state->get_paragraph_properties(), style_state->get_table_cell_properties()); } convert(style->tcTxStyle.GetPointer(), style_state->get_text_properties()); @@ -379,6 +395,830 @@ void PptxConverter::convert(PPTX::Logic::TcTxStyle* style, odf_writer::text_form //nullable fontRef; //UniColor Color; } + +void PptxConverter::convert(const PPTX::Limit::TLNodeType& oox_note_type) +{ + odf_types::presentation_node_type odfNodeType; + + switch (oox_note_type.GetBYTECode()) + { + case 0: + case 1: + odfNodeType = odf_types::presentation_node_type::after_previous; + break; + case 2: + case 3: + odfNodeType = odf_types::presentation_node_type::on_click; + break; + case 4: + odfNodeType = odf_types::presentation_node_type::interactive_sequence; + break; + case 5: + odfNodeType = odf_types::presentation_node_type::main_sequence; + break; + case 6: + odfNodeType = odf_types::presentation_node_type::timing_root; + break; + case 7: + case 8: + odfNodeType = odf_types::presentation_node_type::with_previous; + break; + default: + odfNodeType = odf_types::presentation_node_type::on_click; + } + + odp_context->current_slide().set_anim_type(odfNodeType); +} + +void PptxConverter::convert(const PPTX::Limit::TLPresetClass& oox_preset_class) +{ + odf_types::preset_class odfPresetClass; + + switch (oox_preset_class.GetBYTECode()) + { + case 0: odfPresetClass = odf_types::preset_class::emphasis; break; + case 1: odfPresetClass = odf_types::preset_class::entrance; break; + case 2: odfPresetClass = odf_types::preset_class::exit; break; + case 3: odfPresetClass = odf_types::preset_class::media_call; break; + case 4: odfPresetClass = odf_types::preset_class::motion_path; break; + default: odfPresetClass = odf_types::preset_class::custom; break; + } + + odp_context->current_slide().set_anim_preset_class(odfPresetClass); +} + +void PptxConverter::convert(const PPTX::Limit::TLPresetClass& oox_preset_class, int preset_id) +{ + odf_types::preset_id odfPresetId = preset_id::type::none; + + switch (oox_preset_class.GetBYTECode()) + { + case 0: // "emph" + { + switch (preset_id) + { + case 1: odfPresetId = preset_id::type::ooo_emphasis_fill_color ; break; + case 2: odfPresetId = preset_id::type::ooo_emphasis_font ; break; + case 3: odfPresetId = preset_id::type::ooo_emphasis_font_color ; break; + case 4: odfPresetId = preset_id::type::ooo_emphasis_font_size ; break; + case 5: odfPresetId = preset_id::type::ooo_emphasis_font_style ; break; + case 6: odfPresetId = preset_id::type::ooo_emphasis_grow_and_shrink ; break; + case 7: odfPresetId = preset_id::type::ooo_emphasis_line_color ; break; + case 8: odfPresetId = preset_id::type::ooo_emphasis_spin ; break; + case 9: odfPresetId = preset_id::type::ooo_emphasis_transparency ; break; + case 10: odfPresetId = preset_id::type::ooo_emphasis_bold_flash ; break; + case 14: odfPresetId = preset_id::type::ooo_emphasis_blast ; break; + case 15: odfPresetId = preset_id::type::ooo_emphasis_bold_reveal ; break; + case 16: odfPresetId = preset_id::type::ooo_emphasis_color_over_by_word ; break; + case 18: odfPresetId = preset_id::type::ooo_emphasis_reveal_underline ; break; + case 19: odfPresetId = preset_id::type::ooo_emphasis_color_blend ; break; + case 20: odfPresetId = preset_id::type::ooo_emphasis_color_over_by_letter ; break; + case 21: odfPresetId = preset_id::type::ooo_emphasis_complementary_color ; break; + case 22: odfPresetId = preset_id::type::ooo_emphasis_complementary_color_2 ; break; + case 23: odfPresetId = preset_id::type::ooo_emphasis_contrasting_color ; break; + case 24: odfPresetId = preset_id::type::ooo_emphasis_darken ; break; + case 25: odfPresetId = preset_id::type::ooo_emphasis_desaturate ; break; + case 26: odfPresetId = preset_id::type::ooo_emphasis_flash_bulb ; break; + case 27: odfPresetId = preset_id::type::ooo_emphasis_flicker ; break; + case 28: odfPresetId = preset_id::type::ooo_emphasis_grow_with_color ; break; + case 30: odfPresetId = preset_id::type::ooo_emphasis_lighten ; break; + case 31: odfPresetId = preset_id::type::ooo_emphasis_style_emphasis ; break; + case 32: odfPresetId = preset_id::type::ooo_emphasis_teeter ; break; + case 33: odfPresetId = preset_id::type::ooo_emphasis_vertical_highlight ; break; + case 34: odfPresetId = preset_id::type::ooo_emphasis_wave ; break; + case 35: odfPresetId = preset_id::type::ooo_emphasis_blink ; break; + case 36: odfPresetId = preset_id::type::ooo_emphasis_shimmer ; break; + } + } break; + case 1: // "entrance" + { + switch (preset_id) + { + case 1: odfPresetId = preset_id::type::ooo_entrance_appear ; break; + case 2: odfPresetId = preset_id::type::ooo_entrance_fly_in ; break; + case 3: odfPresetId = preset_id::type::ooo_entrance_venetian_blinds ; break; + case 4: odfPresetId = preset_id::type::ooo_entrance_box ; break; + case 5: odfPresetId = preset_id::type::ooo_entrance_checkerboard ; break; + case 6: odfPresetId = preset_id::type::ooo_entrance_circle ; break; + case 7: odfPresetId = preset_id::type::ooo_entrance_fly_in_slow ; break; + case 8: odfPresetId = preset_id::type::ooo_entrance_diamond ; break; + case 9: odfPresetId = preset_id::type::ooo_entrance_dissolve_in ; break; + case 10: odfPresetId = preset_id::type::ooo_entrance_fade_in ; break; + case 11: odfPresetId = preset_id::type::ooo_entrance_flash_once ; break; + case 12: odfPresetId = preset_id::type::ooo_entrance_peek_in ; break; + case 13: odfPresetId = preset_id::type::ooo_entrance_plus ; break; + case 14: odfPresetId = preset_id::type::ooo_entrance_random_bars ; break; + case 15: odfPresetId = preset_id::type::ooo_entrance_spiral_in ; break; + case 16: odfPresetId = preset_id::type::ooo_entrance_split ; break; + case 17: odfPresetId = preset_id::type::ooo_entrance_stretchy ; break; + case 18: odfPresetId = preset_id::type::ooo_entrance_diagonal_squares; break; + case 19: odfPresetId = preset_id::type::ooo_entrance_swivel ; break; + case 20: odfPresetId = preset_id::type::ooo_entrance_wedge ; break; + case 21: odfPresetId = preset_id::type::ooo_entrance_wheel ; break; + case 22: odfPresetId = preset_id::type::ooo_entrance_wipe ; break; + case 23: odfPresetId = preset_id::type::ooo_entrance_zoom ; break; + case 24: odfPresetId = preset_id::type::ooo_entrance_random ; break; + case 25: odfPresetId = preset_id::type::ooo_entrance_boomerang ; break; + case 26: odfPresetId = preset_id::type::ooo_entrance_bounce ; break; + case 27: odfPresetId = preset_id::type::ooo_entrance_colored_lettering; break; + case 28: odfPresetId = preset_id::type::ooo_entrance_movie_credits ; break; + case 29: odfPresetId = preset_id::type::ooo_entrance_ease_in ; break; + case 30: odfPresetId = preset_id::type::ooo_entrance_float ; break; + case 31: odfPresetId = preset_id::type::ooo_entrance_turn_and_grow ; break; + case 34: odfPresetId = preset_id::type::ooo_entrance_breaks ; break; + case 35: odfPresetId = preset_id::type::ooo_entrance_pinwheel ; break; + case 37: odfPresetId = preset_id::type::ooo_entrance_rise_up ; break; + case 38: odfPresetId = preset_id::type::ooo_entrance_falling_in ; break; + case 39: odfPresetId = preset_id::type::ooo_entrance_thread ; break; + case 40: odfPresetId = preset_id::type::ooo_entrance_unfold ; break; + case 41: odfPresetId = preset_id::type::ooo_entrance_whip ; break; + case 42: odfPresetId = preset_id::type::ooo_entrance_ascend ; break; + case 43: odfPresetId = preset_id::type::ooo_entrance_center_revolve ; break; + case 45: odfPresetId = preset_id::type::ooo_entrance_fade_in_and_swivel; break; + case 47: odfPresetId = preset_id::type::ooo_entrance_descend ; break; + case 48: odfPresetId = preset_id::type::ooo_entrance_sling ; break; + case 49: odfPresetId = preset_id::type::ooo_entrance_spin_in ; break; + case 50: odfPresetId = preset_id::type::ooo_entrance_compress ; break; + case 51: odfPresetId = preset_id::type::ooo_entrance_magnify ; break; + case 52: odfPresetId = preset_id::type::ooo_entrance_curve_up ; break; + case 53: odfPresetId = preset_id::type::ooo_entrance_fade_in_and_zoom; break; + case 54: odfPresetId = preset_id::type::ooo_entrance_glide ; break; + case 55: odfPresetId = preset_id::type::ooo_entrance_expand ; break; + case 56: odfPresetId = preset_id::type::ooo_entrance_flip ; break; + case 58: odfPresetId = preset_id::type::ooo_entrance_fold ; break; + } + } break; + case 2: // "exit" + { + switch (preset_id) + { + case 1: odfPresetId = preset_id::type::ooo_exit_disappear ; break; + case 2: odfPresetId = preset_id::type::ooo_exit_fly_out ; break; + case 3: odfPresetId = preset_id::type::ooo_exit_venetian_blinds ; break; + case 4: odfPresetId = preset_id::type::ooo_exit_box ; break; + case 5: odfPresetId = preset_id::type::ooo_exit_checkerboard ; break; + case 6: odfPresetId = preset_id::type::ooo_exit_circle ; break; + case 7: odfPresetId = preset_id::type::ooo_exit_crawl_out ; break; + case 8: odfPresetId = preset_id::type::ooo_exit_diamond ; break; + case 9: odfPresetId = preset_id::type::ooo_exit_dissolve ; break; + case 10: odfPresetId = preset_id::type::ooo_exit_fade_out ; break; + case 11: odfPresetId = preset_id::type::ooo_exit_flash_once ; break; + case 12: odfPresetId = preset_id::type::ooo_exit_peek_out ; break; + case 13: odfPresetId = preset_id::type::ooo_exit_plus ; break; + case 14: odfPresetId = preset_id::type::ooo_exit_random_bars ; break; + case 15: odfPresetId = preset_id::type::ooo_exit_spiral_out ; break; + case 16: odfPresetId = preset_id::type::ooo_exit_split ; break; + case 17: odfPresetId = preset_id::type::ooo_exit_collapse ; break; + case 18: odfPresetId = preset_id::type::ooo_exit_diagonal_squares ; break; + case 19: odfPresetId = preset_id::type::ooo_exit_swivel ; break; + case 20: odfPresetId = preset_id::type::ooo_exit_wedge ; break; + case 21: odfPresetId = preset_id::type::ooo_exit_wheel ; break; + case 22: odfPresetId = preset_id::type::ooo_exit_wipe ; break; + case 23: odfPresetId = preset_id::type::ooo_exit_zoom ; break; + case 24: odfPresetId = preset_id::type::ooo_exit_random ; break; + case 25: odfPresetId = preset_id::type::ooo_exit_boomerang ; break; + case 26: odfPresetId = preset_id::type::ooo_exit_bounce ; break; + case 27: odfPresetId = preset_id::type::ooo_exit_colored_lettering ; break; + case 28: odfPresetId = preset_id::type::ooo_exit_movie_credits ; break; + case 29: odfPresetId = preset_id::type::ooo_exit_ease_out ; break; + case 30: odfPresetId = preset_id::type::ooo_exit_float ; break; + case 31: odfPresetId = preset_id::type::ooo_exit_turn_and_grow ; break; + case 34: odfPresetId = preset_id::type::ooo_exit_breaks ; break; + case 35: odfPresetId = preset_id::type::ooo_exit_pinwheel ; break; + case 37: odfPresetId = preset_id::type::ooo_exit_sink_down ; break; + case 38: odfPresetId = preset_id::type::ooo_exit_swish ; break; + case 39: odfPresetId = preset_id::type::ooo_exit_thread ; break; + case 40: odfPresetId = preset_id::type::ooo_exit_unfold ; break; + case 41: odfPresetId = preset_id::type::ooo_exit_whip ; break; + case 42: odfPresetId = preset_id::type::ooo_exit_descend ; break; + case 43: odfPresetId = preset_id::type::ooo_exit_center_revolve ; break; + case 45: odfPresetId = preset_id::type::ooo_exit_fade_out_and_swivel; break; + case 47: odfPresetId = preset_id::type::ooo_exit_ascend ; break; + case 48: odfPresetId = preset_id::type::ooo_exit_sling ; break; + case 53: odfPresetId = preset_id::type::ooo_exit_fade_out_and_zoom ; break; + case 55: odfPresetId = preset_id::type::ooo_exit_contract ; break; + case 49: odfPresetId = preset_id::type::ooo_exit_spin_out ; break; + case 50: odfPresetId = preset_id::type::ooo_exit_stretchy ; break; + case 51: odfPresetId = preset_id::type::ooo_exit_magnify ; break; + case 52: odfPresetId = preset_id::type::ooo_exit_curve_down ; break; + case 54: odfPresetId = preset_id::type::ooo_exit_glide ; break; + case 56: odfPresetId = preset_id::type::ooo_exit_flip ; break; + case 58: odfPresetId = preset_id::type::ooo_exit_fold ; break; + } + } break; + case 4: // motion-path + { + switch (preset_id) + { + case 16: odfPresetId = preset_id::type::ooo_motionpath_4_point_star ; break; + case 5: odfPresetId = preset_id::type::ooo_motionpath_5_point_star ; break; + case 11: odfPresetId = preset_id::type::ooo_motionpath_6_point_star ; break; + case 17: odfPresetId = preset_id::type::ooo_motionpath_8_point_star ; break; + case 1: odfPresetId = preset_id::type::ooo_motionpath_circle ; break; + case 6: odfPresetId = preset_id::type::ooo_motionpath_crescent_moon ; break; + case 3: odfPresetId = preset_id::type::ooo_motionpath_diamond ; break; + case 13: odfPresetId = preset_id::type::ooo_motionpath_equal_triangle ; break; + case 12: odfPresetId = preset_id::type::ooo_motionpath_oval ; break; + case 9: odfPresetId = preset_id::type::ooo_motionpath_heart ; break; + case 4: odfPresetId = preset_id::type::ooo_motionpath_hexagon ; break; + case 10: odfPresetId = preset_id::type::ooo_motionpath_octagon ; break; + case 14: odfPresetId = preset_id::type::ooo_motionpath_parallelogram ; break; + case 15: odfPresetId = preset_id::type::ooo_motionpath_pentagon ; break; + case 2: odfPresetId = preset_id::type::ooo_motionpath_right_triangle ; break; + case 7: odfPresetId = preset_id::type::ooo_motionpath_square ; break; + case 18: odfPresetId = preset_id::type::ooo_motionpath_teardrop ; break; + case 8: odfPresetId = preset_id::type::ooo_motionpath_trapezoid ; break; + case 37: odfPresetId = preset_id::type::ooo_motionpath_arc_down ; break; + case 51: odfPresetId = preset_id::type::ooo_motionpath_arc_left ; break; + case 58: odfPresetId = preset_id::type::ooo_motionpath_arc_right ; break; + case 44: odfPresetId = preset_id::type::ooo_motionpath_arc_up ; break; + case 41: odfPresetId = preset_id::type::ooo_motionpath_bounce_left ; break; + case 54: odfPresetId = preset_id::type::ooo_motionpath_bounce_right ; break; + case 48: odfPresetId = preset_id::type::ooo_motionpath_curvy_left ; break; + case 61: odfPresetId = preset_id::type::ooo_motionpath_curvy_right ; break; + case 60: odfPresetId = preset_id::type::ooo_motionpath_decaying_wave ; break; + case 49: odfPresetId = preset_id::type::ooo_motionpath_diagonal_down_right; break; + case 56: odfPresetId = preset_id::type::ooo_motionpath_diagonal_up_right ; break; + case 42: odfPresetId = preset_id::type::ooo_motionpath_down ; break; + case 52: odfPresetId = preset_id::type::ooo_motionpath_funnel ; break; + case 53: odfPresetId = preset_id::type::ooo_motionpath_spring ; break; + case 62: odfPresetId = preset_id::type::ooo_motionpath_stairs_down ; break; + case 50: odfPresetId = preset_id::type::ooo_motionpath_turn_down ; break; + case 36: odfPresetId = preset_id::type::ooo_motionpath_turn_down_right ; break; + case 43: odfPresetId = preset_id::type::ooo_motionpath_turn_up ; break; + case 57: odfPresetId = preset_id::type::ooo_motionpath_turn_up_right ; break; + case 64: odfPresetId = preset_id::type::ooo_motionpath_up ; break; + case 47: odfPresetId = preset_id::type::ooo_motionpath_wave ; break; + case 38: odfPresetId = preset_id::type::ooo_motionpath_zigzag ; break; + case 31: odfPresetId = preset_id::type::ooo_motionpath_bean ; break; + case 25: odfPresetId = preset_id::type::ooo_motionpath_buzz_saw ; break; + case 20: odfPresetId = preset_id::type::ooo_motionpath_curved_square ; break; + case 21: odfPresetId = preset_id::type::ooo_motionpath_curved_x ; break; + case 23: odfPresetId = preset_id::type::ooo_motionpath_curvy_star ; break; + case 28: odfPresetId = preset_id::type::ooo_motionpath_figure_8_four ; break; + case 26: odfPresetId = preset_id::type::ooo_motionpath_horizontal_figure_8; break; + case 34: odfPresetId = preset_id::type::ooo_motionpath_inverted_square ; break; + case 33: odfPresetId = preset_id::type::ooo_motionpath_inverted_triangle ; break; + case 24: odfPresetId = preset_id::type::ooo_motionpath_loop_de_loop ; break; + case 29: odfPresetId = preset_id::type::ooo_motionpath_neutron ; break; + case 27: odfPresetId = preset_id::type::ooo_motionpath_peanut ; break; + case 32: odfPresetId = preset_id::type::ooo_motionpath_clover ; break; + case 19: odfPresetId = preset_id::type::ooo_motionpath_pointy_star ; break; + case 30: odfPresetId = preset_id::type::ooo_motionpath_swoosh ; break; + case 22: odfPresetId = preset_id::type::ooo_motionpath_vertical_figure_8 ; break; + case 35: odfPresetId = preset_id::type::ooo_motionpath_left ; break; + case 63: odfPresetId = preset_id::type::ooo_motionpath_right ; break; + case 55: odfPresetId = preset_id::type::ooo_motionpath_spiral_left ; break; + case 46: odfPresetId = preset_id::type::ooo_motionpath_spiral_right ; break; + case 40: odfPresetId = preset_id::type::ooo_motionpath_sine_wave ; break; + case 59: odfPresetId = preset_id::type::ooo_motionpath_s_curve_1 ; break; + case 39: odfPresetId = preset_id::type::ooo_motionpath_s_curve_2 ; break; + case 45: odfPresetId = preset_id::type::ooo_motionpath_heartbeat ; break; + default: odfPresetId = preset_id::type::libo_motionpath_curve ; break; + } + } break; + } + + if(odfPresetId.get_type() != preset_id::type::none) + odp_context->current_slide().set_anim_preset_id(odfPresetId); + else + odp_context->current_slide().set_anim_preset_id(odfPresetId); +} + +void PptxConverter::convert(PPTX::Logic::CBhvr* oox_cbhvr) +{ + if (!oox_cbhvr) + return; + + convert(&oox_cbhvr->cTn); + convert(&oox_cbhvr->tgtEl); + + if (oox_cbhvr->attrNameLst.IsInit()) + { + if (oox_cbhvr->attrNameLst->list.size() == 1) + { + convert(&oox_cbhvr->attrNameLst->list[0]); + } + else + _CP_LOG << L"[warning] : multiple attribute list elements not supported\n"; + } + +} + +void PptxConverter::convert(PPTX::Logic::TgtEl* oox_tgt_el) +{ + if (!oox_tgt_el) + return; + + if (oox_tgt_el->spTgt.IsInit()) + { + const std::wstring& odfId = odp_context->get_mapped_identifier(oox_tgt_el->spTgt->spid); + + if(!odfId.empty()) + odp_context->current_slide().set_anim_target_element(odfId); + } +} + +void PptxConverter::convert(PPTX::Logic::AnimVariant* oox_anim_variant) +{ + if (!oox_anim_variant) + return; + + std::wstring val; + + if (oox_anim_variant->boolVal.IsInit()) + val = std::to_wstring(*oox_anim_variant->boolVal); + else if (oox_anim_variant->strVal.IsInit()) + val = *oox_anim_variant->strVal; + else if (oox_anim_variant->intVal.IsInit()) + val = std::to_wstring(*oox_anim_variant->intVal); + else if (oox_anim_variant->fltVal.IsInit()) + val = std::to_wstring(*oox_anim_variant->fltVal); + + odp_context->current_slide().set_anim_to(val); +} + +void PptxConverter::convert(PPTX::Logic::AttrName* oox_attr_name) +{ + if (!oox_attr_name) + return; + + smil_attribute_name attrName = smil_attribute_name::none; + const std::wstring& val = oox_attr_name->text; + + if (val == L"style.color") + attrName = smil_attribute_name::color; + else if(val == L"stroke.color") + attrName = smil_attribute_name::strokeColor; + else if (val == L"fill.type") + attrName = smil_attribute_name::fill; + else if (val == L"fillcolor") + attrName = smil_attribute_name::fillColor; + else if (val == L"fill.on") + attrName = smil_attribute_name::fillOn; + else if (val == L"style.opacity") + attrName = smil_attribute_name::opacity; + else if (val == L"stroke.on") + attrName = smil_attribute_name::stroke; + else if (val == L"r" || val == L"style.rotation") + attrName = smil_attribute_name::rotate; + else if (val == L"xshear") + attrName = smil_attribute_name::skewX; + else if (val == L"style.visibility") + attrName = smil_attribute_name::visibility; + else if (val == L"ppt_x") + attrName = smil_attribute_name::x; + else if (val == L"ppt_y") + attrName = smil_attribute_name::y; + else if (val == L"ppt_w") + attrName = smil_attribute_name::width; + else if (val == L"ppt_h") + attrName = smil_attribute_name::height; + else if (val == L"ppt_c") + attrName = smil_attribute_name::dim; + + odp_context->current_slide().set_anim_attribute_name(attrName); +} + +void PptxConverter::convert(PPTX::Logic::AnimEffect* oox_anim_effect) +{ + if (!oox_anim_effect) + return; + + odp_context->current_slide().start_timing_transition_filter(); + + if (oox_anim_effect->transition.IsInit()) + { + odp_context->current_slide().set_anim_transition_filter_mode(oox_anim_effect->transition->get()); + } + if (oox_anim_effect->filter.IsInit()) + { + std::wstring filter = *oox_anim_effect->filter; + std::wstring subtype = L""; + + _CP_OPT(smil_transition_type) odfType = boost::none; + std::wstring odfSubtype = L""; + bool odfReversed = false; + + std::string::size_type openBracket = filter.find('('); + std::string::size_type closeBracket = filter.find(')'); + + if (openBracket != std::wstring::npos && + closeBracket != std::wstring::npos) + { + filter = oox_anim_effect->filter->substr(0, openBracket); + subtype = oox_anim_effect->filter->substr(openBracket + 1, closeBracket - openBracket - 1); + } + + std::transform(filter.begin(), filter.end(), filter.begin(), ::towlower); + if (filter == L"blinds") + { + odfType = smil_transition_type::blindsWipe; + odfReversed = false; + if (subtype == L"horizontal") odfSubtype = L"horizontal"; + else if (subtype == L"vertical") odfSubtype = L"vertical"; + } + else if (filter == L"box") + { + odfType = smil_transition_type::irisWipe; + odfSubtype = L"rectangle"; + if (subtype == L"in") odfReversed = true; + else if (subtype == L"out") odfReversed = false; + } + else if (filter == L"checkerboard") + { + odfType = smil_transition_type::checkerBoardWipe; + odfReversed = false; + if (subtype == L"across") odfSubtype = L"across"; + else if (subtype == L"down") odfSubtype = L"down"; + } + else if (filter == L"circle") + { + odfType = smil_transition_type::ellipseWipe; + odfSubtype = L"horizontal"; + if (subtype == L"in") odfReversed = true; + else if (subtype == L"out") odfReversed = false; + } + else if (filter == L"diamond") + { + odfType = smil_transition_type::irisWipe; + odfSubtype = L"diamond"; + if (subtype == L"in") odfReversed = true; + else if (subtype == L"out") odfReversed = false; + } + else if (filter == L"dissolve") + { + odfType = smil_transition_type::dissolve; + odfSubtype = L""; + odfReversed = false; + } + else if (filter == L"fade") + { + odfType = smil_transition_type::fade; + odfSubtype = L"crossfade"; + odfReversed = false; + } + else if (filter == L"slide") + { + odfType = smil_transition_type::slideWipe; + odfReversed = false; + odfSubtype = subtype; + } + else if (filter == L"plus") + { + odfType = smil_transition_type::fourBoxWipe; + odfSubtype = L"cornersIn"; + if (subtype == L"in") odfReversed = false; + else if (subtype == L"out") odfReversed = true; + } + else if (filter == L"barn") + { + odfType = smil_transition_type::barnDoorWipe; + if (subtype == L"inVertical") { odfReversed = true; odfSubtype = L"vertical"; } + else if (subtype == L"inHorizontal") { odfReversed = true; odfSubtype = L"horizontal"; } + else if (subtype == L"outVertical") { odfReversed = false; odfSubtype = L"vertical"; } + else if (subtype == L"outHorizontal") { odfReversed = false; odfSubtype = L"horizontal"; } + } + else if (boost::starts_with(filter, L"randombar")) + { + odfType = smil_transition_type::randomBarWipe; + odfReversed = false; + odfSubtype = subtype; + } + else if (filter == L"strips") + { + odfType = smil_transition_type::waterfallWipe; + if (subtype == L"downLeft") { odfReversed = false; odfSubtype = L"horizontalRight"; } + else if (subtype == L"upLeft") { odfReversed = true; odfSubtype = L"horizontalLeft"; } + else if (subtype == L"downRight") { odfReversed = false; odfSubtype = L"horizontalLeft"; } + else if (subtype == L"upRight") { odfReversed = true; odfSubtype = L"horizontalRight"; } + } + else if (filter == L"wedge") + { + odfType = smil_transition_type::fanWipe; + odfReversed = false; + odfSubtype = L"centerTop"; + } + else if (filter == L"wheel") + { + odfType = smil_transition_type::pinWheelWipe; + odfReversed = false; + if (subtype == L"1") odfSubtype = L"oneBlade"; + else if (subtype == L"2") odfSubtype = L"twoBladeVertical"; + else if (subtype == L"3") odfSubtype = L"threeBlade"; + else if (subtype == L"4") odfSubtype = L"fourBlade"; + else if (subtype == L"8") odfSubtype = L"eightBlade"; + } + else if (filter == L"wipe") + { + odfType = smil_transition_type::slideWipe; + if (subtype == L"right") { odfReversed = true; odfSubtype = L"fromRight"; } + else if (subtype == L"left") { odfReversed = false; odfSubtype = L"fromLeft"; } + else if (subtype == L"down") { odfReversed = true; odfSubtype = L"fromBottom"; } + else if (subtype == L"up") { odfReversed = false; odfSubtype = L"fromTop"; } + } + else if (filter == L"image") + { + odfType = boost::none; + } + else + { + odfType = smil_transition_type::fade; + odfReversed = false; + } + + if(odfType) + odp_context->current_slide().set_anim_transition_filter_type(odfType.value()); + + if(!odfSubtype.empty()) + odp_context->current_slide().set_anim_transition_filter_subtype(odfSubtype); + if(odfReversed) + odp_context->current_slide().set_anim_transition_filter_direction(L"reverse"); + } + + convert(&oox_anim_effect->cBhvr); + + odp_context->current_slide().end_timing_transition_filter(); +} + +void PptxConverter::convert(PPTX::Logic::Anim* oox_anim) +{ + if (!oox_anim) + return; + + odp_context->current_slide().start_timing_anim(); + + convert(&oox_anim->cBhvr); + + if (oox_anim->tavLst.IsInit()) + { + std::wstringstream ss_tm; + std::wstringstream ss_val; + + for (size_t i = 0; i < oox_anim->tavLst->list.size(); i++) + { + if (i > 0) + ss_tm << L";"; + + if (oox_anim->tavLst->list[i].tm.IsInit()) + ss_tm << boost::lexical_cast(*oox_anim->tavLst->list[i].tm) / 100000.0; + else + ss_tm << 0; + + if (oox_anim->tavLst->list[i].val.IsInit()) + { + if (i > 0) + ss_val << L";"; + + if(oox_anim->tavLst->list[i].val->boolVal.IsInit()) + ss_val << *oox_anim->tavLst->list[i].val->boolVal; + else if (oox_anim->tavLst->list[i].val->intVal.IsInit()) + ss_val << *oox_anim->tavLst->list[i].val->intVal; + else if (oox_anim->tavLst->list[i].val->fltVal.IsInit()) + ss_val << *oox_anim->tavLst->list[i].val->fltVal; + else if (oox_anim->tavLst->list[i].val->strVal.IsInit()) + ss_val << *oox_anim->tavLst->list[i].val->strVal; + } + } + + if (oox_anim->tavLst->list.size() > 1) + { + if (oox_anim->tavLst->list[0].fmla.IsInit()) + { + std::wstring formula = convert_animation_formula(*oox_anim->tavLst->list[0].fmla); + odp_context->current_slide().set_anim_animation_formula(formula); + } + } + + odp_context->current_slide().set_anim_animation_keytimes(odf_types::smil_key_times::parse(convert_animation_formula(ss_tm.str()))); + odp_context->current_slide().set_anim_animation_values(odf_types::smil_values::parse(convert_animation_formula(ss_val.str()))); + } + + if (oox_anim->by.IsInit()) + { + std::wstring by = convert_animation_formula(*oox_anim->by); + odp_context->current_slide().set_anim_animation_by(by); + } + if (oox_anim->from.IsInit()) + { + std::wstring from = convert_animation_formula(*oox_anim->from); + odp_context->current_slide().set_anim_animation_from(from); + } + if (oox_anim->to.IsInit()) + { + std::wstring to = convert_animation_formula(*oox_anim->to); + odp_context->current_slide().set_anim_animation_to(to); + } + + odp_context->current_slide().end_timing_anim(); +} + +void PptxConverter::convert(PPTX::Logic::AnimMotion* oox_anim_motion) +{ + if (!oox_anim_motion) + return; + + odp_context->current_slide().start_timing_motion(); + odp_context->current_slide().set_anim_attribute_name(odf_types::smil_attribute_name::x); + + convert(&oox_anim_motion->cBhvr); + + if (oox_anim_motion->path.IsInit()) + odp_context->current_slide().set_anim_motion_path(*oox_anim_motion->path); + + // TODO: Convert "from", "to", "by" + // TODO: Convert "rCtr" + + odp_context->current_slide().end_timing_motion(); +} + +void PptxConverter::convert(PPTX::Logic::AnimClr* oox_anim_color) +{ + if (!oox_anim_color) + return; + + odp_context->current_slide().start_timing_anim_clr(); + + convert(&oox_anim_color->cBhvr); + + if (oox_anim_color->to.is_init()) + { + std::wstringstream ss; + ss << L"#" << std::hex << (oox_anim_color->to.GetRGBA() >> 8); + + odp_context->current_slide().set_anim_color_to(ss.str()); + } + + if (oox_anim_color->clrSpc.IsInit()) + { + odp_context->current_slide().set_anim_color_interpolation(oox_anim_color->clrSpc->get()); + } + + if (oox_anim_color->dir.IsInit()) + { + if(oox_anim_color->dir->get() == L"cw") + odp_context->current_slide().set_anim_color_direction(L"clockwise"); + else if (oox_anim_color->dir->get() == L"ccw") + odp_context->current_slide().set_anim_color_direction(L"counter-clockwise"); + } + + if (oox_anim_color->byR.IsInit() || + oox_anim_color->byG.IsInit() || + oox_anim_color->byB.IsInit()) + { + const int r = oox_anim_color->byR.get_value_or(0); + const int g = oox_anim_color->byG.get_value_or(0); + const int b = oox_anim_color->byB.get_value_or(0); + const float multiplyer = 1000.0f; + + std::wstringstream ss; + ss << L"#" + << std::setfill(L'0') + << std::setw(2) + << std::hex + << ((int)(r / multiplyer) & 0xff) + << ((int)(g / multiplyer) & 0xff) + << ((int)(b / multiplyer) & 0xff); + + odp_context->current_slide().set_anim_color_by(ss.str()); + } + else if (oox_anim_color->byH.IsInit() || + oox_anim_color->byS.IsInit() || + oox_anim_color->byL.IsInit()) + { + const int h = oox_anim_color->byH.get_value_or(0); + const int s = oox_anim_color->byS.get_value_or(0); + const int l = oox_anim_color->byL.get_value_or(0); + + std::wstringstream ss; + ss << L"hsl(" + << (h / 100000) << L"," + << (s / 1000 ) << L"%," + << (l / 1000 ) << L"%)"; + odp_context->current_slide().set_anim_color_by(ss.str()); + } + + odp_context->current_slide().end_timing_anim_clr(); +} + +void PptxConverter::convert(PPTX::Logic::AnimRot* oox_anim_rot) +{ + if (!oox_anim_rot) + return; + + odp_context->current_slide().start_timing_anim(); + odp_context->current_slide().set_anim_animation_type(odf_types::svg_type::rotate); + + convert(&oox_anim_rot->cBhvr); + + const double odp_mulipyer = 60000.0; + if (oox_anim_rot->from.IsInit()) + { + odp_context->current_slide().set_anim_animation_from(std::to_wstring(*oox_anim_rot->from / odp_mulipyer)); + } + if (oox_anim_rot->to.IsInit()) + { + odp_context->current_slide().set_anim_animation_to(std::to_wstring(*oox_anim_rot->to / odp_mulipyer)); + } + if (oox_anim_rot->by.IsInit()) + { + odp_context->current_slide().set_anim_animation_by(std::to_wstring(*oox_anim_rot->by / odp_mulipyer)); + } + + odp_context->current_slide().end_timing_anim(); +} + +void PptxConverter::convert(PPTX::Logic::AnimScale* oox_anim_scale) +{ + if (!oox_anim_scale) + return; + + odp_context->current_slide().start_timing_transform(); + odp_context->current_slide().set_anim_transform_type(odf_types::svg_type::scale); + odp_context->current_slide().set_anim_attribute_name(odf_types::smil_attribute_name::transform); + + convert(&oox_anim_scale->cBhvr); + + if (oox_anim_scale->fromX.IsInit() && oox_anim_scale->fromY.IsInit()) + { + std::wstring from = convert_animation_scale_values(*oox_anim_scale->fromX, *oox_anim_scale->fromY); + odp_context->current_slide().set_anim_transform_from(from); + } + + if (oox_anim_scale->toX.IsInit() && oox_anim_scale->toY.IsInit()) + { + std::wstring to = convert_animation_scale_values(*oox_anim_scale->toX, *oox_anim_scale->toY); + odp_context->current_slide().set_anim_transform_to(to); + } + + if (oox_anim_scale->byX.IsInit() && oox_anim_scale->byY.IsInit()) + { + const int pptx_multiplyer = 100000; + std::wstring by = convert_animation_scale_values(*oox_anim_scale->byX - pptx_multiplyer, *oox_anim_scale->byY - pptx_multiplyer); + odp_context->current_slide().set_anim_transform_by(by); + } + + odp_context->current_slide().end_timing_transform(); +} + +void PptxConverter::convert(PPTX::Logic::Audio* oox_audio) +{ + if (!oox_audio) + return; + + odp_context->current_slide().start_anim_audio(); + + if (oox_audio->cMediaNode.tgtEl.name.IsInit()) + { + bool isExternal; + const std::wstring aID = oox_audio->cMediaNode.tgtEl.embed->get(); + const std::wstring pathAudio = find_link_by_id(aID, 3, isExternal); + + const std::wstring xlink = odp_context->add_media(pathAudio); + + odp_context->current_slide().set_anim_audio_xlink(xlink); + } + + odp_context->current_slide().end_anim_audio(); +} + +void PptxConverter::convert(odf_writer::graphic_format_properties* graphic_props, odf_writer::style_table_cell_properties* table_cell_props) +{ + if (!graphic_props) + return; + if (!table_cell_props) + return; + + using namespace odf_types; + + if(graphic_props->common_draw_fill_attlist_.draw_fill_color_) + table_cell_props->content_.common_background_color_attlist_.fo_background_color_ = background_color(*graphic_props->common_draw_fill_attlist_.draw_fill_color_); + + odf_types::color color_ = graphic_props->svg_stroke_color_.get_value_or(odf_types::color(L"#FFFFFF")); + // odf_types::draw_fill draw_fill_ = graphic_props->common_draw_fill_attlist_.draw_fill_.get_value_or(draw_fill(draw_fill::solid)); + odf_types::length length_ = graphic_props->svg_stroke_width_.get_value_or(length(1, length::pt)).get_length(); + + table_cell_props->content_.common_border_attlist_.fo_border_bottom_ = odf_types::border_style(color_, border_style::solid, length_); +} + +void PptxConverter::convert(odf_writer::paragraph_format_properties* paragraph_props, odf_writer::style_table_cell_properties* table_cell_props) +{ + if (!paragraph_props) + return; + if (!table_cell_props) + return; + + if (paragraph_props->common_border_attlist_.fo_border_) + { + table_cell_props->content_.common_border_attlist_.fo_border_left_ = *paragraph_props->common_border_attlist_.fo_border_; + table_cell_props->content_.common_border_attlist_.fo_border_top_ = *paragraph_props->common_border_attlist_.fo_border_; + table_cell_props->content_.common_border_attlist_.fo_border_right_ = *paragraph_props->common_border_attlist_.fo_border_; + table_cell_props->content_.common_border_attlist_.fo_border_bottom_ = *paragraph_props->common_border_attlist_.fo_border_; + } + else + table_cell_props->content_.common_border_attlist_ = paragraph_props->common_border_attlist_; +} + void PptxConverter::convert_common() { if (presentation->sldSz.IsInit()) @@ -398,6 +1238,123 @@ void PptxConverter::convert_common() } } +std::wstring PptxConverter::convert_animation_formula(std::wstring formula) +{ + boost::erase_all(formula, L"#"); + boost::replace_all(formula, L"ppt_x", L"x"); + boost::replace_all(formula, L"ppt_y", L"y"); + boost::replace_all(formula, L"ppt_w", L"width"); + boost::replace_all(formula, L"ppt_h", L"height"); + + return formula; +} + +std::wstring PptxConverter::convert_animation_scale_values(int x, int y) +{ + std::wstringstream ss; + ss.setf(std::ios::fixed); + ss.precision(2); + const double odp_multipyer = 100000; + double _x = x / odp_multipyer; + double _y = y / odp_multipyer; + ss << _x << L"," << _y; + + return ss.str(); +} + +std::wstring PptxConverter::get_page_name(PPTX::Logic::CSld* oox_slide, _typePages type) +{ + if (!oox_slide) + return std::wstring(); + + std::wstring page_name; + if (oox_slide->attrName.IsInit()) + page_name = oox_slide->attrName.get(); + + if (page_name.empty()) + { + if (type == Slide) + page_name = L"Slide_" + std::to_wstring((int)odp_context->get_pages_count()); + } + + return page_name; +} + +void PptxConverter::fill_in_deferred_hyperlinks() +{ + auto links = odp_context->get_deferred_hyperlinks(); + auto slidenames_vec = std::vector>(odp_context->map_slidenames_.begin(), odp_context->map_slidenames_.end()); + + for (size_t i = 0; i < links.size(); i++) + { + const auto& hyperlink = links[i]; + + cpdoccore::odf_writer::presentation_event_listener* event_listener = dynamic_cast(hyperlink.first.get()); + cpdoccore::odf_writer::text_a* text = dynamic_cast(hyperlink.first.get()); + const std::wstring& slidename = hyperlink.second; + + std::wstring href; + auto hrefIt = odp_context->map_slidenames_.find(slidename); + if (slidename == L"previous-page" && i > 0) + href = slidenames_vec[i - 1].second; + else if (slidename == L"next-page" && i < slidenames_vec.size() - 2) + href = slidenames_vec[i + 1].second; + else if (slidename == L"first-page") + href = slidenames_vec[0].second; + else if (slidename == L"last-page") + href = slidenames_vec[slidenames_vec.size() - 1].second; + else if (hrefIt == odp_context->map_slidenames_.end()) + continue; + else + href = hrefIt->second; + + if (event_listener) + { + event_listener->attlist_.common_xlink_attlist_.href_ = std::wstring(L"#") + href; + event_listener->attlist_.common_xlink_attlist_.type_ = xlink_type::Simple; + event_listener->attlist_.common_xlink_attlist_.show_ = xlink_show::Embed; + event_listener->attlist_.common_xlink_attlist_.actuate_ = xlink_actuate::OnRequest; + } + else if (text) + { + text->common_xlink_attlist_.href_ = std::wstring(L"#") + href; + text->common_xlink_attlist_.type_ = xlink_type::Simple; + } + } +} + + +void PptxConverter::convert_masters_and_layouts() +{ + for (size_t iMaster = 0; iMaster < presentation->sldMasterIdLst.size(); ++iMaster) + { + smart_ptr slideMaster = ((*presentation)[presentation->sldMasterIdLst[iMaster].rid.get()]).smart_dynamic_cast(); + + if (slideMaster.IsInit() == false) + continue; + + for (size_t iLayout = 0; iLayout < slideMaster->sldLayoutIdLst.size(); ++iLayout) + { + std::wstring rId = slideMaster->sldLayoutIdLst[iLayout].rid.get(); + smart_ptr slideLayout = ((*slideMaster)[rId]).smart_dynamic_cast(); + + if (false == slideLayout.IsInit()) continue; + + std::map::iterator pFind = m_mapLayouts.find(slideLayout->m_sOutputFilename); + if (pFind == m_mapLayouts.end()) + { + odp_context->start_layout_slide(); + convert_layout(&slideLayout->cSld); + odp_context->end_layout_slide(); + + std::wstring layout_style_name = odp_context->page_layout_context()->get_local_styles_context()->last_state(odf_types::style_family::PresentationPageLayout)->get_name(); + + m_mapLayouts.insert(std::make_pair(slideLayout->m_sOutputFilename, layout_style_name)); + } + } + } +} + void PptxConverter::convert_slides() { for (size_t i = 0; i < presentation->sldIdLst.size(); ++i) @@ -486,7 +1443,7 @@ void PptxConverter::convert_slides() } pFind = m_mapLayouts.find(slide->Layout->m_sOutputFilename); if (pFind == m_mapLayouts.end()) - { + {//сюда уже не попадет - выше odp_context->start_layout_slide(); convert_layout(&slide->Layout->cSld); odp_context->end_layout_slide(); @@ -512,17 +1469,23 @@ void PptxConverter::convert_slides() odp_context->current_slide().set_master_page (master_style_name); odp_context->current_slide().set_layout_page (layout_style_name); - + + odp_context->add_page_name(get_page_name(slide->cSld.GetPointer(), Slide)); convert_slide (slide->cSld.GetPointer(), current_txStyles, true, bShowMasterSp, Slide); + convert (slide->timing.GetPointer()); convert (slide->comments.GetPointer()); convert (slide->Note.GetPointer()); convert (slide->transition.GetPointer()); - //convert (slide->timing.GetPointer()); + + if (!bShow) + odp_context->hide_slide(); odp_context->end_slide(); } + + fill_in_deferred_hyperlinks(); } void PptxConverter::convert(PPTX::NotesMaster *oox_notes) { @@ -735,6 +1698,46 @@ void PptxConverter::convert(PPTX::Logic::TimeNodeBase *oox_time_base) convert(&seq.cTn); odp_context->current_slide().end_timing_seq(); } + else if (oox_time_base->is()) + { + PPTX::Logic::Set& set = oox_time_base->as(); + convert(&set); + } + else if (oox_time_base->is()) + { + PPTX::Logic::AnimEffect& animEffect = oox_time_base->as(); + convert(&animEffect); + } + else if (oox_time_base->is()) + { + PPTX::Logic::Anim& animate = oox_time_base->as(); + convert(&animate); + } + else if (oox_time_base->is()) + { + PPTX::Logic::AnimMotion& motion = oox_time_base->as(); + convert(&motion); + } + else if (oox_time_base->is()) + { + PPTX::Logic::AnimClr& color = oox_time_base->as(); + convert(&color); + } + else if (oox_time_base->is()) + { + PPTX::Logic::AnimRot& rotate = oox_time_base->as(); + convert(&rotate); + } + else if (oox_time_base->is()) + { + PPTX::Logic::AnimScale& rotate = oox_time_base->as(); + convert(&rotate); + } + else if (oox_time_base->is()) + { + PPTX::Logic::Audio& audio = oox_time_base->as(); + convert(&audio); + } } void PptxConverter::convert(PPTX::Logic::EmptyTransition *oox_transition) { @@ -828,22 +1831,35 @@ void PptxConverter::convert(PPTX::Logic::EightDirectionTransition *oox_transitio if (!oox_transition) return; if (oox_transition->name == L"cover") - odp_context->current_slide().set_transition_type(1); + odp_context->current_slide().set_transition_type(35); if (oox_transition->name == L"pull") odp_context->current_slide().set_transition_type(35); - if (oox_transition->dir.IsInit()) - { - if (oox_transition->dir->get() == L"d") odp_context->current_slide().set_transition_subtype(L"fromTop"); - else if (oox_transition->dir->get() == L"l") odp_context->current_slide().set_transition_subtype(L"fromRight"); - else if (oox_transition->dir->get() == L"r") odp_context->current_slide().set_transition_subtype(L"fromLeft"); - else if (oox_transition->dir->get() == L"u") odp_context->current_slide().set_transition_subtype(L"fromBottom"); + const std::wstring default_subtype = L"l"; + std::wstring dir = oox_transition->dir.get_value_or(default_subtype); + if (dir.empty()) + dir = default_subtype; - else if (oox_transition->dir->get() == L"rd") odp_context->current_slide().set_transition_subtype(L"horizontalLeft"); - else if (oox_transition->dir->get() == L"lu") odp_context->current_slide().set_transition_subtype(L"horizontalRight"); - else if (oox_transition->dir->get() == L"ld") odp_context->current_slide().set_transition_subtype(L"verticalRight"); - else if (oox_transition->dir->get() == L"ru") odp_context->current_slide().set_transition_subtype(L"verticalLeft"); + if (dir == L"d") odp_context->current_slide().set_transition_subtype(L"fromTop"); + else if (dir == L"l") odp_context->current_slide().set_transition_subtype(L"fromRight"); + else if (dir == L"r") odp_context->current_slide().set_transition_subtype(L"fromLeft"); + else if (dir == L"u") odp_context->current_slide().set_transition_subtype(L"fromBottom"); + + if(oox_transition->name == L"cover") + { + if (dir == L"rd") odp_context->current_slide().set_transition_subtype(L"fromTopLeft"); + else if (dir == L"lu") odp_context->current_slide().set_transition_subtype(L"fromBottomRight"); + else if (dir == L"ld") odp_context->current_slide().set_transition_subtype(L"fromTopRight"); + else if (dir == L"ru") odp_context->current_slide().set_transition_subtype(L"fromBottomLeft"); + } + else + { + if (dir == L"rd") odp_context->current_slide().set_transition_subtype(L"horizontalLeft"); + else if (dir == L"lu") odp_context->current_slide().set_transition_subtype(L"horizontalRight"); + else if (dir == L"ld") odp_context->current_slide().set_transition_subtype(L"verticalRight"); + else if (dir == L"ru") odp_context->current_slide().set_transition_subtype(L"verticalLeft"); } + } void PptxConverter::convert(PPTX::Logic::OptionalBlackTransition *oox_transition) { @@ -903,8 +1919,19 @@ void PptxConverter::convert(PPTX::Logic::SplitTransition *oox_transition) { if (!oox_transition) return; //name == split + + const std::wstring& orient = oox_transition->orient.get_value_or(L"horz"); + const std::wstring& dir = oox_transition->dir.get_value_or(L"out"); + odp_context->current_slide().set_transition_type(3); - odp_context->current_slide().set_transition_subtype(L"vertical"); + + if(orient == L"horz" || orient == L"") + odp_context->current_slide().set_transition_subtype(L"horizontal"); + else if (orient == L"vert") + odp_context->current_slide().set_transition_subtype(L"vertical"); + + if (dir == L"in") + odp_context->current_slide().set_transition_direction(L"reverse"); } void PptxConverter::convert(PPTX::Logic::ZoomTransition *oox_transition) { @@ -913,6 +1940,116 @@ void PptxConverter::convert(PPTX::Logic::ZoomTransition *oox_transition) odp_context->current_slide().set_transition_type(11); } +struct preset_subtype_maping +{ + int OOX_PresetSubtype; + std::wstring ODF_PresetSubtype; +}; + +static const preset_subtype_maping s_preset_subtype_maping[] = +{ + { 1, L"from-top" }, + { 2, L"from-right" }, + { 3, L"from-top-right" }, + { 4, L"from-bottom" }, + { 5, L"horizontal" }, + { 6, L"from-bottom-right" }, + { 8, L"from-left" }, + { 9, L"from-top-left" }, + { 10, L"vertical" }, + { 12, L"from-bottom-left" }, + { 16, L"in" }, + { 21, L"vertical-in" }, + { 26, L"horizontal-in" }, + { 32, L"out" }, + { 36, L"out-from-screen-center" }, + { 37, L"vertical-out" }, + { 42, L"horizontal-out" }, + { 272, L"in-slightly" }, + { 288, L"out-slightly" }, + { 528, L"in-from-screen-center" }, + { 0, L"" } +}; + +static std::wstring convert_subtype(PPTX::Limit::TLPresetClass preset_class_, int preset_id_, int preset_subtype_) +{ + _CP_OPT(std::wstring) subtype; + + const unsigned char entrance_bytecode = 1; + const unsigned char exit_bytecode = 2; + + if ((preset_class_.GetBYTECode() == entrance_bytecode) || (preset_class_.GetBYTECode() == exit_bytecode)) + { + // skip wheel effect + if (preset_id_ != 21) + { + if (preset_id_ == 5) + { + // checkerboard + switch (preset_subtype_) + { + case 5: subtype = L"downward"; break; + case 10: subtype = L"across"; break; + default: subtype = boost::none; + } + } + else if (preset_id_ == 17) + { + // stretch + if (preset_subtype_ == 10) + subtype = L"across"; + } + else if (preset_id_ == 18) + { + // strips + switch (preset_subtype_) + { + case 3: subtype = L"right-to-top"; break; + case 6: subtype = L"right-to-bottom"; break; + case 9: subtype = L"left-to-top"; break; + case 12: subtype = L"left-to-bottom"; break; + default: subtype = boost::none; + } + } + else if (preset_id_ == 6) + { + switch (preset_subtype_) + { + case 16: subtype = L"out"; break; + case 32: subtype = L"in"; break; + default: subtype = boost::none; + } + } + + if (!subtype) + { + const preset_subtype_maping* p = s_preset_subtype_maping; + + while (p->OOX_PresetSubtype != 0) + { + if (p->OOX_PresetSubtype == preset_subtype_) + { + subtype = p->ODF_PresetSubtype; + break; + } + p++; + } + } + } + } + + if (!subtype && preset_subtype_ != 0) + return std::to_wstring(preset_subtype_); + + return subtype.get_value_or(std::to_wstring(preset_subtype_)); +} + +static double convert_acceleration(int acceleration) +{ + const double odf_multiplier = 100000.0; + return acceleration / odf_multiplier; +} + void PptxConverter::convert(PPTX::Logic::CTn *oox_time_common) { if (!oox_time_common) return; @@ -923,7 +2060,7 @@ void PptxConverter::convert(PPTX::Logic::CTn *oox_time_common) } if (oox_time_common->nodeType.IsInit()) { - odp_context->current_slide().set_anim_type(oox_time_common->nodeType->get()); + convert(*oox_time_common->nodeType); } if (oox_time_common->dur.IsInit()) { @@ -935,7 +2072,39 @@ void PptxConverter::convert(PPTX::Logic::CTn *oox_time_common) if (oox_time_common->restart.IsInit()) { odp_context->current_slide().set_anim_restart(oox_time_common->restart->get()); - } + } + if (oox_time_common->fill.IsInit()) + { + odp_context->current_slide().set_anim_fill(odf_types::smil_fill::parse(oox_time_common->fill->get())); + } + if (oox_time_common->autoRev.IsInit()) + { + odp_context->current_slide().set_anim_auto_reverse(*oox_time_common->autoRev); + } + if (oox_time_common->presetClass.IsInit()) + { + convert(*oox_time_common->presetClass); + if (oox_time_common->presetID.IsInit()) + { + convert(*oox_time_common->presetClass, *oox_time_common->presetID); + + if (oox_time_common->presetSubtype.IsInit()) + { + const std::wstring odf_subtype = convert_subtype( + *oox_time_common->presetClass, + *oox_time_common->presetID, + *oox_time_common->presetSubtype); + if(!odf_subtype.empty()) + odp_context->current_slide().set_anim_subtype(odf_subtype); + } + } + } + if (oox_time_common->accel.IsInit()) + odp_context->current_slide().set_anim_accelerate(convert_acceleration(*oox_time_common->accel)); + if (oox_time_common->decel.IsInit()) + odp_context->current_slide().set_anim_decelerate(convert_acceleration(*oox_time_common->decel)); + + //nullable stCondLst; //nullable endCondLst; @@ -943,15 +2112,36 @@ void PptxConverter::convert(PPTX::Logic::CTn *oox_time_common) //nullable iterate; // TODO -// for (auto& child : oox_time_common->childTnLst) -// { -// for (size_t i = 0; i childTnLst->list[i]); -// } -// } + //for (auto& child : oox_time_common->childTnLst) + //{ + // for (size_t i = 0; i childTnLst->list[i]); + // } + //} + + if (oox_time_common->stCondLst.IsInit()) + { + for (size_t i = 0; i < oox_time_common->stCondLst->list.size(); i++) + { + PPTX::Logic::Cond& cond = oox_time_common->stCondLst->list[i]; + convert(&cond); + } + } + + if (oox_time_common->childTnLst.IsInit()) + { + for (size_t i = 0; i < oox_time_common->childTnLst->list.size(); i++) + { + PPTX::Logic::TimeNodeBase& child = oox_time_common->childTnLst->list[i]; + if(child.is_init()) + convert(&child); + } + } + + // if (oox_time_common->childTnLst.IsInit()) // { // for (size_t i = 0; i < oox_time_common->childTnLst->list.size(); i++) @@ -961,16 +2151,77 @@ void PptxConverter::convert(PPTX::Logic::CTn *oox_time_common) // convert(&oox_time_common->childTnLst->list[i]); // } // } - //if (oox_time_common->subTnLst.IsInit()) - //{ - // for (size_t i = 0; i < oox_time_common->subTnLst->list.size(); i++) - // { - // if (oox_time_common->subTnLst->list[i].is_init() == false) continue; + if (oox_time_common->subTnLst.IsInit()) + { + for (size_t i = 0; i < oox_time_common->subTnLst->list.size(); i++) + { + if (oox_time_common->subTnLst->list[i].is_init() == false) continue; - // convert(&oox_time_common->subTnLst->list[i]); - // } - //} + convert(&oox_time_common->subTnLst->list[i]); + } + } +} + + +void PptxConverter::convert(PPTX::Logic::Cond* oox_condition) +{ + if (!oox_condition) + return; + + std::wstring begin = L"0s"; + + if (oox_condition->delay.IsInit()) + { + std::wstring delay; + if (*oox_condition->delay == L"indefinite") + delay = L"next"; + else + { + int ms = XmlUtils::GetInteger(*oox_condition->delay); + std::wstringstream ss; + ss << ms / 1000.0 << L"s"; + delay = ss.str(); + } + + if (!interactive_animation_element_id.empty()) + { + delay = interactive_animation_element_id + L".click+" + delay; + interactive_animation_element_id = std::wstring(); + } + + + begin = delay; + } + + if (oox_condition->tgtEl.IsInit()) + { + if (oox_condition->tgtEl->spTgt.IsInit()) + { + std::wstring id = odp_context->get_mapped_identifier(oox_condition->tgtEl->spTgt->spid); + interactive_animation_element_id = id; + } + } + + odp_context->current_slide().set_anim_begin(begin); + + //else if(oox_condition->evt.IsInit()) + // odp_context->current_slide().set_anim_evt(); } + +void PptxConverter::convert(PPTX::Logic::Set* oox_set) +{ + if (!oox_set) + return; + + odp_context->current_slide().start_timing_set(); + + convert(&oox_set->cBhvr); + if(oox_set->to.IsInit()) + convert(oox_set->to.GetPointer()); + + odp_context->current_slide().end_timing_set(); +} + void PptxConverter::convert(PPTX::Logic::TableProperties *oox_table_pr) { if (!oox_table_pr) return; @@ -1004,27 +2255,27 @@ void PptxConverter::convert(PPTX::Logic::TableProperties *oox_table_pr) if (!table_style.default_.empty()) odp_context->slide_context()->table_context()->set_default_cell_properties(table_style.default_); - if (oox_table_pr->FirstRow.is_init() && !table_style.first_row_.empty()) + if (oox_table_pr->FirstRow.get_value_or(false) && !table_style.first_row_.empty()) { odp_context->slide_context()->table_context()->set_first_row_cell_properties(table_style.first_row_); } - if (oox_table_pr->FirstCol.is_init() && !table_style.first_col_.empty()) + if (oox_table_pr->FirstCol.get_value_or(false) && !table_style.first_col_.empty()) { odp_context->slide_context()->table_context()->set_first_col_cell_properties(table_style.first_col_); } - if (oox_table_pr->BandRow.is_init() && !table_style.band_row_.empty()) + if (oox_table_pr->BandRow.get_value_or(false) && !table_style.band_row_.empty()) { odp_context->slide_context()->table_context()->set_band_row_cell_properties(table_style.band_row_); } - if (oox_table_pr->BandCol.is_init() && !table_style.band_col_.empty()) + if (oox_table_pr->BandCol.get_value_or(false) && !table_style.band_col_.empty()) { odp_context->slide_context()->table_context()->set_band_col_cell_properties(table_style.band_col_); } - if (oox_table_pr->LastRow.is_init() && !table_style.last_row_.empty()) + if (oox_table_pr->LastRow.get_value_or(false) && !table_style.last_row_.empty()) { odp_context->slide_context()->table_context()->set_last_row_cell_properties(table_style.last_row_); } - if (oox_table_pr->LastCol.is_init() && !table_style.last_col_.empty()) + if (oox_table_pr->LastCol.get_value_or(false) && !table_style.last_col_.empty()) { odp_context->slide_context()->table_context()->set_last_col_cell_properties(table_style.last_col_); } @@ -1059,8 +2310,6 @@ void PptxConverter::convert(PPTX::Logic::Table *oox_table) convert(oox_table->tableProperties.GetPointer()); - odp_context->slide_context()->start_table_columns(); - for (size_t i = 0; i < oox_table->TableCols.size(); i++) { double width = -1; @@ -1071,7 +2320,6 @@ void PptxConverter::convert(PPTX::Logic::Table *oox_table) odp_context->slide_context()->add_table_column(width); } - odp_context->slide_context()->end_table_columns(); odp_context->slide_context()->table_context()->set_table_size(oox_table->TableCols.size(), oox_table->TableRows.size()); @@ -1486,16 +2734,7 @@ void PptxConverter::convert_slide(PPTX::Logic::CSld *oox_slide, PPTX::Logic::TxS if (current_theme && current_clrMap) current_theme->SetColorMap(*current_clrMap); - std::wstring page_name; - if (oox_slide->attrName.IsInit()) - page_name = oox_slide->attrName.get(); - - - if (page_name.empty()) - { - if (type == Slide) - page_name = L"Slide_" + std::to_wstring((int)odp_context->get_pages_count()); - } + std::wstring page_name = get_page_name(oox_slide, type); odp_context->current_slide().set_page_name(page_name); if (type != Notes && type != NotesMaster) @@ -1536,10 +2775,17 @@ void PptxConverter::convert_slide(PPTX::Logic::CSld *oox_slide, PPTX::Logic::TxS } int ph_type = 0; + bool placeholder_replacing = false; if (pNvPr->ph->type.IsInit()) { ph_type = pNvPr->ph->type->GetBYTECode(); + if (type == Slide && ph_type == 0) + { + placeholder_replacing = true; + ph_type = 16; // body + } + if (type == Layout && (ph_type == 5 || ph_type == 6 || ph_type == 7 || ph_type == 12)) continue; } @@ -1547,6 +2793,7 @@ void PptxConverter::convert_slide(PPTX::Logic::CSld *oox_slide, PPTX::Logic::TxS if (!bPlaceholders) continue; + odf_context()->drawing_context()->placeholder_replacing(placeholder_replacing); odf_context()->drawing_context()->set_placeholder_type(ph_type); if (pNvPr->ph->idx.IsInit()) @@ -1642,6 +2889,19 @@ void PptxConverter::convert_slide(PPTX::Logic::CSld *oox_slide, PPTX::Logic::TxS OoxConverter::convert(pElem.GetPointer()); } + { + // TODO: Move to NvPicPr.cNvPr conversion + int id = -1; + if (pPic.IsInit()) + id = pPic->nvPicPr.cNvPr.id; + + if (id != -1) + { + const std::wstring xml_id = odp_context->map_indentifier(std::to_wstring(id)); + odf_context()->drawing_context()->set_xml_id(xml_id); + } + } + odf_context()->drawing_context()->end_drawing(); } convert(oox_slide->controls.GetPointer()); @@ -1669,7 +2929,7 @@ void PptxConverter::convert_layout(PPTX::Logic::CSld *oox_slide) odf_writer::office_element_ptr elm; create_element(L"presentation", L"placeholder", elm, odp_context); - odf_context()->drawing_context()->start_drawing(); + odf_context()->drawing_context()->start_drawing(); odf_context()->drawing_context()->start_element(elm); odf_context()->drawing_context()->set_placeholder_type(type); @@ -1678,6 +2938,7 @@ void PptxConverter::convert_layout(PPTX::Logic::CSld *oox_slide) odf_context()->drawing_context()->set_placeholder_id(*pShape->nvSpPr.nvPr.ph->idx); OoxConverter::convert(pShape->spPr.xfrm.GetPointer()); + OoxConverter::convert(pShape->txBody.GetPointer()); odf_context()->drawing_context()->end_element(); odf_context()->drawing_context()->end_drawing(); diff --git a/OdfFile/Writer/Converter/PptxConverter.h b/OdfFile/Writer/Converter/PptxConverter.h index fafd10fa46a..d5e1a7c835f 100644 --- a/OdfFile/Writer/Converter/PptxConverter.h +++ b/OdfFile/Writer/Converter/PptxConverter.h @@ -71,6 +71,22 @@ namespace PPTX class TcTxStyle; class TimeNodeBase; class CTn; + class Cond; + class Anim; + class AnimClr; + class AnimEffect; + class AnimMotion; + class AnimRot; + class AnimScale; + class Audio; + class Cmd; + class Excl; + class Set; + class Video; + class CBhvr; + class TgtEl; + class AnimVariant; + class AttrName; class EmptyTransition; class OrientationTransition; class EightDirectionTransition; @@ -81,6 +97,12 @@ namespace PPTX class SplitTransition; class ZoomTransition; } + + namespace Limit + { + class TLNodeType; + class TLPresetClass; + } } namespace cpdoccore @@ -95,6 +117,10 @@ namespace cpdoccore class odf_conversion_context; class odt_conversion_context; class odp_conversion_context; + + class graphic_format_properties; + class style_table_cell_properties; + class paragraph_format_properties; } } @@ -139,6 +165,22 @@ namespace Oox2Odf void convert(PPTX::Logic::Transition *oox_transition); void convert(PPTX::Logic::TimeNodeBase *oox_base_time); void convert(PPTX::Logic::CTn *oox_common_time); + void convert(PPTX::Logic::Cond *oox_condition); + void convert(PPTX::Logic::Anim *oox_anim); + void convert(PPTX::Logic::AnimClr *oox_anim_color); + void convert(PPTX::Logic::AnimEffect *oox_anim_effect); + void convert(PPTX::Logic::AnimMotion *oox_anim_motion); + void convert(PPTX::Logic::AnimRot *oox_anim_rot); + void convert(PPTX::Logic::AnimScale *oox_anim_scale); + void convert(PPTX::Logic::Audio *oox_audio); + void convert(PPTX::Logic::Cmd *oox_cmd); + void convert(PPTX::Logic::Excl *oox_excl); + void convert(PPTX::Logic::Set *oox_set); + void convert(PPTX::Logic::Video *oox_video); + void convert(PPTX::Logic::CBhvr *oox_cbhvr); + void convert(PPTX::Logic::TgtEl *oox_tgt_el); + void convert(PPTX::Logic::AnimVariant *oox_anim_variant); + void convert(PPTX::Logic::AttrName *oox_attr_name); void convert(PPTX::Logic::Table *oox_table); void convert(PPTX::Logic::TableRow *oox_table_row); @@ -171,6 +213,12 @@ namespace Oox2Odf void convert(PPTX::Logic::SplitTransition *oox_transition); void convert(PPTX::Logic::ZoomTransition *oox_transition); + void convert(const PPTX::Limit::TLNodeType& oox_note_type); + void convert(const PPTX::Limit::TLPresetClass& oox_preset_class); + void convert(const PPTX::Limit::TLPresetClass& oox_preset_class, int preset_id); + void convert(odf_writer::graphic_format_properties* graphic_props, odf_writer::style_table_cell_properties* table_cell_props); + void convert(odf_writer::paragraph_format_properties* paragraph_props, odf_writer::style_table_cell_properties* table_cell_props); + PPTX::Document *pptx_document; PPTX::Presentation *presentation; @@ -183,13 +231,21 @@ namespace Oox2Odf std::map m_mapMasters; std::map m_mapLayouts; - - void convert_slides (); - void convert_styles (); - void convert_settings (); - void convert_layouts (); - void convert_common (); + std::wstring interactive_animation_element_id; + + void convert_slides (); + void convert_styles (); + void convert_settings (); + void convert_layouts (); + void convert_common (); + void convert_masters_and_layouts(); + + std::wstring convert_animation_formula(std::wstring formula); + std::wstring convert_animation_scale_values(int x, int y); + + std::wstring get_page_name(PPTX::Logic::CSld* oox_slide, _typePages type); + void fill_in_deferred_hyperlinks(); //-------------------------------------------------------------------------------- }; diff --git a/OdfFile/Writer/Converter/XlsxConverter.cpp b/OdfFile/Writer/Converter/XlsxConverter.cpp index 61d9fba8bb9..7c73ed9aede 100644 --- a/OdfFile/Writer/Converter/XlsxConverter.cpp +++ b/OdfFile/Writer/Converter/XlsxConverter.cpp @@ -170,6 +170,7 @@ bool XlsxConverter::convertDocument() ods_context->start_document(); convert_meta(xlsx_document->m_pApp, xlsx_document->m_pCore); + convert_customs(xlsx_document); convert_styles(); convert_sheets(); @@ -445,9 +446,10 @@ void XlsxConverter::convert(OOX::Spreadsheet::CWorksheet *oox_sheet) if (!oox_sheet->m_arrConditionalFormatting.empty() || oox_sheet->m_oExtLst.IsInit()) { - std::multimap mapSorted; + std::multimap> mapSorted; - std::vector arUnsorted; + std::vector> arUnsorted; + std::vector> arUnsortedEx; // sort by prioritet for (size_t fmt = 0; fmt < oox_sheet->m_arrConditionalFormatting.size(); fmt++) @@ -465,9 +467,9 @@ void XlsxConverter::convert(OOX::Spreadsheet::CWorksheet *oox_sheet) } } if (priority >= 0) - mapSorted.insert(std::make_pair(priority, cond_fmt)); + mapSorted.insert(std::make_pair(priority, std::make_pair(cond_fmt, false))); else - arUnsorted.push_back(cond_fmt); + arUnsorted.push_back(std::make_pair(cond_fmt, false)); } } @@ -492,27 +494,32 @@ void XlsxConverter::convert(OOX::Spreadsheet::CWorksheet *oox_sheet) } } if (priority >= 0) - mapSorted.insert(std::make_pair(priority, cond_fmt)); + mapSorted.insert(std::make_pair(priority, std::make_pair(cond_fmt, true))); else - arUnsorted.push_back(cond_fmt); + arUnsortedEx.push_back(std::make_pair(cond_fmt, true)); } } } } //-------------------------------------------------------------------------- - if (arUnsorted.size() + mapSorted.size() > 0) + if (arUnsorted.size() + mapSorted.size() + arUnsortedEx.size() > 0) { ods_context->start_conditional_formats(); for (size_t fmt = 0; fmt < arUnsorted.size(); fmt++) { - convert(arUnsorted[fmt]); + convert(arUnsorted[fmt].first, oox_sheet->m_mapConditionalFormattingEx, arUnsorted[fmt].second); } - for (std::multimap::iterator it = mapSorted.begin(); it != mapSorted.end(); ++it) + for (std::multimap>::iterator it = mapSorted.begin(); it != mapSorted.end(); ++it) { - convert(it->second); + convert(it->second.first, oox_sheet->m_mapConditionalFormattingEx, it->second.second); + } + + for (size_t fmt = 0; fmt < arUnsortedEx.size(); fmt++) + { + convert(arUnsortedEx[fmt].first, oox_sheet->m_mapConditionalFormattingEx, arUnsortedEx[fmt].second); } ods_context->end_conditional_formats(); } @@ -611,7 +618,7 @@ void XlsxConverter::convert(OOX::Spreadsheet::CLegacyDrawingHFWorksheet *oox_bac oox_current_child_document = dynamic_cast(vmlDrawing.GetPointer()); - for (boost::unordered_map::iterator it = vmlDrawing->m_mapShapes.begin(); it!= vmlDrawing->m_mapShapes.end(); ++it) + for (std::map::iterator it = vmlDrawing->m_mapShapes.begin(); it!= vmlDrawing->m_mapShapes.end(); ++it) { OOX::Vml::CShape* pShape = dynamic_cast(it->second.pElement); @@ -1151,6 +1158,7 @@ void XlsxConverter::convert(OOX::Spreadsheet::CRow *oox_row, OOX::Spreadsheet::C { if (oox_row_prev->m_oCollapsed.IsInit()) { + if (oox_row->m_oCollapsed->GetValue() != oox_row_prev->m_oCollapsed->GetValue()) bEqual = false; } else bEqual = false; } @@ -1268,8 +1276,8 @@ void XlsxConverter::convert(OOX::Spreadsheet::CRow *oox_row, OOX::Spreadsheet::C ods_context->start_row(row_number, 1, level, _default); - if (oox_row->m_oHidden.IsInit()) ods_context->current_table()->set_row_hidden(true); - if (oox_row->m_oCollapsed.IsInit()) ods_context->current_table()->set_row_hidden(true); + if (oox_row->m_oHidden.IsInit() && oox_row->m_oHidden->ToBool()) ods_context->current_table()->set_row_hidden(true); + if (oox_row->m_oCollapsed.IsInit() && oox_row->m_oCollapsed->ToBool()) ods_context->current_table()->set_row_hidden(true); std::wstring style_cell_name; if (oox_row->m_oS.IsInit() && ( oox_row->m_oCustomFormat.IsInit() && oox_row->m_oCustomFormat->GetValue()==1)) @@ -1346,8 +1354,7 @@ void XlsxConverter::convert(OOX::Spreadsheet::CCell *oox_cell) if (value_type >=0) ods_context->current_table()->set_cell_type (value_type); - ods_context->current_table()->set_cell_value (oox_cell->m_oValue->m_sText); - //ods_context->current_table()->set_cell_cache (oox_cell->m_oValue->m_sText); + ods_context->current_table()->set_cell_value (oox_cell->m_oValue->m_sText, oox_cell->m_oFormula.IsInit()); } } @@ -1401,9 +1408,19 @@ void XlsxConverter::convert(OOX::Spreadsheet::CExternalLink *oox_external_link) smart_ptr fileExternal = file.smart_dynamic_cast(); if (fileExternal.IsInit()) { - ods_context->add_external_reference(fileExternal->Uri().GetPath()); + std::wstring filePath = fileExternal->Uri().GetPath(); + + if (std::wstring::npos == filePath.find(L"file://")) + filePath = L"file://" + filePath; + ods_context->add_external_reference(filePath); } } + //todooo + } + if (oox_external_link->m_oFileKey.IsInit() || oox_external_link->m_oInstanceId.IsInit()) + { + //todooo + } xlsx_current_container = old_container; } @@ -1708,7 +1725,7 @@ void XlsxConverter::convert(OOX::Spreadsheet::CFileSharing *oox_file_sharing) if (oox_file_sharing->m_oHashValue.IsInit() && oox_file_sharing->m_oAlgorithmName.IsInit() && oox_file_sharing->m_oSaltValue.IsInit() && oox_file_sharing->m_oSpinCount.IsInit()) { - ods_context->settings_context()->set_modify_info(oox_file_sharing->m_oAlgorithmName->ToString(), *oox_file_sharing->m_oSaltValue, *oox_file_sharing->m_oHashValue, oox_file_sharing->m_oSpinCount->GetValue()); + ods_context->settings_context()->set_modify_info(L"", oox_file_sharing->m_oAlgorithmName->ToString(), *oox_file_sharing->m_oSaltValue, *oox_file_sharing->m_oHashValue, oox_file_sharing->m_oSpinCount->GetValue()); } } } @@ -1992,6 +2009,19 @@ void XlsxConverter::convert(OOX::Spreadsheet::CPageSetup *oox_page) width = odf_types::length(8.5, odf_types::length::inch); height = odf_types::length(11, odf_types::length::inch); break; + //case SimpleTypes::Spreadsheet::pagesizeLetterSmall: + case SimpleTypes::Spreadsheet::pagesizeTabloidPaper: + width = odf_types::length(279.4, odf_types::length::mm); + height = odf_types::length(431.8, odf_types::length::mm); + break; + case SimpleTypes::Spreadsheet::pagesizeLegalPaper: + width = odf_types::length(215.9, odf_types::length::mm); + height = odf_types::length(355.6, odf_types::length::mm); + break; + case SimpleTypes::Spreadsheet::pagesizeExecutivePaper: + width = odf_types::length(184.2, odf_types::length::mm); + height = odf_types::length(266.7, odf_types::length::mm); + break; case SimpleTypes::Spreadsheet::pagesizeA3Paper: width = odf_types::length(297, odf_types::length::mm); height = odf_types::length(420, odf_types::length::mm); @@ -2000,9 +2030,45 @@ void XlsxConverter::convert(OOX::Spreadsheet::CPageSetup *oox_page) width = odf_types::length(210, odf_types::length::mm); height = odf_types::length(297, odf_types::length::mm); break; + //case SimpleTypes::Spreadsheet::pagesizeA4SmallPaper: + case SimpleTypes::Spreadsheet::pagesizeA5Paper: + width = odf_types::length(148, odf_types::length::mm); + height = odf_types::length(210, odf_types::length::mm); + break; + case SimpleTypes::Spreadsheet::pagesizeB4Paper: + width = odf_types::length(257, odf_types::length::mm); + height = odf_types::length(364, odf_types::length::mm); + break; + case SimpleTypes::Spreadsheet::pagesizeB5Paper: + width = odf_types::length(182, odf_types::length::mm); + height = odf_types::length(257, odf_types::length::mm); + break; + case SimpleTypes::Spreadsheet::pagesizeFolioPaper: + width = odf_types::length(215.9, odf_types::length::mm); + height = odf_types::length(330.2, odf_types::length::mm); + break; + case SimpleTypes::Spreadsheet::pagesize10Envelope: + width = odf_types::length(104.7, odf_types::length::mm); + height = odf_types::length(241.3, odf_types::length::mm); + break; + case SimpleTypes::Spreadsheet::pagesizeDLEnvelope: + width = odf_types::length(110, odf_types::length::mm); + height = odf_types::length(220, odf_types::length::mm); + break; + case SimpleTypes::Spreadsheet::pagesizeC5Envelope: + width = odf_types::length(162, odf_types::length::mm); + height = odf_types::length(229, odf_types::length::mm); + break; + case SimpleTypes::Spreadsheet::pagesizeC4Envelope: + width = odf_types::length(229, odf_types::length::mm); + height = odf_types::length(324, odf_types::length::mm); + break; + case SimpleTypes::Spreadsheet::pagesizeMonarchEnvelope: + width = odf_types::length(98.4, odf_types::length::mm); + height = odf_types::length(190.5, odf_types::length::mm); + break; default: break; - //todooo } } ods_context->page_layout_context()->set_page_size(width, height); @@ -2501,47 +2567,47 @@ void XlsxConverter::convert(OOX::Spreadsheet::CBorderProp *borderProp, std::wstr switch(borderProp->m_oStyle->GetValue()) { case SimpleTypes::Spreadsheet::borderstyleDashDot: - border_style = L"1pt dot-dashed"; + border_style = L"0.74pt dash-dot"; break; case SimpleTypes::Spreadsheet::borderstyleDashDotDot: - border_style = L"1pt dot-dashed"; + border_style = L"0.74pt dash-dot-dot"; break; case SimpleTypes::Spreadsheet::borderstyleDashed: - border_style = L"1pt dashed"; + border_style = L"0.74pt dashed"; break; case SimpleTypes::Spreadsheet::borderstyleDotted: - border_style = L"1pt dotted"; + border_style = L"0.74pt dotted"; break; case SimpleTypes::Spreadsheet::borderstyleDouble: - border_style = L"1pt double"; + border_style = L"0.74pt double"; break; case SimpleTypes::Spreadsheet::borderstyleHair: - border_style = L"1pt solid"; + border_style = L"0.06pt solid"; break; case SimpleTypes::Spreadsheet::borderstyleMedium: - border_style = L"2.49pt solid"; + border_style = L"1.76pt solid"; break; case SimpleTypes::Spreadsheet::borderstyleMediumDashDot: - border_style = L"2.49pt dot-dashed"; + border_style = L"1.76pt dash-dot"; break; case SimpleTypes::Spreadsheet::borderstyleMediumDashDotDot: - border_style = L"2.49pt dot-dashed"; + border_style = L"1.76pt dash-dot-dot"; break; case SimpleTypes::Spreadsheet::borderstyleMediumDashed: - border_style = L"2.49pt dashed"; + border_style = L"1.76pt dashed"; break; case SimpleTypes::Spreadsheet::borderstyleNone: border_style = L"none"; return; break; case SimpleTypes::Spreadsheet::borderstyleSlantDashDot: - border_style = L"1pt solid"; + border_style = L"1.76pt fine-dashed"; break; case SimpleTypes::Spreadsheet::borderstyleThick: - border_style = L"1pt solid"; + border_style = L"2.49pt solid"; break; case SimpleTypes::Spreadsheet::borderstyleThin: - border_style = L"1pt solid"; + border_style = L"0.74pt solid"; break; } } @@ -2615,7 +2681,7 @@ void XlsxConverter::convert(OOX::Spreadsheet::CColor *color, _CP_OPT(odf_types:: } else { - result = OOX::Spreadsheet::CIndexedColors::GetDefaultRGBAByIndex(ind, ucR, ucG, ucB, ucA); + result = ind < 64 ? OOX::Spreadsheet::CIndexedColors::GetDefaultRGBAByIndex(ind, ucR, ucG, ucB, ucA) : false; } } if (result == true) @@ -2956,7 +3022,7 @@ void XlsxConverter::convert(OOX::Spreadsheet::COleObjects *oox_objects, OOX::Spr std::wstring pathOle = find_link_by_id(sID, 4, bExternal); - odf_ref_object = odf_context()->add_oleobject(pathOle); + odf_ref_object = odf_context()->add_oleobject(pathOle, bExternal); } if ((object->m_oObjectPr.IsInit()) && (object->m_oObjectPr->m_oRid.IsInit())) { @@ -2964,7 +3030,7 @@ void XlsxConverter::convert(OOX::Spreadsheet::COleObjects *oox_objects, OOX::Spr std::wstring pathImage = find_link_by_id(sID, 1, bExternal); - odf_ref_image = odf_context()->add_imageobject(pathImage); + odf_ref_image = odf_context()->add_imageobject(pathImage, bExternal); } //-------------------------------------------------------------------------------------------------- if ((!bAnchor || odf_ref_image.empty()) && object->m_oShapeId.IsInit()) @@ -3018,9 +3084,9 @@ void XlsxConverter::convert(OOX::Spreadsheet::COleObjects *oox_objects, OOX::Spr if (pFile.IsInit() && ( OOX::FileTypes::Image == pFile->type())) { - OOX::Image* pImageFileCache = static_cast(pFile.GetPointer()); - - if (pImageFileCache && odf_ref_image.empty()) + smart_ptr pImageFileCache = pFile.smart_dynamic_cast(); + + if (pImageFileCache.IsInit() && odf_ref_image.empty()) { odf_ref_image = odf_context()->add_imageobject(pImageFileCache->filename().GetPath()); } @@ -3173,25 +3239,25 @@ void XlsxConverter::convert(OOX::Spreadsheet::CControls *oox_controls, OOX::Spre { { oox_table_position from = {}, to = {}; - - convert(oCellAnchor->m_oFrom.GetPointer(), &from); + + convert(oCellAnchor->m_oFrom.GetPointer(), &from); convert(oCellAnchor->m_oTo.GetPointer(), &to); double x1 = 0, y1 = 0, x2 = 0, y2 = 0; ods_context->current_table()->convert_position(from, x1, y1); - ods_context->current_table()->convert_position(to, x2, y2); - + ods_context->current_table()->convert_position(to, x2, y2); + ods_context->drawing_context()->set_drawings_rect(x1, y1, x2 - x1, y2 - y1); - } + } ods_context->drawing_context()->start_drawing(); ods_context->drawing_context()->start_control(id); - + if (pControl->m_oName.IsInit()) { ods_context->controls_context()->set_name(*pControl->m_oName); ods_context->drawing_context()->set_name(*pControl->m_oName); } -//---------------------- + //---------------------- if (oFormControlPr->m_oText.IsInit()) { ods_context->controls_context()->set_label(*oFormControlPr->m_oText); @@ -3199,13 +3265,13 @@ void XlsxConverter::convert(OOX::Spreadsheet::CControls *oox_controls, OOX::Spre if (oFormControlPr->m_oFillColor.IsInit()) { ods_context->drawing_context()->start_area_properties(true); - ods_context->drawing_context()->set_solid_fill(oFormControlPr->m_oFillColor->ToString()); + ods_context->drawing_context()->set_solid_fill(oFormControlPr->m_oFillColor->ToString()); ods_context->drawing_context()->end_area_properties(); } if (oFormControlPr->m_oBorderColor.IsInit()) { ods_context->drawing_context()->start_line_properties(); - ods_context->drawing_context()->set_line_color(oFormControlPr->m_oBorderColor->ToString()); + ods_context->drawing_context()->set_line_color(oFormControlPr->m_oBorderColor->ToString()); ods_context->drawing_context()->end_line_properties(); } if (oFormControlPr->m_oTextHAlign.IsInit()) @@ -3283,37 +3349,40 @@ void XlsxConverter::convert(OOX::Spreadsheet::CControls *oox_controls, OOX::Spre //nullable_bool m_oPasswordEdit; //nullable m_oItemLst; //--------------------- - if (pControl->m_oControlPr->m_oLinkedCell.IsInit()) - { - ods_context->controls_context()->set_linkedCell(*pControl->m_oControlPr->m_oLinkedCell); - } - if (pControl->m_oControlPr->m_oListFillRange.IsInit()) - { - ods_context->controls_context()->set_listFillRange(*pControl->m_oControlPr->m_oListFillRange); - } - if (pControl->m_oControlPr->m_oMacro.IsInit()) - { - ods_context->controls_context()->set_macro(*pControl->m_oControlPr->m_oMacro); - } - if (pControl->m_oControlPr->m_oDisabled.IsInit()) - { - ods_context->controls_context()->set_disabled(*pControl->m_oControlPr->m_oDisabled); - } - if (pControl->m_oControlPr->m_oPrint.IsInit()) - { - ods_context->controls_context()->set_printable(*pControl->m_oControlPr->m_oPrint); - } - if (pControl->m_oControlPr->m_oLocked.IsInit()) + if (pControl->m_oControlPr.IsInit()) { + if (pControl->m_oControlPr->m_oLinkedCell.IsInit()) + { + ods_context->controls_context()->set_linkedCell(*pControl->m_oControlPr->m_oLinkedCell); + } + if (pControl->m_oControlPr->m_oListFillRange.IsInit()) + { + ods_context->controls_context()->set_listFillRange(*pControl->m_oControlPr->m_oListFillRange); + } + if (pControl->m_oControlPr->m_oMacro.IsInit()) + { + ods_context->controls_context()->set_macro(*pControl->m_oControlPr->m_oMacro); + } + if (pControl->m_oControlPr->m_oDisabled.IsInit()) + { + ods_context->controls_context()->set_disabled(*pControl->m_oControlPr->m_oDisabled); + } + if (pControl->m_oControlPr->m_oPrint.IsInit()) + { + ods_context->controls_context()->set_printable(*pControl->m_oControlPr->m_oPrint); + } + if (pControl->m_oControlPr->m_oLocked.IsInit()) + { + } + //nullable_string m_oAltText; + //nullable_bool m_oAutoFill; + //nullable_bool m_oAutoLine; + //nullable_bool m_oAutoPict; + //nullable_bool m_oDde; + //nullable_bool m_oDefaultSize; + //nullable_string m_oCf; + //nullable_bool m_oRecalcAlways; } - //nullable_string m_oAltText; - //nullable_bool m_oAutoFill; - //nullable_bool m_oAutoLine; - //nullable_bool m_oAutoPict; - //nullable_bool m_oDde; - //nullable_bool m_oDefaultSize; - //nullable_string m_oCf; - //nullable_bool m_oRecalcAlways; //--------------------- ods_context->drawing_context()->end_control(); ods_context->drawing_context()->end_drawing(); @@ -3391,9 +3460,12 @@ void XlsxConverter::convert(OOX::Spreadsheet::CSparklines *sparklines) ods_context->current_table()->start_sparklines(); for (size_t i = 0; i < sparklines->m_arrItems.size(); ++i) { + if (!sparklines->m_arrItems[i]) continue; ods_context->current_table()->start_sparkline(); - ods_context->current_table()->set_sparkline_range(*sparklines->m_arrItems[i]->m_oRef); - ods_context->current_table()->set_sparkline_cell(*sparklines->m_arrItems[i]->m_oSqRef); + if (sparklines->m_arrItems[i]->m_oRef.IsInit()) + ods_context->current_table()->set_sparkline_range(*sparklines->m_arrItems[i]->m_oRef); + if (sparklines->m_arrItems[i]->m_oSqRef.IsInit()) + ods_context->current_table()->set_sparkline_cell(*sparklines->m_arrItems[i]->m_oSqRef); ods_context->current_table()->end_sparkline(); } ods_context->current_table()->end_sparklines(); @@ -3403,35 +3475,66 @@ void XlsxConverter::convert(OOX::Spreadsheet::CAltTextTable *alt_text) if (!alt_text) return; } -void XlsxConverter::convert(OOX::Spreadsheet::CConditionalFormatting *oox_cond_fmt) +void XlsxConverter::convert(OOX::Spreadsheet::CConditionalFormatting *oox_cond_fmt, + std::map& mapCFRuleEx, bool isExt) { if (!oox_cond_fmt)return; - if (oox_cond_fmt->m_oSqRef.IsInit()) + bool bRule = false; + for (size_t i = 0; i < oox_cond_fmt->m_arrItems.size(); i++) + { + if (oox_cond_fmt->m_arrItems[i]->bUsage) continue; + bRule = true; + break; + } + if (!bRule) return; + + if (oox_cond_fmt->m_oSqRef.IsInit()) { ods_context->current_table()->start_conditional_format(oox_cond_fmt->m_oSqRef.get()); for (size_t i = 0; i < oox_cond_fmt->m_arrItems.size(); i++) { - convert(oox_cond_fmt->m_arrItems[i]);//rule + convert(oox_cond_fmt->m_arrItems[i], mapCFRuleEx, isExt);//rule } ods_context->current_table()->end_conditional_format(); } } -void XlsxConverter::convert(OOX::Spreadsheet::CConditionalFormattingRule *oox_cond_rule) +void XlsxConverter::convert(OOX::Spreadsheet::CConditionalFormattingRule *oox_cond_rule, + std::map& mapCFRuleEx, bool isExt) { - if (!oox_cond_rule)return; + if (!oox_cond_rule) return; + + std::map::iterator pFind; + if (oox_cond_rule->m_oExtId.IsInit()) + { + pFind = mapCFRuleEx.find(*oox_cond_rule->m_oExtId); + + if (pFind != mapCFRuleEx.end()) + { + OOX::Spreadsheet::CConditionalFormattingRule newRule = + OOX::Spreadsheet::CConditionalFormattingRule::Merge(*oox_cond_rule, *pFind->second); + + pFind->second->bUsage = true; + convert(&newRule, mapCFRuleEx, true); + return; + } + } if (false == oox_cond_rule->m_oType.IsInit()) return; _CP_OPT(unsigned int) rank; - _CP_OPT(bool) bottom, percent; - + _CP_OPT(bool) bottom, percent, above, equal; + _CP_OPT(int) stdDev; + if (oox_cond_rule->m_oRank.IsInit()) rank = oox_cond_rule->m_oRank->GetValue(); if (oox_cond_rule->m_oBottom.IsInit()) bottom = oox_cond_rule->m_oBottom->ToBool(); if (oox_cond_rule->m_oPercent.IsInit()) percent = oox_cond_rule->m_oPercent->ToBool(); + if (oox_cond_rule->m_oAboveAverage.IsInit()) above = oox_cond_rule->m_oAboveAverage->ToBool(); + if (oox_cond_rule->m_oEqualAverage.IsInit()) equal = oox_cond_rule->m_oEqualAverage->ToBool(); + if (oox_cond_rule->m_oStdDev.IsInit()) stdDev = oox_cond_rule->m_oStdDev->GetValue(); - ods_context->current_table()->start_conditional_rule(oox_cond_rule->m_oType->GetValue(), rank, bottom, percent); + ods_context->current_table()->start_conditional_rule(oox_cond_rule->m_oType->GetValue(), rank, bottom, percent, above, equal, stdDev); { if (oox_cond_rule->m_oDxfId.IsInit()) { @@ -3454,7 +3557,7 @@ void XlsxConverter::convert(OOX::Spreadsheet::CConditionalFormattingRule *oox_co if (oox_cond_rule->m_oTimePeriod.IsInit()) ods_context->current_table()->set_conditional_time(oox_cond_rule->m_oTimePeriod->GetValue()); - + convert(oox_cond_rule->m_oIconSet.GetPointer()); convert(oox_cond_rule->m_oColorScale.GetPointer()); convert(oox_cond_rule->m_oDataBar.GetPointer()); @@ -3470,26 +3573,38 @@ void XlsxConverter::convert(OOX::Spreadsheet::CDataBar *oox_cond_databar) _CP_OPT(odf_types::color) color; - if (oox_cond_databar->m_oBorderColor.IsInit()) - convert(oox_cond_databar->m_oBorderColor.GetPointer(), color); - else + if (oox_cond_databar->m_oColor.IsInit()) convert(oox_cond_databar->m_oColor.GetPointer(), color); + else if (oox_cond_databar->m_oBorderColor.IsInit()) // ???? + convert(oox_cond_databar->m_oBorderColor.GetPointer(), color); ods_context->current_table()->set_conditional_databar_color(color); convert(oox_cond_databar->m_oAxisColor.GetPointer(), color); ods_context->current_table()->set_conditional_databar_axis_color(color); - convert(oox_cond_databar->m_oNegativeBorderColor.GetPointer(), color); + if (oox_cond_databar->m_oNegativeFillColor.IsInit()) + convert(oox_cond_databar->m_oNegativeFillColor.GetPointer(), color); + else if (oox_cond_databar->m_oNegativeBorderColor.IsInit()) // ???? + convert(oox_cond_databar->m_oNegativeBorderColor.GetPointer(), color); + ods_context->current_table()->set_conditional_databar_negative_color(color); + if (oox_cond_databar->m_oGradient.IsInit()) + ods_context->current_table()->set_conditional_databar_gradient(oox_cond_databar->m_oGradient->ToBool()); + if (oox_cond_databar->m_oAxisPosition.IsInit()) ods_context->current_table()->set_conditional_databar_axis_position(oox_cond_databar->m_oAxisPosition->ToString()); if (oox_cond_databar->m_oShowValue.IsInit()) ods_context->current_table()->set_conditional_show_value(oox_cond_databar->m_oShowValue->ToBool()); - //nullable> m_oMaxLength; - //nullable> m_oMinLength; + + if (oox_cond_databar->m_oMaxLength.IsInit()) + ods_context->current_table()->set_conditional_databar_max(oox_cond_databar->m_oMaxLength->GetValue()); + + if (oox_cond_databar->m_oMinLength.IsInit()) + ods_context->current_table()->set_conditional_databar_min(oox_cond_databar->m_oMinLength->GetValue()); + for (size_t i=0; i< oox_cond_databar->m_arrValues.size(); i++) convert(oox_cond_databar->m_arrValues[i].GetPointer()); } diff --git a/OdfFile/Writer/Converter/XlsxConverter.h b/OdfFile/Writer/Converter/XlsxConverter.h index 39a268bfff5..1266979c112 100644 --- a/OdfFile/Writer/Converter/XlsxConverter.h +++ b/OdfFile/Writer/Converter/XlsxConverter.h @@ -233,8 +233,10 @@ namespace Oox2Odf void convert(OOX::Spreadsheet::CSheetProtection *oox_prot); void convert(OOX::Spreadsheet::CDataValidations *oox_validations); void convert(OOX::Spreadsheet::CDataValidation *oox_validation); - void convert(OOX::Spreadsheet::CConditionalFormatting *oox_cond_fmt); - void convert(OOX::Spreadsheet::CConditionalFormattingRule *oox_cond_rule); + void convert(OOX::Spreadsheet::CConditionalFormatting *oox_cond_fmtc, + std::map& mapCFRuleEx, bool isExt); + void convert(OOX::Spreadsheet::CConditionalFormattingRule *oox_cond_rule, + std::map& mapCFRuleEx, bool isExt); void convert(OOX::Spreadsheet::CAutofilter *oox_filter); void convert(OOX::Spreadsheet::CFilterColumn *oox_filter_column); void convert(OOX::Spreadsheet::CDataBar *oox_cond_databar); diff --git a/OdfFile/Writer/Format/Shapes/odf_shape_mapping.h b/OdfFile/Writer/Format/Shapes/odf_shape_mapping.h index d68c7d66ffa..85001886084 100644 --- a/OdfFile/Writer/Format/Shapes/odf_shape_mapping.h +++ b/OdfFile/Writer/Format/Shapes/odf_shape_mapping.h @@ -62,7 +62,7 @@ namespace cpdoccore { L"" , drawCustom}, // shapetypeAccentCallout1, { L"" , drawCustom}, // shapetypeAccentCallout2, { L"" , drawCustom}, // shapetypeAccentCallout3, - { L"actionButtonBackPrevious" , drawCustom}, // shapetypeActionButtonBackPrevious, //mso-spt194 + { L"mso-spt194" , drawCustom}, // shapetypeActionButtonBackPrevious, { L"mso-spt196" , drawCustom}, // shapetypeActionButtonBeginning, { L"mso-spt189" , drawCustom}, // shapetypeActionButtonBlank, { L"mso-spt198" , drawCustom}, // shapetypeActionButtonDocument, @@ -72,7 +72,7 @@ namespace cpdoccore { L"mso-spt190" , drawCustom}, // shapetypeActionButtonHome, { L"mso-spt192" , drawCustom}, // shapetypeActionButtonInformation, { L"mso-spt200" , drawCustom}, // shapetypeActionButtonMovie, - { L"mso-spt19drawCustom" , drawCustom}, // shapetypeActionButtonReturn, + { L"mso-spt197" , drawCustom}, // shapetypeActionButtonReturn, { L"mso-spt199" , drawCustom}, // shapetypeActionButtonSound, { L"" , drawCustom}, // shapetypeArc, { L"" , drawCustom}, // shapetypeBentArrow, @@ -243,19 +243,19 @@ namespace cpdoccore { L"" , drawCustom}, // shapetypeWedgeEllipseCallout, { L"" , drawCustom}, // shapetypeWedgeRectCallout, { L"" , drawCustom}, // shapetypeWedgeRoundRectCallout, - { L"mso-spt1drawCustom" , drawCustom}, // shapetypeBallon, + { L"mso-spt17" , drawCustom}, // shapetypeBallon, { L"up-right-arrow" , drawCustom}, // shapetypeRightUpArrow, { L"fontwork-arch-down-pour" , drawCustom}, // shapetypeTextArchDownPour, { L"fontwork-arch-up-pour" , drawCustom}, // shapetypeTextArchUpPour, - { L"mso-spt1drawCustom5" , drawCustom}, // shapetypeTextCanDown, - { L"mso-spt1drawCustom4" , drawCustom}, // shapetypeTextCanUp, + { L"mso-spt175" , drawCustom}, // shapetypeTextCanDown, + { L"mso-spt174" , drawCustom}, // shapetypeTextCanUp, { L"fontwork-circle-pour" , drawCustom}, // shapetypeTextCirclePour, { L"fontwork-curve-down" , drawCustom}, // shapetypeTextCurveDown, { L"fontwork-curve-up" , drawCustom}, // shapetypeTextCurveUp, { L"mso-spt161" , drawCustom}, // shapetypeTextDeflate, { L"mso-spt163" , drawCustom}, // shapetypeTextDeflateBottom, { L"mso-spt166" , drawCustom}, // shapetypeTextDeflateInflate, - { L"mso-spt16drawCustom" , drawCustom}, // shapetypeTextDeflateInflateDeflat, + { L"mso-spt167" , drawCustom}, // shapetypeTextDeflateInflateDeflat, { L"mso-spt165" , drawCustom}, // shapetypeTextDeflateTop, { L"mso-spt158" , drawCustom}, // shapetypeTextDoubleWave1, { L"fontwork-fade-down" , drawCustom}, // shapetypeTextFadeDown, @@ -267,7 +267,7 @@ namespace cpdoccore { L"mso-spt142" , drawCustom}, // shapetypeTextRingInside, { L"mso-spt143" , drawCustom}, // shapetypeTextRingOutside, { L"fontwork-wave" , drawCustom}, // shapetypeTextWave1, - { L"mso-spt15drawCustom" , drawCustom}, // shapetypeTextWave2, + { L"mso-spt157" , drawCustom}, // shapetypeTextWave2, { L"mso-spt159" , drawCustom}, // shapetypeTextWave4, { L"mso-spt14" , drawCustom} // shapetypeThickArrow }; diff --git a/OdfFile/Writer/Format/Shapes/oox_shapeArrows.h b/OdfFile/Writer/Format/Shapes/oox_shapeArrows.h index 87df3c2df21..3c8948957c9 100644 --- a/OdfFile/Writer/Format/Shapes/oox_shapeArrows.h +++ b/OdfFile/Writer/Format/Shapes/oox_shapeArrows.h @@ -57,7 +57,7 @@ class oox_shape_LeftArrow : public oox_shape text_areas = L"?f12 ?f8 ?f13 ?f9"; modifiers = L"50000 50000"; view_box = L"0 0 0 0"; - + add(L"f0", L"min(logwidth,logheight)"); add(L"f1", L"100000*logwidth/?f0 "); add(L"f2", L"if(0-$0 ,0,if(100000-$0 ,$0 ,100000))"); @@ -79,12 +79,12 @@ class oox_shape_LeftArrow : public oox_shape h1.position = L"?f13 ?f8"; h1.y_minimum = L"0"; h1.y_maximum = L"100000"; - - handles.push_back(h1); - h2.position = L"?f5 0"; + h2.position = L"?f5 0"; h2.x_minimum = L"0"; h2.x_maximum = L"?f1"; + + handles.push_back(h1); handles.push_back(h2); } }; @@ -95,39 +95,29 @@ class oox_shape_RightArrow : public oox_shape { odf_type_name = L"ooxml-rightArrow"; - enhanced_path = L"M 0 ?f8 L ?f5 ?f8 ?f5 0 ?f14 ?f7 ?f5 ?f13 ?f5 ?f9 0 ?f9 Z N"; - text_areas = L"?f12 ?f8 ?f13 ?f9"; - modifiers = L"50000 50000"; - view_box = L"0 0 0 0"; - - add(L"f0", L"min(logwidth,logheight)"); - add(L"f1", L"100000*logwidth/?f0 "); - add(L"f2", L"if(0-$0 ,0,if(100000-$0 ,$0 ,100000))"); - add(L"f3", L"if(0-$1 ,0,if(?f1 -$1 ,$1 ,?f1 ))"); - add(L"f4", L"?f0 *?f3 /100000"); - add(L"f5", L"logwidth+0-?f4 "); - add(L"f6", L"logheight*?f2 /200000"); - add(L"f7", L"logheight/2"); - add(L"f8", L"?f7 +0-?f6 "); - add(L"f9", L"?f7 +?f6 -0"); - add(L"f10", L"logheight/2"); - add(L"f11", L"?f8 *?f4 /?f10 "); - add(L"f12", L"?f5 +?f11 -0"); - add(L"f13", L"logheight"); - add(L"f14", L"logwidth"); + enhanced_path = L"M 0 ?f0 L ?f1 ?f0 ?f1 0 21600 10800 ?f1 21600 ?f1 ?f2 0 ?f2 Z N"; + text_areas = L"0 ?f0 ?f5 ?f2"; + modifiers = L"10800 5400"; + view_box = L"0 0 21600 21600"; + + add(L"f0", L"$1 "); + add(L"f1", L"$0 "); + add(L"f2", L"21600-$1 "); + add(L"f3", L"21600-?f1 "); + add(L"f4", L"?f3 *?f0 /10800"); + add(L"f5", L"?f1 +?f4 "); + add(L"f6", L"?f1 *?f0 /10800"); + add(L"f7", L"?f1 -?f6 "); ///////////////////////////////////////////////////////// - _handle h1, h2; + _handle h; - h1.position = L"0 ?f8"; - h1.y_minimum = L"0"; - h1.y_maximum = L"100000"; + h.position = L"$0 $1"; + h.x_minimum = L"0"; + h.x_maximum = L"21600"; + h.y_minimum = L"0"; + h.y_maximum = L"10800"; - handles.push_back(h1); - - h2.position = L"?f5 0"; - h2.x_minimum = L"0"; - h2.x_maximum = L"?f1"; - handles.push_back(h2); + handles.push_back(h); } }; class oox_shape_DownArrow : public oox_shape @@ -137,39 +127,30 @@ class oox_shape_DownArrow : public oox_shape { odf_type_name = L"ooxml-downArrow"; - enhanced_path = L"M 0 ?f5 L ?f8 ?f5 ?f8 0 ?f9 0 ?f9 ?f5 ?f14 ?f5 ?f7 ?f13 Z N"; - text_areas = L"?f8 0 ?f9 ?f12"; - modifiers = L"50000 50000"; - view_box = L"0 0 0 0"; + enhanced_path = L"M ?f0 0 L ?f0 ?f1 0 ?f1 10800 21600 21600 ?f1 ?f2 ?f1 ?f2 0 Z N"; + text_areas = L"?f0 0 ?f2 ?f5"; + modifiers = L"11405 5400"; + view_box = L"0 0 21600 21600"; - add(L"f0", L"min(logwidth,logheight)"); - add(L"f1", L"100000*logheight/?f0 "); - add(L"f2", L"if(0-$0 ,0,if(100000-$0 ,$0 ,100000))"); - add(L"f3", L"if(0-$1 ,0,if(?f1 -$1 ,$1 ,?f1 ))"); - add(L"f4", L"?f0 *?f3 /100000"); - add(L"f5", L"logheight+0-?f4 "); - add(L"f6", L"logwidth*?f2 /200000"); - add(L"f7", L"logwidth/2"); - add(L"f8", L"?f7 +0-?f6 "); - add(L"f9", L"?f7 +?f6 -0"); - add(L"f10", L"logwidth/2"); - add(L"f11", L"?f8 *?f4 /?f10 "); - add(L"f12", L"?f5 +?f11 -0"); - add(L"f13", L"logheight"); - add(L"f14", L"logwidth"); + add(L"f0", L"$1 "); + add(L"f1", L"$0 "); + add(L"f2", L"21600-$1 "); + add(L"f3", L"21600-?f1 "); + add(L"f4", L"?f3 *?f0 /10800"); + add(L"f5", L"?f1 +?f4 "); + add(L"f6", L"?f1 *?f0 /10800"); + add(L"f7", L"?f1 -?f6 "); + ///////////////////////////////////////////////////////// - _handle h1, h2; + _handle h; - h1.position = L"?f8 0"; - h1.y_minimum = L"0"; - h1.y_maximum = L"100000"; + h.position = L"$0 $1"; + h.x_minimum = L"0"; + h.x_maximum = L"21600"; + h.y_minimum = L"0"; + h.y_maximum = L"10800"; - handles.push_back(h1); - - h2.position = L"0 ?f5"; - h2.x_minimum = L"0"; - h2.x_maximum = L"?f1"; - handles.push_back(h2); + handles.push_back(h); } }; class oox_shape_UpArrow : public oox_shape @@ -179,39 +160,29 @@ class oox_shape_UpArrow : public oox_shape { odf_type_name = L"ooxml-upArrow"; - enhanced_path = L"M 0 ?f5 L ?f7 0 ?f14 ?f5 ?f9 ?f5 ?f9 ?f13 ?f8 ?f13 ?f8 ?f5 Z N"; - text_areas = L"?f8 ?f12 ?f9 ?f13"; - modifiers = L"50000 50000"; - view_box = L"0 0 0 0"; + enhanced_path = L"M ?f0 21600 L ?f0 ?f1 0 ?f1 10800 0 21600 ?f1 ?f2 ?f1 ?f2 21600 Z N"; + text_areas = L"?f0 ?f7 ?f2 21600"; + modifiers = L"9450 5400"; + view_box = L"0 0 21600 21600"; - add(L"f0", L"min(logwidth,logheight)"); - add(L"f1", L"100000*logheight/?f0 "); - add(L"f2", L"if(0-$0 ,0,if(100000-$0 ,$0 ,100000))"); - add(L"f3", L"if(0-$1 ,0,if(?f1 -$1 ,$1 ,?f1 ))"); - add(L"f4", L"?f0 *?f3 /100000"); - add(L"f5", L"0+?f4 -0"); - add(L"f6", L"logwidth*?f2 /200000"); - add(L"f7", L"logwidth/2"); - add(L"f8", L"?f7 +0-?f6 "); - add(L"f9", L"?f7 +?f6 -0"); - add(L"f10", L"logwidth/2"); - add(L"f11", L"?f8 *?f4 /?f10 "); - add(L"f12", L"?f5 +0-?f11 "); - add(L"f13", L"logheight"); - add(L"f14", L"logwidth"); + add(L"f0", L"$1 "); + add(L"f1", L"$0 "); + add(L"f2", L"21600-$1 "); + add(L"f3", L"21600-?f1 "); + add(L"f4", L"?f3 *?f0 /10800"); + add(L"f5", L"?f1 +?f4 "); + add(L"f6", L"?f1 *?f0 /10800"); + add(L"f7", L"?f1 -?f6 "); ///////////////////////////////////////////////////////// - _handle h1, h2; + _handle h; - h1.position = L"?f8 ?f13"; - h1.x_minimum = L"0"; - h1.x_maximum = L"100000"; + h.position = L"$0 $1"; + h.x_minimum = L"0"; + h.x_maximum = L"21600"; + h.y_minimum = L"0"; + h.y_maximum = L"10800"; - handles.push_back(h1); - - h2.position = L"0 ?f5"; - h2.y_minimum = L"0"; - h2.y_maximum = L"?f1"; - handles.push_back(h2); + handles.push_back(h); } }; class oox_shape_LeftRightArrow : public oox_shape diff --git a/OdfFile/Writer/Format/Shapes/oox_shapeCallouts.h b/OdfFile/Writer/Format/Shapes/oox_shapeCallouts.h index 6845f5e1e94..0bce8878567 100644 --- a/OdfFile/Writer/Format/Shapes/oox_shapeCallouts.h +++ b/OdfFile/Writer/Format/Shapes/oox_shapeCallouts.h @@ -404,7 +404,8 @@ class oox_shape_WedgeRectCallout : public oox_shape view_box = L"0 0 21600 21600"; modifiers = L"6300 24300"; glue_points = L"?f40 ?f41"; - + glue_points_leaving_directions = L"180"; + add(L"f0", L"$0 -10800"); add(L"f1", L"$1 -10800"); add(L"f2", L"if(?f18 ,$0 ,0)"); diff --git a/OdfFile/Writer/Format/Shapes/oox_shapeMaths.h b/OdfFile/Writer/Format/Shapes/oox_shapeMaths.h index 6cff140db58..5db2e50c8f5 100644 --- a/OdfFile/Writer/Format/Shapes/oox_shapeMaths.h +++ b/OdfFile/Writer/Format/Shapes/oox_shapeMaths.h @@ -314,33 +314,34 @@ class oox_shape_mathPlus : public oox_shape { odf_type_name =L"ooxml-mathPlus"; - enhanced_path = L"M ?f6 ?f12 L ?f7 ?f12 ?f7 ?f11 ?f8 ?f11 ?f8 ?f12 ?f9 ?f12 ?f9 ?f13 ?f8 ?f13 ?f8 ?f14 ?f7 ?f14 ?f7 ?f13 ?f6 ?f13 Z N"; - text_areas = L"?f6 ?f12 ?f9 ?f13"; - view_box = L"0 0 0 0"; + enhanced_path = L"M ?f15 ?f20 L ?f16 ?f20 ?f16 ?f19 ?f17 ?f19 ?f17 ?f20 ?f18 ?f20 ?f18 ?f21 ?f17 ?f21 ?f17 ?f22 ?f16 ?f22 ?f16 ?f21 ?f15 ?f21 Z N"; + text_areas = L"?f15 ?f20 ?f18 ?f21"; + view_box = L"0 0 21600 21600"; modifiers = L"23520"; - add(L"f0", L"if(0-$0 ,0,if(73490-$0 ,$0 ,73490))"); - add(L"f1", L"logwidth*73490/200000"); - add(L"f2", L"logheight*73490/200000"); - add(L"f3", L"min(logwidth,logheight)"); - add(L"f4", L"?f3 *?f0 /200000"); - add(L"f5", L"logwidth/2"); - add(L"f6", L"?f5 +0-?f1 "); - add(L"f7", L"?f5 +0-?f4 "); - add(L"f8", L"?f5 +?f4 -0"); - add(L"f9", L"?f5 +?f1 -0"); - add(L"f10", L"logheight/2"); - add(L"f11", L"?f10 +0-?f2 "); - add(L"f12", L"?f10 +0-?f4 "); - add(L"f13", L"?f10 +?f4 -0"); - add(L"f14", L"?f10 +?f2 -0"); - -///////////////////////////////////////////////////////// - _handle h; - h.position = L"0 ?f12"; - h.y_maximum= L"73490"; - h.y_minimum= L"0"; - handles.push_back(h); + add(L"f0", L"left"); + add(L"f1", L"right"); + add(L"f2", L"top"); + add(L"f3", L"bottom"); + add(L"f4", L"?f3 - ?f2"); + add(L"f5", L"?f4 / 2"); + add(L"f6", L"?f2 + ?f5"); + add(L"f7", L"?f1 - ?f0"); + add(L"f8", L"?f7 / 2"); + add(L"f9", L"?f0 + ?f8"); + add(L"f10", L"min(?f7, ?f4)"); + add(L"f11", L"$0"); + add(L"f12", L"?f7 * 73490 / 200000"); + add(L"f13", L"?f4 * 73490 / 200000"); + add(L"f14", L"?f10 * ?f11 / 200000"); + add(L"f15", L"?f9 - ?f12"); + add(L"f16", L"?f9 - ?f14"); + add(L"f17", L"?f9 + ?f14"); + add(L"f18", L"?f9 + ?f12"); + add(L"f19", L"?f6 - ?f13"); + add(L"f20", L"?f6 - ?f14"); + add(L"f21", L"?f6 + ?f14"); + add(L"f22", L"?f6 + ?f13"); } }; diff --git a/OdfFile/Writer/Format/Shapes/oox_shapePrimitives.h b/OdfFile/Writer/Format/Shapes/oox_shapePrimitives.h index 0921330a14c..939f4e39568 100644 --- a/OdfFile/Writer/Format/Shapes/oox_shapePrimitives.h +++ b/OdfFile/Writer/Format/Shapes/oox_shapePrimitives.h @@ -1347,28 +1347,29 @@ class oox_shape_Triangle : public oox_shape public: oox_shape_Triangle() { - odf_type_name =L"ooxml-triangle"; + odf_type_name =L"isosceles-triangle"; - enhanced_path = L"M 0 ?f6 L ?f2 0 ?f7 ?f6 Z N"; - text_areas = L"?f1 ?f5 ?f4 ?f6"; - view_box = L"0 0 0 0"; - modifiers = L"50000"; + enhanced_path = L"M ?f0 0 L 21600 21600 0 21600 Z N"; + text_areas = L"?f1 10800 ?f2 18000 ?f3 7200 ?f4 21600"; + view_box = L"0 0 21600 21600"; + modifiers = L"10800"; + glue_points = L"?f0 0 ?f1 10800 0 21600 10800 21600 21600 21600 ?f7 10800"; - add(L"f0", L"if(0-$0 ,0,if(100000-$0 ,$0 ,100000))"); - add(L"f1", L"logwidth*?f0 /200000"); - add(L"f2", L"logwidth*?f0 /100000"); - add(L"f3", L"logwidth/2"); - add(L"f4", L"?f1 +?f3 -0"); - add(L"f5", L"logheight/2"); - add(L"f6", L"logheight"); - add(L"f7", L"logwidth"); + add(L"f0", L"$0 "); + add(L"f1", L"$0 /2"); + add(L"f2", L"?f1 +10800"); + add(L"f3", L"$0 *2/3"); + add(L"f4", L"?f3 +7200"); + add(L"f5", L"21600-?f0 "); + add(L"f6", L"?f5 /2"); + add(L"f7", L"21600-?f6 "); ///////////////////////////////////////////////////////// _handle h; - h.position = L"?f2 0"; + h.position = L"$0 top"; h.x_minimum = L"0"; - h.x_maximum = L"100000"; + h.x_maximum = L"21600"; handles.push_back(h); } }; diff --git a/OdfFile/Writer/Format/Shapes/oox_shapeSnipRoundRects.h b/OdfFile/Writer/Format/Shapes/oox_shapeSnipRoundRects.h index 1aa7048e1aa..e58a3fb1633 100644 --- a/OdfFile/Writer/Format/Shapes/oox_shapeSnipRoundRects.h +++ b/OdfFile/Writer/Format/Shapes/oox_shapeSnipRoundRects.h @@ -724,39 +724,33 @@ class oox_shape_roundRect : public oox_shape public: oox_shape_roundRect() { - odf_type_name =L"ooxml-roundRect"; + odf_type_name =L"round-rectangle"; - enhanced_path = L"M 0 ?f2 G ?f2 ?f2 ?f12 ?f13 L ?f3 0 G ?f2 ?f2 ?f14 ?f15 L ?f11 ?f4 G ?f2 ?f2 ?f16 ?f17 L ?f2 ?f10 G ?f2 ?f2 ?f18 ?f19 Z N"; - text_areas = L"?f5 ?f5 ?f6 ?f7"; - view_box = L"0 0 0 0"; - modifiers = L"16667"; + enhanced_path = L"M ?f7 0 X 0 ?f8 L 0 ?f9 Y ?f7 21600 L ?f10 21600 X 21600 ?f9 L 21600 ?f8 Y ?f10 0 Z N"; + text_areas = L"?f3 ?f4 ?f5 ?f6"; + view_box = L"0 0 21600 21600"; + modifiers = L"3600"; + path_stretchpoint_x = L"10800"; + path_stretchpoint_y = L"10800"; - add(L"f0", L"if(0-$0 ,0,if(50000-$0 ,$0 ,50000))"); - add(L"f1", L"min(logwidth,logheight)"); - add(L"f2", L"?f1 *?f0 /100000"); - add(L"f3", L"logwidth+0-?f2 "); - add(L"f4", L"logheight+0-?f2 "); - add(L"f5", L"?f2 *29289/100000"); - add(L"f6", L"logwidth+0-?f5 "); - add(L"f7", L"logheight+0-?f5 "); - add(L"f8", L"logwidth/2"); - add(L"f9", L"logheight/2"); - add(L"f10", L"logheight"); - add(L"f11", L"logwidth"); - add(L"f12", L"(10800000)/60000.0"); - add(L"f13", L"(5400000)/60000.0"); - add(L"f14", L"(16200000)/60000.0"); - add(L"f15", L"(5400000)/60000.0"); - add(L"f16", L"(0)/60000.0"); - add(L"f17", L"(5400000)/60000.0"); - add(L"f18", L"(5400000)/60000.0"); - add(L"f19", L"(5400000)/60000.0"); + add(L"f0", L"45"); + add(L"f1", L"$0 *sin(?f0 *(pi/180))"); + add(L"f2", L"?f1 *3163/7636 "); + add(L"f3", L"left+?f2 "); + add(L"f4", L"top+?f2 "); + add(L"f5", L"right-?f2 "); + add(L"f6", L"bottom-?f2 "); + add(L"f7", L"left+$0 "); + add(L"f8", L"top+$0 "); + add(L"f9", L"bottom-$0 "); + add(L"f10", L"right-$0 "); //----------------------------------------------------------------- _handle h1; - h1.position = L"?f2 0"; - h1.x_maximum= L"50000"; - h1.x_minimum= L"0"; + h1.position = L"$0 top"; + h1.x_minimum = L"0"; + h1.x_maximum = L"10800"; + h1.handle_swiched = true; handles.push_back(h1); } }; diff --git a/OdfFile/Writer/Format/anim_elements.cpp b/OdfFile/Writer/Format/anim_elements.cpp index 6cced1420a1..76a78597361 100644 --- a/OdfFile/Writer/Format/anim_elements.cpp +++ b/OdfFile/Writer/Format/anim_elements.cpp @@ -64,7 +64,7 @@ void anim_par::add_child_element( const office_element_ptr & child_element) ElementType type_ = child_element->get_type(); if (type_ == typeAnimPar) - anim_par_ = child_element; + anim_par_.push_back(child_element); else if (type_ == typeAnimSeq) anim_seq_array_.push_back(child_element); else @@ -77,10 +77,13 @@ void anim_par::serialize(std::wostream & _Wostream) CP_XML_NODE_SIMPLE() { attlist_.serialize(CP_GET_XML_NODE()); + par_attlist_.serialize(CP_GET_XML_NODE()); + + for (size_t i = 0; i < anim_par_.size(); i++) + { + anim_par_[i]->serialize(CP_XML_STREAM()); + } - if (anim_par_) - anim_par_->serialize(CP_XML_STREAM()); - for (size_t i = 0; i < anim_seq_array_.size(); i++) { anim_seq_array_[i]->serialize(CP_XML_STREAM()); @@ -122,19 +125,6 @@ void anim_seq::add_child_element( const office_element_ptr & child) anim_par_array_.push_back(child); } //////////////////////////////////////////////////////////////// -void anim_transition_filter_attlist::serialize(CP_ATTR_NODE) -{ - CP_XML_ATTR_OPT(L"smil:subtype", smil_subtype_); - CP_XML_ATTR_OPT(L"smil:type", smil_type_); - CP_XML_ATTR_OPT(L"smil:fadeColor", smil_fadeColor_); - CP_XML_ATTR_OPT(L"smil:mode", smil_mode_); - -} -void anim_audio_attlist::serialize(CP_ATTR_NODE) -{ - CP_XML_ATTR_OPT_ENCODE_STRING(L"xlink:href", xlink_href_); - CP_XML_ATTR_OPT(L"anim:audio-level",anim_audio_level_); -} const wchar_t * anim_transitionFilter::ns = L"anim"; const wchar_t * anim_transitionFilter::name = L"transitionFilter"; @@ -164,6 +154,83 @@ void anim_audio::serialize(std::wostream & _Wostream) } } } +//------------------------------------------------------------------------------------------------ +const wchar_t* anim_set::ns = L"anim"; +const wchar_t* anim_set::name = L"set"; + +void anim_set::serialize(std::wostream& _Wostream) +{ + CP_XML_WRITER(_Wostream) + { + CP_XML_NODE_SIMPLE() + { + common_attlist_.serialize(CP_GET_XML_NODE()); + set_attlist_.serialize(CP_GET_XML_NODE()); + } + } +} +//------------------------------------------------------------------------------------------------ +const wchar_t* anim_animate::ns = L"anim"; +const wchar_t* anim_animate::name = L"animate"; + +void anim_animate::serialize(std::wostream& _Wostream) +{ + CP_XML_WRITER(_Wostream) + { + CP_XML_NODE_SIMPLE() + { + common_attlist_.serialize(CP_GET_XML_NODE()); + animate_attlist_.serialize(CP_GET_XML_NODE()); + } + } +} +//------------------------------------------------------------------------------------------------ +const wchar_t* anim_animate_motion::ns = L"anim"; +const wchar_t* anim_animate_motion::name = L"animateMotion"; + +void anim_animate_motion::serialize(std::wostream& _Wostream) +{ + CP_XML_WRITER(_Wostream) + { + CP_XML_NODE_SIMPLE() + { + common_attlist_.serialize(CP_GET_XML_NODE()); + animate_motion_attlist_.serialize(CP_GET_XML_NODE()); + } + } +} + +//------------------------------------------------------------------------------------------------ +const wchar_t* anim_animate_color::ns = L"anim"; +const wchar_t* anim_animate_color::name = L"animateColor"; + +void anim_animate_color::serialize(std::wostream& _Wostream) +{ + CP_XML_WRITER(_Wostream) + { + CP_XML_NODE_SIMPLE() + { + common_attlist_.serialize(CP_GET_XML_NODE()); + color_attlist_.serialize(CP_GET_XML_NODE()); + } + } +} + +//------------------------------------------------------------------------------------------------ +const wchar_t* anim_animate_transform::ns = L"anim"; +const wchar_t* anim_animate_transform::name = L"animateTransform"; + +void anim_animate_transform::serialize(std::wostream& _Wostream) +{ + CP_XML_WRITER(_Wostream) + { + CP_XML_NODE_SIMPLE() + { + common_attlist_.serialize(CP_GET_XML_NODE()); + animate_transform_attlist_.serialize(CP_GET_XML_NODE()); + } + } +} } } diff --git a/OdfFile/Writer/Format/anim_elements.h b/OdfFile/Writer/Format/anim_elements.h index ff5dd23306b..e19bd1e2479 100644 --- a/OdfFile/Writer/Format/anim_elements.h +++ b/OdfFile/Writer/Format/anim_elements.h @@ -39,7 +39,7 @@ #include "office_elements_create.h" #include "../../DataTypes/common_attlists.h" -#include "../../DataTypes/smil_transitiontype.h" +#include "../../DataTypes/animation_attlists.h" namespace cpdoccore { namespace odf_writer { @@ -54,7 +54,8 @@ class anim_par : public office_element_impl//Параллельные odf_types::common_anim_smil_attlist attlist_; - office_element_ptr anim_par_; + odf_types::anim_par_attlist par_attlist_; + office_element_ptr_array anim_par_; office_element_ptr_array anim_seq_array_; office_element_ptr_array content_; @@ -85,26 +86,6 @@ CP_REGISTER_OFFICE_ELEMENT2(anim_seq); /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //anim:iterate -class anim_audio_attlist -{ -public: - void serialize(CP_ATTR_NODE); - - _CP_OPT(std::wstring) xlink_href_; - _CP_OPT(std::wstring) anim_audio_level_; -}; - -class anim_transition_filter_attlist -{ -public: - void serialize(CP_ATTR_NODE); - - _CP_OPT(std::wstring) smil_subtype_; - _CP_OPT(odf_types::smil_transition_type) smil_type_; - _CP_OPT(std::wstring) smil_mode_; - _CP_OPT(odf_types::color) smil_fadeColor_; -}; - class anim_transitionFilter : public office_element_impl { @@ -120,8 +101,8 @@ class anim_transitionFilter : public office_element_impl virtual void serialize(std::wostream & strm); /////////////////////////////////////////////////////////// - odf_types::common_anim_smil_attlist common_attlist_; - anim_transition_filter_attlist filter_attlist_; + odf_types::common_anim_smil_attlist common_attlist_; + odf_types::anim_transition_filter_attlist filter_attlist_; }; CP_REGISTER_OFFICE_ELEMENT2(anim_transitionFilter); @@ -140,10 +121,110 @@ class anim_audio : public office_element_impl virtual void serialize(std::wostream & strm); /////////////////////////////////////////////////////////// odf_types::common_anim_smil_attlist common_attlist_; - anim_audio_attlist audio_attlist_; + odf_types::anim_audio_attlist audio_attlist_; }; CP_REGISTER_OFFICE_ELEMENT2(anim_audio); //anim:command +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//anim:set +class anim_set : public office_element_impl +{ +public: + static const wchar_t* ns; + static const wchar_t* name; + + static const ElementType type = typeAnimSet; + + virtual void create_child_element(const std::wstring& Ns, const std::wstring& Name) {} + virtual void add_child_element(const office_element_ptr& child) {} + + virtual void serialize(std::wostream& strm); +/////////////////////////////////////////////////////////// + odf_types::common_anim_smil_attlist common_attlist_; + odf_types::anim_set_attlist set_attlist_; +}; +CP_REGISTER_OFFICE_ELEMENT2(anim_set); + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//anim:animate +class anim_animate : public office_element_impl +{ +public: + static const wchar_t* ns; + static const wchar_t* name; + + static const ElementType type = typeAnimAnimate; + + virtual void create_child_element(const std::wstring& Ns, const std::wstring& Name) {} + virtual void add_child_element(const office_element_ptr& child) {} + + virtual void serialize(std::wostream& strm); + + odf_types::common_anim_smil_attlist common_attlist_; + odf_types::anim_animate_attlist animate_attlist_; +}; +CP_REGISTER_OFFICE_ELEMENT2(anim_animate); + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// anim:animateMotion +class anim_animate_motion : public office_element_impl +{ +public: + static const wchar_t* ns; + static const wchar_t* name; + + static const ElementType type = typeAnimAnimateMotion; + + virtual void create_child_element(const std::wstring& Ns, const std::wstring& Name) {} + virtual void add_child_element(const office_element_ptr& child) {} + + virtual void serialize(std::wostream& strm); + + odf_types::common_anim_smil_attlist common_attlist_; + odf_types::anim_animate_motion_attlist animate_motion_attlist_; +}; +CP_REGISTER_OFFICE_ELEMENT2(anim_animate_motion); + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// anim:animateColor +class anim_animate_color: public office_element_impl +{ +public: + static const wchar_t* ns; + static const wchar_t* name; + + static const ElementType type = typeAnimAnimateColor; + + virtual void create_child_element(const std::wstring& Ns, const std::wstring& Name) {} + virtual void add_child_element(const office_element_ptr& child) {} + + virtual void serialize(std::wostream& strm); + + odf_types::common_anim_smil_attlist common_attlist_; + odf_types::anim_animate_color_attlist color_attlist_; +}; +CP_REGISTER_OFFICE_ELEMENT2(anim_animate_color); + +////////////////////////////////////////////////////////////////////////// +// anim:animateTransform +class anim_animate_transform : public office_element_impl +{ +public: + static const wchar_t* ns; + static const wchar_t* name; + + static const ElementType type = typeAnimAnimateTransform; + + virtual void create_child_element(const std::wstring& Ns, const std::wstring& Name) {} + virtual void add_child_element(const office_element_ptr& child) {} + + virtual void serialize(std::wostream& strm); + + odf_types::common_anim_smil_attlist common_attlist_; + odf_types::anim_animate_transform_attlist animate_transform_attlist_; +}; +CP_REGISTER_OFFICE_ELEMENT2(anim_animate_transform); + } } diff --git a/OdfFile/Writer/Format/calcext_elements.cpp b/OdfFile/Writer/Format/calcext_elements.cpp index 406b4015436..2e2fda1e7a6 100644 --- a/OdfFile/Writer/Format/calcext_elements.cpp +++ b/OdfFile/Writer/Format/calcext_elements.cpp @@ -44,10 +44,13 @@ namespace odf_writer { void calcext_data_bar_attr::serialize(CP_ATTR_NODE) { - CP_XML_ATTR_OPT(L"calcext:axis-color", calcext_axis_color_); - CP_XML_ATTR_OPT(L"calcext:positive-color", calcext_positive_color_); - CP_XML_ATTR_OPT(L"calcext:negative-color", calcext_negative_color_); - CP_XML_ATTR_OPT(L"calcext:axis-position", calcext_axis_position_); + CP_XML_ATTR_OPT(L"calcext:axis-color", axis_color_); + CP_XML_ATTR_OPT(L"calcext:positive-color", positive_color_); + CP_XML_ATTR_OPT(L"calcext:negative-color", negative_color_); + CP_XML_ATTR_OPT(L"calcext:axis-position", axis_position_); + CP_XML_ATTR_OPT(L"calcext:gradient", gradient_); + CP_XML_ATTR_OPT(L"calcext:min-length", min_length_); + CP_XML_ATTR_OPT(L"calcext:max-length", max_length_); } void calcext_icon_set_attr::serialize(CP_ATTR_NODE) @@ -60,6 +63,7 @@ void calcext_condition_attr::serialize(CP_ATTR_NODE) CP_XML_ATTR_OPT_ENCODE_STRING(L"calcext:base-cell-address", calcext_base_cell_address_); CP_XML_ATTR_OPT(L"calcext:apply-style-name", calcext_apply_style_name_); CP_XML_ATTR_OPT_ENCODE_STRING(L"calcext:value", calcext_value_); + CP_XML_ATTR_OPT(L"loext:stdDev", loext_stdDev_); } void calcext_date_is_attr::serialize(CP_ATTR_NODE) { @@ -235,7 +239,7 @@ void calcext_icon_set::serialize(std::wostream & _Wostream) } } -// calcext_formatting_entry +// calcext:formatting-entry ////////////////////////////////////////////////////////////////////////////////////////////////// const wchar_t * calcext_formatting_entry::ns = L"calcext"; const wchar_t * calcext_formatting_entry::name = L"formatting-entry"; diff --git a/OdfFile/Writer/Format/calcext_elements.h b/OdfFile/Writer/Format/calcext_elements.h index 593e0a60185..9885064689b 100644 --- a/OdfFile/Writer/Format/calcext_elements.h +++ b/OdfFile/Writer/Format/calcext_elements.h @@ -56,10 +56,13 @@ class calcext_data_bar_attr public: void serialize(CP_ATTR_NODE); - _CP_OPT(odf_types::color) calcext_axis_color_; - _CP_OPT(odf_types::color) calcext_positive_color_; - _CP_OPT(odf_types::color) calcext_negative_color_; - _CP_OPT(std::wstring) calcext_axis_position_; + _CP_OPT(odf_types::color) axis_color_; + _CP_OPT(odf_types::color) positive_color_; + _CP_OPT(odf_types::color) negative_color_; + _CP_OPT(std::wstring) axis_position_; + _CP_OPT(odf_types::Bool) gradient_; + _CP_OPT(unsigned int) min_length_; + _CP_OPT(unsigned int) max_length_; }; class calcext_condition_attr @@ -70,7 +73,7 @@ class calcext_condition_attr _CP_OPT(std::wstring) calcext_base_cell_address_; _CP_OPT(std::wstring) calcext_apply_style_name_; _CP_OPT(std::wstring) calcext_value_; - + _CP_OPT(int) loext_stdDev_; }; class calcext_icon_set_attr { diff --git a/OdfFile/Writer/Format/draw_base.cpp b/OdfFile/Writer/Format/draw_base.cpp index de6243b62ac..14d2d0c21b4 100644 --- a/OdfFile/Writer/Format/draw_base.cpp +++ b/OdfFile/Writer/Format/draw_base.cpp @@ -71,6 +71,8 @@ void draw_base::serialize(std::wostream & strm) } void draw_base::serialize_attlist(CP_ATTR_NODE) { + CP_XML_ATTR_OPT(L"xml:id", xml_id_); + CP_XML_ATTR_OPT(L"draw:id", xml_id_); common_draw_attlists_.serialize(CP_GET_XML_NODE()); } diff --git a/OdfFile/Writer/Format/draw_base.h b/OdfFile/Writer/Format/draw_base.h index d42e7d9b18f..6ddace82a0b 100644 --- a/OdfFile/Writer/Format/draw_base.h +++ b/OdfFile/Writer/Format/draw_base.h @@ -57,7 +57,8 @@ class draw_base : public office_element_impl virtual void serialize(std::wostream & _Wostream); virtual void serialize_attlist(CP_ATTR_NODE); - odf_types::union_common_draw_attlists common_draw_attlists_; + odf_types::union_common_draw_attlists common_draw_attlists_; + _CP_OPT(std::wstring) xml_id_; office_element_ptr_array content_; }; diff --git a/OdfFile/Writer/Format/draw_frame.cpp b/OdfFile/Writer/Format/draw_frame.cpp index a95f678c097..3f09673d571 100644 --- a/OdfFile/Writer/Format/draw_frame.cpp +++ b/OdfFile/Writer/Format/draw_frame.cpp @@ -170,6 +170,9 @@ void draw_g::serialize(std::wostream & _Wostream) common_draw_attlists_.shape_with_text_and_styles_.common_shape_draw_attlist_.draw_name_ = L""; //брееед ... иначе либра не показывает группу!!! + CP_XML_ATTR_OPT(L"xml:id", xml_id_); + CP_XML_ATTR_OPT(L"draw:id", xml_id_); + common_draw_attlists_.serialize(CP_GET_XML_NODE()); for (size_t i = 0; i < content_.size(); i++) diff --git a/OdfFile/Writer/Format/draw_frame.h b/OdfFile/Writer/Format/draw_frame.h index f990832887c..b80e7ff524e 100644 --- a/OdfFile/Writer/Format/draw_frame.h +++ b/OdfFile/Writer/Format/draw_frame.h @@ -155,7 +155,8 @@ class draw_g : public office_element_impl virtual void serialize(std::wostream & _Wostream); - odf_types::union_common_draw_attlists common_draw_attlists_; + odf_types::union_common_draw_attlists common_draw_attlists_; + _CP_OPT(std::wstring) xml_id_; office_element_ptr_array content_; }; diff --git a/OdfFile/Writer/Format/draw_page.cpp b/OdfFile/Writer/Format/draw_page.cpp index 174db936a79..5f89d19407b 100644 --- a/OdfFile/Writer/Format/draw_page.cpp +++ b/OdfFile/Writer/Format/draw_page.cpp @@ -88,14 +88,27 @@ void draw_page::serialize(std::wostream & _Wostream) { CP_XML_NODE_SIMPLE() { + office_element_ptr_array deffer_serialization; + attlist_.serialize(CP_GET_XML_NODE()); for (int i = 0; i < content_.size(); i++) { + presentation_notes* presentation_notes_ = dynamic_cast(content_[i].get()); + + if (presentation_notes_) + { + deffer_serialization.push_back(content_[i]); + continue; + } + content_[i]->serialize(CP_XML_STREAM()); } if (animation_) animation_->serialize(CP_XML_STREAM()); + + for (size_t i = 0; i < deffer_serialization.size(); i++) + deffer_serialization[i]->serialize(CP_XML_STREAM()); } } } diff --git a/OdfFile/Writer/Format/draw_shapes.cpp b/OdfFile/Writer/Format/draw_shapes.cpp index 3497666ec3c..49b8c3dc913 100644 --- a/OdfFile/Writer/Format/draw_shapes.cpp +++ b/OdfFile/Writer/Format/draw_shapes.cpp @@ -428,6 +428,7 @@ void draw_enhanced_geometry_attlist::serialize(CP_ATTR_NODE) //CP_XML_ATTR_OPT(L"drawooo:enhanced-path", draw_enhanced_path_); CP_XML_ATTR_OPT(L"draw:enhanced-path", draw_enhanced_path_); CP_XML_ATTR_OPT(L"draw:glue-points", draw_glue_points_); + CP_XML_ATTR_OPT(L"draw:glue-point-leaving-directions", glue_points_leaving_directions_); CP_XML_ATTR_OPT(L"draw:mirror-vertical", draw_mirror_vertical_); CP_XML_ATTR_OPT(L"draw:mirror-horizontal", draw_mirror_horizontal_); @@ -435,6 +436,9 @@ void draw_enhanced_geometry_attlist::serialize(CP_ATTR_NODE) CP_XML_ATTR_OPT(L"draw:text-path-mode", draw_text_path_mode_); CP_XML_ATTR_OPT(L"draw:text-path-scale", draw_text_path_scale_); CP_XML_ATTR_OPT(L"draw:text-path-same-letter-heights", draw_text_path_same_letter_heights_); + + CP_XML_ATTR_OPT(L"draw:path-stretchpoint-x", draw_path_stretchpoint_x_); + CP_XML_ATTR_OPT(L"draw:path-stretchpoint-y", draw_path_stretchpoint_y_); } //------------------------------------------------------------------------------------------- // draw:enhanced_geometry diff --git a/OdfFile/Writer/Format/draw_shapes.h b/OdfFile/Writer/Format/draw_shapes.h index e1e0199d35a..de272fb8e2d 100644 --- a/OdfFile/Writer/Format/draw_shapes.h +++ b/OdfFile/Writer/Format/draw_shapes.h @@ -47,19 +47,14 @@ class draw_shape : public draw_base static const ElementType type = typeDrawShape; - virtual void serialize(std::wostream & _Wostream); virtual void serialize_attlist(CP_ATTR_NODE); odf_types::common_xlink_attlist common_xlink_attlist_; _CP_OPT(std::wstring) draw_id_;//используется для анимашек - - - int sub_type_; - }; //---------------------------------------------------------------------------------------------- class draw_rect_attlist @@ -316,7 +311,8 @@ class draw_enhanced_geometry_attlist _CP_OPT(std::wstring) draw_enhanced_path_; _CP_OPT(std::wstring) draw_text_areas_; _CP_OPT(std::wstring) draw_glue_points_; - + _CP_OPT(std::wstring) glue_points_leaving_directions_; + _CP_OPT(std::wstring) draw_sub_view_size_; _CP_OPT(odf_types::Bool) draw_mirror_vertical_; @@ -328,6 +324,9 @@ class draw_enhanced_geometry_attlist _CP_OPT(std::wstring) draw_text_path_scale_; _CP_OPT(int) draw_text_rotate_angle_; + + _CP_OPT(std::wstring) draw_path_stretchpoint_x_; + _CP_OPT(std::wstring) draw_path_stretchpoint_y_; void serialize(CP_ATTR_NODE); }; diff --git a/OdfFile/Writer/Format/odf_chart_context.cpp b/OdfFile/Writer/Format/odf_chart_context.cpp index 36a56058972..9e07bf202b6 100644 --- a/OdfFile/Writer/Format/odf_chart_context.cpp +++ b/OdfFile/Writer/Format/odf_chart_context.cpp @@ -642,6 +642,11 @@ void odf_chart_context::set_view3D(int rotX, int rotY, int depthPercent, int per if (impl_->current_level_.back().chart_properties) { impl_->current_level_.back().chart_properties->right_angled_axes_ = angAx; + + if (!angAx) + { + plot_area->chart_plot_area_attlist_.common_dr3d_attlist_.projection_ = L"perspective"; + } } } } diff --git a/OdfFile/Writer/Format/odf_conversion_context.cpp b/OdfFile/Writer/Format/odf_conversion_context.cpp index c424750ff5a..e0204e020fa 100644 --- a/OdfFile/Writer/Format/odf_conversion_context.cpp +++ b/OdfFile/Writer/Format/odf_conversion_context.cpp @@ -35,6 +35,7 @@ #include "office_spreadsheet.h" #include "office_scripts.h" #include "office_chart.h" +#include "office_meta.h" #include "office_elements_create.h" @@ -56,20 +57,21 @@ namespace odf_writer { namespace utils { - void calculate_size_font_symbols(_font_metrix & metrix, NSFonts::IApplicationFonts *appFonts) { std::pair appr = _graphics_utils_::calculate_size_symbol_asc(metrix.font_name, metrix.font_size, metrix.italic, metrix.bold, appFonts); if (appr.first < 0.01 || appr.second < 0.01) - { - appr.first = _graphics_utils_::calculate_size_symbol_win(metrix.font_name, metrix.font_size, false/*metrix.italic*/, false/*metrix.bold*/); + { + appr = _graphics_utils_::calculate_size_symbol_win(metrix.font_name, metrix.font_size, false/*metrix.italic*/, false/*metrix.bold*/); + appr.first = appr.first = ((int)(appr.first + 0.5) + 2 * (int)appr.first) / 3.; } if (appr.first > 0) { - metrix.approx_symbol_size = (int)appr.first; + metrix.approx_symbol_width = (int)appr.first; + metrix.approx_symbol_height = (int)appr.second; metrix.IsCalc = true; } @@ -109,9 +111,9 @@ void odf_conversion_context::set_fonts_directory(const std::wstring & fontsPath) if (applicationFonts_) applicationFonts_->InitializeFromFolder(fontsPath); } -void odf_conversion_context::calculate_font_metrix(std::wstring name, double size, bool italic, bool bold) +void odf_conversion_context::calculate_font_metrix(std::wstring name, double size, bool italic, bool bold, bool recalc) { - if (font_metrix_.IsCalc) return; + if (font_metrix_.IsCalc && !recalc) return; if (size < 1) size = 12; @@ -131,16 +133,27 @@ double odf_conversion_context::convert_symbol_width(double val, bool add_padding //if (add_padding) { - val = ((int)((val * font_metrix_.approx_symbol_size + 5) / font_metrix_.approx_symbol_size * 256)) / 256.; + val = ((int)((val * font_metrix_.approx_symbol_width + 5) / font_metrix_.approx_symbol_width * 256)) / 256.; } - double pixels = (int)(((256. * val + ((int)(128. / font_metrix_.approx_symbol_size))) / 256.) * font_metrix_.approx_symbol_size); //in pixels + double pixels = (int)(((256. * val + ((int)(128. / font_metrix_.approx_symbol_width))) / 256.) * font_metrix_.approx_symbol_width); //in pixels // to back - //double back = (int((pixels /*/ 0.75*/ - 5) / font_metrix_.approx_symbol_size * 100. + 0.5)) / 100.;// *0.98; // * 9525. * 72.0 / (360000.0 * 2.54); + //double back = (int((pixels /*/ 0.75*/ - 5) / font_metrix_.approx_symbol_width * 100. + 0.5)) / 100.;// *0.98; // * 9525. * 72.0 / (360000.0 * 2.54); return pixels * 0.75; //* 9525. * 72.0 / (360000.0 * 2.54); } + +void odf_conversion_context::add_hyperlink(office_element_ptr& elem, const std::wstring& ref) +{ + hyperlinks_.push_back(std::make_pair(elem, ref)); +} + +std::vector> odf_conversion_context::get_deferred_hyperlinks() +{ + return hyperlinks_; +} + void odf_conversion_context::set_styles_context(odf_style_context_ptr styles_context) { if (!objects_.empty()) @@ -396,7 +409,7 @@ void odf_conversion_context::end_math() end_object(); - calculate_font_metrix(math_context_.font, math_context_.size, false, false); // смотреть по формуле - перевычислять только если есть изменения это шрифт и кегль + calculate_font_metrix(math_context_.font, math_context_.size, false, false, true); // смотреть по формуле - перевычислять только если есть изменения это шрифт и кегль double h = math_context_.lvl_max - math_context_.lvl_min; if (math_context_.lvl_min < 0) h += 1; @@ -508,6 +521,26 @@ office_element_ptr odf_conversion_context::start_tabs() create_element(L"style", L"tab-stops", temporary_.elm, this, true); return temporary_.elm; } +void odf_conversion_context::add_meta(const office_element_ptr& elm) +{ + if (!elm) return; + objects_[current_object_]->meta.push_back(elm); +} +void odf_conversion_context::add_meta_user_define(const std::wstring& name, const std::wstring& content) +{ + office_element_ptr elm; + create_element(L"meta", L"user-defined", elm, this, true); + + meta_user_defined* meta_user = dynamic_cast(elm.get()); + if (meta_user) + { + meta_user->meta_name_ = name; + meta_user->content_ = content; + meta_user->meta_value_type_ = odf_types::office_value_type::String; + + add_meta(elm); + } +} void odf_conversion_context::add_meta(const std::wstring & ns, const std::wstring & name, const std::wstring & content) { if (name.empty()) return; @@ -553,23 +586,37 @@ std::wstring odf_conversion_context::add_media(const std::wstring & file_name, b return odf_ref_name; } } -std::wstring odf_conversion_context::add_imageobject(const std::wstring & file_name) +std::wstring odf_conversion_context::add_imageobject(const std::wstring & file_name, bool bExternal) { if (file_name.empty()) return L""; - std::wstring odf_ref_name ; - mediaitems()->add_or_find(file_name,_mediaitems::typeObjectReplacement, odf_ref_name); + if (bExternal) + { + return file_name; + } + else + { + std::wstring odf_ref_name; + mediaitems()->add_or_find(file_name, _mediaitems::typeObjectReplacement, odf_ref_name); - return odf_ref_name; + return odf_ref_name; + } } -std::wstring odf_conversion_context::add_oleobject(const std::wstring & file_name) +std::wstring odf_conversion_context::add_oleobject(const std::wstring & file_name, bool bExternal) { if (file_name.empty()) return L""; - std::wstring odf_ref_name ; - mediaitems()->add_or_find(file_name,_mediaitems::typeOleObject, odf_ref_name); + if (bExternal) + { + return file_name; + } + else + { + std::wstring odf_ref_name; + mediaitems()->add_or_find(file_name, _mediaitems::typeOleObject, odf_ref_name); - return odf_ref_name; + return odf_ref_name; + } } void odf_conversion_context::add_tab(_CP_OPT(int) type, _CP_OPT(length) _length, _CP_OPT(int) leader) { diff --git a/OdfFile/Writer/Format/odf_conversion_context.h b/OdfFile/Writer/Format/odf_conversion_context.h index 855acf0be1b..a067b4190c4 100644 --- a/OdfFile/Writer/Format/odf_conversion_context.h +++ b/OdfFile/Writer/Format/odf_conversion_context.h @@ -64,7 +64,8 @@ namespace odf_writer { bool italic = false; bool bold = false; - double approx_symbol_size = 0;//in pt + double approx_symbol_width = 0;//in pt + double approx_symbol_height = 0;//in pt }; //---------------------------------------------------------------------- class office_element; @@ -122,10 +123,12 @@ class odf_conversion_context : boost::noncopyable std::wstring add_image (const std::wstring & image_file_name, bool bExternal = false); std::wstring add_media (const std::wstring & file_name, bool bExternal = false); - std::wstring add_oleobject (const std::wstring & ole_file_name); - std::wstring add_imageobject(const std::wstring & ole_file_name); + std::wstring add_oleobject (const std::wstring & ole_file_name, bool bExternal = false); + std::wstring add_imageobject(const std::wstring & ole_file_name, bool bExternal = false); void add_meta(const std::wstring & ns, const std::wstring & name, const std::wstring & content); + void add_meta(const office_element_ptr &elm); + void add_meta_user_define(const std::wstring& name, const std::wstring& content); virtual odf_style_context_ptr styles_context(); virtual void set_styles_context(odf_style_context_ptr styles_context); @@ -169,9 +172,13 @@ class odf_conversion_context : boost::noncopyable void add_tab(_CP_OPT(int) type, _CP_OPT(odf_types::length) length, _CP_OPT(int) leader); void end_tabs(); - void calculate_font_metrix(std::wstring name, double size, bool italic, bool bold); + void calculate_font_metrix(std::wstring name, double size, bool italic, bool bold, bool recalc = false); double convert_symbol_width(double va, bool add_padding = false); + void add_hyperlink(office_element_ptr& elem, const std::wstring& ref); + std::vector> get_deferred_hyperlinks(); + + std::pair font_metrix() { return std::make_pair(font_metrix_.approx_symbol_width, font_metrix_.approx_symbol_height); } protected: std::vector text_context_; std::vector drawing_context_; @@ -191,6 +198,8 @@ class odf_conversion_context : boost::noncopyable void process_settings (_object & object, bool isRoot); int current_object_; + + std::vector> hyperlinks_; }; } diff --git a/OdfFile/Writer/Format/odf_drawing_context.cpp b/OdfFile/Writer/Format/odf_drawing_context.cpp index 259a4fd12dd..349aabd2256 100644 --- a/OdfFile/Writer/Format/odf_drawing_context.cpp +++ b/OdfFile/Writer/Format/odf_drawing_context.cpp @@ -195,11 +195,13 @@ struct odf_drawing_state fill_color_ = boost::none; name_ = L""; description_ = L""; + xml_id_ = L""; hidden_ = false; z_order_ = -1; - presentation_class_ = boost::none; - presentation_placeholder_ = boost::none; + presentation_class_ = boost::none; + presentation_placeholder_id_ = boost::none; + placeholder_replacing = false; rotateAngle_ = boost::none; text_rotateAngle_ = boost::none; @@ -218,6 +220,8 @@ struct odf_drawing_state flipH_ = flipV_ = false; + draw_type_ = boost::none; + } std::vector elements_; @@ -229,11 +233,14 @@ struct odf_drawing_state _CP_OPT(double) cx_; _CP_OPT(double) cy_; + _CP_OPT(std::wstring) draw_type_; + bool flipH_; bool flipV_; std::wstring name_; std::wstring description_; + std::wstring xml_id_; int z_order_; bool hidden_; @@ -242,7 +249,8 @@ struct odf_drawing_state _CP_OPT(int) text_rotateAngle_; _CP_OPT(presentation_class) presentation_class_; - _CP_OPT(std::wstring) presentation_placeholder_; + _CP_OPT(std::wstring) presentation_placeholder_id_; + bool placeholder_replacing; std::wstring program_; std::wstring replacement_; @@ -288,6 +296,7 @@ class odf_drawing_context::Impl is_header_ = false; is_footer_ = false; is_background_ = false; + placeholder_replacing = false; //некоторые свойства для объектов графики не поддерживаюися в редакторах Libre && OpenOffice.net //в MS Office и в нашем - проблем таких нет. } @@ -303,6 +312,7 @@ class odf_drawing_context::Impl bool is_footer_; bool is_header_; bool is_background_; + bool placeholder_replacing; _CP_OPT(int) is_presentation_; void create_draw_base(eOdfDrawElements type); @@ -415,9 +425,9 @@ void odf_drawing_context::start_group() if (false == impl_->current_level_.empty()) impl_->current_level_.back().elm->add_child_element(group_elm); - if (group == NULL)return; + if (group == NULL) return; - //если группа топовая - то данные если не записать - сотруться + //если группа топовая - то данные если не записать - сотрутся if (!impl_->current_drawing_state_.name_.empty()) group->common_draw_attlists_.shape_with_text_and_styles_.common_shape_draw_attlist_.draw_name_ = impl_->current_drawing_state_.name_; else @@ -427,7 +437,9 @@ void odf_drawing_context::start_group() //if (!impl_->current_drawing_state_.description_.empty()) // group->common_draw_attlists_.shape_with_text_and_styles_.common_shape_draw_attlist_.draw_name_ = impl_->current_drawing_state_.description_; if (impl_->current_drawing_state_.hidden_) - group->common_draw_attlists_.shape_with_text_and_styles_.common_shape_draw_attlist_.drawooo_display_ = L"printer"; + group->common_draw_attlists_.shape_with_text_and_styles_.common_shape_draw_attlist_.drawooo_display_ = L"printer"; // L"none" ??? + if (!impl_->current_drawing_state_.xml_id_.empty()) + group->xml_id_ = impl_->current_drawing_state_.xml_id_; impl_->current_drawing_state_.z_order_ = -1; @@ -591,7 +603,7 @@ void odf_drawing_context::end_drawing() draw_base* draw = impl_->current_drawing_state_.elements_.empty() ? NULL : dynamic_cast(impl_->current_drawing_state_.elements_[index].elm.get()); if (draw) { - if (impl_->current_drawing_state_.presentation_class_ || impl_->current_drawing_state_.presentation_placeholder_) + if (impl_->current_drawing_state_.presentation_class_ || impl_->current_drawing_state_.presentation_placeholder_id_) { _CP_OPT(std::wstring) draw_layer; if (impl_->is_presentation_.get() > 0) @@ -622,7 +634,9 @@ void odf_drawing_context::end_drawing() if (impl_->current_drawing_state_.z_order_ >= 0) draw->common_draw_attlists_.shape_with_text_and_styles_.common_shape_draw_attlist_.draw_z_index_ = impl_->current_drawing_state_.z_order_; if (impl_->current_drawing_state_.hidden_) - draw->common_draw_attlists_.shape_with_text_and_styles_.common_shape_draw_attlist_.drawooo_display_ = L"printer"; + draw->common_draw_attlists_.shape_with_text_and_styles_.common_shape_draw_attlist_.drawooo_display_ = L"printer"; // L"none" ??? + if (!impl_->current_drawing_state_.xml_id_.empty()) + draw->xml_id_ = impl_->current_drawing_state_.xml_id_; std::wstring strTransform; @@ -689,7 +703,7 @@ void odf_drawing_context::end_drawing() draw->common_draw_attlists_.rel_size_.common_draw_size_attlist_.svg_width_ = impl_->current_drawing_state_.svg_width_; } /////////////////////////////////////////////////////// - presentation_placeholder * placeholder = impl_->current_drawing_state_.elements_.empty() ? NULL : dynamic_cast(impl_->current_drawing_state_.elements_[index].elm.get()); + presentation_placeholder *placeholder = impl_->current_drawing_state_.elements_.empty() ? NULL : dynamic_cast(impl_->current_drawing_state_.elements_[index].elm.get()); if (placeholder) { placeholder->presentation_object_ = impl_->current_drawing_state_.presentation_class_; @@ -884,6 +898,14 @@ bool odf_drawing_context::is_wordart() return false; } +bool odf_drawing_context::is_placeholder() +{ + if (!impl_->current_level_.empty() && typeStylePresentationPlaceholder == impl_->current_level_[0].elm->get_type()) + return true; + + return false; +} + bool odf_drawing_context::change_text_box_2_wordart() { if (impl_->current_drawing_state_.oox_shape_preset_ > 2000 && impl_->current_drawing_state_.oox_shape_preset_ < 3000) @@ -1101,6 +1123,10 @@ void odf_drawing_context::end_shape() { text_shape = true; } + else if (impl_->current_drawing_state_.draw_type_) + { + sub_type = *impl_->current_drawing_state_.draw_type_; + } //else //{ // sub_type = L"polyline"; @@ -1156,7 +1182,16 @@ void odf_drawing_context::end_shape() enhanced->attlist_.draw_glue_points_ = shape_define->glue_points; enhanced->attlist_.draw_sub_view_size_ = shape_define->sub_view_size; + enhanced->attlist_.glue_points_leaving_directions_ = shape_define->glue_points_leaving_directions; + enhanced->attlist_.draw_path_stretchpoint_x_ = shape_define->path_stretchpoint_x; + enhanced->attlist_.draw_path_stretchpoint_y_ = shape_define->path_stretchpoint_y; + + //if (!shape_define->modifiers.empty()) + //{ + // enhanced->attlist_.draw_modifiers_ = shape_define->modifiers; + //} + if (impl_->current_drawing_state_.oox_shape_ && !impl_->current_drawing_state_.oox_shape_->modifiers.empty()) { enhanced->attlist_.draw_modifiers_ = impl_->current_drawing_state_.oox_shape_->modifiers; @@ -1304,13 +1339,13 @@ void odf_drawing_context::end_frame() end_element(); } ///////////////////// -void odf_drawing_context::start_element(office_element_ptr elm, office_element_ptr style_elm) +void odf_drawing_context::start_element(office_element_ptr elm, office_element_ptr style_elm) { size_t level = impl_->current_level_.size(); //если фейковый предыдущий уровень (для сохранения порядка выше) - привязывааем к уровню выше - for (int i = impl_->current_level_.size() - 1; elm && i >= 0; i--) + for (int i = (int)impl_->current_level_.size() - 1; elm && i >= 0; i--) { if (impl_->current_level_[i].elm) { @@ -1362,8 +1397,10 @@ void odf_drawing_context::end_area_properties() } void odf_drawing_context::start_line_properties(bool reset) { + if (!impl_->current_graphic_properties) return; + impl_->current_drawing_part_ = Line; - if (reset) + if (reset ) impl_->current_graphic_properties->draw_stroke_ = boost::none; } void odf_drawing_context::end_line_properties() @@ -1397,7 +1434,7 @@ void odf_drawing_context::set_hidden (bool bVal) } void odf_drawing_context::set_opacity(double percent_) { - if (!impl_->current_graphic_properties)return; + if (!impl_->current_graphic_properties) return; switch(impl_->current_drawing_part_) { @@ -1438,11 +1475,7 @@ void odf_drawing_context::set_shadow(int type, std::wstring hexColor, _CP_OPT(do hexColor = std::wstring(L"#") + hexColor; impl_->current_graphic_properties->common_shadow_attlist_.draw_shadow_offset_x_ = length(length(dist_pt, length::pt).get_value_unit(length::cm), length::cm); - - if (dist_pt_y > 0) - impl_->current_graphic_properties->common_shadow_attlist_.draw_shadow_offset_y_ = length(length(dist_pt_y, length::pt).get_value_unit(length::cm), length::cm); - else - impl_->current_graphic_properties->common_shadow_attlist_.draw_shadow_offset_y_ = length(length(dist_pt, length::pt).get_value_unit(length::cm), length::cm); + impl_->current_graphic_properties->common_shadow_attlist_.draw_shadow_offset_y_ = length(length(dist_pt_y, length::pt).get_value_unit(length::cm), length::cm); impl_->current_graphic_properties->common_shadow_attlist_.draw_shadow_ = shadow_type1(shadow_type1::Visible); if (opacity) impl_->current_graphic_properties->common_shadow_attlist_.draw_shadow_opacity_ = *opacity; @@ -1454,7 +1487,7 @@ void odf_drawing_context::set_placeholder_id (std::wstring val) { if (!impl_->is_presentation_) return; - impl_->current_drawing_state_.presentation_placeholder_ = val; + impl_->current_drawing_state_.presentation_placeholder_id_ = val; } void odf_drawing_context::set_placeholder_type (int val) { @@ -1486,11 +1519,18 @@ void odf_drawing_context::set_placeholder_type (int val) case 13: impl_->current_drawing_state_.presentation_class_ = presentation_class::subtitle; break; case 14: impl_->current_drawing_state_.presentation_class_ = presentation_class::table; break; case 15: impl_->current_drawing_state_.presentation_class_ = presentation_class::title; break; + case 16: impl_->current_drawing_state_.presentation_class_ = presentation_class::body; break; default: impl_->current_drawing_state_.presentation_class_ = presentation_class::outline; break; } //todooo draw_layer for master for sldnum, datetime ... } + +void odf_drawing_context::set_xml_id(const std::wstring& xml_id) +{ + impl_->current_drawing_state_.xml_id_ = xml_id; +} + void odf_drawing_context::set_group_fill() { if (!impl_->current_graphic_properties) return; @@ -1608,6 +1648,13 @@ void odf_drawing_context::set_z_order(int id) impl_->current_drawing_state_.z_order_ = id + 1; } +int odf_drawing_context::get_formulas_count() +{ + if (!impl_->current_drawing_state_.oox_shape_) + return 0; + + return (int)impl_->current_drawing_state_.oox_shape_->equations.size(); +} void odf_drawing_context::set_path(std::wstring path_string) { impl_->current_drawing_state_.path_ = path_string; @@ -1616,7 +1663,8 @@ void odf_drawing_context::add_path_element(std::wstring command, std::wstring st { XmlUtils::replace_all(strE, L"gd", L"?f"); - if (command != impl_->current_drawing_state_.path_last_command_) + if (command != impl_->current_drawing_state_.path_last_command_ + || command == L"M") // NOTE: Две последовательые команды "Move" должны быть записаны без сокращений (включая команду "M" для каждого мува) { impl_->current_drawing_state_.path_ += command; if (!strE.empty()) @@ -1663,10 +1711,25 @@ int GetFormulaType2(const WCHAR& c1, const WCHAR& c2) return 0; } +static std::wstring replace_textarea(std::wstring textarea_coord) +{ + XmlUtils::replace_all(textarea_coord, L"t", L"0"); + XmlUtils::replace_all(textarea_coord, L"l", L"0"); + XmlUtils::replace_all(textarea_coord, L"r", L"logwidth"); + XmlUtils::replace_all(textarea_coord, L"b", L"logheight"); + + return textarea_coord; +} + void odf_drawing_context::set_textarea (std::wstring l, std::wstring t, std::wstring r, std::wstring b) { if (!impl_->current_drawing_state_.oox_shape_) return; + l = replace_textarea(l); + t = replace_textarea(t); + r = replace_textarea(r); + b = replace_textarea(b); + impl_->current_drawing_state_.oox_shape_->text_areas = l + L" " + t + L" " + r + L" " + b; XmlUtils::replace_all(impl_->current_drawing_state_.oox_shape_->text_areas, L"gd", L"?f"); @@ -1692,6 +1755,11 @@ void odf_drawing_context::add_handle (std::wstring x, std::wstring y, std::wstri impl_->current_drawing_state_.oox_shape_->handles.push_back(h); } +void odf_drawing_context::set_draw_type(const std::wstring& draw_type) +{ + impl_->current_drawing_state_.draw_type_ = draw_type; +} + void odf_drawing_context::add_formula (std::wstring name, std::wstring fmla) { if (!impl_->current_drawing_state_.oox_shape_) return; @@ -1699,6 +1767,11 @@ void odf_drawing_context::add_formula (std::wstring name, std::wstring fmla) size_t nStart = 0; size_t nCurrent = 0; + XmlUtils::replace_all(fmla, L" * ", L"*"); + XmlUtils::replace_all(fmla, L" - ", L"-"); + XmlUtils::replace_all(fmla, L" + ", L"+"); + XmlUtils::replace_all(fmla, L" / ", L"/"); + const wchar_t* pData = fmla.c_str(); int nFound = 0, x = 0, y = 0; @@ -1724,7 +1797,10 @@ void odf_drawing_context::add_formula (std::wstring name, std::wstring fmla) } else { - val[nFound-1] = std::wstring( pData + nStart, (ULONG)(nCurrent - nStart)); + if (nFound > 4) + return; // ! + + val[nFound - 1] = std::wstring(pData + nStart, (ULONG)(nCurrent - nStart)); } nStart = nCurrent + 1; ++nFound; @@ -1769,10 +1845,13 @@ void odf_drawing_context::add_formula (std::wstring name, std::wstring fmla) { odf_fmla += val[i] + L","; } - odf_fmla += val[nFound-1] + L")"; break; + odf_fmla += val[nFound - 1] + L")"; break; case 4: odf_fmla = L"abs(" + val[0] + L")"; break; + case 5: + odf_fmla = L"(10800000 * atan2(" + val[1] + L", " + val[0] + L"))/pi"; + break; case 7: odf_fmla = val[0] + L"*cos(pi*(" + val[1] + L")/10800000)"; break; @@ -1794,7 +1873,6 @@ void odf_drawing_context::add_formula (std::wstring name, std::wstring fmla) XmlUtils::replace_all(odf_fmla, L"h", L"logheight"); XmlUtils::replace_all(odf_fmla, L"w", L"logwidth"); XmlUtils::replace_all(odf_fmla, L"adj", L"$"); - //XmlUtils::replace_all(name, L"gd", L"f"); impl_->current_drawing_state_.oox_shape_->add(name, odf_fmla); } @@ -1834,8 +1912,7 @@ void odf_drawing_context::set_flip_V(bool bVal) void odf_drawing_context::set_rotate(double dVal) { - if (dVal > 180) dVal = dVal - 360; - double dRotate = dVal / 180. * 3.14159265358979323846; + double dRotate = -dVal / 180. * 3.14159265358979323846; impl_->current_drawing_state_.rotateAngle_ = dRotate; } @@ -2103,6 +2180,18 @@ void odf_drawing_context::set_group_name(const std::wstring & name) if ( !name.empty() ) group->common_draw_attlists_.shape_with_text_and_styles_.common_shape_draw_attlist_.draw_name_ = name; } + +void odf_drawing_context::set_group_xml_id(const std::wstring& xml_id) +{ + if (impl_->group_list_.empty()) + return; + + draw_g* group = dynamic_cast(impl_->current_group_->elm.get()); + + if (!xml_id.empty()) + group->xml_id_ = xml_id; +} + void odf_drawing_context::set_group_flip_H(bool bVal) { if ( impl_->group_list_.empty() )return; @@ -2442,8 +2531,9 @@ void odf_drawing_context::set_line_dash_preset(int style) impl_->current_graphic_properties->draw_stroke_=line_style(line_style::Solid); break; } } -void odf_drawing_context::set_text_properties(style_text_properties *text_properties) +void odf_drawing_context::set_text_properties(text_format_properties* text_properties) { + if (!text_properties) return; if (impl_->current_drawing_state_.elements_.empty()) return; if (!impl_->current_text_properties) @@ -2451,29 +2541,45 @@ void odf_drawing_context::set_text_properties(style_text_properties *text_proper draw_base* draw = dynamic_cast(impl_->current_drawing_state_.elements_[0].elm.get()); if (draw) { - if(!draw->common_draw_attlists_.shape_with_text_and_styles_.common_shape_draw_attlist_.draw_text_style_name_) + if (!draw->common_draw_attlists_.shape_with_text_and_styles_.common_shape_draw_attlist_.draw_text_style_name_) { - impl_->styles_context_->create_style(L"", style_family::Paragraph, true, false, -1); - - office_element_ptr & style_shape_elm = impl_->styles_context_->last_state()->get_office_element(); + impl_->styles_context_->create_style(L"", style_family::Paragraph, true, false, -1); + + office_element_ptr& style_shape_elm = impl_->styles_context_->last_state()->get_office_element(); style* style_ = dynamic_cast(style_shape_elm.get()); if (style_) { impl_->current_text_properties = style_->content_.add_get_style_text_properties(); draw->common_draw_attlists_.shape_with_text_and_styles_.common_shape_draw_attlist_.draw_text_style_name_ = style_->style_name_; - + if (!impl_->current_level_.empty()) impl_->current_level_.back().text_properties = impl_->current_text_properties; } } else - { - //??? find by name + { //todooo - см set_parent_text_style (контент контроли) } } } if (impl_->current_text_properties) - impl_->current_text_properties->apply_from(text_properties->content_); + impl_->current_text_properties->apply_from(*text_properties); +} +void odf_drawing_context::set_text_properties(style_text_properties *text_properties) +{ + if (!text_properties) return; + if (impl_->current_drawing_state_.elements_.empty()) return; + + set_text_properties(&text_properties->content_); +} +void odf_drawing_context::set_placeholder_style(const std::wstring& style_name) +{ + if (impl_->current_drawing_state_.elements_.empty()) return; + + presentation_placeholder* placeholder = dynamic_cast(impl_->current_drawing_state_.elements_[0].elm.get()); + if (placeholder) + { + placeholder->text_style_name_ = style_name; + } } void odf_drawing_context::set_paragraph_properties(paragraph_format_properties *paragraph_properties) { @@ -2484,7 +2590,7 @@ void odf_drawing_context::set_paragraph_properties(paragraph_format_properties * draw_base* draw = dynamic_cast(impl_->current_drawing_state_.elements_[0].elm.get()); if (draw) { - if(!draw->common_draw_attlists_.shape_with_text_and_styles_.common_shape_draw_attlist_.draw_text_style_name_) + if (!draw->common_draw_attlists_.shape_with_text_and_styles_.common_shape_draw_attlist_.draw_text_style_name_) { impl_->styles_context_->create_style(L"", style_family::Paragraph, true, false, -1); @@ -2501,18 +2607,47 @@ void odf_drawing_context::set_paragraph_properties(paragraph_format_properties * } else { - //??? find by name + /// find by name + if (!draw->common_draw_attlists_.shape_with_text_and_styles_.common_shape_draw_attlist_.draw_text_style_name_->empty()) + { + style* found_style; + + impl_->styles_context_->find_odf_style( + *draw->common_draw_attlists_.shape_with_text_and_styles_.common_shape_draw_attlist_.draw_text_style_name_, + odf_types::style_family::Paragraph, + found_style); + + if (found_style) + impl_->current_paragraph_properties = found_style->content_.add_get_style_paragraph_properties(); + } } } } if (impl_->current_paragraph_properties && paragraph_properties) - impl_->current_paragraph_properties ->apply_from(*paragraph_properties); + impl_->current_paragraph_properties->apply_from(*paragraph_properties); } void odf_drawing_context::set_graphic_properties(style_graphic_properties *graphic_properties) { if (impl_->current_graphic_properties && graphic_properties) impl_->current_graphic_properties->apply_from(graphic_properties->content_); } + +void odf_drawing_context::set_graphic_properties(graphic_format_properties* graphic_properties) +{ + if (impl_->current_graphic_properties && graphic_properties) + impl_->current_graphic_properties->apply_from(*graphic_properties); +} + +void odf_drawing_context::placeholder_replacing(bool replacing) +{ + impl_->current_drawing_state_.placeholder_replacing = replacing; +} + +bool odf_drawing_context::placeholder_replacing() +{ + return impl_->current_drawing_state_.placeholder_replacing; +} + graphic_format_properties* odf_drawing_context::get_graphic_properties() { return impl_->current_graphic_properties; @@ -2649,7 +2784,7 @@ void odf_drawing_context::set_textarea_writing_mode(int mode) if (draw) { style* style_ = NULL; - if(!draw->common_draw_attlists_.shape_with_text_and_styles_.common_shape_draw_attlist_.draw_text_style_name_) + if (!draw->common_draw_attlists_.shape_with_text_and_styles_.common_shape_draw_attlist_.draw_text_style_name_) { impl_->styles_context_->create_style(L"", style_family::Paragraph, true, false, -1); @@ -2673,12 +2808,13 @@ void odf_drawing_context::set_textarea_writing_mode(int mode) { switch(mode) { + case 4://SimpleTypes::textverticaltypeVert270: //нужно отзеркалить по горизонтали текст + paragraph_properties->style_writing_mode_ = odf_types::writing_mode(odf_types::writing_mode::TbLr); + break; case 5://textverticaltypeWordArtVert: case 6://textverticaltypeWordArtVertRtl: - case 4://SimpleTypes::textverticaltypeVert270: //нужно отзеркалить по горизонтали текст case 3://SimpleTypes::textverticaltypeVert: case 2://SimpleTypes::textverticaltypeMongolianVert: - paragraph_properties->style_writing_mode_ = odf_types::writing_mode(odf_types::writing_mode::TbRl); break; case 0://SimpleTypes::textverticaltypeEaVert: @@ -2694,9 +2830,11 @@ void odf_drawing_context::set_textarea_writing_mode(int mode) { switch(mode) { + case 4://SimpleTypes::textverticaltypeVert270: //нужно отзеркалить по горизонтали текст + impl_->current_paragraph_properties->style_writing_mode_ = odf_types::writing_mode(odf_types::writing_mode::TbLr); + break; case 5://textverticaltypeWordArtVert: case 6://textverticaltypeWordArtVertRtl: - case 4://SimpleTypes::textverticaltypeVert270: //нужно отзеркалить по горизонтали текст case 3://SimpleTypes::textverticaltypeVert: case 2://SimpleTypes::textverticaltypeMongolianVert: impl_->current_paragraph_properties->style_writing_mode_ = odf_types::writing_mode(odf_types::writing_mode::TbRl); @@ -2984,16 +3122,18 @@ void odf_drawing_context::start_action(std::wstring value) } else if (std::wstring::npos != value.find(L"hlinksldjump")) { - event_->attlist_.presentation_action_ = L"previous-page"; + event_->attlist_.presentation_action_ = L"show"; } else if (std::wstring::npos != value.find(L"macro")) { } else if (std::wstring::npos != value.find(L"hlinkfile")) { + event_->attlist_.presentation_action_ = L"show"; } else if (std::wstring::npos != value.find(L"hlinkpres")) { + event_->attlist_.presentation_action_ = L"show"; } else {//hyperlink @@ -3084,6 +3224,28 @@ void odf_drawing_context::end_action() end_element(); end_element(); } + +void odf_drawing_context::start_style_columns(int cols, int gap) +{ + graphic_format_properties* graphic_props = get_graphic_properties(); + if (!graphic_props) + return; + + if (!graphic_props->style_columns_) + graphic_props->style_columns_ = boost::make_shared(); + + graphic_props->style_columns_->fo_column_count_ = cols; + graphic_props->style_columns_->fo_column_gap_ = length(gap, length::cm); +} + +void odf_drawing_context::add_style_column() +{ +} + +void odf_drawing_context::end_style_columns() +{ +} + void odf_drawing_context::set_text_box_min_size(double w_pt, double h_pt) { if (impl_->current_drawing_state_.elements_.empty()) return; @@ -3105,6 +3267,36 @@ void odf_drawing_context::set_text_box_tableframe(bool val) impl_->current_drawing_state_.text_box_tableframe_ = val; } +void odf_drawing_context::set_parent_text_style(std::wstring style_name) +{ + if (impl_->current_drawing_state_.elements_.empty()) return; + + if (!impl_->current_text_properties) + { + draw_base* draw = dynamic_cast(impl_->current_drawing_state_.elements_[0].elm.get()); + if (draw) + { + impl_->styles_context_->create_style(L"", style_family::Paragraph, true, false, -1); + + office_element_ptr& style_shape_elm = impl_->styles_context_->last_state()->get_office_element(); + style* style_ = dynamic_cast(style_shape_elm.get()); + if (style_) + { + style_->style_parent_style_name_ = style_name; + + impl_->current_text_properties = style_->content_.add_get_style_text_properties(); + draw->common_draw_attlists_.shape_with_text_and_styles_.common_shape_draw_attlist_.draw_text_style_name_ = style_->style_name_; + + if (!impl_->current_level_.empty()) + impl_->current_level_.back().text_properties = impl_->current_text_properties; + } + } + } + else + { + + } +} void odf_drawing_context::set_parent_style(std::wstring style_name) { if (impl_->current_drawing_state_.elements_.empty()) return; @@ -3136,6 +3328,13 @@ void odf_drawing_context::end_image() else impl_->current_graphic_properties->style_mirror_ = std::wstring(L"horizontal"); } + if (impl_->current_drawing_state_.flipV_) + { + if (impl_->current_graphic_properties->style_mirror_) + impl_->current_graphic_properties->style_mirror_ = *impl_->current_graphic_properties->style_mirror_ + std::wstring(L" vertical"); + else + impl_->current_graphic_properties->style_mirror_ = std::wstring(L"vertical"); + } end_element(); end_frame(); } diff --git a/OdfFile/Writer/Format/odf_drawing_context.h b/OdfFile/Writer/Format/odf_drawing_context.h index f68196ce298..a52e7c6dcf7 100644 --- a/OdfFile/Writer/Format/odf_drawing_context.h +++ b/OdfFile/Writer/Format/odf_drawing_context.h @@ -53,6 +53,7 @@ class odf_text_context; class graphic_format_properties; class paragraph_format_properties; +class text_format_properties; class style_text_properties; class style_graphic_properties; @@ -74,7 +75,8 @@ class odf_drawing_context void clear (); void set_styles_context (odf_style_context_ptr styles_context);//для embedded - void set_parent_style (std::wstring style_name); + void set_parent_style(std::wstring style_name); + void set_parent_text_style(std::wstring style_name); void set_header_state (bool Val); void set_footer_state (bool Val); @@ -124,6 +126,7 @@ class odf_drawing_context void set_group_flip_V (bool bVal); void set_group_z_order (int Val); void set_group_name (const std::wstring & name); + void set_group_xml_id (const std::wstring& xml_id); void set_group_rotate (int iVal); void set_group_size (_CP_OPT(double) cx, _CP_OPT(double) cy, _CP_OPT(double) change_cx, _CP_OPT(double) change_cy); @@ -148,12 +151,19 @@ class odf_drawing_context bool change_text_box_2_wordart(); bool is_wordart(); bool is_text_box(); + bool is_placeholder(); + void placeholder_replacing(bool replacing); + bool placeholder_replacing(); graphic_format_properties* get_graphic_properties(); void set_graphic_properties (style_graphic_properties *graphic_properties); + void set_graphic_properties (graphic_format_properties* graphic_properties); void set_paragraph_properties (paragraph_format_properties *paragraph_properties); void set_text_properties (style_text_properties *text_properties); + void set_text_properties (text_format_properties* text_properties); + + void set_placeholder_style(const std::wstring& style_name); void start_text_box (); void set_text_box_min_size (bool val); @@ -194,6 +204,8 @@ class odf_drawing_context bool is_exist_content(); bool is_current_empty(); ////////////////////////////////////////////////////////////////////////////////////// + int get_formulas_count(); + void set_path (std::wstring path_string); void add_path_element (std::wstring command, std::wstring elm); void add_modifier (std::wstring modifier); @@ -201,6 +213,7 @@ class odf_drawing_context void set_textarea (std::wstring l, std::wstring t, std::wstring r, std::wstring b); void add_handle (std::wstring x, std::wstring y, std::wstring refX, std::wstring refY, std::wstring minX, std::wstring maxX, std::wstring minY, std::wstring maxY); + void set_draw_type (const std::wstring& draw_type); void set_viewBox (double W, double H); @@ -268,6 +281,7 @@ class odf_drawing_context void set_placeholder_id (std::wstring val); void set_placeholder_type (int val); + void set_xml_id (const std::wstring& xml_id); ////////////////////////////////////////////////////////////////////////////////////// void start_gradient_style (); void set_gradient_type (odf_types::gradient_style::type style); @@ -313,6 +327,10 @@ class odf_drawing_context void add_link (std::wstring href); void end_action(); + void start_style_columns(int cols, int gap); + void add_style_column(); + void end_style_columns(); + private: class Impl; _CP_PTR(Impl) impl_; diff --git a/OdfFile/Writer/Format/odf_math_context.cpp b/OdfFile/Writer/Format/odf_math_context.cpp index 83be706f665..b94a9bf192c 100644 --- a/OdfFile/Writer/Format/odf_math_context.cpp +++ b/OdfFile/Writer/Format/odf_math_context.cpp @@ -111,7 +111,7 @@ namespace odf_writer odf_math_context::odf_math_context(odf_conversion_context *odf_context) : impl_(new odf_math_context::Impl(odf_context)), - lvl_of_me(0), style_flag(true), counter(0), symbol_counter(0), annotation_flag(true), annotation_oper_flag(false), matrix_row_counter(0) + lvl_of_me(0), style_flag(true), counter(0), symbol_counter(0), matrix_row_counter(0) { mo = { L'+', L'-', L'±', L'∓', L'∙', L'×', L'∗', L'÷', L'/', L'≂', L'⊕', L'⊖', L'⊙', L'⊗', L'⊘', L'∘', L'¬', L'∧', L'∨', // un/bi operators L'=', L'≠', L'<', L'≤', L'>', L'≥', L'≪', L'≫', L'≈', L'~', L'≃', L'≡', L'∝', L'∥', L'⟂', L'|', L'∤', L'→', L'⊷', // relations @@ -129,22 +129,6 @@ namespace odf_writer //{L'', L''}, { L'', L'' }, { L'', L'' }, { L'', L'' }, { L'', L'' }, { L'', L'' }, { L'', L'' } }; - annotation_diak_symbols = { {L"˙",L"dot"}, {L"¨",L"ddot"}, {L"⃛",L"dddot"}, {L"˄", L"hat"}, {L"ˇ",L"check"}, {L"´",L"acute"}, {L"ˋ",L"grave"}, {L"˘",L"breve"}, - {L"~",L"tilde"},{L"¯",L"overline"},{L"→",L"vec"}, {L"⇀",L"harpoon"}, {L"-",L"underline"}/*, {L"",L""}, {L"",L""}, {L"",L""}, {L"",L""}, {L"",L""}, {L"",L""},{L"",L""}, - {L"",L""}*/ - }; - - annotation_operators = { {L"∫",L"int"}, {L"∬", L"iint "}, {L"∭", L"iiint "}, {L"∮", L"lint "}, {L"∯", L"llint "}, - {L"∰", L"lllint "}, {L"∑", L"sum "}, {L"∏", L"prod "}, {L"∐", L"coprod "} - - }; - - annotation_brackets_begin = { {L"(", L"("}, {L"[", L"["}, {L"{", L"lbrace"}, {L"⟨", L"langle"}, {L"〈", L"langle"}, {L"⌊", L"lfloor"}, {L"⌈", L"lceil"}, {L"|", L"lline"}, {L"‖", L"ldline"}, - {L"]", L"]"}, {L"⟦", L"ldbracket"} - }; - annotation_brackets_end = { {L")", L")"}, {L"]", L"]"}, {L"}", L"rbrace"}, {L"⟩", L"rangle"}, {L"〉", L"rangle"},{L"⌋", L"rfloor"}, {L"⌉", L"rceil"}, {L"|", L"rline"}, {L"‖", L"rdline"}, - {L"[", L"["}, {L"⟧", L"rdbracket"} - }; lvl_counter = 1; lvl_up_counter = 1; lvl_down_counter = -1; diff --git a/OdfFile/Writer/Format/odf_math_context.h b/OdfFile/Writer/Format/odf_math_context.h index 33941348b17..a9ed3f8bedf 100644 --- a/OdfFile/Writer/Format/odf_math_context.h +++ b/OdfFile/Writer/Format/odf_math_context.h @@ -112,7 +112,6 @@ namespace cpdoccore { void end_element(); std::vector> brackets; - std::wstring annotation; int lvl_of_me = 0; int matrix_row_counter = 0; std::vector end_counter; @@ -129,13 +128,7 @@ namespace cpdoccore { double size = 0; std::set mo; std::map diak_symbols; - bool annotation_flag; - bool annotation_oper_flag; - std::map annotation_operators; - std::map annotation_brackets_begin; - std::map annotation_brackets_end; - std::map annotation_diak_symbols; - //std::pair, bool> annotation_from_to_operators; + void end_math(); std::wofstream debug_stream; diff --git a/OdfFile/Writer/Format/odf_number_styles_context.cpp b/OdfFile/Writer/Format/odf_number_styles_context.cpp index fb50979f8fb..2bd277e1a7e 100644 --- a/OdfFile/Writer/Format/odf_number_styles_context.cpp +++ b/OdfFile/Writer/Format/odf_number_styles_context.cpp @@ -228,7 +228,9 @@ static const def_language_code LanguageCodeTable[] = {L"Vietnamese", L"", L"", 0x042A}, {L"Welsh", L"", L"", 0x0452}, {L"Xhosa", L"", L"", 0x0434}, - {L"Zulu", L"", L"", 0x0435} + {L"Zulu", L"", L"", 0x0435}, + {L"", L"PL", L"pl", 0x019F }, + {L"", L"IR", L"fa", 0x00160429} }; odf_number_styles_context::odf_number_styles_context() @@ -340,7 +342,7 @@ void odf_number_styles_context::create_default(int oox_num_fmt, std::wstring for } boost::algorithm::split(state.format_code, formatCode, boost::algorithm::is_any_of(L";"), boost::algorithm::token_compress_on); - if (state.format_code.size()>1 && state.format_code[state.format_code.size()-1].find(L"@")>=0) + if (state.format_code.size() > 1 && state.format_code[state.format_code.size()-1].find(L"@") >= 0) { state.format_code.pop_back(); } @@ -421,19 +423,20 @@ void odf_number_styles_context::create_number_style(number_format_state & state, create_numbers(state, elm, root_elm); } } -void odf_number_styles_context::create_numbers(number_format_state & state, office_element_ptr & elm, office_element_ptr & root_elm) +void odf_number_styles_context::create_numbers(number_format_state& state, office_element_ptr& elm, office_element_ptr& root_elm) { _CP_OPT(int) min_digit, min_decimal; + _CP_OPT(int) separate; - switch(state.ods_type) + switch (state.ods_type) { - case office_value_type::Currency: - case office_value_type::Percentage: - case office_value_type::Float: create_element(L"number", L"number", elm, odf_context_); break; - case office_value_type::Scientific: create_element(L"number", L"scientific-number", elm, odf_context_); break; - case office_value_type::Fraction: create_element(L"number", L"fraction", elm, odf_context_); break; + case office_value_type::Currency: + case office_value_type::Percentage: + case office_value_type::Float: create_element(L"number", L"number", elm, odf_context_); break; + case office_value_type::Scientific: create_element(L"number", L"scientific-number", elm, odf_context_); break; + case office_value_type::Fraction: create_element(L"number", L"fraction", elm, odf_context_); break; } - + office_element_ptr elm_text; bool bText = false; @@ -471,74 +474,90 @@ void odf_number_styles_context::create_numbers(number_format_state & state, offi if (indNumber < 0) indNumber = 0; - std::wstring str1,str2; - boost::wregex re1(L"([^0-9.,]+)"); - boost::wsmatch result; - boost::wregex re2(L"([^#.,]+)"); - + // split by space, find #0 - use it ... ???? + std::wstring str1; + boost::wregex re1(L"([^#0.,]+)"); + str1 = boost::regex_replace(splits[indNumber], re1, L"", boost::match_default | boost::format_all); - str2 = boost::regex_replace(splits[indNumber], re2, L"", boost::match_default | boost::format_all); - if (str1.length() < str2.length()) str1 = str2; + size_t pos_separate_1000 = str1.find(L","); + size_t pos_separate_decimal = str1.find(L"."); + + if (pos_separate_decimal != std::wstring::npos) + { + std::wstring str2; + boost::wregex re2(L"([^0]+)"); + + str2 = boost::regex_replace(str1.substr(pos_separate_decimal), re2, L"", boost::match_default | boost::format_all); - std::vector numbers; - boost::algorithm::split(numbers, str1, boost::algorithm::is_any_of(L".,"), boost::algorithm::token_compress_on); + if (false == str2.empty()) + min_decimal = str2.length(); - int ind = 1;// - for (size_t i = 0; i < numbers.size(); i++) + str1 = str1.substr(0, pos_separate_decimal); + } + else { - if (numbers[i].empty())continue; + min_decimal = 0; + } + { + std::wstring str2; + boost::wregex re2(L"([^0]+)"); + + str2 = boost::regex_replace(str1, re2, L"", boost::match_default | boost::format_all); - if (ind == 1) min_digit = numbers[i].length(); - if (ind == 2) min_decimal = numbers[i].length(); - ind++; + if (false == str2.empty()) + min_digit = str2.length(); + } + if (pos_separate_1000 != std::wstring::npos) + { + separate = str1.length() - pos_separate_1000 - 1; } if (bText && root_elm) { - int res1 = (int) splits[indText].find(L"\""); - int res2 = (int) splits[indText].find(L"\"", res1 + 1); + int res1 = (int)splits[indText].find(L"\""); + int res2 = (int)splits[indText].find(L"\"", res1 + 1); if (res2 > 0) { std::wstring text = splits[indText].substr(res1 + 1, res2 - res1 - 1); if (!text.empty()) - { + { if (indText < indNumber) text = text + L" "; else text = L" " + text; create_element(L"number", L"text", elm_text, odf_context_); number_text* number_text_ = dynamic_cast(elm_text.get()); - + if (number_text_) - number_text_->add_text(text); + number_text_->add_text(text); } } } } - + number_number* number_ = dynamic_cast(elm.get()); if (number_) { - number_->number_min_integer_digits_ = min_digit; - number_->number_decimal_places_ = min_digit ? min_decimal.get_value_or(0) : min_decimal; + number_->number_min_integer_digits_ = min_digit; + number_->number_decimal_places_ = min_decimal.get_value_or(0); - if (root_elm && bText) + if (separate) number_->number_grouping_ = true; } number_scientific_number* scientific_ = dynamic_cast(elm.get()); if (scientific_) { - scientific_->number_min_integer_digits_ = min_digit; - scientific_->number_decimal_places_ = min_decimal; - scientific_->number_min_exponent_digits_= min_digit; - scientific_->number_min_decimal_places_ = min_decimal; + scientific_->number_min_integer_digits_ = min_digit; + scientific_->number_decimal_places_ = min_decimal; + scientific_->number_min_exponent_digits_ = min_digit; + scientific_->number_min_decimal_places_ = min_decimal; scientific_->number_forced_exponent_sign_ = true; - - if (root_elm && bText) + + if (separate) scientific_->number_grouping_ = true; - } + } number_fraction* fraction_ = dynamic_cast(elm.get()); if (fraction_) { @@ -546,7 +565,7 @@ void odf_number_styles_context::create_numbers(number_format_state & state, offi fraction_->number_min_numerator_digits_ = min_digit; fraction_->number_min_denominator_digits_ = min_digit; - if (root_elm && bText) + if (separate) fraction_->number_grouping_ = true; } if (root_elm) @@ -613,7 +632,29 @@ void odf_number_styles_context::create_currency_style(number_format_state & stat } } } + std::wstring number_country, number_language; + for (long i = 0; state.language_code > 0 && i < sizeof(LanguageCodeTable) / sizeof(def_language_code); i++) + { + if (LanguageCodeTable[i].id == state.language_code) + { + number_country = LanguageCodeTable[i].country_code; + number_language = LanguageCodeTable[i].language_code; + break; + } + } + //number_currency_style* currency_style_ = dynamic_cast(root_elm.get()); + //if (currency_style_) + //{ + // if (false == number_country.empty()) + // { + // currency_style_->common_data_style_attlist_.number_country_ = number_country; + // } + // if (number_language.length() > 0) + // { + // currency_style_->common_data_style_attlist_.number_language_ = number_language; + // } + //} office_element_ptr elm_symbol; create_element(L"number", L"currency-symbol", elm_symbol, odf_context_); styles_elments.push_back(elm_symbol); @@ -621,18 +662,6 @@ void odf_number_styles_context::create_currency_style(number_format_state & stat number_currency_symbol* number_currency_symbol_ = dynamic_cast(elm_symbol.get()); if (number_currency_symbol_) { - std::wstring number_country,number_language; - - for (long i = 0; state.language_code > 0 && i < sizeof(LanguageCodeTable)/sizeof(def_language_code); i++) - { - if (LanguageCodeTable[i].id == state.language_code) - { - number_country = LanguageCodeTable[i].country_code; - number_language = LanguageCodeTable[i].language_code; - break; - } - } - if (false == number_country.empty()) { number_currency_symbol_->number_country_ = number_country; @@ -672,9 +701,28 @@ void odf_number_styles_context::create_currency_style(number_format_state & stat void odf_number_styles_context::create_date_style(number_format_state & state, office_element_ptr & root_elm) { create_element(L"number", L"date-style", root_elm, odf_context_); + number_date_style *date_ = dynamic_cast(root_elm.get()); - //state.language_code == L"F800" System long date format - + std::wstring number_country, number_language; + + for (long i = 0; state.language_code > 0 && i < sizeof(LanguageCodeTable) / sizeof(def_language_code); i++) + { + if (LanguageCodeTable[i].id == state.language_code) + { + number_country = LanguageCodeTable[i].country_code; + number_language = LanguageCodeTable[i].language_code; + break; + } + } + if (false == number_country.empty()) + { + date_->common_data_style_attlist_.number_country_ = number_country; + } + if (number_language.length() > 0) + { + date_->common_data_style_attlist_.number_language_ = number_language; + } +//--------------------------------------------------------------------------------- std::wstring s = state.format_code[0]; boost::wregex re(L"([mMdDyYhHsS^(AM)^(PM)^(am)^(pm)]+)([^m^M^d^D^y^Y^h^H^s^S^(AM)^(PM)^(am)^(pm)]+)"); @@ -893,41 +941,55 @@ void odf_number_styles_context::detect_format(number_format_state & state) if (state.ods_type != office_value_type::Custom) return; if (state.format_code.empty()) return; - boost::wregex re_unwanted(L"([\"'])(.+?)\\1"); + boost::wregex re_unwanted(L"(\\\\.{1})"); - std::wstring strFormatCode = boost::regex_replace(state.format_code[0], re_unwanted, &replace_unwanted, boost::match_default | boost::format_all); + std::wstring strFormatCode = boost::regex_replace(state.format_code[0], re_unwanted, &replace_unwanted, boost::match_any | boost::format_all); //find [$-]. - boost::wregex re(L"(?:\\[)(?:\\$)(\\S+)?\-(\\S+)(?:\\])"); - boost::wsmatch result; - bool b = boost::regex_search(strFormatCode, result, re); + boost::wregex re(L"(\\[\\$.*\-[\\w\\d]+\\])"); - if (b && result.size() >= 3) - { - state.currency_str = result[1]; - int code = -1; - try + std::vector result; + std::wstring tmp = strFormatCode; + bool b = boost::regex_split(std::back_inserter(result), tmp, re); + + if (b && result.size() > 0) + {//split Currency String + tmp = result[0].substr(1, result[0].size() - 2); + size_t sep = tmp.find(L"-"); + if (sep != std::wstring::npos) { - std::wstringstream ss; - ss << std::hex << result[2]; - ss >> state.language_code; - }catch(...){} + state.currency_str = tmp.substr(1, sep - 1); + + try + { + std::wstringstream ss; + ss << std::hex << tmp.substr(sep + 1); + ss >> state.language_code; + } + catch (...) {} + } + if (false == state.currency_str.empty()) + { + size_t pos_digit = (std::min)(strFormatCode.find(L"0"), strFormatCode.find(L"#")); + size_t pos_currency = strFormatCode.find(state.currency_str); - //state.format_code[0] = boost::regex_replace( state.format_code[0],re,L""); + if (pos_digit != std::wstring::npos) state.currency_pos = pos_digit < pos_currency ? 1 : 2; + } + XmlUtils::replace_all(strFormatCode, result[0], L""); } if (state.format_code.size() > 0) //any { - boost::wregex re1(L"([mMhH{2,}sS{2,}]+)"); - boost::wregex re2(L"([mMdD{1,}yY{2,}]+)"); + boost::wregex re1(L"([mM]{2,}|[hH]{1,}|[sS]{2,})"); + boost::wregex re2(L"([M]{2,}|[m]{1,}|[dD]{1,}|[yY]{2,})"); - std::wstring tmp = strFormatCode; + tmp = strFormatCode; - std::list result1; + std::vector result1; bool b1 = boost::regex_split(std::back_inserter(result1), tmp, re1); tmp = strFormatCode; - std::list result2; + std::vector result2; bool b2 = boost::regex_split(std::back_inserter(result2), tmp, re2); if (b1 && b2 && result1.size() > 2 && result2.size() > 2) diff --git a/OdfFile/Writer/Format/odf_number_styles_context.h b/OdfFile/Writer/Format/odf_number_styles_context.h index 3dca3db10f8..0fffa3d735d 100644 --- a/OdfFile/Writer/Format/odf_number_styles_context.h +++ b/OdfFile/Writer/Format/odf_number_styles_context.h @@ -49,7 +49,7 @@ typedef shared_ptr::Type office_element_ptr; struct number_format_state { - int oox_num_fmt;//дефолтные (по документации - номера 0-163, за исключением некоторых) + int oox_num_fmt;//дефолтные odf_types::office_value_type::type ods_type; @@ -59,6 +59,7 @@ struct number_format_state unsigned int language_code; std::wstring currency_str; + unsigned int currency_pos = 0; }; class odf_number_styles_context @@ -67,7 +68,7 @@ class odf_number_styles_context odf_number_styles_context(); void set_odf_context(odf_conversion_context * Context); - number_format_state & add_or_find(int oox_num_fmt, std::wstring formatCode = L""); + number_format_state & add_or_find(int oox_num_fmt, std::wstring formatCode = L""); void process_styles(office_element_ptr root ); private: @@ -81,7 +82,7 @@ class odf_number_styles_context void detect_format(number_format_state & state); //////////////// - odf_conversion_context *odf_context_; + odf_conversion_context *odf_context_; std::vector styles_elments; ////////////////// @@ -94,8 +95,6 @@ class odf_number_styles_context void create_percentage_style(number_format_state & state, office_element_ptr & root_elm); void create_numbers(number_format_state & state, office_element_ptr & elm, office_element_ptr & root_elm); - - }; } } diff --git a/OdfFile/Writer/Format/odf_settings_context.cpp b/OdfFile/Writer/Format/odf_settings_context.cpp index c64f185687c..3e1c91fd9c5 100644 --- a/OdfFile/Writer/Format/odf_settings_context.cpp +++ b/OdfFile/Writer/Format/odf_settings_context.cpp @@ -91,7 +91,7 @@ void odf_settings_context::end_table() { current_table_ = -1; } -void odf_settings_context::set_modify_info(const std::wstring& algorithm, const std::wstring& solt, const std::wstring& hash, int iteration_count) +void odf_settings_context::set_modify_info(const std::wstring& crypt, const std::wstring& algorithm, const std::wstring& solt, const std::wstring& hash, int iteration_count) { office_element_ptr elm_item_set; create_element(L"config", L"config-item-set", elm_item_set, odf_context_); @@ -100,9 +100,13 @@ void odf_settings_context::set_modify_info(const std::wstring& algorithm, const settings_config_item_set *item_set = dynamic_cast(elm_item_set.get()); if (item_set) { - item_set->config_name_ = L"ModifyPasswordInfo"; + item_set->config_name_ = (algorithm != L"PBKDF2") ? L"OOXMLModifyPasswordInfo" : L"ModifyPasswordInfo"; office_element_ptr prop; + if (false == crypt.empty()) + { + prop = create_property(L"crypt-name", L"string", crypt); elm_item_set->add_child_element(prop); + } prop = create_property(L"algorithm-name", L"string", algorithm); elm_item_set->add_child_element(prop); prop = create_property(L"salt", L"base64Binary", solt); elm_item_set->add_child_element(prop); prop = create_property(L"iteration-count", L"int", std::to_wstring(iteration_count)); elm_item_set->add_child_element(prop); diff --git a/OdfFile/Writer/Format/odf_settings_context.h b/OdfFile/Writer/Format/odf_settings_context.h index f91c5d25529..49eef559b74 100644 --- a/OdfFile/Writer/Format/odf_settings_context.h +++ b/OdfFile/Writer/Format/odf_settings_context.h @@ -70,7 +70,7 @@ class odf_settings_context void add_config_content_item(const std::wstring &name, const std::wstring &type, const std::wstring &value); void add_common_views_property(const std::wstring &name, const std::wstring &type, const std::wstring &value); - void set_modify_info(const std::wstring& algorithm, const std::wstring& solt, const std::wstring& hash, int iteration_count); + void set_modify_info(const std::wstring& crypt, const std::wstring& algorithm, const std::wstring& solt, const std::wstring& hash, int iteration_count); private: struct _table { diff --git a/OdfFile/Writer/Format/odf_table_context.cpp b/OdfFile/Writer/Format/odf_table_context.cpp index 06748830c5c..c6afbd9ed14 100644 --- a/OdfFile/Writer/Format/odf_table_context.cpp +++ b/OdfFile/Writer/Format/odf_table_context.cpp @@ -133,6 +133,11 @@ class odf_table_context::Impl _CP_OPT(double) default_column_width; bool optimal_column_width; + _CP_OPT(odf_types::length) default_cell_padding_left; + _CP_OPT(odf_types::length) default_cell_padding_right; + _CP_OPT(odf_types::length) default_cell_padding_top; + _CP_OPT(odf_types::length) default_cell_padding_bottom; + std::wstring default_cell_properties; // для предустановки .. private: @@ -406,11 +411,23 @@ std::wstring odf_table_context::get_default_cell_properties() else if (impl_->current_table().count_rows && impl_->current_table().current_row == *impl_->current_table().count_rows && false == impl_->current_table().last_row_cell_properties.empty()) { default_cell_props = impl_->current_table().last_row_cell_properties; - } + } + else if (impl_->current_table().current_column == 0 && false == impl_->current_table().first_col_cell_properties.empty()) + { + default_cell_props = impl_->current_table().first_col_cell_properties; + } + else if (impl_->current_table().count_cols && (impl_->current_table().current_column + 1) == *impl_->current_table().count_cols && false == impl_->current_table().last_col_cell_properties.empty()) + { + default_cell_props = impl_->current_table().last_col_cell_properties; + } else if (impl_->current_table().current_row % 2 == 0 && false == impl_->current_table().band_row_cell_properties.empty()) { default_cell_props = impl_->current_table().band_row_cell_properties; } + else if (impl_->current_table().current_column % 2 == 1 && false == impl_->current_table().band_col_cell_properties.empty()) + { + default_cell_props = impl_->current_table().band_col_cell_properties; + } return default_cell_props; } @@ -435,6 +452,23 @@ std::wstring odf_table_context::get_column_cell_properties() return default_cell_props; } + +void odf_table_context::set_default_cell_paddings(_CP_OPT(odf_types::length) left, _CP_OPT(odf_types::length) right, _CP_OPT(odf_types::length) top, _CP_OPT(odf_types::length) bottom) +{ + impl_->default_cell_padding_left = left; + impl_->default_cell_padding_right = right; + impl_->default_cell_padding_top = top; + impl_->default_cell_padding_bottom = bottom; +} + +void odf_table_context::get_default_cell_paddings(_CP_OPT(odf_types::length)& left, _CP_OPT(odf_types::length)& right, _CP_OPT(odf_types::length)& top, _CP_OPT(odf_types::length)& bottom) +{ + left = impl_->default_cell_padding_left; + right = impl_->default_cell_padding_right; + top = impl_->default_cell_padding_top; + bottom = impl_->default_cell_padding_bottom; +} + void odf_table_context::set_default_row_height(double height) { impl_->default_row_height = height; diff --git a/OdfFile/Writer/Format/odf_table_context.h b/OdfFile/Writer/Format/odf_table_context.h index b064b1a5431..47c4e5371e3 100644 --- a/OdfFile/Writer/Format/odf_table_context.h +++ b/OdfFile/Writer/Format/odf_table_context.h @@ -83,6 +83,17 @@ class odf_table_context void set_default_cell_properties(const std::wstring &style_name); std::wstring get_default_cell_properties(); std::wstring get_column_cell_properties(); + + void set_default_cell_paddings( + _CP_OPT(odf_types::length) left, + _CP_OPT(odf_types::length) right, + _CP_OPT(odf_types::length) top, + _CP_OPT(odf_types::length) bottom); + void get_default_cell_paddings( + _CP_OPT(odf_types::length)& left, + _CP_OPT(odf_types::length)& right, + _CP_OPT(odf_types::length)& top, + _CP_OPT(odf_types::length)& bottom); _CP_OPT(double) get_table_width(); _CP_OPT(double) get_table_height(); diff --git a/OdfFile/Writer/Format/odf_table_styles_context.cpp b/OdfFile/Writer/Format/odf_table_styles_context.cpp index 9e0cd7e287c..17fabf7a14c 100644 --- a/OdfFile/Writer/Format/odf_table_styles_context.cpp +++ b/OdfFile/Writer/Format/odf_table_styles_context.cpp @@ -439,6 +439,8 @@ void odf_table_styles_context::get_text_properties (int col, int row, text_forma } bool odf_table_styles_context::is_styled(int col, int row) { + if (current_used_.empty()) return false; + table_format_state & state = table_format_array_[current_used_.back().table_style_]; int col_shift = 0; diff --git a/OdfFile/Writer/Format/odf_text_context.cpp b/OdfFile/Writer/Format/odf_text_context.cpp index e5371d96ca3..286ca3c7086 100644 --- a/OdfFile/Writer/Format/odf_text_context.cpp +++ b/OdfFile/Writer/Format/odf_text_context.cpp @@ -269,6 +269,12 @@ void odf_text_context::start_paragraph(bool styled) start_paragraph(paragr_elm, styled); } +std::wstring odf_text_context::get_current_style_name() +{ + if (current_level_.empty()) return L""; + + return current_level_.back().style_name; +} void odf_text_context::start_paragraph(office_element_ptr & elm, bool styled) { size_t level = current_level_.size(); @@ -522,12 +528,12 @@ void odf_text_context::end_list() } //------------------------------------------------------------------------------------------ LIST -bool odf_text_context::start_field(int type, const std::wstring& value, const std::wstring& format) +office_element_ptr odf_text_context::start_field(int type, const std::wstring& value, const std::wstring& format) { - if (single_paragraph_ == true) return false; - office_element_ptr elm; + if (single_paragraph_ == true) return elm; + switch(type) { case fieldXE: @@ -596,6 +602,27 @@ bool odf_text_context::start_field(int type, const std::wstring& value, const st { create_element(L"text", L"text-input", elm, odf_context_); }break; + case fieldRef: + { + create_element(L"text", L"bookmark-ref", elm, odf_context_); + text_bookmark_ref* ref = dynamic_cast(elm.get()); + if (ref) + { + if (false == value.empty()) ref->ref_name_ = value; + + ref->reference_format_ = odf_types::reference_format::parse(format.empty() ? L"text" : format); + + } + }break; + case fieldUserDefined: + { + create_element(L"text", L"user-defined", elm, odf_context_); + text_user_defined* user_defined = dynamic_cast(elm.get()); + if (user_defined) + { + if (false == value.empty()) user_defined->text_name_ = value; + } + }break; } if (elm) @@ -604,10 +631,8 @@ bool odf_text_context::start_field(int type, const std::wstring& value, const st start_element(elm); current_level_.back().type = 3; - - return true; - } - return false; + } + return elm; } void odf_text_context::end_field() @@ -663,9 +688,14 @@ void odf_text_context::add_hyperlink (const std::wstring & link, const std::wstr if (!display.empty()) hyperlink->add_text(display); //////////////////////////// - - hyperlink->common_xlink_attlist_.href_ = link + (location.empty() ? L"" : (L"#" + location)); - hyperlink->common_xlink_attlist_.type_ = xlink_type::Simple; + + if (!link.empty()) + { + hyperlink->common_xlink_attlist_.href_ = link + (location.empty() ? L"" : (L"#" + location)); + hyperlink->common_xlink_attlist_.type_ = xlink_type::Simple; + } + else + odf_context_->add_hyperlink(elm, location); if (false == current_level_.empty()) current_level_.back().elm->add_child_element(elm); diff --git a/OdfFile/Writer/Format/odf_text_context.h b/OdfFile/Writer/Format/odf_text_context.h index 4158fca5301..c39bce1f7ca 100644 --- a/OdfFile/Writer/Format/odf_text_context.h +++ b/OdfFile/Writer/Format/odf_text_context.h @@ -58,6 +58,8 @@ namespace odf_writer fieldDropDown, fieldDate, fieldTime, + fieldRef, + fieldUserDefined, fieldBibliography = 0xff + 1, fieldIndex, @@ -97,6 +99,8 @@ class odf_text_context: boost::noncopyable void add_text_file_name (const std::wstring &text); void add_text_sheet_name(const std::wstring &text); + std::wstring get_current_style_name(); + void set_symbol_font (const std::wstring & font); void set_symbol_text (int sym); @@ -109,8 +113,8 @@ class odf_text_context: boost::noncopyable void add_element_in_span_or_par(office_element_ptr & elm); - bool start_field (int type, const std::wstring& value, const std::wstring& format); - void end_field (); + office_element_ptr start_field(int type, const std::wstring& value, const std::wstring& format); + void end_field(); void start_span (bool styled = false); void end_span (); diff --git a/OdfFile/Writer/Format/odp_conversion_context.cpp b/OdfFile/Writer/Format/odp_conversion_context.cpp index 567910bbc68..c5e283ddc04 100644 --- a/OdfFile/Writer/Format/odp_conversion_context.cpp +++ b/OdfFile/Writer/Format/odp_conversion_context.cpp @@ -55,7 +55,7 @@ namespace odf_writer { odp_conversion_context::odp_conversion_context(package::odf_document * outputDocument) - : odf_conversion_context (PresentationDocument, outputDocument), root_presentation_(NULL), slide_context_(*this) + : odf_conversion_context (PresentationDocument, outputDocument), root_presentation_(NULL), slide_context_(*this), rId_(1) { } odf_text_context* odp_conversion_context::text_context() @@ -126,6 +126,12 @@ void odp_conversion_context::start_slide() drawing_context()->set_presentation(0); } + +void odp_conversion_context::hide_slide() +{ + slide_context_.hide_page(); +} + void odp_conversion_context::end_slide() { slide_context_.end_page(); @@ -235,6 +241,48 @@ void odp_conversion_context::end_note() current_slide().drawing_context()->end_drawing(); } +int odp_conversion_context::next_id() +{ + return rId_++; +} + +std::wstring odp_conversion_context::map_indentifier(std::wstring id) +{ + const int page_index = slide_context_.page_index(); + if (page_index < 0 || page_index >= map_identifiers_.size()) + return L""; + + IdentifierMap& map = map_identifiers_[page_index]; + + IdentifierMap::iterator it = map.find(id); + if (it != map.end()) + return it->second; + + std::wstring odfId = L"id" + std::to_wstring(next_id()); + map.insert(std::make_pair(id, odfId)); + return odfId; +} + +std::wstring odp_conversion_context::get_mapped_identifier(const std::wstring& id) +{ + for (int i = map_identifiers_.size() - 1; i >= 0 ; i--) + { + const IdentifierMap& map = map_identifiers_[i]; + const IdentifierMap::const_iterator it = map.find(id); + + if (it != map.end()) + return it->second; + } + + return std::wstring(); +} + +void odp_conversion_context::add_page_name(const std::wstring& page_name) +{ + std::wstring pptx_slide_name = std::wstring(L"slide") + std::to_wstring(map_slidenames_.size() + 1); + + map_slidenames_.insert(std::make_pair(pptx_slide_name, page_name)); +} } } diff --git a/OdfFile/Writer/Format/odp_conversion_context.h b/OdfFile/Writer/Format/odp_conversion_context.h index 6810a8af4ba..76b32462166 100644 --- a/OdfFile/Writer/Format/odp_conversion_context.h +++ b/OdfFile/Writer/Format/odp_conversion_context.h @@ -59,6 +59,7 @@ class odp_conversion_context : public odf_conversion_context virtual void end_document(); void start_slide(); + void hide_slide(); void end_slide(); size_t get_pages_count(); @@ -89,10 +90,26 @@ class odp_conversion_context : public odf_conversion_context void start_note(bool bMaster = false); void end_note(); - std::map map_table_styles_; + int next_id(); + std::wstring map_indentifier(std::wstring id); + std::wstring get_mapped_identifier(const std::wstring& id); + + void add_page_name(const std::wstring& page_name); + + std::map map_table_styles_; + + // NOTE(Kamil Kerimov): Key - PPTX identifier, value - ODP identifier + using IdentifierMap = std::unordered_map; + std::vector map_identifiers_; + + // NOTE(Kamil Kerimov): Key - slide name in pptx (e.g. slide1.xml), Value - slide name in odp (e.g. "This is a title") + using SlidenameMap = std::map; + SlidenameMap map_slidenames_; private: odp_slide_context slide_context_; office_presentation* root_presentation_; + + int rId_; }; diff --git a/OdfFile/Writer/Format/odp_page_state.cpp b/OdfFile/Writer/Format/odp_page_state.cpp index 005033e4018..91adaf20ce4 100644 --- a/OdfFile/Writer/Format/odp_page_state.cpp +++ b/OdfFile/Writer/Format/odp_page_state.cpp @@ -92,6 +92,19 @@ void odp_page_state::set_page_duration(int id) page_properties_->content_.presentation_page_duration_ = id; } +void odp_page_state::hide_page() +{ + style* office_page_style_ = dynamic_cast(page_style_elm_.get()); + if (!office_page_style_) + return; + + drawing_page_properties* page_props = office_page_style_->content_.get_drawing_page_properties(); + if (!page_props) + return; + + page_props->presentation_visibility_ = presentation_visibility::hidden; +} + void odp_page_state::set_layout_page(std::wstring name) { if (name.empty())return; @@ -142,6 +155,7 @@ void odp_page_state::add_child_element( const office_element_ptr & child_element { page_elm_->add_child_element(child_element); } + void odp_page_state::set_anim_id (int val) { if (anim_levels.empty()) return; @@ -159,7 +173,7 @@ void odp_page_state::finalize_page() start_timing_par(); set_anim_duration(-1); set_anim_restart(L"never"); - set_anim_type(L"tmRoot"); + set_anim_type(odf_types::presentation_node_type::timing_root); end_timing_par(); end_timing(); } @@ -173,30 +187,30 @@ void odp_page_state::finalize_page() page_elm_->add_child_element(forms_root_elm); } } -void odp_page_state::set_anim_type(std::wstring val) +void odp_page_state::set_anim_type(const odf_types::presentation_node_type& val) { if (anim_levels.empty()) return; if (!anim_levels.back().attlist)return; - if (val == L"tmRoot") + anim_levels.back().attlist->presentation_node_type_ = val; + if (val.get_type() == presentation_node_type::timing_root) { - anim_levels.back().attlist->presentation_node_type_ = L"timing-root"; if (transactions.empty() == false) { std::wstring slide_id = L"slide" + std::to_wstring(page_id_) + L"id"; draw_page* page = dynamic_cast(page_elm_.get()); - if (page) + if (page) { page->attlist_.draw_id_ = slide_id; - + start_timing_par(); - anim_levels.back().attlist->smil_begin_ = slide_id + L".begin"; - while(!transactions.empty()) - { - anim_levels.back().elm->add_child_element( transactions[0] ); - transactions.erase(transactions.begin()); - } + anim_levels.back().attlist->smil_begin_ = slide_id + L".begin"; + while (!transactions.empty()) + { + anim_levels.back().elm->add_child_element(transactions[0]); + transactions.erase(transactions.begin()); + } end_timing_par(); } } @@ -208,7 +222,6 @@ void odp_page_state::set_anim_duration(int val) if (!anim_levels.back().attlist)return; anim_levels.back().attlist->smil_dur_ = odf_types::clockvalue(val); - } void odp_page_state::set_anim_restart(std::wstring val) { @@ -217,6 +230,361 @@ void odp_page_state::set_anim_restart(std::wstring val) anim_levels.back().attlist->smil_restart_ = val; } + +void odp_page_state::set_anim_fill(const odf_types::smil_fill& val) +{ + if (anim_levels.empty()) return; + if (!anim_levels.back().attlist)return; + + anim_levels.back().attlist->smil_fill_ = val; +} + +void odp_page_state::set_anim_begin(const std::wstring& val) +{ + if (anim_levels.empty()) return; + if (!anim_levels.back().attlist)return; + + anim_levels.back().attlist->smil_begin_ = val; +} + +void odp_page_state::set_anim_node_type(const odf_types::presentation_node_type& val) +{ + if (anim_levels.empty()) return; + if (!anim_levels.back().attlist)return; + + anim_levels.back().attlist->presentation_node_type_ = val; +} + +void odp_page_state::set_anim_preset_class(const odf_types::preset_class& val) +{ + if (anim_levels.empty()) return; + if (!anim_levels.back().attlist)return; + + anim_levels.back().par_attlist->presentation_preset_class_ = val; +} + +void odp_page_state::set_anim_preset_id(const odf_types::preset_id& val) +{ + if (anim_levels.empty()) return; + if (!anim_levels.back().attlist)return; + + anim_levels.back().par_attlist->presentation_preset_id_ = val; +} + +void odp_page_state::set_anim_attribute_name(const odf_types::smil_attribute_name& val) +{ + if (anim_levels.empty()) return; + if (!anim_levels.back().attlist)return; + + anim_levels.back().attlist->smil_attribute_name_ = val; +} + +void odp_page_state::set_anim_to(const std::wstring& val) +{ + if (anim_levels.empty()) return; + if (!anim_levels.back().attlist)return; + + anim_levels.back().set_attlist->smil_to_ = val; +} + +void odp_page_state::set_anim_target_element(const std::wstring& val) +{ + if (anim_levels.empty()) return; + if (!anim_levels.back().attlist)return; + + anim_levels.back().attlist->smil_target_element_ = val; +} + +void odp_page_state::set_anim_auto_reverse(bool val) +{ + if (anim_levels.empty()) return; + if (!anim_levels.back().attlist)return; + + anim_levels.back().attlist->smil_auto_reverse_ = val; +} + +void odp_page_state::set_anim_subtype(const std::wstring& val) +{ + if (anim_levels.empty()) return; + if (!anim_levels.back().attlist)return; + + anim_par* animate = dynamic_cast(anim_levels.back().elm.get()); + if (!animate) + return; + + anim_levels.back().par_attlist->presentation_preset_sub_type_ = val; +} + +void odp_page_state::set_anim_accelerate(double val) +{ + if (anim_levels.empty()) return; + if (!anim_levels.back().attlist)return; + + anim_levels.back().attlist->smil_accelerate_ = val; +} + +void odp_page_state::set_anim_decelerate(double val) +{ + if (anim_levels.empty()) return; + if (!anim_levels.back().attlist)return; + + anim_levels.back().attlist->smil_decelerate_ = val; +} + +void odp_page_state::set_anim_animation_formula(const std::wstring& val) +{ + if (anim_levels.empty()) return; + if (!anim_levels.back().attlist)return; + + anim_animate* animate= dynamic_cast(anim_levels.back().elm.get()); + if (!animate) + return; + + anim_levels.back().animate_attlist->anim_formula_ = val; +} + +void odp_page_state::set_anim_animation_keytimes(const odf_types::smil_key_times& val) +{ + if (anim_levels.empty()) return; + if (!anim_levels.back().attlist)return; + + anim_animate* animate = dynamic_cast(anim_levels.back().elm.get()); + if (!animate) + return; + + anim_levels.back().animate_attlist->smil_key_times_ = val; +} + +void odp_page_state::set_anim_animation_values(const odf_types::smil_values& val) +{ + if (anim_levels.empty()) return; + if (!anim_levels.back().attlist)return; + + anim_animate* animate = dynamic_cast(anim_levels.back().elm.get()); + if (!animate) + return; + + anim_levels.back().animate_attlist->smil_values_ = val; +} + +void odp_page_state::set_anim_animation_by(const std::wstring& val) +{ + if (anim_levels.empty()) return; + if (!anim_levels.back().attlist)return; + + anim_animate* animate = dynamic_cast(anim_levels.back().elm.get()); + if (!animate) + return; + + anim_levels.back().animate_attlist->smil_by_ = val; +} + +void odp_page_state::set_anim_animation_from(const std::wstring& val) +{ + if (anim_levels.empty()) return; + if (!anim_levels.back().attlist)return; + + anim_animate* animate = dynamic_cast(anim_levels.back().elm.get()); + if (!animate) + return; + + anim_levels.back().animate_attlist->smil_from_ = val; +} + +void odp_page_state::set_anim_animation_to(const std::wstring& val) +{ + if (anim_levels.empty()) return; + if (!anim_levels.back().attlist)return; + + anim_animate* animate = dynamic_cast(anim_levels.back().elm.get()); + if (!animate) + return; + + anim_levels.back().animate_attlist->smil_to_ = val; +} + +void odp_page_state::set_anim_animation_type(const odf_types::svg_type& val) +{ + if (anim_levels.empty()) return; + if (!anim_levels.back().attlist)return; + + anim_animate* animate = dynamic_cast(anim_levels.back().elm.get()); + if (!animate) + return; + + anim_levels.back().animate_attlist->svg_type_ = val; +} + +void odp_page_state::set_anim_transition_filter_mode(const std::wstring& val) +{ + if (anim_levels.empty()) return; + if (!anim_levels.back().attlist)return; + + anim_transitionFilter* transitionFilter = dynamic_cast(anim_levels.back().elm.get()); + if (!transitionFilter) + return; + + anim_levels.back().transition_filter_attlist->smil_mode_ = val; +} + +void odp_page_state::set_anim_transition_filter_type(const odf_types::smil_transition_type& val) +{ + if (anim_levels.empty()) return; + if (!anim_levels.back().attlist)return; + + anim_transitionFilter* transitionFilter = dynamic_cast(anim_levels.back().elm.get()); + if (!transitionFilter) + return; + + anim_levels.back().transition_filter_attlist->smil_type_ = val; +} + +void odp_page_state::set_anim_transition_filter_subtype(const std::wstring& val) +{ + if (anim_levels.empty()) return; + if (!anim_levels.back().attlist)return; + + anim_transitionFilter* transitionFilter = dynamic_cast(anim_levels.back().elm.get()); + if (!transitionFilter) + return; + + anim_levels.back().transition_filter_attlist->smil_subtype_ = val; +} + +void odp_page_state::set_anim_transition_filter_direction(const std::wstring& val) +{ + if (anim_levels.empty()) return; + if (!anim_levels.back().attlist)return; + + anim_transitionFilter* transitionFilter = dynamic_cast(anim_levels.back().elm.get()); + if (!transitionFilter) + return; + + anim_levels.back().transition_filter_attlist->smil_direction_ = val; +} + +void odp_page_state::set_anim_motion_path(const std::wstring& val) +{ + if (anim_levels.empty()) return; + if (!anim_levels.back().attlist)return; + + anim_animate_motion* motion = dynamic_cast(anim_levels.back().elm.get()); + if (!motion) + return; + + anim_levels.back().motion_attlist->svg_path_= val; +} + +void odp_page_state::set_anim_color_to(const std::wstring& val) +{ + if (anim_levels.empty()) return; + if (!anim_levels.back().attlist)return; + + anim_animate_color* color = dynamic_cast(anim_levels.back().elm.get()); + if (!color) + return; + + anim_levels.back().color_attlist->smil_to_= val; +} + +void odp_page_state::set_anim_color_by(const std::wstring& val) +{ + if (anim_levels.empty()) return; + if (!anim_levels.back().attlist)return; + + anim_animate_color* color = dynamic_cast(anim_levels.back().elm.get()); + if (!color) + return; + + anim_levels.back().color_attlist->smil_by_ = val; +} + +void odp_page_state::set_anim_color_interpolation(const std::wstring& val) +{ + if (anim_levels.empty()) return; + if (!anim_levels.back().attlist)return; + + anim_animate_color* color = dynamic_cast(anim_levels.back().elm.get()); + if (!color) + return; + + anim_levels.back().color_attlist->anim_color_interpolation_ = val; +} + +void odp_page_state::set_anim_color_direction(const std::wstring& val) +{ + if (anim_levels.empty()) return; + if (!anim_levels.back().attlist)return; + + anim_animate_color* color = dynamic_cast(anim_levels.back().elm.get()); + if (!color) + return; + + anim_levels.back().color_attlist->anim_color_interpolation_direction = val; +} + +void odp_page_state::set_anim_transform_type(const odf_types::svg_type& val) +{ + if (anim_levels.empty()) return; + if (!anim_levels.back().attlist)return; + + anim_animate_transform* transform = dynamic_cast(anim_levels.back().elm.get()); + if (!transform) + return; + + anim_levels.back().transform_attlist->svg_type_ = val; +} + +void odp_page_state::set_anim_transform_from(const std::wstring& val) +{ + if (anim_levels.empty()) return; + if (!anim_levels.back().attlist)return; + + anim_animate_transform* transform = dynamic_cast(anim_levels.back().elm.get()); + if (!transform) + return; + + anim_levels.back().transform_attlist->smil_from_= val; + + +} + +void odp_page_state::set_anim_transform_to(const std::wstring& val) +{ + if (anim_levels.empty()) return; + if (!anim_levels.back().attlist)return; + + anim_animate_transform* transform = dynamic_cast(anim_levels.back().elm.get()); + if (!transform) + return; + + anim_levels.back().transform_attlist->smil_to_ = val; +} + +void odp_page_state::set_anim_transform_by(const std::wstring& val) +{ + if (anim_levels.empty()) return; + if (!anim_levels.back().attlist)return; + + anim_animate_transform* transform = dynamic_cast(anim_levels.back().elm.get()); + if (!transform) + return; + + anim_levels.back().transform_attlist->smil_by_ = val; +} + +void odp_page_state::set_anim_audio_xlink(const std::wstring& val) +{ + if (anim_levels.empty()) return; + if (!anim_levels.back().attlist)return; + + anim_audio* audio = dynamic_cast(anim_levels.back().elm.get()); + if (!audio) + return; + + anim_levels.back().audio_attlist->xlink_href_ = val; +} + void odp_page_state::start_transition() { office_element_ptr elm; @@ -259,19 +627,19 @@ void odp_page_state::set_transition_speed(int val) { if (page_properties_) page_properties_->content_.presentation_transition_speed_ = L"fast"; - trans->common_attlist_.smil_dur_ = odf_types::clockvalue(2000); + trans->common_attlist_.smil_dur_ = odf_types::clockvalue(250); } if (val == 1) { if (page_properties_) page_properties_->content_.presentation_transition_speed_ = L"medium"; - trans->common_attlist_.smil_dur_ = odf_types::clockvalue(3000); + trans->common_attlist_.smil_dur_ = odf_types::clockvalue(500); } if (val == 2) { if (page_properties_) page_properties_->content_.presentation_transition_speed_ = L"slow"; - trans->common_attlist_.smil_dur_ = odf_types::clockvalue(4000); + trans->common_attlist_.smil_dur_ = odf_types::clockvalue(1000); } } } @@ -316,29 +684,99 @@ void odp_page_state::set_transition_sound(std::wstring ref, bool loop) void odp_page_state::start_timing_seq() { - if (anim_levels.empty()) return; + start_anim_level(L"anim", L"seq"); +} +void odp_page_state::start_timing() +{ + if (!anim_levels.empty()) + return; + + anim_state anim; + anim.elm = page_elm_; + + anim_levels.push_back(anim); +} + +void odp_page_state::start_anim_level(const std::wstring& ns, const std::wstring& name) +{ + if (anim_levels.empty()) + return; anim_state anim; - create_element(L"anim", L"seq", anim.elm, context_); - if (!anim.elm) return; + create_element(ns, name, anim.elm, context_); - anim_seq *seq = dynamic_cast(anim.elm.get()); - if (seq) anim.attlist = &seq->attlist_; + if (!anim.elm) + return; + + anim_par* par = dynamic_cast (anim.elm.get()); + anim_seq* seq = dynamic_cast (anim.elm.get()); + anim_set* set = dynamic_cast (anim.elm.get()); + anim_transitionFilter* transitionFilter = dynamic_cast (anim.elm.get()); + anim_animate* animate = dynamic_cast (anim.elm.get()); + anim_animate_motion* motion = dynamic_cast (anim.elm.get()); + anim_animate_color* color = dynamic_cast (anim.elm.get()); + anim_animate_transform* transfrom = dynamic_cast (anim.elm.get()); + anim_audio* audio = dynamic_cast (anim.elm.get()); + + if (par) + { + anim.attlist = &par->attlist_; + anim.par_attlist = &par->par_attlist_; + } + else if (seq) + { + anim.attlist = &seq->attlist_; + } + else if (set) + { + anim.attlist = &set->common_attlist_; + anim.set_attlist = &set->set_attlist_; + } + else if (transitionFilter) + { + anim.attlist = &transitionFilter->common_attlist_; + anim.transition_filter_attlist = &transitionFilter->filter_attlist_; + } + else if (animate) + { + anim.attlist = &animate->common_attlist_; + anim.animate_attlist = &animate->animate_attlist_; + } + else if (motion) + { + anim.attlist = &motion->common_attlist_; + anim.motion_attlist = &motion->animate_motion_attlist_; + } + else if (color) + { + anim.attlist = &color->common_attlist_; + anim.color_attlist = &color->color_attlist_; + } + else if (transfrom) + { + anim.attlist = &transfrom->common_attlist_; + anim.transform_attlist = &transfrom->animate_transform_attlist_; + } + else if (audio) + { + anim.attlist = &audio->common_attlist_; + anim.audio_attlist = &audio->audio_attlist_; + } anim_levels.back().empty = false; anim_levels.back().elm->add_child_element(anim.elm); - + anim_levels.push_back(anim); } -void odp_page_state::start_timing() + +void odp_page_state::end_anim_level() { - if (!anim_levels.empty()) return; - - anim_state anim; - anim.elm = page_elm_; - - anim_levels.push_back(anim); + if (anim_levels.empty()) + return; + + anim_levels.pop_back(); } + void odp_page_state::end_timing() { if (anim_levels.empty()) return; @@ -346,29 +784,86 @@ void odp_page_state::end_timing() } void odp_page_state::end_timing_seq() { - if (anim_levels.empty()) return; - anim_levels.pop_back(); + end_anim_level(); } -void odp_page_state::start_timing_par() + +void odp_page_state::start_timing_set() { - if (anim_levels.empty()) return; + start_anim_level(L"anim", L"set"); +} - anim_state anim; - create_element(L"anim", L"par", anim.elm, context_); - if (!anim.elm) return; +void odp_page_state::end_timing_set() +{ + end_anim_level(); +} + +void odp_page_state::start_timing_transition_filter() +{ + start_anim_level(L"anim", L"transitionFilter"); +} - anim_par *par = dynamic_cast(anim.elm.get()); - if (par) anim.attlist = &par->attlist_; +void odp_page_state::end_timing_transition_filter() +{ + end_anim_level(); +} - anim_levels.back().empty = false; - anim_levels.back().elm->add_child_element(anim.elm); +void odp_page_state::start_timing_anim() +{ + start_anim_level(L"anim", L"animate"); +} - anim_levels.push_back(anim); +void odp_page_state::end_timing_anim() +{ + end_anim_level(); +} + +void odp_page_state::start_timing_motion() +{ + start_anim_level(L"anim", L"animateMotion"); +} + +void odp_page_state::end_timing_motion() +{ + end_anim_level(); +} + +void odp_page_state::start_timing_anim_clr() +{ + start_anim_level(L"anim", L"animateColor"); +} + +void odp_page_state::end_timing_anim_clr() +{ + end_anim_level(); +} + +void odp_page_state::start_timing_transform() +{ + start_anim_level(L"anim", L"animateTransform"); +} + +void odp_page_state::end_timing_transform() +{ + end_anim_level(); +} + +void odp_page_state::start_anim_audio() +{ + start_anim_level(L"anim", L"audio"); +} + +void odp_page_state::end_anim_audio() +{ + end_anim_level(); +} + +void odp_page_state::start_timing_par() +{ + start_anim_level(L"anim", L"par"); } void odp_page_state::end_timing_par() { - if (anim_levels.empty()) return; - anim_levels.pop_back(); + end_anim_level(); } } } diff --git a/OdfFile/Writer/Format/odp_page_state.h b/OdfFile/Writer/Format/odp_page_state.h index 49911b88c89..72baafd36ca 100644 --- a/OdfFile/Writer/Format/odp_page_state.h +++ b/OdfFile/Writer/Format/odp_page_state.h @@ -61,7 +61,15 @@ struct anim_state int id; office_element_ptr elm; - odf_types::common_anim_smil_attlist* attlist; + odf_types::common_anim_smil_attlist* attlist; + odf_types::anim_par_attlist* par_attlist; + odf_types::anim_set_attlist* set_attlist; + odf_types::anim_transition_filter_attlist* transition_filter_attlist; + odf_types::anim_animate_attlist* animate_attlist; + odf_types::anim_animate_motion_attlist* motion_attlist; + odf_types::anim_animate_color_attlist* color_attlist; + odf_types::anim_animate_transform_attlist* transform_attlist; + odf_types::anim_audio_attlist* audio_attlist; bool empty; }; @@ -75,6 +83,8 @@ class odp_page_state void set_page_id (int id); void set_page_style (office_element_ptr & _style); void set_page_duration (int id); + + void hide_page(); void set_master_page(std::wstring name); void set_layout_page(std::wstring name); @@ -95,16 +105,81 @@ class odp_page_state std::vector transactions; void start_timing(); + void start_anim_level(const std::wstring& ns, const std::wstring& name); + void end_anim_level(); + void start_timing_par(); void end_timing_par(); void start_timing_seq(); void end_timing_seq(); - void set_anim_id (int val); - void set_anim_type (std::wstring val); - void set_anim_duration (int val); - void set_anim_restart (std::wstring val); + void start_timing_set(); + void end_timing_set(); + + void start_timing_transition_filter(); + void end_timing_transition_filter(); + + void start_timing_anim(); + void end_timing_anim(); + + void start_timing_motion(); + void end_timing_motion(); + + void start_timing_anim_clr(); + void end_timing_anim_clr(); + + void start_timing_transform(); + void end_timing_transform(); + + void start_anim_audio(); + void end_anim_audio(); + + void set_anim_id (int val); + void set_anim_type (const odf_types::presentation_node_type& val); + void set_anim_duration (int val); + void set_anim_restart (std::wstring val); + void set_anim_fill (const odf_types::smil_fill& val); + void set_anim_begin (const std::wstring& val); + void set_anim_node_type (const odf_types::presentation_node_type& val); + void set_anim_preset_class (const odf_types::preset_class& val); + void set_anim_preset_id (const odf_types::preset_id& val); + void set_anim_attribute_name(const odf_types::smil_attribute_name& val); + void set_anim_to (const std::wstring& val); + void set_anim_target_element(const std::wstring& val); + void set_anim_auto_reverse (bool val); + void set_anim_subtype (const std::wstring& val); + void set_anim_accelerate (double val); + void set_anim_decelerate (double val); + + void set_anim_animation_formula(const std::wstring& val); + void set_anim_animation_keytimes(const odf_types::smil_key_times& val); + void set_anim_animation_values(const odf_types::smil_values& val); + void set_anim_animation_by(const std::wstring& val); + void set_anim_animation_from(const std::wstring& val); + void set_anim_animation_to(const std::wstring& val); + void set_anim_animation_type(const odf_types::svg_type& val); + + void set_anim_transition_filter_mode(const std::wstring& val); + void set_anim_transition_filter_type(const odf_types::smil_transition_type& val); + void set_anim_transition_filter_subtype(const std::wstring& val); + void set_anim_transition_filter_direction(const std::wstring& val); + + void set_anim_motion_path(const std::wstring& val); + + void set_anim_color_to(const std::wstring& val); + void set_anim_color_by(const std::wstring& val); + void set_anim_color_interpolation(const std::wstring& val); + void set_anim_color_direction(const std::wstring& val); + + void set_anim_transform_type(const odf_types::svg_type& val); + void set_anim_transform_from(const std::wstring& val); + void set_anim_transform_to(const std::wstring& val); + void set_anim_transform_by(const std::wstring& val); + + void set_anim_audio_xlink(const std::wstring& val); + + void end_timing(); void start_transition(); diff --git a/OdfFile/Writer/Format/odp_slide_context.cpp b/OdfFile/Writer/Format/odp_slide_context.cpp index 76470d0e8f0..209758e6424 100644 --- a/OdfFile/Writer/Format/odp_slide_context.cpp +++ b/OdfFile/Writer/Format/odp_slide_context.cpp @@ -66,8 +66,14 @@ odp_page_state & odp_slide_context::state() return page_state_list_.back(); } +int odp_slide_context::page_index() +{ + return count_slides_ - 1; +} + void odp_slide_context::start_page(office_element_ptr & elm) { + context_.map_identifiers_.push_back(odp_conversion_context::IdentifierMap()); page_state_list_.push_back( odp_page_state(&context_, elm) ); std::wstring style_name_new = L"dp" + std::to_wstring(++count_slides_); @@ -80,6 +86,11 @@ void odp_slide_context::start_page(office_element_ptr & elm) state().drawing_context()->set_styles_context(styles_context_); } +void odp_slide_context::hide_page() +{ + state().hide_page(); +} + void odp_slide_context::end_page() { state().drawing_context()->finalize(state().page_elm_); @@ -185,7 +196,7 @@ void odp_slide_context::start_table_row (bool styled) if (styled) { - styles_context_->create_style(L"",odf_types::style_family::TableRow, true, false, -1); + styles_context_->create_style(L"", odf_types::style_family::TableRow, true, false, -1); odf_style_state_ptr style_state = styles_context_->last_state(style_family::TableRow); if (style_state) diff --git a/OdfFile/Writer/Format/odp_slide_context.h b/OdfFile/Writer/Format/odp_slide_context.h index 96805b94bad..e41648b7b27 100644 --- a/OdfFile/Writer/Format/odp_slide_context.h +++ b/OdfFile/Writer/Format/odp_slide_context.h @@ -81,6 +81,7 @@ class odp_slide_context odp_slide_context(odp_conversion_context & Context); void start_page (office_element_ptr & elm); + void hide_page(); void end_page (); void remove_page(); @@ -104,6 +105,7 @@ class odp_slide_context void end_table (); odp_page_state & state(); + int page_index(); private: diff --git a/OdfFile/Writer/Format/ods_conversion_context.cpp b/OdfFile/Writer/Format/ods_conversion_context.cpp index 07d86f81de5..d529fabbcd1 100644 --- a/OdfFile/Writer/Format/ods_conversion_context.cpp +++ b/OdfFile/Writer/Format/ods_conversion_context.cpp @@ -201,6 +201,7 @@ void ods_conversion_context::start_row(int _start_row, int repeated, int level, add_default_row(repeated_default); } + if (in_rows_) level += 1; //------------------------------------------------------------------------------------------- while (level < current_table()->current_level()) { @@ -209,7 +210,7 @@ void ods_conversion_context::start_row(int _start_row, int repeated, int level, while (level > current_table()->current_level()) { office_element_ptr row_group_elm; - create_element(L"table", L"table-row-group",row_group_elm,this); + create_element(L"table", L"table-row-group", row_group_elm, this); current_table()->start_group(row_group_elm); } //------------------------------------------------------------------------------------------- @@ -264,14 +265,12 @@ void ods_conversion_context::start_row(int _start_row, int repeated, int level, else row_properties->style_table_row_properties_attlist_.common_break_attlist_.fo_break_before_ = fo_break(fo_break::Auto); } - header_row_ = false; + in_header_row_ = false; if (_start_row == 1 && (false == current_table()->table_parts().empty()) && (false == current_table()->table_parts().back().columns.empty())) { - header_row_ = true; + in_header_row_ = true; repeated = 1; - } - if (header_row_) - { + office_element_ptr row_headers_elm; create_element(L"table", L"table-header-rows", row_headers_elm, this); current_table()->start_headers(row_headers_elm); @@ -296,9 +295,16 @@ void ods_conversion_context::end_row() current_table()->add_default_cell(repeated); } - if (header_row_) + if (in_header_row_) { + in_header_row_ = false; current_table()->end_headers(); + + office_element_ptr rows_elm; + create_element(L"table", L"table-rows", rows_elm, this); + current_table()->start_rows(rows_elm); + + in_rows_ = true; } } ////////////////////// @@ -557,10 +563,16 @@ void ods_conversion_context::add_default_row(int repeated) void ods_conversion_context::end_rows() { //add default last row - int repeated = (std::max)(current_table()->dimension_row, 64) - current_table()->current_row(); + int repeated = (std::max)(current_table()->dimension_row, 64) - current_table()->current_row(); if (repeated < 0) repeated = 1; add_default_row(repeated); + + if (in_rows_) + { + in_rows_ = false; + current_table()->end_rows(); + } } void ods_conversion_context::add_column(int start_column, int repeated, int level, bool _default) { @@ -628,10 +640,21 @@ void ods_conversion_context::add_column(int start_column, int repeated, int leve else column_properties->attlist_.common_break_attlist_.fo_break_before_ = fo_break(fo_break::Auto); } - office_element_ptr column_elm; create_element(L"table", L"table-column", column_elm, this); - + + if (start_column == 1 && (false == current_table()->table_parts().empty()) && (false == current_table()->table_parts().back().columns.empty())) + { + office_element_ptr column_headers_elm; + create_element(L"table", L"table-header-columns", column_headers_elm, this); + + current_table()->start_headers(column_headers_elm); + current_table()->add_column(column_elm, 1, style_elm); + current_table()->end_headers(); + + repeated -= 1; + } + current_table()->add_column(column_elm, repeated, style_elm); if (_default) diff --git a/OdfFile/Writer/Format/ods_conversion_context.h b/OdfFile/Writer/Format/ods_conversion_context.h index 7d22aaf2b43..e9c57a53b8a 100644 --- a/OdfFile/Writer/Format/ods_conversion_context.h +++ b/OdfFile/Writer/Format/ods_conversion_context.h @@ -139,7 +139,9 @@ class ods_conversion_context : public odf_conversion_context ods_table_context table_context_; office_spreadsheet* root_spreadsheet_; bool repeat_at_lasts_ = true; - bool header_row_ = false; + + bool in_header_row_ = false; + bool in_rows_ = false; }; diff --git a/OdfFile/Writer/Format/ods_table_context.cpp b/OdfFile/Writer/Format/ods_table_context.cpp index ba405cc273a..1d0475d935a 100644 --- a/OdfFile/Writer/Format/ods_table_context.cpp +++ b/OdfFile/Writer/Format/ods_table_context.cpp @@ -89,7 +89,7 @@ ods_table_state_ptr & ods_table_context::state() void ods_table_context::start_table_part(const std::wstring &name, std::wstring ref) { - if (!table_database_ranges_.root) create_element(L"table", L"database-ranges",table_database_ranges_.root,&context_); + if (!table_database_ranges_.root) create_element(L"table", L"database-ranges", table_database_ranges_.root, &context_); office_element_ptr elm; create_element(L"table", L"database-range",elm, &context_); @@ -118,11 +118,17 @@ void ods_table_context::start_table_part(const std::wstring &name, std::wstring part_state.name = name; part_state.ref = ref; - int r = ref.rfind(L":"); - if (r < 0) return;//тута однозначно .. по правилам оох + size_t pos = ref.rfind(L"!"); + if (pos != std::wstring::npos) + { + ref = ref.substr(pos + 1); + } - utils::parsing_ref (ref.substr(0, r), part_state.col_start, part_state.row_start); - utils::parsing_ref (ref.substr(r + 1, ref.size() - r), part_state.col_end, part_state.row_end); + pos = ref.rfind(L":"); + if (pos == std::wstring::npos) return;//тута однозначно .. по правилам оох + + utils::parsing_ref (ref.substr(0, pos), part_state.col_start, part_state.row_start); + utils::parsing_ref (ref.substr(pos + 1, ref.size() - pos), part_state.col_end, part_state.row_end); state()->table_parts_.push_back(part_state); } @@ -138,14 +144,22 @@ void ods_table_context::add_table_part_column(std::wstring name) bool bQuotes = (std::wstring::npos != table_state_list_.back()->office_table_name_.find(L" ")); std::wstring ref = L"$"; - + std::wstring refUse = L"$"; + ref += (bQuotes ? L"'" : L"") + table_state_list_.back()->office_table_name_ + (bQuotes ? L"'" : L"") + L"."; + refUse += (bQuotes ? L"'" : L"") + table_state_list_.back()->office_table_name_ + (bQuotes ? L"'" : L"") + L"."; ref += sCol + std::to_wstring(state()->table_parts_.back().row_start); ref += L":"; ref += sCol + std::to_wstring(state()->table_parts_.back().row_end); - state()->table_parts_.back().columns.push_back(std::make_pair(name, ref)); + refUse += sCol + std::to_wstring(state()->table_parts_.back().row_start + 1); + refUse += L":"; + refUse += sCol + std::to_wstring(state()->table_parts_.back().row_end); + + state()->mapTabled.insert(std::make_pair(name, refUse)); + + state()->table_parts_.back().columns.push_back(std::make_pair(name, refUse)); } void ods_table_context::set_table_part_autofilter(bool val) { @@ -572,9 +586,9 @@ void ods_table_context::start_table(office_element_ptr & elm) std::wstring style_name_new = L"ta" + boost::lexical_cast(table_state_list_.size()); - office_element_ptr & style = context_.styles_context()->add_or_find(style_name_new, style_family::Table, true); + office_element_ptr& style = context_.styles_context()->add_or_find(style_name_new, style_family::Table, true); style->create_child_element(L"style", L"table-properties"); - + state()->set_table_style(style); state()->set_table_hidden(false); diff --git a/OdfFile/Writer/Format/ods_table_state.cpp b/OdfFile/Writer/Format/ods_table_state.cpp index ba6ddbe5dda..c294b3eb188 100644 --- a/OdfFile/Writer/Format/ods_table_state.cpp +++ b/OdfFile/Writer/Format/ods_table_state.cpp @@ -58,18 +58,18 @@ namespace cpdoccore { namespace odf_writer { -int ods_table_state::current_table_column_ = 0; -int ods_table_state::current_table_row_ = 0; + _INT32 ods_table_state::current_table_column_ = 0; + _INT32 ods_table_state::current_table_row_ = 0; -int ods_table_state::tmp_column_ =0; -int ods_table_state::tmp_row_ =0; + _INT32 ods_table_state::tmp_column_ =0; + _INT32 ods_table_state::tmp_row_ =0; namespace utils//////////////////////////////////////////// ОБЩАЯ хрень .. вытащить что ли в utils ??? { std::wstring convert_date(int date) { - boost::gregorian::date date_ = boost::gregorian::date(1900, 1, 1) + boost::gregorian::date_duration(date - 2); + boost::gregorian::date date_ = boost::gregorian::date(1900, 1, 1) + boost::gregorian::date_duration( date - (date < 60 ? 1 : 2)); //29.02.1900 std::wstring date_str; @@ -100,9 +100,9 @@ namespace utils//////////////////////////////////////////// ОБЩАЯ хрен } return convert_date(iDate); } - std::wstring convert_time(double dTime) + std::wstring convert_time(double dTime, bool bPT) { - //12H15M42S + //12H15M42S - pt int hours = 0, minutes = 0; double sec = 0; @@ -110,23 +110,20 @@ namespace utils//////////////////////////////////////////// ОБЩАЯ хрен double millisec = day.total_milliseconds() * dTime; - sec = millisec / 1000.; hours = (int)(sec / 60. / 60.); - minutes = (int)((sec - (hours * 60 * 60)) / 60.); - sec = sec - (hours * 60 + minutes) * 60.; + minutes = (int)((sec - (hours * (int)60 * (int)60)) / 60.); + sec = sec - (hours * (int)60 + minutes) * 60.; int sec1 = (int)sec; std::wstring time_str = (hours < 10 ? L"0" : L"") + boost::lexical_cast(hours) - //+ std::wstring(L"H") + - + std::wstring(L":") + + + (bPT ? std::wstring(L"H") : std::wstring(L":")) + (minutes < 10 ? L"0" : L"") + boost::lexical_cast(minutes) - //+ std::wstring(L"M") + - + std::wstring(L":") + - (sec1 < 10 ? L"0" : L"") + boost::lexical_cast(sec1); - //+ std::wstring(L"S"); + + (bPT ? std::wstring(L"M") : std::wstring(L":")) + + (sec1 < 10 ? L"0" : L"") + boost::lexical_cast(sec1) + + (bPT ? std::wstring(L"S") : std::wstring(L"")); return time_str; } @@ -148,7 +145,7 @@ namespace utils//////////////////////////////////////////// ОБЩАЯ хрен std::wstring sDate, sTime; if (dTime > 0) { - sTime = convert_time(dTime); + sTime = convert_time(dTime, false); } if (nDate > 0) { @@ -173,8 +170,7 @@ namespace utils//////////////////////////////////////////// ОБЩАЯ хрен { return oox_time; } - //PT12H15M42S - return std::wstring(L"PT") + convert_time(dTime); + return std::wstring(L"PT") + convert_time(dTime, true); } }; @@ -324,7 +320,7 @@ void ods_table_state::set_table_style(office_element_ptr & elm) { office_table_style_ = dynamic_cast(elm.get()); - if (!office_table_style_)return; + if (!office_table_style_) return; table_table* table = dynamic_cast(office_table_.get()); if (table == NULL)return; @@ -337,11 +333,19 @@ void ods_table_state::start_group(office_element_ptr & elm) current_level_.back()->add_child_element(elm); current_level_.push_back(elm); } - void ods_table_state::end_group() { current_level_.pop_back(); } +void ods_table_state::start_rows(office_element_ptr& elm) +{ + current_level_.back()->add_child_element(elm); + current_level_.push_back(elm); +} +void ods_table_state::end_rows() +{ + current_level_.pop_back(); +} void ods_table_state::start_headers(office_element_ptr & elm) { current_level_.back()->add_child_element(elm); @@ -351,40 +355,39 @@ void ods_table_state::end_headers() { current_level_.pop_back(); } -void ods_table_state::add_column_break(int val) +void ods_table_state::add_column_break(_INT32 val) { column_breaks_.push_back(val + 1); } -void ods_table_state::add_row_break(int val) +void ods_table_state::add_row_break(_INT32 val) { row_breaks_.push_back(val + 1); } -void ods_table_state::add_column(office_element_ptr & elm, unsigned int repeated,office_element_ptr & style_elm) +void ods_table_state::add_column(office_element_ptr & elm, _UINT32 repeated, office_element_ptr & style_elm) { current_level_.back()->add_child_element(elm); std::wstring style_name; odf_writer::style* style = dynamic_cast(style_elm.get()); - if (style)style_name = style->style_name_; + if (style) style_name = style->style_name_; + + ods_column_state state(elm, repeated, style_name, style_elm, defaut_column_width_, current_level_.size()); - ods_element_state state(elm, repeated, style_name, style_elm, defaut_column_width_, current_level_.size()); - //if (repeated > 10000) repeated = 1024;//???? current_table_column_ += repeated; - columns_.push_back(state); + columns_.push_back(state); table_table_column* column = dynamic_cast(columns_.back().elm.get()); - if (column == NULL)return; + if (column == NULL) return; if (false == style_name.empty()) column->attlist_.table_style_name_ = style_name; column->attlist_.table_number_columns_repeated_ = repeated; - } void ods_table_state::set_column_default_cell_style(std::wstring & style_name) { - if (style_name.length() < 1)return; + if (style_name.empty()) return; table_table_column* column = dynamic_cast(columns_.back().elm.get()); if (column == NULL)return; @@ -393,13 +396,13 @@ void ods_table_state::set_column_default_cell_style(std::wstring & style_name) columns_.back().cell_style_name = style_name; } -std::wstring ods_table_state::get_column_default_cell_style(int column) +std::wstring ods_table_state::get_column_default_cell_style(_INT32 column) { - int curr=0; + _INT32 curr = 0; for (size_t i=0; i < columns_.size(); i++) { - if (curr + (int)columns_[i].repeated < column + 1)continue; + if (curr + (_INT32)columns_[i].repeated < column + 1) continue; else { return columns_[i].cell_style_name; @@ -447,7 +450,7 @@ void ods_table_state::set_column_hidden(bool val) column->attlist_.table_visibility_ = table_visibility(table_visibility::Collapse); } -void ods_table_state::set_table_dimension(int col, int row) +void ods_table_state::set_table_dimension(_INT32 col, _INT32 row) { if (col < 1 || row < 1 ) return; @@ -455,7 +458,7 @@ void ods_table_state::set_table_dimension(int col, int row) if (dimension_row < row) dimension_row = row + 1; } -void ods_table_state::add_row(office_element_ptr & elm, unsigned int repeated, office_element_ptr & style_elm) +void ods_table_state::add_row(office_element_ptr & elm, _UINT32 repeated, office_element_ptr & style_elm) { current_table_column_ = 0; current_table_row_ += repeated; @@ -470,33 +473,31 @@ void ods_table_state::add_row(office_element_ptr & elm, unsigned int repeated, o i--; } } - current_level_.back()->add_child_element(elm); std::wstring style_name; odf_writer::style* style = dynamic_cast(style_elm.get()); - if (style)style_name = style->style_name_; + if (style) style_name = style->style_name_; - ods_element_state state(elm, repeated, style_name, style_elm, defaut_row_height_ , current_level_.size()); + ods_row_state state(elm, repeated, style_name, style_elm, defaut_row_height_, current_level_.size()); rows_.push_back(state); table_table_row* row = dynamic_cast(rows_.back().elm.get()); - if (row == NULL)return; + if (row == NULL) return; if (false == style_name.empty()) row->attlist_.table_style_name_ = style_name; row->attlist_.table_number_rows_repeated_ = repeated; row_default_cell_style_name_ = L""; - } void ods_table_state::add_row_repeated() { table_table_row* row = dynamic_cast(rows_.back().elm.get()); - if (row == NULL)return; + if (row == NULL) return; - unsigned int t = rows_.back().repeated; + _UINT32 t = rows_.back().repeated; rows_.back().repeated++; current_table_row_++; @@ -555,31 +556,31 @@ bool ods_table_state::is_cell_comment() bool ods_table_state::is_cell_data_validation() { if (cells_.empty()) return false; - return cells_.back().data_validation_name.empty() ? true : false; + return cells_.back().data_validation_idx >= 0 ? true : false; } -int ods_table_state::is_cell_hyperlink(int col, int row) +_INT32 ods_table_state::is_cell_hyperlink(_INT32 col, _INT32 row) { for (size_t i = 0; i < hyperlinks_.size(); i++) { if (hyperlinks_[i].col == col && hyperlinks_[i].row == row) { - return (int)i; + return (_INT32)i; } } return -1; } -std::wstring ods_table_state::is_cell_data_validation(int col, int row, unsigned int repeate_col, data_validation_state::_ref & ref) +_INT32 ods_table_state::is_cell_data_validation(_INT32 col, _INT32 row, _UINT32 repeate_col, data_validation_state::_ref & ref) { for (size_t i = 0; i < data_validations_.size(); i++) { if (data_validations_[i].in_ref(col, row, repeate_col, ref)) { - return data_validations_[i].name; + return (_INT32)i; } } - return L""; + return -1; } -int ods_table_state::is_row_validation(int row, int & repeate_row) +_INT32 ods_table_state::is_row_validation(_INT32 row, _INT32 & repeate_row) { for (size_t i = 0; i < data_validations_.size(); i++) { @@ -594,18 +595,18 @@ int ods_table_state::is_row_validation(int row, int & repeate_row) } return -1; } -int ods_table_state::is_cell_comment(int col, int row, unsigned int repeate_col) +_INT32 ods_table_state::is_cell_comment(_INT32 col, _INT32 row, _UINT32 repeate_col) { for (size_t i = 0; i < comments_.size(); i++) { - if ((comments_[i].col < col + (int)repeate_col && comments_[i].col >= col) && comments_[i].row == row && comments_[i].used == false) + if ((comments_[i].col < col + (_INT32)repeate_col && comments_[i].col >= col) && comments_[i].row == row && comments_[i].used == false) { - return (int)i; + return (_INT32)i; } } return -1; } -int ods_table_state::is_row_comment(int row, int repeate_row) +_INT32 ods_table_state::is_row_comment(_INT32 row, _INT32 repeate_row) { for (size_t i = 0; i < comments_.size(); i++) { @@ -616,18 +617,18 @@ int ods_table_state::is_row_comment(int row, int repeate_row) } return -1; } -int ods_table_state::current_column() const +_INT32 ods_table_state::current_column() const { return current_table_column_; } -int ods_table_state::current_row() const +_INT32 ods_table_state::current_row() const { return current_table_row_; } -unsigned int ods_table_state::get_last_row_repeated () +_UINT32 ods_table_state::get_last_row_repeated () { return rows_.empty() ? 1 : rows_.back().repeated; } @@ -671,35 +672,36 @@ ods_hyperlink_state & ods_table_state::current_hyperlink() void ods_table_state::start_cell(office_element_ptr & elm, office_element_ptr & style_elm) { current_row_element()->add_child_element(elm); - + std::wstring style_name; + table_table_cell* cell = dynamic_cast(elm.get()); + table_covered_table_cell* covered_cell = dynamic_cast(elm.get()); + odf_writer::style* style = dynamic_cast(style_elm.get()); if (style) style_name = style->style_name_; else style_name = row_default_cell_style_name_; - table_table_cell* cell = dynamic_cast(elm.get()); - if (cell && !style_name.empty() && style_name != get_column_default_cell_style(current_column())) + if (cell && !style_name.empty() && style_name != get_column_default_cell_style(current_column())) { - cell->attlist_.table_style_name_ = style_name; + cell->attlist_.table_style_name_ = style_name; } - table_covered_table_cell* covered_cell = dynamic_cast(elm.get()); - if (covered_cell && !style_name.empty() && style_name != get_column_default_cell_style(current_column())) + if (covered_cell && !style_name.empty() && style_name != get_column_default_cell_style(current_column())) { - covered_cell->attlist_.table_style_name_ = style_name; + covered_cell->attlist_.table_style_name_ = style_name; } + ods_cell_state state; state.empty = true; - state.elm = elm; state.repeated = 1; state.style_name = style_name; state.style_elm = style_elm; + state.elm = elm; state.repeated = 1; state.style_name = style_name; state.style_elm = style_name.empty() ? office_element_ptr() : style_elm; state.row = current_table_row_; state.col = current_table_column_ + 1; data_validation_state::_ref ref; - std::wstring validation_name = is_cell_data_validation(state.col, state.row, 1, ref); - state.hyperlink_idx = is_cell_hyperlink(state.col, state.row); - state.comment_idx = is_cell_comment(state.col, state.row); - state.data_validation_name = validation_name; + state.hyperlink_idx = is_cell_hyperlink(state.col, state.row); + state.comment_idx = is_cell_comment(state.col, state.row); + state.data_validation_idx = is_cell_data_validation(state.col, state.row, 1, ref); current_table_column_ += state.repeated; cells_.push_back(state); @@ -764,7 +766,7 @@ void ods_table_state::add_definded_expression(office_element_ptr & elm) if (!table_defined_expressions_)return; table_defined_expressions_->add_child_element(elm); } -void ods_table_state::add_hyperlink(const std::wstring & ref,int col, int row, const std::wstring & link, const std::wstring & location) +void ods_table_state::add_hyperlink(const std::wstring & ref, _INT32 col, _INT32 row, const std::wstring & link, const std::wstring & location) { ods_hyperlink_state state; state.row = row; state.col = col; state.ref = ref; @@ -783,7 +785,7 @@ void ods_table_state::add_hyperlink(const std::wstring & ref,int col, int row, c hyperlinks_.push_back(state); } -void ods_table_state::start_comment(int col, int row, std::wstring & author) +void ods_table_state::start_comment(_INT32 col, _INT32 row, std::wstring & author) { ods_comment_state state; @@ -791,7 +793,7 @@ void ods_table_state::start_comment(int col, int row, std::wstring & author) create_element(L"office", L"annotation", state.elm, context_); office_annotation * annotation = dynamic_cast(state.elm.get()); - if (!annotation)return; + if (!annotation) return; context_->styles_context()->create_style(L"", style_family::Graphic, true, false, -1); @@ -863,15 +865,15 @@ void ods_table_state::end_comment(odf_text_context *text_context) void ods_table_state::check_spanned_cells() { - for (std::map>::iterator it = map_merged_cells.begin(); it != map_merged_cells.end(); ++it) + for (std::map<_INT32, std::map<_INT32, _spanned_info>>::iterator it = map_merged_cells.begin(); it != map_merged_cells.end(); ++it) { - for (std::map::iterator jt = it->second.begin(); jt != it->second.end(); ++jt) + for (std::map<_INT32, _spanned_info>::iterator jt = it->second.begin(); jt != it->second.end(); ++jt) { - int start_row = it->first; - int end_row = it->first + jt->second.spanned_rows; + _INT32 start_row = it->first; + _INT32 end_row = it->first + jt->second.spanned_rows; - int start_col = jt->first; - int end_col = jt->first + jt->second.spanned_cols; + _INT32 start_col = jt->first; + _INT32 end_col = jt->first + jt->second.spanned_cols; for (size_t i = 0; i < cells_.size(); ++i) //todooo cells_ vector -> map by row { @@ -895,7 +897,7 @@ void ods_table_state::check_spanned_cells() } } -void ods_table_state::set_merge_cells(int start_col, int start_row, int end_col, int end_row) +void ods_table_state::set_merge_cells(_INT32 start_col, _INT32 start_row, _INT32 end_col, _INT32 end_row) { if (end_col - start_col < 0) return; if (end_row - start_row < 0) return; @@ -907,18 +909,18 @@ void ods_table_state::set_merge_cells(int start_col, int start_row, int end_col, //if (info.spanned_cols > 10000) info.spanned_cols = 1024; - std::map>::iterator pFindRow = map_merged_cells.find(start_row); + std::map<_INT32, std::map<_INT32, _spanned_info>>::iterator pFindRow = map_merged_cells.find(start_row); if (pFindRow == map_merged_cells.end()) { - std::map mapCols; + std::map<_INT32, _spanned_info> mapCols; mapCols.insert(std::make_pair(start_col, info)); map_merged_cells.insert(std::make_pair(start_row, mapCols)); } else { - std::map::iterator pFindCol = pFindRow->second.find(start_col); + std::map<_INT32, _spanned_info>::iterator pFindCol = pFindRow->second.find(start_col); if (pFindCol == pFindRow->second.end()) { pFindRow->second.insert(std::make_pair(start_col, info)); @@ -927,15 +929,15 @@ void ods_table_state::set_merge_cells(int start_col, int start_row, int end_col, //else нереально pFindCol->second.insert(info); } } -bool ods_table_state::isSpannedCell(int col, int row, int &spanned_cols, int &spanned_rows ) +bool ods_table_state::isSpannedCell(_INT32 col, _INT32 row, _INT32&spanned_cols, _INT32&spanned_rows ) { spanned_cols = spanned_rows = 0; - std::map>::iterator pFindRow = map_merged_cells.find(row); + std::map<_INT32, std::map<_INT32, _spanned_info>>::iterator pFindRow = map_merged_cells.find(row); if (pFindRow != map_merged_cells.end()) { - std::map::iterator pFindCol = pFindRow->second.find(col); + std::map<_INT32, _spanned_info>::iterator pFindCol = pFindRow->second.find(col); if (pFindCol != pFindRow->second.end()) { spanned_cols = pFindCol->second.spanned_cols; @@ -965,7 +967,7 @@ bool ods_table_state::isSpannedCell(int col, int row, int &spanned_cols, int &sp } return false; } -bool ods_table_state::isCoveredCell( int col, int repeated_cols) +bool ods_table_state::isCoveredCell(_INT32 col, _INT32 repeated_cols) { if (current_covered_cols_ > 0) return true; @@ -980,7 +982,7 @@ bool ods_table_state::isCoveredCell( int col, int repeated_cols) return false; } -void ods_table_state::set_cell_spanned(int spanned_cols, int spanned_rows) +void ods_table_state::set_cell_spanned(_INT32 spanned_cols, _INT32 spanned_rows) { table_table_cell* cell = dynamic_cast(cells_.back().elm.get()); if (cell == NULL)return; @@ -990,20 +992,28 @@ void ods_table_state::set_cell_spanned(int spanned_cols, int spanned_rows) } void ods_table_state::set_cell_formula(std::wstring & formula) { - if (formula.empty())return; + if (formula.empty()) return; + + //todooo used tabled columns in formula - TableName[TableColumn] + for (size_t i = 0; i < table_parts_.size(); ++i) + { + if (std::wstring::npos != formula.find(table_parts_[i].name + L"[")) + return; + } ods_conversion_context* ods_context = dynamic_cast(context_); - //test external link + std::wstring odfFormula = formulas_converter_table.convert_formula(formula); + +//test external link bool bExternal = !ods_context->externals_.empty(); boost::wregex re(L"([\\[]\\d+[\\]])+"); while(bExternal) { boost::wsmatch result; - bExternal = boost::regex_search(formula, result, re); + bExternal = boost::regex_search(odfFormula, result, re); if (!bExternal) break; - std::wstring refExternal = result[1].str(); int idExternal = XmlUtils::GetInteger(refExternal.substr(1, refExternal.length() - 1)) - 1; @@ -1012,33 +1022,28 @@ void ods_table_state::set_cell_formula(std::wstring & formula) while(idExternal >= 0 && idExternal < (int)ods_context->externals_.size()) { - size_t pos = formula.find(refExternal); + size_t pos = odfFormula.find(refExternal); if (pos == std::wstring::npos) break; std::wstring new_formula; - if (pos > 0 && formula[pos - 1] == L'\'') + if (pos > 0 && odfFormula[pos - 1] == L'\'') { - new_formula = formula.substr(0, pos - 1); - new_formula += L"'EXTERNALREF" + ods_context->externals_[idExternal].ref + L"'#"; + new_formula = odfFormula.substr(0, pos - 1); + new_formula += L"'" + ods_context->externals_[idExternal].ref + L"'#"; new_formula += L"'"; } else { - new_formula = formula.substr(0, pos); - new_formula += L"'EXTERNALREF" + ods_context->externals_[idExternal].ref + L"'#"; + new_formula = odfFormula.substr(0, pos); + new_formula += L"'" + ods_context->externals_[idExternal].ref + L"'#"; } pos += refExternal.length(); - new_formula += formula.substr(pos, formula.length() - pos); - formula = new_formula; + new_formula += odfFormula.substr(pos, odfFormula.length() - pos); + odfFormula = new_formula; } } - - std::wstring odfFormula = formulas_converter_table.convert_formula(formula); - - XmlUtils::replace_all(odfFormula, L"EXTERNALREF", L"file://");//снятие экранирования - if ((false == table_parts_.empty()) && (std::wstring::npos != odfFormula.find(L"["))) { for (size_t i = 0; i < table_parts_.size(); i++) @@ -1069,10 +1074,10 @@ std::wstring ods_table_state::replace_cell_row(boost::wsmatch const & what) if (what[1].matched) { std::wstring ref_formula = what[1].str(); - int col_formula=0, row_formula=0; + _INT32 col_formula = 0, row_formula = 0; utils::parsing_ref(ref_formula, col_formula, row_formula);col_formula--;//инче отсчет с 1 - ref_formula = utils::getColAddress(col_formula) + std::to_wstring(row_formula +current_table_row_ - tmp_row_); + ref_formula = utils::getColAddress(col_formula) + std::to_wstring(row_formula + current_table_row_ - tmp_row_); return ref_formula; @@ -1089,10 +1094,10 @@ std::wstring ods_table_state::replace_cell_column(boost::wsmatch const & what) if (what[1].matched) { std::wstring ref_formula = what[1].str(); - int col_formula=0, row_formula=0; + _INT32 col_formula = 0, row_formula =0; utils::parsing_ref(ref_formula, col_formula, row_formula);col_formula--; - ref_formula = utils::getColAddress(col_formula+current_table_column_ -tmp_column_)+boost::lexical_cast(row_formula); + ref_formula = utils::getColAddress(col_formula+current_table_column_ - tmp_column_)+boost::lexical_cast(row_formula); return ref_formula; } @@ -1104,7 +1109,7 @@ std::wstring ods_table_state::replace_cell_column(boost::wsmatch const & what) return L""; } -void ods_table_state::add_or_find_cell_shared_formula(std::wstring & formula, std::wstring ref, int ind) +void ods_table_state::add_or_find_cell_shared_formula(std::wstring & formula, std::wstring ref, _INT32 ind) { if (ind < 0)return; @@ -1123,22 +1128,22 @@ void ods_table_state::add_or_find_cell_shared_formula(std::wstring & formula, st boost::algorithm::split(distance, ref, boost::algorithm::is_any_of(L":"), boost::algorithm::token_compress_on); if (distance.size() > 1) { - int col1, row1, col2, row2; + _INT32 col1, row1, col2, row2; utils::parsing_ref(distance[0], col1, row1); utils::parsing_ref(distance[1], col2, row2); if (row2 - row1 > 0) moving_type = 2; - if (col2 - col1 > 0)moving_type = 1; + if (col2 - col1 > 0) moving_type = 1; } - ods_shared_formula_state state = {(unsigned int)ind, odf_formula,ref, current_table_column_,current_table_row_, moving_type}; - shared_formulas_.insert(std::make_pair((unsigned int)ind, state)); + ods_shared_formula_state state = {(_UINT32)ind, odf_formula,ref, current_table_column_,current_table_row_, moving_type}; + shared_formulas_.insert(std::make_pair((_UINT32)ind, state)); cell->attlist_.table_formula_ = odf_formula; cells_.back().empty = false; } else { - std::map::iterator pFind = shared_formulas_.find(ind); + std::map<_UINT32, ods_shared_formula_state>::iterator pFind = shared_formulas_.find(ind); if (pFind != shared_formulas_.end()) { @@ -1183,13 +1188,13 @@ void ods_table_state::set_cell_array_formula(std::wstring & formula, std::wstrin std::vector ref_cells; boost::algorithm::split(ref_cells,ref, boost::algorithm::is_any_of(L":"), boost::algorithm::token_compress_on); - int row_span = 0; - int col_span = 0; + _INT32 row_span = 0; + _INT32 col_span = 0; if (ref_cells.size() ==2) { - int col1 = -1, row1 = -1; - int col2 = -1, row2 = -1; + _INT32 col1 = -1, row1 = -1; + _INT32 col2 = -1, row2 = -1; utils::parsing_ref (ref_cells[0], col1, row1); utils::parsing_ref (ref_cells[1], col2, row2); @@ -1227,7 +1232,7 @@ void ods_table_state::convert_position(oox_table_position & oox_pos, double & x, for (i = 0; i < columns_.size(); i++) { - if (oox_pos.col >(int)(columns_[i].repeated + curr_col)) + if (oox_pos.col >(_INT32)(columns_[i].repeated + curr_col)) { sz_col += (columns_[i].repeated ) * columns_[i].size; } @@ -1240,7 +1245,7 @@ void ods_table_state::convert_position(oox_table_position & oox_pos, double & x, curr_col += columns_[i].repeated; } - if ((int)curr_col < oox_pos.col && false == columns_.empty()) + if ((_INT32)curr_col < oox_pos.col && false == columns_.empty()) { sz_col += (oox_pos.col - curr_col) * columns_[columns_.size() - 1].size; } @@ -1252,7 +1257,7 @@ void ods_table_state::convert_position(oox_table_position & oox_pos, double & x, size_t curr_row =0 ; for (i = 0; i < rows_.size(); i++) { - if (oox_pos.row >(int)(rows_[i].repeated + curr_row)) + if (oox_pos.row >(_INT32)(rows_[i].repeated + curr_row)) { sz_row += (rows_[i].repeated ) * rows_[i].size; } @@ -1266,7 +1271,7 @@ void ods_table_state::convert_position(oox_table_position & oox_pos, double & x, curr_row += rows_[i].repeated; } - if ((int)curr_row < oox_pos.row && false == rows_.empty()) + if ((_INT32)curr_row < oox_pos.row && false == rows_.empty()) { sz_row += (oox_pos.row - curr_row ) * rows_[rows_.size() - 1].size; } @@ -1386,7 +1391,7 @@ void ods_table_state::set_cell_value(const std::wstring & value, bool need_cash) bool need_test_cach = false; - if (cell->attlist_.common_value_and_type_attlist_->office_value_type_) + if (!need_cash && cell->attlist_.common_value_and_type_attlist_->office_value_type_) { if (cell->attlist_.common_value_and_type_attlist_->office_value_type_->get_type() == office_value_type::Float || cell->attlist_.common_value_and_type_attlist_->office_value_type_->get_type() == office_value_type::Currency || @@ -1486,10 +1491,11 @@ void ods_table_state::end_cell() cells_.back().elm->add_child_element(comm_elm); comments_[cells_.back().comment_idx].used = true; } - if (false == cells_.back().data_validation_name.empty()) + if (cells_.back().data_validation_idx >= 0) { table_table_cell* cell = dynamic_cast(cells_.back().elm.get()); - if (cell)cell->attlist_.table_content_validation_name_ = cells_.back().data_validation_name; + if (cell) + cell->attlist_.table_content_validation_name_ = data_validations_[cells_.back().data_validation_idx].name; } if (cells_.back().empty) { @@ -1502,15 +1508,15 @@ void ods_table_state::end_cell() } } -void ods_table_state::add_default_cell( int repeated) +void ods_table_state::add_default_cell(_INT32 repeated) { if (repeated < 1) return; - int comment_idx = is_cell_comment(current_table_column_ + 1, current_table_row_, repeated); + _INT32 comment_idx = is_cell_comment(current_table_column_ + 1, current_table_row_, repeated); if (comment_idx >= 0 && repeated > 1) { //делим на 3 - до, с комметом, после; - int c = current_table_column_; + _INT32 c = current_table_column_; add_default_cell(comments_[comment_idx].col - c - 1); add_default_cell(1); @@ -1519,19 +1525,19 @@ void ods_table_state::add_default_cell( int repeated) return; } //----------------------------------------------------------------------------------------- - std::map>::iterator pFindRow = map_merged_cells.find(current_table_row_); + std::map<_INT32, std::map<_INT32, _spanned_info>>::iterator pFindRow = map_merged_cells.find(current_table_row_); bool bSpanned = false; if (pFindRow != map_merged_cells.end()) { - for (std::map::iterator it = pFindRow->second.begin(); !bSpanned && it != pFindRow->second.end(); ++it) + for (std::map<_INT32, _spanned_info>::iterator it = pFindRow->second.begin(); !bSpanned && it != pFindRow->second.end(); ++it) { if (it->first < current_table_column_ + repeated + 1 && it->first >= current_table_column_ + 1) { if (repeated > 1) { //делим на 3 - до, с spanned, после; - int c = current_table_column_; + _INT32 c = current_table_column_; add_default_cell(it->first - c - 1); add_default_cell(1); @@ -1549,14 +1555,14 @@ void ods_table_state::add_default_cell( int repeated) } //----------------------------------------------------------------------------------------- data_validation_state::_ref ref; - std::wstring validation_name = is_cell_data_validation(current_table_column_ + 1, current_table_row_, repeated, ref); + _INT32 data_validation_idx = is_cell_data_validation(current_table_column_ + 1, current_table_row_, repeated, ref); - int repeated_validation = (std::min)(ref.col_end, current_table_column_ + (int)repeated) - (std::max)(ref.col_start, current_table_column_ + 1) + 1; + _INT32 repeated_validation = (std::min)(ref.col_end, current_table_column_ + (_INT32)repeated) - (std::max)(ref.col_start, current_table_column_ + 1) + 1; - if (false == validation_name.empty() && repeated > 1 && repeated_validation != repeated) + if (data_validation_idx >= 0 && repeated > 1 && repeated_validation != repeated) { //делим на 3 - до, с validation, после; - int c = current_table_column_; + _INT32 c = current_table_column_; add_default_cell(ref.col_start - c - 1); add_default_cell(repeated_validation); @@ -1579,8 +1585,8 @@ void ods_table_state::add_default_cell( int repeated) else if (!( current_table_column_ + repeated < current_covered_rows_[i].start_col || current_table_column_ > current_covered_rows_[i].start_col + current_covered_rows_[i].count_cols)) { - int c = current_table_column_; - int split = current_covered_rows_[i].start_col > current_table_column_ ? current_covered_rows_[i].start_col : + _INT32 c = current_table_column_; + _INT32 split = current_covered_rows_[i].start_col > current_table_column_ ? current_covered_rows_[i].start_col : current_covered_rows_[i].start_col + current_covered_rows_[i].count_cols; if (split != current_table_column_ && split != current_table_column_ + repeated) @@ -1610,7 +1616,7 @@ void ods_table_state::add_default_cell( int repeated) if (bSpanned) { - int spanned_rows = 0, spanned_cols = 0; + _INT32 spanned_rows = 0, spanned_cols = 0; if (cell && isSpannedCell(current_table_column_, current_table_row_, spanned_cols, spanned_rows)) { cell->attlist_extra_.table_number_columns_spanned_ = spanned_cols; @@ -1626,9 +1632,9 @@ void ods_table_state::add_default_cell( int repeated) state.row = current_table_row_; state.col = current_table_column_ + 1; - state.hyperlink_idx = is_cell_hyperlink(state.col, current_table_row_); - state.data_validation_name = validation_name; - state.comment_idx = comment_idx; + state.hyperlink_idx = is_cell_hyperlink(state.col, current_table_row_); + state.data_validation_idx = data_validation_idx; + state.comment_idx = comment_idx; cells_.push_back(state); @@ -1945,7 +1951,7 @@ void ods_table_state::end_conditional_format() { current_level_.pop_back(); } -void ods_table_state::start_conditional_rule(int rule_type, _CP_OPT(unsigned int) rank, _CP_OPT(bool) bottom, _CP_OPT(bool) percent) +void ods_table_state::start_conditional_rule(int rule_type, _CP_OPT(unsigned int) rank, _CP_OPT(bool) bottom, _CP_OPT(bool) percent, _CP_OPT(bool) above, _CP_OPT(bool) equal, _CP_OPT(int) stdDev) { office_element_ptr elm; @@ -1988,18 +1994,27 @@ void ods_table_state::start_conditional_rule(int rule_type, _CP_OPT(unsigned int table = L"'" + table + L"'"; } } - condition->attr_.calcext_base_cell_address_ = table + col + row; + condition->attr_.calcext_base_cell_address_ = (table.empty() ? L"" : (table + L".")) + col + row; } switch(rule_type) { - case 0: condition->attr_.calcext_value_ = L"above-average"; break; + case 0: + { + if (equal) condition->attr_.calcext_value_ = above.get_value_or(true) ? L"above-equal-average" : L"below-equal-average"; + else condition->attr_.calcext_value_ = above.get_value_or(true) ? L"above-average" : L"below-average"; + + if (stdDev) + { + condition->attr_.loext_stdDev_ = *stdDev; + } + }break; case 1: condition->attr_.calcext_value_ = L"begins-with()"; break; - case 4: condition->attr_.calcext_value_ = L"contains-text()"; break; + case 4: condition->attr_.calcext_value_ = L"formula-is()"; break; case 5: condition->attr_.calcext_value_ = L"is-error"; break; case 6: condition->attr_.calcext_value_ = L"contains-text()"; break; case 8: condition->attr_.calcext_value_ = L"duplicate"; break; case 9: condition->attr_.calcext_value_ = L"formula-is()"; break; - case 11: condition->attr_.calcext_value_ = L"not-contains-text()"; break; + case 11: condition->attr_.calcext_value_ = L"formula-is()"; break; case 12: condition->attr_.calcext_value_ = L"is-no-error"; break; case 13: condition->attr_.calcext_value_ = L"not-contains-text()"; break; case 15: @@ -2032,17 +2047,19 @@ void ods_table_state::end_conditional_rule() void ods_table_state::set_conditional_formula(const std::wstring& formula) { calcext_condition* condition = dynamic_cast (current_level_.back().get()); - if (!condition) return; std::wstring odfFormula = formulas_converter_table.convert_conditional_formula(formula); - std::wstring operator_; + std::wstring operator_ = condition->attr_.calcext_value_.get_value_or(L""); + + if (std::wstring::npos != operator_.find(L"is-no-error") || + std::wstring::npos != operator_.find(L"is-error")) + return; + bool s = false; bool split = false; - operator_ = condition->attr_.calcext_value_.get_value_or(L""); - size_t f_start = operator_.find(L"("); size_t f_end = operator_.rfind(L")"); if (f_start != std::wstring::npos && f_end != std::wstring::npos) @@ -2077,18 +2094,18 @@ void ods_table_state::set_conditional_time(int period) { switch (period) { - case 1: date_is->attr_.calcext_date_ = odf_types::time_period::yesterday; break; - case 2: date_is->attr_.calcext_date_ = odf_types::time_period::tomorrow; break; - case 3: date_is->attr_.calcext_date_ = odf_types::time_period::last7Days; break; - case 4: date_is->attr_.calcext_date_ = odf_types::time_period::thisMonth; break; - case 5: date_is->attr_.calcext_date_ = odf_types::time_period::lastMonth; break; - case 6: date_is->attr_.calcext_date_ = odf_types::time_period::nextMonth; break; - case 7: date_is->attr_.calcext_date_ = odf_types::time_period::thisWeek; break; - case 8: date_is->attr_.calcext_date_ = odf_types::time_period::lastWeek; break; - case 9: date_is->attr_.calcext_date_ = odf_types::time_period::nextWeek; break; + case 1: date_is->attr_.calcext_date_ = odf_types::time_period::lastMonth; break; + case 2: date_is->attr_.calcext_date_ = odf_types::time_period::lastWeek; break; + case 3: date_is->attr_.calcext_date_ = odf_types::time_period::nextMonth; break; + case 4: date_is->attr_.calcext_date_ = odf_types::time_period::nextWeek; break; + case 5: date_is->attr_.calcext_date_ = odf_types::time_period::thisMonth; break; + case 6: date_is->attr_.calcext_date_ = odf_types::time_period::thisWeek; break; + case 7: date_is->attr_.calcext_date_ = odf_types::time_period::today; break; + case 8: date_is->attr_.calcext_date_ = odf_types::time_period::tomorrow; break; + case 9: date_is->attr_.calcext_date_ = odf_types::time_period::yesterday; break; case 0: default: - date_is->attr_.calcext_date_ = odf_types::time_period::today; + date_is->attr_.calcext_date_ = odf_types::time_period::last7Days; } } } @@ -2243,7 +2260,7 @@ void ods_table_state::set_conditional_databar_color(_CP_OPT(color)& color) if (cond_format) { - cond_format->attr_.calcext_positive_color_ = color; + cond_format->attr_.positive_color_ = color; } } void ods_table_state::set_conditional_databar_axis_color(_CP_OPT(color)& color) @@ -2252,7 +2269,7 @@ void ods_table_state::set_conditional_databar_axis_color(_CP_OPT(color)& color) if (cond_format) { - cond_format->attr_.calcext_axis_color_ = color; + cond_format->attr_.axis_color_ = color; } } void ods_table_state::set_conditional_databar_negative_color(_CP_OPT(color)& color) @@ -2261,7 +2278,7 @@ void ods_table_state::set_conditional_databar_negative_color(_CP_OPT(color)& col if (cond_format) { - cond_format->attr_.calcext_negative_color_ = color; + cond_format->attr_.negative_color_ = color; } } void ods_table_state::set_conditional_databar_axis_position(const std::wstring& type) @@ -2270,9 +2287,35 @@ void ods_table_state::set_conditional_databar_axis_position(const std::wstring& if (cond_format) { - cond_format->attr_.calcext_axis_position_ = type; + cond_format->attr_.axis_position_ = type; } +} +void ods_table_state::set_conditional_databar_gradient(bool val) +{ + calcext_data_bar* cond_format = dynamic_cast(current_level_.back().get()); + if (cond_format) + { + cond_format->attr_.gradient_ = val; + } +} +void ods_table_state::set_conditional_databar_max(unsigned int val) +{ + calcext_data_bar* cond_format = dynamic_cast(current_level_.back().get()); + + if (cond_format) + { + cond_format->attr_.max_length_ = val; + } +} +void ods_table_state::set_conditional_databar_min(unsigned int val) +{ + calcext_data_bar* cond_format = dynamic_cast(current_level_.back().get()); + + if (cond_format) + { + cond_format->attr_.min_length_ = val; + } } } diff --git a/OdfFile/Writer/Format/ods_table_state.h b/OdfFile/Writer/Format/ods_table_state.h index 960a6e23d0e..a1d422c1540 100644 --- a/OdfFile/Writer/Format/ods_table_state.h +++ b/OdfFile/Writer/Format/ods_table_state.h @@ -52,9 +52,9 @@ namespace cpdoccore { struct oox_table_position { - int col; + _INT32 col; double col_off; - int row; + _INT32 row; double row_off; }; @@ -88,7 +88,7 @@ namespace utils else return std::wstring(1, (wchar_t)(L'A' + col)); } - static int getColAddressInv(const std::wstring & a_) + static _INT32 getColAddressInv(const std::wstring & a_) { std::wstring a = a_; XmlUtils::GetUpper(a); @@ -109,11 +109,11 @@ namespace utils } return res; } - static int getRowAdderssInv(const std::wstring & a_) + static _INT32 getRowAdderssInv(const std::wstring & a_) { if (!a_.empty()) { - return boost::lexical_cast(a_) - 1; + return boost::lexical_cast<_INT32>(a_) - 1; } else return 0; @@ -138,7 +138,7 @@ namespace utils std::reverse(col.begin(), col.end()); std::reverse(row.begin(), row.end()); } - static void parsing_ref (std::wstring ref, int & col, int & row) + static void parsing_ref (std::wstring ref, _INT32& col, _INT32& row) { if (std::wstring::npos != ref.find(L" ")) return; @@ -170,32 +170,43 @@ namespace utils struct ods_element_state { ods_element_state(){} - ods_element_state(office_element_ptr &elm_, unsigned int repeated_, const std::wstring &style_name_, office_element_ptr &style_elm_, double size_, size_t level_) - : elm(elm_), repeated(repeated_), style_name(style_name_), style_elm(style_elm_), size(size_), level(level_) + ods_element_state(office_element_ptr &elm_, _UINT32 repeated_, const std::wstring &style_name_, office_element_ptr &style_elm_, size_t level_) + : elm(elm_), repeated(repeated_), style_name(style_name_), style_elm(style_elm_), level(level_) {} office_element_ptr elm; - unsigned int repeated = 1; + _UINT32 repeated = 1; std::wstring style_name; office_element_ptr style_elm; - double size = 0; - - size_t level = 1; - + _UINT32 level = 1; +}; +struct ods_column_state : ods_element_state +{ + ods_column_state(office_element_ptr& elm_, _UINT32 repeated_, const std::wstring& style_name_, office_element_ptr& style_elm_, double size_, size_t level_) + { + elm = elm_; + repeated = repeated_; + style_name = style_name_; + style_elm = style_elm_; + size = size_; + level = level_; + } + double size = 0; std::wstring cell_style_name; }; +typedef ods_column_state ods_row_state; struct ods_cell_state : ods_element_state { - int col = -1; - int row = -1; + _INT32 col = -1; + _INT32 row = -1; - int hyperlink_idx = -1; - int comment_idx = -1; + _INT32 hyperlink_idx = -1; + _INT32 comment_idx = -1; - std::wstring data_validation_name; + _INT32 data_validation_idx = -1; bool empty = true; }; @@ -203,16 +214,16 @@ struct ods_cell_state : ods_element_state struct ods_hyperlink_state { std::wstring ref; - int col = -1; - int row = -1; + _INT32 col = -1; + _INT32 row = -1; std::wstring link; bool bLocation = false; }; struct ods_comment_state { - int col = -1; - int row = -1; + _INT32 col = -1; + _INT32 row = -1; std::wstring author; office_element_ptr elm; @@ -223,12 +234,12 @@ struct ods_comment_state }; struct ods_shared_formula_state { - unsigned int index; + _UINT32 index; std::wstring formula; std::wstring ref; - int base_column; - int base_row; + _INT32 base_column; + _INT32 base_row; int moving_type; //1 - col, 2 - row }; @@ -243,13 +254,13 @@ struct table_part_state std::wstring name; std::wstring ref; - int col_start = 0; - int row_start = 0; + _INT32 col_start = 0; + _INT32 row_start = 0; - int col_end = 0; - int row_end = 0; + _INT32 col_end = 0; + _INT32 row_end = 0; - bool in_ref(int col, int row) + bool in_ref(_INT32 col, _INT32 row) { return (col >= col_start && col <= col_end && row >= row_start && row <= row_end); } @@ -267,34 +278,34 @@ struct data_validation_state struct _ref { std::wstring ref; - int col_start = 0; - int row_start = 0; + _INT32 col_start = 0; + _INT32 row_start = 0; - int col_end = 0; - int row_end = 0; + _INT32 col_end = 0; + _INT32 row_end = 0; }; std::vector<_ref> refs; std::wstring condition; - bool in_ref(int col, int row, unsigned int repeate_col, _ref & ref) + bool in_ref(_INT32 col, _INT32 row, _UINT32 repeate_col, _ref & ref) { for (size_t i = 0; i < refs.size(); i++) { if (row < refs[i].row_start || row > refs[i].row_end) continue; - if (col + (int)repeate_col <= refs[i].col_start || col > refs[i].col_end) continue; + if (col + (_INT32)repeate_col <= refs[i].col_start || col > refs[i].col_end) continue; ref = refs[i]; return true; } return false; } - bool in_row(int row, unsigned int repeate_row, _ref & ref) + bool in_row(_INT32 row, _UINT32 repeate_row, _ref & ref) { for (size_t i = 0; i < refs.size(); i++) { - if (row + (int)repeate_row <= refs[i].row_start || row > refs[i].row_end) continue; + if (row + (_INT32)repeate_row <= refs[i].row_start || row > refs[i].row_end) continue; ref = refs[i]; return true; @@ -318,7 +329,7 @@ class ods_table_state void set_table_master_page(std::wstring name); void set_table_rtl(bool Val); void set_table_tab_color(_CP_OPT(odf_types::color) & _color); - void set_table_dimension(int col, int row); + void set_table_dimension(_INT32 col, _INT32 row); void set_table_print_ranges(const std::wstring &ranges); void set_table_protection(bool Val); @@ -329,39 +340,42 @@ class ods_table_state void set_table_protection_unprotected_cells(bool Val); void set_table_protection_protected_cells(bool Val); - void add_column(office_element_ptr & elm, unsigned int repeated, office_element_ptr & style); + void add_column(office_element_ptr & elm, _UINT32 repeated, office_element_ptr & style); void set_column_width_sym(double width); void set_column_width(double width); void set_column_optimal_width(bool val); void set_column_hidden(bool val); void set_column_default_cell_style(std::wstring & style_name); - std::wstring get_column_default_cell_style(int column); + std::wstring get_column_default_cell_style(_INT32 column); - void add_row_break(int val); - void add_column_break(int val); + void add_row_break(_INT32 val); + void add_column_break(_INT32 val); void start_group(office_element_ptr & elm); void end_group(); - int current_level() {return (int)current_level_.size()-1;} + void start_rows(office_element_ptr& elm); + void end_rows(); + + _INT32 current_level() {return (_INT32)current_level_.size() - 1;} void start_headers(office_element_ptr & elm); void end_headers(); - void add_row(office_element_ptr & elm, unsigned int repeated , office_element_ptr & style);//const std::wstring & StyleName, const std::wstring & defaultCellStyleName); + void add_row(office_element_ptr & elm, _UINT32 repeated , office_element_ptr & style);//const std::wstring & StyleName, const std::wstring & defaultCellStyleName); void set_row_hidden(bool Val); void set_row_optimal_height(bool val); void set_row_height(double height); void set_row_default_cell_style(std::wstring & style_name); void add_row_repeated(); - bool isSpannedCell(int col, int row, int &spanned_cols, int &spanned_rows ); - bool isCoveredCell(int col, int repeated_cols = 1); + bool isSpannedCell(_INT32 col, _INT32 row, _INT32 &spanned_cols, _INT32 &spanned_rows); + bool isCoveredCell(_INT32 col, _INT32 repeated_cols = 1); void start_cell(office_element_ptr & elm ,office_element_ptr & style); void end_cell(); - void add_default_cell(int repeated); + void add_default_cell(_INT32 repeated); void check_spanned_cells(); @@ -371,8 +385,8 @@ class ods_table_state void set_cell_text(odf_text_context *text_context, bool cash_value = false); void set_cell_formula(std::wstring &formula); void set_cell_array_formula(std::wstring & formula, std::wstring ref); - void set_cell_spanned(int spanned_cols, int spanned_rows); - void add_or_find_cell_shared_formula(std::wstring & formula, std::wstring ref, int ind); + void set_cell_spanned(_INT32 spanned_cols, _INT32 spanned_rows); + void add_or_find_cell_shared_formula(std::wstring & formula, std::wstring ref, _INT32 ind); void start_cell_text(); void end_cell_text(); @@ -384,7 +398,7 @@ class ods_table_state void start_conditional_formats(); void start_conditional_format(const std::wstring& ref); - void start_conditional_rule(int rule_type, _CP_OPT(unsigned int) rank, _CP_OPT(bool) bottom, _CP_OPT(bool) percent); + void start_conditional_rule(int rule_type, _CP_OPT(unsigned int) rank, _CP_OPT(bool) bottom, _CP_OPT(bool) percent, _CP_OPT(bool) above, _CP_OPT(bool) equal, _CP_OPT(int) stdDev); void set_conditional_formula(const std::wstring& formula); void set_conditional_value(int type, const std::wstring& value ); @@ -398,6 +412,9 @@ class ods_table_state void set_conditional_databar_negative_color(_CP_OPT(odf_types::color) & color); void set_conditional_databar_axis_color(_CP_OPT(odf_types::color) & color); void set_conditional_databar_axis_position(const std::wstring& value); + void set_conditional_databar_gradient(bool val); + void set_conditional_databar_max(unsigned int val); + void set_conditional_databar_min(unsigned int val); void set_conditional_style_name(const std::wstring &style_name); void set_conditional_operator(int _operator); @@ -451,17 +468,17 @@ class ods_table_state void end_sparkline_group(); void end_sparkline_groups(); /////////////////////////////// - void add_hyperlink(const std::wstring & ref,int col, int row, const std::wstring & link, const std::wstring & location); + void add_hyperlink(const std::wstring & ref, _INT32 col, _INT32 row, const std::wstring & link, const std::wstring & location); void add_definded_expression(office_element_ptr & elm); - void start_comment(int col, int row, std::wstring & author); + void start_comment(_INT32 col, _INT32 row, std::wstring & author); void set_comment_rect(double l, double t, double w, double h); void set_comment_visible(bool val); void set_comment_color(const std::wstring & color); void end_comment(odf_text_context *text_context); - void set_merge_cells(int start_col, int start_row, int end_col, int end_row); + void set_merge_cells(_INT32 start_col, _INT32 start_row, _INT32 end_col, _INT32 end_row); office_element_ptr & current_row_element(); office_element_ptr & current_cell_element(); @@ -470,13 +487,13 @@ class ods_table_state bool is_cell_hyperlink(); bool is_cell_comment(); - int is_cell_hyperlink(int col, int row); - int is_cell_comment(int col, int row, unsigned int repeate_col = 1); - int is_row_comment(int row, int repeate_row = 1); - int is_row_validation(int row, int & repeate_row); - std::wstring is_cell_data_validation(int col, int row, unsigned int repeate_col, data_validation_state::_ref & ref); + _INT32 is_cell_hyperlink(_INT32 col, _INT32 row); + _INT32 is_cell_comment(_INT32 col, _INT32 row, _UINT32 repeate_col = 1); + _INT32 is_row_comment(_INT32 row, _INT32 repeate_row = 1); + _INT32 is_row_validation(_INT32 row, _INT32& repeate_row); + _INT32 is_cell_data_validation(_INT32 col, _INT32 row, _UINT32 repeate_col, data_validation_state::_ref & ref); - unsigned int get_last_row_repeated (); + _UINT32 get_last_row_repeated (); ods_hyperlink_state & current_hyperlink(); @@ -485,18 +502,18 @@ class ods_table_state return table_parts_; } - int current_column() const; - int current_row() const; + _INT32 current_column() const; + _INT32 current_row() const; - int dimension_columns; - int dimension_row; + _INT32 dimension_columns; + _INT32 dimension_row; double defaut_column_width_sym_ = 0; double defaut_column_width_; double defaut_row_height_; - std::vector column_breaks_; - std::vector row_breaks_; + std::vector<_INT32> column_breaks_; + std::vector<_INT32> row_breaks_; void convert_position(oox_table_position & oox_pos, double & x, double & y); @@ -507,50 +524,53 @@ class ods_table_state std::vector comments_; std::map mapHeaderFooterImages; + private: struct _spanned_info { - int spanned_cols = 0; - int spanned_rows = 0; - int state = 0; + _INT32 spanned_cols = 0; + _INT32 spanned_rows = 0; + _INT32 state = 0; }; struct _covered_info { - int start_col = 0; - int count_cols = 0; + _INT32 start_col = 0; + _INT32 count_cols = 0; - int count_rows = 0; // от текущей строки + _INT32 count_rows = 0; // от текущей строки }; std::vector<_covered_info> current_covered_rows_; - int current_covered_cols_; + _INT32 current_covered_cols_; odf_conversion_context *context_; office_element_ptr office_table_; - style* office_table_style_;//??? может хранить как office_element_ptr ??? + style* office_table_style_ = NULL;//??? может хранить как office_element_ptr ??? office_element_ptr table_defined_expressions_; std::wstring row_default_cell_style_name_; - static int current_table_column_; - static int current_table_row_; + static _INT32 current_table_column_; + static _INT32 current_table_row_; - static int tmp_column_; - static int tmp_row_; + static _INT32 tmp_column_; + static _INT32 tmp_row_; - std::vector columns_; - std::vector rows_; + std::vector columns_; + std::vector rows_; // row column - std::map> map_merged_cells; + std::map<_INT32, std::map<_INT32, _spanned_info>> map_merged_cells; std::vector current_level_;//постоянно меняющийся список уровней ("0-й элемент - сама таблица) std::vector cells_; std::vector hyperlinks_; - std::map shared_formulas_; + std::map<_UINT32, ods_shared_formula_state> shared_formulas_; + + std::map mapTabled; // for formula used ... perhaps std::vector table_parts_; diff --git a/OdfFile/Writer/Format/odt_conversion_context.cpp b/OdfFile/Writer/Format/odt_conversion_context.cpp index af1e07c0685..4eccc6afc68 100644 --- a/OdfFile/Writer/Format/odt_conversion_context.cpp +++ b/OdfFile/Writer/Format/odt_conversion_context.cpp @@ -63,11 +63,11 @@ namespace utils double calculate_size_font_symbols(std::wstring str_test, std::wstring font_name, double font_size, NSFonts::IApplicationFonts *appFonts) { - std::pair appr = _graphics_utils_::calculate_size_symbol_asc(font_name, font_size, false, false, appFonts); + std::pair appr = _graphics_utils_::calculate_size_symbol_asc(font_name, font_size, false, false, appFonts); if (appr.first < 0.01 || appr.second < 0.01) { - appr.first = _graphics_utils_::calculate_size_symbol_win(font_name, font_size, false, false, str_test); + appr = _graphics_utils_::calculate_size_symbol_win(font_name, font_size, false, false, str_test); //appr_px = ((int)(appr_px+0.5) + 2*(int)appr_px)/3.; } @@ -134,6 +134,14 @@ void odt_conversion_context::end_document() } root_document_->add_child_element(seq_decls); } + if (false == mapUserDefineds.empty()) + { + office_element_ptr elm; + for (std::map::iterator it = mapUserDefineds.begin(); it != mapUserDefineds.end(); ++it) + { + add_meta_user_define(it->first, it->second); + } + } if (controls_context()->is_exist_content()) { office_element_ptr forms_root_elm; @@ -590,6 +598,15 @@ void odt_conversion_context::start_hyperlink(const std::wstring& link, const std text_a* hyperlink = dynamic_cast(hyperlink_elm.get()); if (hyperlink) { + if (location == L"_top") + hyperlink->office_target_frame_name_ = odf_types::target_frame_name::Top; + else if (location == L"_blank") + hyperlink->office_target_frame_name_ = odf_types::target_frame_name::Blank; + else if (location == L"_self") + hyperlink->office_target_frame_name_ = odf_types::target_frame_name::Self; + else if (location == L"_parent") + hyperlink->office_target_frame_name_ = odf_types::target_frame_name::Parent; + hyperlink->common_xlink_attlist_.href_ = link + (location.empty() ? L"" : (L"#" + location)); hyperlink->common_xlink_attlist_.type_ = xlink_type::Simple; @@ -611,10 +628,9 @@ void odt_conversion_context::end_hyperlink() } void odt_conversion_context::start_drop_down() { - office_element_ptr elm_drop_down; - create_element(L"text", L"drop-down", elm_drop_down, this); + create_element(L"text", L"drop-down", current_fields.back().elm, this); - text_drop_down* drop_down = dynamic_cast(elm_drop_down.get()); + text_drop_down* drop_down = dynamic_cast(current_fields.back().elm.get()); if (drop_down) drop_down->text_name_ = current_fields.back().name; @@ -629,14 +645,36 @@ void odt_conversion_context::start_drop_down() label->text_value_ = current_fields.back().items[i].first; } - elm_drop_down->add_child_element(elm); + current_fields.back().elm->add_child_element(elm); } - text_context()->start_element(elm_drop_down); + text_context()->start_element(current_fields.back().elm); } void odt_conversion_context::end_drop_down() { text_context()->end_element(); } +void odt_conversion_context::start_user_defined() +{ + mapUserDefineds.insert(std::make_pair(current_fields.back().value, L"")); + + current_fields.back().elm = text_context()->start_field(current_fields.back().type, current_fields.back().value, current_fields.back().format); +} +void odt_conversion_context::end_user_defined() +{ + text_user_defined* user_defined = dynamic_cast(current_fields.back().elm.get()); + + if (user_defined) + { + std::map::iterator pFind = mapUserDefineds.find(current_fields.back().value); + + if (pFind != mapUserDefineds.end()) + { + pFind->second = user_defined->get_text_content(); + } + } + + text_context()->end_field(); +} void odt_conversion_context::start_sequence() { std::map::iterator pFind = mapSequenceDecls.find(current_fields.back().value); @@ -650,10 +688,9 @@ void odt_conversion_context::start_sequence() { index = ++pFind->second; } - office_element_ptr seq_elm; - create_element(L"text", L"sequence", seq_elm, this); + create_element(L"text", L"sequence", current_fields.back().elm, this); - text_sequence* sequence = dynamic_cast(seq_elm.get()); + text_sequence* sequence = dynamic_cast(current_fields.back().elm.get()); if (sequence) { sequence->name_ = current_fields.back().value; @@ -661,7 +698,7 @@ void odt_conversion_context::start_sequence() sequence->formula_ = L"ooow:" + current_fields.back().value + L"+1"; sequence->style_num_format_ = style_numformat(style_numformat::arabic); - text_context()->start_element(seq_elm); + text_context()->start_element(current_fields.back().elm); } } void odt_conversion_context::end_sequence() @@ -767,6 +804,36 @@ void odt_conversion_context::set_field_instr() if (instr.length() > 9) current_fields.back().value = instr.substr(9, instr.length() - 5); } + res1 = instr.find(L"REF"); + if (std::wstring::npos != res1 && current_fields.back().type == 0) + { + current_fields.back().type = fieldRef; + + std::wstring options_str; + if (instr.size() > 3) options_str = instr.substr(4); + std::map options = parse_instr_options(options_str); + + for (std::map::iterator it = options.begin(); it != options.end(); ++it) + { + if (it->first == L" ")//field-argument + { + current_fields.back().value = it->second; + boost::algorithm::trim(current_fields.back().value); + } + else if (it->first == L"h") + { + current_fields.back().bHyperlinks = true; + } + else if (it->first == L"p") + { + current_fields.back().format = L"direction"; + } + else if (it->first == L"r" || it->first == L"n") + { + current_fields.back().format = L"number"; + } + } + } res1 = instr.find(L"PAGE"); if (std::wstring::npos != res1 && current_fields.back().type == 0) { @@ -831,6 +898,20 @@ void odt_conversion_context::set_field_instr() current_fields.back().type = fieldIndex; current_fields.back().in_span = false; } + res1 = instr.find(L"DOCPROPERTY"); + if (std::wstring::npos != res1 && current_fields.back().type == 0) + { + current_fields.back().type = fieldUserDefined; + current_fields.back().in_span = false; + + std::map options = parse_instr_options(instr.substr(11)); + + std::map::iterator pFind = options.find(L" "); + if (pFind != options.end()) + { + current_fields.back().value = pFind->second; + } + } res1 = instr.find(L"TOC"); if (std::wstring::npos != res1 && current_fields.back().type == 0) { @@ -889,25 +970,25 @@ void odt_conversion_context::set_field_instr() current_fields.back().bHidePageNumbers = true; } } - ////////////////////////////////////////// + +////////////////////////////////////////// res1 = instr.find(L" "); if (std::wstring::npos != res1) { - if (current_fields.back().format.empty()) + if (current_fields.back().type == 0) { - std::map options = parse_instr_options(instr.substr(res1 + 1)); + current_fields.back().name = instr.substr(0, res1); + } + std::map options = parse_instr_options(instr.substr(res1 + 1)); + if (current_fields.back().format.empty()) + { std::map::iterator pFind = options.find(L"@"); if (pFind != options.end()) { current_fields.back().format = pFind->second; } } - - if (current_fields.back().type == 0) - { - current_fields.back().name = instr.substr(0, res1); - } } } void odt_conversion_context::set_field_date_time(const std::wstring &date_time) @@ -1122,8 +1203,9 @@ void odt_conversion_context::end_field() } else if (current_fields.back().type == fieldSeq) start_sequence(); else if (current_fields.back().type == fieldDropDown) start_drop_down(); + else if (current_fields.back().type == fieldUserDefined)start_user_defined(); else - text_context()->start_field(current_fields.back().type, current_fields.back().value, current_fields.back().format); + current_fields.back().elm = text_context()->start_field(current_fields.back().type, current_fields.back().value, current_fields.back().format); } if (current_fields.back().status == 2) { @@ -1134,6 +1216,7 @@ void odt_conversion_context::end_field() if (current_fields.back().type == fieldHyperlink) end_hyperlink(); else if (current_fields.back().type == fieldSeq) end_sequence(); else if (current_fields.back().type == fieldDropDown) end_drop_down(); + else if (current_fields.back().type == fieldUserDefined)end_user_defined(); else text_context()->end_field(); current_fields.pop_back(); @@ -1281,8 +1364,9 @@ void odt_conversion_context::start_run(bool styled) } else if (current_fields.back().type == fieldSeq) start_sequence(); else if (current_fields.back().type == fieldDropDown) start_drop_down(); - else - text_context()->start_field(current_fields.back().type, current_fields.back().value, current_fields.back().format); + else if (current_fields.back().type == fieldUserDefined)start_user_defined(); + else + current_fields.back().elm = text_context()->start_field(current_fields.back().type, current_fields.back().value, current_fields.back().format); } text_context()->start_span(styled); @@ -1297,7 +1381,7 @@ void odt_conversion_context::start_run(bool styled) if (!current_fields.empty() && current_fields.back().status == 1 && current_fields.back().in_span)//поле стартуется в span - нужно для сохранения стиля { current_fields.back().status = 2; - text_context()->start_field(current_fields.back().type, current_fields.back().value, current_fields.back().format); + current_fields.back().elm = text_context()->start_field(current_fields.back().type, current_fields.back().value, current_fields.back().format); } } void odt_conversion_context::end_run() diff --git a/OdfFile/Writer/Format/odt_conversion_context.h b/OdfFile/Writer/Format/odt_conversion_context.h index 69cf32c026e..02871fe5ddd 100644 --- a/OdfFile/Writer/Format/odt_conversion_context.h +++ b/OdfFile/Writer/Format/odt_conversion_context.h @@ -101,6 +101,9 @@ class odt_conversion_context : public odf_conversion_context void start_drop_down(); void end_drop_down(); + void start_user_defined(); + void end_user_defined(); + void start_table_of_content (); void end_table_of_content (); @@ -216,13 +219,14 @@ class odt_conversion_context : public odf_conversion_context std::wstring current_master_page_; - odf_controls_context controls_context_; + odf_controls_context controls_context_; std::vector current_root_elements_; // for section, if needed std::vector sections_; std::map mapSequenceDecls; std::map mapBookmarks; + std::mapmapUserDefineds; void add_to_root(); @@ -238,6 +242,8 @@ class odt_conversion_context : public odf_conversion_context _CP_OPT(color) color_; + office_element_ptr elm; + short status = 0;//0, 1, 2, 3 - init, prapare, start, finish bool in_span = false; bool result = false; //after separate diff --git a/OdfFile/Writer/Format/office_forms.cpp b/OdfFile/Writer/Format/office_forms.cpp index f40247309d2..b52aa6127f8 100644 --- a/OdfFile/Writer/Format/office_forms.cpp +++ b/OdfFile/Writer/Format/office_forms.cpp @@ -598,6 +598,52 @@ void form_item::serialize(std::wostream & _Wostream) } } } +// loext:content-control +//---------------------------------------------------------------------------------- +const wchar_t* loext_content_control::ns = L"loext"; +const wchar_t* loext_content_control::name = L"content-control"; +void loext_content_control::create_child_element(const std::wstring& Ns, const std::wstring& Name) +{ + CP_CREATE_ELEMENT(content); +} +void loext_content_control::add_child_element(const office_element_ptr& child_element) +{ + content.push_back(child_element); +} +void loext_content_control::serialize(std::wostream& _Wostream) +{ + CP_XML_WRITER(_Wostream) + { + CP_XML_NODE_SIMPLE() + { + CP_XML_ATTR(L"loext:alias", alias); + CP_XML_ATTR(L"loext:tag", tag); + CP_XML_ATTR(L"loext:lock", lock); + CP_XML_ATTR(L"loext:showing-place-holder", showing_place_holder); + CP_XML_ATTR(L"loext:id", id); + CP_XML_ATTR(L"loext:tab-index", tab_index); + CP_XML_ATTR(L"loext:checked", checked); + CP_XML_ATTR(L"loext:checkedState", checked_state); + CP_XML_ATTR(L"loext:uncheckedState", unchecked_state); + CP_XML_ATTR(L"loext:date-format", date_format); + CP_XML_ATTR(L"loext:date-language", date_language); + CP_XML_ATTR(L"loext:current-date", current_date); + CP_XML_ATTR(L"loext:date-rfc-language-tag", date_rfc_language); + + CP_XML_ATTR(L"loext:checkbox", checkbox); + CP_XML_ATTR(L"loext:picture", picture); + CP_XML_ATTR(L"loext:date", date); + CP_XML_ATTR(L"loext:dropdown", dropdown); + CP_XML_ATTR(L"loext:combobox", combobox); + CP_XML_ATTR(L"loext:plain-text", plain_text); + + for (size_t i = 0; i < content.size(); i++) + { + content[i]->serialize(CP_XML_STREAM()); + } + } + } +} } } diff --git a/OdfFile/Writer/Format/office_forms.h b/OdfFile/Writer/Format/office_forms.h index 3a8e578b15c..65e8e6c443a 100644 --- a/OdfFile/Writer/Format/office_forms.h +++ b/OdfFile/Writer/Format/office_forms.h @@ -77,14 +77,12 @@ class form_form : public office_element_impl static const wchar_t * ns; static const wchar_t * name; - static const ElementType type = typeFormForm; - + static const ElementType type = typeFormForm; virtual void create_child_element(const std::wstring & Ns, const std::wstring & Name); virtual void add_child_element( const office_element_ptr & child_element); virtual void serialize(std::wostream & _Wostream); - public: office_element_ptr_array content_; office_element_ptr office_event_listeners_; @@ -125,8 +123,7 @@ class form_properties : public office_element_impl static const wchar_t * ns; static const wchar_t * name; - static const ElementType type = typeFormProperties; - + static const ElementType type = typeFormProperties; virtual void create_child_element(const std::wstring & Ns, const std::wstring & Name); virtual void add_child_element( const office_element_ptr & child_element); @@ -144,8 +141,7 @@ class form_property : public office_element_impl static const wchar_t * ns; static const wchar_t * name; - static const ElementType type = typeFormProperty; - + static const ElementType type = typeFormProperty; virtual void create_child_element(const std::wstring & Ns, const std::wstring & Name){} virtual void add_child_element( const office_element_ptr & child_element){} @@ -164,8 +160,7 @@ class form_list_property : public office_element_impl static const wchar_t * ns; static const wchar_t * name; - static const ElementType type = typeFormListProperty; - + static const ElementType type = typeFormListProperty; virtual void create_child_element(const std::wstring & Ns, const std::wstring & Name); virtual void add_child_element( const office_element_ptr & child_element); @@ -186,8 +181,7 @@ class form_list_value : public office_element_impl static const wchar_t * ns; static const wchar_t * name; - static const ElementType type = typeFormListValue; - + static const ElementType type = typeFormListValue; virtual void create_child_element(const std::wstring & Ns, const std::wstring & Name){} virtual void add_child_element( const office_element_ptr & child_element){} @@ -203,8 +197,7 @@ class form_element : public office_element_impl { public: static const wchar_t * ns; - static const wchar_t * name; - + static const wchar_t * name; static const ElementType type = typeFormElement; @@ -246,8 +239,7 @@ class form_button : public form_element static const wchar_t * ns; static const wchar_t * name; - static const ElementType type = typeFormButton; - + static const ElementType type = typeFormButton; virtual void serialize(std::wostream & _Wostream); @@ -273,8 +265,7 @@ class form_image_frame : public form_element static const wchar_t * ns; static const wchar_t * name; - static const ElementType type = typeFormImageFrame; - + static const ElementType type = typeFormImageFrame; virtual void serialize(std::wostream & _Wostream); @@ -289,8 +280,7 @@ class form_text : public form_element static const wchar_t * ns; static const wchar_t * name; - static const ElementType type = typeFormText; - + static const ElementType type = typeFormText; virtual void serialize(std::wostream & _Wostream); @@ -309,8 +299,7 @@ class form_textarea : public form_element static const wchar_t * ns; static const wchar_t * name; - static const ElementType type = typeFormTextarea; - + static const ElementType type = typeFormTextarea; virtual void serialize(std::wostream & _Wostream); @@ -328,8 +317,7 @@ class form_fixed_text : public form_element static const wchar_t * ns; static const wchar_t * name; - static const ElementType type = typeFormFixedText; - + static const ElementType type = typeFormFixedText; virtual void serialize(std::wostream & _Wostream); }; @@ -342,8 +330,7 @@ class form_checkbox : public form_text static const wchar_t * ns; static const wchar_t * name; - static const ElementType type = typeFormCheckbox; - + static const ElementType type = typeFormCheckbox; form_checkbox() : current_state_(false), image_position_(L"center") {} virtual void serialize(std::wostream & _Wostream); @@ -363,8 +350,7 @@ class form_radio : public form_checkbox static const wchar_t * ns; static const wchar_t * name; - static const ElementType type = typeFormRadio; - + static const ElementType type = typeFormRadio; virtual void serialize(std::wostream & _Wostream); }; @@ -377,8 +363,7 @@ class form_combobox : public form_text static const wchar_t * ns; static const wchar_t * name; - static const ElementType type = typeFormCombobox; - + static const ElementType type = typeFormCombobox; virtual void create_child_element(const std::wstring & Ns, const std::wstring & Name); virtual void add_child_element( const office_element_ptr & child_element); @@ -392,7 +377,6 @@ class form_combobox : public form_text _CP_OPT(std::wstring) list_source_; //form:auto-complete - }; CP_REGISTER_OFFICE_ELEMENT2(form_combobox); @@ -403,8 +387,7 @@ class form_listbox : public form_element static const wchar_t * ns; static const wchar_t * name; - static const ElementType type = typeFormListbox; - + static const ElementType type = typeFormListbox; virtual void create_child_element(const std::wstring & Ns, const std::wstring & Name); virtual void add_child_element( const office_element_ptr & child_element); @@ -417,14 +400,12 @@ class form_listbox : public form_element _CP_OPT(std::wstring) list_source_type_; _CP_OPT(int) size_; - office_element_ptr_array options_; + office_element_ptr_array options_; //form:bound-column //form:xforms-list-source //form:multiple //form:listlinkage-type - - }; CP_REGISTER_OFFICE_ELEMENT2(form_listbox); //----------------------------------------------------------------------------------------- @@ -435,8 +416,7 @@ class form_date : public form_element static const wchar_t * ns; static const wchar_t * name; - static const ElementType type = typeFormDate; - + static const ElementType type = typeFormDate; virtual void serialize(std::wostream & _Wostream); }; @@ -451,8 +431,7 @@ class form_value_range : public form_element static const wchar_t * ns; static const wchar_t * name; - static const ElementType type = typeFormValueRange; - + static const ElementType type = typeFormValueRange; virtual void serialize(std::wostream & _Wostream); @@ -472,8 +451,7 @@ class form_frame : public form_element static const wchar_t * ns; static const wchar_t * name; - static const ElementType type = typeFormFrame; - + static const ElementType type = typeFormFrame; virtual void serialize(std::wostream & _Wostream); }; @@ -486,8 +464,7 @@ class form_item : public office_element_impl static const wchar_t * ns; static const wchar_t * name; - static const ElementType type = typeFormItem; - + static const ElementType type = typeFormItem; virtual void create_child_element(const std::wstring & Ns, const std::wstring & Name){} virtual void add_child_element( const office_element_ptr & child_element){} @@ -498,8 +475,6 @@ class form_item : public office_element_impl std::wstring text_; }; CP_REGISTER_OFFICE_ELEMENT2(form_item); -} -} //7.6.2, // 13.5.5, // 13.5.6, @@ -512,3 +487,50 @@ CP_REGISTER_OFFICE_ELEMENT2(form_item); // 13.5.7, // 13.5.4, // +//----------------------------------------------------------------------------------------- +//----------------------------------------------------------------------------------------- +//----------------------------------------------------------------------------------------- +//----------------------------------------------------------------------------------------- +//----------------------------------------------------------------------------------------- +// loext:content-control +class loext_content_control : public office_element_impl +{ +public: + static const wchar_t* ns; + static const wchar_t* name; + + static const ElementType type = typeContentControl; + + virtual void create_child_element(const std::wstring& Ns, const std::wstring& Name); + virtual void add_child_element(const office_element_ptr& child_element); + + virtual void serialize(std::wostream& _Wostream); + + _CP_OPT(std::wstring) alias; + _CP_OPT(std::wstring) tag; + _CP_OPT(std::wstring) lock; + _CP_OPT(odf_types::Bool) showing_place_holder; + _CP_OPT(int) id; + _CP_OPT(unsigned int) tab_index; + _CP_OPT(odf_types::Bool) checked; + _CP_OPT(std::wstring) checked_state; + _CP_OPT(std::wstring) unchecked_state; + _CP_OPT(std::wstring) date_format; + _CP_OPT(std::wstring) date_language; + _CP_OPT(std::wstring) current_date; + _CP_OPT(std::wstring) date_rfc_language; + + _CP_OPT(odf_types::Bool) checkbox; + _CP_OPT(odf_types::Bool) picture; + _CP_OPT(odf_types::Bool) date; + _CP_OPT(odf_types::Bool) dropdown; + _CP_OPT(odf_types::Bool) combobox; + _CP_OPT(odf_types::Bool) plain_text; + + _CP_OPT(std::wstring) text_content; + office_element_ptr_array content; +}; +CP_REGISTER_OFFICE_ELEMENT2(loext_content_control); + +} +} diff --git a/OdfFile/Writer/Format/office_meta.cpp b/OdfFile/Writer/Format/office_meta.cpp index cac13508ed0..507992192fe 100644 --- a/OdfFile/Writer/Format/office_meta.cpp +++ b/OdfFile/Writer/Format/office_meta.cpp @@ -229,14 +229,12 @@ void meta_user_defined::serialize(std::wostream & _Wostream) CP_XML_NODE_SIMPLE() { CP_XML_ATTR(L"meta:name", meta_name_); + CP_XML_ATTR_OPT(L"meta:value-type", meta_value_type_); CP_XML_STREAM() << XmlUtils::EncodeXmlString(content_); } } } -void meta_user_defined::add_text(const std::wstring & text) -{ - content_ = text; -} + } } diff --git a/OdfFile/Writer/Format/office_meta.h b/OdfFile/Writer/Format/office_meta.h index 58f8d8c1867..e61351269bc 100644 --- a/OdfFile/Writer/Format/office_meta.h +++ b/OdfFile/Writer/Format/office_meta.h @@ -40,6 +40,9 @@ #include "office_elements.h" #include "office_elements_create.h" +#include "../../DataTypes/common_attlists.h" +#include "../../DataTypes/officevaluetype.h" + namespace cpdoccore { namespace odf_writer { @@ -267,7 +270,8 @@ class meta_document_statistic : public office_element_impl static const ElementType type = typeOfficeMetaUserDefined; std::wstring meta_name_; - std::wstring content_; + std::wstring content_; + _CP_OPT(odf_types::office_value_type) meta_value_type_; virtual void create_child_element(const std::wstring & Ns, const std::wstring & Name) {} - virtual void add_child_element(const office_element_ptr & child_element) {} virtual void add_text(const std::wstring & Text); + virtual void add_child_element(const office_element_ptr & child_element) {} virtual void serialize(std::wostream & _Wostream); }; CP_REGISTER_OFFICE_ELEMENT2(meta_user_defined); diff --git a/OdfFile/Writer/Format/oox_shape_defines.h b/OdfFile/Writer/Format/oox_shape_defines.h index 1cbbf7417f2..f281c352aa1 100644 --- a/OdfFile/Writer/Format/oox_shape_defines.h +++ b/OdfFile/Writer/Format/oox_shape_defines.h @@ -66,6 +66,8 @@ namespace cpdoccore _CP_OPT(std::wstring) x_maximum; _CP_OPT(std::wstring) r_minimum; _CP_OPT(std::wstring) r_maximum; + + _CP_OPT(bool) handle_swiched; }; void add(std::wstring name,std::wstring frmla); @@ -80,6 +82,10 @@ namespace cpdoccore _CP_OPT(std::wstring) view_box; _CP_OPT(std::wstring) sub_view_size; _CP_OPT(std::wstring) glue_points; + _CP_OPT(std::wstring) glue_points_leaving_directions; + + _CP_OPT(std::wstring) path_stretchpoint_x; + _CP_OPT(std::wstring) path_stretchpoint_y; std::wstring odf_type_name; }; diff --git a/OdfFile/Writer/Format/paragraph_elements.cpp b/OdfFile/Writer/Format/paragraph_elements.cpp index 6df4f4a83d6..e9efafe6154 100644 --- a/OdfFile/Writer/Format/paragraph_elements.cpp +++ b/OdfFile/Writer/Format/paragraph_elements.cpp @@ -188,6 +188,42 @@ void text_bookmark_end::serialize(std::wostream & _Wostream) } } } +//---------------------------------------------------------------------------------- +// text:bookmark-ref +//---------------------------------------------------------------------------------- +const wchar_t* text_bookmark_ref::ns = L"text"; +const wchar_t* text_bookmark_ref::name = L"bookmark-ref"; + +void text_bookmark_ref::create_child_element(const std::wstring& Ns, const std::wstring& Name) +{ + CP_CREATE_ELEMENT(content_); +} +void text_bookmark_ref::add_child_element(const office_element_ptr& child_element) +{ + content_.push_back(child_element); +} +void text_bookmark_ref::add_text(const std::wstring& Text) +{ + office_element_ptr elm = text_text::create(Text); + content_.push_back(elm); +} +void text_bookmark_ref::serialize(std::wostream& _Wostream) +{ + CP_XML_WRITER(_Wostream) + { + CP_XML_NODE_SIMPLE() + { + CP_XML_ATTR_OPT_ENCODE_STRING(L"text:ref-name", ref_name_); + CP_XML_ATTR_OPT(L"text:reference-format", reference_format_); + + for (size_t i = 0; i < content_.size(); i++) + { + content_[i]->serialize(CP_XML_STREAM()); + } + } + } +} + //---------------------------------------------------------------------------------- // text:reference-mark //---------------------------------------------------------------------------------- @@ -1156,5 +1192,49 @@ void text_label::serialize(std::wostream & _Wostream) } } } +//---------------------------------------------------------------------------------- +// text:user-defined +//---------------------------------------------------------------------------------- +const wchar_t* text_user_defined::ns = L"text"; +const wchar_t* text_user_defined::name = L"user-defined"; + +void text_user_defined::add_child_element(const office_element_ptr& child_element) +{ + if (!child_element) return; + + content_.push_back(child_element); +} +std::wstring text_user_defined::get_text_content() +{ + std::wstringstream strm; + for (size_t i = 0; i < content_.size(); i++) + { + content_[i]->text_to_stream(strm); + } + return strm.str(); +} + +void text_user_defined::add_text(const std::wstring& Text) +{ + text_ = Text; +} +void text_user_defined::serialize(std::wostream& _Wostream) +{ + CP_XML_WRITER(_Wostream) + { + CP_XML_NODE_SIMPLE() + { + CP_XML_ATTR_OPT(L"text:name", text_name_); + + if (text_) + CP_XML_CONTENT(*text_); + + for (size_t i = 0; i < content_.size(); i++) + { + content_[i]->text_to_stream(CP_XML_STREAM()); + } + } + } +} } } diff --git a/OdfFile/Writer/Format/paragraph_elements.h b/OdfFile/Writer/Format/paragraph_elements.h index 78e345513d9..865aa75d380 100644 --- a/OdfFile/Writer/Format/paragraph_elements.h +++ b/OdfFile/Writer/Format/paragraph_elements.h @@ -42,6 +42,7 @@ #include "../../DataTypes/targetframename.h" #include "../../DataTypes/noteclass.h" #include "../../DataTypes/bibliography.h" +#include "../../DataTypes/referenceformat.h" #include "../../DataTypes/common_attlists.h" @@ -211,7 +212,33 @@ class text_bookmark_end : public office_element_impl std::wstring text_name_; }; CP_REGISTER_OFFICE_ELEMENT2(text_bookmark_end); +//------------------------------------------------------------------------------------------------------------------- +// text:bookmark-ref +//------------------------------------------------------------------------------------------------------------------- +class text_bookmark_ref : public office_element_impl +{ +public: + static const wchar_t* ns; + static const wchar_t* name; + + static const ElementType type = typeTextBookmarkRef; + + text_bookmark_ref() {}; + text_bookmark_ref(const std::wstring& Name) : ref_name_(Name) {}; + + virtual void create_child_element(const std::wstring& Ns, const std::wstring& Name); + virtual void add_child_element(const office_element_ptr& child_element); + virtual void add_text(const std::wstring& Text); + + virtual void serialize(std::wostream& _Wostream); + _CP_OPT(std::wstring) ref_name_; + _CP_OPT(odf_types::reference_format) reference_format_; + + _CP_OPT(std::wstring) text_; + office_element_ptr_array content_; +}; +CP_REGISTER_OFFICE_ELEMENT2(text_bookmark_ref); // text:reference-mark //--------------------------------------------------------------------------------------------------- class text_reference_mark : public office_element_impl @@ -631,8 +658,7 @@ class text_sequence : public office_element_impl static const wchar_t * ns; static const wchar_t * name; - static const ElementType type = typeTextSequence; - + static const ElementType type = typeTextSequence; virtual void create_child_element(const std::wstring & Ns, const std::wstring & Name); virtual void add_child_element( const office_element_ptr & child_element); @@ -738,7 +764,7 @@ class text_toc_mark_start : public office_element_impl static const wchar_t * ns; static const wchar_t * name; - static const ElementType type = typeTextTocMarkStart; + static const ElementType type = typeTextTocMarkStart; virtual void create_child_element (const std::wstring & Ns, const std::wstring & Name){} @@ -759,7 +785,7 @@ class text_toc_mark_end : public office_element_impl static const wchar_t * ns; static const wchar_t * name; - static const ElementType type = typeTextTocMarkEnd; + static const ElementType type = typeTextTocMarkEnd; virtual void create_child_element (const std::wstring & Ns, const std::wstring & Name){} @@ -779,7 +805,7 @@ class text_toc_mark : public office_element_impl static const wchar_t * ns; static const wchar_t * name; - static const ElementType type = typeTextTocMark; + static const ElementType type = typeTextTocMark; virtual void create_child_element (const std::wstring & Ns, const std::wstring & Name){} @@ -800,7 +826,7 @@ class text_alphabetical_index_mark_start : public office_element_impl static const wchar_t * ns; static const wchar_t * name; - static const ElementType type = typeTextSequenceRef; - + static const ElementType type = typeTextSequenceRef; virtual void create_child_element (const std::wstring & Ns, const std::wstring & Name){} virtual void add_child_element ( const office_element_ptr & child_element){} virtual void serialize(std::wostream & _Wostream); - _CP_OPT(std::wstring) reference_format_;//caption, category-and-value, value, chapter, direction, page, text, number, number-all-superior, number-no-superior - _CP_OPT(std::wstring) ref_name_; + _CP_OPT(odf_types::reference_format) reference_format_; + _CP_OPT(std::wstring) ref_name_; - std::wstring content_; + std::wstring content_; }; CP_REGISTER_OFFICE_ELEMENT2(text_sequence_ref); //------------------------------------------------------------------------------------------------------------------- @@ -943,8 +967,7 @@ class text_drop_down : public office_element_impl static const wchar_t * ns; static const wchar_t * name; - static const ElementType type = typeTextDropDown; - + static const ElementType type = typeTextDropDown; virtual void create_child_element (const std::wstring & Ns, const std::wstring & Name); virtual void add_child_element ( const office_element_ptr & child_element); @@ -967,8 +990,7 @@ class text_label : public office_element_impl static const wchar_t * ns; static const wchar_t * name; - static const ElementType type = typeTextLabel; - + static const ElementType type = typeTextLabel; virtual void create_child_element (const std::wstring & Ns, const std::wstring & Name){} virtual void add_child_element ( const office_element_ptr & child_element){} @@ -981,5 +1003,33 @@ class text_label : public office_element_impl _CP_OPT(std::wstring) text_; }; CP_REGISTER_OFFICE_ELEMENT2(text_label); +//------------------------------------------------------------------------------------------------------------------- +//text:user-defined +//--------------------------------------------------------------------------------------------------- +class text_user_defined : public office_element_impl +{ +public: + static const wchar_t* ns; + static const wchar_t* name; + + static const ElementType type = typeTextUserDefined; + + virtual void create_child_element(const std::wstring& Ns, const std::wstring& Name) {} + virtual void add_child_element(const office_element_ptr& child_element); + + virtual void add_text(const std::wstring& Text); + virtual void serialize(std::wostream& _Wostream); + + std::wstring get_text_content(); + + _CP_OPT(std::wstring) style_data_style_name_; + _CP_OPT(std::wstring) text_name_; + _CP_OPT(odf_types::Bool) text_fixed_; + odf_types::common_value_and_type_attlist office_value_; + + _CP_OPT(std::wstring) text_; + office_element_ptr_array content_; +}; +CP_REGISTER_OFFICE_ELEMENT2(text_user_defined); } // namespace odf_writer } // namespace cpdoccore diff --git a/OdfFile/Writer/Format/style_graphic_properties.cpp b/OdfFile/Writer/Format/style_graphic_properties.cpp index 6a4743b41ca..6bc7e7f32ed 100644 --- a/OdfFile/Writer/Format/style_graphic_properties.cpp +++ b/OdfFile/Writer/Format/style_graphic_properties.cpp @@ -110,6 +110,11 @@ void graphic_format_properties::apply_from(const graphic_format_properties & Oth _CP_APPLY_PROP(style_background_image_, Other.style_background_image_); } +void graphic_format_properties::add_child_element(xml::sax* Reader, const std::wstring& Ns, const std::wstring& Name) +{ + +} + void graphic_format_properties::serialize(std::wostream & _Wostream ,const wchar_t * ns, const wchar_t * name ) { CP_XML_WRITER(_Wostream) @@ -175,6 +180,9 @@ void graphic_format_properties::serialize(std::wostream & _Wostream ,const wchar common_border_line_width_attlist_.serialize(CP_GET_XML_NODE()); common_padding_attlist_.serialize(CP_GET_XML_NODE()); common_background_color_attlist_.serialize(CP_GET_XML_NODE()); + + if(style_columns_) + style_columns_->serialize(CP_XML_STREAM()); } } } diff --git a/OdfFile/Writer/Format/style_graphic_properties.h b/OdfFile/Writer/Format/style_graphic_properties.h index d8f97ba0459..6095cbdb440 100644 --- a/OdfFile/Writer/Format/style_graphic_properties.h +++ b/OdfFile/Writer/Format/style_graphic_properties.h @@ -38,6 +38,7 @@ #include #include "office_elements_create.h" +#include "style_section_properties.h" #include "../../DataTypes/common_attlists.h" #include "../../DataTypes/lengthorpercent.h" @@ -66,6 +67,8 @@ class graphic_format_properties graphic_format_properties(); //for defaults set void apply_from(const graphic_format_properties & Other); + void add_child_element(xml::sax* Reader, const std::wstring& Ns, const std::wstring& Name); + void serialize(std::wostream & strm, const wchar_t * ns, const wchar_t * name ); _CP_OPT(odf_types::length_or_percent) fo_min_width_; @@ -140,8 +143,10 @@ class graphic_format_properties _CP_OPT(std::wstring) style_mirror_; _CP_OPT(std::wstring) fo_clip_; + //------------------------------------------------------------------------------------- office_element_ptr style_background_image_; + style_columns_ptr style_columns_; }; typedef boost::shared_ptr graphic_format_properties_ptr; diff --git a/OdfFile/Writer/Format/style_presentation.cpp b/OdfFile/Writer/Format/style_presentation.cpp index 64fb1b722ac..e42d11826af 100644 --- a/OdfFile/Writer/Format/style_presentation.cpp +++ b/OdfFile/Writer/Format/style_presentation.cpp @@ -58,7 +58,7 @@ void presentation_placeholder::serialize(std::wostream & strm) CP_XML_ATTR_OPT(L"svg:width", svg_width_); CP_XML_ATTR_OPT(L"svg:x", svg_x_); CP_XML_ATTR_OPT(L"svg:y", svg_y_); - + CP_XML_ATTR_OPT(L"draw:text-style-name", text_style_name_); } } } @@ -100,6 +100,8 @@ void drawing_page_properties::serialize(std::wostream & strm, const wchar_t * ns CP_XML_ATTR_OPT(L"presentation:display-date-time", presentation_display_date_time_); CP_XML_ATTR_OPT(L"presentation:display-header", presentation_display_header_); + CP_XML_ATTR_OPT(L"presentation:visibility", presentation_visibility_); + if (presentation_sound_) presentation_sound_->serialize(CP_XML_STREAM()); } diff --git a/OdfFile/Writer/Format/style_presentation.h b/OdfFile/Writer/Format/style_presentation.h index f6b6600f3e8..b3a791eedef 100644 --- a/OdfFile/Writer/Format/style_presentation.h +++ b/OdfFile/Writer/Format/style_presentation.h @@ -40,13 +40,15 @@ #include "anim_elements.h" #include "../../DataTypes/common_attlists.h" +#include "../../DataTypes/animation_attlists.h" #include "../../DataTypes/presentationclass.h" +#include "../../DataTypes/presentationvisibility.h" #include "../../DataTypes/drawfill.h" namespace cpdoccore { namespace odf_writer { -class presentation_placeholder : public office_element_impl +class presentation_placeholder : public office_element_impl //draw_base ?? { public: static const wchar_t * ns; @@ -54,22 +56,20 @@ class presentation_placeholder : public office_element_impl office_element_ptr_array style_column_; }; +typedef shared_ptr::Type style_columns_ptr; CP_REGISTER_OFFICE_ELEMENT2(style_columns); @@ -91,6 +92,7 @@ class style_column : public office_element_impl _CP_OPT(odf_types::length) fo_space_after_; }; +typedef shared_ptr::Type style_column_ptr; CP_REGISTER_OFFICE_ELEMENT2(style_column); @@ -115,6 +117,7 @@ class style_column_sep : public office_element_impl _CP_OPT(odf_types::vertical_align) style_vertical_align_; // default top _CP_OPT(odf_types::color) style_color_; // default #000000 }; +typedef shared_ptr::Type style_column_sep_ptr; CP_REGISTER_OFFICE_ELEMENT2(style_column_sep); @@ -144,6 +147,7 @@ class style_section_properties : public office_element_impl::Type style_section_properties_ptr; CP_REGISTER_OFFICE_ELEMENT2(style_section_properties); } diff --git a/OdfFile/Writer/Format/styles.cpp b/OdfFile/Writer/Format/styles.cpp index 325b622354b..9408af114d3 100644 --- a/OdfFile/Writer/Format/styles.cpp +++ b/OdfFile/Writer/Format/styles.cpp @@ -109,6 +109,13 @@ text_format_properties* style_content::get_text_properties() return &(style_text->content_); return NULL; } +drawing_page_properties* style_content::get_drawing_page_properties() +{ + style_drawing_page_properties* style_page = dynamic_cast(style_drawing_page_properties_.get()); + if (style_page) + return &(style_page->content_); + return NULL; +} graphic_format_properties * style_content::add_get_style_graphic_properties() { if (!style_graphic_properties_) @@ -247,17 +254,17 @@ void style_content::create_child_element( const std::wstring & Ns, const std::ws } void style_content::serialize(std::wostream & strm) { - if (style_text_properties_) style_text_properties_->serialize(strm); - if (style_paragraph_properties_)style_paragraph_properties_->serialize(strm); - if (style_section_properties_) style_section_properties_->serialize(strm); - if (style_ruby_properties_) style_ruby_properties_->serialize(strm); - if (style_table_properties_) style_table_properties_->serialize(strm); - if (style_table_column_properties_)style_table_column_properties_->serialize(strm); - if (style_table_row_properties_)style_table_row_properties_->serialize(strm); - if (style_chart_properties_) style_chart_properties_->serialize(strm); - if (style_graphic_properties_) style_graphic_properties_->serialize(strm); - if (style_table_cell_properties_)style_table_cell_properties_->serialize(strm); - if (style_drawing_page_properties_)style_drawing_page_properties_->serialize(strm); + if (style_table_cell_properties_) style_table_cell_properties_->serialize(strm); + if (style_graphic_properties_) style_graphic_properties_->serialize(strm); + if (style_paragraph_properties_) style_paragraph_properties_->serialize(strm); + if (style_section_properties_) style_section_properties_->serialize(strm); + if (style_ruby_properties_) style_ruby_properties_->serialize(strm); + if (style_table_properties_) style_table_properties_->serialize(strm); + if (style_table_column_properties_) style_table_column_properties_->serialize(strm); + if (style_table_row_properties_) style_table_row_properties_->serialize(strm); + if (style_chart_properties_) style_chart_properties_->serialize(strm); + if (style_drawing_page_properties_) style_drawing_page_properties_->serialize(strm); + if (style_text_properties_) style_text_properties_->serialize(strm); } // style:default-style @@ -1416,6 +1423,7 @@ void text_linenumbering_configuration::serialize(std::wostream & strm) CP_XML_ATTR_OPT(L"text:count-empty-lines", text_count_empty_lines_); CP_XML_ATTR_OPT(L"text:count-in-text-boxes", text_count_in_text_boxes_); CP_XML_ATTR_OPT(L"text:increment", text_increment_); + CP_XML_ATTR_OPT(L"text:start", text_start_); CP_XML_ATTR_OPT(L"text:number-position", text_number_position_); //inner, left, outer, right CP_XML_ATTR_OPT(L"text:offset", text_offset_); CP_XML_ATTR_OPT(L"text:restart-on-page", text_restart_on_page_); diff --git a/OdfFile/Writer/Format/styles.h b/OdfFile/Writer/Format/styles.h index 48eee7b4023..a932d5dc1f4 100644 --- a/OdfFile/Writer/Format/styles.h +++ b/OdfFile/Writer/Format/styles.h @@ -94,6 +94,7 @@ class graphic_format_properties; class paragraph_format_properties; class chart_format_properties; class text_format_properties; +class drawing_page_properties; class style_content : noncopyable { @@ -108,6 +109,7 @@ class style_content : noncopyable paragraph_format_properties* get_paragraph_properties(); chart_format_properties* get_chart_properties(); text_format_properties* get_text_properties(); + drawing_page_properties* get_drawing_page_properties(); //add & get graphic_format_properties* add_get_style_graphic_properties(); text_format_properties* add_get_style_text_properties(); @@ -839,7 +841,8 @@ class text_linenumbering_configuration : public office_element_implserialize(strm); + content_[i]->serialize(CP_XML_STREAM()); } } } diff --git a/OfficeCryptReader/ooxml_crypt/ooxml_crypt.pro b/OfficeCryptReader/ooxml_crypt/ooxml_crypt.pro index 21c1d2d66a7..df66d25d18b 100644 --- a/OfficeCryptReader/ooxml_crypt/ooxml_crypt.pro +++ b/OfficeCryptReader/ooxml_crypt/ooxml_crypt.pro @@ -24,11 +24,15 @@ DESTDIR = $$CORE_BUILDS_BINARY_PATH HEADERS += \ $$PWD/../source/ECMACryptFile.h \ $$PWD/../source/CryptTransform.h \ - $$PWD/../source/simple_xml_writer.h + $$PWD/../source/simple_xml_writer.h \ + ../../MsBinaryFile/XlsFile/Format/Logging/Log.h \ + ../../MsBinaryFile/XlsFile/Format/Logging/Logger.h SOURCES += \ $$PWD/../source/ECMACryptFile.cpp \ - $$PWD/../source/CryptTransform.cpp + $$PWD/../source/CryptTransform.cpp \ + ../../MsBinaryFile/XlsFile/Format/Logging/Log.cpp \ + ../../MsBinaryFile/XlsFile/Format/Logging/Logger.cpp SOURCES += \ $$CORE_ROOT_DIR/Common/OfficeFileFormatChecker2.cpp \ diff --git a/OfficeCryptReader/source/CryptTransform.cpp b/OfficeCryptReader/source/CryptTransform.cpp index ae7bc0c214c..f822ef48bc4 100644 --- a/OfficeCryptReader/source/CryptTransform.cpp +++ b/OfficeCryptReader/source/CryptTransform.cpp @@ -305,8 +305,16 @@ _buf GenerateOdfKey(_buf & pSalt, _buf & pPassword, int keySize, int spin, CRYPT { _buf pKey (keySize); _buf empty (NULL, 0, false); + _buf pPassword_hash; - _buf pPassword_hash = HashAppend(pPassword, empty, algorithm); + if (algorithm == CRYPT_METHOD::None) + { + pPassword_hash = pPassword; + } + else + { + pPassword_hash = HashAppend(pPassword, empty, algorithm); + } PKCS5_PBKDF2_HMAC pbkdf; @@ -570,6 +578,11 @@ bool ECMADecryptor::SetPassword(std::wstring _password) if (password.empty()) return false; + if (cryptData.keySize > 64 || cryptData.keySize < 1) return false; + if (cryptData.hashSize > 64 || cryptData.hashSize < 1) return false; + if (cryptData.blockSize > 64 || cryptData.blockSize < 1) return false; + if (cryptData.saltSize > 64 || cryptData.saltSize < 1) return false; + _buf pPassword (password); _buf pSalt (cryptData.saltValue); _buf empty (NULL, 0, false); @@ -814,36 +827,63 @@ void ECMADecryptor::Decrypt(unsigned char* data_inp, int size, unsigned char*& d } } //----------------------------------------------------------------------------------------------------------- -void odfWriteProtect::SetPassword (const std::wstring &password_) +void ODFWriteProtect::SetPassword (const std::wstring &password_) { password = password_; } -void odfWriteProtect::SetProtectKey (const std::string &key) + +void ODFWriteProtect::SetCryptData(_odfWriteProtectData &_data) { - protect_key = key; + data = _data; } -void odfWriteProtect::SetProtectAlgorithm (const CRYPT_METHOD::_hashAlgorithm &alg) +void ODFWriteProtect::GetCryptData(_odfWriteProtectData &_data) { - hash = alg; + _data = data; } -void odfWriteProtect::Generate() + +void ODFWriteProtect::Generate() { - _buf pPassword (password); - _buf empty (NULL, 0, false); + //сгенерить соль + RandomPool prng; + SecByteBlock seed_salt(16); + OS_GenerateRandomBlock(false, seed_salt, seed_salt.size()); + if (prng.CanIncorporateEntropy()) + { + prng.IncorporateEntropy(seed_salt, seed_salt.size()); + } - _buf pHashTest = HashAppend(empty, pPassword, hash); - - protect_key = std::string((char*)pHashTest.ptr, pHashTest.size); + std::string passw_ansi = std::string(password.begin(), password.end()); + _buf pPassword (passw_ansi); + _buf pSalt (seed_salt.data(), seed_salt.size()); + + _buf pHash = GenerateOdfKey(pSalt, pPassword, 16, data.spinCount, CRYPT_METHOD::None); + + data.saltValue = std::string((char*)pSalt.ptr, pSalt.size); + data.hashValue = std::string((char*)pHash.ptr, pHash.size); } -bool odfWriteProtect::Verify() +bool ODFWriteProtect::Verify() { - _buf pPassword (password); - _buf empty (NULL, 0, false); - _buf pHash (protect_key); + std::string passw_ansi = std::string(password.begin(), password.end()); - _buf pHashTest = HashAppend(empty, pPassword, hash); - - return (pHashTest == pHash); + _buf pPassword (passw_ansi); + _buf pHash (data.hashValue); + + if (data.hashAlgorithm == CRYPT_METHOD::PBKDF2) + { + _buf pSalt (data.saltValue); + + _buf pHashTest = GenerateOdfKey(pSalt, pPassword, 16, data.spinCount, CRYPT_METHOD::None); + + return (pHashTest == pHash); + } + else + { + _buf empty (NULL, 0, false); + + _buf pHashTest = HashAppend(empty, pPassword, data.hashAlgorithm); + + return (pHashTest == pHash); + } } //---------------------------------------------------------------------------------------------------------- void ECMAWriteProtect::SetPassword (const std::wstring &password_) diff --git a/OfficeCryptReader/source/CryptTransform.h b/OfficeCryptReader/source/CryptTransform.h index 3065e73a228..71c227f6f2b 100644 --- a/OfficeCryptReader/source/CryptTransform.h +++ b/OfficeCryptReader/source/CryptTransform.h @@ -40,12 +40,14 @@ namespace CRYPT_METHOD { enum _hashAlgorithm { + None, MD5, SHA1, SHA224, SHA256, SHA384, - SHA512 + SHA512, + PBKDF2 }; enum _cipherAlgorithm @@ -81,6 +83,7 @@ struct _ecmaWriteProtectData std::string saltValue; std::string hashValue; }; +typedef _ecmaWriteProtectData _odfWriteProtectData; struct _ecmaCryptData { //default ms2010 @@ -162,21 +165,22 @@ class ECMAWriteProtect }; //--------------------------------------------------------------------------------------------------- -class odfWriteProtect +class ODFWriteProtect { public: - odfWriteProtect() : hash(CRYPT_METHOD::SHA1) {} + ODFWriteProtect(){} + virtual ~ODFWriteProtect(){} - void SetPassword (const std::wstring & password); - void SetProtectKey (const std::string & protect_key); - void SetProtectAlgorithm (const CRYPT_METHOD::_hashAlgorithm & hash); + void SetPassword (const std::wstring &password); + + void SetCryptData(_odfWriteProtectData &data); + void GetCryptData(_odfWriteProtectData &data); void Generate(); bool Verify(); private: - std::wstring password; - CRYPT_METHOD::_hashAlgorithm hash; - std::string protect_key; + std::wstring password; + _odfWriteProtectData data; }; //--------------------------------------------------------------------------------------------------- class ECMAEncryptor diff --git a/OfficeCryptReader/source/ECMACryptFile.cpp b/OfficeCryptReader/source/ECMACryptFile.cpp index ee676356d59..174c0066c12 100644 --- a/OfficeCryptReader/source/ECMACryptFile.cpp +++ b/OfficeCryptReader/source/ECMACryptFile.cpp @@ -573,7 +573,7 @@ bool WriteStandartEncryptionInfo(unsigned char* data, int &size, _ecmaCryptData } bool ReadStandartEncryptionInfo(unsigned char* data, int size, _ecmaCryptData & cryptData) { - if (!data || size < 1) return false; + if (!data || size < 36) return false; MemoryStream mem_stream(data, size, false); //EncryptionHeader @@ -780,43 +780,11 @@ bool ECMACryptFile::EncryptOfficeFile(const std::wstring &file_name_inp, const s bool bLargeFile = (lengthData > 3 * 1024 * 1024); - bLargeFile = true; // test ??? - //------------------------------------------------------------------- - POLE::Storage *pStorage = NULL; - CFCPP::CompoundFile *pStorageNew = NULL; - - if (bLargeFile) - { - pStorageNew = new CFCPP::CompoundFile(CFCPP::Ver_3, CFCPP::Default); - } - else - { - pStorage = new POLE::Storage(file_name_out.c_str()); - if (!pStorage)return false; - - if (!pStorage->open(true, true)) - { - delete pStorage; - return false; - } - } -//------------------------------------------------------------------- - if (bLargeFile) - { - std::shared_ptr oPackage = pStorageNew->RootStorage()->AddStream(L"EncryptedPackage"); - oPackage->Write((char*)data_out, 0, lengthData); - } - else - { - POLE::Stream *pStream = new POLE::Stream(pStorage, L"EncryptedPackage", true, lengthData); - - pStream->write(data_out, lengthData); - - pStream->flush(); - delete pStream; - } + CFCPP::CompoundFile *pStorageNew = new CFCPP::CompoundFile(CFCPP::Ver_3, CFCPP::Default); //------------------------------------------------------------------- + std::shared_ptr oPackage = pStorageNew->RootStorage()->AddStream(L"EncryptedPackage"); + oPackage->Write((char*)data_out, 0, lengthData); if (data_out) { @@ -826,134 +794,64 @@ bool ECMACryptFile::EncryptOfficeFile(const std::wstring &file_name_inp, const s cryptor.GetCryptData(cryptData); - if (bLargeFile) - { - std::shared_ptr oInfo = pStorageNew->RootStorage()->AddStream(L"EncryptionInfo"); - - if (cryptData.bAgile) - { - _UINT16 VersionInfoMajor = 0x0004, VersionInfoMinor = 0x0004; //agile - - std::streamsize position = 0; - oInfo->Write((char*)&VersionInfoMajor, position, 2); position += 2; - oInfo->Write((char*)&VersionInfoMinor, position, 2); position += 2; - - _UINT32 nEncryptionInfoFlags = 64; - oInfo->Write((char*)&nEncryptionInfoFlags, position, 4); position += 4; - - std::string strXml; - WriteXmlEncryptionInfo(cryptData, strXml); - - oInfo->Write(strXml.c_str(), position, strXml.length()); position += strXml.length(); - } - else - { - _UINT16 VersionInfoMajor = 0x0004, VersionInfoMinor = 0x0002; // standart - - std::streamsize position = 0; - oInfo->Write((char*)&VersionInfoMajor, position, 2); position += 2; - oInfo->Write((char*)&VersionInfoMinor, position, 2); position += 2; - - _UINT32 nEncryptionInfoFlags = 0; - bool fCryptoAPI = true, fDocProps = false, fExternal = false, fAES = cryptData.cipherAlgorithm != CRYPT_METHOD::RC4; - - SETBIT(nEncryptionInfoFlags, 2, fCryptoAPI); - SETBIT(nEncryptionInfoFlags, 3, fDocProps); - SETBIT(nEncryptionInfoFlags, 4, fExternal); - SETBIT(nEncryptionInfoFlags, 5, fAES); - - oInfo->Write((char*)&nEncryptionInfoFlags, position, 4); position += 4; - - int nEncryptionInfoSize = 4096; - unsigned char* byteEncryptionInfo = new unsigned char[nEncryptionInfoSize]; + std::shared_ptr oInfo = pStorageNew->RootStorage()->AddStream(L"EncryptionInfo"); - WriteStandartEncryptionInfo(byteEncryptionInfo, nEncryptionInfoSize, cryptData); - - oInfo->Write((char*)byteEncryptionInfo, position, 4); position += nEncryptionInfoSize; - delete[]byteEncryptionInfo; - } - } - else - { - POLE::Stream *pStream = new POLE::Stream(pStorage, L"EncryptionInfo", true); - - if (cryptData.bAgile) - { - _UINT16 VersionInfoMajor = 0x0004, VersionInfoMinor = 0x0004; //agile + if (cryptData.bAgile) + { + _UINT16 VersionInfoMajor = 0x0004, VersionInfoMinor = 0x0004; //agile - pStream->write((unsigned char*)&VersionInfoMajor, 2); - pStream->write((unsigned char*)&VersionInfoMinor, 2); + std::streamsize position = 0; + oInfo->Write((char*)&VersionInfoMajor, position, 2); position += 2; + oInfo->Write((char*)&VersionInfoMinor, position, 2); position += 2; - _UINT32 nEncryptionInfoFlags = 64; - pStream->write((unsigned char*)&nEncryptionInfoFlags, 4); + _UINT32 nEncryptionInfoFlags = 64; + oInfo->Write((char*)&nEncryptionInfoFlags, position, 4); position += 4; - std::string strXml; - WriteXmlEncryptionInfo(cryptData, strXml); + std::string strXml; + WriteXmlEncryptionInfo(cryptData, strXml); - pStream->write((unsigned char*)strXml.c_str(), strXml.length()); - } - else - { - _UINT16 VersionInfoMajor = 0x0004, VersionInfoMinor = 0x0002; // standart + oInfo->Write(strXml.c_str(), position, strXml.length()); position += strXml.length(); + } + else + { + _UINT16 VersionInfoMajor = 0x0004, VersionInfoMinor = 0x0002; // standart - pStream->write((unsigned char*)&VersionInfoMajor, 2); - pStream->write((unsigned char*)&VersionInfoMinor, 2); + std::streamsize position = 0; + oInfo->Write((char*)&VersionInfoMajor, position, 2); position += 2; + oInfo->Write((char*)&VersionInfoMinor, position, 2); position += 2; - _UINT32 nEncryptionInfoFlags = 0; - bool fCryptoAPI = true, fDocProps = false, fExternal = false, fAES = cryptData.cipherAlgorithm != CRYPT_METHOD::RC4; + _UINT32 nEncryptionInfoFlags = 0; + bool fCryptoAPI = true, fDocProps = false, fExternal = false, fAES = cryptData.cipherAlgorithm != CRYPT_METHOD::RC4; - SETBIT(nEncryptionInfoFlags, 2, fCryptoAPI); - SETBIT(nEncryptionInfoFlags, 3, fDocProps); - SETBIT(nEncryptionInfoFlags, 4, fExternal); - SETBIT(nEncryptionInfoFlags, 5, fAES); + SETBIT(nEncryptionInfoFlags, 2, fCryptoAPI); + SETBIT(nEncryptionInfoFlags, 3, fDocProps); + SETBIT(nEncryptionInfoFlags, 4, fExternal); + SETBIT(nEncryptionInfoFlags, 5, fAES); - pStream->write((unsigned char*)&nEncryptionInfoFlags, 4); + oInfo->Write((char*)&nEncryptionInfoFlags, position, 4); position += 4; - int nEncryptionInfoSize = 4096; - unsigned char* byteEncryptionInfo = new unsigned char[nEncryptionInfoSize]; + int nEncryptionInfoSize = 4096; + unsigned char* byteEncryptionInfo = new unsigned char[nEncryptionInfoSize]; - WriteStandartEncryptionInfo(byteEncryptionInfo, nEncryptionInfoSize, cryptData); + WriteStandartEncryptionInfo(byteEncryptionInfo, nEncryptionInfoSize, cryptData); - pStream->write(byteEncryptionInfo, nEncryptionInfoSize); - delete[]byteEncryptionInfo; + oInfo->Write((char*)byteEncryptionInfo, position, 4); position += nEncryptionInfoSize; + delete[]byteEncryptionInfo; + } - } - pStream->flush(); - delete pStream; - } //------------------------------------------------------------------- if (false == documentID.empty()) { std::string utfDocumentID = NSFile::CUtf8Converter::GetUtf8StringFromUnicode(documentID); - if (bLargeFile) - { - - std::shared_ptr oDocumentID = pStorageNew->RootStorage()->AddStream(L"DocumentID"); - oDocumentID->Write(utfDocumentID.c_str(), 0, utfDocumentID.length()); - } - else - { - POLE::Stream *pStream = new POLE::Stream(pStorage, L"DocumentID", true, utfDocumentID.length()); - - pStream->write((BYTE*)utfDocumentID.c_str(), utfDocumentID.length()); - pStream->flush(); - delete pStream; - } + std::shared_ptr oDocumentID = pStorageNew->RootStorage()->AddStream(L"DocumentID"); + oDocumentID->Write(utfDocumentID.c_str(), 0, utfDocumentID.length()); } //------------------------------------------------------------------- - bool result = true; - if (bLargeFile) - { - result = pStorageNew->Save(file_name_out); - pStorageNew->Close(); - delete pStorageNew; - } - else - { - pStorage->close(); - delete pStorage; - } + bool result = pStorageNew->Save(file_name_out); + pStorageNew->Close(); + delete pStorageNew; + // ////test back---------------------------------------------------------------------------------test back // ECMADecryptor decryptor; @@ -998,7 +896,7 @@ bool ECMACryptFile::DecryptOfficeFile(const std::wstring &file_name_inp, const s if (pStream) { - if (pStream->fail()) + if (pStream->fail() || pStream->size() < 8) { delete pStream; delete pStorage; @@ -1195,3 +1093,22 @@ bool ECMACryptFile::WriteAdditional(const std::wstring &file_name, const std::ws return true; } + +bool TestOdfProtect(const std::wstring &passward, const std::string &salt, const std::string &hash, int count) +{ + CRYPT::ODFWriteProtect test; + + CRYPT::_odfWriteProtectData ver1; + + ver1.hashAlgorithm = CRYPT_METHOD::PBKDF2; + ver1.hashValue = DecodeBase64(hash); + ver1.saltValue = DecodeBase64(salt); + ver1.spinCount = count; + + test.SetCryptData(ver1); + test.SetPassword(passward); + bool result_ver1 = test.Verify(); + + return result_ver1; +} + diff --git a/OfficeUtils/js/wasm/js/code.js b/OfficeUtils/js/wasm/js/code.js index 9cafcdbb018..37f43c3f961 100644 --- a/OfficeUtils/js/wasm/js/code.js +++ b/OfficeUtils/js/wasm/js/code.js @@ -1,3 +1,5 @@ +// not intended for use in production. only for testing/debugging purposes + window.onload = function() { var holder = document.body; diff --git a/OfficeUtils/src/OfficeUtils.h b/OfficeUtils/src/OfficeUtils.h index 7e9d1a081cc..827352118f2 100644 --- a/OfficeUtils/src/OfficeUtils.h +++ b/OfficeUtils/src/OfficeUtils.h @@ -53,7 +53,7 @@ class KERNEL_DECL COfficeUtils HRESULT ExtractToDirectory (const std::wstring& zipFile, const std::wstring& unzipDir, wchar_t* password, short extract_without_path); HRESULT ExtractToDirectory (BYTE* data, size_t len, const std::wstring& unzipDir, wchar_t* password, short extract_without_path); - HRESULT CompressFileOrDirectory (const std::wstring& name, const std::wstring& outputFile, bool bSorted = false, int method = Z_DEFLATED, short level = -1, bool bDateTime = false); + HRESULT CompressFileOrDirectory (const std::wstring& name, const std::wstring& outputFile, bool bSorted = false, int method = Z_DEFLATED, short level = -1, bool bDateTime = true); HRESULT Uncompress (BYTE* destBuf, ULONG* destSize, BYTE* sourceBuf, ULONG sourceSize); HRESULT Compress (BYTE* destBuf, ULONG* destSize, BYTE* sourceBuf, ULONG sourceSize, short level = -1); diff --git a/OfficeUtils/src/ZipFolder.h b/OfficeUtils/src/ZipFolder.h index 35577f851f6..20f2b7fd5b9 100644 --- a/OfficeUtils/src/ZipFolder.h +++ b/OfficeUtils/src/ZipFolder.h @@ -99,6 +99,7 @@ class IFolder virtual void remove(const std::wstring& path) = 0; // работа с директориями virtual void createDirectory(const std::wstring& path) = 0; + virtual void removeDirectory(const std::wstring& path) = 0; virtual std::vector getFiles(const std::wstring& path, bool recursion) = 0; // финализация virtual CBuffer* finalize() { return NULL; } @@ -133,6 +134,7 @@ class IFolder { return true; } + iter++; } } @@ -184,6 +186,70 @@ class IFolder delete buffer; return sXmlUtf8; } + bool readFileWithChunks(const std::wstring& path, CBuffer*& buffer) + { + if (this->exists(path)) + return this->read(path, buffer); + + std::vector arPieces = getFiles(path, false); + if (0 < arPieces.size()) + { + std::sort(arPieces.begin(), arPieces.end(), compareAsXmlPiece); + std::vector::iterator iter = arPieces.begin(); + while (iter != arPieces.end()) + { + std::wstring::size_type len = iter->length(); + std::wstring::size_type pos = iter->rfind(L".piece"); + if (std::wstring::npos != pos && ((pos + 6) == len)) + { + iter++; + continue; + } + else + { + iter = arPieces.erase(iter); + } + } + } + if (0 == arPieces.size()) + return false; + + std::vector arBuffers; + DWORD dwSizeFull = 0; + for (std::vector::iterator iter = arPieces.begin(); iter != arPieces.end(); iter++) + { + CBuffer* bufferPiece = NULL; + if (read(*iter, bufferPiece)) + { + arBuffers.push_back(bufferPiece); + dwSizeFull += bufferPiece->Size; + } + } + + if (0 == dwSizeFull) + return false; + + BYTE* pData = new BYTE[dwSizeFull]; + DWORD dwPos = 0; + for (std::vector::iterator iter = arBuffers.begin(); iter != arBuffers.end(); iter++) + { + CBuffer* bufferPiece = *iter; + DWORD dwSizeChunk = bufferPiece->Size; + if (dwSizeChunk != 0) + { + memcpy(pData + dwPos, bufferPiece->Buffer, dwSizeChunk); + dwPos += dwSizeChunk; + } + delete bufferPiece; + } + arBuffers.clear(); + + this->removeDirectory(path); + this->write(path, pData, dwSizeFull); + + buffer = new CBuffer(pData, dwSizeFull, true); + return true; + } std::string getFileBase64(const std::wstring& path) { CBuffer* buffer = NULL; @@ -343,7 +409,8 @@ class CFolderSystem : public IFolder } virtual bool exists(const std::wstring& path) { - return NSFile::CFileBinary::Exists(getFullFilePath(path)); + std::wstring full = getFullFilePath(path); + return NSFile::CFileBinary::Exists(full) && !NSDirectory::Exists(full); } virtual void remove(const std::wstring& path) { @@ -355,6 +422,12 @@ class CFolderSystem : public IFolder if (!NSDirectory::Exists(sPath)) NSDirectory::CreateDirectory(sPath); } + virtual void removeDirectory(const std::wstring& path) + { + std::wstring sPath = getFullFilePath(path); + if (NSDirectory::Exists(sPath)) + NSDirectory::DeleteDirectory(sPath); + } virtual std::vector getFiles(const std::wstring& path, bool bIsRecursion) { std::wstring folder = getFullFilePath(path); @@ -394,8 +467,8 @@ class CZipFolderMemory : public IFolder { std::string sPath = U_TO_UTF8(path); if (!sPath.empty() && sPath[0] == '/') - return NSSystemPath::NormalizePath(sPath.substr(1)); - return NSSystemPath::NormalizePath(sPath); + return NSSystemPath::NormalizePath(sPath.substr(1), true); + return NSSystemPath::NormalizePath(sPath, true); } public: @@ -474,6 +547,12 @@ class CZipFolderMemory : public IFolder virtual void createDirectory(const std::wstring& path) { } + virtual void removeDirectory(const std::wstring& path) + { + std::vector arFiles = getFiles(path, true); + for (std::vector::iterator i = arFiles.begin(); i != arFiles.end(); i++) + remove(*i); + } // Возвращает вектор путей расположенных в папке virtual std::vector getFiles(const std::wstring& path, bool bIsRecursion) { diff --git a/OfficeUtils/src/ZipUtilsCP.cpp b/OfficeUtils/src/ZipUtilsCP.cpp index 2092cc754b5..184dbb95d2a 100644 --- a/OfficeUtils/src/ZipUtilsCP.cpp +++ b/OfficeUtils/src/ZipUtilsCP.cpp @@ -206,7 +206,7 @@ namespace ZLibZipUtils #endif } static void change_file_date( const wchar_t *filename, uLong dosdate, tm_unz tmu_date ); - static int do_extract_currentfile( unzFile uf, const wchar_t* unzip_dir, const int* popt_extract_without_path, int* popt_overwrite, const char* password ); + static int do_extract_currentfile( unzFile uf, const wchar_t* unzip_dir, const int* popt_extract_without_path, int* popt_overwrite, const char* password, bool is_replace_slash = false ); static int do_extract( unzFile uf, const wchar_t* unzip_dir, int opt_extract_without_path, int opt_overwrite, const char* password, const OnProgressCallback* progress ); static bool is_file_in_archive(unzFile uf, const wchar_t *filename); @@ -217,28 +217,6 @@ namespace ZLibZipUtils /*========================================================================================================*/ - /* change_file_date : change the date/time of a file - filename : the filename of the file where date/time must be modified - dosdate : the new date at the MSDos format (4 bytes) - tmu_date : the SAME new date at the tm_unz format */ - static void change_file_date( const wchar_t *filename, uLong dosdate, tm_unz tmu_date ) - { -#if defined(_WIN32) || defined (_WIN64) - HANDLE hFile; - FILETIME ftm,ftLocal,ftCreate,ftLastAcc,ftLastWrite; - - hFile = CreateFileW(filename,GENERIC_READ | GENERIC_WRITE, - 0,NULL,OPEN_EXISTING,0,NULL); - GetFileTime(hFile,&ftCreate,&ftLastAcc,&ftLastWrite); - DosDateTimeToFileTime((WORD)(dosdate>>16),(WORD)dosdate,&ftLocal); - LocalFileTimeToFileTime(&ftLocal,&ftm); - SetFileTime(hFile,&ftm,&ftLastAcc,&ftm); - CloseHandle(hFile); -#endif - } - - /*========================================================================================================*/ - static void replace_all(std::string& subject, const std::string& search, const std::string& replace) { size_t pos = 0; @@ -259,7 +237,7 @@ namespace ZLibZipUtils } } - static int do_extract_currentfile( unzFile uf, const wchar_t* unzip_dir, const int* popt_extract_without_path, int* popt_overwrite, const char* password ) + static int do_extract_currentfile( unzFile uf, const wchar_t* unzip_dir, const int* popt_extract_without_path, int* popt_overwrite, const char* password, bool is_replcace_slash ) { char filename_inzipA[4096]; int err = UNZ_OK; @@ -279,6 +257,12 @@ namespace ZLibZipUtils for(std::wstring::size_type i = 0, len = filenameW.length(); i < len; ++i) if(filenameW[i] == L'/') filenameW[i] = L'\\'; +#else + if (is_replcace_slash) + for (std::wstring::size_type i = 0, len = filenameW.length(); i < len; ++i) + if(filenameW[i] == L'\\') + filenameW[i] = L'/'; + #endif std::wstring filenameW_withoutpath = L""; @@ -380,13 +364,22 @@ namespace ZLibZipUtils break; } } + // ? while (err>0); - - //close вызовется в oFile - if (err==0) { - change_file_date(write_filename, file_info.dosDate, file_info.tmu_date); + oFile.CloseFile(); + + struct tm time; + memset(&time, 0, sizeof(struct tm)); + time.tm_sec = file_info.tmu_date.tm_sec; + time.tm_min = file_info.tmu_date.tm_min; + time.tm_hour = file_info.tmu_date.tm_hour; + time.tm_mday = file_info.tmu_date.tm_mday; + time.tm_mon = file_info.tmu_date.tm_mon + 1; + time.tm_year = file_info.tmu_date.tm_year; + + NSFile::CFileBinary::SetTime(write_filename, &time); } } @@ -407,21 +400,27 @@ namespace ZLibZipUtils static int do_extract( unzFile uf, const wchar_t* unzip_dir, int opt_extract_without_path, int opt_overwrite, const char* password, const OnProgressCallback* progress ) { - uLong i; + uLong i, number_extract = 0; unz_global_info gi; int err; FILE* fout=NULL; + // [Content-Types.xml] check + // if found - it is a office file, so we can replace '\' to '/' for non-windows + // fixes bad zips + const char* content_types = "[Content_Types].xml"; + bool is_office = UNZ_OK == unzLocateFile(uf, content_types, true); + unzGoToFirstFile(uf); + err = unzGetGlobalInfo (uf,&gi); - for (i=0;idosDate = oFile.GetDateTime(file_name); + struct tm edited; + bool ok = NSFile::CFileBinary::GetTime(file_name, &edited); + if (ok) + { + zinfo.tmz_date.tm_sec = edited.tm_sec; + zinfo.tmz_date.tm_min = edited.tm_min; + zinfo.tmz_date.tm_hour = edited.tm_hour; + zinfo.tmz_date.tm_mday = edited.tm_mday; + zinfo.tmz_date.tm_mon = edited.tm_mon - 1; + zinfo.tmz_date.tm_year = edited.tm_year; + } } - if(oFile.OpenFile(file_name)) + zip_fileinfo* zi_new = bDateTime ? &zinfo : NULL; + + if (oFile.OpenFile(file_name)) { DWORD dwSizeRead; BYTE* pData = new BYTE[oFile.GetFileSize()]; - if(oFile.ReadFile(pData, oFile.GetFileSize(), dwSizeRead)) + if (oFile.ReadFile(pData, oFile.GetFileSize(), dwSizeRead)) { std::string zipFileNameA = codepage_issue_fixToOEM(zip_file_name); @@ -592,7 +604,7 @@ namespace ZLibZipUtils } RELEASEARRAYOBJECTS(pData); } - return 0; + return err; } int ZipDir( const WCHAR* dir, const WCHAR* outputFile, const OnProgressCallback* progress, bool sorted, int method, int compressionLevel, bool bDateTime ) { @@ -647,6 +659,11 @@ namespace ZLibZipUtils StringDeque.push_front( aCurDirectories[i] ); zipDeque.push_front( zipDir + sDirName ); } + else if (sDirName == L"_rels") + { + StringDeque.push_front(aCurDirectories[i]); + zipDeque.push_front(zipDir + sDirName); + } else { StringDeque.push_back( aCurDirectories[i] ); @@ -664,13 +681,14 @@ namespace ZLibZipUtils { std::wstring cFileName = NSSystemPath::GetFileName(aCurFiles[i]); - if (std::wstring::npos != cFileName.find(L"mimetype") || - std::wstring::npos != cFileName.find(L"[Content_Types]")) // возможно и полное соответствие - { + if ( std::wstring::npos != cFileName.find(L"mimetype") || + std::wstring::npos != cFileName.find(L"[Content_Types]") || + cFileName == L".rels") + { file = NSSystemPath::Combine(szText, cFileName); zipFileName = zipDir + cFileName; - oneZipFile(zf, NULL, file, zipFileName, 0, compressionLevel, bDateTime); + oneZipFile(zf, file, zipFileName, 0, compressionLevel, bDateTime); aCurFiles.erase(aCurFiles.begin() + i, aCurFiles.begin() + i + 1); break; @@ -683,7 +701,7 @@ namespace ZLibZipUtils file = NSSystemPath::Combine(szText, cFileName); zipFileName = zipDir + cFileName; - oneZipFile(zf, NULL, file, zipFileName, method, compressionLevel, bDateTime); + oneZipFile(zf, file, zipFileName, method, compressionLevel, bDateTime); if ( progress != NULL ) { @@ -720,15 +738,32 @@ namespace ZLibZipUtils { int err = -1; - if ( ( inputFile != NULL ) && ( outputFile != NULL ) ) + if (( inputFile != NULL) && (outputFile != NULL)) { NSFile::CFileBinary oFile; zip_fileinfo zinfo; - zinfo.external_fa = zinfo.internal_fa = 0; - zinfo.dosDate = bDateTime ? oFile.GetDateTime(inputFile) : 0; + zinfo.dosDate = 0; + zinfo.external_fa = 0; + zinfo.internal_fa = 0; + + if (bDateTime) + { + struct tm edited; + bool ok = NSFile::CFileBinary::GetTime(inputFile, &edited); + if (ok) + { + zinfo.tmz_date.tm_sec = edited.tm_sec; + zinfo.tmz_date.tm_min = edited.tm_min; + zinfo.tmz_date.tm_hour = edited.tm_hour; + zinfo.tmz_date.tm_mday = edited.tm_mday; + zinfo.tmz_date.tm_mon = edited.tm_mon - 1; + zinfo.tmz_date.tm_year = edited.tm_year; + } + } + zip_fileinfo* zi_new = bDateTime ? &zinfo : NULL; - if(oFile.OpenFile(inputFile)) + if (oFile.OpenFile(inputFile)) { DWORD dwSizeRead; BYTE* pData = new BYTE[oFile.GetFileSize()]; @@ -737,26 +772,10 @@ namespace ZLibZipUtils zipFile zf = zipOpenHelp(outputFile); if (zf) { - wstring inputFileName( inputFile ); - - wstring::size_type pos = 0; - static const wstring::size_type npos = -1; - - pos = inputFileName.find_last_of( L'\\' ); - - wstring zipFileName; - - if ( pos != npos ) - { - zipFileName = wstring( ( inputFileName.begin() + pos + 1 ), inputFileName.end() ); - } - else - { - zipFileName = wstring( inputFileName.begin(), inputFileName.end() ); - } + wstring zipFileName = NSFile::GetFileName(inputFile); std::string zipFileNameA = codepage_issue_fixToOEM(zipFileName); - err = zipOpenNewFileInZip( zf, zipFileNameA.c_str(), &zinfo, NULL, 0, NULL, 0, NULL, method, compressionLevel ); + err = zipOpenNewFileInZip( zf, zipFileNameA.c_str(), zi_new, NULL, 0, NULL, 0, NULL, method, compressionLevel ); err = zipWriteInFileInZip( zf, pData, dwSizeRead ); err = zipCloseFileInZip( zf ); err = zipClose( zf, NULL ); @@ -839,11 +858,12 @@ namespace ZLibZipUtils int UnzipToDir(unzFile uf, const WCHAR* unzipDir, const OnProgressCallback* progress, const WCHAR* password, bool opt_extract_without_path, bool clearOutputDirectory ) { int err = -1; - if(NSDirectory::Exists(unzipDir)) - err = 0; if ( uf != NULL && unzipDir != NULL ) { + if (NSDirectory::Exists(unzipDir)) + err = 0; + if ( clearOutputDirectory ) { ClearDirectory( unzipDir ); diff --git a/OfficeUtils/tests/.gitignore b/OfficeUtils/tests/.gitignore index 07fb5b83ca6..3390380ff38 100644 --- a/OfficeUtils/tests/.gitignore +++ b/OfficeUtils/tests/.gitignore @@ -1 +1,2 @@ -unzip \ No newline at end of file +unzip +temp \ No newline at end of file diff --git a/OfficeUtils/tests/main.cpp b/OfficeUtils/tests/main.cpp index 22bfc763624..4f6364f6035 100644 --- a/OfficeUtils/tests/main.cpp +++ b/OfficeUtils/tests/main.cpp @@ -1,5 +1,7 @@ #include #include +#include +#include #include "gtest/gtest.h" @@ -53,6 +55,7 @@ class COfficeUtilsTest : public testing::Test std::wstring zipDirectory; std::wstring unzipDirectory; std::wstring wsep; + std::wstring tempDirectory; std::vector expected_general; std::vector expected_general_no_folder; @@ -70,10 +73,14 @@ class COfficeUtilsTest : public testing::Test workDirectory = NSFile::GetProcessDirectory(); unzipDirectory = workDirectory + wsep + L".." + wsep + L"unzip"; zipDirectory = workDirectory + wsep + L".." + wsep + L"zip"; + tempDirectory = workDirectory + wsep + L".." + wsep + L"temp"; if(!NSDirectory::Exists(unzipDirectory)) NSDirectory::CreateDirectories(unzipDirectory); + if(!NSDirectory::Exists(tempDirectory)) + NSDirectory::CreateDirectories(tempDirectory); + // general expected_general.push_back(L"1.txt"); expected_general.push_back(L"2.txt"); @@ -380,3 +387,112 @@ TEST_F(COfficeUtilsTest, other_win) ASSERT_EQ(error_code, S_OK); EXPECT_EQ(wstr, L"123 321"); } + +TEST_F(COfficeUtilsTest, time_file) +{ + // creating file + std::wstring filename = L"time_file_test.txt"; + std::wstring file_path = tempDirectory + wsep + filename; + + std::wstring zip_filename = L"time_file_test.zip"; + std::wstring zip_path = tempDirectory + wsep + zip_filename; + + std::wstring unzip_folder = tempDirectory + wsep + L"time_file_test"; + std::wstring unzip_path = unzip_folder + wsep + filename; + + // folder for unzip files + if (NSDirectory::Exists(unzip_folder)) + NSDirectory::DeleteDirectory(unzip_folder); + + NSDirectory::CreateDirectories(unzip_folder); + + // create file to zip, then unzip it + if (NSFile::CFileBinary::Exists(file_path)) + NSFile::CFileBinary::Remove(file_path); + + NSFile::CFileBinary file; + file.CreateFileW(file_path); + file.WriteStringUTF8(L"some text"); + file.CloseFile(); + + struct tm edit_time_before{}; + bool result_get_time_before = NSFile::CFileBinary::GetTime(file_path, &edit_time_before); + ASSERT_EQ(result_get_time_before, true); + + HRESULT error_code = utils.CompressFileOrDirectory(file_path, zip_path); + ASSERT_EQ(error_code, S_OK); + + error_code = utils.ExtractToDirectory(zip_path, unzip_folder, NULL, false); + ASSERT_EQ(error_code, S_OK); + + struct tm edit_time_after{}; + bool result_get_time_after = NSFile::CFileBinary::GetTime(unzip_path, &edit_time_after); + ASSERT_EQ(result_get_time_after, true); + + EXPECT_EQ(edit_time_before.tm_sec, edit_time_after.tm_sec); + EXPECT_EQ(edit_time_before.tm_min, edit_time_after.tm_min); + EXPECT_EQ(edit_time_before.tm_hour, edit_time_after.tm_hour); + EXPECT_EQ(edit_time_before.tm_mday, edit_time_after.tm_mday); + EXPECT_EQ(edit_time_before.tm_mon, edit_time_after.tm_mon); + EXPECT_EQ(edit_time_before.tm_year, edit_time_after.tm_year); +} + +TEST_F(COfficeUtilsTest, time_folder) +{ + std::wstring file_folder = tempDirectory + wsep + L"time_file_test_folder"; + + // creating file + std::wstring filename = L"time_file_test.txt"; + std::wstring file_path = file_folder + wsep + filename; + + std::wstring zip_filename = L"time_file_test.zip"; + std::wstring zip_path = tempDirectory + wsep + zip_filename; + + std::wstring unzip_folder = tempDirectory + wsep + L"time_file_test"; + std::wstring unzip_path = unzip_folder + wsep + filename; + + // folder for unzip files + if (NSDirectory::Exists(unzip_folder)) + NSDirectory::DeleteDirectory(unzip_folder); + + NSDirectory::CreateDirectories(unzip_folder); + + // folder for zip files + if (NSDirectory::Exists(file_folder)) + NSDirectory::DeleteDirectory(file_folder); + + NSDirectory::CreateDirectories(file_folder); + + // create file to zip, then unzip it + if (NSFile::CFileBinary::Exists(file_path)) + NSFile::CFileBinary::Remove(file_path); + + NSFile::CFileBinary file; + file.CreateFileW(file_path); + file.WriteStringUTF8(L"some text"); + file.CloseFile(); + + struct tm edit_time_before{}; + bool result_get_time_before = NSFile::CFileBinary::GetTime(file_path, &edit_time_before); + ASSERT_EQ(result_get_time_before, true); + + HRESULT error_code = utils.CompressFileOrDirectory(file_folder, zip_path); + ASSERT_EQ(error_code, S_OK); + + error_code = utils.ExtractToDirectory(zip_path, unzip_folder, NULL, false); + ASSERT_EQ(error_code, S_OK); + + struct tm edit_time_after{}; + bool result_get_time_after = NSFile::CFileBinary::GetTime(unzip_path, &edit_time_after); + ASSERT_EQ(result_get_time_after, true); + + // the 2-second precision + EXPECT_LE(std::abs(edit_time_before.tm_sec - edit_time_after.tm_sec), 1); + + EXPECT_EQ(edit_time_before.tm_min, edit_time_after.tm_min); + EXPECT_EQ(edit_time_before.tm_hour, edit_time_after.tm_hour); + EXPECT_EQ(edit_time_before.tm_mday, edit_time_after.tm_mday); + EXPECT_EQ(edit_time_before.tm_mon, edit_time_after.tm_mon); + EXPECT_EQ(edit_time_before.tm_year, edit_time_after.tm_year); +} + diff --git a/PdfFile/OnlineOfficeBinToPdf.cpp b/PdfFile/OnlineOfficeBinToPdf.cpp index 52f828f1f92..b41b122b247 100644 --- a/PdfFile/OnlineOfficeBinToPdf.cpp +++ b/PdfFile/OnlineOfficeBinToPdf.cpp @@ -146,13 +146,14 @@ namespace NSOnlineOfficeBinToPdf enum class AddCommandType { - EditPage = 0, // Annotation + EditPage = 0, // ранее Annotation AddPage = 1, RemovePage = 2, + WidgetInfo = 3, Undefined = 255 }; - bool AddBinToPdf(CPdfFile* pPdf, BYTE* pBuffer, unsigned int nLen, CConvertFromBinParams* pParams) + bool AddBinToPdf(CPdfFile* pPdf, BYTE* pBuffer, unsigned int nBufferLen, CConvertFromBinParams* pParams) { CMetafileToRenderterPDF oCorrector(pPdf); oCorrector.SetTempDirectory(pPdf->GetTempDirectory()); @@ -166,19 +167,18 @@ namespace NSOnlineOfficeBinToPdf oCorrector.InitPicker(pPdf->GetFonts()); } - NSOnlineOfficeBinToPdf::CBufferReader oReader(pBuffer, (int)nLen); + NSOnlineOfficeBinToPdf::CBufferReader oReader(pBuffer, (int)nBufferLen); while (oReader.Check()) { int nLen = oReader.ReadInt(); AddCommandType CommandType = (AddCommandType)oReader.ReadByte(); - int nPageNum = oReader.ReadInt(); + int nPageNum = 0; + if (CommandType != AddCommandType::WidgetInfo) + nPageNum = oReader.ReadInt(); if (nPageNum < 0) - { - // ошибка в бинарнике return false; - } switch (CommandType) { @@ -191,9 +191,22 @@ namespace NSOnlineOfficeBinToPdf break; } case AddCommandType::AddPage: + { + pPdf->AddPage(nPageNum); + + NSOnlineOfficeBinToPdf::ConvertBufferToRenderer(oReader.GetCurrentBuffer(), (LONG)(nLen - 9) , &oCorrector); + oReader.Skip(nLen - 9); + break; + } case AddCommandType::RemovePage: { - // TODO: version 7.6+ + pPdf->DeletePage(nPageNum); + break; + } + case AddCommandType::WidgetInfo: + { + NSOnlineOfficeBinToPdf::ConvertBufferToRenderer(oReader.GetCurrentBuffer(), (LONG)(nLen - 5) , &oCorrector); + oReader.Skip(nLen - 5); break; } default: diff --git a/PdfFile/PdfEditor.cpp b/PdfFile/PdfEditor.cpp new file mode 100644 index 00000000000..bdc7ec1dfb6 --- /dev/null +++ b/PdfFile/PdfEditor.cpp @@ -0,0 +1,1576 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#include "PdfEditor.h" + +#include "../DesktopEditor/common/Path.h" + +#include "SrcReader/Adaptors.h" +#include "lib/xpdf/PDFDoc.h" +#include "lib/xpdf/AcroForm.h" +#include "lib/xpdf/TextString.h" +#include "lib/xpdf/Lexer.h" +#include "lib/xpdf/Parser.h" + +#include "SrcWriter/Catalog.h" +#include "SrcWriter/EncryptDictionary.h" +#include "SrcWriter/Info.h" +#include "SrcWriter/ResourcesDictionary.h" +#include "SrcWriter/Streams.h" + +#define AddToObject(oVal)\ +{\ + if (pObj->GetType() == PdfWriter::object_type_DICT)\ + ((PdfWriter::CDictObject*)pObj)->Add(sKey, oVal);\ + else if (pObj->GetType() == PdfWriter::object_type_ARRAY)\ + ((PdfWriter::CArrayObject*)pObj)->Add(oVal);\ +} + +void DictToCDictObject(Object* obj, PdfWriter::CObjectBase* pObj, bool bBinary, const std::string& sKey, bool bUnicode = false) +{ + Object oTemp; + switch (obj->getType()) + { + case objBool: + { + bool b = obj->getBool(); + AddToObject(b) + break; + } + case objInt: + { + AddToObject(obj->getInt()) + break; + } + case objReal: + { + AddToObject(obj->getReal()) + break; + } + case objString: + { + if (bBinary) + { + GString* str = obj->getString(); + int nLength = str->getLength(); + BYTE* arrId = new BYTE[nLength]; + for (int nIndex = 0; nIndex < nLength; ++nIndex) + arrId[nIndex] = str->getChar(nIndex); + AddToObject(new PdfWriter::CBinaryObject(arrId, nLength)); + RELEASEARRAYOBJECTS(arrId); + } + else + { + TextString* s = new TextString(obj->getString()); + std::string sValue = NSStringExt::CConverter::GetUtf8FromUTF32(s->getUnicode(), s->getLength()); + AddToObject(new PdfWriter::CStringObject(sValue.c_str(), bUnicode)) + delete s; + } + break; + } + case objName: + { + AddToObject(obj->getName()) + break; + } + case objNull: + { + AddToObject(new PdfWriter::CNullObject()) + break; + } + case objArray: + { + PdfWriter::CArrayObject* pArray = new PdfWriter::CArrayObject(); + AddToObject(pArray) + for (int nIndex = 0; nIndex < obj->arrayGetLength(); ++nIndex) + { + obj->arrayGetNF(nIndex, &oTemp); + DictToCDictObject(&oTemp, pArray, bBinary, "", bUnicode); + oTemp.free(); + } + break; + } + case objDict: + { + PdfWriter::CDictObject* pDict = new PdfWriter::CDictObject(); + AddToObject(pDict); + for (int nIndex = 0; nIndex < obj->dictGetLength(); ++nIndex) + { + char* chKey = obj->dictGetKey(nIndex); + obj->dictGetValNF(nIndex, &oTemp); + DictToCDictObject(&oTemp, pDict, bBinary, chKey, bUnicode); + oTemp.free(); + } + break; + } + case objRef: + { + PdfWriter::CObjectBase* pBase = new PdfWriter::CObjectBase(); + pBase->SetRef(obj->getRefNum(), obj->getRefGen()); + AddToObject(new PdfWriter::CProxyObject(pBase, true)) + break; + } + case objNone: + { + AddToObject("None") + break; + } + case objStream: + case objCmd: + case objError: + case objEOF: + break; + } +} +PdfWriter::CDictObject* GetWidgetParent(PDFDoc* pdfDoc, PdfWriter::CDocument* pDoc, Object* pParentRef) +{ + if (!pParentRef || !pParentRef->isRef() || !pdfDoc) + return NULL; + PdfWriter::CDictObject* pParent = pDoc->GetParent(pParentRef->getRefNum()); + if (pParent) + return pParent; + + Object oParent; + if (!pParentRef->fetch(pdfDoc->getXRef(), &oParent)->isDict()) + { + oParent.free(); + return pParent; + } + + PdfWriter::CXref* pXref = new PdfWriter::CXref(pDoc, pParentRef->getRefNum()); + pParent = new PdfWriter::CDictObject(); + pXref->Add(pParent, pParentRef->getRefGen()); + if (!pDoc->EditParent(pXref, pParent, pParentRef->getRefNum())) + { + RELEASEOBJECT(pXref); + oParent.free(); + return NULL; + } + + for (int i = 0; i < oParent.dictGetLength(); ++i) + { + char* chKey = oParent.dictGetKey(i); + if (strcmp("Parent", chKey) == 0) + { + Object oParentRef; + oParent.dictGetValNF(i, &oParentRef); + PdfWriter::CDictObject* pParent2 = GetWidgetParent(pdfDoc, pDoc, &oParentRef); + if (pParent2) + { + pParent->Add("Parent", pParent2); + oParentRef.free(); + continue; + } + oParentRef.free(); + } + Object oTemp; + oParent.dictGetValNF(i, &oTemp); + DictToCDictObject(&oTemp, pParent, false, chKey); + oTemp.free(); + } + + oParent.free(); + return pParent; +} +HRESULT _ChangePassword(const std::wstring& wsPath, const std::wstring& wsPassword, CPdfReader* _pReader, CPdfWriter* _pWriter) +{ + if (!_pReader || !_pWriter) + return S_FALSE; + PDFDoc* pPDFDocument = _pReader->GetPDFDocument(); + if (!pPDFDocument) + return S_FALSE; + XRef* xref = pPDFDocument->getXRef(); + if (!xref) + return S_FALSE; + Object* trailerDict = xref->getTrailerDict(); + if (!trailerDict) + return S_FALSE; + + PdfWriter::CDocument* pDoc = _pWriter->GetDocument(); + PdfWriter::CXref* pXref = new PdfWriter::CXref(pDoc, 0); + PdfWriter::CXref* m_pXref = new PdfWriter::CXref(pDoc, xref->getNumObjects()); // Для новых объектов + if (!xref || !pDoc || !pXref || !m_pXref) + { + RELEASEOBJECT(pXref); + RELEASEOBJECT(m_pXref); + return S_FALSE; + } + pXref->SetPrev(m_pXref); + + for (int i = 0; i < xref->getSize(); ++i) + { + XRefEntry* pEntry = xref->getEntry(i); + if (pEntry->type == xrefEntryFree) + continue; + + if (i != pXref->GetSizeXRef()) + { + PdfWriter::CXref* pXref2 = new PdfWriter::CXref(pDoc, i); + pXref2->SetPrev(pXref); + pXref = pXref2; + } + + Object oTemp; + xref->fetch(i, pEntry->gen, &oTemp); + PdfWriter::CObjectBase* pObj = NULL; + + switch (oTemp.getType()) + { + case objBool: + { + pObj = new PdfWriter::CBoolObject(oTemp.getBool()); + break; + } + case objInt: + { + pObj = new PdfWriter::CNumberObject(oTemp.getInt()); + break; + } + case objReal: + { + pObj = new PdfWriter::CRealObject(oTemp.getReal()); + break; + } + case objString: + { + TextString* s = new TextString(oTemp.getString()); + std::string sValue = NSStringExt::CConverter::GetUtf8FromUTF32(s->getUnicode(), s->getLength()); + pObj = new PdfWriter::CStringObject(sValue.c_str()); + delete s; + break; + } + case objName: + { + pObj = new PdfWriter::CNameObject(oTemp.getName()); + break; + } + case objNull: + { + pObj = new PdfWriter::CNullObject(); + break; + } + case objArray: + { + pObj = new PdfWriter::CArrayObject(); + + for (int nIndex = 0; nIndex < oTemp.arrayGetLength(); ++nIndex) + { + Object oT; + oTemp.arrayGetNF(nIndex, &oT); + DictToCDictObject(&oT, pObj, false, ""); + oT.free(); + } + break; + } + case objDict: + { + pObj = new PdfWriter::CDictObject(); + + for (int nIndex = 0; nIndex < oTemp.dictGetLength(); ++nIndex) + { + Object oT; + char* chKey = oTemp.dictGetKey(nIndex); + oTemp.dictGetValNF(nIndex, &oT); + DictToCDictObject(&oT, pObj, false, chKey); + oT.free(); + } + break; + } + case objRef: + { + PdfWriter::CObjectBase* pBase = new PdfWriter::CObjectBase(); + pBase->SetRef(oTemp.getRefNum(), oTemp.getRefGen()); + pObj = new PdfWriter::CProxyObject(pBase, true); + break; + } + case objStream: + { + Dict* pDict = oTemp.streamGetDict(); + Object oObjStm; + if (pDict->lookup("Type", &oObjStm)->isName("ObjStm")) + { + oObjStm.free(); + break; + } + oObjStm.free(); + + PdfWriter::CDictObject* pDObj = new PdfWriter::CDictObject(); + pObj = pDObj; + + int nLength = 0; + for (int nIndex = 0; nIndex < pDict->getLength(); ++nIndex) + { + Object oT; + char* chKey = pDict->getKey(nIndex); + if (strcmp("Length", chKey) == 0) + { + Object oLength; + nLength = pDict->getVal(nIndex, &oLength)->isInt() ? oLength.getInt() : 0; + oLength.free(); + continue; + } + pDict->getValNF(nIndex, &oT); + DictToCDictObject(&oT, pObj, false, chKey); + oT.free(); + } + + PdfWriter::CStream* pStream = new PdfWriter::CMemoryStream(); + pDObj->SetStream(m_pXref, pStream, false); + + Stream* pImage = oTemp.getStream()->getUndecodedStream(); + pImage->reset(); + for (int nI = 0; nI < nLength; ++nI) + pStream->WriteChar(pImage->getChar()); + break; + } + case objNone: + case objCmd: + case objError: + case objEOF: + default: + break; + } + oTemp.free(); + + if (pObj) + pXref->Add(pObj); + } + + PdfWriter::CDictObject* pTrailer = pXref->GetTrailer(); + for (int nIndex = 0; nIndex < trailerDict->dictGetLength(); ++nIndex) + { + Object oTemp; + char* chKey = trailerDict->dictGetKey(nIndex); + if (strcmp("Root", chKey) == 0 || strcmp("Info", chKey) == 0) + { + trailerDict->dictGetValNF(nIndex, &oTemp); + DictToCDictObject(&oTemp, pTrailer, true, chKey); + } + oTemp.free(); + } + + bool bRes = pDoc->SaveNewWithPassword(pXref, m_pXref, wsPath, wsPassword, wsPassword, pTrailer); + + RELEASEOBJECT(pXref); + + return bRes ? S_OK : S_FALSE; +} +void GetCTM(XRef* pXref, Object* oPage, double* dCTM) +{ + if (!oPage || !oPage->isDict()) + return; + + Object oContents; + if (!oPage->dictLookup("Contents", &oContents) || (!oContents.isArray() && !oContents.isStream())) + { + oContents.free(); + return; + } + + Parser* parser = new Parser(pXref, new Lexer(pXref, &oContents), gFalse); + + int nNumArgs = 0; + Object oObj; + Object pArgs[maxArgs]; + + parser->getObj(&oObj); + while (!oObj.isEOF()) + { + if (oObj.isCmd()) + { + if (oObj.isCmd("q")) + { + Object obj; + parser->getObj(&obj); + while (!obj.isEOF() && !obj.isCmd("Q")) + { + obj.free(); + parser->getObj(&obj); + } + obj.free(); + } + else if (oObj.isCmd("cm") && nNumArgs > 5) + { + double a1 = dCTM[0]; + double b1 = dCTM[1]; + double c1 = dCTM[2]; + double d1 = dCTM[3]; + + dCTM[0] = pArgs[0].getNum() * a1 + pArgs[1].getNum() * c1; + dCTM[1] = pArgs[0].getNum() * b1 + pArgs[1].getNum() * d1; + dCTM[2] = pArgs[2].getNum() * a1 + pArgs[3].getNum() * c1; + dCTM[3] = pArgs[2].getNum() * b1 + pArgs[3].getNum() * d1; + dCTM[4] = pArgs[4].getNum() * a1 + pArgs[5].getNum() * c1 + dCTM[4]; + dCTM[5] = pArgs[4].getNum() * b1 + pArgs[5].getNum() * d1 + dCTM[5]; + } + oObj.free(); + for (int i = 0; i < nNumArgs; ++i) + pArgs[i].free(); + nNumArgs = 0; + } + else if (nNumArgs < maxArgs) + pArgs[nNumArgs++] = oObj; + + parser->getObj(&oObj); + } + oObj.free(); + for (int i = 0; i < nNumArgs; ++i) + pArgs[i].free(); + RELEASEOBJECT(parser); + + oContents.free(); +} + +CPdfEditor::CPdfEditor(const std::wstring& _wsSrcFile, const std::wstring& _wsPassword, CPdfReader* _pReader, const std::wstring& _wsDstFile, CPdfWriter* _pWriter) +{ + wsSrcFile = _wsSrcFile; + wsPassword = _wsPassword; + pReader = _pReader; + pWriter = _pWriter; + m_nEditPage = -1; + nError = 0; + + PDFDoc* pPDFDocument = pReader->GetPDFDocument(); + if (!pPDFDocument) + { + nError = 1; + return; + } + + // Если результат редактирования будет сохранен в тот же файл, что открыт для чтения, то файл необходимо сделать редактируемым + std::string sPathUtf8New = U_TO_UTF8(_wsDstFile); + std::string sPathUtf8Old = U_TO_UTF8(wsSrcFile); + if (sPathUtf8Old == sPathUtf8New || NSSystemPath::NormalizePath(sPathUtf8Old) == NSSystemPath::NormalizePath(sPathUtf8New)) + { + GString* owner_pswd = NSStrings::CreateString(wsPassword); + GString* user_pswd = NSStrings::CreateString(wsPassword); + GBool bRes = pPDFDocument->makeWritable(true, owner_pswd, user_pswd); + delete owner_pswd; + delete user_pswd; + if (!bRes) + { + nError = 2; // Не удалось проверить файл для записи + return; + } + } + else + { + if (!NSFile::CFileBinary::Copy(wsSrcFile, _wsDstFile)) + { + nError = 2; + return; + } + NSFile::CFileBinary oFile; + if (!oFile.OpenFile(_wsDstFile, true)) + { + nError = 2; + return; + } + oFile.CloseFile(); + } + + XRef* xref = pPDFDocument->getXRef(); + PdfWriter::CDocument* pDoc = pWriter->GetDocument(); + if (!xref || !pDoc) + { + nError = 1; + return; + } + + // Получение каталога и дерева страниц из reader + Object catDict, catRefObj, pagesRefObj; + if (!xref->getCatalog(&catDict)->isDict() || !catDict.dictLookupNF("Pages", &pagesRefObj)) + { + pagesRefObj.free(); catDict.free(); + nError = 3; // Не удалось получить каталог и дерево страниц + return; + } + Object* trailer = xref->getTrailerDict(); + if (!trailer || !trailer->isDict() || !trailer->dictLookupNF("Root", &catRefObj)->isRef()) + { + pagesRefObj.free(); catDict.free(); catRefObj.free(); + nError = 3; // Не удалось получить каталог и дерево страниц + return; + } + Ref catRef = catRefObj.getRef(); + catRefObj.free(); + + // Создание каталога для writer + PdfWriter::CXref* pXref = new PdfWriter::CXref(pDoc, catRef.num); + if (!pXref) + { + pagesRefObj.free(); catDict.free(); + nError = 1; + return; + } + PdfWriter::CCatalog* pCatalog = new PdfWriter::CCatalog(); + if (!pCatalog) + { + pagesRefObj.free(); catDict.free(); RELEASEOBJECT(pXref); + nError = 1; + return; + } + pXref->Add(pCatalog, catRef.gen); + PdfWriter::CResourcesDict* pDR = NULL; + PdfWriter::CXref* pDRXref = NULL; + for (int nIndex = 0; nIndex < catDict.dictGetLength(); ++nIndex) + { + Object oAcroForm; + char* chKey = catDict.dictGetKey(nIndex); + if (strcmp("AcroForm", chKey) == 0) + { + catDict.dictGetVal(nIndex, &oAcroForm); + PdfWriter::CDictObject* pAcroForm = new PdfWriter::CDictObject(); + + for (int nIndex = 0; nIndex < oAcroForm.dictGetLength(); ++nIndex) + { + Object oTemp2; + char* chKey = oAcroForm.dictGetKey(nIndex); + if (strcmp("DR", chKey) == 0) + { + if (!oAcroForm.dictGetVal(nIndex, &oTemp2)->isDict()) + { + oTemp2.free(); + continue; + } + + Object oDR; + oAcroForm.dictGetValNF(nIndex, &oDR); + int nDRxrefNum = oDR.isRef() ? oDR.getRefNum() : xref->getNumObjects(); + int nDRxrefGen = oDR.isRef() ? oDR.getRefGen() : 0; + oDR.free(); + pDRXref = new PdfWriter::CXref(pDoc, nDRxrefNum); + + pDR = new PdfWriter::CResourcesDict(NULL, true, false); + pDRXref->Add(pDR, nDRxrefGen); + + pAcroForm->Add(chKey, pDR); + for (int nIndex2 = 0; nIndex2 < oTemp2.dictGetLength(); ++nIndex2) + { + Object oTemp; + char* chKey2 = oTemp2.dictGetKey(nIndex2); + oTemp2.dictGetVal(nIndex2, &oTemp); + DictToCDictObject(&oTemp, pDR, false, chKey2); + oTemp.free(); + } + oTemp2.free(); + + pDR->Fix(); + continue; + } + else + oAcroForm.dictGetValNF(nIndex, &oTemp2); + DictToCDictObject(&oTemp2, pAcroForm, false, chKey); + oTemp2.free(); + } + + if (!pAcroForm->Get("Fields")) + pAcroForm->Add("Fields", new PdfWriter::CArrayObject()); + + oAcroForm.free(); + pCatalog->Add(chKey, pAcroForm); + continue; + } + else + catDict.dictGetValNF(nIndex, &oAcroForm); + DictToCDictObject(&oAcroForm, pCatalog, false, chKey); + oAcroForm.free(); + } + catDict.free(); + + // Проверка уникальности имён текущих цифровых подписей pdf + unsigned int nFormField = 0; + AcroForm* form = pPDFDocument->getCatalog()->getForm(); + if (form) + { + nFormField = form->getNumFields() + 1; + std::wstring sSig = L"Sig" + std::to_wstring(nFormField); + int i = 0, nFormFields = form->getNumFields(); + while (i < nFormFields) + { + int nLength; + Unicode* uName = form->getField(i)->getName(&nLength); + std::wstring sName = NSStringExt::CConverter::GetUnicodeFromUTF32(uName, nLength); + RELEASEMEM(uName); + if (sName == sSig) + { + i = 0; + nFormField++; + sSig = L"Sig" + std::to_wstring(nFormField); + } + else + i++; + } + nFormField--; + } + + // Получение шифрования из reader и применения для writer + int nCryptAlgorithm = -1; + PdfWriter::CEncryptDict* pEncryptDict = NULL; + if (xref->isEncrypted()) + { + CryptAlgorithm encAlgorithm; + GBool ownerPasswordOk; + int permFlags, keyLength, encVersion; + xref->getEncryption(&permFlags, &ownerPasswordOk, &keyLength, &encVersion, &encAlgorithm); + nCryptAlgorithm = encAlgorithm; + + Object* pTrailerDict = xref->getTrailerDict(); + if (pTrailerDict) + { + pEncryptDict = new PdfWriter::CEncryptDict(); + + // Нужно получить словарь Encrypt БЕЗ дешифровки, поэтому времено отключаем encrypted в xref + xref->offEncrypted(); + + Object encrypt, ID, ID1; + if (pTrailerDict->dictLookup("Encrypt", &encrypt) && encrypt.isDict()) + { + for (int nIndex = 0; nIndex < encrypt.dictGetLength(); ++nIndex) + { + Object oTemp; + char* chKey = encrypt.dictGetKey(nIndex); + encrypt.dictGetValNF(nIndex, &oTemp); + DictToCDictObject(&oTemp, pEncryptDict, true, chKey); + oTemp.free(); + } + } + + if (!pEncryptDict->Get("Length")) + pEncryptDict->Add("Length", 40); + + encrypt.free(); + + if (pTrailerDict->dictLookup("ID", &ID) && ID.isArray() && ID.arrayGet(0, &ID1) && ID1.isString()) + DictToCDictObject(&ID1, pEncryptDict, true, "ID"); + ID.free(); ID1.free(); + + xref->onEncrypted(); + + pEncryptDict->SetRef(0, 0); + pEncryptDict->Fix(); + + pEncryptDict->SetPasswords(wsPassword, wsPassword); + if (!pEncryptDict->UpdateKey(nCryptAlgorithm)) + { + pagesRefObj.free(); + RELEASEOBJECT(pXref); + RELEASEOBJECT(pDRXref); + nError = 4; // Ошибка шифрования файла + return; + } + } + } + + // Применение редактирования для writer + bool bRes = pDoc->EditPdf(_wsDstFile, xref->getLastXRefPos(), xref->getNumObjects() + 1, pXref, pCatalog, pEncryptDict, nFormField); + if (bRes) + { + // Воспроизведение дерева страниц во writer + GetPageTree(xref, &pagesRefObj); + + if (pDR && pDRXref) + bRes = pDoc->EditResources(pDRXref, pDR); + } + pagesRefObj.free(); + if (!bRes) + nError = 5; // Ошибка применения редактирования +} +void CPdfEditor::Close() +{ + PDFDoc* pPDFDocument = pReader->GetPDFDocument(); + PdfWriter::CDocument* pDoc = pWriter->GetDocument(); + if (!pPDFDocument || !pDoc) + return; + XRef* xref = pPDFDocument->getXRef(); + if (!xref) + return; + + // Добавляем первый элемент в таблицу xref + // он должен иметь вид 0000000000 65535 f + PdfWriter::CXref* pXref = new PdfWriter::CXref(pDoc, 0, 65535); + if (!pXref) + return; + + PdfWriter::CDictObject* pTrailer = NULL; + Object* trailerDict = xref->getTrailerDict(); + if (trailerDict) + { + pTrailer = pXref->GetTrailer(); + + for (int nIndex = 0; nIndex < trailerDict->dictGetLength(); ++nIndex) + { + Object oTemp; + char* chKey = trailerDict->dictGetKey(nIndex); + trailerDict->dictGetValNF(nIndex, &oTemp); + DictToCDictObject(&oTemp, pTrailer, true, chKey); + oTemp.free(); + } + } + + Object info; + pPDFDocument->getDocInfo(&info); + PdfWriter::CXref* pInfoXref = NULL; + PdfWriter::CInfoDict* pInfoDict = NULL; + if (info.isDict()) + { + // Обновление Info + PdfWriter::CObjectBase* pInfo = pTrailer->Get("Info"); + pInfoXref = new PdfWriter::CXref(pDoc, pInfo ? pInfo->GetObjId() : 0); + if (!pInfoXref) + { + RELEASEOBJECT(pXref); + return; + } + pInfoDict = new PdfWriter::CInfoDict(); + if (!pInfoDict) + { + RELEASEOBJECT(pXref); + RELEASEOBJECT(pInfoXref); + return; + } + pInfoXref->Add(pInfoDict, pInfo ? pInfo->GetGenNo() : 0); + + for (int nIndex = 0; nIndex < info.dictGetLength(); ++nIndex) + { + Object oTemp; + char* chKey = info.dictGetKey(nIndex); + info.dictGetValNF(nIndex, &oTemp); + DictToCDictObject(&oTemp, pInfoDict, true, chKey); + oTemp.free(); + } + pInfoDict->SetTime(PdfWriter::InfoModaDate); + } + info.free(); + + if (!pWriter->EditClose() || !pDoc->AddToFile(pXref, pTrailer, pInfoXref, pInfoDict)) + { + RELEASEOBJECT(pXref); + return; + } + + std::wstring wsPath = pDoc->GetEditPdfPath(); + std::string sPathUtf8New = U_TO_UTF8(wsPath); + std::string sPathUtf8Old = U_TO_UTF8(wsSrcFile); + if (sPathUtf8Old == sPathUtf8New || NSSystemPath::NormalizePath(sPathUtf8Old) == NSSystemPath::NormalizePath(sPathUtf8New)) + { + GString* owner_pswd = NSStrings::CreateString(wsPassword); + GString* user_pswd = NSStrings::CreateString(wsPassword); + pPDFDocument->makeWritable(false, owner_pswd, user_pswd); + delete owner_pswd; + delete user_pswd; + + NSFile::CFileBinary oFile; + if (oFile.OpenFile(wsSrcFile)) + { + pReader->ChangeLength(oFile.GetFileSize()); + oFile.CloseFile(); + } + } + + pReader = NULL; + pWriter = NULL; + m_nEditPage = -1; +} +int CPdfEditor::GetError() +{ + return nError; +} +void CPdfEditor::GetPageTree(XRef* xref, Object* pPagesRefObj, PdfWriter::CPageTree* pPageParent) +{ + PdfWriter::CDocument* pDoc = pWriter->GetDocument(); + if (!pPagesRefObj || !xref || !pDoc) + return; + + Object pagesObj; + if (!pPagesRefObj->isRef() || !pPagesRefObj->fetch(xref, &pagesObj)->isDict("Pages")) + { + pagesObj.free(); + return; + } + + Ref topPagesRef = pPagesRefObj->getRef(); + PdfWriter::CXref* pXref = new PdfWriter::CXref(pDoc, topPagesRef.num); + if (!pXref) + { + pagesObj.free(); + return; + } + + PdfWriter::CPageTree* pPageT = new PdfWriter::CPageTree(); + if (!pPageT) + { + pagesObj.free(); + RELEASEOBJECT(pXref); + return; + } + pXref->Add(pPageT, topPagesRef.gen); + for (int nIndex = 0; nIndex < pagesObj.dictGetLength(); ++nIndex) + { + Object oTemp; + char* chKey = pagesObj.dictGetKey(nIndex); + if (strcmp("Resources", chKey) == 0) + { + if (pagesObj.dictGetVal(nIndex, &oTemp)->isDict()) + { + PdfWriter::CResourcesDict* pDict = new PdfWriter::CResourcesDict(NULL, true, false); + pPageT->Add("Resources", pDict); + for (int nIndex = 0; nIndex < oTemp.dictGetLength(); ++nIndex) + { + Object oRes; + char* chKey2 = oTemp.dictGetKey(nIndex); + if (strcmp("Font", chKey2) == 0 || strcmp("ExtGState", chKey2) == 0 || strcmp("XObject", chKey2) == 0 || strcmp("Shading", chKey2) == 0 || strcmp("Pattern", chKey2) == 0) + oTemp.dictGetVal(nIndex, &oRes); + else + oTemp.dictGetValNF(nIndex, &oRes); + DictToCDictObject(&oRes, pDict, false, chKey2); + oRes.free(); + } + + oTemp.free(); + continue; + } + else + { + oTemp.free(); + pagesObj.dictGetValNF(nIndex, &oTemp); + } + } + else if (strcmp("Parent", chKey) == 0 && pPageParent) + { + pPageT->Add("Parent", pPageParent); + continue; + } + else + pagesObj.dictGetValNF(nIndex, &oTemp); + DictToCDictObject(&oTemp, pPageT, false, chKey); + oTemp.free(); + } + pDoc->CreatePageTree(pXref, pPageT); + pPageT->Fix(); + + Object kidsArrObj; + if (!pagesObj.dictLookup("Kids", &kidsArrObj)->isArray()) + { + pagesObj.free(); + kidsArrObj.free(); + return; + } + pagesObj.free(); + + for (int i = 0, count = kidsArrObj.arrayGetLength(); i < count; ++i) + { + Object kidRefObj; + if (kidsArrObj.arrayGetNF(i, &kidRefObj)) + GetPageTree(xref, &kidRefObj, pPageT); + kidRefObj.free(); + } + kidsArrObj.free(); +} +bool CPdfEditor::EditPage(int nPageIndex, bool bSet) +{ + PDFDoc* pPDFDocument = pReader->GetPDFDocument(); + PdfWriter::CDocument* pDoc = pWriter->GetDocument(); + if (!pPDFDocument || !pDoc) + return false; + + PdfWriter::CPage* pEditPage = pDoc->GetEditPage(nPageIndex); + if (pEditPage) + { + if (bSet) + { + pDoc->SetCurPage(pEditPage); + pWriter->EditPage(pEditPage); + m_nEditPage = nPageIndex; + } + return true; + } + + XRef* xref = pPDFDocument->getXRef(); + Catalog* pCatalog = pPDFDocument->getCatalog(); + if (!xref || !pCatalog) + return false; + std::pair pPageRef = pDoc->GetPageRef(nPageIndex); + if (pPageRef.first == 0) + return false; + + // Получение объекта страницы + Object pageRefObj, pageObj; + pageRefObj.initRef(pPageRef.first, pPageRef.second); + if (!pageRefObj.fetch(xref, &pageObj) || !pageObj.isDict()) + { + pageObj.free(); + pageRefObj.free(); + return false; + } + pageRefObj.free(); + + // Воспроизведение словаря страницы из reader для writer + PdfWriter::CXref* pXref = new PdfWriter::CXref(pDoc, pPageRef.first); + if (!pXref) + { + pageObj.free(); + return false; + } + PdfWriter::CPage* pPage = new PdfWriter::CPage(pDoc); + if (!pPage) + { + pageObj.free(); + RELEASEOBJECT(pXref); + return false; + } + pXref->Add(pPage, pPageRef.second); + for (int nIndex = 0; nIndex < pageObj.dictGetLength(); ++nIndex) + { + Object oTemp; + char* chKey = pageObj.dictGetKey(nIndex); + if (strcmp("Resources", chKey) == 0) + { + if (pageObj.dictGetVal(nIndex, &oTemp)->isDict()) + { + PdfWriter::CResourcesDict* pDict = new PdfWriter::CResourcesDict(NULL, true, false); + pPage->Add("Resources", pDict); + for (int nIndex = 0; nIndex < oTemp.dictGetLength(); ++nIndex) + { + Object oRes; + char* chKey2 = oTemp.dictGetKey(nIndex); + if (strcmp("Font", chKey2) == 0 || strcmp("ExtGState", chKey2) == 0 || strcmp("XObject", chKey2) == 0 || strcmp("Shading", chKey2) == 0 || strcmp("Pattern", chKey2) == 0) + oTemp.dictGetVal(nIndex, &oRes); + else + oTemp.dictGetValNF(nIndex, &oRes); + DictToCDictObject(&oRes, pDict, false, chKey2); + oRes.free(); + } + + oTemp.free(); + continue; + } + else + { + oTemp.free(); + pageObj.dictGetValNF(nIndex, &oTemp); + } + } + else if (strcmp("Annots", chKey) == 0) + { + if (pageObj.dictGetVal(nIndex, &oTemp)->isArray()) + { + PdfWriter::CArrayObject* pArray = new PdfWriter::CArrayObject(); + pPage->Add("Annots", pArray); + for (int nIndex = 0; nIndex < oTemp.arrayGetLength(); ++nIndex) + { + Object oAnnot; + oTemp.arrayGetNF(nIndex, &oAnnot); + DictToCDictObject(&oAnnot, pArray, false, ""); + oAnnot.free(); + } + oTemp.free(); + continue; + } + else + { + oTemp.free(); + pageObj.dictGetValNF(nIndex, &oTemp); + } + } + else if (strcmp("Contents", chKey) == 0) + { + if (pageObj.dictGetVal(nIndex, &oTemp)->isArray()) + { + DictToCDictObject(&oTemp, pPage, true, chKey); + oTemp.free(); + continue; + } + else + { + oTemp.free(); + pageObj.dictGetValNF(nIndex, &oTemp); + } + } + else if (strcmp("Parent", chKey) == 0) + { + pageObj.dictGetValNF(nIndex, &oTemp); + } + else + pageObj.dictGetValNF(nIndex, &oTemp); + DictToCDictObject(&oTemp, pPage, true, chKey); + oTemp.free(); + } + pPage->Fix(); + double dCTM[6] = { 1, 0, 0, 1, 0, 0 }; + GetCTM(xref, &pageObj, dCTM); + pageObj.free(); + + // Применение редактирования страницы для writer + if (pDoc->EditPage(pXref, pPage, nPageIndex)) + { + if (bSet) + { + pWriter->EditPage(pPage); + m_nEditPage = nPageIndex; + } + pPage->StartTransform(dCTM[0], dCTM[1], dCTM[2], dCTM[3], dCTM[4], dCTM[5]); + pPage->SetStrokeColor(0, 0, 0); + pPage->SetFillColor(0, 0, 0); + pPage->SetExtGrState(pDoc->GetExtGState(255, 255)); + pPage->BeginText(); + pPage->SetCharSpace(0); + pPage->SetTextRenderingMode(PdfWriter::textrenderingmode_Fill); + pPage->SetHorizontalScalling(100); + pPage->EndText(); + return true; + } + + RELEASEOBJECT(pXref); + return false; +} +bool CPdfEditor::DeletePage(int nPageIndex) +{ + return pWriter->GetDocument()->DeletePage(nPageIndex); +} +bool CPdfEditor::AddPage(int nPageIndex) +{ + // Применение добавления страницы для writer + if (!pWriter->AddPage(nPageIndex)) + return false; + // По умолчанию выставляются размеры первой страницы, в дальнейшем размеры можно изменить + double dPageDpiX, dPageDpiY; + double dWidth, dHeight; + pReader->GetPageInfo(0, &dWidth, &dHeight, &dPageDpiX, &dPageDpiY); + + dWidth *= 25.4 / dPageDpiX; + dHeight *= 25.4 / dPageDpiY; + + pWriter->put_Width(dWidth); + pWriter->put_Height(dHeight); + return true; +} +bool CPdfEditor::EditAnnot(int nPageIndex, int nID) +{ + PDFDoc* pPDFDocument = pReader->GetPDFDocument(); + PdfWriter::CDocument* pDoc = pWriter->GetDocument(); + if (!pPDFDocument || !pDoc) + return false; + + XRef* xref = pPDFDocument->getXRef(); + std::pair pPageRef = pDoc->GetPageRef(nPageIndex); + if (!xref || pPageRef.first == 0) + return false; + + // Получение объекта аннотации + Object pageRefObj, pageObj, oAnnots; + pageRefObj.initRef(pPageRef.first, pPageRef.second); + if (!pageRefObj.fetch(xref, &pageObj)->isDict() || !pageObj.dictLookup("Annots", &oAnnots)->isArray()) + { + pageRefObj.free(); pageObj.free(); oAnnots.free(); + return false; + } + pageRefObj.free(); pageObj.free(); + + Object oAnnotRef, oAnnot, oType; + for (int i = 0; i < oAnnots.arrayGetLength(); ++i) + { + if (oAnnots.arrayGetNF(i, &oAnnotRef)->isRef() && oAnnotRef.getRefNum() == nID) + break; + oAnnotRef.free(); + } + oAnnots.free(); + if (!oAnnotRef.isRef() || !oAnnotRef.fetch(xref, &oAnnot)->isDict() || !oAnnot.dictLookup("Subtype", &oType)->isName()) + { + oAnnotRef.free(); oAnnot.free(); oType.free(); + return false; + } + + PdfWriter::CPage* pEditPage = pDoc->GetEditPage(nPageIndex); + if (!pEditPage) + { + pEditPage = pDoc->GetCurPage(); + EditPage(nPageIndex); + pDoc->SetCurPage(pEditPage); + pWriter->EditPage(pEditPage); + } + + // Воспроизведение словаря аннотации из reader для writer + PdfWriter::CXref* pXref = new PdfWriter::CXref(pDoc, oAnnotRef.getRefNum()); + if (!pXref) + { + oAnnotRef.free(); oAnnot.free(); oType.free(); + return false; + } + + bool bIsWidget = false; + PdfWriter::CAnnotation* pAnnot = NULL; + if (oType.isName("Text")) + pAnnot = new PdfWriter::CTextAnnotation(pXref); + else if (oType.isName("Ink")) + pAnnot = new PdfWriter::CInkAnnotation(pXref); + else if (oType.isName("Line")) + pAnnot = new PdfWriter::CLineAnnotation(pXref); + else if (oType.isName("Highlight") || oType.isName("Underline") || oType.isName("Squiggly") || oType.isName("StrikeOut")) + pAnnot = new PdfWriter::CTextMarkupAnnotation(pXref); + else if (oType.isName("Square") || oType.isName("Circle")) + pAnnot = new PdfWriter::CSquareCircleAnnotation(pXref); + else if (oType.isName("Polygon") || oType.isName("PolyLine")) + pAnnot = new PdfWriter::CPolygonLineAnnotation(pXref); + else if (oType.isName("FreeText")) + { + std::map mapFont = pReader->GetAnnotFonts(&oAnnotRef); + m_mFonts.insert(mapFont.begin(), mapFont.end()); + pAnnot = new PdfWriter::CFreeTextAnnotation(pXref); + } + else if (oType.isName("Caret")) + pAnnot = new PdfWriter::CCaretAnnotation(pXref); + else if (oType.isName("Stamp")) + pAnnot = new PdfWriter::CStampAnnotation(pXref); + else if (oType.isName("Popup")) + pAnnot = new PdfWriter::CPopupAnnotation(pXref); + else if (oType.isName("Widget")) + { + bIsWidget = true; + char* sName = NULL; + Object oFT; + if (oAnnot.dictLookup("FT", &oFT)->isName()) + sName = oFT.getName(); + + if (!sName) + { + Object oParent, oParent2; + oAnnot.dictLookup("Parent", &oParent); + while (oParent.isDict()) + { + if (oParent.dictLookup("FT", &oFT)->isName()) + { + sName = oFT.getName(); + break; + } + oFT.free(); + oParent.dictLookup("Parent", &oParent2); + oParent.free(); + oParent = oParent2; + } + oParent.free(); + } + + if (sName) + { + if (strcmp("Btn", sName) == 0) + { + bool bPushButton = false; + oFT.free(); + int nFf = 0; + if (oAnnot.dictLookup("Ff", &oFT)->isInt()) + nFf = oFT.getInt(); + if (!nFf) + { + Object oParent, oParent2; + oAnnot.dictLookup("Parent", &oParent); + while (oParent.isDict()) + { + if (oParent.dictLookup("Ff", &oFT)->isInt()) + { + nFf = oFT.getInt(); + break; + } + oFT.free(); + oParent.dictLookup("Parent", &oParent2); + oParent.free(); + oParent = oParent2; + } + oParent.free(); + } + + bPushButton = (bool)((nFf >> 16) & 1); + if (bPushButton) + pAnnot = new PdfWriter::CPushButtonWidget(pXref); + else + pAnnot = new PdfWriter::CCheckBoxWidget(pXref); + } + else if (strcmp("Tx", sName) == 0) + pAnnot = new PdfWriter::CTextWidget(pXref); + else if (strcmp("Ch", sName) == 0) + pAnnot = new PdfWriter::CChoiceWidget(pXref); + else if (strcmp("Sig", sName) == 0) + pAnnot = new PdfWriter::CSignatureWidget(pXref); + else + pAnnot = new PdfWriter::CWidgetAnnotation(pXref, PdfWriter::EAnnotType::AnnotWidget); + } + oFT.free(); + } + + if (!pAnnot) + { + oAnnotRef.free(); oAnnot.free(); oType.free(); + RELEASEOBJECT(pXref); + return false; + } + pXref->Add(pAnnot, oAnnotRef.getRefGen()); + + for (int nIndex = 0; nIndex < oAnnot.dictGetLength(); ++nIndex) + { + bool bUnicode = false; + char* chKey = oAnnot.dictGetKey(nIndex); + if (!strcmp("Popup", chKey)) + { + Object oPopupRef; + if (oAnnot.dictGetValNF(nIndex, &oPopupRef)->isRef() && EditAnnot(nPageIndex, oPopupRef.getRefNum())) + { + PdfWriter::CAnnotation* pPopup = pDoc->GetAnnot(oPopupRef.getRefNum()); + if (pPopup) + { + pAnnot->Add("Popup", pPopup); + pPopup->Add("Parent", pAnnot); + } + } + continue; + } + else if (!strcmp("Parent", chKey) && bIsWidget) + { + Object oParentRef; + oAnnot.dictGetValNF(nIndex, &oParentRef); + PdfWriter::CDictObject* pParent = GetWidgetParent(pPDFDocument, pDoc, &oParentRef); + + if (!pParent) + { + oParentRef.free(); + continue; + } + + ((PdfWriter::CWidgetAnnotation*)pAnnot)->SetParent(pParent); + PdfWriter::CArrayObject* pKids = dynamic_cast(pParent->Get("Kids")); + if (!pKids) + { + oParentRef.free(); + continue; + } + + for (int i = 0; i < pKids->GetCount(); ++i) + { + PdfWriter::CObjectBase* pKid = pKids->Get(i); + if (pKid->GetObjId() == oAnnotRef.getRefNum()) + { + pKids->Insert(pKid, pAnnot, true); + break; + } + } + oParentRef.free(); + } + else if (!strcmp("Opt", chKey)) + bUnicode = true; + Object oTemp; + oAnnot.dictGetValNF(nIndex, &oTemp); + DictToCDictObject(&oTemp, pAnnot, false, chKey, bUnicode); + oTemp.free(); + } + + if (oType.isName("Stamp")) + { + Object oAP, oAPN; + if (oAnnot.dictLookup("AP", &oAP)->isDict() && oAP.dictLookup("N", &oAPN)->isStream()) + { + Object oAPNRef; + oAP.dictLookupNF("N", &oAPNRef); + PdfWriter::CXref* pXRef = new PdfWriter::CXref(pDoc, oAPNRef.getRefNum()); + pDoc->EditXref(pXRef); + + PdfWriter::CDictObject* pAPN = new PdfWriter::CDictObject(); + pXRef->Add(pAPN, oAPNRef.getRefGen()); + ((PdfWriter::CStampAnnotation*)pAnnot)->SetAPStream(pAPN); + oAPNRef.free(); + + Object oTemp; + Dict* pODict = oAPN.streamGetDict(); + for (int nIndex = 0; nIndex < pODict->getLength(); ++nIndex) + { + char* chKey = pODict->getKey(nIndex); + pODict->getValNF(nIndex, &oTemp); + DictToCDictObject(&oTemp, pAPN, false, chKey); + oTemp.free(); + } + int nLength = 0; + if (pODict->lookup("Length", &oTemp)->isInt()) + nLength = oTemp.getInt(); + PdfWriter::CStream* pStream = new PdfWriter::CMemoryStream(nLength); + pAPN->SetStream(pStream); + pAPN->Add("Length", nLength); + Stream* pOStream = oAPN.getStream()->getUndecodedStream(); + pOStream->reset(); + for (int nI = 0; nI < nLength; ++nI) + pStream->WriteChar(pOStream->getChar()); + } + oAP.free(); oAPN.free(); + } + oAnnotRef.free(); oAnnot.free(); oType.free(); + + if (pDoc->EditAnnot(pXref, pAnnot, nID)) + return true; + + RELEASEOBJECT(pXref); + return false; +} +bool CPdfEditor::DeleteAnnot(int nID, Object* oAnnots) +{ + PDFDoc* pPDFDocument = pReader->GetPDFDocument(); + PdfWriter::CDocument* pDoc = pWriter->GetDocument(); + if (!pPDFDocument || !pDoc) + return false; + + XRef* xref = pPDFDocument->getXRef(); + bool bClear = false; + if (!oAnnots) + { + std::pair pPageRef = pDoc->GetPageRef(m_nEditPage); + if (pPageRef.first == 0) + return false; + + oAnnots = new Object(); + bClear = true; + + // Получение объекта аннотации + Object pageRefObj, pageObj; + pageRefObj.initRef(pPageRef.first, pPageRef.second); + if (!pageRefObj.fetch(xref, &pageObj)->isDict() || !pageObj.dictLookup("Annots", oAnnots)->isArray()) + { + pageRefObj.free(); pageObj.free(); oAnnots->free(); + RELEASEOBJECT(oAnnots); + return false; + } + pageRefObj.free(); pageObj.free(); + } + + bool bRes = false; + for (int i = 0; i < oAnnots->arrayGetLength(); ++i) + { + Object oAnnotRef, oAnnot; + if (oAnnots->arrayGetNF(i, &oAnnotRef)->isRef() && oAnnotRef.getRefNum() == nID) + { + bRes = pDoc->DeleteAnnot(oAnnotRef.getRefNum(), oAnnotRef.getRefGen()); + if (oAnnotRef.fetch(xref, &oAnnot)->isDict()) + { + Object oPopupRef; + if (oAnnot.dictLookupNF("Popup", &oPopupRef)->isRef()) + pDoc->DeleteAnnot(oPopupRef.getRefNum(), oPopupRef.getRefGen()); + oPopupRef.free(); + } + } + else if (oAnnots->arrayGet(i, &oAnnot)->isDict()) + { + Object oIRTRef; + if (oAnnot.dictLookupNF("IRT", &oIRTRef)->isRef() && oIRTRef.getRefNum() == nID) + DeleteAnnot(oAnnotRef.getRefNum(), oAnnots); + oIRTRef.free(); + } + oAnnotRef.free(); oAnnot.free(); + } + + if (bClear) + { + oAnnots->free(); + RELEASEOBJECT(oAnnots); + } + + return bRes; +} +bool CPdfEditor::EditWidgets(IAdvancedCommand* pCommand) +{ + CWidgetsInfo* pFieldInfo = (CWidgetsInfo*)pCommand; + PDFDoc* pPDFDocument = pReader->GetPDFDocument(); + PdfWriter::CDocument* pDoc = pWriter->GetDocument(); + + std::vector arrParents = pFieldInfo->GetParents(); + for (CWidgetsInfo::CParent* pParent : arrParents) + { + PdfWriter::CDictObject* pDParent = pDoc->GetParent(pParent->nID); + if (pDParent) + continue; + + Object oParentRef; + // TODO узнать gen родителя + oParentRef.initRef(pParent->nID, 0); + GetWidgetParent(pPDFDocument, pDoc, &oParentRef); + // TODO перевыставить детей + oParentRef.free(); + } + return true; +} +int CPdfEditor::GetPagesCount() +{ + return pWriter->GetDocument()->GetPagesCount(); +} +void CPdfEditor::GetPageInfo(int nPageIndex, double* pdWidth, double* pdHeight, double* pdDpiX, double* pdDpiY) +{ + PdfWriter::CPage* pPage = pWriter->GetDocument()->GetPage(nPageIndex); + if (!pPage) + return; + + int nRotate = pPage->GetRotate(); + if (nRotate % 180 == 0) + { + *pdWidth = pPage->GetWidth(); + *pdHeight = pPage->GetHeight(); + } + else + { + *pdWidth = pPage->GetHeight(); + *pdHeight = pPage->GetWidth(); + } + + *pdDpiX = 72.0; + *pdDpiY = 72.0; +} +int CPdfEditor::GetRotate(int nPageIndex) +{ + PdfWriter::CPage* pPage = pWriter->GetDocument()->GetPage(nPageIndex); + if (!pPage) + return 0; + return pPage->GetRotate(); +} +bool CPdfEditor::IsEditPage() +{ + return m_nEditPage >= 0; +} +void CPdfEditor::ClearPage() +{ + PDFDoc* pPDFDocument = pReader->GetPDFDocument(); + XRef* xref = pPDFDocument->getXRef(); + PdfWriter::CDocument* pDoc = pWriter->GetDocument(); + std::pair pPageRef = pDoc->GetPageRef(m_nEditPage); + + // Получение объекта страницы + Object pageRefObj, pageObj; + pageRefObj.initRef(pPageRef.first, pPageRef.second); + if (!pageRefObj.fetch(xref, &pageObj)->isDict()) + { + pageObj.free(); pageRefObj.free(); + return; + } + pageRefObj.free(); + + Object oAnnots; + // ВРЕМЕННО удаление Link аннотаций при редактировании + if (pageObj.dictLookup("Annots", &oAnnots)->isArray()) + { + for (int nIndex = 0; nIndex < oAnnots.arrayGetLength(); ++nIndex) + { + Object oAnnot, oSubtype, oAnnotRef; + if (oAnnots.arrayGet(nIndex, &oAnnot)->isDict("Annot") && oAnnot.dictLookup("Subtype", &oSubtype)->isName("Link")) + { + oAnnots.arrayGetNF(nIndex, &oAnnotRef); + DeleteAnnot(oAnnotRef.getRefNum(), &oAnnots); + } + oAnnot.free(); oSubtype.free(); oAnnotRef.free(); + } + } + pageObj.free(); + + pDoc->ClearPage(); +} +void CPdfEditor::AddShapeXML(const std::string& sXML) +{ + return pWriter->GetDocument()->AddShapeXML(sXML); +} +void CPdfEditor::EndMarkedContent() +{ + pWriter->GetDocument()->EndShapeXML(); +} +bool CPdfEditor::IsBase14(const std::wstring& wsFontName, bool& bBold, bool& bItalic, std::wstring& wsFontPath) +{ + std::map::iterator it = m_mFonts.find(wsFontName); + if (it != m_mFonts.end()) + wsFontPath = it->second; + if (wsFontPath.empty()) + { + std::map mFonts = pReader->GetFonts(); + std::map::iterator it2 = mFonts.find(wsFontName); + if (it2 != mFonts.end()) + wsFontPath = it2->second; + } + if (wsFontPath.empty()) + return false; + if (wsFontName == L"Helvetica") + return true; + if (wsFontName == L"Helvetica-Bold") + { + bBold = true; + return true; + } + if (wsFontName == L"Helvetica-Oblique") + { + bItalic = true; + return true; + } + if (wsFontName == L"Helvetice-BoldOblique") + { + bBold = true; + bItalic = true; + return true; + } + if (wsFontName == L"Courier") + return true; + if (wsFontName == L"Courier-Bold") + { + bBold = true; + return true; + } + if (wsFontName == L"Courier-Oblique") + { + bItalic = true; + return true; + } + if (wsFontName == L"Courier-BoldOblique") + { + bBold = true; + bItalic = true; + return true; + } + if (wsFontName == L"Times" || wsFontName == L"Times-Roman") + return true; + if (wsFontName == L"Times-Bold") + { + bBold = true; + return true; + } + if (wsFontName == L"Times-Oblique") + { + bItalic = true; + return true; + } + if (wsFontName == L"Times-BoldOblique") + { + bBold = true; + bItalic = true; + return true; + } + if (wsFontName == L"Symbol") + return true; + if (wsFontName == L"ZapfDingbats") + return true; + return false; +} diff --git a/PdfFile/PdfEditor.h b/PdfFile/PdfEditor.h new file mode 100644 index 00000000000..61e3b155139 --- /dev/null +++ b/PdfFile/PdfEditor.h @@ -0,0 +1,76 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#ifndef _PDF_EDITOR_H +#define _PDF_EDITOR_H + +#include "PdfWriter.h" +#include "PdfReader.h" + +HRESULT _ChangePassword(const std::wstring& wsPath, const std::wstring& wsPassword, CPdfReader* _pReader, CPdfWriter* _pWriter); + +class CPdfEditor +{ +public: + CPdfEditor(const std::wstring& _wsSrcFile, const std::wstring& _wsPassword, CPdfReader* _pReader, const std::wstring& _wsDstFile, CPdfWriter* _pWriter); + + int GetError(); + void Close(); + bool EditPage(int nPageIndex, bool bSet = true); + bool DeletePage(int nPageIndex); + bool AddPage(int nPageIndex); + bool EditAnnot(int nPageIndex, int nID); + bool DeleteAnnot(int nID, Object* oAnnots = NULL); + bool EditWidgets(IAdvancedCommand* pCommand); + int GetPagesCount(); + void GetPageInfo(int nPageIndex, double* pdWidth, double* pdHeight, double* pdDpiX, double* pdDpiY); + int GetRotate(int nPageIndex); + bool IsEditPage(); + void ClearPage(); + void AddShapeXML(const std::string& sXML); + void EndMarkedContent(); + bool IsBase14(const std::wstring& wsFontName, bool& bBold, bool& bItalic, std::wstring& wsFontPath); + +private: + void GetPageTree(XRef* xref, Object* pPagesRefObj, PdfWriter::CPageTree* pPageParent = NULL); + + std::wstring wsSrcFile; + std::wstring wsPassword; + std::map m_mFonts; + + CPdfReader* pReader; + CPdfWriter* pWriter; + + int nError; + int m_nEditPage; +}; + +#endif // _PDF_EDITOR_H diff --git a/PdfFile/PdfFile.cpp b/PdfFile/PdfFile.cpp index b47427117b1..a720c616440 100644 --- a/PdfFile/PdfFile.cpp +++ b/PdfFile/PdfFile.cpp @@ -34,132 +34,37 @@ #include "PdfReader.h" #include "../DesktopEditor/common/File.h" -#include "../HtmlRenderer/include/HTMLRendererText.h" +#include "../DesktopEditor/graphics/commands/DocInfo.h" #include "lib/xpdf/PDFDoc.h" #ifndef BUILDING_WASM_MODULE +#include "PdfEditor.h" #include "OnlineOfficeBinToPdf.h" -#include "../DesktopEditor/common/Path.h" -#include "../DesktopEditor/common/StringExt.h" -#include "SrcReader/Adaptors.h" -#include "lib/xpdf/AcroForm.h" -#include "lib/xpdf/TextString.h" - -#include "SrcWriter/Objects.h" #include "SrcWriter/Document.h" -#include "SrcWriter/Pages.h" -#include "SrcWriter/Catalog.h" -#include "SrcWriter/EncryptDictionary.h" -#include "SrcWriter/Info.h" -#include "SrcWriter/Annotation.h" - -#define AddToObject(oVal)\ -{\ - if (pObj->GetType() == PdfWriter::object_type_DICT)\ - ((PdfWriter::CDictObject*)pObj)->Add(sKey, oVal);\ - else if (pObj->GetType() == PdfWriter::object_type_ARRAY)\ - ((PdfWriter::CArrayObject*)pObj)->Add(oVal);\ -} +#include "Resources/BaseFonts.h" -void DictToCDictObject(Object* obj, PdfWriter::CObjectBase* pObj, bool bBinary, const std::string& sKey) +#else +class CPdfEditor { - Object oTemp; - switch (obj->getType()) - { - case objBool: - { - bool b = obj->getBool(); - AddToObject(b) - break; - } - case objInt: - { - AddToObject(obj->getInt()) - break; - } - case objReal: - { - AddToObject(obj->getReal()) - break; - } - case objString: - { - if (bBinary) - { - GString* str = obj->getString(); - int nLength = str->getLength(); - BYTE* arrId = new BYTE[nLength]; - for (int nIndex = 0; nIndex < nLength; ++nIndex) - arrId[nIndex] = str->getChar(nIndex); - AddToObject(new PdfWriter::CBinaryObject(arrId, nLength)); - RELEASEARRAYOBJECTS(arrId); - } - else - { - TextString* s = new TextString(obj->getString()); - std::string sValue = NSStringExt::CConverter::GetUtf8FromUTF32(s->getUnicode(), s->getLength()); - AddToObject(new PdfWriter::CStringObject(sValue.c_str())) - delete s; - } - break; - } - case objName: - { - AddToObject(obj->getName()) - break; - } - case objNull: - { - AddToObject(new PdfWriter::CNullObject()) - break; - } - case objArray: - { - PdfWriter::CArrayObject* pArray = new PdfWriter::CArrayObject(); - AddToObject(pArray) - - for (int nIndex = 0; nIndex < obj->arrayGetLength(); ++nIndex) - { - obj->arrayGetNF(nIndex, &oTemp); - DictToCDictObject(&oTemp, pArray, bBinary, ""); - oTemp.free(); - } - break; - } - case objDict: - { - PdfWriter::CDictObject* pDict = new PdfWriter::CDictObject(); - AddToObject(pDict); - - for (int nIndex = 0; nIndex < obj->dictGetLength(); ++nIndex) - { - char* chKey = obj->dictGetKey(nIndex); - obj->dictGetValNF(nIndex, &oTemp); - DictToCDictObject(&oTemp, pDict, bBinary, chKey); - oTemp.free(); - } - break; - } - case objRef: - { - PdfWriter::CObjectBase* pBase = new PdfWriter::CObjectBase(); - pBase->SetRef(obj->getRefNum(), obj->getRefGen()); - AddToObject(new PdfWriter::CProxyObject(pBase, true)) - break; - } - case objNone: - { - AddToObject("None") - break; - } - case objStream: - case objCmd: - case objError: - case objEOF: - break; - } -} +public: + int GetError() { return 0; } + void Close() {} + bool EditPage(int nPageIndex, bool bSet = true) { return false; } + bool DeletePage(int nPageIndex) { return false; } + bool AddPage(int nPageIndex) { return false; } + bool EditAnnot(int nPageIndex, int nID) { return false; } + bool DeleteAnnot(int nID, Object* oAnnots = NULL) { return false; } + bool EditWidgets(IAdvancedCommand* pCommand) { return false; } + int GetPagesCount() { return 0; } + void GetPageInfo(int nPageIndex, double* pdWidth, double* pdHeight, double* pdDpiX, double* pdDpiY) {} + int GetRotate(int nPageIndex) { return 0; } + bool IsEditPage() { return false; } + void ClearPage() {} + void AddShapeXML(const std::string& sXML) {} + void EndMarkedContent() {} + bool IsBase14(const std::wstring& wsFontName, bool& bBold, bool& bItalic, std::wstring& wsFontPath) { return false; } +}; #endif // BUILDING_WASM_MODULE class CPdfFile_Private @@ -171,80 +76,8 @@ class CPdfFile_Private NSFonts::IApplicationFonts* pAppFonts; CPdfReader* pReader; - CPdfWriter* pWriter; - LONG lClipMode; - bool bEdit; - bool bEditPage; - -#ifndef BUILDING_WASM_MODULE - void GetPageTree(XRef* xref, Object* pPagesRefObj) - { - PdfWriter::CDocument* pDoc = pWriter->m_pDocument; - if (!pPagesRefObj || !xref || !pDoc) - return; - - Object typeDict, pagesObj; - if (!pPagesRefObj->isRef() || !pPagesRefObj->fetch(xref, &pagesObj)->isDict()) - { - pagesObj.free(); - return; - } - if (pagesObj.dictLookup("Type", &typeDict)->isName() && !typeDict.isName("Pages")) - { - pagesObj.free(); - typeDict.free(); - return; - } - typeDict.free(); - - Ref topPagesRef = pPagesRefObj->getRef(); - - PdfWriter::CXref* pXref = new PdfWriter::CXref(pDoc, topPagesRef.num); - if (!pXref) - { - pagesObj.free(); - return; - } - - PdfWriter::CPageTree* pPageT = new PdfWriter::CPageTree(); - if (!pPageT) - { - pagesObj.free(); - RELEASEOBJECT(pXref); - return; - } - pXref->Add(pPageT, topPagesRef.gen); - for (int nIndex = 0; nIndex < pagesObj.dictGetLength(); ++nIndex) - { - Object oTemp; - char* chKey = pagesObj.dictGetKey(nIndex); - pagesObj.dictGetValNF(nIndex, &oTemp); - DictToCDictObject(&oTemp, pPageT, false, chKey); - oTemp.free(); - } - pDoc->CreatePageTree(pXref, pPageT); - pPageT->Fix(); - - Object kidsArrObj; - if (!pagesObj.dictLookup("Kids", &kidsArrObj)->isArray()) - { - pagesObj.free(); - kidsArrObj.free(); - return; - } - pagesObj.free(); - - for (int i = 0, count = kidsArrObj.arrayGetLength(); i < count; ++i) - { - Object kidRefObj; - if (kidsArrObj.arrayGetNF(i, &kidRefObj)) - GetPageTree(xref, &kidRefObj); - kidRefObj.free(); - } - kidsArrObj.free(); - } -#endif + CPdfEditor* pEditor; }; // ------------------------------------------------------------------------ @@ -256,14 +89,14 @@ CPdfFile::CPdfFile(NSFonts::IApplicationFonts* pAppFonts) m_pInternal->pAppFonts = pAppFonts; m_pInternal->pWriter = NULL; m_pInternal->pReader = NULL; - m_pInternal->wsPassword = L""; - m_pInternal->bEdit = false; - m_pInternal->bEditPage = false; + m_pInternal->pEditor = NULL; } CPdfFile::~CPdfFile() { RELEASEOBJECT(m_pInternal->pWriter); RELEASEOBJECT(m_pInternal->pReader); + RELEASEOBJECT(m_pInternal->pEditor); + RELEASEOBJECT(m_pInternal); } NSFonts::IFontManager* CPdfFile::GetFontManager() { @@ -274,109 +107,10 @@ NSFonts::IFontManager* CPdfFile::GetFontManager() void CPdfFile::Close() { - if (!m_pInternal->bEdit) - { - if (m_pInternal->pReader) - m_pInternal->pReader->Close(); - return; - } -#ifndef BUILDING_WASM_MODULE - if (!m_pInternal->pWriter || !m_pInternal->pReader) - return; - PDFDoc* pPDFDocument = m_pInternal->pReader->GetPDFDocument(); - PdfWriter::CDocument* pDoc = m_pInternal->pWriter->m_pDocument; - if (!pPDFDocument || !pDoc) - return; - - XRef* xref = pPDFDocument->getXRef(); - if (!xref) - return; - - // Добавляем первый элемент в таблицу xref - // он должен иметь вид 0000000000 65535 f - PdfWriter::CXref* pXref = new PdfWriter::CXref(pDoc, 0, 65535); - if (!pXref) - return; - - PdfWriter::CDictObject* pTrailer = NULL; - Object* trailerDict = xref->getTrailerDict(); - if (trailerDict) - { - pTrailer = pXref->GetTrailer(); - - for (int nIndex = 0; nIndex < trailerDict->dictGetLength(); ++nIndex) - { - Object oTemp; - char* chKey = trailerDict->dictGetKey(nIndex); - trailerDict->dictGetValNF(nIndex, &oTemp); - DictToCDictObject(&oTemp, pTrailer, true, chKey); - oTemp.free(); - } - } - - Object info; - pPDFDocument->getDocInfo(&info); - PdfWriter::CXref* pInfoXref = NULL; - PdfWriter::CInfoDict* pInfoDict = NULL; - if (info.isDict()) - { - // Обновление Info - PdfWriter::CObjectBase* pInfo = pTrailer->Get("Info"); - pInfoXref = new PdfWriter::CXref(pDoc, pInfo ? pInfo->GetObjId() : 0); - if (!pInfoXref) - { - RELEASEOBJECT(pXref); - return; - } - pInfoDict = new PdfWriter::CInfoDict(); - if (!pInfoDict) - { - RELEASEOBJECT(pXref); - RELEASEOBJECT(pInfoXref); - return; - } - pInfoXref->Add(pInfoDict, pInfo ? pInfo->GetGenNo() : 0); - - for (int nIndex = 0; nIndex < info.dictGetLength(); ++nIndex) - { - Object oTemp; - char* chKey = info.dictGetKey(nIndex); - info.dictGetValNF(nIndex, &oTemp); - DictToCDictObject(&oTemp, pInfoDict, true, chKey); - oTemp.free(); - } - pInfoDict->SetTime(PdfWriter::InfoModaDate); - } - info.free(); - - if (!m_pInternal->pWriter->EditClose() || !pDoc->AddToFile(pXref, pTrailer, pInfoXref, pInfoDict)) - { - RELEASEOBJECT(pXref); - return; - } - - std::wstring wsPath = pDoc->GetEditPdfPath(); - std::string sPathUtf8New = U_TO_UTF8(wsPath); - std::string sPathUtf8Old = U_TO_UTF8(m_pInternal->wsSrcFile); - if (sPathUtf8Old == sPathUtf8New || NSSystemPath::NormalizePath(sPathUtf8Old) == NSSystemPath::NormalizePath(sPathUtf8New)) - { - GString* owner_pswd = NSStrings::CreateString(m_pInternal->wsPassword); - GString* user_pswd = NSStrings::CreateString(m_pInternal->wsPassword); - pPDFDocument->makeWritable(false, owner_pswd, user_pswd); - delete owner_pswd; - delete user_pswd; - - NSFile::CFileBinary oFile; - if (oFile.OpenFile(m_pInternal->wsSrcFile)) - { - m_pInternal->pReader->ChangeLength(oFile.GetFileSize()); - oFile.CloseFile(); - } - } - - m_pInternal->bEdit = false; - m_pInternal->bEditPage = false; -#endif + if (m_pInternal->pEditor) + m_pInternal->pEditor->Close(); + else if (m_pInternal->pReader) + m_pInternal->pReader->Close(); } void CPdfFile::Sign(const double& dX, const double& dY, const double& dW, const double& dH, const std::wstring& wsPicturePath, ICertificate* pCertificate) { @@ -410,560 +144,33 @@ bool CPdfFile::EditPdf(const std::wstring& wsDstFile) RELEASEOBJECT(m_pInternal->pWriter); m_pInternal->pWriter = new CPdfWriter(m_pInternal->pAppFonts, false, this); - PDFDoc* pPDFDocument = m_pInternal->pReader->GetPDFDocument(); - if (!pPDFDocument) - return false; - - // Если результат редактирования будет сохранен в тот же файл, что открыт для чтения, то файл необходимо сделать редактируемым - std::string sPathUtf8New = U_TO_UTF8(wsDstFile); - std::string sPathUtf8Old = U_TO_UTF8(m_pInternal->wsSrcFile); - if (sPathUtf8Old == sPathUtf8New || NSSystemPath::NormalizePath(sPathUtf8Old) == NSSystemPath::NormalizePath(sPathUtf8New)) - { - GString* owner_pswd = NSStrings::CreateString(m_pInternal->wsPassword); - GString* user_pswd = NSStrings::CreateString(m_pInternal->wsPassword); - GBool bRes = pPDFDocument->makeWritable(true, owner_pswd, user_pswd); - delete owner_pswd; - delete user_pswd; - if (!bRes) - return false; - } - else - { - if (!NSFile::CFileBinary::Copy(m_pInternal->wsSrcFile, wsDstFile)) - return false; - NSFile::CFileBinary oFile; - if (!oFile.OpenFile(wsDstFile, true)) - return false; - oFile.CloseFile(); - } - - XRef* xref = pPDFDocument->getXRef(); - PdfWriter::CDocument* pDoc = m_pInternal->pWriter->m_pDocument; - if (!xref || !pDoc) - return false; - - // Получение каталога и дерева страниц из reader - Object catDict, catRefObj, pagesRefObj; - if (!xref->getCatalog(&catDict) || !catDict.isDict() || !catDict.dictLookupNF("Pages", &pagesRefObj)) - { - pagesRefObj.free(); - catDict.free(); - return false; - } - Object* trailer = xref->getTrailerDict(); - if (!trailer || !trailer->isDict() || !trailer->dictLookupNF("Root", &catRefObj) || !catRefObj.isRef()) - { - pagesRefObj.free(); - catDict.free(); - catRefObj.free(); - return false; - } - Ref catRef = catRefObj.getRef(); - catRefObj.free(); - - // Создание каталога для writer - PdfWriter::CXref* pXref = new PdfWriter::CXref(pDoc, catRef.num); - if (!pXref) - { - pagesRefObj.free(); - catDict.free(); - return false; - } - PdfWriter::CCatalog* pCatalog = new PdfWriter::CCatalog(); - if (!pCatalog) - { - pagesRefObj.free(); - catDict.free(); - RELEASEOBJECT(pXref); - return false; - } - pXref->Add(pCatalog, catRef.gen); - for (int nIndex = 0; nIndex < catDict.dictGetLength(); ++nIndex) - { - Object oTemp; - char* chKey = catDict.dictGetKey(nIndex); - catDict.dictGetValNF(nIndex, &oTemp); - DictToCDictObject(&oTemp, pCatalog, false, chKey); - oTemp.free(); - } - catDict.free(); - - // Проверка уникальности имён текущих цифровых подписей pdf - unsigned int nFormField = 0; - AcroForm* form = pPDFDocument->getCatalog()->getForm(); - if (form) - { - nFormField = form->getNumFields() + 1; - std::wstring sSig = L"Sig" + std::to_wstring(nFormField); - int i = 0, nFormFields = form->getNumFields(); - while (i < nFormFields) - { - int nLength; - Unicode* uName = form->getField(i)->getName(&nLength); - std::wstring sName = NSStringExt::CConverter::GetUnicodeFromUTF32(uName, nLength); - RELEASEMEM(uName); - if (sName == sSig) - { - i = 0; - nFormField++; - sSig = L"Sig" + std::to_wstring(nFormField); - } - else - i++; - } - nFormField--; - } - - // Получение шифрования из reader и применения для writer - int nCryptAlgorithm = -1; - PdfWriter::CEncryptDict* pEncryptDict = NULL; - if (xref->isEncrypted()) - { - CryptAlgorithm encAlgorithm; - GBool ownerPasswordOk; - int permFlags, keyLength, encVersion; - xref->getEncryption(&permFlags, &ownerPasswordOk, &keyLength, &encVersion, &encAlgorithm); - nCryptAlgorithm = encAlgorithm; - - Object* pTrailerDict = xref->getTrailerDict(); - if (pTrailerDict) - { - pEncryptDict = new PdfWriter::CEncryptDict(); - - Object encrypt, ID, ID1; - if (pTrailerDict->dictLookup("Encrypt", &encrypt) && encrypt.isDict()) - { - for (int nIndex = 0; nIndex < encrypt.dictGetLength(); ++nIndex) - { - Object oTemp; - char* chKey = encrypt.dictGetKey(nIndex); - encrypt.dictGetValNF(nIndex, &oTemp); - DictToCDictObject(&oTemp, pEncryptDict, true, chKey); - oTemp.free(); - } - - pEncryptDict->SetRef(0, 0); - pEncryptDict->Fix(); - } - encrypt.free(); - - if (pTrailerDict->dictLookup("ID", &ID) && ID.isArray() && ID.arrayGet(0, &ID1) && ID1.isString()) - { - for (int nIndex = 0; nIndex < ID1.dictGetLength(); ++nIndex) - { - Object oTemp; - char* chKey = ID1.dictGetKey(nIndex); - ID1.dictGetValNF(nIndex, &oTemp); - DictToCDictObject(&oTemp, pEncryptDict, true, chKey); - oTemp.free(); - } - } - - pEncryptDict->SetRef(0, 0); - pEncryptDict->Fix(); - pEncryptDict->SetPasswords(m_pInternal->wsPassword, m_pInternal->wsPassword); - pEncryptDict->UpdateKey(nCryptAlgorithm); - - ID.free(); - ID1.free(); - } - } - - // Применение редактирования для writer - bool bRes = pDoc->EditPdf(wsDstFile, xref->getLastXRefPos(), xref->getNumObjects(), pXref, pCatalog, pEncryptDict, nFormField); - if (bRes) - { - // Воспроизведение дерева страниц во writer - m_pInternal->GetPageTree(xref, &pagesRefObj); - m_pInternal->bEdit = true; - } - pagesRefObj.free(); - return bRes; + RELEASEOBJECT(m_pInternal->pEditor); + m_pInternal->pEditor = new CPdfEditor(m_pInternal->wsSrcFile, m_pInternal->wsPassword, m_pInternal->pReader, wsDstFile, m_pInternal->pWriter); + return m_pInternal->pEditor->GetError() == 0; } bool CPdfFile::EditPage(int nPageIndex) { - // Проверка режима редактирования - if (!m_pInternal->pWriter || !m_pInternal->pReader) - return false; - PDFDoc* pPDFDocument = m_pInternal->pReader->GetPDFDocument(); - PdfWriter::CDocument* pDoc = m_pInternal->pWriter->m_pDocument; - if (!pPDFDocument || !pDoc || !m_pInternal->bEdit) - return false; - - PdfWriter::CPage* pEditPage = pDoc->GetEditPage(nPageIndex); - if (pEditPage) - { - pDoc->SetCurPage(pEditPage); - m_pInternal->pWriter->EditPage(pEditPage); - return true; - } - - XRef* xref = pPDFDocument->getXRef(); - Catalog* pCatalog = pPDFDocument->getCatalog(); - if (!xref || !pCatalog) - return false; - std::pair pPageRef = pDoc->GetPageRef(nPageIndex); - if (pPageRef.first == 0) - return false; - - // Получение объекта страницы - Object pageRefObj, pageObj; - pageRefObj.initRef(pPageRef.first, pPageRef.second); - if (!pageRefObj.fetch(xref, &pageObj) || !pageObj.isDict()) - { - pageObj.free(); - pageRefObj.free(); - return false; - } - pageRefObj.free(); - - // Воспроизведение словаря страницы из reader для writer - PdfWriter::CXref* pXref = new PdfWriter::CXref(pDoc, pPageRef.first); - if (!pXref) - { - pageObj.free(); - return false; - } - PdfWriter::CPage* pPage = new PdfWriter::CPage(pDoc); - if (!pPage) - { - pageObj.free(); - RELEASEOBJECT(pXref); + if (!m_pInternal->pEditor) return false; - } - pXref->Add(pPage, pPageRef.second); - for (int nIndex = 0; nIndex < pageObj.dictGetLength(); ++nIndex) - { - Object oTemp; - char* chKey = pageObj.dictGetKey(nIndex); - if (strcmp("Resources", chKey) == 0 || strcmp("AcroForm", chKey) == 0 || strcmp("Annots", chKey) == 0) - pageObj.dictGetVal(nIndex, &oTemp); - else - pageObj.dictGetValNF(nIndex, &oTemp); - DictToCDictObject(&oTemp, pPage, true, chKey); - oTemp.free(); - } - pPage->Fix(); - pageObj.free(); - - // Применение редактирования страницы для writer - m_pInternal->bEditPage = true; - if (m_pInternal->pWriter->EditPage(pPage) && pDoc->EditPage(pXref, pPage, nPageIndex)) - return true; - - RELEASEOBJECT(pXref); - return false; + return m_pInternal->pEditor->EditPage(nPageIndex); } bool CPdfFile::DeletePage(int nPageIndex) { - // Проверка режима редактирования - if (!m_pInternal->pWriter || !m_pInternal->pWriter->m_pDocument || !m_pInternal->bEdit) + if (!m_pInternal->pEditor) return false; - // Применение удаления страницы для writer - return m_pInternal->pWriter->m_pDocument->DeletePage(nPageIndex); + return m_pInternal->pEditor->DeletePage(nPageIndex); } bool CPdfFile::AddPage(int nPageIndex) { - // Проверка режима редактирования - if (!m_pInternal->pWriter || !m_pInternal->bEdit) - return false; - // Применение добавления страницы для writer - bool bRes = m_pInternal->pWriter->AddPage(nPageIndex); - // По умолчанию выставляются размеры первой страницы, в дальнейшем размеры можно изменить - if (bRes) - { - double dPageDpiX, dPageDpiY; - double dWidth, dHeight; - m_pInternal->pReader->GetPageInfo(0, &dWidth, &dHeight, &dPageDpiX, &dPageDpiY); - - dWidth *= 25.4 / dPageDpiX; - dHeight *= 25.4 / dPageDpiY; - - m_pInternal->pWriter->put_Width(dWidth); - m_pInternal->pWriter->put_Height(dHeight); - } - return bRes; -} -PdfWriter::CDictObject* GetWidgetParent(PDFDoc* pdfDoc, PdfWriter::CDocument* pDoc, Object* pParentRef) -{ - PdfWriter::CDictObject* pParent = NULL; - - if (!pParentRef || !pParentRef->isRef() || !pdfDoc) - return pParent; - XRef* xref = pdfDoc->getXRef(); - Object oParent; - if (!pParentRef->fetch(xref, &oParent)->isDict()) - { - oParent.free(); - return pParent; - } - - PdfWriter::CXref* pXref = new PdfWriter::CXref(pDoc, pParentRef->getRefNum()); - pParent = new PdfWriter::CDictObject(); - pXref->Add(pParent, pParentRef->getRefGen()); - if (!pDoc->EditParent(pXref, pParent, pParentRef->getRefNum())) - { - RELEASEOBJECT(pXref); - oParent.free(); - return NULL; - } - - for (int i = 0; i < oParent.dictGetLength(); ++i) - { - char* chKey = oParent.dictGetKey(i); - if (strcmp("Parent", chKey) == 0) - { - Object oParentRef; - oParent.dictGetValNF(i, &oParentRef); - PdfWriter::CDictObject* pParent2 = GetWidgetParent(pdfDoc, pDoc, &oParentRef); - if (pParent2) - { - pParent->Add("Parent", pParent2); - oParentRef.free(); - continue; - } - oParentRef.free(); - } - Object oTemp; - oParent.dictGetValNF(i, &oTemp); - DictToCDictObject(&oTemp, pParent, false, chKey); - oTemp.free(); - } - - oParent.free(); - - return pParent; -} -bool CPdfFile::EditAnnot(int nPageIndex, int nID) -{ - // Проверка режима редактирования - if (!m_pInternal->pWriter || !m_pInternal->bEdit) - return false; - - PDFDoc* pPDFDocument = m_pInternal->pReader->GetPDFDocument(); - PdfWriter::CDocument* pDoc = m_pInternal->pWriter->m_pDocument; - if (!pPDFDocument || !pDoc || !m_pInternal->bEdit) - return false; - - PdfWriter::CPage* pEditPage = pDoc->GetEditPage(nPageIndex); - if (!pEditPage) - { - pEditPage = pDoc->GetCurPage(); - EditPage(nPageIndex); - pDoc->SetCurPage(pEditPage); - m_pInternal->pWriter->EditPage(pEditPage); - } - - XRef* xref = pPDFDocument->getXRef(); - std::pair pPageRef = pDoc->GetPageRef(nPageIndex); - if (!xref || pPageRef.first == 0) - return false; - - // Получение объекта аннотации - Object pageRefObj, pageObj, oAnnots; - pageRefObj.initRef(pPageRef.first, pPageRef.second); - if (!pageRefObj.fetch(xref, &pageObj)->isDict() || !pageObj.dictLookup("Annots", &oAnnots)->isArray()) - { - pageRefObj.free(); pageObj.free(); oAnnots.free(); - return false; - } - pageRefObj.free(); pageObj.free(); - - Object oAnnotRef, oAnnot, oType; - for (int i = 0; i < oAnnots.arrayGetLength(); ++i) - { - if (oAnnots.arrayGetNF(i, &oAnnotRef)->isRef() && oAnnotRef.getRefNum() == nID) - break; - oAnnotRef.free(); - } - oAnnots.free(); - if (!oAnnotRef.isRef() || !oAnnotRef.fetch(xref, &oAnnot)->isDict() || !oAnnot.dictLookup("Subtype", &oType)->isName()) - { - oAnnotRef.free(); oAnnot.free(); oType.free(); - return false; - } - - // Воспроизведение словаря аннотации из reader для writer - PdfWriter::CXref* pXref = new PdfWriter::CXref(pDoc, oAnnotRef.getRefNum()); - if (!pXref) - { - oAnnotRef.free(); oAnnot.free(); oType.free(); + if (!m_pInternal->pEditor) return false; - } - - bool bIsWidget = false; - PdfWriter::CAnnotation* pAnnot = NULL; - if (oType.isName("Text")) - pAnnot = new PdfWriter::CTextAnnotation(pXref); - else if (oType.isName("Ink")) - pAnnot = new PdfWriter::CInkAnnotation(pXref); - else if (oType.isName("Line")) - pAnnot = new PdfWriter::CLineAnnotation(pXref); - else if (oType.isName("Highlight") || oType.isName("Underline") || oType.isName("Squiggly") || oType.isName("StrikeOut")) - pAnnot = new PdfWriter::CTextMarkupAnnotation(pXref); - else if (oType.isName("Square") || oType.isName("Circle")) - pAnnot = new PdfWriter::CSquareCircleAnnotation(pXref); - else if (oType.isName("Polygon") || oType.isName("PolyLine")) - pAnnot = new PdfWriter::CPolygonLineAnnotation(pXref); - else if (oType.isName("FreeText")) - pAnnot = new PdfWriter::CFreeTextAnnotation(pXref); - else if (oType.isName("Caret")) - pAnnot = new PdfWriter::CCaretAnnotation(pXref); - else if (oType.isName("Popup")) - pAnnot = new PdfWriter::CPopupAnnotation(pXref); - else if (oType.isName("Widget")) - { - bIsWidget = true; - char* sName = NULL; - Object oFT; - if (oAnnot.dictLookup("FT", &oFT)->isName()) - sName = oFT.getName(); - - if (!sName) - { - Object oParent, oParent2; - oAnnot.dictLookup("Parent", &oParent); - while (oParent.isDict()) - { - if (oParent.dictLookup("FT", &oFT)->isName()) - { - sName = oFT.getName(); - break; - } - oFT.free(); - oParent.dictLookup("Parent", &oParent2); - oParent.free(); - oParent = oParent2; - } - oParent.free(); - } - - if (sName) - { - if (strcmp("Btn", sName) == 0) - pAnnot = new PdfWriter::CButtonWidget(pXref); - else if (strcmp("Tx", sName) == 0) - pAnnot = new PdfWriter::CTextWidget(pXref); - else if (strcmp("Ch", sName) == 0) - pAnnot = new PdfWriter::CChoiceWidget(pXref); - else if (strcmp("Sig", sName) == 0) - pAnnot = new PdfWriter::CSignatureWidget(pXref); - else - pAnnot = new PdfWriter::CWidgetAnnotation(pXref, PdfWriter::EAnnotType::AnnotWidget); - } - oFT.free(); - } - oType.free(); - - if (!pAnnot) - { - oAnnotRef.free(); oAnnot.free(); - RELEASEOBJECT(pXref); - return false; - } - pXref->Add(pAnnot, oAnnotRef.getRefGen()); - - for (int nIndex = 0; nIndex < oAnnot.dictGetLength(); ++nIndex) - { - char* chKey = oAnnot.dictGetKey(nIndex); - if (strcmp("AP", chKey) == 0) - continue; - if (strcmp("Popup", chKey) == 0) - { - Object oPopupRef; - if (oAnnot.dictGetValNF(nIndex, &oPopupRef)->isRef() && EditAnnot(nPageIndex, oPopupRef.getRefNum())) - { - PdfWriter::CAnnotation* pPopup = pDoc->GetAnnot(oPopupRef.getRefNum()); - if (pPopup) - { - pAnnot->Add("Popup", pPopup); - pPopup->Add("Parent", pAnnot); - } - } - continue; - } - if (strcmp("Parent", chKey) == 0 && bIsWidget) - { - Object oParentRef; - oAnnot.dictGetValNF(nIndex, &oParentRef); - PdfWriter::CDictObject* pParent = GetWidgetParent(pPDFDocument, pDoc, &oParentRef); - - if (pParent) - { - ((PdfWriter::CWidgetAnnotation*)pAnnot)->SetParent(pParent); - oParentRef.free(); - continue; - } - oParentRef.free(); - } - Object oTemp; - oAnnot.dictGetValNF(nIndex, &oTemp); - DictToCDictObject(&oTemp, pAnnot, false, chKey); - oTemp.free(); - } - oAnnotRef.free(); oAnnot.free(); - - if (pDoc->EditAnnot(pXref, pAnnot, nID)) - return true; - - RELEASEOBJECT(pXref); - return false; + return m_pInternal->pEditor->AddPage(nPageIndex); } -bool CPdfFile::DeleteAnnot(int nID) +HRESULT CPdfFile::ChangePassword(const std::wstring& wsPath, const std::wstring& wsPassword) { - // Проверка режима редактирования - if (!m_pInternal->pWriter || !m_pInternal->pWriter->m_pDocument || !m_pInternal->bEdit) - return false; - - PDFDoc* pPDFDocument = m_pInternal->pReader->GetPDFDocument(); - PdfWriter::CDocument* pDoc = m_pInternal->pWriter->m_pDocument; - if (!pPDFDocument || !pDoc || !m_pInternal->bEdit) - return false; - - XRef* xref = pPDFDocument->getXRef(); - std::pair pPageRef; - pPageRef.first = pDoc->GetCurPage()->GetObjId(); - pPageRef.second = pDoc->GetCurPage()->GetGenNo(); - if (!xref || pPageRef.first == 0) - return false; - - // Получение объекта аннотации - Object pageRefObj, pageObj, oAnnots; - pageRefObj.initRef(pPageRef.first, pPageRef.second); - if (!pageRefObj.fetch(xref, &pageObj)->isDict() || !pageObj.dictLookup("Annots", &oAnnots)->isArray()) - { - pageRefObj.free(); pageObj.free(); oAnnots.free(); - return false; - } - pageRefObj.free(); pageObj.free(); - - bool bRes = false; - for (int i = 0; i < oAnnots.arrayGetLength(); ++i) - { - Object oAnnotRef, oAnnot; - if (oAnnots.arrayGetNF(i, &oAnnotRef)->isRef() && oAnnotRef.getRefNum() == nID) - { - bRes = m_pInternal->pWriter->m_pDocument->DeleteAnnot(oAnnotRef.getRefNum(), oAnnotRef.getRefGen()); - if (oAnnotRef.fetch(xref, &oAnnot)->isDict()) - { - Object oPopupRef; - if (oAnnot.dictLookupNF("Popup", &oPopupRef)->isRef()) - m_pInternal->pWriter->m_pDocument->DeleteAnnot(oPopupRef.getRefNum(), oPopupRef.getRefGen()); - oPopupRef.free(); - } - } - else if (oAnnots.arrayGet(i, &oAnnot)->isDict()) - { - Object oIRTRef; - if (oAnnot.dictLookupNF("IRT", &oIRTRef)->isRef() && oIRTRef.getRefNum() == nID) - DeleteAnnot(oAnnotRef.getRefNum()); - oIRTRef.free(); - } - oAnnotRef.free(); oAnnot.free(); - } - oAnnots.free(); - - return bRes; + RELEASEOBJECT(m_pInternal->pWriter); + m_pInternal->pWriter = new CPdfWriter(m_pInternal->pAppFonts, false, this, false); + return _ChangePassword(wsPath, wsPassword, m_pInternal->pReader, m_pInternal->pWriter); } #endif // BUILDING_WASM_MODULE @@ -1007,6 +214,92 @@ void CPdfFile::ToXml(const std::wstring& sFile, bool bSaveStreams) m_pInternal->pReader->ToXml(sFile, bSaveStreams); } +bool CPdfFile::GetMetaData(const std::wstring& sFile, const std::wstring& sMetaName, BYTE** pMetaData, DWORD& nMetaLength) +{ + NSFile::CFileBinary oFile; + if (!oFile.OpenFile(sFile)) + return false; + + int nBufferSize = 4096; + BYTE* pBuffer = new BYTE[nBufferSize]; + if (!pBuffer) + { + oFile.CloseFile(); + return false; + } + + DWORD nReadBytes = 0; + if (!oFile.ReadFile(pBuffer, nBufferSize, nReadBytes)) + { + RELEASEARRAYOBJECTS(pBuffer); + oFile.CloseFile(); + return false; + } + oFile.CloseFile(); + pBuffer[nReadBytes - 1] = '\0'; + + char* pFirst = strstr((char*)pBuffer, "%\315\312\322\251\015"); + + if (!pFirst || pFirst - (char*)pBuffer + 6 >= nReadBytes) + { + RELEASEARRAYOBJECTS(pBuffer); + return false; + } + pFirst += 6; + + if (strncmp(pFirst, "1 0 obj\012<<\012", 11) != 0 || pFirst - (char*)pBuffer + 11 >= nReadBytes) + { + RELEASEARRAYOBJECTS(pBuffer); + return false; + } + pFirst += 11; + + std::string sMeta = U_TO_UTF8(sMetaName); + char* pStream = strstr(pFirst, "stream\015\012"); + char* pMeta = strstr(pFirst, sMeta.c_str()); + if (!pStream || !pMeta || pStream < pMeta) + { + RELEASEARRAYOBJECTS(pBuffer); + return false; + } + pStream += 8; + int nStreamBegin = (int)(pStream - (char*)pBuffer); + pMeta += sMeta.length() + 3; + + char* pMetaLast = strstr(pMeta, " "); + if (!pMetaLast) + { + RELEASEARRAYOBJECTS(pBuffer); + return false; + } + std::string sMetaOffset = std::string(pMeta, pMetaLast - pMeta); + int nMetaOffset = std::stoi(sMetaOffset); + + pMeta = pMetaLast + 1; + pMetaLast = strstr(pMeta, " "); + if (!pMetaLast) + { + RELEASEARRAYOBJECTS(pBuffer); + return false; + } + std::string sMetaSize = std::string(pMeta, pMetaLast - pMeta); + nMetaLength = std::stoi(sMetaSize); + + RELEASEARRAYOBJECTS(pBuffer); + *pMetaData = new BYTE[nMetaLength]; + pBuffer = *pMetaData; + nReadBytes = 0; + if (!oFile.OpenFile(sFile) || !oFile.SeekFile(nStreamBegin + nMetaOffset) || !oFile.ReadFile(pBuffer, nMetaLength, nReadBytes)) + { + RELEASEARRAYOBJECTS(pBuffer); + oFile.CloseFile(); + return false; + } + oFile.CloseFile(); + nMetaLength = nReadBytes; + + return true; +} bool CPdfFile::LoadFromFile(const std::wstring& file, const std::wstring& options, const std::wstring& owner_password, const std::wstring& user_password) { m_pInternal->pReader = new CPdfReader(m_pInternal->pAppFonts); @@ -1037,9 +330,7 @@ OfficeDrawingFileType CPdfFile::GetType() } std::wstring CPdfFile::GetTempDirectory() { - if (!m_pInternal->pReader) - return std::wstring(); - return m_pInternal->pReader->GetTempDirectory(); + return m_pInternal->wsTempFolder; } void CPdfFile::SetTempDirectory(const std::wstring& wsPath) { @@ -1053,75 +344,49 @@ int CPdfFile::GetPagesCount() return 0; PDFDoc* pPdfDoc = m_pInternal->pReader->GetPDFDocument(); int nPages = pPdfDoc ? pPdfDoc->getNumPages() : 0; -#ifndef BUILDING_WASM_MODULE - if (m_pInternal->bEdit && m_pInternal->pWriter && m_pInternal->pWriter->m_pDocument) + if (m_pInternal->pEditor) { - int nWPages = m_pInternal->pWriter->m_pDocument->GetPagesCount(); + int nWPages = m_pInternal->pEditor->GetPagesCount(); if (nWPages > 0) nPages = nWPages; } -#endif return nPages; } void CPdfFile::GetPageInfo(int nPageIndex, double* pdWidth, double* pdHeight, double* pdDpiX, double* pdDpiY) { if (!m_pInternal->pReader) return; -#ifndef BUILDING_WASM_MODULE - if (m_pInternal->bEdit && m_pInternal->pWriter && m_pInternal->pWriter->m_pDocument) - { - PdfWriter::CPage* pPage = m_pInternal->pWriter->m_pDocument->GetPage(nPageIndex); - if (!pPage) - return; - - int nRotate = pPage->GetRotate(); - if (nRotate % 180 == 0) - { - *pdWidth = pPage->GetWidth(); - *pdHeight = pPage->GetHeight(); - } - else - { - *pdWidth = pPage->GetHeight(); - *pdHeight = pPage->GetWidth(); - } - - *pdDpiX = 72.0; - *pdDpiY = 72.0; - } + if (m_pInternal->pEditor) + m_pInternal->pEditor->GetPageInfo(nPageIndex, pdWidth, pdHeight, pdDpiX, pdDpiY); else -#endif m_pInternal->pReader->GetPageInfo(nPageIndex, pdWidth, pdHeight, pdDpiX, pdDpiY); } int CPdfFile::GetRotate(int nPageIndex) { if (!m_pInternal->pReader) return 0; -#ifndef BUILDING_WASM_MODULE - if (m_pInternal->bEdit && m_pInternal->pWriter && m_pInternal->pWriter->m_pDocument) - { - PdfWriter::CPage* pPage = m_pInternal->pWriter->m_pDocument->GetPage(nPageIndex); - if (!pPage) - return 0; - - return pPage->GetRotate(); - } - else -#endif + if (m_pInternal->pEditor) + return m_pInternal->pEditor->GetRotate(nPageIndex); return m_pInternal->pReader->GetRotate(nPageIndex); } int CPdfFile::GetMaxRefID() { if (!m_pInternal->pReader) return 0; - return m_pInternal->pReader->GetMaxRefID(); } -void CPdfFile::DrawPageOnRenderer(IRenderer* pRenderer, int nPageIndex, bool* pBreak) +bool CPdfFile::ValidMetaData() +{ + if (!m_pInternal->pReader) + return false; + return m_pInternal->pReader->ValidMetaData(); +} +void CPdfFile::DrawPageOnRenderer(IRenderer* pRenderer, int nPageIndex, bool* pBreak, COfficeDrawingPageParams* pParams) { if (!m_pInternal->pReader) return; pRenderer->CommandLong(c_nPenWidth0As1px, 1); + m_pInternal->pReader->SetParams(pParams); m_pInternal->pReader->DrawPageOnRenderer(pRenderer, nPageIndex, pBreak); } std::wstring CPdfFile::GetInfo() @@ -1148,6 +413,30 @@ BYTE* CPdfFile::GetWidgets() return NULL; return m_pInternal->pReader->GetWidgets(); } +BYTE* CPdfFile::GetAnnotEmbeddedFonts() +{ + if (!m_pInternal->pReader) + return NULL; + return m_pInternal->pReader->GetFonts(false); +} +BYTE* CPdfFile::GetAnnotStandardFonts() +{ + if (!m_pInternal->pReader) + return NULL; + return m_pInternal->pReader->GetFonts(true); +} +std::wstring CPdfFile::GetFontPath(const std::wstring& wsFontName) +{ + if (!m_pInternal->pReader) + return L""; + return m_pInternal->pReader->GetFontPath(wsFontName, false); +} +std::wstring CPdfFile::GetEmbeddedFontPath(const std::wstring& wsFontName) +{ + if (!m_pInternal->pReader) + return L""; + return m_pInternal->pReader->GetFontPath(wsFontName); +} BYTE* CPdfFile::GetAnnots(int nPageIndex) { if (!m_pInternal->pReader) @@ -1166,11 +455,11 @@ BYTE* CPdfFile::GetAPWidget(int nRasterW, int nRasterH, int nBackgroundColor, in return NULL; return m_pInternal->pReader->GetAPWidget(nRasterW, nRasterH, nBackgroundColor, nPageIndex, nWidget, sView, sButtonView); } -BYTE* CPdfFile::GetButtonIcon(int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex, bool bBase64, int nButtonWidget, const char* sIconView) +BYTE* CPdfFile::GetButtonIcon(int nBackgroundColor, int nPageIndex, bool bBase64, int nButtonWidget, const char* sIconView) { if (!m_pInternal->pReader) return NULL; - return m_pInternal->pReader->GetButtonIcon(nRasterW, nRasterH, nBackgroundColor, nPageIndex, bBase64, nButtonWidget, sIconView); + return m_pInternal->pReader->GetButtonIcon(nBackgroundColor, nPageIndex, bBase64, nButtonWidget, sIconView); } BYTE* CPdfFile::GetAPAnnots(int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex, int nAnnot, const char* sView) { @@ -1204,6 +493,12 @@ void CPdfFile::SetDocumentID(const std::wstring& wsDocumentID) return; m_pInternal->pWriter->SetDocumentID(wsDocumentID); } +void CPdfFile::AddMetaData(const std::wstring& sMetaName, BYTE* pMetaData, DWORD nMetaLength) +{ + if (!m_pInternal->pWriter) + return; + m_pInternal->pWriter->AddMetaData(sMetaName, pMetaData, nMetaLength); +} HRESULT CPdfFile::OnlineWordToPdf(const std::wstring& wsSrcFile, const std::wstring& wsDstFile, CConvertFromBinParams* pParams) { #ifndef BUILDING_WASM_MODULE @@ -1223,7 +518,7 @@ HRESULT CPdfFile::OnlineWordToPdfFromBinary(const std::wstring& wsSrcFile, const HRESULT CPdfFile::AddToPdfFromBinary(BYTE* pBuffer, unsigned int nLen, CConvertFromBinParams* pParams) { #ifndef BUILDING_WASM_MODULE - if (!m_pInternal->pReader || !m_pInternal->pWriter || !m_pInternal->bEdit || !NSOnlineOfficeBinToPdf::AddBinToPdf(this, pBuffer, nLen, pParams)) + if (!m_pInternal->pEditor || !NSOnlineOfficeBinToPdf::AddBinToPdf(this, pBuffer, nLen, pParams)) return S_FALSE; #endif return S_OK; @@ -1262,7 +557,7 @@ HRESULT CPdfFile::get_Type(LONG* lType) } HRESULT CPdfFile::NewPage() { - if (!m_pInternal->pWriter || m_pInternal->bEdit) + if (!m_pInternal->pWriter || m_pInternal->pEditor) return S_FALSE; return m_pInternal->pWriter->NewPage(); } @@ -1276,7 +571,7 @@ HRESULT CPdfFile::put_Height(const double& dHeight) { if (!m_pInternal->pWriter) return S_FALSE; - if (m_pInternal->bEdit && m_pInternal->bEditPage) + if (m_pInternal->pEditor) return S_OK; return m_pInternal->pWriter->put_Height(dHeight); } @@ -1290,7 +585,7 @@ HRESULT CPdfFile::put_Width(const double& dWidth) { if (!m_pInternal->pWriter) return S_FALSE; - if (m_pInternal->bEdit && m_pInternal->bEditPage) + if (m_pInternal->pEditor) return S_OK; return m_pInternal->pWriter->put_Width(dWidth); } @@ -1597,7 +892,51 @@ HRESULT CPdfFile::put_FontName(const std::wstring& wsName) { if (!m_pInternal->pWriter) return S_FALSE; - return m_pInternal->pWriter->put_FontName(wsName); + std::wstring wsFont = wsName; + if (m_pInternal->pEditor && wsName.find(L"Embedded: ") == 0) + { + std::wstring sSub = wsName.substr(10); + bool bBold = false, bItalic = false; + std::wstring wsFontPath; + if (m_pInternal->pEditor->IsBase14(sSub, bBold, bItalic, wsFontPath)) + { + if (bBold || bItalic) + { + LONG lStyle = 0; + if (bBold) + lStyle |= 1; + if (bItalic) + lStyle |= 2; + put_FontStyle(lStyle); + } + + NSFonts::IFontsMemoryStorage* pMemoryStorage = NSFonts::NSApplicationFontStream::GetGlobalMemoryStorage(); + if (wsFontPath == sSub && (!pMemoryStorage || !pMemoryStorage->Get(wsFontPath))) + { + const BYTE* pData14 = NULL; + unsigned int nSize14 = 0; + std::wstring wsTempFileName = m_pInternal->wsTempFolder + L"/" + wsFontPath + L".base"; + if (NSFile::CFileBinary::Exists(wsTempFileName)) + wsFontPath = wsTempFileName; + else if (PdfReader::GetBaseFont(sSub, pData14, nSize14)) + { + NSFile::CFileBinary oFile; + if (oFile.CreateFileW(wsTempFileName)) + { + oFile.WriteFile((BYTE*)pData14, nSize14); + wsFontPath = wsTempFileName; + } + else if (!wsTempFileName.empty()) + NSFile::CFileBinary::Remove(wsTempFileName); + oFile.CloseFile(); + } + } + } + else + wsFont = sSub; + m_pInternal->pWriter->AddFont(wsFont, bBold, bItalic, wsFontPath, 0); + } + return m_pInternal->pWriter->put_FontName(wsFont); } HRESULT CPdfFile::get_FontPath(std::wstring* wsPath) { @@ -1709,7 +1048,7 @@ HRESULT CPdfFile::EndCommand(const DWORD& lType) { if (!m_pInternal->pWriter) return S_FALSE; - return m_pInternal->pWriter->EndCommand(lType, m_pInternal->lClipMode); + return m_pInternal->pWriter->EndCommand(lType); } HRESULT CPdfFile::PathCommandMoveTo(const double& dX, const double& dY) { @@ -1833,13 +1172,15 @@ HRESULT CPdfFile::ResetTransform() } HRESULT CPdfFile::get_ClipMode(LONG* lMode) { - *lMode = m_pInternal->lClipMode; - return S_OK; + if (!m_pInternal->pWriter) + return S_FALSE; + return m_pInternal->pWriter->get_ClipMode(lMode); } HRESULT CPdfFile::put_ClipMode(const LONG& lMode) { - m_pInternal->lClipMode = lMode; - return S_OK; + if (!m_pInternal->pWriter) + return S_FALSE; + return m_pInternal->pWriter->put_ClipMode(lMode); } HRESULT CPdfFile::CommandLong(const LONG& lType, const LONG& lCommand) { @@ -1864,6 +1205,12 @@ HRESULT CPdfFile::IsSupportAdvancedCommand(const IAdvancedCommand::AdvancedComma case IAdvancedCommand::AdvancedCommandType::FormField: case IAdvancedCommand::AdvancedCommandType::Annotaion: case IAdvancedCommand::AdvancedCommandType::DeleteAnnot: + case IAdvancedCommand::AdvancedCommandType::WidgetsInfo: + case IAdvancedCommand::AdvancedCommandType::ShapeStart: + case IAdvancedCommand::AdvancedCommandType::ShapeEnd: + case IAdvancedCommand::AdvancedCommandType::PageClear: + case IAdvancedCommand::AdvancedCommandType::PageRotate: + case IAdvancedCommand::AdvancedCommandType::Headings: return S_OK; default: break; @@ -1887,6 +1234,8 @@ HRESULT CPdfFile::AdvancedCommand(IAdvancedCommand* command) case IAdvancedCommand::AdvancedCommandType::Link: { CLinkCommand* pCommand = (CLinkCommand*)command; + if (m_pInternal->pEditor && m_pInternal->pEditor->IsEditPage()) + m_pInternal->pEditor->EditPage(pCommand->GetPage(), false); return m_pInternal->pWriter->AddLink(pCommand->GetX(), pCommand->GetY(), pCommand->GetW(), pCommand->GetH(), pCommand->GetDestX(), pCommand->GetDestY(), pCommand->GetPage()); } @@ -1904,20 +1253,54 @@ HRESULT CPdfFile::AdvancedCommand(IAdvancedCommand* command) case IAdvancedCommand::AdvancedCommandType::Annotaion: { CAnnotFieldInfo* pCommand = (CAnnotFieldInfo*)command; -#ifndef BUILDING_WASM_MODULE - if (m_pInternal->bEdit && m_pInternal->bEditPage) - EditAnnot(pCommand->GetPage(), pCommand->GetID()); -#endif + if (m_pInternal->pEditor && m_pInternal->pEditor->IsEditPage()) + m_pInternal->pEditor->EditAnnot(pCommand->GetPage(), pCommand->GetID()); return m_pInternal->pWriter->AddAnnotField(m_pInternal->pAppFonts, pCommand); } case IAdvancedCommand::AdvancedCommandType::DeleteAnnot: { CAnnotFieldDelete* pCommand = (CAnnotFieldDelete*)command; -#ifndef BUILDING_WASM_MODULE - if (m_pInternal->bEdit && m_pInternal->bEditPage) - DeleteAnnot(pCommand->GetID()); -#endif - return true; + if (m_pInternal->pEditor && m_pInternal->pEditor->IsEditPage()) + m_pInternal->pEditor->DeleteAnnot(pCommand->GetID()); + return S_OK; + } + case IAdvancedCommand::AdvancedCommandType::WidgetsInfo: + { + CWidgetsInfo* pCommand = (CWidgetsInfo*)command; + if (m_pInternal->pEditor && m_pInternal->pEditor->EditWidgets(pCommand)) + return m_pInternal->pWriter->EditWidgetParents(m_pInternal->pAppFonts, pCommand, m_pInternal->wsTempFolder); + return S_OK; + } + case IAdvancedCommand::AdvancedCommandType::ShapeStart: + { + CShapeStart* pCommand = (CShapeStart*)command; + if (m_pInternal->pEditor) + m_pInternal->pEditor->AddShapeXML(pCommand->GetShapeXML()); + return S_OK; + } + case IAdvancedCommand::AdvancedCommandType::ShapeEnd: + { + if (m_pInternal->pEditor) + m_pInternal->pEditor->EndMarkedContent(); + return S_OK; + } + case IAdvancedCommand::AdvancedCommandType::PageClear: + { + if (m_pInternal->pEditor && m_pInternal->pEditor->IsEditPage()) + m_pInternal->pEditor->ClearPage(); + return S_OK; + } + case IAdvancedCommand::AdvancedCommandType::PageRotate: + { + CPageRotate* pCommand = (CPageRotate*)command; + if (m_pInternal->pEditor) + m_pInternal->pWriter->PageRotate(pCommand->GetPageRotate()); + return S_OK; + } + case IAdvancedCommand::AdvancedCommandType::Headings: + { + m_pInternal->pWriter->SetHeadings((CHeadings*)command); + return S_OK; } default: break; diff --git a/PdfFile/PdfFile.h b/PdfFile/PdfFile.h index a3e12fceae4..dc64c231df0 100644 --- a/PdfFile/PdfFile.h +++ b/PdfFile/PdfFile.h @@ -97,8 +97,7 @@ class PDFFILE_DECL_EXPORT CPdfFile : public IOfficeDrawingFile, public IRenderer bool EditPage (int nPageIndex); bool DeletePage (int nPageIndex); bool AddPage (int nPageIndex); - bool EditAnnot (int nPageIndex, int nID); - bool DeleteAnnot(int nID); + HRESULT ChangePassword(const std::wstring& wsPath, const std::wstring& wsPassword = L""); #endif // --- READER --- @@ -110,6 +109,7 @@ class PDFFILE_DECL_EXPORT CPdfFile : public IOfficeDrawingFile, public IRenderer void SetCMapFile(const std::wstring& sFile); void ToXml(const std::wstring& sFile, bool bSaveStreams = false); + static bool GetMetaData(const std::wstring& sFile, const std::wstring& sMetaName, BYTE** pMetaData, DWORD& nMetaLength); virtual bool LoadFromFile (const std::wstring& file, const std::wstring& options = L"", const std::wstring& owner_password = L"", const std::wstring& user_password = L""); virtual bool LoadFromMemory(BYTE* data, DWORD length, const std::wstring& options = L"", const std::wstring& owner_password = L"", const std::wstring& user_password = L""); virtual NSFonts::IApplicationFonts* GetFonts(); @@ -121,18 +121,23 @@ class PDFFILE_DECL_EXPORT CPdfFile : public IOfficeDrawingFile, public IRenderer virtual int GetPagesCount(); virtual void GetPageInfo(int nPageIndex, double* pdWidth, double* pdHeight, double* pdDpiX, double* pdDpiY); - virtual void DrawPageOnRenderer(IRenderer* pRenderer, int nPageIndex, bool* pBreak); + virtual void DrawPageOnRenderer(IRenderer* pRenderer, int nPageIndex, bool* pBreak, COfficeDrawingPageParams* pParams = NULL); virtual std::wstring GetInfo(); virtual BYTE* GetStructure(); virtual BYTE* GetLinks(int nPageIndex); + bool ValidMetaData(); int GetRotate(int nPageIndex); int GetMaxRefID(); BYTE* GetWidgets(); + BYTE* GetAnnotEmbeddedFonts(); + BYTE* GetAnnotStandardFonts(); BYTE* GetAnnots (int nPageIndex = -1); BYTE* VerifySign (const std::wstring& sFile, ICertificate* pCertificate, int nWidget = -1); - BYTE* GetAPWidget (int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex, int nWidget = -1, const char* sView = NULL, const char* sButtonView = NULL); - BYTE* GetButtonIcon(int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex, bool bBase64 = false, int nButtonWidget = -1, const char* sIconView = NULL); - BYTE* GetAPAnnots (int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex, int nAnnot = -1, const char* sView = NULL); + BYTE* GetAPWidget (int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex, int nWidget = -1, const char* sView = NULL, const char* sBView = NULL); + BYTE* GetAPAnnots (int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex, int nAnnot = -1, const char* sView = NULL); + BYTE* GetButtonIcon(int nBackgroundColor, int nPageIndex, bool bBase64 = false, int nBWidget = -1, const char* sIView = NULL); + std::wstring GetFontPath(const std::wstring& wsFontName); + std::wstring GetEmbeddedFontPath(const std::wstring& wsFontName); // --- WRITER --- @@ -143,6 +148,7 @@ class PDFFILE_DECL_EXPORT CPdfFile : public IOfficeDrawingFile, public IRenderer void SetDocumentID(const std::wstring& wsDocumentID); void Sign(const double& dX, const double& dY, const double& dW, const double& dH, const std::wstring& wsPicturePath, ICertificate* pCertificate); void SetDocumentInfo(const std::wstring& wsTitle, const std::wstring& wsCreator, const std::wstring& wsSubject, const std::wstring& wsKeywords); + void AddMetaData(const std::wstring& sMetaName, BYTE* pMetaData, DWORD nMetaLength); HRESULT OnlineWordToPdf (const std::wstring& wsSrcFile, const std::wstring& wsDstFile, CConvertFromBinParams* pParams = NULL); HRESULT OnlineWordToPdfFromBinary(const std::wstring& wsSrcFile, const std::wstring& wsDstFile, CConvertFromBinParams* pParams = NULL); diff --git a/PdfFile/PdfFile.pro b/PdfFile/PdfFile.pro index e2beaffa8b5..fb74d3257c9 100644 --- a/PdfFile/PdfFile.pro +++ b/PdfFile/PdfFile.pro @@ -16,6 +16,12 @@ DEFINES += PDFFILE_USE_DYNAMIC_LIBRARY ADD_DEPENDENCY(graphics, kernel, UnicodeConverter, kernel_network) +#CONFIG += use_openssl_hash +use_openssl_hash { + DEFINES += USE_OPENSSL_HASH + INCLUDEPATH += $$PWD/../Common/3dParty/openssl/openssl/include +} + # PdfReader core_windows { @@ -99,17 +105,7 @@ use_external_jpeg2000 { SOURCES += SrcReader/JPXStream2.cpp } -#CONFIG += build_viewer_module -build_viewer_module { - DEFINES += BUILDING_WASM_MODULE \ - TEST_CPP_BINARY - - HEADERS += $$CORE_ROOT_DIR/HtmlRenderer/include/HTMLRendererText.h - SOURCES += $$CORE_ROOT_DIR/HtmlRenderer/src/HTMLRendererText.cpp -} - # PdfWriter - DEFINES += CRYPTOPP_DISABLE_ASM \ NOMINMAX LIBS += -L$$CORE_BUILDS_LIBRARIES_PATH -lCryptoPPLib @@ -199,9 +195,11 @@ SOURCES += \ HEADERS += PdfFile.h \ PdfWriter.h \ PdfReader.h \ + PdfEditor.h \ OnlineOfficeBinToPdf.h SOURCES += PdfFile.cpp \ PdfWriter.cpp \ PdfReader.cpp \ + PdfEditor.cpp \ OnlineOfficeBinToPdf.cpp diff --git a/PdfFile/PdfReader.cpp b/PdfFile/PdfReader.cpp index 258b7986894..ba49925cb30 100644 --- a/PdfFile/PdfReader.cpp +++ b/PdfFile/PdfReader.cpp @@ -41,6 +41,7 @@ #include "SrcReader/Adaptors.h" #include "SrcReader/PdfAnnot.h" +#include "Resources/BaseFonts.h" #include "lib/xpdf/PDFDoc.h" #include "lib/xpdf/PDFCore.h" @@ -59,7 +60,6 @@ CPdfReader::CPdfReader(NSFonts::IApplicationFonts* pAppFonts) { - m_wsTempFolder = L""; m_pPDFDocument = NULL; m_nFileLength = 0; @@ -68,7 +68,7 @@ CPdfReader::CPdfReader(NSFonts::IApplicationFonts* pAppFonts) globalParams->setErrQuiet(gTrue); #endif - m_pFontList = new PdfReader::CFontList(); + m_pFontList = new PdfReader::CPdfFontList(); // Создаем менеджер шрифтов с собственным кэшем m_pFontManager = pAppFonts->GenerateFontManager(); @@ -82,7 +82,7 @@ CPdfReader::CPdfReader(NSFonts::IApplicationFonts* pAppFonts) SetCMapFile(NSFile::GetProcessDirectory() + L"/cmap.bin"); #else globalParams->setDrawFormFields(gFalse); - //globalParams->setDrawAnnotations(gFalse); + globalParams->setDrawAnnotations(gFalse); SetCMapMemory(NULL, 0); #endif @@ -107,108 +107,136 @@ CPdfReader::~CPdfReader() RELEASEINTERFACE(m_pFontManager); } -bool scanFonts(Dict *pResources, PDFDoc *pDoc, const std::vector& arrCMap, int nDepth) +bool scanFonts(Dict *pResources, const std::vector& arrCMap, int nDepth, std::vector& arrUniqueResources) { if (nDepth > 5) return false; Object oFonts; - if (pResources->lookup("Font", &oFonts) && oFonts.isDict()) + if (pResources->lookup("Font", &oFonts)->isDict()) { for (int i = 0, nLength = oFonts.dictGetLength(); i < nLength; ++i) { Object oFont, oEncoding; - if (!oFonts.dictGetVal(i, &oFont) || !oFont.isDict() || !oFont.dictLookup("Encoding", &oEncoding) || !oEncoding.isName()) + if (!oFonts.dictGetVal(i, &oFont)->isDict() || !oFont.dictLookup("Encoding", &oEncoding)->isName()) { oFont.free(); oEncoding.free(); continue; } - + oFont.free(); char* sName = oEncoding.getName(); if (std::find(arrCMap.begin(), arrCMap.end(), sName) != arrCMap.end()) { - oEncoding.free(); oFont.free(); oFonts.free(); + oEncoding.free(); oFonts.free(); return true; } - oEncoding.free(); oFont.free(); + oEncoding.free(); } } oFonts.free(); -#define SCAN_FONTS(sName)\ -{\ - Object oObject;\ - if (pResources->lookup(sName, &oObject) && oObject.isDict())\ - {\ - for (int i = 0, nLength = oObject.dictGetLength(); i < nLength; ++i)\ - {\ - Object oXObj, oResources;\ - if (!oObject.dictGetVal(i, &oXObj) || !oXObj.isStream() || !oXObj.streamGetDict()->lookup("Resources", &oResources) || !oResources.isDict())\ - {\ - oXObj.free(); oResources.free();\ - continue;\ - }\ - oXObj.free();\ - if (scanFonts(oResources.getDict(), pDoc, arrCMap, nDepth + 1))\ - {\ - oResources.free(); oObject.free();\ - return true;\ - }\ - oResources.free();\ - }\ - }\ - oObject.free();\ -} - SCAN_FONTS("XObject"); - SCAN_FONTS("Pattern"); - - Object oExtGState; - if (pResources->lookup("ExtGState", &oExtGState) && oExtGState.isDict()) + auto fScanFonts = [pResources, nDepth, &arrUniqueResources](const std::vector& arrCMap, const char* sName) { - for (int i = 0, nLength = oExtGState.dictGetLength(); i < nLength; ++i) + Object oObject; + if (!pResources->lookup(sName, &oObject)->isDict()) + { + oObject.free(); + return false; + } + for (int i = 0, nLength = oObject.dictGetLength(); i < nLength; ++i) { - Object oGS, oSMask, oSMaskGroup, oResources; - if (!oExtGState.dictGetVal(i, &oGS) || !oGS.isDict() || !oGS.dictLookup("SMask", &oSMask) || !oSMask.isDict() || !oSMask.dictLookup("G", &oSMaskGroup) || !oSMaskGroup.isStream() || - oSMaskGroup.streamGetDict()->lookup("Resources", &oResources) || !oResources.isDict()) + Object oXObj, oResources; + if (!oObject.dictGetVal(i, &oXObj)->isStream() || !oXObj.streamGetDict()->lookup("Resources", &oResources)->isDict()) { - oGS.free(); oSMask.free(); oSMaskGroup.free(); oResources.free(); + oXObj.free(); oResources.free(); continue; } - oGS.free(); oSMask.free(); oSMaskGroup.free(); - if (scanFonts(oResources.getDict(), pDoc, arrCMap, nDepth + 1)) + Object oRef; + if (oXObj.streamGetDict()->lookupNF("Resources", &oRef)->isRef() && std::find(arrUniqueResources.begin(), arrUniqueResources.end(), oRef.getRef().num) != arrUniqueResources.end()) { - oResources.free(); oExtGState.free(); + oXObj.free(); oResources.free(); oRef.free(); + continue; + } + arrUniqueResources.push_back(oRef.getRef().num); + oXObj.free(); oRef.free(); + if (scanFonts(oResources.getDict(), arrCMap, nDepth + 1, arrUniqueResources)) + { + oResources.free(); oObject.free(); return true; } oResources.free(); } + oObject.free(); + return false; + }; + + if (fScanFonts(arrCMap, "XObject") || fScanFonts(arrCMap, "Pattern")) + return true; + + Object oExtGState; + if (!pResources->lookup("ExtGState", &oExtGState)->isDict()) + { + oExtGState.free(); + return false; + } + for (int i = 0, nLength = oExtGState.dictGetLength(); i < nLength; ++i) + { + Object oGS, oSMask, oSMaskGroup, oResources; + if (!oExtGState.dictGetVal(i, &oGS)->isDict() || !oGS.dictLookup("SMask", &oSMask)->isDict() || !oSMask.dictLookup("G", &oSMaskGroup)->isStream() || !oSMaskGroup.streamGetDict()->lookup("Resources", &oResources)->isDict()) + { + oGS.free(); oSMask.free(); oSMaskGroup.free(); oResources.free(); + continue; + } + oGS.free(); oSMask.free(); + Object oRef; + if (oSMaskGroup.streamGetDict()->lookupNF("Resources", &oRef)->isRef() && std::find(arrUniqueResources.begin(), arrUniqueResources.end(), oRef.getRef().num) != arrUniqueResources.end()) + { + oSMaskGroup.free(); oResources.free(); oRef.free(); + continue; + } + arrUniqueResources.push_back(oRef.getRef().num); + oSMaskGroup.free(); oRef.free(); + if (scanFonts(oResources.getDict(), arrCMap, nDepth + 1, arrUniqueResources)) + { + oResources.free(); oExtGState.free(); + return true; + } + oResources.free(); } oExtGState.free(); return false; } -bool scanAPfonts(Object* oAnnot, PDFDoc *pDoc, const std::vector& arrCMap) +bool scanAPfonts(Object* oAnnot, const std::vector& arrCMap, std::vector& arrUniqueResources) { Object oAP; - if (oAnnot->dictLookup("AP", &oAP)->isDict()) + if (!oAnnot->dictLookup("AP", &oAP)->isDict()) { - Object oAPi, oRes; - -#define SCAN_AP_VIEW(sName)\ -{\ -if (oAP.dictLookup(sName, &oAPi)->isStream() && oAPi.streamGetDict()->lookup("Resources", &oRes)->isDict() && scanFonts(oRes.getDict(), pDoc, arrCMap, 0))\ -{\ - oAPi.free(); oAP.free(); oRes.free();\ - return true;\ -}\ -oAPi.free(); oRes.free();\ -} - - SCAN_AP_VIEW("N"); - SCAN_AP_VIEW("D"); - SCAN_AP_VIEW("R"); + oAP.free(); + return false; } + auto fScanAPView = [&arrUniqueResources](Object* oAP, const std::vector& arrCMap, const char* sName) + { + Object oAPi, oRes; + if (!oAP->dictLookup(sName, &oAPi)->isStream() || !oAPi.streamGetDict()->lookup("Resources", &oRes)->isDict()) + { + oAPi.free(); oRes.free(); + return false; + } + Object oRef; + if (oAPi.streamGetDict()->lookupNF("Resources", &oRef)->isRef() && std::find(arrUniqueResources.begin(), arrUniqueResources.end(), oRef.getRef().num) != arrUniqueResources.end()) + { + oAPi.free(); oRes.free(); oRef.free(); + return false; + } + arrUniqueResources.push_back(oRef.getRef().num); + oAPi.free(); oRef.free(); + bool bRes = scanFonts(oRes.getDict(), arrCMap, 0, arrUniqueResources); + oRes.free(); + return bRes; + }; + bool bRes = fScanAPView(&oAP, arrCMap, "N") || fScanAPView(&oAP, arrCMap, "D") || fScanAPView(&oAP, arrCMap, "R"); oAP.free(); - return false; + return bRes; } bool CPdfReader::IsNeedCMap() { @@ -235,81 +263,82 @@ bool CPdfReader::IsNeedCMap() if (!m_pPDFDocument || !m_pPDFDocument->getCatalog()) return false; - for (int nPage = 0, nLastPage = m_pPDFDocument->getNumPages(); nPage < nLastPage; ++nPage) + std::vector arrUniqueResources; + + for (int nPage = 1, nLastPage = m_pPDFDocument->getNumPages(); nPage <= nLastPage; ++nPage) { - Page* pPage = m_pPDFDocument->getCatalog()->getPage(nPage + 1); + Page* pPage = m_pPDFDocument->getCatalog()->getPage(nPage); Dict* pResources = pPage->getResourceDict(); - if (pResources && scanFonts(pResources, m_pPDFDocument, arrCMap, 0)) + if (pResources && scanFonts(pResources, arrCMap, 0, arrUniqueResources)) return true; Object oAnnots; - if (pPage->getAnnots(&oAnnots)->isArray()) + if (!pPage->getAnnots(&oAnnots)->isArray()) { - for (int i = 0, nNum = oAnnots.arrayGetLength(); i < nNum; ++i) + oAnnots.free(); + continue; + } + for (int i = 0, nNum = oAnnots.arrayGetLength(); i < nNum; ++i) + { + Object oAnnot; + if (!oAnnots.arrayGet(i, &oAnnot)->isDict()) { - Object oAnnot; - if (!oAnnots.arrayGet(i, &oAnnot)->isDict()) - { - oAnnot.free(); - continue; - } - - Object oDR; - if (oAnnot.dictLookup("DR", &oDR)->isDict() && scanFonts(oDR.getDict(), m_pPDFDocument, arrCMap, 0)) - { - oDR.free(); oAnnot.free(); oAnnots.free(); - return true; - } - oDR.free(); + oAnnot.free(); + continue; + } - if (scanAPfonts(&oAnnot, m_pPDFDocument, arrCMap)) - { - oAnnot.free(); oAnnots.free(); - return true; - } + Object oDR; + if (oAnnot.dictLookup("DR", &oDR)->isDict() && scanFonts(oDR.getDict(), arrCMap, 0, arrUniqueResources)) + { + oDR.free(); oAnnot.free(); oAnnots.free(); + return true; + } + oDR.free(); - oAnnot.free(); + if (scanAPfonts(&oAnnot, arrCMap, arrUniqueResources)) + { + oAnnot.free(); oAnnots.free(); + return true; } + oAnnot.free(); } oAnnots.free(); } AcroForm* pAcroForms = m_pPDFDocument->getCatalog()->getForm(); - if (pAcroForms) + if (!pAcroForms) + return false; + Object oDR; + Object* oAcroForm = pAcroForms->getAcroFormObj(); + if (oAcroForm->dictLookup("DR", &oDR)->isDict() && scanFonts(oDR.getDict(), arrCMap, 0, arrUniqueResources)) + { + oDR.free(); + return true; + } + oDR.free(); + + for (int i = 0, nNum = pAcroForms->getNumFields(); i < nNum; ++i) { - Object oDR; - Object* oAcroForm = pAcroForms->getAcroFormObj(); - if (oAcroForm->dictLookup("DR", &oDR)->isDict() && scanFonts(oDR.getDict(), m_pPDFDocument, arrCMap, 0)) + AcroFormField* pField = pAcroForms->getField(i); + + if (pField->getResources(&oDR)->isDict() && scanFonts(oDR.getDict(), arrCMap, 0, arrUniqueResources)) { oDR.free(); return true; } oDR.free(); - for (int i = 0, nNum = pAcroForms->getNumFields(); i < nNum; ++i) - { - AcroFormField* pField = pAcroForms->getField(i); + Object oWidgetRef, oWidget; + pField->getFieldRef(&oWidgetRef); + oWidgetRef.fetch(m_pPDFDocument->getXRef(), &oWidget); + oWidgetRef.free(); - Object oDR; - if (pField->getResources(&oDR)->isDict() && scanFonts(oDR.getDict(), m_pPDFDocument, arrCMap, 0)) - { - oDR.free(); - return true; - } - oDR.free(); - - Object oWidgetRef, oWidget; - pField->getFieldRef(&oWidgetRef); - oWidgetRef.fetch(m_pPDFDocument->getXRef(), &oWidget); - oWidgetRef.free(); - - if (scanAPfonts(&oWidget, m_pPDFDocument, arrCMap)) - { - oWidget.free(); - return true; - } + if (scanAPfonts(&oWidget, arrCMap, arrUniqueResources)) + { oWidget.free(); + return true; } + oWidget.free(); } return false; @@ -369,6 +398,9 @@ bool CPdfReader::LoadFromFile(NSFonts::IApplicationFonts* pAppFonts, const std:: m_pFontList->Clear(); + std::map mFonts = PdfReader::CAnnotFonts::GetAllFonts(m_pPDFDocument, m_pFontManager, m_pFontList); + m_mFonts.insert(mFonts.begin(), mFonts.end()); + return true; } bool CPdfReader::LoadFromMemory(NSFonts::IApplicationFonts* pAppFonts, BYTE* data, DWORD length, const std::wstring& owner_password, const std::wstring& user_password) @@ -406,11 +438,24 @@ bool CPdfReader::LoadFromMemory(NSFonts::IApplicationFonts* pAppFonts, BYTE* dat m_pFontList->Clear(); + std::map mFonts = PdfReader::CAnnotFonts::GetAllFonts(m_pPDFDocument, m_pFontManager, m_pFontList); + m_mFonts.insert(mFonts.begin(), mFonts.end()); + return true; } void CPdfReader::Close() { RELEASEOBJECT(m_pPDFDocument); + m_mFonts.clear(); +} +void CPdfReader::SetParams(COfficeDrawingPageParams* pParams) +{ + if (!pParams) + return; + + GBool bDraw = pParams->m_bNeedDrawAnnotation ? gTrue : gFalse; + globalParams->setDrawFormFields(bDraw); + globalParams->setDrawAnnotations(bDraw); } int CPdfReader::GetError() @@ -430,7 +475,7 @@ void CPdfReader::GetPageInfo(int _nPageIndex, double* pdWidth, double* pdHeight, if (!m_pPDFDocument) return; -#if 0 //#ifdef BUILDING_WASM_MODULE +#ifdef BUILDING_WASM_MODULE *pdWidth = m_pPDFDocument->getPageCropWidth(nPageIndex); *pdHeight = m_pPDFDocument->getPageCropHeight(nPageIndex); #else @@ -452,34 +497,55 @@ void CPdfReader::GetPageInfo(int _nPageIndex, double* pdWidth, double* pdHeight, } int CPdfReader::GetRotate(int _nPageIndex) { - int nPageIndex = _nPageIndex + 1; - if (!m_pPDFDocument) return 0; - - return m_pPDFDocument->getPageRotate(nPageIndex); + return m_pPDFDocument->getPageRotate(_nPageIndex + 1); } int CPdfReader::GetMaxRefID() { if (!m_pPDFDocument) return 0; + return m_pPDFDocument->getXRef()->getNumObjects(); +} +bool CPdfReader::ValidMetaData() +{ + if (!m_pPDFDocument) + return false; + XRef* xref = m_pPDFDocument->getXRef(); - return xref->getNumObjects(); + Object oMeta, oType, oID; + if (!xref->fetch(1, 0, &oMeta)->isStream() || !oMeta.streamGetDict()->lookup("Type", &oType)->isName("MetaOForm") || !oMeta.streamGetDict()->lookup("ID", &oID)->isString()) + { + oMeta.free(); oType.free(); oID.free(); + return false; + } + oMeta.free(); oType.free(); + + Object oTID, oID2; + Object* pTrailerDict = xref->getTrailerDict(); + if (!pTrailerDict->dictLookup("ID", &oTID)->isArray() || !oTID.arrayGet(1, &oID2)->isString()) + { + oID.free(); oTID.free(); oID2.free(); + return false; + } + oTID.free(); + + bool bRes = oID2.getString()->cmp(oID.getString()) == 0; + oID.free(); oID2.free(); + return bRes; } void CPdfReader::DrawPageOnRenderer(IRenderer* pRenderer, int _nPageIndex, bool* pbBreak) { - int nPageIndex = _nPageIndex + 1; - if (m_pPDFDocument && pRenderer) { PdfReader::RendererOutputDev oRendererOut(pRenderer, m_pFontManager, m_pFontList); oRendererOut.NewPDF(m_pPDFDocument->getXRef()); oRendererOut.SetBreak(pbBreak); int nRotate = 0; -#if 0 //#ifdef BUILDING_WASM_MODULE - nRotate = -m_pPDFDocument->getPageRotate(nPageIndex); +#ifdef BUILDING_WASM_MODULE + nRotate = -m_pPDFDocument->getPageRotate(_nPageIndex + 1); #endif - m_pPDFDocument->displayPage(&oRendererOut, nPageIndex, 72.0, 72.0, nRotate, gFalse, gTrue, gFalse); + m_pPDFDocument->displayPage(&oRendererOut, _nPageIndex + 1, 72.0, 72.0, nRotate, gFalse, gTrue, gFalse); } } void CPdfReader::SetTempDirectory(const std::wstring& wsTempFolder) @@ -507,7 +573,7 @@ void CPdfReader::SetTempDirectory(const std::wstring& wsTempFolder) m_wsTempFolder = L""; if (globalParams) - ((GlobalParamsAdaptor*)globalParams)->SetTempFolder(m_wsTempFolder.c_str()); + ((GlobalParamsAdaptor*)globalParams)->SetTempFolder(m_wsTempFolder); } std::wstring CPdfReader::GetTempDirectory() { @@ -535,12 +601,6 @@ void CPdfReader::ChangeLength(DWORD nLength) m_nFileLength = nLength; } -void EscapingCharacter(std::wstring& sValue) -{ - NSStringExt::Replace(sValue, L"\\", L"\\\\"); - NSStringExt::Replace(sValue, L"\"", L"\\\""); - sValue.erase(std::remove_if(sValue.begin(), sValue.end(), [] (const wchar_t& wc) { return wc < 0x20; } ), sValue.end()); -} std::wstring CPdfReader::GetInfo() { if (!m_pPDFDocument) @@ -552,69 +612,83 @@ std::wstring CPdfReader::GetInfo() std::wstring sRes = L"{"; - Object info, obj1; - m_pPDFDocument->getDocInfo(&info); - if (info.isDict()) + Object oInfo; + if (m_pPDFDocument->getDocInfo(&oInfo)->isDict()) { -#define DICT_LOOKUP(sName, wsName) \ -if (info.dictLookup(sName, &obj1)->isString())\ -{\ - TextString* s = new TextString(obj1.getString());\ - std::wstring sValue = NSStringExt::CConverter::GetUnicodeFromUTF32(s->getUnicode(), s->getLength());\ - delete s;\ - EscapingCharacter(sValue);\ - if (!sValue.empty())\ - {\ - sRes += L"\"";\ - sRes += wsName;\ - sRes += L"\":\"";\ - sRes += sValue;\ - sRes += L"\",";\ - }\ -}\ -obj1.free(); - DICT_LOOKUP("Title", L"Title"); - DICT_LOOKUP("Author", L"Author"); - DICT_LOOKUP("Subject", L"Subject"); - DICT_LOOKUP("Keywords", L"Keywords"); - DICT_LOOKUP("Creator", L"Creator"); - DICT_LOOKUP("Producer", L"Producer"); -#define DICT_LOOKUP_DATE(sName, wsName) \ -if (info.dictLookup(sName, &obj1)->isString())\ -{\ - char* str = obj1.getString()->getCString();\ - if (str)\ - {\ - TextString* s = new TextString(obj1.getString());\ - std::wstring sNoDate = NSStringExt::CConverter::GetUnicodeFromUTF32(s->getUnicode(), s->getLength());\ - if (sNoDate.length() > 16)\ - {\ - std::wstring sDate = sNoDate.substr(2, 4) + L'-' + sNoDate.substr(6, 2) + L'-' + sNoDate.substr(8, 2) + L'T' +\ - sNoDate.substr(10, 2) + L':' + sNoDate.substr(12, 2) + L':' + sNoDate.substr(14, 2);\ - if (sNoDate.length() > 21 && (sNoDate[16] == L'+' || sNoDate[16] == L'-'))\ - sDate += (L".000" + sNoDate.substr(16, 3) + L':' + sNoDate.substr(20, 2));\ - else\ - sDate += L"Z";\ - NSStringExt::Replace(sDate, L"\"", L"\\\"");\ - sRes += L"\"";\ - sRes += wsName;\ - sRes += L"\":\"";\ - sRes += sDate;\ - sRes += L"\",";\ - }\ - delete s;\ - }\ -}\ -obj1.free(); - DICT_LOOKUP_DATE("CreationDate", L"CreationDate"); - DICT_LOOKUP_DATE("ModDate", L"ModDate"); + auto fDictLookup = [&oInfo](const char* sName, const wchar_t* wsName) + { + std::wstring sRes; + Object obj1; + if (oInfo.dictLookup(sName, &obj1)->isString()) + { + TextString* s = new TextString(obj1.getString()); + std::wstring sValue = NSStringExt::CConverter::GetUnicodeFromUTF32(s->getUnicode(), s->getLength()); + delete s; + NSStringExt::Replace(sValue, L"\\", L"\\\\"); + NSStringExt::Replace(sValue, L"\"", L"\\\""); + sValue.erase(std::remove_if(sValue.begin(), sValue.end(), [] (const wchar_t& wc) { return wc < 0x20; } ), sValue.end()); + if (!sValue.empty()) + { + sRes += L"\""; + sRes += wsName; + sRes += L"\":\""; + sRes += sValue; + sRes += L"\","; + } + } + obj1.free(); + return sRes; + }; + sRes += fDictLookup("Title", L"Title"); + sRes += fDictLookup("Author", L"Author"); + sRes += fDictLookup("Subject", L"Subject"); + sRes += fDictLookup("Keywords", L"Keywords"); + sRes += fDictLookup("Creator", L"Creator"); + sRes += fDictLookup("Producer", L"Producer"); + + auto fDictLookupDate = [&oInfo](const char* sName, const wchar_t* wsName) + { + std::wstring sRes; + Object obj1; + if (!oInfo.dictLookup(sName, &obj1)->isString() || !obj1.getString()->getLength()) + { + obj1.free(); + return sRes; + } + + TextString* s = new TextString(obj1.getString()); + std::wstring sNoDate = NSStringExt::CConverter::GetUnicodeFromUTF32(s->getUnicode(), s->getLength()); + if (sNoDate.length() > 16) + { + std::wstring sDate = sNoDate.substr(2, 4) + L'-' + sNoDate.substr(6, 2) + L'-' + sNoDate.substr(8, 2) + L'T' + + sNoDate.substr(10, 2) + L':' + sNoDate.substr(12, 2) + L':' + sNoDate.substr(14, 2); + if (sNoDate.length() > 21 && (sNoDate[16] == L'+' || sNoDate[16] == L'-')) + sDate += (L".000" + sNoDate.substr(16, 3) + L':' + sNoDate.substr(20, 2)); + else + sDate += L"Z"; + NSStringExt::Replace(sDate, L"\\", L"\\\\"); + NSStringExt::Replace(sDate, L"\"", L"\\\""); + sDate.erase(std::remove_if(sDate.begin(), sDate.end(), [] (const wchar_t& wc) { return wc < 0x20; } ), sDate.end()); + sRes += L"\""; + sRes += wsName; + sRes += L"\":\""; + sRes += sDate; + sRes += L"\","; + } + delete s; + + obj1.free(); + return sRes; + }; + sRes += fDictLookupDate("CreationDate", L"CreationDate"); + sRes += fDictLookupDate("ModDate", L"ModDate"); } - info.free(); + oInfo.free(); std::wstring version = std::to_wstring(m_pPDFDocument->getPDFVersion()); std::wstring::size_type posDot = version.find('.'); if (posDot != std::wstring::npos) - version = version.substr(0, posDot + 2); + version.resize(posDot + 2); if (!version.empty()) sRes += (L"\"Version\":" + version + L","); @@ -630,7 +704,7 @@ obj1.free(); sRes += std::to_wstring(m_pPDFDocument->getNumPages()); sRes += L",\"FastWebView\":"; - Object obj2, obj3, obj4, obj5, obj6; + Object obj1, obj2, obj3, obj4, obj5, obj6; bool bLinearized = false; obj1.initNull(); Parser* parser = new Parser(xref, new Lexer(xref, str->makeSubStream(str->getStart(), gFalse, 0, &obj1)), gTrue); @@ -661,14 +735,14 @@ obj1.free(); bool bTagged = false; Object catDict, markInfoObj; - if (xref->getCatalog(&catDict) && catDict.isDict() && catDict.dictLookup("MarkInfo", &markInfoObj) && markInfoObj.isDict()) + if (xref->getCatalog(&catDict)->isDict() && catDict.dictLookup("MarkInfo", &markInfoObj)->isDict()) { Object marked, suspects; - if (markInfoObj.dictLookup("Marked", &marked) && marked.isBool() && marked.getBool() == gTrue) + if (markInfoObj.dictLookup("Marked", &marked)->isBool() && marked.getBool() == gTrue) { bTagged = true; // If Suspects is true, the document may not completely conform to Tagged PDF conventions. - if (markInfoObj.dictLookup("Suspects", &suspects) && suspects.isBool() && suspects.getBool() == gTrue) + if (markInfoObj.dictLookup("Suspects", &suspects)->isBool() && suspects.getBool() == gTrue) bTagged = false; } marked.free(); @@ -681,17 +755,15 @@ obj1.free(); return sRes; } -void getBookmars(PDFDoc* pdfDoc, OutlineItem* pOutlineItem, NSWasm::CData& out, int level) +std::wstring CPdfReader::GetFontPath(const std::wstring& wsFontName, bool bSave) +{ + std::map::const_iterator oIter = m_mFonts.find(wsFontName); + return oIter == m_mFonts.end() ? std::wstring() : oIter->second; +} +void getBookmarks(PDFDoc* pdfDoc, OutlineItem* pOutlineItem, NSWasm::CData& out, int level) { - int nLengthTitle = pOutlineItem->getTitleLength(); - Unicode* pTitle = pOutlineItem->getTitle(); - std::string sTitle = NSStringExt::CConverter::GetUtf8FromUTF32(pTitle, nLengthTitle); - LinkAction* pLinkAction = pOutlineItem->getAction(); - if (!pLinkAction) - return; - LinkActionKind kind = pLinkAction->getKind(); - if (kind != actionGoTo) + if (!pLinkAction || pLinkAction->getKind() != actionGoTo) return; GString* str = ((LinkGoTo*)pLinkAction)->getNamedDest(); @@ -708,14 +780,25 @@ void getBookmars(PDFDoc* pdfDoc, OutlineItem* pOutlineItem, NSWasm::CData& out, pg = pLinkDest->getPageNum(); if (pg == 0) pg = 1; + double dy = 0; double dTop = pLinkDest->getTop(); double dHeight = pdfDoc->getPageCropHeight(pg); + /* + if (pdfDoc->getPageRotate(pg) % 180 != 0) + { + dHeight = pdfDoc->getPageCropWidth(pg); + dTop = pLinkDest->getLeft(); + } + */ if (dTop > 0 && dTop < dHeight) dy = dHeight - dTop; + if (str) RELEASEOBJECT(pLinkDest); + std::string sTitle = NSStringExt::CConverter::GetUtf8FromUTF32(pOutlineItem->getTitle(), pOutlineItem->getTitleLength()); + out.AddInt(pg - 1); out.AddInt(level); out.AddDouble(dy); @@ -724,13 +807,15 @@ void getBookmars(PDFDoc* pdfDoc, OutlineItem* pOutlineItem, NSWasm::CData& out, pOutlineItem->open(); GList* pList = pOutlineItem->getKids(); if (!pList) + { + pOutlineItem->close(); return; + } for (int i = 0, num = pList->getLength(); i < num; i++) { OutlineItem* pOutlineItemKid = (OutlineItem*)pList->get(i); - if (!pOutlineItemKid) - continue; - getBookmars(pdfDoc, pOutlineItemKid, out, level + 1); + if (pOutlineItemKid) + getBookmarks(pdfDoc, pOutlineItemKid, out, level + 1); } pOutlineItem->close(); } @@ -747,12 +832,11 @@ BYTE* CPdfReader::GetStructure() NSWasm::CData oRes; oRes.SkipLen(); - int num = pList->getLength(); - for (int i = 0; i < num; i++) + for (int i = 0, num = pList->getLength(); i < num; i++) { OutlineItem* pOutlineItem = (OutlineItem*)pList->get(i); if (pOutlineItem) - getBookmars(m_pPDFDocument, pOutlineItem, oRes, 1); + getBookmarks(m_pPDFDocument, pOutlineItem, oRes, 1); } oRes.WriteLen(); @@ -762,68 +846,97 @@ BYTE* CPdfReader::GetStructure() } BYTE* CPdfReader::GetLinks(int nPageIndex) { - if (!m_pPDFDocument) + if (!m_pPDFDocument || !m_pPDFDocument->getCatalog()) return NULL; nPageIndex++; + Page* pPage = m_pPDFDocument->getCatalog()->getPage(nPageIndex); + if (!pPage) + return NULL; NSWasm::CPageLink oLinks; - double height = m_pPDFDocument->getPageCropHeight(nPageIndex); // Гиперссылка Links* pLinks = m_pPDFDocument->getLinks(nPageIndex); - if (!pLinks) - return NULL; - - int num = pLinks->getNumLinks(); - for (int i = 0; i < num; i++) + if (pLinks) { - Link* pLink = pLinks->getLink(i); - if (!pLink) - continue; + PDFRectangle* cropBox = pPage->getCropBox(); + for (int i = 0, num = pLinks->getNumLinks(); i < num; i++) + { + Link* pLink = pLinks->getLink(i); + if (!pLink) + continue; - GString* str = NULL; - double x1 = 0.0, y1 = 0.0, x2 = 0.0, y2 = 0.0, dy = 0.0; - pLink->getRect(&x1, &y1, &x2, &y2); - y1 = height - y1; - y2 = height - y2; + GString* str = NULL; + double x1 = 0.0, y1 = 0.0, x2 = 0.0, y2 = 0.0, dy = 0.0; + pLink->getRect(&x1, &y1, &x2, &y2); + x1 = x1 - cropBox->x1; + y1 = cropBox->y2 - y1; + x2 = x2 - cropBox->x1; + y2 = cropBox->y2 - y2; - LinkAction* pLinkAction = pLink->getAction(); - if (!pLinkAction) - continue; - LinkActionKind kind = pLinkAction->getKind(); - if (kind == actionGoTo) - { - str = ((LinkGoTo*)pLinkAction)->getNamedDest(); - LinkDest* pLinkDest = str ? m_pPDFDocument->findDest(str) : ((LinkGoTo*)pLinkAction)->getDest()->copy(); - if (pLinkDest) + LinkAction* pLinkAction = pLink->getAction(); + if (!pLinkAction) + continue; + LinkActionKind kind = pLinkAction->getKind(); + if (kind == actionGoTo) { - int pg; - if (pLinkDest->isPageRef()) + str = ((LinkGoTo*)pLinkAction)->getNamedDest(); + LinkDest* pLinkDest = str ? m_pPDFDocument->findDest(str) : ((LinkGoTo*)pLinkAction)->getDest()->copy(); + if (pLinkDest) { - Ref pageRef = pLinkDest->getPageRef(); - pg = m_pPDFDocument->findPage(pageRef.num, pageRef.gen); + int pg; + if (pLinkDest->isPageRef()) + { + Ref pageRef = pLinkDest->getPageRef(); + pg = m_pPDFDocument->findPage(pageRef.num, pageRef.gen); + } + else + pg = pLinkDest->getPageNum(); + if (0 == pg) + ++pg; + + std::string sLink = "#" + std::to_string(pg - 1); + str = new GString(sLink.c_str()); + dy = m_pPDFDocument->getPageCropHeight(pg) - pLinkDest->getTop(); } else - pg = pLinkDest->getPageNum(); + str = NULL; + RELEASEOBJECT(pLinkDest); + } + else if (kind == actionURI) + str = ((LinkURI*)pLinkAction)->getURI()->copy(); + else if (kind == actionNamed) + { + str = ((LinkNamed*)pLinkAction)->getName(); + int pg = 1; + if (!str->cmp("NextPage")) + { + pg = nPageIndex + 1; + if (pg > m_pPDFDocument->getNumPages()) + pg = m_pPDFDocument->getNumPages(); + } + else if (!str->cmp("PrevPage")) + { + pg = nPageIndex - 1; + if (pg < 1) + pg = 1; + } + else if (!str->cmp("LastPage")) + pg = m_pPDFDocument->getNumPages(); + std::string sLink = "#" + std::to_string(pg - 1); str = new GString(sLink.c_str()); - dy = m_pPDFDocument->getPageCropHeight(pg) - pLinkDest->getTop(); } - else - str = NULL; - RELEASEOBJECT(pLinkDest); - } - else if (kind == actionURI) - str = ((LinkURI*)pLinkAction)->getURI()->copy(); - oLinks.m_arLinks.push_back({str ? std::string(str->getCString(), str->getLength()) : "", dy, x1, y2, x2 - x1, y1 - y2}); - RELEASEOBJECT(str); + oLinks.m_arLinks.push_back({str ? std::string(str->getCString(), str->getLength()) : "", dy, x1, y2, x2 - x1, y1 - y2}); + RELEASEOBJECT(str); + } } RELEASEOBJECT(pLinks); int nRotate = 0; -#if 0 //#ifdef BUILDING_WASM_MODULE +#ifdef BUILDING_WASM_MODULE nRotate = -m_pPDFDocument->getPageRotate(nPageIndex); #endif @@ -843,6 +956,7 @@ BYTE* CPdfReader::GetLinks(int nPageIndex) if (!sLink) continue; std::string link(sLink->getCString(), sLink->getLength()); + RELEASEOBJECT(sLink); size_t find = link.find("http://"); if (find == std::string::npos) find = link.find("https://"); @@ -856,6 +970,7 @@ BYTE* CPdfReader::GetLinks(int nPageIndex) oLinks.m_arLinks.push_back({link, 0, x1, y1, x2 - x1, y2 - y1}); } } + RELEASEOBJECT(pWordList); RELEASEOBJECT(pTextOut); return oLinks.Serialize(); @@ -864,16 +979,13 @@ BYTE* CPdfReader::GetWidgets() { if (!m_pPDFDocument || !m_pPDFDocument->getCatalog()) return NULL; - - AcroForm* pAcroForms = m_pPDFDocument->getCatalog()->getForm(); - XRef* xref = m_pPDFDocument->getXRef(); - if (!pAcroForms || !xref) + if (!m_pPDFDocument->getCatalog()->getForm() || !m_pPDFDocument->getXRef()) return NULL; NSWasm::CData oRes; oRes.SkipLen(); - PdfReader::CAnnots* pAnnots = new PdfReader::CAnnots(m_pPDFDocument); + PdfReader::CAnnots* pAnnots = new PdfReader::CAnnots(m_pPDFDocument, m_pFontManager, m_pFontList); if (pAnnots) pAnnots->ToWASM(oRes); RELEASEOBJECT(pAnnots); @@ -883,6 +995,39 @@ BYTE* CPdfReader::GetWidgets() oRes.ClearWithoutAttack(); return bRes; } +BYTE* CPdfReader::GetFonts(bool bStandart) +{ + NSWasm::CData oRes; + oRes.SkipLen(); + + int nFonts = 0; + int nFontsPos = oRes.GetSize(); + oRes.AddInt(nFonts); + + for (std::map::iterator it = m_mFonts.begin(); it != m_mFonts.end(); ++it) + { + if (PdfReader::CAnnotFonts::IsBaseFont(it->second)) + { + if (bStandart) + { + oRes.WriteString(it->first); + nFonts++; + } + } + else if (!bStandart) + { + oRes.WriteString(it->first); + nFonts++; + } + } + + oRes.AddInt(nFonts, nFontsPos); + + oRes.WriteLen(); + BYTE* bRes = oRes.GetBuffer(); + oRes.ClearWithoutAttack(); + return bRes; +} BYTE* CPdfReader::VerifySign(const std::wstring& sFile, ICertificate* pCertificate, int nWidget) { if (!m_pPDFDocument || !m_pPDFDocument->getCatalog()) @@ -970,14 +1115,9 @@ BYTE* CPdfReader::GetAPWidget(int nRasterW, int nRasterH, int nBackgroundColor, return NULL; AcroForm* pAcroForms = m_pPDFDocument->getCatalog()->getForm(); - Page* pPage = m_pPDFDocument->getCatalog()->getPage(nPageIndex + 1); - if (!pAcroForms || !pPage) + if (!pAcroForms) return NULL; - double dPageDpiX, dPageDpiY; - double dWidth, dHeight; - GetPageInfo(nPageIndex, &dWidth, &dHeight, &dPageDpiX, &dPageDpiY); - NSWasm::CData oRes; oRes.SkipLen(); @@ -1003,20 +1143,15 @@ BYTE* CPdfReader::GetAPWidget(int nRasterW, int nRasterH, int nBackgroundColor, oRes.ClearWithoutAttack(); return bRes; } -BYTE* CPdfReader::GetButtonIcon(int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex, bool bBase64, int nButtonWidget, const char* sIconView) +BYTE* CPdfReader::GetButtonIcon(int nBackgroundColor, int nPageIndex, bool bBase64, int nButtonWidget, const char* sIconView) { if (!m_pPDFDocument || !m_pPDFDocument->getCatalog()) return NULL; AcroForm* pAcroForms = m_pPDFDocument->getCatalog()->getForm(); - Page* pPage = m_pPDFDocument->getCatalog()->getPage(nPageIndex + 1); - if (!pAcroForms || !pPage) + if (!pAcroForms) return NULL; - double dPageDpiX, dPageDpiY; - double dWidth, dHeight; - GetPageInfo(nPageIndex, &dWidth, &dHeight, &dPageDpiX, &dPageDpiY); - NSWasm::CData oRes; oRes.SkipLen(); @@ -1027,9 +1162,6 @@ BYTE* CPdfReader::GetButtonIcon(int nRasterW, int nRasterH, int nBackgroundColor if (pField->getPageNum() != nPageIndex + 1 || pField->getAcroFormFieldType() != acroFormFieldPushbutton || (nButtonWidget >= 0 && i != nButtonWidget)) continue; - bool bFirst = true; - int nMKPos = -1; - unsigned int nMKLength = 0; Object oMK; if (!pField->fieldLookup("MK", &oMK)->isDict()) { @@ -1037,6 +1169,9 @@ BYTE* CPdfReader::GetButtonIcon(int nRasterW, int nRasterH, int nBackgroundColor continue; } + bool bFirst = true; + int nMKPos = -1; + unsigned int nMKLength = 0; std::vector arrMKName { "I", "RI", "IX" }; for (unsigned int j = 0; j < arrMKName.size(); ++j) { @@ -1057,236 +1192,41 @@ BYTE* CPdfReader::GetButtonIcon(int nRasterW, int nRasterH, int nBackgroundColor // Номер аннотации для сопоставления с AP oRes.AddInt(oFieldRef.getRefNum()); oFieldRef.free(); - nMKPos = oRes.GetSize(); + // Количество иконок 1-3 + nMKPos = oRes.GetSize(); oRes.AddInt(nMKLength); bFirst = false; } - oRes.WriteString((BYTE*)sMKName.c_str(), (unsigned int)sMKName.size()); - - // Resources - Dict* oStreamDict = oStr.streamGetDict(); - Object oResources; - oStreamDict->lookup("Resources", &oResources); - Dict* oResourcesDict = oResources.isDict() ? oResources.getDict() : (Dict *)NULL; - // Получение единственного XObject из Resources, если возможно - bool bImage = false; - Object oXObject, oIm; - if (oResourcesDict && oResourcesDict->lookup("XObject", &oXObject)->isDict() && oXObject.dictGetLength() == 1 && oXObject.dictGetVal(0, &oIm)->isStream()) + Object oResources, oXObject, oIm; + if (!oStr.streamGetDict()->lookup("Resources", &oResources)->isDict() || !oResources.dictLookup("XObject", &oXObject)->isDict() || oXObject.dictGetLength() != 1 || !oXObject.dictGetVal(0, &oIm)->isStream()) { - Dict *oImDict = oIm.streamGetDict(); - Object oType, oSubtype; - if (oImDict->lookup("Type", &oType)->isName("XObject") && oImDict->lookup("Subtype", &oSubtype)->isName("Image")) - { - bImage = true; - - Object oStrRef; - oXObject.dictGetValNF(0, &oStrRef); - int nView = oStrRef.getRefNum(); - oRes.AddInt(nView); - oStrRef.free(); - if (std::find(arrUniqueImage.begin(), arrUniqueImage.end(), nView) != arrUniqueImage.end()) - { - oStr.free(); oResources.free(); - oType.free(); oSubtype.free(); - oXObject.free(); oIm.free(); - oRes.WriteBYTE(0); - nMKLength++; - continue; - } - arrUniqueImage.push_back(nView); - oRes.WriteBYTE(1); - - // Width & Height - Object oWidth, oHeight; - int nWidth = 0; - int nHeight = 0; - if (oImDict->lookup("Width", &oWidth)->isInt() && oImDict->lookup("Height", &oHeight)->isInt()) - { - nWidth = oWidth.getInt(); - nHeight = oHeight.getInt(); - } - oRes.AddInt(nWidth); - oRes.AddInt(nHeight); - oWidth.free(); oHeight.free(); - - if (bBase64) - { - int nLength = 0; - Object oLength; - if (oImDict->lookup("Length", &oLength)->isInt()) - nLength = oLength.getInt(); - oLength.free(); - if (oImDict->lookup("DL", &oLength)->isInt()) - nLength = oLength.getInt(); - oLength.free(); - - bool bNew = false; - BYTE* pBuffer = NULL; - Stream* pImage = oIm.getStream()->getUndecodedStream(); - pImage->reset(); - MemStream* pMemory = dynamic_cast(pImage); - if (pImage->getKind() == strWeird && pMemory) - { - if (pMemory->getBufPtr() + nLength == pMemory->getBufEnd()) - pBuffer = (BYTE*)pMemory->getBufPtr(); - else - nLength = 0; - } - else - { - bNew = true; - pBuffer = new BYTE[nLength]; - BYTE* pBufferPtr = pBuffer; - for (int nI = 0; nI < nLength; ++nI) - *pBufferPtr++ = (BYTE)pImage->getChar(); - } - - char* cData64 = NULL; - int nData64Dst = 0; - NSFile::CBase64Converter::Encode(pBuffer, nLength, cData64, nData64Dst, NSBase64::B64_BASE64_FLAG_NOCRLF); - - oRes.WriteString((BYTE*)cData64, nData64Dst); - - nMKLength++; - if (bNew) - RELEASEARRAYOBJECTS(pBuffer); - RELEASEARRAYOBJECTS(cData64); - continue; - } - - BYTE* pBgraData = new BYTE[nWidth * nHeight * 4]; - unsigned int nColor = (unsigned int)nBackgroundColor; - unsigned int nSize = (unsigned int)(nWidth * nHeight); - unsigned int* pTemp = (unsigned int*)pBgraData; - for (unsigned int k = 0; k < nSize; ++k) - *pTemp++ = nColor; - - int bits = 0; - StreamColorSpaceMode csMode = streamCSNone; - oIm.getStream()->getImageParams(&bits, &csMode); - - if (bits == 0) - { - Object oBits; - if (oImDict->lookup("BitsPerComponent", &oBits)->isNull()) - { - oBits.free(); - oImDict->lookup("BPC", &oBits); - } - bits = oBits.isInt() ? oBits.getInt() : 8; - oBits.free(); - } - - GfxColorSpace* colorSpace = NULL; - Object oColorSpace; - if (oImDict->lookup("ColorSpace", &oColorSpace)->isNull()) - { - oColorSpace.free(); - oImDict->lookup("CS", &oColorSpace); - } - if (oColorSpace.isName()) - { - // TODO - } - if (!oColorSpace.isNull()) - colorSpace = GfxColorSpace::parse(&oColorSpace); - else if (csMode == streamCSDeviceGray) - colorSpace = GfxColorSpace::create(csDeviceGray); - else if (csMode == streamCSDeviceRGB) - colorSpace = GfxColorSpace::create(csDeviceRGB); - else if (csMode == streamCSDeviceCMYK) - colorSpace = GfxColorSpace::create(csDeviceCMYK); - else - colorSpace = NULL; - oColorSpace.free(); - - Object oDecode; - if (oImDict->lookup("Decode", &oDecode)->isNull()) - { - oDecode.free(); - oImDict->lookup("D", &oDecode); - } - - GfxImageColorMap* pColorMap = new GfxImageColorMap(bits, &oDecode, colorSpace); - oDecode.free(); - - ImageStream *pImageStream = new ImageStream(oIm.getStream(), nWidth, pColorMap->getNumPixelComps(), pColorMap->getBits()); - pImageStream->reset(); - - int nComps = pImageStream->getComps(); - int nCheckWidth = std::min(nWidth, pImageStream->getVals() / nComps); - - int nColorMapType = pColorMap->getFillType(); - GfxColorComp** pColorMapLookup = pColorMap->getLookup(); - if (!pColorMapLookup) - nColorMapType = 0; - - for (int nY = 0; nY < nHeight; ++nY) - { - unsigned char* pLine = pImageStream->getLine(); - unsigned char* pLineDst = pBgraData + 4 * nWidth * nY; - - if (!pLine) - { - memset(pLineDst, 0, 4 * nWidth); - continue; - } - - for (int nX = 0; nX < nCheckWidth; ++nX) - { - if (2 == nColorMapType) - { - pLineDst[0] = colToByte(clip01(pColorMapLookup[0][pLine[0]])); - pLineDst[1] = colToByte(clip01(pColorMapLookup[1][pLine[1]])); - pLineDst[2] = colToByte(clip01(pColorMapLookup[2][pLine[2]])); - } - else if (1 == nColorMapType) - { - pLineDst[0] = pLineDst[1] = pLineDst[2] = colToByte(clip01(pColorMapLookup[0][pLine[0]])); - } - else - { - GfxRGB oRGB; - pColorMap->getRGB(pLine, &oRGB, gfxRenderingIntentAbsoluteColorimetric); - pLineDst[0] = colToByte(oRGB.r); - pLineDst[1] = colToByte(oRGB.g); - pLineDst[2] = colToByte(oRGB.b); - } - - pLineDst[3] = 255; - pLine += nComps; - pLineDst += 4; - } - } - delete pColorMap; - - nMKLength++; - unsigned long long npSubMatrix = (unsigned long long)pBgraData; - unsigned int npSubMatrix1 = npSubMatrix & 0xFFFFFFFF; - oRes.AddInt(npSubMatrix1); - oRes.AddInt(npSubMatrix >> 32); - } - oType.free(); oSubtype.free(); + oStr.free(); oResources.free(); oXObject.free(); oIm.free(); + continue; } - oXObject.free(); oIm.free(); + oStr.free(); oResources.free(); - // else - if (bImage) + Dict *oImDict = oIm.streamGetDict(); + Object oType, oSubtype; + if (!oImDict->lookup("Type", &oType)->isName("XObject") || !oImDict->lookup("Subtype", &oSubtype)->isName("Image")) { - oStr.free(); oResources.free(); + oType.free(); oSubtype.free(); + oXObject.free(); oIm.free(); continue; } + oType.free(); oSubtype.free(); + oRes.WriteString(sMKName); Object oStrRef; - oMK.dictLookupNF(sMKName.c_str(), &oStrRef); + oXObject.dictGetValNF(0, &oStrRef); int nView = oStrRef.getRefNum(); oRes.AddInt(nView); + oStrRef.free(); oXObject.free(); if (std::find(arrUniqueImage.begin(), arrUniqueImage.end(), nView) != arrUniqueImage.end()) { - oStr.free(); oStrRef.free(); oResources.free(); + oIm.free(); oRes.WriteBYTE(0); nMKLength++; continue; @@ -1294,52 +1234,65 @@ BYTE* CPdfReader::GetButtonIcon(int nRasterW, int nRasterH, int nBackgroundColor arrUniqueImage.push_back(nView); oRes.WriteBYTE(1); - // BBox - Object bboxObj; - double bbox[4]; - if (oStreamDict->lookup("BBox", &bboxObj)->isArray()) - { - for (int k = 0; k < 4; ++k) - { - Object obj1; - bboxObj.arrayGet(k, &obj1); - bbox[k] = obj1.getNum(); - obj1.free(); - } - } - else + // Width & Height + Object oWidth, oHeight; + int nWidth = 0; + int nHeight = 0; + if (oImDict->lookup("Width", &oWidth)->isInt() && oImDict->lookup("Height", &oHeight)->isInt()) { - bbox[0] = 0; bbox[1] = 0; - bbox[2] = 0; bbox[3] = 0; + nWidth = oWidth.getInt(); + nHeight = oHeight.getInt(); } - bboxObj.free(); + oRes.AddInt(nWidth); + oRes.AddInt(nHeight); + oWidth.free(); oHeight.free(); - // Matrix - double m[6]; - Object matrixObj; - if (oStreamDict->lookup("Matrix", &matrixObj)->isArray()) + if (bBase64) { - for (int k = 0; k < 6; ++k) + int nLength = 0; + Object oLength; + if (oImDict->lookup("Length", &oLength)->isInt()) + nLength = oLength.getInt(); + oLength.free(); + if (oImDict->lookup("DL", &oLength)->isInt()) + nLength = oLength.getInt(); + oLength.free(); + + bool bNew = false; + BYTE* pBuffer = NULL; + Stream* pImage = oIm.getStream()->getUndecodedStream(); + pImage->reset(); + MemStream* pMemory = dynamic_cast(pImage); + if (pImage->getKind() == strWeird && pMemory) { - Object obj1; - matrixObj.arrayGet(k, &obj1); - m[k] = obj1.getNum(); - obj1.free(); + if (pMemory->getBufPtr() + nLength == pMemory->getBufEnd()) + pBuffer = (BYTE*)pMemory->getBufPtr(); + else + nLength = 0; + } + else + { + bNew = true; + pBuffer = new BYTE[nLength]; + BYTE* pBufferPtr = pBuffer; + for (int nI = 0; nI < nLength; ++nI) + *pBufferPtr++ = (BYTE)pImage->getChar(); } - } - else - { - m[0] = 1; m[1] = 0; - m[2] = 0; m[3] = 1; - m[4] = 0; m[5] = 0; - } - matrixObj.free(); - int nWidth = (bbox[2] > 0) ? (int)round(bbox[2] * (double)nRasterW / dWidth) : (int)((int)dWidth * 96 / dPageDpiX); - int nHeight = (bbox[3] > 0) ? (int)round(bbox[3] * (double)nRasterH / dHeight): (int)((int)dHeight * 96 / dPageDpiY); - oRes.AddInt(nWidth); - oRes.AddInt(nHeight); + char* cData64 = NULL; + int nData64Dst = 0; + NSFile::CBase64Converter::Encode(pBuffer, nLength, cData64, nData64Dst, NSBase64::B64_BASE64_FLAG_NOCRLF); + oRes.WriteString((BYTE*)cData64, nData64Dst); + + nMKLength++; + if (bNew) + RELEASEARRAYOBJECTS(pBuffer); + RELEASEARRAYOBJECTS(cData64); + continue; + } + + // else BYTE* pBgraData = new BYTE[nWidth * nHeight * 4]; unsigned int nColor = (unsigned int)nBackgroundColor; unsigned int nSize = (unsigned int)(nWidth * nHeight); @@ -1347,65 +1300,112 @@ BYTE* CPdfReader::GetButtonIcon(int nRasterW, int nRasterH, int nBackgroundColor for (unsigned int k = 0; k < nSize; ++k) *pTemp++ = nColor; - CBgraFrame* pFrame = new CBgraFrame(); - pFrame->put_Data(pBgraData); - pFrame->put_Width(nWidth); - pFrame->put_Height(nHeight); - pFrame->put_Stride(4 * nWidth); + int bits = 0; + StreamColorSpaceMode csMode = streamCSNone; + oIm.getStream()->getImageParams(&bits, &csMode); + + if (bits == 0) + { + Object oBits; + if (oImDict->lookup("BitsPerComponent", &oBits)->isNull()) + { + oBits.free(); + oImDict->lookup("BPC", &oBits); + } + bits = oBits.isInt() ? oBits.getInt() : 8; + oBits.free(); + } - NSGraphics::IGraphicsRenderer* pRenderer = NSGraphics::Create(); - pRenderer->SetFontManager(m_pFontManager); - pRenderer->CreateFromBgraFrame(pFrame); - pRenderer->SetSwapRGB(true); - pRenderer->put_Width (bbox[2] * 25.4 / dPageDpiX); - pRenderer->put_Height(bbox[3] * 25.4 / dPageDpiX); - if (nBackgroundColor != 0xFFFFFF) - pRenderer->CommandLong(c_nDarkMode, 1); + GfxColorSpace* colorSpace = NULL; + Object oColorSpace; + if (oImDict->lookup("ColorSpace", &oColorSpace)->isNull()) + { + oColorSpace.free(); + oImDict->lookup("CS", &oColorSpace); + } + if (oColorSpace.isName()) + { + // TODO + } + if (!oColorSpace.isNull()) + colorSpace = GfxColorSpace::parse(&oColorSpace); + else if (csMode == streamCSDeviceGray) + colorSpace = GfxColorSpace::create(csDeviceGray); + else if (csMode == streamCSDeviceRGB) + colorSpace = GfxColorSpace::create(csDeviceRGB); + else if (csMode == streamCSDeviceCMYK) + colorSpace = GfxColorSpace::create(csDeviceCMYK); + else + colorSpace = NULL; + oColorSpace.free(); - PdfReader::RendererOutputDev oRendererOut(pRenderer, m_pFontManager, m_pFontList); - oRendererOut.NewPDF(m_pPDFDocument->getXRef()); + Object oDecode; + if (oImDict->lookup("Decode", &oDecode)->isNull()) + { + oDecode.free(); + oImDict->lookup("D", &oDecode); + } - // Создание Gfx - GBool crop = gTrue; - PDFRectangle box; - pPage->makeBox(72.0, 72.0, 0, gFalse, oRendererOut.upsideDown(), -1, -1, -1, -1, &box, &crop); - PDFRectangle* cropBox = pPage->getCropBox(); + GfxImageColorMap* pColorMap = new GfxImageColorMap(bits, &oDecode, colorSpace); + oDecode.free(); - Gfx* gfx = new Gfx(m_pPDFDocument, &oRendererOut, nPageIndex + 1, pPage->getAttrs()->getResourceDict(), 72.0, 72.0, &box, cropBox ? cropBox : (PDFRectangle *)NULL, 0, NULL, NULL); + ImageStream *pImageStream = new ImageStream(oIm.getStream(), nWidth, pColorMap->getNumPixelComps(), pColorMap->getBits()); + pImageStream->reset(); - pRenderer->SetCoordTransformOffset(0, bbox[3] * (double)nRasterH / dHeight - nRasterH); - gfx->drawForm(&oStrRef, oResourcesDict, m, bbox, gFalse, gFalse, gFalse, gFalse); - oStr.free(); oStrRef.free(); oResources.free(); + int nComps = pImageStream->getComps(); + int nCheckWidth = std::min(nWidth, pImageStream->getVals() / nComps); - nMKLength++; + int nColorMapType = pColorMap->getFillType(); + GfxColorComp** pColorMapLookup = pColorMap->getLookup(); + if (!pColorMapLookup) + nColorMapType = 0; - if (bBase64) + for (int nY = 0; nY < nHeight; ++nY) { - BYTE* pPngBuffer = NULL; - int nPngSize = 0; - pFrame->Encode(pPngBuffer, nPngSize, 4); + unsigned char* pLine = pImageStream->getLine(); + unsigned char* pLineDst = pBgraData + 4 * nWidth * nY; - char* cData64 = NULL; - int nData64Dst = 0; - NSFile::CBase64Converter::Encode(pPngBuffer, nPngSize, cData64, nData64Dst, NSBase64::B64_BASE64_FLAG_NOCRLF); + if (!pLine) + { + memset(pLineDst, 0, 4 * nWidth); + continue; + } - oRes.WriteString((BYTE*)cData64, nData64Dst); + for (int nX = 0; nX < nCheckWidth; ++nX) + { + if (2 == nColorMapType) + { + pLineDst[0] = colToByte(clip01(pColorMapLookup[0][pLine[0]])); + pLineDst[1] = colToByte(clip01(pColorMapLookup[1][pLine[1]])); + pLineDst[2] = colToByte(clip01(pColorMapLookup[2][pLine[2]])); + } + else if (1 == nColorMapType) + { + pLineDst[0] = pLineDst[1] = pLineDst[2] = colToByte(clip01(pColorMapLookup[0][pLine[0]])); + } + else + { + GfxRGB oRGB; + pColorMap->getRGB(pLine, &oRGB, gfxRenderingIntentAbsoluteColorimetric); + pLineDst[0] = colToByte(oRGB.r); + pLineDst[1] = colToByte(oRGB.g); + pLineDst[2] = colToByte(oRGB.b); + } - RELEASEARRAYOBJECTS(cData64); + pLineDst[3] = 255; + pLine += nComps; + pLineDst += 4; + } } - else - { - unsigned long long npSubMatrix = (unsigned long long)pBgraData; - unsigned int npSubMatrix1 = npSubMatrix & 0xFFFFFFFF; - oRes.AddInt(npSubMatrix1); - oRes.AddInt(npSubMatrix >> 32); + delete pColorMap; - pFrame->ClearNoAttack(); - } + nMKLength++; + unsigned long long npSubMatrix = (unsigned long long)pBgraData; + unsigned int npSubMatrix1 = npSubMatrix & 0xFFFFFFFF; + oRes.AddInt(npSubMatrix1); + oRes.AddInt(npSubMatrix >> 32); - delete gfx; - RELEASEOBJECT(pFrame); - RELEASEOBJECT(pRenderer); + oIm.free(); } oMK.free(); @@ -1418,7 +1418,7 @@ BYTE* CPdfReader::GetButtonIcon(int nRasterW, int nRasterH, int nBackgroundColor oRes.ClearWithoutAttack(); return bRes; } -void GetPageAnnots(PDFDoc* pdfDoc, NSWasm::CData& oRes, int nPageIndex) +void GetPageAnnots(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, PdfReader::CPdfFontList *pFontList, NSWasm::CData& oRes, int nPageIndex) { Page* pPage = pdfDoc->getCatalog()->getPage(nPageIndex + 1); if (!pPage) @@ -1433,21 +1433,20 @@ void GetPageAnnots(PDFDoc* pdfDoc, NSWasm::CData& oRes, int nPageIndex) for (int i = 0, nNum = oAnnots.arrayGetLength(); i < nNum; ++i) { - // Ходовые объекты - Object oObj, oObj2; - - Object oAnnot, oAnnotRef; + Object oAnnot; if (!oAnnots.arrayGet(i, &oAnnot)->isDict()) { oAnnot.free(); continue; } + Object oSubtype; std::string sType; - if (oAnnot.dictLookup("Subtype", &oObj)->isName()) - sType = oObj.getName(); - oObj.free(); oAnnot.free(); + if (oAnnot.dictLookup("Subtype", &oSubtype)->isName()) + sType = oSubtype.getName(); + oSubtype.free(); oAnnot.free(); + Object oAnnotRef; PdfReader::CAnnot* pAnnot = NULL; oAnnots.arrayGetNF(i, &oAnnotRef); if (sType == "Text") @@ -1460,7 +1459,9 @@ void GetPageAnnots(PDFDoc* pdfDoc, NSWasm::CData& oRes, int nPageIndex) } else if (sType == "FreeText") { - pAnnot = new PdfReader::CAnnotFreeText(pdfDoc, &oAnnotRef, nPageIndex); + PdfReader::CAnnotFreeText* pFreeText = new PdfReader::CAnnotFreeText(pdfDoc, &oAnnotRef, nPageIndex); + pFreeText->SetFont(pdfDoc, &oAnnotRef, pFontManager, pFontList); + pAnnot = pFreeText; } else if (sType == "Line") { @@ -1483,7 +1484,7 @@ void GetPageAnnots(PDFDoc* pdfDoc, NSWasm::CData& oRes, int nPageIndex) } else if (sType == "Stamp") { - + pAnnot = new PdfReader::CAnnotStamp(pdfDoc, &oAnnotRef, nPageIndex); } else if (sType == "Caret") { @@ -1493,6 +1494,10 @@ void GetPageAnnots(PDFDoc* pdfDoc, NSWasm::CData& oRes, int nPageIndex) { pAnnot = new PdfReader::CAnnotInk(pdfDoc, &oAnnotRef, nPageIndex); } + // else if (sType == "FileAttachment") + // { + // pAnnot = new PdfReader::CAnnotFileAttachment(pdfDoc, &oAnnotRef, nPageIndex); + // } // else if (sType == "Popup") // { // pAnnot = new PdfReader::CAnnotPopup(pdfDoc, &oAnnotRef, nPageIndex); @@ -1516,14 +1521,68 @@ BYTE* CPdfReader::GetAnnots(int nPageIndex) oRes.SkipLen(); if (nPageIndex >= 0) - GetPageAnnots(m_pPDFDocument, oRes, nPageIndex); + GetPageAnnots(m_pPDFDocument, m_pFontManager, m_pFontList, oRes, nPageIndex); else - { for (int nPage = 0, nLastPage = m_pPDFDocument->getNumPages(); nPage < nLastPage; ++nPage) + GetPageAnnots(m_pPDFDocument, m_pFontManager, m_pFontList, oRes, nPage); + + oRes.WriteLen(); + BYTE* bRes = oRes.GetBuffer(); + oRes.ClearWithoutAttack(); + return bRes; +} +BYTE* CPdfReader::GetShapes(int nPageIndex) +{ + if (!m_pPDFDocument || !m_pPDFDocument->getCatalog()) + return NULL; + Dict* pResources = m_pPDFDocument->getCatalog()->getPage(nPageIndex + 1)->getResourceDict(); + if (!pResources) + return NULL; + + Object oProperties, oMetaOForm, oID; + XRef* xref = m_pPDFDocument->getXRef(); + if (!pResources->lookup("Properties", &oProperties)->isDict() || !oProperties.dictLookup("OShapes", &oMetaOForm)->isDict("OShapes") || !oMetaOForm.dictLookup("ID", &oID)->isString()) + { + oProperties.free(); oMetaOForm.free(); oID.free(); + return NULL; + } + oProperties.free(); + + Object oTID, oID2; + Object* pTrailerDict = xref->getTrailerDict(); + if (!pTrailerDict->dictLookup("ID", &oTID)->isArray() || !oTID.arrayGet(1, &oID2)->isString() || oID2.getString()->cmp(oID.getString()) != 0) + { + oMetaOForm.free(); oID.free(); oTID.free(); oID2.free(); + return NULL; + } + oID.free(); oTID.free(); oID2.free(); + + Object oMetadata; + if (!oMetaOForm.dictLookup("Metadata", &oMetadata)->isArray()) + { + oMetaOForm.free(); oMetadata.free(); + return NULL; + } + oMetaOForm.free(); + + NSWasm::CData oRes; + oRes.SkipLen(); + int nMetadataLength = oMetadata.arrayGetLength(); + oRes.AddInt(nMetadataLength); + + for (int i = 0; i < nMetadataLength; ++i) + { + Object oMetaStr; + std::string sStr; + if (oMetadata.arrayGet(i, &oMetaStr)->isString()) { - GetPageAnnots(m_pPDFDocument, oRes, nPage); + TextString* s = new TextString(oMetaStr.getString()); + sStr = NSStringExt::CConverter::GetUtf8FromUTF32(s->getUnicode(), s->getLength()); + delete s; } + oRes.WriteString(sStr); } + oMetadata.free(); oRes.WriteLen(); BYTE* bRes = oRes.GetBuffer(); @@ -1549,13 +1608,7 @@ BYTE* CPdfReader::GetAPAnnots(int nRasterW, int nRasterH, int nBackgroundColor, for (int i = 0, nNum = oAnnots.arrayGetLength(); i < nNum; ++i) { Object oAnnotRef; - if (!oAnnots.arrayGetNF(i, &oAnnotRef)->isRef()) - { - oAnnotRef.free(); - continue; - } - - if (nAnnot >= 0 && oAnnotRef.getRefNum() != nAnnot) + if (!oAnnots.arrayGetNF(i, &oAnnotRef)->isRef() || (nAnnot >= 0 && oAnnotRef.getRefNum() != nAnnot)) { oAnnotRef.free(); continue; @@ -1589,3 +1642,7 @@ BYTE* CPdfReader::GetAPAnnots(int nRasterW, int nRasterH, int nBackgroundColor, oRes.ClearWithoutAttack(); return bRes; } +std::map CPdfReader::GetAnnotFonts(Object* pRefAnnot) +{ + return PdfReader::CAnnotFonts::GetAnnotFont(m_pPDFDocument, m_pFontManager, m_pFontList, pRefAnnot); +} diff --git a/PdfFile/PdfReader.h b/PdfFile/PdfReader.h index 0dc90aaa272..2cb86aeb755 100644 --- a/PdfFile/PdfReader.h +++ b/PdfFile/PdfReader.h @@ -50,6 +50,7 @@ class CPdfReader void Close(); + void SetParams(COfficeDrawingPageParams* pParams); std::wstring GetTempDirectory(); void SetTempDirectory(const std::wstring& directory); @@ -58,36 +59,41 @@ class CPdfReader void SetCMapFolder(const std::wstring& sFolder); void SetCMapFile(const std::wstring& sFile); + int GetError(); int GetRotate(int nPageIndex); int GetMaxRefID(); + bool ValidMetaData(); void GetPageInfo(int nPageIndex, double* pdWidth, double* pdHeight, double* pdDpiX, double* pdDpiY); void DrawPageOnRenderer(IRenderer* pRenderer, int nPageIndex, bool* pBreak); std::wstring GetInfo(); + std::wstring GetFontPath(const std::wstring& wsFontName, bool bSave = true); - int GetError(); - - NSFonts::IFontManager* GetFontManager() { return m_pFontManager; } std::wstring ToXml(const std::wstring& wsXmlPath, bool isPrintStreams = false); - PDFDoc* GetPDFDocument() { return m_pPDFDocument; } void ChangeLength(DWORD nLength); + NSFonts::IFontManager* GetFontManager() { return m_pFontManager; } + PDFDoc* GetPDFDocument() { return m_pPDFDocument; } BYTE* GetStructure(); BYTE* GetLinks(int nPageIndex); BYTE* GetWidgets(); + BYTE* GetFonts(bool bStandart); BYTE* GetAnnots(int nPageIndex = -1); + BYTE* GetShapes(int nPageIndex); BYTE* VerifySign(const std::wstring& sFile, ICertificate* pCertificate, int nWidget = -1); - BYTE* GetAPWidget (int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex, int nWidget = -1, const char* sView = NULL, const char* sButtonView = NULL); - BYTE* GetButtonIcon(int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex, bool bBase64 = false, int nButtonWidget = -1, const char* sIconView = NULL); - BYTE* GetAPAnnots(int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex, int nAnnot = -1, const char* sView = NULL); + BYTE* GetAPWidget (int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex, int nWidget = -1, const char* sView = NULL, const char* sBView = NULL); + BYTE* GetAPAnnots (int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex, int nAnnot = -1, const char* sView = NULL); + BYTE* GetButtonIcon(int nBackgroundColor, int nPageIndex, bool bBase64 = false, int nBWidget = -1, const char* sIView = NULL); + std::map GetAnnotFonts(Object* pRefAnnot); + std::map GetFonts() { return m_mFonts; } private: - IOfficeDrawingFile* m_pRenderer; - PDFDoc* m_pPDFDocument; - std::wstring m_wsTempFolder; + PDFDoc* m_pPDFDocument; + std::wstring m_wsTempFolder; NSFonts::IFontManager* m_pFontManager; - PdfReader::CFontList* m_pFontList; - DWORD m_nFileLength; - int m_eError; + PdfReader::CPdfFontList* m_pFontList; + DWORD m_nFileLength; + int m_eError; + std::map m_mFonts; }; #endif // _PDF_READER_H diff --git a/PdfFile/PdfWriter.cpp b/PdfFile/PdfWriter.cpp index b185c5e87e1..595defc42f3 100644 --- a/PdfFile/PdfWriter.cpp +++ b/PdfFile/PdfWriter.cpp @@ -29,8 +29,8 @@ * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode * */ -#include "../../DesktopEditor/common/File.h" -#include "../../DesktopEditor/common/Directory.h" +#include "../DesktopEditor/common/File.h" +#include "../DesktopEditor/common/Directory.h" #include "PdfWriter.h" @@ -40,21 +40,24 @@ #include "SrcWriter/Font.h" #include "SrcWriter/FontCidTT.h" #include "SrcWriter/FontTT.h" -#include "SrcWriter/Annotation.h" +#include "SrcWriter/Font14.h" #include "SrcWriter/Destination.h" #include "SrcWriter/Field.h" - -#include "../../DesktopEditor/graphics/Image.h" -#include "../../DesktopEditor/graphics/structures.h" -#include "../../DesktopEditor/raster/BgraFrame.h" -#include "../../DesktopEditor/raster/ImageFileFormatChecker.h" -#include "../../DesktopEditor/graphics/pro/Fonts.h" -#include "../../DesktopEditor/graphics/pro/Image.h" -#include "../../DesktopEditor/common/StringExt.h" -#include "../../DesktopEditor/graphics/GraphicsPath.h" - -#include "../../UnicodeConverter/UnicodeConverter.h" -#include "../../Common/Network/FileTransporter/include/FileTransporter.h" +#include "SrcWriter/Outline.h" + +#include "../DesktopEditor/graphics/Image.h" +#include "../DesktopEditor/graphics/structures.h" +#include "../DesktopEditor/raster/BgraFrame.h" +#include "../DesktopEditor/raster/ImageFileFormatChecker.h" +#include "../DesktopEditor/graphics/pro/Fonts.h" +#include "../DesktopEditor/graphics/pro/Image.h" +#include "../DesktopEditor/common/StringExt.h" +#include "../DesktopEditor/graphics/GraphicsPath.h" +#include "../DesktopEditor/graphics/MetafileToRenderer.h" +#include "../DesktopEditor/raster/Metafile/MetaFileCommon.h" + +#include "../UnicodeConverter/UnicodeConverter.h" +#include "../Common/Network/FileTransporter/include/FileTransporter.h" #if defined(GetTempPath) #undef GetTempPath @@ -71,6 +74,8 @@ #define MM_2_PT(X) ((X) * 72.0 / 25.4) #define PT_2_MM(X) ((X) * 25.4 / 72.0) +#define MM_TO_PT(value) (value * 300.0 / 25.4) + #define LONG_2_BOOL(X) ((X) ? true : false) #ifdef DrawText @@ -90,12 +95,44 @@ static const long c_BrushTypeLinearGradient = 8001; static const long c_BrushTypeRadialGradient = 8002; +Aggplus::CImage* ConvertMetafile(NSFonts::IApplicationFonts* pAppFonts, const std::wstring& wsPath, const std::wstring& wsTempDirectory, double dWidth = -1, double dHeight = -1) +{ + CImageFileFormatChecker oImageFormat(wsPath); + if (_CXIMAGE_FORMAT_WMF == oImageFormat.eFileType || + _CXIMAGE_FORMAT_EMF == oImageFormat.eFileType || + _CXIMAGE_FORMAT_SVM == oImageFormat.eFileType || + _CXIMAGE_FORMAT_SVG == oImageFormat.eFileType) + { + MetaFile::IMetaFile* pMeta = MetaFile::Create(pAppFonts); + + if (NULL == pMeta || !pMeta->LoadFromFile(wsPath.c_str())) + return new Aggplus::CImage(wsPath); + + bool bUseMax = false; + if (dWidth > 5000 || dHeight > 5000) + bUseMax = true; + else if (dWidth <= 0 && dHeight <= 0) + bUseMax = true; + + if (!bUseMax) + pMeta->ConvertToRaster(wsTempDirectory.c_str(), _CXIMAGE_FORMAT_PNG, MM_2_PT(dWidth), MM_2_PT(dHeight)); + else + MetaFile::ConvertToRasterMaxSize(pMeta, wsTempDirectory.c_str(), _CXIMAGE_FORMAT_PNG, 2000); + + RELEASEOBJECT(pMeta); + + return new Aggplus::CImage(wsTempDirectory); + } + + return new Aggplus::CImage(wsPath); +} + //---------------------------------------------------------------------------------------- // // CPdfRenderer // //---------------------------------------------------------------------------------------- -CPdfWriter::CPdfWriter(NSFonts::IApplicationFonts* pAppFonts, bool isPDFA, IRenderer* pRenderer) : m_oCommandManager(this) +CPdfWriter::CPdfWriter(NSFonts::IApplicationFonts* pAppFonts, bool isPDFA, IRenderer* pRenderer, bool bCreate) : m_oCommandManager(this) { // Создаем менеджер шрифтов с собственным кэшем m_pFontManager = pAppFonts->GenerateFontManager(); @@ -109,7 +146,7 @@ CPdfWriter::CPdfWriter(NSFonts::IApplicationFonts* pAppFonts, bool isPDFA, IRend if (isPDFA) m_pDocument->SetPDFAConformanceMode(true); - if (!m_pDocument || !m_pDocument->CreateNew()) + if (!m_pDocument || (bCreate && !m_pDocument->CreateNew())) { SetError(); return; @@ -122,13 +159,11 @@ CPdfWriter::CPdfWriter(NSFonts::IApplicationFonts* pAppFonts, bool isPDFA, IRend m_dPageWidth = 210; m_pPage = NULL; m_pFont = NULL; + m_pFont14 = NULL; + m_lClipMode = 0; - m_unFieldsCounter = 0; - m_bNeedUpdateTextFont = true; - m_bNeedUpdateTextColor = true; - m_bNeedUpdateTextAlpha = true; - m_bNeedUpdateTextCharSpace = true; - m_bNeedUpdateTextSize = true; + m_unFieldsCounter = 0; + m_bNeedUpdateTextFont = true; } CPdfWriter::~CPdfWriter() { @@ -155,6 +190,13 @@ int CPdfWriter::SaveToFile(const std::wstring& wsPath) if (!IsValid()) return 1; + if (!m_pFont && !m_pFont14 && !m_pDocument->IsPDFA()) + { + m_bNeedUpdateTextFont = false; + m_pFont14 = m_pDocument->CreateFont14(L"Helvetica", 0, PdfWriter::EStandard14Fonts::standard14fonts_Helvetica); + CommandDrawTextCHAR(32, 0, 0, 0, 0); + } + m_oCommandManager.Flush(); if (!m_pDocument->SaveToFile(wsPath)) @@ -368,7 +410,6 @@ HRESULT CPdfWriter::put_BrushColor1(const LONG& lColor) if (lColor != m_oBrush.GetColor1()) { m_oBrush.SetColor1(lColor); - m_bNeedUpdateTextColor = true; } return S_OK; } @@ -382,7 +423,6 @@ HRESULT CPdfWriter::put_BrushAlpha1(const LONG& lAlpha) if (lAlpha != m_oBrush.GetAlpha1()) { m_oBrush.SetAlpha1(lAlpha); - m_bNeedUpdateTextAlpha = true; } return S_OK; } @@ -521,7 +561,6 @@ HRESULT CPdfWriter::put_FontSize(const double& dSize) if (fabs(dSize - m_oFont.GetSize()) > 0.001) { m_oFont.SetSize(dSize); - m_bNeedUpdateTextSize = true; } return S_OK; } @@ -559,7 +598,6 @@ HRESULT CPdfWriter::put_FontCharSpace(const double& dSpace) if (fabs(dSpace - m_oFont.GetCharSpace()) > 0.001) { m_oFont.SetCharSpace(dSpace); - m_bNeedUpdateTextCharSpace = true; } return S_OK; } @@ -581,6 +619,19 @@ HRESULT CPdfWriter::put_FontFaceIndex(const int& nFaceIndex) //---------------------------------------------------------------------------------------- // Функции для вывода текста //---------------------------------------------------------------------------------------- +bool UnicodePUA(unsigned int unUnicode) +{ + return (unUnicode >= 0xE000 && unUnicode <= 0xF8FF) || (unUnicode >= 0xF0000 && unUnicode <= 0xFFFFD) || (unUnicode >= 0x100000 && unUnicode <= 0x10FFFD); +} +bool UnicodesPUA(unsigned int* pUnicodes, unsigned int unLen) +{ + for (int i = 0; i < unLen; ++i) + { + if (UnicodePUA(pUnicodes[i])) + return true; + } + return false; +} HRESULT CPdfWriter::CommandDrawTextCHAR(const LONG& lUnicode, const double& dX, const double& dY, const double& dW, const double& dH) { if (!IsPageValid()) @@ -588,7 +639,7 @@ HRESULT CPdfWriter::CommandDrawTextCHAR(const LONG& lUnicode, const double& dX, unsigned int unUnicode = lUnicode; unsigned char* pCodes = EncodeString(&unUnicode, 1); - return DrawText(pCodes, 2, dX, dY) ? S_OK : S_FALSE; + return DrawText(pCodes, 2, dX, dY, UnicodePUA(unUnicode) ? NSStringExt::CConverter::GetUtf8FromUTF32(&unUnicode, 1) : "") ? S_OK : S_FALSE; } HRESULT CPdfWriter::CommandDrawText(const std::wstring& wsUnicodeText, const double& dX, const double& dY, const double& dW, const double& dH) { @@ -601,6 +652,9 @@ HRESULT CPdfWriter::CommandDrawText(const std::wstring& wsUnicodeText, const dou return S_FALSE; unsigned char* pCodes = EncodeString(pUnicodes, unLen); + std::string sPUA; + if (UnicodesPUA(pUnicodes, unLen)) + sPUA = NSStringExt::CConverter::GetUtf8FromUTF32(pUnicodes, unLen); delete[] pUnicodes; if (!pCodes) @@ -637,11 +691,12 @@ HRESULT CPdfWriter::CommandDrawText(const std::wstring& wsUnicodeText, const dou pText->SetMode(PdfWriter::textrenderingmode_Invisible); if (fabs(dStringWidth) > 0.001) pText->SetHorScaling(dResultWidth / dStringWidth * 100); + pText->SetPUA(sPUA); return S_OK; } - return DrawText(pCodes, unLen * 2, dX, dY) ? S_OK : S_FALSE; + return DrawText(pCodes, unLen * 2, dX, dY, sPUA) ? S_OK : S_FALSE; } HRESULT CPdfWriter::CommandDrawTextExCHAR(const LONG& lUnicode, const LONG& lGid, const double& dX, const double& dY, const double& dW, const double& dH) { @@ -653,7 +708,7 @@ HRESULT CPdfWriter::CommandDrawTextExCHAR(const LONG& lUnicode, const LONG& lGid unsigned char* pCodes = EncodeGID(unGID, &unUnicode, 1); if (!pCodes) return DrawTextToRenderer(&unGID, 1, dX, dY) ? S_OK : S_FALSE; - return DrawText(pCodes, 2, dX, dY) ? S_OK : S_FALSE; + return DrawText(pCodes, 2, dX, dY, UnicodePUA(unUnicode) ? NSStringExt::CConverter::GetUtf8FromUTF32(&unUnicode, 1) : "") ? S_OK : S_FALSE; } HRESULT CPdfWriter::CommandDrawTextEx(const std::wstring& wsUnicodeText, const unsigned int* pGids, const unsigned int unGidsCount, const double& dX, const double& dY, const double& dW, const double& dH) { @@ -691,10 +746,13 @@ HRESULT CPdfWriter::CommandDrawTextEx(const std::wstring& wsUnicodeText, const u } unsigned char* pCodes = EncodeString(pUnicodes, unLen, pGids); + std::string sPUA; + if (UnicodesPUA(pUnicodes, unLen)) + sPUA = NSStringExt::CConverter::GetUtf8FromUTF32(pUnicodes, unLen); RELEASEARRAYOBJECTS(pUnicodes); if (!pCodes) return DrawTextToRenderer(pGids, unGidsCount, dX, dY) ? S_OK : S_FALSE; - return DrawText(pCodes, unLen * 2, dX, dY) ? S_OK : S_FALSE; + return DrawText(pCodes, unLen * 2, dX, dY, sPUA) ? S_OK : S_FALSE; } HRESULT CPdfWriter::CommandDrawTextCHAR2(unsigned int* pUnicodes, const unsigned int& unUnicodeCount, const unsigned int& unGid, const double& dX, const double& dY, const double& dW, const double& dH) { @@ -704,12 +762,12 @@ HRESULT CPdfWriter::CommandDrawTextCHAR2(unsigned int* pUnicodes, const unsigned unsigned char* pCodes = EncodeGID(unGid, pUnicodes, unUnicodeCount); if (!pCodes) return DrawTextToRenderer(&unGid, 1, dX, dY) ? S_OK : S_FALSE; - return DrawText(pCodes, 2, dX, dY) ? S_OK : S_FALSE; + return DrawText(pCodes, 2, dX, dY, UnicodesPUA(pUnicodes, unUnicodeCount) ? NSStringExt::CConverter::GetUtf8FromUTF32(pUnicodes, unUnicodeCount) : "") ? S_OK : S_FALSE; } //---------------------------------------------------------------------------------------- // Маркеры команд //---------------------------------------------------------------------------------------- -HRESULT CPdfWriter::EndCommand(const DWORD& dwType, const LONG& lClipMode) +HRESULT CPdfWriter::EndCommand(const DWORD& dwType) { if (!IsPageValid()) return S_FALSE; @@ -722,7 +780,7 @@ HRESULT CPdfWriter::EndCommand(const DWORD& dwType, const LONG& lClipMode) m_lClipDepth++; UpdateTransform(); - m_oPath.Clip(m_pPage, c_nClipRegionTypeEvenOdd & lClipMode); + m_oPath.Clip(m_pPage, c_nClipRegionTypeEvenOdd & m_lClipMode); } else if (c_nResetClipType == dwType) { @@ -825,8 +883,10 @@ HRESULT CPdfWriter::DrawPath(NSFonts::IApplicationFonts* pAppFonts, const std::w { m_oBrush.SetTexturePath(sTextureOldPath); - if (NSFile::CFileBinary::Exists(sTextureTmpPath)) - NSFile::CFileBinary::Remove(sTextureTmpPath); + // We do not delete the temporary file - it will still be used. + // It must be deleted along with the temporary directory + //if (NSFile::CFileBinary::Exists(sTextureTmpPath)) + // NSFile::CFileBinary::Remove(sTextureTmpPath); } return S_OK; @@ -983,37 +1043,26 @@ HRESULT CPdfWriter::DrawImageFromFile(NSFonts::IApplicationFonts* pAppFonts, con if (!IsPageValid()) return S_OK; - std::wstring sTempImagePath = GetDownloadFile(wsImagePathSrc, wsTempDirectory); - std::wstring wsImagePath = sTempImagePath.empty() ? wsImagePathSrc : sTempImagePath; - - Aggplus::CImage* pAggImage = NULL; - - CImageFileFormatChecker oImageFormat(wsImagePath); - if (_CXIMAGE_FORMAT_WMF == oImageFormat.eFileType || - _CXIMAGE_FORMAT_EMF == oImageFormat.eFileType || - _CXIMAGE_FORMAT_SVM == oImageFormat.eFileType || - _CXIMAGE_FORMAT_SVG == oImageFormat.eFileType) + if (m_pDocument->HasImage(wsImagePathSrc, nAlpha)) { - // TODO: Реализовать отрисовку метафайлов по-нормальному - MetaFile::IMetaFile* pMeta = MetaFile::Create(pAppFonts); - pMeta->LoadFromFile(wsImagePath.c_str()); - - double dNewW = std::max(10.0, dW) / 25.4 * 300; - std::wstring wsTempFile = GetTempFile(wsTempDirectory); - pMeta->ConvertToRaster(wsTempFile.c_str(), _CXIMAGE_FORMAT_PNG, dNewW); + PdfWriter::CImageDict* pPdfImage = m_pDocument->GetImage(wsImagePathSrc, nAlpha); + m_pPage->GrSave(); + UpdateTransform(); + m_pPage->DrawImage(pPdfImage, MM_2_PT(dX), MM_2_PT(m_dPageHeight - dY - dH), MM_2_PT(dW), MM_2_PT(dH)); + m_pPage->GrRestore(); + return S_OK; + } - RELEASEOBJECT(pMeta); + std::wstring sTempImagePath = GetDownloadFile(wsImagePathSrc, wsTempDirectory); + std::wstring wsImagePath = sTempImagePath.empty() ? wsImagePathSrc : sTempImagePath; - pAggImage = new Aggplus::CImage(wsTempFile); - } - else - { - pAggImage = new Aggplus::CImage(wsImagePath); - } + Aggplus::CImage* pAggImage = ConvertMetafile(pAppFonts, wsImagePath, GetTempFile(wsTempDirectory), MM_TO_PT(dW), MM_TO_PT(dH)); HRESULT hRes = S_OK; - if (!pAggImage || !DrawImage(pAggImage, dX, dY, dW, dH, nAlpha)) + PdfWriter::CImageDict* pPdfImage = NULL; + if (!pAggImage || !(pPdfImage = DrawImage(pAggImage, dX, dY, dW, dH, nAlpha))) hRes = S_FALSE; + m_pDocument->AddImage(wsImagePathSrc, nAlpha, pPdfImage); if (NSFile::CFileBinary::Exists(sTempImagePath)) NSFile::CFileBinary::Remove(sTempImagePath); @@ -1048,6 +1097,16 @@ HRESULT CPdfWriter::ResetTransform() m_oTransform.Reset(); return S_OK; } +HRESULT CPdfWriter::get_ClipMode(LONG* lMode) +{ + *lMode = m_lClipMode; + return S_OK; +} +HRESULT CPdfWriter::put_ClipMode(const LONG& lMode) +{ + m_lClipMode = lMode; + return S_OK; +} //---------------------------------------------------------------------------------------- // Дополнительные функции //---------------------------------------------------------------------------------------- @@ -1056,7 +1115,7 @@ HRESULT CPdfWriter::AddHyperlink(const double& dX, const double& dY, const doubl NSUnicodeConverter::CUnicodeConverter conv; PdfWriter::CAnnotation* pAnnot = m_pDocument->CreateUriLinkAnnot(PdfWriter::TRect(MM_2_PT(dX), m_pPage->GetHeight() - MM_2_PT(dY), MM_2_PT(dX + dW), m_pPage->GetHeight() - MM_2_PT(dY + dH)), conv.SASLprepToUtf8(wsUrl).c_str()); m_pPage->AddAnnotation(pAnnot); - pAnnot->SetBorder(0, 0); + pAnnot->SetBorder(0, 0, {}); return S_OK; } HRESULT CPdfWriter::AddLink(const double& dX, const double& dY, const double& dW, const double& dH, const double& dDestX, const double& dDestY, const int& nPage) @@ -1079,29 +1138,39 @@ HRESULT CPdfWriter::AddLink(const double& dX, const double& dY, const double& dW } HRESULT CPdfWriter::AddFormField(NSFonts::IApplicationFonts* pAppFonts, CFormFieldInfo* pFieldInfo, const std::wstring& wsTempDirectory) { - unsigned int unPagesCount = m_pDocument->GetPagesCount(); - if (!m_pDocument || 0 == unPagesCount || !pFieldInfo) - return S_OK; - - if (m_bNeedUpdateTextFont) - UpdateFont(); - - if (!m_pFont) - return S_OK; - - PdfWriter::CFontTrueType* pFontTT = m_pDocument->CreateTrueTypeFont(m_pFont); - if (!pFontTT) + if (!m_pDocument || 0 == m_pDocument->GetPagesCount() || !pFieldInfo) return S_OK; - CFormFieldInfo& oInfo = *pFieldInfo; + PdfWriter::CFontCidTrueType* pCheckedFont = NULL; + PdfWriter::CFontCidTrueType* pUncheckedFont = NULL; + if (oInfo.IsCheckBox()) + { + const CFormFieldInfo::CCheckBoxFormPr* pPr = oInfo.GetCheckBoxPr(); + pCheckedFont = GetFont(pPr->GetCheckedFontName(), false, false); + pUncheckedFont = GetFont(pPr->GetUncheckedFontName(), false, false); + } + if ((oInfo.IsCheckBox() && (!pCheckedFont || !pUncheckedFont)) || oInfo.IsTextField() || oInfo.IsDropDownList() || oInfo.IsDateTime()) + { + if (m_bNeedUpdateTextFont) + UpdateFont(); + if (!m_pFont) + return S_OK; + if (oInfo.IsCheckBox()) + { + if (!pCheckedFont) + pCheckedFont = m_pFont; + if (!pUncheckedFont) + pUncheckedFont = m_pFont; + } + } + double dX, dY, dW, dH; oInfo.GetBounds(dX, dY, dW, dH); PdfWriter::CFieldBase* pFieldBase = NULL; bool bRadioButton = false; - if (oInfo.IsTextField()) { PdfWriter::CTextField* pField = m_pDocument->CreateTextField(); @@ -1137,11 +1206,6 @@ HRESULT CPdfWriter::AddFormField(NSFonts::IApplicationFonts* pAppFonts, CFormFie PdfWriter::CPictureField* pField = m_pDocument->CreatePictureField(); pFieldBase = static_cast(pField); } - else if (oInfo.IsSignature()) - { - PdfWriter::CSignatureField* pField = m_pDocument->CreateSignatureField(); - pFieldBase = static_cast(pField); - } else if (oInfo.IsDateTime()) { PdfWriter::CDateTimeField* pField = m_pDocument->CreateDateTimeField(); @@ -1183,52 +1247,23 @@ HRESULT CPdfWriter::AddFormField(NSFonts::IApplicationFonts* pAppFonts, CFormFie bool isBold = m_oFont.IsBold(); bool isItalic = m_oFont.IsItalic(); - if (oInfo.IsTextField()) { const CFormFieldInfo::CTextFormPr* pPr = oInfo.GetTextFormPr(); std::wstring wsValue = pPr->GetTextValue(); - unsigned int unLen; - unsigned int* pUnicodes = NSStringExt::CConverter::GetUtf32FromUnicode(wsValue, unLen); - if (!pUnicodes) - return S_FALSE; - - unsigned short* pCodes = new unsigned short[unLen]; - if (!pCodes) - { - RELEASEARRAYOBJECTS(pUnicodes); - return S_FALSE; - } - - PdfWriter::CFontCidTrueType** ppFonts = new PdfWriter::CFontCidTrueType*[unLen]; - if (!ppFonts) + unsigned int unLen = 0; + unsigned int* pUnicodes = NULL; + unsigned short* pCodes = NULL; + PdfWriter::CFontCidTrueType** ppFonts = NULL; + bool bFont = GetFontData(pAppFonts, wsValue, m_pFont, isBold, isItalic, pUnicodes, unLen, pCodes, ppFonts); + if (!bFont) { RELEASEARRAYOBJECTS(pUnicodes); RELEASEARRAYOBJECTS(pCodes); + RELEASEARRAYOBJECTS(ppFonts); return S_FALSE; } - - for (unsigned int unIndex = 0; unIndex < unLen; ++unIndex) - { - unsigned int unUnicode = pUnicodes[unIndex]; - - if (!m_pFont->HaveChar(unUnicode)) - { - std::wstring wsFontFamily = pAppFonts->GetFontBySymbol(unUnicode); - PdfWriter::CFontCidTrueType* pTempFont = GetFont(wsFontFamily, isBold, isItalic); - if (pTempFont) - { - pCodes[unIndex] = pTempFont->EncodeUnicode(unUnicode); - ppFonts[unIndex] = pTempFont; - continue; - } - } - - pCodes[unIndex] = m_pFont->EncodeUnicode(unUnicode); - ppFonts[unIndex] = m_pFont; - } - PdfWriter::CTextField* pField = dynamic_cast(pFieldBase); if (!pField) { @@ -1267,6 +1302,7 @@ HRESULT CPdfWriter::AddFormField(NSFonts::IApplicationFonts* pAppFonts, CFormFie if (!isPlaceHolder) pField->SetTextValue(wsValue); + PdfWriter::CFontTrueType* pFontTT = NULL; if (!isComb && pPr->IsMultiLine()) { @@ -1286,6 +1322,8 @@ HRESULT CPdfWriter::AddFormField(NSFonts::IApplicationFonts* pAppFonts, CFormFie pCodes2[unIndex] = ushCode; pWidths[unIndex] = ppFonts[unIndex]->GetWidth(pCodes[unIndex]); } + + pFontTT = m_pDocument->CreateTrueTypeFont(m_pFont); m_oLinesManager.Init(pCodes2, pWidths, unLen, ushSpaceCode, ushNewLineCode, pFontTT->GetLineHeight(), pFontTT->GetAscent()); @@ -1389,6 +1427,8 @@ HRESULT CPdfWriter::AddFormField(NSFonts::IApplicationFonts* pAppFonts, CFormFie RELEASEARRAYOBJECTS(pCodes); RELEASEARRAYOBJECTS(ppFonts); + if (pField->GetFont() && pField->GetFont() != m_pFont && pField->GetFont()->GetFontType() == PdfWriter::fontCIDType2) + pFontTT = m_pDocument->CreateTrueTypeFont((PdfWriter::CFontCidTrueType*)pField->GetFont()); pField->SetDefaultAppearance(pFontTT, m_oFont.GetSize(), PdfWriter::TRgb(oColor.r, oColor.g, oColor.b)); std::wstring wsPlaceHolder = pPr->GetPlaceHolder(); @@ -1408,45 +1448,19 @@ HRESULT CPdfWriter::AddFormField(NSFonts::IApplicationFonts* pAppFonts, CFormFie const CFormFieldInfo::CDropDownFormPr* pPr = oInfo.GetDropDownPr(); std::wstring wsValue = pPr->GetTextValue(); - unsigned int unLen; - unsigned int* pUnicodes = NSStringExt::CConverter::GetUtf32FromUnicode(wsValue, unLen); - if (!pUnicodes) - return S_FALSE; - - unsigned short* pCodes = new unsigned short[unLen]; - if (!pCodes) - { - RELEASEARRAYOBJECTS(pUnicodes); - return S_FALSE; - } - - PdfWriter::CFontCidTrueType** ppFonts = new PdfWriter::CFontCidTrueType*[unLen]; - if (!ppFonts) + unsigned int unLen = 0; + unsigned int* pUnicodes = NULL; + unsigned short* pCodes = NULL; + PdfWriter::CFontCidTrueType** ppFonts = NULL; + bool bFont = GetFontData(pAppFonts, wsValue, m_pFont, isBold, isItalic, pUnicodes, unLen, pCodes, ppFonts); + if (!bFont) { RELEASEARRAYOBJECTS(pUnicodes); RELEASEARRAYOBJECTS(pCodes); + RELEASEARRAYOBJECTS(ppFonts); return S_FALSE; } - for (unsigned int unIndex = 0; unIndex < unLen; ++unIndex) - { - unsigned int unUnicode = pUnicodes[unIndex]; - - if (!m_pFont->HaveChar(unUnicode)) - { - std::wstring wsFontFamily = pAppFonts->GetFontBySymbol(unUnicode); - PdfWriter::CFontCidTrueType* pTempFont = GetFont(wsFontFamily, isBold, isItalic); - if (pTempFont) - { - pCodes[unIndex] = pTempFont->EncodeUnicode(unUnicode); - ppFonts[unIndex] = pTempFont; - continue; - } - } - pCodes[unIndex] = m_pFont->EncodeUnicode(unUnicode); - ppFonts[unIndex] = m_pFont; - } - PdfWriter::CChoiceField* pField = dynamic_cast(pFieldBase); if (!pField) { @@ -1485,6 +1499,11 @@ HRESULT CPdfWriter::AddFormField(NSFonts::IApplicationFonts* pAppFonts, CFormFie pField->SetComboFlag(true); pField->SetEditFlag(pPr->IsEditComboBox()); + PdfWriter::CFontTrueType* pFontTT = NULL; + if (pField->GetFont() && pField->GetFont() != m_pFont && pField->GetFont()->GetFontType() == PdfWriter::fontCIDType2) + pFontTT = m_pDocument->CreateTrueTypeFont((PdfWriter::CFontCidTrueType*)pField->GetFont()); + else + pFontTT = m_pDocument->CreateTrueTypeFont(m_pFont); pField->SetDefaultAppearance(pFontTT, m_oFont.GetSize(), oInfo.IsPlaceHolder() ? oPlaceHolderColor : oNormalColor); if (!pPr->GetPlaceHolder().empty()) @@ -1515,14 +1534,6 @@ HRESULT CPdfWriter::AddFormField(NSFonts::IApplicationFonts* pAppFonts, CFormFie pFieldBase->AddPageRect(m_pPage, PdfWriter::TRect(MM_2_PT(dX), m_pPage->GetHeight() - MM_2_PT(dY), MM_2_PT(dX + dW), m_pPage->GetHeight() - MM_2_PT(dY + dH))); pField->SetValue(pPr->IsChecked()); - PdfWriter::CFontCidTrueType* pCheckedFont = GetFont(pPr->GetCheckedFontName(), false, false); - PdfWriter::CFontCidTrueType* pUncheckedFont = GetFont(pPr->GetUncheckedFontName(), false, false); - if (!pCheckedFont) - pCheckedFont = m_pFont; - - if (!pUncheckedFont) - pUncheckedFont = m_pFont; - unsigned int unCheckedSymbol = pPr->GetCheckedSymbol(); unsigned int unUncheckedSymbol = pPr->GetUncheckedSymbol(); @@ -1547,105 +1558,32 @@ HRESULT CPdfWriter::AddFormField(NSFonts::IApplicationFonts* pAppFonts, CFormFie PdfWriter::CImageDict* pImage = NULL; if (wsPath.length()) { - Aggplus::CImage* pCImage = NULL; - CImageFileFormatChecker oImageFormat(wsPath); - if (_CXIMAGE_FORMAT_WMF == oImageFormat.eFileType || - _CXIMAGE_FORMAT_EMF == oImageFormat.eFileType || - _CXIMAGE_FORMAT_SVM == oImageFormat.eFileType || - _CXIMAGE_FORMAT_SVG == oImageFormat.eFileType) - { - MetaFile::IMetaFile* pMeta = MetaFile::Create(pAppFonts); - pMeta->LoadFromFile(wsPath.c_str()); - - double dNewW = std::max(10.0, dW) / 25.4 * 300; - std::wstring wsTempFile = GetTempFile(wsTempDirectory); - pMeta->ConvertToRaster(wsTempFile.c_str(), _CXIMAGE_FORMAT_PNG, dNewW); - - RELEASEOBJECT(pMeta); - - pCImage = new Aggplus::CImage(wsTempFile); - } - else - pCImage = new Aggplus::CImage(wsPath); - + Aggplus::CImage* pCImage = ConvertMetafile(pAppFonts, wsPath, GetTempFile(wsTempDirectory), MM_TO_PT(dW), MM_TO_PT(dH)); pImage = LoadImage(pCImage, 255); RELEASEOBJECT(pCImage); } pField->SetAppearance(pImage); } - else if (oInfo.IsSignature()) - { - const CFormFieldInfo::CSignatureFormPr* pPr = oInfo.GetSignaturePr(); - - PdfWriter::CSignatureField* pField = dynamic_cast(pFieldBase); - if (!pField) - return S_FALSE; - - pFieldBase->AddPageRect(m_pPage, PdfWriter::TRect(MM_2_PT(dX), m_pPage->GetHeight() - MM_2_PT(dY), MM_2_PT(dX + dW), m_pPage->GetHeight() - MM_2_PT(dY + dH))); - pField->SetName(pPr->GetName()); - pField->SetReason(pPr->GetReason()); - pField->SetContact(pPr->GetContact()); - pField->SetDate(pPr->GetDate()); - - std::wstring wsPath = pPr->GetPicturePath(); - PdfWriter::CImageDict* pImage = NULL; - if (!wsPath.empty()) - { - Aggplus::CImage oImage(wsPath); - pImage = LoadImage(&oImage, 255); - } - - pField->SetAppearance(pImage); - - // TODO Реализовать, когда появится поддержка CSignatureField - pField->SetCert(); - } else if (oInfo.IsDateTime()) { const CFormFieldInfo::CDateTimeFormPr* pPr = oInfo.GetDateTimePr(); std::wstring wsValue = pPr->GetValue(); - unsigned int unLen; - unsigned int* pUnicodes = NSStringExt::CConverter::GetUtf32FromUnicode(wsValue, unLen); - if (!pUnicodes) - return S_FALSE; - - unsigned short* pCodes = new unsigned short[unLen]; - if (!pCodes) - { - RELEASEARRAYOBJECTS(pUnicodes); - return S_FALSE; - } - - PdfWriter::CFontCidTrueType** ppFonts = new PdfWriter::CFontCidTrueType*[unLen]; - if (!ppFonts) + unsigned int unLen = 0; + unsigned int* pUnicodes = NULL; + unsigned short* pCodes = NULL; + PdfWriter::CFontCidTrueType** ppFonts = NULL; + bool bFont = GetFontData(pAppFonts, wsValue, m_pFont, isBold, isItalic, pUnicodes, unLen, pCodes, ppFonts); + if (!bFont) { RELEASEARRAYOBJECTS(pUnicodes); RELEASEARRAYOBJECTS(pCodes); + RELEASEARRAYOBJECTS(ppFonts); return S_FALSE; } - for (unsigned int unIndex = 0; unIndex < unLen; ++unIndex) - { - unsigned int unUnicode = pUnicodes[unIndex]; - - if (!m_pFont->HaveChar(unUnicode)) - { - std::wstring wsFontFamily = pAppFonts->GetFontBySymbol(unUnicode); - PdfWriter::CFontCidTrueType* pTempFont = GetFont(wsFontFamily, isBold, isItalic); - if (pTempFont) - { - pCodes[unIndex] = pTempFont->EncodeUnicode(unUnicode); - ppFonts[unIndex] = pTempFont; - continue; - } - } - pCodes[unIndex] = m_pFont->EncodeUnicode(unUnicode); - ppFonts[unIndex] = m_pFont; - } - PdfWriter::CDateTimeField* pField = dynamic_cast(pFieldBase); if (!pField) { @@ -1675,7 +1613,6 @@ HRESULT CPdfWriter::AddFormField(NSFonts::IApplicationFonts* pAppFonts, CFormFie pField->SetFormat(pPr->GetFormat()); } - // Выставляем имя в конце, потому что там возможно копирование настроек поля в новое родительское поле, поэтому к текущему моменту // все настройки должны быть выставлены if (!bRadioButton) @@ -1689,10 +1626,52 @@ HRESULT CPdfWriter::AddFormField(NSFonts::IApplicationFonts* pAppFonts, CFormFie return S_OK; } +void GetRCSpanStyle(CAnnotFieldInfo::CMarkupAnnotPr::CFontData* pFontData, NSStringUtils::CStringBuilder& oRC) +{ + oRC += L"font-size:"; + oRC.AddDouble(pFontData->dFontSise, 2); + oRC += L"pt;text-align:"; + switch (pFontData->nAlignment) + { + case 1: { oRC += L"center"; break; } + case 2: { oRC += L"right"; break; } + case 3: { oRC += L"justify"; break; } + case 0: + default:{ oRC += L"left"; break; } + } + + oRC += L";text-decoration:"; + if ((pFontData->nFontFlag >> 4) & 1) + oRC += L"word"; + if ((pFontData->nFontFlag >> 3) & 1) + { + if ((pFontData->nFontFlag >> 4) & 1) + oRC += L" "; + oRC += L"line-through"; + } + + oRC += L";color:"; + oRC.WriteHexColor3((unsigned char)(pFontData->dColor[0] * 255.0), + (unsigned char)(pFontData->dColor[1] * 255.0), + (unsigned char)(pFontData->dColor[2] * 255.0)); + oRC += L";font-weight:"; + oRC += (pFontData->nFontFlag >> 0) & 1 ? L"bold" : L"normal"; + oRC += L";font-style:"; + oRC += (pFontData->nFontFlag >> 1) & 1 ? L"italic" : L"normal"; + oRC += L";font-family:"; + oRC += pFontData->sActualFont.empty() ? pFontData->sFontFamily : pFontData->sActualFont; + + if (pFontData->dVAlign != 0) + { + oRC += L";vertical-align:"; + if (pFontData->dVAlign > 0) + oRC += L"+"; + oRC.AddDouble(pFontData->dVAlign, 2); + } +} HRESULT CPdfWriter::AddAnnotField(NSFonts::IApplicationFonts* pAppFonts, CAnnotFieldInfo* pFieldInfo) { - unsigned int unPagesCount = m_pDocument->GetPagesCount(); - if (!m_pDocument || 0 == unPagesCount || !pFieldInfo) + if (!m_pDocument || 0 == m_pDocument->GetPagesCount() || !pFieldInfo) return S_OK; CAnnotFieldInfo& oInfo = *pFieldInfo; @@ -1702,7 +1681,8 @@ HRESULT CPdfWriter::AddAnnotField(NSFonts::IApplicationFonts* pAppFonts, CAnnotF PdfWriter::CPage* pPage = m_pPage; int nID = oInfo.GetID(); - pAnnot = m_pDocument->GetAnnot(nID); + if (nID > 0) + pAnnot = m_pDocument->GetAnnot(nID); if (pAnnot && pOrigPage && pPage != pOrigPage) { @@ -1710,7 +1690,13 @@ HRESULT CPdfWriter::AddAnnotField(NSFonts::IApplicationFonts* pAppFonts, CAnnotF pPage->AddAnnotation(pAnnot); } - BYTE nWidgetType = 0; + BYTE nWidgetType = 0; + if (oInfo.IsWidget()) + { + CAnnotFieldInfo::CWidgetAnnotPr* pPr = oInfo.GetWidgetAnnotPr(); + nWidgetType = pPr->GetType(); + } + if (!pAnnot) { if (oInfo.IsText()) @@ -1731,12 +1717,11 @@ HRESULT CPdfWriter::AddAnnotField(NSFonts::IApplicationFonts* pAppFonts, CAnnotF pAnnot = m_pDocument->CreateFreeTextAnnot(); else if (oInfo.IsCaret()) pAnnot = m_pDocument->CreateCaretAnnot(); + else if (oInfo.IsStamp()) + pAnnot = m_pDocument->CreateStampAnnot(); if (oInfo.IsWidget()) { - CAnnotFieldInfo::CWidgetAnnotPr* pPr = oInfo.GetWidgetAnnotPr(); - nWidgetType = pPr->GetType(); - switch (nWidgetType) { case 26: @@ -1745,10 +1730,14 @@ HRESULT CPdfWriter::AddAnnotField(NSFonts::IApplicationFonts* pAppFonts, CAnnotF break; } case 27: + { + pAnnot = m_pDocument->CreatePushButtonWidget(); + break; + } case 28: case 29: { - pAnnot = m_pDocument->CreateButtonWidget(); + pAnnot = m_pDocument->CreateCheckBoxWidget(); break; } case 30: @@ -1779,14 +1768,20 @@ HRESULT CPdfWriter::AddAnnotField(NSFonts::IApplicationFonts* pAppFonts, CAnnotF if (!pAnnot) return S_FALSE; - - pAnnot->SetPage(pPage); - pAnnot->SetAnnotFlag(oInfo.GetAnnotFlag()); - double dX1, dY1, dX2, dY2; + PdfWriter::CArrayObject* pPageBox = (PdfWriter::CArrayObject*)pPage->Get("CropBox"); + if (!pPageBox) + pPageBox = (PdfWriter::CArrayObject*)pPage->Get("MediaBox"); + PdfWriter::CObjectBase* pD = pPageBox->Get(3); + double dPageH = pD->GetType() == PdfWriter::object_type_NUMBER ? ((PdfWriter::CNumberObject*)pD)->Get() : ((PdfWriter::CRealObject*)pD)->Get(); + pD = pPageBox->Get(0); + double dPageX = pD->GetType() == PdfWriter::object_type_NUMBER ? ((PdfWriter::CNumberObject*)pD)->Get() : ((PdfWriter::CRealObject*)pD)->Get(); oInfo.GetBounds(dX1, dY1, dX2, dY2); - PdfWriter::TRect oRect(dX1, pPage->GetHeight() - dY1, dX2, pPage->GetHeight() - dY2); - pAnnot->SetRect(oRect); + pAnnot->SetRect({dPageX + dX1, dPageH - dY1, dPageX + dX2, dPageH - dY2}); + + pAnnot->SetPage(pPage, pPage->GetWidth(), dPageH, dPageX); + pAnnot->SetAnnotFlag(oInfo.GetAnnotFlag()); + pAnnot->SetDocument(m_pDocument); int nFlags = oInfo.GetFlag(); if (nFlags & (1 << 0)) @@ -1805,12 +1800,16 @@ HRESULT CPdfWriter::AddAnnotField(NSFonts::IApplicationFonts* pAppFonts, CAnnotF if (nFlags & (1 << 4)) { BYTE nType; - double dWidth, d1, d2; - oInfo.GetBorder(nType, dWidth, d1, d2); - pAnnot->SetBorder(nType, dWidth, d1, d2); + double dWidth; + std::vector arrDash; + oInfo.GetBorder(nType, dWidth, arrDash); + pAnnot->SetBorder(nType, dWidth, arrDash); } if (nFlags & (1 << 5)) pAnnot->SetLM(oInfo.GetLM()); + bool bRender = (nFlags >> 6) & 1; + if (nFlags & (1 << 7)) + pAnnot->SetOUserID(oInfo.GetOUserID()); if (oInfo.IsMarkup()) { @@ -1845,10 +1844,45 @@ HRESULT CPdfWriter::AddAnnotField(NSFonts::IApplicationFonts* pAppFonts, CAnnotF pMarkupAnnot->SetT(pPr->GetT()); if (nFlags & (1 << 2)) pMarkupAnnot->SetCA(pPr->GetCA()); + std::wstring sDefaultStyle; if (nFlags & (1 << 3)) { - // TODO - // pMarkupAnnot->SetRC(pPr->GetRC()); + NSStringUtils::CStringBuilder oRC; + oRC += L"

"; + std::vector arrRC = pPr->GetRC(); + + if (!arrRC.empty()) + { + NSStringUtils::CStringBuilder oDS; + oDS += L"font: Helvetica,sans-serif "; + oDS.AddDouble(arrRC[0]->dFontSise, 2); + oDS += L"pt; text-align:"; + switch (arrRC[0]->nAlignment) + { + case 1: { oDS += L"center"; break; } + case 2: { oDS += L"right"; break; } + case 3: { oDS += L"justify"; break; } + case 0: + default:{ oDS += L"left"; break; } + } + oDS += L"; color:"; + oDS.WriteHexColor3((unsigned char)(arrRC[0]->dColor[0] * 255.0), + (unsigned char)(arrRC[0]->dColor[1] * 255.0), + (unsigned char)(arrRC[0]->dColor[2] * 255.0)); + sDefaultStyle = oDS.GetData(); + } + + for (int i = 0; i < arrRC.size(); ++i) + { + oRC += L""; + oRC.WriteEncodeXmlString(arrRC[i]->sText); + oRC += L""; + } + oRC += L"

"; + pMarkupAnnot->SetRC(oRC.GetData()); + // std::wcout << oRC.GetData() << std::endl; } if (nFlags & (1 << 4)) pMarkupAnnot->SetCD(pPr->GetCD()); @@ -1858,169 +1892,269 @@ HRESULT CPdfWriter::AddAnnotField(NSFonts::IApplicationFonts* pAppFonts, CAnnotF PdfWriter::CAnnotation* pIRTAnnot = m_pDocument->GetAnnot(nIRTID); if (pIRTAnnot) pMarkupAnnot->SetIRTID(pIRTAnnot); + else + { + PdfWriter::CObjectBase* pBase = new PdfWriter::CObjectBase(); + pBase->SetRef(nIRTID, 0); + pMarkupAnnot->Add("IRT", new PdfWriter::CProxyObject(pBase, true)); + } } if (nFlags & (1 << 6)) pMarkupAnnot->SetRT(pPr->GetRT()); if (nFlags & (1 << 7)) pMarkupAnnot->SetSubj(pPr->GetSubj()); - } - if (oInfo.IsText()) - { - CAnnotFieldInfo::CTextAnnotPr* pPr = oInfo.GetTextAnnotPr(); - PdfWriter::CTextAnnotation* pTextAnnot = (PdfWriter::CTextAnnotation*)pAnnot; + if (oInfo.IsText()) + { + CAnnotFieldInfo::CTextAnnotPr* pPr = oInfo.GetTextAnnotPr(); + PdfWriter::CTextAnnotation* pTextAnnot = (PdfWriter::CTextAnnotation*)pAnnot; + + pTextAnnot->SetOpen(pPr->IsOpen()); + if (nFlags & (1 << 16)) + pTextAnnot->SetName(pPr->GetName()); + if (nFlags & (1 << 17)) + pTextAnnot->SetStateModel(pPr->GetStateModel()); + if (nFlags & (1 << 18)) + pTextAnnot->SetState(pPr->GetState()); + + pMarkupAnnot->RemoveAP(); + pTextAnnot->SetAP(); + } + else if (oInfo.IsInk()) + { + CAnnotFieldInfo::CInkAnnotPr* pPr = oInfo.GetInkAnnotPr(); + PdfWriter::CInkAnnotation* pInkAnnot = (PdfWriter::CInkAnnotation*)pAnnot; - pTextAnnot->SetOpen(pPr->IsOpen()); - if (nFlags & (1 << 16)) - pTextAnnot->SetName(pPr->GetName()); - if (nFlags & (1 << 17)) - pTextAnnot->SetStateModel(pPr->GetStateModel()); - if (nFlags & (1 << 18)) - pTextAnnot->SetState(pPr->GetState()); - } - else if (oInfo.IsInk()) - { - CAnnotFieldInfo::CInkAnnotPr* pPr = oInfo.GetInkAnnotPr(); - PdfWriter::CInkAnnotation* pInkAnnot = (PdfWriter::CInkAnnotation*)pAnnot; + pInkAnnot->SetInkList(pPr->GetInkList()); + if (bRender) + { + pMarkupAnnot->RemoveAP(); + LONG nLen = 0; + BYTE* pRender = oInfo.GetRender(nLen); + DrawAP(pAnnot, pRender, nLen); + } + } + else if (oInfo.IsLine()) + { + CAnnotFieldInfo::CLineAnnotPr* pPr = oInfo.GetLineAnnotPr(); + PdfWriter::CLineAnnotation* pLineAnnot = (PdfWriter::CLineAnnotation*)pAnnot; - pInkAnnot->SetInkList(pPr->GetInkList()); - } - else if (oInfo.IsLine()) - { - CAnnotFieldInfo::CLineAnnotPr* pPr = oInfo.GetLineAnnotPr(); - PdfWriter::CLineAnnotation* pLineAnnot = (PdfWriter::CLineAnnotation*)pAnnot; + double dLX1, dLY1, dLX2, dLY2; + pPr->GetL(dLX1, dLY1, dLX2, dLY2); + pLineAnnot->SetL(dLX1, dLY1, dLX2, dLY2); - double dLX1, dLY1, dLX2, dLY2; - pPr->GetL(dLX1, dLY1, dLX2, dLY2); - pLineAnnot->SetL(dLX1, dLY1, dLX2, dLY2); + if (nFlags & (1 << 15)) + { + BYTE nLE1, nLE2; + pPr->GetLE(nLE1, nLE2); + pLineAnnot->SetLE(nLE1, nLE2); + } + if (nFlags & (1 << 16)) + pLineAnnot->SetIC(pPr->GetIC()); + if (nFlags & (1 << 17)) + pLineAnnot->SetLL(pPr->GetLL()); + if (nFlags & (1 << 18)) + pLineAnnot->SetLLE(pPr->GetLLE()); + pLineAnnot->SetCap(pPr->IsCap()); + if (nFlags & (1 << 20)) + pLineAnnot->SetIT(pPr->GetIT()); + if (nFlags & (1 << 21)) + pLineAnnot->SetLLO(pPr->GetLLO()); + if (nFlags & (1 << 22)) + pLineAnnot->SetCP(pPr->GetCP()); + if (nFlags & (1 << 23)) + { + double dCO1, dCO2; + pPr->GetCO(dCO1, dCO2); + pLineAnnot->SetCO(dCO1, dCO2); + } - if (nFlags & (1 << 15)) - { - BYTE nLE1, nLE2; - pPr->GetLE(nLE1, nLE2); - pLineAnnot->SetLE(nLE1, nLE2); + //pLineAnnot->SetAP(); + if (bRender) + { + pMarkupAnnot->RemoveAP(); + LONG nLen = 0; + BYTE* pRender = oInfo.GetRender(nLen); + DrawAP(pAnnot, pRender, nLen); + } } - if (nFlags & (1 << 16)) - pLineAnnot->SetIC(pPr->GetIC()); - if (nFlags & (1 << 17)) - pLineAnnot->SetLL(pPr->GetLL()); - if (nFlags & (1 << 18)) - pLineAnnot->SetLLE(pPr->GetLLE()); - pLineAnnot->SetCap(pPr->IsCap()); - if (nFlags & (1 << 20)) - pLineAnnot->SetIT(pPr->GetIT()); - if (nFlags & (1 << 21)) - pLineAnnot->SetLLO(pPr->GetLLO()); - if (nFlags & (1 << 22)) - pLineAnnot->SetCP(pPr->GetCP()); - if (nFlags & (1 << 23)) + else if (oInfo.IsTextMarkup()) { - double dCO1, dCO2; - pPr->GetCO(dCO1, dCO2); - pLineAnnot->SetCO(dCO1, dCO2); - } - } - else if (oInfo.IsTextMarkup()) - { - CAnnotFieldInfo::CTextMarkupAnnotPr* pPr = oInfo.GetTextMarkupAnnotPr(); - PdfWriter::CTextMarkupAnnotation* pTextMarkupAnnot = (PdfWriter::CTextMarkupAnnotation*)pAnnot; + CAnnotFieldInfo::CTextMarkupAnnotPr* pTMPr = oInfo.GetTextMarkupAnnotPr(); + PdfWriter::CTextMarkupAnnotation* pTextMarkupAnnot = (PdfWriter::CTextMarkupAnnotation*)pAnnot; - pTextMarkupAnnot->SetSubtype(pPr->GetSubtype()); - pTextMarkupAnnot->SetQuadPoints(pPr->GetQuadPoints()); - } - else if (oInfo.IsSquareCircle()) - { - CAnnotFieldInfo::CSquareCircleAnnotPr* pPr = oInfo.GetSquareCircleAnnotPr(); - PdfWriter::CSquareCircleAnnotation* pSquareCircleAnnot = (PdfWriter::CSquareCircleAnnotation*)pAnnot; + pTextMarkupAnnot->SetSubtype(pTMPr->GetSubtype()); + pTextMarkupAnnot->SetQuadPoints(pTMPr->GetQuadPoints()); - pSquareCircleAnnot->SetSubtype(pPr->GetSubtype()); - if (nFlags & (1 << 15)) - { - double dRD1, dRD2, dRD3, dRD4; - pPr->GetRD(dRD1, dRD2, dRD3, dRD4); - pSquareCircleAnnot->SetRD(dRD1, dRD2, dRD3, dRD4); + pMarkupAnnot->RemoveAP(); + pTextMarkupAnnot->SetAP(pTMPr->GetQuadPoints(), pPr->GetCA()); } - if (nFlags & (1 << 16)) - pSquareCircleAnnot->SetIC(pPr->GetIC()); - } - else if (oInfo.IsPolygonLine()) - { - CAnnotFieldInfo::CPolygonLineAnnotPr* pPr = oInfo.GetPolygonLineAnnotPr(); - PdfWriter::CPolygonLineAnnotation* pPolygonLineAnnot = (PdfWriter::CPolygonLineAnnotation*)pAnnot; - - pPolygonLineAnnot->SetVertices(pPr->GetVertices()); - pPolygonLineAnnot->SetSubtype(pPr->GetSubtype()); - if (nFlags & (1 << 15)) + else if (oInfo.IsSquareCircle()) { - BYTE nLE1, nLE2; - pPr->GetLE(nLE1, nLE2); - pPolygonLineAnnot->SetLE(nLE1, nLE2); - } - if (nFlags & (1 << 16)) - pPolygonLineAnnot->SetIC(pPr->GetIC()); - if (nFlags & (1 << 20)) - pPolygonLineAnnot->SetIT(pPr->GetIT()); - } - else if (oInfo.IsPopup()) - { - CAnnotFieldInfo::CPopupAnnotPr* pPr = oInfo.GetPopupAnnotPr(); - PdfWriter::CPopupAnnotation* pPopupAnnot = (PdfWriter::CPopupAnnotation*)pAnnot; + CAnnotFieldInfo::CSquareCircleAnnotPr* pPr = oInfo.GetSquareCircleAnnotPr(); + PdfWriter::CSquareCircleAnnotation* pSquareCircleAnnot = (PdfWriter::CSquareCircleAnnotation*)pAnnot; - nFlags = pPr->GetFlag(); - pPopupAnnot->SetOpen(pPr->IsOpen()); - if (nFlags & (1 << 1)) - { - int nParentID = pPr->GetParentID(); - PdfWriter::CAnnotation* pParentAnnot = m_pDocument->GetAnnot(nParentID); - if (pParentAnnot) - pPopupAnnot->SetParentID(pParentAnnot); + pSquareCircleAnnot->SetSubtype(pPr->GetSubtype()); + if (nFlags & (1 << 15)) + { + double dRD1, dRD2, dRD3, dRD4; + pPr->GetRD(dRD1, dRD2, dRD3, dRD4); + pSquareCircleAnnot->SetRD(dRD1, dRD2, dRD3, dRD4); + } + if (nFlags & (1 << 16)) + pSquareCircleAnnot->SetIC(pPr->GetIC()); + if (bRender) + { + pMarkupAnnot->RemoveAP(); + LONG nLen = 0; + BYTE* pRender = oInfo.GetRender(nLen); + DrawAP(pAnnot, pRender, nLen); + } } - } - else if (oInfo.IsFreeText()) - { - CAnnotFieldInfo::CFreeTextAnnotPr* pPr = oInfo.GetFreeTextAnnotPr(); - PdfWriter::CFreeTextAnnotation* pFreeTextAnnot = (PdfWriter::CFreeTextAnnotation*)pAnnot; - - pFreeTextAnnot->SetQ(pPr->GetQ()); - if (nFlags & (1 << 15)) + else if (oInfo.IsPolygonLine()) { - double dRD1, dRD2, dRD3, dRD4; - pPr->GetRD(dRD1, dRD2, dRD3, dRD4); - pFreeTextAnnot->SetRD(dRD1, dRD2, dRD3, dRD4); + CAnnotFieldInfo::CPolygonLineAnnotPr* pPr = oInfo.GetPolygonLineAnnotPr(); + PdfWriter::CPolygonLineAnnotation* pPolygonLineAnnot = (PdfWriter::CPolygonLineAnnotation*)pAnnot; + + pPolygonLineAnnot->SetVertices(pPr->GetVertices()); + pPolygonLineAnnot->SetSubtype(pPr->GetSubtype()); + if (nFlags & (1 << 15)) + { + BYTE nLE1, nLE2; + pPr->GetLE(nLE1, nLE2); + pPolygonLineAnnot->SetLE(nLE1, nLE2); + } + if (nFlags & (1 << 16)) + pPolygonLineAnnot->SetIC(pPr->GetIC()); + if (nFlags & (1 << 20)) + pPolygonLineAnnot->SetIT(pPr->GetIT()); + if (bRender) + { + pMarkupAnnot->RemoveAP(); + LONG nLen = 0; + BYTE* pRender = oInfo.GetRender(nLen); + DrawAP(pAnnot, pRender, nLen); + } + } + else if (oInfo.IsFreeText()) + { + CAnnotFieldInfo::CFreeTextAnnotPr* pFTPr = oInfo.GetFreeTextAnnotPr(); + PdfWriter::CFreeTextAnnotation* pFreeTextAnnot = (PdfWriter::CFreeTextAnnotation*)pAnnot; + + pFreeTextAnnot->SetQ(pFTPr->GetQ()); + pFreeTextAnnot->SetRotate(pFTPr->GetRotate()); + if (nFlags & (1 << 15)) + { + double dRD1, dRD2, dRD3, dRD4; + pFTPr->GetRD(dRD1, dRD2, dRD3, dRD4); + pFreeTextAnnot->SetRD(dRD1, dRD2, dRD3, dRD4); + } + if (nFlags & (1 << 16)) + pFreeTextAnnot->SetCL(pFTPr->GetCL()); + + std::wstring sDS = pFTPr->GetDS(); + if (sDS.empty()) + sDS = sDefaultStyle; + pFreeTextAnnot->SetDS(sDS); + + if (nFlags & (1 << 18)) + pFreeTextAnnot->SetLE(pFTPr->GetLE()); + if (nFlags & (1 << 20)) + pFreeTextAnnot->SetIT(pFTPr->GetIT()); + if (nFlags & (1 << 21)) + pFreeTextAnnot->SetIC(pFTPr->GetIC()); + if (bRender) + { + pMarkupAnnot->RemoveAP(); + LONG nLen = 0; + BYTE* pRender = oInfo.GetRender(nLen); + DrawAP(pAnnot, pRender, nLen); + } + + PdfWriter::CFontDict* pFont = m_pFont; + if (m_pFont14) + pFont = m_pFont14; + pFreeTextAnnot->SetDA(pFont, m_oFont.GetSize(), oInfo.GetC()); + } + else if (oInfo.IsCaret()) + { + CAnnotFieldInfo::CCaretAnnotPr* pPr = oInfo.GetCaretAnnotPr(); + PdfWriter::CCaretAnnotation* pCaretAnnot = (PdfWriter::CCaretAnnotation*)pAnnot; + + if (nFlags & (1 << 15)) + { + double dRD1, dRD2, dRD3, dRD4; + pPr->GetRD(dRD1, dRD2, dRD3, dRD4); + pCaretAnnot->SetRD(dRD1, dRD2, dRD3, dRD4); + } + if (nFlags & (1 << 16)) + pCaretAnnot->SetSy(pPr->GetSy()); + + // pMarkupAnnot->RemoveAP(); + } + else if (oInfo.IsStamp()) + { + CAnnotFieldInfo::CStampAnnotPr* pPr = oInfo.GetStampAnnotPr(); + PdfWriter::CStampAnnotation* pStampAnnot = (PdfWriter::CStampAnnotation*)pAnnot; + + pStampAnnot->SetName(L"#" + pPr->GetName()); + double nRotate = pPr->GetRotate(); + + if (bRender) + { + pMarkupAnnot->RemoveAP(); + LONG nLen = 0; + BYTE* pRender = oInfo.GetRender(nLen); + PdfWriter::CAnnotAppearanceObject* pAP = DrawAP(pAnnot, pRender, nLen); + + double dRD1, dRD2, dRD3, dRD4; + pPr->GetInRect(dRD1, dRD2, dRD3, dRD4); + PdfWriter::CArrayObject* pArray = new PdfWriter::CArrayObject(); + pAP->Add("BBox", pArray); + pArray->Add(dRD1); + pArray->Add(MM_2_PT(m_dPageHeight) - dRD4); + pArray->Add(dRD3); + pArray->Add(MM_2_PT(m_dPageHeight) - dRD2); + pStampAnnot->SetAPStream(pAP); + } + + pStampAnnot->SetRotate(nRotate); } - if (nFlags & (1 << 16)) - pFreeTextAnnot->SetCL(pPr->GetCL()); - if (nFlags & (1 << 17)) - pFreeTextAnnot->SetDS(pPr->GetDS()); - if (nFlags & (1 << 18)) - pFreeTextAnnot->SetLE(pPr->GetLE()); - if (nFlags & (1 << 20)) - pFreeTextAnnot->SetIT(pPr->GetIT()); } - else if (oInfo.IsCaret()) + else if (oInfo.IsPopup()) { - CAnnotFieldInfo::CCaretAnnotPr* pPr = oInfo.GetCaretAnnotPr(); - PdfWriter::CCaretAnnotation* pCaretAnnot = (PdfWriter::CCaretAnnotation*)pAnnot; + CAnnotFieldInfo::CPopupAnnotPr* pPr = oInfo.GetPopupAnnotPr(); + PdfWriter::CPopupAnnotation* pPopupAnnot = (PdfWriter::CPopupAnnotation*)pAnnot; - if (nFlags & (1 << 15)) + nFlags = pPr->GetFlag(); + pPopupAnnot->SetOpen(pPr->IsOpen()); + if (nFlags & (1 << 1)) { - double dRD1, dRD2, dRD3, dRD4; - pPr->GetRD(dRD1, dRD2, dRD3, dRD4); - pCaretAnnot->SetRD(dRD1, dRD2, dRD3, dRD4); + int nParentID = pPr->GetParentID(); + PdfWriter::CAnnotation* pParentAnnot = m_pDocument->GetAnnot(nParentID); + if (pParentAnnot) + pPopupAnnot->SetParentID(pParentAnnot); } - if (nFlags & (1 << 16)) - pCaretAnnot->SetSy(pPr->GetSy()); } - - if (oInfo.IsWidget()) + else if (oInfo.IsWidget()) { CAnnotFieldInfo::CWidgetAnnotPr* pPr = oInfo.GetWidgetAnnotPr(); PdfWriter::CWidgetAnnotation* pWidgetAnnot = (PdfWriter::CWidgetAnnotation*)pAnnot; - // TODO - pWidgetAnnot->SetDA(NULL, 0, pPr->GetTC()); - pWidgetAnnot->SetQ(pPr->GetQ()); + std::wstring wsFontKey; + if (nFlags & (1 << 2)) + wsFontKey = pPr->GetFontKey(); + + std::wstring wsFontName = pPr->GetFontName(); + int nStyle = pPr->GetFontStyle(); + double dFontSize = pPr->GetFontSizeAP(); + PdfWriter::CFontTrueType* pFontTT = NULL; + + BYTE nAlign = pPr->GetQ(); + if (nWidgetType != 27 && nWidgetType != 28 && nWidgetType != 29) + pWidgetAnnot->SetQ(nAlign); int nWidgetFlag = pPr->GetFlag(); + pWidgetAnnot->SetSubtype(nWidgetType); pWidgetAnnot->SetFlag(nWidgetFlag); int nFlags = pPr->GetFlags(); @@ -2041,41 +2175,228 @@ HRESULT CPdfWriter::AddAnnotField(NSFonts::IApplicationFonts* pAppFonts, CAnnotF if (nFlags & (1 << 18)) pWidgetAnnot->SetT(pPr->GetT()); - if (oInfo.IsButtonWidget()) + const std::vector arrActions = pPr->GetActions(); + for (CAnnotFieldInfo::CWidgetAnnotPr::CActionWidget* pAction : arrActions) { - CAnnotFieldInfo::CWidgetAnnotPr::CButtonWidgetPr* pPr = oInfo.GetWidgetAnnotPr()->GetButtonWidgetPr(); - PdfWriter::CButtonWidget* pButtonWidget = (PdfWriter::CButtonWidget*)pAnnot; + PdfWriter::CAction* pA = (PdfWriter::CAction*)m_pDocument->CreateAction(pAction->nActionType); + if (!pA) + continue; + pA->SetType(pAction->wsType); - if (nFlags & (1 << 14)) - pButtonWidget->SetAP_N_Yes(pPr->GetAP_N_Yes()); - pButtonWidget->SetV(nFlags & (1 << 9)); - int nIFFlags = pPr->GetIFFlag(); - pButtonWidget->SetIFFlag(nIFFlags); + switch (pAction->nActionType) + { + case 1: + { + PdfWriter::CActionGoTo* ppA = (PdfWriter::CActionGoTo*)pA; + PdfWriter::CPage* pPageD = m_pDocument->GetPage(pAction->nInt1); + PdfWriter::CDestination* pDest = m_pDocument->CreateDestination(pPageD); + if (!pDest) + break; + ppA->SetDestination(pDest); + + PdfWriter::CArrayObject* pPageBoxD = (PdfWriter::CArrayObject*)pPageD->Get("CropBox"); + if (!pPageBoxD) + pPageBoxD = (PdfWriter::CArrayObject*)pPageD->Get("MediaBox"); + if (!pPageBoxD) + pPageBoxD = pPageBox; + pD = pPageBoxD->Get(3); + double dPageDH = pD->GetType() == PdfWriter::object_type_NUMBER ? ((PdfWriter::CNumberObject*)pD)->Get() : ((PdfWriter::CRealObject*)pD)->Get(); + pD = pPageBoxD->Get(0); + double dPageDX = pD->GetType() == PdfWriter::object_type_NUMBER ? ((PdfWriter::CNumberObject*)pD)->Get() : ((PdfWriter::CRealObject*)pD)->Get(); + + switch (pAction->nKind) + { + case 0: + { + pDest->SetXYZ(pAction->dD[0] + dPageDX, dPageDH - pAction->dD[1], pAction->dD[2]); + break; + } + case 1: + { + pDest->SetFit(); + break; + } + case 2: + { + pDest->SetFitH(dPageDH - pAction->dD[1]); + break; + } + case 3: + { + pDest->SetFitV(pAction->dD[0] + dPageDX); + break; + } + case 4: + { + pDest->SetFitR(pAction->dD[0] + dPageDX, dPageDH - pAction->dD[1], pAction->dD[2] + dPageDX, dPageDH - pAction->dD[3]); + break; + } + case 5: + { + pDest->SetFitB(); + break; + } + case 6: + { + pDest->SetFitBH(dPageDH - pAction->dD[1]); + break; + } + case 7: + { + pDest->SetFitBV(pAction->dD[0] + dPageDX); + break; + } + } + break; + } + case 6: + { + PdfWriter::CActionURI* ppA = (PdfWriter::CActionURI*)pA; + ppA->SetURI(pAction->wsStr1); + break; + } + case 9: + { + PdfWriter::CActionHide* ppA = (PdfWriter::CActionHide*)pA; + ppA->SetH(pAction->nKind); + ppA->SetT(pAction->arrStr); + break; + } + case 10: + { + PdfWriter::CActionNamed* ppA = (PdfWriter::CActionNamed*)pA; + ppA->SetN(pAction->wsStr1); + break; + } + case 12: + { + PdfWriter::CActionResetForm* ppA = (PdfWriter::CActionResetForm*)pA; + ppA->SetFlags(pAction->nInt1); + ppA->SetFields(pAction->arrStr); + break; + } + case 14: + { + PdfWriter::CActionJavaScript* ppA = (PdfWriter::CActionJavaScript*)pA; + ppA->SetJS(pAction->wsStr1); + break; + } + } + pWidgetAnnot->AddAction(pA); + } + + bool isBold = (nStyle & 1 ? true : false); + bool isItalic = (nStyle & 2 ? true : false); + + if (oInfo.IsButtonWidget()) + { if (nWidgetType == 27) { + CAnnotFieldInfo::CWidgetAnnotPr::CButtonWidgetPr* pPr = oInfo.GetWidgetAnnotPr()->GetButtonWidgetPr(); + PdfWriter::CPushButtonWidget* pButtonWidget = (PdfWriter::CPushButtonWidget*)pAnnot; + + BYTE nTP = 0; + if (nFlags & (1 << 13)) + { + nTP = pPr->GetTP(); + pButtonWidget->SetTP(nTP); + } + + int nIFFlags = pPr->GetIFFlag(); + pButtonWidget->SetIFFlag(nIFFlags); + if (nIFFlags & (1 << 0)) + { + if (nIFFlags & (1 << 1)) + pButtonWidget->SetSW(pPr->GetSW()); + if (nIFFlags & (1 << 2)) + pButtonWidget->SetS(pPr->GetS()); + if (nIFFlags & (1 << 3)) + { + double d1, d2; + pPr->GetA(d1, d2); + pButtonWidget->SetA(d1, d2); + } + } + + if (nIFFlags & (1 << 5)) + pButtonWidget->SetI(pPr->GetI()); + if (nIFFlags & (1 << 6)) + pButtonWidget->SetRI(pPr->GetRI()); + if (nIFFlags & (1 << 7)) + pButtonWidget->SetIX(pPr->GetIX()); + + put_FontName(wsFontName); + put_FontStyle(nStyle); + put_FontSize(dFontSize); + + if (m_bNeedUpdateTextFont) + UpdateFont(); + if (m_pFont) + pFontTT = m_pDocument->CreateTrueTypeFont(m_pFont); + pWidgetAnnot->SetDA(pFontTT, oInfo.GetWidgetAnnotPr()->GetFontSize(), dFontSize, oInfo.GetWidgetAnnotPr()->GetTC()); + + // ВНЕШНИЙ ВИД + pButtonWidget->SetFont(m_pFont, dFontSize, isBold, isItalic); if (nFlags & (1 << 10)) + { pButtonWidget->SetCA(pPr->GetCA()); + if (nTP == 0) + DrawButtonWidget(pAppFonts, pButtonWidget, 0, NULL); + } if (nFlags & (1 << 11)) + { pButtonWidget->SetRC(pPr->GetRC()); + if (nTP == 0) + DrawButtonWidget(pAppFonts, pButtonWidget, 1, NULL); + } if (nFlags & (1 << 12)) + { pButtonWidget->SetAC(pPr->GetAC()); + if (nTP == 0) + DrawButtonWidget(pAppFonts, pButtonWidget, 2, NULL); + } } else - pButtonWidget->SetS(pPr->GetS()); + { + CAnnotFieldInfo::CWidgetAnnotPr::CButtonWidgetPr* pPrB = oInfo.GetWidgetAnnotPr()->GetButtonWidgetPr(); + PdfWriter::CCheckBoxWidget* pButtonWidget = (PdfWriter::CCheckBoxWidget*)pAnnot; - if (nFlags & (1 << 13)) - pButtonWidget->SetTP(pPr->GetTP()); - if (nIFFlags & (1 << 0)) - { - if (nIFFlags & (1 << 1)) - pButtonWidget->SetSW(pPr->GetSW()); - if (nIFFlags & (1 << 2)) - pButtonWidget->SetS(pPr->GetS()); - if (nIFFlags & (1 << 3)) + std::wstring wsValue; + if (nFlags & (1 << 14)) + pButtonWidget->SetAP_N_Yes(pPrB->GetAP_N_Yes()); + if (nFlags & (1 << 9)) { - double d1, d2; - pPr->GetA(d1, d2); - pButtonWidget->SetA(d1, d2); + wsValue = pPrB->GetV(); + pButtonWidget->SetV(wsValue); + } + + std::wstring wsStyleValue = pButtonWidget->SetStyle(pPrB->GetStyle()); + + // ВНЕШНИЙ ВИД + // Если изменился текущий внешний вид + if (pButtonWidget->Get("AP")) + { + if (!wsValue.empty()) + pButtonWidget->SwitchAP(U_TO_UTF8(wsValue)); + return S_OK; + } + + put_FontName(wsFontName); + put_FontStyle(nStyle); + put_FontSize(dFontSize); + + if (m_bNeedUpdateTextFont) + UpdateFont(); + if (m_pFont) + pFontTT = m_pDocument->CreateTrueTypeFont(m_pFont); + pWidgetAnnot->SetDA(pFontTT, pPr->GetFontSize(), dFontSize, pPr->GetTC()); + + pButtonWidget->SetFont(m_pFont, dFontSize, isBold, isItalic); + if (!wsStyleValue.empty()) + { + double dMargin = 2; + double dBaseLine = dY2 - dY1 - dFontSize - dMargin; + pButtonWidget->SetAP(wsStyleValue, NULL, 0, 0, dBaseLine, NULL, NULL); } } } @@ -2084,24 +2405,111 @@ HRESULT CPdfWriter::AddAnnotField(NSFonts::IApplicationFonts* pAppFonts, CAnnotF CAnnotFieldInfo::CWidgetAnnotPr::CTextWidgetPr* pPr = oInfo.GetWidgetAnnotPr()->GetTextWidgetPr(); PdfWriter::CTextWidget* pTextWidget = (PdfWriter::CTextWidget*)pAnnot; + std::wstring wsValue; + bool bValue = false; if (nFlags & (1 << 9)) - pTextWidget->SetV(pPr->GetV()); + { + bValue = true; + wsValue = pPr->GetV(); + pTextWidget->SetV(wsValue); + } if (nFlags & (1 << 10)) pTextWidget->SetMaxLen(pPr->GetMaxLen()); if (nWidgetFlag & (1 << 25)) pTextWidget->SetRV(pPr->GetRV()); + bool bAPValue = false; + if (nFlags & (1 << 12)) + { + bAPValue = true; + wsValue = pPr->GetAPV(); + pTextWidget->SetAPV(); + } + if (nFlags & (1 << 13)) + { + pTextWidget->SetAPV(); + + LONG nLen = 0; + BYTE* pRender = pPr->GetRender(nLen); + DrawWidgetAP(pAnnot, pRender, nLen); + + PdfWriter::CFontDict* pFont = NULL; + if (m_pFont14) + pFont = m_pFont14; + else if (m_pFont) + pFont = m_pDocument->CreateTrueTypeFont(m_pFont); + if (pFont) + pWidgetAnnot->SetDA(pFont, oInfo.GetWidgetAnnotPr()->GetFontSize(), dFontSize, oInfo.GetWidgetAnnotPr()->GetTC()); + } + else if ((bValue && pTextWidget->Get("T")) || bAPValue) + { + put_FontName(wsFontName); + put_FontStyle(nStyle); + put_FontSize(dFontSize); + + if (m_bNeedUpdateTextFont) + UpdateFont(); + if (m_pFont) + pFontTT = m_pDocument->CreateTrueTypeFont(m_pFont); + pWidgetAnnot->SetDA(pFontTT, oInfo.GetWidgetAnnotPr()->GetFontSize(), dFontSize, oInfo.GetWidgetAnnotPr()->GetTC()); + + pTextWidget->SetFont(m_pFont, dFontSize, isBold, isItalic); + DrawTextWidget(pAppFonts, pTextWidget, wsValue); + } } else if (oInfo.IsChoiceWidget()) { CAnnotFieldInfo::CWidgetAnnotPr::CChoiceWidgetPr* pPr = oInfo.GetWidgetAnnotPr()->GetChoiceWidgetPr(); PdfWriter::CChoiceWidget* pChoiceWidget = (PdfWriter::CChoiceWidget*)pAnnot; + std::vector arrValue; if (nFlags & (1 << 9)) - pChoiceWidget->SetV(pPr->GetV()); + { + arrValue.push_back(pPr->GetV()); + pChoiceWidget->SetV(arrValue.back()); + } if (nFlags & (1 << 10)) pChoiceWidget->SetOpt(pPr->GetOpt()); if (nFlags & (1 << 11)) pChoiceWidget->SetTI(pPr->GetTI()); + if (nFlags & (1 << 12)) + arrValue[arrValue.size()] = pPr->GetAPV(); + if (nFlags & (1 << 13)) + pChoiceWidget->SetV(pPr->GetArrV()); + if (nFlags & (1 << 14)) + pChoiceWidget->SetI(pPr->GetI()); + else + pChoiceWidget->Remove("I"); + if (nFlags & (1 << 15)) + { + pChoiceWidget->SetAPV(); + + LONG nLen = 0; + BYTE* pRender = pPr->GetRender(nLen); + DrawWidgetAP(pAnnot, pRender, nLen); + + PdfWriter::CFontDict* pFont = NULL; + if (m_pFont14) + pFont = m_pFont14; + else if (m_pFont) + pFont = m_pDocument->CreateTrueTypeFont(m_pFont); + if (pFont) + pWidgetAnnot->SetDA(pFont, oInfo.GetWidgetAnnotPr()->GetFontSize(), dFontSize, oInfo.GetWidgetAnnotPr()->GetTC()); + } + else if (!arrValue.empty()) + { + put_FontName(wsFontName); + put_FontStyle(nStyle); + put_FontSize(dFontSize); + + if (m_bNeedUpdateTextFont) + UpdateFont(); + if (m_pFont) + pFontTT = m_pDocument->CreateTrueTypeFont(m_pFont); + pWidgetAnnot->SetDA(pFontTT, oInfo.GetWidgetAnnotPr()->GetFontSize(), dFontSize, oInfo.GetWidgetAnnotPr()->GetTC()); + + pChoiceWidget->SetFont(m_pFont, dFontSize, isBold, isItalic); + DrawChoiceWidget(pAppFonts, pChoiceWidget, arrValue); + } } else if (oInfo.IsSignatureWidget()) { @@ -2112,6 +2520,33 @@ HRESULT CPdfWriter::AddAnnotField(NSFonts::IApplicationFonts* pAppFonts, CAnnotF return S_OK; } +HRESULT CPdfWriter::AddMetaData(const std::wstring& sMetaName, BYTE* pMetaData, DWORD nMetaLength) +{ + return m_pDocument->AddMetaData(sMetaName, pMetaData, nMetaLength) ? S_OK : S_FALSE; +} +void CreateOutlines(PdfWriter::CDocument* m_pDocument, const std::vector& arrHeadings, PdfWriter::COutline* pParent) +{ + for (int i = 0; i < arrHeadings.size(); ++i) + { + std::string sTitle = U_TO_UTF8(arrHeadings[i]->wsTitle); + PdfWriter::COutline* pOutline = m_pDocument->CreateOutline(pParent, sTitle.c_str()); + PdfWriter::CPage* pPageD = m_pDocument->GetPage(arrHeadings[i]->nPage); + PdfWriter::CDestination* pDest = m_pDocument->CreateDestination(pPageD, true); + if (pDest) + { + pOutline->SetDestination(pDest); + pDest->SetXYZ(MM_2_PT(arrHeadings[i]->dX), pPageD->GetHeight() - MM_2_PT(arrHeadings[i]->dY), 0); + } + CreateOutlines(m_pDocument, arrHeadings[i]->arrHeading, pOutline); + } +} +void CPdfWriter::SetHeadings(CHeadings* pCommand) +{ + if (!m_pDocument || !pCommand) + return; + + CreateOutlines(m_pDocument, pCommand->GetHeading(), NULL); +} //---------------------------------------------------------------------------------------- // Дополнительные функции Pdf рендерера //---------------------------------------------------------------------------------------- @@ -2167,6 +2602,188 @@ HRESULT CPdfWriter::DrawImageWith1bppMask(IGrObject* pImage, NSImages::CPixJbig2 m_pPage->GrRestore(); return S_OK; } +HRESULT CPdfWriter::EditWidgetParents(NSFonts::IApplicationFonts* pAppFonts, CWidgetsInfo* pFieldInfo, const std::wstring& wsTempDirectory) +{ + if (!m_pDocument || 0 == m_pDocument->GetPagesCount() || !pFieldInfo) + return S_OK; + + if (!m_pDocument->EditCO(pFieldInfo->GetCO())) + return S_FALSE; + + std::vector arrParents = pFieldInfo->GetParents(); + for (int j = 0; j < arrParents.size(); ++j) + { + CWidgetsInfo::CParent* pParent = arrParents[j]; + PdfWriter::CDictObject* pParentObj = m_pDocument->GetParent(pParent->nID); + if (!pParentObj) + continue; + + std::vector arrValue; + + int nFlags = pParent->nFlags; + // Adobe не может смешивать юникод и utf имена полей + // if (nFlags & (1 << 0)) + // pParentObj->Add("T", new PdfWriter::CStringObject((U_TO_UTF8(pParent->sName)).c_str(), true)); + if (nFlags & (1 << 1)) + { + std::string sV = U_TO_UTF8(pParent->sV); + bool bName = !sV.empty() && (iswdigit(pParent->sV[0]) || sV == "Off"); + + PdfWriter::CObjectBase* pKids = pParentObj->Get("Kids"); + if (pKids && pKids->GetType() == PdfWriter::object_type_ARRAY) + { + PdfWriter::CArrayObject* pAKids = (PdfWriter::CArrayObject*)pKids; + for (int i = 0; i < pAKids->GetCount(); ++i) + { + PdfWriter::CObjectBase* pObj = pAKids->Get(i); + if (pObj->GetType() != PdfWriter::object_type_DICT || + ((PdfWriter::CDictObject*)pObj)->GetDictType() != PdfWriter::dict_type_ANNOTATION || + ((PdfWriter::CAnnotation*)pObj)->GetAnnotationType() != PdfWriter::AnnotWidget) + continue; + PdfWriter::EWidgetType nType = ((PdfWriter::CWidgetAnnotation*)pObj)->GetWidgetType(); + if (nType == PdfWriter::WidgetCheckbox || nType == PdfWriter::WidgetRadiobutton) + { + PdfWriter::CCheckBoxWidget* pKid = dynamic_cast(pObj); + if (pKid) + pKid->SwitchAP(sV); + } + if (nType == PdfWriter::WidgetCombobox || nType == PdfWriter::WidgetListbox) + { + PdfWriter::CChoiceWidget* pKid = dynamic_cast(pObj); + if (!pKid->HaveAPV()) + DrawChoiceWidget(pAppFonts, pKid, {pParent->sV}); + bName = false; + } + if (nType == PdfWriter::WidgetText) + { + PdfWriter::CTextWidget* pKid = dynamic_cast(pObj); + if (!pKid->HaveAPV()) + DrawTextWidget(pAppFonts, pKid, pParent->sV); + bName = false; + } + } + } + + if (bName) + pParentObj->Add("V", sV.c_str()); + else + pParentObj->Add("V", new PdfWriter::CStringObject(sV.c_str(), true)); + } + if (nFlags & (1 << 2)) + pParentObj->Add("DV", new PdfWriter::CStringObject((U_TO_UTF8(pParent->sDV)).c_str(), true)); + if (nFlags & (1 << 3)) + { + PdfWriter::CArrayObject* pArray = new PdfWriter::CArrayObject(); + pParentObj->Add("I", pArray); + for (int i = 0; i < pParent->arrI.size(); ++i) + pArray->Add(pParent->arrI[i]); + } + else + pParentObj->Remove("I"); + if (nFlags & (1 << 4)) + { + PdfWriter::CDictObject* pParentObj2 = m_pDocument->GetParent(pParent->nParentID); + if (pParentObj2) + pParentObj->Add("Parent", pParentObj2); + } + if (nFlags & (1 << 5)) + { + PdfWriter::CArrayObject* pArray = new PdfWriter::CArrayObject(); + pParentObj->Add("V", pArray); + for (int i = 0; i < pParent->arrV.size(); ++i) + pArray->Add(new PdfWriter::CStringObject(U_TO_UTF8(pParent->arrV[i]).c_str(), true)); + PdfWriter::CObjectBase* pKids = pParentObj->Get("Kids"); + if (pKids && pKids->GetType() == PdfWriter::object_type_ARRAY) + { + PdfWriter::CArrayObject* pAKids = (PdfWriter::CArrayObject*)pKids; + for (int i = 0; i < pAKids->GetCount(); ++i) + { + PdfWriter::CObjectBase* pObj = pAKids->Get(i); + if (pObj->GetType() != PdfWriter::object_type_DICT || + ((PdfWriter::CDictObject*)pObj)->GetDictType() != PdfWriter::dict_type_ANNOTATION || + ((PdfWriter::CAnnotation*)pObj)->GetAnnotationType() != PdfWriter::AnnotWidget) + continue; + PdfWriter::EWidgetType nType = ((PdfWriter::CWidgetAnnotation*)pObj)->GetWidgetType(); + if (nType == PdfWriter::WidgetCombobox || nType == PdfWriter::WidgetListbox) + { + PdfWriter::CChoiceWidget* pKid = dynamic_cast(pObj); + if (!pKid->HaveAPV()) + DrawChoiceWidget(pAppFonts, pKid, pParent->arrV); + } + } + } + } + } + + std::vector arrBI = pFieldInfo->GetButtonImg(); + std::vector arrForm; + for (int i = 0; i < arrBI.size(); ++i) + { + std::wstring wsPath = arrBI[i]; + if (wsPath.empty()) + { + arrForm.push_back(NULL); + continue; + } + std::wstring sTempImagePath = GetDownloadFile(wsPath, wsTempDirectory); + std::wstring wsImagePath = sTempImagePath.empty() ? wsPath : sTempImagePath; + + Aggplus::CImage* pCImage = ConvertMetafile(pAppFonts, wsImagePath, GetTempFile(wsTempDirectory)); + PdfWriter::CImageDict* pImage = LoadImage(pCImage, 255); + RELEASEOBJECT(pCImage); + + arrForm.push_back(m_pDocument->CreateForm(pImage, std::to_string(i))); + } + + if (arrForm.empty()) + return S_OK; + + std::map mAnnots = m_pDocument->GetAnnots(); + for (auto it = mAnnots.begin(); it != mAnnots.end(); it++) + { + PdfWriter::CAnnotation* pAnnot = it->second; + if (pAnnot->GetAnnotationType() != PdfWriter::AnnotWidget || ((PdfWriter::CWidgetAnnotation*)pAnnot)->GetWidgetType() != PdfWriter::WidgetPushbutton) + continue; + + PdfWriter::CPushButtonWidget* pPBWidget = (PdfWriter::CPushButtonWidget*)pAnnot; + if (pPBWidget->m_nI >= 0) + DrawButtonWidget(pAppFonts, pPBWidget, 0, arrForm[pPBWidget->m_nI]); + if (pPBWidget->m_nRI >= 0) + DrawButtonWidget(pAppFonts, pPBWidget, 1, arrForm[pPBWidget->m_nRI]); + else if (pPBWidget->m_nI >= 0) + { + PdfWriter::CDictObject* pObj = dynamic_cast(pPBWidget->Get("AP")); + if (pObj && pObj->Get("R")) + { + pObj = dynamic_cast(pPBWidget->Get("MK")); + if (pObj && !pObj->Get("RI")) + DrawButtonWidget(pAppFonts, pPBWidget, 1, arrForm[pPBWidget->m_nI]); + } + } + if (pPBWidget->m_nIX >= 0) + DrawButtonWidget(pAppFonts, pPBWidget, 2, arrForm[pPBWidget->m_nIX]); + else if (pPBWidget->m_nI >= 0) + { + PdfWriter::CDictObject* pObj = dynamic_cast(pPBWidget->Get("AP")); + if (pObj && pObj->Get("D")) + { + pObj = dynamic_cast(pPBWidget->Get("MK")); + if (pObj && !pObj->Get("IX")) + DrawButtonWidget(pAppFonts, pPBWidget, 2, arrForm[pPBWidget->m_nI]); + } + } + } + + return S_OK; +} +PdfWriter::CDocument* CPdfWriter::GetDocument() +{ + return m_pDocument; +} +PdfWriter::CPage* CPdfWriter::GetPage() +{ + return m_pPage; +} bool CPdfWriter::EditPage(PdfWriter::CPage* pNewPage) { if (!IsValid()) @@ -2240,7 +2857,7 @@ void CPdfWriter::Sign(const double& dX, const double& dY, const double& dW, cons //---------------------------------------------------------------------------------------- // Внутренние функции //---------------------------------------------------------------------------------------- -PdfWriter::CImageDict* CPdfWriter::LoadImage(Aggplus::CImage* pImage, const BYTE& nAlpha) +PdfWriter::CImageDict* CPdfWriter::LoadImage(Aggplus::CImage* pImage, BYTE nAlpha) { TColor oColor; int nImageW = abs((int)pImage->GetWidth()); @@ -2264,6 +2881,7 @@ PdfWriter::CImageDict* CPdfWriter::LoadImage(Aggplus::CImage* pImage, const BYTE bool bAlpha = false; CBgraFrame oFrame; + /* if (m_pDocument->IsPDFA()) { BYTE* pCopyImage = new BYTE[4 * nImageW * nImageH]; @@ -2290,6 +2908,7 @@ PdfWriter::CImageDict* CPdfWriter::LoadImage(Aggplus::CImage* pImage, const BYTE oFrame.put_Stride(-4* nImageW); } else + */ { BYTE* pDataMem = pData; for (int nIndex = 0, nSize = nImageW * nImageH; nIndex < nSize; nIndex++) @@ -2335,20 +2954,20 @@ PdfWriter::CImageDict* CPdfWriter::LoadImage(Aggplus::CImage* pImage, const BYTE return pPdfImage; } -bool CPdfWriter::DrawImage(Aggplus::CImage* pImage, const double& dX, const double& dY, const double& dW, const double& dH, const BYTE& nAlpha) +PdfWriter::CImageDict* CPdfWriter::DrawImage(Aggplus::CImage* pImage, const double& dX, const double& dY, const double& dW, const double& dH, const BYTE& nAlpha) { PdfWriter::CImageDict* pPdfImage = LoadImage(pImage, nAlpha); if (!pPdfImage) - return false; + return NULL; m_pPage->GrSave(); UpdateTransform(); m_pPage->DrawImage(pPdfImage, MM_2_PT(dX), MM_2_PT(m_dPageHeight - dY - dH), MM_2_PT(dW), MM_2_PT(dH)); m_pPage->GrRestore(); - return true; + return pPdfImage; } -bool CPdfWriter::DrawText(unsigned char* pCodes, const unsigned int& unLen, const double& dX, const double& dY) +bool CPdfWriter::DrawText(unsigned char* pCodes, const unsigned int& unLen, const double& dX, const double& dY, const std::string& sPUA) { if (!pCodes || !unLen) return false; @@ -2357,13 +2976,17 @@ bool CPdfWriter::DrawText(unsigned char* pCodes, const unsigned int& unLen, cons m_oCommandManager.SetTransform(t.m11, -t.m12, -t.m21, t.m22, MM_2_PT(t.dx + t.m21 * m_dPageHeight), MM_2_PT(m_dPageHeight - m_dPageHeight * t.m22 - t.dy)); CRendererTextCommand* pText = m_oCommandManager.AddText(pCodes, unLen, MM_2_PT(dX), MM_2_PT(m_dPageHeight - dY)); - pText->SetFont(m_pFont); + PdfWriter::CFontDict* pFont = m_pFont; + if (m_pFont14) + pFont = m_pFont14; + pText->SetFont(pFont); pText->SetSize(m_oFont.GetSize()); pText->SetColor(m_oBrush.GetColor1()); pText->SetAlpha((BYTE)m_oBrush.GetAlpha1()); pText->SetCharSpace(MM_2_PT(m_oFont.GetCharSpace())); pText->SetNeedDoBold(m_oFont.IsNeedDoBold()); pText->SetNeedDoItalic(m_oFont.IsNeedDoItalic()); + pText->SetPUA(sPUA); return true; } @@ -2391,24 +3014,80 @@ bool CPdfWriter::PathCommandDrawText(unsigned int* pUnicodes, unsigned int unLen m_oPath.AddText(m_pFont, pCodes, unLen * 2, MM_2_PT(dX), MM_2_PT(m_dPageHeight - dY), m_oFont.GetSize(), MM_2_PT(m_oFont.GetCharSpace())); return true; } +int CPdfWriter::IsEmbeddedBase14(const std::wstring& wsName) +{ + if (wsName.find(L"Embedded: ") != 0) + return -1; + std::wstring sSub = wsName.substr(10); + if (sSub == L"Helvetica") + return 0; + if (sSub == L"Helvetica-Bold") + return 1; + if (sSub == L"Helvetica-Oblique") + return 2; + if (sSub == L"Helvetice-BoldOblique") + return 3; + if (sSub == L"Courier") + return 4; + if (sSub == L"Courier-Bold") + return 5; + if (sSub == L"Courier-Oblique") + return 6; + if (sSub == L"Courier-BoldOblique") + return 7; + if (sSub == L"Times" || sSub == L"Times-Roman") + return 8; + if (sSub == L"Times-Bold") + return 9; + if (sSub == L"Times-Oblique") + return 10; + if (sSub == L"Times-BoldOblique") + return 11; + if (sSub == L"Symbol") + return 12; + if (sSub == L"ZapfDingbats") + return 13; + return -1; +} +bool CPdfWriter::GetBaseFont14(const std::wstring& wsFontName, int nBase14) +{ + std::wstring wsFontPath = m_oFont.GetPath(); + LONG lFaceIndex = m_oFont.GetFaceIndex(); + if (!FindFontPath(wsFontName, m_oFont.IsBold(), m_oFont.IsItalic(), wsFontPath, lFaceIndex)) + return false; + if (!m_pFontManager->LoadFontFromFile(wsFontPath, lFaceIndex, m_oFont.GetSize(), 72, 72)) + return false; + PdfWriter::EStandard14Fonts nType = (PdfWriter::EStandard14Fonts)nBase14; + m_pFont14 = m_pDocument->CreateFont14(wsFontPath, lFaceIndex, nType); + return !!m_pFont14; +} bool CPdfWriter::UpdateFont() { m_bNeedUpdateTextFont = false; + m_pFont14 = NULL; + std::wstring wsFontPath = m_oFont.GetPath(); LONG lFaceIndex = m_oFont.GetFaceIndex(); if (L"" == wsFontPath) { - if (!GetFontPath(m_oFont.GetName(), m_oFont.IsBold(), m_oFont.IsItalic(), wsFontPath, lFaceIndex)) + std::wstring wsFontName = m_oFont.GetName(); + int nBase14 = IsEmbeddedBase14(wsFontName); + if (nBase14 >= 0 && GetBaseFont14(wsFontName, nBase14)) + { + m_pFont = NULL; + return true; + } + if (!GetFontPath(wsFontName, m_oFont.IsBold(), m_oFont.IsItalic(), wsFontPath, lFaceIndex)) { m_pFont = NULL; return false; } } + m_pFont = NULL; m_oFont.SetNeedDoBold(false); m_oFont.SetNeedDoItalic(false); - m_pFont = NULL; if (L"" != wsFontPath) { m_pFont = GetFont(wsFontPath, lFaceIndex); @@ -2425,9 +3104,16 @@ bool CPdfWriter::UpdateFont() } return true; } -bool CPdfWriter::GetFontPath(const std::wstring &wsFontName, const bool &bBold, const bool &bItalic, std::wstring& wsFontPath, LONG& lFaceIndex) +void CPdfWriter::AddFont(const std::wstring& wsFontName, const bool& bBold, const bool& bItalic, const std::wstring& wsFontPath, const LONG& lFaceIndex) +{ + std::wstring _wsFontPath; + LONG _lFaceIndex; + if (FindFontPath(wsFontName, bBold, bItalic, _wsFontPath, _lFaceIndex)) + return; + m_vFonts.push_back(TFontInfo(wsFontName, bBold, bItalic, wsFontPath, lFaceIndex)); +} +bool CPdfWriter::FindFontPath(const std::wstring& wsFontName, const bool& bBold, const bool& bItalic, std::wstring& wsFontPath, LONG& lFaceIndex) { - bool bFind = false; for (int nIndex = 0, nCount = m_vFonts.size(); nIndex < nCount; nIndex++) { TFontInfo& oInfo = m_vFonts.at(nIndex); @@ -2435,10 +3121,14 @@ bool CPdfWriter::GetFontPath(const std::wstring &wsFontName, const bool &bBold, { wsFontPath = oInfo.wsFontPath; lFaceIndex = oInfo.lFaceIndex; - bFind = true; - break; + return true; } } + return false; +} +bool CPdfWriter::GetFontPath(const std::wstring &wsFontName, const bool &bBold, const bool &bItalic, std::wstring& wsFontPath, LONG& lFaceIndex) +{ + bool bFind = FindFontPath(wsFontName, bBold, bItalic, wsFontPath, lFaceIndex); if (!bFind) { @@ -2498,6 +3188,49 @@ PdfWriter::CFontCidTrueType* CPdfWriter::GetFont(const std::wstring& wsFontName, GetFontPath(wsFontName, bBold, bItalic, wsFontPath, lFaceIndex); return GetFont(wsFontPath, lFaceIndex); } +bool CPdfWriter::GetFontData(NSFonts::IApplicationFonts* pAppFonts, const std::wstring& wsValue, PdfWriter::CFontCidTrueType* pFont, bool bBold, bool bItalic, + unsigned int*& pUnicodes, unsigned int& unLen, unsigned short*& pCodes, PdfWriter::CFontCidTrueType**& ppFonts) +{ + pUnicodes = NSStringExt::CConverter::GetUtf32FromUnicode(wsValue, unLen); + if (!pUnicodes) + return false; + + pCodes = new unsigned short[unLen]; + if (!pCodes) + { + RELEASEARRAYOBJECTS(pUnicodes); + return false; + } + + ppFonts = new PdfWriter::CFontCidTrueType*[unLen]; + if (!ppFonts) + { + RELEASEARRAYOBJECTS(pUnicodes); + RELEASEARRAYOBJECTS(pCodes); + return false; + } + + for (unsigned int unIndex = 0; unIndex < unLen; ++unIndex) + { + unsigned int unUnicode = pUnicodes[unIndex]; + + if (!pFont->HaveChar(unUnicode)) + { + std::wstring wsFontFamily = pAppFonts->GetFontBySymbol(unUnicode); + PdfWriter::CFontCidTrueType* pTempFont = GetFont(wsFontFamily, bBold, bItalic); + if (pTempFont) + { + pCodes[unIndex] = pTempFont->EncodeUnicode(unUnicode); + ppFonts[unIndex] = pTempFont; + continue; + } + } + pCodes[unIndex] = pFont->EncodeUnicode(unUnicode); + ppFonts[unIndex] = pFont; + } + + return true; +} void CPdfWriter::UpdateTransform() { CTransform& t = m_oTransform; @@ -2572,12 +3305,21 @@ void CPdfWriter::UpdateBrush(NSFonts::IApplicationFonts* pAppFonts, const std::w if (c_BrushTypeTexture == lBrushType) { std::wstring wsTexturePath = m_oBrush.GetTexturePath(); + BYTE nAlpha = m_oBrush.GetTextureAlpha(); CImageFileFormatChecker oImageFormat(wsTexturePath); PdfWriter::CImageDict* pImage = NULL; int nImageW = 0; int nImageH = 0; - if (_CXIMAGE_FORMAT_JPG == oImageFormat.eFileType || _CXIMAGE_FORMAT_JP2 == oImageFormat.eFileType) + bool bHasImage = false; + if (m_pDocument->HasImage(wsTexturePath, nAlpha)) + { + pImage = m_pDocument->GetImage(wsTexturePath, nAlpha); + nImageH = pImage->GetHeight(); + nImageW = pImage->GetWidth(); + bHasImage = true; + } + else if (_CXIMAGE_FORMAT_JPG == oImageFormat.eFileType || _CXIMAGE_FORMAT_JP2 == oImageFormat.eFileType) { pImage = m_pDocument->CreateImage(); CBgraFrame oFrame; @@ -2591,6 +3333,8 @@ void CPdfWriter::UpdateBrush(NSFonts::IApplicationFonts* pAppFonts, const std::w pImage->LoadJpeg(wsTexturePath.c_str(), nImageW, nImageH, oFrame.IsGrayScale()); else pImage->LoadJpx(wsTexturePath.c_str(), nImageW, nImageH); + + m_pDocument->AddImage(wsTexturePath, nAlpha, pImage); } } else if (_CXIMAGE_FORMAT_WMF == oImageFormat.eFileType || @@ -2634,6 +3378,7 @@ void CPdfWriter::UpdateBrush(NSFonts::IApplicationFonts* pAppFonts, const std::w nImageW = abs((int)oImage.GetWidth()); nImageH = abs((int)oImage.GetHeight()); pImage = LoadImage(&oImage, 255); + m_pDocument->AddImage(wsTexturePath, nAlpha, pImage); } else { @@ -2641,12 +3386,12 @@ void CPdfWriter::UpdateBrush(NSFonts::IApplicationFonts* pAppFonts, const std::w nImageW = abs((int)oImage.GetWidth()); nImageH = abs((int)oImage.GetHeight()); pImage = LoadImage(&oImage, 255); + m_pDocument->AddImage(wsTexturePath, nAlpha, pImage); } if (pImage) { - BYTE nAlpha = m_oBrush.GetTextureAlpha(); - if (0xFF != nAlpha) + if (0xFF != nAlpha && !bHasImage) pImage->AddTransparency(nAlpha); LONG lTextureMode = m_oBrush.GetTextureMode(); @@ -2685,6 +3430,8 @@ void CPdfWriter::UpdateBrush(NSFonts::IApplicationFonts* pAppFonts, const std::w // Размеры картинки заданы в пикселях. Размеры тайла - это размеры картинки в пунктах. dW = (double)nImageW * 72.0 / 96.0; dH = (double)nImageH * 72.0 / 96.0; + + dT = dB; } // Нам нужно, чтобы левый нижний угол границ нашего пата являлся точкой переноса для матрицы преобразования. @@ -2777,7 +3524,7 @@ void CPdfWriter::AddLink(PdfWriter::CPage* pPage, const double& dX, const double if (!pPage || !pDestPage) return; - PdfWriter::CDestination* pDestination = m_pDocument->CreateDestination(unDestPage); + PdfWriter::CDestination* pDestination = m_pDocument->CreateDestination(pDestPage); if (!pDestination) return; @@ -2785,7 +3532,7 @@ void CPdfWriter::AddLink(PdfWriter::CPage* pPage, const double& dX, const double PdfWriter::CAnnotation* pAnnot = m_pDocument->CreateLinkAnnot(PdfWriter::TRect(MM_2_PT(dX), pPage->GetHeight() - MM_2_PT(dY), MM_2_PT(dX + dW), pPage->GetHeight() - MM_2_PT(dY + dH)), pDestination); if (pAnnot && pPage) pPage->AddAnnotation(pAnnot); - pAnnot->SetBorder(0, 0); + pAnnot->SetBorder(0, 0, {}); } bool CPdfWriter::IsValid() { @@ -2810,6 +3557,30 @@ unsigned char* CPdfWriter::EncodeString(const unsigned int *pUnicodes, const uns return NULL; } + if (m_pFont14) + { + unsigned char* pCodes = new unsigned char[unCount * 2]; + if (!pCodes) + return NULL; + + for (unsigned int unIndex = 0; unIndex < unCount; unIndex++) + { + bool bNew = false; + if (pGIDs) + m_pFont14->EncodeUnicode(pGIDs[unIndex], pUnicodes[unIndex], bNew); + if (bNew) + { + TBBoxAdvance oBox = m_pFontManager->MeasureChar2(*pUnicodes); + double dWidth = oBox.fAdvanceX / m_oFont.GetSize() * 1000.0; + m_pFont14->AddWidth(dWidth); + } + + pCodes[2 * unIndex + 0] = (pUnicodes[unIndex] >> 8) & 0xFF; + pCodes[2 * unIndex + 1] = pUnicodes[unIndex] & 0xFF; + } + return pCodes; + } + if (!m_pFont) return NULL; @@ -2839,6 +3610,22 @@ unsigned char* CPdfWriter::EncodeGID(const unsigned int& unGID, const unsigned i return NULL; } + if (m_pFont14) + { + bool bNew = false; + m_pFont14->EncodeUnicode(unGID, *pUnicodes, bNew); + if (bNew) + { + TBBoxAdvance oBox = m_pFontManager->MeasureChar2(*pUnicodes); + double dWidth = oBox.fAdvanceX / m_oFont.GetSize() * 1000.0; + m_pFont14->AddWidth(dWidth); + } + unsigned char* pCodes = new unsigned char[2]; + pCodes[0] = (*pUnicodes >> 8) & 0xFF; + pCodes[1] = *pUnicodes & 0xFF; + return pCodes; + } + if (!m_pFont) return NULL; @@ -2857,6 +3644,7 @@ std::wstring CPdfWriter::GetDownloadFile(const std::wstring& sUrl, const std::ws std::wstring::size_type n2 = sUrl.find(L"http://"); std::wstring::size_type n3 = sUrl.find(L"ftp://"); std::wstring::size_type n4 = sUrl.find(L"https://"); + std::wstring::size_type n5 = sUrl.find(L"file://"); std::wstring::size_type nMax = 3; bool bIsNeedDownload = false; @@ -2868,6 +3656,8 @@ std::wstring CPdfWriter::GetDownloadFile(const std::wstring& sUrl, const std::ws bIsNeedDownload = true; else if (n4 != std::wstring::npos && n4 < nMax) bIsNeedDownload = true; + else if (n5 != std::wstring::npos && n5 < nMax) + bIsNeedDownload = true; if (!bIsNeedDownload) return L""; @@ -2884,3 +3674,486 @@ std::wstring CPdfWriter::GetDownloadFile(const std::wstring& sUrl, const std::ws return L""; } +PdfWriter::CAnnotAppearanceObject* CPdfWriter::DrawAP(PdfWriter::CAnnotation* pAnnot, BYTE* pRender, LONG nLenRender) +{ + if (!pAnnot || !pRender) + return NULL; + + PdfWriter::CPage* pCurPage = m_pPage; + PdfWriter::CPage* pFakePage = m_pDocument->CreateFakePage(); + m_pPage = pFakePage; + m_pDocument->SetCurPage(pFakePage); + m_pPage->StartTransform(1, 0, 0, 1, -pAnnot->GetPageX(), 0); + + PdfWriter::CAnnotAppearanceObject* pAP = pAnnot->StartAP(); + + pFakePage->SetStream(pAP->GetStream()); + pFakePage->Add("Resources", (PdfWriter::CObjectBase*)m_pDocument->GetFieldsResources()); + + IMetafileToRenderter* pCorrector = new IMetafileToRenderter(m_pRenderer); + NSOnlineOfficeBinToPdf::ConvertBufferToRenderer(pRender, nLenRender, pCorrector); + RELEASEOBJECT(pCorrector); + + pAnnot->APFromFakePage(pFakePage); + + m_pPage = pCurPage; + m_pDocument->SetCurPage(pCurPage); + RELEASEOBJECT(pFakePage); + + return pAP; +} +void CPdfWriter::DrawWidgetAP(PdfWriter::CAnnotation* pA, BYTE* pRender, LONG nLenRender) +{ + if (!pA || !pRender) + return; + + PdfWriter::CWidgetAnnotation* pAnnot = (PdfWriter::CWidgetAnnotation*)pA; + + PdfWriter::CPage* pCurPage = m_pPage; + PdfWriter::CPage* pFakePage = m_pDocument->CreateFakePage(); + m_pPage = pFakePage; + m_pDocument->SetCurPage(pFakePage); + m_oTransform.Set(1, 0, 0, 1, PT_2_MM(-pAnnot->GetPageX() - pAnnot->GetRect().fLeft), PT_2_MM(pAnnot->GetRect().fBottom)); + + PdfWriter::CAnnotAppearanceObject* pAP = pAnnot->StartAP(); + pAP->EndText(); + + pFakePage->SetStream(pAP->GetStream()); + pFakePage->Add("Resources", (PdfWriter::CObjectBase*)m_pDocument->GetFieldsResources()); + + pFakePage->SetStrokeColor(0, 0, 0); + pFakePage->SetFillColor(0, 0, 0); + + IMetafileToRenderter* pCorrector = new IMetafileToRenderter(m_pRenderer); + NSOnlineOfficeBinToPdf::ConvertBufferToRenderer(pRender, nLenRender, pCorrector); + RELEASEOBJECT(pCorrector); + + m_oCommandManager.Flush(); + pAP->EndDraw(); + pFakePage->EndMarkedContent(); + + pAnnot->APFromFakePage(pFakePage); + + m_pPage = pCurPage; + m_pDocument->SetCurPage(pCurPage); + RELEASEOBJECT(pFakePage); +} +void CPdfWriter::DrawTextWidget(NSFonts::IApplicationFonts* pAppFonts, PdfWriter::CTextWidget* pTextWidget, const std::wstring& wsValue) +{ + if (!pAppFonts || !pTextWidget) + return; + PdfWriter::CFontCidTrueType* pFont = pTextWidget->GetFont(); + if (!pFont) + return; + PdfWriter::CFontTrueType* pFontTT = m_pDocument->CreateTrueTypeFont(pFont); + double dFontSize = pTextWidget->GetFontSize(); + bool isBold = pTextWidget->GetFontIsBold(); + bool isItalic = pTextWidget->GetFontIsItalic(); + bool isComb = pTextWidget->IsCombFlag(); + double dWidth = pTextWidget->GetWidth(); + double dHeight = pTextWidget->GetHeight(); + BYTE nAlign = pTextWidget->GetQ(); + + if (!pTextWidget->HaveBorder() && pTextWidget->HaveBC()) + pTextWidget->SetBorder(0, 1, {}); + double dShiftBorder = pTextWidget->GetBorderWidth(); + BYTE nType = pTextWidget->GetBorderType(); + if (nType == 1 || nType == 3) + dShiftBorder *= 2; + + // Коды, шрифты, количество + unsigned int unLen = 0; + unsigned int* pUnicodes = NULL; + unsigned short* pCodes = NULL; + PdfWriter::CFontCidTrueType** ppFonts = NULL; + bool bFont = GetFontData(pAppFonts, wsValue, pFont, isBold, isItalic, pUnicodes, unLen, pCodes, ppFonts); + if (!bFont) + { + pTextWidget->SetEmptyAP(); + RELEASEARRAYOBJECTS(pUnicodes); + RELEASEARRAYOBJECTS(pCodes); + RELEASEARRAYOBJECTS(ppFonts); + return; + } + + if (!isComb && pTextWidget->IsMultiLine() && pFontTT) + { + unsigned short* pCodes2 = new unsigned short[unLen]; + unsigned int* pWidths = new unsigned int[unLen]; + + unsigned short ushSpaceCode = 0xFFFF; + unsigned short ushNewLineCode = 0xFFFE; + for (unsigned int unIndex = 0; unIndex < unLen; ++unIndex) + { + unsigned short ushCode = 0; + if (0x0020 == pUnicodes[unIndex]) + ushCode = ushSpaceCode; + else if (0x000D == pUnicodes[unIndex] || 0x000A == pUnicodes[unIndex]) + ushCode = ushNewLineCode; + + pCodes2[unIndex] = ushCode; + pWidths[unIndex] = ppFonts[unIndex]->GetWidth(pCodes[unIndex]); + } + + m_oLinesManager.Init(pCodes2, pWidths, unLen, ushSpaceCode, ushNewLineCode, pFontTT->GetLineHeight(), pFontTT->GetAscent()); + + double dKoef = dFontSize / pFontTT->m_dUnitsPerEm; + double dLineHeight = (pFontTT->m_dAscent + std::abs(pFontTT->m_dDescent)) * dKoef; + + m_oLinesManager.CalculateLines(dFontSize, dWidth - dShiftBorder * 4); + + pTextWidget->StartAP(); + + unsigned int unLinesCount = m_oLinesManager.GetLinesCount(); + double dLineShiftY = dHeight - dShiftBorder * 2 - dLineHeight; + for (unsigned int unIndex = 0; unIndex < unLinesCount; ++unIndex) + { + unsigned int unLineStart = m_oLinesManager.GetLineStartPos(unIndex); + double dLineShiftX = dShiftBorder * 2; + double dLineWidth = m_oLinesManager.GetLineWidth(unIndex, dFontSize); + if (2 == nAlign) + dLineShiftX = dWidth - dLineWidth - dShiftBorder * 2; + else if (1 == nAlign) + dLineShiftX = (dWidth - dLineWidth) / 2; + + int nInLineCount = m_oLinesManager.GetLineEndPos(unIndex) - m_oLinesManager.GetLineStartPos(unIndex); + if (nInLineCount > 0) + pTextWidget->AddLineToAP(dLineShiftX, dLineShiftY, pCodes + unLineStart, nInLineCount, ppFonts + unLineStart, NULL); + + dLineShiftY -= dLineHeight; + } + + pTextWidget->EndAP(); + + m_oLinesManager.Clear(); + + RELEASEARRAYOBJECTS(pCodes2); + RELEASEARRAYOBJECTS(pWidths); + } + else + { + double* pShifts = NULL; + unsigned int unShiftsCount = 0; + double dShiftX = dShiftBorder * 2; + if (dShiftX == 0) + dShiftX = 2; + + if (isComb) + { + unShiftsCount = unLen; + pShifts = new double[unShiftsCount]; + if (pShifts && unShiftsCount) + { + dShiftX = 0; + unsigned int unCellsCount = std::max(unShiftsCount, pTextWidget->GetMaxLen()); + double dPrevW = 0; + double dCellW = dWidth / unCellsCount; + + if (1 == nAlign) + { + unsigned int unCells = (unCellsCount - unShiftsCount) / 2; + dPrevW = unCells * dCellW; + } + if (2 == nAlign) + dPrevW = (unCellsCount - unShiftsCount) * dCellW; + + for (unsigned int unIndex = 0; unIndex < unShiftsCount; ++unIndex) + { + unsigned short ushCode = pCodes[unIndex]; + double dGlyphWidth = ppFonts[unIndex]->GetGlyphWidth(ushCode) / 1000.0 * dFontSize; + double dTempShift = (dCellW - dGlyphWidth) / 2; + pShifts[unIndex] = dPrevW + dTempShift; + dPrevW = dCellW - dTempShift; + } + } + } + else if (1 == nAlign || 2 == nAlign) + { + double dLineWidth = 0; + for (unsigned int unIndex = 0; unIndex < unLen; ++unIndex) + { + unsigned short ushCode = pCodes[unIndex]; + double dLetterWidth = ppFonts[unIndex]->GetWidth(ushCode) / 1000.0 * dFontSize; + dLineWidth += dLetterWidth; + } + + if (2 == nAlign) + dShiftX = dWidth - dLineWidth - dShiftBorder * 2; + else if (1 == nAlign) + dShiftX = (dWidth - dLineWidth) / 2; + } + + double dBaseLine = (dHeight - dFontSize) / 2.0 - dShiftBorder; + if (pFontTT) + { + double dKoef = dFontSize / pFontTT->m_dUnitsPerEm; + double dLineHeight = (pFontTT->m_dAscent + std::abs(pFontTT->m_dDescent)) * dKoef;; + dBaseLine = (dHeight - dLineHeight) / 2.0 + std::abs(pFontTT->m_dDescent * dKoef); + } + + pTextWidget->SetAP(wsValue, pCodes, unLen, dShiftX, dBaseLine, ppFonts, pShifts); + RELEASEARRAYOBJECTS(pShifts); + } + + RELEASEARRAYOBJECTS(pUnicodes); + RELEASEARRAYOBJECTS(pCodes); + RELEASEARRAYOBJECTS(ppFonts); +} +void CPdfWriter::DrawChoiceWidget(NSFonts::IApplicationFonts* pAppFonts, PdfWriter::CChoiceWidget* pChoiceWidget, const std::vector& arrValue) +{ + if (!pAppFonts || !pChoiceWidget) + return; + PdfWriter::CFontCidTrueType* pFont = pChoiceWidget->GetFont(); + if (!pFont) + return; + PdfWriter::CFontTrueType* pFontTT = m_pDocument->CreateTrueTypeFont(pFont); + if (!pFontTT) + return; + double dFontSize = pChoiceWidget->GetFontSize(); + bool isBold = pChoiceWidget->GetFontIsBold(); + bool isItalic = pChoiceWidget->GetFontIsItalic(); + double dWidth = pChoiceWidget->GetWidth(); + double dHeight = pChoiceWidget->GetHeight(); + BYTE nAlign = pChoiceWidget->GetQ(); + + if (!pChoiceWidget->HaveBorder() && pChoiceWidget->HaveBC()) + pChoiceWidget->SetBorder(0, 1, {}); + double dShiftBorder = pChoiceWidget->GetBorderWidth(); + BYTE nType = pChoiceWidget->GetBorderType(); + if (nType == 1 || nType == 3) + dShiftBorder *= 2; + + if (arrValue.empty()) + { + pChoiceWidget->SetEmptyAP(); + return; + } + + if (pChoiceWidget->GetWidgetType() == PdfWriter::WidgetCombobox) + { + std::wstring wsValue = pChoiceWidget->GetValue(arrValue.back()); + unsigned int unLen = 0; + unsigned int* pUnicodes = NULL; + unsigned short* pCodes = NULL; + PdfWriter::CFontCidTrueType** ppFonts = NULL; + bool bFont = GetFontData(pAppFonts, wsValue, pFont, isBold, isItalic, pUnicodes, unLen, pCodes, ppFonts); + if (!bFont) + { + RELEASEARRAYOBJECTS(pUnicodes); + RELEASEARRAYOBJECTS(pCodes); + RELEASEARRAYOBJECTS(ppFonts); + return; + } + + double dShiftX = dShiftBorder * 2; + if (dShiftX == 0) + dShiftX = 2; + if (1 == nAlign || 2 == nAlign) + { + double dSumWidth = 0; + for (unsigned int unIndex = 0; unIndex < unLen; ++unIndex) + { + unsigned short ushCode = pCodes[unIndex]; + double dLetterWidth = ppFonts[unIndex]->GetWidth(ushCode) / 1000.0 * dFontSize; + dSumWidth += dLetterWidth; + } + + if (2 == nAlign) + dShiftX = dWidth - dSumWidth - dShiftBorder * 2; + else if (1 == nAlign) + dShiftX = (dWidth - dSumWidth) / 2; + } + + double dBaseLine = (dHeight - dFontSize) / 2.0 - dShiftBorder; + if (pFontTT) + dBaseLine = (dHeight - pFontTT->m_dHeight * dFontSize / pFontTT->m_dUnitsPerEm) / 2.0 + std::abs(pFontTT->m_dDescent * dFontSize / pFontTT->m_dUnitsPerEm); + + pChoiceWidget->SetAP(wsValue, pCodes, unLen, dShiftX, dBaseLine, ppFonts, NULL); + + RELEASEARRAYOBJECTS(pUnicodes); + RELEASEARRAYOBJECTS(pCodes); + RELEASEARRAYOBJECTS(ppFonts); + } + else // ListBox + { + std::wstring wsValue = pChoiceWidget->SetListBoxIndex(arrValue); + unsigned int unLen = 0; + unsigned int* pUnicodes = NULL; + unsigned short* pCodes = NULL; + PdfWriter::CFontCidTrueType** ppFonts = NULL; + bool bFont = GetFontData(pAppFonts, wsValue, pFont, isBold, isItalic, pUnicodes, unLen, pCodes, ppFonts); + if (!bFont) + { + RELEASEARRAYOBJECTS(pUnicodes); + RELEASEARRAYOBJECTS(pCodes); + RELEASEARRAYOBJECTS(ppFonts); + return; + } + + unsigned short* pCodes2 = new unsigned short[unLen]; + unsigned int* pWidths = new unsigned int[unLen]; + + unsigned short ushSpaceCode = 0xFFFF; + unsigned short ushNewLineCode = 0xFFFE; + for (unsigned int unIndex = 0; unIndex < unLen; ++unIndex) + { + unsigned short ushCode = 0; + if (0x0020 == pUnicodes[unIndex]) + ushCode = ushSpaceCode; + else if (0x000D == pUnicodes[unIndex] || 0x000A == pUnicodes[unIndex]) + ushCode = ushNewLineCode; + + pCodes2[unIndex] = ushCode; + pWidths[unIndex] = ppFonts[unIndex]->GetWidth(pCodes[unIndex]); + } + + m_oLinesManager.Init(pCodes2, pWidths, unLen, ushSpaceCode, ushNewLineCode, pFontTT->GetLineHeight(), pFontTT->GetAscent()); + + m_oLinesManager.CalculateLines(dFontSize, dWidth - dShiftBorder * 4); + + double dKoef = dFontSize / pFontTT->m_dUnitsPerEm; + double dLineHeight = pFontTT->m_dHeight * dKoef; + pChoiceWidget->SetListBoxHeight(dLineHeight); + pChoiceWidget->StartAP(); + + // double dKoef = dFontSize / pFontTT->m_dUnitsPerEm; + // double dDescent = std::abs(pFontTT->m_dDescent * dFontSize / pFontTT->m_dUnitsPerEm); + // double dAscent = dLineHeight - dDescent; + // double dMidPoint = dAscent - pFontTT->m_dMinY * dKoef + dAscent - pFontTT->m_dMaxY * dKoef; + // double dDiff = dLineHeight - dMidPoint; + double dLineShiftY = dHeight - dShiftBorder - dLineHeight + std::abs(pFontTT->m_dDescent * dKoef); + + unsigned int unLinesCount = m_oLinesManager.GetLinesCount(); + for (unsigned int unIndex = 0; unIndex < unLinesCount; ++unIndex) + { + unsigned int unLineStart = m_oLinesManager.GetLineStartPos(unIndex); + double dLineShiftX = dShiftBorder * 2; + if (dLineShiftX == 0) + dLineShiftX = 2; + double dLineWidth = m_oLinesManager.GetLineWidth(unIndex, dFontSize); + if (2 == nAlign) + dLineShiftX = dWidth - dLineWidth - dShiftBorder * 2; + else if (1 == nAlign) + dLineShiftX = (dWidth - dLineWidth) / 2; + + int nInLineCount = m_oLinesManager.GetLineEndPos(unIndex) - m_oLinesManager.GetLineStartPos(unIndex); + if (nInLineCount > 0) + pChoiceWidget->AddLineToAP(dLineShiftX, dLineShiftY, pCodes + unLineStart, nInLineCount, ppFonts + unLineStart, NULL); + + dLineShiftY -= dLineHeight; + if (dLineShiftY < 0) + break; + } + + pChoiceWidget->EndAP(); + + m_oLinesManager.Clear(); + + RELEASEARRAYOBJECTS(pCodes2); + RELEASEARRAYOBJECTS(pWidths); + + RELEASEARRAYOBJECTS(pUnicodes); + RELEASEARRAYOBJECTS(pCodes); + RELEASEARRAYOBJECTS(ppFonts); + } +} +void CPdfWriter::DrawButtonWidget(NSFonts::IApplicationFonts* pAppFonts, PdfWriter::CPushButtonWidget* pButtonWidget, BYTE nAP, PdfWriter::CXObject* pForm) +{ + if (!pAppFonts || !pButtonWidget) + return; + + double dShiftX = 0; + double dShiftY = 0; + double dLineW = 0; + double dLineH = 0; + unsigned int unLen = 0; + unsigned int* pUnicodes = NULL; + unsigned short* pCodes = NULL; + PdfWriter::CFontCidTrueType** ppFonts = NULL; + BYTE nTP = pButtonWidget->GetTP(); + std::wstring wsValue; + if (nAP == 0) + wsValue = pButtonWidget->GetCA(); + else if (nAP == 1) + wsValue = pButtonWidget->GetRC().empty() ? pButtonWidget->GetCA() : pButtonWidget->GetRC(); + else + wsValue = pButtonWidget->GetAC().empty() ? pButtonWidget->GetCA() : pButtonWidget->GetAC(); + + if (!pButtonWidget->HaveBorder() && pButtonWidget->HaveBC()) + pButtonWidget->SetBorder(0, 1, {}); + + if (!wsValue.empty() && nTP != 1) + { + PdfWriter::CFontCidTrueType* pFont = pButtonWidget->GetFont(); + if (!pFont) + return; + PdfWriter::CFontTrueType* pFontTT = m_pDocument->CreateTrueTypeFont(pFont); + double dFontSize = pButtonWidget->GetFontSize(); + bool isBold = pButtonWidget->GetFontIsBold(); + bool isItalic = pButtonWidget->GetFontIsItalic(); + double dWidth = pButtonWidget->GetWidth(); + double dHeight = pButtonWidget->GetHeight(); + + double dShiftBorder = pButtonWidget->GetBorderWidth(); + BYTE nType = pButtonWidget->GetBorderType(); + if (nType == 1 || nType == 3) + dShiftBorder *= 2; + if (dShiftBorder == 0) + dShiftBorder = 1; + double dShiftRespectBorder = dShiftBorder / 2; + bool bRespectBorder = pButtonWidget->GetRespectBorder(); + if (!bRespectBorder) + dShiftBorder = 0; + + bool bFont = GetFontData(pAppFonts, wsValue, pFont, isBold, isItalic, pUnicodes, unLen, pCodes, ppFonts); + if (!bFont) + { + RELEASEARRAYOBJECTS(pUnicodes); + RELEASEARRAYOBJECTS(pCodes); + RELEASEARRAYOBJECTS(ppFonts); + return; + } + + for (unsigned int unIndex = 0; unIndex < unLen; ++unIndex) + { + unsigned short ushCode = pCodes[unIndex]; + double dLetterWidth = ppFonts[unIndex]->GetWidth(ushCode) / 1000.0 * dFontSize; + dLineW += dLetterWidth; + } + + if (pFontTT) + { + double dKoef = dFontSize / pFontTT->m_dUnitsPerEm; + // TODO что-то между m_dMaxY-m_dMinY и m_dHeight, но не просто среднее + dLineH = (pFontTT->m_dMaxY + std::abs(pFontTT->m_dMinY) + pFontTT->m_dHeight) / 2.0 * dKoef; + // dLineH = (pFontTT->m_dMaxY + std::abs(pFontTT->m_dMinY)) * dKoef; + // dLineH = pFontTT->m_dHeight * dKoef; + // double dLineHeight = pFontTT->m_dHeight * dKoef; + // double dDescent = std::abs(pFontTT->m_dDescent * dKoef); + // double dAscent1 = pFontTT->m_dAscent * dKoef; + // double dAscent = dLineHeight - dDescent; + // double dMidPoint = dAscent - pFontTT->m_dMinY * dKoef + dAscent - pFontTT->m_dMaxY * dKoef; + // double dDiff = dLineHeight - dMidPoint; + + if (nTP == 0 || nTP == 2 || nTP == 3 || nTP == 6) + dShiftX = (dWidth - dLineW) / 2; + else if (nTP == 4) + dShiftX = dWidth - dLineW - dShiftBorder * 2 + dShiftRespectBorder; + else if (nTP == 5) + dShiftX = dShiftBorder * 2 + dShiftRespectBorder; + + if (nTP == 0 || nTP == 6 || nTP == 4 || nTP == 5) + dShiftY = (dHeight - dLineH) / 2 + std::abs(pFontTT->m_dMinY * dKoef); + else if (nTP == 3) + dShiftY = dHeight - dShiftBorder * 2 - dShiftRespectBorder - dLineH + std::abs(pFontTT->m_dMinY * dKoef); + else if (nTP == 2) + dShiftY = dShiftBorder * 2 + std::abs(pFontTT->m_dMinY * dKoef); + } + } + + pButtonWidget->SetAP(pForm, nAP, pCodes, unLen, dShiftX, dShiftY, dLineW, dLineH, ppFonts); + + RELEASEARRAYOBJECTS(pUnicodes); + RELEASEARRAYOBJECTS(pCodes); + RELEASEARRAYOBJECTS(ppFonts); +} diff --git a/PdfFile/PdfWriter.h b/PdfFile/PdfWriter.h index 6986c25d011..38fa7fc70f3 100644 --- a/PdfFile/PdfWriter.h +++ b/PdfFile/PdfWriter.h @@ -32,19 +32,19 @@ #ifndef _PDF_WRITER_H #define _PDF_WRITER_H -#include "../../DesktopEditor/graphics/IRenderer.h" -#include "../../DesktopEditor/graphics/pro/Fonts.h" -#include "../../DesktopEditor/graphics/pro/Image.h" -#include "../../DesktopEditor/xmlsec/src/include/Certificate.h" -#include "SrcWriter/States.h" - #include #include #include -#include "../../DesktopEditor/graphics/commands/DocInfo.h" +#include "../../DesktopEditor/graphics/IRenderer.h" +#include "../../DesktopEditor/graphics/pro/Fonts.h" +#include "../../DesktopEditor/graphics/pro/Image.h" #include "../../DesktopEditor/graphics/commands/FormField.h" +#include "../../DesktopEditor/graphics/commands/DocInfo.h" #include "../../DesktopEditor/graphics/commands/AnnotField.h" +#include "../../DesktopEditor/xmlsec/src/include/Certificate.h" +#include "SrcWriter/States.h" +#include "SrcWriter/Annotation.h" namespace PdfWriter { @@ -64,7 +64,7 @@ namespace Aggplus class CPdfWriter { public: - CPdfWriter(NSFonts::IApplicationFonts* pAppFonts, bool isPDFA = false, IRenderer* pRenderer = NULL); + CPdfWriter(NSFonts::IApplicationFonts* pAppFonts, bool isPDFA = false, IRenderer* pRenderer = NULL, bool bCreate = true); ~CPdfWriter(); int SaveToFile(const std::wstring& wsPath); void SetPassword(const std::wstring& wsPassword); @@ -158,7 +158,7 @@ class CPdfWriter //---------------------------------------------------------------------------------------- // Маркеры команд //---------------------------------------------------------------------------------------- - HRESULT EndCommand(const DWORD& lType, const LONG& lClipMode); + HRESULT EndCommand(const DWORD& lType); //---------------------------------------------------------------------------------------- // Функции для работы с патом //---------------------------------------------------------------------------------------- @@ -195,6 +195,9 @@ class CPdfWriter HRESULT AddLink(const double& dX, const double& dY, const double& dW, const double& dH, const double& dDestX, const double& dDestY, const int& nPage); HRESULT AddFormField (NSFonts::IApplicationFonts* pAppFonts, CFormFieldInfo* pFieldInfo, const std::wstring& wsTempDirectory); HRESULT AddAnnotField(NSFonts::IApplicationFonts* pAppFonts, CAnnotFieldInfo* pFieldInfo); + HRESULT AddMetaData(const std::wstring& sMetaName, BYTE* pMetaData, DWORD nMetaLength); + HRESULT get_ClipMode(LONG* lMode); + HRESULT put_ClipMode(const LONG& lMode); //---------------------------------------------------------------------------------------- // Дополнительные функции Pdf рендерера //---------------------------------------------------------------------------------------- @@ -203,7 +206,6 @@ class CPdfWriter HRESULT SetLinearGradient(const double& dX1, const double& dY1, const double& dX2, const double& dY2); HRESULT SetRadialGradient(const double& dX1, const double& dY1, const double& dR1, const double& dX2, const double& dY2, const double& dR2); HRESULT DrawImageWith1bppMask(IGrObject* pImage, NSImages::CPixJbig2* pMaskBuffer, const unsigned int& unMaskWidth, const unsigned int& unMaskHeight, const double& dX, const double& dY, const double& dW, const double& dH); - //---------------------------------------------------------------------------------------- // Дополнительные функции для дозаписи Pdf //---------------------------------------------------------------------------------------- @@ -212,20 +214,27 @@ class CPdfWriter bool EditClose(); void PageRotate(int nRotate); void Sign(const double& dX, const double& dY, const double& dW, const double& dH, const std::wstring& wsPicturePath, ICertificate* pCertificate); - - PdfWriter::CDocument* m_pDocument; - PdfWriter::CPage* m_pPage; + HRESULT EditWidgetParents(NSFonts::IApplicationFonts* pAppFonts, CWidgetsInfo* pFieldInfo, const std::wstring& wsTempDirectory); + PdfWriter::CDocument* GetDocument(); + PdfWriter::CPage* GetPage(); + void AddFont(const std::wstring& wsFontName, const bool& bBold, const bool& bItalic, const std::wstring& wsFontPath, const LONG& lFaceIndex); + void SetHeadings(CHeadings* pCommand); private: - PdfWriter::CImageDict* LoadImage(Aggplus::CImage* pImage, const BYTE& nAlpha); - bool DrawImage(Aggplus::CImage* pImage, const double& dX, const double& dY, const double& dW, const double& dH, const BYTE& nAlpha); - bool DrawText(unsigned char* pCodes, const unsigned int& unLen, const double& dX, const double& dY); + PdfWriter::CImageDict* LoadImage(Aggplus::CImage* pImage, BYTE nAlpha); + PdfWriter::CImageDict* DrawImage(Aggplus::CImage* pImage, const double& dX, const double& dY, const double& dW, const double& dH, const BYTE& nAlpha); + bool DrawText(unsigned char* pCodes, const unsigned int& unLen, const double& dX, const double& dY, const std::string& sPUA); bool DrawTextToRenderer(const unsigned int* unGid, const unsigned int& unLen, const double& dX, const double& dY); bool PathCommandDrawText(unsigned int* pUnicodes, unsigned int unLen, const double& dX, const double& dY, const unsigned int* pGids = NULL); + int IsEmbeddedBase14(const std::wstring& wsFontName); + bool GetBaseFont14(const std::wstring& wsFontName, int nBase14); bool UpdateFont(); + bool FindFontPath(const std::wstring& wsFontName, const bool& bBold, const bool& bItalic, std::wstring& wsFontPath, LONG& lFaceIndex); bool GetFontPath(const std::wstring& wsFontName, const bool& bBold, const bool& bItalic, std::wstring& wsFontPath, LONG& lFaceIndex); PdfWriter::CFontCidTrueType* GetFont(const std::wstring& wsFontPath, const LONG& lFontIndex); PdfWriter::CFontCidTrueType* GetFont(const std::wstring& wsFontName, const bool& bBold, const bool& bItalic); + bool GetFontData(NSFonts::IApplicationFonts* pAppFonts, const std::wstring& wsValue, PdfWriter::CFontCidTrueType* pFont, bool bBold, bool bItalic, + unsigned int*& pUnicodes, unsigned int& unLen, unsigned short*& pCodes, PdfWriter::CFontCidTrueType**& ppFonts); void UpdateTransform(); void UpdatePen(); void UpdateBrush(NSFonts::IApplicationFonts* pAppFonts, const std::wstring& wsTempDirectory); @@ -237,31 +246,33 @@ class CPdfWriter unsigned char* EncodeString(const unsigned int* pUnicodes, const unsigned int& unUnicodesCount, const unsigned int* pGIDs = NULL); unsigned char* EncodeGID(const unsigned int& unGID, const unsigned int* pUnicodes, const unsigned int& unUnicodesCount); std::wstring GetDownloadFile(const std::wstring& sUrl, const std::wstring& wsTempDirectory); + PdfWriter::CAnnotAppearanceObject* DrawAP(PdfWriter::CAnnotation* pAnnot, BYTE* pRender, LONG nLenRender); + void DrawWidgetAP(PdfWriter::CAnnotation* pAnnot, BYTE* pRender, LONG nLenRender); + void DrawTextWidget (NSFonts::IApplicationFonts* pAppFonts, PdfWriter::CTextWidget* pTextWidget, const std::wstring& wsValue); + void DrawChoiceWidget(NSFonts::IApplicationFonts* pAppFonts, PdfWriter::CChoiceWidget* pChoiceWidget, const std::vector& arrValue); + void DrawButtonWidget(NSFonts::IApplicationFonts* pAppFonts, PdfWriter::CPushButtonWidget* pButtonWidget, BYTE nAP, PdfWriter::CXObject* pForm); private: NSFonts::IFontManager* m_pFontManager; IRenderer* m_pRenderer; - + PdfWriter::CDocument* m_pDocument; + PdfWriter::CPage* m_pPage; PdfWriter::CFontCidTrueType* m_pFont; + PdfWriter::CFont14* m_pFont14; PdfWriter::CShading* m_pShading; PdfWriter::CExtGrState* m_pShadingExtGrState; - bool m_bNeedUpdateTextFont; - bool m_bNeedUpdateTextColor; - bool m_bNeedUpdateTextAlpha; - bool m_bNeedUpdateTextCharSpace; - bool m_bNeedUpdateTextSize; - CCommandManager m_oCommandManager; - CPenState m_oPen; CBrushState m_oBrush; CFontState m_oFont; CPath m_oPath; CTransform m_oTransform; + bool m_bNeedUpdateTextFont; double m_dPageHeight; double m_dPageWidth; LONG m_lClipDepth; + LONG m_lClipMode; std::vector m_vFonts; std::vectorm_vDestinations; unsigned int m_unFieldsCounter; diff --git a/PdfFile/SrcReader/Adaptors.cpp b/PdfFile/SrcReader/Adaptors.cpp index 60f1be6590b..ad8da8382cd 100644 --- a/PdfFile/SrcReader/Adaptors.cpp +++ b/PdfFile/SrcReader/Adaptors.cpp @@ -34,7 +34,6 @@ #include "../lib/xpdf/TextString.h" #include "../../DesktopEditor/graphics/pro/js/wasm/src/serialize.h" - void GlobalParamsAdaptor::SetFontManager(NSFonts::IFontManager *pFontManager) { m_pFontManager = pFontManager; @@ -187,44 +186,9 @@ bool GlobalParamsAdaptor::GetCMap(const char* sName, char*& pData, unsigned int& return false; } -void GlobalParamsAdaptor::AddTextFormField(const std::wstring& sText, const std::wstring& sFontName, double dFontSize) -{ - if (!m_arrTextFormField.empty()) - { - TextFormField& tFF = m_arrTextFormField.back(); - if (tFF.sFontName == sFontName && tFF.dFontSize == dFontSize) - { - tFF.sText += sText; - return; - } - } - m_arrTextFormField.push_back({sText, sFontName, dFontSize}); -} -BYTE* GlobalParamsAdaptor::GetTextFormField() -{ - NSWasm::CData oRes; - oRes.SkipLen(); - - oRes.AddInt(m_arrTextFormField.size()); - for (TextFormField& tFF : m_arrTextFormField) - { - std::string sText = U_TO_UTF8(tFF.sText); - std::string sFontName = U_TO_UTF8(tFF.sFontName); - oRes.WriteString((BYTE*)sText.c_str(), (unsigned int)sText.length()); - oRes.WriteString((BYTE*)sFontName.c_str(), (unsigned int)sFontName.length()); - oRes.AddDouble(tFF.dFontSize); - } - m_arrTextFormField.clear(); - - oRes.WriteLen(); - BYTE* bRes = oRes.GetBuffer(); - oRes.ClearWithoutAttack(); - return bRes; -} - bool operator==(const Ref &a, const Ref &b) { - return a.gen == b.gen && a.num == b.gen; + return a.gen == b.gen && a.num == b.num; } bool operator<(const Ref &a, const Ref &b) diff --git a/PdfFile/SrcReader/Adaptors.h b/PdfFile/SrcReader/Adaptors.h index 21f63aa878e..825c4801f14 100644 --- a/PdfFile/SrcReader/Adaptors.h +++ b/PdfFile/SrcReader/Adaptors.h @@ -59,13 +59,6 @@ class GlobalParamsAdaptor : public GlobalParams BYTE* m_bCMapData; DWORD m_nCMapDataLength; - struct TextFormField - { - std::wstring sText; - std::wstring sFontName; - double dFontSize; - }; - std::vector m_arrTextFormField; bool m_bDrawFormField; public: @@ -97,8 +90,6 @@ class GlobalParamsAdaptor : public GlobalParams void SetCMapMemory(BYTE* pData, DWORD nSizeData); bool GetCMap(const char* sName, char*& pData, unsigned int& nSize); - void AddTextFormField(const std::wstring& sText, const std::wstring& sFontName, double dFontSize); - BYTE* GetTextFormField(); void setDrawFormField(bool bDrawFormField) { m_bDrawFormField = bDrawFormField; } bool getDrawFormField() { return m_bDrawFormField; } private: diff --git a/PdfFile/SrcReader/GfxClip.h b/PdfFile/SrcReader/GfxClip.h index 1a12a806914..60fb159cacd 100644 --- a/PdfFile/SrcReader/GfxClip.h +++ b/PdfFile/SrcReader/GfxClip.h @@ -37,6 +37,7 @@ #include #include #include "../lib/xpdf/GfxState.h" +#include "../../DesktopEditor/common/Types.h" #include "MemoryUtils.h" struct GfxClipMatrix @@ -345,24 +346,23 @@ class GfxClip public: GfxClip() { - m_pTextClip = new GfxTextClip(); } ~GfxClip() { - delete m_pTextClip; + for (int i = 0; i < m_vPaths.size(); ++i) + RELEASEOBJECT(m_vPaths[i]); } - void AddPath(GfxPath *pPath, double *Matrix, bool bEo) + void AddPath(GfxPath *pPath, double *Matrix, int nFlag) { if (pPath && Matrix) { m_vPaths.push_back(pPath->copy()); m_vMatrix.push_back(GfxClipMatrix()); m_vMatrix.back().FromDoublePointer(Matrix); - m_vPathsClipEo.push_back(bEo); + m_vPathsClipFlag.push_back(nFlag); } - } size_t GetPathNum() @@ -375,9 +375,9 @@ class GfxClip return m_vPaths[i]; } - bool GetClipEo(int i) + int GetClipFlag(int i) { - return m_vPathsClipEo[i]; + return m_vPathsClipFlag[i]; } bool IsChanged() @@ -390,23 +390,11 @@ class GfxClip m_bChanged = b; } - GfxTextClip *GetTextClip() const - { - return m_pTextClip; - } - - GfxClip(const GfxClip &c) { - m_pTextClip = new GfxTextClip(c.GetTextClip()); - }; - std::vector m_vMatrix; private: - - std::vector m_vPaths; - std::vector m_vPathsClipEo; + std::vector m_vPathsClipFlag; bool m_bChanged; - GfxTextClip *m_pTextClip; }; diff --git a/PdfFile/SrcReader/PdfAnnot.cpp b/PdfFile/SrcReader/PdfAnnot.cpp index 5bc3f9fec7c..6db2cbd03b7 100644 --- a/PdfFile/SrcReader/PdfAnnot.cpp +++ b/PdfFile/SrcReader/PdfAnnot.cpp @@ -31,35 +31,38 @@ */ #include "PdfAnnot.h" +#include "RendererOutputDev.h" +#include "Adaptors.h" + #include "../lib/xpdf/TextString.h" #include "../lib/xpdf/Link.h" #include "../lib/xpdf/Annot.h" +#include "../lib/xpdf/GfxFont.h" +#include "../lib/xpdf/Lexer.h" +#include "../lib/xpdf/Parser.h" #include "../lib/goo/GList.h" +#include "../Resources/BaseFonts.h" #include "../../DesktopEditor/common/Types.h" #include "../../DesktopEditor/common/StringExt.h" +#include "../../DesktopEditor/xml/include/xmlutils.h" +#include "../../DesktopEditor/fontengine/ApplicationFonts.h" +#include "../../DesktopEditor/graphics/pro/Fonts.h" + +#include namespace PdfReader { -#define DICT_LOOKUP_STRING(func, sName, byte, put) \ -{\ -if (func(sName, &oObj)->isString())\ -{\ - m_unFlags |= (1 << byte);\ - TextString* s = new TextString(oObj.getString());\ - put = NSStringExt::CConverter::GetUtf8FromUTF32(s->getUnicode(), s->getLength());\ - delete s;\ -}\ -oObj.free();\ -} -#define ARR_GET_NUM(take, get, put) \ -{\ - if (take.arrayGet(get, &oObj2)->isNum())\ - put = oObj2.getNum();\ - oObj2.free();\ +double ArrGetNum(Object* pArr, int nI) +{ + double dRes = 0.0; + Object oObj; + if (pArr->arrayGet(nI, &oObj)->isNum()) + dRes = oObj.getNum(); + oObj.free(); + return dRes; } - TextString* getName(Object* oField) { TextString* sResName = NULL; @@ -127,12 +130,18 @@ CAction* getAction(PDFDoc* pdfDoc, Object* oAction) if (pLinkDest->isPageRef()) { Ref pageRef = pLinkDest->getPageRef(); - ppRes->unPage = pdfDoc->findPage(pageRef.num, pageRef.gen) - 1; + ppRes->unPage = pdfDoc->findPage(pageRef.num, pageRef.gen); } else - ppRes->unPage = pLinkDest->getPageNum() - 1; + ppRes->unPage = pLinkDest->getPageNum(); + + if (ppRes->unPage > 0) + --ppRes->unPage; ppRes->nKind = pLinkDest->getKind(); - double dHeight = pdfDoc->getPageCropHeight(ppRes->unPage + 1); + + PDFRectangle* pCropBox = pdfDoc->getCatalog()->getPage(ppRes->unPage + 1)->getCropBox(); + double dHeight = pCropBox->y2; + double dX = pCropBox->x1; switch (ppRes->nKind) { case destXYZ: @@ -142,20 +151,19 @@ CAction* getAction(PDFDoc* pdfDoc, Object* oAction) case destFitBV: { ppRes->unKindFlag = 0; - // 1 - left + // 0 - left if (pLinkDest->getChangeLeft()) { ppRes->unKindFlag |= (1 << 0); - ppRes->pRect[0] = pLinkDest->getLeft(); + ppRes->pRect[0] = pLinkDest->getLeft() - dX; } - // 2 - top + // 1 - top if (pLinkDest->getChangeTop()) { ppRes->unKindFlag |= (1 << 1); - double dTop = dHeight - pLinkDest->getTop(); - ppRes->pRect[1] = (dTop < 0 ? 0.0 : dTop); + ppRes->pRect[1] = dHeight - pLinkDest->getTop(); } - // 3 - zoom + // 2 - zoom if (pLinkDest->getChangeZoom() && pLinkDest->getZoom()) { ppRes->unKindFlag |= (1 << 2); @@ -165,13 +173,10 @@ CAction* getAction(PDFDoc* pdfDoc, Object* oAction) } case destFitR: { - - ppRes->pRect[0] = pLinkDest->getLeft(); - double dTop = dHeight - pLinkDest->getTop(); - ppRes->pRect[1] = (dTop < 0 ? 0.0 : dTop); - ppRes->pRect[2] = pLinkDest->getRight(); - dTop = dHeight - pLinkDest->getBottom(); - ppRes->pRect[3] = (dTop < 0 ? 0.0 : dTop); + ppRes->pRect[0] = pLinkDest->getLeft() - dX; + ppRes->pRect[1] = dHeight - pLinkDest->getTop(); + ppRes->pRect[2] = pLinkDest->getRight() - dX; + ppRes->pRect[3] = dHeight - pLinkDest->getBottom(); break; } case destFit: @@ -324,7 +329,7 @@ CAction* getAction(PDFDoc* pdfDoc, Object* oAction) RELEASEOBJECT(oAct); return pRes; }; -std::string getValue(Object* oV) +std::string getValue(Object* oV, bool bArray = true) { std::string sRes; if (oV->isName()) @@ -343,7 +348,7 @@ std::string getValue(Object* oV) } oContents.free(); } - else if (oV->isArray()) + else if (bArray && oV->isArray()) { Object oContents; if (oV->arrayGet(0, &oContents)->isString()) @@ -410,6 +415,646 @@ BYTE getLE(Object* oObj) return nLE; } +CAnnotFileAttachment::CEmbeddedFile* getEF(Object* oObj) +{ + CAnnotFileAttachment::CEmbeddedFile* pRes = new CAnnotFileAttachment::CEmbeddedFile(); + + Object oObj2; + Dict* pImDict = oObj->streamGetDict(); + if (pImDict->lookup("Length", &oObj2)->isInt()) + pRes->nLength = oObj2.getInt(); + oObj2.free(); + if (pImDict->lookup("DL", &oObj2)->isInt()) + pRes->nLength = oObj2.getInt(); + oObj2.free(); + + Stream* pImage = oObj->getStream(); + pImage->reset(); + pRes->pFile = new BYTE[pRes->nLength]; + BYTE* pBufferPtr = pRes->pFile; + for (int nI = 0; nI < pRes->nLength; ++nI) + *pBufferPtr++ = (BYTE)pImage->getChar(); + + return pRes; +} +GList* tokenize(GString *s) +{ + GList *toks; + int i, j; + + toks = new GList(); + i = 0; + while (i < s->getLength()) { + while (i < s->getLength() && Lexer::isSpace(s->getChar(i))) { + ++i; + } + if (i < s->getLength()) { + for (j = i + 1; + j < s->getLength() && !Lexer::isSpace(s->getChar(j)); + ++j) ; + toks->append(new GString(s, i, j - i)); + i = j; + } + } + return toks; +} +CAnnot::CBorderType* getBorder(Object* oBorder, bool bBSorBorder) +{ + // Границы и Dash Pattern - Border/BS + CAnnot::CBorderType* pBorderType = new CAnnot::CBorderType(); + if (!oBorder) + return pBorderType; + if (bBSorBorder) + { + pBorderType->nType = annotBorderSolid; + Object oV; + if (oBorder->dictLookup("S", &oV)->isName()) + { + if (oV.isName("S")) + pBorderType->nType = annotBorderSolid; + else if (oV.isName("D")) + pBorderType->nType = annotBorderDashed; + else if (oV.isName("B")) + pBorderType->nType = annotBorderBeveled; + else if (oV.isName("I")) + pBorderType->nType = annotBorderInset; + else if (oV.isName("U")) + pBorderType->nType = annotBorderUnderlined; + } + oV.free(); + if (oBorder->dictLookup("W", &oV)->isNum()) + pBorderType->dWidth = oV.getNum(); + oV.free(); + if (oBorder->dictLookup("D", &oV)->isArray()) + { + for (int j = 0; j < oV.arrayGetLength(); ++j) + { + Object oObj2; + if (oV.arrayGet(j, &oObj2)->isNum()) + pBorderType->arrDash.push_back(oObj2.getNum()); + oObj2.free(); + } + } + oV.free(); + } + else + { + pBorderType->nType = annotBorderSolid; + pBorderType->dWidth = ArrGetNum(oBorder, 2); + if (!pBorderType->dWidth) + pBorderType->dWidth = 1.0; + + Object oObj; + if (oBorder->arrayGetLength() > 3 && oBorder->arrayGet(3, &oObj)->isArray() && oObj.arrayGetLength() > 1) + { + pBorderType->nType = annotBorderDashed; + for (int j = 0; j < oObj.arrayGetLength(); ++j) + { + Object oObj2; + if (oObj.arrayGet(j, &oObj2)->isNum()) + pBorderType->arrDash.push_back(oObj2.getNum()); + oObj2.free(); + } + } + oObj.free(); + } + + return pBorderType; +} + +//------------------------------------------------------------------------ +// Fonts +//------------------------------------------------------------------------ + +bool CAnnotFonts::IsBaseFont(const std::wstring& wsName) +{ + return wsName == L"Courier" || wsName == L"Courier-Bold" || wsName == L"Courier-BoldOblique" || wsName == L"Courier-Oblique" || + wsName == L"Helvetica" || wsName == L"Helvetica-Bold" || wsName == L"Helvetica-BoldOblique" || + wsName == L"Helvetica-Oblique" || wsName == L"Symbol" || wsName == L"Times-Bold" || wsName == L"Times-BoldItalic" || + wsName == L"Times-Italic" || wsName == L"Times-Roman" || wsName == L"ZapfDingbats"; +} +std::map CAnnotFonts::GetAllFonts(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CPdfFontList* pFontList) +{ + std::map mFonts; + + AcroForm* pAcroForms = pdfDoc->getCatalog()->getForm(); + if (pAcroForms) + { + std::vector arrUniqueFontsRef; + for (int nField = 0, nNum = pAcroForms->getNumFields(); nField < nNum; ++nField) + { + AcroFormField* pField = pAcroForms->getField(nField); + if (!pField) + continue; + + // Шрифт и размер шрифта - из DA + Ref fontID; + double dFontSize = 0; + pField->getFont(&fontID, &dFontSize); + + Object oFontRef; + if (fontID.num < 0) + { + std::string sFontKey; + if (!GetFontFromAP(pdfDoc, pField, &oFontRef, sFontKey)) + { + oFontRef.free(); + continue; + } + } + else + oFontRef.initRef(fontID.num, fontID.gen); + + if (std::find(arrUniqueFontsRef.begin(), arrUniqueFontsRef.end(), oFontRef.getRefNum()) != arrUniqueFontsRef.end()) + { + oFontRef.free(); + continue; + } + + std::string sFontName; + std::string sActualFontName; + std::wstring wsFileName; + bool bBold = false, bItalic = false; + wsFileName = GetFontData(pdfDoc, pFontManager, pFontList, &oFontRef, sFontName, sActualFontName, bBold, bItalic); + + if (!sActualFontName.empty()) + { + oFontRef.free(); + continue; + } + + if (!sFontName.empty()) + { + std::wstring wsFontName = UTF8_TO_U(sFontName); + if (mFonts.find(wsFontName) == mFonts.end()) + { + arrUniqueFontsRef.push_back(oFontRef.getRefNum()); + mFonts[wsFontName] = wsFileName; + } + } + oFontRef.free(); + + if (pField->getAcroFormFieldType() == acroFormFieldPushbutton && fontID.num >= 0) + { + std::string sFontKey; + if (GetFontFromAP(pdfDoc, pField, &oFontRef, sFontKey) && std::find(arrUniqueFontsRef.begin(), arrUniqueFontsRef.end(), oFontRef.getRefNum()) == arrUniqueFontsRef.end()) + { + wsFileName = GetFontData(pdfDoc, pFontManager, pFontList, &oFontRef, sFontName, sActualFontName, bBold, bItalic); + + std::wstring wsFontName = UTF8_TO_U(sFontName); + if (sActualFontName.empty() && mFonts.find(wsFontName) == mFonts.end()) + { + arrUniqueFontsRef.push_back(oFontRef.getRefNum()); + mFonts[wsFontName] = wsFileName; + } + } + } + oFontRef.free(); + } + } + + for (int nPage = 0, nLastPage = pdfDoc->getNumPages(); nPage < nLastPage; ++nPage) + { + Page* pPage = pdfDoc->getCatalog()->getPage(nPage + 1); + if (!pPage) + continue; + + Object oAnnots; + if (!pPage->getAnnots(&oAnnots)->isArray()) + { + oAnnots.free(); + continue; + } + + for (int i = 0, nNum = oAnnots.arrayGetLength(); i < nNum; ++i) + { + Object oAnnot; + if (!oAnnots.arrayGet(i, &oAnnot)->isDict()) + { + oAnnot.free(); + continue; + } + + Object oSubtype; + if (!oAnnot.dictLookup("Subtype", &oSubtype)->isName("FreeText")) + { + oSubtype.free(); oAnnot.free(); + continue; + } + oSubtype.free(); + + Object oObj; + if (!oAnnot.dictLookup("RC", &oObj)->isString()) + { + oObj.free(); + if (oAnnot.dictLookup("AP", &oObj)->isNull() && oAnnot.dictLookup("Contents", &oObj)->isString() && oObj.getString()->getLength()) + { + const unsigned char* pData14 = NULL; + unsigned int nSize14 = 0; + std::wstring wsFontName = L"Helvetica"; + NSFonts::IFontsMemoryStorage* pMemoryStorage = NSFonts::NSApplicationFontStream::GetGlobalMemoryStorage(); + if (pMemoryStorage && !pMemoryStorage->Get(wsFontName) && GetBaseFont(wsFontName, pData14, nSize14)) + pMemoryStorage->Add(wsFontName, (BYTE*)pData14, nSize14, false); + mFonts[L"Helvetica"] = L"Helvetica"; + } + oAnnot.free(); oObj.free(); + continue; + } + oAnnot.free(); + + TextString* s = new TextString(oObj.getString()); + std::string sRC = NSStringExt::CConverter::GetUtf8FromUTF32(s->getUnicode(), s->getLength()); + delete s; + oObj.free(); + + Object oAnnotRef; + oAnnots.arrayGetNF(i, &oAnnotRef); + std::vector arrRC = CAnnotMarkup::ReadRC(sRC); + std::map mFreeText = GetFreeTextFont(pdfDoc, pFontManager, pFontList, &oAnnotRef, arrRC); + for (std::map::iterator it = mFreeText.begin(); it != mFreeText.end(); ++it) + { + if (mFonts.find(it->first) != mFonts.end()) + continue; + mFonts[it->first] = it->second; + } + oAnnotRef.free(); + for (int j = 0; j < arrRC.size(); ++j) + RELEASEOBJECT(arrRC[j]); + } + oAnnots.free(); + } + + return mFonts; +} +std::wstring CAnnotFonts::GetFontData(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CPdfFontList *pFontList, Object* oFontRef, std::string& sFontName, std::string& sActualFontName, bool& bBold, bool& bItalic) +{ + bBold = false, bItalic = false; + XRef* xref = pdfDoc->getXRef(); + + Object oFont; + if (!xref->fetch(oFontRef->getRefNum(), oFontRef->getRefGen(), &oFont)->isDict()) + { + oFont.free(); + return L""; + } + + GfxFont* gfxFont = GfxFont::makeFont(xref, "F", oFontRef->getRef(), oFont.getDict()); + oFont.free(); + if (!gfxFont) + return L""; + + Ref oEmbRef; + std::wstring wsFontBaseName = NSStrings::GetStringFromUTF32(gfxFont->getName()); + std::wstring wsFileName; + + if (gfxFont->getEmbeddedFontID(&oEmbRef) || IsBaseFont(wsFontBaseName)) + { + std::wstring wsFontName; + RendererOutputDev::GetFont(xref, pFontManager, pFontList, gfxFont, wsFileName, wsFontName); + + sFontName = U_TO_UTF8(wsFontName); + RendererOutputDev::CheckFontStylePDF(wsFontName, bBold, bItalic); + if (!bBold) + bBold = gfxFont->isBold(); + if (!bItalic) + bItalic = gfxFont->isItalic(); + } + else + { + std::wstring wsFBN = wsFontBaseName; + NSFonts::CFontInfo* pFontInfo = RendererOutputDev::GetFontByParams(xref, pFontManager, gfxFont, wsFBN); + if (pFontInfo && !pFontInfo->m_wsFontPath.empty()) + { + if (wsFontBaseName.length() > 7 && wsFontBaseName.at(6) == '+') + { + bool bIsRemove = true; + for (int nIndex = 0; nIndex < 6; nIndex++) + { + wchar_t nChar = wsFontBaseName.at(nIndex); + if (nChar < 'A' || nChar > 'Z') + { + bIsRemove = false; + break; + } + } + if (bIsRemove) + wsFontBaseName.erase(0, 7); + } + + wsFileName = pFontInfo->m_wsFontPath; + sFontName = U_TO_UTF8(wsFontBaseName); + sActualFontName = U_TO_UTF8(pFontInfo->m_wsFontName); + bBold = pFontInfo->m_bBold; + bItalic = pFontInfo->m_bItalic; + } + } + + RELEASEOBJECT(gfxFont); + return wsFileName; +} +bool CAnnotFonts::GetFontFromAP(PDFDoc* pdfDoc, AcroFormField* pField, Object* oFontRef, std::string& sFontKey) +{ + bool bFindResources = false; + + Object oAP, oN; + XRef* xref = pdfDoc->getXRef(); + if (pField->fieldLookup("AP", &oAP)->isDict() && oAP.dictLookup("N", &oN)->isStream()) + { + Parser* parser = new Parser(xref, new Lexer(xref, &oN), gFalse); + + bool bFindFont = false; + Object oObj1, oObj2, oObj3; + parser->getObj(&oObj1); + while (!oObj1.isEOF()) + { + if (oObj1.isName()) + { + parser->getObj(&oObj2); + if (oObj2.isEOF()) + break; + if (oObj2.isNum()) + { + parser->getObj(&oObj3); + if (oObj3.isEOF()) + break; + if (oObj3.isCmd("Tf")) + { + bFindFont = true; + break; + } + } + } + if (oObj2.isName()) + { + oObj1.free(); + oObj2.copy(&oObj1); + oObj2.free(); oObj3.free(); + continue; + } + if (oObj3.isName()) + { + oObj1.free(); + oObj3.copy(&oObj1); + oObj3.free(); oObj2.free(); + continue; + } + oObj1.free(); oObj2.free(); oObj3.free(); + + parser->getObj(&oObj1); + } + + if (bFindFont && oObj1.isName()) + { + Object oR, oFonts; + bFindResources = oN.streamGetDict()->lookup("Resources", &oR)->isDict() && oR.dictLookup("Font", &oFonts)->isDict() && oFonts.dictLookupNF(oObj1.getName(), oFontRef)->isRef(); + sFontKey = oObj1.getName(); + oR.free(); oFonts.free(); + } + + oObj1.free(); oObj2.free(); oObj3.free(); + RELEASEOBJECT(parser); + } + oAP.free(); oN.free(); + + return bFindResources; +} +bool CAnnotFonts::FindFonts(Object* oStream, int nDepth, Object* oResFonts) +{ + if (nDepth > 5) + return false; + + Object oResources; + if (!oStream->streamGetDict()->lookup("Resources", &oResources)->isDict()) + { + oResources.free(); + return false; + } + + if (oResources.dictLookup("Font", oResFonts)->isDict()) + { + oResources.free(); + return true; + } + + Object oXObject; + if (oResources.dictLookup("XObject", &oXObject)->isDict()) + { + for (int i = 0, nLength = oXObject.dictGetLength(); i < nLength; ++i) + { + Object oXObj; + if (!oXObject.dictGetVal(i, &oXObj)->isStream()) + { + oXObj.free(); + continue; + } + if (FindFonts(&oXObj, nDepth + 1, oResFonts)) + { + oXObj.free(); oXObject.free(); oResources.free(); + return true; + } + oXObj.free(); + } + } + oXObject.free(); oResources.free(); + return false; +} +std::map CAnnotFonts::GetAnnotFont(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CPdfFontList *pFontList, Object* oAnnotRef) +{ + Object oAnnot, oObj; + XRef* pXref = pdfDoc->getXRef(); + oAnnotRef->fetch(pXref, &oAnnot); + std::map mFontFreeText; + + Object oAP, oN; + if (!oAnnot.dictLookup("AP", &oAP)->isDict() || !oAP.dictLookup("N", &oN)->isStream()) + { + oAP.free(); oN.free(); oAnnot.free(); + return mFontFreeText; + } + oAP.free(); + + Object oFonts; + if (!FindFonts(&oN, 0, &oFonts)) + { + oN.free(); oFonts.free(); oAnnot.free(); + return mFontFreeText; + } + oN.free(); + + CFontList* pAppFontList = (CFontList*)pFontManager->GetApplication()->GetList(); + NSFonts::IFontsMemoryStorage* pMemoryStorage = NSFonts::NSApplicationFontStream::GetGlobalMemoryStorage(); + + for (int i = 0, nFonts = oFonts.dictGetLength(); i < nFonts; ++i) + { + Object oFontRef; + if (!oFonts.dictGetValNF(i, &oFontRef)->isRef()) + { + oFontRef.free(); + continue; + } + + std::string sFontName, sActualFontName; + bool bBold = false, bItalic = false; + std::wstring sFontPath = GetFontData(pdfDoc, pFontManager, pFontList, &oFontRef, sFontName, sActualFontName, bBold, bItalic); + oFontRef.free(); + if (sFontPath.empty() || IsBaseFont(sFontPath) || !sActualFontName.empty()) + continue; + + std::wstring wsFontName = UTF8_TO_U(sFontName); + NSFonts::IFontStream* pFontStream = pMemoryStorage ? (NSFonts::IFontStream*)pMemoryStorage->Get(sFontPath) : NULL; + if (pFontStream) + { + bool bNew = true; + std::vector* arrFontList = pAppFontList->GetFonts(); + for (int nIndex = 0; nIndex < arrFontList->size(); ++nIndex) + { + if (((*arrFontList)[nIndex]->m_wsFontPath == sFontPath || + (*arrFontList)[nIndex]->m_wsFontName == wsFontName) && + (*arrFontList)[nIndex]->m_bBold == (bBold ? 1 : 0) && + (*arrFontList)[nIndex]->m_bItalic == (bItalic ? 1 : 0)) + { + bNew = false; + break; + } + } + if (bNew) + pAppFontList->Add(sFontPath, pFontStream); + } + mFontFreeText[wsFontName] = sFontPath; + } + + oFonts.free(); oAnnot.free(); + return mFontFreeText; +} +std::map CAnnotFonts::GetFreeTextFont(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CPdfFontList* pFontList, Object* oAnnotRef, std::vector& arrRC) +{ + std::map mRes; + + std::map mFontFreeText = GetAnnotFont(pdfDoc, pFontManager, pFontList, oAnnotRef); + CFontList* pAppFontList = (CFontList*)pFontManager->GetApplication()->GetList(); + for (int i = 0; i < arrRC.size(); ++i) + { + if (arrRC[i]->bFind) + continue; + + std::string sFontName = arrRC[i]->sFontFamily; + std::wstring wsFontName = UTF8_TO_U(sFontName); + bool bBold = (bool)((arrRC[i]->unFontFlags >> 0) & 1); + bool bItalic = (bool)((arrRC[i]->unFontFlags >> 1) & 1); + if (IsBaseFont(wsFontName)) + { + if (sFontName == "Times-Roman") + { + if (bBold && bItalic) + sFontName = "Times-BoldItalic"; + else if (bBold) + sFontName = "Times-Bold"; + else if (bItalic) + sFontName = "Times-Italic"; + } + else if (sFontName == "Courier" || sFontName == "Helvetica") + { + if (bBold && bItalic) + sFontName += "-BoldOblique"; + else if (bBold) + sFontName += "-Bold"; + else if (bItalic) + sFontName += "-Oblique"; + } + wsFontName = UTF8_TO_U(sFontName); + + const unsigned char* pData14 = NULL; + unsigned int nSize14 = 0; + NSFonts::IFontsMemoryStorage* pMemoryStorage = NSFonts::NSApplicationFontStream::GetGlobalMemoryStorage(); + if (pMemoryStorage && !pMemoryStorage->Get(wsFontName) && GetBaseFont(wsFontName, pData14, nSize14)) + pMemoryStorage->Add(wsFontName, (BYTE*)pData14, nSize14, false); + + std::string sFontNameBefore = arrRC[i]->sFontFamily; + arrRC[i]->sFontFamily = sFontName; + arrRC[i]->bFind = true; + mRes[wsFontName] = wsFontName; + + for (int j = i; j < arrRC.size(); ++j) + { + if (arrRC[j]->sFontFamily == sFontNameBefore && bBold == (bool)((arrRC[j]->unFontFlags >> 0) & 1) && bItalic == (bool)((arrRC[j]->unFontFlags >> 1) & 1)) + { + arrRC[j]->sFontFamily = sFontName; + arrRC[j]->bFind = true; + } + } + } + else + { + NSFonts::CFontSelectFormat oFontSelect; + if (bBold) + oFontSelect.bBold = new INT(1); + if (bItalic) + oFontSelect.bItalic = new INT(1); + oFontSelect.wsName = new std::wstring(wsFontName); + + NSFonts::CFontInfo* pFontInfo = pAppFontList->GetByParams(oFontSelect); + if (pFontInfo && !pFontInfo->m_wsFontPath.empty()) + { + std::wstring sFontPath = pFontInfo->m_wsFontPath; + bool bFindFreeText = false; + for (std::map::iterator it = mFontFreeText.begin(); it != mFontFreeText.end(); ++it) + { + if (it->second == sFontPath) + { + bFindFreeText = true; + break; + } + } + std::wstring wsFontBaseName = pFontInfo->m_wsFontName; + if (wsFontBaseName.length() > 7 && wsFontBaseName.at(6) == '+') + { + bool bIsRemove = true; + for (int nIndex = 0; nIndex < 6; nIndex++) + { + wchar_t nChar = wsFontBaseName.at(nIndex); + if (nChar < 'A' || nChar > 'Z') + { + bIsRemove = false; + break; + } + } + if (bIsRemove) + wsFontBaseName.erase(0, 7); + } + + if (bFindFreeText) + { + arrRC[i]->sFontFamily = U_TO_UTF8(wsFontBaseName); + mRes[wsFontBaseName] = pFontInfo->m_wsFontPath; + } + else + { + arrRC[i]->unFontFlags |= (1 << 6); + arrRC[i]->sActualFont = U_TO_UTF8(wsFontBaseName); + } + arrRC[i]->bFind = true; + + std::string sFontNameNew = bFindFreeText ? arrRC[i]->sFontFamily : arrRC[i]->sActualFont; + for (int j = i; j < arrRC.size(); ++j) + { + if (arrRC[j]->sFontFamily == sFontName && bBold == (bool)((arrRC[j]->unFontFlags >> 0) & 1) && bItalic == (bool)((arrRC[j]->unFontFlags >> 1) & 1)) + { + if (bFindFreeText) + arrRC[j]->sFontFamily = sFontNameNew; + else + { + arrRC[j]->unFontFlags |= (1 << 6); + arrRC[j]->sActualFont = sFontNameNew; + } + arrRC[j]->bFind = true; + } + } + } + } + } + + return mRes; +} //------------------------------------------------------------------------ // Widget @@ -420,34 +1065,38 @@ CAnnotWidgetBtn::CAnnotWidgetBtn(PDFDoc* pdfDoc, AcroFormField* pField) : CAnnot m_unIFFlag = 0; Object oObj; + Object oFieldRef, oField; + pField->getFieldRef(&oFieldRef); + oFieldRef.fetch(pdfDoc->getXRef(), &oField); + oFieldRef.free(); - // Значение поля - V - int nValueLength; - Unicode* pValue = pField->getValue(&nValueLength); - std::string sValue = NSStringExt::CConverter::GetUtf8FromUTF32(pValue, nValueLength); - gfree(pValue); + // 9 - Значение поля - V + if (oField.dictLookup("V", &oObj)) + { + m_sV = getValue(&oObj); + if (!m_sV.empty()) + m_unFlags |= (1 << 9); + } + oObj.free(); + oField.free(); if (pField->fieldLookup("AS", &oObj)->isName()) - sValue = oObj.getName(); + m_sV = oObj.getName(); oObj.free(); - // 10 - Включено - if (sValue != "Off") - m_unFlags |= (1 << 9); - Object oMK; AcroFormFieldType oType = pField->getAcroFormFieldType(); m_nStyle = (oType == acroFormFieldRadioButton ? 3 : 0); if (pField->fieldLookup("MK", &oMK)->isDict()) { - // 11 - Заголовок - СА - // 12 - Заголовок прокрутки - RC - // 13 - Альтернативный заголовок - AC if (oType == acroFormFieldPushbutton) { - DICT_LOOKUP_STRING(oMK.dictLookup, "CA", 10, m_sCA); - DICT_LOOKUP_STRING(oMK.dictLookup, "RC", 11, m_sRC); - DICT_LOOKUP_STRING(oMK.dictLookup, "AC", 12, m_sAC); + // 10 - Заголовок - СА + m_sCA = DictLookupString(&oMK, "CA", 10); + // 11 - Заголовок прокрутки - RC + m_sRC = DictLookupString(&oMK, "RC", 11); + // 12 - Альтернативный заголовок - AC + m_sAC = DictLookupString(&oMK, "AC", 12); } else { @@ -471,7 +1120,7 @@ CAnnotWidgetBtn::CAnnotWidgetBtn(PDFDoc* pdfDoc, AcroFormField* pField) : CAnnot oObj.free(); } - // 14 - Положение заголовка - TP + // 13 - Положение заголовка - TP if (oMK.dictLookup("TP", &oObj)->isInt()) { m_nTP = oObj.getInt(); @@ -483,7 +1132,7 @@ CAnnotWidgetBtn::CAnnotWidgetBtn(PDFDoc* pdfDoc, AcroFormField* pField) : CAnnot if (oMK.dictLookup("IF", &oIF)->isDict()) { m_unIFFlag = 1; - // 2 - Масштабирование - SW + // 1 - Масштабирование - SW if (oIF.dictLookup("SW", &oObj)->isName()) { m_unIFFlag |= (1 << 1); @@ -497,7 +1146,7 @@ CAnnotWidgetBtn::CAnnotWidgetBtn(PDFDoc* pdfDoc, AcroFormField* pField) : CAnnot m_nSW = 1; } oObj.free(); - // 3 - Тип масштабирования - S + // 2 - Тип масштабирования - S if (oIF.dictLookup("S", &oObj)->isName()) { m_unIFFlag |= (1 << 2); @@ -507,17 +1156,17 @@ CAnnotWidgetBtn::CAnnotWidgetBtn(PDFDoc* pdfDoc, AcroFormField* pField) : CAnnot m_nS = 1; } oObj.free(); - // 4 - Смещение - A + // 3 - Смещение - A if (oIF.dictLookup("A", &oObj)->isArray()) { + m_dA1 = 0.5, m_dA2 = 0.5; Object oObj2; m_unIFFlag |= (1 << 3); - m_dA1 = 0.5; m_dA2 = 0.5; - ARR_GET_NUM(oObj, 0, m_dA1); - ARR_GET_NUM(oObj, 1, m_dA2); + m_dA1 = ArrGetNum(&oObj, 0); + m_dA2 = ArrGetNum(&oObj, 1); } oObj.free(); - // 5 - Полное соответствие - FB + // 4 - Полное соответствие - FB if (oIF.dictLookup("FB", &oObj)->isBool() && oObj.getBool()) m_unIFFlag |= (1 << 4); oObj.free(); @@ -526,7 +1175,10 @@ CAnnotWidgetBtn::CAnnotWidgetBtn(PDFDoc* pdfDoc, AcroFormField* pField) : CAnnot } oMK.free(); - // 15 - Имя вкл состояния - AP - N - Yes + Object oOpt; + pField->fieldLookup("Opt", &oOpt); + + // 14 - Имя вкл состояния - AP - N - Yes Object oNorm; if (pField->fieldLookup("AP", &oObj)->isDict() && oObj.dictLookup("N", &oNorm)->isDict()) { @@ -537,13 +1189,42 @@ CAnnotWidgetBtn::CAnnotWidgetBtn(PDFDoc* pdfDoc, AcroFormField* pField) : CAnnot { m_unFlags |= (1 << 14); m_sAP_N_Yes = sNormName; + + int nOptI; + if (oOpt.isArray() && isdigit(sNormName[0]) && (nOptI = std::stoi(sNormName)) >= 0 && nOptI < oOpt.arrayGetLength()) + { + Object oOptJ; + if (!oOpt.arrayGet(nOptI, &oOptJ) || !(oOptJ.isString() || oOptJ.isArray())) + { + oOptJ.free(); + break; + } + + if (oOptJ.isString()) + { + TextString* s = new TextString(oOptJ.getString()); + m_sAP_N_Yes = NSStringExt::CConverter::GetUtf8FromUTF32(s->getUnicode(), s->getLength()); + delete s; + } + else if (oOptJ.isArray() && oOptJ.arrayGetLength() > 0) + { + Object oOptJ2; + if (oOptJ.arrayGet(0, &oOptJ2)->isString()) + { + TextString* s = new TextString(oOptJ2.getString()); + m_sAP_N_Yes = NSStringExt::CConverter::GetUtf8FromUTF32(s->getUnicode(), s->getLength()); + delete s; + } + oOptJ2.free(); + } + oOptJ.free(); + } break; } } } - oNorm.free(); oObj.free(); + oNorm.free(); oObj.free(); oOpt.free(); } - CAnnotWidgetTx::CAnnotWidgetTx(PDFDoc* pdfDoc, AcroFormField* pField) : CAnnotWidget(pdfDoc, pField) { Object oObj; @@ -552,9 +1233,7 @@ CAnnotWidgetTx::CAnnotWidgetTx(PDFDoc* pdfDoc, AcroFormField* pField) : CAnnotWi oFieldRef.fetch(pdfDoc->getXRef(), &oField); oFieldRef.free(); - // 10 - Значение - // 11 - Максимальное количество символов - // 12 - Расширенный текст RV + // 9 - Значение - V if (oField.dictLookup("V", &oObj)) { m_sV = getValue(&oObj); @@ -564,7 +1243,7 @@ CAnnotWidgetTx::CAnnotWidgetTx(PDFDoc* pdfDoc, AcroFormField* pField) : CAnnotWi oObj.free(); oField.free(); - // Максимальное количество символов в Tx - MaxLen + // 10 - Максимальное количество символов в Tx - MaxLen int nMaxLen = pField->getMaxLen(); if (nMaxLen > 0) { @@ -572,13 +1251,10 @@ CAnnotWidgetTx::CAnnotWidgetTx(PDFDoc* pdfDoc, AcroFormField* pField) : CAnnotWi m_unMaxLen = nMaxLen; } - // RichText + // 11 - Расширенный текст RV - RichText if (pField->getFlags() & (1 << 25)) - { - DICT_LOOKUP_STRING(pField->fieldLookup, "RV", 11, m_sRV); - } + m_sRV = FieldLookupString(pField, "RV", 11); } - CAnnotWidgetCh::CAnnotWidgetCh(PDFDoc* pdfDoc, AcroFormField* pField) : CAnnotWidget(pdfDoc, pField) { Object oObj; @@ -587,18 +1263,17 @@ CAnnotWidgetCh::CAnnotWidgetCh(PDFDoc* pdfDoc, AcroFormField* pField) : CAnnotWi oFieldRef.fetch(pdfDoc->getXRef(), &oField); oFieldRef.free(); - // 10 - Значение + // 9 - Значение if (oField.dictLookup("V", &oObj)) { - m_sV = getValue(&oObj); + m_sV = getValue(&oObj, false); if (!m_sV.empty()) m_unFlags |= (1 << 9); } oObj.free(); - oField.free(); Object oOpt; - // 11 - Список значений + // 10 - Список значений if (pField->fieldLookup("Opt", &oOpt)->isArray()) { m_unFlags |= (1 << 10); @@ -643,15 +1318,48 @@ CAnnotWidgetCh::CAnnotWidgetCh(PDFDoc* pdfDoc, AcroFormField* pField) : CAnnotWi } oOpt.free(); - // 12 - Индекс верхнего элемента - TI + // 11 - Индекс верхнего элемента - TI if (pField->fieldLookup("TI", &oObj)->isInt()) { m_unFlags |= (1 << 11); m_unTI = oObj.getInt(); } oObj.free(); -} + // 12 - Выбранные индексы - I + if (oField.dictLookup("I", &oOpt)->isArray()) + { + m_unFlags |= (1 << 12); + int nILength = oOpt.arrayGetLength(); + for (int j = 0; j < nILength; ++j) + { + if (oOpt.arrayGet(j, &oObj)->isInt()) + m_arrI.push_back(oObj.getInt()); + oObj.free(); + } + } + oOpt.free(); + + // 13 - Массив значений + if (oField.dictLookup("V", &oOpt)->isArray()) + { + m_unFlags |= (1 << 13); + int nVLength = oOpt.arrayGetLength(); + for (int j = 0; j < nVLength; ++j) + { + if (oOpt.arrayGet(j, &oObj)->isString()) + { + TextString* s = new TextString(oObj.getString()); + m_arrV.push_back(NSStringExt::CConverter::GetUtf8FromUTF32(s->getUnicode(), s->getLength())); + delete s; + } + oObj.free(); + } + } + oOpt.free(); + + oField.free(); +} CAnnotWidgetSig::CAnnotWidgetSig(PDFDoc* pdfDoc, AcroFormField* pField) : CAnnotWidget(pdfDoc, pField) { Object oObj; @@ -660,14 +1368,13 @@ CAnnotWidgetSig::CAnnotWidgetSig(PDFDoc* pdfDoc, AcroFormField* pField) : CAnnot oFieldRef.fetch(pdfDoc->getXRef(), &oField); oFieldRef.free(); - // 10 - Значение + // 9 - Значение if (oField.dictLookup("V", &oObj)->isDict()) m_unFlags |= (1 << 9); oObj.free(); oField.free(); } - CAnnotWidget::CAnnotWidget(PDFDoc* pdfDoc, AcroFormField* pField) : CAnnot(pdfDoc, pField) { Object oObj, oField; @@ -676,6 +1383,9 @@ CAnnotWidget::CAnnotWidget(PDFDoc* pdfDoc, AcroFormField* pField) : CAnnot(pdfDo oObj.fetch(xref, &oField); oObj.free(); + m_dFontSize = 0.0; + m_unFontStyle = 0; + // Цвет текста - из DA int nSpace; GList *arrColors = pField->getColorSpace(&nSpace); @@ -710,16 +1420,13 @@ CAnnotWidget::CAnnotWidget(PDFDoc* pdfDoc, AcroFormField* pField) : CAnnot(pdfDo // Флаг - Ff m_unFieldFlag = pField->getFlags(); - // Исходное значение флага данных - m_unFlags = 0; - - // 1 - Альтернативное имя поля, используется во всплывающей подсказке и сообщениях об ошибке - TU - DICT_LOOKUP_STRING(pField->fieldLookup, "TU", 0, m_sTU); + // 0 - Альтернативное имя поля, используется во всплывающей подсказке и сообщениях об ошибке - TU + m_sTU = FieldLookupString(pField, "TU", 0); - // 2 - Строка стиля по умолчанию - DS - DICT_LOOKUP_STRING(pField->fieldLookup, "DS", 1, m_sDS); + // 1 - Строка стиля по умолчанию - DS + m_sDS = FieldLookupString(pField, "DS", 1); - // 4 - Режим выделения - H + // 3 - Режим выделения - H if (pField->fieldLookup("H", &oObj)->isName()) { m_unFlags |= (1 << 3); @@ -737,7 +1444,7 @@ CAnnotWidget::CAnnotWidget(PDFDoc* pdfDoc, AcroFormField* pField) : CAnnot(pdfDo Object oMK; if (pField->fieldLookup("MK", &oMK)->isDict()) { - // 6 - Цвет границ - BC. Даже если граница не задана BS/Border, то при наличии BC предоставляется граница по-умолчанию (сплошная, толщиной 1) + // 5 - Цвет границ - BC. Даже если граница не задана BS/Border, то при наличии BC предоставляется граница по-умолчанию (сплошная, толщиной 1) if (oMK.dictLookup("BC", &oObj)->isArray()) { m_unFlags |= (1 << 5); @@ -751,7 +1458,7 @@ CAnnotWidget::CAnnotWidget(PDFDoc* pdfDoc, AcroFormField* pField) : CAnnot(pdfDo } oObj.free(); - // 7 - Поворот аннотации относительно страницы - R + // 6 - Поворот аннотации относительно страницы - R if (oMK.dictLookup("R", &oObj)->isInt()) { m_unFlags |= (1 << 6); @@ -759,7 +1466,7 @@ CAnnotWidget::CAnnotWidget(PDFDoc* pdfDoc, AcroFormField* pField) : CAnnot(pdfDo } oObj.free(); - // 8 - Цвет фона - BG + // 7 - Цвет фона - BG if (oMK.dictLookup("BG", &oObj)->isArray()) { m_unFlags |= (1 << 7); @@ -775,7 +1482,7 @@ CAnnotWidget::CAnnotWidget(PDFDoc* pdfDoc, AcroFormField* pField) : CAnnot(pdfDo } oMK.free(); - // 9 - Значение по-умолчанию + // 8 - Значение по-умолчанию if (oField.dictLookup("DV", &oObj)) { m_sDV = getValue(&oObj); @@ -784,7 +1491,7 @@ CAnnotWidget::CAnnotWidget(PDFDoc* pdfDoc, AcroFormField* pField) : CAnnot(pdfDo } oObj.free(); - // 18 - Родитель - Parent + // 17 - Родитель - Parent if (oField.dictLookupNF("Parent", &oObj)->isRef()) { m_unRefNumParent = oObj.getRefNum(); @@ -792,8 +1499,8 @@ CAnnotWidget::CAnnotWidget(PDFDoc* pdfDoc, AcroFormField* pField) : CAnnot(pdfDo } oObj.free(); - // 19 - Частичное имя поля - T - DICT_LOOKUP_STRING(oField.dictLookup, "T", 18, m_sT); + // 18 - Частичное имя поля - T + m_sT = DictLookupString(&oField, "T", 18); // Action - A Object oAction; @@ -811,13 +1518,20 @@ CAnnotWidget::CAnnotWidget(PDFDoc* pdfDoc, AcroFormField* pField) : CAnnot(pdfDo // Actions - AA Object oAA; - if (pField->fieldLookup("AA", &oAA)->isDict()) + Object parent, parent2; + bool bParent = oField.dictLookup("Parent", &parent)->isDict(); + bool bAA = bParent && parent.dictLookup("AA", &oAA)->isDict(); + oAA.free(); + + if (oField.dictLookup("AA", &oAA)->isDict()) { for (int j = 0; j < oAA.dictGetLength(); ++j) { if (oAA.dictGetVal(j, &oAction)->isDict()) { std::string sAA(oAA.dictGetKey(j)); + if (bAA && (sAA == "K" || sAA == "F" || sAA == "V" || sAA == "C")) + continue; CAction* pA = getAction(pdfDoc, &oAction); if (pA) { @@ -829,14 +1543,114 @@ CAnnotWidget::CAnnotWidget(PDFDoc* pdfDoc, AcroFormField* pField) : CAnnot(pdfDo } } oAA.free(); + + if (bParent) + { + int depth = 0; + while (parent.isDict() && depth < 50) + { + if (parent.dictLookup("AA", &oAA)->isDict()) + { + for (int j = 0; j < oAA.dictGetLength(); ++j) + { + if (oAA.dictGetVal(j, &oAction)->isDict()) + { + std::string sAA(oAA.dictGetKey(j)); + if (sAA == "E" || sAA == "X" || sAA == "D" || sAA == "U" || sAA == "Fo" || sAA == "Bl" || sAA == "PO" || sAA == "PC" || sAA == "PV" || sAA == "PI") + continue; + CAction* pA = getAction(pdfDoc, &oAction); + if (pA) + { + pA->sType = sAA; + m_arrAction.push_back(pA); + } + } + oAction.free(); + } + } + oAA.free(); + parent.dictLookup("Parent", &parent2); + parent.free(); + parent = parent2; + ++depth; + } + } + parent.free(); + oField.free(); } - CAnnotWidget::~CAnnotWidget() { for (int i = 0; i < m_arrAction.size(); ++i) RELEASEOBJECT(m_arrAction[i]); } +std::string CAnnotWidget::FieldLookupString(AcroFormField* pField, const char* sName, int nByte) +{ + std::string sRes; + Object oObj; + if (pField->fieldLookup(sName, &oObj)->isString()) + { + m_unFlags |= (1 << nByte); + TextString* s = new TextString(oObj.getString()); + sRes = NSStringExt::CConverter::GetUtf8FromUTF32(s->getUnicode(), s->getLength()); + delete s; + } + oObj.free(); + return sRes; +} +void CAnnotWidget::SetFont(PDFDoc* pdfDoc, AcroFormField* pField, NSFonts::IFontManager* pFontManager, CPdfFontList *pFontList) +{ + // Шрифт и размер шрифта - из DA + Ref fontID; + pField->getFont(&fontID, &m_dFontSize); + m_unFontStyle = 0; + + Object oFontRef; + if (fontID.num < 0) + { + if (!CAnnotFonts::GetFontFromAP(pdfDoc, pField, &oFontRef, m_sFontKey)) + { + oFontRef.free(); + return; + } + } + else + oFontRef.initRef(fontID.num, fontID.gen); + + bool bBold = false, bItalic = false; + CAnnotFonts::GetFontData(pdfDoc, pFontManager, pFontList, &oFontRef, m_sFontName, m_sActualFontName, bBold, bItalic); + oFontRef.free(); + + // 2 - Актуальный шрифт + if (!m_sActualFontName.empty()) + m_unFlags |= (1 << 2); + + // 4 - Уникальный идентификатор шрифта + if (!m_sFontKey.empty()) + m_unFlags |= (1 << 4); + + if (bBold) + m_unFontStyle |= (1 << 0); + if (bItalic) + m_unFontStyle |= (1 << 1); +} +void CAnnotWidget::SetButtonFont(PDFDoc* pdfDoc, AcroFormField* pField, NSFonts::IFontManager* pFontManager, CPdfFontList *pFontList) +{ + // Неполный шрифт во внешнем виде pushbutton + Object oFontRef; + if (!CAnnotFonts::GetFontFromAP(pdfDoc, pField, &oFontRef, m_sFontKey)) + { + oFontRef.free(); + return; + } + + bool bBold = false, bItalic = false; + CAnnotFonts::GetFontData(pdfDoc, pFontManager, pFontList, &oFontRef, m_sButtonFontName, m_sButtonFontName, bBold, bItalic); + if (!m_sButtonFontName.empty()) + m_unFlags |= (1 << 19); + + oFontRef.free(); +} //------------------------------------------------------------------------ // Popup @@ -850,12 +1664,12 @@ CAnnotPopup::CAnnotPopup(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CA XRef* pXref = pdfDoc->getXRef(); oAnnotRef->fetch(pXref, &oAnnot); - // 1 - Отображаться открытой - Open + // 0 - Отображаться открытой - Open if (oAnnot.dictLookup("Open", &oObj)->isBool() && oObj.getBool()) m_unFlags |= (1 << 0); oObj.free(); - // 2 - Родитель - Parent + // 1 - Родитель - Parent if (oAnnot.dictLookupNF("Parent", &oObj)->isRef()) { m_unFlags |= (1 << 1); @@ -869,31 +1683,31 @@ CAnnotPopup::CAnnotPopup(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CA // Text //------------------------------------------------------------------------ -CAnnotText::CAnnotText(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CMarkupAnnot(pdfDoc, oAnnotRef, nPageIndex) +CAnnotText::CAnnotText(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CAnnotMarkup(pdfDoc, oAnnotRef, nPageIndex) { Object oAnnot, oObj; XRef* pXref = pdfDoc->getXRef(); oAnnotRef->fetch(pXref, &oAnnot); - // 16 - Отображаться открытой - Open + // 15 - Отображаться открытой - Open if (oAnnot.dictLookup("Open", &oObj)->isBool() && oObj.getBool()) m_unFlags |= (1 << 15); oObj.free(); - // 17 - Иконка - Name + // 16 - Иконка - Name + m_unFlags |= (1 << 16); + m_nName = 10; // Default: Note if (oAnnot.dictLookup("Name", &oObj)->isName()) { - m_unFlags |= (1 << 16); std::string sName(oObj.getName()); std::vector arrName = {"Check", "Checkmark", "Circle", "Comment", "Cross", "CrossHairs", "Help", "Insert", "Key", "NewParagraph", "Note", "Paragraph", "RightArrow", "RightPointer", "Star", "UpArrow", "UpLeftArrow"}; - m_nName = 10; // Default: Note std::vector::iterator p = std::find(arrName.begin(), arrName.end(), sName); if (p != arrName.end()) m_nName = p - arrName.begin(); } oObj.free(); - // 18 - Модель состояния - StateModel + // 17 - Модель состояния - StateModel if (oAnnot.dictLookup("StateModel", &oObj)->isString()) { m_unFlags |= (1 << 17); @@ -906,7 +1720,7 @@ CAnnotText::CAnnotText(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CMar } oObj.free(); - // 19 - Состояние - State + // 18 - Состояние - State if (oAnnot.dictLookup("State", &oObj)->isString()) { m_unFlags |= (1 << 18); @@ -935,7 +1749,7 @@ CAnnotText::CAnnotText(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CMar // Ink //------------------------------------------------------------------------ -CAnnotInk::CAnnotInk(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CMarkupAnnot(pdfDoc, oAnnotRef, nPageIndex) +CAnnotInk::CAnnotInk(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CAnnotMarkup(pdfDoc, oAnnotRef, nPageIndex) { Object oAnnot, oObj, oObj2; XRef* pXref = pdfDoc->getXRef(); @@ -953,7 +1767,7 @@ CAnnotInk::CAnnotInk(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CMarku { Object oObj1; if (oObj2.arrayGet(k, &oObj1)->isNum()) - arrLine.push_back(k % 2 == 0 ? oObj1.getNum() : m_dHeight - oObj1.getNum()); + arrLine.push_back(k % 2 == 0 ? oObj1.getNum() - m_dX : m_dHeight - oObj1.getNum()); else arrLine.push_back(0.0); oObj1.free(); @@ -971,7 +1785,7 @@ CAnnotInk::CAnnotInk(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CMarku // Line //------------------------------------------------------------------------ -CAnnotLine::CAnnotLine(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CMarkupAnnot(pdfDoc, oAnnotRef, nPageIndex) +CAnnotLine::CAnnotLine(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CAnnotMarkup(pdfDoc, oAnnotRef, nPageIndex) { Object oAnnot, oObj, oObj2; XRef* pXref = pdfDoc->getXRef(); @@ -980,16 +1794,14 @@ CAnnotLine::CAnnotLine(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CMar // Координаты линии - L if (oAnnot.dictLookup("L", &oObj)->isArray()) { - ARR_GET_NUM(oObj, 0, m_pL[0]); - ARR_GET_NUM(oObj, 1, m_pL[1]); - ARR_GET_NUM(oObj, 2, m_pL[2]); - ARR_GET_NUM(oObj, 3, m_pL[3]); - m_pL[1] = m_dHeight - m_pL[1]; - m_pL[3] = m_dHeight - m_pL[3]; + m_pL[0] = ArrGetNum(&oObj, 0) - m_dX; + m_pL[1] = m_dHeight - ArrGetNum(&oObj, 1); + m_pL[2] = ArrGetNum(&oObj, 2) - m_dX; + m_pL[3] = m_dHeight - ArrGetNum(&oObj, 3); } oObj.free(); - // 16 - Стили окончания линии - LE + // 15 - Стили окончания линии - LE if (oAnnot.dictLookup("LE", &oObj)->isArray()) { m_unFlags |= (1 << 15); @@ -1003,7 +1815,7 @@ CAnnotLine::CAnnotLine(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CMar } oObj.free(); - // 17 - Цвет окончаний линии - IC + // 16 - Цвет окончаний линии - IC if (oAnnot.dictLookup("IC", &oObj)->isArray()) { m_unFlags |= (1 << 16); @@ -1015,7 +1827,7 @@ CAnnotLine::CAnnotLine(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CMar } oObj.free(); - // 18 - Длина линий выноски - LL + // 17 - Длина линий выноски - LL if (oAnnot.dictLookup("LL", &oObj)->isNum()) { m_unFlags |= (1 << 17); @@ -1023,7 +1835,7 @@ CAnnotLine::CAnnotLine(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CMar } oObj.free(); - // 19 - Продолжение линий выноски - LLE + // 18 - Продолжение линий выноски - LLE if (oAnnot.dictLookup("LLE", &oObj)->isNum()) { m_unFlags |= (1 << 18); @@ -1031,12 +1843,12 @@ CAnnotLine::CAnnotLine(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CMar } oObj.free(); - // 20 - Местоположение заголовка - Cap + // 19 - Местоположение заголовка - Cap if (oAnnot.dictLookup("Cap", &oObj)->isBool()) m_unFlags |= (1 << 19); oObj.free(); - // 21 - Назначение аннотации - IT + // 20 - Назначение аннотации - IT if (oAnnot.dictLookup("IT", &oObj)->isName()) { m_unFlags |= (1 << 20); @@ -1046,7 +1858,7 @@ CAnnotLine::CAnnotLine(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CMar } oObj.free(); - // 22 - Длина смещения выноски - LLO + // 21 - Длина смещения выноски - LLO if (oAnnot.dictLookup("LLO", &oObj)->isNum()) { m_unFlags |= (1 << 21); @@ -1054,7 +1866,7 @@ CAnnotLine::CAnnotLine(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CMar } oObj.free(); - // 23 - Расположение заголовка аннотации - CP + // 22 - Расположение заголовка аннотации - CP if (oAnnot.dictLookup("CP", &oObj)->isName()) { m_unFlags |= (1 << 22); @@ -1064,13 +1876,13 @@ CAnnotLine::CAnnotLine(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CMar } oObj.free(); - // 24 - Смещение текста подписи - CO + // 23 - Смещение текста подписи - CO m_pCO[0] = 0.0; m_pCO[1] = 0.0; if (oAnnot.dictLookup("CO", &oObj)->isArray()) { m_unFlags |= (1 << 23); - ARR_GET_NUM(oObj, 0, m_pCO[0]); - ARR_GET_NUM(oObj, 1, m_pCO[1]); + m_pCO[0] = ArrGetNum(&oObj, 0); + m_pCO[1] = ArrGetNum(&oObj, 1); } oObj.free(); @@ -1081,7 +1893,7 @@ CAnnotLine::CAnnotLine(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CMar // TextMarkup: Highlight, Underline, Squiggly, StrikeOut //------------------------------------------------------------------------ -CAnnotTextMarkup::CAnnotTextMarkup(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CMarkupAnnot(pdfDoc, oAnnotRef, nPageIndex) +CAnnotTextMarkup::CAnnotTextMarkup(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CAnnotMarkup(pdfDoc, oAnnotRef, nPageIndex) { Object oAnnot, oObj, oObj2; XRef* pXref = pdfDoc->getXRef(); @@ -1093,7 +1905,7 @@ CAnnotTextMarkup::CAnnotTextMarkup(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageI for (int i = 0; i < oObj.arrayGetLength(); ++i) { if (oObj.arrayGet(i, &oObj2)->isNum()) - m_arrQuadPoints.push_back(i % 2 == 1 ? m_dHeight - oObj2.getNum() : oObj2.getNum()); + m_arrQuadPoints.push_back(i % 2 == 0 ? oObj2.getNum() - m_dX : m_dHeight - oObj2.getNum()); oObj2.free(); } } @@ -1121,7 +1933,7 @@ CAnnotTextMarkup::CAnnotTextMarkup(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageI // Square, Circle //------------------------------------------------------------------------ -CAnnotSquareCircle::CAnnotSquareCircle(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CMarkupAnnot(pdfDoc, oAnnotRef, nPageIndex) +CAnnotSquareCircle::CAnnotSquareCircle(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CAnnotMarkup(pdfDoc, oAnnotRef, nPageIndex) { Object oAnnot, oObj, oObj2; XRef* pXref = pdfDoc->getXRef(); @@ -1138,18 +1950,18 @@ CAnnotSquareCircle::CAnnotSquareCircle(PDFDoc* pdfDoc, Object* oAnnotRef, int nP else if (sType == "Circle") m_nSubtype = 5; - // 16 - Различия Rect и фактического размера - RD + // 15 - Различия Rect и фактического размера - RD if (oAnnot.dictLookup("RD", &oObj)->isArray()) { m_unFlags |= (1 << 15); - ARR_GET_NUM(oObj, 0, m_pRD[0]); - ARR_GET_NUM(oObj, 1, m_pRD[1]); - ARR_GET_NUM(oObj, 2, m_pRD[2]); - ARR_GET_NUM(oObj, 3, m_pRD[3]); + m_pRD[0] = ArrGetNum(&oObj, 0); + m_pRD[3] = ArrGetNum(&oObj, 1); + m_pRD[2] = ArrGetNum(&oObj, 2); + m_pRD[1] = ArrGetNum(&oObj, 3); } oObj.free(); - // 17 - Цвет заполнения - IC + // 16 - Цвет заполнения - IC if (oAnnot.dictLookup("IC", &oObj)->isArray()) { m_unFlags |= (1 << 16); @@ -1168,7 +1980,7 @@ CAnnotSquareCircle::CAnnotSquareCircle(PDFDoc* pdfDoc, Object* oAnnotRef, int nP // Polygon, PolyLine //------------------------------------------------------------------------ -CAnnotPolygonLine::CAnnotPolygonLine(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CMarkupAnnot(pdfDoc, oAnnotRef, nPageIndex) +CAnnotPolygonLine::CAnnotPolygonLine(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CAnnotMarkup(pdfDoc, oAnnotRef, nPageIndex) { Object oAnnot, oObj, oObj2; XRef* pXref = pdfDoc->getXRef(); @@ -1191,7 +2003,7 @@ CAnnotPolygonLine::CAnnotPolygonLine(PDFDoc* pdfDoc, Object* oAnnotRef, int nPag for (int j = 0; j < oObj.arrayGetLength(); ++j) { if (oObj.arrayGet(j, &oObj2)->isNum()) - m_arrVertices.push_back(j % 2 == 0 ? oObj2.getNum() : m_dHeight - oObj2.getNum()); + m_arrVertices.push_back(j % 2 == 0 ? oObj2.getNum() - m_dX : m_dHeight - oObj2.getNum()); else m_arrVertices.push_back(0.0); oObj2.free(); @@ -1199,7 +2011,7 @@ CAnnotPolygonLine::CAnnotPolygonLine(PDFDoc* pdfDoc, Object* oAnnotRef, int nPag } oObj.free(); - // 16 - Стили окончания линии - LE + // 15 - Стили окончания линии - LE if (oAnnot.dictLookup("LE", &oObj)->isArray()) { m_unFlags |= (1 << 15); @@ -1213,7 +2025,7 @@ CAnnotPolygonLine::CAnnotPolygonLine(PDFDoc* pdfDoc, Object* oAnnotRef, int nPag } oObj.free(); - // 17 - Цвет заполнения - IC + // 16 - Цвет заполнения - IC if (oAnnot.dictLookup("IC", &oObj)->isArray()) { m_unFlags |= (1 << 16); @@ -1225,7 +2037,7 @@ CAnnotPolygonLine::CAnnotPolygonLine(PDFDoc* pdfDoc, Object* oAnnotRef, int nPag } oObj.free(); - // 21 - Назначение аннотации - IT + // 20 - Назначение аннотации - IT if (oAnnot.dictLookup("IT", &oObj)->isName()) { m_unFlags |= (1 << 20); @@ -1244,7 +2056,7 @@ CAnnotPolygonLine::CAnnotPolygonLine(PDFDoc* pdfDoc, Object* oAnnotRef, int nPag // FreeText //------------------------------------------------------------------------ -CAnnotFreeText::CAnnotFreeText(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CMarkupAnnot(pdfDoc, oAnnotRef, nPageIndex) +CAnnotFreeText::CAnnotFreeText(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CAnnotMarkup(pdfDoc, oAnnotRef, nPageIndex) { Object oAnnot, oObj, oObj2; XRef* pXref = pdfDoc->getXRef(); @@ -1256,25 +2068,30 @@ CAnnotFreeText::CAnnotFreeText(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex m_nQ = oObj.getInt(); oObj.free(); - // 16 - Различия Rect и фактического размера - RD + m_nRotate = 0; + if (oAnnot.dictLookup("Rotate", &oObj)->isInt()) + m_nRotate = oObj.getInt(); + oObj.free(); + + // 15 - Различия Rect и фактического размера - RD if (oAnnot.dictLookup("RD", &oObj)->isArray()) { m_unFlags |= (1 << 15); - ARR_GET_NUM(oObj, 0, m_pRD[0]); - ARR_GET_NUM(oObj, 1, m_pRD[1]); - ARR_GET_NUM(oObj, 2, m_pRD[2]); - ARR_GET_NUM(oObj, 3, m_pRD[3]); + m_pRD[0] = ArrGetNum(&oObj, 0); + m_pRD[3] = ArrGetNum(&oObj, 1); + m_pRD[2] = ArrGetNum(&oObj, 2); + m_pRD[1] = ArrGetNum(&oObj, 3); } oObj.free(); - // 17 - Координаты выноски - CL + // 16 - Координаты выноски - CL if (oAnnot.dictLookup("CL", &oObj)->isArray()) { m_unFlags |= (1 << 16); for (int j = 0; j < oObj.arrayGetLength(); ++j) { if (oObj.arrayGet(j, &oObj2)->isNum()) - m_arrCL.push_back(j % 2 == 0 ? oObj2.getNum() : m_dHeight - oObj2.getNum()); + m_arrCL.push_back(j % 2 == 0 ? oObj2.getNum() - m_dX : m_dHeight - oObj2.getNum()); else m_arrCL.push_back(0.0); oObj2.free(); @@ -1282,10 +2099,10 @@ CAnnotFreeText::CAnnotFreeText(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex } oObj.free(); - // 18 - Строка стиля по умолчанию - DS - DICT_LOOKUP_STRING(oAnnot.dictLookup, "DS", 17, m_sDS); + // 17 - Строка стиля по умолчанию - DS + m_sDS = DictLookupString(&oAnnot, "DS", 17); - // 19 - Стили окончания линии - LE + // 18 - Стили окончания линии - LE if (oAnnot.dictLookup("LE", &oObj)->isName()) { m_unFlags |= (1 << 18); @@ -1293,7 +2110,7 @@ CAnnotFreeText::CAnnotFreeText(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex } oObj.free(); - // 21 - Назначение аннотации - IT + // 20 - Назначение аннотации - IT if (oAnnot.dictLookup("IT", &oObj)->isName()) { m_unFlags |= (1 << 20); @@ -1305,6 +2122,74 @@ CAnnotFreeText::CAnnotFreeText(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex } oObj.free(); + // 21 - Цвет границы - color from DA + if (oAnnot.dictLookup("DA", &oObj)->isString()) + { + m_unFlags |= (1 << 21); + int nSpace; + GList *arrColors = new GList(); + + // parse the default appearance string + GList* daToks = tokenize(oObj.getString()); + for (int i = daToks->getLength() - 1; i > 0; --i) { + + // handle the g operator + if (!((GString *)daToks->get(i))->cmp("g")) { + arrColors->append(new double(atof(((GString *)daToks->get(i - 1))->getCString()))); + break; + + // handle the rg operator + } else if (i >= 3 && !((GString *)daToks->get(i))->cmp("rg")) { + arrColors->append(new double(atof(((GString *)daToks->get(i - 3))->getCString()))); + arrColors->append(new double(atof(((GString *)daToks->get(i - 2))->getCString()))); + arrColors->append(new double(atof(((GString *)daToks->get(i - 1))->getCString()))); + break; + } else if (i >= 4 && !((GString *)daToks->get(i))->cmp("k")) { + arrColors->append(new double(atof(((GString *)daToks->get(i - 4))->getCString()))); + arrColors->append(new double(atof(((GString *)daToks->get(i - 3))->getCString()))); + arrColors->append(new double(atof(((GString *)daToks->get(i - 2))->getCString()))); + arrColors->append(new double(atof(((GString *)daToks->get(i - 1))->getCString()))); + break; + } + } + deleteGList(daToks, GString); + + nSpace = arrColors->getLength(); + + for (int j = 0; j < nSpace; ++j) + m_arrCFromDA.push_back(*(double*)arrColors->get(j)); + deleteGList(arrColors, double); + } + oObj.free(); + + if (oAnnot.dictLookup("AP", &oObj)->isNull() && oAnnot.dictLookup("RC", &oObj2)->isNull() && oAnnot.dictLookup("Contents", &oObj)->isString() && oObj.getString()->getLength()) + { + NSStringUtils::CStringBuilder oRC; + + oRC += L"

"; + TextString* s = new TextString(oObj.getString()); + std::wstring wsContents = NSStringExt::CConverter::GetUnicodeFromUTF32(s->getUnicode(), s->getLength()); + delete s; + oRC.WriteEncodeXmlString(wsContents); + oRC += L"

"; + + std::wstring wsRC = oRC.GetData(); + m_arrRC = CAnnotMarkup::ReadRC(U_TO_UTF8(wsRC)); + if (m_arrRC.empty()) + m_unFlags &= ~(1 << 3); + else + m_unFlags |= (1 << 3); + } + oObj.free(); oObj2.free(); + oAnnot.free(); } @@ -1312,24 +2197,24 @@ CAnnotFreeText::CAnnotFreeText(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex // Caret //------------------------------------------------------------------------ -CAnnotCaret::CAnnotCaret(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CMarkupAnnot(pdfDoc, oAnnotRef, nPageIndex) +CAnnotCaret::CAnnotCaret(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CAnnotMarkup(pdfDoc, oAnnotRef, nPageIndex) { Object oAnnot, oObj, oObj2; XRef* pXref = pdfDoc->getXRef(); oAnnotRef->fetch(pXref, &oAnnot); - // 16 - Различия Rect и фактического размера - RD - if (oAnnot.dictLookup("RD", &oObj)->isArray()) + // 15 - Различия Rect и фактического размера - RD + if (oAnnot.dictLookup("RD", &oObj)->isArray() && oObj.arrayGetLength() == 4) { m_unFlags |= (1 << 15); - ARR_GET_NUM(oObj, 0, m_pRD[0]); - ARR_GET_NUM(oObj, 1, m_pRD[1]); - ARR_GET_NUM(oObj, 2, m_pRD[2]); - ARR_GET_NUM(oObj, 3, m_pRD[3]); + m_pRD[0] = ArrGetNum(&oObj, 0); + m_pRD[3] = ArrGetNum(&oObj, 1); + m_pRD[2] = ArrGetNum(&oObj, 2); + m_pRD[1] = ArrGetNum(&oObj, 3); } oObj.free(); - // 17 - Связанный символ - Sy + // 16 - Связанный символ - Sy if (oAnnot.dictLookup("Sy", &oObj)->isName()) { m_unFlags |= (1 << 16); @@ -1344,11 +2229,256 @@ CAnnotCaret::CAnnotCaret(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CM oAnnot.free(); } +//------------------------------------------------------------------------ +// FileAttachment +//------------------------------------------------------------------------ + +CAnnotFileAttachment::CAnnotFileAttachment(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CAnnotMarkup(pdfDoc, oAnnotRef, nPageIndex) +{ + m_pEF = NULL; + + Object oAnnot, oObj, oObj2; + XRef* pXref = pdfDoc->getXRef(); + oAnnotRef->fetch(pXref, &oAnnot); + + // 15 - Иконка - Name + if (oAnnot.dictLookup("Name", &oObj)->isName()) + { + m_unFlags |= (1 << 15); + m_sName = oObj.getName(); + } + oObj.free(); + + Object oFS; + if (!oAnnot.dictLookup("FS", &oFS)->isDict()) + { + oFS.free(); oAnnot.free(); + return; + } + + // 16 - Файловая система - FS + if (oFS.dictLookup("FS", &oObj)->isName()) + { + m_unFlags |= (1 << 16); + m_sFS = oObj.getName(); + } + oObj.free(); + + // 17 - Спецификация файла - F + m_sF = DictLookupString(&oFS, "F", 17); + + // 18 - Спецификация файла - UF + m_sUF = DictLookupString(&oFS, "UF", 18); + + // 19 - Спецификация файла - DOS + m_sDOS = DictLookupString(&oFS, "DOS", 19); + + // 20 - Спецификация файла - Mac + m_sMac = DictLookupString(&oFS, "Mac", 20); + + // 21 - Спецификация файла - Unix + m_sUnix = DictLookupString(&oFS, "Unix", 21); + + // 22 - Идентификатор файла - ID + if (oFS.dictLookup("ID", &oObj)->isArray() && oObj.arrayGetLength() == 2) + { + m_unFlags |= (1 << 22); + if (oObj.arrayGet(0, &oObj2)->isString()) + { + TextString* s = new TextString(oObj2.getString()); + m_sID.first = NSStringExt::CConverter::GetUtf8FromUTF32(s->getUnicode(), s->getLength()); + delete s; + } + oObj2.free(); + if (oObj.arrayGet(1, &oObj2)->isString()) + { + TextString* s = new TextString(oObj2.getString()); + m_sID.second = NSStringExt::CConverter::GetUtf8FromUTF32(s->getUnicode(), s->getLength()); + delete s; + } + oObj2.free(); + } + oObj.free(); + + // 23 - Изменчивость файла - V + if (oFS.dictLookup("V", &oObj)->isBool() && oObj.getBool()) + m_unFlags |= (1 << 23); + oObj.free(); + + // 24 - Встроенные файловые потоки - EF + Object oEF; + if (oFS.dictLookup("EF", &oEF)->isDict()) + { + m_unFlags |= (1 << 24); + m_pEF = new CEmbeddedFiles(); + if (oEF.dictLookup("F", &oObj)->isStream()) + m_pEF->m_pF = getEF(&oObj); + oObj.free(); + if (oEF.dictLookup("UF", &oObj)->isStream()) + m_pEF->m_pUF = getEF(&oObj); + oObj.free(); + if (oEF.dictLookup("DOS", &oObj)->isStream()) + m_pEF->m_pDOS = getEF(&oObj); + oObj.free(); + if (oEF.dictLookup("Mac", &oObj)->isStream()) + m_pEF->m_pMac = getEF(&oObj); + oObj.free(); + if (oEF.dictLookup("Unix", &oObj)->isStream()) + m_pEF->m_pUnix = getEF(&oObj); + oObj.free(); + } + oEF.free(); + + // 25 - Встроенные файловые потоки - RF + Object oRF; + if (oFS.dictLookup("RF", &oRF)->isDict()) + { + m_unFlags |= (1 << 25); + } + oRF.free(); + + // 26 - Описание файла - Desc + m_sDesc = DictLookupString(&oFS, "Desc", 26); + + // 27 - Коллекция - Cl + if (oFS.dictLookup("Cl", &oObj)->isDict()) + { + m_unFlags |= (1 << 27); + } + oObj.free(); + + oFS.free(); oAnnot.free(); +} +CAnnotFileAttachment::~CAnnotFileAttachment() +{ + RELEASEOBJECT(m_pEF); +} + +//------------------------------------------------------------------------ +// Stamp +//------------------------------------------------------------------------ + +CAnnotStamp::CAnnotStamp(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CAnnotMarkup(pdfDoc, oAnnotRef, nPageIndex) +{ + Object oAnnot, oObj; + XRef* pXref = pdfDoc->getXRef(); + oAnnotRef->fetch(pXref, &oAnnot); + + // Иконка - Name + if (oAnnot.dictLookup("Name", &oObj)->isName()) + { + m_sName = oObj.getName(); + } + oObj.free(); + + m_dRotate = 0; + if (oAnnot.dictLookup("Rotate", &oObj)->isNum()) + m_dRotate = oObj.getNum(); + oObj.free(); + + double m[6] = { 1, 0, 0, 1, 0, 0 }, bbox[4] = { 0, 0, 0, 0 }; + + Object oAP, oObj2; + if (oAnnot.dictLookup("AP", &oAP)->isDict() && oAP.dictLookup("N", &oObj2)->isStream()) + { + Object oObj1; + if (oObj2.streamGetDict()->lookup("BBox", &oObj)->isArray() && oObj.arrayGetLength() == 4) + { + for (int i = 0; i < 4; ++i) + { + oObj.arrayGet(i, &oObj1); + bbox[i] = oObj1.isNum() ? oObj1.getNum() : 0; + oObj1.free(); + } + } + + oObj.free(); + if (oObj2.streamGetDict()->lookup("Matrix", &oObj)->isArray() && oObj.arrayGetLength() == 6) + { + for (int i = 0; i < 6; ++i) + { + oObj.arrayGet(i, &oObj1); + m[i] = oObj1.getNum(); + oObj1.free(); + } + } + } + oAP.free(); oObj2.free(); oObj.free(); + + double formXMin, formYMin, formXMax, formYMax, x, y, sx, sy; + x = bbox[0] * m[0] + bbox[1] * m[2] + m[4]; + y = bbox[0] * m[1] + bbox[1] * m[3] + m[5]; + formXMin = formXMax = x; + formYMin = formYMax = y; + x = bbox[0] * m[0] + bbox[3] * m[2] + m[4]; + y = bbox[0] * m[1] + bbox[3] * m[3] + m[5]; + if (x < formXMin) + formXMin = x; + else if (x > formXMax) + formXMax = x; + if (y < formYMin) + formYMin = y; + else if (y > formYMax) + formYMax = y; + x = bbox[2] * m[0] + bbox[1] * m[2] + m[4]; + y = bbox[2] * m[1] + bbox[1] * m[3] + m[5]; + if (x < formXMin) + formXMin = x; + else if (x > formXMax) + formXMax = x; + if (y < formYMin) + formYMin = y; + else if (y > formYMax) + formYMax = y; + x = bbox[2] * m[0] + bbox[3] * m[2] + m[4]; + y = bbox[2] * m[1] + bbox[3] * m[3] + m[5]; + if (x < formXMin) + formXMin = x; + else if (x > formXMax) + formXMax = x; + if (y < formYMin) + formYMin = y; + else if (y > formYMax) + formYMax = y; + + if (formXMin == formXMax) + sx = 1; + else + sx = (m_pRect[2] - m_pRect[0]) / (formXMax - formXMin); + if (formYMin == formYMax) + sy = 1; + else + sy = (m_pRect[3] - m_pRect[1]) / (formYMax - formYMin); + double tx = -formXMin * sx + m_pRect[0]; + double ty = -formYMin * sy + m_pRect[1]; + + m[0] *= sx; + m[1] *= sy; + m[2] *= sx; + m[3] *= sy; + m[4] = m[4] * sx + tx; + m[5] = m[5] * sy + ty; + + m_dX1 = bbox[0] * m[0] + bbox[1] * m[2] + m[4]; + m_dY1 = bbox[0] * m[1] + bbox[1] * m[3] + m[5]; + + m_dX2 = bbox[0] * m[0] + bbox[3] * m[2] + m[4]; + m_dY2 = bbox[0] * m[1] + bbox[3] * m[3] + m[5]; + + m_dX3 = bbox[2] * m[0] + bbox[3] * m[2] + m[4]; + m_dY3 = bbox[2] * m[1] + bbox[3] * m[3] + m[5]; + + m_dX4 = bbox[2] * m[0] + bbox[1] * m[2] + m[4]; + m_dY4 = bbox[2] * m[1] + bbox[1] * m[3] + m[5]; + + oAnnot.free(); +} + //------------------------------------------------------------------------ // Annots //------------------------------------------------------------------------ -CAnnots::CAnnots(PDFDoc* pdfDoc) +CAnnots::CAnnots(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CPdfFontList *pFontList) { Object oObj1, oObj2; XRef* xref = pdfDoc->getXRef(); @@ -1356,18 +2486,12 @@ CAnnots::CAnnots(PDFDoc* pdfDoc) // Порядок вычислений - CO Object* oAcroForm = pAcroForms->getAcroFormObj(); - if (oAcroForm && oAcroForm->dictLookup("CO", &oObj1)->isArray()) + if (oAcroForm->dictLookup("CO", &oObj1)->isArray()) { for (int j = 0; j < oObj1.arrayGetLength(); ++j) { - oObj1.arrayGet(j, &oObj2); - TextString* s = getName(&oObj2); - if (s) - { - std::string sStr = NSStringExt::CConverter::GetUtf8FromUTF32(s->getUnicode(), s->getLength()); - m_arrCO.push_back(sStr); - delete s; - } + if (oObj1.arrayGetNF(j, &oObj2)->isRef()) + m_arrCO.push_back(oObj2.getRefNum()); oObj2.free(); } } @@ -1383,6 +2507,16 @@ CAnnots::CAnnots(PDFDoc* pdfDoc) oField.free(); oFieldRef.free(); continue; } + + if (pField->getPageNum() < 1) + { + oField.free(); oFieldRef.free(); + std::vector::iterator it = std::find(m_arrCO.begin(), m_arrCO.end(), oFieldRef.getRefNum()); + if (it != m_arrCO.end()) + m_arrCO.erase(it); + continue; + } + // Родители Object oParentRefObj; if (oField.dictLookupNF("Parent", &oParentRefObj)->isRef()) @@ -1390,7 +2524,7 @@ CAnnots::CAnnots(PDFDoc* pdfDoc) oParentRefObj.free(); oField.free(); oFieldRef.free(); - CAnnot* pAnnot = NULL; + CAnnotWidget* pAnnot = NULL; AcroFormFieldType oType = pField->getAcroFormFieldType(); switch (oType) { @@ -1424,10 +2558,14 @@ CAnnots::CAnnots(PDFDoc* pdfDoc) break; } if (pAnnot) + { + pAnnot->SetFont(pdfDoc, pField, pFontManager, pFontList); + if (pField->getAcroFormFieldType() == acroFormFieldPushbutton) + pAnnot->SetButtonFont(pdfDoc, pField, pFontManager, pFontList); m_arrAnnots.push_back(pAnnot); + } } } - CAnnots::~CAnnots() { for (int i = 0; i < m_arrParents.size(); ++i) @@ -1436,7 +2574,6 @@ CAnnots::~CAnnots() for (int i = 0; i < m_arrAnnots.size(); ++i) RELEASEOBJECT(m_arrAnnots[i]); } - void CAnnots::getParents(XRef* xref, Object* oFieldRef) { if (!oFieldRef || !xref || !oFieldRef->isRef() || @@ -1448,57 +2585,114 @@ void CAnnots::getParents(XRef* xref, Object* oFieldRef) if (!pAnnotParent || !oFieldRef->fetch(xref, &oField)->isDict()) { oField.free(); + RELEASEOBJECT(pAnnotParent); return; } pAnnotParent->unRefNum = oFieldRef->getRefNum(); - Object oT; - if (oField.dictLookup("T", &oT)->isString()) + Object oObj; + if (oField.dictLookup("T", &oObj)->isString()) { - TextString* s = new TextString(oT.getString()); + TextString* s = new TextString(oObj.getString()); std::string sStr = NSStringExt::CConverter::GetUtf8FromUTF32(s->getUnicode(), s->getLength()); pAnnotParent->unFlags |= (1 << 0); pAnnotParent->sT = sStr; delete s; } - oT.free(); + oObj.free(); - Object oV; - if (oField.dictLookup("V", &oV)) + if (oField.dictLookup("V", &oObj)) { - pAnnotParent->sV = getValue(&oV); + pAnnotParent->sV = getValue(&oObj, false); if (!pAnnotParent->sV.empty()) pAnnotParent->unFlags |= (1 << 1); + + if (oObj.isArray()) + { + pAnnotParent->unFlags |= (1 << 5); + int nVLength = oObj.arrayGetLength(); + for (int j = 0; j < nVLength; ++j) + { + Object oObj2; + if (oObj.arrayGet(j, &oObj2)->isString()) + { + TextString* s = new TextString(oObj2.getString()); + pAnnotParent->arrV.push_back(NSStringExt::CConverter::GetUtf8FromUTF32(s->getUnicode(), s->getLength())); + delete s; + } + oObj2.free(); + } + } } - oV.free(); + oObj.free(); - Object oDV; - if (oField.dictLookup("DV", &oDV)) + if (oField.dictLookup("DV", &oObj)) { - pAnnotParent->sDV = getValue(&oDV); + pAnnotParent->sDV = getValue(&oObj); if (!pAnnotParent->sDV.empty()) pAnnotParent->unFlags |= (1 << 2); } - oDV.free(); + oObj.free(); + + Object oI; + if (oField.dictLookup("I", &oI)->isArray()) + { + int nILength = oI.arrayGetLength(); + for (int j = 0; j < nILength; ++j) + { + if (oI.arrayGet(j, &oObj)->isInt()) + pAnnotParent->arrI.push_back(oObj.getInt()); + oObj.free(); + } + if (!pAnnotParent->arrI.empty()) + pAnnotParent->unFlags |= (1 << 3); + } + oI.free(); + + Object oOpt; + // 6 - Opt + if (oField.dictLookup("Opt", &oOpt)->isArray()) + { + int nOptLength = oOpt.arrayGetLength(); + for (int j = 0; j < nOptLength; ++j) + { + Object oOptJ; + if (!oOpt.arrayGet(j, &oOptJ) || !oOptJ.isString()) + { + oOptJ.free(); + continue; + } + + TextString* s = new TextString(oOptJ.getString()); + pAnnotParent->arrOpt.push_back(NSStringExt::CConverter::GetUtf8FromUTF32(s->getUnicode(), s->getLength())); + delete s; + oOptJ.free(); + } + if (!pAnnotParent->arrOpt.empty()) + pAnnotParent->unFlags |= (1 << 6); + } + oOpt.free(); m_arrParents.push_back(pAnnotParent); Object oParentRefObj; if (oField.dictLookupNF("Parent", &oParentRefObj)->isRef()) { - pAnnotParent->unFlags |= (1 << 3); + pAnnotParent->unFlags |= (1 << 4); pAnnotParent->unRefNumParent = oParentRefObj.getRefNum(); getParents(xref, &oParentRefObj); } oParentRefObj.free(); + + oField.free(); } //------------------------------------------------------------------------ // Markup //------------------------------------------------------------------------ -CMarkupAnnot::CMarkupAnnot(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CAnnot(pdfDoc, oAnnotRef, nPageIndex) +CAnnotMarkup::CAnnotMarkup(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CAnnot(pdfDoc, oAnnotRef, nPageIndex) { m_unFlags = 0; @@ -1506,17 +2700,17 @@ CMarkupAnnot::CMarkupAnnot(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : XRef* pXref = pdfDoc->getXRef(); oAnnotRef->fetch(pXref, &oAnnot); - // 1 - Всплывающая аннотация - Popup + // 0 - Всплывающая аннотация - Popup if (oAnnot.dictLookupNF("Popup", &oObj)->isRef()) { m_unFlags |= (1 << 0); m_unRefNumPopup = oObj.getRefNum(); } - // 2 - Текстовая метка пользователя - T - DICT_LOOKUP_STRING(oAnnot.dictLookup, "T", 1, m_sT); + // 1 - Текстовая метка пользователя - T + m_sT = DictLookupString(&oAnnot, "T", 1); - // 3 - Значение непрозрачности - CA + // 2 - Значение непрозрачности - CA if (oAnnot.dictLookup("CA", &oObj)->isNum()) { m_unFlags |= (1 << 2); @@ -1524,15 +2718,21 @@ CMarkupAnnot::CMarkupAnnot(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : } oObj.free(); - // 4 - Форматированный текст - RC - DICT_LOOKUP_STRING(oAnnot.dictLookup, "RC", 3, m_sRC); + // 3 - Форматированный текст - RC + std::string sRC = DictLookupString(&oAnnot, "RC", 3); + // std::cout << sRC << std::endl; // if (oAnnot.dictLookup("RC", &oObj)->isStream()) // TODO streamGetBlock + m_arrRC = CAnnotMarkup::ReadRC(sRC); + if (m_arrRC.empty()) + m_unFlags &= ~(1 << 3); + else + m_unFlags |= (1 << 3); - // 5 - Дата создания - CreationDate - DICT_LOOKUP_STRING(oAnnot.dictLookup, "CreationDate", 4, m_sCreationDate); + // 4 - Дата создания - CreationDate + m_sCreationDate = DictLookupString(&oAnnot, "CreationDate", 4); - // 6 - Ссылка на аннотацию ответ - IRT + // 5 - Ссылка на аннотацию ответ - IRT if (oAnnot.dictLookupNF("IRT", &oObj)->isRef()) { m_unFlags |= (1 << 5); @@ -1540,7 +2740,7 @@ CMarkupAnnot::CMarkupAnnot(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : } oObj.free(); - // 7 - Тип аннотации ответа - RT + // 6 - Тип аннотации ответа - RT if (oAnnot.dictLookup("RT", &oObj)->isName()) { m_unFlags |= (1 << 6); @@ -1550,11 +2750,165 @@ CMarkupAnnot::CMarkupAnnot(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : } oObj.free(); - // 8 - Краткое описание - Subj - DICT_LOOKUP_STRING(oAnnot.dictLookup, "Subj", 7, m_sSubj); + // 7 - Краткое описание - Subj + m_sSubj = DictLookupString(&oAnnot, "Subj", 7); oAnnot.free(); } +CAnnotMarkup::~CAnnotMarkup() +{ + for (int i = 0; i < m_arrRC.size(); ++i) + RELEASEOBJECT(m_arrRC[i]); +} +void ReadFontData(const std::string& sData, CAnnotMarkup::CFontData* pFont) +{ + size_t nSemicolon = 0; + size_t nColon = sData.find(':'); + while (nColon != std::string::npos && nColon > nSemicolon) + { + std::string sProperty = sData.substr(nSemicolon, nColon - nSemicolon); + nSemicolon = sData.find(';', nSemicolon); + nColon++; + std::string sValue = sData.substr(nColon, nSemicolon - nColon); + nColon = sData.find(':', nSemicolon); + nSemicolon++; + + if (sProperty == "font-size") + pFont->dFontSise = std::stod(sValue); + else if (sProperty == "text-align") + { + // 0 start / left + if (sValue == "center" || sValue == "middle") + pFont->nAlign = 1; + else if (sValue == "right" || sValue == "end") + pFont->nAlign = 2; + else if (sValue == "justify") + pFont->nAlign = 3; + } + else if (sProperty == "color") + { + if (sValue[0] == '#') + { + sValue = sValue.substr(1); + BYTE nColor1 = 0, nColor2 = 0, nColor3 = 0; + if (sValue.length() == 6) + sscanf(sValue.c_str(), "%2hhx%2hhx%2hhx", &nColor1, &nColor2, &nColor3); + else if (sValue.length() == 3) + { + sscanf(sValue.c_str(), "%1hhx%1hhx%1hhx", &nColor1, &nColor2, &nColor3); + nColor1 *= 17; + nColor2 *= 17; + nColor3 *= 17; + } + + pFont->dColor[0] = (double)nColor1 / 255.0; + pFont->dColor[1] = (double)nColor2 / 255.0; + pFont->dColor[2] = (double)nColor3 / 255.0; + } + } + else if (sProperty == "font-weight") + { + // 0 normal / 300 / 400 / 500 + if (sValue == "normal" || sValue == "300" || sValue == "400" || sValue == "500") + pFont->unFontFlags &= ~(1 << 0); + else if (sValue == "bold" || sValue == "bolder" || sValue == "600" || sValue == "700" || sValue == "800" || sValue == "900") + pFont->unFontFlags |= (1 << 0); + } + else if (sProperty == "font-style") + { + // 0 normal + if (sValue == "normal") + pFont->unFontFlags &= ~(1 << 1); + else if (sValue == "italic" || sValue.find("oblique") != std::string::npos) + pFont->unFontFlags |= (1 << 1); + } + else if (sProperty == "font-family") + pFont->sFontFamily = sValue[0] == '\'' ? sValue.substr(1, sValue.length() - 2) : sValue; + else if (sProperty == "text-decoration") + { + if (sValue.find("line-through") != std::string::npos) + pFont->unFontFlags |= (1 << 3); + if (sValue.find("word") != std::string::npos || sValue.find("underline") != std::string::npos) + pFont->unFontFlags |= (1 << 4); + if (sValue.find("none") != std::string::npos) + { + pFont->unFontFlags &= ~(1 << 3); + pFont->unFontFlags &= ~(1 << 4); + } + } + else if (sProperty == "vertical-align") + { + pFont->unFontFlags |= (1 << 5); + pFont->dVAlign = std::stod(sValue); + if (pFont->dVAlign == 0 && sValue[0] == '-') + pFont->dVAlign = -0.01; + } + // font-stretch + } +} +std::vector CAnnotMarkup::ReadRC(const std::string& sRC) +{ + std::vector arrRC; + + XmlUtils::CXmlLiteReader oLightReader; + if (sRC.empty() || !oLightReader.FromStringA(sRC) || !oLightReader.ReadNextNode() || oLightReader.GetNameA() != "body") + return arrRC; + + CAnnotMarkup::CFontData oFontBase; + while (oLightReader.MoveToNextAttribute()) + { + if (oLightReader.GetNameA() == "style") + { + ReadFontData(oLightReader.GetTextA(), &oFontBase); + break; + } + } + oLightReader.MoveToElement(); + + int nDepthP = oLightReader.GetDepth(); + while (oLightReader.ReadNextSiblingNode2(nDepthP)) + { + if (oLightReader.GetNameA() != "p") + continue; + + int nDepthSpan = oLightReader.GetDepth(); + if (oLightReader.IsEmptyNode() || !oLightReader.ReadNextSiblingNode2(nDepthSpan)) + continue; + + do + { + std::string sName = oLightReader.GetNameA(); + if (sName == "span") + { + CAnnotMarkup::CFontData* pFont = new CAnnotMarkup::CFontData(oFontBase); + while (oLightReader.MoveToNextAttribute()) + { + if (oLightReader.GetNameA() == "style") + { + ReadFontData(oLightReader.GetTextA(), pFont); + break; + } + } + oLightReader.MoveToElement(); + + pFont->sText = oLightReader.GetText2A(); + arrRC.push_back(pFont); + } + else if (sName == "#text") + { + CAnnotMarkup::CFontData* pFont = new CAnnotMarkup::CFontData(oFontBase); + pFont->sText = oLightReader.GetTextA(); + arrRC.push_back(pFont); + } + } while (oLightReader.ReadNextSiblingNode2(nDepthSpan)); + } + + return arrRC; +} +void CAnnotMarkup::SetFont(PDFDoc* pdfDoc, Object* oAnnotRef, NSFonts::IFontManager* pFontManager, CPdfFontList *pFontList) +{ + CAnnotFonts::GetFreeTextFont(pdfDoc, pFontManager, pFontList, oAnnotRef, m_arrRC); +} //------------------------------------------------------------------------ // Annot @@ -1565,6 +2919,7 @@ CAnnot::CAnnot(PDFDoc* pdfDoc, AcroFormField* pField) m_pBorder = NULL; m_unAnnotFlag = 0; m_unAFlags = 0; + m_unFlags = 0; Object oObj; pField->getFieldRef(&oObj); @@ -1577,16 +2932,22 @@ CAnnot::CAnnot(PDFDoc* pdfDoc, AcroFormField* pField) oObj.free(); // Номер страницы - P - m_unPage = pField->getPageNum() - 1; + m_unPage = pField->getPageNum(); + if (m_unPage > 0) + --m_unPage; // Координаты - Rect pField->getBBox(&m_pRect[0], &m_pRect[1], &m_pRect[2], &m_pRect[3]); - m_dHeight = pdfDoc->getPageCropHeight(m_unPage + 1); + PDFRectangle* pCropBox = pdfDoc->getCatalog()->getPage(m_unPage + 1)->getCropBox(); + m_dHeight = pCropBox->y2; + m_dX = pCropBox->x1; double dTemp = m_pRect[1]; + m_pRect[0] = m_pRect[0] - m_dX; m_pRect[1] = m_dHeight - m_pRect[3]; + m_pRect[2] = m_pRect[2] - m_dX; m_pRect[3] = m_dHeight - dTemp; - // 1 - Уникальное имя - NM + // 0 - Уникальное имя - NM if (pField->fieldLookup("NM", &oObj)->isString()) { m_unAFlags |= (1 << 0); @@ -1596,7 +2957,7 @@ CAnnot::CAnnot(PDFDoc* pdfDoc, AcroFormField* pField) } oObj.free(); - // 2 - Альтернативный текст - Contents + // 1 - Альтернативный текст - Contents if (pField->fieldLookup("Contents", &oObj)->isString()) { m_unAFlags |= (1 << 1); @@ -1606,7 +2967,7 @@ CAnnot::CAnnot(PDFDoc* pdfDoc, AcroFormField* pField) } oObj.free(); - // 3 - Эффекты границы - BE + // 2 - Эффекты границы - BE if (pField->fieldLookup("BE", &oObj)->isDict()) { Object oBorderBE; @@ -1624,7 +2985,7 @@ CAnnot::CAnnot(PDFDoc* pdfDoc, AcroFormField* pField) } oObj.free(); - // 4 - Специальный цвет для аннотации - C + // 3 - Специальный цвет для аннотации - C if (pField->fieldLookup("C", &oObj)->isArray()) { m_unAFlags |= (1 << 3); @@ -1638,7 +2999,7 @@ CAnnot::CAnnot(PDFDoc* pdfDoc, AcroFormField* pField) } oObj.free(); - // 5 - Границы и Dash Pattern - Border/BS + // 4 - Границы и Dash Pattern - Border/BS m_pBorder = NULL; if (pField->fieldLookup("BS", &oObj)->isDict()) m_pBorder = getBorder(&oObj, true); @@ -1652,7 +3013,7 @@ CAnnot::CAnnot(PDFDoc* pdfDoc, AcroFormField* pField) if (m_pBorder && m_pBorder->nType != 5) m_unAFlags |= (1 << 4); - // 6 - Дата последнего изменения - M + // 5 - Дата последнего изменения - M if (pField->fieldLookup("M", &oObj)->isString()) { m_unAFlags |= (1 << 5); @@ -1662,17 +3023,27 @@ CAnnot::CAnnot(PDFDoc* pdfDoc, AcroFormField* pField) } oObj.free(); - // 7 - Наличие/Отсутствие внешнего вида + // 6 - Наличие/Отсутствие внешнего вида if (pField->fieldLookup("AP", &oObj)->isDict() && oObj.dictGetLength()) m_unAFlags |= (1 << 6); oObj.free(); -} + // 7 - User ID + if (pField->fieldLookup("OUserID", &oObj)->isString()) + { + m_unAFlags |= (1 << 7); + TextString* s = new TextString(oObj.getString()); + m_sOUserID = NSStringExt::CConverter::GetUtf8FromUTF32(s->getUnicode(), s->getLength()); + delete s; + } + oObj.free(); +} CAnnot::CAnnot(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) { m_pBorder = NULL; m_unAnnotFlag = 0; m_unAFlags = 0; + m_unFlags = 0; Object oAnnot, oObj, oObj2; XRef* pXref = pdfDoc->getXRef(); @@ -1688,31 +3059,22 @@ CAnnot::CAnnot(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) // Номер страницы - P m_unPage = nPageIndex; + PDFRectangle* pCropBox = pdfDoc->getCatalog()->getPage(m_unPage + 1)->getCropBox(); + m_dHeight = pCropBox->y2; + m_dX = pCropBox->x1; // Координаты - Rect m_pRect[0] = 0.0, m_pRect[1] = 0.0, m_pRect[2] = 0.0, m_pRect[3] = 0.0; if (oAnnot.dictLookup("Rect", &oObj)->isArray() && oObj.arrayGetLength() == 4) { - ARR_GET_NUM(oObj, 0, m_pRect[0]); - ARR_GET_NUM(oObj, 1, m_pRect[1]); - ARR_GET_NUM(oObj, 2, m_pRect[2]); - ARR_GET_NUM(oObj, 3, m_pRect[3]); - - double dTemp; - m_dHeight = pdfDoc->getPageCropHeight(nPageIndex + 1); - if (m_pRect[0] > m_pRect[2]) - { - dTemp = m_pRect[0]; m_pRect[0] = m_pRect[2]; m_pRect[2] = dTemp; - } - if (m_pRect[1] > m_pRect[3]) - { - dTemp = m_pRect[1]; m_pRect[1] = m_pRect[3]; m_pRect[3] = dTemp; - } - dTemp = m_pRect[1]; m_pRect[1] = m_dHeight - m_pRect[3]; m_pRect[3] = m_dHeight - dTemp; + m_pRect[0] = ArrGetNum(&oObj, 0) - m_dX; + m_pRect[1] = m_dHeight - ArrGetNum(&oObj, 3); + m_pRect[2] = ArrGetNum(&oObj, 2) - m_dX; + m_pRect[3] = m_dHeight - ArrGetNum(&oObj, 1); } oObj.free(); - // 1 - Уникальное имя - NM + // 0 - Уникальное имя - NM if (oAnnot.dictLookup("NM", &oObj)->isString()) { m_unAFlags |= (1 << 0); @@ -1722,7 +3084,7 @@ CAnnot::CAnnot(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) } oObj.free(); - // 2 - Альтернативный текст - Contents + // 1 - Альтернативный текст - Contents if (oAnnot.dictLookup("Contents", &oObj)->isString()) { m_unAFlags |= (1 << 1); @@ -1732,7 +3094,7 @@ CAnnot::CAnnot(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) } oObj.free(); - // 3 - Эффекты границы - BE + // 2 - Эффекты границы - BE if (oAnnot.dictLookup("BE", &oObj)->isDict()) { Object oBorderBE; @@ -1750,7 +3112,7 @@ CAnnot::CAnnot(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) } oObj.free(); - // 4 - Цвет - C + // 3 - Цвет - C if (oAnnot.dictLookup("C", &oObj)->isArray()) { m_unAFlags |= (1 << 3); @@ -1763,7 +3125,7 @@ CAnnot::CAnnot(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) } oObj.free(); - // 5 - Границы и Dash Pattern - Border/BS + // 4 - Границы и Dash Pattern - Border/BS m_pBorder = NULL; if (oAnnot.dictLookup("BS", &oObj)->isDict()) m_pBorder = getBorder(&oObj, true); @@ -1777,7 +3139,7 @@ CAnnot::CAnnot(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) if (m_pBorder && m_pBorder->nType != 5) m_unAFlags |= (1 << 4); - // 6 - Дата последнего изменения - M + // 5 - Дата последнего изменения - M if (oAnnot.dictLookup("M", &oObj)->isString()) { m_unAFlags |= (1 << 5); @@ -1787,85 +3149,55 @@ CAnnot::CAnnot(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) } oObj.free(); - // 7 - Наличие/Отсутствие внешнего вида + // 6 - Наличие/Отсутствие внешнего вида if (oAnnot.dictLookup("AP", &oObj)->isDict() && oObj.dictGetLength()) m_unAFlags |= (1 << 6); oObj.free(); + // 7 - User ID + if (oAnnot.dictLookup("OUserID", &oObj)->isString()) + { + m_unAFlags |= (1 << 7); + TextString* s = new TextString(oObj.getString()); + m_sOUserID = NSStringExt::CConverter::GetUtf8FromUTF32(s->getUnicode(), s->getLength()); + delete s; + } + oObj.free(); + oAnnot.free(); } - CAnnot::~CAnnot() { RELEASEOBJECT(m_pBorder); } - -CAnnot::CBorderType* CAnnot::getBorder(Object* oBorder, bool bBSorBorder) +std::string CAnnot::DictLookupString(Object* pObj, const char* sName, int nByte) { - // Границы и Dash Pattern - Border/BS - CBorderType* pBorderType = new CBorderType(); - if (!oBorder) - return pBorderType; - if (bBSorBorder) - { - pBorderType->nType = annotBorderSolid; - Object oV; - if (oBorder->dictLookup("S", &oV)->isName()) - { - if (oV.isName("S")) - pBorderType->nType = annotBorderSolid; - else if (oV.isName("D")) - pBorderType->nType = annotBorderDashed; - else if (oV.isName("B")) - pBorderType->nType = annotBorderBeveled; - else if (oV.isName("I")) - pBorderType->nType = annotBorderInset; - else if (oV.isName("U")) - pBorderType->nType = annotBorderUnderlined; - } - oV.free(); - if (oBorder->dictLookup("W", &oV)->isNum()) - pBorderType->dWidth = oV.getNum(); - oV.free(); - if (oBorder->dictLookup("D", &oV)->isArray()) - { - Object oObj2; - ARR_GET_NUM(oV, 0, pBorderType->dDashesAlternating); - pBorderType->dGaps = pBorderType->dDashesAlternating; - ARR_GET_NUM(oV, 1, pBorderType->dGaps); - } - oV.free(); - } - else + std::string sRes; + Object oObj; + if (pObj->dictLookup(sName, &oObj)->isString()) { - pBorderType->nType = annotBorderSolid; - Object oObj2; - pBorderType->dWidth = 1.0; - ARR_GET_NUM((*oBorder), 2, pBorderType->dWidth); - - Object oObj; - if (oBorder->arrayGetLength() > 3 && oBorder->arrayGet(3, &oObj)->isArray() && oObj.arrayGetLength() > 1) - { - pBorderType->nType = annotBorderDashed; - ARR_GET_NUM(oObj, 0, pBorderType->dDashesAlternating); - ARR_GET_NUM(oObj, 1, pBorderType->dGaps); - } - oObj.free(); + m_unFlags |= (1 << nByte); + TextString* s = new TextString(oObj.getString()); + sRes = NSStringExt::CConverter::GetUtf8FromUTF32(s->getUnicode(), s->getLength()); + delete s; } - - return pBorderType; + oObj.free(); + return sRes; } //------------------------------------------------------------------------ // AP //------------------------------------------------------------------------ -CAnnotAP::CAnnotAP(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CFontList* pFontList, int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex, const char* sView, const char* sButtonView, AcroFormField* pField) +CAnnotAP::CAnnotAP(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CPdfFontList* pFontList, int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex, const char* sView, const char* sButtonView, AcroFormField* pField) { m_gfx = NULL; m_pFrame = NULL; m_pRendererOut = NULL; m_pRenderer = NULL; + m_dRWScale = 1; + m_dRHScale = 1; + m_bIsStamp = false; Object oAP; if (pField->fieldLookup("AP", &oAP)->isDict() && oAP.dictGetLength()) @@ -1878,17 +3210,19 @@ CAnnotAP::CAnnotAP(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CFontLis Clear(); } - -CAnnotAP::CAnnotAP(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CFontList* pFontList, int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex, const char* sView, Object* oAnnotRef) +CAnnotAP::CAnnotAP(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CPdfFontList* pFontList, int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex, const char* sView, Object* oAnnotRef) { m_gfx = NULL; m_pFrame = NULL; m_pRendererOut = NULL; m_pRenderer = NULL; + m_dRWScale = 1; + m_dRHScale = 1; - Object oAnnot, oAP; + Object oAnnot, oAP, oSubtype; XRef* xref = pdfDoc->getXRef(); oAnnotRef->fetch(xref, &oAnnot); + m_bIsStamp = oAnnot.dictLookup("Subtype", &oSubtype)->isName("Stamp") == gTrue; if (oAnnot.dictLookup("AP", &oAP)->isDict()) { m_unRefNum = oAnnotRef->getRefNum(); @@ -1897,22 +3231,19 @@ CAnnotAP::CAnnotAP(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CFontLis Init(pdfDoc, pFontManager, pFontList, nRasterW, nRasterH, nBackgroundColor, nPageIndex); Draw(pdfDoc, &oAP, nRasterH, nBackgroundColor, oAnnotRef, sView); } - oAP.free(); oAnnot.free(); + oAP.free(); oAnnot.free(); oSubtype.free(); Clear(); } - CAnnotAP::~CAnnotAP() { Clear(); for (int i = 0; i < m_arrAP.size(); ++i) { - RELEASEOBJECT(m_arrAP[i]->pText); RELEASEOBJECT(m_arrAP[i]); } } - void CAnnotAP::Clear() { RELEASEOBJECT(m_gfx); @@ -1920,16 +3251,20 @@ void CAnnotAP::Clear() RELEASEOBJECT(m_pRendererOut); RELEASEOBJECT(m_pRenderer); } - -void CAnnotAP::Init(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CFontList* pFontList, int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex) +void CAnnotAP::Init(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CPdfFontList* pFontList, int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex) { Page* pPage = pdfDoc->getCatalog()->getPage(nPageIndex + 1); + PDFRectangle* pCropBox = pPage->getCropBox(); + m_dCropX = pCropBox->x1; + m_dCropY = pCropBox->y1; - double dWidth = pdfDoc->getPageCropWidth(nPageIndex + 1); - double dHeight = pdfDoc->getPageCropHeight(nPageIndex + 1); + double dWidth = round(pdfDoc->getPageCropWidth(nPageIndex + 1)); + double dHeight = round(pdfDoc->getPageCropHeight(nPageIndex + 1)); + double dRasterW = (double)nRasterW * m_dRWScale; + double dRasterH = (double)nRasterH * m_dRHScale; - m_dWScale = (double)nRasterW / dWidth; - m_dHScale = (double)nRasterH / dHeight; + m_dWScale = dRasterW / dWidth; + m_dHScale = dRasterH / dHeight; m_nWidth = (int)round((m_dx2 - m_dx1) * m_dWScale); m_nHeight = (int)round((m_dy2 - m_dy1) * m_dHScale); m_dWTale = m_nWidth - (m_dx2 - m_dx1) * m_dWScale; @@ -1956,10 +3291,11 @@ void CAnnotAP::Init(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CFontLi m_pRenderer->SetFontManager(pFontManager); m_pRenderer->CreateFromBgraFrame(m_pFrame); m_pRenderer->SetSwapRGB(true); - m_pRenderer->put_Width ((m_dx2 - m_dx1 + (2 + m_dWTale) * dWidth / (double)nRasterW) * 25.4 / 72.0); - m_pRenderer->put_Height((m_dy2 - m_dy1 + (2 + m_dHTale) * dHeight / (double)nRasterH) * 25.4 / 72.0); + m_pRenderer->put_Width ((m_dx2 - m_dx1 + (2 + m_dWTale) * dWidth / dRasterW) * 25.4 / 72.0); + m_pRenderer->put_Height((m_dy2 - m_dy1 + (2 + m_dHTale) * dHeight / dRasterH) * 25.4 / 72.0); if (nBackgroundColor != 0xFFFFFF) m_pRenderer->CommandLong(c_nDarkMode, 1); + m_pRenderer->CommandLong(c_nPenWidth0As1px, 1); m_pRendererOut = new RendererOutputDev(m_pRenderer, pFontManager, pFontList); m_pRendererOut->NewPDF(pdfDoc->getXRef()); @@ -1974,10 +3310,9 @@ void CAnnotAP::Init(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CFontLi m_gfx = new Gfx(pdfDoc, m_pRendererOut, nPageIndex + 1, pPage->getAttrs()->getResourceDict(), 72.0, 72.0, &box, crop ? cropBox : (PDFRectangle *)NULL, 0, NULL, NULL); // Координаты внешнего вида - m_nRx1 = (int)round(m_dx1 * m_dWScale) - 1; - m_nRy1 = nRasterH - (int)round(m_dy2 * m_dHScale) - 1; + m_dRx1 = (m_dx1 - m_dCropX) * m_dWScale - 1; + m_dRy1 = (pdfDoc->getPageCropHeight(nPageIndex + 1) - m_dy2 + m_dCropY) * m_dHScale - 1; } - void CAnnotAP::Init(AcroFormField* pField) { // Номер аннотации для сопоставления с AP @@ -1989,16 +3324,100 @@ void CAnnotAP::Init(AcroFormField* pField) // Координаты - BBox pField->getBBox(&m_dx1, &m_dy1, &m_dx2, &m_dy2); } - void CAnnotAP::Init(Object* oAnnot) { Object oObj, oObj2; if (oAnnot->dictLookup("Rect", &oObj)->isArray() && oObj.arrayGetLength() == 4) { - ARR_GET_NUM(oObj, 0, m_dx1); - ARR_GET_NUM(oObj, 1, m_dy1); - ARR_GET_NUM(oObj, 2, m_dx2); - ARR_GET_NUM(oObj, 3, m_dy2); + m_dx1 = ArrGetNum(&oObj, 0); + m_dy1 = ArrGetNum(&oObj, 1); + m_dx2 = ArrGetNum(&oObj, 2); + m_dy2 = ArrGetNum(&oObj, 3); + + if (m_bIsStamp) + { + double m[6] = { 1, 0, 0, 1, 0, 0 }, bbox[4] = { m_dx1, m_dy1, m_dx2, m_dy2 }; + + oObj.free(); + Object oAP; + if (oAnnot->dictLookup("AP", &oAP)->isDict() && oAP.dictLookup("N", &oObj2)->isStream()) + { + Object oObj1; + if (oObj2.streamGetDict()->lookup("BBox", &oObj)->isArray() && oObj.arrayGetLength() == 4) + { + for (int i = 0; i < 4; ++i) + { + oObj.arrayGet(i, &oObj1); + bbox[i] = oObj1.isNum() ? oObj1.getNum() : 0; + oObj1.free(); + } + } + + oObj.free(); + if (oObj2.streamGetDict()->lookup("Matrix", &oObj)->isArray() && oObj.arrayGetLength() == 6) + { + for (int i = 0; i < 6; ++i) + { + oObj.arrayGet(i, &oObj1); + m[i] = oObj1.getNum(); + oObj1.free(); + } + } + } + oAP.free(); oObj2.free(); + + double formXMin, formYMin, formXMax, formYMax, x, y, sx, sy; + x = bbox[0] * m[0] + bbox[1] * m[2] + m[4]; + y = bbox[0] * m[1] + bbox[1] * m[3] + m[5]; + formXMin = formXMax = x; + formYMin = formYMax = y; + x = bbox[0] * m[0] + bbox[3] * m[2] + m[4]; + y = bbox[0] * m[1] + bbox[3] * m[3] + m[5]; + if (x < formXMin) + formXMin = x; + else if (x > formXMax) + formXMax = x; + if (y < formYMin) + formYMin = y; + else if (y > formYMax) + formYMax = y; + x = bbox[2] * m[0] + bbox[1] * m[2] + m[4]; + y = bbox[2] * m[1] + bbox[1] * m[3] + m[5]; + if (x < formXMin) + formXMin = x; + else if (x > formXMax) + formXMax = x; + if (y < formYMin) + formYMin = y; + else if (y > formYMax) + formYMax = y; + x = bbox[2] * m[0] + bbox[3] * m[2] + m[4]; + y = bbox[2] * m[1] + bbox[3] * m[3] + m[5]; + if (x < formXMin) + formXMin = x; + else if (x > formXMax) + formXMax = x; + if (y < formYMin) + formYMin = y; + else if (y > formYMax) + formYMax = y; + + if (formXMin == formXMax) + sx = 1; + else + sx = (m_dx2 - m_dx1) / (formXMax - formXMin); + if (formYMin == formYMax) + sy = 1; + else + sy = (m_dy2 - m_dy1) / (formYMax - formYMin); + + m_dx1 = bbox[0]; + m_dy1 = bbox[1]; + m_dx2 = bbox[2]; + m_dy2 = bbox[3]; + m_dRWScale = sx; + m_dRHScale = sy; + } double dTemp; if (m_dx1 > m_dx2) @@ -2012,19 +3431,22 @@ void CAnnotAP::Init(Object* oAnnot) } oObj.free(); } - void CAnnotAP::Draw(PDFDoc* pdfDoc, Object* oAP, int nRasterH, int nBackgroundColor, int nPageIndex, AcroFormField* pField, const char* sView, const char* sButtonView) { // Отрисовка внешних видов аннотации AcroFormFieldType oType = pField->getAcroFormFieldType(); ((GlobalParamsAdaptor*)globalParams)->setDrawFormField(true); + double dOffsetX = -(m_dx1 - m_dCropX) * m_dWScale + 1 + m_dWTale / 2; + double dOffsetY = (m_dy2 - m_dCropY) * m_dHScale - nRasterH + 1 + m_dHTale / 2; + nPageIndex++; + std::vector arrAPName { "N", "D", "R" }; for (unsigned int j = 0; j < arrAPName.size(); ++j) { if (sView && strcmp(sView, arrAPName[j]) != 0) continue; - CAnnotAPView* pView = NULL; + Object oObj; if (oAP->dictLookup(arrAPName[j], &oObj)->isDict()) { @@ -2037,33 +3459,33 @@ void CAnnotAP::Draw(PDFDoc* pdfDoc, Object* oAP, int nRasterH, int nBackgroundCo if (strcmp(sButtonView, "Yes") == 0 && strcmp(oObj.dictGetKey(k), "Off") == 0) continue; } - pView = new CAnnotAPView(); + CAnnotAPView* pView = new CAnnotAPView(); pView->sAPName = arrAPName[j]; pView->sASName = oObj.dictGetKey(k); if ((oType == acroFormFieldRadioButton || oType == acroFormFieldCheckbox) && pView->sASName != "Off") pView->sASName = "Yes"; - m_pRenderer->SetCoordTransformOffset(-m_dx1 * m_dWScale + 1 + m_dWTale / 2, m_dy2 * m_dHScale - nRasterH + 1 + m_dHTale / 2); - DrawAppearance(pdfDoc, nPageIndex + 1, pField, m_gfx, arrAPName[j], pView->sASName.c_str()); + m_pRenderer->SetCoordTransformOffset(dOffsetX, dOffsetY); + DrawAppearance(pdfDoc, nPageIndex, pField, m_gfx, arrAPName[j], pView->sASName.c_str()); WriteAppearance(nBackgroundColor, pView); + pView->nBlendMode = GetBlendMode(); + m_arrAP.push_back(pView); } } else if (!oObj.isNull()) { - pView = new CAnnotAPView(); + CAnnotAPView* pView = new CAnnotAPView(); pView->sAPName = arrAPName[j]; - m_pRenderer->SetCoordTransformOffset(-m_dx1 * m_dWScale + 1 + m_dWTale / 2, m_dy2 * m_dHScale - nRasterH + 1 + m_dHTale / 2); - DrawAppearance(pdfDoc, nPageIndex + 1, pField, m_gfx, arrAPName[j], NULL); + m_pRenderer->SetCoordTransformOffset(dOffsetX, dOffsetY); + DrawAppearance(pdfDoc, nPageIndex, pField, m_gfx, arrAPName[j], NULL); WriteAppearance(nBackgroundColor, pView); + pView->nBlendMode = GetBlendMode(); + m_arrAP.push_back(pView); } oObj.free(); - - if (pView) - m_arrAP.push_back(pView); } ((GlobalParamsAdaptor*)globalParams)->setDrawFormField(false); } - void CAnnotAP::Draw(PDFDoc* pdfDoc, Object* oAP, int nRasterH, int nBackgroundColor, Object* oAnnotRef, const char* sView) { ((GlobalParamsAdaptor*)globalParams)->setDrawFormField(true); @@ -2072,19 +3494,21 @@ void CAnnotAP::Draw(PDFDoc* pdfDoc, Object* oAP, int nRasterH, int nBackgroundCo XRef* xref = pdfDoc->getXRef(); oAnnotRef->fetch(xref, &oAnnot); + double dOffsetX = -(m_dx1 - m_dCropX) * m_dWScale + 1 + m_dWTale / 2; + double dOffsetY = (m_dy2 - m_dCropY) * m_dHScale - (double)nRasterH * m_dRHScale + 1 + m_dHTale / 2; + std::vector arrAPName { "N", "D", "R" }; for (unsigned int j = 0; j < arrAPName.size(); ++j) { if (sView && strcmp(sView, arrAPName[j]) != 0) continue; - CAnnotAPView* pView = NULL; Object oObj; if (oAP->dictLookup(arrAPName[j], &oObj)->isStream()) { - pView = new CAnnotAPView(); + CAnnotAPView* pView = new CAnnotAPView(); pView->sAPName = arrAPName[j]; - m_pRenderer->SetCoordTransformOffset(-m_dx1 * m_dWScale + 1 + m_dWTale / 2, m_dy2 * m_dHScale - nRasterH + 1 + m_dHTale / 2); + m_pRenderer->SetCoordTransformOffset(dOffsetX, dOffsetY); Ref ref = oAnnotRef->getRef(); Annot* annot = new Annot(pdfDoc, oAnnot.getDict(), &ref, arrAPName[j]); @@ -2096,17 +3520,15 @@ void CAnnotAP::Draw(PDFDoc* pdfDoc, Object* oAP, int nRasterH, int nBackgroundCo RELEASEOBJECT(annot); WriteAppearance(nBackgroundColor, pView); + pView->nBlendMode = GetBlendMode(); + m_arrAP.push_back(pView); } oObj.free(); - - if (pView) - m_arrAP.push_back(pView); } oAnnot.free(); ((GlobalParamsAdaptor*)globalParams)->setDrawFormField(false); } - void CAnnotAP::WriteAppearance(unsigned int nColor, CAnnotAPView* pView) { BYTE* pSubMatrix = new BYTE[m_nWidth * m_nHeight * 4]; @@ -2123,7 +3545,10 @@ void CAnnotAP::WriteAppearance(unsigned int nColor, CAnnotAPView* pView) } pView->pAP = pSubMatrix; - pView->pText = ((GlobalParamsAdaptor*)globalParams)->GetTextFormField(); +} +BYTE CAnnotAP::GetBlendMode() +{ + return 0; } //------------------------------------------------------------------------ @@ -2136,8 +3561,8 @@ void CAnnotAP::ToWASM(NSWasm::CData& oRes) return; oRes.AddInt(m_unRefNum); - oRes.AddInt(m_nRx1); - oRes.AddInt(m_nRy1); + oRes.AddDouble(m_dRx1); + oRes.AddDouble(m_dRy1); oRes.AddInt(m_nWidth); oRes.AddInt(m_nHeight); oRes.AddInt((unsigned int)m_arrAP.size()); @@ -2151,27 +3576,15 @@ void CAnnotAP::ToWASM(NSWasm::CData& oRes) oRes.AddInt(npSubMatrix1); oRes.AddInt(npSubMatrix >> 32); - BYTE* pTextFormField = m_arrAP[i]->pText; - if (pTextFormField) - { - BYTE* x = pTextFormField; - unsigned int nLength = x ? (x[0] | x[1] << 8 | x[2] << 16 | x[3] << 24) : 4; - nLength -= 4; - oRes.Write(pTextFormField + 4, nLength); - } - else - oRes.AddInt(0); - RELEASEARRAYOBJECTS(pTextFormField); - m_arrAP[i]->pText = NULL; + oRes.WriteBYTE(m_arrAP[i]->nBlendMode); } } - void CAnnots::ToWASM(NSWasm::CData& oRes) { // Порядок вычислений - CO oRes.AddInt(m_arrCO.size()); for (int i = 0; i < m_arrCO.size(); ++i) - oRes.WriteString(m_arrCO[i]); + oRes.AddInt(m_arrCO[i]); // Родительские Fields oRes.AddInt(m_arrParents.size()); @@ -2182,7 +3595,6 @@ void CAnnots::ToWASM(NSWasm::CData& oRes) for (int i = 0; i < m_arrAnnots.size(); ++i) m_arrAnnots[i]->ToWASM(oRes); } - void CAnnots::CAnnotParent::ToWASM(NSWasm::CData& oRes) { oRes.AddInt(unRefNum); @@ -2194,9 +3606,26 @@ void CAnnots::CAnnotParent::ToWASM(NSWasm::CData& oRes) if (unFlags & (1 << 2)) oRes.WriteString(sDV); if (unFlags & (1 << 3)) + { + oRes.AddInt((unsigned int)arrI.size()); + for (int i = 0; i < arrI.size(); ++i) + oRes.AddInt(arrI[i]); + } + if (unFlags & (1 << 4)) oRes.AddInt(unRefNumParent); + if (unFlags & (1 << 5)) + { + oRes.AddInt((unsigned int)arrV.size()); + for (int i = 0; i < arrV.size(); ++i) + oRes.WriteString(arrV[i]); + } + if (unFlags & (1 << 6)) + { + oRes.AddInt((unsigned int)arrOpt.size()); + for (int i = 0; i < arrOpt.size(); ++i) + oRes.WriteString(arrOpt[i]); + } } - void CAnnot::ToWASM(NSWasm::CData& oRes) { oRes.AddInt(m_unRefNum); @@ -2218,14 +3647,15 @@ void CAnnot::ToWASM(NSWasm::CData& oRes) { oRes.AddInt((unsigned int)m_arrC.size()); for (int i = 0; i < m_arrC.size(); ++i) - oRes.AddDouble(m_arrC[i]); + oRes.WriteDouble(m_arrC[i]); } if (m_pBorder && (m_unAFlags & (1 << 4))) m_pBorder->ToWASM(oRes); if (m_unAFlags & (1 << 5)) oRes.WriteString(m_sM); + if (m_unAFlags & (1 << 7)) + oRes.WriteString(m_sOUserID); } - void CAnnot::CBorderType::ToWASM(NSWasm::CData& oRes) { BYTE nBP = nType; @@ -2238,20 +3668,23 @@ void CAnnot::CBorderType::ToWASM(NSWasm::CData& oRes) oRes.AddDouble(dWidth); if (nType == annotBorderDashed) { - oRes.AddDouble(dDashesAlternating); - oRes.AddDouble(dGaps); + oRes.AddInt(arrDash.size()); + for (int i = 0; i < arrDash.size(); ++i) + oRes.AddDouble(arrDash[i]); } } - void CAnnotWidget::ToWASM(NSWasm::CData& oRes) { oRes.WriteBYTE(m_nType); CAnnot::ToWASM(oRes); + oRes.WriteString(m_sFontName); + oRes.AddDouble(m_dFontSize); + oRes.AddInt(m_unFontStyle); oRes.AddInt(m_arrTC.size()); for (int i = 0; i < m_arrTC.size(); ++i) - oRes.AddDouble(m_arrTC[i]); + oRes.WriteDouble(m_arrTC[i]); oRes.WriteBYTE(m_nQ); oRes.AddInt(m_unFieldFlag); oRes.AddInt(m_unFlags); @@ -2259,13 +3692,17 @@ void CAnnotWidget::ToWASM(NSWasm::CData& oRes) oRes.WriteString(m_sTU); if (m_unFlags & (1 << 1)) oRes.WriteString(m_sDS); + if (m_unFlags & (1 << 2)) + oRes.WriteString(m_sActualFontName); if (m_unFlags & (1 << 3)) oRes.WriteBYTE(m_nH); + if (m_unFlags & (1 << 4)) + oRes.WriteString(m_sFontKey); if (m_unFlags & (1 << 5)) { oRes.AddInt(m_arrBC.size()); for (int i = 0; i < m_arrBC.size(); ++i) - oRes.AddDouble(m_arrBC[i]); + oRes.WriteDouble(m_arrBC[i]); } if (m_unFlags & (1 << 6)) oRes.AddInt(m_unR); @@ -2273,7 +3710,7 @@ void CAnnotWidget::ToWASM(NSWasm::CData& oRes) { oRes.AddInt(m_arrBG.size()); for (int i = 0; i < m_arrBG.size(); ++i) - oRes.AddDouble(m_arrBG[i]); + oRes.WriteDouble(m_arrBG[i]); } if (m_unFlags & (1 << 8)) oRes.WriteString(m_sDV); @@ -2281,6 +3718,8 @@ void CAnnotWidget::ToWASM(NSWasm::CData& oRes) oRes.AddInt(m_unRefNumParent); if (m_unFlags & (1 << 18)) oRes.WriteString(m_sT); + if (m_unFlags & (1 << 19)) + oRes.WriteString(m_sButtonFontName); oRes.AddInt(m_arrAction.size()); for (int i = 0; i < m_arrAction.size(); ++i) { @@ -2288,7 +3727,6 @@ void CAnnotWidget::ToWASM(NSWasm::CData& oRes) m_arrAction[i]->ToWASM(oRes); } } - void CActionGoTo::ToWASM(NSWasm::CData& oRes) { oRes.WriteBYTE(1); @@ -2327,7 +3765,6 @@ void CActionGoTo::ToWASM(NSWasm::CData& oRes) CAction::ToWASM(oRes); } - void CActionURI::ToWASM(NSWasm::CData& oRes) { oRes.WriteBYTE(6); @@ -2335,7 +3772,6 @@ void CActionURI::ToWASM(NSWasm::CData& oRes) CAction::ToWASM(oRes); } - void CActionNamed::ToWASM(NSWasm::CData& oRes) { oRes.WriteBYTE(10); @@ -2343,7 +3779,6 @@ void CActionNamed::ToWASM(NSWasm::CData& oRes) CAction::ToWASM(oRes); } - void CActionJavaScript::ToWASM(NSWasm::CData& oRes) { oRes.WriteBYTE(14); @@ -2351,7 +3786,6 @@ void CActionJavaScript::ToWASM(NSWasm::CData& oRes) CAction::ToWASM(oRes); } - void CActionHide::ToWASM(NSWasm::CData& oRes) { oRes.WriteBYTE(9); @@ -2362,7 +3796,6 @@ void CActionHide::ToWASM(NSWasm::CData& oRes) CAction::ToWASM(oRes); } - void CActionResetForm::ToWASM(NSWasm::CData& oRes) { oRes.WriteBYTE(12); @@ -2373,7 +3806,6 @@ void CActionResetForm::ToWASM(NSWasm::CData& oRes) CAction::ToWASM(oRes); } - void CAction::ToWASM(NSWasm::CData& oRes) { if (pNext) @@ -2384,38 +3816,43 @@ void CAction::ToWASM(NSWasm::CData& oRes) else oRes.WriteBYTE(0); } - void CAnnotWidgetBtn::ToWASM(NSWasm::CData& oRes) { CAnnotWidget::ToWASM(oRes); - oRes.AddInt(m_unIFFlag); + if (m_unFlags & (1 << 9)) + oRes.WriteString(m_sV); if (m_nType == 27) { + oRes.AddInt(m_unIFFlag); if (m_unFlags & (1 << 10)) oRes.WriteString(m_sCA); if (m_unFlags & (1 << 11)) oRes.WriteString(m_sRC); if (m_unFlags & (1 << 12)) oRes.WriteString(m_sAC); + if (m_unFlags & (1 << 13)) + oRes.WriteBYTE(m_nTP); + if (m_unIFFlag & (1 << 0)) + { + if (m_unIFFlag & (1 << 1)) + oRes.WriteBYTE(m_nSW); + if (m_unIFFlag & (1 << 2)) + oRes.WriteBYTE(m_nS); + if (m_unIFFlag & (1 << 3)) + { + oRes.AddDouble(m_dA1); + oRes.AddDouble(m_dA2); + } + } } else - oRes.WriteBYTE(m_nStyle); - if (m_unFlags & (1 << 13)) - oRes.WriteBYTE(m_nTP); - if (m_unIFFlag & (1 << 1)) - oRes.WriteBYTE(m_nSW); - if (m_unIFFlag & (1 << 2)) - oRes.WriteBYTE(m_nS); - if (m_unIFFlag & (1 << 3)) { - oRes.AddDouble(m_dA1); - oRes.AddDouble(m_dA2); + oRes.WriteBYTE(m_nStyle); + if (m_unFlags & (1 << 14)) + oRes.WriteString(m_sAP_N_Yes); } - if (m_unFlags & (1 << 14)) - oRes.WriteString(m_sAP_N_Yes); } - void CAnnotWidgetTx::ToWASM(NSWasm::CData& oRes) { CAnnotWidget::ToWASM(oRes); @@ -2427,7 +3864,6 @@ void CAnnotWidgetTx::ToWASM(NSWasm::CData& oRes) if (m_unFieldFlag & (1 << 25)) oRes.WriteString(m_sRV); } - void CAnnotWidgetCh::ToWASM(NSWasm::CData& oRes) { CAnnotWidget::ToWASM(oRes); @@ -2445,14 +3881,24 @@ void CAnnotWidgetCh::ToWASM(NSWasm::CData& oRes) } if (m_unFlags & (1 << 11)) oRes.AddInt(m_unTI); + if (m_unFlags & (1 << 12)) + { + oRes.AddInt(m_arrI.size()); + for (int i = 0; i < m_arrI.size(); ++i) + oRes.AddInt(m_arrI[i]); + } + if (m_unFlags & (1 << 13)) + { + oRes.AddInt(m_arrV.size()); + for (int i = 0; i < m_arrV.size(); ++i) + oRes.WriteString(m_arrV[i]); + } } - void CAnnotWidgetSig::ToWASM(NSWasm::CData& oRes) { CAnnotWidget::ToWASM(oRes); } - -void CMarkupAnnot::ToWASM(NSWasm::CData& oRes) +void CAnnotMarkup::ToWASM(NSWasm::CData& oRes) { CAnnot::ToWASM(oRes); @@ -2464,7 +3910,24 @@ void CMarkupAnnot::ToWASM(NSWasm::CData& oRes) if (m_unFlags & (1 << 2)) oRes.AddDouble(m_dCA); if (m_unFlags & (1 << 3)) - oRes.WriteString(m_sRC); + { + oRes.AddInt(m_arrRC.size()); + for (int i = 0; i < m_arrRC.size(); ++i) + { + oRes.WriteBYTE(m_arrRC[i]->nAlign); + oRes.AddInt(m_arrRC[i]->unFontFlags); + if (m_arrRC[i]->unFontFlags & (1 << 5)) + oRes.AddDouble(m_arrRC[i]->dVAlign); + if (m_arrRC[i]->unFontFlags & (1 << 6)) + oRes.WriteString(m_arrRC[i]->sActualFont); + oRes.AddDouble(m_arrRC[i]->dFontSise); + oRes.WriteDouble(m_arrRC[i]->dColor[0]); + oRes.WriteDouble(m_arrRC[i]->dColor[1]); + oRes.WriteDouble(m_arrRC[i]->dColor[2]); + oRes.WriteString(m_arrRC[i]->sFontFamily); + oRes.WriteString(m_arrRC[i]->sText); + } + } if (m_unFlags & (1 << 4)) oRes.WriteString(m_sCreationDate); if (m_unFlags & (1 << 5)) @@ -2474,12 +3937,11 @@ void CMarkupAnnot::ToWASM(NSWasm::CData& oRes) if (m_unFlags & (1 << 7)) oRes.WriteString(m_sSubj); } - void CAnnotText::ToWASM(NSWasm::CData& oRes) { oRes.WriteBYTE(0); // Text - CMarkupAnnot::ToWASM(oRes); + CAnnotMarkup::ToWASM(oRes); if (m_unFlags & (1 << 16)) oRes.WriteBYTE(m_nName); @@ -2488,7 +3950,6 @@ void CAnnotText::ToWASM(NSWasm::CData& oRes) if (m_unFlags & (1 << 18)) oRes.WriteBYTE(m_nState); } - void CAnnotPopup::ToWASM(NSWasm::CData& oRes) { oRes.WriteBYTE(15); // Popup @@ -2499,12 +3960,11 @@ void CAnnotPopup::ToWASM(NSWasm::CData& oRes) if (m_unFlags & (1 << 1)) oRes.AddInt(m_unRefNumParent); } - void CAnnotInk::ToWASM(NSWasm::CData& oRes) { oRes.WriteBYTE(14); // Ink - CMarkupAnnot::ToWASM(oRes); + CAnnotMarkup::ToWASM(oRes); oRes.AddInt(m_arrInkList.size()); for (int i = 0; i < m_arrInkList.size(); ++i) @@ -2514,12 +3974,11 @@ void CAnnotInk::ToWASM(NSWasm::CData& oRes) oRes.AddDouble(m_arrInkList[i][j]); } } - void CAnnotLine::ToWASM(NSWasm::CData& oRes) { oRes.WriteBYTE(3); // Line - CMarkupAnnot::ToWASM(oRes); + CAnnotMarkup::ToWASM(oRes); for (int i = 0; i < 4; ++i) oRes.AddDouble(m_pL[i]); @@ -2533,7 +3992,7 @@ void CAnnotLine::ToWASM(NSWasm::CData& oRes) { oRes.AddInt((unsigned int)m_arrIC.size()); for (int i = 0; i < m_arrIC.size(); ++i) - oRes.AddDouble(m_arrIC[i]); + oRes.WriteDouble(m_arrIC[i]); } if (m_unFlags & (1 << 17)) oRes.AddDouble(m_dLL); @@ -2551,23 +4010,21 @@ void CAnnotLine::ToWASM(NSWasm::CData& oRes) oRes.AddDouble(m_pCO[1]); } } - void CAnnotTextMarkup::ToWASM(NSWasm::CData& oRes) { oRes.WriteBYTE(m_nSubtype); // Highlight, Underline, Squiggly, StrikeOut - CMarkupAnnot::ToWASM(oRes); + CAnnotMarkup::ToWASM(oRes); oRes.AddInt((unsigned int)m_arrQuadPoints.size()); for (int i = 0; i < m_arrQuadPoints.size(); ++i) oRes.AddDouble(m_arrQuadPoints[i]); } - void CAnnotSquareCircle::ToWASM(NSWasm::CData& oRes) { oRes.WriteBYTE(m_nSubtype); // Square, Circle - CMarkupAnnot::ToWASM(oRes); + CAnnotMarkup::ToWASM(oRes); if (m_unFlags & (1 << 15)) { @@ -2578,15 +4035,14 @@ void CAnnotSquareCircle::ToWASM(NSWasm::CData& oRes) { oRes.AddInt((unsigned int)m_arrIC.size()); for (int i = 0; i < m_arrIC.size(); ++i) - oRes.AddDouble(m_arrIC[i]); + oRes.WriteDouble(m_arrIC[i]); } } - void CAnnotPolygonLine::ToWASM(NSWasm::CData& oRes) { oRes.WriteBYTE(m_nSubtype); // Polygon, PolyLine - CMarkupAnnot::ToWASM(oRes); + CAnnotMarkup::ToWASM(oRes); oRes.AddInt((unsigned int)m_arrVertices.size()); for (int i = 0; i < m_arrVertices.size(); ++i) @@ -2601,19 +4057,19 @@ void CAnnotPolygonLine::ToWASM(NSWasm::CData& oRes) { oRes.AddInt((unsigned int)m_arrIC.size()); for (int i = 0; i < m_arrIC.size(); ++i) - oRes.AddDouble(m_arrIC[i]); + oRes.WriteDouble(m_arrIC[i]); } if (m_unFlags & (1 << 20)) oRes.WriteBYTE(m_nIT); } - void CAnnotFreeText::ToWASM(NSWasm::CData& oRes) { oRes.WriteBYTE(2); // FreeText - CMarkupAnnot::ToWASM(oRes); + CAnnotMarkup::ToWASM(oRes); oRes.WriteBYTE(m_nQ); + oRes.AddInt(m_nRotate); if (m_unFlags & (1 << 15)) { for (int i = 0; i < 4; ++i) @@ -2631,13 +4087,18 @@ void CAnnotFreeText::ToWASM(NSWasm::CData& oRes) oRes.WriteBYTE(m_nLE); if (m_unFlags & (1 << 20)) oRes.WriteBYTE(m_nIT); + if (m_unFlags & (1 << 21)) + { + oRes.AddInt((unsigned int)m_arrCFromDA.size()); + for (int i = 0; i < m_arrCFromDA.size(); ++i) + oRes.WriteDouble(m_arrCFromDA[i]); + } } - void CAnnotCaret::ToWASM(NSWasm::CData& oRes) { oRes.WriteBYTE(13); // Caret - CMarkupAnnot::ToWASM(oRes); + CAnnotMarkup::ToWASM(oRes); if (m_unFlags & (1 << 15)) { @@ -2647,4 +4108,99 @@ void CAnnotCaret::ToWASM(NSWasm::CData& oRes) if (m_unFlags & (1 << 16)) oRes.WriteBYTE(m_nSy); } +void CAnnotFileAttachment::ToWASM(NSWasm::CData& oRes) +{ + oRes.WriteBYTE(16); // FileAttachment + + CAnnotMarkup::ToWASM(oRes); + + if (m_unFlags & (1 << 15)) + oRes.WriteString(m_sName); + if (m_unFlags & (1 << 16)) + oRes.WriteString(m_sFS); + if (m_unFlags & (1 << 17)) + oRes.WriteString(m_sF); + if (m_unFlags & (1 << 18)) + oRes.WriteString(m_sUF); + if (m_unFlags & (1 << 19)) + oRes.WriteString(m_sDOS); + if (m_unFlags & (1 << 20)) + oRes.WriteString(m_sMac); + if (m_unFlags & (1 << 21)) + oRes.WriteString(m_sUnix); + if (m_unFlags & (1 << 22)) + { + oRes.WriteString(m_sID.first); + oRes.WriteString(m_sID.second); + } + if (m_unFlags & (1 << 24)) + { + int nFlag = 0; + int nPos = oRes.GetSize(); + oRes.AddInt(nFlag); + + auto fWriteEF = [&oRes](CAnnotFileAttachment::CEmbeddedFile* pEF) + { + oRes.AddInt(pEF->nLength); + unsigned long long npSubMatrix = (unsigned long long)pEF->pFile; + unsigned int npSubMatrix1 = npSubMatrix & 0xFFFFFFFF; + oRes.AddInt(npSubMatrix1); + oRes.AddInt(npSubMatrix >> 32); + pEF->bFree = false; + }; + + // Освобождение памяти необходимо вызвать с js стороны + if (m_pEF->m_pF) + { + nFlag |= (1 << 0); + fWriteEF(m_pEF->m_pF); + } + if (m_pEF->m_pUF) + { + nFlag |= (1 << 1); + fWriteEF(m_pEF->m_pUF); + } + if (m_pEF->m_pDOS) + { + nFlag |= (1 << 2); + fWriteEF(m_pEF->m_pDOS); + } + if (m_pEF->m_pMac) + { + nFlag |= (1 << 3); + fWriteEF(m_pEF->m_pMac); + } + if (m_pEF->m_pUnix) + { + nFlag |= (1 << 4); + fWriteEF(m_pEF->m_pUnix); + } + oRes.AddInt(nFlag, nPos); + } + if (m_unFlags & (1 << 25)) + { + } + if (m_unFlags & (1 << 26)) + oRes.WriteString(m_sDesc); + if (m_unFlags & (1 << 27)) + { + } +} +void CAnnotStamp::ToWASM(NSWasm::CData& oRes) +{ + oRes.WriteBYTE(12); // Stamp + + CAnnotMarkup::ToWASM(oRes); + + oRes.WriteString(m_sName); + oRes.WriteDouble(m_dRotate); + oRes.WriteDouble(m_dX1); + oRes.WriteDouble(m_dY1); + oRes.WriteDouble(m_dX2); + oRes.WriteDouble(m_dY2); + oRes.WriteDouble(m_dX3); + oRes.WriteDouble(m_dY3); + oRes.WriteDouble(m_dX4); + oRes.WriteDouble(m_dY4); +} } diff --git a/PdfFile/SrcReader/PdfAnnot.h b/PdfFile/SrcReader/PdfAnnot.h index f82e13d6b96..4eeec542c61 100644 --- a/PdfFile/SrcReader/PdfAnnot.h +++ b/PdfFile/SrcReader/PdfAnnot.h @@ -117,8 +117,8 @@ struct CActionResetForm final : public CAction class CAnnotAP final { public: - CAnnotAP(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CFontList* pFontList, int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex, const char* sView, const char* sButtonView, AcroFormField* pField); - CAnnotAP(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CFontList* pFontList, int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex, const char* sView, Object* oAnnotRef); + CAnnotAP(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CPdfFontList* pFontList, int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex, const char* sView, const char* sButtonView, AcroFormField* pField); + CAnnotAP(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CPdfFontList* pFontList, int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex, const char* sView, Object* oAnnotRef); ~CAnnotAP(); void ToWASM(NSWasm::CData& oRes); @@ -126,33 +126,36 @@ class CAnnotAP final private: struct CAnnotAPView final { + BYTE nBlendMode; std::string sAPName; std::string sASName; BYTE* pAP; - BYTE* pText; }; + void WriteAppearance(unsigned int nColor, CAnnotAPView* pView); + BYTE GetBlendMode(); + void Init(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CPdfFontList* pFontList, int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex); + void Init(AcroFormField* pField); + void Init(Object* oAnnot); + void Draw(PDFDoc* pdfDoc, Object* oAP, int nRasterH, int nBackgroundColor, int nPageIndex, AcroFormField* pField, const char* sView, const char* sButtonView); + void Draw(PDFDoc* pdfDoc, Object* oAP, int nRasterH, int nBackgroundColor, Object* oAnnotRef, const char* sView); + void Clear(); unsigned int m_unRefNum; // Номер ссылки на объект double m_dx1, m_dy1, m_dx2, m_dy2; + double m_dCropX, m_dCropY; double m_dWScale, m_dHScale; - double m_dWTale; - double m_dHTale; - int m_nRx1, m_nRy1, m_nWidth, m_nHeight; + double m_dRWScale, m_dRHScale; + double m_dWTale, m_dHTale; + double m_dRx1, m_dRy1; + int m_nWidth, m_nHeight; std::vector m_arrAP; + bool m_bIsStamp; Gfx* m_gfx; CBgraFrame* m_pFrame; RendererOutputDev* m_pRendererOut; NSGraphics::IGraphicsRenderer* m_pRenderer; - - void Init(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CFontList* pFontList, int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex); - void Init(AcroFormField* pField); - void Init(Object* oAnnot); - void Draw(PDFDoc* pdfDoc, Object* oAP, int nRasterH, int nBackgroundColor, int nPageIndex, AcroFormField* pField, const char* sView, const char* sButtonView); - void Draw(PDFDoc* pdfDoc, Object* oAP, int nRasterH, int nBackgroundColor, Object* oAnnotRef, const char* sView); - - void Clear(); }; //------------------------------------------------------------------------ @@ -166,41 +169,41 @@ class CAnnot virtual void ToWASM(NSWasm::CData& oRes); -protected: - CAnnot(PDFDoc* pdfDoc, AcroFormField* pField); - CAnnot(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex); - - double m_dHeight; // Высота холста, для Y трансормации - -private: struct CBorderType final { CBorderType() { nType = 0; dWidth = 1; - dDashesAlternating = 3; - dGaps = 3; } void ToWASM(NSWasm::CData& oRes); BYTE nType; double dWidth; - double dDashesAlternating; - double dGaps; + std::vector arrDash; }; - CBorderType* getBorder(Object* oBorder, bool bBSorBorder); + +protected: + CAnnot(PDFDoc* pdfDoc, AcroFormField* pField); + CAnnot(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex); + std::string DictLookupString(Object* pObj, const char* sName, int nByte); unsigned int m_unAFlags; + unsigned int m_unFlags; + double m_dHeight; // Высота холста, для Y трансформации + double m_dX; // Смещение по X для трансформации + double m_pRect[4]; // Координаты + +private: unsigned int m_unAnnotFlag; // Флаг аннотации - F unsigned int m_unRefNum; // Номер ссылки на объект unsigned int m_unPage; // Страница - double m_pRect[4]; // Координаты std::pair m_pBE; // Эффекты границы std::string m_sContents; // Отображаемый текст std::string m_sNM; // Уникальное имя std::string m_sM; // Дата последнего изменения + std::string m_sOUserID; // OO User ID std::vector m_arrC; // Специальный цвет CBorderType* m_pBorder; // Граница }; @@ -214,18 +217,23 @@ class CAnnotWidget : public CAnnot public: virtual ~CAnnotWidget(); + void SetFont(PDFDoc* pdfDoc, AcroFormField* pField, NSFonts::IFontManager* pFontManager, CPdfFontList *pFontList); + void SetButtonFont(PDFDoc* pdfDoc, AcroFormField* pField, NSFonts::IFontManager* pFontManager, CPdfFontList *pFontList); + protected: CAnnotWidget(PDFDoc* pdfDoc, AcroFormField* pField); + std::string FieldLookupString(AcroFormField* pField, const char* sName, int nByte); virtual void ToWASM(NSWasm::CData& oRes) override; - unsigned int m_unFlags; BYTE m_nType; // Тип - FT + флаги unsigned int m_unFieldFlag; // Флаг - Ff private: unsigned int m_unR; // Поворот аннотации относительно страницы - R unsigned int m_unRefNumParent; // Номер ссылки на объект родителя + unsigned int m_unFontStyle; // Стиль шрифта - из DA + double m_dFontSize; // Размер шрифта - из DA std::vector m_arrTC; // Цвет текста - из DA std::vector m_arrBC; // Цвет границ - BC std::vector m_arrBG; // Цвет фона - BG @@ -236,6 +244,10 @@ class CAnnotWidget : public CAnnot std::string m_sDS; // Строка стиля по умолчанию - DS std::string m_sDV; // Значение по-умолчанию - DV std::string m_sT; // Частичное имя поля - T + std::string m_sFontKey; // Уникальный идентификатор шрифта + std::string m_sFontName; // Имя шрифта - из DA + std::string m_sActualFontName; // Имя замененного шрифта + std::string m_sButtonFontName; // Имя шрифта кнопки }; class CAnnotWidgetBtn final : public CAnnotWidget @@ -250,6 +262,7 @@ class CAnnotWidgetBtn final : public CAnnotWidget BYTE m_nSW; BYTE m_nS; unsigned int m_unIFFlag; + std::string m_sV; std::string m_sCA; std::string m_sRC; std::string m_sAC; @@ -277,6 +290,8 @@ class CAnnotWidgetCh final : public CAnnotWidget void ToWASM(NSWasm::CData& oRes) override; private: std::string m_sV; + std::vector m_arrV; + std::vector m_arrI; std::vector< std::pair > m_arrOpt; unsigned int m_unTI; }; @@ -306,17 +321,39 @@ class CAnnotPopup final : public CAnnot }; //------------------------------------------------------------------------ -// PdfReader::CMarkupAnnot +// PdfReader::CAnnotMarkup //------------------------------------------------------------------------ -class CMarkupAnnot : public CAnnot +class CAnnotMarkup : public CAnnot { +public: + struct CFontData final + { + bool bFind; + BYTE nAlign; + unsigned int unFontFlags; // 0 Bold, 1 Italic, 3 зачеркнутый, 4 подчеркнутый, 5 vertical-align, 6 actual font + double dFontSise; + double dVAlign; + double dColor[3]; + std::string sFontFamily; + std::string sActualFont; + std::string sText; + + CFontData() : bFind(false), nAlign(0), unFontFlags(4), dFontSise(10), dVAlign(0), dColor{0, 0, 0} {} + CFontData(const CFontData& oFont) : bFind(oFont.bFind), nAlign(oFont.nAlign), unFontFlags(oFont.unFontFlags), dFontSise(oFont.dFontSise), dVAlign(oFont.dVAlign), + dColor{oFont.dColor[0], oFont.dColor[1], oFont.dColor[2]}, sFontFamily(oFont.sFontFamily), sActualFont(oFont.sActualFont), sText(oFont.sText) {} + }; + + void SetFont(PDFDoc* pdfDoc, Object* oAnnotRef, NSFonts::IFontManager* pFontManager, CPdfFontList *pFontList); + static std::vector ReadRC(const std::string& sRC); + protected: - CMarkupAnnot(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex); + CAnnotMarkup(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex); + virtual ~CAnnotMarkup(); virtual void ToWASM(NSWasm::CData& oRes) override; - unsigned int m_unFlags; + std::vector m_arrRC; // Форматированный текст private: BYTE m_nRT; // Тип аннотации-ответа @@ -324,7 +361,6 @@ class CMarkupAnnot : public CAnnot unsigned int m_unRefNumIRT; // Номер ссылки на аннотацию-ответ double m_dCA; // Значение непрозрачности std::string m_sT; // Текстовая метка, пользователь добавивший аннотацию - std::string m_sRC; // Форматированный текст для отображения во всплывающем окне std::string m_sCreationDate; // Дата создания std::string m_sSubj; // Краткое описание }; @@ -333,7 +369,7 @@ class CMarkupAnnot : public CAnnot // PdfReader::CAnnotText //------------------------------------------------------------------------ -class CAnnotText final : public CMarkupAnnot +class CAnnotText final : public CAnnotMarkup { public: CAnnotText(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex); @@ -349,7 +385,7 @@ class CAnnotText final : public CMarkupAnnot // PdfReader::CAnnotInk //------------------------------------------------------------------------ -class CAnnotInk final : public CMarkupAnnot +class CAnnotInk final : public CAnnotMarkup { public: CAnnotInk(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex); @@ -364,7 +400,7 @@ class CAnnotInk final : public CMarkupAnnot // PdfReader::CAnnotLine //------------------------------------------------------------------------ -class CAnnotLine final : public CMarkupAnnot +class CAnnotLine final : public CAnnotMarkup { public: CAnnotLine(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex); @@ -388,7 +424,7 @@ class CAnnotLine final : public CMarkupAnnot // PdfReader::CAnnotTextMarkup //------------------------------------------------------------------------ -class CAnnotTextMarkup final : public CMarkupAnnot +class CAnnotTextMarkup final : public CAnnotMarkup { public: CAnnotTextMarkup(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex); @@ -404,7 +440,7 @@ class CAnnotTextMarkup final : public CMarkupAnnot // PdfReader::CAnnotSquareCircle //------------------------------------------------------------------------ -class CAnnotSquareCircle final : public CMarkupAnnot +class CAnnotSquareCircle final : public CAnnotMarkup { public: CAnnotSquareCircle(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex); @@ -421,7 +457,7 @@ class CAnnotSquareCircle final : public CMarkupAnnot // PdfReader::CAnnotPolygonPolyline //------------------------------------------------------------------------ -class CAnnotPolygonLine final : public CMarkupAnnot +class CAnnotPolygonLine final : public CAnnotMarkup { public: CAnnotPolygonLine(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex); @@ -441,7 +477,7 @@ class CAnnotPolygonLine final : public CMarkupAnnot // PdfReader::CAnnotFreeText //------------------------------------------------------------------------ -class CAnnotFreeText final : public CMarkupAnnot +class CAnnotFreeText final : public CAnnotMarkup { public: CAnnotFreeText(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex); @@ -452,8 +488,10 @@ class CAnnotFreeText final : public CMarkupAnnot BYTE m_nQ; // Выравнивание текста - Q BYTE m_nIT; // Назначение аннотации BYTE m_nLE; // Стиль окончания линии + int m_nRotate; std::string m_sDS; // Строка стиля по умолчанию - DS double m_pRD[4]{}; // Различия Rect и фактического размера + std::vector m_arrCFromDA; // Цвет границы std::vector m_arrCL; // Координаты выноски }; @@ -461,7 +499,7 @@ class CAnnotFreeText final : public CMarkupAnnot // PdfReader::CAnnotCaret //------------------------------------------------------------------------ -class CAnnotCaret final : public CMarkupAnnot +class CAnnotCaret final : public CAnnotMarkup { public: CAnnotCaret(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex); @@ -473,6 +511,78 @@ class CAnnotCaret final : public CMarkupAnnot double m_pRD[4]{}; // Различия Rect и фактического размера }; +//------------------------------------------------------------------------ +// PdfReader::CAnnotFileAttachment +//------------------------------------------------------------------------ + +class CAnnotFileAttachment final : public CAnnotMarkup +{ +public: + CAnnotFileAttachment(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex); + virtual ~CAnnotFileAttachment(); + + void ToWASM(NSWasm::CData& oRes) override; + + struct CEmbeddedFile + { + BYTE* pFile; + int nLength; + bool bFree; + + CEmbeddedFile() : pFile(NULL), nLength(0), bFree(true) {} + ~CEmbeddedFile() { if (bFree) RELEASEARRAYOBJECTS(pFile); } + }; + + struct CEmbeddedFiles + { + CEmbeddedFile* m_pF; + CEmbeddedFile* m_pUF; + CEmbeddedFile* m_pDOS; + CEmbeddedFile* m_pMac; + CEmbeddedFile* m_pUnix; + + CEmbeddedFiles() : m_pF(NULL), m_pUF(NULL), m_pDOS(NULL), m_pMac(NULL), m_pUnix(NULL) {} + ~CEmbeddedFiles() + { + RELEASEOBJECT(m_pF); + RELEASEOBJECT(m_pUF); + RELEASEOBJECT(m_pDOS); + RELEASEOBJECT(m_pMac); + RELEASEOBJECT(m_pUnix); + } + }; + +private: + std::string m_sName; // Иконка + std::string m_sFS; // Файловая система + std::string m_sDesc; // Описание файла + std::string m_sF; // Спецификация файла (обратная совместимость) + std::string m_sUF; // Спецификация файла (кросс-платформенная и межъязыковая совместимость) + std::string m_sDOS; // Спецификация файла DOS + std::string m_sMac; // Спецификация файла Mac + std::string m_sUnix; // Спецификация файла Unix + std::pair m_sID; // Идентификатор файла + CEmbeddedFiles* m_pEF; // EF содержит F/UF/DOS/Mac/Unix со ссылками на встроенные файловые потоки по соответствующим спецификациях + // TODO RF содержит F/UF/DOS/Mac/Unix с массивами связанных файлов по соответствующим спецификациях + // TODO Cl коллекция для создания пользовательского интерфейса +}; + +//------------------------------------------------------------------------ +// PdfReader::CAnnotStamp +//------------------------------------------------------------------------ + +class CAnnotStamp final : public CAnnotMarkup +{ +public: + CAnnotStamp(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex); + + void ToWASM(NSWasm::CData& oRes) override; +private: + std::string m_sName; // Иконка + double m_dRotate; + double m_dX1, m_dY1, m_dX2, m_dY2, m_dX3, m_dY3, m_dX4, m_dY4; +}; + //------------------------------------------------------------------------ // PdfReader::CAnnots //------------------------------------------------------------------------ @@ -480,7 +590,7 @@ class CAnnotCaret final : public CMarkupAnnot class CAnnots { public: - CAnnots(PDFDoc* pdfDoc); + CAnnots(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CPdfFontList *pFontList); ~CAnnots(); void ToWASM(NSWasm::CData& oRes); @@ -500,6 +610,9 @@ class CAnnots unsigned int unFlags; unsigned int unRefNum; // Номер ссылки на объект unsigned int unRefNumParent; // Номер ссылки на объект родителя + std::vector arrI; + std::vector arrV; + std::vector arrOpt; std::string sT; std::string sV; std::string sDV; @@ -507,11 +620,28 @@ class CAnnots void getParents(XRef* xref, Object* oFieldRef); - std::vector m_arrCO; // Порядок вычислений - CO + std::vector m_arrCO; // Порядок вычислений - CO std::vector m_arrParents; // Родительские Fields std::vector m_arrAnnots; }; +//------------------------------------------------------------------------ +// PdfReader::CAnnotFonts +//------------------------------------------------------------------------ + +class CAnnotFonts final +{ +public: + static bool IsBaseFont(const std::wstring& wsName); + static std::map GetAllFonts(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CPdfFontList* pFontList); + static std::wstring GetFontData(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CPdfFontList *pFontList, Object* oFontRef, std::string& sFontName, std::string& sActualFontName, bool& bBold, bool& bItalic); + static bool GetFontFromAP(PDFDoc* pdfDoc, AcroFormField* pField, Object* oFontRef, std::string& sFontKey); + static std::map GetAnnotFont(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CPdfFontList *pFontList, Object* oAnnotRef); + static std::map GetFreeTextFont(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CPdfFontList* pFontList, Object* oAnnotRef, std::vector& arrRC); +private: + static bool FindFonts(Object* oStream, int nDepth, Object* oResFonts); +}; + } #endif // _PDF_READER_ANNOT_H diff --git a/PdfFile/SrcReader/RendererOutputDev.cpp b/PdfFile/SrcReader/RendererOutputDev.cpp index 93de17ae4c7..44fed8e90fe 100644 --- a/PdfFile/SrcReader/RendererOutputDev.cpp +++ b/PdfFile/SrcReader/RendererOutputDev.cpp @@ -30,6 +30,7 @@ * */ +#include "RendererOutputDev.h" #include "Adaptors.h" #include "../lib/xpdf/ErrorCodes.h" #include "../lib/xpdf/GfxState.h" @@ -38,27 +39,29 @@ #include "../lib/fofi/FoFiType1C.h" #include "../lib/fofi/FoFiIdentifier.h" #include "../lib/xpdf/Page.h" -#include "../lib/xpdf/CMap.h" #include "../lib/xpdf/Dict.h" #include "../lib/xpdf/Stream.h" -//#include "FontFileTrueType.h" -//#include "FontFileType1C.h" +#include "../lib/xpdf/PDFDoc.h" #include "../lib/xpdf/CharCodeToUnicode.h" -#include "RendererOutputDev.h" #include "XmlUtils.h" +#include "../../DesktopEditor/graphics/pro/Graphics.h" #include "../../DesktopEditor/graphics/Image.h" #include "../../DesktopEditor/graphics/pro/Fonts.h" #include "../../DesktopEditor/common/File.h" #include "../../DesktopEditor/common/Path.h" #include "../../DesktopEditor/common/Array.h" +#include "../../DesktopEditor/common/StringExt.h" #include "../../DesktopEditor/graphics/BaseThread.h" +#include "../../DesktopEditor/graphics/commands/DocInfo.h" +#include "../../DesktopEditor/graphics/AlphaMask.h" #include "../Resources/BaseFonts.h" #include #ifndef BUILDING_WASM_MODULE #define FONTS_USE_AFM_SETTINGS #else +#include "../../DesktopEditor/graphics/pro/js/wasm/src/serialize.h" #include "FontsWasm.h" #define FONTS_USE_ONLY_MEMORY_STREAMS #endif @@ -69,7 +72,7 @@ #define OO_INLINE inline #endif -namespace NSCorrectFontName +namespace PdfReader { bool CheckFontNameStyle(std::wstring& sName, const std::wstring& sStyle) { @@ -83,7 +86,7 @@ namespace NSCorrectFontName while (std::wstring::npos != (nPos = sName2.find(sStyle, nPos))) { size_t nOffset = 0; - if ((nPos > 0) && sName2.at(nPos - 1) == '-') + if ((nPos > 0) && (sName2.at(nPos - 1) == '-' || sName2.at(nPos - 1) == ',')) { --nPos; ++nOffset; @@ -96,7 +99,7 @@ namespace NSCorrectFontName return bRet; } - void CheckFontNamePDF(std::wstring& sName, NSFonts::CFontSelectFormat& format) + void RendererOutputDev::CheckFontStylePDF(std::wstring& sName, bool& bBold, bool& bItalic) { if (sName.length() > 7 && sName.at(6) == '+') { @@ -116,33 +119,61 @@ namespace NSCorrectFontName } } - bool bBold = false; - bool bItalic = false; - + CheckFontNameStyle(sName, L"condensedbold"); + CheckFontNameStyle(sName, L"semibold"); CheckFontNameStyle(sName, L"regular"); - CheckFontNameStyle(sName, L"condensed"); + + CheckFontNameStyle(sName, L"ultraexpanded"); + CheckFontNameStyle(sName, L"extraexpanded"); + CheckFontNameStyle(sName, L"semiexpanded"); + CheckFontNameStyle(sName, L"expanded"); + + CheckFontNameStyle(sName, L"ultracondensed"); + CheckFontNameStyle(sName, L"extracondensed"); + CheckFontNameStyle(sName, L"semicondensed"); CheckFontNameStyle(sName, L"condensedlight"); + CheckFontNameStyle(sName, L"condensed"); //CheckFontNameStyle(sName, L"light"); - CheckFontNameStyle(sName, L"condensedbold"); - CheckFontNameStyle(sName, L"semibold"); + if (CheckFontNameStyle(sName, L"bold_italic")) { bBold = true; bItalic = true; } + if (CheckFontNameStyle(sName, L"bold_oblique")) { bBold = true; bItalic = true; } + if (CheckFontNameStyle(sName, L"boldmt")) bBold = true; - if (CheckFontNameStyle(sName, L"bold")) bBold = true; + if (CheckFontNameStyle(sName, L"bold")) bBold = true; if (CheckFontNameStyle(sName, L"italicmt")) bItalic = true; - if (CheckFontNameStyle(sName, L"italic")) bItalic = true; - if (CheckFontNameStyle(sName, L"oblique")) bItalic = true; + if (CheckFontNameStyle(sName, L"italic")) bItalic = true; + if (CheckFontNameStyle(sName, L"oblique")) bItalic = true; - if (CheckFontNameStyle(sName, L"bolditalicmt")) { bBold = true; bItalic = true; } - if (CheckFontNameStyle(sName, L"bolditalic")) { bBold = true; bItalic = true; } - if (CheckFontNameStyle(sName, L"bold_italic")) { bBold = true; bItalic = true; } - if (CheckFontNameStyle(sName, L"boldoblique")) { bBold = true; bItalic = true; } - if (CheckFontNameStyle(sName, L"bold_oblique")) { bBold = true; bItalic = true; } + //if (CheckFontNameStyle(sName, L"bolditalicmt")) { bBold = true; bItalic = true; } + //if (CheckFontNameStyle(sName, L"bolditalic")) { bBold = true; bItalic = true; } + //if (CheckFontNameStyle(sName, L"boldoblique")) { bBold = true; bItalic = true; } + } + + void CheckFontNamePDF(std::wstring& sName, NSFonts::CFontSelectFormat* format) + { + bool bBold = false; + bool bItalic = false; + + RendererOutputDev::CheckFontStylePDF(sName, bBold, bItalic); + + if (format) + { + if (bBold) + format->bBold = new INT(1); + if (bItalic) + format->bItalic = new INT(1); + } + } - if (bBold) - format.bBold = new INT(1); - if (bItalic) - format.bItalic = new INT(1); + void Transform(double* pMatrix, double dUserX, double dUserY, double* pdDeviceX, double* pdDeviceY) + { + *pdDeviceX = dUserX * pMatrix[0] + dUserY * pMatrix[2] + pMatrix[4]; + *pdDeviceY = dUserX * pMatrix[1] + dUserY * pMatrix[3] + pMatrix[5]; + } + inline int luminosity(BYTE* p) + { + return (p[2]*77 + p[1]*150 + p[0]*29) >> 8; } } @@ -245,165 +276,17 @@ namespace PdfReader //-------------------------------------------------------------------------------------- // CFontList //-------------------------------------------------------------------------------------- - CFontList::CFontList() + CPdfFontList::CPdfFontList() { m_oCS.InitializeCriticalSection(); m_oFontMap.clear(); } - CFontList::~CFontList() + CPdfFontList::~CPdfFontList() { m_oCS.DeleteCriticalSection(); Clear(); } - void CFontList::LoadFromFile(std::wstring wsDirPath) - { - return; - //Clear(); - - //CStringW wsFilePath = wsDirPath + CStringW( _T("/FontList.rsc") ); - //XmlUtils::CXmlNode oMainNode; - - //if ( !oMainNode.FromXmlFile( wsFilePath ) ) - // return; - - //if ( _T("PDFFontList") == oMainNode.getName() ) - //{ - // std::vector oFonts; - // oMainNode.GetNodes( _T("Font"), oFonts ); - // for ( int nIndex = 0; nIndex < oFonts.GetCount(); nIndex++ ) - // { - // XmlUtils::CXmlNode oFont; - // Ref oRef; - // CStringW sFilePath; - // int nLength = 0; - // unsigned short *pCodeToGid = NULL, *pCodeToUnicode = NULL; - - // if ( oFonts.GetAt( nIndex, oFont ) ) - // { - // XmlUtils::CXmlNode oNode; - // CStringW sValue; - - // if ( oFont.GetNode( _T("ID"), oNode ) ) - // { - // sValue = oNode.GetAttribute( _T("num") ); - // oRef.num = XmlUtils::GetInteger( sValue ); - // sValue = oNode.GetAttribute( _T("gen") ); - // oRef.gen = XmlUtils::GetInteger( sValue ); - // } - - // if ( oFont.GetNode( _T("FilePath"), oNode ) ) - // { - // sFilePath = oNode.GetAttribute( _T("value") ); - // } - // if ( oFont.GetNode( _T("CodeToGid"), oNode ) ) - // { - // sValue = oNode.GetAttribute( _T("length") ); - // nLength = XmlUtils::GetInteger( sValue ); - // pCodeToGid = (unsigned short *)MemUtilsMalloc( sizeof(unsigned short) * nLength ); - // if ( !pCodeToGid ) - // return; - - // std::vector oArray; - // oNode.GetNodes( _T("Entry"), oArray ); - // for ( int nCurIndex = 0; nCurIndex < oArray.GetCount() && nCurIndex < nLength; nCurIndex++ ) - // { - // XmlUtils::CXmlNode oArrayItem; - // if ( oArray.GetAt( nCurIndex, oArrayItem ) ) - // { - // sValue = oArrayItem.GetAttribute( _T("value") ); - // pCodeToGid[nCurIndex] = XmlUtils::GetInteger( sValue ); - // } - // else - // pCodeToGid[nCurIndex] = 0; - // } - // } - // if ( oFont.GetNode( _T("CodeToUnicode"), oNode ) ) - // { - // sValue = oNode.GetAttribute( _T("length") ); - // nLength = XmlUtils::GetInteger( sValue ); - // pCodeToUnicode = (int *)MemUtilsMalloc( sizeof(int) * nLength ); - // if ( !pCodeToUnicode ) - // return; - - // std::vector oArray; - // oNode.GetNodes( _T("Entry"), oArray ); - // for ( int nCurIndex = 0; nCurIndex < oArray.GetCount() && nCurIndex < nLength; nCurIndex++ ) - // { - // XmlUtils::CXmlNode oArrayItem; - // if ( oArray.GetAt( nCurIndex, oArrayItem ) ) - // { - // sValue = oArrayItem.GetAttribute( _T("value") ); - // pCodeToUnicode[nCurIndex] = XmlUtils::GetInteger( sValue ); - // } - // else - // pCodeToUnicode[nCurIndex] = 0; - // } - // } - - // } - - // Add( oRef, sFilePath, pCodeToGid, pCodeToUnicode, nLength ); - // } - //} - } - void CFontList::SaveToFile(std::wstring wsDirPath) - { - return; - //CStringW wsFilePath = wsDirPath + CStringW( _T("/FontList.rsc") ); - //XmlUtils::CXmlWriter oWriter; - - //oWriter.WriteNodeBegin( _T("PDFFontList") ); - - //for ( int nIndex = 0; nIndex < (int)m_arrList.GetCount(); nIndex++ ) - //{ - // TFontEntry oEntry = m_arrList.GetAt( nIndex ); - // oWriter.WriteNodeBegin( _T("Font") ); - - - // oWriter.WriteNodeBegin( _T("ID"), true ); - // oWriter.WriteAttribute( _T("num"), oEntry.oRef.num ); - // oWriter.WriteAttribute( _T("gen"), oEntry.oRef.gen ); - // oWriter.WriteNodeEnd( _T("ID"), true, true ); - - // oWriter.WriteNodeBegin( _T("FilePath"), true ); - // oWriter.WriteAttribute( _T("value"), oEntry.wsFilePath ); - // oWriter.WriteNodeEnd( _T("FilePath"), true, true ); - - // if ( NULL != oEntry.pCodeToGID ) - // { - // oWriter.WriteNodeBegin( _T("CodeToGid"), true ); - // oWriter.WriteAttribute( _T("length"), oEntry.nLen ); - // oWriter.WriteNodeEnd( _T("CodeToGid"), true, false ); - // for ( int nCurIndex = 0; nCurIndex < oEntry.nLen; nCurIndex++ ) - // { - // oWriter.WriteNodeBegin( _T("Entry"), true ); - // oWriter.WriteAttribute( _T("value"), oEntry.pCodeToGID[nCurIndex] ); - // oWriter.WriteNodeEnd( _T("Entry"), true, true ); - // } - // oWriter.WriteNodeEnd( _T("CodeToGid") ); - // } - - // if ( NULL != oEntry.pCodeToUnicode ) - // { - // oWriter.WriteNodeBegin( _T("CodeToUnicode"), true ); - // oWriter.WriteAttribute( _T("length"), oEntry.nLen ); - // oWriter.WriteNodeEnd( _T("CodeToUnicode"), true, false ); - // for ( int nCurIndex = 0; nCurIndex < oEntry.nLen; nCurIndex++ ) - // { - // oWriter.WriteNodeBegin( _T("Entry"), true ); - // oWriter.WriteAttribute( _T("value"), oEntry.pCodeToUnicode[nCurIndex] ); - // oWriter.WriteNodeEnd( _T("Entry"), true, true ); - // } - // oWriter.WriteNodeEnd( _T("CodeToUnicode") ); - // } - - // oWriter.WriteNodeEnd( _T("Font") ); - //} - //oWriter.WriteNodeEnd( _T("PDFFontList") ); - - //oWriter.SaveToFile( wsFilePath ); - } - bool CFontList::Find(Ref oRef, TFontEntry *pEntry) + bool CPdfFontList::Find(Ref oRef, TFontEntry* pEntry) { CTemporaryCS* pCS = new CTemporaryCS(&m_oCS); @@ -420,7 +303,7 @@ namespace PdfReader return bResult; } - bool CFontList::Find2(Ref oRef, TFontEntry **ppEntry) + bool CPdfFontList::Find2(Ref oRef, TFontEntry** ppEntry) { CTemporaryCS* pCS = new CTemporaryCS(&m_oCS); @@ -435,7 +318,7 @@ namespace PdfReader if (!bResult) { - (*ppEntry) = Add(oRef, L"", NULL, NULL, 0, 0); + (*ppEntry) = Add(oRef, std::wstring(), NULL, NULL, 0, 0); (*ppEntry)->bAvailable = false; } @@ -443,14 +326,12 @@ namespace PdfReader return bResult; } - TFontEntry* CFontList::Add(Ref oRef, std::wstring wsFileName, int *pCodeToGID, int *pCodeToUnicode, unsigned int unLenGID, unsigned int unLenUnicode) + TFontEntry* CPdfFontList::Add(Ref oRef, const std::wstring& wsFileName, int* pCodeToGID, int* pCodeToUnicode, unsigned int unLenGID, unsigned int unLenUnicode) { // Данная функция приходит только из Find2, поэтому проверять есть ли данный шрифт уже не надо CTemporaryCS* pCS = new CTemporaryCS(&m_oCS); - TFontEntry *pNewEntry = new TFontEntry; - pNewEntry->oRef.gen = oRef.gen; - pNewEntry->oRef.num = oRef.num; + TFontEntry* pNewEntry = new TFontEntry; pNewEntry->wsFilePath = wsFileName; pNewEntry->pCodeToGID = pCodeToGID; pNewEntry->pCodeToUnicode = pCodeToUnicode; @@ -463,12 +344,12 @@ namespace PdfReader return pNewEntry; } - void CFontList::Remove(Ref oRef) + void CPdfFontList::Remove(Ref oRef) { CRefFontMap::iterator oPos = m_oFontMap.find(oRef); if (m_oFontMap.end() != oPos) { - TFontEntry *pEntry = oPos->second; + TFontEntry* pEntry = oPos->second; if (NULL != pEntry) { MemUtilsFree(pEntry->pCodeToGID); @@ -478,11 +359,11 @@ namespace PdfReader m_oFontMap.erase(oPos); } } - void CFontList::Clear() + void CPdfFontList::Clear() { for (auto const &oIt : m_oFontMap) { - TFontEntry *pEntry = oIt.second; + TFontEntry* pEntry = oIt.second; if (NULL != pEntry) { MemUtilsFree(pEntry->pCodeToGID); @@ -492,7 +373,7 @@ namespace PdfReader } m_oFontMap.clear(); } - bool CFontList::GetFont(Ref *pRef, TFontEntry *pEntry) + bool CPdfFontList::GetFont(Ref* pRef, TFontEntry* pEntry) { TFontEntry* pFindEntry = Lookup(*pRef); if (NULL == pFindEntry) @@ -501,20 +382,26 @@ namespace PdfReader *pEntry = *pFindEntry; return true; } + TFontEntry* CPdfFontList::Lookup(Ref& oRef) + { + CRefFontMap::const_iterator oPos = m_oFontMap.find(oRef); + return m_oFontMap.end() == oPos ? NULL : oPos->second; + } + void CPdfFontList::Add(Ref& oRef, TFontEntry* pFontEntry) + { + // До вызова данной функции надо проверять есть ли элемент с данным ключом + m_oFontMap.insert(std::pair(oRef, pFontEntry)); + } //-------------------------------------------------------------------------------------- // RendererOutputDev //-------------------------------------------------------------------------------------- - RendererOutputDev::RendererOutputDev(IRenderer *pRenderer, NSFonts::IFontManager* pFontManager, CFontList *pFontList) + RendererOutputDev::RendererOutputDev(IRenderer* pRenderer, NSFonts::IFontManager* pFontManager, CPdfFontList* pFontList) { - m_pFontManager = pFontManager; m_pFontManager = pFontManager; m_pFontList = pFontList; m_bTiling = false; - //m_pBufferTextClip = NULL; tmpchange - //m_sClip = NULL; - m_lRendererType = c_nUnknownRenderer; m_pRenderer = pRenderer; @@ -531,124 +418,30 @@ namespace PdfReader m_pRenderer->get_Type(&m_lRendererType); } - m_pbBreak = NULL; - m_bTransparentGroup = false; - m_bIsolatedTransparentGroup = false; - m_bTransparentGroupSoftMask = false; - m_bTransparentGroupSoftMaskEnd = false; + m_pXref = NULL; + m_pbBreak = NULL; + m_pSoftMask = NULL; m_bDrawOnlyText = false; - m_bClipChanged = true; - - //m_oFontList.LoadFromFile( (GlobalParamsAdaptor*)globalParams->GetTempFolder() ); - //// Тестовый пример - //m_pRenderer->NewPage(); - //m_pRenderer->BeginCommand( c_nPageType ); - - //m_pRenderer->SetWidth( 100.0f ); - //m_pRenderer->SetHeight( 100.0f ); - - //m_oFont.SetFontSize( 1.0 ); - //m_oPen.SetSize( 0.3 ); - //m_oPen.SetAlpha( 128 ); - //m_pRenderer->SetFont( m_oFont.ToXmlString().AllocSysString() ); - //m_pRenderer->SetShadow( m_oShadow.ToXmlString().AllocSysString() ); - //m_pRenderer->SetPen( m_oPen.ToXmlString().AllocSysString() ); - - //m_pRenderer->PathCommandMoveTo( 0, 50 ); - //m_pRenderer->PathCommandLineTo( 100, 50 ); - //m_pRenderer->DrawPath( c_nStroke ); - - //m_pRenderer->PathCommandMoveTo( 50, 0 ); - //m_pRenderer->PathCommandLineTo( 50, 100 ); - //m_pRenderer->DrawPath( c_nStroke ); - // - //m_oPen.SetSize( 0.3 ); - //m_oPen.SetAlpha( 255 ); - //m_pRenderer->SetPen( m_oPen.ToXmlString().AllocSysString() ); - - //IAVSOfficeRendererTemplate2 *pRenderer2 = NULL; - //m_pRenderer->QueryInterface( __uuidof(AVSOfficeEditor::IAVSOfficeRendererTemplate2), (void**)&pRenderer2 ); - - //double pNewTm[6], arrMatrix[6]; - //double dAscent = 0.905; - //double dDescent = -0.211; - //double dKoef = ( dAscent - fabs( dDescent ) ) * 1; - - //double pCTM[6] = { 10, 0, 0, 10, 50, 50}; - //pNewTm[0] = 1;//pTm[0]; - //pNewTm[1] = 0;//pTm[1]; - //pNewTm[2] = -0;//pTm[2]; - //pNewTm[3] = -1;//pTm[3]; - //pNewTm[4] = 0 + 0 * dKoef; - //pNewTm[5] = 0 + 1 * dKoef; - - //arrMatrix[0] = pNewTm[0] * pCTM[0] + pNewTm[1] * pCTM[2]; - //arrMatrix[1] = -(pNewTm[0] * pCTM[1] + pNewTm[1] * pCTM[3]); - //arrMatrix[2] = pNewTm[2] * pCTM[0] + pNewTm[3] * pCTM[2]; - //arrMatrix[3] = -(pNewTm[2] * pCTM[1] + pNewTm[3] * pCTM[3]); - //arrMatrix[4] = pNewTm[4] * pCTM[0] + pNewTm[5] * pCTM[2] + pCTM[4]; - //arrMatrix[5] = -(pNewTm[4] * pCTM[1] + pNewTm[5] * pCTM[3] + pCTM[5]) + 100; - - //double dAcsentFactor = ( ( fabs(-0.324) + fabs(1.005) ) - ( dAscent + fabs( dDescent ) ) ) / 2 + dAscent; - //double dAscentShiftX = -arrMatrix[2] * dAcsentFactor; - //double dAscentShiftY = -arrMatrix[3] * dAcsentFactor; - - ////arrMatrix[4] += dAscentShiftX; - ////arrMatrix[5] += dAscentShiftY; - - - //pRenderer2->SetTransform( arrMatrix[0], arrMatrix[1], arrMatrix[2], arrMatrix[3], arrMatrix[4], arrMatrix[5] ); - - //m_pRenderer->PathCommandMoveTo( -0.664, -0.324 ); - //m_pRenderer->PathCommandLineTo( 2.000, -0.324 ); - //m_pRenderer->PathCommandLineTo( 2.000, 1.005 ); - //m_pRenderer->PathCommandLineTo( -0.664, 1.005 ); - //m_pRenderer->PathCommandClose(); - //m_pRenderer->DrawPath( c_nStroke ); - - - //m_pRenderer->CommandDrawText( _T("A"), 0, 0, 0, 0, 0 ); - - //double dAlpha = 0*(3.14 / 180.f) * 160; - //pRenderer2->SetTransform( cos( dAlpha ), -sin( dAlpha ), -sin( dAlpha ), -cos( dAlpha ), 50, 50 ); - //m_pRenderer->PathCommandMoveTo( 0, 0 ); - //m_pRenderer->PathCommandLineTo( 10, 0 ); - //m_pRenderer->PathCommandLineTo( 10, 10 ); - //m_pRenderer->PathCommandLineTo( 0, 10 ); - //m_pRenderer->PathCommandClose(); - //m_pRenderer->DrawPath( c_nStroke ); - - //m_pRenderer->EndCommand( c_nPageType ); - //RELEASEINTERFACE( pRenderer2 ); } RendererOutputDev::~RendererOutputDev() { m_pRenderer = NULL; - - // if (m_sClip) tmpchange - // delete m_sClip; - - // if (m_pBufferTextClip) tmpchange - // delete m_pBufferTextClip; - + RELEASEINTERFACE(m_pSoftMask); } - void RendererOutputDev::startPage(int nPageIndex, GfxState *pGState) + void RendererOutputDev::startPage(int nPageIndex, GfxState* pGState) { + if (nPageIndex < 0) + return; + m_pRenderer->BeginCommand(c_nPageType); - // Переводим пункты в миллиметры m_arrMatrix[0] = 1; m_arrMatrix[1] = 0; m_arrMatrix[2] = 0; m_arrMatrix[3] = 1; m_arrMatrix[4] = 0; m_arrMatrix[5] = 0; - m_bTransparentGroup = false; - m_bIsolatedTransparentGroup = false; - m_bTransparentGroupSoftMask = false; - m_bTransparentGroupSoftMaskEnd = false; - if (c_nHtmlRendrerer2 == m_lRendererType) - m_bDrawOnlyText = (S_OK == m_pRenderer->CommandLong(c_nCommandLongTypeOnlyText, 0)) ? true : false; + m_bDrawOnlyText = S_OK == m_pRenderer->CommandLong(c_nCommandLongTypeOnlyText, 0); else if (c_nHtmlRendrererText == m_lRendererType) m_bDrawOnlyText = true; else @@ -658,25 +451,49 @@ namespace PdfReader { m_pRenderer->EndCommand(c_nPageType); } - void RendererOutputDev::saveState(GfxState *pGState) + void RendererOutputDev::saveState(GfxState* pGState) { - m_sClip.push_back(GfxClip()); - m_bClipChanged = true; + m_sStates.push_back(GfxOutputState()); + m_sStates.back().pGState = pGState; + if (m_pSoftMask) + { + m_pSoftMask->AddRef(); + m_sStates.back().pSoftMask = m_pSoftMask; + } + + // Выходит дольше из-за копирования Clip, Pen, Brush, + // но не имеет смысла, т.к. Restore всё равно перенакладывает все Clip с нуля + //if (c_nGrRenderer == m_lRendererType) + //{ + // NSGraphics::IGraphicsRenderer* GRenderer = dynamic_cast(m_pRenderer); + // GRenderer->Save(); + //} + //else updateAll(pGState); } - void RendererOutputDev::restoreState(GfxState *pGState) + void RendererOutputDev::restoreState(GfxState* pGState) { - if (!m_sClip.empty()) - m_sClip.pop_back(); - m_bClipChanged = true; + RELEASEINTERFACE(m_pSoftMask); + m_pSoftMask = m_sStates.back().pSoftMask; + if (c_nGrRenderer == m_lRendererType) + { + if (NSGraphics::IGraphicsRenderer* GRenderer = dynamic_cast(m_pRenderer)) + GRenderer->SetSoftMask(m_pSoftMask); + } + + bool bClipChanged = m_sStates.back().pClip || m_sStates.back().pTextClip; + m_sStates.pop_back(); + updateAll(pGState); + if (bClipChanged) + UpdateAllClip(pGState); } - void RendererOutputDev::updateCTM(GfxState *pGState, double dMatrix11, double dMatrix12, double dMatrix21, double dMatrix22, double dMatrix31, double dMatrix32) + void RendererOutputDev::updateCTM(GfxState* pGState, double dMatrix11, double dMatrix12, double dMatrix21, double dMatrix22, double dMatrix31, double dMatrix32) { } - void RendererOutputDev::updateLineDash(GfxState *pGState) + void RendererOutputDev::updateLineDash(GfxState* pGState) { - double *pDash = NULL; + double* pDash = NULL; int nSize = 0; double dStart = 0; pGState->getLineDash(&pDash, &nSize, &dStart); @@ -697,22 +514,22 @@ namespace PdfReader } else { + double* dDash = new double[nSize]; for (int nIndex = 0; nIndex < nSize; ++nIndex) - { - pDash[nIndex] = PDFCoordsToMM(pDash[nIndex]); - } + dDash[nIndex] = PDFCoordsToMM(pDash[nIndex]); - m_pRenderer->PenDashPattern(pDash, (long)nSize); + m_pRenderer->PenDashPattern(dDash, (long)nSize); m_pRenderer->put_PenDashStyle(Aggplus::DashStyleCustom); m_pRenderer->put_PenDashOffset(PDFCoordsToMM(dStart)); + RELEASEARRAYOBJECTS(dDash); } if (bOffCopy) delete[] pDash; } - void RendererOutputDev::updateFlatness(GfxState *pGState) + void RendererOutputDev::updateFlatness(GfxState* pGState) { } - void RendererOutputDev::updateLineJoin(GfxState *pGState) + void RendererOutputDev::updateLineJoin(GfxState* pGState) { int nJoinStyle = pGState->getLineJoin(); if (1 == nJoinStyle) @@ -722,7 +539,7 @@ namespace PdfReader m_pRenderer->put_PenLineJoin(nJoinStyle); } - void RendererOutputDev::updateLineCap(GfxState *pGState) + void RendererOutputDev::updateLineCap(GfxState* pGState) { int nCapStyle = pGState->getLineCap(); if (1 == nCapStyle) @@ -733,21 +550,21 @@ namespace PdfReader m_pRenderer->put_PenLineStartCap(nCapStyle); m_pRenderer->put_PenLineEndCap(nCapStyle); } - void RendererOutputDev::updateMiterLimit(GfxState *pGState) + void RendererOutputDev::updateMiterLimit(GfxState* pGState) { m_pRenderer->put_PenMiterLimit(PDFCoordsToMM(pGState->getMiterLimit())); } - void RendererOutputDev::updateLineWidth(GfxState *pGState) + void RendererOutputDev::updateLineWidth(GfxState* pGState) { m_pRenderer->put_PenSize(PDFCoordsToMM(pGState->getLineWidth())); } - void RendererOutputDev::updateStrokeAdjust(GfxState *pGState) + void RendererOutputDev::updateStrokeAdjust(GfxState* pGState) { } - void RendererOutputDev::updateFillColor(GfxState *pGState) + void RendererOutputDev::updateFillColor(GfxState* pGState) { - GfxColor *pColor = pGState->getFillColor(); - GfxColorSpace *pColorSpace = pGState->getFillColorSpace(); + GfxColor* pColor = pGState->getFillColor(); + GfxColorSpace* pColorSpace = pGState->getFillColorSpace(); GfxRGB c; @@ -756,10 +573,10 @@ namespace PdfReader m_pRenderer->put_BrushColor1(dwColor); m_pRenderer->put_BrushColor2(dwColor); } - void RendererOutputDev::updateStrokeColor(GfxState *pGState) + void RendererOutputDev::updateStrokeColor(GfxState* pGState) { - GfxColor *pColor = pGState->getStrokeColor(); - GfxColorSpace *pColorSpace = pGState->getStrokeColorSpace(); + GfxColor* pColor = pGState->getStrokeColor(); + GfxColorSpace* pColorSpace = pGState->getStrokeColorSpace(); GfxRGB c; @@ -768,60 +585,59 @@ namespace PdfReader m_pRenderer->put_PenColor(dwColor); } - void RendererOutputDev::updateBlendMode(GfxState *pGState) + void RendererOutputDev::updateBlendMode(GfxState* pGState) { - NSGraphics::IGraphicsRenderer* GRenderer = dynamic_cast(m_pRenderer); - if (((GlobalParamsAdaptor*)globalParams)->getDrawFormField() || !GRenderer) + if (((GlobalParamsAdaptor*)globalParams)->getDrawFormField()) return; switch (pGState->getBlendMode()) { case gfxBlendNormal: - GRenderer->put_BlendMode(3); + m_pRenderer->put_BlendMode(3); // agg::comp_op_src_over break; case gfxBlendMultiply: - GRenderer->put_BlendMode(14); + m_pRenderer->put_BlendMode(14); // agg::comp_op_multiply break; case gfxBlendScreen: - GRenderer->put_BlendMode(15); + m_pRenderer->put_BlendMode(15); // agg::comp_op_screen break; case gfxBlendOverlay: - GRenderer->put_BlendMode(16); + m_pRenderer->put_BlendMode(16); // agg::comp_op_overlay break; case gfxBlendDarken: - GRenderer->put_BlendMode(17); + m_pRenderer->put_BlendMode(17); // agg::comp_op_darken break; case gfxBlendLighten: - GRenderer->put_BlendMode(18); + m_pRenderer->put_BlendMode(18); // agg::comp_op_lighten break; case gfxBlendColorDodge: - GRenderer->put_BlendMode(19); + m_pRenderer->put_BlendMode(19); // agg::comp_op_color_dodge break; case gfxBlendColorBurn: - GRenderer->put_BlendMode(20); + m_pRenderer->put_BlendMode(20); // agg::comp_op_color_burn break; case gfxBlendHardLight: - GRenderer->put_BlendMode(21); + m_pRenderer->put_BlendMode(21); // agg::comp_op_hard_light break; case gfxBlendSoftLight: - GRenderer->put_BlendMode(22); + m_pRenderer->put_BlendMode(22); // agg::comp_op_soft_light break; case gfxBlendDifference: - GRenderer->put_BlendMode(23); + m_pRenderer->put_BlendMode(23); // agg::comp_op_difference break; case gfxBlendExclusion: - GRenderer->put_BlendMode(24); + m_pRenderer->put_BlendMode(24); // agg::comp_op_exclusion break; case gfxBlendHue: @@ -829,23 +645,22 @@ namespace PdfReader case gfxBlendColor: case gfxBlendLuminosity: default: - GRenderer->put_BlendMode(3); + m_pRenderer->put_BlendMode(3); // agg::comp_op_src_over break; } } - void RendererOutputDev::updateFillOpacity(GfxState *pGState) + void RendererOutputDev::updateFillOpacity(GfxState* pGState) { m_pRenderer->put_BrushAlpha1(std::min(255, std::max(0, int(pGState->getFillOpacity() * 255)))); m_pRenderer->put_BrushAlpha2(std::min(255, std::max(0, int(pGState->getFillOpacity() * 255)))); } - void RendererOutputDev::updateStrokeOpacity(GfxState *pGState) + void RendererOutputDev::updateStrokeOpacity(GfxState* pGState) { m_pRenderer->put_PenAlpha(std::min(255, std::max(0, int(pGState->getStrokeOpacity() * 255)))); } - void RendererOutputDev::updateAll(GfxState *pGState) + void RendererOutputDev::updateAll(GfxState* pGState) { - updateCTM(pGState, pGState->getCTM()[0], pGState->getCTM()[1], pGState->getCTM()[2], pGState->getCTM()[3], pGState->getCTM()[4], pGState->getCTM()[5]); updateLineDash(pGState); updateFlatness(pGState); updateLineJoin(pGState); @@ -861,34 +676,119 @@ namespace PdfReader updateFillOpacity(pGState); updateStrokeOpacity(pGState); updateFont(pGState); - updateClip(pGState); } - void RendererOutputDev::updateRender(GfxState *pGState) + void RendererOutputDev::updateRender(GfxState* pGState) { } - void RendererOutputDev::updateFont(GfxState *pGState) + NSFonts::CFontInfo* RendererOutputDev::GetFontByParams(XRef* pXref, NSFonts::IFontManager* pFontManager, GfxFont* pFont, std::wstring& wsFontBaseName) { + NSFonts::CFontInfo* pFontInfo = NULL; + if (!pFontManager) + return pFontInfo; + Ref* pRef = pFont->getID(); + Object oRefObject, oFontObject; + oRefObject.initRef(pRef->num, pRef->gen); + oRefObject.fetch(pXref, &oFontObject); + oRefObject.free(); - // Проверяем наличие списка со шрифтами - if (NULL == m_pFontList) - return; + NSFonts::CFontSelectFormat oFontSelect; + CheckFontNamePDF(wsFontBaseName, &oFontSelect); + if (oFontObject.isDict()) + { + Dict* pFontDict = oFontObject.getDict(); + Object oFontDescriptor; + if (pFontDict->lookup("FontDescriptor", &oFontDescriptor)->isDict()) + { + Object oDictItem; + oFontDescriptor.dictLookup("FontName", &oDictItem); + if (oDictItem.isName()) + oFontSelect.wsName = AStringToPWString(oDictItem.getName()); + else + oFontSelect.wsName = new std::wstring(wsFontBaseName); + oDictItem.free(); - GfxFont *pFont = pGState->getFont(); - if (NULL == pFont) - return; + oFontDescriptor.dictLookup("FontFamily", &oDictItem); + oDictItem.free(); - m_pRenderer->put_FontSize(pGState->getFontSize()); - //m_oFont.Size = pGState->getFontSize(); + oFontDescriptor.dictLookup("FontStretch", &oDictItem); + oDictItem.free(); + oFontDescriptor.dictLookup("FontWeight", &oDictItem); + oDictItem.free(); + oFontDescriptor.dictLookup("FontBBox", &oDictItem); + oDictItem.free(); - std::wstring wsFileName = L""; - std::wstring wsFontName = L""; - TFontEntry *pEntry = NULL; + oFontDescriptor.dictLookup("ItalicAngle", &oDictItem); + if (oDictItem.isInt() && 0 != oDictItem.getInt()) + { + if (oFontSelect.bItalic) RELEASEOBJECT(oFontSelect.bItalic); + oFontSelect.bItalic = new INT(1); + } + oDictItem.free(); + + oFontDescriptor.dictLookup("Ascent", &oDictItem); + if (oDictItem.isInt()) oFontSelect.shAscent = new SHORT(oDictItem.getInt()); + oDictItem.free(); + + oFontDescriptor.dictLookup("Leading", &oDictItem); + if (oDictItem.isInt()) oFontSelect.shLineGap = new SHORT(oDictItem.getInt()); + oDictItem.free(); + + oFontDescriptor.dictLookup("CapHeight", &oDictItem); + if (oDictItem.isInt()) oFontSelect.shCapHeight = new SHORT(oDictItem.getInt()); + oDictItem.free(); + + oFontDescriptor.dictLookup("XHeight", &oDictItem); + if (oDictItem.isInt()) oFontSelect.shXHeight = new SHORT(oDictItem.getInt()); + oDictItem.free(); + + oFontDescriptor.dictLookup("StemV", &oDictItem); + if (oDictItem.isNum()) + { + double dStemV = oDictItem.getNum(); + if (dStemV > 50.5) + oFontSelect.usWeight = new USHORT(sqrt(oDictItem.getNum() - 50.5) * 65); + } + oDictItem.free(); + + oFontDescriptor.dictLookup("StemH", &oDictItem); + oDictItem.free(); + + oFontDescriptor.dictLookup("Descent", &oDictItem); + if (oDictItem.isInt()) oFontSelect.shDescent = new SHORT(oDictItem.getInt()); + oDictItem.free(); + + oFontDescriptor.dictLookup("AvgWidth", &oDictItem); + if (oDictItem.isInt()) oFontSelect.shAvgCharWidth = new SHORT(oDictItem.getInt()); + oDictItem.free(); + + oFontDescriptor.dictLookup("MaxWidth", &oDictItem); + oDictItem.free(); + + oFontDescriptor.dictLookup("MissingWidth", &oDictItem); + oDictItem.free(); + + } + else + oFontSelect.wsName = new std::wstring(wsFontBaseName); + oFontDescriptor.free(); + } + else + oFontSelect.wsName = new std::wstring(wsFontBaseName); + + pFontInfo = pFontManager->GetFontInfoByParams(oFontSelect); + return pFontInfo; + } + void RendererOutputDev::GetFont(XRef* pXref, NSFonts::IFontManager* pFontManager, CPdfFontList* pFontList, GfxFont* pFont, std::wstring& wsFileName, std::wstring& wsFontName) + { + wsFileName = L""; + wsFontName = L""; + TFontEntry* pEntry = NULL; // MEMERR string dealocation pEntry - if (!m_pFontList->Find2((*pFont->getID()), &pEntry)) + if (!pFontList->Find2((*pFont->getID()), &pEntry)) { GfxFontType eFontType = pFont->getType(); if (fontType3 == eFontType) // FontType3 обрабатывается отдельной командой @@ -903,7 +803,7 @@ namespace PdfReader std::wstring wsFontBaseName = NSStrings::GetStringFromUTF32(pFont->getName()); if (wsFontBaseName.empty()) wsFontBaseName = L"Helvetica"; - const unsigned char* pData14 = NULL; + const BYTE* pData14 = NULL; unsigned int nSize14 = 0; #ifdef FONTS_USE_ONLY_MEMORY_STREAMS CMemoryFontStream oMemoryFontStream; @@ -937,7 +837,7 @@ namespace PdfReader #else FILE* pTempFile = NULL; if (!NSFile::CFileBinary::OpenTempFile(&wsTempFileName, &pTempFile, L"wb", (wchar_t*)wsExt.c_str(), - (wchar_t*)((GlobalParamsAdaptor *)globalParams)->GetTempFolder().c_str(), NULL)) + (wchar_t*)((GlobalParamsAdaptor*)globalParams)->GetTempFolder().c_str(), NULL)) { if (L"" != wsTempFileName) NSFile::CFileBinary::Remove(wsTempFileName); @@ -950,14 +850,14 @@ namespace PdfReader Object oReferenceObject, oStreamObject; oReferenceObject.initRef(oEmbRef.num, oEmbRef.gen); - oReferenceObject.fetch(m_pXref, &oStreamObject); + oReferenceObject.fetch(pXref, &oStreamObject); oReferenceObject.free(); if (!oStreamObject.isStream()) { // Внедренный шрифт неправильно записан oStreamObject.free(); -#ifndef BUILDING_WASM_MODULE +#ifndef FONTS_USE_ONLY_MEMORY_STREAMS fclose(pTempFile); if (L"" != wsTempFileName) @@ -996,113 +896,75 @@ namespace PdfReader FILE* pFile = NSFile::CFileBinary::OpenFileNative(wsAfmPath, L"wb"); if (pFile) { - Ref *pRef = pFont->getID(); + Ref* pRef = pFont->getID(); Object oRefObject, oFontObject; oRefObject.initRef(pRef->num, pRef->gen); - oRefObject.fetch(m_pXref, &oFontObject); + oRefObject.fetch(pXref, &oFontObject); oRefObject.free(); if (oFontObject.isDict()) { - char *sFontName = NULL, *sFontFamily = NULL, *sFontStretch = NULL; - int nFontWeight = 0, nItalicAngle = 0, nAscent = 0, nDescent = 0, nLeading = 0; - int nCapHeight = 0, nXHeight = 0, nStemV = 0, nStemH = 0, nAvgWidth = 0, nMaxWidth = 0, nMissingWidth = 0; - Array *pBBox = NULL; - int arrBBox[4] ={ 0, 0, 0, 0 }; + std::string sFontName, sFontFamily; + int nFontWeight = 0, nItalicAngle = 0, nAscent = 0, nDescent = 0; + int nCapHeight = 0, nXHeight = 0, nStemV = 0, nStemH = 0, nMissingWidth = 0; + int arrBBox[4] = { 0, 0, 0, 0 }; - Dict *pFontDict = oFontObject.getDict(); Object oFontDescriptor; - if (pFontDict->lookup("FontDescriptor", &oFontDescriptor)->isDict()) + if (oFontObject.dictLookup("FontDescriptor", &oFontDescriptor)->isDict()) { Object oDictItem; - // FontName oFontDescriptor.dictLookup("FontName", &oDictItem); if (oDictItem.isName()) sFontName = oDictItem.getName(); oDictItem.free(); - // FontFamily oFontDescriptor.dictLookup("FontFamily", &oDictItem); if (oDictItem.isName()) sFontFamily = oDictItem.getName(); oDictItem.free(); - // FontStretch - oFontDescriptor.dictLookup("FontStretch", &oDictItem); - if (oDictItem.isName()) sFontStretch = oDictItem.getName(); - oDictItem.free(); - - // FontWeight oFontDescriptor.dictLookup("FontWeight", &oDictItem); if (oDictItem.isInt()) nFontWeight = oDictItem.getInt(); oDictItem.free(); - // FontBBox - oFontDescriptor.dictLookup("FontBBox", &oDictItem); - if (oDictItem.isArray()) pBBox = oDictItem.getArray(); - if (4 == pBBox->getLength()) + if (oFontDescriptor.dictLookup("FontBBox", &oDictItem)->isArray() && oDictItem.arrayGetLength() == 4) { for (int nIndex = 0; nIndex < 4; nIndex++) { Object oArrayItem; - pBBox->get(nIndex, &oArrayItem); - if (oArrayItem.isInt()) + if (oDictItem.arrayGet(nIndex, &oArrayItem)->isInt()) arrBBox[nIndex] = oArrayItem.getInt(); - oArrayItem.free(); } } oDictItem.free(); - // ItalicAngle oFontDescriptor.dictLookup("ItalicAngle", &oDictItem); if (oDictItem.isInt()) nItalicAngle = oDictItem.getInt(); oDictItem.free(); - // Ascent oFontDescriptor.dictLookup("Ascent", &oDictItem); if (oDictItem.isInt()) nAscent = oDictItem.getInt(); oDictItem.free(); - // Leading - oFontDescriptor.dictLookup("Leading", &oDictItem); - if (oDictItem.isInt()) nLeading = oDictItem.getInt(); - oDictItem.free(); - - // CapHeight oFontDescriptor.dictLookup("CapHeight", &oDictItem); if (oDictItem.isInt()) nCapHeight = oDictItem.getInt(); oDictItem.free(); - // XHeight oFontDescriptor.dictLookup("XHeight", &oDictItem); if (oDictItem.isInt()) nXHeight = oDictItem.getInt(); oDictItem.free(); - // StemV oFontDescriptor.dictLookup("StemV", &oDictItem); if (oDictItem.isInt()) nStemV = oDictItem.getInt(); oDictItem.free(); - // StemH oFontDescriptor.dictLookup("StemH", &oDictItem); if (oDictItem.isInt()) nStemH = oDictItem.getInt(); oDictItem.free(); - // Descent oFontDescriptor.dictLookup("Descent", &oDictItem); if (oDictItem.isInt()) nDescent = oDictItem.getInt(); oDictItem.free(); - // AvgWidth - oFontDescriptor.dictLookup("AvgWidth", &oDictItem); - if (oDictItem.isInt()) nAvgWidth = oDictItem.getInt(); - oDictItem.free(); - - // MaxWidth - oFontDescriptor.dictLookup("MaxWidth", &oDictItem); - if (oDictItem.isInt()) nMaxWidth = oDictItem.getInt(); - oDictItem.free(); - - // MissingWidth oFontDescriptor.dictLookup("MissingWidth", &oDictItem); if (oDictItem.isInt()) nMissingWidth = oDictItem.getInt(); oDictItem.free(); @@ -1111,8 +973,8 @@ namespace PdfReader oFontDescriptor.free(); fprintf(pFile, "StartFontMetrics 3.0\n"); - if (NULL != sFontName) fprintf(pFile, "FontName %s\n", sFontName); - if (NULL != sFontFamily) fprintf(pFile, "FamilyName %s\n", sFontFamily); + if (!sFontName.empty()) fprintf(pFile, "FontName %s\n", sFontName.c_str()); + if (!sFontFamily.empty()) fprintf(pFile, "FamilyName %s\n", sFontFamily.c_str()); if (nFontWeight >= 550) fprintf(pFile, "Weight Bold\n"); fprintf(pFile, "ItalicAngle %d\n", nItalicAngle); @@ -1128,38 +990,24 @@ namespace PdfReader int nFirstChar = 0; Object oDictItem; - pFontDict->lookup("FirstChar", &oDictItem); - if (oDictItem.isInt()) nFirstChar = oDictItem.getInt(); + if (oFontObject.dictLookup("FirstChar", &oDictItem)->isInt()) nFirstChar = oDictItem.getInt(); oDictItem.free(); - int nLastChar = nFirstChar; - pFontDict->lookup("LastChar", &oDictItem); - if (oDictItem.isInt()) nLastChar = oDictItem.getInt(); - oDictItem.free(); - - Array *pWidths = NULL; - pFontDict->lookup("Widths", &oDictItem); - if (oDictItem.isArray()) pWidths = oDictItem.getArray(); - - int nCount = nLastChar - nFirstChar + 1; - Gfx8BitFont *pT1Font = (Gfx8BitFont *)pFont; - - if (NULL != pWidths) + Gfx8BitFont* pT1Font = (Gfx8BitFont*)pFont; + if (oFontObject.dictLookup("Widths", &oDictItem)->isArray()) { - int nWidthsCount = pWidths->getLength(); + int nWidthsCount = oDictItem.arrayGetLength(); fprintf(pFile, "StartCharMetrics %d\n", nWidthsCount); for (int nIndex = 0; nIndex < nWidthsCount; nIndex++) { int nWidth = nMissingWidth; Object oArrayItem; - pWidths->get(nIndex, &oArrayItem); - if (oArrayItem.isInt()) nWidth = oArrayItem.getInt(); + if (oDictItem.arrayGet(nIndex, &oArrayItem)->isInt()) nWidth = oArrayItem.getInt(); oArrayItem.free(); - char **ppEncoding = pT1Font->getEncoding(); + char** ppEncoding = pT1Font->getEncoding(); - - if (NULL != ppEncoding && NULL != ppEncoding[nIndex]) + if (ppEncoding && ppEncoding[nIndex]) fprintf(pFile, "C %d ; WX %d ; N %s ;\n", nIndex + nFirstChar, nWidth, ppEncoding[nIndex]); else fprintf(pFile, "C %d ; WX %d ;\n", nIndex + nFirstChar, nWidth); @@ -1168,19 +1016,20 @@ namespace PdfReader } oDictItem.free(); } + oFontObject.free(); } fclose(pFile); } #endif // Загрузим сам файл со шрифтом, чтобы точно определить его тип - if (!m_pFontManager->LoadFontFromFile(wsFileName, 0, 10, 72, 72)) + if (!pFontManager->LoadFontFromFile(wsFileName, 0, 10, 72, 72)) { pEntry->bAvailable = true; return; } - std::wstring wsFontType = m_pFontManager->GetFontType(); + std::wstring wsFontType = pFontManager->GetFontType(); if (L"TrueType" == wsFontType) { if (eFontType != fontType1COT && eFontType != fontTrueType @@ -1247,134 +1096,24 @@ namespace PdfReader #else else if ([&oMemoryFontStream, wsFontBaseName]() { - const unsigned char* pData14 = NULL; - unsigned int nSize14 = 0; - if (PdfReader::GetBaseFont(wsFontBaseName, pData14, nSize14)) - { - oMemoryFontStream.fromBuffer((BYTE*)pData14, nSize14); - return true; - } - return false; - }()) + const BYTE* pData14 = NULL; + unsigned int nSize14 = 0; + if (PdfReader::GetBaseFont(wsFontBaseName, pData14, nSize14)) + { + oMemoryFontStream.fromBuffer((BYTE*)pData14, nSize14); + return true; + } + return false; + }()) { wsFileName = wsFontBaseName; NSFonts::NSApplicationFontStream::GetGlobalMemoryStorage()->Add(wsFileName, oMemoryFontStream.m_pData, (LONG)oMemoryFontStream.m_nSize, true); } #endif - else if (!pFont->locateFont(m_pXref, false) || - (wsFileName = NSStrings::GetStringFromUTF32(pFont->locateFont(m_pXref, false)->path)).length() == 0) - //else if (0) + else if (!pFont->locateFont(pXref, false) || + (wsFileName = NSStrings::GetStringFromUTF32(pFont->locateFont(pXref, false)->path)).length() == 0) { - // TODO: Сначала тут мы должны проверить, если ищется один из 14 стандартных шрифтов, - // тогда мы должны вернуть путь к стандартному шрифту. - - NSFonts::CFontInfo* pFontInfo = NULL; - if (m_pFontManager) - { - Ref *pRef = pFont->getID(); - Object oRefObject, oFontObject; - oRefObject.initRef(pRef->num, pRef->gen); - oRefObject.fetch(m_pXref, &oFontObject); - oRefObject.free(); - - NSFonts::CFontSelectFormat oFontSelect; - NSCorrectFontName::CheckFontNamePDF(wsFontBaseName, oFontSelect); - if (oFontObject.isDict()) - { - Dict *pFontDict = oFontObject.getDict(); - Object oFontDescriptor; - if (pFontDict->lookup("FontDescriptor", &oFontDescriptor)->isDict()) - { - Object oDictItem; - // FontName - oFontDescriptor.dictLookup("FontName", &oDictItem); - if (oDictItem.isName()) - oFontSelect.wsName = AStringToPWString(oDictItem.getName()); - else - oFontSelect.wsName = new std::wstring(wsFontBaseName); - oDictItem.free(); - - // FontFamily - oFontDescriptor.dictLookup("FontFamily", &oDictItem); - oDictItem.free(); - - // FontStretch - oFontDescriptor.dictLookup("FontStretch", &oDictItem); - oDictItem.free(); - - // FontWeight - oFontDescriptor.dictLookup("FontWeight", &oDictItem); - oDictItem.free(); - - // FontBBox - oFontDescriptor.dictLookup("FontBBox", &oDictItem); - oDictItem.free(); - - // ItalicAngle - oFontDescriptor.dictLookup("ItalicAngle", &oDictItem); - if (oDictItem.isInt() && 0 != oDictItem.getInt()) - { - if (oFontSelect.bItalic) RELEASEOBJECT(oFontSelect.bItalic); - oFontSelect.bItalic = new INT(1); - } - oDictItem.free(); - - // Ascent - oFontDescriptor.dictLookup("Ascent", &oDictItem); - if (oDictItem.isInt()) oFontSelect.shAscent = new SHORT(oDictItem.getInt()); - oDictItem.free(); - - // Leading - oFontDescriptor.dictLookup("Leading", &oDictItem); - if (oDictItem.isInt()) oFontSelect.shLineGap = new SHORT(oDictItem.getInt()); - oDictItem.free(); - - // CapHeight - oFontDescriptor.dictLookup("CapHeight", &oDictItem); - if (oDictItem.isInt()) oFontSelect.shCapHeight = new SHORT(oDictItem.getInt()); - oDictItem.free(); - - // XHeight - oFontDescriptor.dictLookup("XHeight", &oDictItem); - if (oDictItem.isInt()) oFontSelect.shXHeight = new SHORT(oDictItem.getInt()); - oDictItem.free(); - - // StemV - oFontDescriptor.dictLookup("StemV", &oDictItem); - oDictItem.free(); - - // StemH - oFontDescriptor.dictLookup("StemH", &oDictItem); - oDictItem.free(); - - // Descent - oFontDescriptor.dictLookup("Descent", &oDictItem); - if (oDictItem.isInt()) oFontSelect.shDescent = new SHORT(oDictItem.getInt()); - oDictItem.free(); - - // AvgWidth - oFontDescriptor.dictLookup("AvgWidth", &oDictItem); - if (oDictItem.isInt()) oFontSelect.shAvgCharWidth = new SHORT(oDictItem.getInt()); - oDictItem.free(); - - // MaxWidth - oFontDescriptor.dictLookup("MaxWidth", &oDictItem); - oDictItem.free(); - - // MissingWidth - oFontDescriptor.dictLookup("MissingWidth", &oDictItem); - oDictItem.free(); - - } - else - oFontSelect.wsName = new std::wstring(wsFontBaseName); - oFontDescriptor.free(); - } - else - oFontSelect.wsName = new std::wstring(wsFontBaseName); - - pFontInfo = m_pFontManager->GetFontInfoByParams(oFontSelect); - } + NSFonts::CFontInfo* pFontInfo = GetFontByParams(pXref, pFontManager, pFont, wsFontBaseName); if (pFontInfo && L"" != pFontInfo->m_wsFontPath) { @@ -1390,7 +1129,7 @@ namespace PdfReader wsFileName = NSWasm::LoadFont(wsFileName, pFontInfo->m_bBold, pFontInfo->m_bItalic); if (wsFileName.empty()) { - m_pFontList->Remove(*pFont->getID()); + pFontList->Remove(*pFont->getID()); return; } } @@ -1404,161 +1143,12 @@ namespace PdfReader pEntry->bAvailable = true; return; } - - // Записываем файл с кодировкой. (Специально для перезаписи в PDF) - if (c_nPDFWriter == m_lRendererType) - { - std::wstring wsExt; - if (!pFont->isCIDFont()) - { - wsExt = L".non"; - } - else if (pFont->isCIDFont()) - { - wsExt = L".cid_non"; - } - - FILE* pTempFile = NULL; - if (!NSFile::CFileBinary::OpenTempFile(&wsTempFileName, &pTempFile, L"wb", (wchar_t*)wsExt.c_str(), - (wchar_t*)((GlobalParamsAdaptor*)globalParams)->GetTempFolder().c_str(), NULL)) - { - if (L"" != wsTempFileName) - NSFile::CFileBinary::Remove(wsTempFileName); - - pEntry->bAvailable = true; - return; - } - fclose(pTempFile); - - // Копируем файл, для создания уникального имени, чтобы связать с файлом с кодировкой - if (NSFile::CFileBinary::Copy(wsFileName, wsTempFileName)) - { - wsFileName = wsTempFileName; - } - else - { - NSFile::CFileBinary::Remove(wsTempFileName); - wsTempFileName = L""; - } - - if (L"" != wsTempFileName) - { - std::wstring wsSplitFileName, wsSplitFileExt; - SpitPathExt(wsFileName, &wsSplitFileName, &wsSplitFileExt); - std::wstring wsEncodingPath = wsSplitFileName + L".enc"; - - CXmlWriter oXmlWriter; - - Ref *pRef = pFont->getID(); - Object oRefObject, oFontObject; - oRefObject.initRef(pRef->num, pRef->gen); - oRefObject.fetch(m_pXref, &oFontObject); - oRefObject.free(); - - if (oFontObject.isDict()) - { - Dict *pFontDict = oFontObject.getDict(); - - int nEncodingType = -1; // Объекта Encoding нет - int nBaseEncoding = -1; - - Object oDictItem; - pFontDict->lookup("Encoding", &oDictItem); - if (oDictItem.isDict()) - { - nEncodingType = 1; // Encoding - идет отдельным объектом - - Object oTemp; - oDictItem.dictLookup("BaseEncoding", &oTemp); - - if (oTemp.isName("MacRomanEncoding")) - nBaseEncoding = 0; - else if (oTemp.isName("MacExpertEncoding")) - nBaseEncoding = 1; - else if (oTemp.isName("WinAnsiEncoding")) - nBaseEncoding = 2; - - oTemp.free(); - } - else if (oDictItem.isName("MacRomanEncoding")) - { - nEncodingType = 0; - nBaseEncoding = 0; - } - else if (oDictItem.isName("MacExpertEncoding")) - { - nEncodingType = 0; - nBaseEncoding = 1; - } - else if (oDictItem.isName("WinAnsiEncoding")) - { - nEncodingType = 0; - nBaseEncoding = 2; - } - else - { - nEncodingType = -1; - } - - oXmlWriter.WriteNodeBegin(L"Encoding", true); - oXmlWriter.WriteAttribute(L"type", nEncodingType); - oXmlWriter.WriteAttribute(L"base", nBaseEncoding); - oXmlWriter.WriteNodeEnd(L"Encoding", true, false); - - // Differences - if (oDictItem.isDict()) - { - Object oDifferences; - oDictItem.dictLookup("Differences", &oDifferences); - if (oDifferences.isArray()) - { - int nArrayLen = oDifferences.arrayGetLength(); - oXmlWriter.WriteNodeBegin(L"Differences", true); - oXmlWriter.WriteAttribute(L"count", nArrayLen); - oXmlWriter.WriteNodeEnd(L"Differences", true, false); - - for (int nIndex = 0; nIndex < nArrayLen; ++nIndex) - { - Object oTemp; - oDifferences.arrayGet(nIndex, &oTemp); - if (oTemp.isInt()) - { - int nCode = oTemp.getInt(); - oXmlWriter.WriteNodeBegin(L"Code", true); - oXmlWriter.WriteAttribute(L"value", nCode); - oXmlWriter.WriteNodeEnd(L"Code", true, true); - } - else if (oTemp.isName()) - { - char *sName = oTemp.getName(); - oXmlWriter.WriteNodeBegin(L"Name", true); - oXmlWriter.WriteAttribute(L"value", AStringToWString(sName)); - oXmlWriter.WriteNodeEnd(L"Name", true, true); - } - else - { - // TODO: Неправильный тип записи - } - oTemp.free(); - } - - oXmlWriter.WriteNodeEnd(L"Differences"); - } - oDifferences.free(); - } - oDictItem.free(); - oXmlWriter.WriteNodeEnd(L"Encoding"); - } - oFontObject.free(); - oXmlWriter.SaveToFile(wsEncodingPath); - } - } } // Здесь мы грузим кодировки - int *pCodeToGID = NULL, *pCodeToUnicode = NULL; + int* pCodeToGID = NULL, *pCodeToUnicode = NULL; int nLen = 0; - FoFiTrueType *pTTFontFile = NULL; - FoFiType1C *pT1CFontFile = NULL; + FoFiTrueType* pTTFontFile = NULL; + FoFiType1C* pT1CFontFile = NULL; #ifdef FONTS_USE_ONLY_MEMORY_STREAMS FoFiIdentifierType fofiType = FoFiIdentifier::identifyStream(&readFromMemoryStream, &oMemoryFontStream); oMemoryFontStream.toStart(); @@ -1583,7 +1173,7 @@ namespace PdfReader if (pTTFontFile) { - pCodeToGID = ((Gfx8BitFont *)pFont)->getCodeToGIDMap(pTTFontFile); + pCodeToGID = ((Gfx8BitFont*)pFont)->getCodeToGIDMap(pTTFontFile); nLen = 256; delete pTTFontFile; @@ -1595,17 +1185,17 @@ namespace PdfReader nLen = 0; } } - else if (L"" != wsFileName && (pFont8bit = dynamic_cast(pFont)) && pFont8bit->getHasEncoding()) + else if (L"" != wsFileName && (pFont8bit = dynamic_cast(pFont))) { - char **ppEncoding = pFont8bit->getEncoding(); + char** ppEncoding = pFont8bit->getEncoding(); if (!ppEncoding) break; - if (!m_pFontManager) + if (!pFontManager) break; - m_pFontManager->LoadFontFromFile(wsFileName, 0, 1, 72, 72); - pCodeToGID = (int *)MemUtilsMallocArray(256, sizeof(int)); + pFontManager->LoadFontFromFile(wsFileName, 0, 1, 72, 72); + pCodeToGID = (int*)MemUtilsMallocArray(256, sizeof(int)); if (!pCodeToGID) break; @@ -1616,7 +1206,7 @@ namespace PdfReader char* sName = NULL; if ((sName = ppEncoding[nIndex])) { - unsigned short ushGID = m_pFontManager->GetNameIndex(AStringToWString(sName)); + unsigned short ushGID = pFontManager->GetNameIndex(AStringToWString(sName)); pCodeToGID[nIndex] = ushGID; } } @@ -1631,15 +1221,15 @@ namespace PdfReader Gfx8BitFont* pFont8bit = dynamic_cast(pFont); if (L"" != wsFileName && pFont8bit && pFont8bit->getHasEncoding()) { - char **ppEncoding = pFont8bit->getEncoding(); + char** ppEncoding = pFont8bit->getEncoding(); if (!ppEncoding) break; - if (!m_pFontManager) + if (!pFontManager) break; - m_pFontManager->LoadFontFromFile(wsFileName, 0, 1, 72, 72); - pCodeToGID = (int *)MemUtilsMallocArray(256, sizeof(int)); + pFontManager->LoadFontFromFile(wsFileName, 0, 1, 72, 72); + pCodeToGID = (int*)MemUtilsMallocArray(256, sizeof(int)); if (!pCodeToGID) break; @@ -1650,7 +1240,7 @@ namespace PdfReader char* sName = NULL; if ((sName = ppEncoding[nIndex])) { - unsigned short ushGID = m_pFontManager->GetNameIndex(AStringToWString(sName)); + unsigned short ushGID = pFontManager->GetNameIndex(AStringToWString(sName)); pCodeToGID[nIndex] = ushGID; } } @@ -1665,7 +1255,7 @@ namespace PdfReader #endif if (pTTFontFile) { - pCodeToGID = ((Gfx8BitFont *)pFont)->getCodeToGIDMap(pTTFontFile); + pCodeToGID = ((Gfx8BitFont*)pFont)->getCodeToGIDMap(pTTFontFile); nLen = 256; delete pTTFontFile; @@ -1676,14 +1266,14 @@ namespace PdfReader pCodeToGID = NULL; nLen = 0; - if (m_pFontManager->LoadFontFromFile(wsFileName, 0, 10, 72, 72)) + if (pFontManager->LoadFontFromFile(wsFileName, 0, 10, 72, 72)) { INT* pCodes = NULL; nLen = 256; pCodeToGID = (int*)MemUtilsMallocArray(nLen, sizeof(int)); for (int nCode = 0; nCode < nLen; ++nCode) { - pCodeToGID[nCode] = m_pFontManager->GetGIDByUnicode(nCode); + pCodeToGID[nCode] = pFontManager->GetGIDByUnicode(nCode); } } } @@ -1692,7 +1282,6 @@ namespace PdfReader case fontCIDType0: case fontCIDType0C: { - /* GfxCIDFont* pFontCID = dynamic_cast(pFont); if (!bFontSubstitution && pFontCID && pFontCID->getCIDToGID()) { @@ -1708,6 +1297,7 @@ namespace PdfReader memcpy(pCodeToGID, ((GfxCIDFont*)pFont)->getCIDToGID(), nLen * sizeof(int)); break; } + /* #ifdef FONTS_USE_ONLY_MEMORY_STREAMS pT1CFontFile = FoFiType1C::make((char*)oMemoryFontStream.m_pData, oMemoryFontStream.m_nSize); #else @@ -1784,8 +1374,8 @@ namespace PdfReader nLen = 0; if (L"" != wsFileName && bFontSubstitution) { - CharCodeToUnicode *pCodeToUnicode = NULL; - if ((pCodeToUnicode = ((GfxCIDFont *)pFont)->getToUnicode())) + CharCodeToUnicode* pCodeToUnicode = NULL; + if ((pCodeToUnicode = ((GfxCIDFont*)pFont)->getToUnicode())) { #ifdef FONTS_USE_ONLY_MEMORY_STREAMS pTTFontFile = FoFiTrueType::make((char*)oMemoryFontStream.m_pData, oMemoryFontStream.m_nSize, 0); @@ -1807,7 +1397,7 @@ namespace PdfReader { // CID -> Unicode -> GID nLen = pCodeToUnicode->getLength(); - pCodeToGID = (int *)MemUtilsMallocArray(nLen, sizeof(int)); + pCodeToGID = (int*)MemUtilsMallocArray(nLen, sizeof(int)); for (int nCode = 0; nCode < nLen; ++nCode) { Unicode arrUnicodeBuffer[8]; @@ -1834,14 +1424,14 @@ namespace PdfReader pCodeToUnicode->decRefCnt(); } } - else if (((GfxCIDFont *)pFont)->getCIDToGID()) + else if (((GfxCIDFont*)pFont)->getCIDToGID()) { - nLen = ((GfxCIDFont *)pFont)->getCIDToGIDLen(); - pCodeToGID = (int *)MemUtilsMallocArray(nLen, sizeof(int)); + nLen = ((GfxCIDFont*)pFont)->getCIDToGIDLen(); + pCodeToGID = (int*)MemUtilsMallocArray(nLen, sizeof(int)); if (!pCodeToGID) break; - memcpy(pCodeToGID, ((GfxCIDFont *)pFont)->getCIDToGID(), nLen * sizeof(int)); + memcpy(pCodeToGID, ((GfxCIDFont*)pFont)->getCIDToGID(), nLen * sizeof(int)); } break; @@ -1853,7 +1443,6 @@ namespace PdfReader if (L"" != wsTempFileName) NSFile::CFileBinary::Remove(wsTempFileName); #endif - break; } } @@ -1861,12 +1450,12 @@ namespace PdfReader int nToUnicodeLen = 0; if (pFont->isCIDFont()) { - GfxCIDFont *pCIDFont = (GfxCIDFont *)pFont; - CharCodeToUnicode *pToUnicode = pCIDFont->getToUnicode(); + GfxCIDFont* pCIDFont = (GfxCIDFont*)pFont; + CharCodeToUnicode* pToUnicode = pCIDFont->getToUnicode(); if (NULL != pToUnicode) { nToUnicodeLen = pToUnicode->getLength(); - pCodeToUnicode = (int *)MemUtilsMallocArray(nToUnicodeLen, sizeof(int)); + pCodeToUnicode = (int*)MemUtilsMallocArray(nToUnicodeLen, sizeof(int)); if (pCodeToUnicode) { @@ -1874,7 +1463,7 @@ namespace PdfReader { Unicode aUnicode[2]; if (pToUnicode->mapToUnicode(nIndex, aUnicode, 2)) - pCodeToUnicode[nIndex] = (unsigned short)aUnicode[0]; + pCodeToUnicode[nIndex] = aUnicode[0]; else pCodeToUnicode[nIndex] = 0; } @@ -1887,11 +1476,11 @@ namespace PdfReader { // memory troubles here - CharCodeToUnicode *pToUnicode = ((Gfx8BitFont *)pFont)->getToUnicode(); + CharCodeToUnicode* pToUnicode = ((Gfx8BitFont*)pFont)->getToUnicode(); if (NULL != pToUnicode) { nToUnicodeLen = pToUnicode->getLength(); - pCodeToUnicode = (int *)MemUtilsMallocArray(nToUnicodeLen, sizeof(int));//literally here + pCodeToUnicode = (int*)MemUtilsMallocArray(nToUnicodeLen, sizeof(int));//literally here if (pCodeToUnicode) { @@ -1908,1014 +1497,18 @@ namespace PdfReader } } - // Записываем файл с настройками шрифта (Специально для перезаписи в PDF) - if (L"" != wsFileName && c_nPDFWriter == m_lRendererType) + // Обрежем индекс у FontName, если он есть + if (wsFontName.empty()) + wsFontName = wsFontBaseName; + if (wsFontName.length() > 7) { - std::wstring wsSplitFileName, wsSplitFileExt; - SpitPathExt(wsFileName, &wsSplitFileName, &wsSplitFileExt); - std::wstring wsEncodingPath = wsSplitFileName + L".enc"; + bool bIsIndex = true; + if ('+' != wsFontName.at(6)) + bIsIndex = false; - GfxFontType eFontType = pFont->getType(); - if (fontType1 == eFontType || fontType1C == eFontType || fontType1COT == eFontType || fontTrueType == eFontType || fontTrueTypeOT == eFontType) + if (bIsIndex) { - // Запись информации для простых шрифтов - CXmlWriter oXmlWriter; - - Ref *pRef = pFont->getID(); - Object oRefObject, oFontObject; - oRefObject.initRef(pRef->num, pRef->gen); - oRefObject.fetch(m_pXref, &oFontObject); - oRefObject.free(); - - if (oFontObject.isDict()) - { - Dict *pFontDict = oFontObject.getDict(); - - int nEncodingType = -1; // Объекта Encoding нет - int nBaseEncoding = -1; - - Object oDictItem; - pFontDict->lookup("Encoding", &oDictItem); - if (oDictItem.isDict()) - { - nEncodingType = 1; // Encoding - идет отдельным объектом - - Object oTemp; - oDictItem.dictLookup("BaseEncoding", &oTemp); - - if (oTemp.isName("MacRomanEncoding")) - nBaseEncoding = 0; - else if (oTemp.isName("MacExpertEncoding")) - nBaseEncoding = 1; - else if (oTemp.isName("WinAnsiEncoding")) - nBaseEncoding = 2; - - oTemp.free(); - } - else if (oDictItem.isName("MacRomanEncoding")) - { - nEncodingType = 0; - nBaseEncoding = 0; - } - else if (oDictItem.isName("MacExpertEncoding")) - { - nEncodingType = 0; - nBaseEncoding = 1; - } - else if (oDictItem.isName("WinAnsiEncoding")) - { - nEncodingType = 0; - nBaseEncoding = 2; - } - else - { - nEncodingType = -1; - } - - oXmlWriter.WriteNodeBegin(L"PDF-resources"); - oXmlWriter.WriteNodeBegin(L"Encoding", true); - oXmlWriter.WriteAttribute(L"type", nEncodingType); - oXmlWriter.WriteAttribute(L"base", nBaseEncoding); - oXmlWriter.WriteNodeEnd(L"Encoding", true, false); - - // Differences - if (oDictItem.isDict()) - { - Object oDifferences; - oDictItem.dictLookup("Differences", &oDifferences); - if (oDifferences.isArray()) - { - int nArrayLen = oDifferences.arrayGetLength(); - oXmlWriter.WriteNodeBegin(L"Differences", true); - oXmlWriter.WriteAttribute(L"count", nArrayLen); - oXmlWriter.WriteNodeEnd(L"Differences", true, false); - - for (int nIndex = 0; nIndex < nArrayLen; ++nIndex) - { - Object oTemp; - oDifferences.arrayGet(nIndex, &oTemp); - if (oTemp.isInt()) - { - int nCode = oTemp.getInt(); - oXmlWriter.WriteNodeBegin(L"Code", true); - oXmlWriter.WriteAttribute(L"value", nCode); - oXmlWriter.WriteNodeEnd(L"Code", true, true); - } - else if (oTemp.isName()) - { - char* sName = oTemp.getName(); - oXmlWriter.WriteNodeBegin(L"Name", true); - oXmlWriter.WriteAttribute(L"value", AStringToWString(sName)); - oXmlWriter.WriteNodeEnd(L"Name", true, true); - } - else - { - // TO DO: Error "Wrong type in font encoding resource differences" - } - oTemp.free(); - } - - oXmlWriter.WriteNodeEnd(L"Differences"); - } - oDifferences.free(); - } - oDictItem.free(); - oXmlWriter.WriteNodeEnd(L"Encoding"); - - pFontDict->lookup("BaseFont", &oDictItem); - if (oDictItem.isName()) - { - oXmlWriter.WriteNodeBegin(L"FontBase", true); - oXmlWriter.WriteAttribute(L"value", AStringToWString(oDictItem.getName())); - oXmlWriter.WriteNodeEnd(L"FontBase", true, true); - } - oDictItem.free(); - - pFontDict->lookup("ToUnicode", &oDictItem); - if (oDictItem.isStream()) - { - oXmlWriter.WriteNodeBegin(L"ToUnicode"); - - std::string sBuffer; - if (true) - { - oDictItem.streamReset(); - int nChar = 0; - while ((nChar = oDictItem.streamGetChar()) != EOF) - { - sBuffer+=(char)nChar; - } - oDictItem.streamClose(); - - CBase64 oBase64; - oBase64.Encode((unsigned char*)sBuffer.c_str(), sBuffer.length()); - - oXmlWriter.WriteString(AStringToWString(oBase64.GetCString())); - } - - oXmlWriter.WriteNodeEnd(L"ToUnicode"); - } - oDictItem.free(); - - - oXmlWriter.WriteNodeBegin(L"FontDescriptor"); - - Object oFontDescriptor; - if (pFontDict->lookup("FontDescriptor", &oFontDescriptor)->isDict()) - { - // FontName - oFontDescriptor.dictLookup("FontName", &oDictItem); - if (oDictItem.isName()) - { - oXmlWriter.WriteNodeBegin(L"FontName", true); - oXmlWriter.WriteAttribute(L"value", AStringToWString(oDictItem.getName())); - oXmlWriter.WriteNodeEnd(L"FontName", true); - } - oDictItem.free(); - - // FontFamily - oFontDescriptor.dictLookup("FontFamily", &oDictItem); - if (oDictItem.isName()) - { - oXmlWriter.WriteNodeBegin(L"FontFamily", true); - oXmlWriter.WriteAttribute(L"value", AStringToWString(oDictItem.getName())); - oXmlWriter.WriteNodeEnd(L"FontFamily", true); - } - oDictItem.free(); - - // FontStretch - oFontDescriptor.dictLookup("FontStretch", &oDictItem); - if (oDictItem.isName()) - { - oXmlWriter.WriteNodeBegin(L"FontStretch", true); - oXmlWriter.WriteAttribute(L"value", AStringToWString(oDictItem.getName())); - oXmlWriter.WriteNodeEnd(L"FontStretch", true); - } - oDictItem.free(); - - // FontWeight - oFontDescriptor.dictLookup("FontWeight", &oDictItem); - if (oDictItem.isInt()) - { - oXmlWriter.WriteNodeBegin(L"FontWeight", true); - oXmlWriter.WriteAttribute(L"value", oDictItem.getInt()); - oXmlWriter.WriteNodeEnd(L"FontWeight", true); - } - oDictItem.free(); - - // FontWeight - oFontDescriptor.dictLookup("Flags", &oDictItem); - if (oDictItem.isInt()) - { - oXmlWriter.WriteNodeBegin(L"Flags", true); - oXmlWriter.WriteAttribute(L"value", oDictItem.getInt()); - oXmlWriter.WriteNodeEnd(L"Flags", true); - } - oDictItem.free(); - - // FontBBox - oFontDescriptor.dictLookup("FontBBox", &oDictItem); - if (oDictItem.isArray()) - { - Array *pBBox = oDictItem.getArray(); - if (NULL != pBBox && 4 == pBBox->getLength()) - { - oXmlWriter.WriteNodeBegin(L"FontBBox", true); - for (int nIndex = 0; nIndex < 4; nIndex++) - { - Object oArrayItem; - pBBox->get(nIndex, &oArrayItem); - if (oArrayItem.isInt()) - { - std::wstring wsValue = L"value" + std::to_wstring(nIndex); - oXmlWriter.WriteAttribute(wsValue, oArrayItem.getInt()); - } - - oArrayItem.free(); - } - oXmlWriter.WriteNodeEnd(L"FontBBox", true); - } - } - oDictItem.free(); - - // ItalicAngle - oFontDescriptor.dictLookup("ItalicAngle", &oDictItem); - if (oDictItem.isInt()) - { - oXmlWriter.WriteNodeBegin(L"ItalicAngle", true); - oXmlWriter.WriteAttribute(L"value", oDictItem.getInt()); - oXmlWriter.WriteNodeEnd(L"ItalicAngle", true); - } - oDictItem.free(); - - // Ascent - oFontDescriptor.dictLookup("Ascent", &oDictItem); - if (oDictItem.isInt()) - { - oXmlWriter.WriteNodeBegin(L"Ascent", true); - oXmlWriter.WriteAttribute(L"value", oDictItem.getInt()); - oXmlWriter.WriteNodeEnd(L"Ascent", true); - } - oDictItem.free(); - - // Leading - oFontDescriptor.dictLookup("Leading", &oDictItem); - if (oDictItem.isInt()) - { - oXmlWriter.WriteNodeBegin(L"Leading", true); - oXmlWriter.WriteAttribute(L"value", oDictItem.getInt()); - oXmlWriter.WriteNodeEnd(L"Leading", true); - } - oDictItem.free(); - - // CapHeight - oFontDescriptor.dictLookup("CapHeight", &oDictItem); - if (oDictItem.isInt()) - { - oXmlWriter.WriteNodeBegin(L"CapHeight", true); - oXmlWriter.WriteAttribute(L"value", oDictItem.getInt()); - oXmlWriter.WriteNodeEnd(L"CapHeight", true); - } - oDictItem.free(); - - // XHeight - oFontDescriptor.dictLookup("XHeight", &oDictItem); - if (oDictItem.isInt()) - { - oXmlWriter.WriteNodeBegin(L"XHeight", true); - oXmlWriter.WriteAttribute(L"value", oDictItem.getInt()); - oXmlWriter.WriteNodeEnd(L"XHeight", true); - } - oDictItem.free(); - - // StemV - oFontDescriptor.dictLookup("StemV", &oDictItem); - if (oDictItem.isInt()) - { - oXmlWriter.WriteNodeBegin(L"StemV", true); - oXmlWriter.WriteAttribute(L"value", oDictItem.getInt()); - oXmlWriter.WriteNodeEnd(L"StemV", true); - } - oDictItem.free(); - - // StemH - oFontDescriptor.dictLookup("StemH", &oDictItem); - if (oDictItem.isInt()) - { - oXmlWriter.WriteNodeBegin(L"StemH", true); - oXmlWriter.WriteAttribute(L"value", oDictItem.getInt()); - oXmlWriter.WriteNodeEnd(L"StemH", true); - } - oDictItem.free(); - - // Descent - oFontDescriptor.dictLookup("Descent", &oDictItem); - if (oDictItem.isInt()) - { - oXmlWriter.WriteNodeBegin(L"Descent", true); - oXmlWriter.WriteAttribute(L"value", oDictItem.getInt()); - oXmlWriter.WriteNodeEnd(L"Descent", true); - } - oDictItem.free(); - - // AvgWidth - oFontDescriptor.dictLookup("AvgWidth", &oDictItem); - if (oDictItem.isInt()) - { - oXmlWriter.WriteNodeBegin(L"AvgWidth", true); - oXmlWriter.WriteAttribute(L"value", oDictItem.getInt()); - oXmlWriter.WriteNodeEnd(L"AvgWidth", true); - } - oDictItem.free(); - - // MaxWidth - oFontDescriptor.dictLookup("MaxWidth", &oDictItem); - if (oDictItem.isInt()) - { - oXmlWriter.WriteNodeBegin(L"MaxWidth", true); - oXmlWriter.WriteAttribute(L"value", oDictItem.getInt()); - oXmlWriter.WriteNodeEnd(L"MaxWidth", true); - } - oDictItem.free(); - - // MissingWidth - oFontDescriptor.dictLookup("MissingWidth", &oDictItem); - if (oDictItem.isInt()) - { - oXmlWriter.WriteNodeBegin(L"MissingWidth", true); - oXmlWriter.WriteAttribute(L"value", oDictItem.getInt()); - oXmlWriter.WriteNodeEnd(L"MissingWidth", true); - } - oDictItem.free(); - - } - oFontDescriptor.free(); - oXmlWriter.WriteNodeEnd(L"FontDescriptor"); - - int nFirstChar = 0; - pFontDict->lookup("FirstChar", &oDictItem); - if (oDictItem.isInt()) nFirstChar = oDictItem.getInt(); - oDictItem.free(); - - int nLastChar = 0; - pFontDict->lookup("LastChar", &oDictItem); - if (oDictItem.isInt()) nLastChar = oDictItem.getInt(); - oDictItem.free(); - - Array *pWidths = NULL; - pFontDict->lookup("Widths", &oDictItem); - if (oDictItem.isArray()) - { - oXmlWriter.WriteNodeBegin(L"Widths", true); - oXmlWriter.WriteAttribute(L"FirstChar", nFirstChar); - oXmlWriter.WriteAttribute(L"LastChar", nLastChar); - oXmlWriter.WriteNodeEnd(L"Widths", true, false); - - Array *pWidths = oDictItem.getArray(); - int nWidthsCount = pWidths->getLength(); - for (int nIndex = 0; nIndex < nWidthsCount; nIndex++) - { - Object oArrayItem; - pWidths->get(nIndex, &oArrayItem); - if (oArrayItem.isInt()) - { - oXmlWriter.WriteNodeBegin(L"Width", true); - oXmlWriter.WriteAttribute(L"value", oArrayItem.getInt()); - oXmlWriter.WriteNodeEnd(L"Width", true); - } - oArrayItem.free(); - } - oXmlWriter.WriteNodeEnd(L"Widths"); - } - oDictItem.free(); - oXmlWriter.WriteNodeEnd(L"PDF-resources"); - } - oFontObject.free(); - oXmlWriter.SaveToFile(wsEncodingPath); - } - else if (fontCIDType0 == eFontType || fontCIDType0C == eFontType || fontCIDType0COT == eFontType || fontCIDType2 == eFontType || fontCIDType2OT == eFontType) - { - // Пишем файл с кодировкой CMap - std::wstring wsCMapPath = wsSplitFileName + L".cmap"; - if (pFont->isCIDFont()) - { - GfxCIDFont *pCIDFont = (GfxCIDFont *)pFont; - // if (NULL != pCIDFont->GetCMap()) todo toxml - // pCIDFont->GetCMap()->ToXml(wsCMapPath); - } - - CXmlWriter oXmlWriter; - Ref *pRef = pFont->getID(); - Object oRefObject, oFontObject; - oRefObject.initRef(pRef->num, pRef->gen); - oRefObject.fetch(m_pXref, &oFontObject); - oRefObject.free(); - if (oFontObject.isDict()) - { - Dict *pFontDict = oFontObject.getDict(); - oXmlWriter.WriteNodeBegin(L"PDF-resources"); - Object oDictItem; - pFontDict->lookup("BaseFont", &oDictItem); - if (oDictItem.isName()) - { - oXmlWriter.WriteNodeBegin(L"Type0", true); - oXmlWriter.WriteAttribute(L"value", AStringToWString(oDictItem.getName())); - oXmlWriter.WriteNodeEnd(L"Type0", true, false); - } - else - { - oXmlWriter.WriteNodeBegin(L"Type0"); - } - oDictItem.free(); - - pFontDict->lookup("ToUnicode", &oDictItem); - if (oDictItem.isStream()) - { - oXmlWriter.WriteNodeBegin(L"ToUnicode"); - - std::string sBuffer; - oDictItem.streamReset(); - int nChar = 0; - while ((nChar = oDictItem.streamGetChar()) != EOF) - { - sBuffer+=(char)nChar; - } - oDictItem.streamClose(); - - CBase64 oBase64; - oBase64.Encode((unsigned char*)sBuffer.c_str(), sBuffer.length()); - - oXmlWriter.WriteString(AStringToWString(oBase64.GetCString())); - oXmlWriter.WriteNodeEnd(L"ToUnicode"); - } - oDictItem.free(); - - pFontDict->lookup("Encoding", &oDictItem); - if (oDictItem.isName()) - { - oXmlWriter.WriteNodeBegin(L"Encoding", true); - oXmlWriter.WriteAttribute(L"name", AStringToWString(oDictItem.getName())); - oXmlWriter.WriteNodeEnd(L"Encoding", true, true); - } - else if (oDictItem.isStream()) - { - oXmlWriter.WriteNodeBegin(L"Encoding"); - - Dict *pEncodingDict = oDictItem.streamGetDict(); - if (NULL != pEncodingDict) - { - Object oEncItem; - pEncodingDict->lookup("CMapName", &oEncItem); - if (oEncItem.isName()) - { - oXmlWriter.WriteNodeBegin(L"CMapName", true); - oXmlWriter.WriteAttribute(L"name", AStringToWString(oEncItem.getName())); - oXmlWriter.WriteNodeEnd(L"CMapName", true, true); - } - oEncItem.free(); - - pEncodingDict->lookup("CIDSystemInfo", &oEncItem); - if (oEncItem.isDict()) - { - Dict *pCIDInfo = oEncItem.getDict(); - - if (NULL != pCIDInfo) - { - oXmlWriter.WriteNodeBegin(L"CIDSystemInfo"); - - Object oCIDInfoItem; - pCIDInfo->lookup("Registry", &oCIDInfoItem); - if (oCIDInfoItem.isString()) - { - oXmlWriter.WriteNodeBegin(L"Registry", true); - oXmlWriter.WriteAttribute(L"string", AStringToWString(oCIDInfoItem.getString()->getCString())); - oXmlWriter.WriteNodeEnd(L"Registry", true, true); - } - oCIDInfoItem.free(); - - pCIDInfo->lookup("Ordering", &oCIDInfoItem); - if (oCIDInfoItem.isString()) - { - oXmlWriter.WriteNodeBegin(L"Ordering", true); - oXmlWriter.WriteAttribute(L"string", AStringToWString(oCIDInfoItem.getString()->getCString())); - oXmlWriter.WriteNodeEnd(L"Ordering", true, true); - } - oCIDInfoItem.free(); - - pCIDInfo->lookup("Supplement", &oCIDInfoItem); - if (oCIDInfoItem.isInt()) - { - oXmlWriter.WriteNodeBegin(L"Supplement", true); - oXmlWriter.WriteAttribute(L"integer", oCIDInfoItem.getInt()); - oXmlWriter.WriteNodeEnd(L"Supplement", true, true); - } - oCIDInfoItem.free(); - - oXmlWriter.WriteNodeEnd(L"CIDSystemInfo"); - } - } - oEncItem.free(); - - pEncodingDict->lookup("WMode", &oEncItem); - if (oEncItem.isInt()) - { - oXmlWriter.WriteNodeBegin(L"WMode", true); - oXmlWriter.WriteAttribute(L"integer", oEncItem.getInt()); - oXmlWriter.WriteNodeEnd(L"WMode", true, true); - } - oEncItem.free(); - - pEncodingDict->lookup("UseCMap", &oEncItem); - if (oEncItem.isName()) - { - oXmlWriter.WriteNodeBegin(L"UseCMap", true); - oXmlWriter.WriteAttribute(L"name", AStringToWString(oEncItem.getName())); - oXmlWriter.WriteNodeEnd(L"UseCMap", true, true); - } - else if (oEncItem.isStream()) - { - oXmlWriter.WriteNodeBegin(L"UseCMap"); - - std::string sBuffer; - oEncItem.streamReset(); - int nChar = 0; - while ((nChar = oEncItem.streamGetChar()) != EOF) - { - sBuffer+=(char)nChar; - } - oEncItem.streamClose(); - - CBase64 oBase64; - oBase64.Encode((unsigned char*)sBuffer.c_str(), sBuffer.length()); - - oXmlWriter.WriteString(AStringToWString(oBase64.GetCString())); - - oXmlWriter.WriteNodeEnd(L"UseCMap"); - } - oEncItem.free(); - } - - oXmlWriter.WriteNodeBegin(L"Stream"); - std::string sBuffer; - oDictItem.streamReset(); - int nChar = 0; - while ((nChar = oDictItem.streamGetChar()) != EOF) - { - sBuffer+=(char)nChar; - } - oDictItem.streamClose(); - - CBase64 oBase64; - oBase64.Encode((unsigned char*)sBuffer.c_str(), sBuffer.length()); - - oXmlWriter.WriteString(AStringToWString(oBase64.GetCString())); - - oXmlWriter.WriteNodeEnd(L"Stream"); - oXmlWriter.WriteNodeEnd(L"Encoding"); - } - oDictItem.free(); - - pFontDict->lookup("DescendantFonts", &oDictItem); - if (oDictItem.isArray()) - { - Array *pArray = oDictItem.getArray(); - if (1 == pArray->getLength()) - { - Object oDescFont; - pArray->get(0, &oDescFont); - - if (oDescFont.isDict()) - { - Dict *pDescFont = oDescFont.getDict(); - if (NULL != pDescFont) - { - oXmlWriter.WriteNodeBegin(L"DescendantFonts"); - - Object oFontItem; - pDescFont->lookup("Subtype", &oFontItem); - if (oFontItem.isName()) - { - oXmlWriter.WriteNodeBegin(L"Subtype", true); - oXmlWriter.WriteAttribute(L"name", AStringToWString(oFontItem.getName())); - oXmlWriter.WriteNodeEnd(L"Subtype", true, true); - } - oFontItem.free(); - - pDescFont->lookup("BaseFont", &oFontItem); - if (oFontItem.isName()) - { - oXmlWriter.WriteNodeBegin(L"BaseFont", true); - oXmlWriter.WriteAttribute(L"name", AStringToWString(oFontItem.getName())); - oXmlWriter.WriteNodeEnd(L"BaseFont", true, true); - } - oFontItem.free(); - - pDescFont->lookup("CIDSystemInfo", &oFontItem); - if (oFontItem.isDict()) - { - Dict *pCIDInfo = oFontItem.getDict(); - if (NULL != pCIDInfo) - { - oXmlWriter.WriteNodeBegin(L"CIDSystemInfo"); - - Object oCIDInfoItem; - pCIDInfo->lookup("Registry", &oCIDInfoItem); - if (oCIDInfoItem.isString()) - { - oXmlWriter.WriteNodeBegin(L"Registry", true); - oXmlWriter.WriteAttribute(L"string", AStringToWString(oCIDInfoItem.getString()->getCString())); - oXmlWriter.WriteNodeEnd(L"Registry", true, true); - } - oCIDInfoItem.free(); - - pCIDInfo->lookup("Ordering", &oCIDInfoItem); - if (oCIDInfoItem.isString()) - { - oXmlWriter.WriteNodeBegin(L"Ordering", true); - oXmlWriter.WriteAttribute(L"string", AStringToWString(oCIDInfoItem.getString()->getCString())); - oXmlWriter.WriteNodeEnd(L"Ordering", true, true); - } - oCIDInfoItem.free(); - - pCIDInfo->lookup("Supplement", &oCIDInfoItem); - if (oCIDInfoItem.isInt()) - { - oXmlWriter.WriteNodeBegin(L"Supplement", true); - oXmlWriter.WriteAttribute(L"integer", oCIDInfoItem.getInt()); - oXmlWriter.WriteNodeEnd(L"Supplement", true, true); - } - oCIDInfoItem.free(); - - oXmlWriter.WriteNodeEnd(L"CIDSystemInfo"); - } - } - oFontItem.free(); - - pDescFont->lookup("FontDescriptor", &oFontItem); - if (oFontItem.isDict()) - { - Dict *pFontDescriptor = oFontItem.getDict(); - if (NULL != pFontDescriptor) - { - oXmlWriter.WriteNodeBegin(L"FontDescriptor"); - Object oItemFD; - - pFontDescriptor->lookup("FontName", &oItemFD); - if (oItemFD.isName()) - { - oXmlWriter.WriteNodeBegin(L"FontName", true); - oXmlWriter.WriteAttribute(L"name", AStringToWString(oItemFD.getName())); - oXmlWriter.WriteNodeEnd(L"FontName", true, true); - } - oItemFD.free(); - - pFontDescriptor->lookup("FontStretch", &oItemFD); - if (oItemFD.isName()) - { - oXmlWriter.WriteNodeBegin(L"FontStretch", true); - oXmlWriter.WriteAttribute(L"name", AStringToWString(oItemFD.getName())); - oXmlWriter.WriteNodeEnd(L"FontStretch", true, true); - } - oItemFD.free(); - - pFontDescriptor->lookup("FontWeight", &oItemFD); - if (oItemFD.isInt()) - { - oXmlWriter.WriteNodeBegin(L"FontWeight", true); - oXmlWriter.WriteAttribute(L"number", oItemFD.getInt()); - oXmlWriter.WriteNodeEnd(L"FontWeight", true, true); - } - oItemFD.free(); - - pFontDescriptor->lookup("Flags", &oItemFD); - if (oItemFD.isInt()) - { - oXmlWriter.WriteNodeBegin(L"Flags", true); - oXmlWriter.WriteAttribute(L"integer", oItemFD.getInt()); - oXmlWriter.WriteNodeEnd(L"Flags", true, true); - } - oItemFD.free(); - - pFontDescriptor->lookup("FontBBox", &oItemFD); - if (oItemFD.isArray()) - { - Array *pBBox = oItemFD.getArray(); - if (NULL != pBBox && 4 == pBBox->getLength()) - { - oXmlWriter.WriteNodeBegin(L"FontBBox", true); - for (int nIndex = 0; nIndex < 4; nIndex++) - { - Object oArrayItem; - pBBox->get(nIndex, &oArrayItem); - if (oArrayItem.isInt()) - { - std::wstring wsValue = L"value" + std::to_wstring(nIndex); - oXmlWriter.WriteAttribute(wsValue, oArrayItem.getInt()); - } - - oArrayItem.free(); - } - oXmlWriter.WriteNodeEnd(L"FontBBox", true); - } - } - oItemFD.free(); - - pFontDescriptor->lookup("ItalicAngle", &oItemFD); - if (oItemFD.isInt()) - { - oXmlWriter.WriteNodeBegin(L"ItalicAngle", true); - oXmlWriter.WriteAttribute(L"number", oItemFD.getInt()); - oXmlWriter.WriteNodeEnd(L"ItalicAngle", true, true); - } - oItemFD.free(); - - pFontDescriptor->lookup("Ascent", &oItemFD); - if (oItemFD.isInt()) - { - oXmlWriter.WriteNodeBegin(L"Ascent", true); - oXmlWriter.WriteAttribute(L"number", oItemFD.getInt()); - oXmlWriter.WriteNodeEnd(L"Ascent", true, true); - } - oItemFD.free(); - - pFontDescriptor->lookup("Descent", &oItemFD); - if (oItemFD.isInt()) - { - oXmlWriter.WriteNodeBegin(L"Descent", true); - oXmlWriter.WriteAttribute(L"number", oItemFD.getInt()); - oXmlWriter.WriteNodeEnd(L"Descent", true, true); - } - oItemFD.free(); - - pFontDescriptor->lookup("Leading", &oItemFD); - if (oItemFD.isInt()) - { - oXmlWriter.WriteNodeBegin(L"Leading", true); - oXmlWriter.WriteAttribute(L"number", oItemFD.getInt()); - oXmlWriter.WriteNodeEnd(L"Leading", true, true); - } - oItemFD.free(); - - pFontDescriptor->lookup("CapHeight", &oItemFD); - if (oItemFD.isInt()) - { - oXmlWriter.WriteNodeBegin(L"CapHeight", true); - oXmlWriter.WriteAttribute(L"number", oItemFD.getInt()); - oXmlWriter.WriteNodeEnd(L"CapHeight", true, true); - } - oItemFD.free(); - - pFontDescriptor->lookup("XHeight", &oItemFD); - if (oItemFD.isInt()) - { - oXmlWriter.WriteNodeBegin(L"XHeight", true); - oXmlWriter.WriteAttribute(L"number", oItemFD.getInt()); - oXmlWriter.WriteNodeEnd(L"XHeight", true, true); - } - oItemFD.free(); - - pFontDescriptor->lookup("StemV", &oItemFD); - if (oItemFD.isInt()) - { - oXmlWriter.WriteNodeBegin(L"StemV", true); - oXmlWriter.WriteAttribute(L"number", oItemFD.getInt()); - oXmlWriter.WriteNodeEnd(L"StemV", true, true); - } - oItemFD.free(); - - pFontDescriptor->lookup("StemH", &oItemFD); - if (oItemFD.isInt()) - { - oXmlWriter.WriteNodeBegin(L"StemH", true); - oXmlWriter.WriteAttribute(L"number", oItemFD.getInt()); - oXmlWriter.WriteNodeEnd(L"StemH", true, true); - } - oItemFD.free(); - - pFontDescriptor->lookup("AvgWidth", &oItemFD); - if (oItemFD.isInt()) - { - oXmlWriter.WriteNodeBegin(L"AvgWidth", true); - oXmlWriter.WriteAttribute(L"number", oItemFD.getInt()); - oXmlWriter.WriteNodeEnd(L"AvgWidth", true, true); - } - oItemFD.free(); - - pFontDescriptor->lookup("MaxWidth", &oItemFD); - if (oItemFD.isInt()) - { - oXmlWriter.WriteNodeBegin(L"MaxWidth", true); - oXmlWriter.WriteAttribute(L"number", oItemFD.getInt()); - oXmlWriter.WriteNodeEnd(L"MaxWidth", true, true); - } - oItemFD.free(); - - pFontDescriptor->lookup("MissingWidth", &oItemFD); - if (oItemFD.isInt()) - { - oXmlWriter.WriteNodeBegin(L"MissingWidth", true); - oXmlWriter.WriteAttribute(L"number", oItemFD.getInt()); - oXmlWriter.WriteNodeEnd(L"MissingWidth", true, true); - } - oItemFD.free(); - - // TODO: Тут надо реализовать чтени полей /Style, /Lang, /FD, /CIDSet - - oXmlWriter.WriteNodeEnd(L"FontDescriptor"); - } - } - oFontItem.free(); - - pDescFont->lookup("DW", &oFontItem); - if (oFontItem.isInt()) - { - oXmlWriter.WriteNodeBegin(L"DW", true); - oXmlWriter.WriteAttribute(L"integer", oFontItem.getInt()); - oXmlWriter.WriteNodeEnd(L"DW", true, true); - } - oFontItem.free(); - - pDescFont->lookup("W", &oFontItem); - if (oFontItem.isArray()) - { - Array *pArray = oFontItem.getArray(); - if (NULL != pArray) - { - oXmlWriter.WriteNodeBegin(L"W"); - - for (int nIndex = 0; nIndex < pArray->getLength(); nIndex++) - { - Object oArrayItem; - pArray->get(nIndex, &oArrayItem); - if (oArrayItem.isInt()) - { - oXmlWriter.WriteNodeBegin(L"Int", true); - oXmlWriter.WriteAttribute(L"value", oArrayItem.getInt()); - oXmlWriter.WriteNodeEnd(L"Int", true, true); - } - else if (oArrayItem.isArray()) - { - Array *pWArray = oArrayItem.getArray(); - if (NULL != pWArray) - { - oXmlWriter.WriteNodeBegin(L"Array"); - for (int nWIndex = 0; nWIndex < pWArray->getLength(); nWIndex++) - { - Object oWArrayItem; - pWArray->get(nWIndex, &oWArrayItem); - if (oWArrayItem.isInt()) - { - oXmlWriter.WriteNodeBegin(L"Int", true); - oXmlWriter.WriteAttribute(L"value", oWArrayItem.getInt()); - oXmlWriter.WriteNodeEnd(L"Int", true, true); - } - oWArrayItem.free(); - } - oXmlWriter.WriteNodeEnd(L"Array"); - } - } - oArrayItem.free(); - } - - oXmlWriter.WriteNodeEnd(L"W"); - } - } - oFontItem.free(); - - pDescFont->lookup("DW2", &oFontItem); - if (oFontItem.isArray()) - { - Array *pArray = oFontItem.getArray(); - if (NULL != pArray && 2 == pArray->getLength()) - { - oXmlWriter.WriteNodeBegin(L"DW2", true); - - Object oArrayItem; - pArray->get(0, &oArrayItem); - if (oArrayItem.isInt()) - { - oXmlWriter.WriteAttribute(L"value0", oArrayItem.getInt()); - } - oArrayItem.free(); - - pArray->get(1, &oArrayItem); - if (oArrayItem.isInt()) - { - oXmlWriter.WriteAttribute(L"value1", oArrayItem.getInt()); - } - oArrayItem.free(); - - oXmlWriter.WriteNodeEnd(L"DW2", true, true); - } - } - oFontItem.free(); - - pDescFont->lookup("W2", &oFontItem); - if (oFontItem.isArray()) - { - Array *pArray = oFontItem.getArray(); - if (NULL != pArray) - { - oXmlWriter.WriteNodeBegin(L"W2"); - - for (int nIndex = 0; nIndex < pArray->getLength(); nIndex++) - { - Object oArrayItem; - pArray->get(nIndex, &oArrayItem); - if (oArrayItem.isInt()) - { - oXmlWriter.WriteNodeBegin(L"Int", true); - oXmlWriter.WriteAttribute(L"value", oArrayItem.getInt()); - oXmlWriter.WriteNodeEnd(L"Int", true, true); - } - else if (oArrayItem.isArray()) - { - Array *pWArray = oArrayItem.getArray(); - if (NULL != pWArray) - { - oXmlWriter.WriteNodeBegin(L"Array"); - for (int nWIndex = 0; nWIndex < pWArray->getLength(); nWIndex++) - { - Object oWArrayItem; - pWArray->get(nWIndex, &oWArrayItem); - if (oWArrayItem.isInt()) - { - oXmlWriter.WriteNodeBegin(L"Int", true); - oXmlWriter.WriteAttribute(L"value", oWArrayItem.getInt()); - oXmlWriter.WriteNodeEnd(L"Int", true, true); - } - oWArrayItem.free(); - } - oXmlWriter.WriteNodeEnd(L"Array"); - } - } - oArrayItem.free(); - } - - oXmlWriter.WriteNodeEnd(L"W2"); - } - } - oFontItem.free(); - - pDescFont->lookup("CIDToGIDMap", &oFontItem); - if (oFontItem.isName()) - { - oXmlWriter.WriteNodeBegin(L"CIDToGIDMap", true); - oXmlWriter.WriteAttribute(L"name", AStringToWString(oFontItem.getName())); - oXmlWriter.WriteNodeEnd(L"CIDToGIDMap", true, true); - } - else if (oFontItem.isStream()) - { - oXmlWriter.WriteNodeBegin(L"CIDToGIDMap"); - - std::string sBuffer; - oFontItem.streamReset(); - int nChar = 0; - while ((nChar = oFontItem.streamGetChar()) != EOF) - { - sBuffer+=(char)nChar; - } - oFontItem.streamClose(); - - CBase64 oBase64; - oBase64.Encode((unsigned char*)sBuffer.c_str(), sBuffer.length()); - - oXmlWriter.WriteString(AStringToWString(oBase64.GetCString())); - - oXmlWriter.WriteNodeEnd(L"CIDToGIDMap"); - } - oFontItem.free(); - - - oXmlWriter.WriteNodeEnd(L"DescendantFonts"); - } - } - oDescFont.free(); - } - } - oDictItem.free(); - - oXmlWriter.WriteNodeEnd(L"Type0"); - oXmlWriter.WriteNodeEnd(L"PDF-resources"); - } - oFontObject.free(); - - oXmlWriter.SaveToFile(wsEncodingPath); - } - } - - // Обрежем индекс у FontName, если он есть - if (wsFontName.empty()) - wsFontName = wsFontBaseName; - if (wsFontName.length() > 7) - { - bool bIsIndex = true; - if ('+' != wsFontName.at(6)) - bIsIndex = false; - - if (bIsIndex) - { - for (int nIndex = 0; nIndex < 6; nIndex++) + for (int nIndex = 0; nIndex < 6; nIndex++) { int nChar = wsFontName.at(nIndex); if (nChar < 'A' || nChar > 'Z') @@ -2945,105 +1538,106 @@ namespace PdfReader wsFileName = pEntry->wsFilePath; wsFontName = pEntry->wsFontName; } + } + void RendererOutputDev::updateFont(GfxState* pGState) + { + // Проверяем наличие списка со шрифтами + if (!m_pFontList) + return; + + GfxFont* pFont = pGState->getFont(); + if (!pFont) + return; + + m_pRenderer->put_FontSize(pGState->getFontSize()); - if (L"" != wsFileName) + std::wstring wsFileName = L""; + std::wstring wsFontName = L""; + GetFont(m_pXref, m_pFontManager, m_pFontList, pFont, wsFileName, wsFontName); + + if (!wsFileName.empty()) { m_pRenderer->put_FontPath(wsFileName); m_pRenderer->put_FontName(wsFontName); } } - void RendererOutputDev::stroke(GfxState *pGState) + void RendererOutputDev::stroke(GfxState* pGState) { if (m_bDrawOnlyText) return; - if (m_bTransparentGroupSoftMask) - return; - DoPath(pGState, pGState->getPath(), pGState->getPageHeight(), pGState->getCTM()); m_pRenderer->DrawPath(c_nStroke); m_pRenderer->EndCommand(c_nPathType); } - void RendererOutputDev::fill(GfxState *pGState) + void RendererOutputDev::fill(GfxState* pGState) { if (m_bDrawOnlyText) return; - if (m_bTransparentGroupSoftMask || (!m_arrTransparentGroupSoftMask.empty() && m_bTransparentGroupSoftMaskEnd)) - return; - DoPath(pGState, pGState->getPath(), pGState->getPageHeight(), pGState->getCTM()); m_pRenderer->DrawPath(c_nWindingFillMode); m_pRenderer->EndCommand(c_nPathType); } - void RendererOutputDev::eoFill(GfxState *pGState) + void RendererOutputDev::eoFill(GfxState* pGState) { if (m_bDrawOnlyText) return; - if (m_bTransparentGroupSoftMask || (!m_arrTransparentGroupSoftMask.empty() && m_bTransparentGroupSoftMaskEnd)) - return; - DoPath(pGState, pGState->getPath(), pGState->getPageHeight(), pGState->getCTM()); m_pRenderer->DrawPath(c_nEvenOddFillMode); m_pRenderer->EndCommand(c_nPathType); } - void RendererOutputDev::FillStroke(GfxState *pGState) + void RendererOutputDev::FillStroke(GfxState* pGState) { if (m_bDrawOnlyText) return; - if (m_bTransparentGroupSoftMask || (!m_arrTransparentGroupSoftMask.empty() && m_bTransparentGroupSoftMaskEnd)) - return; - DoPath(pGState, pGState->getPath(), pGState->getPageHeight(), pGState->getCTM()); m_pRenderer->DrawPath(c_nStroke | c_nWindingFillMode); m_pRenderer->EndCommand(c_nPathType); } - void RendererOutputDev::EoFillStroke(GfxState *pGState) + void RendererOutputDev::EoFillStroke(GfxState* pGState) { if (m_bDrawOnlyText) return; - if (m_bTransparentGroupSoftMask || (!m_arrTransparentGroupSoftMask.empty() && m_bTransparentGroupSoftMaskEnd)) - return; - DoPath(pGState, pGState->getPath(), pGState->getPageHeight(), pGState->getCTM()); m_pRenderer->DrawPath(c_nStroke | c_nEvenOddFillMode); m_pRenderer->EndCommand(c_nPathType); } - void RendererOutputDev::tilingPatternFill(GfxState *pGState, Gfx *gfx, Object *pStream, int nPaintType, int nTilingType, Dict *pResourcesDict, double *matrix, double *pBBox, + void RendererOutputDev::tilingPatternFill(GfxState* pGState, Gfx* gfx, Object* pStream, int nPaintType, int nTilingType, Dict* pResourcesDict, double* pMatrix, double* pBBox, int nX0, int nY0, int nX1, int nY1, double dXStep, double dYStep) { if (m_bDrawOnlyText) return; - if (m_bTransparentGroupSoftMask || (!m_arrTransparentGroupSoftMask.empty() && m_bTransparentGroupSoftMaskEnd)) + if (nX1 - nX0 == 1 && nY1 - nY0 == 1) // Одно изображение, tilingPattern не требуется + { + gfx->drawForm(pStream, pResourcesDict, pMatrix, pBBox); return; + } - double xMin, yMin, xMax, yMax; - pGState->getUserClipBBox(&xMin, &yMin, &xMax, &yMax); - pGState->moveTo(xMin, yMin); - pGState->lineTo(xMax, yMin); - pGState->lineTo(xMax, yMax); - pGState->lineTo(xMin, yMax); - pGState->closePath(); - - DoPath(pGState, pGState->getPath(), pGState->getPageHeight(), pGState->getCTM()); - - // Image - long brush; - int alpha = pGState->getFillOpacity() * 255; + if (fabs(pBBox[2] - pBBox[0] - dXStep) > 0.001 || fabs(pBBox[3] - pBBox[1] - dYStep) > 0.001) + return; - double dDpiX, dDpiY; + double dWidth, dHeight, dDpiX, dDpiY; + m_pRenderer->get_Width(&dWidth); + m_pRenderer->get_Height(&dHeight); m_pRenderer->get_DpiX(&dDpiX); m_pRenderer->get_DpiY(&dDpiY); - int nWidth = dXStep * dDpiX / 72.0; - int nHeight = dYStep * dDpiY / 72.0; + dWidth = dWidth * dDpiX / 25.4; + dHeight = dHeight * dDpiY / 25.4; + + dWidth *= (dXStep / pGState->getPageWidth()); + dHeight *= (dYStep / pGState->getPageHeight()); + + int nWidth = round(dWidth); + int nHeight = round(dHeight); BYTE* pBgraData = new BYTE[nWidth * nHeight * 4]; memset(pBgraData, 0, nWidth * nHeight * 4); @@ -3052,16 +1646,15 @@ namespace PdfReader pFrame->put_Data(pBgraData); pFrame->put_Width(nWidth); pFrame->put_Height(nHeight); - pFrame->put_Stride(4 * nWidth); + pFrame->put_Stride(-4 * nWidth); NSGraphics::IGraphicsRenderer* pRenderer = NSGraphics::Create(); pRenderer->SetFontManager(m_pFontManager); pRenderer->CreateFromBgraFrame(pFrame); - pRenderer->put_Width (dXStep * 25.4 / 72.0); - pRenderer->put_Height(dYStep * 25.4 / 72.0); - - IRenderer* pOldRenderer = m_pRenderer; - m_pRenderer = pRenderer; + pRenderer->put_Width (dWidth * 25.4 / 72.0); + pRenderer->put_Height(dHeight * 25.4 / 72.0); + pRenderer->CommandLong(c_nPenWidth0As1px, 1); + pRenderer->SetSwapRGB(false); PDFRectangle box; box.x1 = pBBox[0]; @@ -3069,46 +1662,57 @@ namespace PdfReader box.x2 = pBBox[2]; box.y2 = pBBox[3]; - Gfx* m_gfx = new Gfx(gfx->getDoc(), this, pResourcesDict, &box, NULL); + RendererOutputDev* m_pRendererOut = new RendererOutputDev(pRenderer, m_pFontManager, m_pFontList); + m_pRendererOut->NewPDF(gfx->getDoc()->getXRef()); + + Gfx* m_gfx = new Gfx(gfx->getDoc(), m_pRendererOut, -1, pResourcesDict, dDpiX, dDpiY, &box, NULL, 0); m_gfx->display(pStream); - // pBgraData будет передано oImage pFrame->ClearNoAttack(); RELEASEOBJECT(m_gfx); RELEASEOBJECT(pRenderer); + RELEASEOBJECT(m_pRendererOut); RELEASEOBJECT(pFrame); - m_pRenderer = pOldRenderer; Aggplus::CImage* oImage = new Aggplus::CImage(); oImage->Create(pBgraData, nWidth, nHeight, 4 * nWidth); - m_pRenderer->BrushRect(true, xMin, yMin, xMax, yMax); + double xMin, yMin, xMax, yMax; + xMin = nX0 * dXStep + pBBox[0]; + yMin = nY0 * dYStep + pBBox[1]; + xMax = nX1 * dXStep + pBBox[0]; + yMax = nY1 * dYStep + pBBox[1]; + Transform(pMatrix, xMin, yMin, &xMin, &yMin); + Transform(pMatrix, xMax, yMax, &xMax, &yMax); + pGState->moveTo(xMin, yMin); + pGState->lineTo(xMax, yMin); + pGState->lineTo(xMax, yMax); + pGState->lineTo(xMin, yMax); + pGState->closePath(); + + DoPath(pGState, pGState->getPath(), pGState->getPageHeight(), pGState->getCTM()); + + long brush; m_pRenderer->get_BrushType(&brush); + + int alpha = pGState->getFillOpacity() * 255; m_pRenderer->put_BrushType(c_BrushTypeTexture); m_pRenderer->put_BrushTextureImage(oImage); - m_pRenderer->put_BrushTextureMode(1); // TODO Tile 1 или TileCenter 2 + m_pRenderer->put_BrushTextureMode(c_BrushTextureModeTile); m_pRenderer->put_BrushTextureAlpha(alpha); -#ifdef BUILDING_WASM_MODULE - if (NSGraphics::IGraphicsRenderer* GRenderer = dynamic_cast(m_pRenderer)) - { - // oImage BGRA - GRenderer->SetSwapRGB(false); - m_pRenderer->DrawPath(c_nWindingFillMode); - GRenderer->SetSwapRGB(true); - } -#else + m_pRenderer->BeginCommand(c_nImageType); + m_pRenderer->DrawPath(c_nWindingFillMode); -#endif - m_pRenderer->EndCommand(c_nPathType); - m_pRenderer->BrushRect(false, 0, 0, 1, 1); + m_pRenderer->PathCommandEnd(); + m_pRenderer->EndCommand(c_nImageType); m_pRenderer->put_BrushType(brush); + m_pRenderer->put_BrushTextureImage(NULL); pGState->clearPath(); - RELEASEINTERFACE(oImage); } - void RendererOutputDev::StartTilingFill(GfxState *pGState) + void RendererOutputDev::StartTilingFill(GfxState* pGState) { if (m_bDrawOnlyText) return; @@ -3125,18 +1729,18 @@ namespace PdfReader m_bTiling = false; } - GBool RendererOutputDev::shadedFill(GfxState *pGState, GfxShading *pShading) + GBool RendererOutputDev::shadedFill(GfxState* pGState, GfxShading* pShading) { double x0, y0, x1, x2, y1, y2, r1, r2; double xmin, xmax, ymin, ymax, r; - double *matrix; + double* matrix; int nTriangles = 0, nPatches = 0; switch (pShading->getType()) { case 1: - ((GfxFunctionShading *)pShading)->getDomain(&x0, &y0, &x1, &y1); - matrix = ((GfxFunctionShading *)pShading)->getMatrix(); + ((GfxFunctionShading*)pShading)->getDomain(&x0, &y0, &x1, &y1); + matrix = ((GfxFunctionShading*)pShading)->getMatrix(); pGState->moveTo(x0 * matrix[0] + y0 * matrix[2] + matrix[4], x0 * matrix[1] + y0 * matrix[3] + matrix[5]); pGState->lineTo(x1 * matrix[0] + y0 * matrix[2] + matrix[4], @@ -3146,12 +1750,10 @@ namespace PdfReader pGState->lineTo(x0 * matrix[0] + y1 * matrix[2] + matrix[4], x0 * matrix[1] + y1 * matrix[3] + matrix[5]); pGState->closePath(); - FunctionShadedFill(pGState, (GfxFunctionShading *) pShading); + FunctionShadedFill(pGState, (GfxFunctionShading*) pShading); return true; case 2: pGState->getUserClipBBox(&xmin, &ymin, &xmax, &ymax); - //pGState->clearPath(); - pGState->moveTo(xmin, ymin); pGState->lineTo(xmin, ymax); @@ -3161,7 +1763,7 @@ namespace PdfReader AxialShadedFill(pGState, (GfxAxialShading* )pShading); return true; case 3: - ((GfxRadialShading *)pShading)->getCoords(&x1, &y1, &r1, &x2, &y2, &r2); + ((GfxRadialShading*)pShading)->getCoords(&x1, &y1, &r1, &x2, &y2, &r2); r = std::max(r1,r2); xmin = std::min(x1, x2) - 2 * r; @@ -3178,21 +1780,21 @@ namespace PdfReader return true; case 4: case 5: - nTriangles = ((GfxGouraudTriangleShading *) pShading)->getNTriangles(); + nTriangles = ((GfxGouraudTriangleShading*) pShading)->getNTriangles(); for (int i = 0; i < nTriangles; i++) { - int nComps = ((GfxGouraudTriangleShading *) pShading)->getNComps(); + int nComps = ((GfxGouraudTriangleShading*) pShading)->getNComps(); double x1,x2,x3,y1,y2,y3; - double *c1 = new double[nComps]; - double *c2 = new double[nComps]; - double *c3 = new double[nComps]; + double* c1 = new double[nComps]; + double* c2 = new double[nComps]; + double* c3 = new double[nComps]; GfxColor col1, col2, col3; - ((GfxGouraudTriangleShading *) pShading)->getTriangle(i, &x1, &y1, c1, &x2, &y2, c2, &x3, &y3, c3); - ((GfxGouraudTriangleShading *) pShading)->getColor(c1, &col1); - ((GfxGouraudTriangleShading *) pShading)->getColor(c2, &col2); - ((GfxGouraudTriangleShading *) pShading)->getColor(c3, &col3); + ((GfxGouraudTriangleShading*) pShading)->getTriangle(i, &x1, &y1, c1, &x2, &y2, c2, &x3, &y3, c3); + ((GfxGouraudTriangleShading*) pShading)->getColor(c1, &col1); + ((GfxGouraudTriangleShading*) pShading)->getColor(c2, &col2); + ((GfxGouraudTriangleShading*) pShading)->getColor(c3, &col3); pGState->clearPath(); @@ -3210,10 +1812,16 @@ namespace PdfReader return true; case 6: case 7: - int nComps = ((GfxPatchMeshShading *) pShading)->getNComps(); - int nPatches = ((GfxPatchMeshShading *) pShading)->getNPatches(); + int nComps = ((GfxPatchMeshShading*)pShading)->getNComps(); + int nPatches = ((GfxPatchMeshShading*)pShading)->getNPatches(); + + NSGraphics::IGraphicsRenderer* GRenderer = dynamic_cast(m_pRenderer); + if (GRenderer) + GRenderer->SetSoftMask(NULL); + m_pRenderer->BeginCommand(c_nLayerType); + for (int i = 0; i < nPatches; i++) { - GfxPatch *patch = ((GfxPatchMeshShading *) pShading)->getPatch(i); + GfxPatch* patch = ((GfxPatchMeshShading*)pShading)->getPatch(i); pGState->clearPath(); pGState->moveTo(patch->x[0][0], patch->y[0][0]); pGState->curveTo(patch->x[0][1], patch->y[0][1], @@ -3229,22 +1837,24 @@ namespace PdfReader patch->x[1][0], patch->y[1][0], patch->x[0][0], patch->y[0][0]); pGState->closePath(); - PatchMeshFill(pGState, patch, (GfxPatchMeshShading *) pShading); + PatchMeshFill(pGState, patch, (GfxPatchMeshShading*)pShading); } + + if (GRenderer) + GRenderer->SetSoftMask(m_pSoftMask); + m_pRenderer->EndCommand(c_nLayerType); + return true; } return false; } - bool RendererOutputDev::FunctionShadedFill(GfxState *pGState, GfxFunctionShading *pShading) + bool RendererOutputDev::FunctionShadedFill(GfxState* pGState, GfxFunctionShading* pShading) { if (m_bDrawOnlyText) return true; - if (m_bTransparentGroupSoftMask || (!m_arrTransparentGroupSoftMask.empty() && m_bTransparentGroupSoftMaskEnd)) - return true; - DoPath(pGState, pGState->getPath(), pGState->getPageHeight(), pGState->getCTM()); long brush; int alpha = pGState->getFillOpacity() * 255; @@ -3259,15 +1869,15 @@ namespace PdfReader } NSStructures::GradientInfo info = NSStructures::GInfoConstructor::get_functional(x1, x2, y1, y2, mapping); - float cur_x = 0, cur_y = 0; + float cur_y = 0; float delta_x = (x2 - x1) / info.shading.function.get_resolution(); float delta_y = (y2 - y1) / info.shading.function.get_resolution(); - GfxColorSpace *ColorSpace = pShading->getColorSpace(); + GfxColorSpace* ColorSpace = pShading->getColorSpace(); for (size_t i = 0; i < info.shading.function.get_resolution(); i++) { - cur_x = 0; + float cur_x = 0; for (size_t j = 0; j < info.shading.function.get_resolution(); j++) { GfxColor c; @@ -3283,65 +1893,25 @@ namespace PdfReader cur_y += delta_y; } - if (NSGraphics::IGraphicsRenderer* GRenderer = dynamic_cast(m_pRenderer)) - { - GRenderer->put_BrushGradInfo(info); - m_pRenderer->DrawPath(c_nWindingFillMode); - } + m_pRenderer->put_BrushGradInfo(&info); + m_pRenderer->DrawPath(c_nWindingFillMode); m_pRenderer->EndCommand(c_nPathType); m_pRenderer->put_BrushType(brush); pGState->clearPath(); return true; } - bool RendererOutputDev::AxialShadedFill(GfxState *pGState, GfxAxialShading *pShading) + bool RendererOutputDev::AxialShadedFill(GfxState* pGState, GfxAxialShading* pShading) { if (m_bDrawOnlyText) return true; - if (m_bTransparentGroupSoftMask || (!m_arrTransparentGroupSoftMask.empty() && m_bTransparentGroupSoftMaskEnd)) - return true; double x1, x2, y1, y2; double t0, t1; long brush; m_pRenderer->get_BrushType(&brush); - /* - IRenderer* pLastRenderer = m_pRenderer; - BYTE* pBgraData = NULL; - CBgraFrame* pFrame = NULL; - double dpi, dWidth, dHeight; - m_pRenderer->get_DpiX(&dpi); - // TODO что если размеры не равны размерам m_pSoftMask - pLastRenderer->get_Width(&dWidth); - pLastRenderer->get_Height(&dHeight); - int nWidth = dWidth * 96 / dpi; - int nHeight = dHeight * 96 / dpi; - if (m_pSoftMask) - { - NSGraphics::IGraphicsRenderer* pRenderer = NSGraphics::Create(); - m_pRenderer = pRenderer; - - pBgraData = new BYTE[nWidth * nHeight * 4]; - memset(pBgraData, 0xff, nWidth * nHeight * 4); - - pFrame = new CBgraFrame(); - pFrame->put_Data(pBgraData); - pFrame->put_Width(nWidth); - pFrame->put_Height(nHeight); - // TODO bIsFlip = true ~ 4 - pFrame->put_Stride(-4 * nWidth); - - pRenderer->CreateFromBgraFrame(pFrame); - // TODO проверить - pRenderer->SetSwapRGB(true); - - pRenderer->put_Width(dWidth); - pRenderer->put_Height(dHeight); - } - */ - DoPath(pGState, pGState->getPath(), pGState->getPageHeight(), pGState->getCTM()); double dAlphaKoef = pGState->getFillOpacity(); @@ -3359,7 +1929,7 @@ namespace PdfReader NSStructures::GradientInfo info = NSStructures::GInfoConstructor::get_linear({x1, y1}, {x2, y2}, t0, t1, pShading->getExtend0(), pShading->getExtend1()); - GfxColorSpace *ColorSpace = pShading->getColorSpace(); + GfxColorSpace* ColorSpace = pShading->getColorSpace(); float delta = (t1 - t0) / info.shading.function.get_resolution(); float t = t0; for (size_t i = 0; i < info.shading.function.get_resolution(); i++) @@ -3378,76 +1948,21 @@ namespace PdfReader t+=delta; } - if (NSGraphics::IGraphicsRenderer* GRenderer = dynamic_cast(m_pRenderer)) - { - GRenderer->put_BrushGradInfo(info); - m_pRenderer->DrawPath(c_nWindingFillMode); - } + m_pRenderer->put_BrushGradInfo(&info); + m_pRenderer->DrawPath(c_nWindingFillMode); m_pRenderer->EndCommand(c_nPathType); - /* - if (m_pSoftMask) - { - for (int nY = m_nSoftMaskHeight - 1; nY >= 0; nY--) - { - int nIndex = 4 * nY * m_nSoftMaskWidth; - for (int nX = 0; nX < m_nSoftMaskWidth; nX++) - { - if (m_pSoftMask[nIndex + 3]) - { - m_pSoftMask[nIndex + 0] = pBgraData[nIndex + 0]; - m_pSoftMask[nIndex + 1] = pBgraData[nIndex + 1]; - m_pSoftMask[nIndex + 2] = pBgraData[nIndex + 2]; - } - nIndex += 4; - } - } - - pFrame->SaveFile(NSFile::GetProcessDirectory() + L"/res3.png", _CXIMAGE_FORMAT_PNG); - RELEASEOBJECT(m_pRenderer); - m_pRenderer = pLastRenderer; - - Aggplus::CImage oImage; - oImage.Create(m_pSoftMask, m_nSoftMaskWidth, m_nSoftMaskHeight, -4 * m_nSoftMaskWidth, true); - - double arrMatrix[6]; - double* pCTM = m_pCTMSoftMask; - - // Исходное предобразование - // |1 0 0| |pCTM[0] pCTM[1] 0| - // arrMattrix = |0 -1 0| * |pCTM[2] pCTM[3] 0| - // |0 1 1| |pCTM[4] pCTM[5] 1| - - arrMatrix[0] = pCTM[0]; - arrMatrix[1] = -pCTM[1]; - arrMatrix[2] = -pCTM[2]; - arrMatrix[3] = -(-pCTM[3]); - arrMatrix[4] = pCTM[2] + pCTM[4]; - arrMatrix[5] = -(pCTM[3] + pCTM[5]) + pGState->getPageHeight(); - - double dShiftX = 0, dShiftY = 0; - DoTransform(arrMatrix, &dShiftX, &dShiftY, true); - m_pRenderer->DrawImage(&oImage, 0 + dShiftX, 0 + dShiftY, PDFCoordsToMM(1), PDFCoordsToMM(1)); - oImage.SaveFile(NSFile::GetProcessDirectory() + L"/res2.png", _CXIMAGE_FORMAT_PNG); - } - */ - m_pRenderer->put_BrushType(brush); pGState->clearPath(); return true; } - bool RendererOutputDev::RadialShadedFill(GfxState *pGState, GfxRadialShading *pShading) + bool RendererOutputDev::RadialShadedFill(GfxState* pGState, GfxRadialShading* pShading) { if (m_bDrawOnlyText) return true; - if (m_bTransparentGroupSoftMask || (!m_arrTransparentGroupSoftMask.empty() && m_bTransparentGroupSoftMaskEnd)) - return true; - - - DoPath(pGState, pGState->getPath(), pGState->getPageHeight(), pGState->getCTM()); long brush; @@ -3471,7 +1986,7 @@ namespace PdfReader NSStructures::GradientInfo info = NSStructures::GInfoConstructor::get_radial({x1, y1}, {x2, y2}, r1, r2, t0, t1, pShading->getExtend0(), pShading->getExtend1()); - GfxColorSpace *ColorSpace = pShading->getColorSpace();; + GfxColorSpace* ColorSpace = pShading->getColorSpace();; float delta = (t1 - t0) / info.shading.function.get_resolution(); float t = t0; for (size_t i = 0; i < info.shading.function.get_resolution(); i++) @@ -3486,24 +2001,19 @@ namespace PdfReader t+=delta; } - if (NSGraphics::IGraphicsRenderer* GRenderer = dynamic_cast(m_pRenderer)) - { - GRenderer->put_BrushGradInfo(info); - m_pRenderer->DrawPath(c_nWindingFillMode); - } + m_pRenderer->put_BrushGradInfo(&info); + m_pRenderer->DrawPath(c_nWindingFillMode); + m_pRenderer->EndCommand(c_nPathType); m_pRenderer->put_BrushType(brush); pGState->clearPath(); return true; } - bool RendererOutputDev::GouraundTriangleFill(GfxState *pGState, const std::vector &colors, const std::vector &points) + bool RendererOutputDev::GouraundTriangleFill(GfxState* pGState, const std::vector &colors, const std::vector &points) { if (m_bDrawOnlyText) return true; - if (m_bTransparentGroupSoftMask || (!m_arrTransparentGroupSoftMask.empty() && m_bTransparentGroupSoftMaskEnd)) - return true; - DoPath(pGState, pGState->getPath(), pGState->getPageHeight(), pGState->getCTM()); long brush; @@ -3531,24 +2041,19 @@ namespace PdfReader NSStructures::GradientInfo info = NSStructures::GInfoConstructor::get_triangle(pixel_points, rgba8_colors, {}, false); - if (NSGraphics::IGraphicsRenderer* GRenderer = dynamic_cast(m_pRenderer)) - { - GRenderer->put_BrushGradInfo(info); - m_pRenderer->DrawPath(c_nWindingFillMode); - } + m_pRenderer->put_BrushGradInfo(&info); + m_pRenderer->DrawPath(c_nWindingFillMode); + pGState->clearPath(); m_pRenderer->EndCommand(c_nPathType); m_pRenderer->put_BrushType(brush); return true; } - bool RendererOutputDev::PatchMeshFill(GfxState *pGState, GfxPatch *patch, GfxPatchMeshShading *pShading) + bool RendererOutputDev::PatchMeshFill(GfxState* pGState, GfxPatch* patch, GfxPatchMeshShading* pShading) { if (m_bDrawOnlyText) return true; - if (m_bTransparentGroupSoftMask || (!m_arrTransparentGroupSoftMask.empty() && m_bTransparentGroupSoftMaskEnd)) - return true; - DoPath(pGState, pGState->getPath(), pGState->getPageHeight(), pGState->getCTM()); long brush; @@ -3571,7 +2076,7 @@ namespace PdfReader } } std::vector> colors(2, std::vector(2)); - GfxDeviceRGBColorSpace ColorSpace; + GfxColorSpace* ColorSpace = pShading->getColorSpace(); for (int i = 0; i < 2; i ++) { for (int j = 0; j < 2; j++) @@ -3580,7 +2085,7 @@ namespace PdfReader pShading->getColor(patch->color[i][j], &c); GfxRGB draw_color; // RenderingIntent in this case does nothing but it's an obligatory arguments - ColorSpace.getRGB(&c, &draw_color, gfxRenderingIntentAbsoluteColorimetric); + ColorSpace->getRGB(&c, &draw_color, gfxRenderingIntentAbsoluteColorimetric); colors[j][i] = {colToByte(draw_color.b), colToByte(draw_color.g), colToByte(draw_color.r), (unsigned)alpha}; } } @@ -3590,51 +2095,40 @@ namespace PdfReader false ); - if (NSGraphics::IGraphicsRenderer* GRenderer = dynamic_cast(m_pRenderer)) - { - GRenderer->put_BrushGradInfo(info); - m_pRenderer->DrawPath(c_nWindingFillMode); - } + m_pRenderer->put_BrushGradInfo(&info); + m_pRenderer->DrawPath(c_nWindingFillMode); m_pRenderer->EndCommand(c_nPathType); m_pRenderer->put_BrushType(brush); pGState->clearPath(); return true; } - void RendererOutputDev::StartShadedFill(GfxState *pGState) + void RendererOutputDev::StartShadedFill() { - if (m_bDrawOnlyText) - return; - - m_pRenderer->BeginCommand(c_nComplexFigureType); + if (!m_bDrawOnlyText) + m_pRenderer->BeginCommand(c_nComplexFigureType); } void RendererOutputDev::EndShadedFill() { - if (m_bDrawOnlyText) - return; - - m_pRenderer->EndCommand(c_nComplexFigureType); + if (!m_bDrawOnlyText) + m_pRenderer->EndCommand(c_nComplexFigureType); } void RendererOutputDev::StartTilingFillIteration() { - if (m_bDrawOnlyText) - return; - - m_pRenderer->BeginCommand(c_nPDFTilingFillIteration); + if (!m_bDrawOnlyText) + m_pRenderer->BeginCommand(c_nPDFTilingFillIteration); } void RendererOutputDev::EndTilingFillIteration() { - if (m_bDrawOnlyText) - return; - - m_pRenderer->EndCommand(c_nPDFTilingFillIteration); + if (!m_bDrawOnlyText) + m_pRenderer->EndCommand(c_nPDFTilingFillIteration); } - void RendererOutputDev::StartSimpleTilingFill(GfxState *pGState, int nX0, int nY0, int nX1, int nY1, double dStepX, double dStepY, double dXMin, double dYMin, double dXMax, double dYMax, double* pMatrix) + void RendererOutputDev::StartSimpleTilingFill(GfxState* pGState, int nX0, int nY0, int nX1, int nY1, double dStepX, double dStepY, double dXMin, double dYMin, double dXMax, double dYMax, double* pMatrix) { if (m_bDrawOnlyText) return; - this->clipAttack(pGState); + UpdateAllClip(pGState); m_pRenderer->BeginCommand(c_nPDFTilingFill); @@ -3669,58 +2163,47 @@ namespace PdfReader } void RendererOutputDev::EndSimpleTilingFill() { - if (m_bDrawOnlyText) - return; - - m_pRenderer->EndCommand(c_nPDFTilingFill); + if (!m_bDrawOnlyText) + m_pRenderer->EndCommand(c_nPDFTilingFill); } - void RendererOutputDev::clip(GfxState *pGState) + void RendererOutputDev::clip(GfxState* pGState) { if (m_bDrawOnlyText) return; - if (m_sClip.empty()) - { - m_sClip.push_back(GfxClip()); - } - m_sClip.back().AddPath(pGState->getPath(), pGState->getCTM(), false); - m_bClipChanged = true; - updateClip(pGState); + if (!m_sStates.back().pClip) + m_sStates.back().pClip = new GfxClip(); + int nClipFlag = c_nClipRegionIntersect | c_nClipRegionTypeWinding; + m_sStates.back().pClip->AddPath(pGState->getPath(), pGState->getCTM(), nClipFlag); + AddClip(pGState, &m_sStates.back(), m_sStates.back().pClip->GetPathNum() - 1); } - void RendererOutputDev::eoClip(GfxState *pGState) + void RendererOutputDev::eoClip(GfxState* pGState) { if (m_bDrawOnlyText) return; - if (m_sClip.empty()) - { - m_sClip.push_back(GfxClip()); - } - m_sClip.back().AddPath(pGState->getPath(), pGState->getCTM(), true); - m_bClipChanged = true; - updateClip(pGState); + if (!m_sStates.back().pClip) + m_sStates.back().pClip = new GfxClip(); + int nClipFlag = c_nClipRegionIntersect | c_nClipRegionTypeEvenOdd; + m_sStates.back().pClip->AddPath(pGState->getPath(), pGState->getCTM(), nClipFlag); + AddClip(pGState, &m_sStates.back(), m_sStates.back().pClip->GetPathNum() - 1); } - void RendererOutputDev::clipToStrokePath(GfxState *pGState) + void RendererOutputDev::clipToStrokePath(GfxState* pGState) { if (m_bDrawOnlyText) return; - if (m_sClip.empty()) - { - m_sClip.push_back(GfxClip()); - } - m_sClip.back().AddPath(pGState->getPath(), pGState->getCTM(), false); - m_bClipChanged = true; - updateClip(pGState); + if (!m_sStates.back().pClip) + m_sStates.back().pClip = new GfxClip(); + int nClipFlag = c_nClipRegionIntersect | c_nClipRegionTypeWinding | c_nClipToStrokePath; + m_sStates.back().pClip->AddPath(pGState->getPath(), pGState->getCTM(), nClipFlag); + AddClip(pGState, &m_sStates.back(), m_sStates.back().pClip->GetPathNum() - 1); } - void RendererOutputDev::clipToPath(GfxState *pGState, GfxPath *pPath, double *pMatrix, bool bEO) + void RendererOutputDev::clipToPath(GfxState* pGState, GfxPath* pPath, double* pMatrix, bool bEO) { if (m_bDrawOnlyText) return; - if (m_bTransparentGroupSoftMask) - return; - int nClipFlag = bEO ? c_nClipRegionTypeEvenOdd : c_nClipRegionTypeWinding; nClipFlag |= c_nClipRegionIntersect; @@ -3730,14 +2213,11 @@ namespace PdfReader m_pRenderer->EndCommand(c_nPathType); m_pRenderer->EndCommand(c_nClipType); } - void RendererOutputDev::ClipToText(const std::wstring& wsFontName, const std::wstring& wsFontPath, double dFontSize, int nFontStyle, double *pMatrix, const std::wstring& wsText, double dX, double dY, double dWidth, double dHeight, double dBaseLineOffset) + void RendererOutputDev::ClipToText(const std::wstring& wsFontName, const std::wstring& wsFontPath, double dFontSize, int nFontStyle, double* pMatrix, const std::wstring& wsText, double dX, double dY, double dWidth, double dHeight, double dBaseLineOffset) { if (m_bDrawOnlyText) return; - if (m_bTransparentGroupSoftMask) - return; - m_pRenderer->put_FontName(wsFontName); m_pRenderer->put_FontPath(wsFontPath); m_pRenderer->put_FontSize(dFontSize); @@ -3762,31 +2242,20 @@ namespace PdfReader RELEASEARRAYOBJECTS(pGids); } } - void RendererOutputDev::endTextObject(GfxState *pGState) + void RendererOutputDev::endTextObject(GfxState* pGState) { - // if (NULL != m_pBufferTextClip) tmpchange - // { - // updateClip(pGState); - // - // RELEASEOBJECT(m_pBufferTextClip); - // } + if (m_sStates.back().pTextClip && 4 <= pGState->getRender()) + { + AddTextClip(pGState, &m_sStates.back()); + updateFont(pGState); + } } - void RendererOutputDev::beginStringOp(GfxState *pGState) + void RendererOutputDev::beginStringOp(GfxState* pGState) { - if (m_bTransparentGroupSoftMask) - return; - m_pRenderer->BeginCommand(c_nTextType); int nRenderMode = pGState->getRender(); - // Обработка Clip - // if (nRenderMode >= 4) tmpchange - // { - // RELEASEOBJECT(m_pBufferTextClip); - // m_pBufferTextClip = new GfxTextClip(); - // } - // Обработка Stroke if (1 == nRenderMode || 2 == nRenderMode || 5 == nRenderMode || 6 == nRenderMode) { @@ -3801,19 +2270,14 @@ namespace PdfReader // ::SysFreeString( bsPen ); } } - void RendererOutputDev::endStringOp(GfxState *pGState) + void RendererOutputDev::endStringOp(GfxState* pGState) { - if (m_bTransparentGroupSoftMask) - return; int nRenderMode = pGState->getRender(); // Добавляем в Clipping Path текст if (nRenderMode >= 4) { - // if (m_pBufferTextClip) tmpchange - // pGState->GetClip()->AppendTextClip(m_pBufferTextClip); - updateFont(pGState); } @@ -3827,11 +2291,8 @@ namespace PdfReader m_pRenderer->EndCommand(c_nTextType); } - void RendererOutputDev::drawString(GfxState *pGState, GString *seString) + void RendererOutputDev::drawString(GfxState* pGState, GString* seString) { - if (m_bTransparentGroupSoftMask) - return; - // Проверяем наличие списка со шрифтами if (NULL == m_pFontList) return; @@ -3846,9 +2307,9 @@ namespace PdfReader if (3 == nRendererMode) // Невидимый текст return; - double *pCTM = pGState->getCTM(); - double *pTm = pGState->getTextMat(); - GfxFont *pFont = pGState->getFont(); + double* pCTM = pGState->getCTM(); + double* pTm = pGState->getTextMat(); + GfxFont* pFont = pGState->getFont(); unsigned int unGidsCount = seString->getLength(); unsigned int* pGids = new unsigned int[unGidsCount]; @@ -3876,11 +2337,8 @@ namespace PdfReader m_pRenderer->CommandDrawTextEx(wsUnicodeText, pGids, unGidsCount, PDFCoordsToMM(100), PDFCoordsToMM(100), 0, PDFCoordsToMM(0)); RELEASEARRAYOBJECTS(pGids); } - void RendererOutputDev::drawChar(GfxState *pGState, double dX, double dY, double dDx, double dDy, double dOriginX, double dOriginY, CharCode nCode, int nBytesCount, Unicode *pUnicode, int nUnicodeLen) + void RendererOutputDev::drawChar(GfxState* pGState, double dX, double dY, double dDx, double dDy, double dOriginX, double dOriginY, CharCode nCode, int nBytesCount, Unicode* pUnicode, int nUnicodeLen) { - if (m_bTransparentGroupSoftMask) - return; - // Проверяем наличие списка со шрифтами if (NULL == m_pFontList) return; @@ -3890,40 +2348,40 @@ namespace PdfReader if (!m_pFontList->GetFont(pGState->getFont()->getID(), &oEntry)) return; - int nRenderMode = pGState->getRender(); - - if (3 == nRenderMode) // Невидимый текст + int nRenderMode = pGState->getRender(); + if (3 == nRenderMode && !m_bDrawOnlyText) // Невидимый текст { return; } - double *pCTM = pGState->getCTM(); - double *pTm = pGState->getTextMat(); - GfxFont *pFont = pGState->getFont(); + double* pCTM = pGState->getCTM(); + double* pTm = pGState->getTextMat(); + GfxFont* pFont = pGState->getFont(); double pNewTm[6], arrMatrix[6]; double dTextScale = std::min(sqrt(pTm[2] * pTm[2] + pTm[3] * pTm[3]), sqrt(pTm[0] * pTm[0] + pTm[1] * pTm[1])); double dITextScale = 1 / dTextScale; - double dOldSize = 10.0; + double dOldSize = 10.0, dOldWidth = 1.0; m_pRenderer->get_FontSize(&dOldSize); + m_pRenderer->get_PenSize(&dOldWidth); if (dOldSize * dTextScale > 0) { m_pRenderer->put_FontSize(dOldSize * dTextScale); - pNewTm[0] = pTm[0] * dITextScale; - pNewTm[1] = pTm[1] * dITextScale; + pNewTm[0] = pTm[0] * dITextScale * pGState->getHorizScaling(); + pNewTm[1] = pTm[1] * dITextScale * pGState->getHorizScaling(); pNewTm[2] = -pTm[2] * dITextScale; pNewTm[3] = -pTm[3] * dITextScale; - pNewTm[4] = dX; - pNewTm[5] = dY; + pNewTm[4] = dX - dOriginX; + pNewTm[5] = dY - dOriginY; } else { m_pRenderer->put_FontSize(-dOldSize * dTextScale); - pNewTm[0] = pTm[0] * dITextScale; - pNewTm[1] = pTm[1] * dITextScale; + pNewTm[0] = -pTm[0] * dITextScale * pGState->getHorizScaling(); + pNewTm[1] = -pTm[1] * dITextScale * pGState->getHorizScaling(); pNewTm[2] = pTm[2] * dITextScale; pNewTm[3] = pTm[3] * dITextScale; pNewTm[4] = dX; @@ -3951,6 +2409,8 @@ namespace PdfReader double dSize = 1; m_pRenderer->get_FontSize(&dSize); m_pRenderer->put_FontSize(dSize * dNorma); + if (nRenderMode == 1 || nRenderMode == 2 || nRenderMode == 5 || nRenderMode == 6) + m_pRenderer->put_PenSize(PDFCoordsToMM(pGState->getLineWidth() * dNorma)); } } @@ -3966,20 +2426,23 @@ namespace PdfReader if (NULL != oEntry.pCodeToUnicode && nCode < oEntry.unLenUnicode) { - unsigned short unUnicode = oEntry.pCodeToUnicode[nCode]; - wsUnicodeText = (wchar_t(unUnicode)); + int unUnicode = oEntry.pCodeToUnicode[nCode]; + wsUnicodeText = NSStringExt::CConverter::GetUnicodeFromUTF32((const unsigned int*)(&unUnicode), 1); } else { if (isCIDFont) { - // Значит кодировка была Identity-H или Identity-V, что означает, что иходные коды и есть юникодные значения + // Значит кодировка была Identity-H или Identity-V, что означает, что исходные коды и есть юникодные значения wsUnicodeText = (wchar_t(nCode)); } else { // Договорились, что если нельзя точно составить юникодные значения, тогда отдаем NULL - wsUnicodeText = L""; + if (pFont->getType() == fontType3) + wsUnicodeText = NSStringExt::CConverter::GetUnicodeFromUTF32(pUnicode, nUnicodeLen); + else + wsUnicodeText = L""; } } @@ -4003,17 +2466,18 @@ namespace PdfReader } } - if (nRenderMode == 0 || nRenderMode == 4 || nRenderMode == 6) + if (nRenderMode == 0 || nRenderMode == 4 || nRenderMode == 6 || m_bDrawOnlyText) { -#ifdef BUILDING_WASM_MODULE + bool bReplace = false; std::wstring sFontPath; +#ifdef BUILDING_WASM_MODULE m_pRenderer->get_FontPath(&sFontPath); if (!unGid && !wsUnicodeText.empty() && !sFontPath.empty()) { unsigned int lUnicode = (unsigned int)wsUnicodeText[0]; long lStyle; m_pRenderer->get_FontStyle(&lStyle); - m_pFontManager->LoadFontFromFile(sFontPath, 0, 10, 72, 72); + m_pFontManager->LoadFontFromFile(sFontPath, 0, dOldSize, 72, 72); NSFonts::IFontFile* pFontFile = m_pFontManager->GetFile(); if (pFontFile) @@ -4049,22 +2513,49 @@ namespace PdfReader return; } m_pRenderer->put_FontPath(wsFileName); - sFontPath = wsFileName; + bReplace = true; } } } } - if (((GlobalParamsAdaptor*)globalParams)->getDrawFormField()) +#endif + m_pRenderer->CommandDrawTextEx(wsUnicodeText, &unGid, unGidsCount, PDFCoordsToMM(dShiftX), PDFCoordsToMM(dShiftY), PDFCoordsToMM(dDx), PDFCoordsToMM(dDy)); + if (bReplace) + m_pRenderer->put_FontPath(sFontPath); + } + + LONG lRendererType = 0; + m_pRenderer->get_Type(&lRendererType); + + bool bIsEmulateBold = false; + if (c_nDocxWriter == lRendererType && 2 == nRenderMode) + bIsEmulateBold = (S_OK == m_pRenderer->CommandLong(c_nSupportPathTextAsText, 0)) ? true : false; + + if (bIsEmulateBold) + { + m_pRenderer->BeginCommand(c_nStrokeTextType); + + LONG lOldStyle = 0; + m_pRenderer->get_FontStyle(&lOldStyle); + LONG lNewStyle = lOldStyle; + + if ((lNewStyle & 0x01) == 0) { - double dFontSize; - m_pRenderer->get_FontSize(&dFontSize); - ((GlobalParamsAdaptor*)globalParams)->AddTextFormField(wsUnicodeText, sFontPath, dFontSize); + lNewStyle |= 0x01; + m_pRenderer->put_FontStyle(lNewStyle); } -#endif - m_pRenderer->CommandDrawTextEx(wsUnicodeText, &unGid, unGidsCount, PDFCoordsToMM(dShiftX), PDFCoordsToMM(dShiftY), PDFCoordsToMM(dDx), PDFCoordsToMM(dDy)); - } - if (nRenderMode == 1 || nRenderMode == 2 || nRenderMode == 5 || nRenderMode == 6) + if (unGid) + m_pRenderer->CommandDrawTextEx(wsUnicodeText, &unGid, unGidsCount, PDFCoordsToMM(dShiftX), PDFCoordsToMM(dShiftY), PDFCoordsToMM(dDx), PDFCoordsToMM(dDy)); + else + m_pRenderer->CommandDrawText(wsUnicodeText, PDFCoordsToMM(dShiftX), PDFCoordsToMM(dShiftY), PDFCoordsToMM(dDx), PDFCoordsToMM(dDy)); + + if (lOldStyle != lNewStyle) + m_pRenderer->put_FontStyle(lOldStyle); + + m_pRenderer->EndCommand(c_nStrokeTextType); + } + else if (nRenderMode == 1 || nRenderMode == 2 || nRenderMode == 5 || nRenderMode == 6) { m_pRenderer->BeginCommand(c_nStrokeTextType); @@ -4077,7 +2568,6 @@ namespace PdfReader long lDrawPath = c_nStroke; if (nRenderMode == 2) lDrawPath |= c_nWindingFillMode; - m_pRenderer->DrawPath(lDrawPath); m_pRenderer->EndCommand(c_nStrokeTextType); @@ -4093,47 +2583,98 @@ namespace PdfReader m_pRenderer->get_FontPath(&wsTempFontPath); m_pRenderer->get_FontSize(&dTempFontSize); m_pRenderer->get_FontStyle(&lTempFontStyle); - // tmpchange - if (m_sClip.empty()) - { - m_sClip.push_back(GfxClip()); - } - m_sClip.back().GetTextClip()->ClipToText(wsTempFontName, wsTempFontPath, dTempFontSize, (int)lTempFontStyle, arrMatrix, wsClipText, 0 + dShiftX, /*-fabs(pFont->getFontBBox()[3]) * dTfs*/ + dShiftY, 0, 0, 0); - m_bClipChanged = true; + // tmpchange + if (!m_sStates.back().pTextClip) + m_sStates.back().pTextClip = new GfxTextClip(); + m_sStates.back().pTextClip->ClipToText(wsTempFontName, wsTempFontPath, dTempFontSize, (int)lTempFontStyle, arrMatrix, wsClipText, dShiftX, /*-fabs(pFont->getFontBBox()[3]) * dTfs + */ dShiftY, 0, 0, 0); } m_pRenderer->put_FontSize(dOldSize); + m_pRenderer->put_PenSize(dOldWidth); } - void RendererOutputDev::endType3Char(GfxState *pGState) + GBool RendererOutputDev::beginType3Char(GfxState* state, double x, double y, double dx, double dy, CharCode code, Unicode* u, int uLen) { - return; + if (!m_bDrawOnlyText) + return false; + + //drawChar(state, x, y, dx, dy, 0, 0, code, 1, u, uLen); + + return false; } - void RendererOutputDev::Type3D0(GfxState *pGState, double dWx, double dWy) + void RendererOutputDev::endType3Char(GfxState* pGState) { return; } - void RendererOutputDev::Type3D1(GfxState *pGState, double dWx, double dWy, double dBLx, double dBLy, double dTRx, double dTRy) + GBool RendererOutputDev::beginMarkedContent(GfxState* state, GString* s) { - return; + return gFalse; } - void RendererOutputDev::drawImageMask(GfxState *pGState, Object *pRef, Stream *pStream, int nWidth, int nHeight,GBool bInvert, GBool bInlineImage, GBool interpolate) + GBool RendererOutputDev::beginMCOShapes(GfxState* state, GString* s, Object* ref) { - if (m_bDrawOnlyText) - return; + IAdvancedCommand::AdvancedCommandType eAdvancedCommandType = IAdvancedCommand::AdvancedCommandType::ShapeStart; + if (m_pRenderer->IsSupportAdvancedCommand(eAdvancedCommandType) == S_OK) + { + CShapeStart* pCommand = new CShapeStart(); + pCommand->SetShapeXML(s->getCString()); - if (pGState->getFillColorSpace()->isNonMarking()) + Object oIm; + if (ref && ref->isRef() && ref->fetch(m_pXref, &oIm)->isStream()) + { + Dict* oImDict = oIm.streamGetDict(); + + int nLength = 0; + Object oLength; + if (oImDict->lookup("Length", &oLength)->isInt()) + nLength = oLength.getInt(); + oLength.free(); + if (oImDict->lookup("DL", &oLength)->isInt()) + nLength = oLength.getInt(); + oLength.free(); + + Stream* pImage = oIm.getStream()->getUndecodedStream(); + pImage->reset(); + + BYTE* pBuffer = new BYTE[nLength]; + BYTE* pBufferPtr = pBuffer; + for (int nI = 0; nI < nLength; ++nI) + *pBufferPtr++ = (BYTE)pImage->getChar(); + + CBgraFrame oFrame; + if (oFrame.Decode(pBuffer, nLength)) + { + pCommand->SetShapeImage(oFrame.get_Data(), oFrame.get_Width(), oFrame.get_Height()); + oFrame.ClearNoAttack(); + } + } + oIm.free(); + bool bRes = m_pRenderer->AdvancedCommand(pCommand) == S_OK; + RELEASEOBJECT(pCommand); + if (bRes) + return gTrue; + } + return gFalse; + } + void RendererOutputDev::endMarkedContent(GfxState* state) + { + IAdvancedCommand::AdvancedCommandType eAdvancedCommandType = IAdvancedCommand::AdvancedCommandType::ShapeEnd; + if (m_pRenderer->IsSupportAdvancedCommand(eAdvancedCommandType) == S_OK) { - return; + CEmptyComand* pCommand = new CEmptyComand(IAdvancedCommand::AdvancedCommandType::ShapeEnd); + m_pRenderer->AdvancedCommand(pCommand); + RELEASEOBJECT(pCommand); } - - double dPageHeight = pGState->getPageHeight(); + } + void RendererOutputDev::drawImageMask(GfxState* pGState, Object* pRef, Stream* pStream, int nWidth, int nHeight, GBool bInvert, GBool bInlineImage, GBool interpolate) + { + if (m_bDrawOnlyText || pGState->getFillColorSpace()->isNonMarking()) + return; int nBufferSize = 4 * nWidth * nHeight; if (nBufferSize < 1) return; - unsigned char *pBufferPtr = new(std::nothrow) unsigned char[nBufferSize]; + BYTE* pBufferPtr = new(std::nothrow) BYTE[nBufferSize]; if (!pBufferPtr) return; @@ -4141,88 +2682,86 @@ namespace PdfReader oImage.Create(pBufferPtr, nWidth, nHeight, -4 * nWidth); // Пишем данные в pBufferPtr - ImageStream *pImageStream = new ImageStream(pStream, nWidth, 1, 1); - + ImageStream* pImageStream = new ImageStream(pStream, nWidth, 1, 1); pImageStream->reset(); GfxColorSpace* pColorSpace = pGState->getFillColorSpace(); GfxRGB oRGB; pColorSpace->getRGB(pGState->getFillColor(), &oRGB, GfxRenderingIntent::gfxRenderingIntentAbsoluteColorimetric); - unsigned char r = colToByte(oRGB.r); - unsigned char g = colToByte(oRGB.g); - unsigned char b = colToByte(oRGB.b); + BYTE r = colToByte(oRGB.r); + BYTE g = colToByte(oRGB.g); + BYTE b = colToByte(oRGB.b); + BYTE unAlpha = std::min(255, std::max(0, int(pGState->getFillOpacity() * 255))); + int nInvert = bInvert ? 1 : 0; - unsigned char unAlpha = m_bTransparentGroup ? (m_bIsolatedTransparentGroup ? 0 : 255.0 * pGState->getFillOpacity()) : 255; - int nInvert = (bInvert ? 1 : 0); - for (int nY = nHeight - 1; nY >= 0; nY--) + for (int nY = nHeight - 1; nY >= 0; --nY) { - unsigned char *pMask = NULL; - int nX = 0; - for (nX = 0, pMask = pImageStream->getLine(); nX < nWidth; nX++) + BYTE* pMask = pImageStream->getLine(); + int nIndex = 4 * nY * nWidth; + for (int nX = 0; nX < nWidth; ++nX) { - int nIndex = 4 * (nX + nY * nWidth); - unsigned char unPixel = *pMask++ ^ nInvert; - pBufferPtr[nIndex + 0] = unPixel ? 255 : b; - pBufferPtr[nIndex + 1] = unPixel ? 255 : g; - pBufferPtr[nIndex + 2] = unPixel ? 255 : r; - pBufferPtr[nIndex + 3] = unPixel ? 0 : unAlpha; + BYTE unPixel = *pMask++ ^ nInvert; + if (unPixel) + { + pBufferPtr[nIndex + 0] = 255; + pBufferPtr[nIndex + 1] = 255; + pBufferPtr[nIndex + 2] = 255; + pBufferPtr[nIndex + 3] = 0; + } + else + { + pBufferPtr[nIndex + 0] = b; + pBufferPtr[nIndex + 1] = g; + pBufferPtr[nIndex + 2] = r; + pBufferPtr[nIndex + 3] = unAlpha; + } + nIndex += 4; } } delete pImageStream; double arrMatrix[6]; - double *pCTM = pGState->getCTM(); + double* pCTM = pGState->getCTM(); // Исходное предобразование // |1 0 0| |pCTM[0] pCTM[1] 0| // arrMattrix = |0 -1 0| * |pCTM[2] pCTM[3] 0| // |0 1 1| |pCTM[4] pCTM[5] 1| - arrMatrix[0] = pCTM[0]; - arrMatrix[1] = -pCTM[1]; - arrMatrix[2] = -pCTM[2]; - arrMatrix[3] = -(-pCTM[3]); - arrMatrix[4] = pCTM[2] + pCTM[4]; - arrMatrix[5] = -(pCTM[3] + pCTM[5]) + dPageHeight; + arrMatrix[0] = pCTM[0]; + arrMatrix[1] = -pCTM[1]; + arrMatrix[2] = -pCTM[2]; + arrMatrix[3] = pCTM[3]; + arrMatrix[4] = pCTM[2] + pCTM[4]; + arrMatrix[5] = -(pCTM[3] + pCTM[5]) + pGState->getPageHeight(); double dShiftX = 0, dShiftY = 0; DoTransform(arrMatrix, &dShiftX, &dShiftY, true); - m_pRenderer->DrawImage(&oImage, 0 + dShiftX, 0 + dShiftY, PDFCoordsToMM(1), PDFCoordsToMM(1)); + m_pRenderer->DrawImage(&oImage, dShiftX, dShiftY, PDFCoordsToMM(1), PDFCoordsToMM(1)); } - void RendererOutputDev::setSoftMaskFromImageMask(GfxState *pGState, Object *pRef, Stream *pStream, int nWidth, int nHeight, GBool bInvert, GBool bInlineImage, GBool interpolate) + void RendererOutputDev::setSoftMaskFromImageMask(GfxState* pGState, Object* pRef, Stream* pStream, int nWidth, int nHeight, GBool bInvert, GBool bInlineImage, GBool interpolate) { - if (m_bDrawOnlyText) + if (m_bDrawOnlyText || pGState->getFillColorSpace()->isNonMarking()) return; - if (pGState->getFillColorSpace()->isNonMarking()) - { - return; - } - - double dPageHeight = pGState->getPageHeight(); - int nBufferSize = 4 * nWidth * nHeight; if (nBufferSize < 1) return; - unsigned char *pBufferPtr = new(std::nothrow) unsigned char[nBufferSize]; + BYTE* pBufferPtr = new(std::nothrow) BYTE[nBufferSize]; if (!pBufferPtr) return; - /* - RELEASEARRAYOBJECTS(m_pSoftMask); - m_pSoftMask = pBufferPtr; - m_nSoftMaskWidth = nWidth; - m_nSoftMaskHeight = nHeight; - */ + + double bbox[4] = { 0, 0, 1, 1 }; + beginTransparencyGroup(pGState, bbox, pGState->getFillColorSpace(), true, false, true); Aggplus::CImage oImage; oImage.Create(pBufferPtr, nWidth, nHeight, -4 * nWidth, true); // Пишем данные в pBufferPtr - ImageStream *pImageStream = new ImageStream(pStream, nWidth, 1, 1); - + ImageStream* pImageStream = new ImageStream(pStream, nWidth, 1, 1); pImageStream->reset(); GfxColorSpace* pColorSpace = pGState->getFillColorSpace(); @@ -4231,30 +2770,39 @@ namespace PdfReader GfxPattern* pPattern = pGState->getFillPattern(); if (pPattern && pPattern->getType() == 2) { - GfxShading *pShading = ((GfxShadingPattern*)pPattern)->getShading(); + GfxShading* pShading = ((GfxShadingPattern*)pPattern)->getShading(); pColorSpace = pShading->getColorSpace(); if (pShading->getHasBackground()) pColorSpace->getRGB(pShading->getBackground(), &oRGB, GfxRenderingIntent::gfxRenderingIntentAbsoluteColorimetric); } - unsigned char r = colToByte(oRGB.r); - unsigned char g = colToByte(oRGB.g); - unsigned char b = colToByte(oRGB.b); + BYTE r = colToByte(oRGB.r); + BYTE g = colToByte(oRGB.g); + BYTE b = colToByte(oRGB.b); + BYTE unAlpha = std::min(255, std::max(0, int(pGState->getFillOpacity() * 255))); + int nInvert = bInvert ? 1 : 0; - double dAlphaKoef = m_bTransparentGroup ? (m_bIsolatedTransparentGroup ? 0 : pGState->getFillOpacity()) : 1; - int nInvert = (bInvert ? 1 : 0); - for (int nY = nHeight - 1; nY >= 0; nY--) + for (int nY = nHeight - 1; nY >= 0; --nY) { - unsigned char *pMask = NULL; - int nX = 0; + BYTE* pMask = pImageStream->getLine(); int nIndex = 4 * nY * nWidth; - for (nX = 0, pMask = pImageStream->getLine(); nX < nWidth; nX++) + for (int nX = 0; nX < nWidth; ++nX) { - unsigned char unPixel = *pMask++ ^ nInvert; - pBufferPtr[nIndex + 0] = unPixel ? 255 : b; - pBufferPtr[nIndex + 1] = unPixel ? 255 : g; - pBufferPtr[nIndex + 2] = unPixel ? 255 : r; - pBufferPtr[nIndex + 3] = unPixel ? 0 : (unsigned char)(255.0 * dAlphaKoef); + BYTE unPixel = *pMask++ ^ nInvert; + if (unPixel) + { + pBufferPtr[nIndex + 0] = 255; + pBufferPtr[nIndex + 1] = 255; + pBufferPtr[nIndex + 2] = 255; + pBufferPtr[nIndex + 3] = 0; + } + else + { + pBufferPtr[nIndex + 0] = b; + pBufferPtr[nIndex + 1] = g; + pBufferPtr[nIndex + 2] = r; + pBufferPtr[nIndex + 3] = unAlpha; + } nIndex += 4; } } @@ -4262,26 +2810,28 @@ namespace PdfReader delete pImageStream; double arrMatrix[6]; - double *pCTM = pGState->getCTM(); + double* pCTM = pGState->getCTM(); // Исходное предобразование // |1 0 0| |pCTM[0] pCTM[1] 0| // arrMattrix = |0 -1 0| * |pCTM[2] pCTM[3] 0| // |0 1 1| |pCTM[4] pCTM[5] 1| - arrMatrix[0] = pCTM[0]; - arrMatrix[1] = -pCTM[1]; - arrMatrix[2] = -pCTM[2]; - arrMatrix[3] = -(-pCTM[3]); - arrMatrix[4] = pCTM[2] + pCTM[4]; - arrMatrix[5] = -(pCTM[3] + pCTM[5]) + dPageHeight; + arrMatrix[0] = pCTM[0]; + arrMatrix[1] = -pCTM[1]; + arrMatrix[2] = -pCTM[2]; + arrMatrix[3] = pCTM[3]; + arrMatrix[4] = pCTM[2] + pCTM[4]; + arrMatrix[5] = -(pCTM[3] + pCTM[5]) + pGState->getPageHeight(); double dShiftX = 0, dShiftY = 0; DoTransform(arrMatrix, &dShiftX, &dShiftY, true); - m_pRenderer->DrawImage(&oImage, 0 + dShiftX, 0 + dShiftY, PDFCoordsToMM(1), PDFCoordsToMM(1)); + m_pRenderer->DrawImage(&oImage, dShiftX, dShiftY, PDFCoordsToMM(1), PDFCoordsToMM(1)); + + setSoftMask(pGState, bbox, 0, NULL, NULL); } - OO_INLINE bool CheckMask(const int& nComponentsCount, const int* pMaskColors, const unsigned char* pLine) + OO_INLINE bool CheckMask(const int& nComponentsCount, const int* pMaskColors, const BYTE* pLine) { bool isMask = true; for (int nCompIndex = 0; nCompIndex < nComponentsCount; ++nCompIndex) @@ -4292,113 +2842,154 @@ namespace PdfReader break; } } - return isMask; } - void RendererOutputDev::drawImage(GfxState *pGState, Object *pRef, Stream *pStream, int nWidth, int nHeight, GfxImageColorMap *pColorMap, int *pMaskColors, GBool bInlineImg, GBool interpolate) + bool RendererOutputDev::ReadImage(Aggplus::CImage* pImageRes, Object* pRef, Stream* pStream) { - if (m_bDrawOnlyText) - return; + Object oIm; + int nLength = 0; + if (pRef && pRef->isRef() && pRef->fetch(m_pXref, &oIm)->isStream()) + { + Object oLength; + if (oIm.streamGetDict()->lookup("Length", &oLength)->isInt()) + nLength = oLength.getInt(); + oLength.free(); + } + oIm.free(); + if (!nLength) + return false; - double dPageHeight = pGState->getPageHeight(); + BYTE* pBuffer = new BYTE[nLength]; + Stream* pS = pStream->getUndecodedStream(); + pS->reset(); + nLength = pS->getBlock((char*)pBuffer, nLength); + if (!nLength) + { + RELEASEARRAYOBJECTS(pBuffer); + return false; + } - int nBufferSize = 4 * nWidth * nHeight; - if (nBufferSize < 1) - return; + CBgraFrame oFrame; + if (oFrame.Decode(pBuffer, nLength, _CXIMAGE_FORMAT_JPG)) + { + pImageRes->Create(oFrame.get_Data(), oFrame.get_Width(), oFrame.get_Height(), -4 * oFrame.get_Width()); + oFrame.ClearNoAttack(); + RELEASEARRAYOBJECTS(pBuffer); + return true; + } - unsigned char *pBufferPtr = new(std::nothrow) unsigned char[nBufferSize]; - if (!pBufferPtr) + RELEASEARRAYOBJECTS(pBuffer); + return false; + } + void RendererOutputDev::drawImage(GfxState* pGState, Object* pRef, Stream* pStream, int nWidth, int nHeight, GfxImageColorMap* pColorMap, int* pMaskColors, GBool bInlineImg, GBool interpolate) + { + if (m_bDrawOnlyText) return; + Aggplus::CImage oImage; + StreamKind nSK = pStream->getKind(); int nComponentsCount = pColorMap->getNumPixelComps(); - // Пишем данные в pBufferPtr - ImageStream *pImageStream = new ImageStream(pStream, nWidth, nComponentsCount, pColorMap->getBits()); - pImageStream->reset(); + // Чтение jpeg через cximage происходит быстрее чем через xpdf на ~40% + if (pMaskColors || (nSK != strDCT || nComponentsCount != 3 || !ReadImage(&oImage, pRef, pStream))) + { + int nBufferSize = 4 * nWidth * nHeight; + if (nBufferSize < 1) + return; - bool bTransperent = false; - for (const bool& b : m_arrTransparentGroupSoftMask) - bTransperent = b || bTransperent; - unsigned char unAlpha = m_bTransparentGroup ? ((m_bIsolatedTransparentGroup && bTransperent) ? 0 : 255.0 * pGState->getFillOpacity()) : 255; + BYTE* pBufferPtr = new(std::nothrow) BYTE[nBufferSize]; + if (!pBufferPtr) + return; - int nStride = pImageStream->getVals(); - int nComps = pImageStream->getComps(); - int nWidthMax = nStride / nComps; - int nCheckWidth = std::min(nWidth, nWidthMax); + // Пишем данные в pBufferPtr + ImageStream* pImageStream = new ImageStream(pStream, nWidth, nComponentsCount, pColorMap->getBits()); + pImageStream->reset(); - // fast realization for some colorspaces (for wasm module) - int nColorMapType = pColorMap->getFillType(); - GfxColorComp** pColorMapLookup = pColorMap->getLookup(); - if (!pColorMapLookup) - nColorMapType = 0; + BYTE unAlpha = std::min(255, std::max(0, int(pGState->getFillOpacity() * 255))); + int nComps = pImageStream->getComps(); + int nCheckWidth = std::min(nWidth, pImageStream->getVals() / nComps); + GfxRenderingIntent intent = pGState->getRenderingIntent(); - for (int nY = nHeight - 1; nY >= 0; --nY) - { - unsigned char* pLine = pImageStream->getLine(); - unsigned char* pLineDst = pBufferPtr + 4 * nWidth * nY; + // fast realization for some colorspaces (for wasm module) + int nColorMapType = pColorMap->getFillType(); + GfxColorComp** pColorMapLookup = pColorMap->getLookup(); + if (!pColorMapLookup) + nColorMapType = 0; - if (!pLine) + for (int nY = nHeight - 1; nY >= 0; --nY) { - memset(pLineDst, 0, 4 * nWidth); - continue; - } + BYTE* pLine = pImageStream->getLine(); + BYTE* pLineDst = pBufferPtr + 4 * nWidth * nY; - for (int nX = 0; nX < nCheckWidth; ++nX) - { - if (2 == nColorMapType) - { - pLineDst[2] = colToByte(clip01(pColorMapLookup[0][pLine[0]])); - pLineDst[1] = colToByte(clip01(pColorMapLookup[1][pLine[1]])); - pLineDst[0] = colToByte(clip01(pColorMapLookup[2][pLine[2]])); - } - else if (1 == nColorMapType) + if (!pLine) { - pLineDst[0] = pLineDst[1] = pLineDst[2] = colToByte(clip01(pColorMapLookup[0][pLine[0]])); + memset(pLineDst, 0, 4 * nWidth); + continue; } - else + + for (int nX = 0; nX < nCheckWidth; ++nX) { - GfxRGB oRGB; - pColorMap->getRGB(pLine, &oRGB, gfxRenderingIntentAbsoluteColorimetric); - pLineDst[0] = colToByte(oRGB.b); - pLineDst[1] = colToByte(oRGB.g); - pLineDst[2] = colToByte(oRGB.r); - } + if (2 == nColorMapType) + { + pLineDst[2] = colToByte(clip01(pColorMapLookup[0][pLine[0]])); + pLineDst[1] = colToByte(clip01(pColorMapLookup[1][pLine[1]])); + pLineDst[0] = colToByte(clip01(pColorMapLookup[2][pLine[2]])); + } + else if (1 == nColorMapType) + { + pLineDst[0] = pLineDst[1] = pLineDst[2] = colToByte(clip01(pColorMapLookup[0][pLine[0]])); + } + else if (3 == nColorMapType) + { + pLineDst[2] = colToByte(clip01(pColorMapLookup[0][pLine[0]])); + pLineDst[1] = colToByte(clip01(pColorMapLookup[1][pLine[1]])); + pLineDst[0] = colToByte(clip01(pColorMapLookup[2][pLine[2]])); + pLineDst[3] = colToByte(clip01(pColorMapLookup[3][pLine[3]])); + } + else + { + GfxRGB oRGB; + pColorMap->getRGB(pLine, &oRGB, intent); + pLineDst[0] = colToByte(oRGB.b); + pLineDst[1] = colToByte(oRGB.g); + pLineDst[2] = colToByte(oRGB.r); + } - if (pMaskColors && CheckMask(nComponentsCount, pMaskColors, pLine)) - pLineDst[3] = 0; - else - pLineDst[3] = unAlpha; + if (pMaskColors && CheckMask(nComponentsCount, pMaskColors, pLine)) + pLineDst[3] = 0; + else if (3 != nColorMapType) + pLineDst[3] = unAlpha; - pLine += nComps; - pLineDst += 4; + pLine += nComps; + pLineDst += 4; + } } - } - Aggplus::CImage oImage; - oImage.Create(pBufferPtr, nWidth, nHeight, -4 * nWidth); + pImageStream->close(); + delete pImageStream; - pImageStream->close(); - delete pImageStream; + oImage.Create(pBufferPtr, nWidth, nHeight, -4 * nWidth); + } double arrMatrix[6]; - double *pCTM = pGState->getCTM(); + double* pCTM = pGState->getCTM(); // Исходное предобразование // |1 0 0| |pCTM[0] pCTM[1] 0| // arrMatrix = |0 -1 0| * |pCTM[2] pCTM[3] 0| // |0 1 1| |pCTM[4] pCTM[5] 1| - arrMatrix[0] = pCTM[0]; - arrMatrix[1] = -pCTM[1]; - arrMatrix[2] = -pCTM[2]; - arrMatrix[3] = -(-pCTM[3]); - arrMatrix[4] = pCTM[2] + pCTM[4]; - arrMatrix[5] = -(pCTM[3] + pCTM[5]) + dPageHeight; + arrMatrix[0] = pCTM[0]; + arrMatrix[1] = -pCTM[1]; + arrMatrix[2] = -pCTM[2]; + arrMatrix[3] = pCTM[3]; + arrMatrix[4] = pCTM[2] + pCTM[4]; + arrMatrix[5] = -(pCTM[3] + pCTM[5]) + pGState->getPageHeight(); double dShiftX = 0, dShiftY = 0; DoTransform(arrMatrix, &dShiftX, &dShiftY, true); - m_pRenderer->DrawImage(&oImage, 0 + dShiftX, 0 + dShiftY, PDFCoordsToMM(1), PDFCoordsToMM(1)); + m_pRenderer->DrawImage(&oImage, dShiftX, dShiftY, PDFCoordsToMM(1), PDFCoordsToMM(1)); } - void RendererOutputDev::drawMaskedImage(GfxState *pGState, Object *pRef, Stream *pStream, int nWidth, int nHeight, GfxImageColorMap *pColorMap, Object* pStreamRef, Stream *pMaskStream, int nMaskWidth, int nMaskHeight, GBool bMaskInvert, GBool interpolate) + void RendererOutputDev::drawMaskedImage(GfxState* pGState, Object* pRef, Stream* pStream, int nWidth, int nHeight, GfxImageColorMap* pColorMap, Object* pStreamRef, Stream* pMaskStream, int nMaskWidth, int nMaskHeight, GBool bMaskInvert, GBool interpolate) { if (m_bDrawOnlyText) return; @@ -4411,7 +3002,7 @@ namespace PdfReader // If the mask is higher resolution than the image, use // drawSoftMaskedImage() instead. - GfxImageColorMap *maskColorMap; + GfxImageColorMap* maskColorMap; Object maskDecode, decodeLow, decodeHigh; decodeLow.initInt(bMaskInvert ? 0 : 1); @@ -4433,7 +3024,7 @@ namespace PdfReader if (nBufferSize < 1) return; - unsigned char *pBufferPtr = new(std::nothrow) unsigned char[nBufferSize]; + BYTE* pBufferPtr = new(std::nothrow) BYTE[nBufferSize]; if (!pBufferPtr) return; @@ -4441,15 +3032,15 @@ namespace PdfReader oImage.Create(pBufferPtr, nWidth, nHeight, -4 * nWidth); // Пишем данные в pBufferPtr - ImageStream *pImageStream = new ImageStream(pStream, nWidth, pColorMap->getNumPixelComps(), pColorMap->getBits()); - ImageStream *pMask = new ImageStream(pMaskStream, nMaskWidth, 1, 1); - + ImageStream* pImageStream = new ImageStream(pStream, nWidth, pColorMap->getNumPixelComps(), pColorMap->getBits()); + ImageStream* pMask = new ImageStream(pMaskStream, nMaskWidth, 1, 1); pMask->reset(); pImageStream->reset(); + BYTE unAlpha = std::min(255, std::max(0, int(pGState->getFillOpacity() * 255))); if (nWidth != nMaskWidth || nHeight != nMaskHeight) { - unsigned char *pMaskBuffer = new(std::nothrow) unsigned char[nMaskWidth * nMaskHeight]; + BYTE* pMaskBuffer = new(std::nothrow) BYTE[nMaskWidth * nMaskHeight]; if (!pMaskBuffer) { delete pMask; @@ -4457,7 +3048,7 @@ namespace PdfReader return; } - unsigned char unMask = 0; + BYTE unMask = 0; for (int nY = nMaskHeight - 1; nY >= 0; nY--) { int nIndex = nY * nMaskWidth; @@ -4471,7 +3062,7 @@ namespace PdfReader double dScaleWidth = (double)nWidth / (double)nMaskWidth; double dScaleHeight = (double)nHeight / (double)nMaskHeight; - unsigned char unPixel[4] ={ 0, 0, 0, 0 }; + BYTE unPixel[4] ={ 0, 0, 0, 0 }; for (int nY = nHeight - 1; nY >= 0; nY--) { int nIndex = 4 * nY * nWidth; @@ -4492,7 +3083,7 @@ namespace PdfReader if (unMask && !bMaskInvert) pBufferPtr[nIndex + 3] = 0; else - pBufferPtr[nIndex + 3] = 255; + pBufferPtr[nIndex + 3] = unAlpha; nIndex += 4; } @@ -4502,12 +3093,12 @@ namespace PdfReader } else { - unsigned char unPixel[4] ={ 0, 0, 0, 0 }; - unsigned char unMask = 0; - for (int nY = nHeight - 1; nY >= 0; nY--) + BYTE unPixel[4] = { 0, 0, 0, 0 }; + BYTE unMask = 0; + for (int nY = nHeight - 1; nY >= 0; --nY) { int nIndex = 4 * nY * nWidth; - for (int nX = 0; nX < nWidth; nX++) + for (int nX = 0; nX < nWidth; ++nX) { pImageStream->getPixel(unPixel); pMask->getPixel(&unMask); @@ -4516,11 +3107,7 @@ namespace PdfReader pBufferPtr[nIndex + 0] = colToByte(oRGB.b); pBufferPtr[nIndex + 1] = colToByte(oRGB.g); pBufferPtr[nIndex + 2] = colToByte(oRGB.r); - - if (unMask && !bMaskInvert) - pBufferPtr[nIndex + 3] = 0; - else - pBufferPtr[nIndex + 3] = 255; + pBufferPtr[nIndex + 3] = unMask && !bMaskInvert ? 0 : unAlpha; nIndex += 4; } @@ -4531,86 +3118,84 @@ namespace PdfReader delete pImageStream; double arrMatrix[6]; - double *pCTM = pGState->getCTM(); + double* pCTM = pGState->getCTM(); // Исходное предобразование // |1 0 0| |pCTM[0] pCTM[1] 0| // arrMatrix = |0 -1 0| * |pCTM[2] pCTM[3] 0| // |0 1 1| |pCTM[4] pCTM[5] 1| - arrMatrix[0] = pCTM[0]; - arrMatrix[1] = -pCTM[1]; - arrMatrix[2] = -pCTM[2]; - arrMatrix[3] = -(-pCTM[3]); - arrMatrix[4] = pCTM[2] + pCTM[4]; - arrMatrix[5] = -(pCTM[3] + pCTM[5]) + dPageHeight; + arrMatrix[0] = pCTM[0]; + arrMatrix[1] = -pCTM[1]; + arrMatrix[2] = -pCTM[2]; + arrMatrix[3] = pCTM[3]; + arrMatrix[4] = pCTM[2] + pCTM[4]; + arrMatrix[5] = -(pCTM[3] + pCTM[5]) + dPageHeight; double dShiftX = 0, dShiftY = 0; DoTransform(arrMatrix, &dShiftX, &dShiftY, true); - m_pRenderer->DrawImage(&oImage, 0 + dShiftX, 0 + dShiftY, PDFCoordsToMM(1), PDFCoordsToMM(1)); + m_pRenderer->DrawImage(&oImage, dShiftX, dShiftY, PDFCoordsToMM(1), PDFCoordsToMM(1)); } - void RendererOutputDev::drawSoftMaskedImage(GfxState *pGState, Object *pRef, Stream *pStream, - int nWidth, int nHeight, - GfxImageColorMap *pColorMap, - Object *maskRef, Stream *pMaskStream, - int nMaskWidth, int nMaskHeight, - GfxImageColorMap *pMaskColorMap, - double *pMatteColor, GBool interpolate) + void RendererOutputDev::drawSoftMaskedImage(GfxState* pGState, Object* pRef, Stream* pStream, int nWidth, int nHeight, GfxImageColorMap* pColorMap, Object* maskRef, Stream* pMaskStream, int nMaskWidth, int nMaskHeight, GfxImageColorMap* pMaskColorMap, double* pMatteColor, GBool interpolate) { if (m_bDrawOnlyText) return; - double dPageHeight = pGState->getPageHeight(); - int nBufferSize = 4 * nWidth * nHeight; if (nBufferSize < 1) return; - unsigned char *pBufferPtr = new(std::nothrow) unsigned char[nBufferSize]; - if (!pBufferPtr) - return; - Aggplus::CImage oImage; - oImage.Create(pBufferPtr, nWidth, nHeight, -4 * nWidth); - - // Пишем данные в pBufferPtr - ImageStream *pImageStream = new ImageStream(pStream, nWidth, pColorMap->getNumPixelComps(), pColorMap->getBits()); - pImageStream->reset(); + int nComponentsCount = pColorMap->getNumPixelComps(); - double dAlphaKoef = m_bTransparentGroup ? (m_bIsolatedTransparentGroup ? 0 : pGState->getFillOpacity()) : 1; - unsigned char unPixel[4] = { 0, 0, 0, 0 }; - for (int nY = nHeight - 1; nY >= 0; nY--) + if (nComponentsCount != 3 || pStream->getKind() != strDCT || !ReadImage(&oImage, pRef, pStream)) { - int nIndex = 4 * nY * nWidth; - for (int nX = 0; nX < nWidth; nX++) + BYTE* pBufferPtr = new(std::nothrow) BYTE[nBufferSize]; + if (!pBufferPtr) + return; + + // Пишем данные в pBufferPtr + ImageStream* pImageStream = new ImageStream(pStream, nWidth, pColorMap->getNumPixelComps(), pColorMap->getBits()); + pImageStream->reset(); + + BYTE unPixel[4] = { 0, 0, 0, 0 }; + for (int nY = nHeight - 1; nY >= 0; --nY) { - pImageStream->getPixel(unPixel); - GfxRGB oRGB; - pColorMap->getRGB(unPixel, &oRGB, gfxRenderingIntentAbsoluteColorimetric); - pBufferPtr[nIndex + 0] = colToByte(oRGB.b); - pBufferPtr[nIndex + 1] = colToByte(oRGB.g); - pBufferPtr[nIndex + 2] = colToByte(oRGB.r); - pBufferPtr[nIndex + 3] = 255; + int nIndex = 4 * nY * nWidth; + for (int nX = 0; nX < nWidth; ++nX) + { + pImageStream->getPixel(unPixel); + GfxRGB oRGB; + pColorMap->getRGB(unPixel, &oRGB, gfxRenderingIntentAbsoluteColorimetric); + pBufferPtr[nIndex + 0] = colToByte(oRGB.b); + pBufferPtr[nIndex + 1] = colToByte(oRGB.g); + pBufferPtr[nIndex + 2] = colToByte(oRGB.r); + pBufferPtr[nIndex + 3] = 255; - nIndex += 4; + nIndex += 4; + } } + delete pImageStream; + + oImage.Create(pBufferPtr, nWidth, nHeight, -4 * nWidth); } - delete pImageStream; + BYTE* pBufferPtr = oImage.GetData(); + double dAlphaKoef = pGState->getFillOpacity(); if (nWidth != nMaskWidth || nHeight != nMaskHeight) { - // TO DO: Здесь сделан элементарный вариант масштабирования маски. + // TODO: Здесь сделан элементарный вариант масштабирования маски. // Надо улучшить алгоритм. bool bResize = true; if (0 != nWidth && 0 != nMaskHeight && 0 != nHeight && 0 != nMaskWidth) { - ImageStream *pSMaskStream = new ImageStream(pMaskStream, nMaskWidth, pMaskColorMap->getNumPixelComps(), pMaskColorMap->getBits()); - unsigned char *pAlpha = new(std::nothrow) unsigned char[nMaskWidth * nMaskHeight]; + ImageStream* pSMaskStream = new ImageStream(pMaskStream, nMaskWidth, pMaskColorMap->getNumPixelComps(), pMaskColorMap->getBits()); + BYTE* pAlpha = new(std::nothrow) BYTE[nMaskWidth * nMaskHeight]; if (pSMaskStream && pAlpha) { pSMaskStream->reset(); - unsigned char unAlpha = 0; + BYTE unAlpha = 0; for (int i = 0, nCount = nMaskWidth * nMaskHeight; i < nCount; ++i) { pSMaskStream->getPixel(&unAlpha); @@ -4628,8 +3213,8 @@ namespace PdfReader if (nWidth != nMaxW || nHeight != nMaxH) { - unsigned char* pImageBuffer = pBufferPtr; - pBufferPtr = new(std::nothrow) unsigned char[4 * nMaxW * nMaxH]; + BYTE* pImageBuffer = pBufferPtr; + pBufferPtr = new(std::nothrow) BYTE[4 * nMaxW * nMaxH]; if (!pBufferPtr) { delete[] pImageBuffer; @@ -4653,7 +3238,7 @@ namespace PdfReader pBufferPtr[nIndex + 0] = pImageBuffer[nNearestImageMatch + 0]; pBufferPtr[nIndex + 1] = pImageBuffer[nNearestImageMatch + 1]; pBufferPtr[nIndex + 2] = pImageBuffer[nNearestImageMatch + 2]; - pBufferPtr[nIndex + 3] = (unsigned char)(pAlpha[nNearestAlphaMatch] * dAlphaKoef); + pBufferPtr[nIndex + 3] = (BYTE)(pAlpha[nNearestAlphaMatch] * dAlphaKoef); nIndex += 4; } } @@ -4669,7 +3254,7 @@ namespace PdfReader { int nNearestAlphaMatch = (((int)((nHeight - 1 - nY) * dAlphaScaleHeight) * nMaskWidth) + ((int)(nX * dAlphaScaleWidth))); - pBufferPtr[nIndex + 3] = (unsigned char)(pAlpha[nNearestAlphaMatch] * dAlphaKoef); + pBufferPtr[nIndex + 3] = (BYTE)(pAlpha[nNearestAlphaMatch] * dAlphaKoef); nIndex += 4; } } @@ -4695,25 +3280,25 @@ namespace PdfReader { for (int i = 3, nCount = nWidth * nHeight * 4; i < nCount; i += 4) { - pBufferPtr[i] = (unsigned char)(255.0 * dAlphaKoef); + pBufferPtr[i] = (BYTE)(255.0 * dAlphaKoef); } } } else { - ImageStream *pSMaskStream = new ImageStream(pMaskStream, nMaskWidth, pMaskColorMap->getNumPixelComps(), pMaskColorMap->getBits()); + ImageStream* pSMaskStream = new ImageStream(pMaskStream, nMaskWidth, pMaskColorMap->getNumPixelComps(), pMaskColorMap->getBits()); pSMaskStream->reset(); - unsigned char unAlpha = 0; - for (int nY = nHeight - 1; nY >= 0; nY--) + BYTE unAlpha = 0; + for (int nY = nMaskHeight - 1; nY >= 0; --nY) { - int nIndex = 4 * nY * nWidth; - for (int nX = 0; nX < nWidth; nX++) + int nIndex = 4 * nY * nMaskWidth; + for (int nX = 0; nX < nMaskWidth; ++nX) { pSMaskStream->getPixel(&unAlpha); GfxGray oGray; pMaskColorMap->getGray(&unAlpha, &oGray, GfxRenderingIntent::gfxRenderingIntentAbsoluteColorimetric); - pBufferPtr[nIndex + 3] = (unsigned char)(colToByte(oGray) * dAlphaKoef); + pBufferPtr[nIndex + 3] = (BYTE)(colToByte(oGray) * dAlphaKoef); nIndex += 4; } } @@ -4725,133 +3310,141 @@ namespace PdfReader { GfxRGB oMatteRGB; GfxColor oColor; - for (int i = 0; i < pColorMap->getNumPixelComps(); ++i) { + for (int i = 0; i < pColorMap->getNumPixelComps(); ++i) oColor.c[i] = dblToCol(pMatteColor[i]); - } pColorMap->getColorSpace()->getRGB(&oColor, &oMatteRGB, gfxRenderingIntentAbsoluteColorimetric); - unsigned char unMatteR = colToByte(oMatteRGB.r); - unsigned char unMatteG = colToByte(oMatteRGB.g); - unsigned char unMatteB = colToByte(oMatteRGB.b); + BYTE unMatteR = colToByte(oMatteRGB.r); + BYTE unMatteG = colToByte(oMatteRGB.g); + BYTE unMatteB = colToByte(oMatteRGB.b); - for (int nIndex = 0; nIndex < nHeight * nWidth * 4; nIndex += 4) + for (int nIndex = 0; nIndex < nBufferSize; nIndex += 4) { - unsigned char unA = pBufferPtr[nIndex + 3]; - - if (0 == unA) - { - pBufferPtr[nIndex + 0] = 255; - pBufferPtr[nIndex + 1] = 255; - pBufferPtr[nIndex + 2] = 255; - } - else + BYTE unA = pBufferPtr[nIndex + 3]; + if (unA) { double dK = 255.0 / unA; - pBufferPtr[nIndex + 0] = std::max(0, std::min(255, int((pBufferPtr[nIndex + 0] - unMatteB) * dK + unMatteB))); pBufferPtr[nIndex + 1] = std::max(0, std::min(255, int((pBufferPtr[nIndex + 1] - unMatteG) * dK + unMatteG))); pBufferPtr[nIndex + 2] = std::max(0, std::min(255, int((pBufferPtr[nIndex + 2] - unMatteR) * dK + unMatteR))); } + else + { + pBufferPtr[nIndex + 0] = 255; + pBufferPtr[nIndex + 1] = 255; + pBufferPtr[nIndex + 2] = 255; + } } } double arrMatrix[6]; - double *pCTM = pGState->getCTM(); + double* pCTM = pGState->getCTM(); // Исходное предобразование // |1 0 0| |pCTM[0] pCTM[1] 0| // arrMattrix = |0 -1 0| * |pCTM[2] pCTM[3] 0| // |0 1 1| |pCTM[4] pCTM[5] 1| - arrMatrix[0] = pCTM[0]; - arrMatrix[1] = -pCTM[1]; - arrMatrix[2] = -pCTM[2]; - arrMatrix[3] = -(-pCTM[3]); - arrMatrix[4] = pCTM[2] + pCTM[4]; - arrMatrix[5] = -(pCTM[3] + pCTM[5]) + dPageHeight; + arrMatrix[0] = pCTM[0]; + arrMatrix[1] = -pCTM[1]; + arrMatrix[2] = -pCTM[2]; + arrMatrix[3] = pCTM[3]; + arrMatrix[4] = pCTM[2] + pCTM[4]; + arrMatrix[5] = -(pCTM[3] + pCTM[5]) + pGState->getPageHeight(); double dShiftX = 0, dShiftY = 0; DoTransform(arrMatrix, &dShiftX, &dShiftY, true); - m_pRenderer->DrawImage(&oImage, 0 + dShiftX, 0 + dShiftY, PDFCoordsToMM(1), PDFCoordsToMM(1)); + m_pRenderer->DrawImage(&oImage, dShiftX, dShiftY, PDFCoordsToMM(1), PDFCoordsToMM(1)); + } + void RendererOutputDev::beginTransparencyGroup(GfxState* pGState, double* pBBox, GfxColorSpace* pBlendingColorSpace, GBool bIsolated, GBool bKnockout, GBool bForSoftMask) + { + if (c_nGrRenderer != m_lRendererType) + return; + + m_pRenderer->BeginCommand(c_nLayerType); + m_sCS.push_back(GfxOutputCS()); + m_sCS.back().bKnockout = bKnockout; + m_sCS.back().pBlendingCS = pBlendingColorSpace; + // TODO if (bKnockout) } - void RendererOutputDev::beginTransparencyGroup(GfxState *pGState, double *pBBox, GfxColorSpace *pBlendingColorSpace, GBool bIsolated, GBool bKnockout, GBool bForSoftMask) + void RendererOutputDev::endTransparencyGroup(GfxState* pGState) { - m_bTransparentGroup = true; - m_bIsolatedTransparentGroup = bIsolated; - m_bTransparentGroupSoftMask = bForSoftMask; - m_arrTransparentGroupSoftMask.push_back(bForSoftMask); } - void RendererOutputDev::endTransparencyGroup(GfxState *pGState) + void RendererOutputDev::paintTransparencyGroup(GfxState* pGState, double* pBBox) { - if (m_bTransparentGroupSoftMask) - m_bTransparentGroupSoftMaskEnd = true; + if (c_nGrRenderer != m_lRendererType) + return; - m_arrTransparentGroupSoftMask.pop_back(); - m_bTransparentGroup = false; - m_bTransparentGroupSoftMask = m_arrTransparentGroupSoftMask.empty() ? false : m_arrTransparentGroupSoftMask.back(); + double dOpacity = std::min(1.0, std::max(0.0, pGState->getFillOpacity())); + m_pRenderer->put_LayerOpacity(dOpacity); + m_pRenderer->EndCommand(c_nLayerType); + + m_sCS.pop_back(); } - void RendererOutputDev::paintTransparencyGroup(GfxState *pGState, double *pBBox) + void RendererOutputDev::setSoftMask(GfxState* pGState, double* pBBox, GBool bAlpha, Function* pTransferFunc, GfxColor* pBackdropColor) { - m_bIsolatedTransparentGroup = false; - m_bTransparentGroupSoftMaskEnd = false; - /* - if (!m_pTransparentGroupSoftMask) + if (c_nGrRenderer != m_lRendererType) + return; + NSGraphics::IGraphicsRenderer* GRenderer = dynamic_cast(m_pRenderer); + if (!GRenderer) return; - double arrMatrix[6]; - double *pCTM = pGState->getCTM(); - double dPageHeight = pGState->getPageHeight(); + RELEASEINTERFACE(m_pSoftMask); - arrMatrix[0] = pCTM[0]; - arrMatrix[1] = -pCTM[1]; - arrMatrix[2] = -pCTM[2]; - arrMatrix[3] = -(-pCTM[3]); - arrMatrix[4] = pCTM[2] + pCTM[4]; - arrMatrix[5] = -(pCTM[3] + pCTM[5]) + dPageHeight; + m_pSoftMask = GRenderer->CreateSoftMask(bAlpha); + m_pSoftMask->AddRef(); - double dShiftX = pBBox[0], dShiftY = pBBox[1]; - DoTransform(arrMatrix, &dShiftX, &dShiftY, true); + if (!bAlpha && m_sCS.back().pBlendingCS) + { + GfxRGB c; + m_sCS.back().pBlendingCS->getRGB(pBackdropColor, &c, GfxRenderingIntent::gfxRenderingIntentAbsoluteColorimetric); + DWORD dwColor = colToByte(c.r) + colToByte(c.g) * 0x100 + colToByte(c.b) * 0x100 * 0x100; + // TODO цвет фона мягкой маски должен быть установлен в dwColor + } - Aggplus::CImage oImage; - oImage.Create(m_pTransparentGroupSoftMask->get_Data(), m_pTransparentGroupSoftMask->get_Width(), m_pTransparentGroupSoftMask->get_Height(), m_pTransparentGroupSoftMask->get_Stride()); - m_pTransparentGroupSoftMask->ClearNoAttack(); + if (pTransferFunc) + { + BYTE* pSource = m_pSoftMask->GetBuffer(); + int nWidth = m_pSoftMask->GetWidth(); + int nHeight = m_pSoftMask->GetHeight(); + + for (int y = 0; y < nHeight; ++y) + { + for (int x = 0; x < nWidth; ++x) + { + int dLum = bAlpha ? pSource[y * nWidth * 4 + x * 4 + 3] : luminosity(pSource + y * nWidth * 4 + x * 4); - m_pRenderer->DrawImage(&oImage, 0 + dShiftX, 0 + dShiftY, PDFCoordsToMM(1), PDFCoordsToMM(1)); + double dLumIn, dLumOut; + dLumIn = (double)dLum / 256.0; + pTransferFunc->transform(&dLumIn, &dLumOut); + dLum = (int)(dLumOut * 255.0 + 0.5); - RELEASEOBJECT(m_pTransparentGroupSoftMask); - */ - } - void RendererOutputDev::setSoftMask(GfxState *pGState, double *pBBox, GBool bAlpha, Function *pTransferFunc, GfxColor *pBackdropColor) - { - m_bIsolatedTransparentGroup = false; - //m_bTransparentGroupSoftMaskEnd = false; + pSource[y * nWidth * 4 + x * 4 + 3] = dLum; + } + } + + // if (!bAlpha) // pTransferFunc преобразовала результат luminosity маски в alpha маску + // m_pSoftMask->SetType(Aggplus::EMaskDataType::Alpha4Buffer); + } + + m_sCS.pop_back(); } - void RendererOutputDev::clearSoftMask(GfxState *pGState) + void RendererOutputDev::clearSoftMask(GfxState* pGState) { + if (c_nGrRenderer != m_lRendererType) + return; + if (NSGraphics::IGraphicsRenderer* GRenderer = dynamic_cast(m_pRenderer)) + GRenderer->SetSoftMask(NULL); + RELEASEINTERFACE(m_pSoftMask); } - void RendererOutputDev::NewPDF(XRef *pXref) + void RendererOutputDev::NewPDF(XRef* pXref) { m_pXref = pXref; } - void RendererOutputDev::Transform(double *pMatrix, double dUserX, double dUserY, double *pdDeviceX, double *pdDeviceY) - { - *pdDeviceX = dUserX * pMatrix[0] + dUserY * pMatrix[2] + pMatrix[4]; - *pdDeviceY = dUserX * pMatrix[1] + dUserY * pMatrix[3] + pMatrix[5]; - } - void RendererOutputDev::DoPath(GfxState *pGState, GfxPath *pPath, double dPageHeight, double *pCTM, GfxClipMatrix* pCTM2) + void RendererOutputDev::DoPath(GfxState* pGState, GfxPath* pPath, double dPageHeight, double* pCTM, GfxClipMatrix* pCTM2) { if (m_bDrawOnlyText) return; - if (m_bTransparentGroupSoftMask) - return; - double arrMatrix[6]; - //double *pCTM = pGState->getCTM(); - arrMatrix[0] = pCTM[0]; - arrMatrix[1] = -pCTM[1]; - arrMatrix[2] = pCTM[2]; - arrMatrix[3] = -pCTM[3]; - arrMatrix[4] = pCTM[4]; - arrMatrix[5] = -pCTM[5] + dPageHeight; if (pCTM2) { arrMatrix[0] = pCTM2->dA; @@ -4861,6 +3454,15 @@ namespace PdfReader arrMatrix[4] = pCTM2->dE; arrMatrix[5] = -pCTM2->dF + dPageHeight; } + else + { + arrMatrix[0] = pCTM[0]; + arrMatrix[1] = -pCTM[1]; + arrMatrix[2] = pCTM[2]; + arrMatrix[3] = -pCTM[3]; + arrMatrix[4] = pCTM[4]; + arrMatrix[5] = -pCTM[5] + dPageHeight; + } double dShiftX = 0, dShiftY = 0; DoTransform(arrMatrix, &dShiftX, &dShiftY); @@ -4870,7 +3472,7 @@ namespace PdfReader for (int nSubPathIndex = 0, nSubPathCount = pPath->getNumSubpaths(); nSubPathIndex < nSubPathCount; ++nSubPathIndex) { - GfxSubpath *pSubpath = pPath->getSubpath(nSubPathIndex); + GfxSubpath* pSubpath = pPath->getSubpath(nSubPathIndex); int nPointsCount = pSubpath->getNumPoints(); m_pRenderer->PathCommandMoveTo(PDFCoordsToMM(pSubpath->getX(0) + dShiftX), PDFCoordsToMM(pSubpath->getY(0) + dShiftY)); @@ -4897,138 +3499,117 @@ namespace PdfReader } } } - void RendererOutputDev::updateClip(GfxState *pGState) + void RendererOutputDev::AddClip(GfxState* pGState, GfxOutputState* pState, int nIndex) { - if (m_bDrawOnlyText) - return; - - if (m_bTransparentGroupSoftMask) + if (m_bDrawOnlyText || m_bTiling) return; - if (m_bTiling) - return; + GfxClip* pClip = pState->pClip; + GfxPath* pPath = pClip->GetPath(nIndex); + int nClipFlag = pClip->GetClipFlag(nIndex);; - updateClipAttack(pGState); + m_pRenderer->BeginCommand(c_nClipType); + m_pRenderer->put_ClipMode(nClipFlag); + DoPath(pGState, pPath, pGState->getPageHeight(), pGState->getCTM(), &pClip->m_vMatrix[nIndex]); + m_pRenderer->EndCommand(c_nClipType); + m_pRenderer->PathCommandEnd(); } - void RendererOutputDev::updateClipAttack(GfxState *pGState) + void RendererOutputDev::AddTextClip(GfxState* pGState, GfxOutputState* pState) { - if (!m_bClipChanged) + if (m_bDrawOnlyText || m_bTiling) return; - m_pRenderer->BeginCommand(c_nResetClipType); - m_pRenderer->EndCommand(c_nResetClipType); - - if (m_sClip.empty()) - return; + GfxTextClip* pTextClip = pState->pTextClip; + m_pRenderer->BeginCommand(c_nClipType); + m_pRenderer->put_ClipMode(c_nClipRegionTypeWinding | c_nClipRegionIntersect); + m_pRenderer->StartConvertCoordsToIdentity(); - //for (int i = m_sClip.size() - 1; i >= 0; i--) - for (int i = 0; i < m_sClip.size(); i++) + for (int nIndex = 0, nTextClipCount = pTextClip->GetTextsCount(); nIndex < nTextClipCount; nIndex++) { - for (int nIndex = 0; nIndex < m_sClip[i].GetPathNum(); nIndex++) - { - GfxPath *pPath = m_sClip[i].GetPath(nIndex); - bool bFlag = m_sClip[i].GetClipEo(nIndex); - - int nClipFlag = bFlag ? c_nClipRegionTypeEvenOdd : c_nClipRegionTypeWinding; - nClipFlag |= c_nClipRegionIntersect; - - m_pRenderer->BeginCommand(c_nClipType); - m_pRenderer->put_ClipMode(nClipFlag); - DoPath(pGState, pPath, pGState->getPageHeight(), pGState->getCTM(), &m_sClip[i].m_vMatrix[nIndex]); - m_pRenderer->EndCommand(c_nPathType); - m_pRenderer->EndCommand(c_nClipType); - m_pRenderer->PathCommandEnd(); - } - - int nTextClipCount = m_sClip[i].GetTextClip()->GetTextsCount(); - if (nTextClipCount > 0) - { - m_pRenderer->BeginCommand(c_nClipType); - m_pRenderer->put_ClipMode(c_nClipRegionTypeWinding | c_nClipRegionIntersect); - m_pRenderer->StartConvertCoordsToIdentity(); + wchar_t* wsFontName, *wsFontPath; + int lFontStyle; + double dFontSize = 10, dX = 0, dY = 0, dWidth = 0, dHeight = 0, dBaseLineOffset = 0; + wchar_t* wsText = pTextClip->GetText(nIndex, &dX, &dY, &dWidth, &dHeight, &dBaseLineOffset, &wsFontName, &wsFontPath, &dFontSize, &lFontStyle); - for (int nIndex = 0; nIndex < nTextClipCount; nIndex++) - { - wchar_t *wsFontName, *wsFontPath; - int lFontStyle; - double dFontSize = 10, dX = 0, dY = 0, dWidth = 0, dHeight = 0, dBaseLineOffset = 0; - wchar_t *wsText = m_sClip[i].GetTextClip()->GetText(nIndex, &dX, &dY, &dWidth, &dHeight, &dBaseLineOffset, &wsFontName, &wsFontPath, &dFontSize, &lFontStyle); - - m_pRenderer->put_FontName(wsFontName); - m_pRenderer->put_FontPath(wsFontPath); - m_pRenderer->put_FontSize(dFontSize); - m_pRenderer->put_FontStyle(lFontStyle); - - double dShiftX = 0, dShiftY = 0; - DoTransform(m_sClip[i].GetTextClip()->GetMatrix(nIndex), &dShiftX, &dShiftY, true); - - // TODO: нужна нормальная конвертация - int nLen = 0; - wchar_t *wsTextTmp = wsText; - if (wsTextTmp) - { - while (*wsTextTmp) - ++wsTextTmp; + m_pRenderer->put_FontName(wsFontName); + m_pRenderer->put_FontPath(wsFontPath); + m_pRenderer->put_FontSize(dFontSize); + m_pRenderer->put_FontStyle(lFontStyle); - nLen = (int)(wsTextTmp - wsText); - } + double dShiftX = 0, dShiftY = 0; + DoTransform(pTextClip->GetMatrix(nIndex), &dShiftX, &dShiftY, true); - if (1 == nLen) - m_pRenderer->PathCommandTextExCHAR(0, (LONG)wsText[0], PDFCoordsToMM(dX), PDFCoordsToMM(dY), PDFCoordsToMM(dWidth), PDFCoordsToMM(dHeight)); - else if (0 != nLen) - { - unsigned int* pGids = new unsigned int[nLen]; - for (int nIndex = 0; nIndex < nLen; ++nIndex) - pGids[nIndex] = (unsigned int)wsText[nIndex]; + // TODO: нужна нормальная конвертация + int nLen = 0; + wchar_t* wsTextTmp = wsText; + if (wsTextTmp) + { + while (*wsTextTmp) + ++wsTextTmp; - m_pRenderer->PathCommandTextEx(L"", pGids, nLen, PDFCoordsToMM(dX), PDFCoordsToMM(dY), PDFCoordsToMM(dWidth), PDFCoordsToMM(dHeight)); + nLen = (int)(wsTextTmp - wsText); + } - RELEASEARRAYOBJECTS(pGids); - } + if (1 == nLen) + m_pRenderer->PathCommandTextExCHAR(0, (LONG)wsText[0], PDFCoordsToMM(dX), PDFCoordsToMM(dY), PDFCoordsToMM(dWidth), PDFCoordsToMM(dHeight)); + else if (0 != nLen) + { + unsigned int* pGids = new unsigned int[nLen]; + for (int nIndex = 0; nIndex < nLen; ++nIndex) + pGids[nIndex] = (unsigned int)wsText[nIndex]; - } + m_pRenderer->PathCommandTextEx(L"", pGids, nLen, PDFCoordsToMM(dX), PDFCoordsToMM(dY), PDFCoordsToMM(dWidth), PDFCoordsToMM(dHeight)); - m_pRenderer->EndCommand(c_nPathType); - m_pRenderer->EndCommand(c_nClipType); - m_pRenderer->PathCommandEnd(); - m_pRenderer->EndConvertCoordsToIdentity(); + RELEASEARRAYOBJECTS(pGids); } } - m_bClipChanged = false; + m_pRenderer->EndCommand(c_nClipType); + m_pRenderer->PathCommandEnd(); + m_pRenderer->EndConvertCoordsToIdentity(); + } + void RendererOutputDev::UpdateAllClip(GfxState* pGState) + { + if (m_bDrawOnlyText || m_bTiling) + return; + + m_pRenderer->BeginCommand(c_nResetClipType); + m_pRenderer->EndCommand(c_nResetClipType); + + for (int i = 0; i < m_sStates.size(); i++) + { + GfxClip* pClip = m_sStates[i].pClip; + if (pClip) + for (int nIndex = 0, nClipCount = pClip->GetPathNum(); nIndex < nClipCount; nIndex++) + AddClip(pGState, &m_sStates[i], nIndex); + GfxTextClip* pTextClip = m_sStates[i].pTextClip; + if (pTextClip) + AddTextClip(pGState, &m_sStates[i]); + } updateFont(pGState); } - void RendererOutputDev::DoTransform(double *pMatrix, double *pdShiftX, double *pdShiftY, bool bText) + void RendererOutputDev::DoTransform(double* pMatrix, double* pdShiftX, double* pdShiftY, bool bText) { if (1 == pMatrix[0] && 0 == pMatrix[1] && 0 == pMatrix[2] && 1 == pMatrix[3] && !bText) { - if (0 == pMatrix[4] && 0 == pMatrix[5]) - { - m_pRenderer->ResetTransform(); - m_arrMatrix[0] = 1; m_arrMatrix[1] = 0; - m_arrMatrix[2] = 0; m_arrMatrix[3] = 1; - m_arrMatrix[4] = 0; m_arrMatrix[5] = 0; - } - else + if (pMatrix[4] || pMatrix[5]) { *pdShiftX = pMatrix[4]; *pdShiftY = pMatrix[5]; - m_pRenderer->ResetTransform(); - m_arrMatrix[0] = 1; m_arrMatrix[1] = 0; - m_arrMatrix[2] = 0; m_arrMatrix[3] = 1; - m_arrMatrix[4] = 0; m_arrMatrix[5] = 0; } + m_pRenderer->ResetTransform(); + m_arrMatrix[0] = 1; m_arrMatrix[1] = 0; + m_arrMatrix[2] = 0; m_arrMatrix[3] = 1; + m_arrMatrix[4] = 0; m_arrMatrix[5] = 0; } else if (m_arrMatrix[0] == pMatrix[0] && m_arrMatrix[1] == pMatrix[1] && m_arrMatrix[2] == pMatrix[2] && m_arrMatrix[3] == pMatrix[3] && m_arrMatrix[4] == pMatrix[4] && m_arrMatrix[5] == pMatrix[5] && !bText) { - double dNewX = pMatrix[4], dNewY = pMatrix[5]; double dIDet = 1 / (pMatrix[0] * pMatrix[3] - pMatrix[1] * pMatrix[2]); - - *pdShiftX = ((dNewX - m_arrMatrix[4]) * m_arrMatrix[3] - (dNewY - m_arrMatrix[5]) * m_arrMatrix[1]) * dIDet; - *pdShiftY = ((dNewY - m_arrMatrix[5]) * m_arrMatrix[0] - (dNewX - m_arrMatrix[4]) * m_arrMatrix[2]) * dIDet; + *pdShiftX = ((pMatrix[4] - m_arrMatrix[4]) * m_arrMatrix[3] - (pMatrix[5] - m_arrMatrix[5]) * m_arrMatrix[1]) * dIDet; + *pdShiftY = ((pMatrix[5] - m_arrMatrix[5]) * m_arrMatrix[0] - (pMatrix[4] - m_arrMatrix[4]) * m_arrMatrix[2]) * dIDet; } else { diff --git a/PdfFile/SrcReader/RendererOutputDev.h b/PdfFile/SrcReader/RendererOutputDev.h index c0ea466aa9c..f5f380b3e69 100644 --- a/PdfFile/SrcReader/RendererOutputDev.h +++ b/PdfFile/SrcReader/RendererOutputDev.h @@ -34,89 +34,56 @@ #include "../../DesktopEditor/graphics/IRenderer.h" #include "../../DesktopEditor/graphics/pro/Fonts.h" -#include "../../DesktopEditor/graphics/pro/Graphics.h" +#include "../../DesktopEditor/graphics/AlphaMask.h" #include "../../DesktopEditor/graphics/TemporaryCS.h" #include "../../DesktopEditor/graphics/structures.h" -//#include "../PdfReader.h" #include "../lib/xpdf/Gfx.h" - #include "../lib/xpdf/OutputDev.h" -#include "../lib/xpdf/Object.h" -#include "../lib/xpdf/GlobalParams.h" -#include "XmlUtils.h" -#include "Adaptors.h" -#include "MemoryUtils.h" + #include "GfxClip.h" #include -#ifdef BUILDING_WASM_MODULE -#include "../../DesktopEditor/graphics/pro/js/wasm/src/serialize.h" -#endif namespace PdfReader { - - //------------------------------------------------------------------------------------------------------------------------------- struct TFontEntry { - Ref oRef; // Ссылка на объект-шрифт - std::wstring wsFilePath; // Путь к шрифту на диске - std::wstring wsFontName; // Имя шрифта, которое записано в PDF(ветка для случаев, когда имя шрифта в самом шрифте не указано) - int *pCodeToGID; // Таблица код - номер глифа в шрифте - int *pCodeToUnicode; // Таблица код - юникодное значение - unsigned int unLenGID; // Количество элементов в таблицах - unsigned int unLenUnicode; // - bool bAvailable; // Доступен ли шрифт. Сделано для многопотоковости + std::wstring wsFilePath; // Путь к шрифту на диске + std::wstring wsFontName; // Имя шрифта, которое записано в PDF(ветка для случаев, когда имя шрифта в самом шрифте не указано) + int* pCodeToGID; // Таблица код - номер глифа в шрифте + int* pCodeToUnicode; // Таблица код - юникодное значение + unsigned int unLenGID; + unsigned int unLenUnicode; + bool bAvailable; // Доступен ли шрифт. Сделано для многопотоковости }; - class CFontList + class CPdfFontList { public: - - CFontList(); - ~CFontList(); - void LoadFromFile(std::wstring wsDirPath); - void SaveToFile(std::wstring wsDirPath); - bool Find(Ref oRef, TFontEntry *pEntry); - bool Find2(Ref oRef, TFontEntry **ppEntry); + CPdfFontList(); + ~CPdfFontList(); + bool Find(Ref oRef, TFontEntry* pEntry); + bool Find2(Ref oRef, TFontEntry** ppEntry); void Remove(Ref oRef); - TFontEntry *Add(Ref oRef, std::wstring wsFileName, int *pCodeToGID, int *pCodeToUnicode, unsigned int nLenGID, unsigned int nLenUnicode); + TFontEntry* Add(Ref oRef, const std::wstring& wsFileName, int* pCodeToGID, int* pCodeToUnicode, unsigned int unLenGID, unsigned int unLenUnicode); void Clear(); - bool GetFont(Ref *pRef, TFontEntry *pEntry); + bool GetFont(Ref* pRef, TFontEntry* pEntry); private: - - TFontEntry* Lookup(Ref& oRef) - { - CRefFontMap::const_iterator oPos = m_oFontMap.find(oRef); - if (m_oFontMap.end() != oPos) - return oPos->second; - - return NULL; - } - void Add(Ref& oRef, TFontEntry* pFontEntry) - { - // До вызова данной функции надо проверять есть ли элемент с данным ключом - m_oFontMap.insert(std::pair(oRef, pFontEntry)); - } + TFontEntry* Lookup(Ref& oRef); + void Add(Ref& oRef, TFontEntry* pFontEntry); private: - typedef std::map CRefFontMap; CRefFontMap m_oFontMap; - NSCriticalSection::CRITICAL_SECTION m_oCS; // Критическая секция + NSCriticalSection::CRITICAL_SECTION m_oCS; // Критическая секция }; + //------------------------------------------------------------------------------------------------------------------------------- template inline static double PDFCoordsToMM(T tX) { - return ((double)tX / 72.0) * 25.4; - } - - //------------------------------------------------------------------------------------------------------------------------------- - static void FileWrite(void *pStream, char *sData, int nLen) - { - ::fwrite(sData, 1, nLen, (FILE *)pStream); + return ((double)tX / 72.0) * 25.4; } //------------------------------------------------------------------------------------------------------------------------------- // RendererOutputDev @@ -125,24 +92,20 @@ namespace PdfReader class RendererOutputDev : public OutputDev { public: - RendererOutputDev(IRenderer *pRenderer, NSFonts::IFontManager* pFontManager, CFontList *pFontList = NULL); + RendererOutputDev(IRenderer* pRenderer, NSFonts::IFontManager* pFontManager, CPdfFontList* pFontList = NULL); virtual ~RendererOutputDev(); - virtual GBool upsideDown() + virtual GBool upsideDown() override { return false; } - virtual GBool useDrawChar() + virtual GBool useDrawChar() override { return true; } - virtual GBool useTilingPatternFill() + virtual GBool useTilingPatternFill() override { - // TODO Доделать поддержку различных параметров TilingPattern - if (m_bDrawOnlyText) - return true; - - return false; + return true; } virtual GBool useFunctionalShadedFills() { @@ -168,7 +131,7 @@ namespace PdfReader { return false;//true; } - virtual GBool interpretType3Chars() + virtual GBool interpretType3Chars() override { return true; } @@ -197,114 +160,120 @@ namespace PdfReader return false; } //--------------------------------------------------------------------------------------------------------------------------- - virtual void startPage(int nPageIndex, GfxState *pGState); - virtual void endPage(); + virtual void startPage(int nPageIndex, GfxState *pGState) override; + virtual void endPage() override; //----- Save/Restore GState - virtual void saveState(GfxState *pGState); - virtual void restoreState(GfxState *pGState); + virtual void saveState(GfxState *pGState) override; + virtual void restoreState(GfxState *pGState) override; //----- Изменение параметров в GState - virtual void updateCTM(GfxState *pGState, double dMatrix11, double dMatrix12, double dMatrix21, double dMatrix22, double dMatrix31, double dMatrix32); - virtual void updateLineDash(GfxState *pGState); - virtual void updateFlatness(GfxState *pGState); - virtual void updateLineJoin(GfxState *pGState); - virtual void updateLineCap(GfxState *pGState); - virtual void updateMiterLimit(GfxState *pGState); - virtual void updateLineWidth(GfxState *pGState); - virtual void updateStrokeAdjust(GfxState *pGState); - virtual void updateFillColor(GfxState *pGState); - virtual void updateStrokeColor(GfxState *pGState); - virtual void updateBlendMode(GfxState *pGState); - virtual void updateFillOpacity(GfxState *pGState); - virtual void updateStrokeOpacity(GfxState *pGState); - virtual void updateAll(GfxState *pGState); - virtual void updateRender(GfxState *pGState); + virtual void updateCTM(GfxState *pGState, double dMatrix11, double dMatrix12, double dMatrix21, double dMatrix22, double dMatrix31, double dMatrix32) override; + virtual void updateLineDash(GfxState *pGState) override; + virtual void updateFlatness(GfxState *pGState) override; + virtual void updateLineJoin(GfxState *pGState) override; + virtual void updateLineCap(GfxState *pGState) override; + virtual void updateMiterLimit(GfxState *pGState) override; + virtual void updateLineWidth(GfxState *pGState) override; + virtual void updateStrokeAdjust(GfxState *pGState) override; + virtual void updateFillColor(GfxState *pGState) override; + virtual void updateStrokeColor(GfxState *pGState) override; + virtual void updateBlendMode(GfxState *pGState) override; + virtual void updateFillOpacity(GfxState *pGState) override; + virtual void updateStrokeOpacity(GfxState *pGState) override; + virtual void updateAll(GfxState *pGState) override; + virtual void updateRender(GfxState *pGState) override; //----- Изменение текстовых параметров - virtual void updateFont(GfxState *pGState); + virtual void updateFont(GfxState *pGState) override; //----- Рисование Path - virtual void stroke(GfxState *pGState); - virtual void fill(GfxState *pGState); - virtual void eoFill(GfxState *pGState); + virtual void stroke(GfxState *pGState) override; + virtual void fill(GfxState *pGState) override; + virtual void eoFill(GfxState *pGState) override; virtual void FillStroke(GfxState *pGState); virtual void EoFillStroke(GfxState *pGState); - virtual void tilingPatternFill(GfxState *pGState, Gfx *gfx, Object *pStream, int nPaintType, int nTilingType, Dict *pResourcesDict, double *pMatrix, double *pBBox, int nX0, int nY0, int nX1, int nY1, double dXStep, double dYStep); + virtual void tilingPatternFill(GfxState *pGState, Gfx *gfx, Object *pStream, int nPaintType, int nTilingType, Dict *pResourcesDict, double *pMatrix, double *pBBox, int nX0, int nY0, int nX1, int nY1, double dXStep, double dYStep) override; virtual void StartTilingFill(GfxState *pGState); virtual void EndTilingFill(); - virtual GBool shadedFill(GfxState *state, GfxShading *shading); - virtual bool FunctionShadedFill(GfxState *pGState, GfxFunctionShading *pShading); - virtual bool AxialShadedFill(GfxState *pGState, GfxAxialShading *pShading); - virtual bool RadialShadedFill(GfxState *pGState, GfxRadialShading *pShading); - virtual bool GouraundTriangleFill(GfxState *pGState, const std::vector &colors, const std::vector &points); - virtual bool PatchMeshFill(GfxState *pGState, GfxPatch* pPatch, GfxPatchMeshShading *pShading); - virtual void StartShadedFill(GfxState *pGState); - virtual void EndShadedFill(); - virtual void StartTilingFillIteration(); - virtual void EndTilingFillIteration(); - virtual void StartSimpleTilingFill(GfxState *pGState, int nX0, int nY0, int nX1, int nY1, double dStepX, double dStepY, double dXMin, double dYMin, double dXMax, double dYMax, double* pMatrix); - virtual void EndSimpleTilingFill(); + virtual GBool shadedFill(GfxState* pGState, GfxShading* shading) override; + bool FunctionShadedFill(GfxState* pGState, GfxFunctionShading* pShading); + bool AxialShadedFill(GfxState* pGState, GfxAxialShading* pShading); + bool RadialShadedFill(GfxState* pGState, GfxRadialShading* pShading); + bool GouraundTriangleFill(GfxState* pGState, const std::vector& colors, const std::vector& points); + bool PatchMeshFill(GfxState* pGState, GfxPatch* pPatch, GfxPatchMeshShading* pShading); + void StartShadedFill(); + void EndShadedFill(); + void StartTilingFillIteration(); + void EndTilingFillIteration(); + void StartSimpleTilingFill(GfxState* pGState, int nX0, int nY0, int nX1, int nY1, double dStepX, double dStepY, double dXMin, double dYMin, double dXMax, double dYMax, double* pMatrix); + void EndSimpleTilingFill(); //----- Path clipping - virtual void clip(GfxState *pGState); - virtual void clipAttack(GfxState *pGState) - { - updateClipAttack(pGState); - } - virtual void eoClip(GfxState *pGState); - virtual void clipToStrokePath(GfxState *pGState); + virtual void clip(GfxState *pGState) override; + virtual void eoClip(GfxState *pGState) override; + virtual void clipToStrokePath(GfxState *pGState) override; virtual void clipToPath(GfxState *pGState, GfxPath *pPath, double *pMatrix, bool bEO); //----- Вывод текста - virtual void endTextObject(GfxState *pGState); - virtual void beginStringOp(GfxState *pGState); - virtual void endStringOp(GfxState *pGState); - virtual void drawString(GfxState *pGState, GString *seString); - virtual void drawChar(GfxState *pGState, double dX, double dY, double dDx, double dDy, double dOriginX, double dOriginY, CharCode nCode, int nBytesCount, Unicode *pUnicode, int nUnicodeLen); - GBool beginType3Char(GfxState *state, double x, double y, - double dx, double dy, - CharCode code, Unicode *u, int uLen) { - return false; - } - void endType3Char(GfxState *pGState); - void Type3D0(GfxState *pGState, double dWx, double dWy); - void Type3D1(GfxState *pGState, double dWx, double dWy, double dBLx, double dBLy, double dTRx, double dTRy); + virtual void endTextObject(GfxState *pGState) override; + virtual void beginStringOp(GfxState *pGState) override; + virtual void endStringOp(GfxState *pGState) override; + virtual void drawString(GfxState *pGState, GString *seString) override; + virtual void drawChar(GfxState *pGState, double dX, double dY, double dDx, double dDy, double dOriginX, double dOriginY, CharCode nCode, int nBytesCount, Unicode *pUnicode, int nUnicodeLen) override; + GBool beginType3Char(GfxState *state, double x, double y, double dx, double dy, CharCode code, Unicode *u, int uLen) override; + void endType3Char(GfxState *pGState) override; + //----- Дополнительные функции + virtual GBool beginMarkedContent(GfxState *state, GString *s) override; + virtual GBool beginMCOShapes(GfxState *state, GString *s, Object *ref) override; + virtual void endMarkedContent(GfxState *state) override; //----- Вывод картинок + bool ReadImage(Aggplus::CImage* pImageRes, Object *pRef, Stream *pStream); virtual void drawImageMask(GfxState *pGState, Object *pRef, Stream *pStream, int nWidth, int nHeight, GBool bInvert, GBool bInlineImage, GBool interpolate) override; virtual void setSoftMaskFromImageMask(GfxState *pGState, Object *pRef, Stream *pStream, int nWidth, int nHeight, GBool bInvert, GBool bInlineImage, GBool interpolate) override; virtual void drawImage(GfxState *pGState, Object *pRef, Stream *pStream, int nWidth, int nHeight, GfxImageColorMap *pColorMap, int *pMaskColors, GBool bInlineImg, GBool interpolate) override; - virtual void drawMaskedImage(GfxState *pGState, - Object *pRef, - Stream *pStream, - int nWidth, int nHeight, - GfxImageColorMap *pColorMap, - Object* pMaskRef, - Stream *pMaskStream, - int nMaskWidth, int nMaskHeight, - GBool bMaskInvert, - GBool interpolate) override; - virtual void drawSoftMaskedImage(GfxState *pGState, Object *pRef, Stream *pStream, - int nWidth, int nHeight, - GfxImageColorMap *pColorMap, - Object *maskRef, Stream *pMaskStream, - int nMaskWidth, int nMaskHeight, - GfxImageColorMap *pMaskColorMap, - double *pMatte, GBool interpolate) override; + virtual void drawMaskedImage(GfxState *pGState, Object *pRef, Stream *pStream, int nWidth, int nHeight, GfxImageColorMap *pColorMap, + Object* pMaskRef, Stream *pMaskStream, int nMaskWidth, int nMaskHeight, GBool bMaskInvert, GBool interpolate) override; + virtual void drawSoftMaskedImage(GfxState *pGState, Object *pRef, Stream *pStream, int nWidth, int nHeight, GfxImageColorMap *pColorMap, + Object *maskRef, Stream *pMaskStream, int nMaskWidth, int nMaskHeight, GfxImageColorMap *pMaskColorMap, double *pMatte, GBool interpolate) override; //----- Transparency groups и SMasks - virtual void beginTransparencyGroup(GfxState *pGState, double *pBBox, GfxColorSpace *pBlendingColorSpace, GBool bIsolated, GBool bKnockout, GBool bForSoftMask); - virtual void endTransparencyGroup(GfxState *pGState); - virtual void paintTransparencyGroup(GfxState *pGState, double *pBBox); - virtual void setSoftMask(GfxState *pGState, double *pBBox, GBool bAlpha, Function *pTransferFunc, GfxColor *pBackdropColor); - virtual void clearSoftMask(GfxState *pGState); + virtual void beginTransparencyGroup(GfxState *pGState, double *pBBox, GfxColorSpace *pBlendingColorSpace, GBool bIsolated, GBool bKnockout, GBool bForSoftMask) override; + virtual void endTransparencyGroup(GfxState *pGState) override; + virtual void paintTransparencyGroup(GfxState *pGState, double *pBBox) override; + virtual void setSoftMask(GfxState *pGState, double *pBBox, GBool bAlpha, Function *pTransferFunc, GfxColor *pBackdropColor) override; + virtual void clearSoftMask(GfxState *pGState) override; //----- Дополнительные функции для данного устройства void NewPDF(XRef *pXref); void SetBreak(bool* pbBreak) { m_pbBreak = pbBreak; } + static NSFonts::CFontInfo* GetFontByParams(XRef* pXref, NSFonts::IFontManager* pFontManager, GfxFont* pFont, std::wstring& wsFontBaseName); + static void GetFont(XRef* pXref, NSFonts::IFontManager* pFontManager, CPdfFontList *pFontList, GfxFont* pFont, std::wstring& wsFileName, std::wstring& wsFontName); + static void CheckFontStylePDF(std::wstring& sName, bool& bBold, bool& bItalic); private: + struct GfxOutputState + { + GfxState* pGState; + Aggplus::CSoftMask* pSoftMask; + GfxClip* pClip; + GfxTextClip* pTextClip; + + GfxOutputState() : pGState(NULL), pSoftMask(NULL), pClip(NULL), pTextClip(NULL) {} + ~GfxOutputState() + { + RELEASEOBJECT(pClip); + RELEASEOBJECT(pTextClip); + } + }; + struct GfxOutputCS + { + bool bKnockout; + GfxColorSpace* pBlendingCS; + + GfxOutputCS() : bKnockout(false), pBlendingCS(NULL) {} + }; - void Transform(double *pMatrix, double dUserX, double dUserY, double *pdDeviceX, double *pdDeviceY); void DoPath(GfxState *pGState, GfxPath *pPath, double dPageHeight, double *pCTM, GfxClipMatrix* pCTM2 = NULL); void ClipToText(const std::wstring& wsFontName, const std::wstring& wsFontPath, double dFontSize, int nFontStyle, double* pMatrix, const std::wstring& wsText, double dX, double dY, double dWidth = 0, double dHeight = 0, double dBaseLineOffset = 0); - void updateClip(GfxState *pGState); - void updateClipAttack(GfxState *pGState); + void AddClip(GfxState* pGState, GfxOutputState* pState, int nIndex); + void AddTextClip(GfxState* pGState, GfxOutputState* pState = NULL); + void UpdateAllClip(GfxState *pGState); void DoTransform(double *pMatrix, double *pdShiftX, double *pdShiftY, bool bText = false); private: @@ -313,28 +282,16 @@ namespace PdfReader double m_arrMatrix[6]; NSFonts::IFontManager* m_pFontManager; - //GfxTextClip *m_pBufferTextClip; - - XRef *m_pXref; // Таблица Xref для данного PDF-документа - CFontList *m_pFontList; + XRef* m_pXref; // Таблица Xref для данного PDF-документа + CPdfFontList* m_pFontList; bool *m_pbBreak; // Внешняя остановка рендерера - std::deque m_sClip; - bool m_bClipChanged; + std::deque m_sCS; + std::deque m_sStates; + Aggplus::CSoftMask* m_pSoftMask; bool m_bTiling; - bool m_bTransparentGroup; - bool m_bIsolatedTransparentGroup; - bool m_bTransparentGroupSoftMask; - bool m_bTransparentGroupSoftMaskEnd; - std::vector m_arrTransparentGroupSoftMask; - - /* - unsigned char* m_pSoftMask; - int m_nSoftMaskWidth; - int m_nSoftMaskHeight; - */ bool m_bDrawOnlyText; // Special option for html-renderer diff --git a/PdfFile/SrcWriter/Annotation.cpp b/PdfFile/SrcWriter/Annotation.cpp index a9d0e023a62..2cf08c03126 100644 --- a/PdfFile/SrcWriter/Annotation.cpp +++ b/PdfFile/SrcWriter/Annotation.cpp @@ -33,7 +33,9 @@ #include "Pages.h" #include "Utils.h" #include "ResourcesDictionary.h" +#include "FontCidTT.h" #include "Streams.h" +#include "Image.h" #include "../../DesktopEditor/common/File.h" @@ -70,11 +72,101 @@ namespace PdfWriter "Check", "Checkmark", "Circle", "Comment", "Cross", "CrossHairs", "Help", "Insert", "Key", "NewParagraph", "Note", "Paragraph", "RightArrow", "RightPointer", "Star", "UpArrow", "UpLeftArrow" }; + void AddToVectorD(CDictObject* pObj, const std::string& sName, const std::vector& arrV) + { + CArrayObject* pArray = new CArrayObject(); + if (!pArray) + return; + + pObj->Add(sName, pArray); + + for (const double& dV : arrV) + pArray->Add(dV); + } + std::string AddLE(const BYTE& nLE) + { + std::string sValue; + switch (nLE) + { + case ELineEndType::Square: sValue = "Square"; break; + case ELineEndType::Circle: sValue = "Circle"; break; + case ELineEndType::Diamond: sValue = "Diamond"; break; + case ELineEndType::OpenArrow: sValue = "OpenArrow"; break; + case ELineEndType::ClosedArrow: sValue = "ClosedArrow"; break; + case ELineEndType::None: sValue = "None"; break; + case ELineEndType::Butt: sValue = "Butt"; break; + case ELineEndType::ROpenArrow: sValue = "ROpenArrow"; break; + case ELineEndType::RClosedArrow: sValue = "RClosedArrow"; break; + case ELineEndType::Slash: sValue = "Slash"; break; + } + + return sValue; + } + void AddRD(CDictObject* pObj, const double& dRD1, const double& dRD2, const double& dRD3, const double& dRD4) + { + CArrayObject* pArray = new CArrayObject(); + if (!pArray) + return; + + pObj->Add("RD", pArray); + + pArray->Add(dRD1); + pArray->Add(dRD4); + pArray->Add(dRD3); + pArray->Add(dRD2); + } + std::string GetColor(const std::vector& arr, bool bCaps, double dDiff = 0) + { + if (arr.empty()) + return bCaps ? "1 G" : "1 g"; + + std::string sDA; + for (double dColoc : arr) + { + sDA.append(std::to_string(dColoc + dDiff)); + sDA.append(" "); + } + if (arr.size() == 3) + sDA.append(bCaps ? "RG" : "rg"); + else if (arr.size() == 4) + sDA.append(bCaps ? "K" : "k"); + else if (arr.size() == 1) + sDA.append(bCaps ? "G" : "g"); + return sDA; + } + std::string GetColor(CArrayObject* pArr, bool bCAPS, float dDiff = 0) + { + std::string sDA; + if (!pArr) + return sDA; + + int nSize = pArr->GetCount(); + for (int i = 0; i < nSize; ++i) + { + CObjectBase* pColor = pArr->Get(i); + float fColor = pColor->GetType() == object_type_REAL ? ((CRealObject*)pColor)->Get() : ((CNumberObject*)pColor)->Get(); + + sDA.append(std::to_string(fColor + dDiff)); + sDA.append(" "); + } + + if (nSize == 3) + sDA.append(bCAPS ? "RG" : "rg"); + else if (nSize == 4) + sDA.append(bCAPS ? "K" : "k"); + else if (nSize == 1) + sDA.append(bCAPS ? "G" : "g"); + + return sDA; + } + //---------------------------------------------------------------------------------------- // CAnnotation //---------------------------------------------------------------------------------------- CAnnotation::CAnnotation(CXref* pXref, EAnnotType eType) { + m_pAppearance = NULL; + m_pDocument = NULL; m_pXref = pXref; Add("Type", "Annot"); @@ -95,20 +187,16 @@ namespace PdfWriter if (oRect.fTop < oRect.fBottom) { - pArray->Add(oRect.fLeft); - pArray->Add(oRect.fTop); - pArray->Add(oRect.fRight); - pArray->Add(oRect.fBottom); - } - else - { - pArray->Add(oRect.fLeft); - pArray->Add(oRect.fBottom); - pArray->Add(oRect.fRight); - pArray->Add(oRect.fTop); + m_oRect.fTop = oRect.fBottom; + m_oRect.fBottom = oRect.fTop; } + + pArray->Add(m_oRect.fLeft); + pArray->Add(m_oRect.fBottom); + pArray->Add(m_oRect.fRight); + pArray->Add(m_oRect.fTop); } - void CAnnotation::SetBorder(BYTE nType, double dWidth, double dDashesAlternating, double dGaps) + void CAnnotation::SetBorder(BYTE nType, double dWidth, const std::vector& arrDash) { CDictObject* pBorderStyleDict = new CDictObject(); if (!pBorderStyleDict) @@ -119,36 +207,34 @@ namespace PdfWriter pBorderStyleDict->Add("Type", "Border"); pBorderStyleDict->Add("W", dWidth); - EBorderSubtype eSubtype = EBorderSubtype(nType); - if (border_subtype_Dashed == eSubtype) - { - CArrayObject* pDash = new CArrayObject(); - if (pDash) - { - pBorderStyleDict->Add("D", pDash); - pDash->Add(dDashesAlternating); - pDash->Add(dGaps); - } - } + EBorderType eBT = EBorderType(nType); + if (EBorderType::Dashed == eBT) + AddToVectorD(pBorderStyleDict, "D", arrDash); - switch (eSubtype) + switch (eBT) { - case border_subtype_Solid: pBorderStyleDict->Add("S", "S"); break; - case border_subtype_Dashed: pBorderStyleDict->Add("S", "D"); break; - case border_subtype_Beveled: pBorderStyleDict->Add("S", "B"); break; - case border_subtype_Inset: pBorderStyleDict->Add("S", "I"); break; - case border_subtype_Underlined: pBorderStyleDict->Add("S", "U"); break; + case EBorderType::Solid: pBorderStyleDict->Add("S", "S"); break; + case EBorderType::Dashed: pBorderStyleDict->Add("S", "D"); break; + case EBorderType::Beveled: pBorderStyleDict->Add("S", "B"); break; + case EBorderType::Inset: pBorderStyleDict->Add("S", "I"); break; + case EBorderType::Underline: pBorderStyleDict->Add("S", "U"); break; } + + m_oBorder.bHave = true; + m_oBorder.nType = EBorderType(nType); + m_oBorder.dWidth = dWidth; + m_oBorder.arrDash = arrDash; } void CAnnotation::SetAnnotFlag(const int& nAnnotFlag) { Add("F", nAnnotFlag); } - void CAnnotation::SetPage(CPage* pPage) + void CAnnotation::SetPage(CPage* pPage, double dW, double dH, double dX) { Add("P", pPage); - m_dPageWidth = pPage->GetWidth(); - m_dPageHeight = pPage->GetHeight(); + m_dPageWidth = dW; + m_dPageH = dH; + m_dPageX = dX; } void CAnnotation::SetBE(BYTE nType, const double& dBE) { @@ -157,6 +243,7 @@ namespace PdfWriter return; Add("BE", pBEDict); + pBEDict->Add("I", dBE); std::string sValue; switch (nType) @@ -165,10 +252,10 @@ namespace PdfWriter { sValue = "S"; break; } case 1: { sValue = "C"; break; } + default: { return; } } pBEDict->Add("S", sValue.c_str()); - pBEDict->Add("I", dBE); } void CAnnotation::SetContents(const std::wstring& wsText) { @@ -188,24 +275,50 @@ namespace PdfWriter std::string sValue = U_TO_UTF8(wsLM); Add("M", new CStringObject(sValue.c_str())); } - void AddToVectorD(CDictObject* pObj, const std::string& sName, const std::vector& arrV) + void CAnnotation::SetOUserID(const std::wstring& wsLM) { - CArrayObject* pArray = new CArrayObject(); - if (!pArray) - return; - - pObj->Add(sName, pArray); - - for (const double& dV : arrV) - pArray->Add(dV); + std::string sValue = U_TO_UTF8(wsLM); + Add("OUserID", new CStringObject(sValue.c_str())); } void CAnnotation::SetC(const std::vector& arrC) { AddToVectorD(this, "C", arrC); } - void CAnnotation::CreateAP() + void CAnnotation::SetDocument(CDocument* pDocument) + { + m_pDocument = pDocument; + } + CDocument* CAnnotation::GetDocument() + { + return m_pDocument; + } + std::string CAnnotation::GetBorderDash() + { + std::string sRes = "["; + for (double dDash : m_oBorder.arrDash) + { + sRes.append(" "); + sRes.append(std::to_string(dDash)); + } + sRes.append(" ] 0 d\012"); + return sRes; + } + CAnnotAppearanceObject* CAnnotation::StartAP() + { + m_pAppearance = new CAnnotAppearance(m_pXref, this); + if (!m_pAppearance) + return NULL; + Add("AP", m_pAppearance); + return m_pAppearance->GetNormal(); + } + void CAnnotation::APFromFakePage(CPage* pFakePage) { + if (!m_pAppearance) + return; + CAnnotAppearanceObject* pNormal = m_pAppearance->GetNormal(); + pNormal->AddBBox(GetRect().fLeft, GetRect().fBottom, GetRect().fRight, GetRect().fTop); + pNormal->AddMatrix(1, 0, 0, 1, -GetRect().fLeft, -GetRect().fBottom); } //---------------------------------------------------------------------------------------- // CMarkupAnnotation @@ -213,7 +326,7 @@ namespace PdfWriter CMarkupAnnotation::CMarkupAnnotation(CXref* pXref, EAnnotType eType) : CAnnotation(pXref, eType) { } - void CMarkupAnnotation::SetRT(const BYTE& nRT) + void CMarkupAnnotation::SetRT(BYTE nRT) { Add("RT", nRT ? "Group" : "R"); } @@ -242,7 +355,8 @@ namespace PdfWriter void CMarkupAnnotation::SetT(const std::wstring& wsT) { std::string sValue = U_TO_UTF8(wsT); - Add("T", new CStringObject(sValue.c_str(), true)); + if (!Get("T")) + Add("T", new CStringObject(sValue.c_str(), true)); } void CMarkupAnnotation::SetRC(const std::wstring& wsRC) { @@ -263,9 +377,9 @@ namespace PdfWriter { Add("IRT", pAnnot); } - void CMarkupAnnotation::CreateAP() + void CMarkupAnnotation::RemoveAP() { - + Remove("AP"); } //---------------------------------------------------------------------------------------- // CLinkAnnotation @@ -346,6 +460,7 @@ namespace PdfWriter { sValue = "Completed"; break; } case 6: { sValue = "None"; break; } + default: { return; } } Add("State", new CStringObject(sValue.c_str())); @@ -361,25 +476,157 @@ namespace PdfWriter { sValue = "Marked"; break; } case 1: { sValue = "Review"; break; } + default: { return; } } Add("StateModel", new CStringObject(sValue.c_str())); } - void CTextAnnotation::CreateAP() + void CTextAnnotation::SetAP() { + std::string sColor = GetColor(dynamic_cast(Get("C")), false); + + CAnnotAppearance* pAP = new CAnnotAppearance(m_pXref, this); + Add("AP", pAP); + CAnnotAppearanceObject* pN = pAP->GetNormal(); + CAnnotAppearanceObject* pR = pAP->GetRollover(); + switch (m_nName) { + case 0: + { + pN->AddBBox(0, 0, 19, 19); + pN->DrawTextCheck(sColor); + pR->AddBBox(0, 0, 19, 19); + pR->DrawTextCheck(sColor); + break; + } + case 1: + { + pN->AddBBox(0, 0, 20, 20); + pN->DrawTextCheckmark(); + pR->AddBBox(0, 0, 20, 20); + pR->DrawTextCheckmark(); + break; + } + case 2: + { + pN->AddBBox(0, 0, 20, 20); + pN->DrawTextCircle(sColor); + pR->AddBBox(0, 0, 20, 20); + pR->DrawTextCircle(sColor); + break; + } case 3: { - CAnnotationAppearance* pAP = new CAnnotationAppearance(m_pXref, {0, 0, 20, 20}); - Add("AP", pAP); - - pAP->DrawTextComment(); + pN->AddBBox(0, 0, 24, 24); + pN->DrawTextCommentN(sColor); + pR->AddBBox(0, 0, 24, 24); + pR->DrawTextCommentR(sColor); + break; + } + case 4: + { + pN->AddBBox(0, 0, 19, 19); + pN->DrawTextCross(sColor); + pR->AddBBox(0, 0, 19, 19); + pR->DrawTextCross(sColor); + break; + } + case 5: + { + pN->AddBBox(0, 0, 20, 20); + pN->DrawTextCrossHairs(sColor); + pR->AddBBox(0, 0, 20, 20); + pR->DrawTextCrossHairs(sColor); + break; + } + case 6: + { + pN->AddBBox(0, 0, 20, 20); + pN->DrawTextHelp(sColor); + pR->AddBBox(0, 0, 20, 20); + pR->DrawTextHelp(sColor); + break; + } + case 7: + { + pN->AddBBox(0, 0, 17, 20); + pN->DrawTextInsert(sColor); + pR->AddBBox(0, 0, 17, 20); + pR->DrawTextInsert(sColor); + break; + } + case 8: + { + pN->AddBBox(0, 0, 13, 18); + pN->DrawTextKey(sColor); + pR->AddBBox(0, 0, 13, 18); + pR->DrawTextKey(sColor); + break; + } + case 9: + { + pN->AddBBox(0, 0, 13, 20); + pN->DrawTextNewParagraph(sColor); + pR->AddBBox(0, 0, 13, 20); + pR->DrawTextNewParagraph(sColor); + break; + } + case 11: + { + pN->AddBBox(0, 0, 20, 20); + pN->DrawTextParagraph(sColor); + pR->AddBBox(0, 0, 20, 20); + pR->DrawTextParagraph(sColor); + break; + } + case 12: + { + pN->AddBBox(0, 0, 20, 20); + pN->DrawTextRightArrow(sColor); + pR->AddBBox(0, 0, 20, 20); + pR->DrawTextRightArrow(sColor); + break; + } + case 13: + { + pN->AddBBox(0, 0, 20, 17); + pN->DrawTextRightPointer(sColor); + pR->AddBBox(0, 0, 20, 17); + pR->DrawTextRightPointer(sColor); + break; + } + case 14: + { + pN->AddBBox(0, 0, 20, 19); + pN->DrawTextStar(sColor); + pR->AddBBox(0, 0, 20, 19); + pR->DrawTextStar(sColor); + break; + } + case 15: + { + pN->AddBBox(0, 0, 17, 20); + pN->DrawTextUpArrow(sColor); + pR->AddBBox(0, 0, 17, 20); + pR->DrawTextUpArrow(sColor); + break; + } + case 16: + { + pN->AddBBox(0, 0, 17, 17); + pN->DrawTextUpLeftArrow(sColor); + pR->AddBBox(0, 0, 17, 17); + pR->DrawTextUpLeftArrow(sColor); break; } case 10: default: { + pN->AddBBox(0, 0, 18, 20); + pN->DrawTextNote(sColor); + pR->AddBBox(0, 0, 18, 20); + pR->DrawTextNote(sColor); break; } } @@ -418,41 +665,44 @@ namespace PdfWriter pArray->Add(pArrayI); for (int i = 0; i < arrInk.size(); ++i) - pArrayI->Add(i % 2 == 0 ? arrInk[i] : (m_dPageHeight - arrInk[i])); + pArrayI->Add(i % 2 == 0 ? (arrInk[i] + m_dPageX) : (m_dPageH - arrInk[i])); } } //---------------------------------------------------------------------------------------- // CLineAnnotation //---------------------------------------------------------------------------------------- - CLineAnnotation::CLineAnnotation(CXref* pXref) : CMarkupAnnotation(pXref, AnnotLine) + CLineAnnotation::CLineAnnotation(CXref* pXref) : CMarkupAnnotation(pXref, AnnotLine), dL{0.0, 0.0, 0.0, 0.0} { + m_nLE1 = ELineEndType::None; + m_nLE2 = ELineEndType::None; } void CLineAnnotation::SetCap(bool bCap) { Add("Open", new CBoolObject(bCap)); } - void CLineAnnotation::SetIT(const BYTE& nIT) + void CLineAnnotation::SetIT(BYTE nIT) { std::string sValue; switch (nIT) { - case 0: - { sValue = "LineDimension"; break; } - case 1: - { sValue = "LineArrow"; break; } + case ELineIntentType::LineDimension: sValue = "LineDimension"; break; + case ELineIntentType::LineArrow: sValue = "LineArrow"; break; + default: return; } Add("IT", sValue.c_str()); } - void CLineAnnotation::SetCP(const BYTE& nCP) + void CLineAnnotation::SetCP(BYTE nCP) { + if (!Get("Open")) + return; + std::string sValue; switch (nCP) { - case 0: - { sValue = "Inline"; break; } - case 1: - { sValue = "Top"; break; } + case ECaptionPositioning::Inline: sValue = "Inline"; break; + case ECaptionPositioning::Top: sValue = "Top"; break; + default: return; } Add("CP", sValue.c_str()); @@ -469,36 +719,7 @@ namespace PdfWriter { Add("LLO", dLLO); } - std::string AddLE(const BYTE& nLE) - { - std::string sValue; - switch (nLE) - { - case 0: - { sValue = "Square"; break; } - case 1: - { sValue = "Circle"; break; } - case 2: - { sValue = "Diamond"; break; } - case 3: - { sValue = "OpenArrow"; break; } - case 4: - { sValue = "ClosedArrow"; break; } - case 5: - { sValue = "None"; break; } - case 6: - { sValue = "Butt"; break; } - case 7: - { sValue = "ROpenArrow"; break; } - case 8: - { sValue = "RClosedArrow"; break; } - case 9: - { sValue = "Slash"; break; } - } - - return sValue; - } - void CLineAnnotation::SetLE(const BYTE& nLE1, const BYTE& nLE2) + void CLineAnnotation::SetLE(BYTE nLE1, BYTE nLE2) { CArrayObject* pArray = new CArrayObject(); if (!pArray) @@ -508,6 +729,9 @@ namespace PdfWriter pArray->Add(AddLE(nLE1).c_str()); pArray->Add(AddLE(nLE2).c_str()); + + m_nLE1 = ELineEndType(nLE1); + m_nLE2 = ELineEndType(nLE2); } void CLineAnnotation::SetL(const double& dL1, const double& dL2, const double& dL3, const double& dL4) { @@ -517,10 +741,15 @@ namespace PdfWriter Add("L", pArray); - pArray->Add(dL1); - pArray->Add(m_dPageHeight - dL2); - pArray->Add(dL3); - pArray->Add(m_dPageHeight - dL4); + dL[0] = dL1 + m_dPageX; + dL[1] = m_dPageH - dL2; + dL[2] = dL3 + m_dPageX; + dL[3] = m_dPageH - dL4; + + pArray->Add(dL[0]); + pArray->Add(dL[1]); + pArray->Add(dL[2]); + pArray->Add(dL[3]); } void CLineAnnotation::SetCO(const double& dCO1, const double& dCO2) { @@ -537,6 +766,300 @@ namespace PdfWriter { AddToVectorD(this, "IC", arrIC); } + void AdjustLineEndpoint(ELineEndType nType, double x, double y, double dx, double dy, double w, double& tx, double& ty) + { + tx = x; + ty = y; + + switch (nType) + { + case ELineEndType::ClosedArrow: + case ELineEndType::OpenArrow: + case ELineEndType::Diamond: + { + tx += w * dx; + if ((dx > 0.001 && dy > 0) || (dx < -0.001 && dy < 0)) + ty += w * dy; + break; + } + case ELineEndType::Square: + case ELineEndType::Circle: + { + if ((dx > -0.02 && dy < 0.02) || (dx < 0.02 && dy > -0.02)) + tx += w * dx; + break; + } + case ELineEndType::Slash: + case ELineEndType::Butt: + case ELineEndType::ROpenArrow: + case ELineEndType::RClosedArrow: + case ELineEndType::None: + default: + break; + } + } + void SreamWriteXYMove(CStream* pStream, double x, double y) + { + pStream->WriteReal(x); + pStream->WriteChar(' '); + pStream->WriteReal(y); + pStream->WriteStr(" m\012"); + } + void SreamWriteXYLine(CStream* pStream, double x, double y) + { + pStream->WriteReal(x); + pStream->WriteChar(' '); + pStream->WriteReal(y); + pStream->WriteStr(" l\012"); + } + void SreamWriteXYCurve(CStream* pStream, double x1, double y1, double x2, double y2, double x3, double y3) + { + pStream->WriteReal(x1); + pStream->WriteChar(' '); + pStream->WriteReal(y1); + pStream->WriteChar(' '); + pStream->WriteReal(x2); + pStream->WriteChar(' '); + pStream->WriteReal(y2); + pStream->WriteChar(' '); + pStream->WriteReal(x3); + pStream->WriteChar(' '); + pStream->WriteReal(y3); + pStream->WriteStr(" c\012"); + } + void StreamWriteRect(CStream* pStream, double x1, double y1, double x2, double y2) + { + pStream->WriteReal(x1); + pStream->WriteChar(' '); + pStream->WriteReal(y1); + pStream->WriteChar(' '); + pStream->WriteReal(x2); + pStream->WriteChar(' '); + pStream->WriteReal(y2); + pStream->WriteStr(" re\012"); + } + void SreamWriteCircle(CStream* pStream, double cx, double cy, double r) + { + double bezierCircle = 0.55228475 * r; + SreamWriteXYMove(pStream, cx + r, cy); + SreamWriteXYCurve(pStream, cx + r, cy + bezierCircle, cx + bezierCircle, cy + r, cx, cy + r); + SreamWriteXYCurve(pStream, cx - bezierCircle, cy + r, cx - r, cy + bezierCircle, cx - r, cy); + SreamWriteXYCurve(pStream, cx - r, cy - bezierCircle, cx - bezierCircle, cy - r, cx, cy - r); + SreamWriteXYCurve(pStream, cx + bezierCircle, cy - r, cx + r, cy - bezierCircle, cx + r, cy); + } + void DrawArrow(CStream* pStream, ELineEndType nType, double x, double y, double dx, double dy, double w) + { + double lineEndSize1 = 3, pi = 3.14159265358979323846; + switch (nType) + { + case ELineEndType::Butt: + { + w *= lineEndSize1; + SreamWriteXYMove(pStream, x + w * dy, y - w * dx); + SreamWriteXYLine(pStream, x - w * dy, y + w * dx); + pStream->WriteStr("S\012"); + break; + } + case ELineEndType::Circle: + { + SreamWriteCircle(pStream, x, y, w * lineEndSize1); + pStream->WriteStr("h\012B\012"); + break; + } + case ELineEndType::Diamond: + { + w *= lineEndSize1; + SreamWriteXYMove(pStream, x - w, y); + SreamWriteXYLine(pStream, x, y + w); + SreamWriteXYLine(pStream, x + w, y); + SreamWriteXYLine(pStream, x, y - w); + pStream->WriteStr("b\012"); + break; + } + case ELineEndType::OpenArrow: + case ELineEndType::ClosedArrow: + { + w *= lineEndSize1 * lineEndSize1; + double d32 = pi * 32.0 / 180.0; + double d28 = pi * 28.0 / 180.0; + if ((dx > 0.001 && dy < 0) || (dx < -0.001 && dy > 0)) + { + SreamWriteXYMove(pStream, x + w * cos(d32) * dx + w * sin(d32) * dy, y + w * cos(d32) * dy - w * sin(d32) * dx); + SreamWriteXYLine(pStream, x, y); + SreamWriteXYLine(pStream, x + w * cos(d28) * dx - w * sin(d28) * dy, y + w * cos(d28) * dy + w * sin(d28) * dx); + } + else + { + double dCos = w * cos(pi / 6.0); + double dSin = w * sin(pi / 6.0); + + SreamWriteXYMove(pStream, x + dCos * dx + dSin * dy, y + dCos * dy - dSin * dx); + SreamWriteXYLine(pStream, x, y); + SreamWriteXYLine(pStream, x + dCos * dx - dSin * dy, y + dCos * dy + dSin * dx); + } + pStream->WriteStr(nType == ELineEndType::OpenArrow ? "S\012" : "b\012"); + break; + } + case ELineEndType::ROpenArrow: + case ELineEndType::RClosedArrow: + { + x -= cos(pi / 18.0) * dx * w; + y -= cos(pi / 18.0) * dy * w; + w *= lineEndSize1 * lineEndSize1; + double dCos = w * cos(pi / 6.0); + double dSin = w * sin(pi / 6.0); + SreamWriteXYMove(pStream, x - dCos * dx + dSin * dy, y - dCos * dy - dSin * dx); + SreamWriteXYLine(pStream, x, y); + SreamWriteXYLine(pStream, x - dCos * dx - dSin * dy, y - dCos * dy + dSin * dx); + pStream->WriteStr(nType == ELineEndType::ROpenArrow ? "S\012" : "b\012"); + break; + } + case ELineEndType::Slash: + { + w *= lineEndSize1 * lineEndSize1; + double dCos = w * cos(pi / 6.0); + double dSin = w * sin(pi / 6.0); + SreamWriteXYMove(pStream, x + dCos * dy - dSin * dx, y - dCos * dx - dSin * dy); + SreamWriteXYLine(pStream, x - dCos * dy + dSin * dx, y + dCos * dx + dSin * dy); + pStream->WriteStr("S\012"); + break; + } + case ELineEndType::Square: + { + w *= lineEndSize1; + pStream->WriteReal(x - w); + pStream->WriteChar(' '); + pStream->WriteReal(y - w); + pStream->WriteChar(' '); + pStream->WriteReal(w * 2); + pStream->WriteChar(' '); + pStream->WriteReal(w * 2); + pStream->WriteStr(" re\012"); + pStream->WriteStr("B\012"); + break; + } + case ELineEndType::None: + default: + { + break; + } + } + } + void DrawLineArrow(CStream* pStream, double dBorderSize, double x1, double y1, double x2, double y2, ELineEndType nLE1, ELineEndType nLE2, double dLL = 0, double dLLO = 0, double dLLE = 0) + { + double dDX = x2 - x1; + double dDY = y2 - y1; + double dLen = sqrt(dDX * dDX + dDY * dDY); + if (dLen > 0) + { + dDX /= dLen; + dDY /= dLen; + } + + double lx1, ly1, lx2, ly2; + double ax1, ay1, ax2, ay2; + double bx1, by1, bx2, by2; + if (dLL != 0) + { + ax1 = x1 + dLLO * dDY; + ay1 = y1 - dLLO * dDX; + lx1 = ax1 + dLL * dDY; + ly1 = ay1 - dLL * dDX; + bx1 = lx1 + dLLE * dDY; + by1 = ly1 - dLLE * dDX; + ax2 = x2 + dLLO * dDY; + ay2 = y2 - dLLO * dDX; + lx2 = ax2 + dLL * dDY; + ly2 = ay2 - dLL * dDX; + bx2 = lx2 + dLLE * dDY; + by2 = ly2 - dLLE * dDX; + } + else + { + lx1 = x1; + ly1 = y1; + lx2 = x2; + ly2 = y2; + ax1 = ay1 = ax2 = ay2 = 0; + bx1 = by1 = bx2 = by2 = 0; + } + + double tx1, ty1, tx2, ty2; + AdjustLineEndpoint(nLE1, lx1, ly1, dDX, dDY, dBorderSize, tx1, ty1); + AdjustLineEndpoint(nLE2, lx2, ly2, -dDX, -dDY, dBorderSize, tx2, ty2); + + if (dLL) + { + SreamWriteXYMove(pStream, ax1, ay1); + SreamWriteXYLine(pStream, bx1, by1); + + SreamWriteXYMove(pStream, ax2, ay2); + SreamWriteXYLine(pStream, bx2, by2); + } + + SreamWriteXYMove(pStream, tx1, ty1); + SreamWriteXYLine(pStream, tx2, ty2); + pStream->WriteStr("S\012"); + + DrawArrow(pStream, nLE1, tx1, ty1, dDX, dDY, dBorderSize); + DrawArrow(pStream, nLE2, tx2, ty2, -dDX, -dDY, dBorderSize); + } + void CLineAnnotation::SetAP() + { + CAnnotAppearance* pAppearance = new CAnnotAppearance(m_pXref, this); + Add("AP", pAppearance); + CAnnotAppearanceObject* pNormal = pAppearance->GetNormal(); + CStream* pStream = pNormal->GetStream(); + + pNormal->AddBBox(GetRect().fLeft, GetRect().fBottom, GetRect().fRight, GetRect().fTop); + pNormal->AddMatrix(1, 0, 0, 1, -GetRect().fLeft, -GetRect().fBottom); + + if (GetBorderType() == EBorderType::Dashed) + pStream->WriteStr(GetBorderDash().c_str()); + + double dBorderSize = GetBorderWidth(); + pStream->WriteReal(dBorderSize); + pStream->WriteStr(" w\012"); + + CObjectBase* pObj = Get("IC"); + if (pObj && pObj->GetType() == object_type_ARRAY) + { + pStream->WriteStr(GetColor(dynamic_cast(pObj), false).c_str()); + pStream->WriteStr("\012"); + } + + pStream->WriteStr(GetColor(dynamic_cast(Get("C")), true).c_str()); + pStream->WriteStr("\012"); + + pObj = Get("CA"); + if (pObj && pObj->GetType() == object_type_REAL) + { + float dAlpha = ((CRealObject*)pObj)->Get(); + if (dAlpha != 1) + { + CExtGrState* pExtGrState = m_pDocument->GetExtGState(dAlpha, dAlpha); + const char* sExtGrStateName = m_pDocument->GetFieldsResources()->GetExtGrStateName(pExtGrState); + if (sExtGrStateName) + { + pStream->WriteEscapeName(sExtGrStateName); + pStream->WriteStr(" gs\012"); + } + } + } + + double dLL = 0, dLLE = 0, dLLO = 0; + pObj = Get("LL"); + if (pObj && pObj->GetType() == object_type_REAL) + dLL = ((CRealObject*)pObj)->Get(); + pObj = Get("LLE"); + if (pObj && pObj->GetType() == object_type_REAL) + dLLE = ((CRealObject*)pObj)->Get(); + pObj = Get("LLO"); + if (pObj && pObj->GetType() == object_type_REAL) + dLLO = ((CRealObject*)pObj)->Get(); + + DrawLineArrow(pStream, dBorderSize, dL[0], dL[1], dL[2], dL[3], m_nLE1, m_nLE2, dLL, dLLE, dLLO); + } //---------------------------------------------------------------------------------------- // CPopupAnnotation //---------------------------------------------------------------------------------------- @@ -557,13 +1080,34 @@ namespace PdfWriter CFreeTextAnnotation::CFreeTextAnnotation(CXref* pXref) : CMarkupAnnotation(pXref, AnnotFreeText) { } - void CFreeTextAnnotation::SetQ(const BYTE& nQ) + void CFreeTextAnnotation::SetDA(CFontDict* pFont, const double& dFontSize, const std::vector& arrC) { - Add("Q", (int)nQ); - } - void CFreeTextAnnotation::SetIT(const BYTE& nIT) - { - std::string sValue; + CResourcesDict* pFieldsResources = m_pDocument->GetFieldsResources(); + const char* sFontName = pFieldsResources->GetFontName(pFont); + + std::vector _arrC = arrC; + if (arrC.empty()) + _arrC = {0}; + std::string sDA = GetColor(_arrC, false); + if (sFontName) + { + sDA.append(" /"); + sDA.append(sFontName); + } + + sDA.append(" "); + sDA.append(std::to_string(dFontSize)); + sDA.append(" Tf"); + + Add("DA", new CStringObject(sDA.c_str())); + } + void CFreeTextAnnotation::SetQ(BYTE nQ) + { + Add("Q", (int)nQ); + } + void CFreeTextAnnotation::SetIT(BYTE nIT) + { + std::string sValue; switch (nIT) { case 0: @@ -572,32 +1116,24 @@ namespace PdfWriter { sValue = "FreeTextCallout"; break; } case 2: { sValue = "FreeTextTypeWriter"; break; } + default: { return; } } Add("IT", sValue.c_str()); } - void CFreeTextAnnotation::SetLE(const BYTE& nLE) + void CFreeTextAnnotation::SetLE(BYTE nLE) { Add("LE", AddLE(nLE).c_str()); } + void CFreeTextAnnotation::SetRotate(int nRotate) + { + Add("Rotate", nRotate); + } void CFreeTextAnnotation::SetDS(const std::wstring& wsDS) { std::string sValue = U_TO_UTF8(wsDS); Add("DS", new CStringObject(sValue.c_str())); } - void AddRD(CDictObject* pObj, const double& dRD1, const double& dRD2, const double& dRD3, const double& dRD4) - { - CArrayObject* pArray = new CArrayObject(); - if (!pArray) - return; - - pObj->Add("RD", pArray); - - pArray->Add(dRD1); - pArray->Add(dRD2); - pArray->Add(dRD3); - pArray->Add(dRD4); - } void CFreeTextAnnotation::SetRD(const double& dRD1, const double& dRD2, const double& dRD3, const double& dRD4) { AddRD(this, dRD1, dRD2, dRD3, dRD4); @@ -611,7 +1147,11 @@ namespace PdfWriter Add("CL", pArray); for (int i = 0; i < arrCL.size(); ++i) - pArray->Add(i % 2 == 0 ? arrCL[i] : (m_dPageHeight - arrCL[i])); + pArray->Add(i % 2 == 0 ? (arrCL[i] + m_dPageX) : (m_dPageH - arrCL[i])); + } + void CFreeTextAnnotation::SetIC(const std::vector& arrIC) + { + SetC(arrIC); } //---------------------------------------------------------------------------------------- // CTextMarkupAnnotation @@ -620,7 +1160,7 @@ namespace PdfWriter { m_nSubtype = AnnotHighLight; } - void CTextMarkupAnnotation::SetSubtype(const BYTE& nSubtype) + void CTextMarkupAnnotation::SetSubtype(BYTE nSubtype) { switch (nSubtype) { @@ -630,6 +1170,7 @@ namespace PdfWriter { m_nSubtype = AnnotUnderline; break; } case 10: { m_nSubtype = AnnotSquiggly; break; } + default: case 11: { m_nSubtype = AnnotStrikeOut; break; } } @@ -645,7 +1186,115 @@ namespace PdfWriter Add("QuadPoints", pArray); for (int i = 0; i < arrQuadPoints.size(); ++i) - pArray->Add(i % 2 == 0 ? arrQuadPoints[i] : (m_dPageHeight - arrQuadPoints[i])); + pArray->Add(i % 2 == 0 ? (arrQuadPoints[i] + m_dPageX) : (m_dPageH - arrQuadPoints[i])); + } + void CTextMarkupAnnotation::SetAP(const std::vector& arrQuadPoints, const double& dCA) + { + CAnnotAppearance* pAP = new CAnnotAppearance(m_pXref, this); + Add("AP", pAP); + CAnnotAppearanceObject* pN = pAP->GetNormal(); + CStream* pStream = pN->GetStream(); + + pN->AddBBox(GetRect().fLeft, GetRect().fBottom, GetRect().fRight, GetRect().fTop); + pN->AddMatrix(1, 0, 0, 1, -GetRect().fLeft, -GetRect().fBottom); + + CExtGrState* pExtGrState = m_pDocument->GetExtGState(dCA, dCA, m_nSubtype == AnnotHighLight ? blendmode_Multiply : blendmode_Unknown); + const char* sExtGrStateName = m_pDocument->GetFieldsResources()->GetExtGrStateName(pExtGrState); + if (sExtGrStateName) + { + pStream->WriteEscapeName(sExtGrStateName); + pStream->WriteStr(" gs\012"); + } + std::string sColor = GetColor(dynamic_cast(Get("C")), m_nSubtype != AnnotHighLight); + pStream->WriteStr(sColor.c_str()); + pStream->WriteChar('\012'); + + switch (m_nSubtype) + { + case AnnotHighLight: + { + pStream->WriteStr("1 w\012"); + + for (int i = 0; i < arrQuadPoints.size(); i += 8) + { + pStream->WriteReal(arrQuadPoints[i] + m_dPageX); + pStream->WriteChar(' '); + pStream->WriteReal(m_dPageH - arrQuadPoints[i + 1]); + pStream->WriteStr(" m\012"); + + pStream->WriteReal(arrQuadPoints[i + 2] + m_dPageX); + pStream->WriteChar(' '); + pStream->WriteReal(m_dPageH - arrQuadPoints[i + 3]); + pStream->WriteStr(" l\012"); + + pStream->WriteReal(arrQuadPoints[i + 6] + m_dPageX); + pStream->WriteChar(' '); + pStream->WriteReal(m_dPageH - arrQuadPoints[i + 7]); + pStream->WriteStr(" l\012"); + + pStream->WriteReal(arrQuadPoints[i + 4] + m_dPageX); + pStream->WriteChar(' '); + pStream->WriteReal(m_dPageH - arrQuadPoints[i + 5]); + pStream->WriteStr(" l\012f\012"); + } + break; + } + case AnnotSquiggly: + case AnnotUnderline: + { + for (int i = 0; i < arrQuadPoints.size(); i += 8) + { + double dX = arrQuadPoints[i + 2] - arrQuadPoints[i]; + double dY = arrQuadPoints[i + 3] - arrQuadPoints[i + 1]; + double dAngle = atan2(dY, dX); + double dHeight = sqrt(pow(arrQuadPoints[i] - arrQuadPoints[i + 4], 2) + pow(arrQuadPoints[i + 1] - arrQuadPoints[i + 5], 2)); + double dLineWidth = std::max(0.5, dHeight * 0.075); + double dIndentX = sin(dAngle) * dLineWidth * 1.9; + double dIndentY = cos(dAngle) * dLineWidth * 1.9; + + pStream->WriteReal(dLineWidth); + pStream->WriteStr(" w\012"); + + pStream->WriteReal(arrQuadPoints[i + 4] + m_dPageX + dIndentX); + pStream->WriteChar(' '); + pStream->WriteReal(m_dPageH - arrQuadPoints[i + 5] + dIndentY); + pStream->WriteStr(" m\012"); + + pStream->WriteReal(arrQuadPoints[i + 6] + m_dPageX + dIndentX); + pStream->WriteChar(' '); + pStream->WriteReal(m_dPageH - arrQuadPoints[i + 7] + dIndentY); + pStream->WriteStr(" l\012S\012"); + } + break; + } + case AnnotStrikeOut: + default: + { + for (int i = 0; i < arrQuadPoints.size(); i += 8) + { + double dX1 = arrQuadPoints[i] + (arrQuadPoints[i + 4] - arrQuadPoints[i]) / 2.0; + double dY1 = arrQuadPoints[i + 1] + (arrQuadPoints[i + 5] - arrQuadPoints[i + 1]) / 2.0; + double dX2 = arrQuadPoints[i + 2] + (arrQuadPoints[i + 6] - arrQuadPoints[i + 2]) / 2.0; + double dY2 = arrQuadPoints[i + 3] + (arrQuadPoints[i + 7] - arrQuadPoints[i + 3]) / 2.0; + double dHeight = sqrt(pow(arrQuadPoints[i] - arrQuadPoints[i + 4], 2) + pow(arrQuadPoints[i + 1] - arrQuadPoints[i + 5], 2)); + double dLineWidth = std::max(0.5, dHeight * 0.075); + + pStream->WriteReal(dLineWidth); + pStream->WriteStr(" w\012"); + + pStream->WriteReal(dX1 + m_dPageX); + pStream->WriteChar(' '); + pStream->WriteReal(m_dPageH - dY1); + pStream->WriteStr(" m\012"); + + pStream->WriteReal(dX2 + m_dPageX); + pStream->WriteChar(' '); + pStream->WriteReal(m_dPageH - dY2); + pStream->WriteStr(" l\012S\012"); + } + break; + } + } } //---------------------------------------------------------------------------------------- // CSquareCircleAnnotation @@ -654,12 +1303,13 @@ namespace PdfWriter { m_nSubtype = AnnotSquare; } - void CSquareCircleAnnotation::SetSubtype(const BYTE& nSubtype) + void CSquareCircleAnnotation::SetSubtype(BYTE nSubtype) { switch (nSubtype) { case 4: { m_nSubtype = AnnotSquare; break; } + default: case 5: { m_nSubtype = AnnotCircle; break; } } @@ -681,7 +1331,7 @@ namespace PdfWriter { m_nSubtype = AnnotPolygon; } - void CPolygonLineAnnotation::SetIT(const BYTE& nIT) + void CPolygonLineAnnotation::SetIT(BYTE nIT) { std::string sValue; switch (nIT) @@ -692,23 +1342,25 @@ namespace PdfWriter { sValue = "PolyLineDimension"; break; } case 2: { sValue = "PolygonDimension"; break; } + default: { return; } } Add("IT", sValue.c_str()); } - void CPolygonLineAnnotation::SetSubtype(const BYTE& nSubtype) + void CPolygonLineAnnotation::SetSubtype(BYTE nSubtype) { switch (nSubtype) { case 6: { m_nSubtype = AnnotPolygon; break; } + default: case 7: { m_nSubtype = AnnotPolyLine; break; } } Add("Subtype", c_sAnnotTypeNames[(int)m_nSubtype]); } - void CPolygonLineAnnotation::SetLE(const BYTE& nLE1, const BYTE& nLE2) + void CPolygonLineAnnotation::SetLE(BYTE nLE1, BYTE nLE2) { CArrayObject* pArray = new CArrayObject(); if (!pArray) @@ -732,7 +1384,7 @@ namespace PdfWriter Add("Vertices", pArray); for (int i = 0; i < arrVertices.size(); ++i) - pArray->Add(i % 2 == 0 ? arrVertices[i] : (m_dPageHeight - arrVertices[i])); + pArray->Add(i % 2 == 0 ? (arrVertices[i] + m_dPageX) : (m_dPageH - arrVertices[i])); } //---------------------------------------------------------------------------------------- // CCaretAnnotation @@ -744,7 +1396,7 @@ namespace PdfWriter { AddRD(this, dRD1, dRD2, dRD3, dRD4); } - void CCaretAnnotation::SetSy(const BYTE& nSy) + void CCaretAnnotation::SetSy(BYTE nSy) { std::string sValue; switch (nSy) @@ -753,46 +1405,73 @@ namespace PdfWriter { sValue = "P"; break; } case 1: { sValue = "None"; break; } + default: { return; } } Add("IT", sValue.c_str()); } //---------------------------------------------------------------------------------------- + // CStampAnnotation + //---------------------------------------------------------------------------------------- + CStampAnnotation::CStampAnnotation(CXref* pXref) : CMarkupAnnotation(pXref, AnnotStamp), m_pAPStream(NULL) + { + } + void CStampAnnotation::SetRotate(double nRotate) + { + Add("Rotate", nRotate); + + if (!m_pAPStream) + return; + + CArrayObject* pArray = new CArrayObject(); + if (!pArray) + return; + + double ca = cos(nRotate / 180.0 * M_PI); + double sa = sin(nRotate / 180.0 * M_PI); + m_pAPStream->Add("Matrix", pArray); + pArray->Add(ca); + pArray->Add(sa); + pArray->Add(-sa); + pArray->Add(ca); + pArray->Add(0); + pArray->Add(0); + } + void CStampAnnotation::SetName(const std::wstring& wsName) + { + std::string sValue = U_TO_UTF8(wsName); + Add("Name", sValue.c_str()); + } + void CStampAnnotation::SetAPStream(CDictObject* pStream) + { + m_pAPStream = pStream; + } + //---------------------------------------------------------------------------------------- // CWidgetAnnotation //---------------------------------------------------------------------------------------- CWidgetAnnotation::CWidgetAnnotation(CXref* pXref, EAnnotType eType) : CAnnotation(pXref, eType) { - Add("Ff", 0); - - m_pMK = NULL; - m_pParent = NULL; - m_pDocument = NULL; + m_pMK = NULL; + m_pParent = NULL; + m_pAppearance = NULL; + m_pFont = NULL; + m_dFontSizeAP = 0; + m_nQ = 0; + m_dFontSize = 10.0; + m_bBold = false; + m_bItalic = false; + m_nSubtype = WidgetUnknown; } - void CWidgetAnnotation::SetDocument(CDocument* pDocument) + void CWidgetAnnotation::SetSubtype(BYTE nSubtype) { - m_pDocument = pDocument; + m_nSubtype = (EWidgetType)nSubtype; } - void CWidgetAnnotation::SetDA(CFontDict* pFont, const double& dFontSize, const std::vector& arrTC) + void CWidgetAnnotation::SetDA(CFontDict* pFont, const double& dFontSize, const double& dFontSizeAP, const std::vector& arrTC) { CResourcesDict* pFieldsResources = m_pDocument->GetFieldsResources(); - const char* sFontName = pFieldsResources->GetFontName(pFont); - std::string sDA; - for (double dColoc : arrTC) - { - sDA.append(std::to_string(dColoc)); - sDA.append(" "); - } - if (arrTC.size() == 3) - sDA.append("rg"); - else if (arrTC.size() == 4) - sDA.append("k"); - else if (arrTC.size() == 1) - sDA.append("g"); - else - sDA.append("sc"); - + std::string sDA = GetColor(arrTC, false); if (sFontName) { sDA.append(" /"); @@ -803,7 +1482,20 @@ namespace PdfWriter sDA.append(std::to_string(dFontSize)); sDA.append(" Tf"); - Add("DA", new CStringObject(sDA.c_str(), false, true)); + CDictObject* pOwner = GetObjOwnValue("DA"); + if (pOwner) + pOwner->Remove("DA"); + Add("DA", new CStringObject(sDA.c_str())); + + m_arrTC = arrTC; + m_dFontSizeAP = dFontSizeAP; + } + void CWidgetAnnotation::SetFont(CFontCidTrueType* pFont, double dFontSize, bool bBold, bool bItalic) + { + m_pFont = pFont; + m_dFontSize = dFontSize; + m_bBold = bBold; + m_bItalic = bItalic; } CDictObject* CWidgetAnnotation::GetObjOwnValue(const std::string& sV) { @@ -822,19 +1514,49 @@ namespace PdfWriter } return NULL; } + CObjectBase* CWidgetAnnotation::GetObjValue(const std::string& sV) + { + CObjectBase* pRes = Get(sV); + if (pRes) + return pRes; + CDictObject* pParent = m_pParent; + while (pParent) + { + pRes = pParent->Get(sV); + if (pRes) + return pRes; + CObjectBase* pParent2 = pParent->Get("Parent"); + if (pParent2 && pParent2->GetType() == object_type_DICT) + pParent = (CDictObject*)pParent2; + else + return NULL; + } + return NULL; + } void CWidgetAnnotation::CheckMK() { if (!m_pMK) { + CObjectBase* pMK = Get("MK"); + if (pMK && pMK->GetType() == object_type_DICT) + { + m_pMK = (CDictObject*)pMK; + return; + } + m_pMK = new CDictObject(); Add("MK", m_pMK); } } - void CWidgetAnnotation::SetQ(const BYTE& nQ) + void CWidgetAnnotation::SetQ(BYTE nQ) { - Add("Q", (int)nQ); + CDictObject* pOwner = GetObjOwnValue("Q"); + if (!pOwner) + pOwner = this; + pOwner->Add("Q", (int)nQ); + m_nQ = nQ; } - void CWidgetAnnotation::SetH(const BYTE& nH) + void CWidgetAnnotation::SetH(BYTE nH) { std::string sValue; switch (nH) @@ -847,6 +1569,7 @@ namespace PdfWriter { sValue = "P"; break; } case 3: { sValue = "O"; break; } + default: { return; } } Add("H", sValue.c_str()); @@ -859,7 +1582,10 @@ namespace PdfWriter } void CWidgetAnnotation::SetFlag(const int& nFlag) { - Add("Ff", nFlag); + CDictObject* pOwner = GetObjOwnValue("Ff"); + if (!pOwner) + pOwner = this; + pOwner->Add("Ff", nFlag); } void CWidgetAnnotation::SetParent(CDictObject* pParent) { @@ -871,20 +1597,36 @@ namespace PdfWriter void CWidgetAnnotation::SetTU(const std::wstring& wsTU) { std::string sValue = U_TO_UTF8(wsTU); - Add("TU", new CStringObject(sValue.c_str())); + CDictObject* pOwner = GetObjOwnValue("TU"); + if (!pOwner) + pOwner = this; + pOwner->Add("TU", new CStringObject(sValue.c_str(), true)); } void CWidgetAnnotation::SetDS(const std::wstring& wsDS) { - + std::string sValue = U_TO_UTF8(wsDS); + CDictObject* pOwner = GetObjOwnValue("DS"); + if (!pOwner) + pOwner = this; + pOwner->Add("DS", new CStringObject(sValue.c_str(), true)); } void CWidgetAnnotation::SetDV(const std::wstring& wsDV) { - + std::string sValue = U_TO_UTF8(wsDV); + CDictObject* pOwner = GetObjOwnValue("DV"); + if (!pOwner) + pOwner = this; + pOwner->Add("DV", new CStringObject(sValue.c_str(), true)); } void CWidgetAnnotation::SetT(const std::wstring& wsT) { std::string sValue = U_TO_UTF8(wsT); - Add("T", new CStringObject(sValue.c_str())); + CDictObject* pOwner = GetObjOwnValue("T"); + if (!pOwner) + { + pOwner = this; + pOwner->Add("T", new CStringObject(sValue.c_str(), true)); + } } void CWidgetAnnotation::SetBC(const std::vector& arrBC) { @@ -896,16 +1638,161 @@ namespace PdfWriter CheckMK(); AddToVectorD(m_pMK, "BG", arrBG); } + void CWidgetAnnotation::AddAction(CAction* pAction) + { + if (!pAction) + return; + + if (pAction->m_sType == "A") + { + CDictObject* pOwner = GetObjOwnValue(pAction->m_sType); + if (!pOwner) + pOwner = this; + + pOwner->Add(pAction->m_sType.c_str(), pAction); + return; + } + + std::string sAA = pAction->m_sType; + CDictObject* pAA = NULL; + if (m_pParent && (sAA == "K" || sAA == "F" || sAA == "V" || sAA == "C")) + pAA = (CDictObject*)m_pParent->Get("AA"); + else if (sAA == "E" || sAA == "X" || sAA == "D" || sAA == "U" || sAA == "Fo" || sAA == "Bl" || sAA == "PO" || sAA == "PC" || sAA == "PV" || sAA == "PI") + { + pAA = (CDictObject*)Get("AA"); + if (!pAA) + { + pAA = new CDictObject(); + Add("AA", pAA); + } + } + + if (!pAA) + { + pAA = (CDictObject*)GetObjValue("AA"); + if (!pAA) + { + pAA = new CDictObject(); + Add("AA", pAA); + } + } + + if (pAA) + pAA->Add(sAA.c_str(), pAction); + } + std::string CWidgetAnnotation::GetDAforAP(CFontDict* pFont) + { + CResourcesDict* pFieldsResources = m_pDocument->GetFieldsResources(); + const char* sFontName = pFieldsResources->GetFontName(pFont); + + std::string sDA = GetColor(m_arrTC, false); + if (sFontName) + { + sDA.append(" /"); + sDA.append(sFontName); + } + + sDA.append(" "); + sDA.append(std::to_string(m_dFontSizeAP)); + sDA.append(" Tf\012"); + + return sDA; + } + std::string CWidgetAnnotation::GetBGforAP(double dDiff) + { + if (m_pMK) + return GetColor(dynamic_cast(m_pMK->Get("BG")), false, dDiff); + return ""; + } + std::string CWidgetAnnotation::GetBCforAP() + { + if (m_pMK) + return GetColor(dynamic_cast(m_pMK->Get("BC")), true); + return ""; + } + bool CWidgetAnnotation::HaveBG() + { + if (!m_pMK) + return false; + CObjectBase* pObj = m_pMK->Get("BG"); + return pObj && pObj->GetType() == object_type_ARRAY; + } + bool CWidgetAnnotation::HaveBC() + { + if (!m_pMK) + return false; + CObjectBase* pObj = m_pMK->Get("BC"); + return pObj && pObj->GetType() == object_type_ARRAY; + } + void CWidgetAnnotation::APFromFakePage(CPage* pFakePage) + { + if (!m_pAppearance) + return; + CAnnotAppearanceObject* pNormal = m_pAppearance->GetNormal(); + pNormal->AddBBox(0, 0, GetWidth(), GetHeight()); + } + void CWidgetAnnotation::SetEmptyAP() + { + if (!m_pAppearance) + m_pAppearance = new CAnnotAppearance(m_pXref, this); + Add("AP", m_pAppearance); + CAnnotAppearanceObject* pAppearance = m_pAppearance->GetNormal(); + + double dHeight = fabs(m_oRect.fTop - m_oRect.fBottom); + double dWidth = fabs(m_oRect.fRight - m_oRect.fLeft); + + pAppearance->StartDraw(dWidth, dHeight); + pAppearance->EndDraw(); + } + void CWidgetAnnotation::SetAP(const std::wstring& wsValue, unsigned short* pCodes, unsigned int unCount, double dX, double dY, CFontCidTrueType** ppFonts, double* pShifts) + { + if (!m_pAppearance) + m_pAppearance = new CAnnotAppearance(m_pXref, this); + Add("AP", m_pAppearance); + CAnnotAppearanceObject* pNormal = m_pAppearance->GetNormal(); + pNormal->DrawSimpleText(wsValue, pCodes, unCount, m_pFont, m_dFontSize, dX, dY, 0, 0, 0, NULL, fabs(m_oRect.fRight - m_oRect.fLeft), fabs(m_oRect.fBottom - m_oRect.fTop), ppFonts, pShifts); + } + CAnnotAppearanceObject* CWidgetAnnotation::StartAP() + { + m_pAppearance = new CAnnotAppearance(m_pXref, this); + if (!m_pAppearance) + return NULL; + Add("AP", m_pAppearance); + CAnnotAppearanceObject* pNormal = m_pAppearance->GetNormal(); + pNormal->StartDrawText(m_pFont, m_dFontSize, 0, 0, 0, NULL, fabs(m_oRect.fRight - m_oRect.fLeft), fabs(m_oRect.fBottom - m_oRect.fTop)); + return pNormal; + } + void CWidgetAnnotation::AddLineToAP(const double& dX, const double& dY, unsigned short* pCodes, const unsigned int& unCodesCount, CFontCidTrueType** ppFonts, const double* pShifts) + { + if (!m_pAppearance) + return; + CAnnotAppearanceObject* pNormal = m_pAppearance->GetNormal(); + pNormal->DrawTextLine(dX, dY, pCodes, unCodesCount, ppFonts, pShifts); + } + void CWidgetAnnotation::EndAP() + { + if (!m_pAppearance) + return; + CAnnotAppearanceObject* pNormal = m_pAppearance->GetNormal(); + pNormal->EndDrawText(); + } //---------------------------------------------------------------------------------------- - // CButtonWidget + // CPushButtonWidget //---------------------------------------------------------------------------------------- - CButtonWidget::CButtonWidget(CXref* pXref) : CWidgetAnnotation(pXref, AnnotWidget) + CPushButtonWidget::CPushButtonWidget(CXref* pXref) : CWidgetAnnotation(pXref, AnnotWidget) { - Add("FT", "Btn"); - m_pIF = NULL; - } - void CButtonWidget::CheckIF() + m_nI = -1; + m_nRI = -1; + m_nIX = -1; + m_nTP = 0; + m_nScaleType = 0; + m_bRespectBorders = false; + m_bConstantProportions = true; + m_dShiftX = 0.5; + m_dShiftY = 0.5; + } + void CPushButtonWidget::CheckIF() { CheckMK(); @@ -915,32 +1802,18 @@ namespace PdfWriter m_pMK->Add("IF", m_pIF); } } - void CButtonWidget::SetV(bool bV) + void CPushButtonWidget::SetV(const std::wstring& wsV) { + std::string sV = U_TO_UTF8(wsV); CDictObject* pOwner = GetObjOwnValue("V"); if (!pOwner) - { - if (m_pParent) - { - if (bV) - m_pParent->Add("V", m_sAP_N_Yes.c_str()); - } - else - Add("V", (bV ? m_sAP_N_Yes.c_str() : "Off")); - } - else if (bV) - pOwner->Add("V", m_sAP_N_Yes.c_str()); - - // TODO - // Add("AS", (bV ? m_sAP_N_Yes.c_str() : "Off")); - } - void CButtonWidget::SetDV(const std::wstring& wsDV) - { - std::string sValue = U_TO_UTF8(wsDV); - Add("DV", sValue.c_str()); + pOwner = this; + pOwner->Add("V", new CStringObject(sV.c_str(), true)); } - void CButtonWidget::SetS(const BYTE& nS) + void CPushButtonWidget::SetS(BYTE nS) { + m_bConstantProportions = !nS; + CheckIF(); std::string sValue; @@ -950,16 +1823,22 @@ namespace PdfWriter { sValue = "P"; break; } case 1: { sValue = "A"; break; } + default: { return; } } m_pIF->Add("S", sValue.c_str()); } - void CButtonWidget::SetTP(const BYTE& nTP) + void CPushButtonWidget::SetTP(BYTE nTP) { - Add("TP", (int)nTP); + CheckMK(); + + m_pMK->Add("TP", (int)nTP); + m_nTP = nTP; } - void CButtonWidget::SetSW(const BYTE& nSW) + void CPushButtonWidget::SetSW(BYTE nSW) { + m_nScaleType = nSW; + CheckIF(); std::string sValue; @@ -973,41 +1852,41 @@ namespace PdfWriter { sValue = "B"; break; } case 3: { sValue = "S"; break; } + default: { return; } } m_pIF->Add("SW", sValue.c_str()); } - void CButtonWidget::SetStyle(const BYTE& nStyle) + void CPushButtonWidget::SetIFFlag(const int& nIFFlag) { - CheckMK(); - - std::string sValue; - switch (nStyle) - { - case 0: - { sValue = "4"; break; } - case 1: - { sValue = "8"; break; } - case 2: - { sValue = "u"; break; } - case 3: - { sValue = "l"; break; } - case 4: - { sValue = "H"; break; } - case 5: - { sValue = "n"; break; } - } + CheckIF(); - m_pMK->Add("CA", new CStringObject(sValue.c_str())); + m_bRespectBorders = (nIFFlag & (1 << 4)) ? false : true; + m_pIF->Add("FB", !m_bRespectBorders); } - void CButtonWidget::SetIFFlag(const int& nIFFlag) + void CPushButtonWidget::SetFlag(const int& nFlag) { - CheckIF(); - - m_pIF->Add("FB", (nIFFlag & (1 << 4)) ? true : false); + int nFlags = nFlag; + nFlags |= (1 << 16); + CWidgetAnnotation::SetFlag(nFlags); + } + void CPushButtonWidget::SetI(const int& nI) + { + m_nI = nI; } - void CButtonWidget::SetA(const double& dA1, const double& dA2) + void CPushButtonWidget::SetRI(const int& nRI) { + m_nRI = nRI; + } + void CPushButtonWidget::SetIX(const int& nIX) + { + m_nIX = nIX; + } + void CPushButtonWidget::SetA(const double& dA1, const double& dA2) + { + m_dShiftX = dA1; + m_dShiftY = dA2; + CheckIF(); CArrayObject* pArray = new CArrayObject(); @@ -1019,98 +1898,383 @@ namespace PdfWriter pArray->Add(dA1); pArray->Add(dA2); } - void CButtonWidget::SetCA(const std::wstring& wsCA) + void CPushButtonWidget::SetCA(const std::wstring& wsCA) { CheckMK(); std::string sValue = U_TO_UTF8(wsCA); - m_pMK->Add("CA", new CStringObject(sValue.c_str())); + m_pMK->Add("CA", new CStringObject(sValue.c_str(), true)); + m_wsCA = wsCA; } - void CButtonWidget::SetRC(const std::wstring& wsRC) + void CPushButtonWidget::SetRC(const std::wstring& wsRC) { CheckMK(); std::string sValue = U_TO_UTF8(wsRC); - m_pMK->Add("RC", new CStringObject(sValue.c_str())); + m_pMK->Add("RC", new CStringObject(sValue.c_str(), true)); + m_wsRC = wsRC; } - void CButtonWidget::SetAC(const std::wstring& wsAC) + void CPushButtonWidget::SetAC(const std::wstring& wsAC) { CheckMK(); std::string sValue = U_TO_UTF8(wsAC); - m_pMK->Add("AC", new CStringObject(sValue.c_str())); + m_pMK->Add("AC", new CStringObject(sValue.c_str(), true)); + m_wsAC = wsAC; + } + void CPushButtonWidget::SetAP(CXObject* pForm, BYTE nAP, unsigned short* pCodes, unsigned int unCount, double dX, double dY, double dLineW, double dLineH, CFontCidTrueType** ppFonts) + { + if (!m_pAppearance) + { + m_pAppearance = new CAnnotAppearance(m_pXref, this); + CObjectBase* pAP = Get("AP"); + if (pAP && pAP->GetType() == object_type_DICT) + { + CDictObject* pDAP = (CDictObject*)pAP; + CObjectBase* pAPi = pDAP->Get("N"); + if (pAPi) + { + CProxyObject* pNewAPi = new CProxyObject(pAPi->Copy(), true); + pNewAPi->Get()->SetRef(pAPi->GetObjId(), pAPi->GetGenNo()); + m_pAppearance->Add("N", pNewAPi); + } + pAPi = pDAP->Get("D"); + if (pAPi) + { + CProxyObject* pNewAPi = new CProxyObject(pAPi->Copy(), true); + pNewAPi->Get()->SetRef(pAPi->GetObjId(), pAPi->GetGenNo()); + m_pAppearance->Add("D", pNewAPi); + } + pAPi = pDAP->Get("R"); + if (pAPi) + { + CProxyObject* pNewAPi = new CProxyObject(pAPi->Copy(), true); + pNewAPi->Get()->SetRef(pAPi->GetObjId(), pAPi->GetGenNo()); + m_pAppearance->Add("R", pNewAPi); + } + } + } + + CAnnotAppearanceObject* pAppearance = NULL; + if (nAP == 0) + pAppearance = m_pAppearance->GetNormal(); + else if (nAP == 1) + pAppearance = m_pAppearance->GetRollover(); + else if (nAP == 2) + pAppearance = m_pAppearance->GetDown(); + if (!pAppearance) + return; + Add("AP", m_pAppearance); + + double dHeight = fabs(m_oRect.fTop - m_oRect.fBottom); + double dWidth = fabs(m_oRect.fRight - m_oRect.fLeft); + + pAppearance->StartDraw(dWidth, dHeight); + + if (pForm) + { + double dH = dHeight; + double dW = dWidth; + + double dOriginW = pForm->GetWidth(); + double dOriginH = pForm->GetHeight(); + + bool bNeedScale = (0 == m_nScaleType + || (2 == m_nScaleType && (dOriginH > dH || dOriginW > dW)) + || (3 == m_nScaleType && dOriginH < dH && dOriginW < dW)); + + double dBorderSize = m_oBorder.dWidth; + if (m_oBorder.nType == 1 || m_oBorder.nType == 3) + dBorderSize *= 2; + + double dDstW = dOriginW; + double dDstH = dOriginH; + double dDstX = 0; + double dDstY = 0; + + if (m_nTP == 2) + { + dH -= (dLineH + dBorderSize); + dDstY += (dLineH + dBorderSize); + } + if (m_nTP == 3) + dH -= (dLineH + dBorderSize); + if (m_nTP == 4) + dW -= (dLineW + dBorderSize); + if (m_nTP == 5) + { + dW -= (dLineW + dBorderSize); + dDstX += (dLineW + dBorderSize); + } + + if (m_bRespectBorders) + { + dDstX += 2 * dBorderSize; + dDstY += 2 * dBorderSize; + dH -= 4 * dBorderSize; + dW -= 4 * dBorderSize; + } + + if (bNeedScale) + { + if (!m_bConstantProportions) + { + dDstH = dH; + dDstW = dW; + } + else + { + double dScaleKoef = fmin(dW / dOriginW, dH / dOriginH); + dDstW = dScaleKoef * dOriginW; + dDstH = dScaleKoef * dOriginH; + } + } + + dDstX += (dW - dDstW) * m_dShiftX; + dDstY += (dH - dDstH) * m_dShiftY; + + pAppearance->DrawPictureInline(pForm->GetName().c_str(), dDstX, dDstY, dDstW / dOriginW, dDstH / dOriginH, m_bRespectBorders); + + CheckMK(); + std::string sAP = nAP == 0 ? "I" : (nAP == 1 ? "RI" : "IX"); + m_pMK->Add(sAP, pForm); + } + + if (pCodes) + { + pAppearance->StartText(m_pFont, m_dFontSize); + pAppearance->DrawTextLine(dX, dY, pCodes, unCount, ppFonts, NULL); + pAppearance->EndText(); + } + + pAppearance->EndDraw(); } - void CButtonWidget::SetAP_N_Yes(const std::wstring& wsAP_N_Yes) + //---------------------------------------------------------------------------------------- + // CCheckBoxWidget + //---------------------------------------------------------------------------------------- + CCheckBoxWidget::CCheckBoxWidget(CXref* pXref) : CWidgetAnnotation(pXref, AnnotWidget) + { + m_nSubtype = WidgetRadiobutton; + } + void CCheckBoxWidget::SetV(const std::wstring& wsV) + { + std::string sV = U_TO_UTF8(wsV); + CDictObject* pOwner = GetObjOwnValue("V"); + if (!pOwner) + pOwner = this; + + if (isdigit(sV[0])) + pOwner->Add("V", sV.c_str()); + else + pOwner->Add("V", new CStringObject(sV.c_str(), true)); + } + std::wstring CCheckBoxWidget::SetStyle(BYTE nStyle) + { + CheckMK(); + + std::string sValue; + switch (nStyle) + { + case 1: + { sValue = "8"; break; } + case 2: + { sValue = "u"; break; } + case 3: + { sValue = "l"; break; } + case 4: + { sValue = "H"; break; } + case 5: + { sValue = "n"; break; } + default: + case 0: + { sValue = "4"; break; } + } + + m_pMK->Add("CA", new CStringObject(sValue.c_str())); + + return UTF8_TO_U(sValue); + } + void CCheckBoxWidget::SetAP_N_Yes(const std::wstring& wsAP_N_Yes) { std::string sValue = U_TO_UTF8(wsAP_N_Yes); m_sAP_N_Yes = sValue; } + void CCheckBoxWidget::SwitchAP(const std::string& sV) + { + CObjectBase* pAP, *pAPN; + Add("AS", "Off"); + if (!m_sAP_N_Yes.empty()) + { + CObjectBase* pObj = GetObjValue("Opt"); + if (pObj && pObj->GetType() == object_type_ARRAY) + { + CArrayObject* pArr = (CArrayObject*)pObj; + for (int i = 0; i < pArr->GetCount(); ++i) + { + pObj = pArr->Get(i); + if (pObj->GetType() == object_type_ARRAY && ((CArrayObject*)pObj)->GetCount() > 0) + pObj = ((CArrayObject*)pObj)->Get(0); + if (pObj->GetType() == object_type_STRING) + { + CStringObject* pStr = (CStringObject*)pObj; + const BYTE* pBinary = pStr->GetString(); + if (pStr->GetLength() == m_sAP_N_Yes.length() && !StrCmp((const char*)pBinary, m_sAP_N_Yes.c_str())) + { + m_sAP_N_Yes = std::to_string(i); + SetV(UTF8_TO_U(m_sAP_N_Yes)); + break; + } + } + } + } + Add("AS", m_sAP_N_Yes.c_str()); + } + else if ((pAP = Get("AP")) && pAP->GetType() == object_type_DICT && (pAPN = ((CDictObject*)pAP)->Get("N")) && pAPN->GetType() == object_type_DICT && ((CDictObject*)pAPN)->Get(sV)) + Add("AS", sV.c_str()); + } + void CCheckBoxWidget::SetFlag(const int& nFlag) + { + int nFlags = nFlag; + if (m_nSubtype == WidgetRadiobutton) + nFlags |= (1 << 15); + CWidgetAnnotation::SetFlag(nFlags); + } //---------------------------------------------------------------------------------------- // CTextWidget //---------------------------------------------------------------------------------------- CTextWidget::CTextWidget(CXref* pXref) : CWidgetAnnotation(pXref, AnnotWidget) { + m_bAPV = false; } void CTextWidget::SetMaxLen(const int& nMaxLen) { if (nMaxLen > 0) { - if (m_pParent) - m_pParent->Add("MaxLen", nMaxLen); - else - Add("MaxLen", nMaxLen); + CDictObject* pOwner = GetObjOwnValue("MaxLen"); + if (!pOwner) + pOwner = this; + pOwner->Add("MaxLen", nMaxLen); } } void CTextWidget::SetV(const std::wstring& wsV) { - std::string sValue = U_TO_UTF8(wsV); + m_sV = U_TO_UTF8(wsV); CDictObject* pOwner = GetObjOwnValue("V"); - if (!pOwner) - pOwner = GetObjOwnValue("FT"); if (!pOwner) pOwner = this; - pOwner->Add("V", new CStringObject(sValue.c_str())); + pOwner->Add("V", new CStringObject(m_sV.c_str(), true)); } void CTextWidget::SetRV(const std::wstring& wsRV) { std::string sValue = U_TO_UTF8(wsRV); - Add("RV", new CStringObject(sValue.c_str())); + CDictObject* pOwner = GetObjOwnValue("RV"); + if (!pOwner) + pOwner = this; + pOwner->Add("RV", new CStringObject(sValue.c_str(), true)); + } + bool CTextWidget::IsCombFlag() + { + int nFlags = ((CNumberObject*)GetObjValue("Ff"))->Get(); + return (nFlags & (1 << 24)); + } + bool CTextWidget::IsMultiLine() + { + int nFlags = ((CNumberObject*)GetObjValue("Ff"))->Get(); + return (nFlags & (1 << 12)); + } + unsigned int CTextWidget::GetMaxLen() + { + CNumberObject* oMaxLen = (CNumberObject*)GetObjValue("MaxLen"); + return oMaxLen ? oMaxLen->Get() : 0; } //---------------------------------------------------------------------------------------- // CChoiceWidget //---------------------------------------------------------------------------------------- CChoiceWidget::CChoiceWidget(CXref* pXref) : CWidgetAnnotation(pXref, AnnotWidget) { - Add("FT", "Ch"); + m_dHeight = 0; + m_nTI = -1; + m_bAPV = false; + } + void CChoiceWidget::SetFlag(const int& nFlag) + { + int nFlags = nFlag; + if (m_nSubtype == WidgetCombobox) + nFlags |= (1 << 17); + + CDictObject* pOwner = GetObjOwnValue("Ff"); + if (!pOwner) + pOwner = this; + else + { + int nFlags2 = ((CNumberObject*)(pOwner->Get("Ff")))->Get(); + if (nFlags2 & (1 << 19)) + nFlags |= (1 << 19); + } + pOwner->Add("Ff", nFlags); } void CChoiceWidget::SetTI(const int& nTI) { - Add("TI", nTI); + m_nTI = nTI; + CDictObject* pOwner = GetObjOwnValue("TI"); + if (!pOwner) + pOwner = this; + pOwner->Add("TI", nTI); } void CChoiceWidget::SetV(const std::wstring& wsV) { std::string sValue = U_TO_UTF8(wsV); CDictObject* pOwner = GetObjOwnValue("V"); if (!pOwner) - pOwner = GetObjOwnValue("FT"); + pOwner = this; + pOwner->Add("V", new CStringObject(sValue.c_str(), true)); + } + void CChoiceWidget::SetI(const std::vector& arrI) + { + CArrayObject* pArray = new CArrayObject(); + if (!pArray) + return; + + CDictObject* pOwner = GetObjOwnValue("I"); if (!pOwner) pOwner = this; - pOwner->Add("V", new CStringObject(sValue.c_str())); + pOwner->Add("I", pArray); + + for (int i = 0; i < arrI.size(); ++i) + pArray->Add(arrI[i]); + } + void CChoiceWidget::SetV(const std::vector& arrV) + { + CArrayObject* pArray = new CArrayObject(); + if (!pArray) + return; + + CDictObject* pOwner = GetObjOwnValue("V"); + if (!pOwner) + pOwner = this; + pOwner->Add("V", pArray); + + for (int i = 0; i < arrV.size(); ++i) + pArray->Add(new PdfWriter::CStringObject(U_TO_UTF8(arrV[i]).c_str(), true)); } void CChoiceWidget::SetOpt(const std::vector< std::pair >& arrOpt) { + m_arrOpt = arrOpt; CArrayObject* pArray = new CArrayObject(); if (!pArray) return; - Add("Opt", pArray); + CDictObject* pOwner = GetObjOwnValue("Opt"); + if (!pOwner) + pOwner = this; + pOwner->Add("Opt", pArray); for (const std::pair& PV : arrOpt) { if (PV.first.empty()) { std::string sValue = U_TO_UTF8(PV.second); - pArray->Add(new CStringObject(sValue.c_str())); + pArray->Add(new CStringObject(sValue.c_str(), true)); } else { @@ -1118,12 +2282,70 @@ namespace PdfWriter pArray->Add(pArray2); std::string sValue = U_TO_UTF8(PV.first); - pArray2->Add(new CStringObject(sValue.c_str())); + pArray2->Add(new CStringObject(sValue.c_str(), true)); sValue = U_TO_UTF8(PV.second); - pArray2->Add(new CStringObject(sValue.c_str())); + pArray2->Add(new CStringObject(sValue.c_str(), true)); + } + } + } + std::wstring CChoiceWidget::GetValue(const std::wstring& wsExportV) + { + for (int i = 0; i < m_arrOpt.size(); ++i) + { + if (( m_arrOpt[i].first.empty() && m_arrOpt[i].second == wsExportV) || + (!m_arrOpt[i].first.empty() && m_arrOpt[i].first == wsExportV)) + return m_arrOpt[i].second; + } + return wsExportV; + } + std::wstring CChoiceWidget::SetListBoxIndex(const std::vector& arrV) + { + std::wstring sRes; + int i = 0; + if (m_nTI < 0) + { + // Ищем верхний элемент отрисовки + for (; i < m_arrOpt.size(); ++i) + { + if (( m_arrOpt[i].first.empty() && m_arrOpt[i].second == arrV.front()) || + (!m_arrOpt[i].first.empty() && m_arrOpt[i].first == arrV.front())) + { + m_nTI = i; + break; + } + } + } + else + i = m_nTI; + + if (m_nTI < 0) + return L""; + + for (; i < m_arrOpt.size(); ++i) + sRes += (m_arrOpt[i].second + L"\n"); + i = m_nTI; + + for (const std::wstring& sV : arrV) + { + for (int j = i; j < m_arrOpt.size(); ++j) + { + if (( m_arrOpt[j].first.empty() && m_arrOpt[j].second == sV) || + (!m_arrOpt[j].first.empty() && m_arrOpt[j].first == sV)) + { + m_arrIndex.push_back(j - m_nTI); + i = j + 1; + break; + } } } + + if (!sRes.empty()) + { + sRes.pop_back(); + return sRes; + } + return L""; } //---------------------------------------------------------------------------------------- // CSignatureWidget @@ -1132,30 +2354,101 @@ namespace PdfWriter { } //---------------------------------------------------------------------------------------- - // CAnnotationAppearance + // CAction //---------------------------------------------------------------------------------------- - CAnnotationAppearance::CAnnotationAppearance(CXref* pXref, const TRect& oRect) + CAction::CAction(CXref* pXref) { - m_pXref = pXref; - m_pStream = new CMemoryStream(); - - SetStream(m_pXref, m_pStream); + pXref->Add(this); + Add("Type", "Action"); + } + void CAction::SetType(const std::wstring& wsType) + { + m_sType = U_TO_UTF8(wsType); + } + //---------------------------------------------------------------------------------------- + CActionResetForm::CActionResetForm(CXref* pXref) : CAction(pXref) + { + Add("S", "ResetForm"); + Add("Flags", 1); + } + void CActionResetForm::SetFlags(int nFlag) + { + Add("Flags", nFlag); + } + void CActionResetForm::SetFields(const std::vector& arrFileds) + { + CArrayObject* pArray = new CArrayObject(); + if (!pArray) + return; - Add("Type", "XObject"); - Add("Subtype", "Form"); + Add("Fields", pArray); + for (const std::wstring& A : arrFileds) + { + std::string sValue = U_TO_UTF8(A); + pArray->Add(new CStringObject(sValue.c_str(), true)); + } + } + //---------------------------------------------------------------------------------------- + CActionJavaScript::CActionJavaScript(CXref* pXref) : CAction(pXref) + { + Add("S", "JavaScript"); + } + void CActionJavaScript::SetJS(const std::wstring& wsJS) + { + std::string sValue = U_TO_UTF8(wsJS); + Add("JS", new CStringObject(sValue.c_str(), true)); + } + //---------------------------------------------------------------------------------------- + CActionGoTo::CActionGoTo(CXref* pXref) : CAction(pXref) + { + Add("S", "GoTo"); + } + void CActionGoTo::SetDestination(CArrayObject* pDest) + { + Add("D", pDest); + } + //---------------------------------------------------------------------------------------- + CActionURI::CActionURI(CXref* pXref) : CAction(pXref) + { + Add("S", "URI"); + } + void CActionURI::SetURI(const std::wstring& wsURI) + { + std::string sValue = U_TO_UTF8(wsURI); + Add("URI", new CStringObject(sValue.c_str(), true)); + } + //---------------------------------------------------------------------------------------- + CActionHide::CActionHide(CXref* pXref) : CAction(pXref) + { + Add("S", "Hide"); + } + void CActionHide::SetH(BYTE nH) + { + Add("H", !!nH); + } + void CActionHide::SetT(const std::vector& arrT) + { CArrayObject* pArray = new CArrayObject(); if (!pArray) return; - Add("BBox", pArray); - pArray->Add(0); - pArray->Add(0); - pArray->Add(oRect.fRight - oRect.fLeft); - pArray->Add(oRect.fBottom - oRect.fTop); + Add("T", pArray); + + for (const std::wstring& A : arrT) + { + std::string sValue = U_TO_UTF8(A); + pArray->Add(new CStringObject(sValue.c_str(), true)); + } + } + //---------------------------------------------------------------------------------------- + CActionNamed::CActionNamed(CXref* pXref) : CAction(pXref) + { + Add("S", "Named"); } - void CAnnotationAppearance::DrawTextComment() + void CActionNamed::SetN(const std::wstring& wsN) { - m_pStream->WriteStr(""); + std::string sValue = U_TO_UTF8(wsN); + Add("N", sValue.c_str()); } } diff --git a/PdfFile/SrcWriter/Annotation.h b/PdfFile/SrcWriter/Annotation.h index 3850499738e..890249a9dea 100644 --- a/PdfFile/SrcWriter/Annotation.h +++ b/PdfFile/SrcWriter/Annotation.h @@ -36,62 +36,95 @@ #include "Types.h" #include "Pages.h" #include "Document.h" +#include "Field.h" namespace PdfWriter { class CDestination; + enum ELineIntentType + { + LineDimension = 0, + LineArrow + }; + enum ELineEndType + { + Square = 0, + Circle, + Diamond, + OpenArrow, + ClosedArrow, + None, + Butt, + ROpenArrow, + RClosedArrow, + Slash + }; + enum ECaptionPositioning + { + Inline = 0, + Top + }; + enum EBorderType + { + Solid = 0, + Beveled, + Dashed, + Inset, + Underline + }; + + class CAction : public CDictObject + { + public: + std::string m_sType; + CAction(CXref* pXref); + + void SetType(const std::wstring& wsType); + void SetNext(CAction* pNext); + }; + class CActionResetForm : public CAction + { + public: + CActionResetForm(CXref* pXref); - enum EBorderSubtype + void SetFlags(int nFlag); + void SetFields(const std::vector& arrFileds); + }; + class CActionJavaScript : public CAction { - border_subtype_Solid, - border_subtype_Beveled, - border_subtype_Dashed, - border_subtype_Inset, - border_subtype_Underlined + public: + CActionJavaScript(CXref* pXref); + + void SetJS(const std::wstring& wsJS); }; - enum EAnnotType + class CActionGoTo : public CAction { - AnnotUnknown = -1, - AnnotText = 0, - AnnotLink = 1, - AnnotSound = 2, - AnnotFreeText = 3, - AnnotStamp = 4, - AnnotSquare = 5, - AnnotCircle = 6, - AnnotStrikeOut = 7, - AnnotHighLight = 8, - AnnotUnderline = 9, - AnnotInk = 10, - AnnotFileAttachment = 11, - AnnotPopup = 12, - AnnotLine = 13, - AnnotSquiggly = 14, - AnnotPolygon = 15, - AnnotPolyLine = 16, - AnnotCaret = 17, - AnnotWidget = 18 + public: + CActionGoTo(CXref* pXref); + + void SetDestination(CArrayObject* pDest); }; - enum EAnnotHighlightMode + class CActionURI : public CAction { - AnnotNoHighlight = 0, - AnnotInvertBox, - AnnotInvertBorder, - AnnotDownAppearance, - AnnotHighlightModeEOF + public: + CActionURI(CXref* pXref); + + void SetURI(const std::wstring& wsURI); + }; + class CActionHide : public CAction + { + public: + CActionHide(CXref* pXref); + + void SetH(BYTE nH); + void SetT(const std::vector& arrT); }; - enum EAnnotIcon + class CActionNamed : public CAction { - AnnotIconComment = 0, - AnnotIconKey = 1, - AnnotIconNote = 2, - AnnotIconHelp = 3, - AnnotIconNewParagraph = 4, - AnnotIconParagraph = 5, - AnnotIconInsert = 6, - - AnnotIconMin = 0, - AnnotIconMax = 6 + public: + CActionNamed(CXref* pXref); + + void SetN(const std::wstring& wsN); }; class CAnnotation : public CDictObject @@ -99,10 +132,30 @@ namespace PdfWriter protected: CAnnotation(CXref* pXref, EAnnotType eType); + struct CBorderType + { + CBorderType() + { + bHave = false; + nType = EBorderType::Solid; + dWidth = 1; + } + + bool bHave; + EBorderType nType; + double dWidth; + std::vector arrDash; + }; + + CBorderType m_oBorder; + CXref* m_pXref; TRect m_oRect; double m_dPageWidth = 0; - double m_dPageHeight = 0; + double m_dPageH = 0; + double m_dPageX = 0; + CDocument* m_pDocument; + CAnnotAppearance* m_pAppearance; public: EDictType GetDictType() const @@ -120,16 +173,30 @@ namespace PdfWriter } void SetRect(const TRect& oRect); - void SetBorder(BYTE nType, double dWidth, double dDashesAlternating = 0.0, double dGaps = 0.0); + void SetBorder(BYTE nType, double dWidth, const std::vector& arrDash); void SetAnnotFlag(const int& nAnnotFlag); - void SetPage(CPage* pPage); + void SetPage(CPage* pPage, double dW = 0, double dH = 0, double dX = 0); void SetBE(BYTE nType, const double& dBE); void SetContents(const std::wstring& wsText); void SetNM(const std::wstring& wsNM); void SetLM(const std::wstring& wsLM); + void SetOUserID(const std::wstring& wsOUserID); void SetC(const std::vector& arrC); - // TODO AP Необходимо генерировать внешний вид аннотации как у Widget - virtual void CreateAP(); + + void APFromFakePage(CPage* pFakePage); + CAnnotAppearanceObject* StartAP(); + TRect& GetRect() { return m_oRect; } + void SetXref(CXref* pXref) { m_pXref = pXref; } + void SetDocument(CDocument* pDocument); + CDocument* GetDocument(); + bool HaveBorder() { return m_oBorder.bHave; } + EBorderType GetBorderType() { return m_oBorder.nType; } + double GetBorderWidth() { return m_oBorder.dWidth; } + std::string GetBorderDash(); + double GetWidth() { return abs(m_oRect.fRight - m_oRect.fLeft); } + double GetHeight() { return abs(m_oRect.fTop - m_oRect.fBottom); } + double GetPageX() { return m_dPageX; } + double GetPageH() { return m_dPageH; } }; class CPopupAnnotation : public CAnnotation { @@ -155,16 +222,16 @@ namespace PdfWriter return true; } - void SetRT(const BYTE& nRT); + void SetRT(BYTE nRT); void SetCA(const double& dCA); void SetT(const std::wstring& wsT); void SetRC(const std::wstring& wsRC); void SetCD(const std::wstring& wsCD); void SetSubj(const std::wstring& wsSubj); + void RemoveAP(); void SetIRTID(CAnnotation* pAnnot); CPopupAnnotation* CreatePopup(); - virtual void CreateAP() override; }; class CLinkAnnotation : public CAnnotation { @@ -193,7 +260,7 @@ namespace PdfWriter void SetState(BYTE nState); void SetStateModel(BYTE nStateModel); - void CreateAP() override; + void SetAP(); }; class CUriLinkAnnotation : public CAnnotation { @@ -217,6 +284,9 @@ namespace PdfWriter }; class CLineAnnotation : public CMarkupAnnotation { + private: + ELineEndType m_nLE1, m_nLE2; + double dL[4]; public: CLineAnnotation(CXref* pXref); EAnnotType GetAnnotationType() const override @@ -225,15 +295,17 @@ namespace PdfWriter } void SetCap(bool bCap); - void SetIT(const BYTE& nIT); - void SetCP(const BYTE& nCP); + void SetIT(BYTE nIT); + void SetCP(BYTE nCP); void SetLL(const double& dLL); void SetLLE(const double& dLLE); void SetLLO(const double& dLLO); - void SetLE(const BYTE& nLE1, const BYTE& nLE2); + void SetLE(BYTE nLE1, BYTE nLE2); void SetL(const double& dL1, const double& dL2, const double& dL3, const double& dL4); void SetCO(const double& dCO1, const double& dCO2); void SetIC(const std::vector& arrIC); + + void SetAP(); }; class CTextMarkupAnnotation : public CMarkupAnnotation { @@ -246,8 +318,10 @@ namespace PdfWriter return m_nSubtype; } - void SetSubtype(const BYTE& nSubtype); + void SetSubtype(BYTE nSubtype); void SetQuadPoints(const std::vector& arrQuadPoints); + + void SetAP(const std::vector& arrQuadPoints, const double& dCA); }; class CSquareCircleAnnotation : public CMarkupAnnotation { @@ -260,7 +334,7 @@ namespace PdfWriter return m_nSubtype; } - void SetSubtype(const BYTE& nSubtype); + void SetSubtype(BYTE nSubtype); void SetRD(const double& dRD1, const double& dRD2, const double& dRD3, const double& dRD4); void SetIC(const std::vector& arrIC); }; @@ -275,9 +349,9 @@ namespace PdfWriter return m_nSubtype; } - void SetIT(const BYTE& nIT); - void SetSubtype(const BYTE& nSubtype); - void SetLE(const BYTE& nLE1, const BYTE& nLE2); + void SetIT(BYTE nIT); + void SetSubtype(BYTE nSubtype); + void SetLE(BYTE nLE1, BYTE nLE2); void SetIC(const std::vector& arrIC); void SetVertices(const std::vector& arrVertices); }; @@ -290,12 +364,16 @@ namespace PdfWriter return AnnotFreeText; } - void SetQ(const BYTE& nQ); - void SetIT(const BYTE& nIT); - void SetLE(const BYTE& nLE); + void SetDA(CFontDict* pFont, const double& dFontSize, const std::vector& arrC); + + void SetQ(BYTE nQ); + void SetIT(BYTE nIT); + void SetLE(BYTE nLE); + void SetRotate(int nRotate); void SetDS(const std::wstring& wsDS); void SetRD(const double& dRD1, const double& dRD2, const double& dRD3, const double& dRD4); void SetCL(const std::vector& arrCL); + void SetIC(const std::vector& arrIC); }; class CCaretAnnotation : public CMarkupAnnotation { @@ -306,121 +384,197 @@ namespace PdfWriter return AnnotCaret; } - void SetSy(const BYTE& nSy); + void SetSy(BYTE nSy); void SetRD(const double& dRD1, const double& dRD2, const double& dRD3, const double& dRD4); }; + class CStampAnnotation : public CMarkupAnnotation + { + private: + CDictObject* m_pAPStream; + public: + CStampAnnotation(CXref* pXref); + EAnnotType GetAnnotationType() const override + { + return AnnotStamp; + } + + void SetRotate(double nRotate); + void SetName(const std::wstring& wsName); + void SetAPStream(CDictObject* pStream); + }; class CWidgetAnnotation : public CAnnotation { protected: + EWidgetType m_nSubtype; CDictObject* m_pMK; CDictObject* m_pParent; - CDocument* m_pDocument; - CDictObject* GetObjOwnValue(const std::string& sV); + CFontCidTrueType* m_pFont; + double m_dFontSize; + bool m_bBold; + bool m_bItalic; + + CAnnotAppearance* m_pAppearance; + double m_dFontSizeAP; + std::vector m_arrTC; + BYTE m_nQ; + void CheckMK(); public: CWidgetAnnotation(CXref* pXref, EAnnotType eType); + EAnnotType GetAnnotationType() const override + { + return AnnotWidget; + } + EWidgetType GetWidgetType() const + { + return m_nSubtype; + } - void SetDocument(CDocument* pDocument); - void SetDA(CFontDict* pFont, const double& dFontSize, const std::vector& arrTC); + void SetSubtype(BYTE nSubtype); + void SetDA(CFontDict* pFont, const double& dFontSize, const double& dFontSizeAP, const std::vector& arrTC); + void SetFont(CFontCidTrueType* pFont, double dFontSize, bool bBold, bool bItalic); + CDictObject* GetObjOwnValue(const std::string& sV); + CObjectBase* GetObjValue(const std::string& sV); - void SetQ(const BYTE& nQ); - void SetH(const BYTE& nH); + void SetQ(BYTE nQ); + void SetH(BYTE nH); void SetR(const int& nR); - void SetFlag (const int& nFlag); + virtual void SetFlag (const int& nFlag); void SetParent(CDictObject* pParent); void SetTU(const std::wstring& wsTU); void SetDS(const std::wstring& wsDS); - virtual void SetDV(const std::wstring& wsDV); + void SetDV(const std::wstring& wsDV); void SetT (const std::wstring& wsT); void SetBC(const std::vector& arrBC); void SetBG(const std::vector& arrBG); + void AddAction(CAction* pAction); + + std::string GetDAforAP(CFontDict* pFont); + std::string GetBGforAP(double dDiff = 0); + std::string GetBCforAP(); + CFontCidTrueType* GetFont() { return m_pFont; } + double GetFontSize() { return m_dFontSize; } + bool GetFontIsBold() { return m_bBold; } + bool GetFontIsItalic() { return m_bItalic; } + bool HaveBG(); + bool HaveBC(); + BYTE GetQ() { return m_nQ; } + + void APFromFakePage(CPage* pFakePage); + void SetEmptyAP(); + void SetAP(const std::wstring& wsValue, unsigned short* pCodes, unsigned int unCount, double dX, double dY, CFontCidTrueType** ppFonts, double* pShifts); + CAnnotAppearanceObject* StartAP(); + void AddLineToAP(const double& dX, const double& dY, unsigned short* pCodes, const unsigned int& unCodesCount, CFontCidTrueType** ppFonts = NULL, const double* pShifts = NULL); + void EndAP(); }; - class CButtonWidget : public CWidgetAnnotation + class CPushButtonWidget : public CWidgetAnnotation { private: - EAnnotType m_nSubtype; + bool m_bRespectBorders; + bool m_bConstantProportions; + BYTE m_nScaleType; + BYTE m_nTP; + double m_dShiftX; + double m_dShiftY; + std::wstring m_wsCA; + std::wstring m_wsRC; + std::wstring m_wsAC; CDictObject* m_pIF; - std::string m_sAP_N_Yes; void CheckIF(); public: - CButtonWidget(CXref* pXref); - EAnnotType GetAnnotationType() const override - { - return m_nSubtype; - } + CPushButtonWidget(CXref* pXref); - void SetV(bool bV); - void SetDV(const std::wstring& wsDV) override; - void SetS(const BYTE& nS); - void SetTP(const BYTE& nTP); - void SetSW(const BYTE& nSW); - void SetStyle(const BYTE& nStyle); + void SetV(const std::wstring& wsV); + void SetS(BYTE nS); + void SetTP(BYTE nTP); + void SetSW(BYTE nSW); void SetIFFlag(const int& nIFFlag); + virtual void SetFlag (const int& nFlag) override; + void SetI(const int& nI); + void SetRI(const int& nRI); + void SetIX(const int& nIX); void SetA(const double& dA1, const double& dA2); void SetCA(const std::wstring& wsCA); void SetRC(const std::wstring& wsRC); void SetAC(const std::wstring& wsAC); + + void SetAP(CXObject* pForm, BYTE nAP, unsigned short* pCodes, unsigned int unCount, double dX, double dY, double dLineW, double dLineH, CFontCidTrueType** ppFonts); + const std::wstring& GetCA() { return m_wsCA; } + const std::wstring& GetRC() { return m_wsRC; } + const std::wstring& GetAC() { return m_wsAC; } + BYTE GetTP() { return m_nTP; } + bool GetRespectBorder() { return m_bRespectBorders; } + + int m_nI, m_nRI, m_nIX; + }; + class CCheckBoxWidget : public CWidgetAnnotation + { + private: + std::string m_sAP_N_Yes; + + public: + CCheckBoxWidget(CXref* pXref); + + void SetV(const std::wstring& wsV); + std::wstring SetStyle(BYTE nStyle); void SetAP_N_Yes(const std::wstring& wsAP_N_Yes); + virtual void SetFlag (const int& nFlag); + + void SwitchAP(const std::string& sV); }; class CTextWidget : public CWidgetAnnotation { private: - EAnnotType m_nSubtype; + std::string m_sV; + bool m_bAPV; public: CTextWidget(CXref* pXref); - EAnnotType GetAnnotationType() const override - { - return m_nSubtype; - } void SetMaxLen(const int& nMaxLen); void SetV (const std::wstring& wsV); void SetRV(const std::wstring& wsRV); + void SetAPV() { m_bAPV = true; } + + bool IsCombFlag(); + bool IsMultiLine(); + unsigned int GetMaxLen(); + bool HaveAPV() { return m_bAPV; } }; class CChoiceWidget : public CWidgetAnnotation { private: - EAnnotType m_nSubtype; - + std::vector< std::pair > m_arrOpt; + double m_dHeight; + int m_nTI; + std::vector m_arrIndex; + bool m_bAPV; public: CChoiceWidget(CXref* pXref); - EAnnotType GetAnnotationType() const override - { - return m_nSubtype; - } + virtual void SetFlag (const int& nFlag) override; void SetTI(const int& nTI); void SetV(const std::wstring& wsV); + void SetI(const std::vector& arrI); + void SetV(const std::vector& arrV); void SetOpt(const std::vector< std::pair >& arrOpt); + void SetAPV() { m_bAPV = true; } + + std::wstring GetValue(const std::wstring& wsExportV); + void SetListBoxHeight(double dHeight) { m_dHeight = dHeight; } + double GetListBoxHeight() { return m_dHeight; } + std::wstring SetListBoxIndex(const std::vector& arrV); + std::vector GetListBoxIndex() { return m_arrIndex; } + bool HaveAPV() { return m_bAPV; } }; class CSignatureWidget : public CWidgetAnnotation { - private: - EAnnotType m_nSubtype; - public: CSignatureWidget(CXref* pXref); - EAnnotType GetAnnotationType() const override - { - return m_nSubtype; - } - }; - - class CAnnotationAppearance : public CDictObject - { - public: - CAnnotationAppearance(CXref* pXref, const TRect& oRect); - - void DrawTextComment(); - - private: - CXref* m_pXref; - CStream* m_pStream; }; } #endif // _PDF_WRITER_SRC_ANNOTATION_H diff --git a/PdfFile/SrcWriter/Destination.cpp b/PdfFile/SrcWriter/Destination.cpp index 9dc1bfab34c..2f2a3429235 100644 --- a/PdfFile/SrcWriter/Destination.cpp +++ b/PdfFile/SrcWriter/Destination.cpp @@ -37,9 +37,10 @@ namespace PdfWriter //---------------------------------------------------------------------------------------- // CDestination //---------------------------------------------------------------------------------------- - CDestination::CDestination(CPage* pPage, CXref* pXref) + CDestination::CDestination(CPage* pPage, CXref* pXref, bool bInline) { - pXref->Add(this); + if (!bInline) + pXref->Add(this); // Первый элемент массива должен быть страницей, которой принадлежит объект Add((CObjectBase*)pPage); diff --git a/PdfFile/SrcWriter/Destination.h b/PdfFile/SrcWriter/Destination.h index a1019091813..d0e73bb6eb5 100644 --- a/PdfFile/SrcWriter/Destination.h +++ b/PdfFile/SrcWriter/Destination.h @@ -41,7 +41,7 @@ namespace PdfWriter class CDestination : public CArrayObject { public: - CDestination(CPage* pPage, CXref* pXref); + CDestination(CPage* pPage, CXref* pXref, bool bInline = false); bool IsValid() const; void SetXYZ (float fLeft, float fTop, float fZoom); void SetFit (); diff --git a/PdfFile/SrcWriter/Document.cpp b/PdfFile/SrcWriter/Document.cpp index ede4881e546..237e6edf64f 100644 --- a/PdfFile/SrcWriter/Document.cpp +++ b/PdfFile/SrcWriter/Document.cpp @@ -50,6 +50,7 @@ #include "AcroForm.h" #include "Field.h" #include "ResourcesDictionary.h" +#include "Metadata.h" #include "../../DesktopEditor/agg-2.4/include/agg_span_hatch.h" #include "../../DesktopEditor/common/SystemUtils.h" @@ -79,30 +80,29 @@ namespace PdfWriter m_pPageTree = NULL; m_pCurPage = NULL; m_nCurPageNum = -1; - m_unFormFields = 0; + m_pCurImage = NULL; m_pInfo = NULL; m_pTrailer = NULL; m_pResources = NULL; + m_pMetaData = NULL; m_bEncrypt = false; m_pEncryptDict = NULL; + m_unFormFields = 0; m_unCompressMode = COMP_NONE; - m_pJbig2 = NULL; memset((void*)m_sTTFontTag, 0x00, 8); + m_pJbig2 = NULL; + m_pDefaultCheckBoxFont = NULL; m_pTransparencyGroup = NULL; m_pFreeTypeLibrary = NULL; + m_bPDFAConformance = false; m_pAcroForm = NULL; m_pFieldsResources = NULL; - m_pDefaultCheckBoxFont = NULL; - m_wsDocumentID = L""; - m_wsFilePath = L""; - - m_bPDFAConformance = false; } CDocument::~CDocument() { Close(); } - bool CDocument::CreateNew() + bool CDocument::CreateNew() { Close(); @@ -114,6 +114,10 @@ namespace PdfWriter if (!m_pTrailer) return false; + m_pMetaData = new CStreamData(m_pXref); + if (!m_pMetaData) + return false; + m_pCatalog = new CCatalog(m_pXref); if (!m_pCatalog) return false; @@ -167,6 +171,8 @@ namespace PdfWriter m_vFillAlpha.clear(); m_vStrokeAlpha.clear(); m_vRadioGroups.clear(); + m_vMetaOForms.clear(); + m_vImages.clear(); m_pTransparencyGroup = NULL; @@ -185,6 +191,7 @@ namespace PdfWriter m_pPageTree = NULL; m_pCurPage = NULL; m_nCurPageNum = 0; + m_pCurImage = NULL; m_unFormFields = 0; m_bEncrypt = false; m_pEncryptDict = NULL; @@ -207,16 +214,18 @@ namespace PdfWriter m_vTTFonts.clear(); m_vFreeTypeFonts.clear(); m_vSignatures.clear(); + m_vMetaOForms.clear(); + m_vImages.clear(); if (m_pFreeTypeLibrary) { FT_Done_FreeType(m_pFreeTypeLibrary); m_pFreeTypeLibrary = NULL; } } - bool CDocument::SaveToFile(const std::wstring& wsPath, bool bAdd) + bool CDocument::SaveToFile(const std::wstring& wsPath) { CFileStream* pStream = new CFileStream(); - if (!pStream || !pStream->OpenFile(wsPath, bAdd)) + if (!pStream || !pStream->OpenFile(wsPath, true)) return false; if (m_pJbig2) @@ -259,6 +268,33 @@ namespace PdfWriter m_pXref->WriteToStream(pStream, pEncrypt); } + bool CDocument::SaveNewWithPassword(CXref* pXref, CXref* _pXref, const std::wstring& wsPath, const std::wstring& wsOwnerPassword, const std::wstring& wsUserPassword, CDictObject* pTrailer) + { + if (!pXref || !pTrailer || !_pXref) + return false; + m_pTrailer = pTrailer; + + CEncrypt* pEncrypt = NULL; + if (!wsOwnerPassword.empty()) + { + m_pEncryptDict = new CEncryptDict(_pXref); + m_pEncryptDict->SetPasswords(wsOwnerPassword, wsUserPassword); + m_pTrailer->Add("Encrypt", m_pEncryptDict); + + pEncrypt = m_pEncryptDict->GetEncrypt(); + PrepareEncryption(); + } + + CFileStream* pStream = new CFileStream(); + if (!pStream || !pStream->OpenFile(wsPath, true)) + return false; + pStream->WriteStr(c_sPdfHeader); + + pXref->WriteToStream(pStream, pEncrypt); + + delete pStream; + return true; + } void CDocument::PrepareEncryption() { CEncrypt* pEncrypt = m_pEncryptDict->GetEncrypt(); @@ -278,6 +314,12 @@ namespace PdfWriter pID->Add(new CBinaryObject(pEncrypt->m_anEncryptID, 16)); pID->Add(new CBinaryObject(pEncrypt->m_anEncryptID, 16)); + + if (m_pMetaData) + m_pMetaData->SetID(new CBinaryObject(pEncrypt->m_anEncryptID, 16)); + + for (int i = 0; i < m_vMetaOForms.size(); ++i) + m_vMetaOForms[i]->Add("ID", new CBinaryObject(pEncrypt->m_anEncryptID, 16)); } void CDocument::SetPasswords(const std::wstring & wsOwnerPassword, const std::wstring & wsUserPassword) { @@ -401,7 +443,34 @@ namespace PdfWriter m_pCatalog->AddPageLabel(unPageNum, pPageLabel); } - CDictObject* CDocument::CreatePageLabel(EPageNumStyle eStyle, unsigned int unFirstPage, const char* sPrefix) + bool CDocument::AddMetaData(const std::wstring& sMetaName, BYTE* pMetaData, DWORD nMetaLength) + { + if (!m_pMetaData) + return false; + + CBinaryObject* sID = NULL; + CArrayObject* pID = (CArrayObject*)m_pTrailer->Get("ID"); + if (!pID) + { + BYTE arrId[16]; + CEncryptDict::CreateId(m_pInfo, m_pXref, (BYTE*)arrId); + + pID = new CArrayObject(); + m_pTrailer->Add("ID", pID); + + pID->Add(new CBinaryObject(arrId, 16)); + pID->Add(new CBinaryObject(arrId, 16)); + + sID = new CBinaryObject(arrId, 16); + } + else + sID = (CBinaryObject*)pID->Get(1)->Copy(); + + m_pMetaData->SetID(sID); + + return m_pMetaData->AddMetaData(sMetaName, pMetaData, nMetaLength); + } + CDictObject* CDocument::CreatePageLabel(EPageNumStyle eStyle, unsigned int unFirstPage, const char* sPrefix) { CDictObject* pLabel = new CDictObject(); if (!pLabel) @@ -443,14 +512,10 @@ namespace PdfWriter return new COutline(pParent, sTitle, m_pXref); } - CDestination* CDocument::CreateDestination(unsigned int unPageIndex) + CDestination* CDocument::CreateDestination(CPage* pPage, bool bInline) { - if (unPageIndex >= m_pPageTree->GetCount()) - return NULL; - - CPage* pPage = m_pPageTree->GetPage(unPageIndex); if (pPage) - return new CDestination(pPage, m_pXref); + return new CDestination(pPage, m_pXref, bInline); return NULL; } CExtGrState* CDocument::FindExtGrState(double dAlphaStroke, double dAlphaFill, EBlendMode eMode, int nStrokeAdjustment) @@ -479,9 +544,6 @@ namespace PdfWriter } CExtGrState* CDocument::GetExtGState(double dAlphaStroke, double dAlphaFill, EBlendMode eMode, int nStrokeAdjustment) { - if (IsPDFA()) - return NULL; - CExtGrState* pExtGrState = FindExtGrState(dAlphaStroke, dAlphaFill, eMode, nStrokeAdjustment); if (!pExtGrState) @@ -509,9 +571,6 @@ namespace PdfWriter } CExtGrState* CDocument::GetStrokeAlpha(double dAlpha) { - if (IsPDFA()) - return NULL; - CExtGrState* pExtGrState = NULL; for (unsigned int unIndex = 0, unCount = m_vStrokeAlpha.size(); unIndex < unCount; unIndex++) { @@ -532,9 +591,6 @@ namespace PdfWriter } CExtGrState* CDocument::GetFillAlpha(double dAlpha) { - if (IsPDFA()) - return NULL; - CExtGrState* pExtGrState = NULL; for (unsigned int unIndex = 0, unCount = m_vFillAlpha.size(); unIndex < unCount; unIndex++) { @@ -605,13 +661,31 @@ namespace PdfWriter { return new CCaretAnnotation(m_pXref); } + CAnnotation* CDocument::CreateStampAnnot() + { + return new CStampAnnotation(m_pXref); + } CAnnotation* CDocument::CreateWidgetAnnot() { - return new CWidgetAnnotation(m_pXref, EAnnotType::AnnotWidget); + if (!CheckAcroForm()) + return NULL; + + CWidgetAnnotation* pWidget = new CWidgetAnnotation(m_pXref, EAnnotType::AnnotWidget); + if (!pWidget) + return NULL; + + CArrayObject* ppFields = (CArrayObject*)m_pAcroForm->Get("Fields"); + ppFields->Add(pWidget); + + return pWidget; } - CAnnotation* CDocument::CreateButtonWidget() + CAnnotation* CDocument::CreatePushButtonWidget() { - return new CButtonWidget(m_pXref); + return new CPushButtonWidget(m_pXref); + } + CAnnotation* CDocument::CreateCheckBoxWidget() + { + return new CCheckBoxWidget(m_pXref); } CAnnotation* CDocument::CreateTextWidget() { @@ -627,6 +701,20 @@ namespace PdfWriter { return new CSignatureWidget(m_pXref); } + CAction* CDocument::CreateAction(BYTE nType) + { + switch (nType) + { + case 1: return new CActionGoTo(m_pXref); + case 6: return new CActionURI(m_pXref); + case 9: return new CActionHide(m_pXref); + case 10: return new CActionNamed(m_pXref); + case 12: return new CActionResetForm(m_pXref); + case 14: return new CActionJavaScript(m_pXref); + } + + return NULL; + } void CDocument::AddAnnotation(const int& nID, CAnnotation* pAnnot) { m_pXref->Add(pAnnot); @@ -636,9 +724,89 @@ namespace PdfWriter { return new CImageDict(m_pXref, this); } - CFont14* CDocument::CreateFont14(EStandard14Fonts eType) + CXObject* CDocument::CreateForm(CImageDict* pImage, const std::string& sName) { - return new CFont14(m_pXref, this, eType); + if (!pImage) + return NULL; + + std::string sFrmName = "FRM" + sName; + std::string sImgName = "Img" + sName; + + CXObject* pForm = new CXObject(); + CStream* pStream = new CMemoryStream(); + pForm->SetStream(m_pXref, pStream); + +#ifndef FILTER_FLATE_DECODE_DISABLED + if (m_unCompressMode & COMP_TEXT) + pForm->SetFilter(STREAM_FILTER_FLATE_DECODE); +#endif + double dOriginW = pImage->GetWidth(); + double dOriginH = pImage->GetHeight(); + pForm->SetWidth(dOriginW); + pForm->SetHeight(dOriginH); + + CArrayObject* pBBox = new CArrayObject(); + pForm->Add("BBox", pBBox); + pBBox->Add(0); + pBBox->Add(0); + pBBox->Add(dOriginW); + pBBox->Add(dOriginH); + pForm->Add("FormType", 1); + CArrayObject* pFormMatrix = new CArrayObject(); + pForm->Add("Matrix", pFormMatrix); + pFormMatrix->Add(1); + pFormMatrix->Add(0); + pFormMatrix->Add(0); + pFormMatrix->Add(1); + pFormMatrix->Add(0); + pFormMatrix->Add(0); + pForm->Add("Name", sFrmName.c_str()); + pForm->SetName(sFrmName); + + CDictObject* pFormRes = new CDictObject(); + CArrayObject* pFormResProcset = new CArrayObject(); + pFormRes->Add("ProcSet", pFormResProcset); + pFormResProcset->Add(new CNameObject("PDF")); + pFormResProcset->Add(new CNameObject("ImageC")); + CDictObject* pFormResXObject = new CDictObject(); + pFormRes->Add("XObject", pFormResXObject); + + pFormResXObject->Add(sImgName, pImage); + pForm->Add("Resources", pFormRes); + + pForm->Add("Subtype", "Form"); + pForm->Add("Type", "XObject"); + + pStream->WriteStr("q\012"); + pStream->WriteReal(dOriginW); + pStream->WriteStr(" 0 0 "); + pStream->WriteReal(dOriginH); + pStream->WriteStr(" 0 0 cm\012/"); + pStream->WriteStr(sImgName.c_str()); + pStream->WriteStr(" Do\012Q"); + + GetFieldsResources()->AddXObjectWithName(sFrmName.c_str(), pForm); + + return pForm; + } + CFont14* CDocument::CreateFont14(const std::wstring& wsFontPath, unsigned int unIndex, EStandard14Fonts eType) + { + CFont14* pFont = FindFont14(wsFontPath, unIndex); + if (pFont) + return pFont; + pFont = new CFont14(m_pXref, this, eType); + m_vFonts14.push_back(TFontInfo(wsFontPath, unIndex, pFont)); + return pFont; + } + CFont14* CDocument::FindFont14(const std::wstring& wsFontPath, unsigned int unIndex) + { + for (int nIndex = 0, nCount = m_vFonts14.size(); nIndex < nCount; nIndex++) + { + TFontInfo& oInfo = m_vFonts14.at(nIndex); + if (wsFontPath == oInfo.wsPath && unIndex == oInfo.unIndex) + return (CFont14*)oInfo.pFont; + } + return NULL; } CFontCidTrueType* CDocument::CreateCidTrueTypeFont(const std::wstring& wsFontPath, unsigned int unIndex) { @@ -1093,6 +1261,34 @@ namespace PdfWriter return pField; } + bool CDocument::HasImage(const std::wstring& wsImagePath, BYTE nAlpha) + { + for (size_t i = 0, nSize = m_vImages.size(); i < nSize; ++i) + { + if (m_vImages[i].wsImagePath == wsImagePath && m_vImages[i].nAlpha == nAlpha) + return true; + } + return false; + } + CImageDict* CDocument::GetImage(const std::wstring& wsImagePath, BYTE nAlpha) + { + for (size_t i = 0, nSize = m_vImages.size(); i < nSize; ++i) + { + if (m_vImages[i].wsImagePath == wsImagePath && m_vImages[i].nAlpha == nAlpha) + { + m_pCurImage = m_vImages[i].pImage; + return m_vImages[i].pImage; + } + } + return NULL; + } + void CDocument::AddImage(const std::wstring& wsImagePath, BYTE nAlpha, CImageDict* pImage) + { + if (!pImage) + return; + m_pCurImage = pImage; + m_vImages.push_back({wsImagePath, nAlpha, pImage}); + } bool CDocument::CheckFieldName(CFieldBase* pField, const std::string& sName) { CFieldBase* pBase = m_mFields[sName]; @@ -1211,15 +1407,6 @@ namespace PdfWriter if (pAcroForm && pAcroForm->GetType() == object_type_DICT) m_pAcroForm = (CDictObject*)pAcroForm; - if (m_pAcroForm) - { - CObjectBase* pFieldsResources = m_pAcroForm->Get("DR"); - if (pFieldsResources && pFieldsResources->GetType() == object_type_DICT) - m_pFieldsResources = (CResourcesDict*)pFieldsResources; - - // TODO заполнить поля m_pFieldsResources - } - if (pEncrypt) { m_pEncryptDict = pEncrypt; @@ -1230,6 +1417,16 @@ namespace PdfWriter m_wsFilePath = wsPath; return true; } + bool CDocument::EditResources(CXref* pXref, CResourcesDict* pResources) + { + if (!pResources || !EditXref(pXref)) + return false; + + CheckAcroForm(); + m_pAcroForm->Add("DR", pResources); + m_pFieldsResources = pResources; + return true; + } std::pair CDocument::GetPageRef(int nPageIndex) { std::pair pRes = std::make_pair(0, 0); @@ -1259,6 +1456,9 @@ namespace PdfWriter m_pCurPage = pPage; m_mEditPages[nPageIndex] = pPage; + if (m_pPageTree) + m_pPageTree->ReplacePage(nPageIndex, pPage); + return true; } bool CDocument::EditAnnot(CXref* pXref, CAnnotation* pAnnot, int nID) @@ -1266,6 +1466,7 @@ namespace PdfWriter if (!pAnnot || !EditXref(pXref)) return false; + pAnnot->SetXref(m_pXref); m_mAnnotations[nID] = pAnnot; return true; @@ -1310,6 +1511,46 @@ namespace PdfWriter return p->second; return NULL; } + CDictObject* CDocument::GetParent(int nID) + { + std::map::iterator p = m_mParents.find(nID); + if (p != m_mParents.end()) + return p->second; + return NULL; + } + CPage* CDocument::CreateFakePage() + { + return new CPage(this, NULL); + } + bool CDocument::EditCO(const std::vector& arrCO) + { + if (arrCO.empty()) + return true; + + if (!CheckAcroForm()) + return false; + + CArrayObject* pArray = new CArrayObject(); + if (!pArray) + return false; + + m_pAcroForm->Add("CO", pArray); + + for (int CO : arrCO) + { + CDictObject* pObj = GetParent(CO); + if (pObj) + pArray->Add(pObj); + else + { + CAnnotation* pAnnot = m_mAnnotations[CO]; + if (pAnnot) + pArray->Add(pAnnot); + } + } + + return true; + } CPage* CDocument::AddPage(int nPageIndex) { if (!m_pPageTree) @@ -1392,13 +1633,28 @@ namespace PdfWriter // Вторая часть идентификатора должна обновляться CObjectBase* pID = m_pTrailer->Get("ID"); - if (pID && pID->GetType() == object_type_ARRAY) + if ((pID && pID->GetType() == object_type_ARRAY) || !m_vMetaOForms.empty()) { BYTE arrId[16]; CEncryptDict::CreateId(m_pInfo, m_pXref, (BYTE*)arrId); - CObjectBase* pObject = ((CArrayObject*)pID)->Get(1, false); - ((CArrayObject*)pID)->Insert(pObject, new CBinaryObject(arrId, 16), true); + CArrayObject* pArrID = (CArrayObject*)pID; + if (pArrID) + { + CObjectBase* pObject = pArrID->Get(1, false); + pArrID->Insert(pObject, new CBinaryObject(arrId, 16), true); + } + else + { + pArrID = new CArrayObject(); + m_pTrailer->Add("ID", pArrID); + + pArrID->Add(new CBinaryObject(arrId, 16)); + pArrID->Add(new CBinaryObject(arrId, 16)); + } + + for (int i = 0; i < m_vMetaOForms.size(); ++i) + m_vMetaOForms[i]->Add("ID", new CBinaryObject(arrId, 16)); } CEncrypt* pEncrypt = NULL; @@ -1523,4 +1779,98 @@ namespace PdfWriter RELEASEOBJECT(XRef); vXRefForWrite.clear(); } + void CDocument::AddShapeXML(const std::string& sXML) + { + CDictObject* pResources = (CDictObject*)m_pCurPage->GetResourcesItem(); + if (!pResources) + { + pResources = new CResourcesDict(NULL, true, false); + m_pCurPage->Add("Resources", pResources); + } + CDictObject* pProperties = (CDictObject*)pResources->Get("Properties"); + if (!pProperties) + { + pProperties = new CDictObject(); + pResources->Add("Properties", pProperties); + } + CObjectBase* pObj = pProperties->Get("OShapes"); + if (pObj && pObj->GetType() != object_type_DICT) + { + pProperties->Remove("OShapes"); + pObj = NULL; + } + + CBinaryObject* sID = NULL; + CArrayObject* pID = (CArrayObject*)m_pTrailer->Get("ID"); + if (!pID) + { + BYTE arrId[16]; + CEncryptDict::CreateId(m_pInfo, m_pXref, (BYTE*)arrId); + + pID = new CArrayObject(); + m_pTrailer->Add("ID", pID); + + pID->Add(new CBinaryObject(arrId, 16)); + pID->Add(new CBinaryObject(arrId, 16)); + + sID = new CBinaryObject(arrId, 16); + } + else + sID = (CBinaryObject*)pID->Get(1)->Copy(); + + CDictObject* pMetaOForm = (CDictObject*)pObj; + if (!pMetaOForm) + { + pMetaOForm = new CDictObject(); + m_pXref->Add(pMetaOForm); + pMetaOForm->Add("Type", "OShapes"); + pProperties->Add("OShapes", pMetaOForm); + m_vMetaOForms.push_back(pMetaOForm); + pMetaOForm->Add("IDF", sID->Copy()); + pMetaOForm->Add("ID", sID->Copy()); + } + CArrayObject* pArrayMeta = (CArrayObject*)pMetaOForm->Get("Metadata"); + if (!pArrayMeta) + { + pArrayMeta = new CArrayObject(); + pMetaOForm->Add("Metadata", pArrayMeta); + CArrayObject* pArrayImage = new CArrayObject(); + pMetaOForm->Add("Image", pArrayImage); + } + pArrayMeta->Add(new CStringObject(sXML.c_str())); + + CDictObject* pBDC = new CDictObject(); + pBDC->Add("MCID", pArrayMeta->GetCount() - 1); + pBDC->Add("IDF", sID); + m_pCurPage->BeginMarkedContentDict("OShapes", pBDC); + RELEASEOBJECT(pBDC); + } + void CDocument::EndShapeXML() + { + CDictObject* pResources = (CDictObject*)m_pCurPage->GetResourcesItem(); + if (!pResources) + return; + CDictObject* pProperties = (CDictObject*)pResources->Get("Properties"); + if (!pProperties) + return; + CObjectBase* pObj = pProperties->Get("OShapes"); + if (!pObj || pObj->GetType() != object_type_DICT) + return; + CDictObject* pMetaOForm = (CDictObject*)pObj; + CArrayObject* pArrayImage = (CArrayObject*)pMetaOForm->Get("Image"); + if (!pArrayImage) + return; + + pObj = m_pCurImage; + if (!pObj) + pObj = new PdfWriter::CNullObject(); + pArrayImage->Add(pObj); + + m_pCurPage->EndMarkedContent(); + } + void CDocument::ClearPage() + { + m_pCurPage->ClearContent(m_pXref); + m_pCurPage->StartTransform(1, 0, 0, 1, 0, 0); + } } diff --git a/PdfFile/SrcWriter/Document.h b/PdfFile/SrcWriter/Document.h index eff9e96b3a7..6e5fc1f0659 100644 --- a/PdfFile/SrcWriter/Document.h +++ b/PdfFile/SrcWriter/Document.h @@ -70,6 +70,7 @@ namespace PdfWriter class CDestination; class CExtGrState; class CAnnotation; + class CAction; class CImageDict; class CFontDict; class CFont14; @@ -89,6 +90,8 @@ namespace PdfWriter class CSignatureField; class CDateTimeField; class CFieldBase; + class CStreamData; + class CXObject; //---------------------------------------------------------------------------------------- // CDocument //---------------------------------------------------------------------------------------- @@ -101,7 +104,8 @@ namespace PdfWriter bool CreateNew(); void Close(); - bool SaveToFile(const std::wstring& wsPath, bool bAdd = true); + bool SaveToFile(const std::wstring& wsPath); + bool SaveNewWithPassword(CXref* pXref, CXref* _pXref, const std::wstring& wsPath, const std::wstring& wsOwnerPassword, const std::wstring& wsUserPassword, CDictObject* pTrailer); void SetPasswords(const std::wstring & wsOwnerPassword, const std::wstring & wsUserPassword); void SetPermission(unsigned int unPermission); @@ -123,7 +127,8 @@ namespace PdfWriter void AddPageLabel(EPageNumStyle eStyle, unsigned int unFirstPage, const char* sPrefix); void AddPageLabel(unsigned int unPageIndex, EPageNumStyle eStyle, unsigned int unFirstPage, const char* sPrefix); COutline* CreateOutline(COutline* pParent, const char* sTitle); - CDestination* CreateDestination(unsigned int unPageIndex); + CDestination* CreateDestination(CPage* pPage, bool bInline = false); + bool AddMetaData(const std::wstring& sMetaName, BYTE* pMetaData, DWORD nMetaLength); CExtGrState* GetExtGState(double dAlphaStroke = -1, double dAlphaFill = -1, EBlendMode eMode = blendmode_Unknown, int nStrokeAdjustment = -1); CExtGrState* GetStrokeAlpha(double dAlpha); @@ -141,15 +146,20 @@ namespace PdfWriter CAnnotation* CreatePopupAnnot(); CAnnotation* CreateFreeTextAnnot(); CAnnotation* CreateCaretAnnot(); + CAnnotation* CreateStampAnnot(); CAnnotation* CreateWidgetAnnot(); - CAnnotation* CreateButtonWidget(); + CAnnotation* CreatePushButtonWidget(); + CAnnotation* CreateCheckBoxWidget(); CAnnotation* CreateTextWidget(); CAnnotation* CreateChoiceWidget(); CAnnotation* CreateSignatureWidget(); void AddAnnotation(const int& nID, CAnnotation* pAnnot); + CAction* CreateAction(BYTE nType); CImageDict* CreateImage(); - CFont14* CreateFont14(EStandard14Fonts eType); + CXObject* CreateForm(CImageDict* pImage, const std::string& sName); + CFont14* CreateFont14(const std::wstring& wsFontPath, unsigned int unIndex, EStandard14Fonts eType); + CFont14* FindFont14 (const std::wstring& wsFontPath, unsigned int unIndex); CFontCidTrueType* CreateCidTrueTypeFont(const std::wstring& wsFontPath, unsigned int unIndex); CFontCidTrueType* FindCidTrueTypeFont(const std::wstring& wsFontPath, unsigned int unIndex); CFontTrueType* CreateTrueTypeFont(const std::wstring& wsFontPath, unsigned int unIndex); @@ -170,9 +180,16 @@ namespace PdfWriter CSignatureField* CreateSignatureField(); CDateTimeField* CreateDateTimeField(); bool CheckFieldName(CFieldBase* pField, const std::string& sName); + + bool HasImage(const std::wstring& wsImagePath, BYTE nAlpha); + CImageDict* GetImage(const std::wstring& wsImagePath, BYTE nAlpha); + void AddImage(const std::wstring& wsImagePath, BYTE nAlpha, CImageDict* pImage); + CImageDict* GetCurImage() { return m_pCurImage; } + void SetCurImage(CImageDict* pImage) { m_pCurImage = pImage; } bool CreatePageTree(CXref* pXref, CPageTree* pPageTree); bool EditPdf(const std::wstring& wsPath, int nPosLastXRef, int nSizeXRef, CXref* pXref, CCatalog* pCatalog, CEncryptDict* pEncrypt, int nFormField); + bool EditResources(CXref* pXref, CResourcesDict* pResources); std::pair GetPageRef(int nPageIndex); bool EditPage(CXref* pXref, CPage* pPage, int nPageIndex); CPage* AddPage(int nPageIndex); @@ -184,8 +201,16 @@ namespace PdfWriter bool EditParent(CXref* pXref, CDictObject* pParent, int nID); bool DeleteAnnot(int nObjNum, int nObjGen); CAnnotation* GetAnnot(int nID); + CDictObject* GetParent(int nID); CPage* GetCurPage() { return m_pCurPage; } void SetCurPage(CPage* pPage) { m_pCurPage = pPage; } + CPage* CreateFakePage(); + bool EditCO(const std::vector& arrCO); + const std::map& GetAnnots() { return m_mAnnotations; } + void AddShapeXML(const std::string& sXML); + void EndShapeXML(); + void ClearPage(); + bool EditXref(CXref* pXref); private: char* GetTTFontTag(); @@ -201,7 +226,6 @@ namespace PdfWriter bool CheckAcroForm(); CRadioGroupField* FindRadioGroupField(const std::wstring& wsGroupName); void Sign(const std::wstring& wsPath, unsigned int nSizeXRef, bool bNeedStreamXRef = false); - bool EditXref(CXref* pXref); private: @@ -233,6 +257,19 @@ namespace PdfWriter CImageDict* pImage; ICertificate* pCertificate; }; + struct TImageInfo + { + TImageInfo(const std::wstring& _wsImagePath, BYTE _nAlpha, CImageDict* _pImage) + { + wsImagePath = _wsImagePath; + nAlpha = _nAlpha; + pImage = _pImage; + } + + std::wstring wsImagePath; + BYTE nAlpha; + CImageDict* pImage; + }; CCatalog* m_pCatalog; COutline* m_pOutlines; @@ -241,12 +278,15 @@ namespace PdfWriter CPageTree* m_pPageTree; CPage* m_pCurPage; int m_nCurPageNum; + CImageDict* m_pCurImage; CInfoDict* m_pInfo; CDictObject* m_pTrailer; CDictObject* m_pResources; + CStreamData* m_pMetaData; bool m_bEncrypt; CEncryptDict* m_pEncryptDict; std::vector m_vSignatures; + std::vector m_vImages; unsigned int m_unFormFields; unsigned int m_unCompressMode; std::vector m_vExtGrStates; @@ -257,6 +297,7 @@ namespace PdfWriter std::vector m_vShadings; std::vector m_vCidTTFonts; std::vector m_vTTFonts; + std::vector m_vFonts14; CFont14* m_pDefaultCheckBoxFont; CDictObject* m_pTransparencyGroup; std::vector m_vFreeTypeFonts; @@ -267,6 +308,7 @@ namespace PdfWriter CDictObject* m_pAcroForm; CResourcesDict* m_pFieldsResources; std::vector m_vRadioGroups; + std::vector m_vMetaOForms; std::map m_mFields; std::map m_mAnnotations; std::map m_mParents; diff --git a/PdfFile/SrcWriter/Encrypt.cpp b/PdfFile/SrcWriter/Encrypt.cpp index 78d3ebc98a4..f47451e399f 100644 --- a/PdfFile/SrcWriter/Encrypt.cpp +++ b/PdfFile/SrcWriter/Encrypt.cpp @@ -203,6 +203,12 @@ namespace PdfWriter m_unPermission = ENABLE_PRINT | ENABLE_EDIT_ALL | ENABLE_COPY | ENABLE_EDIT | PERMISSION_PAD; MemSet(m_anEncryptID, 0, ID_LEN); + + MemSet(m_anOwnerKey, 0, 48); + MemSet(m_anUserKey, 0, 48); + MemSet(m_anOwnerEncryptKey, 0, 32); + MemSet(m_anUserEncryptKey, 0, 32); + MemSet(m_anPermEncrypt, 0, 16); } CEncrypt::~CEncrypt() { diff --git a/PdfFile/SrcWriter/EncryptDictionary.cpp b/PdfFile/SrcWriter/EncryptDictionary.cpp index d0d42ac5c77..5842adc7c8b 100644 --- a/PdfFile/SrcWriter/EncryptDictionary.cpp +++ b/PdfFile/SrcWriter/EncryptDictionary.cpp @@ -205,9 +205,9 @@ namespace PdfWriter CBinaryObject* pEncryptPerm = new CBinaryObject(m_pEncrypt->m_anPermEncrypt, 16); Add("Perms", pEncryptPerm); } - void CEncryptDict::UpdateKey(int nCryptAlgorithm) + bool CEncryptDict::UpdateKey(int nCryptAlgorithm) { - m_pEncrypt->MakeFileKey(nCryptAlgorithm); + return m_pEncrypt->MakeFileKey(nCryptAlgorithm); } //---------------------------------------------------------------------------------------- // CSignatureDict @@ -254,17 +254,42 @@ namespace PdfWriter CSignatureDict::~CSignatureDict() { } - void CSignatureDict::SetByteRange(int nLen1, int nOffset2) - { - m_nLen1 = nLen1; - m_nOffset2 = nOffset2; - } - void CSignatureDict::ByteRangeOffset(int nBegin, int nEnd) - { - m_nByteRangeBegin = nBegin; - m_nByteRangeEnd = nEnd; - } - void CSignatureDict::WriteToStream(CStream* pStream, int nFileEnd) + void CSignatureDict::WriteToStream(CStream* pStream, CEncrypt* pEncrypt) + { + for (auto const &oIter : m_mList) + { + CObjectBase* pObject = oIter.second; + if (!pObject) + continue; + + if (pObject->IsHidden()) + { + // ничего не делаем + } + else + { + int nBegin, nEnd; + pStream->WriteEscapeName(oIter.first.c_str()); + pStream->WriteChar(' '); + nBegin = pStream->Tell(); + // Цифровая подпись не шифруется + pStream->Write(pObject, oIter.first == "Contents" ? NULL : pEncrypt); + nEnd = pStream->Tell(); + pStream->WriteStr("\012"); + if (oIter.first == "Contents") + { + m_nLen1 = nBegin; + m_nOffset2 = nEnd; + } + if (oIter.first == "ByteRange") + { + m_nByteRangeBegin = nBegin; + m_nByteRangeEnd = nEnd; + } + } + } + } + void CSignatureDict::WriteToStream(CStream* pStream, int nFileEnd) { // Запись ByteRange if (m_nByteRangeBegin > 0 && m_nByteRangeEnd > 0 && m_nByteRangeBegin < m_nByteRangeEnd && m_nByteRangeEnd < nFileEnd) diff --git a/PdfFile/SrcWriter/EncryptDictionary.h b/PdfFile/SrcWriter/EncryptDictionary.h index a02222e7a54..d296223e087 100644 --- a/PdfFile/SrcWriter/EncryptDictionary.h +++ b/PdfFile/SrcWriter/EncryptDictionary.h @@ -61,7 +61,7 @@ namespace PdfWriter { return m_pEncrypt; } - void UpdateKey(int nCryptAlgorithm); + bool UpdateKey(int nCryptAlgorithm); private: CEncrypt* m_pEncrypt; std::string PadOrTrancatePassword(const std::wstring & wsPassword); @@ -72,13 +72,12 @@ namespace PdfWriter public: CSignatureDict(CXref* pXref); ~CSignatureDict(); - EDictType GetDictType() const + EDictType GetDictType() const override { return dict_type_SIGNATURE; } - void SetByteRange(int nLen1, int nOffset2); - void ByteRangeOffset(int nBegin, int nEnd); + void WriteToStream(CStream* pStream, CEncrypt* pEncrypt) override; void WriteToStream(CStream* pStream, int nFileEnd); void SetCert(ICertificate* pCert); diff --git a/PdfFile/SrcWriter/Field.cpp b/PdfFile/SrcWriter/Field.cpp index fc92c70f86d..ba50565fb4a 100644 --- a/PdfFile/SrcWriter/Field.cpp +++ b/PdfFile/SrcWriter/Field.cpp @@ -39,6 +39,7 @@ #include "Font.h" #include "Info.h" #include "EncryptDictionary.h" +#include "Annotation.h" #include #include @@ -76,6 +77,7 @@ namespace PdfWriter m_pAppearance = NULL; m_pFocus = NULL; m_pBlur = NULL; + m_pFont = NULL; } void CFieldBase::SetReadOnlyFlag(bool isReadOnly) { @@ -267,6 +269,7 @@ namespace PdfWriter } pNormal->DrawSimpleText(wsValue, pCodes, unCount, pFont, dFontSize, dX, dY, oColor.r, oColor.g, oColor.b, sExtGrStateName, fabs(m_oRect.fRight - m_oRect.fLeft), fabs(m_oRect.fBottom - m_oRect.fTop), ppFonts, pShifts); + m_pFont = pNormal->GetFont(); } void CFieldBase::StartTextAppearance(CFontDict* pFont, const double& dFontSize, const TRgb& oColor, const double& dAlpha) { @@ -287,6 +290,7 @@ namespace PdfWriter } pNormal->StartDrawText(pFont, dFontSize, oColor.r, oColor.g, oColor.b, sExtGrStateName, fabs(m_oRect.fRight - m_oRect.fLeft), fabs(m_oRect.fBottom - m_oRect.fTop)); + m_pFont = pNormal->GetFont(); } void CFieldBase::AddLineToTextAppearance(const double& dX, const double& dY, unsigned short* pCodes, const unsigned int& unCodesCount, CFontCidTrueType** ppFonts, const double* pShifts) { @@ -295,6 +299,7 @@ namespace PdfWriter CAnnotAppearanceObject* pNormal = m_pAppearance->GetNormal(); pNormal->DrawTextLine(dX, dY, pCodes, unCodesCount, ppFonts, pShifts); + m_pFont = pNormal->GetFont(); } void CFieldBase::EndTextAppearance() { @@ -697,6 +702,10 @@ namespace PdfWriter AddScriptToAA("F", scriptF, pAA); } } + CFontDict* CFieldBase::GetFont() + { + return m_pFont; + } //---------------------------------------------------------------------------------------- // CTextField //---------------------------------------------------------------------------------------- @@ -1518,6 +1527,7 @@ namespace PdfWriter { m_pXref = pXref; m_pField = pField; + m_pAnnot = NULL; m_pNormal = new CAnnotAppearanceObject(pXref, pField); m_pRollover = NULL; @@ -1525,25 +1535,51 @@ namespace PdfWriter Add("N", m_pNormal); } - CAnnotAppearanceObject* CAnnotAppearance::GetNormal() + CAnnotAppearance::CAnnotAppearance(CXref* pXref, CAnnotation* pAnnot) { + m_pXref = pXref; + m_pAnnot = pAnnot; + m_pField = NULL; + + m_pNormal = NULL; + m_pRollover = NULL; + m_pDown = NULL; + } + CAnnotAppearanceObject* CAnnotAppearance::GetNormal(CResourcesDict* pResources) + { + if (!m_pNormal) + { + if (m_pField) + m_pNormal = new CAnnotAppearanceObject(m_pXref, m_pField); + else if (m_pAnnot) + m_pNormal = new CAnnotAppearanceObject(m_pXref, m_pAnnot, pResources); + if (m_pXref) + Add("N", m_pNormal); + } + return m_pNormal; } - CAnnotAppearanceObject* CAnnotAppearance::GetRollover() + CAnnotAppearanceObject* CAnnotAppearance::GetRollover(CResourcesDict* pResources) { if (!m_pRollover) { - m_pRollover = new CAnnotAppearanceObject(m_pXref, m_pField); + if (m_pField) + m_pRollover = new CAnnotAppearanceObject(m_pXref, m_pField); + else if (m_pAnnot) + m_pRollover = new CAnnotAppearanceObject(m_pXref, m_pAnnot, pResources); Add("R", m_pRollover); } return m_pRollover; } - CAnnotAppearanceObject* CAnnotAppearance::GetDown() + CAnnotAppearanceObject* CAnnotAppearance::GetDown(CResourcesDict* pResources) { if (!m_pDown) { - m_pDown = new CAnnotAppearanceObject(m_pXref, m_pField); + if (m_pField) + m_pDown = new CAnnotAppearanceObject(m_pXref, m_pField); + else if (m_pAnnot) + m_pDown = new CAnnotAppearanceObject(m_pXref, m_pAnnot, pResources); Add("D", m_pDown); } @@ -1591,20 +1627,31 @@ namespace PdfWriter //---------------------------------------------------------------------------------------- // CAnnotAppearanceObject //---------------------------------------------------------------------------------------- - CAnnotAppearanceObject::CAnnotAppearanceObject(CXref* pXref, CFieldBase* pField) + void CAnnotAppearanceObject::Init(CXref* pXref, CResourcesDict* pResources) { - m_pXref = pXref; - m_pStream = new CMemoryStream(); - m_pField = pField; + m_pXref = pXref ? pXref : NULL; m_pFont = NULL; m_dFontSize = 10.0; + m_bStart = true; - SetStream(m_pXref, m_pStream); + if (m_pXref) + { + m_pStream = new CMemoryStream(); + SetStream(m_pXref, m_pStream); +#ifndef FILTER_FLATE_DECODE_DISABLED + SetFilter(STREAM_FILTER_FLATE_DECODE); +#endif + } Add("Type", "XObject"); Add("Subtype", "Form"); - - TRect oRect = pField->GetRect(); + Add("Resources", pResources); + } + CAnnotAppearanceObject::CAnnotAppearanceObject(CXref* pXref, CFieldBase* pField) + { + Init(pXref, pField->GetResourcesDict()); + m_pField = pField; + m_pAnnot = NULL; CArrayObject* pArray = new CArrayObject(); if (!pArray) @@ -1613,14 +1660,27 @@ namespace PdfWriter Add("BBox", pArray); pArray->Add(0); pArray->Add(0); - pArray->Add(oRect.fRight - oRect.fLeft); - pArray->Add(oRect.fBottom - oRect.fTop); + pArray->Add(fabs(pField->GetRect().fRight - pField->GetRect().fLeft)); + pArray->Add(fabs(pField->GetRect().fBottom - pField->GetRect().fTop)); + } + CAnnotAppearanceObject::CAnnotAppearanceObject(CXref* pXRef, CAnnotation* pAnnot, CResourcesDict* pResources) + { + Init(pXRef, pResources ? pResources : pAnnot->GetDocument()->GetFieldsResources()); + m_pAnnot = pAnnot; + m_pField = NULL; - Add("Resources", pField->GetResourcesDict()); + if (pAnnot->GetAnnotationType() == EAnnotType::AnnotWidget) + { + CArrayObject* pArray = new CArrayObject(); + if (!pArray) + return; + Add("BBox", pArray); -#ifndef FILTER_FLATE_DECODE_DISABLED - //SetFilter(STREAM_FILTER_FLATE_DECODE); -#endif + pArray->Add(0); + pArray->Add(0); + pArray->Add(fabs(pAnnot->GetRect().fRight - pAnnot->GetRect().fLeft)); + pArray->Add(fabs(pAnnot->GetRect().fBottom - pAnnot->GetRect().fTop)); + } } void CAnnotAppearanceObject::DrawSimpleText(const std::wstring& wsText, unsigned short* pCodes, unsigned int unCount, CFontDict* pFont, double dFontSize, double dX, double dY, double dR, double dG, double dB, const char* sExtGStateName, double dWidth, double dHeight, CFontCidTrueType** ppFonts, double* pShifts) { @@ -1641,25 +1701,37 @@ namespace PdfWriter if (!m_pStream) return; + CWidgetAnnotation* pAnnot = NULL; + if (m_pAnnot) + pAnnot = (CWidgetAnnotation*)m_pAnnot; + double dW = 0, dH = 0; - if (m_pField) + if (m_pField || pAnnot) { - TRect oRect = m_pField->GetRect(); + TRect oRect = m_pField ? m_pField->GetRect() : pAnnot->GetRect(); dW = fabs(oRect.fRight - oRect.fLeft); dH = fabs(oRect.fBottom - oRect.fTop); } m_pStream->WriteStr("q\012"); - if (m_pField->HaveShd()) + if ((m_pField && m_pField->HaveShd()) || (pAnnot && pAnnot->HaveBG())) { - TRgb oColor = m_pField->GetShdColor(); - m_pStream->WriteReal(oColor.r); - m_pStream->WriteChar(' '); - m_pStream->WriteReal(oColor.g); - m_pStream->WriteChar(' '); - m_pStream->WriteReal(oColor.b); - m_pStream->WriteStr(" rg\012"); + if (m_pField) + { + TRgb oColor = m_pField->GetShdColor(); + m_pStream->WriteReal(oColor.r); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(oColor.g); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(oColor.b); + m_pStream->WriteStr(" rg\012"); + } + else + { + m_pStream->WriteStr(pAnnot->GetBGforAP().c_str()); + m_pStream->WriteStr("\012"); + } m_pStream->WriteStr("1 0 0 1 0 0 cm\012"); m_pStream->WriteStr("0 0 "); @@ -1678,30 +1750,145 @@ namespace PdfWriter m_pStream->WriteStr(" re\012f\012"); } - if (m_pField->HaveBorder()) + if ((m_pField && m_pField->HaveBorder()) || (pAnnot && pAnnot->HaveBorder())) { - TRgb oColor = m_pField->GetBorderColor(); + double dBorderSize = m_pField ? m_pField->GetBorderSize() : pAnnot->GetBorderWidth(); - m_pStream->WriteReal(oColor.r); - m_pStream->WriteChar(' '); - m_pStream->WriteReal(oColor.g); - m_pStream->WriteChar(' '); - m_pStream->WriteReal(oColor.b); - m_pStream->WriteStr(" RG\012"); + BYTE nType = 0; + if (pAnnot) + { + nType = pAnnot->GetBorderType(); + switch (nType) + { + case 1: // Beveled + case 3: // Inset + { + m_pStream->WriteStr(nType == 1 ? "1 g\012" : "0.501953 g\012"); + + m_pStream->WriteReal(dBorderSize); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(dBorderSize); + m_pStream->WriteStr(" m\012"); + + m_pStream->WriteReal(dBorderSize); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(dH - dBorderSize); + m_pStream->WriteStr(" l\012"); + + m_pStream->WriteReal(dW - dBorderSize); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(dH - dBorderSize); + m_pStream->WriteStr(" l\012"); + + m_pStream->WriteReal(dW - 2 * dBorderSize); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(dH - 2 * dBorderSize); + m_pStream->WriteStr(" l\012"); + + m_pStream->WriteReal(2 * dBorderSize); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(dH - 2 * dBorderSize); + m_pStream->WriteStr(" l\012"); + + m_pStream->WriteReal(2 * dBorderSize); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(2 * dBorderSize); + m_pStream->WriteStr(" l\012"); + + m_pStream->WriteStr("f\012"); + + if (nType == 1 && pAnnot->HaveBG()) + { + m_pStream->WriteStr(pAnnot->GetBGforAP(-0.25).c_str()); + m_pStream->WriteStr("\012"); + } + else + m_pStream->WriteStr("0.75293 g\012"); + + m_pStream->WriteReal(dW - dBorderSize); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(dH - dBorderSize); + m_pStream->WriteStr(" m\012"); + + m_pStream->WriteReal(dW - dBorderSize); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(dBorderSize); + m_pStream->WriteStr(" l\012"); + + m_pStream->WriteReal(dBorderSize); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(dBorderSize); + m_pStream->WriteStr(" l\012"); + + m_pStream->WriteReal(2 * dBorderSize); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(2 * dBorderSize); + m_pStream->WriteStr(" l\012"); + + m_pStream->WriteReal(dW - 2 * dBorderSize); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(2 * dBorderSize); + m_pStream->WriteStr(" l\012"); + + m_pStream->WriteReal(dW - 2 * dBorderSize); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(dH - 2 * dBorderSize); + m_pStream->WriteStr(" l\012"); + + m_pStream->WriteStr("f\012"); + break; + } + case 2: // Dashed + { + m_pStream->WriteStr(pAnnot->GetBorderDash().c_str()); + break; + } + default: break; + } + } + + if (m_pField) + { + TRgb oColor = m_pField->GetBorderColor(); + m_pStream->WriteReal(oColor.r); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(oColor.g); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(oColor.b); + m_pStream->WriteStr(" RG\012"); + } + else + { + m_pStream->WriteStr(pAnnot->GetBCforAP().c_str()); + m_pStream->WriteStr("\012"); + } - double dBorderSize = m_pField->GetBorderSize(); - double dBorderSize_2 = dBorderSize / 2; m_pStream->WriteReal(dBorderSize); m_pStream->WriteStr(" w\0120 j\0120 J\012"); - m_pStream->WriteReal(dBorderSize_2); - m_pStream->WriteChar(' '); - m_pStream->WriteReal(dBorderSize_2); - m_pStream->WriteChar(' '); - m_pStream->WriteReal(fmax(dW - dBorderSize, 0.0)); - m_pStream->WriteChar(' '); - m_pStream->WriteReal(fmax(dH - dBorderSize, 0.0)); - m_pStream->WriteStr(" re\012S\012"); + if (nType == 4) // Underline + { + m_pStream->WriteInt(0); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(dBorderSize / 2); + m_pStream->WriteStr(" m\012"); + + m_pStream->WriteReal(dW); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(dBorderSize / 2); + m_pStream->WriteStr(" l\012S\012"); + } + else + { + m_pStream->WriteReal(dBorderSize / 2); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(dBorderSize / 2); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(std::max(dW - dBorderSize, 0.0)); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(std::max(dH - dBorderSize, 0.0)); + m_pStream->WriteStr(" re\012S\012"); + } if (bRespectBorder && sImageName) { @@ -1728,7 +1915,6 @@ namespace PdfWriter if (sImageName) { - m_pStream->WriteReal(dImageW); m_pStream->WriteStr(" 0 0 "); m_pStream->WriteReal(dImageH); @@ -1746,23 +1932,35 @@ namespace PdfWriter } void CAnnotAppearanceObject::StartDrawText(CFontDict* pFont, const double& dFontSize, const double& dR, const double& dG, const double& dB, const char* sExtGStateName, const double& dWidth, const double& dHeight) { - CResourcesDict* pResources = m_pField->GetResourcesDict(); - if (!m_pStream || !pFont || !pResources) + CResourcesDict* pResources = dynamic_cast(Get("Resources")); + if (!m_pStream || !pResources) return; + CWidgetAnnotation* pAnnot = NULL; + if (m_pAnnot) + pAnnot = (CWidgetAnnotation*)m_pAnnot; + m_pStream->WriteEscapeName("Tx"); m_pStream->WriteStr(" BMC\012"); - if (m_pField->HaveShd()) + if ((m_pField && m_pField->HaveShd()) || (pAnnot && pAnnot->HaveBG())) { m_pStream->WriteStr("q\012"); - TRgb oColor = m_pField->GetShdColor(); - m_pStream->WriteReal(oColor.r); - m_pStream->WriteChar(' '); - m_pStream->WriteReal(oColor.g); - m_pStream->WriteChar(' '); - m_pStream->WriteReal(oColor.b); - m_pStream->WriteStr(" rg\012"); + if (m_pField) + { + TRgb oColor = m_pField->GetShdColor(); + m_pStream->WriteReal(oColor.r); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(oColor.g); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(oColor.b); + m_pStream->WriteStr(" rg\012"); + } + else + { + m_pStream->WriteStr(pAnnot->GetBGforAP().c_str()); + m_pStream->WriteStr("\012"); + } m_pStream->WriteStr("1 0 0 1 0 0 cm\012"); m_pStream->WriteStr("0 0 "); @@ -1773,40 +1971,168 @@ namespace PdfWriter m_pStream->WriteStr("Q\012"); } - double dBorderSize = 0; - double dBorderSize_2 = 0; - double dBorderSize2 = 0; - if (m_pField && m_pField->HaveBorder()) + double dBorderSize = 0; + double dBorderSizeStyle = 0; + + if (pAnnot && pAnnot->HaveBorder()) + { + dBorderSize = pAnnot->GetBorderWidth(); + dBorderSizeStyle = dBorderSize; + + if (pAnnot->GetBorderType() == 1 || pAnnot->GetBorderType() == 3) + dBorderSizeStyle *= 2; + } + + if ((m_pField && m_pField->HaveBorder()) || (pAnnot && pAnnot->HaveBorder() && pAnnot->HaveBC())) { - TRgb oColor = m_pField->GetBorderColor(); m_pStream->WriteStr("q\012"); - m_pStream->WriteReal(oColor.r); - m_pStream->WriteChar(' '); - m_pStream->WriteReal(oColor.g); - m_pStream->WriteChar(' '); - m_pStream->WriteReal(oColor.b); - m_pStream->WriteStr(" RG\012"); + dBorderSize = m_pField ? m_pField->GetBorderSize() : pAnnot->GetBorderWidth(); + dBorderSizeStyle = dBorderSize; + + BYTE nType = 0; + if (pAnnot) + { + nType = pAnnot->GetBorderType(); + switch (nType) + { + case 1: // Beveled + case 3: // Inset + { + dBorderSizeStyle *= 2; + + m_pStream->WriteStr(nType == 1 ? "1 g\012" : "0.501953 g\012"); + + m_pStream->WriteReal(dBorderSize); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(dBorderSize); + m_pStream->WriteStr(" m\012"); + + m_pStream->WriteReal(dBorderSize); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(dHeight - dBorderSize); + m_pStream->WriteStr(" l\012"); + + m_pStream->WriteReal(dWidth - dBorderSize); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(dHeight - dBorderSize); + m_pStream->WriteStr(" l\012"); + + m_pStream->WriteReal(dWidth - 2 * dBorderSize); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(dHeight - 2 * dBorderSize); + m_pStream->WriteStr(" l\012"); + + m_pStream->WriteReal(2 * dBorderSize); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(dHeight - 2 * dBorderSize); + m_pStream->WriteStr(" l\012"); + + m_pStream->WriteReal(2 * dBorderSize); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(2 * dBorderSize); + m_pStream->WriteStr(" l\012"); + + m_pStream->WriteStr("f\012"); + + if (nType == 1 && pAnnot->HaveBG()) + { + m_pStream->WriteStr(pAnnot->GetBGforAP(-0.25).c_str()); + m_pStream->WriteStr("\012"); + } + else + m_pStream->WriteStr("0.75293 g\012"); + + m_pStream->WriteReal(dWidth - dBorderSize); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(dHeight - dBorderSize); + m_pStream->WriteStr(" m\012"); + + m_pStream->WriteReal(dWidth - dBorderSize); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(dBorderSize); + m_pStream->WriteStr(" l\012"); + + m_pStream->WriteReal(dBorderSize); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(dBorderSize); + m_pStream->WriteStr(" l\012"); + + m_pStream->WriteReal(2 * dBorderSize); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(2 * dBorderSize); + m_pStream->WriteStr(" l\012"); + + m_pStream->WriteReal(dWidth - 2 * dBorderSize); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(2 * dBorderSize); + m_pStream->WriteStr(" l\012"); + + m_pStream->WriteReal(dWidth - 2 * dBorderSize); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(dHeight - 2 * dBorderSize); + m_pStream->WriteStr(" l\012"); + + m_pStream->WriteStr("f\012"); + break; + } + case 2: // Dashed + { + m_pStream->WriteStr(pAnnot->GetBorderDash().c_str()); + break; + } + default: break; + } + } + + if (m_pField) + { + TRgb oColor = m_pField->GetBorderColor(); + m_pStream->WriteReal(oColor.r); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(oColor.g); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(oColor.b); + m_pStream->WriteStr(" RG\012"); + } + else + { + m_pStream->WriteStr(pAnnot->GetBCforAP().c_str()); + m_pStream->WriteStr("\012"); + } - dBorderSize = m_pField->GetBorderSize(); - dBorderSize_2 = dBorderSize / 2; - dBorderSize2 = dBorderSize * 2; m_pStream->WriteReal(dBorderSize); m_pStream->WriteStr(" w\0120 j\0120 J\012"); - m_pStream->WriteReal(dBorderSize_2); - m_pStream->WriteChar(' '); - m_pStream->WriteReal(dBorderSize_2); - m_pStream->WriteChar(' '); - m_pStream->WriteReal(std::max(dWidth - dBorderSize, 0.0)); - m_pStream->WriteChar(' '); - m_pStream->WriteReal(std::max(dHeight - dBorderSize, 0.0)); - m_pStream->WriteStr(" re\012S\012"); + if (nType == 4) // Underline + { + m_pStream->WriteInt(0); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(dBorderSize / 2); + m_pStream->WriteStr(" m\012"); + + m_pStream->WriteReal(dWidth); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(dBorderSize / 2); + m_pStream->WriteStr(" l\012S\012"); + } + else + { + m_pStream->WriteReal(dBorderSize / 2); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(dBorderSize / 2); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(std::max(dWidth - dBorderSize, 0.0)); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(std::max(dHeight - dBorderSize, 0.0)); + m_pStream->WriteStr(" re\012S\012"); + } CTextField* pTextField = dynamic_cast(m_pField); - if (pTextField && pTextField->IsCombFlag()) + CTextWidget* pAnnot = dynamic_cast(m_pAnnot); + if ((pTextField && pTextField->IsCombFlag()) || (pAnnot && pAnnot->IsCombFlag() && (nType == 0 || nType == 2))) { - int nMaxLen = pTextField->GetMaxLen(); + int nMaxLen = pTextField ? pTextField->GetMaxLen() : pAnnot->GetMaxLen(); if (nMaxLen > 1) { double dStep = dWidth / nMaxLen; @@ -1834,44 +2160,341 @@ namespace PdfWriter m_pStream->WriteStr("q\012"); + if (pAnnot && pAnnot->GetWidgetType() == WidgetPushbutton && !((CPushButtonWidget*)pAnnot)->GetRespectBorder()) + { + m_pStream->WriteStr("0 0 "); + m_pStream->WriteReal(std::max(dWidth, 0.0)); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(std::max(dHeight, 0.0)); + } + else + { + m_pStream->WriteReal(dBorderSizeStyle); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(dBorderSizeStyle); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(std::max(dWidth - dBorderSizeStyle * 2, 0.0)); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(std::max(dHeight - dBorderSizeStyle * 2, 0.0)); + } + m_pStream->WriteStr(" re\012W\012n\012"); + + if (pAnnot && pAnnot->GetWidgetType() == WidgetListbox) + { + CChoiceWidget* pAnnot = dynamic_cast(m_pAnnot); + double dBaseLine = pAnnot->GetListBoxHeight(); + std::vector arrIndex = pAnnot->GetListBoxIndex(); + m_pStream->WriteStr("0.60 0.75 0.85 rg\012"); + for (int i = 0; i < arrIndex.size(); ++i) + { + double dH = dHeight - dBorderSizeStyle - dBaseLine * (double)(arrIndex[i] + 1); + if (dH < 0) + break; + m_pStream->WriteReal(dBorderSizeStyle); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(dH); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(std::max(dWidth - dBorderSizeStyle * 2.0, 0.0)); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(dBaseLine); + m_pStream->WriteStr(" re\012f\012"); + } + } + + m_pStream->WriteStr("BT\012"); + + m_dFontSize = std::min(1000.0, std::max(0.0, dFontSize)); + if (m_pField) + { + m_pStream->WriteReal(dR); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(dG); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(dB); + m_pStream->WriteStr(" rg\012"); + + if (sExtGStateName) + { + m_pStream->WriteEscapeName(sExtGStateName); + m_pStream->WriteStr(" gs\012"); + } + + m_pStream->WriteEscapeName(pResources->GetFontName(pFont)); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(m_dFontSize); + m_pStream->WriteStr(" Tf\012"); + } + else if (pFont) + m_pStream->WriteStr(pAnnot->GetDAforAP(pFont).c_str()); + + m_bStart = true; + m_pFont = pFont; + } + void CAnnotAppearanceObject::StartDraw(const double& dWidth, const double& dHeight) + { + CWidgetAnnotation* pAnnot = dynamic_cast(m_pAnnot); + if (!m_pStream || !pAnnot) + return; + + DrawBackground(dWidth, dHeight); + DrawBorder(dWidth, dHeight); + + m_pStream->WriteStr("q\012"); + + double dBorderSize = pAnnot->GetBorderWidth(); + BYTE nType = pAnnot->GetBorderType(); + if (nType == 1 || nType == 3) + dBorderSize *= 2; + + if (pAnnot->GetWidgetType() == WidgetPushbutton && !((CPushButtonWidget*)pAnnot)->GetRespectBorder()) + dBorderSize = 0; + m_pStream->WriteReal(dBorderSize); m_pStream->WriteChar(' '); m_pStream->WriteReal(dBorderSize); m_pStream->WriteChar(' '); - m_pStream->WriteReal(std::max(dWidth - dBorderSize2, 0.0)); + m_pStream->WriteReal(std::max(dWidth - dBorderSize * 2, 0.0)); m_pStream->WriteChar(' '); - m_pStream->WriteReal(std::max(dHeight - dBorderSize2, 0.0)); + m_pStream->WriteReal(std::max(dHeight - dBorderSize * 2, 0.0)); m_pStream->WriteStr(" re\012W\012n\012"); + if (pAnnot && pAnnot->GetWidgetType() == WidgetListbox) + { + CChoiceWidget* pAnnot = dynamic_cast(m_pAnnot); + double dBaseLine = pAnnot->GetListBoxHeight(); + std::vector arrIndex = pAnnot->GetListBoxIndex(); + m_pStream->WriteStr("0.60 0.75 0.85 rg\012"); + for (int i = 0; i < arrIndex.size(); ++i) + { + double dH = dHeight - dBorderSize - dBaseLine * (double)(arrIndex[i] + 1); + if (dH < 0) + break; + m_pStream->WriteReal(dBorderSize); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(dH); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(std::max(dWidth - dBorderSize * 2.0, 0.0)); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(dBaseLine); + m_pStream->WriteStr(" re\012f\012"); + } + } + } + void CAnnotAppearanceObject::StartText(CFontDict* pFont, const double& dFontSize) + { + CWidgetAnnotation* pAnnot = dynamic_cast(m_pAnnot); + if (!m_pStream || !pAnnot) + return; + + m_dFontSize = std::min(1000.0, std::max(0.0, dFontSize)); + m_pFont = pFont; + m_bStart = true; + m_pStream->WriteStr("BT\012"); + if (pFont) + m_pStream->WriteStr(pAnnot->GetDAforAP(pFont).c_str()); + } + void CAnnotAppearanceObject::DrawPictureInline(const char* sImageName, const double& dX, const double& dY, const double& dW, const double& dH, const bool& bRespectBorder) + { + CWidgetAnnotation* pAnnot = dynamic_cast(m_pAnnot); + if (!m_pStream || !pAnnot || !sImageName) + return; - m_pStream->WriteReal(dR); + m_pStream->WriteStr("q\012"); + + if (bRespectBorder) + { + TRect oRect = pAnnot->GetRect(); + double dWidth = fabs(oRect.fRight - oRect.fLeft); + double dHeight = fabs(oRect.fBottom - oRect.fTop); + + double dBorderSize = pAnnot->GetBorderWidth(); + BYTE nType = pAnnot->GetBorderType(); + if (nType == 1 || nType == 3) + dBorderSize *= 2; + + m_pStream->WriteReal(2 * dBorderSize); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(2 * dBorderSize); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(fmax(dWidth - 4 * dBorderSize, 0.0)); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(fmax(dHeight - 4 * dBorderSize, 0.0)); + m_pStream->WriteStr(" re\012W\012n\012"); + } + + m_pStream->WriteReal(dW); + m_pStream->WriteStr(" 0 0 "); + m_pStream->WriteReal(dH); m_pStream->WriteChar(' '); - m_pStream->WriteReal(dG); + m_pStream->WriteReal(dX); m_pStream->WriteChar(' '); - m_pStream->WriteReal(dB); - m_pStream->WriteStr(" rg\012"); + m_pStream->WriteReal(dY); + m_pStream->WriteStr(" cm\012"); - if (sExtGStateName) + m_pStream->WriteEscapeName(sImageName); + m_pStream->WriteStr(" Do\012"); + + m_pStream->WriteStr("Q\012"); + } + void CAnnotAppearanceObject::EndText() + { + m_pStream->WriteStr("ET\012"); + } + void CAnnotAppearanceObject::EndDraw() + { + m_pStream->WriteStr("Q\012"); + } + void CAnnotAppearanceObject::DrawBackground(const double& dWidth, const double& dHeight) + { + CWidgetAnnotation* pAnnot = dynamic_cast(m_pAnnot); + if (!pAnnot || !pAnnot->HaveBG()) + return; + + m_pStream->WriteStr("q\012"); + m_pStream->WriteStr(pAnnot->GetBGforAP().c_str()); + m_pStream->WriteStr("\012"); + m_pStream->WriteStr("1 0 0 1 0 0 cm\012"); + m_pStream->WriteStr("0 0 "); + m_pStream->WriteReal(fmax(dWidth, 0.0)); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(fmax(dHeight, 0.0)); + m_pStream->WriteStr(" re\012f\012"); + m_pStream->WriteStr("Q\012"); + } + void CAnnotAppearanceObject::DrawBorder(const double& dWidth, const double& dHeight) + { + CWidgetAnnotation* pAnnot = dynamic_cast(m_pAnnot); + if (!pAnnot || !pAnnot->HaveBorder()) + return; + + m_pStream->WriteStr("q\012"); + + double dBorderSize = pAnnot->GetBorderWidth(); + BYTE nType = pAnnot->GetBorderType(); + + switch (nType) + { + case 1: // Beveled + case 3: // Inset { - m_pStream->WriteEscapeName(sExtGStateName); - m_pStream->WriteStr(" gs\012"); + m_pStream->WriteStr(nType == 1 ? "1 g\012" : "0.501953 g\012"); + + m_pStream->WriteReal(dBorderSize); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(dBorderSize); + m_pStream->WriteStr(" m\012"); + + m_pStream->WriteReal(dBorderSize); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(dHeight - dBorderSize); + m_pStream->WriteStr(" l\012"); + + m_pStream->WriteReal(dWidth - dBorderSize); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(dHeight - dBorderSize); + m_pStream->WriteStr(" l\012"); + + m_pStream->WriteReal(dWidth - 2 * dBorderSize); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(dHeight - 2 * dBorderSize); + m_pStream->WriteStr(" l\012"); + + m_pStream->WriteReal(2 * dBorderSize); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(dHeight - 2 * dBorderSize); + m_pStream->WriteStr(" l\012"); + + m_pStream->WriteReal(2 * dBorderSize); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(2 * dBorderSize); + m_pStream->WriteStr(" l\012"); + + m_pStream->WriteStr("f\012"); + + if (nType == 1 && pAnnot->HaveBG()) + { + m_pStream->WriteStr(pAnnot->GetBGforAP(-0.25).c_str()); + m_pStream->WriteStr("\012"); + } + else + m_pStream->WriteStr("0.75293 g\012"); + + m_pStream->WriteReal(dWidth - dBorderSize); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(dHeight - dBorderSize); + m_pStream->WriteStr(" m\012"); + + m_pStream->WriteReal(dWidth - dBorderSize); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(dBorderSize); + m_pStream->WriteStr(" l\012"); + + m_pStream->WriteReal(dBorderSize); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(dBorderSize); + m_pStream->WriteStr(" l\012"); + + m_pStream->WriteReal(2 * dBorderSize); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(2 * dBorderSize); + m_pStream->WriteStr(" l\012"); + + m_pStream->WriteReal(dWidth - 2 * dBorderSize); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(2 * dBorderSize); + m_pStream->WriteStr(" l\012"); + + m_pStream->WriteReal(dWidth - 2 * dBorderSize); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(dHeight - 2 * dBorderSize); + m_pStream->WriteStr(" l\012"); + + m_pStream->WriteStr("f\012"); + break; + } + case 2: // Dashed + { + m_pStream->WriteStr(pAnnot->GetBorderDash().c_str()); + break; + } + default: break; } - double _dFontSize = std::min(1000.0, std::max(0.0, dFontSize)); + m_pStream->WriteStr(pAnnot->GetBCforAP().c_str()); + m_pStream->WriteStr("\012"); + m_pStream->WriteReal(dBorderSize); + m_pStream->WriteStr(" w\0120 j\0120 J\012"); - m_pStream->WriteEscapeName(pResources->GetFontName(pFont)); - m_pStream->WriteChar(' '); - m_pStream->WriteReal(_dFontSize); - m_pStream->WriteStr(" Tf\012"); + if (nType == 4) // Underline + { + m_pStream->WriteInt(0); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(dBorderSize / 2); + m_pStream->WriteStr(" m\012"); - m_bStart = true; - m_pFont = pFont; - m_dFontSize = _dFontSize; + m_pStream->WriteReal(dWidth); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(dBorderSize / 2); + m_pStream->WriteStr(" l\012S\012"); + } + else + { + m_pStream->WriteReal(dBorderSize / 2); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(dBorderSize / 2); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(std::max(dWidth - dBorderSize, 0.0)); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(std::max(dHeight - dBorderSize, 0.0)); + m_pStream->WriteStr(" re\012S\012"); + } + + m_pStream->WriteStr("Q\012"); } void CAnnotAppearanceObject::DrawTextLine(const double& dX, const double& dY, const unsigned short* pCodes, const unsigned int& unCount, CFontCidTrueType** ppFonts, const double* pShifts) { - CResourcesDict* pResources = m_pField->GetResourcesDict(); + CResourcesDict* pResources = dynamic_cast(Get("Resources")); if (!pResources) return; @@ -1994,4 +2617,231 @@ namespace PdfWriter m_pStream->WriteStr("ET\012"); m_pStream->WriteStr("Q\012EMC\012"); } + void CAnnotAppearanceObject::AddBBox(double dX, double dY, double dW, double dH) + { + CArrayObject* pArray = new CArrayObject(); + Add("BBox", pArray); + pArray->Add(dX); + pArray->Add(dY); + pArray->Add(dW); + pArray->Add(dH); + } + void CAnnotAppearanceObject::AddMatrix(double sx, double shy, double shx, double sy, double tx, double ty) + { + CArrayObject* pArray = new CArrayObject(); + Add("Matrix", pArray); + pArray->Add(sx); + pArray->Add(shy); + pArray->Add(shx); + pArray->Add(sy); + pArray->Add(tx); + pArray->Add(ty); + } + void CAnnotAppearanceObject::DrawTextCommentN(const std::string& sColor) + { + CExtGrState* pExtGrState = m_pAnnot->GetDocument()->GetExtGState(0.6, 0.6); + const char* sExtGrStateName = m_pAnnot->GetDocument()->GetFieldsResources()->GetExtGrStateName(pExtGrState); + + m_pStream->WriteStr("q 1 1 1 rg 0 i 1 w 4 M 1 j 0 J [] 0 d "); + if (sExtGrStateName) + { + m_pStream->WriteEscapeName(sExtGrStateName); + m_pStream->WriteStr(" gs "); + } + m_pStream->WriteStr("1 0 0 1 9 5.0908 cm 7.74 12.616 m -7.74 12.616 l -8.274 12.616 -8.707 12.184 -8.707 11.649 c -8.707 -3.831 l -8.707 -4.365 -8.274 -4.798 -7.74 -4.798 c "); + m_pStream->WriteStr("7.74 -4.798 l 8.274 -4.798 8.707 -4.365 8.707 -3.831 c 8.707 11.649 l 8.707 12.184 8.274 12.616 7.74 12.616 c h f Q 0 G "); + m_pStream->WriteStr(sColor.c_str()); + m_pStream->WriteStr(" 0 i 0.60 w 4 M 1 j 0 J [0 100] 1 d 1 0 0 1 9 5.0908 cm 1 0 m -2.325 -2.81 l -2.325 0 l -5.72 0 l -5.72 8.94 l 5.51 8.94 l 5.51 0 l 1 0 l -3.50 5.01 m "); + m_pStream->WriteStr("-3.50 5.59 l 3.29 5.59 l 3.29 5.01 l -3.50 5.01 l -3.50 3.34 m -3.50 3.92 l 2.27 3.92 l 2.27 3.34 l -3.50 3.34 l 7.74 12.616 m -7.74 12.616 l "); + m_pStream->WriteStr("-8.274 12.616 -8.707 12.184 -8.707 11.649 c -8.707 -3.831 l -8.707 -4.365 -8.274 -4.798 -7.74 -4.798 c 7.74 -4.798 l "); + m_pStream->WriteStr("8.274 -4.798 8.707 -4.365 8.707 -3.831 c 8.707 11.649 l 8.707 12.184 8.274 12.616 7.74 12.616 c b"); + } + void CAnnotAppearanceObject::DrawTextCommentR(const std::string& sColor) + { + m_pStream->WriteStr("0 G "); + m_pStream->WriteStr(sColor.c_str()); + m_pStream->WriteStr(" 0 i 0.60 w 4 M 1 j 0 J [0 100] 1 d 1 0 0 1 9 5.0908 cm 4.1 1.71 m -0.54 -2.29 l -0.54 1.71 l -5.5 1.71 l -5.5 14.42 l 10.5 14.42 l 10.5 1.71 l 4.1 1.71 l "); + m_pStream->WriteStr("-2.33 9.66 m 7.34 9.66 l 7.34 8.83 l -2.33 8.83 l -2.33 9.66 l -2.33 7.28 m 5.88 7.28 l 5.88 6.46 l -2.33 6.46 l -2.33 7.28 l 14.9 23.1235 m -14.9 23.1235 l "); + m_pStream->WriteStr("-14.9 -20.345 l 14.9 -20.345 l 14.9 23.1235 l b"); + } + void CAnnotAppearanceObject::DrawTextCheck(const std::string& sColor) + { + m_pStream->WriteStr(sColor.c_str()); + m_pStream->WriteStr(" 0 G 0 i 0.59 w 4 M 1 j 0 J [] 0 d 1 0 0 1 7.1836 1.2061 cm 0 0 m 6.691 11.152 11.31 14.196 v 10.773 15.201 9.626 16.892 8.155 17.587 c "); + m_pStream->WriteStr("2.293 10.706 -0.255 4.205 y -4.525 9.177 l -6.883 5.608 l h b"); + } + void CAnnotAppearanceObject::DrawTextCheckmark() + { + m_pStream->WriteStr("q 0.396 0.396 0.396 rg 1 0 0 1 13.5151 16.5 cm 0 0 m -6.7 -10.23 l -8.81 -7 l -13.22 -7 l -6.29 -15 l 4.19 0 l h f Q"); + } + void CAnnotAppearanceObject::DrawTextCircle(const std::string& sColor) + { + CExtGrState* pExtGrState = m_pAnnot->GetDocument()->GetExtGState(0.6, 0.6); + const char* sExtGrStateName = m_pAnnot->GetDocument()->GetFieldsResources()->GetExtGrStateName(pExtGrState); + + m_pStream->WriteStr("q 1 1 1 rg 0 i 1 w 4 M 1 j 0 J [] 0 d "); + if (sExtGrStateName) + { + m_pStream->WriteEscapeName(sExtGrStateName); + m_pStream->WriteStr(" gs "); + } + m_pStream->WriteStr("1 0 0 1 9.999 3.6387 cm 0 0 m -3.513 0 -6.36 2.85 -6.36 6.363 c -6.36 9.875 -3.513 12.724 0 12.724 c 3.514 12.724 6.363 9.875 6.363 6.363 c "); + m_pStream->WriteStr("6.363 2.85 3.514 0 0 0 c h f Q "); + m_pStream->WriteStr(sColor.c_str()); + m_pStream->WriteStr(" 0 G 0 i 0.59 w 4 M 1 j 0 J [] 0 d 1 0 0 1 9.999 3.6387 cm 0 0 m -3.513 0 -6.36 2.85 -6.36 6.363 c -6.36 9.875 -3.513 12.724 0 12.724 c "); + m_pStream->WriteStr("3.514 12.724 6.363 9.875 6.363 6.363 c 6.363 2.85 3.514 0 0 0 c 0 16.119 m -5.388 16.119 -9.756 11.751 -9.756 6.363 c -9.756 0.973 -5.388 -3.395 0 -3.395 c "); + m_pStream->WriteStr("5.391 -3.395 9.757 0.973 9.757 6.363 c 9.757 11.751 5.391 16.119 0 16.119 c b"); + } + void CAnnotAppearanceObject::DrawTextCross(const std::string& sColor) + { + m_pStream->WriteStr(sColor.c_str()); + m_pStream->WriteStr(" 0 G 0 i 0.59 w 4 M 1 j 0 J [] 0 d 1 0 0 1 18.6924 3.1357 cm 0 0 m -6.363 6.364 l 0 12.728 l -2.828 15.556 l -9.192 9.192 l -15.556 15.556 l "); + m_pStream->WriteStr("-18.384 12.728 l -12.02 6.364 l -18.384 0 l -15.556 -2.828 l -9.192 3.535 l -2.828 -2.828 l h b"); + } + void CAnnotAppearanceObject::DrawTextCrossHairs(const std::string& sColor) + { + CExtGrState* pExtGrState = m_pAnnot->GetDocument()->GetExtGState(0.6, 0.6); + const char* sExtGrStateName = m_pAnnot->GetDocument()->GetFieldsResources()->GetExtGrStateName(pExtGrState); + + m_pStream->WriteStr("q 1 1 1 rg 0 i 1 w 4 M 1 j 0 J [] 0 d "); + if (sExtGrStateName) + { + m_pStream->WriteEscapeName(sExtGrStateName); + m_pStream->WriteStr(" gs "); + } + m_pStream->WriteStr("1 0 0 1 9.9771 1.9443 cm 0 0 m -4.448 0 -8.053 3.604 -8.053 8.053 c -8.053 12.5 -4.448 16.106 0 16.106 c 4.447 16.106 8.054 12.5 8.054 8.053 c "); + m_pStream->WriteStr("8.054 3.604 4.447 0 0 0 c h f Q "); + m_pStream->WriteStr(sColor.c_str()); + m_pStream->WriteStr(" 0 G 0 i 0.61 w 4 M 0 j 0 J [] 0 d q 1 0 0 1 9.9771 1.9443 cm 0 0 m -4.448 0 -8.053 3.604 -8.053 8.053 c -8.053 12.5 -4.448 16.106 0 16.106 c "); + m_pStream->WriteStr("4.447 16.106 8.054 12.5 8.054 8.053 c 8.054 3.604 4.447 0 0 0 c 0 17.716 m -5.336 17.716 -9.663 13.39 -9.663 8.053 c -9.663 2.716 -5.336 -1.61 0 -1.61 c "); + m_pStream->WriteStr("5.337 -1.61 9.664 2.716 9.664 8.053 c 9.664 13.39 5.337 17.716 0 17.716 c b Q q 1 0 0 1 10.7861 14.8325 cm 0 0 m -1.611 0 l -1.611 -4.027 l -5.638 -4.027 l "); + m_pStream->WriteStr("-5.638 -5.638 l -1.611 -5.638 l -1.611 -9.665 l 0 -9.665 l 0 -5.638 l 4.026 -5.638 l 4.026 -4.027 l 0 -4.027 l h b Q"); + } + void CAnnotAppearanceObject::DrawTextHelp(const std::string& sColor) + { + CExtGrState* pExtGrState = m_pAnnot->GetDocument()->GetExtGState(0.6, 0.6); + const char* sExtGrStateName = m_pAnnot->GetDocument()->GetFieldsResources()->GetExtGrStateName(pExtGrState); + + m_pStream->WriteStr("q 1 1 1 rg 0 i 1 w 4 M 1 j 0 J [] 0 d "); + if (sExtGrStateName) + { + m_pStream->WriteEscapeName(sExtGrStateName); + m_pStream->WriteStr(" gs "); + } + m_pStream->WriteStr("1 0 0 1 12.1465 10.5137 cm -2.146 9.403 m -7.589 9.403 -12.001 4.99 -12.001 -0.453 c -12.001 -5.895 -7.589 -10.309 -2.146 -10.309 c "); + m_pStream->WriteStr("3.296 -10.309 7.709 -5.895 7.709 -0.453 c 7.709 4.99 3.296 9.403 -2.146 9.403 c h f Q "); + m_pStream->WriteStr(sColor.c_str()); + m_pStream->WriteStr(" 0 G 0 i 0.59 w 4 M 1 j 0 J [] 0 d 1 0 0 1 12.1465 10.5137 cm 0 0 m -0.682 -0.756 -0.958 -1.472 -0.938 -2.302 c -0.938 -2.632 l -3.385 -2.632 l "); + m_pStream->WriteStr("-3.403 -2.154 l -3.459 -1.216 -3.147 -0.259 -2.316 0.716 c -1.729 1.433 -1.251 2.022 -1.251 2.647 c -1.251 3.291 -1.674 3.715 -2.594 3.751 c "); + m_pStream->WriteStr("-3.202 3.751 -3.937 3.531 -4.417 3.2 c -5.041 5.205 l -4.361 5.591 -3.274 5.959 -1.968 5.959 c 0.46 5.959 1.563 4.616 1.563 3.089 c "); + m_pStream->WriteStr("1.563 1.691 0.699 0.771 0 0 c -2.227 -6.863 m -2.245 -6.863 l -3.202 -6.863 -3.864 -6.146 -3.864 -5.189 c -3.864 -4.196 -3.182 -3.516 -2.227 -3.516 c "); + m_pStream->WriteStr("-1.233 -3.516 -0.589 -4.196 -0.57 -5.189 c -0.57 -6.146 -1.233 -6.863 -2.227 -6.863 c -2.146 9.403 m -7.589 9.403 -12.001 4.99 -12.001 -0.453 c "); + m_pStream->WriteStr("-12.001 -5.895 -7.589 -10.309 -2.146 -10.309 c 3.296 -10.309 7.709 -5.895 7.709 -0.453 c 7.709 4.99 3.296 9.403 -2.146 9.403 c b"); + } + void CAnnotAppearanceObject::DrawTextInsert(const std::string& sColor) + { + m_pStream->WriteStr("0 G "); + m_pStream->WriteStr(sColor.c_str()); + m_pStream->WriteStr(" 0 i 0.59 w 4 M 0 j 0 J [] 0 d 1 0 0 1 8.5386 19.8545 cm 0 0 m -8.39 -19.719 l 8.388 -19.719 l h B"); + } + void CAnnotAppearanceObject::DrawTextKey(const std::string& sColor) + { + CExtGrState* pExtGrState = m_pAnnot->GetDocument()->GetExtGState(0.6, 0.6); + const char* sExtGrStateName = m_pAnnot->GetDocument()->GetFieldsResources()->GetExtGrStateName(pExtGrState); + + m_pStream->WriteStr("q 1 1 1 rg 0 i 1 w 4 M 1 j 0 J [] 0 d "); + if (sExtGrStateName) + { + m_pStream->WriteEscapeName(sExtGrStateName); + m_pStream->WriteStr(" gs "); + } + m_pStream->WriteStr("1 0 0 1 6.5 12.6729 cm 0.001 5.138 m -2.543 5.138 -4.604 3.077 -4.604 0.534 c -4.604 -1.368 -3.449 -3.001 -1.802 -3.702 c "); + m_pStream->WriteStr("-1.802 -4.712 l -0.795 -5.719 l -1.896 -6.82 l -0.677 -8.039 l -1.595 -8.958 l -0.602 -9.949 l -1.479 -10.829 l -0.085 -12.483 l 1.728 -10.931 l "); + m_pStream->WriteStr("1.728 -3.732 l 1.737 -3.728 1.75 -3.724 1.76 -3.721 c 3.429 -3.03 4.604 -1.385 4.604 0.534 c 4.604 3.077 2.542 5.138 0.001 5.138 c f Q "); + m_pStream->WriteStr(sColor.c_str()); + m_pStream->WriteStr(" 0 G 0 i 0.59 w 4 M 1 j 0 J [] 0 d 1 0 0 1 6.5 12.6729 cm 0 0 m -1.076 0 -1.95 0.874 -1.95 1.95 c -1.95 3.028 -1.076 3.306 0 3.306 c "); + m_pStream->WriteStr("1.077 3.306 1.95 3.028 1.95 1.95 c 1.95 0.874 1.077 0 0 0 c 0.001 5.138 m -2.543 5.138 -4.604 3.077 -4.604 0.534 c -4.604 -1.368 -3.449 -3.001 -1.802 -3.702 c "); + m_pStream->WriteStr("-1.802 -4.712 l -0.795 -5.719 l -1.896 -6.82 l -0.677 -8.039 l -1.595 -8.958 l -0.602 -9.949 l -1.479 -10.829 l -0.085 -12.483 l 1.728 -10.931 l 1.728 -3.732 l "); + m_pStream->WriteStr("1.737 -3.728 1.75 -3.724 1.76 -3.721 c 3.429 -3.03 4.604 -1.385 4.604 0.534 c 4.604 3.077 2.542 5.138 0.001 5.138 c b"); + } + void CAnnotAppearanceObject::DrawTextNewParagraph(const std::string& sColor) + { + m_pStream->WriteStr(sColor.c_str()); + m_pStream->WriteStr(" 0 G 0 i 0.59 w 4 M 1 j 0 J [] 0 d q 1 0 0 1 6.4995 20 cm 0 0 m -6.205 -12.713 l 6.205 -12.713 l h b Q q 1 0 0 1 1.1909 6.2949 cm 0 0 m 1.278 0 l "); + m_pStream->WriteStr("1.353 0 1.362 -0.02 1.391 -0.066 c 2.128 -1.363 3.78 -4.275 3.966 -4.713 c 3.985 -4.713 l 3.976 -4.453 3.957 -3.91 3.957 -3.137 c 3.957 -0.076 l "); + m_pStream->WriteStr("3.957 -0.02 3.976 0 4.041 0 c 4.956 0 l 5.021 0 5.04 -0.029 5.04 -0.084 c 5.04 -6.049 l 5.04 -6.113 5.021 -6.133 4.947 -6.133 c 3.695 -6.133 l "); + m_pStream->WriteStr("3.621 -6.133 3.611 -6.113 3.574 -6.066 c 3.052 -4.955 1.353 -2.063 0.971 -1.186 c 0.961 -1.186 l 0.999 -1.68 0.999 -2.146 1.008 -3.025 c 1.008 -6.049 l "); + m_pStream->WriteStr("1.008 -6.104 0.989 -6.133 0.933 -6.133 c 0.009 -6.133 l -0.046 -6.133 -0.075 -6.123 -0.075 -6.049 c -0.075 -0.066 l -0.075 -0.02 -0.056 0 0 0 c f Q q "); + m_pStream->WriteStr("1 0 0 1 9.1367 3.0273 cm 0 0 m 0.075 0 0.215 -0.008 0.645 -0.008 c 1.4 -0.008 2.119 0.281 2.119 1.213 c 2.119 1.969 1.633 2.381 0.737 2.381 c "); + m_pStream->WriteStr("0.354 2.381 0.075 2.371 0 2.361 c h -1.146 3.201 m -1.146 3.238 -1.129 3.268 -1.082 3.268 c -0.709 3.275 0.02 3.285 0.729 3.285 c "); + m_pStream->WriteStr("2.613 3.285 3.248 2.314 3.258 1.232 c 3.258 -0.27 2.007 -0.914 0.607 -0.914 c 0.327 -0.914 0.057 -0.914 0 -0.904 c 0 -2.789 l "); + m_pStream->WriteStr("0 -2.836 -0.019 -2.865 -0.074 -2.865 c -1.082 -2.865 l -1.119 -2.865 -1.146 -2.846 -1.146 -2.799 c h f Q"); + } + void CAnnotAppearanceObject::DrawTextNote(const std::string& sColor) + { + m_pStream->WriteStr(sColor.c_str()); + m_pStream->WriteStr(" 0 G 0 i 0.61 w 4 M 0 j 0 J [] 0 d q 1 0 0 1 16.959 1.3672 cm 0 0 m 0 -0.434 -0.352 -0.785 -0.784 -0.785 c -14.911 -0.785 l "); + m_pStream->WriteStr("-15.345 -0.785 -15.696 -0.434 -15.696 0 c -15.696 17.266 l -15.696 17.699 -15.345 18.051 -14.911 18.051 c -0.784 18.051 l -0.352 18.051 0 17.699 0 17.266 c "); + m_pStream->WriteStr("h b Q q 1 0 0 1 4.4023 13.9243 cm 0 0 m 9.418 0 l S Q q 1 0 0 1 4.4019 11.2207 cm 0 0 m 9.418 0 l S Q q 1 0 0 1 4.4023 8.5176 cm 0 0 m 9.418 0 l S Q q "); + m_pStream->WriteStr("1 0 0 1 4.4023 5.8135 cm 0 0 m 9.418 0 l S Q"); + } + void CAnnotAppearanceObject::DrawTextParagraph(const std::string& sColor) + { + CExtGrState* pExtGrState = m_pAnnot->GetDocument()->GetExtGState(0.6, 0.6); + const char* sExtGrStateName = m_pAnnot->GetDocument()->GetFieldsResources()->GetExtGrStateName(pExtGrState); + + m_pStream->WriteStr("q 1 1 1 rg 0 i 1 w 4 M 1 j 0 J [] 0 d "); + if (sExtGrStateName) + { + m_pStream->WriteEscapeName(sExtGrStateName); + m_pStream->WriteStr(" gs "); + } + m_pStream->WriteStr("1 0 0 1 19.6973 10.0005 cm 0 0 m 0 -5.336 -4.326 -9.662 -9.663 -9.662 c -14.998 -9.662 -19.324 -5.336 -19.324 0 c -19.324 5.335 -14.998 9.662 -9.663 9.662 c "); + m_pStream->WriteStr("-4.326 9.662 0 5.335 0 0 c h f Q "); + m_pStream->WriteStr(sColor.c_str()); + m_pStream->WriteStr(" 0 G 0 i 0.59 w 4 M 1 j 0 J [] 0 d q 1 0 0 1 19.6973 10.0005 cm 0 0 m 0 -5.336 -4.326 -9.662 -9.663 -9.662 c -14.998 -9.662 -19.324 -5.336 -19.324 0 c "); + m_pStream->WriteStr("-19.324 5.335 -14.998 9.662 -9.663 9.662 c -4.326 9.662 0 5.335 0 0 c h S Q q 1 0 0 1 11.6787 2.6582 cm 0 0 m -1.141 0 l -1.227 0 -1.244 0.052 -1.227 0.139 c "); + m_pStream->WriteStr("-0.656 1.157 -0.52 2.505 -0.52 3.317 c -0.52 3.594 l -2.833 3.783 -5.441 4.838 -5.441 8.309 c -5.441 10.778 -3.714 12.626 -0.57 13.024 c "); + m_pStream->WriteStr("-0.535 13.508 -0.381 14.129 -0.242 14.389 c -0.207 14.44 -0.174 14.475 -0.104 14.475 c 1.088 14.475 l 1.156 14.475 1.191 14.458 1.175 14.372 c "); + m_pStream->WriteStr("1.105 14.095 0.881 13.127 0.881 12.402 c 0.881 9.431 0.932 7.324 0.95 4.06 c 0.95 2.298 0.708 0.813 0.189 0.07 c 0.155 0.034 0.103 0 0 0 c b Q"); + } + void CAnnotAppearanceObject::DrawTextRightArrow(const std::string& sColor) + { + CExtGrState* pExtGrState = m_pAnnot->GetDocument()->GetExtGState(0.6, 0.6); + const char* sExtGrStateName = m_pAnnot->GetDocument()->GetFieldsResources()->GetExtGrStateName(pExtGrState); + + m_pStream->WriteStr("q 1 1 1 rg 0 i 1 w 4 M 1 j 0 J [] 0 d "); + if (sExtGrStateName) + { + m_pStream->WriteEscapeName(sExtGrStateName); + m_pStream->WriteStr(" gs "); + } + m_pStream->WriteStr("1 0 0 1 3.7856 11.1963 cm 6.214 -10.655 m 11.438 -10.655 15.673 -6.42 15.673 -1.196 c 15.673 4.027 11.438 8.262 6.214 8.262 c "); + m_pStream->WriteStr("0.991 8.262 -3.244 4.027 -3.244 -1.196 c -3.244 -6.42 0.991 -10.655 6.214 -10.655 c h f Q "); + m_pStream->WriteStr(sColor.c_str()); + m_pStream->WriteStr(" 0 G 0 i 0.59 w 4 M 0 j 0 J [] 0 d 1 0 0 1 3.7856 11.1963 cm 0 0 m 8.554 0 l 6.045 2.51 l 7.236 3.702 l 12.135 -1.197 l 7.236 -6.096 l 6.088 -4.949 l "); + m_pStream->WriteStr("8.644 -2.394 l 0 -2.394 l h 6.214 -10.655 m 11.438 -10.655 15.673 -6.42 15.673 -1.196 c 15.673 4.027 11.438 8.262 6.214 8.262 c "); + m_pStream->WriteStr("0.991 8.262 -3.244 4.027 -3.244 -1.196 c -3.244 -6.42 0.991 -10.655 6.214 -10.655 c b"); + } + void CAnnotAppearanceObject::DrawTextRightPointer(const std::string& sColor) + { + m_pStream->WriteStr(sColor.c_str()); + m_pStream->WriteStr(" 0 G 0.59 w 4 M 0 j 0 J [] 0 d 1 0 0 1 1.1871 17.0000 cm 0 0 m 4.703 -8.703 l 0 -17 l 18.813 -8.703 l b"); + } + void CAnnotAppearanceObject::DrawTextStar(const std::string& sColor) + { + m_pStream->WriteStr(sColor.c_str()); + m_pStream->WriteStr(" 0 G 0 i 0.59 w 4 M 1 j 0 J [] 0 d 1 0 0 1 9.999 18.8838 cm 0 0 m 3.051 -6.178 l 9.867 -7.168 l 4.934 -11.978 l 6.099 -18.768 l 0 -15.562 l -6.097 -18.768 l "); + m_pStream->WriteStr("-4.933 -11.978 l -9.866 -7.168 l -3.048 -6.178 l b"); + } + void CAnnotAppearanceObject::DrawTextUpArrow(const std::string& sColor) + { + m_pStream->WriteStr(sColor.c_str()); + m_pStream->WriteStr(" 0 G 0 i 0.59 w 4 M 1 j 0 J [] 0 d 1 0 0 1 1.1007 6.7185 cm 0 0 m 4.009 0 l 4.009 -6.719 l 11.086 -6.719 l 11.086 0 l 14.963 0 l 7.499 13.081 l b"); + } + void CAnnotAppearanceObject::DrawTextUpLeftArrow(const std::string& sColor) + { + m_pStream->WriteStr(sColor.c_str()); + m_pStream->WriteStr(" 0 G 0 i 0.59 w 4 M 1 j 0 J [] 0 d 1 0 0 1 2.8335 1.7627 cm 0 0 m -2.74 15.16 l 12.345 12.389 l 9.458 9.493 l 14.027 4.91 l 7.532 -1.607 l 2.964 2.975 l b"); + } } diff --git a/PdfFile/SrcWriter/Field.h b/PdfFile/SrcWriter/Field.h index a3366d672aa..5c11b57be4b 100644 --- a/PdfFile/SrcWriter/Field.h +++ b/PdfFile/SrcWriter/Field.h @@ -34,7 +34,6 @@ #include "Objects.h" #include "Types.h" -#include "Annotation.h" #include "../../DesktopEditor/graphics/commands/FormField.h" namespace PdfWriter @@ -49,6 +48,71 @@ namespace PdfWriter class CImageDict; class CFontCidTrueType; class CSignatureDict; + class CAnnotation; + + enum EBorderSubtype + { + border_subtype_Solid, + border_subtype_Beveled, + border_subtype_Dashed, + border_subtype_Inset, + border_subtype_Underlined + }; + enum EAnnotType + { + AnnotUnknown = -1, + AnnotText = 0, + AnnotLink = 1, + AnnotSound = 2, + AnnotFreeText = 3, + AnnotStamp = 4, + AnnotSquare = 5, + AnnotCircle = 6, + AnnotStrikeOut = 7, + AnnotHighLight = 8, + AnnotUnderline = 9, + AnnotInk = 10, + AnnotFileAttachment = 11, + AnnotPopup = 12, + AnnotLine = 13, + AnnotSquiggly = 14, + AnnotPolygon = 15, + AnnotPolyLine = 16, + AnnotCaret = 17, + AnnotWidget = 18 + }; + enum EWidgetType + { + WidgetUnknown = 26, + WidgetPushbutton = 27, + WidgetRadiobutton = 28, + WidgetCheckbox = 29, + WidgetText = 30, + WidgetCombobox = 31, + WidgetListbox = 32, + WisgetSignature = 33 + }; + enum EAnnotHighlightMode + { + AnnotNoHighlight = 0, + AnnotInvertBox, + AnnotInvertBorder, + AnnotDownAppearance, + AnnotHighlightModeEOF + }; + enum EAnnotIcon + { + AnnotIconComment = 0, + AnnotIconKey = 1, + AnnotIconNote = 2, + AnnotIconHelp = 3, + AnnotIconNewParagraph = 4, + AnnotIconParagraph = 5, + AnnotIconInsert = 6, + + AnnotIconMin = 0, + AnnotIconMax = 6 + }; class CFieldBase : public CDictObject { @@ -101,7 +165,7 @@ namespace PdfWriter const TRgb& GetNormalColor(); const TRgb& GetPlaceHolderColor(); void SetFormat(const CFormFieldInfo::CTextFormFormat* pFormat); - + CFontDict* GetFont(); protected: @@ -130,6 +194,7 @@ namespace PdfWriter TRgb m_oPlaceHolderColor; CDictObject* m_pFocus; CDictObject* m_pBlur; + CFontDict* m_pFont; }; class CTextField : public CFieldBase @@ -277,11 +342,12 @@ namespace PdfWriter class CAnnotAppearance : public CDictObject { public: - CAnnotAppearance(CXref* pXRef, CFieldBase* pField); + CAnnotAppearance(CXref* pXRef, CFieldBase* pField); + CAnnotAppearance(CXref* pXRef, CAnnotation* pAnnot); - CAnnotAppearanceObject* GetNormal(); - CAnnotAppearanceObject* GetRollover(); - CAnnotAppearanceObject* GetDown(); + CAnnotAppearanceObject* GetNormal(CResourcesDict* pResources = NULL); + CAnnotAppearanceObject* GetRollover(CResourcesDict* pResources = NULL); + CAnnotAppearanceObject* GetDown(CResourcesDict* pResources = NULL); private: @@ -290,6 +356,7 @@ namespace PdfWriter CAnnotAppearanceObject* m_pRollover; CAnnotAppearanceObject* m_pDown; CFieldBase* m_pField; + CAnnotation* m_pAnnot; }; class CCheckBoxAnnotAppearance : public CDictObject @@ -315,24 +382,62 @@ namespace PdfWriter class CAnnotAppearanceObject : public CDictObject { public: - CAnnotAppearanceObject(CXref* pXRef, CFieldBase* pField); + CAnnotAppearanceObject(CXref* pXRef, CFieldBase* pField); + CAnnotAppearanceObject(CXref* pXRef, CAnnotation* pAnnot, CResourcesDict* pResources = NULL); void DrawSimpleText(const std::wstring& wsText, unsigned short* pCodes, unsigned int unCount, CFontDict* pFont, double dFontSize = 10.0, double dX = 0.0, double dY = 0.0, double dR = 0.0, double dG = 0.0, double dB = 0.0, const char* sExtGrStateName = NULL, double dW = 1.0, double dH = 1.0, CFontCidTrueType** ppFonts = NULL, double* pShifts = NULL); void DrawPicture(const char* sImageName = NULL, const double& dX = 0.0, const double& dY = 0.0, const double& dW = 0.0, const double& dH = 0.0, const bool& bRespectBorder = false); void StartDrawText(CFontDict* pFont, const double& dFontSize, const double& dR, const double& dG, const double& dB, const char* sExtGStateName, const double& dWidth, const double& dHeight); void DrawTextLine(const double& dX, const double& dY, const unsigned short* pCodes, const unsigned int& unCount, CFontCidTrueType** ppFonts, const double* pShifts); void DrawTextLine(const double &dX, const double &dY, const std::wstring& wsText); void EndDrawText(); + void AddBBox(double dX, double dY, double dW, double dH); + void AddMatrix(double sx, double shy, double shx, double sy, double tx, double ty); + + void StartDraw(const double& dWidth, const double& dHeight); + void StartText(CFontDict* pFont, const double& dFontSize); + void DrawPictureInline(const char* sImageName, const double& dX, const double& dY, const double& dW, const double& dH, const bool& bRespectBorder); + void EndText(); + void EndDraw(); + + void DrawTextCommentN(const std::string& sColor); + void DrawTextCommentR(const std::string& sColor); + void DrawTextCheck(const std::string& sColor); + void DrawTextCheckmark(); + void DrawTextCircle(const std::string& sColor); + void DrawTextCross(const std::string& sColor); + void DrawTextCrossHairs(const std::string& sColor); + void DrawTextHelp(const std::string& sColor); + void DrawTextInsert(const std::string& sColor); + void DrawTextKey(const std::string& sColor); + void DrawTextNewParagraph(const std::string& sColor); + void DrawTextNote(const std::string& sColor); + void DrawTextParagraph(const std::string& sColor); + void DrawTextRightArrow(const std::string& sColor); + void DrawTextRightPointer(const std::string& sColor); + void DrawTextStar(const std::string& sColor); + void DrawTextUpArrow(const std::string& sColor); + void DrawTextUpLeftArrow(const std::string& sColor); + + CStream* GetStream() const { return m_pStream; } + CFontDict* GetFont() { return m_pFont; } + + bool m_bStart; private: + void Init(CXref* pXref, CResourcesDict* pResources); + + void DrawBackground(const double& dWidth, const double& dHeight); + void DrawBorder(const double& dWidth, const double& dHeight); CXref* m_pXref; CStream* m_pStream; CFieldBase* m_pField; double m_dCurX; double m_dCurY; - bool m_bStart; CFontDict* m_pFont; double m_dFontSize; + + CAnnotation* m_pAnnot; }; } diff --git a/PdfFile/SrcWriter/Font.h b/PdfFile/SrcWriter/Font.h index 65abf3bd811..444880ad211 100644 --- a/PdfFile/SrcWriter/Font.h +++ b/PdfFile/SrcWriter/Font.h @@ -51,6 +51,10 @@ namespace PdfWriter { return fontUnknownType; } + virtual unsigned int GetWidth(unsigned short ushCode) + { + return 0; + } protected: diff --git a/PdfFile/SrcWriter/Font14.cpp b/PdfFile/SrcWriter/Font14.cpp index f305a42f409..3ae4b8cb091 100644 --- a/PdfFile/SrcWriter/Font14.cpp +++ b/PdfFile/SrcWriter/Font14.cpp @@ -30,6 +30,7 @@ * */ #include "Font14.h" +#include "Document.h" namespace PdfWriter { @@ -43,7 +44,7 @@ namespace PdfWriter "Courier-Bold", "Courier-Oblique", "Courier-BoldOblique", - "Times", + "Times-Roman", "Times-Bold", "Times-Oblique", "Times-BoldOblique", @@ -56,5 +57,46 @@ namespace PdfWriter Add("Type", "Font"); Add("Subtype", "Type1"); Add("BaseFont", c_sStandardFontNames[(int)eType]); + m_ushCodesCount = 0; } -} \ No newline at end of file + unsigned int CFont14::GetWidth(unsigned short ushCode) + { + std::map::const_iterator oIter = m_mUnicodeToCode.find(ushCode); + if (oIter == m_mUnicodeToCode.end()) + return 0; + ushCode = oIter->second; + if (ushCode >= m_vWidths.size()) + return 0; + + return m_vWidths.at(ushCode); + } + void CFont14::AddWidth(unsigned int nWidth) + { + m_vWidths.push_back(nWidth); + } + unsigned short CFont14::EncodeUnicode(const unsigned int& unGID, const unsigned int& unUnicode, bool& bNew) + { + std::map::const_iterator oIter = m_mUnicodeToCode.find(unUnicode); + if (oIter != m_mUnicodeToCode.end()) + return oIter->second; + + unsigned short ushCode = EncodeGID(unGID, bNew); + m_mUnicodeToCode.insert(std::pair(unUnicode, ushCode)); + return ushCode; + } + unsigned short CFont14::EncodeGID(const unsigned int& unGID, bool& bNew) + { + for (unsigned short ushCurCode = 0, ushCodesCount = m_vCodeToGid.size(); ushCurCode < ushCodesCount; ushCurCode++) + { + if (unGID == m_vCodeToGid.at(ushCurCode)) + return ushCurCode; + } + + unsigned short ushCode = m_ushCodesCount++; + + m_vCodeToGid.push_back(unGID); + bNew = true; + + return ushCode; + } +} diff --git a/PdfFile/SrcWriter/Font14.h b/PdfFile/SrcWriter/Font14.h index e7992520cee..89c4a0ee036 100644 --- a/PdfFile/SrcWriter/Font14.h +++ b/PdfFile/SrcWriter/Font14.h @@ -46,8 +46,18 @@ namespace PdfWriter { return fontType1; } + unsigned int GetWidth(unsigned short ushCode); + void AddWidth(unsigned int nWidth); + unsigned short EncodeUnicode(const unsigned int& unGID, const unsigned int& unUnicode, bool& bNew); + unsigned short EncodeGID(const unsigned int& unGID, bool& bNew); + + private: + unsigned short m_ushCodesCount; + std::map m_mUnicodeToCode; + std::vector m_vCodeToGid; + std::vector m_vWidths; }; } -#endif // _PDF_WRITER_SRC_FONT14_H \ No newline at end of file +#endif // _PDF_WRITER_SRC_FONT14_H diff --git a/PdfFile/SrcWriter/FontCidTT.cpp b/PdfFile/SrcWriter/FontCidTT.cpp index 062c2d6db5f..57bb4204948 100644 --- a/PdfFile/SrcWriter/FontCidTT.cpp +++ b/PdfFile/SrcWriter/FontCidTT.cpp @@ -171,7 +171,7 @@ namespace PdfWriter if (m_pXref->IsPDFA()) { - pFontDescriptor->Add("CIDSet", new CDictObject(m_pXref)); + //pFontDescriptor->Add("CIDSet", new CDictObject(m_pXref)); } } bool CFontCidTrueType::HaveChar(const unsigned int &unUnicode) @@ -357,10 +357,14 @@ namespace PdfWriter pS->WriteStr(c_sToUnicodeHeader); pS->WriteStr(c_sToUnicodeInfo); + int pCodesCount = pS->Tell(); + int nCodesCount = 0; pS->WriteInt(m_ushCodesCount); pS->WriteStr(" beginbfchar\n"); for (unsigned short ushCode = 0; ushCode < m_ushCodesCount; ushCode++) { + if (!m_mGlyphs[m_vCodeToGid[ushCode]]) + continue; pS->WriteChar('<'); pS->WriteHex(ushCode, 4); pS->WriteStr("> <"); @@ -384,9 +388,12 @@ namespace PdfWriter } pS->WriteStr(">\n"); + nCodesCount++; } pS->WriteStr("endbfchar\n"); - m_pToUnicodeStream->WriteStr(c_sToUnicodeFooter); + pS->WriteStr(c_sToUnicodeFooter); + pS->Seek(pCodesCount, SeekSet); + pS->WriteInt(nCodesCount); } void CFontCidTrueType::CloseFontFace() { @@ -470,7 +477,16 @@ namespace PdfWriter for (unsigned short ushCurCode = 0, ushCodesCount = m_vCodeToGid.size(); ushCurCode < ushCodesCount; ushCurCode++) { if (unGID == m_vCodeToGid.at(ushCurCode)) + { + if (m_vUnicodes.at(ushCurCode).empty() && unCount) + { + std::vector vUnicodes; + for (unsigned int i = 0; i < unCount; i++) + vUnicodes.push_back(pUnicodes[i]); + m_vUnicodes[ushCurCode] = vUnicodes; + } return ushCurCode; + } } if (!OpenFontFace()) @@ -492,6 +508,17 @@ namespace PdfWriter // Если данный символ составной (CompositeGlyf), тогда мы должны учесть все его дочерные символы (subglyfs) if (0 == FT_Load_Glyph(m_pFace, unGID, FT_LOAD_NO_SCALE | FT_LOAD_NO_RECURSE)) { + if (0 != m_pFace->units_per_EM) + { + m_vWidths.push_back((unsigned int)m_pFace->glyph->metrics.horiAdvance * 1000 / m_pFace->units_per_EM); + m_vGlypWidths.push_back((unsigned int)(m_pFace->glyph->metrics.width) * 1000 / m_pFace->units_per_EM); + } + else + { + m_vWidths.push_back((unsigned int)m_pFace->glyph->metrics.horiAdvance); + m_vGlypWidths.push_back((unsigned int)(m_pFace->glyph->metrics.width) * 1000 / m_pFace->units_per_EM); + } + for (int nSubIndex = 0; nSubIndex < m_pFace->glyph->num_subglyphs; nSubIndex++) { FT_Int nSubGID; @@ -501,18 +528,10 @@ namespace PdfWriter FT_Matrix oMatrix; FT_Get_SubGlyph_Info(m_pFace->glyph, nSubIndex, &nSubGID, &unFlags, &nArg1, &nArg2, &oMatrix); - m_mGlyphs.insert(std::pair(nSubGID, true)); - } + m_mGlyphs.insert(std::pair(nSubGID, false)); - if (0 != m_pFace->units_per_EM) - { - m_vWidths.push_back((unsigned int)m_pFace->glyph->metrics.horiAdvance * 1000 / m_pFace->units_per_EM); - m_vGlypWidths.push_back((unsigned int)(m_pFace->glyph->metrics.width) * 1000 / m_pFace->units_per_EM); - } - else - { - m_vWidths.push_back((unsigned int)m_pFace->glyph->metrics.horiAdvance); - m_vGlypWidths.push_back((unsigned int)(m_pFace->glyph->metrics.width) * 1000 / m_pFace->units_per_EM); + EncodeGID(nSubGID, NULL, 0); // TODO необходимо верно указать Unicode для случая записи подсимволов + FT_Load_Glyph(m_pFace, unGID, FT_LOAD_NO_SCALE | FT_LOAD_NO_RECURSE); } } else diff --git a/PdfFile/SrcWriter/FontTT.cpp b/PdfFile/SrcWriter/FontTT.cpp index 0a6fe34faaa..21419e9543b 100644 --- a/PdfFile/SrcWriter/FontTT.cpp +++ b/PdfFile/SrcWriter/FontTT.cpp @@ -177,6 +177,13 @@ namespace PdfWriter m_nLineHeight = yMax - yMin; m_nAscent = yMax; + m_dHeight = pFace->height; + m_dDescent = pFace->descender; + m_dAscent = pFace->ascender; + m_dUnitsPerEm = pFace->units_per_EM; + m_dMaxY = pFace->bbox.yMax; + m_dMinY = pFace->bbox.yMin; + CArrayObject* pBBox = new CArrayObject(); pBBox->Add(xMin); pBBox->Add(yMin); diff --git a/PdfFile/SrcWriter/FontTT.h b/PdfFile/SrcWriter/FontTT.h index 17064ed61ad..37483c45710 100644 --- a/PdfFile/SrcWriter/FontTT.h +++ b/PdfFile/SrcWriter/FontTT.h @@ -58,7 +58,6 @@ namespace PdfWriter CFontTrueType(CXref* pXref, CDocument* pDocument, const std::wstring& wsFontPath, unsigned int unIndex); ~CFontTrueType(); - unsigned int GetWidth(unsigned short ushCode); int GetLineHeight() const { return m_nLineHeight; @@ -72,6 +71,13 @@ namespace PdfWriter return fontTrueType; } + double m_dUnitsPerEm; + double m_dHeight; + double m_dDescent; + double m_dAscent; + double m_dMaxY; + double m_dMinY; + private: void BeforeWrite(); diff --git a/PdfFile/SrcWriter/FontTTWriter.cpp b/PdfFile/SrcWriter/FontTTWriter.cpp index a21f0a337f2..2f5c21cb25a 100644 --- a/PdfFile/SrcWriter/FontTTWriter.cpp +++ b/PdfFile/SrcWriter/FontTTWriter.cpp @@ -321,7 +321,6 @@ namespace PdfWriter 0, 0, // idDelta[0] 0, 0 // pad to a mulitple of four bytes }; - static char arrNameTab[8] = { 0, 0, // format @@ -623,11 +622,11 @@ namespace PdfWriter arrNewCmapTable[0] = 0; // table version number = 0 arrNewCmapTable[1] = 0; // arrNewCmapTable[2] = 0; // number of encoding tables = 1 - arrNewCmapTable[3] = 1; // + arrNewCmapTable[3] = 1; // arrNewCmapTable[4] = 0; // platform ID = 1 (MacOS) // Эти два поля обязательно должны arrNewCmapTable[5] = 1; // // иметь таки значения, иначе, Adobe arrNewCmapTable[6] = 0; // encoding ID = 0 // Acrobat может открыть данный шрифт. - arrNewCmapTable[7] = 0; // // + arrNewCmapTable[7] = 0; // arrNewCmapTable[8] = 0; // offset of subtable arrNewCmapTable[9] = 0; // arrNewCmapTable[10] = 0; // diff --git a/PdfFile/SrcWriter/Image.cpp b/PdfFile/SrcWriter/Image.cpp index 3d4e98b5965..3da811029c3 100644 --- a/PdfFile/SrcWriter/Image.cpp +++ b/PdfFile/SrcWriter/Image.cpp @@ -53,8 +53,8 @@ namespace NSImageReSaver return; int nSize = oFile.GetFileSize(); - if (nSize > 1000) - nSize = 1000; + if (nSize > 10000) + nSize = 10000; BYTE* data = new BYTE[nSize]; DWORD dwRead = 0; @@ -68,27 +68,32 @@ namespace NSImageReSaver oFile.CloseFile(); RELEASEARRAYOBJECTS(data); - if (std::string::npos == sFind.find("Photoshop") && std::string::npos == sFind.find("photoshop")) - return; - - CBgraFrame oFrame; - if (!oFrame.OpenFile(wsFileName)) - return; + if (std::string::npos != sFind.find("Adobe") || std::string::npos != sFind.find("Photoshop") || std::string::npos != sFind.find("photoshop")) + { + CBgraFrame oFrame; + if (!oFrame.OpenFile(wsFileName)) + return; - oFrame.SetJpegQuality(85.0); - if (!oFrame.Encode(pBuffer, nBufferSize, _CXIMAGE_FORMAT_JPG)) - return; + oFrame.SetJpegQuality(85.0); + if (!oFrame.Encode(pBuffer, nBufferSize, _CXIMAGE_FORMAT_JPG)) + return; - if (!pBuffer || !nBufferSize) - return; + if (!pBuffer || !nBufferSize) + return; - unWidth = (unsigned int)oFrame.get_Width(); - unHeight = (unsigned int)oFrame.get_Height(); + unWidth = (unsigned int)oFrame.get_Width(); + unHeight = (unsigned int)oFrame.get_Height(); + } } } namespace PdfWriter { + CXObject::CXObject() + { + m_dOriginW = 0; + m_dOriginH = 0; + } //---------------------------------------------------------------------------------------- // CImageDict //---------------------------------------------------------------------------------------- @@ -284,9 +289,6 @@ namespace PdfWriter } void CImageDict::LoadSMask(const BYTE* pBgra, unsigned int unWidth, unsigned int unHeight, unsigned char unAlpha, bool bVerFlip) { - if (m_pDocument->IsPDFA()) - return; - CMemoryStream* pStream = new CMemoryStream(unWidth * unHeight); if (!pStream) return; diff --git a/PdfFile/SrcWriter/Image.h b/PdfFile/SrcWriter/Image.h index cdd67e70cef..2c5d00e46d9 100644 --- a/PdfFile/SrcWriter/Image.h +++ b/PdfFile/SrcWriter/Image.h @@ -41,11 +41,23 @@ namespace PdfWriter class CMemoryStream; class CXObject : public CDictObject { + private: + double m_dOriginW; + double m_dOriginH; + std::string m_sName; public: + CXObject(); EDictType GetDictType() const { return dict_type_XOBJECT; } + void SetWidth (double dW) { m_dOriginW = dW; } + void SetHeight(double dH) { m_dOriginH = dH; } + void SetName(const std::string& sName) { m_sName = sName; } + + double GetWidth() { return m_dOriginW; } + double GetHeight() { return m_dOriginH; } + const std::string& GetName() { return m_sName; } }; //---------------------------------------------------------------------------------------- // CImageDict diff --git a/PdfFile/SrcWriter/Metadata.cpp b/PdfFile/SrcWriter/Metadata.cpp index 97e2a61ca87..ad4211b8098 100644 --- a/PdfFile/SrcWriter/Metadata.cpp +++ b/PdfFile/SrcWriter/Metadata.cpp @@ -32,6 +32,7 @@ #include "Metadata.h" #include "Streams.h" #include "Info.h" +#include "Utils.h" #include "../../DesktopEditor/common/SystemUtils.h" #include "../../OOXML/Base/Base.h" @@ -154,7 +155,7 @@ namespace PdfWriter if (pXref->IsPDFA()) { sXML += "\n"; - sXML += "1A\n"; + sXML += "2A\n"; sXML += ""; } @@ -163,5 +164,90 @@ namespace PdfWriter m_pStream->WriteStr(sXML.c_str()); } + //---------------------------------------------------------------------------------------- + // StreamData + //---------------------------------------------------------------------------------------- + CStreamData::CStreamData(CXref* pXref) + { + pXref->Add(this); + + m_pStream = new CMemoryStream(); + Add("Length", 1234567890); + Add("Type", "MetaOForm"); + SetStream(pXref, m_pStream); + + m_nLengthBegin = 0; + m_nLengthEnd = 0; + } + void CStreamData::SetID(CBinaryObject* pID) + { + if (!pID) + return; + Add("ID", pID); + } + bool CStreamData::AddMetaData(const std::wstring& sMetaName, BYTE* pMetaData, DWORD nMetaLength) + { + if (sMetaName == L"Length") + return false; + + CArrayObject* pArr = new CArrayObject(); + if (!pArr) + return false; + + std::string sKey = U_TO_UTF8(sMetaName); + Add(sKey, pArr); + + int nCur = m_pStream->Tell(); + pArr->Add(nCur); + pArr->Add((int)nMetaLength); + m_pStream->Write(pMetaData, nMetaLength); + + return true; + } + void CStreamData::WriteToStream(CStream* pStream, CEncrypt* pEncrypt) + { + for (auto const &oIter : m_mList) + { + CObjectBase* pObject = oIter.second; + if (!pObject) + continue; + + if (!pObject->IsHidden()) + { + int nBegin, nEnd; + pStream->WriteEscapeName(oIter.first.c_str()); + pStream->WriteChar(' '); + nBegin = pStream->Tell(); + pStream->Write(pObject, NULL); + nEnd = pStream->Tell(); + pStream->WriteStr("\012"); + if (oIter.first == "Length") + { + m_nLengthBegin = nBegin; + m_nLengthEnd = nEnd; + } + } + } + } + void CStreamData::AfterWrite(CStream* pStream) + { + int nCurrent = pStream->Tell(); + + pStream->Seek(m_nLengthBegin, EWhenceMode::SeekSet); + pStream->Write(Get("Length"), NULL); + + int nEnd = pStream->Tell(); + if (nEnd < m_nLengthEnd) + { + unsigned int nLength = m_nLengthEnd - nEnd; + BYTE* pDifference = new BYTE[nLength]; + MemSet(pDifference, ' ', nLength); + pStream->Write(pDifference, nLength); + + RELEASEARRAYOBJECTS(pDifference); + } + + pStream->Seek(nCurrent, EWhenceMode::SeekSet); + } } diff --git a/PdfFile/SrcWriter/Metadata.h b/PdfFile/SrcWriter/Metadata.h index f55bdd45eb7..ea3673035d4 100644 --- a/PdfFile/SrcWriter/Metadata.h +++ b/PdfFile/SrcWriter/Metadata.h @@ -52,6 +52,27 @@ namespace PdfWriter CMemoryStream* m_pStream; }; + + class CStreamData : public CDictObject + { + public: + CStreamData(CXref* pXref); + EDictType GetDictType() const override + { + return dict_type_STREAM; + } + + void SetID(CBinaryObject* pID); + bool AddMetaData(const std::wstring& sMetaName, BYTE* pMetaData, DWORD nMetaLength); + void WriteToStream(CStream* pStream, CEncrypt* pEncrypt) override; + void AfterWrite(CStream* pStream) override; + + private: + CMemoryStream* m_pStream; + + int m_nLengthBegin; + int m_nLengthEnd; + }; } #endif // _PDF_WRITER_SRC_METADATA_H diff --git a/PdfFile/SrcWriter/Objects.cpp b/PdfFile/SrcWriter/Objects.cpp index 6ce4dd07171..1522834b98f 100644 --- a/PdfFile/SrcWriter/Objects.cpp +++ b/PdfFile/SrcWriter/Objects.cpp @@ -651,36 +651,11 @@ namespace PdfWriter } } } - void CDictObject::WriteSignatureToStream(CStream* pStream, CEncrypt* pEncrypt) + void CDictObject::SetStream(CStream* pStream) { - for (auto const &oIter : m_mList) - { - CObjectBase* pObject = oIter.second; - if (!pObject) - continue; - - if (pObject->IsHidden()) - { - // ничего не делаем - } - else - { - int nBegin, nEnd; - pStream->WriteEscapeName(oIter.first.c_str()); - pStream->WriteChar(' '); - nBegin = pStream->Tell(); - // Цифровая подпись не шифруется - pStream->Write(pObject, oIter.first == "Contents" ? NULL : pEncrypt); - nEnd = pStream->Tell(); - pStream->WriteStr("\012"); - if (oIter.first == "Contents") - ((CSignatureDict*)this)->SetByteRange(nBegin, nEnd); - if (oIter.first == "ByteRange") - ((CSignatureDict*)this)->ByteRangeOffset(nBegin, nEnd); - } - } + m_pStream = pStream; } - void CDictObject::SetStream(CXref* pXref, CStream* pStream) + void CDictObject::SetStream(CXref* pXref, CStream* pStream, bool bThis) { if (m_pStream) delete m_pStream; @@ -690,7 +665,8 @@ namespace PdfWriter CNumberObject* pLength = new CNumberObject(0); // Только stream object добавляются в таблицу xref автоматически - pXref->Add((CObjectBase*)this); + if (bThis) + pXref->Add((CObjectBase*)this); pXref->Add((CObjectBase*)pLength); Add("Length", (CObjectBase*)pLength); @@ -881,7 +857,7 @@ namespace PdfWriter unsigned int unMaxObjId = m_pPrev ? pPrev->m_arrEntries.size() + pPrev->m_unStartOffset : m_arrEntries.size() + m_unStartOffset; m_pTrailer->Add("Size", unMaxObjId); - if (m_pPrev) + if (m_pPrev && pPrev->m_unAddr) m_pTrailer->Add("Prev", pPrev->m_unAddr); pStream->WriteStr("trailer\012"); @@ -945,12 +921,12 @@ namespace PdfWriter CDictObject* pTrailer = m_pTrailer; pTrailer->Add("Type", "XRef"); pTrailer->Add("Size", unMaxObjId + 1); - if (m_pPrev) + if (m_pPrev && pPrev->m_unAddr) pTrailer->Add("Prev", pPrev->m_unAddr); CArrayObject* pW = new CArrayObject(); pTrailer->Add("W", pW); pW->Add(1); - pW->Add(3); + pW->Add(4); pW->Add(2); CArrayObject* pIndex = new CArrayObject(); pTrailer->Add("Index", pIndex); @@ -1010,6 +986,7 @@ namespace PdfWriter pTrailerStream->WriteChar('\000'); else if (pEntry->nEntryType == IN_USE_ENTRY) pTrailerStream->WriteChar('\001'); + pTrailerStream->WriteChar((unsigned char)(pEntry->unByteOffset >> 24)); pTrailerStream->WriteChar((unsigned char)(pEntry->unByteOffset >> 16)); pTrailerStream->WriteChar((unsigned char)(pEntry->unByteOffset >> 8)); pTrailerStream->WriteChar((unsigned char)(pEntry->unByteOffset)); @@ -1024,6 +1001,7 @@ namespace PdfWriter pIndex->Add(unEntries); pIndex->Add(unEntriesSize); pTrailerStream->WriteChar('\001'); + pTrailerStream->WriteChar((unsigned char)(nStreamOffset >> 24)); pTrailerStream->WriteChar((unsigned char)(nStreamOffset >> 16)); pTrailerStream->WriteChar((unsigned char)(nStreamOffset >> 8)); pTrailerStream->WriteChar((unsigned char)(nStreamOffset)); diff --git a/PdfFile/SrcWriter/Objects.h b/PdfFile/SrcWriter/Objects.h index b4a806e9043..cac33259bc8 100644 --- a/PdfFile/SrcWriter/Objects.h +++ b/PdfFile/SrcWriter/Objects.h @@ -80,7 +80,8 @@ namespace PdfWriter dict_type_EXT_GSTATE = 0x0A, dict_type_EXT_GSTATE_R = 0x0B, /* read only object */ dict_type_METADATA = 0x0C, - dict_type_SIGNATURE = 0x0D + dict_type_SIGNATURE = 0x0D, + dict_type_STREAM = 0x0E } EDictType; class CObjectBase @@ -451,10 +452,11 @@ namespace PdfWriter void Add(const std::string& sKey, double dReal); void Add(const std::string& sKey, bool bBool); const char* GetKey(const CObjectBase* pObject); - CStream* GetStream() const + virtual CStream* GetStream() const { return m_pStream; } + virtual void SetStream(CStream* pStream); unsigned int GetFilter() const { return m_unFilter; @@ -467,25 +469,25 @@ namespace PdfWriter { m_unFilter = unFiler; } - void SetStream(CXref* pXref, CStream* pStream); + void SetStream(CXref* pXref, CStream* pStream, bool bThis = true); virtual void BeforeWrite(){} virtual void Write(CStream* pStream){} - virtual void AfterWrite(){} + virtual void AfterWrite(CStream* pStream){} virtual CObjectBase* Copy(CObjectBase* pOut = NULL) const; virtual EDictType GetDictType() const { return dict_type_UNKNOWN; } - void WriteToStream(CStream* pStream, CEncrypt* pEncrypt); - void WriteSignatureToStream(CStream* pStream, CEncrypt* pEncrypt); + virtual void WriteToStream(CStream* pStream, CEncrypt* pEncrypt); unsigned int GetSize() { return m_mList.size(); } void FromXml(const std::wstring& sXml); - private: - + protected: std::map m_mList; + + private: unsigned int m_unFilter; unsigned int m_unPredictor; CStream* m_pStream; diff --git a/PdfFile/SrcWriter/Outline.cpp b/PdfFile/SrcWriter/Outline.cpp index 80e4f8a380b..77c30c8102a 100644 --- a/PdfFile/SrcWriter/Outline.cpp +++ b/PdfFile/SrcWriter/Outline.cpp @@ -48,7 +48,7 @@ namespace PdfWriter pOpenFlag->SetHidden(); Add("_OPENED", pOpenFlag); - Add("Type", "Outline"); + Add("Type", "Outlines"); } COutline::COutline(COutline* pParent, const char* sTitle, CXref* pXref) { @@ -57,7 +57,7 @@ namespace PdfWriter pXref->Add(this); - CStringObject* pString = new CStringObject(sTitle); + CStringObject* pString = new CStringObject(sTitle, true); if (!pString) return; @@ -172,4 +172,4 @@ namespace PdfWriter else pNumber->Set(bOpened ? OUTLINE_OPENED : OUTLINE_CLOSED); } -} \ No newline at end of file +} diff --git a/PdfFile/SrcWriter/Pages.cpp b/PdfFile/SrcWriter/Pages.cpp index 9654560dc10..8212a8f9842 100644 --- a/PdfFile/SrcWriter/Pages.cpp +++ b/PdfFile/SrcWriter/Pages.cpp @@ -41,6 +41,7 @@ #include "Pattern.h" #include "Document.h" #include "Field.h" +#include "ResourcesDictionary.h" #ifdef DrawText #undef DrawText @@ -218,6 +219,10 @@ namespace PdfWriter m_pCount = new CNumberObject(0); Add("Count", m_pCount); } + + CResourcesDict* pResources = (CResourcesDict*)Get("Resources"); + if (pResources) + pResources->Fix(); } void CPageTree::AddPage(CDictObject* pPage) { @@ -256,6 +261,16 @@ namespace PdfWriter return true; return false; } + bool CPageTree::ReplacePage(int nPageIndex, CPage* pPage) + { + if (nPageIndex >= m_pCount->Get()) + return false; + int nI = 0; + CObjectBase* pObj = GetFromPageTree(nPageIndex, nI, true, true, pPage); + if (pObj) + return true; + return false; + } CObjectBase* CPageTree::GetFromPageTree(int nPageIndex, int& nI, bool bRemove, bool bInsert, CPage* pPage) { for (int i = 0, count = m_pPages->GetCount(); i < count; ++i) @@ -269,9 +284,14 @@ namespace PdfWriter if (nPageIndex == nI) { pRes = pObj; - if (bRemove) + if (bRemove && bInsert) + { + m_pPages->Insert(pObj, pPage, true); + pPage->Add("Parent", this); + } + else if (bRemove) pRes = m_pPages->Remove(i); - if (bInsert) + else if (bInsert) { m_pPages->Insert(pObj, pPage); pPage->Add("Parent", this); @@ -310,9 +330,16 @@ namespace PdfWriter //---------------------------------------------------------------------------------------- // CPage //---------------------------------------------------------------------------------------- - CPage::CPage(CDocument* pDocument) + CPage::CPage(CDocument* pDocument, CXref* pXref) { Init(pDocument); + if (pXref) + { + AddResource(pXref); + m_pContents = new CArrayObject(); + Add("Contents", m_pContents); + AddContents(pXref); + } } void CPage::Fix() { @@ -377,32 +404,10 @@ namespace PdfWriter if (pRotate && pRotate->GetType() == object_type_NUMBER) Add("Rotate", ((CNumberObject*)pRotate)->Get() % 360); - CDictObject* pResources = GetResourcesItem(); + CResourcesDict* pResources = GetResourcesItem(); if (pResources) { - // Инициализация текущего fonts - CObjectBase* pFonts = pResources->Get("Font"); - if (pFonts && pFonts->GetType() == object_type_DICT) - { - m_pFonts = (CDictObject*)pFonts; - m_unFontsCount = 0; - } - - // Инициализация текущего ExtGStates - CObjectBase* pExtGStates = pResources->Get("ExtGState"); - if (pExtGStates && pExtGStates->GetType() == object_type_DICT) - { - m_pExtGStates = (CDictObject*)pExtGStates; - m_unExtGStatesCount = m_pExtGStates->GetSize(); - } - - // Инициализация текущего XObject - CObjectBase* pXObject = pResources->Get("XObject"); - if (pXObject && pXObject->GetType() == object_type_DICT) - { - m_pXObjects = (CDictObject*)pXObject; - m_unXObjectsCount = m_pXObjects->GetSize(); - } + pResources->Fix(); // Инициализация текущего Shading CObjectBase* pShading = pResources->Get("Shading"); @@ -420,8 +425,6 @@ namespace PdfWriter m_unPatternsCount = m_pPatterns->GetSize(); } } - else - Add("Resources", new CDictObject()); m_pStream = NULL; } @@ -457,13 +460,7 @@ namespace PdfWriter m_eGrMode = grmode_PAGE; m_pGrState = new CGrState(NULL); - m_pExtGStates = NULL; - m_unExtGStatesCount = 0; - m_pFonts = NULL; m_pFont = NULL; - m_unFontsCount = 0; - m_pXObjects = NULL; - m_unXObjectsCount = 0; m_pShadings = NULL; m_unShadingsCount = 0; m_pPatterns = NULL; @@ -534,7 +531,7 @@ namespace PdfWriter { return (CArrayObject*)Get("MediaBox"); } - CDictObject* CPage::GetResourcesItem() + CResourcesDict* CPage::GetResourcesItem() { CObjectBase* pObject = Get("Resources"); @@ -547,7 +544,7 @@ namespace PdfWriter pPageTree = (CPageTree*)pObj; while (pPageTree) { - pObject = Get("Resources"); + pObject = pPageTree->Get("Resources"); if (pObject) break; @@ -556,7 +553,7 @@ namespace PdfWriter } } - return (CDictObject*)pObject; + return (CResourcesDict*)pObject; } CObjectBase* CPage::GetCropBoxItem() { @@ -566,27 +563,13 @@ namespace PdfWriter { return Get("Rotate"); } - void CPage::AddResource() + void CPage::AddResource(CXref* pXref) { - // TODO: Переделать на ResourcesDict - CDictObject* pResource = new CDictObject(); + CResourcesDict* pResource = new CResourcesDict(pXref, !pXref, true); if (!pResource) return; - - // Не смотря на то, что ProcSet - устаревший объект, добавляем - // его для совместимости + Add("Resources", pResource); - - CArrayObject* pProcset = new CArrayObject(); - if (!pProcset) - return; - - pResource->Add("ProcSet", pProcset); - pProcset->Add(new CNameObject("PDF")); - pProcset->Add(new CNameObject("Text")); - pProcset->Add(new CNameObject("ImageB")); - pProcset->Add(new CNameObject("ImageC")); - pProcset->Add(new CNameObject("ImageI")); } void CPage::BeforeWrite() { @@ -1043,6 +1026,15 @@ namespace PdfWriter m_pGrState->m_oMatrix.x = dX * oCTM.m11 + dY * oCTM.m21 + oCTM.x; m_pGrState->m_oMatrix.y = dX * oCTM.m12 + dY * oCTM.m22 + oCTM.y; } + void CPage::StartTransform(double dM11, double dM12, double dM21, double dM22, double dX, double dY) + { + m_pGrState->m_oMatrix.m11 = dM11; + m_pGrState->m_oMatrix.m12 = dM12; + m_pGrState->m_oMatrix.m21 = dM21; + m_pGrState->m_oMatrix.m22 = dM22; + m_pGrState->m_oMatrix.x = dX; + m_pGrState->m_oMatrix.y = dY; + } void CPage::SetTransform(double dM11, double dM12, double dM21, double dM22, double dX, double dY) { CMatrix oInverse = m_pGrState->m_oMatrix.Inverse(); @@ -1082,46 +1074,17 @@ namespace PdfWriter // Operator : gs // Description: устанавливаем сразу все настройки данного графического состояния(ExtGState) - const char* sGsName = GetExtGrStateName(pState); + CResourcesDict* pResources = GetResourcesItem(); + if (!pResources) + return; + + const char* sGsName = pResources->GetExtGrStateName(pState); if (!sGsName) return; m_pStream->WriteEscapeName(sGsName); m_pStream->WriteStr(" gs\012"); } - const char* CPage::GetExtGrStateName(CExtGrState* pState) - { - const char *sKey; - - if (!m_pExtGStates) - { - CDictObject* pResources = (CDictObject*)GetResourcesItem(); - if (!pResources) - return NULL; - - m_pExtGStates = new CDictObject(); - if (!m_pExtGStates) - return NULL; - - pResources->Add("ExtGState", m_pExtGStates); - } - - sKey = m_pExtGStates->GetKey(pState); - if (!sKey) - { - // Если ExtGState не зарегистрирован в Resource, регистрируем. - char sExtGrStateName[LIMIT_MAX_NAME_LEN + 1]; - char *pPointer; - char *pEndPointer = sExtGrStateName + LIMIT_MAX_NAME_LEN; - - pPointer = (char*)StrCpy(sExtGrStateName, "E", pEndPointer); - ItoA(pPointer, ++m_unExtGStatesCount, pEndPointer); - m_pExtGStates->Add(sExtGrStateName, pState); - sKey = m_pExtGStates->GetKey(pState); - } - - return sKey; - } void CPage::AddAnnotation(CDictObject* pAnnot) { CArrayObject* pArray = (CArrayObject*)Get("Annots"); @@ -1205,6 +1168,15 @@ namespace PdfWriter m_pStream->WriteBinary(sText, unLen, NULL); m_pStream->WriteChar('>'); } + else if (fontType1 == eType) + { + unLen = unLen / 2; + BYTE* sText2 = new BYTE[unLen]; + for (int i = 0; i < unLen; ++i) + sText2[i] = sText[i * 2 + 1]; + m_pStream->WriteEscapeText(sText2, unLen); + RELEASEARRAYOBJECTS(sText2); + } else { m_pStream->WriteEscapeText(sText, unLen); @@ -1309,7 +1281,11 @@ namespace PdfWriter // Description: Устанавливаем фонт и размер фонта dSize = std::min((double)MAX_FONTSIZE, std::max(0.0, dSize)); - const char* sFontName = GetLocalFontName(pFont); + CResourcesDict* pResources = GetResourcesItem(); + if (!pResources) + return; + + const char* sFontName = pResources->GetFontName(pFont); if (!sFontName) return; @@ -1320,46 +1296,6 @@ namespace PdfWriter m_pFont = pFont; } - const char* CPage::GetLocalFontName(CFontDict* pFont) - { - if (!m_pFonts) - { - CDictObject* pResources = GetResourcesItem(); - if (!pResources) - return NULL; - - m_pFonts = new CDictObject(); - if (!m_pFonts) - return NULL; - - pResources->Add("Font", m_pFonts); - } - - const char *sKey = m_pFonts->GetKey(pFont); - if (!sKey) - { - // если фонт не зарегистрирован в ресурсах, тогда регистрируем его - char sFontName[LIMIT_MAX_NAME_LEN + 1]; - char *pPointer = NULL; - char *pEndPointer = sFontName + LIMIT_MAX_NAME_LEN; - - ++m_unFontsCount; - while (m_unFontsCount < LIMIT_MAX_DICT_ELEMENT) - { - if (m_pFonts->Get("F" + std::to_string(m_unFontsCount))) - ++m_unFontsCount; - else - break; - } - - pPointer = (char*)StrCpy(sFontName, "F", pEndPointer); - ItoA(pPointer, m_unFontsCount, pEndPointer); - m_pFonts->Add(sFontName, pFont); - sKey = m_pFonts->GetKey(pFont); - } - - return sKey; - } void CPage::SetTextRenderingMode(ETextRenderingMode eMode) { // Operator : Tr @@ -1397,8 +1333,11 @@ namespace PdfWriter } void CPage::ExecuteXObject(CXObject* pXObject) { - const char* sXObjectName = GetXObjectName(pXObject); + CResourcesDict* pResources = GetResourcesItem(); + if (!pResources) + return; + const char* sXObjectName = pResources->GetXObjectName(pXObject); if (!sXObjectName) return; @@ -1412,36 +1351,6 @@ namespace PdfWriter ExecuteXObject(pImage); GrRestore(); } - const char* CPage::GetXObjectName(CXObject* pObject) - { - if (!m_pXObjects) - { - CDictObject* pResources = GetResourcesItem(); - if (!pResources) - return NULL; - - m_pXObjects = new CDictObject(); - if (!m_pXObjects) - return NULL; - - pResources->Add("XObject", m_pXObjects); - } - - const char* sKey = m_pXObjects->GetKey(pObject); - if (!sKey) - { - char sXObjName[LIMIT_MAX_NAME_LEN + 1]; - char *pPointer; - char *pEndPointer = sXObjName + LIMIT_MAX_NAME_LEN; - - pPointer = (char*)StrCpy(sXObjName, "X", pEndPointer); - ItoA(pPointer, ++m_unXObjectsCount, pEndPointer); - m_pXObjects->Add(sXObjName, pObject); - sKey = m_pXObjects->GetKey(pObject); - } - - return sKey; - } void CPage::DrawShading(CShading* pShading) { // Operator : sh @@ -1488,8 +1397,17 @@ namespace PdfWriter char *pPointer; char *pEndPointer = sShadingName + LIMIT_MAX_NAME_LEN; + ++m_unShadingsCount; + while (m_unShadingsCount < LIMIT_MAX_DICT_ELEMENT) + { + if (m_pShadings->Get("S" + std::to_string(m_unShadingsCount))) + ++m_unShadingsCount; + else + break; + } + pPointer = (char*)StrCpy(sShadingName, "S", pEndPointer); - ItoA(pPointer, ++m_unShadingsCount, pEndPointer); + ItoA(pPointer, m_unShadingsCount, pEndPointer); m_pShadings->Add(sShadingName, pShading); sKey = m_pShadings->GetKey(pShading); } @@ -1518,9 +1436,17 @@ namespace PdfWriter char *pPointer; char *pEndPointer = sPatternName + LIMIT_MAX_NAME_LEN; + ++m_unPatternsCount; + while (m_unPatternsCount < LIMIT_MAX_DICT_ELEMENT) + { + if (m_pPatterns->Get("P" + std::to_string(m_unPatternsCount))) + ++m_unPatternsCount; + else + break; + } + pPointer = (char*)StrCpy(sPatternName, "P", pEndPointer); - ItoA(pPointer, m_unPatternsCount + 1, pEndPointer); - m_unPatternsCount++; + ItoA(pPointer, m_unPatternsCount, pEndPointer); m_pPatterns->Add(sPatternName, pPattern); sKey = m_pPatterns->GetKey(pPattern); } @@ -1569,21 +1495,50 @@ namespace PdfWriter void CPage::SetRotate(int nRotate) { // The value shall be a multiple of 90 - if (nRotate > 0 && nRotate % 90 == 0) - { - CNumberObject* pRotate = (CNumberObject*)GetRotateItem(); - if (pRotate) - Add("Rotate", (nRotate + pRotate->Get()) % 360); - else - Add("Rotate", nRotate % 360); - } + if (nRotate % 90 == 0) + Add("Rotate", nRotate % 360); + } + void CPage::ClearContent(CXref* pXref) + { + m_pContents = new CArrayObject(); + Add("Contents", m_pContents); + AddContents(pXref); + } + CDictObject* CPage::GetContent() const + { + return (CDictObject*)m_pContents->Remove(0); } int CPage::GetRotate() { CNumberObject* pRotate = (CNumberObject*)GetRotateItem(); return pRotate ? pRotate->Get() : 0; } - //---------------------------------------------------------------------------------------- + void CPage::BeginMarkedContent(const std::string& sName) + { + // Operator : BMC + // Description: Начало маркированного контента + + m_pStream->WriteEscapeName(sName.c_str()); + m_pStream->WriteStr(" BMC\012"); + } + void CPage::BeginMarkedContentDict(const std::string& sName, CDictObject* pBDC) + { + // Operator : BDC + // Description: Начало маркированного контента со списком свойств + + m_pStream->WriteEscapeName(sName.c_str()); + m_pStream->WriteChar(' '); + m_pStream->Write(pBDC, NULL); + m_pStream->WriteStr(" BDC\012"); + } + void CPage::EndMarkedContent() + { + // Operator : EMC + // Description: Конец маркированного контента + + m_pStream->WriteStr("EMC\012"); + } + //---------------------------------------------------------------------------------------- // CTextWord //---------------------------------------------------------------------------------------- CTextWord::CTextWord() diff --git a/PdfFile/SrcWriter/Pages.h b/PdfFile/SrcWriter/Pages.h index 8989cff8c13..29099cc4dd9 100644 --- a/PdfFile/SrcWriter/Pages.h +++ b/PdfFile/SrcWriter/Pages.h @@ -55,6 +55,7 @@ namespace PdfWriter class CTextWord; class CFieldBase; class CPage; + class CResourcesDict; //---------------------------------------------------------------------------------------- // CPageTree //---------------------------------------------------------------------------------------- @@ -69,6 +70,7 @@ namespace PdfWriter CPage* GetPage(int nPageIndex); CObjectBase* RemovePage(int nPageIndex); bool InsertPage(int nPageIndex, CPage* pPage); + bool ReplacePage(int nPageIndex, CPage* pPage); bool Join(CPageTree* pPageTree); unsigned int GetCount() { @@ -90,7 +92,7 @@ namespace PdfWriter class CPage : public CDictObject { public: - CPage(CDocument* pDocument); + CPage(CDocument* pDocument, CXref* pXref = NULL); CPage(CXref* pXref, CPageTree* pParent, CDocument* pDocument); ~CPage(); @@ -104,6 +106,14 @@ namespace PdfWriter { return dict_type_PAGE; } + CStream* GetStream() const + { + return m_pStream; + } + void SetStream(CStream* pStream) + { + m_pStream = pStream; + } void BeforeWrite(); void MoveTo(double dX, double dY); @@ -131,6 +141,7 @@ namespace PdfWriter void SetStrokeColor(unsigned char unR, unsigned char unG, unsigned char unB); void SetFillColor(unsigned char unR, unsigned char unG, unsigned char unB); void Concat(double dM11, double dM12, double dM21, double dM22, double dX, double dY); + void StartTransform(double dM11, double dM12, double dM21, double dM22, double dX, double dY); void SetTransform(double dM11, double dM12, double dM21, double dM22, double dX, double dY); void SetExtGrState(CExtGrState* pExtGrState); void AddAnnotation(CDictObject* pAnnot); @@ -138,6 +149,9 @@ namespace PdfWriter void DrawShading(CShading* pShading); void SetStrokeAlpha(unsigned char unAlpha); void SetFillAlpha(unsigned char unAlpha); + void BeginMarkedContent(const std::string& sName); + void BeginMarkedContentDict(const std::string& sName, CDictObject* pBDC); + void EndMarkedContent(); void BeginText(); void EndText(); @@ -161,24 +175,23 @@ namespace PdfWriter void AddContents(CXref* pXref); void SetRotate(int nRotate); int GetRotate(); + void ClearContent(CXref* pXref); + CDictObject* GetContent() const; + CResourcesDict* GetResourcesItem(); private: void Init(CDocument* pDocument); void EllipseArc(double dX, double dY, double dXRad, double dYRad, double dAngle1, double dAngle2, bool bClockDirection); CArrayObject* GetMediaBoxItem(); - CDictObject* GetResourcesItem(); CObjectBase* GetCropBoxItem(); CObjectBase* GetRotateItem(); TBox GetMediaBox(); void SetMediaBoxValue(unsigned int unIndex, double dValue); - void AddResource(); + void AddResource(CXref* pXref = NULL); void SetGrMode(EGrMode eMode); void CheckGrMode(EGrMode eMode); void WriteText(const BYTE* sText, unsigned int unLen); - const char* GetExtGrStateName(CExtGrState* pState); - const char* GetLocalFontName(CFontDict* pFont); - const char* GetXObjectName(CXObject* pObject); const char* GetLocalShadingName(CShading* pShading); const char* GetLocalPatternName(CImageTilePattern* pPattern); @@ -193,15 +206,9 @@ namespace PdfWriter CArrayObject* m_pContents; CStream* m_pStream; unsigned int m_unCompressionMode; - CDictObject* m_pExtGStates; - unsigned int m_unExtGStatesCount; EGrMode m_eGrMode; CGrState* m_pGrState; - CDictObject* m_pFonts; - unsigned int m_unFontsCount; CFontDict* m_pFont; // Текущий шрифт - CDictObject* m_pXObjects; - unsigned int m_unXObjectsCount; CDictObject* m_pShadings; unsigned int m_unShadingsCount; CDictObject* m_pPatterns; diff --git a/PdfFile/SrcWriter/ResourcesDictionary.cpp b/PdfFile/SrcWriter/ResourcesDictionary.cpp index 7c8da0ea993..eee1ba6b013 100644 --- a/PdfFile/SrcWriter/ResourcesDictionary.cpp +++ b/PdfFile/SrcWriter/ResourcesDictionary.cpp @@ -80,14 +80,19 @@ namespace PdfWriter const char *sKey = m_pFonts->GetKey(pFont); if (!sKey) { - // ���� ���� �� ��������������� � ��������, ����� ������������ ��� + // если фонт не зарегистрирован в ресурсах, тогда регистрируем его char sFontName[LIMIT_MAX_NAME_LEN + 1]; char *pPointer = NULL; char *pEndPointer = sFontName + LIMIT_MAX_NAME_LEN; + while (++m_unFontsCount < LIMIT_MAX_DICT_ELEMENT) + { + if (!m_pFonts->Get("F" + std::to_string(m_unFontsCount))) + break; + } + pPointer = (char*)StrCpy(sFontName, "F", pEndPointer); - ItoA(pPointer, m_unFontsCount + 1, pEndPointer); - m_unFontsCount++; + ItoA(pPointer, m_unFontsCount, pEndPointer); m_pFonts->Add(sFontName, pFont); sKey = m_pFonts->GetKey(pFont); } @@ -108,21 +113,26 @@ namespace PdfWriter const char* sKey = m_pExtGStates->GetKey(pState); if (!sKey) { - // ���� ExtGState �� ��������������� � Resource, ������������ + // Если ExtGState не зарегистрирован в Resource, регистрируем. char sExtGrStateName[LIMIT_MAX_NAME_LEN + 1]; char *pPointer; char *pEndPointer = sExtGrStateName + LIMIT_MAX_NAME_LEN; + while (++m_unExtGStatesCount < LIMIT_MAX_DICT_ELEMENT) + { + if (!m_pExtGStates->Get("E" + std::to_string(m_unExtGStatesCount))) + break; + } + pPointer = (char*)StrCpy(sExtGrStateName, "E", pEndPointer); - ItoA(pPointer, m_unExtGStatesCount + 1, pEndPointer); - m_unExtGStatesCount++; + ItoA(pPointer, m_unExtGStatesCount, pEndPointer); m_pExtGStates->Add(sExtGrStateName, pState); sKey = m_pExtGStates->GetKey(pState); } return sKey; } - const char* CResourcesDict::GetXObjectName(CXObject* pObject) + const char* CResourcesDict::GetXObjectName(CObjectBase* pObject) { if (!m_pXObjects) { @@ -140,9 +150,14 @@ namespace PdfWriter char *pPointer; char *pEndPointer = sXObjName + LIMIT_MAX_NAME_LEN; + while (++m_unXObjectsCount < LIMIT_MAX_DICT_ELEMENT) + { + if (!m_pXObjects->Get("X" + std::to_string(m_unXObjectsCount))) + break; + } + pPointer = (char*)StrCpy(sXObjName, "X", pEndPointer); - ItoA(pPointer, m_unXObjectsCount + 1, pEndPointer); - m_unXObjectsCount++; + ItoA(pPointer, m_unXObjectsCount, pEndPointer); m_pXObjects->Add(sXObjName, pObject); sKey = m_pXObjects->GetKey(pObject); } @@ -162,4 +177,30 @@ namespace PdfWriter m_pXObjects->Add(sXObjName, pObject); } + void CResourcesDict::Fix() + { + // Инициализация текущего fonts + CObjectBase* pFonts = Get("Font"); + if (pFonts && pFonts->GetType() == object_type_DICT) + { + m_pFonts = (CDictObject*)pFonts; + m_unFontsCount = 0; + } + + // Инициализация текущего ExtGStates + CObjectBase* pExtGStates = Get("ExtGState"); + if (pExtGStates && pExtGStates->GetType() == object_type_DICT) + { + m_pExtGStates = (CDictObject*)pExtGStates; + m_unExtGStatesCount = 0; + } + + // Инициализация текущего XObject + CObjectBase* pXObject = Get("XObject"); + if (pXObject && pXObject->GetType() == object_type_DICT) + { + m_pXObjects = (CDictObject*)pXObject; + m_unXObjectsCount = 0; + } + } } diff --git a/PdfFile/SrcWriter/ResourcesDictionary.h b/PdfFile/SrcWriter/ResourcesDictionary.h index 82bdbb03f02..47eb1d074d2 100644 --- a/PdfFile/SrcWriter/ResourcesDictionary.h +++ b/PdfFile/SrcWriter/ResourcesDictionary.h @@ -48,8 +48,9 @@ namespace PdfWriter const char* GetFontName(CFontDict* pFont); const char* GetExtGrStateName(CExtGrState* pState); - const char* GetXObjectName(CXObject* pXObject); + const char* GetXObjectName(CObjectBase* pXObject); void AddXObjectWithName(const char* sXObjectName, CXObject* pXObject); + void Fix(); private: diff --git a/PdfFile/SrcWriter/States.cpp b/PdfFile/SrcWriter/States.cpp index 683d0153887..5b2087cc7e4 100644 --- a/PdfFile/SrcWriter/States.cpp +++ b/PdfFile/SrcWriter/States.cpp @@ -68,7 +68,7 @@ void CCommandManager::Flush() size_t nCommandsCount = m_vCommands.size(); if (nCommandsCount > 0) { - PdfWriter::CPage* pPage = m_pRenderer->m_pPage; + PdfWriter::CPage* pPage = m_pRenderer->GetPage(); pPage->GrSave(); pPage->SetTransform(m_oTransform.m11, m_oTransform.m12, m_oTransform.m21, m_oTransform.m22, m_oTransform.dx, m_oTransform.dy); @@ -171,13 +171,22 @@ void CCommandManager::Flush() isNeedDoItalic = pText->IsNeedDoItalic(); } + if (!pText->GetPUA().empty()) + { + oTextLine.Flush(pPage); + PdfWriter::CDictObject* pBDC = new PdfWriter::CDictObject(); + pBDC->Add("ActualText", new PdfWriter::CStringObject(pText->GetPUA().c_str(), true)); + pPage->BeginMarkedContentDict("Span", pBDC); + RELEASEOBJECT(pBDC); + } + unsigned char* pCodes = pText->GetCodes(); unsigned short ushCode = (pCodes[0] << 8) + pCodes[1]; unsigned int unLen = pText->GetCodesLen(); double dX = pText->GetX(); double dY = pText->GetY(); double dTextSize = pText->GetSize(); - double dWidth = ((PdfWriter::CFontCidTrueType*)pText->GetFont())->GetWidth(ushCode) / 1000.0 * dTextSize; + double dWidth = pText->GetFont()->GetWidth(ushCode) / 1000.0 * dTextSize; if (!oTextLine.Add(pCodes, unLen, dX, dY, dWidth, dTextSize)) { @@ -187,6 +196,12 @@ void CCommandManager::Flush() pPage->DrawText(dX, dY, pCodes, unLen); } } + + if (!pText->GetPUA().empty()) + { + oTextLine.Flush(pPage); + pPage->EndMarkedContent(); + } } oTextLine.Flush(pPage); diff --git a/PdfFile/SrcWriter/States.h b/PdfFile/SrcWriter/States.h index d9b84243826..cf1abf65660 100644 --- a/PdfFile/SrcWriter/States.h +++ b/PdfFile/SrcWriter/States.h @@ -143,6 +143,10 @@ class CRendererTextCommand : public CRendererCommandBase { m_bNeedDoBold = bBold; } + inline void SetPUA(const std::string& sPUA) + { + m_sPUA = sPUA; + } inline PdfWriter::CFontDict* GetFont() const { return m_pFont; @@ -179,6 +183,10 @@ class CRendererTextCommand : public CRendererCommandBase { return m_bNeedDoBold; } + inline std::string GetPUA() const + { + return m_sPUA; + } private: @@ -196,6 +204,7 @@ class CRendererTextCommand : public CRendererCommandBase double m_dCharSpace; int m_nMode; double m_dHorScaling; + std::string m_sPUA; }; struct TFontInfo { diff --git a/PdfFile/SrcWriter/Streams.cpp b/PdfFile/SrcWriter/Streams.cpp index d630a62a687..e5a873b2b57 100644 --- a/PdfFile/SrcWriter/Streams.cpp +++ b/PdfFile/SrcWriter/Streams.cpp @@ -311,7 +311,7 @@ namespace PdfWriter { BYTE nChar = (BYTE)*sTxt++; - if ((isDictValue && NEEDS_ESCAPE_DICTVALUE(nChar)) || (!isDictValue && NEEDS_ESCAPE(nChar))) + if ((isDictValue && NEEDS_ESCAPE_DICTVALUE(nChar)) || (!isDictValue && NEEDS_ESCAPE_STR(nChar))) { sBuf[nIndex++] = '\\'; sBuf[nIndex++] = 0x30 + (nChar >> 6); @@ -541,9 +541,33 @@ namespace PdfWriter if (pEncrypt) { const BYTE* pBinary = pString->GetString(); + unsigned int unLen = pString->GetLength(); + WriteChar('<'); - WriteBinary(pBinary, StrLen((const char*)pBinary, -1), pEncrypt); + + BYTE* pNewBinary = NULL; + if (pString->IsUTF16()) + { + std::string sUtf8((char*)pBinary, unLen); + std::wstring sUnicode = UTF8_TO_U(sUtf8); + unsigned int unLenUtf16 = 0; + unsigned short* pUtf16Data = NSStringExt::CConverter::GetUtf16FromUnicode(sUnicode, unLenUtf16, false); + unLenUtf16 *= 2; + unLen = unLenUtf16 + 2; + + pNewBinary = new BYTE[unLenUtf16 + 2]; + pNewBinary[0] = 0xFE; + pNewBinary[1] = 0xFF; + MemCpy(pNewBinary + 2, (BYTE*)pUtf16Data, unLenUtf16); + RELEASEARRAYOBJECTS(pUtf16Data); + + pBinary = pNewBinary; + } + + WriteBinary(pBinary, unLen, pEncrypt); WriteChar('>'); + + RELEASEARRAYOBJECTS(pNewBinary); } else { @@ -589,7 +613,6 @@ namespace PdfWriter // Добавляем запись Filter if (pDict->GetStream()) { - pDict->Remove("Filter"); unsigned int unFilter = pDict->GetFilter(); if (STREAM_FILTER_NONE != unFilter) { @@ -648,10 +671,7 @@ namespace PdfWriter } } - if (dict_type_SIGNATURE == pDict->GetDictType()) - pDict->WriteSignatureToStream(this, pEncrypt); - else - pDict->WriteToStream(this, pEncrypt); + pDict->WriteToStream(this, pEncrypt); pDict->Write(this); WriteStr(">>"); @@ -661,7 +681,7 @@ namespace PdfWriter { CNumberObject* pLength = (CNumberObject*)pDict->Get("Length"); // "Length" должен управляться таблицей Xref (флаг Indirect) - if (pLength && object_type_NUMBER == pLength->GetType() && pLength->IsIndirect()) + if (pLength && object_type_NUMBER == pLength->GetType()) { if (pEncrypt) pEncrypt->Reset(); @@ -669,14 +689,14 @@ namespace PdfWriter WriteStr("\012stream\015\012"); unsigned int unStartSize = Tell(); - WriteStream(pStream, pDict->GetFilter(), pEncrypt); + WriteStream(pStream, pDict->GetFilter(), pDict->GetDictType() == dict_type_STREAM ? NULL : pEncrypt); pLength->Set(Tell() - unStartSize); WriteStr("\012endstream"); } } - pDict->AfterWrite(); + pDict->AfterWrite(this); } void CStream::Write(CObjectBase* pObject, CEncrypt* pEncrypt) { diff --git a/PdfFile/SrcWriter/Types.h b/PdfFile/SrcWriter/Types.h index 20a211ceb00..4a87cb6af3f 100644 --- a/PdfFile/SrcWriter/Types.h +++ b/PdfFile/SrcWriter/Types.h @@ -89,6 +89,15 @@ namespace PdfWriter x = 0; y = 0; } + CMatrix(double d1, double d2, double d3, double d4, double d5, double d6) + { + m11 = d1; + m12 = d2; + m21 = d3; + m22 = d4; + x = d5; + y = d6; + } void Reset() { @@ -136,7 +145,7 @@ namespace PdfWriter CMatrix oInverse; double dDet = m11 * m22 - m12 * m21; - if (dDet < 0.0001 && dDet > 0.0001) + if (dDet < 0.0001 && dDet > -0.0001) return oInverse; oInverse.m11 = m22 / dDet; diff --git a/PdfFile/SrcWriter/Utils.h b/PdfFile/SrcWriter/Utils.h index cade16ba39c..15160cf1899 100644 --- a/PdfFile/SrcWriter/Utils.h +++ b/PdfFile/SrcWriter/Utils.h @@ -49,6 +49,12 @@ c == '{' || \ c == '}') \ +#define NEEDS_ESCAPE_STR(c) (c < 0x20 || \ + c > 0x7e || \ + c == '\\' || \ + c == '(' || \ + c == ')') \ + #define NEEDS_ESCAPE_DICTVALUE(c) (c != 0x9 && \ c != 0xA && \ (c < 0x20 || \ diff --git a/PdfFile/lib/xpdf/Annot.cc b/PdfFile/lib/xpdf/Annot.cc index 0fb26704053..07d29172120 100644 --- a/PdfFile/lib/xpdf/Annot.cc +++ b/PdfFile/lib/xpdf/Annot.cc @@ -78,6 +78,7 @@ AnnotBorderStyle::~AnnotBorderStyle() { //------------------------------------------------------------------------ Annot::Annot(PDFDoc *docA, Dict *dict, Ref *refA, const char* AP, const char* AS) { + GBool bBorder; Object apObj, asObj, obj1, obj2, obj3; AnnotBorderType borderType; double borderWidth; @@ -88,6 +89,7 @@ Annot::Annot(PDFDoc *docA, Dict *dict, Ref *refA, const char* AP, const char* AS double t; int i; + bBorder = gFalse; ok = gTrue; doc = docA; xref = doc->getXRef(); @@ -189,6 +191,7 @@ Annot::Annot(PDFDoc *docA, Dict *dict, Ref *refA, const char* AP, const char* AS } } obj2.free(); + bBorder = gTrue; } else { obj1.free(); if (dict->lookup("Border", &obj1)->isArray()) { @@ -197,6 +200,7 @@ Annot::Annot(PDFDoc *docA, Dict *dict, Ref *refA, const char* AP, const char* AS borderWidth = obj2.getNum(); } obj2.free(); + bBorder = gTrue; if (obj1.arrayGetLength() >= 4) { if (obj1.arrayGet(3, &obj2)->isArray()) { borderType = annotBorderDashed; @@ -214,6 +218,7 @@ Annot::Annot(PDFDoc *docA, Dict *dict, Ref *refA, const char* AP, const char* AS // Adobe draws no border at all if the last element is of // the wrong type. borderWidth = 0; + bBorder = gFalse; } obj2.free(); } @@ -237,11 +242,14 @@ Annot::Annot(PDFDoc *docA, Dict *dict, Ref *refA, const char* AP, const char* AS } obj2.free(); } + } else if (type && type->cmp("FreeText")) { + bBorder = gFalse; } obj1.free(); - borderStyle = new AnnotBorderStyle(borderType, borderWidth, - borderDash, borderDashLength, - borderColor, nBorderColorComps); + if (bBorder) { + borderStyle = new AnnotBorderStyle(borderType, borderWidth, + borderDash, borderDashLength, borderColor, nBorderColorComps); + } //----- get the appearance state @@ -315,6 +323,8 @@ void Annot::generateAnnotAppearance() { generatePolygonAppearance(); } else if (!type->cmp("FreeText")) { generateFreeTextAppearance(); + } else if (!type->cmp("Text")) { + generateTextAppearance(); } } } @@ -350,8 +360,10 @@ void Annot::generateLineAppearance() { obj1.free(); //----- set line style, colors - setLineStyle(borderStyle, &w); - setStrokeColor(borderStyle->getColor(), borderStyle->getNumColorComps()); + if (borderStyle) { + setLineStyle(borderStyle, &w); + setStrokeColor(borderStyle->getColor(), borderStyle->getNumColorComps()); + } fill = gFalse; if (annotObj.dictLookup("IC", &obj1)->isArray()) { if (setFillColor(&obj1)) { @@ -478,7 +490,7 @@ void Annot::generateLineAppearance() { appearBuf->append("S\n"); //----- draw the arrows - if (borderStyle->getType() == annotBorderDashed) { + if (borderStyle && borderStyle->getType() == annotBorderDashed) { appearBuf->append("[] 0 d\n"); } drawLineArrow(lineEnd1, lx1, ly1, dx, dy, w, fill); @@ -536,8 +548,10 @@ void Annot::generatePolyLineAppearance() { obj1.free(); //----- set line style, colors - setLineStyle(borderStyle, &w); - setStrokeColor(borderStyle->getColor(), borderStyle->getNumColorComps()); + if (borderStyle) { + setLineStyle(borderStyle, &w); + setStrokeColor(borderStyle->getColor(), borderStyle->getNumColorComps()); + } // fill = gFalse; // if (annotObj.dictLookup("IC", &obj1)->isArray()) { // if (setFillColor(&obj1)) { @@ -717,10 +731,26 @@ void Annot::generateFreeTextAppearance() { if (annotObj.dictLookup("CA", &obj1)->isNum()) { gfxStateDict.initDict(doc->getXRef()); gfxStateDict.dictAdd(copyString("ca"), obj1.copy(&obj2)); + gfxStateDict.dictAdd(copyString("CA"), obj1.copy(&obj2)); appearBuf->append("/GS1 gs\n"); } obj1.free(); + lineWidth = 0; + if (borderStyle && borderStyle->getWidth() != 0) { + lineWidth = 0.1; + if (borderStyle->getWidth() > 0) { + lineWidth = borderStyle->getWidth(); + } + } + + if (annotObj.dictLookup("C", &obj1)->isArray()) { + setFillColor(&obj1); + appearBuf->appendf("{0:.4f} {1:.4f} {2:.4f} {3:.4f} re f\n", + 0.5 * lineWidth, 0.5 * lineWidth, + xMax - xMin - lineWidth, yMax - yMin - lineWidth); + } + //----- draw the text if (annotObj.dictLookup("Contents", &obj1)->isString()) { text = obj1.getString()->copy(); @@ -739,7 +769,7 @@ void Annot::generateFreeTextAppearance() { } else { da = new GString(); } - obj1.free(); + appearDict.free(); obj1.free(); // the "Rotate" field is not defined in the PDF spec, but Acrobat // looks at it if (annotObj.dictLookup("Rotate", &obj1)->isInt()) { @@ -748,16 +778,17 @@ void Annot::generateFreeTextAppearance() { rot = 0; } obj1.free(); - drawText(text, da, quadding, 0, rot); + drawText(text, da, quadding, lineWidth, rot); delete text; delete da; //----- draw the border - if (borderStyle->getWidth() != 0) { - setLineStyle(borderStyle, &lineWidth); - appearBuf->appendf("{0:.4f} {1:.4f} {2:.4f} {3:.4f} re s\n", - 0.5 * lineWidth, 0.5 * lineWidth, - xMax - xMin - lineWidth, yMax - yMin - lineWidth); + if (lineWidth != 0) { + setLineStyle(borderStyle, &lineWidth); + appearBuf->appendf("{0:.4f} {1:.4f} {2:.4f} {3:.4f} re S\n", + 0.5 * lineWidth, 0.5 * lineWidth, + xMax - xMin - lineWidth, yMax - yMin - lineWidth); + obj1.free(); } //----- build the appearance stream dictionary @@ -796,18 +827,251 @@ void Annot::generateFreeTextAppearance() { annotObj.free(); } +void Annot::generateTextAppearance() +{ + Object oAnnotObj, oName, oAppearDict, gfxStateDict, obj1, obj2; + MemStream* pAppearStream; + if (!getObject(&oAnnotObj)->isDict() || !oAnnotObj.dictLookup("Name", &oName)->isName()) + { + oAnnotObj.free(); oName.free(); + return; + } + + appearBuf = new GString(); + pAppearStream = NULL; + + if (oName.isName("Check")) + { + yMin = yMax - 19; + xMax = xMin + 19; + if (!oAnnotObj.dictLookup("C", &obj1)->isArray() || !setFillColor(&obj1)) + appearBuf->append("1 0.819611 0 rg"); + obj1.free(); + appearBuf->append(" 0 G 0 i 0.59 w 4 M 1 j 0 J [] 0 d 1 0 0 1 7.1836 1.2061 cm 0 0 m 6.691 11.152 11.31 14.196 v 10.773 15.201 9.626 16.892 8.155 17.587 c 2.293 10.706 -0.255 4.205 y -4.525 9.177 l -6.883 5.608 l h b"); + } + else if (oName.isName("Checkmark")) + { + yMin = yMax - 20; + xMax = xMin + 20; + appearBuf->append("q 0.396 0.396 0.396 rg 1 0 0 1 13.5151 16.5 cm 0 0 m -6.7 -10.23 l -8.81 -7 l -13.22 -7 l -6.29 -15 l 4.19 0 l h f Q"); + } + else if (oName.isName("Circle")) + { + yMin = yMax - 20; + xMax = xMin + 20; + gfxStateDict.initDict(doc->getXRef()); + oAnnotObj.dictLookup("CA", &obj1); + gfxStateDict.dictAdd(copyString("ca"), obj1.isNum() ? obj1.copy(&obj2) : obj2.initReal(0.6)); + gfxStateDict.dictAdd(copyString("CA"), obj1.isNum() ? obj1.copy(&obj2) : obj2.initReal(0.6)); + obj1.free(); + appearBuf->append("q 1 1 1 rg 0 i 1 w 4 M 1 j 0 J [] 0 d /GS1 gs 1 0 0 1 9.999 3.6387 cm 0 0 m -3.513 0 -6.36 2.85 -6.36 6.363 c -6.36 9.875 -3.513 12.724 0 12.724 c 3.514 12.724 6.363 9.875 6.363 6.363 c 6.363 2.85 3.514 0 0 0 c h f Q "); + if (!oAnnotObj.dictLookup("C", &obj1)->isArray() || !setFillColor(&obj1)) + appearBuf->append("1 0.819611 0 rg"); + obj1.free(); + appearBuf->append(" 0 G 0 i 0.59 w 4 M 1 j 0 J [] 0 d 1 0 0 1 9.999 3.6387 cm 0 0 m -3.513 0 -6.36 2.85 -6.36 6.363 c -6.36 9.875 -3.513 12.724 0 12.724 c 3.514 12.724 6.363 9.875 6.363 6.363 c 6.363 2.85 3.514 0 0 0 c 0 16.119 m -5.388 16.119 -9.756 11.751 -9.756 6.363 c -9.756 0.973 -5.388 -3.395 0 -3.395 c 5.391 -3.395 9.757 0.973 9.757 6.363 c 9.757 11.751 5.391 16.119 0 16.119 c b"); + } + else if (oName.isName("Comment")) + { + yMin = yMax - 24; + xMax = xMin + 24; + gfxStateDict.initDict(doc->getXRef()); + oAnnotObj.dictLookup("CA", &obj1); + gfxStateDict.dictAdd(copyString("ca"), obj1.isNum() ? obj1.copy(&obj2) : obj2.initReal(0.6)); + gfxStateDict.dictAdd(copyString("CA"), obj1.isNum() ? obj1.copy(&obj2) : obj2.initReal(0.6)); + obj1.free(); + appearBuf->append("q 1 1 1 rg 0 i 1 w 4 M 1 j 0 J [] 0 d /GS1 gs 1 0 0 1 9 5.0908 cm 7.74 12.616 m -7.74 12.616 l -8.274 12.616 -8.707 12.184 -8.707 11.649 c -8.707 -3.831 l -8.707 -4.365 -8.274 -4.798 -7.74 -4.798 c 7.74 -4.798 l 8.274 -4.798 8.707 -4.365 8.707 -3.831 c 8.707 11.649 l 8.707 12.184 8.274 12.616 7.74 12.616 c h f Q 0 G "); + if (!oAnnotObj.dictLookup("C", &obj1)->isArray() || !setFillColor(&obj1)) + appearBuf->append("1 0.819611 0 rg"); + obj1.free(); + appearBuf->append(" 0 i 0.60 w 4 M 1 j 0 J [0 100] 1 d 1 0 0 1 9 5.0908 cm 1 0 m -2.325 -2.81 l -2.325 0 l -5.72 0 l -5.72 8.94 l 5.51 8.94 l 5.51 0 l 1 0 l -3.50 5.01 m -3.50 5.59 l 3.29 5.59 l 3.29 5.01 l -3.50 5.01 l -3.50 3.34 m -3.50 3.92 l 2.27 3.92 l 2.27 3.34 l -3.50 3.34 l 7.74 12.616 m -7.74 12.616 l -8.274 12.616 -8.707 12.184 -8.707 11.649 c -8.707 -3.831 l -8.707 -4.365 -8.274 -4.798 -7.74 -4.798 c 7.74 -4.798 l 8.274 -4.798 8.707 -4.365 8.707 -3.831 c 8.707 11.649 l 8.707 12.184 8.274 12.616 7.74 12.616 c b"); + } + else if (oName.isName("Cross")) + { + yMin = yMax - 19; + xMax = xMin + 19; + if (!oAnnotObj.dictLookup("C", &obj1)->isArray() || !setFillColor(&obj1)) + appearBuf->append("1 0.819611 0 rg"); + obj1.free(); + appearBuf->append(" 0 G 0 i 0.59 w 4 M 1 j 0 J [] 0 d 1 0 0 1 18.6924 3.1357 cm 0 0 m -6.363 6.364 l 0 12.728 l -2.828 15.556 l -9.192 9.192 l -15.556 15.556 l -18.384 12.728 l -12.02 6.364 l -18.384 0 l -15.556 -2.828 l -9.192 3.535 l -2.828 -2.828 l h b"); + } + else if (oName.isName("CrossHairs")) + { + yMin = yMax - 20; + xMax = xMin + 20; + gfxStateDict.initDict(doc->getXRef()); + oAnnotObj.dictLookup("CA", &obj1); + gfxStateDict.dictAdd(copyString("ca"), obj1.isNum() ? obj1.copy(&obj2) : obj2.initReal(0.6)); + gfxStateDict.dictAdd(copyString("CA"), obj1.isNum() ? obj1.copy(&obj2) : obj2.initReal(0.6)); + obj1.free(); + appearBuf->append("q 1 1 1 rg 0 i 1 w 4 M 1 j 0 J [] 0 d /GS1 gs 1 0 0 1 9.9771 1.9443 cm 0 0 m -4.448 0 -8.053 3.604 -8.053 8.053 c -8.053 12.5 -4.448 16.106 0 16.106 c 4.447 16.106 8.054 12.5 8.054 8.053 c 8.054 3.604 4.447 0 0 0 c h f Q "); + if (!oAnnotObj.dictLookup("C", &obj1)->isArray() || !setFillColor(&obj1)) + appearBuf->append("1 0.819611 0 rg"); + obj1.free(); + appearBuf->append(" 0 G 0 i 0.61 w 4 M 0 j 0 J [] 0 d q 1 0 0 1 9.9771 1.9443 cm 0 0 m -4.448 0 -8.053 3.604 -8.053 8.053 c -8.053 12.5 -4.448 16.106 0 16.106 c 4.447 16.106 8.054 12.5 8.054 8.053 c 8.054 3.604 4.447 0 0 0 c 0 17.716 m -5.336 17.716 -9.663 13.39 -9.663 8.053 c -9.663 2.716 -5.336 -1.61 0 -1.61 c 5.337 -1.61 9.664 2.716 9.664 8.053 c 9.664 13.39 5.337 17.716 0 17.716 c b Q q 1 0 0 1 10.7861 14.8325 cm 0 0 m -1.611 0 l -1.611 -4.027 l -5.638 -4.027 l -5.638 -5.638 l -1.611 -5.638 l -1.611 -9.665 l 0 -9.665 l 0 -5.638 l 4.026 -5.638 l 4.026 -4.027 l 0 -4.027 l h b Q"); + } + else if (oName.isName("Help")) + { + yMin = yMax - 20; + xMax = xMin + 20; + gfxStateDict.initDict(doc->getXRef()); + oAnnotObj.dictLookup("CA", &obj1); + gfxStateDict.dictAdd(copyString("ca"), obj1.isNum() ? obj1.copy(&obj2) : obj2.initReal(0.6)); + gfxStateDict.dictAdd(copyString("CA"), obj1.isNum() ? obj1.copy(&obj2) : obj2.initReal(0.6)); + obj1.free(); + appearBuf->append("q 1 1 1 rg 0 i 1 w 4 M 1 j 0 J [] 0 d /GS1 gs 1 0 0 1 12.1465 10.5137 cm -2.146 9.403 m -7.589 9.403 -12.001 4.99 -12.001 -0.453 c -12.001 -5.895 -7.589 -10.309 -2.146 -10.309 c 3.296 -10.309 7.709 -5.895 7.709 -0.453 c 7.709 4.99 3.296 9.403 -2.146 9.403 c h f Q "); + if (!oAnnotObj.dictLookup("C", &obj1)->isArray() || !setFillColor(&obj1)) + appearBuf->append("1 0.819611 0 rg"); + obj1.free(); + appearBuf->append(" 0 G 0 i 0.59 w 4 M 1 j 0 J [] 0 d 1 0 0 1 12.1465 10.5137 cm 0 0 m -0.682 -0.756 -0.958 -1.472 -0.938 -2.302 c -0.938 -2.632 l -3.385 -2.632 l -3.403 -2.154 l -3.459 -1.216 -3.147 -0.259 -2.316 0.716 c -1.729 1.433 -1.251 2.022 -1.251 2.647 c -1.251 3.291 -1.674 3.715 -2.594 3.751 c -3.202 3.751 -3.937 3.531 -4.417 3.2 c -5.041 5.205 l -4.361 5.591 -3.274 5.959 -1.968 5.959 c 0.46 5.959 1.563 4.616 1.563 3.089 c 1.563 1.691 0.699 0.771 0 0 c -2.227 -6.863 m -2.245 -6.863 l -3.202 -6.863 -3.864 -6.146 -3.864 -5.189 c -3.864 -4.196 -3.182 -3.516 -2.227 -3.516 c -1.233 -3.516 -0.589 -4.196 -0.57 -5.189 c -0.57 -6.146 -1.233 -6.863 -2.227 -6.863 c -2.146 9.403 m -7.589 9.403 -12.001 4.99 -12.001 -0.453 c -12.001 -5.895 -7.589 -10.309 -2.146 -10.309 c 3.296 -10.309 7.709 -5.895 7.709 -0.453 c 7.709 4.99 3.296 9.403 -2.146 9.403 c b"); + } + else if (oName.isName("Insert")) + { + yMin = yMax - 20; + xMax = xMin + 17; + appearBuf->append("0 G "); + if (!oAnnotObj.dictLookup("C", &obj1)->isArray() || !setFillColor(&obj1)) + appearBuf->append("1 0.819611 0 rg"); + obj1.free(); + appearBuf->append(" 0 i 0.59 w 4 M 0 j 0 J [] 0 d 1 0 0 1 8.5386 19.8545 cm 0 0 m -8.39 -19.719 l 8.388 -19.719 l h B"); + } + else if (oName.isName("Key")) + { + yMin = yMax - 18; + xMax = xMin + 13; + gfxStateDict.initDict(doc->getXRef()); + oAnnotObj.dictLookup("CA", &obj1); + gfxStateDict.dictAdd(copyString("ca"), obj1.isNum() ? obj1.copy(&obj2) : obj2.initReal(0.6)); + gfxStateDict.dictAdd(copyString("CA"), obj1.isNum() ? obj1.copy(&obj2) : obj2.initReal(0.6)); + obj1.free(); + appearBuf->append("q 1 1 1 rg 0 i 1 w 4 M 1 j 0 J [] 0 d /GS1 gs 1 0 0 1 6.5 12.6729 cm 0.001 5.138 m -2.543 5.138 -4.604 3.077 -4.604 0.534 c -4.604 -1.368 -3.449 -3.001 -1.802 -3.702 c -1.802 -4.712 l -0.795 -5.719 l -1.896 -6.82 l -0.677 -8.039 l -1.595 -8.958 l -0.602 -9.949 l -1.479 -10.829 l -0.085 -12.483 l 1.728 -10.931 l 1.728 -3.732 l 1.737 -3.728 1.75 -3.724 1.76 -3.721 c 3.429 -3.03 4.604 -1.385 4.604 0.534 c 4.604 3.077 2.542 5.138 0.001 5.138 c f Q "); + if (!oAnnotObj.dictLookup("C", &obj1)->isArray() || !setFillColor(&obj1)) + appearBuf->append("1 0.819611 0 rg"); + obj1.free(); + appearBuf->append(" 0 G 0 i 0.59 w 4 M 1 j 0 J [] 0 d 1 0 0 1 6.5 12.6729 cm 0 0 m -1.076 0 -1.95 0.874 -1.95 1.95 c -1.95 3.028 -1.076 3.306 0 3.306 c 1.077 3.306 1.95 3.028 1.95 1.95 c 1.95 0.874 1.077 0 0 0 c 0.001 5.138 m -2.543 5.138 -4.604 3.077 -4.604 0.534 c -4.604 -1.368 -3.449 -3.001 -1.802 -3.702 c -1.802 -4.712 l -0.795 -5.719 l -1.896 -6.82 l -0.677 -8.039 l -1.595 -8.958 l -0.602 -9.949 l -1.479 -10.829 l -0.085 -12.483 l 1.728 -10.931 l 1.728 -3.732 l 1.737 -3.728 1.75 -3.724 1.76 -3.721 c 3.429 -3.03 4.604 -1.385 4.604 0.534 c 4.604 3.077 2.542 5.138 0.001 5.138 c b"); + } + else if (oName.isName("NewParagraph")) + { + yMin = yMax - 20; + xMax = xMin + 13; + if (!oAnnotObj.dictLookup("C", &obj1)->isArray() || !setFillColor(&obj1)) + appearBuf->append("1 0.819611 0 rg"); + obj1.free(); + appearBuf->append(" 0 G 0 i 0.59 w 4 M 1 j 0 J [] 0 d q 1 0 0 1 6.4995 20 cm 0 0 m -6.205 -12.713 l 6.205 -12.713 l h b Q q 1 0 0 1 1.1909 6.2949 cm 0 0 m 1.278 0 l 1.353 0 1.362 -0.02 1.391 -0.066 c 2.128 -1.363 3.78 -4.275 3.966 -4.713 c 3.985 -4.713 l 3.976 -4.453 3.957 -3.91 3.957 -3.137 c 3.957 -0.076 l 3.957 -0.02 3.976 0 4.041 0 c 4.956 0 l 5.021 0 5.04 -0.029 5.04 -0.084 c 5.04 -6.049 l 5.04 -6.113 5.021 -6.133 4.947 -6.133 c 3.695 -6.133 l 3.621 -6.133 3.611 -6.113 3.574 -6.066 c 3.052 -4.955 1.353 -2.063 0.971 -1.186 c 0.961 -1.186 l 0.999 -1.68 0.999 -2.146 1.008 -3.025 c 1.008 -6.049 l 1.008 -6.104 0.989 -6.133 0.933 -6.133 c 0.009 -6.133 l -0.046 -6.133 -0.075 -6.123 -0.075 -6.049 c -0.075 -0.066 l -0.075 -0.02 -0.056 0 0 0 c f Q q 1 0 0 1 9.1367 3.0273 cm 0 0 m 0.075 0 0.215 -0.008 0.645 -0.008 c 1.4 -0.008 2.119 0.281 2.119 1.213 c 2.119 1.969 1.633 2.381 0.737 2.381 c 0.354 2.381 0.075 2.371 0 2.361 c h -1.146 3.201 m -1.146 3.238 -1.129 3.268 -1.082 3.268 c -0.709 3.275 0.02 3.285 0.729 3.285 c 2.613 3.285 3.248 2.314 3.258 1.232 c 3.258 -0.27 2.007 -0.914 0.607 -0.914 c 0.327 -0.914 0.057 -0.914 0 -0.904 c 0 -2.789 l 0 -2.836 -0.019 -2.865 -0.074 -2.865 c -1.082 -2.865 l -1.119 -2.865 -1.146 -2.846 -1.146 -2.799 c h f Q"); + } + else if (oName.isName("Note")) + { + yMin = yMax - 20; + xMax = xMin + 18; + if (!oAnnotObj.dictLookup("C", &obj1)->isArray() || !setFillColor(&obj1)) + appearBuf->append("1 0.819611 0 rg"); + obj1.free(); + appearBuf->append(" 0 G 0 i 0.61 w 4 M 0 j 0 J [] 0 d q 1 0 0 1 16.959 1.3672 cm 0 0 m 0 -0.434 -0.352 -0.785 -0.784 -0.785 c -14.911 -0.785 l -15.345 -0.785 -15.696 -0.434 -15.696 0 c -15.696 17.266 l -15.696 17.699 -15.345 18.051 -14.911 18.051 c -0.784 18.051 l -0.352 18.051 0 17.699 0 17.266 c h b Q q 1 0 0 1 4.4023 13.9243 cm 0 0 m 9.418 0 l S Q q 1 0 0 1 4.4019 11.2207 cm 0 0 m 9.418 0 l S Q q 1 0 0 1 4.4023 8.5176 cm 0 0 m 9.418 0 l S Q q 1 0 0 1 4.4023 5.8135 cm 0 0 m 9.418 0 l S Q"); + } + else if (oName.isName("Paragraph")) + { + yMin = yMax - 20; + xMax = xMin + 20; + gfxStateDict.initDict(doc->getXRef()); + oAnnotObj.dictLookup("CA", &obj1); + gfxStateDict.dictAdd(copyString("ca"), obj1.isNum() ? obj1.copy(&obj2) : obj2.initReal(0.6)); + gfxStateDict.dictAdd(copyString("CA"), obj1.isNum() ? obj1.copy(&obj2) : obj2.initReal(0.6)); + obj1.free(); + appearBuf->append("q 1 1 1 rg 0 i 1 w 4 M 1 j 0 J [] 0 d /GS1 gs 1 0 0 1 19.6973 10.0005 cm 0 0 m 0 -5.336 -4.326 -9.662 -9.663 -9.662 c -14.998 -9.662 -19.324 -5.336 -19.324 0 c -19.324 5.335 -14.998 9.662 -9.663 9.662 c -4.326 9.662 0 5.335 0 0 c h f Q "); + if (!oAnnotObj.dictLookup("C", &obj1)->isArray() || !setFillColor(&obj1)) + appearBuf->append("1 0.819611 0 rg"); + obj1.free(); + appearBuf->append(" 0 G 0 i 0.59 w 4 M 1 j 0 J [] 0 d q 1 0 0 1 19.6973 10.0005 cm 0 0 m 0 -5.336 -4.326 -9.662 -9.663 -9.662 c -14.998 -9.662 -19.324 -5.336 -19.324 0 c -19.324 5.335 -14.998 9.662 -9.663 9.662 c -4.326 9.662 0 5.335 0 0 c h S Q q 1 0 0 1 11.6787 2.6582 cm 0 0 m -1.141 0 l -1.227 0 -1.244 0.052 -1.227 0.139 c -0.656 1.157 -0.52 2.505 -0.52 3.317 c -0.52 3.594 l -2.833 3.783 -5.441 4.838 -5.441 8.309 c -5.441 10.778 -3.714 12.626 -0.57 13.024 c -0.535 13.508 -0.381 14.129 -0.242 14.389 c -0.207 14.44 -0.174 14.475 -0.104 14.475 c 1.088 14.475 l 1.156 14.475 1.191 14.458 1.175 14.372 c 1.105 14.095 0.881 13.127 0.881 12.402 c 0.881 9.431 0.932 7.324 0.95 4.06 c 0.95 2.298 0.708 0.813 0.189 0.07 c 0.155 0.034 0.103 0 0 0 c b Q"); + } + else if (oName.isName("RightArrow")) + { + yMin = yMax - 20; + xMax = xMin + 20; + gfxStateDict.initDict(doc->getXRef()); + oAnnotObj.dictLookup("CA", &obj1); + gfxStateDict.dictAdd(copyString("ca"), obj1.isNum() ? obj1.copy(&obj2) : obj2.initReal(0.6)); + gfxStateDict.dictAdd(copyString("CA"), obj1.isNum() ? obj1.copy(&obj2) : obj2.initReal(0.6)); + obj1.free(); + appearBuf->append("q 1 1 1 rg 0 i 1 w 4 M 1 j 0 J [] 0 d /GS1 gs 1 0 0 1 3.7856 11.1963 cm 6.214 -10.655 m 11.438 -10.655 15.673 -6.42 15.673 -1.196 c 15.673 4.027 11.438 8.262 6.214 8.262 c 0.991 8.262 -3.244 4.027 -3.244 -1.196 c -3.244 -6.42 0.991 -10.655 6.214 -10.655 c h f Q "); + if (!oAnnotObj.dictLookup("C", &obj1)->isArray() || !setFillColor(&obj1)) + appearBuf->append("1 0.819611 0 rg"); + obj1.free(); + appearBuf->append(" 0 G 0 i 0.59 w 4 M 0 j 0 J [] 0 d 1 0 0 1 3.7856 11.1963 cm 0 0 m 8.554 0 l 6.045 2.51 l 7.236 3.702 l 12.135 -1.197 l 7.236 -6.096 l 6.088 -4.949 l 8.644 -2.394 l 0 -2.394 l h 6.214 -10.655 m 11.438 -10.655 15.673 -6.42 15.673 -1.196 c 15.673 4.027 11.438 8.262 6.214 8.262 c 0.991 8.262 -3.244 4.027 -3.244 -1.196 c -3.244 -6.42 0.991 -10.655 6.214 -10.655 c b"); + } + else if (oName.isName("RightPointer")) + { + yMin = yMax - 17; + xMax = xMin + 20; + if (!oAnnotObj.dictLookup("C", &obj1)->isArray() || !setFillColor(&obj1)) + appearBuf->append("1 0.819611 0 rg"); + obj1.free(); + appearBuf->append(" 0 G 0.59 w 4 M 0 j 0 J [] 0 d 1 0 0 1 1.1871 17.0000 cm 0 0 m 4.703 -8.703 l 0 -17 l 18.813 -8.703 l b"); + } + else if (oName.isName("Star")) + { + yMin = yMax - 19; + xMax = xMin + 20; + if (!oAnnotObj.dictLookup("C", &obj1)->isArray() || !setFillColor(&obj1)) + appearBuf->append("1 0.819611 0 rg"); + obj1.free(); + appearBuf->append(" 0 G 0 i 0.59 w 4 M 1 j 0 J [] 0 d 1 0 0 1 9.999 18.8838 cm 0 0 m 3.051 -6.178 l 9.867 -7.168 l 4.934 -11.978 l 6.099 -18.768 l 0 -15.562 l -6.097 -18.768 l -4.933 -11.978 l -9.866 -7.168 l -3.048 -6.178 l b"); + } + else if (oName.isName("UpArrow")) + { + yMin = yMax - 20; + xMax = xMin + 17; + if (!oAnnotObj.dictLookup("C", &obj1)->isArray() || !setFillColor(&obj1)) + appearBuf->append("1 0.819611 0 rg"); + obj1.free(); + appearBuf->append(" 0 G 0 i 0.59 w 4 M 1 j 0 J [] 0 d 1 0 0 1 1.1007 6.7185 cm 0 0 m 4.009 0 l 4.009 -6.719 l 11.086 -6.719 l 11.086 0 l 14.963 0 l 7.499 13.081 l b"); + } + else if (oName.isName("UpLeftArrow")) + { + yMin = yMax - 17; + xMax = xMin + 17; + if (!oAnnotObj.dictLookup("C", &obj1)->isArray() || !setFillColor(&obj1)) + appearBuf->append("1 0.819611 0 rg"); + obj1.free(); + appearBuf->append(" 0 G 0 i 0.59 w 4 M 1 j 0 J [] 0 d 1 0 0 1 2.8335 1.7627 cm 0 0 m -2.74 15.16 l 12.345 12.389 l 9.458 9.493 l 14.027 4.91 l 7.532 -1.607 l 2.964 2.975 l b"); + } + + oAnnotObj.free(); oName.free(); + + oAppearDict.initDict(doc->getXRef()); + oAppearDict.dictAdd(copyString("Length"), obj1.initInt(appearBuf->getLength())); + oAppearDict.dictAdd(copyString("Subtype"), obj1.initName("Form")); + obj1.initArray(doc->getXRef()); + obj1.arrayAdd(obj2.initReal(0)); + obj1.arrayAdd(obj2.initReal(0)); + obj1.arrayAdd(obj2.initReal(xMax - xMin)); + obj1.arrayAdd(obj2.initReal(yMax - yMin)); + oAppearDict.dictAdd(copyString("BBox"), &obj1); + if (gfxStateDict.isDict()) + { + obj1.initDict(doc->getXRef()); + obj2.initDict(doc->getXRef()); + obj2.dictAdd(copyString("GS1"), &gfxStateDict); + obj1.dictAdd(copyString("ExtGState"), &obj2); + oAppearDict.dictAdd(copyString("Resources"), &obj1); + } + + pAppearStream = new MemStream(appearBuf->getCString(), 0, appearBuf->getLength(), &oAppearDict); + appearance.free(); + appearance.initStream(pAppearStream); +} + void Annot::setLineStyle(AnnotBorderStyle *bs, double *lineWidth) { double *dash; double w; int dashLength, i; - if ((w = borderStyle->getWidth()) <= 0) { - w = 0.1; + w = 0.1; + if (borderStyle && borderStyle->getWidth() > 0) { + w = borderStyle->getWidth(); } *lineWidth = w; appearBuf->appendf("{0:.4f} w\n", w); // this treats beveled/inset/underline as solid - if (borderStyle->getType() == annotBorderDashed) { + if (borderStyle && borderStyle->getType() == annotBorderDashed) { borderStyle->getDash(&dash, &dashLength); appearBuf->append("["); for (i = 0; i < dashLength; ++i) { @@ -1127,11 +1391,11 @@ void Annot::drawCircleBottomRight(double cx, double cy, double r) { void Annot::drawText(GString *text, GString *da, int quadding, double margin, int rot) { GString *text2, *tok; - GList *daToks; + GList *daToks, *vBreaks; const char *charName; double dx, dy, fontSize, fontSize2, x, y, w; Gushort charWidth; - int tfPos, tmPos, i, j, c; + int rgPos, i, j, c; // check for a Unicode string //~ this currently drops all non-Latin1 characters @@ -1151,7 +1415,7 @@ void Annot::drawText(GString *text, GString *da, int quadding, double margin, } // parse the default appearance string - tfPos = tmPos = -1; + rgPos = -1; if (da) { daToks = new GList(); i = 0; @@ -1167,32 +1431,13 @@ void Annot::drawText(GString *text, GString *da, int quadding, double margin, i = j; } } - for (i = 2; i < daToks->getLength(); ++i) { - if (i >= 2 && !((GString *)daToks->get(i))->cmp("Tf")) { - tfPos = i - 2; - } else if (i >= 6 && !((GString *)daToks->get(i))->cmp("Tm")) { - tmPos = i - 6; - } + for (i = 0; i < daToks->getLength(); ++i) { + if (i >= 3 && !((GString *)daToks->get(i))->cmp("rg")) { + rgPos = i - 3; + } } } else { - daToks = NULL; - } - - // get the font and font size - fontSize = 0; - if (tfPos >= 0) { - //~ where do we look up the font? - tok = (GString *)daToks->get(tfPos); - tok->clear(); - tok->append("/xpdf_default_font"); - tok = (GString *)daToks->get(tfPos + 1); - fontSize = atof(tok->getCString()); - } else { - error(errSyntaxError, -1, - "Missing 'Tf' operator in annotation's DA string"); - daToks->append(new GString("/xpdf_default_font")); - daToks->append(new GString("10")); - daToks->append(new GString("Tf")); + daToks = new GList(); } // setup @@ -1204,7 +1449,7 @@ void Annot::drawText(GString *text, GString *da, int quadding, double margin, } else if (rot == 180) { appearBuf->appendf("-1 0 0 -1 {0:.4f} {1:.4f} cm\n", xMax - xMin, yMax - yMin); - dx = xMax - yMax; + dx = xMax - xMin; dy = yMax - yMin; } else if (rot == 270) { appearBuf->appendf("0 -1 1 0 0 {0:.4f} cm\n", yMax - yMin); @@ -1218,91 +1463,198 @@ void Annot::drawText(GString *text, GString *da, int quadding, double margin, // compute string width //~ this assumes we're substituting Helvetica/WinAnsiEncoding for everything - w = 0; - for (i = 0; i < text2->getLength(); ++i) { - charName = winAnsiEncoding[text->getChar(i) & 0xff]; - if (charName && builtinFonts[4].widths->getWidth(charName, &charWidth)) { - w += charWidth; - } else { - w += 0.5; - } - } + fontSize = 14; + i = 0; + vBreaks = new GList(); + double dX = 0, dWordWidth = 0, dKoef = fontSize / 1000.0; + unsigned int unWordStartPos = 0; + bool bLineStart = true, bWord = false, bFirstItemOnLine = true; + while (i < text2->getLength()) + { + charName = winAnsiEncoding[text->getChar(i) & 0xff]; + if (!charName || !builtinFonts[4].widths->getWidth(charName, &charWidth)) + charWidth = 500; + + char c = text->getChar(i); + if (c == 0x20) + { + dX += dWordWidth + charWidth * dKoef; + bWord = false; + dWordWidth = 0; + bLineStart = false; + bFirstItemOnLine = false; + } + else if (c == 0xA || c == 0xD) + { + bLineStart = true; + bFirstItemOnLine = true; + bWord = false; + dX = 0; + dWordWidth = 0; + vBreaks->append(new int(i + 1)); + } + else + { + double dLetterWidth = charWidth * dKoef; + if (dX + dWordWidth + dLetterWidth > dx - margin * 4) + { + if (bLineStart) + { + if (bFirstItemOnLine) + { + if (i != text2->getLength() - 1) + vBreaks->append(new int(i + 1)); + i++; + } + else + vBreaks->append(new int(i)); + } + else + { + if (bWord) + { + vBreaks->append(new int(unWordStartPos)); + i = unWordStartPos; + } + else + vBreaks->append(new int(i)); + } + + dX = 0; + bWord = false; + dWordWidth = 0; + bLineStart = true; + bFirstItemOnLine = true; + continue; + } + + if (bWord) + dWordWidth += charWidth * dKoef; + else + { + unWordStartPos = i; + bWord = true; + dWordWidth = charWidth * dKoef; + } + + bFirstItemOnLine = false; + } - // compute font autosize - if (fontSize == 0) { - fontSize = dy - 2 * margin; - fontSize2 = (dx - 2 * margin) / w; - if (fontSize2 < fontSize) { - fontSize = fontSize2; - } - fontSize = floor(fontSize); - if (tfPos >= 0) { - tok = (GString *)daToks->get(tfPos + 1); - tok->clear(); - tok->appendf("{0:.4f}", fontSize); - } + i++; } - // compute text start position - w *= fontSize; - switch (quadding) { - case 0: - default: - x = margin + 2; - break; - case 1: - x = (dx - w) / 2; - break; - case 2: - x = dx - margin - 2 - w; - break; - } - y = 0.5 * dy - 0.4 * fontSize; - - // set the font matrix - if (tmPos >= 0) { - tok = (GString *)daToks->get(tmPos + 4); - tok->clear(); - tok->appendf("{0:.4f}", x); - tok = (GString *)daToks->get(tmPos + 5); - tok->clear(); - tok->appendf("{0:.4f}", y); - } - // write the DA string - if (daToks) { - for (i = 0; i < daToks->getLength(); ++i) { - appearBuf->append((GString *)daToks->get(i))->append(' '); - } - } - - // write the font matrix (if not part of the DA string) - if (tmPos < 0) { - appearBuf->appendf("1 0 0 1 {0:.4f} {1:.4f} Tm\n", x, y); - } - - // write the text string - appearBuf->append('('); - for (i = 0; i < text2->getLength(); ++i) { - c = text2->getChar(i) & 0xff; - if (c == '(' || c == ')' || c == '\\') { - appearBuf->append('\\'); - appearBuf->append((char)c); - } else if (c < 0x20 || c >= 0x80) { - appearBuf->appendf("\\{0:03o}", c); - } else { - appearBuf->append((char)c); - } + appearBuf->append("/xpdf_default_font 14 Tf\n"); + if (rgPos > 0) { + appearBuf->append((GString *)daToks->get(rgPos))->append(' '); + appearBuf->append((GString *)daToks->get(rgPos + 1))->append(' '); + appearBuf->append((GString *)daToks->get(rgPos + 2))->append(' '); + appearBuf->append("rg\n"); + } + + unsigned int unLinesCount = vBreaks->getLength() + 1; + + double dShiftY = dy - margin - 2 - 0.789571 * fontSize; + double dLineHeight = 1.2 * fontSize; + double dCurX, dCurY; + bool bStart = true; + for (i = 0; i < unLinesCount; ++i) + { + int nLineStartPos = i == 0 ? 0 : *(int*)vBreaks->get(i - 1); + int nLineEndPos = i == vBreaks->getLength() ? text2->getLength() : *(int*)vBreaks->get(i); + int nInLineCount = nLineEndPos - nLineStartPos; + + if (nInLineCount > 0) + { + // compute width + w = 0; + int nStart = nLineStartPos, nEnd = nLineEndPos; + while (nStart < nEnd) + { + char c = text->getChar(nStart); + if (c == 0x20) + nStart++; + else + break; + } + + while (nEnd > nStart && nEnd > 0) + { + char c = text->getChar(nEnd - 1); + if (c == 0x20) + nEnd--; + else + break; + } + + for (unsigned int unPos = nStart; unPos < nEnd; ++unPos) + { + charName = winAnsiEncoding[text->getChar(unPos) & 0xff]; + if (!charName || !builtinFonts[4].widths->getWidth(charName, &charWidth)) + charWidth = 500; + w += charWidth * dKoef; + } + + // compute text start position + x = margin * 2; + if (2 == quadding) + x = dx - w - margin * 2; + else if (1 == quadding) + x = (dx - w) / 2; + y = dShiftY; + + if (bStart) + { + dCurX = x; + dCurY = y; + } + else + { + x -= dCurX; + y -= dCurY; + + dCurX += x; + dCurY += y; + } + bStart = false; + + // write the font matrix + appearBuf->appendf("{0:.4f} {1:.4f} Td\n", x, y); + + // write the text string + appearBuf->append('('); + for (int j = nLineStartPos; j < nLineEndPos; ++j) { + c = text2->getChar(j) & 0xff; + if (c == '(' || c == ')' || c == '\\') { + appearBuf->append('\\'); + appearBuf->append((char)c); + } else if (c < 0x20 || c >= 0x80) { + appearBuf->appendf("\\{0:03o}", c); + } else { + appearBuf->append((char)c); + } + } + appearBuf->append(") Tj\n"); + } + dShiftY -= dLineHeight; } - appearBuf->append(") Tj\n"); // cleanup appearBuf->append("ET\n"); appearBuf->append("Q\n"); + if (rgPos > 0) { + appearBuf->append((GString *)daToks->get(rgPos))->append(' '); + appearBuf->append((GString *)daToks->get(rgPos + 1))->append(' '); + appearBuf->append((GString *)daToks->get(rgPos + 2))->append(' '); + appearBuf->append("RG\n"); + } + if (daToks) { deleteGList(daToks, GString); } + if (vBreaks) + deleteGList(vBreaks, int); if (text2 != text) { delete text2; } @@ -1325,6 +1677,13 @@ void Annot::draw(Gfx *gfx, GBool printing) { // draw the appearance stream isLink = type && !type->cmp("Link"); +#ifdef BUILDING_WASM_MODULE + if (type && !type->cmp("Stamp")) + { + gfx->drawStamp(&appearance); + return; + } +#endif gfx->drawAnnot(&appearance, isLink ? borderStyle : (AnnotBorderStyle *)NULL, xMin, yMin, xMax, yMax); } diff --git a/PdfFile/lib/xpdf/Annot.h b/PdfFile/lib/xpdf/Annot.h index aac4714156c..3f8cc967dbc 100644 --- a/PdfFile/lib/xpdf/Annot.h +++ b/PdfFile/lib/xpdf/Annot.h @@ -113,6 +113,7 @@ class Annot { void generatePolyLineAppearance(); void generatePolygonAppearance(); void generateFreeTextAppearance(); + void generateTextAppearance(); void setLineStyle(AnnotBorderStyle *bs, double *lineWidth); void setStrokeColor(double *color, int nComps); GBool setFillColor(Object *colorObj); diff --git a/PdfFile/lib/xpdf/Decrypt.cc b/PdfFile/lib/xpdf/Decrypt.cc index d4f8d4ec336..7c5468563ba 100644 --- a/PdfFile/lib/xpdf/Decrypt.cc +++ b/PdfFile/lib/xpdf/Decrypt.cc @@ -17,6 +17,14 @@ #include "gmempp.h" #include "Decrypt.h" +#ifdef USE_OPENSSL_HASH +#include "../../../Common/3dParty/openssl/openssl/crypto/sha/sha512.c" +#include "../../../Common/3dParty/openssl/openssl/crypto/mem_clr.c" +#else +#define SHA384 sha384 +#define SHA512 sha512 +#endif + static void aes256KeyExpansion(DecryptAES256State *s, Guchar *objKey, int objKeyLen); static void aes256DecryptBlock(DecryptAES256State *s, Guchar *in, GBool last); @@ -230,11 +238,11 @@ void Decrypt::r6Hash(Guchar *key, int keyLen, const char *pwd, int pwdLen, keyLen = 32; break; case 1: - sha384(key1, n, key); + SHA384(key1, n, key); keyLen = 48; break; case 2: - sha512(key1, n, key); + SHA512(key1, n, key); keyLen = 64; break; } diff --git a/PdfFile/lib/xpdf/Gfx.cc b/PdfFile/lib/xpdf/Gfx.cc index 4bfebe6c619..abb942b6765 100644 --- a/PdfFile/lib/xpdf/Gfx.cc +++ b/PdfFile/lib/xpdf/Gfx.cc @@ -2190,7 +2190,7 @@ void Gfx::doTilingPatternFill(GfxTilingPattern *tPat, for (i = 0; i < 4; ++i) { m1[i] = m[i]; } - if (out->useTilingPatternFill()) { + if (out->useTilingPatternFill() && fabs(bbox[2] - bbox[0] - xstep) < 0.001 && fabs(bbox[3] - bbox[1] - ystep) < 0.001) { m1[4] = m[4]; m1[5] = m[5]; out->tilingPatternFill(state, this, tPat->getContentStreamRef(), @@ -4161,10 +4161,10 @@ GBool Gfx::doImage(Object *ref, Stream *str, GBool inlineImg) { obj1.free(); dict->lookup("W", &obj1); } - if (!obj1.isInt()) { + if (!obj1.isNum()) { goto err2; } - width = obj1.getInt(); + width = obj1.getNum(); obj1.free(); if (width <= 0) { goto err1; @@ -4174,10 +4174,10 @@ GBool Gfx::doImage(Object *ref, Stream *str, GBool inlineImg) { obj1.free(); dict->lookup("H", &obj1); } - if (!obj1.isInt()) { + if (!obj1.isNum()) { goto err2; } - height = obj1.getInt(); + height = obj1.getNum(); obj1.free(); if (height <= 0) { goto err1; @@ -4289,15 +4289,32 @@ GBool Gfx::doImage(Object *ref, Stream *str, GBool inlineImg) { obj2.free(); } } - if (!obj1.isNull()) { - colorSpace = GfxColorSpace::parse(&obj1 - ); + + GBool haveRGBA = gFalse; + if (str->getKind() == strJPX && (csMode == streamCSDeviceRGB || csMode == streamCSDeviceCMYK)) { + // Case of transparent JPX image, they may contain RGBA data when SMaskInData=1 + Object smaskInData; + dict->lookup("SMaskInData", &smaskInData); + haveRGBA = smaskInData.isInt() && smaskInData.getInt(); + smaskInData.free(); + } + + if (!obj1.isNull() && !haveRGBA) { + colorSpace = GfxColorSpace::parse(&obj1); } else if (csMode == streamCSDeviceGray) { colorSpace = GfxColorSpace::create(csDeviceGray); } else if (csMode == streamCSDeviceRGB) { - colorSpace = GfxColorSpace::create(csDeviceRGB); + if (haveRGBA) { + colorSpace = GfxColorSpace::create(csDeviceRGBA); + } else { + colorSpace = GfxColorSpace::create(csDeviceRGB); + } } else if (csMode == streamCSDeviceCMYK) { - colorSpace = GfxColorSpace::create(csDeviceCMYK); + if (haveRGBA) { + colorSpace = GfxColorSpace::create(csDeviceRGBA); + } else { + colorSpace = GfxColorSpace::create(csDeviceCMYK); + } } else { colorSpace = NULL; } @@ -4345,26 +4362,26 @@ GBool Gfx::doImage(Object *ref, Stream *str, GBool inlineImg) { obj1.free(); maskDict->lookup("W", &obj1); } - if (!obj1.isInt()) { + if (!obj1.isNum()) { delete colorMap; maskObj.free(); smaskObj.free(); goto err2; } - maskWidth = obj1.getInt(); + maskWidth = obj1.getNum(); obj1.free(); maskDict->lookup("Height", &obj1); if (obj1.isNull()) { obj1.free(); maskDict->lookup("H", &obj1); } - if (!obj1.isInt()) { + if (!obj1.isNum()) { delete colorMap; maskObj.free(); smaskObj.free(); goto err2; } - maskHeight = obj1.getInt(); + maskHeight = obj1.getNum(); obj1.free(); if (maskWidth <= 0 || maskHeight <= 0) { delete colorMap; @@ -4493,26 +4510,26 @@ GBool Gfx::doImage(Object *ref, Stream *str, GBool inlineImg) { obj1.free(); maskDict->lookup("W", &obj1); } - if (!obj1.isInt()) { + if (!obj1.isNum()) { delete colorMap; maskObj.free(); smaskObj.free(); goto err2; } - maskWidth = obj1.getInt(); + maskWidth = obj1.getNum(); obj1.free(); maskDict->lookup("Height", &obj1); if (obj1.isNull()) { obj1.free(); maskDict->lookup("H", &obj1); } - if (!obj1.isInt()) { + if (!obj1.isNum()) { delete colorMap; maskObj.free(); smaskObj.free(); goto err2; } - maskHeight = obj1.getInt(); + maskHeight = obj1.getNum(); obj1.free(); if (maskWidth <= 0 || maskHeight <= 0) { delete colorMap; @@ -4770,7 +4787,6 @@ void Gfx::drawForm(Object *strRef, Dict *resDict, strObj.free(); traceBegin(oldBaseMatrix, softMask ? "begin soft mask" : "begin t-group"); - /* if (state->getBlendMode() != gfxBlendNormal) { state->setBlendMode(gfxBlendNormal); out->updateBlendMode(state); @@ -4783,7 +4799,6 @@ void Gfx::drawForm(Object *strRef, Dict *resDict, state->setStrokeOpacity(1); out->updateStrokeOpacity(state); } - */ out->clearSoftMask(state); out->beginTransparencyGroup(state, bbox, blendingColorSpace, isolated, knockout, softMask); @@ -5053,6 +5068,30 @@ void Gfx::opBeginMarkedContent(Object args[], int numArgs) { mcKind = gfxMCActualText; } obj.free(); + } else if (args[0].isName("OShapes") && numArgs == 2 && args[1].isDict() && res->lookupPropertiesNF("OShapes", &obj)) { + Object oMetaOForm, oID, oTID, oID2, oIDF, oIDF2, oMCID, oMetadata, oMetadataCur; + if (obj.fetch(xref, &oMetaOForm)->isDict("OShapes") && args[1].dictLookup("IDF", &oIDF)->isString() && oMetaOForm.dictLookup("IDF", &oIDF2)->isString() && + oIDF.getString()->cmp(oIDF2.getString()) == 0 && oMetaOForm.dictLookup("ID", &oID)->isString() && xref->getTrailerDict()->dictLookup("ID", &oTID)->isArray() && + oTID.arrayGet(1, &oID2)->isString() && oID2.getString()->cmp(oID.getString()) == 0 && args[1].dictLookup("MCID", &oMCID)->isInt() && + oMetaOForm.dictLookup("Metadata", &oMetadata)->isArray() && oMetadata.arrayGet(oMCID.getInt(), &oMetadataCur)->isString()) { + oID.free(); oTID.free(); oID2.free(); oIDF.free(); oIDF2.free(); oMCID.free(); oMetadata.free(); obj.free(); + Object oImRef, oArrImage; + if (!oMetaOForm.dictLookup("Image", &oArrImage)->isArray() || !oArrImage.arrayGetNF(oMCID.getInt(), &oImRef)->isRef()) + oImRef.free(); + if (out->beginMCOShapes(state, oMetadataCur.getString(), &oImRef)) { + getContentObj(&obj); + while (!obj.isEOF() && !obj.isCmd("EMC")) { + obj.free(); + getContentObj(&obj); + } + out->endMarkedContent(state); + oImRef.free(); oArrImage.free(); + oMetaOForm.free(); oMetadataCur.free(); obj.free(); + return; + } + oImRef.free(); oArrImage.free(); + } + oMetaOForm.free(); oID.free(); oTID.free(); oID2.free(); oIDF.free(); oIDF2.free(); oMCID.free(), oMetadata.free(); oMetadataCur.free(); obj.free(); } mc = new GfxMarkedContent(mcKind, ocState); markedContentStack->append(mc); @@ -5296,6 +5335,54 @@ void Gfx::drawAnnot(Object *strRef, AnnotBorderStyle *borderStyle, } } +void Gfx::drawStamp(Object *strRef) +{ + Dict *dict, *resDict; + Object str, bboxObj, resObj, obj1; + double m[6], bbox[4]; + int i; + + // draw the appearance stream (if there is one) + strRef->fetch(xref, &str); + if (str.isStream()) { + // get stream dict + dict = str.streamGetDict(); + + // get the form bounding box + dict->lookup("BBox", &bboxObj); + if (!bboxObj.isArray() || bboxObj.arrayGetLength() != 4) { + error(errSyntaxError, getPos(), "Bad form bounding box"); + bboxObj.free(); + str.free(); + return; + } + for (i = 0; i < 4; ++i) { + bboxObj.arrayGet(i, &obj1); + if (obj1.isNum()) { + bbox[i] = obj1.getNum(); + } else { + bbox[i] = 0; + } + obj1.free(); + } + bboxObj.free(); + + m[0] = 1; m[1] = 0; + m[2] = 0; m[3] = 1; + m[4] = 0; m[5] = 0; + + // get the resources + dict->lookup("Resources", &resObj); + resDict = resObj.isDict() ? resObj.getDict() : (Dict *)NULL; + + // draw it + drawForm(strRef, resDict, m, bbox); + + resObj.free(); + } + str.free(); +} + void Gfx::saveState() { out->saveState(state); state = state->save(); diff --git a/PdfFile/lib/xpdf/Gfx.h b/PdfFile/lib/xpdf/Gfx.h index 4e90a23eb85..bdc03da3110 100644 --- a/PdfFile/lib/xpdf/Gfx.h +++ b/PdfFile/lib/xpdf/Gfx.h @@ -153,6 +153,7 @@ class Gfx { // border style, and bounding box (in default user space). void drawAnnot(Object *strRef, AnnotBorderStyle *borderStyle, double xMin, double yMin, double xMax, double yMax); + void drawStamp(Object *strRef); // Save graphics state. void saveState(); diff --git a/PdfFile/lib/xpdf/GfxState.cc b/PdfFile/lib/xpdf/GfxState.cc index 0d8edd55872..d30414d96b5 100644 --- a/PdfFile/lib/xpdf/GfxState.cc +++ b/PdfFile/lib/xpdf/GfxState.cc @@ -174,6 +174,8 @@ GfxColorSpace *GfxColorSpace::create(GfxColorSpaceMode mode) { cs = new GfxDeviceRGBColorSpace(); } else if (mode == csDeviceCMYK) { cs = new GfxDeviceCMYKColorSpace(); + } else if (mode == csDeviceRGBA) { + cs = new GfxDeviceRGBAColorSpace(); } return cs; } @@ -395,6 +397,24 @@ void GfxDeviceRGBColorSpace::getDefaultColor(GfxColor *color) { color->c[2] = 0; } +//------------------------------------------------------------------------ +// GfxDeviceRGBAColorSpace +//------------------------------------------------------------------------ + +GfxDeviceRGBAColorSpace::GfxDeviceRGBAColorSpace() { +} + +GfxDeviceRGBAColorSpace::~GfxDeviceRGBAColorSpace() { +} + +GfxColorSpace* GfxDeviceRGBAColorSpace::copy() +{ + GfxDeviceRGBAColorSpace *cs; + + cs = new GfxDeviceRGBAColorSpace(); + return cs; +} + //------------------------------------------------------------------------ // GfxCalRGBColorSpace //------------------------------------------------------------------------ @@ -568,18 +588,829 @@ void GfxDeviceCMYKColorSpace::getGray(GfxColor *color, GfxGray *gray, - 0.11 * color->c[2] + 0.5)); } +const Guchar g_CMYKSamples[81 * 81 * 3] = { + 255, 255, 255, 225, 226, 228, 199, 200, 202, 173, 174, 178, 147, 149, 152, 123, 125, 128, 99, 99, 102, 69, 70, 71, 34, 30, 31, + 255, 253, 229, 226, 224, 203, 200, 199, 182, 173, 173, 158, 149, 148, 135, 125, 124, 113, 99, 99, 90, 70, 69, 63, 33, 29, 24, + 255, 251, 204, 228, 223, 182, 201, 198, 163, 174, 172, 142, 150, 147, 122, 125, 123, 101, 99, 98, 80, 70, 68, 54, 32, 28, 16, + 255, 249, 179, 230, 222, 160, 203, 197, 144, 174, 170, 124, 150, 145, 105, 125, 122, 88, 99, 97, 69, 70, 68, 46, 31, 28, 6, + 255, 247, 154, 229, 220, 138, 203, 195, 122, 176, 169, 107, 150, 145, 91, 125, 121, 74, 100, 96, 57, 70, 67, 35, 29, 26, 0, + 255, 246, 128, 231, 217, 114, 205, 194, 101, 176, 167, 88, 150, 144, 75, 125, 120, 60, 100, 96, 44, 70, 66, 24, 28, 26, 0, + 255, 244, 96, 231, 217, 87, 203, 192, 78, 175, 167, 66, 150, 143, 56, 125, 119, 43, 100, 95, 29, 69, 66, 7, 26, 26, 0, + 255, 243, 51, 232, 215, 51, 204, 191, 43, 176, 165, 38, 150, 142, 28, 125, 118, 17, 99, 94, 0, 68, 65, 0, 24, 25, 0, + 255, 241, 0, 231, 215, 0, 203, 190, 0, 176, 164, 0, 150, 141, 0, 126, 117, 0, 99, 93, 0, 68, 65, 0, 24, 25, 0, + 252, 228, 238, 222, 201, 211, 197, 180, 190, 171, 156, 166, 147, 133, 143, 123, 111, 119, 99, 88, 94, 71, 61, 66, 34, 22, 26, + 254, 226, 213, 224, 201, 191, 199, 179, 171, 172, 155, 148, 147, 133, 128, 123, 110, 106, 98, 87, 83, 70, 59, 57, 33, 21, 18, + 254, 224, 191, 224, 199, 172, 200, 177, 153, 173, 154, 133, 147, 132, 115, 123, 109, 94, 98, 86, 74, 70, 59, 49, 32, 21, 9, + 255, 222, 168, 227, 198, 150, 200, 175, 135, 173, 153, 118, 148, 130, 99, 123, 109, 82, 98, 86, 64, 69, 58, 40, 31, 19, 0, + 255, 221, 145, 227, 196, 129, 201, 174, 115, 173, 151, 99, 148, 129, 85, 124, 108, 69, 98, 85, 52, 69, 58, 30, 30, 19, 0, + 255, 219, 121, 227, 195, 109, 201, 174, 97, 174, 150, 83, 148, 129, 70, 124, 107, 55, 98, 84, 40, 69, 58, 19, 28, 18, 0, + 255, 218, 92, 229, 194, 82, 202, 173, 75, 174, 150, 63, 149, 128, 51, 124, 106, 39, 98, 84, 24, 68, 57, 3, 26, 18, 0, + 255, 217, 54, 228, 193, 52, 201, 172, 46, 174, 148, 36, 148, 127, 27, 123, 105, 14, 98, 83, 0, 68, 56, 0, 25, 18, 0, + 255, 216, 0, 229, 192, 2, 202, 171, 4, 173, 148, 0, 148, 126, 0, 124, 105, 0, 98, 83, 0, 68, 56, 0, 24, 17, 0, + 249, 204, 223, 219, 181, 199, 195, 160, 178, 170, 140, 156, 146, 119, 134, 123, 99, 112, 98, 77, 88, 70, 52, 61, 34, 11, 20, + 250, 201, 200, 221, 180, 178, 197, 159, 161, 171, 139, 139, 147, 119, 120, 123, 98, 99, 98, 77, 78, 69, 51, 52, 34, 11, 10, + 252, 201, 180, 223, 179, 162, 197, 159, 144, 170, 138, 125, 146, 117, 107, 122, 97, 89, 98, 76, 69, 69, 50, 44, 32, 11, 2, + 252, 199, 158, 222, 177, 143, 199, 158, 127, 171, 137, 110, 147, 117, 93, 122, 96, 76, 97, 75, 58, 69, 50, 36, 32, 10, 0, + 253, 198, 137, 223, 177, 123, 198, 156, 110, 171, 136, 95, 146, 116, 80, 122, 96, 65, 97, 75, 47, 69, 50, 25, 30, 10, 0, + 254, 197, 115, 225, 175, 104, 198, 156, 92, 172, 135, 79, 147, 115, 66, 123, 95, 52, 98, 74, 37, 69, 49, 15, 29, 10, 0, + 254, 196, 89, 224, 175, 80, 199, 154, 70, 172, 134, 59, 146, 114, 48, 122, 95, 36, 97, 74, 21, 68, 49, 0, 27, 9, 0, + 255, 195, 57, 225, 173, 52, 198, 154, 44, 172, 133, 36, 147, 113, 26, 123, 94, 14, 98, 74, 0, 68, 49, 0, 26, 10, 0, + 254, 194, 15, 225, 172, 12, 198, 153, 7, 172, 132, 3, 146, 113, 0, 123, 93, 0, 98, 73, 0, 68, 49, 0, 26, 9, 0, + 246, 178, 209, 218, 159, 186, 194, 140, 166, 168, 122, 145, 144, 104, 125, 121, 85, 103, 97, 65, 81, 69, 41, 55, 34, 0, 12, + 248, 176, 186, 219, 157, 166, 195, 139, 149, 168, 121, 130, 144, 103, 111, 121, 85, 91, 97, 65, 71, 69, 41, 46, 34, 0, 4, + 249, 175, 168, 220, 156, 150, 196, 139, 135, 169, 121, 116, 144, 103, 100, 122, 84, 83, 98, 65, 63, 70, 41, 39, 33, 0, 0, + 249, 175, 148, 220, 155, 133, 196, 138, 119, 169, 120, 103, 145, 101, 87, 121, 83, 71, 97, 65, 54, 69, 41, 31, 32, 0, 0, + 249, 173, 128, 222, 154, 115, 195, 137, 102, 170, 119, 88, 145, 101, 74, 122, 83, 59, 97, 64, 43, 68, 40, 20, 30, 0, 0, + 250, 172, 108, 221, 154, 98, 195, 136, 86, 170, 118, 73, 145, 100, 61, 122, 82, 48, 97, 63, 32, 69, 40, 11, 28, 0, 0, + 250, 171, 85, 221, 153, 76, 196, 136, 67, 170, 117, 56, 145, 99, 44, 121, 82, 33, 97, 63, 17, 68, 40, 0, 28, 0, 0, + 251, 171, 58, 222, 152, 50, 197, 135, 43, 169, 117, 34, 146, 99, 25, 121, 81, 10, 96, 63, 0, 68, 40, 0, 27, 0, 0, + 250, 170, 26, 222, 151, 19, 196, 134, 13, 169, 116, 4, 145, 99, 0, 122, 81, 0, 97, 63, 0, 67, 40, 0, 26, 0, 0, + 244, 153, 194, 215, 136, 173, 192, 121, 155, 167, 104, 135, 143, 89, 115, 121, 72, 96, 97, 54, 75, 70, 31, 49, 34, 0, 6, + 245, 153, 173, 216, 136, 155, 192, 120, 138, 167, 104, 121, 144, 88, 103, 121, 71, 85, 97, 54, 66, 69, 31, 42, 34, 0, 0, + 246, 152, 157, 217, 135, 140, 193, 120, 126, 167, 103, 109, 143, 88, 92, 121, 72, 76, 97, 54, 58, 69, 31, 35, 33, 0, 0, + 245, 150, 139, 218, 134, 125, 193, 119, 111, 167, 103, 96, 144, 87, 80, 121, 71, 66, 96, 53, 49, 68, 31, 26, 32, 0, 0, + 246, 151, 122, 218, 133, 108, 194, 118, 96, 168, 102, 81, 144, 86, 69, 120, 71, 55, 95, 53, 39, 68, 30, 17, 31, 0, 0, + 248, 150, 103, 218, 133, 91, 193, 118, 81, 168, 102, 69, 143, 86, 56, 120, 70, 43, 96, 53, 28, 68, 31, 6, 29, 0, 0, + 247, 149, 81, 218, 132, 72, 194, 117, 62, 168, 101, 52, 144, 86, 42, 121, 70, 29, 96, 52, 13, 68, 30, 0, 28, 0, 0, + 247, 148, 55, 219, 131, 50, 194, 117, 43, 167, 101, 32, 144, 85, 22, 120, 69, 8, 96, 52, 0, 67, 30, 0, 27, 0, 0, + 247, 147, 29, 218, 131, 24, 194, 116, 20, 168, 100, 11, 144, 85, 0, 120, 69, 0, 96, 52, 0, 67, 30, 0, 26, 0, 0, + 242, 130, 179, 214, 114, 160, 190, 101, 143, 166, 87, 125, 143, 72, 107, 120, 58, 88, 96, 42, 68, 69, 17, 44, 35, 0, 0, + 243, 129, 161, 215, 114, 143, 191, 101, 128, 166, 87, 113, 143, 73, 96, 120, 58, 79, 96, 41, 60, 69, 18, 37, 33, 0, 0, + 243, 129, 146, 216, 114, 130, 192, 101, 117, 166, 87, 101, 143, 72, 86, 121, 58, 69, 96, 42, 52, 69, 18, 29, 31, 0, 0, + 243, 128, 130, 216, 114, 115, 191, 101, 102, 165, 86, 88, 142, 72, 75, 120, 58, 60, 95, 42, 43, 68, 19, 21, 30, 0, 0, + 244, 127, 112, 217, 113, 101, 192, 99, 89, 166, 85, 75, 142, 72, 63, 119, 57, 50, 96, 41, 35, 68, 19, 13, 30, 0, 0, + 244, 127, 96, 216, 112, 86, 191, 99, 75, 166, 86, 64, 143, 72, 52, 120, 57, 40, 95, 41, 24, 67, 20, 1, 29, 0, 0, + 245, 126, 77, 216, 113, 68, 191, 100, 59, 166, 85, 49, 142, 71, 38, 119, 57, 26, 95, 41, 10, 67, 20, 0, 28, 0, 0, + 244, 126, 55, 216, 112, 48, 191, 99, 40, 166, 85, 31, 143, 71, 20, 119, 57, 6, 95, 42, 0, 67, 20, 0, 28, 0, 0, + 245, 126, 33, 217, 112, 26, 192, 99, 22, 166, 84, 11, 142, 70, 0, 119, 57, 0, 95, 41, 0, 66, 20, 0, 27, 0, 0, + 241, 102, 167, 213, 90, 149, 189, 79, 133, 165, 66, 115, 141, 54, 98, 119, 41, 81, 96, 25, 63, 69, 0, 38, 30, 0, 0, + 241, 102, 149, 213, 90, 133, 189, 79, 119, 165, 66, 103, 142, 55, 88, 119, 41, 71, 96, 25, 53, 69, 0, 31, 28, 0, 0, + 241, 102, 135, 214, 90, 121, 190, 79, 108, 165, 66, 92, 141, 55, 78, 119, 42, 63, 96, 26, 46, 69, 0, 24, 28, 0, 0, + 241, 101, 120, 214, 90, 107, 189, 79, 95, 165, 67, 83, 141, 54, 68, 118, 41, 54, 95, 27, 39, 68, 0, 16, 27, 0, 0, + 241, 102, 106, 213, 90, 93, 189, 78, 82, 164, 67, 70, 141, 55, 58, 118, 42, 45, 94, 27, 29, 67, 2, 6, 27, 0, 0, + 242, 101, 90, 214, 89, 79, 190, 79, 69, 166, 67, 59, 141, 55, 47, 118, 41, 35, 95, 27, 19, 67, 3, 0, 26, 0, 0, + 242, 102, 72, 213, 89, 63, 191, 79, 56, 164, 67, 45, 141, 55, 34, 118, 42, 22, 94, 28, 6, 67, 3, 0, 26, 0, 0, + 242, 100, 51, 214, 89, 45, 190, 78, 38, 164, 67, 30, 141, 55, 18, 118, 42, 3, 95, 28, 0, 66, 4, 0, 26, 0, 0, + 243, 100, 33, 214, 90, 27, 190, 78, 22, 165, 67, 13, 141, 55, 0, 118, 43, 0, 94, 29, 0, 66, 5, 0, 26, 0, 0, + 237, 69, 153, 211, 58, 135, 187, 51, 121, 163, 41, 105, 141, 28, 90, 118, 15, 73, 96, 0, 56, 68, 0, 33, 25, 0, 0, + 239, 67, 137, 212, 60, 123, 189, 50, 110, 163, 41, 94, 141, 29, 79, 118, 17, 65, 95, 0, 48, 69, 0, 26, 25, 0, 0, + 240, 69, 124, 211, 60, 111, 188, 50, 98, 163, 42, 85, 141, 31, 72, 118, 18, 57, 94, 0, 41, 68, 0, 19, 25, 0, 0, + 240, 70, 112, 212, 61, 99, 188, 52, 87, 163, 41, 74, 140, 31, 62, 118, 20, 48, 94, 2, 32, 68, 0, 11, 24, 0, 0, + 239, 70, 98, 212, 62, 86, 188, 53, 77, 164, 42, 64, 140, 32, 52, 118, 20, 40, 94, 3, 24, 67, 0, 3, 23, 0, 0, + 239, 71, 85, 212, 61, 74, 187, 53, 65, 163, 44, 54, 140, 34, 43, 118, 22, 30, 95, 3, 14, 67, 0, 0, 23, 0, 0, + 239, 70, 67, 212, 62, 59, 188, 53, 51, 163, 45, 42, 141, 34, 31, 117, 22, 17, 94, 5, 2, 66, 0, 0, 23, 0, 0, + 239, 71, 50, 213, 62, 43, 188, 54, 37, 164, 45, 28, 139, 34, 16, 117, 22, 2, 94, 7, 0, 65, 0, 0, 23, 0, 0, + 240, 71, 34, 212, 63, 29, 189, 54, 24, 163, 46, 15, 139, 36, 2, 117, 25, 0, 94, 8, 0, 66, 0, 0, 23, 0, 0, + 237, 0, 140, 209, 0, 124, 186, 0, 112, 162, 0, 97, 141, 0, 82, 118, 0, 67, 95, 0, 49, 68, 0, 27, 20, 0, 0, + 237, 0, 126, 210, 0, 113, 187, 0, 99, 163, 0, 86, 139, 0, 72, 118, 0, 58, 95, 0, 42, 67, 0, 20, 20, 0, 0, + 237, 1, 114, 209, 1, 102, 187, 0, 90, 163, 0, 78, 139, 0, 64, 118, 0, 50, 95, 0, 35, 67, 0, 13, 20, 0, 0, + 236, 16, 102, 209, 7, 91, 186, 0, 80, 162, 0, 68, 139, 0, 56, 117, 0, 43, 94, 0, 27, 67, 0, 6, 20, 0, 0, + 238, 15, 89, 209, 13, 79, 186, 6, 69, 162, 0, 58, 139, 0, 47, 117, 0, 34, 93, 0, 20, 66, 0, 2, 20, 0, 0, + 237, 20, 78, 210, 12, 68, 187, 4, 59, 163, 0, 49, 139, 0, 38, 116, 0, 26, 94, 0, 11, 66, 0, 0, 20, 0, 0, + 237, 25, 64, 210, 18, 56, 186, 11, 48, 162, 4, 39, 138, 0, 27, 117, 0, 14, 93, 0, 0, 66, 0, 0, 20, 0, 0, + 238, 25, 48, 210, 22, 43, 186, 15, 35, 162, 8, 26, 140, 0, 14, 117, 0, 0, 93, 0, 0, 65, 0, 0, 20, 0, 0, + 238, 28, 35, 210, 21, 30, 187, 15, 24, 162, 8, 16, 139, 1, 2, 117, 0, 0, 93, 0, 0, 65, 0, 0, 22, 0, 0, + 219, 242, 252, 195, 214, 225, 172, 191, 201, 148, 165, 175, 127, 142, 150, 106, 119, 126, 84, 95, 101, 58, 66, 72, 24, 27, 32, + 222, 239, 226, 196, 213, 202, 173, 189, 180, 150, 165, 158, 129, 141, 135, 107, 118, 113, 85, 94, 90, 58, 66, 63, 21, 26, 24, + 223, 237, 203, 198, 211, 182, 175, 188, 163, 152, 164, 141, 129, 140, 121, 107, 117, 101, 85, 93, 80, 58, 64, 54, 21, 26, 18, + 226, 236, 179, 201, 210, 160, 177, 187, 143, 153, 162, 125, 130, 139, 106, 108, 116, 89, 85, 92, 69, 58, 64, 45, 20, 25, 8, + 227, 234, 153, 201, 208, 139, 178, 185, 124, 154, 161, 107, 131, 138, 91, 108, 115, 75, 85, 91, 58, 58, 63, 35, 17, 25, 0, + 229, 233, 130, 203, 207, 116, 178, 184, 104, 154, 160, 90, 131, 137, 76, 109, 114, 62, 85, 90, 46, 58, 63, 25, 16, 24, 0, + 230, 231, 100, 202, 205, 90, 179, 183, 80, 154, 159, 69, 131, 136, 57, 109, 113, 46, 86, 90, 32, 58, 63, 10, 14, 24, 0, + 230, 230, 65, 204, 204, 58, 180, 182, 52, 155, 157, 44, 132, 135, 35, 110, 113, 24, 86, 89, 9, 57, 62, 0, 11, 24, 0, + 232, 230, 19, 204, 204, 19, 180, 181, 17, 155, 157, 10, 131, 134, 2, 109, 112, 0, 85, 89, 0, 57, 62, 0, 10, 23, 0, + 218, 216, 236, 194, 192, 211, 172, 171, 188, 149, 149, 164, 128, 127, 141, 106, 106, 119, 84, 84, 94, 59, 57, 66, 25, 18, 26, + 221, 214, 211, 196, 191, 190, 174, 170, 170, 150, 148, 148, 128, 126, 127, 107, 105, 106, 85, 83, 84, 59, 56, 58, 23, 17, 18, + 222, 213, 190, 197, 189, 170, 175, 169, 153, 151, 147, 133, 129, 126, 113, 108, 105, 94, 85, 82, 74, 59, 56, 49, 22, 17, 11, + 224, 211, 168, 199, 188, 151, 175, 168, 135, 152, 146, 117, 129, 124, 99, 107, 103, 82, 84, 82, 64, 59, 55, 41, 21, 17, 1, + 224, 210, 145, 199, 187, 130, 176, 166, 117, 152, 145, 101, 129, 123, 86, 107, 103, 70, 85, 81, 53, 58, 55, 31, 19, 17, 0, + 227, 208, 123, 200, 186, 110, 177, 165, 98, 153, 143, 84, 130, 122, 70, 108, 102, 57, 85, 80, 41, 58, 54, 20, 18, 16, 0, + 227, 208, 97, 202, 185, 86, 177, 164, 77, 153, 142, 65, 130, 122, 54, 108, 101, 42, 85, 80, 27, 58, 54, 7, 16, 16, 0, + 228, 206, 66, 202, 184, 58, 178, 163, 50, 154, 141, 42, 131, 121, 33, 109, 101, 21, 86, 79, 5, 58, 54, 0, 13, 16, 0, + 228, 206, 29, 202, 183, 25, 178, 163, 20, 154, 141, 15, 131, 121, 5, 108, 100, 0, 85, 79, 0, 58, 53, 0, 13, 16, 0, + 217, 193, 221, 193, 172, 198, 172, 153, 178, 149, 133, 154, 128, 114, 132, 107, 94, 111, 85, 74, 89, 59, 49, 61, 25, 8, 22, + 219, 191, 198, 195, 171, 178, 173, 153, 159, 149, 132, 139, 128, 113, 119, 107, 94, 100, 85, 73, 79, 59, 48, 52, 25, 7, 14, + 221, 191, 180, 196, 170, 160, 174, 152, 144, 150, 132, 125, 129, 113, 107, 107, 93, 89, 85, 73, 69, 59, 48, 45, 23, 7, 4, + 222, 189, 159, 197, 169, 142, 174, 151, 127, 151, 131, 110, 129, 112, 94, 108, 93, 78, 85, 72, 60, 58, 47, 37, 22, 7, 0, + 223, 188, 138, 197, 168, 123, 175, 150, 109, 151, 130, 95, 130, 111, 81, 108, 92, 65, 85, 72, 49, 59, 47, 27, 21, 7, 0, + 224, 187, 118, 198, 167, 105, 176, 149, 93, 152, 129, 79, 130, 110, 68, 108, 91, 54, 85, 71, 38, 59, 47, 17, 18, 7, 0, + 224, 187, 93, 199, 166, 83, 176, 148, 73, 152, 128, 62, 129, 109, 51, 108, 90, 39, 85, 71, 25, 58, 46, 3, 16, 8, 0, + 226, 186, 64, 200, 165, 57, 177, 147, 50, 153, 127, 40, 130, 108, 31, 108, 90, 19, 85, 70, 3, 58, 46, 0, 16, 8, 0, + 227, 185, 35, 200, 165, 30, 176, 146, 25, 152, 127, 18, 130, 108, 7, 108, 89, 0, 85, 70, 0, 57, 46, 0, 14, 8, 0, + 216, 169, 205, 192, 150, 184, 171, 134, 164, 149, 116, 144, 128, 99, 124, 107, 81, 103, 85, 63, 81, 60, 39, 55, 26, 0, 15, + 217, 168, 186, 193, 150, 165, 172, 134, 149, 150, 116, 130, 128, 99, 111, 107, 81, 92, 85, 62, 72, 59, 39, 47, 25, 0, 6, + 219, 168, 168, 194, 149, 150, 173, 133, 135, 150, 116, 117, 128, 98, 99, 107, 80, 82, 86, 62, 63, 59, 38, 39, 24, 0, 0, + 219, 166, 148, 195, 149, 133, 173, 133, 119, 150, 115, 103, 128, 98, 88, 107, 80, 72, 85, 61, 54, 59, 38, 32, 23, 0, 0, + 220, 166, 129, 196, 148, 116, 174, 132, 103, 151, 114, 89, 129, 97, 75, 107, 79, 60, 85, 61, 44, 59, 38, 22, 21, 0, 0, + 222, 164, 110, 197, 147, 99, 175, 131, 87, 151, 113, 75, 129, 96, 63, 107, 79, 49, 85, 61, 33, 58, 38, 12, 19, 0, 0, + 222, 164, 88, 197, 146, 79, 174, 130, 69, 151, 113, 58, 129, 95, 47, 107, 78, 35, 85, 60, 20, 58, 38, 0, 18, 0, 0, + 223, 164, 63, 198, 145, 55, 175, 129, 48, 151, 112, 39, 129, 95, 29, 107, 78, 16, 85, 60, 1, 58, 38, 0, 17, 0, 0, + 223, 163, 36, 198, 145, 32, 174, 129, 26, 151, 111, 17, 129, 95, 7, 107, 78, 0, 84, 60, 0, 57, 37, 0, 15, 0, 0, + 215, 147, 192, 191, 130, 172, 170, 116, 153, 148, 100, 133, 127, 85, 115, 107, 69, 96, 85, 51, 75, 60, 28, 50, 25, 0, 8, + 217, 146, 173, 192, 130, 154, 171, 115, 138, 149, 100, 121, 128, 84, 103, 107, 68, 85, 85, 51, 66, 60, 28, 42, 25, 0, 0, + 217, 145, 157, 193, 129, 140, 173, 115, 125, 149, 100, 109, 128, 84, 92, 107, 68, 76, 85, 51, 58, 59, 28, 35, 23, 0, 0, + 218, 145, 140, 193, 129, 125, 172, 114, 110, 149, 99, 96, 128, 83, 81, 107, 67, 65, 84, 51, 49, 59, 29, 27, 22, 0, 0, + 219, 144, 121, 194, 128, 108, 172, 113, 96, 149, 98, 83, 128, 83, 69, 107, 68, 55, 85, 50, 40, 59, 28, 18, 20, 0, 0, + 220, 143, 104, 195, 128, 93, 173, 114, 82, 150, 98, 69, 127, 82, 58, 107, 67, 45, 85, 50, 30, 59, 28, 7, 19, 0, 0, + 220, 143, 84, 195, 127, 74, 173, 113, 65, 149, 97, 55, 128, 82, 44, 106, 67, 32, 84, 50, 16, 58, 28, 0, 18, 0, 0, + 221, 142, 62, 196, 126, 53, 173, 112, 46, 150, 97, 37, 128, 82, 26, 107, 66, 14, 84, 50, 0, 58, 28, 0, 16, 0, 0, + 222, 142, 38, 196, 126, 34, 174, 112, 27, 150, 96, 17, 128, 82, 6, 106, 66, 0, 84, 50, 0, 57, 29, 0, 16, 0, 0, + 214, 123, 179, 191, 110, 159, 169, 98, 143, 147, 84, 124, 126, 70, 106, 107, 55, 88, 85, 39, 69, 60, 15, 45, 23, 0, 2, + 216, 123, 161, 192, 110, 144, 170, 98, 129, 148, 84, 112, 127, 70, 95, 107, 55, 79, 85, 39, 61, 60, 15, 37, 20, 0, 0, + 217, 122, 145, 192, 110, 130, 170, 97, 116, 149, 84, 101, 127, 70, 85, 106, 55, 70, 85, 39, 53, 59, 16, 30, 19, 0, 0, + 217, 123, 131, 192, 109, 116, 171, 96, 103, 149, 83, 89, 127, 70, 75, 106, 55, 60, 85, 40, 45, 59, 16, 23, 17, 0, 0, + 217, 122, 114, 193, 109, 101, 172, 96, 91, 149, 82, 77, 128, 69, 64, 106, 55, 50, 84, 39, 35, 59, 17, 14, 17, 0, 0, + 218, 122, 98, 194, 108, 87, 171, 96, 77, 149, 82, 65, 127, 69, 52, 106, 55, 40, 84, 40, 25, 59, 18, 3, 15, 0, 0, + 219, 122, 80, 193, 108, 70, 172, 95, 61, 149, 82, 51, 127, 69, 40, 106, 55, 28, 84, 39, 12, 58, 17, 0, 13, 0, 0, + 219, 121, 59, 194, 108, 52, 172, 96, 44, 149, 82, 35, 127, 68, 24, 106, 55, 11, 84, 40, 0, 57, 18, 0, 13, 0, 0, + 219, 121, 40, 193, 108, 33, 172, 95, 26, 149, 81, 19, 128, 68, 6, 106, 54, 0, 84, 39, 0, 57, 18, 0, 13, 0, 0, + 213, 99, 165, 189, 87, 148, 169, 76, 132, 147, 64, 115, 126, 52, 98, 106, 39, 81, 85, 23, 63, 60, 0, 39, 16, 0, 0, + 214, 98, 149, 191, 87, 133, 170, 76, 119, 148, 65, 103, 127, 53, 88, 106, 39, 72, 85, 24, 55, 60, 0, 32, 15, 0, 0, + 215, 99, 136, 191, 87, 121, 170, 77, 108, 148, 65, 93, 126, 53, 79, 106, 40, 64, 85, 24, 47, 59, 0, 25, 14, 0, 0, + 215, 99, 121, 192, 87, 108, 170, 77, 96, 148, 65, 82, 126, 53, 69, 106, 40, 55, 85, 25, 39, 59, 0, 18, 13, 0, 0, + 216, 99, 106, 191, 87, 95, 170, 76, 83, 148, 65, 71, 126, 53, 58, 106, 41, 45, 85, 26, 30, 59, 0, 8, 11, 0, 0, + 216, 98, 91, 192, 88, 82, 170, 77, 71, 148, 65, 60, 127, 53, 48, 105, 41, 36, 83, 26, 21, 58, 1, 2, 11, 0, 0, + 217, 99, 75, 192, 87, 66, 170, 76, 57, 148, 65, 47, 126, 53, 36, 105, 41, 24, 83, 26, 8, 57, 2, 0, 9, 0, 0, + 217, 98, 57, 192, 87, 49, 171, 77, 41, 147, 65, 32, 126, 53, 21, 105, 41, 8, 84, 27, 0, 57, 3, 0, 9, 0, 0, + 217, 98, 40, 193, 87, 34, 171, 76, 27, 148, 65, 19, 126, 53, 6, 105, 41, 0, 83, 27, 0, 57, 4, 0, 9, 0, 0, + 211, 67, 152, 189, 58, 136, 168, 50, 122, 147, 39, 105, 127, 28, 89, 106, 14, 74, 85, 0, 56, 59, 0, 33, 9, 0, 0, + 213, 68, 138, 190, 59, 123, 169, 51, 109, 148, 40, 95, 126, 30, 80, 106, 16, 65, 85, 0, 48, 59, 0, 27, 9, 0, 0, + 214, 69, 125, 190, 59, 111, 168, 51, 99, 148, 41, 86, 126, 31, 72, 106, 18, 58, 85, 0, 41, 59, 0, 20, 7, 0, 0, + 215, 70, 112, 190, 61, 100, 169, 52, 88, 147, 42, 76, 126, 32, 63, 106, 19, 49, 84, 1, 34, 58, 0, 13, 7, 0, 0, + 214, 70, 99, 190, 62, 88, 169, 53, 77, 147, 43, 65, 125, 32, 53, 106, 20, 40, 84, 3, 26, 58, 0, 4, 7, 0, 0, + 214, 71, 86, 190, 61, 75, 169, 53, 65, 146, 43, 54, 126, 33, 44, 105, 21, 31, 83, 4, 17, 57, 0, 0, 7, 0, 0, + 215, 71, 71, 191, 62, 62, 169, 53, 53, 147, 44, 44, 126, 34, 33, 105, 22, 20, 83, 5, 4, 57, 0, 0, 7, 0, 0, + 215, 71, 54, 191, 62, 47, 169, 54, 39, 147, 44, 30, 126, 35, 20, 105, 23, 6, 83, 6, 0, 56, 0, 0, 5, 0, 0, + 215, 71, 41, 191, 63, 34, 170, 54, 27, 147, 45, 17, 126, 35, 6, 105, 23, 0, 83, 8, 0, 56, 0, 0, 5, 0, 0, + 210, 13, 140, 189, 1, 125, 167, 0, 110, 146, 0, 96, 126, 0, 81, 106, 0, 67, 85, 0, 51, 59, 0, 28, 4, 0, 0, + 212, 18, 126, 190, 7, 113, 168, 0, 100, 146, 0, 86, 126, 0, 73, 106, 0, 59, 84, 0, 43, 59, 0, 22, 4, 0, 0, + 212, 21, 115, 190, 13, 103, 168, 3, 91, 146, 0, 78, 125, 0, 65, 105, 0, 52, 84, 0, 36, 58, 0, 16, 4, 0, 0, + 213, 24, 103, 189, 19, 91, 168, 9, 82, 146, 0, 69, 125, 0, 57, 105, 0, 44, 84, 0, 29, 58, 0, 7, 4, 0, 0, + 213, 27, 92, 188, 21, 81, 168, 14, 71, 146, 1, 59, 125, 0, 48, 105, 0, 36, 84, 0, 21, 58, 0, 4, 4, 0, 0, + 213, 30, 80, 189, 22, 69, 168, 17, 61, 146, 5, 50, 125, 0, 39, 104, 0, 27, 83, 0, 12, 57, 0, 0, 4, 0, 0, + 214, 30, 67, 189, 25, 57, 168, 20, 50, 146, 9, 40, 125, 0, 29, 104, 0, 17, 83, 0, 2, 56, 0, 0, 4, 0, 0, + 214, 32, 53, 189, 27, 44, 169, 20, 38, 146, 13, 28, 124, 2, 17, 104, 0, 4, 83, 0, 0, 56, 0, 0, 4, 0, 0, + 214, 33, 41, 190, 27, 33, 168, 23, 27, 146, 13, 18, 125, 3, 5, 105, 0, 0, 83, 0, 0, 56, 0, 0, 4, 0, 0, + 185, 229, 250, 164, 204, 223, 146, 182, 199, 127, 158, 174, 108, 136, 149, 89, 113, 125, 70, 90, 100, 46, 62, 71, 10, 25, 33, + 189, 227, 225, 168, 202, 201, 148, 181, 179, 129, 157, 156, 109, 135, 134, 90, 113, 113, 70, 89, 90, 46, 62, 62, 8, 24, 25, + 192, 226, 202, 170, 202, 182, 151, 179, 162, 130, 156, 141, 110, 133, 121, 91, 112, 101, 71, 89, 80, 46, 61, 54, 7, 24, 19, + 194, 224, 179, 173, 200, 160, 153, 178, 144, 132, 155, 125, 112, 133, 107, 92, 111, 89, 71, 88, 69, 46, 61, 45, 6, 23, 10, + 196, 223, 155, 174, 198, 139, 154, 176, 124, 132, 153, 107, 113, 131, 91, 92, 110, 75, 72, 87, 58, 47, 60, 37, 4, 23, 0, + 198, 221, 131, 175, 197, 117, 155, 175, 105, 133, 152, 91, 113, 130, 76, 92, 109, 63, 72, 86, 47, 46, 60, 26, 3, 23, 0, + 200, 220, 104, 176, 196, 94, 156, 175, 84, 134, 151, 72, 113, 129, 59, 93, 108, 47, 72, 85, 33, 46, 59, 13, 0, 23, 0, + 201, 219, 73, 179, 195, 65, 157, 173, 57, 135, 150, 48, 114, 129, 39, 94, 108, 28, 72, 85, 15, 47, 59, 0, 0, 22, 0, + 203, 219, 42, 178, 195, 37, 157, 173, 32, 135, 150, 26, 114, 128, 16, 94, 107, 6, 73, 85, 0, 46, 58, 0, 0, 22, 0, + 186, 205, 233, 165, 183, 209, 148, 163, 187, 128, 142, 163, 109, 121, 140, 91, 101, 118, 71, 80, 94, 48, 54, 66, 12, 15, 27, + 189, 204, 211, 169, 182, 189, 151, 163, 169, 131, 141, 147, 111, 121, 126, 92, 101, 105, 72, 79, 84, 48, 54, 58, 11, 15, 19, + 192, 202, 190, 171, 181, 170, 152, 161, 152, 131, 141, 133, 112, 120, 113, 93, 100, 94, 72, 79, 74, 48, 53, 50, 10, 15, 11, + 195, 201, 169, 172, 179, 151, 153, 160, 135, 132, 139, 117, 113, 119, 100, 93, 99, 82, 72, 78, 64, 48, 53, 41, 9, 14, 3, + 195, 200, 146, 174, 179, 131, 154, 159, 117, 133, 138, 101, 113, 118, 86, 93, 98, 70, 73, 77, 53, 48, 52, 32, 8, 15, 0, + 198, 199, 125, 175, 177, 111, 155, 158, 100, 133, 137, 85, 113, 117, 71, 93, 97, 57, 72, 77, 42, 47, 52, 22, 5, 14, 0, + 199, 198, 101, 176, 177, 89, 155, 157, 79, 134, 136, 68, 113, 116, 56, 94, 97, 44, 73, 76, 30, 47, 52, 10, 2, 15, 0, + 200, 197, 72, 178, 176, 63, 157, 156, 56, 135, 136, 46, 114, 116, 37, 94, 96, 26, 73, 76, 11, 47, 51, 0, 0, 14, 0, + 201, 197, 45, 177, 175, 38, 156, 155, 31, 135, 135, 25, 114, 115, 17, 94, 96, 5, 73, 75, 0, 46, 51, 0, 0, 14, 0, + 187, 183, 218, 167, 165, 197, 149, 147, 176, 129, 127, 153, 111, 109, 132, 92, 90, 111, 73, 70, 89, 49, 46, 62, 15, 4, 22, + 190, 183, 197, 170, 164, 177, 151, 146, 159, 130, 127, 139, 112, 109, 119, 93, 90, 99, 72, 70, 78, 49, 45, 53, 14, 4, 15, + 192, 182, 179, 171, 163, 161, 153, 145, 144, 132, 126, 125, 113, 108, 107, 93, 89, 88, 73, 70, 69, 49, 45, 45, 13, 5, 6, + 195, 181, 159, 172, 162, 142, 152, 145, 127, 132, 125, 111, 113, 107, 94, 93, 88, 77, 73, 69, 59, 48, 45, 37, 11, 5, 0, + 195, 180, 139, 173, 161, 124, 153, 143, 110, 133, 125, 96, 113, 106, 81, 94, 88, 66, 73, 68, 49, 49, 44, 28, 9, 6, 0, + 196, 179, 118, 174, 160, 106, 154, 142, 94, 133, 124, 81, 113, 105, 68, 94, 87, 54, 73, 68, 39, 48, 44, 18, 5, 5, 0, + 197, 178, 96, 176, 159, 86, 155, 141, 75, 134, 123, 64, 114, 105, 53, 94, 87, 40, 73, 68, 26, 48, 44, 5, 2, 6, 0, + 199, 178, 70, 176, 158, 62, 156, 141, 54, 134, 122, 44, 114, 104, 35, 94, 86, 23, 73, 67, 8, 47, 44, 0, 2, 6, 0, + 199, 177, 45, 178, 158, 40, 156, 140, 32, 135, 122, 26, 114, 104, 16, 94, 86, 4, 73, 67, 0, 47, 44, 0, 0, 7, 0, + 188, 161, 204, 168, 144, 183, 149, 129, 164, 130, 112, 144, 112, 95, 123, 93, 78, 103, 74, 60, 81, 50, 36, 56, 16, 0, 16, + 190, 160, 185, 170, 144, 165, 151, 128, 148, 132, 111, 130, 112, 95, 110, 93, 78, 92, 74, 59, 72, 50, 36, 48, 16, 0, 8, + 192, 160, 167, 171, 143, 150, 153, 128, 134, 132, 111, 117, 112, 94, 100, 94, 77, 82, 74, 59, 63, 50, 36, 40, 14, 0, 0, + 193, 159, 149, 172, 143, 134, 153, 127, 119, 133, 110, 103, 113, 94, 87, 93, 77, 72, 73, 59, 54, 50, 36, 32, 12, 0, 0, + 195, 159, 131, 173, 142, 117, 153, 127, 104, 132, 110, 90, 113, 93, 76, 93, 76, 61, 74, 59, 45, 49, 36, 23, 9, 0, 0, + 196, 158, 113, 174, 141, 101, 155, 126, 89, 133, 109, 76, 113, 93, 64, 94, 76, 51, 74, 58, 35, 49, 36, 14, 6, 0, 0, + 197, 157, 92, 174, 141, 80, 154, 125, 71, 134, 108, 60, 114, 92, 50, 94, 75, 37, 73, 58, 22, 48, 36, 1, 5, 0, 0, + 197, 157, 68, 175, 140, 59, 155, 124, 51, 134, 108, 41, 113, 91, 32, 94, 75, 21, 73, 57, 5, 48, 35, 0, 5, 0, 0, + 198, 156, 46, 176, 140, 40, 155, 124, 32, 134, 107, 24, 114, 91, 14, 94, 75, 2, 73, 57, 0, 48, 36, 0, 3, 0, 0, + 189, 140, 191, 168, 126, 172, 150, 112, 154, 131, 97, 134, 112, 82, 115, 94, 66, 96, 74, 49, 75, 51, 25, 50, 12, 0, 10, + 191, 139, 173, 170, 125, 154, 152, 111, 138, 132, 96, 121, 113, 81, 103, 94, 66, 85, 74, 48, 66, 50, 26, 42, 12, 0, 1, + 192, 139, 157, 171, 125, 140, 152, 111, 125, 132, 96, 109, 113, 81, 92, 94, 65, 76, 74, 48, 58, 50, 26, 35, 9, 0, 0, + 193, 139, 140, 172, 124, 125, 153, 110, 112, 133, 95, 96, 113, 80, 82, 94, 65, 66, 74, 49, 50, 50, 26, 28, 7, 0, 0, + 194, 138, 123, 172, 123, 109, 153, 110, 97, 133, 95, 84, 113, 80, 70, 94, 65, 56, 74, 48, 40, 50, 26, 20, 6, 0, 0, + 194, 138, 105, 173, 123, 94, 153, 109, 83, 133, 94, 70, 112, 79, 59, 94, 64, 46, 74, 48, 31, 50, 26, 9, 4, 0, 0, + 196, 138, 87, 174, 122, 77, 153, 109, 67, 133, 93, 56, 113, 79, 46, 94, 64, 34, 73, 48, 18, 49, 27, 0, 4, 0, 0, + 196, 137, 65, 174, 122, 57, 154, 108, 49, 133, 93, 39, 113, 79, 29, 94, 64, 18, 74, 48, 3, 49, 27, 0, 2, 0, 0, + 197, 137, 47, 175, 122, 40, 155, 108, 32, 133, 93, 23, 114, 79, 14, 94, 64, 1, 73, 48, 0, 48, 27, 0, 2, 0, 0, + 189, 119, 177, 168, 106, 159, 150, 94, 142, 131, 81, 124, 113, 67, 107, 94, 53, 89, 74, 37, 69, 51, 11, 45, 6, 0, 3, + 191, 119, 161, 170, 106, 144, 152, 94, 129, 132, 81, 112, 113, 67, 96, 94, 53, 79, 74, 37, 61, 51, 13, 38, 6, 0, 0, + 192, 119, 146, 170, 106, 131, 152, 94, 117, 132, 80, 101, 112, 67, 85, 94, 53, 70, 74, 37, 53, 50, 14, 31, 4, 0, 0, + 192, 119, 131, 171, 106, 117, 153, 94, 105, 132, 80, 89, 113, 67, 75, 94, 54, 61, 74, 38, 45, 51, 14, 23, 3, 0, 0, + 193, 118, 114, 171, 106, 102, 153, 93, 90, 132, 80, 78, 113, 67, 65, 94, 53, 52, 74, 37, 36, 50, 15, 16, 1, 0, 0, + 194, 118, 99, 172, 105, 89, 153, 93, 78, 132, 80, 66, 113, 67, 54, 94, 53, 42, 74, 38, 27, 50, 16, 5, 1, 0, 0, + 194, 118, 82, 173, 105, 72, 153, 93, 63, 132, 79, 53, 113, 67, 42, 94, 53, 30, 74, 38, 15, 49, 16, 0, 0, 0, 0, + 195, 117, 63, 173, 105, 55, 154, 93, 47, 133, 79, 37, 113, 66, 27, 94, 53, 15, 73, 38, 0, 48, 16, 0, 0, 0, 0, + 195, 117, 46, 173, 104, 39, 154, 92, 32, 133, 79, 22, 113, 66, 13, 94, 53, 0, 73, 38, 0, 48, 17, 0, 0, 0, 0, + 189, 96, 166, 168, 85, 147, 150, 74, 132, 131, 62, 115, 113, 51, 99, 94, 38, 82, 74, 21, 63, 51, 0, 40, 1, 0, 0, + 190, 96, 150, 170, 85, 133, 152, 75, 119, 132, 63, 104, 113, 51, 88, 94, 38, 72, 75, 22, 55, 51, 0, 33, 1, 0, 0, + 192, 96, 137, 170, 85, 121, 152, 74, 108, 132, 64, 94, 113, 52, 79, 94, 39, 64, 74, 23, 48, 50, 0, 26, 0, 0, 0, + 192, 96, 122, 171, 86, 109, 152, 75, 96, 132, 63, 83, 113, 52, 69, 94, 39, 56, 74, 24, 41, 50, 0, 19, 0, 0, 0, + 193, 96, 107, 171, 85, 96, 152, 75, 84, 132, 64, 72, 113, 52, 60, 94, 39, 47, 74, 24, 32, 50, 1, 10, 0, 0, 0, + 193, 96, 93, 172, 85, 82, 152, 75, 72, 133, 63, 61, 113, 51, 49, 94, 39, 37, 73, 25, 23, 49, 2, 2, 0, 0, 0, + 194, 96, 78, 172, 85, 68, 152, 75, 59, 132, 63, 49, 113, 52, 39, 94, 40, 26, 73, 25, 11, 48, 3, 0, 0, 0, 0, + 194, 96, 60, 173, 85, 52, 153, 75, 44, 132, 64, 35, 112, 52, 25, 94, 40, 12, 73, 26, 0, 48, 4, 0, 0, 0, 0, + 195, 96, 46, 173, 85, 38, 154, 74, 31, 133, 63, 22, 113, 52, 11, 93, 40, 0, 73, 26, 0, 47, 5, 0, 0, 0, 0, + 188, 67, 153, 168, 58, 137, 151, 49, 122, 131, 39, 106, 113, 28, 90, 94, 13, 75, 75, 0, 57, 51, 0, 35, 0, 0, 0, + 190, 68, 138, 170, 59, 123, 152, 50, 110, 132, 41, 96, 113, 29, 80, 94, 16, 66, 75, 0, 49, 50, 0, 27, 0, 0, 0, + 191, 69, 126, 170, 59, 112, 151, 52, 100, 132, 42, 86, 113, 30, 73, 95, 17, 58, 75, 0, 42, 50, 0, 21, 0, 0, 0, + 192, 70, 113, 170, 61, 100, 151, 52, 89, 132, 42, 77, 113, 31, 64, 94, 19, 50, 74, 1, 35, 50, 0, 14, 0, 0, 0, + 192, 70, 100, 170, 62, 89, 151, 53, 77, 131, 43, 66, 112, 32, 54, 94, 20, 42, 74, 2, 27, 49, 0, 5, 0, 0, 0, + 192, 71, 87, 171, 61, 77, 152, 53, 67, 131, 44, 57, 112, 33, 45, 94, 21, 33, 74, 4, 19, 49, 0, 1, 0, 0, 0, + 193, 71, 74, 171, 62, 64, 152, 53, 55, 132, 44, 45, 113, 34, 34, 94, 22, 23, 73, 5, 7, 48, 0, 0, 0, 0, 0, + 193, 70, 58, 172, 62, 50, 152, 54, 42, 132, 44, 32, 112, 35, 22, 93, 23, 10, 73, 6, 0, 47, 0, 0, 0, 0, 0, + 193, 70, 45, 172, 62, 38, 153, 54, 31, 132, 44, 21, 112, 35, 9, 94, 23, 0, 73, 7, 0, 47, 0, 0, 0, 0, 0, + 189, 26, 141, 169, 15, 126, 150, 2, 112, 131, 0, 97, 113, 0, 82, 94, 0, 67, 75, 0, 51, 50, 0, 29, 0, 0, 0, + 190, 28, 128, 170, 18, 114, 151, 8, 101, 132, 0, 88, 113, 0, 74, 94, 0, 60, 75, 0, 44, 50, 0, 23, 0, 0, 0, + 191, 30, 117, 170, 23, 104, 152, 11, 92, 132, 1, 79, 113, 0, 67, 95, 0, 53, 75, 0, 37, 50, 0, 17, 0, 0, 0, + 191, 33, 105, 170, 26, 93, 151, 18, 83, 132, 6, 70, 112, 0, 58, 94, 0, 45, 75, 0, 30, 49, 0, 8, 0, 0, 0, + 191, 34, 93, 170, 27, 82, 151, 20, 72, 131, 8, 61, 112, 0, 49, 94, 0, 38, 74, 0, 23, 49, 0, 4, 0, 0, 0, + 191, 36, 82, 170, 29, 71, 151, 22, 63, 131, 11, 52, 112, 0, 41, 93, 0, 29, 74, 0, 14, 48, 0, 1, 0, 0, 0, + 191, 38, 69, 170, 31, 60, 151, 24, 51, 131, 14, 41, 112, 1, 31, 93, 0, 19, 73, 0, 3, 48, 0, 0, 0, 0, 0, + 192, 37, 56, 171, 31, 47, 152, 25, 40, 131, 17, 30, 112, 4, 19, 93, 0, 7, 73, 0, 0, 47, 0, 0, 0, 0, 0, + 192, 38, 45, 171, 33, 36, 152, 26, 30, 131, 18, 21, 111, 7, 9, 93, 0, 0, 73, 0, 0, 47, 0, 0, 0, 0, 0, + 149, 218, 248, 133, 194, 222, 119, 173, 198, 102, 151, 173, 86, 130, 148, 70, 108, 125, 53, 85, 100, 32, 59, 71, 0, 22, 33, + 154, 216, 223, 137, 193, 200, 122, 172, 178, 106, 150, 156, 89, 128, 133, 73, 107, 112, 54, 85, 89, 31, 59, 63, 0, 22, 26, + 159, 215, 202, 141, 192, 181, 126, 171, 161, 108, 149, 141, 90, 128, 121, 74, 107, 100, 55, 85, 80, 32, 58, 55, 0, 22, 19, + 161, 213, 179, 144, 190, 160, 126, 170, 143, 109, 148, 125, 92, 127, 107, 74, 106, 89, 56, 84, 69, 32, 58, 46, 0, 21, 11, + 163, 211, 156, 144, 189, 139, 129, 168, 125, 110, 147, 108, 93, 126, 92, 75, 105, 76, 57, 83, 58, 33, 58, 37, 0, 21, 1, + 167, 211, 133, 147, 188, 120, 130, 167, 105, 110, 145, 92, 93, 125, 78, 76, 104, 64, 58, 83, 48, 33, 57, 27, 0, 21, 0, + 169, 210, 108, 149, 187, 96, 131, 166, 86, 112, 144, 74, 94, 124, 62, 77, 103, 49, 58, 82, 35, 33, 57, 15, 0, 21, 0, + 170, 209, 80, 151, 186, 71, 133, 165, 62, 114, 143, 52, 95, 123, 42, 77, 103, 32, 58, 81, 18, 33, 56, 0, 0, 21, 0, + 173, 208, 55, 152, 186, 49, 134, 165, 41, 114, 143, 34, 95, 122, 25, 77, 102, 14, 58, 81, 0, 33, 56, 0, 0, 21, 0, + 154, 195, 232, 137, 174, 207, 122, 156, 185, 105, 136, 163, 89, 116, 140, 73, 97, 117, 56, 76, 94, 35, 51, 66, 0, 13, 28, + 158, 194, 209, 141, 174, 187, 125, 155, 167, 109, 135, 146, 91, 116, 125, 75, 96, 105, 57, 75, 83, 35, 50, 57, 0, 12, 21, + 161, 193, 189, 144, 173, 169, 128, 154, 151, 110, 134, 132, 93, 115, 113, 77, 95, 94, 58, 75, 74, 35, 50, 50, 0, 12, 13, + 164, 192, 168, 145, 171, 151, 129, 153, 134, 111, 133, 117, 94, 114, 100, 76, 95, 82, 58, 75, 64, 36, 50, 42, 0, 12, 5, + 165, 191, 147, 147, 170, 131, 130, 152, 117, 113, 132, 102, 95, 113, 86, 77, 94, 71, 58, 74, 54, 35, 50, 33, 0, 13, 0, + 167, 189, 126, 148, 169, 113, 132, 151, 100, 113, 131, 86, 96, 112, 73, 77, 93, 59, 59, 73, 43, 35, 49, 23, 0, 12, 0, + 170, 189, 104, 150, 168, 91, 133, 150, 81, 114, 130, 69, 96, 111, 57, 78, 92, 46, 59, 73, 31, 35, 49, 11, 0, 13, 0, + 171, 188, 78, 152, 168, 68, 134, 149, 60, 115, 130, 50, 96, 111, 41, 78, 92, 29, 60, 73, 15, 35, 49, 0, 0, 12, 0, + 173, 187, 55, 153, 167, 47, 134, 149, 39, 115, 129, 33, 97, 110, 24, 79, 92, 13, 60, 72, 0, 35, 48, 0, 0, 12, 0, + 157, 175, 217, 139, 157, 196, 125, 141, 175, 109, 122, 153, 92, 104, 132, 76, 86, 110, 59, 67, 88, 37, 43, 61, 1, 1, 23, + 161, 174, 196, 144, 156, 176, 127, 140, 158, 110, 121, 137, 94, 104, 118, 77, 85, 98, 59, 67, 78, 37, 43, 53, 0, 2, 16, + 163, 174, 178, 146, 156, 160, 130, 139, 143, 112, 121, 124, 95, 103, 106, 78, 85, 88, 60, 66, 69, 37, 42, 46, 0, 2, 7, + 166, 173, 159, 147, 154, 142, 130, 138, 127, 113, 120, 111, 96, 103, 95, 78, 84, 77, 60, 66, 59, 37, 43, 37, 0, 2, 0, + 166, 172, 139, 148, 154, 125, 131, 137, 112, 113, 120, 96, 96, 102, 81, 78, 84, 66, 60, 65, 50, 37, 42, 29, 0, 3, 0, + 167, 171, 120, 149, 153, 107, 133, 137, 95, 114, 118, 81, 97, 101, 69, 79, 84, 56, 60, 65, 40, 37, 42, 19, 0, 3, 0, + 170, 170, 99, 151, 152, 87, 134, 136, 77, 115, 118, 66, 97, 101, 55, 79, 83, 42, 61, 65, 28, 37, 42, 7, 0, 3, 0, + 172, 170, 75, 152, 151, 65, 134, 135, 57, 115, 117, 48, 97, 100, 38, 79, 83, 27, 61, 64, 12, 36, 42, 0, 0, 3, 0, + 172, 169, 55, 154, 151, 46, 135, 134, 40, 116, 116, 32, 97, 99, 21, 80, 82, 10, 61, 64, 0, 36, 41, 0, 0, 3, 0, + 160, 154, 203, 143, 139, 182, 127, 124, 164, 111, 107, 143, 95, 91, 122, 78, 75, 103, 60, 57, 81, 39, 33, 56, 1, 0, 18, + 163, 154, 184, 146, 138, 165, 130, 123, 148, 113, 107, 129, 96, 90, 110, 79, 74, 92, 61, 56, 72, 39, 34, 48, 2, 0, 9, + 165, 154, 167, 147, 137, 149, 131, 122, 134, 114, 106, 117, 96, 90, 100, 79, 74, 82, 61, 56, 64, 39, 33, 40, 2, 0, 1, + 166, 153, 150, 149, 137, 133, 132, 122, 119, 114, 106, 104, 97, 90, 88, 79, 74, 72, 61, 56, 55, 39, 34, 33, 0, 0, 0, + 168, 152, 132, 149, 136, 117, 132, 121, 104, 114, 105, 90, 97, 89, 76, 79, 73, 62, 61, 56, 46, 38, 34, 25, 0, 0, 0, + 169, 151, 114, 150, 135, 101, 133, 121, 90, 114, 104, 77, 97, 89, 65, 80, 73, 51, 61, 56, 36, 38, 34, 16, 0, 0, 0, + 170, 150, 94, 151, 135, 83, 134, 120, 73, 115, 104, 62, 98, 88, 51, 80, 72, 39, 61, 56, 24, 38, 34, 3, 0, 0, 0, + 172, 150, 72, 153, 134, 63, 135, 119, 55, 115, 103, 45, 98, 88, 36, 80, 72, 24, 61, 55, 9, 38, 34, 0, 0, 0, 0, + 172, 150, 54, 153, 134, 47, 135, 119, 38, 116, 103, 30, 98, 87, 21, 80, 72, 8, 62, 55, 0, 37, 34, 0, 0, 0, 0, + 162, 134, 190, 145, 120, 171, 129, 108, 153, 113, 93, 134, 97, 78, 115, 80, 63, 96, 62, 46, 75, 41, 23, 51, 0, 0, 11, + 165, 134, 173, 147, 120, 154, 131, 107, 138, 114, 92, 120, 97, 78, 103, 80, 63, 85, 62, 46, 66, 40, 23, 43, 0, 0, 2, + 166, 134, 157, 148, 120, 140, 132, 106, 125, 114, 92, 109, 97, 77, 93, 81, 63, 77, 62, 46, 58, 40, 24, 36, 0, 0, 0, + 168, 133, 140, 149, 119, 125, 132, 106, 112, 115, 92, 97, 98, 77, 82, 81, 62, 67, 62, 46, 50, 40, 24, 29, 0, 0, 0, + 168, 133, 123, 150, 119, 110, 133, 106, 97, 115, 91, 84, 98, 77, 70, 81, 62, 57, 62, 46, 41, 40, 24, 20, 0, 0, 0, + 169, 132, 107, 150, 118, 94, 133, 105, 84, 115, 91, 72, 98, 76, 60, 80, 62, 47, 62, 46, 32, 39, 25, 11, 0, 0, 0, + 171, 132, 89, 152, 118, 79, 135, 105, 69, 115, 90, 58, 98, 76, 47, 80, 62, 36, 62, 46, 21, 39, 25, 0, 0, 0, 0, + 171, 132, 69, 153, 117, 60, 135, 104, 52, 116, 90, 42, 98, 76, 33, 81, 61, 21, 62, 46, 6, 38, 25, 0, 0, 0, 0, + 172, 132, 54, 153, 118, 45, 135, 104, 38, 116, 90, 28, 98, 76, 18, 81, 61, 6, 62, 46, 0, 38, 25, 0, 0, 0, 0, + 164, 115, 177, 146, 103, 159, 130, 91, 143, 114, 78, 125, 97, 65, 107, 81, 51, 89, 63, 34, 69, 41, 9, 46, 0, 0, 4, + 166, 115, 161, 148, 103, 144, 132, 91, 129, 115, 78, 112, 98, 65, 96, 81, 51, 79, 63, 35, 61, 41, 11, 38, 0, 0, 0, + 167, 115, 146, 150, 102, 131, 132, 91, 117, 115, 78, 101, 98, 65, 86, 81, 51, 71, 63, 35, 54, 41, 12, 32, 0, 0, 0, + 168, 114, 132, 150, 103, 118, 133, 91, 105, 116, 78, 91, 98, 64, 76, 82, 51, 61, 63, 36, 46, 41, 13, 24, 0, 0, 0, + 169, 114, 116, 150, 102, 103, 134, 90, 91, 116, 78, 79, 98, 65, 66, 81, 51, 53, 63, 36, 37, 40, 14, 17, 0, 0, 0, + 169, 114, 101, 151, 101, 89, 134, 90, 79, 116, 77, 67, 98, 64, 56, 81, 51, 44, 63, 36, 29, 40, 15, 7, 0, 0, 0, + 170, 114, 85, 152, 101, 75, 135, 90, 65, 116, 77, 54, 98, 64, 44, 81, 51, 32, 63, 36, 17, 39, 15, 0, 0, 0, 0, + 172, 113, 66, 152, 101, 58, 135, 89, 49, 116, 77, 40, 99, 64, 30, 81, 51, 18, 62, 36, 3, 38, 16, 0, 0, 0, 0, + 171, 113, 51, 153, 101, 44, 136, 89, 36, 116, 77, 28, 99, 64, 18, 81, 51, 5, 62, 36, 0, 38, 16, 0, 0, 0, 0, + 165, 94, 166, 147, 82, 147, 132, 72, 132, 115, 61, 115, 98, 49, 99, 82, 36, 82, 64, 19, 64, 42, 0, 41, 0, 0, 0, + 167, 93, 150, 150, 83, 134, 133, 73, 120, 116, 62, 104, 99, 49, 88, 82, 36, 72, 64, 20, 55, 41, 0, 33, 0, 0, 0, + 169, 93, 137, 150, 83, 122, 134, 73, 109, 116, 61, 94, 99, 50, 80, 82, 37, 65, 64, 21, 49, 41, 0, 27, 0, 0, 0, + 169, 94, 123, 150, 83, 110, 133, 73, 97, 116, 61, 83, 99, 50, 70, 82, 38, 57, 63, 23, 42, 41, 0, 20, 0, 0, 0, + 169, 94, 109, 150, 84, 97, 134, 73, 85, 116, 62, 73, 99, 51, 61, 81, 38, 48, 63, 23, 33, 41, 1, 11, 0, 0, 0, + 170, 94, 96, 150, 83, 84, 134, 73, 74, 116, 61, 62, 99, 50, 51, 82, 38, 39, 64, 23, 24, 40, 3, 4, 0, 0, 0, + 171, 93, 79, 152, 82, 70, 135, 73, 61, 116, 62, 51, 98, 51, 40, 81, 38, 28, 63, 24, 14, 39, 4, 0, 0, 0, 0, + 171, 94, 64, 152, 83, 55, 135, 73, 47, 116, 62, 37, 98, 50, 27, 81, 38, 15, 63, 24, 1, 39, 4, 0, 0, 0, 0, + 172, 93, 51, 153, 82, 42, 135, 73, 35, 117, 62, 26, 99, 51, 16, 81, 39, 3, 63, 25, 0, 38, 5, 0, 0, 0, 0, + 166, 68, 153, 148, 59, 137, 133, 49, 121, 115, 39, 106, 99, 28, 91, 82, 13, 75, 65, 0, 58, 42, 0, 36, 0, 0, 0, + 168, 68, 139, 150, 59, 124, 134, 50, 110, 116, 40, 96, 99, 30, 81, 82, 16, 66, 64, 0, 50, 41, 0, 29, 0, 0, 0, + 169, 69, 126, 150, 59, 113, 134, 51, 101, 117, 42, 87, 100, 30, 73, 82, 17, 59, 65, 0, 43, 41, 0, 23, 0, 0, 0, + 169, 70, 115, 150, 61, 102, 134, 52, 89, 116, 42, 77, 99, 32, 65, 82, 19, 52, 64, 0, 36, 41, 0, 15, 0, 0, 0, + 169, 70, 101, 150, 61, 90, 134, 52, 79, 116, 43, 68, 99, 32, 55, 82, 21, 43, 64, 2, 28, 41, 0, 6, 0, 0, 0, + 170, 70, 89, 151, 62, 79, 134, 53, 69, 116, 44, 58, 99, 33, 46, 81, 21, 34, 64, 3, 20, 41, 0, 2, 0, 0, 0, + 170, 71, 76, 152, 62, 66, 134, 53, 57, 116, 43, 46, 99, 33, 36, 82, 22, 24, 64, 5, 10, 40, 0, 0, 0, 0, 0, + 171, 70, 61, 152, 62, 52, 135, 53, 44, 116, 44, 35, 99, 34, 24, 82, 22, 12, 63, 6, 0, 39, 0, 0, 0, 0, 0, + 171, 71, 49, 153, 62, 41, 135, 54, 33, 117, 45, 25, 98, 34, 13, 81, 23, 0, 63, 7, 0, 39, 0, 0, 0, 0, 0, + 167, 33, 142, 149, 24, 127, 134, 10, 113, 116, 0, 97, 100, 0, 83, 83, 0, 68, 65, 0, 52, 40, 0, 30, 0, 0, 0, + 169, 33, 129, 150, 26, 115, 134, 17, 102, 116, 3, 89, 100, 0, 75, 83, 0, 60, 65, 0, 45, 40, 0, 24, 0, 0, 0, + 169, 36, 118, 151, 27, 104, 134, 19, 93, 116, 7, 80, 100, 0, 67, 83, 0, 54, 65, 0, 38, 41, 0, 17, 0, 0, 0, + 169, 39, 107, 150, 30, 94, 134, 22, 84, 116, 11, 71, 99, 0, 59, 83, 0, 46, 64, 0, 31, 40, 0, 9, 0, 0, 0, + 169, 39, 95, 151, 31, 83, 134, 24, 73, 116, 15, 62, 100, 1, 51, 83, 0, 38, 64, 0, 24, 40, 0, 5, 0, 0, 0, + 169, 41, 83, 151, 33, 73, 134, 26, 64, 117, 17, 54, 99, 4, 42, 82, 0, 30, 64, 0, 16, 40, 0, 1, 0, 0, 0, + 170, 42, 71, 152, 34, 62, 134, 28, 53, 117, 19, 44, 99, 6, 33, 82, 0, 21, 63, 0, 4, 39, 0, 0, 0, 0, 0, + 171, 42, 59, 152, 35, 50, 134, 29, 42, 117, 21, 32, 99, 9, 22, 82, 0, 9, 63, 0, 0, 38, 0, 0, 0, 0, 0, + 172, 42, 48, 152, 36, 40, 135, 29, 32, 117, 21, 23, 99, 10, 12, 82, 0, 0, 63, 0, 0, 38, 0, 0, 0, 0, 0, + 107, 207, 246, 96, 185, 220, 86, 165, 196, 73, 144, 171, 60, 123, 147, 46, 103, 125, 32, 82, 100, 9, 56, 71, 0, 20, 33, + 115, 206, 221, 104, 184, 198, 92, 164, 178, 78, 143, 154, 64, 123, 133, 51, 102, 111, 34, 81, 89, 10, 56, 63, 0, 20, 27, + 122, 204, 200, 108, 183, 180, 95, 163, 161, 82, 142, 140, 68, 122, 120, 54, 102, 101, 36, 81, 79, 11, 56, 55, 0, 20, 20, + 125, 203, 179, 111, 181, 160, 97, 162, 143, 85, 141, 124, 70, 121, 107, 55, 101, 89, 38, 80, 69, 14, 55, 46, 0, 19, 10, + 128, 202, 156, 113, 180, 140, 102, 161, 125, 87, 140, 108, 71, 120, 92, 56, 100, 76, 39, 79, 59, 14, 55, 38, 0, 20, 3, + 132, 200, 135, 117, 179, 121, 103, 159, 106, 88, 139, 93, 73, 119, 79, 57, 100, 65, 41, 79, 49, 15, 54, 28, 0, 19, 0, + 134, 200, 111, 119, 178, 98, 105, 158, 87, 89, 138, 76, 74, 118, 64, 58, 99, 51, 41, 78, 37, 16, 54, 17, 0, 19, 0, + 137, 199, 85, 122, 177, 75, 108, 158, 66, 91, 137, 56, 75, 118, 46, 59, 98, 35, 42, 78, 22, 16, 54, 3, 0, 19, 0, + 140, 198, 62, 125, 177, 55, 109, 158, 47, 92, 137, 40, 76, 117, 32, 59, 98, 21, 42, 78, 6, 16, 54, 0, 0, 18, 0, + 118, 186, 231, 106, 167, 206, 93, 149, 184, 81, 130, 161, 67, 111, 139, 54, 92, 117, 39, 72, 93, 17, 48, 66, 0, 10, 29, + 123, 185, 207, 110, 166, 186, 98, 148, 167, 85, 129, 145, 71, 111, 125, 56, 92, 104, 40, 72, 83, 18, 48, 57, 0, 10, 22, + 128, 184, 188, 113, 165, 168, 102, 147, 151, 88, 128, 131, 73, 110, 113, 58, 91, 94, 42, 71, 74, 19, 48, 50, 0, 9, 15, + 131, 183, 168, 116, 164, 151, 104, 146, 134, 89, 127, 117, 73, 109, 100, 58, 90, 83, 42, 71, 65, 20, 48, 42, 0, 9, 5, + 134, 182, 148, 120, 163, 131, 105, 145, 118, 90, 126, 102, 75, 108, 86, 59, 90, 72, 43, 71, 55, 19, 47, 34, 0, 9, 0, + 136, 181, 128, 122, 162, 115, 107, 144, 102, 92, 125, 87, 76, 107, 74, 61, 89, 60, 44, 70, 45, 20, 47, 24, 0, 8, 0, + 139, 180, 106, 124, 161, 95, 109, 144, 83, 93, 124, 71, 77, 107, 60, 61, 89, 47, 44, 70, 33, 20, 47, 13, 0, 8, 0, + 142, 179, 82, 125, 160, 72, 111, 143, 63, 94, 124, 54, 77, 106, 44, 61, 88, 32, 44, 69, 18, 20, 46, 0, 0, 8, 0, + 143, 179, 62, 127, 160, 54, 111, 142, 47, 94, 124, 39, 78, 106, 29, 62, 88, 18, 45, 69, 3, 20, 46, 0, 0, 8, 0, + 124, 167, 216, 112, 150, 194, 99, 134, 174, 87, 117, 153, 73, 100, 131, 58, 82, 110, 43, 64, 88, 23, 40, 61, 0, 0, 24, + 129, 166, 195, 116, 150, 175, 103, 134, 158, 89, 116, 137, 75, 99, 118, 60, 82, 98, 44, 63, 78, 23, 40, 53, 0, 0, 17, + 132, 166, 177, 119, 149, 160, 106, 133, 143, 90, 115, 124, 76, 99, 107, 61, 81, 88, 45, 63, 69, 24, 40, 46, 0, 0, 9, + 136, 166, 159, 121, 148, 143, 107, 132, 126, 92, 115, 111, 77, 98, 94, 62, 81, 78, 46, 63, 60, 23, 40, 38, 0, 0, 0, + 138, 164, 140, 122, 147, 125, 108, 131, 111, 93, 114, 97, 79, 98, 82, 63, 80, 67, 46, 62, 50, 24, 40, 29, 0, 0, 0, + 139, 163, 122, 124, 146, 109, 110, 131, 96, 94, 114, 83, 79, 97, 70, 63, 81, 57, 46, 62, 41, 24, 40, 21, 0, 0, 0, + 141, 163, 101, 126, 145, 90, 111, 130, 79, 95, 113, 68, 79, 96, 56, 63, 80, 44, 47, 62, 30, 23, 40, 10, 0, 0, 0, + 144, 162, 79, 127, 145, 70, 112, 129, 60, 95, 112, 51, 79, 96, 41, 64, 79, 30, 47, 61, 15, 23, 40, 0, 0, 0, 0, + 145, 162, 60, 129, 145, 52, 113, 129, 46, 96, 112, 37, 79, 95, 27, 64, 79, 16, 47, 61, 1, 23, 39, 0, 0, 0, 0, + 131, 147, 202, 117, 133, 181, 105, 119, 162, 91, 103, 142, 77, 87, 122, 62, 71, 102, 47, 54, 81, 26, 31, 56, 0, 0, 18, + 135, 147, 183, 120, 132, 164, 107, 118, 147, 93, 102, 128, 78, 87, 110, 63, 71, 92, 47, 54, 72, 26, 31, 48, 0, 0, 10, + 138, 147, 166, 123, 131, 149, 108, 118, 133, 94, 102, 116, 79, 86, 100, 64, 71, 82, 48, 54, 64, 27, 31, 41, 0, 0, 2, + 139, 146, 149, 124, 131, 134, 111, 117, 119, 94, 101, 103, 79, 86, 88, 64, 70, 72, 48, 53, 55, 27, 31, 33, 0, 0, 0, + 141, 146, 132, 125, 131, 117, 111, 117, 104, 95, 101, 91, 80, 86, 77, 65, 70, 62, 48, 53, 46, 26, 31, 25, 0, 0, 0, + 143, 145, 115, 126, 130, 101, 112, 116, 90, 96, 100, 78, 80, 85, 65, 65, 70, 52, 49, 53, 37, 27, 32, 17, 0, 0, 0, + 144, 144, 96, 128, 129, 85, 112, 115, 75, 97, 100, 64, 81, 85, 52, 65, 69, 40, 49, 53, 26, 26, 31, 5, 0, 0, 0, + 146, 144, 76, 129, 129, 67, 114, 115, 58, 97, 99, 48, 82, 84, 38, 66, 69, 27, 49, 53, 12, 26, 32, 0, 0, 0, 0, + 146, 144, 59, 130, 128, 51, 114, 114, 43, 98, 99, 35, 82, 84, 25, 66, 69, 13, 49, 53, 0, 26, 32, 0, 0, 0, 0, + 135, 129, 189, 122, 115, 170, 107, 103, 152, 94, 89, 133, 79, 74, 114, 64, 60, 95, 49, 43, 75, 29, 20, 51, 0, 0, 12, + 138, 129, 171, 124, 115, 153, 110, 103, 138, 95, 89, 120, 81, 74, 103, 66, 60, 86, 50, 44, 67, 28, 21, 43, 0, 0, 3, + 140, 129, 156, 125, 115, 140, 111, 103, 125, 96, 89, 109, 81, 74, 93, 67, 60, 76, 50, 44, 59, 29, 22, 36, 0, 0, 0, + 142, 128, 140, 127, 115, 125, 112, 102, 112, 97, 88, 97, 82, 74, 83, 67, 60, 67, 50, 44, 51, 29, 22, 29, 0, 0, 0, + 142, 128, 124, 127, 114, 111, 113, 102, 98, 98, 88, 85, 82, 74, 71, 66, 60, 58, 50, 44, 42, 29, 22, 21, 0, 0, 0, + 144, 127, 108, 128, 114, 96, 113, 101, 85, 98, 87, 73, 82, 74, 61, 67, 60, 48, 50, 44, 33, 28, 23, 12, 0, 0, 0, + 145, 127, 91, 129, 114, 81, 115, 101, 71, 98, 87, 60, 82, 73, 48, 67, 59, 37, 50, 44, 22, 29, 23, 1, 0, 0, 0, + 147, 127, 73, 130, 113, 63, 115, 101, 55, 98, 87, 45, 83, 73, 35, 67, 59, 24, 50, 44, 10, 28, 24, 0, 0, 0, 0, + 147, 127, 58, 131, 113, 49, 115, 100, 42, 99, 86, 33, 83, 73, 23, 67, 59, 10, 50, 44, 0, 27, 24, 0, 0, 0, 0, + 138, 110, 177, 124, 99, 159, 110, 88, 142, 96, 75, 125, 82, 62, 107, 66, 48, 89, 51, 33, 70, 30, 8, 46, 0, 0, 5, + 142, 111, 160, 127, 99, 144, 113, 88, 130, 98, 75, 112, 82, 62, 96, 68, 49, 80, 51, 33, 61, 30, 10, 39, 0, 0, 0, + 143, 111, 146, 128, 99, 131, 114, 88, 118, 98, 75, 101, 83, 62, 86, 68, 49, 71, 52, 33, 54, 30, 11, 32, 0, 0, 0, + 144, 111, 132, 128, 99, 118, 113, 88, 106, 99, 75, 91, 83, 62, 77, 68, 49, 62, 52, 34, 46, 30, 12, 25, 0, 0, 0, + 144, 111, 117, 129, 98, 104, 114, 87, 92, 99, 75, 80, 83, 62, 67, 68, 49, 53, 51, 34, 38, 30, 13, 18, 0, 0, 0, + 145, 111, 103, 130, 98, 91, 114, 87, 80, 99, 75, 68, 83, 63, 57, 68, 50, 45, 51, 34, 30, 30, 14, 8, 0, 0, 0, + 146, 110, 87, 131, 98, 76, 115, 87, 67, 99, 75, 56, 83, 62, 45, 68, 49, 33, 52, 35, 19, 30, 15, 2, 0, 0, 0, + 148, 110, 70, 131, 98, 60, 116, 86, 52, 99, 74, 43, 84, 62, 33, 69, 49, 21, 52, 35, 6, 29, 15, 0, 0, 0, 0, + 148, 110, 56, 132, 97, 48, 117, 87, 40, 100, 75, 31, 84, 62, 22, 68, 49, 9, 51, 35, 0, 28, 15, 0, 0, 0, 0, + 142, 91, 166, 126, 80, 148, 113, 71, 132, 98, 59, 115, 83, 47, 99, 69, 34, 82, 53, 17, 64, 32, 0, 41, 0, 0, 0, + 143, 91, 150, 128, 81, 135, 114, 71, 120, 99, 60, 104, 85, 48, 89, 69, 35, 73, 53, 19, 56, 32, 0, 34, 0, 0, 0, + 145, 91, 137, 129, 81, 122, 115, 71, 109, 100, 60, 94, 85, 48, 81, 69, 35, 65, 53, 19, 49, 32, 0, 28, 0, 0, 0, + 146, 92, 124, 130, 81, 110, 115, 71, 98, 100, 60, 84, 85, 49, 71, 69, 36, 57, 53, 21, 42, 32, 0, 21, 0, 0, 0, + 147, 91, 110, 130, 81, 97, 115, 71, 86, 100, 60, 74, 84, 49, 62, 69, 36, 48, 53, 22, 34, 32, 0, 13, 0, 0, 0, + 147, 92, 97, 130, 81, 85, 116, 72, 76, 100, 60, 63, 85, 49, 52, 69, 37, 40, 53, 22, 26, 31, 1, 5, 0, 0, 0, + 148, 92, 82, 131, 81, 71, 116, 71, 62, 100, 60, 53, 84, 49, 42, 69, 37, 30, 52, 23, 16, 31, 2, 0, 0, 0, 0, + 148, 91, 67, 132, 81, 57, 117, 71, 49, 100, 60, 39, 84, 49, 30, 69, 37, 18, 52, 23, 2, 30, 2, 0, 0, 0, 0, + 149, 91, 54, 132, 81, 46, 118, 71, 39, 101, 60, 29, 85, 49, 19, 69, 37, 6, 52, 23, 0, 29, 3, 0, 0, 0, 0, + 143, 68, 153, 128, 59, 137, 115, 49, 122, 99, 39, 107, 85, 28, 91, 70, 13, 75, 54, 0, 58, 32, 0, 36, 0, 0, 0, + 146, 68, 140, 131, 59, 125, 116, 51, 111, 100, 40, 97, 85, 29, 82, 70, 15, 67, 54, 0, 50, 32, 0, 29, 0, 0, 0, + 147, 68, 127, 131, 59, 114, 117, 51, 102, 101, 41, 88, 86, 30, 74, 70, 17, 60, 54, 0, 44, 32, 0, 23, 0, 0, 0, + 147, 70, 115, 131, 60, 103, 116, 52, 91, 100, 42, 78, 85, 32, 65, 70, 19, 53, 54, 1, 38, 32, 0, 17, 0, 0, 0, + 147, 70, 103, 131, 61, 91, 117, 53, 81, 101, 43, 69, 86, 32, 57, 70, 20, 44, 54, 2, 30, 32, 0, 7, 0, 0, 0, + 148, 70, 91, 132, 61, 80, 117, 52, 70, 101, 43, 59, 85, 33, 48, 70, 21, 36, 53, 4, 22, 32, 0, 3, 0, 0, 0, + 148, 70, 78, 132, 62, 68, 117, 53, 58, 101, 43, 48, 85, 34, 38, 70, 22, 26, 53, 6, 12, 31, 0, 0, 0, 0, 0, + 149, 71, 64, 132, 62, 54, 118, 54, 46, 101, 44, 37, 85, 34, 27, 69, 23, 15, 53, 7, 1, 30, 0, 0, 0, 0, 0, + 150, 70, 53, 134, 61, 44, 118, 54, 36, 101, 44, 28, 85, 35, 17, 69, 23, 4, 52, 8, 0, 30, 0, 0, 0, 0, 0, + 145, 38, 143, 130, 29, 128, 117, 18, 114, 101, 3, 98, 87, 0, 84, 72, 0, 69, 54, 0, 53, 30, 0, 31, 0, 0, 0, + 147, 38, 130, 132, 30, 116, 117, 22, 103, 101, 8, 89, 87, 0, 76, 72, 0, 62, 54, 0, 46, 30, 0, 24, 0, 0, 0, + 148, 40, 119, 132, 31, 105, 117, 23, 94, 101, 13, 81, 87, 0, 68, 71, 0, 55, 54, 0, 39, 30, 0, 18, 0, 0, 0, + 148, 42, 108, 132, 34, 96, 117, 25, 85, 102, 15, 73, 86, 2, 60, 71, 0, 47, 54, 0, 33, 30, 0, 11, 0, 0, 0, + 148, 43, 96, 133, 35, 85, 117, 28, 75, 102, 18, 64, 87, 5, 52, 71, 0, 40, 54, 0, 25, 30, 0, 5, 0, 0, 0, + 149, 44, 85, 132, 36, 75, 118, 29, 66, 101, 20, 55, 86, 8, 44, 70, 0, 32, 53, 0, 18, 29, 0, 2, 0, 0, 0, + 149, 45, 74, 133, 37, 64, 118, 31, 55, 102, 21, 45, 85, 10, 34, 70, 0, 22, 53, 0, 6, 28, 0, 0, 0, 0, 0, + 150, 46, 61, 133, 39, 52, 118, 31, 44, 102, 23, 34, 85, 12, 24, 70, 0, 12, 52, 0, 0, 28, 0, 0, 0, 0, 0, + 150, 46, 51, 133, 40, 42, 119, 32, 35, 102, 24, 25, 85, 13, 14, 70, 0, 1, 52, 0, 0, 27, 0, 0, 0, 0, 0, + 53, 198, 244, 49, 177, 218, 41, 158, 195, 32, 138, 171, 22, 118, 147, 11, 98, 124, 0, 78, 100, 0, 54, 71, 0, 18, 34, + 69, 196, 220, 64, 175, 196, 54, 157, 176, 45, 137, 154, 32, 117, 133, 19, 98, 111, 0, 78, 89, 0, 53, 63, 0, 17, 27, + 80, 195, 198, 69, 175, 179, 60, 156, 159, 50, 136, 139, 38, 116, 120, 25, 98, 101, 4, 77, 80, 0, 53, 55, 0, 17, 21, + 84, 193, 177, 75, 173, 159, 64, 155, 142, 55, 135, 124, 41, 116, 107, 27, 97, 89, 9, 76, 70, 0, 53, 47, 0, 17, 11, + 89, 193, 157, 79, 172, 140, 70, 154, 125, 57, 134, 109, 44, 115, 92, 32, 96, 76, 13, 76, 59, 0, 52, 39, 0, 16, 4, + 94, 191, 135, 85, 171, 121, 72, 152, 108, 60, 133, 94, 47, 114, 80, 32, 95, 65, 15, 76, 49, 0, 52, 29, 0, 16, 0, + 98, 190, 113, 87, 170, 100, 76, 152, 89, 62, 132, 77, 49, 113, 65, 35, 95, 52, 18, 75, 37, 0, 52, 18, 0, 15, 0, + 103, 190, 89, 90, 169, 80, 78, 151, 70, 64, 132, 60, 51, 113, 49, 37, 94, 38, 20, 75, 25, 0, 52, 5, 0, 15, 0, + 106, 189, 69, 93, 169, 61, 80, 151, 53, 66, 131, 45, 52, 113, 36, 37, 94, 25, 19, 74, 11, 0, 51, 0, 0, 15, 0, + 76, 178, 229, 68, 159, 205, 61, 142, 183, 50, 124, 160, 40, 106, 138, 28, 88, 116, 12, 69, 93, 0, 45, 66, 0, 5, 29, + 86, 177, 207, 78, 158, 184, 67, 142, 166, 56, 123, 145, 45, 106, 125, 31, 88, 105, 16, 69, 83, 0, 45, 58, 0, 6, 22, + 93, 176, 187, 81, 158, 168, 71, 141, 150, 61, 123, 131, 47, 105, 113, 35, 87, 94, 20, 68, 74, 0, 45, 51, 0, 5, 16, + 98, 175, 168, 84, 157, 150, 75, 140, 134, 63, 122, 117, 50, 104, 100, 37, 87, 83, 21, 68, 65, 0, 45, 42, 0, 4, 7, + 100, 174, 149, 89, 155, 132, 76, 139, 117, 65, 121, 102, 53, 104, 87, 39, 86, 72, 23, 67, 55, 0, 45, 34, 0, 3, 0, + 103, 173, 130, 92, 155, 115, 80, 138, 102, 68, 120, 88, 53, 103, 75, 40, 86, 61, 24, 67, 45, 0, 45, 25, 0, 3, 0, + 107, 172, 108, 95, 154, 96, 82, 137, 85, 70, 119, 73, 55, 102, 61, 42, 85, 49, 25, 67, 34, 0, 45, 14, 0, 3, 0, + 110, 172, 86, 97, 153, 76, 85, 137, 67, 70, 119, 57, 56, 102, 46, 42, 84, 35, 26, 66, 21, 0, 44, 1, 0, 3, 0, + 112, 171, 67, 98, 153, 59, 86, 137, 52, 71, 119, 44, 58, 102, 34, 44, 85, 22, 27, 66, 7, 0, 44, 0, 0, 3, 0, + 90, 160, 215, 81, 144, 193, 70, 129, 173, 61, 112, 151, 49, 95, 131, 37, 79, 109, 22, 61, 87, 0, 38, 61, 0, 0, 25, + 96, 160, 194, 86, 143, 174, 75, 128, 157, 65, 112, 137, 53, 95, 117, 40, 78, 98, 25, 60, 78, 0, 38, 53, 0, 0, 17, + 100, 159, 177, 89, 143, 159, 79, 128, 143, 67, 111, 124, 55, 95, 107, 42, 78, 89, 27, 60, 70, 2, 38, 46, 0, 0, 9, + 104, 158, 159, 92, 142, 143, 81, 127, 127, 69, 110, 110, 56, 94, 94, 43, 78, 78, 28, 60, 60, 2, 38, 38, 0, 0, 1, + 107, 157, 140, 94, 141, 125, 82, 126, 112, 71, 110, 97, 59, 94, 82, 45, 77, 67, 29, 59, 51, 4, 37, 30, 0, 0, 0, + 110, 156, 122, 97, 140, 109, 85, 125, 97, 72, 109, 83, 58, 93, 71, 45, 77, 57, 29, 60, 42, 5, 38, 22, 0, 0, 0, + 111, 156, 103, 99, 139, 91, 87, 125, 81, 73, 108, 69, 60, 92, 58, 46, 77, 45, 30, 59, 31, 5, 38, 12, 0, 0, 0, + 115, 156, 82, 101, 140, 73, 88, 124, 63, 74, 108, 53, 60, 92, 44, 46, 76, 32, 31, 59, 18, 6, 37, 0, 0, 0, 0, + 116, 155, 65, 102, 139, 58, 89, 124, 49, 75, 108, 41, 61, 92, 32, 48, 76, 21, 31, 59, 6, 5, 37, 0, 0, 0, 0, + 100, 141, 201, 88, 127, 181, 79, 114, 162, 69, 99, 142, 57, 83, 122, 44, 68, 102, 30, 51, 81, 7, 28, 56, 0, 0, 19, + 105, 141, 182, 94, 127, 163, 83, 114, 146, 71, 98, 128, 59, 83, 110, 46, 68, 91, 31, 51, 72, 10, 28, 48, 0, 0, 11, + 108, 141, 166, 96, 127, 149, 85, 113, 133, 73, 98, 116, 60, 83, 99, 46, 68, 82, 32, 51, 64, 11, 29, 41, 0, 0, 2, + 111, 141, 149, 98, 126, 134, 88, 112, 119, 74, 97, 103, 61, 83, 88, 48, 67, 72, 33, 51, 56, 11, 29, 34, 0, 0, 0, + 112, 140, 132, 100, 125, 118, 89, 112, 105, 75, 97, 91, 62, 82, 77, 49, 68, 62, 33, 51, 47, 12, 29, 26, 0, 0, 0, + 115, 140, 116, 102, 125, 103, 90, 111, 91, 76, 96, 78, 62, 82, 65, 49, 67, 52, 34, 51, 38, 13, 29, 18, 0, 0, 0, + 117, 139, 97, 103, 124, 87, 91, 111, 77, 78, 96, 65, 63, 81, 54, 49, 67, 41, 34, 51, 27, 12, 29, 7, 0, 0, 0, + 119, 138, 78, 105, 124, 69, 92, 110, 60, 78, 95, 50, 65, 81, 40, 50, 67, 29, 34, 51, 15, 13, 30, 0, 0, 0, 0, + 120, 138, 64, 106, 124, 54, 93, 110, 47, 78, 95, 38, 65, 81, 29, 50, 66, 17, 34, 50, 2, 13, 29, 0, 0, 0, 0, + 107, 124, 189, 96, 111, 169, 85, 99, 152, 73, 85, 132, 61, 71, 114, 48, 57, 95, 34, 41, 75, 14, 18, 51, 0, 0, 13, + 111, 124, 171, 100, 111, 153, 88, 99, 137, 75, 85, 120, 63, 72, 103, 50, 58, 85, 36, 41, 66, 15, 19, 43, 0, 0, 4, + 113, 124, 156, 101, 111, 139, 90, 99, 125, 77, 85, 109, 64, 71, 93, 51, 57, 77, 36, 42, 59, 17, 20, 37, 0, 0, 0, + 115, 124, 140, 103, 111, 125, 90, 99, 112, 78, 85, 97, 64, 71, 82, 52, 57, 67, 36, 42, 50, 16, 20, 30, 0, 0, 0, + 117, 123, 125, 104, 110, 111, 92, 98, 99, 79, 85, 86, 65, 71, 72, 51, 58, 59, 37, 42, 43, 17, 21, 22, 0, 0, 0, + 118, 123, 110, 105, 110, 97, 93, 98, 86, 78, 84, 74, 66, 71, 62, 52, 57, 49, 37, 42, 34, 17, 22, 14, 0, 0, 0, + 120, 123, 93, 106, 109, 82, 94, 97, 72, 80, 84, 61, 66, 71, 50, 52, 57, 38, 37, 42, 24, 17, 22, 2, 0, 0, 0, + 121, 122, 75, 108, 109, 66, 95, 97, 58, 80, 84, 48, 66, 71, 37, 52, 57, 26, 37, 42, 12, 16, 22, 0, 0, 0, 0, + 122, 123, 62, 108, 109, 52, 95, 97, 45, 81, 84, 36, 67, 70, 26, 52, 57, 14, 37, 42, 0, 15, 22, 0, 0, 0, 0, + 113, 107, 177, 102, 96, 159, 89, 85, 141, 78, 72, 124, 65, 60, 107, 52, 46, 89, 37, 30, 70, 18, 5, 46, 0, 0, 6, + 116, 107, 160, 104, 96, 144, 92, 85, 129, 80, 72, 112, 67, 60, 96, 53, 47, 80, 38, 31, 62, 19, 7, 39, 0, 0, 0, + 118, 107, 147, 105, 96, 131, 93, 85, 118, 80, 72, 101, 67, 60, 87, 54, 47, 71, 39, 31, 54, 19, 8, 32, 0, 0, 0, + 119, 107, 132, 106, 96, 118, 94, 85, 106, 81, 73, 91, 67, 60, 77, 54, 47, 63, 39, 32, 47, 20, 9, 25, 0, 0, 0, + 119, 107, 118, 106, 95, 105, 94, 85, 93, 81, 72, 80, 68, 60, 68, 54, 47, 54, 39, 32, 39, 20, 11, 18, 0, 0, 0, + 121, 107, 104, 107, 96, 92, 95, 84, 80, 81, 72, 69, 68, 61, 58, 54, 48, 46, 39, 33, 31, 20, 12, 9, 0, 0, 0, + 123, 107, 88, 108, 95, 77, 96, 84, 68, 82, 72, 57, 68, 60, 46, 54, 47, 35, 39, 33, 20, 19, 13, 2, 0, 0, 0, + 123, 106, 72, 110, 95, 63, 96, 84, 54, 82, 72, 45, 69, 60, 35, 55, 48, 23, 39, 33, 9, 18, 14, 0, 0, 0, 0, + 125, 106, 60, 110, 94, 50, 98, 84, 42, 83, 72, 34, 69, 60, 25, 55, 48, 12, 39, 33, 0, 17, 13, 0, 0, 0, 0, + 118, 89, 165, 105, 79, 148, 93, 69, 132, 81, 57, 115, 68, 45, 99, 55, 32, 82, 41, 15, 64, 21, 0, 41, 0, 0, 0, + 120, 89, 150, 107, 79, 135, 96, 69, 121, 82, 58, 105, 70, 46, 89, 56, 34, 73, 41, 17, 56, 21, 0, 34, 0, 0, 0, + 121, 89, 137, 108, 79, 123, 96, 69, 109, 82, 58, 95, 70, 47, 81, 56, 34, 66, 41, 18, 49, 21, 0, 28, 0, 0, 0, + 122, 90, 124, 109, 79, 110, 96, 69, 99, 83, 58, 85, 70, 47, 72, 56, 35, 58, 41, 19, 42, 21, 0, 22, 0, 0, 0, + 123, 90, 111, 110, 79, 98, 97, 69, 87, 83, 59, 75, 70, 47, 63, 56, 35, 50, 41, 20, 35, 21, 0, 14, 0, 0, 0, + 123, 90, 98, 110, 79, 87, 97, 70, 76, 84, 58, 64, 70, 48, 53, 56, 36, 41, 40, 21, 26, 21, 0, 5, 0, 0, 0, + 125, 89, 84, 111, 79, 73, 97, 69, 64, 84, 59, 54, 70, 48, 43, 56, 36, 31, 40, 22, 17, 20, 1, 1, 0, 0, 0, + 125, 89, 69, 112, 79, 60, 98, 70, 51, 84, 59, 42, 70, 48, 32, 56, 36, 20, 41, 22, 5, 19, 2, 0, 0, 0, 0, + 126, 89, 57, 112, 79, 49, 99, 70, 41, 84, 59, 32, 70, 48, 22, 56, 36, 10, 40, 22, 0, 18, 2, 0, 0, 0, 0, + 121, 67, 154, 108, 58, 138, 97, 50, 124, 84, 39, 107, 71, 28, 92, 58, 12, 76, 43, 0, 59, 20, 0, 37, 0, 0, 0, + 124, 68, 140, 111, 59, 126, 98, 50, 112, 84, 40, 98, 71, 29, 83, 58, 15, 67, 42, 0, 51, 20, 0, 30, 0, 0, 0, + 124, 68, 129, 111, 59, 114, 99, 51, 102, 86, 41, 88, 71, 30, 75, 58, 17, 60, 42, 0, 45, 20, 0, 24, 0, 0, 0, + 125, 70, 116, 111, 60, 103, 99, 51, 92, 85, 41, 79, 71, 31, 66, 58, 19, 53, 42, 3, 38, 20, 0, 17, 0, 0, 0, + 125, 70, 104, 111, 61, 93, 99, 52, 81, 85, 43, 69, 72, 32, 58, 58, 20, 45, 42, 4, 31, 20, 0, 8, 0, 0, 0, + 126, 70, 92, 111, 61, 81, 99, 52, 71, 85, 42, 60, 71, 33, 49, 57, 21, 37, 42, 6, 23, 20, 0, 3, 0, 0, 0, + 126, 70, 79, 112, 61, 70, 99, 53, 60, 85, 43, 50, 71, 33, 39, 57, 22, 28, 41, 7, 13, 19, 0, 0, 0, 0, 0, + 127, 71, 66, 113, 62, 56, 100, 53, 48, 86, 44, 39, 71, 34, 29, 57, 23, 18, 41, 8, 2, 18, 0, 0, 0, 0, 0, + 128, 70, 55, 114, 62, 46, 100, 54, 39, 86, 44, 30, 71, 34, 20, 57, 23, 7, 41, 9, 0, 18, 0, 0, 0, 0, 0, + 124, 41, 145, 111, 32, 128, 99, 23, 114, 86, 10, 100, 73, 0, 85, 60, 0, 71, 43, 0, 54, 17, 0, 32, 0, 0, 0, + 126, 42, 131, 113, 33, 117, 100, 25, 104, 86, 14, 90, 73, 0, 77, 60, 0, 63, 44, 0, 47, 18, 0, 25, 0, 0, 0, + 127, 43, 120, 113, 34, 106, 101, 26, 95, 86, 17, 82, 73, 2, 69, 59, 0, 56, 43, 0, 41, 18, 0, 19, 0, 0, 0, + 127, 45, 109, 113, 37, 97, 101, 28, 85, 86, 19, 74, 73, 5, 61, 59, 0, 48, 43, 0, 34, 19, 0, 11, 0, 0, 0, + 127, 46, 98, 114, 38, 86, 100, 30, 76, 87, 21, 65, 73, 9, 54, 59, 0, 41, 43, 0, 26, 18, 0, 5, 0, 0, 0, + 127, 47, 87, 113, 39, 76, 101, 31, 67, 86, 22, 56, 72, 11, 45, 59, 0, 33, 43, 0, 19, 18, 0, 2, 0, 0, 0, + 128, 48, 75, 114, 39, 65, 101, 33, 56, 86, 23, 46, 72, 12, 36, 58, 0, 24, 42, 0, 9, 17, 0, 0, 0, 0, 0, + 129, 48, 63, 114, 41, 54, 102, 33, 46, 87, 24, 36, 72, 14, 26, 58, 1, 14, 42, 0, 2, 16, 0, 0, 0, 0, 0, + 128, 48, 53, 114, 41, 44, 102, 34, 37, 87, 25, 27, 72, 15, 17, 58, 1, 3, 41, 0, 0, 15, 0, 0, 0, 0, 0, + 0, 189, 242, 0, 169, 217, 0, 151, 194, 0, 132, 170, 0, 113, 147, 0, 94, 123, 0, 74, 99, 0, 51, 71, 0, 15, 34, + 1, 187, 219, 1, 167, 195, 0, 150, 175, 0, 131, 153, 0, 113, 132, 0, 94, 111, 0, 74, 89, 0, 50, 63, 0, 13, 28, + 1, 186, 198, 1, 167, 178, 0, 149, 158, 0, 130, 139, 0, 111, 119, 0, 93, 100, 0, 74, 80, 0, 50, 55, 0, 13, 22, + 1, 185, 176, 1, 165, 159, 1, 148, 142, 0, 129, 123, 0, 111, 106, 0, 93, 89, 0, 73, 70, 0, 50, 47, 0, 13, 13, + 1, 184, 157, 1, 164, 141, 1, 147, 125, 0, 128, 110, 0, 110, 93, 0, 92, 77, 0, 73, 60, 0, 50, 39, 0, 12, 5, + 25, 182, 137, 25, 163, 122, 17, 146, 109, 0, 128, 96, 0, 110, 81, 0, 92, 66, 0, 73, 51, 0, 50, 30, 0, 10, 0, + 42, 181, 114, 35, 163, 102, 30, 145, 91, 14, 127, 80, 0, 109, 67, 0, 91, 53, 0, 72, 39, 0, 50, 19, 0, 10, 0, + 52, 181, 92, 43, 162, 83, 32, 145, 73, 19, 126, 63, 0, 108, 52, 0, 90, 40, 0, 72, 27, 0, 50, 7, 0, 10, 0, + 57, 181, 74, 48, 162, 66, 37, 144, 57, 24, 126, 49, 7, 108, 40, 0, 90, 29, 0, 72, 15, 0, 49, 0, 0, 10, 0, + 1, 170, 227, 1, 152, 203, 0, 136, 182, 0, 119, 159, 0, 101, 137, 0, 84, 115, 0, 65, 92, 0, 43, 66, 0, 1, 29, + 1, 169, 206, 1, 151, 184, 1, 136, 165, 0, 118, 144, 0, 102, 125, 0, 84, 105, 0, 65, 83, 0, 43, 58, 0, 0, 22, + 29, 168, 186, 21, 151, 167, 14, 135, 150, 4, 118, 131, 0, 101, 112, 0, 83, 94, 0, 65, 75, 0, 43, 51, 0, 0, 16, + 41, 167, 167, 33, 150, 150, 31, 134, 134, 19, 117, 117, 4, 100, 100, 0, 83, 83, 0, 65, 65, 0, 42, 43, 0, 0, 8, + 48, 167, 149, 41, 149, 133, 33, 133, 118, 25, 116, 103, 13, 99, 88, 0, 83, 73, 0, 65, 56, 0, 42, 35, 0, 0, 0, + 58, 165, 130, 49, 148, 115, 42, 132, 103, 31, 115, 89, 18, 99, 75, 0, 82, 61, 0, 64, 46, 0, 42, 26, 0, 0, 0, + 62, 164, 110, 55, 147, 97, 45, 132, 87, 35, 115, 75, 22, 98, 63, 5, 82, 50, 0, 64, 36, 0, 42, 16, 0, 0, 0, + 69, 164, 89, 60, 147, 78, 50, 131, 70, 37, 114, 59, 26, 98, 49, 10, 81, 37, 0, 64, 24, 0, 42, 4, 0, 0, 0, + 71, 164, 71, 63, 147, 63, 53, 131, 55, 40, 114, 47, 28, 98, 38, 13, 81, 26, 0, 64, 12, 0, 42, 0, 0, 0, 0, + 28, 153, 214, 24, 138, 193, 23, 123, 171, 16, 107, 150, 0, 91, 130, 0, 75, 109, 0, 58, 87, 0, 35, 61, 0, 0, 25, + 48, 153, 194, 41, 138, 174, 34, 123, 156, 27, 107, 136, 16, 91, 117, 1, 75, 98, 0, 57, 78, 0, 35, 53, 0, 0, 17, + 55, 153, 177, 47, 137, 158, 42, 122, 142, 33, 107, 124, 22, 91, 106, 6, 75, 88, 0, 57, 70, 0, 35, 46, 0, 0, 9, + 61, 152, 158, 53, 136, 143, 45, 122, 127, 36, 106, 111, 24, 90, 94, 10, 74, 78, 0, 57, 61, 0, 35, 39, 0, 0, 2, + 67, 151, 141, 59, 135, 126, 49, 121, 112, 39, 105, 98, 29, 90, 83, 14, 74, 68, 0, 57, 52, 0, 35, 31, 0, 0, 0, + 71, 150, 123, 62, 135, 110, 54, 120, 98, 42, 105, 84, 31, 89, 71, 16, 74, 58, 0, 57, 43, 0, 35, 22, 0, 0, 0, + 74, 150, 105, 64, 134, 92, 55, 120, 83, 45, 104, 71, 34, 89, 59, 20, 73, 47, 0, 57, 32, 0, 35, 13, 0, 0, 0, + 78, 149, 84, 69, 134, 75, 59, 120, 66, 47, 103, 56, 34, 88, 46, 22, 73, 34, 1, 57, 20, 0, 35, 1, 0, 0, 0, + 80, 149, 69, 70, 133, 61, 60, 119, 53, 49, 103, 44, 36, 88, 35, 23, 73, 24, 2, 56, 10, 0, 35, 0, 0, 0, 0, + 58, 136, 200, 50, 122, 180, 45, 109, 162, 38, 94, 141, 27, 80, 121, 15, 65, 102, 0, 48, 81, 0, 26, 56, 0, 0, 19, + 66, 136, 182, 59, 122, 163, 52, 109, 146, 42, 94, 128, 32, 80, 109, 20, 65, 91, 2, 48, 72, 0, 26, 49, 0, 0, 11, + 70, 136, 165, 62, 122, 149, 55, 108, 133, 46, 94, 116, 35, 80, 99, 21, 65, 82, 4, 49, 64, 0, 26, 41, 0, 0, 3, + 76, 135, 149, 66, 121, 133, 58, 108, 119, 48, 94, 103, 36, 79, 88, 23, 65, 73, 7, 49, 56, 0, 27, 34, 0, 0, 0, + 78, 135, 133, 69, 120, 118, 60, 107, 106, 50, 93, 92, 39, 79, 77, 26, 65, 63, 8, 49, 47, 0, 27, 26, 0, 0, 0, + 82, 134, 117, 71, 120, 104, 62, 107, 92, 51, 93, 79, 39, 78, 66, 27, 64, 53, 10, 48, 39, 0, 27, 18, 0, 0, 0, + 84, 134, 99, 73, 119, 87, 64, 106, 77, 53, 92, 66, 42, 78, 55, 28, 64, 42, 11, 48, 29, 0, 28, 9, 0, 0, 0, + 87, 133, 81, 76, 119, 72, 66, 106, 62, 55, 92, 52, 43, 78, 42, 29, 64, 31, 12, 48, 17, 0, 28, 0, 0, 0, 0, + 88, 134, 67, 77, 119, 58, 68, 106, 51, 56, 92, 42, 44, 78, 32, 30, 64, 20, 12, 48, 6, 0, 28, 0, 0, 0, 0, + 73, 120, 189, 64, 107, 168, 57, 96, 151, 47, 82, 133, 38, 69, 114, 26, 55, 95, 11, 39, 75, 0, 16, 51, 0, 0, 14, + 78, 120, 171, 69, 107, 153, 62, 95, 137, 51, 82, 119, 40, 69, 102, 29, 55, 85, 15, 39, 66, 0, 17, 44, 0, 0, 4, + 81, 120, 156, 71, 107, 140, 64, 95, 125, 53, 82, 109, 42, 69, 93, 31, 55, 77, 16, 39, 59, 0, 18, 37, 0, 0, 0, + 85, 120, 141, 74, 107, 126, 65, 95, 112, 54, 82, 97, 43, 69, 82, 32, 55, 67, 17, 39, 51, 0, 19, 30, 0, 0, 0, + 86, 119, 126, 76, 106, 112, 66, 95, 100, 56, 81, 85, 45, 69, 72, 33, 55, 59, 18, 40, 43, 0, 19, 22, 0, 0, 0, + 89, 119, 110, 78, 106, 98, 69, 94, 87, 56, 81, 75, 46, 68, 62, 33, 55, 49, 18, 40, 35, 0, 20, 15, 0, 0, 0, + 89, 119, 95, 80, 106, 83, 70, 94, 73, 58, 81, 63, 46, 68, 51, 34, 55, 39, 19, 40, 25, 0, 20, 4, 0, 0, 0, + 92, 118, 78, 82, 106, 68, 70, 93, 59, 59, 81, 49, 47, 68, 39, 34, 55, 28, 19, 40, 14, 0, 20, 0, 0, 0, 0, + 93, 118, 65, 82, 105, 55, 72, 93, 48, 60, 81, 39, 47, 68, 29, 34, 55, 18, 20, 40, 2, 0, 20, 0, 0, 0, 0, + 83, 104, 177, 74, 93, 159, 65, 82, 142, 56, 70, 124, 45, 57, 106, 33, 44, 89, 20, 28, 70, 1, 4, 46, 0, 0, 8, + 86, 104, 161, 78, 93, 145, 68, 82, 128, 58, 70, 112, 48, 58, 96, 35, 45, 80, 21, 29, 62, 1, 6, 40, 0, 0, 0, + 89, 104, 147, 79, 93, 131, 69, 82, 118, 59, 70, 102, 47, 58, 87, 36, 45, 72, 23, 29, 55, 3, 7, 33, 0, 0, 0, + 90, 104, 132, 80, 93, 119, 71, 82, 106, 60, 70, 91, 48, 58, 77, 37, 45, 62, 23, 30, 47, 4, 7, 26, 0, 0, 0, + 92, 104, 118, 82, 93, 105, 72, 82, 93, 61, 69, 80, 50, 58, 68, 37, 45, 55, 23, 30, 39, 4, 8, 18, 0, 0, 0, + 94, 104, 105, 82, 92, 93, 72, 82, 82, 61, 70, 70, 50, 58, 58, 38, 46, 46, 23, 31, 31, 6, 10, 11, 0, 0, 0, + 95, 104, 90, 84, 92, 79, 74, 82, 70, 62, 70, 58, 50, 58, 48, 37, 46, 36, 23, 31, 22, 4, 11, 3, 0, 0, 0, + 96, 103, 74, 85, 92, 65, 75, 81, 56, 63, 70, 47, 50, 58, 37, 38, 46, 25, 24, 31, 11, 3, 11, 0, 0, 0, 0, + 97, 103, 62, 86, 92, 53, 76, 81, 45, 63, 69, 36, 51, 58, 27, 38, 46, 15, 23, 31, 0, 3, 11, 0, 0, 0, 0, + 90, 87, 165, 81, 77, 148, 72, 67, 132, 62, 55, 116, 50, 44, 99, 39, 31, 82, 25, 14, 64, 1, 0, 42, 0, 0, 1, + 93, 87, 150, 83, 77, 135, 74, 67, 121, 63, 56, 105, 52, 45, 90, 40, 32, 74, 25, 16, 57, 3, 0, 35, 0, 0, 0, + 95, 87, 138, 85, 77, 123, 75, 67, 109, 63, 57, 95, 53, 45, 81, 41, 33, 66, 26, 17, 50, 4, 0, 28, 0, 0, 0, + 95, 88, 124, 85, 77, 111, 75, 67, 99, 63, 57, 86, 53, 45, 72, 41, 33, 58, 26, 18, 43, 5, 1, 22, 0, 0, 0, + 97, 88, 112, 87, 77, 100, 76, 68, 88, 64, 57, 76, 53, 46, 63, 41, 34, 50, 26, 19, 35, 5, 2, 14, 0, 0, 0, + 99, 87, 99, 87, 78, 88, 76, 68, 77, 65, 57, 65, 53, 46, 54, 41, 35, 42, 27, 20, 27, 6, 2, 5, 0, 0, 0, + 100, 87, 85, 88, 77, 75, 77, 68, 65, 65, 57, 54, 53, 46, 44, 41, 35, 32, 27, 21, 19, 5, 3, 2, 0, 0, 0, + 100, 88, 71, 89, 77, 61, 78, 68, 53, 66, 57, 44, 53, 47, 33, 41, 35, 22, 27, 21, 7, 5, 3, 0, 0, 0, 0, + 101, 87, 60, 90, 77, 52, 79, 68, 44, 66, 58, 34, 53, 47, 25, 41, 35, 13, 26, 22, 0, 5, 3, 0, 0, 0, 0, + 97, 67, 155, 86, 58, 138, 77, 50, 125, 66, 39, 108, 55, 28, 92, 43, 12, 76, 29, 0, 59, 2, 0, 37, 0, 0, 0, + 99, 67, 141, 88, 59, 127, 78, 50, 113, 68, 40, 98, 56, 29, 83, 44, 15, 68, 29, 0, 52, 3, 0, 30, 0, 0, 0, + 100, 68, 129, 89, 59, 115, 80, 51, 103, 68, 41, 89, 56, 30, 75, 44, 16, 61, 30, 0, 45, 4, 0, 24, 0, 0, 0, + 100, 69, 118, 90, 60, 104, 80, 51, 92, 67, 41, 79, 56, 31, 66, 44, 18, 53, 29, 2, 38, 4, 0, 18, 0, 0, 0, + 101, 69, 104, 90, 61, 93, 79, 51, 82, 67, 42, 70, 56, 32, 59, 44, 20, 46, 29, 4, 31, 6, 0, 9, 0, 0, 0, + 102, 69, 93, 90, 61, 83, 80, 52, 72, 68, 42, 61, 56, 33, 50, 43, 20, 38, 29, 5, 23, 7, 0, 4, 0, 0, 0, + 102, 70, 80, 91, 61, 71, 80, 52, 61, 68, 43, 51, 56, 32, 40, 44, 21, 29, 30, 6, 14, 7, 0, 0, 0, 0, 0, + 103, 70, 68, 92, 61, 58, 81, 53, 50, 69, 43, 41, 56, 34, 31, 43, 22, 19, 29, 7, 3, 7, 0, 0, 0, 0, 0, + 104, 70, 57, 92, 61, 48, 82, 53, 40, 69, 43, 32, 56, 34, 22, 43, 23, 10, 29, 8, 0, 6, 0, 0, 0, 0, 0, + 101, 45, 145, 91, 35, 129, 80, 26, 116, 69, 15, 101, 59, 0, 86, 46, 0, 71, 31, 0, 55, 0, 0, 33, 0, 0, 0, + 104, 44, 132, 92, 36, 118, 82, 28, 105, 71, 17, 91, 58, 3, 77, 46, 0, 63, 31, 0, 48, 2, 0, 26, 0, 0, 0, + 104, 46, 121, 93, 37, 107, 82, 30, 96, 70, 20, 83, 58, 6, 70, 46, 0, 57, 32, 0, 41, 4, 0, 20, 0, 0, 0, + 104, 48, 110, 93, 40, 98, 82, 31, 87, 70, 22, 74, 59, 9, 62, 45, 0, 49, 31, 0, 35, 6, 0, 13, 0, 0, 0, + 104, 48, 99, 92, 41, 88, 82, 32, 77, 70, 23, 65, 58, 11, 54, 46, 0, 42, 32, 0, 27, 7, 0, 5, 0, 0, 0, + 105, 50, 88, 93, 41, 77, 82, 34, 68, 71, 24, 57, 58, 13, 46, 45, 1, 35, 31, 0, 21, 7, 0, 2, 0, 0, 0, + 105, 50, 76, 94, 41, 66, 83, 34, 57, 71, 25, 47, 58, 15, 37, 45, 2, 25, 32, 0, 11, 7, 0, 0, 0, 0, 0, + 106, 50, 64, 94, 42, 55, 83, 35, 47, 71, 26, 38, 58, 16, 27, 45, 4, 17, 31, 0, 4, 7, 0, 0, 0, 0, 0, + 106, 51, 54, 95, 42, 45, 83, 35, 38, 71, 27, 30, 58, 16, 19, 45, 5, 7, 30, 0, 0, 6, 0, 0, 0, 0, 0, + 0, 181, 240, 0, 162, 216, 0, 144, 193, 0, 126, 168, 0, 109, 146, 0, 91, 123, 0, 71, 98, 0, 48, 71, 0, 9, 34, + 0, 179, 218, 0, 161, 195, 0, 144, 174, 0, 126, 153, 0, 108, 132, 0, 90, 110, 0, 71, 88, 0, 48, 63, 0, 8, 29, + 0, 178, 197, 0, 159, 177, 0, 143, 159, 0, 125, 139, 0, 107, 119, 0, 90, 99, 0, 71, 79, 0, 48, 55, 0, 8, 22, + 0, 177, 177, 0, 158, 158, 0, 142, 141, 0, 124, 123, 0, 107, 106, 0, 89, 88, 0, 71, 70, 0, 48, 47, 0, 8, 14, + 0, 176, 157, 0, 158, 141, 0, 141, 126, 0, 123, 109, 0, 106, 93, 0, 89, 78, 0, 70, 60, 0, 47, 39, 0, 7, 5, + 0, 175, 138, 0, 157, 123, 0, 141, 110, 0, 123, 96, 0, 105, 81, 0, 88, 67, 0, 70, 51, 0, 48, 30, 0, 6, 0, + 0, 173, 115, 0, 155, 104, 0, 140, 92, 0, 122, 80, 0, 105, 67, 0, 88, 55, 0, 69, 40, 0, 47, 20, 0, 6, 0, + 0, 173, 94, 0, 155, 85, 0, 139, 75, 0, 121, 64, 0, 104, 53, 0, 88, 42, 0, 70, 28, 0, 47, 9, 0, 6, 0, + 0, 173, 76, 0, 155, 70, 0, 138, 61, 0, 122, 53, 0, 104, 44, 0, 87, 32, 0, 69, 18, 0, 47, 0, 0, 6, 0, + 0, 164, 226, 0, 147, 203, 0, 131, 181, 0, 114, 158, 0, 97, 136, 0, 80, 115, 0, 63, 92, 0, 40, 65, 0, 0, 30, + 0, 162, 205, 0, 145, 184, 0, 130, 164, 0, 114, 143, 0, 97, 124, 0, 81, 104, 0, 63, 83, 0, 40, 58, 0, 0, 23, + 0, 162, 187, 0, 145, 167, 0, 130, 150, 0, 113, 131, 0, 96, 112, 0, 80, 93, 0, 62, 74, 0, 40, 50, 0, 0, 16, + 0, 160, 167, 0, 144, 150, 0, 129, 134, 0, 112, 116, 0, 96, 100, 0, 80, 82, 0, 62, 65, 0, 40, 43, 0, 0, 7, + 0, 160, 148, 0, 143, 133, 0, 128, 118, 0, 111, 103, 0, 96, 88, 0, 80, 73, 0, 62, 56, 0, 40, 35, 0, 0, 0, + 0, 158, 130, 0, 142, 117, 0, 127, 104, 0, 111, 89, 0, 95, 76, 0, 79, 62, 0, 62, 46, 0, 40, 26, 0, 0, 0, + 0, 158, 111, 0, 141, 99, 0, 127, 88, 0, 111, 76, 0, 95, 63, 0, 79, 51, 0, 62, 37, 0, 40, 18, 0, 0, 0, + 0, 158, 91, 0, 141, 81, 0, 126, 72, 0, 110, 62, 0, 94, 50, 0, 79, 39, 0, 62, 25, 0, 40, 5, 0, 0, 0, + 0, 157, 74, 0, 141, 66, 0, 126, 59, 0, 110, 49, 0, 94, 40, 0, 78, 29, 0, 61, 15, 0, 40, 0, 0, 0, 0, + 0, 148, 214, 0, 133, 192, 0, 119, 171, 0, 103, 150, 0, 87, 129, 0, 72, 108, 0, 55, 86, 0, 32, 61, 0, 0, 25, + 0, 147, 193, 0, 132, 173, 0, 118, 155, 0, 103, 136, 0, 87, 116, 0, 72, 98, 0, 55, 78, 0, 32, 53, 0, 0, 17, + 0, 147, 176, 0, 132, 158, 0, 118, 142, 0, 102, 124, 0, 87, 106, 0, 72, 88, 0, 55, 69, 0, 33, 46, 0, 0, 9, + 0, 146, 159, 0, 131, 142, 0, 117, 127, 0, 102, 111, 0, 87, 95, 0, 71, 79, 0, 55, 61, 0, 33, 39, 0, 0, 2, + 0, 145, 140, 0, 130, 126, 0, 117, 112, 0, 101, 98, 0, 86, 83, 0, 71, 68, 0, 55, 52, 0, 33, 31, 0, 0, 0, + 0, 144, 124, 0, 130, 111, 0, 116, 99, 0, 101, 84, 0, 86, 72, 0, 71, 59, 0, 55, 43, 0, 33, 23, 0, 0, 0, + 0, 144, 106, 0, 129, 94, 0, 115, 83, 0, 101, 72, 0, 85, 60, 0, 71, 48, 0, 55, 34, 0, 33, 14, 0, 0, 0, + 3, 143, 86, 0, 129, 77, 0, 115, 68, 0, 100, 58, 0, 85, 48, 0, 70, 36, 0, 54, 22, 0, 33, 3, 0, 0, 0, + 18, 143, 72, 13, 128, 63, 0, 115, 57, 0, 100, 47, 0, 85, 37, 0, 70, 26, 0, 54, 13, 0, 33, 0, 0, 0, 0, + 0, 132, 200, 0, 118, 179, 0, 105, 161, 0, 91, 140, 0, 76, 121, 0, 62, 101, 0, 46, 81, 0, 24, 56, 0, 0, 19, + 0, 131, 182, 0, 118, 163, 0, 105, 146, 0, 91, 128, 0, 77, 110, 0, 62, 91, 0, 46, 72, 0, 25, 48, 0, 0, 11, + 0, 131, 165, 0, 117, 149, 0, 104, 133, 0, 91, 116, 0, 77, 99, 0, 62, 82, 0, 46, 64, 0, 25, 41, 0, 0, 4, + 0, 131, 149, 0, 116, 134, 0, 104, 119, 0, 91, 104, 0, 77, 89, 0, 62, 73, 0, 46, 56, 0, 25, 34, 0, 0, 0, + 10, 130, 133, 2, 116, 119, 0, 104, 106, 0, 90, 91, 0, 76, 78, 0, 62, 64, 0, 46, 48, 0, 26, 27, 0, 0, 0, + 23, 130, 118, 20, 116, 104, 13, 103, 93, 3, 89, 79, 0, 76, 67, 0, 62, 54, 0, 46, 39, 0, 26, 19, 0, 0, 0, + 33, 129, 101, 27, 115, 89, 19, 103, 79, 9, 89, 67, 0, 75, 56, 0, 61, 43, 0, 46, 29, 0, 26, 10, 0, 0, 0, + 41, 128, 83, 35, 115, 73, 27, 102, 64, 15, 89, 55, 0, 76, 45, 0, 62, 33, 0, 46, 18, 0, 26, 0, 0, 0, 0, + 43, 129, 69, 38, 115, 61, 30, 102, 54, 17, 89, 45, 2, 75, 34, 0, 61, 23, 0, 46, 9, 0, 26, 0, 0, 0, 0, + 1, 116, 188, 1, 104, 168, 0, 92, 151, 0, 79, 132, 0, 66, 113, 0, 52, 94, 0, 36, 75, 0, 14, 52, 0, 0, 14, + 17, 116, 171, 16, 104, 153, 14, 92, 137, 8, 79, 119, 0, 67, 102, 0, 53, 85, 0, 37, 67, 0, 16, 44, 0, 0, 4, + 31, 116, 155, 27, 104, 140, 21, 92, 125, 13, 79, 109, 3, 66, 93, 0, 53, 77, 0, 37, 59, 0, 16, 38, 0, 0, 0, + 37, 115, 141, 30, 103, 126, 26, 92, 112, 16, 79, 98, 5, 66, 83, 0, 53, 67, 0, 38, 51, 0, 17, 31, 0, 0, 0, + 41, 115, 126, 37, 103, 112, 31, 92, 100, 22, 79, 86, 10, 66, 72, 0, 53, 59, 0, 38, 44, 0, 17, 23, 0, 0, 0, + 48, 115, 111, 41, 102, 99, 34, 91, 88, 24, 78, 76, 14, 66, 63, 0, 53, 50, 0, 38, 36, 0, 18, 15, 0, 0, 0, + 51, 115, 95, 46, 102, 85, 37, 91, 74, 26, 78, 63, 16, 66, 52, 0, 53, 40, 0, 38, 26, 0, 18, 5, 0, 0, 0, + 55, 114, 80, 47, 102, 69, 40, 90, 60, 30, 78, 51, 19, 66, 41, 3, 53, 29, 0, 38, 15, 0, 17, 0, 0, 0, 0, + 56, 114, 66, 50, 102, 58, 40, 91, 50, 32, 78, 41, 18, 66, 32, 4, 53, 21, 0, 38, 5, 0, 17, 0, 0, 0, 0, + 39, 102, 178, 37, 90, 159, 30, 79, 142, 21, 68, 124, 14, 55, 106, 0, 42, 89, 0, 26, 70, 0, 4, 46, 0, 0, 8, + 48, 102, 161, 42, 90, 145, 35, 79, 128, 26, 68, 112, 19, 55, 96, 3, 43, 79, 0, 27, 62, 0, 6, 40, 0, 0, 0, + 50, 102, 147, 44, 90, 132, 37, 79, 118, 30, 68, 102, 20, 56, 87, 7, 43, 72, 0, 28, 55, 0, 6, 34, 0, 0, 0, + 53, 101, 133, 47, 90, 118, 41, 79, 106, 32, 68, 91, 21, 56, 78, 9, 43, 63, 0, 28, 47, 0, 6, 26, 0, 0, 0, + 57, 101, 119, 50, 89, 106, 42, 79, 94, 34, 67, 81, 24, 56, 68, 9, 44, 55, 0, 29, 40, 0, 6, 19, 0, 0, 0, + 60, 100, 105, 50, 90, 94, 45, 80, 83, 36, 68, 71, 24, 56, 59, 11, 44, 46, 0, 29, 32, 0, 7, 12, 0, 0, 0, + 63, 101, 91, 55, 90, 80, 46, 79, 70, 37, 68, 59, 26, 56, 49, 12, 44, 37, 1, 29, 23, 0, 7, 3, 0, 0, 0, + 64, 101, 75, 56, 89, 67, 48, 79, 57, 37, 68, 48, 27, 56, 37, 15, 44, 26, 0, 29, 12, 0, 7, 0, 0, 0, 0, + 66, 101, 64, 58, 89, 55, 49, 79, 47, 39, 68, 38, 27, 56, 29, 14, 44, 18, 1, 30, 2, 0, 7, 0, 0, 0, 0, + 57, 86, 165, 51, 75, 148, 45, 65, 133, 38, 54, 116, 28, 43, 100, 16, 29, 83, 0, 13, 64, 0, 0, 42, 0, 0, 3, + 60, 86, 151, 55, 75, 135, 47, 66, 121, 39, 55, 105, 30, 44, 90, 18, 31, 74, 3, 16, 57, 0, 1, 35, 0, 0, 0, + 62, 86, 139, 56, 75, 123, 49, 66, 110, 40, 55, 95, 30, 44, 81, 19, 31, 66, 4, 17, 51, 0, 1, 29, 0, 0, 0, + 65, 86, 125, 56, 76, 112, 49, 66, 99, 39, 55, 86, 31, 44, 72, 19, 32, 59, 5, 18, 44, 0, 1, 23, 0, 0, 0, + 67, 86, 113, 58, 75, 100, 51, 66, 88, 41, 56, 77, 31, 45, 64, 20, 32, 51, 6, 18, 35, 0, 1, 14, 0, 0, 0, + 69, 86, 99, 61, 76, 88, 52, 66, 78, 43, 56, 66, 32, 45, 55, 20, 33, 42, 7, 19, 27, 0, 1, 6, 0, 0, 0, + 69, 86, 86, 61, 76, 75, 53, 67, 66, 43, 56, 55, 33, 45, 45, 21, 34, 34, 8, 20, 20, 0, 2, 2, 0, 0, 0, + 71, 86, 72, 63, 75, 62, 54, 66, 55, 45, 56, 45, 33, 45, 35, 22, 34, 23, 7, 20, 8, 0, 2, 0, 0, 0, 0, + 71, 86, 62, 64, 75, 53, 55, 66, 46, 45, 56, 36, 33, 46, 27, 22, 34, 15, 8, 20, 0, 0, 2, 0, 0, 0, 0, + 69, 67, 156, 61, 58, 140, 53, 50, 125, 45, 39, 108, 35, 28, 93, 25, 12, 77, 12, 0, 59, 0, 0, 37, 0, 0, 0, + 71, 68, 142, 63, 59, 126, 56, 50, 114, 47, 40, 98, 37, 28, 84, 26, 15, 68, 12, 0, 53, 0, 0, 30, 0, 0, 0, + 72, 68, 130, 63, 59, 116, 56, 50, 104, 47, 40, 90, 38, 30, 75, 27, 16, 61, 13, 0, 46, 0, 0, 24, 0, 0, 0, + 73, 69, 118, 65, 59, 105, 57, 51, 92, 47, 41, 80, 37, 30, 67, 26, 18, 53, 14, 1, 39, 0, 0, 18, 0, 0, 0, + 74, 69, 106, 65, 60, 93, 57, 51, 82, 48, 41, 70, 38, 31, 59, 26, 19, 46, 13, 2, 32, 0, 0, 10, 0, 0, 0, + 76, 69, 95, 66, 61, 84, 58, 52, 73, 48, 42, 61, 37, 32, 50, 26, 20, 38, 14, 4, 24, 0, 0, 4, 0, 0, 0, + 76, 69, 81, 68, 60, 72, 58, 52, 62, 48, 42, 51, 38, 32, 41, 27, 21, 30, 14, 4, 16, 0, 0, 1, 0, 0, 0, + 76, 69, 68, 68, 61, 60, 60, 52, 51, 49, 43, 41, 38, 33, 32, 27, 21, 20, 14, 5, 5, 0, 0, 0, 0, 0, 0, + 78, 70, 59, 69, 61, 50, 60, 52, 42, 49, 43, 34, 39, 33, 24, 27, 22, 13, 14, 7, 1, 0, 0, 0, 0, 0, 0, + 75, 46, 146, 68, 38, 131, 60, 30, 117, 50, 19, 102, 41, 4, 87, 29, 0, 72, 13, 0, 55, 0, 0, 33, 0, 0, 0, + 78, 47, 132, 70, 39, 119, 61, 30, 105, 53, 20, 92, 42, 5, 78, 30, 0, 64, 13, 0, 49, 0, 0, 27, 0, 0, 0, + 79, 48, 122, 70, 40, 108, 62, 32, 96, 52, 22, 84, 42, 9, 71, 30, 0, 58, 14, 0, 42, 0, 0, 20, 0, 0, 0, + 79, 50, 111, 70, 42, 99, 62, 33, 88, 52, 23, 74, 41, 11, 63, 29, 0, 50, 14, 0, 36, 0, 0, 14, 0, 0, 0, + 80, 50, 99, 70, 42, 89, 61, 34, 78, 52, 25, 67, 41, 14, 55, 30, 0, 42, 15, 0, 28, 0, 0, 6, 0, 0, 0, + 81, 51, 89, 71, 43, 78, 62, 35, 69, 52, 25, 58, 42, 15, 47, 30, 3, 36, 15, 0, 22, 0, 0, 3, 0, 0, 0, + 81, 51, 77, 71, 44, 68, 63, 36, 59, 53, 26, 49, 41, 16, 38, 31, 4, 27, 16, 0, 12, 0, 0, 0, 0, 0, 0, + 81, 52, 65, 72, 43, 56, 63, 36, 48, 53, 27, 39, 41, 17, 29, 30, 4, 18, 14, 0, 3, 0, 0, 0, 0, 0, 0, + 81, 52, 55, 73, 44, 47, 64, 36, 39, 53, 28, 32, 42, 18, 21, 31, 6, 9, 14, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 174, 239, 0, 156, 214, 0, 139, 192, 0, 121, 168, 0, 105, 145, 0, 87, 123, 0, 68, 98, 0, 46, 70, 0, 3, 35, + 0, 172, 217, 0, 155, 194, 0, 139, 173, 0, 121, 152, 0, 104, 130, 0, 87, 110, 0, 69, 88, 0, 46, 63, 0, 4, 28, + 0, 171, 197, 0, 153, 175, 0, 138, 158, 0, 121, 139, 0, 103, 118, 0, 86, 100, 0, 68, 79, 0, 46, 55, 0, 4, 22, + 0, 170, 177, 0, 152, 158, 0, 136, 141, 0, 119, 124, 0, 103, 106, 0, 86, 88, 0, 68, 70, 0, 45, 47, 0, 3, 14, + 0, 169, 157, 0, 152, 141, 0, 136, 126, 0, 119, 109, 0, 102, 94, 0, 86, 78, 0, 68, 60, 0, 46, 39, 0, 3, 5, + 0, 167, 138, 0, 150, 124, 0, 135, 111, 0, 118, 97, 0, 102, 82, 0, 85, 68, 0, 68, 52, 0, 46, 31, 0, 3, 0, + 0, 167, 118, 0, 150, 104, 0, 135, 94, 0, 118, 81, 0, 101, 69, 0, 84, 56, 0, 67, 41, 0, 45, 21, 0, 3, 0, + 0, 166, 97, 0, 149, 87, 0, 134, 77, 0, 117, 67, 0, 101, 56, 0, 85, 44, 0, 67, 30, 0, 45, 10, 0, 3, 0, + 0, 165, 79, 0, 149, 73, 0, 133, 64, 0, 117, 56, 0, 101, 46, 0, 85, 34, 0, 68, 21, 0, 46, 1, 0, 3, 0, + 0, 158, 225, 0, 141, 201, 0, 126, 180, 0, 109, 158, 0, 94, 136, 0, 78, 114, 0, 60, 91, 0, 38, 66, 0, 0, 30, + 0, 156, 203, 0, 140, 183, 0, 125, 164, 0, 109, 143, 0, 94, 124, 0, 78, 104, 0, 61, 83, 0, 38, 57, 0, 0, 23, + 0, 156, 186, 0, 140, 166, 0, 125, 150, 0, 109, 130, 0, 93, 111, 0, 77, 93, 0, 60, 74, 0, 38, 50, 0, 0, 17, + 0, 155, 167, 0, 138, 149, 0, 124, 134, 0, 109, 117, 0, 93, 100, 0, 76, 83, 0, 60, 65, 0, 38, 43, 0, 0, 9, + 0, 153, 147, 0, 138, 134, 0, 124, 120, 0, 107, 103, 0, 92, 88, 0, 77, 73, 0, 60, 56, 0, 38, 35, 0, 0, 0, + 0, 153, 131, 0, 137, 118, 0, 122, 105, 0, 107, 90, 0, 91, 76, 0, 76, 63, 0, 60, 47, 0, 39, 28, 0, 0, 0, + 0, 153, 111, 0, 136, 100, 0, 123, 90, 0, 107, 77, 0, 92, 65, 0, 76, 52, 0, 60, 37, 0, 38, 18, 0, 0, 0, + 0, 152, 93, 0, 136, 82, 0, 122, 74, 0, 106, 63, 0, 91, 52, 0, 76, 40, 0, 59, 26, 0, 38, 6, 0, 0, 0, + 0, 151, 78, 0, 136, 69, 0, 121, 61, 0, 106, 52, 0, 91, 43, 0, 76, 32, 0, 59, 17, 0, 38, 0, 0, 0, 0, + 0, 143, 213, 0, 128, 191, 0, 115, 171, 0, 100, 149, 0, 84, 128, 0, 69, 108, 0, 52, 86, 0, 30, 61, 0, 0, 25, + 0, 142, 193, 0, 127, 173, 0, 114, 154, 0, 99, 134, 0, 84, 116, 0, 69, 98, 0, 52, 77, 0, 31, 53, 0, 0, 18, + 0, 141, 176, 0, 127, 158, 0, 114, 141, 0, 98, 122, 0, 84, 105, 0, 69, 88, 0, 53, 69, 0, 31, 46, 0, 0, 9, + 0, 141, 159, 0, 126, 142, 0, 113, 127, 0, 98, 110, 0, 83, 95, 0, 69, 78, 0, 53, 60, 0, 32, 39, 0, 0, 2, + 0, 140, 140, 0, 126, 126, 0, 112, 112, 0, 98, 98, 0, 83, 83, 0, 68, 69, 0, 52, 52, 0, 31, 31, 0, 0, 0, + 0, 140, 124, 0, 125, 112, 0, 112, 100, 0, 97, 86, 0, 83, 72, 0, 68, 59, 0, 52, 44, 0, 31, 23, 0, 0, 0, + 0, 139, 106, 0, 125, 96, 0, 111, 85, 0, 97, 72, 0, 83, 62, 0, 68, 49, 0, 52, 35, 0, 31, 15, 0, 0, 0, + 0, 138, 88, 0, 124, 79, 0, 111, 70, 0, 96, 59, 0, 82, 48, 0, 68, 38, 0, 52, 24, 0, 31, 4, 0, 0, 0, + 0, 139, 76, 0, 124, 66, 0, 111, 58, 0, 96, 50, 0, 82, 40, 0, 68, 29, 0, 52, 15, 0, 31, 0, 0, 0, 0, + 0, 129, 200, 0, 114, 179, 0, 102, 160, 0, 87, 139, 0, 74, 120, 0, 60, 101, 0, 44, 81, 0, 22, 56, 0, 0, 19, + 0, 127, 181, 0, 114, 163, 0, 102, 146, 0, 88, 127, 0, 74, 109, 0, 60, 91, 0, 44, 72, 0, 23, 48, 0, 0, 11, + 0, 127, 166, 0, 113, 148, 0, 101, 133, 0, 87, 115, 0, 74, 99, 0, 60, 82, 0, 44, 64, 0, 23, 42, 0, 0, 4, + 0, 127, 150, 0, 113, 134, 0, 101, 119, 0, 87, 104, 0, 74, 89, 0, 60, 73, 0, 44, 56, 0, 23, 35, 0, 0, 0, + 0, 125, 134, 0, 112, 118, 0, 100, 106, 0, 87, 92, 0, 73, 78, 0, 60, 64, 0, 44, 48, 0, 23, 27, 0, 0, 0, + 0, 125, 118, 0, 112, 105, 0, 100, 94, 0, 86, 80, 0, 73, 68, 0, 60, 54, 0, 44, 39, 0, 23, 20, 0, 0, 0, + 0, 125, 101, 0, 111, 90, 0, 99, 80, 0, 86, 69, 0, 73, 58, 0, 59, 45, 0, 44, 30, 0, 23, 11, 0, 0, 0, + 0, 124, 85, 0, 111, 75, 0, 99, 66, 0, 86, 56, 0, 73, 45, 0, 59, 34, 0, 44, 20, 0, 23, 1, 0, 0, 0, + 0, 125, 72, 0, 111, 62, 0, 99, 56, 0, 86, 46, 0, 73, 36, 0, 60, 26, 0, 44, 12, 0, 23, 0, 0, 0, 0, + 0, 114, 188, 0, 101, 167, 0, 89, 150, 0, 77, 131, 0, 64, 113, 0, 50, 95, 0, 34, 75, 0, 12, 52, 0, 0, 14, + 0, 113, 170, 0, 101, 153, 0, 89, 137, 0, 77, 120, 0, 64, 102, 0, 50, 85, 0, 35, 67, 0, 12, 44, 0, 0, 4, + 0, 113, 156, 0, 100, 139, 0, 89, 125, 0, 77, 109, 0, 64, 92, 0, 51, 77, 0, 35, 60, 0, 12, 38, 0, 0, 0, + 0, 112, 141, 0, 100, 126, 0, 89, 113, 0, 77, 98, 0, 64, 83, 0, 51, 68, 0, 35, 51, 0, 12, 30, 0, 0, 0, + 0, 112, 127, 0, 100, 112, 0, 89, 100, 0, 76, 87, 0, 64, 74, 0, 51, 59, 0, 35, 44, 0, 13, 24, 0, 0, 0, + 0, 112, 111, 0, 100, 100, 0, 88, 88, 0, 76, 76, 0, 64, 64, 0, 51, 52, 0, 36, 37, 0, 13, 17, 0, 0, 0, + 0, 111, 96, 0, 99, 85, 0, 88, 76, 0, 76, 64, 0, 64, 53, 0, 51, 41, 0, 36, 27, 0, 13, 6, 0, 0, 0, + 0, 111, 81, 0, 99, 71, 0, 88, 62, 0, 76, 52, 0, 64, 43, 0, 51, 31, 0, 36, 17, 0, 13, 0, 0, 0, 0, + 0, 111, 69, 0, 99, 60, 0, 88, 52, 0, 75, 43, 0, 63, 34, 0, 51, 21, 0, 36, 7, 0, 13, 0, 0, 0, 0, + 0, 99, 177, 0, 88, 158, 0, 77, 141, 0, 66, 123, 0, 53, 106, 0, 40, 89, 0, 25, 71, 0, 5, 47, 0, 0, 8, + 0, 99, 160, 0, 88, 144, 0, 77, 129, 0, 66, 112, 0, 54, 97, 0, 41, 80, 0, 26, 62, 0, 5, 40, 0, 0, 0, + 0, 99, 147, 0, 87, 132, 0, 78, 117, 0, 66, 102, 0, 54, 87, 0, 42, 72, 0, 26, 55, 0, 5, 34, 0, 0, 0, + 0, 99, 134, 0, 88, 119, 0, 77, 107, 0, 66, 92, 0, 54, 78, 0, 42, 64, 0, 27, 48, 0, 5, 27, 0, 0, 0, + 0, 99, 120, 0, 87, 107, 0, 78, 94, 0, 66, 81, 0, 54, 68, 0, 42, 55, 0, 27, 40, 0, 6, 20, 0, 0, 0, + 0, 98, 105, 0, 87, 94, 0, 77, 84, 0, 65, 71, 0, 55, 59, 0, 42, 47, 0, 28, 33, 0, 6, 12, 0, 0, 0, + 0, 98, 93, 0, 87, 81, 0, 77, 72, 0, 66, 61, 0, 54, 49, 0, 42, 37, 0, 28, 24, 0, 6, 4, 0, 0, 0, + 0, 98, 77, 0, 87, 68, 0, 77, 59, 0, 65, 49, 0, 54, 39, 0, 42, 27, 0, 29, 14, 0, 6, 0, 0, 0, 0, + 1, 98, 65, 7, 87, 56, 0, 77, 49, 0, 66, 41, 0, 54, 30, 0, 42, 19, 0, 29, 3, 0, 6, 0, 0, 0, 0, + 0, 84, 166, 0, 74, 149, 0, 64, 134, 0, 53, 117, 0, 41, 100, 0, 28, 83, 0, 11, 64, 0, 0, 42, 0, 0, 3, + 0, 84, 151, 0, 74, 135, 0, 64, 121, 0, 53, 105, 0, 42, 90, 0, 30, 75, 0, 14, 58, 0, 0, 36, 0, 0, 0, + 0, 84, 138, 0, 74, 124, 1, 64, 110, 0, 54, 95, 0, 43, 81, 0, 30, 67, 0, 15, 51, 0, 1, 29, 0, 0, 0, + 14, 84, 126, 12, 74, 112, 2, 65, 99, 0, 54, 85, 0, 44, 73, 0, 31, 59, 0, 16, 44, 0, 1, 23, 0, 0, 0, + 16, 84, 113, 13, 74, 100, 6, 65, 89, 0, 54, 77, 0, 44, 65, 0, 31, 51, 0, 17, 36, 0, 1, 16, 0, 0, 0, + 24, 84, 100, 18, 74, 88, 13, 65, 78, 2, 55, 68, 0, 44, 55, 0, 32, 43, 0, 18, 28, 0, 1, 6, 0, 0, 0, + 26, 84, 87, 24, 74, 76, 17, 65, 67, 7, 54, 57, 0, 44, 46, 0, 32, 35, 0, 19, 21, 0, 2, 3, 0, 0, 0, + 30, 84, 74, 28, 74, 64, 20, 65, 55, 12, 55, 46, 0, 44, 35, 0, 32, 24, 0, 18, 9, 0, 1, 0, 0, 0, 0, + 32, 84, 63, 28, 74, 54, 21, 65, 47, 13, 54, 38, 0, 44, 28, 0, 32, 16, 0, 18, 1, 0, 1, 0, 0, 0, 0, + 30, 67, 155, 20, 58, 139, 20, 49, 126, 12, 39, 110, 0, 27, 94, 0, 13, 77, 0, 0, 60, 0, 0, 37, 0, 0, 0, + 35, 67, 142, 30, 58, 126, 23, 50, 114, 16, 40, 99, 7, 29, 85, 0, 15, 69, 0, 0, 52, 0, 0, 30, 0, 0, 0, + 35, 68, 131, 30, 59, 116, 27, 50, 104, 18, 40, 90, 9, 29, 76, 0, 17, 62, 0, 2, 46, 0, 0, 24, 0, 0, 0, + 37, 69, 119, 33, 59, 106, 27, 51, 94, 21, 41, 80, 9, 30, 67, 0, 18, 54, 0, 3, 39, 0, 0, 18, 0, 0, 0, + 40, 69, 107, 36, 59, 94, 28, 51, 84, 18, 41, 72, 10, 31, 60, 0, 19, 47, 0, 4, 32, 0, 0, 10, 0, 0, 0, + 42, 69, 95, 36, 59, 84, 29, 51, 74, 19, 41, 63, 10, 31, 52, 0, 20, 39, 0, 4, 25, 0, 0, 4, 0, 0, 0, + 43, 69, 83, 38, 60, 73, 32, 51, 62, 23, 42, 53, 11, 31, 42, 0, 20, 31, 0, 5, 17, 0, 0, 1, 0, 0, 0, + 45, 69, 70, 39, 60, 60, 33, 51, 52, 24, 42, 43, 13, 32, 33, 0, 21, 21, 0, 5, 6, 0, 0, 0, 0, 0, 0, + 47, 69, 59, 41, 60, 51, 34, 51, 43, 24, 42, 35, 12, 33, 26, 1, 22, 14, 0, 5, 1, 0, 0, 0, 0, 0, 0, + 46, 48, 146, 42, 40, 131, 36, 32, 118, 27, 22, 103, 17, 6, 88, 5, 0, 73, 0, 0, 55, 0, 0, 33, 0, 0, 0, + 48, 48, 133, 44, 40, 119, 37, 32, 107, 28, 22, 93, 20, 8, 79, 7, 0, 65, 0, 0, 49, 0, 0, 27, 0, 0, 0, + 48, 50, 123, 44, 41, 109, 37, 33, 97, 30, 23, 83, 21, 11, 71, 8, 0, 58, 0, 0, 42, 0, 0, 21, 0, 0, 0, + 49, 51, 111, 45, 42, 99, 38, 34, 87, 29, 25, 75, 20, 13, 63, 8, 0, 51, 0, 0, 36, 0, 0, 14, 0, 0, 0, + 52, 52, 100, 44, 43, 89, 38, 35, 79, 29, 26, 68, 19, 15, 56, 10, 1, 43, 0, 0, 28, 0, 0, 6, 0, 0, 0, + 52, 52, 90, 47, 44, 79, 39, 36, 70, 30, 27, 59, 20, 16, 47, 9, 2, 36, 0, 0, 22, 0, 0, 2, 0, 0, 0, + 52, 53, 78, 46, 44, 68, 39, 37, 60, 32, 27, 49, 22, 17, 39, 10, 3, 28, 0, 0, 12, 0, 0, 0, 0, 0, 0, + 53, 53, 66, 47, 44, 57, 40, 36, 48, 32, 27, 39, 22, 18, 30, 9, 4, 18, 0, 0, 3, 0, 0, 0, 0, 0, 0, + 54, 53, 57, 48, 45, 49, 41, 37, 41, 33, 28, 32, 22, 19, 23, 11, 6, 10, 1, 0, 0, 0, 0, 0, 0, 0, 0, +}; + void GfxDeviceCMYKColorSpace::getRGB(GfxColor *color, GfxRGB *rgb, GfxRenderingIntent ri) { - double c, m, y, k, c1, m1, y1, k1, r, g, b, x; - - c = colToDbl(color->c[0]); - m = colToDbl(color->c[1]); - y = colToDbl(color->c[2]); - k = colToDbl(color->c[3]); - c1 = 1 - c; - m1 = 1 - m; - y1 = 1 - y; - k1 = 1 - k; + // double c, m, y, k, c1, m1, y1, k1, r, g, b, x; + double r, g, b; + + Guchar c = (Guchar)(colToDbl(color->c[0]) * 255.0 + 0.5); + Guchar m = (Guchar)(colToDbl(color->c[1]) * 255.0 + 0.5); + Guchar y = (Guchar)(colToDbl(color->c[2]) * 255.0 + 0.5); + Guchar k = (Guchar)(colToDbl(color->c[3]) * 255.0 + 0.5); + + int fix_c = c << 8; + int fix_m = m << 8; + int fix_y = y << 8; + int fix_k = k << 8; + int c_index = (fix_c + 4096) >> 13; + int m_index = (fix_m + 4096) >> 13; + int y_index = (fix_y + 4096) >> 13; + int k_index = (fix_k + 4096) >> 13; + int pos = (c_index * 9 * 9 * 9 + m_index * 9 * 9 + y_index * 9 + k_index) * 3; + int fix_r = g_CMYKSamples[pos] << 8; + int fix_g = g_CMYKSamples[pos + 1] << 8; + int fix_b = g_CMYKSamples[pos + 2] << 8; + int c1_index = fix_c >> 13; + if (c1_index == c_index) { + c1_index = c1_index == 8 ? c1_index - 1 : c1_index + 1; + } + int m1_index = fix_m >> 13; + if (m1_index == m_index) { + m1_index = m1_index == 8 ? m1_index - 1 : m1_index + 1; + } + int y1_index = fix_y >> 13; + if (y1_index == y_index) { + y1_index = y1_index == 8 ? y1_index - 1 : y1_index + 1; + } + int k1_index = fix_k >> 13; + if (k1_index == k_index) { + k1_index = k1_index == 8 ? k1_index - 1 : k1_index + 1; + } + int c1_pos = pos + (c1_index - c_index) * 9 * 9 * 9 * 3; + int m1_pos = pos + (m1_index - m_index) * 9 * 9 * 3; + int y1_pos = pos + (y1_index - y_index) * 9 * 3; + int k1_pos = pos + (k1_index - k_index) * 3; + int c_r_delta = g_CMYKSamples[pos] - g_CMYKSamples[c1_pos]; + int c_g_delta = g_CMYKSamples[pos + 1] - g_CMYKSamples[c1_pos + 1]; + int c_b_delta = g_CMYKSamples[pos + 2] - g_CMYKSamples[c1_pos + 2]; + int m_r_delta = g_CMYKSamples[pos] - g_CMYKSamples[m1_pos]; + int m_g_delta = g_CMYKSamples[pos + 1] - g_CMYKSamples[m1_pos + 1]; + int m_b_delta = g_CMYKSamples[pos + 2] - g_CMYKSamples[m1_pos + 2]; + int y_r_delta = g_CMYKSamples[pos] - g_CMYKSamples[y1_pos]; + int y_g_delta = g_CMYKSamples[pos + 1] - g_CMYKSamples[y1_pos + 1]; + int y_b_delta = g_CMYKSamples[pos + 2] - g_CMYKSamples[y1_pos + 2]; + int k_r_delta = g_CMYKSamples[pos] - g_CMYKSamples[k1_pos]; + int k_g_delta = g_CMYKSamples[pos + 1] - g_CMYKSamples[k1_pos + 1]; + int k_b_delta = g_CMYKSamples[pos + 2] - g_CMYKSamples[k1_pos + 2]; + int c_rate = (fix_c - (c_index << 13)) * (c_index - c1_index); + fix_r += c_r_delta * c_rate / 32; + fix_g += c_g_delta * c_rate / 32; + fix_b += c_b_delta * c_rate / 32; + int m_rate = (fix_m - (m_index << 13)) * (m_index - m1_index); + fix_r += m_r_delta * m_rate / 32; + fix_g += m_g_delta * m_rate / 32; + fix_b += m_b_delta * m_rate / 32; + int y_rate = (fix_y - (y_index << 13)) * (y_index - y1_index); + fix_r += y_r_delta * y_rate / 32; + fix_g += y_g_delta * y_rate / 32; + fix_b += y_b_delta * y_rate / 32; + int k_rate = (fix_k - (k_index << 13)) * (k_index - k1_index); + fix_r += k_r_delta * k_rate / 32; + fix_g += k_g_delta * k_rate / 32; + fix_b += k_b_delta * k_rate / 32; + if (fix_r < 0) { + fix_r = 0; + } + if (fix_g < 0) { + fix_g = 0; + } + if (fix_b < 0) { + fix_b = 0; + } + r = fix_r >> 8; + g = fix_g >> 8; + b = fix_b >> 8; + + r = 1.0 * r / 255.0; + g = 1.0 * g / 255.0; + b = 1.0 * b / 255.0; + /* + c1 = 1.0 - c; + m1 = 1.0 - m; + y1 = 1.0 - y; + k1 = 1.0 - k; // this is a matrix multiplication, unrolled for performance // C M Y K x = c1 * m1 * y1 * k1; // 0 0 0 0 @@ -626,6 +1457,7 @@ void GfxDeviceCMYKColorSpace::getRGB(GfxColor *color, GfxRGB *rgb, r += 0.2118 * x; g += 0.2119 * x; b += 0.2235 * x; + */ rgb->r = clip01(dblToCol(r)); rgb->g = clip01(dblToCol(g)); rgb->b = clip01(dblToCol(b)); @@ -3878,6 +4710,8 @@ int GfxImageColorMap::getFillType() case csDeviceRGB: case csCalRGB: return nComps > 2 ? 2 : 0; + case csDeviceRGBA: + return nComps > 3 ? 3 : 0; default: return 0; } @@ -4371,7 +5205,12 @@ void GfxState::getUserClipBBox(double *xMin, double *yMin, double xMin1, yMin1, xMax1, yMax1, det, tx, ty; // invert the CTM - det = 1 / (ctm[0] * ctm[3] - ctm[1] * ctm[2]); + det = ctm[0] * ctm[3] - ctm[1] * ctm[2]; + if (fabs(det) <= 1e-10) { + *xMin = *yMin = *xMax = *yMax = 0; + return; + } + det = 1 / det; ictm[0] = ctm[3] * det; ictm[1] = -ctm[1] * det; ictm[2] = -ctm[2] * det; diff --git a/PdfFile/lib/xpdf/GfxState.h b/PdfFile/lib/xpdf/GfxState.h index 5ddbd1750cd..cedadb486f2 100644 --- a/PdfFile/lib/xpdf/GfxState.h +++ b/PdfFile/lib/xpdf/GfxState.h @@ -164,7 +164,8 @@ enum GfxColorSpaceMode { csIndexed, csSeparation, csDeviceN, - csPattern + csPattern, + csDeviceRGBA // used for transparent JPX images, they contain RGBA data }; class GfxColorSpace { @@ -310,6 +311,23 @@ class GfxDeviceRGBColorSpace: public GfxColorSpace { private: }; +//------------------------------------------------------------------------ +// GfxDeviceRGBAColorSpace +//------------------------------------------------------------------------ + +class GfxDeviceRGBAColorSpace : public GfxDeviceRGBColorSpace +{ +public: + GfxDeviceRGBAColorSpace(); + virtual ~GfxDeviceRGBAColorSpace(); + virtual GfxColorSpace* copy(); + virtual GfxColorSpaceMode getMode() { return csDeviceRGBA; } + + virtual int getNComps() { return 4; } + +private: +}; + //------------------------------------------------------------------------ // GfxCalRGBColorSpace //------------------------------------------------------------------------ diff --git a/PdfFile/lib/xpdf/OutputDev.h b/PdfFile/lib/xpdf/OutputDev.h index 6fe7eeedb4e..540c2900715 100644 --- a/PdfFile/lib/xpdf/OutputDev.h +++ b/PdfFile/lib/xpdf/OutputDev.h @@ -186,6 +186,11 @@ class OutputDev { virtual void beginActualText(GfxState *state, Unicode *u, int uLen) {} virtual void endActualText(GfxState *state) {} + //----- additional + virtual GBool beginMarkedContent(GfxState *state, GString *s) { return gFalse; } + virtual GBool beginMCOShapes(GfxState *state, GString *s, Object *ref) { return gFalse; } + virtual void endMarkedContent(GfxState *state) {} + //----- image drawing virtual void drawImageMask(GfxState *state, Object *ref, Stream *str, int width, int height, GBool invert, diff --git a/PdfFile/lib/xpdf/Page.cc b/PdfFile/lib/xpdf/Page.cc index 970c13ed1ff..05b03ce7395 100644 --- a/PdfFile/lib/xpdf/Page.cc +++ b/PdfFile/lib/xpdf/Page.cc @@ -380,7 +380,7 @@ void Page::displaySlice(OutputDev *out, double hDPI, double vDPI, obj.free(); // draw (non-form) annotations - if (globalParams->getDrawAnnotations()) { + if (true) { annotList = new Annots(doc, getAnnots(&obj)); obj.free(); annotList->generateAnnotAppearances(); @@ -392,12 +392,10 @@ void Page::displaySlice(OutputDev *out, double hDPI, double vDPI, if (abortCheckCbk && (*abortCheckCbk)(abortCheckCbkData)) { break; } -#ifdef BUILDING_WASM_MODULE sType = annotList->getAnnot(i)->getType(); - if (sType->cmp("Link") == 0 || sType->cmp("Stamp") == 0 || sType->cmp("FileAttachment") == 0 || + if (globalParams->getDrawAnnotations() || sType->cmp("Link") == 0 || sType->cmp("FileAttachment") == 0 || sType->cmp("Sound") == 0 || sType->cmp("Movie") == 0 || sType->cmp("Screen") == 0 || sType->cmp("PrinterMark") == 0 || sType->cmp("TrapNet") == 0 || sType->cmp("Watermark") == 0 || sType->cmp("3D") == 0 || sType->cmp("Redact") == 0) -#endif annotList->getAnnot(i)->draw(gfx, printing); } } diff --git a/PdfFile/lib/xpdf/Stream.cc b/PdfFile/lib/xpdf/Stream.cc index e531e7a822d..8119de4f759 100644 --- a/PdfFile/lib/xpdf/Stream.cc +++ b/PdfFile/lib/xpdf/Stream.cc @@ -989,7 +989,9 @@ void MemStream::setPos(GFileOffset pos, int dir) { } else { i = (Guint)(start + length - pos); } - if (i < start) { + if (dir < 0 && start + length < pos) { + i = 0; + } else if (i < start) { i = start; } else if (i > start + length) { i = start + length; @@ -1438,7 +1440,7 @@ GBool LZWStream::processNextCode() { totalOut += seqLength; // check for a 'decompression bomb' - if (totalOut > 50000000 && totalIn < totalOut / 250) { + if (totalOut > 500000000 && totalIn < totalOut / 250) { error(errSyntaxError, getPos(), "Decompression bomb in flate stream"); eof = gTrue; return gFalse; @@ -5250,7 +5252,7 @@ void FlateStream::readSome() { totalOut += remain; // check for a 'decompression bomb' - if (totalOut > 50000000 && totalIn < totalOut / 250) { + if (totalOut > 500000000 && totalIn < totalOut / 250) { error(errSyntaxError, getPos(), "Decompression bomb in flate stream"); endOfBlock = eof = gTrue; remain = 0; diff --git a/PdfFile/lib/xpdf/XRef.cc b/PdfFile/lib/xpdf/XRef.cc index 0c364638b39..1b2721be139 100644 --- a/PdfFile/lib/xpdf/XRef.cc +++ b/PdfFile/lib/xpdf/XRef.cc @@ -414,20 +414,36 @@ XRef::~XRef() { GFileOffset XRef::getStartXref() { char buf[xrefSearchSize+1]; char *p; - int n, i; - - // read last xrefSearchSize bytes - str->setPos(xrefSearchSize, -1); - n = str->getBlock(buf, xrefSearchSize); - buf[n] = '\0'; + int n, i, nTry; + bool bFind; + nTry = 1; + bFind = false; + + bool isBreak = false; + do + { + str->setPos(xrefSearchSize * nTry, -1); + isBreak = str->getPos() == 0; + n = str->getBlock(buf, xrefSearchSize); + buf[n] = '\0'; + + // find startxref + for (i = n - 9; i >= 0; --i) { + if (!strncmp(&buf[i], "startxref", 9)) { + bFind = true; + break; + } + } - // find startxref - for (i = n - 9; i >= 0; --i) { - if (!strncmp(&buf[i], "startxref", 9)) { + if (bFind) { break; } - } - if (i < 0) { + nTry++; + } while (!isBreak); + + // read last xrefSearchSize bytes + + if (!bFind) { return 0; } for (p = &buf[i+9]; isspace(*p & 0xff); ++p) ; @@ -930,6 +946,7 @@ GBool XRef::constructXRef() { } // read each stream object, check for xref or object stream + GBool bRoot = gFalse; for (int i = 0; i < streamObjNumsLen; ++i) { Object obj; fetch(streamObjNums[i], entries[streamObjNums[i]].gen, &obj); @@ -937,8 +954,8 @@ GBool XRef::constructXRef() { Dict *dict = obj.streamGetDict(); Object type; dict->lookup("Type", &type); - if (type.isName("XRef")) { - saveTrailerDict(dict, gTrue); + if (type.isName("XRef") && !bRoot) { + bRoot = saveTrailerDict(dict, gTrue); } else if (type.isName("ObjStm")) { constructObjectStreamEntries(&obj, streamObjNums[i]); } @@ -975,7 +992,8 @@ void XRef::constructTrailerDict(GFileOffset pos) { // If [dict] "looks like" a trailer dict (i.e., has a Root entry), // save it as the trailer dict. -void XRef::saveTrailerDict(Dict *dict, GBool isXRefStream) { +GBool XRef::saveTrailerDict(Dict *dict, GBool isXRefStream) { + GBool bRes = gFalse; Object obj; dict->lookupNF("Root", &obj); if (obj.isRef()) { @@ -989,9 +1007,11 @@ void XRef::saveTrailerDict(Dict *dict, GBool isXRefStream) { trailerDict.free(); } trailerDict.initDict(dict); + bRes = gTrue; } } obj.free(); + return bRes; } // Look for an object header ("nnn ggg obj") at [p]. The first diff --git a/PdfFile/lib/xpdf/XRef.h b/PdfFile/lib/xpdf/XRef.h index 00a8644f3a9..3ea5ba7a393 100644 --- a/PdfFile/lib/xpdf/XRef.h +++ b/PdfFile/lib/xpdf/XRef.h @@ -77,6 +77,8 @@ class XRef { // Is the file encrypted? GBool isEncrypted() { return encrypted; } + void offEncrypted() { encrypted = gFalse; } + void onEncrypted() { encrypted = gTrue; } GBool getEncryption(int *permFlagsA, GBool *ownerPasswordOkA, int *keyLengthA, int *encVersionA, CryptAlgorithm *encAlgorithmA); @@ -172,7 +174,7 @@ class XRef { GBool readXRefStreamSection(Stream *xrefStr, int *w, int first, int n); GBool constructXRef(); void constructTrailerDict(GFileOffset pos); - void saveTrailerDict(Dict *dict, GBool isXRefStream); + GBool saveTrailerDict(Dict *dict, GBool isXRefStream); char *constructObjectEntry(char *p, GFileOffset pos, int *objNum); void constructObjectStreamEntries(Object *objStr, int objStrObjNum); GBool constructXRefEntry(int num, int gen, GFileOffset pos, diff --git a/PdfFile/test/test.cpp b/PdfFile/test/test.cpp index 0a35e6e44e4..49e36f3bc8d 100644 --- a/PdfFile/test/test.cpp +++ b/PdfFile/test/test.cpp @@ -29,256 +29,655 @@ * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode * */ + +#include "gtest/gtest.h" #include "../../DesktopEditor/common/File.h" #include "../../DesktopEditor/common/Directory.h" #include "../../DesktopEditor/fontengine/ApplicationFontsWorker.h" #include "../../DesktopEditor/xmlsec/src/include/CertificateCommon.h" #include "../../DesktopEditor/graphics/MetafileToGraphicsRenderer.h" -#include "../../DesktopEditor/graphics/commands/AnnotField.h" +#include "../../DesktopEditor/raster/BgraFrame.h" +#include "../../DjVuFile/DjVu.h" #include "../PdfFile.h" -#include "../OnlineOfficeBinToPdf.h" -void TEST(IRenderer* pRenderer) +class CPdfFileTest : public testing::Test { - // ТЕСТОВЫЕ КОММАНДЫ - pRenderer->PathCommandStart(); - pRenderer->PathCommandMoveTo(10, 10); - pRenderer->PathCommandLineTo(20, 20); - pRenderer->PathCommandCurveTo(70, 30, 30, 20, 50, 50); - pRenderer->PathCommandClose(); - pRenderer->put_BrushColor1(0xFF0000); - pRenderer->put_PenColor(0x0000FF); - pRenderer->put_PenSize(1); - pRenderer->DrawPath(c_nStroke | c_nWindingFillMode); - pRenderer->PathCommandEnd(); -} +protected: + static CApplicationFontsWorker* oWorker; + static NSFonts::IApplicationFonts* pApplicationFonts; + static std::wstring wsTempDir; + static std::wstring wsSrcFile; + static std::wstring wsDstFile; + + static std::wstring strDirIn; + static std::wstring strDirOut; + static std::wstring strDiffs; + +public: + CPdfFile* pdfFile; + +public: + static void SetUpTestSuite() + { + oWorker = new CApplicationFontsWorker(); -void TEST2(IRenderer* pRenderer) -{ - ((CPdfFile*)pRenderer)->OnlineWordToPdf(NSFile::GetProcessDirectory() + L"/../example/pdf.bin", L""); -} + oWorker->m_sDirectory = NSFile::GetProcessDirectory() + L"/fonts_cache"; + oWorker->m_bIsNeedThumbnails = false; -void TEST3(IRenderer* pRenderer) -{ - ((CPdfFile*)pRenderer)->OnlineWordToPdfFromBinary(NSFile::GetProcessDirectory() + L"/../example1/1/pdf.bin", L""); -} + if (!NSDirectory::Exists(oWorker->m_sDirectory)) + NSDirectory::CreateDirectory(oWorker->m_sDirectory); -int main() -{ - CApplicationFontsWorker oWorker; - oWorker.m_sDirectory = NSFile::GetProcessDirectory() + L"/fonts_cache"; - oWorker.m_bIsNeedThumbnails = false; - - if (!NSDirectory::Exists(oWorker.m_sDirectory)) - NSDirectory::CreateDirectory(oWorker.m_sDirectory); + pApplicationFonts = oWorker->Check(); - NSFonts::IApplicationFonts* pApplicationFonts = oWorker.Check(); + wsTempDir = NSFile::GetProcessDirectory() + L"/pdftemp"; + wsSrcFile = NSFile::GetProcessDirectory() + L"/test.pdf"; + wsDstFile = NSFile::GetProcessDirectory() + L"/test2.pdf"; - std::wstring wsSrcFile = NSFile::GetProcessDirectory() + L"/test.pdf"; - std::wstring wsDstFile = NSFile::GetProcessDirectory() + L"/test2.pdf"; - std::wstring wsTempDir = NSFile::GetProcessDirectory() + L"/pdftemp"; + strDirIn = NSFile::GetProcessDirectory() + L"/resI"; + strDirOut = NSFile::GetProcessDirectory() + L"/resO"; + strDiffs = NSFile::GetProcessDirectory() + L"/resD"; - if (!NSDirectory::Exists(wsTempDir)) - NSDirectory::CreateDirectory(wsTempDir); + if (NSDirectory::Exists(wsTempDir)) + NSDirectory::DeleteDirectory(wsTempDir); + NSDirectory::CreateDirectory(wsTempDir); - CPdfFile pdfFile(pApplicationFonts); - pdfFile.SetTempDirectory(wsTempDir); + if (!NSDirectory::Exists(strDirOut)) + NSDirectory::CreateDirectory(strDirOut); + } + static void TearDownTestSuite() + { + RELEASEINTERFACE(pApplicationFonts); + RELEASEOBJECT(oWorker); + } - std::wstring wsPassword; - bool bResult = pdfFile.LoadFromFile(wsSrcFile); - if (!bResult) - { - wsPassword = L"123456"; - bResult = pdfFile.LoadFromFile(wsSrcFile, L"", wsPassword, wsPassword); - } + void LoadFromFile() + { + bool bResult = pdfFile->LoadFromFile(wsSrcFile); + if (!bResult) + { + std::wstring wsPassword = L"123456"; + bResult = pdfFile->LoadFromFile(wsSrcFile, L"", wsPassword, wsPassword); + } - ICertificate* pCertificate = NULL; - if (false) - { + ASSERT_TRUE(bResult); + } + void DrawSmth() + { + pdfFile->PathCommandStart(); + pdfFile->PathCommandMoveTo(10, 10); + pdfFile->PathCommandLineTo(20, 20); + pdfFile->PathCommandCurveTo(70, 30, 30, 20, 50, 50); + pdfFile->PathCommandClose(); + pdfFile->put_BrushColor1(0xFF0000); + pdfFile->put_PenColor(0x0000FF); + pdfFile->put_PenSize(1); + pdfFile->DrawPath(c_nStroke | c_nWindingFillMode); + pdfFile->PathCommandEnd(); + } + ICertificate* GetCertificate() + { std::wstring wsCertificateFile = NSFile::GetProcessDirectory() + L"/cert.pfx"; - std::wstring wsPrivateKeyFile = L""; - std::string sCertificateFilePassword = "123456"; + std::wstring wsPrivateKeyFile = L""; + std::string sCertificateFilePassword = "123456"; std::string sPrivateFilePassword = ""; - pCertificate = NSCertificate::FromFiles(wsPrivateKeyFile, sPrivateFilePassword, wsCertificateFile, sCertificateFilePassword); + return NSCertificate::FromFiles(wsPrivateKeyFile, sPrivateFilePassword, wsCertificateFile, sCertificateFilePassword); + } + ICertificate* GenerateCertificateECDSA512() + { + std::map properties; + properties.insert(std::make_pair(L"DNS", L"8.8.8.8")); + properties.insert(std::make_pair(L"email", L"sign@onlyoffice.com")); + return NSCertificate::GenerateByAlg("ecdsa512", properties); + } + ICertificate* GenerateCertificateRSA2048() + { std::map properties; properties.insert(std::make_pair(L"DNS", L"8.8.8.8")); - //properties.insert(std::make_pair(L"IP Address", L"127.0.0.1")); properties.insert(std::make_pair(L"email", L"sign@onlyoffice.com")); - //properties.insert(std::make_pair(L"phone", L"+00000000000")); - //std::wstring sNameTest = L"NameTest"; - //std::wstring sValueTest = L"ValueTest"; - //properties.insert(std::make_pair(sNameTest, sValueTest)); - //pCertificate = NSCertificate::GenerateByAlg("ecdsa512", properties); - //pCertificate = NSCertificate::GenerateByAlg("rsa2048", properties); - } + return NSCertificate::GenerateByAlg("rsa2048", properties); + } - if (false) + virtual void SetUp() override + { + pdfFile = new CPdfFile(pApplicationFonts); + pdfFile->SetTempDirectory(wsTempDir); + } + virtual void TearDown() override + { + RELEASEOBJECT(pdfFile); + } +}; + +CApplicationFontsWorker* CPdfFileTest::oWorker = NULL; +NSFonts::IApplicationFonts* CPdfFileTest::pApplicationFonts = NULL; +std::wstring CPdfFileTest::wsTempDir; +std::wstring CPdfFileTest::wsSrcFile; +std::wstring CPdfFileTest::wsDstFile; +std::wstring CPdfFileTest::strDirIn; +std::wstring CPdfFileTest::strDirOut; +std::wstring CPdfFileTest::strDiffs; + +TEST_F(CPdfFileTest, DjVuToPdf) +{ + GTEST_SKIP(); + + CDjVuFile* pDjVu = new CDjVuFile(pApplicationFonts); + pDjVu->LoadFromFile(NSFile::GetProcessDirectory() + L"/test.djvu"); + pDjVu->ConvertToPdf(wsDstFile); + + RELEASEOBJECT(pDjVu); +} + +TEST_F(CPdfFileTest, GetMetaData) +{ + GTEST_SKIP(); + + BYTE* pMetaData = NULL; + DWORD nMetaLength = 0; + + if (pdfFile->GetMetaData(wsSrcFile, L"ONLYOFFICEFORM", &pMetaData, nMetaLength)) { NSFile::CFileBinary oFile; - if (!oFile.OpenFile(NSFile::GetProcessDirectory() + L"/pdf.bin")) - return 0; + if (oFile.CreateFileW(NSFile::GetProcessDirectory() + L"/ONLYOFFICEFORM.docxf")) + oFile.WriteFile(pMetaData, nMetaLength); + oFile.CloseFile(); + + EXPECT_TRUE(pMetaData); + } + RELEASEARRAYOBJECTS(pMetaData); +} - DWORD dwFileSize = oFile.GetFileSize(); - BYTE* pFileContent = new BYTE[dwFileSize]; - if (!pFileContent) +TEST_F(CPdfFileTest, PdfType) +{ + GTEST_SKIP(); + + NSFile::CFileBinary oFile; + ASSERT_TRUE(oFile.OpenFile(wsSrcFile)); + + int nSize = 4096; + BYTE* pBuffer = new BYTE[nSize]; + if (!pBuffer) + { + oFile.CloseFile(); + return; + } + + DWORD dwReadBytes = 0; + oFile.ReadFile(pBuffer, nSize, dwReadBytes); + oFile.CloseFile(); + + char* pData = (char*)pBuffer; + bool bPDF = false; + for (int i = 0; i < nSize - 5; ++i) + { + int nPDF = strncmp(&pData[i], "%PDF-", 5); + if (!nPDF) { - oFile.CloseFile(); - return 0; + bPDF = true; + break; } + } + + ASSERT_TRUE(bPDF); + + RELEASEARRAYOBJECTS(pBuffer); +} + +TEST_F(CPdfFileTest, GetEmbeddedFont) +{ + GTEST_SKIP(); + + LoadFromFile(); + + std::wcout << pdfFile->GetEmbeddedFontPath(L"Symbol") << std::endl; +} - DWORD dwReaded; - oFile.ReadFile(pFileContent, dwFileSize, dwReaded); +TEST_F(CPdfFileTest, ValidMetaData) +{ + GTEST_SKIP(); + + LoadFromFile(); + + std::cout << "ValidMetaData " << (pdfFile->ValidMetaData() ? "true" : "false") << std::endl; +} + +TEST_F(CPdfFileTest, PdfBinToPng) +{ + GTEST_SKIP(); + + NSFile::CFileBinary oFile; + ASSERT_TRUE(oFile.OpenFile(NSFile::GetProcessDirectory() + L"/pdf.bin")); + + DWORD dwFileSize = oFile.GetFileSize(); + BYTE* pFileContent = new BYTE[dwFileSize]; + if (!pFileContent) + { oFile.CloseFile(); + FAIL(); + } + + DWORD dwReaded = 0; + EXPECT_TRUE(oFile.ReadFile(pFileContent, dwFileSize, dwReaded)); + oFile.CloseFile(); - NSOnlineOfficeBinToPdf::CMetafileToRenderterRaster imageWriter(NULL); - imageWriter.SetApplication(pApplicationFonts); - imageWriter.SetRasterFormat(4); - imageWriter.SetFileName(NSFile::GetProcessDirectory() + L"/res.png"); + NSOnlineOfficeBinToPdf::CMetafileToRenderterRaster imageWriter(NULL); + imageWriter.SetApplication(pApplicationFonts); + imageWriter.SetRasterFormat(4); + imageWriter.SetFileName(NSFile::GetProcessDirectory() + L"/resPdfBinToPng.png"); - imageWriter.ConvertBuffer(pFileContent, dwFileSize); + imageWriter.ConvertBuffer(pFileContent, dwFileSize); +} + +TEST_F(CPdfFileTest, PdfFromBin) +{ + GTEST_SKIP(); + + pdfFile->CreatePdf(); + EXPECT_HRESULT_SUCCEEDED(pdfFile->OnlineWordToPdfFromBinary(NSFile::GetProcessDirectory() + L"/pdf.bin", wsDstFile)); +} + +TEST_F(CPdfFileTest, PdfFromBase64) +{ + GTEST_SKIP(); + + pdfFile->CreatePdf(); + EXPECT_HRESULT_SUCCEEDED(pdfFile->OnlineWordToPdf(NSFile::GetProcessDirectory() + L"/base64.txt", wsDstFile)); +} + +TEST_F(CPdfFileTest, PdfToPdf) +{ + GTEST_SKIP(); + + LoadFromFile(); + pdfFile->CreatePdf(); + + for (int i = 0; i < pdfFile->GetPagesCount(); i++) + { + pdfFile->NewPage(); + pdfFile->DrawPageOnRenderer(pdfFile, i, NULL); + } + + pdfFile->SaveToFile(wsDstFile); +} + +TEST_F(CPdfFileTest, SetMetaData) +{ + GTEST_SKIP(); + + pdfFile->CreatePdf(); + + BYTE* pFileData = NULL; + DWORD nFileSize; + std::wstring sFile = NSFile::GetProcessDirectory() + L"/ONLYOFFICEFORM.docxf"; + EXPECT_TRUE(NSFile::CFileBinary::ReadAllBytes(sFile, &pFileData, nFileSize)); + pdfFile->AddMetaData(L"ONLYOFFICEFORM", pFileData, nFileSize); + RELEASEARRAYOBJECTS(pFileData); + + EXPECT_HRESULT_SUCCEEDED(pdfFile->OnlineWordToPdfFromBinary(NSFile::GetProcessDirectory() + L"/pdf.bin", wsDstFile)); +} + +TEST_F(CPdfFileTest, ConvertToRaster) +{ + GTEST_SKIP(); + LoadFromFile(); + + double dPageDpiX, dPageDpiY, dWidth, dHeight; + int i = 0; + //for (i = 0; i < pdfFile->GetPagesCount(); i++) + { + pdfFile->GetPageInfo(i, &dWidth, &dHeight, &dPageDpiX, &dPageDpiY); + pdfFile->ConvertToRaster(i, NSFile::GetProcessDirectory() + L"/resO/res" + std::to_wstring(i) + L".png", 4, dWidth, dHeight, true, pdfFile->GetFontManager()); + } +} + +TEST_F(CPdfFileTest, VerifySign) +{ + GTEST_SKIP(); + + LoadFromFile(); + + ICertificate* pCertificate = GetCertificate(); + ASSERT_TRUE(pCertificate); + + BYTE* pWidgets = pdfFile->VerifySign(wsSrcFile, pCertificate); + EXPECT_TRUE(pWidgets); + + RELEASEARRAYOBJECTS(pWidgets); + RELEASEOBJECT(pCertificate); +} + +TEST_F(CPdfFileTest, EditPdf) +{ + GTEST_SKIP(); + + LoadFromFile(); + ASSERT_TRUE(pdfFile->EditPdf(wsDstFile)); + + EXPECT_TRUE(pdfFile->EditPage(0)); + { + DrawSmth(); + pdfFile->RotatePage(90); + } + + pdfFile->DeletePage(1); + + pdfFile->AddPage(2); + + pdfFile->Close(); +} + +TEST_F(CPdfFileTest, EditPdfFromBase64) +{ + //GTEST_SKIP(); + + NSFonts::NSApplicationFontStream::SetGlobalMemoryStorage(NSFonts::NSApplicationFontStream::CreateDefaultGlobalMemoryStorage()); + + LoadFromFile(); + ASSERT_TRUE(pdfFile->EditPdf(wsDstFile)); + + // чтение и конвертации бинарника + NSFile::CFileBinary oFile; + ASSERT_TRUE(oFile.OpenFile(NSFile::GetProcessDirectory() + L"/base64.txt")); + + DWORD dwFileSize = oFile.GetFileSize(); + BYTE* pFileContent = new BYTE[dwFileSize]; + if (!pFileContent) + { + oFile.CloseFile(); + FAIL(); + } + + DWORD dwReaded; + EXPECT_TRUE(oFile.ReadFile(pFileContent, dwFileSize, dwReaded)); + oFile.CloseFile(); + + int nBufferLen = NSBase64::Base64DecodeGetRequiredLength(dwFileSize); + BYTE* pBuffer = new BYTE[nBufferLen]; + if (!pBuffer) + { RELEASEARRAYOBJECTS(pFileContent); - RELEASEINTERFACE(pApplicationFonts); - RELEASEOBJECT(pCertificate); - return 0; + FAIL(); } - if (false) - { - pdfFile.CreatePdf(); - pdfFile.OnlineWordToPdfFromBinary(NSFile::GetProcessDirectory() + L"/pdf.bin", wsDstFile); - - RELEASEINTERFACE(pApplicationFonts); - RELEASEOBJECT(pCertificate); - return 0; - } - - if (false) - { - double dPageDpiX, dPageDpiY, dWidth, dHeight; - int i = 0; - for (i = 0; i < pdfFile.GetPagesCount(); i++) - { - pdfFile.GetPageInfo(i, &dWidth, &dHeight, &dPageDpiX, &dPageDpiY); - pdfFile.ConvertToRaster(i, NSFile::GetProcessDirectory() + L"/res" + std::to_wstring(i) + L".png", 4, dWidth, dHeight, true, pdfFile.GetFontManager()); - } - - if (pCertificate) - { - BYTE* pWidgets = pdfFile.VerifySign(wsSrcFile, pCertificate); - RELEASEARRAYOBJECTS(pWidgets); - } - - RELEASEINTERFACE(pApplicationFonts); - RELEASEOBJECT(pCertificate); - return 0; - } - - if (false) - { - pdfFile.CreatePdf(true); - double dPageDpiX, dPageDpiY, dWidth, dHeight; - pdfFile.GetPageInfo(0, &dWidth, &dHeight, &dPageDpiX, &dPageDpiY); - - dWidth *= 25.4 / dPageDpiX; - dHeight *= 25.4 / dPageDpiY; - - pdfFile.NewPage(); - pdfFile.BeginCommand(c_nPageType); - pdfFile.put_Width(dWidth); - pdfFile.put_Height(dHeight); - std::string sTitle = "1<2<3<4"; - pdfFile.SetDocumentInfo(UTF8_TO_U(sTitle), L"5\"6\";7\'8\'", L"1>2>3>4", L"1&2&3&4&5"); - //pdfFile.DrawImageFromFile(NSFile::GetProcessDirectory() + L"/test.jpg", 10, 10, 455, 200); - pdfFile.EndCommand(c_nPageType); - - if (pCertificate) - pdfFile.Sign(10, 70, 50, 50, NSFile::GetProcessDirectory() + L"/test.png", pCertificate); - int nRes = pdfFile.SaveToFile(wsDstFile); - - RELEASEINTERFACE(pApplicationFonts); - RELEASEOBJECT(pCertificate); - return 0; - } - - if (bResult && pdfFile.EditPdf(wsDstFile)) - { - if (pCertificate) - { - if (pdfFile.EditPage(0)) - { - //TEST(&pdfFile); - pdfFile.Sign(10, 10, 100, 100, NSFile::GetProcessDirectory() + L"/test.jpeg", pCertificate); - } - } - else if (true) - { - // чтение и конвертации бинарника - NSFile::CFileBinary oFile; - if (!oFile.OpenFile(NSFile::GetProcessDirectory() + L"/base64.txt")) - return 0; + EXPECT_TRUE(NSBase64::Base64Decode((const char*)pFileContent, dwFileSize, pBuffer, &nBufferLen)); + CConvertFromBinParams* pParams = new CConvertFromBinParams(); + pParams->m_sMediaDirectory = NSFile::GetProcessDirectory(); + pdfFile->AddToPdfFromBinary(pBuffer + 4, nBufferLen - 4, pParams); - DWORD dwFileSize = oFile.GetFileSize(); - BYTE* pFileContent = new BYTE[dwFileSize]; - if (!pFileContent) - { - oFile.CloseFile(); - return 0; - } + RELEASEOBJECT(pParams); + RELEASEARRAYOBJECTS(pBuffer); + RELEASEARRAYOBJECTS(pFileContent); - DWORD dwReaded; - oFile.ReadFile(pFileContent, dwFileSize, dwReaded); - oFile.CloseFile(); + pdfFile->Close(); +} - int nBufferLen = NSBase64::Base64DecodeGetRequiredLength(dwFileSize); - BYTE* pBuffer = new BYTE[nBufferLen]; - if (!pBuffer) - { - RELEASEARRAYOBJECTS(pFileContent); - return 0; - } +TEST_F(CPdfFileTest, EditPdfFromBin) +{ + GTEST_SKIP(); + + LoadFromFile(); + ASSERT_TRUE(pdfFile->EditPdf(wsDstFile)); + + // чтение бинарника + NSFile::CFileBinary oFile; + ASSERT_TRUE(oFile.OpenFile(NSFile::GetProcessDirectory() + L"/changes0.json")); + + DWORD dwFileSize = oFile.GetFileSize(); + BYTE* pFileContent = new BYTE[dwFileSize]; + if (!pFileContent) + { + oFile.CloseFile(); + FAIL(); + } + + DWORD dwReaded; + EXPECT_TRUE(oFile.ReadFile(pFileContent, dwFileSize, dwReaded)); + oFile.CloseFile(); - if (NSBase64::Base64Decode((const char*)pFileContent, dwFileSize, pBuffer, &nBufferLen)) - pdfFile.AddToPdfFromBinary(pBuffer, nBufferLen, NULL); + CConvertFromBinParams* pParams = new CConvertFromBinParams(); + pParams->m_sMediaDirectory = NSFile::GetProcessDirectory(); + pdfFile->AddToPdfFromBinary(pFileContent, dwReaded, pParams); + + RELEASEOBJECT(pParams); + RELEASEARRAYOBJECTS(pFileContent); + + pdfFile->Close(); +} + +TEST_F(CPdfFileTest, EditPdfSign) +{ + GTEST_SKIP(); + + LoadFromFile(); + ASSERT_TRUE(pdfFile->EditPdf(wsDstFile)); + + ICertificate* pCertificate = GetCertificate(); + ASSERT_TRUE(pCertificate); + + EXPECT_TRUE(pdfFile->EditPage(0)); + { + pdfFile->Sign(10, 10, 100, 100, NSFile::GetProcessDirectory() + L"/test.jpeg", pCertificate); + } + + pdfFile->Close(); + + RELEASEOBJECT(pCertificate); +} + +TEST_F(CPdfFileTest, ChangePasswordToEmpty) +{ + GTEST_SKIP(); + + LoadFromFile(); + EXPECT_HRESULT_SUCCEEDED(pdfFile->ChangePassword(wsDstFile)); +} + +TEST_F(CPdfFileTest, ChangePasswordToPassword) +{ + GTEST_SKIP(); + + LoadFromFile(); + EXPECT_HRESULT_SUCCEEDED(pdfFile->ChangePassword(wsDstFile, L"123456")); +} - RELEASEARRAYOBJECTS(pBuffer); - RELEASEARRAYOBJECTS(pFileContent); +TEST_F(CPdfFileTest, ImgDiff) +{ + GTEST_SKIP(); + + if (NSDirectory::Exists(strDirIn)) + NSDirectory::DeleteDirectory(strDirIn); + NSDirectory::CreateDirectory(strDirIn); + if (NSDirectory::Exists(strDirOut)) + NSDirectory::DeleteDirectory(strDirOut); + NSDirectory::CreateDirectory(strDirOut); + if (NSDirectory::Exists(strDiffs)) + NSDirectory::DeleteDirectory(strDiffs); + NSDirectory::CreateDirectory(strDiffs); + + LoadFromFile(); + + int nCountInPages = pdfFile->GetPagesCount(); + for (int nPage = 0; nPage < nCountInPages; ++nPage) + { + std::wstring sPageI = strDirIn + L"/res" + std::to_wstring(nPage) + L".png"; + std::wstring sPageO = strDirOut + L"/res" + std::to_wstring(nPage) + L".png"; + std::wstring sPageDiff = strDiffs + L"/res" + std::to_wstring(nPage) + 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(strDiffs)) + NSDirectory::CreateDirectories(CorrectPathW(strDiffs)); + + std::wstring sFilePagesDiff = sPageDiff; + NSFile::CFileBinary oFile; + oFile.CreateFileW(sPageDiff); + oFile.WriteStringUTF8(L"sizes!"); + oFile.CloseFile(); + continue; } - else if (false) + + 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; + + int nEpsilonEps = 3; + int nEpsilonNatural = 5; + + int nDivExist = 0; + for (int indexPixH = 0; indexPixH < nH_I; indexPixH++) { - if (pdfFile.EditPage(0)) + for (int indexPixW = 0; indexPixW < nW_I; indexPixW++) { - pdfFile.EditAnnot(0, 99); + if (pDataI[0] != pDataO[0] || pDataI[1] != pDataO[1] || pDataI[2] != pDataO[2]) + { + // test epsilon natural + if ((abs(pDataI[0] - pDataO[0]) < nEpsilonNatural) && + (abs(pDataI[1] - pDataO[1]) < nEpsilonNatural) && + (abs(pDataI[2] - pDataO[2]) < nEpsilonNatural)) + { + pDataI += 4; + pDataO += 4; + continue; + } + + // test epsilon left, right, top, bottom + int nEpsUp = nEpsilonEps; + if (indexPixH > 0) + { + BYTE* pByteI = frameI.get_Data() + 4 * (indexPixH - 1) * nW_I + 4 * indexPixW; + + if ((abs(pByteI[0] - pDataO[0]) < nEpsilonEps) && + (abs(pByteI[1] - pDataO[1]) < nEpsilonEps) && + (abs(pByteI[2] - pDataO[2]) < nEpsilonEps)) + { + nEpsUp = nEpsilonEps - 1; + } + } + + int nEpsDown = nEpsilonEps; + if (indexPixH < (nH_I - 1)) + { + BYTE* pByteI = frameI.get_Data() + 4 * (indexPixH + 1) * nW_I + 4 * indexPixW; + + if ((abs(pByteI[0] - pDataO[0]) < nEpsilonEps) && + (abs(pByteI[1] - pDataO[1]) < nEpsilonEps) && + (abs(pByteI[2] - pDataO[2]) < nEpsilonEps)) + { + nEpsDown = nEpsilonEps - 1; + } + } + + int nEpsLeft = nEpsilonEps; + if (indexPixW > 0) + { + BYTE* pByteI = pDataI - 4; + + if ((abs(pByteI[0] - pDataO[0]) < nEpsilonEps) && + (abs(pByteI[1] - pDataO[1]) < nEpsilonEps) && + (abs(pByteI[2] - pDataO[2]) < nEpsilonEps)) + { + nEpsLeft = nEpsilonEps - 1; + } + } + + int nEpsRight = nEpsilonEps; + if (indexPixW < (nW_I - 1)) + { + BYTE* pByteI = pDataI + 4; + + if ((abs(pByteI[0] - pDataO[0]) < nEpsilonEps) && + (abs(pByteI[1] - pDataO[1]) < nEpsilonEps) && + (abs(pByteI[2] - pDataO[2]) < nEpsilonEps)) + { + nEpsRight = nEpsilonEps - 1; + } + } + + if ((nEpsLeft < nEpsilonEps) || + (nEpsRight < nEpsilonEps) || + (nEpsUp < nEpsilonEps) || + (nEpsDown < nEpsilonEps)) + { + pDataI += 4; + pDataO += 4; + continue; + } + + ++nDivExist; + + 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; } } - else - { - if (pdfFile.EditPage(0)) - { - TEST(&pdfFile); - pdfFile.RotatePage(90); - } - pdfFile.DeletePage(1); + if (nDivExist > 7) + { + if (!NSDirectory::Exists(strDiffs)) + NSDirectory::CreateDirectories(CorrectPathW(strDiffs)); - if (pdfFile.EditPage(1)) - { - TEST2(&pdfFile); - } + CBgraFrame frameOSrc; + frameOSrc.OpenFile(sPageO); - if (pdfFile.AddPage(3)) + BYTE* pData1 = frameI.get_Data(); + BYTE* pData2 = frameOSrc.get_Data(); + BYTE* pData3 = frameO.get_Data(); + + int nRowW = 4 * nW_I; + BYTE* pDataAll = new BYTE[3 * nRowW * nH_I]; + BYTE* pDataAllSrc = pDataAll; + for (int j = 0; j < nH_I; j++) { - TEST3(&pdfFile); - } - } + memcpy(pDataAll, pData1, nRowW); + pDataAll += nRowW; + pData1 += nRowW; + + memcpy(pDataAll, pData2, nRowW); + pDataAll += nRowW; + pData2 += nRowW; - pdfFile.Close(); - } + memcpy(pDataAll, pData3, nRowW); + pDataAll += nRowW; + pData3 += nRowW; + } - RELEASEINTERFACE(pApplicationFonts); - RELEASEOBJECT(pCertificate); - return 0; + CBgraFrame oFrameAll; + oFrameAll.put_Data(pDataAllSrc); + oFrameAll.put_Width(3 * nW_I); + oFrameAll.put_Height(nH_I); + oFrameAll.put_Stride(-3 * nRowW); + oFrameAll.SaveFile(sPageDiff, 4); + } + } } diff --git a/PdfFile/test/test.pro b/PdfFile/test/test.pro index aa172132030..040b2c268c7 100644 --- a/PdfFile/test/test.pro +++ b/PdfFile/test/test.pro @@ -10,9 +10,10 @@ CONFIG -= app_bundle CORE_ROOT_DIR = $$PWD/../.. PWD_ROOT_DIR = $$PWD include($$CORE_ROOT_DIR/Common/base.pri) +include($$CORE_ROOT_DIR/Common/3dParty/googletest/googletest.pri) include($$CORE_ROOT_DIR/Common/3dParty/icu/icu.pri) -ADD_DEPENDENCY(UnicodeConverter, kernel, graphics, PdfFile, ooxmlsignature) +ADD_DEPENDENCY(UnicodeConverter, kernel, graphics, PdfFile, DjVuFile, ooxmlsignature) SOURCES += test.cpp diff --git a/RtfFile/Format/DestinationCommand.cpp b/RtfFile/Format/DestinationCommand.cpp index 6d14a90bd70..c3f2f6fd1c7 100644 --- a/RtfFile/Format/DestinationCommand.cpp +++ b/RtfFile/Format/DestinationCommand.cpp @@ -68,7 +68,8 @@ void ConvertOle1ToOle2(BYTE *pData, int nSize, std::wstring sOle2Name) { POLE::Stream stream(storageIn, L"Package"); if (false == stream.fail()) - {//test package stream??? xls ole -> xlsx ole + { +// AVS_OFFICESTUDIO_FILE_OTHER_PACKAGE_IN_OLE POLE::uint64 size = stream.size(); unsigned char* data = new unsigned char[size]; @@ -217,31 +218,31 @@ bool RtfDocumentCommand::ExecuteCommand(RtfDocument& oDocument, RtfReader& oRead } COMMAND_RTF_INT ( "themelang", oDocument.m_oProperty.m_nThemelang, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "themelangfe", oDocument.m_oProperty.m_nThemelangfe, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "themelangcs", oDocument.m_oProperty.m_nThemelangcs, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "themelangfe", oDocument.m_oProperty.m_nThemelangfe, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "themelangcs", oDocument.m_oProperty.m_nThemelangcs, sCommand, hasParameter, parameter ) - COMMAND_RTF_BOOL( "rtlgutter", oDocument.m_oProperty.m_bRtlGutter, sCommand, hasParameter, parameter) - COMMAND_RTF_BOOL( "rtldoc", oDocument.m_oProperty.m_bRtl, sCommand, hasParameter, parameter) + COMMAND_RTF_BOOL( "rtlgutter", oDocument.m_oProperty.m_bRtlGutter, sCommand, hasParameter, parameter) + COMMAND_RTF_BOOL( "rtldoc", oDocument.m_oProperty.m_bRtl, sCommand, hasParameter, parameter) - COMMAND_RTF_BOOL( "hyphcaps", oDocument.m_oProperty.m_bHypCaps, sCommand, hasParameter, parameter ) - COMMAND_RTF_BOOL( "hyphauto", oDocument.m_oProperty.m_bAutoHyp, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "hyphconsec", oDocument.m_oProperty.m_nMaxHypen, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "hyphhotz", oDocument.m_oProperty.m_nHyphenationRight, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "deftab", oDocument.m_oProperty.m_nTabWidth, sCommand, hasParameter, parameter ) + COMMAND_RTF_BOOL( "hyphcaps", oDocument.m_oProperty.m_bHypCaps, sCommand, hasParameter, parameter ) + COMMAND_RTF_BOOL( "hyphauto", oDocument.m_oProperty.m_bAutoHyp, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "hyphconsec", oDocument.m_oProperty.m_nMaxHypen, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "hyphhotz", oDocument.m_oProperty.m_nHyphenationRight, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "deftab", oDocument.m_oProperty.m_nTabWidth, sCommand, hasParameter, parameter ) //Page Borders - COMMAND_RTF_BOOL( "pgbrdrhead", oDocument.m_oProperty.m_bDorderSurroundHeader, sCommand, hasParameter, parameter ) - COMMAND_RTF_BOOL( "pgbrdrfoot", oDocument.m_oProperty.m_bDorderSurroundFotter, sCommand, hasParameter, parameter ) - COMMAND_RTF_BOOL( "pgbrdrsnap", oDocument.m_oProperty.m_bAlignBordersAndEdges, sCommand, hasParameter, parameter ) + COMMAND_RTF_BOOL( "pgbrdrhead", oDocument.m_oProperty.m_bDorderSurroundHeader, sCommand, hasParameter, parameter ) + COMMAND_RTF_BOOL( "pgbrdrfoot", oDocument.m_oProperty.m_bDorderSurroundFotter, sCommand, hasParameter, parameter ) + COMMAND_RTF_BOOL( "pgbrdrsnap", oDocument.m_oProperty.m_bAlignBordersAndEdges, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "dghspace", oDocument.m_oProperty.m_nDrawingGridHorizontalSpacing, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "dgvspace", oDocument.m_oProperty.m_nDrawingGridVerticalSpacing, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "dghorigin", oDocument.m_oProperty.m_nDrawingGridHorizontalOrigin, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "dgvorigin", oDocument.m_oProperty.m_nDrawingGridVerticalOrigin, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "dghshow", oDocument.m_oProperty.m_nDisplayHorizontalDrawingGridEvery, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "dgvshow", oDocument.m_oProperty.m_nDisplayVerticalDrawingGridEvery, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "dghspace", oDocument.m_oProperty.m_nDrawingGridHorizontalSpacing, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "dgvspace", oDocument.m_oProperty.m_nDrawingGridVerticalSpacing, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "dghorigin", oDocument.m_oProperty.m_nDrawingGridHorizontalOrigin, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "dgvorigin", oDocument.m_oProperty.m_nDrawingGridVerticalOrigin, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "dghshow", oDocument.m_oProperty.m_nDisplayHorizontalDrawingGridEvery, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "dgvshow", oDocument.m_oProperty.m_nDisplayVerticalDrawingGridEvery, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "viewscale", oDocument.m_oProperty.m_nZoom, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "viewscale", oDocument.m_oProperty.m_nZoom, sCommand, hasParameter, parameter ) //Page Informationf else if ( "paperw" == sCommand ) @@ -339,72 +340,72 @@ bool RtfDocumentCommand::ExecuteCommand(RtfDocument& oDocument, RtfReader& oRead oDocument.m_oProperty.m_bLandScape = 1; } COMMAND_RTF_BOOL( "gutterprl", oDocument.m_oProperty.m_bGutterAtTop, sCommand, hasParameter, parameter ) - COMMAND_RTF_BOOL( "viewbksp", oDocument.m_oProperty.m_nDisplayBackground, sCommand, hasParameter, parameter ) - COMMAND_RTF_BOOL( "htmautsp", oDocument.m_oProperty.m_bHtmlAutoSpace, sCommand, hasParameter, parameter ) - COMMAND_RTF_BOOL( "useltbaln", oDocument.m_oProperty.m_bUseTabAlignment, sCommand, hasParameter, parameter ) + COMMAND_RTF_BOOL( "viewbksp", oDocument.m_oProperty.m_nDisplayBackground, sCommand, hasParameter, parameter ) + COMMAND_RTF_BOOL( "htmautsp", oDocument.m_oProperty.m_bHtmlAutoSpace, sCommand, hasParameter, parameter ) + COMMAND_RTF_BOOL( "useltbaln", oDocument.m_oProperty.m_bUseTabAlignment, sCommand, hasParameter, parameter ) //Footnotes and Endnotes - COMMAND_RTF_INT ( "endnotes", oDocument.m_oProperty.m_eFootnotePlacement, sCommand, true, RtfDocumentProperty::fp_EndSection ) - COMMAND_RTF_INT ( "enddoc", oDocument.m_oProperty.m_eFootnotePlacement, sCommand, true, RtfDocumentProperty::fp_EndDocument ) - COMMAND_RTF_INT ( "ftntj", oDocument.m_oProperty.m_eFootnotePlacement, sCommand, true, RtfDocumentProperty::fp_BeneathText ) - COMMAND_RTF_INT ( "ftnbj", oDocument.m_oProperty.m_eFootnotePlacement, sCommand, true, RtfDocumentProperty::fp_BottomPage ) - - COMMAND_RTF_INT ( "aendnotes", oDocument.m_oProperty.m_eEndnotePlacement, sCommand, true, RtfDocumentProperty::ep_EndSection ) - COMMAND_RTF_INT ( "aenddoc", oDocument.m_oProperty.m_eEndnotePlacement, sCommand, true, RtfDocumentProperty::ep_EndDocument ) - COMMAND_RTF_INT ( "aftnbj", oDocument.m_oProperty.m_eEndnotePlacement, sCommand, true, RtfDocumentProperty::ep_BeneathText ) - COMMAND_RTF_INT ( "aftntj", oDocument.m_oProperty.m_eEndnotePlacement, sCommand, true, RtfDocumentProperty::ep_BottomPage ) - - COMMAND_RTF_INT ( "ftnstart", oDocument.m_oProperty.m_nFootnoteStart, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "aftnstart", oDocument.m_oProperty.m_nEndnoteStart, sCommand, hasParameter, parameter ) - - COMMAND_RTF_INT ( "ftnrstpg", oDocument.m_oProperty.m_eFootnoteRestart, sCommand, true, RtfDocumentProperty::fr_EachPage ) - COMMAND_RTF_INT ( "ftnrestart", oDocument.m_oProperty.m_eFootnoteRestart, sCommand, true, RtfDocumentProperty::fr_EachSection ) - COMMAND_RTF_INT ( "ftnrstcont", oDocument.m_oProperty.m_eFootnoteRestart, sCommand, true, RtfDocumentProperty::fr_Continuous ) - COMMAND_RTF_INT ( "aftnrestart", oDocument.m_oProperty.m_eEndnoteRestart, sCommand, true, RtfDocumentProperty::er_EachSection ) - COMMAND_RTF_INT ( "aftnrstcont", oDocument.m_oProperty.m_eEndnoteRestart, sCommand, true, RtfDocumentProperty::er_Continuous ) - - COMMAND_RTF_INT ( "ftnnar", oDocument.m_oProperty.m_nFootnoteNumberingFormat, sCommand, true, 0 ) - COMMAND_RTF_INT ( "ftnnalc", oDocument.m_oProperty.m_nFootnoteNumberingFormat, sCommand, true, 4 ) - COMMAND_RTF_INT ( "ftnnauc", oDocument.m_oProperty.m_nFootnoteNumberingFormat, sCommand, true, 3 ) - COMMAND_RTF_INT ( "ftnnrlc", oDocument.m_oProperty.m_nFootnoteNumberingFormat, sCommand, true, 2 ) - COMMAND_RTF_INT ( "ftnnruc", oDocument.m_oProperty.m_nFootnoteNumberingFormat, sCommand, true, 1 ) - COMMAND_RTF_INT ( "ftnnchi", oDocument.m_oProperty.m_nFootnoteNumberingFormat, sCommand, true, 70 ) - COMMAND_RTF_INT ( "ftnnchi", oDocument.m_oProperty.m_nFootnoteNumberingFormat, sCommand, true, 25 ) - COMMAND_RTF_INT ( "ftnncnum", oDocument.m_oProperty.m_nFootnoteNumberingFormat, sCommand, true, 18 ) - COMMAND_RTF_INT ( "ftnndbnum", oDocument.m_oProperty.m_nFootnoteNumberingFormat, sCommand, true, 10 ) - COMMAND_RTF_INT ( "ftnndbnumd", oDocument.m_oProperty.m_nFootnoteNumberingFormat, sCommand, true, 11 ) - COMMAND_RTF_INT ( "ftnndbnumt", oDocument.m_oProperty.m_nFootnoteNumberingFormat, sCommand, true, 16 ) - COMMAND_RTF_INT ( "ftnndbnumk", oDocument.m_oProperty.m_nFootnoteNumberingFormat, sCommand, true, 17 ) - COMMAND_RTF_INT ( "ftnndbar", oDocument.m_oProperty.m_nFootnoteNumberingFormat, sCommand, true, 20 ) - COMMAND_RTF_INT ( "ftnnganada", oDocument.m_oProperty.m_nFootnoteNumberingFormat, sCommand, true, 24 ) - COMMAND_RTF_INT ( "ftnngbnum", oDocument.m_oProperty.m_nFootnoteNumberingFormat, sCommand, true, 26 ) - COMMAND_RTF_INT ( "ftnngbnumd", oDocument.m_oProperty.m_nFootnoteNumberingFormat, sCommand, true, 27 ) - COMMAND_RTF_INT ( "ftnngbnuml", oDocument.m_oProperty.m_nFootnoteNumberingFormat, sCommand, true, 28 ) - COMMAND_RTF_INT ( "ftnngbnumk", oDocument.m_oProperty.m_nFootnoteNumberingFormat, sCommand, true, 29 ) - COMMAND_RTF_INT ( "ftnnzodiac", oDocument.m_oProperty.m_nFootnoteNumberingFormat, sCommand, true, 30 ) - COMMAND_RTF_INT ( "ftnnzodiacd", oDocument.m_oProperty.m_nFootnoteNumberingFormat, sCommand, true, 31 ) - COMMAND_RTF_INT ( "ftnnzodiacl", oDocument.m_oProperty.m_nFootnoteNumberingFormat, sCommand, true, 32 ) - - COMMAND_RTF_INT ( "aftnnar", oDocument.m_oProperty.m_nFootnoteNumberingFormat, sCommand, true, 0 ) - COMMAND_RTF_INT ( "aftnnalc", oDocument.m_oProperty.m_nFootnoteNumberingFormat, sCommand, true, 4 ) - COMMAND_RTF_INT ( "aftnnauc", oDocument.m_oProperty.m_nFootnoteNumberingFormat, sCommand, true, 3 ) - COMMAND_RTF_INT ( "aftnnrlc", oDocument.m_oProperty.m_nFootnoteNumberingFormat, sCommand, true, 2 ) - COMMAND_RTF_INT ( "aftnnruc", oDocument.m_oProperty.m_nFootnoteNumberingFormat, sCommand, true, 1 ) - COMMAND_RTF_INT ( "aftnnchi", oDocument.m_oProperty.m_nFootnoteNumberingFormat, sCommand, true, 70 ) - COMMAND_RTF_INT ( "aftnnchi", oDocument.m_oProperty.m_nFootnoteNumberingFormat, sCommand, true, 25 ) - COMMAND_RTF_INT ( "aftnncnum", oDocument.m_oProperty.m_nFootnoteNumberingFormat, sCommand, true, 18 ) - COMMAND_RTF_INT ( "aftnndbnum", oDocument.m_oProperty.m_nFootnoteNumberingFormat, sCommand, true, 10 ) - COMMAND_RTF_INT ( "aftnndbnumd", oDocument.m_oProperty.m_nFootnoteNumberingFormat, sCommand, true, 11 ) - COMMAND_RTF_INT ( "aftnndbnumt", oDocument.m_oProperty.m_nFootnoteNumberingFormat, sCommand, true, 16 ) - COMMAND_RTF_INT ( "aftnndbnumk", oDocument.m_oProperty.m_nFootnoteNumberingFormat, sCommand, true, 17 ) - COMMAND_RTF_INT ( "aftnndbar", oDocument.m_oProperty.m_nFootnoteNumberingFormat, sCommand, true, 20 ) - COMMAND_RTF_INT ( "aftnnganada", oDocument.m_oProperty.m_nFootnoteNumberingFormat, sCommand, true, 24 ) - COMMAND_RTF_INT ( "aftnngbnum", oDocument.m_oProperty.m_nFootnoteNumberingFormat, sCommand, true, 26 ) - COMMAND_RTF_INT ( "aftnngbnumd", oDocument.m_oProperty.m_nFootnoteNumberingFormat, sCommand, true, 27 ) - COMMAND_RTF_INT ( "aftnngbnuml", oDocument.m_oProperty.m_nFootnoteNumberingFormat, sCommand, true, 28 ) - COMMAND_RTF_INT ( "aftnngbnumk", oDocument.m_oProperty.m_nFootnoteNumberingFormat, sCommand, true, 29 ) - COMMAND_RTF_INT ( "aftnnzodiac", oDocument.m_oProperty.m_nFootnoteNumberingFormat, sCommand, true, 30 ) - COMMAND_RTF_INT ( "aftnnzodiacd", oDocument.m_oProperty.m_nFootnoteNumberingFormat, sCommand, true, 31 ) - COMMAND_RTF_INT ( "aftnnzodiacl", oDocument.m_oProperty.m_nFootnoteNumberingFormat, sCommand, true, 32 ) + COMMAND_RTF_INT ( "endnotes", oDocument.m_oProperty.m_eFootnotePlacement, sCommand, true, RtfDocumentProperty::fp_EndSection ) + COMMAND_RTF_INT ( "enddoc", oDocument.m_oProperty.m_eFootnotePlacement, sCommand, true, RtfDocumentProperty::fp_EndDocument ) + COMMAND_RTF_INT ( "ftntj", oDocument.m_oProperty.m_eFootnotePlacement, sCommand, true, RtfDocumentProperty::fp_BeneathText ) + COMMAND_RTF_INT ( "ftnbj", oDocument.m_oProperty.m_eFootnotePlacement, sCommand, true, RtfDocumentProperty::fp_BottomPage ) + + COMMAND_RTF_INT ( "aendnotes", oDocument.m_oProperty.m_eEndnotePlacement, sCommand, true, RtfDocumentProperty::ep_EndSection ) + COMMAND_RTF_INT ( "aenddoc", oDocument.m_oProperty.m_eEndnotePlacement, sCommand, true, RtfDocumentProperty::ep_EndDocument ) + COMMAND_RTF_INT ( "aftnbj", oDocument.m_oProperty.m_eEndnotePlacement, sCommand, true, RtfDocumentProperty::ep_BeneathText ) + COMMAND_RTF_INT ( "aftntj", oDocument.m_oProperty.m_eEndnotePlacement, sCommand, true, RtfDocumentProperty::ep_BottomPage ) + + COMMAND_RTF_INT ( "ftnstart", oDocument.m_oProperty.m_nFootnoteStart, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "aftnstart", oDocument.m_oProperty.m_nEndnoteStart, sCommand, hasParameter, parameter ) + + COMMAND_RTF_INT ( "ftnrstpg", oDocument.m_oProperty.m_eFootnoteRestart, sCommand, true, RtfDocumentProperty::fr_EachPage ) + COMMAND_RTF_INT ( "ftnrestart", oDocument.m_oProperty.m_eFootnoteRestart, sCommand, true, RtfDocumentProperty::fr_EachSection ) + COMMAND_RTF_INT ( "ftnrstcont", oDocument.m_oProperty.m_eFootnoteRestart, sCommand, true, RtfDocumentProperty::fr_Continuous ) + COMMAND_RTF_INT ( "aftnrestart", oDocument.m_oProperty.m_eEndnoteRestart, sCommand, true, RtfDocumentProperty::er_EachSection ) + COMMAND_RTF_INT ( "aftnrstcont", oDocument.m_oProperty.m_eEndnoteRestart, sCommand, true, RtfDocumentProperty::er_Continuous ) + + COMMAND_RTF_INT ( "ftnnar", oDocument.m_oProperty.m_nFootnoteNumberingFormat, sCommand, true, 0 ) + COMMAND_RTF_INT ( "ftnnalc", oDocument.m_oProperty.m_nFootnoteNumberingFormat, sCommand, true, 4 ) + COMMAND_RTF_INT ( "ftnnauc", oDocument.m_oProperty.m_nFootnoteNumberingFormat, sCommand, true, 3 ) + COMMAND_RTF_INT ( "ftnnrlc", oDocument.m_oProperty.m_nFootnoteNumberingFormat, sCommand, true, 2 ) + COMMAND_RTF_INT ( "ftnnruc", oDocument.m_oProperty.m_nFootnoteNumberingFormat, sCommand, true, 1 ) + COMMAND_RTF_INT ( "ftnnchi", oDocument.m_oProperty.m_nFootnoteNumberingFormat, sCommand, true, 70 ) + COMMAND_RTF_INT ( "ftnnchi", oDocument.m_oProperty.m_nFootnoteNumberingFormat, sCommand, true, 25 ) + COMMAND_RTF_INT ( "ftnncnum", oDocument.m_oProperty.m_nFootnoteNumberingFormat, sCommand, true, 18 ) + COMMAND_RTF_INT ( "ftnndbnum", oDocument.m_oProperty.m_nFootnoteNumberingFormat, sCommand, true, 10 ) + COMMAND_RTF_INT ( "ftnndbnumd", oDocument.m_oProperty.m_nFootnoteNumberingFormat, sCommand, true, 11 ) + COMMAND_RTF_INT ( "ftnndbnumt", oDocument.m_oProperty.m_nFootnoteNumberingFormat, sCommand, true, 16 ) + COMMAND_RTF_INT ( "ftnndbnumk", oDocument.m_oProperty.m_nFootnoteNumberingFormat, sCommand, true, 17 ) + COMMAND_RTF_INT ( "ftnndbar", oDocument.m_oProperty.m_nFootnoteNumberingFormat, sCommand, true, 20 ) + COMMAND_RTF_INT ( "ftnnganada", oDocument.m_oProperty.m_nFootnoteNumberingFormat, sCommand, true, 24 ) + COMMAND_RTF_INT ( "ftnngbnum", oDocument.m_oProperty.m_nFootnoteNumberingFormat, sCommand, true, 26 ) + COMMAND_RTF_INT ( "ftnngbnumd", oDocument.m_oProperty.m_nFootnoteNumberingFormat, sCommand, true, 27 ) + COMMAND_RTF_INT ( "ftnngbnuml", oDocument.m_oProperty.m_nFootnoteNumberingFormat, sCommand, true, 28 ) + COMMAND_RTF_INT ( "ftnngbnumk", oDocument.m_oProperty.m_nFootnoteNumberingFormat, sCommand, true, 29 ) + COMMAND_RTF_INT ( "ftnnzodiac", oDocument.m_oProperty.m_nFootnoteNumberingFormat, sCommand, true, 30 ) + COMMAND_RTF_INT ( "ftnnzodiacd", oDocument.m_oProperty.m_nFootnoteNumberingFormat, sCommand, true, 31 ) + COMMAND_RTF_INT ( "ftnnzodiacl", oDocument.m_oProperty.m_nFootnoteNumberingFormat, sCommand, true, 32 ) + + COMMAND_RTF_INT ( "aftnnar", oDocument.m_oProperty.m_nFootnoteNumberingFormat, sCommand, true, 0 ) + COMMAND_RTF_INT ( "aftnnalc", oDocument.m_oProperty.m_nFootnoteNumberingFormat, sCommand, true, 4 ) + COMMAND_RTF_INT ( "aftnnauc", oDocument.m_oProperty.m_nFootnoteNumberingFormat, sCommand, true, 3 ) + COMMAND_RTF_INT ( "aftnnrlc", oDocument.m_oProperty.m_nFootnoteNumberingFormat, sCommand, true, 2 ) + COMMAND_RTF_INT ( "aftnnruc", oDocument.m_oProperty.m_nFootnoteNumberingFormat, sCommand, true, 1 ) + COMMAND_RTF_INT ( "aftnnchi", oDocument.m_oProperty.m_nFootnoteNumberingFormat, sCommand, true, 70 ) + COMMAND_RTF_INT ( "aftnnchi", oDocument.m_oProperty.m_nFootnoteNumberingFormat, sCommand, true, 25 ) + COMMAND_RTF_INT ( "aftnncnum", oDocument.m_oProperty.m_nFootnoteNumberingFormat, sCommand, true, 18 ) + COMMAND_RTF_INT ( "aftnndbnum", oDocument.m_oProperty.m_nFootnoteNumberingFormat, sCommand, true, 10 ) + COMMAND_RTF_INT ( "aftnndbnumd", oDocument.m_oProperty.m_nFootnoteNumberingFormat, sCommand, true, 11 ) + COMMAND_RTF_INT ( "aftnndbnumt", oDocument.m_oProperty.m_nFootnoteNumberingFormat, sCommand, true, 16 ) + COMMAND_RTF_INT ( "aftnndbnumk", oDocument.m_oProperty.m_nFootnoteNumberingFormat, sCommand, true, 17 ) + COMMAND_RTF_INT ( "aftnndbar", oDocument.m_oProperty.m_nFootnoteNumberingFormat, sCommand, true, 20 ) + COMMAND_RTF_INT ( "aftnnganada", oDocument.m_oProperty.m_nFootnoteNumberingFormat, sCommand, true, 24 ) + COMMAND_RTF_INT ( "aftnngbnum", oDocument.m_oProperty.m_nFootnoteNumberingFormat, sCommand, true, 26 ) + COMMAND_RTF_INT ( "aftnngbnumd", oDocument.m_oProperty.m_nFootnoteNumberingFormat, sCommand, true, 27 ) + COMMAND_RTF_INT ( "aftnngbnuml", oDocument.m_oProperty.m_nFootnoteNumberingFormat, sCommand, true, 28 ) + COMMAND_RTF_INT ( "aftnngbnumk", oDocument.m_oProperty.m_nFootnoteNumberingFormat, sCommand, true, 29 ) + COMMAND_RTF_INT ( "aftnnzodiac", oDocument.m_oProperty.m_nFootnoteNumberingFormat, sCommand, true, 30 ) + COMMAND_RTF_INT ( "aftnnzodiacd", oDocument.m_oProperty.m_nFootnoteNumberingFormat, sCommand, true, 31 ) + COMMAND_RTF_INT ( "aftnnzodiacl", oDocument.m_oProperty.m_nFootnoteNumberingFormat, sCommand, true, 32 ) else return false; return true; @@ -786,16 +787,16 @@ bool RtfSectionCommand::ExecuteCommand(RtfDocument& oDocument, RtfReader& oReade if ( "11111111" == sCommand ) ; COMMAND_RTF_BOOL( "rtlsect", oReader.m_oCurSectionProp.m_bBidi, sCommand, hasParameter, parameter) - COMMAND_RTF_INT ( "binfsxn", oReader.m_oCurSectionProp.m_nPaperSourceFirst, sCommand, hasParameter, parameter) - COMMAND_RTF_INT ( "binsxn", oReader.m_oCurSectionProp.m_nPaperSourceOther, sCommand, hasParameter, parameter) - COMMAND_RTF_BOOL( "rtlgutter", oReader.m_oCurSectionProp.m_bRtlGutter, sCommand, hasParameter, parameter) - COMMAND_RTF_BOOL( "endnhere", oReader.m_oCurSectionProp.m_bEndnotes, sCommand, hasParameter, parameter) - COMMAND_RTF_INT ( "ds", oReader.m_oCurSectionProp.m_nStyle, sCommand, hasParameter, parameter) - COMMAND_RTF_INT ( "sbknone", oReader.m_oCurSectionProp.m_eSectionBreak, sCommand, true, RtfSectionProperty::sb_sbknone) - COMMAND_RTF_INT ( "sbkcol", oReader.m_oCurSectionProp.m_eSectionBreak, sCommand, true, RtfSectionProperty::sb_sbkcol) - COMMAND_RTF_INT ( "sbkpage", oReader.m_oCurSectionProp.m_eSectionBreak, sCommand, true, RtfSectionProperty::sb_sbkpage) - COMMAND_RTF_INT ( "sbkeven", oReader.m_oCurSectionProp.m_eSectionBreak, sCommand, true, RtfSectionProperty::sb_sbkeven) - COMMAND_RTF_INT ( "sbkodd", oReader.m_oCurSectionProp.m_eSectionBreak, sCommand, true, RtfSectionProperty::sb_sbkodd) + COMMAND_RTF_INT ( "binfsxn", oReader.m_oCurSectionProp.m_nPaperSourceFirst, sCommand, hasParameter, parameter) + COMMAND_RTF_INT ( "binsxn", oReader.m_oCurSectionProp.m_nPaperSourceOther, sCommand, hasParameter, parameter) + COMMAND_RTF_BOOL( "rtlgutter", oReader.m_oCurSectionProp.m_bRtlGutter, sCommand, hasParameter, parameter) + COMMAND_RTF_BOOL( "endnhere", oReader.m_oCurSectionProp.m_bEndnotes, sCommand, hasParameter, parameter) + COMMAND_RTF_INT ( "ds", oReader.m_oCurSectionProp.m_nStyle, sCommand, hasParameter, parameter) + COMMAND_RTF_INT ( "sbknone", oReader.m_oCurSectionProp.m_eSectionBreak, sCommand, true, RtfSectionProperty::sb_sbknone) + COMMAND_RTF_INT ( "sbkcol", oReader.m_oCurSectionProp.m_eSectionBreak, sCommand, true, RtfSectionProperty::sb_sbkcol) + COMMAND_RTF_INT ( "sbkpage", oReader.m_oCurSectionProp.m_eSectionBreak, sCommand, true, RtfSectionProperty::sb_sbkpage) + COMMAND_RTF_INT ( "sbkeven", oReader.m_oCurSectionProp.m_eSectionBreak, sCommand, true, RtfSectionProperty::sb_sbkeven) + COMMAND_RTF_INT ( "sbkodd", oReader.m_oCurSectionProp.m_eSectionBreak, sCommand, true, RtfSectionProperty::sb_sbkodd) else if ( "cols" == sCommand ) { if ( hasParameter ) @@ -823,99 +824,99 @@ bool RtfSectionCommand::ExecuteCommand(RtfDocument& oDocument, RtfReader& oReade oReader.m_oCurSectionProp.m_oCollumnProperty.m_aCollumnProperty[ nCurCollumnNumber ].m_nColumnWidth = parameter; } COMMAND_RTF_BOOL( "linebetcol", oReader.m_oCurSectionProp.m_bColumnLineBetween, sCommand, hasParameter, parameter) - COMMAND_RTF_INT ( "sftntj", oReader.m_oCurSectionProp.m_eFootnotesJust, sCommand, true, RtfSectionProperty::fj_sftntj) - COMMAND_RTF_INT ( "sftnbj", oReader.m_oCurSectionProp.m_eFootnotesJust, sCommand, true, RtfSectionProperty::fj_sftnbj) + COMMAND_RTF_INT ( "sftntj", oReader.m_oCurSectionProp.m_eFootnotesJust, sCommand, true, RtfSectionProperty::fj_sftntj) + COMMAND_RTF_INT ( "sftnbj", oReader.m_oCurSectionProp.m_eFootnotesJust, sCommand, true, RtfSectionProperty::fj_sftnbj) //Footnotes and Endnotes - COMMAND_RTF_INT ( "sftnstart", oReader.m_oCurSectionProp.m_nFootnotesStart, sCommand, hasParameter, parameter) - COMMAND_RTF_INT ( "sftnrstpg", oReader.m_oCurSectionProp.m_eFootnotesRestart, sCommand, true, RtfSectionProperty::fr_sftnrstpg) - COMMAND_RTF_INT ( "sftnrestart", oReader.m_oCurSectionProp.m_eFootnotesRestart, sCommand, true, RtfSectionProperty::fr_sftnrestart) - COMMAND_RTF_INT ( "sftnrstcont", oReader.m_oCurSectionProp.m_eFootnotesRestart, sCommand, true, RtfSectionProperty::fr_sftnrstcont) - COMMAND_RTF_INT ( "sftnnar", oReader.m_oCurSectionProp.m_eFootnotesFormat, sCommand, true, RtfSectionProperty::ff_sftnnar) - COMMAND_RTF_INT ( "sftnnalc", oReader.m_oCurSectionProp.m_eFootnotesFormat, sCommand, true, RtfSectionProperty::ff_sftnnalc) - COMMAND_RTF_INT ( "sftnnauc", oReader.m_oCurSectionProp.m_eFootnotesFormat, sCommand, true, RtfSectionProperty::ff_sftnnauc) - COMMAND_RTF_INT ( "sftnnrlc", oReader.m_oCurSectionProp.m_eFootnotesFormat, sCommand, true, RtfSectionProperty::ff_sftnnrlc) - COMMAND_RTF_INT ( "sftnnruc", oReader.m_oCurSectionProp.m_eFootnotesFormat, sCommand, true, RtfSectionProperty::ff_sftnnruc) - COMMAND_RTF_INT ( "sftnnchi", oReader.m_oCurSectionProp.m_eFootnotesFormat, sCommand, true, RtfSectionProperty::ff_sftnnchi) - COMMAND_RTF_INT ( "sftnnchosung", oReader.m_oCurSectionProp.m_eFootnotesFormat, sCommand, true, RtfSectionProperty::ff_sftnnchosung) - COMMAND_RTF_INT ( "sftnncnum", oReader.m_oCurSectionProp.m_eFootnotesFormat, sCommand, true, RtfSectionProperty::ff_sftnncnum) - COMMAND_RTF_INT ( "sftnndbnum", oReader.m_oCurSectionProp.m_eFootnotesFormat, sCommand, true, RtfSectionProperty::ff_sftnndbnum) - COMMAND_RTF_INT ( "sftnndbnumd", oReader.m_oCurSectionProp.m_eFootnotesFormat, sCommand, true, RtfSectionProperty::ff_sftnndbnumd) - COMMAND_RTF_INT ( "sftnndbnumt", oReader.m_oCurSectionProp.m_eFootnotesFormat, sCommand, true, RtfSectionProperty::ff_sftnndbnumt) - COMMAND_RTF_INT ( "sftnndbnumk", oReader.m_oCurSectionProp.m_eFootnotesFormat, sCommand, true, RtfSectionProperty::ff_sftnndbnumk) - COMMAND_RTF_INT ( "sftnndbar", oReader.m_oCurSectionProp.m_eFootnotesFormat, sCommand, true, RtfSectionProperty::ff_sftnndbar) - COMMAND_RTF_INT ( "sftnnganada", oReader.m_oCurSectionProp.m_eFootnotesFormat, sCommand, true, RtfSectionProperty::ff_sftnnganada) - COMMAND_RTF_INT ( "sftnngbnum", oReader.m_oCurSectionProp.m_eFootnotesFormat, sCommand, true, RtfSectionProperty::ff_sftnngbnum) - COMMAND_RTF_INT ( "sftnngbnumd", oReader.m_oCurSectionProp.m_eFootnotesFormat, sCommand, true, RtfSectionProperty::ff_sftnngbnumd) - COMMAND_RTF_INT ( "sftnngbnuml", oReader.m_oCurSectionProp.m_eFootnotesFormat, sCommand, true, RtfSectionProperty::ff_sftnngbnuml) - COMMAND_RTF_INT ( "sftnngbnumk", oReader.m_oCurSectionProp.m_eFootnotesFormat, sCommand, true, RtfSectionProperty::ff_sftnngbnumk) - COMMAND_RTF_INT ( "sftnnzodiac", oReader.m_oCurSectionProp.m_eFootnotesFormat, sCommand, true, RtfSectionProperty::ff_sftnnzodiac) - COMMAND_RTF_INT ( "sftnnzodiacd", oReader.m_oCurSectionProp.m_eFootnotesFormat, sCommand, true, RtfSectionProperty::ff_sftnnzodiacd) - COMMAND_RTF_INT ( "sftnnzodiacl", oReader.m_oCurSectionProp.m_eFootnotesFormat, sCommand, true, RtfSectionProperty::ff_sftnnzodiacl) - - COMMAND_RTF_INT ( "saftnstart", oReader.m_oCurSectionProp.m_nEndnotesStart, sCommand, hasParameter, parameter) - COMMAND_RTF_INT ( "saftnrestart", oReader.m_oCurSectionProp.m_eEndnotesRestart, sCommand, true, RtfSectionProperty::er_saftnrestart) - COMMAND_RTF_INT ( "saftnrstcont", oReader.m_oCurSectionProp.m_eEndnotesRestart, sCommand, true, RtfSectionProperty::er_saftnrstcont) - COMMAND_RTF_INT ( "saftnnar", oReader.m_oCurSectionProp.m_eEndnotesFormat, sCommand, true, RtfSectionProperty::ef_saftnnar) - COMMAND_RTF_INT ( "saftnnalc", oReader.m_oCurSectionProp.m_eEndnotesFormat, sCommand, true, RtfSectionProperty::ef_saftnnalc) - COMMAND_RTF_INT ( "saftnnauc", oReader.m_oCurSectionProp.m_eEndnotesFormat, sCommand, true, RtfSectionProperty::ef_saftnnauc) - COMMAND_RTF_INT ( "saftnnrlc", oReader.m_oCurSectionProp.m_eEndnotesFormat, sCommand, true, RtfSectionProperty::ef_saftnnrlc) - COMMAND_RTF_INT ( "saftnnruc", oReader.m_oCurSectionProp.m_eEndnotesFormat, sCommand, true, RtfSectionProperty::ef_saftnnruc) - COMMAND_RTF_INT ( "saftnnchi", oReader.m_oCurSectionProp.m_eEndnotesFormat, sCommand, true, RtfSectionProperty::ef_saftnnchi) - COMMAND_RTF_INT ( "saftnnchosung", oReader.m_oCurSectionProp.m_eEndnotesFormat, sCommand, true, RtfSectionProperty::ef_saftnnchosung) - COMMAND_RTF_INT ( "saftnncnum", oReader.m_oCurSectionProp.m_eEndnotesFormat, sCommand, true, RtfSectionProperty::ef_saftnncnum) - COMMAND_RTF_INT ( "saftnndbnum", oReader.m_oCurSectionProp.m_eEndnotesFormat, sCommand, true, RtfSectionProperty::ef_saftnndbnum) - COMMAND_RTF_INT ( "saftnndbnumd", oReader.m_oCurSectionProp.m_eEndnotesFormat, sCommand, true, RtfSectionProperty::ef_saftnndbnumd) - COMMAND_RTF_INT ( "saftnndbnumt", oReader.m_oCurSectionProp.m_eEndnotesFormat, sCommand, true, RtfSectionProperty::ef_saftnndbnumt) - COMMAND_RTF_INT ( "saftnndbnumk", oReader.m_oCurSectionProp.m_eEndnotesFormat, sCommand, true, RtfSectionProperty::ef_saftnndbnumk) - COMMAND_RTF_INT ( "saftnndbar", oReader.m_oCurSectionProp.m_eEndnotesFormat, sCommand, true, RtfSectionProperty::ef_saftnndbar) - COMMAND_RTF_INT ( "saftnnganada", oReader.m_oCurSectionProp.m_eEndnotesFormat, sCommand, true, RtfSectionProperty::ef_saftnnganada) - COMMAND_RTF_INT ( "saftnngbnum", oReader.m_oCurSectionProp.m_eEndnotesFormat, sCommand, true, RtfSectionProperty::ef_saftnngbnum) - COMMAND_RTF_INT ( "saftnngbnumd", oReader.m_oCurSectionProp.m_eEndnotesFormat, sCommand, true, RtfSectionProperty::ef_saftnngbnumd) - COMMAND_RTF_INT ( "saftnngbnuml", oReader.m_oCurSectionProp.m_eEndnotesFormat, sCommand, true, RtfSectionProperty::ef_saftnngbnuml) - COMMAND_RTF_INT ( "saftnngbnumk", oReader.m_oCurSectionProp.m_eEndnotesFormat, sCommand, true, RtfSectionProperty::ef_saftnngbnumk) - COMMAND_RTF_INT ( "saftnnzodiac", oReader.m_oCurSectionProp.m_eEndnotesFormat, sCommand, true, RtfSectionProperty::ef_saftnnzodiac) - COMMAND_RTF_INT ( "saftnnzodiacd", oReader.m_oCurSectionProp.m_eEndnotesFormat, sCommand, true, RtfSectionProperty::ef_saftnnzodiacd) - COMMAND_RTF_INT ( "saftnnzodiacl", oReader.m_oCurSectionProp.m_eEndnotesFormat, sCommand, true, RtfSectionProperty::ef_saftnnzodiacl) + COMMAND_RTF_INT ( "sftnstart", oReader.m_oCurSectionProp.m_nFootnotesStart, sCommand, hasParameter, parameter) + COMMAND_RTF_INT ( "sftnrstpg", oReader.m_oCurSectionProp.m_eFootnotesRestart, sCommand, true, RtfSectionProperty::fr_sftnrstpg) + COMMAND_RTF_INT ( "sftnrestart", oReader.m_oCurSectionProp.m_eFootnotesRestart, sCommand, true, RtfSectionProperty::fr_sftnrestart) + COMMAND_RTF_INT ( "sftnrstcont", oReader.m_oCurSectionProp.m_eFootnotesRestart, sCommand, true, RtfSectionProperty::fr_sftnrstcont) + COMMAND_RTF_INT ( "sftnnar", oReader.m_oCurSectionProp.m_eFootnotesFormat, sCommand, true, RtfSectionProperty::ff_sftnnar) + COMMAND_RTF_INT ( "sftnnalc", oReader.m_oCurSectionProp.m_eFootnotesFormat, sCommand, true, RtfSectionProperty::ff_sftnnalc) + COMMAND_RTF_INT ( "sftnnauc", oReader.m_oCurSectionProp.m_eFootnotesFormat, sCommand, true, RtfSectionProperty::ff_sftnnauc) + COMMAND_RTF_INT ( "sftnnrlc", oReader.m_oCurSectionProp.m_eFootnotesFormat, sCommand, true, RtfSectionProperty::ff_sftnnrlc) + COMMAND_RTF_INT ( "sftnnruc", oReader.m_oCurSectionProp.m_eFootnotesFormat, sCommand, true, RtfSectionProperty::ff_sftnnruc) + COMMAND_RTF_INT ( "sftnnchi", oReader.m_oCurSectionProp.m_eFootnotesFormat, sCommand, true, RtfSectionProperty::ff_sftnnchi) + COMMAND_RTF_INT ( "sftnnchosung", oReader.m_oCurSectionProp.m_eFootnotesFormat, sCommand, true, RtfSectionProperty::ff_sftnnchosung) + COMMAND_RTF_INT ( "sftnncnum", oReader.m_oCurSectionProp.m_eFootnotesFormat, sCommand, true, RtfSectionProperty::ff_sftnncnum) + COMMAND_RTF_INT ( "sftnndbnum", oReader.m_oCurSectionProp.m_eFootnotesFormat, sCommand, true, RtfSectionProperty::ff_sftnndbnum) + COMMAND_RTF_INT ( "sftnndbnumd", oReader.m_oCurSectionProp.m_eFootnotesFormat, sCommand, true, RtfSectionProperty::ff_sftnndbnumd) + COMMAND_RTF_INT ( "sftnndbnumt", oReader.m_oCurSectionProp.m_eFootnotesFormat, sCommand, true, RtfSectionProperty::ff_sftnndbnumt) + COMMAND_RTF_INT ( "sftnndbnumk", oReader.m_oCurSectionProp.m_eFootnotesFormat, sCommand, true, RtfSectionProperty::ff_sftnndbnumk) + COMMAND_RTF_INT ( "sftnndbar", oReader.m_oCurSectionProp.m_eFootnotesFormat, sCommand, true, RtfSectionProperty::ff_sftnndbar) + COMMAND_RTF_INT ( "sftnnganada", oReader.m_oCurSectionProp.m_eFootnotesFormat, sCommand, true, RtfSectionProperty::ff_sftnnganada) + COMMAND_RTF_INT ( "sftnngbnum", oReader.m_oCurSectionProp.m_eFootnotesFormat, sCommand, true, RtfSectionProperty::ff_sftnngbnum) + COMMAND_RTF_INT ( "sftnngbnumd", oReader.m_oCurSectionProp.m_eFootnotesFormat, sCommand, true, RtfSectionProperty::ff_sftnngbnumd) + COMMAND_RTF_INT ( "sftnngbnuml", oReader.m_oCurSectionProp.m_eFootnotesFormat, sCommand, true, RtfSectionProperty::ff_sftnngbnuml) + COMMAND_RTF_INT ( "sftnngbnumk", oReader.m_oCurSectionProp.m_eFootnotesFormat, sCommand, true, RtfSectionProperty::ff_sftnngbnumk) + COMMAND_RTF_INT ( "sftnnzodiac", oReader.m_oCurSectionProp.m_eFootnotesFormat, sCommand, true, RtfSectionProperty::ff_sftnnzodiac) + COMMAND_RTF_INT ( "sftnnzodiacd", oReader.m_oCurSectionProp.m_eFootnotesFormat, sCommand, true, RtfSectionProperty::ff_sftnnzodiacd) + COMMAND_RTF_INT ( "sftnnzodiacl", oReader.m_oCurSectionProp.m_eFootnotesFormat, sCommand, true, RtfSectionProperty::ff_sftnnzodiacl) + + COMMAND_RTF_INT ( "saftnstart", oReader.m_oCurSectionProp.m_nEndnotesStart, sCommand, hasParameter, parameter) + COMMAND_RTF_INT ( "saftnrestart", oReader.m_oCurSectionProp.m_eEndnotesRestart, sCommand, true, RtfSectionProperty::er_saftnrestart) + COMMAND_RTF_INT ( "saftnrstcont", oReader.m_oCurSectionProp.m_eEndnotesRestart, sCommand, true, RtfSectionProperty::er_saftnrstcont) + COMMAND_RTF_INT ( "saftnnar", oReader.m_oCurSectionProp.m_eEndnotesFormat, sCommand, true, RtfSectionProperty::ef_saftnnar) + COMMAND_RTF_INT ( "saftnnalc", oReader.m_oCurSectionProp.m_eEndnotesFormat, sCommand, true, RtfSectionProperty::ef_saftnnalc) + COMMAND_RTF_INT ( "saftnnauc", oReader.m_oCurSectionProp.m_eEndnotesFormat, sCommand, true, RtfSectionProperty::ef_saftnnauc) + COMMAND_RTF_INT ( "saftnnrlc", oReader.m_oCurSectionProp.m_eEndnotesFormat, sCommand, true, RtfSectionProperty::ef_saftnnrlc) + COMMAND_RTF_INT ( "saftnnruc", oReader.m_oCurSectionProp.m_eEndnotesFormat, sCommand, true, RtfSectionProperty::ef_saftnnruc) + COMMAND_RTF_INT ( "saftnnchi", oReader.m_oCurSectionProp.m_eEndnotesFormat, sCommand, true, RtfSectionProperty::ef_saftnnchi) + COMMAND_RTF_INT ( "saftnnchosung", oReader.m_oCurSectionProp.m_eEndnotesFormat, sCommand, true, RtfSectionProperty::ef_saftnnchosung) + COMMAND_RTF_INT ( "saftnncnum", oReader.m_oCurSectionProp.m_eEndnotesFormat, sCommand, true, RtfSectionProperty::ef_saftnncnum) + COMMAND_RTF_INT ( "saftnndbnum", oReader.m_oCurSectionProp.m_eEndnotesFormat, sCommand, true, RtfSectionProperty::ef_saftnndbnum) + COMMAND_RTF_INT ( "saftnndbnumd", oReader.m_oCurSectionProp.m_eEndnotesFormat, sCommand, true, RtfSectionProperty::ef_saftnndbnumd) + COMMAND_RTF_INT ( "saftnndbnumt", oReader.m_oCurSectionProp.m_eEndnotesFormat, sCommand, true, RtfSectionProperty::ef_saftnndbnumt) + COMMAND_RTF_INT ( "saftnndbnumk", oReader.m_oCurSectionProp.m_eEndnotesFormat, sCommand, true, RtfSectionProperty::ef_saftnndbnumk) + COMMAND_RTF_INT ( "saftnndbar", oReader.m_oCurSectionProp.m_eEndnotesFormat, sCommand, true, RtfSectionProperty::ef_saftnndbar) + COMMAND_RTF_INT ( "saftnnganada", oReader.m_oCurSectionProp.m_eEndnotesFormat, sCommand, true, RtfSectionProperty::ef_saftnnganada) + COMMAND_RTF_INT ( "saftnngbnum", oReader.m_oCurSectionProp.m_eEndnotesFormat, sCommand, true, RtfSectionProperty::ef_saftnngbnum) + COMMAND_RTF_INT ( "saftnngbnumd", oReader.m_oCurSectionProp.m_eEndnotesFormat, sCommand, true, RtfSectionProperty::ef_saftnngbnumd) + COMMAND_RTF_INT ( "saftnngbnuml", oReader.m_oCurSectionProp.m_eEndnotesFormat, sCommand, true, RtfSectionProperty::ef_saftnngbnuml) + COMMAND_RTF_INT ( "saftnngbnumk", oReader.m_oCurSectionProp.m_eEndnotesFormat, sCommand, true, RtfSectionProperty::ef_saftnngbnumk) + COMMAND_RTF_INT ( "saftnnzodiac", oReader.m_oCurSectionProp.m_eEndnotesFormat, sCommand, true, RtfSectionProperty::ef_saftnnzodiac) + COMMAND_RTF_INT ( "saftnnzodiacd", oReader.m_oCurSectionProp.m_eEndnotesFormat, sCommand, true, RtfSectionProperty::ef_saftnnzodiacd) + COMMAND_RTF_INT ( "saftnnzodiacl", oReader.m_oCurSectionProp.m_eEndnotesFormat, sCommand, true, RtfSectionProperty::ef_saftnnzodiacl) //Line Numbering - COMMAND_RTF_INT ( "linemod", oReader.m_oCurSectionProp.m_nLineModulus, sCommand, hasParameter, parameter) - COMMAND_RTF_INT ( "linex", oReader.m_oCurSectionProp.m_nLineX, sCommand, hasParameter, parameter) - COMMAND_RTF_INT ( "linestarts", oReader.m_oCurSectionProp.m_nLineStart, sCommand, hasParameter, parameter) - COMMAND_RTF_INT ( "linerestart", oReader.m_oCurSectionProp.m_eLineNumberRestart, sCommand, true, RtfSectionProperty::lnr_linerestart) - COMMAND_RTF_INT ( "lineppage", oReader.m_oCurSectionProp.m_eLineNumberRestart, sCommand, true, RtfSectionProperty::lnr_lineppage) - COMMAND_RTF_INT ( "linecont", oReader.m_oCurSectionProp.m_eLineNumberRestart, sCommand, true, RtfSectionProperty::lnr_linecont) + COMMAND_RTF_INT ( "linemod", oReader.m_oCurSectionProp.m_nLineModulus, sCommand, hasParameter, parameter) + COMMAND_RTF_INT ( "linex", oReader.m_oCurSectionProp.m_nLineX, sCommand, hasParameter, parameter) + COMMAND_RTF_INT ( "linestarts", oReader.m_oCurSectionProp.m_nLineStart, sCommand, hasParameter, parameter) + COMMAND_RTF_INT ( "linerestart", oReader.m_oCurSectionProp.m_eLineNumberRestart, sCommand, true, RtfSectionProperty::lnr_linerestart) + COMMAND_RTF_INT ( "lineppage", oReader.m_oCurSectionProp.m_eLineNumberRestart, sCommand, true, RtfSectionProperty::lnr_lineppage) + COMMAND_RTF_INT ( "linecont", oReader.m_oCurSectionProp.m_eLineNumberRestart, sCommand, true, RtfSectionProperty::lnr_linecont) //Page Information - COMMAND_RTF_INT ( "pgwsxn", oReader.m_oCurSectionProp.m_nPageWidth, sCommand, hasParameter, parameter) - COMMAND_RTF_INT ( "pghsxn", oReader.m_oCurSectionProp.m_nPageHeight, sCommand, hasParameter, parameter) - COMMAND_RTF_INT ( "marglsxn", oReader.m_oCurSectionProp.m_nMarginLeft, sCommand, hasParameter, parameter) - COMMAND_RTF_INT ( "margrsxn", oReader.m_oCurSectionProp.m_nMarginRight, sCommand, hasParameter, parameter) - COMMAND_RTF_INT ( "margtsxn", oReader.m_oCurSectionProp.m_nMarginTop, sCommand, hasParameter, parameter) - COMMAND_RTF_INT ( "margbsxn", oReader.m_oCurSectionProp.m_nMarginBottom, sCommand, hasParameter, parameter) - COMMAND_RTF_INT ( "guttersxn", oReader.m_oCurSectionProp.m_nGutterMarginWidth, sCommand, hasParameter, parameter) - COMMAND_RTF_BOOL( "margmirsxn", oReader.m_oCurSectionProp.m_bSwitchMargin, sCommand, hasParameter, parameter) - COMMAND_RTF_BOOL( "lndscpsxn", oReader.m_oCurSectionProp.m_bLandscapeFormat, sCommand, hasParameter, parameter) - COMMAND_RTF_BOOL( "titlepg", oReader.m_oCurSectionProp.m_bTitlePage, sCommand, hasParameter, parameter) + COMMAND_RTF_INT ( "pgwsxn", oReader.m_oCurSectionProp.m_nPageWidth, sCommand, hasParameter, parameter) + COMMAND_RTF_INT ( "pghsxn", oReader.m_oCurSectionProp.m_nPageHeight, sCommand, hasParameter, parameter) + COMMAND_RTF_INT ( "marglsxn", oReader.m_oCurSectionProp.m_nMarginLeft, sCommand, hasParameter, parameter) + COMMAND_RTF_INT ( "margrsxn", oReader.m_oCurSectionProp.m_nMarginRight, sCommand, hasParameter, parameter) + COMMAND_RTF_INT ( "margtsxn", oReader.m_oCurSectionProp.m_nMarginTop, sCommand, hasParameter, parameter) + COMMAND_RTF_INT ( "margbsxn", oReader.m_oCurSectionProp.m_nMarginBottom, sCommand, hasParameter, parameter) + COMMAND_RTF_INT ( "guttersxn", oReader.m_oCurSectionProp.m_nGutterMarginWidth, sCommand, hasParameter, parameter) + COMMAND_RTF_BOOL( "margmirsxn", oReader.m_oCurSectionProp.m_bSwitchMargin, sCommand, hasParameter, parameter) + COMMAND_RTF_BOOL( "lndscpsxn", oReader.m_oCurSectionProp.m_bLandscapeFormat, sCommand, hasParameter, parameter) + COMMAND_RTF_BOOL( "titlepg", oReader.m_oCurSectionProp.m_bTitlePage, sCommand, hasParameter, parameter) //else if ( "headery" == sCommand ) //{ // static int nCount = 0; // nCount++; //} - COMMAND_RTF_INT ( "headery", oReader.m_oCurSectionProp.m_nHeaderTop, sCommand, hasParameter, parameter) - COMMAND_RTF_INT ( "footery", oReader.m_oCurSectionProp.m_nFooterBottom, sCommand, hasParameter, parameter) + COMMAND_RTF_INT ( "headery", oReader.m_oCurSectionProp.m_nHeaderTop, sCommand, hasParameter, parameter) + COMMAND_RTF_INT ( "footery", oReader.m_oCurSectionProp.m_nFooterBottom, sCommand, hasParameter, parameter) //Page Numbers - COMMAND_RTF_INT ( "pgnstarts", oReader.m_oCurSectionProp.m_nPageNumberStart, sCommand, hasParameter, parameter) - COMMAND_RTF_BOOL( "pgncont", oReader.m_oCurSectionProp.m_bPageNumberContinuos, sCommand, hasParameter, parameter) - COMMAND_RTF_BOOL( "pgnrestart", oReader.m_oCurSectionProp.m_bPageNumberRestart, sCommand, hasParameter, parameter) - COMMAND_RTF_INT ( "pgnx", oReader.m_oCurSectionProp.m_nPageNumberX, sCommand, hasParameter, parameter) - COMMAND_RTF_INT ( "pgny", oReader.m_oCurSectionProp.m_nPageNumberY, sCommand, hasParameter, parameter) - COMMAND_RTF_INT ( "pgndec", oReader.m_oCurSectionProp.m_ePageNumberFormat, sCommand, true, RtfSectionProperty::pnf_pgndec) - COMMAND_RTF_INT ( "pgnucrm", oReader.m_oCurSectionProp.m_ePageNumberFormat, sCommand, true, RtfSectionProperty::pnf_pgnucrm) - COMMAND_RTF_INT ( "pgnlcrm", oReader.m_oCurSectionProp.m_ePageNumberFormat, sCommand, true, RtfSectionProperty::pnf_pgnlcrm) - COMMAND_RTF_INT ( "vertalt", oReader.m_oCurSectionProp.m_eVerticalAlignment, sCommand, true, RtfSectionProperty::va_vertalt) - COMMAND_RTF_INT ( "vertalb", oReader.m_oCurSectionProp.m_eVerticalAlignment, sCommand, true, RtfSectionProperty::va_vertalb) - COMMAND_RTF_INT ( "vertalc", oReader.m_oCurSectionProp.m_eVerticalAlignment, sCommand, true, RtfSectionProperty::va_vertalc) - COMMAND_RTF_INT ( "vertalj", oReader.m_oCurSectionProp.m_eVerticalAlignment, sCommand, true, RtfSectionProperty::va_vertalj) + COMMAND_RTF_INT ( "pgnstarts", oReader.m_oCurSectionProp.m_nPageNumberStart, sCommand, hasParameter, parameter) + COMMAND_RTF_BOOL( "pgncont", oReader.m_oCurSectionProp.m_bPageNumberContinuos, sCommand, hasParameter, parameter) + COMMAND_RTF_BOOL( "pgnrestart", oReader.m_oCurSectionProp.m_bPageNumberRestart, sCommand, hasParameter, parameter) + COMMAND_RTF_INT ( "pgnx", oReader.m_oCurSectionProp.m_nPageNumberX, sCommand, hasParameter, parameter) + COMMAND_RTF_INT ( "pgny", oReader.m_oCurSectionProp.m_nPageNumberY, sCommand, hasParameter, parameter) + COMMAND_RTF_INT ( "pgndec", oReader.m_oCurSectionProp.m_ePageNumberFormat, sCommand, true, RtfSectionProperty::pnf_pgndec) + COMMAND_RTF_INT ( "pgnucrm", oReader.m_oCurSectionProp.m_ePageNumberFormat, sCommand, true, RtfSectionProperty::pnf_pgnucrm) + COMMAND_RTF_INT ( "pgnlcrm", oReader.m_oCurSectionProp.m_ePageNumberFormat, sCommand, true, RtfSectionProperty::pnf_pgnlcrm) + COMMAND_RTF_INT ( "vertalt", oReader.m_oCurSectionProp.m_eVerticalAlignment, sCommand, true, RtfSectionProperty::va_vertalt) + COMMAND_RTF_INT ( "vertalb", oReader.m_oCurSectionProp.m_eVerticalAlignment, sCommand, true, RtfSectionProperty::va_vertalb) + COMMAND_RTF_INT ( "vertalc", oReader.m_oCurSectionProp.m_eVerticalAlignment, sCommand, true, RtfSectionProperty::va_vertalc) + COMMAND_RTF_INT ( "vertalj", oReader.m_oCurSectionProp.m_eVerticalAlignment, sCommand, true, RtfSectionProperty::va_vertalj) //Text Flow - COMMAND_RTF_INT ( "stextflow", oReader.m_oCurSectionProp.m_nTextFollow, sCommand, hasParameter, parameter) + COMMAND_RTF_INT ( "stextflow", oReader.m_oCurSectionProp.m_nTextFollow, sCommand, hasParameter, parameter) //Page Borders else if ( "pgbrdrl" == sCommand ) m_eInternalState = is_border_left; @@ -924,11 +925,11 @@ bool RtfSectionCommand::ExecuteCommand(RtfDocument& oDocument, RtfReader& oReade else if ( "pgbrdrb" == sCommand ) m_eInternalState = is_border_bottom; COMMAND_RTF_INT ( "brdrart", oReader.m_oCurSectionProp.m_nBorderArt, sCommand, hasParameter, parameter) - COMMAND_RTF_INT ( "pgbrdropt", oReader.m_oCurSectionProp.m_nBorderMeasure, sCommand, hasParameter, parameter) - COMMAND_RTF_BOOL( "pgbrdrsna", oReader.m_oCurSectionProp.m_nBorderAlign, sCommand, hasParameter, parameter) + COMMAND_RTF_INT ( "pgbrdropt", oReader.m_oCurSectionProp.m_nBorderMeasure, sCommand, hasParameter, parameter) + COMMAND_RTF_BOOL( "pgbrdrsna", oReader.m_oCurSectionProp.m_nBorderAlign, sCommand, hasParameter, parameter) - COMMAND_RTF_INT ( "srauth", oReader.m_oCurSectionProp.m_nSrAuth, sCommand, hasParameter, parameter) - COMMAND_RTF_INT ( "srdate", oReader.m_oCurSectionProp.m_nSrDate, sCommand, hasParameter, parameter) + COMMAND_RTF_INT ( "srauth", oReader.m_oCurSectionProp.m_nSrAuth, sCommand, hasParameter, parameter) + COMMAND_RTF_INT ( "srdate", oReader.m_oCurSectionProp.m_nSrDate, sCommand, hasParameter, parameter) else if ( "header" == sCommand || "footer" == sCommand || "headerl" == sCommand || "headerr" == sCommand || "headerf" == sCommand || "footerl" == sCommand || @@ -1034,15 +1035,15 @@ bool RtfShadingCellCommand::ExecuteCommand(RtfDocument& oDocument, RtfReader& oR oOutput.m_eType = RtfShading::st_chbgdkdcross; COMMAND_RTF_INT ( "clcfpat", oOutput.m_nForeColor, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "clcbpat", oOutput.m_nBackColor, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "clcfpatraw", oOutput.m_nForeColor, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "clcbpatraw", oOutput.m_nBackColor, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "tscellcfpat", oOutput.m_nForeColor, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "tscellcbpat", oOutput.m_nBackColor, sCommand, hasParameter, parameter ) - - COMMAND_RTF_INT ( "clshdng", oOutput.m_nValue, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "clshdngraw", oOutput.m_nValue, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "tscellpct", oOutput.m_nValue, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "clcbpat", oOutput.m_nBackColor, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "clcfpatraw", oOutput.m_nForeColor, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "clcbpatraw", oOutput.m_nBackColor, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "tscellcfpat", oOutput.m_nForeColor, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "tscellcbpat", oOutput.m_nBackColor, sCommand, hasParameter, parameter ) + + COMMAND_RTF_INT ( "clshdng", oOutput.m_nValue, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "clshdngraw", oOutput.m_nValue, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "tscellpct", oOutput.m_nValue, sCommand, hasParameter, parameter ) else return false; @@ -1126,30 +1127,32 @@ bool RtfCharPropsCommand::ExecuteCommand(RtfDocument& oDocument, RtfReader& oRea charProps->SetDefaultRtf(); COMMAND_RTF_INT ( "animtext" , charProps->m_nAnimated, sCommand, hasParameter, parameter) - COMMAND_RTF_BOOL( "b" , charProps->m_bBold, sCommand, hasParameter, parameter) - COMMAND_RTF_BOOL( "caps" , charProps->m_bCaps, sCommand, hasParameter, parameter) - COMMAND_RTF_INT ( "charscalex" , charProps->m_nScalex, sCommand, hasParameter, parameter) - COMMAND_RTF_INT ( "cs" , charProps->m_nCharStyle, sCommand, hasParameter, parameter) - COMMAND_RTF_INT ( "down" , charProps->m_nDown, sCommand, hasParameter, parameter) - COMMAND_RTF_BOOL( "embo" , charProps->m_bEmbo, sCommand, hasParameter, parameter) - COMMAND_RTF_INT ( "expndtw" , charProps->m_nCharacterSpacing, sCommand, hasParameter, parameter) - - else if ( "expnd" == sCommand ) + COMMAND_RTF_BOOL( "b" , charProps->m_bBold, sCommand, hasParameter, parameter) + COMMAND_RTF_BOOL( "caps" , charProps->m_bCaps, sCommand, hasParameter, parameter) + COMMAND_RTF_INT ( "charscalex" , charProps->m_nScalex, sCommand, hasParameter, parameter) + COMMAND_RTF_INT ( "cs" , charProps->m_nCharStyle, sCommand, hasParameter, parameter) + COMMAND_RTF_INT ( "down" , charProps->m_nDown, sCommand, hasParameter, parameter) + COMMAND_RTF_BOOL( "embo" , charProps->m_bEmbo, sCommand, hasParameter, parameter) + COMMAND_RTF_INT ( "expndtw" , charProps->m_nCharacterSpacing, sCommand, hasParameter, parameter) + else if ( "expnd" == sCommand ) { if ( hasParameter ) charProps->m_nCharacterSpacing = 5 * parameter; //quater -points } COMMAND_RTF_INT ( "fittext" , charProps->m_nFitText, sCommand, hasParameter, parameter) - else if ("f" == sCommand && hasParameter) + else if ("f" == sCommand && hasParameter) { charProps->m_nFont = parameter; - oReader.m_nDefFont = charProps->m_nFont; //reset + + if (false == charProps->m_bListLevel) + oReader.m_nDefFont = charProps->m_nFont; //reset } COMMAND_RTF_INT ( "fs" , charProps->m_nFontSize, sCommand, hasParameter, parameter) - COMMAND_RTF_BOOL( "i" , charProps->m_bItalic, sCommand, hasParameter, parameter) - COMMAND_RTF_BOOL( "impr" , charProps->m_bImprint, sCommand, hasParameter, parameter) - COMMAND_RTF_INT ( "kerning" , charProps->m_nKerning, sCommand, hasParameter, parameter) - else if ( "ltrch" == sCommand ) + COMMAND_RTF_BOOL( "fcs" , charProps->m_nComplexScript, sCommand, hasParameter, parameter) + COMMAND_RTF_BOOL( "i" , charProps->m_bItalic, sCommand, hasParameter, parameter) + COMMAND_RTF_BOOL( "impr" , charProps->m_bImprint, sCommand, hasParameter, parameter) + COMMAND_RTF_INT ( "kerning" , charProps->m_nKerning, sCommand, hasParameter, parameter) + else if ( "ltrch" == sCommand ) { if ( false == hasParameter || 0 != parameter ) charProps->m_bRightToLeft = 0; @@ -1157,24 +1160,23 @@ bool RtfCharPropsCommand::ExecuteCommand(RtfDocument& oDocument, RtfReader& oRea charProps->m_bRightToLeft = 1; } COMMAND_RTF_BOOL( "rtlch", charProps->m_bRightToLeft, sCommand, hasParameter, parameter) - COMMAND_RTF_INT ( "lang", charProps->m_nLanguage, sCommand, hasParameter, parameter) - COMMAND_RTF_INT ( "langfe", charProps->m_nLanguageAsian,sCommand, hasParameter, parameter) - - COMMAND_RTF_BOOL( "cs", charProps->m_nComplexScript, sCommand, hasParameter, parameter) - COMMAND_RTF_BOOL( "outl", charProps->m_bOutline, sCommand, hasParameter, parameter) - COMMAND_RTF_BOOL( "scaps", charProps->m_bScaps, sCommand, hasParameter, parameter) - COMMAND_RTF_BOOL( "shad", charProps->m_bShadow, sCommand, hasParameter, parameter) - COMMAND_RTF_BOOL( "strike", charProps->m_bStrike, sCommand, hasParameter, parameter) - COMMAND_RTF_BOOL( "striked", charProps->m_nStriked, sCommand, hasParameter, parameter) - COMMAND_RTF_BOOL( "sub", charProps->m_bSub, sCommand, hasParameter, parameter) - COMMAND_RTF_BOOL( "super", charProps->m_bSuper, sCommand, hasParameter, parameter) - COMMAND_RTF_INT ( "highlight", charProps->m_nHightlited, sCommand, hasParameter, parameter) - else if ( "cf" == sCommand ) + COMMAND_RTF_INT ( "lang", charProps->m_nLanguage, sCommand, hasParameter, parameter) + COMMAND_RTF_INT ( "langfe", charProps->m_nLanguageAsian,sCommand, hasParameter, parameter) + + COMMAND_RTF_BOOL( "outl", charProps->m_bOutline, sCommand, hasParameter, parameter) + COMMAND_RTF_BOOL( "scaps", charProps->m_bScaps, sCommand, hasParameter, parameter) + COMMAND_RTF_BOOL( "shad", charProps->m_bShadow, sCommand, hasParameter, parameter) + COMMAND_RTF_BOOL( "strike", charProps->m_bStrike, sCommand, hasParameter, parameter) + COMMAND_RTF_BOOL( "striked", charProps->m_nStriked, sCommand, hasParameter, parameter) + COMMAND_RTF_BOOL( "sub", charProps->m_bSub, sCommand, hasParameter, parameter) + COMMAND_RTF_BOOL( "super", charProps->m_bSuper, sCommand, hasParameter, parameter) + COMMAND_RTF_INT ( "highlight", charProps->m_nHightlited, sCommand, hasParameter, parameter) + else if ( "cf" == sCommand ) { if ( hasParameter ) charProps->m_nForeColor = parameter; else - charProps->m_nForeColor= PROP_DEF; + charProps->m_nForeColor = PROP_DEF; //auto? } else if ( "ul" == sCommand ) { @@ -1184,38 +1186,37 @@ bool RtfCharPropsCommand::ExecuteCommand(RtfDocument& oDocument, RtfReader& oRea charProps->m_eUnderStyle = RtfCharProperty::uls_Single; } //COMMAND_RTF_BOOL( "ul", charProps->m_bUnderline, sCommand, hasParameter, parameter) - COMMAND_RTF_INT ( "ulc", charProps->m_nUnderlineColor, sCommand, hasParameter, parameter) - - COMMAND_RTF_INT ( "uld", charProps->m_eUnderStyle, sCommand, true, RtfCharProperty::uls_Dotted) - COMMAND_RTF_INT ( "uldash", charProps->m_eUnderStyle, sCommand, true, RtfCharProperty::uls_Dashed) - COMMAND_RTF_INT ( "uldashd", charProps->m_eUnderStyle, sCommand, true, RtfCharProperty::uls_Dash_dotted) - COMMAND_RTF_INT ( "uldashdd", charProps->m_eUnderStyle, sCommand, true, RtfCharProperty::uls_Dash_dot_dotted) - COMMAND_RTF_INT ( "uldb", charProps->m_eUnderStyle, sCommand, true, RtfCharProperty::uls_Double) - COMMAND_RTF_INT ( "ulhwave", charProps->m_eUnderStyle, sCommand, true, RtfCharProperty::uls_Heavy_wave) - COMMAND_RTF_INT ( "ulldash", charProps->m_eUnderStyle, sCommand, true, RtfCharProperty::uls_Long_dashe) - COMMAND_RTF_INT ( "ulnone", charProps->m_eUnderStyle, sCommand, true, RtfCharProperty::uls_none) - COMMAND_RTF_INT ( "ulth", charProps->m_eUnderStyle, sCommand, true, RtfCharProperty::uls_Thick) - COMMAND_RTF_INT ( "ulthd", charProps->m_eUnderStyle, sCommand, true, RtfCharProperty::uls_Thick_dotted) - COMMAND_RTF_INT ( "ulthdash", charProps->m_eUnderStyle, sCommand, true, RtfCharProperty::uls_Thick_dashed) - COMMAND_RTF_INT ( "ulthdashd", charProps->m_eUnderStyle, sCommand, true, RtfCharProperty::uls_Thick_dash_dotted) - COMMAND_RTF_INT ( "ulthdashdd", charProps->m_eUnderStyle, sCommand, true, RtfCharProperty::uls_Thick_dash_dot_dotted) - COMMAND_RTF_INT ( "ulthldash", charProps->m_eUnderStyle, sCommand, true, RtfCharProperty::uls_Thick_long_dashed) - COMMAND_RTF_INT ( "ululdbwave", charProps->m_eUnderStyle, sCommand, true, RtfCharProperty::uls_Double_wave) - COMMAND_RTF_INT ( "ulw", charProps->m_eUnderStyle, sCommand, true, RtfCharProperty::uls_Word) - COMMAND_RTF_INT ( "ulwave", charProps->m_eUnderStyle, sCommand, true, RtfCharProperty::uls_Wave) - - COMMAND_RTF_INT ( "up", charProps->m_nUp, sCommand, hasParameter, parameter) - - COMMAND_RTF_INT ( "crauth", charProps->m_nCrAuth, sCommand, hasParameter, parameter) - COMMAND_RTF_INT ( "crdate", charProps->m_nCrDate, sCommand, hasParameter, parameter) - COMMAND_RTF_INT ( "insrsid", charProps->m_nInsrsid, sCommand, hasParameter, parameter) - - COMMAND_RTF_INT ( "revauth", charProps->m_nRevauth, sCommand, hasParameter, parameter) - COMMAND_RTF_INT ( "revdttm", charProps->m_nRevdttm, sCommand, hasParameter, parameter) - COMMAND_RTF_INT ( "revauthdel", charProps->m_nRevauthDel, sCommand, hasParameter, parameter) - COMMAND_RTF_INT ( "revdttmdel", charProps->m_nRevdttmDel, sCommand, hasParameter, parameter) - - else if ( "revised" == sCommand ) + COMMAND_RTF_INT ( "ulc", charProps->m_nUnderlineColor, sCommand, hasParameter, parameter) + COMMAND_RTF_INT ( "uld", charProps->m_eUnderStyle, sCommand, true, RtfCharProperty::uls_Dotted) + COMMAND_RTF_INT ( "uldash", charProps->m_eUnderStyle, sCommand, true, RtfCharProperty::uls_Dashed) + COMMAND_RTF_INT ( "uldashd", charProps->m_eUnderStyle, sCommand, true, RtfCharProperty::uls_Dash_dotted) + COMMAND_RTF_INT ( "uldashdd", charProps->m_eUnderStyle, sCommand, true, RtfCharProperty::uls_Dash_dot_dotted) + COMMAND_RTF_INT ( "uldb", charProps->m_eUnderStyle, sCommand, true, RtfCharProperty::uls_Double) + COMMAND_RTF_INT ( "ulhwave", charProps->m_eUnderStyle, sCommand, true, RtfCharProperty::uls_Heavy_wave) + COMMAND_RTF_INT ( "ulldash", charProps->m_eUnderStyle, sCommand, true, RtfCharProperty::uls_Long_dashe) + COMMAND_RTF_INT ( "ulnone", charProps->m_eUnderStyle, sCommand, true, RtfCharProperty::uls_none) + COMMAND_RTF_INT ( "ulth", charProps->m_eUnderStyle, sCommand, true, RtfCharProperty::uls_Thick) + COMMAND_RTF_INT ( "ulthd", charProps->m_eUnderStyle, sCommand, true, RtfCharProperty::uls_Thick_dotted) + COMMAND_RTF_INT ( "ulthdash", charProps->m_eUnderStyle, sCommand, true, RtfCharProperty::uls_Thick_dashed) + COMMAND_RTF_INT ( "ulthdashd", charProps->m_eUnderStyle, sCommand, true, RtfCharProperty::uls_Thick_dash_dotted) + COMMAND_RTF_INT ( "ulthdashdd", charProps->m_eUnderStyle, sCommand, true, RtfCharProperty::uls_Thick_dash_dot_dotted) + COMMAND_RTF_INT ( "ulthldash", charProps->m_eUnderStyle, sCommand, true, RtfCharProperty::uls_Thick_long_dashed) + COMMAND_RTF_INT ( "ululdbwave", charProps->m_eUnderStyle, sCommand, true, RtfCharProperty::uls_Double_wave) + COMMAND_RTF_INT ( "ulw", charProps->m_eUnderStyle, sCommand, true, RtfCharProperty::uls_Word) + COMMAND_RTF_INT ( "ulwave", charProps->m_eUnderStyle, sCommand, true, RtfCharProperty::uls_Wave) + + COMMAND_RTF_INT ( "up", charProps->m_nUp, sCommand, hasParameter, parameter) + + COMMAND_RTF_INT ( "crauth", charProps->m_nCrAuth, sCommand, hasParameter, parameter) + COMMAND_RTF_INT ( "crdate", charProps->m_nCrDate, sCommand, hasParameter, parameter) + COMMAND_RTF_INT ( "insrsid", charProps->m_nInsrsid, sCommand, hasParameter, parameter) + + COMMAND_RTF_INT ( "revauth", charProps->m_nRevauth, sCommand, hasParameter, parameter) + COMMAND_RTF_INT ( "revdttm", charProps->m_nRevdttm, sCommand, hasParameter, parameter) + COMMAND_RTF_INT ( "revauthdel", charProps->m_nRevauthDel, sCommand, hasParameter, parameter) + COMMAND_RTF_INT ( "revdttmdel", charProps->m_nRevdttmDel, sCommand, hasParameter, parameter) + + else if ( "revised" == sCommand ) { charProps->m_nRevised = 1; } @@ -1246,6 +1247,13 @@ bool RtfCharPropsCommand::ExecuteCommand(RtfDocument& oDocument, RtfReader& oRea if (RtfBorderCommand::ExecuteCommand( oDocument, oReader,sCommand, hasParameter, parameter, charProps->m_poBorder)) return true; } + + if (sCommand[0] == L'a') + { + charProps->m_bAssociated = true; + sCommand = sCommand.substr(1); + return ExecuteCommand(oDocument, oReader, sCommand, hasParameter, parameter, charProps, bLookOnBorder); + } return false; } @@ -1260,9 +1268,9 @@ bool RtfParagraphPropsCommand::ExecuteCommand(RtfDocument& oDocument, RtfReader& paragraphProps->SetDefaultRtf(); } COMMAND_RTF_INT ( "outlinelevel", paragraphProps->m_nOutlinelevel, sCommand, hasParameter, parameter ) - COMMAND_RTF_BOOL( "hyphpar", paragraphProps->m_bAutoHyphenation, sCommand, hasParameter, parameter ) - COMMAND_RTF_BOOL( "contextualspace", paragraphProps->m_bContextualSpacing, sCommand, hasParameter, parameter ) - else if ( "intbl" == sCommand ) + COMMAND_RTF_BOOL( "hyphpar", paragraphProps->m_bAutoHyphenation, sCommand, hasParameter, parameter ) + COMMAND_RTF_BOOL( "contextualspace", paragraphProps->m_bContextualSpacing, sCommand, hasParameter, parameter ) + else if ( "intbl" == sCommand ) { if ( hasParameter && 0 == parameter ) { @@ -1288,16 +1296,16 @@ bool RtfParagraphPropsCommand::ExecuteCommand(RtfDocument& oDocument, RtfReader& paragraphProps->m_nItap = parameter; } COMMAND_RTF_BOOL( "keep", paragraphProps->m_bKeep, sCommand, hasParameter, parameter ) - COMMAND_RTF_BOOL( "keepn", paragraphProps->m_bKeepNext, sCommand, hasParameter, parameter ) - COMMAND_RTF_BOOL( "pagebb", paragraphProps->m_bPageBB, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "s", paragraphProps->m_nStyle, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "qc", paragraphProps->m_eAlign, sCommand, true, RtfParagraphProperty::pa_qc ) - COMMAND_RTF_INT ( "qj", paragraphProps->m_eAlign, sCommand, true, RtfParagraphProperty::pa_qj ) - COMMAND_RTF_INT ( "ql", paragraphProps->m_eAlign, sCommand, true, RtfParagraphProperty::pa_ql ) - COMMAND_RTF_INT ( "qr", paragraphProps->m_eAlign, sCommand, true, RtfParagraphProperty::pa_qr ) - COMMAND_RTF_INT ( "qd", paragraphProps->m_eAlign, sCommand, true, RtfParagraphProperty::pa_qd ) + COMMAND_RTF_BOOL( "keepn", paragraphProps->m_bKeepNext, sCommand, hasParameter, parameter ) + COMMAND_RTF_BOOL( "pagebb", paragraphProps->m_bPageBB, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "s", paragraphProps->m_nStyle, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "qc", paragraphProps->m_eAlign, sCommand, true, RtfParagraphProperty::pa_qc ) + COMMAND_RTF_INT ( "qj", paragraphProps->m_eAlign, sCommand, true, RtfParagraphProperty::pa_qj ) + COMMAND_RTF_INT ( "ql", paragraphProps->m_eAlign, sCommand, true, RtfParagraphProperty::pa_ql ) + COMMAND_RTF_INT ( "qr", paragraphProps->m_eAlign, sCommand, true, RtfParagraphProperty::pa_qr ) + COMMAND_RTF_INT ( "qd", paragraphProps->m_eAlign, sCommand, true, RtfParagraphProperty::pa_qd ) - else if ( "qk0" == sCommand ) + else if ( "qk0" == sCommand ) { switch( parameter ) { @@ -1308,34 +1316,33 @@ bool RtfParagraphPropsCommand::ExecuteCommand(RtfDocument& oDocument, RtfReader& } } COMMAND_RTF_INT ( "faauto", paragraphProps->m_eFontAlign, sCommand, true, RtfParagraphProperty::fa_faauto ) - COMMAND_RTF_INT ( "fahang", paragraphProps->m_eFontAlign, sCommand, true, RtfParagraphProperty::fa_fahang ) - COMMAND_RTF_INT ( "facenter", paragraphProps->m_eFontAlign, sCommand, true, RtfParagraphProperty::fa_facenter ) - COMMAND_RTF_INT ( "faroman", paragraphProps->m_eFontAlign, sCommand, true, RtfParagraphProperty::fa_faroman ) - COMMAND_RTF_INT ( "favar", paragraphProps->m_eFontAlign, sCommand, true, RtfParagraphProperty::fa_favar ) - COMMAND_RTF_INT ( "fafixed", paragraphProps->m_eFontAlign, sCommand, true, RtfParagraphProperty::fa_fafixed ) - COMMAND_RTF_INT ( "fi", paragraphProps->m_nIndFirstLine, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "li", paragraphProps->m_nIndLeft, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "ri", paragraphProps->m_nIndRight, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "lin", paragraphProps->m_nIndStart, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "rin", paragraphProps->m_nIndEnd, sCommand, hasParameter, parameter ) - COMMAND_RTF_BOOL( "adjustright",paragraphProps->m_bIndRightAuto, sCommand, hasParameter, parameter ) - COMMAND_RTF_BOOL( "indmirror", paragraphProps->m_bIndMirror, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "sb", paragraphProps->m_nSpaceBefore, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "sa", paragraphProps->m_nSpaceAfter, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "sbauto", paragraphProps->m_nSpaceBeforeAuto, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "saauto", paragraphProps->m_nSpaceAfterAuto, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "lisb", paragraphProps->m_nSpaceBeforeLine, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "lisa", paragraphProps->m_nSpaceAfterLine, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "slmult", paragraphProps->m_nSpaceMultiLine, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "ilvl", paragraphProps->m_nListLevel, sCommand, hasParameter, parameter ) - - COMMAND_RTF_BOOL( "absnoovrlp", paragraphProps->m_bOverlap, sCommand, hasParameter, parameter ) - - //changes - COMMAND_RTF_INT ( "prdate", paragraphProps->m_nPrDate, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "prauth", paragraphProps->m_nPrAuth, sCommand, hasParameter, parameter ) - - else if ( "sl" == sCommand ) + COMMAND_RTF_INT ( "fahang", paragraphProps->m_eFontAlign, sCommand, true, RtfParagraphProperty::fa_fahang ) + COMMAND_RTF_INT ( "facenter", paragraphProps->m_eFontAlign, sCommand, true, RtfParagraphProperty::fa_facenter ) + COMMAND_RTF_INT ( "faroman", paragraphProps->m_eFontAlign, sCommand, true, RtfParagraphProperty::fa_faroman ) + COMMAND_RTF_INT ( "favar", paragraphProps->m_eFontAlign, sCommand, true, RtfParagraphProperty::fa_favar ) + COMMAND_RTF_INT ( "fafixed", paragraphProps->m_eFontAlign, sCommand, true, RtfParagraphProperty::fa_fafixed ) + COMMAND_RTF_INT ( "fi", paragraphProps->m_nIndFirstLine, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "li", paragraphProps->m_nIndLeft, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "ri", paragraphProps->m_nIndRight, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "lin", paragraphProps->m_nIndStart, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "rin", paragraphProps->m_nIndEnd, sCommand, hasParameter, parameter ) + COMMAND_RTF_BOOL( "adjustright",paragraphProps->m_bIndRightAuto, sCommand, hasParameter, parameter ) + COMMAND_RTF_BOOL( "indmirror", paragraphProps->m_bIndMirror, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "sb", paragraphProps->m_nSpaceBefore, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "sa", paragraphProps->m_nSpaceAfter, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "sbauto", paragraphProps->m_nSpaceBeforeAuto, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "saauto", paragraphProps->m_nSpaceAfterAuto, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "lisb", paragraphProps->m_nSpaceBeforeLine, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "lisa", paragraphProps->m_nSpaceAfterLine, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "slmult", paragraphProps->m_nSpaceMultiLine, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "ilvl", paragraphProps->m_nListLevel, sCommand, hasParameter, parameter ) + + COMMAND_RTF_BOOL( "absnoovrlp", paragraphProps->m_bOverlap, sCommand, hasParameter, parameter ) +//changes + COMMAND_RTF_INT ( "prdate", paragraphProps->m_nPrDate, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "prauth", paragraphProps->m_nPrAuth, sCommand, hasParameter, parameter ) + + else if ( "sl" == sCommand ) { if ( hasParameter ) { @@ -1347,7 +1354,7 @@ bool RtfParagraphPropsCommand::ExecuteCommand(RtfDocument& oDocument, RtfReader& else if ( "rtlpar" == sCommand ) paragraphProps->m_bRtl = 1; else if ( "ltrpar" == sCommand ) paragraphProps->m_bRtl = 0; COMMAND_RTF_BOOL( "nowwrap", paragraphProps->m_bNoWordWrap, sCommand, hasParameter, parameter ) - else if ( "nowwrap" == sCommand ) + else if ( "nowwrap" == sCommand ) { if ( hasParameter && 0 == parameter) paragraphProps->m_bSnapToGrid = 1; @@ -1363,47 +1370,47 @@ bool RtfParagraphPropsCommand::ExecuteCommand(RtfDocument& oDocument, RtfReader& paragraphProps->m_nListLevel = 0; } } - //Frame +//Frame COMMAND_RTF_INT ( "absw", paragraphProps->m_oFrame.m_nWidth, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "absh", paragraphProps->m_oFrame.m_nHeight, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "phmrg", paragraphProps->m_oFrame.m_eHRef, sCommand, true, RtfFrame::hr_phmrg ) - COMMAND_RTF_INT ( "phpg", paragraphProps->m_oFrame.m_eHRef, sCommand, true, RtfFrame::hr_phpg ) - COMMAND_RTF_INT ( "phcol", paragraphProps->m_oFrame.m_eHRef, sCommand, true, RtfFrame::hr_phcol ) - COMMAND_RTF_INT ( "posx", paragraphProps->m_oFrame.m_nHPos, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "posnegx", paragraphProps->m_oFrame.m_nHPos, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "posxc", paragraphProps->m_oFrame.m_eHPos, sCommand, true, RtfFrame::hp_posxc ) - COMMAND_RTF_INT ( "posxi", paragraphProps->m_oFrame.m_eHPos, sCommand, true, RtfFrame::hp_posxi ) - COMMAND_RTF_INT ( "posxo", paragraphProps->m_oFrame.m_eHPos, sCommand, true, RtfFrame::hp_posxo ) - COMMAND_RTF_INT ( "posxl", paragraphProps->m_oFrame.m_eHPos, sCommand, true, RtfFrame::hp_posxl ) - COMMAND_RTF_INT ( "posxr", paragraphProps->m_oFrame.m_eHPos, sCommand, true, RtfFrame::hp_posxr ) - COMMAND_RTF_INT ( "pvmrg", paragraphProps->m_oFrame.m_eVRef, sCommand, true, RtfFrame::vr_pvmrg ) - COMMAND_RTF_INT ( "pvpg", paragraphProps->m_oFrame.m_eVRef, sCommand, true, RtfFrame::vr_pvpg ) - COMMAND_RTF_INT ( "pvpara", paragraphProps->m_oFrame.m_eVRef, sCommand, true, RtfFrame::vr_pvpara ) - COMMAND_RTF_INT ( "posy", paragraphProps->m_oFrame.m_nVPos, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "posnegy", paragraphProps->m_oFrame.m_nVPos, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "posyt", paragraphProps->m_oFrame.m_eVPos, sCommand, true, RtfFrame::vp_posyt ) - COMMAND_RTF_INT ( "posyil", paragraphProps->m_oFrame.m_eVPos, sCommand, true, RtfFrame::vp_posyil ) - COMMAND_RTF_INT ( "posyb", paragraphProps->m_oFrame.m_eVPos, sCommand, true, RtfFrame::vp_posyb ) - COMMAND_RTF_INT ( "posyc", paragraphProps->m_oFrame.m_eVPos, sCommand, true, RtfFrame::vp_posyc ) - COMMAND_RTF_INT ( "posyin", paragraphProps->m_oFrame.m_eVPos, sCommand, true, RtfFrame::vp_posyin ) - COMMAND_RTF_INT ( "posyout", paragraphProps->m_oFrame.m_eVPos, sCommand, true, RtfFrame::vp_posyout ) - COMMAND_RTF_BOOL( "abslock", paragraphProps->m_oFrame.m_bLockAnchor, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "wrapdefault", paragraphProps->m_oFrame.m_eWrap, sCommand, true, RtfFrame::tw_wrapdefault ) - COMMAND_RTF_INT ( "wraparound", paragraphProps->m_oFrame.m_eWrap, sCommand, true, RtfFrame::tw_wraparound ) - COMMAND_RTF_INT ( "wraptight", paragraphProps->m_oFrame.m_eWrap, sCommand, true, RtfFrame::tw_wraptight ) - COMMAND_RTF_INT ( "wrapthrough", paragraphProps->m_oFrame.m_eWrap, sCommand, true, RtfFrame::tw_wrapthrough ) - COMMAND_RTF_INT ( "dropcapt", paragraphProps->m_oFrame.m_DropcapType, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "dropcapli", paragraphProps->m_oFrame.m_DropcapLines, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "dxfrtext", paragraphProps->m_oFrame.m_nAllSpace, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "dfrmtxtx", paragraphProps->m_oFrame.m_nHorSpace, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "dfrmtxty", paragraphProps->m_oFrame.m_nVerSpace, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "frmtxlrtb", paragraphProps->m_eTextFollow, sCommand, true, RtfParagraphProperty::tf_frmtxlrtb ) - COMMAND_RTF_INT ( "frmtxtbrl", paragraphProps->m_eTextFollow, sCommand, true, RtfParagraphProperty::tf_frmtxtbrl ) - COMMAND_RTF_INT ( "frmtxbtlr", paragraphProps->m_eTextFollow, sCommand, true, RtfParagraphProperty::tf_frmtxbtlr ) - COMMAND_RTF_INT ( "frmtxlrtbv", paragraphProps->m_eTextFollow, sCommand, true, RtfParagraphProperty::tf_frmtxlrtbv ) - COMMAND_RTF_INT ( "frmtxtbrlv", paragraphProps->m_eTextFollow, sCommand, true, RtfParagraphProperty::tf_frmtxtbrlv ) + COMMAND_RTF_INT ( "absh", paragraphProps->m_oFrame.m_nHeight, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "phmrg", paragraphProps->m_oFrame.m_eHRef, sCommand, true, RtfFrame::hr_phmrg ) + COMMAND_RTF_INT ( "phpg", paragraphProps->m_oFrame.m_eHRef, sCommand, true, RtfFrame::hr_phpg ) + COMMAND_RTF_INT ( "phcol", paragraphProps->m_oFrame.m_eHRef, sCommand, true, RtfFrame::hr_phcol ) + COMMAND_RTF_INT ( "posx", paragraphProps->m_oFrame.m_nHPos, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "posnegx", paragraphProps->m_oFrame.m_nHPos, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "posxc", paragraphProps->m_oFrame.m_eHPos, sCommand, true, RtfFrame::hp_posxc ) + COMMAND_RTF_INT ( "posxi", paragraphProps->m_oFrame.m_eHPos, sCommand, true, RtfFrame::hp_posxi ) + COMMAND_RTF_INT ( "posxo", paragraphProps->m_oFrame.m_eHPos, sCommand, true, RtfFrame::hp_posxo ) + COMMAND_RTF_INT ( "posxl", paragraphProps->m_oFrame.m_eHPos, sCommand, true, RtfFrame::hp_posxl ) + COMMAND_RTF_INT ( "posxr", paragraphProps->m_oFrame.m_eHPos, sCommand, true, RtfFrame::hp_posxr ) + COMMAND_RTF_INT ( "pvmrg", paragraphProps->m_oFrame.m_eVRef, sCommand, true, RtfFrame::vr_pvmrg ) + COMMAND_RTF_INT ( "pvpg", paragraphProps->m_oFrame.m_eVRef, sCommand, true, RtfFrame::vr_pvpg ) + COMMAND_RTF_INT ( "pvpara", paragraphProps->m_oFrame.m_eVRef, sCommand, true, RtfFrame::vr_pvpara ) + COMMAND_RTF_INT ( "posy", paragraphProps->m_oFrame.m_nVPos, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "posnegy", paragraphProps->m_oFrame.m_nVPos, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "posyt", paragraphProps->m_oFrame.m_eVPos, sCommand, true, RtfFrame::vp_posyt ) + COMMAND_RTF_INT ( "posyil", paragraphProps->m_oFrame.m_eVPos, sCommand, true, RtfFrame::vp_posyil ) + COMMAND_RTF_INT ( "posyb", paragraphProps->m_oFrame.m_eVPos, sCommand, true, RtfFrame::vp_posyb ) + COMMAND_RTF_INT ( "posyc", paragraphProps->m_oFrame.m_eVPos, sCommand, true, RtfFrame::vp_posyc ) + COMMAND_RTF_INT ( "posyin", paragraphProps->m_oFrame.m_eVPos, sCommand, true, RtfFrame::vp_posyin ) + COMMAND_RTF_INT ( "posyout", paragraphProps->m_oFrame.m_eVPos, sCommand, true, RtfFrame::vp_posyout ) + COMMAND_RTF_BOOL( "abslock", paragraphProps->m_oFrame.m_bLockAnchor, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "wrapdefault", paragraphProps->m_oFrame.m_eWrap, sCommand, true, RtfFrame::tw_wrapdefault ) + COMMAND_RTF_INT ( "wraparound", paragraphProps->m_oFrame.m_eWrap, sCommand, true, RtfFrame::tw_wraparound ) + COMMAND_RTF_INT ( "wraptight", paragraphProps->m_oFrame.m_eWrap, sCommand, true, RtfFrame::tw_wraptight ) + COMMAND_RTF_INT ( "wrapthrough", paragraphProps->m_oFrame.m_eWrap, sCommand, true, RtfFrame::tw_wrapthrough ) + COMMAND_RTF_INT ( "dropcapt", paragraphProps->m_oFrame.m_DropcapType, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "dropcapli", paragraphProps->m_oFrame.m_DropcapLines, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "dxfrtext", paragraphProps->m_oFrame.m_nAllSpace, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "dfrmtxtx", paragraphProps->m_oFrame.m_nHorSpace, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "dfrmtxty", paragraphProps->m_oFrame.m_nVerSpace, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "frmtxlrtb", paragraphProps->m_eTextFollow, sCommand, true, RtfParagraphProperty::tf_frmtxlrtb ) + COMMAND_RTF_INT ( "frmtxtbrl", paragraphProps->m_eTextFollow, sCommand, true, RtfParagraphProperty::tf_frmtxtbrl ) + COMMAND_RTF_INT ( "frmtxbtlr", paragraphProps->m_eTextFollow, sCommand, true, RtfParagraphProperty::tf_frmtxbtlr ) + COMMAND_RTF_INT ( "frmtxlrtbv", paragraphProps->m_eTextFollow, sCommand, true, RtfParagraphProperty::tf_frmtxlrtbv ) + COMMAND_RTF_INT ( "frmtxtbrlv", paragraphProps->m_eTextFollow, sCommand, true, RtfParagraphProperty::tf_frmtxtbrlv ) - else + else { if (RtfShadingCommand::ExecuteCommand( oDocument, oReader, sCommand, hasParameter, parameter, oReader.m_oState->m_oParagraphProp.m_oShading )) return true; @@ -1418,30 +1425,29 @@ bool RtfTableCellPropsCommand::ExecuteCommand(RtfDocument& oDocument, RtfReader& if (!cellProps) return false; COMMAND_RTF_BOOL( "clmgf", cellProps->m_bMergeFirst, sCommand, hasParameter, parameter ) - COMMAND_RTF_BOOL( "clmrg", cellProps->m_bMerge, sCommand, hasParameter, parameter ) - COMMAND_RTF_BOOL( "clvmgf", cellProps->m_bMergeFirstVertical, sCommand, hasParameter, parameter ) - COMMAND_RTF_BOOL( "clvmrg", cellProps->m_bMergeVertical, sCommand, hasParameter, parameter ) - COMMAND_RTF_BOOL( "clFitText", cellProps->m_bFitText, sCommand, hasParameter, parameter ) - COMMAND_RTF_BOOL( "clNoWrap", cellProps->m_bNoWrap, sCommand, hasParameter, parameter ) - - //https://www.office-forums.com/threads/rtf-file-weirdness-clpadt-vs-clpadl.2163500/ - COMMAND_RTF_INT ( "clpadft", cellProps->m_ePaddingLeftUnit, sCommand, hasParameter, parameter ) //перепутаны top & left - COMMAND_RTF_INT ( "clpadt", cellProps->m_nPaddingLeft, sCommand, hasParameter, parameter ) //перепутаны top & left - COMMAND_RTF_INT ( "clpadfl", cellProps->m_ePaddingTopUnit, sCommand, hasParameter, parameter ) //перепутаны top & left - COMMAND_RTF_INT ( "clpadl", cellProps->m_nPaddingTop, sCommand, hasParameter, parameter ) //перепутаны top & left - COMMAND_RTF_INT ( "clpadfr", cellProps->m_ePaddingRightUnit, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "clpadr", cellProps->m_nPaddingRight, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "clpadfb", cellProps->m_ePaddingBottomUnit, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "clpadb", cellProps->m_nPaddingBottom, sCommand, hasParameter, parameter ) - - COMMAND_RTF_INT ( "clspfl", cellProps->m_eSpacingLeftUnit, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "clspl", cellProps->m_nSpacingLeft, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "clspft", cellProps->m_eSpacingTopUnit, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "clspt", cellProps->m_nSpacingTop, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "clspfr", cellProps->m_eSpacingRightUnit, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "clspr", cellProps->m_nSpacingRight, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "clspfb", cellProps->m_eSpacingBottomUnit, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "clspb", cellProps->m_nSpacingBottom, sCommand, hasParameter, parameter ) + COMMAND_RTF_BOOL( "clmrg", cellProps->m_bMerge, sCommand, hasParameter, parameter ) + COMMAND_RTF_BOOL( "clvmgf", cellProps->m_bMergeFirstVertical, sCommand, hasParameter, parameter ) + COMMAND_RTF_BOOL( "clvmrg", cellProps->m_bMergeVertical, sCommand, hasParameter, parameter ) + COMMAND_RTF_BOOL( "clFitText", cellProps->m_bFitText, sCommand, hasParameter, parameter ) + COMMAND_RTF_BOOL( "clNoWrap", cellProps->m_bNoWrap, sCommand, hasParameter, parameter ) +//https://www.office-forums.com/threads/rtf-file-weirdness-clpadt-vs-clpadl.2163500/ + COMMAND_RTF_INT ( "clpadft", cellProps->m_ePaddingLeftUnit, sCommand, hasParameter, parameter ) //перепутаны top & left + COMMAND_RTF_INT ( "clpadt", cellProps->m_nPaddingLeft, sCommand, hasParameter, parameter ) //перепутаны top & left + COMMAND_RTF_INT ( "clpadfl", cellProps->m_ePaddingTopUnit, sCommand, hasParameter, parameter ) //перепутаны top & left + COMMAND_RTF_INT ( "clpadl", cellProps->m_nPaddingTop, sCommand, hasParameter, parameter ) //перепутаны top & left + COMMAND_RTF_INT ( "clpadfr", cellProps->m_ePaddingRightUnit, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "clpadr", cellProps->m_nPaddingRight, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "clpadfb", cellProps->m_ePaddingBottomUnit, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "clpadb", cellProps->m_nPaddingBottom, sCommand, hasParameter, parameter ) + + COMMAND_RTF_INT ( "clspfl", cellProps->m_eSpacingLeftUnit, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "clspl", cellProps->m_nSpacingLeft, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "clspft", cellProps->m_eSpacingTopUnit, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "clspt", cellProps->m_nSpacingTop, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "clspfr", cellProps->m_eSpacingRightUnit, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "clspr", cellProps->m_nSpacingRight, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "clspfb", cellProps->m_eSpacingBottomUnit, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "clspb", cellProps->m_nSpacingBottom, sCommand, hasParameter, parameter ) else if ( "clftsWidth" == sCommand ) { @@ -1459,29 +1465,29 @@ bool RtfTableCellPropsCommand::ExecuteCommand(RtfDocument& oDocument, RtfReader& } } COMMAND_RTF_INT ( "clwWidth", cellProps->m_nWidth, sCommand, hasParameter, parameter ) - COMMAND_RTF_BOOL( "clhidemark", cellProps->m_bHideMark, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "clvertalt", cellProps->m_eAlign, sCommand, true, RtfCellProperty::ca_Top ) - COMMAND_RTF_INT ( "clvertalc", cellProps->m_eAlign, sCommand, true, RtfCellProperty::ca_Center ) - COMMAND_RTF_INT ( "clvertalb", cellProps->m_eAlign, sCommand, true, RtfCellProperty::ca_Bottom ) - COMMAND_RTF_INT ( "cltxlrtb", cellProps->m_oCellFlow, sCommand, true, RtfCellProperty::cf_lrtb ) - COMMAND_RTF_INT ( "cltxtbrl", cellProps->m_oCellFlow, sCommand, true, RtfCellProperty::cf_tbrl ) - COMMAND_RTF_INT ( "cltxbtlr", cellProps->m_oCellFlow, sCommand, true, RtfCellProperty::cf_btlr ) - COMMAND_RTF_INT ( "cltxlrtbv", cellProps->m_oCellFlow, sCommand, true, RtfCellProperty::cf_lrtbv ) - COMMAND_RTF_INT ( "cltxtbrlv", cellProps->m_oCellFlow, sCommand, true, RtfCellProperty::cf_tbrlv ) + COMMAND_RTF_BOOL( "clhidemark", cellProps->m_bHideMark, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "clvertalt", cellProps->m_eAlign, sCommand, true, RtfCellProperty::ca_Top ) + COMMAND_RTF_INT ( "clvertalc", cellProps->m_eAlign, sCommand, true, RtfCellProperty::ca_Center ) + COMMAND_RTF_INT ( "clvertalb", cellProps->m_eAlign, sCommand, true, RtfCellProperty::ca_Bottom ) + COMMAND_RTF_INT ( "cltxlrtb", cellProps->m_oCellFlow, sCommand, true, RtfCellProperty::cf_lrtb ) + COMMAND_RTF_INT ( "cltxtbrl", cellProps->m_oCellFlow, sCommand, true, RtfCellProperty::cf_tbrl ) + COMMAND_RTF_INT ( "cltxbtlr", cellProps->m_oCellFlow, sCommand, true, RtfCellProperty::cf_btlr ) + COMMAND_RTF_INT ( "cltxlrtbv", cellProps->m_oCellFlow, sCommand, true, RtfCellProperty::cf_lrtbv ) + COMMAND_RTF_INT ( "cltxtbrlv", cellProps->m_oCellFlow, sCommand, true, RtfCellProperty::cf_tbrlv ) //table style - COMMAND_RTF_INT ( "tscellpaddfl", cellProps->m_ePaddingLeftUnit, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "tscellpaddl", cellProps->m_nPaddingLeft, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "tscellpaddft", cellProps->m_ePaddingTopUnit, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "tscellpaddt", cellProps->m_nPaddingTop, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "tscellpaddfr", cellProps->m_ePaddingRightUnit, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "tscellpaddr", cellProps->m_nPaddingRight, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "tscellpaddfb", cellProps->m_ePaddingBottomUnit,sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "tscellpaddb", cellProps->m_nPaddingBottom, sCommand, hasParameter, parameter ) - COMMAND_RTF_BOOL( "tsnowrap", cellProps->m_bNoWrap, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "tsvertalt", cellProps->m_eAlign, sCommand, true, RtfCellProperty::ca_Top ) - COMMAND_RTF_INT ( "tsvertalc", cellProps->m_eAlign, sCommand, true, RtfCellProperty::ca_Center ) - COMMAND_RTF_INT ( "tsvertalb", cellProps->m_eAlign, sCommand, true, RtfCellProperty::ca_Bottom ) + COMMAND_RTF_INT ( "tscellpaddfl", cellProps->m_ePaddingLeftUnit, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "tscellpaddl", cellProps->m_nPaddingLeft, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "tscellpaddft", cellProps->m_ePaddingTopUnit, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "tscellpaddt", cellProps->m_nPaddingTop, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "tscellpaddfr", cellProps->m_ePaddingRightUnit, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "tscellpaddr", cellProps->m_nPaddingRight, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "tscellpaddfb", cellProps->m_ePaddingBottomUnit,sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "tscellpaddb", cellProps->m_nPaddingBottom, sCommand, hasParameter, parameter ) + COMMAND_RTF_BOOL( "tsnowrap", cellProps->m_bNoWrap, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "tsvertalt", cellProps->m_eAlign, sCommand, true, RtfCellProperty::ca_Top ) + COMMAND_RTF_INT ( "tsvertalc", cellProps->m_eAlign, sCommand, true, RtfCellProperty::ca_Center ) + COMMAND_RTF_INT ( "tsvertalb", cellProps->m_eAlign, sCommand, true, RtfCellProperty::ca_Bottom ) else { if (RtfShadingCellCommand::ExecuteCommand( oDocument, oReader,sCommand, hasParameter, parameter, cellProps->m_oShading )) @@ -1506,63 +1512,63 @@ bool RtfTableRowPropsCommand::ExecuteCommand(RtfDocument& oDocument, RtfReader& } COMMAND_RTF_INT ( "irow", rowProps->m_nIndex, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "irowband", rowProps->m_nBandIndex, sCommand, hasParameter, parameter ) - COMMAND_RTF_BOOL( "lastrow", rowProps->m_bLastRow, sCommand, hasParameter, parameter ) - COMMAND_RTF_BOOL( "trhdr", rowProps->m_bIsHeader, sCommand, hasParameter, parameter ) - COMMAND_RTF_BOOL( "trkeep", rowProps->m_bKeep, sCommand, hasParameter, parameter ) - COMMAND_RTF_BOOL( "trkeepfollow", rowProps->m_bKeep, sCommand, hasParameter, parameter ) - - COMMAND_RTF_INT ( "trql", rowProps->m_eJust, sCommand, true, RtfRowProperty::rj_trql ) - COMMAND_RTF_INT ( "trqr", rowProps->m_eJust, sCommand, true, RtfRowProperty::rj_trqr ) - COMMAND_RTF_INT ( "trqc", rowProps->m_eJust, sCommand, true, RtfRowProperty::rj_trqc ) - - COMMAND_RTF_INT ( "trrh", rowProps->m_nHeight, sCommand, hasParameter, parameter ) - - COMMAND_RTF_INT ( "trftsWidth", rowProps->m_eWidthUnit, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "trwWidth", rowProps->m_nWidth, sCommand, hasParameter, parameter ) - - COMMAND_RTF_INT ( "trftsWidthB", rowProps->m_eWidthStartInvCellUnit, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "trwWidthB", rowProps->m_nWidthStartInvCell, sCommand, hasParameter, parameter ) - - COMMAND_RTF_INT ( "trftsWidthA", rowProps->m_eWidthEndInvCellUnit, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "trwWidthA", rowProps->m_nWidthEndInvCell, sCommand, hasParameter, parameter ) - - COMMAND_RTF_BOOL( "taprtl", rowProps->m_bBidi, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "trautofit", rowProps->m_nAutoFit, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "trgaph", rowProps->m_nGraph, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "tblind", rowProps->nTableIndent, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "tblindtype", rowProps->eTableIndentUnit, sCommand, hasParameter, parameter ) - - COMMAND_RTF_INT ( "tdfrmtxtLeft", rowProps->m_nWrapLeft, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "tdfrmtxtRight", rowProps->m_nWrapRight, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "tdfrmtxtTop", rowProps->m_nWrapTop, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "tdfrmtxtBottom", rowProps->m_nWrapBottom, sCommand, hasParameter, parameter ) - COMMAND_RTF_BOOL( "tabsnoovrlp", rowProps->m_bOverlap, sCommand, hasParameter, parameter ) - - COMMAND_RTF_INT ( "tphmrg", rowProps->m_eHRef, sCommand, true, RtfTableProperty::hr_phmrg ) - COMMAND_RTF_INT ( "tphpg", rowProps->m_eHRef, sCommand, true, RtfTableProperty::hr_phpg ) - COMMAND_RTF_INT ( "tphcol", rowProps->m_eHRef, sCommand, true, RtfTableProperty::hr_phcol ) - COMMAND_RTF_INT ( "tposx", rowProps->m_nHPos, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "tposnegx", rowProps->m_nHPos, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "tposxc", rowProps->m_eHPos, sCommand, true, RtfTableProperty::hp_posxc ) - COMMAND_RTF_INT ( "tposxi", rowProps->m_eHPos, sCommand, true, RtfTableProperty::hp_posxi ) - COMMAND_RTF_INT ( "tposxo", rowProps->m_eHPos, sCommand, true, RtfTableProperty::hp_posxo ) - COMMAND_RTF_INT ( "tposxl", rowProps->m_eHPos, sCommand, true, RtfTableProperty::hp_posxl ) - COMMAND_RTF_INT ( "tposxr", rowProps->m_eHPos, sCommand, true, RtfTableProperty::hp_posxr ) - - COMMAND_RTF_INT ( "tpvmrg", rowProps->m_eVRef, sCommand, true, RtfTableProperty::vr_pvmrg ) - COMMAND_RTF_INT ( "tpvpg", rowProps->m_eVRef, sCommand, true, RtfTableProperty::vr_pvpg ) - COMMAND_RTF_INT ( "tpvpara", rowProps->m_eVRef, sCommand, true, RtfTableProperty::vr_pvpara ) - COMMAND_RTF_INT ( "tposy", rowProps->m_nVPos, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "tposnegy", rowProps->m_nVPos, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "tposyt", rowProps->m_eVPos, sCommand, true, RtfTableProperty::vp_posyt ) - COMMAND_RTF_INT ( "tposyil", rowProps->m_eVPos, sCommand, true, RtfTableProperty::vp_posyil ) - COMMAND_RTF_INT ( "tposyb", rowProps->m_eVPos, sCommand, true, RtfTableProperty::vp_posyb ) - COMMAND_RTF_INT ( "tposyc", rowProps->m_eVPos, sCommand, true, RtfTableProperty::vp_posyc ) - COMMAND_RTF_INT ( "tposyin", rowProps->m_eVPos, sCommand, true, RtfTableProperty::vp_posyin ) - COMMAND_RTF_INT ( "tposyout", rowProps->m_eVPos, sCommand, true, RtfTableProperty::vp_posyout ) - - else if ( "trleft" == sCommand ) + COMMAND_RTF_INT ( "irowband", rowProps->m_nBandIndex, sCommand, hasParameter, parameter ) + COMMAND_RTF_BOOL( "lastrow", rowProps->m_bLastRow, sCommand, hasParameter, parameter ) + COMMAND_RTF_BOOL( "trhdr", rowProps->m_bIsHeader, sCommand, hasParameter, parameter ) + COMMAND_RTF_BOOL( "trkeep", rowProps->m_bKeep, sCommand, hasParameter, parameter ) + COMMAND_RTF_BOOL( "trkeepfollow", rowProps->m_bKeep, sCommand, hasParameter, parameter ) + + COMMAND_RTF_INT ( "trql", rowProps->m_eJust, sCommand, true, RtfRowProperty::rj_trql ) + COMMAND_RTF_INT ( "trqr", rowProps->m_eJust, sCommand, true, RtfRowProperty::rj_trqr ) + COMMAND_RTF_INT ( "trqc", rowProps->m_eJust, sCommand, true, RtfRowProperty::rj_trqc ) + + COMMAND_RTF_INT ( "trrh", rowProps->m_nHeight, sCommand, hasParameter, parameter ) + + COMMAND_RTF_INT ( "trftsWidth", rowProps->m_eWidthUnit, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "trwWidth", rowProps->m_nWidth, sCommand, hasParameter, parameter ) + + COMMAND_RTF_INT ( "trftsWidthB", rowProps->m_eWidthStartInvCellUnit, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "trwWidthB", rowProps->m_nWidthStartInvCell, sCommand, hasParameter, parameter ) + + COMMAND_RTF_INT ( "trftsWidthA", rowProps->m_eWidthEndInvCellUnit, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "trwWidthA", rowProps->m_nWidthEndInvCell, sCommand, hasParameter, parameter ) + + COMMAND_RTF_BOOL( "taprtl", rowProps->m_bBidi, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "trautofit", rowProps->m_nAutoFit, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "trgaph", rowProps->m_nGraph, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "tblind", rowProps->nTableIndent, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "tblindtype", rowProps->eTableIndentUnit, sCommand, hasParameter, parameter ) + + COMMAND_RTF_INT ( "tdfrmtxtLeft", rowProps->m_nWrapLeft, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "tdfrmtxtRight", rowProps->m_nWrapRight, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "tdfrmtxtTop", rowProps->m_nWrapTop, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "tdfrmtxtBottom", rowProps->m_nWrapBottom, sCommand, hasParameter, parameter ) + COMMAND_RTF_BOOL( "tabsnoovrlp", rowProps->m_bOverlap, sCommand, hasParameter, parameter ) + + COMMAND_RTF_INT ( "tphmrg", rowProps->m_eHRef, sCommand, true, RtfTableProperty::hr_phmrg ) + COMMAND_RTF_INT ( "tphpg", rowProps->m_eHRef, sCommand, true, RtfTableProperty::hr_phpg ) + COMMAND_RTF_INT ( "tphcol", rowProps->m_eHRef, sCommand, true, RtfTableProperty::hr_phcol ) + COMMAND_RTF_INT ( "tposx", rowProps->m_nHPos, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "tposnegx", rowProps->m_nHPos, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "tposxc", rowProps->m_eHPos, sCommand, true, RtfTableProperty::hp_posxc ) + COMMAND_RTF_INT ( "tposxi", rowProps->m_eHPos, sCommand, true, RtfTableProperty::hp_posxi ) + COMMAND_RTF_INT ( "tposxo", rowProps->m_eHPos, sCommand, true, RtfTableProperty::hp_posxo ) + COMMAND_RTF_INT ( "tposxl", rowProps->m_eHPos, sCommand, true, RtfTableProperty::hp_posxl ) + COMMAND_RTF_INT ( "tposxr", rowProps->m_eHPos, sCommand, true, RtfTableProperty::hp_posxr ) + + COMMAND_RTF_INT ( "tpvmrg", rowProps->m_eVRef, sCommand, true, RtfTableProperty::vr_pvmrg ) + COMMAND_RTF_INT ( "tpvpg", rowProps->m_eVRef, sCommand, true, RtfTableProperty::vr_pvpg ) + COMMAND_RTF_INT ( "tpvpara", rowProps->m_eVRef, sCommand, true, RtfTableProperty::vr_pvpara ) + COMMAND_RTF_INT ( "tposy", rowProps->m_nVPos, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "tposnegy", rowProps->m_nVPos, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "tposyt", rowProps->m_eVPos, sCommand, true, RtfTableProperty::vp_posyt ) + COMMAND_RTF_INT ( "tposyil", rowProps->m_eVPos, sCommand, true, RtfTableProperty::vp_posyil ) + COMMAND_RTF_INT ( "tposyb", rowProps->m_eVPos, sCommand, true, RtfTableProperty::vp_posyb ) + COMMAND_RTF_INT ( "tposyc", rowProps->m_eVPos, sCommand, true, RtfTableProperty::vp_posyc ) + COMMAND_RTF_INT ( "tposyin", rowProps->m_eVPos, sCommand, true, RtfTableProperty::vp_posyin ) + COMMAND_RTF_INT ( "tposyout", rowProps->m_eVPos, sCommand, true, RtfTableProperty::vp_posyout ) + + else if ( "trleft" == sCommand ) { if ( hasParameter ) { @@ -1577,7 +1583,7 @@ bool RtfTableRowPropsCommand::ExecuteCommand(RtfDocument& oDocument, RtfReader& } } COMMAND_RTF_INT ( "trwWidth", rowProps->m_nWidth, sCommand, hasParameter, parameter ) - else if ( "trftsWidth" == sCommand ) + else if ( "trftsWidth" == sCommand ) { if ( hasParameter ) { @@ -1593,39 +1599,39 @@ bool RtfTableRowPropsCommand::ExecuteCommand(RtfDocument& oDocument, RtfReader& } } COMMAND_RTF_INT ( "trpaddb", rowProps->m_nDefCellMarBottom, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "trpaddl", rowProps->m_nDefCellMarLeft, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "trpaddr", rowProps->m_nDefCellMarRight, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "trpaddt", rowProps->m_nDefCellMarTop, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "trpaddfb", rowProps->m_eDefCellMarBottomUnit, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "trpaddfl", rowProps->m_eDefCellMarLeftUnit, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "trpaddfr", rowProps->m_eDefCellMarRightUnit, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "trpaddft", rowProps->m_eDefCellMarTopUnit, sCommand, hasParameter, parameter ) - - COMMAND_RTF_INT ( "trspdb", rowProps->m_nDefCellSpBottom, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "trspdl", rowProps->m_nDefCellSpLeft, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "trspdr", rowProps->m_nDefCellSpRight, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "trspdt", rowProps->m_nDefCellSpTop, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "trspdfb", rowProps->m_eDefCellSpBottomUnit, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "trspdfl", rowProps->m_eDefCellSpLeftUnit, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "trspdfr", rowProps->m_eDefCellSpRightUnit, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "trspdft", rowProps->m_eDefCellSpTopUnit, sCommand, hasParameter, parameter ) - - COMMAND_RTF_INT ( "ts", rowProps->m_nStyle, sCommand, hasParameter, parameter ) - - COMMAND_RTF_INT ( "tbllkhdrrows", rowProps->m_bAutoFirstRow, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "tbllklastrow", rowProps->m_bAutoLastRow, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "tbllkhdrcols", rowProps->m_bAutoFirstCol, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "tbllklastcol", rowProps->m_bAutoLastCol, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "tbllknorowband", rowProps->m_bAutoNoRowBand, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "tbllknocolband", rowProps->m_bAutoNoColBand, sCommand, hasParameter, parameter ) - - COMMAND_RTF_INT ( "tscbandsh", rowProps->m_nRowBandSize, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "tscbandsv", rowProps->m_nColBandSize, sCommand, hasParameter, parameter ) - - COMMAND_RTF_INT ( "trdate", rowProps->m_nTrDate, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "trauth", rowProps->m_nTrAuth, sCommand, hasParameter, parameter ) - - else if ( "rtlrow" == sCommand ) rowProps->m_nRightToLeft = 1; + COMMAND_RTF_INT ( "trpaddl", rowProps->m_nDefCellMarLeft, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "trpaddr", rowProps->m_nDefCellMarRight, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "trpaddt", rowProps->m_nDefCellMarTop, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "trpaddfb", rowProps->m_eDefCellMarBottomUnit, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "trpaddfl", rowProps->m_eDefCellMarLeftUnit, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "trpaddfr", rowProps->m_eDefCellMarRightUnit, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "trpaddft", rowProps->m_eDefCellMarTopUnit, sCommand, hasParameter, parameter ) + + COMMAND_RTF_INT ( "trspdb", rowProps->m_nDefCellSpBottom, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "trspdl", rowProps->m_nDefCellSpLeft, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "trspdr", rowProps->m_nDefCellSpRight, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "trspdt", rowProps->m_nDefCellSpTop, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "trspdfb", rowProps->m_eDefCellSpBottomUnit, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "trspdfl", rowProps->m_eDefCellSpLeftUnit, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "trspdfr", rowProps->m_eDefCellSpRightUnit, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "trspdft", rowProps->m_eDefCellSpTopUnit, sCommand, hasParameter, parameter ) + + COMMAND_RTF_INT ( "ts", rowProps->m_nStyle, sCommand, hasParameter, parameter ) + + COMMAND_RTF_INT ( "tbllkhdrrows", rowProps->m_bAutoFirstRow, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "tbllklastrow", rowProps->m_bAutoLastRow, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "tbllkhdrcols", rowProps->m_bAutoFirstCol, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "tbllklastcol", rowProps->m_bAutoLastCol, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "tbllknorowband", rowProps->m_bAutoNoRowBand, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "tbllknocolband", rowProps->m_bAutoNoColBand, sCommand, hasParameter, parameter ) + + COMMAND_RTF_INT ( "tscbandsh", rowProps->m_nRowBandSize, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "tscbandsv", rowProps->m_nColBandSize, sCommand, hasParameter, parameter ) + + COMMAND_RTF_INT ( "trdate", rowProps->m_nTrDate, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "trauth", rowProps->m_nTrAuth, sCommand, hasParameter, parameter ) + + else if ( "rtlrow" == sCommand ) rowProps->m_nRightToLeft = 1; else if ( "ltrrow" == sCommand ) rowProps->m_nRightToLeft = 0; else @@ -1709,8 +1715,12 @@ void RtfOldShapeReader::ExitReader( RtfDocument& oDocument, RtfReader& oReader ) } bool RtfOldShapeReader::ExecuteCommand(RtfDocument& oDocument, RtfReader& oReader, std::string sCommand, bool hasParameter, int parameter) { - if ( "do" == sCommand ) + if ("do" == sCommand) + { + m_oShape.m_bLayoutInCell = 0; + m_oShape.m_nZOrderRelative = 1; return true; + } else if ( "doinst" == sCommand ) return true; else if ( "dorslt" == sCommand ) @@ -1745,19 +1755,66 @@ bool RtfOldShapeReader::ExecuteCommand(RtfDocument& oDocument, RtfReader& oReade else if ( "dolockanchor" == sCommand ) m_oShape.m_bLockAnchor = true; else if ( "dplinehollow" == sCommand ) m_oShape.m_bLine = false; + else if ("dplinecor" == sCommand) + { + if (m_oShape.m_nLineColor == PROP_DEF) m_oShape.m_nLineColor = 0xFFFFFF; + SETBITS(m_oShape.m_nLineColor, 0, 7, parameter); + } + else if ("dplinecog" == sCommand) + { + if (m_oShape.m_nLineColor == PROP_DEF) m_oShape.m_nLineColor = 0xFFFFFF; + SETBITS(m_oShape.m_nLineColor, 8, 15, parameter); + } + else if ("dplinecob" == sCommand) + { + if (m_oShape.m_nLineColor == PROP_DEF) m_oShape.m_nLineColor = 0xFFFFFF; + SETBITS(m_oShape.m_nLineColor, 16, 23, parameter); + } + else if ("dpfillbgcr" == sCommand) + { + if (m_oShape.m_nFillColor == PROP_DEF) m_oShape.m_nFillColor = 0xFFFFFF; + SETBITS(m_oShape.m_nFillColor, 0, 7, parameter); + } + else if ("dpfillbgcg" == sCommand) + { + if (m_oShape.m_nFillColor == PROP_DEF) m_oShape.m_nFillColor = 0xFFFFFF; + SETBITS(m_oShape.m_nFillColor, 8, 15, parameter); + } + else if ("dpfillbgcb" == sCommand) + { + if (m_oShape.m_nFillColor == PROP_DEF) m_oShape.m_nFillColor = 0xFFFFFF; + SETBITS(m_oShape.m_nFillColor, 16, 23, parameter); + } + else if ("dpfillfgcr" == sCommand) + { + if (m_oShape.m_nFillColor2 == PROP_DEF) m_oShape.m_nFillColor2 = 0xFFFFFF; + SETBITS(m_oShape.m_nFillColor2, 0, 7, parameter); + } + else if ("dpfillfgcg" == sCommand) + { + if (m_oShape.m_nFillColor2 == PROP_DEF) m_oShape.m_nFillColor2 = 0xFFFFFF; + SETBITS(m_oShape.m_nFillColor2, 8, 15, parameter); + } + else if ("dpfillfgcb" == sCommand) + { + if (m_oShape.m_nFillColor2 == PROP_DEF) m_oShape.m_nFillColor2 = 0xFFFFFF; + SETBITS(m_oShape.m_nFillColor2, 16, 23, parameter); + } else if ( hasParameter) { if ( "dpx" == sCommand ) m_oShape.m_nLeft = parameter; - else if ( "dpx" == sCommand ) m_oShape.m_nLeft = parameter; else if ( "dpy" == sCommand ) m_oShape.m_nTop = parameter; - else if ( "dpysize" == sCommand ) m_oShape.m_nBottom = parameter + m_oShape.m_nTop; else if ( "dpxsize" == sCommand ) m_oShape.m_nRight = parameter + m_oShape.m_nLeft; + else if ( "dpysize" == sCommand ) m_oShape.m_nBottom = parameter + m_oShape.m_nTop; else if ( "doz" == sCommand ) m_oShape.m_nZOrder = parameter; else if ( "dofhdr" == sCommand ) m_oShape.m_nHeader = parameter; else if ( "dowr" == sCommand ) m_oShape.m_nWrapType = parameter; else if ( "dowrk" == sCommand ) m_oShape.m_nWrapSideType = parameter; else if ( "dofblwtxt" == sCommand ) m_oShape.m_nZOrderRelative = parameter; - else if ( "dplinew" == sCommand ) m_oShape.m_nLineWidth = parameter; + else if ( "dplinew" == sCommand ) m_oShape.m_nLineWidth = RtfUtility::Pt2Emu(parameter); + else if ( "dplinehollow"== sCommand ) m_oShape.m_bLine = false; + else if ( "dplinedot" == sCommand ) m_oShape.m_nLineDashing = 5; + else if ( "dplinedash" == sCommand ) m_oShape.m_nLineDashing = 6; else if ( "dodhgt" == sCommand ) m_oShape.m_nZOrder = parameter; else if ( "dptxbxmar" == sCommand ) { @@ -1765,8 +1822,14 @@ bool RtfOldShapeReader::ExecuteCommand(RtfDocument& oDocument, RtfReader& oReade } else if ( "dpfillpat" == sCommand ) { - m_oShape.m_nFillType = parameter; - if (m_oShape.m_nFillType == 0) m_oShape.m_bFilled = false; + switch(parameter) + { + case 0: m_oShape.m_bFilled = false; break; + case 1: m_oShape.m_nFillType = 0; break; //solid + default: + m_oShape.m_nFillType = 2; // pattern + break; + } } } else @@ -2219,7 +2282,7 @@ bool RtfBackgroundReader::ExecuteCommand(RtfDocument& oDocument, RtfReader& oRea return true; } -RtfFieldReader::RtfFieldReader( RtfField& oField ):m_oField(oField) +RtfFieldReader::RtfFieldReader( RtfField& oField ) : m_oField(oField) { m_eInternalState = is_normal; } @@ -2410,8 +2473,8 @@ bool RtfFieldReader::ExecuteCommand(RtfDocument& oDocument, RtfReader& oReader, { RtfFieldInstPtr oNewFieldInst = RtfFieldInstPtr(new RtfFieldInst()); oNewFieldInst->m_oCharProperty = oReader.m_oState->m_oCharProp; - - RtfFieldInstReader oFieldInstReader( *oNewFieldInst ); + + RtfFieldInstReader oFieldInstReader( *oNewFieldInst ); StartSubReader( oFieldInstReader, oDocument, oReader ); if ( oNewFieldInst->IsValid() ) @@ -2429,7 +2492,6 @@ bool RtfFieldReader::ExecuteCommand(RtfDocument& oDocument, RtfReader& oReader, } return true; } - RtfAnnotElemReader::RtfAnnotElemReader( RtfAnnotElem& oAnnot ) : m_oAnnot(oAnnot) { } @@ -2495,19 +2557,18 @@ void RtfBookmarkEndReader::ExecuteText(RtfDocument& oDocument, RtfReader& oReade RtfFieldInstReader::RtfFieldInstReader( RtfFieldInst& oFieldInst ) : m_oFieldInst(oFieldInst) {} void RtfFieldInstReader::ExecuteText( RtfDocument& oDocument, RtfReader& oReader, std::wstring sText ) { - RtfParagraphPropDestination::ExecuteText( oDocument, oReader, sText ); + RtfParagraphPropDestination::ExecuteText(oDocument, oReader, sText); } void RtfFieldInstReader::ExitReader( RtfDocument& oDocument, RtfReader& oReader ) { RtfParagraphPropDestination::Finalize( oReader ); - - m_oFieldInst.m_pTextItems = m_oTextItems; + m_oFieldInst.m_pTextItems = m_oTextItems; } bool RtfFieldInstReader::ExecuteCommand(RtfDocument& oDocument, RtfReader& oReader , std::string sCommand, bool hasParameter, int parameter) { - if( "fldinst" == sCommand ) + if ("fldinst" == sCommand) return true; - if( "fldrslt" == sCommand ) + if ("fldrslt" == sCommand) return true; else if ("formfield" == sCommand) { @@ -2562,17 +2623,17 @@ bool RtfFormFieldReader::ExecuteCommand(RtfDocument& oDocument, RtfReader& oRead else if ("ffexitmcr" == sCommand) m_eInternalState = is_exitmcr; else if ("ffl" == sCommand) m_eInternalState = is_list; COMMAND_RTF_INT("fftype", m_oFormField.type, sCommand, hasParameter, parameter) - COMMAND_RTF_INT("ffownhelp", m_oFormField.ownhelp, sCommand, hasParameter, parameter) - COMMAND_RTF_INT("ffownstat", m_oFormField.ownstat, sCommand, hasParameter, parameter) - COMMAND_RTF_INT("ffprot", m_oFormField.prot, sCommand, hasParameter, parameter) - COMMAND_RTF_INT("ffsize", m_oFormField.sizeCheckBox, sCommand, hasParameter, parameter) - COMMAND_RTF_INT("fftypetx", m_oFormField.typetx, sCommand, hasParameter, parameter) - COMMAND_RTF_INT("ffrecalc", m_oFormField.recalc, sCommand, hasParameter, parameter) - COMMAND_RTF_INT("ffhaslistbox", m_oFormField.haslistbox, sCommand, hasParameter, parameter) - COMMAND_RTF_INT("ffmaxlen", m_oFormField.maxlen, sCommand, hasParameter, parameter) - COMMAND_RTF_INT("ffhps", m_oFormField.hps, sCommand, hasParameter, parameter) - COMMAND_RTF_INT("ffdefres", m_oFormField.defres, sCommand, hasParameter, parameter) - COMMAND_RTF_INT("ffres", m_oFormField.res, sCommand, hasParameter, parameter) + COMMAND_RTF_INT("ffownhelp", m_oFormField.ownhelp, sCommand, hasParameter, parameter) + COMMAND_RTF_INT("ffownstat", m_oFormField.ownstat, sCommand, hasParameter, parameter) + COMMAND_RTF_INT("ffprot", m_oFormField.prot, sCommand, hasParameter, parameter) + COMMAND_RTF_INT("ffsize", m_oFormField.sizeCheckBox, sCommand, hasParameter, parameter) + COMMAND_RTF_INT("fftypetx", m_oFormField.typetx, sCommand, hasParameter, parameter) + COMMAND_RTF_INT("ffrecalc", m_oFormField.recalc, sCommand, hasParameter, parameter) + COMMAND_RTF_INT("ffhaslistbox", m_oFormField.haslistbox, sCommand, hasParameter, parameter) + COMMAND_RTF_INT("ffmaxlen", m_oFormField.maxlen, sCommand, hasParameter, parameter) + COMMAND_RTF_INT("ffhps", m_oFormField.hps, sCommand, hasParameter, parameter) + COMMAND_RTF_INT("ffdefres", m_oFormField.defres, sCommand, hasParameter, parameter) + COMMAND_RTF_INT("ffres", m_oFormField.res, sCommand, hasParameter, parameter) return true; } @@ -2648,9 +2709,9 @@ bool RtfOleReader::ExecuteCommand(RtfDocument& oDocument, RtfReader& oReader, st return true; COMMAND_RTF_INT ( "objw", m_oOle.m_nWidth, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "objh", m_oOle.m_nHeight, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT ( "objemb", m_oOle.m_eOleType, sCommand, true, RtfOle::ot_emb ) - COMMAND_RTF_INT ( "objlink", m_oOle.m_eOleType, sCommand, true, RtfOle::ot_link ) + COMMAND_RTF_INT ( "objh", m_oOle.m_nHeight, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT ( "objemb", m_oOle.m_eOleType, sCommand, true, RtfOle::ot_emb ) + COMMAND_RTF_INT ( "objlink", m_oOle.m_eOleType, sCommand, true, RtfOle::ot_link ) else if ( "objclass" == sCommand ) { @@ -2996,6 +3057,12 @@ void RtfShapeReader::ShapePropertyReader::ShapePropertyValueReader::PopState( Rt else if ( L"lineEndArrowLength" == m_sPropName ) m_oShape.m_nLineEndArrowLength = nValue; else if ( L"lineWidth" == m_sPropName ) m_oShape.m_nLineWidth = nValue; else if ( L"lineDashing" == m_sPropName ) m_oShape.m_nLineDashing = nValue; + + else if (L"borderTopColor" == m_sPropName) m_oShape.m_nBorderTopColor = nValue; + else if (L"borderLeftColor" == m_sPropName) m_oShape.m_nBorderLeftColor = nValue; + else if (L"borderBottomColor" == m_sPropName) m_oShape.m_nBorderBottomColor = nValue; + else if (L"borderRightColor" == m_sPropName) m_oShape.m_nBorderRightColor= nValue; + else if ( L"cxstyle" == m_sPropName ) m_oShape.m_nConnectorStyle = nValue; else if ( L"cxk" == m_sPropName ) m_oShape.m_nConnectionType = nValue; //office signature @@ -3153,7 +3220,6 @@ RtfOldListReader::RtfOldListReader( RtfOldList& oTarget) : m_oTarget(oTarget) } void RtfOldListReader::ExitReader( RtfDocument& oDocument, RtfReader& oReader ) { - m_oTarget.m_oLevelText->m_oProperty.m_oCharProperty = oReader.m_oState->m_oCharProp; } bool RtfOldListReader::ExecuteCommand( RtfDocument& oDocument, RtfReader& oReader, std::string sKey, bool bHasPar, int nPar ) { @@ -3165,29 +3231,29 @@ bool RtfOldListReader::ExecuteCommand( RtfDocument& oDocument, RtfReader& oReade m_oTarget.m_nIlvl = 0; } COMMAND_RTF_INT ( "pnf", oReader.m_oState->m_oCharProp.m_nFont, sKey, bHasPar, nPar ) - COMMAND_RTF_INT ( "pnfs", oReader.m_oState->m_oCharProp.m_nFontSize, sKey, bHasPar, nPar ) - COMMAND_RTF_BOOL( "pnb", oReader.m_oState->m_oCharProp.m_bBold, sKey, bHasPar, nPar ) - COMMAND_RTF_BOOL( "pni", oReader.m_oState->m_oCharProp.m_bItalic, sKey, bHasPar, nPar ) - COMMAND_RTF_BOOL( "pncaps", oReader.m_oState->m_oCharProp.m_bCaps, sKey, bHasPar, nPar ) - COMMAND_RTF_BOOL( "pnstrike", oReader.m_oState->m_oCharProp.m_bStrike, sKey, bHasPar, nPar ) - COMMAND_RTF_INT ( "pnul", oReader.m_oState->m_oCharProp.m_eUnderStyle, sKey, true, RtfCharProperty::uls_Single) - COMMAND_RTF_INT ( "pnuld", oReader.m_oState->m_oCharProp.m_eUnderStyle, sKey, true, RtfCharProperty::uls_Dashed) - COMMAND_RTF_INT ( "pnuldash", oReader.m_oState->m_oCharProp.m_eUnderStyle, sKey, true, RtfCharProperty::uls_Dash_dotted) - COMMAND_RTF_INT ( "pnuldashdd", oReader.m_oState->m_oCharProp.m_eUnderStyle, sKey, true, RtfCharProperty::uls_Dash_dot_dotted) - COMMAND_RTF_INT ( "pnulth", oReader.m_oState->m_oCharProp.m_eUnderStyle, sKey, true, RtfCharProperty::uls_Thick) - COMMAND_RTF_INT ( "pnulwave", oReader.m_oState->m_oCharProp.m_eUnderStyle, sKey, true, RtfCharProperty::uls_Wave) - COMMAND_RTF_INT ( "pnuldb", oReader.m_oState->m_oCharProp.m_eUnderStyle, sKey, true, RtfCharProperty::uls_Double) - COMMAND_RTF_INT ( "pnulnone", oReader.m_oState->m_oCharProp.m_eUnderStyle, sKey, true, RtfCharProperty::uls_none) - COMMAND_RTF_INT ( "pnulnone", oReader.m_oState->m_oCharProp.m_eUnderStyle, sKey, true, RtfCharProperty::uls_Word) - - COMMAND_RTF_INT ( "pnindent", m_oTarget.m_oLevelText->m_oProperty.m_nIndLeft, sKey, bHasPar, nPar ) - COMMAND_RTF_INT ( "pnsp", m_oTarget.m_oLevelText->m_oProperty.m_nIndLeft, sKey, bHasPar, nPar ) - COMMAND_RTF_INT ( "pnstart", m_oTarget.m_oLevelText->m_oProperty.m_nIndLeft, sKey, bHasPar, nPar ) - COMMAND_RTF_INT ( "pnhang", m_oTarget.m_oLevelText->m_oProperty.m_nIndLeft, sKey, bHasPar, nPar ) - - COMMAND_RTF_INT ( "pnqc", m_oTarget.m_eLevelJust, sKey, true, RtfOldList::lj_center ) - COMMAND_RTF_INT ( "pnql", m_oTarget.m_eLevelJust, sKey, true, RtfOldList::lj_left ) - COMMAND_RTF_INT ( "pnqr", m_oTarget.m_eLevelJust, sKey, true, RtfOldList::lj_right ) + COMMAND_RTF_INT ( "pnfs", oReader.m_oState->m_oCharProp.m_nFontSize, sKey, bHasPar, nPar ) + COMMAND_RTF_BOOL( "pnb", oReader.m_oState->m_oCharProp.m_bBold, sKey, bHasPar, nPar ) + COMMAND_RTF_BOOL( "pni", oReader.m_oState->m_oCharProp.m_bItalic, sKey, bHasPar, nPar ) + COMMAND_RTF_BOOL( "pncaps", oReader.m_oState->m_oCharProp.m_bCaps, sKey, bHasPar, nPar ) + COMMAND_RTF_BOOL( "pnstrike", oReader.m_oState->m_oCharProp.m_bStrike, sKey, bHasPar, nPar ) + COMMAND_RTF_INT ( "pnul", oReader.m_oState->m_oCharProp.m_eUnderStyle, sKey, true, RtfCharProperty::uls_Single) + COMMAND_RTF_INT ( "pnuld", oReader.m_oState->m_oCharProp.m_eUnderStyle, sKey, true, RtfCharProperty::uls_Dashed) + COMMAND_RTF_INT ( "pnuldash", oReader.m_oState->m_oCharProp.m_eUnderStyle, sKey, true, RtfCharProperty::uls_Dash_dotted) + COMMAND_RTF_INT ( "pnuldashdd", oReader.m_oState->m_oCharProp.m_eUnderStyle, sKey, true, RtfCharProperty::uls_Dash_dot_dotted) + COMMAND_RTF_INT ( "pnulth", oReader.m_oState->m_oCharProp.m_eUnderStyle, sKey, true, RtfCharProperty::uls_Thick) + COMMAND_RTF_INT ( "pnulwave", oReader.m_oState->m_oCharProp.m_eUnderStyle, sKey, true, RtfCharProperty::uls_Wave) + COMMAND_RTF_INT ( "pnuldb", oReader.m_oState->m_oCharProp.m_eUnderStyle, sKey, true, RtfCharProperty::uls_Double) + COMMAND_RTF_INT ( "pnulnone", oReader.m_oState->m_oCharProp.m_eUnderStyle, sKey, true, RtfCharProperty::uls_none) + COMMAND_RTF_INT ( "pnulnone", oReader.m_oState->m_oCharProp.m_eUnderStyle, sKey, true, RtfCharProperty::uls_Word) + + COMMAND_RTF_INT ( "pnindent", m_oTarget.m_oLevelText->m_oProperty.m_nIndLeft, sKey, bHasPar, nPar ) + COMMAND_RTF_INT ( "pnsp", m_oTarget.m_oLevelText->m_oProperty.m_nIndLeft, sKey, bHasPar, nPar ) + COMMAND_RTF_INT ( "pnstart", m_oTarget.m_oLevelText->m_oProperty.m_nIndLeft, sKey, bHasPar, nPar ) + COMMAND_RTF_INT ( "pnhang", m_oTarget.m_oLevelText->m_oProperty.m_nIndLeft, sKey, bHasPar, nPar ) + + COMMAND_RTF_INT ( "pnqc", m_oTarget.m_eLevelJust, sKey, true, RtfOldList::lj_center ) + COMMAND_RTF_INT ( "pnql", m_oTarget.m_eLevelJust, sKey, true, RtfOldList::lj_left ) + COMMAND_RTF_INT ( "pnqr", m_oTarget.m_eLevelJust, sKey, true, RtfOldList::lj_right ) else if ( "pntxtb" == sKey ) { @@ -3774,8 +3840,31 @@ bool RtfPictureReader::ExecuteCommand(RtfDocument& oDocument, RtfReader& oReader oReader.m_oLex.ReadBytes( parameter, &m_pbBin );//читаем сразу байты, потому что если между ними и был пробел, то он пропустится в RtfLex::parseKeyword } } + else if ("brdrt" == sCommand) m_eInternalState = is_borderTop; + else if ("brdrb" == sCommand) m_eInternalState = is_borderBottom; + else if ("brdrl" == sCommand) m_eInternalState = is_borderLeft; + else if ("brdrr" == sCommand) m_eInternalState = is_borderRight; else - return false; + { + bool bResult = false; + + switch (m_eInternalState) + { + case is_borderBottom: + bResult = RtfBorderCommand::ExecuteCommand(oDocument, oReader, sCommand, hasParameter, parameter, m_oShape.m_oPicture->m_oBorderBottom); + break; + case is_borderLeft: + bResult = RtfBorderCommand::ExecuteCommand(oDocument, oReader, sCommand, hasParameter, parameter, m_oShape.m_oPicture->m_oBorderLeft); + break; + case is_borderRight: + bResult = RtfBorderCommand::ExecuteCommand(oDocument, oReader, sCommand, hasParameter, parameter, m_oShape.m_oPicture->m_oBorderRight); + break; + case is_borderTop: + bResult = RtfBorderCommand::ExecuteCommand(oDocument, oReader, sCommand, hasParameter, parameter, m_oShape.m_oPicture->m_oBorderTop); + break; + } + return bResult; + } return true; } void RtfPictureReader::ExecuteText(RtfDocument& oDocument, RtfReader& oReader, std::wstring sText) @@ -3990,7 +4079,7 @@ void RtfParagraphPropDestination::AddItem( RtfParagraphPtr oItem, RtfReader& oRe { if ( nCurItap > 0 ) //Если до этого были только параграфы в таблицах - завершаем таблицу { - if (bEndRow) EndRows(oReader); //ê¡ñ¿ó¿ñπá½∞¡á∩ »α«úαá¼¼á.rtf + if (bEndRow) EndRows(oReader); RtfTablePtr oNewTable ( new RtfTable() ); oNewTable->m_oProperty = oCurRowProperty; @@ -4256,15 +4345,15 @@ bool RtfParagraphPropDestination::ExecuteCommand(RtfDocument& oDocument, RtfRead COMMAND_RTF_INT ( "uc", oReader.m_oState->m_nUnicodeClean, sCommand, hasParameter, parameter) //Tab todoooo перенести в ParagrProps (trackchanges) - COMMAND_RTF_INT ( "tldot", m_oCurTab.m_eLeader, sCommand, true, RtfTab::tl_dot ) - COMMAND_RTF_INT ( "tlmdot", m_oCurTab.m_eLeader, sCommand, true, RtfTab::tl_mdot ) - COMMAND_RTF_INT ( "tlhyph", m_oCurTab.m_eLeader, sCommand, true, RtfTab::tl_hyph ) - COMMAND_RTF_INT ( "tlul", m_oCurTab.m_eLeader, sCommand, true, RtfTab::tl_ul ) - COMMAND_RTF_INT ( "tlth", m_oCurTab.m_eLeader, sCommand, true, RtfTab::tl_ul ) - COMMAND_RTF_INT ( "tqr", m_oCurTab.m_eKind , sCommand, true, RtfTab::tk_tqr ) - COMMAND_RTF_INT ( "tqc", m_oCurTab.m_eKind , sCommand, true, RtfTab::tk_tqc ) - COMMAND_RTF_INT ( "tqdec", m_oCurTab.m_eKind , sCommand, true, RtfTab::tk_tqdec ) - else if ( "tb" == sCommand ) + COMMAND_RTF_INT ( "tldot", m_oCurTab.m_eLeader, sCommand, true, RtfTab::tl_dot ) + COMMAND_RTF_INT ( "tlmdot", m_oCurTab.m_eLeader, sCommand, true, RtfTab::tl_mdot ) + COMMAND_RTF_INT ( "tlhyph", m_oCurTab.m_eLeader, sCommand, true, RtfTab::tl_hyph ) + COMMAND_RTF_INT ( "tlul", m_oCurTab.m_eLeader, sCommand, true, RtfTab::tl_ul ) + COMMAND_RTF_INT ( "tlth", m_oCurTab.m_eLeader, sCommand, true, RtfTab::tl_ul ) + COMMAND_RTF_INT ( "tqr", m_oCurTab.m_eKind , sCommand, true, RtfTab::tk_tqr ) + COMMAND_RTF_INT ( "tqc", m_oCurTab.m_eKind , sCommand, true, RtfTab::tk_tqc ) + COMMAND_RTF_INT ( "tqdec", m_oCurTab.m_eKind , sCommand, true, RtfTab::tk_tqdec ) + else if ( "tb" == sCommand ) { if ( hasParameter ) { @@ -4313,53 +4402,53 @@ bool RtfParagraphPropDestination::ExecuteCommand(RtfDocument& oDocument, RtfRead ; COMMAND_RTF_INT ( "yts", oReader.m_oState->m_oParagraphProp.m_nTableStyle, sCommand, hasParameter, parameter ) - COMMAND_RTF_BOOL( "tscfirstrow", oReader.m_oState->m_oParagraphProp.m_bStyleFirstRow, sCommand, hasParameter, parameter ) - COMMAND_RTF_BOOL( "tscfirstrow", oReader.m_oState->m_oCellProperty.m_bStyleFirstRow, sCommand, hasParameter, parameter ) - COMMAND_RTF_BOOL( "tscfirstrow", oReader.m_oState->m_oRowProperty.m_bStyleFirstRow, sCommand, hasParameter, parameter ) + COMMAND_RTF_BOOL( "tscfirstrow", oReader.m_oState->m_oParagraphProp.m_bStyleFirstRow, sCommand, hasParameter, parameter ) + COMMAND_RTF_BOOL( "tscfirstrow", oReader.m_oState->m_oCellProperty.m_bStyleFirstRow, sCommand, hasParameter, parameter ) + COMMAND_RTF_BOOL( "tscfirstrow", oReader.m_oState->m_oRowProperty.m_bStyleFirstRow, sCommand, hasParameter, parameter ) - COMMAND_RTF_BOOL( "tsclastrow", oReader.m_oState->m_oParagraphProp.m_bStyleLastRow, sCommand, hasParameter, parameter ) - COMMAND_RTF_BOOL( "tsclastrow", oReader.m_oState->m_oCellProperty.m_bStyleLastRow, sCommand, hasParameter, parameter ) - COMMAND_RTF_BOOL( "tsclastrow", oReader.m_oState->m_oRowProperty.m_bStyleLastRow, sCommand, hasParameter, parameter ) + COMMAND_RTF_BOOL( "tsclastrow", oReader.m_oState->m_oParagraphProp.m_bStyleLastRow, sCommand, hasParameter, parameter ) + COMMAND_RTF_BOOL( "tsclastrow", oReader.m_oState->m_oCellProperty.m_bStyleLastRow, sCommand, hasParameter, parameter ) + COMMAND_RTF_BOOL( "tsclastrow", oReader.m_oState->m_oRowProperty.m_bStyleLastRow, sCommand, hasParameter, parameter ) - COMMAND_RTF_BOOL( "tscfirstcol", oReader.m_oState->m_oParagraphProp.m_bStyleFirstCollumn, sCommand, hasParameter, parameter ) - COMMAND_RTF_BOOL( "tscfirstcol", oReader.m_oState->m_oCellProperty.m_bStyleFirstCol, sCommand, hasParameter, parameter ) - COMMAND_RTF_BOOL( "tscfirstcol", oReader.m_oState->m_oRowProperty.m_bStyleFirstCol, sCommand, hasParameter, parameter ) + COMMAND_RTF_BOOL( "tscfirstcol", oReader.m_oState->m_oParagraphProp.m_bStyleFirstCollumn, sCommand, hasParameter, parameter ) + COMMAND_RTF_BOOL( "tscfirstcol", oReader.m_oState->m_oCellProperty.m_bStyleFirstCol, sCommand, hasParameter, parameter ) + COMMAND_RTF_BOOL( "tscfirstcol", oReader.m_oState->m_oRowProperty.m_bStyleFirstCol, sCommand, hasParameter, parameter ) - COMMAND_RTF_BOOL( "tsclastcol", oReader.m_oState->m_oParagraphProp.m_bStyleLastCollumn, sCommand, hasParameter, parameter ) - COMMAND_RTF_BOOL( "tsclastcol", oReader.m_oState->m_oCellProperty.m_bStyleLastCol, sCommand, hasParameter, parameter ) - COMMAND_RTF_BOOL( "tsclastcol", oReader.m_oState->m_oRowProperty.m_bStyleLastCol, sCommand, hasParameter, parameter ) + COMMAND_RTF_BOOL( "tsclastcol", oReader.m_oState->m_oParagraphProp.m_bStyleLastCollumn, sCommand, hasParameter, parameter ) + COMMAND_RTF_BOOL( "tsclastcol", oReader.m_oState->m_oCellProperty.m_bStyleLastCol, sCommand, hasParameter, parameter ) + COMMAND_RTF_BOOL( "tsclastcol", oReader.m_oState->m_oRowProperty.m_bStyleLastCol, sCommand, hasParameter, parameter ) - COMMAND_RTF_BOOL( "tscbandhorzodd", oReader.m_oState->m_oParagraphProp.m_bStyleOddRowBand, sCommand, hasParameter, parameter ) - COMMAND_RTF_BOOL( "tscbandhorzodd", oReader.m_oState->m_oCellProperty.m_bStyleOddRowBand, sCommand, hasParameter, parameter ) - COMMAND_RTF_BOOL( "tscbandhorzodd", oReader.m_oState->m_oRowProperty.m_bStyleOddRowBand, sCommand, hasParameter, parameter ) + COMMAND_RTF_BOOL( "tscbandhorzodd", oReader.m_oState->m_oParagraphProp.m_bStyleOddRowBand, sCommand, hasParameter, parameter ) + COMMAND_RTF_BOOL( "tscbandhorzodd", oReader.m_oState->m_oCellProperty.m_bStyleOddRowBand, sCommand, hasParameter, parameter ) + COMMAND_RTF_BOOL( "tscbandhorzodd", oReader.m_oState->m_oRowProperty.m_bStyleOddRowBand, sCommand, hasParameter, parameter ) - COMMAND_RTF_BOOL( "tscbandhorzeven", oReader.m_oState->m_oParagraphProp.m_bStyleEvenRowBand, sCommand, hasParameter, parameter ) - COMMAND_RTF_BOOL( "tscbandhorzeven", oReader.m_oState->m_oCellProperty.m_bStyleEvenRowBand, sCommand, hasParameter, parameter ) - COMMAND_RTF_BOOL( "tscbandhorzeven", oReader.m_oState->m_oRowProperty.m_bStyleEvenRowBand, sCommand, hasParameter, parameter ) + COMMAND_RTF_BOOL( "tscbandhorzeven", oReader.m_oState->m_oParagraphProp.m_bStyleEvenRowBand, sCommand, hasParameter, parameter ) + COMMAND_RTF_BOOL( "tscbandhorzeven", oReader.m_oState->m_oCellProperty.m_bStyleEvenRowBand, sCommand, hasParameter, parameter ) + COMMAND_RTF_BOOL( "tscbandhorzeven", oReader.m_oState->m_oRowProperty.m_bStyleEvenRowBand, sCommand, hasParameter, parameter ) - COMMAND_RTF_BOOL( "tscbandvertodd", oReader.m_oState->m_oParagraphProp.m_bStyleOddColBand, sCommand, hasParameter, parameter ) - COMMAND_RTF_BOOL( "tscbandvertodd", oReader.m_oState->m_oCellProperty.m_bStyleOddColBand, sCommand, hasParameter, parameter ) - COMMAND_RTF_BOOL( "tscbandvertodd", oReader.m_oState->m_oRowProperty.m_bStyleOddColBand, sCommand, hasParameter, parameter ) + COMMAND_RTF_BOOL( "tscbandvertodd", oReader.m_oState->m_oParagraphProp.m_bStyleOddColBand, sCommand, hasParameter, parameter ) + COMMAND_RTF_BOOL( "tscbandvertodd", oReader.m_oState->m_oCellProperty.m_bStyleOddColBand, sCommand, hasParameter, parameter ) + COMMAND_RTF_BOOL( "tscbandvertodd", oReader.m_oState->m_oRowProperty.m_bStyleOddColBand, sCommand, hasParameter, parameter ) - COMMAND_RTF_BOOL( "tscbandverteven", oReader.m_oState->m_oParagraphProp.m_bStyleEvenColBand, sCommand, hasParameter, parameter ) - COMMAND_RTF_BOOL( "tscbandverteven", oReader.m_oState->m_oCellProperty.m_bStyleEvenColBand, sCommand, hasParameter, parameter ) - COMMAND_RTF_BOOL( "tscbandverteven", oReader.m_oState->m_oRowProperty.m_bStyleEvenColBand, sCommand, hasParameter, parameter ) + COMMAND_RTF_BOOL( "tscbandverteven", oReader.m_oState->m_oParagraphProp.m_bStyleEvenColBand, sCommand, hasParameter, parameter ) + COMMAND_RTF_BOOL( "tscbandverteven", oReader.m_oState->m_oCellProperty.m_bStyleEvenColBand, sCommand, hasParameter, parameter ) + COMMAND_RTF_BOOL( "tscbandverteven", oReader.m_oState->m_oRowProperty.m_bStyleEvenColBand, sCommand, hasParameter, parameter ) - COMMAND_RTF_BOOL( "tscnwcell", oReader.m_oState->m_oParagraphProp.m_bStyleNWCell, sCommand, hasParameter, parameter ) - COMMAND_RTF_BOOL( "tscnwcell", oReader.m_oState->m_oCellProperty.m_bStyleNWCell, sCommand, hasParameter, parameter ) - COMMAND_RTF_BOOL( "tscnwcell", oReader.m_oState->m_oRowProperty.m_bStyleNWCell, sCommand, hasParameter, parameter ) + COMMAND_RTF_BOOL( "tscnwcell", oReader.m_oState->m_oParagraphProp.m_bStyleNWCell, sCommand, hasParameter, parameter ) + COMMAND_RTF_BOOL( "tscnwcell", oReader.m_oState->m_oCellProperty.m_bStyleNWCell, sCommand, hasParameter, parameter ) + COMMAND_RTF_BOOL( "tscnwcell", oReader.m_oState->m_oRowProperty.m_bStyleNWCell, sCommand, hasParameter, parameter ) - COMMAND_RTF_BOOL( "tscnecell", oReader.m_oState->m_oParagraphProp.m_bStyleNECell, sCommand, hasParameter, parameter ) - COMMAND_RTF_BOOL( "tscnecell", oReader.m_oState->m_oCellProperty.m_bStyleNECell, sCommand, hasParameter, parameter ) - COMMAND_RTF_BOOL( "tscnecell", oReader.m_oState->m_oRowProperty.m_bStyleNECell, sCommand, hasParameter, parameter ) + COMMAND_RTF_BOOL( "tscnecell", oReader.m_oState->m_oParagraphProp.m_bStyleNECell, sCommand, hasParameter, parameter ) + COMMAND_RTF_BOOL( "tscnecell", oReader.m_oState->m_oCellProperty.m_bStyleNECell, sCommand, hasParameter, parameter ) + COMMAND_RTF_BOOL( "tscnecell", oReader.m_oState->m_oRowProperty.m_bStyleNECell, sCommand, hasParameter, parameter ) - COMMAND_RTF_BOOL( "tscswcell", oReader.m_oState->m_oParagraphProp.m_bStyleSWCell, sCommand, hasParameter, parameter ) - COMMAND_RTF_BOOL( "tscswcell", oReader.m_oState->m_oCellProperty.m_bStyleSWCell, sCommand, hasParameter, parameter ) - COMMAND_RTF_BOOL( "tscswcell", oReader.m_oState->m_oRowProperty.m_bStyleSWCell, sCommand, hasParameter, parameter ) + COMMAND_RTF_BOOL( "tscswcell", oReader.m_oState->m_oParagraphProp.m_bStyleSWCell, sCommand, hasParameter, parameter ) + COMMAND_RTF_BOOL( "tscswcell", oReader.m_oState->m_oCellProperty.m_bStyleSWCell, sCommand, hasParameter, parameter ) + COMMAND_RTF_BOOL( "tscswcell", oReader.m_oState->m_oRowProperty.m_bStyleSWCell, sCommand, hasParameter, parameter ) - COMMAND_RTF_BOOL( "tscsecell", oReader.m_oState->m_oParagraphProp.m_bStyleSECell, sCommand, hasParameter, parameter ) - COMMAND_RTF_BOOL( "tscsecell", oReader.m_oState->m_oCellProperty.m_bStyleSECell, sCommand, hasParameter, parameter ) - COMMAND_RTF_BOOL( "tscsecell", oReader.m_oState->m_oRowProperty.m_bStyleSECell, sCommand, hasParameter, parameter ) + COMMAND_RTF_BOOL( "tscsecell", oReader.m_oState->m_oParagraphProp.m_bStyleSECell, sCommand, hasParameter, parameter ) + COMMAND_RTF_BOOL( "tscsecell", oReader.m_oState->m_oCellProperty.m_bStyleSECell, sCommand, hasParameter, parameter ) + COMMAND_RTF_BOOL( "tscsecell", oReader.m_oState->m_oRowProperty.m_bStyleSECell, sCommand, hasParameter, parameter ) //Math else if ( "mmath" == sCommand ) { @@ -4619,8 +4708,8 @@ bool RtfParagraphPropDestination::ExecuteCommand(RtfDocument& oDocument, RtfRead //m_oCurParagraph = RtfParagraphPtr(new RtfParagraph()); } COMMAND_RTF_SPECIAL_CHAR( "column", m_oCurParagraph, sCommand, hasParameter, RtfCharSpecial::rsc_column ) - COMMAND_RTF_SPECIAL_CHAR( "line", m_oCurParagraph, sCommand, hasParameter, RtfCharSpecial::rsc_line ) - else if ( "lbr" == sCommand ) + COMMAND_RTF_SPECIAL_CHAR( "line", m_oCurParagraph, sCommand, hasParameter, RtfCharSpecial::rsc_line ) + else if ( "lbr" == sCommand ) { if ( hasParameter ) { @@ -4632,8 +4721,8 @@ bool RtfParagraphPropDestination::ExecuteCommand(RtfDocument& oDocument, RtfRead } } COMMAND_RTF_SPECIAL_CHAR( "softpage", m_oCurParagraph, sCommand, hasParameter, RtfCharSpecial::rsc_softpage ) - COMMAND_RTF_SPECIAL_CHAR( "softcol", m_oCurParagraph, sCommand, hasParameter, RtfCharSpecial::rsc_softcol ) - COMMAND_RTF_SPECIAL_CHAR( "softline", m_oCurParagraph, sCommand, hasParameter, RtfCharSpecial::rsc_softline ) + COMMAND_RTF_SPECIAL_CHAR( "softcol", m_oCurParagraph, sCommand, hasParameter, RtfCharSpecial::rsc_softcol ) + COMMAND_RTF_SPECIAL_CHAR( "softline", m_oCurParagraph, sCommand, hasParameter, RtfCharSpecial::rsc_softline ) else if ( "softlheight" == sCommand ) { @@ -4653,8 +4742,8 @@ bool RtfParagraphPropDestination::ExecuteCommand(RtfDocument& oDocument, RtfRead ExecuteNumberChar( oDocument, oReader, oAbstrReader, 150, 0xD1 ); // bullet Word for Windows - 150 ; Apple Macintosh - 0xD1 COMMAND_RTF_SPECIAL_CHAR( "emspace", m_oCurParagraph, sCommand, hasParameter, RtfCharSpecial::rsc_emspace ) - COMMAND_RTF_SPECIAL_CHAR( "enspace", m_oCurParagraph, sCommand, hasParameter, RtfCharSpecial::rsc_enspace ) - COMMAND_RTF_SPECIAL_CHAR( "qmspace", m_oCurParagraph, sCommand, hasParameter, RtfCharSpecial::rsc_qmspace ) + COMMAND_RTF_SPECIAL_CHAR( "enspace", m_oCurParagraph, sCommand, hasParameter, RtfCharSpecial::rsc_enspace ) + COMMAND_RTF_SPECIAL_CHAR( "qmspace", m_oCurParagraph, sCommand, hasParameter, RtfCharSpecial::rsc_qmspace ) else if ( "bullet" == sCommand ) ExecuteNumberChar( oDocument, oReader, oAbstrReader, 149, 0xA5 ); // bullet Word for Windows - 149 ; Apple Macintosh - 0xA5 @@ -4668,14 +4757,14 @@ bool RtfParagraphPropDestination::ExecuteCommand(RtfDocument& oDocument, RtfRead ExecuteNumberChar( oDocument, oReader, oAbstrReader, 148, 0xD3 ); // bullet Word for Windows - 148 ; Apple Macintosh - 0xD3 COMMAND_RTF_SPECIAL_CHAR( "|", m_oCurParagraph, sCommand, hasParameter, RtfCharSpecial::rsc_Formula ) - COMMAND_RTF_SPECIAL_CHAR( "~", m_oCurParagraph, sCommand, hasParameter, RtfCharSpecial::rsc_NonBrSpace ) - COMMAND_RTF_SPECIAL_CHAR( "-", m_oCurParagraph, sCommand, hasParameter, RtfCharSpecial::rsc_OptHyphen ) - COMMAND_RTF_SPECIAL_CHAR( "_", m_oCurParagraph, sCommand, hasParameter, RtfCharSpecial::rsc_NonBrHyphen ) - COMMAND_RTF_SPECIAL_CHAR( ":", m_oCurParagraph, sCommand, hasParameter, RtfCharSpecial::rsc_SubEntry ) - COMMAND_RTF_SPECIAL_CHAR( "zwbo", m_oCurParagraph, sCommand, hasParameter, RtfCharSpecial::rsc_zwbo ) - COMMAND_RTF_SPECIAL_CHAR( "zwnbo", m_oCurParagraph, sCommand, hasParameter, RtfCharSpecial::rsc_zwnbo ) - COMMAND_RTF_SPECIAL_CHAR( "zwj", m_oCurParagraph, sCommand, hasParameter, RtfCharSpecial::rsc_zwj ) - COMMAND_RTF_SPECIAL_CHAR( "zwnj", m_oCurParagraph, sCommand, hasParameter, RtfCharSpecial::rsc_zwnj ) + COMMAND_RTF_SPECIAL_CHAR( "~", m_oCurParagraph, sCommand, hasParameter, RtfCharSpecial::rsc_NonBrSpace ) + COMMAND_RTF_SPECIAL_CHAR( "-", m_oCurParagraph, sCommand, hasParameter, RtfCharSpecial::rsc_OptHyphen ) + COMMAND_RTF_SPECIAL_CHAR( "_", m_oCurParagraph, sCommand, hasParameter, RtfCharSpecial::rsc_NonBrHyphen ) + COMMAND_RTF_SPECIAL_CHAR( ":", m_oCurParagraph, sCommand, hasParameter, RtfCharSpecial::rsc_SubEntry ) + COMMAND_RTF_SPECIAL_CHAR( "zwbo", m_oCurParagraph, sCommand, hasParameter, RtfCharSpecial::rsc_zwbo ) + COMMAND_RTF_SPECIAL_CHAR( "zwnbo", m_oCurParagraph, sCommand, hasParameter, RtfCharSpecial::rsc_zwnbo ) + COMMAND_RTF_SPECIAL_CHAR( "zwj", m_oCurParagraph, sCommand, hasParameter, RtfCharSpecial::rsc_zwj ) + COMMAND_RTF_SPECIAL_CHAR( "zwnj", m_oCurParagraph, sCommand, hasParameter, RtfCharSpecial::rsc_zwnj ) else if ( "oldcprops" == sCommand ) { @@ -4967,13 +5056,13 @@ bool RtfStyleTableReader::RtfStyleReader::ExecuteCommand(RtfDocument& oDocument, } } COMMAND_RTF_INT( "sbasedon", m_oCurStyle->m_nBasedOn, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT( "snext", m_oCurStyle->m_nNext, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT( "slink", m_oCurStyle->m_nLink, sCommand, hasParameter, parameter ) - COMMAND_RTF_BOOL( "sqformat", m_oCurStyle->m_bQFormat, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT( "spriority", m_oCurStyle->m_nPriority, sCommand, hasParameter, parameter ) - COMMAND_RTF_BOOL( "sunhideused", m_oCurStyle->m_bUnhiddenWhenUse, sCommand, hasParameter, parameter ) - COMMAND_RTF_BOOL( "slocked", m_oCurStyle->m_bLocked, sCommand, hasParameter, parameter ) - COMMAND_RTF_BOOL( "shidden", m_oCurStyle->m_bHidden, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT( "snext", m_oCurStyle->m_nNext, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT( "slink", m_oCurStyle->m_nLink, sCommand, hasParameter, parameter ) + COMMAND_RTF_BOOL( "sqformat", m_oCurStyle->m_bQFormat, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT( "spriority", m_oCurStyle->m_nPriority, sCommand, hasParameter, parameter ) + COMMAND_RTF_BOOL( "sunhideused", m_oCurStyle->m_bUnhiddenWhenUse, sCommand, hasParameter, parameter ) + COMMAND_RTF_BOOL( "slocked", m_oCurStyle->m_bLocked, sCommand, hasParameter, parameter ) + COMMAND_RTF_BOOL( "shidden", m_oCurStyle->m_bHidden, sCommand, hasParameter, parameter ) else if( "ssemihidden" == sCommand ) { if( true == hasParameter && 0 == parameter) @@ -4982,8 +5071,8 @@ bool RtfStyleTableReader::RtfStyleReader::ExecuteCommand(RtfDocument& oDocument, m_oCurStyle->m_nSemiHidden = 1; } COMMAND_RTF_BOOL( "spersonal", m_oCurStyle->m_bPersonal, sCommand, hasParameter, parameter ) - COMMAND_RTF_BOOL( "scompose", m_oCurStyle->m_bCompose, sCommand, hasParameter, parameter ) - COMMAND_RTF_BOOL( "sreply", m_oCurStyle->m_bReply, sCommand, hasParameter, parameter ) + COMMAND_RTF_BOOL( "scompose", m_oCurStyle->m_bCompose, sCommand, hasParameter, parameter ) + COMMAND_RTF_BOOL( "sreply", m_oCurStyle->m_bReply, sCommand, hasParameter, parameter ) //tableStyleCommands //else if( "tscellpaddt" == sCommand ) @@ -5237,26 +5326,30 @@ bool RtfListTableReader::ListReader::ListLevelReader::ExecuteCommand(RtfDocument if( "listlevel" == sCommand ) ; COMMAND_RTF_INT( "levelnfc", m_oListLevelProp.m_nNumberType, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT( "levelnfcn", m_oListLevelProp.m_nNumberType, sCommand, hasParameter, parameter ) - COMMAND_RTF_BOOL( "lvltentative", m_oListLevelProp.m_bTentative, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT( "leveljc", m_oListLevelProp.m_nJustification, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT( "leveljcn", m_oListLevelProp.m_nJustification, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT( "levelfollow", m_oListLevelProp.m_nFollow, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT( "levelstartat", m_oListLevelProp.m_nStart, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT( "levelnorestart", m_oListLevelProp.m_nNoRestart, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT( "levellegal", m_oListLevelProp.m_nLegal, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT( "levelpicture", m_oListLevelProp.m_nPictureIndex, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT( "levelspace", m_oListLevelProp.m_nSpace, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT( "levelindent", m_oListLevelProp.m_nIndent, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT( "li", m_oListLevelProp.m_nIndent, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT( "lin", m_oListLevelProp.m_nIndentStart, sCommand, hasParameter, parameter ) - COMMAND_RTF_INT( "fi", m_oListLevelProp.m_nFirstIndent, sCommand, hasParameter, parameter ) - else if( "tx" == sCommand ) + COMMAND_RTF_INT( "levelnfcn", m_oListLevelProp.m_nNumberType, sCommand, hasParameter, parameter ) + COMMAND_RTF_BOOL( "lvltentative", m_oListLevelProp.m_bTentative, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT( "leveljc", m_oListLevelProp.m_nJustification, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT( "leveljcn", m_oListLevelProp.m_nJustification, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT( "levelfollow", m_oListLevelProp.m_nFollow, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT( "levelstartat", m_oListLevelProp.m_nStart, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT( "levelnorestart", m_oListLevelProp.m_nNoRestart, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT( "levellegal", m_oListLevelProp.m_nLegal, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT( "levelpicture", m_oListLevelProp.m_nPictureIndex, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT( "levelspace", m_oListLevelProp.m_nSpace, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT( "levelindent", m_oListLevelProp.m_nIndent, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT( "li", m_oListLevelProp.m_nIndent, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT( "lin", m_oListLevelProp.m_nIndentStart, sCommand, hasParameter, parameter ) + COMMAND_RTF_INT( "fi", m_oListLevelProp.m_nFirstIndent, sCommand, hasParameter, parameter ) + else if ("jclisttab" == sCommand) + { + } + else if( "tx" == sCommand) { if( true == hasParameter ) { RtfTab oNewTab; oNewTab.m_nTab = parameter; + oNewTab.m_eKind = RtfTab::tk_tqnum; m_oListLevelProp.m_oTabs.m_aTabs.push_back( oNewTab ); } } @@ -5280,7 +5373,6 @@ bool RtfListTableReader::ListReader::ListLevelReader::ExecuteCommand(RtfDocument } void RtfListTableReader::ListReader::ListLevelReader::ExitReader( RtfDocument& oDocument, RtfReader& oReader ) { - m_oListLevelProp.m_oCharProp = oReader.m_oState->m_oCharProp; //убираем shading и border (word тоже так делает) m_oListLevelProp.m_oCharProp.m_poBorder.SetDefaultRtf(); m_oListLevelProp.m_oCharProp.m_poShading.SetDefaultRtf(); @@ -5295,10 +5387,10 @@ bool RtfListTableReader::ListReader::ExecuteCommand(RtfDocument& oDocument, RtfR if( "list" == sCommand ) ; COMMAND_RTF_INT( "listid", m_oListProp.m_nID , sCommand, hasParameter, parameter ) - COMMAND_RTF_INT( "listtemplateid", m_oListProp.m_nTemplateId , sCommand, hasParameter, parameter ) - COMMAND_RTF_BOOL( "listsimple", m_oListProp.m_nListSimple , sCommand, hasParameter, parameter ) - COMMAND_RTF_BOOL( "listhybrid", m_oListProp.m_bListHybrid , sCommand, hasParameter, parameter ) - else if( "listname" == sCommand ) + COMMAND_RTF_INT( "listtemplateid", m_oListProp.m_nTemplateId , sCommand, hasParameter, parameter ) + COMMAND_RTF_BOOL( "listsimple", m_oListProp.m_nListSimple , sCommand, hasParameter, parameter ) + COMMAND_RTF_BOOL( "listhybrid", m_oListProp.m_bListHybrid , sCommand, hasParameter, parameter ) + else if( "listname" == sCommand ) { TextReader oListNameReader( m_oListProp.m_sName ); return StartSubReader( oListNameReader, oDocument, oReader ); diff --git a/RtfFile/Format/DestinationCommand.h b/RtfFile/Format/DestinationCommand.h index 52b54f97466..e9ad39516d0 100644 --- a/RtfFile/Format/DestinationCommand.h +++ b/RtfFile/Format/DestinationCommand.h @@ -269,7 +269,6 @@ class RtfPictureReader : public RtfAbstractReader DWORD Reserved; /* Reserved (always 0) */ WORD Checksum; /* Checksum value for previous 10 WORDs */ - public: PLACEABLEMETAHEADER(); void CalculateChecksum(); @@ -277,16 +276,24 @@ class RtfPictureReader : public RtfAbstractReader std::wstring ToString(); std::wstring ByteToString( BYTE* pbData, int nSize, bool bLittleEnd = true ); }; +public: -private: + enum _InternalState { + is_normal, is_charBorder, is_borderTop, is_borderLeft, is_borderBottom, is_borderRight, is_borderBox, is_borderBar, + is_borderCellLeft, is_borderCellTop, is_borderCellRight, is_borderCellBottom, is_borderCellLR, is_borderCellRL, + is_borderRowLeft, is_borderRowTop, is_borderRowRight, is_borderRowBottom, is_borderRowVer, is_borderRowHor + }; + //только для определения бордера + +private: + _InternalState m_eInternalState; private: RtfShape& m_oShape; std::wstring m_sFile; std::wstring m_sData; bool m_bBin; BYTE* m_pbBin; size_t m_nBinLength; - -public: +public: RtfPictureReader( RtfReader& oReader, RtfShape& oShape ); ~RtfPictureReader(); bool ExecuteCommand(RtfDocument& oDocument, RtfReader& oReader, std::string sCommand, bool hasParameter, int parameter); diff --git a/RtfFile/Format/RtfChar.cpp b/RtfFile/Format/RtfChar.cpp index f5c9f9c5255..daf1774fb08 100644 --- a/RtfFile/Format/RtfChar.cpp +++ b/RtfFile/Format/RtfChar.cpp @@ -120,7 +120,8 @@ std::wstring RtfChar::RenderToOOX(RenderParameter oRenderParameter) OOXWriter* poOOXWriter = static_cast (oRenderParameter.poWriter); std::wstring sResult; - if (RENDER_TO_OOX_PARAM_RUN == oRenderParameter.nType) + if (RENDER_TO_OOX_PARAM_RUN == oRenderParameter.nType || + RENDER_TO_OOX_PARAM_FIELD == oRenderParameter.nType) { bool bInsert = false; bool bDelete = false; @@ -132,7 +133,7 @@ std::wstring RtfChar::RenderToOOX(RenderParameter oRenderParameter) std::wstring sAuthor = poRtfDocument->m_oRevisionTable.GetAuthor(m_oProperty.m_nRevauth); std::wstring sDate(RtfUtility::convertDateTime(m_oProperty.m_nRevdttm).c_str()); - sResult += L"m_nCurTrackChangesId++).c_str() + L"\">"; + sResult += L"m_nCurTrackChangesId++).c_str() + L"\">"; m_oProperty.m_nRevised = PROP_DEF; } if (m_oProperty.m_nDeleted != PROP_DEF) @@ -142,7 +143,7 @@ std::wstring RtfChar::RenderToOOX(RenderParameter oRenderParameter) std::wstring sAuthor = poRtfDocument->m_oRevisionTable.GetAuthor(m_oProperty.m_nRevauthDel); std::wstring sDate(RtfUtility::convertDateTime(m_oProperty.m_nRevdttmDel).c_str()); - sResult += L"m_nCurTrackChangesId++).c_str() + L"\">"; + sResult += L"m_nCurTrackChangesId++).c_str() + L"\">"; m_oProperty.m_nDeleted = PROP_DEF; } sResult += L""; @@ -150,7 +151,7 @@ std::wstring RtfChar::RenderToOOX(RenderParameter oRenderParameter) sResult += m_oProperty.RenderToOOX(oRenderParameter); sResult += L""; - sResult += renderTextToXML(L"Text", bDelete ); + sResult += renderTextToXML((RENDER_TO_OOX_PARAM_FIELD == oRenderParameter.nType ? L"Field" : L"Text"), bDelete ); sResult += L""; if (bDelete)sResult += L""; @@ -173,7 +174,7 @@ std::wstring RtfChar::RenderToOOX(RenderParameter oRenderParameter) std::wstring sAuthor = poRtfDocument->m_oRevisionTable.GetAuthor(m_oProperty.m_nRevauth); std::wstring sDate(RtfUtility::convertDateTime(m_oProperty.m_nRevdttm).c_str()); - sResult += L"m_nCurTrackChangesId++).c_str() + L"\">"; + sResult += L"m_nCurTrackChangesId++).c_str() + L"\">"; m_oProperty.m_nRevised = PROP_DEF; } if (m_oProperty.m_nDeleted != PROP_DEF) @@ -183,7 +184,7 @@ std::wstring RtfChar::RenderToOOX(RenderParameter oRenderParameter) std::wstring sAuthor = poRtfDocument->m_oRevisionTable.GetAuthor(m_oProperty.m_nRevauthDel); std::wstring sDate(RtfUtility::convertDateTime(m_oProperty.m_nRevdttmDel).c_str()); - sResult += L"m_nCurTrackChangesId++).c_str() + L"\">"; + sResult += L"m_nCurTrackChangesId++).c_str() + L"\">"; m_oProperty.m_nDeleted = PROP_DEF; } sResult += m_oProperty.RenderToOOX(oRenderParameter);//w:rPr внутри @@ -221,6 +222,12 @@ std::wstring RtfChar::renderTextToXML( std::wstring sParam, bool bDelete ) sResult += XmlUtils::EncodeXmlString( m_sChars, true ); sResult += L""; } + else if (L"Field" == sParam && !m_sChars.empty()) + { + sResult += L""; + sResult += XmlUtils::EncodeXmlString(m_sChars, true); + sResult += L""; + } return sResult; } std::wstring RtfChar::renderRtfText( std::wstring& sText, void* poDocument, RtfCharProperty* oCharProperty, bool bMarker) @@ -243,14 +250,37 @@ std::wstring RtfChar::renderRtfText( std::wstring& sText, void* poDocument, RtfC } return renderRtfText(sText, pDocument, nCodePage, bMarker); +} +std::wstring RtfChar::renderRtfText(const std::wstring& sText) +{ + std::wstring sResult; + for (size_t i = 0; i < sText.length(); i++) + { + int nUnicode = (int)sText[i]; + if (0 < nUnicode && nUnicode <= 0x8000) + { + sResult += L"\\u" + std::to_wstring(nUnicode) + L"*"; + } + else if (0x8000 < nUnicode && nUnicode <= 0xffff) { + sResult += L"\\u" + std::to_wstring(nUnicode - 0x10000) + L"*"; //??? font alt name china ALL FONTS NEW.docx (Mekanik LET) + } + else { + sResult += L"\\u9633*"; + } + } + return sResult; } std::wstring RtfChar::renderRtfText( std::wstring& sText, void* poDocument, int nCodePage, bool bMarker) { RtfDocument* pDocument = static_cast(poDocument); std::wstring sResult; - //от настроек документа + if (sText.empty()) + { + return sResult; + } + //от настроек документа if( -1 == nCodePage && RtfDocumentProperty::cp_none != pDocument->m_oProperty.m_eCodePage ) { switch ( pDocument->m_oProperty.m_eCodePage ) @@ -274,84 +304,17 @@ std::wstring RtfChar::renderRtfText( std::wstring& sText, void* poDocument, int nCodePage = CP_ACP; } - if (nCodePage == CP_ACP && pDocument->m_nUserLCID > 0) + if ((nCodePage == CP_ACP || nCodePage == 1252) && pDocument->m_nUserLCID > 0) { nCodePage = pDocument->m_lcidConverter.get_codepage(pDocument->m_nUserLCID); - } - - std::wstring unicodeStr (sText); - std::string ansiStr ; - - if (unicodeStr.empty()) - { - return sResult; - } - - //ansiStr = RtfUtility::convert_string(unicodeStr.begin(), unicodeStr.end(), nCodePage); - - std::wstring sTextBack = RtfUtility::convert_string_icu(ansiStr.begin(), ansiStr.end(), nCodePage); - - //if (!ansiStr.empty() && sTextBack.empty()) - //{ - // //code page not support in icu !!! - // sTextBack = RtfUtility::convert_string(ansiStr.begin(), ansiStr.end(), nCodePage); .. to UnicodeConverter - //} - - //обратное преобразование чтобы понять какие символы свонвертировались неправильно - while (sTextBack.length() < sText.length()) - sTextBack += L"-"; + } if (bMarker) sResult += L"{\\uc1"; + + sResult += renderRtfText(sText); - for ( size_t i = 0; i < sText.length() ; i++ ) - { - bool bWriteUnicode = true; - - if(sTextBack[i] == sText[i] ) - { - std::wstring sUniChar; sUniChar += unicodeStr[i]; - - //делаем Ansi строку sUniChar - // -> sTempAnsiChars - std::string sTempAnsiChars = RtfUtility::convert_string_icu(unicodeStr.begin() + i, unicodeStr.begin() + i + 1, nCodePage); - - for( size_t k = 0; k < sTempAnsiChars.length(); k++ ) - { - unsigned char nCharCode = sTempAnsiChars[k]; - bWriteUnicode = false; - - if (nCharCode == 0x5c || nCharCode == 0x7b || nCharCode == 0x7d || - (0x00 <= nCharCode && nCharCode < 0x20) ) - { - sResult += L"\\'" + XmlUtils::ToString( nCharCode, L"%02x"); - } - else if ( 0x20 <= nCharCode && nCharCode < 0x80 ) - { - sResult += nCharCode; - } - else - { // 0x80 <= nUnicode <= 0xff - sResult += L"\\'" + XmlUtils::ToString(nCharCode, L"%x" ); - } - } - } - if( true == bWriteUnicode ) - { - int nUnicode = (int)unicodeStr[i]; - - if (0 < nUnicode && nUnicode <= 0x8000) - { - sResult += L"\\u" + std::to_wstring(nUnicode) + L"*"; - } else if (0x8000 < nUnicode && nUnicode <= 0xffff) { - sResult += L"\\u" + std::to_wstring(nUnicode - 0x10000) + L"*"; //??? font alt name china ALL FONTS NEW.docx (Mekanik LET) - } else { - sResult += L"\\u9633*"; - } - } - - } - if (bMarker) + if (bMarker) sResult += L"}"; return sResult; } @@ -447,7 +410,8 @@ std::wstring RtfCharSpecial::RenderToOOX(RenderParameter oRenderParameter) OOXWriter* poOOXWriter = static_cast (oRenderParameter.poWriter); std::wstring sResult; - if(RENDER_TO_OOX_PARAM_RUN == oRenderParameter.nType) + if (RENDER_TO_OOX_PARAM_RUN == oRenderParameter.nType || + RENDER_TO_OOX_PARAM_FIELD == oRenderParameter.nType) { bool bInsert = false; bool bDelete = false; @@ -459,7 +423,7 @@ std::wstring RtfCharSpecial::RenderToOOX(RenderParameter oRenderParameter) std::wstring sAuthor = poRtfDocument->m_oRevisionTable.GetAuthor(m_oProperty.m_nRevauth); std::wstring sDate(RtfUtility::convertDateTime(m_oProperty.m_nRevdttm).c_str()); - sResult += L"m_nCurTrackChangesId++).c_str() + L"\">"; + sResult += L"m_nCurTrackChangesId++).c_str() + L"\">"; m_oProperty.m_nRevised = PROP_DEF; } if (m_oProperty.m_nDeleted != PROP_DEF) @@ -469,7 +433,7 @@ std::wstring RtfCharSpecial::RenderToOOX(RenderParameter oRenderParameter) std::wstring sAuthor = poRtfDocument->m_oRevisionTable.GetAuthor(m_oProperty.m_nRevauthDel); std::wstring sDate(RtfUtility::convertDateTime(m_oProperty.m_nRevdttmDel).c_str()); - sResult += L"m_nCurTrackChangesId++).c_str() + L"\">"; + sResult += L"m_nCurTrackChangesId++).c_str() + L"\">"; m_oProperty.m_nDeleted = PROP_DEF; } sResult += L""; @@ -539,7 +503,7 @@ std::wstring RtfCharSpecial::RenderToRtf(RenderParameter oRenderParameter) } sResult += L"}"; return sResult; - } +} std::wstring RtfCharNative::RenderToRtf(RenderParameter oRenderParameter) { diff --git a/RtfFile/Format/RtfChar.h b/RtfFile/Format/RtfChar.h index f32203e6075..b2342a95e53 100644 --- a/RtfFile/Format/RtfChar.h +++ b/RtfFile/Format/RtfChar.h @@ -142,6 +142,8 @@ class RtfChar : public IDocumentElement static std::wstring renderRtfText( std::wstring& sText, void* poDocument, RtfCharProperty* oCharProperty = NULL, bool bMarker = false); static std::wstring renderRtfText( std::wstring& sText, void* poDocument, int nCodePage, bool bMarker = false ); + static std::wstring renderRtfText(const std::wstring& sText); + std::wstring RenderToRtf(RenderParameter oRenderParameter); private: diff --git a/RtfFile/Format/RtfDefine.h b/RtfFile/Format/RtfDefine.h index 58e489eded1..6b4c3cca82d 100644 --- a/RtfFile/Format/RtfDefine.h +++ b/RtfFile/Format/RtfDefine.h @@ -108,13 +108,15 @@ const long g_cdMaxPercent = 1000000; #define RENDER_TO_OOX_PARAM_STYLES 18 #define RENDER_TO_OOX_PARAM_BORDER_ATTRIBUTE 19 #define RENDER_TO_OOX_PARAM_BORDER_TAG 20 -#define RENDER_TO_OOX_PARAM_SHAPE_WSHAPE 22 -#define RENDER_TO_OOX_PARAM_SHAPE_WSHAPE2 23 +#define RENDER_TO_OOX_PARAM_PIC_BULLET 22 +#define RENDER_TO_OOX_PARAM_SHAPE_CHILD 23 #define RENDER_TO_OOX_PARAM_FIRST_SECTION 24 #define RENDER_TO_OOX_PARAM_OLE_ONLY 25 #define RENDER_TO_OOX_PARAM_OLDLIST_ABS 26 #define RENDER_TO_OOX_PARAM_OLDLIST_OVR 27 #define RENDER_TO_OOX_PARAM_COMMENT 28 +#define RENDER_TO_OOX_PARAM_SHAPE 29 +#define RENDER_TO_OOX_PARAM_FIELD 30 #define RENDER_TO_RTF_PARAM_UNKNOWN 0 #define RENDER_TO_RTF_PARAM_CHAR 1 diff --git a/RtfFile/Format/RtfDocument.cpp b/RtfFile/Format/RtfDocument.cpp index 60e3e53c09e..6e056743d81 100644 --- a/RtfFile/Format/RtfDocument.cpp +++ b/RtfFile/Format/RtfDocument.cpp @@ -77,8 +77,9 @@ std::wstring RtfDocument::RenderToOOX(RenderParameter oRenderParameter) return L""; } -int RtfDocument::GetZIndex() +int RtfDocument::GetZIndex(bool bReverse) { + if (bReverse ) return -(0xFFFF - (m_nZIndexLast++)); return m_nZIndexLast++; } void RtfDocument::SetZIndex(int val) diff --git a/RtfFile/Format/RtfDocument.h b/RtfFile/Format/RtfDocument.h index 86766ac9ce1..58635888644 100644 --- a/RtfFile/Format/RtfDocument.h +++ b/RtfFile/Format/RtfDocument.h @@ -96,7 +96,7 @@ class RtfDocument : public ItemContainer<_section> public: MS_LCID_converter m_lcidConverter; - int GetZIndex(); + int GetZIndex(bool bReverse = false); void SetZIndex(int val); IdGenerator m_oIdGenerator; diff --git a/RtfFile/Format/RtfField.cpp b/RtfFile/Format/RtfField.cpp index 7efac19245b..b3f31c569d4 100644 --- a/RtfFile/Format/RtfField.cpp +++ b/RtfFile/Format/RtfField.cpp @@ -270,8 +270,8 @@ std::wstring RtfField::RenderToOOX(RenderParameter oRenderParameter) if( true == m_bTextOnly ) { - RenderParameter oNewParam = oRenderParameter; - oNewParam.nType = RENDER_TO_OOX_PARAM_RUN; + RenderParameter oNewParam = oRenderParameter; + oNewParam.nType = RENDER_TO_OOX_PARAM_RUN; sResult += m_pResult->m_pTextItems->RenderToOOX(oNewParam); } @@ -289,7 +289,7 @@ std::wstring RtfField::RenderToOOX(RenderParameter oRenderParameter) sAuthor = pRtfDocument->m_oRevisionTable.GetAuthor(m_pInsert->m_oCharProperty.m_nRevauth); sDate = std::wstring(RtfUtility::convertDateTime(m_pInsert->m_oCharProperty.m_nRevdttm).c_str()); - sResult += L"m_nCurTrackChangesId++).c_str() + L"\">"; + sResult += L"m_nCurTrackChangesId++).c_str() + L"\">"; m_pInsert->m_oCharProperty.m_nRevised = PROP_DEF; } if (m_pInsert->m_oCharProperty.m_nDeleted != PROP_DEF) @@ -299,17 +299,17 @@ std::wstring RtfField::RenderToOOX(RenderParameter oRenderParameter) sAuthor = pRtfDocument->m_oRevisionTable.GetAuthor(m_pInsert->m_oCharProperty.m_nRevauthDel); sDate = std::wstring(RtfUtility::convertDateTime(m_pInsert->m_oCharProperty.m_nRevdttmDel).c_str()); - sResult += L"m_nCurTrackChangesId++).c_str() + L"\">"; + sResult += L"m_nCurTrackChangesId++).c_str() + L"\">"; m_pInsert->m_oCharProperty.m_nDeleted = PROP_DEF; } //поверяем на наличие гиперссылки - RenderParameter oNewParam = oRenderParameter; - oNewParam.nType = RENDER_TO_OOX_PARAM_PLAIN; + RenderParameter oNewParam = oRenderParameter; + oNewParam.nType = RENDER_TO_OOX_PARAM_PLAIN; std::wstring sInsertText = m_pInsert->m_pTextItems->RenderToOOX( oNewParam ); size_t nIndex = sInsertText.find( L"HYPERLINK" ); - if( std::wstring::npos != nIndex ) + if ( std::wstring::npos != nIndex && (m_pResult) && (m_pResult->m_pTextItems) && m_pResult->m_pTextItems->GetCount() < 2) { std::wstring sHyperlink = sInsertText; sHyperlink.erase( nIndex, 9/*(int)_tcslen( L"HYPERLINK" )*/ ); @@ -354,8 +354,8 @@ std::wstring RtfField::RenderToOOX(RenderParameter oRenderParameter) } else { - RenderParameter oNewParametr = oRenderParameter; - oNewParametr.nType = RENDER_TO_OOX_PARAM_PLAIN; + RenderParameter oNewParametr = oRenderParameter; + oNewParametr.nType = RENDER_TO_OOX_PARAM_FIELD; std::wstring props = m_pResult->m_oCharProperty.RenderToOOX(oRenderParameter); if (!props.empty()) props = L"" + props + L""; @@ -430,26 +430,21 @@ std::wstring RtfField::RenderToOOX(RenderParameter oRenderParameter) sResult += L""; //----------- - sResult += L""; - if (!props.empty()) - sResult += props; - - sResult += L""; - - if (m_pInsert->m_pTextItems) + if ((m_pInsert->m_pTextItems) && (m_pInsert->m_pTextItems->GetCount() > 0)) { - sResult += XmlUtils::EncodeXmlString( m_pInsert->m_pTextItems->RenderToOOX(oNewParametr), true ); + for (int i = 0; i < m_pInsert->m_pTextItems->GetCount(); i++) + { + sResult += m_pInsert->m_pTextItems->m_aArray[i]->RenderToOOX(oNewParametr); + } } - sResult += L""; - + oNewParametr = oRenderParameter; // разделитель sResult += L""; sResult += L""; - //пишем содержание-кэш + //пишем содержание-кэш if ((m_pResult->m_pTextItems) && (m_pResult->m_pTextItems->GetCount() > 0)) { - oNewParametr.nType = RENDER_TO_OOX_PARAM_RUN; sResult += m_pResult->m_pTextItems->m_aArray[0]->RenderToOOX(oNewParametr); for (int i = 1; i < m_pResult->m_pTextItems->GetCount(); i++) diff --git a/RtfFile/Format/RtfField.h b/RtfFile/Format/RtfField.h index d47b929325d..75917368e15 100644 --- a/RtfFile/Format/RtfField.h +++ b/RtfFile/Format/RtfField.h @@ -124,10 +124,11 @@ class RtfFieldInst : public IDocumentElement std::wstring RenderToRtf(RenderParameter oRenderParameter); std::wstring RenderToOOX(RenderParameter oRenderParameter); - RtfCharProperty m_oCharProperty; - TextItemContainerPtr m_pTextItems; + RtfCharProperty m_oCharProperty; + + TextItemContainerPtr m_pTextItems; - RtfFormFieldPtr m_pFormField; + RtfFormFieldPtr m_pFormField; }; typedef boost::shared_ptr RtfFieldInstPtr; diff --git a/RtfFile/Format/RtfGlobalTables.cpp b/RtfFile/Format/RtfGlobalTables.cpp index 4db392a7ea3..c04ba80f213 100644 --- a/RtfFile/Format/RtfGlobalTables.cpp +++ b/RtfFile/Format/RtfGlobalTables.cpp @@ -64,15 +64,20 @@ bool RtfFontTable::GetFont( std::wstring sName, RtfFont& oFont ) } std::wstring RtfFontTable::RenderToOOX(RenderParameter oRenderParameter) { + if (m_aArray.empty()) return L""; + std::wstring sResult; - if( !m_aArray.empty()) + std::map mapFontsDouble; + + for (size_t i = 0; i < m_aArray.size(); i++) { - for (size_t i = 0; i < m_aArray.size(); i++) + std::map::iterator pFind = mapFontsDouble.find(m_aArray[i].m_sName); + if (pFind == mapFontsDouble.end()) { - if (m_aArray[i].m_bUsed) - sResult += m_aArray[i].RenderToOOX(oRenderParameter); + //if (m_aArray[i].m_bUsed) + sResult += m_aArray[i].RenderToOOX(oRenderParameter); + mapFontsDouble.insert(std::make_pair(m_aArray[i].m_sName, m_aArray[i].m_bUsed)); } - } return sResult; } @@ -352,7 +357,7 @@ std::wstring RtfListTable::RenderToOOX(RenderParameter oRenderParameter) if( m_aArray.size() > 0 ) { RenderParameter oNewParam = oRenderParameter; - oNewParam.nType = RENDER_TO_OOX_PARAM_SHAPE_WSHAPE; + oNewParam.nType = RENDER_TO_OOX_PARAM_PIC_BULLET; for (int i = 0; i < m_aPictureList.GetCount(); i++ ) { sResult += L""; diff --git a/RtfFile/Format/RtfOldList.cpp b/RtfFile/Format/RtfOldList.cpp index 41ddd908062..469b5e0f583 100644 --- a/RtfFile/Format/RtfOldList.cpp +++ b/RtfFile/Format/RtfOldList.cpp @@ -40,6 +40,10 @@ std::wstring RtfOldList::RenderToRtf(RenderParameter oRenderParameter) sResult += m_oText->RenderToRtf( oRenderParameter ); return sResult; } +static inline bool IsControlSymbol(unsigned short c) +{ + return (c <= 31) ? (true) : (false); +} std::wstring RtfOldList::RenderToOOX(RenderParameter oRenderParameter) { std::wstring sResult; @@ -61,12 +65,15 @@ std::wstring RtfOldList::RenderToOOX(RenderParameter oRenderParameter) if(!sText.empty() ) { - // В символьном шрифте обрезать надо, в других случаях - нет - if (/*bIsSymbol && */(sText[0] & 0xF000) != 0) + wchar_t xchBullet = sText[0]; + if ((xchBullet & 0xF000) != 0) + { + xchBullet &= 0x00FF; + } + if (!IsControlSymbol(xchBullet)) { - sText[0] &= 0x00FF; + sResult += L""; } - sResult += L""; } else { diff --git a/RtfFile/Format/RtfOle.cpp b/RtfFile/Format/RtfOle.cpp index bab4dd3daa4..5980582d072 100644 --- a/RtfFile/Format/RtfOle.cpp +++ b/RtfFile/Format/RtfOle.cpp @@ -82,7 +82,7 @@ std::wstring RtfOle::RenderToOOX(RenderParameter oRenderParameter) std::wstring sAuthor = poRtfDocument->m_oRevisionTable.GetAuthor(pCharProps->m_nRevauth); std::wstring sDate(RtfUtility::convertDateTime(pCharProps->m_nRevdttm).c_str()); - sResult += L"m_nCurTrackChangesId++).c_str() + L"\">"; + sResult += L"m_nCurTrackChangesId++).c_str() + L"\">"; pCharProps->m_nRevised = PROP_DEF; } if (pCharProps->m_nDeleted != PROP_DEF) @@ -92,7 +92,7 @@ std::wstring RtfOle::RenderToOOX(RenderParameter oRenderParameter) std::wstring sAuthor = poRtfDocument->m_oRevisionTable.GetAuthor(pCharProps->m_nRevauthDel); std::wstring sDate(RtfUtility::convertDateTime(pCharProps->m_nRevdttmDel).c_str()); - sResult += L"m_nCurTrackChangesId++).c_str() + L"\">"; + sResult += L"m_nCurTrackChangesId++).c_str() + L"\">"; pCharProps->m_nDeleted = PROP_DEF; } //---------- @@ -111,7 +111,7 @@ std::wstring RtfOle::RenderToOOX(RenderParameter oRenderParameter) L"\" w:dyaOrig=\"" + std::to_wstring(m_nHeight) + L"\">"; RenderParameter oNewRenderParameter = oRenderParameter; - oNewRenderParameter.nType = RENDER_TO_OOX_PARAM_SHAPE_WSHAPE2; + oNewRenderParameter.nType = RENDER_TO_OOX_PARAM_SHAPE_CHILD; if (m_oResultShape) { @@ -172,6 +172,7 @@ std::wstring RtfOle::RenderToOOXOnlyOle(RenderParameter oRenderParameter) sRelsType = L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/package"; }break; case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOC: + case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOC_FLAT: { sExtension = L"doc"; sMime = L"application/msword"; diff --git a/RtfFile/Format/RtfParagraph.cpp b/RtfFile/Format/RtfParagraph.cpp index 2b43cc6a876..cfc76a836bf 100644 --- a/RtfFile/Format/RtfParagraph.cpp +++ b/RtfFile/Format/RtfParagraph.cpp @@ -110,21 +110,22 @@ std::wstring RtfParagraph::RenderToOOX(RenderParameter oRenderParameter) std::wstring sResult ; - if( RENDER_TO_OOX_PARAM_PLAIN == oRenderParameter.nType ) + if (RENDER_TO_OOX_PARAM_PLAIN == oRenderParameter.nType ) { for (size_t i = 0; i < m_aArray.size(); i++ ) { sResult += m_aArray[i]->RenderToOOX(oRenderParameter); } } - else if( RENDER_TO_OOX_PARAM_RUN == oRenderParameter.nType ) + else if (RENDER_TO_OOX_PARAM_RUN == oRenderParameter.nType || + RENDER_TO_OOX_PARAM_FIELD == oRenderParameter.nType) { for (size_t i = 0; i < m_aArray.size(); i++ ) { sResult += m_aArray[i]->RenderToOOX(oRenderParameter); } } - else if( RENDER_TO_OOX_PARAM_MATH == oRenderParameter.nType ) + else if (RENDER_TO_OOX_PARAM_MATH == oRenderParameter.nType ) { if (m_aArray.size() < 1) { @@ -157,7 +158,7 @@ std::wstring RtfParagraph::RenderToOOX(RenderParameter oRenderParameter) } sResult += L">"; - m_oProperty.m_bOldList = (NULL != m_oOldList); + m_oProperty.m_bList = (NULL != m_oOldList) || m_oProperty.m_bList; bool bRenderProps = false; if ( PROP_DEF != m_oProperty.m_nTableStyle && m_oProperty.m_bInTable > 0) diff --git a/RtfFile/Format/RtfPicture.cpp b/RtfFile/Format/RtfPicture.cpp index 4f053eeb1e5..9c32d0be25a 100644 --- a/RtfFile/Format/RtfPicture.cpp +++ b/RtfFile/Format/RtfPicture.cpp @@ -33,6 +33,7 @@ #include "../OOXml/Writer/OOXWriter.h" #include "RtfWriter.h" #include "Utils.h" +#include "../../DesktopEditor/raster/BgraFrame.h" RtfPicture::RtfPicture() { @@ -144,6 +145,26 @@ std::wstring RtfPicture::RenderToRtf(RenderParameter oRenderParameter) RENDER_RTF_INT( m_nWidthGoal, sResult, L"picwgoal" ) RENDER_RTF_INT( m_nHeightGoal, sResult, L"pichgoal" ) + if (true == m_oBorderTop.IsValid()) + { + sResult += L"\\brdrt"; + sResult += m_oBorderTop.RenderToRtf(oRenderParameter); + } + if (true == m_oBorderLeft.IsValid()) + { + sResult += L"\\brdrl"; + sResult += m_oBorderLeft.RenderToRtf(oRenderParameter); + } + if (true == m_oBorderBottom.IsValid()) + { + sResult += L"\\brdrb"; + sResult += m_oBorderBottom.RenderToRtf(oRenderParameter); + } + if (true == m_oBorderRight.IsValid()) + { + sResult += L"\\brdrr"; + sResult += m_oBorderRight.RenderToRtf(oRenderParameter); + } switch( eDataType ) { case dt_emf: sResult += L"\\emfblip"; break; @@ -172,11 +193,11 @@ std::wstring RtfPicture::RenderToOOX(RenderParameter oRenderParameter) std::wstring sMime; switch( eDataType ) { + case dt_macpict: // convert it case dt_png: sExtension = L"png"; sMime = L"image/png"; break; case dt_jpg: sExtension = L"jpg"; sMime = L"image/jpg"; break; case dt_wmf: sExtension = L"wmf"; sMime = L"image/x-wmf"; break; case dt_emf: sExtension = L"emf"; sMime = L"image/x-emf"; break; - case dt_macpict:sExtension = L"pct"; sMime = L"image/x-pict"; break; case dt_svg: sExtension = L"svg"; sMime = L"image/svg+xml"; break; } if (poOOXWriter->m_sTargetFolder.empty()) return L"rIdtemp"; //test from fields @@ -193,7 +214,16 @@ std::wstring RtfPicture::RenderToOOX(RenderParameter oRenderParameter) sFilenameFull += FILE_SEPARATOR_STR + sFilenameRels; sFilenameRels = L"media/" + sFilenameRels; - if( m_sPicFilename != sFilenameFull ) + if (eDataType == dt_macpict) + { + CBgraFrame bgraFrame; + + if (bgraFrame.OpenFile(m_sPicFilename)) + { + bgraFrame.SaveFile(sFilenameFull, 4); // png + } + } + else if( m_sPicFilename != sFilenameFull ) Utils::CopyDirOrFile( m_sPicFilename, sFilenameFull ); else m_bIsCopy = false; diff --git a/RtfFile/Format/RtfPicture.h b/RtfFile/Format/RtfPicture.h index 5bfd77b07d7..89a41eae516 100644 --- a/RtfFile/Format/RtfPicture.h +++ b/RtfFile/Format/RtfPicture.h @@ -55,6 +55,11 @@ class RtfPicture : public IDocumentElement int m_nCropR; int m_nCropB; + RtfBorder m_oBorderTop; + RtfBorder m_oBorderLeft; + RtfBorder m_oBorderBottom; + RtfBorder m_oBorderRight; + bool m_bIsCopy; // true - надо удалять m_sPicFilename, false - не надо удалять std::wstring m_sPicFilename; //всегда содержит имя картинки, тип которой поддерживает rtf diff --git a/RtfFile/Format/RtfProperty.cpp b/RtfFile/Format/RtfProperty.cpp index 2dfd475527d..10561fa6946 100644 --- a/RtfFile/Format/RtfProperty.cpp +++ b/RtfFile/Format/RtfProperty.cpp @@ -1002,6 +1002,54 @@ std::wstring RtfShading::RenderToOOX(RenderParameter oRenderParameter) m_nValue = 0; std::wstring sShading; + if (PROP_DEF != m_nValue) + { + std::wstring sValue; + if (0 <= m_nValue && m_nValue <= 2) sShading += L" w:val=\"clear\""; + else if (2 < m_nValue && m_nValue <= 7) sShading += L" w:val=\"pct5\""; + else if (7 < m_nValue && m_nValue <= 11) sShading += L" w:val=\"pct10\""; + else if (11 < m_nValue && m_nValue <= 13) sShading += L" w:val=\"pct12\""; + else if (13 < m_nValue && m_nValue <= 17) sShading += L" w:val=\"pct15\""; + else if (17 < m_nValue && m_nValue <= 22) sShading += L" w:val=\"pct20\""; + else if (22 < m_nValue && m_nValue <= 27) sShading += L" w:val=\"pct25\""; + else if (27 < m_nValue && m_nValue <= 32) sShading += L" w:val=\"pct30\""; + else if (32 < m_nValue && m_nValue <= 36) sShading += L" w:val=\"pct35\""; + else if (36 < m_nValue && m_nValue <= 38) sShading += L" w:val=\"pct37\""; + else if (38 < m_nValue && m_nValue <= 42) sShading += L" w:val=\"pct40\""; + else if (42 < m_nValue && m_nValue <= 47) sShading += L" w:val=\"pct45\""; + else if (47 < m_nValue && m_nValue <= 52) sShading += L" w:val=\"pct50\""; + else if (52 < m_nValue && m_nValue <= 57) sShading += L" w:val=\"pct55\""; + else if (57 < m_nValue && m_nValue <= 61) sShading += L" w:val=\"pct60\""; + else if (61 < m_nValue && m_nValue <= 63) sShading += L" w:val=\"pct62\""; + else if (63 < m_nValue && m_nValue <= 70) sShading += L" w:val=\"pct65\""; + else if (70 < m_nValue && m_nValue <= 80) sShading += L" w:val=\"pct75\""; + else if (80 < m_nValue && m_nValue <= 86) sShading += L" w:val=\"pct85\""; + else if (86 < m_nValue && m_nValue <= 88) sShading += L" w:val=\"pct87\""; + else if (88 < m_nValue && m_nValue <= 92) sShading += L" w:val=\"pct90\""; + else if (92 < m_nValue && m_nValue <= 97) sShading += L" w:val=\"pct95\""; + else if (97 < m_nValue && m_nValue <= 100) sShading += L" w:val=\"solid\""; + } + else + { + switch (m_eType) + { + case st_clshdrawnil: sShading += L" w:val=\"nil\""; break; + case st_chbghoriz: sShading += L" w:val=\"thinHorzStripehorzStripe\""; break; + case st_chbgvert: sShading += L" w:val=\"thinVertStripe\""; break; + case st_chbgfdiag: sShading += L" w:val=\"thinReverseDiagStripe\""; break; + case st_chbgbdiag: sShading += L" w:val=\"thinDiagStripe\""; break; + case st_chbgcross: sShading += L" w:val=\"thinHorzCross\""; break; + case st_chbgdcross: sShading += L" w:val=\"thinDiagCross\""; break; + case st_chbgdkhoriz: sShading += L" w:val=\"horzStripe\""; break; + case st_chbgdkvert: sShading += L" w:val=\"vertStripe\""; break; + case st_chbgdkfdiag: sShading += L" w:val=\"reverseDiagStripe\""; break; + case st_chbgdkbdiag: sShading += L" w:val=\"diagStripe\""; break; + case st_chbgdkcross: sShading += L" w:val=\"horzCross\""; break; + case st_chbgdkdcross: sShading += L" w:val=\"diagCross\""; break; + default: + break; + } + } if( PROP_DEF != m_nForeColor ) { RtfColor oForeColor; @@ -1014,54 +1062,6 @@ std::wstring RtfShading::RenderToOOX(RenderParameter oRenderParameter) if( true == poRtfDocument->m_oColorTable.GetColor( m_nBackColor, oBackColor ) ) sShading += L" w:fill=\"" + oBackColor.RenderToOOX(oNewParam) + L"\""; } - if( PROP_DEF != m_nValue ) - { - std::wstring sValue; - if( 0 <= m_nValue && m_nValue <= 2 ) sShading += L" w:val=\"clear\""; - else if( 2 < m_nValue && m_nValue <= 7 ) sShading += L" w:val=\"pct5\""; - else if( 7 < m_nValue && m_nValue <= 11 ) sShading += L" w:val=\"pct10\""; - else if( 11 < m_nValue && m_nValue <= 13 ) sShading += L" w:val=\"pct12\""; - else if( 13 < m_nValue && m_nValue <= 17 ) sShading += L" w:val=\"pct15\""; - else if( 17 < m_nValue && m_nValue <= 22 ) sShading += L" w:val=\"pct20\""; - else if( 22 < m_nValue && m_nValue <= 27 ) sShading += L" w:val=\"pct25\""; - else if( 27 < m_nValue && m_nValue <= 32 ) sShading += L" w:val=\"pct30\""; - else if( 32 < m_nValue && m_nValue <= 36 ) sShading += L" w:val=\"pct35\""; - else if( 36 < m_nValue && m_nValue <= 38 ) sShading += L" w:val=\"pct37\""; - else if( 38 < m_nValue && m_nValue <= 42 ) sShading += L" w:val=\"pct40\""; - else if( 42 < m_nValue && m_nValue <= 47 ) sShading += L" w:val=\"pct45\""; - else if( 47 < m_nValue && m_nValue <= 52 ) sShading += L" w:val=\"pct50\""; - else if( 52 < m_nValue && m_nValue <= 57 ) sShading += L" w:val=\"pct55\""; - else if( 57 < m_nValue && m_nValue <= 61 ) sShading += L" w:val=\"pct60\""; - else if( 61 < m_nValue && m_nValue <= 63 ) sShading += L" w:val=\"pct62\""; - else if( 63 < m_nValue && m_nValue <= 70 ) sShading += L" w:val=\"pct65\""; - else if( 70 < m_nValue && m_nValue <= 80 ) sShading += L" w:val=\"pct75\""; - else if( 80 < m_nValue && m_nValue <= 86 ) sShading += L" w:val=\"pct85\""; - else if( 86 < m_nValue && m_nValue <= 88 ) sShading += L" w:val=\"pct87\""; - else if( 88 < m_nValue && m_nValue <= 92 ) sShading += L" w:val=\"pct90\""; - else if( 92 < m_nValue && m_nValue <= 97 ) sShading += L" w:val=\"pct95\""; - else if( 97 < m_nValue && m_nValue <= 100 ) sShading += L" w:val=\"solid\""; - } - else - { - switch( m_eType ) - { - case st_clshdrawnil: sShading += L" w:val=\"nil\""; break; - case st_chbghoriz: sShading += L" w:val=\"thinHorzStripehorzStripe\""; break; - case st_chbgvert: sShading += L" w:val=\"thinVertStripe\""; break; - case st_chbgfdiag: sShading += L" w:val=\"thinReverseDiagStripe\""; break; - case st_chbgbdiag: sShading += L" w:val=\"thinDiagStripe\""; break; - case st_chbgcross: sShading += L" w:val=\"thinHorzCross\""; break; - case st_chbgdcross: sShading += L" w:val=\"thinDiagCross\""; break; - case st_chbgdkhoriz: sShading += L" w:val=\"horzStripe\""; break; - case st_chbgdkvert: sShading += L" w:val=\"vertStripe\""; break; - case st_chbgdkfdiag: sShading += L" w:val=\"reverseDiagStripe\""; break; - case st_chbgdkbdiag: sShading += L" w:val=\"diagStripe\""; break; - case st_chbgdkcross: sShading += L" w:val=\"horzCross\""; break; - case st_chbgdkdcross: sShading += L" w:val=\"diagCross\""; break; - default: - break; - } - } if( false == sShading.empty() ) sResult = L""; return sResult; @@ -1077,7 +1077,7 @@ bool RtfBorder::operator==( const RtfBorder& oChar ) } bool RtfBorder::IsValid() { - return bt_none != m_eType; + return PROP_DEF != m_eType; } int RtfBorder::GetType() { @@ -1093,7 +1093,8 @@ void RtfBorder::SetDefaultOOX( ) } void RtfBorder::SetDefault( ) { - DEFAULT_PROPERTY_DEF( m_eType, bt_none ) + DEFAULT_PROPERTY (m_eType) + //DEFAULT_PROPERTY_DEF( m_eType, bt_none ) DEFAULT_PROPERTY ( m_nWidth ) DEFAULT_PROPERTY ( m_nSpace ) DEFAULT_PROPERTY ( m_nColor ) @@ -1108,7 +1109,7 @@ void RtfBorder::SetEmpty( ) void RtfBorder::Merge( RtfBorder& oBorPr ) { //свойство должно быть как единое целое, поэтому если oBorPr задано, то переписыватся целиком - if ( bt_none != oBorPr.m_eType || PROP_DEF != oBorPr.m_nWidth || PROP_DEF != oBorPr.m_nSpace || PROP_DEF != oBorPr.m_nColor ) + if (PROP_DEF != oBorPr.m_eType || PROP_DEF != oBorPr.m_nWidth || PROP_DEF != oBorPr.m_nSpace || PROP_DEF != oBorPr.m_nColor ) { m_eType = oBorPr.m_eType; m_nWidth = oBorPr.m_nWidth; @@ -1178,45 +1179,57 @@ std::wstring RtfBorder::RenderToRtf(RenderParameter oRenderParameter) sResult += L"\\brdrcf" + std::to_wstring(m_nColor ); return sResult; } +std::wstring RtfBorder::GetBorderType() +{ + std::wstring val; + switch (m_eType) + { + case bt_brdrs: val = L"single"; break; + case bt_brdrth: val = L"thick"; break; + case bt_brdrsh: val = L"thin"; break; + case bt_brdrdb: val = L"double"; break; + case bt_brdrdot: val = L"dotted"; break; + case bt_brdrdash: val = L"dashed"; break; + case bt_brdrhair: val = L"hair"; break; + case bt_brdrdashsm: val = L"dashSmallGap"; break; + case bt_brdrdashd: val = L"dotDash"; break; + case bt_brdrdashdd: val = L"dotDotDash"; break; + case bt_brdrinset: val = L"inset"; break; + case bt_brdrnone: val = L"nil"; break; + case bt_brdroutset: val = L"outset"; break; + case bt_brdrtriple: val = L"triple"; break; + case bt_brdrtnthsg: val = L"thinThickSmallGap"; break; + case bt_brdrthtnsg: val = L"thickThinSmallGap"; break; + case bt_brdrtnthtnsg: val = L"thinThickThinSmallGap"; break; + case bt_brdrtnthtnmg: val = L"thinThickThinMediumGap"; break; + case bt_brdrtnthmg: val = L"thinThickMediumGap"; break; + case bt_brdrthtnmg: val = L"thickThinMediumGap"; break; + case bt_brdrtnthlg: val = L"thinThickLargeGap"; break; + case bt_brdrthtnlg: val = L"thickThinLargeGap"; break; + case bt_brdrtnthtnlg: val = L"thinThickThinLargeGap"; break; + case bt_brdrwavy: val = L"wave"; break; + case bt_brdrwavydb: val = L"doubleWave"; break; + case bt_brdrdashdotstr: val = L"dashDotStroked"; break; + case bt_brdremboss: val = L"threeDEmboss"; break; + case bt_brdrengrave: val = L"threeDEngrave"; break; + default: + break; + } + return val; +} std::wstring RtfBorder::RenderToOOX(RenderParameter oRenderParameter) { - RtfDocument* poRtfDocument = static_cast(oRenderParameter.poDocument); std::wstring sResult; - switch( m_eType ) + RtfDocument* poRtfDocument = static_cast(oRenderParameter.poDocument); + + std::wstring val = GetBorderType(); + if (false == val.empty()) { - case bt_brdrs: sResult += L" w:val=\"single\""; break; - case bt_brdrth: sResult += L" w:val=\"thick\""; break; - case bt_brdrsh: sResult += L" w:val=\"thin"; break; - case bt_brdrdb: sResult += L" w:val=\"double\""; break; - case bt_brdrdot: sResult += L" w:val=\"dotted\""; break; - case bt_brdrdash: sResult += L" w:val=\"dashed\""; break; - case bt_brdrhair: sResult += L" w:val=\"hair\""; break; - case bt_brdrdashsm: sResult += L" w:val=\"dashSmallGap\""; break; - case bt_brdrdashd: sResult += L" w:val=\"dotDash\""; break; - case bt_brdrdashdd: sResult += L" w:val=\"dotDotDash\""; break; - case bt_brdrinset: sResult += L" w:val=\"inset\""; break; - case bt_brdrnone: sResult += L" w:val=\"nil\""; break; - case bt_brdroutset: sResult += L" w:val=\"outset\""; break; - case bt_brdrtriple: sResult += L" w:val=\"triple\""; break; - case bt_brdrtnthsg: sResult += L" w:val=\"thinThickSmallGap\""; break; - case bt_brdrthtnsg: sResult += L" w:val=\"thickThinSmallGap\""; break; - case bt_brdrtnthtnsg: sResult += L" w:val=\"thinThickThinSmallGap\""; break; - case bt_brdrtnthtnmg: sResult += L" w:val=\"thinThickThinMediumGap\"";break; - case bt_brdrtnthmg: sResult += L" w:val=\"thinThickMediumGap\""; break; - case bt_brdrthtnmg: sResult += L" w:val=\"thickThinMediumGap\""; break; - case bt_brdrtnthlg: sResult += L" w:val=\"thinThickLargeGap\""; break; - case bt_brdrthtnlg: sResult += L" w:val=\"thickThinLargeGap\""; break; - case bt_brdrtnthtnlg: sResult += L" w:val=\"thinThickThinLargeGap\""; break; - case bt_brdrwavy: sResult += L" w:val=\"wave\""; break; - case bt_brdrwavydb: sResult += L" w:val=\"doubleWave\""; break; - case bt_brdrdashdotstr: sResult += L" w:val=\"dashDotStroked\""; break; - case bt_brdremboss: sResult += L" w:val=\"threeDEmboss\""; break; - case bt_brdrengrave: sResult += L" w:val=\"threeDEngrave\""; break; - default: - break; + sResult += L" w:val=\"" + val + L"\""; + val.clear(); } - if( PROP_DEF != m_nColor ) + if ( PROP_DEF != m_nColor ) { RtfColor oColor; RenderParameter oNewParam = oRenderParameter; @@ -1225,31 +1238,81 @@ std::wstring RtfBorder::RenderToOOX(RenderParameter oRenderParameter) if (m_nColor == -1) { oColor.m_bAuto = true; - sResult += L" w:color=\"auto\""; + val = L"auto"; + } + else if (true == poRtfDocument->m_oColorTable.GetColor(m_nColor, oColor)) + { + val = oColor.RenderToOOX(oNewParam); } - else if( true == poRtfDocument->m_oColorTable.GetColor( m_nColor, oColor ) ) - sResult += L" w:color=\"" + oColor.RenderToOOX(oNewParam) + L"\""; } - if( PROP_DEF != m_nWidth ) //w:sz 1/8 twips (equivalent to 1/576th of an inch) + if (false == val.empty()) { - sResult += L" w:sz=\"" + std::to_wstring(2 * m_nWidth / 5 ) + L"\""; + sResult += L" w:color=\"" + val + L"\""; + val.clear(); } - if( PROP_DEF != m_nSpace ) + if ( PROP_DEF != m_nWidth ) //w:sz 1/8 twips (equivalent to 1/576th of an inch) { - sResult += L" w:space=\"" + std::to_wstring((int)RtfUtility::Twip2pt( m_nSpace )) + L"\""; + sResult += L" w:sz=\"" + std::to_wstring(2 * m_nWidth / 5) + L"\""; } - - if( false == sResult.empty() ) + if ( PROP_DEF != m_nSpace ) { - if( RENDER_TO_OOX_PARAM_BORDER_ATTRIBUTE == oRenderParameter.nType ) + sResult += L" w:space=\"" + std::to_wstring((int)RtfUtility::Twip2pt(m_nSpace)) + L"\""; + } + if ( false == sResult.empty() ) + { + if ( RENDER_TO_OOX_PARAM_BORDER_ATTRIBUTE == oRenderParameter.nType) ; - else if( RENDER_TO_OOX_PARAM_BORDER_TAG == oRenderParameter.nType ) + else if ( RENDER_TO_OOX_PARAM_BORDER_TAG == oRenderParameter.nType ) sResult = L"<" + oRenderParameter.sValue + sResult + L"/>"; else sResult = L""; } return sResult; } +std::wstring RtfBorder::RenderToShapeOOX(RenderParameter oRenderParameter) +{ + std::wstring sResult; + + RtfDocument* poRtfDocument = static_cast(oRenderParameter.poDocument); + + std::wstring val = GetBorderType(); + if (false == val.empty()) + { + sResult += L" type=\"" + val + L"\""; + val.clear(); + } + if (PROP_DEF != m_nColor) + { + RtfColor oColor; + RenderParameter oNewParam = oRenderParameter; + oNewParam.nType = RENDER_TO_OOX_PARAM_COLOR_VALUE; + + if (m_nColor == -1) + { + oColor.m_bAuto = true; + val = L"auto"; + } + else if (true == poRtfDocument->m_oColorTable.GetColor(m_nColor, oColor)) + { + val = oColor.RenderToOOX(oNewParam); + } + } + if (false == val.empty()) + { + sResult += L" color=\"" + val + L"\""; + val.clear(); + } + if (PROP_DEF != m_nWidth) //w:sz 1/8 twips (equivalent to 1/576th of an inch) + { + sResult += L" width=\"" + std::to_wstring(2 * m_nWidth / 5) + L"\""; + } + + if (false == sResult.empty()) + { + sResult = L"<" + oRenderParameter.sValue + sResult + L"/>"; + } + return sResult; +} RtfCharProperty::RtfCharProperty() { @@ -1530,7 +1593,7 @@ std::wstring RtfCharProperty::RenderToOOX(RenderParameter oRenderParameter) std::wstring sAuthor = poRtfDocument->m_oRevisionTable.GetAuthor(m_nRevauth); std::wstring sDate(RtfUtility::convertDateTime( m_nRevdttm ).c_str()); - sResult += L"m_nCurTrackChangesId++).c_str() + L"\">"; + sResult += L"m_nCurTrackChangesId++).c_str() + L"\">"; m_nRevised = PROP_DEF; } if (m_nDeleted != PROP_DEF) @@ -1540,7 +1603,7 @@ std::wstring RtfCharProperty::RenderToOOX(RenderParameter oRenderParameter) std::wstring sAuthor = poRtfDocument->m_oRevisionTable.GetAuthor(m_nRevauthDel); std::wstring sDate(RtfUtility::convertDateTime( m_nRevdttmDel ).c_str()); - sResult += L"m_nCurTrackChangesId++).c_str() + L"\">"; + sResult += L"m_nCurTrackChangesId++).c_str() + L"\">"; m_nDeleted = PROP_DEF; } sResult += L""; @@ -1551,14 +1614,14 @@ std::wstring RtfCharProperty::RenderToOOX(RenderParameter oRenderParameter) std::wstring sAuthor = poRtfDocument->m_oRevisionTable.GetAuthor(m_nRevauthDel); std::wstring sDate(RtfUtility::convertDateTime(m_nRevdttmDel).c_str()); - sResult += L"m_nCurTrackChangesId++).c_str() + L"\"/>"; + sResult += L"m_nCurTrackChangesId++).c_str() + L"\"/>"; } if ( PROP_DEF != m_nRevised ) { std::wstring sAuthor = poRtfDocument->m_oRevisionTable.GetAuthor(m_nRevauth); std::wstring sDate(RtfUtility::convertDateTime(m_nRevdttm).c_str()); - sResult += L"m_nCurTrackChangesId++).c_str() + L"\"/>"; + sResult += L"m_nCurTrackChangesId++).c_str() + L"\"/>"; } if( PROP_DEF != m_nCharStyle ) { @@ -1606,27 +1669,30 @@ std::wstring RtfCharProperty::RenderToOOX(RenderParameter oRenderParameter) sResult += L"m_nCurFitId + L"\" w:val=\"" + std::to_wstring(poOOXWriter->m_nCurFitWidth) + L"\"/>"; } } - if( PROP_DEF == m_nFont) + if (RENDER_TO_OOX_PARAM_UNKNOWN != oRenderParameter.nType) { - if (RENDER_TO_OOX_PARAM_MATH == oRenderParameter.nType) - m_nFont = poRtfDocument->m_oProperty.m_nDefMathFont; - else - m_nFont = poRtfDocument->m_oProperty.m_nDefFont; - } - if (PROP_DEF == m_nLanguage) - { - m_nLanguage = poRtfDocument->m_oProperty.m_nDefLang; - } - if (PROP_DEF == m_nLanguageAsian) - { - m_nLanguageAsian = poRtfDocument->m_oProperty.m_nDefLangAsian; + if (PROP_DEF == m_nFont) + { + if (RENDER_TO_OOX_PARAM_MATH == oRenderParameter.nType) + m_nFont = poRtfDocument->m_oProperty.m_nDefMathFont; + else + m_nFont = poRtfDocument->m_oProperty.m_nDefFont; + } + if (PROP_DEF == m_nLanguage) + { + m_nLanguage = poRtfDocument->m_oProperty.m_nDefLang; + } + if (PROP_DEF == m_nLanguageAsian) + { + m_nLanguageAsian = poRtfDocument->m_oProperty.m_nDefLangAsian; + } } if (PROP_DEF != m_nFont) { RtfFont oCurFont; RenderParameter oNewParam = oRenderParameter; oNewParam.nType = RENDER_TO_OOX_PARAM_UNKNOWN; - if( true == poRtfDocument->m_oFontTable.GetFont(m_nFont,oCurFont) ) + if( true == poRtfDocument->m_oFontTable.GetFont(m_nFont, oCurFont) ) { sResult += oCurFont.RenderToOOX(oNewParam); } @@ -1793,7 +1859,7 @@ std::wstring RtfCharProperty::RenderToOOX(RenderParameter oRenderParameter) RenderParameter oRenderParameterNew = oRenderParameter; oRenderParameterNew.nType = RENDER_TO_OOX_PARAM_UNKNOWN; - sResult += L"m_nCurTrackChangesId++).c_str() + L"\">"; + sResult += L"m_nCurTrackChangesId++).c_str() + L"\">"; sResult += L""; sResult += m_pOldCharProp->RenderToOOX(oRenderParameterNew); sResult += L""; @@ -1864,6 +1930,32 @@ void RtfListLevelProperty::SetDefault() m_oTabs.SetDefault(); m_oCharProp.SetDefault(); } +void RtfListLevelProperty::Merge(RtfListLevelProperty& oListLevel) +{ + MERGE_PROPERTY( m_nSpace, oListLevel) + MERGE_PROPERTY( m_nLevel, oListLevel) + MERGE_PROPERTY( m_nNumberType, oListLevel) + MERGE_PROPERTY( m_bTentative, oListLevel) + MERGE_PROPERTY( m_nJustification, oListLevel) + MERGE_PROPERTY( m_nFollow, oListLevel) + MERGE_PROPERTY( m_nStart, oListLevel) + + if (!oListLevel.m_sText.empty()) + m_sText = oListLevel.m_sText; + + if (!oListLevel.m_sNumber.empty()) + m_sNumber = oListLevel.m_sNumber; + + MERGE_PROPERTY( m_nNoRestart, oListLevel) + MERGE_PROPERTY( m_nLegal, oListLevel) + MERGE_PROPERTY( m_nPictureIndex, oListLevel) + MERGE_PROPERTY( m_nFirstIndent, oListLevel) + MERGE_PROPERTY( m_nIndent, oListLevel) + MERGE_PROPERTY( m_nIndentStart, oListLevel) + + m_oTabs.Merge(oListLevel.m_oTabs); + m_oCharProp.Merge(oListLevel.m_oCharProp); +} std::wstring RtfListLevelProperty::GetFormat( int nNumFormat) { std::wstring sResult; @@ -1937,7 +2029,7 @@ std::wstring RtfListLevelProperty::GetFormat( int nNumFormat) } return sResult; } -int RtfListLevelProperty::GetFormat( std::wstring sFormat) +int RtfListLevelProperty::GetFormat(const std::wstring& sFormat) { if ( L"aiueo" == sFormat ) return 12; else if ( L"aiueoFullWidth" == sFormat ) return 20; @@ -2025,10 +2117,10 @@ std::wstring RtfListLevelProperty::RenderToRtf(RenderParameter oRenderParameter) RENDER_RTF_INT( m_nNoRestart, sResult, L"levelnorestart" ) RENDER_RTF_INT( m_nPictureIndex, sResult, L"levelpicture" ) //чтобы при последующем чтении из rtf не потерялась информация о шрифте - sResult += m_oCharProp.RenderToRtf( oRenderParameter ); + sResult += m_oCharProp.RenderToRtf( oRenderParameter ); - sResult += L"{\\leveltext " + RtfChar::renderRtfText( m_sText, oRenderParameter.poDocument, &m_oCharProp ) + L";}"; - sResult += L"{\\levelnumbers " + RtfChar::renderRtfText( m_sNumber, oRenderParameter.poDocument, &m_oCharProp ) + L";}"; + sResult += L"{\\leveltext" + m_sText + L";}"; + sResult += L"{\\levelnumbers" + m_sNumber + L";}"; RENDER_RTF_INT( m_nFirstIndent, sResult, L"fi" ) RENDER_RTF_INT( m_nIndent, sResult, L"li" ) @@ -2080,12 +2172,13 @@ std::wstring RtfListLevelProperty::GetLevelTextOOX() return XmlUtils::EncodeXmlString( sResult ); } -void RtfListLevelProperty::SetLevelTextOOX(std::wstring sText) +void RtfListLevelProperty::SetLevelTextOOX(const std::wstring& sText) { m_sText = L""; m_sNumber = L""; int nLevelOffsets = 0; + int nText = 0; for (size_t i = 0; i < sText.length() ; i++ ) { @@ -2093,18 +2186,21 @@ void RtfListLevelProperty::SetLevelTextOOX(std::wstring sText) { int nLevel = RtfUtility::ToByte( sText[ i + 1 ] ); - wchar_t ch1 = nLevel - 1; - m_sText += ch1; + m_sText += L"\\'" + XmlUtils::ToString(nLevel - 1, L"%02x"); + m_sNumber += L"\\'" + XmlUtils::ToString(nLevelOffsets + 1, L"%02x"); i++; //т.к. следующий симовл уже учли - wchar_t ch2 = nLevelOffsets + 1; - m_sNumber += ch2; + + nText++; } else - m_sText += sText[i]; + { + std::wstring s (sText.c_str() + i, 1); + m_sText += RtfChar::renderRtfText(s); + nText++; + } nLevelOffsets++; } - wchar_t ch = (wchar_t)m_sText.length(); - m_sText.insert(m_sText.begin() + 0, ch ); + m_sText = L"\\'" + XmlUtils::ToString(nText, L"%02x") + m_sText; } std::wstring RtfListLevelProperty::RenderToOOX(RenderParameter oRenderParameter) { @@ -2279,10 +2375,7 @@ std::wstring RtfListProperty::RenderToOOX(RenderParameter oRenderParameter) RtfListOverrideProperty::ListOverrideLevels::ListOverrideLevels() { } -RtfListOverrideProperty::ListOverrideLevels::ListOverrideLevels( const ListOverrideLevels& oOverLevel ) -{ - (*this) = oOverLevel; -} + RtfListOverrideProperty::ListOverrideLevels& RtfListOverrideProperty::ListOverrideLevels::operator=( const ListOverrideLevels& oOverLevel ) { m_aOverrideLevels.clear(); @@ -2946,6 +3039,7 @@ std::wstring RtfTab::RenderToOOX(RenderParameter oRenderParameter) case tk_tqdec: sTab += L" w:val=\"decimal\""; break; case tk_tqbar: sTab += L" w:val=\"bar\""; break; case tk_tqclear:sTab += L" w:val=\"clear\""; break; + case tk_tqnum: sTab += L" w:val=\"num\""; break; default: break; } @@ -2961,15 +3055,7 @@ RtfTabs::RtfTabs() { SetDefault(); } -RtfTabs::RtfTabs( const RtfTabs& oTabs ) -{ - SetDefault(); -} -const RtfTabs& RtfTabs::operator=( const RtfTabs& oTabs ) -{ - Merge( oTabs ); - return (*this); -} + void RtfTabs::Merge( const RtfTabs& oTabs ) { m_aTabs.clear(); @@ -2991,7 +3077,7 @@ std::wstring RtfTabs::RenderToRtf(RenderParameter oRenderParameter) std::wstring RtfTabs::RenderToOOX(RenderParameter oRenderParameter) { std::wstring sTabs; - for (size_t i = 0; i < (int)m_aTabs.size(); i++ ) + for (size_t i = 0; i < m_aTabs.size(); i++ ) { sTabs += m_aTabs[i].RenderToOOX( oRenderParameter ); } @@ -3352,7 +3438,7 @@ void RtfParagraphProperty::SetDefault() m_oCharProperty.SetDefault(); m_bHidden = false; - m_bOldList = false; + m_bList = false; m_pOldParagraphProp = RtfParagraphPropertyPtr(); } void RtfParagraphProperty::Merge( RtfParagraphProperty& oParPr ) @@ -3735,7 +3821,7 @@ std::wstring RtfParagraphProperty::RenderToOOX(RenderParameter oRenderParameter) if( m_nIndFirstLine >= 0 ) sIndent += L" w:firstLine=\"" + std::to_wstring(m_nIndFirstLine) + L"\""; else sIndent += L" w:hanging=\"" + std::to_wstring(-m_nIndFirstLine) + L"\""; } - else if (m_bOldList && PROP_DEF != m_nIndLeft) + else if ((m_bList || (PROP_DEF != m_nListId && PROP_DEF != m_nListLevel)) && PROP_DEF != m_nIndLeft) sIndent += L" w:firstLine=\"0\""; if( !sIndent.empty() ) @@ -3830,19 +3916,19 @@ std::wstring RtfParagraphProperty::RenderToOOX(RenderParameter oRenderParameter) { if( true == m_oBorderTop.IsValid() ) { - sBorder += L""; + sBorder += L""; } if( true == m_oBorderLeft.IsValid() ) { - sBorder += L""; + sBorder += L""; } if( true == m_oBorderBottom.IsValid() ) { - sBorder += L""; + sBorder += L""; } if( true == m_oBorderRight.IsValid() ) { - sBorder += L""; + sBorder += L""; } } @@ -3917,7 +4003,7 @@ std::wstring RtfParagraphProperty::RenderToOOX(RenderParameter oRenderParameter) RenderParameter oRenderParameterNew = oRenderParameter; oRenderParameterNew.nType = RENDER_TO_OOX_PARAM_UNKNOWN; - sResult += L"m_nCurTrackChangesId++).c_str() + L"\">"; + sResult += L"m_nCurTrackChangesId++).c_str() + L"\">"; sResult += L""; sResult += m_pOldParagraphProp->RenderToOOX(oRenderParameterNew); sResult += L""; @@ -4237,10 +4323,11 @@ std::wstring RtfCellProperty::RenderToOOX(RenderParameter oRenderParameter) if( PROP_DEF != m_nWidth ) { if( mu_Percent == m_eWidthUnit ) - sResult += L""; + sResult += L""; else if( mu_Twips == m_eWidthUnit ) - sResult += L""; + sResult += L""; } + RENDER_OOX_INT(m_nSpan, sResult, L"w:gridSpan"); RENDER_OOX_BOOL( m_bHideMark, sResult, L"w:hideMark" ) RenderParameter oNewParam = oRenderParameter; @@ -4257,26 +4344,26 @@ std::wstring RtfCellProperty::RenderToOOX(RenderParameter oRenderParameter) oNewParam.sValue = L"w:tr2bl"; sBorder += m_oBorderDiagonalRL.RenderToOOX(oNewParam); } + if( true == m_oBorderTop.IsValid() ) + { + oNewParam.sValue = L"w:top"; + sBorder += m_oBorderTop.RenderToOOX(oNewParam); + } if( true == m_oBorderLeft.IsValid() ) { oNewParam.sValue = L"w:left"; sBorder += m_oBorderLeft.RenderToOOX(oNewParam); } - if( true == m_oBorderTop.IsValid() ) + if( true == m_oBorderBottom.IsValid() ) { - oNewParam.sValue = L"w:top"; - sBorder += m_oBorderTop.RenderToOOX(oNewParam); + oNewParam.sValue = L"w:bottom"; + sBorder += m_oBorderBottom.RenderToOOX(oNewParam); } if( true == m_oBorderRight.IsValid() ) { oNewParam.sValue = L"w:right"; sBorder += m_oBorderRight.RenderToOOX(oNewParam); } - if( true == m_oBorderBottom.IsValid() ) - { - oNewParam.sValue = L"w:bottom"; - sBorder += m_oBorderBottom.RenderToOOX(oNewParam); - } if( true == m_oBorderInsideH.IsValid() ) { oNewParam.sValue = L"w:insideH"; @@ -4324,8 +4411,6 @@ std::wstring RtfCellProperty::RenderToOOX(RenderParameter oRenderParameter) break; } - RENDER_OOX_INT( m_nSpan, sResult, L"w:gridSpan" ); - //std::wstring scnfStyle; //RENDER_OOX_BOOL_ATTRIBUTE( m_bStyleFirstRow, scnfStyle, L"w:firstRow" ) //RENDER_OOX_BOOL_ATTRIBUTE( m_bStyleLastRow, scnfStyle, L"w:lastRow" ) @@ -5056,14 +5141,14 @@ std::wstring RtfRowProperty::RenderToOOX(RenderParameter oRenderParameter) // std::wstring sAuthor = poRtfDocument->m_oRevisionTable.GetAuthor(oReader.m_oState->m_oCharProp.m_nRevauthDel); // std::wstring sDate(RtfUtility::convertDateTime(oReader.m_oState->m_oCharProp.m_nRevdttmDel).c_str()); - // sResult += L"m_nCurTrackChangesId++).c_str() + L"\"/>"; + // sResult += L"m_nCurTrackChangesId++).c_str() + L"\"/>"; //} //if ( PROP_DEF != oReader.m_oState->m_oCharProp.m_nRevised ) //{ // std::wstring sAuthor = poRtfDocument->m_oRevisionTable.GetAuthor(oReader.m_oState->m_oCharProp.m_nRevauth); // std::wstring sDate(RtfUtility::convertDateTime(oReader.m_oState->m_oCharProp.m_nRevdttm).c_str()); // - // sResult += L"m_nCurTrackChangesId++).c_str() + L"\"/>"; + // sResult += L"m_nCurTrackChangesId++).c_str() + L"\"/>"; //} std::wstring sAuthor = poRtfDocument->m_oRevisionTable.GetAuthor(m_nTrAuth); std::wstring sDate(RtfUtility::convertDateTime(m_nTrDate).c_str()); @@ -5074,11 +5159,11 @@ std::wstring RtfRowProperty::RenderToOOX(RenderParameter oRenderParameter) if (rowChangeProps.empty()) { - sResult += L"m_nCurTrackChangesId++).c_str() + L"\"/>"; + sResult += L"m_nCurTrackChangesId++).c_str() + L"\"/>"; } else { - sResult += L"m_nCurTrackChangesId++).c_str() + L"\">"; + sResult += L"m_nCurTrackChangesId++).c_str() + L"\">"; sResult += L""; sResult += rowChangeProps; sResult += L""; diff --git a/RtfFile/Format/RtfProperty.h b/RtfFile/Format/RtfProperty.h index 1089d1d4237..fe464e8a4f8 100644 --- a/RtfFile/Format/RtfProperty.h +++ b/RtfFile/Format/RtfProperty.h @@ -304,7 +304,7 @@ class RtfBorder { public: enum _BorderType - { + { bt_none, bt_brdrs, //brdrs Single-thickness border. bt_brdrth, //brdrth Double-thickness border. @@ -335,8 +335,8 @@ class RtfBorder bt_brdrdashdotstr, //brdrdashdotstr Striped border. bt_brdremboss, //brdremboss Embossed border. bt_brdrengrave, //brdrengrave Engraved border. - } m_eType; - + }; + _INT32 m_eType; _INT32 m_nWidth; _INT32 m_nSpace; _INT32 m_nColor; @@ -347,6 +347,8 @@ class RtfBorder bool IsValid(); _INT32 GetType(); + std::wstring GetBorderType(); + void SetDefaultRtf( ); void SetDefaultOOX( ); void SetDefault( ); @@ -356,6 +358,7 @@ class RtfBorder std::wstring RenderToRtf(RenderParameter oRenderParameter); std::wstring RenderToOOX(RenderParameter oRenderParameter); + std::wstring RenderToShapeOOX(RenderParameter oRenderParameter); static bool GetStringRtfByType( _BorderType nValue, std::wstring& sValue ); static std::wstring GetStringOOXByType( _BorderType nValue, std::wstring& sValue ); @@ -379,7 +382,8 @@ class RtfTab : public IRenderableProperty tk_tqc, //tqc Centered tab. tk_tqdec, //tqdec Decimal tab. tk_tqbar, //tbN Bar tab position in twips from the left margin. - tk_tqclear + tk_tqclear, + tk_tqnum } m_eKind; _INT32 m_nTab; //tbN or \txN Tab position in twips from the left margin. @@ -400,9 +404,6 @@ class RtfTabs: public IRenderableProperty std::vector m_aTabs; RtfTabs(); - RtfTabs( const RtfTabs& oTabs ); - - const RtfTabs& operator=( const RtfTabs& oTabs ); void Merge( const RtfTabs& oTabs ); void SetDefault(); @@ -419,24 +420,25 @@ typedef boost::shared_ptr RtfCharPropertyPtr; class RtfCharProperty: public IRenderableProperty { public: - bool m_bListLevel; + bool m_bListLevel = false; + bool m_bAssociated = false; enum _UnderlineStyle {uls_none, uls_Single, uls_Dotted,uls_Dashed ,uls_Dash_dotted,uls_Dash_dot_dotted,uls_Double,uls_Heavy_wave,uls_Long_dashe,uls_Stops_all,uls_Thick,uls_Thick_dotted,uls_Thick_dashed,uls_Thick_dash_dotted,uls_Thick_dash_dot_dotted,uls_Thick_long_dashed,uls_Double_wave,uls_Word,uls_Wave}; _INT32 m_nAnimated; //animtextN Animated text properties (note: Word 2007 ignores this control word): _INT32 m_bBold; //b* Bold. - _INT32 m_bCaps; //caps* All capitals. + _INT32 m_bCaps; //caps* All capitals. _INT32 m_nScalex; //charscalexN Character scaling value. The N argument is a value representing a percentage (default is 100). _INT32 m_nCharStyle; //csN Designates character style. If a character style is specified, style properties must be specified with the character run. N refers to an entry in the style table. - _INT32 m_nDown; //dnN Move down N half-points (default is 6). - _INT32 m_bEmbo; //embo* Emboss. - _INT32 m_nCharacterSpacing;//expndtwN Expansion or compression of the space between characters in twips; a negative value compresses. For backward compatibility, both \expndtwN and \expndN should be emitted. + _INT32 m_nDown; //dnN Move down N half-points (default is 6). + _INT32 m_bEmbo; //embo* Emboss. + _INT32 m_nCharacterSpacing; //expndtwN Expansion or compression of the space between characters in twips; a negative value compresses. For backward compatibility, both \expndtwN and \expndN should be emitted. _INT32 m_nFitText; //fittextN Fit the text in the current group in N twips. When N is set to -1 (\fittext-1), it indicates a continuation of the previous \fittextN run. In other words, {\fittext1000 Fit this} {\fittext-1 text} fits the string “Fit this text” in 1000 twips. - _INT32 m_nFont; //fN Font number. N refers to an entry in the font table. + _INT32 m_nFont; //fN Font number. N refers to an entry in the font table. _INT32 m_nFont2; _INT32 m_nFont3; - _INT32 m_nFontSize; //fsN Font size in half-points (default is 24). + _INT32 m_nFontSize; //fsN Font size in half-points (default is 24). _INT32 m_bItalic; //i* Italic. _INT32 m_bImprint; //impr* Engrave (imprint). _INT32 m_nKerning; //kerningN Point size (in half-points) above which to kern character pairs. \kerning0 turns off kerning. @@ -454,24 +456,24 @@ class RtfCharProperty: public IRenderableProperty _INT32 m_bHidden; //v* Hidden text. _INT32 m_nHightlited; - _INT32 m_nForeColor; + _INT32 m_nForeColor; - _INT32 m_nCrAuth; - _INT32 m_nCrDate; + _INT32 m_nCrAuth; + _INT32 m_nCrDate; - _INT32 m_nDeleted; - _INT32 m_nRevised; - _INT32 m_nRevauth; - _INT32 m_nRevdttm; - _INT32 m_nRevauthDel; - _INT32 m_nRevdttmDel; + _INT32 m_nDeleted; + _INT32 m_nRevised; + _INT32 m_nRevauth; + _INT32 m_nRevdttm; + _INT32 m_nRevauthDel; + _INT32 m_nRevdttmDel; - _INT32 m_nInsrsid; + _INT32 m_nInsrsid; -// _INT32 m_bUnderline; //ul* Continuous underline. \ul0 turns off all underlining. +// _INT32 m_bUnderline; //ul* Continuous underline. \ul0 turns off all underlining. _UnderlineStyle m_eUnderStyle; // - _INT32 m_nUnderlineColor; // - _INT32 m_nUp; //upN Move up N half-points (default is 6). + _INT32 m_nUnderlineColor; // + _INT32 m_nUp; //upN Move up N half-points (default is 6). RtfCharPropertyPtr m_pOldCharProp; RtfBorder m_poBorder; @@ -506,14 +508,14 @@ class RtfListLevelProperty : IRenderableProperty _INT32 m_nNoRestart; //levelnorestartN 1 if this level does not restart its count each time a super ordinate level is incremented; 0 if this level does restart its count each time a super ordinate level is incremented. _INT32 m_nLegal; //levellegalN 1 if any list numbers from previous levels should be converted to Arabic numbers; 0 if they should be left with the format specified by their own level’s definition. _INT32 m_nPictureIndex; //levelpictureN Determines which picture bullet from the \listpicture destination should be applied. - - RtfTabs m_oTabs; //ParagraphProp +//ParagraphProp + RtfTabs m_oTabs; _INT32 m_nFirstIndent; _INT32 m_nIndent; _INT32 m_nIndentStart; - _INT32 m_nSpace; - - RtfCharProperty m_oCharProp; //Char + _INT32 m_nSpace; + + RtfCharProperty m_oCharProp; RtfListLevelProperty(); @@ -521,15 +523,17 @@ class RtfListLevelProperty : IRenderableProperty std::wstring GenerateListText(); void SetDefault(); - std::wstring RenderToRtf(RenderParameter oRenderParameter); + void Merge(RtfListLevelProperty& oListLevel); + + std::wstring RenderToRtf(RenderParameter oRenderParameter); std::wstring RenderToOOX(RenderParameter oRenderParameter); std::wstring RenderToOOX2(RenderParameter oRenderParameter, _INT32 lvl = PROP_DEF); static std::wstring GetFormat( _INT32 nNumFormat); - static _INT32 GetFormat( std::wstring sFormat); + static _INT32 GetFormat(const std::wstring& sFormat); std::wstring GetLevelTextOOX(); - void SetLevelTextOOX(std::wstring sText); + void SetLevelTextOOX(const std::wstring& sText); }; class RtfListProperty : public IRenderableProperty, public ItemContainer @@ -571,7 +575,6 @@ class RtfListOverrideProperty : IRenderableProperty std::vector m_aOverrideLevels; ListOverrideLevels(); - ListOverrideLevels( const ListOverrideLevels& oOverLevel ); ListOverrideLevels& operator=( const ListOverrideLevels& oOverLevel ); void SetDefault(); @@ -875,10 +878,10 @@ class RtfCellProperty: public IRenderableProperty _INT32 m_nSpacingBottom; _INT32 m_eSpacingBottomUnit; - _INT32 m_nWidth; //clwWidthN Preferred cell width. Overrides \trautofitN. - _INT32 m_eWidthUnit; //clftsWidthN Units for \clwWidthN: + _INT32 m_nWidth; //clwWidthN Preferred cell width. Overrides \trautofitN. + _INT32 m_eWidthUnit; //clftsWidthN Units for \clwWidthN: - _INT32 m_bHideMark; //clhidemark This control word specifies whether the end of cell glyph shall influence the height of the given table row in the table. If it is specified, then only printing characters in this cell shall be used to determine the row height. + _INT32 m_bHideMark; //clhidemark This control word specifies whether the end of cell glyph shall influence the height of the given table row in the table. If it is specified, then only printing characters in this cell shall be used to determine the row height. RtfBorder m_oBorderDiagonalLR; RtfBorder m_oBorderDiagonalRL; @@ -890,7 +893,7 @@ class RtfCellProperty: public IRenderableProperty RtfBorder m_oBorderInsideV; RtfShadingCell m_oShading; - _INT32 m_nShadingPctFrom; + _INT32 m_nShadingPctFrom; typedef enum{ ca_none, ca_Top, //clvertalt Text is top-aligned in cell (the default). @@ -1005,8 +1008,9 @@ typedef boost::shared_ptr RtfParagraphPropertyPtr; class RtfParagraphProperty: public IRenderableProperty { public: - bool m_bHidden; - bool m_bOldList; + bool m_bHidden = false; + bool m_bList = false; + RtfParagraphPropertyPtr m_pOldParagraphProp; //------------- _INT32 m_bAutoHyphenation; //hyphpar Switches automatic hyphenation for the paragraph. Append 1 or nothing to toggle property on; append 0 to turn it off. @@ -1076,9 +1080,9 @@ class RtfParagraphProperty: public IRenderableProperty tbw_txbxtwfirstlast, //txbxtwfirstlast tbw_txbxtwfirst, //txbxtwfirst tbw_txbxtwlast, //txbxtwlast - } m_eTextBoxWrap; - _INT32 m_nListId; //lsN Should exactly match the \lsN for one of the list overrides in the List Override table. - _INT32 m_nListLevel; //ilvlN The 0-based level of the list to which the paragraph belongs. For all simple lists, N should always be 0. For multilevel lists, it can be 0 through 8. The value 9 is never used. The values 10 through 12 have the special meanings for documents generated by Word 6: 10 = ilvlBullet (a bulleted paragraph in Word 6), 11 = ilvlList (a numbered paragraph in Word 6), 12 = ilvlContinue (a paragraph that was not itself numbered, but took its indenting scheme from its numbering properties and did not “break” numbering (that in Word 6 required otherwise contiguous paragraphs). + } m_eTextBoxWrap; + _INT32 m_nListId; //lsN Should exactly match the \lsN for one of the list overrides in the List Override table. + _INT32 m_nListLevel; //ilvlN The 0-based level of the list to which the paragraph belongs. For all simple lists, N should always be 0. For multilevel lists, it can be 0 through 8. The value 9 is never used. The values 10 through 12 have the special meanings for documents generated by Word 6: 10 = ilvlBullet (a bulleted paragraph in Word 6), 11 = ilvlList (a numbered paragraph in Word 6), 12 = ilvlContinue (a paragraph that was not itself numbered, but took its indenting scheme from its numbering properties and did not “break” numbering (that in Word 6 required otherwise contiguous paragraphs). RtfShadingPar m_oShading; @@ -1089,8 +1093,8 @@ class RtfParagraphProperty: public IRenderableProperty RtfBorder m_oBorderBox; RtfBorder m_oBorderBar; - RtfFrame m_oFrame; - _INT32 m_bOverlap; //1\absnoovrlpN Allow overlap with other frames or objects with similar wrapping: + RtfFrame m_oFrame; + _INT32 m_bOverlap; //1\absnoovrlpN Allow overlap with other frames or objects with similar wrapping: enum _TextFollow { tf_none, @@ -1099,8 +1103,8 @@ class RtfParagraphProperty: public IRenderableProperty tf_frmtxbtlr, //frmtxbtlr Frame box flows left to right and bottom to top. tf_frmtxlrtbv, //frmtxlrtbv Frame box flows left to right and top to bottom, vertical. tf_frmtxtbrlv //frmtxtbrlv Frame box flows top to bottom and right to left, vertical. - } m_eTextFollow; - RtfTabs m_oTabs; + } m_eTextFollow; + RtfTabs m_oTabs; //Table Style Specific _INT32 m_nTableStyle; // ytsN Designates the table style handle that was applied to the row/cell. @@ -1120,9 +1124,9 @@ class RtfParagraphProperty: public IRenderableProperty _INT32 m_nPrAuth; _INT32 m_nPrDate; - RtfCharProperty m_oCharProperty; + RtfCharProperty m_oCharProperty; - //-------------------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------------------- RtfParagraphProperty(); bool IsValid(); diff --git a/RtfFile/Format/RtfReader.cpp b/RtfFile/Format/RtfReader.cpp index 9714892bc54..6fb9f74e6a4 100644 --- a/RtfFile/Format/RtfReader.cpp +++ b/RtfFile/Format/RtfReader.cpp @@ -356,7 +356,7 @@ std::wstring RtfAbstractReader::ExecuteTextInternalCodePage( std::string& sCharS nCodepage = oFont.m_nCodePage; } else if ((PROP_DEF != oFont.m_nCharset && oFont.m_nCharset > 2) - && (PROP_DEF == oDocument.m_oProperty.m_nAnsiCodePage || 0 == oDocument.m_oProperty.m_nAnsiCodePage)) + && (PROP_DEF == oDocument.m_oProperty.m_nAnsiCodePage || 0 == oDocument.m_oProperty.m_nAnsiCodePage || 1252 == oDocument.m_oProperty.m_nAnsiCodePage)) { nCodepage = RtfUtility::CharsetToCodepage(oFont.m_nCharset); } @@ -386,7 +386,7 @@ std::wstring RtfAbstractReader::ExecuteTextInternalCodePage( std::string& sCharS { nCodepage = CP_ACP; } - if (nCodepage == CP_ACP && oDocument.m_nUserLCID > 0) + if ((nCodepage == CP_ACP || nCodepage == 1252)&& oDocument.m_nUserLCID > 0) { nCodepage = oDocument.m_lcidConverter.get_codepage(oDocument.m_nUserLCID); } diff --git a/RtfFile/Format/RtfSection.cpp b/RtfFile/Format/RtfSection.cpp index f4cddef8195..50b69589a8c 100644 --- a/RtfFile/Format/RtfSection.cpp +++ b/RtfFile/Format/RtfSection.cpp @@ -1000,7 +1000,7 @@ std::wstring RtfSectionProperty::RenderToOOX(RenderParameter oRenderParameter) RenderParameter oRenderParameterNew = oRenderParameter; oRenderParameterNew.nType = RENDER_TO_OOX_PARAM_UNKNOWN; - sResult += L"m_nCurTrackChangesId++).c_str() + L"\">"; + sResult += L"m_nCurTrackChangesId++).c_str() + L"\">"; sResult += m_pOldSectionProp->RenderToOOX(oRenderParameterNew); sResult += L""; } diff --git a/RtfFile/Format/RtfShape.cpp b/RtfFile/Format/RtfShape.cpp index b54a468298f..fd47c3119db 100644 --- a/RtfFile/Format/RtfShape.cpp +++ b/RtfFile/Format/RtfShape.cpp @@ -119,6 +119,11 @@ void RtfShape::SetDefault() DEFAULT_PROPERTY( m_eYAnchor ) DEFAULT_PROPERTY( m_nLockPosition ) DEFAULT_PROPERTY( m_nLockRotation ) + + DEFAULT_PROPERTY(m_nBorderTopColor) + DEFAULT_PROPERTY(m_nBorderLeftColor) + DEFAULT_PROPERTY(m_nBorderRightColor) + DEFAULT_PROPERTY(m_nBorderBottomColor) //Position absolute DEFAULT_PROPERTY( m_nPositionH ) DEFAULT_PROPERTY( m_nPositionHRelative ) @@ -259,7 +264,7 @@ std::wstring RtfShape::RenderToRtf(RenderParameter oRenderParameter) { if (m_bIsGroup) return GroupRenderToRtf(oRenderParameter); - if( PROP_DEF == m_nShapeType) return L""; + if ( PROP_DEF == m_nShapeType) return L""; std::wstring sResult; //запоминаем координаты и если нужно поворачиваем @@ -275,11 +280,11 @@ std::wstring RtfShape::RenderToRtf(RenderParameter oRenderParameter) int nRelBottom = m_nRelBottom; int nRelRotate = m_nRelRotation; - if( PROP_DEF != m_nRotation && PROP_DEF != m_nLeft && PROP_DEF != m_nTop && + if ( PROP_DEF != m_nRotation && PROP_DEF != m_nLeft && PROP_DEF != m_nTop && PROP_DEF != m_nRight && PROP_DEF != m_nBottom ) ToRtfRotation( m_nRotation, m_nLeft, m_nTop, m_nRight, m_nBottom ); - if( PROP_DEF != m_nRelRotation && PROP_DEF != m_nRelLeft && PROP_DEF != m_nRelTop && + if ( PROP_DEF != m_nRelRotation && PROP_DEF != m_nRelLeft && PROP_DEF != m_nRelTop && PROP_DEF != m_nRelRight && PROP_DEF != m_nRelBottom ) ToRtfRotation( m_nRelRotation, m_nRelLeft, m_nRelTop, m_nRelRight, m_nRelBottom ); @@ -292,7 +297,7 @@ std::wstring RtfShape::RenderToRtf(RenderParameter oRenderParameter) } else if (( st_inline == m_eAnchorTypeShape || st_none == m_eAnchorTypeShape) && !m_bIsOle) { - if( NULL != m_oPicture && m_nShapeType == ODRAW::sptPictureFrame && !m_bInGroup) + if ( NULL != m_oPicture && m_nShapeType == ODRAW::sptPictureFrame && !m_bInGroup) { if (m_oPicture->m_nWidth == PROP_DEF) { @@ -304,19 +309,34 @@ std::wstring RtfShape::RenderToRtf(RenderParameter oRenderParameter) m_oPicture->m_nWidthGoal = m_oPicture->m_nWidth; m_oPicture->m_nHeightGoal = m_oPicture->m_nHeight; } - if( RtfPicture::dt_wmf == m_oPicture->eDataType ) + if ( RtfPicture::dt_wmf == m_oPicture->eDataType ) { sResult += m_oPicture->RenderToRtf( oRenderParameter ); } else { sResult += L"{\\*\\shppict"; + + if (m_bLine) + { + if (m_nBorderTopColor == PROP_DEF) + m_nBorderTopColor = m_nBorderLeftColor = m_nBorderTopColor = m_nBorderBottomColor = m_nLineColor; - m_oPicture->dump_shape_properties = RenderToRtfShapeProperty( oRenderParameter ); + INT brdrw = PROP_DEF; + if (PROP_DEF != m_nLineWidth) + { + m_oPicture->m_oBorderTop.m_nWidth = m_oPicture->m_oBorderLeft.m_nWidth = + m_oPicture->m_oBorderBottom.m_nWidth = m_oPicture->m_oBorderRight.m_nWidth = m_nLineWidth / 576; + + m_oPicture->m_oBorderTop.m_eType = m_oPicture->m_oBorderLeft.m_eType = m_oPicture->m_oBorderBottom.m_eType = m_oPicture->m_oBorderRight.m_eType = RtfBorder::bt_brdrs; + } + } + m_oPicture->dump_shape_properties = RenderToRtfShapeProperty(oRenderParameter); sResult += m_oPicture->RenderToRtf( oRenderParameter ); - + sResult += L"}"; + sResult += L"{\\nonshppict"; sResult += m_oPicture->GenerateWMF( oRenderParameter ); @@ -374,20 +394,20 @@ std::wstring RtfShape::RenderToRtf(RenderParameter oRenderParameter) //sResult += L"{\\sp{\\sn fLockRotation}{\\sv 1}}"; //picture - if( NULL != m_oPicture && m_nShapeType == ODRAW::sptPictureFrame && m_bInGroup) + if ( NULL != m_oPicture && m_nShapeType == ODRAW::sptPictureFrame && m_bInGroup) { sResult += L"{\\sp{\\sn pib}{\\sv "; sResult += m_oPicture->RenderToRtf( oRenderParameter ); sResult += L"}}"; } - else if( NULL != m_oPicture && m_nFillType == 1 || m_nFillType == 2 || m_nFillType == 3 || m_nFillType == 9) + else if ( NULL != m_oPicture && m_nFillType == 1 || m_nFillType == 2 || m_nFillType == 3 || m_nFillType == 9) { sResult += L"{\\sp{\\sn fillBlip}{\\sv "; sResult += m_oPicture->RenderToRtf( oRenderParameter ); sResult += L"}}"; } //textbox - if( 0 != m_aTextItems ) + if ( 0 != m_aTextItems ) { sResult += L"{\\shptxt "; sResult += m_aTextItems->RenderToRtf( oRenderParameter ); @@ -439,7 +459,7 @@ std::wstring RtfShape::RenderToRtf(RenderParameter oRenderParameter) sResult += RenderToRtfShapeProperty( oRenderParameter ); //picture - if( 0 != m_oPicture) + if ( 0 != m_oPicture) { if (m_nShapeType == ODRAW::sptPictureFrame) { @@ -456,14 +476,14 @@ std::wstring RtfShape::RenderToRtf(RenderParameter oRenderParameter) } } //textbox - if( m_aTextItems ) + if ( m_aTextItems ) { sResult += L"{\\shptxt "; sResult += m_aTextItems->RenderToRtf( oRenderParameter ); sResult += L"}"; } sResult += L"}"; - if( m_oPicture && m_nShapeType == ODRAW::sptPictureFrame ) + if ( m_oPicture && m_nShapeType == ODRAW::sptPictureFrame ) { sResult += L"{\\shprslt\\par\\plain"; sResult += m_oPicture->GenerateWMF( oRenderParameter ); @@ -511,6 +531,11 @@ std::wstring RtfShape::RenderToRtfShapeProperty(RenderParameter oRenderParameter RENDER_RTF_SHAPE_PROP(L"fLayoutInCell", sResult, m_bLayoutInCell); RENDER_RTF_SHAPE_PROP(L"fAllowOverlap", sResult, m_bAllowOverlap); + RENDER_RTF_SHAPE_PROP(L"o:bordertopcolor", sResult, m_nBorderTopColor); + RENDER_RTF_SHAPE_PROP(L"o:borderleftcolor", sResult, m_nBorderLeftColor); + RENDER_RTF_SHAPE_PROP(L"o:borderbottomcolor", sResult, m_nBorderRightColor); + RENDER_RTF_SHAPE_PROP(L"o:borderrightcolor", sResult, m_nBorderBottomColor); + //Position relative RENDER_RTF_SHAPE_PROP(L"pctHorizPos", sResult, m_nPositionHPct); RENDER_RTF_SHAPE_PROP(L"pctVertPos", sResult, m_nPositionVPct); @@ -584,7 +609,7 @@ std::wstring RtfShape::RenderToRtfShapeProperty(RenderParameter oRenderParameter RENDER_RTF_SHAPE_PROP(L"geoBottom", sResult, m_nGeoBottom ); RENDER_RTF_SHAPE_PROP(L"shapePath", sResult, m_nShapePath ); - if( !m_aPVerticles.empty()) + if ( !m_aPVerticles.empty()) { sResult += L"{\\sp{\\sn pVerticies}{\\sv 8;" + std::to_wstring( (int)m_aPVerticles.size() ); for (size_t i = 0; i < m_aPVerticles.size(); i ++ ) @@ -593,7 +618,7 @@ std::wstring RtfShape::RenderToRtfShapeProperty(RenderParameter oRenderParameter } sResult += L"}}"; } - if( !m_aPSegmentInfo.empty()) + if ( !m_aPSegmentInfo.empty()) { sResult += L"{\\sp{\\sn pSegmentInfo}{\\sv 2;" + std::to_wstring( (int)m_aPSegmentInfo.size() ); for (size_t i = 0; i < m_aPSegmentInfo.size(); i ++ ) @@ -620,7 +645,7 @@ std::wstring RtfShape::RenderToRtfShapeProperty(RenderParameter oRenderParameter RENDER_RTF_SHAPE_PROP(L"relRotation", sResult, m_nRelRotation ); RENDER_RTF_SHAPE_PROP(L"dhgt", sResult, m_nRelZOrder ); //Fill - if( 0 == m_bFilled) + if ( 0 == m_bFilled) sResult += L"{\\sp{\\sn fFilled}{\\sv 0}}"; RENDER_RTF_SHAPE_PROP(L"fillType", sResult, m_nFillType ); RENDER_RTF_SHAPE_PROP(L"fillColor", sResult, m_nFillColor ); @@ -654,7 +679,7 @@ std::wstring RtfShape::RenderToRtfShapeProperty(RenderParameter oRenderParameter sResult += L"}}"; } //Line - if( 0 == m_bLine ) + if ( 0 == m_bLine ) sResult += L"{\\sp{\\sn fLine}{\\sv 0}}"; RENDER_RTF_SHAPE_PROP(L"lineColor", sResult, m_nLineColor ); RENDER_RTF_SHAPE_PROP(L"lineStartArrowhead", sResult, m_nLineStartArrow ); @@ -667,7 +692,7 @@ std::wstring RtfShape::RenderToRtfShapeProperty(RenderParameter oRenderParameter RENDER_RTF_SHAPE_PROP(L"lineDashing", sResult, m_nLineDashing ); //pWrapPolygonVertices Points of the text wrap polygon. - if( !m_aWrapPoints.empty()) + if ( !m_aWrapPoints.empty()) { sResult += L"{\\sp{\\sn pWrapPolygonVertices}{\\sv 8;" + std::to_wstring((int)m_aWrapPoints.size()); for( size_t i = 0; i < m_aWrapPoints.size(); i ++ ) @@ -675,29 +700,29 @@ std::wstring RtfShape::RenderToRtfShapeProperty(RenderParameter oRenderParameter sResult += L"}}"; } //WordArt - if( PROP_DEF != m_bGtext ) + if ( PROP_DEF != m_bGtext ) { RENDER_RTF_SHAPE_PROP(L"fGtext", sResult, m_bGtext ); int nCodePage = 48; //utf-16 - if( m_sGtextFont.empty() == false) + if ( m_sGtextFont.empty() == false) { sResult += L"{\\sp{\\sn gtextFont}{\\sv "; sResult += m_sGtextFont + L"}}"; //--------------------------------- RtfFont oFont; - if( true == pDocument->m_oFontTable.GetFont( m_sGtextFont, oFont ) ) + if ( true == pDocument->m_oFontTable.GetFont( m_sGtextFont, oFont ) ) { if (PROP_DEF != oFont.m_nCodePage) nCodePage = oFont.m_nCodePage; - else if( PROP_DEF != oFont.m_nCharset && oFont.m_nCharset > 2) + else if ( PROP_DEF != oFont.m_nCharset && oFont.m_nCharset > 2) nCodePage = RtfUtility::CharsetToCodepage( oFont.m_nCharset ); } } - if( !m_sGtextUNICODE.empty() ) + if ( !m_sGtextUNICODE.empty() ) { sResult += L"{\\sp{\\sn gtextUNICODE}{\\sv "; sResult += RtfChar::renderRtfText(m_sGtextUNICODE, oRenderParameter.poDocument, nCodePage); @@ -716,31 +741,31 @@ std::wstring RtfShape::RenderToRtfShapeProperty(RenderParameter oRenderParameter RENDER_RTF_SHAPE_PROP(L"fIsSignatureLine", sResult, m_bIsSignatureLine); RENDER_RTF_SHAPE_PROP(L"fSigSetupAllowComments", sResult, m_bSigSetupAllowComments); - if( !m_sSigSetupId.empty() ) + if ( !m_sSigSetupId.empty() ) { sResult += L"{\\sp{\\sn wzSigSetupId}{\\sv "; sResult += RtfChar::renderRtfText(m_sSigSetupId, oRenderParameter.poDocument, 48); //utf-16 sResult += L"}}"; } - if( !m_sSigSetupProvId.empty() ) + if ( !m_sSigSetupProvId.empty() ) { sResult += L"{\\sp{\\sn wzSigSetupProvId}{\\sv "; sResult += RtfChar::renderRtfText(m_sSigSetupProvId, oRenderParameter.poDocument, 48); //utf-16 sResult += L"}}"; } - if( !m_sSigSetupSuggSigner.empty() ) + if ( !m_sSigSetupSuggSigner.empty() ) { sResult += L"{\\sp{\\sn wzSigSetupSuggSigner}{\\sv "; sResult += RtfChar::renderRtfText(m_sSigSetupSuggSigner, oRenderParameter.poDocument, 48); //utf-16 sResult += L"}}"; } - if( !m_sSigSetupSuggSigner2.empty() ) + if ( !m_sSigSetupSuggSigner2.empty() ) { sResult += L"{\\sp{\\sn wzSigSetupSuggSigner2}{\\sv "; sResult += RtfChar::renderRtfText(m_sSigSetupSuggSigner2, oRenderParameter.poDocument, 48); //utf-16 sResult += L"}}"; } - if( !m_sSigSetupSuggSignerEmail.empty() ) + if ( !m_sSigSetupSuggSignerEmail.empty() ) { sResult += L"{\\sp{\\sn wzSigSetupSuggSignerEmail}{\\sv "; sResult += RtfChar::renderRtfText(m_sSigSetupSuggSignerEmail, oRenderParameter.poDocument, 48); //utf-16 @@ -753,35 +778,35 @@ std::wstring RtfShape::RenderToOOX(RenderParameter oRenderParameter) { if (m_bIsGroup) return GroupRenderToOOX(oRenderParameter); - if( PROP_DEF == m_nShapeType ) + if ( PROP_DEF == m_nShapeType ) return L""; std::wstring sResult; RtfDocument* poDocument = static_cast(oRenderParameter.poDocument); - if( ODRAW::sptPictureFrame == m_nShapeType && 0 != m_aTextItems ) + if ( ODRAW::sptPictureFrame == m_nShapeType && 0 != m_aTextItems ) {//test for ole TextItemContainerPtr aTempTextItems = m_aTextItems; m_aTextItems = TextItemContainerPtr(); - if( 0 != aTempTextItems ) + if ( 0 != aTempTextItems ) {//пишем только Ole обьект size_t nTempTextItemsCount = aTempTextItems->GetCount(); for (size_t i = 0; i < nTempTextItemsCount; i++ ) { ITextItemPtr piCurTextItem; aTempTextItems->GetItem( piCurTextItem, (int)i ); - if( NULL != piCurTextItem && TYPE_RTF_PARAGRAPH == piCurTextItem->GetType() ) + if ( NULL != piCurTextItem && TYPE_RTF_PARAGRAPH == piCurTextItem->GetType() ) { RtfParagraphPtr poCurParagraph = boost::static_pointer_cast< RtfParagraph, ITextItem >( piCurTextItem ); - if( NULL != poCurParagraph ) + if ( NULL != poCurParagraph ) { for (int j = 0; j < poCurParagraph->GetCount(); j++ ) { IDocumentElementPtr piCurIDocumentElement; poCurParagraph->GetItem( piCurIDocumentElement, j ); - if( NULL != piCurIDocumentElement && TYPE_RTF_OLE == piCurIDocumentElement->GetType() ) + if ( NULL != piCurIDocumentElement && TYPE_RTF_OLE == piCurIDocumentElement->GetType() ) { //рендерим только Ole часть RenderParameter oNewParam = oRenderParameter; @@ -789,7 +814,7 @@ std::wstring RtfShape::RenderToOOX(RenderParameter oRenderParameter) oNewParam.nValue = m_nID; RtfOlePtr poCurOle = boost::static_pointer_cast< RtfOle, IDocumentElement >( piCurIDocumentElement ); - if( NULL != poCurOle ) + if ( NULL != poCurOle ) { m_sOle += poCurOle->RenderToOOX( oNewParam ); if (!m_sOle.empty()) @@ -801,7 +826,7 @@ std::wstring RtfShape::RenderToOOX(RenderParameter oRenderParameter) } } } - if( true == m_bIsOle ) + if ( true == m_bIsOle ) break; } } @@ -813,7 +838,7 @@ std::wstring RtfShape::RenderToOOX(RenderParameter oRenderParameter) sResult = RenderToOOXBegin(oRenderParameter); - if( !sResult.empty() ) + if ( !sResult.empty() ) sResult += RenderToOOXEnd(oRenderParameter); return sResult; @@ -835,9 +860,9 @@ std::wstring RtfShape::GetShapeNodeName() } std::wstring RtfShape::RenderToOOXBegin(RenderParameter oRenderParameter) { - if( !IsValid() ) return L""; + if ( !IsValid() ) return L""; - std::wstring sResult; + std::wstring sShapeStart, sShapeNodes; RtfDocument* poRtfDocument = static_cast (oRenderParameter.poDocument); OOXWriter* poOOXWriter = static_cast (oRenderParameter.poWriter); @@ -845,17 +870,17 @@ std::wstring RtfShape::RenderToOOXBegin(RenderParameter oRenderParameter) m_bInsert = false; m_bDelete = false; - if( RENDER_TO_OOX_PARAM_SHAPE_WSHAPE2 == oRenderParameter.nType ) + if ( RENDER_TO_OOX_PARAM_SHAPE_CHILD == oRenderParameter.nType ) ;//child shape - else if( RENDER_TO_OOX_PARAM_SHAPE_WSHAPE == oRenderParameter.nType ) + else if ( RENDER_TO_OOX_PARAM_PIC_BULLET == oRenderParameter.nType ) {//pic bullets if (m_bIsOle) { - sResult += L""; + sShapeStart += L""; } else { - sResult += L""; + sShapeStart += L""; } } else @@ -867,7 +892,7 @@ std::wstring RtfShape::RenderToOOXBegin(RenderParameter oRenderParameter) std::wstring sAuthor = poRtfDocument->m_oRevisionTable.GetAuthor(m_oCharProperty.m_nRevauth); std::wstring sDate(RtfUtility::convertDateTime(m_oCharProperty.m_nRevdttm).c_str()); - sResult += L"m_nCurTrackChangesId++).c_str() + L"\">"; + sShapeStart += L"m_nCurTrackChangesId++).c_str() + L"\">"; m_oCharProperty.m_nRevised = PROP_DEF; } if (m_oCharProperty.m_nDeleted != PROP_DEF) @@ -877,24 +902,24 @@ std::wstring RtfShape::RenderToOOXBegin(RenderParameter oRenderParameter) std::wstring sAuthor = poRtfDocument->m_oRevisionTable.GetAuthor(m_oCharProperty.m_nRevauthDel); std::wstring sDate(RtfUtility::convertDateTime(m_oCharProperty.m_nRevdttmDel).c_str()); - sResult += L"m_nCurTrackChangesId++).c_str() + L"\">"; + sShapeStart += L"m_nCurTrackChangesId++).c_str() + L"\">"; m_oCharProperty.m_nDeleted = PROP_DEF; } std::wstring sCharProp = m_oCharProperty.RenderToOOX(oRenderParameter); - sResult += L""; + sShapeStart += L""; if (!sCharProp .empty()) { - sResult += L""; - sResult += sCharProp; - sResult += L""; + sShapeStart += L""; + sShapeStart += sCharProp; + sShapeStart += L""; } if (m_bIsOle) { - sResult += L""; + sShapeStart += L""; } else { - sResult += L""; + sShapeStart += L""; } } @@ -903,80 +928,80 @@ std::wstring RtfShape::RenderToOOXBegin(RenderParameter oRenderParameter) oRenderParameter.sValue = GetShapeNodeName(); } - sResult += L"<" + oRenderParameter.sValue; + sShapeStart += L"<" + oRenderParameter.sValue; - sResult += L" id=\"_x0000_s" + std::to_wstring(poRtfDocument->GetShapeId( m_nID )) + L"\""; + sShapeStart += L" id=\"_x0000_s" + std::to_wstring(poRtfDocument->GetShapeId( m_nID )) + L"\""; if (!m_sName.empty()) { - sResult += L" title=\"" + m_sName + L"\""; + sShapeStart += L" title=\"" + m_sName + L"\""; } if (!m_bIsGroup) { if (PROP_DEF != m_nShapeType && 0 != m_nShapeType) { - sResult += L" type=\"#_x0000_t" + std::to_wstring(m_nShapeType) + L"\""; - sResult += L" o:spt=\"" + std::to_wstring(m_nShapeType) + L"\""; + sShapeStart += L" type=\"#_x0000_t" + std::to_wstring(m_nShapeType) + L"\""; + sShapeStart += L" o:spt=\"" + std::to_wstring(m_nShapeType) + L"\""; } if (0 == m_bFilled || (m_nFillColor == PROP_DEF && m_nFillColor2 == PROP_DEF && m_nFillType == PROP_DEF)) - sResult += L" filled=\"f\""; //сф_850000158725_R7_M194_МО_Q194.rtf + sShapeStart += L" filled=\"f\""; //сф_850000158725_R7_M194_МО_Q194.rtf else - sResult += L" filled=\"t\""; + sShapeStart += L" filled=\"t\""; if (PROP_DEF == m_bLine) { m_bLine = (m_nShapeType == SimpleTypes::Vml::sptPictureFrame || m_nShapeType == SimpleTypes::Vml::sptTextBox) ? 0 : 1; } - if (0 == m_bLine) sResult += L" stroked=\"f\""; - else sResult += L" stroked=\"t\""; + if (0 == m_bLine) sShapeStart += L" stroked=\"f\""; + else sShapeStart += L" stroked=\"t\""; if (PROP_DEF != m_nFillColor) { RtfColor color(m_nFillColor); - sResult += L" fillcolor=\"#" + color.ToHexColor(true) + L"\""; + sShapeStart += L" fillcolor=\"#" + color.ToHexColor(true) + L"\""; } if (PROP_DEF != m_nLineColor) { RtfColor color(m_nLineColor); - sResult += L" strokecolor=\"#" + color.ToHexColor(true) + L"\""; + sShapeStart += L" strokecolor=\"#" + color.ToHexColor(true) + L"\""; } if (PROP_DEF != m_nLineWidth) - sResult += L" strokeweight=\"" + XmlUtils::ToString(RtfUtility::Emu2Pt(m_nLineWidth), L"%.2f") + L"pt\""; + sShapeStart += L" strokeweight=\"" + XmlUtils::ToString(RtfUtility::Emu2Pt(m_nLineWidth), L"%.2f") + L"pt\""; //path switch (m_nConnectionType) { - case 0: sResult += L" o:connecttype=\"custom\""; break; - case 1: sResult += L" o:connecttype=\"none\""; break; - case 2: sResult += L" o:connecttype=\"rect\""; break; - case 3: sResult += L" o:connecttype=\"segments\""; break; + case 0: sShapeStart += L" o:connecttype=\"custom\""; break; + case 1: sShapeStart += L" o:connecttype=\"none\""; break; + case 2: sShapeStart += L" o:connecttype=\"rect\""; break; + case 3: sShapeStart += L" o:connecttype=\"segments\""; break; } //Connectors switch (m_nConnectorStyle) { - case 0: sResult += L" o:connectortype=\"straight\""; break; - case 1: sResult += L" o:connectortype=\"elbow\""; break; - case 2: sResult += L" o:connectortype=\"curved\""; break; - case 3: sResult += L" o:connectortype=\"none\""; break; + case 0: sShapeStart += L" o:connectortype=\"straight\""; break; + case 1: sShapeStart += L" o:connectortype=\"elbow\""; break; + case 2: sShapeStart += L" o:connectortype=\"curved\""; break; + case 3: sShapeStart += L" o:connectortype=\"none\""; break; } } //----------------------------------------------------------------------------------------------------------------- std::wstring sStyle ; - if( PROP_DEF != m_nLeft && PROP_DEF != m_nRight && PROP_DEF != m_nTop && PROP_DEF != m_nBottom ) + if ( PROP_DEF != m_nLeft && PROP_DEF != m_nRight && PROP_DEF != m_nTop && PROP_DEF != m_nBottom ) { - if( PROP_DEF == m_nPositionHRelative && PROP_DEF == m_nPositionVRelative && + if ( PROP_DEF == m_nPositionHRelative && PROP_DEF == m_nPositionVRelative && PROP_DEF == m_eXAnchor && PROP_DEF == m_eYAnchor) { m_eXAnchor = RtfShape::ax_margin; m_eYAnchor = RtfShape::ay_margin; } //не пишем если inline - if( 3 != m_nPositionHRelative || 3 != m_nPositionVRelative ) + if ( 3 != m_nPositionHRelative || 3 != m_nPositionVRelative ) { sStyle += L"position:absolute;"; - if (oRenderParameter.nType != RENDER_TO_OOX_PARAM_SHAPE_WSHAPE2) + if (oRenderParameter.nType != RENDER_TO_OOX_PARAM_SHAPE_CHILD) { sStyle += L"margin-left:" + XmlUtils::ToString(RtfUtility::Twip2pt(m_nLeft), L"%.2f") + L"pt;"; sStyle += L"margin-top:" + XmlUtils::ToString(RtfUtility::Twip2pt(m_nTop), L"%.2f") + L"pt;"; @@ -988,12 +1013,12 @@ std::wstring RtfShape::RenderToOOXBegin(RenderParameter oRenderParameter) int nWidth = m_nRight - m_nLeft; int nHeight = m_nBottom - m_nTop; - if (oRenderParameter.nType == RENDER_TO_OOX_PARAM_SHAPE_WSHAPE2) + if (oRenderParameter.nType == RENDER_TO_OOX_PARAM_SHAPE_CHILD) sStyle += L"width:" + XmlUtils::ToString(RtfUtility::Twip2pt(nWidth), L"%.2f") + L";height:" + XmlUtils::ToString(RtfUtility::Twip2pt(nHeight), L"%.2f"); else sStyle += L"width:" + XmlUtils::ToString(RtfUtility::Twip2pt(nWidth), L"%.2f") + L"pt;height:" + XmlUtils::ToString(RtfUtility::Twip2pt(nHeight), L"%.2f") + L"pt;"; } - else if( PROP_DEF != m_nRelLeft && PROP_DEF != m_nRelRight && PROP_DEF != m_nRelTop && PROP_DEF != m_nRelBottom ) + else if ( PROP_DEF != m_nRelLeft && PROP_DEF != m_nRelRight && PROP_DEF != m_nRelTop && PROP_DEF != m_nRelBottom ) { int nWidth = m_nRelRight - m_nRelLeft; int nHeight = m_nRelBottom - m_nRelTop; @@ -1005,24 +1030,28 @@ std::wstring RtfShape::RenderToOOXBegin(RenderParameter oRenderParameter) //sStyle += L"right:" + std::to_wstring() + L";" , m_nRelRight); sStyle += L"width:" + std::to_wstring(nWidth) + L";height:" + std::to_wstring(nHeight) + L";"; } - else if( 0 != m_oPicture) + else if ( 0 != m_oPicture) { if (PROP_DEF != m_oPicture->m_nWidthGoal && PROP_DEF != m_oPicture->m_nHeightGoal && PROP_DEF != (int)m_oPicture->m_dScaleX && PROP_DEF != (int)m_oPicture->m_dScaleY )//scale default = 100. { double nWidth = m_oPicture->m_nWidthGoal * m_oPicture->m_dScaleX / 100.f; - if( PROP_DEF != m_oPicture->m_nCropL ) + if ( PROP_DEF != m_oPicture->m_nCropL ) nWidth -= m_oPicture->m_nCropL; - if( PROP_DEF != m_oPicture->m_nCropR ) + if ( PROP_DEF != m_oPicture->m_nCropR ) nWidth -= m_oPicture->m_nCropR; double nHeight = m_oPicture->m_nHeightGoal * m_oPicture->m_dScaleY / 100.f; - if( PROP_DEF != m_oPicture->m_nCropT ) + + if ( PROP_DEF != m_oPicture->m_nCropT ) nHeight -= m_oPicture->m_nCropT; - if( PROP_DEF != m_oPicture->m_nCropB ) + if ( PROP_DEF != m_oPicture->m_nCropB ) nHeight -= m_oPicture->m_nCropB; - if (oRenderParameter.nType == RENDER_TO_OOX_PARAM_SHAPE_WSHAPE2) + nWidth = std::abs(nWidth); + nHeight = std::abs(nHeight); + + if (oRenderParameter.nType == RENDER_TO_OOX_PARAM_SHAPE_CHILD) sStyle += L"width:" + XmlUtils::ToString(RtfUtility::Twip2pt(nWidth), L"%.2f") + L";height:" + XmlUtils::ToString(RtfUtility::Twip2pt(nHeight), L"%.2f") + L";"; else sStyle += L"width:" + XmlUtils::ToString(RtfUtility::Twip2pt(nWidth), L"%.2f") + L"pt;height:" + XmlUtils::ToString(RtfUtility::Twip2pt(nHeight), L"%.2f") + L"pt;"; @@ -1057,14 +1086,14 @@ std::wstring RtfShape::RenderToOOXBegin(RenderParameter oRenderParameter) case 4: sStyle += L"mso-position-horizontal:inside;"; break; case 5: sStyle += L"mso-position-horizontal:outside;"; break; } - if( PROP_DEF != m_nPositionHPct && m_nPositionHPct > 0)//todo + if ( PROP_DEF != m_nPositionHPct && m_nPositionHPct > 0)//todo { sStyle += L"mso-left-percent:" + std::to_wstring(m_nPositionHPct) + L";"; } - if( PROP_DEF != m_nPositionH && PROP_DEF == m_nPositionHRelative ) + if ( PROP_DEF != m_nPositionH && PROP_DEF == m_nPositionHRelative ) m_nPositionHRelative = 2; - if( PROP_DEF != m_nPositionHRelative ) + if ( PROP_DEF != m_nPositionHRelative ) { switch( m_nPositionHRelative ) { @@ -1097,12 +1126,12 @@ std::wstring RtfShape::RenderToOOXBegin(RenderParameter oRenderParameter) case 4: sStyle += L"mso-position-vertical:inside;"; break; case 5: sStyle += L"mso-position-vertical:outside;"; break; } - if( PROP_DEF != m_nPositionVPct && m_nPositionVPct > 0) + if ( PROP_DEF != m_nPositionVPct && m_nPositionVPct > 0) sStyle += L"mso-top-percent:" + std::to_wstring(m_nPositionVPct) + L";"; - if( PROP_DEF != m_nPositionV && PROP_DEF == m_nPositionVRelative ) + if ( PROP_DEF != m_nPositionV && PROP_DEF == m_nPositionVRelative ) m_nPositionVRelative =2; - if( PROP_DEF != m_nPositionVRelative ) + if ( PROP_DEF != m_nPositionVRelative ) { switch( m_nPositionVRelative ) { @@ -1125,7 +1154,7 @@ std::wstring RtfShape::RenderToOOXBegin(RenderParameter oRenderParameter) //case ay_Para: sStyle += L"mso-position-vertical-relative:text;"; break; } } - if( PROP_DEF != m_nPctWidth && m_nPctWidth > 0) + if ( PROP_DEF != m_nPctWidth && m_nPctWidth > 0) sStyle += L"mso-width-percent:" + std::to_wstring(m_nPctWidth) + L";"; switch( m_nPctWidthRelative ) { @@ -1137,7 +1166,7 @@ std::wstring RtfShape::RenderToOOXBegin(RenderParameter oRenderParameter) case 5: sStyle += L"mso-width-relative:outer-margin-area;"; break; } - if( PROP_DEF != m_nPctHeight && m_nPctHeight > 0) + if ( PROP_DEF != m_nPctHeight && m_nPctHeight > 0) sStyle += L"mso-height-percent:" + std::to_wstring(m_nPctHeight) + L";"; switch( m_nPctHeightRelative ) @@ -1150,36 +1179,40 @@ std::wstring RtfShape::RenderToOOXBegin(RenderParameter oRenderParameter) case 5: sStyle += L"mso-height-relative:outer-margin-area;"; break; } - if( PROP_DEF != m_nRotation ) + if ( PROP_DEF != m_nRotation ) sStyle += L"rotation:" + std::to_wstring(m_nRotation / 65536) + L";"; - else if( PROP_DEF != m_nRelRotation ) + else if ( PROP_DEF != m_nRelRotation ) sStyle += L"rotation:" + std::to_wstring(m_nRelRotation / 65536) + L";"; int nZIndex = PROP_DEF; - if( PROP_DEF != m_nRelZOrder ) - nZIndex = m_nRelZOrder; - else if( PROP_DEF != m_nZOrder ) - nZIndex = m_nZOrder; - else if (oRenderParameter.nType != RENDER_TO_OOX_PARAM_SHAPE_WSHAPE2) + if (PROP_DEF != m_nRelZOrder) + { + if (0 == m_nZOrderRelative) nZIndex = m_nRelZOrder; + else nZIndex = -m_nRelZOrder; + } + else if (PROP_DEF != m_nZOrder) + { + if (0 == m_nZOrderRelative) nZIndex = m_nZOrder; + else nZIndex = -m_nZOrder; + } + else if (oRenderParameter.nType != RENDER_TO_OOX_PARAM_SHAPE_CHILD) { - nZIndex = poRtfDocument->GetZIndex(); + nZIndex = poRtfDocument->GetZIndex(0 != m_nZOrderRelative); } - if( PROP_DEF != m_nZOrderRelative && PROP_DEF != nZIndex) + if ( PROP_DEF != m_nZOrderRelative && PROP_DEF != nZIndex) { - if( 0 == m_nZOrderRelative ) nZIndex = abs(nZIndex); - else nZIndex = -abs(nZIndex); } if (PROP_DEF != nZIndex) sStyle += L"z-index:" + std::to_wstring(nZIndex) + L";"; - if( PROP_DEF != m_nWrapDistLeft ) + if ( PROP_DEF != m_nWrapDistLeft ) sStyle += L"mso-wrap-distance-left:" + XmlUtils::ToString(RtfUtility::Twip2pt( m_nWrapDistLeft ), L"%.2f") + L"pt;"; - if( PROP_DEF != m_nWrapDistTop ) + if ( PROP_DEF != m_nWrapDistTop ) sStyle += L"mso-wrap-distance-top:" + XmlUtils::ToString(RtfUtility::Twip2pt( m_nWrapDistTop ), L"%.2f") + L"pt;"; - if( PROP_DEF != m_nWrapDistRight ) + if ( PROP_DEF != m_nWrapDistRight ) sStyle += L"mso-wrap-distance-right:" + XmlUtils::ToString(RtfUtility::Twip2pt( m_nWrapDistRight ), L"%.2f") + L"pt;"; - if( PROP_DEF != m_nWrapDistBottom ) + if ( PROP_DEF != m_nWrapDistBottom ) sStyle += L"mso-wrap-distance-bottom:" + XmlUtils::ToString(RtfUtility::Twip2pt( m_nWrapDistBottom ), L"%.2f") + L"pt;"; switch( m_nAnchorText) @@ -1197,37 +1230,46 @@ std::wstring RtfShape::RenderToOOXBegin(RenderParameter oRenderParameter) } //--------------------------------------------------------------------------------------------------------------------------- - if( false == sStyle.empty() ) + if ( false == sStyle.empty() ) { sStyle.erase( sStyle.length() - 1 ); - sResult += L" style=\"" + sStyle + L"\""; + sShapeStart += L" style=\"" + sStyle + L"\""; } //---------------------------------------------------------------------------------------------------------------------------- - if (m_bIsOle) sResult += L" o:ole=\"\""; + if (m_bIsOle) sShapeStart += L" o:ole=\"\""; - if( PROP_DEF != m_nGroupLeft && PROP_DEF != m_nGroupTop ) - sResult += L" coordorigin=\"" + std::to_wstring(m_nGroupLeft) + L"," + std::to_wstring(m_nGroupTop) + L"\""; + if ( PROP_DEF != m_nGroupLeft && PROP_DEF != m_nGroupTop ) + sShapeStart += L" coordorigin=\"" + std::to_wstring(m_nGroupLeft) + L"," + std::to_wstring(m_nGroupTop) + L"\""; - if( PROP_DEF != m_nGroupLeft && PROP_DEF != m_nGroupTop && PROP_DEF != m_nGroupRight && PROP_DEF != m_nGroupBottom) - sResult += L" coordsize=\"" + std::to_wstring(m_nGroupRight - m_nGroupLeft) + L"," + std::to_wstring(m_nGroupBottom - m_nGroupTop) + L"\""; - else if ( PROP_DEF != m_nGeoLeft && PROP_DEF != m_nGeoTop && PROP_DEF != m_nGeoRight && PROP_DEF != m_nGeoBottom) - sResult += L" coordsize=\"" + std::to_wstring(m_nGeoRight - m_nGeoLeft) + L"," + std::to_wstring(m_nGeoBottom - m_nGeoTop) + L"\""; + if (PROP_DEF != m_nGroupRight && PROP_DEF != m_nGroupBottom) + { + sShapeStart += L" coordsize=\"" + std::to_wstring(m_nGroupRight - (PROP_DEF != m_nGroupLeft ? m_nGroupLeft : 0)) + L"," + + std::to_wstring(m_nGroupBottom - (PROP_DEF != m_nGroupTop ? m_nGroupTop : 0)) + L"\""; + } + else if (PROP_DEF != m_nGeoRight && PROP_DEF != m_nGeoBottom) + { + sShapeStart += L" coordsize=\"" + std::to_wstring(m_nGeoRight - (PROP_DEF != m_nGeoLeft ? m_nGeoLeft : 0)) + L"," + + std::to_wstring(m_nGeoBottom - (PROP_DEF != m_nGeoTop ? m_nGeoTop : 0)) + L"\""; + } + else + { + } - if (oRenderParameter.nType != RENDER_TO_OOX_PARAM_SHAPE_WSHAPE2) + if (oRenderParameter.nType != RENDER_TO_OOX_PARAM_SHAPE_CHILD) { - if( PROP_DEF != m_bLayoutInCell ) + if ( PROP_DEF != m_bLayoutInCell ) { - if( 0 == m_bLayoutInCell ) - sResult += L" o:allowincell=\"false\""; + if ( 0 == m_bLayoutInCell ) + sShapeStart += L" o:allowincell=\"false\""; else - sResult += L" o:allowincell=\"true\""; + sShapeStart += L" o:allowincell=\"true\""; } - if( PROP_DEF != m_bAllowOverlap ) + if ( PROP_DEF != m_bAllowOverlap ) { - if( 0 == m_bAllowOverlap ) - sResult += L" o:allowoverlap=\"false\""; + if ( 0 == m_bAllowOverlap ) + sShapeStart += L" o:allowoverlap=\"false\""; else - sResult += L" o:allowoverlap=\"true\""; + sShapeStart += L" o:allowoverlap=\"true\""; } } //Geometry @@ -1244,7 +1286,7 @@ std::wstring RtfShape::RenderToOOXBegin(RenderParameter oRenderParameter) else sAdjust += L","; } - sResult += L" adj=\"" + sAdjust + L"\""; + sShapeStart += L" adj=\"" + sAdjust + L"\""; } //Custom if (!m_aPVerticles.empty() || !m_aPSegmentInfo.empty()) @@ -1271,50 +1313,68 @@ std::wstring RtfShape::RenderToOOXBegin(RenderParameter oRenderParameter) custom_shape->m_oCustomVML.ToCustomShape(custom_shape, custom_shape->m_oManager); - sResult += L" path=\"" + custom_shape->m_strPath + L"\""; + sShapeStart += L" path=\"" + custom_shape->m_strPath + L"\""; } } } //Wrap Geometry - if( !m_aWrapPoints.empty()) + if ( !m_aWrapPoints.empty()) { - sResult += L" wrapcoords=\""; - sResult += L" " + std::to_wstring(m_aWrapPoints[0].first) + L", " + std::to_wstring(m_aWrapPoints[0].second) + L""; + sShapeStart += L" wrapcoords=\""; + sShapeStart += L" " + std::to_wstring(m_aWrapPoints[0].first) + L", " + std::to_wstring(m_aWrapPoints[0].second) + L""; for (size_t i = 1; i < (int)m_aWrapPoints.size(); i++ ) { - sResult += L", " + std::to_wstring(m_aWrapPoints[i].first) + L", " + std::to_wstring(m_aWrapPoints[i].second) + L""; + sShapeStart += L", " + std::to_wstring(m_aWrapPoints[i].first) + L", " + std::to_wstring(m_aWrapPoints[i].second) + L""; } - sResult += L"\""; + sShapeStart += L"\""; + } + if (PROP_DEF != m_nBorderTopColor) + { + RtfColor color(m_nBorderTopColor); + sShapeStart += L" o:bordertopcolor=\"#" + color.ToHexColor(true) + L"\""; + } + if (PROP_DEF != m_nBorderLeftColor) + { + RtfColor color(m_nBorderLeftColor); + sShapeStart += L" o:borderleftcolor=\"#" + color.ToHexColor(true) + L"\""; + } + if (PROP_DEF != m_nBorderRightColor) + { + RtfColor color(m_nBorderRightColor); + sShapeStart += L" o:borderrightcolor=\"#" + color.ToHexColor(true) + L"\""; + } + if (PROP_DEF != m_nBorderBottomColor) + { + RtfColor color(m_nBorderBottomColor); + sShapeStart += L" o:borderbottomcolor=\"#" + color.ToHexColor(true) + L"\""; } - - sResult += L">"; //-------------------------------------------------------------------------------------------------------------- nodes - if( PROP_DEF != m_nWrapType && 3 != m_nWrapType) + if ( PROP_DEF != m_nWrapType && 3 != m_nWrapType) { - sResult += L""; + sShapeNodes += L"/>"; } //Line - if( 0 != m_bLine && !m_bIsGroup) + if ( 0 != m_bLine && !m_bIsGroup) { std::wstring sStroke; switch( m_nLineDashing ) @@ -1377,42 +1437,42 @@ std::wstring RtfShape::RenderToOOXBegin(RenderParameter oRenderParameter) case 2: sStroke += L" endarrowwidth=\"wide\""; break; } - if( false == sStroke.empty()) + if ( false == sStroke.empty()) { - sResult += L""; + sShapeNodes += L""; } } - if( 0 != m_aTextItems && !m_bIsOle && !m_bIsGroup) + if ( 0 != m_aTextItems && !m_bIsOle && !m_bIsGroup) { RenderParameter oNewParam = oRenderParameter; oNewParam.nType = RENDER_TO_OOX_PARAM_UNKNOWN; - sResult += L""; } else - sResult += L">"; + sShapeNodes += L">"; - sResult += L""; - sResult += m_aTextItems->RenderToOOX(oNewParam); - sResult += L""; - sResult += L""; + sShapeNodes += L""; + sShapeNodes += m_aTextItems->RenderToOOX(oNewParam); + sShapeNodes += L""; + sShapeNodes += L""; } std::wstring sPicture; - if( m_oPicture && !m_bIsGroup) + if ( m_oPicture && !m_bIsGroup) { sPicture = m_oPicture->RenderToOOX(oRenderParameter); if (m_nShapeType == PROP_DEF || m_nShapeType == 75 || m_bIsOle) { - if( sPicture.empty() )//если не сохранилась картинка, то весь shape-picture будет бесполезным + if ( sPicture.empty() )//если не сохранилась картинка, то весь shape-picture будет бесполезным return L""; int nCropLeft = PROP_DEF; @@ -1420,88 +1480,108 @@ std::wstring RtfShape::RenderToOOXBegin(RenderParameter oRenderParameter) int nCropRight = PROP_DEF; int nCropBottom = PROP_DEF; - if( PROP_DEF != m_nCropFromLeft ) + if ( PROP_DEF != m_nCropFromLeft ) nCropLeft = m_nCropFromLeft; - else if( PROP_DEF != m_oPicture->m_nWidthGoal && PROP_DEF != m_oPicture->m_nCropL ) + else if ( PROP_DEF != m_oPicture->m_nWidthGoal && PROP_DEF != m_oPicture->m_nCropL ) nCropLeft = (int)( 65536 * ( 1.0 * m_oPicture->m_nCropL / m_oPicture->m_nWidthGoal) ); //This numeric value can also be specified in 1/65536-ths if a trailing "f" is supplied - if( PROP_DEF != m_nCropFromTop ) + if ( PROP_DEF != m_nCropFromTop ) nCropTop = m_nCropFromTop; - else if( PROP_DEF != m_oPicture->m_nHeightGoal && PROP_DEF != m_oPicture->m_nCropT ) + else if ( PROP_DEF != m_oPicture->m_nHeightGoal && PROP_DEF != m_oPicture->m_nCropT ) nCropTop = (int)( 65536 * ( 1.0 * m_oPicture->m_nCropT / m_oPicture->m_nHeightGoal) ); - if( PROP_DEF != m_nCropFromRight ) + if ( PROP_DEF != m_nCropFromRight ) nCropRight = m_nCropFromRight; - else if( PROP_DEF != m_oPicture->m_nWidthGoal && PROP_DEF != m_oPicture->m_nCropR ) + else if ( PROP_DEF != m_oPicture->m_nWidthGoal && PROP_DEF != m_oPicture->m_nCropR ) nCropRight = (int)( 65536 * ( 1.0 * m_oPicture->m_nCropR / m_oPicture->m_nWidthGoal) ); - if( PROP_DEF != m_nCropFromBottom ) + if ( PROP_DEF != m_nCropFromBottom ) nCropBottom = m_nCropFromBottom; - else if( PROP_DEF != m_oPicture->m_nHeightGoal && PROP_DEF != m_oPicture->m_nCropB ) + else if ( PROP_DEF != m_oPicture->m_nHeightGoal && PROP_DEF != m_oPicture->m_nCropB ) nCropBottom = (int)( 65536 * ( 1.0 * m_oPicture->m_nCropB / m_oPicture->m_nHeightGoal) ); - sResult += L""; + sShapeNodes += L" o:title=\"" + m_sName + L"\"/>"; + } + if (true == m_oPicture->m_oBorderTop.IsValid()) + { + oRenderParameter.sValue = L"w10:bordertop"; + sShapeNodes += m_oPicture->m_oBorderTop.RenderToShapeOOX(oRenderParameter); } + if (true == m_oPicture->m_oBorderLeft.IsValid()) + { + oRenderParameter.sValue = L"w10:borderleft"; + sShapeNodes += m_oPicture->m_oBorderLeft.RenderToShapeOOX(oRenderParameter); + } + if (true == m_oPicture->m_oBorderBottom.IsValid()) + { + oRenderParameter.sValue = L"w10:borderbottom"; + sShapeNodes += m_oPicture->m_oBorderBottom.RenderToShapeOOX(oRenderParameter); + } + if (true == m_oPicture->m_oBorderRight.IsValid()) + { + oRenderParameter.sValue = L"w10:borderright"; + sShapeNodes += m_oPicture->m_oBorderRight.RenderToShapeOOX(oRenderParameter); + } + oRenderParameter.sValue.clear(); } //----------------------------------------------------------------------------------------------- - if( 0 != m_bFilled && !m_bIsGroup) + if ( 0 != m_bFilled && !m_bIsGroup) { - sResult += L""; + sShapeNodes += L"/>"; } //--------------------------------------------------------------------------------------------------------------------------- - if( false == m_sGtextUNICODE.empty() && !m_bIsGroup) + if ( false == m_sGtextUNICODE.empty() && !m_bIsGroup) { - sResult += L""; + sShapeNodes += L" string=\"" + XmlUtils::EncodeXmlString(m_sGtextUNICODE) + L"\""; + sShapeNodes += L"/>"; } if ( PROP_DEF != m_bIsSignatureLine) { - sResult += L""; + sShapeNodes += L" issignatureline=\"t\"/>"; } - - return sResult; + return sShapeStart + L">" + sShapeNodes; } std::wstring RtfShape::RenderToOOXEnd(RenderParameter oRenderParameter) { @@ -1574,9 +1653,9 @@ std::wstring RtfShape::RenderToOOXEnd(RenderParameter oRenderParameter) sResult += L""; - if( RENDER_TO_OOX_PARAM_SHAPE_WSHAPE2 == oRenderParameter.nType ) + if ( RENDER_TO_OOX_PARAM_SHAPE_CHILD == oRenderParameter.nType ) ; - else if( RENDER_TO_OOX_PARAM_SHAPE_WSHAPE == oRenderParameter.nType ) + else if ( RENDER_TO_OOX_PARAM_PIC_BULLET == oRenderParameter.nType ) { if (!m_sOle.empty()) sResult += m_sOle + L""; else sResult += L""; @@ -1613,17 +1692,17 @@ std::wstring RtfShape::GroupRenderToRtf(RenderParameter oRenderParameter) int nRelBottom = m_nRelBottom; int nRelRotate = m_nRelRotation; - if( PROP_DEF != m_nRotation && PROP_DEF != m_nLeft && PROP_DEF != m_nTop && + if ( PROP_DEF != m_nRotation && PROP_DEF != m_nLeft && PROP_DEF != m_nTop && PROP_DEF != m_nRight && PROP_DEF != m_nBottom ) ToRtfRotation( m_nRotation, m_nLeft, m_nTop, m_nRight, m_nBottom ); - if( PROP_DEF != m_nRelRotation && PROP_DEF != m_nRelLeft && PROP_DEF != m_nRelTop && + if ( PROP_DEF != m_nRelRotation && PROP_DEF != m_nRelLeft && PROP_DEF != m_nRelTop && PROP_DEF != m_nRelRight && PROP_DEF != m_nRelBottom ) ToRtfRotation( m_nRelRotation, m_nRelLeft, m_nRelTop, m_nRelRight, m_nRelBottom ); sResult += m_oCharProperty.RenderToRtf( oRenderParameter ); - if( st_inline == m_eAnchorTypeShape ) + if ( st_inline == m_eAnchorTypeShape ) { sResult += L"{\\shpgrp"; sResult += L"{\\*\\shpinst"; @@ -1732,8 +1811,8 @@ std::wstring RtfShape::GroupRenderToOOX(RenderParameter oRenderParameter) for (size_t i = 0; i < m_aArray.size(); i++ ) { RenderParameter oNewParamShape = oRenderParameter; - oNewParamShape.sValue = L""; - oNewParamShape.nType = RENDER_TO_OOX_PARAM_SHAPE_WSHAPE2; //in group + oNewParamShape.sValue = L""; + oNewParamShape.nType = RENDER_TO_OOX_PARAM_SHAPE_CHILD; //in group sResult += m_aArray[i]->RenderToOOX( oNewParamShape ); } @@ -1772,10 +1851,10 @@ void RtfShape::ToRtfRotation( int nAngel , int &nLeft, int &nTop, int& nRight, i //делаем угол от 0 до 360 nAngel = nAngel % 360; - if( nAngel < 0 ) nAngel += 360; + if ( nAngel < 0 ) nAngel += 360; int nQuater = nAngel / 90; // определяем четверть - if( 0 == nQuater || 2 == nQuater ) + if ( 0 == nQuater || 2 == nQuater ) { //поворачиваем относительно центра на 90 градусов обратно int nCenterX = ( nLeft + nRight ) / 2; diff --git a/RtfFile/Format/RtfShape.h b/RtfFile/Format/RtfShape.h index c88882f1395..49ccbcd588b 100644 --- a/RtfFile/Format/RtfShape.h +++ b/RtfFile/Format/RtfShape.h @@ -94,7 +94,12 @@ class RtfShape: public IRenderableProperty, public ItemContainer int m_bLockAnchor; //shplockanchor Lock anchor for a shape. int m_nLockPosition; int m_nLockRotation; - + + int m_nBorderTopColor; + int m_nBorderLeftColor; + int m_nBorderRightColor; + int m_nBorderBottomColor; + int m_eXAnchor; int m_eYAnchor; diff --git a/RtfFile/Format/RtfTable.cpp b/RtfFile/Format/RtfTable.cpp index b6e57daed74..cbdaa3c33ed 100644 --- a/RtfFile/Format/RtfTable.cpp +++ b/RtfFile/Format/RtfTable.cpp @@ -365,7 +365,7 @@ void RtfTable::AddToArray(std::vector& aArray, int nValue)//todo можно bool bNeedAdd = true; for (size_t k = 0; k < aArray.size(); k++) { - if (std::abs(aArray[k] - nValue) < 3) + if (std::abs(aArray[k] - nValue) < 1) { bNeedAdd = false; break; diff --git a/RtfFile/Format/Utils.cpp b/RtfFile/Format/Utils.cpp index f14ed380288..85f736a3020 100644 --- a/RtfFile/Format/Utils.cpp +++ b/RtfFile/Format/Utils.cpp @@ -300,6 +300,10 @@ float RtfUtility::Emu2Pt(int emu) { return (float)(1.0 * emu / (635 * 20.0)); } +int RtfUtility::Pt2Emu(int pt) +{ + return pt * (635 * 20); +} void RtfUtility::WriteDataToFileBinary(std::wstring& sFilename, BYTE* pbData, size_t nLength) { if( NULL == pbData ) diff --git a/RtfFile/Format/Utils.h b/RtfFile/Format/Utils.h index 687f0df0eba..25fed2b06ca 100644 --- a/RtfFile/Format/Utils.h +++ b/RtfFile/Format/Utils.h @@ -207,6 +207,7 @@ class RtfUtility static int Twips2Emu(int pt); static int Emu2Twips(int pt); static float Emu2Pt(int emu); + static int Pt2Emu(int emu); static void WriteDataToFileBinary(std::wstring& sFilename, BYTE* pbData, size_t nLength); static void WriteDataToFile(std::wstring& sFilename, std::wstring& sData); static void DecodeHexString( std::string sHexText, BYTE *&pData ); diff --git a/RtfFile/OOXml/Reader/OOXMathReader.cpp b/RtfFile/OOXml/Reader/OOXMathReader.cpp index a213d164096..a36ca28fa8b 100644 --- a/RtfFile/OOXml/Reader/OOXMathReader.cpp +++ b/RtfFile/OOXml/Reader/OOXMathReader.cpp @@ -236,6 +236,20 @@ bool OOXMathReader::ParseElement(ReaderParameter oParam , OOX::WritingElement * rtfMath->AddItem(oSubMath); } }break; + case OOX::et_m_borderBox: + { + OOX::Logic::CBorderBox* ooxSubMath = dynamic_cast(ooxMath); + if (ooxSubMath) + { + RtfMathPtr oSubMath; + if (ParseElement(oParam, ooxSubMath->m_oBorderBoxPr.GetPointer(), oSubMath)) + rtfMath->AddItem(oSubMath); + + oSubMath.reset(); + if (ParseElement(oParam, ooxSubMath->m_oElement.GetPointer(), oSubMath)) + rtfMath->AddItem(oSubMath); + } + }break; case OOX::et_m_box: { OOX::Logic::CBox *ooxSubMath = dynamic_cast(ooxMath); @@ -250,6 +264,25 @@ bool OOXMathReader::ParseElement(ReaderParameter oParam , OOX::WritingElement * rtfMath->AddItem(oSubMath); } }break; + case OOX::et_m_borderBoxPr: + { + OOX::Logic::CBorderBoxPr* ooxSubMath = dynamic_cast(ooxMath); + if (ooxSubMath) + { + RtfMathPtr oSubMath; + if (ParseElement(oParam, ooxSubMath->m_oCtrlPr.GetPointer(), oSubMath)) + rtfMath->AddItem(oSubMath); + + //nullable m_oHideBot; + //nullable m_oHideLeft; + //nullable m_oHideRight; + //nullable m_oHideTop; + //nullable m_oStrikeBLTR; + //nullable m_oStrikeH; + //nullable m_oStrikeTLBR; + //nullable m_oStrikeV; + } + }break; case OOX::et_m_boxPr: { OOX::Logic::CBoxPr *ooxSubMath = dynamic_cast(ooxMath); diff --git a/RtfFile/OOXml/Reader/OOXParagraphElementReaders.cpp b/RtfFile/OOXml/Reader/OOXParagraphElementReaders.cpp index 8233c736cc1..e8a5697fed3 100644 --- a/RtfFile/OOXml/Reader/OOXParagraphElementReaders.cpp +++ b/RtfFile/OOXml/Reader/OOXParagraphElementReaders.cpp @@ -468,7 +468,7 @@ bool OOXParagraphReader::Parse3( ReaderParameter oParam , RtfParagraph& oOutputP oMathReader.m_oCharProperty = m_oCharProperty; oMathReader.m_oCharProperty.Merge(oOutputParagraph.m_oProperty.m_oCharProperty); - if(true == oMathReader.Parse( oParam, (*oNewMath) ) ) + if (true == oMathReader.Parse( oParam, (*oNewMath) ) ) oOutputParagraph.AddItem( oNewMath ); }break; case OOX::et_m_oMathPara: @@ -482,17 +482,17 @@ bool OOXParagraphReader::Parse3( ReaderParameter oParam , RtfParagraph& oOutputP oMathReader.m_oCharProperty = m_oCharProperty; oMathReader.m_oCharProperty.Merge(oOutputParagraph.m_oProperty.m_oCharProperty); - if(true == oMathReader.Parse( oParam, (*oNewMath) ) ) + if (true == oMathReader.Parse( oParam, (*oNewMath) ) ) oOutputParagraph.AddItem( oNewMath ); }break; case OOX::et_w_sdt: { OOX::Logic::CSdt * pSdt = dynamic_cast(m_ooxElement); - if( pSdt->m_oSdtEndPr.IsInit() ) + if (pSdt->m_oSdtEndPr.IsInit() ) { //todo } - if(pSdt->m_oSdtContent.IsInit()) + if (pSdt->m_oSdtContent.IsInit()) { if (pSdt->m_oSdtContent->m_arrItems.size() > 0) { @@ -508,12 +508,12 @@ bool OOXParagraphReader::Parse3( ReaderParameter oParam , RtfParagraph& oOutputP { OOX::Logic::CCommentRangeStart * pCommentStart = dynamic_cast(m_ooxElement); - if(pCommentStart->m_oId.IsInit()) + if (pCommentStart->m_oId.IsInit()) { int nId = pCommentStart->m_oId->GetValue(); std::map::iterator pFind = oParam.oReader->m_mapComments.find( nId ); - if( pFind == oParam.oReader->m_mapComments.end()) + if (pFind == oParam.oReader->m_mapComments.end()) { RtfAnnotElemPtr oNewAnnotElem ( new RtfAnnotElem(1) ); oNewAnnotElem->m_sValue = std::to_wstring(0x7700000 + nId); @@ -535,7 +535,7 @@ bool OOXParagraphReader::Parse3( ReaderParameter oParam , RtfParagraph& oOutputP std::map::iterator pFindRef = oParam.oReader->m_mapComments.find( nId ); - if( pFindRef != oParam.oReader->m_mapComments.end()) + if (pFindRef != oParam.oReader->m_mapComments.end()) { RtfAnnotElemPtr oNewAnnotElem ( new RtfAnnotElem(2) ); oNewAnnotElem->m_sValue = pFindRef->second.ref; @@ -546,7 +546,7 @@ bool OOXParagraphReader::Parse3( ReaderParameter oParam , RtfParagraph& oOutputP if (pFindComment != oParam.oDocx->m_oMain.comments->m_mapComments.end()) { - if ( pFindComment->second < (int)oParam.oDocx->m_oMain.comments->m_arrComments.size() && pFindComment->second >= 0) + if (pFindComment->second < (int)oParam.oDocx->m_oMain.comments->m_arrComments.size() && pFindComment->second >= 0) { OOX::CComment* oox_comment = oParam.oDocx->m_oMain.comments->m_arrComments[pFindComment->second]; if (oox_comment) @@ -688,28 +688,28 @@ bool OOXRunReader::Parse( ReaderParameter oParam , RtfParagraph& oOutputParagrap { switch(ooxFldChar->m_oFldCharType->GetValue()) { - case SimpleTypes::fldchartypeBegin: + case SimpleTypes::fldchartypeBegin: { - OOXFieldBeginPtr oNewField ( new OOXFieldBegin() ); + OOXFieldBeginPtr oNewField(new OOXFieldBegin()); if (ooxFldChar->m_oFldLock.IsInit()) oNewField->m_bLock = ooxFldChar->m_oFldLock->ToBool(); if (ooxFldChar->m_oDirty.IsInit()) oNewField->m_bDirty = ooxFldChar->m_oDirty->ToBool(); - + oNewField->m_oCharProperty = oNewProperty; - oOutputParagraph.AddItem( oNewField ); + oOutputParagraph.AddItem(oNewField); }break; - case SimpleTypes::fldchartypeEnd: + case SimpleTypes::fldchartypeEnd: { - OOXFieldEndPtr oNewField ( new OOXFieldEnd() ); - oOutputParagraph.AddItem( oNewField ); + OOXFieldEndPtr oNewField(new OOXFieldEnd()); + oOutputParagraph.AddItem(oNewField); }break; - case SimpleTypes::fldchartypeSeparate: + case SimpleTypes::fldchartypeSeparate: { - OOXFieldSeparatePtr oNewField ( new OOXFieldSeparate() ); - oOutputParagraph.AddItem( oNewField ); + OOXFieldSeparatePtr oNewField(new OOXFieldSeparate()); + oOutputParagraph.AddItem(oNewField); }break; - default: break; + default: break; } } }break; @@ -735,7 +735,7 @@ bool OOXRunReader::Parse( ReaderParameter oParam , RtfParagraph& oOutputParagrap int nID = ooxFootnoteReference->m_oId->GetValue(); std::map::iterator oPair = oParam.oReader->m_mapFootnotes.find( nID ); - if( oParam.oReader->m_mapFootnotes.end() != oPair ) + if (oParam.oReader->m_mapFootnotes.end() != oPair ) { RtfFootnotePtr oNewFootnote ( new RtfFootnote() ); oNewFootnote->m_oCharProp = oNewProperty; @@ -753,7 +753,7 @@ bool OOXRunReader::Parse( ReaderParameter oParam , RtfParagraph& oOutputParagrap int nID = ooxEndnoteReference->m_oId->GetValue(); std::map::iterator oPair = oParam.oReader->m_mapEndnotes.find ( nID ); - if( oParam.oReader->m_mapEndnotes.end() != oPair ) + if (oParam.oReader->m_mapEndnotes.end() != oPair ) { RtfFootnotePtr oNewEndnote ( new RtfFootnote() ); oNewEndnote->m_oCharProp = oNewProperty; diff --git a/RtfFile/OOXml/Reader/OOXReader.h b/RtfFile/OOXml/Reader/OOXReader.h index 16d739866bf..8dea8cadefe 100644 --- a/RtfFile/OOXml/Reader/OOXReader.h +++ b/RtfFile/OOXml/Reader/OOXReader.h @@ -63,7 +63,8 @@ class OOXReader RtfConvertationManager* m_convertationManager; std::wstring m_sPath; - int m_nCurItap; //для определение вложенности таблицы + int m_nCurItap = 0; //для определение вложенности таблицы + bool m_bInTable = false; int m_nCurOleChartId; int m_nCurFittextId; diff --git a/RtfFile/OOXml/Reader/OOXTableReader.cpp b/RtfFile/OOXml/Reader/OOXTableReader.cpp index 611679d76c2..f98f4399829 100644 --- a/RtfFile/OOXml/Reader/OOXTableReader.cpp +++ b/RtfFile/OOXml/Reader/OOXTableReader.cpp @@ -33,6 +33,7 @@ #include "OOXTableRowReader.h" #include "OOXTableReader.h" #include "OOXParagraphReader.h" +#include "OOXTextItemReader.h" #include "../../../OOXML/DocxFormat/Logic/Table.h" #include "../../../OOXML/DocxFormat/Logic/Paragraph.h" @@ -305,26 +306,8 @@ bool OOXTableCellReader::Parse( ReaderParameter oParam ,RtfTableCell& oOutputCel { switch((*it)->getType()) { - case OOX::et_w_p: - { - OOX::Logic::CParagraph * pParagraph = dynamic_cast(*it); - - RtfParagraphPtr oNewParagraph( new RtfParagraph() ); - //применяем к новому параграфу default property - oNewParagraph->m_oProperty = oParam.oRtf->m_oDefaultParagraphProp; - oNewParagraph->m_oProperty.m_oCharProperty = oParam.oRtf->m_oDefaultCharProp; - - OOXParagraphReader oParagraphReader(pParagraph); - oParagraphReader.Parse( oParam, (*oNewParagraph), oConditionalTableStyle ); - - //ставим стиль таблицы - if( NULL != oParam.poTableStyle ) - oNewParagraph->m_oProperty.m_nTableStyle = oParam.poTableStyle->m_nID; - oNewParagraph->m_oProperty.m_nItap = oParam.oReader->m_nCurItap; - oNewParagraph->m_oProperty.m_bInTable = 1; - - oOutputCell.AddItem( oNewParagraph ); - }break; + case OOX::et_w_tcPr: + break; case OOX::et_w_tbl: { OOX::Logic::CTbl * pTbl = dynamic_cast(*it); @@ -336,13 +319,23 @@ bool OOXTableCellReader::Parse( ReaderParameter oParam ,RtfTableCell& oOutputCel oOutputCell.AddItem( oNewTabel ); oParam.oReader->m_nCurItap -- ; }break; - default: + default: { - //todooo - универсальный риадер - //OOXElementReader oElementReader((*it)); - //ITextItemPtr *rtfElement = oElementReader.Parse( oParam); - //oOutputCell.AddItem( rtfElement ); - }break; + oParam.oReader->m_bInTable = true; + + OOXTextItemReader oElementReader; + if (oElementReader.Parse(*it, oParam)) + { + if (oElementReader.m_oTextItems) + { + for (auto elm : oElementReader.m_oTextItems->m_aArray) + { + oOutputCell.AddItem(elm); + } + } + } + oParam.oReader->m_bInTable = false; + }break; } } return true; diff --git a/RtfFile/OOXml/Reader/OOXTextItemReader.cpp b/RtfFile/OOXml/Reader/OOXTextItemReader.cpp index 8a73a59f6c8..371163468d3 100644 --- a/RtfFile/OOXml/Reader/OOXTextItemReader.cpp +++ b/RtfFile/OOXml/Reader/OOXTextItemReader.cpp @@ -73,15 +73,28 @@ bool OOXTextItemReader::Parse(OOX::WritingElement* ooxElement, ReaderParameter o OOXParagraphReader oParagraphReader(pParagraph); RtfParagraphPtr oNewParagraph(new RtfParagraph()); - //применяем к новому параграфу default property + //применяем к новому параграфу default property oNewParagraph->m_oProperty = oParam.oRtf->m_oDefaultParagraphProp; oNewParagraph->m_oProperty.m_oCharProperty = oParam.oRtf->m_oDefaultCharProp; - oNewParagraph->m_oProperty.m_nItap = 0; + + if (oParam.oReader->m_bInTable) + { + if (NULL != oParam.poTableStyle) + oNewParagraph->m_oProperty.m_nTableStyle = oParam.poTableStyle->m_nID; + oNewParagraph->m_oProperty.m_bInTable = 1; + oNewParagraph->m_oProperty.m_nItap = oParam.oReader->m_nCurItap; + } + else + { + oNewParagraph->m_oProperty.m_nItap = 0; + } if (true == oParagraphReader.Parse(oParam, (*oNewParagraph), CcnfStyle())) { m_oTextItems->AddItem(oNewParagraph); } + + }break; case OOX::et_w_tbl: { diff --git a/RtfFile/OOXml/Writer/OOXCommentsWriter.cpp b/RtfFile/OOXml/Writer/OOXCommentsWriter.cpp index 7b576c52a72..2007ce82a74 100644 --- a/RtfFile/OOXml/Writer/OOXCommentsWriter.cpp +++ b/RtfFile/OOXml/Writer/OOXCommentsWriter.cpp @@ -153,7 +153,7 @@ mc:Ignorable=\"w14 w15 wp14\">"; for (std::map::iterator it = m_mapComments.begin(); it != m_mapComments.end(); ++it) { sResult += L"second.nID) + L"\" w:author=\"" + - it->second.author + L"\" w:date=\"" + it->second.date + L"\" w:initials=\"" + it->second.authorId + L"\">"; + XmlUtils::EncodeXmlString(it->second.author) + L"\" w:date=\"" + it->second.date + L"\" w:initials=\"" + it->second.authorId + L"\">"; sResult += it->second.content; sResult += L""; diff --git a/RtfFile/OOXml/Writer/OOXDocumentWriter.cpp b/RtfFile/OOXml/Writer/OOXDocumentWriter.cpp index 58d73c9d942..7c3cf57c0cb 100644 --- a/RtfFile/OOXml/Writer/OOXDocumentWriter.cpp +++ b/RtfFile/OOXml/Writer/OOXDocumentWriter.cpp @@ -93,7 +93,7 @@ mc:Ignorable=\"w14 w15 w16se wp14\">"; sResult += L""; { - oNewParam.nType = RENDER_TO_OOX_PARAM_SHAPE_WSHAPE2; + oNewParam.nType = RENDER_TO_OOX_PARAM_SHAPE_CHILD; sResult += m_oDocument.m_pBackground->RenderToOOX(oNewParam); oNewParam.nType = RENDER_TO_OOX_PARAM_UNKNOWN; } @@ -274,7 +274,7 @@ bool OOXDocumentWriter::SaveBySection() RtfParagraph *para = dynamic_cast(m_oDocument[0].props->operator[](i).get()); bParaCurrEmpty = (para) ? (para->GetCount() < 1) : true; - sXml = m_oDocument[0].props->operator[](i)->RenderToOOX(oNewParam); + sXml = m_oDocument[0].props->operator[](i)->RenderToOOX(oNewParam); if (!sXml.empty() || !sXmlSectProp.empty()) { @@ -292,24 +292,30 @@ bool OOXDocumentWriter::SaveBySection() } else { - size_t nFind, nFindPict, pos = sXml.size(); + size_t nFindPPr, nFindP, nFindPictStart, nFindPictEnd, pos = sXml.size(); do { - nFindPict = sXml.rfind(L"", pos); - nFind = sXml.rfind(L"", pos); - pos = nFindPict - 1; - }while(nFind != std::wstring::npos && nFindPict != std::wstring::npos && nFind > nFindPict); + nFindPictStart = sXml.rfind(L"", pos); + nFindPictEnd = sXml.rfind(L"/w:pict>", pos); + nFindPPr = sXml.rfind(L"", pos); + nFindP = sXml.rfind(L"", pos); - if( nFind != std::wstring::npos) + pos = nFindPictStart - 1; + + if (nFindPictStart == std::wstring::npos) + break; + + } while (true); + + if (nFindPPr != std::wstring::npos) { - sXml.insert( nFind, sXmlSectProp ); + sXml.insert(nFindPPr, sXmlSectProp ); } - else + else if (nFindP != std::wstring::npos) { - nFind = sXml.rfind( L"" ); - if( std::wstring::npos != nFind ) - sXml.insert( nFind + 5, L"" + sXmlSectProp + L"" ); + if( std::wstring::npos != nFindP) + sXml.insert(nFindP + 5, L"" + sXmlSectProp + L"" ); } } } diff --git a/Test/Applications/DocxFormatCodeGen/codegen/CodeGenXmlJS.cs b/Test/Applications/DocxFormatCodeGen/codegen/CodeGenXmlJS.cs index 1273cacf978..b6c704ea640 100644 --- a/Test/Applications/DocxFormatCodeGen/codegen/CodeGenXmlJS.cs +++ b/Test/Applications/DocxFormatCodeGen/codegen/CodeGenXmlJS.cs @@ -76,12 +76,12 @@ class CodeGenXmlJS //string gc_sTargetNamespace = "http://schemas.microsoft.com/office/spreadsheetml/2019/namedsheetviews"; //string gc_sXsd = "xlsx-ext/sml.xsd"; - //string[] gc_aTargetTypes = new string[] { "CT_Stylesheet" }; + //string[] gc_aTargetTypes = new string[] { "CT_Workbook", "CT_Worksheet", "CT_PivotCacheDefinition", "CT_PivotCacheRecords", "CT_pivotTableDefinition", "CT_Stylesheet" }; //string gc_sTargetNamespace = "http://schemas.openxmlformats.org/spreadsheetml/2006/main"; - string gc_sXsd = "wml.xsd"; - string[] gc_aTargetTypes = new string[] { "CT_Comments" }; - string gc_sTargetNamespace = "http://purl.oclc.org/ooxml/wordprocessingml/main"; + //string gc_sXsd = "wml.xsd"; + //string[] gc_aTargetTypes = new string[] { "CT_Document", "CT_GlossaryDocument", "CT_Styles", "CT_Numbering", "CT_Settings", "CT_HdrFtr", "CT_Footnotes", "CT_Endnotes", "CT_Comments" }; + //string gc_sTargetNamespace = "http://purl.oclc.org/ooxml/wordprocessingml/main"; //string gc_sXsd = "dml-chart.xsd"; //string[] gc_aTargetTypes = new string[] { "CT_ChartSpace" }; @@ -107,6 +107,10 @@ class CodeGenXmlJS //string[] gc_aTargetTypes = new string[] { "CT_CommentsExtensible" }; //string gc_sTargetNamespace = "http://schemas.microsoft.com/office/word/2018/wordml/cex"; + string gc_sXsd = "vsdx/visio.xsd"; + string[] gc_aTargetTypes = new string[] { "VisioDocument_Type", "Masters_Type", "PageContents_Type", "Pages_Type", "PageContents_Type", + "DataConnections_Type", "DataRecordSets_Type", "Comments_Type", "Extensions_Type"}; + string gc_sTargetNamespace = "http://schemas.microsoft.com/office/visio/2012/main"; public void Start(string sDirIn, string sDirCppXmlOut, string sDirCppBinOut, string sDirJsBinOut, ValidationEventHandler oValidationEventHandler) { diff --git a/Test/Applications/DocxFormatCodeGen/codegen/CodegenXmlJSFiles.cs b/Test/Applications/DocxFormatCodeGen/codegen/CodegenXmlJSFiles.cs index 61d5f235ca8..921ea66b978 100644 --- a/Test/Applications/DocxFormatCodeGen/codegen/CodegenXmlJSFiles.cs +++ b/Test/Applications/DocxFormatCodeGen/codegen/CodegenXmlJSFiles.cs @@ -41,7 +41,7 @@ namespace codegen { class CodeGenXmlJSCPP { - string toXmlNaspace = "w:"; + string toXmlNaspace = ""; Dictionary m_mapProcessedClasses = new Dictionary(); string[] gc_numeric = { "Null", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine" }; public static Dictionary m_mapNamespaceToPrefix = new Dictionary() diff --git a/Test/Applications/DocxFormatCodeGen/codegen/Resource/vsdx/visio.xsd b/Test/Applications/DocxFormatCodeGen/codegen/Resource/vsdx/visio.xsd new file mode 100644 index 00000000000..b3381b6c57b --- /dev/null +++ b/Test/Applications/DocxFormatCodeGen/codegen/Resource/vsdx/visio.xsd @@ -0,0 +1,830 @@ + + + + + + + + Permission to copy, display and distribute the contents of this document (the + "Specification"), in any medium for any purpose without fee or royalty is + hereby granted, provided that you include the following notice on ALL copies of + the Specification, or portions thereof, that you make: + Copyright (c) Microsoft Corporation. All rights reserved. Permission to copy, + display and distribute this document is available at: + http://msdn.microsoft.com/library/en-us/odcXMLRef/html/odcXMLRefLegalNotice.asp?frame=true. + No right to create modifications or derivatives of this Specification is + granted herein. There is a separate patent license available to parties + interested in implementing software programs that can read and write files that + conform to the Specification. This patent license is available at this + location: http://www.microsoft.com/mscorp/ip/format/xmlpatentlicense.asp. + THE SPECIFICATION IS PROVIDED "AS IS" AND MICROSOFT MAKES NO REPRESENTATIONS OR + WARRANTIES, EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, OR TITLE; + THAT THE CONTENTS OF THE SPECIFICATION ARE SUITABLE FOR ANY PURPOSE; NOR THAT + THE IMPLEMENTATION OF SUCH CONTENTS WILL NOT INFRINGE ANY THIRD PARTY PATENTS, + COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS. MICROSOFT WILL NOT BE LIABLE FOR ANY + DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF + OR RELATING TO ANY USE OR DISTRIBUTION OF THE SPECIFICATION. + The name and trademarks of Microsoft may NOT be used in any manner, including + advertising or publicity pertaining to the Specification or its contents + without specific, written prior permission. Title to copyright in the + Specification will at all times remain with Microsoft. No other rights are + granted by implication, estoppel or otherwise. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Test/Applications/DocxFormatCodeGen/codegen/Resource/wml.xsd b/Test/Applications/DocxFormatCodeGen/codegen/Resource/wml.xsd index 300a688133c..40a4fa61f86 100644 --- a/Test/Applications/DocxFormatCodeGen/codegen/Resource/wml.xsd +++ b/Test/Applications/DocxFormatCodeGen/codegen/Resource/wml.xsd @@ -821,14 +821,16 @@ - - - + + + + + + - diff --git a/Test/Applications/FilesSort/FilesSort/Program.cs b/Test/Applications/FilesSort/FilesSort/Program.cs index 6db1322b2ca..df0be938989 100644 --- a/Test/Applications/FilesSort/FilesSort/Program.cs +++ b/Test/Applications/FilesSort/FilesSort/Program.cs @@ -40,8 +40,8 @@ static void initCache(Dictionary hash, string dir) } static void Main(string[] args) { - string input = @"D:\logs\doc.onlyoffice.com\sync\files"; - string output = @"D:\logs\doc.onlyoffice.com\6.4.1\errorsorted"; + string input = @"D:\logs\doc.onlyoffice.com\7.3.2\files"; + string output = @"D:\logs\doc.onlyoffice.com\7.3.2\files-sorted"; DateTime start = DateTime.Now; Dictionary hash = new Dictionary(); @@ -58,39 +58,43 @@ static void Main(string[] args) string[] dirs2 = Directory.GetDirectories(dirs[i]); for (int j = 0; j < dirs2.Length; ++j) { - string curDir = dirs2[j]; - if (!curDir.EndsWith("browser")) + string[] dirs3 = Directory.GetDirectories(dirs2[j]); + for (int k = 0; k < dirs3.Length; ++k) { - string source = Path.Combine(curDir, "source"); - bool bError = true; - if (Directory.Exists(source)) + string curDir = dirs3[k]; + if (!curDir.EndsWith("browser")) { - string[] files = Directory.GetFiles(source); - if (files.Length > 0) + string source = Path.Combine(curDir, "source"); + bool bError = true; + if (Directory.Exists(source)) { - bError = false; - string file = files[0]; - long size = new System.IO.FileInfo(file).Length; - long outVal; - if (!hash.TryGetValue(size, out outVal)) + string[] files = Directory.GetFiles(source); + if (files.Length > 0) { - hash[size] = 1; + bError = false; + string file = files[0]; + long size = new System.IO.FileInfo(file).Length; + long outVal; + if (!hash.TryGetValue(size, out outVal)) + { + hash[size] = 1; - int format = FormatChecker.GetFileFormat(file); - string formatStr = FormatChecker.FileFormats.ToString(format); - if (string.IsNullOrEmpty(formatStr)) - formatStr = "unknown"; - string formatDir = Path.Combine(output, formatStr); - Directory.CreateDirectory(formatDir); - Copy(curDir, Path.Combine(formatDir, Path.GetFileName(curDir))); + int format = FormatChecker.GetFileFormat(file); + string formatStr = FormatChecker.FileFormats.ToString(format); + if (string.IsNullOrEmpty(formatStr)) + formatStr = "unknown"; + string formatDir = Path.Combine(output, formatStr); + Directory.CreateDirectory(formatDir); + Copy(curDir, Path.Combine(formatDir, Path.GetFileName(curDir))); + } } } - } - if (bError) - { - string error = Path.Combine(output, "error"); - Directory.CreateDirectory(error); - Copy(curDir, Path.Combine(error, Path.GetFileName(curDir))); + if (bError) + { + string error = Path.Combine(output, "error"); + Directory.CreateDirectory(error); + Copy(curDir, Path.Combine(error, Path.GetFileName(curDir))); + } } } } diff --git a/Test/Applications/ParseAllCultureInfo/ParseAllCultureInfo/Parser.cs b/Test/Applications/ParseAllCultureInfo/ParseAllCultureInfo/Parser.cs index 6d3d9daf8c9..dcfb58e54fb 100644 --- a/Test/Applications/ParseAllCultureInfo/ParseAllCultureInfo/Parser.cs +++ b/Test/Applications/ParseAllCultureInfo/ParseAllCultureInfo/Parser.cs @@ -182,6 +182,7 @@ public ParamsSerializable(CultureInfo ci) static Dictionary g_mapUsedValues = new Dictionary() { {4, 1}, {5, 1}, + {6, 1}, {7, 1}, {8, 1}, {9, 1}, @@ -197,6 +198,7 @@ public ParamsSerializable(CultureInfo ci) {25, 1}, {29, 1}, {31, 1}, + {33, 1}, {34, 1}, {36, 1}, {38, 1}, @@ -208,6 +210,7 @@ public ParamsSerializable(CultureInfo ci) {1026, 1}, {1028, 1}, {1029, 1}, + {1030, 1}, {1031, 1}, {1032, 1}, {1033, 1}, @@ -225,6 +228,7 @@ public ParamsSerializable(CultureInfo ci) {1051, 1}, {1053, 1}, {1055, 1}, + {1057, 1}, {1058, 1}, {1060, 1}, {1062, 1}, diff --git a/Test/Applications/ParseExcelNumberFormatLocales/ParseDateTimeList/all-date.csv b/Test/Applications/ParseExcelNumberFormatLocales/ParseDateTimeList/all-date.csv new file mode 100644 index 00000000000..dbba1012883 --- /dev/null +++ b/Test/Applications/ParseExcelNumberFormatLocales/ParseDateTimeList/all-date.csv @@ -0,0 +1,270 @@ +"yyyy-mm-dd;@","m/d;@","m/d/yy;@","mm/dd/yy;@","[$-409]d-mmm;@","[$-409]d-mmm-yy;@","[$-409]dd-mmm-yy;@","[$-409]mmm-yy;@","[$-409]mmmm-yy;@","[$-409]mmmm d, yyyy;@","[$-409]m/d/yy h:mm AM/PM;@","m/d/yy h:mm;@","[$-409]mmmmm;@","[$-409]mmmmm-yy;@","m/d/yyyy;@","[$-409]d-mmm-yyyy;@",,,,, +"yyyy/mm/dd;@","yy/mm/dd;@","yyyy-mm-dd;@","[$-436]dd mmmm yyyy;@",,,,,,,,,,,,,,,,,,, +"yyyy-mm-dd;@","dddd, d mmmm yyyy;@","d.m.yyyy;@",,,,,,,,,,,,,,,,,,,, +"[$-10484]dd/mm/yyyy;@","[$-10484]dd/mm/yy;@","[$-10484]dd.mm.yy;@","[$-10484]dd-mm-yy;@","[$-10484]yyyy-mm-dd;@","[$-10484]dddd d mmmm yyyy;@","[$-10484]d mmm yy;@","[$-10484]d mmmm yyyy;@",,,,,,,,,,,,,,, +"yyyy-mm-dd;@","[$-1045E]dd/mm/yyyy;@","[$-1045E]d mmm yyyy;@","[$-1045E]yyyy mmmm d, dddd;@","[$-1045E]d mmmm yyyy;@",,,,,,,,,,,,,,,,,, +"yyyy-mm-dd;@","[$-1010000]d/m/yyyy;@","[$-1010000]yyyy/mm/dd;@","[$-1010401]d/m/yyyy h:mm AM/PM;@","[$-1010409]d/m/yyyy h:mm AM/PM;@","[$-2010000]d/mm/yyyy;@","[$-2010000]yyyy/mm/dd;@","[$-2010401]d/mm/yyyy h:mm AM/PM;@",,,,,,,,,,,,,,, +"yyyy-mm-dd;@","[$-1010000]d/m/yyyy;@","[$-1010000]yyyy/mm/dd;@","[$-1010401]d/m/yyyy h:mm AM/PM;@","[$-1010409]d/m/yyyy h:mm AM/PM;@","[$-2010000]d/mm/yyyy;@","[$-2010000]yyyy/mm/dd;@","[$-2010401]d/mm/yyyy h:mm AM/PM;@",,,,,,,,,,,,,,, +"yyyy-mm-dd;@","[$-1010000]d/m/yyyy;@","[$-1010000]yyyy/mm/dd;@","[$-1010401]d/m/yyyy h:mm AM/PM;@","[$-1010409]d/m/yyyy h:mm AM/PM;@","[$-2010000]d/mm/yyyy;@","[$-2010000]yyyy/mm/dd;@","[$-2010401]d/mm/yyyy h:mm AM/PM;@",,,,,,,,,,,,,,, +"yyyy-mm-dd;@","[$-1010000]d/m/yyyy;@","[$-1010000]yyyy/mm/dd;@","[$-1010401]d/m/yyyy h:mm AM/PM;@","[$-1010409]d/m/yyyy h:mm AM/PM;@","[$-2010000]d/mm/yyyy;@","[$-2010000]yyyy/mm/dd;@","[$-2010401]d/mm/yyyy h:mm AM/PM;@",,,,,,,,,,,,,,, +"yyyy-mm-dd;@","[$-1010000]d/m/yyyy;@","[$-1010000]yyyy/mm/dd;@","[$-1010401]d/m/yyyy h:mm AM/PM;@","[$-1010409]d/m/yyyy h:mm AM/PM;@","[$-2010000]d/mm/yyyy;@","[$-2010000]yyyy/mm/dd;@","[$-2010401]d/mm/yyyy h:mm AM/PM;@",,,,,,,,,,,,,,, +"yyyy-mm-dd;@","[$-1010000]d/m/yyyy;@","[$-1010000]yyyy/mm/dd;@","[$-1010401]d/m/yyyy h:mm AM/PM;@","[$-1010409]d/m/yyyy h:mm AM/PM;@","[$-2010000]d/mm/yyyy;@","[$-2010000]yyyy/mm/dd;@","[$-2010401]d/mm/yyyy h:mm AM/PM;@",,,,,,,,,,,,,,, +"yyyy-mm-dd;@","[$-1010000]d/m/yyyy;@","[$-1010000]yyyy/mm/dd;@","[$-1010401]d/m/yyyy h:mm AM/PM;@","[$-1010409]d/m/yyyy h:mm AM/PM;@","[$-2010000]d/mm/yyyy;@","[$-2010000]yyyy/mm/dd;@","[$-2010401]d/mm/yyyy h:mm AM/PM;@",,,,,,,,,,,,,,, +"yyyy-mm-dd;@","[$-1010000]d/m/yyyy;@","[$-1010000]yyyy/mm/dd;@","[$-1010401]d/m/yyyy h:mm AM/PM;@","[$-1010409]d/m/yyyy h:mm AM/PM;@","[$-2010000]d/mm/yyyy;@","[$-2010000]yyyy/mm/dd;@","[$-2010401]d/mm/yyyy h:mm AM/PM;@",,,,,,,,,,,,,,, +"yyyy-mm-dd;@","[$-1010000]d/m/yyyy;@","[$-1010000]yyyy/mm/dd;@","[$-1010401]d/m/yyyy h:mm AM/PM;@","[$-1010409]d/m/yyyy h:mm AM/PM;@","[$-2010000]d/mm/yyyy;@","[$-2010000]yyyy/mm/dd;@","[$-2010401]d/mm/yyyy h:mm AM/PM;@",,,,,,,,,,,,,,, +"yyyy-mm-dd;@","[$-1010000]d/m/yyyy;@","[$-1010000]yyyy/mm/dd;@","[$-1010401]d/m/yyyy h:mm AM/PM;@","[$-1010409]d/m/yyyy h:mm AM/PM;@","[$-2010000]d/mm/yyyy;@","[$-2010000]yyyy/mm/dd;@","[$-2010401]d/mm/yyyy h:mm AM/PM;@",,,,,,,,,,,,,,, +"yyyy-mm-dd;@","[$-1010000]d/m/yyyy;@","[$-1010000]yyyy/mm/dd;@","[$-1010401]d/m/yyyy h:mm AM/PM;@","[$-1010409]d/m/yyyy h:mm AM/PM;@","[$-2010000]d/mm/yyyy;@","[$-2010000]yyyy/mm/dd;@","[$-2010401]d/mm/yyyy h:mm AM/PM;@",,,,,,,,,,,,,,, +"[$-1170000]B2dd/mm/yyyy;@","[$-1170000]B2dd/mm/yy;@","[$-1170000]B2yyyy-mm-dd;@","[$-2170000]B2dd/mm/yyyy;@","[$-2170000]B2dd/mm/yy;@","[$-2170000]B2yyyy-mm-dd;@","[$-1170401]B2dd mmmm, yyyy;@","[$-1170401]B2dddd, dd mmmm, yyyy;@",,,,,,,,,,,,,,, +"yyyy-mm-dd;@","[$-1010000]d/m/yyyy;@","[$-1010000]yyyy/mm/dd;@","[$-1010401]d/m/yyyy h:mm AM/PM;@","[$-1010409]d/m/yyyy h:mm AM/PM;@","[$-2010000]d/mm/yyyy;@","[$-2010000]yyyy/mm/dd;@","[$-2010401]d/mm/yyyy h:mm AM/PM;@",,,,,,,,,,,,,,, +"yyyy-mm-dd;@","[$-1010000]d/m/yyyy;@","[$-1010000]yyyy/mm/dd;@","[$-1010401]d/m/yyyy h:mm AM/PM;@","[$-1010409]d/m/yyyy h:mm AM/PM;@","[$-2010000]d/mm/yyyy;@","[$-2010000]yyyy/mm/dd;@","[$-2010401]d/mm/yyyy h:mm AM/PM;@",,,,,,,,,,,,,,, +"yyyy-mm-dd;@","[$-1010000]d/m/yyyy;@","[$-1010000]yyyy/mm/dd;@","[$-1010401]d/m/yyyy h:mm AM/PM;@","[$-1010409]d/m/yyyy h:mm AM/PM;@","[$-2010000]d/mm/yyyy;@","[$-2010000]yyyy/mm/dd;@","[$-2010401]d/mm/yyyy h:mm AM/PM;@",,,,,,,,,,,,,,, +"yyyy-mm-dd;@","[$-1010000]d/m/yyyy;@","[$-1010000]yyyy/mm/dd;@","[$-1010401]d/m/yyyy h:mm AM/PM;@","[$-1010409]d/m/yyyy h:mm AM/PM;@","[$-2010000]d/mm/yyyy;@","[$-2010000]yyyy/mm/dd;@","[$-2010401]d/mm/yyyy h:mm AM/PM;@",,,,,,,,,,,,,,, +"dd.mm.yyyy;@","dd.mm.yy;@","d/mm/yyyy;@","dd/mm/yyyy;@","[$-42B]d/mmm/yyyy;@","[$-42B]dd/mmm/yyyy;@","yyyy-mm-dd;@","[$-42B]d mmmm, yyyy;@","[$-42B]dddd, d mmmm yyyy;@","[$-42B]dddd, dd mmmm yyyy;@","[$-42B]dd mmmm yyyy;@","[$-42B]d-mmm-yyyy;@","[$-42B]dd-mmm-yyyy;@","[$-42B]ddd, d-mmmm-yyyy;@","[$-42B]ddd, dd-mmmm-yyyy;@",,,,,,,, +"yyyy-mm-dd;@","[$-1044D]dd-mm-yyyy;@","[$-1044D]yyyy,mmmm dd, dddd;@",,,,,,,,,,,,,,,,,,,, +"dd.mm.yyyy;@","dd.mm.yy;@","d.m.yy;@","dd/mm/yy;@","yyyy-mm-dd;@","[$-82C]d mmmm yyyy;@","[$-82C]dd mmmm yyyy;@",,,,,,,,,,,,,,,, +"dd.mm.yyyy;@","dd.mm.yy;@","d.m.yy;@","dd/mm/yy;@","yyyy-mm-dd;@","[$-42C]d mmmm yyyy;@","[$-42C]dd mmmm yyyy;@",,,,,,,,,,,,,,,, +"dd-mm-yyyy;@","dd-mm-yy;@","d-m-yy;@","d.m.yy;@","yyyy-mm-dd;@","[$-845]dd mmmm yyyy;@","[$-845]d mmmm yyyy;@","[$-5000845]dd-mm-yyyy;@","[$-5000845]dd-mm-yy;@","[$-5000845]d-m-yy;@","[$-5000845]d.m.yy;@","[$-5000845]yyyy-mm-dd;@","[$-5000845]d/m/yyyy;@","[$-5000845]dd mmmm yyyy;@","[$-5000845]d mmmm yyyy;@","[$-5000845]d mmmm, yyyy;@","[$-5000845]dddd, d mmmm, yyyy;@",,,,,, +"[$-1046D]dd.mm.yy;@","[$-1046D]yyyy-mm-dd;@","[$-1046D]d mmmm yyyy ""й"";@","[$-1046D]dddd mmmm yyyy ""й"";@",,,,,,,,,,,,,,,,,,, +"yyyy-mm-dd;@","m/d;@","yy/m/d;@","yy/mm/dd;@","[$-42D]mmm-d;@","[$-42D]yy-mmm-d;@","[$-42D]yy-mmm-dd;@","[$-42D]yy-mmm;@","[$-42D]yy-mmmm;@","[$-42D]yyyy""(e)ko"" mmmm""ren"" d""(a)"";@","[$-42D]yy/mm/dd/ h:mm AM/PM;@","yy/m/d/ h:mm;@","[$-42D]mmmmm;@","[$-42D]yy-mmmmm;@","yyyy/m/d;@","[$-42D]yyyy-mmm-d;@","yyyy.mm.dd;@","[$-42D]yyyy""(e)ko"" mmmm""ren"" d""(a)"";@","[$-42D]yyyy""(e)ko"" mmmm""k"" d""(a)"";@","[$-42D]yyyy""(e)ko"" mmmm;@",,, +"dd.mm.yyyy;@","dd.mm.yy;@","yyyy-mm-dd;@","[$-FC23]d mmmm yyyy;@",,,,,,,,,,,,,,,,,,, +"dd-mm-yyyy;@","dd-mm-yy;@","d-m-yy;@","d.m.yy;@","yyyy-mm-dd;@","[$-445]dd mmmm yyyy;@","[$-445]d mmmm yyyy;@","[$-5000445]dd-mm-yyyy;@","[$-5000445]dd-mm-yy;@","[$-5000445]d-m-yy;@","[$-5000445]d.m.yy;@","[$-5000445]yyyy-mm-dd;@","[$-5000445]dd mmmm yyyy;@","[$-5000445]d mmmm yyyy;@",,,,,,,,, +"[$-1201A]d.m.yyyy;@","[$-1201A]d.m.yy;@","[$-1201A]d. m. yyyy;@","[$-1201A]dd.mm.yyyy;@","[$-1201A]d. m. yy;@","[$-1201A]dd.mm.yy;@","[$-1201A]dd. mm. yy;@","[$-1201A]yyyy-mm-dd;@","[$-1201A]d. mmmm yyyy;@","[$-1201A]dd. mmmm yyyy;@","[$-1201A]dddd, d. mmmm yyyy;@",,,,,,,,,,,, +"yyyy-mm-dd;@","[$-1141A]d. m. yyyy.;@","[$-1141A]d. mmm yyyy.;@","[$-1141A]dddd, d. mmmm yyyy.;@","[$-1141A]d. mmmm yyyy.;@",,,,,,,,,,,,,,,,,, +"yyyy-mm-dd;@","[$-1047E]dd/mm/yyyy;@","[$-1047E]d mmm yyyy;@","[$-1047E]dddd d mmmm yyyy;@","[$-1047E]d mmmm yyyy;@",,,,,,,,,,,,,,,,,, +"dd.m.yyyy ""г."";@","d.m.yyyy ""г."";@","dd.mm.yyyy ""г."";@","yyyy-mm-dd;@","[$-402]dd mmmm yyyy ""г."";@","[$-402]dddd, dd mmmm yyyy ""г."";@",,,,,,,,,,,,,,,,, +"yyyy-mm-dd;@","[$-10455]dd-mm-yyyy;@","[$-10455]dd-mm-yy;@","[$-10455]yyyy၊ mmm d;@","[$-10455]yyyy၊ mmmm d၊ dddd;@","[$-10455]yyyy၊ d mmmm;@",,,,,,,,,,,,,,,,, +"dd/mm/yyyy;@","dd/mm/yy;@","yyyy-mm-dd;@","[$-403]dddd, d mmmm"" de ""yyyy;@","[$-403]d mmmm"" de ""yyyy;@","[$-403]mmmm"" de ""yyyy;@",,,,,,,,,,,,,,,,, +"yyyy-mm-dd;@","[$-1045F]d/m/yyyy;@","[$-1045F]dd/mm/yyyy;@","[$-1045F]dddd، d mmmm yyyy;@","[$-1045F]d mmmm yyyy;@",,,,,,,,,,,,,,,,,, +"[$-1085F]dd-mm-yyyy;@","[$-1085F]dd-mm-yy;@","[$-1085F]yyyy-mm-dd;@","[$-1085F]dd mmmm, yyyy;@","[$-1085F]dddd, dd mmmm, yyyy;@",,,,,,,,,,,,,,,,,, +"yyyy-mm-dd;@","dd-mm;@","dd-mm-yyyy;@","dd.mmm.yyyy;@","[$-105F]d-mmm;@","[$-105F]d-mmm-yy;@","[$-105F]dd-mmm-yy;@","[$-105F]mmm-yy;@","[$-105F]mmmm-yy;@","[$-105F]dd mmmm, yyyy;@","[$-105F]dd-mm-yy h:mm;@","dd-mm-yy h:mm;@","[$-105F]mmmmm;@","[$-105F]mmmmm, yyyy;@","yyyy-mm-dd;@","[$-105F]dd.mmm.yyyy;@",,,,,,, +"yyyy-mm-dd;@","[$-1010000]dd/m/yyyy;@","[$-1010429]dd/m/yyyy hh:mm AM/PM;@","[$-1010409]d/m/yyyy hh:mm AM/PM;@","[$-3010000]d/mm/yyyy;@","[$-3010429]d/mm/yyyy h:mm AM/PM;@",,,,,,,,,,,,,,,,, +"[$-1045C]m/d/yyyy;@","[$-1045C]m/d/yy;@","[$-1045C]mm/dd/yy;@","[$-1045C]mm/dd/yyyy;@","[$-1045C]yy/mm/dd;@","[$-1045C]yyyy-mm-dd;@","[$-1045C]dd-mmm-yy;@","[$-1045C]dddd, mmmm dd,yyyy;@","[$-1045C]mmmm dd,yyyy;@","[$-1045C]dddd, dd mmmm, yyyy;@","[$-1045C]dd mmmm, yyyy;@",,,,,,,,,,,, +"yyyy-mm-dd;@","[DBNum1][$-804]yyyy""年""m""月""d""日"";@","[DBNum1][$-804]yyyy""年""m""月"";@","[DBNum1][$-804]m""月""d""日"";@","yyyy""年""m""月""d""日"";@","yyyy""年""m""月"";@","m""月""d""日"";@","[$-804]aaaa;@","[$-804]aaa;@","yyyy/m/d;@","[$-409]yyyy/m/d h:mm AM/PM;@","yyyy/m/d h:mm;@","yy/m/d;@","m/d;@","m/d/yy;@","mm/dd/yy;@","[$-409]d-mmm;@","[$-409]d-mmm-yy;@","[$-409]dd-mmm-yy;@","[$-409]mmm-yy;@","[$-409]mmmm-yy;@","[$-409]mmmmm;@","[$-409]mmmmm-yy;@" +"d/m/yyyy;@","d/m/yy;@","dd/mm/yy;@","yy/m/d;@","yy/mm/dd;@","yyyy/m/d;@","yyyy/mm/dd;@","yyyy-mm-dd;@","[$-C04]dddd, d mmmm, yyyy;@","[$-C04]d mmmm, yyyy;@","[$-C04]dddd yyyy mm dd;@","yyyy mm dd;@",,,,,,,,,,, +"d/m/yyyy;@","d/m/yy;@","dd/mm/yy;@","yy/m/d;@","yy/mm/dd;@","yyyy/m/d;@","yyyy/mm/dd;@","yyyy-mm-dd;@","[$-1404]dddd, d mmmm, yyyy;@","[$-1404]d mmmm, yyyy;@","[$-1404]dddd yyyy mm dd;@","yyyy mm dd;@",,,,,,,,,,, +"d/m/yyyy;@","d/m/yy;@","dd/mm/yy;@","yy/m/d;@","yy/mm/dd;@","yyyy/m/d;@","yyyy/mm/dd;@","yyyy-mm-dd;@","[$-1004]dddd, d mmmm, yyyy;@","[$-1004]d mmmm, yyyy;@","[$-1004]dddd yyyy mm dd;@","yyyy mm dd;@",,,,,,,, +"yyyy-mm-dd;@","yyyy""年""m""月""d""日"";@","m""月""d""日"";@","[DBNum1][$-404]yyyy""年""m""月""d""日"";@","[DBNum1][$-404]m""月""d""日"";@","[$-404]aaaa;@","[$-404]aaa;@","yyyy/m/d;@","yyyy/m/d h:mm;@","[$-409]yyyy/m/d h:mm AM/PM;@","m/d;@","m/d/yy;@","mm/dd/yy;@","[$-409]d-mmm;@","[$-409]d-mmm-yy;@","[$-409]mmmmm;@","[$-409]mmmmm-yy;@",,, +"yyyy-mm-dd;@","[$-10483]dd/mm/yyyy;@","[$-10483]dd/mm/yy;@","[$-10483]dddd d mmmm yyyy;@","[$-10483]d mmm yy;@","[$-10483]d mmmm yyyy;@",,,,,,,,,,,,,, +"yyyy-mm-dd;@","[$-1101A]d. m. yyyy.;@","[$-1101A]d. m. yy.;@","[$-1101A]d. mmm yyyy.;@","[$-1101A]dddd, d. mmmm yyyy.;@","[$-1101A]d. mmmm yyyy.;@",,,,,,,,,,,,,, +"yyyy-mm-dd;@","d.m.;@","d.m.yy.;@","dd.mm.yy.;@","[$-41A]d-mmm;@","[$-41A]d-mmm-yy;@","[$-41A]dd-mmm-yy;@","[$-41A]mmm-yy;@","[$-41A]mmmm-yy;@","[$-41A]d. mmmm yyyy.;@","[$-409]d.m.yy. h:mm AM/PM;@","d.m.yy. h:mm;@","[$-41A]mmmmm;@","[$-41A]mmmmm-yy.;@","d.m.yyyy.;@","[$-41A]d-mmm-yyyy.;@",,,, +"yyyy-mm-dd;@","d/m;@","d/m/yy;@","dd/mm/yy;@","[$-405]d-mmm.;@","[$-405]d/mmm/yy;@","[$-405]dd-mmm-yy;@","[$-405]mmm-yy;@","[$-405]mmmm yy;@","[$-405]d. mmmm yyyy;@","[$-409]d/m/yy h:mm AM/PM;@","d/m/yy h:mm;@","[$-405]mmmmm;@","[$-405]mmmmm-yy;@","d/m/yyyy;@","[$-405]d-mmm-yyyy;@",,,, +"dd-mm-yy;@","[$-406]d. mmmm yyyy;@","yyyy-mm-dd;@","yyyy.mm.dd;@","yy-mm-dd;@","[$-406]mmmm yyyy;@","d.m.yy;@","d/m yyyy;@","dd-mm-yy hh:mm;@","dd-mm-yy hh:mm:ss;@","yyyy-mm-dd hh:mm;@","[$-406]mmmm yy;@","dd.mm.yyyy;@","d.m.yyyy;@","dd.mm.yy;@","dd/mm yyyy;@","dd/mm yy;@","d/m yy;@","[$-406]mmmmm;@","[$-406]mmmmm-yy;@" +"[$-16048C]yyyy/m/d;@","[$-16048C]yyyy-mm-dd;@","[$-16048C]dddd, d mmmm yyyy;@","[$-16048C]d mmmm yyyy;@",,,,,,,,,,,,,,,, +"yyyy-mm-dd;@","[$-1010000]dd/mm/yy;@","[$-1010000]dd/mm/yyyy;@","[$-1010000]dd mm yyyy;@","[$-1010465]dd mmm yyyy;@","[$-1010465]dd mmmm yyyy;@","[$-1010465]ddd, dd mmmm yyyy;@","[$-1010465]ddd, dd mmm yyyy;@","[$-1010465]dddd, dd mmm yyyy;@","[$-1010465]dddd, dd mmmm yyyy;@",,,,,,,,,, +"d/mm/yyyy;@","d/mm/yy;@","dd-mm-yy;@","dd.mm.yy;@","yyyy-mm-dd;@","[$-813]dddd d mmmm yyyy;@","[$-813]dd-mmm-yy;@","[$-813]d mmmm yyyy;@","[$-813]dd mmm yy;@",,,,,,,,,,, +"yyyy-mm-dd;@","d-m;@","d-mm-yy;@","dd-mm-yy;@","[$-413]d-mmm;@","[$-413]d-mmm-yy;@","[$-413]dd-mmm-yy;@","[$-413]mmm-yy;@","[$-413]mmmm-yy;@","[$-413]d mmmm yyyy;@","[$-409]d-mm-yy h:mm AM/PM;@","d-mm-yy h:mm;@","[$-413]mmmmm;@","[$-413]mmmmm-yy;@","m/d/yyyy;@","[$-413]d-mmm-yyyy;@",,,, +"yyyy-mm-dd;@","[$-10466]d/m/yyyy;@","[$-10466]d mmm yyyy;@","[$-10466]dddd, mmmm dd, yyyy;@","[$-10466]mmmm dd, yyyy;@",,,,,,,,,,,,,,, +"d/mm/yyyy;@","d/mm/yy;@","d/m/yy;@","d/m/yyyy;@","dd/mm/yy;@","dd/mm/yyyy;@","[$-C09]dd-mmm-yy;@","[$-C09]dd-mmmm-yyyy;@","yyyy-mm-dd;@","yy/mm/dd;@","yyyy/mm/dd;@","[$-C09]dddd, d mmmm yyyy;@","[$-C09]d mmmm yyyy;@",,,,,,, +"dd/mm/yyyy;@","yyyy-mm-dd;@","[$-2809]dddd, dd mmmm yyyy;@",,,,,,,,,,,,,,,,, +"dd/mm/yyyy;@","dd/mm/yy;@","d/m/yy;@","yyyy-mm-dd;@","yy-mm-dd;@","m/dd/yy;@","[$-1009]mmmm d, yyyy;@","[$-1009]d-mmm-yy;@",,,,,,,,,,,, +"mm/dd/yyyy;@","mm/dd/yy;@","yyyy-mm-dd;@","[$-2409]dddd, mmmm dd, yyyy;@","[$-2409]mmmm dd, yyyy;@","[$-2409]dddd, dd mmmm, yyyy;@","[$-2409]dd mmmm, yyyy;@",,,,,,,,,,,,, +"yyyy-mm-dd;@","[$-13C09]d/m/yyyy;@","[$-13C09]d mmm yyyy;@","[$-13C09]dddd, d mmmm yyyy;@","[$-13C09]d mmmm yyyy;@",,,,,,,,,,,,,,, +"[$-14009]dd-mm-yyyy;@","[$-14009]dd-mm-yy;@","[$-14009]d-m-yy;@","[$-14009]d.m.yy;@","[$-14009]yyyy-mm-dd;@","[$-14009]dd mmmm yyyy;@","[$-14009]d mmmm yyyy;@","[$-14009]dddd, d mmmm, yyyy;@",,,,,,,,,,,, +"yyyy-mm-dd;@","[$-13809]dd/mm/yyyy;@","[$-13809]dd/mm/yy;@","[$-13809]d mmm yyyy;@","[$-13809]dddd, dd mmmm yyyy;@","[$-13809]dd mmmm yyyy;@",,,,,,,,,,,,,, +"dd/mm/yyyy;@","dd/mm/yy;@","d/m/yy;@","d.m.yy;@","yyyy-mm-dd;@","[$-1809]dd mmmm yyyy;@","[$-1809]d mmmm yyyy;@",,,,,,,,,,,,, +"dd/mm/yyyy;@","yyyy-mm-dd;@","[$-2009]dddd, mmmm dd, yyyy;@","[$-2009]mmmm dd, yyyy;@","[$-2009]dddd, dd mmmm, yyyy;@","[$-2009]dd mmmm, yyyy;@",,,,,,,,,,,,,, +"[$-14409]d/m/yyyy;@","[$-14409]d/m/yy;@","[$-14409]dd/mm/yyyy;@","[$-14409]dd/mm/yy;@","[$-14409]yyyy-mm-dd;@","[$-14409]dddd, d mmmm, yyyy;@","[$-14409]d mmmm, yyyy;@",,,,,,,,,,,,, +"d/mm/yyyy;@","d/mm/yy;@","dd/mm/yy;@","d.mm.yy;@","yyyy-mm-dd;@","[$-1409]dddd, d mmmm yyyy;@","[$-1409]d mmmm yyyy;@",,,,,,,,,,,,, +"m/d/yyyy;@","m/d/yy;@","mm/dd/yy;@","mm/dd/yyyy;@","yyyy-mm-dd;@","yy/mm/dd;@","[$-3409]dd-mmm-yy;@","[$-3409]dddd, mmmm dd, yyyy;@","[$-3409]mmmm dd, yyyy;@","[$-3409]dddd, dd mmmm, yyyy;@","[$-3409]dd mmmm, yyyy;@",,,,,,,,, +"yyyy-mm-dd;@","[$-14809]d/m/yyyy;@","[$-14809]d/m/yy;@","[$-14809]d mmm yyyy;@","[$-14809]dddd, d mmmm yyyy;@","[$-14809]d mmmm yyyy;@",,,,,,,,,,,,,, +"yyyy/mm/dd;@","yy/mm/dd;@","yyyy-mm-dd;@","[$-1C09]dd mmmm yyyy;@",,,,,,,,,,,,,,,, +"dd/mm/yyyy;@","yyyy-mm-dd;@","[$-2C09]dddd, dd mmmm yyyy;@",,,,,,,,,,,,,,,,, +"dd/mm/yyyy;@","dd/mm/yy;@","d/m/yy;@","d.m.yy;@","yyyy-mm-dd;@","[$-809]dd mmmm yyyy;@","[$-809]d mmmm yyyy;@",,,,,,,,,,,,, +"yyyy-mm-dd;@","m/d;@","m/d/yy;@","mm/dd/yy;@","[$-409]d-mmm;@","[$-409]d-mmm-yy;@","[$-409]dd-mmm-yy;@","[$-409]mmm-yy;@","[$-409]mmmm-yy;@","[$-409]mmmm d, yyyy;@","[$-409]m/d/yy h:mm AM/PM;@","m/d/yy h:mm;@","[$-409]mmmmm;@","[$-409]mmmmm-yy;@","m/d/yyyy;@","[$-409]d-mmm-yyyy;@",, +"m/d/yyyy;@","m/d/yy;@","mm/dd/yy;@","mm/dd/yyyy;@","yyyy-mm-dd;@","yy/mm/dd;@","[$-3009]dd-mmm-yy;@","[$-3009]dddd, mmmm dd, yyyy;@","[$-3009]mmmm dd, yyyy;@","[$-3009]dddd, dd mmmm, yyyy;@","[$-3009]dd mmmm, yyyy;@",,,,,,,,, +"d.mm.yyyy;@","dd.mm.yyyy;@","dd.mm.yy;@","yyyy-mm-dd;@","[$-425]d. mmmm yyyy"". a."";@","[$-425]dd. mmmm yyyy"". a."";@","[$-425]dddd, d. mmmm yyyy;@",,,,,,,,,,,,, +"dd-mm-yyyy;@","dd-mm-yy;@","yyyy-mm-dd;@","[$-438]d. mmmm yyyy;@",,,,,,,,,,,,,,,, +"yyyy-mm-dd;@","[$-10464]m/d/yyyy;@","[$-10464]m/d/yy;@","[$-10464]mmm d, yyyy;@","[$-10464]dddd, mmmm d, yyyy;@","[$-10464]mmmm d, yyyy;@",,,,,,,,,,,,,, +"d.m.;@","d.m.yy;@","d.m.yyyy;@","[$-40B]d. mmmmt\a;@","[$-40B]d. mmmmt\a yy;@","[$-40B]d. mmmmt\a yyyy;@","[$-40B]mmmm yy;@","[$-40B]mmmm yyyy;@","[$-40B]d. mmmmt\a yyyy h:mm;@","d.m.yyyy h:mm;@","d.m.yy h:mm;@","[$-40B]mmmmm;@","[$-40B]mmmmm yy;@","yyyy-mm-dd;@","yyyy-mm-dd hh:mm;@", +"d/mm/yyyy;@","d/mm/yy;@","dd.mm.yy;@","yy/mm/dd;@","dd-mm-yy;@","dd/mm/yyyy;@","yyyy-mm-dd;@","[$-80C]dddd d mmmm yyyy;@","[$-80C]d mmmm yyyy;@","[$-80C]dd-mmm-yy;@",,,,,, +"yyyy-mm-dd;@","[$-12C0C]dd/mm/yyyy;@","[$-12C0C]d mmm yyyy;@","[$-12C0C]dddd d mmmm yyyy;@","[$-12C0C]d mmmm yyyy;@",,,,,,,,,,, +"yyyy-mm-dd;@","yy-mm-dd;@","dd-mm-yy;@","yy mm dd;@","dd/mm/yy;@","[$-C0C]d mmmm, yyyy;@","[$-C0C]d mmm yyyy;@",,,,,,,,, +"yyyy-mm-dd;@","[$-11C0C]dd/mm/yyyy;@","[$-11C0C]d mmm yyyy;@","[$-11C0C]dddd d mmmm yyyy;@","[$-11C0C]d mmmm yyyy;@",,,,,,,,,,, +"yyyy-mm-dd;@","[$-1240C]dd/mm/yyyy;@","[$-1240C]d mmm yyyy;@","[$-1240C]dddd d mmmm yyyy;@","[$-1240C]d mmmm yyyy;@",,,,,,,,,,, +"yyyy-mm-dd;@","[$-1300C]dd/mm/yyyy;@","[$-1300C]d mmm yyyy;@","[$-1300C]dddd d mmmm yyyy;@","[$-1300C]d mmmm yyyy;@",,,,,,,,,,, +"yyyy-mm-dd;@","d/m;@","d/m/yy;@","dd/mm/yy;@","[$-40C]d-mmm;@","[$-40C]d-mmm-yy;@","[$-40C]dd-mmm-yy;@","[$-40C]mmm-yy;@","[$-40C]mmmm-yy;@","[$-40C]d mmmm yyyy;@","[$-409]d/m/yy h:mm AM/PM;@","d/m/yy h:mm;@","[$-40C]mmmmm;@","[$-40C]mmmmm-yy;@","m/d/yyyy;@","[$-40C]d-mmm-yyyy;@" +"yyyy-mm-dd;@","[$-13C0C]dd/mm/yyyy;@","[$-13C0C]d mmm yyyy;@","[$-13C0C]dddd d mmmm yyyy;@","[$-13C0C]d mmmm yyyy;@",,,,,,,,,,, +"dd/mm/yyyy;@","dd/mm/yy;@","dd.mm.yy;@","dd-mm-yy;@","yyyy-mm-dd;@","[$-140C]dddd d mmmm yyyy;@","[$-140C]d mmm yy;@","[$-140C]d mmmm yyyy;@",,,,,,,, +"yyyy-mm-dd;@","[$-1340C]dd/mm/yyyy;@","[$-1340C]d mmm yyyy;@","[$-1340C]dddd d mmmm yyyy;@","[$-1340C]d mmmm yyyy;@",,,,,,,,,,, +"dd/mm/yyyy;@","dd/mm/yy;@","dd.mm.yy;@","dd-mm-yy;@","yyyy-mm-dd;@","[$-180C]dddd d mmmm yyyy;@","[$-180C]d mmm yy;@","[$-180C]d mmmm yyyy;@",,,,,,,, +"yyyy-mm-dd;@","[$-1380C]dd/mm/yyyy;@","[$-1380C]d mmm yyyy;@","[$-1380C]dddd d mmmm yyyy;@","[$-1380C]d mmmm yyyy;@",,,,,,,,,,, +"yyyy-mm-dd;@","[$-1200C]dd/mm/yyyy;@","[$-1200C]d mmm yyyy;@","[$-1200C]dddd d mmmm yyyy;@","[$-1200C]d mmmm yyyy;@",,,,,,,,,,, +"yyyy-mm-dd;@","[$-1280C]dd/mm/yyyy;@","[$-1280C]d mmm yyyy;@","[$-1280C]dddd d mmmm yyyy;@","[$-1280C]d mmmm yyyy;@",,,,,,,,,,, +"dd.mm.yyyy;@","dd.mm.yy;@","dd. m. yy;@","d.m.yy;@","yyyy-mm-dd;@","[$-100C]dddd, d. mmmm yyyy;@","[$-100C]d. mmmm yyyy;@","[$-100C]d mmm yy;@",,,,,,,, +"[$-10867]dd/mm/yyyy;@","[$-10867]dd/mm/yy;@","[$-10867]dd.mm.yy;@","[$-10867]dd-mm-yy;@","[$-10867]yyyy-mm-dd;@","[$-10867]dddd d mmmm yyyy;@","[$-10867]d mmm yy;@","[$-10867]d mmmm yyyy;@",,,,,,,, +"yyyy-mm-dd;@","[$-10467]d/m/yyyy;@","[$-10467]d mmm, yyyy;@","[$-10467]dddd d mmmm yyyy;@","[$-10467]d mmmm yyyy;@",,,,,,,,,,, +"yyyy-mm-dd;@","dd/mm/yy;@","d/mm/yy;@","d/m/yy;@","dd-mm-yy;@","dd.mm.yy;@","dd/mm/yyyy;@","[$-456]dddd, dd"" de ""mmmm"" de ""yyyy;@","[$-456]dddd d"" de ""mmmm"" de ""yyyy;@","[$-456]d"" de ""mmmm"" de ""yyyy;@",,,,,, +"dd.mm.yyyy;@","dd.mm.yy;@","d.m.yy;@","dd/mm/yy;@","yyyy-mm-dd;@","[$-437]dddd, d mmmm, yyyy ""წელი"";@",,,,,,,,,, +"dd.mm.yyyy;@","dd.mm.yy;@","dd.m.yyyy;@","yyyy-mm-dd;@","[$-C07]dddd, dd. mmmm yyyy;@","[$-C07]d.mmmm yyyy;@","[$-C07]d.mmmyyyy;@","[$-C07]d mmm yyyy;@",,,,,,,, +"yyyy-mm-dd;@","d.m;@","d.m.yy;@","dd.mm.yy;@","[$-407]d. mmm.;@","[$-407]d. mmm. yy;@","[$-407]d. mmm yy;@","[$-407]mmm. yy;@","[$-407]mmmm yy;@","[$-407]d. mmmm yyyy;@","[$-409]d/m/yy h:mm AM/PM;@","d.m.yy h:mm;@","[$-407]mmmmm;@","[$-407]mmmmm yy;@","d.m.yyyy;@","[$-407]d. mmm. yyyy;@" +"dd.mm.yyyy;@","dd.mm.yy;@","d.mm.yy;@","dd. m. yy;@","d.m.yy;@","dd.mm.yyyy;@","yyyy-mm-dd;@","[$-1407]dddd, d. mmmm yyyy;@","[$-1407]d. mmmm yyyy;@","[$-1407]d. mmm yy;@",,,,,, +"dd.mm.yyyy;@","dd.mm.yy;@","d.mm.yy;@","d.m.yy;@","d.m.yyyy;@","yyyy-mm-dd;@","[$-1007]dddd, d. mmmm yyyy;@","[$-1007]d. mmmm yyyy;@","[$-1007]d. mmm yyyy;@",,,,,,, +"dd.mm.yyyy;@","dd.mm.yy;@","d.mm.yy;@","dd. m. yy;@","d.m.yy;@","dd.mm.yyyy;@","yyyy-mm-dd;@","[$-807]dddd, d. mmmm yyyy;@","[$-807]d. mmmm yyyy;@","[$-807]d. mmm yy;@",,,,,, +"yyyy-mm-dd;@","d/m;@","d/m/yy;@","dd/mm/yy;@","d/m/yyyy;@","[$-408]d-mmm;@","[$-408]d-mmm-yy;@","[$-408]dd-mmm-yy;@","[$-408]mmm-yy;@","[$-408]d mmmm yyyy;@","[$-408]d/m/yy h:mm AM/PM;@","d/m/yy h:mm;@","[$-408]mmmmm;@","[$-408]mmmmm-yy;@","[$-408]d-mmm-yyyy;@", +"yyyy-mm-dd;@","[$-10474]dd/mm/yyyy;@","[$-10474]dd/mm/yy;@","[$-10474]dd-mm-yyyy;@","[$-10474]dd-mm-yy;@","[$-10474]dddd, dd mmmm, yyyy;@","[$-10474]dddd, d mmmm, yyyy;@","[$-10474]dd/mmmm/yyyy;@","[$-10474]d/mmmm/yyyy;@","[$-10474]dd mmmm, yyyy;@","[$-10474]d mmmm, yyyy;@",,,,, +"dd-mm-yy;@","d-m-yy;@","d.m.yy;@","dd-mm-yyyy;@","yyyy-mm-dd;@","[$-447]dd mmmm yyyy;@","[$-447]d mmmm yyyy;@","[$-7000447]dd-mm-yy;@","[$-7000447]d-m-yy;@","[$-7000447]d.m.yy;@","[$-7000447]dd-mm-yyyy;@","[$-7000447]yyyy-mm-dd;@","[$-7000447]dd mmmm yyyy;@","[$-7000447]d mmmm yyyy;@",, +"yyyy-mm-dd;@","[$-10468]d/m/yyyy;@","[$-10468]d/m/yy;@","[$-10468]d mmm, yyyy;@","[$-10468]dddd d mmmm, yyyy;@","[$-10468]d mmmm, yyyy;@",,,,,,,,,, +"yyyy-mm-dd;@","[$-10475]d/m/yyyy;@","[$-10475]d/m/yy;@","[$-10475]d mmm yyyy;@","[$-10475]dddd, d mmmm yyyy;@","[$-10475]d mmmm yyyy;@",,,,,,,,,, +"yyyy-mm-dd;@","[$-1010000]d/m/yy;@","[$-1010000]d/m/yyyy;@","[$-1010000]d.m.yy;@","[$-1010000]d.m.yyyy;@","[$-1010000]m/d/yyyy;@","[$-1010409]d/m/yyyy h:mm AM/PM;@","[$-1010409]d/m/yyyy h:mm;@","[$-101040D]d mmm yy;@","[$-101040D]d mmmm yyyy;@","[$-1010409]d mmm yy;@","[$-1010409]d mmmm yyyy;@",,,, +"yyyy-mm-dd;@","[$-4010000]d/m/yy;@","[$-4010000]d/m/yyyy;@","[$-4010439]d/m/yyyy h:mm AM/PM;@","[$-4010409]d/m/yyyy h:mm AM/PM;@","[$-1010000]d/m/yy;@","[$-1010000]d/m/yyyy;@","[$-1010439]d/m/yyyy h:mm AM/PM;@","[$-1010409]d/m/yyyy h:mm AM/PM;@","[$-1010439]d mmm yy;@","[$-1010439]d mmmm yyyy;@","[$-4010439]d mmm yy;@","[$-4010439]d mmmm yyyy;@","[$-1010409]d mmm yy;@","[$-1010409]d mmmm yyyy;@", +"m. d.;@","yyyy/ m/ d.;@","yyyy/mm/dd;@","[$-40E]yyyy/ mmm/ d.;@","[$-40E]yy/ mmmm d.;@","[$-40E]mmmm d.;@","[$-40E]yyyy/ mmm.;@","[$-40E]yyyy/ mmmm;@","[$-40E]yyyy/ mmmm d.;@","[$-40E]yyyy/ m/ d. h:mm AM/PM;@","yyyy/ m/ d. h:mm;@","[$-40E]mmm/ d.;@","yyyy-mm-dd;@","yyyy mm dd;@","yyyy.mm.dd;@","[$-40E]mmmmm.;@","[$-40E]yy-mmmmm.;@","[$-40E]yy/ mmmm;@",,, +"yyyy-mm-dd;@","[$-10469]d/m/yyyy;@","[$-10469]d mmm yyyy;@","[$-10469]dddd, mmmm dd, yyyy;@","[$-10469]mmmm dd, yyyy;@",,,,,,,,,,,,,,,, +"d.m.yyyy;@","dd.mm.yy;@","d. m. yyyy.;@","d. m. ""'""yy.;@","yyyy-mm-dd;@","yy mm dd;@","[$-40F]d. mmmm yyyy;@","[$-40F]dd. mmmm yyyy;@",,,,,,,,,,,,, +"yyyy-mm-dd;@","[$-10470]d/m/yyyy;@","[$-10470]d/m/yy;@","[$-10470]d mmm yyyy;@","[$-10470]dddd, d mmmm yyyy;@","[$-10470]d mmmm yyyy;@",,,,,,,,,,,,,,, +"[$-1243B]d.m.yyyy;@","[$-1243B]dd.mm.yyyy;@","[$-1243B]d.m.yy;@","[$-1243B]yyyy-mm-dd;@","[$-1243B]mmmm d"". p. ""yyyy;@","[$-1243B]dddd, mmmm d. yyyy;@",,,,,,,,,,,,,,, +"dd/mm/yyyy;@","dd/mm/yy;@","yyyy-mm-dd;@","[$-421]dd mmmm yyyy;@",,,,,,,,,,,,,,,,, +"[$-1085D]d/mm/yyyy;@","[$-1085D]d/m/yy;@","[$-1085D]dd/mm/yyyy;@","[$-1085D]yy-mm-dd;@","[$-1085D]yyyy-mm-dd;@","[$-1085D]dd-mmm-yy;@","[$-1085D]dddd, dd mmmm, yyyy;@","[$-1085D]ddd, mmmm dd,yyyy;@","[$-1085D]mmmm dd,yyyy;@","[$-1085D]dd mmmm, yyyy;@",,,,,,,,,,, +"[$-1045D]d/m/yyyy;@","[$-1045D]d/m/yy;@","[$-1045D]dd/mm/yy;@","[$-1045D]yy/mm/dd;@","[$-1045D]yyyy-mm-dd;@","[$-1045D]dd-mmm-yy;@","[$-1045D]dddd,mmmm dd,yyyy;@","[$-1045D]mmmm dd,yyyy;@","[$-1045D]dddd, dd mmmm, yyyy;@","[$-1045D]dd mmmm, yyyy;@",,,,,,,,,,, +"yyyy-mm-dd;@","[$-1083C]dd/mm/yyyy;@","[$-1083C]d mmm yyyy;@","[$-1083C]dddd d mmmm yyyy;@","[$-1083C]d mmmm yyyy;@",,,,,,,,,,,,,,,, +"[$-10434]yyyy-mm-dd;@","[$-10434]yyyy mmm d;@","[$-10434]yyyy mmmm d, dddd;@","[$-10434]yyyy mmmm d;@",,,,,,,,,,,,,,,,, +"yyyy-mm-dd;@","[$-10435]m/d/yyyy;@","[$-10435]m/d/yy;@","[$-10435]mmm d, yyyy;@","[$-10435]dddd, mmmm d, yyyy;@","[$-10435]mmmm d, yyyy;@",,,,,,,,,,,,,,, +"yyyy-mm-dd;@","d/m;@","d/m/yy;@","dd/mm/yy;@","[$-410]d-mmm;@","[$-410]d-mmm-yy;@","[$-410]dd-mmm-yy;@","[$-410]mmm-yy;@","[$-410]mmmm-yy;@","[$-410]d mmmm yyyy;@","[$-409]d/m/yy h.mm AM/PM;@","d/m/yy h.mm;@","[$-410]mmmmm;@","[$-410]mmmmm-yy;@","d/m/yyyy;@","[$-410]d-mmm-yyyy;@",,,,, +"dd.mm.yyyy;@","dd.mm.yy;@","dd. mm. yy;@","d/m/yy;@","dd.m.yy;@","yyyy-mm-dd;@","[$-810]dddd, d. mmmm yyyy;@","[$-810]d-mmm-yy;@","[$-810]d mmmm yyyy;@",,,,,,,,,,,, +"yyyy-mm-dd;@","yyyy""年""m""月""d""日"";@","yyyy""年""m""月"";@","m""月""d""日"";@","yyyy/m/d;@","[$-409]yyyy/m/d h:mm AM/PM;@","yyyy/m/d h:mm;@","m/d;@","m/d/yy;@","mm/dd/yy;@","[$-409]d-mmm;@","[$-409]d-mmm-yy;@","[$-409]dd-mmm-yy;@","[$-409]mmm-yy;@","[$-409]mmmm-yy;@","[$-409]mmmmm;@","[$-409]mmmmm-yy;@",,,, +"yyyy-mm-dd;@","[$]dd-mm-yyyy;@","[$]d mmm yyyy;@","[$]dddd, d mmmm yyyy;@","[$]d mmmm yyyy;@",,,,,,,,,,,,,,,, +"dd/mm/yyyy;@","dd/mm/yy;@","yyyy-mm-dd;@",,,,,,,,,,,,,,,,,, +"[$-1046F]dd-mm-yyyy;@","[$-1046F]dd-mm-yy;@","[$-1046F]yyyy-mm-dd;@","[$-1046F]yyyy mm dd;@","[$-1046F]mmmm d"".-at, ""yyyy;@","[$-1046F]d. mmmm yyyy;@","[$-1046F]dd. mmmm yyyy;@","[$-1046F]dddd dd mmmm yyyy;@",,,,,,,,,,,,, +"dd-mm-yy;@","d-m-yy;@","d.m.yy;@","dd-mm-yyyy;@","yyyy-mm-dd;@","[$-44B]dd mmmm yyyy;@","[$-44B]d mmmm yyyy;@",,,,,,,,,,,,,, +"yyyy-mm-dd;@","[$-10471]d/m/yyyy;@","[$-10471]mmm d, yyyy;@","[$-10471]dddd, mmmm dd, yyyy;@","[$-10471]mmmm dd, yyyy;@",,,,,,,,,,,,,,,, +"yyyy-mm-dd;@","[$-10860]d/m/yyyy;@","[$-10860]d/m/yy;@","[$-10860]d mmm yyyy;@","[$-10860]dddd, d mmmm yyyy;@","[$-10860]d mmmm yyyy;@",,,,,,,,,,,,,,, +"yyyy-mm-dd;@","[$-10460]m/d/yyyy;@","[$-10460]m/d/yy;@","[$-10460]mmm d, yyyy;@","[$-10460]dddd, mmmm d, yyyy;@","[$-10460]mmmm d, yyyy;@",,,,,,,,,,,,,,, +"dd.mm.yyyy;@","dd.mm.yy;@","d.m.yy;@","dd/mm/yy;@","yyyy-mm-dd;@","[$-43F]d mmmm yyyy ""ж."";@","[$-43F]dd mmmm yyyy ""ж."";@",,,,,,,,,,,,,, +"[$-10453]dd/mm/yy;@","[$-10453]yyyy-mm-dd;@","[$-10453]d mmmm yyyy;@","[$-10453]ddd d mmmm yyyy;@","[$-10453]dddd d mmmm yyyy;@",,,,,,,,,,,,,,,, +"yyyy-mm-dd;@","[$-10486]dd/mm/yyyy;@","[$-10486]d/mm/yyyy;@","[$-10486]dddd, dd"" rech ""mmmm"" rech ""yyyy;@","[$-10486]dddd d"" de ""mmmm"" de ""yyyy;@","[$-10486]d"" de ""mmmm"" de ""yyyy;@",,,,,,,,,,,,,,, +"[$-10487]yyyy-mm-dd;@","[$-10487]yyyy mmm d;@","[$-10487]yyyy mmmm d, dddd;@","[$-10487]yyyy mmmm d;@",,,,,,,,,,,,,,,,, +"m/d/yyyy;@","m/d/yy;@","mm/dd/yy;@","mm/dd/yyyy;@","yy/mm/dd;@","yyyy-mm-dd;@","[$-441]dd-mmm-yy;@","[$-441]dddd, mmmm dd, yyyy;@","[$-441]mmmm dd, yyyy;@","[$-441]dddd, dd mmmm, yyyy;@","[$-441]dd mmmm, yyyy;@",,,,,,,,,, +"dd-mm-yyyy;@","dd-mm-yy;@","d-m-yy;@","d.m.yy;@","yyyy-mm-dd;@","[$-457]dd mmmm yyyy;@","[$-457]d mmmm yyyy;@",,,,,,,,,,,,,, +"yyyy-mm-dd;@","yyyy""년"" m""월"" d""일"";@","yy""年"" m""月"" d""日"";@","yyyy""년"" m""월"";@","m""월"" d""일"";@","yy""-""m""-""d;@","yy""-""m""-""d h:mm;@","[$-412]yy""-""m""-""d AM/PM h:mm;@","[$-409]yy""-""m""-""d h:mm AM/PM;@","yy""/""m""/""d;@","yyyy""-""m""-""d;@","yyyy""/""m""/""d;@","m""/""d;@","m""/""d""/""yy;@","mm""/""dd""/""yy;@","[$-409]d""-""mmm;@","[$-409]d""-""mmm""-""yy;@","[$-409]mmm""-""yy;@","[$-409]mmmm""-""yy;@","[$-409]mmmmm;@","[$-409]mmmmm-yy;@" +"yyyy-mm-dd;@","dd.mm.yy;@","[$-440]d""-""mmmm yyyy""-ж."";@",,,,,,,,,,,,,,,,,, +"yyyy-mm-dd;@","[$-10454]d/m/yyyy;@","[$-10454]d mmm yyyy;@","[$-10454]dddd ທີ d mmmm gg yyyy;@","[$-10454]d mmmm yyyy;@",,,,,,,,,,,,,,,, +"yyyy-mm-dd;@","[$-10476]d m yyyy gg;@","[$-10476]""die"" d mmm yyyy gg;@","[$-10476]dddd, ""die"" d mmmm yyyy gg;@","[$-10476]""die"" d mmmm yyyy gg;@",,,,,,,,,,,,,,,, +"yyyy.mm.dd.;@","yy.mm.dd.;@","yyyy-mm-dd;@","[$-426]dddd, yyyy"". gada ""d. mmmm;@",,,,,,,,,,,,,,,,, +"yyyy-mm-dd;@","yyyy.mm.dd;@","[$-FC27]yyyy ""m."" mmmm d ""d."";@","[$-427]yyyy ""m."" mmmm d ""d."";@",,,,,,,,,,,,,,,,, +"[$-1082E]d. m. yyyy;@","[$-1082E]d. m. yy;@","[$-1082E]dd.mm.yyyy;@","[$-1082E]dd.mm.yy;@","[$-1082E]yyyy-mm-dd;@","[$-1082E]dddd, d. mmmm yyyy;@","[$-1082E]d. mmmm yyyy;@",,,,,,,,, +"[$-1103B]dd.mm.yyyy;@","[$-1103B]dd.mm.yy;@","[$-1103B]d.m.yy;@","[$-1103B]yyyy-mm-dd;@","[$-1103B]dddd, mmmm d"". b. ""yyyy;@","[$-1103B]mmmm d"". b. ""yyyy;@",,,,,,,,,, +"[$-1143B]yyyy-mm-dd;@","[$-1143B]yy-mm-dd;@","[$-1143B]dddd, mmmm d"". b. ""yyyy;@","[$-1143B]mmmm d"". b. ""yyyy;@",,,,,,,,,,,, +"yyyy-mm-dd;@","[$-1046E]dd.mm.yy;@","[$-1046E]dd/mm/yy;@","[$-1046E]dd-mm-yy;@","[$-1046E]d. mmmm yyyy;@","[$-1046E]dd. mmmmyyyy;@","[$-1046E]dddd, d. mmmm yyyy;@","[$-1046E]dddd, dd. mmmm yyyy;@","[$-1046E]dddd,"" den ""d. mmmm yyyy;@","[$-1046E]dddd,"" den ""dd. mmmm yyyy;@",,,,,, +"dd.mm.yyyy;@","dd.mm.yy;@","yyyy-mm-dd;@","[$-42F]dddd, dd mmmm yyyy;@",,,,,,,,,,,, +"[$]yyyy-mm-dd;@","[$]yyyy mmm d;@","[$]dddd d mmmm yyyy;@","[$]d mmmm yyyy;@",,,,,,,,,,,, +"dd/mm/yyyy;@","dd/mm/yy;@","yyyy-mm-dd;@","[$-83E]dd mmmm yyyy;@",,,,,,,,,,,, +"dd/mm/yyyy;@","dd/mm/yy;@","yyyy-mm-dd;@","[$-43E]dd mmmm yyyy;@",,,,,,,,,,,, +"dd-mm-yyyy;@","dd-mm-yy;@","d-m-yy;@","d.m.yy;@","yyyy-mm-dd;@","[$-44C]dd mmmm yyyy;@","[$-44C]d mmmm yyyy;@","[$-C00044C]dd-mm-yyyy;@","[$-C00044C]dd-mm-yy;@","[$-C00044C]d-m-yy;@","[$-C00044C]d.m.yy;@","[$-C00044C]yyyy-mm-dd;@","[$-C00044C]dd mmmm yyyy;@","[$-C00044C]d mmmm yyyy;@",, +"yyyy-mm-dd;@","[$-1043A]dd/mm/yyyy;@","[$-1043A]dd mmm yyyy;@","[$-1043A]dddd, d ""ta""’ mmmm yyyy;@","[$-1043A]d ""ta""’ mmmm yyyy;@",,,,,,,,,,, +"yyyy-mm-dd;@","[$-10458]d/m/yyyy;@","[$-10458]d/m/yy;@","[$-10458]mmm d, yyyy;@","[$-10458]mmmm d, yyyy, dddd;@","[$-10458]mmmm d, yyyy;@",,,,,,,,,, +"yyyy-mm-dd;@","[$-10481]dd-mm-yyyy;@","[$-10481]d mmm yyyy;@","[$-10481]dddd, d mmmm yyyy;@","[$-10481]d mmmm yyyy;@",,,,,,,,,,, +"[$-1047A]dd-mm-yyyy;@","[$-1047A]dd-mm-yy;@","[$-1047A]dd/mm/yy;@","[$-1047A]d/m/yy;@","[$-1047A]yyyy-mm-dd;@","[$-1047A]dddd, dd"" de ""mmmm"" de ""yyyy;@","[$-1047A]dddd d"" de ""mmmm"" de ""yyyy;@","[$-1047A]d"" de ""mmmm"" de ""yyyy;@",,,,,,,, +"dd-mm-yyyy;@","dd-mm-yy;@","d-m-yy;@","d.m.yy;@","yyyy-mm-dd;@","[$-44E]dd mmmm yyyy;@","[$-44E]d mmmm yyyy;@",,,,,,,,, +"[$-1047C]m/d/yyyy;@","[$-1047C]m/d/yy;@","[$-1047C]mm/dd/yy;@","[$-1047C]mm/dd/yyyy;@","[$-1047C]yy/mm/dd;@","[$-1047C]yyyy-mm-dd;@","[$-1047C]dd-mmm-yy;@","[$-1047C]dddd, mmmm dd, yyyy;@","[$-1047C]mmmm dd, yyyy;@","[$-1047C]dddd, dd mmmm, yyyy;@","[$-1047C]dd mmmm, yyyy;@",,,,, +"yyyy-mm-dd;@","yy.mm.dd;@","[$-450]yyyy ""оны"" mmmm d;@",,,,,,,,,,,,, +"[$-10850]yyyy/m/d;@","[$-10850]yyyy-m-d;@","[$-10850]yyyy.m.d;@","[$-10850]yyyy.mm.dd;@","[$-10850]yyyy-mm-dd;@","[$-10850]yyyy/mm/dd;@","[$-10850]yy-m-d;@","[$-10850]yy/m/d;@","[$-10850]yy.m.d;@","[$-10850]yy/mm/dd;@","[$-10850]yyyyᠣᠨ mmmm dᠡᠳᠦᠷ᠂ dddd;@","[$-10850]yyyyᠣᠨ mmmm dᠡᠳᠦᠷ;@",,,, +"[$-10C50]yyyy/m/d;@","[$-10C50]yyyy-m-d;@","[$-10C50]yyyy.m.d;@","[$-10C50]yyyy.mm.dd;@","[$-10C50]yyyy-mm-dd;@","[$-10C50]yyyy/mm/dd;@","[$-10C50]yy-m-d;@","[$-10C50]yy/m/d;@","[$-10C50]yy.m.d;@","[$-10C50]yy/mm/dd;@","[$-10C50]yyyyᠣᠨ mmmm dᠡᠳᠦᠷ᠂ dddd;@","[$-10C50]yyyyᠣᠨ mmmm dᠡᠳᠦᠷ;@",,,, +"[$-10461]m/d/yyyy;@","[$-10461]m/d/yy;@","[$-10461]mm/dd/yy;@","[$-10461]mm/dd/yyyy;@","[$-10461]yy/mm/dd;@","[$-10461]yyyy-mm-dd;@","[$-10461]dd-mmm-yy;@","[$-10461]dddd, mmmm dd, yyyy;@","[$-10461]mmmm dd, yyyy;@","[$-10461]dddd, dd mmmm, yyyy;@","[$-10461]dd mmmm, yyyy;@",,,,, +"yyyy-mm-dd;@","[$-10861]yyyy/m/d;@","[$-10861]yy/m/d;@","[$-10861]yyyy mmm d;@","[$-10861]yyyy mmmm d, dddd;@","[$-10861]yyyy mmmm d;@",,,,,,,,,, +"[$]dd/mm/yyyy;@","[$]dd/mm/yy;@","[$]yyyy-mm-dd;@","[$]dddd, mmmm dd, yyyy;@","[$]mmmm dd, yyyy;@",,,,,,,,,,, +"[$-10C3B]d.m.yyyy;@","[$-10C3B]dd.mm.yyyy;@","[$-10C3B]d.m.yy;@","[$-10C3B]yyyy-mm-dd;@","[$-10C3B]dddd"", ""mmmm d"". b. ""yyyy;@","[$-10C3B]mmmm d"". b. ""yyyy;@",,,,,,,,,, +"[$-1043B]yyyy-mm-dd;@","[$-1043B]yyyy mmm d;@","[$-1043B]dddd, mmmm d"". b. ""yyyy;@","[$-1043B]yyyy mmmm d, dddd;@","[$-1043B]yyyy mmmm d;@",,,,,,,,,,, +"[$-1083B]yyyy-mm-dd;@","[$-1083B]yy-mm-dd;@","[$-1083B]dddd, mmmm d"". b. ""yyyy;@","[$-1083B]mmmm d"". b. ""yyyy;@",,,,,,,,,,,, +"d/m/;@","d/m/yy;@","d/m/yyyy;@","dd/mm/yy;@","dd/mm/yyyy;@","[$-414]d/ mmm.;@","[$-414]d/ mmmm;@","[$-414]d/ mmm. yyyy;@","[$-414]d/ mmmm yyyy;@","[$-414]mmm. yy;@","[$-414]mmmm yy;@","[$-414]mmmm yyyy;@","yyyy-mm-dd;@","dd/mm/yy h:mm;@","[$-409]m/d/yy h:mm AM/PM;@","m/d/yy h:mm;@" +"dd.mm.yyyy;@","dd.mm.yy;@","d.m.yy;@","yyyy-mm-dd;@","[$-814]d. mmmm yyyy;@","[$-814]dd. mmmm yyyy;@",,,,,,,,,, +"yyyy-mm-dd;@","[$-10482]d/mm/yyyy;@","[$-10482]d/mm/yy;@","[$-10482]d mmm yyyy;@","[$-10482]dddd d mmmm"" de ""yyyy;@","[$-10482]dddd d mmmm ""de"" yyyy;@","[$-10482]d mmmm ""de"" yyyy;@",,,,,,,,, +"[$-10448]dd-mm-yy;@","[$-10448]d-m-yy;@","[$-10448]d.m.yy;@","[$-10448]dd-mm-yyyy;@","[$-10448]yyyy-mm-dd;@","[$-10448]dd mmmm yyyy;@","[$-10448]d mmmm yyyy;@","[$-10448]dddd, mmmm d, yyyy;@",,,,,,,, +"yyyy-mm-dd;@","[$-10472]dd/mm/yyyy;@","[$-10472]dd/mm/yy;@","[$-10472]dd-mmm-yyyy;@","[$-10472]dddd, mmmm d, yyyy;@","[$-10472]dd mmmm yyyy;@",,,,,,,,,, +"yyyy-mm-dd;@","[$-10479]d-m-yyyy;@","[$-10479]d mmm yyyy;@","[$-10479]d mmm yy;@","[$-10479]dddd d mmmm yyyy;@","[$-10479]d mmmm yyyy;@",,,,,,,,,, +"[$-160463]yyyy/m/d;@","[$-160463]yyyy-mm-dd;@","[$-160463]d mmmm yyyy;@","[$-160463]dddd d mmmm yyyy;@",,,,,,,,,,,, +"[$-160429]dd/mm/yyyy;@","[$-160429]dd/mm/yy;@","[$-160429]dddd, d mmmm yyyy;@","[$-160429]d mmmm yyyy;@",,,,,,,,,,,, +"d-mm;@","yyyy-mm-dd;@","yy-mm-dd;@","[$-415]d mmm;@","[$-415]d mmm yy;@","[$-415]dd mmm yy;@","[$-415]mmm yy;@","[$-415]mmmm yy;@","[$-415]d mmmm yyyy;@","[$-409]dd-mm-yy h:mm AM/PM;@","dd-mm-yy h:mm;@","[$-415]mmmmm;@","[$-415]mmmmm.yy;@","d-m-yyyy;@","[$-415]d-mmm-yyyy;@", +"yyyy-mm-dd;@","dd-mm-yyyy;@","d/m/yy;@","dd/mm/yy;@","[$-816]d/mmm;@","[$-816]d-mmm-yy;@","[$-816]dd-mmm-yy;@","[$-816]mmm/yy;@","[$-816]mmmm yy;@","[$-816]d ""de"" mmmm ""de"" yyyy;@","[$-409]d/m/yy h:mm AM/PM;@","d/m/yy h:mm;@","[$-816]mmmmm;@","[$-816]mmmmm-yy;@","d/m/yyyy;@","[$-816]d-mmm-yyyy;@" +"yyyy-mm-dd;@","d/m;@","d/m/yy;@","dd/mm/yy;@","[$-416]d-mmm;@","[$-416]d-mmm-yy;@","[$-416]dd-mmm-yy;@","[$-416]mmm-yy;@","[$-416]mmmm-yy;@","[$-416]d;@","mmmm, yyyy;@","[$-409]d/m/yy h:mm AM/PM;@","d/m/yy h:mm;@",,, +"yyyy-mm-dd;@","dd-mm-yyyy;@","d/m/yy;@","dd/mm/yy;@","[$-816]d/mmm;@","[$-816]d-mmm-yy;@","[$-816]dd-mmm-yy;@","[$-816]mmm/yy;@","[$-816]mmmm yy;@","[$-816]d ""de"" mmmm ""de"" yyyy;@","[$-409]d/m/yy h:mm AM/PM;@","d/m/yy h:mm;@","[$-816]mmmmm;@","[$-816]mmmmm-yy;@","d/m/yyyy;@","[$-816]d-mmm-yyyy;@" +"dd-mm-yy;@","d-m-yy;@","d.m.yy;@","dd-mm-yyyy;@","yyyy-mm-dd;@","[$-446]dd mmmm yyyy dddd;@","[$-446]d mmmm yyyy;@","[$-6000446]dd-mm-yy;@","[$-6000446]d-m-yy;@","[$-6000446]d.m.yy;@","[$-6000446]dd-mm-yyyy;@","[$-6000446]yyyy-mm-dd;@","[$-6000446]dd mmmm yyyy dddd;@","[$-6000446]d mmmm yyyy;@",, +"[$-10846]dd-mm-yy;@","[$-10846]d-m-yy;@","[$-10846]d.m.yy;@","[$-10846]dd-mm-yyyy;@","[$-10846]yyyy-mm-dd;@","[$-10846]dd mmmm yyyy dddd;@","[$-10846]d mmmm yyyy;@",,,,,,,,, +"[$-1046B]dd/mm/yyyy;@","[$-1046B]dd/mm/yy;@","[$-1046B]d/m/yy;@","[$-1046B]dd-mm-yy;@","[$-1046B]yyyy-mm-dd;@","[$-1046B]dddd, dd"" de ""mmmm"" de ""yyyy;@","[$-1046B]dddd d"" de ""mmmm"" de ""yyyy;@","[$-1046B]d"" de ""mmmm"" de ""yyyy;@",,,,,,,, +"[$-1086B]dd/mm/yyyy;@","[$-1086B]dd/mm/yy;@","[$-1086B]d/m/yy;@","[$-1086B]dd-mm-yy;@","[$-1086B]yyyy-mm-dd;@","[$-1086B]dddd, dd"" de ""mmmm"" de ""yyyy;@","[$-1086B]dddd d"" de ""mmmm"" de ""yyyy;@","[$-1086B]d"" de ""mmmm"" de ""yyyy;@",,,,,,,, +"[$-10C6B]dd/mm/yyyy;@","[$-10C6B]dd/mm/yy;@","[$-10C6B]d/m/yy;@","[$-10C6B]dd-mm-yy;@","[$-10C6B]yyyy-mm-dd;@","[$-10C6B]dddd, d mmmm, yyyy;@",,,,,,,,,, +"yyyy-mm-dd;@","d/m;@","d/m/yy;@","dd/mm/yy;@","[$-418]d-mmm;@","[$-418]d-mmm-yy;@","[$-418]dd-mmm-yy;@","[$-418]mmm-yy;@","[$-418]mmmm-yy;@","[$-418]d mmmm yyyy;@","[$-409]d/m/yy h:mm AM/PM;@","d/m/yy h:mm;@","[$-418]mmmmm;@","[$-418]mmmmm-yy;@","d/m/yyyy;@","[$-418]d-mmm-yyyy;@" +"yyyy-mm-dd;@","[$-10818]dd.mm.yyyy;@","[$-10818]d mmm yyyy;@","[$-10818]dddd, d mmmm yyyy;@","[$-10818]d mmmm yyyy;@",,,,,,,,,,, +"yyyy-mm-dd;@","[$-10417]dd-mm-yyyy;@","[$-10417]dd-mm-yy;@","[$-10417]dddd, ""ils’"" d. mmmm, yyyy;@","[$-10417]dddd, ""ils"" d mmmm yyyy;@","[$-10417]d mmmm yyyy;@",,,,,,,,,, +"yyyy-mm-dd;@","d/m;@","d/m/yy;@","dd/mm/yy;@","[$-419]d mmm;@","[$-419]d mmm yy;@","[$-419]dd mmm yy;@","[$-F419]yyyy, mmmm;@","[$-419]mmmm yyyy;@","[$-FC19]dd mmmm yyyy г.;@","[$-409]dd/mm/yy h:mm AM/PM;@","dd/mm/yy h:mm;@","[$-419]mmmm;@","[$-FC19]yyyy, dd mmmm;@","d/m/yyyy;@","[$-419]d-mmm-yyyy;@" +"yyyy-mm-dd;@","[$-10819]dd.mm.yyyy;@","[$-10819]d mmm yyyy ""г"".;@","[$]dddd, d mmmm yyyy ""г"".;@","[$]d mmmm yyyy ""г"".;@",,,,,,,,,,, +"[$-10485]dd.mm.yyyy;@","[$-10485]d.m.yyyy;@","[$-10485]yyyy-mm-dd;@","[$-10485]yyyy mm d;@","[$-10485]dd yyyy mm d;@","[$-10485]dddd, yyyy ""с."" mmmm d ""күнэ"";@","[$-10485]yyyy ""с."" mmmm d ""күнэ"";@","[$-10485]dddd, mmmm d ""күнэ"" yyyy ""с."";@",,,,,,,, +"dd-mm-yyyy;@","dd-mm-yy;@","d-m-yy;@","d.m.yy;@","yyyy-mm-dd;@","[$-44F]dd mmmm yyyy dddd;@","[$-44F]d mmmm yyyy;@",,,,,,,,, +"yyyy-mm-dd;@","[$-10491]dd/mm/yyyy;@","[$-10491]d mmm yyyy;@","[$-10491]dd mmmm yyyy;@","[$-10491]dddd, d""mh"" mmmm yyyy;@","[$-10491]d""mh"" mmmm yyyy;@",,,,,,,,,, +"d.m.yyyy;@","d.m.yy;@","d. m. yyyy;@","dd.mm.yyyy;@","d. m. yy;@","dd.mm.yy;@","dd. mm. yy;@","yyyy-mm-dd;@","[$-1C1A]d. mmmm yyyy;@","[$-1C1A]dd. mmmm yyyy;@","[$-1C1A]dddd, d. mmmm yyyy;@",,,,, +"d.m.yyyy;@","d.m.yy;@","d. m. yyyy;@","dd.mm.yyyy;@","d. m. yy;@","dd.mm.yy;@","dd. mm. yy;@","yyyy-mm-dd;@","[$-C1A]d. mmmm yyyy;@","[$-C1A]dd. mmmm yyyy;@","[$-C1A]dddd, d. mmmm yyyy;@",,,,, +"d.m.yyyy.;@","d.m.yy.;@","d. m. yyyy.;@","dd.mm.yyyy.;@","d. m. yy.;@","dd.mm.yy.;@","dd. mm. yy.;@","yyyy-mm-dd;@","[$-C1A]d. mmmm yyyy.;@","[$-C1A]dd. mmmm yyyy.;@","[$-C1A]dddd, d. mmmm yyyy.;@",,,,, +"d.m.yyyy.;@","d.m.yy.;@","d. m. yyyy.;@","dd.mm.yyyy.;@","d. m. yy.;@","dd.mm.yy.;@","dd. mm. yy.;@","yyyy-mm-dd;@","[$-281A]d. mmmm yyyy.;@","[$-281A]dd. mmmm yyyy.;@","[$-281A]dddd, d. mmmm yyyy.;@",,,,, +"yyyy-mm-dd;@","[$-1181A]d.m.yyyy.;@","[$-1181A]d.m.yy.;@","[$-1181A]dd.mm.yyyy.;@","[$-1181A]d. mmmm yyyy.;@","[$-1181A]dddd, dd. mmmm yyyy.;@","[$-1181A]dd. mmmm yyyy.;@",,,,,,,,, +"d.m.yyyy;@","d.m.yy;@","d. m. yyyy;@","dd.mm.yyyy;@","d. m. yy;@","dd.mm.yy;@","dd. mm. yy;@","yyyy-mm-dd;@","[$-81A]d. mmmm yyyy;@","[$-81A]dd. mmmm yyyy;@","[$-81A]dddd, d. mmmm yyyy;@",,,,, +"d.m.yyyy;@","d.m.yy;@","d. m. yyyy;@","dd.mm.yyyy;@","d. m. yy;@","dd.mm.yy;@","dd. mm. yy;@","yyyy-mm-dd;@","[$-81A]d. mmmm yyyy;@","[$-81A]dd. mmmm yyyy;@","[$-81A]dddd, d. mmmm yyyy;@",,,,, +"d.m.yyyy;@","d.m.yy;@","d. m. yyyy;@","dd.mm.yyyy;@","d. m. yy;@","dd.mm.yy;@","dd. mm. yy;@","yyyy-mm-dd;@","[$-241A]d. mmmm yyyy;@","[$-241A]dd. mmmm yyyy;@","[$-241A]dddd, d. mmmm yyyy;@",,,,, +"[$-10430]yyyy-mm-dd;@","[$-10430]yyyy mmm d;@","[$-10430]yyyy mmmm d, dddd;@","[$-10430]yyyy mmmm d;@",,,,,,,,,,,, +"[$-1046C]yyyy-mm-dd;@","[$-1046C]yyyy mmm d;@","[$-1046C]yyyy mmmm d, dddd;@","[$-1046C]yyyy mmmm d;@",,,,,,,,,,,, +"[$-10832]yyyy-mm-dd;@","[$-10832]yyyy mmm d;@","[$-10832]yyyy mmmm d, dddd;@","[$-10832]yyyy mmmm d;@",,,,,,,,,,,, +"[$-10432]yyyy-mm-dd;@","[$-10432]yyyy mmm d;@","[$-10432]dd mmmm yyyy;@","[$-10432]yyyy mmmm d, dddd;@","[$-10432]yyyy mmmm d;@",,,,,,,,,,, +"m/d/yyyy;@","m/d/yy;@","mm/dd/yy;@","mm/dd/yyyy;@","yyyy-mm-dd;@","yy/mm/dd;@",,,,,,,,,, +"[$-10859]dd/mm/yyyy;@","[$-10859]dd/mm/yy;@","[$-10859]yyyy-mm-dd;@","[$-10859]dddd, dd mmmm, yyyy;@","[$-10859]dd mmmm yyyy;@",,,,,,,,,,, +"yyyy-mm-dd;@","[$-10459]d/m/yyyy;@","[$-10459]d/m/yy;@","[$-10459]d mmm yyyy;@","[$-10459]dddd, d mmmm yyyy;@","[$-10459]d mmmm yyyy;@",,,,,,,,,, +"[$-1045B]yyyy-mm-dd;@","[$-1045B]yyyy mmm d;@","[$-1045B]yyyy mmmm d, dddd;@","[$-1045B]yyyy mmmm d;@",,,,,,,,,,,, +"[$-1203B]d.m.yyyy;@","[$-1203B]dd.mm.yyyy;@","[$-1203B]d.m.yy;@","[$-1203B]yyyy-mm-dd;@","[$-1203B]mmmm d"". p. ""yyyy;@","[$-1203B]dddd, mmmm d"". p. ""yyyy;@",,,,,,,,,,,,,, +"yyyy-mm-dd;@","d/m;@","d/m/yy;@","dd/mm/yy;@","[$-41B]d-mmm.;@","[$-41B]d/mmm/yy;@","[$-41B]dd-mmm-yy;@","[$-41B]mmm-yy;@","[$-41B]mmmm yy;@","[$-41B]d. mmmm yyyy;@","[$-409]d/m/yy h:mm AM/PM;@","d/m/yy h:mm;@","[$-41B]mmmmm;@","[$-41B]mmmmm-yy;@","d/m/yyyy;@","[$-41B]d/mmm/yyyy;@",,,, +"d.m.yyyy;@","d.m.yy;@","d. m. yyyy;@","dd.mm.yyyy;@","d. m. yy;@","dd.mm.yy;@","dd. mm. yy;@","yyyy-mm-dd;@","[$-424]d. mmmm yyyy;@","[$-424]dd. mmmm yyyy;@","[$-424]dddd, d. mmmm yyyy;@",,,,,,,,, +"yyyy-mm-dd;@","[$-10477]dd/mm/yyyy;@","[$-10477]dd/mm/yy;@","[$-10477]dd-mmm-yyyy;@","[$-10477]dddd, mmmm dd, yyyy;@","[$-10477]dd mmmm yyyy;@",,,,,,,,,,,,,, +"[$-1183B]dd.mm.yyyy;@","[$-1183B]dd.mm.yy;@","[$-1183B]d.m.yy;@","[$-1183B]yyyy-mm-dd;@","[$-1183B]dddd, mmmm d"". b. ""yyyy;@","[$-1183B]mmmm d"". b. ""yyyy;@",,,,,,,,,,,,,, +"[$-11C3B]yyyy-mm-dd;@","[$-11C3B]yy-mm-dd;@","[$-11C3B]dddd, mmmm d"". b. ""yyyy;@","[$-11C3B]mmmm d"". b. ""yyyy;@",,,,,,,,,,,,,,,, +"dd/mm/yyyy;@","dd/mm/yy;@","d/m/yy;@","dd-mm-yy;@","yyyy-mm-dd;@","[$-2C0A]dddd, dd"" de ""mmmm"" de ""yyyy;@","[$-2C0A]dddd d"" de ""mmmm"" de ""yyyy;@","[$-2C0A]d"" de ""mmmm"" de ""yyyy;@",,,,,,,,,,,, +"dd/mm/yyyy;@","dd/mm/yy;@","d/m/yy;@","dd-mm-yy;@","yyyy-mm-dd;@","[$-400A]dddd, dd"" de ""mmmm"" de ""yyyy;@","[$-400A]dddd d"" de ""mmmm"" de ""yyyy;@","[$-400A]d"" de ""mmmm"" de ""yyyy;@",,,,,,,,,,,, +"dd-mm-yyyy;@","dd-mm-yy;@","dd/mm/yy;@","d/m/yy;@","yyyy-mm-dd;@","[$-340A]dddd, dd"" de ""mmmm"" de ""yyyy;@","[$-340A]dddd d"" de ""mmmm"" de ""yyyy;@","[$-340A]d"" de ""mmmm"" de ""yyyy;@",,,,,,,,,,,, +"dd/mm/yyyy;@","dd/mm/yy;@","d/mm/yyyy;@","d/m/yy;@","dd-mm-yy;@","yyyy-mm-dd;@","[$-240A]dddd, dd"" de ""mmmm"" de ""yyyy;@","[$-240A]dddd d"" de ""mmmm"" de ""yyyy;@","[$-240A]d"" de ""mmmm"" de ""yyyy;@",,,,,,,,,,, +"dd/mm/yyyy;@","dd/mm/yy;@","d/m/yy;@","dd-mm-yy;@","yyyy-mm-dd;@","[$-140A]dddd, dd"" de ""mmmm"" de ""yyyy;@","[$-140A]dddd d"" de ""mmmm"" de ""yyyy;@","[$-140A]d"" de ""mmmm"" de ""yyyy;@",,,,,,,,,,,, +"dd/mm/yyyy;@","dd/mm/yy;@","mm/dd/yyyy;@","d/m/yy;@","dd-mm-yy;@","yyyy-mm-dd;@","[$-1C0A]dddd, dd"" de ""mmmm"" de ""yyyy;@","[$-1C0A]dddd d"" de ""mmmm"" de ""yyyy;@","[$-1C0A]d"" de ""mmmm"" de ""yyyy;@",,,,,,,,,,, +"dd/mm/yyyy;@","dd/mm/yy;@","d/m/yy;@","dd-mm-yy;@","yyyy-mm-dd;@","[$-300A]dddd, dd"" de ""mmmm"" de ""yyyy;@","[$-300A]dddd d"" de ""mmmm"" de ""yyyy;@","[$-300A]d"" de ""mmmm"" de ""yyyy;@",,,,,,,,,,,, +"dd/mm/yyyy;@","dd/mm/yy;@","mm-dd-yyyy;@","yyyy-mm-dd;@","[$-440A]dddd, dd"" de ""mmmm"" de ""yyyy;@",,,,,,,,,,,,,,, +"dd/mm/yyyy;@","dd/mm/yy;@","d/mm/yyyy;@","d/m/yy;@","dd-mm-yy;@","yyyy-mm-dd;@","[$-100A]dddd, dd"" de ""mmmm"" de ""yyyy;@","[$-100A]dddd d"" de ""mmmm"" de ""yyyy;@","[$-100A]d"" de ""mmmm"" de ""yyyy;@",,,,,,,,,,, +"dd/mm/yyyy;@","dd/mm/yy;@","mm-dd-yyyy;@","yyyy-mm-dd;@","[$-480A]dddd, dd"" de ""mmmm"" de ""yyyy;@",,,,,,,,,,,,,,, +"dd/mm/yyyy;@","dd/mm/yy;@","d/mm/yy;@","d/m/yy;@","dd-mm-yy;@","yyyy-mm-dd;@","[$-580A]dddd, dd"" de ""mmmm"" de ""yyyy;@","[$-580A]dddd d"" de ""mmmm"" de ""yyyy;@","[$-580A]d"" de ""mmmm"" de ""yyyy;@",,,,,,,,,,, +"dd/mm/yyyy;@","dd/mm/yy;@","d/mm/yy;@","d/m/yy;@","dd-mm-yy;@","yyyy-mm-dd;@","[$-80A]dddd, dd"" de ""mmmm"" de ""yyyy;@","[$-80A]dddd d"" de ""mmmm"" de ""yyyy;@","[$-80A]d"" de ""mmmm"" de ""yyyy;@",,,,,,,,,,, +"dd/mm/yyyy;@","dd/mm/yy;@","mm-dd-yyyy;@","yyyy-mm-dd;@","[$-4C0A]dddd, dd"" de ""mmmm"" de ""yyyy;@",,,,,,,,,,,,,,, +"mm/dd/yyyy;@","mm/dd/yy;@","d/m/yy;@","dd/mm/yy;@","dd-mm-yy;@","yyyy-mm-dd;@","[$-180A]dddd, dd"" de ""mmmm"" de ""yyyy;@","[$-180A]dddd d"" de ""mmmm"" de ""yyyy;@","[$-180A]d"" de ""mmmm"" de ""yyyy;@",,,,,,,,,,, +"dd/mm/yyyy;@","dd/mm/yy;@","d/m/yy;@","dd-mm-yy;@","yyyy-mm-dd;@","[$-3C0A]dddd, dd"" de ""mmmm"" de ""yyyy;@","[$-3C0A]dddd d"" de ""mmmm"" de ""yyyy;@","[$-3C0A]d"" de ""mmmm"" de ""yyyy;@",,,,,,,,,,,, +"dd/mm/yyyy;@","dd/mm/yy;@","d/m/yy;@","dd-mm-yy;@","yyyy-mm-dd;@","[$-280A]dddd, dd"" de ""mmmm"" de ""yyyy;@","[$-280A]dddd d"" de ""mmmm"" de ""yyyy;@","[$-280A]d"" de ""mmmm"" de ""yyyy;@",,,,,,,,,,,, +"dd/mm/yyyy;@","dd/mm/yy;@","mm-dd-yyyy;@","yyyy-mm-dd;@","[$-500A]dddd, dd"" de ""mmmm"" de ""yyyy;@",,,,,,,,,,,,,,, +"yyyy-mm-dd;@","d-m;@","d-m-yy;@","dd-mm-yy;@","[$-C0A]d-mmm;@","[$-C0A]d-mmm-yy;@","[$-C0A]dd-mmm-yy;@","[$-C0A]mmm-yy;@","[$-C0A]mmmm-yy;@","[$-C0A]d ""de"" mmmm ""de"" yyyy;@","[$-409]d-m-yy h:mm AM/PM;@","d-m-yy h:mm;@","[$-C0A]mmmmm;@","[$-C0A]mmmmm-yy;@","d-m-yyyy;@","[$-C0A]d-mmm-yyyy;@",,,, +"dd/mm/yyyy;@","dd/mm/yy;@","d/mm/yy;@","d/m/yy;@","dd-mm-yy;@","dd.mm.yy;@","yyyy-mm-dd;@","[$-40A]dddd, dd"" de ""mmmm"" de ""yyyy;@","[$-40A]dddd d"" de ""mmmm"" de ""yyyy;@","[$-40A]d"" de ""mmmm"" de ""yyyy;@",,,,,,,,,, +"[$-1540A]m/d/yyyy;@","[$-1540A]m/d/yy;@","[$-1540A]mm/dd/yy;@","[$-1540A]mm/dd/yyyy;@","[$-1540A]yy/mm/dd;@","[$-1540A]yyyy-mm-dd;@","[$-1540A]dd-mmm-yy;@","[$-1540A]dddd, mmmm dd, yyyy;@","[$-1540A]mmmm dd, yyyy;@","[$-1540A]dddd, dd mmmm, yyyy;@","[$-1540A]dd mmmm, yyyy;@",,,,,,,,, +"dd/mm/yyyy;@","dd/mm/yy;@","d/m/yy;@","dd-mm-yy;@","yyyy-mm-dd;@","[$-380A]dddd, dd"" de ""mmmm"" de ""yyyy;@","[$-380A]dddd d"" de ""mmmm"" de ""yyyy;@","[$-380A]d"" de ""mmmm"" de ""yyyy;@",,,,,,,,,,,, +"dd/mm/yyyy;@","dd/mm/yy;@","d/m/yy;@","dd-mm-yy;@","yyyy-mm-dd;@","[$-200A]dddd, dd"" de ""mmmm"" de ""yyyy;@","[$-200A]dddd d"" de ""mmmm"" de ""yyyy;@","[$-200A]d"" de ""mmmm"" de ""yyyy;@",,,,,,,,,,,, +"yyyy-mm-dd;@","dd-mm;@","dd-mm-yyyy;@","dd.mmm.yyyy;@","dd-mm-yy h:mm;@","yyyy-mm-dd;@",,,,,,,,,,,,,, +"d.m.yyyy;@","dd.mm.yyyy;@","d.m.yy;@","yyyy-mm-dd;@","[$-81D]""den ""d mmmm yyyy;@",,,,,,,,,,,,,,, +"yyyy-mm-dd;@","yyyy-mm-dd hh:mm;@","yy-mm-dd;@","yy-mm-dd hh:mm;@","d/m yyyy;@","d/m -yy;@","d/m yy;@","d/m/yy;@","[$-41D]""den "" d mmmm yyyy;@","[$-41D]d mmmm yyyy;@","[$-41D]d mmmm -yy;@","[$-41D]mmmmm;@","[$-41D]mmmmm-yy;@","yyyy mm dd;@","[$-41D]mmmm;@","[$-41D]dd-mmm;@","[$-41D]mmmm yyyy;@","[$-41D]mmmm -yy;@","[$-41D]mmm-yy;@","yyyy;@" +"yyyy-mm-dd;@","[$]dd.mm.yyyy;@","[$]dd.mm.yy;@","[$]dddd, d. mmmm yyyy;@","[$]d. mmmm yyyy;@",,,,,,,,,,,,,,, +"dd/mm/yyyy;@","dd/mm/yy;@","yyyy-mm-dd;@","[$-45A]dd mmmm, yyyy;@","[$-45A]dddd, dd mmmm, yyyy;@",,,,,,,,,,,,,,, +"yyyy-mm-dd;@","[$-10428]dd.mm.yyyy;@","[$-10428]dd.mm.yy;@","[$-10428]d.m.yy;@","[$-10428]dd-mm-yyyy;@","[$-10428]dd/mm/yy;@","[$-10428]d mmmm yyyy"" с."";@","[$-10428]dd mmmm yyyy"" с."";@","[$-10428]dddd, dd mmmm yyyy;@",,,,,,,,,,, +"dd-mm-yyyy;@","dd-mm-yy;@","d-m-yy;@","d.m.yy;@","yyyy-mm-dd;@","[$-449]dd mmmm yyyy;@","[$-449]d mmmm yyyy;@","[$-9000449]dd-mm-yyyy;@","[$-9000449]dd-mm-yy;@","[$-9000449]d-m-yy;@","[$-9000449]d.m.yy;@","[$-9000449]yyyy-mm-dd;@","[$-9000449]dd mmmm yyyy;@","[$-9000449]d mmmm yyyy;@",,,,,, +"dd-mm-yyyy;@","dd-mm-yy;@","d-m-yy;@","d.m.yy;@","yyyy-mm-dd;@","[$-449]dd mmmm yyyy;@","[$-449]d mmmm yyyy;@","[$-9000449]dd-mm-yyyy;@","[$-9000449]dd-mm-yy;@","[$-9000449]d-m-yy;@","[$-9000449]d.m.yy;@","[$-9000449]yyyy-mm-dd;@","[$-9000449]dd mmmm yyyy;@","[$-9000449]d mmmm yyyy;@",,,,,, +"dd.mm.yyyy;@","dd.mm.yy;@","d.m.yy;@","dd/mm/yy;@","yyyy-mm-dd;@","[$-444]d mmmm yyyy;@","[$-444]dd mmmm yyyy;@",,,,,,,,,,,,, +"dd-mm-yy;@","d-m-yy;@","d.m.yy;@","dd-mm-yyyy;@","yyyy-mm-dd;@","[$-44A]dd mmmm yyyy;@","[$-44A]d mmmm yyyy;@","[$-A00044A]dd-mm-yy;@","[$-A00044A]d-m-yy;@","[$-A00044A]d.m.yy;@","[$-A00044A]dd-mm-yyyy;@","[$-A00044A]yyyy-mm-dd;@","[$-A00044A]dd mmmm yyyy;@","[$-A00044A]d mmmm yyyy;@",,,,,, +"[$-1070000]d/m/yy;@","[$-1070000]d/mm/yyyy;@","[$-1070000]d/mm/yyyy h:mm ""น."";@","[$-1070409]d/mm/yyyy h:mm AM/PM;@","[$-D070000]d/m/yy;@","[$-D070000]d/mm/yyyy;@","[$-D070000]d/mm/yyyy h:mm ""น."";@","[$-D07041E]d mmm yy;@","[$-D07041E]d mmmm yyyy;@","[$-107041E]d mmm yy;@","[$-107041E]d mmmm yyyy;@",,,,,,,,, +"[$-10451]yyyy/m/d;@","[$-10451]yyyy-m-d;@","[$-10451]yyyy.m.d;@","[$-10451]yyyy.mm.dd;@","[$-10451]yyyy-mm-dd;@","[$-10451]yyyy/mm/dd;@","[$-10451]yy-m-d;@","[$-10451]yy/m/d;@","[$-10451]yy.m.d;@","[$-10451]yyyy""ལོའི་ཟླ"" m""ཚེས"" d;@","[$-10451]yyyy""ལོའི་ཟླ"" m""ཚེས"" d dddd;@","[$-10451]yyyyལོའི་ཟླ mmm d;@","[$-10451]yyyyལོའི་ཟླ mmm d dddd;@",,, +"yyyy-mm-dd;@","[$-10873]dd/mm/yyyy;@","[$-10873]dd/mm/yy;@","[$-10873]dd-mmm-yyyy;@","[$-10873]dddd\፣ dd mmmm መዓልቲ yyyy gg;@","[$-10873]dd mmmm yyyy;@",,,,,,,,,, +"yyyy-mm-dd;@","[$-10473]d/m/yyyy;@","[$-10473]dd/mm/yyyy;@","[$-10473]dd/mm/yy;@","[$-10473]dd-mmm-yyyy;@","[$-10473]dddd ""፣"" mmmm d ""መዓልቲ"" yyyy;@","[$-10473]dddd\፣ dd mmmm መዓልቲ yyyy gg;@","[$-10473]dd mmmm yyyy;@",,,,,,,, +"yyyy-mm-dd;@","d/m;@","d/m/yy;@","dd/mm/yy;@","[$-41F]d mmmm;@","[$-41F]d mmmm yy;@","[$-41F]dd mmmm yy;@","dd/mm/yyyy;@","[$-41F]mmmm yy;@","[$-41F]d mmmm yyyy;@","d/m/yy h:mm;@","[$-41F]d mmmm yyyy h:mm;@","[$-41F]mmmmm;@","[$-41F]mmmmm yy;@","m/d/yyyy;@","[$-41F]d mmm yyyy;@" +"yyyy-mm-dd;@","d/m;@","d/m/yy;@","dd/mm/yy;@","[$-41F]d mmmm;@","[$-41F]d mmmm yy;@","[$-41F]dd mmmm yy;@","dd/mm/yyyy;@","[$-41F]mmmm yy;@","[$-41F]d mmmm yyyy;@","d/m/yy h:mm;@","[$-41F]d mmmm yyyy h:mm;@","[$-41F]mmmmm;@","[$-41F]mmmmm yy;@","m/d/yyyy;@","[$-41F]d mmm yyyy;@" +"yyyy-mm-dd;@","[$-10442]dd.mm.yy ""ý."";@","[$-10442]dd.mm.yyyy;@","[$-10442]yyyy""-nji ýylyň ""d""-nji ""mmmm;@","[$-10442]d mmmm yyyy dddd;@",,,,,,,,,,, +"dd.mm.yyyy;@","dd.mm.yy;@","yyyy-mm-dd;@","[$-FC22]d mmmm yyyy"" р."";@",,,,,,,,,,,, +"yyyy-mm-dd;@","[$-1042E]d.m.yyyy;@","[$-1042E]d.m.yy;@","[$-1042E]dddd, d. mmmm yyyy;@","[$-1042E]d. mmmm yyyy;@",,,,,,,,,,, +"dd/mm/yyyy;@","dd/mm/yy;@","yyyy-mm-dd;@","m/d/yyyy;@","m/d/yy;@","mm/dd/yy;@","mm/dd/yyyy;@","[$-420]dd mmmm, yyyy;@","[$-420]dddd, dd mmmm, yyyy;@","[$-420]dddd, mmmm dd, yyyy;@","[$-420]mmmm dd, yyyy;@","[$-420]dd/mmmm/yyyy;@",,,, +"dd/mm/yyyy;@","dd/mm/yy;@","yyyy-mm-dd;@","m/d/yyyy;@","m/d/yy;@","mm/dd/yy;@","mm/dd/yyyy;@","[$-420]dd mmmm, yyyy;@","[$-420]dddd, dd mmmm, yyyy;@","[$-420]dddd, mmmm dd, yyyy;@","[$-420]mmmm dd, yyyy;@","[$-420]dd/mmmm/yyyy;@",,,, +"[$-10480]yyyy-m-d;@","[$-10480]yyyy.m.d;@","[$-10480]yyyy-mm-dd;@","[$-10480]yyyy.mm.dd;@","[$-10480]yyyy-""يىل"" d-mmmm;@","[$-10480]yyyy-""يىل"" d-mmmm dddd;@","[$-10480]yyyy-""يىلى"" mmm""نىڭ"" d""-كۈنى"";@","[$-10480]yyyy-""يىلى"" mmm""نىڭ"" d""-كۈنى"" dddd;@","[$-10480]yyyy-m-d dddd;@",,,,,,, +"dd.mm.yyyy;@","dd.mm.yy;@","dd/mm yyyy;@","d.m.yy;@","dd/mm/yy;@","yyyy-mm-dd;@","[$-843]yyyy ""йил"" d-mmmm;@","[$-843]d mmmm yyyy;@","[$-843]dd mmmm yyyy;@",,,,,,, +"dd/mm yyyy;@","dd.mm.yy;@","d.m.yy;@","dd/mm/yy;@","yyyy-mm-dd;@","[$-443]yyyy ""yil"" d-mmmm;@","[$-443]d mmmm yyyy;@","[$-443]dd mmmm yyyy;@",,,,,,,, +"[$]dd/mm yyyy;@","[$]dd.mm.yy;@","[$]d.m.yy;@","[$]dd/mm/yy;@","[$]yyyy-mm-dd;@","[$]dddd d mmmm yyyy;@","[$]d mmmm yyyy;@",,,,,,,,, +"dd/mm/yyyy;@","dd/mm/yy;@","yyyy-mm-dd;@","[$-403]dddd, d"" de ""mmmm"" de ""yyyy;@","[$-403]d"" de ""mmmm"" de ""yyyy;@","[$-403]d"" ""mmmm"" ""yyyy;@",,,,,,,,,, +"[$-10433]yyyy-mm-dd;@","[$-10433]yyyy mmm d;@","[$-10433]yyyy mmmm d, dddd;@","[$-10433]yyyy mmmm d;@",,,,,,,,,,,, +"yyyy-mm-dd;@","[$-1010000]d/m/yy;@","[$-1010000]d/m/yyyy;@","[$-101042A]d/m/yyyy h:mm AM/PM;@","[$-1010409]d/m/yyyy h:mm AM/PM;@","[$-101042A]d mmm yy;@","[$-101042A]d mmmm yyyy;@","[$-101040C]d mmm yy;@","[$-101040C]d mmmm yyyy;@","[$-1010409]d mmm yy;@","[$-1010409]d mmmm yyyy;@",,,,, +"yyyy-mm-dd;@","[$-10452]dd/mm/yyyy;@","[$-10452]dd/mm/yy;@","[$-10452]d mmm yyyy;@","[$-10452]dddd, d mmmm yyyy;@","[$-10452]d mmmm yyyy;@",,,,,,,,,, +"yyyy-mm-dd;@","[$-10462]dd-mm-yyyy;@","[$-10462]dd-mm-yy;@","[$-10462]d mmm yyyy;@","[$-10462]dddd d mmmm yyyy;@","[$-10462]d mmmm yyyy;@",,,,,,,,,, +"yyyy-mm-dd;@","[$-10488]dd-mm-yyyy;@","[$-10488]d mmm, yyyy;@","[$-10488]dddd, d mmm, yyyy;@","[$-10488]d mmmm, yyyy;@",,,,,,,,,,, +"[$-10431]yyyy-mm-dd;@","[$-10431]yyyy mmm d;@","[$-10431]yyyy mmmm d, dddd;@","[$-10431]yyyy mmmm d;@",,,,,,,,,,,, +"[$-10478]yyyy/m/d;@","[$-10478]yyyy-m-d;@","[$-10478]yyyy.m.d;@","[$-10478]yyyy.mm.dd;@","[$-10478]yyyy-mm-dd;@","[$-10478]yyyy/mm/dd;@","[$-10478]yyyy""ꈎ"" m""ꆪ"" d""ꑍ"";@","[$-10478]dddd, yyyy""ꈎ"" m""ꆪ"" d""ꑍ"";@","[$-10478]yyyy""ꈎ"" m""ꆪ"" d""ꑍ"", dddd;@","[$-10478]yyyyꈎ mmm dꑍ;@","[$-10478]dddd, yyyyꈎ mmm dꑍ;@",,,,, +"yyyy-mm-dd;@","[$-1043D]dd/mm/yyyy;@","[$-1043D]dd/mm/yy;@","[$-1043D]dטן mmm yyyy;@","[$-1043D]dddd, dטן mmmm yyyy;@","[$-1043D]dטן mmmm yyyy;@",,,,,,,,,, +"yyyy-mm-dd;@","[$-1046A]d/m/yyyy;@","[$-1046A]d mm yyyy;@","[$-1046A]dddd, d mmm yyyy;@","[$-1046A]d mmm yyyy;@",,,,,,,,,,, \ No newline at end of file diff --git a/Test/Applications/ParseExcelNumberFormatLocales/ParseDateTimeList/all-time.csv b/Test/Applications/ParseExcelNumberFormatLocales/ParseDateTimeList/all-time.csv new file mode 100644 index 00000000000..9d0e8642281 --- /dev/null +++ b/Test/Applications/ParseExcelNumberFormatLocales/ParseDateTimeList/all-time.csv @@ -0,0 +1,270 @@ +"h:mm;@","[$-409]h:mm AM/PM;@","h:mm:ss;@","[$-409]h:mm:ss AM/PM;@","mm:ss.0;@","[h]:mm:ss;@","[$-409]m/d/yy h:mm AM/PM;@","m/d/yy h:mm;@", +"[$-409]hh:mm:ss AM/PM;@","[$-409]h:mm:ss AM/PM;@",,,,,,,, +"[$-41C]hh:mm:ss.Pd/md;@","hh:mm:ss;@",,,,,,,, +"[$-10484]hh:mm:ss;@","[$-10484]h:mm:ss;@","[$-10484]hh:mm;@","[$-10484]h:mm;@","[$-10484]hh.mm;@","[$-10484]hh"" h ""mm;@","[$-10484]hh""h""mm;@",,, +"[$-1045E]h:mm:ss AM/PM;@","[$-1045E]hh:mm:ss;@","[$-1045E]h:mm AM/PM;@","[$-1045E]hh:mm;@",,,,,, +"[$-1000000]h:mm:ss;@","[$-1000401]h:mm AM/PM;@","[$-1000409]h:mm AM/PM;@","[$-2000000]h:mm:ss;@","[$-2000401]h:mm AM/PM;@","[$-2000409]h:mm AM/PM;@",,,, +"[$-1000000]h:mm:ss;@","[$-1000401]h:mm AM/PM;@","[$-1000409]h:mm AM/PM;@","[$-2000000]h:mm:ss;@","[$-2000401]h:mm AM/PM;@","[$-2000409]h:mm AM/PM;@",,,, +"[$-1000000]h:mm:ss;@","[$-1000401]h:mm AM/PM;@","[$-1000409]h:mm AM/PM;@","[$-2000000]h:mm:ss;@","[$-2000401]h:mm AM/PM;@","[$-2000409]h:mm AM/PM;@",,,, +"[$-1000000]h:mm:ss;@","[$-1000401]h:mm AM/PM;@","[$-1000409]h:mm AM/PM;@","[$-2000000]h:mm:ss;@","[$-2000401]h:mm AM/PM;@","[$-2000409]h:mm AM/PM;@",,,, +"[$-1000000]h:mm:ss;@","[$-1000401]h:mm AM/PM;@","[$-1000409]h:mm AM/PM;@","[$-2000000]h:mm:ss;@","[$-2000401]h:mm AM/PM;@","[$-2000409]h:mm AM/PM;@",,,, +"[$-1000000]h:mm:ss;@","[$-1000401]h:mm AM/PM;@","[$-1000409]h:mm AM/PM;@","[$-2000000]h:mm:ss;@","[$-2000401]h:mm AM/PM;@","[$-2000409]h:mm AM/PM;@",,,, +"[$-1000000]h:mm:ss;@","[$-1000401]h:mm AM/PM;@","[$-1000409]h:mm AM/PM;@","[$-2000000]h:mm:ss;@","[$-2000401]h:mm AM/PM;@","[$-2000409]h:mm AM/PM;@",,,, +"[$-1000000]h:mm:ss;@","[$-1000401]h:mm AM/PM;@","[$-1000409]h:mm AM/PM;@","[$-2000000]h:mm:ss;@","[$-2000401]h:mm AM/PM;@","[$-2000409]h:mm AM/PM;@",,,, +"[$-1000000]h:mm:ss;@","[$-1000401]h:mm AM/PM;@","[$-1000409]h:mm AM/PM;@","[$-2000000]h:mm:ss;@","[$-2000401]h:mm AM/PM;@","[$-2000409]h:mm AM/PM;@",,,, +"[$-1000000]h:mm:ss;@","[$-1000401]h:mm AM/PM;@","[$-1000409]h:mm AM/PM;@","[$-2000000]h:mm:ss;@","[$-2000401]h:mm AM/PM;@","[$-2000409]h:mm AM/PM;@",,,, +"[$-1000000]h:mm:ss;@","[$-1000401]h:mm AM/PM;@","[$-1000409]h:mm AM/PM;@","[$-2000000]h:mm:ss;@","[$-2000401]h:mm AM/PM;@","[$-2000409]h:mm AM/PM;@",,,, +"[$-1000000]h:mm:ss;@","[$-1000401]h:mm AM/PM;@","[$-1000409]h:mm AM/PM;@","[$-2000000]h:mm:ss;@","[$-2000401]h:mm AM/PM;@","[$-2000409]h:mm AM/PM;@",,,, +"[$-1000000]h:mm:ss;@","[$-1000401]h:mm AM/PM;@","[$-1000409]h:mm AM/PM;@","[$-2000000]h:mm:ss;@","[$-2000401]h:mm AM/PM;@","[$-2000409]h:mm AM/PM;@",,,, +"[$-1000000]h:mm:ss;@","[$-1000401]h:mm AM/PM;@","[$-1000409]h:mm AM/PM;@","[$-2000000]h:mm:ss;@","[$-2000401]h:mm AM/PM;@","[$-2000409]h:mm AM/PM;@",,,, +"[$-1000000]h:mm:ss;@","[$-1000401]h:mm AM/PM;@","[$-1000409]h:mm AM/PM;@","[$-2000000]h:mm:ss;@","[$-2000401]h:mm AM/PM;@","[$-2000409]h:mm AM/PM;@",,,, +"[$-1000000]h:mm:ss;@","[$-1000401]h:mm AM/PM;@","[$-1000409]h:mm AM/PM;@","[$-2000000]h:mm:ss;@","[$-2000401]h:mm AM/PM;@","[$-2000409]h:mm AM/PM;@",,,, +"h:mm:ss;@","hh:mm:ss;@","[$-409]h:mm:ss AM/PM;@","[$-409]hh:mm:ss AM/PM;@",,,,,, +"[$-1044D]AM/PM h:mm:ss;@","[$-1044D]AM/PM hh:mm:ss;@","[$-1044D]h:mm:ss;@","[$-1044D]AM/PM h:mm;@","[$-1044D]AM/PM hh:mm;@","[$-1044D]h:mm;@",,,, +"h:mm:ss;@","hh:mm:ss;@",,,,,,,, +"h:mm:ss;@","hh:mm:ss;@",,,,,,,, +"[$-10409]h:mm:ss AM/PM;@","[$-10845]hh:mm:ss;@","[$-10409]h:mm AM/PM;@","[$-10845]hh:mm;@",,,,,, +"[$-1046D]h:mm:ss;@","[$-1046D]h:mm;@",,,,,,,, +"h:mm;@","[$-409]h:mm AM/PM;@","h:mm:ss;@","[$-409]h:mm:ss AM/PM;@","mm:ss.0;@","[h]:mm:ss;@","[$-409]yy/mm/dd h:mm AM/PM;@","yy/mm/dd h:mm;@",, +"h:mm:ss;@","hh:mm:ss;@",,,,,,,, +"[$-10445]hh.mm.ss;@","[$-10445]h.mm.ss;@","[$-10409]AM/PM hh.mm.ss;@","[$-10409]AM/PM h.mm.ss;@","[$-10445]hh.mm;@","[$-10445]h.mm;@","[$-10409]AM/PM hh.mm;@","[$-10409]AM/PM h.mm;@",, +"[$-1201A]h:mm:ss;@","[$-1201A]hh:mm:ss;@","[$-1201A]h:mm;@","[$-1201A]hh:mm;@",,,,,, +"[$-1141A]hh:mm:ss;@","[$-1141A]hh:mm;@",,,,,,,, +"[$-1047E]hh:mm:ss;@","[$-1047E]hh:mm;@",,,,,,,, +"hh:mm:ss;@","h:mm:ss;@",,,,,,,, +"[$-10455]hh:mm:ss;@","[$-10455]h:mm;@","[$-10455]hh:mm;@",,,,,,, +"h:mm:ss;@","h:mm;@",,,,,,,, +"[$-1045F]hh:mm:ss;@","[$-1045F]hh:mm;@",,,,,,,, +"[$-1085F]h:mm:ss;@","[$-1085F]hh:mm:ss;@","[$-1085F]h:mm;@","[$-1085F]hh:mm;@",,,,,, +"h:mm;@","[$-105F]h:mm;@","h:mm:ss;@","[$-105F]h:mm:ss;@","mm:ss.0;@","[h]:mm:ss;@","[$-105F]dd-mm-yy h:mm;@","dd-mm-yy h:mm;@",, +"[$-1000000]hh:mm:ss;@","[$-1000429]hh:mm AM/PM;@","[$-1000409]h:mm AM/PM;@","[$-3000000]h:mm:ss;@","[$-3000429]h:mm AM/PM;@","[$-3000409]h:mm AM/PM;@",,,, +"[$-10409]h:mm:ss AM/PM;@","[$-10409]hh:mm:ss AM/PM;@","[$-1045C]h:mm:ss;@","[$-1045C]hh:mm:ss;@","[$-10409]h:mm AM/PM;@","[$-10409]hh:mm AM/PM;@","[$-1045C]h:mm;@","[$-1045C]hh:mm;@",, +"h:mm;@","[$-409]h:mm AM/PM;@","h:mm:ss;@","[$-409]h:mm:ss AM/PM;@","h""时""mm""分"";@","h""时""mm""分""ss""秒"";@","上午/下午h""时""mm""分"";@","上午/下午h""时""mm""分""ss""秒"";@","[DBNum1][$-804]h""时""mm""分"";@","[DBNum1][$-804]上午/下午h""时""mm""分"";@" +"h:mm:ss;@","hh:mm:ss;@",,,,,,,, +"h:mm:ss;@","hh:mm:ss;@",,,,,,,, +"[$-409]AM/PM h:mm:ss;@","[$-409]AM/PM hh:mm:ss;@","h:mm:ss;@","hh:mm:ss;@",,,,,, +"h:mm;@","[$-409]h:mm AM/PM;@","h:mm:ss;@","[$-409]h:mm:ss AM/PM;@","[$-409]yyyy/m/d h:mm AM/PM;@","yyyy/m/d h:mm;@","h""時""mm""分"";@","h""時""mm""分""ss""秒"";@","上午/下午h""時""mm""分"";@","上午/下午h""時""mm""分""ss""秒"";@" +"[$-10483]h:mm:ss;@","[$-10483]hh:mm:ss;@","[$-10483]hh:mm;@","[$-10483]h:mm;@","[$-10483]hh.mm;@",,,,, +"[$-1101A]hh:mm:ss;@","[$-1101A]hh:mm;@",,,,,,,, +"h:mm;@","[$-409]h:mm AM/PM;@","h:mm:ss;@","[$-409]h:mm:ss AM/PM;@","mm:ss.0;@","[h]:mm:ss;@","[$-409]d.m.yy. h:mm AM/PM;@","d.m.yy. h:mm;@",, +"h:mm;@","[$-409]h:mm AM/PM;@","h:mm:ss;@","[$-409]h:mm:ss AM/PM;@","mm:ss.0;@","[h]:mm:ss;@","[$-409]d/m/yy h:mm AM/PM;@","d/m/yy h:mm;@",, +"hh:mm;@","hh:mm:ss;@","[$-409]hh:mm AM/PM;@","[$-409]hh:mm:ss AM/PM;@","dd-mm-yy hh:mm;@","mm-dd-yy hh:mm:ss;@","dd-mm-yy hh:mm:ss;@","yyyy-mm-dd hh:mm;@",, +"[$-16048C]h:mm:ss;@","[$-16048C]hh:mm:ss;@","[$-16048C]h:mm;@","[$-16048C]hh:mm;@",,,,,, +"hh:mm;@","hh:mm:ss;@","hh:mm;@","[$-465]hh:mm AM/PM;@","hh:mm:ss;@","[$-465]hh:mm:ss AM/PM;@",,,, +"h:mm:ss;@","hh:mm:ss;@","h.mm"" u."";@","h:mm;@",,,,,, +"h:mm;@","[$-409]h:mm AM/PM;@","h:mm:ss;@","[$-409]h:mm:ss AM/PM;@","mm:ss.0;@","[h]:mm:ss;@","[$-409]d-mm-yy h:mm AM/PM;@","d-mm-yy h:mm;@",, +"[$-10466]hh:mm:ss;@","[$-10466]hh:mm;@",,,,,,,, +"[$-409]h:mm:ss AM/PM;@","h:mm:ss;@","hh:mm:ss;@",,,,,,, +"[$-409]hh:mm:ss AM/PM;@","hh:mm:ss;@",,,,,,,, +"[$-409]h:mm:ss AM/PM;@","[$-409]hh:mm:ss AM/PM;@","hh:mm:ss;@","h:mm:ss;@",,,,,, +"[$-409]h:mm:ss AM/PM;@","[$-409]hh:mm:ss AM/PM;@","h:mm:ss;@","hh:mm:ss;@",,,,,, +"[$-10409]h:mm:ss AM/PM;@","[$-13C09]hh:mm:ss;@","[$-10409]h:mm AM/PM;@","[$-13C09]hh:mm;@",,,,,, +"[$-14009]hh:mm:ss;@","[$-14009]h:mm:ss;@","[$-10409]h.mm.ss AM/PM;@","[$-10409]hh:mm:ss AM/PM;@","[$-14009]hh:mm;@","[$-14009]h:mm;@","[$-10409]hh:mm AM/PM;@",,, +"[$-13809]hh:mm:ss;@","[$-13809]h:mm:ss;@","[$-13809]hh:mm;@","[$-13809]h:mm;@",,,,,, +"hh:mm:ss;@","h:mm:ss;@",,,,,,,, +"[$-409]hh:mm:ss AM/PM;@","[$-409]h:mm:ss AM/PM;@","h:mm:ss;@","hh:mm:ss;@",,,,,, +"[$-10409]h:mm:ss AM/PM;@","[$-10409]hh:mm:ss AM/PM;@","[$-14409]h:mm:ss;@","[$-14409]hh:mm:ss;@","[$-10409]h:mm AM/PM;@","[$-10409]hh:mm AM/PM;@","[$-14409]h:mm;@","[$-14409]hh:mm;@",, +"[$-1409]h:mm:ss AM/PM;@","[$-1409]hh:mm:ss AM/PM;@","hh:mm:ss;@","h:mm:ss;@",,,,,, +"[$-409]h:mm:ss AM/PM;@","[$-409]hh:mm:ss AM/PM;@","h:mm:ss;@","hh:mm:ss;@",,,,,, +"[$-10409]h:mm:ss AM/PM;@","[$-14809]hh:mm:ss;@","[$-10409]h:mm AM/PM;@","[$-14809]hh:mm;@",,,,,, +"[$-409]hh:mm:ss AM/PM;@","hh:mm:ss;@",,,,,,,, +"[$-409]hh:mm:ss AM/PM;@","hh:mm:ss;@",,,,,,,, +"hh:mm:ss;@","h:mm:ss;@","[$-409]hh:mm:ss AM/PM;@","[$-409]h:mm:ss AM/PM;@",,,,,, +"h:mm;@","[$-409]h:mm AM/PM;@","h:mm:ss;@","[$-409]h:mm:ss AM/PM;@","mm:ss.0;@","[h]:mm:ss;@","[$-409]m/d/yy h:mm AM/PM;@","m/d/yy h:mm;@", +"[$-409]h:mm:ss AM/PM;@","[$-409]hh:mm:ss AM/PM;@","h:mm:ss;@","hh:mm:ss;@",,,,,, +"h:mm:ss;@","hh:mm:ss;@",,,,,,,, +"hh.mm.ss;@","hh:mm:ss;@",,,,,,,, +"[$-10409]h:mm:ss AM/PM;@","[$-10464]hh:mm:ss;@","[$-10409]h:mm AM/PM;@","[$-10464]hh:mm;@",,,,,, +"h:mm;@","[$-409]h:mm AM/PM;@","h:mm:ss;@","[$-409]h:mm:ss AM/PM;@","mm:ss.0;@","[h]:mm:ss;@","[$-409]d.m.yyyy h:mm AM/PM;@","d.m.yyyy h:mm;@",, +"h:mm:ss;@","hh:mm:ss;@","h.mm;@","h"" h ""mm;@","h"" h ""m"" min ""s"" s "";@",,,,, +"[$-12C0C]hh:mm:ss;@","[$-12C0C]hh:mm;@",,,,,,,, +"hh:mm:ss;@","h:mm:ss;@","h"" h ""mm;@","h:mm;@",,,,,, +"[$-11C0C]hh:mm:ss;@","[$-11C0C]h:mm:ss;@","[$-11C0C]hh:mm;@","[$-11C0C]h:mm;@",,,,,, +"[$-1240C]hh:mm:ss;@","[$-1240C]hh:mm;@",,,,,,,, +"[$-1300C]hh:mm:ss;@","[$-1300C]hh:mm;@",,,,,,,, +"h:mm;@","[$-409]h:mm AM/PM;@","h:mm:ss;@","[$-409]h:mm:ss AM/PM;@","mm:ss.0;@","[h]:mm:ss;@","[$-409]d/m/yy h:mm AM/PM;@","d/m/yy h:mm;@",, +"[$-13C0C]hh:mm:ss;@","[$-13C0C]hh:mm;@",,,,,,,, +"hh:mm:ss;@","h:mm:ss;@","hh.mm;@","hh"" h ""mm;@",,,,,, +"[$-1340C]hh:mm:ss;@","[$-1340C]hh:mm;@",,,,,,,, +"hh:mm:ss;@","h:mm:ss;@","hh.mm;@","hh"" h ""mm;@",,,,,, +"[$-1380C]hh:mm:ss;@","[$-1380C]hh:mm;@",,,,,,,, +"[$-1200C]hh:mm:ss;@","[$-1200C]hh:mm;@",,,,,,,, +"[$-1280C]hh:mm:ss;@","[$-1280C]hh:mm;@",,,,,,,, +"hh:mm:ss;@","h:mm:ss;@","hh.mm"" h"";@",,,,,,, +"[$-10867]hh:mm:ss;@","[$-10867]h:mm:ss;@","[$-10867]hh:mm;@","[$-10867]h:mm;@","[$-10867]hh.mm;@","[$-10867]hh"" h ""mm;@",,,, +"[$-10467]hh:mm:ss;@","[$-10467]hh:mm;@",,,,,,,, +"h:mm:ss;@","hh:mm:ss;@","hh:mm;@","[$-456]hh:mm:ss AM/PM;@",,,,,, +"h:mm:ss;@","hh:mm:ss;@",,,,,,,, +"hh:mm:ss;@","h:mm:ss;@","hh:mm;@","hh:mm"" Uhr"";@",,,,,, +"h:mm;@","[$-409]h:mm AM/PM;@","h:mm:ss;@","[$-409]h:mm:ss AM/PM;@","mm:ss.0;@","[h]:mm:ss;@","[$-409]d/m/yy h:mm AM/PM;@","d.m.yy h:mm;@",, +"hh:mm:ss;@","h:mm:ss;@","h.mm"" h"";@","hh.mm"" h"";@","h.mm"" Uhr"";@",,,,, +"hh:mm:ss;@","h:mm:ss;@","h.mm;@","h.mm"" Uhr "";@",,,,,, +"hh:mm:ss;@","h:mm:ss;@","h.mm"" h"";@","hh.mm"" h"";@","h.mm"" Uhr"";@",,,,, +"h:mm;@","[$-408]h:mm AM/PM;@","h:mm:ss;@","[$-408]h:mm:ss AM/PM;@","mm:ss.0;@","[h]:mm:ss;@","[$-408]d/m/yy h:mm AM/PM;@","d/m/yy h:mm;@",, +"[$-10474]hh:mm:ss;@","[$-10474]h:mm:ss;@","[$-10474]hh:mm:ss AM/PM;@","[$-10474]hh:mm;@","[$-10474]h:mm;@","[$-10474]hh:mm AM/PM;@",,,, +"hh:mm:ss;@","h:mm:ss;@","[$-447]AM/PM hh:mm:ss;@","[$-447]AM/PM h:mm:ss;@",,,,,, +"[$-10468]hh:mm:ss;@","[$-10468]hh:mm;@",,,,,,,, +"[$-10409]h:mm:ss AM/PM;@","[$-10475]hh:mm:ss;@","[$-10409]h:mm AM/PM;@","[$-10475]hh:mm;@",,,,,, +"[$-1000000]h:mm;@","[$-1000409]h:mm AM/PM;@","[$-1000000]h:mm:ss;@","[$-1000409]h:mm:ss AM/PM;@","[$-1010409]d/m/yyyy h:mm AM/PM;@","[$-1010409]d/m/yyyy h:mm;@",,,,,,, +"[$-1000000]h:mm;@","[$-4000000]h:mm;@","[$-1000439]h:mm AM/PM;@","[$-4000439]h:mm AM/PM;@","[$-1000409]h:mm AM/PM;@","[$-1000439]h:mm:ss AM/PM;@","[$-4000439]h:mm:ss AM/PM;@","[$-1000409]h:mm:ss AM/PM;@",,,,, +"h:mm;@","[$-40E]h:mm AM/PM;@","h:mm:ss;@","[$-40E]h:mm:ss AM/PM;@","mm:ss.0;@","[h]:mm:ss;@","[$-40E]yyyy. m. d. h:mm AM/PM;@","yyyy. m. d. h:mm;@","[$-40E]h ""óra"" m ""perc"" AM/PM;@","h ""óra"" m ""perc"";@","[$-40E]h ""óra"" m ""perckor"" AM/PM;@",, +"[$-10469]hh:mm:ss;@","[$-10469]hh:mm;@",,,,,,,,,,, +"hh:mm:ss;@","h:mm:ss;@","hh:mm;@",,,,,,,,,, +"[$-10470]hh:mm:ss;@","[$-10470]hh:mm;@",,,,,,,,,,, +"[$-1243B]h:mm:ss;@","[$-1243B]hh:mm:ss;@","[$-1243B]h:mm;@","[$-1243B]hh:mm;@",,,,,,,,, +"h:mm:ss;@","hh:mm:ss;@",,,,,,,,,,, +"[$-10409]h:mm:ss AM/PM;@","[$-10409]hh:mm:ss AM/PM;@","[$-1085D]hh:mm:ss;@","[$-1085D]h:mm:ss;@","[$-10409]h:mm AM/PM;@","[$-10409]hh:mm AM/PM;@","[$-1085D]hh:mm;@","[$-1085D]h:mm;@",,,,, +"[$-10409]h:mm:ss AM/PM;@","[$-10409]hh:mm:ss AM/PM;@","[$-1045D]h:mm:ss;@","[$-1045D]hh:mm:ss;@","[$-10409]h:mm AM/PM;@","[$-10409]hh:mm AM/PM;@","[$-1045D]h:mm;@","[$-1045D]hh:mm;@",,,,, +"[$-1083C]hh:mm:ss;@","[$-1083C]hh:mm;@",,,,,,,,,,, +"[$-10434]hh:mm:ss;@","[$-10434]hh:mm;@",,,,,,,,,,, +"[$-10435]hh:mm:ss;@","[$-10435]hh:mm;@",,,,,,,,,,, +"h:mm;@","[$-409]h:mm AM/PM;@","h:mm:ss;@","[$-409]h:mm:ss AM/PM;@","mm:ss.0;@","[h]:mm:ss;@","[$-409]d/m/yy h:mm AM/PM;@","d/m/yy h:mm;@",,,,, +"hh:mm:ss;@","h:mm:ss;@","h.mm"" h"";@",,,,,,,,,, +"h:mm;@","[$-409]h:mm AM/PM;@","h:mm:ss;@","[$-409]h:mm:ss AM/PM;@","[$-409]yyyy/m/d h:mm AM/PM;@","yyyy/m/d h:mm;@","h""時""mm""分"";@","h""時""mm""分""ss""秒"";@",,,,, +"[$]hh:mm:ss;@","[$]hh:mm;@",,,,,,,,,,, +"h:mm:ss;@","hh:mm:ss;@",,,,,,,,,,, +"[$-1046F]hh:mm:ss;@","[$-1046F]h:mm:ss;@","[$-1046F]hh:mm;@","[$-1046F]h:mm;@",,,,,,,,, +"hh:mm:ss;@","h:mm:ss;@","[$-44B]AM/PM hh:mm:ss;@","[$-44B]AM/PM h:mm:ss;@",,,,,,,,, +"[$-10409]h:mm:ss AM/PM;@","[$-10471]hh:mm:ss;@","[$-10409]h:mm AM/PM;@","[$-10471]hh:mm;@",,,,,,,,, +"[$-10409]AM/PM h:mm:ss;@","[$-10860]hh:mm:ss;@","[$-10409]AM/PM h:mm;@","[$-10860]hh:mm;@",,,,,,,,, +"[$-10409]h:mm:ss AM/PM;@","[$-10460]hh:mm:ss;@","[$-10409]h:mm AM/PM;@","[$-10460]hh:mm;@",,,,,,,,, +"h:mm:ss;@","hh:mm:ss;@",,,,,,,,,,, +"[$-10453]hh:mm:ss;@","[$-10453]h:mm;@",,,,,,,,,,, +"[$-10486]h:mm:ss AM/PM;@","[$-10486]hh:mm:ss;@","[$-10486]h:mm AM/PM;@","[$-10486]hh:mm;@",,,,,,,,, +"[$-10487]hh:mm:ss;@","[$-10487]hh:mm;@",,,,,,,,,,, +"[$-409]h:mm:ss AM/PM;@","[$-409]hh:mm:ss AM/PM;@","h:mm:ss;@","hh:mm:ss;@",,,,,,,,, +"hh:mm:ss;@","h:mm:ss;@","[$-457]hh:mm:ss AM/PM;@","[$-457]h:mm:ss AM/PM;@",,,,,,,,, +"h:mm;@","h:mm:ss;@","[$-412]AM/PM h:mm;@","[$-412]AM/PM h:mm:ss;@","[$-409]h:mm AM/PM;@","[$-409]h:mm:ss AM/PM;@","yyyy""-""m""-""d h:mm;@","[$-412]yyyy""-""m""-""d AM/PM h:mm;@","[$-409]yyyy""-""m""-""d h:mm AM/PM;@","h""시"" mm""분"";@","h""시"" mm""분"" ss""초"";@","[$-412]AM/PM h""시"" mm""분"";@","[$-412]AM/PM h""시"" mm""분"" ss""초"";@" +"h:mm:ss;@",,,,,,,,,,,, +"[$-10454]h:mm:ss;@","[$-10454]hh:mm:ss;@","[$-10454]h:mm;@","[$-10454]hh:mm;@",,,,,,,,, +"[$-10476]hh:mm:ss;@","[$-10476]hh:mm;@",,,,,,,,,,, +"h:mm:ss;@","hh:mm:ss;@",,,,,,,,,,, +"hh:mm:ss;@","hh:mm;@",,,,,,,,,,, +"[$-1082E]hh:mm:ss;@","[$-1082E]h:mm:ss"" góź."";@","[$-1082E]""zeger ""h:mm:ss;@","[$-1082E]hh:mm;@","[$-1082E]h:mm;@","[$-1082E]h:mm"" góź."";@","[$-1082E]""zeger ""h:mm;@",,,,,, +"[$-1103B]hh:mm:ss;@","[$-1103B]h:mm:ss;@","[$-1103B]hh.mm.ss;@","[$-1103B]hh:mm;@","[$-1103B]h:mm;@","[$-1103B]hh.mm;@",,,,,,, +"[$-1143B]hh:mm:ss;@","[$-1143B]h:mm:ss;@","[$-1143B]hh:mm;@","[$-1143B]h:mm;@",,,,,,,,, +"[$-1046E]hh:mm:ss;@","[$-1046E]h:mm:ss"" Auer"";@","[$-1046E]hh:mm:ss"" Auer"";@","[$-1046E]hh:mm;@","[$-1046E]h:mm;@","[$-1046E]h.mm;@","[$-1046E]h.mm"" Auer"";@",,,,,, +"hh:mm:ss;@",,,,,,,,,,,, +"[$]hh:mm:ss;@","[$]hh:mm;@",,,,,,,,,,, +"h:mm:ss;@","hh:mm:ss;@",,,,,,,,,,, +"h:mm:ss;@","hh:mm:ss;@",,,,,,,,,,, +"[$-10409]h:mm:ss AM/PM;@","[$-1044C]hh:mm:ss;@","[$-10409]h:mm AM/PM;@","[$-1044C]hh:mm;@",,,,,,,,, +"[$-1043A]hh:mm:ss;@","[$-1043A]hh:mm;@",,,,,,,,,,, +"[$-10458]h:mm:ss AM/PM;@","[$-10458]hh:mm:ss;@","[$-10458]h:mm AM/PM;@","[$-10458]hh:mm;@",,,,,,,,, +"[$-10409]h:mm:ss AM/PM;@","[$-10481]hh:mm:ss;@","[$-10409]h:mm AM/PM;@","[$-10481]hh:mm;@",,,,,,,,, +"[$-1047A]h:mm:ss;@","[$-1047A]hh:mm:ss;@","[$-1047A]h:mm;@","[$-1047A]hh:mm;@",,,,,,,,, +"hh:mm:ss;@","h:mm:ss;@","[$-44E]hh:mm:ss AM/PM;@","[$-44E]h:mm:ss AM/PM;@",,,,,,,,, +"[$-10409]h:mm:ss AM/PM;@","[$-10409]hh:mm:ss AM/PM;@","[$-1047C]hh:mm:ss;@","[$-1047C]h:mm:ss;@","[$-10409]h:mm AM/PM;@","[$-10409]hh:mm AM/PM;@","[$-1047C]hh:mm;@","[$-1047C]h:mm;@",,,,, +"h:mm:ss;@",,,,,,,,,,,, +"[$-10850]h:mm:ss;@","[$-10850]h:mm;@",,,,,,,,,,, +"[$-10C50]h:mm:ss;@","[$-10C50]h:mm;@",,,,,,,,,,, +"[$-10461]h:mm:ss AM/PM;@","[$-10461]hh:mm:ss AM/PM;@","[$-10461]h:mm:ss;@","[$-10461]hh:mm:ss;@","[$-10461]h:mm AM/PM;@","[$-10461]hh:mm AM/PM;@","[$-10461]h:mm;@","[$-10461]hh:mm;@",,,,, +"[$-10861]h:mm:ss AM/PM;@","[$-10861]hh:mm:ss;@","[$-10861]h:mm AM/PM;@","[$-10861]hh:mm;@",,,,,,,,, +"[$]AM/PM hh:mm:ss;@","[$]hh:mm:ss;@","[$]AM/PM hh:mm;@","[$]hh:mm;@",,,,,,,,, +"[$-10C3B]h:mm:ss;@","[$-10C3B]hh:mm:ss;@","[$-10C3B]h:mm;@","[$-10C3B]hh:mm;@",,,,,,,,, +"[$-1043B]hh:mm:ss;@","[$-1043B]hh:mm;@",,,,,,,,,,, +"[$-1083B]hh:mm:ss;@","[$-1083B]h:mm:ss;@","[$-1083B]hh:mm;@","[$-1083B]h:mm;@",,,,,,,,, +"hh:mm;@","[$-409]h:mm AM/PM;@","hh:mm:ss;@","[$-409]h:mm:ss AM/PM;@","kl 'hh.mm;@","[h]:mm:ss;@","[$-409]m/d/yy h:mm AM/PM;@","m/d/yy hh:mm;@",,,,, +"hh:mm:ss;@","h:mm:ss;@","""kl ""hh.mm;@","hh.mm.ss;@",,,,,,,,, +"[$-10482]h""h""mm:ss;@","[$-10482]hh""h""mm ss ""seg"".;@","[$-10482]h""h""mm;@","[$-10482]hh""h""mm;@",,,,,,,,, +"[$-10448]hh:mm:ss;@","[$-10448]h:mm:ss;@","[$-10409]AM/PM hh:mm:ss;@","[$-10409]AM/PM h:mm:ss;@","[$-10448]hh:mm;@","[$-10448]h:mm;@","[$-10409]AM/PM hh:mm;@","[$-10409]AM/PM h:mm;@",,,,, +"[$-10472]h:mm:ss AM/PM;@","[$-10472]hh:mm:ss;@","[$-10472]h:mm AM/PM;@","[$-10472]hh:mm;@",,,,,,,,, +"[$-10479]h:mm:ss;@","[$-10479]hh:mm:ss;@","[$-10479]h:mm;@","[$-10479]hh:mm;@",,,,,,,,, +"[$-160463]h:mm:ss;@","[$-160463]hh:mm:ss;@","[$-160463]h:mm;@","[$-160463]hh:mm;@",,,,,,,,, +"[$-1000000]hh:mm:ss;@","[$-1000429]hh:mm AM/PM;@","[$-1000409]h:mm AM/PM;@","[$-3000000]h:mm:ss;@","[$-3000429]h:mm AM/PM;@","[$-3000409]h:mm AM/PM;@",, +"h:mm;@","[$-409]h:mm AM/PM;@","h:mm:ss;@","[$-409]h:mm:ss AM/PM;@","mm:ss.0;@","[h]:mm:ss;@","[$-409]yy-mm-dd h:mm AM/PM;@","yy-mm-dd h:mm;@" +"h:mm;@","[$-409]h:mm AM/PM;@","h:mm:ss;@","[$-409]h:mm:ss AM/PM;@","mm:ss.0;@","[h]:mm:ss;@","[$-409]d/m/yy h:mm AM/PM;@","d/m/yy h:mm;@" +"h:mm;@","[$-409]h:mm AM/PM;@","h:mm:ss;@","[$-409]h:mm:ss AM/PM;@","mm:ss.0;@","[h]:mm:ss;@","[$-409]d/m/yy h:mm AM/PM;@","d/m/yy h:mm;@" +"h:mm;@","[$-409]h:mm AM/PM;@","h:mm:ss;@","[$-409]h:mm:ss AM/PM;@","mm:ss.0;@","[h]:mm:ss;@","[$-409]d/m/yy h:mm AM/PM;@","d/m/yy h:mm;@" +"[$-446]AM/PM hh:mm:ss;@","[$-446]AM/PM h:mm:ss;@","h:mm:ss;@","hh:mm:ss;@",,,, +"[$-10409]h.mm.ss AM/PM;@","[$-10409]hh:mm:ss AM/PM;@","[$-10846]h:mm:ss;@","[$-10846]hh:mm:ss;@","[$-10409]h.mm AM/PM;@","[$-10409]hh:mm AM/PM;@","[$-10846]h:mm;@","[$-10846]hh:mm;@" +"[$-1046B]hh:mm:ss AM/PM;@","[$-1046B]h:mm:ss AM/PM;@","[$-1046B]h:mm:ss;@","[$-1046B]hh:mm:ss;@","[$-1046B]hh:mm AM/PM;@","[$-1046B]h:mm AM/PM;@","[$-1046B]h:mm;@","[$-1046B]hh:mm;@" +"[$-1086B]h:mm:ss;@","[$-1086B]hh:mm:ss;@","[$-1086B]h:mm;@","[$-1086B]hh:mm;@",,,, +"[$-10C6B]hh:mm:ss AM/PM;@","[$-10C6B]hh:mm:ss;@","[$-10C6B]hh:mm AM/PM;@","[$-10C6B]hh:mm;@",,,, +"h:mm;@","[$-409]h:mm AM/PM;@","h:mm:ss;@","[$-409]h:mm:ss AM/PM;@","mm:ss.0;@","[h]:mm:ss;@","[$-409]d/m/yy h:mm AM/PM;@","d/m/yy h:mm;@" +"[$-10818]hh:mm:ss;@","[$-10818]hh:mm;@",,,,,, +"[$-10417]hh:mm:ss;@","[$-10417]hh:mm;@",,,,,, +"h:mm;@","[$-409]h:mm AM/PM;@","h:mm:ss;@","[$-409]h:mm:ss AM/PM;@","mm:ss.0;@","[h]:mm:ss;@","[$-409]dd/mm/yy h:mm AM/PM;@","dd/mm/yy h:mm;@" +"[$-10819]hh:mm:ss;@","[$-10819]hh:mm;@",,,,,, +"[$-10485]hh:mm:ss;@","[$-10485]hh:mm;@",,,,,, +"hh:mm:ss;@","h:mm:ss;@","[$-44F]hh:mm:ss AM/PM;@","[$-44F]h:mm:ss AM/PM;@",,,, +"[$-10491]hh:mm:ss;@","[$-10491]hh:mm;@",,,,,, +"h:mm:ss;@","hh:mm:ss;@",,,,,, +"h:mm:ss;@","hh:mm:ss;@",,,,,, +"h:mm:ss;@","hh:mm:ss;@",,,,,, +"h:mm:ss;@","hh:mm:ss;@",,,,,, +"[$-1181A]hh:mm:ss;@","[$-1181A]hh:mm;@",,,,,, +"h:mm:ss;@","hh:mm:ss;@",,,,,, +"h:mm:ss;@","hh:mm:ss;@",,,,,, +"h:mm:ss;@","hh:mm:ss;@",,,,,, +"[$-10430]hh:mm:ss;@","[$-10430]hh:mm;@",,,,,, +"[$-1046C]hh:mm:ss;@","[$-1046C]hh:mm;@",,,,,, +"[$-10832]hh:mm:ss;@","[$-10832]hh:mm;@",,,,,, +"[$-10432]hh:mm:ss;@","[$-10432]hh:mm;@",,,,,, +"[$-409]h:mm:ss AM/PM;@","[$-409]hh:mm:ss AM/PM;@","h:mm:ss;@","hh:mm:ss;@",,,, +"[$-10409]h:mm:ss AM/PM;@","[$-10409]hh:mm:ss AM/PM;@","[$-10859]h:mm:ss;@","[$-10859]hh:mm:ss;@","[$-10409]h:mm AM/PM;@","[$-10409]hh:mm AM/PM;@","[$-10859]h:mm;@","[$-10859]hh:mm;@" +"[$-10409]AM/PM h:mm:ss;@","[$-10459]hh:mm:ss;@","[$-10409]AM/PM h:mm;@","[$-10459]hh:mm;@",,,, +"[$-1045B]hh.mm.ss;@","[$-1045B]hh.mm;@",,,,,, +"[$-1203B]h:mm:ss;@","[$-1203B]hh:mm:ss;@","[$-1203B]h:mm;@","[$-1203B]hh:mm;@",,,, +"h:mm;@","[$-409]h:mm AM/PM;@","h:mm:ss;@","[$-409]h:mm:ss AM/PM;@","mm:ss.0;@","[h]:mm:ss;@","[$-409]d/m/yy h:mm AM/PM;@","d/m/yy h:mm;@" +"h:mm:ss;@","hh:mm:ss;@",,,,,, +"[$-10477]h:mm:ss AM/PM;@","[$-10477]hh:mm:ss;@","[$-10477]h:mm AM/PM;@","[$-10477]hh:mm;@",,,, +"[$-1183B]hh:mm:ss;@","[$-1183B]h:mm:ss;@","[$-1183B]hh:mm;@","[$-1183B]h:mm;@",,,, +"[$-11C3B]hh:mm:ss;@","[$-11C3B]h:mm:ss;@","[$-11C3B]hh:mm;@","[$-11C3B]h:mm;@",,,, +"[$-2C0A]hh:mm:ss AM/PM;@","[$-2C0A]h:mm:ss AM/PM;@","hh:mm:ss;@","h:mm:ss;@",,,, +"[$-400A]hh:mm:ss AM/PM;@","[$-400A]h:mm:ss AM/PM;@","h:mm:ss;@","hh:mm:ss;@",,,, +"h:mm:ss;@","hh:mm:ss;@",,,,,, +"[$-240A]hh:mm:ss AM/PM;@","[$-240A]h:mm:ss AM/PM;@","h:mm:ss;@","hh:mm:ss;@",,,, +"[$-140A]hh:mm:ss AM/PM;@","[$-140A]h:mm:ss AM/PM;@","h:mm:ss;@","hh:mm:ss;@",,,, +"[$-1C0A]hh:mm:ss AM/PM;@","[$-1C0A]h:mm:ss AM/PM;@","h:mm:ss;@","hh:mm:ss;@",,,, +"h:mm:ss;@","hh:mm:ss;@",,,,,, +"[$-440A]hh:mm:ss AM/PM;@","hh:mm:ss;@",,,,,, +"[$-100A]hh:mm:ss AM/PM;@","[$-100A]h:mm:ss AM/PM;@","h:mm:ss;@","hh:mm:ss;@",,,, +"[$-480A]hh:mm:ss AM/PM;@","hh:mm:ss;@",,,,,, +"[$-580A]hh:mm:ss AM/PM;@","[$-580A]h:mm:ss AM/PM;@","h:mm:ss;@","hh:mm:ss;@",,,, +"[$-80A]hh:mm:ss AM/PM;@","[$-80A]h:mm:ss AM/PM;@","h:mm:ss;@","hh:mm:ss;@",,,, +"[$-4C0A]hh:mm:ss AM/PM;@","hh:mm:ss;@",,,,,, +"[$-180A]hh:mm:ss AM/PM;@","[$-180A]h:mm:ss AM/PM;@","h:mm:ss;@","hh:mm:ss;@",,,, +"[$-3C0A]hh:mm:ss AM/PM;@","[$-3C0A]h:mm:ss AM/PM;@","h:mm:ss;@","hh:mm:ss;@",,,, +"[$-280A]hh:mm:ss AM/PM;@","[$-280A]h:mm:ss AM/PM;@","h:mm:ss;@","hh:mm:ss;@",,,, +"[$-500A]hh:mm:ss AM/PM;@","hh:mm:ss;@",,,,,, +"h:mm;@","[$-409]h:mm AM/PM;@","h:mm:ss;@","[$-409]h:mm:ss AM/PM;@","mm:ss.0;@","[h]:mm:ss;@","[$-409]d-m-yy h:mm AM/PM;@","d-m-yy h:mm;@" +"h:mm:ss;@","hh:mm:ss;@","hh:mm;@","hh""H""mm""'"";@",,,, +"[$-10409]h:mm:ss AM/PM;@","[$-10409]hh:mm:ss AM/PM;@","[$-1540A]h:mm:ss;@","[$-1540A]hh:mm:ss;@","[$-10409]h:mm AM/PM;@","[$-10409]hh:mm AM/PM;@","[$-1540A]h:mm;@","[$-1540A]hh:mm;@" +"[$-380A]hh:mm:ss AM/PM;@","[$-380A]h:mm:ss AM/PM;@","h:mm:ss;@","hh:mm:ss;@",,,, +"[$-200A]hh:mm:ss AM/PM;@","[$-200A]h:mm:ss AM/PM;@","h:mm:ss;@","hh:mm:ss;@",,,, +"h:mm;@","h:mm:ss;@","mm:ss.0;@","[h]:mm:ss;@","dd-mm-yy h:mm;@",,, +"hh:mm:ss;@","h:mm:ss;@","""kl ""h:mm;@",,,,, +"hh:mm;@","hh:mm:ss;@","""kl ""hh:mm;@","""kl ""hh:mm:ss;@","[$-409]yyyy-mm-dd h:mm AM/PM;@","[h]:mm:ss;@","yyyy-mm-dd hh:mm;@","[$-409]yyyy-mm-dd h:mm AM/PM;@" +"[$]hh:mm:ss;@","[$]hh:mm;@",,,,,, +"[$-45A]hh:mm:ss AM/PM;@","hh:mm:ss;@",,,,,, +"[$-10428]hh:mm:ss;@","[$-10428]h:mm:ss;@","[$-10428]hh:mm;@","[$-10428]h:mm;@",,,, +"hh:mm:ss;@","h:mm:ss;@","[$-449]hh:mm:ss AM/PM;@","[$-449]h:mm:ss AM/PM;@",,,, +"hh:mm:ss;@","h:mm:ss;@","[$-449]hh:mm:ss AM/PM;@","[$-449]h:mm:ss AM/PM;@",,,, +"h:mm:ss;@","hh:mm:ss;@",,,,,, +"hh:mm:ss;@","h:mm:ss;@","[$-44A]AM/PM hh:mm:ss;@","[$-44A]AM/PM h:mm:ss;@",,,, +"[$-D000000]h:mm:ss AM/PM;@","[$-D000000]h:mm:ss;@","[$-D000000]h:mm ""น."";@","[$-D000409]h:mm AM/PM;@","[$-1000000]h:mm:ss AM/PM;@","[$-1000000]h:mm:ss;@","[$-1000000]h:mm ""น."";@","[$-1000409]h:mm AM/PM;@" +"[$-10451]hh:mm:ss;@","[$-10451]hh:mm;@",,,,,, +"[$-10873]h:mm:ss AM/PM;@","[$-10873]hh:mm:ss;@","[$-10873]h:mm AM/PM;@","[$-10873]hh:mm;@",,,, +"[$-10473]h:mm:ss AM/PM;@","[$-10473]hh:mm:ss;@","[$-10473]h:mm AM/PM;@","[$-10473]hh:mm;@",,,, +"hh:mm;@","hh:mm:ss;@","mm:ss.0;@","d/m/yy hh:mm;@","dd/mm/yy hh:mm;@","d/m/yyyy hh:mm;@","m/d/yy hh:mm;@", +"hh:mm;@","hh:mm:ss;@","mm:ss.0;@","d/m/yy hh:mm;@","dd/mm/yy hh:mm;@","d/m/yyyy hh:mm;@","m/d/yy hh:mm;@", +"[$-10442]hh:mm:ss;@","[$-10442]h:mm:ss;@","[$-10442]hh:mm;@","[$-10442]h:mm;@",,,, +"h:mm:ss;@","hh:mm:ss;@",,,,,, +"[$-1042E]h:mm:ss;@","[$-1042E]h:mm ""hodź"".;@",,,,,, +"[$-409]h:mm:ss AM/PM;@","[$-409]hh:mm:ss AM/PM;@","h:mm:ss;@","hh:mm:ss;@",,,, +"[$-409]h:mm:ss AM/PM;@","[$-409]hh:mm:ss AM/PM;@","h:mm:ss;@","hh:mm:ss;@",,,, +"[$-10480]h:mm:ss;@","[$-10480]hh:mm:ss;@","[$-10480]AM/PM h:mm:ss;@","[$-10480]AM/PM hh:mm:ss;@","[$-10480]h:mm;@","[$-10480]hh:mm;@","[$-10480]AM/PM h:mm;@","[$-10480]AM/PM hh:mm;@" +"hh:mm:ss;@","h:mm:ss;@",,,,,, +"hh:mm:ss;@","h:mm:ss;@",,,,,, +"[$]h:mm:ss;@","[$]hh:mm:ss;@","[$]h:mm;@","[$]hh:mm;@",,,, +"hh:mm:ss;@","h:mm:ss;@","hh:mm;@","h:mm;@",,,, +"[$-10433]hh:mm:ss;@","[$-10433]hh:mm;@",,,,,, +"[$-1000000]h:mm;@","[$-100042A]h:mm:ss AM/PM;@","[$-1000409]h:mm:ss AM/PM;@","[$-1000000]h:mm:ss;@",,,, +"[$-10452]hh:mm:ss;@","[$-10452]hh:mm;@",,,,,, +"[$-10462]hh:mm:ss;@","[$-10462]hh:mm;@",,,,,, +"[$-10488]hh:mm:ss;@","[$-10488]hh:mm;@",,,,,, +"[$-10431]hh:mm:ss;@","[$-10431]hh:mm;@",,,, +"[$-10478]AM/PM h:mm:ss;@","[$-10478]h:mm:ss;@","[$-10478]hh:mm:ss;@","[$-10478]AM/PM h:mm;@","[$-10478]h:mm;@","[$-10478]hh:mm;@" +"[$-1043D]hh:mm:ss;@","[$-1043D]hh:mm;@",,,, +"[$-1046A]h:m:s;@","[$-1046A]hh:mm:ss;@","[$-1046A]h:m;@","[$-1046A]hh:mm;@",, \ No newline at end of file diff --git a/Test/Applications/ParseExcelNumberFormatLocales/ParseDateTimeList/all.json b/Test/Applications/ParseExcelNumberFormatLocales/ParseDateTimeList/all.json new file mode 100644 index 00000000000..50feb80c07e --- /dev/null +++ b/Test/Applications/ParseExcelNumberFormatLocales/ParseDateTimeList/all.json @@ -0,0 +1,4186 @@ +{ + "0": 1033, + "1": 1078, + "2": 1052, + "3": 1156, + "4": 1118, + "5": 1025, + "6": 0, + "7": 0, + "8": 0, + "9": 0, + "10": 0, + "11": 0, + "12": 0, + "13": 0, + "14": 0, + "15": 0, + "16": 0, + "17": 0, + "18": 0, + "19": 0, + "20": 0, + "21": 1067, + "22": 1101, + "23": 2092, + "24": 1068, + "25": 2117, + "26": 1133, + "27": 1069, + "28": 64547, + "29": 1093, + "30": 8218, + "31": 5146, + "32": 1150, + "33": 1026, + "34": 1109, + "35": 1027, + "36": 1119, + "37": 2143, + "38": 4191, + "39": 1065, + "40": 1116, + "41": 2052, + "42": 3076, + "43": 5124, + "44": 4100, + "45": 1028, + "46": 1155, + "47": 4122, + "48": 1050, + "49": 1029, + "50": 1030, + "51": 1164, + "52": 1125, + "53": 2067, + "54": 1043, + "55": 1126, + "56": 3081, + "57": 10249, + "58": 4105, + "59": 9225, + "60": 15369, + "61": 16393, + "62": 14345, + "63": 6153, + "64": 8201, + "65": 17417, + "66": 5129, + "67": 13321, + "68": 18441, + "69": 7177, + "70": 11273, + "71": 2057, + "72": 0, + "73": 12297, + "74": 1061, + "75": 1080, + "76": 1124, + "77": 1035, + "78": 2060, + "79": 11276, + "80": 3084, + "81": 7180, + "82": 9228, + "83": 12300, + "84": 1036, + "85": 15372, + "86": 5132, + "87": 13324, + "88": 6156, + "89": 14348, + "90": 8204, + "91": 10252, + "92": 4108, + "93": 2151, + "94": 1127, + "95": 1110, + "96": 1079, + "97": 3079, + "98": 1031, + "99": 5127, + "100": 4103, + "101": 2055, + "102": 1032, + "103": 1140, + "104": 1095, + "105": 1128, + "106": 1141, + "107": 1037, + "108": 1081, + "109": 1038, + "110": 1129, + "111": 1039, + "112": 1136, + "113": 9275, + "114": 1057, + "115": 2141, + "116": 1117, + "117": 2108, + "118": 1076, + "119": 1077, + "120": 1040, + "121": 2064, + "122": 0, + "123": 0, + "124": 0, + "125": 1135, + "126": 1099, + "127": 1137, + "128": 2144, + "129": 1120, + "130": 1087, + "131": 1107, + "132": 1158, + "133": 1159, + "134": 1089, + "135": 1111, + "136": 1042, + "137": 1088, + "138": 1108, + "139": 1142, + "140": 1062, + "141": 64551, + "142": 2094, + "143": 4155, + "144": 5179, + "145": 1134, + "146": 1071, + "147": 0, + "148": 2110, + "149": 1086, + "150": 1100, + "151": 1082, + "152": 1112, + "153": 1153, + "154": 1146, + "155": 1102, + "156": 1148, + "157": 1104, + "158": 2128, + "159": 3152, + "160": 1121, + "161": 2145, + "162": 0, + "163": 3131, + "164": 1083, + "165": 2107, + "166": 1044, + "167": 2068, + "168": 1154, + "169": 1096, + "170": 1138, + "171": 1145, + "172": 1123, + "173": 0, + "174": 1045, + "175": 2070, + "176": 1046, + "177": 0, + "178": 1094, + "179": 2118, + "180": 1131, + "181": 2155, + "182": 3179, + "183": 1048, + "184": 2072, + "185": 1047, + "186": 1049, + "187": 2073, + "188": 1157, + "189": 1103, + "190": 1169, + "191": 7194, + "192": 3098, + "193": 0, + "194": 10266, + "195": 6170, + "196": 2074, + "197": 0, + "198": 9242, + "199": 1072, + "200": 1132, + "201": 2098, + "202": 1074, + "203": 0, + "204": 2137, + "205": 1113, + "206": 1115, + "207": 8251, + "208": 1051, + "209": 1060, + "210": 1143, + "211": 6203, + "212": 7227, + "213": 11274, + "214": 16394, + "215": 13322, + "216": 9226, + "217": 5130, + "218": 7178, + "219": 12298, + "220": 17418, + "221": 4106, + "222": 18442, + "223": 22538, + "224": 2058, + "225": 19466, + "226": 6154, + "227": 15370, + "228": 10250, + "229": 20490, + "230": 3082, + "231": 1034, + "232": 21514, + "233": 14346, + "234": 8202, + "235": 0, + "236": 2077, + "237": 1053, + "238": 0, + "239": 1114, + "240": 1064, + "241": 1097, + "242": 0, + "243": 1092, + "244": 1098, + "245": 1054, + "246": 1105, + "247": 2163, + "248": 1139, + "249": 1055, + "250": 0, + "251": 1090, + "252": 64546, + "253": 1070, + "254": 1056, + "255": 0, + "256": 1152, + "257": 2115, + "258": 1091, + "259": 0, + "260": 0, + "261": 1075, + "262": 1066, + "263": 1106, + "264": 1122, + "265": 1160, + "266": 1073, + "267": 1144, + "268": 1085, + "269": 1130 +} +{ + "1025": [ + "yyyy-mm-dd;@", + "[$-1010000]d/m/yyyy;@", + "[$-1010000]yyyy/mm/dd;@", + "[$-1010401]d/m/yyyy h:mm AM/PM;@", + "[$-1010409]d/m/yyyy h:mm AM/PM;@", + "[$-2010000]d/mm/yyyy;@", + "[$-2010000]yyyy/mm/dd;@", + "[$-2010401]d/mm/yyyy h:mm AM/PM;@" + ], + "1026": [ + "dd.m.yyyy \"г.\";@", + "d.m.yyyy \"г.\";@", + "dd.mm.yyyy \"г.\";@", + "yyyy-mm-dd;@", + "[$-402]dd mmmm yyyy \"г.\";@", + "[$-402]dddd, dd mmmm yyyy \"г.\";@" + ], + "1027": [ + "dd/mm/yyyy;@", + "dd/mm/yy;@", + "yyyy-mm-dd;@", + "[$-403]dddd, d mmmm\" de \"yyyy;@", + "[$-403]d mmmm\" de \"yyyy;@", + "[$-403]mmmm\" de \"yyyy;@" + ], + "1028": [ + "yyyy-mm-dd;@", + "yyyy\"年\"m\"月\"d\"日\";@", + "m\"月\"d\"日\";@", + "[DBNum1][$-404]yyyy\"年\"m\"月\"d\"日\";@", + "[DBNum1][$-404]m\"月\"d\"日\";@", + "[$-404]aaaa;@", + "[$-404]aaa;@", + "yyyy/m/d;@", + "yyyy/m/d h:mm;@", + "[$-409]yyyy/m/d h:mm AM/PM;@", + "m/d;@", + "m/d/yy;@", + "mm/dd/yy;@", + "[$-409]d-mmm;@", + "[$-409]d-mmm-yy;@", + "[$-409]mmmmm;@", + "[$-409]mmmmm-yy;@" + ], + "1029": [ + "yyyy-mm-dd;@", + "d/m;@", + "d/m/yy;@", + "dd/mm/yy;@", + "[$-405]d-mmm.;@", + "[$-405]d/mmm/yy;@", + "[$-405]dd-mmm-yy;@", + "[$-405]mmm-yy;@", + "[$-405]mmmm yy;@", + "[$-405]d. mmmm yyyy;@", + "[$-409]d/m/yy h:mm AM/PM;@", + "d/m/yy h:mm;@", + "[$-405]mmmmm;@", + "[$-405]mmmmm-yy;@", + "d/m/yyyy;@", + "[$-405]d-mmm-yyyy;@" + ], + "1030": [ + "dd-mm-yy;@", + "[$-406]d. mmmm yyyy;@", + "yyyy-mm-dd;@", + "yyyy.mm.dd;@", + "yy-mm-dd;@", + "[$-406]mmmm yyyy;@", + "d.m.yy;@", + "d/m yyyy;@", + "dd-mm-yy hh:mm;@", + "dd-mm-yy hh:mm:ss;@", + "yyyy-mm-dd hh:mm;@", + "[$-406]mmmm yy;@", + "dd.mm.yyyy;@", + "d.m.yyyy;@", + "dd.mm.yy;@", + "dd/mm yyyy;@", + "dd/mm yy;@", + "d/m yy;@", + "[$-406]mmmmm;@", + "[$-406]mmmmm-yy;@" + ], + "1031": [ + "yyyy-mm-dd;@", + "d.m;@", + "d.m.yy;@", + "dd.mm.yy;@", + "[$-407]d. mmm.;@", + "[$-407]d. mmm. yy;@", + "[$-407]d. mmm yy;@", + "[$-407]mmm. yy;@", + "[$-407]mmmm yy;@", + "[$-407]d. mmmm yyyy;@", + "[$-409]d/m/yy h:mm AM/PM;@", + "d.m.yy h:mm;@", + "[$-407]mmmmm;@", + "[$-407]mmmmm yy;@", + "d.m.yyyy;@", + "[$-407]d. mmm. yyyy;@" + ], + "1032": [ + "yyyy-mm-dd;@", + "d/m;@", + "d/m/yy;@", + "dd/mm/yy;@", + "d/m/yyyy;@", + "[$-408]d-mmm;@", + "[$-408]d-mmm-yy;@", + "[$-408]dd-mmm-yy;@", + "[$-408]mmm-yy;@", + "[$-408]d mmmm yyyy;@", + "[$-408]d/m/yy h:mm AM/PM;@", + "d/m/yy h:mm;@", + "[$-408]mmmmm;@", + "[$-408]mmmmm-yy;@", + "[$-408]d-mmm-yyyy;@" + ], + "1033": [ + "yyyy-mm-dd;@", + "m/d;@", + "m/d/yy;@", + "mm/dd/yy;@", + "[$-409]d-mmm;@", + "[$-409]d-mmm-yy;@", + "[$-409]dd-mmm-yy;@", + "[$-409]mmm-yy;@", + "[$-409]mmmm-yy;@", + "[$-409]mmmm d, yyyy;@", + "[$-409]m/d/yy h:mm AM/PM;@", + "m/d/yy h:mm;@", + "[$-409]mmmmm;@", + "[$-409]mmmmm-yy;@", + "m/d/yyyy;@", + "[$-409]d-mmm-yyyy;@" + ], + "1034": [ + "dd/mm/yyyy;@", + "dd/mm/yy;@", + "d/mm/yy;@", + "d/m/yy;@", + "dd-mm-yy;@", + "dd.mm.yy;@", + "yyyy-mm-dd;@", + "[$-40A]dddd, dd\" de \"mmmm\" de \"yyyy;@", + "[$-40A]dddd d\" de \"mmmm\" de \"yyyy;@", + "[$-40A]d\" de \"mmmm\" de \"yyyy;@" + ], + "1035": [ + "d.m.;@", + "d.m.yy;@", + "d.m.yyyy;@", + "[$-40B]d. mmmmt\\a;@", + "[$-40B]d. mmmmt\\a yy;@", + "[$-40B]d. mmmmt\\a yyyy;@", + "[$-40B]mmmm yy;@", + "[$-40B]mmmm yyyy;@", + "[$-40B]d. mmmmt\\a yyyy h:mm;@", + "d.m.yyyy h:mm;@", + "d.m.yy h:mm;@", + "[$-40B]mmmmm;@", + "[$-40B]mmmmm yy;@", + "yyyy-mm-dd;@", + "yyyy-mm-dd hh:mm;@" + ], + "1036": [ + "yyyy-mm-dd;@", + "d/m;@", + "d/m/yy;@", + "dd/mm/yy;@", + "[$-40C]d-mmm;@", + "[$-40C]d-mmm-yy;@", + "[$-40C]dd-mmm-yy;@", + "[$-40C]mmm-yy;@", + "[$-40C]mmmm-yy;@", + "[$-40C]d mmmm yyyy;@", + "[$-409]d/m/yy h:mm AM/PM;@", + "d/m/yy h:mm;@", + "[$-40C]mmmmm;@", + "[$-40C]mmmmm-yy;@", + "m/d/yyyy;@", + "[$-40C]d-mmm-yyyy;@" + ], + "1037": [ + "yyyy-mm-dd;@", + "[$-1010000]d/m/yy;@", + "[$-1010000]d/m/yyyy;@", + "[$-1010000]d.m.yy;@", + "[$-1010000]d.m.yyyy;@", + "[$-1010000]m/d/yyyy;@", + "[$-1010409]d/m/yyyy h:mm AM/PM;@", + "[$-1010409]d/m/yyyy h:mm;@", + "[$-101040D]d mmm yy;@", + "[$-101040D]d mmmm yyyy;@", + "[$-1010409]d mmm yy;@", + "[$-1010409]d mmmm yyyy;@" + ], + "1038": [ + "m. d.;@", + "yyyy/ m/ d.;@", + "yyyy/mm/dd;@", + "[$-40E]yyyy/ mmm/ d.;@", + "[$-40E]yy/ mmmm d.;@", + "[$-40E]mmmm d.;@", + "[$-40E]yyyy/ mmm.;@", + "[$-40E]yyyy/ mmmm;@", + "[$-40E]yyyy/ mmmm d.;@", + "[$-40E]yyyy/ m/ d. h:mm AM/PM;@", + "yyyy/ m/ d. h:mm;@", + "[$-40E]mmm/ d.;@", + "yyyy-mm-dd;@", + "yyyy mm dd;@", + "yyyy.mm.dd;@", + "[$-40E]mmmmm.;@", + "[$-40E]yy-mmmmm.;@", + "[$-40E]yy/ mmmm;@" + ], + "1039": [ + "d.m.yyyy;@", + "dd.mm.yy;@", + "d. m. yyyy.;@", + "d. m. \"'\"yy.;@", + "yyyy-mm-dd;@", + "yy mm dd;@", + "[$-40F]d. mmmm yyyy;@", + "[$-40F]dd. mmmm yyyy;@" + ], + "1040": [ + "yyyy-mm-dd;@", + "d/m;@", + "d/m/yy;@", + "dd/mm/yy;@", + "[$-410]d-mmm;@", + "[$-410]d-mmm-yy;@", + "[$-410]dd-mmm-yy;@", + "[$-410]mmm-yy;@", + "[$-410]mmmm-yy;@", + "[$-410]d mmmm yyyy;@", + "[$-409]d/m/yy h.mm AM/PM;@", + "d/m/yy h.mm;@", + "[$-410]mmmmm;@", + "[$-410]mmmmm-yy;@", + "d/m/yyyy;@", + "[$-410]d-mmm-yyyy;@" + ], + "1042": [ + "yyyy-mm-dd;@", + "yyyy\"년\" m\"월\" d\"일\";@", + "yy\"年\" m\"月\" d\"日\";@", + "yyyy\"년\" m\"월\";@", + "m\"월\" d\"일\";@", + "yy\"-\"m\"-\"d;@", + "yy\"-\"m\"-\"d h:mm;@", + "[$-412]yy\"-\"m\"-\"d AM/PM h:mm;@", + "[$-409]yy\"-\"m\"-\"d h:mm AM/PM;@", + "yy\"/\"m\"/\"d;@", + "yyyy\"-\"m\"-\"d;@", + "yyyy\"/\"m\"/\"d;@", + "m\"/\"d;@", + "m\"/\"d\"/\"yy;@", + "mm\"/\"dd\"/\"yy;@", + "[$-409]d\"-\"mmm;@", + "[$-409]d\"-\"mmm\"-\"yy;@", + "[$-409]mmm\"-\"yy;@", + "[$-409]mmmm\"-\"yy;@", + "[$-409]mmmmm;@", + "[$-409]mmmmm-yy;@" + ], + "1043": [ + "yyyy-mm-dd;@", + "d-m;@", + "d-mm-yy;@", + "dd-mm-yy;@", + "[$-413]d-mmm;@", + "[$-413]d-mmm-yy;@", + "[$-413]dd-mmm-yy;@", + "[$-413]mmm-yy;@", + "[$-413]mmmm-yy;@", + "[$-413]d mmmm yyyy;@", + "[$-409]d-mm-yy h:mm AM/PM;@", + "d-mm-yy h:mm;@", + "[$-413]mmmmm;@", + "[$-413]mmmmm-yy;@", + "m/d/yyyy;@", + "[$-413]d-mmm-yyyy;@" + ], + "1044": [ + "d/m/;@", + "d/m/yy;@", + "d/m/yyyy;@", + "dd/mm/yy;@", + "dd/mm/yyyy;@", + "[$-414]d/ mmm.;@", + "[$-414]d/ mmmm;@", + "[$-414]d/ mmm. yyyy;@", + "[$-414]d/ mmmm yyyy;@", + "[$-414]mmm. yy;@", + "[$-414]mmmm yy;@", + "[$-414]mmmm yyyy;@", + "yyyy-mm-dd;@", + "dd/mm/yy h:mm;@", + "[$-409]m/d/yy h:mm AM/PM;@", + "m/d/yy h:mm;@" + ], + "1045": [ + "d-mm;@", + "yyyy-mm-dd;@", + "yy-mm-dd;@", + "[$-415]d mmm;@", + "[$-415]d mmm yy;@", + "[$-415]dd mmm yy;@", + "[$-415]mmm yy;@", + "[$-415]mmmm yy;@", + "[$-415]d mmmm yyyy;@", + "[$-409]dd-mm-yy h:mm AM/PM;@", + "dd-mm-yy h:mm;@", + "[$-415]mmmmm;@", + "[$-415]mmmmm.yy;@", + "d-m-yyyy;@", + "[$-415]d-mmm-yyyy;@" + ], + "1046": [ + "yyyy-mm-dd;@", + "d/m;@", + "d/m/yy;@", + "dd/mm/yy;@", + "[$-416]d-mmm;@", + "[$-416]d-mmm-yy;@", + "[$-416]dd-mmm-yy;@", + "[$-416]mmm-yy;@", + "[$-416]mmmm-yy;@", + "[$-416]d;@", + "mmmm, yyyy;@", + "[$-409]d/m/yy h:mm AM/PM;@", + "d/m/yy h:mm;@" + ], + "1047": [ + "yyyy-mm-dd;@", + "[$-10417]dd-mm-yyyy;@", + "[$-10417]dd-mm-yy;@", + "[$-10417]dddd, \"ils’\" d. mmmm, yyyy;@", + "[$-10417]dddd, \"ils\" d mmmm yyyy;@", + "[$-10417]d mmmm yyyy;@" + ], + "1048": [ + "yyyy-mm-dd;@", + "d/m;@", + "d/m/yy;@", + "dd/mm/yy;@", + "[$-418]d-mmm;@", + "[$-418]d-mmm-yy;@", + "[$-418]dd-mmm-yy;@", + "[$-418]mmm-yy;@", + "[$-418]mmmm-yy;@", + "[$-418]d mmmm yyyy;@", + "[$-409]d/m/yy h:mm AM/PM;@", + "d/m/yy h:mm;@", + "[$-418]mmmmm;@", + "[$-418]mmmmm-yy;@", + "d/m/yyyy;@", + "[$-418]d-mmm-yyyy;@" + ], + "1049": [ + "yyyy-mm-dd;@", + "d/m;@", + "d/m/yy;@", + "dd/mm/yy;@", + "[$-419]d mmm;@", + "[$-419]d mmm yy;@", + "[$-419]dd mmm yy;@", + "[$-F419]yyyy, mmmm;@", + "[$-419]mmmm yyyy;@", + "[$-FC19]dd mmmm yyyy г.;@", + "[$-409]dd/mm/yy h:mm AM/PM;@", + "dd/mm/yy h:mm;@", + "[$-419]mmmm;@", + "[$-FC19]yyyy, dd mmmm;@", + "d/m/yyyy;@", + "[$-419]d-mmm-yyyy;@" + ], + "1050": [ + "yyyy-mm-dd;@", + "d.m.;@", + "d.m.yy.;@", + "dd.mm.yy.;@", + "[$-41A]d-mmm;@", + "[$-41A]d-mmm-yy;@", + "[$-41A]dd-mmm-yy;@", + "[$-41A]mmm-yy;@", + "[$-41A]mmmm-yy;@", + "[$-41A]d. mmmm yyyy.;@", + "[$-409]d.m.yy. h:mm AM/PM;@", + "d.m.yy. h:mm;@", + "[$-41A]mmmmm;@", + "[$-41A]mmmmm-yy.;@", + "d.m.yyyy.;@", + "[$-41A]d-mmm-yyyy.;@" + ], + "1051": [ + "yyyy-mm-dd;@", + "d/m;@", + "d/m/yy;@", + "dd/mm/yy;@", + "[$-41B]d-mmm.;@", + "[$-41B]d/mmm/yy;@", + "[$-41B]dd-mmm-yy;@", + "[$-41B]mmm-yy;@", + "[$-41B]mmmm yy;@", + "[$-41B]d. mmmm yyyy;@", + "[$-409]d/m/yy h:mm AM/PM;@", + "d/m/yy h:mm;@", + "[$-41B]mmmmm;@", + "[$-41B]mmmmm-yy;@", + "d/m/yyyy;@", + "[$-41B]d/mmm/yyyy;@" + ], + "1052": [ + "yyyy-mm-dd;@", + "dddd, d mmmm yyyy;@", + "d.m.yyyy;@" + ], + "1053": [ + "yyyy-mm-dd;@", + "yyyy-mm-dd hh:mm;@", + "yy-mm-dd;@", + "yy-mm-dd hh:mm;@", + "d/m yyyy;@", + "d/m -yy;@", + "d/m yy;@", + "d/m/yy;@", + "[$-41D]\"den \" d mmmm yyyy;@", + "[$-41D]d mmmm yyyy;@", + "[$-41D]d mmmm -yy;@", + "[$-41D]mmmmm;@", + "[$-41D]mmmmm-yy;@", + "yyyy mm dd;@", + "[$-41D]mmmm;@", + "[$-41D]dd-mmm;@", + "[$-41D]mmmm yyyy;@", + "[$-41D]mmmm -yy;@", + "[$-41D]mmm-yy;@", + "yyyy;@" + ], + "1054": [ + "[$-1070000]d/m/yy;@", + "[$-1070000]d/mm/yyyy;@", + "[$-1070000]d/mm/yyyy h:mm \"น.\";@", + "[$-1070409]d/mm/yyyy h:mm AM/PM;@", + "[$-D070000]d/m/yy;@", + "[$-D070000]d/mm/yyyy;@", + "[$-D070000]d/mm/yyyy h:mm \"น.\";@", + "[$-D07041E]d mmm yy;@", + "[$-D07041E]d mmmm yyyy;@", + "[$-107041E]d mmm yy;@", + "[$-107041E]d mmmm yyyy;@" + ], + "1055": [ + "yyyy-mm-dd;@", + "d/m;@", + "d/m/yy;@", + "dd/mm/yy;@", + "[$-41F]d mmmm;@", + "[$-41F]d mmmm yy;@", + "[$-41F]dd mmmm yy;@", + "dd/mm/yyyy;@", + "[$-41F]mmmm yy;@", + "[$-41F]d mmmm yyyy;@", + "d/m/yy h:mm;@", + "[$-41F]d mmmm yyyy h:mm;@", + "[$-41F]mmmmm;@", + "[$-41F]mmmmm yy;@", + "m/d/yyyy;@", + "[$-41F]d mmm yyyy;@" + ], + "1056": [ + "dd/mm/yyyy;@", + "dd/mm/yy;@", + "yyyy-mm-dd;@", + "m/d/yyyy;@", + "m/d/yy;@", + "mm/dd/yy;@", + "mm/dd/yyyy;@", + "[$-420]dd mmmm, yyyy;@", + "[$-420]dddd, dd mmmm, yyyy;@", + "[$-420]dddd, mmmm dd, yyyy;@", + "[$-420]mmmm dd, yyyy;@", + "[$-420]dd/mmmm/yyyy;@" + ], + "1057": [ + "dd/mm/yyyy;@", + "dd/mm/yy;@", + "yyyy-mm-dd;@", + "[$-421]dd mmmm yyyy;@" + ], + "1060": [ + "d.m.yyyy;@", + "d.m.yy;@", + "d. m. yyyy;@", + "dd.mm.yyyy;@", + "d. m. yy;@", + "dd.mm.yy;@", + "dd. mm. yy;@", + "yyyy-mm-dd;@", + "[$-424]d. mmmm yyyy;@", + "[$-424]dd. mmmm yyyy;@", + "[$-424]dddd, d. mmmm yyyy;@" + ], + "1061": [ + "d.mm.yyyy;@", + "dd.mm.yyyy;@", + "dd.mm.yy;@", + "yyyy-mm-dd;@", + "[$-425]d. mmmm yyyy\". a.\";@", + "[$-425]dd. mmmm yyyy\". a.\";@", + "[$-425]dddd, d. mmmm yyyy;@" + ], + "1062": [ + "yyyy.mm.dd.;@", + "yy.mm.dd.;@", + "yyyy-mm-dd;@", + "[$-426]dddd, yyyy\". gada \"d. mmmm;@" + ], + "1064": [ + "yyyy-mm-dd;@", + "[$-10428]dd.mm.yyyy;@", + "[$-10428]dd.mm.yy;@", + "[$-10428]d.m.yy;@", + "[$-10428]dd-mm-yyyy;@", + "[$-10428]dd/mm/yy;@", + "[$-10428]d mmmm yyyy\" с.\";@", + "[$-10428]dd mmmm yyyy\" с.\";@", + "[$-10428]dddd, dd mmmm yyyy;@" + ], + "1065": [ + "yyyy-mm-dd;@", + "[$-1010000]dd/m/yyyy;@", + "[$-1010429]dd/m/yyyy hh:mm AM/PM;@", + "[$-1010409]d/m/yyyy hh:mm AM/PM;@", + "[$-3010000]d/mm/yyyy;@", + "[$-3010429]d/mm/yyyy h:mm AM/PM;@" + ], + "1066": [ + "yyyy-mm-dd;@", + "[$-1010000]d/m/yy;@", + "[$-1010000]d/m/yyyy;@", + "[$-101042A]d/m/yyyy h:mm AM/PM;@", + "[$-1010409]d/m/yyyy h:mm AM/PM;@", + "[$-101042A]d mmm yy;@", + "[$-101042A]d mmmm yyyy;@", + "[$-101040C]d mmm yy;@", + "[$-101040C]d mmmm yyyy;@", + "[$-1010409]d mmm yy;@", + "[$-1010409]d mmmm yyyy;@" + ], + "1067": [ + "dd.mm.yyyy;@", + "dd.mm.yy;@", + "d/mm/yyyy;@", + "dd/mm/yyyy;@", + "[$-42B]d/mmm/yyyy;@", + "[$-42B]dd/mmm/yyyy;@", + "yyyy-mm-dd;@", + "[$-42B]d mmmm, yyyy;@", + "[$-42B]dddd, d mmmm yyyy;@", + "[$-42B]dddd, dd mmmm yyyy;@", + "[$-42B]dd mmmm yyyy;@", + "[$-42B]d-mmm-yyyy;@", + "[$-42B]dd-mmm-yyyy;@", + "[$-42B]ddd, d-mmmm-yyyy;@", + "[$-42B]ddd, dd-mmmm-yyyy;@" + ], + "1068": [ + "dd.mm.yyyy;@", + "dd.mm.yy;@", + "d.m.yy;@", + "dd/mm/yy;@", + "yyyy-mm-dd;@", + "[$-42C]d mmmm yyyy;@", + "[$-42C]dd mmmm yyyy;@" + ], + "1069": [ + "yyyy-mm-dd;@", + "m/d;@", + "yy/m/d;@", + "yy/mm/dd;@", + "[$-42D]mmm-d;@", + "[$-42D]yy-mmm-d;@", + "[$-42D]yy-mmm-dd;@", + "[$-42D]yy-mmm;@", + "[$-42D]yy-mmmm;@", + "[$-42D]yyyy\"(e)ko\" mmmm\"ren\" d\"(a)\";@", + "[$-42D]yy/mm/dd/ h:mm AM/PM;@", + "yy/m/d/ h:mm;@", + "[$-42D]mmmmm;@", + "[$-42D]yy-mmmmm;@", + "yyyy/m/d;@", + "[$-42D]yyyy-mmm-d;@", + "yyyy.mm.dd;@", + "[$-42D]yyyy\"(e)ko\" mmmm\"ren\" d\"(a)\";@", + "[$-42D]yyyy\"(e)ko\" mmmm\"k\" d\"(a)\";@", + "[$-42D]yyyy\"(e)ko\" mmmm;@" + ], + "1070": [ + "yyyy-mm-dd;@", + "[$-1042E]d.m.yyyy;@", + "[$-1042E]d.m.yy;@", + "[$-1042E]dddd, d. mmmm yyyy;@", + "[$-1042E]d. mmmm yyyy;@" + ], + "1071": [ + "dd.mm.yyyy;@", + "dd.mm.yy;@", + "yyyy-mm-dd;@", + "[$-42F]dddd, dd mmmm yyyy;@" + ], + "1072": [ + "[$-10430]yyyy-mm-dd;@", + "[$-10430]yyyy mmm d;@", + "[$-10430]yyyy mmmm d, dddd;@", + "[$-10430]yyyy mmmm d;@" + ], + "1073": [ + "[$-10431]yyyy-mm-dd;@", + "[$-10431]yyyy mmm d;@", + "[$-10431]yyyy mmmm d, dddd;@", + "[$-10431]yyyy mmmm d;@" + ], + "1074": [ + "[$-10432]yyyy-mm-dd;@", + "[$-10432]yyyy mmm d;@", + "[$-10432]dd mmmm yyyy;@", + "[$-10432]yyyy mmmm d, dddd;@", + "[$-10432]yyyy mmmm d;@" + ], + "1075": [ + "[$-10433]yyyy-mm-dd;@", + "[$-10433]yyyy mmm d;@", + "[$-10433]yyyy mmmm d, dddd;@", + "[$-10433]yyyy mmmm d;@" + ], + "1076": [ + "[$-10434]yyyy-mm-dd;@", + "[$-10434]yyyy mmm d;@", + "[$-10434]yyyy mmmm d, dddd;@", + "[$-10434]yyyy mmmm d;@" + ], + "1077": [ + "yyyy-mm-dd;@", + "[$-10435]m/d/yyyy;@", + "[$-10435]m/d/yy;@", + "[$-10435]mmm d, yyyy;@", + "[$-10435]dddd, mmmm d, yyyy;@", + "[$-10435]mmmm d, yyyy;@" + ], + "1078": [ + "yyyy/mm/dd;@", + "yy/mm/dd;@", + "yyyy-mm-dd;@", + "[$-436]dd mmmm yyyy;@" + ], + "1079": [ + "dd.mm.yyyy;@", + "dd.mm.yy;@", + "d.m.yy;@", + "dd/mm/yy;@", + "yyyy-mm-dd;@", + "[$-437]dddd, d mmmm, yyyy \"წელი\";@" + ], + "1080": [ + "dd-mm-yyyy;@", + "dd-mm-yy;@", + "yyyy-mm-dd;@", + "[$-438]d. mmmm yyyy;@" + ], + "1081": [ + "yyyy-mm-dd;@", + "[$-4010000]d/m/yy;@", + "[$-4010000]d/m/yyyy;@", + "[$-4010439]d/m/yyyy h:mm AM/PM;@", + "[$-4010409]d/m/yyyy h:mm AM/PM;@", + "[$-1010000]d/m/yy;@", + "[$-1010000]d/m/yyyy;@", + "[$-1010439]d/m/yyyy h:mm AM/PM;@", + "[$-1010409]d/m/yyyy h:mm AM/PM;@", + "[$-1010439]d mmm yy;@", + "[$-1010439]d mmmm yyyy;@", + "[$-4010439]d mmm yy;@", + "[$-4010439]d mmmm yyyy;@", + "[$-1010409]d mmm yy;@", + "[$-1010409]d mmmm yyyy;@" + ], + "1082": [ + "yyyy-mm-dd;@", + "[$-1043A]dd/mm/yyyy;@", + "[$-1043A]dd mmm yyyy;@", + "[$-1043A]dddd, d \"ta\"’ mmmm yyyy;@", + "[$-1043A]d \"ta\"’ mmmm yyyy;@" + ], + "1083": [ + "[$-1043B]yyyy-mm-dd;@", + "[$-1043B]yyyy mmm d;@", + "[$-1043B]dddd, mmmm d\". b. \"yyyy;@", + "[$-1043B]yyyy mmmm d, dddd;@", + "[$-1043B]yyyy mmmm d;@" + ], + "1085": [ + "yyyy-mm-dd;@", + "[$-1043D]dd/mm/yyyy;@", + "[$-1043D]dd/mm/yy;@", + "[$-1043D]dטן mmm yyyy;@", + "[$-1043D]dddd, dטן mmmm yyyy;@", + "[$-1043D]dטן mmmm yyyy;@" + ], + "1086": [ + "dd/mm/yyyy;@", + "dd/mm/yy;@", + "yyyy-mm-dd;@", + "[$-43E]dd mmmm yyyy;@" + ], + "1087": [ + "dd.mm.yyyy;@", + "dd.mm.yy;@", + "d.m.yy;@", + "dd/mm/yy;@", + "yyyy-mm-dd;@", + "[$-43F]d mmmm yyyy \"ж.\";@", + "[$-43F]dd mmmm yyyy \"ж.\";@" + ], + "1088": [ + "yyyy-mm-dd;@", + "dd.mm.yy;@", + "[$-440]d\"-\"mmmm yyyy\"-ж.\";@" + ], + "1089": [ + "m/d/yyyy;@", + "m/d/yy;@", + "mm/dd/yy;@", + "mm/dd/yyyy;@", + "yy/mm/dd;@", + "yyyy-mm-dd;@", + "[$-441]dd-mmm-yy;@", + "[$-441]dddd, mmmm dd, yyyy;@", + "[$-441]mmmm dd, yyyy;@", + "[$-441]dddd, dd mmmm, yyyy;@", + "[$-441]dd mmmm, yyyy;@" + ], + "1090": [ + "yyyy-mm-dd;@", + "[$-10442]dd.mm.yy \"ý.\";@", + "[$-10442]dd.mm.yyyy;@", + "[$-10442]yyyy\"-nji ýylyň \"d\"-nji \"mmmm;@", + "[$-10442]d mmmm yyyy dddd;@" + ], + "1091": [ + "dd/mm yyyy;@", + "dd.mm.yy;@", + "d.m.yy;@", + "dd/mm/yy;@", + "yyyy-mm-dd;@", + "[$-443]yyyy \"yil\" d-mmmm;@", + "[$-443]d mmmm yyyy;@", + "[$-443]dd mmmm yyyy;@" + ], + "1092": [ + "dd.mm.yyyy;@", + "dd.mm.yy;@", + "d.m.yy;@", + "dd/mm/yy;@", + "yyyy-mm-dd;@", + "[$-444]d mmmm yyyy;@", + "[$-444]dd mmmm yyyy;@" + ], + "1093": [ + "dd-mm-yyyy;@", + "dd-mm-yy;@", + "d-m-yy;@", + "d.m.yy;@", + "yyyy-mm-dd;@", + "[$-445]dd mmmm yyyy;@", + "[$-445]d mmmm yyyy;@", + "[$-5000445]dd-mm-yyyy;@", + "[$-5000445]dd-mm-yy;@", + "[$-5000445]d-m-yy;@", + "[$-5000445]d.m.yy;@", + "[$-5000445]yyyy-mm-dd;@", + "[$-5000445]dd mmmm yyyy;@", + "[$-5000445]d mmmm yyyy;@" + ], + "1094": [ + "dd-mm-yy;@", + "d-m-yy;@", + "d.m.yy;@", + "dd-mm-yyyy;@", + "yyyy-mm-dd;@", + "[$-446]dd mmmm yyyy dddd;@", + "[$-446]d mmmm yyyy;@", + "[$-6000446]dd-mm-yy;@", + "[$-6000446]d-m-yy;@", + "[$-6000446]d.m.yy;@", + "[$-6000446]dd-mm-yyyy;@", + "[$-6000446]yyyy-mm-dd;@", + "[$-6000446]dd mmmm yyyy dddd;@", + "[$-6000446]d mmmm yyyy;@" + ], + "1095": [ + "dd-mm-yy;@", + "d-m-yy;@", + "d.m.yy;@", + "dd-mm-yyyy;@", + "yyyy-mm-dd;@", + "[$-447]dd mmmm yyyy;@", + "[$-447]d mmmm yyyy;@", + "[$-7000447]dd-mm-yy;@", + "[$-7000447]d-m-yy;@", + "[$-7000447]d.m.yy;@", + "[$-7000447]dd-mm-yyyy;@", + "[$-7000447]yyyy-mm-dd;@", + "[$-7000447]dd mmmm yyyy;@", + "[$-7000447]d mmmm yyyy;@" + ], + "1096": [ + "[$-10448]dd-mm-yy;@", + "[$-10448]d-m-yy;@", + "[$-10448]d.m.yy;@", + "[$-10448]dd-mm-yyyy;@", + "[$-10448]yyyy-mm-dd;@", + "[$-10448]dd mmmm yyyy;@", + "[$-10448]d mmmm yyyy;@", + "[$-10448]dddd, mmmm d, yyyy;@" + ], + "1097": [ + "dd-mm-yyyy;@", + "dd-mm-yy;@", + "d-m-yy;@", + "d.m.yy;@", + "yyyy-mm-dd;@", + "[$-449]dd mmmm yyyy;@", + "[$-449]d mmmm yyyy;@", + "[$-9000449]dd-mm-yyyy;@", + "[$-9000449]dd-mm-yy;@", + "[$-9000449]d-m-yy;@", + "[$-9000449]d.m.yy;@", + "[$-9000449]yyyy-mm-dd;@", + "[$-9000449]dd mmmm yyyy;@", + "[$-9000449]d mmmm yyyy;@" + ], + "1098": [ + "dd-mm-yy;@", + "d-m-yy;@", + "d.m.yy;@", + "dd-mm-yyyy;@", + "yyyy-mm-dd;@", + "[$-44A]dd mmmm yyyy;@", + "[$-44A]d mmmm yyyy;@", + "[$-A00044A]dd-mm-yy;@", + "[$-A00044A]d-m-yy;@", + "[$-A00044A]d.m.yy;@", + "[$-A00044A]dd-mm-yyyy;@", + "[$-A00044A]yyyy-mm-dd;@", + "[$-A00044A]dd mmmm yyyy;@", + "[$-A00044A]d mmmm yyyy;@" + ], + "1099": [ + "dd-mm-yy;@", + "d-m-yy;@", + "d.m.yy;@", + "dd-mm-yyyy;@", + "yyyy-mm-dd;@", + "[$-44B]dd mmmm yyyy;@", + "[$-44B]d mmmm yyyy;@" + ], + "1100": [ + "dd-mm-yyyy;@", + "dd-mm-yy;@", + "d-m-yy;@", + "d.m.yy;@", + "yyyy-mm-dd;@", + "[$-44C]dd mmmm yyyy;@", + "[$-44C]d mmmm yyyy;@", + "[$-C00044C]dd-mm-yyyy;@", + "[$-C00044C]dd-mm-yy;@", + "[$-C00044C]d-m-yy;@", + "[$-C00044C]d.m.yy;@", + "[$-C00044C]yyyy-mm-dd;@", + "[$-C00044C]dd mmmm yyyy;@", + "[$-C00044C]d mmmm yyyy;@" + ], + "1101": [ + "yyyy-mm-dd;@", + "[$-1044D]dd-mm-yyyy;@", + "[$-1044D]yyyy,mmmm dd, dddd;@" + ], + "1102": [ + "dd-mm-yyyy;@", + "dd-mm-yy;@", + "d-m-yy;@", + "d.m.yy;@", + "yyyy-mm-dd;@", + "[$-44E]dd mmmm yyyy;@", + "[$-44E]d mmmm yyyy;@" + ], + "1103": [ + "dd-mm-yyyy;@", + "dd-mm-yy;@", + "d-m-yy;@", + "d.m.yy;@", + "yyyy-mm-dd;@", + "[$-44F]dd mmmm yyyy dddd;@", + "[$-44F]d mmmm yyyy;@" + ], + "1104": [ + "yyyy-mm-dd;@", + "yy.mm.dd;@", + "[$-450]yyyy \"оны\" mmmm d;@" + ], + "1105": [ + "[$-10451]yyyy/m/d;@", + "[$-10451]yyyy-m-d;@", + "[$-10451]yyyy.m.d;@", + "[$-10451]yyyy.mm.dd;@", + "[$-10451]yyyy-mm-dd;@", + "[$-10451]yyyy/mm/dd;@", + "[$-10451]yy-m-d;@", + "[$-10451]yy/m/d;@", + "[$-10451]yy.m.d;@", + "[$-10451]yyyy\"ལོའི་ཟླ\" m\"ཚེས\" d;@", + "[$-10451]yyyy\"ལོའི་ཟླ\" m\"ཚེས\" d dddd;@", + "[$-10451]yyyyལོའི་ཟླ mmm d;@", + "[$-10451]yyyyལོའི་ཟླ mmm d dddd;@" + ], + "1106": [ + "yyyy-mm-dd;@", + "[$-10452]dd/mm/yyyy;@", + "[$-10452]dd/mm/yy;@", + "[$-10452]d mmm yyyy;@", + "[$-10452]dddd, d mmmm yyyy;@", + "[$-10452]d mmmm yyyy;@" + ], + "1107": [ + "[$-10453]dd/mm/yy;@", + "[$-10453]yyyy-mm-dd;@", + "[$-10453]d mmmm yyyy;@", + "[$-10453]ddd d mmmm yyyy;@", + "[$-10453]dddd d mmmm yyyy;@" + ], + "1108": [ + "yyyy-mm-dd;@", + "[$-10454]d/m/yyyy;@", + "[$-10454]d mmm yyyy;@", + "[$-10454]dddd ທີ d mmmm gg yyyy;@", + "[$-10454]d mmmm yyyy;@" + ], + "1109": [ + "yyyy-mm-dd;@", + "[$-10455]dd-mm-yyyy;@", + "[$-10455]dd-mm-yy;@", + "[$-10455]yyyy၊ mmm d;@", + "[$-10455]yyyy၊ mmmm d၊ dddd;@", + "[$-10455]yyyy၊ d mmmm;@" + ], + "1110": [ + "yyyy-mm-dd;@", + "dd/mm/yy;@", + "d/mm/yy;@", + "d/m/yy;@", + "dd-mm-yy;@", + "dd.mm.yy;@", + "dd/mm/yyyy;@", + "[$-456]dddd, dd\" de \"mmmm\" de \"yyyy;@", + "[$-456]dddd d\" de \"mmmm\" de \"yyyy;@", + "[$-456]d\" de \"mmmm\" de \"yyyy;@" + ], + "1111": [ + "dd-mm-yyyy;@", + "dd-mm-yy;@", + "d-m-yy;@", + "d.m.yy;@", + "yyyy-mm-dd;@", + "[$-457]dd mmmm yyyy;@", + "[$-457]d mmmm yyyy;@" + ], + "1112": [ + "yyyy-mm-dd;@", + "[$-10458]d/m/yyyy;@", + "[$-10458]d/m/yy;@", + "[$-10458]mmm d, yyyy;@", + "[$-10458]mmmm d, yyyy, dddd;@", + "[$-10458]mmmm d, yyyy;@" + ], + "1113": [ + "yyyy-mm-dd;@", + "[$-10459]d/m/yyyy;@", + "[$-10459]d/m/yy;@", + "[$-10459]d mmm yyyy;@", + "[$-10459]dddd, d mmmm yyyy;@", + "[$-10459]d mmmm yyyy;@" + ], + "1114": [ + "dd/mm/yyyy;@", + "dd/mm/yy;@", + "yyyy-mm-dd;@", + "[$-45A]dd mmmm, yyyy;@", + "[$-45A]dddd, dd mmmm, yyyy;@" + ], + "1115": [ + "[$-1045B]yyyy-mm-dd;@", + "[$-1045B]yyyy mmm d;@", + "[$-1045B]yyyy mmmm d, dddd;@", + "[$-1045B]yyyy mmmm d;@" + ], + "1116": [ + "[$-1045C]m/d/yyyy;@", + "[$-1045C]m/d/yy;@", + "[$-1045C]mm/dd/yy;@", + "[$-1045C]mm/dd/yyyy;@", + "[$-1045C]yy/mm/dd;@", + "[$-1045C]yyyy-mm-dd;@", + "[$-1045C]dd-mmm-yy;@", + "[$-1045C]dddd, mmmm dd,yyyy;@", + "[$-1045C]mmmm dd,yyyy;@", + "[$-1045C]dddd, dd mmmm, yyyy;@", + "[$-1045C]dd mmmm, yyyy;@" + ], + "1117": [ + "[$-1045D]d/m/yyyy;@", + "[$-1045D]d/m/yy;@", + "[$-1045D]dd/mm/yy;@", + "[$-1045D]yy/mm/dd;@", + "[$-1045D]yyyy-mm-dd;@", + "[$-1045D]dd-mmm-yy;@", + "[$-1045D]dddd,mmmm dd,yyyy;@", + "[$-1045D]mmmm dd,yyyy;@", + "[$-1045D]dddd, dd mmmm, yyyy;@", + "[$-1045D]dd mmmm, yyyy;@" + ], + "1118": [ + "yyyy-mm-dd;@", + "[$-1045E]dd/mm/yyyy;@", + "[$-1045E]d mmm yyyy;@", + "[$-1045E]yyyy mmmm d, dddd;@", + "[$-1045E]d mmmm yyyy;@" + ], + "1119": [ + "yyyy-mm-dd;@", + "[$-1045F]d/m/yyyy;@", + "[$-1045F]dd/mm/yyyy;@", + "[$-1045F]dddd، d mmmm yyyy;@", + "[$-1045F]d mmmm yyyy;@" + ], + "1120": [ + "yyyy-mm-dd;@", + "[$-10460]m/d/yyyy;@", + "[$-10460]m/d/yy;@", + "[$-10460]mmm d, yyyy;@", + "[$-10460]dddd, mmmm d, yyyy;@", + "[$-10460]mmmm d, yyyy;@" + ], + "1121": [ + "[$-10461]m/d/yyyy;@", + "[$-10461]m/d/yy;@", + "[$-10461]mm/dd/yy;@", + "[$-10461]mm/dd/yyyy;@", + "[$-10461]yy/mm/dd;@", + "[$-10461]yyyy-mm-dd;@", + "[$-10461]dd-mmm-yy;@", + "[$-10461]dddd, mmmm dd, yyyy;@", + "[$-10461]mmmm dd, yyyy;@", + "[$-10461]dddd, dd mmmm, yyyy;@", + "[$-10461]dd mmmm, yyyy;@" + ], + "1122": [ + "yyyy-mm-dd;@", + "[$-10462]dd-mm-yyyy;@", + "[$-10462]dd-mm-yy;@", + "[$-10462]d mmm yyyy;@", + "[$-10462]dddd d mmmm yyyy;@", + "[$-10462]d mmmm yyyy;@" + ], + "1123": [ + "[$-160463]yyyy/m/d;@", + "[$-160463]yyyy-mm-dd;@", + "[$-160463]d mmmm yyyy;@", + "[$-160463]dddd d mmmm yyyy;@" + ], + "1124": [ + "yyyy-mm-dd;@", + "[$-10464]m/d/yyyy;@", + "[$-10464]m/d/yy;@", + "[$-10464]mmm d, yyyy;@", + "[$-10464]dddd, mmmm d, yyyy;@", + "[$-10464]mmmm d, yyyy;@" + ], + "1125": [ + "yyyy-mm-dd;@", + "[$-1010000]dd/mm/yy;@", + "[$-1010000]dd/mm/yyyy;@", + "[$-1010000]dd mm yyyy;@", + "[$-1010465]dd mmm yyyy;@", + "[$-1010465]dd mmmm yyyy;@", + "[$-1010465]ddd, dd mmmm yyyy;@", + "[$-1010465]ddd, dd mmm yyyy;@", + "[$-1010465]dddd, dd mmm yyyy;@", + "[$-1010465]dddd, dd mmmm yyyy;@" + ], + "1126": [ + "yyyy-mm-dd;@", + "[$-10466]d/m/yyyy;@", + "[$-10466]d mmm yyyy;@", + "[$-10466]dddd, mmmm dd, yyyy;@", + "[$-10466]mmmm dd, yyyy;@" + ], + "1127": [ + "yyyy-mm-dd;@", + "[$-10467]d/m/yyyy;@", + "[$-10467]d mmm, yyyy;@", + "[$-10467]dddd d mmmm yyyy;@", + "[$-10467]d mmmm yyyy;@" + ], + "1128": [ + "yyyy-mm-dd;@", + "[$-10468]d/m/yyyy;@", + "[$-10468]d/m/yy;@", + "[$-10468]d mmm, yyyy;@", + "[$-10468]dddd d mmmm, yyyy;@", + "[$-10468]d mmmm, yyyy;@" + ], + "1129": [ + "yyyy-mm-dd;@", + "[$-10469]d/m/yyyy;@", + "[$-10469]d mmm yyyy;@", + "[$-10469]dddd, mmmm dd, yyyy;@", + "[$-10469]mmmm dd, yyyy;@" + ], + "1130": [ + "yyyy-mm-dd;@", + "[$-1046A]d/m/yyyy;@", + "[$-1046A]d mm yyyy;@", + "[$-1046A]dddd, d mmm yyyy;@", + "[$-1046A]d mmm yyyy;@" + ], + "1131": [ + "[$-1046B]dd/mm/yyyy;@", + "[$-1046B]dd/mm/yy;@", + "[$-1046B]d/m/yy;@", + "[$-1046B]dd-mm-yy;@", + "[$-1046B]yyyy-mm-dd;@", + "[$-1046B]dddd, dd\" de \"mmmm\" de \"yyyy;@", + "[$-1046B]dddd d\" de \"mmmm\" de \"yyyy;@", + "[$-1046B]d\" de \"mmmm\" de \"yyyy;@" + ], + "1132": [ + "[$-1046C]yyyy-mm-dd;@", + "[$-1046C]yyyy mmm d;@", + "[$-1046C]yyyy mmmm d, dddd;@", + "[$-1046C]yyyy mmmm d;@" + ], + "1133": [ + "[$-1046D]dd.mm.yy;@", + "[$-1046D]yyyy-mm-dd;@", + "[$-1046D]d mmmm yyyy \"й\";@", + "[$-1046D]dddd mmmm yyyy \"й\";@" + ], + "1134": [ + "yyyy-mm-dd;@", + "[$-1046E]dd.mm.yy;@", + "[$-1046E]dd/mm/yy;@", + "[$-1046E]dd-mm-yy;@", + "[$-1046E]d. mmmm yyyy;@", + "[$-1046E]dd. mmmmyyyy;@", + "[$-1046E]dddd, d. mmmm yyyy;@", + "[$-1046E]dddd, dd. mmmm yyyy;@", + "[$-1046E]dddd,\" den \"d. mmmm yyyy;@", + "[$-1046E]dddd,\" den \"dd. mmmm yyyy;@" + ], + "1135": [ + "[$-1046F]dd-mm-yyyy;@", + "[$-1046F]dd-mm-yy;@", + "[$-1046F]yyyy-mm-dd;@", + "[$-1046F]yyyy mm dd;@", + "[$-1046F]mmmm d\".-at, \"yyyy;@", + "[$-1046F]d. mmmm yyyy;@", + "[$-1046F]dd. mmmm yyyy;@", + "[$-1046F]dddd dd mmmm yyyy;@" + ], + "1136": [ + "yyyy-mm-dd;@", + "[$-10470]d/m/yyyy;@", + "[$-10470]d/m/yy;@", + "[$-10470]d mmm yyyy;@", + "[$-10470]dddd, d mmmm yyyy;@", + "[$-10470]d mmmm yyyy;@" + ], + "1137": [ + "yyyy-mm-dd;@", + "[$-10471]d/m/yyyy;@", + "[$-10471]mmm d, yyyy;@", + "[$-10471]dddd, mmmm dd, yyyy;@", + "[$-10471]mmmm dd, yyyy;@" + ], + "1138": [ + "yyyy-mm-dd;@", + "[$-10472]dd/mm/yyyy;@", + "[$-10472]dd/mm/yy;@", + "[$-10472]dd-mmm-yyyy;@", + "[$-10472]dddd, mmmm d, yyyy;@", + "[$-10472]dd mmmm yyyy;@" + ], + "1139": [ + "yyyy-mm-dd;@", + "[$-10473]d/m/yyyy;@", + "[$-10473]dd/mm/yyyy;@", + "[$-10473]dd/mm/yy;@", + "[$-10473]dd-mmm-yyyy;@", + "[$-10473]dddd \"፣\" mmmm d \"መዓልቲ\" yyyy;@", + "[$-10473]dddd\\፣ dd mmmm መዓልቲ yyyy gg;@", + "[$-10473]dd mmmm yyyy;@" + ], + "1140": [ + "yyyy-mm-dd;@", + "[$-10474]dd/mm/yyyy;@", + "[$-10474]dd/mm/yy;@", + "[$-10474]dd-mm-yyyy;@", + "[$-10474]dd-mm-yy;@", + "[$-10474]dddd, dd mmmm, yyyy;@", + "[$-10474]dddd, d mmmm, yyyy;@", + "[$-10474]dd/mmmm/yyyy;@", + "[$-10474]d/mmmm/yyyy;@", + "[$-10474]dd mmmm, yyyy;@", + "[$-10474]d mmmm, yyyy;@" + ], + "1141": [ + "yyyy-mm-dd;@", + "[$-10475]d/m/yyyy;@", + "[$-10475]d/m/yy;@", + "[$-10475]d mmm yyyy;@", + "[$-10475]dddd, d mmmm yyyy;@", + "[$-10475]d mmmm yyyy;@" + ], + "1142": [ + "yyyy-mm-dd;@", + "[$-10476]d m yyyy gg;@", + "[$-10476]\"die\" d mmm yyyy gg;@", + "[$-10476]dddd, \"die\" d mmmm yyyy gg;@", + "[$-10476]\"die\" d mmmm yyyy gg;@" + ], + "1143": [ + "yyyy-mm-dd;@", + "[$-10477]dd/mm/yyyy;@", + "[$-10477]dd/mm/yy;@", + "[$-10477]dd-mmm-yyyy;@", + "[$-10477]dddd, mmmm dd, yyyy;@", + "[$-10477]dd mmmm yyyy;@" + ], + "1144": [ + "[$-10478]yyyy/m/d;@", + "[$-10478]yyyy-m-d;@", + "[$-10478]yyyy.m.d;@", + "[$-10478]yyyy.mm.dd;@", + "[$-10478]yyyy-mm-dd;@", + "[$-10478]yyyy/mm/dd;@", + "[$-10478]yyyy\"ꈎ\" m\"ꆪ\" d\"ꑍ\";@", + "[$-10478]dddd, yyyy\"ꈎ\" m\"ꆪ\" d\"ꑍ\";@", + "[$-10478]yyyy\"ꈎ\" m\"ꆪ\" d\"ꑍ\", dddd;@", + "[$-10478]yyyyꈎ mmm dꑍ;@", + "[$-10478]dddd, yyyyꈎ mmm dꑍ;@" + ], + "1145": [ + "yyyy-mm-dd;@", + "[$-10479]d-m-yyyy;@", + "[$-10479]d mmm yyyy;@", + "[$-10479]d mmm yy;@", + "[$-10479]dddd d mmmm yyyy;@", + "[$-10479]d mmmm yyyy;@" + ], + "1146": [ + "[$-1047A]dd-mm-yyyy;@", + "[$-1047A]dd-mm-yy;@", + "[$-1047A]dd/mm/yy;@", + "[$-1047A]d/m/yy;@", + "[$-1047A]yyyy-mm-dd;@", + "[$-1047A]dddd, dd\" de \"mmmm\" de \"yyyy;@", + "[$-1047A]dddd d\" de \"mmmm\" de \"yyyy;@", + "[$-1047A]d\" de \"mmmm\" de \"yyyy;@" + ], + "1148": [ + "[$-1047C]m/d/yyyy;@", + "[$-1047C]m/d/yy;@", + "[$-1047C]mm/dd/yy;@", + "[$-1047C]mm/dd/yyyy;@", + "[$-1047C]yy/mm/dd;@", + "[$-1047C]yyyy-mm-dd;@", + "[$-1047C]dd-mmm-yy;@", + "[$-1047C]dddd, mmmm dd, yyyy;@", + "[$-1047C]mmmm dd, yyyy;@", + "[$-1047C]dddd, dd mmmm, yyyy;@", + "[$-1047C]dd mmmm, yyyy;@" + ], + "1150": [ + "yyyy-mm-dd;@", + "[$-1047E]dd/mm/yyyy;@", + "[$-1047E]d mmm yyyy;@", + "[$-1047E]dddd d mmmm yyyy;@", + "[$-1047E]d mmmm yyyy;@" + ], + "1152": [ + "[$-10480]yyyy-m-d;@", + "[$-10480]yyyy.m.d;@", + "[$-10480]yyyy-mm-dd;@", + "[$-10480]yyyy.mm.dd;@", + "[$-10480]yyyy-\"يىل\" d-mmmm;@", + "[$-10480]yyyy-\"يىل\" d-mmmm dddd;@", + "[$-10480]yyyy-\"يىلى\" mmm\"نىڭ\" d\"-كۈنى\";@", + "[$-10480]yyyy-\"يىلى\" mmm\"نىڭ\" d\"-كۈنى\" dddd;@", + "[$-10480]yyyy-m-d dddd;@" + ], + "1153": [ + "yyyy-mm-dd;@", + "[$-10481]dd-mm-yyyy;@", + "[$-10481]d mmm yyyy;@", + "[$-10481]dddd, d mmmm yyyy;@", + "[$-10481]d mmmm yyyy;@" + ], + "1154": [ + "yyyy-mm-dd;@", + "[$-10482]d/mm/yyyy;@", + "[$-10482]d/mm/yy;@", + "[$-10482]d mmm yyyy;@", + "[$-10482]dddd d mmmm\" de \"yyyy;@", + "[$-10482]dddd d mmmm \"de\" yyyy;@", + "[$-10482]d mmmm \"de\" yyyy;@" + ], + "1155": [ + "yyyy-mm-dd;@", + "[$-10483]dd/mm/yyyy;@", + "[$-10483]dd/mm/yy;@", + "[$-10483]dddd d mmmm yyyy;@", + "[$-10483]d mmm yy;@", + "[$-10483]d mmmm yyyy;@" + ], + "1156": [ + "[$-10484]dd/mm/yyyy;@", + "[$-10484]dd/mm/yy;@", + "[$-10484]dd.mm.yy;@", + "[$-10484]dd-mm-yy;@", + "[$-10484]yyyy-mm-dd;@", + "[$-10484]dddd d mmmm yyyy;@", + "[$-10484]d mmm yy;@", + "[$-10484]d mmmm yyyy;@" + ], + "1157": [ + "[$-10485]dd.mm.yyyy;@", + "[$-10485]d.m.yyyy;@", + "[$-10485]yyyy-mm-dd;@", + "[$-10485]yyyy mm d;@", + "[$-10485]dd yyyy mm d;@", + "[$-10485]dddd, yyyy \"с.\" mmmm d \"күнэ\";@", + "[$-10485]yyyy \"с.\" mmmm d \"күнэ\";@", + "[$-10485]dddd, mmmm d \"күнэ\" yyyy \"с.\";@" + ], + "1158": [ + "yyyy-mm-dd;@", + "[$-10486]dd/mm/yyyy;@", + "[$-10486]d/mm/yyyy;@", + "[$-10486]dddd, dd\" rech \"mmmm\" rech \"yyyy;@", + "[$-10486]dddd d\" de \"mmmm\" de \"yyyy;@", + "[$-10486]d\" de \"mmmm\" de \"yyyy;@" + ], + "1159": [ + "[$-10487]yyyy-mm-dd;@", + "[$-10487]yyyy mmm d;@", + "[$-10487]yyyy mmmm d, dddd;@", + "[$-10487]yyyy mmmm d;@" + ], + "1160": [ + "yyyy-mm-dd;@", + "[$-10488]dd-mm-yyyy;@", + "[$-10488]d mmm, yyyy;@", + "[$-10488]dddd, d mmm, yyyy;@", + "[$-10488]d mmmm, yyyy;@" + ], + "1164": [ + "[$-16048C]yyyy/m/d;@", + "[$-16048C]yyyy-mm-dd;@", + "[$-16048C]dddd, d mmmm yyyy;@", + "[$-16048C]d mmmm yyyy;@" + ], + "1169": [ + "yyyy-mm-dd;@", + "[$-10491]dd/mm/yyyy;@", + "[$-10491]d mmm yyyy;@", + "[$-10491]dd mmmm yyyy;@", + "[$-10491]dddd, d\"mh\" mmmm yyyy;@", + "[$-10491]d\"mh\" mmmm yyyy;@" + ], + "2052": [ + "yyyy-mm-dd;@", + "[DBNum1][$-804]yyyy\"年\"m\"月\"d\"日\";@", + "[DBNum1][$-804]yyyy\"年\"m\"月\";@", + "[DBNum1][$-804]m\"月\"d\"日\";@", + "yyyy\"年\"m\"月\"d\"日\";@", + "yyyy\"年\"m\"月\";@", + "m\"月\"d\"日\";@", + "[$-804]aaaa;@", + "[$-804]aaa;@", + "yyyy/m/d;@", + "[$-409]yyyy/m/d h:mm AM/PM;@", + "yyyy/m/d h:mm;@", + "yy/m/d;@", + "m/d;@", + "m/d/yy;@", + "mm/dd/yy;@", + "[$-409]d-mmm;@", + "[$-409]d-mmm-yy;@", + "[$-409]dd-mmm-yy;@", + "[$-409]mmm-yy;@", + "[$-409]mmmm-yy;@", + "[$-409]mmmmm;@", + "[$-409]mmmmm-yy;@" + ], + "2055": [ + "dd.mm.yyyy;@", + "dd.mm.yy;@", + "d.mm.yy;@", + "dd. m. yy;@", + "d.m.yy;@", + "dd.mm.yyyy;@", + "yyyy-mm-dd;@", + "[$-807]dddd, d. mmmm yyyy;@", + "[$-807]d. mmmm yyyy;@", + "[$-807]d. mmm yy;@" + ], + "2057": [ + "dd/mm/yyyy;@", + "dd/mm/yy;@", + "d/m/yy;@", + "d.m.yy;@", + "yyyy-mm-dd;@", + "[$-809]dd mmmm yyyy;@", + "[$-809]d mmmm yyyy;@" + ], + "2058": [ + "dd/mm/yyyy;@", + "dd/mm/yy;@", + "d/mm/yy;@", + "d/m/yy;@", + "dd-mm-yy;@", + "yyyy-mm-dd;@", + "[$-80A]dddd, dd\" de \"mmmm\" de \"yyyy;@", + "[$-80A]dddd d\" de \"mmmm\" de \"yyyy;@", + "[$-80A]d\" de \"mmmm\" de \"yyyy;@" + ], + "2060": [ + "d/mm/yyyy;@", + "d/mm/yy;@", + "dd.mm.yy;@", + "yy/mm/dd;@", + "dd-mm-yy;@", + "dd/mm/yyyy;@", + "yyyy-mm-dd;@", + "[$-80C]dddd d mmmm yyyy;@", + "[$-80C]d mmmm yyyy;@", + "[$-80C]dd-mmm-yy;@" + ], + "2064": [ + "dd.mm.yyyy;@", + "dd.mm.yy;@", + "dd. mm. yy;@", + "d/m/yy;@", + "dd.m.yy;@", + "yyyy-mm-dd;@", + "[$-810]dddd, d. mmmm yyyy;@", + "[$-810]d-mmm-yy;@", + "[$-810]d mmmm yyyy;@" + ], + "2067": [ + "d/mm/yyyy;@", + "d/mm/yy;@", + "dd-mm-yy;@", + "dd.mm.yy;@", + "yyyy-mm-dd;@", + "[$-813]dddd d mmmm yyyy;@", + "[$-813]dd-mmm-yy;@", + "[$-813]d mmmm yyyy;@", + "[$-813]dd mmm yy;@" + ], + "2068": [ + "dd.mm.yyyy;@", + "dd.mm.yy;@", + "d.m.yy;@", + "yyyy-mm-dd;@", + "[$-814]d. mmmm yyyy;@", + "[$-814]dd. mmmm yyyy;@" + ], + "2070": [ + "yyyy-mm-dd;@", + "dd-mm-yyyy;@", + "d/m/yy;@", + "dd/mm/yy;@", + "[$-816]d/mmm;@", + "[$-816]d-mmm-yy;@", + "[$-816]dd-mmm-yy;@", + "[$-816]mmm/yy;@", + "[$-816]mmmm yy;@", + "[$-816]d \"de\" mmmm \"de\" yyyy;@", + "[$-409]d/m/yy h:mm AM/PM;@", + "d/m/yy h:mm;@", + "[$-816]mmmmm;@", + "[$-816]mmmmm-yy;@", + "d/m/yyyy;@", + "[$-816]d-mmm-yyyy;@" + ], + "2072": [ + "yyyy-mm-dd;@", + "[$-10818]dd.mm.yyyy;@", + "[$-10818]d mmm yyyy;@", + "[$-10818]dddd, d mmmm yyyy;@", + "[$-10818]d mmmm yyyy;@" + ], + "2073": [ + "yyyy-mm-dd;@", + "[$-10819]dd.mm.yyyy;@", + "[$-10819]d mmm yyyy \"г\".;@", + "[$]dddd, d mmmm yyyy \"г\".;@", + "[$]d mmmm yyyy \"г\".;@" + ], + "2074": [ + "d.m.yyyy;@", + "d.m.yy;@", + "d. m. yyyy;@", + "dd.mm.yyyy;@", + "d. m. yy;@", + "dd.mm.yy;@", + "dd. mm. yy;@", + "yyyy-mm-dd;@", + "[$-81A]d. mmmm yyyy;@", + "[$-81A]dd. mmmm yyyy;@", + "[$-81A]dddd, d. mmmm yyyy;@" + ], + "2077": [ + "d.m.yyyy;@", + "dd.mm.yyyy;@", + "d.m.yy;@", + "yyyy-mm-dd;@", + "[$-81D]\"den \"d mmmm yyyy;@" + ], + "2092": [ + "dd.mm.yyyy;@", + "dd.mm.yy;@", + "d.m.yy;@", + "dd/mm/yy;@", + "yyyy-mm-dd;@", + "[$-82C]d mmmm yyyy;@", + "[$-82C]dd mmmm yyyy;@" + ], + "2094": [ + "[$-1082E]d. m. yyyy;@", + "[$-1082E]d. m. yy;@", + "[$-1082E]dd.mm.yyyy;@", + "[$-1082E]dd.mm.yy;@", + "[$-1082E]yyyy-mm-dd;@", + "[$-1082E]dddd, d. mmmm yyyy;@", + "[$-1082E]d. mmmm yyyy;@" + ], + "2098": [ + "[$-10832]yyyy-mm-dd;@", + "[$-10832]yyyy mmm d;@", + "[$-10832]yyyy mmmm d, dddd;@", + "[$-10832]yyyy mmmm d;@" + ], + "2107": [ + "[$-1083B]yyyy-mm-dd;@", + "[$-1083B]yy-mm-dd;@", + "[$-1083B]dddd, mmmm d\". b. \"yyyy;@", + "[$-1083B]mmmm d\". b. \"yyyy;@" + ], + "2108": [ + "yyyy-mm-dd;@", + "[$-1083C]dd/mm/yyyy;@", + "[$-1083C]d mmm yyyy;@", + "[$-1083C]dddd d mmmm yyyy;@", + "[$-1083C]d mmmm yyyy;@" + ], + "2110": [ + "dd/mm/yyyy;@", + "dd/mm/yy;@", + "yyyy-mm-dd;@", + "[$-83E]dd mmmm yyyy;@" + ], + "2115": [ + "dd.mm.yyyy;@", + "dd.mm.yy;@", + "dd/mm yyyy;@", + "d.m.yy;@", + "dd/mm/yy;@", + "yyyy-mm-dd;@", + "[$-843]yyyy \"йил\" d-mmmm;@", + "[$-843]d mmmm yyyy;@", + "[$-843]dd mmmm yyyy;@" + ], + "2117": [ + "dd-mm-yyyy;@", + "dd-mm-yy;@", + "d-m-yy;@", + "d.m.yy;@", + "yyyy-mm-dd;@", + "[$-845]dd mmmm yyyy;@", + "[$-845]d mmmm yyyy;@", + "[$-5000845]dd-mm-yyyy;@", + "[$-5000845]dd-mm-yy;@", + "[$-5000845]d-m-yy;@", + "[$-5000845]d.m.yy;@", + "[$-5000845]yyyy-mm-dd;@", + "[$-5000845]d/m/yyyy;@", + "[$-5000845]dd mmmm yyyy;@", + "[$-5000845]d mmmm yyyy;@", + "[$-5000845]d mmmm, yyyy;@", + "[$-5000845]dddd, d mmmm, yyyy;@" + ], + "2118": [ + "[$-10846]dd-mm-yy;@", + "[$-10846]d-m-yy;@", + "[$-10846]d.m.yy;@", + "[$-10846]dd-mm-yyyy;@", + "[$-10846]yyyy-mm-dd;@", + "[$-10846]dd mmmm yyyy dddd;@", + "[$-10846]d mmmm yyyy;@" + ], + "2128": [ + "[$-10850]yyyy/m/d;@", + "[$-10850]yyyy-m-d;@", + "[$-10850]yyyy.m.d;@", + "[$-10850]yyyy.mm.dd;@", + "[$-10850]yyyy-mm-dd;@", + "[$-10850]yyyy/mm/dd;@", + "[$-10850]yy-m-d;@", + "[$-10850]yy/m/d;@", + "[$-10850]yy.m.d;@", + "[$-10850]yy/mm/dd;@", + "[$-10850]yyyyᠣᠨ mmmm dᠡᠳᠦᠷ᠂ dddd;@", + "[$-10850]yyyyᠣᠨ mmmm dᠡᠳᠦᠷ;@" + ], + "2137": [ + "[$-10859]dd/mm/yyyy;@", + "[$-10859]dd/mm/yy;@", + "[$-10859]yyyy-mm-dd;@", + "[$-10859]dddd, dd mmmm, yyyy;@", + "[$-10859]dd mmmm yyyy;@" + ], + "2141": [ + "[$-1085D]d/mm/yyyy;@", + "[$-1085D]d/m/yy;@", + "[$-1085D]dd/mm/yyyy;@", + "[$-1085D]yy-mm-dd;@", + "[$-1085D]yyyy-mm-dd;@", + "[$-1085D]dd-mmm-yy;@", + "[$-1085D]dddd, dd mmmm, yyyy;@", + "[$-1085D]ddd, mmmm dd,yyyy;@", + "[$-1085D]mmmm dd,yyyy;@", + "[$-1085D]dd mmmm, yyyy;@" + ], + "2143": [ + "[$-1085F]dd-mm-yyyy;@", + "[$-1085F]dd-mm-yy;@", + "[$-1085F]yyyy-mm-dd;@", + "[$-1085F]dd mmmm, yyyy;@", + "[$-1085F]dddd, dd mmmm, yyyy;@" + ], + "2144": [ + "yyyy-mm-dd;@", + "[$-10860]d/m/yyyy;@", + "[$-10860]d/m/yy;@", + "[$-10860]d mmm yyyy;@", + "[$-10860]dddd, d mmmm yyyy;@", + "[$-10860]d mmmm yyyy;@" + ], + "2145": [ + "yyyy-mm-dd;@", + "[$-10861]yyyy/m/d;@", + "[$-10861]yy/m/d;@", + "[$-10861]yyyy mmm d;@", + "[$-10861]yyyy mmmm d, dddd;@", + "[$-10861]yyyy mmmm d;@" + ], + "2151": [ + "[$-10867]dd/mm/yyyy;@", + "[$-10867]dd/mm/yy;@", + "[$-10867]dd.mm.yy;@", + "[$-10867]dd-mm-yy;@", + "[$-10867]yyyy-mm-dd;@", + "[$-10867]dddd d mmmm yyyy;@", + "[$-10867]d mmm yy;@", + "[$-10867]d mmmm yyyy;@" + ], + "2155": [ + "[$-1086B]dd/mm/yyyy;@", + "[$-1086B]dd/mm/yy;@", + "[$-1086B]d/m/yy;@", + "[$-1086B]dd-mm-yy;@", + "[$-1086B]yyyy-mm-dd;@", + "[$-1086B]dddd, dd\" de \"mmmm\" de \"yyyy;@", + "[$-1086B]dddd d\" de \"mmmm\" de \"yyyy;@", + "[$-1086B]d\" de \"mmmm\" de \"yyyy;@" + ], + "2163": [ + "yyyy-mm-dd;@", + "[$-10873]dd/mm/yyyy;@", + "[$-10873]dd/mm/yy;@", + "[$-10873]dd-mmm-yyyy;@", + "[$-10873]dddd\\፣ dd mmmm መዓልቲ yyyy gg;@", + "[$-10873]dd mmmm yyyy;@" + ], + "3076": [ + "d/m/yyyy;@", + "d/m/yy;@", + "dd/mm/yy;@", + "yy/m/d;@", + "yy/mm/dd;@", + "yyyy/m/d;@", + "yyyy/mm/dd;@", + "yyyy-mm-dd;@", + "[$-C04]dddd, d mmmm, yyyy;@", + "[$-C04]d mmmm, yyyy;@", + "[$-C04]dddd yyyy mm dd;@", + "yyyy mm dd;@" + ], + "3079": [ + "dd.mm.yyyy;@", + "dd.mm.yy;@", + "dd.m.yyyy;@", + "yyyy-mm-dd;@", + "[$-C07]dddd, dd. mmmm yyyy;@", + "[$-C07]d.mmmm yyyy;@", + "[$-C07]d.mmmyyyy;@", + "[$-C07]d mmm yyyy;@" + ], + "3081": [ + "d/mm/yyyy;@", + "d/mm/yy;@", + "d/m/yy;@", + "d/m/yyyy;@", + "dd/mm/yy;@", + "dd/mm/yyyy;@", + "[$-C09]dd-mmm-yy;@", + "[$-C09]dd-mmmm-yyyy;@", + "yyyy-mm-dd;@", + "yy/mm/dd;@", + "yyyy/mm/dd;@", + "[$-C09]dddd, d mmmm yyyy;@", + "[$-C09]d mmmm yyyy;@" + ], + "3082": [ + "yyyy-mm-dd;@", + "d-m;@", + "d-m-yy;@", + "dd-mm-yy;@", + "[$-C0A]d-mmm;@", + "[$-C0A]d-mmm-yy;@", + "[$-C0A]dd-mmm-yy;@", + "[$-C0A]mmm-yy;@", + "[$-C0A]mmmm-yy;@", + "[$-C0A]d \"de\" mmmm \"de\" yyyy;@", + "[$-409]d-m-yy h:mm AM/PM;@", + "d-m-yy h:mm;@", + "[$-C0A]mmmmm;@", + "[$-C0A]mmmmm-yy;@", + "d-m-yyyy;@", + "[$-C0A]d-mmm-yyyy;@" + ], + "3084": [ + "yyyy-mm-dd;@", + "yy-mm-dd;@", + "dd-mm-yy;@", + "yy mm dd;@", + "dd/mm/yy;@", + "[$-C0C]d mmmm, yyyy;@", + "[$-C0C]d mmm yyyy;@" + ], + "3098": [ + "d.m.yyyy;@", + "d.m.yy;@", + "d. m. yyyy;@", + "dd.mm.yyyy;@", + "d. m. yy;@", + "dd.mm.yy;@", + "dd. mm. yy;@", + "yyyy-mm-dd;@", + "[$-C1A]d. mmmm yyyy;@", + "[$-C1A]dd. mmmm yyyy;@", + "[$-C1A]dddd, d. mmmm yyyy;@" + ], + "3131": [ + "[$-10C3B]d.m.yyyy;@", + "[$-10C3B]dd.mm.yyyy;@", + "[$-10C3B]d.m.yy;@", + "[$-10C3B]yyyy-mm-dd;@", + "[$-10C3B]dddd\", \"mmmm d\". b. \"yyyy;@", + "[$-10C3B]mmmm d\". b. \"yyyy;@" + ], + "3152": [ + "[$-10C50]yyyy/m/d;@", + "[$-10C50]yyyy-m-d;@", + "[$-10C50]yyyy.m.d;@", + "[$-10C50]yyyy.mm.dd;@", + "[$-10C50]yyyy-mm-dd;@", + "[$-10C50]yyyy/mm/dd;@", + "[$-10C50]yy-m-d;@", + "[$-10C50]yy/m/d;@", + "[$-10C50]yy.m.d;@", + "[$-10C50]yy/mm/dd;@", + "[$-10C50]yyyyᠣᠨ mmmm dᠡᠳᠦᠷ᠂ dddd;@", + "[$-10C50]yyyyᠣᠨ mmmm dᠡᠳᠦᠷ;@" + ], + "3179": [ + "[$-10C6B]dd/mm/yyyy;@", + "[$-10C6B]dd/mm/yy;@", + "[$-10C6B]d/m/yy;@", + "[$-10C6B]dd-mm-yy;@", + "[$-10C6B]yyyy-mm-dd;@", + "[$-10C6B]dddd, d mmmm, yyyy;@" + ], + "4100": [ + "d/m/yyyy;@", + "d/m/yy;@", + "dd/mm/yy;@", + "yy/m/d;@", + "yy/mm/dd;@", + "yyyy/m/d;@", + "yyyy/mm/dd;@", + "yyyy-mm-dd;@", + "[$-1004]dddd, d mmmm, yyyy;@", + "[$-1004]d mmmm, yyyy;@", + "[$-1004]dddd yyyy mm dd;@", + "yyyy mm dd;@" + ], + "4103": [ + "dd.mm.yyyy;@", + "dd.mm.yy;@", + "d.mm.yy;@", + "d.m.yy;@", + "d.m.yyyy;@", + "yyyy-mm-dd;@", + "[$-1007]dddd, d. mmmm yyyy;@", + "[$-1007]d. mmmm yyyy;@", + "[$-1007]d. mmm yyyy;@" + ], + "4105": [ + "dd/mm/yyyy;@", + "dd/mm/yy;@", + "d/m/yy;@", + "yyyy-mm-dd;@", + "yy-mm-dd;@", + "m/dd/yy;@", + "[$-1009]mmmm d, yyyy;@", + "[$-1009]d-mmm-yy;@" + ], + "4106": [ + "dd/mm/yyyy;@", + "dd/mm/yy;@", + "d/mm/yyyy;@", + "d/m/yy;@", + "dd-mm-yy;@", + "yyyy-mm-dd;@", + "[$-100A]dddd, dd\" de \"mmmm\" de \"yyyy;@", + "[$-100A]dddd d\" de \"mmmm\" de \"yyyy;@", + "[$-100A]d\" de \"mmmm\" de \"yyyy;@" + ], + "4108": [ + "dd.mm.yyyy;@", + "dd.mm.yy;@", + "dd. m. yy;@", + "d.m.yy;@", + "yyyy-mm-dd;@", + "[$-100C]dddd, d. mmmm yyyy;@", + "[$-100C]d. mmmm yyyy;@", + "[$-100C]d mmm yy;@" + ], + "4122": [ + "yyyy-mm-dd;@", + "[$-1101A]d. m. yyyy.;@", + "[$-1101A]d. m. yy.;@", + "[$-1101A]d. mmm yyyy.;@", + "[$-1101A]dddd, d. mmmm yyyy.;@", + "[$-1101A]d. mmmm yyyy.;@" + ], + "4155": [ + "[$-1103B]dd.mm.yyyy;@", + "[$-1103B]dd.mm.yy;@", + "[$-1103B]d.m.yy;@", + "[$-1103B]yyyy-mm-dd;@", + "[$-1103B]dddd, mmmm d\". b. \"yyyy;@", + "[$-1103B]mmmm d\". b. \"yyyy;@" + ], + "4191": [ + "yyyy-mm-dd;@", + "dd-mm;@", + "dd-mm-yyyy;@", + "dd.mmm.yyyy;@", + "[$-105F]d-mmm;@", + "[$-105F]d-mmm-yy;@", + "[$-105F]dd-mmm-yy;@", + "[$-105F]mmm-yy;@", + "[$-105F]mmmm-yy;@", + "[$-105F]dd mmmm, yyyy;@", + "[$-105F]dd-mm-yy h:mm;@", + "dd-mm-yy h:mm;@", + "[$-105F]mmmmm;@", + "[$-105F]mmmmm, yyyy;@", + "yyyy-mm-dd;@", + "[$-105F]dd.mmm.yyyy;@" + ], + "5124": [ + "d/m/yyyy;@", + "d/m/yy;@", + "dd/mm/yy;@", + "yy/m/d;@", + "yy/mm/dd;@", + "yyyy/m/d;@", + "yyyy/mm/dd;@", + "yyyy-mm-dd;@", + "[$-1404]dddd, d mmmm, yyyy;@", + "[$-1404]d mmmm, yyyy;@", + "[$-1404]dddd yyyy mm dd;@", + "yyyy mm dd;@" + ], + "5127": [ + "dd.mm.yyyy;@", + "dd.mm.yy;@", + "d.mm.yy;@", + "dd. m. yy;@", + "d.m.yy;@", + "dd.mm.yyyy;@", + "yyyy-mm-dd;@", + "[$-1407]dddd, d. mmmm yyyy;@", + "[$-1407]d. mmmm yyyy;@", + "[$-1407]d. mmm yy;@" + ], + "5129": [ + "d/mm/yyyy;@", + "d/mm/yy;@", + "dd/mm/yy;@", + "d.mm.yy;@", + "yyyy-mm-dd;@", + "[$-1409]dddd, d mmmm yyyy;@", + "[$-1409]d mmmm yyyy;@" + ], + "5130": [ + "dd/mm/yyyy;@", + "dd/mm/yy;@", + "d/m/yy;@", + "dd-mm-yy;@", + "yyyy-mm-dd;@", + "[$-140A]dddd, dd\" de \"mmmm\" de \"yyyy;@", + "[$-140A]dddd d\" de \"mmmm\" de \"yyyy;@", + "[$-140A]d\" de \"mmmm\" de \"yyyy;@" + ], + "5132": [ + "dd/mm/yyyy;@", + "dd/mm/yy;@", + "dd.mm.yy;@", + "dd-mm-yy;@", + "yyyy-mm-dd;@", + "[$-140C]dddd d mmmm yyyy;@", + "[$-140C]d mmm yy;@", + "[$-140C]d mmmm yyyy;@" + ], + "5146": [ + "yyyy-mm-dd;@", + "[$-1141A]d. m. yyyy.;@", + "[$-1141A]d. mmm yyyy.;@", + "[$-1141A]dddd, d. mmmm yyyy.;@", + "[$-1141A]d. mmmm yyyy.;@" + ], + "5179": [ + "[$-1143B]yyyy-mm-dd;@", + "[$-1143B]yy-mm-dd;@", + "[$-1143B]dddd, mmmm d\". b. \"yyyy;@", + "[$-1143B]mmmm d\". b. \"yyyy;@" + ], + "6153": [ + "dd/mm/yyyy;@", + "dd/mm/yy;@", + "d/m/yy;@", + "d.m.yy;@", + "yyyy-mm-dd;@", + "[$-1809]dd mmmm yyyy;@", + "[$-1809]d mmmm yyyy;@" + ], + "6154": [ + "mm/dd/yyyy;@", + "mm/dd/yy;@", + "d/m/yy;@", + "dd/mm/yy;@", + "dd-mm-yy;@", + "yyyy-mm-dd;@", + "[$-180A]dddd, dd\" de \"mmmm\" de \"yyyy;@", + "[$-180A]dddd d\" de \"mmmm\" de \"yyyy;@", + "[$-180A]d\" de \"mmmm\" de \"yyyy;@" + ], + "6156": [ + "dd/mm/yyyy;@", + "dd/mm/yy;@", + "dd.mm.yy;@", + "dd-mm-yy;@", + "yyyy-mm-dd;@", + "[$-180C]dddd d mmmm yyyy;@", + "[$-180C]d mmm yy;@", + "[$-180C]d mmmm yyyy;@" + ], + "6170": [ + "yyyy-mm-dd;@", + "[$-1181A]d.m.yyyy.;@", + "[$-1181A]d.m.yy.;@", + "[$-1181A]dd.mm.yyyy.;@", + "[$-1181A]d. mmmm yyyy.;@", + "[$-1181A]dddd, dd. mmmm yyyy.;@", + "[$-1181A]dd. mmmm yyyy.;@" + ], + "6203": [ + "[$-1183B]dd.mm.yyyy;@", + "[$-1183B]dd.mm.yy;@", + "[$-1183B]d.m.yy;@", + "[$-1183B]yyyy-mm-dd;@", + "[$-1183B]dddd, mmmm d\". b. \"yyyy;@", + "[$-1183B]mmmm d\". b. \"yyyy;@" + ], + "7177": [ + "yyyy/mm/dd;@", + "yy/mm/dd;@", + "yyyy-mm-dd;@", + "[$-1C09]dd mmmm yyyy;@" + ], + "7178": [ + "dd/mm/yyyy;@", + "dd/mm/yy;@", + "mm/dd/yyyy;@", + "d/m/yy;@", + "dd-mm-yy;@", + "yyyy-mm-dd;@", + "[$-1C0A]dddd, dd\" de \"mmmm\" de \"yyyy;@", + "[$-1C0A]dddd d\" de \"mmmm\" de \"yyyy;@", + "[$-1C0A]d\" de \"mmmm\" de \"yyyy;@" + ], + "7180": [ + "yyyy-mm-dd;@", + "[$-11C0C]dd/mm/yyyy;@", + "[$-11C0C]d mmm yyyy;@", + "[$-11C0C]dddd d mmmm yyyy;@", + "[$-11C0C]d mmmm yyyy;@" + ], + "7194": [ + "d.m.yyyy;@", + "d.m.yy;@", + "d. m. yyyy;@", + "dd.mm.yyyy;@", + "d. m. yy;@", + "dd.mm.yy;@", + "dd. mm. yy;@", + "yyyy-mm-dd;@", + "[$-1C1A]d. mmmm yyyy;@", + "[$-1C1A]dd. mmmm yyyy;@", + "[$-1C1A]dddd, d. mmmm yyyy;@" + ], + "7227": [ + "[$-11C3B]yyyy-mm-dd;@", + "[$-11C3B]yy-mm-dd;@", + "[$-11C3B]dddd, mmmm d\". b. \"yyyy;@", + "[$-11C3B]mmmm d\". b. \"yyyy;@" + ], + "8201": [ + "dd/mm/yyyy;@", + "yyyy-mm-dd;@", + "[$-2009]dddd, mmmm dd, yyyy;@", + "[$-2009]mmmm dd, yyyy;@", + "[$-2009]dddd, dd mmmm, yyyy;@", + "[$-2009]dd mmmm, yyyy;@" + ], + "8202": [ + "dd/mm/yyyy;@", + "dd/mm/yy;@", + "d/m/yy;@", + "dd-mm-yy;@", + "yyyy-mm-dd;@", + "[$-200A]dddd, dd\" de \"mmmm\" de \"yyyy;@", + "[$-200A]dddd d\" de \"mmmm\" de \"yyyy;@", + "[$-200A]d\" de \"mmmm\" de \"yyyy;@" + ], + "8204": [ + "yyyy-mm-dd;@", + "[$-1200C]dd/mm/yyyy;@", + "[$-1200C]d mmm yyyy;@", + "[$-1200C]dddd d mmmm yyyy;@", + "[$-1200C]d mmmm yyyy;@" + ], + "8218": [ + "[$-1201A]d.m.yyyy;@", + "[$-1201A]d.m.yy;@", + "[$-1201A]d. m. yyyy;@", + "[$-1201A]dd.mm.yyyy;@", + "[$-1201A]d. m. yy;@", + "[$-1201A]dd.mm.yy;@", + "[$-1201A]dd. mm. yy;@", + "[$-1201A]yyyy-mm-dd;@", + "[$-1201A]d. mmmm yyyy;@", + "[$-1201A]dd. mmmm yyyy;@", + "[$-1201A]dddd, d. mmmm yyyy;@" + ], + "8251": [ + "[$-1203B]d.m.yyyy;@", + "[$-1203B]dd.mm.yyyy;@", + "[$-1203B]d.m.yy;@", + "[$-1203B]yyyy-mm-dd;@", + "[$-1203B]mmmm d\". p. \"yyyy;@", + "[$-1203B]dddd, mmmm d\". p. \"yyyy;@" + ], + "9225": [ + "mm/dd/yyyy;@", + "mm/dd/yy;@", + "yyyy-mm-dd;@", + "[$-2409]dddd, mmmm dd, yyyy;@", + "[$-2409]mmmm dd, yyyy;@", + "[$-2409]dddd, dd mmmm, yyyy;@", + "[$-2409]dd mmmm, yyyy;@" + ], + "9226": [ + "dd/mm/yyyy;@", + "dd/mm/yy;@", + "d/mm/yyyy;@", + "d/m/yy;@", + "dd-mm-yy;@", + "yyyy-mm-dd;@", + "[$-240A]dddd, dd\" de \"mmmm\" de \"yyyy;@", + "[$-240A]dddd d\" de \"mmmm\" de \"yyyy;@", + "[$-240A]d\" de \"mmmm\" de \"yyyy;@" + ], + "9228": [ + "yyyy-mm-dd;@", + "[$-1240C]dd/mm/yyyy;@", + "[$-1240C]d mmm yyyy;@", + "[$-1240C]dddd d mmmm yyyy;@", + "[$-1240C]d mmmm yyyy;@" + ], + "9242": [ + "d.m.yyyy;@", + "d.m.yy;@", + "d. m. yyyy;@", + "dd.mm.yyyy;@", + "d. m. yy;@", + "dd.mm.yy;@", + "dd. mm. yy;@", + "yyyy-mm-dd;@", + "[$-241A]d. mmmm yyyy;@", + "[$-241A]dd. mmmm yyyy;@", + "[$-241A]dddd, d. mmmm yyyy;@" + ], + "9275": [ + "[$-1243B]d.m.yyyy;@", + "[$-1243B]dd.mm.yyyy;@", + "[$-1243B]d.m.yy;@", + "[$-1243B]yyyy-mm-dd;@", + "[$-1243B]mmmm d\". p. \"yyyy;@", + "[$-1243B]dddd, mmmm d. yyyy;@" + ], + "10249": [ + "dd/mm/yyyy;@", + "yyyy-mm-dd;@", + "[$-2809]dddd, dd mmmm yyyy;@" + ], + "10250": [ + "dd/mm/yyyy;@", + "dd/mm/yy;@", + "d/m/yy;@", + "dd-mm-yy;@", + "yyyy-mm-dd;@", + "[$-280A]dddd, dd\" de \"mmmm\" de \"yyyy;@", + "[$-280A]dddd d\" de \"mmmm\" de \"yyyy;@", + "[$-280A]d\" de \"mmmm\" de \"yyyy;@" + ], + "10252": [ + "yyyy-mm-dd;@", + "[$-1280C]dd/mm/yyyy;@", + "[$-1280C]d mmm yyyy;@", + "[$-1280C]dddd d mmmm yyyy;@", + "[$-1280C]d mmmm yyyy;@" + ], + "10266": [ + "d.m.yyyy.;@", + "d.m.yy.;@", + "d. m. yyyy.;@", + "dd.mm.yyyy.;@", + "d. m. yy.;@", + "dd.mm.yy.;@", + "dd. mm. yy.;@", + "yyyy-mm-dd;@", + "[$-281A]d. mmmm yyyy.;@", + "[$-281A]dd. mmmm yyyy.;@", + "[$-281A]dddd, d. mmmm yyyy.;@" + ], + "11273": [ + "dd/mm/yyyy;@", + "yyyy-mm-dd;@", + "[$-2C09]dddd, dd mmmm yyyy;@" + ], + "11274": [ + "dd/mm/yyyy;@", + "dd/mm/yy;@", + "d/m/yy;@", + "dd-mm-yy;@", + "yyyy-mm-dd;@", + "[$-2C0A]dddd, dd\" de \"mmmm\" de \"yyyy;@", + "[$-2C0A]dddd d\" de \"mmmm\" de \"yyyy;@", + "[$-2C0A]d\" de \"mmmm\" de \"yyyy;@" + ], + "11276": [ + "yyyy-mm-dd;@", + "[$-12C0C]dd/mm/yyyy;@", + "[$-12C0C]d mmm yyyy;@", + "[$-12C0C]dddd d mmmm yyyy;@", + "[$-12C0C]d mmmm yyyy;@" + ], + "12297": [ + "m/d/yyyy;@", + "m/d/yy;@", + "mm/dd/yy;@", + "mm/dd/yyyy;@", + "yyyy-mm-dd;@", + "yy/mm/dd;@", + "[$-3009]dd-mmm-yy;@", + "[$-3009]dddd, mmmm dd, yyyy;@", + "[$-3009]mmmm dd, yyyy;@", + "[$-3009]dddd, dd mmmm, yyyy;@", + "[$-3009]dd mmmm, yyyy;@" + ], + "12298": [ + "dd/mm/yyyy;@", + "dd/mm/yy;@", + "d/m/yy;@", + "dd-mm-yy;@", + "yyyy-mm-dd;@", + "[$-300A]dddd, dd\" de \"mmmm\" de \"yyyy;@", + "[$-300A]dddd d\" de \"mmmm\" de \"yyyy;@", + "[$-300A]d\" de \"mmmm\" de \"yyyy;@" + ], + "12300": [ + "yyyy-mm-dd;@", + "[$-1300C]dd/mm/yyyy;@", + "[$-1300C]d mmm yyyy;@", + "[$-1300C]dddd d mmmm yyyy;@", + "[$-1300C]d mmmm yyyy;@" + ], + "13321": [ + "m/d/yyyy;@", + "m/d/yy;@", + "mm/dd/yy;@", + "mm/dd/yyyy;@", + "yyyy-mm-dd;@", + "yy/mm/dd;@", + "[$-3409]dd-mmm-yy;@", + "[$-3409]dddd, mmmm dd, yyyy;@", + "[$-3409]mmmm dd, yyyy;@", + "[$-3409]dddd, dd mmmm, yyyy;@", + "[$-3409]dd mmmm, yyyy;@" + ], + "13322": [ + "dd-mm-yyyy;@", + "dd-mm-yy;@", + "dd/mm/yy;@", + "d/m/yy;@", + "yyyy-mm-dd;@", + "[$-340A]dddd, dd\" de \"mmmm\" de \"yyyy;@", + "[$-340A]dddd d\" de \"mmmm\" de \"yyyy;@", + "[$-340A]d\" de \"mmmm\" de \"yyyy;@" + ], + "13324": [ + "yyyy-mm-dd;@", + "[$-1340C]dd/mm/yyyy;@", + "[$-1340C]d mmm yyyy;@", + "[$-1340C]dddd d mmmm yyyy;@", + "[$-1340C]d mmmm yyyy;@" + ], + "14345": [ + "yyyy-mm-dd;@", + "[$-13809]dd/mm/yyyy;@", + "[$-13809]dd/mm/yy;@", + "[$-13809]d mmm yyyy;@", + "[$-13809]dddd, dd mmmm yyyy;@", + "[$-13809]dd mmmm yyyy;@" + ], + "14346": [ + "dd/mm/yyyy;@", + "dd/mm/yy;@", + "d/m/yy;@", + "dd-mm-yy;@", + "yyyy-mm-dd;@", + "[$-380A]dddd, dd\" de \"mmmm\" de \"yyyy;@", + "[$-380A]dddd d\" de \"mmmm\" de \"yyyy;@", + "[$-380A]d\" de \"mmmm\" de \"yyyy;@" + ], + "14348": [ + "yyyy-mm-dd;@", + "[$-1380C]dd/mm/yyyy;@", + "[$-1380C]d mmm yyyy;@", + "[$-1380C]dddd d mmmm yyyy;@", + "[$-1380C]d mmmm yyyy;@" + ], + "15369": [ + "yyyy-mm-dd;@", + "[$-13C09]d/m/yyyy;@", + "[$-13C09]d mmm yyyy;@", + "[$-13C09]dddd, d mmmm yyyy;@", + "[$-13C09]d mmmm yyyy;@" + ], + "15370": [ + "dd/mm/yyyy;@", + "dd/mm/yy;@", + "d/m/yy;@", + "dd-mm-yy;@", + "yyyy-mm-dd;@", + "[$-3C0A]dddd, dd\" de \"mmmm\" de \"yyyy;@", + "[$-3C0A]dddd d\" de \"mmmm\" de \"yyyy;@", + "[$-3C0A]d\" de \"mmmm\" de \"yyyy;@" + ], + "15372": [ + "yyyy-mm-dd;@", + "[$-13C0C]dd/mm/yyyy;@", + "[$-13C0C]d mmm yyyy;@", + "[$-13C0C]dddd d mmmm yyyy;@", + "[$-13C0C]d mmmm yyyy;@" + ], + "16393": [ + "[$-14009]dd-mm-yyyy;@", + "[$-14009]dd-mm-yy;@", + "[$-14009]d-m-yy;@", + "[$-14009]d.m.yy;@", + "[$-14009]yyyy-mm-dd;@", + "[$-14009]dd mmmm yyyy;@", + "[$-14009]d mmmm yyyy;@", + "[$-14009]dddd, d mmmm, yyyy;@" + ], + "16394": [ + "dd/mm/yyyy;@", + "dd/mm/yy;@", + "d/m/yy;@", + "dd-mm-yy;@", + "yyyy-mm-dd;@", + "[$-400A]dddd, dd\" de \"mmmm\" de \"yyyy;@", + "[$-400A]dddd d\" de \"mmmm\" de \"yyyy;@", + "[$-400A]d\" de \"mmmm\" de \"yyyy;@" + ], + "17417": [ + "[$-14409]d/m/yyyy;@", + "[$-14409]d/m/yy;@", + "[$-14409]dd/mm/yyyy;@", + "[$-14409]dd/mm/yy;@", + "[$-14409]yyyy-mm-dd;@", + "[$-14409]dddd, d mmmm, yyyy;@", + "[$-14409]d mmmm, yyyy;@" + ], + "17418": [ + "dd/mm/yyyy;@", + "dd/mm/yy;@", + "mm-dd-yyyy;@", + "yyyy-mm-dd;@", + "[$-440A]dddd, dd\" de \"mmmm\" de \"yyyy;@" + ], + "18441": [ + "yyyy-mm-dd;@", + "[$-14809]d/m/yyyy;@", + "[$-14809]d/m/yy;@", + "[$-14809]d mmm yyyy;@", + "[$-14809]dddd, d mmmm yyyy;@", + "[$-14809]d mmmm yyyy;@" + ], + "18442": [ + "dd/mm/yyyy;@", + "dd/mm/yy;@", + "mm-dd-yyyy;@", + "yyyy-mm-dd;@", + "[$-480A]dddd, dd\" de \"mmmm\" de \"yyyy;@" + ], + "19466": [ + "dd/mm/yyyy;@", + "dd/mm/yy;@", + "mm-dd-yyyy;@", + "yyyy-mm-dd;@", + "[$-4C0A]dddd, dd\" de \"mmmm\" de \"yyyy;@" + ], + "20490": [ + "dd/mm/yyyy;@", + "dd/mm/yy;@", + "mm-dd-yyyy;@", + "yyyy-mm-dd;@", + "[$-500A]dddd, dd\" de \"mmmm\" de \"yyyy;@" + ], + "21514": [ + "[$-1540A]m/d/yyyy;@", + "[$-1540A]m/d/yy;@", + "[$-1540A]mm/dd/yy;@", + "[$-1540A]mm/dd/yyyy;@", + "[$-1540A]yy/mm/dd;@", + "[$-1540A]yyyy-mm-dd;@", + "[$-1540A]dd-mmm-yy;@", + "[$-1540A]dddd, mmmm dd, yyyy;@", + "[$-1540A]mmmm dd, yyyy;@", + "[$-1540A]dddd, dd mmmm, yyyy;@", + "[$-1540A]dd mmmm, yyyy;@" + ], + "22538": [ + "dd/mm/yyyy;@", + "dd/mm/yy;@", + "d/mm/yy;@", + "d/m/yy;@", + "dd-mm-yy;@", + "yyyy-mm-dd;@", + "[$-580A]dddd, dd\" de \"mmmm\" de \"yyyy;@", + "[$-580A]dddd d\" de \"mmmm\" de \"yyyy;@", + "[$-580A]d\" de \"mmmm\" de \"yyyy;@" + ], + "64546": [ + "dd.mm.yyyy;@", + "dd.mm.yy;@", + "yyyy-mm-dd;@", + "[$-FC22]d mmmm yyyy\" р.\";@" + ], + "64547": [ + "dd.mm.yyyy;@", + "dd.mm.yy;@", + "yyyy-mm-dd;@", + "[$-FC23]d mmmm yyyy;@" + ], + "64551": [ + "yyyy-mm-dd;@", + "yyyy.mm.dd;@", + "[$-FC27]yyyy \"m.\" mmmm d \"d.\";@", + "[$-427]yyyy \"m.\" mmmm d \"d.\";@" + ] +} +{ + "1025": [ + "[$-1000000]h:mm:ss;@", + "[$-1000401]h:mm AM/PM;@", + "[$-1000409]h:mm AM/PM;@", + "[$-2000000]h:mm:ss;@", + "[$-2000401]h:mm AM/PM;@", + "[$-2000409]h:mm AM/PM;@" + ], + "1026": [ + "hh:mm:ss;@", + "h:mm:ss;@" + ], + "1027": [ + "h:mm:ss;@", + "h:mm;@" + ], + "1028": [ + "h:mm;@", + "[$-409]h:mm AM/PM;@", + "h:mm:ss;@", + "[$-409]h:mm:ss AM/PM;@", + "[$-409]yyyy/m/d h:mm AM/PM;@", + "yyyy/m/d h:mm;@", + "h\"時\"mm\"分\";@", + "h\"時\"mm\"分\"ss\"秒\";@", + "上午/下午h\"時\"mm\"分\";@", + "上午/下午h\"時\"mm\"分\"ss\"秒\";@" + ], + "1029": [ + "h:mm;@", + "[$-409]h:mm AM/PM;@", + "h:mm:ss;@", + "[$-409]h:mm:ss AM/PM;@", + "mm:ss.0;@", + "[h]:mm:ss;@", + "[$-409]d/m/yy h:mm AM/PM;@", + "d/m/yy h:mm;@" + ], + "1030": [ + "hh:mm;@", + "hh:mm:ss;@", + "[$-409]hh:mm AM/PM;@", + "[$-409]hh:mm:ss AM/PM;@", + "dd-mm-yy hh:mm;@", + "mm-dd-yy hh:mm:ss;@", + "dd-mm-yy hh:mm:ss;@", + "yyyy-mm-dd hh:mm;@" + ], + "1031": [ + "h:mm;@", + "[$-409]h:mm AM/PM;@", + "h:mm:ss;@", + "[$-409]h:mm:ss AM/PM;@", + "mm:ss.0;@", + "[h]:mm:ss;@", + "[$-409]d/m/yy h:mm AM/PM;@", + "d.m.yy h:mm;@" + ], + "1032": [ + "h:mm;@", + "[$-408]h:mm AM/PM;@", + "h:mm:ss;@", + "[$-408]h:mm:ss AM/PM;@", + "mm:ss.0;@", + "[h]:mm:ss;@", + "[$-408]d/m/yy h:mm AM/PM;@", + "d/m/yy h:mm;@" + ], + "1033": [ + "h:mm;@", + "[$-409]h:mm AM/PM;@", + "h:mm:ss;@", + "[$-409]h:mm:ss AM/PM;@", + "mm:ss.0;@", + "[h]:mm:ss;@", + "[$-409]m/d/yy h:mm AM/PM;@", + "m/d/yy h:mm;@" + ], + "1034": [ + "h:mm:ss;@", + "hh:mm:ss;@", + "hh:mm;@", + "hh\"H\"mm\"'\";@" + ], + "1035": [ + "h:mm;@", + "[$-409]h:mm AM/PM;@", + "h:mm:ss;@", + "[$-409]h:mm:ss AM/PM;@", + "mm:ss.0;@", + "[h]:mm:ss;@", + "[$-409]d.m.yyyy h:mm AM/PM;@", + "d.m.yyyy h:mm;@" + ], + "1036": [ + "h:mm;@", + "[$-409]h:mm AM/PM;@", + "h:mm:ss;@", + "[$-409]h:mm:ss AM/PM;@", + "mm:ss.0;@", + "[h]:mm:ss;@", + "[$-409]d/m/yy h:mm AM/PM;@", + "d/m/yy h:mm;@" + ], + "1037": [ + "[$-1000000]h:mm;@", + "[$-1000409]h:mm AM/PM;@", + "[$-1000000]h:mm:ss;@", + "[$-1000409]h:mm:ss AM/PM;@", + "[$-1010409]d/m/yyyy h:mm AM/PM;@", + "[$-1010409]d/m/yyyy h:mm;@" + ], + "1038": [ + "h:mm;@", + "[$-40E]h:mm AM/PM;@", + "h:mm:ss;@", + "[$-40E]h:mm:ss AM/PM;@", + "mm:ss.0;@", + "[h]:mm:ss;@", + "[$-40E]yyyy. m. d. h:mm AM/PM;@", + "yyyy. m. d. h:mm;@", + "[$-40E]h \"óra\" m \"perc\" AM/PM;@", + "h \"óra\" m \"perc\";@", + "[$-40E]h \"óra\" m \"perckor\" AM/PM;@" + ], + "1039": [ + "hh:mm:ss;@", + "h:mm:ss;@", + "hh:mm;@" + ], + "1040": [ + "h:mm;@", + "[$-409]h:mm AM/PM;@", + "h:mm:ss;@", + "[$-409]h:mm:ss AM/PM;@", + "mm:ss.0;@", + "[h]:mm:ss;@", + "[$-409]d/m/yy h:mm AM/PM;@", + "d/m/yy h:mm;@" + ], + "1042": [ + "h:mm;@", + "h:mm:ss;@", + "[$-412]AM/PM h:mm;@", + "[$-412]AM/PM h:mm:ss;@", + "[$-409]h:mm AM/PM;@", + "[$-409]h:mm:ss AM/PM;@", + "yyyy\"-\"m\"-\"d h:mm;@", + "[$-412]yyyy\"-\"m\"-\"d AM/PM h:mm;@", + "[$-409]yyyy\"-\"m\"-\"d h:mm AM/PM;@", + "h\"시\" mm\"분\";@", + "h\"시\" mm\"분\" ss\"초\";@", + "[$-412]AM/PM h\"시\" mm\"분\";@", + "[$-412]AM/PM h\"시\" mm\"분\" ss\"초\";@" + ], + "1043": [ + "h:mm;@", + "[$-409]h:mm AM/PM;@", + "h:mm:ss;@", + "[$-409]h:mm:ss AM/PM;@", + "mm:ss.0;@", + "[h]:mm:ss;@", + "[$-409]d-mm-yy h:mm AM/PM;@", + "d-mm-yy h:mm;@" + ], + "1044": [ + "hh:mm;@", + "[$-409]h:mm AM/PM;@", + "hh:mm:ss;@", + "[$-409]h:mm:ss AM/PM;@", + "kl 'hh.mm;@", + "[h]:mm:ss;@", + "[$-409]m/d/yy h:mm AM/PM;@", + "m/d/yy hh:mm;@" + ], + "1045": [ + "h:mm;@", + "[$-409]h:mm AM/PM;@", + "h:mm:ss;@", + "[$-409]h:mm:ss AM/PM;@", + "mm:ss.0;@", + "[h]:mm:ss;@", + "[$-409]yy-mm-dd h:mm AM/PM;@", + "yy-mm-dd h:mm;@" + ], + "1046": [ + "h:mm;@", + "[$-409]h:mm AM/PM;@", + "h:mm:ss;@", + "[$-409]h:mm:ss AM/PM;@", + "mm:ss.0;@", + "[h]:mm:ss;@", + "[$-409]d/m/yy h:mm AM/PM;@", + "d/m/yy h:mm;@" + ], + "1047": [ + "[$-10417]hh:mm:ss;@", + "[$-10417]hh:mm;@" + ], + "1048": [ + "h:mm;@", + "[$-409]h:mm AM/PM;@", + "h:mm:ss;@", + "[$-409]h:mm:ss AM/PM;@", + "mm:ss.0;@", + "[h]:mm:ss;@", + "[$-409]d/m/yy h:mm AM/PM;@", + "d/m/yy h:mm;@" + ], + "1049": [ + "h:mm;@", + "[$-409]h:mm AM/PM;@", + "h:mm:ss;@", + "[$-409]h:mm:ss AM/PM;@", + "mm:ss.0;@", + "[h]:mm:ss;@", + "[$-409]dd/mm/yy h:mm AM/PM;@", + "dd/mm/yy h:mm;@" + ], + "1050": [ + "h:mm;@", + "[$-409]h:mm AM/PM;@", + "h:mm:ss;@", + "[$-409]h:mm:ss AM/PM;@", + "mm:ss.0;@", + "[h]:mm:ss;@", + "[$-409]d.m.yy. h:mm AM/PM;@", + "d.m.yy. h:mm;@" + ], + "1051": [ + "h:mm;@", + "[$-409]h:mm AM/PM;@", + "h:mm:ss;@", + "[$-409]h:mm:ss AM/PM;@", + "mm:ss.0;@", + "[h]:mm:ss;@", + "[$-409]d/m/yy h:mm AM/PM;@", + "d/m/yy h:mm;@" + ], + "1052": [ + "[$-41C]hh:mm:ss.Pd/md;@", + "hh:mm:ss;@" + ], + "1053": [ + "hh:mm;@", + "hh:mm:ss;@", + "\"kl \"hh:mm;@", + "\"kl \"hh:mm:ss;@", + "[$-409]yyyy-mm-dd h:mm AM/PM;@", + "[h]:mm:ss;@", + "yyyy-mm-dd hh:mm;@", + "[$-409]yyyy-mm-dd h:mm AM/PM;@" + ], + "1054": [ + "[$-D000000]h:mm:ss AM/PM;@", + "[$-D000000]h:mm:ss;@", + "[$-D000000]h:mm \"น.\";@", + "[$-D000409]h:mm AM/PM;@", + "[$-1000000]h:mm:ss AM/PM;@", + "[$-1000000]h:mm:ss;@", + "[$-1000000]h:mm \"น.\";@", + "[$-1000409]h:mm AM/PM;@" + ], + "1055": [ + "hh:mm;@", + "hh:mm:ss;@", + "mm:ss.0;@", + "d/m/yy hh:mm;@", + "dd/mm/yy hh:mm;@", + "d/m/yyyy hh:mm;@", + "m/d/yy hh:mm;@" + ], + "1056": [ + "[$-409]h:mm:ss AM/PM;@", + "[$-409]hh:mm:ss AM/PM;@", + "h:mm:ss;@", + "hh:mm:ss;@" + ], + "1057": [ + "h:mm:ss;@", + "hh:mm:ss;@" + ], + "1060": [ + "h:mm:ss;@", + "hh:mm:ss;@" + ], + "1061": [ + "h:mm:ss;@", + "hh:mm:ss;@" + ], + "1062": [ + "h:mm:ss;@", + "hh:mm:ss;@" + ], + "1064": [ + "[$-10428]hh:mm:ss;@", + "[$-10428]h:mm:ss;@", + "[$-10428]hh:mm;@", + "[$-10428]h:mm;@" + ], + "1065": [ + "[$-1000000]hh:mm:ss;@", + "[$-1000429]hh:mm AM/PM;@", + "[$-1000409]h:mm AM/PM;@", + "[$-3000000]h:mm:ss;@", + "[$-3000429]h:mm AM/PM;@", + "[$-3000409]h:mm AM/PM;@" + ], + "1066": [ + "[$-1000000]h:mm;@", + "[$-100042A]h:mm:ss AM/PM;@", + "[$-1000409]h:mm:ss AM/PM;@", + "[$-1000000]h:mm:ss;@" + ], + "1067": [ + "h:mm:ss;@", + "hh:mm:ss;@", + "[$-409]h:mm:ss AM/PM;@", + "[$-409]hh:mm:ss AM/PM;@" + ], + "1068": [ + "h:mm:ss;@", + "hh:mm:ss;@" + ], + "1069": [ + "h:mm;@", + "[$-409]h:mm AM/PM;@", + "h:mm:ss;@", + "[$-409]h:mm:ss AM/PM;@", + "mm:ss.0;@", + "[h]:mm:ss;@", + "[$-409]yy/mm/dd h:mm AM/PM;@", + "yy/mm/dd h:mm;@" + ], + "1070": [ + "[$-1042E]h:mm:ss;@", + "[$-1042E]h:mm \"hodź\".;@" + ], + "1071": [ + "hh:mm:ss;@" + ], + "1072": [ + "[$-10430]hh:mm:ss;@", + "[$-10430]hh:mm;@" + ], + "1073": [ + "[$-10431]hh:mm:ss;@", + "[$-10431]hh:mm;@" + ], + "1074": [ + "[$-10432]hh:mm:ss;@", + "[$-10432]hh:mm;@" + ], + "1075": [ + "[$-10433]hh:mm:ss;@", + "[$-10433]hh:mm;@" + ], + "1076": [ + "[$-10434]hh:mm:ss;@", + "[$-10434]hh:mm;@" + ], + "1077": [ + "[$-10435]hh:mm:ss;@", + "[$-10435]hh:mm;@" + ], + "1078": [ + "[$-409]hh:mm:ss AM/PM;@", + "[$-409]h:mm:ss AM/PM;@" + ], + "1079": [ + "h:mm:ss;@", + "hh:mm:ss;@" + ], + "1080": [ + "hh.mm.ss;@", + "hh:mm:ss;@" + ], + "1081": [ + "[$-1000000]h:mm;@", + "[$-4000000]h:mm;@", + "[$-1000439]h:mm AM/PM;@", + "[$-4000439]h:mm AM/PM;@", + "[$-1000409]h:mm AM/PM;@", + "[$-1000439]h:mm:ss AM/PM;@", + "[$-4000439]h:mm:ss AM/PM;@", + "[$-1000409]h:mm:ss AM/PM;@" + ], + "1082": [ + "[$-1043A]hh:mm:ss;@", + "[$-1043A]hh:mm;@" + ], + "1083": [ + "[$-1043B]hh:mm:ss;@", + "[$-1043B]hh:mm;@" + ], + "1085": [ + "[$-1043D]hh:mm:ss;@", + "[$-1043D]hh:mm;@" + ], + "1086": [ + "h:mm:ss;@", + "hh:mm:ss;@" + ], + "1087": [ + "h:mm:ss;@", + "hh:mm:ss;@" + ], + "1088": [ + "h:mm:ss;@" + ], + "1089": [ + "[$-409]h:mm:ss AM/PM;@", + "[$-409]hh:mm:ss AM/PM;@", + "h:mm:ss;@", + "hh:mm:ss;@" + ], + "1090": [ + "[$-10442]hh:mm:ss;@", + "[$-10442]h:mm:ss;@", + "[$-10442]hh:mm;@", + "[$-10442]h:mm;@" + ], + "1091": [ + "hh:mm:ss;@", + "h:mm:ss;@" + ], + "1092": [ + "h:mm:ss;@", + "hh:mm:ss;@" + ], + "1093": [ + "[$-10445]hh.mm.ss;@", + "[$-10445]h.mm.ss;@", + "[$-10409]AM/PM hh.mm.ss;@", + "[$-10409]AM/PM h.mm.ss;@", + "[$-10445]hh.mm;@", + "[$-10445]h.mm;@", + "[$-10409]AM/PM hh.mm;@", + "[$-10409]AM/PM h.mm;@" + ], + "1094": [ + "[$-446]AM/PM hh:mm:ss;@", + "[$-446]AM/PM h:mm:ss;@", + "h:mm:ss;@", + "hh:mm:ss;@" + ], + "1095": [ + "hh:mm:ss;@", + "h:mm:ss;@", + "[$-447]AM/PM hh:mm:ss;@", + "[$-447]AM/PM h:mm:ss;@" + ], + "1096": [ + "[$-10448]hh:mm:ss;@", + "[$-10448]h:mm:ss;@", + "[$-10409]AM/PM hh:mm:ss;@", + "[$-10409]AM/PM h:mm:ss;@", + "[$-10448]hh:mm;@", + "[$-10448]h:mm;@", + "[$-10409]AM/PM hh:mm;@", + "[$-10409]AM/PM h:mm;@" + ], + "1097": [ + "hh:mm:ss;@", + "h:mm:ss;@", + "[$-449]hh:mm:ss AM/PM;@", + "[$-449]h:mm:ss AM/PM;@" + ], + "1098": [ + "hh:mm:ss;@", + "h:mm:ss;@", + "[$-44A]AM/PM hh:mm:ss;@", + "[$-44A]AM/PM h:mm:ss;@" + ], + "1099": [ + "hh:mm:ss;@", + "h:mm:ss;@", + "[$-44B]AM/PM hh:mm:ss;@", + "[$-44B]AM/PM h:mm:ss;@" + ], + "1100": [ + "[$-10409]h:mm:ss AM/PM;@", + "[$-1044C]hh:mm:ss;@", + "[$-10409]h:mm AM/PM;@", + "[$-1044C]hh:mm;@" + ], + "1101": [ + "[$-1044D]AM/PM h:mm:ss;@", + "[$-1044D]AM/PM hh:mm:ss;@", + "[$-1044D]h:mm:ss;@", + "[$-1044D]AM/PM h:mm;@", + "[$-1044D]AM/PM hh:mm;@", + "[$-1044D]h:mm;@" + ], + "1102": [ + "hh:mm:ss;@", + "h:mm:ss;@", + "[$-44E]hh:mm:ss AM/PM;@", + "[$-44E]h:mm:ss AM/PM;@" + ], + "1103": [ + "hh:mm:ss;@", + "h:mm:ss;@", + "[$-44F]hh:mm:ss AM/PM;@", + "[$-44F]h:mm:ss AM/PM;@" + ], + "1104": [ + "h:mm:ss;@" + ], + "1105": [ + "[$-10451]hh:mm:ss;@", + "[$-10451]hh:mm;@" + ], + "1106": [ + "[$-10452]hh:mm:ss;@", + "[$-10452]hh:mm;@" + ], + "1107": [ + "[$-10453]hh:mm:ss;@", + "[$-10453]h:mm;@" + ], + "1108": [ + "[$-10454]h:mm:ss;@", + "[$-10454]hh:mm:ss;@", + "[$-10454]h:mm;@", + "[$-10454]hh:mm;@" + ], + "1109": [ + "[$-10455]hh:mm:ss;@", + "[$-10455]h:mm;@", + "[$-10455]hh:mm;@" + ], + "1110": [ + "h:mm:ss;@", + "hh:mm:ss;@", + "hh:mm;@", + "[$-456]hh:mm:ss AM/PM;@" + ], + "1111": [ + "hh:mm:ss;@", + "h:mm:ss;@", + "[$-457]hh:mm:ss AM/PM;@", + "[$-457]h:mm:ss AM/PM;@" + ], + "1112": [ + "[$-10458]h:mm:ss AM/PM;@", + "[$-10458]hh:mm:ss;@", + "[$-10458]h:mm AM/PM;@", + "[$-10458]hh:mm;@" + ], + "1113": [ + "[$-10409]AM/PM h:mm:ss;@", + "[$-10459]hh:mm:ss;@", + "[$-10409]AM/PM h:mm;@", + "[$-10459]hh:mm;@" + ], + "1114": [ + "[$-45A]hh:mm:ss AM/PM;@", + "hh:mm:ss;@" + ], + "1115": [ + "[$-1045B]hh.mm.ss;@", + "[$-1045B]hh.mm;@" + ], + "1116": [ + "[$-10409]h:mm:ss AM/PM;@", + "[$-10409]hh:mm:ss AM/PM;@", + "[$-1045C]h:mm:ss;@", + "[$-1045C]hh:mm:ss;@", + "[$-10409]h:mm AM/PM;@", + "[$-10409]hh:mm AM/PM;@", + "[$-1045C]h:mm;@", + "[$-1045C]hh:mm;@" + ], + "1117": [ + "[$-10409]h:mm:ss AM/PM;@", + "[$-10409]hh:mm:ss AM/PM;@", + "[$-1045D]h:mm:ss;@", + "[$-1045D]hh:mm:ss;@", + "[$-10409]h:mm AM/PM;@", + "[$-10409]hh:mm AM/PM;@", + "[$-1045D]h:mm;@", + "[$-1045D]hh:mm;@" + ], + "1118": [ + "[$-1045E]h:mm:ss AM/PM;@", + "[$-1045E]hh:mm:ss;@", + "[$-1045E]h:mm AM/PM;@", + "[$-1045E]hh:mm;@" + ], + "1119": [ + "[$-1045F]hh:mm:ss;@", + "[$-1045F]hh:mm;@" + ], + "1120": [ + "[$-10409]h:mm:ss AM/PM;@", + "[$-10460]hh:mm:ss;@", + "[$-10409]h:mm AM/PM;@", + "[$-10460]hh:mm;@" + ], + "1121": [ + "[$-10461]h:mm:ss AM/PM;@", + "[$-10461]hh:mm:ss AM/PM;@", + "[$-10461]h:mm:ss;@", + "[$-10461]hh:mm:ss;@", + "[$-10461]h:mm AM/PM;@", + "[$-10461]hh:mm AM/PM;@", + "[$-10461]h:mm;@", + "[$-10461]hh:mm;@" + ], + "1122": [ + "[$-10462]hh:mm:ss;@", + "[$-10462]hh:mm;@" + ], + "1123": [ + "[$-160463]h:mm:ss;@", + "[$-160463]hh:mm:ss;@", + "[$-160463]h:mm;@", + "[$-160463]hh:mm;@" + ], + "1124": [ + "[$-10409]h:mm:ss AM/PM;@", + "[$-10464]hh:mm:ss;@", + "[$-10409]h:mm AM/PM;@", + "[$-10464]hh:mm;@" + ], + "1125": [ + "hh:mm;@", + "hh:mm:ss;@", + "hh:mm;@", + "[$-465]hh:mm AM/PM;@", + "hh:mm:ss;@", + "[$-465]hh:mm:ss AM/PM;@" + ], + "1126": [ + "[$-10466]hh:mm:ss;@", + "[$-10466]hh:mm;@" + ], + "1127": [ + "[$-10467]hh:mm:ss;@", + "[$-10467]hh:mm;@" + ], + "1128": [ + "[$-10468]hh:mm:ss;@", + "[$-10468]hh:mm;@" + ], + "1129": [ + "[$-10469]hh:mm:ss;@", + "[$-10469]hh:mm;@" + ], + "1130": [ + "[$-1046A]h:m:s;@", + "[$-1046A]hh:mm:ss;@", + "[$-1046A]h:m;@", + "[$-1046A]hh:mm;@" + ], + "1131": [ + "[$-1046B]hh:mm:ss AM/PM;@", + "[$-1046B]h:mm:ss AM/PM;@", + "[$-1046B]h:mm:ss;@", + "[$-1046B]hh:mm:ss;@", + "[$-1046B]hh:mm AM/PM;@", + "[$-1046B]h:mm AM/PM;@", + "[$-1046B]h:mm;@", + "[$-1046B]hh:mm;@" + ], + "1132": [ + "[$-1046C]hh:mm:ss;@", + "[$-1046C]hh:mm;@" + ], + "1133": [ + "[$-1046D]h:mm:ss;@", + "[$-1046D]h:mm;@" + ], + "1134": [ + "[$-1046E]hh:mm:ss;@", + "[$-1046E]h:mm:ss\" Auer\";@", + "[$-1046E]hh:mm:ss\" Auer\";@", + "[$-1046E]hh:mm;@", + "[$-1046E]h:mm;@", + "[$-1046E]h.mm;@", + "[$-1046E]h.mm\" Auer\";@" + ], + "1135": [ + "[$-1046F]hh:mm:ss;@", + "[$-1046F]h:mm:ss;@", + "[$-1046F]hh:mm;@", + "[$-1046F]h:mm;@" + ], + "1136": [ + "[$-10470]hh:mm:ss;@", + "[$-10470]hh:mm;@" + ], + "1137": [ + "[$-10409]h:mm:ss AM/PM;@", + "[$-10471]hh:mm:ss;@", + "[$-10409]h:mm AM/PM;@", + "[$-10471]hh:mm;@" + ], + "1138": [ + "[$-10472]h:mm:ss AM/PM;@", + "[$-10472]hh:mm:ss;@", + "[$-10472]h:mm AM/PM;@", + "[$-10472]hh:mm;@" + ], + "1139": [ + "[$-10473]h:mm:ss AM/PM;@", + "[$-10473]hh:mm:ss;@", + "[$-10473]h:mm AM/PM;@", + "[$-10473]hh:mm;@" + ], + "1140": [ + "[$-10474]hh:mm:ss;@", + "[$-10474]h:mm:ss;@", + "[$-10474]hh:mm:ss AM/PM;@", + "[$-10474]hh:mm;@", + "[$-10474]h:mm;@", + "[$-10474]hh:mm AM/PM;@" + ], + "1141": [ + "[$-10409]h:mm:ss AM/PM;@", + "[$-10475]hh:mm:ss;@", + "[$-10409]h:mm AM/PM;@", + "[$-10475]hh:mm;@" + ], + "1142": [ + "[$-10476]hh:mm:ss;@", + "[$-10476]hh:mm;@" + ], + "1143": [ + "[$-10477]h:mm:ss AM/PM;@", + "[$-10477]hh:mm:ss;@", + "[$-10477]h:mm AM/PM;@", + "[$-10477]hh:mm;@" + ], + "1144": [ + "[$-10478]AM/PM h:mm:ss;@", + "[$-10478]h:mm:ss;@", + "[$-10478]hh:mm:ss;@", + "[$-10478]AM/PM h:mm;@", + "[$-10478]h:mm;@", + "[$-10478]hh:mm;@" + ], + "1145": [ + "[$-10479]h:mm:ss;@", + "[$-10479]hh:mm:ss;@", + "[$-10479]h:mm;@", + "[$-10479]hh:mm;@" + ], + "1146": [ + "[$-1047A]h:mm:ss;@", + "[$-1047A]hh:mm:ss;@", + "[$-1047A]h:mm;@", + "[$-1047A]hh:mm;@" + ], + "1148": [ + "[$-10409]h:mm:ss AM/PM;@", + "[$-10409]hh:mm:ss AM/PM;@", + "[$-1047C]hh:mm:ss;@", + "[$-1047C]h:mm:ss;@", + "[$-10409]h:mm AM/PM;@", + "[$-10409]hh:mm AM/PM;@", + "[$-1047C]hh:mm;@", + "[$-1047C]h:mm;@" + ], + "1150": [ + "[$-1047E]hh:mm:ss;@", + "[$-1047E]hh:mm;@" + ], + "1152": [ + "[$-10480]h:mm:ss;@", + "[$-10480]hh:mm:ss;@", + "[$-10480]AM/PM h:mm:ss;@", + "[$-10480]AM/PM hh:mm:ss;@", + "[$-10480]h:mm;@", + "[$-10480]hh:mm;@", + "[$-10480]AM/PM h:mm;@", + "[$-10480]AM/PM hh:mm;@" + ], + "1153": [ + "[$-10409]h:mm:ss AM/PM;@", + "[$-10481]hh:mm:ss;@", + "[$-10409]h:mm AM/PM;@", + "[$-10481]hh:mm;@" + ], + "1154": [ + "[$-10482]h\"h\"mm:ss;@", + "[$-10482]hh\"h\"mm ss \"seg\".;@", + "[$-10482]h\"h\"mm;@", + "[$-10482]hh\"h\"mm;@" + ], + "1155": [ + "[$-10483]h:mm:ss;@", + "[$-10483]hh:mm:ss;@", + "[$-10483]hh:mm;@", + "[$-10483]h:mm;@", + "[$-10483]hh.mm;@" + ], + "1156": [ + "[$-10484]hh:mm:ss;@", + "[$-10484]h:mm:ss;@", + "[$-10484]hh:mm;@", + "[$-10484]h:mm;@", + "[$-10484]hh.mm;@", + "[$-10484]hh\" h \"mm;@", + "[$-10484]hh\"h\"mm;@" + ], + "1157": [ + "[$-10485]hh:mm:ss;@", + "[$-10485]hh:mm;@" + ], + "1158": [ + "[$-10486]h:mm:ss AM/PM;@", + "[$-10486]hh:mm:ss;@", + "[$-10486]h:mm AM/PM;@", + "[$-10486]hh:mm;@" + ], + "1159": [ + "[$-10487]hh:mm:ss;@", + "[$-10487]hh:mm;@" + ], + "1160": [ + "[$-10488]hh:mm:ss;@", + "[$-10488]hh:mm;@" + ], + "1164": [ + "[$-16048C]h:mm:ss;@", + "[$-16048C]hh:mm:ss;@", + "[$-16048C]h:mm;@", + "[$-16048C]hh:mm;@" + ], + "1169": [ + "[$-10491]hh:mm:ss;@", + "[$-10491]hh:mm;@" + ], + "2052": [ + "h:mm;@", + "[$-409]h:mm AM/PM;@", + "h:mm:ss;@", + "[$-409]h:mm:ss AM/PM;@", + "h\"时\"mm\"分\";@", + "h\"时\"mm\"分\"ss\"秒\";@", + "上午/下午h\"时\"mm\"分\";@", + "上午/下午h\"时\"mm\"分\"ss\"秒\";@", + "[DBNum1][$-804]h\"时\"mm\"分\";@", + "[DBNum1][$-804]上午/下午h\"时\"mm\"分\";@" + ], + "2055": [ + "hh:mm:ss;@", + "h:mm:ss;@", + "h.mm\" h\";@", + "hh.mm\" h\";@", + "h.mm\" Uhr\";@" + ], + "2057": [ + "hh:mm:ss;@", + "h:mm:ss;@", + "[$-409]hh:mm:ss AM/PM;@", + "[$-409]h:mm:ss AM/PM;@" + ], + "2058": [ + "[$-80A]hh:mm:ss AM/PM;@", + "[$-80A]h:mm:ss AM/PM;@", + "h:mm:ss;@", + "hh:mm:ss;@" + ], + "2060": [ + "h:mm:ss;@", + "hh:mm:ss;@", + "h.mm;@", + "h\" h \"mm;@", + "h\" h \"m\" min \"s\" s \";@" + ], + "2064": [ + "hh:mm:ss;@", + "h:mm:ss;@", + "h.mm\" h\";@" + ], + "2067": [ + "h:mm:ss;@", + "hh:mm:ss;@", + "h.mm\" u.\";@", + "h:mm;@" + ], + "2068": [ + "hh:mm:ss;@", + "h:mm:ss;@", + "\"kl \"hh.mm;@", + "hh.mm.ss;@" + ], + "2070": [ + "h:mm;@", + "[$-409]h:mm AM/PM;@", + "h:mm:ss;@", + "[$-409]h:mm:ss AM/PM;@", + "mm:ss.0;@", + "[h]:mm:ss;@", + "[$-409]d/m/yy h:mm AM/PM;@", + "d/m/yy h:mm;@" + ], + "2072": [ + "[$-10818]hh:mm:ss;@", + "[$-10818]hh:mm;@" + ], + "2073": [ + "[$-10819]hh:mm:ss;@", + "[$-10819]hh:mm;@" + ], + "2074": [ + "h:mm:ss;@", + "hh:mm:ss;@" + ], + "2077": [ + "hh:mm:ss;@", + "h:mm:ss;@", + "\"kl \"h:mm;@" + ], + "2092": [ + "h:mm:ss;@", + "hh:mm:ss;@" + ], + "2094": [ + "[$-1082E]hh:mm:ss;@", + "[$-1082E]h:mm:ss\" góź.\";@", + "[$-1082E]\"zeger \"h:mm:ss;@", + "[$-1082E]hh:mm;@", + "[$-1082E]h:mm;@", + "[$-1082E]h:mm\" góź.\";@", + "[$-1082E]\"zeger \"h:mm;@" + ], + "2098": [ + "[$-10832]hh:mm:ss;@", + "[$-10832]hh:mm;@" + ], + "2107": [ + "[$-1083B]hh:mm:ss;@", + "[$-1083B]h:mm:ss;@", + "[$-1083B]hh:mm;@", + "[$-1083B]h:mm;@" + ], + "2108": [ + "[$-1083C]hh:mm:ss;@", + "[$-1083C]hh:mm;@" + ], + "2110": [ + "h:mm:ss;@", + "hh:mm:ss;@" + ], + "2115": [ + "hh:mm:ss;@", + "h:mm:ss;@" + ], + "2117": [ + "[$-10409]h:mm:ss AM/PM;@", + "[$-10845]hh:mm:ss;@", + "[$-10409]h:mm AM/PM;@", + "[$-10845]hh:mm;@" + ], + "2118": [ + "[$-10409]h.mm.ss AM/PM;@", + "[$-10409]hh:mm:ss AM/PM;@", + "[$-10846]h:mm:ss;@", + "[$-10846]hh:mm:ss;@", + "[$-10409]h.mm AM/PM;@", + "[$-10409]hh:mm AM/PM;@", + "[$-10846]h:mm;@", + "[$-10846]hh:mm;@" + ], + "2128": [ + "[$-10850]h:mm:ss;@", + "[$-10850]h:mm;@" + ], + "2137": [ + "[$-10409]h:mm:ss AM/PM;@", + "[$-10409]hh:mm:ss AM/PM;@", + "[$-10859]h:mm:ss;@", + "[$-10859]hh:mm:ss;@", + "[$-10409]h:mm AM/PM;@", + "[$-10409]hh:mm AM/PM;@", + "[$-10859]h:mm;@", + "[$-10859]hh:mm;@" + ], + "2141": [ + "[$-10409]h:mm:ss AM/PM;@", + "[$-10409]hh:mm:ss AM/PM;@", + "[$-1085D]hh:mm:ss;@", + "[$-1085D]h:mm:ss;@", + "[$-10409]h:mm AM/PM;@", + "[$-10409]hh:mm AM/PM;@", + "[$-1085D]hh:mm;@", + "[$-1085D]h:mm;@" + ], + "2143": [ + "[$-1085F]h:mm:ss;@", + "[$-1085F]hh:mm:ss;@", + "[$-1085F]h:mm;@", + "[$-1085F]hh:mm;@" + ], + "2144": [ + "[$-10409]AM/PM h:mm:ss;@", + "[$-10860]hh:mm:ss;@", + "[$-10409]AM/PM h:mm;@", + "[$-10860]hh:mm;@" + ], + "2145": [ + "[$-10861]h:mm:ss AM/PM;@", + "[$-10861]hh:mm:ss;@", + "[$-10861]h:mm AM/PM;@", + "[$-10861]hh:mm;@" + ], + "2151": [ + "[$-10867]hh:mm:ss;@", + "[$-10867]h:mm:ss;@", + "[$-10867]hh:mm;@", + "[$-10867]h:mm;@", + "[$-10867]hh.mm;@", + "[$-10867]hh\" h \"mm;@" + ], + "2155": [ + "[$-1086B]h:mm:ss;@", + "[$-1086B]hh:mm:ss;@", + "[$-1086B]h:mm;@", + "[$-1086B]hh:mm;@" + ], + "2163": [ + "[$-10873]h:mm:ss AM/PM;@", + "[$-10873]hh:mm:ss;@", + "[$-10873]h:mm AM/PM;@", + "[$-10873]hh:mm;@" + ], + "3076": [ + "h:mm:ss;@", + "hh:mm:ss;@" + ], + "3079": [ + "hh:mm:ss;@", + "h:mm:ss;@", + "hh:mm;@", + "hh:mm\" Uhr\";@" + ], + "3081": [ + "[$-409]h:mm:ss AM/PM;@", + "h:mm:ss;@", + "hh:mm:ss;@" + ], + "3082": [ + "h:mm;@", + "[$-409]h:mm AM/PM;@", + "h:mm:ss;@", + "[$-409]h:mm:ss AM/PM;@", + "mm:ss.0;@", + "[h]:mm:ss;@", + "[$-409]d-m-yy h:mm AM/PM;@", + "d-m-yy h:mm;@" + ], + "3084": [ + "hh:mm:ss;@", + "h:mm:ss;@", + "h\" h \"mm;@", + "h:mm;@" + ], + "3098": [ + "h:mm:ss;@", + "hh:mm:ss;@" + ], + "3131": [ + "[$-10C3B]h:mm:ss;@", + "[$-10C3B]hh:mm:ss;@", + "[$-10C3B]h:mm;@", + "[$-10C3B]hh:mm;@" + ], + "3152": [ + "[$-10C50]h:mm:ss;@", + "[$-10C50]h:mm;@" + ], + "3179": [ + "[$-10C6B]hh:mm:ss AM/PM;@", + "[$-10C6B]hh:mm:ss;@", + "[$-10C6B]hh:mm AM/PM;@", + "[$-10C6B]hh:mm;@" + ], + "4100": [ + "[$-409]AM/PM h:mm:ss;@", + "[$-409]AM/PM hh:mm:ss;@", + "h:mm:ss;@", + "hh:mm:ss;@" + ], + "4103": [ + "hh:mm:ss;@", + "h:mm:ss;@", + "h.mm;@", + "h.mm\" Uhr \";@" + ], + "4105": [ + "[$-409]h:mm:ss AM/PM;@", + "[$-409]hh:mm:ss AM/PM;@", + "hh:mm:ss;@", + "h:mm:ss;@" + ], + "4106": [ + "[$-100A]hh:mm:ss AM/PM;@", + "[$-100A]h:mm:ss AM/PM;@", + "h:mm:ss;@", + "hh:mm:ss;@" + ], + "4108": [ + "hh:mm:ss;@", + "h:mm:ss;@", + "hh.mm\" h\";@" + ], + "4122": [ + "[$-1101A]hh:mm:ss;@", + "[$-1101A]hh:mm;@" + ], + "4155": [ + "[$-1103B]hh:mm:ss;@", + "[$-1103B]h:mm:ss;@", + "[$-1103B]hh.mm.ss;@", + "[$-1103B]hh:mm;@", + "[$-1103B]h:mm;@", + "[$-1103B]hh.mm;@" + ], + "4191": [ + "h:mm;@", + "[$-105F]h:mm;@", + "h:mm:ss;@", + "[$-105F]h:mm:ss;@", + "mm:ss.0;@", + "[h]:mm:ss;@", + "[$-105F]dd-mm-yy h:mm;@", + "dd-mm-yy h:mm;@" + ], + "5124": [ + "h:mm:ss;@", + "hh:mm:ss;@" + ], + "5127": [ + "hh:mm:ss;@", + "h:mm:ss;@", + "h.mm\" h\";@", + "hh.mm\" h\";@", + "h.mm\" Uhr\";@" + ], + "5129": [ + "[$-1409]h:mm:ss AM/PM;@", + "[$-1409]hh:mm:ss AM/PM;@", + "hh:mm:ss;@", + "h:mm:ss;@" + ], + "5130": [ + "[$-140A]hh:mm:ss AM/PM;@", + "[$-140A]h:mm:ss AM/PM;@", + "h:mm:ss;@", + "hh:mm:ss;@" + ], + "5132": [ + "hh:mm:ss;@", + "h:mm:ss;@", + "hh.mm;@", + "hh\" h \"mm;@" + ], + "5146": [ + "[$-1141A]hh:mm:ss;@", + "[$-1141A]hh:mm;@" + ], + "5179": [ + "[$-1143B]hh:mm:ss;@", + "[$-1143B]h:mm:ss;@", + "[$-1143B]hh:mm;@", + "[$-1143B]h:mm;@" + ], + "6153": [ + "hh:mm:ss;@", + "h:mm:ss;@" + ], + "6154": [ + "[$-180A]hh:mm:ss AM/PM;@", + "[$-180A]h:mm:ss AM/PM;@", + "h:mm:ss;@", + "hh:mm:ss;@" + ], + "6156": [ + "hh:mm:ss;@", + "h:mm:ss;@", + "hh.mm;@", + "hh\" h \"mm;@" + ], + "6170": [ + "[$-1181A]hh:mm:ss;@", + "[$-1181A]hh:mm;@" + ], + "6203": [ + "[$-1183B]hh:mm:ss;@", + "[$-1183B]h:mm:ss;@", + "[$-1183B]hh:mm;@", + "[$-1183B]h:mm;@" + ], + "7177": [ + "[$-409]hh:mm:ss AM/PM;@", + "hh:mm:ss;@" + ], + "7178": [ + "[$-1C0A]hh:mm:ss AM/PM;@", + "[$-1C0A]h:mm:ss AM/PM;@", + "h:mm:ss;@", + "hh:mm:ss;@" + ], + "7180": [ + "[$-11C0C]hh:mm:ss;@", + "[$-11C0C]h:mm:ss;@", + "[$-11C0C]hh:mm;@", + "[$-11C0C]h:mm;@" + ], + "7194": [ + "h:mm:ss;@", + "hh:mm:ss;@" + ], + "7227": [ + "[$-11C3B]hh:mm:ss;@", + "[$-11C3B]h:mm:ss;@", + "[$-11C3B]hh:mm;@", + "[$-11C3B]h:mm;@" + ], + "8201": [ + "[$-409]hh:mm:ss AM/PM;@", + "[$-409]h:mm:ss AM/PM;@", + "h:mm:ss;@", + "hh:mm:ss;@" + ], + "8202": [ + "[$-200A]hh:mm:ss AM/PM;@", + "[$-200A]h:mm:ss AM/PM;@", + "h:mm:ss;@", + "hh:mm:ss;@" + ], + "8204": [ + "[$-1200C]hh:mm:ss;@", + "[$-1200C]hh:mm;@" + ], + "8218": [ + "[$-1201A]h:mm:ss;@", + "[$-1201A]hh:mm:ss;@", + "[$-1201A]h:mm;@", + "[$-1201A]hh:mm;@" + ], + "8251": [ + "[$-1203B]h:mm:ss;@", + "[$-1203B]hh:mm:ss;@", + "[$-1203B]h:mm;@", + "[$-1203B]hh:mm;@" + ], + "9225": [ + "[$-409]h:mm:ss AM/PM;@", + "[$-409]hh:mm:ss AM/PM;@", + "h:mm:ss;@", + "hh:mm:ss;@" + ], + "9226": [ + "[$-240A]hh:mm:ss AM/PM;@", + "[$-240A]h:mm:ss AM/PM;@", + "h:mm:ss;@", + "hh:mm:ss;@" + ], + "9228": [ + "[$-1240C]hh:mm:ss;@", + "[$-1240C]hh:mm;@" + ], + "9242": [ + "h:mm:ss;@", + "hh:mm:ss;@" + ], + "9275": [ + "[$-1243B]h:mm:ss;@", + "[$-1243B]hh:mm:ss;@", + "[$-1243B]h:mm;@", + "[$-1243B]hh:mm;@" + ], + "10249": [ + "[$-409]hh:mm:ss AM/PM;@", + "hh:mm:ss;@" + ], + "10250": [ + "[$-280A]hh:mm:ss AM/PM;@", + "[$-280A]h:mm:ss AM/PM;@", + "h:mm:ss;@", + "hh:mm:ss;@" + ], + "10252": [ + "[$-1280C]hh:mm:ss;@", + "[$-1280C]hh:mm;@" + ], + "10266": [ + "h:mm:ss;@", + "hh:mm:ss;@" + ], + "11273": [ + "[$-409]hh:mm:ss AM/PM;@", + "hh:mm:ss;@" + ], + "11274": [ + "[$-2C0A]hh:mm:ss AM/PM;@", + "[$-2C0A]h:mm:ss AM/PM;@", + "hh:mm:ss;@", + "h:mm:ss;@" + ], + "11276": [ + "[$-12C0C]hh:mm:ss;@", + "[$-12C0C]hh:mm;@" + ], + "12297": [ + "[$-409]h:mm:ss AM/PM;@", + "[$-409]hh:mm:ss AM/PM;@", + "h:mm:ss;@", + "hh:mm:ss;@" + ], + "12298": [ + "h:mm:ss;@", + "hh:mm:ss;@" + ], + "12300": [ + "[$-1300C]hh:mm:ss;@", + "[$-1300C]hh:mm;@" + ], + "13321": [ + "[$-409]h:mm:ss AM/PM;@", + "[$-409]hh:mm:ss AM/PM;@", + "h:mm:ss;@", + "hh:mm:ss;@" + ], + "13322": [ + "h:mm:ss;@", + "hh:mm:ss;@" + ], + "13324": [ + "[$-1340C]hh:mm:ss;@", + "[$-1340C]hh:mm;@" + ], + "14345": [ + "[$-13809]hh:mm:ss;@", + "[$-13809]h:mm:ss;@", + "[$-13809]hh:mm;@", + "[$-13809]h:mm;@" + ], + "14346": [ + "[$-380A]hh:mm:ss AM/PM;@", + "[$-380A]h:mm:ss AM/PM;@", + "h:mm:ss;@", + "hh:mm:ss;@" + ], + "14348": [ + "[$-1380C]hh:mm:ss;@", + "[$-1380C]hh:mm;@" + ], + "15369": [ + "[$-10409]h:mm:ss AM/PM;@", + "[$-13C09]hh:mm:ss;@", + "[$-10409]h:mm AM/PM;@", + "[$-13C09]hh:mm;@" + ], + "15370": [ + "[$-3C0A]hh:mm:ss AM/PM;@", + "[$-3C0A]h:mm:ss AM/PM;@", + "h:mm:ss;@", + "hh:mm:ss;@" + ], + "15372": [ + "[$-13C0C]hh:mm:ss;@", + "[$-13C0C]hh:mm;@" + ], + "16393": [ + "[$-14009]hh:mm:ss;@", + "[$-14009]h:mm:ss;@", + "[$-10409]h.mm.ss AM/PM;@", + "[$-10409]hh:mm:ss AM/PM;@", + "[$-14009]hh:mm;@", + "[$-14009]h:mm;@", + "[$-10409]hh:mm AM/PM;@" + ], + "16394": [ + "[$-400A]hh:mm:ss AM/PM;@", + "[$-400A]h:mm:ss AM/PM;@", + "h:mm:ss;@", + "hh:mm:ss;@" + ], + "17417": [ + "[$-10409]h:mm:ss AM/PM;@", + "[$-10409]hh:mm:ss AM/PM;@", + "[$-14409]h:mm:ss;@", + "[$-14409]hh:mm:ss;@", + "[$-10409]h:mm AM/PM;@", + "[$-10409]hh:mm AM/PM;@", + "[$-14409]h:mm;@", + "[$-14409]hh:mm;@" + ], + "17418": [ + "[$-440A]hh:mm:ss AM/PM;@", + "hh:mm:ss;@" + ], + "18441": [ + "[$-10409]h:mm:ss AM/PM;@", + "[$-14809]hh:mm:ss;@", + "[$-10409]h:mm AM/PM;@", + "[$-14809]hh:mm;@" + ], + "18442": [ + "[$-480A]hh:mm:ss AM/PM;@", + "hh:mm:ss;@" + ], + "19466": [ + "[$-4C0A]hh:mm:ss AM/PM;@", + "hh:mm:ss;@" + ], + "20490": [ + "[$-500A]hh:mm:ss AM/PM;@", + "hh:mm:ss;@" + ], + "21514": [ + "[$-10409]h:mm:ss AM/PM;@", + "[$-10409]hh:mm:ss AM/PM;@", + "[$-1540A]h:mm:ss;@", + "[$-1540A]hh:mm:ss;@", + "[$-10409]h:mm AM/PM;@", + "[$-10409]hh:mm AM/PM;@", + "[$-1540A]h:mm;@", + "[$-1540A]hh:mm;@" + ], + "22538": [ + "[$-580A]hh:mm:ss AM/PM;@", + "[$-580A]h:mm:ss AM/PM;@", + "h:mm:ss;@", + "hh:mm:ss;@" + ], + "64546": [ + "h:mm:ss;@", + "hh:mm:ss;@" + ], + "64547": [ + "h:mm:ss;@", + "hh:mm:ss;@" + ], + "64551": [ + "hh:mm:ss;@", + "hh:mm;@" + ] +} +missing:[123,124,147,162,235,238,259] +duplicate_line_to_lcid:{ + "6": "1033-[$-2000409]", + "7": "1033-[$-2000409]", + "8": "1033-[$-2000409]", + "9": "1033-[$-2000409]", + "10": "1033-[$-2000409]", + "11": "1033-[$-2000409]", + "12": "1033-[$-2000409]", + "13": "1033-[$-2000409]", + "14": "1033-[$-2000409]", + "15": "1033-[$-2000409]", + "16": "1033-[$-2000409]", + "17": "1033-[$-2000409]", + "18": "1033-[$-2000409]", + "19": "1033-[$-2000409]", + "20": "1033-[$-2000409]", + "72": "1033-[$-409]", + "122": "1033-[$-409]", + "173": "1033-[$-3000409]", + "177": "1033-[$-409]", + "193": "3098-[$-C1A]", + "197": "2074-[$-81A]", + "203": "1033-[$-409]", + "242": "1097-[$-449]", + "250": "1055-[$-41F]", + "255": "1033-[$-409]", + "260": "1027-[$-403]" +} \ No newline at end of file diff --git a/Test/Applications/ParseExcelNumberFormatLocales/ParseDateTimeList/get-lcid-from-format.js b/Test/Applications/ParseExcelNumberFormatLocales/ParseDateTimeList/get-lcid-from-format.js new file mode 100644 index 00000000000..3a264c2edd0 --- /dev/null +++ b/Test/Applications/ParseExcelNumberFormatLocales/ParseDateTimeList/get-lcid-from-format.js @@ -0,0 +1,126 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ + +'use strict'; +const { readFile, writeFile } = require("node:fs/promises"); + +async function startTest() { + let args = process.argv.slice(2); + if (args.length < 3) { + console.error(`missing arguments.USAGE: ${process.argv[0]} "in-time.csv" "in-date.csv" "out.json"`); + return; + } + console.info("test started"); + + let missing = []; + let duplicates = {}; + let unique = {}; + + let outLineMap = {}; + let outDates = {}; + let outTimes = {}; + let textDate = await readFile(args[0], {encoding: 'utf8'}); + let linesDate = textDate.split('\n'); + let textTime = await readFile(args[1], {encoding: 'utf8'}); + let linesTime = textTime.split('\n'); + for (let i = 0; i < linesDate.length && i < linesTime.length; ++i) { + // console.log(i) + outLineMap[i] = 0; + let lineDate = linesDate[i]; + lineDate = lineDate.replace(/[\r\,]*$/, ""); + lineDate = lineDate.replace(/\\/g, '\\\\'); + lineDate = lineDate.replace(/\"\"\"/g, '"\\"'); + lineDate = lineDate.replace(/\"\"/g, '\\"'); + let lineTime = linesTime[i]; + lineTime = lineTime.replace(/[\r\,]*$/, ""); + lineTime = lineTime.replace(/\\/g, '\\\\'); + lineTime = lineTime.replace(/\"\"\"/g, '"\\"'); + lineTime = lineTime.replace(/\"\"/g, '\\"'); + + let found = lineDate.match(/\[\$-([A-F0-9]*)\]/g); + if (!found) { + found = lineTime.match(/\[\$-([A-F0-9]*)\]/g); + } else { + let foundTime = lineTime.match(/\[\$-([A-F0-9]*)\]/g); + if (foundTime) { + found = found.concat(foundTime); + } + } + if (found) { + let LCID = 0; + let LCIDOrigin = 0; + for (let j = 0; j < found.length; ++j) { + let test = parseInt(found[j].substring(3), 16) & 0xFFFF; + if (test > 0) { + LCID = test; + LCIDOrigin = found[j] + if(!unique[LCID]) { + break; + } + } + } + // console.log(LCID); + if(LCID > 0) { + if(!unique[LCID]) { + unique[LCID] = 1; + outLineMap[i] = LCID; + outDates[LCID] = JSON.parse(`[${lineDate}]`); + outTimes[LCID] = JSON.parse(`[${lineTime}]`); + } else { + duplicates[i] = LCID + "-" + LCIDOrigin; + } + } else { + missing.push(i); + } + } else { + missing.push(i); + } + } + let res = []; + res.push(JSON.stringify(outLineMap, null, 2)); + res.push(JSON.stringify(outDates, null, 2)); + res.push(JSON.stringify(outTimes, null, 2)); + res.push('missing:' + JSON.stringify(missing)); + res.push('duplicate_line_to_lcid:' + JSON.stringify(duplicates, null, 2)); + + await writeFile(args[2], res.join('\n'), {encoding: 'utf8'}); + + console.info("test finished"); +} + +startTest().then(()=>{ + //delay to log observer events +}).catch((err) => { + console.error(err.stack); +}).finally(() => { + process.exit(0); +}); diff --git a/Test/Applications/ParseExcelNumberFormatLocales/ParseDateTimeList/macro-formats-date-template.xlsm b/Test/Applications/ParseExcelNumberFormatLocales/ParseDateTimeList/macro-formats-date-template.xlsm new file mode 100644 index 00000000000..141eabe9a96 Binary files /dev/null and b/Test/Applications/ParseExcelNumberFormatLocales/ParseDateTimeList/macro-formats-date-template.xlsm differ diff --git a/Test/Applications/ParseLogs/ParseLogs/Program.cs b/Test/Applications/ParseLogs/ParseLogs/Program.cs index e137c1e5615..4bb3a4fd514 100644 --- a/Test/Applications/ParseLogs/ParseLogs/Program.cs +++ b/Test/Applications/ParseLogs/ParseLogs/Program.cs @@ -15,17 +15,18 @@ static bool processFile(string filename, bool start, Dictionary uni string logMessage = ""; foreach (var line in File.ReadLines(filename)) { + var _line = line.Replace("\\n", "\n"); if (!start) { - if (line.Contains("[ERROR] nodeJS - changesError")) + if (_line.Contains("changesError:")) { key = ""; logMessage = ""; - int indexStart = line.IndexOf(" Error: "); + int indexStart = _line.IndexOf("Error:"); if (-1 != indexStart) { - key = line.Substring(indexStart); - int indexEnd = key.IndexOf(" userAgent: "); + key = _line.Substring(indexStart); + int indexEnd = key.IndexOf("userAgent:"); if (-1 != indexEnd) { key = key.Substring(0, indexEnd); @@ -38,7 +39,7 @@ static bool processFile(string filename, bool start, Dictionary uni unique[key] = 1; } start = true; - logMessage += line; + logMessage += _line; logMessage += '\n'; } } @@ -47,7 +48,7 @@ static bool processFile(string filename, bool start, Dictionary uni { if ("" == key) { - key = line; + key = _line; if (!unique.ContainsKey(key)) { unique[key] = 1; @@ -58,9 +59,9 @@ static bool processFile(string filename, bool start, Dictionary uni continue; } } - if (!line.StartsWith("[")) + if (!_line.StartsWith("202") && !line.StartsWith("[202") && !_line.StartsWith("\"{\"\"startTime") && !_line.StartsWith("{\"\"startTime")) { - logMessage += line; + logMessage += _line; logMessage += '\n'; } else @@ -76,9 +77,9 @@ static bool processFile(string filename, bool start, Dictionary uni } static void Main(string[] args) { - string inputDir = @"D:\logs\doc.onlyoffice.com\sync\logs\docservice"; - string outputFile = @"D:\logs\doc.onlyoffice.com\sync\changesError.txt"; - string startDate = "out.log-20200601"; + //string inputDir = @"D:\logs\doc.onlyoffice.eu\7.3.2\log2"; + string inputDir = @"D:\logs\doc.onlyoffice.eu\7.4.0\log"; + string outputFile = @"D:\logs\doc.onlyoffice.eu\7.4.0\changesError.txt"; using (StreamWriter writetext = new StreamWriter(outputFile)) { Dictionary unique = new Dictionary(); @@ -87,12 +88,8 @@ static void Main(string[] args) Array.Sort(fileNames, StringComparer.InvariantCulture); foreach (string file in fileNames) { - if (String.Compare(Path.GetFileName(file), startDate) >= 0) - { start = processFile(file, start, unique, writetext); - } } - start = processFile(Path.Combine(inputDir, "out.log"), start, unique, writetext); } } } diff --git a/Test/Applications/StandardTester/main.cpp b/Test/Applications/StandardTester/main.cpp index d68817925d8..d109d0eeb34 100644 --- a/Test/Applications/StandardTester/main.cpp +++ b/Test/Applications/StandardTester/main.cpp @@ -27,6 +27,19 @@ enum CheckResultCode bool g_save_x2t_xml = false; +int GetPagesCount(const std::wstring& dir) +{ + int nCount = 0; + std::vector files = NSDirectory::GetFiles(dir, false); + for (std::vector::iterator i = files.begin(); i != files.end(); i++) + { + std::wstring sExt = NSFile::GetFileExtention(*i); + if (sExt == L"png") + ++nCount; + } + return nCount; +} + class CConverter; class CInternalWorker { @@ -63,6 +76,7 @@ class CInternalWorker bool m_bIsStandard; bool m_bIsDiffAllInOne; + bool m_bDiffOnly{false}; NSCriticalSection::CRITICAL_SECTION m_oCS; NSCriticalSection::CRITICAL_SECTION m_oCS_OfficeUtils; @@ -96,6 +110,13 @@ class CInternalWorker m_formats.insert(std::make_pair(AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_XPS, true)); m_formats.insert(std::make_pair(AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_DJVU, true)); + m_formats.insert(std::make_pair(AVS_OFFICESTUDIO_FILE_DRAW_VSDX, true)); + m_formats.insert(std::make_pair(AVS_OFFICESTUDIO_FILE_DRAW_VSSX, true)); + m_formats.insert(std::make_pair(AVS_OFFICESTUDIO_FILE_DRAW_VSTX, true)); + m_formats.insert(std::make_pair(AVS_OFFICESTUDIO_FILE_DRAW_VSDM, true)); + m_formats.insert(std::make_pair(AVS_OFFICESTUDIO_FILE_DRAW_VSSM, true)); + m_formats.insert(std::make_pair(AVS_OFFICESTUDIO_FILE_DRAW_VSTM, true)); + m_nCount = 0; m_nCurrent = 0; m_nCurrentComplete = 0; @@ -121,6 +142,7 @@ class CInternalWorker void OpenDir(std::wstring sDir) { m_sInputFolder = sDir; + std::vector arFiles = NSDirectory::GetFiles(sDir, true); for (std::vector::iterator iter = arFiles.begin(); iter != arFiles.end(); iter++) { @@ -129,7 +151,8 @@ class CInternalWorker if (sExt == L"docx" || sExt == L"doc" || sExt == L"odt" || sExt == L"rtf" || sExt == L"docxf" || sExt == L"oform" || sExt == L"pptx" || sExt == L"ppt" || sExt == L"odp" || sExt == L"xlsx" || sExt == L"xls" || sExt == L"ods" || - sExt == L"pdf" || sExt == L"xps" || sExt == L"djvu") + sExt == L"pdf" || sExt == L"xps" || sExt == L"djvu" || + sExt == L"vsdx") { m_files.push_back(*iter); } @@ -268,15 +291,237 @@ class CInternalWorker NSFile::CFileBinary::SaveToFile(sLogFile, sLogContent, true); } + + int GenerateDiff(const std::wstring strDirIn, const std::wstring strDirOut, const std::wstring strDiffs) + { + int nCountInPages = GetPagesCount(strDirIn); + int nCountOutPages = GetPagesCount(strDirOut); + int checkCode = crcEqual; + + if (nCountInPages != nCountOutPages) + { + if (nCountInPages > nCountOutPages) + nCountInPages = nCountOutPages; + + if (!NSDirectory::Exists(strDiffs)) + NSDirectory::CreateDirectories(CorrectPathW(strDiffs)); + + std::wstring sFilePagesDiff = strDiffs + L"/pages_count"; + NSFile::CFileBinary oFile; + oFile.CreateFileW(sFilePagesDiff); + oFile.CloseFile(); + + checkCode |= crcPageCount; + } + + 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(strDiffs)) + NSDirectory::CreateDirectories(CorrectPathW(strDiffs)); + + std::wstring sFilePagesDiff = sPageDiff; + NSFile::CFileBinary oFile; + oFile.CreateFileW(sPageDiff); + oFile.WriteStringUTF8(L"sizes!"); + oFile.CloseFile(); + + checkCode |= crcPageSize; + 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; + + int nEpsilonEps = 3; + int nEpsilonNatural = 5; + + int nDivExist = 0; + for (int indexPixH = 0; indexPixH < nH_I; indexPixH++) + { + for (int indexPixW = 0; indexPixW < nW_I; indexPixW++) + { + if (pDataI[0] != pDataO[0] || pDataI[1] != pDataO[1] || pDataI[2] != pDataO[2]) + { + // test epsilon natural + if ((abs(pDataI[0] - pDataO[0]) < nEpsilonNatural) && + (abs(pDataI[1] - pDataO[1]) < nEpsilonNatural) && + (abs(pDataI[2] - pDataO[2]) < nEpsilonNatural)) + { + pDataI += 4; + pDataO += 4; + continue; + } + + // test epsilon left, right, top, bottom + int nEpsUp = nEpsilonEps; + if (indexPixH > 0) + { + BYTE* pByteI = frameI.get_Data() + 4 * (indexPixH - 1) * nW_I + 4 * indexPixW; + + if ((abs(pByteI[0] - pDataO[0]) < nEpsilonEps) && + (abs(pByteI[1] - pDataO[1]) < nEpsilonEps) && + (abs(pByteI[2] - pDataO[2]) < nEpsilonEps)) + { + nEpsUp = nEpsilonEps - 1; + } + } + + int nEpsDown = nEpsilonEps; + if (indexPixH < (nH_I - 1)) + { + BYTE* pByteI = frameI.get_Data() + 4 * (indexPixH + 1) * nW_I + 4 * indexPixW; + + if ((abs(pByteI[0] - pDataO[0]) < nEpsilonEps) && + (abs(pByteI[1] - pDataO[1]) < nEpsilonEps) && + (abs(pByteI[2] - pDataO[2]) < nEpsilonEps)) + { + nEpsDown = nEpsilonEps - 1; + } + } + + int nEpsLeft = nEpsilonEps; + if (indexPixW > 0) + { + BYTE* pByteI = pDataI - 4; + + if ((abs(pByteI[0] - pDataO[0]) < nEpsilonEps) && + (abs(pByteI[1] - pDataO[1]) < nEpsilonEps) && + (abs(pByteI[2] - pDataO[2]) < nEpsilonEps)) + { + nEpsLeft = nEpsilonEps - 1; + } + } + + int nEpsRight = nEpsilonEps; + if (indexPixW < (nW_I - 1)) + { + BYTE* pByteI = pDataI + 4; + + if ((abs(pByteI[0] - pDataO[0]) < nEpsilonEps) && + (abs(pByteI[1] - pDataO[1]) < nEpsilonEps) && + (abs(pByteI[2] - pDataO[2]) < nEpsilonEps)) + { + nEpsRight = nEpsilonEps - 1; + } + } + + if ((nEpsLeft < nEpsilonEps) || + (nEpsRight < nEpsilonEps) || + (nEpsUp < nEpsilonEps) || + (nEpsDown < nEpsilonEps)) + { + pDataI += 4; + pDataO += 4; + continue; + } + + ++nDivExist; + + 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 (nDivExist > 7) + { + if (!NSDirectory::Exists(strDiffs)) + NSDirectory::CreateDirectories(CorrectPathW(strDiffs)); + + if (!m_bIsDiffAllInOne) + { + frameO.SaveFile(sPageDiff, 4); + } + else + { + CBgraFrame frameOSrc; + frameOSrc.OpenFile(sPageO); + + BYTE* pData1 = frameI.get_Data(); + BYTE* pData2 = frameOSrc.get_Data(); + BYTE* pData3 = frameO.get_Data(); + + int nRowW = 4 * nW_I; + BYTE* pDataAll = new BYTE[3 * nRowW * nH_I]; + BYTE* pDataAllSrc = pDataAll; + for (int j = 0; j < nH_I; j++) + { + memcpy(pDataAll, pData1, nRowW); + pDataAll += nRowW; + pData1 += nRowW; + + memcpy(pDataAll, pData2, nRowW); + pDataAll += nRowW; + pData2 += nRowW; + + memcpy(pDataAll, pData3, nRowW); + pDataAll += nRowW; + pData3 += nRowW; + } + + CBgraFrame oFrameAll; + oFrameAll.put_Data(pDataAllSrc); + oFrameAll.put_Width(3 * nW_I); + oFrameAll.put_Height(nH_I); + oFrameAll.put_Stride(-3 * nRowW); + oFrameAll.SaveFile(sPageDiff, 4); + } + + checkCode |= crcPageDiffs; + } + } + return checkCode; + } }; class CConverter : public NSThreads::CBaseThread { public: CInternalWorker* m_pInternal; + + std::wstring m_input_dir; + std::wstring m_output_dir; + std::wstring m_file; std::wstring m_folder_dst; int m_format; + bool m_bDiffOnly{false}; public: CConverter(CInternalWorker* pWorker) : NSThreads::CBaseThread() @@ -289,8 +534,48 @@ class CConverter : public NSThreads::CBaseThread Stop(); } + std::wstring GetOutputFile(const std::wstring& sFolderAddon = L"", const bool& isStandart = false) + { + std::wstring input_dir = m_input_dir; + NSStringUtils::string_replace(input_dir, L"\\", L"/"); + + std::wstring input_file = m_file; + NSStringUtils::string_replace(input_file, L"\\", L"/"); + + std::wstring output_dir = isStandart ? (m_input_dir + L"/../out/master") : (m_output_dir + L"/"); + if (!sFolderAddon.empty()) + output_dir += (sFolderAddon + L"/"); + + NSStringUtils::string_replace(output_dir, L"\\", L"/"); + NSStringUtils::string_replace(output_dir, L"//", L"/"); + + std::wstring output_file = output_dir + input_file.substr(input_dir.length()); + + NSStringUtils::string_replace(output_file, L"//", L"/"); + +#ifdef _WIN32 + NSStringUtils::string_replace(output_file, L"/", L"\\"); +#endif + + return output_file; + } + virtual DWORD ThreadProc() { + if (m_bDiffOnly) + { + std::wstring strDirIn = GetOutputFile(L"", true); + std::wstring strDirOut = m_folder_dst; + + std::wstring strDiffs = GetOutputFile(L"DIFF"); + + int checkCode = m_pInternal->GenerateDiff(strDirIn, strDirOut, strDiffs); + + m_bRunThread = FALSE; + m_pInternal->OnConvertFile(this, 0, 0, checkCode); + + return 0; + } bool bIsOfficeFile = true; if (true) { @@ -387,229 +672,11 @@ class CConverter : public NSThreads::CBaseThread if (!m_pInternal->m_bIsStandard) { // смотрим разницу - std::wstring strDirIn = NSFile::GetDirectoryName(m_file); + std::wstring strDirIn = GetOutputFile(L"", true); 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(); - - checkCode |= crcPageCount; - } - - 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(); - - checkCode |= crcPageSize; - 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; - - int nEpsilonEps = 3; - int nEpsilonNatural = 5; - - int nDivExist = 0; - for (int indexPixH = 0; indexPixH < nH_I; indexPixH++) - { - for (int indexPixW = 0; indexPixW < nW_I; indexPixW++) - { - if (pDataI[0] != pDataO[0] || pDataI[1] != pDataO[1] || pDataI[2] != pDataO[2]) - { - // test epsilon natural - if ((abs(pDataI[0] - pDataO[0]) < nEpsilonNatural) && - (abs(pDataI[1] - pDataO[1]) < nEpsilonNatural) && - (abs(pDataI[2] - pDataO[2]) < nEpsilonNatural)) - { - pDataI += 4; - pDataO += 4; - continue; - } - - // test epsilon left, right, top, bottom - int nEpsUp = nEpsilonEps; - if (indexPixH > 0) - { - BYTE* pByteI = frameI.get_Data() + 4 * (indexPixH - 1) * nW_I + 4 * indexPixW; - - if ((abs(pByteI[0] - pDataO[0]) < nEpsilonEps) && - (abs(pByteI[1] - pDataO[1]) < nEpsilonEps) && - (abs(pByteI[2] - pDataO[2]) < nEpsilonEps)) - { - nEpsUp = nEpsilonEps - 1; - } - } - - int nEpsDown = nEpsilonEps; - if (indexPixH < (nH_I - 1)) - { - BYTE* pByteI = frameI.get_Data() + 4 * (indexPixH + 1) * nW_I + 4 * indexPixW; - - if ((abs(pByteI[0] - pDataO[0]) < nEpsilonEps) && - (abs(pByteI[1] - pDataO[1]) < nEpsilonEps) && - (abs(pByteI[2] - pDataO[2]) < nEpsilonEps)) - { - nEpsDown = nEpsilonEps - 1; - } - } - - int nEpsLeft = nEpsilonEps; - if (indexPixW > 0) - { - BYTE* pByteI = pDataI - 4; - - if ((abs(pByteI[0] - pDataO[0]) < nEpsilonEps) && - (abs(pByteI[1] - pDataO[1]) < nEpsilonEps) && - (abs(pByteI[2] - pDataO[2]) < nEpsilonEps)) - { - nEpsLeft = nEpsilonEps - 1; - } - } - - int nEpsRight = nEpsilonEps; - if (indexPixW < (nW_I - 1)) - { - BYTE* pByteI = pDataI + 4; - - if ((abs(pByteI[0] - pDataO[0]) < nEpsilonEps) && - (abs(pByteI[1] - pDataO[1]) < nEpsilonEps) && - (abs(pByteI[2] - pDataO[2]) < nEpsilonEps)) - { - nEpsRight = nEpsilonEps - 1; - } - } - - if ((nEpsLeft < nEpsilonEps) || - (nEpsRight < nEpsilonEps) || - (nEpsUp < nEpsilonEps) || - (nEpsDown < nEpsilonEps)) - { - pDataI += 4; - pDataO += 4; - continue; - } - - ++nDivExist; - - 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 (nDivExist > 7) - { - if (!NSDirectory::Exists(strDiffsMain)) - NSDirectory::CreateDirectory(strDiffsMain); - if (!NSDirectory::Exists(strDiffs)) - NSDirectory::CreateDirectory(strDiffs); - - if (!m_pInternal->m_bIsDiffAllInOne) - { - frameO.SaveFile(sPageDiff, 4); - } - else - { - CBgraFrame frameOSrc; - frameOSrc.OpenFile(sPageO); - - BYTE* pData1 = frameI.get_Data(); - BYTE* pData2 = frameOSrc.get_Data(); - BYTE* pData3 = frameO.get_Data(); - - int nRowW = 4 * nW_I; - BYTE* pDataAll = new BYTE[3 * nRowW * nH_I]; - BYTE* pDataAllSrc = pDataAll; - for (int j = 0; j < nH_I; j++) - { - memcpy(pDataAll, pData1, nRowW); - pDataAll += nRowW; - pData1 += nRowW; - - memcpy(pDataAll, pData2, nRowW); - pDataAll += nRowW; - pData2 += nRowW; - - memcpy(pDataAll, pData3, nRowW); - pDataAll += nRowW; - pData3 += nRowW; - } - - CBgraFrame oFrameAll; - oFrameAll.put_Data(pDataAllSrc); - oFrameAll.put_Width(3 * nW_I); - oFrameAll.put_Height(nH_I); - oFrameAll.put_Stride(-3 * nRowW); - oFrameAll.SaveFile(sPageDiff, 4); - } - - checkCode |= crcPageDiffs; - } - } + std::wstring strDiffs = GetOutputFile(L"DIFF"); + checkCode = m_pInternal->GenerateDiff(strDirIn, strDirOut, strDiffs); } m_bRunThread = FALSE; @@ -617,19 +684,6 @@ class CConverter : public NSThreads::CBaseThread m_pInternal->OnConvertFile(this, nReturnCode, (int)(dwTime2 - dwTime1), checkCode); return 0; } - - int GetPagesCount(const std::wstring& dir) - { - int nCount = 0; - std::vector files = NSDirectory::GetFiles(dir, false); - for (std::vector::iterator i = files.begin(); i != files.end(); i++) - { - std::wstring sExt = NSFile::GetFileExtention(*i); - if (sExt == L"png") - ++nCount; - } - return nCount; - } }; CConverter* CInternalWorker::GetNextConverter() @@ -639,12 +693,18 @@ CConverter* CInternalWorker::GetNextConverter() CConverter* pConverter = new CConverter(this); pConverter->DestroyOnFinish(); + + pConverter->m_input_dir = m_sInputFolder; + pConverter->m_output_dir = m_sOutputFolder; + pConverter->m_file = m_files[m_nCurrent]; + pConverter->m_bDiffOnly = m_bDiffOnly; ++m_nCurrent; std::wstring sName = NSFile::GetFileName(pConverter->m_file); - pConverter->m_folder_dst = m_sOutputFolder + L"/" + sName; - NSDirectory::CreateDirectory(pConverter->m_folder_dst); + pConverter->m_folder_dst = pConverter->GetOutputFile(); + + NSDirectory::CreateDirectories(pConverter->m_folder_dst); if (m_bIsStandard) NSFile::CFileBinary::Copy(pConverter->m_file, pConverter->m_folder_dst + L"/" + sName); @@ -737,6 +797,7 @@ int main(int argc, char** argv) { std::vector arFontsDirs; bool bIsStandard = false; + bool bDiffOnly = false; std::wstring strInputFolder = L""; std::wstring strOutputFolder = L""; bool bIsUseSystemFonts = true; @@ -780,6 +841,10 @@ int main(int argc, char** argv) { bIsStandard = true; } + else if (sKey == L"--diff-only") + { + bDiffOnly = true; + } else if (sKey == L"--use-system-fonts") { if (sValue == L"0" || sValue == L"false") @@ -853,6 +918,7 @@ int main(int argc, char** argv) #endif CInternalWorker oWorker; + oWorker.m_bDiffOnly = bDiffOnly; oWorker.OpenDir(strInputFolder); oWorker.m_sOutputFolder = strOutputFolder; oWorker.m_bIsStandard = bIsStandard; diff --git a/Test/Applications/TestDocsWithChart/TestDocsWithChart/Program.cs b/Test/Applications/TestDocsWithChart/TestDocsWithChart/Program.cs index 07a47797b2f..078d17e9554 100644 --- a/Test/Applications/TestDocsWithChart/TestDocsWithChart/Program.cs +++ b/Test/Applications/TestDocsWithChart/TestDocsWithChart/Program.cs @@ -63,7 +63,8 @@ static void Main(string[] args) //getGradientPos(); //getCAFiles(); //getSlicerFiles(); - getNamedSheetView(); + //getNamedSheetView(); + getExternalMasters(); } static void getFilesPivot() { @@ -437,7 +438,30 @@ static void getNamedSheetView() catch { } } } - + static void getExternalMasters() + { + string sDirInput = @"D:\Files\xlsx-testers"; + string sDirOutput = @"D:\Files\external-masters"; + String[] allfiles = System.IO.Directory.GetFiles(sDirInput, "*.*", System.IO.SearchOption.AllDirectories); + for (var i = 0; i < allfiles.Length; ++i) + { + string file = allfiles[i]; + try + { + ZipArchive zip = ZipFile.OpenRead(file); + foreach (ZipArchiveEntry entry in zip.Entries) + { + if (entry.FullName.Contains("externalLink")) + { + System.IO.File.Copy(file, Path.Combine(sDirOutput, Path.GetFileName(file)), true); + break; + } + } + } + catch { } + } + } + static void getFilesConditional() { diff --git a/Test/Applications/gradient/Gradient/Gradient.pro b/Test/Applications/gradient/Gradient/Gradient.pro index f3412898485..cfad92ed6f4 100644 --- a/Test/Applications/gradient/Gradient/Gradient.pro +++ b/Test/Applications/gradient/Gradient/Gradient.pro @@ -1,5 +1,7 @@ QT += core gui widgets +QMAKE_CXXFLAGS += /permissive- + SOURCES += \ main.cpp \ mainwindow.cpp @@ -14,10 +16,5 @@ PWD_ROOT_DIR = $$PWD CORE_ROOT_DIR = $$PWD/../../../../../core include($$CORE_ROOT_DIR/Common/base.pri) -ADD_DEPENDENCY(kernel, graphics, UnicodeConverter) -ADD_DEPENDENCY(PdfReader) -ADD_DEPENDENCY(HtmlRenderer) +ADD_DEPENDENCY(kernel, graphics, UnicodeConverter, PdfFile) core_linux:include($$CORE_ROOT_DIR/Common/3dParty/icu/icu.pri) - -LIBS += -L$$CORE_BUILDS_LIBRARIES_PATH -lkernel -lgraphics - diff --git a/Test/Applications/gradient/Gradient/main.cpp b/Test/Applications/gradient/Gradient/main.cpp index 7c9d4c93b5e..d0857b28b15 100644 --- a/Test/Applications/gradient/Gradient/main.cpp +++ b/Test/Applications/gradient/Gradient/main.cpp @@ -1,11 +1,10 @@ #include "mainwindow.h" -#include #include -#include "../../../../DesktopEditor/graphics/pro/Graphics.h" + int main(int argc, char *argv[]) { - QApplication a(argc, argv ); - MainWindow w; - w.show(); - return a.exec(); + QApplication a(argc, argv); + MainWindow w; + w.show(); + return a.exec(); } diff --git a/Test/Applications/gradient/Gradient/mainwindow.cpp b/Test/Applications/gradient/Gradient/mainwindow.cpp index f597ed98f99..d01fd8ab223 100644 --- a/Test/Applications/gradient/Gradient/mainwindow.cpp +++ b/Test/Applications/gradient/Gradient/mainwindow.cpp @@ -1,630 +1,481 @@ #include "mainwindow.h" #include "ui_mainwindow.h" -#include -#include + #include "../../../../DesktopEditor/graphics/pro/Graphics.h" -#include "../../../../DesktopEditor/fontengine/ApplicationFontsWorker.h" -#include "../../../../DesktopEditor/common/Directory.h" -#include "../../../../PdfReader/PdfReader.h" - -std::vector drawCircle1(int n, double cx, double cy, double r) { - std::vector res; - for (int i = 0; i < n; i++) { - double x = cx + r * cos(i * 8 * atan(1) / n); - double y = cy + r * sin(i * 8 * atan(1) / n); - res.push_back({x, y}); - } - return res; -} +#include "../../../../PdfFile/PdfFile.h" -MainWindow::MainWindow(QWidget *parent) - : QMainWindow(parent) - , ui(new Ui::MainWindow) - , img("test.png") - , lable(new QLabel) +MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow), img("test.png") { - ui->setupUi(this); - ui->lable_test->setStyleSheet("QLabel { background-color : white;}"); - points = {{0, 0}, {105, 0}, {105, 105}, {0, 105}}; -} + ui->setupUi(this); + listOfLines = ui->centralwidget->findChildren(); + listOfCheckBox = ui->centralwidget->findChildren(); + listOfColorLabels = ui->centralwidget->findChildren(); + listOfParametricLines = ui->centralwidget->findChildren(); + connect(ui->label_test, SIGNAL(mousePressed()), this, SLOT(on_label_test_clicked())); -MainWindow::~MainWindow() -{ - delete ui; + on_actionLinear_Gradient_triggered(); } - -void GenerateImg(QImage &img, std::vector &points, Info &info) { - - NSGraphics::IGraphicsRenderer* pRasterRenderer = NSGraphics::Create(); - NSFonts::IFontManager *fmp = NSFonts::NSFontManager::Create(); - pRasterRenderer->SetFontManager(fmp); - int nRasterW = img.size().width(); - int nRasterH = img.size().height(); - BYTE* pData = new BYTE[4 * nRasterW * nRasterH]; - - unsigned int back = 0xffffff; - unsigned int* pData32 = (unsigned int*)pData; - unsigned int* pData32End = pData32 + nRasterW * nRasterH ; - //дефолтный тон должен быть прозрачным, а не белым - while (pData32 < pData32End) - *pData32++ = back; - - CBgraFrame oFrame; - oFrame.put_Data(pData); - oFrame.put_Width(nRasterW); - oFrame.put_Height(nRasterH); - oFrame.put_Stride(4 * nRasterW); - - pRasterRenderer->CreateFromBgraFrame(&oFrame); - pRasterRenderer->SetSwapRGB(true); - - double dW_MM = nRasterW * 25.4 / 96; - double dH_MM = nRasterH * 25.4 / 96; - - pRasterRenderer->put_Width(dW_MM); - pRasterRenderer->put_Height(dH_MM); - - NSStructures::GradientInfo ginfo = info.ginfo; - //ginfo.reflected = true; - ginfo.shading.f_type = NSStructures::ShadingInfo::UseNew; - pRasterRenderer->put_BrushGradInfo(ginfo); - auto a = info.c; - auto b = info.p; - LONG *c = a.data(); - double *p = b.data(); - pRasterRenderer->CommandDrawText(L"Test", 10, 10, 345, 345); - pRasterRenderer->put_BrushType(info.gradient_type); - pRasterRenderer->put_BrushGradientColors(c, p, info.n_colors); - pRasterRenderer->PathCommandStart(); - pRasterRenderer->BeginCommand(c_nPathType); - if (points.size() > 0) { - pRasterRenderer->PathCommandMoveTo(points[0].x, points[0].y); - for (uint i = 1; i < points.size(); i++) { - pRasterRenderer->PathCommandLineTo(points[i].x, points[i].y) ; - } - } - pRasterRenderer->Fill(); - //pRasterRenderer->DrawPath(c_nStroke); - pRasterRenderer->EndCommand(c_nPathType); - pRasterRenderer->PathCommandEnd(); - pData32 = (unsigned int*)pData; - for (long i = 0; i < img.size().height(); i++) { - for (long j = 0; j < img.size().width(); j++) { - img.setPixelColor(j, i, QColor(pData32[j + i * nRasterW])); - } - } -} - - - -void MainWindow::on_RenderPic_clicked() +MainWindow::~MainWindow() { - /* - CApplicationFontsWorker oWorker; - oWorker.m_sDirectory = NSFile::GetProcessDirectory() + L"/fonts_cache"; - oWorker.m_bIsNeedThumbnails = false; - if (!NSDirectory::Exists(oWorker.m_sDirectory)) - NSDirectory::CreateDirectory(oWorker.m_sDirectory); - - NSFonts::IApplicationFonts* pFonts = oWorker.Check(); - PdfReader::CPdfReader PDFREADER(pFonts); - PDFREADER.LoadFromFile(L"test.pdf"); - int page = ui->lineEdit->text().toInt(); - PDFREADER.ConvertToRaster(page + 1, L"testpdf.bmp", 1); - */ - - // QImage pm("testpdf.bmp"); - QImage pm(400, 400, QImage::Format_RGB888); - GenerateImg(pm, points, info); - //setColor2(pm, 0x0000FF); - //pm.invertPixels(); - ui->lable_test->setPixmap(QPixmap::fromImage(pm)); - ui->lable_test->setScaledContents(true); - // ui->lable_test->resize(pm.size()); - //pm.save("test.bmp"); - - // pFonts->Release(); + delete ui; } - -void MainWindow::on_GradientType_itemDoubleClicked(QListWidgetItem *item) +void CleanupFunction(void *data) { - on_GradientType_itemClicked(item); - on_RenderPic_clicked(); + delete[] data; } -void MainWindow::on_GradientType_itemClicked(QListWidgetItem *item) +QImage GenerateImg(std::vector &points, Info &info, const int& w, const int& h) { - points = {{0, 0}, {105, 0}, {105, 105}, {0, 105}}; - if (item->text() == "Linear") { - info.gradient_type = c_BrushTypePathNewLinearGradient; - info.ginfo = NSStructures::GInfoConstructor::get_linear(info.p0, info.p1, 0, 1, info.cont_b, info.cont_f); - } - else if (item->text() == "Radial") { - info.gradient_type = c_BrushTypePathRadialGradient; - info.ginfo = NSStructures::GInfoConstructor::get_radial(info.c0, info.c1, info.r0, info.r1, - 0, 1, info.cont_b, info.cont_f); - } - else if (item->text() == "Triangle") { - info.gradient_type = c_BrushTypeTriagnleMeshGradient; - info.ginfo = NSStructures::GInfoConstructor::get_triangle( - info.triangle, - {{255, 0, 0}, {0, 255, 0}, {0, 0, 255}}, - {}, false - ); - points = {}; - for (auto p : info.triangle) - { - points.push_back({p.x / 3.84, p.y / 3.84}); - } - } - else if (item->text() == "Functional" ) { - info.gradient_type = c_BrushTypePathNewLinearGradient; - info.ginfo = NSStructures::GInfoConstructor::get_functional(0, 1, 0, 1, - {400, 0, 0, 400, 0, 0}); - } - else if (item->text() == "TriangleParametric" ) { - info.gradient_type = c_BrushTypeTriagnleMeshGradient; - info.ginfo = NSStructures::GInfoConstructor::get_triangle( - info.triangle, - {{255, 0, 0}, {0, 255, 0}, {0, 0, 255}}, - {0.f, 0.4f, 1.f}, true - ); - points = {}; - for (auto p : info.triangle) - { - points.push_back({p.x / 3.84, p.y / 3.84}); - } - } - else if (item->text() == "CoonsPatch" ) { - info.gradient_type = c_BrushTypePathNewLinearGradient; - info.ginfo = NSStructures::GInfoConstructor::get_curve( - { - {100, 300}, {50, 250}, {150, 150}, {100, 100}, - {150, 50}, {250, 150}, {300, 100}, {250, 150}, - {350, 250}, {300, 300}, {250, 350}, {150,250} - }, - {0, 0.5, 1, 0.5}, - {{0, 0, 255}, {255, 0, 255}, - {255, 0, 0}, {0, 255, 0}}, - false - ); - } - else if (item->text() == "TesnorCoonsPatch" ) { - info.gradient_type = c_BrushTypePathNewLinearGradient; - info.ginfo = NSStructures::GInfoConstructor::get_tensor_curve( - { - {{100, 300}, {150, 250}, {50, 150}, {100,100}}, - {{150, 250}, {170, 230}, {170, 170}, {50, 150}}, - {{350, 250}, {230, 230}, {230, 170}, {150, 250}}, - {{300, 300}, {250, 250}, {350, 150}, {300, 100}} - }, - {{0, 0.5}, {1, 0.5}}, - {{{0, 0, 255}, {255, 0, 255}}, {{255, 0, 0}, {0, 255, 0}}}, - false - ); - } - else if (item->text() == "CoonsPatchParametric") { - info.gradient_type = c_BrushTypeCurveGradient; - info.ginfo = NSStructures::GInfoConstructor::get_curve( - { - {100, 300}, {50, 250}, {150, 150}, {100, 100}, - {150, 50}, {250, 150}, {300, 100}, {250, 150}, - {350, 250}, {300, 300}, {250, 350}, {150,250} - }, - {0, 0.5, 1, 0.5}, - {{0, 0, 255}, {255, 0, 255}, - {255, 0, 0}, {0, 255, 0}}, - true - ); - } - else if (item->text() == "TensorCoonsPatchParametric") { - info.gradient_type = c_BrushTypeTensorCurveGradient; - info.ginfo = NSStructures::GInfoConstructor::get_tensor_curve( - { - {{100, 300}, {150, 250}, {50, 150}, {100,100}}, - {{150, 250}, {170, 230}, {170, 170}, {50, 150}}, - {{350, 250}, {230, 230}, {230, 170}, {150, 250}}, - {{300, 300}, {250, 250}, {350, 150}, {300, 100}} - }, - {{0, 0.5}, {1, 0.5}}, - {{{0, 0, 255}, {255, 0, 255}}, {{255, 0, 0}, {0, 255, 0}}}, - true - ); - } + NSGraphics::IGraphicsRenderer *pRasterRenderer = NSGraphics::Create(); + NSFonts::IFontManager *fmp = NSFonts::NSFontManager::Create(); + pRasterRenderer->SetFontManager(fmp); + int nRasterW = w; + int nRasterH = h; + BYTE *pData = new BYTE[4 * nRasterW * nRasterH]; + + unsigned int back = 0xffffff; + unsigned int *pData32 = (unsigned int *)pData; + unsigned int *pData32End = pData32 + nRasterW * nRasterH; + // дефолтный тон должен быть прозрачным, а не белым + while (pData32 < pData32End) + *pData32++ = back; + + CBgraFrame oFrame; + oFrame.put_Data(pData); + oFrame.put_Width(nRasterW); + oFrame.put_Height(nRasterH); + oFrame.put_Stride(4 * nRasterW); + + pRasterRenderer->CreateFromBgraFrame(&oFrame); + pRasterRenderer->SetSwapRGB(false); + + double dW_MM = COORD_SIZE_MM; + double dH_MM = COORD_SIZE_MM; + + pRasterRenderer->put_Width(dW_MM); + pRasterRenderer->put_Height(dH_MM); + + NSStructures::GradientInfo ginfo = info.ginfo; + ginfo.shading.f_type = NSStructures::ShadingInfo::UseNew; + pRasterRenderer->put_BrushGradInfo(&ginfo); + auto a = info.c; + auto b = info.p; + LONG *c = a.data(); + double *p = b.data(); + pRasterRenderer->put_BrushType(info.gradient_type); + pRasterRenderer->put_BrushGradientColors(c, p, info.n_colors); + pRasterRenderer->PathCommandStart(); + pRasterRenderer->BeginCommand(c_nPathType); + if (points.size() > 0) + { + pRasterRenderer->PathCommandMoveTo(points[0].x, points[0].y); + for (uint i = 1; i < points.size(); i++) + { + pRasterRenderer->PathCommandLineTo(points[i].x, points[i].y); + } + } + pRasterRenderer->Fill(); + pRasterRenderer->EndCommand(c_nPathType); + pRasterRenderer->PathCommandEnd(); + + QImage img = QImage(pData, nRasterW, nRasterH, QImage::Format_RGBA8888, CleanupFunction); + oFrame.put_Data(NULL); + return img; } - - - -void MainWindow::on_ColorSpaces_itemClicked(QListWidgetItem *item) +void MainWindow::initializeColors(bool Triangle) { - - if (item->text() == "Rainbow") { - info.c = {(LONG)0xFFff0000, (LONG)0xFFffa500, (LONG)0xFFffff00, (LONG)0xFF008000, (LONG)0xFF0000ff, (LONG)0xFFFF00FF}; - info.p = {0.0,0.2,0.4,0.6,0.8,1}; - info.n_colors = 6; - info.ginfo.shading.function.set_linear_interpolation({0xFFff0000, 0xFFffa500, 0xFFffff00, 0xFF008000, 0xFF0000ff, 0xFFFF00FF} - , {0.0f,0.2f,0.4f,0.6f,0.8f,1.0f}); - } - else if (item->text() == "Black and white") { - info.c = {(LONG)0xFFFFFFFF, (LONG)0xFF000000}; - info.p = {0.0, 1}; - info.n_colors = 2; - info.ginfo.shading.function.set_linear_interpolation({0xFFFFFFFF, 0xFF000000}, {0.0f, 1.0f}); - } - else if (item->text() == "Red Blue") { - info.c = {(LONG)0xFFFF0000, (LONG)0xFF0000FF}; - info.p = {0.0, 1}; - info.n_colors = 2; - info.ginfo.shading.function.set_linear_interpolation({0xFFFF0000, 0xFF0000FF}, {0.0f, 1.0f}); - } - else if (item->text() == "Pastel") { - info.c = {(LONG)0xfff39189, (LONG)0xff046582}; - info.p = {0.0, 1}; - info.n_colors = 2; - info.ginfo.shading.function.set_linear_interpolation({0xfff39189, 0xff046582}, {0.0f, 1.0f}); - } + listOfColorLabels[0]->setColor(QColor(Qt::red)); + listOfColorLabels[1]->setColor(QColor(Qt::green)); + listOfColorLabels[2]->setColor(QColor(Qt::blue)); + if (!Triangle) + { + listOfColorLabels[3]->setColor(QColor(Qt::yellow)); + } } -void MainWindow::on_ColorSpaces_itemDoubleClicked(QListWidgetItem *item) +void MainWindow::on_actionLinear_Gradient_triggered() { - on_ColorSpaces_itemClicked(item); - on_RenderPic_clicked(); + ui->stackedWidget_1->setCurrentIndex(0); + ui->stackedWidget_2->setCurrentIndex(0); + ui->stackedWidget_3->setCurrentIndex(0); + info.gradient = Linear; + info.offset = LinearOffset; + info.gradient_type = c_BrushTypePathNewLinearGradient; + ui->statusbar->showMessage("Linear"); } - -void MainWindow::on_Point1X_sliderMoved(int position) +void MainWindow::on_actionRadial_Gradient_triggered() { - info.p0.x= position; - if (info.gradient_type != c_BrushTypePathNewLinearGradient) return; - info.ginfo = NSStructures::GInfoConstructor::get_linear(info.p0, info.p1, 0, 1, info.cont_b, info.cont_f); - on_RenderPic_clicked(); + ui->stackedWidget_1->setCurrentIndex(1); + ui->stackedWidget_2->setCurrentIndex(1); + ui->stackedWidget_3->setCurrentIndex(0); + info.gradient = Radial; + info.offset = RadialOffset; + info.gradient_type = c_BrushTypePathRadialGradient; + ui->statusbar->showMessage("Radial"); } -void MainWindow::on_Point1Y_sliderMoved(int position) +void MainWindow::on_actionTriangle_Gradient_triggered() { - info.p0.y = position; - if (info.gradient_type != c_BrushTypePathNewLinearGradient) return; - info.ginfo = NSStructures::GInfoConstructor::get_linear(info.p0, info.p1, 0, 1, info.cont_b, info.cont_f); - on_RenderPic_clicked(); + ui->stackedWidget_1->setCurrentIndex(2); + ui->stackedWidget_2->setCurrentIndex(2); + ui->stackedWidget_3->setCurrentIndex(1); + info.gradient = Triangle; + info.offset = TriangleOffset; + info.gradient_type = c_BrushTypeTriagnleMeshGradient; + initializeColors(true); + ui->statusbar->showMessage("Triangle"); } -void MainWindow::on_Point2X_sliderMoved(int position) +void MainWindow::on_actionTriangle_Parametric_Gradient_triggered() { - info.p1.x = position; - if (info.gradient_type != c_BrushTypePathNewLinearGradient) return; - info.ginfo = NSStructures::GInfoConstructor::get_linear(info.p0, info.p1, 0, 1, info.cont_b, info.cont_f); - on_RenderPic_clicked(); + ui->stackedWidget_1->setCurrentIndex(2); + ui->stackedWidget_2->setCurrentIndex(3); + ui->stackedWidget_3->setCurrentIndex(0); + info.gradient = TriangleParametric; + info.offset = TriangleOffset; + info.gradient_type = c_BrushTypeTriagnleMeshGradient; + ui->statusbar->showMessage("Triangle Parametric"); } -void MainWindow::on_Point2Y_sliderMoved(int position) +void MainWindow::on_actionCoons_Patch_Gradient_triggered() { - info.p1.y = position; - if (info.gradient_type != c_BrushTypePathNewLinearGradient) return; - info.ginfo = NSStructures::GInfoConstructor::get_linear(info.p0, info.p1, 0, 1, info.cont_b, info.cont_f); - on_RenderPic_clicked(); + ui->stackedWidget_1->setCurrentIndex(3); + ui->stackedWidget_2->setCurrentIndex(4); + ui->stackedWidget_3->setCurrentIndex(1); + info.gradient = CoonsPatch; + info.offset = CoonsPatchOffset; + info.gradient_type = c_BrushTypeCurveGradient; + initializeColors(false); + ui->statusbar->showMessage("Coons Patch"); } - -void MainWindow::on_CenterX0_valueChanged(int value) +void MainWindow::on_actionCoons_Patch_Parametric_triggered() { - info.c0.x = value; - if (info.gradient_type != c_BrushTypePathRadialGradient) return; - info.ginfo = NSStructures::GInfoConstructor::get_radial(info.c0, info.c1, info.r0, info.r1, - 0, 1, info.cont_b, info.cont_f); - on_RenderPic_clicked(); + ui->stackedWidget_1->setCurrentIndex(3); + ui->stackedWidget_2->setCurrentIndex(5); + ui->stackedWidget_3->setCurrentIndex(0); + info.gradient = CoonsPatchParametric; + info.offset = CoonsPatchOffset; + info.gradient_type = c_BrushTypeCurveGradient; + ui->statusbar->showMessage("Coons Patch Parametric"); } -void MainWindow::on_CenterY0_valueChanged(int value) +void MainWindow::on_actionTensor_Coons_Patch_Gradient_triggered() { - info.c0.y = value; - if (info.gradient_type != c_BrushTypePathRadialGradient) return; - info.ginfo = NSStructures::GInfoConstructor::get_radial(info.c0, info.c1, info.r0, info.r1, - 0, 1, info.cont_b, info.cont_f); - on_RenderPic_clicked(); + ui->stackedWidget_1->setCurrentIndex(4); + ui->stackedWidget_2->setCurrentIndex(6); + ui->stackedWidget_3->setCurrentIndex(1); + info.gradient = TensorCoonsPatch; + info.offset = TensorCoonsPatchOffset; + info.gradient_type = c_BrushTypeTensorCurveGradient; + initializeColors(false); + ui->statusbar->showMessage("Tensor Coons Patch"); } -void MainWindow::on_CenterX1_valueChanged(int value) +void MainWindow::on_actionTensor_Coons_Patch_Parametric_triggered() { - info.c1.x = value; - if (info.gradient_type != c_BrushTypePathRadialGradient) return; - info.ginfo = NSStructures::GInfoConstructor::get_radial(info.c0, info.c1, info.r0, info.r1, - 0, 1, info.cont_b, info.cont_f); - on_RenderPic_clicked(); + ui->stackedWidget_1->setCurrentIndex(4); + ui->stackedWidget_2->setCurrentIndex(7); + ui->stackedWidget_3->setCurrentIndex(0); + info.gradient = TensorCoonsPatchParametric; + info.offset = TensorCoonsPatchOffset; + info.gradient_type = c_BrushTypeTensorCurveGradient; + ui->statusbar->showMessage("Tensor Coons Patch Parametric"); } -void MainWindow::on_CenterY1_valueChanged(int value) +inline agg::rgba8 getRGB(CustomColorLabel *label) { - info.c1.y= value; - if (info.gradient_type != c_BrushTypePathRadialGradient) return; - info.ginfo = NSStructures::GInfoConstructor::get_radial(info.c0, info.c1, info.r0, info.r1, - 0, 1, info.cont_b, info.cont_f); - on_RenderPic_clicked(); + return {static_cast(label->getColor().red()), + static_cast(label->getColor().green()), + static_cast(label->getColor().blue())}; } -void MainWindow::on_r0slider_valueChanged(int value) +std::vector MainWindow::qColor2rgba(bool triangle) { - info.r0 = value; - if (info.gradient_type != c_BrushTypePathRadialGradient) return; - info.ginfo = NSStructures::GInfoConstructor::get_radial(info.c0, info.c1, info.r0, info.r1, - 0, 1, info.cont_b, info.cont_f); - on_RenderPic_clicked(); -} + std::vector colors; -void MainWindow::on_r1slider_valueChanged(int value) -{ - info.r1 = value; - if (info.gradient_type != c_BrushTypePathRadialGradient) return; - info.ginfo = NSStructures::GInfoConstructor::get_radial(info.c0, info.c1, info.r0, info.r1, - 0, 1, info.cont_b, info.cont_f); - on_RenderPic_clicked(); + size_t size = listOfColorLabels.size(); + if (triangle) + size--; + + for (int i = 0; i < size; i++) + { + colors.push_back(getRGB(listOfColorLabels[i])); + } + + return colors; } -void MainWindow::on_ContinueForvard_clicked(bool checked) +std::vector> MainWindow::qColor2rgbaMatrix() { - info.cont_f= checked; - if (info.gradient_type == c_BrushTypePathNewLinearGradient) - { - info.ginfo = NSStructures::GInfoConstructor::get_linear(info.p0, info.p1, 0, 1, info.cont_b, info.cont_f); - on_RenderPic_clicked(); - } - if (info.gradient_type == c_BrushTypePathRadialGradient) - { - info.ginfo = NSStructures::GInfoConstructor::get_radial(info.c0, info.c1, info.r0, info.r1, - 0, 1, info.cont_b, info.cont_f); - on_RenderPic_clicked(); - } + std::vector> colors; + size_t size = listOfColorLabels.size() / 2; + + for (int i = 0; i < size; i++) + { + std::vector sub_colors; + for (int j = 0; j < size; j++) + { + sub_colors.push_back(getRGB(listOfColorLabels[2 * i + j])); + } + colors.push_back(sub_colors); + } + + return colors; } -void MainWindow::on_ContinueBack_clicked(bool checked) +NSStructures::Point MainWindow::scaleCoord(NSStructures::Point p) { - info.cont_b = checked; - if (info.gradient_type == c_BrushTypePathNewLinearGradient) - { - info.ginfo = NSStructures::GInfoConstructor::get_linear(info.p0, info.p1, 0, 1, info.cont_b, info.cont_f); - on_RenderPic_clicked(); - } - if (info.gradient_type == c_BrushTypePathRadialGradient) - { - info.ginfo = NSStructures::GInfoConstructor::get_radial(info.c0, info.c1, info.r0, info.r1, - 0, 1, info.cont_b, info.cont_f); - on_RenderPic_clicked(); - } + return {p.x * MM_TO_COORD(ui->label_test->width()), p.y * MM_TO_COORD(ui->label_test->height())}; } - - -void MainWindow::on_TrianglePoint1X_sliderMoved(int position) +inline void setPoint(QImage *image, NSStructures::Point p) { - - info.triangle[0].x = position; - if (info.ginfo.shading.shading_type == NSStructures::ShadingInfo::TriangleInterpolation) - { - info.gradient_type = c_BrushTypeTriagnleMeshGradient; - info.ginfo = NSStructures::GInfoConstructor::get_triangle( - info.triangle, - {{255, 0, 0}, {0, 255, 0}, {0, 0, 255}}, - {}, false - ); - points = {}; - for (auto p : info.triangle) - { - points.push_back({p.x / 3.84, p.y / 3.84}); - } - on_RenderPic_clicked(); - return; - } - else if (info.gradient_type == c_BrushTypeTriagnleMeshGradient) - { - info.gradient_type = c_BrushTypeTriagnleMeshGradient; - info.ginfo = NSStructures::GInfoConstructor::get_triangle( - info.triangle, - {{255, 0, 0}, {0, 255, 0}, {0, 0, 255}}, - {0.f, 0.4f, 1.f}, true - ); - points = {}; - for (auto p : info.triangle) - { - points.push_back({p.x / 3.84, p.y / 3.84}); - } - on_RenderPic_clicked(); - } + image->setPixel(p.x, p.y, qRgb(0, 0, 0)); + image->setPixel(p.x - 1, p.y, qRgb(0, 0, 0)); + image->setPixel(p.x, p.y - 1, qRgb(0, 0, 0)); + image->setPixel(p.x + 1, p.y, qRgb(0, 0, 0)); + image->setPixel(p.x, p.y + 1, qRgb(0, 0, 0)); } -void MainWindow::on_TrianglePoint1Y_sliderMoved(int position) +void MainWindow::setPoints(QImage *image) { - info.triangle[0].y = position; - if (info.ginfo.shading.shading_type == NSStructures::ShadingInfo::TriangleInterpolation) - { - info.gradient_type = c_BrushTypeTriagnleMeshGradient; - info.ginfo = NSStructures::GInfoConstructor::get_triangle( - info.triangle, - {{255, 0, 0}, {0, 255, 0}, {0, 0, 255}}, - {}, false - ); - points = {}; - for (auto p : info.triangle) - { - points.push_back({p.x / 3.84, p.y / 3.84}); - } - on_RenderPic_clicked(); - return; - } - else if (info.gradient_type == c_BrushTypeTriagnleMeshGradient) - { - info.gradient_type = c_BrushTypeTriagnleMeshGradient; - info.ginfo = NSStructures::GInfoConstructor::get_triangle( - info.triangle, - {{255, 0, 0}, {0, 255, 0}, {0, 0, 255}}, - {0.f, 0.4f, 1.f}, true - ); - points = {}; - for (auto p : info.triangle) - { - points.push_back({p.x / 3.84, p.y / 3.84}); - } - on_RenderPic_clicked(); - } + std::vector points; + switch (info.gradient) + { + case Linear: + setPoint(image, scaleCoord(info.p0)); + setPoint(image, scaleCoord(info.p1)); + points.push_back(scaleCoord(info.p0)); + points.push_back(scaleCoord(info.p1)); + break; + case Radial: + setPoint(image, scaleCoord(info.c0)); + setPoint(image, scaleCoord(info.c1)); + points.push_back(scaleCoord(info.c0)); + points.push_back(scaleCoord(info.c1)); + break; + case Triangle: + case TriangleParametric: + for (NSStructures::Point p : info.triangle) + { + setPoint(image, scaleCoord(p)); + points.push_back(scaleCoord(p)); + } + break; + case CoonsPatch: + case CoonsPatchParametric: + for (int i = 0; i < info.curve.size(); i++) + { + setPoint(image, scaleCoord(info.curve[i])); + points.push_back(scaleCoord(info.curve[i])); + } + break; + case TensorCoonsPatch: + case TensorCoonsPatchParametric: + for (std::vector v : info.tensorcurve) + { + for (NSStructures::Point p : v) + { + setPoint(image, scaleCoord(p)); + points.push_back(scaleCoord(p)); + } + } + break; + default: + break; + } + ui->label_test->setPoints(points); } -void MainWindow::on_TrianglePoint2X_sliderMoved(int position) +void MainWindow::on_label_test_clicked() { - info.triangle[1].x = position; - if (info.ginfo.shading.shading_type == NSStructures::ShadingInfo::TriangleInterpolation) - { - info.gradient_type = c_BrushTypeTriagnleMeshGradient; - info.ginfo = NSStructures::GInfoConstructor::get_triangle( - info.triangle, - {{255, 0, 0}, {0, 255, 0}, {0, 0, 255}}, - {}, false - ); - points = {}; - for (auto p : info.triangle) - { - points.push_back({p.x / 3.84, p.y / 3.84}); - } - on_RenderPic_clicked(); - return; - } - else if (info.gradient_type == c_BrushTypeTriagnleMeshGradient) - { - info.gradient_type = c_BrushTypeTriagnleMeshGradient; - info.ginfo = NSStructures::GInfoConstructor::get_triangle( - info.triangle, - {{255, 0, 0}, {0, 255, 0}, {0, 0, 255}}, - {0.f, 0.4f, 1.f}, true - ); - points = {}; - for (auto p : info.triangle) - { - points.push_back({p.x / 3.84, p.y / 3.84}); - } - on_RenderPic_clicked(); - } + if (ui->label_test->getMovable()) + { + ui->label_test->resetMovable(); + disconnect(ui->label_test, SIGNAL(mouseMoved()), this, SLOT(on_label_test_mouse_move())); + } + else if (ui->label_test->checkPointArea()) + { + ui->label_test->resetMovable(); + connect(ui->label_test, SIGNAL(mouseMoved()), this, SLOT(on_label_test_mouse_move())); + } } -void MainWindow::on_TrianglePoint2Y_sliderMoved(int position) +void MainWindow::on_label_test_mouse_move() { - info.triangle[1].y = position; - if (info.ginfo.shading.shading_type == NSStructures::ShadingInfo::TriangleInterpolation) - { - info.gradient_type = c_BrushTypeTriagnleMeshGradient; - info.ginfo = NSStructures::GInfoConstructor::get_triangle( - info.triangle, - {{255, 0, 0}, {0, 255, 0}, {0, 0, 255}}, - {}, false - ); - points = {}; - for (auto p : info.triangle) - { - points.push_back({p.x / 3.84, p.y / 3.84}); - } - on_RenderPic_clicked(); - return; - } - else if (info.gradient_type == c_BrushTypeTriagnleMeshGradient) - { - info.gradient_type = c_BrushTypeTriagnleMeshGradient; - info.ginfo = NSStructures::GInfoConstructor::get_triangle( - info.triangle, - {{255, 0, 0}, {0, 255, 0}, {0, 0, 255}}, - {0.f, 0.4f, 1.f}, true - ); - points = {}; - for (auto p : info.triangle) - { - points.push_back({p.x / 3.84, p.y / 3.84}); - } - on_RenderPic_clicked(); - } + listOfLines[info.offset + 2 * ui->label_test->getIndex() + 0]->setText(QString::number(static_cast(ui->label_test->getMovePoint().x) / MM_TO_COORD(ui->label_test->width()))); + listOfLines[info.offset + 2 * ui->label_test->getIndex() + 1]->setText(QString::number(static_cast(ui->label_test->getMovePoint().y) / MM_TO_COORD(ui->label_test->height()))); + on_pushButton_clicked(); } -void MainWindow::on_TrianglePoint3X_sliderMoved(int position) +void MainWindow::lineEdits2Points() { - info.triangle[2].x = position; - if (info.ginfo.shading.shading_type == NSStructures::ShadingInfo::TriangleInterpolation) - { - info.gradient_type = c_BrushTypeTriagnleMeshGradient; - info.ginfo = NSStructures::GInfoConstructor::get_triangle( - info.triangle, - {{255, 0, 0}, {0, 255, 0}, {0, 0, 255}}, - {}, false - ); - points = {}; - for (auto p : info.triangle) - { - points.push_back({p.x / 3.84, p.y / 3.84}); - } - on_RenderPic_clicked(); - return; - } - else if (info.gradient_type == c_BrushTypeTriagnleMeshGradient) - { - info.gradient_type = c_BrushTypeTriagnleMeshGradient; - info.ginfo = NSStructures::GInfoConstructor::get_triangle( - info.triangle, - {{255, 0, 0}, {0, 255, 0}, {0, 0, 255}}, - {0.f, 0.4f, 1.f}, true - ); - points = {}; - for (auto p : info.triangle) - { - points.push_back({p.x / 3.84, p.y / 3.84}); - } - on_RenderPic_clicked(); - } + //Linear + info.p0.x = listOfLines[LinearOffset + 0]->text().toInt(); + info.p0.y = listOfLines[LinearOffset + 1]->text().toInt(); + info.p1.x = listOfLines[LinearOffset + 2]->text().toInt(); + info.p1.y = listOfLines[LinearOffset + 3]->text().toInt(); + + //Radial + info.c0.x = listOfLines[RadialOffset + 0]->text().toInt(); + info.c0.y = listOfLines[RadialOffset + 1]->text().toInt(); + info.c1.x = listOfLines[RadialOffset + 2]->text().toInt(); + info.c1.y = listOfLines[RadialOffset + 3]->text().toInt(); + info.r0 = listOfLines[RadialOffset + 4]->text().toInt(); + info.r1 = listOfLines[RadialOffset + 5]->text().toInt(); + + //Triangle and TriangleParametric + for (size_t i = 0; i < info.triangle.size(); i++) + { + info.triangle[i].x = listOfLines[TriangleOffset + 2 * i + 0]->text().toInt(); + info.triangle[i].y = listOfLines[TriangleOffset + 2 * i + 1]->text().toInt(); + } + + //CoonsPatch and CoonsPatchParametric + for (size_t i = 0; i < info.curve.size(); i++) + { + info.curve[i].x = listOfLines[CoonsPatchOffset + 2 * i + 0]->text().toInt(); + info.curve[i].y = listOfLines[CoonsPatchOffset + 2 * i + 1]->text().toInt(); + } + + //TensorCoonsPatch and TensorCoonsPatchParametric + for (size_t i = 0; i < info.tensorcurve.size(); i++) + { + for (size_t j = 0; j < info.tensorcurve[i].size(); j++) + { + info.tensorcurve[i][j].x = listOfLines[TensorCoonsPatchOffset + 2 * (i * info.tensorcurve[i].size() + j) + 0]->text().toInt(); + info.tensorcurve[i][j].y = listOfLines[TensorCoonsPatchOffset + 2 * (i * info.tensorcurve[i].size() + j) + 1]->text().toInt(); + } + } } -void MainWindow::on_TrianglePoint3Y_sliderMoved(int position) +void MainWindow::lineEdits2Parametrs() { - info.triangle[2].y = position; - if (info.ginfo.shading.shading_type == NSStructures::ShadingInfo::TriangleInterpolation) - { - info.gradient_type = c_BrushTypeTriagnleMeshGradient; - info.ginfo = NSStructures::GInfoConstructor::get_triangle( - info.triangle, - {{255, 0, 0}, {0, 255, 0}, {0, 0, 255}}, - {}, false - ); - points = {}; - for (auto p : info.triangle) - { - points.push_back({p.x / 3.84, p.y / 3.84}); - } - on_RenderPic_clicked(); - return; - } - else if (info.gradient_type == c_BrushTypeTriagnleMeshGradient) - { - info.gradient_type = c_BrushTypeTriagnleMeshGradient; - info.ginfo = NSStructures::GInfoConstructor::get_triangle( - info.triangle, - {{255, 0, 0}, {0, 255, 0}, {0, 0, 255}}, - {0.f, 0.4f, 1.f}, true - ); - points = {}; - for (auto p : info.triangle) - { - points.push_back({p.x / 3.84, p.y / 3.84}); - } - on_RenderPic_clicked(); - } + size_t offset = 0; + + //CoonsPatchParametric + for (size_t i = 0; i < info.curve_parametrs.size(); i++) + { + info.curve_parametrs[i] = listOfParametricLines[offset + i]->text().toFloat(); + } + offset += info.curve_parametrs.size(); + + //TriangleParametric + for (size_t i = 0; i < info.triangle_parametrs.size(); i++) + { + info.triangle_parametrs[i] = listOfParametricLines[offset + i]->text().toFloat(); + } + offset += info.triangle_parametrs.size(); + + //TensorCoonsPatchParametric + for (size_t i = 0; i < info.tensor_curve_parametrs.size(); i++) + { + offset += i; + for (size_t j = 0; j < info.tensor_curve_parametrs[i].size(); j++) + { + info.tensor_curve_parametrs[i][j] = listOfParametricLines[offset + i]->text().toFloat(); + } + } } -void MainWindow::on_LeftButton_clicked() +void MainWindow::checkBox2Continue() { - int page = ui->lineEdit->text().toInt(); - ui->lineEdit->setText(QString::number(page - 1)); - on_RenderPic_clicked(); + switch (info.gradient) + { + case Linear: + info.cont_f = listOfCheckBox[0]->isChecked(); + info.cont_b = listOfCheckBox[1]->isChecked(); + break; + case Radial: + info.cont_f = listOfCheckBox[2]->isChecked(); + info.cont_b = listOfCheckBox[3]->isChecked(); + break; + default: + break; + } } -void MainWindow::on_RightButton_clicked() +void MainWindow::on_pushButton_clicked() { - int page = ui->lineEdit->text().toInt(); - ui->lineEdit->setText(QString::number(page + 1)); - on_RenderPic_clicked(); + lineEdits2Points(); + lineEdits2Parametrs(); + checkBox2Continue(); + points = {{0, 0}, + {ui->label_test->width(), 0}, + {ui->label_test->width(), ui->label_test->height()}, + {0, ui->label_test->height()}}; + + switch (info.gradient) + { + case Linear: + info.ginfo = NSStructures::GInfoConstructor::get_linear(info.p0, info.p1, 0, 1, info.cont_b, info.cont_f); + break; + case Radial: + info.ginfo = NSStructures::GInfoConstructor::get_radial(info.c0, info.c1, info.r0, info.r1, 0, 1, info.cont_b, info.cont_f); + break; + case Triangle: + case TriangleParametric: + info.ginfo = NSStructures::GInfoConstructor::get_triangle(info.triangle, qColor2rgba(true), + info.triangle_parametrs, info.gradient == TriangleParametric); + points = {}; + for (auto p : info.triangle) + { + points.push_back({p.x, p.y}); + } + break; + case CoonsPatch: + case CoonsPatchParametric: + info.ginfo = NSStructures::GInfoConstructor::get_curve(info.curve, info.curve_parametrs, + qColor2rgba(false), info.gradient == CoonsPatchParametric); + break; + case TensorCoonsPatch: + case TensorCoonsPatchParametric: + info.ginfo = NSStructures::GInfoConstructor::get_tensor_curve(info.tensorcurve, info.tensor_curve_parametrs, + qColor2rgbaMatrix(), info.gradient == TensorCoonsPatchParametric); + break; + default: + break; + } + + if (ui->Rainbow_Colorspace_Radio_Button->isChecked()) + { + info.c = {(LONG)0xFFff0000, (LONG)0xFFffa500, (LONG)0xFFffff00, (LONG)0xFF008000, (LONG)0xFF0000ff, (LONG)0xFFFF00FF}; + info.p = {0.0, 0.2, 0.4, 0.6, 0.8, 1}; + info.n_colors = 6; + info.ginfo.shading.function.set_linear_interpolation({0xFFff0000, 0xFFffa500, 0xFFffff00, 0xFF008000, 0xFF0000ff, 0xFFFF00FF}, + {0.0f, 0.2f, 0.4f, 0.6f, 0.8f, 1.0f}); + } + else if (ui->BAW_Colorspace_Radio_Button->isChecked()) + { + info.c = {(LONG)0xFFFFFFFF, (LONG)0xFF000000}; + info.p = {0.0, 1}; + info.n_colors = 2; + info.ginfo.shading.function.set_linear_interpolation({0xFFFFFFFF, 0xFF000000}, {0.0f, 1.0f}); + } + else if (ui->RAB_Colorspace_Radio_Button->isChecked()) + { + info.c = {(LONG)0xFFFF0000, (LONG)0xFF0000FF}; + info.p = {0.0, 1}; + info.n_colors = 2; + info.ginfo.shading.function.set_linear_interpolation({0xFFFF0000, 0xFF0000FF}, {0.0f, 1.0f}); + } + else if (ui->Pastel_Colorspace_Radio_Button->isChecked()) + { + info.c = {(LONG)0xfff39189, (LONG)0xff046582}; + info.p = {0.0, 1}; + info.n_colors = 2; + info.ginfo.shading.function.set_linear_interpolation({0xfff39189, 0xff046582}, {0.0f, 1.0f}); + } + + QImage pm = GenerateImg(points, info, ui->label_test->width(), ui->label_test->height()); + setPoints(&pm); + ui->label_test->setPixmap(QPixmap::fromImage(pm)); + ui->label_test->setScaledContents(true); } diff --git a/Test/Applications/gradient/Gradient/mainwindow.h b/Test/Applications/gradient/Gradient/mainwindow.h index 9c2dedfcf71..2a78c1a472e 100644 --- a/Test/Applications/gradient/Gradient/mainwindow.h +++ b/Test/Applications/gradient/Gradient/mainwindow.h @@ -1,134 +1,293 @@ #ifndef MAINWINDOW_H #define MAINWINDOW_H -#include #include -#include -#include -#include "../../../../DesktopEditor/graphics/pro/Graphics.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include "../../../../DesktopEditor/graphics/structures.h" + +#define COORD_SIZE_MM 100 +#define MM_TO_COORD(size) (size / COORD_SIZE_MM) + QT_BEGIN_NAMESPACE -namespace Ui { class MainWindow; } +namespace Ui +{ + class MainWindow; +} QT_END_NAMESPACE -struct Point { - Point(double _x = 0, double _y = 0) : x(_x), y(_y){} - double x, y; -}; -struct Color { - uint r,g,b; - Color() { - r = b = g = 0; - } - Color(uint rgb) { - b = rgb % 0x100; - g = (rgb / 0x100) % 0x100; - r = rgb / 0x100 / 0x100; - } - uint get_color() { - return b + g * 0x100 + r * 0x10000; - } +class CustomLineEdit : public QLineEdit +{ + Q_OBJECT +public: + CustomLineEdit(QWidget *parent = nullptr) : QLineEdit(parent) + { + connect(this, &QLineEdit::editingFinished, this, &CustomLineEdit::onEditingFinished); + } + ~CustomLineEdit() {} +public slots: + void onEditingFinished() + { + if (this->text() == "") + this->setText(this->placeholderText()); + if (this->text().toInt() < 0) + this->setText("0"); + if (this->text().toInt() > COORD_SIZE_MM) + this->setText(QString::number(COORD_SIZE_MM)); + } }; -struct Info { - // Для теста адаптора все вынес в инфо. - float r0, r1; - NSStructures::Point c0, c1; - NSStructures::Point p0, p1; - bool cont_b, cont_f; - std::vector triangle ={{100, 100}, {300, 200}, {200, 350}}; - - - NSStructures::GradientInfo ginfo; - int gradient_type; - std::vector c; - std::vector p; - int n_colors; - Info() : gradient_type(c_BrushTypePathNewLinearGradient) { - c = {(LONG)0xFFff0000, (LONG)0xFFffa500, (LONG)0xFFffff00, (LONG)0xFF008000, (LONG)0xFF0000ff, (LONG)0xFFFF00FF}; - p = {0.0,0.2,0.4,0.6,0.8,1}; - n_colors = 6; - ginfo.shading.shading_type = NSStructures::ShadingInfo::Parametric; - - - - r0 = 0; - r1 = 100; - c0 = {200, 200}; - c1 = {200, 200}; - p0 = {0, 0}; - p1 = {400, 400}; - cont_b = cont_f = false; - }; - ~Info() { - } +class CustomParametrLineEdit : public QLineEdit +{ + Q_OBJECT +public: + CustomParametrLineEdit(QWidget *parent = nullptr) : QLineEdit(parent) + { + connect(this, &QLineEdit::editingFinished, this, &CustomParametrLineEdit::onEditingFinished); + } + ~CustomParametrLineEdit() {} +public slots: + void onEditingFinished() + { + if (this->text() == "") + this->setText(this->placeholderText()); + if (this->text().toDouble() < 0) + this->setText("0"); + if (this->text().toDouble() > 1) + this->setText("1"); + } }; -void GenerateImg(QImage &img, int grad = 1,double angle = 0,std::vector points = {}); -std::vector drawCircle1(int n, double cx, double cy, double r); -class MainWindow : public QMainWindow +class CustomLabel : public QLabel { - Q_OBJECT - + Q_OBJECT public: - MainWindow(QWidget *parent = nullptr); - ~MainWindow(); - QImage img; - QLabel *lable; - std::vector points; - Info info; + CustomLabel(QWidget *parent = nullptr) : QLabel(parent) + { + movable = false; + setMouseTracking(true); + } + + ~CustomLabel() {} + + void setPoints(const std::vector& points) + { + m_points = points; + } + + NSStructures::Point getMovePoint() const + { + return movePoint; + } + + size_t getIndex() const + { + return index; + } + + bool getMovable() const + { + return movable; + } + + void resetMovable() + { + movable = !movable; + } + + void setIndex(size_t _index) + { + index = _index; + } + + bool checkPointArea() + { + for (int i = 0; i < m_points.size(); i++) + { + QRect rect(m_points[i].x - 5, m_points[i].y - 5, 10, 10); + if (rect.contains(checkPoint.x, checkPoint.y)) + { + index = i; + return true; + } + } + return false; + } + +signals: + void mousePressed(); + void mouseMoved(); + +protected: + void mousePressEvent(QMouseEvent *event) override + { + checkPoint = {event->pos().x(), event->pos().y()}; + emit mousePressed(); + } + + void mouseMoveEvent(QMouseEvent *event) override + { + movePoint = {event->pos().x(), event->pos().y()}; + emit mouseMoved(); + } -private slots: - void on_RenderPic_clicked(); - - void on_GradientType_itemDoubleClicked(QListWidgetItem *item); - - void on_GradientType_itemClicked(QListWidgetItem *item); +private: + bool movable; + size_t index; - void on_ColorSpaces_itemClicked(QListWidgetItem *item); + NSStructures::Point movePoint; + NSStructures::Point checkPoint; + std::vector m_points; +}; - void on_ColorSpaces_itemDoubleClicked(QListWidgetItem *item); +class CustomColorLabel : public QLabel +{ + Q_OBJECT +public: + CustomColorLabel(QWidget *parent = nullptr) : QLabel(parent) + { + connect(this, &CustomColorLabel::mousePressed, this, &CustomColorLabel::onMousePressed); + } + + ~CustomColorLabel() {} + + void setColor(QColor color) + { + m_color = color; + this->setStyleSheet("QLabel { background-color : " + m_color.name() + "; border: 1px solid black; padding 10px;}"); + } + + QColor getColor() const + { + return m_color; + } +signals: + void mousePressed(); +protected: + void mousePressEvent(QMouseEvent *event) override + { + emit mousePressed(); + } +public slots: + void onMousePressed() + { + QColorDialog colorDialog; + QColor color = colorDialog.getColor(); + + if (color.isValid()) + { + setColor(color); + } + } +private: + QColor m_color; +}; - void on_Point1X_sliderMoved(int position); +typedef enum +{ + Linear, + Radial, + Triangle, + TriangleParametric, + CoonsPatch, + CoonsPatchParametric, + TensorCoonsPatch, + TensorCoonsPatchParametric +} GradientType; + +typedef enum +{ + LinearOffset = 68, + RadialOffset = 62, + TriangleOffset = 56, + CoonsPatchOffset = 32, + TensorCoonsPatchOffset = 0 +} GradientOffse; + +struct Info +{ + GradientType gradient; + GradientOffse offset; + + NSStructures::Point p0, p1; + NSStructures::Point c0, c1; + float r0, r1; + std::vector triangle = std::vector(3); + std::vector curve = std::vector(12); + std::vector> tensorcurve = std::vector>(4, std::vector(4)); + + std::vector triangle_parametrs = std::vector(3); + std::vector curve_parametrs = std::vector(4); + std::vector> tensor_curve_parametrs = std::vector>(2, std::vector(2)); + + bool cont_b, cont_f; + + NSStructures::GradientInfo ginfo; + std::vector c; + std::vector p; + int gradient_type; + int n_colors; +}; - void on_Point1Y_sliderMoved(int position); +class MainWindow : public QMainWindow +{ + Q_OBJECT - void on_Point2X_sliderMoved(int position); +public: + MainWindow(QWidget *parent = nullptr); + ~MainWindow(); - void on_Point2Y_sliderMoved(int position); + void initializeColors(bool triangle); + std::vector qColor2rgba(bool triangle); + std::vector> qColor2rgbaMatrix(); - void on_CenterX0_valueChanged(int value); + void setPoints(QImage *image); + NSStructures::Point scaleCoord(NSStructures::Point p); - void on_CenterY0_valueChanged(int value); + void lineEdits2Points(); + void lineEdits2Parametrs(); + void checkBox2Continue(); - void on_CenterX1_valueChanged(int value); +private slots: - void on_CenterY1_valueChanged(int value); + void on_label_test_clicked(); - void on_r0slider_valueChanged(int value); + void on_label_test_mouse_move(); - void on_r1slider_valueChanged(int value); + void on_actionLinear_Gradient_triggered(); - void on_ContinueForvard_clicked(bool checked); + void on_actionRadial_Gradient_triggered(); - void on_ContinueBack_clicked(bool checked); + void on_pushButton_clicked(); - void on_TrianglePoint1X_sliderMoved(int position); + void on_actionTriangle_Gradient_triggered(); - void on_TrianglePoint1Y_sliderMoved(int position); + void on_actionTriangle_Parametric_Gradient_triggered(); - void on_TrianglePoint2X_sliderMoved(int position); + void on_actionCoons_Patch_Gradient_triggered(); - void on_TrianglePoint2Y_sliderMoved(int position); + void on_actionCoons_Patch_Parametric_triggered(); - void on_TrianglePoint3X_sliderMoved(int position); + void on_actionTensor_Coons_Patch_Gradient_triggered(); - void on_TrianglePoint3Y_sliderMoved(int position); + void on_actionTensor_Coons_Patch_Parametric_triggered(); - void on_LeftButton_clicked(); +private: + QImage img; + Info info; + std::vector points; - void on_RightButton_clicked(); + QList listOfCheckBox; + QList listOfLines; + QList listOfColorLabels; + QList listOfParametricLines; -private: - Ui::MainWindow *ui; + Ui::MainWindow *ui; }; #endif // MAINWINDOW_H diff --git a/Test/Applications/gradient/Gradient/mainwindow.ui b/Test/Applications/gradient/Gradient/mainwindow.ui index e743183e25b..f64b558c704 100644 --- a/Test/Applications/gradient/Gradient/mainwindow.ui +++ b/Test/Applications/gradient/Gradient/mainwindow.ui @@ -6,8 +6,8 @@ 0 0 - 1025 - 651 + 1126 + 795 @@ -17,589 +17,3341 @@ true - + 0 0 - 400 - 400 + 500 + 500 - - QFrame::Box - - - QFrame::Sunken + + background-color : white; - + - 600 - 540 - 171 - 51 + 510 + 0 + 610 + 710 - - RenderPic - - - false - - - - - - 20 - 400 - 171 - 161 - + + - - - Functional - - - - - Linear + + + + 10 + 140 + 590 + 560 + - - - - Radial + + 0 - - - - Triangle + + + + + 0 + 0 + 440 + 150 + + + + Set Coordinates + + + + + 10 + 30 + 158 + 20 + + + + X Coordinate, First Point + + + + + + 10 + 80 + 157 + 20 + + + + Y Coordinate, First Point + + + + + + 240 + 30 + 180 + 20 + + + + X Coordinate, Second Point + + + + + + 240 + 80 + 179 + 20 + + + + Y Coordinate, Second Point + + + + + + 10 + 50 + 113 + 28 + + + + 10 + + + 10 + + + + + + 10 + 100 + 113 + 28 + + + + 10 + + + 10 + + + + + + 240 + 50 + 113 + 28 + + + + 90 + + + 90 + + + + + + 240 + 100 + 113 + 28 + + + + 90 + + + 90 + + + + + + + 450 + 0 + 130 + 150 + + + + Continue Shading + + + + + 20 + 50 + 93 + 26 + + + + Forward + + + false + + + + + + 20 + 100 + 93 + 26 + + + + Backward + + + + + + + + + 450 + 0 + 130 + 150 + + + + Continue Shading + + + + + 20 + 50 + 93 + 26 + + + + Forward + + + + + + 20 + 100 + 93 + 26 + + + + Backward + + + + + + + 0 + 0 + 440 + 150 + + + + Set Coordinates Of Circle Centers + + + + + 20 + 30 + 168 + 20 + + + + X Coordinate, First Center + + + + + + 20 + 80 + 167 + 20 + + + + Y Coordinate, First Center + + + + + + 230 + 30 + 190 + 20 + + + + X Coordinate, Second Center + + + + + + 230 + 80 + 189 + 20 + + + + Y Coordinate, Second Center + + + + + + 20 + 50 + 113 + 28 + + + + 50 + + + 50 + + + + + + 20 + 100 + 113 + 28 + + + + 50 + + + 50 + + + + + + 230 + 50 + 113 + 28 + + + + 50 + + + 50 + + + + + + 230 + 100 + 113 + 28 + + + + 50 + + + 50 + + + + + + + 0 + 150 + 440 + 100 + + + + Set Radius Of Circle + + + + + 20 + 30 + 75 + 20 + + + + First Radius + + + + + + 230 + 30 + 97 + 20 + + + + Second Radius + + + + + + 20 + 50 + 113 + 28 + + + + 10 + + + 10 + + + + + + 230 + 50 + 113 + 28 + + + + 30 + + + 30 + + + + + + + + + 0 + 0 + 590 + 140 + + + + Set Coordinates Of Triangle Vertices + + + + + 10 + 30 + 168 + 20 + + + + X Coordinate, First Vertex + + + + + + 10 + 80 + 167 + 20 + + + + Y Coordinate, First Vertex + + + + + + 200 + 30 + 188 + 20 + + + + X Coordinate, Second Vertex + + + + + + 200 + 80 + 187 + 20 + + + + Y Coordinate, Second Vertex + + + + + + 410 + 30 + 173 + 20 + + + + X Coordinate, Third Vertex + + + + + + 410 + 80 + 173 + 20 + + + + Y Coordinate, Third Vertex + + + + + + 10 + 50 + 113 + 28 + + + + 50 + + + 50 + + + + + + 10 + 100 + 113 + 28 + + + + 20 + + + 20 + + + + + + 200 + 50 + 113 + 28 + + + + 20 + + + 20 + + + + + + 200 + 100 + 113 + 28 + + + + 70 + + + 70 + + + + + + 410 + 50 + 113 + 28 + + + + 80 + + + 80 + + + + + + 410 + 100 + 113 + 28 + + + + 70 + + + 70 + + + + + + + + + 20 + 0 + 130 + 140 + + + + First Vertex + + + + + 10 + 30 + 87 + 20 + + + + X Coordinate + + + + + + 10 + 50 + 113 + 28 + + + + 20 + + + 20 + + + + + + 10 + 80 + 86 + 20 + + + + Y Coordinate + + + + + + 10 + 100 + 113 + 28 + + + + 60 + + + 60 + + + + + + + 200 + 0 + 370 + 140 + + + + First Edge + + + + + 10 + 30 + 118 + 20 + + + + First X Coordinate + + + + + + 210 + 30 + 140 + 20 + + + + Second X Coordinate + + + + + + 10 + 80 + 117 + 20 + + + + First Y Coordinate + + + + + + 210 + 80 + 139 + 20 + + + + Second Y Coordinate + + + + + + 10 + 50 + 113 + 28 + + + + 10 + + + 10 + + + + + + 10 + 100 + 113 + 28 + + + + 50 + + + 50 + + + + + + 210 + 50 + 113 + 28 + + + + 30 + + + 30 + + + + + + 210 + 100 + 113 + 28 + + + + 30 + + + 30 + + + + + + + 20 + 140 + 130 + 140 + + + + Second Vertex + + + + + 10 + 30 + 87 + 20 + + + + X Coordinate + + + + + + 10 + 80 + 86 + 20 + + + + Y Coordinate + + + + + + 10 + 50 + 113 + 28 + + + + 20 + + + 20 + + + + + + 10 + 100 + 113 + 28 + + + + 20 + + + 20 + + + + + + + 200 + 140 + 370 + 140 + + + + Second Edge + + + + + 10 + 30 + 118 + 20 + + + + First X Coordinate + + + + + + 210 + 30 + 140 + 20 + + + + Second X Coordinate + + + + + + 10 + 80 + 117 + 20 + + + + First Y Coordinate + + + + + + 210 + 80 + 140 + 20 + + + + Second Y Coordinate + + + + + + 10 + 50 + 113 + 28 + + + + 30 + + + 30 + + + + + + 10 + 100 + 113 + 28 + + + + 10 + + + 10 + + + + + + 210 + 50 + 113 + 28 + + + + 50 + + + 50 + + + + + + 210 + 100 + 113 + 28 + + + + 30 + + + 30 + + + + + + + 20 + 280 + 130 + 140 + + + + Third Vertex + + + + + 10 + 30 + 87 + 20 + + + + X Coordinate + + + + + + 10 + 80 + 86 + 20 + + + + Y Coordinate + + + + + + 10 + 50 + 113 + 28 + + + + 60 + + + 60 + + + + + + 10 + 100 + 113 + 28 + + + + 20 + + + 20 + + + + + + + 200 + 280 + 370 + 140 + + + + Third Edge + + + + + 10 + 30 + 118 + 20 + + + + First X Coordinate + + + + + + 220 + 30 + 140 + 20 + + + + Second X Coordinate + + + + + + 10 + 80 + 117 + 20 + + + + First Y Coordinate + + + + + + 220 + 80 + 140 + 20 + + + + Second Y Coordinate + + + + + + 10 + 50 + 113 + 28 + + + + 50 + + + 50 + + + + + + 10 + 100 + 113 + 28 + + + + 30 + + + 30 + + + + + + 220 + 50 + 113 + 28 + + + + 70 + + + 70 + + + + + + 220 + 100 + 113 + 28 + + + + 50 + + + 50 + + + + + + + 20 + 420 + 130 + 140 + + + + Fourth Vertex + + + + + 10 + 30 + 87 + 20 + + + + X Coordinate + + + + + + 10 + 80 + 86 + 20 + + + + Y Coordinate + + + + + + 10 + 50 + 113 + 28 + + + + 60 + + + 60 + + + + + + 10 + 100 + 113 + 28 + + + + 60 + + + 60 + + + + + + + 200 + 420 + 370 + 140 + + + + Fourth Edge + + + + + 10 + 30 + 118 + 20 + + + + First X Coordinate + + + + + + 220 + 30 + 140 + 20 + + + + Second X Coordinate + + + + + + 10 + 80 + 117 + 20 + + + + First Y Coordinate + + + + + + 220 + 80 + 140 + 20 + + + + Second Y Coordinate + + + + + + 10 + 50 + 113 + 28 + + + + 50 + + + 50 + + + + + + 10 + 100 + 113 + 28 + + + + 70 + + + 70 + + + + + + 220 + 50 + 113 + 28 + + + + 30 + + + 30 + + + + + + 220 + 100 + 113 + 28 + + + + 50 + + + 50 + + + + + + + + + 0 + 0 + 590 + 140 + + + + Set Coordinates Of First Curved Edge + + + + + 10 + 30 + 118 + 20 + + + + First X Coordinate + + + + + + 10 + 80 + 117 + 20 + + + + First Y Coordinate + + + + + + 140 + 30 + 140 + 20 + + + + Second X Coordinate + + + + + + 140 + 80 + 139 + 20 + + + + Second Y Coordinate + + + + + + 300 + 30 + 125 + 20 + + + + Third X Coordinate + + + + + + 300 + 80 + 124 + 20 + + + + Third Y Coordinate + + + + + + 450 + 30 + 133 + 20 + + + + Fourth X Coordinate + + + + + + 450 + 80 + 128 + 20 + + + + Fourth Y Coorfinate + + + + + + 10 + 50 + 113 + 28 + + + + 20 + + + 20 + + + + + + 10 + 100 + 113 + 28 + + + + 60 + + + 60 + + + + + + 140 + 50 + 113 + 28 + + + + 30 + + + 30 + + + + + + 140 + 100 + 113 + 28 + + + + 50 + + + 50 + + + + + + 300 + 50 + 113 + 28 + + + + 10 + + + 10 + + + + + + 300 + 100 + 113 + 28 + + + + 30 + + + 30 + + + + + + 450 + 50 + 113 + 28 + + + + 20 + + + 20 + + + + + + 450 + 100 + 113 + 28 + + + + 20 + + + 20 + + + + + + + 0 + 140 + 590 + 140 + + + + Set Coordinates Of Second Curved Edge + + + + + 10 + 30 + 118 + 20 + + + + First X Coordinate + + + + + + 10 + 80 + 117 + 20 + + + + First Y Coordinate + + + + + + 140 + 30 + 140 + 20 + + + + Second X Coordinate + + + + + + 140 + 80 + 139 + 20 + + + + Second Y Coordinate + + + + + + 300 + 30 + 125 + 20 + + + + Third X Coordinate + + + + + + 300 + 80 + 124 + 20 + + + + Third Y Coordinate + + + + + + 450 + 30 + 133 + 20 + + + + Fourth X Coordinate + + + + + + 450 + 80 + 128 + 20 + + + + Fourth Y Coorfinate + + + + + + 10 + 50 + 113 + 28 + + + + 30 + + + 30 + + + + + + 10 + 100 + 113 + 28 + + + + 50 + + + 50 + + + + + + 140 + 50 + 113 + 28 + + + + 34 + + + 34 + + + + + + 140 + 100 + 113 + 28 + + + + 46 + + + 46 + + + + + + 300 + 50 + 113 + 28 + + + + 34 + + + 34 + + + + + + 300 + 100 + 113 + 28 + + + + 34 + + + 34 + + + + + + 450 + 50 + 113 + 28 + + + + 10 + + + 10 + + + + + + 450 + 100 + 113 + 28 + + + + 30 + + + 30 + + + + + + + 0 + 280 + 590 + 140 + + + + Set Coordinates Of Third Curved Edge + + + + + 10 + 30 + 118 + 20 + + + + First X Coordinate + + + + + + 10 + 80 + 117 + 20 + + + + First Y Coordinate + + + + + + 140 + 30 + 140 + 20 + + + + Second X Coordinate + + + + + + 140 + 80 + 139 + 20 + + + + Second Y Coordinate + + + + + + 300 + 30 + 125 + 20 + + + + Third X Coordinate + + + + + + 300 + 80 + 124 + 20 + + + + Third Y Coordinate + + + + + + 450 + 30 + 133 + 20 + + + + Fourth X Coordinate + + + + + + 450 + 80 + 128 + 20 + + + + Fourth Y Coorfinate + + + + + + 10 + 50 + 113 + 28 + + + + 70 + + + 70 + + + + + + 10 + 100 + 113 + 28 + + + + 50 + + + 50 + + + + + + 140 + 50 + 113 + 28 + + + + 46 + + + 46 + + + + + + 140 + 100 + 113 + 28 + + + + 46 + + + 46 + + + + + + 300 + 50 + 113 + 28 + + + + 46 + + + 46 + + + + + + 300 + 100 + 113 + 28 + + + + 34 + + + 34 + + + + + + 450 + 50 + 113 + 28 + + + + 30 + + + 30 + + + + + + 450 + 100 + 113 + 28 + + + + 50 + + + 50 + + + + + + + 0 + 420 + 590 + 140 + + + + Set Coordinates Of Fourth Curved Edge + + + + + 10 + 30 + 118 + 20 + + + + First X Coordinate + + + + + + 10 + 80 + 117 + 20 + + + + First Y Coordinate + + + + + + 140 + 30 + 140 + 20 + + + + Second X Coordinate + + + + + + 140 + 80 + 139 + 20 + + + + Second Y Coordinate + + + + + + 300 + 30 + 125 + 20 + + + + Third X Coordinate + + + + + + 300 + 80 + 124 + 20 + + + + Third Y Coordinate + + + + + + 450 + 30 + 133 + 20 + + + + Fourth X Coordinate + + + + + + 450 + 80 + 128 + 20 + + + + Fourth Y Coorfinate + + + + + + 10 + 50 + 113 + 28 + + + + 60 + + + 60 + + + + + + 10 + 100 + 113 + 28 + + + + 60 + + + 60 + + + + + + 140 + 50 + 113 + 28 + + + + 50 + + + 50 + + + + + + 140 + 100 + 113 + 28 + + + + 50 + + + 50 + + + + + + 300 + 50 + 113 + 28 + + + + 70 + + + 70 + + + + + + 300 + 100 + 113 + 28 + + + + 30 + + + 30 + + + + + + 450 + 50 + 113 + 28 + + + + 60 + + + 60 + + + + + + 450 + 100 + 113 + 28 + + + + 20 + + + 20 + + + + + + + + + 370 + 40 + 117 + 29 + - - - CoonsPatch + Render Gradient - - - - TesnorCoonsPatch + + + + + 10 + 10 + 221 + 130 + - - - - TriangleParametric + + 0 - - - - CoonsPatchParametric - - - - - TensorCoonsPatchParametric - - - - - - - 20 - 570 - 101 - 16 - - - - Gradient Type - - - - - - 210 - 400 - 121 - 161 - - - - - Rainbow - - - - - Black and white - - - - - Red Blue - - - - - Pastel - - - - - - - 230 - 570 - 58 - 16 - - - - Colours - - - - - - 340 - 530 - 141 - 41 - - - - Double Click to change - - - - - - 460 - 30 - 160 - 16 - - - - 400 - - - Qt::Horizontal - - - - - - 460 - 60 - 160 - 16 - - - - 400 - - - Qt::Horizontal - + + + + + 10 + 10 + 201 + 120 + + + + Choose gradient colorspace + + + + + 20 + 30 + 112 + 26 + + + + Rainbow + + + true + + + + + + 20 + 50 + 161 + 26 + + + + Black and White + + + + + + 20 + 70 + 131 + 26 + + + + Red and Blue + + + + + + 20 + 90 + 112 + 26 + + + + Pastel + + + + + + + + + 20 + 20 + 171 + 81 + + + + Set colors in angles + + + + + 10 + 40 + 30 + 20 + + + + + + + + + + 50 + 40 + 30 + 20 + + + + + + + + + + 90 + 40 + 30 + 20 + + + + + + + + + + 130 + 40 + 30 + 20 + + + + + + + + + - + - 460 - 90 - 160 - 16 + 10 + 510 + 490 + 190 - - 400 - - - 400 - - - Qt::Horizontal - - - - - - 460 - 120 - 160 - 16 - - - - 400 - - - 400 - - - Qt::Horizontal - - - - - - 460 - 10 - 151 - 18 - - - - Points XY Linear - - - - - - 740 - 170 - 58 - 18 - - - - r0 r1 - - - - - - 720 - 200 - 160 - 16 - - - - 200 - - - Qt::Horizontal - - - - - - 720 - 230 - 160 - 16 - - - - 200 - - - 100 - - - Qt::Horizontal - - - - - - 720 - 30 - 160 - 16 - - - - 400 - - - 200 - - - Qt::Horizontal - - - - - - 720 - 60 - 160 - 16 - - - - 400 - - - 200 - - - Qt::Horizontal - - - - - - 720 - 90 - 160 - 16 - - - - 400 - - - 200 - - - Qt::Horizontal - - - - - - 720 - 120 - 160 - 16 - - - - 400 - - - 200 - - - Qt::Horizontal - - - - - - 740 - 10 - 131 - 18 - - - - CenterXY Radial - - - - - - 380 - 420 - 141 - 24 - - - - Continue Forward - - - - - - 380 - 460 - 141 - 24 - - - - Continue Back - - - - - - 440 - 190 - 160 - 16 - - - - 400 - - - 100 - - - Qt::Horizontal - - - - - - 440 - 220 - 160 - 16 - - - - 400 - - - 100 - - - Qt::Horizontal - - - - - - 440 - 290 - 160 - 16 - - - - 400 - - - 200 - - - Qt::Horizontal - - - - - - 440 - 260 - 160 - 16 - - - - 400 - - - 300 - - - Qt::Horizontal - - - - - - 440 - 350 - 160 - 16 - - - - 400 - - - 350 - - - Qt::Horizontal - - - - - - 440 - 320 - 160 - 16 - - - - 400 - - - 200 - - - Qt::Horizontal - - - - - - 420 - 170 - 111 - 16 - - - - XY triangle - - - - - - 770 - 320 - 54 - 17 - - - - PDF - - - - - - 680 - 400 - 80 - 25 - - - - Left - - - - - - 790 - 400 - 80 - 25 - - - - Right - - - - - - 730 - 360 - 113 - 25 - - - - 746 - + + 5 + + + + + + 20 + 10 + 415 + 20 + + + + A linear gradient describes a color change along a straight line + + + Qt::AutoText + + + + + + 20 + 30 + 415 + 20 + + + + that is defined by two points. + + + Qt::AutoText + + + + + + + + 10 + 10 + 319 + 20 + + + + Radial gradient describes the color change from + + + + + + 10 + 30 + 335 + 20 + + + + the center to the edges, it is defined by two circles, + + + + + + 10 + 50 + 281 + 20 + + + + which are defined by the center and radius + + + + + + + + 0 + 10 + 472 + 20 + + + + Triangle gradient describes the color change between the three vertices + + + + + + 0 + 30 + 482 + 20 + + + + of a triangle. The color change occurs according to the principle of linear + + + + + + 0 + 50 + 467 + 20 + + + + gradient along the perpendiculars from the triangle vertex to the point + + + + + + 0 + 70 + 230 + 20 + + + + where the perpendiculars intersect. + + + + + + + + 10 + 10 + 469 + 20 + + + + A parametric gradient differs in that the colors at the corners are set by + + + + + + 10 + 30 + 271 + 20 + + + + the initial parameters (value from 0 to 1). + + + + + + 10 + 50 + 470 + 130 + + + + Set Parametrs + + + + + 10 + 30 + 135 + 20 + + + + First Vertex Parametr + + + + + + 270 + 30 + 157 + 20 + + + + Second Vertex Parametr + + + + + + 10 + 80 + 157 + 20 + + + + Third Vertex Parametr + + + + + + 10 + 50 + 113 + 28 + + + + 0 + + + 0 + + + + + + 270 + 50 + 113 + 28 + + + + 0.5 + + + 0.5 + + + + + + 10 + 100 + 113 + 28 + + + + 1 + + + 1 + + + + + + + + + 10 + 10 + 461 + 20 + + + + Coons Patch gradient describes the color change on the surface of the + + + + + + 10 + 30 + 456 + 20 + + + + Coons Patch on the plane. In mathematics, a Coons patch, is a type of + + + + + + 10 + 50 + 418 + 20 + + + + surface patch used in computer graphics to smoothly join other + + + + + + 10 + 70 + 117 + 20 + + + + surfaces together. + + + + + + 10 + 130 + 162 + 20 + + + + Note on set coordinates: + + + + + + 10 + 150 + 459 + 20 + + + + The vertices are counted clockwise. + + + + + + 10 + 170 + 457 + 20 + + + + The edges are counted clockwise starting from the edge between the + + + + + + 10 + 190 + 152 + 20 + + + + first and second vertex. + + + + + + + + 10 + 10 + 469 + 20 + + + + A parametric gradient differs in that the colors at the corners are set by + + + + + + 10 + 30 + 271 + 20 + + + + the initial parameters (value from 0 to 1). + + + + + + 10 + 50 + 470 + 130 + + + + Set Parametrs + + + + + 10 + 30 + 135 + 20 + + + + First Vertex Parametr + + + + + + 270 + 30 + 157 + 20 + + + + Second Vertex Parametr + + + + + + 10 + 80 + 157 + 20 + + + + Third Vertex Parametr + + + + + + 270 + 80 + 157 + 20 + + + + Fourth Vertex Parametr + + + + + + 10 + 50 + 113 + 28 + + + + 0 + + + 0 + + + + + + 270 + 50 + 113 + 28 + + + + 0.3 + + + 0.3 + + + + + + 10 + 100 + 113 + 28 + + + + 1 + + + 1 + + + + + + 270 + 100 + 113 + 28 + + + + 0.6 + + + 1 + + + + + + + + + 10 + 10 + 435 + 20 + + + + Tensor Coons Patch gradient describes the color change as well as + + + + + + 10 + 30 + 279 + 20 + + + + Coons Patch gradient, but in tensor space. + + + + + + 10 + 130 + 162 + 20 + + + + Note on set coordinates: + + + + + + 10 + 150 + 222 + 20 + + + + The curves are counted clockwise. + + + + + + + + 10 + 10 + 469 + 20 + + + + A parametric gradient differs in that the colors at the corners are set by + + + + + + 10 + 30 + 271 + 20 + + + + the initial parameters (value from 0 to 1). + + + + + + 10 + 50 + 470 + 130 + + + + Set Parametrs + + + + + 10 + 30 + 135 + 20 + + + + First Vertex Parametr + + + + + + 270 + 30 + 157 + 20 + + + + Second Vertex Parametr + + + + + + 10 + 80 + 157 + 20 + + + + Third Vertex Parametr + + + + + + 270 + 80 + 157 + 20 + + + + Fourth Vertex Parametr + + + + + + 10 + 50 + 113 + 28 + + + + 0 + + + 0 + + + + + + 270 + 50 + 113 + 28 + + + + 0.3 + + + 0.3 + + + + + + 10 + 100 + 113 + 28 + + + + 1 + + + 1 + + + + + + 270 + 100 + 113 + 28 + + + + 0.6 + + + 0.6 + + + + @@ -607,8 +3359,8 @@ 0 0 - 1025 - 23 + 1126 + 25 @@ -623,8 +3375,99 @@ false + + + + + + + + + + + Linear + + + + + Radial + + + + + Triangle + + + QAction::TextHeuristicRole + + + + + Triangle Parametric + + + QAction::TextHeuristicRole + + + + + Coons Patch + + + QAction::TextHeuristicRole + + + + + Coons Patch Parametric + + + QAction::TextHeuristicRole + + + + + Tensor Coons Patch + + + QAction::TextHeuristicRole + + + + + Tensor Coons Patch Parametric + + + QAction::TextHeuristicRole + + + + + CustomLineEdit + QLineEdit +
mainwindow.h
+
+ + CustomLabel + QLabel +
mainwindow.h
+
+ + CustomParametrLineEdit + QLineEdit +
mainwindow.h
+
+ + CustomColorLabel + QLabel +
mainwindow.h
+ + onMouseClicked() + +
+
diff --git a/Test/Applications/x2tTester/README.md b/Test/Applications/x2tTester/README.md index f8a03581a4a..1b35855423f 100644 --- a/Test/Applications/x2tTester/README.md +++ b/Test/Applications/x2tTester/README.md @@ -1,7 +1,9 @@ CONFIGURATION ============= -You need to create an xml configuration file. It must contain: +## Default conversion + +You need to create an xml configuration file. It contains: # root of xml @@ -95,8 +97,23 @@ You need to create an xml configuration file. It must contain: docx txt pptx xlsx txt doc pdf +## Extraction +x2ttester can extract files with the required output extension instead of default x2t conversion. Set extraction mode: + + (non-required) sets extraction mode (default - "0") + + +When `extract` is "1", you can set the `output` parameter to determine which exts will be extracted. Default `output` is `emf wmf`. +Params `input`, `inputDirectory`, `outputDirectory`, `cores` works the same. + +Extract mode has additional options: + + (non-required) converts non-zip office files into docx (e.g. pdf) (default - "0"). + + +The conversion params in `convertBeforeExtract` are the same as the default conversion. -You can use the following templates: +## Templates # main xml config diff --git a/Test/Applications/x2tTester/x2tTester.cpp b/Test/Applications/x2tTester/x2tTester.cpp index b594a8ae4b9..50fd0988195 100644 --- a/Test/Applications/x2tTester/x2tTester.cpp +++ b/Test/Applications/x2tTester/x2tTester.cpp @@ -1,10 +1,21 @@ #include "x2tTester.h" + +#include + #include "../../../X2tConverter/src/run.h" class CFormatsList; class Cx2tTester; class CConverter; +std::wstring GetFileExtLower(const std::wstring& file) +{ + std::wstring input_ext = NSFile::GetFileExtention(file); + for (auto& c : input_ext) + c = std::tolower(c); + return input_ext; +} + CFormatsList::CFormatsList() { } @@ -33,6 +44,9 @@ CFormatsList& CFormatsList::operator=(const CFormatsList& list) for(auto& val : list.m_images) m_images.push_back(val); + for(auto& val : list.m_draw) + m_draw.push_back(val); + for(auto& val : list.m_crossplatform) m_crossplatform.push_back(val); @@ -56,6 +70,10 @@ std::vector CFormatsList::GetCrossplatform() const { return m_crossplatform; } +std::vector CFormatsList::GetDraw() const +{ + return m_draw; +} std::vector CFormatsList::GetImages() const { return m_images; @@ -81,6 +99,10 @@ bool CFormatsList::IsCrossplatform(const std::wstring& ext) const { return std::find(m_crossplatform.begin(), m_crossplatform.end(), ext) != m_crossplatform.end(); } +bool CFormatsList::IsDraw(const std::wstring& ext) const +{ + return std::find(m_draw.begin(), m_draw.end(), ext) != m_draw.end(); +} bool CFormatsList::IsImage(const std::wstring& ext) const { return std::find(m_images.begin(), m_images.end(), ext) != m_images.end(); @@ -91,7 +113,7 @@ bool CFormatsList::IsPdf(const std::wstring& ext) const } bool CFormatsList::IsAny(const std::wstring& ext) const { - return IsDocument(ext) || IsPresentation(ext) || IsSpreadsheet(ext) || IsCrossplatform(ext) || IsImage(ext) || IsPdf(ext); + return IsDocument(ext) || IsPresentation(ext) || IsSpreadsheet(ext) || IsCrossplatform(ext) || IsImage(ext) || IsPdf(ext) || IsDraw(ext); } void CFormatsList::AddDocument(const std::wstring& ext) @@ -110,6 +132,10 @@ void CFormatsList::AddCrossplatform(const std::wstring& ext) { m_crossplatform.push_back(ext); } +void CFormatsList::AddDraw(const std::wstring& ext) +{ + m_draw.push_back(ext); +} void CFormatsList::AddImage(const std::wstring& ext) { m_images.push_back(ext); @@ -119,22 +145,26 @@ std::vector CFormatsList::GetAllExts() const { std::vector all_formats; - for(auto& val : m_documents) + for (const auto& val : m_documents) all_formats.push_back(val); - for(auto& val : m_presentations) + for (const auto& val : m_presentations) all_formats.push_back(val); - for(auto& val : m_spreadsheets) + for (const auto& val : m_spreadsheets) all_formats.push_back(val); - for(auto& val : m_images) + for (const auto& val : m_images) all_formats.push_back(val); - for(auto& val : m_crossplatform) + for (const auto& val : m_crossplatform) all_formats.push_back(val); - all_formats.push_back(m_pdf); + for (const auto& val : m_draw) + all_formats.push_back(val); + + if (!m_pdf.empty()) + all_formats.push_back(m_pdf); return all_formats; } @@ -156,6 +186,10 @@ CFormatsList CFormatsList::GetDefaultExts() list.m_documents.push_back(L"fodt"); list.m_documents.push_back(L"htm"); list.m_documents.push_back(L"html"); + + list.m_documents.push_back(L"hwp"); + list.m_documents.push_back(L"hwpx"); + list.m_documents.push_back(L"mht"); list.m_documents.push_back(L"odt"); list.m_documents.push_back(L"ott"); @@ -203,8 +237,7 @@ CFormatsList CFormatsList::GetDefaultExts() list.m_crossplatform.push_back(L"djvu"); list.m_crossplatform.push_back(L"xps"); -// list.m_images.push_back(L"jpg"); -// list.m_images.push_back(L"png"); + list.m_draw.push_back(L"vsdx"); list.m_pdf = L"pdf"; @@ -243,6 +276,7 @@ CFormatsList CFormatsList::GetOutputExts() list.m_spreadsheets.push_back(L"csv"); list.m_spreadsheets.push_back(L"ods"); list.m_spreadsheets.push_back(L"ots"); + list.m_spreadsheets.push_back(L"xlsb"); list.m_spreadsheets.push_back(L"xlsm"); list.m_spreadsheets.push_back(L"xlsx"); list.m_spreadsheets.push_back(L"xltm"); @@ -259,6 +293,16 @@ CFormatsList CFormatsList::GetOutputExts() return list; } +CFormatsList CFormatsList::GetExtractExts() +{ + CFormatsList list; + + list.m_images.push_back(L"emf"); + list.m_images.push_back(L"wmf"); + + return list; +} + Cx2tTester::Cx2tTester(const std::wstring& configPath) { m_bIsUseSystemFonts = true; @@ -269,14 +313,22 @@ Cx2tTester::Cx2tTester(const std::wstring& configPath) m_bIsFilenamePassword = true; m_bTroughConversion = false; m_bSaveEnvironment = false; + + m_bExtract = false; + m_bConvertBeforeExtract = false; + m_defaultCsvDelimiter = L";"; m_defaultCsvTxtEndcoding = L"UTF-8"; m_inputFormatsList = CFormatsList::GetDefaultExts(); m_outputFormatsList = CFormatsList::GetOutputExts(); + m_extractFormatsList = CFormatsList::GetExtractExts(); m_timeout = 5 * 60; // 5 min + SetConfig(configPath); + m_errorsXmlDirectory = m_outputDirectory + FILE_SEPARATOR_STR + L"_errors"; m_troughConversionDirectory = m_outputDirectory + FILE_SEPARATOR_STR + L"_t"; + m_tempDirectory = m_outputDirectory + FILE_SEPARATOR_STR + L"_temp"; m_fontsDirectory = NSFile::GetProcessDirectory() + FILE_SEPARATOR_STR + L"fonts"; @@ -301,12 +353,12 @@ Cx2tTester::Cx2tTester(const std::wstring& configPath) time_t now = time(0); std::tm* time = std::localtime(&now); std::wstring timestamp = - std::to_wstring(time->tm_mday) + L"_" + - std::to_wstring(time->tm_mon + 1) + L"_" + - std::to_wstring(time->tm_year + 1900) + L"_" + - std::to_wstring(time->tm_hour) + L"_" + - std::to_wstring(time->tm_min) + L"_" + - std::to_wstring(time->tm_sec); + std::to_wstring(time->tm_mday) + L"_" + + std::to_wstring(time->tm_mon + 1) + L"_" + + std::to_wstring(time->tm_year + 1900) + L"_" + + std::to_wstring(time->tm_hour) + L"_" + + std::to_wstring(time->tm_min) + L"_" + + std::to_wstring(time->tm_sec); std::wstring report_ext = NSFile::GetFileExtention(m_reportFile); m_reportFile = m_reportFile.substr(0, m_reportFile.size() - report_ext.size() - 1); @@ -335,6 +387,12 @@ Cx2tTester::~Cx2tTester() m_reportCS.DeleteCriticalSection(); m_outputCS.DeleteCriticalSection(); m_reportStream.CloseFile(); + + for(auto&& val : m_deleteLaterFiles) + NSFile::CFileBinary::Remove(val); + + for(auto&& val : m_deleteLaterDirectories) + NSDirectory::DeleteDirectory(val); } void Cx2tTester::SetConfig(const std::wstring& configPath) @@ -366,6 +424,8 @@ void Cx2tTester::SetConfig(const std::wstring& configPath) else if(name == L"troughConversion" && !node.GetText().empty()) m_bTroughConversion = std::stoi(node.GetText()); else if(name == L"saveEnvironment" && !node.GetText().empty()) m_bSaveEnvironment = std::stoi(node.GetText()); else if(name == L"defaultCsvTxtEncoding" && !node.GetText().empty()) m_defaultCsvTxtEndcoding = node.GetText(); + else if(name == L"extract" && !node.GetText().empty()) m_bExtract = std::stoi(node.GetText()); + else if(name == L"convertBeforeExtract" && !node.GetText().empty()) m_bConvertBeforeExtract = std::stoi(node.GetText()); else if(name == L"defaultCsvDelimiter" && !node.GetText().empty()) m_defaultCsvDelimiter = (wchar_t)std::stoi(node.GetText(), nullptr, 16); else if(name == L"inputFilesList" && !node.GetText().empty()) { @@ -418,17 +478,40 @@ void Cx2tTester::SetConfig(const std::wstring& configPath) exit(-1); } - if(default_input_formats) + if (default_input_formats) m_inputExts = m_inputFormatsList.GetAllExts(); - if(default_output_formats) - m_outputExts = m_outputFormatsList.GetAllExts(); + if (default_output_formats) + { + if (m_bExtract) + m_outputExts = m_extractFormatsList.GetAllExts(); + else + m_outputExts = m_outputFormatsList.GetAllExts(); + } + } void Cx2tTester::Start() { // setup timer m_timeStart = NSTimers::GetTickCount(); + m_outputDirectory = CorrectPathW(m_outputDirectory); + m_errorsXmlDirectory = CorrectPathW(m_errorsXmlDirectory); + m_troughConversionDirectory = CorrectPathW(m_troughConversionDirectory); + m_tempDirectory = CorrectPathW(m_tempDirectory); + + // setup & clear output folder + if(NSDirectory::Exists(m_outputDirectory)) + NSDirectory::DeleteDirectory(m_outputDirectory); + + NSDirectory::CreateDirectory(m_outputDirectory); + + // setup & clear errors folder + if(NSDirectory::Exists(m_errorsXmlDirectory)) + NSDirectory::DeleteDirectory(m_errorsXmlDirectory); + + NSDirectory::CreateDirectory(m_errorsXmlDirectory); + // check fonts CApplicationFontsWorker fonts_worker; fonts_worker.m_sDirectory = m_fontsDirectory; @@ -449,42 +532,70 @@ void Cx2tTester::Start() NSFonts::IApplicationFonts* pFonts = fonts_worker.Check(); RELEASEINTERFACE(pFonts); - m_outputDirectory = CorrectPathW(m_outputDirectory); - m_errorsXmlDirectory = CorrectPathW(m_errorsXmlDirectory); - m_troughConversionDirectory = CorrectPathW(m_troughConversionDirectory); - - // setup & clear output folder - if(NSDirectory::Exists(m_outputDirectory)) - NSDirectory::DeleteDirectory(m_outputDirectory); - - NSDirectory::CreateDirectory(m_outputDirectory); - - // setup & clear errors folder - if(NSDirectory::Exists(m_errorsXmlDirectory)) - NSDirectory::DeleteDirectory(m_errorsXmlDirectory); - - NSDirectory::CreateDirectory(m_errorsXmlDirectory); - - std::vector files = NSDirectory::GetFiles(m_inputDirectory, true); for(int i = 0; i < files.size(); i++) { std::wstring& input_file = files[i]; std::wstring input_filename = NSFile::GetFileName(input_file); - std::wstring input_ext = NSFile::GetFileExtention(input_file); + std::wstring input_ext = GetFileExtLower(input_file); // if no format in input formats - skip if(std::find(m_inputExts.begin(), m_inputExts.end(), input_ext) == m_inputExts.end() - || (std::find(m_inputFiles.begin(), m_inputFiles.end(), input_filename) == m_inputFiles.end() - && !m_inputFiles.empty())) + || (std::find(m_inputFiles.begin(), m_inputFiles.end(), input_filename) == m_inputFiles.end() + && !m_inputFiles.empty())) { files.erase(files.begin() + i); i--; } } - if(files.size() < m_maxProc) - m_maxProc = files.size(); + if (m_bExtract) + { + COfficeFileFormatChecker checker; + COfficeUtils utils; + std::vector files_to_convert; + + for (size_t i = 0; i < files.size(); i++) + if (utils.IsArchive(files[i]) == S_FALSE && checker.isOfficeFile(files[i])) + { + if (m_bConvertBeforeExtract) + files_to_convert.push_back(files[i]); + files.erase(files.begin() + i); + } + + if (!files_to_convert.empty()) + { + if(NSDirectory::Exists(m_tempDirectory)) + NSDirectory::DeleteDirectory(m_tempDirectory); + + NSDirectory::CreateDirectories(m_tempDirectory); + + auto copy_inputDirectory = m_inputDirectory; + auto copy_outputDirectory = m_outputDirectory; + auto copy_outputExts = m_outputExts; + + m_outputDirectory = m_tempDirectory; + m_outputExts = {L"docx"}; + + Convert(files_to_convert, true, true); + + m_outputDirectory = copy_outputDirectory; + m_outputExts = copy_outputExts; + + m_inputDirectory = m_tempDirectory; + std::vector temp_files = NSDirectory::GetFiles(m_tempDirectory, true); + Extract(temp_files); + + m_inputDirectory = copy_inputDirectory; + } + + Extract(files); + + if(NSDirectory::Exists(m_tempDirectory)) + NSDirectory::DeleteDirectory(m_tempDirectory); + + return; + } // conversion in _t directory -> _t directory to output if(m_bTroughConversion) @@ -512,26 +623,23 @@ void Cx2tTester::Start() Convert(files); WriteTime(); - - for(auto&& val : m_deleteLaterFiles) - NSFile::CFileBinary::Remove(val); - - for(auto&& val : m_deleteLaterDirectories) - NSDirectory::DeleteDirectory(val); } void Cx2tTester::Convert(const std::vector& files, bool bNoDirectory, bool bTrough) { + if(files.size() < m_maxProc) + m_maxProc = files.size(); + for(int i = 0; i < files.size(); i++) { const std::wstring& input_file = files[i]; std::wstring input_filename = NSFile::GetFileName(input_file); - std::wstring input_ext = NSFile::GetFileExtention(input_file); + std::wstring input_ext = GetFileExtLower(input_file); std::wstring input_file_directory = NSFile::GetDirectoryName(input_file); // takes full directory after input folder std::wstring input_subfolders = input_file_directory.substr(m_inputDirectory.size(), - input_file_directory.size() - m_inputDirectory.size()); + input_file_directory.size() - m_inputDirectory.size()); std::wstring output_files_directory = m_outputDirectory + input_subfolders; if(!bNoDirectory) @@ -544,22 +652,22 @@ void Cx2tTester::Convert(const std::vector& files, bool bNoDirecto { // documents -> documents if(((m_outputFormatsList.IsDocument(ext) && m_inputFormatsList.IsDocument(input_ext)) - // spreadsheets -> spreadsheets - || (m_outputFormatsList.IsSpreadsheet(ext) && m_inputFormatsList.IsSpreadsheet(input_ext)) - //presentations -> presentations - || (m_outputFormatsList.IsPresentation(ext) && m_inputFormatsList.IsPresentation(input_ext)) - // xps -> docx - || (ext == L"docx" && input_ext == L"xps") - // pdf -> docx - || (ext == L"docx" && m_inputFormatsList.IsPdf(input_ext)) - // all formats -> images - || m_outputFormatsList.IsImage(ext) - // all formats -> pdf - || m_outputFormatsList.IsPdf(ext)) - // input format != output format - && ext != input_ext - // any good input ext - && m_inputFormatsList.IsAny(input_ext)) + // spreadsheets -> spreadsheets + || (m_outputFormatsList.IsSpreadsheet(ext) && m_inputFormatsList.IsSpreadsheet(input_ext)) + //presentations -> presentations + || (m_outputFormatsList.IsPresentation(ext) && m_inputFormatsList.IsPresentation(input_ext)) + // xps -> docx + || (ext == L"docx" && input_ext == L"xps") + // pdf -> docx + || (ext == L"docx" && m_inputFormatsList.IsPdf(input_ext)) + // all formats -> images + || m_outputFormatsList.IsImage(ext) + // all formats -> pdf + || m_outputFormatsList.IsPdf(ext)) + // input format != output format + && ext != input_ext + // any good input ext + && m_inputFormatsList.IsAny(input_ext)) { output_file_exts.push_back(ext); } @@ -569,7 +677,7 @@ void Cx2tTester::Convert(const std::vector& files, bool bNoDirecto continue; // setup & clear output subfolder - while(!NSDirectory::Exists(output_files_directory)) + if (!NSDirectory::Exists(output_files_directory)) NSDirectory::CreateDirectories(output_files_directory); std::wstring csvTxtEncodingS = m_defaultCsvTxtEndcoding; @@ -577,8 +685,8 @@ void Cx2tTester::Convert(const std::vector& files, bool bNoDirecto // setup csv & txt additional params if(m_bIsFilenameCsvTxtParams - || input_ext == L"txt" - || input_ext == L"csv") + || input_ext == L"txt" + || input_ext == L"csv") { std::wstring find_str = L"[cp"; size_t pos1 = input_filename.find(find_str); @@ -620,6 +728,8 @@ void Cx2tTester::Convert(const std::vector& files, bool bNoDirecto NSThreads::Sleep(50); } while(IsAllBusy()); + + m_coresCS.Enter(); // setup & start new coverter @@ -652,6 +762,50 @@ void Cx2tTester::Convert(const std::vector& files, bool bNoDirecto while(!IsAllFree()) NSThreads::Sleep(150); } +void Cx2tTester::Extract(const std::vector& files) +{ + if(files.size() < m_maxProc) + m_maxProc = files.size(); + + for (int i = 0; i < files.size(); i++) + { + const std::wstring& input_file = files[i]; + std::wstring input_filename = NSFile::GetFileName(input_file); + std::wstring input_file_directory = NSFile::GetDirectoryName(input_file); + std::wstring input_subfolders = input_file_directory.substr(m_inputDirectory.size(), + input_file_directory.size() - m_inputDirectory.size()); + std::wstring output_files_directory = m_outputDirectory + input_subfolders + FILE_SEPARATOR_STR + input_filename; + + if(!NSDirectory::Exists(output_files_directory)) + NSDirectory::CreateDirectories(output_files_directory); + + // waiting... + do + { + NSThreads::Sleep(50); + } while(IsAllBusy()); + + m_coresCS.Enter(); + + // setup & start new extractor + CExtractor *extractor = new CExtractor(this); + extractor->SetInputFile(input_file); + extractor->SetOutputFilesDirectory(output_files_directory); + extractor->SetExtractExts(m_outputExts); + extractor->SetFilesCount(files.size(), i + 1); + extractor->DestroyOnFinish(); + m_currentProc++; + + m_coresCS.Leave(); + + extractor->Start(0); + } + + // waiting all procs end + while(!IsAllFree()) + NSThreads::Sleep(150); +} + void Cx2tTester::WriteReportHeader() { CTemporaryCS CS(&m_reportCS); @@ -726,6 +880,8 @@ std::vector Cx2tTester::ParseExtensionsString(std::wstring extensi while ((pos = extensions.find(' ')) != std::wstring::npos) { std::wstring ext = extensions.substr(0, pos); + for (auto& c : ext) + c = std::tolower(c); if(ext == L"documents") exts = fl.GetDocuments(); @@ -844,13 +1000,13 @@ DWORD CConverter::ThreadProc() for(int i = 0; i < m_outputExts.size(); i++) { std::wstring output_ext = L"."+ m_outputExts[i]; - int output_format = checker.GetFormatByExtension(output_ext); + int output_format = m_checker.GetFormatByExtension(output_ext); std::wstring xml_params_filename = input_filename + L"_" + output_ext + L".xml"; std::wstring xml_params_file = m_outputFilesDirectory + FILE_SEPARATOR_STR + xml_params_filename; std::wstring output_file = m_outputFilesDirectory - + FILE_SEPARATOR_STR + input_filename_no_ext + output_ext; + + FILE_SEPARATOR_STR + input_filename_no_ext + output_ext; std::wstring output_filename = NSFile::GetFileName(output_file); @@ -1006,7 +1162,7 @@ DWORD CConverter::ThreadProc() Cx2tTester::Report report; report.inputFile = input_filename; report.outputFile = output_filename; - report.direction = input_ext.substr(1, input_ext.size() - 1) + L"-" + output_ext.substr(1, output_ext.size() - 1); + report.direction = m_inputExt + L"-" + output_ext.substr(1, output_ext.size() - 1); report.time = NSTimers::GetTickCount() - time_file_start; report.inputSize = input_size; report.outputSize = output_size; @@ -1077,4 +1233,78 @@ DWORD CConverter::ThreadProc() return 0; } +CExtractor::CExtractor(Cx2tTester* internal) : m_internal(internal) +{ +} +CExtractor::~CExtractor() +{ + Stop(); +} + +void CExtractor::SetInputFile(const std::wstring& inputFile) +{ + m_inputFile = inputFile; +} +void CExtractor::SetOutputFilesDirectory(const std::wstring& outputFilesDirectory) +{ + m_outputFilesDirectory = outputFilesDirectory; +} +void CExtractor::SetExtractExts(const std::vector& extractExts) +{ + m_extractExts = extractExts; +} +void CExtractor::SetFilesCount(int totalFiles, int currFile) +{ + m_totalFiles = totalFiles; + m_currFile = currFile; +} + +DWORD CExtractor::ThreadProc() +{ + std::wstring input_filename = NSFile::GetFileName(m_inputFile); + std::wstring input_ext = L'.' + NSFile::GetFileExtention(input_filename); + std::wstring input_filename_no_ext = input_filename.substr(0, input_filename.size() - input_ext.size()); + + for (size_t i = 0; i < m_extractExts.size(); i++) + { + const std::wstring& extract_ext = m_extractExts[i]; + std::wstring output_folder = m_outputFilesDirectory + FILE_SEPARATOR_STR + extract_ext; + + // output_CS start + m_internal->m_outputCS.Enter(); + + std::cout << "[" << m_currFile << "/" << m_totalFiles << "](" << i + 1 << "/" << m_extractExts.size() << ") "; + std::cout << "(" << m_internal->m_currentProc << " processes now) "; + std::cout << U_TO_UTF8(input_filename) << " extract " << U_TO_UTF8(extract_ext) << " "; + + std::cout << std::endl; + m_internal->m_outputCS.Leave(); + + if (NSDirectory::Exists(output_folder)) + NSDirectory::DeleteDirectory(output_folder); + + NSDirectory::CreateDirectories(output_folder); + std::wstring temp_folder = NSDirectory::CreateDirectoryWithUniqueName(output_folder); + m_utils.ExtractToDirectory(m_inputFile, temp_folder, nullptr, false); + + auto unzip_files = NSDirectory::GetFiles(temp_folder, true); + bool delete_empty = true; + for (const auto& file : unzip_files) + { + if (NSFile::GetFileExtention(file) == m_extractExts[i]) + { + delete_empty = false; + NSFile::CFileBinary::Move(file, output_folder + FILE_SEPARATOR_STR +NSFile::GetFileName(file)); + } + } + if (delete_empty) + NSDirectory::DeleteDirectory(output_folder); + NSDirectory::DeleteDirectory(temp_folder); + } + if (NSDirectory::GetFilesCount(m_outputFilesDirectory, true) == 0) + NSDirectory::DeleteDirectory(m_outputFilesDirectory); + + m_internal->m_currentProc--; + return 0; +} diff --git a/Test/Applications/x2tTester/x2tTester.h b/Test/Applications/x2tTester/x2tTester.h index 47dfac86055..2371235076d 100644 --- a/Test/Applications/x2tTester/x2tTester.h +++ b/Test/Applications/x2tTester/x2tTester.h @@ -32,6 +32,7 @@ class CFormatsList std::vector GetPresentations() const; std::vector GetSpreadsheets() const; std::vector GetCrossplatform() const; + std::vector GetDraw() const; std::vector GetImages() const; std::wstring GetPdf() const; @@ -39,6 +40,7 @@ class CFormatsList bool IsPresentation(const std::wstring& ext) const; bool IsSpreadsheet(const std::wstring& ext) const; bool IsCrossplatform(const std::wstring& ext) const; + bool IsDraw(const std::wstring& ext) const; bool IsImage(const std::wstring& ext) const; bool IsPdf(const std::wstring& ext) const; bool IsAny(const std::wstring& ext) const; @@ -47,6 +49,7 @@ class CFormatsList void AddPresentation(const std::wstring& ext); void AddSpreadsheet(const std::wstring& ext); void AddCrossplatform(const std::wstring& ext); + void AddDraw(const std::wstring& ext); void AddImage(const std::wstring& ext); std::vector GetAllExts() const; @@ -55,7 +58,10 @@ class CFormatsList static CFormatsList GetDefaultExts(); // all writable exts - static CFormatsList GetOutputExts(); + static CFormatsList GetOutputExts(); + + // default exts to extract + static CFormatsList GetExtractExts(); private: std::vector m_documents; @@ -63,6 +69,7 @@ class CFormatsList std::vector m_spreadsheets; std::vector m_crossplatform; std::vector m_images; + std::vector m_draw; std::wstring m_pdf; }; @@ -111,6 +118,7 @@ class Cx2tTester // parse string like "docx txt" into vector std::vector ParseExtensionsString(std::wstring extensions, const CFormatsList& fl); void Convert(const std::vector& files, bool bNoDirectory = false, bool bTrough = false); + void Extract(const std::vector& files); // takes from config std::wstring m_reportFile; @@ -121,6 +129,7 @@ class Cx2tTester std::wstring m_errorsXmlDirectory; std::wstring m_troughConversionDirectory; std::wstring m_fontsDirectory; + std::wstring m_tempDirectory; // fonts bool m_bIsUseSystemFonts; @@ -137,6 +146,7 @@ class Cx2tTester // lists CFormatsList m_inputFormatsList; CFormatsList m_outputFormatsList; + CFormatsList m_extractFormatsList; bool m_bIsErrorsOnly; bool m_bIsTimestamp; @@ -157,6 +167,12 @@ class Cx2tTester std::vector m_deleteLaterFiles; std::vector m_deleteLaterDirectories; + + // extract files with output_ext from input_files + bool m_bExtract; + + // convert to docx before extract + bool m_bConvertBeforeExtract; }; // generates temp xml, convert, calls m_internal->writeReport @@ -194,7 +210,7 @@ class CConverter : public NSThreads::CBaseThread std::wstring m_inputExt; std::wstring m_fontsDirectory; - COfficeFileFormatChecker checker; + COfficeFileFormatChecker m_checker; std::wstring m_x2tPath; std::wstring m_errorsXmlDirectory; @@ -214,4 +230,30 @@ class CConverter : public NSThreads::CBaseThread unsigned long m_timeout; }; +// extracts files from office files +class CExtractor : public NSThreads::CBaseThread +{ +public: + CExtractor(Cx2tTester* internal); + virtual ~CExtractor(); + + void SetInputFile(const std::wstring& inputFile); + void SetOutputFilesDirectory(const std::wstring& outputFilesDirectory); + void SetExtractExts(const std::vector& extractExts); + void SetFilesCount(int totalFiles, int currFile); + + virtual DWORD ThreadProc(); + +private: + Cx2tTester* m_internal; + std::wstring m_inputFile; + std::wstring m_outputFilesDirectory; + std::vector m_extractExts; + COfficeUtils m_utils; + + int m_totalFiles; + int m_currFile; + +}; + #endif // X2T_TESTER_H diff --git a/TxtFile/Source/ConvertTxt2Docx.cpp b/TxtFile/Source/ConvertTxt2Docx.cpp index 3df4a199b48..6a68f2cdcd6 100644 --- a/TxtFile/Source/ConvertTxt2Docx.cpp +++ b/TxtFile/Source/ConvertTxt2Docx.cpp @@ -211,11 +211,11 @@ namespace Txt2Docx } while(line.find(_T("\x09")) != line.npos) { - int pos = line.find(_T("\x09")); + size_t pos = line.find(_T("\x09")); - if (pos > 0) + if (pos != std::wstring::npos) { - std::wstring s = line.substr(0, pos - 1); + std::wstring s = line.substr(0, pos); if (!s.empty()) { OOX::Logic::CRunProperty *rPr_ = new OOX::Logic::CRunProperty(); diff --git a/TxtFile/Source/TxtFormat/TxtFile.cpp b/TxtFile/Source/TxtFormat/TxtFile.cpp index 45d77c9562f..021c2afdeb9 100644 --- a/TxtFile/Source/TxtFormat/TxtFile.cpp +++ b/TxtFile/Source/TxtFormat/TxtFile.cpp @@ -86,6 +86,8 @@ const std::vector TxtFile::readAnsiOrCodePage() // == readUtf8witho const std::vector TxtFile::readUnicodeFromBytes(char *file_data, long file_size) { std::vector result; + if (file_size < 3) return result; + long start_pos = 2; // skip Header for (long end_pos = start_pos; end_pos + 1 < file_size; end_pos += 2) diff --git a/X2tConverter/build/Android/libx2t/build.gradle.kts b/X2tConverter/build/Android/libx2t/build.gradle.kts index 95c76dce55b..198defe4fb4 100644 --- a/X2tConverter/build/Android/libx2t/build.gradle.kts +++ b/X2tConverter/build/Android/libx2t/build.gradle.kts @@ -6,7 +6,6 @@ import org.apache.tools.ant.taskdefs.condition.Os plugins { id("com.android.library") kotlin("android") - id("maven-publish") } apply { @@ -15,31 +14,10 @@ apply { val keystore = extra.get("getKeystore") as org.codehaus.groovy.runtime.MethodClosure -publishing { - publications { - create("maven") { - groupId = PublishEditors.groupId - artifactId = PublishEditors.x2tId - version = PublishEditors.version - artifact("$buildDir/outputs/aar/lib${artifactId}-release.aar") - } - } - repositories { - maven { - name = "GitHubPackages" - url = uri("${PublishEditors.publishUrl}/") - credentials { - username = (keystore() as? java.util.Properties)?.getProperty("git_user_name") ?: "" - password = (keystore() as? java.util.Properties)?.getProperty("git_token") ?: "" - } - } - } -} - android { namespace = "lib.x2t" - compileSdk = AppDependency.COMPILE_SDK_VERSION + compileSdk = libs.versions.compileSdk.get().toInt() ndkVersion = rootProject.extra.get("NDK_VERSION").toString() publishing { @@ -48,8 +26,7 @@ android { } defaultConfig { - minSdk = AppDependency.MIN_SDK_VERSION - targetSdk = AppDependency.TARGET_SDK_VERSION + minSdk = libs.versions.minSdk.get().toInt() buildConfigField("String", "LIB_X2T", "\"${extra.get("NAME_LIB")}\"") @@ -57,40 +34,33 @@ android { cmake { arguments( "-DANDROID_TOOLCHAIN=clang", - "-DANDROID_STL=c++_static", + "-DANDROID_STL=c++_shared", "-DANDROID_ARM_NEON=TRUE", "-DARG_PATH_LIB_BUILD_TOOLS=${getProjectPath(extra.get("PATH_LIB_BUILD_TOOLS") as String)}", - "-DARG_PATH_LIB_DST=${getProjectPath(extra.get("PATH_LIB_DST") as String, true)}", "-DARG_PATH_SRC_CORE=${getProjectPath(extra.get("PATH_SRC_CORE") as String)}", "-DARG_NAME_LIB=${extra.get("NAME_LIB")}" ) } } - - ndk { - abiFilters.addAll(arrayOf("armeabi-v7a", "arm64-v8a", "x86", "x86_64")) - } } buildTypes { release { isMinifyEnabled = false proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro") + ndk { + abiFilters.addAll(arrayOf("armeabi-v7a", "arm64-v8a", "x86", "x86_64")) + } } debug { isJniDebuggable = true - } - } - - sourceSets { - getByName("main") { - java.srcDir("src/main/java") - jniLibs.srcDirs( - arrayOf( - extra.get("PATH_LIB_DST") as String, - extra.get("PATH_LIB_BUILD_TOOLS") as String - ) - ) + ndk { + if (System.getProperty("os.arch") == "aarch64") { + abiFilters.add("arm64-v8a") + } else { + abiFilters.addAll(arrayOf("armeabi-v7a", "arm64-v8a", "x86", "x86_64")) + } + } } } @@ -101,8 +71,8 @@ android { } compileOptions { - sourceCompatibility(JavaVersion.VERSION_17) - targetCompatibility(JavaVersion.VERSION_17) + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 } kotlinOptions { @@ -116,21 +86,13 @@ android { packaging { jniLibs.useLegacyPackaging = true arrayOf("armeabi-v7a", "x86", "arm64-v8a", "x86_64").forEach { abi -> - val dh = file("${extra.get("PATH_LIB_BUILD_TOOLS")}/$abi") - dh.listFiles()?.forEach { - if (it.name.contains(".so")) - jniLibs.pickFirsts.add("lib/$abi/${it.name}") - } - jniLibs.pickFirsts.add("lib/$abi/lib${extra.get("NAME_LIB")}.so") - jniLibs.pickFirsts.add("lib/$abi/lib${extra.get("NAME_LIB_KERNEL_NETWORK")}.so") + jniLibs.pickFirsts.add("lib/$abi/libc++_shared.so") } } } dependencies { implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar")))) - implementation("androidx.appcompat:appcompat:1.6.1") - implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:${rootProject.extra.get("kotlin_version")}") } diff --git a/X2tConverter/build/Android/libx2t/src/main/cpp/CMakeLists.txt b/X2tConverter/build/Android/libx2t/src/main/cpp/CMakeLists.txt index 9bfe12baa0c..05c0cb17092 100644 --- a/X2tConverter/build/Android/libx2t/src/main/cpp/CMakeLists.txt +++ b/X2tConverter/build/Android/libx2t/src/main/cpp/CMakeLists.txt @@ -47,13 +47,6 @@ elseif (NOT EXISTS ${ARG_PATH_LIB_BUILD_TOOLS}) message(STATUS "Destination 3dParty path doesn't exist, created!") endif() -# X2t destination path -if (NOT DEFINED ARG_PATH_LIB_DST) - message(FATAL_ERROR "You must set argument \"ARG_PATH_LIB_DST\" with path to x2t.so destination...") -elseif (NOT EXISTS ${ARG_PATH_LIB_DST}) - file(MAKE_DIRECTORY ${ARG_PATH_LIB_DST}) - message(STATUS "Destination library path doesn't exist, created!") -endif() # Core source path if (NOT DEFINED ARG_PATH_SRC_CORE) @@ -72,14 +65,13 @@ set(LIB_NAME_X2T_CONVERTER ${ARG_NAME_LIB}) # ---------- Paths sources ---------- # Core src dir path set(CORE_DIR ${ARG_PATH_SRC_CORE}) -set(X2T_CONVERTER_DEST ${ARG_PATH_LIB_DST}/${ANDROID_ABI}) -message(STATUS "X2t Converter destination path: ${X2T_CONVERTER_DEST}") # Prebuild libraries path set(X2T_CONVERTER_LIBS ${ARG_PATH_LIB_BUILD_TOOLS}/${ANDROID_ABI}) message(STATUS "Prebuild libraries path: ${X2T_CONVERTER_LIBS}") -FILE(GLOB new_list "${X2T_CONVERTER_LIBS}/*.so") +SET(new_list libUnicodeConverter.so libkernel.so libkernel_network.so libgraphics.so libPdfFile.so libDjVuFile.so libXpsFile.so libHtmlFile2.so libFb2File.so libEpubFile.so libIWorkFile.so libDocxRenderer.so libdoctrenderer.so libx2t.so libHWPFile.so) + SET(libs_list "") FOREACH(file_path ${new_list}) GET_FILENAME_COMPONENT(file_path ${file_path} NAME) @@ -147,8 +139,6 @@ link_libraries( # Add target library add_library(${LIB_NAME_X2T_CONVERTER} SHARED - ${CORE_DIR}/DesktopEditor/fontengine/FontsAssistant.cpp - ${CORE_DIR}/DesktopEditor/fontengine/ApplicationFontsWorker.cpp jni/X2t.cpp ) @@ -158,12 +148,6 @@ FOREACH(lib ${libs_list}) ${X2T_CONVERTER_LIBS}/${lib}) ENDFOREACH() - -# Export lib to common libs path -set_target_properties(${LIB_NAME_X2T_CONVERTER} - PROPERTIES LIBRARY_OUTPUT_DIRECTORY - ${X2T_CONVERTER_DEST} -) # Searches for a specified prebuilt library and stores the path as a # variable. Because CMake includes system libraries in the search path by # default, you only need to specify the name of the public NDK library diff --git a/X2tConverter/build/Android/libx2t/src/main/cpp/jni/X2t.cpp b/X2tConverter/build/Android/libx2t/src/main/cpp/jni/X2t.cpp index dd126d6bc9d..fa05caa4fc7 100644 --- a/X2tConverter/build/Android/libx2t/src/main/cpp/jni/X2t.cpp +++ b/X2tConverter/build/Android/libx2t/src/main/cpp/jni/X2t.cpp @@ -67,6 +67,7 @@ extern "C" { jjniHashMap.put(env, "AVS_OFFICESTUDIO_FILE_PRESENTATION_POTM", AVS_OFFICESTUDIO_FILE_PRESENTATION_POTM); jjniHashMap.put(env, "AVS_OFFICESTUDIO_FILE_PRESENTATION_ODP_FLAT", AVS_OFFICESTUDIO_FILE_PRESENTATION_ODP_FLAT); jjniHashMap.put(env, "AVS_OFFICESTUDIO_FILE_PRESENTATION_OTP", AVS_OFFICESTUDIO_FILE_PRESENTATION_OTP); + jjniHashMap.put(env, "AVS_OFFICESTUDIO_FILE_PRESENTATION_KEY", AVS_OFFICESTUDIO_FILE_PRESENTATION_KEY); jjniHashMap.put(env, "AVS_OFFICESTUDIO_FILE_SPREADSHEET", AVS_OFFICESTUDIO_FILE_SPREADSHEET); jjniHashMap.put(env, "AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSX", AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSX); @@ -78,6 +79,7 @@ extern "C" { jjniHashMap.put(env, "AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLTM", AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLTM); jjniHashMap.put(env, "AVS_OFFICESTUDIO_FILE_SPREADSHEET_ODS_FLAT", AVS_OFFICESTUDIO_FILE_SPREADSHEET_ODS_FLAT); jjniHashMap.put(env, "AVS_OFFICESTUDIO_FILE_SPREADSHEET_OTS", AVS_OFFICESTUDIO_FILE_SPREADSHEET_OTS); + jjniHashMap.put(env, "AVS_OFFICESTUDIO_FILE_SPREADSHEET_NUMBERS", AVS_OFFICESTUDIO_FILE_SPREADSHEET_NUMBERS); jjniHashMap.put(env, "AVS_OFFICESTUDIO_FILE_CROSSPLATFORM", AVS_OFFICESTUDIO_FILE_CROSSPLATFORM); jjniHashMap.put(env, "AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_PDF", AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_PDF); @@ -126,6 +128,10 @@ extern "C" { jjniHashMap.put(env, "AVS_OFFICESTUDIO_FILE_CANVAS_SPREADSHEET", AVS_OFFICESTUDIO_FILE_CANVAS_SPREADSHEET); jjniHashMap.put(env, "AVS_OFFICESTUDIO_FILE_CANVAS_PRESENTATION", AVS_OFFICESTUDIO_FILE_CANVAS_PRESENTATION); jjniHashMap.put(env, "AVS_OFFICESTUDIO_FILE_CANVAS_PDF", AVS_OFFICESTUDIO_FILE_CANVAS_PDF); + jjniHashMap.put(env, "AVS_OFFICESTUDIO_FILE_DOCUMENT_OFORM_PDF", AVS_OFFICESTUDIO_FILE_DOCUMENT_OFORM_PDF); + jjniHashMap.put(env, "AVS_OFFICESTUDIO_FILE_DOCUMENT_PAGES", AVS_OFFICESTUDIO_FILE_DOCUMENT_PAGES); + jjniHashMap.put(env, "AVS_OFFICESTUDIO_FILE_DOCUMENT_HWP", AVS_OFFICESTUDIO_FILE_DOCUMENT_HWP); + jjniHashMap.put(env, "AVS_OFFICESTUDIO_FILE_DOCUMENT_HWPX", AVS_OFFICESTUDIO_FILE_DOCUMENT_HWPX); jobject res = jjniHashMap.toJniObject(env); jjniHashMap.destroy(env); @@ -168,6 +174,10 @@ extern "C" { }) } + JNI_FUNC(int, getFileFormat)(JNIEnv* env, jclass type, jstring jPath) { + auto path = JniBaseObjects::jstringToWString(env, jPath); + return GetOfficeFileFormat((wchar_t *) path.c_str()); + } } diff --git a/X2tConverter/build/Android/libx2t/src/main/cpp/jni/objects/JniBaseObjects.h b/X2tConverter/build/Android/libx2t/src/main/cpp/jni/objects/JniBaseObjects.h index 4522a3f1fc3..ba56a040866 100644 --- a/X2tConverter/build/Android/libx2t/src/main/cpp/jni/objects/JniBaseObjects.h +++ b/X2tConverter/build/Android/libx2t/src/main/cpp/jni/objects/JniBaseObjects.h @@ -3,10 +3,9 @@ #include #include -#include -#include #include #include +#include "../../../../../../../../../DesktopEditor/common/File.h" #define DELETE_LOCAL_REF(ENV, REFERENCE) \ if (REFERENCE != NULL && !ENV->IsSameObject(REFERENCE, NULL)) { \ @@ -140,8 +139,8 @@ class JniBaseObjects { static std::string jstringToString(JNIEnv* env, jstring jstr) { jboolean isCopy; const char * charPath = env->GetStringUTFChars(jstr, &isCopy); - const int size = env->GetStringLength(jstr); - const std::string str(charPath, charPath + size); + const int size = env->GetStringUTFLength(jstr); + const std::string str(charPath, (size_t)size); env->ReleaseStringUTFChars(jstr, charPath); return str; } @@ -149,23 +148,28 @@ class JniBaseObjects { static std::string* jstringToPString(JNIEnv* env, jstring jstr) { jboolean isCopy; const char * charPath = env->GetStringUTFChars(jstr, &isCopy); - const int size = env->GetStringLength(jstr); - std::string* pStr = new std::string(charPath, charPath + size); + const int size = env->GetStringUTFLength(jstr); + std::string* pStr = new std::string(charPath, (size_t)size); env->ReleaseStringUTFChars(jstr, charPath); return pStr; } static std::wstring jstringToWString(JNIEnv* env, jstring jstr) { jboolean isCopy; - const char * cstr = env->GetStringUTFChars(jstr, &isCopy); - const int size = env->GetStringLength(jstr); - const std::wstring wstr = charsToWString(cstr); - env->ReleaseStringUTFChars(jstr, cstr); - return wstr; + const char * charPath = env->GetStringUTFChars(jstr, &isCopy); + const int size = env->GetStringUTFLength(jstr); + std::wstring pStr = NSFile::CUtf8Converter::GetUnicodeStringFromUTF8((BYTE*)charPath, (LONG)size); + env->ReleaseStringUTFChars(jstr, charPath); + return pStr; } - static jstring wStringToJString(JNIEnv* env, const std::wstring wstr) { - return env->NewStringUTF(wStringToString(wstr).c_str()); + static jstring wStringToJString(JNIEnv* env, const std::wstring& wstr) { + std::string sTmp = U_TO_UTF8(wstr); + return stringToJString(env, sTmp); + } + + static jstring stringToJString(JNIEnv* env, const std::string& str) { + return env->NewStringUTF(str.c_str()); } static jstring charToJString(JNIEnv* env, const char * str) { @@ -184,24 +188,6 @@ class JniBaseObjects { return jArray; } - static std::wstring charsToWString(const char * str) { - using convert_typeX = std::codecvt_utf8; - std::wstring_convert converterX; - return converterX.from_bytes(str); - } - - static std::wstring stringToWString(const std::string & str) { - using convert_typeX = std::codecvt_utf8; - std::wstring_convert converterX; - return converterX.from_bytes(str); - } - - static std::string wStringToString(const std::wstring & str) { - using convert_typeX = std::codecvt_utf8; - std::wstring_convert converterX; - return converterX.to_bytes(str); - } - static jobjectArray wStringToObjectArray(JNIEnv *jEnv, std::wstring *data, int length) { jobjectArray jObjectArray = NULL; jsize len = length; diff --git a/X2tConverter/build/Android/libx2t/src/main/java/lib/x2t/X2t.kt b/X2tConverter/build/Android/libx2t/src/main/java/lib/x2t/X2t.kt index 7e1d0100ff6..a5c12ebb15d 100644 --- a/X2tConverter/build/Android/libx2t/src/main/java/lib/x2t/X2t.kt +++ b/X2tConverter/build/Android/libx2t/src/main/java/lib/x2t/X2t.kt @@ -1,11 +1,8 @@ package lib.x2t -import android.Manifest.permission.READ_EXTERNAL_STORAGE -import android.Manifest.permission.WRITE_EXTERNAL_STORAGE import android.annotation.SuppressLint import android.content.Context import android.util.Xml -import androidx.annotation.RequiresPermission import lib.x2t.data.Encoding import lib.x2t.utils.FileUtils import org.xmlpull.v1.XmlSerializer @@ -47,7 +44,6 @@ class X2t private constructor() { @JvmStatic external fun setFonts(fontsPaths: Array, cacheFontsPath: String?) - @RequiresPermission(allOf = [READ_EXTERNAL_STORAGE, WRITE_EXTERNAL_STORAGE]) @JvmStatic external fun convertFile(pathXml: String): Int @@ -57,6 +53,9 @@ class X2t private constructor() { @JvmStatic external fun setIcuDataPath(icuDataPath: String?) + @JvmStatic + external fun getFileFormat(path: String): Int + /* * Builder for converter * */ @@ -148,10 +147,10 @@ class X2t private constructor() { var formatFrom: Int = 0 var formatTo: Int = 0 - var isNoBase64:Boolean = false - var isFromChange:Boolean = false - var isPaid:Boolean = false - var isTemplate:Boolean = false + var isNoBase64: Boolean = false + var isFromChange: Boolean = false + var isPaid: Boolean = false + var isTemplate: Boolean = false } @@ -239,8 +238,6 @@ class X2t private constructor() { } - - @RequiresPermission(allOf = [READ_EXTERNAL_STORAGE, WRITE_EXTERNAL_STORAGE]) fun convert(context: Context): ConvertResult { val result = ConvertResult() @@ -278,7 +275,7 @@ class X2t private constructor() { delimiterCode.equals( InputParams.DELIMITER_CODE_NONE ).let { - if(it) + if (it) null else delimiterCode.toString() @@ -286,11 +283,11 @@ class X2t private constructor() { encoding.equals( 0 ).let { - if(it) + if (it) null else encoding.toString() - } ) + }) result.code = convertFile(xml!!) } @@ -305,12 +302,17 @@ class X2t private constructor() { } @Throws(IOException::class) - private fun insertParam(xmlSerializer: XmlSerializer, startTag: String, text: String?, atrr: HashMap? = null, endTag: String = startTag) - { + private fun insertParam( + xmlSerializer: XmlSerializer, + startTag: String, + text: String?, + atrr: HashMap? = null, + endTag: String = startTag + ) { xmlSerializer.startTag(null, startTag) atrr?.let { - it.forEach { - (key, value) -> xmlSerializer.attribute(null, key, value) + it.forEach { (key, value) -> + xmlSerializer.attribute(null, key, value) } } text?.let { @@ -319,19 +321,20 @@ class X2t private constructor() { xmlSerializer.endTag(null, endTag) } - private fun createXmlFileTransform(xmlDirectory: String?, - key: String?, - format: String?, - from: String?, - to: String?, - temp: String?, - fonts: String?, - themes: String?, - password: String?, - delimiter: String?, - delimiterChar: String?, - encoding: String?) - { + private fun createXmlFileTransform( + xmlDirectory: String?, + key: String?, + format: String?, + from: String?, + to: String?, + temp: String?, + fonts: String?, + themes: String?, + password: String?, + delimiter: String?, + delimiterChar: String?, + encoding: String? + ) { try { val fileOutputStream = FileOutputStream(xmlDirectory) val xmlSerializer: XmlSerializer = Xml.newSerializer() @@ -340,49 +343,49 @@ class X2t private constructor() { xmlSerializer.setOutput(writer) xmlSerializer.startDocument("UTF-8", null) xmlSerializer.startTag(null, "TaskQueueDataConvert") - xmlSerializer.attribute(null,"xmlns:xsi","""http://www.w3.org/2001/XMLSchema-instance""") - xmlSerializer.attribute(null,"xmlns:xsd", """http://www.w3.org/2001/XMLSchema""") - - insertParam(xmlSerializer,"m_sKey", key ) - insertParam(xmlSerializer,"m_nFormatTo", format ) - insertParam(xmlSerializer,"m_sFileFrom", from ) - insertParam(xmlSerializer,"m_sFileTo", to ) - insertParam(xmlSerializer,"m_sTempDir", temp ) - insertParam(xmlSerializer,"m_sFontDir", fonts ) - insertParam(xmlSerializer,"m_sThemeDir", themes ) - - password?.let{ - insertParam(xmlSerializer,"m_sPassword", password ) + xmlSerializer.attribute(null, "xmlns:xsi", """http://www.w3.org/2001/XMLSchema-instance""") + xmlSerializer.attribute(null, "xmlns:xsd", """http://www.w3.org/2001/XMLSchema""") + + insertParam(xmlSerializer, "m_sKey", key) + insertParam(xmlSerializer, "m_nFormatTo", format) + insertParam(xmlSerializer, "m_sFileFrom", from) + insertParam(xmlSerializer, "m_sFileTo", to) + insertParam(xmlSerializer, "m_sTempDir", temp) + insertParam(xmlSerializer, "m_sFontDir", fonts) + insertParam(xmlSerializer, "m_sThemeDir", themes) + + password?.let { + insertParam(xmlSerializer, "m_sPassword", password) if (isSave && password.isNotEmpty()) { - insertParam(xmlSerializer,"m_sSavePassword", password) + insertParam(xmlSerializer, "m_sSavePassword", password) } } - insertParam(xmlSerializer,"m_bIsPDFA", null, hashMapOf("xsi:nil" to """true""")) + insertParam(xmlSerializer, "m_bIsPDFA", null, hashMapOf("xsi:nil" to """true""")) - delimiter?.let{ - insertParam(xmlSerializer,"m_nCsvDelimiter", delimiter) + delimiter?.let { + insertParam(xmlSerializer, "m_nCsvDelimiter", delimiter) } ?: run { - insertParam(xmlSerializer,"m_nCsvDelimiter", null, hashMapOf("xsi:nil" to """false""")) + insertParam(xmlSerializer, "m_nCsvDelimiter", null, hashMapOf("xsi:nil" to """false""")) } - delimiterChar?.let{ - insertParam(xmlSerializer,"m_nCsvDelimiterChar", delimiterChar) + delimiterChar?.let { + insertParam(xmlSerializer, "m_nCsvDelimiterChar", delimiterChar) } ?: run { - insertParam(xmlSerializer,"m_nCsvDelimiterChar", null, hashMapOf("xsi:nil" to """false""")) + insertParam(xmlSerializer, "m_nCsvDelimiterChar", null, hashMapOf("xsi:nil" to """false""")) } - encoding?.let{ - insertParam(xmlSerializer,"m_nCsvTxtEncoding", encoding) + encoding?.let { + insertParam(xmlSerializer, "m_nCsvTxtEncoding", encoding) } ?: run { - insertParam(xmlSerializer,"m_nCsvTxtEncoding", null, hashMapOf("xsi:nil" to """false""")) + insertParam(xmlSerializer, "m_nCsvTxtEncoding", null, hashMapOf("xsi:nil" to """false""")) } - insertParam(xmlSerializer,"m_bPaid", null, hashMapOf("xsi:nil" to """true""")) - insertParam(xmlSerializer,"m_bEmbeddedFonts", "false") - insertParam(xmlSerializer,"m_bFromChanges", null, hashMapOf("xsi:nil" to """false""")) - insertParam(xmlSerializer,"m_nDoctParams", null, hashMapOf("xsi:nil" to """false""")) - insertParam(xmlSerializer,"m_bIsNoBase64", "true" ) + insertParam(xmlSerializer, "m_bPaid", null, hashMapOf("xsi:nil" to """true""")) + insertParam(xmlSerializer, "m_bEmbeddedFonts", "false") + insertParam(xmlSerializer, "m_bFromChanges", null, hashMapOf("xsi:nil" to """false""")) + insertParam(xmlSerializer, "m_nDoctParams", null, hashMapOf("xsi:nil" to """false""")) + insertParam(xmlSerializer, "m_bIsNoBase64", "true") xmlSerializer.endTag(null, "TaskQueueDataConvert") @@ -391,8 +394,7 @@ class X2t private constructor() { val dataWrite: String = writer.toString() fileOutputStream.write(dataWrite.toByteArray()) fileOutputStream.close() - } - catch (e: FileNotFoundException) { + } catch (e: FileNotFoundException) { e.printStackTrace() } catch (e: IllegalArgumentException) { diff --git a/X2tConverter/build/Android/libx2t/src/main/java/lib/x2t/utils/FileUtils.kt b/X2tConverter/build/Android/libx2t/src/main/java/lib/x2t/utils/FileUtils.kt index a670deb8303..b1242a843d5 100644 --- a/X2tConverter/build/Android/libx2t/src/main/java/lib/x2t/utils/FileUtils.kt +++ b/X2tConverter/build/Android/libx2t/src/main/java/lib/x2t/utils/FileUtils.kt @@ -1,10 +1,8 @@ package lib.x2t.utils -import android.Manifest.permission.WRITE_EXTERNAL_STORAGE import android.content.Context -import androidx.annotation.RequiresPermission import java.io.File -import java.util.* +import java.util.UUID object FileUtils { @@ -28,7 +26,6 @@ object FileUtils { return File(path).let { it.isDirectory && it.exists() || it.mkdirs() } } - @RequiresPermission(WRITE_EXTERNAL_STORAGE) @JvmStatic fun deletePath(path: File): Int { var count = 0 @@ -43,7 +40,6 @@ object FileUtils { return count } - @RequiresPermission(WRITE_EXTERNAL_STORAGE) @JvmStatic fun deletePath(path: String): Int { return deletePath(File(path)) diff --git a/X2tConverter/build/Mac/OdfOfficeConverter/OdfOfficeConverter.xcodeproj/project.pbxproj b/X2tConverter/build/Mac/OdfOfficeConverter/OdfOfficeConverter.xcodeproj/project.pbxproj deleted file mode 100644 index 09f06340db5..00000000000 --- a/X2tConverter/build/Mac/OdfOfficeConverter/OdfOfficeConverter.xcodeproj/project.pbxproj +++ /dev/null @@ -1,938 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 50; - objects = { - -/* Begin PBXBuildFile section */ - 17513B092216E721008B45F7 /* OdfOfficeConverter.mm in Sources */ = {isa = PBXBuildFile; fileRef = 17513B082216E721008B45F7 /* OdfOfficeConverter.mm */; }; - 17513B0A2216E721008B45F7 /* OdfOfficeConverter.h in Headers */ = {isa = PBXBuildFile; fileRef = 17513B072216E721008B45F7 /* OdfOfficeConverter.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 17513DD12216E785008B45F7 /* sax_xmllite.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513C772216E784008B45F7 /* sax_xmllite.cpp */; }; - 17513DD22216E785008B45F7 /* utils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513C782216E784008B45F7 /* utils.cpp */; }; - 17513DD32216E785008B45F7 /* sax.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513C7A2216E784008B45F7 /* sax.cpp */; }; - 17513DD42216E785008B45F7 /* xmlchar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513C7B2216E784008B45F7 /* xmlchar.cpp */; }; - 17513DD52216E785008B45F7 /* attributes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513C7C2216E784008B45F7 /* attributes.cpp */; }; - 17513DD62216E785008B45F7 /* CPString.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513C7E2216E784008B45F7 /* CPString.cpp */; }; - 17513DD72216E785008B45F7 /* CPColorUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513C7F2216E784008B45F7 /* CPColorUtils.cpp */; }; - 17513DD82216E785008B45F7 /* readdocelement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513C802216E784008B45F7 /* readdocelement.cpp */; }; - 17513DD92216E785008B45F7 /* ConvertOO2OOX.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513C822216E784008B45F7 /* ConvertOO2OOX.cpp */; }; - 17513DDA2216E785008B45F7 /* conversionelement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513C832216E784008B45F7 /* conversionelement.cpp */; }; - 17513DDB2216E785008B45F7 /* xlsx_font.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513C852216E784008B45F7 /* xlsx_font.cpp */; }; - 17513DDC2216E785008B45F7 /* pptx_drawings.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513C862216E784008B45F7 /* pptx_drawings.cpp */; }; - 17513DDD2216E785008B45F7 /* xlsx_alignment.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513C882216E784008B45F7 /* xlsx_alignment.cpp */; }; - 17513DDE2216E785008B45F7 /* xlsx_fill.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513C892216E784008B45F7 /* xlsx_fill.cpp */; }; - 17513DDF2216E785008B45F7 /* oox_chart_series.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513C8A2216E784008B45F7 /* oox_chart_series.cpp */; }; - 17513DE02216E785008B45F7 /* pptx_comments.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513C8F2216E784008B45F7 /* pptx_comments.cpp */; }; - 17513DE12216E785008B45F7 /* xlsx_conditionalFormatting.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513C932216E784008B45F7 /* xlsx_conditionalFormatting.cpp */; }; - 17513DE22216E785008B45F7 /* docx_content_type.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513C952216E784008B45F7 /* docx_content_type.cpp */; }; - 17513DE32216E785008B45F7 /* xlsx_protection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513C962216E784008B45F7 /* xlsx_protection.cpp */; }; - 17513DE42216E785008B45F7 /* xlsx_styles.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513C9A2216E784008B45F7 /* xlsx_styles.cpp */; }; - 17513DE52216E785008B45F7 /* xlsx_merge_cells.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513C9C2216E784008B45F7 /* xlsx_merge_cells.cpp */; }; - 17513DE62216E785008B45F7 /* pptx_text_context.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513C9E2216E784008B45F7 /* pptx_text_context.cpp */; }; - 17513DE72216E785008B45F7 /* oox_chart_legend.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513CA02216E784008B45F7 /* oox_chart_legend.cpp */; }; - 17513DE82216E785008B45F7 /* xlsx_hyperlinks.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513CA22216E784008B45F7 /* xlsx_hyperlinks.cpp */; }; - 17513DE92216E785008B45F7 /* xlsx_numFmts.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513CA72216E784008B45F7 /* xlsx_numFmts.cpp */; }; - 17513DEA2216E785008B45F7 /* oox_chart_axis.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513CA82216E784008B45F7 /* oox_chart_axis.cpp */; }; - 17513DEB2216E785008B45F7 /* hyperlinks.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513CAC2216E784008B45F7 /* hyperlinks.cpp */; }; - 17513DEC2216E785008B45F7 /* headers_footers.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513CAE2216E784008B45F7 /* headers_footers.cpp */; }; - 17513DED2216E785008B45F7 /* xlsxconversioncontext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513CB02216E784008B45F7 /* xlsxconversioncontext.cpp */; }; - 17513DEE2216E785008B45F7 /* xlsx_output_xml.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513CB22216E784008B45F7 /* xlsx_output_xml.cpp */; }; - 17513DEF2216E785008B45F7 /* xlsx_table_state.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513CB32216E784008B45F7 /* xlsx_table_state.cpp */; }; - 17513DF02216E785008B45F7 /* oox_chart_context.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513CB52216E784008B45F7 /* oox_chart_context.cpp */; }; - 17513DF12216E785008B45F7 /* xlsx_border.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513CB72216E784008B45F7 /* xlsx_border.cpp */; }; - 17513DF22216E785008B45F7 /* xlsx_data_validation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513CBD2216E784008B45F7 /* xlsx_data_validation.cpp */; }; - 17513DF32216E785008B45F7 /* xlsx_num_format_context.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513CBF2216E784008B45F7 /* xlsx_num_format_context.cpp */; }; - 17513DF42216E785008B45F7 /* xlsx_cell_format.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513CC02216E784008B45F7 /* xlsx_cell_format.cpp */; }; - 17513DF52216E785008B45F7 /* oox_rels.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513CC12216E784008B45F7 /* oox_rels.cpp */; }; - 17513DF62216E785008B45F7 /* xlsx_borders.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513CC32216E784008B45F7 /* xlsx_borders.cpp */; }; - 17513DF72216E785008B45F7 /* pptx_output_xml.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513CC42216E784008B45F7 /* pptx_output_xml.cpp */; }; - 17513DF82216E785008B45F7 /* oox_plot_area.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513CC72216E784008B45F7 /* oox_plot_area.cpp */; }; - 17513DF92216E785008B45F7 /* xlsx_dxfs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513CC92216E784008B45F7 /* xlsx_dxfs.cpp */; }; - 17513DFA2216E785008B45F7 /* xlsx_xf.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513CCC2216E784008B45F7 /* xlsx_xf.cpp */; }; - 17513DFB2216E785008B45F7 /* measuredigits.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513CCF2216E784008B45F7 /* measuredigits.cpp */; }; - 17513DFC2216E785008B45F7 /* mediaitems.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513CD02216E784008B45F7 /* mediaitems.cpp */; }; - 17513DFD2216E785008B45F7 /* namespaces.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513CD12216E784008B45F7 /* namespaces.cpp */; }; - 17513DFE2216E785008B45F7 /* pptx_comments_context.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513CD52216E784008B45F7 /* pptx_comments_context.cpp */; }; - 17513DFF2216E785008B45F7 /* xlsx_tablecontext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513CD82216E784008B45F7 /* xlsx_tablecontext.cpp */; }; - 17513E002216E785008B45F7 /* xlsx_utils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513CD92216E784008B45F7 /* xlsx_utils.cpp */; }; - 17513E012216E785008B45F7 /* oox_package.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513CDA2216E784008B45F7 /* oox_package.cpp */; }; - 17513E022216E785008B45F7 /* pptx_slide_context.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513CDC2216E784008B45F7 /* pptx_slide_context.cpp */; }; - 17513E032216E785008B45F7 /* oox_types_chart.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513CDD2216E784008B45F7 /* oox_types_chart.cpp */; }; - 17513E042216E785008B45F7 /* oox_title.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513CDE2216E784008B45F7 /* oox_title.cpp */; }; - 17513E052216E785008B45F7 /* docx_table_context.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513CE02216E784008B45F7 /* docx_table_context.cpp */; }; - 17513E062216E785008B45F7 /* xlsx_package.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513CE12216E784008B45F7 /* xlsx_package.cpp */; }; - 17513E072216E785008B45F7 /* pptx_conversion_context.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513CE42216E784008B45F7 /* pptx_conversion_context.cpp */; }; - 17513E082216E785008B45F7 /* pptx_drawing.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513CE82216E784008B45F7 /* pptx_drawing.cpp */; }; - 17513E092216E785008B45F7 /* xlsx_table_metrics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513CEB2216E784008B45F7 /* xlsx_table_metrics.cpp */; }; - 17513E0A2216E785008B45F7 /* oox_data_labels.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513CEF2216E784008B45F7 /* oox_data_labels.cpp */; }; - 17513E0B2216E785008B45F7 /* docx_drawing.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513CF02216E784008B45F7 /* docx_drawing.cpp */; }; - 17513E0C2216E785008B45F7 /* xlsx_fills.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513CF22216E784008B45F7 /* xlsx_fills.cpp */; }; - 17513E0D2216E785008B45F7 /* oox_layout.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513CF42216E784008B45F7 /* oox_layout.cpp */; }; - 17513E0E2216E785008B45F7 /* docx_conversion_context.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513CF82216E784008B45F7 /* docx_conversion_context.cpp */; }; - 17513E0F2216E785008B45F7 /* pptx_package.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513CF92216E784008B45F7 /* pptx_package.cpp */; }; - 17513E102216E785008B45F7 /* xlsx_comments_context.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513CFD2216E784008B45F7 /* xlsx_comments_context.cpp */; }; - 17513E112216E785008B45F7 /* pptx_table_context.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513CFE2216E784008B45F7 /* pptx_table_context.cpp */; }; - 17513E122216E785008B45F7 /* xlsx_fonts.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513CFF2216E784008B45F7 /* xlsx_fonts.cpp */; }; - 17513E132216E785008B45F7 /* xlsx_drawing_context.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513D022216E784008B45F7 /* xlsx_drawing_context.cpp */; }; - 17513E142216E785008B45F7 /* docx_package.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513D032216E784008B45F7 /* docx_package.cpp */; }; - 17513E152216E785008B45F7 /* oox_drawing_fills.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513D042216E784008B45F7 /* oox_drawing_fills.cpp */; }; - 17513E162216E785008B45F7 /* xlsx_textcontext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513D052216E784008B45F7 /* xlsx_textcontext.cpp */; }; - 17513E172216E785008B45F7 /* oox_drawing.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513D082216E784008B45F7 /* oox_drawing.cpp */; }; - 17513E182216E785008B45F7 /* xlsx_sharedstrings.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513D092216E784008B45F7 /* xlsx_sharedstrings.cpp */; }; - 17513E192216E786008B45F7 /* xlsx_cell_styles.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513D0D2216E784008B45F7 /* xlsx_cell_styles.cpp */; }; - 17513E1A2216E786008B45F7 /* xlsx_drawings.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513D0E2216E784008B45F7 /* xlsx_drawings.cpp */; }; - 17513E1B2216E786008B45F7 /* oox_chart_shape.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513D102216E784008B45F7 /* oox_chart_shape.cpp */; }; - 17513E1C2216E786008B45F7 /* xlsx_color.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513D112216E784008B45F7 /* xlsx_color.cpp */; }; - 17513E1D2216E786008B45F7 /* xlsx_pivots_context.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513D132216E784008B45F7 /* xlsx_pivots_context.cpp */; }; - 17513E1E2216E786008B45F7 /* xlsx_complex_number_format.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513D162216E784008B45F7 /* xlsx_complex_number_format.cpp */; }; - 17513E1F2216E786008B45F7 /* xlsx_cell_style.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513D172216E784008B45F7 /* xlsx_cell_style.cpp */; }; - 17513E202216E786008B45F7 /* oox_conversion_context.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513D182216E784008B45F7 /* oox_conversion_context.cpp */; }; - 17513E212216E786008B45F7 /* xlsx_drawing.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513D192216E785008B45F7 /* xlsx_drawing.cpp */; }; - 17513E222216E786008B45F7 /* xlsx_comments.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513D1A2216E785008B45F7 /* xlsx_comments.cpp */; }; - 17513E232216E786008B45F7 /* xlsx_defined_names.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513D1C2216E785008B45F7 /* xlsx_defined_names.cpp */; }; - 17513E272216E8D1008B45F7 /* cextracttools.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513E252216E8D0008B45F7 /* cextracttools.cpp */; }; - 8A5834E9221D90BE0029F06B /* formulasconvert_odf.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A5834E6221D90BE0029F06B /* formulasconvert_odf.cpp */; }; - 8A5834EA221D90BE0029F06B /* formulasconvert_oox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A5834E8221D90BE0029F06B /* formulasconvert_oox.cpp */; }; - 8A8753C52227F45600117573 /* OdfOfficeConverter.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 17513B072216E721008B45F7 /* OdfOfficeConverter.h */; }; -/* End PBXBuildFile section */ - -/* Begin PBXCopyFilesBuildPhase section */ - 17513B022216E721008B45F7 /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = "include/$(PRODUCT_NAME)"; - dstSubfolderSpec = 16; - files = ( - 8A8753C52227F45600117573 /* OdfOfficeConverter.h in CopyFiles */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXCopyFilesBuildPhase section */ - -/* Begin PBXFileReference section */ - 17513B042216E721008B45F7 /* libOdfOfficeConverter.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libOdfOfficeConverter.a; sourceTree = BUILT_PRODUCTS_DIR; }; - 17513B072216E721008B45F7 /* OdfOfficeConverter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OdfOfficeConverter.h; sourceTree = ""; }; - 17513B082216E721008B45F7 /* OdfOfficeConverter.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = OdfOfficeConverter.mm; sourceTree = ""; }; - 17513B132216E783008B45F7 /* conversionelement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = conversionelement.h; sourceTree = ""; }; - 17513C752216E784008B45F7 /* ConvertOO2OOX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ConvertOO2OOX.h; sourceTree = ""; }; - 17513C772216E784008B45F7 /* sax_xmllite.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sax_xmllite.cpp; sourceTree = ""; }; - 17513C782216E784008B45F7 /* utils.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = utils.cpp; sourceTree = ""; }; - 17513C792216E784008B45F7 /* sax_xmllite.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sax_xmllite.h; sourceTree = ""; }; - 17513C7A2216E784008B45F7 /* sax.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sax.cpp; sourceTree = ""; }; - 17513C7B2216E784008B45F7 /* xmlchar.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = xmlchar.cpp; sourceTree = ""; }; - 17513C7C2216E784008B45F7 /* attributes.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = attributes.cpp; sourceTree = ""; }; - 17513C7E2216E784008B45F7 /* CPString.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CPString.cpp; sourceTree = ""; }; - 17513C7F2216E784008B45F7 /* CPColorUtils.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CPColorUtils.cpp; sourceTree = ""; }; - 17513C802216E784008B45F7 /* readdocelement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = readdocelement.cpp; sourceTree = ""; }; - 17513C812216E784008B45F7 /* progressCallback.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = progressCallback.h; sourceTree = ""; }; - 17513C822216E784008B45F7 /* ConvertOO2OOX.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ConvertOO2OOX.cpp; sourceTree = ""; }; - 17513C832216E784008B45F7 /* conversionelement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = conversionelement.cpp; sourceTree = ""; }; - 17513C852216E784008B45F7 /* xlsx_font.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = xlsx_font.cpp; sourceTree = ""; }; - 17513C862216E784008B45F7 /* pptx_drawings.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = pptx_drawings.cpp; sourceTree = ""; }; - 17513C872216E784008B45F7 /* xlsx_cell_style.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xlsx_cell_style.h; sourceTree = ""; }; - 17513C882216E784008B45F7 /* xlsx_alignment.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = xlsx_alignment.cpp; sourceTree = ""; }; - 17513C892216E784008B45F7 /* xlsx_fill.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = xlsx_fill.cpp; sourceTree = ""; }; - 17513C8A2216E784008B45F7 /* oox_chart_series.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = oox_chart_series.cpp; sourceTree = ""; }; - 17513C8B2216E784008B45F7 /* pptx_drawings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pptx_drawings.h; sourceTree = ""; }; - 17513C8C2216E784008B45F7 /* oox_rels.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = oox_rels.h; sourceTree = ""; }; - 17513C8D2216E784008B45F7 /* pptx_slide_context.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pptx_slide_context.h; sourceTree = ""; }; - 17513C8E2216E784008B45F7 /* xlsx_package.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xlsx_package.h; sourceTree = ""; }; - 17513C8F2216E784008B45F7 /* pptx_comments.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = pptx_comments.cpp; sourceTree = ""; }; - 17513C902216E784008B45F7 /* xlsx_cell_format.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xlsx_cell_format.h; sourceTree = ""; }; - 17513C912216E784008B45F7 /* oox_chart_context.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = oox_chart_context.h; sourceTree = ""; }; - 17513C922216E784008B45F7 /* hyperlinks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = hyperlinks.h; sourceTree = ""; }; - 17513C932216E784008B45F7 /* xlsx_conditionalFormatting.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = xlsx_conditionalFormatting.cpp; sourceTree = ""; }; - 17513C942216E784008B45F7 /* xlsx_complex_number_format.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xlsx_complex_number_format.h; sourceTree = ""; }; - 17513C952216E784008B45F7 /* docx_content_type.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = docx_content_type.cpp; sourceTree = ""; }; - 17513C962216E784008B45F7 /* xlsx_protection.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = xlsx_protection.cpp; sourceTree = ""; }; - 17513C972216E784008B45F7 /* xlsx_numFmts.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xlsx_numFmts.h; sourceTree = ""; }; - 17513C982216E784008B45F7 /* measuredigits.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = measuredigits.h; sourceTree = ""; }; - 17513C992216E784008B45F7 /* xlsx_styles.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xlsx_styles.h; sourceTree = ""; }; - 17513C9A2216E784008B45F7 /* xlsx_styles.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = xlsx_styles.cpp; sourceTree = ""; }; - 17513C9B2216E784008B45F7 /* oox_drawing_fills.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = oox_drawing_fills.h; sourceTree = ""; }; - 17513C9C2216E784008B45F7 /* xlsx_merge_cells.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = xlsx_merge_cells.cpp; sourceTree = ""; }; - 17513C9D2216E784008B45F7 /* xlsx_borders.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xlsx_borders.h; sourceTree = ""; }; - 17513C9E2216E784008B45F7 /* pptx_text_context.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = pptx_text_context.cpp; sourceTree = ""; }; - 17513C9F2216E784008B45F7 /* xlsxconversioncontext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xlsxconversioncontext.h; sourceTree = ""; }; - 17513CA02216E784008B45F7 /* oox_chart_legend.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = oox_chart_legend.cpp; sourceTree = ""; }; - 17513CA12216E784008B45F7 /* oox_chart_legend.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = oox_chart_legend.h; sourceTree = ""; }; - 17513CA22216E784008B45F7 /* xlsx_hyperlinks.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = xlsx_hyperlinks.cpp; sourceTree = ""; }; - 17513CA32216E784008B45F7 /* headers_footers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = headers_footers.h; sourceTree = ""; }; - 17513CA42216E784008B45F7 /* xlsx_table_position.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xlsx_table_position.h; sourceTree = ""; }; - 17513CA52216E784008B45F7 /* pptx_drawing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pptx_drawing.h; sourceTree = ""; }; - 17513CA62216E784008B45F7 /* xlsx_protection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xlsx_protection.h; sourceTree = ""; }; - 17513CA72216E784008B45F7 /* xlsx_numFmts.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = xlsx_numFmts.cpp; sourceTree = ""; }; - 17513CA82216E784008B45F7 /* oox_chart_axis.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = oox_chart_axis.cpp; sourceTree = ""; }; - 17513CA92216E784008B45F7 /* docx_package.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = docx_package.h; sourceTree = ""; }; - 17513CAA2216E784008B45F7 /* xlsx_alignment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xlsx_alignment.h; sourceTree = ""; }; - 17513CAB2216E784008B45F7 /* pptx_text_context.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pptx_text_context.h; sourceTree = ""; }; - 17513CAC2216E784008B45F7 /* hyperlinks.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = hyperlinks.cpp; sourceTree = ""; }; - 17513CAD2216E784008B45F7 /* oox_plot_area.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = oox_plot_area.h; sourceTree = ""; }; - 17513CAE2216E784008B45F7 /* headers_footers.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = headers_footers.cpp; sourceTree = ""; }; - 17513CAF2216E784008B45F7 /* pptx_output_xml.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pptx_output_xml.h; sourceTree = ""; }; - 17513CB02216E784008B45F7 /* xlsxconversioncontext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = xlsxconversioncontext.cpp; sourceTree = ""; }; - 17513CB12216E784008B45F7 /* xlsx_textcontext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xlsx_textcontext.h; sourceTree = ""; }; - 17513CB22216E784008B45F7 /* xlsx_output_xml.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = xlsx_output_xml.cpp; sourceTree = ""; }; - 17513CB32216E784008B45F7 /* xlsx_table_state.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = xlsx_table_state.cpp; sourceTree = ""; }; - 17513CB42216E784008B45F7 /* oox_drawing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = oox_drawing.h; sourceTree = ""; }; - 17513CB52216E784008B45F7 /* oox_chart_context.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = oox_chart_context.cpp; sourceTree = ""; }; - 17513CB62216E784008B45F7 /* pptx_comments_context.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pptx_comments_context.h; sourceTree = ""; }; - 17513CB72216E784008B45F7 /* xlsx_border.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = xlsx_border.cpp; sourceTree = ""; }; - 17513CB82216E784008B45F7 /* xlsx_table_state.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xlsx_table_state.h; sourceTree = ""; }; - 17513CB92216E784008B45F7 /* ooxtablerowspanned.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ooxtablerowspanned.h; sourceTree = ""; }; - 17513CBA2216E784008B45F7 /* docx_conversion_context.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = docx_conversion_context.h; sourceTree = ""; }; - 17513CBB2216E784008B45F7 /* docx_table_context.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = docx_table_context.h; sourceTree = ""; }; - 17513CBC2216E784008B45F7 /* xlsx_defined_names.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xlsx_defined_names.h; sourceTree = ""; }; - 17513CBD2216E784008B45F7 /* xlsx_data_validation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = xlsx_data_validation.cpp; sourceTree = ""; }; - 17513CBE2216E784008B45F7 /* xlsx_drawing_context.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xlsx_drawing_context.h; sourceTree = ""; }; - 17513CBF2216E784008B45F7 /* xlsx_num_format_context.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = xlsx_num_format_context.cpp; sourceTree = ""; }; - 17513CC02216E784008B45F7 /* xlsx_cell_format.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = xlsx_cell_format.cpp; sourceTree = ""; }; - 17513CC12216E784008B45F7 /* oox_rels.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = oox_rels.cpp; sourceTree = ""; }; - 17513CC22216E784008B45F7 /* oox_data_labels.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = oox_data_labels.h; sourceTree = ""; }; - 17513CC32216E784008B45F7 /* xlsx_borders.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = xlsx_borders.cpp; sourceTree = ""; }; - 17513CC42216E784008B45F7 /* pptx_output_xml.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = pptx_output_xml.cpp; sourceTree = ""; }; - 17513CC52216E784008B45F7 /* xlsx_conditionalFormatting.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xlsx_conditionalFormatting.h; sourceTree = ""; }; - 17513CC62216E784008B45F7 /* xlsx_pivots_context.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xlsx_pivots_context.h; sourceTree = ""; }; - 17513CC72216E784008B45F7 /* oox_plot_area.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = oox_plot_area.cpp; sourceTree = ""; }; - 17513CC82216E784008B45F7 /* pptx_comments.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pptx_comments.h; sourceTree = ""; }; - 17513CC92216E784008B45F7 /* xlsx_dxfs.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = xlsx_dxfs.cpp; sourceTree = ""; }; - 17513CCA2216E784008B45F7 /* pptx_conversion_context.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pptx_conversion_context.h; sourceTree = ""; }; - 17513CCB2216E784008B45F7 /* mediaitems.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mediaitems.h; sourceTree = ""; }; - 17513CCC2216E784008B45F7 /* xlsx_xf.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = xlsx_xf.cpp; sourceTree = ""; }; - 17513CCD2216E784008B45F7 /* xlsx_data_validation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xlsx_data_validation.h; sourceTree = ""; }; - 17513CCE2216E784008B45F7 /* xlsx_font.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xlsx_font.h; sourceTree = ""; }; - 17513CCF2216E784008B45F7 /* measuredigits.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = measuredigits.cpp; sourceTree = ""; }; - 17513CD02216E784008B45F7 /* mediaitems.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = mediaitems.cpp; sourceTree = ""; }; - 17513CD12216E784008B45F7 /* namespaces.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = namespaces.cpp; sourceTree = ""; }; - 17513CD22216E784008B45F7 /* xlsx_dxfs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xlsx_dxfs.h; sourceTree = ""; }; - 17513CD32216E784008B45F7 /* xlsx_hyperlinks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xlsx_hyperlinks.h; sourceTree = ""; }; - 17513CD42216E784008B45F7 /* xlsx_formula.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xlsx_formula.h; sourceTree = ""; }; - 17513CD52216E784008B45F7 /* pptx_comments_context.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = pptx_comments_context.cpp; sourceTree = ""; }; - 17513CD62216E784008B45F7 /* pptx_package.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pptx_package.h; sourceTree = ""; }; - 17513CD72216E784008B45F7 /* oox_layout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = oox_layout.h; sourceTree = ""; }; - 17513CD82216E784008B45F7 /* xlsx_tablecontext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = xlsx_tablecontext.cpp; sourceTree = ""; }; - 17513CD92216E784008B45F7 /* xlsx_utils.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = xlsx_utils.cpp; sourceTree = ""; }; - 17513CDA2216E784008B45F7 /* oox_package.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = oox_package.cpp; sourceTree = ""; }; - 17513CDB2216E784008B45F7 /* oox_chart_series.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = oox_chart_series.h; sourceTree = ""; }; - 17513CDC2216E784008B45F7 /* pptx_slide_context.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = pptx_slide_context.cpp; sourceTree = ""; }; - 17513CDD2216E784008B45F7 /* oox_types_chart.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = oox_types_chart.cpp; sourceTree = ""; }; - 17513CDE2216E784008B45F7 /* oox_title.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = oox_title.cpp; sourceTree = ""; }; - 17513CDF2216E784008B45F7 /* xlsx_row_spanned.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xlsx_row_spanned.h; sourceTree = ""; }; - 17513CE02216E784008B45F7 /* docx_table_context.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = docx_table_context.cpp; sourceTree = ""; }; - 17513CE12216E784008B45F7 /* xlsx_package.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = xlsx_package.cpp; sourceTree = ""; }; - 17513CE22216E784008B45F7 /* xlsx_drawings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xlsx_drawings.h; sourceTree = ""; }; - 17513CE32216E784008B45F7 /* namespaces.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = namespaces.h; sourceTree = ""; }; - 17513CE42216E784008B45F7 /* pptx_conversion_context.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = pptx_conversion_context.cpp; sourceTree = ""; }; - 17513CE52216E784008B45F7 /* xlsx_fills.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xlsx_fills.h; sourceTree = ""; }; - 17513CE62216E784008B45F7 /* pptx_table_context.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pptx_table_context.h; sourceTree = ""; }; - 17513CE72216E784008B45F7 /* xlsx_output_xml.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xlsx_output_xml.h; sourceTree = ""; }; - 17513CE82216E784008B45F7 /* pptx_drawing.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = pptx_drawing.cpp; sourceTree = ""; }; - 17513CE92216E784008B45F7 /* xlsx_border.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xlsx_border.h; sourceTree = ""; }; - 17513CEA2216E784008B45F7 /* xlsx_drawing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xlsx_drawing.h; sourceTree = ""; }; - 17513CEB2216E784008B45F7 /* xlsx_table_metrics.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = xlsx_table_metrics.cpp; sourceTree = ""; }; - 17513CEC2216E784008B45F7 /* oox_chart_shape.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = oox_chart_shape.h; sourceTree = ""; }; - 17513CED2216E784008B45F7 /* xlsx_merge_cells.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xlsx_merge_cells.h; sourceTree = ""; }; - 17513CEE2216E784008B45F7 /* xlsx_fill.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xlsx_fill.h; sourceTree = ""; }; - 17513CEF2216E784008B45F7 /* oox_data_labels.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = oox_data_labels.cpp; sourceTree = ""; }; - 17513CF02216E784008B45F7 /* docx_drawing.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = docx_drawing.cpp; sourceTree = ""; }; - 17513CF12216E784008B45F7 /* xlsx_cell_styles.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xlsx_cell_styles.h; sourceTree = ""; }; - 17513CF22216E784008B45F7 /* xlsx_fills.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = xlsx_fills.cpp; sourceTree = ""; }; - 17513CF32216E784008B45F7 /* xlsx_color.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xlsx_color.h; sourceTree = ""; }; - 17513CF42216E784008B45F7 /* oox_layout.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = oox_layout.cpp; sourceTree = ""; }; - 17513CF52216E784008B45F7 /* oox_title.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = oox_title.h; sourceTree = ""; }; - 17513CF62216E784008B45F7 /* xlsx_xf.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xlsx_xf.h; sourceTree = ""; }; - 17513CF72216E784008B45F7 /* xlsx_tablecontext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xlsx_tablecontext.h; sourceTree = ""; }; - 17513CF82216E784008B45F7 /* docx_conversion_context.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = docx_conversion_context.cpp; sourceTree = ""; }; - 17513CF92216E784008B45F7 /* pptx_package.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = pptx_package.cpp; sourceTree = ""; }; - 17513CFA2216E784008B45F7 /* xlsx_sharedstrings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xlsx_sharedstrings.h; sourceTree = ""; }; - 17513CFB2216E784008B45F7 /* oox_types_chart.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = oox_types_chart.h; sourceTree = ""; }; - 17513CFC2216E784008B45F7 /* drawing_object_description.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = drawing_object_description.h; sourceTree = ""; }; - 17513CFD2216E784008B45F7 /* xlsx_comments_context.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = xlsx_comments_context.cpp; sourceTree = ""; }; - 17513CFE2216E784008B45F7 /* pptx_table_context.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = pptx_table_context.cpp; sourceTree = ""; }; - 17513CFF2216E784008B45F7 /* xlsx_fonts.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = xlsx_fonts.cpp; sourceTree = ""; }; - 17513D002216E784008B45F7 /* xlsx_table_metrics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xlsx_table_metrics.h; sourceTree = ""; }; - 17513D012216E784008B45F7 /* xlsx_utils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xlsx_utils.h; sourceTree = ""; }; - 17513D022216E784008B45F7 /* xlsx_drawing_context.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = xlsx_drawing_context.cpp; sourceTree = ""; }; - 17513D032216E784008B45F7 /* docx_package.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = docx_package.cpp; sourceTree = ""; }; - 17513D042216E784008B45F7 /* oox_drawing_fills.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = oox_drawing_fills.cpp; sourceTree = ""; }; - 17513D052216E784008B45F7 /* xlsx_textcontext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = xlsx_textcontext.cpp; sourceTree = ""; }; - 17513D062216E784008B45F7 /* xlsx_fonts.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xlsx_fonts.h; sourceTree = ""; }; - 17513D072216E784008B45F7 /* oox_conversion_context.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = oox_conversion_context.h; sourceTree = ""; }; - 17513D082216E784008B45F7 /* oox_drawing.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = oox_drawing.cpp; sourceTree = ""; }; - 17513D092216E784008B45F7 /* xlsx_sharedstrings.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = xlsx_sharedstrings.cpp; sourceTree = ""; }; - 17513D0A2216E784008B45F7 /* xlsx_comments.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xlsx_comments.h; sourceTree = ""; }; - 17513D0B2216E784008B45F7 /* xlsx_comments_context.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xlsx_comments_context.h; sourceTree = ""; }; - 17513D0C2216E784008B45F7 /* pptx_default_serializes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pptx_default_serializes.h; sourceTree = ""; }; - 17513D0D2216E784008B45F7 /* xlsx_cell_styles.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = xlsx_cell_styles.cpp; sourceTree = ""; }; - 17513D0E2216E784008B45F7 /* xlsx_drawings.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = xlsx_drawings.cpp; sourceTree = ""; }; - 17513D0F2216E784008B45F7 /* oox_package.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = oox_package.h; sourceTree = ""; }; - 17513D102216E784008B45F7 /* oox_chart_shape.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = oox_chart_shape.cpp; sourceTree = ""; }; - 17513D112216E784008B45F7 /* xlsx_color.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = xlsx_color.cpp; sourceTree = ""; }; - 17513D122216E784008B45F7 /* oox_chart_values.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = oox_chart_values.h; sourceTree = ""; }; - 17513D132216E784008B45F7 /* xlsx_pivots_context.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = xlsx_pivots_context.cpp; sourceTree = ""; }; - 17513D142216E784008B45F7 /* docx_content_type.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = docx_content_type.h; sourceTree = ""; }; - 17513D152216E784008B45F7 /* oox_chart_axis.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = oox_chart_axis.h; sourceTree = ""; }; - 17513D162216E784008B45F7 /* xlsx_complex_number_format.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = xlsx_complex_number_format.cpp; sourceTree = ""; }; - 17513D172216E784008B45F7 /* xlsx_cell_style.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = xlsx_cell_style.cpp; sourceTree = ""; }; - 17513D182216E784008B45F7 /* oox_conversion_context.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = oox_conversion_context.cpp; sourceTree = ""; }; - 17513D192216E785008B45F7 /* xlsx_drawing.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = xlsx_drawing.cpp; sourceTree = ""; }; - 17513D1A2216E785008B45F7 /* xlsx_comments.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = xlsx_comments.cpp; sourceTree = ""; }; - 17513D1B2216E785008B45F7 /* xlsx_num_format_context.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xlsx_num_format_context.h; sourceTree = ""; }; - 17513D1C2216E785008B45F7 /* xlsx_defined_names.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = xlsx_defined_names.cpp; sourceTree = ""; }; - 17513D1D2216E785008B45F7 /* docx_drawing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = docx_drawing.h; sourceTree = ""; }; - 17513E252216E8D0008B45F7 /* cextracttools.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = cextracttools.cpp; path = ../../../../src/cextracttools.cpp; sourceTree = ""; }; - 17513E262216E8D1008B45F7 /* cextracttools.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = cextracttools.h; path = ../../../../src/cextracttools.h; sourceTree = ""; }; - 8A5834E6221D90BE0029F06B /* formulasconvert_odf.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = formulasconvert_odf.cpp; sourceTree = ""; }; - 8A5834E7221D90BE0029F06B /* formulasconvert.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = formulasconvert.h; sourceTree = ""; }; - 8A5834E8221D90BE0029F06B /* formulasconvert_oox.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = formulasconvert_oox.cpp; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 17513B012216E721008B45F7 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 17513AFB2216E721008B45F7 = { - isa = PBXGroup; - children = ( - 17513B062216E721008B45F7 /* OdfOfficeConverter */, - 17513B052216E721008B45F7 /* Products */, - ); - sourceTree = ""; - }; - 17513B052216E721008B45F7 /* Products */ = { - isa = PBXGroup; - children = ( - 17513B042216E721008B45F7 /* libOdfOfficeConverter.a */, - ); - name = Products; - sourceTree = ""; - }; - 17513B062216E721008B45F7 /* OdfOfficeConverter */ = { - isa = PBXGroup; - children = ( - 17513B112216E743008B45F7 /* ASCOfficeOdfFile */, - 17513E242216E8C9008B45F7 /* src */, - 17513B072216E721008B45F7 /* OdfOfficeConverter.h */, - 17513B082216E721008B45F7 /* OdfOfficeConverter.mm */, - ); - path = OdfOfficeConverter; - sourceTree = ""; - }; - 17513B112216E743008B45F7 /* ASCOfficeOdfFile */ = { - isa = PBXGroup; - children = ( - 8A5834E5221D90BE0029F06B /* formulasconvert */, - 17513B122216E783008B45F7 /* src */, - ); - name = ASCOfficeOdfFile; - sourceTree = ""; - }; - 17513B122216E783008B45F7 /* src */ = { - isa = PBXGroup; - children = ( - 17513B132216E783008B45F7 /* conversionelement.h */, - 17513C752216E784008B45F7 /* ConvertOO2OOX.h */, - 17513C762216E784008B45F7 /* xml */, - 17513C7D2216E784008B45F7 /* common */, - 17513C812216E784008B45F7 /* progressCallback.h */, - 17513C822216E784008B45F7 /* ConvertOO2OOX.cpp */, - 17513C832216E784008B45F7 /* conversionelement.cpp */, - 17513C842216E784008B45F7 /* docx */, - ); - name = src; - path = ../../../../../ASCOfficeOdfFile/src; - sourceTree = ""; - }; - 17513C762216E784008B45F7 /* xml */ = { - isa = PBXGroup; - children = ( - 17513C772216E784008B45F7 /* sax_xmllite.cpp */, - 17513C782216E784008B45F7 /* utils.cpp */, - 17513C792216E784008B45F7 /* sax_xmllite.h */, - 17513C7A2216E784008B45F7 /* sax.cpp */, - 17513C7B2216E784008B45F7 /* xmlchar.cpp */, - 17513C7C2216E784008B45F7 /* attributes.cpp */, - ); - path = xml; - sourceTree = ""; - }; - 17513C7D2216E784008B45F7 /* common */ = { - isa = PBXGroup; - children = ( - 17513C7E2216E784008B45F7 /* CPString.cpp */, - 17513C7F2216E784008B45F7 /* CPColorUtils.cpp */, - 17513C802216E784008B45F7 /* readdocelement.cpp */, - ); - path = common; - sourceTree = ""; - }; - 17513C842216E784008B45F7 /* docx */ = { - isa = PBXGroup; - children = ( - 17513C852216E784008B45F7 /* xlsx_font.cpp */, - 17513C862216E784008B45F7 /* pptx_drawings.cpp */, - 17513C872216E784008B45F7 /* xlsx_cell_style.h */, - 17513C882216E784008B45F7 /* xlsx_alignment.cpp */, - 17513C892216E784008B45F7 /* xlsx_fill.cpp */, - 17513C8A2216E784008B45F7 /* oox_chart_series.cpp */, - 17513C8B2216E784008B45F7 /* pptx_drawings.h */, - 17513C8C2216E784008B45F7 /* oox_rels.h */, - 17513C8D2216E784008B45F7 /* pptx_slide_context.h */, - 17513C8E2216E784008B45F7 /* xlsx_package.h */, - 17513C8F2216E784008B45F7 /* pptx_comments.cpp */, - 17513C902216E784008B45F7 /* xlsx_cell_format.h */, - 17513C912216E784008B45F7 /* oox_chart_context.h */, - 17513C922216E784008B45F7 /* hyperlinks.h */, - 17513C932216E784008B45F7 /* xlsx_conditionalFormatting.cpp */, - 17513C942216E784008B45F7 /* xlsx_complex_number_format.h */, - 17513C952216E784008B45F7 /* docx_content_type.cpp */, - 17513C962216E784008B45F7 /* xlsx_protection.cpp */, - 17513C972216E784008B45F7 /* xlsx_numFmts.h */, - 17513C982216E784008B45F7 /* measuredigits.h */, - 17513C992216E784008B45F7 /* xlsx_styles.h */, - 17513C9A2216E784008B45F7 /* xlsx_styles.cpp */, - 17513C9B2216E784008B45F7 /* oox_drawing_fills.h */, - 17513C9C2216E784008B45F7 /* xlsx_merge_cells.cpp */, - 17513C9D2216E784008B45F7 /* xlsx_borders.h */, - 17513C9E2216E784008B45F7 /* pptx_text_context.cpp */, - 17513C9F2216E784008B45F7 /* xlsxconversioncontext.h */, - 17513CA02216E784008B45F7 /* oox_chart_legend.cpp */, - 17513CA12216E784008B45F7 /* oox_chart_legend.h */, - 17513CA22216E784008B45F7 /* xlsx_hyperlinks.cpp */, - 17513CA32216E784008B45F7 /* headers_footers.h */, - 17513CA42216E784008B45F7 /* xlsx_table_position.h */, - 17513CA52216E784008B45F7 /* pptx_drawing.h */, - 17513CA62216E784008B45F7 /* xlsx_protection.h */, - 17513CA72216E784008B45F7 /* xlsx_numFmts.cpp */, - 17513CA82216E784008B45F7 /* oox_chart_axis.cpp */, - 17513CA92216E784008B45F7 /* docx_package.h */, - 17513CAA2216E784008B45F7 /* xlsx_alignment.h */, - 17513CAB2216E784008B45F7 /* pptx_text_context.h */, - 17513CAC2216E784008B45F7 /* hyperlinks.cpp */, - 17513CAD2216E784008B45F7 /* oox_plot_area.h */, - 17513CAE2216E784008B45F7 /* headers_footers.cpp */, - 17513CAF2216E784008B45F7 /* pptx_output_xml.h */, - 17513CB02216E784008B45F7 /* xlsxconversioncontext.cpp */, - 17513CB12216E784008B45F7 /* xlsx_textcontext.h */, - 17513CB22216E784008B45F7 /* xlsx_output_xml.cpp */, - 17513CB32216E784008B45F7 /* xlsx_table_state.cpp */, - 17513CB42216E784008B45F7 /* oox_drawing.h */, - 17513CB52216E784008B45F7 /* oox_chart_context.cpp */, - 17513CB62216E784008B45F7 /* pptx_comments_context.h */, - 17513CB72216E784008B45F7 /* xlsx_border.cpp */, - 17513CB82216E784008B45F7 /* xlsx_table_state.h */, - 17513CB92216E784008B45F7 /* ooxtablerowspanned.h */, - 17513CBA2216E784008B45F7 /* docx_conversion_context.h */, - 17513CBB2216E784008B45F7 /* docx_table_context.h */, - 17513CBC2216E784008B45F7 /* xlsx_defined_names.h */, - 17513CBD2216E784008B45F7 /* xlsx_data_validation.cpp */, - 17513CBE2216E784008B45F7 /* xlsx_drawing_context.h */, - 17513CBF2216E784008B45F7 /* xlsx_num_format_context.cpp */, - 17513CC02216E784008B45F7 /* xlsx_cell_format.cpp */, - 17513CC12216E784008B45F7 /* oox_rels.cpp */, - 17513CC22216E784008B45F7 /* oox_data_labels.h */, - 17513CC32216E784008B45F7 /* xlsx_borders.cpp */, - 17513CC42216E784008B45F7 /* pptx_output_xml.cpp */, - 17513CC52216E784008B45F7 /* xlsx_conditionalFormatting.h */, - 17513CC62216E784008B45F7 /* xlsx_pivots_context.h */, - 17513CC72216E784008B45F7 /* oox_plot_area.cpp */, - 17513CC82216E784008B45F7 /* pptx_comments.h */, - 17513CC92216E784008B45F7 /* xlsx_dxfs.cpp */, - 17513CCA2216E784008B45F7 /* pptx_conversion_context.h */, - 17513CCB2216E784008B45F7 /* mediaitems.h */, - 17513CCC2216E784008B45F7 /* xlsx_xf.cpp */, - 17513CCD2216E784008B45F7 /* xlsx_data_validation.h */, - 17513CCE2216E784008B45F7 /* xlsx_font.h */, - 17513CCF2216E784008B45F7 /* measuredigits.cpp */, - 17513CD02216E784008B45F7 /* mediaitems.cpp */, - 17513CD12216E784008B45F7 /* namespaces.cpp */, - 17513CD22216E784008B45F7 /* xlsx_dxfs.h */, - 17513CD32216E784008B45F7 /* xlsx_hyperlinks.h */, - 17513CD42216E784008B45F7 /* xlsx_formula.h */, - 17513CD52216E784008B45F7 /* pptx_comments_context.cpp */, - 17513CD62216E784008B45F7 /* pptx_package.h */, - 17513CD72216E784008B45F7 /* oox_layout.h */, - 17513CD82216E784008B45F7 /* xlsx_tablecontext.cpp */, - 17513CD92216E784008B45F7 /* xlsx_utils.cpp */, - 17513CDA2216E784008B45F7 /* oox_package.cpp */, - 17513CDB2216E784008B45F7 /* oox_chart_series.h */, - 17513CDC2216E784008B45F7 /* pptx_slide_context.cpp */, - 17513CDD2216E784008B45F7 /* oox_types_chart.cpp */, - 17513CDE2216E784008B45F7 /* oox_title.cpp */, - 17513CDF2216E784008B45F7 /* xlsx_row_spanned.h */, - 17513CE02216E784008B45F7 /* docx_table_context.cpp */, - 17513CE12216E784008B45F7 /* xlsx_package.cpp */, - 17513CE22216E784008B45F7 /* xlsx_drawings.h */, - 17513CE32216E784008B45F7 /* namespaces.h */, - 17513CE42216E784008B45F7 /* pptx_conversion_context.cpp */, - 17513CE52216E784008B45F7 /* xlsx_fills.h */, - 17513CE62216E784008B45F7 /* pptx_table_context.h */, - 17513CE72216E784008B45F7 /* xlsx_output_xml.h */, - 17513CE82216E784008B45F7 /* pptx_drawing.cpp */, - 17513CE92216E784008B45F7 /* xlsx_border.h */, - 17513CEA2216E784008B45F7 /* xlsx_drawing.h */, - 17513CEB2216E784008B45F7 /* xlsx_table_metrics.cpp */, - 17513CEC2216E784008B45F7 /* oox_chart_shape.h */, - 17513CED2216E784008B45F7 /* xlsx_merge_cells.h */, - 17513CEE2216E784008B45F7 /* xlsx_fill.h */, - 17513CEF2216E784008B45F7 /* oox_data_labels.cpp */, - 17513CF02216E784008B45F7 /* docx_drawing.cpp */, - 17513CF12216E784008B45F7 /* xlsx_cell_styles.h */, - 17513CF22216E784008B45F7 /* xlsx_fills.cpp */, - 17513CF32216E784008B45F7 /* xlsx_color.h */, - 17513CF42216E784008B45F7 /* oox_layout.cpp */, - 17513CF52216E784008B45F7 /* oox_title.h */, - 17513CF62216E784008B45F7 /* xlsx_xf.h */, - 17513CF72216E784008B45F7 /* xlsx_tablecontext.h */, - 17513CF82216E784008B45F7 /* docx_conversion_context.cpp */, - 17513CF92216E784008B45F7 /* pptx_package.cpp */, - 17513CFA2216E784008B45F7 /* xlsx_sharedstrings.h */, - 17513CFB2216E784008B45F7 /* oox_types_chart.h */, - 17513CFC2216E784008B45F7 /* drawing_object_description.h */, - 17513CFD2216E784008B45F7 /* xlsx_comments_context.cpp */, - 17513CFE2216E784008B45F7 /* pptx_table_context.cpp */, - 17513CFF2216E784008B45F7 /* xlsx_fonts.cpp */, - 17513D002216E784008B45F7 /* xlsx_table_metrics.h */, - 17513D012216E784008B45F7 /* xlsx_utils.h */, - 17513D022216E784008B45F7 /* xlsx_drawing_context.cpp */, - 17513D032216E784008B45F7 /* docx_package.cpp */, - 17513D042216E784008B45F7 /* oox_drawing_fills.cpp */, - 17513D052216E784008B45F7 /* xlsx_textcontext.cpp */, - 17513D062216E784008B45F7 /* xlsx_fonts.h */, - 17513D072216E784008B45F7 /* oox_conversion_context.h */, - 17513D082216E784008B45F7 /* oox_drawing.cpp */, - 17513D092216E784008B45F7 /* xlsx_sharedstrings.cpp */, - 17513D0A2216E784008B45F7 /* xlsx_comments.h */, - 17513D0B2216E784008B45F7 /* xlsx_comments_context.h */, - 17513D0C2216E784008B45F7 /* pptx_default_serializes.h */, - 17513D0D2216E784008B45F7 /* xlsx_cell_styles.cpp */, - 17513D0E2216E784008B45F7 /* xlsx_drawings.cpp */, - 17513D0F2216E784008B45F7 /* oox_package.h */, - 17513D102216E784008B45F7 /* oox_chart_shape.cpp */, - 17513D112216E784008B45F7 /* xlsx_color.cpp */, - 17513D122216E784008B45F7 /* oox_chart_values.h */, - 17513D132216E784008B45F7 /* xlsx_pivots_context.cpp */, - 17513D142216E784008B45F7 /* docx_content_type.h */, - 17513D152216E784008B45F7 /* oox_chart_axis.h */, - 17513D162216E784008B45F7 /* xlsx_complex_number_format.cpp */, - 17513D172216E784008B45F7 /* xlsx_cell_style.cpp */, - 17513D182216E784008B45F7 /* oox_conversion_context.cpp */, - 17513D192216E785008B45F7 /* xlsx_drawing.cpp */, - 17513D1A2216E785008B45F7 /* xlsx_comments.cpp */, - 17513D1B2216E785008B45F7 /* xlsx_num_format_context.h */, - 17513D1C2216E785008B45F7 /* xlsx_defined_names.cpp */, - 17513D1D2216E785008B45F7 /* docx_drawing.h */, - ); - path = docx; - sourceTree = ""; - }; - 17513E242216E8C9008B45F7 /* src */ = { - isa = PBXGroup; - children = ( - 17513E262216E8D1008B45F7 /* cextracttools.h */, - 17513E252216E8D0008B45F7 /* cextracttools.cpp */, - ); - name = src; - sourceTree = ""; - }; - 8A5834E5221D90BE0029F06B /* formulasconvert */ = { - isa = PBXGroup; - children = ( - 8A5834E6221D90BE0029F06B /* formulasconvert_odf.cpp */, - 8A5834E7221D90BE0029F06B /* formulasconvert.h */, - 8A5834E8221D90BE0029F06B /* formulasconvert_oox.cpp */, - ); - name = formulasconvert; - path = ../../../../../ASCOfficeOdfFile/formulasconvert; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXHeadersBuildPhase section */ - 8A8753C42227F44A00117573 /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - 17513B0A2216E721008B45F7 /* OdfOfficeConverter.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXHeadersBuildPhase section */ - -/* Begin PBXNativeTarget section */ - 17513B032216E721008B45F7 /* OdfOfficeConverter */ = { - isa = PBXNativeTarget; - buildConfigurationList = 17513B0D2216E721008B45F7 /* Build configuration list for PBXNativeTarget "OdfOfficeConverter" */; - buildPhases = ( - 8A8753C42227F44A00117573 /* Headers */, - 17513B002216E721008B45F7 /* Sources */, - 17513B012216E721008B45F7 /* Frameworks */, - 17513B022216E721008B45F7 /* CopyFiles */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = OdfOfficeConverter; - productName = OfficeOdfConverter; - productReference = 17513B042216E721008B45F7 /* libOdfOfficeConverter.a */; - productType = "com.apple.product-type.library.static"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 17513AFC2216E721008B45F7 /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 1010; - ORGANIZATIONNAME = "Ascensio System SIA"; - TargetAttributes = { - 17513B032216E721008B45F7 = { - CreatedOnToolsVersion = 10.1; - }; - }; - }; - buildConfigurationList = 17513AFF2216E721008B45F7 /* Build configuration list for PBXProject "OdfOfficeConverter" */; - compatibilityVersion = "Xcode 9.3"; - developmentRegion = en; - hasScannedForEncodings = 0; - knownRegions = ( - en, - ); - mainGroup = 17513AFB2216E721008B45F7; - productRefGroup = 17513B052216E721008B45F7 /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 17513B032216E721008B45F7 /* OdfOfficeConverter */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXSourcesBuildPhase section */ - 17513B002216E721008B45F7 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 17513E122216E785008B45F7 /* xlsx_fonts.cpp in Sources */, - 17513DE42216E785008B45F7 /* xlsx_styles.cpp in Sources */, - 17513E162216E785008B45F7 /* xlsx_textcontext.cpp in Sources */, - 17513DE92216E785008B45F7 /* xlsx_numFmts.cpp in Sources */, - 17513E002216E785008B45F7 /* xlsx_utils.cpp in Sources */, - 17513DDA2216E785008B45F7 /* conversionelement.cpp in Sources */, - 17513DFE2216E785008B45F7 /* pptx_comments_context.cpp in Sources */, - 17513DF12216E785008B45F7 /* xlsx_border.cpp in Sources */, - 17513DDC2216E785008B45F7 /* pptx_drawings.cpp in Sources */, - 17513DED2216E785008B45F7 /* xlsxconversioncontext.cpp in Sources */, - 17513DD82216E785008B45F7 /* readdocelement.cpp in Sources */, - 17513DD32216E785008B45F7 /* sax.cpp in Sources */, - 17513E0A2216E785008B45F7 /* oox_data_labels.cpp in Sources */, - 17513E032216E785008B45F7 /* oox_types_chart.cpp in Sources */, - 17513DD12216E785008B45F7 /* sax_xmllite.cpp in Sources */, - 17513E152216E785008B45F7 /* oox_drawing_fills.cpp in Sources */, - 17513E042216E785008B45F7 /* oox_title.cpp in Sources */, - 17513E182216E785008B45F7 /* xlsx_sharedstrings.cpp in Sources */, - 17513E1A2216E786008B45F7 /* xlsx_drawings.cpp in Sources */, - 17513DFD2216E785008B45F7 /* namespaces.cpp in Sources */, - 17513DF32216E785008B45F7 /* xlsx_num_format_context.cpp in Sources */, - 17513DF92216E785008B45F7 /* xlsx_dxfs.cpp in Sources */, - 17513E192216E786008B45F7 /* xlsx_cell_styles.cpp in Sources */, - 8A5834EA221D90BE0029F06B /* formulasconvert_oox.cpp in Sources */, - 17513E232216E786008B45F7 /* xlsx_defined_names.cpp in Sources */, - 17513E1B2216E786008B45F7 /* oox_chart_shape.cpp in Sources */, - 17513E092216E785008B45F7 /* xlsx_table_metrics.cpp in Sources */, - 17513E112216E785008B45F7 /* pptx_table_context.cpp in Sources */, - 17513DE22216E785008B45F7 /* docx_content_type.cpp in Sources */, - 17513DDE2216E785008B45F7 /* xlsx_fill.cpp in Sources */, - 17513E222216E786008B45F7 /* xlsx_comments.cpp in Sources */, - 17513E0C2216E785008B45F7 /* xlsx_fills.cpp in Sources */, - 17513DFC2216E785008B45F7 /* mediaitems.cpp in Sources */, - 17513DFB2216E785008B45F7 /* measuredigits.cpp in Sources */, - 17513DD92216E785008B45F7 /* ConvertOO2OOX.cpp in Sources */, - 17513DD72216E785008B45F7 /* CPColorUtils.cpp in Sources */, - 17513DDD2216E785008B45F7 /* xlsx_alignment.cpp in Sources */, - 17513DEE2216E785008B45F7 /* xlsx_output_xml.cpp in Sources */, - 17513E272216E8D1008B45F7 /* cextracttools.cpp in Sources */, - 17513DEC2216E785008B45F7 /* headers_footers.cpp in Sources */, - 17513E0E2216E785008B45F7 /* docx_conversion_context.cpp in Sources */, - 17513DF72216E785008B45F7 /* pptx_output_xml.cpp in Sources */, - 17513E142216E785008B45F7 /* docx_package.cpp in Sources */, - 17513DD22216E785008B45F7 /* utils.cpp in Sources */, - 17513DEF2216E785008B45F7 /* xlsx_table_state.cpp in Sources */, - 17513DD42216E785008B45F7 /* xmlchar.cpp in Sources */, - 17513E012216E785008B45F7 /* oox_package.cpp in Sources */, - 17513DDB2216E785008B45F7 /* xlsx_font.cpp in Sources */, - 17513DEB2216E785008B45F7 /* hyperlinks.cpp in Sources */, - 17513E172216E785008B45F7 /* oox_drawing.cpp in Sources */, - 17513E212216E786008B45F7 /* xlsx_drawing.cpp in Sources */, - 17513E1D2216E786008B45F7 /* xlsx_pivots_context.cpp in Sources */, - 17513E022216E785008B45F7 /* pptx_slide_context.cpp in Sources */, - 17513E072216E785008B45F7 /* pptx_conversion_context.cpp in Sources */, - 17513E0D2216E785008B45F7 /* oox_layout.cpp in Sources */, - 17513DE02216E785008B45F7 /* pptx_comments.cpp in Sources */, - 17513E052216E785008B45F7 /* docx_table_context.cpp in Sources */, - 17513DD62216E785008B45F7 /* CPString.cpp in Sources */, - 17513DF82216E785008B45F7 /* oox_plot_area.cpp in Sources */, - 17513DF52216E785008B45F7 /* oox_rels.cpp in Sources */, - 17513E0B2216E785008B45F7 /* docx_drawing.cpp in Sources */, - 17513DDF2216E785008B45F7 /* oox_chart_series.cpp in Sources */, - 17513B092216E721008B45F7 /* OdfOfficeConverter.mm in Sources */, - 17513DFF2216E785008B45F7 /* xlsx_tablecontext.cpp in Sources */, - 17513E1F2216E786008B45F7 /* xlsx_cell_style.cpp in Sources */, - 17513DE62216E785008B45F7 /* pptx_text_context.cpp in Sources */, - 17513E102216E785008B45F7 /* xlsx_comments_context.cpp in Sources */, - 17513E202216E786008B45F7 /* oox_conversion_context.cpp in Sources */, - 17513E1E2216E786008B45F7 /* xlsx_complex_number_format.cpp in Sources */, - 17513DF02216E785008B45F7 /* oox_chart_context.cpp in Sources */, - 17513E062216E785008B45F7 /* xlsx_package.cpp in Sources */, - 17513DFA2216E785008B45F7 /* xlsx_xf.cpp in Sources */, - 17513DE32216E785008B45F7 /* xlsx_protection.cpp in Sources */, - 17513DF62216E785008B45F7 /* xlsx_borders.cpp in Sources */, - 17513E1C2216E786008B45F7 /* xlsx_color.cpp in Sources */, - 17513E132216E785008B45F7 /* xlsx_drawing_context.cpp in Sources */, - 17513DD52216E785008B45F7 /* attributes.cpp in Sources */, - 17513DF22216E785008B45F7 /* xlsx_data_validation.cpp in Sources */, - 17513DE52216E785008B45F7 /* xlsx_merge_cells.cpp in Sources */, - 17513DE82216E785008B45F7 /* xlsx_hyperlinks.cpp in Sources */, - 17513DE72216E785008B45F7 /* oox_chart_legend.cpp in Sources */, - 17513DF42216E785008B45F7 /* xlsx_cell_format.cpp in Sources */, - 17513DE12216E785008B45F7 /* xlsx_conditionalFormatting.cpp in Sources */, - 17513DEA2216E785008B45F7 /* oox_chart_axis.cpp in Sources */, - 17513E0F2216E785008B45F7 /* pptx_package.cpp in Sources */, - 17513E082216E785008B45F7 /* pptx_drawing.cpp in Sources */, - 8A5834E9221D90BE0029F06B /* formulasconvert_odf.cpp in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin XCBuildConfiguration section */ - 17513B0B2216E721008B45F7 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - CODE_SIGN_IDENTITY = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu11; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 10.0; - MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; - MTL_FAST_MATH = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - }; - name = Debug; - }; - 17513B0C2216E721008B45F7 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - CODE_SIGN_IDENTITY = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu11; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 10.0; - MTL_ENABLE_DEBUG_INFO = NO; - MTL_FAST_MATH = YES; - SDKROOT = iphoneos; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - 17513B0E2216E721008B45F7 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = 2WH24U26GJ; - GCC_PREPROCESSOR_DEFINITIONS = ( - UNICODE, - _UNICODE, - PPTX_DEF, - PPT_DEF, - ENABLE_PPT_TO_PPTX_CONVERT, - NODOCX, - FILTER_FLATE_DECODE_ENABLED, - CXIMAGE_DONT_DECLARE_TCHAR, - BUILD_CONFIG_FULL_VERSION, - DONT_WRITE_EMBEDDED_FONTS, - AVS_USE_CONVERT_PPTX_TOCUSTOM_VML, - unix, - MAC, - _IOS, - ); - HEADER_SEARCH_PATHS = ( - "$(inherited)", - /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, - /usr/include/libxml2, - "$(PROJECT_DIR)/../../../../DesktopEditor/freetype-2.5.2/include", - "$(PROJECT_DIR)/../../../../DesktopEditor/agg-2.4/include", - "$(PROJECT_DIR)/../../../../Common/3dParty/boost/boost_1_58_0", - "$(PROJECT_DIR)/../../../../ASCOfficeOdfFile/include", - "$(PROJECT_DIR)/../../../../ASCOfficeOdfFile/src/odf/datatypes", - ); - OTHER_CFLAGS = "-fembed-bitcode-marker"; - OTHER_LDFLAGS = "-ObjC"; - PRODUCT_NAME = "$(TARGET_NAME)"; - SKIP_INSTALL = YES; - TARGETED_DEVICE_FAMILY = 1; - VALID_ARCHS = "arm64 armv7 armv7s i386 x86_64"; - }; - name = Debug; - }; - 17513B0F2216E721008B45F7 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = 2WH24U26GJ; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - UNICODE, - _UNICODE, - PPTX_DEF, - PPT_DEF, - ENABLE_PPT_TO_PPTX_CONVERT, - NODOCX, - FILTER_FLATE_DECODE_ENABLED, - CXIMAGE_DONT_DECLARE_TCHAR, - BUILD_CONFIG_FULL_VERSION, - DONT_WRITE_EMBEDDED_FONTS, - AVS_USE_CONVERT_PPTX_TOCUSTOM_VML, - unix, - MAC, - _IOS, - ); - HEADER_SEARCH_PATHS = ( - "$(inherited)", - /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, - /usr/include/libxml2, - "$(PROJECT_DIR)/../../../../DesktopEditor/freetype-2.5.2/include", - "$(PROJECT_DIR)/../../../../DesktopEditor/agg-2.4/include", - "$(PROJECT_DIR)/../../../../Common/3dParty/boost/boost_1_58_0", - "$(PROJECT_DIR)/../../../../ASCOfficeOdfFile/include", - "$(PROJECT_DIR)/../../../../ASCOfficeOdfFile/src/odf/datatypes", - ); - OTHER_CFLAGS = "-fembed-bitcode"; - OTHER_LDFLAGS = "-ObjC"; - PRODUCT_NAME = "$(TARGET_NAME)"; - SKIP_INSTALL = YES; - TARGETED_DEVICE_FAMILY = 1; - VALID_ARCHS = "arm64 armv7 armv7s i386 x86_64"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 17513AFF2216E721008B45F7 /* Build configuration list for PBXProject "OdfOfficeConverter" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 17513B0B2216E721008B45F7 /* Debug */, - 17513B0C2216E721008B45F7 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 17513B0D2216E721008B45F7 /* Build configuration list for PBXNativeTarget "OdfOfficeConverter" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 17513B0E2216E721008B45F7 /* Debug */, - 17513B0F2216E721008B45F7 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 17513AFC2216E721008B45F7 /* Project object */; -} diff --git a/X2tConverter/build/Mac/OdfOfficeConverter/OdfOfficeConverter.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/X2tConverter/build/Mac/OdfOfficeConverter/OdfOfficeConverter.xcodeproj/project.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index c36bc97f98b..00000000000 --- a/X2tConverter/build/Mac/OdfOfficeConverter/OdfOfficeConverter.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/X2tConverter/build/Mac/OdfOfficeConverter/OdfOfficeConverter.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/X2tConverter/build/Mac/OdfOfficeConverter/OdfOfficeConverter.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist deleted file mode 100644 index 18d981003d6..00000000000 --- a/X2tConverter/build/Mac/OdfOfficeConverter/OdfOfficeConverter.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +++ /dev/null @@ -1,8 +0,0 @@ - - - - - IDEDidComputeMac32BitWarning - - - diff --git a/X2tConverter/build/Mac/OdfOfficeConverter/OdfOfficeConverter.xcodeproj/project.xcworkspace/xcuserdata/alexey.musinov.xcuserdatad/UserInterfaceState.xcuserstate b/X2tConverter/build/Mac/OdfOfficeConverter/OdfOfficeConverter.xcodeproj/project.xcworkspace/xcuserdata/alexey.musinov.xcuserdatad/UserInterfaceState.xcuserstate deleted file mode 100644 index f2c10a3b90f..00000000000 Binary files a/X2tConverter/build/Mac/OdfOfficeConverter/OdfOfficeConverter.xcodeproj/project.xcworkspace/xcuserdata/alexey.musinov.xcuserdatad/UserInterfaceState.xcuserstate and /dev/null differ diff --git a/X2tConverter/build/Mac/OdfOfficeConverter/OdfOfficeConverter.xcodeproj/project.xcworkspace/xcuserdata/alexey.xcuserdatad/UserInterfaceState.xcuserstate b/X2tConverter/build/Mac/OdfOfficeConverter/OdfOfficeConverter.xcodeproj/project.xcworkspace/xcuserdata/alexey.xcuserdatad/UserInterfaceState.xcuserstate deleted file mode 100644 index 7c10d39768f..00000000000 Binary files a/X2tConverter/build/Mac/OdfOfficeConverter/OdfOfficeConverter.xcodeproj/project.xcworkspace/xcuserdata/alexey.xcuserdatad/UserInterfaceState.xcuserstate and /dev/null differ diff --git a/X2tConverter/build/Mac/OdfOfficeConverter/OdfOfficeConverter.xcodeproj/xcuserdata/alexey.musinov.xcuserdatad/xcschemes/xcschememanagement.plist b/X2tConverter/build/Mac/OdfOfficeConverter/OdfOfficeConverter.xcodeproj/xcuserdata/alexey.musinov.xcuserdatad/xcschemes/xcschememanagement.plist deleted file mode 100644 index 9d3e83ec1fe..00000000000 --- a/X2tConverter/build/Mac/OdfOfficeConverter/OdfOfficeConverter.xcodeproj/xcuserdata/alexey.musinov.xcuserdatad/xcschemes/xcschememanagement.plist +++ /dev/null @@ -1,14 +0,0 @@ - - - - - SchemeUserState - - OfficeOdfConverter.xcscheme_^#shared#^_ - - orderHint - 0 - - - - diff --git a/X2tConverter/build/Mac/OdfOfficeConverter/OdfOfficeConverter.xcodeproj/xcuserdata/alexey.xcuserdatad/xcschemes/xcschememanagement.plist b/X2tConverter/build/Mac/OdfOfficeConverter/OdfOfficeConverter.xcodeproj/xcuserdata/alexey.xcuserdatad/xcschemes/xcschememanagement.plist deleted file mode 100644 index e9c1aaa5cbb..00000000000 --- a/X2tConverter/build/Mac/OdfOfficeConverter/OdfOfficeConverter.xcodeproj/xcuserdata/alexey.xcuserdatad/xcschemes/xcschememanagement.plist +++ /dev/null @@ -1,22 +0,0 @@ - - - - - SchemeUserState - - OdfOfficeConverter.xcscheme_^#shared#^_ - - orderHint - 5 - - - SuppressBuildableAutocreation - - 17513B032216E721008B45F7 - - primary - - - - - diff --git a/X2tConverter/build/Mac/OdfOfficeConverter/OdfOfficeConverter/OdfOfficeConverter.mm b/X2tConverter/build/Mac/OdfOfficeConverter/OdfOfficeConverter/OdfOfficeConverter.mm deleted file mode 100644 index 3ef6b1606ea..00000000000 --- a/X2tConverter/build/Mac/OdfOfficeConverter/OdfOfficeConverter/OdfOfficeConverter.mm +++ /dev/null @@ -1,167 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2023 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ - -#import "OdfOfficeConverter.h" - -#include "../../../../src/cextracttools.h" -#include "../../OfficeUtils/src/OfficeUtils.h" -#include "../../ASCOfficeOdfFile/src/ConvertOO2OOX.h" - -#include -#include -#include - -namespace NExtractTools -{ - _UINT32 __processEncryptionError(_UINT32 hRes, const std::wstring &sFrom, InputParams& params) - { - if (AVS_ERROR_DRM == hRes) - { - if(!params.getDontSaveAdditional()) - { - copyOrigin(sFrom, *params.m_sFileTo); - } - return AVS_FILEUTILS_ERROR_CONVERT_DRM; - } - else if (AVS_ERROR_PASSWORD == hRes) - { - return AVS_FILEUTILS_ERROR_CONVERT_PASSWORD; - } - return hRes; - } - - static std::wstring nsstring_to_wstring(NSString* nsstring) - { - NSStringEncoding encode = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingUTF32LE); - NSData* data = [nsstring dataUsingEncoding:encode]; - return std::wstring((wchar_t*) data.bytes, data.length / sizeof(wchar_t)); - } -} - -namespace NExtractTools -{ - _UINT32 __odf2oox_dir(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring & sTemp, InputParams& params) - { - std::wstring sTempUnpackedOdf = sTemp + FILE_SEPARATOR_STR + _T("odf_unpacked"); - NSDirectory::CreateDirectory(sTempUnpackedOdf); - - COfficeUtils oCOfficeUtils(NULL); - if (S_OK != oCOfficeUtils.ExtractToDirectory(sFrom, sTempUnpackedOdf, NULL, 0)) - return AVS_FILEUTILS_ERROR_CONVERT;; - - _UINT32 nRes = ConvertODF2OOXml(sTempUnpackedOdf, sTo, params.getFontPath(), sTemp, params.getPassword(), NULL); - nRes = __processEncryptionError(nRes, sFrom, params); - return nRes; - } - - _UINT32 __odf2oox(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring & sTemp, InputParams& params) - { - std::wstring sTempUnpackedOox = sTemp + FILE_SEPARATOR_STR + _T("oox_unpacked"); - NSDirectory::CreateDirectory(sTempUnpackedOox); - - _UINT32 nRes = __odf2oox_dir(sFrom, sTempUnpackedOox, sTemp, params); - if(SUCCEEDED_X2T(nRes)) - { - COfficeUtils oCOfficeUtils(NULL); - nRes = (S_OK == oCOfficeUtils.CompressFileOrDirectory(sTempUnpackedOox, sTo, true)) ? nRes : AVS_FILEUTILS_ERROR_CONVERT; - } - return nRes; - } -} - -@implementation OdfOfficeConverter - -- (int)odf2oox:(NSString*)nsFrom nsTo:(NSString*)nsTo nsTemp:(NSString*)nsTemp nsFontPath:(NSString*)nsFontPath { - std::wstring from = NExtractTools::nsstring_to_wstring(nsFrom); - std::wstring to = NExtractTools::nsstring_to_wstring(nsTo); - std::wstring temp = NExtractTools::nsstring_to_wstring(nsTemp); - - NExtractTools::InputParams oInputParams; - oInputParams.m_sFontDir = new std::wstring(NExtractTools::nsstring_to_wstring(nsFontPath)); - oInputParams.m_bIsNoBase64 = new bool(self.isNoBase64); - - if (self.password) { - oInputParams.m_sPassword = new std::wstring(NExtractTools::nsstring_to_wstring(self.password)); - } - - return NExtractTools::__odf2oox(from, to, temp, oInputParams); -} - -- (int)odt2docx:(NSString*)nsFrom nsTo:(NSString*)nsTo nsTemp:(NSString*)nsTemp nsFontPath:(NSString*)nsFontPath { - std::wstring from = NExtractTools::nsstring_to_wstring(nsFrom); - std::wstring to = NExtractTools::nsstring_to_wstring(nsTo); - std::wstring temp = NExtractTools::nsstring_to_wstring(nsTemp); - - NExtractTools::InputParams oInputParams; - oInputParams.m_sFontDir = new std::wstring(NExtractTools::nsstring_to_wstring(nsFontPath)); - oInputParams.m_bIsNoBase64 = new bool(self.isNoBase64); - - if (self.password) { - oInputParams.m_sPassword = new std::wstring(NExtractTools::nsstring_to_wstring(self.password)); - } - - return NExtractTools::__odf2oox(from, to, temp, oInputParams); -} - -- (int)ods2xlsx:(NSString*)nsFrom nsTo:(NSString*)nsTo nsTemp:(NSString*)nsTemp nsFontPath:(NSString*)nsFontPath { - std::wstring from = NExtractTools::nsstring_to_wstring(nsFrom); - std::wstring to = NExtractTools::nsstring_to_wstring(nsTo); - std::wstring temp = NExtractTools::nsstring_to_wstring(nsTemp); - - NExtractTools::InputParams oInputParams; - oInputParams.m_sFontDir = new std::wstring(NExtractTools::nsstring_to_wstring(nsFontPath)); - oInputParams.m_bIsNoBase64 = new bool(self.isNoBase64); - - if (self.password) { - oInputParams.m_sPassword = new std::wstring(NExtractTools::nsstring_to_wstring(self.password)); - } - - return NExtractTools::__odf2oox(from, to, temp, oInputParams); -} - -- (int)odp2pptx:(NSString*)nsFrom nsTo:(NSString*)nsTo nsTemp:(NSString*)nsTemp nsFontPath:(NSString*)nsFontPath { - std::wstring from = NExtractTools::nsstring_to_wstring(nsFrom); - std::wstring to = NExtractTools::nsstring_to_wstring(nsTo); - std::wstring temp = NExtractTools::nsstring_to_wstring(nsTemp); - - NExtractTools::InputParams oInputParams; - oInputParams.m_sFontDir = new std::wstring(NExtractTools::nsstring_to_wstring(nsFontPath)); - oInputParams.m_bIsNoBase64 = new bool(self.isNoBase64); - - if (self.password) { - oInputParams.m_sPassword = new std::wstring(NExtractTools::nsstring_to_wstring(self.password)); - } - - return NExtractTools::__odf2oox(from, to, temp, oInputParams); -} - -@end diff --git a/X2tConverter/build/Mac/OdfReadFormat/OdfReadFormat.xcodeproj/project.pbxproj b/X2tConverter/build/Mac/OdfReadFormat/OdfReadFormat.xcodeproj/project.pbxproj deleted file mode 100644 index ee7f7728d28..00000000000 --- a/X2tConverter/build/Mac/OdfReadFormat/OdfReadFormat.xcodeproj/project.pbxproj +++ /dev/null @@ -1,1408 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 50; - objects = { - -/* Begin PBXBuildFile section */ - 8A0C9D5523180FE900DCD37A /* math_table_elements.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9BF523180FE500DCD37A /* math_table_elements.cpp */; }; - 8A0C9D5623180FE900DCD37A /* text_elements.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9BF623180FE500DCD37A /* text_elements.cpp */; }; - 8A0C9D5723180FE900DCD37A /* draw_shapes_xlsx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9BF723180FE500DCD37A /* draw_shapes_xlsx.cpp */; }; - 8A0C9D5823180FE900DCD37A /* office_annotation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9BF823180FE500DCD37A /* office_annotation.cpp */; }; - 8A0C9D5923180FE900DCD37A /* style_table_properties.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9C0023180FE500DCD37A /* style_table_properties.cpp */; }; - 8A0C9D5A23180FE900DCD37A /* draw_frame_xlsx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9C0123180FE500DCD37A /* draw_frame_xlsx.cpp */; }; - 8A0C9D5B23180FE900DCD37A /* calcs_styles.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9C0323180FE500DCD37A /* calcs_styles.cpp */; }; - 8A0C9D5C23180FE900DCD37A /* style_chart_properties.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9C0423180FE500DCD37A /* style_chart_properties.cpp */; }; - 8A0C9D5D23180FE900DCD37A /* style_text_properties.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9C0723180FE500DCD37A /* style_text_properties.cpp */; }; - 8A0C9D5E23180FE900DCD37A /* logging.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9C0823180FE500DCD37A /* logging.cpp */; }; - 8A0C9D5F23180FE900DCD37A /* office_binary_data.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9C0A23180FE500DCD37A /* office_binary_data.cpp */; }; - 8A0C9D6023180FE900DCD37A /* table.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9C0B23180FE500DCD37A /* table.cpp */; }; - 8A0C9D6123180FE900DCD37A /* office_chart.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9C0C23180FE500DCD37A /* office_chart.cpp */; }; - 8A0C9D6223180FE900DCD37A /* draw_common.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9C0D23180FE500DCD37A /* draw_common.cpp */; }; - 8A0C9D6323180FE900DCD37A /* font_face.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9C0E23180FE500DCD37A /* font_face.cpp */; }; - 8A0C9D6423180FE900DCD37A /* style_map.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9C0F23180FE500DCD37A /* style_map.cpp */; }; - 8A0C9D6523180FE900DCD37A /* table_docx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9C1223180FE500DCD37A /* table_docx.cpp */; }; - 8A0C9D6623180FE900DCD37A /* svg_parser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9C1423180FE500DCD37A /* svg_parser.cpp */; }; - 8A0C9D6723180FE900DCD37A /* style_paragraph_properties_pptx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9C1623180FE500DCD37A /* style_paragraph_properties_pptx.cpp */; }; - 8A0C9D6823180FE900DCD37A /* office_scripts.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9C1723180FE500DCD37A /* office_scripts.cpp */; }; - 8A0C9D6923180FE900DCD37A /* styles_list.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9C1823180FE500DCD37A /* styles_list.cpp */; }; - 8A0C9D6A23180FE900DCD37A /* table_calculation_settings.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9C1A23180FE500DCD37A /* table_calculation_settings.cpp */; }; - 8A0C9D6B23180FE900DCD37A /* styles_lite_container.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9C1B23180FE500DCD37A /* styles_lite_container.cpp */; }; - 8A0C9D6C23180FE900DCD37A /* textemphasize.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9C1E23180FE500DCD37A /* textemphasize.cpp */; }; - 8A0C9D6D23180FE900DCD37A /* bordermodel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9C1F23180FE500DCD37A /* bordermodel.cpp */; }; - 8A0C9D6E23180FE900DCD37A /* letterspacing.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9C2023180FE500DCD37A /* letterspacing.cpp */; }; - 8A0C9D6F23180FE900DCD37A /* textrotationscale.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9C2123180FE500DCD37A /* textrotationscale.cpp */; }; - 8A0C9D7023180FE900DCD37A /* tablecentering.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9C2223180FE500DCD37A /* tablecentering.cpp */; }; - 8A0C9D7123180FE900DCD37A /* chartinterpolation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9C2423180FE500DCD37A /* chartinterpolation.cpp */; }; - 8A0C9D7223180FE900DCD37A /* fontvariant.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9C2623180FE500DCD37A /* fontvariant.cpp */; }; - 8A0C9D7323180FE900DCD37A /* tableorder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9C2723180FE500DCD37A /* tableorder.cpp */; }; - 8A0C9D7423180FE900DCD37A /* scripttype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9C2823180FE500DCD37A /* scripttype.cpp */; }; - 8A0C9D7523180FE900DCD37A /* calcext_type.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9C2B23180FE500DCD37A /* calcext_type.cpp */; }; - 8A0C9D7623180FE900DCD37A /* runthrough.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9C2C23180FE500DCD37A /* runthrough.cpp */; }; - 8A0C9D7723180FE900DCD37A /* stylewrap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9C2F23180FE500DCD37A /* stylewrap.cpp */; }; - 8A0C9D7823180FE900DCD37A /* borderwidths.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9C3023180FE500DCD37A /* borderwidths.cpp */; }; - 8A0C9D7923180FE900DCD37A /* length.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9C3123180FE500DCD37A /* length.cpp */; }; - 8A0C9D7A23180FE900DCD37A /* commandtype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9C3323180FE500DCD37A /* commandtype.cpp */; }; - 8A0C9D7B23180FE900DCD37A /* textalignsource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9C3423180FE500DCD37A /* textalignsource.cpp */; }; - 8A0C9D7C23180FE900DCD37A /* styleposition.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9C3723180FE500DCD37A /* styleposition.cpp */; }; - 8A0C9D7D23180FE900DCD37A /* backgroundcolor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9C3A23180FE600DCD37A /* backgroundcolor.cpp */; }; - 8A0C9D7E23180FE900DCD37A /* clockvalue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9C3B23180FE600DCD37A /* clockvalue.cpp */; }; - 8A0C9D7F23180FE900DCD37A /* rotationalign.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9C3C23180FE600DCD37A /* rotationalign.cpp */; }; - 8A0C9D8023180FE900DCD37A /* fontrelief.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9C3D23180FE600DCD37A /* fontrelief.cpp */; }; - 8A0C9D8123180FE900DCD37A /* pageusage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9C3F23180FE600DCD37A /* pageusage.cpp */; }; - 8A0C9D8223180FE900DCD37A /* chartsymbol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9C4123180FE600DCD37A /* chartsymbol.cpp */; }; - 8A0C9D8323180FE900DCD37A /* hyphenationkeep.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9C4723180FE600DCD37A /* hyphenationkeep.cpp */; }; - 8A0C9D8423180FE900DCD37A /* styleleadercolor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9C4823180FE600DCD37A /* styleleadercolor.cpp */; }; - 8A0C9D8523180FE900DCD37A /* stylehorizontalrel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9C4C23180FE600DCD37A /* stylehorizontalrel.cpp */; }; - 8A0C9D8623180FE900DCD37A /* percent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9C4D23180FE600DCD37A /* percent.cpp */; }; - 8A0C9D8723180FE900DCD37A /* iconset_type.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9C4E23180FE600DCD37A /* iconset_type.cpp */; }; - 8A0C9D8823180FE900DCD37A /* lengthorpercent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9C4F23180FE600DCD37A /* lengthorpercent.cpp */; }; - 8A0C9D8923180FE900DCD37A /* gradientstyle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9C5323180FE600DCD37A /* gradientstyle.cpp */; }; - 8A0C9D8A23180FE900DCD37A /* dategroup.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9C5823180FE600DCD37A /* dategroup.cpp */; }; - 8A0C9D8B23180FE900DCD37A /* writingmode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9C5923180FE600DCD37A /* writingmode.cpp */; }; - 8A0C9D8C23180FE900DCD37A /* chartsolidtype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9C5D23180FE600DCD37A /* chartsolidtype.cpp */; }; - 8A0C9D8D23180FE900DCD37A /* stylenumformat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9C5F23180FE600DCD37A /* stylenumformat.cpp */; }; - 8A0C9D8E23180FE900DCD37A /* presentationclass.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9C6223180FE600DCD37A /* presentationclass.cpp */; }; - 8A0C9D8F23180FE900DCD37A /* mathvariant.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9C6423180FE600DCD37A /* mathvariant.cpp */; }; - 8A0C9D9023180FE900DCD37A /* linewidth.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9C6623180FE600DCD37A /* linewidth.cpp */; }; - 8A0C9D9123180FE900DCD37A /* textalign.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9C6823180FE600DCD37A /* textalign.cpp */; }; - 8A0C9D9223180FE900DCD37A /* tablemode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9C6B23180FE600DCD37A /* tablemode.cpp */; }; - 8A0C9D9323180FE900DCD37A /* tabletype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9C6C23180FE600DCD37A /* tabletype.cpp */; }; - 8A0C9D9423180FE900DCD37A /* fontsize.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9C6F23180FE600DCD37A /* fontsize.cpp */; }; - 8A0C9D9523180FE900DCD37A /* chartlabelposition.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9C7323180FE600DCD37A /* chartlabelposition.cpp */; }; - 8A0C9D9623180FE900DCD37A /* membertype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9C7723180FE600DCD37A /* membertype.cpp */; }; - 8A0C9D9723180FE900DCD37A /* styleverticalpos.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9C7823180FE600DCD37A /* styleverticalpos.cpp */; }; - 8A0C9D9823180FE900DCD37A /* tablealign.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9C7A23180FE600DCD37A /* tablealign.cpp */; }; - 8A0C9D9923180FE900DCD37A /* chartseriessource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9C7C23180FE600DCD37A /* chartseriessource.cpp */; }; - 8A0C9D9A23180FE900DCD37A /* smil_transitiontype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9C7D23180FE600DCD37A /* smil_transitiontype.cpp */; }; - 8A0C9D9B23180FE900DCD37A /* textautospace.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9C8023180FE600DCD37A /* textautospace.cpp */; }; - 8A0C9D9C23180FE900DCD37A /* color.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9C8123180FE600DCD37A /* color.cpp */; }; - 8A0C9D9D23180FE900DCD37A /* anchortype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9C8523180FE600DCD37A /* anchortype.cpp */; }; - 8A0C9D9E23180FE900DCD37A /* keeptogether.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9C8623180FE600DCD37A /* keeptogether.cpp */; }; - 8A0C9D9F23180FE900DCD37A /* wrapoption.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9C8723180FE600DCD37A /* wrapoption.cpp */; }; - 8A0C9DA023180FE900DCD37A /* borderstyle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9C8823180FE600DCD37A /* borderstyle.cpp */; }; - 8A0C9DA123180FE900DCD37A /* chartlabelarrangement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9C8923180FE600DCD37A /* chartlabelarrangement.cpp */; }; - 8A0C9DA223180FE900DCD37A /* verticalalign.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9C8A23180FE600DCD37A /* verticalalign.cpp */; }; - 8A0C9DA323180FE900DCD37A /* common_attlists.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9C8E23180FE600DCD37A /* common_attlists.cpp */; }; - 8A0C9DA423180FE900DCD37A /* hyphenationladdercount.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9C8F23180FE600DCD37A /* hyphenationladdercount.cpp */; }; - 8A0C9DA523180FE900DCD37A /* dropcaplength.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9C9123180FE600DCD37A /* dropcaplength.cpp */; }; - 8A0C9DA623180FE900DCD37A /* style_ref.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9C9323180FE600DCD37A /* style_ref.cpp */; }; - 8A0C9DA723180FE900DCD37A /* textdisplay.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9C9623180FE600DCD37A /* textdisplay.cpp */; }; - 8A0C9DA823180FE900DCD37A /* linestyle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9C9823180FE600DCD37A /* linestyle.cpp */; }; - 8A0C9DA923180FE900DCD37A /* grandtotal.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9C9923180FE600DCD37A /* grandtotal.cpp */; }; - 8A0C9DAA23180FE900DCD37A /* punctuationwrap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9C9C23180FE600DCD37A /* punctuationwrap.cpp */; }; - 8A0C9DAB23180FE900DCD37A /* stylehorizontalpos.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9C9D23180FE700DCD37A /* stylehorizontalpos.cpp */; }; - 8A0C9DAC23180FE900DCD37A /* tablevisibility.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9CA323180FE700DCD37A /* tablevisibility.cpp */; }; - 8A0C9DAD23180FE900DCD37A /* chartregressiontype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9CA723180FE700DCD37A /* chartregressiontype.cpp */; }; - 8A0C9DAE23180FE900DCD37A /* chartdatalabelnumber.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9CA823180FE700DCD37A /* chartdatalabelnumber.cpp */; }; - 8A0C9DAF23180FE900DCD37A /* tableorientation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9CAB23180FE700DCD37A /* tableorientation.cpp */; }; - 8A0C9DB023180FE900DCD37A /* underlinecolor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9CAC23180FE700DCD37A /* underlinecolor.cpp */; }; - 8A0C9DB123180FE900DCD37A /* linebreak.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9CAE23180FE700DCD37A /* linebreak.cpp */; }; - 8A0C9DB223180FE900DCD37A /* shadowtype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9CAF23180FE700DCD37A /* shadowtype.cpp */; }; - 8A0C9DB323180FE900DCD37A /* styletype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9CB023180FE700DCD37A /* styletype.cpp */; }; - 8A0C9DB423180FE900DCD37A /* officevaluetype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9CB323180FE700DCD37A /* officevaluetype.cpp */; }; - 8A0C9DB523180FE900DCD37A /* percentorscale.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9CB423180FE700DCD37A /* percentorscale.cpp */; }; - 8A0C9DB623180FE900DCD37A /* fontweight.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9CB623180FE700DCD37A /* fontweight.cpp */; }; - 8A0C9DB723180FE900DCD37A /* bibliography.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9CB923180FE700DCD37A /* bibliography.cpp */; }; - 8A0C9DB823180FE900DCD37A /* fobreak.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9CBC23180FE700DCD37A /* fobreak.cpp */; }; - 8A0C9DB923180FE900DCD37A /* hatchstyle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9CBD23180FE700DCD37A /* hatchstyle.cpp */; }; - 8A0C9DBA23180FE900DCD37A /* fontpitch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9CBF23180FE700DCD37A /* fontpitch.cpp */; }; - 8A0C9DBB23180FE900DCD37A /* stylefamily.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9CC023180FE700DCD37A /* stylefamily.cpp */; }; - 8A0C9DBC23180FE900DCD37A /* direction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9CC123180FE700DCD37A /* direction.cpp */; }; - 8A0C9DBD23180FE900DCD37A /* textposition.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9CC423180FE700DCD37A /* textposition.cpp */; }; - 8A0C9DBE23180FE900DCD37A /* fontstretch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9CC523180FE700DCD37A /* fontstretch.cpp */; }; - 8A0C9DBF23180FE900DCD37A /* charterrorcategory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9CC723180FE700DCD37A /* charterrorcategory.cpp */; }; - 8A0C9DC023180FE900DCD37A /* fillimagerefpoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9CC823180FE700DCD37A /* fillimagerefpoint.cpp */; }; - 8A0C9DC123180FE900DCD37A /* fontstyle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9CC923180FE700DCD37A /* fontstyle.cpp */; }; - 8A0C9DC223180FE900DCD37A /* textcombine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9CCD23180FE700DCD37A /* textcombine.cpp */; }; - 8A0C9DC323180FE900DCD37A /* linetype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9CCF23180FE700DCD37A /* linetype.cpp */; }; - 8A0C9DC423180FE900DCD37A /* xlink.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9CD223180FE700DCD37A /* xlink.cpp */; }; - 8A0C9DC523180FE900DCD37A /* texttransform.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9CD623180FE700DCD37A /* texttransform.cpp */; }; - 8A0C9DC623180FE900DCD37A /* stylewrapcontourmode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9CD723180FE700DCD37A /* stylewrapcontourmode.cpp */; }; - 8A0C9DC723180FE900DCD37A /* fontfamilygeneric.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9CDB23180FE700DCD37A /* fontfamilygeneric.cpp */; }; - 8A0C9DC823180FE900DCD37A /* noteclass.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9CDC23180FE700DCD37A /* noteclass.cpp */; }; - 8A0C9DC923180FE900DCD37A /* drawfill.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9CDE23180FE700DCD37A /* drawfill.cpp */; }; - 8A0C9DCA23180FE900DCD37A /* linemode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9CE123180FE700DCD37A /* linemode.cpp */; }; - 8A0C9DCB23180FE900DCD37A /* bool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9CE223180FE700DCD37A /* bool.cpp */; }; - 8A0C9DCC23180FE900DCD37A /* tablefunction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9CE323180FE700DCD37A /* tablefunction.cpp */; }; - 8A0C9DCD23180FE900DCD37A /* markerstyle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9CE523180FE700DCD37A /* markerstyle.cpp */; }; - 8A0C9DCE23180FE900DCD37A /* layoutgridmode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9CE623180FE700DCD37A /* layoutgridmode.cpp */; }; - 8A0C9DCF23180FE900DCD37A /* targetframename.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9CE923180FE700DCD37A /* targetframename.cpp */; }; - 8A0C9DD023180FE900DCD37A /* stylerepeat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9CEA23180FE700DCD37A /* stylerepeat.cpp */; }; - 8A0C9DD123180FE900DCD37A /* styleverticalrel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9CEC23180FE700DCD37A /* styleverticalrel.cpp */; }; - 8A0C9DD223180FE900DCD37A /* math_token_elements.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9CED23180FE700DCD37A /* math_token_elements.cpp */; }; - 8A0C9DD323180FE900DCD37A /* style_paragraph_properties.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9CF023180FE700DCD37A /* style_paragraph_properties.cpp */; }; - 8A0C9DD423180FE900DCD37A /* office_document.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9CF223180FE700DCD37A /* office_document.cpp */; }; - 8A0C9DD523180FE900DCD37A /* draw_frame_pptx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9CF423180FE700DCD37A /* draw_frame_pptx.cpp */; }; - 8A0C9DD623180FE900DCD37A /* anim_elements.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9CF523180FE700DCD37A /* anim_elements.cpp */; }; - 8A0C9DD723180FE900DCD37A /* documentcontext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9CF723180FE700DCD37A /* documentcontext.cpp */; }; - 8A0C9DD823180FE900DCD37A /* odfcontext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9CFA23180FE700DCD37A /* odfcontext.cpp */; }; - 8A0C9DD923180FE900DCD37A /* office_elements_create.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9CFB23180FE700DCD37A /* office_elements_create.cpp */; }; - 8A0C9DDA23180FE900DCD37A /* draw_shapes_pptx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9CFF23180FE700DCD37A /* draw_shapes_pptx.cpp */; }; - 8A0C9DDB23180FE900DCD37A /* office_settings.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9D0323180FE800DCD37A /* office_settings.cpp */; }; - 8A0C9DDC23180FE900DCD37A /* style_presentation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9D0423180FE800DCD37A /* style_presentation.cpp */; }; - 8A0C9DDD23180FE900DCD37A /* office_text.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9D0723180FE800DCD37A /* office_text.cpp */; }; - 8A0C9DDE23180FE900DCD37A /* draw_shapes_docx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9D0C23180FE800DCD37A /* draw_shapes_docx.cpp */; }; - 8A0C9DDF23180FE900DCD37A /* calcext_elements.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9D0D23180FE800DCD37A /* calcext_elements.cpp */; }; - 8A0C9DE023180FE900DCD37A /* math_layout_elements.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9D0E23180FE800DCD37A /* math_layout_elements.cpp */; }; - 8A0C9DE123180FE900DCD37A /* math_limit_elements.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9D0F23180FE800DCD37A /* math_limit_elements.cpp */; }; - 8A0C9DE223180FE900DCD37A /* abstract_xml.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9D1123180FE800DCD37A /* abstract_xml.cpp */; }; - 8A0C9DE323180FE900DCD37A /* table_named_expressions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9D1223180FE800DCD37A /* table_named_expressions.cpp */; }; - 8A0C9DE423180FE900DCD37A /* draw_frame_docx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9D1323180FE800DCD37A /* draw_frame_docx.cpp */; }; - 8A0C9DE523180FE900DCD37A /* math_elements.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9D1523180FE800DCD37A /* math_elements.cpp */; }; - 8A0C9DE623180FE900DCD37A /* draw_page.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9D1723180FE800DCD37A /* draw_page.cpp */; }; - 8A0C9DE723180FE900DCD37A /* number_style.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9D1823180FE800DCD37A /* number_style.cpp */; }; - 8A0C9DE823180FE900DCD37A /* list.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9D1B23180FE800DCD37A /* list.cpp */; }; - 8A0C9DE923180FE900DCD37A /* office_forms.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9D1C23180FE800DCD37A /* office_forms.cpp */; }; - 8A0C9DEA23180FE900DCD37A /* text_content.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9D1E23180FE800DCD37A /* text_content.cpp */; }; - 8A0C9DEC23180FE900DCD37A /* styles.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9D2123180FE800DCD37A /* styles.cpp */; }; - 8A0C9DED23180FE900DCD37A /* table_data_pilot_tables.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9D2223180FE800DCD37A /* table_data_pilot_tables.cpp */; }; - 8A0C9DEE23180FE900DCD37A /* office_presentation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9D2423180FE800DCD37A /* office_presentation.cpp */; }; - 8A0C9DEF23180FE900DCD37A /* style_paragraph_properties_docx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9D2723180FE800DCD37A /* style_paragraph_properties_docx.cpp */; }; - 8A0C9DF023180FE900DCD37A /* table_xlsx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9D2A23180FE800DCD37A /* table_xlsx.cpp */; }; - 8A0C9DF123180FE900DCD37A /* chart_build_oox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9D2B23180FE800DCD37A /* chart_build_oox.cpp */; }; - 8A0C9DF223180FE900DCD37A /* odf_document.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9D2E23180FE800DCD37A /* odf_document.cpp */; }; - 8A0C9DF323180FE900DCD37A /* paragraph_elements.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9D2F23180FE800DCD37A /* paragraph_elements.cpp */; }; - 8A0C9DF423180FE900DCD37A /* style_regions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9D3123180FE800DCD37A /* style_regions.cpp */; }; - 8A0C9DF523180FE900DCD37A /* odf_document_impl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9D3223180FE800DCD37A /* odf_document_impl.cpp */; }; - 8A0C9DF623180FE900DCD37A /* draw_frame.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9D3323180FE800DCD37A /* draw_frame.cpp */; }; - 8A0C9DF723180FE900DCD37A /* table_pptx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9D3B23180FE800DCD37A /* table_pptx.cpp */; }; - 8A0C9DF823180FE900DCD37A /* search_table_cell.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9D3C23180FE800DCD37A /* search_table_cell.cpp */; }; - 8A0C9DF923180FE900DCD37A /* office_body.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9D3E23180FE800DCD37A /* office_body.cpp */; }; - 8A0C9DFA23180FE900DCD37A /* skipelement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9D4123180FE800DCD37A /* skipelement.cpp */; }; - 8A0C9DFB23180FE900DCD37A /* header_footer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9D4223180FE800DCD37A /* header_footer.cpp */; }; - 8A0C9DFC23180FE900DCD37A /* math_elementaries.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9D4423180FE800DCD37A /* math_elementaries.cpp */; }; - 8A0C9DFD23180FE900DCD37A /* office_meta.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9D4523180FE800DCD37A /* office_meta.cpp */; }; - 8A0C9DFE23180FE900DCD37A /* office_event_listeners.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9D4623180FE800DCD37A /* office_event_listeners.cpp */; }; - 8A0C9DFF23180FE900DCD37A /* createandread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9D4723180FE800DCD37A /* createandread.cpp */; }; - 8A0C9E0023180FE900DCD37A /* draw_shapes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9D4823180FE800DCD37A /* draw_shapes.cpp */; }; - 8A0C9E0123180FE900DCD37A /* ruby.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9D4923180FE800DCD37A /* ruby.cpp */; }; - 8A0C9E0223180FE900DCD37A /* style_graphic_properties.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9D4B23180FE800DCD37A /* style_graphic_properties.cpp */; }; - 8A0C9E0323180FE900DCD37A /* office_spreadsheet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9D4D23180FE800DCD37A /* office_spreadsheet.cpp */; }; - 8A0C9E0423180FE900DCD37A /* table_database_ranges.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9D4F23180FE800DCD37A /* table_database_ranges.cpp */; }; - 8A0C9E0523180FE900DCD37A /* templates.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9D5023180FE800DCD37A /* templates.cpp */; }; - 8A0C9E0623180FE900DCD37A /* note.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9D5323180FE800DCD37A /* note.cpp */; }; - 8A0C9E0723180FE900DCD37A /* odf_content_xml.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A0C9D5423180FE800DCD37A /* odf_content_xml.cpp */; }; -/* End PBXBuildFile section */ - -/* Begin PBXCopyFilesBuildPhase section */ - 8A0C9BE623180FD800DCD37A /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = "include/$(PRODUCT_NAME)"; - dstSubfolderSpec = 16; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXCopyFilesBuildPhase section */ - -/* Begin PBXFileReference section */ - 8A0C9BE823180FD800DCD37A /* libOdfReadFormat.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libOdfReadFormat.a; sourceTree = BUILT_PRODUCTS_DIR; }; - 8A0C9BF523180FE500DCD37A /* math_table_elements.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = math_table_elements.cpp; sourceTree = ""; }; - 8A0C9BF623180FE500DCD37A /* text_elements.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = text_elements.cpp; sourceTree = ""; }; - 8A0C9BF723180FE500DCD37A /* draw_shapes_xlsx.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = draw_shapes_xlsx.cpp; sourceTree = ""; }; - 8A0C9BF823180FE500DCD37A /* office_annotation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = office_annotation.cpp; sourceTree = ""; }; - 8A0C9BF923180FE500DCD37A /* office_binary_data.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = office_binary_data.h; sourceTree = ""; }; - 8A0C9BFA23180FE500DCD37A /* draw_frame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = draw_frame.h; sourceTree = ""; }; - 8A0C9BFB23180FE500DCD37A /* styles_lite_container.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = styles_lite_container.h; sourceTree = ""; }; - 8A0C9BFC23180FE500DCD37A /* draw_common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = draw_common.h; sourceTree = ""; }; - 8A0C9BFD23180FE500DCD37A /* office_scripts.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = office_scripts.h; sourceTree = ""; }; - 8A0C9BFE23180FE500DCD37A /* draw_page.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = draw_page.h; sourceTree = ""; }; - 8A0C9BFF23180FE500DCD37A /* anim_elements.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = anim_elements.h; sourceTree = ""; }; - 8A0C9C0023180FE500DCD37A /* style_table_properties.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = style_table_properties.cpp; sourceTree = ""; }; - 8A0C9C0123180FE500DCD37A /* draw_frame_xlsx.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = draw_frame_xlsx.cpp; sourceTree = ""; }; - 8A0C9C0223180FE500DCD37A /* chart_build_oox.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = chart_build_oox.h; sourceTree = ""; }; - 8A0C9C0323180FE500DCD37A /* calcs_styles.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = calcs_styles.cpp; sourceTree = ""; }; - 8A0C9C0423180FE500DCD37A /* style_chart_properties.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = style_chart_properties.cpp; sourceTree = ""; }; - 8A0C9C0523180FE500DCD37A /* office_meta.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = office_meta.h; sourceTree = ""; }; - 8A0C9C0623180FE500DCD37A /* table_calculation_settings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = table_calculation_settings.h; sourceTree = ""; }; - 8A0C9C0723180FE500DCD37A /* style_text_properties.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = style_text_properties.cpp; sourceTree = ""; }; - 8A0C9C0823180FE500DCD37A /* logging.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = logging.cpp; sourceTree = ""; }; - 8A0C9C0923180FE500DCD37A /* calcext_elements.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = calcext_elements.h; sourceTree = ""; }; - 8A0C9C0A23180FE500DCD37A /* office_binary_data.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = office_binary_data.cpp; sourceTree = ""; }; - 8A0C9C0B23180FE500DCD37A /* table.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = table.cpp; sourceTree = ""; }; - 8A0C9C0C23180FE500DCD37A /* office_chart.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = office_chart.cpp; sourceTree = ""; }; - 8A0C9C0D23180FE500DCD37A /* draw_common.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = draw_common.cpp; sourceTree = ""; }; - 8A0C9C0E23180FE500DCD37A /* font_face.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = font_face.cpp; sourceTree = ""; }; - 8A0C9C0F23180FE500DCD37A /* style_map.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = style_map.cpp; sourceTree = ""; }; - 8A0C9C1023180FE500DCD37A /* style_paragraph_properties.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = style_paragraph_properties.h; sourceTree = ""; }; - 8A0C9C1123180FE500DCD37A /* table_database_ranges.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = table_database_ranges.h; sourceTree = ""; }; - 8A0C9C1223180FE500DCD37A /* table_docx.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = table_docx.cpp; sourceTree = ""; }; - 8A0C9C1323180FE500DCD37A /* skipelement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = skipelement.h; sourceTree = ""; }; - 8A0C9C1423180FE500DCD37A /* svg_parser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = svg_parser.cpp; sourceTree = ""; }; - 8A0C9C1523180FE500DCD37A /* odfcontext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = odfcontext.h; sourceTree = ""; }; - 8A0C9C1623180FE500DCD37A /* style_paragraph_properties_pptx.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = style_paragraph_properties_pptx.cpp; sourceTree = ""; }; - 8A0C9C1723180FE500DCD37A /* office_scripts.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = office_scripts.cpp; sourceTree = ""; }; - 8A0C9C1823180FE500DCD37A /* styles_list.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = styles_list.cpp; sourceTree = ""; }; - 8A0C9C1923180FE500DCD37A /* math_elementaries.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = math_elementaries.h; sourceTree = ""; }; - 8A0C9C1A23180FE500DCD37A /* table_calculation_settings.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = table_calculation_settings.cpp; sourceTree = ""; }; - 8A0C9C1B23180FE500DCD37A /* styles_lite_container.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = styles_lite_container.cpp; sourceTree = ""; }; - 8A0C9C1C23180FE500DCD37A /* text_content.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = text_content.h; sourceTree = ""; }; - 8A0C9C1E23180FE500DCD37A /* textemphasize.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = textemphasize.cpp; sourceTree = ""; }; - 8A0C9C1F23180FE500DCD37A /* bordermodel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = bordermodel.cpp; sourceTree = ""; }; - 8A0C9C2023180FE500DCD37A /* letterspacing.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = letterspacing.cpp; sourceTree = ""; }; - 8A0C9C2123180FE500DCD37A /* textrotationscale.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = textrotationscale.cpp; sourceTree = ""; }; - 8A0C9C2223180FE500DCD37A /* tablecentering.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = tablecentering.cpp; sourceTree = ""; }; - 8A0C9C2323180FE500DCD37A /* backgroundcolor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = backgroundcolor.h; sourceTree = ""; }; - 8A0C9C2423180FE500DCD37A /* chartinterpolation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = chartinterpolation.cpp; sourceTree = ""; }; - 8A0C9C2523180FE500DCD37A /* linestyle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = linestyle.h; sourceTree = ""; }; - 8A0C9C2623180FE500DCD37A /* fontvariant.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = fontvariant.cpp; sourceTree = ""; }; - 8A0C9C2723180FE500DCD37A /* tableorder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = tableorder.cpp; sourceTree = ""; }; - 8A0C9C2823180FE500DCD37A /* scripttype.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = scripttype.cpp; sourceTree = ""; }; - 8A0C9C2923180FE500DCD37A /* borderwidths.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = borderwidths.h; sourceTree = ""; }; - 8A0C9C2A23180FE500DCD37A /* styleverticalpos.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = styleverticalpos.h; sourceTree = ""; }; - 8A0C9C2B23180FE500DCD37A /* calcext_type.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = calcext_type.cpp; sourceTree = ""; }; - 8A0C9C2C23180FE500DCD37A /* runthrough.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = runthrough.cpp; sourceTree = ""; }; - 8A0C9C2D23180FE500DCD37A /* fillimagerefpoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fillimagerefpoint.h; sourceTree = ""; }; - 8A0C9C2E23180FE500DCD37A /* commandtype.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = commandtype.h; sourceTree = ""; }; - 8A0C9C2F23180FE500DCD37A /* stylewrap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = stylewrap.cpp; sourceTree = ""; }; - 8A0C9C3023180FE500DCD37A /* borderwidths.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = borderwidths.cpp; sourceTree = ""; }; - 8A0C9C3123180FE500DCD37A /* length.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = length.cpp; sourceTree = ""; }; - 8A0C9C3223180FE500DCD37A /* membertype.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = membertype.h; sourceTree = ""; }; - 8A0C9C3323180FE500DCD37A /* commandtype.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = commandtype.cpp; sourceTree = ""; }; - 8A0C9C3423180FE500DCD37A /* textalignsource.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = textalignsource.cpp; sourceTree = ""; }; - 8A0C9C3523180FE500DCD37A /* styleleadercolor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = styleleadercolor.h; sourceTree = ""; }; - 8A0C9C3623180FE500DCD37A /* grandtotal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = grandtotal.h; sourceTree = ""; }; - 8A0C9C3723180FE500DCD37A /* styleposition.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = styleposition.cpp; sourceTree = ""; }; - 8A0C9C3823180FE600DCD37A /* stylenumformat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = stylenumformat.h; sourceTree = ""; }; - 8A0C9C3923180FE600DCD37A /* fontvariant.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fontvariant.h; sourceTree = ""; }; - 8A0C9C3A23180FE600DCD37A /* backgroundcolor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = backgroundcolor.cpp; sourceTree = ""; }; - 8A0C9C3B23180FE600DCD37A /* clockvalue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = clockvalue.cpp; sourceTree = ""; }; - 8A0C9C3C23180FE600DCD37A /* rotationalign.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = rotationalign.cpp; sourceTree = ""; }; - 8A0C9C3D23180FE600DCD37A /* fontrelief.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = fontrelief.cpp; sourceTree = ""; }; - 8A0C9C3E23180FE600DCD37A /* tabletype.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tabletype.h; sourceTree = ""; }; - 8A0C9C3F23180FE600DCD37A /* pageusage.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = pageusage.cpp; sourceTree = ""; }; - 8A0C9C4023180FE600DCD37A /* smil_transitiontype.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = smil_transitiontype.h; sourceTree = ""; }; - 8A0C9C4123180FE600DCD37A /* chartsymbol.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = chartsymbol.cpp; sourceTree = ""; }; - 8A0C9C4223180FE600DCD37A /* chartseriessource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = chartseriessource.h; sourceTree = ""; }; - 8A0C9C4323180FE600DCD37A /* writingmode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = writingmode.h; sourceTree = ""; }; - 8A0C9C4423180FE600DCD37A /* presentationclass.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = presentationclass.h; sourceTree = ""; }; - 8A0C9C4523180FE600DCD37A /* mathvariant.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mathvariant.h; sourceTree = ""; }; - 8A0C9C4623180FE600DCD37A /* stylewrap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = stylewrap.h; sourceTree = ""; }; - 8A0C9C4723180FE600DCD37A /* hyphenationkeep.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = hyphenationkeep.cpp; sourceTree = ""; }; - 8A0C9C4823180FE600DCD37A /* styleleadercolor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = styleleadercolor.cpp; sourceTree = ""; }; - 8A0C9C4923180FE600DCD37A /* borderstyle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = borderstyle.h; sourceTree = ""; }; - 8A0C9C4A23180FE600DCD37A /* runthrough.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = runthrough.h; sourceTree = ""; }; - 8A0C9C4B23180FE600DCD37A /* styleverticalrel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = styleverticalrel.h; sourceTree = ""; }; - 8A0C9C4C23180FE600DCD37A /* stylehorizontalrel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = stylehorizontalrel.cpp; sourceTree = ""; }; - 8A0C9C4D23180FE600DCD37A /* percent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = percent.cpp; sourceTree = ""; }; - 8A0C9C4E23180FE600DCD37A /* iconset_type.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = iconset_type.cpp; sourceTree = ""; }; - 8A0C9C4F23180FE600DCD37A /* lengthorpercent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = lengthorpercent.cpp; sourceTree = ""; }; - 8A0C9C5023180FE600DCD37A /* hatchstyle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = hatchstyle.h; sourceTree = ""; }; - 8A0C9C5123180FE600DCD37A /* common_attlists.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = common_attlists.h; sourceTree = ""; }; - 8A0C9C5223180FE600DCD37A /* linewidth.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = linewidth.h; sourceTree = ""; }; - 8A0C9C5323180FE600DCD37A /* gradientstyle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gradientstyle.cpp; sourceTree = ""; }; - 8A0C9C5423180FE600DCD37A /* percent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = percent.h; sourceTree = ""; }; - 8A0C9C5523180FE600DCD37A /* anchortype.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = anchortype.h; sourceTree = ""; }; - 8A0C9C5623180FE600DCD37A /* stylerepeat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = stylerepeat.h; sourceTree = ""; }; - 8A0C9C5723180FE600DCD37A /* bool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = bool.h; sourceTree = ""; }; - 8A0C9C5823180FE600DCD37A /* dategroup.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = dategroup.cpp; sourceTree = ""; }; - 8A0C9C5923180FE600DCD37A /* writingmode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = writingmode.cpp; sourceTree = ""; }; - 8A0C9C5A23180FE600DCD37A /* chartregressiontype.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = chartregressiontype.h; sourceTree = ""; }; - 8A0C9C5B23180FE600DCD37A /* linemode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = linemode.h; sourceTree = ""; }; - 8A0C9C5C23180FE600DCD37A /* dategroup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dategroup.h; sourceTree = ""; }; - 8A0C9C5D23180FE600DCD37A /* chartsolidtype.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = chartsolidtype.cpp; sourceTree = ""; }; - 8A0C9C5E23180FE600DCD37A /* fobreak.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fobreak.h; sourceTree = ""; }; - 8A0C9C5F23180FE600DCD37A /* stylenumformat.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = stylenumformat.cpp; sourceTree = ""; }; - 8A0C9C6023180FE600DCD37A /* tablecentering.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tablecentering.h; sourceTree = ""; }; - 8A0C9C6123180FE600DCD37A /* texttransform.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = texttransform.h; sourceTree = ""; }; - 8A0C9C6223180FE600DCD37A /* presentationclass.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = presentationclass.cpp; sourceTree = ""; }; - 8A0C9C6323180FE600DCD37A /* punctuationwrap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = punctuationwrap.h; sourceTree = ""; }; - 8A0C9C6423180FE600DCD37A /* mathvariant.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = mathvariant.cpp; sourceTree = ""; }; - 8A0C9C6523180FE600DCD37A /* keeptogether.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = keeptogether.h; sourceTree = ""; }; - 8A0C9C6623180FE600DCD37A /* linewidth.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = linewidth.cpp; sourceTree = ""; }; - 8A0C9C6723180FE600DCD37A /* textdisplay.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = textdisplay.h; sourceTree = ""; }; - 8A0C9C6823180FE600DCD37A /* textalign.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = textalign.cpp; sourceTree = ""; }; - 8A0C9C6923180FE600DCD37A /* stylehorizontalrel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = stylehorizontalrel.h; sourceTree = ""; }; - 8A0C9C6A23180FE600DCD37A /* markerstyle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = markerstyle.h; sourceTree = ""; }; - 8A0C9C6B23180FE600DCD37A /* tablemode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = tablemode.cpp; sourceTree = ""; }; - 8A0C9C6C23180FE600DCD37A /* tabletype.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = tabletype.cpp; sourceTree = ""; }; - 8A0C9C6D23180FE600DCD37A /* textposition.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = textposition.h; sourceTree = ""; }; - 8A0C9C6E23180FE600DCD37A /* letterspacing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = letterspacing.h; sourceTree = ""; }; - 8A0C9C6F23180FE600DCD37A /* fontsize.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = fontsize.cpp; sourceTree = ""; }; - 8A0C9C7023180FE600DCD37A /* tableorder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tableorder.h; sourceTree = ""; }; - 8A0C9C7123180FE600DCD37A /* errors.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = errors.h; sourceTree = ""; }; - 8A0C9C7223180FE600DCD37A /* color.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = color.h; sourceTree = ""; }; - 8A0C9C7323180FE600DCD37A /* chartlabelposition.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = chartlabelposition.cpp; sourceTree = ""; }; - 8A0C9C7423180FE600DCD37A /* rotationalign.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = rotationalign.h; sourceTree = ""; }; - 8A0C9C7523180FE600DCD37A /* style_ref.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = style_ref.h; sourceTree = ""; }; - 8A0C9C7623180FE600DCD37A /* iconset_type.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = iconset_type.h; sourceTree = ""; }; - 8A0C9C7723180FE600DCD37A /* membertype.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = membertype.cpp; sourceTree = ""; }; - 8A0C9C7823180FE600DCD37A /* styleverticalpos.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = styleverticalpos.cpp; sourceTree = ""; }; - 8A0C9C7923180FE600DCD37A /* direction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = direction.h; sourceTree = ""; }; - 8A0C9C7A23180FE600DCD37A /* tablealign.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = tablealign.cpp; sourceTree = ""; }; - 8A0C9C7B23180FE600DCD37A /* tablefunction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tablefunction.h; sourceTree = ""; }; - 8A0C9C7C23180FE600DCD37A /* chartseriessource.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = chartseriessource.cpp; sourceTree = ""; }; - 8A0C9C7D23180FE600DCD37A /* smil_transitiontype.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = smil_transitiontype.cpp; sourceTree = ""; }; - 8A0C9C7E23180FE600DCD37A /* gradientstyle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gradientstyle.h; sourceTree = ""; }; - 8A0C9C7F23180FE600DCD37A /* stylehorizontalpos.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = stylehorizontalpos.h; sourceTree = ""; }; - 8A0C9C8023180FE600DCD37A /* textautospace.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = textautospace.cpp; sourceTree = ""; }; - 8A0C9C8123180FE600DCD37A /* color.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = color.cpp; sourceTree = ""; }; - 8A0C9C8223180FE600DCD37A /* xlink.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xlink.h; sourceTree = ""; }; - 8A0C9C8323180FE600DCD37A /* hyphenationkeep.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = hyphenationkeep.h; sourceTree = ""; }; - 8A0C9C8423180FE600DCD37A /* fontfamilygeneric.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fontfamilygeneric.h; sourceTree = ""; }; - 8A0C9C8523180FE600DCD37A /* anchortype.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = anchortype.cpp; sourceTree = ""; }; - 8A0C9C8623180FE600DCD37A /* keeptogether.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = keeptogether.cpp; sourceTree = ""; }; - 8A0C9C8723180FE600DCD37A /* wrapoption.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrapoption.cpp; sourceTree = ""; }; - 8A0C9C8823180FE600DCD37A /* borderstyle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = borderstyle.cpp; sourceTree = ""; }; - 8A0C9C8923180FE600DCD37A /* chartlabelarrangement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = chartlabelarrangement.cpp; sourceTree = ""; }; - 8A0C9C8A23180FE600DCD37A /* verticalalign.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = verticalalign.cpp; sourceTree = ""; }; - 8A0C9C8B23180FE600DCD37A /* tablemode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tablemode.h; sourceTree = ""; }; - 8A0C9C8C23180FE600DCD37A /* chartsymbol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = chartsymbol.h; sourceTree = ""; }; - 8A0C9C8D23180FE600DCD37A /* textautospace.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = textautospace.h; sourceTree = ""; }; - 8A0C9C8E23180FE600DCD37A /* common_attlists.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = common_attlists.cpp; sourceTree = ""; }; - 8A0C9C8F23180FE600DCD37A /* hyphenationladdercount.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = hyphenationladdercount.cpp; sourceTree = ""; }; - 8A0C9C9023180FE600DCD37A /* underlinecolor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = underlinecolor.h; sourceTree = ""; }; - 8A0C9C9123180FE600DCD37A /* dropcaplength.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = dropcaplength.cpp; sourceTree = ""; }; - 8A0C9C9223180FE600DCD37A /* layoutgridmode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = layoutgridmode.h; sourceTree = ""; }; - 8A0C9C9323180FE600DCD37A /* style_ref.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = style_ref.cpp; sourceTree = ""; }; - 8A0C9C9423180FE600DCD37A /* custom_shape_types_convert.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = custom_shape_types_convert.h; sourceTree = ""; }; - 8A0C9C9523180FE600DCD37A /* calcext_type.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = calcext_type.h; sourceTree = ""; }; - 8A0C9C9623180FE600DCD37A /* textdisplay.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = textdisplay.cpp; sourceTree = ""; }; - 8A0C9C9723180FE600DCD37A /* chartsolidtype.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = chartsolidtype.h; sourceTree = ""; }; - 8A0C9C9823180FE600DCD37A /* linestyle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = linestyle.cpp; sourceTree = ""; }; - 8A0C9C9923180FE600DCD37A /* grandtotal.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = grandtotal.cpp; sourceTree = ""; }; - 8A0C9C9A23180FE600DCD37A /* chartdatalabelnumber.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = chartdatalabelnumber.h; sourceTree = ""; }; - 8A0C9C9B23180FE600DCD37A /* styleposition.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = styleposition.h; sourceTree = ""; }; - 8A0C9C9C23180FE600DCD37A /* punctuationwrap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = punctuationwrap.cpp; sourceTree = ""; }; - 8A0C9C9D23180FE700DCD37A /* stylehorizontalpos.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = stylehorizontalpos.cpp; sourceTree = ""; }; - 8A0C9C9E23180FE700DCD37A /* textalignsource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = textalignsource.h; sourceTree = ""; }; - 8A0C9C9F23180FE700DCD37A /* targetframename.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = targetframename.h; sourceTree = ""; }; - 8A0C9CA023180FE700DCD37A /* tablevisibility.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tablevisibility.h; sourceTree = ""; }; - 8A0C9CA123180FE700DCD37A /* lengthorpercent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lengthorpercent.h; sourceTree = ""; }; - 8A0C9CA223180FE700DCD37A /* textrotationscale.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = textrotationscale.h; sourceTree = ""; }; - 8A0C9CA323180FE700DCD37A /* tablevisibility.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = tablevisibility.cpp; sourceTree = ""; }; - 8A0C9CA423180FE700DCD37A /* wrapoption.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrapoption.h; sourceTree = ""; }; - 8A0C9CA523180FE700DCD37A /* bordermodel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = bordermodel.h; sourceTree = ""; }; - 8A0C9CA623180FE700DCD37A /* stylewrapcontourmode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = stylewrapcontourmode.h; sourceTree = ""; }; - 8A0C9CA723180FE700DCD37A /* chartregressiontype.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = chartregressiontype.cpp; sourceTree = ""; }; - 8A0C9CA823180FE700DCD37A /* chartdatalabelnumber.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = chartdatalabelnumber.cpp; sourceTree = ""; }; - 8A0C9CA923180FE700DCD37A /* length.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = length.h; sourceTree = ""; }; - 8A0C9CAA23180FE700DCD37A /* fontsize.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fontsize.h; sourceTree = ""; }; - 8A0C9CAB23180FE700DCD37A /* tableorientation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = tableorientation.cpp; sourceTree = ""; }; - 8A0C9CAC23180FE700DCD37A /* underlinecolor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = underlinecolor.cpp; sourceTree = ""; }; - 8A0C9CAD23180FE700DCD37A /* charterrorcategory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = charterrorcategory.h; sourceTree = ""; }; - 8A0C9CAE23180FE700DCD37A /* linebreak.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = linebreak.cpp; sourceTree = ""; }; - 8A0C9CAF23180FE700DCD37A /* shadowtype.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = shadowtype.cpp; sourceTree = ""; }; - 8A0C9CB023180FE700DCD37A /* styletype.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = styletype.cpp; sourceTree = ""; }; - 8A0C9CB123180FE700DCD37A /* chartinterpolation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = chartinterpolation.h; sourceTree = ""; }; - 8A0C9CB223180FE700DCD37A /* fontweight.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fontweight.h; sourceTree = ""; }; - 8A0C9CB323180FE700DCD37A /* officevaluetype.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = officevaluetype.cpp; sourceTree = ""; }; - 8A0C9CB423180FE700DCD37A /* percentorscale.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = percentorscale.cpp; sourceTree = ""; }; - 8A0C9CB523180FE700DCD37A /* officevaluetype.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = officevaluetype.h; sourceTree = ""; }; - 8A0C9CB623180FE700DCD37A /* fontweight.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = fontweight.cpp; sourceTree = ""; }; - 8A0C9CB723180FE700DCD37A /* chartlabelarrangement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = chartlabelarrangement.h; sourceTree = ""; }; - 8A0C9CB823180FE700DCD37A /* hyphenationladdercount.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = hyphenationladdercount.h; sourceTree = ""; }; - 8A0C9CB923180FE700DCD37A /* bibliography.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = bibliography.cpp; sourceTree = ""; }; - 8A0C9CBA23180FE700DCD37A /* verticalalign.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = verticalalign.h; sourceTree = ""; }; - 8A0C9CBB23180FE700DCD37A /* scripttype.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = scripttype.h; sourceTree = ""; }; - 8A0C9CBC23180FE700DCD37A /* fobreak.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = fobreak.cpp; sourceTree = ""; }; - 8A0C9CBD23180FE700DCD37A /* hatchstyle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = hatchstyle.cpp; sourceTree = ""; }; - 8A0C9CBE23180FE700DCD37A /* dropcaplength.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dropcaplength.h; sourceTree = ""; }; - 8A0C9CBF23180FE700DCD37A /* fontpitch.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = fontpitch.cpp; sourceTree = ""; }; - 8A0C9CC023180FE700DCD37A /* stylefamily.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = stylefamily.cpp; sourceTree = ""; }; - 8A0C9CC123180FE700DCD37A /* direction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = direction.cpp; sourceTree = ""; }; - 8A0C9CC223180FE700DCD37A /* drawfill.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = drawfill.h; sourceTree = ""; }; - 8A0C9CC323180FE700DCD37A /* styletype.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = styletype.h; sourceTree = ""; }; - 8A0C9CC423180FE700DCD37A /* textposition.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = textposition.cpp; sourceTree = ""; }; - 8A0C9CC523180FE700DCD37A /* fontstretch.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = fontstretch.cpp; sourceTree = ""; }; - 8A0C9CC623180FE700DCD37A /* odfattributes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = odfattributes.h; sourceTree = ""; }; - 8A0C9CC723180FE700DCD37A /* charterrorcategory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = charterrorcategory.cpp; sourceTree = ""; }; - 8A0C9CC823180FE700DCD37A /* fillimagerefpoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = fillimagerefpoint.cpp; sourceTree = ""; }; - 8A0C9CC923180FE700DCD37A /* fontstyle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = fontstyle.cpp; sourceTree = ""; }; - 8A0C9CCA23180FE700DCD37A /* noteclass.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = noteclass.h; sourceTree = ""; }; - 8A0C9CCB23180FE700DCD37A /* linetype.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = linetype.h; sourceTree = ""; }; - 8A0C9CCC23180FE700DCD37A /* pageusage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pageusage.h; sourceTree = ""; }; - 8A0C9CCD23180FE700DCD37A /* textcombine.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = textcombine.cpp; sourceTree = ""; }; - 8A0C9CCE23180FE700DCD37A /* textalign.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = textalign.h; sourceTree = ""; }; - 8A0C9CCF23180FE700DCD37A /* linetype.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = linetype.cpp; sourceTree = ""; }; - 8A0C9CD023180FE700DCD37A /* clockvalue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = clockvalue.h; sourceTree = ""; }; - 8A0C9CD123180FE700DCD37A /* percentorscale.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = percentorscale.h; sourceTree = ""; }; - 8A0C9CD223180FE700DCD37A /* xlink.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = xlink.cpp; sourceTree = ""; }; - 8A0C9CD323180FE700DCD37A /* shadowtype.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = shadowtype.h; sourceTree = ""; }; - 8A0C9CD423180FE700DCD37A /* chartlabelposition.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = chartlabelposition.h; sourceTree = ""; }; - 8A0C9CD523180FE700DCD37A /* stylefamily.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = stylefamily.h; sourceTree = ""; }; - 8A0C9CD623180FE700DCD37A /* texttransform.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = texttransform.cpp; sourceTree = ""; }; - 8A0C9CD723180FE700DCD37A /* stylewrapcontourmode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = stylewrapcontourmode.cpp; sourceTree = ""; }; - 8A0C9CD823180FE700DCD37A /* fontrelief.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fontrelief.h; sourceTree = ""; }; - 8A0C9CD923180FE700DCD37A /* fontstyle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fontstyle.h; sourceTree = ""; }; - 8A0C9CDA23180FE700DCD37A /* fontpitch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fontpitch.h; sourceTree = ""; }; - 8A0C9CDB23180FE700DCD37A /* fontfamilygeneric.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = fontfamilygeneric.cpp; sourceTree = ""; }; - 8A0C9CDC23180FE700DCD37A /* noteclass.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = noteclass.cpp; sourceTree = ""; }; - 8A0C9CDD23180FE700DCD37A /* textemphasize.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = textemphasize.h; sourceTree = ""; }; - 8A0C9CDE23180FE700DCD37A /* drawfill.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = drawfill.cpp; sourceTree = ""; }; - 8A0C9CDF23180FE700DCD37A /* bibliography.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = bibliography.h; sourceTree = ""; }; - 8A0C9CE023180FE700DCD37A /* tablealign.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tablealign.h; sourceTree = ""; }; - 8A0C9CE123180FE700DCD37A /* linemode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = linemode.cpp; sourceTree = ""; }; - 8A0C9CE223180FE700DCD37A /* bool.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = bool.cpp; sourceTree = ""; }; - 8A0C9CE323180FE700DCD37A /* tablefunction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = tablefunction.cpp; sourceTree = ""; }; - 8A0C9CE423180FE700DCD37A /* linebreak.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = linebreak.h; sourceTree = ""; }; - 8A0C9CE523180FE700DCD37A /* markerstyle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = markerstyle.cpp; sourceTree = ""; }; - 8A0C9CE623180FE700DCD37A /* layoutgridmode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = layoutgridmode.cpp; sourceTree = ""; }; - 8A0C9CE723180FE700DCD37A /* tableorientation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tableorientation.h; sourceTree = ""; }; - 8A0C9CE823180FE700DCD37A /* textcombine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = textcombine.h; sourceTree = ""; }; - 8A0C9CE923180FE700DCD37A /* targetframename.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = targetframename.cpp; sourceTree = ""; }; - 8A0C9CEA23180FE700DCD37A /* stylerepeat.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = stylerepeat.cpp; sourceTree = ""; }; - 8A0C9CEB23180FE700DCD37A /* fontstretch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fontstretch.h; sourceTree = ""; }; - 8A0C9CEC23180FE700DCD37A /* styleverticalrel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = styleverticalrel.cpp; sourceTree = ""; }; - 8A0C9CED23180FE700DCD37A /* math_token_elements.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = math_token_elements.cpp; sourceTree = ""; }; - 8A0C9CEE23180FE700DCD37A /* office_annotation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = office_annotation.h; sourceTree = ""; }; - 8A0C9CEF23180FE700DCD37A /* math_limit_elements.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = math_limit_elements.h; sourceTree = ""; }; - 8A0C9CF023180FE700DCD37A /* style_paragraph_properties.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = style_paragraph_properties.cpp; sourceTree = ""; }; - 8A0C9CF123180FE700DCD37A /* office_chart.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = office_chart.h; sourceTree = ""; }; - 8A0C9CF223180FE700DCD37A /* office_document.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = office_document.cpp; sourceTree = ""; }; - 8A0C9CF323180FE700DCD37A /* table_data_pilot_tables.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = table_data_pilot_tables.h; sourceTree = ""; }; - 8A0C9CF423180FE700DCD37A /* draw_frame_pptx.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = draw_frame_pptx.cpp; sourceTree = ""; }; - 8A0C9CF523180FE700DCD37A /* anim_elements.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = anim_elements.cpp; sourceTree = ""; }; - 8A0C9CF623180FE700DCD37A /* math_layout_elements.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = math_layout_elements.h; sourceTree = ""; }; - 8A0C9CF723180FE700DCD37A /* documentcontext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = documentcontext.cpp; sourceTree = ""; }; - 8A0C9CF823180FE700DCD37A /* office_event_listeners.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = office_event_listeners.h; sourceTree = ""; }; - 8A0C9CF923180FE700DCD37A /* style_table_properties.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = style_table_properties.h; sourceTree = ""; }; - 8A0C9CFA23180FE700DCD37A /* odfcontext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = odfcontext.cpp; sourceTree = ""; }; - 8A0C9CFB23180FE700DCD37A /* office_elements_create.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = office_elements_create.cpp; sourceTree = ""; }; - 8A0C9CFC23180FE700DCD37A /* office_elements.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = office_elements.h; sourceTree = ""; }; - 8A0C9CFD23180FE700DCD37A /* office_settings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = office_settings.h; sourceTree = ""; }; - 8A0C9CFE23180FE700DCD37A /* svg_parser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = svg_parser.h; sourceTree = ""; }; - 8A0C9CFF23180FE700DCD37A /* draw_shapes_pptx.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = draw_shapes_pptx.cpp; sourceTree = ""; }; - 8A0C9D0023180FE800DCD37A /* style_presentation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = style_presentation.h; sourceTree = ""; }; - 8A0C9D0123180FE800DCD37A /* style_graphic_properties.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = style_graphic_properties.h; sourceTree = ""; }; - 8A0C9D0223180FE800DCD37A /* draw_shapes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = draw_shapes.h; sourceTree = ""; }; - 8A0C9D0323180FE800DCD37A /* office_settings.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = office_settings.cpp; sourceTree = ""; }; - 8A0C9D0423180FE800DCD37A /* style_presentation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = style_presentation.cpp; sourceTree = ""; }; - 8A0C9D0523180FE800DCD37A /* visitor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = visitor.h; sourceTree = ""; }; - 8A0C9D0623180FE800DCD37A /* styles.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = styles.h; sourceTree = ""; }; - 8A0C9D0723180FE800DCD37A /* office_text.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = office_text.cpp; sourceTree = ""; }; - 8A0C9D0823180FE800DCD37A /* odf_content_xml.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = odf_content_xml.h; sourceTree = ""; }; - 8A0C9D0923180FE800DCD37A /* all_elements.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = all_elements.h; sourceTree = ""; }; - 8A0C9D0A23180FE800DCD37A /* calcs_styles.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = calcs_styles.h; sourceTree = ""; }; - 8A0C9D0B23180FE800DCD37A /* style_map.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = style_map.h; sourceTree = ""; }; - 8A0C9D0C23180FE800DCD37A /* draw_shapes_docx.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = draw_shapes_docx.cpp; sourceTree = ""; }; - 8A0C9D0D23180FE800DCD37A /* calcext_elements.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = calcext_elements.cpp; sourceTree = ""; }; - 8A0C9D0E23180FE800DCD37A /* math_layout_elements.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = math_layout_elements.cpp; sourceTree = ""; }; - 8A0C9D0F23180FE800DCD37A /* math_limit_elements.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = math_limit_elements.cpp; sourceTree = ""; }; - 8A0C9D1023180FE800DCD37A /* list.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = list.h; sourceTree = ""; }; - 8A0C9D1123180FE800DCD37A /* abstract_xml.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = abstract_xml.cpp; sourceTree = ""; }; - 8A0C9D1223180FE800DCD37A /* table_named_expressions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = table_named_expressions.cpp; sourceTree = ""; }; - 8A0C9D1323180FE800DCD37A /* draw_frame_docx.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = draw_frame_docx.cpp; sourceTree = ""; }; - 8A0C9D1423180FE800DCD37A /* style_chart_properties.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = style_chart_properties.h; sourceTree = ""; }; - 8A0C9D1523180FE800DCD37A /* math_elements.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = math_elements.cpp; sourceTree = ""; }; - 8A0C9D1623180FE800DCD37A /* styles_list.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = styles_list.h; sourceTree = ""; }; - 8A0C9D1723180FE800DCD37A /* draw_page.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = draw_page.cpp; sourceTree = ""; }; - 8A0C9D1823180FE800DCD37A /* number_style.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = number_style.cpp; sourceTree = ""; }; - 8A0C9D1923180FE800DCD37A /* office_elements_create.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = office_elements_create.h; sourceTree = ""; }; - 8A0C9D1A23180FE800DCD37A /* abstract_xml.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = abstract_xml.h; sourceTree = ""; }; - 8A0C9D1B23180FE800DCD37A /* list.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = list.cpp; sourceTree = ""; }; - 8A0C9D1C23180FE800DCD37A /* office_forms.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = office_forms.cpp; sourceTree = ""; }; - 8A0C9D1D23180FE800DCD37A /* serialize_elements.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = serialize_elements.h; sourceTree = ""; }; - 8A0C9D1E23180FE800DCD37A /* text_content.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = text_content.cpp; sourceTree = ""; }; - 8A0C9D1F23180FE800DCD37A /* math_table_elements.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = math_table_elements.h; sourceTree = ""; }; - 8A0C9D2123180FE800DCD37A /* styles.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = styles.cpp; sourceTree = ""; }; - 8A0C9D2223180FE800DCD37A /* table_data_pilot_tables.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = table_data_pilot_tables.cpp; sourceTree = ""; }; - 8A0C9D2323180FE800DCD37A /* office_body.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = office_body.h; sourceTree = ""; }; - 8A0C9D2423180FE800DCD37A /* office_presentation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = office_presentation.cpp; sourceTree = ""; }; - 8A0C9D2523180FE800DCD37A /* math_token_elements.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = math_token_elements.h; sourceTree = ""; }; - 8A0C9D2623180FE800DCD37A /* documentcontext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = documentcontext.h; sourceTree = ""; }; - 8A0C9D2723180FE800DCD37A /* style_paragraph_properties_docx.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = style_paragraph_properties_docx.cpp; sourceTree = ""; }; - 8A0C9D2823180FE800DCD37A /* style_regions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = style_regions.h; sourceTree = ""; }; - 8A0C9D2923180FE800DCD37A /* odf_document_impl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = odf_document_impl.h; sourceTree = ""; }; - 8A0C9D2A23180FE800DCD37A /* table_xlsx.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = table_xlsx.cpp; sourceTree = ""; }; - 8A0C9D2B23180FE800DCD37A /* chart_build_oox.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = chart_build_oox.cpp; sourceTree = ""; }; - 8A0C9D2C23180FE800DCD37A /* chart_objects.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = chart_objects.h; sourceTree = ""; }; - 8A0C9D2D23180FE800DCD37A /* office_spreadsheet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = office_spreadsheet.h; sourceTree = ""; }; - 8A0C9D2E23180FE800DCD37A /* odf_document.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = odf_document.cpp; sourceTree = ""; }; - 8A0C9D2F23180FE800DCD37A /* paragraph_elements.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = paragraph_elements.cpp; sourceTree = ""; }; - 8A0C9D3023180FE800DCD37A /* table.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = table.h; sourceTree = ""; }; - 8A0C9D3123180FE800DCD37A /* style_regions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = style_regions.cpp; sourceTree = ""; }; - 8A0C9D3223180FE800DCD37A /* odf_document_impl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = odf_document_impl.cpp; sourceTree = ""; }; - 8A0C9D3323180FE800DCD37A /* draw_frame.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = draw_frame.cpp; sourceTree = ""; }; - 8A0C9D3423180FE800DCD37A /* style_text_properties.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = style_text_properties.h; sourceTree = ""; }; - 8A0C9D3523180FE800DCD37A /* header_footer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = header_footer.h; sourceTree = ""; }; - 8A0C9D3623180FE800DCD37A /* paragraph_elements.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = paragraph_elements.h; sourceTree = ""; }; - 8A0C9D3723180FE800DCD37A /* text_elements.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = text_elements.h; sourceTree = ""; }; - 8A0C9D3823180FE800DCD37A /* search_table_cell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = search_table_cell.h; sourceTree = ""; }; - 8A0C9D3923180FE800DCD37A /* office_forms.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = office_forms.h; sourceTree = ""; }; - 8A0C9D3A23180FE800DCD37A /* office_text.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = office_text.h; sourceTree = ""; }; - 8A0C9D3B23180FE800DCD37A /* table_pptx.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = table_pptx.cpp; sourceTree = ""; }; - 8A0C9D3C23180FE800DCD37A /* search_table_cell.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = search_table_cell.cpp; sourceTree = ""; }; - 8A0C9D3D23180FE800DCD37A /* number_style.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = number_style.h; sourceTree = ""; }; - 8A0C9D3E23180FE800DCD37A /* office_body.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = office_body.cpp; sourceTree = ""; }; - 8A0C9D3F23180FE800DCD37A /* ruby.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ruby.h; sourceTree = ""; }; - 8A0C9D4023180FE800DCD37A /* table_named_expressions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = table_named_expressions.h; sourceTree = ""; }; - 8A0C9D4123180FE800DCD37A /* skipelement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = skipelement.cpp; sourceTree = ""; }; - 8A0C9D4223180FE800DCD37A /* header_footer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = header_footer.cpp; sourceTree = ""; }; - 8A0C9D4323180FE800DCD37A /* math_elements.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = math_elements.h; sourceTree = ""; }; - 8A0C9D4423180FE800DCD37A /* math_elementaries.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = math_elementaries.cpp; sourceTree = ""; }; - 8A0C9D4523180FE800DCD37A /* office_meta.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = office_meta.cpp; sourceTree = ""; }; - 8A0C9D4623180FE800DCD37A /* office_event_listeners.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = office_event_listeners.cpp; sourceTree = ""; }; - 8A0C9D4723180FE800DCD37A /* createandread.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = createandread.cpp; sourceTree = ""; }; - 8A0C9D4823180FE800DCD37A /* draw_shapes.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = draw_shapes.cpp; sourceTree = ""; }; - 8A0C9D4923180FE800DCD37A /* ruby.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ruby.cpp; sourceTree = ""; }; - 8A0C9D4A23180FE800DCD37A /* font_face.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = font_face.h; sourceTree = ""; }; - 8A0C9D4B23180FE800DCD37A /* style_graphic_properties.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = style_graphic_properties.cpp; sourceTree = ""; }; - 8A0C9D4C23180FE800DCD37A /* note.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = note.h; sourceTree = ""; }; - 8A0C9D4D23180FE800DCD37A /* office_spreadsheet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = office_spreadsheet.cpp; sourceTree = ""; }; - 8A0C9D4E23180FE800DCD37A /* office_document.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = office_document.h; sourceTree = ""; }; - 8A0C9D4F23180FE800DCD37A /* table_database_ranges.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = table_database_ranges.cpp; sourceTree = ""; }; - 8A0C9D5023180FE800DCD37A /* templates.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = templates.cpp; sourceTree = ""; }; - 8A0C9D5123180FE800DCD37A /* office_presentation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = office_presentation.h; sourceTree = ""; }; - 8A0C9D5223180FE800DCD37A /* templates.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = templates.h; sourceTree = ""; }; - 8A0C9D5323180FE800DCD37A /* note.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = note.cpp; sourceTree = ""; }; - 8A0C9D5423180FE800DCD37A /* odf_content_xml.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = odf_content_xml.cpp; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 8A0C9BE523180FD800DCD37A /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 8A0C9BDF23180FD800DCD37A = { - isa = PBXGroup; - children = ( - 8A0C9BF423180FE500DCD37A /* odf */, - 8A0C9BE923180FD800DCD37A /* Products */, - ); - sourceTree = ""; - }; - 8A0C9BE923180FD800DCD37A /* Products */ = { - isa = PBXGroup; - children = ( - 8A0C9BE823180FD800DCD37A /* libOdfReadFormat.a */, - ); - name = Products; - sourceTree = ""; - }; - 8A0C9BF423180FE500DCD37A /* odf */ = { - isa = PBXGroup; - children = ( - 8A0C9BF523180FE500DCD37A /* math_table_elements.cpp */, - 8A0C9BF623180FE500DCD37A /* text_elements.cpp */, - 8A0C9BF723180FE500DCD37A /* draw_shapes_xlsx.cpp */, - 8A0C9BF823180FE500DCD37A /* office_annotation.cpp */, - 8A0C9BF923180FE500DCD37A /* office_binary_data.h */, - 8A0C9BFA23180FE500DCD37A /* draw_frame.h */, - 8A0C9BFB23180FE500DCD37A /* styles_lite_container.h */, - 8A0C9BFC23180FE500DCD37A /* draw_common.h */, - 8A0C9BFD23180FE500DCD37A /* office_scripts.h */, - 8A0C9BFE23180FE500DCD37A /* draw_page.h */, - 8A0C9BFF23180FE500DCD37A /* anim_elements.h */, - 8A0C9C0023180FE500DCD37A /* style_table_properties.cpp */, - 8A0C9C0123180FE500DCD37A /* draw_frame_xlsx.cpp */, - 8A0C9C0223180FE500DCD37A /* chart_build_oox.h */, - 8A0C9C0323180FE500DCD37A /* calcs_styles.cpp */, - 8A0C9C0423180FE500DCD37A /* style_chart_properties.cpp */, - 8A0C9C0523180FE500DCD37A /* office_meta.h */, - 8A0C9C0623180FE500DCD37A /* table_calculation_settings.h */, - 8A0C9C0723180FE500DCD37A /* style_text_properties.cpp */, - 8A0C9C0823180FE500DCD37A /* logging.cpp */, - 8A0C9C0923180FE500DCD37A /* calcext_elements.h */, - 8A0C9C0A23180FE500DCD37A /* office_binary_data.cpp */, - 8A0C9C0B23180FE500DCD37A /* table.cpp */, - 8A0C9C0C23180FE500DCD37A /* office_chart.cpp */, - 8A0C9C0D23180FE500DCD37A /* draw_common.cpp */, - 8A0C9C0E23180FE500DCD37A /* font_face.cpp */, - 8A0C9C0F23180FE500DCD37A /* style_map.cpp */, - 8A0C9C1023180FE500DCD37A /* style_paragraph_properties.h */, - 8A0C9C1123180FE500DCD37A /* table_database_ranges.h */, - 8A0C9C1223180FE500DCD37A /* table_docx.cpp */, - 8A0C9C1323180FE500DCD37A /* skipelement.h */, - 8A0C9C1423180FE500DCD37A /* svg_parser.cpp */, - 8A0C9C1523180FE500DCD37A /* odfcontext.h */, - 8A0C9C1623180FE500DCD37A /* style_paragraph_properties_pptx.cpp */, - 8A0C9C1723180FE500DCD37A /* office_scripts.cpp */, - 8A0C9C1823180FE500DCD37A /* styles_list.cpp */, - 8A0C9C1923180FE500DCD37A /* math_elementaries.h */, - 8A0C9C1A23180FE500DCD37A /* table_calculation_settings.cpp */, - 8A0C9C1B23180FE500DCD37A /* styles_lite_container.cpp */, - 8A0C9C1C23180FE500DCD37A /* text_content.h */, - 8A0C9C1D23180FE500DCD37A /* datatypes */, - 8A0C9CED23180FE700DCD37A /* math_token_elements.cpp */, - 8A0C9CEE23180FE700DCD37A /* office_annotation.h */, - 8A0C9CEF23180FE700DCD37A /* math_limit_elements.h */, - 8A0C9CF023180FE700DCD37A /* style_paragraph_properties.cpp */, - 8A0C9CF123180FE700DCD37A /* office_chart.h */, - 8A0C9CF223180FE700DCD37A /* office_document.cpp */, - 8A0C9CF323180FE700DCD37A /* table_data_pilot_tables.h */, - 8A0C9CF423180FE700DCD37A /* draw_frame_pptx.cpp */, - 8A0C9CF523180FE700DCD37A /* anim_elements.cpp */, - 8A0C9CF623180FE700DCD37A /* math_layout_elements.h */, - 8A0C9CF723180FE700DCD37A /* documentcontext.cpp */, - 8A0C9CF823180FE700DCD37A /* office_event_listeners.h */, - 8A0C9CF923180FE700DCD37A /* style_table_properties.h */, - 8A0C9CFA23180FE700DCD37A /* odfcontext.cpp */, - 8A0C9CFB23180FE700DCD37A /* office_elements_create.cpp */, - 8A0C9CFC23180FE700DCD37A /* office_elements.h */, - 8A0C9CFD23180FE700DCD37A /* office_settings.h */, - 8A0C9CFE23180FE700DCD37A /* svg_parser.h */, - 8A0C9CFF23180FE700DCD37A /* draw_shapes_pptx.cpp */, - 8A0C9D0023180FE800DCD37A /* style_presentation.h */, - 8A0C9D0123180FE800DCD37A /* style_graphic_properties.h */, - 8A0C9D0223180FE800DCD37A /* draw_shapes.h */, - 8A0C9D0323180FE800DCD37A /* office_settings.cpp */, - 8A0C9D0423180FE800DCD37A /* style_presentation.cpp */, - 8A0C9D0523180FE800DCD37A /* visitor.h */, - 8A0C9D0623180FE800DCD37A /* styles.h */, - 8A0C9D0723180FE800DCD37A /* office_text.cpp */, - 8A0C9D0823180FE800DCD37A /* odf_content_xml.h */, - 8A0C9D0923180FE800DCD37A /* all_elements.h */, - 8A0C9D0A23180FE800DCD37A /* calcs_styles.h */, - 8A0C9D0B23180FE800DCD37A /* style_map.h */, - 8A0C9D0C23180FE800DCD37A /* draw_shapes_docx.cpp */, - 8A0C9D0D23180FE800DCD37A /* calcext_elements.cpp */, - 8A0C9D0E23180FE800DCD37A /* math_layout_elements.cpp */, - 8A0C9D0F23180FE800DCD37A /* math_limit_elements.cpp */, - 8A0C9D1023180FE800DCD37A /* list.h */, - 8A0C9D1123180FE800DCD37A /* abstract_xml.cpp */, - 8A0C9D1223180FE800DCD37A /* table_named_expressions.cpp */, - 8A0C9D1323180FE800DCD37A /* draw_frame_docx.cpp */, - 8A0C9D1423180FE800DCD37A /* style_chart_properties.h */, - 8A0C9D1523180FE800DCD37A /* math_elements.cpp */, - 8A0C9D1623180FE800DCD37A /* styles_list.h */, - 8A0C9D1723180FE800DCD37A /* draw_page.cpp */, - 8A0C9D1823180FE800DCD37A /* number_style.cpp */, - 8A0C9D1923180FE800DCD37A /* office_elements_create.h */, - 8A0C9D1A23180FE800DCD37A /* abstract_xml.h */, - 8A0C9D1B23180FE800DCD37A /* list.cpp */, - 8A0C9D1C23180FE800DCD37A /* office_forms.cpp */, - 8A0C9D1D23180FE800DCD37A /* serialize_elements.h */, - 8A0C9D1E23180FE800DCD37A /* text_content.cpp */, - 8A0C9D1F23180FE800DCD37A /* math_table_elements.h */, - 8A0C9D2123180FE800DCD37A /* styles.cpp */, - 8A0C9D2223180FE800DCD37A /* table_data_pilot_tables.cpp */, - 8A0C9D2323180FE800DCD37A /* office_body.h */, - 8A0C9D2423180FE800DCD37A /* office_presentation.cpp */, - 8A0C9D2523180FE800DCD37A /* math_token_elements.h */, - 8A0C9D2623180FE800DCD37A /* documentcontext.h */, - 8A0C9D2723180FE800DCD37A /* style_paragraph_properties_docx.cpp */, - 8A0C9D2823180FE800DCD37A /* style_regions.h */, - 8A0C9D2923180FE800DCD37A /* odf_document_impl.h */, - 8A0C9D2A23180FE800DCD37A /* table_xlsx.cpp */, - 8A0C9D2B23180FE800DCD37A /* chart_build_oox.cpp */, - 8A0C9D2C23180FE800DCD37A /* chart_objects.h */, - 8A0C9D2D23180FE800DCD37A /* office_spreadsheet.h */, - 8A0C9D2E23180FE800DCD37A /* odf_document.cpp */, - 8A0C9D2F23180FE800DCD37A /* paragraph_elements.cpp */, - 8A0C9D3023180FE800DCD37A /* table.h */, - 8A0C9D3123180FE800DCD37A /* style_regions.cpp */, - 8A0C9D3223180FE800DCD37A /* odf_document_impl.cpp */, - 8A0C9D3323180FE800DCD37A /* draw_frame.cpp */, - 8A0C9D3423180FE800DCD37A /* style_text_properties.h */, - 8A0C9D3523180FE800DCD37A /* header_footer.h */, - 8A0C9D3623180FE800DCD37A /* paragraph_elements.h */, - 8A0C9D3723180FE800DCD37A /* text_elements.h */, - 8A0C9D3823180FE800DCD37A /* search_table_cell.h */, - 8A0C9D3923180FE800DCD37A /* office_forms.h */, - 8A0C9D3A23180FE800DCD37A /* office_text.h */, - 8A0C9D3B23180FE800DCD37A /* table_pptx.cpp */, - 8A0C9D3C23180FE800DCD37A /* search_table_cell.cpp */, - 8A0C9D3D23180FE800DCD37A /* number_style.h */, - 8A0C9D3E23180FE800DCD37A /* office_body.cpp */, - 8A0C9D3F23180FE800DCD37A /* ruby.h */, - 8A0C9D4023180FE800DCD37A /* table_named_expressions.h */, - 8A0C9D4123180FE800DCD37A /* skipelement.cpp */, - 8A0C9D4223180FE800DCD37A /* header_footer.cpp */, - 8A0C9D4323180FE800DCD37A /* math_elements.h */, - 8A0C9D4423180FE800DCD37A /* math_elementaries.cpp */, - 8A0C9D4523180FE800DCD37A /* office_meta.cpp */, - 8A0C9D4623180FE800DCD37A /* office_event_listeners.cpp */, - 8A0C9D4723180FE800DCD37A /* createandread.cpp */, - 8A0C9D4823180FE800DCD37A /* draw_shapes.cpp */, - 8A0C9D4923180FE800DCD37A /* ruby.cpp */, - 8A0C9D4A23180FE800DCD37A /* font_face.h */, - 8A0C9D4B23180FE800DCD37A /* style_graphic_properties.cpp */, - 8A0C9D4C23180FE800DCD37A /* note.h */, - 8A0C9D4D23180FE800DCD37A /* office_spreadsheet.cpp */, - 8A0C9D4E23180FE800DCD37A /* office_document.h */, - 8A0C9D4F23180FE800DCD37A /* table_database_ranges.cpp */, - 8A0C9D5023180FE800DCD37A /* templates.cpp */, - 8A0C9D5123180FE800DCD37A /* office_presentation.h */, - 8A0C9D5223180FE800DCD37A /* templates.h */, - 8A0C9D5323180FE800DCD37A /* note.cpp */, - 8A0C9D5423180FE800DCD37A /* odf_content_xml.cpp */, - ); - name = odf; - path = ../../../../ASCOfficeOdfFile/src/odf; - sourceTree = ""; - }; - 8A0C9C1D23180FE500DCD37A /* datatypes */ = { - isa = PBXGroup; - children = ( - 8A0C9C1E23180FE500DCD37A /* textemphasize.cpp */, - 8A0C9C1F23180FE500DCD37A /* bordermodel.cpp */, - 8A0C9C2023180FE500DCD37A /* letterspacing.cpp */, - 8A0C9C2123180FE500DCD37A /* textrotationscale.cpp */, - 8A0C9C2223180FE500DCD37A /* tablecentering.cpp */, - 8A0C9C2323180FE500DCD37A /* backgroundcolor.h */, - 8A0C9C2423180FE500DCD37A /* chartinterpolation.cpp */, - 8A0C9C2523180FE500DCD37A /* linestyle.h */, - 8A0C9C2623180FE500DCD37A /* fontvariant.cpp */, - 8A0C9C2723180FE500DCD37A /* tableorder.cpp */, - 8A0C9C2823180FE500DCD37A /* scripttype.cpp */, - 8A0C9C2923180FE500DCD37A /* borderwidths.h */, - 8A0C9C2A23180FE500DCD37A /* styleverticalpos.h */, - 8A0C9C2B23180FE500DCD37A /* calcext_type.cpp */, - 8A0C9C2C23180FE500DCD37A /* runthrough.cpp */, - 8A0C9C2D23180FE500DCD37A /* fillimagerefpoint.h */, - 8A0C9C2E23180FE500DCD37A /* commandtype.h */, - 8A0C9C2F23180FE500DCD37A /* stylewrap.cpp */, - 8A0C9C3023180FE500DCD37A /* borderwidths.cpp */, - 8A0C9C3123180FE500DCD37A /* length.cpp */, - 8A0C9C3223180FE500DCD37A /* membertype.h */, - 8A0C9C3323180FE500DCD37A /* commandtype.cpp */, - 8A0C9C3423180FE500DCD37A /* textalignsource.cpp */, - 8A0C9C3523180FE500DCD37A /* styleleadercolor.h */, - 8A0C9C3623180FE500DCD37A /* grandtotal.h */, - 8A0C9C3723180FE500DCD37A /* styleposition.cpp */, - 8A0C9C3823180FE600DCD37A /* stylenumformat.h */, - 8A0C9C3923180FE600DCD37A /* fontvariant.h */, - 8A0C9C3A23180FE600DCD37A /* backgroundcolor.cpp */, - 8A0C9C3B23180FE600DCD37A /* clockvalue.cpp */, - 8A0C9C3C23180FE600DCD37A /* rotationalign.cpp */, - 8A0C9C3D23180FE600DCD37A /* fontrelief.cpp */, - 8A0C9C3E23180FE600DCD37A /* tabletype.h */, - 8A0C9C3F23180FE600DCD37A /* pageusage.cpp */, - 8A0C9C4023180FE600DCD37A /* smil_transitiontype.h */, - 8A0C9C4123180FE600DCD37A /* chartsymbol.cpp */, - 8A0C9C4223180FE600DCD37A /* chartseriessource.h */, - 8A0C9C4323180FE600DCD37A /* writingmode.h */, - 8A0C9C4423180FE600DCD37A /* presentationclass.h */, - 8A0C9C4523180FE600DCD37A /* mathvariant.h */, - 8A0C9C4623180FE600DCD37A /* stylewrap.h */, - 8A0C9C4723180FE600DCD37A /* hyphenationkeep.cpp */, - 8A0C9C4823180FE600DCD37A /* styleleadercolor.cpp */, - 8A0C9C4923180FE600DCD37A /* borderstyle.h */, - 8A0C9C4A23180FE600DCD37A /* runthrough.h */, - 8A0C9C4B23180FE600DCD37A /* styleverticalrel.h */, - 8A0C9C4C23180FE600DCD37A /* stylehorizontalrel.cpp */, - 8A0C9C4D23180FE600DCD37A /* percent.cpp */, - 8A0C9C4E23180FE600DCD37A /* iconset_type.cpp */, - 8A0C9C4F23180FE600DCD37A /* lengthorpercent.cpp */, - 8A0C9C5023180FE600DCD37A /* hatchstyle.h */, - 8A0C9C5123180FE600DCD37A /* common_attlists.h */, - 8A0C9C5223180FE600DCD37A /* linewidth.h */, - 8A0C9C5323180FE600DCD37A /* gradientstyle.cpp */, - 8A0C9C5423180FE600DCD37A /* percent.h */, - 8A0C9C5523180FE600DCD37A /* anchortype.h */, - 8A0C9C5623180FE600DCD37A /* stylerepeat.h */, - 8A0C9C5723180FE600DCD37A /* bool.h */, - 8A0C9C5823180FE600DCD37A /* dategroup.cpp */, - 8A0C9C5923180FE600DCD37A /* writingmode.cpp */, - 8A0C9C5A23180FE600DCD37A /* chartregressiontype.h */, - 8A0C9C5B23180FE600DCD37A /* linemode.h */, - 8A0C9C5C23180FE600DCD37A /* dategroup.h */, - 8A0C9C5D23180FE600DCD37A /* chartsolidtype.cpp */, - 8A0C9C5E23180FE600DCD37A /* fobreak.h */, - 8A0C9C5F23180FE600DCD37A /* stylenumformat.cpp */, - 8A0C9C6023180FE600DCD37A /* tablecentering.h */, - 8A0C9C6123180FE600DCD37A /* texttransform.h */, - 8A0C9C6223180FE600DCD37A /* presentationclass.cpp */, - 8A0C9C6323180FE600DCD37A /* punctuationwrap.h */, - 8A0C9C6423180FE600DCD37A /* mathvariant.cpp */, - 8A0C9C6523180FE600DCD37A /* keeptogether.h */, - 8A0C9C6623180FE600DCD37A /* linewidth.cpp */, - 8A0C9C6723180FE600DCD37A /* textdisplay.h */, - 8A0C9C6823180FE600DCD37A /* textalign.cpp */, - 8A0C9C6923180FE600DCD37A /* stylehorizontalrel.h */, - 8A0C9C6A23180FE600DCD37A /* markerstyle.h */, - 8A0C9C6B23180FE600DCD37A /* tablemode.cpp */, - 8A0C9C6C23180FE600DCD37A /* tabletype.cpp */, - 8A0C9C6D23180FE600DCD37A /* textposition.h */, - 8A0C9C6E23180FE600DCD37A /* letterspacing.h */, - 8A0C9C6F23180FE600DCD37A /* fontsize.cpp */, - 8A0C9C7023180FE600DCD37A /* tableorder.h */, - 8A0C9C7123180FE600DCD37A /* errors.h */, - 8A0C9C7223180FE600DCD37A /* color.h */, - 8A0C9C7323180FE600DCD37A /* chartlabelposition.cpp */, - 8A0C9C7423180FE600DCD37A /* rotationalign.h */, - 8A0C9C7523180FE600DCD37A /* style_ref.h */, - 8A0C9C7623180FE600DCD37A /* iconset_type.h */, - 8A0C9C7723180FE600DCD37A /* membertype.cpp */, - 8A0C9C7823180FE600DCD37A /* styleverticalpos.cpp */, - 8A0C9C7923180FE600DCD37A /* direction.h */, - 8A0C9C7A23180FE600DCD37A /* tablealign.cpp */, - 8A0C9C7B23180FE600DCD37A /* tablefunction.h */, - 8A0C9C7C23180FE600DCD37A /* chartseriessource.cpp */, - 8A0C9C7D23180FE600DCD37A /* smil_transitiontype.cpp */, - 8A0C9C7E23180FE600DCD37A /* gradientstyle.h */, - 8A0C9C7F23180FE600DCD37A /* stylehorizontalpos.h */, - 8A0C9C8023180FE600DCD37A /* textautospace.cpp */, - 8A0C9C8123180FE600DCD37A /* color.cpp */, - 8A0C9C8223180FE600DCD37A /* xlink.h */, - 8A0C9C8323180FE600DCD37A /* hyphenationkeep.h */, - 8A0C9C8423180FE600DCD37A /* fontfamilygeneric.h */, - 8A0C9C8523180FE600DCD37A /* anchortype.cpp */, - 8A0C9C8623180FE600DCD37A /* keeptogether.cpp */, - 8A0C9C8723180FE600DCD37A /* wrapoption.cpp */, - 8A0C9C8823180FE600DCD37A /* borderstyle.cpp */, - 8A0C9C8923180FE600DCD37A /* chartlabelarrangement.cpp */, - 8A0C9C8A23180FE600DCD37A /* verticalalign.cpp */, - 8A0C9C8B23180FE600DCD37A /* tablemode.h */, - 8A0C9C8C23180FE600DCD37A /* chartsymbol.h */, - 8A0C9C8D23180FE600DCD37A /* textautospace.h */, - 8A0C9C8E23180FE600DCD37A /* common_attlists.cpp */, - 8A0C9C8F23180FE600DCD37A /* hyphenationladdercount.cpp */, - 8A0C9C9023180FE600DCD37A /* underlinecolor.h */, - 8A0C9C9123180FE600DCD37A /* dropcaplength.cpp */, - 8A0C9C9223180FE600DCD37A /* layoutgridmode.h */, - 8A0C9C9323180FE600DCD37A /* style_ref.cpp */, - 8A0C9C9423180FE600DCD37A /* custom_shape_types_convert.h */, - 8A0C9C9523180FE600DCD37A /* calcext_type.h */, - 8A0C9C9623180FE600DCD37A /* textdisplay.cpp */, - 8A0C9C9723180FE600DCD37A /* chartsolidtype.h */, - 8A0C9C9823180FE600DCD37A /* linestyle.cpp */, - 8A0C9C9923180FE600DCD37A /* grandtotal.cpp */, - 8A0C9C9A23180FE600DCD37A /* chartdatalabelnumber.h */, - 8A0C9C9B23180FE600DCD37A /* styleposition.h */, - 8A0C9C9C23180FE600DCD37A /* punctuationwrap.cpp */, - 8A0C9C9D23180FE700DCD37A /* stylehorizontalpos.cpp */, - 8A0C9C9E23180FE700DCD37A /* textalignsource.h */, - 8A0C9C9F23180FE700DCD37A /* targetframename.h */, - 8A0C9CA023180FE700DCD37A /* tablevisibility.h */, - 8A0C9CA123180FE700DCD37A /* lengthorpercent.h */, - 8A0C9CA223180FE700DCD37A /* textrotationscale.h */, - 8A0C9CA323180FE700DCD37A /* tablevisibility.cpp */, - 8A0C9CA423180FE700DCD37A /* wrapoption.h */, - 8A0C9CA523180FE700DCD37A /* bordermodel.h */, - 8A0C9CA623180FE700DCD37A /* stylewrapcontourmode.h */, - 8A0C9CA723180FE700DCD37A /* chartregressiontype.cpp */, - 8A0C9CA823180FE700DCD37A /* chartdatalabelnumber.cpp */, - 8A0C9CA923180FE700DCD37A /* length.h */, - 8A0C9CAA23180FE700DCD37A /* fontsize.h */, - 8A0C9CAB23180FE700DCD37A /* tableorientation.cpp */, - 8A0C9CAC23180FE700DCD37A /* underlinecolor.cpp */, - 8A0C9CAD23180FE700DCD37A /* charterrorcategory.h */, - 8A0C9CAE23180FE700DCD37A /* linebreak.cpp */, - 8A0C9CAF23180FE700DCD37A /* shadowtype.cpp */, - 8A0C9CB023180FE700DCD37A /* styletype.cpp */, - 8A0C9CB123180FE700DCD37A /* chartinterpolation.h */, - 8A0C9CB223180FE700DCD37A /* fontweight.h */, - 8A0C9CB323180FE700DCD37A /* officevaluetype.cpp */, - 8A0C9CB423180FE700DCD37A /* percentorscale.cpp */, - 8A0C9CB523180FE700DCD37A /* officevaluetype.h */, - 8A0C9CB623180FE700DCD37A /* fontweight.cpp */, - 8A0C9CB723180FE700DCD37A /* chartlabelarrangement.h */, - 8A0C9CB823180FE700DCD37A /* hyphenationladdercount.h */, - 8A0C9CB923180FE700DCD37A /* bibliography.cpp */, - 8A0C9CBA23180FE700DCD37A /* verticalalign.h */, - 8A0C9CBB23180FE700DCD37A /* scripttype.h */, - 8A0C9CBC23180FE700DCD37A /* fobreak.cpp */, - 8A0C9CBD23180FE700DCD37A /* hatchstyle.cpp */, - 8A0C9CBE23180FE700DCD37A /* dropcaplength.h */, - 8A0C9CBF23180FE700DCD37A /* fontpitch.cpp */, - 8A0C9CC023180FE700DCD37A /* stylefamily.cpp */, - 8A0C9CC123180FE700DCD37A /* direction.cpp */, - 8A0C9CC223180FE700DCD37A /* drawfill.h */, - 8A0C9CC323180FE700DCD37A /* styletype.h */, - 8A0C9CC423180FE700DCD37A /* textposition.cpp */, - 8A0C9CC523180FE700DCD37A /* fontstretch.cpp */, - 8A0C9CC623180FE700DCD37A /* odfattributes.h */, - 8A0C9CC723180FE700DCD37A /* charterrorcategory.cpp */, - 8A0C9CC823180FE700DCD37A /* fillimagerefpoint.cpp */, - 8A0C9CC923180FE700DCD37A /* fontstyle.cpp */, - 8A0C9CCA23180FE700DCD37A /* noteclass.h */, - 8A0C9CCB23180FE700DCD37A /* linetype.h */, - 8A0C9CCC23180FE700DCD37A /* pageusage.h */, - 8A0C9CCD23180FE700DCD37A /* textcombine.cpp */, - 8A0C9CCE23180FE700DCD37A /* textalign.h */, - 8A0C9CCF23180FE700DCD37A /* linetype.cpp */, - 8A0C9CD023180FE700DCD37A /* clockvalue.h */, - 8A0C9CD123180FE700DCD37A /* percentorscale.h */, - 8A0C9CD223180FE700DCD37A /* xlink.cpp */, - 8A0C9CD323180FE700DCD37A /* shadowtype.h */, - 8A0C9CD423180FE700DCD37A /* chartlabelposition.h */, - 8A0C9CD523180FE700DCD37A /* stylefamily.h */, - 8A0C9CD623180FE700DCD37A /* texttransform.cpp */, - 8A0C9CD723180FE700DCD37A /* stylewrapcontourmode.cpp */, - 8A0C9CD823180FE700DCD37A /* fontrelief.h */, - 8A0C9CD923180FE700DCD37A /* fontstyle.h */, - 8A0C9CDA23180FE700DCD37A /* fontpitch.h */, - 8A0C9CDB23180FE700DCD37A /* fontfamilygeneric.cpp */, - 8A0C9CDC23180FE700DCD37A /* noteclass.cpp */, - 8A0C9CDD23180FE700DCD37A /* textemphasize.h */, - 8A0C9CDE23180FE700DCD37A /* drawfill.cpp */, - 8A0C9CDF23180FE700DCD37A /* bibliography.h */, - 8A0C9CE023180FE700DCD37A /* tablealign.h */, - 8A0C9CE123180FE700DCD37A /* linemode.cpp */, - 8A0C9CE223180FE700DCD37A /* bool.cpp */, - 8A0C9CE323180FE700DCD37A /* tablefunction.cpp */, - 8A0C9CE423180FE700DCD37A /* linebreak.h */, - 8A0C9CE523180FE700DCD37A /* markerstyle.cpp */, - 8A0C9CE623180FE700DCD37A /* layoutgridmode.cpp */, - 8A0C9CE723180FE700DCD37A /* tableorientation.h */, - 8A0C9CE823180FE700DCD37A /* textcombine.h */, - 8A0C9CE923180FE700DCD37A /* targetframename.cpp */, - 8A0C9CEA23180FE700DCD37A /* stylerepeat.cpp */, - 8A0C9CEB23180FE700DCD37A /* fontstretch.h */, - 8A0C9CEC23180FE700DCD37A /* styleverticalrel.cpp */, - ); - path = datatypes; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 8A0C9BE723180FD800DCD37A /* OdfReadFormat */ = { - isa = PBXNativeTarget; - buildConfigurationList = 8A0C9BF123180FD800DCD37A /* Build configuration list for PBXNativeTarget "OdfReadFormat" */; - buildPhases = ( - 8A0C9BE423180FD800DCD37A /* Sources */, - 8A0C9BE523180FD800DCD37A /* Frameworks */, - 8A0C9BE623180FD800DCD37A /* CopyFiles */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = OdfReadFormat; - productName = OdfReadFormat; - productReference = 8A0C9BE823180FD800DCD37A /* libOdfReadFormat.a */; - productType = "com.apple.product-type.library.static"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 8A0C9BE023180FD800DCD37A /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 1030; - ORGANIZATIONNAME = "Ascensio System SIA"; - TargetAttributes = { - 8A0C9BE723180FD800DCD37A = { - CreatedOnToolsVersion = 10.3; - }; - }; - }; - buildConfigurationList = 8A0C9BE323180FD800DCD37A /* Build configuration list for PBXProject "OdfReadFormat" */; - compatibilityVersion = "Xcode 9.3"; - developmentRegion = en; - hasScannedForEncodings = 0; - knownRegions = ( - en, - ); - mainGroup = 8A0C9BDF23180FD800DCD37A; - productRefGroup = 8A0C9BE923180FD800DCD37A /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 8A0C9BE723180FD800DCD37A /* OdfReadFormat */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXSourcesBuildPhase section */ - 8A0C9BE423180FD800DCD37A /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 8A0C9D5823180FE900DCD37A /* office_annotation.cpp in Sources */, - 8A0C9D5C23180FE900DCD37A /* style_chart_properties.cpp in Sources */, - 8A0C9DDB23180FE900DCD37A /* office_settings.cpp in Sources */, - 8A0C9DDD23180FE900DCD37A /* office_text.cpp in Sources */, - 8A0C9DDC23180FE900DCD37A /* style_presentation.cpp in Sources */, - 8A0C9DE723180FE900DCD37A /* number_style.cpp in Sources */, - 8A0C9DF123180FE900DCD37A /* chart_build_oox.cpp in Sources */, - 8A0C9DB823180FE900DCD37A /* fobreak.cpp in Sources */, - 8A0C9DA123180FE900DCD37A /* chartlabelarrangement.cpp in Sources */, - 8A0C9D9023180FE900DCD37A /* linewidth.cpp in Sources */, - 8A0C9DC323180FE900DCD37A /* linetype.cpp in Sources */, - 8A0C9D8423180FE900DCD37A /* styleleadercolor.cpp in Sources */, - 8A0C9DE523180FE900DCD37A /* math_elements.cpp in Sources */, - 8A0C9D9D23180FE900DCD37A /* anchortype.cpp in Sources */, - 8A0C9D9B23180FE900DCD37A /* textautospace.cpp in Sources */, - 8A0C9DEA23180FE900DCD37A /* text_content.cpp in Sources */, - 8A0C9DD123180FE900DCD37A /* styleverticalrel.cpp in Sources */, - 8A0C9D8A23180FE900DCD37A /* dategroup.cpp in Sources */, - 8A0C9DBD23180FE900DCD37A /* textposition.cpp in Sources */, - 8A0C9D7823180FE900DCD37A /* borderwidths.cpp in Sources */, - 8A0C9D6023180FE900DCD37A /* table.cpp in Sources */, - 8A0C9D6D23180FE900DCD37A /* bordermodel.cpp in Sources */, - 8A0C9DA223180FE900DCD37A /* verticalalign.cpp in Sources */, - 8A0C9DB023180FE900DCD37A /* underlinecolor.cpp in Sources */, - 8A0C9DFE23180FE900DCD37A /* office_event_listeners.cpp in Sources */, - 8A0C9DFD23180FE900DCD37A /* office_meta.cpp in Sources */, - 8A0C9DCD23180FE900DCD37A /* markerstyle.cpp in Sources */, - 8A0C9D9C23180FE900DCD37A /* color.cpp in Sources */, - 8A0C9DF223180FE900DCD37A /* odf_document.cpp in Sources */, - 8A0C9E0323180FE900DCD37A /* office_spreadsheet.cpp in Sources */, - 8A0C9DC123180FE900DCD37A /* fontstyle.cpp in Sources */, - 8A0C9D8023180FE900DCD37A /* fontrelief.cpp in Sources */, - 8A0C9DC623180FE900DCD37A /* stylewrapcontourmode.cpp in Sources */, - 8A0C9DF823180FE900DCD37A /* search_table_cell.cpp in Sources */, - 8A0C9D6923180FE900DCD37A /* styles_list.cpp in Sources */, - 8A0C9D8323180FE900DCD37A /* hyphenationkeep.cpp in Sources */, - 8A0C9D9523180FE900DCD37A /* chartlabelposition.cpp in Sources */, - 8A0C9D5523180FE900DCD37A /* math_table_elements.cpp in Sources */, - 8A0C9DCC23180FE900DCD37A /* tablefunction.cpp in Sources */, - 8A0C9DC223180FE900DCD37A /* textcombine.cpp in Sources */, - 8A0C9DAB23180FE900DCD37A /* stylehorizontalpos.cpp in Sources */, - 8A0C9D5D23180FE900DCD37A /* style_text_properties.cpp in Sources */, - 8A0C9D7C23180FE900DCD37A /* styleposition.cpp in Sources */, - 8A0C9DEE23180FE900DCD37A /* office_presentation.cpp in Sources */, - 8A0C9D8D23180FE900DCD37A /* stylenumformat.cpp in Sources */, - 8A0C9DA023180FE900DCD37A /* borderstyle.cpp in Sources */, - 8A0C9D6323180FE900DCD37A /* font_face.cpp in Sources */, - 8A0C9D8923180FE900DCD37A /* gradientstyle.cpp in Sources */, - 8A0C9DD023180FE900DCD37A /* stylerepeat.cpp in Sources */, - 8A0C9D7123180FE900DCD37A /* chartinterpolation.cpp in Sources */, - 8A0C9DEF23180FE900DCD37A /* style_paragraph_properties_docx.cpp in Sources */, - 8A0C9D6823180FE900DCD37A /* office_scripts.cpp in Sources */, - 8A0C9DE623180FE900DCD37A /* draw_page.cpp in Sources */, - 8A0C9DE423180FE900DCD37A /* draw_frame_docx.cpp in Sources */, - 8A0C9DCE23180FE900DCD37A /* layoutgridmode.cpp in Sources */, - 8A0C9DED23180FE900DCD37A /* table_data_pilot_tables.cpp in Sources */, - 8A0C9DEC23180FE900DCD37A /* styles.cpp in Sources */, - 8A0C9D7A23180FE900DCD37A /* commandtype.cpp in Sources */, - 8A0C9D8C23180FE900DCD37A /* chartsolidtype.cpp in Sources */, - 8A0C9DBC23180FE900DCD37A /* direction.cpp in Sources */, - 8A0C9DE823180FE900DCD37A /* list.cpp in Sources */, - 8A0C9D9823180FE900DCD37A /* tablealign.cpp in Sources */, - 8A0C9D6723180FE900DCD37A /* style_paragraph_properties_pptx.cpp in Sources */, - 8A0C9D5B23180FE900DCD37A /* calcs_styles.cpp in Sources */, - 8A0C9DD823180FE900DCD37A /* odfcontext.cpp in Sources */, - 8A0C9DB523180FE900DCD37A /* percentorscale.cpp in Sources */, - 8A0C9DD423180FE900DCD37A /* office_document.cpp in Sources */, - 8A0C9D9A23180FE900DCD37A /* smil_transitiontype.cpp in Sources */, - 8A0C9DBE23180FE900DCD37A /* fontstretch.cpp in Sources */, - 8A0C9E0023180FE900DCD37A /* draw_shapes.cpp in Sources */, - 8A0C9D9F23180FE900DCD37A /* wrapoption.cpp in Sources */, - 8A0C9D6F23180FE900DCD37A /* textrotationscale.cpp in Sources */, - 8A0C9D7623180FE900DCD37A /* runthrough.cpp in Sources */, - 8A0C9DAC23180FE900DCD37A /* tablevisibility.cpp in Sources */, - 8A0C9D5F23180FE900DCD37A /* office_binary_data.cpp in Sources */, - 8A0C9DB323180FE900DCD37A /* styletype.cpp in Sources */, - 8A0C9D6523180FE900DCD37A /* table_docx.cpp in Sources */, - 8A0C9D5A23180FE900DCD37A /* draw_frame_xlsx.cpp in Sources */, - 8A0C9DF323180FE900DCD37A /* paragraph_elements.cpp in Sources */, - 8A0C9DF523180FE900DCD37A /* odf_document_impl.cpp in Sources */, - 8A0C9D7B23180FE900DCD37A /* textalignsource.cpp in Sources */, - 8A0C9DA423180FE900DCD37A /* hyphenationladdercount.cpp in Sources */, - 8A0C9D9723180FE900DCD37A /* styleverticalpos.cpp in Sources */, - 8A0C9D6B23180FE900DCD37A /* styles_lite_container.cpp in Sources */, - 8A0C9D8723180FE900DCD37A /* iconset_type.cpp in Sources */, - 8A0C9DDA23180FE900DCD37A /* draw_shapes_pptx.cpp in Sources */, - 8A0C9D9223180FE900DCD37A /* tablemode.cpp in Sources */, - 8A0C9D5623180FE900DCD37A /* text_elements.cpp in Sources */, - 8A0C9D5E23180FE900DCD37A /* logging.cpp in Sources */, - 8A0C9DDF23180FE900DCD37A /* calcext_elements.cpp in Sources */, - 8A0C9DC723180FE900DCD37A /* fontfamilygeneric.cpp in Sources */, - 8A0C9DE023180FE900DCD37A /* math_layout_elements.cpp in Sources */, - 8A0C9D7723180FE900DCD37A /* stylewrap.cpp in Sources */, - 8A0C9D6223180FE900DCD37A /* draw_common.cpp in Sources */, - 8A0C9D8523180FE900DCD37A /* stylehorizontalrel.cpp in Sources */, - 8A0C9DD623180FE900DCD37A /* anim_elements.cpp in Sources */, - 8A0C9D6423180FE900DCD37A /* style_map.cpp in Sources */, - 8A0C9DF023180FE900DCD37A /* table_xlsx.cpp in Sources */, - 8A0C9DAA23180FE900DCD37A /* punctuationwrap.cpp in Sources */, - 8A0C9DC923180FE900DCD37A /* drawfill.cpp in Sources */, - 8A0C9E0423180FE900DCD37A /* table_database_ranges.cpp in Sources */, - 8A0C9DB623180FE900DCD37A /* fontweight.cpp in Sources */, - 8A0C9DC823180FE900DCD37A /* noteclass.cpp in Sources */, - 8A0C9DA723180FE900DCD37A /* textdisplay.cpp in Sources */, - 8A0C9D5723180FE900DCD37A /* draw_shapes_xlsx.cpp in Sources */, - 8A0C9DFC23180FE900DCD37A /* math_elementaries.cpp in Sources */, - 8A0C9DBF23180FE900DCD37A /* charterrorcategory.cpp in Sources */, - 8A0C9D7423180FE900DCD37A /* scripttype.cpp in Sources */, - 8A0C9E0523180FE900DCD37A /* templates.cpp in Sources */, - 8A0C9DCA23180FE900DCD37A /* linemode.cpp in Sources */, - 8A0C9DE923180FE900DCD37A /* office_forms.cpp in Sources */, - 8A0C9D8123180FE900DCD37A /* pageusage.cpp in Sources */, - 8A0C9DA923180FE900DCD37A /* grandtotal.cpp in Sources */, - 8A0C9DFA23180FE900DCD37A /* skipelement.cpp in Sources */, - 8A0C9DF423180FE900DCD37A /* style_regions.cpp in Sources */, - 8A0C9D6623180FE900DCD37A /* svg_parser.cpp in Sources */, - 8A0C9DCB23180FE900DCD37A /* bool.cpp in Sources */, - 8A0C9D9623180FE900DCD37A /* membertype.cpp in Sources */, - 8A0C9DE123180FE900DCD37A /* math_limit_elements.cpp in Sources */, - 8A0C9E0223180FE900DCD37A /* style_graphic_properties.cpp in Sources */, - 8A0C9DC523180FE900DCD37A /* texttransform.cpp in Sources */, - 8A0C9DD723180FE900DCD37A /* documentcontext.cpp in Sources */, - 8A0C9D8623180FE900DCD37A /* percent.cpp in Sources */, - 8A0C9D7023180FE900DCD37A /* tablecentering.cpp in Sources */, - 8A0C9DB223180FE900DCD37A /* shadowtype.cpp in Sources */, - 8A0C9D8E23180FE900DCD37A /* presentationclass.cpp in Sources */, - 8A0C9DBB23180FE900DCD37A /* stylefamily.cpp in Sources */, - 8A0C9DB923180FE900DCD37A /* hatchstyle.cpp in Sources */, - 8A0C9D8B23180FE900DCD37A /* writingmode.cpp in Sources */, - 8A0C9DD323180FE900DCD37A /* style_paragraph_properties.cpp in Sources */, - 8A0C9DFB23180FE900DCD37A /* header_footer.cpp in Sources */, - 8A0C9DA623180FE900DCD37A /* style_ref.cpp in Sources */, - 8A0C9E0623180FE900DCD37A /* note.cpp in Sources */, - 8A0C9DC423180FE900DCD37A /* xlink.cpp in Sources */, - 8A0C9DD523180FE900DCD37A /* draw_frame_pptx.cpp in Sources */, - 8A0C9D7223180FE900DCD37A /* fontvariant.cpp in Sources */, - 8A0C9DD923180FE900DCD37A /* office_elements_create.cpp in Sources */, - 8A0C9D9423180FE900DCD37A /* fontsize.cpp in Sources */, - 8A0C9DC023180FE900DCD37A /* fillimagerefpoint.cpp in Sources */, - 8A0C9DA523180FE900DCD37A /* dropcaplength.cpp in Sources */, - 8A0C9E0123180FE900DCD37A /* ruby.cpp in Sources */, - 8A0C9DF623180FE900DCD37A /* draw_frame.cpp in Sources */, - 8A0C9D6E23180FE900DCD37A /* letterspacing.cpp in Sources */, - 8A0C9D8823180FE900DCD37A /* lengthorpercent.cpp in Sources */, - 8A0C9E0723180FE900DCD37A /* odf_content_xml.cpp in Sources */, - 8A0C9DE323180FE900DCD37A /* table_named_expressions.cpp in Sources */, - 8A0C9DA323180FE900DCD37A /* common_attlists.cpp in Sources */, - 8A0C9DA823180FE900DCD37A /* linestyle.cpp in Sources */, - 8A0C9DF723180FE900DCD37A /* table_pptx.cpp in Sources */, - 8A0C9D7323180FE900DCD37A /* tableorder.cpp in Sources */, - 8A0C9DB723180FE900DCD37A /* bibliography.cpp in Sources */, - 8A0C9D6A23180FE900DCD37A /* table_calculation_settings.cpp in Sources */, - 8A0C9D7923180FE900DCD37A /* length.cpp in Sources */, - 8A0C9DE223180FE900DCD37A /* abstract_xml.cpp in Sources */, - 8A0C9D8223180FE900DCD37A /* chartsymbol.cpp in Sources */, - 8A0C9DD223180FE900DCD37A /* math_token_elements.cpp in Sources */, - 8A0C9DB423180FE900DCD37A /* officevaluetype.cpp in Sources */, - 8A0C9DB123180FE900DCD37A /* linebreak.cpp in Sources */, - 8A0C9D6C23180FE900DCD37A /* textemphasize.cpp in Sources */, - 8A0C9DBA23180FE900DCD37A /* fontpitch.cpp in Sources */, - 8A0C9D9123180FE900DCD37A /* textalign.cpp in Sources */, - 8A0C9DCF23180FE900DCD37A /* targetframename.cpp in Sources */, - 8A0C9D7523180FE900DCD37A /* calcext_type.cpp in Sources */, - 8A0C9DDE23180FE900DCD37A /* draw_shapes_docx.cpp in Sources */, - 8A0C9D9323180FE900DCD37A /* tabletype.cpp in Sources */, - 8A0C9D9923180FE900DCD37A /* chartseriessource.cpp in Sources */, - 8A0C9D7D23180FE900DCD37A /* backgroundcolor.cpp in Sources */, - 8A0C9DAD23180FE900DCD37A /* chartregressiontype.cpp in Sources */, - 8A0C9D7F23180FE900DCD37A /* rotationalign.cpp in Sources */, - 8A0C9D6123180FE900DCD37A /* office_chart.cpp in Sources */, - 8A0C9D9E23180FE900DCD37A /* keeptogether.cpp in Sources */, - 8A0C9DAF23180FE900DCD37A /* tableorientation.cpp in Sources */, - 8A0C9DAE23180FE900DCD37A /* chartdatalabelnumber.cpp in Sources */, - 8A0C9DFF23180FE900DCD37A /* createandread.cpp in Sources */, - 8A0C9D7E23180FE900DCD37A /* clockvalue.cpp in Sources */, - 8A0C9D5923180FE900DCD37A /* style_table_properties.cpp in Sources */, - 8A0C9D8F23180FE900DCD37A /* mathvariant.cpp in Sources */, - 8A0C9DF923180FE900DCD37A /* office_body.cpp in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin XCBuildConfiguration section */ - 8A0C9BEF23180FD800DCD37A /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - CODE_SIGN_IDENTITY = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu11; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 10.0; - MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; - MTL_FAST_MATH = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - }; - name = Debug; - }; - 8A0C9BF023180FD800DCD37A /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - CODE_SIGN_IDENTITY = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu11; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 10.0; - MTL_ENABLE_DEBUG_INFO = NO; - MTL_FAST_MATH = YES; - SDKROOT = iphoneos; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - 8A0C9BF223180FD800DCD37A /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = 2WH24U26GJ; - GCC_PREPROCESSOR_DEFINITIONS = ( - UNICODE, - _UNICODE, - PPTX_DEF, - PPT_DEF, - ENABLE_PPT_TO_PPTX_CONVERT, - NODOCX, - FILTER_FLATE_DECODE_ENABLED, - CXIMAGE_DONT_DECLARE_TCHAR, - BUILD_CONFIG_FULL_VERSION, - DONT_WRITE_EMBEDDED_FONTS, - AVS_USE_CONVERT_PPTX_TOCUSTOM_VML, - unix, - MAC, - _IOS, - ); - HEADER_SEARCH_PATHS = ( - "$(inherited)", - /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, - /usr/include/libxml2, - "$(PROJECT_DIR)/../../../../DesktopEditor/freetype-2.5.2/include", - "$(PROJECT_DIR)/../../../../DesktopEditor/agg-2.4/include", - "$(PROJECT_DIR)/../../../../Common/3dParty/boost/boost_1_58_0", - "$(PROJECT_DIR)/../../../../ASCOfficeOdfFile/include", - "$(PROJECT_DIR)/../../../../ASCOfficeOdfFile/src/odf/datatypes", - ); - OTHER_CFLAGS = "-fembed-bitcode-marker"; - OTHER_LDFLAGS = "-ObjC"; - PRODUCT_NAME = "$(TARGET_NAME)"; - SKIP_INSTALL = YES; - TARGETED_DEVICE_FAMILY = 1; - VALID_ARCHS = "arm64 armv7 armv7s i386 x86_64"; - }; - name = Debug; - }; - 8A0C9BF323180FD800DCD37A /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = 2WH24U26GJ; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - UNICODE, - _UNICODE, - PPTX_DEF, - PPT_DEF, - ENABLE_PPT_TO_PPTX_CONVERT, - NODOCX, - FILTER_FLATE_DECODE_ENABLED, - CXIMAGE_DONT_DECLARE_TCHAR, - BUILD_CONFIG_FULL_VERSION, - DONT_WRITE_EMBEDDED_FONTS, - AVS_USE_CONVERT_PPTX_TOCUSTOM_VML, - unix, - MAC, - _IOS, - ); - HEADER_SEARCH_PATHS = ( - "$(inherited)", - /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, - /usr/include/libxml2, - "$(PROJECT_DIR)/../../../../DesktopEditor/freetype-2.5.2/include", - "$(PROJECT_DIR)/../../../../DesktopEditor/agg-2.4/include", - "$(PROJECT_DIR)/../../../../Common/3dParty/boost/boost_1_58_0", - "$(PROJECT_DIR)/../../../../ASCOfficeOdfFile/include", - "$(PROJECT_DIR)/../../../../ASCOfficeOdfFile/src/odf/datatypes", - ); - OTHER_CFLAGS = "-fembed-bitcode"; - OTHER_LDFLAGS = "-ObjC"; - PRODUCT_NAME = "$(TARGET_NAME)"; - SKIP_INSTALL = YES; - TARGETED_DEVICE_FAMILY = 1; - VALID_ARCHS = "arm64 armv7 armv7s i386 x86_64"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 8A0C9BE323180FD800DCD37A /* Build configuration list for PBXProject "OdfReadFormat" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 8A0C9BEF23180FD800DCD37A /* Debug */, - 8A0C9BF023180FD800DCD37A /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 8A0C9BF123180FD800DCD37A /* Build configuration list for PBXNativeTarget "OdfReadFormat" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 8A0C9BF223180FD800DCD37A /* Debug */, - 8A0C9BF323180FD800DCD37A /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 8A0C9BE023180FD800DCD37A /* Project object */; -} diff --git a/X2tConverter/build/Mac/OdfReadFormat/OdfReadFormat.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/X2tConverter/build/Mac/OdfReadFormat/OdfReadFormat.xcodeproj/project.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 7f84a1dcfc4..00000000000 --- a/X2tConverter/build/Mac/OdfReadFormat/OdfReadFormat.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/X2tConverter/build/Mac/OdfReadFormat/OdfReadFormat.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/X2tConverter/build/Mac/OdfReadFormat/OdfReadFormat.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist deleted file mode 100644 index 18d981003d6..00000000000 --- a/X2tConverter/build/Mac/OdfReadFormat/OdfReadFormat.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +++ /dev/null @@ -1,8 +0,0 @@ - - - - - IDEDidComputeMac32BitWarning - - - diff --git a/X2tConverter/build/Mac/OdfReadFormat/OdfReadFormat.xcodeproj/project.xcworkspace/xcuserdata/alexey.xcuserdatad/UserInterfaceState.xcuserstate b/X2tConverter/build/Mac/OdfReadFormat/OdfReadFormat.xcodeproj/project.xcworkspace/xcuserdata/alexey.xcuserdatad/UserInterfaceState.xcuserstate deleted file mode 100644 index e835491efaf..00000000000 Binary files a/X2tConverter/build/Mac/OdfReadFormat/OdfReadFormat.xcodeproj/project.xcworkspace/xcuserdata/alexey.xcuserdatad/UserInterfaceState.xcuserstate and /dev/null differ diff --git a/X2tConverter/build/Mac/OdfReadFormat/OdfReadFormat.xcodeproj/xcuserdata/alexey.xcuserdatad/xcschemes/xcschememanagement.plist b/X2tConverter/build/Mac/OdfReadFormat/OdfReadFormat.xcodeproj/xcuserdata/alexey.xcuserdatad/xcschemes/xcschememanagement.plist deleted file mode 100644 index ade12dbca32..00000000000 --- a/X2tConverter/build/Mac/OdfReadFormat/OdfReadFormat.xcodeproj/xcuserdata/alexey.xcuserdatad/xcschemes/xcschememanagement.plist +++ /dev/null @@ -1,14 +0,0 @@ - - - - - SchemeUserState - - OdfReadFormat.xcscheme_^#shared#^_ - - orderHint - 41 - - - - diff --git a/X2tConverter/build/Mac/OfficeOdfConverter/OfficeOdfConverter.xcodeproj/project.pbxproj b/X2tConverter/build/Mac/OfficeOdfConverter/OfficeOdfConverter.xcodeproj/project.pbxproj deleted file mode 100644 index d35bc586c9a..00000000000 --- a/X2tConverter/build/Mac/OfficeOdfConverter/OfficeOdfConverter.xcodeproj/project.pbxproj +++ /dev/null @@ -1,1115 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 50; - objects = { - -/* Begin PBXBuildFile section */ - 17513B092216E721008B45F7 /* OfficeOdfConverter.mm in Sources */ = {isa = PBXBuildFile; fileRef = 17513B082216E721008B45F7 /* OfficeOdfConverter.mm */; }; - 17513B0A2216E721008B45F7 /* OfficeOdfConverter.h in Headers */ = {isa = PBXBuildFile; fileRef = 17513B072216E721008B45F7 /* OfficeOdfConverter.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 17513E272216E8D1008B45F7 /* cextracttools.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513E252216E8D0008B45F7 /* cextracttools.cpp */; }; - 17513F182216EB49008B45F7 /* utils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513EC62216EB49008B45F7 /* utils.cpp */; }; - 17513F192216EB49008B45F7 /* Converter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513EC92216EB49008B45F7 /* Converter.cpp */; }; - 17513F1A2216EB49008B45F7 /* ConverterChart.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513ECA2216EB49008B45F7 /* ConverterChart.cpp */; }; - 17513F1B2216EB49008B45F7 /* XlsxConverter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513ECC2216EB49008B45F7 /* XlsxConverter.cpp */; }; - 17513F1C2216EB49008B45F7 /* DocxConverter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513ECE2216EB49008B45F7 /* DocxConverter.cpp */; }; - 17513F1D2216EB49008B45F7 /* PptxConverter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513ECF2216EB49008B45F7 /* PptxConverter.cpp */; }; - 17513F1E2216EB49008B45F7 /* ConvertVml.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513ED12216EB49008B45F7 /* ConvertVml.cpp */; }; - 17513F1F2216EB49008B45F7 /* ConvertDrawing.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 17513ED32216EB49008B45F7 /* ConvertDrawing.cpp */; }; - 8A8753C52227F45600117573 /* OfficeOdfConverter.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 17513B072216E721008B45F7 /* OfficeOdfConverter.h */; }; - 8A9873982270764C001F896F /* office_document.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A9872FA22707634001F896F /* office_document.cpp */; }; - 8A9873992270764C001F896F /* odf_style_context.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A9872FB22707634001F896F /* odf_style_context.h */; }; - 8A98739A2270764C001F896F /* draw_shapes.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A9872FC22707634001F896F /* draw_shapes.h */; }; - 8A98739B2270764C001F896F /* odp_page_state.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A9872FD22707634001F896F /* odp_page_state.cpp */; }; - 8A98739C2270764C001F896F /* office_text.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A9872FE22707634001F896F /* office_text.h */; }; - 8A98739D2270764C001F896F /* style_presentation.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A9872FF22707634001F896F /* style_presentation.h */; }; - 8A98739E2270764C001F896F /* odf_drawing_context.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A98730022707634001F896F /* odf_drawing_context.h */; }; - 8A98739F2270764C001F896F /* style_graphic_properties.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A98730122707634001F896F /* style_graphic_properties.h */; }; - 8A9873A02270764C001F896F /* odp_page_state.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A98730222707634001F896F /* odp_page_state.h */; }; - 8A9873A12270764C001F896F /* draw_frame.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A98730322707634001F896F /* draw_frame.cpp */; }; - 8A9873A22270764C001F896F /* office_elements_create.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A98730422707634001F896F /* office_elements_create.cpp */; }; - 8A9873A32270764C001F896F /* odf_lists_styles_context.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A98730522707634001F896F /* odf_lists_styles_context.cpp */; }; - 8A9873A42270764C001F896F /* abstract_xml.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A98730622707634001F896F /* abstract_xml.cpp */; }; - 8A9873A52270764C001F896F /* object_package.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A98730722707635001F896F /* object_package.cpp */; }; - 8A9873A62270764C001F896F /* number_style.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A98730822707635001F896F /* number_style.cpp */; }; - 8A9873A72270764C001F896F /* office_annotation.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A98730922707635001F896F /* office_annotation.h */; }; - 8A9873A82270764C001F896F /* odf_settings_context.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A98730A22707635001F896F /* odf_settings_context.h */; }; - 8A9873A92270764C001F896F /* draw_base.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A98730B22707635001F896F /* draw_base.cpp */; }; - 8A9873AA2270764C001F896F /* odf_drawing_context.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A98730C22707635001F896F /* odf_drawing_context.cpp */; }; - 8A9873AB2270764C001F896F /* odt_conversion_context.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A98730D22707635001F896F /* odt_conversion_context.cpp */; }; - 8A9873AC2270764C001F896F /* office_event_listeners.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A98730E22707636001F896F /* office_event_listeners.cpp */; }; - 8A9873AD2270764C001F896F /* ods_conversion_context.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A98730F22707636001F896F /* ods_conversion_context.cpp */; }; - 8A9873AE2270764C001F896F /* table_database_ranges.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A98731022707636001F896F /* table_database_ranges.cpp */; }; - 8A9873AF2270764C001F896F /* oox_shapePrimitives.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A98731222707636001F896F /* oox_shapePrimitives.h */; }; - 8A9873B02270764C001F896F /* oox_shapeBents.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A98731322707636001F896F /* oox_shapeBents.h */; }; - 8A9873B12270764C001F896F /* oox_shapeConnectors.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A98731422707636001F896F /* oox_shapeConnectors.h */; }; - 8A9873B22270764C001F896F /* oox_shapeCallouts.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A98731522707636001F896F /* oox_shapeCallouts.h */; }; - 8A9873B32270764C001F896F /* oox_shapeCharts.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A98731622707636001F896F /* oox_shapeCharts.h */; }; - 8A9873B42270764C001F896F /* oox_shapeArrows.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A98731722707636001F896F /* oox_shapeArrows.h */; }; - 8A9873B52270764C001F896F /* oox_shapeWordArt.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A98731822707636001F896F /* oox_shapeWordArt.h */; }; - 8A9873B62270764C001F896F /* oox_shapeCurvedArrows.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A98731922707636001F896F /* oox_shapeCurvedArrows.h */; }; - 8A9873B72270764C001F896F /* oox_shapeStars.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A98731A22707636001F896F /* oox_shapeStars.h */; }; - 8A9873B82270764C001F896F /* oox_shapeActionButtons.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A98731B22707636001F896F /* oox_shapeActionButtons.h */; }; - 8A9873B92270764C001F896F /* oox_shapeCustoms.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A98731C22707636001F896F /* oox_shapeCustoms.h */; }; - 8A9873BA2270764C001F896F /* oox_shapeSnipRoundRects.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A98731D22707636001F896F /* oox_shapeSnipRoundRects.h */; }; - 8A9873BB2270764C001F896F /* odf_shape_mapping.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A98731E22707636001F896F /* odf_shape_mapping.h */; }; - 8A9873BC2270764C001F896F /* oox_shapeCurvedConnectors.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A98731F22707636001F896F /* oox_shapeCurvedConnectors.h */; }; - 8A9873BD2270764C001F896F /* oox_shapeMaths.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A98732022707636001F896F /* oox_shapeMaths.h */; }; - 8A9873BE2270764C001F896F /* oox_shapeRibbons.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A98732122707636001F896F /* oox_shapeRibbons.h */; }; - 8A9873BF2270764C001F896F /* oox_shapeAccentCallouts.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A98732222707636001F896F /* oox_shapeAccentCallouts.h */; }; - 8A9873C02270764C001F896F /* odt_conversion_context.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A98732322707636001F896F /* odt_conversion_context.h */; }; - 8A9873C12270764C001F896F /* odf_comment_context.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A98732422707636001F896F /* odf_comment_context.h */; }; - 8A9873C22270764C001F896F /* odf_page_layout_state.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A98732522707636001F896F /* odf_page_layout_state.h */; }; - 8A9873C32270764C001F896F /* anim_elements.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A98732622707637001F896F /* anim_elements.h */; }; - 8A9873C42270764C001F896F /* odf_page_layout_context.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A98732722707637001F896F /* odf_page_layout_context.h */; }; - 8A9873C52270764C001F896F /* office_elements.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A98732822707637001F896F /* office_elements.h */; }; - 8A9873C62270764C001F896F /* odp_slide_context.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A98732922707637001F896F /* odp_slide_context.h */; }; - 8A9873C72270764C001F896F /* styles_lite_container.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A98732A22707637001F896F /* styles_lite_container.cpp */; }; - 8A9873C82270764C001F896F /* ods_table_context.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A98732B22707637001F896F /* ods_table_context.h */; }; - 8A9873C92270764C001F896F /* header_footer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A98732C22707637001F896F /* header_footer.cpp */; }; - 8A9873CA2270764C001F896F /* style_map.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A98732D22707637001F896F /* style_map.h */; }; - 8A9873CB2270764C001F896F /* style_paragraph_properties.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A98732E22707637001F896F /* style_paragraph_properties.cpp */; }; - 8A9873CC2270764C001F896F /* logging.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A98732F22707638001F896F /* logging.cpp */; }; - 8A9873CD2270764C001F896F /* office_text.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A98733022707638001F896F /* office_text.cpp */; }; - 8A9873CE2270764C001F896F /* odf_table_styles_context.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A98733122707638001F896F /* odf_table_styles_context.h */; }; - 8A9873CF2270764C001F896F /* office_forms.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A98733222707638001F896F /* office_forms.h */; }; - 8A9873D02270764C001F896F /* odf_text_context.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A98733322707638001F896F /* odf_text_context.h */; }; - 8A9873D12270764C001F896F /* style_text_properties.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A98733422707638001F896F /* style_text_properties.cpp */; }; - 8A9873D22270764C001F896F /* style_paragraph_properties.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A98733522707638001F896F /* style_paragraph_properties.h */; }; - 8A9873D32270764C001F896F /* list.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A98733622707639001F896F /* list.cpp */; }; - 8A9873D42270764C001F896F /* mediaitems_utils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A98733722707639001F896F /* mediaitems_utils.cpp */; }; - 8A9873D52270764C001F896F /* mediaitems.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A98733822707639001F896F /* mediaitems.h */; }; - 8A9873D62270764C001F896F /* ods_table_state.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A98733922707639001F896F /* ods_table_state.cpp */; }; - 8A9873D72270764C001F896F /* styles_lite_container.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A98733A22707639001F896F /* styles_lite_container.h */; }; - 8A9873D82270764C001F896F /* odf_page_layout_context.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A98733B22707639001F896F /* odf_page_layout_context.cpp */; }; - 8A9873D92270764C001F896F /* odf_number_styles_context.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A98733C22707639001F896F /* odf_number_styles_context.h */; }; - 8A9873DA2270764C001F896F /* style_graphic_properties.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A98733D22707639001F896F /* style_graphic_properties.cpp */; }; - 8A9873DB2270764C001F896F /* style_chart_properties.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A98733E22707639001F896F /* style_chart_properties.cpp */; }; - 8A9873DC2270764C001F896F /* mediaitems_utils.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A98733F2270763A001F896F /* mediaitems_utils.h */; }; - 8A9873DD2270764C001F896F /* object_package.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A9873402270763A001F896F /* object_package.h */; }; - 8A9873DE2270764C001F896F /* odf_rels.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A9873412270763A001F896F /* odf_rels.h */; }; - 8A9873DF2270764C001F896F /* odf_page_layout_state.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A9873422270763A001F896F /* odf_page_layout_state.cpp */; }; - 8A9873E02270764C001F896F /* table.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A9873432270763A001F896F /* table.h */; }; - 8A9873E12270764C001F896F /* calcext_elements.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A9873442270763B001F896F /* calcext_elements.h */; }; - 8A9873E22270764C001F896F /* odf_comment_context.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A9873452270763B001F896F /* odf_comment_context.cpp */; }; - 8A9873E32270764C001F896F /* office_body.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A9873462270763B001F896F /* office_body.cpp */; }; - 8A9873E42270764C001F896F /* odf_style_context.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A9873472270763B001F896F /* odf_style_context.cpp */; }; - 8A9873E52270764C001F896F /* oox_shape_defines.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A9873482270763B001F896F /* oox_shape_defines.cpp */; }; - 8A9873E62270764C001F896F /* style_page_layout_properties.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A9873492270763C001F896F /* style_page_layout_properties.cpp */; }; - 8A9873E72270764C001F896F /* visitor.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A98734A2270763C001F896F /* visitor.h */; }; - 8A9873E82270764C001F896F /* style_chart_properties.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A98734B2270763C001F896F /* style_chart_properties.h */; }; - 8A9873E92270764C001F896F /* odf_style_state.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A98734C2270763C001F896F /* odf_style_state.cpp */; }; - 8A9873EA2270764C001F896F /* header_footer.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A98734D2270763C001F896F /* header_footer.h */; }; - 8A9873EB2270764C001F896F /* odf_controls_context.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A98734E2270763D001F896F /* odf_controls_context.h */; }; - 8A9873EC2270764C001F896F /* calcext_elements.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A98734F2270763D001F896F /* calcext_elements.cpp */; }; - 8A9873ED2270764C001F896F /* oox_shape_defines.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A9873502270763D001F896F /* oox_shape_defines.h */; }; - 8A9873EE2270764C001F896F /* styles_list.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A9873512270763D001F896F /* styles_list.h */; }; - 8A9873EF2270764C001F896F /* ods_conversion_context.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A9873522270763E001F896F /* ods_conversion_context.h */; }; - 8A9873F02270764C001F896F /* table_named_expressions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A9873532270763E001F896F /* table_named_expressions.cpp */; }; - 8A9873F12270764C001F896F /* paragraph_elements.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A9873542270763E001F896F /* paragraph_elements.h */; }; - 8A9873F22270764C001F896F /* odf_text_context.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A9873552270763E001F896F /* odf_text_context.cpp */; }; - 8A9873F32270764C001F896F /* style_section_properties.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A9873562270763E001F896F /* style_section_properties.cpp */; }; - 8A9873F42270764C001F896F /* odf_chart_context.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A9873572270763F001F896F /* odf_chart_context.cpp */; }; - 8A9873F52270764C001F896F /* style_section_properties.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A9873582270763F001F896F /* style_section_properties.h */; }; - 8A9873F62270764C001F896F /* odf_settings_context.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A9873592270763F001F896F /* odf_settings_context.cpp */; }; - 8A9873F72270764C001F896F /* office_chart.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A98735A2270763F001F896F /* office_chart.h */; }; - 8A9873F82270764C001F896F /* ods_table_context.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A98735B2270763F001F896F /* ods_table_context.cpp */; }; - 8A9873F92270764C001F896F /* office_scripts.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A98735C2270763F001F896F /* office_scripts.cpp */; }; - 8A9873FA2270764C001F896F /* office_spreadsheet.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A98735D22707640001F896F /* office_spreadsheet.h */; }; - 8A9873FB2270764C001F896F /* styles_list.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A98735E22707640001F896F /* styles_list.cpp */; }; - 8A9873FC2270764C001F896F /* style_table_properties.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A98735F22707640001F896F /* style_table_properties.h */; }; - 8A9873FD2270764C001F896F /* draw_frame.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A98736022707640001F896F /* draw_frame.h */; }; - 8A9873FE2270764C001F896F /* odp_slide_context.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A98736122707640001F896F /* odp_slide_context.cpp */; }; - 8A9873FF2270764C001F896F /* office_body.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A98736222707641001F896F /* office_body.h */; }; - 8A9874002270764C001F896F /* text_elements.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A98736322707641001F896F /* text_elements.cpp */; }; - 8A9874012270764C001F896F /* odf_table_styles_context.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A98736422707641001F896F /* odf_table_styles_context.cpp */; }; - 8A9874022270764C001F896F /* draw_base.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A98736522707641001F896F /* draw_base.h */; }; - 8A9874032270764C001F896F /* anim_elements.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A98736622707642001F896F /* anim_elements.cpp */; }; - 8A9874042270764C001F896F /* odf_rels.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A98736722707642001F896F /* odf_rels.cpp */; }; - 8A9874052270764C001F896F /* odf_notes_context.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A98736822707642001F896F /* odf_notes_context.cpp */; }; - 8A9874062270764C001F896F /* styles.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A98736922707642001F896F /* styles.cpp */; }; - 8A9874072270764C001F896F /* table.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A98736A22707642001F896F /* table.cpp */; }; - 8A9874082270764D001F896F /* mediaitems.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A98736B22707643001F896F /* mediaitems.cpp */; }; - 8A9874092270764D001F896F /* office_event_listeners.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A98736C22707643001F896F /* office_event_listeners.h */; }; - 8A98740A2270764D001F896F /* office_chart.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A98736D22707643001F896F /* office_chart.cpp */; }; - 8A98740B2270764D001F896F /* office_document.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A98736E22707643001F896F /* office_document.h */; }; - 8A98740C2270764D001F896F /* styles.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A98736F22707644001F896F /* styles.h */; }; - 8A98740D2270764D001F896F /* list.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A98737022707644001F896F /* list.h */; }; - 8A98740E2270764D001F896F /* office_spreadsheet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A98737122707644001F896F /* office_spreadsheet.cpp */; }; - 8A98740F2270764D001F896F /* office_annotation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A98737222707644001F896F /* office_annotation.cpp */; }; - 8A9874102270764D001F896F /* svg_creator.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A98737322707644001F896F /* svg_creator.h */; }; - 8A9874112270764D001F896F /* odf_style_state.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A98737422707645001F896F /* odf_style_state.h */; }; - 8A9874122270764D001F896F /* abstract_xml.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A98737522707645001F896F /* abstract_xml.h */; }; - 8A9874132270764D001F896F /* odf_table_context.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A98737622707645001F896F /* odf_table_context.h */; }; - 8A9874142270764D001F896F /* office_elements_create.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A98737722707645001F896F /* office_elements_create.h */; }; - 8A9874152270764D001F896F /* odf_number_styles_context.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A98737822707645001F896F /* odf_number_styles_context.cpp */; }; - 8A9874162270764D001F896F /* office_scripts.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A98737922707646001F896F /* office_scripts.h */; }; - 8A9874172270764D001F896F /* style_page_layout_properties.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A98737A22707646001F896F /* style_page_layout_properties.h */; }; - 8A9874182270764D001F896F /* number_style.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A98737B22707646001F896F /* number_style.h */; }; - 8A9874192270764D001F896F /* office_settings.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A98737C22707646001F896F /* office_settings.cpp */; }; - 8A98741A2270764D001F896F /* office_elements_type.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A98737D22707646001F896F /* office_elements_type.h */; }; - 8A98741B2270764D001F896F /* odf_lists_styles_context.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A98737E22707647001F896F /* odf_lists_styles_context.h */; }; - 8A98741C2270764D001F896F /* odf_conversion_context.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A98737F22707647001F896F /* odf_conversion_context.h */; }; - 8A98741D2270764D001F896F /* paragraph_elements.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A98738022707647001F896F /* paragraph_elements.cpp */; }; - 8A98741E2270764D001F896F /* odp_conversion_context.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A98738122707647001F896F /* odp_conversion_context.cpp */; }; - 8A98741F2270764D001F896F /* style_text_properties.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A98738222707647001F896F /* style_text_properties.h */; }; - 8A9874202270764D001F896F /* style_table_properties.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A98738322707648001F896F /* style_table_properties.cpp */; }; - 8A9874212270764D001F896F /* ods_table_state.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A98738422707648001F896F /* ods_table_state.h */; }; - 8A9874222270764D001F896F /* odf_chart_context.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A98738522707648001F896F /* odf_chart_context.h */; }; - 8A9874232270764D001F896F /* draw_page.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A98738622707648001F896F /* draw_page.h */; }; - 8A9874242270764D001F896F /* svg_creator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A98738722707649001F896F /* svg_creator.cpp */; }; - 8A9874252270764D001F896F /* odf_conversion_context.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A98738822707649001F896F /* odf_conversion_context.cpp */; }; - 8A9874262270764D001F896F /* text_elements.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A98738922707649001F896F /* text_elements.h */; }; - 8A9874272270764D001F896F /* odf_notes_context.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A98738A22707649001F896F /* odf_notes_context.h */; }; - 8A9874282270764D001F896F /* office_settings.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A98738B22707649001F896F /* office_settings.h */; }; - 8A9874292270764D001F896F /* style_map.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A98738C2270764A001F896F /* style_map.cpp */; }; - 8A98742A2270764D001F896F /* table_named_expressions.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A98738D2270764A001F896F /* table_named_expressions.h */; }; - 8A98742B2270764D001F896F /* draw_page.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A98738E2270764A001F896F /* draw_page.cpp */; }; - 8A98742C2270764D001F896F /* odp_conversion_context.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A98738F2270764A001F896F /* odp_conversion_context.h */; }; - 8A98742D2270764D001F896F /* table_database_ranges.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A9873902270764A001F896F /* table_database_ranges.h */; }; - 8A98742E2270764D001F896F /* office_presentation.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A9873912270764B001F896F /* office_presentation.h */; }; - 8A98742F2270764D001F896F /* odf_table_context.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A9873922270764B001F896F /* odf_table_context.cpp */; }; - 8A9874302270764D001F896F /* draw_shapes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A9873932270764B001F896F /* draw_shapes.cpp */; }; - 8A9874312270764D001F896F /* office_forms.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A9873942270764B001F896F /* office_forms.cpp */; }; - 8A9874322270764D001F896F /* style_presentation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A9873952270764B001F896F /* style_presentation.cpp */; }; - 8A9874332270764D001F896F /* odf_controls_context.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A9873962270764C001F896F /* odf_controls_context.cpp */; }; - 8A9874342270764D001F896F /* office_presentation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A9873972270764C001F896F /* office_presentation.cpp */; }; - 8A9CF4D9238833B500DBCE6B /* table_data_pilot_tables.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A9CF4D8238833B500DBCE6B /* table_data_pilot_tables.cpp */; }; - 8A9CF4DB238833C900DBCE6B /* table_data_pilot_tables.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A9CF4DA238833C900DBCE6B /* table_data_pilot_tables.h */; }; - 8A9CF4E62388373000DBCE6B /* File.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A9CF4E52388373000DBCE6B /* File.h */; }; - 8A9CF4E82388373C00DBCE6B /* File.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A9CF4E72388373C00DBCE6B /* File.cpp */; }; - 8A9CF4EA2388374500DBCE6B /* File_ios.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8A9CF4E92388374500DBCE6B /* File_ios.mm */; }; - 8A9CF4EE2388391500DBCE6B /* styleprint.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A9CF4ED2388391400DBCE6B /* styleprint.h */; }; - 8A9CF4F02388392C00DBCE6B /* styleprint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A9CF4EF2388392C00DBCE6B /* styleprint.cpp */; }; -/* End PBXBuildFile section */ - -/* Begin PBXCopyFilesBuildPhase section */ - 17513B022216E721008B45F7 /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = "include/$(PRODUCT_NAME)"; - dstSubfolderSpec = 16; - files = ( - 8A8753C52227F45600117573 /* OfficeOdfConverter.h in CopyFiles */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXCopyFilesBuildPhase section */ - -/* Begin PBXFileReference section */ - 17513B042216E721008B45F7 /* libOfficeOdfConverter.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libOfficeOdfConverter.a; sourceTree = BUILT_PRODUCTS_DIR; }; - 17513B072216E721008B45F7 /* OfficeOdfConverter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OfficeOdfConverter.h; sourceTree = ""; }; - 17513B082216E721008B45F7 /* OfficeOdfConverter.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = OfficeOdfConverter.mm; sourceTree = ""; }; - 17513E252216E8D0008B45F7 /* cextracttools.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = cextracttools.cpp; path = ../../../../src/cextracttools.cpp; sourceTree = ""; }; - 17513E262216E8D1008B45F7 /* cextracttools.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = cextracttools.h; path = ../../../../src/cextracttools.h; sourceTree = ""; }; - 17513E292216EB48008B45F7 /* progressCallback.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = progressCallback.h; path = ../../../../../ASCOfficeOdfFileW/source/progressCallback.h; sourceTree = ""; }; - 17513E2A2216EB48008B45F7 /* utils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = utils.h; path = ../../../../../ASCOfficeOdfFileW/source/utils.h; sourceTree = ""; }; - 17513EC62216EB49008B45F7 /* utils.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = utils.cpp; path = ../../../../../ASCOfficeOdfFileW/source/utils.cpp; sourceTree = ""; }; - 17513EC82216EB49008B45F7 /* DocxConverter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DocxConverter.h; sourceTree = ""; }; - 17513EC92216EB49008B45F7 /* Converter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Converter.cpp; sourceTree = ""; }; - 17513ECA2216EB49008B45F7 /* ConverterChart.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ConverterChart.cpp; sourceTree = ""; }; - 17513ECB2216EB49008B45F7 /* Converter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Converter.h; sourceTree = ""; }; - 17513ECC2216EB49008B45F7 /* XlsxConverter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = XlsxConverter.cpp; sourceTree = ""; }; - 17513ECD2216EB49008B45F7 /* PptxConverter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PptxConverter.h; sourceTree = ""; }; - 17513ECE2216EB49008B45F7 /* DocxConverter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DocxConverter.cpp; sourceTree = ""; }; - 17513ECF2216EB49008B45F7 /* PptxConverter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PptxConverter.cpp; sourceTree = ""; }; - 17513ED02216EB49008B45F7 /* VmlShapeTypes2Oox.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VmlShapeTypes2Oox.h; sourceTree = ""; }; - 17513ED12216EB49008B45F7 /* ConvertVml.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ConvertVml.cpp; sourceTree = ""; }; - 17513ED22216EB49008B45F7 /* Oox2OdfConverter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Oox2OdfConverter.h; sourceTree = ""; }; - 17513ED32216EB49008B45F7 /* ConvertDrawing.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ConvertDrawing.cpp; sourceTree = ""; }; - 17513ED42216EB49008B45F7 /* XlsxConverter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XlsxConverter.h; sourceTree = ""; }; - 8A9872FA22707634001F896F /* office_document.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = office_document.cpp; sourceTree = ""; }; - 8A9872FB22707634001F896F /* odf_style_context.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = odf_style_context.h; sourceTree = ""; }; - 8A9872FC22707634001F896F /* draw_shapes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = draw_shapes.h; sourceTree = ""; }; - 8A9872FD22707634001F896F /* odp_page_state.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = odp_page_state.cpp; sourceTree = ""; }; - 8A9872FE22707634001F896F /* office_text.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = office_text.h; sourceTree = ""; }; - 8A9872FF22707634001F896F /* style_presentation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = style_presentation.h; sourceTree = ""; }; - 8A98730022707634001F896F /* odf_drawing_context.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = odf_drawing_context.h; sourceTree = ""; }; - 8A98730122707634001F896F /* style_graphic_properties.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = style_graphic_properties.h; sourceTree = ""; }; - 8A98730222707634001F896F /* odp_page_state.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = odp_page_state.h; sourceTree = ""; }; - 8A98730322707634001F896F /* draw_frame.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = draw_frame.cpp; sourceTree = ""; }; - 8A98730422707634001F896F /* office_elements_create.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = office_elements_create.cpp; sourceTree = ""; }; - 8A98730522707634001F896F /* odf_lists_styles_context.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = odf_lists_styles_context.cpp; sourceTree = ""; }; - 8A98730622707634001F896F /* abstract_xml.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = abstract_xml.cpp; sourceTree = ""; }; - 8A98730722707635001F896F /* object_package.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = object_package.cpp; sourceTree = ""; }; - 8A98730822707635001F896F /* number_style.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = number_style.cpp; sourceTree = ""; }; - 8A98730922707635001F896F /* office_annotation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = office_annotation.h; sourceTree = ""; }; - 8A98730A22707635001F896F /* odf_settings_context.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = odf_settings_context.h; sourceTree = ""; }; - 8A98730B22707635001F896F /* draw_base.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = draw_base.cpp; sourceTree = ""; }; - 8A98730C22707635001F896F /* odf_drawing_context.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = odf_drawing_context.cpp; sourceTree = ""; }; - 8A98730D22707635001F896F /* odt_conversion_context.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = odt_conversion_context.cpp; sourceTree = ""; }; - 8A98730E22707636001F896F /* office_event_listeners.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = office_event_listeners.cpp; sourceTree = ""; }; - 8A98730F22707636001F896F /* ods_conversion_context.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ods_conversion_context.cpp; sourceTree = ""; }; - 8A98731022707636001F896F /* table_database_ranges.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = table_database_ranges.cpp; sourceTree = ""; }; - 8A98731222707636001F896F /* oox_shapePrimitives.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = oox_shapePrimitives.h; sourceTree = ""; }; - 8A98731322707636001F896F /* oox_shapeBents.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = oox_shapeBents.h; sourceTree = ""; }; - 8A98731422707636001F896F /* oox_shapeConnectors.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = oox_shapeConnectors.h; sourceTree = ""; }; - 8A98731522707636001F896F /* oox_shapeCallouts.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = oox_shapeCallouts.h; sourceTree = ""; }; - 8A98731622707636001F896F /* oox_shapeCharts.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = oox_shapeCharts.h; sourceTree = ""; }; - 8A98731722707636001F896F /* oox_shapeArrows.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = oox_shapeArrows.h; sourceTree = ""; }; - 8A98731822707636001F896F /* oox_shapeWordArt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = oox_shapeWordArt.h; sourceTree = ""; }; - 8A98731922707636001F896F /* oox_shapeCurvedArrows.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = oox_shapeCurvedArrows.h; sourceTree = ""; }; - 8A98731A22707636001F896F /* oox_shapeStars.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = oox_shapeStars.h; sourceTree = ""; }; - 8A98731B22707636001F896F /* oox_shapeActionButtons.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = oox_shapeActionButtons.h; sourceTree = ""; }; - 8A98731C22707636001F896F /* oox_shapeCustoms.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = oox_shapeCustoms.h; sourceTree = ""; }; - 8A98731D22707636001F896F /* oox_shapeSnipRoundRects.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = oox_shapeSnipRoundRects.h; sourceTree = ""; }; - 8A98731E22707636001F896F /* odf_shape_mapping.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = odf_shape_mapping.h; sourceTree = ""; }; - 8A98731F22707636001F896F /* oox_shapeCurvedConnectors.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = oox_shapeCurvedConnectors.h; sourceTree = ""; }; - 8A98732022707636001F896F /* oox_shapeMaths.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = oox_shapeMaths.h; sourceTree = ""; }; - 8A98732122707636001F896F /* oox_shapeRibbons.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = oox_shapeRibbons.h; sourceTree = ""; }; - 8A98732222707636001F896F /* oox_shapeAccentCallouts.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = oox_shapeAccentCallouts.h; sourceTree = ""; }; - 8A98732322707636001F896F /* odt_conversion_context.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = odt_conversion_context.h; sourceTree = ""; }; - 8A98732422707636001F896F /* odf_comment_context.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = odf_comment_context.h; sourceTree = ""; }; - 8A98732522707636001F896F /* odf_page_layout_state.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = odf_page_layout_state.h; sourceTree = ""; }; - 8A98732622707637001F896F /* anim_elements.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = anim_elements.h; sourceTree = ""; }; - 8A98732722707637001F896F /* odf_page_layout_context.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = odf_page_layout_context.h; sourceTree = ""; }; - 8A98732822707637001F896F /* office_elements.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = office_elements.h; sourceTree = ""; }; - 8A98732922707637001F896F /* odp_slide_context.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = odp_slide_context.h; sourceTree = ""; }; - 8A98732A22707637001F896F /* styles_lite_container.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = styles_lite_container.cpp; sourceTree = ""; }; - 8A98732B22707637001F896F /* ods_table_context.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ods_table_context.h; sourceTree = ""; }; - 8A98732C22707637001F896F /* header_footer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = header_footer.cpp; sourceTree = ""; }; - 8A98732D22707637001F896F /* style_map.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = style_map.h; sourceTree = ""; }; - 8A98732E22707637001F896F /* style_paragraph_properties.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = style_paragraph_properties.cpp; sourceTree = ""; }; - 8A98732F22707638001F896F /* logging.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = logging.cpp; sourceTree = ""; }; - 8A98733022707638001F896F /* office_text.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = office_text.cpp; sourceTree = ""; }; - 8A98733122707638001F896F /* odf_table_styles_context.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = odf_table_styles_context.h; sourceTree = ""; }; - 8A98733222707638001F896F /* office_forms.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = office_forms.h; sourceTree = ""; }; - 8A98733322707638001F896F /* odf_text_context.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = odf_text_context.h; sourceTree = ""; }; - 8A98733422707638001F896F /* style_text_properties.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = style_text_properties.cpp; sourceTree = ""; }; - 8A98733522707638001F896F /* style_paragraph_properties.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = style_paragraph_properties.h; sourceTree = ""; }; - 8A98733622707639001F896F /* list.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = list.cpp; sourceTree = ""; }; - 8A98733722707639001F896F /* mediaitems_utils.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = mediaitems_utils.cpp; sourceTree = ""; }; - 8A98733822707639001F896F /* mediaitems.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mediaitems.h; sourceTree = ""; }; - 8A98733922707639001F896F /* ods_table_state.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ods_table_state.cpp; sourceTree = ""; }; - 8A98733A22707639001F896F /* styles_lite_container.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = styles_lite_container.h; sourceTree = ""; }; - 8A98733B22707639001F896F /* odf_page_layout_context.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = odf_page_layout_context.cpp; sourceTree = ""; }; - 8A98733C22707639001F896F /* odf_number_styles_context.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = odf_number_styles_context.h; sourceTree = ""; }; - 8A98733D22707639001F896F /* style_graphic_properties.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = style_graphic_properties.cpp; sourceTree = ""; }; - 8A98733E22707639001F896F /* style_chart_properties.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = style_chart_properties.cpp; sourceTree = ""; }; - 8A98733F2270763A001F896F /* mediaitems_utils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mediaitems_utils.h; sourceTree = ""; }; - 8A9873402270763A001F896F /* object_package.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = object_package.h; sourceTree = ""; }; - 8A9873412270763A001F896F /* odf_rels.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = odf_rels.h; sourceTree = ""; }; - 8A9873422270763A001F896F /* odf_page_layout_state.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = odf_page_layout_state.cpp; sourceTree = ""; }; - 8A9873432270763A001F896F /* table.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = table.h; sourceTree = ""; }; - 8A9873442270763B001F896F /* calcext_elements.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = calcext_elements.h; sourceTree = ""; }; - 8A9873452270763B001F896F /* odf_comment_context.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = odf_comment_context.cpp; sourceTree = ""; }; - 8A9873462270763B001F896F /* office_body.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = office_body.cpp; sourceTree = ""; }; - 8A9873472270763B001F896F /* odf_style_context.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = odf_style_context.cpp; sourceTree = ""; }; - 8A9873482270763B001F896F /* oox_shape_defines.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = oox_shape_defines.cpp; sourceTree = ""; }; - 8A9873492270763C001F896F /* style_page_layout_properties.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = style_page_layout_properties.cpp; sourceTree = ""; }; - 8A98734A2270763C001F896F /* visitor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = visitor.h; sourceTree = ""; }; - 8A98734B2270763C001F896F /* style_chart_properties.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = style_chart_properties.h; sourceTree = ""; }; - 8A98734C2270763C001F896F /* odf_style_state.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = odf_style_state.cpp; sourceTree = ""; }; - 8A98734D2270763C001F896F /* header_footer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = header_footer.h; sourceTree = ""; }; - 8A98734E2270763D001F896F /* odf_controls_context.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = odf_controls_context.h; sourceTree = ""; }; - 8A98734F2270763D001F896F /* calcext_elements.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = calcext_elements.cpp; sourceTree = ""; }; - 8A9873502270763D001F896F /* oox_shape_defines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = oox_shape_defines.h; sourceTree = ""; }; - 8A9873512270763D001F896F /* styles_list.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = styles_list.h; sourceTree = ""; }; - 8A9873522270763E001F896F /* ods_conversion_context.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ods_conversion_context.h; sourceTree = ""; }; - 8A9873532270763E001F896F /* table_named_expressions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = table_named_expressions.cpp; sourceTree = ""; }; - 8A9873542270763E001F896F /* paragraph_elements.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = paragraph_elements.h; sourceTree = ""; }; - 8A9873552270763E001F896F /* odf_text_context.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = odf_text_context.cpp; sourceTree = ""; }; - 8A9873562270763E001F896F /* style_section_properties.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = style_section_properties.cpp; sourceTree = ""; }; - 8A9873572270763F001F896F /* odf_chart_context.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = odf_chart_context.cpp; sourceTree = ""; }; - 8A9873582270763F001F896F /* style_section_properties.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = style_section_properties.h; sourceTree = ""; }; - 8A9873592270763F001F896F /* odf_settings_context.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = odf_settings_context.cpp; sourceTree = ""; }; - 8A98735A2270763F001F896F /* office_chart.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = office_chart.h; sourceTree = ""; }; - 8A98735B2270763F001F896F /* ods_table_context.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ods_table_context.cpp; sourceTree = ""; }; - 8A98735C2270763F001F896F /* office_scripts.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = office_scripts.cpp; sourceTree = ""; }; - 8A98735D22707640001F896F /* office_spreadsheet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = office_spreadsheet.h; sourceTree = ""; }; - 8A98735E22707640001F896F /* styles_list.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = styles_list.cpp; sourceTree = ""; }; - 8A98735F22707640001F896F /* style_table_properties.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = style_table_properties.h; sourceTree = ""; }; - 8A98736022707640001F896F /* draw_frame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = draw_frame.h; sourceTree = ""; }; - 8A98736122707640001F896F /* odp_slide_context.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = odp_slide_context.cpp; sourceTree = ""; }; - 8A98736222707641001F896F /* office_body.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = office_body.h; sourceTree = ""; }; - 8A98736322707641001F896F /* text_elements.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = text_elements.cpp; sourceTree = ""; }; - 8A98736422707641001F896F /* odf_table_styles_context.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = odf_table_styles_context.cpp; sourceTree = ""; }; - 8A98736522707641001F896F /* draw_base.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = draw_base.h; sourceTree = ""; }; - 8A98736622707642001F896F /* anim_elements.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = anim_elements.cpp; sourceTree = ""; }; - 8A98736722707642001F896F /* odf_rels.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = odf_rels.cpp; sourceTree = ""; }; - 8A98736822707642001F896F /* odf_notes_context.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = odf_notes_context.cpp; sourceTree = ""; }; - 8A98736922707642001F896F /* styles.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = styles.cpp; sourceTree = ""; }; - 8A98736A22707642001F896F /* table.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = table.cpp; sourceTree = ""; }; - 8A98736B22707643001F896F /* mediaitems.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = mediaitems.cpp; sourceTree = ""; }; - 8A98736C22707643001F896F /* office_event_listeners.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = office_event_listeners.h; sourceTree = ""; }; - 8A98736D22707643001F896F /* office_chart.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = office_chart.cpp; sourceTree = ""; }; - 8A98736E22707643001F896F /* office_document.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = office_document.h; sourceTree = ""; }; - 8A98736F22707644001F896F /* styles.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = styles.h; sourceTree = ""; }; - 8A98737022707644001F896F /* list.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = list.h; sourceTree = ""; }; - 8A98737122707644001F896F /* office_spreadsheet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = office_spreadsheet.cpp; sourceTree = ""; }; - 8A98737222707644001F896F /* office_annotation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = office_annotation.cpp; sourceTree = ""; }; - 8A98737322707644001F896F /* svg_creator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = svg_creator.h; sourceTree = ""; }; - 8A98737422707645001F896F /* odf_style_state.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = odf_style_state.h; sourceTree = ""; }; - 8A98737522707645001F896F /* abstract_xml.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = abstract_xml.h; sourceTree = ""; }; - 8A98737622707645001F896F /* odf_table_context.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = odf_table_context.h; sourceTree = ""; }; - 8A98737722707645001F896F /* office_elements_create.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = office_elements_create.h; sourceTree = ""; }; - 8A98737822707645001F896F /* odf_number_styles_context.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = odf_number_styles_context.cpp; sourceTree = ""; }; - 8A98737922707646001F896F /* office_scripts.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = office_scripts.h; sourceTree = ""; }; - 8A98737A22707646001F896F /* style_page_layout_properties.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = style_page_layout_properties.h; sourceTree = ""; }; - 8A98737B22707646001F896F /* number_style.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = number_style.h; sourceTree = ""; }; - 8A98737C22707646001F896F /* office_settings.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = office_settings.cpp; sourceTree = ""; }; - 8A98737D22707646001F896F /* office_elements_type.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = office_elements_type.h; sourceTree = ""; }; - 8A98737E22707647001F896F /* odf_lists_styles_context.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = odf_lists_styles_context.h; sourceTree = ""; }; - 8A98737F22707647001F896F /* odf_conversion_context.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = odf_conversion_context.h; sourceTree = ""; }; - 8A98738022707647001F896F /* paragraph_elements.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = paragraph_elements.cpp; sourceTree = ""; }; - 8A98738122707647001F896F /* odp_conversion_context.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = odp_conversion_context.cpp; sourceTree = ""; }; - 8A98738222707647001F896F /* style_text_properties.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = style_text_properties.h; sourceTree = ""; }; - 8A98738322707648001F896F /* style_table_properties.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = style_table_properties.cpp; sourceTree = ""; }; - 8A98738422707648001F896F /* ods_table_state.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ods_table_state.h; sourceTree = ""; }; - 8A98738522707648001F896F /* odf_chart_context.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = odf_chart_context.h; sourceTree = ""; }; - 8A98738622707648001F896F /* draw_page.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = draw_page.h; sourceTree = ""; }; - 8A98738722707649001F896F /* svg_creator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = svg_creator.cpp; sourceTree = ""; }; - 8A98738822707649001F896F /* odf_conversion_context.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = odf_conversion_context.cpp; sourceTree = ""; }; - 8A98738922707649001F896F /* text_elements.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = text_elements.h; sourceTree = ""; }; - 8A98738A22707649001F896F /* odf_notes_context.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = odf_notes_context.h; sourceTree = ""; }; - 8A98738B22707649001F896F /* office_settings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = office_settings.h; sourceTree = ""; }; - 8A98738C2270764A001F896F /* style_map.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = style_map.cpp; sourceTree = ""; }; - 8A98738D2270764A001F896F /* table_named_expressions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = table_named_expressions.h; sourceTree = ""; }; - 8A98738E2270764A001F896F /* draw_page.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = draw_page.cpp; sourceTree = ""; }; - 8A98738F2270764A001F896F /* odp_conversion_context.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = odp_conversion_context.h; sourceTree = ""; }; - 8A9873902270764A001F896F /* table_database_ranges.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = table_database_ranges.h; sourceTree = ""; }; - 8A9873912270764B001F896F /* office_presentation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = office_presentation.h; sourceTree = ""; }; - 8A9873922270764B001F896F /* odf_table_context.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = odf_table_context.cpp; sourceTree = ""; }; - 8A9873932270764B001F896F /* draw_shapes.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = draw_shapes.cpp; sourceTree = ""; }; - 8A9873942270764B001F896F /* office_forms.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = office_forms.cpp; sourceTree = ""; }; - 8A9873952270764B001F896F /* style_presentation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = style_presentation.cpp; sourceTree = ""; }; - 8A9873962270764C001F896F /* odf_controls_context.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = odf_controls_context.cpp; sourceTree = ""; }; - 8A9873972270764C001F896F /* office_presentation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = office_presentation.cpp; sourceTree = ""; }; - 8A9CF4D8238833B500DBCE6B /* table_data_pilot_tables.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = table_data_pilot_tables.cpp; sourceTree = ""; }; - 8A9CF4DA238833C900DBCE6B /* table_data_pilot_tables.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = table_data_pilot_tables.h; path = ../../../ASCOfficeOdfFile/src/odf/table_data_pilot_tables.h; sourceTree = ""; }; - 8A9CF4E52388373000DBCE6B /* File.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = File.h; path = ../../../../../DesktopEditor/common/File.h; sourceTree = ""; }; - 8A9CF4E72388373C00DBCE6B /* File.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = File.cpp; path = ../../../../../DesktopEditor/common/File.cpp; sourceTree = ""; }; - 8A9CF4E92388374500DBCE6B /* File_ios.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = File_ios.mm; path = ../../../../../DesktopEditor/common/File_ios.mm; sourceTree = ""; }; - 8A9CF4ED2388391400DBCE6B /* styleprint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = styleprint.h; path = ../../../../../ASCOfficeOdfFile/src/odf/datatypes/styleprint.h; sourceTree = ""; }; - 8A9CF4EF2388392C00DBCE6B /* styleprint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = styleprint.cpp; path = ../../../../../ASCOfficeOdfFile/src/odf/datatypes/styleprint.cpp; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 17513B012216E721008B45F7 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 17513AFB2216E721008B45F7 = { - isa = PBXGroup; - children = ( - 17513B062216E721008B45F7 /* OfficeOdfConverter */, - 17513B052216E721008B45F7 /* Products */, - ); - sourceTree = ""; - }; - 17513B052216E721008B45F7 /* Products */ = { - isa = PBXGroup; - children = ( - 17513B042216E721008B45F7 /* libOfficeOdfConverter.a */, - ); - name = Products; - sourceTree = ""; - }; - 17513B062216E721008B45F7 /* OfficeOdfConverter */ = { - isa = PBXGroup; - children = ( - 17513E282216EAAB008B45F7 /* ASCOfficeOdfFileW */, - 17513E242216E8C9008B45F7 /* src */, - 17513B072216E721008B45F7 /* OfficeOdfConverter.h */, - 17513B082216E721008B45F7 /* OfficeOdfConverter.mm */, - ); - path = OfficeOdfConverter; - sourceTree = ""; - }; - 17513E242216E8C9008B45F7 /* src */ = { - isa = PBXGroup; - children = ( - 17513E262216E8D1008B45F7 /* cextracttools.h */, - 17513E252216E8D0008B45F7 /* cextracttools.cpp */, - ); - name = src; - sourceTree = ""; - }; - 17513E282216EAAB008B45F7 /* ASCOfficeOdfFileW */ = { - isa = PBXGroup; - children = ( - 17513E2B2216EB48008B45F7 /* OdfFormat */, - 17513EC72216EB49008B45F7 /* Oox2OdfConverter */, - 17513E292216EB48008B45F7 /* progressCallback.h */, - 17513EC62216EB49008B45F7 /* utils.cpp */, - 17513E2A2216EB48008B45F7 /* utils.h */, - 8A9CF4E52388373000DBCE6B /* File.h */, - 8A9CF4E72388373C00DBCE6B /* File.cpp */, - 8A9CF4E92388374500DBCE6B /* File_ios.mm */, - 8A9CF4ED2388391400DBCE6B /* styleprint.h */, - 8A9CF4EF2388392C00DBCE6B /* styleprint.cpp */, - ); - name = ASCOfficeOdfFileW; - sourceTree = ""; - }; - 17513E2B2216EB48008B45F7 /* OdfFormat */ = { - isa = PBXGroup; - children = ( - 8A9CF4DA238833C900DBCE6B /* table_data_pilot_tables.h */, - 8A9CF4D8238833B500DBCE6B /* table_data_pilot_tables.cpp */, - 8A98730622707634001F896F /* abstract_xml.cpp */, - 8A98737522707645001F896F /* abstract_xml.h */, - 8A98736622707642001F896F /* anim_elements.cpp */, - 8A98732622707637001F896F /* anim_elements.h */, - 8A98734F2270763D001F896F /* calcext_elements.cpp */, - 8A9873442270763B001F896F /* calcext_elements.h */, - 8A98730B22707635001F896F /* draw_base.cpp */, - 8A98736522707641001F896F /* draw_base.h */, - 8A98730322707634001F896F /* draw_frame.cpp */, - 8A98736022707640001F896F /* draw_frame.h */, - 8A98738E2270764A001F896F /* draw_page.cpp */, - 8A98738622707648001F896F /* draw_page.h */, - 8A9873932270764B001F896F /* draw_shapes.cpp */, - 8A9872FC22707634001F896F /* draw_shapes.h */, - 8A98732C22707637001F896F /* header_footer.cpp */, - 8A98734D2270763C001F896F /* header_footer.h */, - 8A98733622707639001F896F /* list.cpp */, - 8A98737022707644001F896F /* list.h */, - 8A98732F22707638001F896F /* logging.cpp */, - 8A98733722707639001F896F /* mediaitems_utils.cpp */, - 8A98733F2270763A001F896F /* mediaitems_utils.h */, - 8A98736B22707643001F896F /* mediaitems.cpp */, - 8A98733822707639001F896F /* mediaitems.h */, - 8A98730822707635001F896F /* number_style.cpp */, - 8A98737B22707646001F896F /* number_style.h */, - 8A98730722707635001F896F /* object_package.cpp */, - 8A9873402270763A001F896F /* object_package.h */, - 8A9873572270763F001F896F /* odf_chart_context.cpp */, - 8A98738522707648001F896F /* odf_chart_context.h */, - 8A9873452270763B001F896F /* odf_comment_context.cpp */, - 8A98732422707636001F896F /* odf_comment_context.h */, - 8A9873962270764C001F896F /* odf_controls_context.cpp */, - 8A98734E2270763D001F896F /* odf_controls_context.h */, - 8A98738822707649001F896F /* odf_conversion_context.cpp */, - 8A98737F22707647001F896F /* odf_conversion_context.h */, - 8A98730C22707635001F896F /* odf_drawing_context.cpp */, - 8A98730022707634001F896F /* odf_drawing_context.h */, - 8A98730522707634001F896F /* odf_lists_styles_context.cpp */, - 8A98737E22707647001F896F /* odf_lists_styles_context.h */, - 8A98736822707642001F896F /* odf_notes_context.cpp */, - 8A98738A22707649001F896F /* odf_notes_context.h */, - 8A98737822707645001F896F /* odf_number_styles_context.cpp */, - 8A98733C22707639001F896F /* odf_number_styles_context.h */, - 8A98733B22707639001F896F /* odf_page_layout_context.cpp */, - 8A98732722707637001F896F /* odf_page_layout_context.h */, - 8A9873422270763A001F896F /* odf_page_layout_state.cpp */, - 8A98732522707636001F896F /* odf_page_layout_state.h */, - 8A98736722707642001F896F /* odf_rels.cpp */, - 8A9873412270763A001F896F /* odf_rels.h */, - 8A9873592270763F001F896F /* odf_settings_context.cpp */, - 8A98730A22707635001F896F /* odf_settings_context.h */, - 8A9873472270763B001F896F /* odf_style_context.cpp */, - 8A9872FB22707634001F896F /* odf_style_context.h */, - 8A98734C2270763C001F896F /* odf_style_state.cpp */, - 8A98737422707645001F896F /* odf_style_state.h */, - 8A9873922270764B001F896F /* odf_table_context.cpp */, - 8A98737622707645001F896F /* odf_table_context.h */, - 8A98736422707641001F896F /* odf_table_styles_context.cpp */, - 8A98733122707638001F896F /* odf_table_styles_context.h */, - 8A9873552270763E001F896F /* odf_text_context.cpp */, - 8A98733322707638001F896F /* odf_text_context.h */, - 8A98738122707647001F896F /* odp_conversion_context.cpp */, - 8A98738F2270764A001F896F /* odp_conversion_context.h */, - 8A9872FD22707634001F896F /* odp_page_state.cpp */, - 8A98730222707634001F896F /* odp_page_state.h */, - 8A98736122707640001F896F /* odp_slide_context.cpp */, - 8A98732922707637001F896F /* odp_slide_context.h */, - 8A98730F22707636001F896F /* ods_conversion_context.cpp */, - 8A9873522270763E001F896F /* ods_conversion_context.h */, - 8A98735B2270763F001F896F /* ods_table_context.cpp */, - 8A98732B22707637001F896F /* ods_table_context.h */, - 8A98733922707639001F896F /* ods_table_state.cpp */, - 8A98738422707648001F896F /* ods_table_state.h */, - 8A98730D22707635001F896F /* odt_conversion_context.cpp */, - 8A98732322707636001F896F /* odt_conversion_context.h */, - 8A98737222707644001F896F /* office_annotation.cpp */, - 8A98730922707635001F896F /* office_annotation.h */, - 8A9873462270763B001F896F /* office_body.cpp */, - 8A98736222707641001F896F /* office_body.h */, - 8A98736D22707643001F896F /* office_chart.cpp */, - 8A98735A2270763F001F896F /* office_chart.h */, - 8A9872FA22707634001F896F /* office_document.cpp */, - 8A98736E22707643001F896F /* office_document.h */, - 8A98730422707634001F896F /* office_elements_create.cpp */, - 8A98737722707645001F896F /* office_elements_create.h */, - 8A98737D22707646001F896F /* office_elements_type.h */, - 8A98732822707637001F896F /* office_elements.h */, - 8A98730E22707636001F896F /* office_event_listeners.cpp */, - 8A98736C22707643001F896F /* office_event_listeners.h */, - 8A9873942270764B001F896F /* office_forms.cpp */, - 8A98733222707638001F896F /* office_forms.h */, - 8A9873972270764C001F896F /* office_presentation.cpp */, - 8A9873912270764B001F896F /* office_presentation.h */, - 8A98735C2270763F001F896F /* office_scripts.cpp */, - 8A98737922707646001F896F /* office_scripts.h */, - 8A98737C22707646001F896F /* office_settings.cpp */, - 8A98738B22707649001F896F /* office_settings.h */, - 8A98737122707644001F896F /* office_spreadsheet.cpp */, - 8A98735D22707640001F896F /* office_spreadsheet.h */, - 8A98733022707638001F896F /* office_text.cpp */, - 8A9872FE22707634001F896F /* office_text.h */, - 8A9873482270763B001F896F /* oox_shape_defines.cpp */, - 8A9873502270763D001F896F /* oox_shape_defines.h */, - 8A98738022707647001F896F /* paragraph_elements.cpp */, - 8A9873542270763E001F896F /* paragraph_elements.h */, - 8A98731122707636001F896F /* Shapes */, - 8A98733E22707639001F896F /* style_chart_properties.cpp */, - 8A98734B2270763C001F896F /* style_chart_properties.h */, - 8A98733D22707639001F896F /* style_graphic_properties.cpp */, - 8A98730122707634001F896F /* style_graphic_properties.h */, - 8A98738C2270764A001F896F /* style_map.cpp */, - 8A98732D22707637001F896F /* style_map.h */, - 8A9873492270763C001F896F /* style_page_layout_properties.cpp */, - 8A98737A22707646001F896F /* style_page_layout_properties.h */, - 8A98732E22707637001F896F /* style_paragraph_properties.cpp */, - 8A98733522707638001F896F /* style_paragraph_properties.h */, - 8A9873952270764B001F896F /* style_presentation.cpp */, - 8A9872FF22707634001F896F /* style_presentation.h */, - 8A9873562270763E001F896F /* style_section_properties.cpp */, - 8A9873582270763F001F896F /* style_section_properties.h */, - 8A98738322707648001F896F /* style_table_properties.cpp */, - 8A98735F22707640001F896F /* style_table_properties.h */, - 8A98733422707638001F896F /* style_text_properties.cpp */, - 8A98738222707647001F896F /* style_text_properties.h */, - 8A98735E22707640001F896F /* styles_list.cpp */, - 8A9873512270763D001F896F /* styles_list.h */, - 8A98732A22707637001F896F /* styles_lite_container.cpp */, - 8A98733A22707639001F896F /* styles_lite_container.h */, - 8A98736922707642001F896F /* styles.cpp */, - 8A98736F22707644001F896F /* styles.h */, - 8A98738722707649001F896F /* svg_creator.cpp */, - 8A98737322707644001F896F /* svg_creator.h */, - 8A98731022707636001F896F /* table_database_ranges.cpp */, - 8A9873902270764A001F896F /* table_database_ranges.h */, - 8A9873532270763E001F896F /* table_named_expressions.cpp */, - 8A98738D2270764A001F896F /* table_named_expressions.h */, - 8A98736A22707642001F896F /* table.cpp */, - 8A9873432270763A001F896F /* table.h */, - 8A98736322707641001F896F /* text_elements.cpp */, - 8A98738922707649001F896F /* text_elements.h */, - 8A98734A2270763C001F896F /* visitor.h */, - ); - name = OdfFormat; - path = ../../../../../ASCOfficeOdfFileW/source/OdfFormat; - sourceTree = ""; - }; - 17513EC72216EB49008B45F7 /* Oox2OdfConverter */ = { - isa = PBXGroup; - children = ( - 17513EC82216EB49008B45F7 /* DocxConverter.h */, - 17513EC92216EB49008B45F7 /* Converter.cpp */, - 17513ECA2216EB49008B45F7 /* ConverterChart.cpp */, - 17513ECB2216EB49008B45F7 /* Converter.h */, - 17513ECC2216EB49008B45F7 /* XlsxConverter.cpp */, - 17513ECD2216EB49008B45F7 /* PptxConverter.h */, - 17513ECE2216EB49008B45F7 /* DocxConverter.cpp */, - 17513ECF2216EB49008B45F7 /* PptxConverter.cpp */, - 17513ED02216EB49008B45F7 /* VmlShapeTypes2Oox.h */, - 17513ED12216EB49008B45F7 /* ConvertVml.cpp */, - 17513ED22216EB49008B45F7 /* Oox2OdfConverter.h */, - 17513ED32216EB49008B45F7 /* ConvertDrawing.cpp */, - 17513ED42216EB49008B45F7 /* XlsxConverter.h */, - ); - name = Oox2OdfConverter; - path = ../../../../../ASCOfficeOdfFileW/source/Oox2OdfConverter; - sourceTree = ""; - }; - 8A98731122707636001F896F /* Shapes */ = { - isa = PBXGroup; - children = ( - 8A98731222707636001F896F /* oox_shapePrimitives.h */, - 8A98731322707636001F896F /* oox_shapeBents.h */, - 8A98731422707636001F896F /* oox_shapeConnectors.h */, - 8A98731522707636001F896F /* oox_shapeCallouts.h */, - 8A98731622707636001F896F /* oox_shapeCharts.h */, - 8A98731722707636001F896F /* oox_shapeArrows.h */, - 8A98731822707636001F896F /* oox_shapeWordArt.h */, - 8A98731922707636001F896F /* oox_shapeCurvedArrows.h */, - 8A98731A22707636001F896F /* oox_shapeStars.h */, - 8A98731B22707636001F896F /* oox_shapeActionButtons.h */, - 8A98731C22707636001F896F /* oox_shapeCustoms.h */, - 8A98731D22707636001F896F /* oox_shapeSnipRoundRects.h */, - 8A98731E22707636001F896F /* odf_shape_mapping.h */, - 8A98731F22707636001F896F /* oox_shapeCurvedConnectors.h */, - 8A98732022707636001F896F /* oox_shapeMaths.h */, - 8A98732122707636001F896F /* oox_shapeRibbons.h */, - 8A98732222707636001F896F /* oox_shapeAccentCallouts.h */, - ); - path = Shapes; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXHeadersBuildPhase section */ - 8A8753C42227F44A00117573 /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - 8A9873C52270764C001F896F /* office_elements.h in Headers */, - 8A9873B02270764C001F896F /* oox_shapeBents.h in Headers */, - 8A9874272270764D001F896F /* odf_notes_context.h in Headers */, - 8A9873DC2270764C001F896F /* mediaitems_utils.h in Headers */, - 8A9873BE2270764C001F896F /* oox_shapeRibbons.h in Headers */, - 8A9873A72270764C001F896F /* office_annotation.h in Headers */, - 8A9873B52270764C001F896F /* oox_shapeWordArt.h in Headers */, - 8A9873C12270764C001F896F /* odf_comment_context.h in Headers */, - 8A9873F72270764C001F896F /* office_chart.h in Headers */, - 8A9873D02270764C001F896F /* odf_text_context.h in Headers */, - 8A9873C42270764C001F896F /* odf_page_layout_context.h in Headers */, - 8A9873FD2270764C001F896F /* draw_frame.h in Headers */, - 8A9874182270764D001F896F /* number_style.h in Headers */, - 8A9873CA2270764C001F896F /* style_map.h in Headers */, - 8A9873C82270764C001F896F /* ods_table_context.h in Headers */, - 8A9873B22270764C001F896F /* oox_shapeCallouts.h in Headers */, - 8A98742D2270764D001F896F /* table_database_ranges.h in Headers */, - 8A9873ED2270764C001F896F /* oox_shape_defines.h in Headers */, - 8A98739F2270764C001F896F /* style_graphic_properties.h in Headers */, - 8A9874112270764D001F896F /* odf_style_state.h in Headers */, - 8A9874142270764D001F896F /* office_elements_create.h in Headers */, - 8A9CF4DB238833C900DBCE6B /* table_data_pilot_tables.h in Headers */, - 8A9874162270764D001F896F /* office_scripts.h in Headers */, - 8A9874212270764D001F896F /* ods_table_state.h in Headers */, - 8A98739D2270764C001F896F /* style_presentation.h in Headers */, - 8A98741A2270764D001F896F /* office_elements_type.h in Headers */, - 8A9873CF2270764C001F896F /* office_forms.h in Headers */, - 8A98740D2270764D001F896F /* list.h in Headers */, - 8A9873B72270764C001F896F /* oox_shapeStars.h in Headers */, - 8A9874092270764D001F896F /* office_event_listeners.h in Headers */, - 8A9874132270764D001F896F /* odf_table_context.h in Headers */, - 8A9873DE2270764C001F896F /* odf_rels.h in Headers */, - 8A9873992270764C001F896F /* odf_style_context.h in Headers */, - 8A9873C32270764C001F896F /* anim_elements.h in Headers */, - 8A98739A2270764C001F896F /* draw_shapes.h in Headers */, - 8A9873EB2270764C001F896F /* odf_controls_context.h in Headers */, - 8A9873BF2270764C001F896F /* oox_shapeAccentCallouts.h in Headers */, - 8A9873B82270764C001F896F /* oox_shapeActionButtons.h in Headers */, - 8A9873E82270764C001F896F /* style_chart_properties.h in Headers */, - 17513B0A2216E721008B45F7 /* OfficeOdfConverter.h in Headers */, - 8A9CF4EE2388391500DBCE6B /* styleprint.h in Headers */, - 8A9873BB2270764C001F896F /* odf_shape_mapping.h in Headers */, - 8A9874122270764D001F896F /* abstract_xml.h in Headers */, - 8A9874222270764D001F896F /* odf_chart_context.h in Headers */, - 8A9873A02270764C001F896F /* odp_page_state.h in Headers */, - 8A98739C2270764C001F896F /* office_text.h in Headers */, - 8A9873BC2270764C001F896F /* oox_shapeCurvedConnectors.h in Headers */, - 8A98739E2270764C001F896F /* odf_drawing_context.h in Headers */, - 8A9873C22270764C001F896F /* odf_page_layout_state.h in Headers */, - 8A9873BA2270764C001F896F /* oox_shapeSnipRoundRects.h in Headers */, - 8A98741C2270764D001F896F /* odf_conversion_context.h in Headers */, - 8A9873D72270764C001F896F /* styles_lite_container.h in Headers */, - 8A9873CE2270764C001F896F /* odf_table_styles_context.h in Headers */, - 8A9873B92270764C001F896F /* oox_shapeCustoms.h in Headers */, - 8A9873F12270764C001F896F /* paragraph_elements.h in Headers */, - 8A9874262270764D001F896F /* text_elements.h in Headers */, - 8A9873EF2270764C001F896F /* ods_conversion_context.h in Headers */, - 8A9873FA2270764C001F896F /* office_spreadsheet.h in Headers */, - 8A98742A2270764D001F896F /* table_named_expressions.h in Headers */, - 8A9873EE2270764C001F896F /* styles_list.h in Headers */, - 8A9873EA2270764C001F896F /* header_footer.h in Headers */, - 8A9873B42270764C001F896F /* oox_shapeArrows.h in Headers */, - 8A98742C2270764D001F896F /* odp_conversion_context.h in Headers */, - 8A9873BD2270764C001F896F /* oox_shapeMaths.h in Headers */, - 8A9873D92270764C001F896F /* odf_number_styles_context.h in Headers */, - 8A9873C02270764C001F896F /* odt_conversion_context.h in Headers */, - 8A9CF4E62388373000DBCE6B /* File.h in Headers */, - 8A9873B32270764C001F896F /* oox_shapeCharts.h in Headers */, - 8A9873A82270764C001F896F /* odf_settings_context.h in Headers */, - 8A9873F52270764C001F896F /* style_section_properties.h in Headers */, - 8A98742E2270764D001F896F /* office_presentation.h in Headers */, - 8A9873FF2270764C001F896F /* office_body.h in Headers */, - 8A9873B12270764C001F896F /* oox_shapeConnectors.h in Headers */, - 8A9874282270764D001F896F /* office_settings.h in Headers */, - 8A9874022270764C001F896F /* draw_base.h in Headers */, - 8A9874232270764D001F896F /* draw_page.h in Headers */, - 8A9873FC2270764C001F896F /* style_table_properties.h in Headers */, - 8A9873E12270764C001F896F /* calcext_elements.h in Headers */, - 8A9873D52270764C001F896F /* mediaitems.h in Headers */, - 8A9873DD2270764C001F896F /* object_package.h in Headers */, - 8A9873D22270764C001F896F /* style_paragraph_properties.h in Headers */, - 8A98741B2270764D001F896F /* odf_lists_styles_context.h in Headers */, - 8A9873B62270764C001F896F /* oox_shapeCurvedArrows.h in Headers */, - 8A9873E72270764C001F896F /* visitor.h in Headers */, - 8A9873E02270764C001F896F /* table.h in Headers */, - 8A9873C62270764C001F896F /* odp_slide_context.h in Headers */, - 8A98740B2270764D001F896F /* office_document.h in Headers */, - 8A98740C2270764D001F896F /* styles.h in Headers */, - 8A98741F2270764D001F896F /* style_text_properties.h in Headers */, - 8A9874102270764D001F896F /* svg_creator.h in Headers */, - 8A9874172270764D001F896F /* style_page_layout_properties.h in Headers */, - 8A9873AF2270764C001F896F /* oox_shapePrimitives.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXHeadersBuildPhase section */ - -/* Begin PBXNativeTarget section */ - 17513B032216E721008B45F7 /* OfficeOdfConverter */ = { - isa = PBXNativeTarget; - buildConfigurationList = 17513B0D2216E721008B45F7 /* Build configuration list for PBXNativeTarget "OfficeOdfConverter" */; - buildPhases = ( - 8A8753C42227F44A00117573 /* Headers */, - 17513B002216E721008B45F7 /* Sources */, - 17513B012216E721008B45F7 /* Frameworks */, - 17513B022216E721008B45F7 /* CopyFiles */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = OfficeOdfConverter; - productName = OfficeOdfConverter; - productReference = 17513B042216E721008B45F7 /* libOfficeOdfConverter.a */; - productType = "com.apple.product-type.library.static"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 17513AFC2216E721008B45F7 /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 1010; - ORGANIZATIONNAME = "Ascensio System SIA"; - TargetAttributes = { - 17513B032216E721008B45F7 = { - CreatedOnToolsVersion = 10.1; - }; - }; - }; - buildConfigurationList = 17513AFF2216E721008B45F7 /* Build configuration list for PBXProject "OfficeOdfConverter" */; - compatibilityVersion = "Xcode 9.3"; - developmentRegion = en; - hasScannedForEncodings = 0; - knownRegions = ( - en, - ); - mainGroup = 17513AFB2216E721008B45F7; - productRefGroup = 17513B052216E721008B45F7 /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 17513B032216E721008B45F7 /* OfficeOdfConverter */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXSourcesBuildPhase section */ - 17513B002216E721008B45F7 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 8A9874322270764D001F896F /* style_presentation.cpp in Sources */, - 8A9874072270764C001F896F /* table.cpp in Sources */, - 17513F1B2216EB49008B45F7 /* XlsxConverter.cpp in Sources */, - 8A9874052270764C001F896F /* odf_notes_context.cpp in Sources */, - 8A9873F32270764C001F896F /* style_section_properties.cpp in Sources */, - 8A9873A42270764C001F896F /* abstract_xml.cpp in Sources */, - 8A9874062270764C001F896F /* styles.cpp in Sources */, - 8A9873C92270764C001F896F /* header_footer.cpp in Sources */, - 8A9873AB2270764C001F896F /* odt_conversion_context.cpp in Sources */, - 8A9873DA2270764C001F896F /* style_graphic_properties.cpp in Sources */, - 8A9873DF2270764C001F896F /* odf_page_layout_state.cpp in Sources */, - 8A9873F62270764C001F896F /* odf_settings_context.cpp in Sources */, - 8A98742F2270764D001F896F /* odf_table_context.cpp in Sources */, - 8A9873A52270764C001F896F /* object_package.cpp in Sources */, - 8A9CF4D9238833B500DBCE6B /* table_data_pilot_tables.cpp in Sources */, - 17513F1D2216EB49008B45F7 /* PptxConverter.cpp in Sources */, - 8A9874032270764C001F896F /* anim_elements.cpp in Sources */, - 8A9874082270764D001F896F /* mediaitems.cpp in Sources */, - 8A9874202270764D001F896F /* style_table_properties.cpp in Sources */, - 8A9873D12270764C001F896F /* style_text_properties.cpp in Sources */, - 8A9873DB2270764C001F896F /* style_chart_properties.cpp in Sources */, - 17513F1E2216EB49008B45F7 /* ConvertVml.cpp in Sources */, - 8A9873F02270764C001F896F /* table_named_expressions.cpp in Sources */, - 8A9873D62270764C001F896F /* ods_table_state.cpp in Sources */, - 8A9874152270764D001F896F /* odf_number_styles_context.cpp in Sources */, - 8A98740F2270764D001F896F /* office_annotation.cpp in Sources */, - 8A9874252270764D001F896F /* odf_conversion_context.cpp in Sources */, - 8A9CF4F02388392C00DBCE6B /* styleprint.cpp in Sources */, - 8A9CF4E82388373C00DBCE6B /* File.cpp in Sources */, - 8A9873C72270764C001F896F /* styles_lite_container.cpp in Sources */, - 17513F192216EB49008B45F7 /* Converter.cpp in Sources */, - 8A9873E92270764C001F896F /* odf_style_state.cpp in Sources */, - 8A9874302270764D001F896F /* draw_shapes.cpp in Sources */, - 8A98741D2270764D001F896F /* paragraph_elements.cpp in Sources */, - 17513F1F2216EB49008B45F7 /* ConvertDrawing.cpp in Sources */, - 8A9873FB2270764C001F896F /* styles_list.cpp in Sources */, - 8A9873A22270764C001F896F /* office_elements_create.cpp in Sources */, - 8A9873EC2270764C001F896F /* calcext_elements.cpp in Sources */, - 8A9873F82270764C001F896F /* ods_table_context.cpp in Sources */, - 8A9874332270764D001F896F /* odf_controls_context.cpp in Sources */, - 17513E272216E8D1008B45F7 /* cextracttools.cpp in Sources */, - 8A9873F22270764C001F896F /* odf_text_context.cpp in Sources */, - 8A9873E62270764C001F896F /* style_page_layout_properties.cpp in Sources */, - 8A9873A62270764C001F896F /* number_style.cpp in Sources */, - 8A9873AE2270764C001F896F /* table_database_ranges.cpp in Sources */, - 8A9873A12270764C001F896F /* draw_frame.cpp in Sources */, - 8A9873D82270764C001F896F /* odf_page_layout_context.cpp in Sources */, - 8A9873982270764C001F896F /* office_document.cpp in Sources */, - 8A9874312270764D001F896F /* office_forms.cpp in Sources */, - 8A9873A32270764C001F896F /* odf_lists_styles_context.cpp in Sources */, - 8A9873A92270764C001F896F /* draw_base.cpp in Sources */, - 8A9873CB2270764C001F896F /* style_paragraph_properties.cpp in Sources */, - 8A9CF4EA2388374500DBCE6B /* File_ios.mm in Sources */, - 17513F182216EB49008B45F7 /* utils.cpp in Sources */, - 8A9874342270764D001F896F /* office_presentation.cpp in Sources */, - 17513F1A2216EB49008B45F7 /* ConverterChart.cpp in Sources */, - 8A9873E42270764C001F896F /* odf_style_context.cpp in Sources */, - 8A98741E2270764D001F896F /* odp_conversion_context.cpp in Sources */, - 8A9873CD2270764C001F896F /* office_text.cpp in Sources */, - 8A9874002270764C001F896F /* text_elements.cpp in Sources */, - 8A9873E32270764C001F896F /* office_body.cpp in Sources */, - 8A9874242270764D001F896F /* svg_creator.cpp in Sources */, - 17513B092216E721008B45F7 /* OfficeOdfConverter.mm in Sources */, - 8A98740E2270764D001F896F /* office_spreadsheet.cpp in Sources */, - 8A9873CC2270764C001F896F /* logging.cpp in Sources */, - 8A9873AC2270764C001F896F /* office_event_listeners.cpp in Sources */, - 8A98740A2270764D001F896F /* office_chart.cpp in Sources */, - 8A9873F42270764C001F896F /* odf_chart_context.cpp in Sources */, - 8A9873D32270764C001F896F /* list.cpp in Sources */, - 8A9874192270764D001F896F /* office_settings.cpp in Sources */, - 8A9873D42270764C001F896F /* mediaitems_utils.cpp in Sources */, - 8A9873F92270764C001F896F /* office_scripts.cpp in Sources */, - 8A9874042270764C001F896F /* odf_rels.cpp in Sources */, - 8A9874292270764D001F896F /* style_map.cpp in Sources */, - 8A9873FE2270764C001F896F /* odp_slide_context.cpp in Sources */, - 8A98742B2270764D001F896F /* draw_page.cpp in Sources */, - 8A9874012270764C001F896F /* odf_table_styles_context.cpp in Sources */, - 17513F1C2216EB49008B45F7 /* DocxConverter.cpp in Sources */, - 8A9873AD2270764C001F896F /* ods_conversion_context.cpp in Sources */, - 8A98739B2270764C001F896F /* odp_page_state.cpp in Sources */, - 8A9873E22270764C001F896F /* odf_comment_context.cpp in Sources */, - 8A9873AA2270764C001F896F /* odf_drawing_context.cpp in Sources */, - 8A9873E52270764C001F896F /* oox_shape_defines.cpp in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin XCBuildConfiguration section */ - 17513B0B2216E721008B45F7 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - CODE_SIGN_IDENTITY = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu11; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 10.0; - MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; - MTL_FAST_MATH = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - }; - name = Debug; - }; - 17513B0C2216E721008B45F7 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - CODE_SIGN_IDENTITY = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu11; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 10.0; - MTL_ENABLE_DEBUG_INFO = NO; - MTL_FAST_MATH = YES; - SDKROOT = iphoneos; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - 17513B0E2216E721008B45F7 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = 2WH24U26GJ; - GCC_PREPROCESSOR_DEFINITIONS = ( - UNICODE, - _UNICODE, - PPTX_DEF, - PPT_DEF, - ENABLE_PPT_TO_PPTX_CONVERT, - NODOCX, - FILTER_FLATE_DECODE_ENABLED, - CXIMAGE_DONT_DECLARE_TCHAR, - BUILD_CONFIG_FULL_VERSION, - DONT_WRITE_EMBEDDED_FONTS, - AVS_USE_CONVERT_PPTX_TOCUSTOM_VML, - unix, - MAC, - _IOS, - ); - HEADER_SEARCH_PATHS = ( - "$(inherited)", - /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, - /usr/include/libxml2, - "$(PROJECT_DIR)/../../../../DesktopEditor/freetype-2.5.2/include", - "$(PROJECT_DIR)/../../../../DesktopEditor/agg-2.4/include", - "$(PROJECT_DIR)/../../../../Common/3dParty/boost/boost_1_58_0", - "$(PROJECT_DIR)/../../../../ASCOfficeOdfFile/include", - "$(PROJECT_DIR)/../../../../ASCOfficeOdfFile/src/odf/datatypes", - ); - OTHER_CFLAGS = "-fembed-bitcode-marker"; - OTHER_LDFLAGS = "-ObjC"; - PRODUCT_NAME = "$(TARGET_NAME)"; - SKIP_INSTALL = YES; - TARGETED_DEVICE_FAMILY = 1; - VALID_ARCHS = "arm64 armv7 armv7s i386 x86_64"; - }; - name = Debug; - }; - 17513B0F2216E721008B45F7 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = 2WH24U26GJ; - GCC_PREPROCESSOR_DEFINITIONS = ( - UNICODE, - _UNICODE, - PPTX_DEF, - PPT_DEF, - ENABLE_PPT_TO_PPTX_CONVERT, - NODOCX, - FILTER_FLATE_DECODE_ENABLED, - CXIMAGE_DONT_DECLARE_TCHAR, - BUILD_CONFIG_FULL_VERSION, - DONT_WRITE_EMBEDDED_FONTS, - AVS_USE_CONVERT_PPTX_TOCUSTOM_VML, - unix, - MAC, - _IOS, - ); - HEADER_SEARCH_PATHS = ( - "$(inherited)", - /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, - /usr/include/libxml2, - "$(PROJECT_DIR)/../../../../DesktopEditor/freetype-2.5.2/include", - "$(PROJECT_DIR)/../../../../DesktopEditor/agg-2.4/include", - "$(PROJECT_DIR)/../../../../Common/3dParty/boost/boost_1_58_0", - "$(PROJECT_DIR)/../../../../ASCOfficeOdfFile/include", - "$(PROJECT_DIR)/../../../../ASCOfficeOdfFile/src/odf/datatypes", - ); - OTHER_CFLAGS = "-fembed-bitcode"; - OTHER_LDFLAGS = "-ObjC"; - PRODUCT_NAME = "$(TARGET_NAME)"; - SKIP_INSTALL = YES; - TARGETED_DEVICE_FAMILY = 1; - VALID_ARCHS = "arm64 armv7 armv7s i386 x86_64"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 17513AFF2216E721008B45F7 /* Build configuration list for PBXProject "OfficeOdfConverter" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 17513B0B2216E721008B45F7 /* Debug */, - 17513B0C2216E721008B45F7 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 17513B0D2216E721008B45F7 /* Build configuration list for PBXNativeTarget "OfficeOdfConverter" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 17513B0E2216E721008B45F7 /* Debug */, - 17513B0F2216E721008B45F7 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 17513AFC2216E721008B45F7 /* Project object */; -} diff --git a/X2tConverter/build/Mac/OfficeOdfConverter/OfficeOdfConverter.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/X2tConverter/build/Mac/OfficeOdfConverter/OfficeOdfConverter.xcodeproj/project.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index e9497df76ac..00000000000 --- a/X2tConverter/build/Mac/OfficeOdfConverter/OfficeOdfConverter.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/X2tConverter/build/Mac/OfficeOdfConverter/OfficeOdfConverter.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/X2tConverter/build/Mac/OfficeOdfConverter/OfficeOdfConverter.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist deleted file mode 100644 index 18d981003d6..00000000000 --- a/X2tConverter/build/Mac/OfficeOdfConverter/OfficeOdfConverter.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +++ /dev/null @@ -1,8 +0,0 @@ - - - - - IDEDidComputeMac32BitWarning - - - diff --git a/X2tConverter/build/Mac/OfficeOdfConverter/OfficeOdfConverter/OfficeOdfConverter.mm b/X2tConverter/build/Mac/OfficeOdfConverter/OfficeOdfConverter/OfficeOdfConverter.mm deleted file mode 100644 index 953a21b6908..00000000000 --- a/X2tConverter/build/Mac/OfficeOdfConverter/OfficeOdfConverter/OfficeOdfConverter.mm +++ /dev/null @@ -1,230 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2023 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ - -#import "OfficeOdfConverter.h" - -#include "../../../../src/cextracttools.h" -#include "../../OfficeUtils/src/OfficeUtils.h" -#include "../../ASCOfficeOdfFileW/source/Oox2OdfConverter/Oox2OdfConverter.h" -//#include "../../ASCOfficeOdfFile/src/ConvertOO2OOX.h" - -#include -#include -#include - -namespace NExtractTools -{ - static std::wstring nsstring_to_wstring(NSString* nsstring) - { - NSStringEncoding encode = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingUTF32LE); - NSData* data = [nsstring dataUsingEncoding:encode]; - return std::wstring((wchar_t*) data.bytes, data.length / sizeof(wchar_t)); - } -} - -namespace NExtractTools -{ - // docx dir -> odt - _UINT32 __docx_dir2odt (const std::wstring &sDocxDir, const std::wstring &sTo, const std::wstring &sTemp, InputParams& params, bool bTemplate) - { - std::wstring sTempUnpackedODT = sTemp + FILE_SEPARATOR_STR + L"odt_unpacked"; - NSDirectory::CreateDirectory(sTempUnpackedODT); - - Oox2Odf::Converter converter(sDocxDir, L"text", params.getFontPath(), bTemplate); - - _UINT32 nRes = 0; - try - { - std::wstring password = params.getSavePassword(); - std::wstring documentID = params.getDocumentID(); - - converter.convert(); - converter.write(sTempUnpackedODT, sTemp, password, documentID); - - COfficeUtils oCOfficeUtils(NULL); - nRes = (S_OK == oCOfficeUtils.CompressFileOrDirectory(sTempUnpackedODT, sTo, false, password.empty() ? Z_DEFLATED : 0)) ? 0 : AVS_FILEUTILS_ERROR_CONVERT; - } - catch(...) - { - nRes = AVS_FILEUTILS_ERROR_CONVERT; - } - return nRes; - } - - _UINT32 __xlsx_dir2ods (const std::wstring &sXlsxDir, const std::wstring &sTo, const std::wstring &sTemp, InputParams& params, bool bTemplate) - { - std::wstring sTempUnpackedODS = sTemp + FILE_SEPARATOR_STR + L"ods_unpacked"; - NSDirectory::CreateDirectory(sTempUnpackedODS); - - Oox2Odf::Converter converter(sXlsxDir, L"spreadsheet", params.getFontPath(), bTemplate); - - _UINT32 nRes = 0; - try - { - std::wstring password = params.getSavePassword(); - std::wstring documentID = params.getDocumentID(); - - converter.convert(); - converter.write(sTempUnpackedODS, sTemp, password, documentID); - - COfficeUtils oCOfficeUtils(NULL); - nRes = (S_OK == oCOfficeUtils.CompressFileOrDirectory(sTempUnpackedODS, sTo, false, password.empty() ? Z_DEFLATED : 0)) ? 0 : AVS_FILEUTILS_ERROR_CONVERT; - } - catch(...) - { - nRes = AVS_FILEUTILS_ERROR_CONVERT; - } - return nRes; - } - - // pptx_dir -> odp - _UINT32 __pptx_dir2odp (const std::wstring &sPptxDir, const std::wstring &sTo, const std::wstring &sTemp, InputParams& params, bool bTemplate) - { - std::wstring sTempUnpackedODP = sTemp + FILE_SEPARATOR_STR + _T("odp_unpacked"); - NSDirectory::CreateDirectory(sTempUnpackedODP); - - Oox2Odf::Converter converter(sPptxDir, _T("presentation"), params.getFontPath(), bTemplate); - - _UINT32 nRes = 0; - try - { - std::wstring password = params.getSavePassword(); - std::wstring documentID = params.getDocumentID(); - - converter.convert(); - converter.write(sTempUnpackedODP, sTemp, password, documentID); - - COfficeUtils oCOfficeUtils(NULL); - nRes = (S_OK == oCOfficeUtils.CompressFileOrDirectory(sTempUnpackedODP, sTo, false, password.empty() ? Z_DEFLATED : 0)) ? 0 : AVS_FILEUTILS_ERROR_CONVERT; - } - catch(...) - { - nRes = AVS_FILEUTILS_ERROR_CONVERT; - } - return nRes; - } - - // docx -> odt - _UINT32 __docx2odt (const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams& params, bool bTemplate) - { - std::wstring sTempUnpackedDOCX = sTemp + FILE_SEPARATOR_STR + _T("docx_unpacked"); - NSDirectory::CreateDirectory(sTempUnpackedDOCX); - - COfficeUtils oCOfficeUtils(NULL); - if (S_OK == oCOfficeUtils.ExtractToDirectory(sFrom, sTempUnpackedDOCX, NULL, 0)) - { - return __docx_dir2odt(sTempUnpackedDOCX, sTo, sTemp, params, bTemplate); - } - return AVS_FILEUTILS_ERROR_CONVERT; - } - - // xlsx -> ods - _UINT32 __xlsx2ods (const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams& params, bool bTemplate) - { - std::wstring sTempUnpackedXLSX = sTemp + FILE_SEPARATOR_STR + L"xlsx_unpacked"; - - NSDirectory::CreateDirectory(sTempUnpackedXLSX); - - COfficeUtils oCOfficeUtils(NULL); - if (S_OK == oCOfficeUtils.ExtractToDirectory(sFrom, sTempUnpackedXLSX, NULL, 0)) - { - return __xlsx_dir2ods(sTempUnpackedXLSX, sTo, sTemp, params, bTemplate); - } - return AVS_FILEUTILS_ERROR_CONVERT; - } - - // pptx -> odp - _UINT32 __pptx2odp (const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams& params, bool bTemplate) - { - std::wstring sTempUnpackedPPTX = sTemp + FILE_SEPARATOR_STR + _T("pptx_unpacked"); - NSDirectory::CreateDirectory(sTempUnpackedPPTX); - - COfficeUtils oCOfficeUtils(NULL); - if (S_OK == oCOfficeUtils.ExtractToDirectory(sFrom, sTempUnpackedPPTX, NULL, 0)) - { - return __pptx_dir2odp(sTempUnpackedPPTX, sTo, sTemp, params, bTemplate); - } - return AVS_FILEUTILS_ERROR_CONVERT; - } -} - -@implementation OfficeOdfConverter - -- (int)docx2odt:(NSString*)nsFrom nsTo:(NSString*)nsTo nsTemp:(NSString*)nsTemp nsFontPath:(NSString*)nsFontPath isTemplate:(bool)isTemplate { - std::wstring from = NExtractTools::nsstring_to_wstring(nsFrom); - std::wstring to = NExtractTools::nsstring_to_wstring(nsTo); - std::wstring temp = NExtractTools::nsstring_to_wstring(nsTemp); - - NExtractTools::InputParams oInputParams; - oInputParams.m_sFontDir = new std::wstring(NExtractTools::nsstring_to_wstring(nsFontPath)); - oInputParams.m_bIsNoBase64 = new bool(self.isNoBase64); - - if (self.password) { - oInputParams.m_sPassword = new std::wstring(NExtractTools::nsstring_to_wstring(self.password)); - } - - return NExtractTools::__docx2odt(from, to, temp, oInputParams, isTemplate); -} - -- (int)xlsx2ods:(NSString*)nsFrom nsTo:(NSString*)nsTo nsTemp:(NSString*)nsTemp nsFontPath:(NSString*)nsFontPath isTemplate:(bool)isTemplate { - std::wstring from = NExtractTools::nsstring_to_wstring(nsFrom); - std::wstring to = NExtractTools::nsstring_to_wstring(nsTo); - std::wstring temp = NExtractTools::nsstring_to_wstring(nsTemp); - - NExtractTools::InputParams oInputParams; - oInputParams.m_sFontDir = new std::wstring(NExtractTools::nsstring_to_wstring(nsFontPath)); - oInputParams.m_bIsNoBase64 = new bool(self.isNoBase64); - - if (self.password) { - oInputParams.m_sPassword = new std::wstring(NExtractTools::nsstring_to_wstring(self.password)); - } - - return NExtractTools::__xlsx2ods(from, to, temp, oInputParams, isTemplate); -} - -- (int)pptx2odp:(NSString*)nsFrom nsTo:(NSString*)nsTo nsTemp:(NSString*)nsTemp nsFontPath:(NSString*)nsFontPath isTemplate:(bool)isTemplate { - std::wstring from = NExtractTools::nsstring_to_wstring(nsFrom); - std::wstring to = NExtractTools::nsstring_to_wstring(nsTo); - std::wstring temp = NExtractTools::nsstring_to_wstring(nsTemp); - - NExtractTools::InputParams oInputParams; - oInputParams.m_sFontDir = new std::wstring(NExtractTools::nsstring_to_wstring(nsFontPath)); - oInputParams.m_bIsNoBase64 = new bool(self.isNoBase64); - - if (self.password) { - oInputParams.m_sPassword = new std::wstring(NExtractTools::nsstring_to_wstring(self.password)); - } - - return NExtractTools::__pptx2odp(from, to, temp, oInputParams, isTemplate); -} - -@end diff --git a/X2tConverter/build/Mac/X2tConverter/X2tConverter.xcodeproj/project.pbxproj b/X2tConverter/build/Mac/X2tConverter/X2tConverter.xcodeproj/project.pbxproj deleted file mode 100644 index 3c3b39ffada..00000000000 --- a/X2tConverter/build/Mac/X2tConverter/X2tConverter.xcodeproj/project.pbxproj +++ /dev/null @@ -1,1370 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXAggregateTarget section */ - 17C1E3E41AD40E2E001E3D18 /* X2tConverter_framework */ = { - isa = PBXAggregateTarget; - buildConfigurationList = 17C1E3E71AD40E2E001E3D18 /* Build configuration list for PBXAggregateTarget "X2tConverter_framework" */; - buildPhases = ( - 17C1E3E51AD40E2E001E3D18 /* ShellScript */, - ); - dependencies = ( - ); - name = X2tConverter_framework; - productName = Build_framework_ios; - }; -/* End PBXAggregateTarget section */ - -/* Begin PBXBuildFile section */ - 17C8DEC71ACD696100902C85 /* X2tConverter.mm in Sources */ = {isa = PBXBuildFile; fileRef = 17C27A191AC2DB3D00E1D003 /* X2tConverter.mm */; }; - 17C8DECC1ACD696100902C85 /* X2tConverter.h in Headers */ = {isa = PBXBuildFile; fileRef = 17C27A171AC2DB3D00E1D003 /* X2tConverter.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 6911A9691F6036DA0061AB4D /* OfficeFileErrorDescription.h in Headers */ = {isa = PBXBuildFile; fileRef = 6911A9681F6036DA0061AB4D /* OfficeFileErrorDescription.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 69415F271CB51C37003E771B /* libOfficeUtils.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 69415F241CB51C2A003E771B /* libOfficeUtils.a */; }; - 69415FE01CB52455003E771B /* libmng_ios.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 69415FD41CB5243F003E771B /* libmng_ios.a */; }; - 69415FE31CB52461003E771B /* libpng_ios.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 69415FD71CB5243F003E771B /* libpng_ios.a */; }; - 69415FE61CB52470003E771B /* libraw_ios.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 69415FDA1CB5243F003E771B /* libraw_ios.a */; }; - 69415FE91CB5247A003E771B /* libtiff_ios.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 69415FDD1CB5243F003E771B /* libtiff_ios.a */; }; - 69415FEC1CB52485003E771B /* liblibpsd_ios.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 69415FD11CB5243F003E771B /* liblibpsd_ios.a */; }; - 69415FEF1CB5248F003E771B /* libjpeg_ios.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 69415FCE1CB5243F003E771B /* libjpeg_ios.a */; }; - 69415FF21CB5249A003E771B /* libjbig_ios.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 69415FCB1CB5243F003E771B /* libjbig_ios.a */; }; - 69415FF51CB524A3003E771B /* libjasper_ios.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 69415FC81CB5243F003E771B /* libjasper_ios.a */; }; - 6967AFB01E2793A500A129E2 /* cextracttools.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6967AFAE1E2793A500A129E2 /* cextracttools.cpp */; }; - 6967AFB11E2793A500A129E2 /* cextracttools.h in Headers */ = {isa = PBXBuildFile; fileRef = 6967AFAF1E2793A500A129E2 /* cextracttools.h */; }; - 6967AFB51E27940600A129E2 /* ASCConverters.h in Headers */ = {isa = PBXBuildFile; fileRef = 6967AFB31E27940600A129E2 /* ASCConverters.h */; }; - 6967AFDF1E279B3600A129E2 /* libTxtXmlFormatLib.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6967AFDC1E279B2300A129E2 /* libTxtXmlFormatLib.a */; }; - 6967B0D41E27A36E00A129E2 /* libHtmlFile.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6967B0D11E27A35F00A129E2 /* libHtmlFile.a */; }; - 6967B10A1E27A41B00A129E2 /* libPdfWriter.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6967B1091E27A41400A129E2 /* libPdfWriter.a */; }; - 6967B10F1E27A65600A129E2 /* OfficeFileFormatChecker.h in Headers */ = {isa = PBXBuildFile; fileRef = 6967B10D1E27A65600A129E2 /* OfficeFileFormatChecker.h */; }; - 6967B1101E27A65600A129E2 /* OfficeFileFormatChecker2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6967B10E1E27A65600A129E2 /* OfficeFileFormatChecker2.cpp */; }; - 6967BEB01E27D16A00A129E2 /* ASCConverters_ios.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6967BEAF1E27D16A00A129E2 /* ASCConverters_ios.cpp */; }; - 69DA32F11CEE100E00E10AF0 /* libagg_ios.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 69DA323D1CEE092A00E10AF0 /* libagg_ios.a */; }; - 69DA32F21CEE100E00E10AF0 /* libcximage_ios.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 69DA322B1CEE087D00E10AF0 /* libcximage_ios.a */; }; - 69DA32F41CEE100E00E10AF0 /* libfontengine_ios.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 69DA32431CEE094300E10AF0 /* libfontengine_ios.a */; }; - 69DA32F51CEE100E00E10AF0 /* libfreetype_ios.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 69DA32551CEE095900E10AF0 /* libfreetype_ios.a */; }; - 69DA32F61CEE100E00E10AF0 /* libgraphics_ios.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 69DA324F1CEE095100E10AF0 /* libgraphics_ios.a */; }; - 69DA32F71CEE100E00E10AF0 /* libmetafile_ios.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 69DA32311CEE08DD00E10AF0 /* libmetafile_ios.a */; }; - 69DA32F91CEE100E00E10AF0 /* libraster_ios.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 69DA32491CEE094A00E10AF0 /* libraster_ios.a */; }; - 69EC66D91E01775B003527E2 /* libUnicodeConverter.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 69EC66D21E01770D003527E2 /* libUnicodeConverter.a */; }; - 8A35A6EE215E5F46005CC806 /* xmlutils.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A35A6EC215E5F46005CC806 /* xmlutils.h */; }; - 8A35A6F3215E5F62005CC806 /* xmldom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A35A6F0215E5F62005CC806 /* xmldom.cpp */; }; - 8A35A6F4215E5F62005CC806 /* xmllight_private.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A35A6F1215E5F62005CC806 /* xmllight_private.h */; }; - 8A35A6F5215E5F62005CC806 /* xmllight.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A35A6F2215E5F62005CC806 /* xmllight.cpp */; }; - 8ADB5F4220C52EFE00B72D37 /* version.h in Headers */ = {isa = PBXBuildFile; fileRef = 8ADB5F4120C52EFE00B72D37 /* version.h */; }; -/* End PBXBuildFile section */ - -/* Begin PBXContainerItemProxy section */ - 69415F231CB51C2A003E771B /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 69415F1F1CB51C29003E771B /* OfficeUtils.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 69676CA91CA58B7400D7A1D1; - remoteInfo = OfficeUtils; - }; - 69415F251CB51C32003E771B /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 69415F1F1CB51C29003E771B /* OfficeUtils.xcodeproj */; - proxyType = 1; - remoteGlobalIDString = 69676CA81CA58B7400D7A1D1; - remoteInfo = OfficeUtils; - }; - 69415FC71CB5243F003E771B /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 69415FC31CB5243F003E771B /* jasper.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 17C100EE1ACC4D64006B99B3; - remoteInfo = jasper; - }; - 69415FCA1CB5243F003E771B /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 69415FC01CB5243F003E771B /* jbig.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 17C100F91ACC4DCC006B99B3; - remoteInfo = jbig; - }; - 69415FCD1CB5243F003E771B /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 69415FBD1CB5243F003E771B /* jpeg.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 17C101511ACC4DFA006B99B3; - remoteInfo = jpeg; - }; - 69415FD01CB5243F003E771B /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 69415FBA1CB5243F003E771B /* libpsd.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 17C101981ACC4EF9006B99B3; - remoteInfo = libpsd; - }; - 69415FD31CB5243F003E771B /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 69415FAE1CB5243F003E771B /* mng.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 17C1022D1ACC4FE0006B99B3; - remoteInfo = mng; - }; - 69415FD61CB5243F003E771B /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 69415FB11CB5243F003E771B /* png.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 17C101FC1ACC4FB7006B99B3; - remoteInfo = png; - }; - 69415FD91CB5243F003E771B /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 69415FB41CB5243F003E771B /* raw.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 17C101DD1ACC4F80006B99B3; - remoteInfo = raw; - }; - 69415FDC1CB5243F003E771B /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 69415FB71CB5243F003E771B /* tiff.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 17C101D31ACC4F45006B99B3; - remoteInfo = tiff; - }; - 69415FDE1CB5244D003E771B /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 69415FAE1CB5243F003E771B /* mng.xcodeproj */; - proxyType = 1; - remoteGlobalIDString = 17C101FD1ACC4FE0006B99B3; - remoteInfo = mng; - }; - 69415FE11CB5245A003E771B /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 69415FB11CB5243F003E771B /* png.xcodeproj */; - proxyType = 1; - remoteGlobalIDString = 17C101DE1ACC4FB7006B99B3; - remoteInfo = png; - }; - 69415FE41CB5246B003E771B /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 69415FB41CB5243F003E771B /* raw.xcodeproj */; - proxyType = 1; - remoteGlobalIDString = 17C101D41ACC4F80006B99B3; - remoteInfo = raw; - }; - 69415FE71CB52475003E771B /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 69415FB71CB5243F003E771B /* tiff.xcodeproj */; - proxyType = 1; - remoteGlobalIDString = 17C101991ACC4F45006B99B3; - remoteInfo = tiff; - }; - 69415FEA1CB52480003E771B /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 69415FBA1CB5243F003E771B /* libpsd.xcodeproj */; - proxyType = 1; - remoteGlobalIDString = 17C101521ACC4EF9006B99B3; - remoteInfo = libpsd; - }; - 69415FED1CB5248B003E771B /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 69415FBD1CB5243F003E771B /* jpeg.xcodeproj */; - proxyType = 1; - remoteGlobalIDString = 17C100FA1ACC4DFA006B99B3; - remoteInfo = jpeg; - }; - 69415FF01CB52495003E771B /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 69415FC01CB5243F003E771B /* jbig.xcodeproj */; - proxyType = 1; - remoteGlobalIDString = 17C100EF1ACC4DCC006B99B3; - remoteInfo = jbig; - }; - 69415FF31CB5249E003E771B /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 69415FC31CB5243F003E771B /* jasper.xcodeproj */; - proxyType = 1; - remoteGlobalIDString = 17C100911ACC4D64006B99B3; - remoteInfo = jasper; - }; - 6967AFDB1E279B2300A129E2 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 6967AFD71E279B2300A129E2 /* TxtXmlFormatLib.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 6967AFBF1E2798B900A129E2; - remoteInfo = TxtXmlFormatLib; - }; - 6967AFDD1E279B2D00A129E2 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 6967AFD71E279B2300A129E2 /* TxtXmlFormatLib.xcodeproj */; - proxyType = 1; - remoteGlobalIDString = 6967AFBE1E2798B900A129E2; - remoteInfo = TxtXmlFormatLib; - }; - 6967B0D01E27A35F00A129E2 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 6967B0CC1E27A35E00A129E2 /* HtmlFile.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 6967B0BD1E27A22E00A129E2; - remoteInfo = HtmlFile; - }; - 6967B0D21E27A36800A129E2 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 6967B0CC1E27A35E00A129E2 /* HtmlFile.xcodeproj */; - proxyType = 1; - remoteGlobalIDString = 6967B0BC1E27A22E00A129E2; - remoteInfo = HtmlFile; - }; - 6967B1081E27A41400A129E2 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 6967B1031E27A41300A129E2 /* PdfWriter.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 7C560F6F1AA71A91000E5860; - remoteInfo = PdfWriter; - }; - 6967B10B1E27A42500A129E2 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 6967B1031E27A41300A129E2 /* PdfWriter.xcodeproj */; - proxyType = 1; - remoteGlobalIDString = 7C560F6E1AA71A91000E5860; - remoteInfo = PdfWriter; - }; - 69DA322A1CEE087D00E10AF0 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 69DA32261CEE087D00E10AF0 /* cximage.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 17C100221ACC4B40006B99B3; - remoteInfo = cximage; - }; - 69DA32301CEE08DD00E10AF0 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 69DA322C1CEE08DC00E10AF0 /* metafile.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 17A762DB1B0F355E0046BC0B; - remoteInfo = metafile; - }; - 69DA323C1CEE092A00E10AF0 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 69DA32381CEE092900E10AF0 /* agg.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 17C1FFC91ACC4B21006B99B3; - remoteInfo = agg; - }; - 69DA32421CEE094300E10AF0 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 69DA323E1CEE094300E10AF0 /* fontengine.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 17C1FF201ACC4AF7006B99B3; - remoteInfo = fontengine; - }; - 69DA32481CEE094A00E10AF0 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 69DA32441CEE094A00E10AF0 /* raster.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 17C1FF0A1ACC4AB0006B99B3; - remoteInfo = raster; - }; - 69DA324E1CEE095100E10AF0 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 69DA324A1CEE095000E10AF0 /* graphics.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 17C1FEFE1ACC4A67006B99B3; - remoteInfo = graphics; - }; - 69DA32541CEE095900E10AF0 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 69DA32501CEE095900E10AF0 /* freetype.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 17C1008A1ACC4BC4006B99B3; - remoteInfo = freetype; - }; - 69DA32D61CEE0FF300E10AF0 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 69DA324A1CEE095000E10AF0 /* graphics.xcodeproj */; - proxyType = 1; - remoteGlobalIDString = 17C1FECF1ACC4A67006B99B3; - remoteInfo = graphics; - }; - 69DA32E11CEE0FF600E10AF0 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 69DA32441CEE094A00E10AF0 /* raster.xcodeproj */; - proxyType = 1; - remoteGlobalIDString = 17C1FEFF1ACC4AB0006B99B3; - remoteInfo = raster; - }; - 69DA32E31CEE0FF800E10AF0 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 69DA323E1CEE094300E10AF0 /* fontengine.xcodeproj */; - proxyType = 1; - remoteGlobalIDString = 17C1FF0B1ACC4AF7006B99B3; - remoteInfo = fontengine; - }; - 69DA32E51CEE0FFB00E10AF0 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 69DA32381CEE092900E10AF0 /* agg.xcodeproj */; - proxyType = 1; - remoteGlobalIDString = 17C1FF211ACC4B21006B99B3; - remoteInfo = agg; - }; - 69DA32E71CEE0FFD00E10AF0 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 69DA322C1CEE08DC00E10AF0 /* metafile.xcodeproj */; - proxyType = 1; - remoteGlobalIDString = 17A762D41B0F355E0046BC0B; - remoteInfo = metafile; - }; - 69DA32E91CEE0FFF00E10AF0 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 69DA32261CEE087D00E10AF0 /* cximage.xcodeproj */; - proxyType = 1; - remoteGlobalIDString = 17C1FFCA1ACC4B40006B99B3; - remoteInfo = cximage; - }; - 69DA32EB1CEE100200E10AF0 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 69DA32501CEE095900E10AF0 /* freetype.xcodeproj */; - proxyType = 1; - remoteGlobalIDString = 17C100411ACC4BC4006B99B3; - remoteInfo = freetype; - }; - 69EC66D11E01770D003527E2 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 69EC66CD1E01770C003527E2 /* UnicodeConverter.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 69EC66C11E0176F2003527E2; - remoteInfo = UnicodeConverter; - }; - 69EC66D71E01774D003527E2 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 69EC66CD1E01770C003527E2 /* UnicodeConverter.xcodeproj */; - proxyType = 1; - remoteGlobalIDString = 69EC66C01E0176F2003527E2; - remoteInfo = UnicodeConverter; - }; -/* End PBXContainerItemProxy section */ - -/* Begin PBXFileReference section */ - 17C27A171AC2DB3D00E1D003 /* X2tConverter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = X2tConverter.h; sourceTree = ""; }; - 17C27A191AC2DB3D00E1D003 /* X2tConverter.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = X2tConverter.mm; sourceTree = ""; }; - 17C8DED01ACD696100902C85 /* libX2tConverter.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libX2tConverter.a; sourceTree = BUILT_PRODUCTS_DIR; }; - 6911A9681F6036DA0061AB4D /* OfficeFileErrorDescription.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OfficeFileErrorDescription.h; path = ../../../../../Common/OfficeFileErrorDescription.h; sourceTree = ""; }; - 69415F1F1CB51C29003E771B /* OfficeUtils.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = OfficeUtils.xcodeproj; path = ../../../../OfficeUtils/OfficeUtils.xcodeproj; sourceTree = ""; }; - 69415FAE1CB5243F003E771B /* mng.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = mng.xcodeproj; path = ../../../../DesktopEditor/mac_build/cximage/mng/mng.xcodeproj; sourceTree = ""; }; - 69415FB11CB5243F003E771B /* png.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = png.xcodeproj; path = ../../../../DesktopEditor/mac_build/cximage/png/png.xcodeproj; sourceTree = ""; }; - 69415FB41CB5243F003E771B /* raw.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = raw.xcodeproj; path = ../../../../DesktopEditor/mac_build/cximage/raw/raw.xcodeproj; sourceTree = ""; }; - 69415FB71CB5243F003E771B /* tiff.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = tiff.xcodeproj; path = ../../../../DesktopEditor/mac_build/cximage/tiff/tiff.xcodeproj; sourceTree = ""; }; - 69415FBA1CB5243F003E771B /* libpsd.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = libpsd.xcodeproj; path = ../../../../DesktopEditor/mac_build/cximage/libpsd/libpsd.xcodeproj; sourceTree = ""; }; - 69415FBD1CB5243F003E771B /* jpeg.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = jpeg.xcodeproj; path = ../../../../DesktopEditor/mac_build/cximage/jpeg/jpeg.xcodeproj; sourceTree = ""; }; - 69415FC01CB5243F003E771B /* jbig.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = jbig.xcodeproj; path = ../../../../DesktopEditor/mac_build/cximage/jbig/jbig.xcodeproj; sourceTree = ""; }; - 69415FC31CB5243F003E771B /* jasper.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = jasper.xcodeproj; path = ../../../../DesktopEditor/mac_build/cximage/jasper/jasper.xcodeproj; sourceTree = ""; }; - 6967AFAE1E2793A500A129E2 /* cextracttools.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = cextracttools.cpp; path = ../../../../src/cextracttools.cpp; sourceTree = ""; }; - 6967AFAF1E2793A500A129E2 /* cextracttools.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = cextracttools.h; path = ../../../../src/cextracttools.h; sourceTree = ""; }; - 6967AFB31E27940600A129E2 /* ASCConverters.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASCConverters.h; path = ../../../../src/ASCConverters.h; sourceTree = ""; }; - 6967AFD71E279B2300A129E2 /* TxtXmlFormatLib.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = TxtXmlFormatLib.xcodeproj; path = ../../../../ASCOfficeTxtFile/TxtXmlFormatLib/Mac/TxtXmlFormatLib/TxtXmlFormatLib.xcodeproj; sourceTree = ""; }; - 6967B0CC1E27A35E00A129E2 /* HtmlFile.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = HtmlFile.xcodeproj; path = ../../../../HtmlFile/Mac/HtmlFile/HtmlFile.xcodeproj; sourceTree = ""; }; - 6967B1031E27A41300A129E2 /* PdfWriter.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = PdfWriter.xcodeproj; path = ../../../../DesktopEditor/ios_projects/PdfWriter/PdfWriter.xcodeproj; sourceTree = ""; }; - 6967B10D1E27A65600A129E2 /* OfficeFileFormatChecker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OfficeFileFormatChecker.h; path = ../../../../../Common/OfficeFileFormatChecker.h; sourceTree = ""; }; - 6967B10E1E27A65600A129E2 /* OfficeFileFormatChecker2.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OfficeFileFormatChecker2.cpp; path = ../../../../../Common/OfficeFileFormatChecker2.cpp; sourceTree = ""; }; - 6967BEAF1E27D16A00A129E2 /* ASCConverters_ios.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ASCConverters_ios.cpp; path = ../../../../src/ASCConverters_ios.cpp; sourceTree = ""; }; - 696DD7C11F5D97DB0021D0F3 /* libcryptopp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libcryptopp.a; path = ../../../../Common/3dParty/cryptopp/libcryptopp.a; sourceTree = ""; }; - 69DA32261CEE087D00E10AF0 /* cximage.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = cximage.xcodeproj; path = ../../../../DesktopEditor/mac_build/cximage/cximage.xcodeproj; sourceTree = ""; }; - 69DA322C1CEE08DC00E10AF0 /* metafile.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = metafile.xcodeproj; path = ../../../../DesktopEditor/mac_build/metafile/metafile.xcodeproj; sourceTree = ""; }; - 69DA32381CEE092900E10AF0 /* agg.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = agg.xcodeproj; path = ../../../../DesktopEditor/mac_build/agg/agg.xcodeproj; sourceTree = ""; }; - 69DA323E1CEE094300E10AF0 /* fontengine.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = fontengine.xcodeproj; path = ../../../../DesktopEditor/mac_build/fontengine/fontengine.xcodeproj; sourceTree = ""; }; - 69DA32441CEE094A00E10AF0 /* raster.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = raster.xcodeproj; path = ../../../../DesktopEditor/mac_build/raster/raster.xcodeproj; sourceTree = ""; }; - 69DA324A1CEE095000E10AF0 /* graphics.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = graphics.xcodeproj; path = ../../../../DesktopEditor/mac_build/graphics/graphics.xcodeproj; sourceTree = ""; }; - 69DA32501CEE095900E10AF0 /* freetype.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = freetype.xcodeproj; path = ../../../../DesktopEditor/mac_build/freetype/freetype.xcodeproj; sourceTree = ""; }; - 69EC66CD1E01770C003527E2 /* UnicodeConverter.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = UnicodeConverter.xcodeproj; path = ../../../../UnicodeConverter/build/UnicodeConverter/UnicodeConverter.xcodeproj; sourceTree = ""; }; - 8A35A6EC215E5F46005CC806 /* xmlutils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = xmlutils.h; path = ../../../../../DesktopEditor/xml/include/xmlutils.h; sourceTree = ""; }; - 8A35A6F0215E5F62005CC806 /* xmldom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = xmldom.cpp; path = ../../../../../DesktopEditor/xml/src/xmldom.cpp; sourceTree = ""; }; - 8A35A6F1215E5F62005CC806 /* xmllight_private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = xmllight_private.h; path = ../../../../../DesktopEditor/xml/src/xmllight_private.h; sourceTree = ""; }; - 8A35A6F2215E5F62005CC806 /* xmllight.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = xmllight.cpp; path = ../../../../../DesktopEditor/xml/src/xmllight.cpp; sourceTree = ""; }; - 8AC4E6F022058B5A0044119A /* boost.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = boost.framework; path = ../../../../Common/3dParty/boost/ios/framework/boost.framework; sourceTree = ""; }; - 8ADB5F4120C52EFE00B72D37 /* version.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = version.h; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 17C8DEC81ACD696100902C85 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 6967B10A1E27A41B00A129E2 /* libPdfWriter.a in Frameworks */, - 6967B0D41E27A36E00A129E2 /* libHtmlFile.a in Frameworks */, - 6967AFDF1E279B3600A129E2 /* libTxtXmlFormatLib.a in Frameworks */, - 69EC66D91E01775B003527E2 /* libUnicodeConverter.a in Frameworks */, - 69DA32F11CEE100E00E10AF0 /* libagg_ios.a in Frameworks */, - 69DA32F21CEE100E00E10AF0 /* libcximage_ios.a in Frameworks */, - 69DA32F41CEE100E00E10AF0 /* libfontengine_ios.a in Frameworks */, - 69DA32F51CEE100E00E10AF0 /* libfreetype_ios.a in Frameworks */, - 69DA32F61CEE100E00E10AF0 /* libgraphics_ios.a in Frameworks */, - 69DA32F71CEE100E00E10AF0 /* libmetafile_ios.a in Frameworks */, - 69DA32F91CEE100E00E10AF0 /* libraster_ios.a in Frameworks */, - 69415FF51CB524A3003E771B /* libjasper_ios.a in Frameworks */, - 69415FF21CB5249A003E771B /* libjbig_ios.a in Frameworks */, - 69415FEF1CB5248F003E771B /* libjpeg_ios.a in Frameworks */, - 69415FEC1CB52485003E771B /* liblibpsd_ios.a in Frameworks */, - 69415FE91CB5247A003E771B /* libtiff_ios.a in Frameworks */, - 69415FE61CB52470003E771B /* libraw_ios.a in Frameworks */, - 69415FE31CB52461003E771B /* libpng_ios.a in Frameworks */, - 69415FE01CB52455003E771B /* libmng_ios.a in Frameworks */, - 69415F271CB51C37003E771B /* libOfficeUtils.a in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 17C27A0B1AC2DB3C00E1D003 = { - isa = PBXGroup; - children = ( - 6967B1031E27A41300A129E2 /* PdfWriter.xcodeproj */, - 6967B0CC1E27A35E00A129E2 /* HtmlFile.xcodeproj */, - 6967AFD71E279B2300A129E2 /* TxtXmlFormatLib.xcodeproj */, - 69EC66CD1E01770C003527E2 /* UnicodeConverter.xcodeproj */, - 69415FAE1CB5243F003E771B /* mng.xcodeproj */, - 69415FB11CB5243F003E771B /* png.xcodeproj */, - 69415FB41CB5243F003E771B /* raw.xcodeproj */, - 69415FB71CB5243F003E771B /* tiff.xcodeproj */, - 69415FBA1CB5243F003E771B /* libpsd.xcodeproj */, - 69415FBD1CB5243F003E771B /* jpeg.xcodeproj */, - 69415FC01CB5243F003E771B /* jbig.xcodeproj */, - 69415FC31CB5243F003E771B /* jasper.xcodeproj */, - 69DA324A1CEE095000E10AF0 /* graphics.xcodeproj */, - 69DA32441CEE094A00E10AF0 /* raster.xcodeproj */, - 69DA323E1CEE094300E10AF0 /* fontengine.xcodeproj */, - 69DA32381CEE092900E10AF0 /* agg.xcodeproj */, - 69DA322C1CEE08DC00E10AF0 /* metafile.xcodeproj */, - 69DA32261CEE087D00E10AF0 /* cximage.xcodeproj */, - 69DA32501CEE095900E10AF0 /* freetype.xcodeproj */, - 69415F1F1CB51C29003E771B /* OfficeUtils.xcodeproj */, - 17C27A161AC2DB3C00E1D003 /* SDK */, - 17C27A151AC2DB3C00E1D003 /* Products */, - 696DD7C01F5D97DB0021D0F3 /* Frameworks */, - ); - sourceTree = ""; - }; - 17C27A151AC2DB3C00E1D003 /* Products */ = { - isa = PBXGroup; - children = ( - 17C8DED01ACD696100902C85 /* libX2tConverter.a */, - ); - name = Products; - sourceTree = ""; - }; - 17C27A161AC2DB3C00E1D003 /* SDK */ = { - isa = PBXGroup; - children = ( - 6967AFA51E27918600A129E2 /* src */, - 8ADB5F4120C52EFE00B72D37 /* version.h */, - 17C27A171AC2DB3D00E1D003 /* X2tConverter.h */, - 17C27A191AC2DB3D00E1D003 /* X2tConverter.mm */, - ); - name = SDK; - path = X2tConverter; - sourceTree = ""; - }; - 69415F201CB51C29003E771B /* Products */ = { - isa = PBXGroup; - children = ( - 69415F241CB51C2A003E771B /* libOfficeUtils.a */, - ); - name = Products; - sourceTree = ""; - }; - 69415FAF1CB5243F003E771B /* Products */ = { - isa = PBXGroup; - children = ( - 69415FD41CB5243F003E771B /* libmng_ios.a */, - ); - name = Products; - sourceTree = ""; - }; - 69415FB21CB5243F003E771B /* Products */ = { - isa = PBXGroup; - children = ( - 69415FD71CB5243F003E771B /* libpng_ios.a */, - ); - name = Products; - sourceTree = ""; - }; - 69415FB51CB5243F003E771B /* Products */ = { - isa = PBXGroup; - children = ( - 69415FDA1CB5243F003E771B /* libraw_ios.a */, - ); - name = Products; - sourceTree = ""; - }; - 69415FB81CB5243F003E771B /* Products */ = { - isa = PBXGroup; - children = ( - 69415FDD1CB5243F003E771B /* libtiff_ios.a */, - ); - name = Products; - sourceTree = ""; - }; - 69415FBB1CB5243F003E771B /* Products */ = { - isa = PBXGroup; - children = ( - 69415FD11CB5243F003E771B /* liblibpsd_ios.a */, - ); - name = Products; - sourceTree = ""; - }; - 69415FBE1CB5243F003E771B /* Products */ = { - isa = PBXGroup; - children = ( - 69415FCE1CB5243F003E771B /* libjpeg_ios.a */, - ); - name = Products; - sourceTree = ""; - }; - 69415FC11CB5243F003E771B /* Products */ = { - isa = PBXGroup; - children = ( - 69415FCB1CB5243F003E771B /* libjbig_ios.a */, - ); - name = Products; - sourceTree = ""; - }; - 69415FC41CB5243F003E771B /* Products */ = { - isa = PBXGroup; - children = ( - 69415FC81CB5243F003E771B /* libjasper_ios.a */, - ); - name = Products; - sourceTree = ""; - }; - 6967AFA51E27918600A129E2 /* src */ = { - isa = PBXGroup; - children = ( - 8A35A6EF215E5F4A005CC806 /* XmlUtils */, - 6967B1181E27A9D500A129E2 /* OfficeFileFormatChecker */, - 6911A9681F6036DA0061AB4D /* OfficeFileErrorDescription.h */, - 6967BEAF1E27D16A00A129E2 /* ASCConverters_ios.cpp */, - 6967AFB31E27940600A129E2 /* ASCConverters.h */, - 6967AFAE1E2793A500A129E2 /* cextracttools.cpp */, - 6967AFAF1E2793A500A129E2 /* cextracttools.h */, - ); - name = src; - sourceTree = ""; - }; - 6967AFD81E279B2300A129E2 /* Products */ = { - isa = PBXGroup; - children = ( - 6967AFDC1E279B2300A129E2 /* libTxtXmlFormatLib.a */, - ); - name = Products; - sourceTree = ""; - }; - 6967B0CD1E27A35E00A129E2 /* Products */ = { - isa = PBXGroup; - children = ( - 6967B0D11E27A35F00A129E2 /* libHtmlFile.a */, - ); - name = Products; - sourceTree = ""; - }; - 6967B1041E27A41300A129E2 /* Products */ = { - isa = PBXGroup; - children = ( - 6967B1091E27A41400A129E2 /* libPdfWriter.a */, - ); - name = Products; - sourceTree = ""; - }; - 6967B1181E27A9D500A129E2 /* OfficeFileFormatChecker */ = { - isa = PBXGroup; - children = ( - 6967B10D1E27A65600A129E2 /* OfficeFileFormatChecker.h */, - 6967B10E1E27A65600A129E2 /* OfficeFileFormatChecker2.cpp */, - ); - name = OfficeFileFormatChecker; - sourceTree = ""; - }; - 696DD7C01F5D97DB0021D0F3 /* Frameworks */ = { - isa = PBXGroup; - children = ( - 8AC4E6F022058B5A0044119A /* boost.framework */, - 696DD7C11F5D97DB0021D0F3 /* libcryptopp.a */, - ); - name = Frameworks; - sourceTree = ""; - }; - 69DA32271CEE087D00E10AF0 /* Products */ = { - isa = PBXGroup; - children = ( - 69DA322B1CEE087D00E10AF0 /* libcximage_ios.a */, - ); - name = Products; - sourceTree = ""; - }; - 69DA322D1CEE08DC00E10AF0 /* Products */ = { - isa = PBXGroup; - children = ( - 69DA32311CEE08DD00E10AF0 /* libmetafile_ios.a */, - ); - name = Products; - sourceTree = ""; - }; - 69DA32391CEE092900E10AF0 /* Products */ = { - isa = PBXGroup; - children = ( - 69DA323D1CEE092A00E10AF0 /* libagg_ios.a */, - ); - name = Products; - sourceTree = ""; - }; - 69DA323F1CEE094300E10AF0 /* Products */ = { - isa = PBXGroup; - children = ( - 69DA32431CEE094300E10AF0 /* libfontengine_ios.a */, - ); - name = Products; - sourceTree = ""; - }; - 69DA32451CEE094A00E10AF0 /* Products */ = { - isa = PBXGroup; - children = ( - 69DA32491CEE094A00E10AF0 /* libraster_ios.a */, - ); - name = Products; - sourceTree = ""; - }; - 69DA324B1CEE095000E10AF0 /* Products */ = { - isa = PBXGroup; - children = ( - 69DA324F1CEE095100E10AF0 /* libgraphics_ios.a */, - ); - name = Products; - sourceTree = ""; - }; - 69DA32511CEE095900E10AF0 /* Products */ = { - isa = PBXGroup; - children = ( - 69DA32551CEE095900E10AF0 /* libfreetype_ios.a */, - ); - name = Products; - sourceTree = ""; - }; - 69EC66CE1E01770C003527E2 /* Products */ = { - isa = PBXGroup; - children = ( - 69EC66D21E01770D003527E2 /* libUnicodeConverter.a */, - ); - name = Products; - sourceTree = ""; - }; - 8A35A6EF215E5F4A005CC806 /* XmlUtils */ = { - isa = PBXGroup; - children = ( - 8A35A6F0215E5F62005CC806 /* xmldom.cpp */, - 8A35A6F1215E5F62005CC806 /* xmllight_private.h */, - 8A35A6F2215E5F62005CC806 /* xmllight.cpp */, - 8A35A6EC215E5F46005CC806 /* xmlutils.h */, - ); - name = XmlUtils; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXHeadersBuildPhase section */ - 17C8DECB1ACD696100902C85 /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - 6967AFB11E2793A500A129E2 /* cextracttools.h in Headers */, - 8ADB5F4220C52EFE00B72D37 /* version.h in Headers */, - 6911A9691F6036DA0061AB4D /* OfficeFileErrorDescription.h in Headers */, - 8A35A6F4215E5F62005CC806 /* xmllight_private.h in Headers */, - 8A35A6EE215E5F46005CC806 /* xmlutils.h in Headers */, - 6967B10F1E27A65600A129E2 /* OfficeFileFormatChecker.h in Headers */, - 6967AFB51E27940600A129E2 /* ASCConverters.h in Headers */, - 17C8DECC1ACD696100902C85 /* X2tConverter.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXHeadersBuildPhase section */ - -/* Begin PBXNativeTarget section */ - 17C8DEC11ACD696100902C85 /* x2tconverter */ = { - isa = PBXNativeTarget; - buildConfigurationList = 17C8DECD1ACD696100902C85 /* Build configuration list for PBXNativeTarget "x2tconverter" */; - buildPhases = ( - 17C8DEC61ACD696100902C85 /* Sources */, - 17C8DEC81ACD696100902C85 /* Frameworks */, - 17C8DECB1ACD696100902C85 /* Headers */, - 8ADB5F4420C52F6E00B72D37 /* ShellScript */, - ); - buildRules = ( - ); - dependencies = ( - 6967B10C1E27A42500A129E2 /* PBXTargetDependency */, - 6967B0D31E27A36800A129E2 /* PBXTargetDependency */, - 6967AFDE1E279B2D00A129E2 /* PBXTargetDependency */, - 69EC66D81E01774D003527E2 /* PBXTargetDependency */, - 69415F261CB51C32003E771B /* PBXTargetDependency */, - 69DA32E81CEE0FFD00E10AF0 /* PBXTargetDependency */, - 69DA32EC1CEE100200E10AF0 /* PBXTargetDependency */, - 69DA32EA1CEE0FFF00E10AF0 /* PBXTargetDependency */, - 69DA32E61CEE0FFB00E10AF0 /* PBXTargetDependency */, - 69DA32E41CEE0FF800E10AF0 /* PBXTargetDependency */, - 69DA32E21CEE0FF600E10AF0 /* PBXTargetDependency */, - 69DA32D71CEE0FF300E10AF0 /* PBXTargetDependency */, - 69415FF41CB5249E003E771B /* PBXTargetDependency */, - 69415FF11CB52495003E771B /* PBXTargetDependency */, - 69415FEE1CB5248B003E771B /* PBXTargetDependency */, - 69415FEB1CB52480003E771B /* PBXTargetDependency */, - 69415FE81CB52475003E771B /* PBXTargetDependency */, - 69415FE51CB5246B003E771B /* PBXTargetDependency */, - 69415FE21CB5245A003E771B /* PBXTargetDependency */, - 69415FDF1CB5244D003E771B /* PBXTargetDependency */, - ); - name = x2tconverter; - productName = X2tConverter; - productReference = 17C8DED01ACD696100902C85 /* libX2tConverter.a */; - productType = "com.apple.product-type.library.static"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 17C27A0C1AC2DB3C00E1D003 /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 0930; - ORGANIZATIONNAME = "Ascensio System SIA"; - }; - buildConfigurationList = 17C27A0F1AC2DB3C00E1D003 /* Build configuration list for PBXProject "X2tConverter" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 0; - knownRegions = ( - English, - en, - ); - mainGroup = 17C27A0B1AC2DB3C00E1D003; - productRefGroup = 17C27A151AC2DB3C00E1D003 /* Products */; - projectDirPath = ""; - projectReferences = ( - { - ProductGroup = 69DA32391CEE092900E10AF0 /* Products */; - ProjectRef = 69DA32381CEE092900E10AF0 /* agg.xcodeproj */; - }, - { - ProductGroup = 69DA32271CEE087D00E10AF0 /* Products */; - ProjectRef = 69DA32261CEE087D00E10AF0 /* cximage.xcodeproj */; - }, - { - ProductGroup = 69DA323F1CEE094300E10AF0 /* Products */; - ProjectRef = 69DA323E1CEE094300E10AF0 /* fontengine.xcodeproj */; - }, - { - ProductGroup = 69DA32511CEE095900E10AF0 /* Products */; - ProjectRef = 69DA32501CEE095900E10AF0 /* freetype.xcodeproj */; - }, - { - ProductGroup = 69DA324B1CEE095000E10AF0 /* Products */; - ProjectRef = 69DA324A1CEE095000E10AF0 /* graphics.xcodeproj */; - }, - { - ProductGroup = 6967B0CD1E27A35E00A129E2 /* Products */; - ProjectRef = 6967B0CC1E27A35E00A129E2 /* HtmlFile.xcodeproj */; - }, - { - ProductGroup = 69415FC41CB5243F003E771B /* Products */; - ProjectRef = 69415FC31CB5243F003E771B /* jasper.xcodeproj */; - }, - { - ProductGroup = 69415FC11CB5243F003E771B /* Products */; - ProjectRef = 69415FC01CB5243F003E771B /* jbig.xcodeproj */; - }, - { - ProductGroup = 69415FBE1CB5243F003E771B /* Products */; - ProjectRef = 69415FBD1CB5243F003E771B /* jpeg.xcodeproj */; - }, - { - ProductGroup = 69415FBB1CB5243F003E771B /* Products */; - ProjectRef = 69415FBA1CB5243F003E771B /* libpsd.xcodeproj */; - }, - { - ProductGroup = 69DA322D1CEE08DC00E10AF0 /* Products */; - ProjectRef = 69DA322C1CEE08DC00E10AF0 /* metafile.xcodeproj */; - }, - { - ProductGroup = 69415FAF1CB5243F003E771B /* Products */; - ProjectRef = 69415FAE1CB5243F003E771B /* mng.xcodeproj */; - }, - { - ProductGroup = 69415F201CB51C29003E771B /* Products */; - ProjectRef = 69415F1F1CB51C29003E771B /* OfficeUtils.xcodeproj */; - }, - { - ProductGroup = 6967B1041E27A41300A129E2 /* Products */; - ProjectRef = 6967B1031E27A41300A129E2 /* PdfWriter.xcodeproj */; - }, - { - ProductGroup = 69415FB21CB5243F003E771B /* Products */; - ProjectRef = 69415FB11CB5243F003E771B /* png.xcodeproj */; - }, - { - ProductGroup = 69DA32451CEE094A00E10AF0 /* Products */; - ProjectRef = 69DA32441CEE094A00E10AF0 /* raster.xcodeproj */; - }, - { - ProductGroup = 69415FB51CB5243F003E771B /* Products */; - ProjectRef = 69415FB41CB5243F003E771B /* raw.xcodeproj */; - }, - { - ProductGroup = 69415FB81CB5243F003E771B /* Products */; - ProjectRef = 69415FB71CB5243F003E771B /* tiff.xcodeproj */; - }, - { - ProductGroup = 6967AFD81E279B2300A129E2 /* Products */; - ProjectRef = 6967AFD71E279B2300A129E2 /* TxtXmlFormatLib.xcodeproj */; - }, - { - ProductGroup = 69EC66CE1E01770C003527E2 /* Products */; - ProjectRef = 69EC66CD1E01770C003527E2 /* UnicodeConverter.xcodeproj */; - }, - ); - projectRoot = ""; - targets = ( - 17C8DEC11ACD696100902C85 /* x2tconverter */, - 17C1E3E41AD40E2E001E3D18 /* X2tConverter_framework */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXReferenceProxy section */ - 69415F241CB51C2A003E771B /* libOfficeUtils.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libOfficeUtils.a; - remoteRef = 69415F231CB51C2A003E771B /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 69415FC81CB5243F003E771B /* libjasper_ios.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libjasper_ios.a; - remoteRef = 69415FC71CB5243F003E771B /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 69415FCB1CB5243F003E771B /* libjbig_ios.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libjbig_ios.a; - remoteRef = 69415FCA1CB5243F003E771B /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 69415FCE1CB5243F003E771B /* libjpeg_ios.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libjpeg_ios.a; - remoteRef = 69415FCD1CB5243F003E771B /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 69415FD11CB5243F003E771B /* liblibpsd_ios.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = liblibpsd_ios.a; - remoteRef = 69415FD01CB5243F003E771B /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 69415FD41CB5243F003E771B /* libmng_ios.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libmng_ios.a; - remoteRef = 69415FD31CB5243F003E771B /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 69415FD71CB5243F003E771B /* libpng_ios.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libpng_ios.a; - remoteRef = 69415FD61CB5243F003E771B /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 69415FDA1CB5243F003E771B /* libraw_ios.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libraw_ios.a; - remoteRef = 69415FD91CB5243F003E771B /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 69415FDD1CB5243F003E771B /* libtiff_ios.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libtiff_ios.a; - remoteRef = 69415FDC1CB5243F003E771B /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 6967AFDC1E279B2300A129E2 /* libTxtXmlFormatLib.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libTxtXmlFormatLib.a; - remoteRef = 6967AFDB1E279B2300A129E2 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 6967B0D11E27A35F00A129E2 /* libHtmlFile.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libHtmlFile.a; - remoteRef = 6967B0D01E27A35F00A129E2 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 6967B1091E27A41400A129E2 /* libPdfWriter.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libPdfWriter.a; - remoteRef = 6967B1081E27A41400A129E2 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 69DA322B1CEE087D00E10AF0 /* libcximage_ios.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libcximage_ios.a; - remoteRef = 69DA322A1CEE087D00E10AF0 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 69DA32311CEE08DD00E10AF0 /* libmetafile_ios.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libmetafile_ios.a; - remoteRef = 69DA32301CEE08DD00E10AF0 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 69DA323D1CEE092A00E10AF0 /* libagg_ios.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libagg_ios.a; - remoteRef = 69DA323C1CEE092A00E10AF0 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 69DA32431CEE094300E10AF0 /* libfontengine_ios.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libfontengine_ios.a; - remoteRef = 69DA32421CEE094300E10AF0 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 69DA32491CEE094A00E10AF0 /* libraster_ios.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libraster_ios.a; - remoteRef = 69DA32481CEE094A00E10AF0 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 69DA324F1CEE095100E10AF0 /* libgraphics_ios.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libgraphics_ios.a; - remoteRef = 69DA324E1CEE095100E10AF0 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 69DA32551CEE095900E10AF0 /* libfreetype_ios.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libfreetype_ios.a; - remoteRef = 69DA32541CEE095900E10AF0 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 69EC66D21E01770D003527E2 /* libUnicodeConverter.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libUnicodeConverter.a; - remoteRef = 69EC66D11E01770D003527E2 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; -/* End PBXReferenceProxy section */ - -/* Begin PBXShellScriptBuildPhase section */ - 17C1E3E51AD40E2E001E3D18 /* ShellScript */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "SIMULATOR_LIBRARY_PATH=\"${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/lib${PROJECT_NAME}.a\" &&\nDEVICE_LIBRARY_PATH=\"${BUILD_DIR}/${CONFIGURATION}-iphoneos/lib${PROJECT_NAME}.a\" &&\nUNIVERSAL_LIBRARY_DIR=\"${BUILD_DIR}/${CONFIGURATION}-iphoneuniversal\" &&\nFRAMEWORK=\"${BUILD_DIR}/${CONFIGURATION}-iphoneuniversal/${PROJECT_NAME}.framework\" &&\n\n# Create framework directory structure.\nrm -rf \"${FRAMEWORK}\" &&\nmkdir -p \"${UNIVERSAL_LIBRARY_DIR}\" &&\n\n# Generate universal binary for the device and simulator.\nlipo \"${SIMULATOR_LIBRARY_PATH}\" \"${DEVICE_LIBRARY_PATH}\" -create -output \"${FRAMEWORK}\""; - }; - 8ADB5F4420C52F6E00B72D37 /* ShellScript */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "VERSION=$(cat \"../../../../Common/version.txt\")\n\necho \"#ifndef X2T_VERSION_H\n#define X2T_VERSION_H\n\n#define X2T_VERSION \\\"$VERSION\\\"\n\n#endif\" > \"X2tConverter/version.h\"\n\n"; - }; -/* End PBXShellScriptBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 17C8DEC61ACD696100902C85 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 17C8DEC71ACD696100902C85 /* X2tConverter.mm in Sources */, - 6967B1101E27A65600A129E2 /* OfficeFileFormatChecker2.cpp in Sources */, - 8A35A6F3215E5F62005CC806 /* xmldom.cpp in Sources */, - 6967BEB01E27D16A00A129E2 /* ASCConverters_ios.cpp in Sources */, - 8A35A6F5215E5F62005CC806 /* xmllight.cpp in Sources */, - 6967AFB01E2793A500A129E2 /* cextracttools.cpp in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXTargetDependency section */ - 69415F261CB51C32003E771B /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = OfficeUtils; - targetProxy = 69415F251CB51C32003E771B /* PBXContainerItemProxy */; - }; - 69415FDF1CB5244D003E771B /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = mng; - targetProxy = 69415FDE1CB5244D003E771B /* PBXContainerItemProxy */; - }; - 69415FE21CB5245A003E771B /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = png; - targetProxy = 69415FE11CB5245A003E771B /* PBXContainerItemProxy */; - }; - 69415FE51CB5246B003E771B /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = raw; - targetProxy = 69415FE41CB5246B003E771B /* PBXContainerItemProxy */; - }; - 69415FE81CB52475003E771B /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = tiff; - targetProxy = 69415FE71CB52475003E771B /* PBXContainerItemProxy */; - }; - 69415FEB1CB52480003E771B /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = libpsd; - targetProxy = 69415FEA1CB52480003E771B /* PBXContainerItemProxy */; - }; - 69415FEE1CB5248B003E771B /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = jpeg; - targetProxy = 69415FED1CB5248B003E771B /* PBXContainerItemProxy */; - }; - 69415FF11CB52495003E771B /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = jbig; - targetProxy = 69415FF01CB52495003E771B /* PBXContainerItemProxy */; - }; - 69415FF41CB5249E003E771B /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = jasper; - targetProxy = 69415FF31CB5249E003E771B /* PBXContainerItemProxy */; - }; - 6967AFDE1E279B2D00A129E2 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = TxtXmlFormatLib; - targetProxy = 6967AFDD1E279B2D00A129E2 /* PBXContainerItemProxy */; - }; - 6967B0D31E27A36800A129E2 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = HtmlFile; - targetProxy = 6967B0D21E27A36800A129E2 /* PBXContainerItemProxy */; - }; - 6967B10C1E27A42500A129E2 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = PdfWriter; - targetProxy = 6967B10B1E27A42500A129E2 /* PBXContainerItemProxy */; - }; - 69DA32D71CEE0FF300E10AF0 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = graphics; - targetProxy = 69DA32D61CEE0FF300E10AF0 /* PBXContainerItemProxy */; - }; - 69DA32E21CEE0FF600E10AF0 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = raster; - targetProxy = 69DA32E11CEE0FF600E10AF0 /* PBXContainerItemProxy */; - }; - 69DA32E41CEE0FF800E10AF0 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = fontengine; - targetProxy = 69DA32E31CEE0FF800E10AF0 /* PBXContainerItemProxy */; - }; - 69DA32E61CEE0FFB00E10AF0 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = agg; - targetProxy = 69DA32E51CEE0FFB00E10AF0 /* PBXContainerItemProxy */; - }; - 69DA32E81CEE0FFD00E10AF0 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = metafile; - targetProxy = 69DA32E71CEE0FFD00E10AF0 /* PBXContainerItemProxy */; - }; - 69DA32EA1CEE0FFF00E10AF0 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = cximage; - targetProxy = 69DA32E91CEE0FFF00E10AF0 /* PBXContainerItemProxy */; - }; - 69DA32EC1CEE100200E10AF0 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = freetype; - targetProxy = 69DA32EB1CEE100200E10AF0 /* PBXContainerItemProxy */; - }; - 69EC66D81E01774D003527E2 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = UnicodeConverter; - targetProxy = 69EC66D71E01774D003527E2 /* PBXContainerItemProxy */; - }; -/* End PBXTargetDependency section */ - -/* Begin XCBuildConfiguration section */ - 17C1E3E81AD40E2E001E3D18 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - PRODUCT_NAME = X2tConverter; - }; - name = Debug; - }; - 17C1E3E91AD40E2E001E3D18 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - PRODUCT_NAME = X2tConverter; - }; - name = Release; - }; - 17C27A261AC2DB3F00E1D003 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COPY_PHASE_STRIP = NO; - ENABLE_BITCODE = YES; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_SYMBOLS_PRIVATE_EXTERN = NO; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 10.0; - MACOSX_DEPLOYMENT_TARGET = 10.10; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = macosx; - }; - name = Debug; - }; - 17C27A271AC2DB3F00E1D003 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_BITCODE = YES; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 10.0; - MACOSX_DEPLOYMENT_TARGET = 10.10; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = macosx; - }; - name = Release; - }; - 17C8DECE1ACD696100902C85 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)"; - ENABLE_BITCODE = YES; - EXECUTABLE_PREFIX = lib; - GCC_PREPROCESSOR_DEFINITIONS = ( - UNICODE, - _UNICODE, - PPTX_DEF, - PPT_DEF, - ENABLE_PPT_TO_PPTX_CONVERT, - NODOCX, - FILTER_FLATE_DECODE_ENABLED, - CXIMAGE_DONT_DECLARE_TCHAR, - BUILD_CONFIG_FULL_VERSION, - DONT_WRITE_EMBEDDED_FONTS, - AVS_USE_CONVERT_PPTX_TOCUSTOM_VML, - unix, - MAC, - _IOS, - ); - HEADER_SEARCH_PATHS = ( - "$(inherited)", - /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, - /usr/include/libxml2, - "$(PROJECT_DIR)/../../../../DesktopEditor/freetype-2.5.2/include", - "$(PROJECT_DIR)/../../../../DesktopEditor/agg-2.4/include", - "$(PROJECT_DIR)/../../../../Common/3dParty/boost/boost_1_58_0", - "$(PROJECT_DIR)/../../../../ASCOfficeOdfFile/include", - "$(PROJECT_DIR)/../../../../ASCOfficeOdfFile/src/odf/datatypes", - ); - IPHONEOS_DEPLOYMENT_TARGET = 10.0; - ONLY_ACTIVE_ARCH = YES; - OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)"; - OTHER_LDFLAGS = ( - "-ObjC", - "-lc++", - ); - PRODUCT_NAME = X2tConverter; - PUBLIC_HEADERS_FOLDER_PATH = ../include; - SDKROOT = iphoneos; - VALID_ARCHS = "arm64 armv7 armv7s i386 x86_64"; - }; - name = Debug; - }; - 17C8DECF1ACD696100902C85 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)"; - ENABLE_BITCODE = YES; - EXECUTABLE_PREFIX = lib; - GCC_PREPROCESSOR_DEFINITIONS = ( - UNICODE, - _UNICODE, - PPTX_DEF, - PPT_DEF, - ENABLE_PPT_TO_PPTX_CONVERT, - NODOCX, - FILTER_FLATE_DECODE_ENABLED, - CXIMAGE_DONT_DECLARE_TCHAR, - BUILD_CONFIG_FULL_VERSION, - DONT_WRITE_EMBEDDED_FONTS, - AVS_USE_CONVERT_PPTX_TOCUSTOM_VML, - unix, - MAC, - _IOS, - ); - HEADER_SEARCH_PATHS = ( - "$(inherited)", - /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, - /usr/include/libxml2, - "$(PROJECT_DIR)/../../../../DesktopEditor/freetype-2.5.2/include", - "$(PROJECT_DIR)/../../../../DesktopEditor/agg-2.4/include", - "$(PROJECT_DIR)/../../../../Common/3dParty/boost/boost_1_58_0", - "$(PROJECT_DIR)/../../../../ASCOfficeOdfFile/include", - "$(PROJECT_DIR)/../../../../ASCOfficeOdfFile/src/odf/datatypes", - ); - IPHONEOS_DEPLOYMENT_TARGET = 10.0; - OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)"; - OTHER_LDFLAGS = ( - "-ObjC", - "-lc++", - ); - PRODUCT_NAME = X2tConverter; - PUBLIC_HEADERS_FOLDER_PATH = ../include; - SDKROOT = iphoneos; - VALID_ARCHS = "arm64 armv7 armv7s i386 x86_64"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 17C1E3E71AD40E2E001E3D18 /* Build configuration list for PBXAggregateTarget "X2tConverter_framework" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 17C1E3E81AD40E2E001E3D18 /* Debug */, - 17C1E3E91AD40E2E001E3D18 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 17C27A0F1AC2DB3C00E1D003 /* Build configuration list for PBXProject "X2tConverter" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 17C27A261AC2DB3F00E1D003 /* Debug */, - 17C27A271AC2DB3F00E1D003 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 17C8DECD1ACD696100902C85 /* Build configuration list for PBXNativeTarget "x2tconverter" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 17C8DECE1ACD696100902C85 /* Debug */, - 17C8DECF1ACD696100902C85 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 17C27A0C1AC2DB3C00E1D003 /* Project object */; -} diff --git a/X2tConverter/build/Mac/X2tConverter/X2tConverter.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/X2tConverter/build/Mac/X2tConverter/X2tConverter.xcodeproj/project.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index db8a90d8cd9..00000000000 --- a/X2tConverter/build/Mac/X2tConverter/X2tConverter.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/X2tConverter/build/Mac/X2tConverter/X2tConverter.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/X2tConverter/build/Mac/X2tConverter/X2tConverter.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist deleted file mode 100644 index 18d981003d6..00000000000 --- a/X2tConverter/build/Mac/X2tConverter/X2tConverter.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +++ /dev/null @@ -1,8 +0,0 @@ - - - - - IDEDidComputeMac32BitWarning - - - diff --git a/X2tConverter/build/Mac/X2tConverter/X2tConverter.xcodeproj/project.xcworkspace/xcuserdata/alexey.musinov.xcuserdatad/UserInterfaceState.xcuserstate b/X2tConverter/build/Mac/X2tConverter/X2tConverter.xcodeproj/project.xcworkspace/xcuserdata/alexey.musinov.xcuserdatad/UserInterfaceState.xcuserstate deleted file mode 100644 index da80b74589f..00000000000 Binary files a/X2tConverter/build/Mac/X2tConverter/X2tConverter.xcodeproj/project.xcworkspace/xcuserdata/alexey.musinov.xcuserdatad/UserInterfaceState.xcuserstate and /dev/null differ diff --git a/X2tConverter/build/Mac/X2tConverter/X2tConverter.xcodeproj/xcuserdata/alexey.musinov.xcuserdatad/xcschemes/xcschememanagement.plist b/X2tConverter/build/Mac/X2tConverter/X2tConverter.xcodeproj/xcuserdata/alexey.musinov.xcuserdatad/xcschemes/xcschememanagement.plist deleted file mode 100644 index 5defde399db..00000000000 --- a/X2tConverter/build/Mac/X2tConverter/X2tConverter.xcodeproj/xcuserdata/alexey.musinov.xcuserdatad/xcschemes/xcschememanagement.plist +++ /dev/null @@ -1,102 +0,0 @@ - - - - - SchemeUserState - - Build_framework_ios.xcscheme - - orderHint - 44 - - X2tConverter.xcscheme - - orderHint - 20 - - X2tConverter_framework.xcscheme - - orderHint - 21 - - X2tConverter_ios.xcscheme - - orderHint - 43 - - X2tConverter_mac.xcscheme - - orderHint - 42 - - - SuppressBuildableAutocreation - - 171E6AC11ACD5599005B8529 - - primary - - - 171E6ACB1ACD55FE005B8529 - - primary - - - 171E6ADE1ACD5617005B8529 - - primary - - - 17C1E3E41AD40E2E001E3D18 - - primary - - - 17C27A131AC2DB3C00E1D003 - - primary - - - 17C27A1E1AC2DB3F00E1D003 - - primary - - - 17C27A2E1AC2DC5D00E1D003 - - primary - - - 17C8DEC11ACD696100902C85 - - primary - - - 17DAB6A71ACC3790005AF479 - - primary - - - 17DAB6B71ACC37A8005AF479 - - primary - - - 17DAB6CA1ACC37C5005AF479 - - primary - - - 17DAB6D41ACC37C5005AF479 - - primary - - - 17DAB6E21ACC3840005AF479 - - primary - - - - - diff --git a/X2tConverter/build/Mac/X2tConverter/X2tConverter/X2tConverter.h b/X2tConverter/build/Mac/X2tConverter/X2tConverter/X2tConverter.h deleted file mode 100644 index efff0f690e0..00000000000 --- a/X2tConverter/build/Mac/X2tConverter/X2tConverter/X2tConverter.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2023 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ - -#import - -@interface Encoding : NSObject -@property (assign) NSInteger index; -@property (assign) NSInteger codePage; -@property (strong) NSString* name; -@property (strong) NSString* displayName; -@end - -@interface X2tConverter : NSObject - -+ (NSString *)version; - -@property (strong) NSString* password; -@property (assign) BOOL isNoBase64; -@property (strong) NSNumber* delimiter; -@property (assign) NSNumber* encoding; - -+ (NSArray *)delimiters; -+ (NSArray *)encodingings; - -- (int)sdk_docx2doct_bin:(NSString*)nsFrom nsTo:(NSString*)nsTo nsTemp:(NSString*)nsTemp nsFontPath:(NSString*)nsFontPath; -- (int)sdk_docx2doct:(NSString*)nsFrom nsTo:(NSString*)nsTo nsTemp:(NSString*)nsTemp nsFontPath:(NSString*)nsFontPath; -- (int)sdk_doct_bin2docx:(NSString*)nsFrom nsTo:(NSString*)nsTo nsTemp:(NSString*)nsTemp nsFontPath:(NSString*)nsFontPath fromChanges:(NSNumber*)fromChanges nsThemeDir:(NSString*)nsThemeDir; -- (int)sdk_doct2docx:(NSString*)nsFrom nsTo:(NSString*)nsTo nsTemp:(NSString*)nsTemp nsFontPath:(NSString*)nsFontPath fromChanges:(NSNumber*)fromChanges nsThemeDir:(NSString*)nsThemeDir; - -- (int)sdk_xlsx2xlst_bin:(NSString*)nsFrom nsTo:(NSString*)nsTo nsTemp:(NSString*)nsTemp nsFontPath:(NSString*)nsFontPath; -- (int)sdk_xlsx2xlst:(NSString*)nsFrom nsTo:(NSString*)nsTo nsTemp:(NSString*)nsTemp nsFontPath:(NSString*)nsFontPath; -- (int)sdk_xlst_bin2xlsx:(NSString*)nsFrom nsTo:(NSString*)nsTo nsTemp:(NSString*)nsTemp nsFontPath:(NSString*)nsFontPath fromChanges:(NSNumber*)fromChanges nsThemeDir:(NSString*)nsThemeDir; -- (int)sdk_xlst2xlsx:(NSString*)nsFrom nsTo:(NSString*)nsTo nsTemp:(NSString*)nsTemp nsFontPath:(NSString*)nsFontPath fromChanges:(NSNumber*)fromChanges nsThemeDir:(NSString*)nsThemeDir; - -- (int)sdk_pptx2pptt_bin:(NSString*)nsFrom nsTo:(NSString*)nsTo nsTemp:(NSString*)nsTemp nsFontPath:(NSString*)nsFontPath; -- (int)sdk_pptx2pptt:(NSString*)nsFrom nsTo:(NSString*)nsTo nsTemp:(NSString*)nsTemp nsFontPath:(NSString*)nsFontPath; -- (int)sdk_pptt_bin2pptx:(NSString*)nsFrom nsTo:(NSString*)nsTo nsTemp:(NSString*)nsTemp nsFontPath:(NSString*)nsFontPath fromChanges:(NSNumber*)fromChanges nsThemeDir:(NSString*)nsThemeDir; -- (int)sdk_pptt2pptx:(NSString*)nsFrom nsTo:(NSString*)nsTo nsTemp:(NSString*)nsTemp nsFontPath:(NSString*)nsFontPath fromChanges:(NSNumber*)fromChanges nsThemeDir:(NSString*)nsThemeDir; - -- (int)sdk_csv2xlst:(NSString*)nsFrom nsTo:(NSString*)nsTo xmlOptions:(NSString*)xmlOptions nsTemp:(NSString*)nsTemp nsFontPath:(NSString*)nsFontPath; -- (int)sdk_csv2xlsx:(NSString*)nsFrom nsTo:(NSString*)nsTo xmlOptions:(NSString*)xmlOptions nsTemp:(NSString*)nsTemp nsFontPath:(NSString*)nsFontPath; -- (int)sdk_csv2xlst_bin:(NSString*)nsFrom nsTo:(NSString*)nsTo nsFontPath:(NSString*)nsFontPath; -- (int)sdk_xlst2csv:(NSString*)nsFrom nsTo:(NSString*)nsTo xmlOptions:(NSString*)xmlOptions nsTemp:(NSString*)nsTemp nsFontPath:(NSString*)nsFontPath; -- (int)sdk_xlsx2csv:(NSString*)nsFrom nsTo:(NSString*)nsTo xmlOptions:(NSString*)xmlOptions nsTemp:(NSString*)nsTemp nsFontPath:(NSString*)nsFontPath; - -- (int)sdk_xls2xlsx:(NSString*)nsFrom nsTo:(NSString*)nsTo xmlOptions:(NSString*)xmlOptions nsTemp:(NSString*)nsTemp nsFontPath:(NSString*)nsFontPath; -- (int)sdk_xls2xlsx_dir:(NSString*)nsFrom nsTo:(NSString*)nsTo xmlOptions:(NSString*)xmlOptions nsTemp:(NSString*)nsTemp nsFontPath:(NSString*)nsFontPath; -- (int)sdk_xls2xlst:(NSString*)nsFrom nsTo:(NSString*)nsTo xmlOptions:(NSString*)xmlOptions nsTemp:(NSString*)nsTemp nsFontPath:(NSString*)nsFontPath; -- (int)sdk_xls2xlst_bin:(NSString*)nsFrom nsTo:(NSString*)nsTo xmlOptions:(NSString*)xmlOptions nsTemp:(NSString*)nsTemp nsFontPath:(NSString*)nsFontPath; -- (int)sdk_xls2xlsm:(NSString*)nsFrom nsTo:(NSString*)nsTo xmlOptions:(NSString*)xmlOptions nsTemp:(NSString*)nsTemp nsFontPath:(NSString*)nsFontPath; -- (int)sdk_xls2xlsm_dir:(NSString*)nsFrom nsTo:(NSString*)nsTo xmlOptions:(NSString*)xmlOptions nsTemp:(NSString*)nsTemp nsFontPath:(NSString*)nsFontPath; - -- (int)doct_bin2dotx:(NSString*)nsFrom nsTo:(NSString*)nsTo nsTemp:(NSString*)nsTemp nsFontPath:(NSString*)nsFontPath fromChanges:(NSNumber*)fromChanges nsThemeDir:(NSString*)nsThemeDir; -- (int)xlst_bin2xltx:(NSString*)nsFrom nsTo:(NSString*)nsTo nsTemp:(NSString*)nsTemp nsFontPath:(NSString*)nsFontPath fromChanges:(NSNumber*)fromChanges nsThemeDir:(NSString*)nsThemeDir; -- (int)pptt_bin2potx:(NSString*)nsFrom nsTo:(NSString*)nsTo nsTemp:(NSString*)nsTemp nsFontPath:(NSString*)nsFontPath fromChanges:(NSNumber*)fromChanges nsThemeDir:(NSString*)nsThemeDir; - -- (int)txt2doct_bin:(NSString*)nsFrom nsTo:(NSString*)nsTo nsTemp:(NSString*)nsTemp nsFontPath:(NSString*)nsFontPath; - -- (int)txt2docx:(NSString*)nsFrom nsTo:(NSString*)nsTo nsTemp:(NSString*)nsTemp nsFontPath:(NSString*)nsFontPath; -- (int)txt2docx_dir:(NSString*)nsFrom nsTo:(NSString*)nsTo nsTemp:(NSString*)nsTemp nsFontPath:(NSString*)nsFontPath; - -- (int)sdk_dir2zip:(NSString*)nsFrom nsTo:(NSString*)nsTo; -- (int)sdk_zip2dir:(NSString*)nsFrom nsTo:(NSString*)nsTo; - -@end diff --git a/X2tConverter/build/Mac/X2tConverter/X2tConverter/X2tConverter.mm b/X2tConverter/build/Mac/X2tConverter/X2tConverter/X2tConverter.mm deleted file mode 100644 index d211407e68c..00000000000 --- a/X2tConverter/build/Mac/X2tConverter/X2tConverter/X2tConverter.mm +++ /dev/null @@ -1,655 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2023 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ - -#import "X2tConverter.h" - -#include "version.h" - -#include "cextracttools.h" -#include "ASCConverters.h" - -#include -#include - -#include "../../../../../UnicodeConverter/UnicodeConverter_Encodings.h" - -static std::wstring nsstring_to_wstring(NSString* nsstring) -{ - NSStringEncoding encode = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingUTF32LE); - NSData* data = [nsstring dataUsingEncoding:encode]; - return std::wstring((wchar_t*) data.bytes, data.length / sizeof(wchar_t)); -} - -@implementation Encoding - -@end - -@implementation X2tConverter - -- (int)sdk_docx2doct_bin:(NSString*)nsFrom nsTo:(NSString*)nsTo nsTemp:(NSString*)nsTemp nsFontPath:(NSString*)nsFontPath { - std::wstring from = nsstring_to_wstring(nsFrom); - std::wstring to = nsstring_to_wstring(nsTo); - std::wstring temp = nsstring_to_wstring(nsTemp); - - NExtractTools::InputParams oInputParams; - oInputParams.m_sFontDir = new std::wstring(nsstring_to_wstring(nsFontPath)); - oInputParams.m_bIsNoBase64 = new bool(self.isNoBase64); - - if (self.password) { - oInputParams.m_sPassword = new std::wstring(nsstring_to_wstring(self.password)); - } - - return NExtractTools::docx2doct_bin(from, to, temp, oInputParams); -} -- (int)sdk_docx2doct:(NSString*)nsFrom nsTo:(NSString*)nsTo nsTemp:(NSString*)nsTemp nsFontPath:(NSString*)nsFontPath { - std::wstring from = nsstring_to_wstring(nsFrom); - std::wstring to = nsstring_to_wstring(nsTo); - std::wstring temp = nsstring_to_wstring(nsTemp); - - NExtractTools::InputParams oInputParams; - oInputParams.m_sFontDir = new std::wstring(nsstring_to_wstring(nsFontPath)); - oInputParams.m_bIsNoBase64 = new bool(self.isNoBase64); - - if (self.password) { - oInputParams.m_sPassword = new std::wstring(nsstring_to_wstring(self.password)); - } - - return NExtractTools::docx2doct(from, to, temp, oInputParams); -} -- (int)sdk_doct_bin2docx:(NSString*)nsFrom nsTo:(NSString*)nsTo nsTemp:(NSString*)nsTemp nsFontPath:(NSString*)nsFontPath fromChanges:(NSNumber*)fromChanges nsThemeDir:(NSString*)nsThemeDir { - std::wstring from = nsstring_to_wstring(nsFrom); - std::wstring to = nsstring_to_wstring(nsTo); - std::wstring temp = nsstring_to_wstring(nsTemp); - std::wstring themeDir = nsstring_to_wstring(nsThemeDir); - bool bFromChanges = (bool)fromChanges.boolValue; - - NExtractTools::InputParams oInputParams; - oInputParams.m_sFontDir = new std::wstring(nsstring_to_wstring(nsFontPath)); - oInputParams.m_bIsNoBase64 = new bool(self.isNoBase64); - - if (nil != self.password && self.password.length > 0) { - oInputParams.m_sSavePassword = new std::wstring(nsstring_to_wstring(self.password)); - - std::wstring sResultDecryptFile = temp + FILE_SEPARATOR_STR + L"uncrypt_file.docx"; - - if ((int)AVS_FILEUTILS_ERROR_CONVERT != NExtractTools::doct_bin2docx(from, sResultDecryptFile, temp, bFromChanges, themeDir, oInputParams)) { - return oox2mscrypt(sResultDecryptFile, to, temp, oInputParams); - } - - return AVS_FILEUTILS_ERROR_CONVERT; - - } else { - return NExtractTools::doct_bin2docx(from, to, temp, bFromChanges, themeDir, oInputParams); - } -} -- (int)sdk_doct2docx:(NSString*)nsFrom nsTo:(NSString*)nsTo nsTemp:(NSString*)nsTemp nsFontPath:(NSString*)nsFontPath fromChanges:(NSNumber*)fromChanges nsThemeDir:(NSString*)nsThemeDir { - std::wstring from = nsstring_to_wstring(nsFrom); - std::wstring to = nsstring_to_wstring(nsTo); - std::wstring temp = nsstring_to_wstring(nsTemp); - std::wstring themeDir = nsstring_to_wstring(nsThemeDir); - bool bFromChanges = (bool)fromChanges.boolValue; - - NExtractTools::InputParams oInputParams; - oInputParams.m_sFontDir = new std::wstring(nsstring_to_wstring(nsFontPath)); - oInputParams.m_bIsNoBase64 = new bool(self.isNoBase64); - - if (self.password) { - oInputParams.m_sPassword = new std::wstring(nsstring_to_wstring(self.password)); - } - - return NExtractTools::doct2docx(from, to, temp, bFromChanges, themeDir, oInputParams); -} - -- (int)sdk_xlsx2xlst_bin:(NSString*)nsFrom nsTo:(NSString*)nsTo nsTemp:(NSString*)nsTemp nsFontPath:(NSString*)nsFontPath { - std::wstring from = nsstring_to_wstring(nsFrom); - std::wstring to = nsstring_to_wstring(nsTo); - std::wstring temp = nsstring_to_wstring(nsTemp); - - NExtractTools::InputParams oInputParams; - oInputParams.m_sFontDir = new std::wstring(nsstring_to_wstring(nsFontPath)); - oInputParams.m_bIsNoBase64 = new bool(self.isNoBase64); - - if (self.password) { - oInputParams.m_sPassword = new std::wstring(nsstring_to_wstring(self.password)); - } - - return NExtractTools::xlsx2xlst_bin(from, to, temp, oInputParams); - -} -- (int)sdk_xlsx2xlst:(NSString*)nsFrom nsTo:(NSString*)nsTo nsTemp:(NSString*)nsTemp nsFontPath:(NSString*)nsFontPath { - std::wstring from = nsstring_to_wstring(nsFrom); - std::wstring to = nsstring_to_wstring(nsTo); - std::wstring temp = nsstring_to_wstring(nsTemp); - - NExtractTools::InputParams oInputParams; - oInputParams.m_sFontDir = new std::wstring(nsstring_to_wstring(nsFontPath)); - oInputParams.m_bIsNoBase64 = new bool(self.isNoBase64); - - if (self.password) { - oInputParams.m_sPassword = new std::wstring(nsstring_to_wstring(self.password)); - } - - return NExtractTools::xlsx2xlst(from, to, temp, oInputParams); -} -- (int)sdk_xlst_bin2xlsx:(NSString*)nsFrom nsTo:(NSString*)nsTo nsTemp:(NSString*)nsTemp nsFontPath:(NSString*)nsFontPath fromChanges:(NSNumber*)fromChanges nsThemeDir:(NSString*)nsThemeDir { - std::wstring from = nsstring_to_wstring(nsFrom); - std::wstring to = nsstring_to_wstring(nsTo); - std::wstring temp = nsstring_to_wstring(nsTemp); - std::wstring themeDir = nsstring_to_wstring(nsThemeDir); - bool bFromChanges = (bool)fromChanges.boolValue; - - NExtractTools::InputParams oInputParams; - oInputParams.m_sFontDir = new std::wstring(nsstring_to_wstring(nsFontPath)); - oInputParams.m_bIsNoBase64 = new bool(self.isNoBase64); - - if (nil != self.password && self.password.length > 0) { - oInputParams.m_sSavePassword = new std::wstring(nsstring_to_wstring(self.password)); - - std::wstring sResultDecryptFile = temp + FILE_SEPARATOR_STR + L"uncrypt_file.xlsx"; - - if ((int)AVS_FILEUTILS_ERROR_CONVERT != NExtractTools::xlst_bin2xlsx(from, sResultDecryptFile, temp, bFromChanges, themeDir, oInputParams)) { - return oox2mscrypt(sResultDecryptFile, to, temp, oInputParams); - } - - return AVS_FILEUTILS_ERROR_CONVERT; - - } else { - return NExtractTools::xlst_bin2xlsx(from, to, temp, bFromChanges, themeDir, oInputParams); - } -} -- (int)sdk_xlst2xlsx:(NSString*)nsFrom nsTo:(NSString*)nsTo nsTemp:(NSString*)nsTemp nsFontPath:(NSString*)nsFontPath fromChanges:(NSNumber*)fromChanges nsThemeDir:(NSString*)nsThemeDir { - std::wstring from = nsstring_to_wstring(nsFrom); - std::wstring to = nsstring_to_wstring(nsTo); - std::wstring temp = nsstring_to_wstring(nsTemp); - std::wstring themeDir = nsstring_to_wstring(nsThemeDir); - bool bFromChanges = (bool)fromChanges.boolValue; - - NExtractTools::InputParams oInputParams; - oInputParams.m_sFontDir = new std::wstring(nsstring_to_wstring(nsFontPath)); - oInputParams.m_bIsNoBase64 = new bool(self.isNoBase64); - - return NExtractTools::xlst2xlsx(from, to, temp, bFromChanges, themeDir, oInputParams); -} - -- (int)sdk_pptx2pptt_bin:(NSString*)nsFrom nsTo:(NSString*)nsTo nsTemp:(NSString*)nsTemp nsFontPath:(NSString*)nsFontPath { - std::wstring from = nsstring_to_wstring(nsFrom); - std::wstring to = nsstring_to_wstring(nsTo); - std::wstring temp = nsstring_to_wstring(nsTemp); - - NExtractTools::InputParams oInputParams; - oInputParams.m_sFontDir = new std::wstring(nsstring_to_wstring(nsFontPath)); - oInputParams.m_bIsNoBase64 = new bool(self.isNoBase64); - - if (self.password) { - oInputParams.m_sPassword = new std::wstring(nsstring_to_wstring(self.password)); - } - - return NExtractTools::pptx2pptt_bin(from, to, temp, oInputParams); -} -- (int)sdk_pptx2pptt:(NSString*)nsFrom nsTo:(NSString*)nsTo nsTemp:(NSString*)nsTemp nsFontPath:(NSString*)nsFontPath { - std::wstring from = nsstring_to_wstring(nsFrom); - std::wstring to = nsstring_to_wstring(nsTo); - std::wstring temp = nsstring_to_wstring(nsTemp); - - NExtractTools::InputParams oInputParams; - oInputParams.m_sFontDir = new std::wstring(nsstring_to_wstring(nsFontPath)); - oInputParams.m_bIsNoBase64 = new bool(self.isNoBase64); - - if (self.password) { - oInputParams.m_sPassword = new std::wstring(nsstring_to_wstring(self.password)); - } - - return NExtractTools::pptx2pptt(from, to, temp, oInputParams); -} -- (int)sdk_pptt_bin2pptx:(NSString*)nsFrom nsTo:(NSString*)nsTo nsTemp:(NSString*)nsTemp nsFontPath:(NSString*)nsFontPath fromChanges:(NSNumber*)fromChanges nsThemeDir:(NSString*)nsThemeDir { - std::wstring from = nsstring_to_wstring(nsFrom); - std::wstring to = nsstring_to_wstring(nsTo); - std::wstring temp = nsstring_to_wstring(nsTemp); - std::wstring themeDir = nsstring_to_wstring(nsThemeDir); - bool bFromChanges = (bool)fromChanges.boolValue; - - NExtractTools::InputParams oInputParams; - oInputParams.m_sFontDir = new std::wstring(nsstring_to_wstring(nsFontPath)); - - if (nil != self.password && self.password.length > 0) { - oInputParams.m_sSavePassword = new std::wstring(nsstring_to_wstring(self.password)); - - std::wstring sResultDecryptFile = temp + FILE_SEPARATOR_STR + L"uncrypt_file.pptx"; - - if ((int)AVS_FILEUTILS_ERROR_CONVERT != NExtractTools::pptt_bin2pptx(from, sResultDecryptFile, temp, bFromChanges, themeDir, oInputParams)) { - return oox2mscrypt(sResultDecryptFile, to, temp, oInputParams); - } - - return AVS_FILEUTILS_ERROR_CONVERT; - - } else { - return NExtractTools::pptt_bin2pptx(from, to, temp, bFromChanges, themeDir, oInputParams); - } -} -- (int)sdk_pptt2pptx:(NSString*)nsFrom nsTo:(NSString*)nsTo nsTemp:(NSString*)nsTemp nsFontPath:(NSString*)nsFontPath fromChanges:(NSNumber*)fromChanges nsThemeDir:(NSString*)nsThemeDir{ - std::wstring from = nsstring_to_wstring(nsFrom); - std::wstring to = nsstring_to_wstring(nsTo); - std::wstring temp = nsstring_to_wstring(nsTemp); - std::wstring themeDir = nsstring_to_wstring(nsThemeDir); - bool bFromChanges = (bool)fromChanges.boolValue; - - NExtractTools::InputParams oInputParams; - oInputParams.m_sFontDir = new std::wstring(nsstring_to_wstring(nsFontPath)); - - return NExtractTools::pptt2pptx(from, to, temp, bFromChanges, themeDir, oInputParams); -} - -- (int)sdk_csv2xlst:(NSString*)nsFrom nsTo:(NSString*)nsTo xmlOptions:(NSString*)xmlOptions nsTemp:(NSString*)nsTemp nsFontPath:(NSString*)nsFontPath { - std::wstring from = nsstring_to_wstring(nsFrom); - std::wstring to = nsstring_to_wstring(nsTo); - std::wstring temp = nsstring_to_wstring(nsTemp); - - // TODO: extract xml options - - NExtractTools::InputParams oInputParams; - oInputParams.m_sFontDir = new std::wstring(nsstring_to_wstring(nsFontPath)); - oInputParams.m_bIsNoBase64 = new bool(self.isNoBase64); - - if (self.password) { - oInputParams.m_sPassword = new std::wstring(nsstring_to_wstring(self.password)); - } - - return NExtractTools::csv2xlst(from, to, temp, oInputParams); -} -- (int)sdk_csv2xlsx:(NSString*)nsFrom nsTo:(NSString*)nsTo xmlOptions:(NSString*)xmlOptions nsTemp:(NSString*)nsTemp nsFontPath:(NSString*)nsFontPath { - std::wstring from = nsstring_to_wstring(nsFrom); - std::wstring to = nsstring_to_wstring(nsTo); - std::wstring temp = nsstring_to_wstring(nsTemp); - - // TODO: extract xml options - - NExtractTools::InputParams oInputParams; - oInputParams.m_sFontDir = new std::wstring(nsstring_to_wstring(nsFontPath)); - oInputParams.m_bIsNoBase64 = new bool(self.isNoBase64); - - if (self.password) { - oInputParams.m_sPassword = new std::wstring(nsstring_to_wstring(self.password)); - } - - return NExtractTools::csv2xlsx(from, to, temp, oInputParams); -} -- (int)sdk_csv2xlst_bin:(NSString*)nsFrom nsTo:(NSString*)nsTo nsFontPath:(NSString*)nsFontPath { - std::wstring from = nsstring_to_wstring(nsFrom); - std::wstring to = nsstring_to_wstring(nsTo); - - NExtractTools::InputParams oInputParams; - oInputParams.m_sFontDir = new std::wstring(nsstring_to_wstring(nsFontPath)); - oInputParams.m_bIsNoBase64 = new bool(self.isNoBase64); - - if (self.delimiter != nil) { - oInputParams.m_nCsvDelimiter = new int(self.delimiter.intValue); - } - if (self.encoding != nil) { - oInputParams.m_nCsvTxtEncoding = new int(self.encoding.intValue); - } - - oInputParams.m_nFormatFrom = new int(AVS_OFFICESTUDIO_FILE_SPREADSHEET_CSV); - oInputParams.m_nFormatTo = new int(AVS_OFFICESTUDIO_FILE_CANVAS_SPREADSHEET); - - return NExtractTools::csv2xlst_bin(from, to, oInputParams); -} -- (int)sdk_xlst2csv:(NSString*)nsFrom nsTo:(NSString*)nsTo xmlOptions:(NSString*)xmlOptions nsTemp:(NSString*)nsTemp nsFontPath:(NSString*)nsFontPath { - std::wstring from = nsstring_to_wstring(nsFrom); - std::wstring to = nsstring_to_wstring(nsTo); - std::wstring temp = nsstring_to_wstring(nsTemp); - - // TODO: extract xml options - - NExtractTools::InputParams oInputParams; - oInputParams.m_sFontDir = new std::wstring(nsstring_to_wstring(nsFontPath)); - oInputParams.m_bIsNoBase64 = new bool(self.isNoBase64); - - return NExtractTools::xlst2csv(from, to, temp, oInputParams); -} -- (int)sdk_xlsx2csv:(NSString*)nsFrom nsTo:(NSString*)nsTo xmlOptions:(NSString*)xmlOptions nsTemp:(NSString*)nsTemp nsFontPath:(NSString*)nsFontPath { - std::wstring from = nsstring_to_wstring(nsFrom); - std::wstring to = nsstring_to_wstring(nsTo); - std::wstring temp = nsstring_to_wstring(nsTemp); - - // TODO: extract xml options - - NExtractTools::InputParams oInputParams; - oInputParams.m_sFontDir = new std::wstring(nsstring_to_wstring(nsFontPath)); - oInputParams.m_bIsNoBase64 = new bool(self.isNoBase64); - - return NExtractTools::xlsx2csv(from, to, temp, oInputParams); -} - -- (int)sdk_xls2xlsx:(NSString*)nsFrom nsTo:(NSString*)nsTo xmlOptions:(NSString*)xmlOptions nsTemp:(NSString*)nsTemp nsFontPath:(NSString*)nsFontPath { - std::wstring from = nsstring_to_wstring(nsFrom); - std::wstring to = nsstring_to_wstring(nsTo); - std::wstring temp = nsstring_to_wstring(nsTemp); - - // TODO: extract xml options - - NExtractTools::InputParams oInputParams; - oInputParams.m_sFontDir = new std::wstring(nsstring_to_wstring(nsFontPath)); - oInputParams.m_bIsNoBase64 = new bool(self.isNoBase64); - - if (self.password) { - oInputParams.m_sPassword = new std::wstring(nsstring_to_wstring(self.password)); - } - - return NExtractTools::xls2xlsx(from, to, temp, oInputParams); -} -- (int)sdk_xls2xlsx_dir:(NSString*)nsFrom nsTo:(NSString*)nsTo xmlOptions:(NSString*)xmlOptions nsTemp:(NSString*)nsTemp nsFontPath:(NSString*)nsFontPath { - std::wstring from = nsstring_to_wstring(nsFrom); - std::wstring to = nsstring_to_wstring(nsTo); - std::wstring temp = nsstring_to_wstring(nsTemp); - - // TODO: extract xml options - - NExtractTools::InputParams oInputParams; - oInputParams.m_sFontDir = new std::wstring(nsstring_to_wstring(nsFontPath)); - oInputParams.m_bIsNoBase64 = new bool(self.isNoBase64); - - if (self.password) { - oInputParams.m_sPassword = new std::wstring(nsstring_to_wstring(self.password)); - } - - return NExtractTools::xls2xlsx_dir(from, to, temp, oInputParams); -} -- (int)sdk_xls2xlst:(NSString*)nsFrom nsTo:(NSString*)nsTo xmlOptions:(NSString*)xmlOptions nsTemp:(NSString*)nsTemp nsFontPath:(NSString*)nsFontPath { - std::wstring from = nsstring_to_wstring(nsFrom); - std::wstring to = nsstring_to_wstring(nsTo); - std::wstring temp = nsstring_to_wstring(nsTemp); - - // TODO: extract xml options - - NExtractTools::InputParams oInputParams; - oInputParams.m_sFontDir = new std::wstring(nsstring_to_wstring(nsFontPath)); - oInputParams.m_bIsNoBase64 = new bool(self.isNoBase64); - - if (self.password) { - oInputParams.m_sPassword = new std::wstring(nsstring_to_wstring(self.password)); - } - - return NExtractTools::xls2xlst(from, to, temp, oInputParams); -} -- (int)sdk_xls2xlst_bin:(NSString*)nsFrom nsTo:(NSString*)nsTo xmlOptions:(NSString*)xmlOptions nsTemp:(NSString*)nsTemp nsFontPath:(NSString*)nsFontPath { - std::wstring from = nsstring_to_wstring(nsFrom); - std::wstring to = nsstring_to_wstring(nsTo); - std::wstring temp = nsstring_to_wstring(nsTemp); - - // TODO: extract xml options - - NExtractTools::InputParams oInputParams; - oInputParams.m_sFontDir = new std::wstring(nsstring_to_wstring(nsFontPath)); - oInputParams.m_bIsNoBase64 = new bool(self.isNoBase64); - - if (self.password) { - oInputParams.m_sPassword = new std::wstring(nsstring_to_wstring(self.password)); - } - - return NExtractTools::xls2xlst_bin(from, to, temp, oInputParams); -} -- (int)sdk_xls2xlsm:(NSString*)nsFrom nsTo:(NSString*)nsTo xmlOptions:(NSString*)xmlOptions nsTemp:(NSString*)nsTemp nsFontPath:(NSString*)nsFontPath { - std::wstring from = nsstring_to_wstring(nsFrom); - std::wstring to = nsstring_to_wstring(nsTo); - std::wstring temp = nsstring_to_wstring(nsTemp); - - // TODO: extract xml options - - NExtractTools::InputParams oInputParams; - oInputParams.m_sFontDir = new std::wstring(nsstring_to_wstring(nsFontPath)); - oInputParams.m_bIsNoBase64 = new bool(self.isNoBase64); - - if (self.password) { - oInputParams.m_sPassword = new std::wstring(nsstring_to_wstring(self.password)); - } - - return NExtractTools::xls2xlsm(from, to, temp, oInputParams); -} -- (int)sdk_xls2xlsm_dir:(NSString*)nsFrom nsTo:(NSString*)nsTo xmlOptions:(NSString*)xmlOptions nsTemp:(NSString*)nsTemp nsFontPath:(NSString*)nsFontPath { - std::wstring from = nsstring_to_wstring(nsFrom); - std::wstring to = nsstring_to_wstring(nsTo); - std::wstring temp = nsstring_to_wstring(nsTemp); - - // TODO: extract xml options - - NExtractTools::InputParams oInputParams; - oInputParams.m_sFontDir = new std::wstring(nsstring_to_wstring(nsFontPath)); - oInputParams.m_bIsNoBase64 = new bool(self.isNoBase64); - - if (self.password) { - oInputParams.m_sPassword = new std::wstring(nsstring_to_wstring(self.password)); - } - - return NExtractTools::xls2xlsm_dir(from, to, temp, oInputParams); -} - -- (int)doct_bin2dotx:(NSString*)nsFrom nsTo:(NSString*)nsTo nsTemp:(NSString*)nsTemp nsFontPath:(NSString*)nsFontPath fromChanges:(NSNumber*)fromChanges nsThemeDir:(NSString*)nsThemeDir { - - int nRes = 0; - - std::wstring from = nsstring_to_wstring(nsFrom); - std::wstring to = nsstring_to_wstring(nsTo); - std::wstring temp = nsstring_to_wstring(nsTemp); - std::wstring themeDir = nsstring_to_wstring(nsThemeDir); - bool bFromChanges = (bool)fromChanges.boolValue; - - NExtractTools::InputParams oInputParams; - oInputParams.m_sFontDir = new std::wstring(nsstring_to_wstring(nsFontPath)); - oInputParams.m_bIsNoBase64 = new bool(self.isNoBase64); - - NSString* nsTemporaryFile = [NSString stringWithFormat:@"%@%@.docx", NSTemporaryDirectory(), [[NSUUID UUID] UUIDString]]; - std::wstring temporaryFile = nsstring_to_wstring(nsTemporaryFile); - - std::wstring sDocxDir = temp + _T("docx_unpacked"); - NSDirectory::DeleteDirectory(sDocxDir); - NSDirectory::CreateDirectory(sDocxDir); - - nRes = doct_bin2docx_dir(from, temporaryFile, sDocxDir, false, temp, oInputParams); - if(SUCCEEDED_X2T(nRes)) - { - nRes = fromDocxDir(sDocxDir, to, AVS_OFFICESTUDIO_FILE_DOCUMENT_DOTX, temp, themeDir, bFromChanges, false, oInputParams); - } - - return nRes; -} - -- (int)xlst_bin2xltx:(NSString*)nsFrom nsTo:(NSString*)nsTo nsTemp:(NSString*)nsTemp nsFontPath:(NSString*)nsFontPath fromChanges:(NSNumber*)fromChanges nsThemeDir:(NSString*)nsThemeDir { - - int nRes = 0; - - std::wstring from = nsstring_to_wstring(nsFrom); - std::wstring to = nsstring_to_wstring(nsTo); - std::wstring temp = nsstring_to_wstring(nsTemp); - std::wstring themeDir = nsstring_to_wstring(nsThemeDir); - bool bFromChanges = (bool)fromChanges.boolValue; - - NExtractTools::InputParams oInputParams; - oInputParams.m_sFontDir = new std::wstring(nsstring_to_wstring(nsFontPath)); - oInputParams.m_bIsNoBase64 = new bool(self.isNoBase64); - - NSString* nsTemporaryFile = [NSString stringWithFormat:@"%@%@.xlsx", NSTemporaryDirectory(), [[NSUUID UUID] UUIDString]]; - std::wstring temporaryFile = nsstring_to_wstring(nsTemporaryFile); - - std::wstring sXlsxDir = temp + _T("xlsx_unpacked"); - NSDirectory::DeleteDirectory(sXlsxDir); - NSDirectory::CreateDirectory(sXlsxDir); - - nRes = xlst_bin2xlsx_dir(from, temporaryFile, sXlsxDir, false, temp, oInputParams); - if(SUCCEEDED_X2T(nRes)) - { - nRes = fromXlsxDir(sXlsxDir, to, AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLTX, temp, themeDir, bFromChanges, false, oInputParams, std::wstring(L"")); - } - - return nRes; -} - -- (int)pptt_bin2potx:(NSString*)nsFrom nsTo:(NSString*)nsTo nsTemp:(NSString*)nsTemp nsFontPath:(NSString*)nsFontPath fromChanges:(NSNumber*)fromChanges nsThemeDir:(NSString*)nsThemeDir { - - int nRes = 0; - - std::wstring from = nsstring_to_wstring(nsFrom); - std::wstring to = nsstring_to_wstring(nsTo); - std::wstring temp = nsstring_to_wstring(nsTemp); - std::wstring themeDir = nsstring_to_wstring(nsThemeDir); - bool bFromChanges = (bool)fromChanges.boolValue; - - NExtractTools::InputParams oInputParams; - oInputParams.m_sFontDir = new std::wstring(nsstring_to_wstring(nsFontPath)); - oInputParams.m_bIsNoBase64 = new bool(self.isNoBase64); - - NSString* nsTemporaryFile = [NSString stringWithFormat:@"%@%@.pptx", NSTemporaryDirectory(), [[NSUUID UUID] UUIDString]]; - std::wstring temporaryFile = nsstring_to_wstring(nsTemporaryFile); - - std::wstring sPptxDir = temp + _T("pptx_unpacked"); - NSDirectory::DeleteDirectory(sPptxDir); - NSDirectory::CreateDirectory(sPptxDir); - - nRes = pptt_bin2pptx_dir(from, temporaryFile, sPptxDir, false, temp, oInputParams); - if(SUCCEEDED_X2T(nRes)) - { - nRes = fromPptxDir(sPptxDir, to, AVS_OFFICESTUDIO_FILE_PRESENTATION_POTX, temp, themeDir, bFromChanges, false, oInputParams); - } - - return nRes; -} - -- (int)txt2doct_bin:(NSString*)nsFrom nsTo:(NSString*)nsTo nsTemp:(NSString*)nsTemp nsFontPath:(NSString*)nsFontPath { - std::wstring from = nsstring_to_wstring(nsFrom); - std::wstring to = nsstring_to_wstring(nsTo); - std::wstring temp = nsstring_to_wstring(nsTemp); - - NExtractTools::InputParams oInputParams; - oInputParams.m_sFontDir = new std::wstring(nsstring_to_wstring(nsFontPath)); - oInputParams.m_bIsNoBase64 = new bool(self.isNoBase64); - - if (self.encoding != nil) { - oInputParams.m_nCsvTxtEncoding = new int(self.encoding.intValue); - } - - oInputParams.m_nFormatFrom = new int(AVS_OFFICESTUDIO_FILE_DOCUMENT_TXT); - oInputParams.m_nFormatTo = new int(AVS_OFFICESTUDIO_FILE_CANVAS_WORD); - - return NExtractTools::txt2doct_bin(from, to, temp, oInputParams); -} - -- (int)txt2docx:(NSString*)nsFrom nsTo:(NSString*)nsTo nsTemp:(NSString*)nsTemp nsFontPath:(NSString*)nsFontPath { - std::wstring from = nsstring_to_wstring(nsFrom); - std::wstring to = nsstring_to_wstring(nsTo); - std::wstring temp = nsstring_to_wstring(nsTemp); - - NExtractTools::InputParams oInputParams; - oInputParams.m_sFontDir = new std::wstring(nsstring_to_wstring(nsFontPath)); - oInputParams.m_bIsNoBase64 = new bool(self.isNoBase64); - - if (self.encoding != nil) { - oInputParams.m_nCsvTxtEncoding = new int(self.encoding.intValue); - } - - oInputParams.m_nFormatFrom = new int(AVS_OFFICESTUDIO_FILE_DOCUMENT_TXT); - oInputParams.m_nFormatTo = new int(AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX); - - return NExtractTools::txt2docx(from, to, temp, oInputParams); -} - -- (int)txt2docx_dir:(NSString*)nsFrom nsTo:(NSString*)nsTo nsTemp:(NSString*)nsTemp nsFontPath:(NSString*)nsFontPath { - std::wstring from = nsstring_to_wstring(nsFrom); - std::wstring to = nsstring_to_wstring(nsTo); - std::wstring temp = nsstring_to_wstring(nsTemp); - - NExtractTools::InputParams oInputParams; - oInputParams.m_sFontDir = new std::wstring(nsstring_to_wstring(nsFontPath)); - oInputParams.m_bIsNoBase64 = new bool(self.isNoBase64); - - if (self.encoding != nil) { - oInputParams.m_nCsvTxtEncoding = new int(self.encoding.intValue); - } - - oInputParams.m_nFormatFrom = new int(AVS_OFFICESTUDIO_FILE_DOCUMENT_TXT); - oInputParams.m_nFormatTo = new int(AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX); - - return NExtractTools::txt2doct_bin(from, to, temp, oInputParams); -} - -- (int)sdk_dir2zip:(NSString*)nsFrom nsTo:(NSString*)nsTo { - std::wstring from = nsstring_to_wstring(nsFrom); - std::wstring to = nsstring_to_wstring(nsTo); - - return NExtractTools::dir2zip(from, to); -} -- (int)sdk_zip2dir:(NSString*)nsFrom nsTo:(NSString*)nsTo { - std::wstring from = nsstring_to_wstring(nsFrom); - std::wstring to = nsstring_to_wstring(nsTo); - - return NExtractTools::zip2dir(from, to); -} - -+ (NSArray *)delimiters { - NSMutableArray *values = [[NSMutableArray alloc]init]; - - [values addObject:[NSString stringWithFormat:@"\t"]]; - [values addObject:[NSString stringWithFormat:@";"]]; - [values addObject:[NSString stringWithFormat:@":"]]; - [values addObject:[NSString stringWithFormat:@","]]; - [values addObject:[NSString stringWithFormat:@" "]]; - - return values; -} - -+ (NSArray *)encodingings { - NSMutableArray *values = [[NSMutableArray alloc]init]; - for (int i = 0; i < UNICODE_CONVERTER_ENCODINGS_COUNT; ++i) { - Encoding *encoding = [[Encoding alloc]init]; - encoding.index = NSUnicodeConverter::Encodings[i].Index; - encoding.codePage = NSUnicodeConverter::Encodings[i].WindowsCodePage; - encoding.name = [NSString stringWithFormat:@"%s", NSUnicodeConverter::Encodings[i].Name]; - encoding.displayName = [NSString stringWithFormat:@"%s", NSUnicodeConverter::Encodings[i].DisplayName]; - [values addObject:encoding]; - } - - return values; -} - -+ (NSString *)version { - return [[NSString alloc] initWithUTF8String:X2T_VERSION]; -} - -- (void)removeFileAt:(NSString *)path { - NSError *error; - if ([[NSFileManager defaultManager] isDeletableFileAtPath:path]) { - BOOL success = [[NSFileManager defaultManager] removeItemAtPath:path error:&error]; - if (!success) { - NSLog(@"Error removing file at path: %@", error.localizedDescription); - } - } -} - -@end diff --git a/X2tConverter/build/Mac/X2tConverter/X2tConverter/version.h b/X2tConverter/build/Mac/X2tConverter/X2tConverter/version.h deleted file mode 100644 index 65594df0cc7..00000000000 --- a/X2tConverter/build/Mac/X2tConverter/X2tConverter/version.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef X2T_VERSION_H -#define X2T_VERSION_H - -#define X2T_VERSION "2.5.565.0" - -#endif diff --git a/X2tConverter/build/Mac/X2tConverter/icu/icu.xcodeproj/project.pbxproj b/X2tConverter/build/Mac/X2tConverter/icu/icu.xcodeproj/project.pbxproj deleted file mode 100644 index d9dabaf884c..00000000000 --- a/X2tConverter/build/Mac/X2tConverter/icu/icu.xcodeproj/project.pbxproj +++ /dev/null @@ -1,2770 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - FCCB1ABB248E82FC000A2F32 /* ucnvlat1.c in Sources */ = {isa = PBXBuildFile; fileRef = FCCB19A1248E82E3000A2F32 /* ucnvlat1.c */; }; - FCCB1ABC248E82FC000A2F32 /* ucharstriebuilder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB19A2248E82E3000A2F32 /* ucharstriebuilder.cpp */; }; - FCCB1ABD248E82FC000A2F32 /* ucharstrie.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB19A3248E82E3000A2F32 /* ucharstrie.cpp */; }; - FCCB1ABE248E82FC000A2F32 /* ustrcase_locale.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB19A4248E82E3000A2F32 /* ustrcase_locale.cpp */; }; - FCCB1ABF248E82FC000A2F32 /* ucnv_cb.c in Sources */ = {isa = PBXBuildFile; fileRef = FCCB19A5248E82E3000A2F32 /* ucnv_cb.c */; }; - FCCB1AC0248E82FC000A2F32 /* ucnv_set.c in Sources */ = {isa = PBXBuildFile; fileRef = FCCB19A7248E82E3000A2F32 /* ucnv_set.c */; }; - FCCB1AC1248E82FC000A2F32 /* locdspnm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB19A9248E82E3000A2F32 /* locdspnm.cpp */; }; - FCCB1AC2248E82FC000A2F32 /* ustr_wcs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB19AB248E82E3000A2F32 /* ustr_wcs.cpp */; }; - FCCB1AC3248E82FC000A2F32 /* unifilt.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB19AD248E82E3000A2F32 /* unifilt.cpp */; }; - FCCB1AC4248E82FC000A2F32 /* ucnvdisp.c in Sources */ = {isa = PBXBuildFile; fileRef = FCCB19B2248E82E3000A2F32 /* ucnvdisp.c */; }; - FCCB1AC5248E82FC000A2F32 /* ucasemap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB19B5248E82E4000A2F32 /* ucasemap.cpp */; }; - FCCB1AC6248E82FC000A2F32 /* chariter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB19B7248E82E4000A2F32 /* chariter.cpp */; }; - FCCB1AC7248E82FC000A2F32 /* ucnvmbcs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB19B8248E82E4000A2F32 /* ucnvmbcs.cpp */; }; - FCCB1AC8248E82FC000A2F32 /* ulist.c in Sources */ = {isa = PBXBuildFile; fileRef = FCCB19BB248E82E4000A2F32 /* ulist.c */; }; - FCCB1AC9248E82FC000A2F32 /* ustr_titlecase_brkiter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB19BC248E82E4000A2F32 /* ustr_titlecase_brkiter.cpp */; }; - FCCB1ACA248E82FC000A2F32 /* uvector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB19BD248E82E4000A2F32 /* uvector.cpp */; }; - FCCB1ACB248E82FC000A2F32 /* unistr_titlecase_brkiter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB19BE248E82E4000A2F32 /* unistr_titlecase_brkiter.cpp */; }; - FCCB1ACC248E82FC000A2F32 /* ucmndata.c in Sources */ = {isa = PBXBuildFile; fileRef = FCCB19BF248E82E4000A2F32 /* ucmndata.c */; }; - FCCB1ACD248E82FC000A2F32 /* rbbiscan.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB19C0248E82E4000A2F32 /* rbbiscan.cpp */; }; - FCCB1ACE248E82FC000A2F32 /* unistr_cnv.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB19C1248E82E4000A2F32 /* unistr_cnv.cpp */; }; - FCCB1ACF248E82FC000A2F32 /* servnotf.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB19C2248E82E5000A2F32 /* servnotf.cpp */; }; - FCCB1AD0248E82FC000A2F32 /* unisetspan.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB19C3248E82E5000A2F32 /* unisetspan.cpp */; }; - FCCB1AD1248E82FC000A2F32 /* util.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB19C4248E82E5000A2F32 /* util.cpp */; }; - FCCB1AD2248E82FC000A2F32 /* simpleformatter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB19C5248E82E5000A2F32 /* simpleformatter.cpp */; }; - FCCB1AD3248E82FC000A2F32 /* cstr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB19C9248E82E5000A2F32 /* cstr.cpp */; }; - FCCB1AD4248E82FC000A2F32 /* uchriter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB19CA248E82E5000A2F32 /* uchriter.cpp */; }; - FCCB1AD5248E82FC000A2F32 /* ucnvisci.c in Sources */ = {isa = PBXBuildFile; fileRef = FCCB19CB248E82E5000A2F32 /* ucnvisci.c */; }; - FCCB1AD6248E82FC000A2F32 /* utrie2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB19CD248E82E6000A2F32 /* utrie2.cpp */; }; - FCCB1AD7248E82FC000A2F32 /* udata.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB19CE248E82E6000A2F32 /* udata.cpp */; }; - FCCB1AD8248E82FC000A2F32 /* uiter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB19CF248E82E6000A2F32 /* uiter.cpp */; }; - FCCB1AD9248E82FC000A2F32 /* locdispnames.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB19D0248E82E6000A2F32 /* locdispnames.cpp */; }; - FCCB1ADA248E82FC000A2F32 /* ucnv_u7.c in Sources */ = {isa = PBXBuildFile; fileRef = FCCB19D2248E82E6000A2F32 /* ucnv_u7.c */; }; - FCCB1ADB248E82FC000A2F32 /* ucurr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB19D3248E82E6000A2F32 /* ucurr.cpp */; }; - FCCB1ADC248E82FC000A2F32 /* putil.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB19D4248E82E6000A2F32 /* putil.cpp */; }; - FCCB1ADD248E82FC000A2F32 /* ustr_cnv.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB19D5248E82E6000A2F32 /* ustr_cnv.cpp */; }; - FCCB1ADE248E82FC000A2F32 /* locutil.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB19D7248E82E7000A2F32 /* locutil.cpp */; }; - FCCB1ADF248E82FC000A2F32 /* ubidiln.c in Sources */ = {isa = PBXBuildFile; fileRef = FCCB19D8248E82E7000A2F32 /* ubidiln.c */; }; - FCCB1AE0248E82FC000A2F32 /* cwchar.c in Sources */ = {isa = PBXBuildFile; fileRef = FCCB19D9248E82E7000A2F32 /* cwchar.c */; }; - FCCB1AE1248E82FC000A2F32 /* dictionarydata.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB19DB248E82E7000A2F32 /* dictionarydata.cpp */; }; - FCCB1AE2248E82FC000A2F32 /* ucnvsel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB19DC248E82E7000A2F32 /* ucnvsel.cpp */; }; - FCCB1AE3248E82FC000A2F32 /* ucnv_u32.c in Sources */ = {isa = PBXBuildFile; fileRef = FCCB19DD248E82E7000A2F32 /* ucnv_u32.c */; }; - FCCB1AE4248E82FC000A2F32 /* ucnv.c in Sources */ = {isa = PBXBuildFile; fileRef = FCCB19DF248E82E7000A2F32 /* ucnv.c */; }; - FCCB1AE5248E82FC000A2F32 /* ucol_swp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB19E0248E82E7000A2F32 /* ucol_swp.cpp */; }; - FCCB1AE6248E82FC000A2F32 /* uscript_props.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB19E2248E82E8000A2F32 /* uscript_props.cpp */; }; - FCCB1AE7248E82FC000A2F32 /* unifunct.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB19E4248E82E8000A2F32 /* unifunct.cpp */; }; - FCCB1AE8248E82FC000A2F32 /* ucln_cmn.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB19E7248E82E8000A2F32 /* ucln_cmn.cpp */; }; - FCCB1AE9248E82FC000A2F32 /* usc_impl.c in Sources */ = {isa = PBXBuildFile; fileRef = FCCB19E8248E82E8000A2F32 /* usc_impl.c */; }; - FCCB1AEA248E82FC000A2F32 /* ustrenum.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB19E9248E82E8000A2F32 /* ustrenum.cpp */; }; - FCCB1AEB248E82FC000A2F32 /* rbbidata.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB19EA248E82E8000A2F32 /* rbbidata.cpp */; }; - FCCB1AEC248E82FC000A2F32 /* errorcode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB19EB248E82E8000A2F32 /* errorcode.cpp */; }; - FCCB1AED248E82FC000A2F32 /* ucnv_ct.c in Sources */ = {isa = PBXBuildFile; fileRef = FCCB19EC248E82E9000A2F32 /* ucnv_ct.c */; }; - FCCB1AEE248E82FC000A2F32 /* unorm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB19EE248E82E9000A2F32 /* unorm.cpp */; }; - FCCB1AEF248E82FC000A2F32 /* ubidiwrt.c in Sources */ = {isa = PBXBuildFile; fileRef = FCCB19EF248E82E9000A2F32 /* ubidiwrt.c */; }; - FCCB1AF0248E82FC000A2F32 /* servlk.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB19F1248E82E9000A2F32 /* servlk.cpp */; }; - FCCB1AF1248E82FC000A2F32 /* ucase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB19F2248E82E9000A2F32 /* ucase.cpp */; }; - FCCB1AF2248E82FC000A2F32 /* sharedobject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB19F3248E82E9000A2F32 /* sharedobject.cpp */; }; - FCCB1AF3248E82FC000A2F32 /* ucat.c in Sources */ = {isa = PBXBuildFile; fileRef = FCCB19F4248E82E9000A2F32 /* ucat.c */; }; - FCCB1AF4248E82FC000A2F32 /* umutex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB19F6248E82E9000A2F32 /* umutex.cpp */; }; - FCCB1AF5248E82FC000A2F32 /* ustrcase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB19F7248E82EA000A2F32 /* ustrcase.cpp */; }; - FCCB1AF6248E82FC000A2F32 /* uidna.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB19F8248E82EA000A2F32 /* uidna.cpp */; }; - FCCB1AF7248E82FC000A2F32 /* ucnv_u16.c in Sources */ = {isa = PBXBuildFile; fileRef = FCCB19F9248E82EA000A2F32 /* ucnv_u16.c */; }; - FCCB1AF8248E82FC000A2F32 /* dictbe.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB19FA248E82EA000A2F32 /* dictbe.cpp */; }; - FCCB1AF9248E82FC000A2F32 /* cmemory.c in Sources */ = {isa = PBXBuildFile; fileRef = FCCB19FB248E82EA000A2F32 /* cmemory.c */; }; - FCCB1AFA248E82FC000A2F32 /* pluralmap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB19FD248E82EA000A2F32 /* pluralmap.cpp */; }; - FCCB1AFB248E82FC000A2F32 /* uvectr32.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB19FE248E82EA000A2F32 /* uvectr32.cpp */; }; - FCCB1AFC248E82FC000A2F32 /* uts46.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB19FF248E82EA000A2F32 /* uts46.cpp */; }; - FCCB1AFD248E82FC000A2F32 /* uprops.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A00248E82EA000A2F32 /* uprops.cpp */; }; - FCCB1AFE248E82FC000A2F32 /* ures_cnv.c in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A01248E82EB000A2F32 /* ures_cnv.c */; }; - FCCB1AFF248E82FC000A2F32 /* messagepattern.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A04248E82EB000A2F32 /* messagepattern.cpp */; }; - FCCB1B00248E82FC000A2F32 /* usetiter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A07248E82EB000A2F32 /* usetiter.cpp */; }; - FCCB1B01248E82FC000A2F32 /* umath.c in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A08248E82EB000A2F32 /* umath.c */; }; - FCCB1B02248E82FC000A2F32 /* uloc_tag.c in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A0A248E82EB000A2F32 /* uloc_tag.c */; }; - FCCB1B03248E82FC000A2F32 /* unifiedcache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A0B248E82EB000A2F32 /* unifiedcache.cpp */; }; - FCCB1B04248E82FC000A2F32 /* uhash.c in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A0C248E82EC000A2F32 /* uhash.c */; }; - FCCB1B05248E82FC000A2F32 /* ucnv_u8.c in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A0D248E82EC000A2F32 /* ucnv_u8.c */; }; - FCCB1B06248E82FC000A2F32 /* uchar.c in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A11248E82EC000A2F32 /* uchar.c */; }; - FCCB1B07248E82FC000A2F32 /* bytestream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A12248E82EC000A2F32 /* bytestream.cpp */; }; - FCCB1B08248E82FC000A2F32 /* rbbistbl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A13248E82EC000A2F32 /* rbbistbl.cpp */; }; - FCCB1B09248E82FC000A2F32 /* servlkf.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A14248E82EC000A2F32 /* servlkf.cpp */; }; - FCCB1B0A248E82FC000A2F32 /* uobject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A15248E82EC000A2F32 /* uobject.cpp */; }; - FCCB1B0B248E82FC000A2F32 /* uresdata.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A16248E82EC000A2F32 /* uresdata.cpp */; }; - FCCB1B0C248E82FC000A2F32 /* propname.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A17248E82ED000A2F32 /* propname.cpp */; }; - FCCB1B0D248E82FC000A2F32 /* ubidi_props.c in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A18248E82ED000A2F32 /* ubidi_props.c */; }; - FCCB1B0E248E82FC000A2F32 /* udataswp.c in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A1A248E82ED000A2F32 /* udataswp.c */; }; - FCCB1B0F248E82FC000A2F32 /* bmpset.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A1C248E82ED000A2F32 /* bmpset.cpp */; }; - FCCB1B10248E82FC000A2F32 /* patternprops.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A1D248E82ED000A2F32 /* patternprops.cpp */; }; - FCCB1B11248E82FC000A2F32 /* ucnv_cnv.c in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A1E248E82ED000A2F32 /* ucnv_cnv.c */; }; - FCCB1B12248E82FC000A2F32 /* utext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A1F248E82ED000A2F32 /* utext.cpp */; }; - FCCB1B13248E82FC000A2F32 /* filterednormalizer2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A20248E82ED000A2F32 /* filterednormalizer2.cpp */; }; - FCCB1B14248E82FC000A2F32 /* ucnv_lmb.c in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A21248E82ED000A2F32 /* ucnv_lmb.c */; }; - FCCB1B15248E82FC000A2F32 /* umapfile.c in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A22248E82ED000A2F32 /* umapfile.c */; }; - FCCB1B16248E82FC000A2F32 /* utrie.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A25248E82EE000A2F32 /* utrie.cpp */; }; - FCCB1B17248E82FC000A2F32 /* servslkf.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A26248E82EE000A2F32 /* servslkf.cpp */; }; - FCCB1B18248E82FC000A2F32 /* ustack.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A27248E82EE000A2F32 /* ustack.cpp */; }; - FCCB1B19248E82FC000A2F32 /* stringtriebuilder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A28248E82EE000A2F32 /* stringtriebuilder.cpp */; }; - FCCB1B1A248E82FC000A2F32 /* unistr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A2B248E82EE000A2F32 /* unistr.cpp */; }; - FCCB1B1B248E82FC000A2F32 /* rbbitblb.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A2E248E82EF000A2F32 /* rbbitblb.cpp */; }; - FCCB1B1C248E82FC000A2F32 /* servrbf.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A2F248E82EF000A2F32 /* servrbf.cpp */; }; - FCCB1B1D248E82FC000A2F32 /* unistr_case.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A30248E82EF000A2F32 /* unistr_case.cpp */; }; - FCCB1B1E248E82FC000A2F32 /* uscript.c in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A31248E82EF000A2F32 /* uscript.c */; }; - FCCB1B1F248E82FC000A2F32 /* unormcmp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A32248E82EF000A2F32 /* unormcmp.cpp */; }; - FCCB1B20248E82FC000A2F32 /* ucharstrieiterator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A33248E82EF000A2F32 /* ucharstrieiterator.cpp */; }; - FCCB1B21248E82FC000A2F32 /* uresbund.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A35248E82EF000A2F32 /* uresbund.cpp */; }; - FCCB1B22248E82FC000A2F32 /* serv.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A36248E82F0000A2F32 /* serv.cpp */; }; - FCCB1B23248E82FC000A2F32 /* utf_impl.c in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A39248E82F0000A2F32 /* utf_impl.c */; }; - FCCB1B24248E82FC000A2F32 /* uarrsort.c in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A3A248E82F0000A2F32 /* uarrsort.c */; }; - FCCB1B25248E82FC000A2F32 /* rbbi.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A3B248E82F0000A2F32 /* rbbi.cpp */; }; - FCCB1B26248E82FC000A2F32 /* bytestrie.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A3C248E82F0000A2F32 /* bytestrie.cpp */; }; - FCCB1B27248E82FC000A2F32 /* parsepos.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A3E248E82F0000A2F32 /* parsepos.cpp */; }; - FCCB1B28248E82FC000A2F32 /* utypes.c in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A3F248E82F0000A2F32 /* utypes.c */; }; - FCCB1B29248E82FC000A2F32 /* loadednormalizer2impl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A41248E82F1000A2F32 /* loadednormalizer2impl.cpp */; }; - FCCB1B2A248E82FC000A2F32 /* ruleiter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A46248E82F1000A2F32 /* ruleiter.cpp */; }; - FCCB1B2B248E82FC000A2F32 /* ubiditransform.c in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A48248E82F1000A2F32 /* ubiditransform.c */; }; - FCCB1B2C248E82FC000A2F32 /* ucnv_err.c in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A49248E82F1000A2F32 /* ucnv_err.c */; }; - FCCB1B2D248E82FC000A2F32 /* uhash_us.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A4A248E82F1000A2F32 /* uhash_us.cpp */; }; - FCCB1B2E248E82FC000A2F32 /* uinvchar.c in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A4C248E82F2000A2F32 /* uinvchar.c */; }; - FCCB1B2F248E82FC000A2F32 /* ucnvbocu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A4D248E82F2000A2F32 /* ucnvbocu.cpp */; }; - FCCB1B30248E82FC000A2F32 /* propsvec.c in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A4E248E82F2000A2F32 /* propsvec.c */; }; - FCCB1B31248E82FC000A2F32 /* wintz.c in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A51248E82F2000A2F32 /* wintz.c */; }; - FCCB1B32248E82FD000A2F32 /* bytestrieiterator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A52248E82F2000A2F32 /* bytestrieiterator.cpp */; }; - FCCB1B33248E82FD000A2F32 /* ushape.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A53248E82F2000A2F32 /* ushape.cpp */; }; - FCCB1B34248E82FD000A2F32 /* brkeng.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A55248E82F3000A2F32 /* brkeng.cpp */; }; - FCCB1B35248E82FD000A2F32 /* icudataver.c in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A56248E82F3000A2F32 /* icudataver.c */; }; - FCCB1B36248E82FD000A2F32 /* rbbirb.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A58248E82F3000A2F32 /* rbbirb.cpp */; }; - FCCB1B37248E82FD000A2F32 /* ustrtrns.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A5A248E82F3000A2F32 /* ustrtrns.cpp */; }; - FCCB1B38248E82FD000A2F32 /* normalizer2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A5B248E82F3000A2F32 /* normalizer2.cpp */; }; - FCCB1B39248E82FD000A2F32 /* unistr_case_locale.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A5E248E82F3000A2F32 /* unistr_case_locale.cpp */; }; - FCCB1B3A248E82FD000A2F32 /* rbbinode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A61248E82F4000A2F32 /* rbbinode.cpp */; }; - FCCB1B3B248E82FD000A2F32 /* uvectr64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A63248E82F4000A2F32 /* uvectr64.cpp */; }; - FCCB1B3C248E82FD000A2F32 /* ucnv_io.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A66248E82F4000A2F32 /* ucnv_io.cpp */; }; - FCCB1B3D248E82FD000A2F32 /* servls.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A67248E82F4000A2F32 /* servls.cpp */; }; - FCCB1B3E248E82FD000A2F32 /* uniset_props.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A68248E82F4000A2F32 /* uniset_props.cpp */; }; - FCCB1B3F248E82FD000A2F32 /* uenum.c in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A6B248E82F5000A2F32 /* uenum.c */; }; - FCCB1B40248E82FD000A2F32 /* listformatter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A6D248E82F5000A2F32 /* listformatter.cpp */; }; - FCCB1B41248E82FD000A2F32 /* loclikely.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A6F248E82F5000A2F32 /* loclikely.cpp */; }; - FCCB1B42248E82FD000A2F32 /* normlzr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A73248E82F5000A2F32 /* normlzr.cpp */; }; - FCCB1B43248E82FD000A2F32 /* resource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A74248E82F5000A2F32 /* resource.cpp */; }; - FCCB1B44248E82FD000A2F32 /* normalizer2impl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A75248E82F6000A2F32 /* normalizer2impl.cpp */; }; - FCCB1B45248E82FD000A2F32 /* filteredbrk.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A76248E82F6000A2F32 /* filteredbrk.cpp */; }; - FCCB1B46248E82FD000A2F32 /* ubidi.c in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A77248E82F6000A2F32 /* ubidi.c */; }; - FCCB1B47248E82FD000A2F32 /* ucnvscsu.c in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A78248E82F6000A2F32 /* ucnvscsu.c */; }; - FCCB1B48248E82FD000A2F32 /* ucnv2022.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A79248E82F6000A2F32 /* ucnv2022.cpp */; }; - FCCB1B49248E82FD000A2F32 /* ustring.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A7A248E82F6000A2F32 /* ustring.cpp */; }; - FCCB1B4A248E82FD000A2F32 /* uniset_closure.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A7B248E82F6000A2F32 /* uniset_closure.cpp */; }; - FCCB1B4B248E82FD000A2F32 /* util_props.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A7C248E82F6000A2F32 /* util_props.cpp */; }; - FCCB1B4C248E82FD000A2F32 /* resbund_cnv.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A7D248E82F6000A2F32 /* resbund_cnv.cpp */; }; - FCCB1B4D248E82FD000A2F32 /* usprep.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A81248E82F7000A2F32 /* usprep.cpp */; }; - FCCB1B4E248E82FD000A2F32 /* brkiter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A82248E82F7000A2F32 /* brkiter.cpp */; }; - FCCB1B4F248E82FD000A2F32 /* ubrk.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A83248E82F7000A2F32 /* ubrk.cpp */; }; - FCCB1B50248E82FD000A2F32 /* rbbisetb.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A85248E82F7000A2F32 /* rbbisetb.cpp */; }; - FCCB1B51248E82FD000A2F32 /* locresdata.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A86248E82F7000A2F32 /* locresdata.cpp */; }; - FCCB1B52248E82FD000A2F32 /* ucnv_ext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A87248E82F7000A2F32 /* ucnv_ext.cpp */; }; - FCCB1B53248E82FD000A2F32 /* punycode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A88248E82F7000A2F32 /* punycode.cpp */; }; - FCCB1B54248E82FD000A2F32 /* schriter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A89248E82F7000A2F32 /* schriter.cpp */; }; - FCCB1B55248E82FD000A2F32 /* uset_props.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A8B248E82F8000A2F32 /* uset_props.cpp */; }; - FCCB1B56248E82FD000A2F32 /* uinit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A8C248E82F8000A2F32 /* uinit.cpp */; }; - FCCB1B57248E82FD000A2F32 /* stringpiece.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A8F248E82F8000A2F32 /* stringpiece.cpp */; }; - FCCB1B58248E82FD000A2F32 /* cstring.c in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A90248E82F8000A2F32 /* cstring.c */; }; - FCCB1B59248E82FD000A2F32 /* bytestriebuilder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A91248E82F8000A2F32 /* bytestriebuilder.cpp */; }; - FCCB1B5A248E82FD000A2F32 /* ucasemap_titlecase_brkiter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A92248E82F8000A2F32 /* ucasemap_titlecase_brkiter.cpp */; }; - FCCB1B5B248E82FD000A2F32 /* charstr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A93248E82F8000A2F32 /* charstr.cpp */; }; - FCCB1B5C248E82FD000A2F32 /* locavailable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A95248E82F9000A2F32 /* locavailable.cpp */; }; - FCCB1B5D248E82FD000A2F32 /* utrace.c in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A96248E82F9000A2F32 /* utrace.c */; }; - FCCB1B5E248E82FD000A2F32 /* ucnv_bld.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A9B248E82F9000A2F32 /* ucnv_bld.cpp */; }; - FCCB1B5F248E82FD000A2F32 /* unames.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A9E248E82F9000A2F32 /* unames.cpp */; }; - FCCB1B60248E82FD000A2F32 /* locid.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1A9F248E82FA000A2F32 /* locid.cpp */; }; - FCCB1B61248E82FD000A2F32 /* dtintrv.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1AA2248E82FA000A2F32 /* dtintrv.cpp */; }; - FCCB1B62248E82FD000A2F32 /* ulistformatter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1AA4248E82FA000A2F32 /* ulistformatter.cpp */; }; - FCCB1B63248E82FD000A2F32 /* utrie2_builder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1AA5248E82FA000A2F32 /* utrie2_builder.cpp */; }; - FCCB1B64248E82FD000A2F32 /* ucnvhz.c in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1AA6248E82FA000A2F32 /* ucnvhz.c */; }; - FCCB1B65248E82FD000A2F32 /* uniset.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1AA7248E82FA000A2F32 /* uniset.cpp */; }; - FCCB1B66248E82FD000A2F32 /* ustrfmt.c in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1AA8248E82FA000A2F32 /* ustrfmt.c */; }; - FCCB1B67248E82FD000A2F32 /* locbased.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1AA9248E82FA000A2F32 /* locbased.cpp */; }; - FCCB1B68248E82FD000A2F32 /* caniter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1AAB248E82FB000A2F32 /* caniter.cpp */; }; - FCCB1B69248E82FD000A2F32 /* udatamem.c in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1AAC248E82FB000A2F32 /* udatamem.c */; }; - FCCB1B6A248E82FD000A2F32 /* unistr_props.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1AAD248E82FB000A2F32 /* unistr_props.cpp */; }; - FCCB1B6B248E82FD000A2F32 /* icuplug.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1AAE248E82FB000A2F32 /* icuplug.cpp */; }; - FCCB1B6C248E82FD000A2F32 /* uloc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1AB1248E82FB000A2F32 /* uloc.cpp */; }; - FCCB1B6D248E82FD000A2F32 /* uset.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1AB2248E82FB000A2F32 /* uset.cpp */; }; - FCCB1B6E248E82FD000A2F32 /* uloc_keytype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1AB5248E82FC000A2F32 /* uloc_keytype.cpp */; }; - FCCB1B6F248E82FD000A2F32 /* resbund.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1AB7248E82FC000A2F32 /* resbund.cpp */; }; - FCCB1B70248E82FD000A2F32 /* appendable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1AB9248E82FC000A2F32 /* appendable.cpp */; }; - FCCB1B71248E82FD000A2F32 /* locmap.c in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1ABA248E82FC000A2F32 /* locmap.c */; }; - FCCB1D21248E8389000A2F32 /* compactdecimalformat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1BD1248E8365000A2F32 /* compactdecimalformat.cpp */; }; - FCCB1D22248E8389000A2F32 /* smallintformatter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1BD2248E8365000A2F32 /* smallintformatter.cpp */; }; - FCCB1D23248E8389000A2F32 /* tztrans.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1BD4248E8365000A2F32 /* tztrans.cpp */; }; - FCCB1D24248E8389000A2F32 /* measfmt.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1BD5248E8365000A2F32 /* measfmt.cpp */; }; - FCCB1D25248E8389000A2F32 /* utf16collationiterator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1BDB248E8366000A2F32 /* utf16collationiterator.cpp */; }; - FCCB1D26248E8389000A2F32 /* digitaffix.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1BDC248E8366000A2F32 /* digitaffix.cpp */; }; - FCCB1D27248E8389000A2F32 /* visibledigits.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1BDE248E8366000A2F32 /* visibledigits.cpp */; }; - FCCB1D28248E8389000A2F32 /* repattrn.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1BDF248E8366000A2F32 /* repattrn.cpp */; }; - FCCB1D29248E8389000A2F32 /* nortrans.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1BE0248E8366000A2F32 /* nortrans.cpp */; }; - FCCB1D2A248E8389000A2F32 /* uspoof_impl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1BE2248E8366000A2F32 /* uspoof_impl.cpp */; }; - FCCB1D2B248E8389000A2F32 /* standardplural.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1BE5248E8366000A2F32 /* standardplural.cpp */; }; - FCCB1D2C248E8389000A2F32 /* ethpccal.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1BE7248E8366000A2F32 /* ethpccal.cpp */; }; - FCCB1D2D248E8389000A2F32 /* nfsubs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1BE8248E8366000A2F32 /* nfsubs.cpp */; }; - FCCB1D2E248E8389000A2F32 /* islamcal.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1BEB248E8367000A2F32 /* islamcal.cpp */; }; - FCCB1D2F248E8389000A2F32 /* dtitvfmt.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1BEE248E8367000A2F32 /* dtitvfmt.cpp */; }; - FCCB1D30248E8389000A2F32 /* hebrwcal.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1BF0248E8367000A2F32 /* hebrwcal.cpp */; }; - FCCB1D31248E8389000A2F32 /* coptccal.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1BF1248E8367000A2F32 /* coptccal.cpp */; }; - FCCB1D32248E8389000A2F32 /* ucal.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1BF3248E8367000A2F32 /* ucal.cpp */; }; - FCCB1D33248E8389000A2F32 /* rematch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1BF5248E8367000A2F32 /* rematch.cpp */; }; - FCCB1D34248E8389000A2F32 /* strrepl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1BF6248E8368000A2F32 /* strrepl.cpp */; }; - FCCB1D35248E8389000A2F32 /* csrutf8.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1BF8248E8368000A2F32 /* csrutf8.cpp */; }; - FCCB1D36248E8389000A2F32 /* zonemeta.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1BFA248E8368000A2F32 /* zonemeta.cpp */; }; - FCCB1D37248E8389000A2F32 /* unum.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1BFC248E8368000A2F32 /* unum.cpp */; }; - FCCB1D38248E8389000A2F32 /* ztrans.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1BFD248E8368000A2F32 /* ztrans.cpp */; }; - FCCB1D39248E8389000A2F32 /* zrule.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1BFF248E8368000A2F32 /* zrule.cpp */; }; - FCCB1D3A248E8389000A2F32 /* digitaffixesandpadding.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C00248E8368000A2F32 /* digitaffixesandpadding.cpp */; }; - FCCB1D3B248E8389000A2F32 /* nfrule.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C02248E8369000A2F32 /* nfrule.cpp */; }; - FCCB1D3C248E8389000A2F32 /* numsys.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C06248E8369000A2F32 /* numsys.cpp */; }; - FCCB1D3D248E8389000A2F32 /* quant.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C08248E8369000A2F32 /* quant.cpp */; }; - FCCB1D3E248E8389000A2F32 /* calendar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C0B248E8369000A2F32 /* calendar.cpp */; }; - FCCB1D3F248E8389000A2F32 /* numfmt.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C0C248E8369000A2F32 /* numfmt.cpp */; }; - FCCB1D40248E8389000A2F32 /* dayperiodrules.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C11248E836A000A2F32 /* dayperiodrules.cpp */; }; - FCCB1D41248E8389000A2F32 /* regextxt.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C13248E836A000A2F32 /* regextxt.cpp */; }; - FCCB1D42248E8389000A2F32 /* pluralaffix.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C14248E836A000A2F32 /* pluralaffix.cpp */; }; - FCCB1D43248E8389000A2F32 /* collationtailoring.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C15248E836A000A2F32 /* collationtailoring.cpp */; }; - FCCB1D44248E8389000A2F32 /* rulebasedcollator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C1A248E836B000A2F32 /* rulebasedcollator.cpp */; }; - FCCB1D45248E8389000A2F32 /* stsearch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C1B248E836B000A2F32 /* stsearch.cpp */; }; - FCCB1D46248E8389000A2F32 /* fmtable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C1E248E836B000A2F32 /* fmtable.cpp */; }; - FCCB1D47248E8389000A2F32 /* currpinf.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C1F248E836B000A2F32 /* currpinf.cpp */; }; - FCCB1D48248E8389000A2F32 /* selfmt.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C22248E836B000A2F32 /* selfmt.cpp */; }; - FCCB1D49248E8389000A2F32 /* remtrans.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C26248E836C000A2F32 /* remtrans.cpp */; }; - FCCB1D4A248E8389000A2F32 /* toupptrn.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C27248E836C000A2F32 /* toupptrn.cpp */; }; - FCCB1D4B248E8389000A2F32 /* tznames.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C28248E836C000A2F32 /* tznames.cpp */; }; - FCCB1D4C248E8389000A2F32 /* tzrule.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C2A248E836C000A2F32 /* tzrule.cpp */; }; - FCCB1D4D248E8389000A2F32 /* ucol_sit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C2C248E836C000A2F32 /* ucol_sit.cpp */; }; - FCCB1D4E248E8389000A2F32 /* collationdatabuilder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C2E248E836C000A2F32 /* collationdatabuilder.cpp */; }; - FCCB1D4F248E8389000A2F32 /* upluralrules.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C2F248E836D000A2F32 /* upluralrules.cpp */; }; - FCCB1D50248E8389000A2F32 /* utrans.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C31248E836D000A2F32 /* utrans.cpp */; }; - FCCB1D51248E8389000A2F32 /* udat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C32248E836D000A2F32 /* udat.cpp */; }; - FCCB1D52248E8389000A2F32 /* rbt_set.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C34248E836D000A2F32 /* rbt_set.cpp */; }; - FCCB1D53248E8389000A2F32 /* uregex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C35248E836D000A2F32 /* uregex.cpp */; }; - FCCB1D54248E8389000A2F32 /* ucoleitr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C36248E836D000A2F32 /* ucoleitr.cpp */; }; - FCCB1D55248E8389000A2F32 /* decimfmtimpl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C37248E836D000A2F32 /* decimfmtimpl.cpp */; }; - FCCB1D56248E8389000A2F32 /* csr2022.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C38248E836D000A2F32 /* csr2022.cpp */; }; - FCCB1D57248E8389000A2F32 /* rbtz.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C3A248E836E000A2F32 /* rbtz.cpp */; }; - FCCB1D58248E8389000A2F32 /* nultrans.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C3B248E836E000A2F32 /* nultrans.cpp */; }; - FCCB1D59248E8389000A2F32 /* collationrootelements.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C3C248E836E000A2F32 /* collationrootelements.cpp */; }; - FCCB1D5A248E8389000A2F32 /* titletrn.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C3E248E836E000A2F32 /* titletrn.cpp */; }; - FCCB1D5B248E8389000A2F32 /* gender.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C3F248E836E000A2F32 /* gender.cpp */; }; - FCCB1D5C248E8389000A2F32 /* usearch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C40248E836E000A2F32 /* usearch.cpp */; }; - FCCB1D5D248E8389000A2F32 /* udateintervalformat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C42248E836E000A2F32 /* udateintervalformat.cpp */; }; - FCCB1D5E248E8389000A2F32 /* tzgnames.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C43248E836E000A2F32 /* tzgnames.cpp */; }; - FCCB1D5F248E8389000A2F32 /* anytrans.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C45248E836F000A2F32 /* anytrans.cpp */; }; - FCCB1D60248E8389000A2F32 /* decimalformatpattern.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C46248E836F000A2F32 /* decimalformatpattern.cpp */; }; - FCCB1D61248E8389000A2F32 /* nfrs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C49248E836F000A2F32 /* nfrs.cpp */; }; - FCCB1D62248E8389000A2F32 /* csmatch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C4B248E836F000A2F32 /* csmatch.cpp */; }; - FCCB1D63248E8389000A2F32 /* tzfmt.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C4D248E836F000A2F32 /* tzfmt.cpp */; }; - FCCB1D64248E8389000A2F32 /* valueformatter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C4E248E836F000A2F32 /* valueformatter.cpp */; }; - FCCB1D65248E8389000A2F32 /* collationfcd.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C4F248E836F000A2F32 /* collationfcd.cpp */; }; - FCCB1D66248E8389000A2F32 /* decfmtst.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C50248E8370000A2F32 /* decfmtst.cpp */; }; - FCCB1D67248E8389000A2F32 /* sortkey.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C52248E8370000A2F32 /* sortkey.cpp */; }; - FCCB1D68248E8389000A2F32 /* esctrn.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C55248E8370000A2F32 /* esctrn.cpp */; }; - FCCB1D69248E8389000A2F32 /* fphdlimp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C56248E8370000A2F32 /* fphdlimp.cpp */; }; - FCCB1D6A248E8389000A2F32 /* bocsu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C58248E8370000A2F32 /* bocsu.cpp */; }; - FCCB1D6B248E8389000A2F32 /* regexcmp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C5A248E8370000A2F32 /* regexcmp.cpp */; }; - FCCB1D6C248E8389000A2F32 /* dcfmtsym.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C5B248E8371000A2F32 /* dcfmtsym.cpp */; }; - FCCB1D6D248E8389000A2F32 /* tmunit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C5C248E8371000A2F32 /* tmunit.cpp */; }; - FCCB1D6E248E8389000A2F32 /* ucln_in.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C5E248E8371000A2F32 /* ucln_in.cpp */; }; - FCCB1D6F248E8389000A2F32 /* udatpg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C5F248E8371000A2F32 /* udatpg.cpp */; }; - FCCB1D70248E8389000A2F32 /* uspoof_build.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C61248E8371000A2F32 /* uspoof_build.cpp */; }; - FCCB1D71248E8389000A2F32 /* collationroot.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C63248E8371000A2F32 /* collationroot.cpp */; }; - FCCB1D72248E8389000A2F32 /* astro.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C65248E8371000A2F32 /* astro.cpp */; }; - FCCB1D73248E8389000A2F32 /* plurfmt.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C66248E8372000A2F32 /* plurfmt.cpp */; }; - FCCB1D74248E8389000A2F32 /* dtitvinf.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C67248E8372000A2F32 /* dtitvinf.cpp */; }; - FCCB1D75248E8389000A2F32 /* windtfmt.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C68248E8372000A2F32 /* windtfmt.cpp */; }; - FCCB1D76248E8389000A2F32 /* csdetect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C69248E8372000A2F32 /* csdetect.cpp */; }; - FCCB1D77248E8389000A2F32 /* unumsys.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C6B248E8372000A2F32 /* unumsys.cpp */; }; - FCCB1D78248E8389000A2F32 /* ufieldpositer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C6C248E8372000A2F32 /* ufieldpositer.cpp */; }; - FCCB1D79248E8389000A2F32 /* strmatch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C6D248E8372000A2F32 /* strmatch.cpp */; }; - FCCB1D7A248E8389000A2F32 /* tridpars.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C6E248E8372000A2F32 /* tridpars.cpp */; }; - FCCB1D7B248E8389000A2F32 /* uregexc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C6F248E8372000A2F32 /* uregexc.cpp */; }; - FCCB1D7C248E8389000A2F32 /* datefmt.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C70248E8372000A2F32 /* datefmt.cpp */; }; - FCCB1D7D248E8389000A2F32 /* simpletz.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C71248E8373000A2F32 /* simpletz.cpp */; }; - FCCB1D7E248E8389000A2F32 /* uregion.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C72248E8373000A2F32 /* uregion.cpp */; }; - FCCB1D7F248E8389000A2F32 /* choicfmt.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C73248E8373000A2F32 /* choicfmt.cpp */; }; - FCCB1D80248E8389000A2F32 /* dtrule.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C74248E8373000A2F32 /* dtrule.cpp */; }; - FCCB1D81248E8389000A2F32 /* coll.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C75248E8373000A2F32 /* coll.cpp */; }; - FCCB1D82248E8389000A2F32 /* inputext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C76248E8373000A2F32 /* inputext.cpp */; }; - FCCB1D83248E8389000A2F32 /* precision.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C77248E8373000A2F32 /* precision.cpp */; }; - FCCB1D84248E8389000A2F32 /* csrsbcs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C79248E8373000A2F32 /* csrsbcs.cpp */; }; - FCCB1D85248E8389000A2F32 /* smpdtfmt.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C7A248E8373000A2F32 /* smpdtfmt.cpp */; }; - FCCB1D86248E8389000A2F32 /* fmtable_cnv.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C7C248E8374000A2F32 /* fmtable_cnv.cpp */; }; - FCCB1D87248E8389000A2F32 /* collationruleparser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C7D248E8374000A2F32 /* collationruleparser.cpp */; }; - FCCB1D88248E8389000A2F32 /* buddhcal.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C7E248E8374000A2F32 /* buddhcal.cpp */; }; - FCCB1D89248E8389000A2F32 /* collationfastlatinbuilder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C7F248E8374000A2F32 /* collationfastlatinbuilder.cpp */; }; - FCCB1D8A248E8389000A2F32 /* uspoof_conf.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C81248E8374000A2F32 /* uspoof_conf.cpp */; }; - FCCB1D8B248E8389000A2F32 /* collationsettings.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C83248E8374000A2F32 /* collationsettings.cpp */; }; - FCCB1D8C248E8389000A2F32 /* collation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C84248E8374000A2F32 /* collation.cpp */; }; - FCCB1D8D248E8389000A2F32 /* basictz.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C85248E8374000A2F32 /* basictz.cpp */; }; - FCCB1D8E248E8389000A2F32 /* collationdatawriter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C86248E8375000A2F32 /* collationdatawriter.cpp */; }; - FCCB1D8F248E8389000A2F32 /* chnsecal.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C87248E8375000A2F32 /* chnsecal.cpp */; }; - FCCB1D90248E8389000A2F32 /* collationsets.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C89248E8375000A2F32 /* collationsets.cpp */; }; - FCCB1D91248E8389000A2F32 /* name2uni.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C8D248E8375000A2F32 /* name2uni.cpp */; }; - FCCB1D92248E8389000A2F32 /* ucsdet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C8F248E8375000A2F32 /* ucsdet.cpp */; }; - FCCB1D93248E8389000A2F32 /* transreg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C90248E8375000A2F32 /* transreg.cpp */; }; - FCCB1D94248E8389000A2F32 /* casetrn.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C93248E8376000A2F32 /* casetrn.cpp */; }; - FCCB1D95248E8389000A2F32 /* regeximp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C94248E8376000A2F32 /* regeximp.cpp */; }; - FCCB1D96248E8389000A2F32 /* csrucode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C98248E8376000A2F32 /* csrucode.cpp */; }; - FCCB1D97248E8389000A2F32 /* collationkeys.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C99248E8376000A2F32 /* collationkeys.cpp */; }; - FCCB1D98248E8389000A2F32 /* quantityformatter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C9B248E8377000A2F32 /* quantityformatter.cpp */; }; - FCCB1D99248E8389000A2F32 /* taiwncal.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C9C248E8377000A2F32 /* taiwncal.cpp */; }; - FCCB1D9A248E8389000A2F32 /* digitlst.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1C9E248E8377000A2F32 /* digitlst.cpp */; }; - FCCB1D9B248E8389000A2F32 /* dtptngen.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1CA0248E8377000A2F32 /* dtptngen.cpp */; }; - FCCB1D9C248E8389000A2F32 /* alphaindex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1CA2248E8377000A2F32 /* alphaindex.cpp */; }; - FCCB1D9D248E8389000A2F32 /* gregoimp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1CA3248E8377000A2F32 /* gregoimp.cpp */; }; - FCCB1D9E248E8389000A2F32 /* currunit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1CA4248E8377000A2F32 /* currunit.cpp */; }; - FCCB1D9F248E8389000A2F32 /* translit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1CA5248E8377000A2F32 /* translit.cpp */; }; - FCCB1DA0248E8389000A2F32 /* persncal.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1CA7248E8378000A2F32 /* persncal.cpp */; }; - FCCB1DA1248E8389000A2F32 /* decContext.c in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1CA8248E8378000A2F32 /* decContext.c */; }; - FCCB1DA2248E8389000A2F32 /* ucol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1CAC248E8378000A2F32 /* ucol.cpp */; }; - FCCB1DA3248E8389000A2F32 /* msgfmt.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1CAD248E8378000A2F32 /* msgfmt.cpp */; }; - FCCB1DA4248E8389000A2F32 /* rbt_data.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1CAE248E8378000A2F32 /* rbt_data.cpp */; }; - FCCB1DA5248E8389000A2F32 /* collationbuilder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1CAF248E8378000A2F32 /* collationbuilder.cpp */; }; - FCCB1DA6248E8389000A2F32 /* scientificnumberformatter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1CB0248E8379000A2F32 /* scientificnumberformatter.cpp */; }; - FCCB1DA7248E8389000A2F32 /* ucol_res.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1CB2248E8379000A2F32 /* ucol_res.cpp */; }; - FCCB1DA8248E8389000A2F32 /* uspoof.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1CB4248E8379000A2F32 /* uspoof.cpp */; }; - FCCB1DA9248E8389000A2F32 /* curramt.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1CB6248E8379000A2F32 /* curramt.cpp */; }; - FCCB1DAA248E8389000A2F32 /* japancal.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1CB7248E8379000A2F32 /* japancal.cpp */; }; - FCCB1DAB248E8389000A2F32 /* unesctrn.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1CB8248E8379000A2F32 /* unesctrn.cpp */; }; - FCCB1DAC248E8389000A2F32 /* collationiterator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1CB9248E8379000A2F32 /* collationiterator.cpp */; }; - FCCB1DAD248E8389000A2F32 /* wintzimpl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1CBA248E8379000A2F32 /* wintzimpl.cpp */; }; - FCCB1DAE248E8389000A2F32 /* collationcompare.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1CBB248E837A000A2F32 /* collationcompare.cpp */; }; - FCCB1DAF248E8389000A2F32 /* uitercollationiterator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1CBC248E837A000A2F32 /* uitercollationiterator.cpp */; }; - FCCB1DB0248E8389000A2F32 /* region.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1CBD248E837A000A2F32 /* region.cpp */; }; - FCCB1DB1248E8389000A2F32 /* measunit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1CC0248E837A000A2F32 /* measunit.cpp */; }; - FCCB1DB2248E8389000A2F32 /* umsg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1CC1248E837A000A2F32 /* umsg.cpp */; }; - FCCB1DB3248E8389000A2F32 /* affixpatternparser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1CC3248E837A000A2F32 /* affixpatternparser.cpp */; }; - FCCB1DB4248E8389000A2F32 /* indiancal.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1CC4248E837A000A2F32 /* indiancal.cpp */; }; - FCCB1DB5248E8389000A2F32 /* scriptset.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1CC9248E837B000A2F32 /* scriptset.cpp */; }; - FCCB1DB6248E8389000A2F32 /* smpdtfst.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1CCA248E837B000A2F32 /* smpdtfst.cpp */; }; - FCCB1DB7248E8389000A2F32 /* decimfmt.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1CCB248E837B000A2F32 /* decimfmt.cpp */; }; - FCCB1DB8248E8389000A2F32 /* timezone.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1CCC248E837B000A2F32 /* timezone.cpp */; }; - FCCB1DB9248E8389000A2F32 /* tznames_impl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1CD0248E837C000A2F32 /* tznames_impl.cpp */; }; - FCCB1DBA248E8389000A2F32 /* collationdata.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1CD1248E837C000A2F32 /* collationdata.cpp */; }; - FCCB1DBB248E8389000A2F32 /* vtzone.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1CD5248E837C000A2F32 /* vtzone.cpp */; }; - FCCB1DBC248E8389000A2F32 /* tmutfmt.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1CD8248E837C000A2F32 /* tmutfmt.cpp */; }; - FCCB1DBD248E8389000A2F32 /* plurrule.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1CDA248E837D000A2F32 /* plurrule.cpp */; }; - FCCB1DBE248E8389000A2F32 /* measure.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1CDB248E837D000A2F32 /* measure.cpp */; }; - FCCB1DBF248E8389000A2F32 /* digitinterval.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1CDC248E837D000A2F32 /* digitinterval.cpp */; }; - FCCB1DC0248E8389000A2F32 /* rbt_rule.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1CDD248E837D000A2F32 /* rbt_rule.cpp */; }; - FCCB1DC1248E8389000A2F32 /* regexst.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1CDF248E837D000A2F32 /* regexst.cpp */; }; - FCCB1DC2248E8389000A2F32 /* winnmfmt.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1CE0248E837D000A2F32 /* winnmfmt.cpp */; }; - FCCB1DC3248E8389000A2F32 /* reldatefmt.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1CE2248E837D000A2F32 /* reldatefmt.cpp */; }; - FCCB1DC4248E8389000A2F32 /* decNumber.c in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1CE4248E837E000A2F32 /* decNumber.c */; }; - FCCB1DC5248E8389000A2F32 /* search.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1CE7248E837E000A2F32 /* search.cpp */; }; - FCCB1DC6248E8389000A2F32 /* digitgrouping.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1CE9248E837E000A2F32 /* digitgrouping.cpp */; }; - FCCB1DC7248E8389000A2F32 /* cecal.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1CEA248E837E000A2F32 /* cecal.cpp */; }; - FCCB1DC8248E8389000A2F32 /* csrmbcs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1CEB248E837E000A2F32 /* csrmbcs.cpp */; }; - FCCB1DC9248E8389000A2F32 /* collationweights.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1CEE248E837F000A2F32 /* collationweights.cpp */; }; - FCCB1DCA248E8389000A2F32 /* tolowtrn.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1CF0248E837F000A2F32 /* tolowtrn.cpp */; }; - FCCB1DCB248E8389000A2F32 /* utmscale.c in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1CF3248E8380000A2F32 /* utmscale.c */; }; - FCCB1DCC248E8389000A2F32 /* olsontz.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1CF4248E8380000A2F32 /* olsontz.cpp */; }; - FCCB1DCD248E8389000A2F32 /* coleitr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1CF5248E8381000A2F32 /* coleitr.cpp */; }; - FCCB1DCE248E8389000A2F32 /* uni2name.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1CFA248E8382000A2F32 /* uni2name.cpp */; }; - FCCB1DCF248E8389000A2F32 /* sharedbreakiterator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1CFC248E8383000A2F32 /* sharedbreakiterator.cpp */; }; - FCCB1DD0248E8389000A2F32 /* brktrans.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1CFD248E8383000A2F32 /* brktrans.cpp */; }; - FCCB1DD1248E8389000A2F32 /* digitformatter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1CFF248E8384000A2F32 /* digitformatter.cpp */; }; - FCCB1DD2248E8389000A2F32 /* cpdtrans.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1D00248E8384000A2F32 /* cpdtrans.cpp */; }; - FCCB1DD3248E8389000A2F32 /* format.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1D01248E8384000A2F32 /* format.cpp */; }; - FCCB1DD4248E8389000A2F32 /* collationfastlatin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1D02248E8385000A2F32 /* collationfastlatin.cpp */; }; - FCCB1DD5248E8389000A2F32 /* utf8collationiterator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1D04248E8385000A2F32 /* utf8collationiterator.cpp */; }; - FCCB1DD6248E8389000A2F32 /* tmutamt.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1D05248E8385000A2F32 /* tmutamt.cpp */; }; - FCCB1DD7248E8389000A2F32 /* dtfmtsym.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1D07248E8385000A2F32 /* dtfmtsym.cpp */; }; - FCCB1DD8248E8389000A2F32 /* ulocdata.c in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1D0A248E8386000A2F32 /* ulocdata.c */; }; - FCCB1DD9248E8389000A2F32 /* fpositer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1D0C248E8386000A2F32 /* fpositer.cpp */; }; - FCCB1DDA248E8389000A2F32 /* vzone.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1D10248E8387000A2F32 /* vzone.cpp */; }; - FCCB1DDB248E8389000A2F32 /* rbt_pars.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1D11248E8387000A2F32 /* rbt_pars.cpp */; }; - FCCB1DDC248E8389000A2F32 /* csrecog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1D13248E8387000A2F32 /* csrecog.cpp */; }; - FCCB1DDD248E8389000A2F32 /* rbnf.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1D15248E8387000A2F32 /* rbnf.cpp */; }; - FCCB1DDE248E8389000A2F32 /* currfmt.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1D16248E8388000A2F32 /* currfmt.cpp */; }; - FCCB1DDF248E8389000A2F32 /* rbt.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1D18248E8388000A2F32 /* rbt.cpp */; }; - FCCB1DE0248E8389000A2F32 /* gregocal.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1D1A248E8388000A2F32 /* gregocal.cpp */; }; - FCCB1DE1248E8389000A2F32 /* reldtfmt.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1D1C248E8388000A2F32 /* reldtfmt.cpp */; }; - FCCB1DE2248E8389000A2F32 /* collationdatareader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1D1D248E8388000A2F32 /* collationdatareader.cpp */; }; - FCCB1DE3248E8389000A2F32 /* funcrepl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1D1E248E8388000A2F32 /* funcrepl.cpp */; }; - FCCB1DE4248E8389000A2F32 /* dangical.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1D20248E8389000A2F32 /* dangical.cpp */; }; - FCCB1E95248E8440000A2F32 /* ustdio.c in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1E83248E843F000A2F32 /* ustdio.c */; }; - FCCB1E96248E8440000A2F32 /* ustream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1E84248E843F000A2F32 /* ustream.cpp */; }; - FCCB1E97248E8440000A2F32 /* ufmt_cmn.c in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1E85248E843F000A2F32 /* ufmt_cmn.c */; }; - FCCB1E98248E8440000A2F32 /* ucln_io.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1E88248E843F000A2F32 /* ucln_io.cpp */; }; - FCCB1E99248E8440000A2F32 /* ufile.c in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1E89248E843F000A2F32 /* ufile.c */; }; - FCCB1E9A248E8440000A2F32 /* sscanf.c in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1E8A248E843F000A2F32 /* sscanf.c */; }; - FCCB1E9B248E8440000A2F32 /* uprintf.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1E8C248E843F000A2F32 /* uprintf.cpp */; }; - FCCB1E9C248E8440000A2F32 /* uprntf_p.c in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1E8F248E843F000A2F32 /* uprntf_p.c */; }; - FCCB1E9D248E8440000A2F32 /* locbund.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1E90248E8440000A2F32 /* locbund.cpp */; }; - FCCB1E9E248E8440000A2F32 /* uscanf_p.c in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1E91248E8440000A2F32 /* uscanf_p.c */; }; - FCCB1E9F248E8440000A2F32 /* sprintf.c in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1E92248E8440000A2F32 /* sprintf.c */; }; - FCCB1EA0248E8440000A2F32 /* uscanf.c in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1E93248E8440000A2F32 /* uscanf.c */; }; - FCCB1EA5248E845E000A2F32 /* stubdata.c in Sources */ = {isa = PBXBuildFile; fileRef = FCCB1EA4248E845E000A2F32 /* stubdata.c */; }; -/* End PBXBuildFile section */ - -/* Begin PBXCopyFilesBuildPhase section */ - 1732417E1BBECF8400E67992 /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = "include/$(PRODUCT_NAME)"; - dstSubfolderSpec = 16; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXCopyFilesBuildPhase section */ - -/* Begin PBXFileReference section */ - 173241801BBECF8400E67992 /* libicu.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libicu.a; sourceTree = BUILT_PRODUCTS_DIR; }; - FCCB19A0248E82E2000A2F32 /* uvector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uvector.h; sourceTree = ""; }; - FCCB19A1248E82E3000A2F32 /* ucnvlat1.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ucnvlat1.c; sourceTree = ""; }; - FCCB19A2248E82E3000A2F32 /* ucharstriebuilder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ucharstriebuilder.cpp; sourceTree = ""; }; - FCCB19A3248E82E3000A2F32 /* ucharstrie.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ucharstrie.cpp; sourceTree = ""; }; - FCCB19A4248E82E3000A2F32 /* ustrcase_locale.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ustrcase_locale.cpp; sourceTree = ""; }; - FCCB19A5248E82E3000A2F32 /* ucnv_cb.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ucnv_cb.c; sourceTree = ""; }; - FCCB19A6248E82E3000A2F32 /* unisetspan.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = unisetspan.h; sourceTree = ""; }; - FCCB19A7248E82E3000A2F32 /* ucnv_set.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ucnv_set.c; sourceTree = ""; }; - FCCB19A8248E82E3000A2F32 /* uvectr64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uvectr64.h; sourceTree = ""; }; - FCCB19A9248E82E3000A2F32 /* locdspnm.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = locdspnm.cpp; sourceTree = ""; }; - FCCB19AA248E82E3000A2F32 /* unistrappender.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = unistrappender.h; sourceTree = ""; }; - FCCB19AB248E82E3000A2F32 /* ustr_wcs.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ustr_wcs.cpp; sourceTree = ""; }; - FCCB19AC248E82E3000A2F32 /* msvcres.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = msvcres.h; sourceTree = ""; }; - FCCB19AD248E82E3000A2F32 /* unifilt.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = unifilt.cpp; sourceTree = ""; }; - FCCB19AE248E82E3000A2F32 /* ustr_cnv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ustr_cnv.h; sourceTree = ""; }; - FCCB19AF248E82E3000A2F32 /* bmpset.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = bmpset.h; sourceTree = ""; }; - FCCB19B0248E82E3000A2F32 /* icuplugimp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = icuplugimp.h; sourceTree = ""; }; - FCCB19B1248E82E3000A2F32 /* rbbirpt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = rbbirpt.h; sourceTree = ""; }; - FCCB19B2248E82E3000A2F32 /* ucnvdisp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ucnvdisp.c; sourceTree = ""; }; - FCCB19B3248E82E3000A2F32 /* ucln_imp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ucln_imp.h; sourceTree = ""; }; - FCCB19B4248E82E4000A2F32 /* dictbe.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dictbe.h; sourceTree = ""; }; - FCCB19B5248E82E4000A2F32 /* ucasemap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ucasemap.cpp; sourceTree = ""; }; - FCCB19B6248E82E4000A2F32 /* ucase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ucase.h; sourceTree = ""; }; - FCCB19B7248E82E4000A2F32 /* chariter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = chariter.cpp; sourceTree = ""; }; - FCCB19B8248E82E4000A2F32 /* ucnvmbcs.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ucnvmbcs.cpp; sourceTree = ""; }; - FCCB19B9248E82E4000A2F32 /* ucol_data.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ucol_data.h; sourceTree = ""; }; - FCCB19BA248E82E4000A2F32 /* pluralmap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pluralmap.h; sourceTree = ""; }; - FCCB19BB248E82E4000A2F32 /* ulist.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ulist.c; sourceTree = ""; }; - FCCB19BC248E82E4000A2F32 /* ustr_titlecase_brkiter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ustr_titlecase_brkiter.cpp; sourceTree = ""; }; - FCCB19BD248E82E4000A2F32 /* uvector.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = uvector.cpp; sourceTree = ""; }; - FCCB19BE248E82E4000A2F32 /* unistr_titlecase_brkiter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = unistr_titlecase_brkiter.cpp; sourceTree = ""; }; - FCCB19BF248E82E4000A2F32 /* ucmndata.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ucmndata.c; sourceTree = ""; }; - FCCB19C0248E82E4000A2F32 /* rbbiscan.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = rbbiscan.cpp; sourceTree = ""; }; - FCCB19C1248E82E4000A2F32 /* unistr_cnv.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = unistr_cnv.cpp; sourceTree = ""; }; - FCCB19C2248E82E5000A2F32 /* servnotf.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = servnotf.cpp; sourceTree = ""; }; - FCCB19C3248E82E5000A2F32 /* unisetspan.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = unisetspan.cpp; sourceTree = ""; }; - FCCB19C4248E82E5000A2F32 /* util.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = util.cpp; sourceTree = ""; }; - FCCB19C5248E82E5000A2F32 /* simpleformatter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = simpleformatter.cpp; sourceTree = ""; }; - FCCB19C6248E82E5000A2F32 /* rbbirb.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = rbbirb.h; sourceTree = ""; }; - FCCB19C7248E82E5000A2F32 /* norm2_nfc_data.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = norm2_nfc_data.h; sourceTree = ""; }; - FCCB19C8248E82E5000A2F32 /* uresimp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uresimp.h; sourceTree = ""; }; - FCCB19C9248E82E5000A2F32 /* cstr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = cstr.cpp; sourceTree = ""; }; - FCCB19CA248E82E5000A2F32 /* uchriter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = uchriter.cpp; sourceTree = ""; }; - FCCB19CB248E82E5000A2F32 /* ucnvisci.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ucnvisci.c; sourceTree = ""; }; - FCCB19CC248E82E6000A2F32 /* localsvc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = localsvc.h; sourceTree = ""; }; - FCCB19CD248E82E6000A2F32 /* utrie2.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = utrie2.cpp; sourceTree = ""; }; - FCCB19CE248E82E6000A2F32 /* udata.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = udata.cpp; sourceTree = ""; }; - FCCB19CF248E82E6000A2F32 /* uiter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = uiter.cpp; sourceTree = ""; }; - FCCB19D0248E82E6000A2F32 /* locdispnames.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = locdispnames.cpp; sourceTree = ""; }; - FCCB19D1248E82E6000A2F32 /* norm2allmodes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = norm2allmodes.h; sourceTree = ""; }; - FCCB19D2248E82E6000A2F32 /* ucnv_u7.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ucnv_u7.c; sourceTree = ""; }; - FCCB19D3248E82E6000A2F32 /* ucurr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ucurr.cpp; sourceTree = ""; }; - FCCB19D4248E82E6000A2F32 /* putil.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = putil.cpp; sourceTree = ""; }; - FCCB19D5248E82E6000A2F32 /* ustr_cnv.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ustr_cnv.cpp; sourceTree = ""; }; - FCCB19D6248E82E6000A2F32 /* utrie2_impl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = utrie2_impl.h; sourceTree = ""; }; - FCCB19D7248E82E7000A2F32 /* locutil.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = locutil.cpp; sourceTree = ""; }; - FCCB19D8248E82E7000A2F32 /* ubidiln.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ubidiln.c; sourceTree = ""; }; - FCCB19D9248E82E7000A2F32 /* cwchar.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = cwchar.c; sourceTree = ""; }; - FCCB19DA248E82E7000A2F32 /* rbbitblb.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = rbbitblb.h; sourceTree = ""; }; - FCCB19DB248E82E7000A2F32 /* dictionarydata.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = dictionarydata.cpp; sourceTree = ""; }; - FCCB19DC248E82E7000A2F32 /* ucnvsel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ucnvsel.cpp; sourceTree = ""; }; - FCCB19DD248E82E7000A2F32 /* ucnv_u32.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ucnv_u32.c; sourceTree = ""; }; - FCCB19DE248E82E7000A2F32 /* uvectr32.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uvectr32.h; sourceTree = ""; }; - FCCB19DF248E82E7000A2F32 /* ucnv.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ucnv.c; sourceTree = ""; }; - FCCB19E0248E82E7000A2F32 /* ucol_swp.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ucol_swp.cpp; sourceTree = ""; }; - FCCB19E1248E82E8000A2F32 /* patternprops.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = patternprops.h; sourceTree = ""; }; - FCCB19E2248E82E8000A2F32 /* uscript_props.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = uscript_props.cpp; sourceTree = ""; }; - FCCB19E3248E82E8000A2F32 /* uenumimp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uenumimp.h; sourceTree = ""; }; - FCCB19E4248E82E8000A2F32 /* unifunct.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = unifunct.cpp; sourceTree = ""; }; - FCCB19E5248E82E8000A2F32 /* umutex.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = umutex.h; sourceTree = ""; }; - FCCB19E6248E82E8000A2F32 /* punycode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = punycode.h; sourceTree = ""; }; - FCCB19E7248E82E8000A2F32 /* ucln_cmn.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ucln_cmn.cpp; sourceTree = ""; }; - FCCB19E8248E82E8000A2F32 /* usc_impl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = usc_impl.c; sourceTree = ""; }; - FCCB19E9248E82E8000A2F32 /* ustrenum.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ustrenum.cpp; sourceTree = ""; }; - FCCB19EA248E82E8000A2F32 /* rbbidata.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = rbbidata.cpp; sourceTree = ""; }; - FCCB19EB248E82E8000A2F32 /* errorcode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = errorcode.cpp; sourceTree = ""; }; - FCCB19EC248E82E9000A2F32 /* ucnv_ct.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ucnv_ct.c; sourceTree = ""; }; - FCCB19ED248E82E9000A2F32 /* ustr_imp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ustr_imp.h; sourceTree = ""; }; - FCCB19EE248E82E9000A2F32 /* unorm.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = unorm.cpp; sourceTree = ""; }; - FCCB19EF248E82E9000A2F32 /* ubidiwrt.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ubidiwrt.c; sourceTree = ""; }; - FCCB19F0248E82E9000A2F32 /* dictionarydata.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dictionarydata.h; sourceTree = ""; }; - FCCB19F1248E82E9000A2F32 /* servlk.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = servlk.cpp; sourceTree = ""; }; - FCCB19F2248E82E9000A2F32 /* ucase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ucase.cpp; sourceTree = ""; }; - FCCB19F3248E82E9000A2F32 /* sharedobject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sharedobject.cpp; sourceTree = ""; }; - FCCB19F4248E82E9000A2F32 /* ucat.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ucat.c; sourceTree = ""; }; - FCCB19F5248E82E9000A2F32 /* uchar_props_data.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uchar_props_data.h; sourceTree = ""; }; - FCCB19F6248E82E9000A2F32 /* umutex.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = umutex.cpp; sourceTree = ""; }; - FCCB19F7248E82EA000A2F32 /* ustrcase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ustrcase.cpp; sourceTree = ""; }; - FCCB19F8248E82EA000A2F32 /* uidna.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = uidna.cpp; sourceTree = ""; }; - FCCB19F9248E82EA000A2F32 /* ucnv_u16.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ucnv_u16.c; sourceTree = ""; }; - FCCB19FA248E82EA000A2F32 /* dictbe.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = dictbe.cpp; sourceTree = ""; }; - FCCB19FB248E82EA000A2F32 /* cmemory.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = cmemory.c; sourceTree = ""; }; - FCCB19FC248E82EA000A2F32 /* locbased.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = locbased.h; sourceTree = ""; }; - FCCB19FD248E82EA000A2F32 /* pluralmap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = pluralmap.cpp; sourceTree = ""; }; - FCCB19FE248E82EA000A2F32 /* uvectr32.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = uvectr32.cpp; sourceTree = ""; }; - FCCB19FF248E82EA000A2F32 /* uts46.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = uts46.cpp; sourceTree = ""; }; - FCCB1A00248E82EA000A2F32 /* uprops.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = uprops.cpp; sourceTree = ""; }; - FCCB1A01248E82EB000A2F32 /* ures_cnv.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ures_cnv.c; sourceTree = ""; }; - FCCB1A02248E82EB000A2F32 /* propsvec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = propsvec.h; sourceTree = ""; }; - FCCB1A03248E82EB000A2F32 /* uprops.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uprops.h; sourceTree = ""; }; - FCCB1A04248E82EB000A2F32 /* messagepattern.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = messagepattern.cpp; sourceTree = ""; }; - FCCB1A05248E82EB000A2F32 /* propname_data.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = propname_data.h; sourceTree = ""; }; - FCCB1A06248E82EB000A2F32 /* unormimp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = unormimp.h; sourceTree = ""; }; - FCCB1A07248E82EB000A2F32 /* usetiter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = usetiter.cpp; sourceTree = ""; }; - FCCB1A08248E82EB000A2F32 /* umath.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = umath.c; sourceTree = ""; }; - FCCB1A09248E82EB000A2F32 /* udatamem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = udatamem.h; sourceTree = ""; }; - FCCB1A0A248E82EB000A2F32 /* uloc_tag.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = uloc_tag.c; sourceTree = ""; }; - FCCB1A0B248E82EB000A2F32 /* unifiedcache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = unifiedcache.cpp; sourceTree = ""; }; - FCCB1A0C248E82EC000A2F32 /* uhash.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = uhash.c; sourceTree = ""; }; - FCCB1A0D248E82EC000A2F32 /* ucnv_u8.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ucnv_u8.c; sourceTree = ""; }; - FCCB1A0E248E82EC000A2F32 /* serv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = serv.h; sourceTree = ""; }; - FCCB1A0F248E82EC000A2F32 /* ucnv_imp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ucnv_imp.h; sourceTree = ""; }; - FCCB1A10248E82EC000A2F32 /* sprpimpl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sprpimpl.h; sourceTree = ""; }; - FCCB1A11248E82EC000A2F32 /* uchar.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = uchar.c; sourceTree = ""; }; - FCCB1A12248E82EC000A2F32 /* bytestream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = bytestream.cpp; sourceTree = ""; }; - FCCB1A13248E82EC000A2F32 /* rbbistbl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = rbbistbl.cpp; sourceTree = ""; }; - FCCB1A14248E82EC000A2F32 /* servlkf.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = servlkf.cpp; sourceTree = ""; }; - FCCB1A15248E82EC000A2F32 /* uobject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = uobject.cpp; sourceTree = ""; }; - FCCB1A16248E82EC000A2F32 /* uresdata.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = uresdata.cpp; sourceTree = ""; }; - FCCB1A17248E82ED000A2F32 /* propname.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = propname.cpp; sourceTree = ""; }; - FCCB1A18248E82ED000A2F32 /* ubidi_props.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ubidi_props.c; sourceTree = ""; }; - FCCB1A19248E82ED000A2F32 /* resource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = resource.h; sourceTree = ""; }; - FCCB1A1A248E82ED000A2F32 /* udataswp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = udataswp.c; sourceTree = ""; }; - FCCB1A1B248E82ED000A2F32 /* locutil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = locutil.h; sourceTree = ""; }; - FCCB1A1C248E82ED000A2F32 /* bmpset.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = bmpset.cpp; sourceTree = ""; }; - FCCB1A1D248E82ED000A2F32 /* patternprops.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = patternprops.cpp; sourceTree = ""; }; - FCCB1A1E248E82ED000A2F32 /* ucnv_cnv.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ucnv_cnv.c; sourceTree = ""; }; - FCCB1A1F248E82ED000A2F32 /* utext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = utext.cpp; sourceTree = ""; }; - FCCB1A20248E82ED000A2F32 /* filterednormalizer2.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = filterednormalizer2.cpp; sourceTree = ""; }; - FCCB1A21248E82ED000A2F32 /* ucnv_lmb.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ucnv_lmb.c; sourceTree = ""; }; - FCCB1A22248E82ED000A2F32 /* umapfile.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = umapfile.c; sourceTree = ""; }; - FCCB1A23248E82EE000A2F32 /* ubidi_props_data.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ubidi_props_data.h; sourceTree = ""; }; - FCCB1A24248E82EE000A2F32 /* util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = util.h; sourceTree = ""; }; - FCCB1A25248E82EE000A2F32 /* utrie.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = utrie.cpp; sourceTree = ""; }; - FCCB1A26248E82EE000A2F32 /* servslkf.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = servslkf.cpp; sourceTree = ""; }; - FCCB1A27248E82EE000A2F32 /* ustack.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ustack.cpp; sourceTree = ""; }; - FCCB1A28248E82EE000A2F32 /* stringtriebuilder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = stringtriebuilder.cpp; sourceTree = ""; }; - FCCB1A29248E82EE000A2F32 /* mutex.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mutex.h; sourceTree = ""; }; - FCCB1A2A248E82EE000A2F32 /* ubidiimp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ubidiimp.h; sourceTree = ""; }; - FCCB1A2B248E82EE000A2F32 /* unistr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = unistr.cpp; sourceTree = ""; }; - FCCB1A2C248E82EE000A2F32 /* uhash.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uhash.h; sourceTree = ""; }; - FCCB1A2D248E82EE000A2F32 /* rbbidata.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = rbbidata.h; sourceTree = ""; }; - FCCB1A2E248E82EF000A2F32 /* rbbitblb.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = rbbitblb.cpp; sourceTree = ""; }; - FCCB1A2F248E82EF000A2F32 /* servrbf.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = servrbf.cpp; sourceTree = ""; }; - FCCB1A30248E82EF000A2F32 /* unistr_case.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = unistr_case.cpp; sourceTree = ""; }; - FCCB1A31248E82EF000A2F32 /* uscript.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = uscript.c; sourceTree = ""; }; - FCCB1A32248E82EF000A2F32 /* unormcmp.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = unormcmp.cpp; sourceTree = ""; }; - FCCB1A33248E82EF000A2F32 /* ucharstrieiterator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ucharstrieiterator.cpp; sourceTree = ""; }; - FCCB1A34248E82EF000A2F32 /* utracimp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = utracimp.h; sourceTree = ""; }; - FCCB1A35248E82EF000A2F32 /* uresbund.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = uresbund.cpp; sourceTree = ""; }; - FCCB1A36248E82F0000A2F32 /* serv.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = serv.cpp; sourceTree = ""; }; - FCCB1A37248E82F0000A2F32 /* locmap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = locmap.h; sourceTree = ""; }; - FCCB1A38248E82F0000A2F32 /* uset_imp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uset_imp.h; sourceTree = ""; }; - FCCB1A39248E82F0000A2F32 /* utf_impl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = utf_impl.c; sourceTree = ""; }; - FCCB1A3A248E82F0000A2F32 /* uarrsort.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = uarrsort.c; sourceTree = ""; }; - FCCB1A3B248E82F0000A2F32 /* rbbi.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = rbbi.cpp; sourceTree = ""; }; - FCCB1A3C248E82F0000A2F32 /* bytestrie.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = bytestrie.cpp; sourceTree = ""; }; - FCCB1A3D248E82F0000A2F32 /* charstr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = charstr.h; sourceTree = ""; }; - FCCB1A3E248E82F0000A2F32 /* parsepos.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = parsepos.cpp; sourceTree = ""; }; - FCCB1A3F248E82F0000A2F32 /* utypes.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = utypes.c; sourceTree = ""; }; - FCCB1A40248E82F0000A2F32 /* utrie2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = utrie2.h; sourceTree = ""; }; - FCCB1A41248E82F1000A2F32 /* loadednormalizer2impl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = loadednormalizer2impl.cpp; sourceTree = ""; }; - FCCB1A42248E82F1000A2F32 /* rbbinode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = rbbinode.h; sourceTree = ""; }; - FCCB1A43248E82F1000A2F32 /* ucln.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ucln.h; sourceTree = ""; }; - FCCB1A44248E82F1000A2F32 /* udataswp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = udataswp.h; sourceTree = ""; }; - FCCB1A45248E82F1000A2F32 /* ucmndata.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ucmndata.h; sourceTree = ""; }; - FCCB1A46248E82F1000A2F32 /* ruleiter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ruleiter.cpp; sourceTree = ""; }; - FCCB1A47248E82F1000A2F32 /* ustrenum.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ustrenum.h; sourceTree = ""; }; - FCCB1A48248E82F1000A2F32 /* ubiditransform.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ubiditransform.c; sourceTree = ""; }; - FCCB1A49248E82F1000A2F32 /* ucnv_err.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ucnv_err.c; sourceTree = ""; }; - FCCB1A4A248E82F1000A2F32 /* uhash_us.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = uhash_us.cpp; sourceTree = ""; }; - FCCB1A4B248E82F2000A2F32 /* usc_impl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = usc_impl.h; sourceTree = ""; }; - FCCB1A4C248E82F2000A2F32 /* uinvchar.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = uinvchar.c; sourceTree = ""; }; - FCCB1A4D248E82F2000A2F32 /* ucnvbocu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ucnvbocu.cpp; sourceTree = ""; }; - FCCB1A4E248E82F2000A2F32 /* propsvec.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = propsvec.c; sourceTree = ""; }; - FCCB1A4F248E82F2000A2F32 /* utypeinfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = utypeinfo.h; sourceTree = ""; }; - FCCB1A50248E82F2000A2F32 /* ucnv_io.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ucnv_io.h; sourceTree = ""; }; - FCCB1A51248E82F2000A2F32 /* wintz.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = wintz.c; sourceTree = ""; }; - FCCB1A52248E82F2000A2F32 /* bytestrieiterator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = bytestrieiterator.cpp; sourceTree = ""; }; - FCCB1A53248E82F2000A2F32 /* ushape.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ushape.cpp; sourceTree = ""; }; - FCCB1A54248E82F3000A2F32 /* cpputils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cpputils.h; sourceTree = ""; }; - FCCB1A55248E82F3000A2F32 /* brkeng.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = brkeng.cpp; sourceTree = ""; }; - FCCB1A56248E82F3000A2F32 /* icudataver.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = icudataver.c; sourceTree = ""; }; - FCCB1A57248E82F3000A2F32 /* ucol_swp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ucol_swp.h; sourceTree = ""; }; - FCCB1A58248E82F3000A2F32 /* rbbirb.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = rbbirb.cpp; sourceTree = ""; }; - FCCB1A59248E82F3000A2F32 /* cstring.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cstring.h; sourceTree = ""; }; - FCCB1A5A248E82F3000A2F32 /* ustrtrns.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ustrtrns.cpp; sourceTree = ""; }; - FCCB1A5B248E82F3000A2F32 /* normalizer2.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = normalizer2.cpp; sourceTree = ""; }; - FCCB1A5C248E82F3000A2F32 /* unifiedcache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = unifiedcache.h; sourceTree = ""; }; - FCCB1A5D248E82F3000A2F32 /* ucnv_cnv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ucnv_cnv.h; sourceTree = ""; }; - FCCB1A5E248E82F3000A2F32 /* unistr_case_locale.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = unistr_case_locale.cpp; sourceTree = ""; }; - FCCB1A5F248E82F4000A2F32 /* cwchar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cwchar.h; sourceTree = ""; }; - FCCB1A60248E82F4000A2F32 /* ucnvmbcs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ucnvmbcs.h; sourceTree = ""; }; - FCCB1A61248E82F4000A2F32 /* rbbinode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = rbbinode.cpp; sourceTree = ""; }; - FCCB1A62248E82F4000A2F32 /* ustrfmt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ustrfmt.h; sourceTree = ""; }; - FCCB1A63248E82F4000A2F32 /* uvectr64.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = uvectr64.cpp; sourceTree = ""; }; - FCCB1A64248E82F4000A2F32 /* uassert.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uassert.h; sourceTree = ""; }; - FCCB1A65248E82F4000A2F32 /* ureslocs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ureslocs.h; sourceTree = ""; }; - FCCB1A66248E82F4000A2F32 /* ucnv_io.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ucnv_io.cpp; sourceTree = ""; }; - FCCB1A67248E82F4000A2F32 /* servls.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = servls.cpp; sourceTree = ""; }; - FCCB1A68248E82F4000A2F32 /* uniset_props.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = uniset_props.cpp; sourceTree = ""; }; - FCCB1A69248E82F4000A2F32 /* ucln_cmn.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ucln_cmn.h; sourceTree = ""; }; - FCCB1A6A248E82F5000A2F32 /* ucurrimp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ucurrimp.h; sourceTree = ""; }; - FCCB1A6B248E82F5000A2F32 /* uenum.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = uenum.c; sourceTree = ""; }; - FCCB1A6C248E82F5000A2F32 /* uposixdefs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uposixdefs.h; sourceTree = ""; }; - FCCB1A6D248E82F5000A2F32 /* listformatter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = listformatter.cpp; sourceTree = ""; }; - FCCB1A6E248E82F5000A2F32 /* normalizer2impl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = normalizer2impl.h; sourceTree = ""; }; - FCCB1A6F248E82F5000A2F32 /* loclikely.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = loclikely.cpp; sourceTree = ""; }; - FCCB1A70248E82F5000A2F32 /* uresdata.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uresdata.h; sourceTree = ""; }; - FCCB1A71248E82F5000A2F32 /* putilimp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = putilimp.h; sourceTree = ""; }; - FCCB1A72248E82F5000A2F32 /* ucase_props_data.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ucase_props_data.h; sourceTree = ""; }; - FCCB1A73248E82F5000A2F32 /* normlzr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = normlzr.cpp; sourceTree = ""; }; - FCCB1A74248E82F5000A2F32 /* resource.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = resource.cpp; sourceTree = ""; }; - FCCB1A75248E82F6000A2F32 /* normalizer2impl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = normalizer2impl.cpp; sourceTree = ""; }; - FCCB1A76248E82F6000A2F32 /* filteredbrk.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = filteredbrk.cpp; sourceTree = ""; }; - FCCB1A77248E82F6000A2F32 /* ubidi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ubidi.c; sourceTree = ""; }; - FCCB1A78248E82F6000A2F32 /* ucnvscsu.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ucnvscsu.c; sourceTree = ""; }; - FCCB1A79248E82F6000A2F32 /* ucnv2022.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ucnv2022.cpp; sourceTree = ""; }; - FCCB1A7A248E82F6000A2F32 /* ustring.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ustring.cpp; sourceTree = ""; }; - FCCB1A7B248E82F6000A2F32 /* uniset_closure.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = uniset_closure.cpp; sourceTree = ""; }; - FCCB1A7C248E82F6000A2F32 /* util_props.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = util_props.cpp; sourceTree = ""; }; - FCCB1A7D248E82F6000A2F32 /* resbund_cnv.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = resbund_cnv.cpp; sourceTree = ""; }; - FCCB1A7E248E82F6000A2F32 /* ruleiter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ruleiter.h; sourceTree = ""; }; - FCCB1A7F248E82F6000A2F32 /* cstr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cstr.h; sourceTree = ""; }; - FCCB1A80248E82F7000A2F32 /* uinvchar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uinvchar.h; sourceTree = ""; }; - FCCB1A81248E82F7000A2F32 /* usprep.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = usprep.cpp; sourceTree = ""; }; - FCCB1A82248E82F7000A2F32 /* brkiter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = brkiter.cpp; sourceTree = ""; }; - FCCB1A83248E82F7000A2F32 /* ubrk.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ubrk.cpp; sourceTree = ""; }; - FCCB1A84248E82F7000A2F32 /* wintz.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wintz.h; sourceTree = ""; }; - FCCB1A85248E82F7000A2F32 /* rbbisetb.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = rbbisetb.cpp; sourceTree = ""; }; - FCCB1A86248E82F7000A2F32 /* locresdata.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = locresdata.cpp; sourceTree = ""; }; - FCCB1A87248E82F7000A2F32 /* ucnv_ext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ucnv_ext.cpp; sourceTree = ""; }; - FCCB1A88248E82F7000A2F32 /* punycode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = punycode.cpp; sourceTree = ""; }; - FCCB1A89248E82F7000A2F32 /* schriter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = schriter.cpp; sourceTree = ""; }; - FCCB1A8A248E82F7000A2F32 /* umapfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = umapfile.h; sourceTree = ""; }; - FCCB1A8B248E82F8000A2F32 /* uset_props.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = uset_props.cpp; sourceTree = ""; }; - FCCB1A8C248E82F8000A2F32 /* uinit.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = uinit.cpp; sourceTree = ""; }; - FCCB1A8D248E82F8000A2F32 /* servloc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = servloc.h; sourceTree = ""; }; - FCCB1A8E248E82F8000A2F32 /* sharedobject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sharedobject.h; sourceTree = ""; }; - FCCB1A8F248E82F8000A2F32 /* stringpiece.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = stringpiece.cpp; sourceTree = ""; }; - FCCB1A90248E82F8000A2F32 /* cstring.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = cstring.c; sourceTree = ""; }; - FCCB1A91248E82F8000A2F32 /* bytestriebuilder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = bytestriebuilder.cpp; sourceTree = ""; }; - FCCB1A92248E82F8000A2F32 /* ucasemap_titlecase_brkiter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ucasemap_titlecase_brkiter.cpp; sourceTree = ""; }; - FCCB1A93248E82F8000A2F32 /* charstr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = charstr.cpp; sourceTree = ""; }; - FCCB1A94248E82F8000A2F32 /* servnotf.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = servnotf.h; sourceTree = ""; }; - FCCB1A95248E82F9000A2F32 /* locavailable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = locavailable.cpp; sourceTree = ""; }; - FCCB1A96248E82F9000A2F32 /* utrace.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = utrace.c; sourceTree = ""; }; - FCCB1A97248E82F9000A2F32 /* cmemory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cmemory.h; sourceTree = ""; }; - FCCB1A98248E82F9000A2F32 /* rbbisetb.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = rbbisetb.h; sourceTree = ""; }; - FCCB1A99248E82F9000A2F32 /* rbbiscan.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = rbbiscan.h; sourceTree = ""; }; - FCCB1A9A248E82F9000A2F32 /* hash.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = hash.h; sourceTree = ""; }; - FCCB1A9B248E82F9000A2F32 /* ucnv_bld.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ucnv_bld.cpp; sourceTree = ""; }; - FCCB1A9C248E82F9000A2F32 /* uelement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uelement.h; sourceTree = ""; }; - FCCB1A9D248E82F9000A2F32 /* brkeng.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = brkeng.h; sourceTree = ""; }; - FCCB1A9E248E82F9000A2F32 /* unames.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = unames.cpp; sourceTree = ""; }; - FCCB1A9F248E82FA000A2F32 /* locid.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = locid.cpp; sourceTree = ""; }; - FCCB1AA0248E82FA000A2F32 /* messageimpl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = messageimpl.h; sourceTree = ""; }; - FCCB1AA1248E82FA000A2F32 /* uarrsort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uarrsort.h; sourceTree = ""; }; - FCCB1AA2248E82FA000A2F32 /* dtintrv.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = dtintrv.cpp; sourceTree = ""; }; - FCCB1AA3248E82FA000A2F32 /* ucnv_bld.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ucnv_bld.h; sourceTree = ""; }; - FCCB1AA4248E82FA000A2F32 /* ulistformatter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ulistformatter.cpp; sourceTree = ""; }; - FCCB1AA5248E82FA000A2F32 /* utrie2_builder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = utrie2_builder.cpp; sourceTree = ""; }; - FCCB1AA6248E82FA000A2F32 /* ucnvhz.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ucnvhz.c; sourceTree = ""; }; - FCCB1AA7248E82FA000A2F32 /* uniset.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = uniset.cpp; sourceTree = ""; }; - FCCB1AA8248E82FA000A2F32 /* ustrfmt.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ustrfmt.c; sourceTree = ""; }; - FCCB1AA9248E82FA000A2F32 /* locbased.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = locbased.cpp; sourceTree = ""; }; - FCCB1AAA248E82FB000A2F32 /* ubidi_props.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ubidi_props.h; sourceTree = ""; }; - FCCB1AAB248E82FB000A2F32 /* caniter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = caniter.cpp; sourceTree = ""; }; - FCCB1AAC248E82FB000A2F32 /* udatamem.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = udatamem.c; sourceTree = ""; }; - FCCB1AAD248E82FB000A2F32 /* unistr_props.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = unistr_props.cpp; sourceTree = ""; }; - FCCB1AAE248E82FB000A2F32 /* icuplug.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = icuplug.cpp; sourceTree = ""; }; - FCCB1AAF248E82FB000A2F32 /* propname.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = propname.h; sourceTree = ""; }; - FCCB1AB0248E82FB000A2F32 /* ulist.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ulist.h; sourceTree = ""; }; - FCCB1AB1248E82FB000A2F32 /* uloc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = uloc.cpp; sourceTree = ""; }; - FCCB1AB2248E82FB000A2F32 /* uset.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = uset.cpp; sourceTree = ""; }; - FCCB1AB3248E82FB000A2F32 /* ubrkimpl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ubrkimpl.h; sourceTree = ""; }; - FCCB1AB4248E82FC000A2F32 /* ucnv_ext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ucnv_ext.h; sourceTree = ""; }; - FCCB1AB5248E82FC000A2F32 /* uloc_keytype.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = uloc_keytype.cpp; sourceTree = ""; }; - FCCB1AB6248E82FC000A2F32 /* ulocimp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ulocimp.h; sourceTree = ""; }; - FCCB1AB7248E82FC000A2F32 /* resbund.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = resbund.cpp; sourceTree = ""; }; - FCCB1AB8248E82FC000A2F32 /* utrie.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = utrie.h; sourceTree = ""; }; - FCCB1AB9248E82FC000A2F32 /* appendable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = appendable.cpp; sourceTree = ""; }; - FCCB1ABA248E82FC000A2F32 /* locmap.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = locmap.c; sourceTree = ""; }; - FCCB1B73248E8305000A2F32 /* utf_old.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = utf_old.h; sourceTree = ""; }; - FCCB1B74248E8305000A2F32 /* ubrk.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ubrk.h; sourceTree = ""; }; - FCCB1B75248E8305000A2F32 /* stringpiece.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = stringpiece.h; sourceTree = ""; }; - FCCB1B76248E8305000A2F32 /* ucat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ucat.h; sourceTree = ""; }; - FCCB1B77248E8305000A2F32 /* ptypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ptypes.h; sourceTree = ""; }; - FCCB1B78248E8305000A2F32 /* usetiter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = usetiter.h; sourceTree = ""; }; - FCCB1B79248E8305000A2F32 /* errorcode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = errorcode.h; sourceTree = ""; }; - FCCB1B7A248E8305000A2F32 /* dtintrv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dtintrv.h; sourceTree = ""; }; - FCCB1B7B248E8305000A2F32 /* ucurr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ucurr.h; sourceTree = ""; }; - FCCB1B7C248E8305000A2F32 /* icuplug.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = icuplug.h; sourceTree = ""; }; - FCCB1B7D248E8305000A2F32 /* utext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = utext.h; sourceTree = ""; }; - FCCB1B7E248E8305000A2F32 /* parsepos.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = parsepos.h; sourceTree = ""; }; - FCCB1B7F248E8305000A2F32 /* urep.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = urep.h; sourceTree = ""; }; - FCCB1B80248E8305000A2F32 /* utf32.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = utf32.h; sourceTree = ""; }; - FCCB1B81248E8305000A2F32 /* ustring.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ustring.h; sourceTree = ""; }; - FCCB1B82248E8305000A2F32 /* ubiditransform.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ubiditransform.h; sourceTree = ""; }; - FCCB1B83248E8305000A2F32 /* uenum.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uenum.h; sourceTree = ""; }; - FCCB1B84248E8305000A2F32 /* appendable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = appendable.h; sourceTree = ""; }; - FCCB1B85248E8305000A2F32 /* uset.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uset.h; sourceTree = ""; }; - FCCB1B87248E8305000A2F32 /* schriter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = schriter.h; sourceTree = ""; }; - FCCB1B88248E8305000A2F32 /* uldnames.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uldnames.h; sourceTree = ""; }; - FCCB1B89248E8305000A2F32 /* uiter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uiter.h; sourceTree = ""; }; - FCCB1B8A248E8305000A2F32 /* docmain.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = docmain.h; sourceTree = ""; }; - FCCB1B8B248E8305000A2F32 /* uniset.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uniset.h; sourceTree = ""; }; - FCCB1B8C248E8305000A2F32 /* udata.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = udata.h; sourceTree = ""; }; - FCCB1B8D248E8305000A2F32 /* stringtriebuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = stringtriebuilder.h; sourceTree = ""; }; - FCCB1B8E248E8305000A2F32 /* chariter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = chariter.h; sourceTree = ""; }; - FCCB1B8F248E8305000A2F32 /* umisc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = umisc.h; sourceTree = ""; }; - FCCB1B90248E8305000A2F32 /* uloc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uloc.h; sourceTree = ""; }; - FCCB1B91248E8305000A2F32 /* bytestriebuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = bytestriebuilder.h; sourceTree = ""; }; - FCCB1B92248E8305000A2F32 /* utrace.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = utrace.h; sourceTree = ""; }; - FCCB1B93248E8305000A2F32 /* locdspnm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = locdspnm.h; sourceTree = ""; }; - FCCB1B94248E8305000A2F32 /* uchriter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uchriter.h; sourceTree = ""; }; - FCCB1B95248E8305000A2F32 /* enumset.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = enumset.h; sourceTree = ""; }; - FCCB1B96248E8305000A2F32 /* utf.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = utf.h; sourceTree = ""; }; - FCCB1B97248E8305000A2F32 /* strenum.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = strenum.h; sourceTree = ""; }; - FCCB1B98248E8305000A2F32 /* ucnv_err.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ucnv_err.h; sourceTree = ""; }; - FCCB1B99248E8305000A2F32 /* bytestrie.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = bytestrie.h; sourceTree = ""; }; - FCCB1B9A248E8305000A2F32 /* listformatter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = listformatter.h; sourceTree = ""; }; - FCCB1B9B248E8305000A2F32 /* uobject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uobject.h; sourceTree = ""; }; - FCCB1B9C248E8305000A2F32 /* ures.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ures.h; sourceTree = ""; }; - FCCB1B9D248E8305000A2F32 /* normlzr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = normlzr.h; sourceTree = ""; }; - FCCB1B9E248E8305000A2F32 /* usprep.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = usprep.h; sourceTree = ""; }; - FCCB1B9F248E8305000A2F32 /* urename.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = urename.h; sourceTree = ""; }; - FCCB1BA0248E8305000A2F32 /* caniter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = caniter.h; sourceTree = ""; }; - FCCB1BA1248E8305000A2F32 /* ucharstrie.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ucharstrie.h; sourceTree = ""; }; - FCCB1BA2248E8305000A2F32 /* unistr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = unistr.h; sourceTree = ""; }; - FCCB1BA3248E8305000A2F32 /* rbbi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = rbbi.h; sourceTree = ""; }; - FCCB1BA4248E8305000A2F32 /* idna.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = idna.h; sourceTree = ""; }; - FCCB1BA5248E8305000A2F32 /* unorm2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = unorm2.h; sourceTree = ""; }; - FCCB1BA6248E8305000A2F32 /* dbbi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dbbi.h; sourceTree = ""; }; - FCCB1BA7248E8305000A2F32 /* bytestream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = bytestream.h; sourceTree = ""; }; - FCCB1BA8248E8305000A2F32 /* uversion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uversion.h; sourceTree = ""; }; - FCCB1BA9248E8305000A2F32 /* messagepattern.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = messagepattern.h; sourceTree = ""; }; - FCCB1BAA248E8305000A2F32 /* uidna.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uidna.h; sourceTree = ""; }; - FCCB1BAB248E8305000A2F32 /* filteredbrk.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = filteredbrk.h; sourceTree = ""; }; - FCCB1BAC248E8305000A2F32 /* symtable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = symtable.h; sourceTree = ""; }; - FCCB1BAD248E8305000A2F32 /* ucasemap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ucasemap.h; sourceTree = ""; }; - FCCB1BAE248E8305000A2F32 /* udisplaycontext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = udisplaycontext.h; sourceTree = ""; }; - FCCB1BAF248E8305000A2F32 /* umachine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = umachine.h; sourceTree = ""; }; - FCCB1BB0248E8305000A2F32 /* ustringtrie.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ustringtrie.h; sourceTree = ""; }; - FCCB1BB1248E8305000A2F32 /* icudataver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = icudataver.h; sourceTree = ""; }; - FCCB1BB2248E8305000A2F32 /* uchar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uchar.h; sourceTree = ""; }; - FCCB1BB3248E8305000A2F32 /* unorm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = unorm.h; sourceTree = ""; }; - FCCB1BB4248E8305000A2F32 /* ushape.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ushape.h; sourceTree = ""; }; - FCCB1BB5248E8305000A2F32 /* unifunct.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = unifunct.h; sourceTree = ""; }; - FCCB1BB6248E8305000A2F32 /* simpleformatter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = simpleformatter.h; sourceTree = ""; }; - FCCB1BB7248E8305000A2F32 /* ucnv_cb.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ucnv_cb.h; sourceTree = ""; }; - FCCB1BB8248E8305000A2F32 /* locid.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = locid.h; sourceTree = ""; }; - FCCB1BB9248E8305000A2F32 /* resbund.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = resbund.h; sourceTree = ""; }; - FCCB1BBA248E8305000A2F32 /* ubidi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ubidi.h; sourceTree = ""; }; - FCCB1BBB248E8305000A2F32 /* uvernum.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uvernum.h; sourceTree = ""; }; - FCCB1BBC248E8305000A2F32 /* unimatch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = unimatch.h; sourceTree = ""; }; - FCCB1BBD248E8305000A2F32 /* ucnvsel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ucnvsel.h; sourceTree = ""; }; - FCCB1BBE248E8305000A2F32 /* parseerr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = parseerr.h; sourceTree = ""; }; - FCCB1BBF248E8305000A2F32 /* putil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = putil.h; sourceTree = ""; }; - FCCB1BC0248E8305000A2F32 /* normalizer2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = normalizer2.h; sourceTree = ""; }; - FCCB1BC1248E8305000A2F32 /* ucnv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ucnv.h; sourceTree = ""; }; - FCCB1BC2248E8305000A2F32 /* ucharstriebuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ucharstriebuilder.h; sourceTree = ""; }; - FCCB1BC3248E8305000A2F32 /* uconfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uconfig.h; sourceTree = ""; }; - FCCB1BC4248E8305000A2F32 /* utf16.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = utf16.h; sourceTree = ""; }; - FCCB1BC5248E8305000A2F32 /* brkiter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = brkiter.h; sourceTree = ""; }; - FCCB1BC6248E8305000A2F32 /* platform.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = platform.h; sourceTree = ""; }; - FCCB1BC7248E8305000A2F32 /* rep.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = rep.h; sourceTree = ""; }; - FCCB1BC9248E8305000A2F32 /* std_string.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = std_string.h; sourceTree = ""; }; - FCCB1BCA248E8305000A2F32 /* utf8.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = utf8.h; sourceTree = ""; }; - FCCB1BCB248E8305000A2F32 /* localpointer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = localpointer.h; sourceTree = ""; }; - FCCB1BCC248E8305000A2F32 /* uclean.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uclean.h; sourceTree = ""; }; - FCCB1BCD248E8305000A2F32 /* uscript.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uscript.h; sourceTree = ""; }; - FCCB1BCE248E8305000A2F32 /* utypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = utypes.h; sourceTree = ""; }; - FCCB1BCF248E8305000A2F32 /* ulistformatter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ulistformatter.h; sourceTree = ""; }; - FCCB1BD0248E8305000A2F32 /* unifilt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = unifilt.h; sourceTree = ""; }; - FCCB1BD1248E8365000A2F32 /* compactdecimalformat.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = compactdecimalformat.cpp; sourceTree = ""; }; - FCCB1BD2248E8365000A2F32 /* smallintformatter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = smallintformatter.cpp; sourceTree = ""; }; - FCCB1BD3248E8365000A2F32 /* standardplural.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = standardplural.h; sourceTree = ""; }; - FCCB1BD4248E8365000A2F32 /* tztrans.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = tztrans.cpp; sourceTree = ""; }; - FCCB1BD5248E8365000A2F32 /* measfmt.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = measfmt.cpp; sourceTree = ""; }; - FCCB1BD6248E8365000A2F32 /* dangical.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dangical.h; sourceTree = ""; }; - FCCB1BD7248E8365000A2F32 /* sharedbreakiterator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sharedbreakiterator.h; sourceTree = ""; }; - FCCB1BD8248E8365000A2F32 /* rbt_rule.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = rbt_rule.h; sourceTree = ""; }; - FCCB1BD9248E8366000A2F32 /* decimfmtimpl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = decimfmtimpl.h; sourceTree = ""; }; - FCCB1BDA248E8366000A2F32 /* zrule.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = zrule.h; sourceTree = ""; }; - FCCB1BDB248E8366000A2F32 /* utf16collationiterator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = utf16collationiterator.cpp; sourceTree = ""; }; - FCCB1BDC248E8366000A2F32 /* digitaffix.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = digitaffix.cpp; sourceTree = ""; }; - FCCB1BDD248E8366000A2F32 /* dtitv_impl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dtitv_impl.h; sourceTree = ""; }; - FCCB1BDE248E8366000A2F32 /* visibledigits.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = visibledigits.cpp; sourceTree = ""; }; - FCCB1BDF248E8366000A2F32 /* repattrn.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = repattrn.cpp; sourceTree = ""; }; - FCCB1BE0248E8366000A2F32 /* nortrans.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = nortrans.cpp; sourceTree = ""; }; - FCCB1BE1248E8366000A2F32 /* valueformatter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = valueformatter.h; sourceTree = ""; }; - FCCB1BE2248E8366000A2F32 /* uspoof_impl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = uspoof_impl.cpp; sourceTree = ""; }; - FCCB1BE3248E8366000A2F32 /* sharednumberformat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sharednumberformat.h; sourceTree = ""; }; - FCCB1BE4248E8366000A2F32 /* toupptrn.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = toupptrn.h; sourceTree = ""; }; - FCCB1BE5248E8366000A2F32 /* standardplural.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = standardplural.cpp; sourceTree = ""; }; - FCCB1BE6248E8366000A2F32 /* collationfastlatinbuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = collationfastlatinbuilder.h; sourceTree = ""; }; - FCCB1BE7248E8366000A2F32 /* ethpccal.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ethpccal.cpp; sourceTree = ""; }; - FCCB1BE8248E8366000A2F32 /* nfsubs.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = nfsubs.cpp; sourceTree = ""; }; - FCCB1BE9248E8366000A2F32 /* ucln_in.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ucln_in.h; sourceTree = ""; }; - FCCB1BEA248E8367000A2F32 /* collationbuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = collationbuilder.h; sourceTree = ""; }; - FCCB1BEB248E8367000A2F32 /* islamcal.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = islamcal.cpp; sourceTree = ""; }; - FCCB1BEC248E8367000A2F32 /* dcfmtimp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dcfmtimp.h; sourceTree = ""; }; - FCCB1BED248E8367000A2F32 /* decfmtst.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = decfmtst.h; sourceTree = ""; }; - FCCB1BEE248E8367000A2F32 /* dtitvfmt.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = dtitvfmt.cpp; sourceTree = ""; }; - FCCB1BEF248E8367000A2F32 /* fmtableimp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fmtableimp.h; sourceTree = ""; }; - FCCB1BF0248E8367000A2F32 /* hebrwcal.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = hebrwcal.cpp; sourceTree = ""; }; - FCCB1BF1248E8367000A2F32 /* coptccal.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = coptccal.cpp; sourceTree = ""; }; - FCCB1BF2248E8367000A2F32 /* tridpars.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tridpars.h; sourceTree = ""; }; - FCCB1BF3248E8367000A2F32 /* ucal.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ucal.cpp; sourceTree = ""; }; - FCCB1BF4248E8367000A2F32 /* regextxt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = regextxt.h; sourceTree = ""; }; - FCCB1BF5248E8367000A2F32 /* rematch.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = rematch.cpp; sourceTree = ""; }; - FCCB1BF6248E8368000A2F32 /* strrepl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = strrepl.cpp; sourceTree = ""; }; - FCCB1BF7248E8368000A2F32 /* fphdlimp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fphdlimp.h; sourceTree = ""; }; - FCCB1BF8248E8368000A2F32 /* csrutf8.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = csrutf8.cpp; sourceTree = ""; }; - FCCB1BF9248E8368000A2F32 /* collationiterator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = collationiterator.h; sourceTree = ""; }; - FCCB1BFA248E8368000A2F32 /* zonemeta.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = zonemeta.cpp; sourceTree = ""; }; - FCCB1BFB248E8368000A2F32 /* decimalformatpatternimpl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = decimalformatpatternimpl.h; sourceTree = ""; }; - FCCB1BFC248E8368000A2F32 /* unum.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = unum.cpp; sourceTree = ""; }; - FCCB1BFD248E8368000A2F32 /* ztrans.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ztrans.cpp; sourceTree = ""; }; - FCCB1BFE248E8368000A2F32 /* zonemeta.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = zonemeta.h; sourceTree = ""; }; - FCCB1BFF248E8368000A2F32 /* zrule.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = zrule.cpp; sourceTree = ""; }; - FCCB1C00248E8368000A2F32 /* digitaffixesandpadding.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = digitaffixesandpadding.cpp; sourceTree = ""; }; - FCCB1C01248E8369000A2F32 /* csrsbcs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = csrsbcs.h; sourceTree = ""; }; - FCCB1C02248E8369000A2F32 /* nfrule.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = nfrule.cpp; sourceTree = ""; }; - FCCB1C03248E8369000A2F32 /* regexcmp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = regexcmp.h; sourceTree = ""; }; - FCCB1C04248E8369000A2F32 /* cecal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cecal.h; sourceTree = ""; }; - FCCB1C05248E8369000A2F32 /* remtrans.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = remtrans.h; sourceTree = ""; }; - FCCB1C06248E8369000A2F32 /* numsys.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = numsys.cpp; sourceTree = ""; }; - FCCB1C07248E8369000A2F32 /* regexcst.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = regexcst.h; sourceTree = ""; }; - FCCB1C08248E8369000A2F32 /* quant.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = quant.cpp; sourceTree = ""; }; - FCCB1C09248E8369000A2F32 /* sharedpluralrules.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sharedpluralrules.h; sourceTree = ""; }; - FCCB1C0A248E8369000A2F32 /* pluralaffix.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pluralaffix.h; sourceTree = ""; }; - FCCB1C0B248E8369000A2F32 /* calendar.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = calendar.cpp; sourceTree = ""; }; - FCCB1C0C248E8369000A2F32 /* numfmt.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = numfmt.cpp; sourceTree = ""; }; - FCCB1C0D248E836A000A2F32 /* collation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = collation.h; sourceTree = ""; }; - FCCB1C0E248E836A000A2F32 /* decimalformatpattern.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = decimalformatpattern.h; sourceTree = ""; }; - FCCB1C0F248E836A000A2F32 /* csdetect.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = csdetect.h; sourceTree = ""; }; - FCCB1C10248E836A000A2F32 /* collationfcd.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = collationfcd.h; sourceTree = ""; }; - FCCB1C11248E836A000A2F32 /* dayperiodrules.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = dayperiodrules.cpp; sourceTree = ""; }; - FCCB1C12248E836A000A2F32 /* coptccal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = coptccal.h; sourceTree = ""; }; - FCCB1C13248E836A000A2F32 /* regextxt.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = regextxt.cpp; sourceTree = ""; }; - FCCB1C14248E836A000A2F32 /* pluralaffix.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = pluralaffix.cpp; sourceTree = ""; }; - FCCB1C15248E836A000A2F32 /* collationtailoring.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = collationtailoring.cpp; sourceTree = ""; }; - FCCB1C16248E836A000A2F32 /* selfmtimpl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = selfmtimpl.h; sourceTree = ""; }; - FCCB1C17248E836A000A2F32 /* csrucode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = csrucode.h; sourceTree = ""; }; - FCCB1C18248E836B000A2F32 /* collationtailoring.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = collationtailoring.h; sourceTree = ""; }; - FCCB1C19248E836B000A2F32 /* tolowtrn.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tolowtrn.h; sourceTree = ""; }; - FCCB1C1A248E836B000A2F32 /* rulebasedcollator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = rulebasedcollator.cpp; sourceTree = ""; }; - FCCB1C1B248E836B000A2F32 /* stsearch.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = stsearch.cpp; sourceTree = ""; }; - FCCB1C1C248E836B000A2F32 /* taiwncal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = taiwncal.h; sourceTree = ""; }; - FCCB1C1D248E836B000A2F32 /* windtfmt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = windtfmt.h; sourceTree = ""; }; - FCCB1C1E248E836B000A2F32 /* fmtable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = fmtable.cpp; sourceTree = ""; }; - FCCB1C1F248E836B000A2F32 /* currpinf.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = currpinf.cpp; sourceTree = ""; }; - FCCB1C20248E836B000A2F32 /* nfrs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = nfrs.h; sourceTree = ""; }; - FCCB1C21248E836B000A2F32 /* inputext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = inputext.h; sourceTree = ""; }; - FCCB1C22248E836B000A2F32 /* selfmt.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = selfmt.cpp; sourceTree = ""; }; - FCCB1C23248E836C000A2F32 /* nortrans.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = nortrans.h; sourceTree = ""; }; - FCCB1C24248E836C000A2F32 /* collationroot.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = collationroot.h; sourceTree = ""; }; - FCCB1C25248E836C000A2F32 /* persncal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = persncal.h; sourceTree = ""; }; - FCCB1C26248E836C000A2F32 /* remtrans.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = remtrans.cpp; sourceTree = ""; }; - FCCB1C27248E836C000A2F32 /* toupptrn.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = toupptrn.cpp; sourceTree = ""; }; - FCCB1C28248E836C000A2F32 /* tznames.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = tznames.cpp; sourceTree = ""; }; - FCCB1C29248E836C000A2F32 /* currfmt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = currfmt.h; sourceTree = ""; }; - FCCB1C2A248E836C000A2F32 /* tzrule.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = tzrule.cpp; sourceTree = ""; }; - FCCB1C2B248E836C000A2F32 /* decContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = decContext.h; sourceTree = ""; }; - FCCB1C2C248E836C000A2F32 /* ucol_sit.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ucol_sit.cpp; sourceTree = ""; }; - FCCB1C2D248E836C000A2F32 /* collunsafe.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = collunsafe.h; sourceTree = ""; }; - FCCB1C2E248E836C000A2F32 /* collationdatabuilder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = collationdatabuilder.cpp; sourceTree = ""; }; - FCCB1C2F248E836D000A2F32 /* upluralrules.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = upluralrules.cpp; sourceTree = ""; }; - FCCB1C30248E836D000A2F32 /* brktrans.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = brktrans.h; sourceTree = ""; }; - FCCB1C31248E836D000A2F32 /* utrans.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = utrans.cpp; sourceTree = ""; }; - FCCB1C32248E836D000A2F32 /* udat.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = udat.cpp; sourceTree = ""; }; - FCCB1C33248E836D000A2F32 /* umsg_imp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = umsg_imp.h; sourceTree = ""; }; - FCCB1C34248E836D000A2F32 /* rbt_set.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = rbt_set.cpp; sourceTree = ""; }; - FCCB1C35248E836D000A2F32 /* uregex.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = uregex.cpp; sourceTree = ""; }; - FCCB1C36248E836D000A2F32 /* ucoleitr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ucoleitr.cpp; sourceTree = ""; }; - FCCB1C37248E836D000A2F32 /* decimfmtimpl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = decimfmtimpl.cpp; sourceTree = ""; }; - FCCB1C38248E836D000A2F32 /* csr2022.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = csr2022.cpp; sourceTree = ""; }; - FCCB1C39248E836D000A2F32 /* islamcal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = islamcal.h; sourceTree = ""; }; - FCCB1C3A248E836E000A2F32 /* rbtz.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = rbtz.cpp; sourceTree = ""; }; - FCCB1C3B248E836E000A2F32 /* nultrans.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = nultrans.cpp; sourceTree = ""; }; - FCCB1C3C248E836E000A2F32 /* collationrootelements.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = collationrootelements.cpp; sourceTree = ""; }; - FCCB1C3D248E836E000A2F32 /* olsontz.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = olsontz.h; sourceTree = ""; }; - FCCB1C3E248E836E000A2F32 /* titletrn.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = titletrn.cpp; sourceTree = ""; }; - FCCB1C3F248E836E000A2F32 /* gender.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gender.cpp; sourceTree = ""; }; - FCCB1C40248E836E000A2F32 /* usearch.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = usearch.cpp; sourceTree = ""; }; - FCCB1C41248E836E000A2F32 /* csmatch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = csmatch.h; sourceTree = ""; }; - FCCB1C42248E836E000A2F32 /* udateintervalformat.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = udateintervalformat.cpp; sourceTree = ""; }; - FCCB1C43248E836E000A2F32 /* tzgnames.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = tzgnames.cpp; sourceTree = ""; }; - FCCB1C44248E836E000A2F32 /* uni2name.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uni2name.h; sourceTree = ""; }; - FCCB1C45248E836F000A2F32 /* anytrans.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = anytrans.cpp; sourceTree = ""; }; - FCCB1C46248E836F000A2F32 /* decimalformatpattern.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = decimalformatpattern.cpp; sourceTree = ""; }; - FCCB1C47248E836F000A2F32 /* titletrn.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = titletrn.h; sourceTree = ""; }; - FCCB1C48248E836F000A2F32 /* collationcompare.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = collationcompare.h; sourceTree = ""; }; - FCCB1C49248E836F000A2F32 /* nfrs.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = nfrs.cpp; sourceTree = ""; }; - FCCB1C4A248E836F000A2F32 /* hebrwcal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = hebrwcal.h; sourceTree = ""; }; - FCCB1C4B248E836F000A2F32 /* csmatch.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = csmatch.cpp; sourceTree = ""; }; - FCCB1C4C248E836F000A2F32 /* utf16collationiterator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = utf16collationiterator.h; sourceTree = ""; }; - FCCB1C4D248E836F000A2F32 /* tzfmt.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = tzfmt.cpp; sourceTree = ""; }; - FCCB1C4E248E836F000A2F32 /* valueformatter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = valueformatter.cpp; sourceTree = ""; }; - FCCB1C4F248E836F000A2F32 /* collationfcd.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = collationfcd.cpp; sourceTree = ""; }; - FCCB1C50248E8370000A2F32 /* decfmtst.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = decfmtst.cpp; sourceTree = ""; }; - FCCB1C51248E8370000A2F32 /* rbt_set.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = rbt_set.h; sourceTree = ""; }; - FCCB1C52248E8370000A2F32 /* sortkey.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sortkey.cpp; sourceTree = ""; }; - FCCB1C53248E8370000A2F32 /* dtptngen_impl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dtptngen_impl.h; sourceTree = ""; }; - FCCB1C54248E8370000A2F32 /* nfrule.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = nfrule.h; sourceTree = ""; }; - FCCB1C55248E8370000A2F32 /* esctrn.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = esctrn.cpp; sourceTree = ""; }; - FCCB1C56248E8370000A2F32 /* fphdlimp.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = fphdlimp.cpp; sourceTree = ""; }; - FCCB1C57248E8370000A2F32 /* dt_impl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dt_impl.h; sourceTree = ""; }; - FCCB1C58248E8370000A2F32 /* bocsu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = bocsu.cpp; sourceTree = ""; }; - FCCB1C59248E8370000A2F32 /* rbt_data.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = rbt_data.h; sourceTree = ""; }; - FCCB1C5A248E8370000A2F32 /* regexcmp.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = regexcmp.cpp; sourceTree = ""; }; - FCCB1C5B248E8371000A2F32 /* dcfmtsym.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = dcfmtsym.cpp; sourceTree = ""; }; - FCCB1C5C248E8371000A2F32 /* tmunit.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = tmunit.cpp; sourceTree = ""; }; - FCCB1C5D248E8371000A2F32 /* japancal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = japancal.h; sourceTree = ""; }; - FCCB1C5E248E8371000A2F32 /* ucln_in.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ucln_in.cpp; sourceTree = ""; }; - FCCB1C5F248E8371000A2F32 /* udatpg.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = udatpg.cpp; sourceTree = ""; }; - FCCB1C60248E8371000A2F32 /* ethpccal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ethpccal.h; sourceTree = ""; }; - FCCB1C61248E8371000A2F32 /* uspoof_build.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = uspoof_build.cpp; sourceTree = ""; }; - FCCB1C62248E8371000A2F32 /* shareddateformatsymbols.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = shareddateformatsymbols.h; sourceTree = ""; }; - FCCB1C63248E8371000A2F32 /* collationroot.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = collationroot.cpp; sourceTree = ""; }; - FCCB1C64248E8371000A2F32 /* esctrn.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = esctrn.h; sourceTree = ""; }; - FCCB1C65248E8371000A2F32 /* astro.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = astro.cpp; sourceTree = ""; }; - FCCB1C66248E8372000A2F32 /* plurfmt.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = plurfmt.cpp; sourceTree = ""; }; - FCCB1C67248E8372000A2F32 /* dtitvinf.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = dtitvinf.cpp; sourceTree = ""; }; - FCCB1C68248E8372000A2F32 /* windtfmt.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = windtfmt.cpp; sourceTree = ""; }; - FCCB1C69248E8372000A2F32 /* csdetect.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = csdetect.cpp; sourceTree = ""; }; - FCCB1C6A248E8372000A2F32 /* smallintformatter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = smallintformatter.h; sourceTree = ""; }; - FCCB1C6B248E8372000A2F32 /* unumsys.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = unumsys.cpp; sourceTree = ""; }; - FCCB1C6C248E8372000A2F32 /* ufieldpositer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ufieldpositer.cpp; sourceTree = ""; }; - FCCB1C6D248E8372000A2F32 /* strmatch.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = strmatch.cpp; sourceTree = ""; }; - FCCB1C6E248E8372000A2F32 /* tridpars.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = tridpars.cpp; sourceTree = ""; }; - FCCB1C6F248E8372000A2F32 /* uregexc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = uregexc.cpp; sourceTree = ""; }; - FCCB1C70248E8372000A2F32 /* datefmt.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = datefmt.cpp; sourceTree = ""; }; - FCCB1C71248E8373000A2F32 /* simpletz.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = simpletz.cpp; sourceTree = ""; }; - FCCB1C72248E8373000A2F32 /* uregion.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = uregion.cpp; sourceTree = ""; }; - FCCB1C73248E8373000A2F32 /* choicfmt.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = choicfmt.cpp; sourceTree = ""; }; - FCCB1C74248E8373000A2F32 /* dtrule.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = dtrule.cpp; sourceTree = ""; }; - FCCB1C75248E8373000A2F32 /* coll.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = coll.cpp; sourceTree = ""; }; - FCCB1C76248E8373000A2F32 /* inputext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = inputext.cpp; sourceTree = ""; }; - FCCB1C77248E8373000A2F32 /* precision.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = precision.cpp; sourceTree = ""; }; - FCCB1C78248E8373000A2F32 /* collationdata.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = collationdata.h; sourceTree = ""; }; - FCCB1C79248E8373000A2F32 /* csrsbcs.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = csrsbcs.cpp; sourceTree = ""; }; - FCCB1C7A248E8373000A2F32 /* smpdtfmt.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = smpdtfmt.cpp; sourceTree = ""; }; - FCCB1C7B248E8373000A2F32 /* usrchimp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = usrchimp.h; sourceTree = ""; }; - FCCB1C7C248E8374000A2F32 /* fmtable_cnv.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = fmtable_cnv.cpp; sourceTree = ""; }; - FCCB1C7D248E8374000A2F32 /* collationruleparser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = collationruleparser.cpp; sourceTree = ""; }; - FCCB1C7E248E8374000A2F32 /* buddhcal.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = buddhcal.cpp; sourceTree = ""; }; - FCCB1C7F248E8374000A2F32 /* collationfastlatinbuilder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = collationfastlatinbuilder.cpp; sourceTree = ""; }; - FCCB1C80248E8374000A2F32 /* nultrans.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = nultrans.h; sourceTree = ""; }; - FCCB1C81248E8374000A2F32 /* uspoof_conf.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = uspoof_conf.cpp; sourceTree = ""; }; - FCCB1C82248E8374000A2F32 /* bocsu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = bocsu.h; sourceTree = ""; }; - FCCB1C83248E8374000A2F32 /* collationsettings.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = collationsettings.cpp; sourceTree = ""; }; - FCCB1C84248E8374000A2F32 /* collation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = collation.cpp; sourceTree = ""; }; - FCCB1C85248E8374000A2F32 /* basictz.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = basictz.cpp; sourceTree = ""; }; - FCCB1C86248E8375000A2F32 /* collationdatawriter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = collationdatawriter.cpp; sourceTree = ""; }; - FCCB1C87248E8375000A2F32 /* chnsecal.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = chnsecal.cpp; sourceTree = ""; }; - FCCB1C88248E8375000A2F32 /* winnmfmt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = winnmfmt.h; sourceTree = ""; }; - FCCB1C89248E8375000A2F32 /* collationsets.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = collationsets.cpp; sourceTree = ""; }; - FCCB1C8A248E8375000A2F32 /* uspoof_impl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uspoof_impl.h; sourceTree = ""; }; - FCCB1C8B248E8375000A2F32 /* plurrule_impl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = plurrule_impl.h; sourceTree = ""; }; - FCCB1C8C248E8375000A2F32 /* regexst.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = regexst.h; sourceTree = ""; }; - FCCB1C8D248E8375000A2F32 /* name2uni.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = name2uni.cpp; sourceTree = ""; }; - FCCB1C8E248E8375000A2F32 /* chnsecal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = chnsecal.h; sourceTree = ""; }; - FCCB1C8F248E8375000A2F32 /* ucsdet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ucsdet.cpp; sourceTree = ""; }; - FCCB1C90248E8375000A2F32 /* transreg.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = transreg.cpp; sourceTree = ""; }; - FCCB1C91248E8376000A2F32 /* collationsets.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = collationsets.h; sourceTree = ""; }; - FCCB1C92248E8376000A2F32 /* digitformatter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = digitformatter.h; sourceTree = ""; }; - FCCB1C93248E8376000A2F32 /* casetrn.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = casetrn.cpp; sourceTree = ""; }; - FCCB1C94248E8376000A2F32 /* regeximp.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = regeximp.cpp; sourceTree = ""; }; - FCCB1C95248E8376000A2F32 /* sharedcalendar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sharedcalendar.h; sourceTree = ""; }; - FCCB1C96248E8376000A2F32 /* csrutf8.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = csrutf8.h; sourceTree = ""; }; - FCCB1C97248E8376000A2F32 /* collationweights.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = collationweights.h; sourceTree = ""; }; - FCCB1C98248E8376000A2F32 /* csrucode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = csrucode.cpp; sourceTree = ""; }; - FCCB1C99248E8376000A2F32 /* collationkeys.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = collationkeys.cpp; sourceTree = ""; }; - FCCB1C9A248E8376000A2F32 /* vzone.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vzone.h; sourceTree = ""; }; - FCCB1C9B248E8377000A2F32 /* quantityformatter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = quantityformatter.cpp; sourceTree = ""; }; - FCCB1C9C248E8377000A2F32 /* taiwncal.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = taiwncal.cpp; sourceTree = ""; }; - FCCB1C9D248E8377000A2F32 /* quantityformatter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = quantityformatter.h; sourceTree = ""; }; - FCCB1C9E248E8377000A2F32 /* digitlst.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = digitlst.cpp; sourceTree = ""; }; - FCCB1C9F248E8377000A2F32 /* region_impl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = region_impl.h; sourceTree = ""; }; - FCCB1CA0248E8377000A2F32 /* dtptngen.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = dtptngen.cpp; sourceTree = ""; }; - FCCB1CA1248E8377000A2F32 /* reldtfmt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = reldtfmt.h; sourceTree = ""; }; - FCCB1CA2248E8377000A2F32 /* alphaindex.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = alphaindex.cpp; sourceTree = ""; }; - FCCB1CA3248E8377000A2F32 /* gregoimp.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gregoimp.cpp; sourceTree = ""; }; - FCCB1CA4248E8377000A2F32 /* currunit.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = currunit.cpp; sourceTree = ""; }; - FCCB1CA5248E8377000A2F32 /* translit.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = translit.cpp; sourceTree = ""; }; - FCCB1CA6248E8378000A2F32 /* rbt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = rbt.h; sourceTree = ""; }; - FCCB1CA7248E8378000A2F32 /* persncal.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = persncal.cpp; sourceTree = ""; }; - FCCB1CA8248E8378000A2F32 /* decContext.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = decContext.c; sourceTree = ""; }; - FCCB1CA9248E8378000A2F32 /* transreg.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = transreg.h; sourceTree = ""; }; - FCCB1CAA248E8378000A2F32 /* numsys_impl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = numsys_impl.h; sourceTree = ""; }; - FCCB1CAB248E8378000A2F32 /* buddhcal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = buddhcal.h; sourceTree = ""; }; - FCCB1CAC248E8378000A2F32 /* ucol.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ucol.cpp; sourceTree = ""; }; - FCCB1CAD248E8378000A2F32 /* msgfmt.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = msgfmt.cpp; sourceTree = ""; }; - FCCB1CAE248E8378000A2F32 /* rbt_data.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = rbt_data.cpp; sourceTree = ""; }; - FCCB1CAF248E8378000A2F32 /* collationbuilder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = collationbuilder.cpp; sourceTree = ""; }; - FCCB1CB0248E8379000A2F32 /* scientificnumberformatter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = scientificnumberformatter.cpp; sourceTree = ""; }; - FCCB1CB1248E8379000A2F32 /* scriptset.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = scriptset.h; sourceTree = ""; }; - FCCB1CB2248E8379000A2F32 /* ucol_res.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ucol_res.cpp; sourceTree = ""; }; - FCCB1CB3248E8379000A2F32 /* digitlst.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = digitlst.h; sourceTree = ""; }; - FCCB1CB4248E8379000A2F32 /* uspoof.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = uspoof.cpp; sourceTree = ""; }; - FCCB1CB5248E8379000A2F32 /* rbt_pars.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = rbt_pars.h; sourceTree = ""; }; - FCCB1CB6248E8379000A2F32 /* curramt.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = curramt.cpp; sourceTree = ""; }; - FCCB1CB7248E8379000A2F32 /* japancal.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = japancal.cpp; sourceTree = ""; }; - FCCB1CB8248E8379000A2F32 /* unesctrn.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = unesctrn.cpp; sourceTree = ""; }; - FCCB1CB9248E8379000A2F32 /* collationiterator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = collationiterator.cpp; sourceTree = ""; }; - FCCB1CBA248E8379000A2F32 /* wintzimpl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wintzimpl.cpp; sourceTree = ""; }; - FCCB1CBB248E837A000A2F32 /* collationcompare.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = collationcompare.cpp; sourceTree = ""; }; - FCCB1CBC248E837A000A2F32 /* uitercollationiterator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = uitercollationiterator.cpp; sourceTree = ""; }; - FCCB1CBD248E837A000A2F32 /* region.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = region.cpp; sourceTree = ""; }; - FCCB1CBE248E837A000A2F32 /* ucol_imp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ucol_imp.h; sourceTree = ""; }; - FCCB1CBF248E837A000A2F32 /* tznames_impl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tznames_impl.h; sourceTree = ""; }; - FCCB1CC0248E837A000A2F32 /* measunit.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = measunit.cpp; sourceTree = ""; }; - FCCB1CC1248E837A000A2F32 /* umsg.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = umsg.cpp; sourceTree = ""; }; - FCCB1CC2248E837A000A2F32 /* collationfastlatin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = collationfastlatin.h; sourceTree = ""; }; - FCCB1CC3248E837A000A2F32 /* affixpatternparser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = affixpatternparser.cpp; sourceTree = ""; }; - FCCB1CC4248E837A000A2F32 /* indiancal.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = indiancal.cpp; sourceTree = ""; }; - FCCB1CC5248E837B000A2F32 /* csr2022.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = csr2022.h; sourceTree = ""; }; - FCCB1CC6248E837B000A2F32 /* decNumberLocal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = decNumberLocal.h; sourceTree = ""; }; - FCCB1CC7248E837B000A2F32 /* collationdatareader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = collationdatareader.h; sourceTree = ""; }; - FCCB1CC8248E837B000A2F32 /* collationdatawriter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = collationdatawriter.h; sourceTree = ""; }; - FCCB1CC9248E837B000A2F32 /* scriptset.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = scriptset.cpp; sourceTree = ""; }; - FCCB1CCA248E837B000A2F32 /* smpdtfst.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = smpdtfst.cpp; sourceTree = ""; }; - FCCB1CCB248E837B000A2F32 /* decimfmt.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = decimfmt.cpp; sourceTree = ""; }; - FCCB1CCC248E837B000A2F32 /* timezone.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = timezone.cpp; sourceTree = ""; }; - FCCB1CCD248E837B000A2F32 /* csrecog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = csrecog.h; sourceTree = ""; }; - FCCB1CCE248E837B000A2F32 /* casetrn.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = casetrn.h; sourceTree = ""; }; - FCCB1CCF248E837C000A2F32 /* strmatch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = strmatch.h; sourceTree = ""; }; - FCCB1CD0248E837C000A2F32 /* tznames_impl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = tznames_impl.cpp; sourceTree = ""; }; - FCCB1CD1248E837C000A2F32 /* collationdata.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = collationdata.cpp; sourceTree = ""; }; - FCCB1CD2248E837C000A2F32 /* collationdatabuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = collationdatabuilder.h; sourceTree = ""; }; - FCCB1CD3248E837C000A2F32 /* gregoimp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gregoimp.h; sourceTree = ""; }; - FCCB1CD4248E837C000A2F32 /* name2uni.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = name2uni.h; sourceTree = ""; }; - FCCB1CD5248E837C000A2F32 /* vtzone.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = vtzone.cpp; sourceTree = ""; }; - FCCB1CD6248E837C000A2F32 /* indiancal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = indiancal.h; sourceTree = ""; }; - FCCB1CD7248E837C000A2F32 /* digitinterval.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = digitinterval.h; sourceTree = ""; }; - FCCB1CD8248E837C000A2F32 /* tmutfmt.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = tmutfmt.cpp; sourceTree = ""; }; - FCCB1CD9248E837C000A2F32 /* tzgnames.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tzgnames.h; sourceTree = ""; }; - FCCB1CDA248E837D000A2F32 /* plurrule.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = plurrule.cpp; sourceTree = ""; }; - FCCB1CDB248E837D000A2F32 /* measure.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = measure.cpp; sourceTree = ""; }; - FCCB1CDC248E837D000A2F32 /* digitinterval.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = digitinterval.cpp; sourceTree = ""; }; - FCCB1CDD248E837D000A2F32 /* rbt_rule.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = rbt_rule.cpp; sourceTree = ""; }; - FCCB1CDE248E837D000A2F32 /* dayperiodrules.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dayperiodrules.h; sourceTree = ""; }; - FCCB1CDF248E837D000A2F32 /* regexst.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = regexst.cpp; sourceTree = ""; }; - FCCB1CE0248E837D000A2F32 /* winnmfmt.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = winnmfmt.cpp; sourceTree = ""; }; - FCCB1CE1248E837D000A2F32 /* smpdtfst.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = smpdtfst.h; sourceTree = ""; }; - FCCB1CE2248E837D000A2F32 /* reldatefmt.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = reldatefmt.cpp; sourceTree = ""; }; - FCCB1CE3248E837D000A2F32 /* collationsettings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = collationsettings.h; sourceTree = ""; }; - FCCB1CE4248E837E000A2F32 /* decNumber.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = decNumber.c; sourceTree = ""; }; - FCCB1CE5248E837E000A2F32 /* wintzimpl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wintzimpl.h; sourceTree = ""; }; - FCCB1CE6248E837E000A2F32 /* significantdigitinterval.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = significantdigitinterval.h; sourceTree = ""; }; - FCCB1CE7248E837E000A2F32 /* search.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = search.cpp; sourceTree = ""; }; - FCCB1CE8248E837E000A2F32 /* csrmbcs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = csrmbcs.h; sourceTree = ""; }; - FCCB1CE9248E837E000A2F32 /* digitgrouping.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = digitgrouping.cpp; sourceTree = ""; }; - FCCB1CEA248E837E000A2F32 /* cecal.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = cecal.cpp; sourceTree = ""; }; - FCCB1CEB248E837E000A2F32 /* csrmbcs.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = csrmbcs.cpp; sourceTree = ""; }; - FCCB1CEC248E837E000A2F32 /* regeximp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = regeximp.h; sourceTree = ""; }; - FCCB1CED248E837F000A2F32 /* visibledigits.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = visibledigits.h; sourceTree = ""; }; - FCCB1CEE248E837F000A2F32 /* collationweights.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = collationweights.cpp; sourceTree = ""; }; - FCCB1CEF248E837F000A2F32 /* quant.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = quant.h; sourceTree = ""; }; - FCCB1CF0248E837F000A2F32 /* tolowtrn.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = tolowtrn.cpp; sourceTree = ""; }; - FCCB1CF1248E8380000A2F32 /* ztrans.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ztrans.h; sourceTree = ""; }; - FCCB1CF2248E8380000A2F32 /* decNumber.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = decNumber.h; sourceTree = ""; }; - FCCB1CF3248E8380000A2F32 /* utmscale.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = utmscale.c; sourceTree = ""; }; - FCCB1CF4248E8380000A2F32 /* olsontz.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = olsontz.cpp; sourceTree = ""; }; - FCCB1CF5248E8381000A2F32 /* coleitr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = coleitr.cpp; sourceTree = ""; }; - FCCB1CF6248E8381000A2F32 /* astro.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = astro.h; sourceTree = ""; }; - FCCB1CF7248E8381000A2F32 /* cpdtrans.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cpdtrans.h; sourceTree = ""; }; - FCCB1CF8248E8382000A2F32 /* anytrans.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = anytrans.h; sourceTree = ""; }; - FCCB1CF9248E8382000A2F32 /* strrepl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = strrepl.h; sourceTree = ""; }; - FCCB1CFA248E8382000A2F32 /* uni2name.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = uni2name.cpp; sourceTree = ""; }; - FCCB1CFB248E8383000A2F32 /* uspoof_conf.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uspoof_conf.h; sourceTree = ""; }; - FCCB1CFC248E8383000A2F32 /* sharedbreakiterator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sharedbreakiterator.cpp; sourceTree = ""; }; - FCCB1CFD248E8383000A2F32 /* brktrans.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = brktrans.cpp; sourceTree = ""; }; - FCCB1CFE248E8384000A2F32 /* collationruleparser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = collationruleparser.h; sourceTree = ""; }; - FCCB1CFF248E8384000A2F32 /* digitformatter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = digitformatter.cpp; sourceTree = ""; }; - FCCB1D00248E8384000A2F32 /* cpdtrans.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = cpdtrans.cpp; sourceTree = ""; }; - FCCB1D01248E8384000A2F32 /* format.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = format.cpp; sourceTree = ""; }; - FCCB1D02248E8385000A2F32 /* collationfastlatin.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = collationfastlatin.cpp; sourceTree = ""; }; - FCCB1D03248E8385000A2F32 /* collationrootelements.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = collationrootelements.h; sourceTree = ""; }; - FCCB1D04248E8385000A2F32 /* utf8collationiterator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = utf8collationiterator.cpp; sourceTree = ""; }; - FCCB1D05248E8385000A2F32 /* tmutamt.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = tmutamt.cpp; sourceTree = ""; }; - FCCB1D06248E8385000A2F32 /* funcrepl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = funcrepl.h; sourceTree = ""; }; - FCCB1D07248E8385000A2F32 /* dtfmtsym.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = dtfmtsym.cpp; sourceTree = ""; }; - FCCB1D08248E8386000A2F32 /* nfsubs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = nfsubs.h; sourceTree = ""; }; - FCCB1D09248E8386000A2F32 /* digitaffix.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = digitaffix.h; sourceTree = ""; }; - FCCB1D0A248E8386000A2F32 /* ulocdata.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ulocdata.c; sourceTree = ""; }; - FCCB1D0B248E8386000A2F32 /* msgfmt_impl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = msgfmt_impl.h; sourceTree = ""; }; - FCCB1D0C248E8386000A2F32 /* fpositer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = fpositer.cpp; sourceTree = ""; }; - FCCB1D0D248E8386000A2F32 /* collationkeys.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = collationkeys.h; sourceTree = ""; }; - FCCB1D0E248E8387000A2F32 /* utf8collationiterator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = utf8collationiterator.h; sourceTree = ""; }; - FCCB1D0F248E8387000A2F32 /* digitaffixesandpadding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = digitaffixesandpadding.h; sourceTree = ""; }; - FCCB1D10248E8387000A2F32 /* vzone.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = vzone.cpp; sourceTree = ""; }; - FCCB1D11248E8387000A2F32 /* rbt_pars.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = rbt_pars.cpp; sourceTree = ""; }; - FCCB1D12248E8387000A2F32 /* uitercollationiterator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uitercollationiterator.h; sourceTree = ""; }; - FCCB1D13248E8387000A2F32 /* csrecog.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = csrecog.cpp; sourceTree = ""; }; - FCCB1D14248E8387000A2F32 /* affixpatternparser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = affixpatternparser.h; sourceTree = ""; }; - FCCB1D15248E8387000A2F32 /* rbnf.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = rbnf.cpp; sourceTree = ""; }; - FCCB1D16248E8388000A2F32 /* currfmt.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = currfmt.cpp; sourceTree = ""; }; - FCCB1D17248E8388000A2F32 /* precision.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = precision.h; sourceTree = ""; }; - FCCB1D18248E8388000A2F32 /* rbt.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = rbt.cpp; sourceTree = ""; }; - FCCB1D19248E8388000A2F32 /* unesctrn.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = unesctrn.h; sourceTree = ""; }; - FCCB1D1A248E8388000A2F32 /* gregocal.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gregocal.cpp; sourceTree = ""; }; - FCCB1D1B248E8388000A2F32 /* nfrlist.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = nfrlist.h; sourceTree = ""; }; - FCCB1D1C248E8388000A2F32 /* reldtfmt.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = reldtfmt.cpp; sourceTree = ""; }; - FCCB1D1D248E8388000A2F32 /* collationdatareader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = collationdatareader.cpp; sourceTree = ""; }; - FCCB1D1E248E8388000A2F32 /* funcrepl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = funcrepl.cpp; sourceTree = ""; }; - FCCB1D1F248E8389000A2F32 /* digitgrouping.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = digitgrouping.h; sourceTree = ""; }; - FCCB1D20248E8389000A2F32 /* dangical.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = dangical.cpp; sourceTree = ""; }; - FCCB1E35248E8419000A2F32 /* udatpg.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = udatpg.h; sourceTree = ""; }; - FCCB1E36248E841A000A2F32 /* uregion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uregion.h; sourceTree = ""; }; - FCCB1E37248E841A000A2F32 /* ulocdata.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ulocdata.h; sourceTree = ""; }; - FCCB1E38248E841A000A2F32 /* dtitvinf.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dtitvinf.h; sourceTree = ""; }; - FCCB1E39248E841A000A2F32 /* utmscale.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = utmscale.h; sourceTree = ""; }; - FCCB1E3A248E841A000A2F32 /* vtzone.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vtzone.h; sourceTree = ""; }; - FCCB1E3B248E841A000A2F32 /* coleitr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = coleitr.h; sourceTree = ""; }; - FCCB1E3C248E841A000A2F32 /* measunit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = measunit.h; sourceTree = ""; }; - FCCB1E3D248E841A000A2F32 /* uregex.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uregex.h; sourceTree = ""; }; - FCCB1E3E248E841A000A2F32 /* alphaindex.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = alphaindex.h; sourceTree = ""; }; - FCCB1E3F248E841A000A2F32 /* gregocal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gregocal.h; sourceTree = ""; }; - FCCB1E40248E841B000A2F32 /* measure.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = measure.h; sourceTree = ""; }; - FCCB1E41248E841B000A2F32 /* tzrule.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tzrule.h; sourceTree = ""; }; - FCCB1E42248E841B000A2F32 /* scientificnumberformatter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = scientificnumberformatter.h; sourceTree = ""; }; - FCCB1E43248E841B000A2F32 /* datefmt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = datefmt.h; sourceTree = ""; }; - FCCB1E44248E841B000A2F32 /* fpositer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fpositer.h; sourceTree = ""; }; - FCCB1E45248E841B000A2F32 /* usearch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = usearch.h; sourceTree = ""; }; - FCCB1E46248E841B000A2F32 /* translit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = translit.h; sourceTree = ""; }; - FCCB1E47248E841B000A2F32 /* ufieldpositer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ufieldpositer.h; sourceTree = ""; }; - FCCB1E48248E841B000A2F32 /* regex.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = regex.h; sourceTree = ""; }; - FCCB1E49248E841B000A2F32 /* utrans.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = utrans.h; sourceTree = ""; }; - FCCB1E4A248E841C000A2F32 /* umsg.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = umsg.h; sourceTree = ""; }; - FCCB1E4B248E841C000A2F32 /* plurrule.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = plurrule.h; sourceTree = ""; }; - FCCB1E4C248E841C000A2F32 /* dtptngen.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dtptngen.h; sourceTree = ""; }; - FCCB1E4D248E841C000A2F32 /* curramt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = curramt.h; sourceTree = ""; }; - FCCB1E4E248E841C000A2F32 /* compactdecimalformat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = compactdecimalformat.h; sourceTree = ""; }; - FCCB1E4F248E841C000A2F32 /* tblcoll.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tblcoll.h; sourceTree = ""; }; - FCCB1E50248E841C000A2F32 /* tznames.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tznames.h; sourceTree = ""; }; - FCCB1E51248E841C000A2F32 /* unumsys.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = unumsys.h; sourceTree = ""; }; - FCCB1E52248E841D000A2F32 /* currunit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = currunit.h; sourceTree = ""; }; - FCCB1E53248E841D000A2F32 /* decimfmt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = decimfmt.h; sourceTree = ""; }; - FCCB1E54248E841D000A2F32 /* uspoof.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uspoof.h; sourceTree = ""; }; - FCCB1E55248E841D000A2F32 /* ureldatefmt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ureldatefmt.h; sourceTree = ""; }; - FCCB1E56248E841D000A2F32 /* tmutfmt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tmutfmt.h; sourceTree = ""; }; - FCCB1E57248E841D000A2F32 /* rbnf.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = rbnf.h; sourceTree = ""; }; - FCCB1E58248E841D000A2F32 /* measfmt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = measfmt.h; sourceTree = ""; }; - FCCB1E59248E841D000A2F32 /* coll.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = coll.h; sourceTree = ""; }; - FCCB1E5A248E841E000A2F32 /* sortkey.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sortkey.h; sourceTree = ""; }; - FCCB1E5B248E841E000A2F32 /* msgfmt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = msgfmt.h; sourceTree = ""; }; - FCCB1E5C248E841E000A2F32 /* choicfmt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = choicfmt.h; sourceTree = ""; }; - FCCB1E5D248E841E000A2F32 /* ucsdet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ucsdet.h; sourceTree = ""; }; - FCCB1E5E248E841E000A2F32 /* fieldpos.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fieldpos.h; sourceTree = ""; }; - FCCB1E5F248E841E000A2F32 /* gender.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gender.h; sourceTree = ""; }; - FCCB1E60248E841E000A2F32 /* selfmt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = selfmt.h; sourceTree = ""; }; - FCCB1E61248E841E000A2F32 /* udateintervalformat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = udateintervalformat.h; sourceTree = ""; }; - FCCB1E62248E841F000A2F32 /* unum.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = unum.h; sourceTree = ""; }; - FCCB1E63248E841F000A2F32 /* calendar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = calendar.h; sourceTree = ""; }; - FCCB1E64248E841F000A2F32 /* currpinf.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = currpinf.h; sourceTree = ""; }; - FCCB1E65248E841F000A2F32 /* dcfmtsym.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dcfmtsym.h; sourceTree = ""; }; - FCCB1E66248E841F000A2F32 /* numfmt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = numfmt.h; sourceTree = ""; }; - FCCB1E67248E841F000A2F32 /* unirepl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = unirepl.h; sourceTree = ""; }; - FCCB1E68248E841F000A2F32 /* simpletz.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = simpletz.h; sourceTree = ""; }; - FCCB1E69248E841F000A2F32 /* timezone.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = timezone.h; sourceTree = ""; }; - FCCB1E6A248E841F000A2F32 /* dtrule.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dtrule.h; sourceTree = ""; }; - FCCB1E6B248E8420000A2F32 /* search.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = search.h; sourceTree = ""; }; - FCCB1E6C248E8420000A2F32 /* stsearch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = stsearch.h; sourceTree = ""; }; - FCCB1E6D248E8420000A2F32 /* plurfmt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = plurfmt.h; sourceTree = ""; }; - FCCB1E6E248E8420000A2F32 /* tmunit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tmunit.h; sourceTree = ""; }; - FCCB1E6F248E8420000A2F32 /* region.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = region.h; sourceTree = ""; }; - FCCB1E70248E8420000A2F32 /* tztrans.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tztrans.h; sourceTree = ""; }; - FCCB1E71248E8420000A2F32 /* numsys.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = numsys.h; sourceTree = ""; }; - FCCB1E72248E8420000A2F32 /* upluralrules.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = upluralrules.h; sourceTree = ""; }; - FCCB1E73248E8420000A2F32 /* basictz.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = basictz.h; sourceTree = ""; }; - FCCB1E74248E8421000A2F32 /* format.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = format.h; sourceTree = ""; }; - FCCB1E75248E8421000A2F32 /* reldatefmt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = reldatefmt.h; sourceTree = ""; }; - FCCB1E76248E8421000A2F32 /* ugender.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ugender.h; sourceTree = ""; }; - FCCB1E77248E8421000A2F32 /* ucal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ucal.h; sourceTree = ""; }; - FCCB1E78248E8421000A2F32 /* dtfmtsym.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dtfmtsym.h; sourceTree = ""; }; - FCCB1E79248E8421000A2F32 /* dtitvfmt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dtitvfmt.h; sourceTree = ""; }; - FCCB1E7A248E8421000A2F32 /* udat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = udat.h; sourceTree = ""; }; - FCCB1E7B248E8421000A2F32 /* ucol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ucol.h; sourceTree = ""; }; - FCCB1E7C248E8421000A2F32 /* tmutamt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tmutamt.h; sourceTree = ""; }; - FCCB1E7D248E8421000A2F32 /* smpdtfmt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = smpdtfmt.h; sourceTree = ""; }; - FCCB1E7E248E8422000A2F32 /* fmtable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fmtable.h; sourceTree = ""; }; - FCCB1E7F248E8422000A2F32 /* uformattable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uformattable.h; sourceTree = ""; }; - FCCB1E80248E8422000A2F32 /* rbtz.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = rbtz.h; sourceTree = ""; }; - FCCB1E81248E8422000A2F32 /* tzfmt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tzfmt.h; sourceTree = ""; }; - FCCB1E82248E8422000A2F32 /* ucoleitr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ucoleitr.h; sourceTree = ""; }; - FCCB1E83248E843F000A2F32 /* ustdio.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ustdio.c; sourceTree = ""; }; - FCCB1E84248E843F000A2F32 /* ustream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ustream.cpp; sourceTree = ""; }; - FCCB1E85248E843F000A2F32 /* ufmt_cmn.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ufmt_cmn.c; sourceTree = ""; }; - FCCB1E86248E843F000A2F32 /* uscanf.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uscanf.h; sourceTree = ""; }; - FCCB1E87248E843F000A2F32 /* ucln_io.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ucln_io.h; sourceTree = ""; }; - FCCB1E88248E843F000A2F32 /* ucln_io.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ucln_io.cpp; sourceTree = ""; }; - FCCB1E89248E843F000A2F32 /* ufile.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ufile.c; sourceTree = ""; }; - FCCB1E8A248E843F000A2F32 /* sscanf.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = sscanf.c; sourceTree = ""; }; - FCCB1E8B248E843F000A2F32 /* uprintf.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uprintf.h; sourceTree = ""; }; - FCCB1E8C248E843F000A2F32 /* uprintf.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = uprintf.cpp; sourceTree = ""; }; - FCCB1E8D248E843F000A2F32 /* ufmt_cmn.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ufmt_cmn.h; sourceTree = ""; }; - FCCB1E8E248E843F000A2F32 /* locbund.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = locbund.h; sourceTree = ""; }; - FCCB1E8F248E843F000A2F32 /* uprntf_p.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = uprntf_p.c; sourceTree = ""; }; - FCCB1E90248E8440000A2F32 /* locbund.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = locbund.cpp; sourceTree = ""; }; - FCCB1E91248E8440000A2F32 /* uscanf_p.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = uscanf_p.c; sourceTree = ""; }; - FCCB1E92248E8440000A2F32 /* sprintf.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = sprintf.c; sourceTree = ""; }; - FCCB1E93248E8440000A2F32 /* uscanf.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = uscanf.c; sourceTree = ""; }; - FCCB1E94248E8440000A2F32 /* ufile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ufile.h; sourceTree = ""; }; - FCCB1EA2248E8447000A2F32 /* ustdio.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ustdio.h; sourceTree = ""; }; - FCCB1EA3248E8447000A2F32 /* ustream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ustream.h; sourceTree = ""; }; - FCCB1EA4248E845E000A2F32 /* stubdata.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = stubdata.c; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 1732417D1BBECF8400E67992 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 173241771BBECF8400E67992 = { - isa = PBXGroup; - children = ( - 173241821BBECF8400E67992 /* icu */, - 173241811BBECF8400E67992 /* Products */, - ); - sourceTree = ""; - }; - 173241811BBECF8400E67992 /* Products */ = { - isa = PBXGroup; - children = ( - 173241801BBECF8400E67992 /* libicu.a */, - ); - name = Products; - sourceTree = ""; - }; - 173241821BBECF8400E67992 /* icu */ = { - isa = PBXGroup; - children = ( - 698AECE91C0726990080D889 /* common */, - 698AEE5B1C07269A0080D889 /* i18n */, - 698AF0061C07269B0080D889 /* io */, - 698AF4C41C0750CE0080D889 /* stubdata */, - ); - name = icu; - path = ../../../../../Common/3dParty/icu/icu/source; - sourceTree = ""; - }; - 698AECE91C0726990080D889 /* common */ = { - isa = PBXGroup; - children = ( - FCCB1B72248E8305000A2F32 /* unicode */, - FCCB1AB9248E82FC000A2F32 /* appendable.cpp */, - FCCB1A1C248E82ED000A2F32 /* bmpset.cpp */, - FCCB19AF248E82E3000A2F32 /* bmpset.h */, - FCCB1A55248E82F3000A2F32 /* brkeng.cpp */, - FCCB1A9D248E82F9000A2F32 /* brkeng.h */, - FCCB1A82248E82F7000A2F32 /* brkiter.cpp */, - FCCB1A12248E82EC000A2F32 /* bytestream.cpp */, - FCCB1A3C248E82F0000A2F32 /* bytestrie.cpp */, - FCCB1A91248E82F8000A2F32 /* bytestriebuilder.cpp */, - FCCB1A52248E82F2000A2F32 /* bytestrieiterator.cpp */, - FCCB1AAB248E82FB000A2F32 /* caniter.cpp */, - FCCB19B7248E82E4000A2F32 /* chariter.cpp */, - FCCB1A93248E82F8000A2F32 /* charstr.cpp */, - FCCB1A3D248E82F0000A2F32 /* charstr.h */, - FCCB19FB248E82EA000A2F32 /* cmemory.c */, - FCCB1A97248E82F9000A2F32 /* cmemory.h */, - FCCB1A54248E82F3000A2F32 /* cpputils.h */, - FCCB19C9248E82E5000A2F32 /* cstr.cpp */, - FCCB1A7F248E82F6000A2F32 /* cstr.h */, - FCCB1A90248E82F8000A2F32 /* cstring.c */, - FCCB1A59248E82F3000A2F32 /* cstring.h */, - FCCB19D9248E82E7000A2F32 /* cwchar.c */, - FCCB1A5F248E82F4000A2F32 /* cwchar.h */, - FCCB19FA248E82EA000A2F32 /* dictbe.cpp */, - FCCB19B4248E82E4000A2F32 /* dictbe.h */, - FCCB19DB248E82E7000A2F32 /* dictionarydata.cpp */, - FCCB19F0248E82E9000A2F32 /* dictionarydata.h */, - FCCB1AA2248E82FA000A2F32 /* dtintrv.cpp */, - FCCB19EB248E82E8000A2F32 /* errorcode.cpp */, - FCCB1A76248E82F6000A2F32 /* filteredbrk.cpp */, - FCCB1A20248E82ED000A2F32 /* filterednormalizer2.cpp */, - FCCB1A9A248E82F9000A2F32 /* hash.h */, - FCCB1A56248E82F3000A2F32 /* icudataver.c */, - FCCB1AAE248E82FB000A2F32 /* icuplug.cpp */, - FCCB19B0248E82E3000A2F32 /* icuplugimp.h */, - FCCB1A6D248E82F5000A2F32 /* listformatter.cpp */, - FCCB1A41248E82F1000A2F32 /* loadednormalizer2impl.cpp */, - FCCB19CC248E82E6000A2F32 /* localsvc.h */, - FCCB1A95248E82F9000A2F32 /* locavailable.cpp */, - FCCB1AA9248E82FA000A2F32 /* locbased.cpp */, - FCCB19FC248E82EA000A2F32 /* locbased.h */, - FCCB19D0248E82E6000A2F32 /* locdispnames.cpp */, - FCCB19A9248E82E3000A2F32 /* locdspnm.cpp */, - FCCB1A9F248E82FA000A2F32 /* locid.cpp */, - FCCB1A6F248E82F5000A2F32 /* loclikely.cpp */, - FCCB1ABA248E82FC000A2F32 /* locmap.c */, - FCCB1A37248E82F0000A2F32 /* locmap.h */, - FCCB1A86248E82F7000A2F32 /* locresdata.cpp */, - FCCB19D7248E82E7000A2F32 /* locutil.cpp */, - FCCB1A1B248E82ED000A2F32 /* locutil.h */, - FCCB1AA0248E82FA000A2F32 /* messageimpl.h */, - FCCB1A04248E82EB000A2F32 /* messagepattern.cpp */, - FCCB19AC248E82E3000A2F32 /* msvcres.h */, - FCCB1A29248E82EE000A2F32 /* mutex.h */, - FCCB19C7248E82E5000A2F32 /* norm2_nfc_data.h */, - FCCB19D1248E82E6000A2F32 /* norm2allmodes.h */, - FCCB1A5B248E82F3000A2F32 /* normalizer2.cpp */, - FCCB1A75248E82F6000A2F32 /* normalizer2impl.cpp */, - FCCB1A6E248E82F5000A2F32 /* normalizer2impl.h */, - FCCB1A73248E82F5000A2F32 /* normlzr.cpp */, - FCCB1A3E248E82F0000A2F32 /* parsepos.cpp */, - FCCB1A1D248E82ED000A2F32 /* patternprops.cpp */, - FCCB19E1248E82E8000A2F32 /* patternprops.h */, - FCCB19FD248E82EA000A2F32 /* pluralmap.cpp */, - FCCB19BA248E82E4000A2F32 /* pluralmap.h */, - FCCB1A05248E82EB000A2F32 /* propname_data.h */, - FCCB1A17248E82ED000A2F32 /* propname.cpp */, - FCCB1AAF248E82FB000A2F32 /* propname.h */, - FCCB1A4E248E82F2000A2F32 /* propsvec.c */, - FCCB1A02248E82EB000A2F32 /* propsvec.h */, - FCCB1A88248E82F7000A2F32 /* punycode.cpp */, - FCCB19E6248E82E8000A2F32 /* punycode.h */, - FCCB19D4248E82E6000A2F32 /* putil.cpp */, - FCCB1A71248E82F5000A2F32 /* putilimp.h */, - FCCB1A3B248E82F0000A2F32 /* rbbi.cpp */, - FCCB19EA248E82E8000A2F32 /* rbbidata.cpp */, - FCCB1A2D248E82EE000A2F32 /* rbbidata.h */, - FCCB1A61248E82F4000A2F32 /* rbbinode.cpp */, - FCCB1A42248E82F1000A2F32 /* rbbinode.h */, - FCCB1A58248E82F3000A2F32 /* rbbirb.cpp */, - FCCB19C6248E82E5000A2F32 /* rbbirb.h */, - FCCB19B1248E82E3000A2F32 /* rbbirpt.h */, - FCCB19C0248E82E4000A2F32 /* rbbiscan.cpp */, - FCCB1A99248E82F9000A2F32 /* rbbiscan.h */, - FCCB1A85248E82F7000A2F32 /* rbbisetb.cpp */, - FCCB1A98248E82F9000A2F32 /* rbbisetb.h */, - FCCB1A13248E82EC000A2F32 /* rbbistbl.cpp */, - FCCB1A2E248E82EF000A2F32 /* rbbitblb.cpp */, - FCCB19DA248E82E7000A2F32 /* rbbitblb.h */, - FCCB1A7D248E82F6000A2F32 /* resbund_cnv.cpp */, - FCCB1AB7248E82FC000A2F32 /* resbund.cpp */, - FCCB1A74248E82F5000A2F32 /* resource.cpp */, - FCCB1A19248E82ED000A2F32 /* resource.h */, - FCCB1A46248E82F1000A2F32 /* ruleiter.cpp */, - FCCB1A7E248E82F6000A2F32 /* ruleiter.h */, - FCCB1A89248E82F7000A2F32 /* schriter.cpp */, - FCCB1A36248E82F0000A2F32 /* serv.cpp */, - FCCB1A0E248E82EC000A2F32 /* serv.h */, - FCCB19F1248E82E9000A2F32 /* servlk.cpp */, - FCCB1A14248E82EC000A2F32 /* servlkf.cpp */, - FCCB1A8D248E82F8000A2F32 /* servloc.h */, - FCCB1A67248E82F4000A2F32 /* servls.cpp */, - FCCB19C2248E82E5000A2F32 /* servnotf.cpp */, - FCCB1A94248E82F8000A2F32 /* servnotf.h */, - FCCB1A2F248E82EF000A2F32 /* servrbf.cpp */, - FCCB1A26248E82EE000A2F32 /* servslkf.cpp */, - FCCB19F3248E82E9000A2F32 /* sharedobject.cpp */, - FCCB1A8E248E82F8000A2F32 /* sharedobject.h */, - FCCB19C5248E82E5000A2F32 /* simpleformatter.cpp */, - FCCB1A10248E82EC000A2F32 /* sprpimpl.h */, - FCCB1A8F248E82F8000A2F32 /* stringpiece.cpp */, - FCCB1A28248E82EE000A2F32 /* stringtriebuilder.cpp */, - FCCB1A3A248E82F0000A2F32 /* uarrsort.c */, - FCCB1AA1248E82FA000A2F32 /* uarrsort.h */, - FCCB1A64248E82F4000A2F32 /* uassert.h */, - FCCB1A23248E82EE000A2F32 /* ubidi_props_data.h */, - FCCB1A18248E82ED000A2F32 /* ubidi_props.c */, - FCCB1AAA248E82FB000A2F32 /* ubidi_props.h */, - FCCB1A77248E82F6000A2F32 /* ubidi.c */, - FCCB1A2A248E82EE000A2F32 /* ubidiimp.h */, - FCCB19D8248E82E7000A2F32 /* ubidiln.c */, - FCCB1A48248E82F1000A2F32 /* ubiditransform.c */, - FCCB19EF248E82E9000A2F32 /* ubidiwrt.c */, - FCCB1A83248E82F7000A2F32 /* ubrk.cpp */, - FCCB1AB3248E82FB000A2F32 /* ubrkimpl.h */, - FCCB1A72248E82F5000A2F32 /* ucase_props_data.h */, - FCCB19F2248E82E9000A2F32 /* ucase.cpp */, - FCCB19B6248E82E4000A2F32 /* ucase.h */, - FCCB1A92248E82F8000A2F32 /* ucasemap_titlecase_brkiter.cpp */, - FCCB19B5248E82E4000A2F32 /* ucasemap.cpp */, - FCCB19F4248E82E9000A2F32 /* ucat.c */, - FCCB19F5248E82E9000A2F32 /* uchar_props_data.h */, - FCCB1A11248E82EC000A2F32 /* uchar.c */, - FCCB19A3248E82E3000A2F32 /* ucharstrie.cpp */, - FCCB19A2248E82E3000A2F32 /* ucharstriebuilder.cpp */, - FCCB1A33248E82EF000A2F32 /* ucharstrieiterator.cpp */, - FCCB19CA248E82E5000A2F32 /* uchriter.cpp */, - FCCB19E7248E82E8000A2F32 /* ucln_cmn.cpp */, - FCCB1A69248E82F4000A2F32 /* ucln_cmn.h */, - FCCB19B3248E82E3000A2F32 /* ucln_imp.h */, - FCCB1A43248E82F1000A2F32 /* ucln.h */, - FCCB19BF248E82E4000A2F32 /* ucmndata.c */, - FCCB1A45248E82F1000A2F32 /* ucmndata.h */, - FCCB1A9B248E82F9000A2F32 /* ucnv_bld.cpp */, - FCCB1AA3248E82FA000A2F32 /* ucnv_bld.h */, - FCCB19A5248E82E3000A2F32 /* ucnv_cb.c */, - FCCB1A1E248E82ED000A2F32 /* ucnv_cnv.c */, - FCCB1A5D248E82F3000A2F32 /* ucnv_cnv.h */, - FCCB19EC248E82E9000A2F32 /* ucnv_ct.c */, - FCCB1A49248E82F1000A2F32 /* ucnv_err.c */, - FCCB1A87248E82F7000A2F32 /* ucnv_ext.cpp */, - FCCB1AB4248E82FC000A2F32 /* ucnv_ext.h */, - FCCB1A0F248E82EC000A2F32 /* ucnv_imp.h */, - FCCB1A66248E82F4000A2F32 /* ucnv_io.cpp */, - FCCB1A50248E82F2000A2F32 /* ucnv_io.h */, - FCCB1A21248E82ED000A2F32 /* ucnv_lmb.c */, - FCCB19A7248E82E3000A2F32 /* ucnv_set.c */, - FCCB19D2248E82E6000A2F32 /* ucnv_u7.c */, - FCCB1A0D248E82EC000A2F32 /* ucnv_u8.c */, - FCCB19F9248E82EA000A2F32 /* ucnv_u16.c */, - FCCB19DD248E82E7000A2F32 /* ucnv_u32.c */, - FCCB19DF248E82E7000A2F32 /* ucnv.c */, - FCCB1A79248E82F6000A2F32 /* ucnv2022.cpp */, - FCCB1A4D248E82F2000A2F32 /* ucnvbocu.cpp */, - FCCB19B2248E82E3000A2F32 /* ucnvdisp.c */, - FCCB1AA6248E82FA000A2F32 /* ucnvhz.c */, - FCCB19CB248E82E5000A2F32 /* ucnvisci.c */, - FCCB19A1248E82E3000A2F32 /* ucnvlat1.c */, - FCCB19B8248E82E4000A2F32 /* ucnvmbcs.cpp */, - FCCB1A60248E82F4000A2F32 /* ucnvmbcs.h */, - FCCB1A78248E82F6000A2F32 /* ucnvscsu.c */, - FCCB19DC248E82E7000A2F32 /* ucnvsel.cpp */, - FCCB19B9248E82E4000A2F32 /* ucol_data.h */, - FCCB19E0248E82E7000A2F32 /* ucol_swp.cpp */, - FCCB1A57248E82F3000A2F32 /* ucol_swp.h */, - FCCB19D3248E82E6000A2F32 /* ucurr.cpp */, - FCCB1A6A248E82F5000A2F32 /* ucurrimp.h */, - FCCB19CE248E82E6000A2F32 /* udata.cpp */, - FCCB1AAC248E82FB000A2F32 /* udatamem.c */, - FCCB1A09248E82EB000A2F32 /* udatamem.h */, - FCCB1A1A248E82ED000A2F32 /* udataswp.c */, - FCCB1A44248E82F1000A2F32 /* udataswp.h */, - FCCB1A9C248E82F9000A2F32 /* uelement.h */, - FCCB1A6B248E82F5000A2F32 /* uenum.c */, - FCCB19E3248E82E8000A2F32 /* uenumimp.h */, - FCCB1A4A248E82F1000A2F32 /* uhash_us.cpp */, - FCCB1A0C248E82EC000A2F32 /* uhash.c */, - FCCB1A2C248E82EE000A2F32 /* uhash.h */, - FCCB19F8248E82EA000A2F32 /* uidna.cpp */, - FCCB1A8C248E82F8000A2F32 /* uinit.cpp */, - FCCB1A4C248E82F2000A2F32 /* uinvchar.c */, - FCCB1A80248E82F7000A2F32 /* uinvchar.h */, - FCCB19CF248E82E6000A2F32 /* uiter.cpp */, - FCCB19BB248E82E4000A2F32 /* ulist.c */, - FCCB1AB0248E82FB000A2F32 /* ulist.h */, - FCCB1AA4248E82FA000A2F32 /* ulistformatter.cpp */, - FCCB1AB5248E82FC000A2F32 /* uloc_keytype.cpp */, - FCCB1A0A248E82EB000A2F32 /* uloc_tag.c */, - FCCB1AB1248E82FB000A2F32 /* uloc.cpp */, - FCCB1AB6248E82FC000A2F32 /* ulocimp.h */, - FCCB1A22248E82ED000A2F32 /* umapfile.c */, - FCCB1A8A248E82F7000A2F32 /* umapfile.h */, - FCCB1A08248E82EB000A2F32 /* umath.c */, - FCCB19F6248E82E9000A2F32 /* umutex.cpp */, - FCCB19E5248E82E8000A2F32 /* umutex.h */, - FCCB1A9E248E82F9000A2F32 /* unames.cpp */, - FCCB1A0B248E82EB000A2F32 /* unifiedcache.cpp */, - FCCB1A5C248E82F3000A2F32 /* unifiedcache.h */, - FCCB19AD248E82E3000A2F32 /* unifilt.cpp */, - FCCB19E4248E82E8000A2F32 /* unifunct.cpp */, - FCCB1A7B248E82F6000A2F32 /* uniset_closure.cpp */, - FCCB1A68248E82F4000A2F32 /* uniset_props.cpp */, - FCCB1AA7248E82FA000A2F32 /* uniset.cpp */, - FCCB19C3248E82E5000A2F32 /* unisetspan.cpp */, - FCCB19A6248E82E3000A2F32 /* unisetspan.h */, - FCCB1A5E248E82F3000A2F32 /* unistr_case_locale.cpp */, - FCCB1A30248E82EF000A2F32 /* unistr_case.cpp */, - FCCB19C1248E82E4000A2F32 /* unistr_cnv.cpp */, - FCCB1AAD248E82FB000A2F32 /* unistr_props.cpp */, - FCCB19BE248E82E4000A2F32 /* unistr_titlecase_brkiter.cpp */, - FCCB1A2B248E82EE000A2F32 /* unistr.cpp */, - FCCB19AA248E82E3000A2F32 /* unistrappender.h */, - FCCB19EE248E82E9000A2F32 /* unorm.cpp */, - FCCB1A32248E82EF000A2F32 /* unormcmp.cpp */, - FCCB1A06248E82EB000A2F32 /* unormimp.h */, - FCCB1A15248E82EC000A2F32 /* uobject.cpp */, - FCCB1A6C248E82F5000A2F32 /* uposixdefs.h */, - FCCB1A00248E82EA000A2F32 /* uprops.cpp */, - FCCB1A03248E82EB000A2F32 /* uprops.h */, - FCCB1A01248E82EB000A2F32 /* ures_cnv.c */, - FCCB1A35248E82EF000A2F32 /* uresbund.cpp */, - FCCB1A16248E82EC000A2F32 /* uresdata.cpp */, - FCCB1A70248E82F5000A2F32 /* uresdata.h */, - FCCB19C8248E82E5000A2F32 /* uresimp.h */, - FCCB1A65248E82F4000A2F32 /* ureslocs.h */, - FCCB19E8248E82E8000A2F32 /* usc_impl.c */, - FCCB1A4B248E82F2000A2F32 /* usc_impl.h */, - FCCB19E2248E82E8000A2F32 /* uscript_props.cpp */, - FCCB1A31248E82EF000A2F32 /* uscript.c */, - FCCB1A38248E82F0000A2F32 /* uset_imp.h */, - FCCB1A8B248E82F8000A2F32 /* uset_props.cpp */, - FCCB1AB2248E82FB000A2F32 /* uset.cpp */, - FCCB1A07248E82EB000A2F32 /* usetiter.cpp */, - FCCB1A53248E82F2000A2F32 /* ushape.cpp */, - FCCB1A81248E82F7000A2F32 /* usprep.cpp */, - FCCB1A27248E82EE000A2F32 /* ustack.cpp */, - FCCB19D5248E82E6000A2F32 /* ustr_cnv.cpp */, - FCCB19AE248E82E3000A2F32 /* ustr_cnv.h */, - FCCB19ED248E82E9000A2F32 /* ustr_imp.h */, - FCCB19BC248E82E4000A2F32 /* ustr_titlecase_brkiter.cpp */, - FCCB19AB248E82E3000A2F32 /* ustr_wcs.cpp */, - FCCB19A4248E82E3000A2F32 /* ustrcase_locale.cpp */, - FCCB19F7248E82EA000A2F32 /* ustrcase.cpp */, - FCCB19E9248E82E8000A2F32 /* ustrenum.cpp */, - FCCB1A47248E82F1000A2F32 /* ustrenum.h */, - FCCB1AA8248E82FA000A2F32 /* ustrfmt.c */, - FCCB1A62248E82F4000A2F32 /* ustrfmt.h */, - FCCB1A7A248E82F6000A2F32 /* ustring.cpp */, - FCCB1A5A248E82F3000A2F32 /* ustrtrns.cpp */, - FCCB1A1F248E82ED000A2F32 /* utext.cpp */, - FCCB1A39248E82F0000A2F32 /* utf_impl.c */, - FCCB1A7C248E82F6000A2F32 /* util_props.cpp */, - FCCB19C4248E82E5000A2F32 /* util.cpp */, - FCCB1A24248E82EE000A2F32 /* util.h */, - FCCB1A96248E82F9000A2F32 /* utrace.c */, - FCCB1A34248E82EF000A2F32 /* utracimp.h */, - FCCB1A25248E82EE000A2F32 /* utrie.cpp */, - FCCB1AB8248E82FC000A2F32 /* utrie.h */, - FCCB1AA5248E82FA000A2F32 /* utrie2_builder.cpp */, - FCCB19D6248E82E6000A2F32 /* utrie2_impl.h */, - FCCB19CD248E82E6000A2F32 /* utrie2.cpp */, - FCCB1A40248E82F0000A2F32 /* utrie2.h */, - FCCB19FF248E82EA000A2F32 /* uts46.cpp */, - FCCB1A4F248E82F2000A2F32 /* utypeinfo.h */, - FCCB1A3F248E82F0000A2F32 /* utypes.c */, - FCCB19BD248E82E4000A2F32 /* uvector.cpp */, - FCCB19A0248E82E2000A2F32 /* uvector.h */, - FCCB19FE248E82EA000A2F32 /* uvectr32.cpp */, - FCCB19DE248E82E7000A2F32 /* uvectr32.h */, - FCCB1A63248E82F4000A2F32 /* uvectr64.cpp */, - FCCB19A8248E82E3000A2F32 /* uvectr64.h */, - FCCB1A51248E82F2000A2F32 /* wintz.c */, - FCCB1A84248E82F7000A2F32 /* wintz.h */, - ); - path = common; - sourceTree = ""; - }; - 698AEE5B1C07269A0080D889 /* i18n */ = { - isa = PBXGroup; - children = ( - FCCB1DE6248E83E1000A2F32 /* unicode */, - FCCB1CC3248E837A000A2F32 /* affixpatternparser.cpp */, - FCCB1D14248E8387000A2F32 /* affixpatternparser.h */, - FCCB1CA2248E8377000A2F32 /* alphaindex.cpp */, - FCCB1C45248E836F000A2F32 /* anytrans.cpp */, - FCCB1CF8248E8382000A2F32 /* anytrans.h */, - FCCB1C65248E8371000A2F32 /* astro.cpp */, - FCCB1CF6248E8381000A2F32 /* astro.h */, - FCCB1C85248E8374000A2F32 /* basictz.cpp */, - FCCB1C58248E8370000A2F32 /* bocsu.cpp */, - FCCB1C82248E8374000A2F32 /* bocsu.h */, - FCCB1CFD248E8383000A2F32 /* brktrans.cpp */, - FCCB1C30248E836D000A2F32 /* brktrans.h */, - FCCB1C7E248E8374000A2F32 /* buddhcal.cpp */, - FCCB1CAB248E8378000A2F32 /* buddhcal.h */, - FCCB1C0B248E8369000A2F32 /* calendar.cpp */, - FCCB1C93248E8376000A2F32 /* casetrn.cpp */, - FCCB1CCE248E837B000A2F32 /* casetrn.h */, - FCCB1CEA248E837E000A2F32 /* cecal.cpp */, - FCCB1C04248E8369000A2F32 /* cecal.h */, - FCCB1C87248E8375000A2F32 /* chnsecal.cpp */, - FCCB1C8E248E8375000A2F32 /* chnsecal.h */, - FCCB1C73248E8373000A2F32 /* choicfmt.cpp */, - FCCB1CF5248E8381000A2F32 /* coleitr.cpp */, - FCCB1C75248E8373000A2F32 /* coll.cpp */, - FCCB1C84248E8374000A2F32 /* collation.cpp */, - FCCB1C0D248E836A000A2F32 /* collation.h */, - FCCB1CAF248E8378000A2F32 /* collationbuilder.cpp */, - FCCB1BEA248E8367000A2F32 /* collationbuilder.h */, - FCCB1CBB248E837A000A2F32 /* collationcompare.cpp */, - FCCB1C48248E836F000A2F32 /* collationcompare.h */, - FCCB1CD1248E837C000A2F32 /* collationdata.cpp */, - FCCB1C78248E8373000A2F32 /* collationdata.h */, - FCCB1C2E248E836C000A2F32 /* collationdatabuilder.cpp */, - FCCB1CD2248E837C000A2F32 /* collationdatabuilder.h */, - FCCB1D1D248E8388000A2F32 /* collationdatareader.cpp */, - FCCB1CC7248E837B000A2F32 /* collationdatareader.h */, - FCCB1C86248E8375000A2F32 /* collationdatawriter.cpp */, - FCCB1CC8248E837B000A2F32 /* collationdatawriter.h */, - FCCB1D02248E8385000A2F32 /* collationfastlatin.cpp */, - FCCB1CC2248E837A000A2F32 /* collationfastlatin.h */, - FCCB1C7F248E8374000A2F32 /* collationfastlatinbuilder.cpp */, - FCCB1BE6248E8366000A2F32 /* collationfastlatinbuilder.h */, - FCCB1C4F248E836F000A2F32 /* collationfcd.cpp */, - FCCB1C10248E836A000A2F32 /* collationfcd.h */, - FCCB1CB9248E8379000A2F32 /* collationiterator.cpp */, - FCCB1BF9248E8368000A2F32 /* collationiterator.h */, - FCCB1C99248E8376000A2F32 /* collationkeys.cpp */, - FCCB1D0D248E8386000A2F32 /* collationkeys.h */, - FCCB1C63248E8371000A2F32 /* collationroot.cpp */, - FCCB1C24248E836C000A2F32 /* collationroot.h */, - FCCB1C3C248E836E000A2F32 /* collationrootelements.cpp */, - FCCB1D03248E8385000A2F32 /* collationrootelements.h */, - FCCB1C7D248E8374000A2F32 /* collationruleparser.cpp */, - FCCB1CFE248E8384000A2F32 /* collationruleparser.h */, - FCCB1C89248E8375000A2F32 /* collationsets.cpp */, - FCCB1C91248E8376000A2F32 /* collationsets.h */, - FCCB1C83248E8374000A2F32 /* collationsettings.cpp */, - FCCB1CE3248E837D000A2F32 /* collationsettings.h */, - FCCB1C15248E836A000A2F32 /* collationtailoring.cpp */, - FCCB1C18248E836B000A2F32 /* collationtailoring.h */, - FCCB1CEE248E837F000A2F32 /* collationweights.cpp */, - FCCB1C97248E8376000A2F32 /* collationweights.h */, - FCCB1C2D248E836C000A2F32 /* collunsafe.h */, - FCCB1BD1248E8365000A2F32 /* compactdecimalformat.cpp */, - FCCB1BF1248E8367000A2F32 /* coptccal.cpp */, - FCCB1C12248E836A000A2F32 /* coptccal.h */, - FCCB1D00248E8384000A2F32 /* cpdtrans.cpp */, - FCCB1CF7248E8381000A2F32 /* cpdtrans.h */, - FCCB1C69248E8372000A2F32 /* csdetect.cpp */, - FCCB1C0F248E836A000A2F32 /* csdetect.h */, - FCCB1C4B248E836F000A2F32 /* csmatch.cpp */, - FCCB1C41248E836E000A2F32 /* csmatch.h */, - FCCB1C38248E836D000A2F32 /* csr2022.cpp */, - FCCB1CC5248E837B000A2F32 /* csr2022.h */, - FCCB1D13248E8387000A2F32 /* csrecog.cpp */, - FCCB1CCD248E837B000A2F32 /* csrecog.h */, - FCCB1CEB248E837E000A2F32 /* csrmbcs.cpp */, - FCCB1CE8248E837E000A2F32 /* csrmbcs.h */, - FCCB1C79248E8373000A2F32 /* csrsbcs.cpp */, - FCCB1C01248E8369000A2F32 /* csrsbcs.h */, - FCCB1C98248E8376000A2F32 /* csrucode.cpp */, - FCCB1C17248E836A000A2F32 /* csrucode.h */, - FCCB1BF8248E8368000A2F32 /* csrutf8.cpp */, - FCCB1C96248E8376000A2F32 /* csrutf8.h */, - FCCB1CB6248E8379000A2F32 /* curramt.cpp */, - FCCB1D16248E8388000A2F32 /* currfmt.cpp */, - FCCB1C29248E836C000A2F32 /* currfmt.h */, - FCCB1C1F248E836B000A2F32 /* currpinf.cpp */, - FCCB1CA4248E8377000A2F32 /* currunit.cpp */, - FCCB1D20248E8389000A2F32 /* dangical.cpp */, - FCCB1BD6248E8365000A2F32 /* dangical.h */, - FCCB1C70248E8372000A2F32 /* datefmt.cpp */, - FCCB1C11248E836A000A2F32 /* dayperiodrules.cpp */, - FCCB1CDE248E837D000A2F32 /* dayperiodrules.h */, - FCCB1BEC248E8367000A2F32 /* dcfmtimp.h */, - FCCB1C5B248E8371000A2F32 /* dcfmtsym.cpp */, - FCCB1CA8248E8378000A2F32 /* decContext.c */, - FCCB1C2B248E836C000A2F32 /* decContext.h */, - FCCB1C50248E8370000A2F32 /* decfmtst.cpp */, - FCCB1BED248E8367000A2F32 /* decfmtst.h */, - FCCB1C46248E836F000A2F32 /* decimalformatpattern.cpp */, - FCCB1C0E248E836A000A2F32 /* decimalformatpattern.h */, - FCCB1BFB248E8368000A2F32 /* decimalformatpatternimpl.h */, - FCCB1CCB248E837B000A2F32 /* decimfmt.cpp */, - FCCB1C37248E836D000A2F32 /* decimfmtimpl.cpp */, - FCCB1BD9248E8366000A2F32 /* decimfmtimpl.h */, - FCCB1CE4248E837E000A2F32 /* decNumber.c */, - FCCB1CF2248E8380000A2F32 /* decNumber.h */, - FCCB1CC6248E837B000A2F32 /* decNumberLocal.h */, - FCCB1BDC248E8366000A2F32 /* digitaffix.cpp */, - FCCB1D09248E8386000A2F32 /* digitaffix.h */, - FCCB1C00248E8368000A2F32 /* digitaffixesandpadding.cpp */, - FCCB1D0F248E8387000A2F32 /* digitaffixesandpadding.h */, - FCCB1CFF248E8384000A2F32 /* digitformatter.cpp */, - FCCB1C92248E8376000A2F32 /* digitformatter.h */, - FCCB1CE9248E837E000A2F32 /* digitgrouping.cpp */, - FCCB1D1F248E8389000A2F32 /* digitgrouping.h */, - FCCB1CDC248E837D000A2F32 /* digitinterval.cpp */, - FCCB1CD7248E837C000A2F32 /* digitinterval.h */, - FCCB1C9E248E8377000A2F32 /* digitlst.cpp */, - FCCB1CB3248E8379000A2F32 /* digitlst.h */, - FCCB1C57248E8370000A2F32 /* dt_impl.h */, - FCCB1D07248E8385000A2F32 /* dtfmtsym.cpp */, - FCCB1BDD248E8366000A2F32 /* dtitv_impl.h */, - FCCB1BEE248E8367000A2F32 /* dtitvfmt.cpp */, - FCCB1C67248E8372000A2F32 /* dtitvinf.cpp */, - FCCB1C53248E8370000A2F32 /* dtptngen_impl.h */, - FCCB1CA0248E8377000A2F32 /* dtptngen.cpp */, - FCCB1C74248E8373000A2F32 /* dtrule.cpp */, - FCCB1C55248E8370000A2F32 /* esctrn.cpp */, - FCCB1C64248E8371000A2F32 /* esctrn.h */, - FCCB1BE7248E8366000A2F32 /* ethpccal.cpp */, - FCCB1C60248E8371000A2F32 /* ethpccal.h */, - FCCB1C7C248E8374000A2F32 /* fmtable_cnv.cpp */, - FCCB1C1E248E836B000A2F32 /* fmtable.cpp */, - FCCB1BEF248E8367000A2F32 /* fmtableimp.h */, - FCCB1D01248E8384000A2F32 /* format.cpp */, - FCCB1C56248E8370000A2F32 /* fphdlimp.cpp */, - FCCB1BF7248E8368000A2F32 /* fphdlimp.h */, - FCCB1D0C248E8386000A2F32 /* fpositer.cpp */, - FCCB1D1E248E8388000A2F32 /* funcrepl.cpp */, - FCCB1D06248E8385000A2F32 /* funcrepl.h */, - FCCB1C3F248E836E000A2F32 /* gender.cpp */, - FCCB1D1A248E8388000A2F32 /* gregocal.cpp */, - FCCB1CA3248E8377000A2F32 /* gregoimp.cpp */, - FCCB1CD3248E837C000A2F32 /* gregoimp.h */, - FCCB1BF0248E8367000A2F32 /* hebrwcal.cpp */, - FCCB1C4A248E836F000A2F32 /* hebrwcal.h */, - FCCB1CC4248E837A000A2F32 /* indiancal.cpp */, - FCCB1CD6248E837C000A2F32 /* indiancal.h */, - FCCB1C76248E8373000A2F32 /* inputext.cpp */, - FCCB1C21248E836B000A2F32 /* inputext.h */, - FCCB1BEB248E8367000A2F32 /* islamcal.cpp */, - FCCB1C39248E836D000A2F32 /* islamcal.h */, - FCCB1CB7248E8379000A2F32 /* japancal.cpp */, - FCCB1C5D248E8371000A2F32 /* japancal.h */, - FCCB1BD5248E8365000A2F32 /* measfmt.cpp */, - FCCB1CC0248E837A000A2F32 /* measunit.cpp */, - FCCB1CDB248E837D000A2F32 /* measure.cpp */, - FCCB1D0B248E8386000A2F32 /* msgfmt_impl.h */, - FCCB1CAD248E8378000A2F32 /* msgfmt.cpp */, - FCCB1C8D248E8375000A2F32 /* name2uni.cpp */, - FCCB1CD4248E837C000A2F32 /* name2uni.h */, - FCCB1D1B248E8388000A2F32 /* nfrlist.h */, - FCCB1C49248E836F000A2F32 /* nfrs.cpp */, - FCCB1C20248E836B000A2F32 /* nfrs.h */, - FCCB1C02248E8369000A2F32 /* nfrule.cpp */, - FCCB1C54248E8370000A2F32 /* nfrule.h */, - FCCB1BE8248E8366000A2F32 /* nfsubs.cpp */, - FCCB1D08248E8386000A2F32 /* nfsubs.h */, - FCCB1BE0248E8366000A2F32 /* nortrans.cpp */, - FCCB1C23248E836C000A2F32 /* nortrans.h */, - FCCB1C3B248E836E000A2F32 /* nultrans.cpp */, - FCCB1C80248E8374000A2F32 /* nultrans.h */, - FCCB1C0C248E8369000A2F32 /* numfmt.cpp */, - FCCB1CAA248E8378000A2F32 /* numsys_impl.h */, - FCCB1C06248E8369000A2F32 /* numsys.cpp */, - FCCB1CF4248E8380000A2F32 /* olsontz.cpp */, - FCCB1C3D248E836E000A2F32 /* olsontz.h */, - FCCB1CA7248E8378000A2F32 /* persncal.cpp */, - FCCB1C25248E836C000A2F32 /* persncal.h */, - FCCB1C14248E836A000A2F32 /* pluralaffix.cpp */, - FCCB1C0A248E8369000A2F32 /* pluralaffix.h */, - FCCB1C66248E8372000A2F32 /* plurfmt.cpp */, - FCCB1C8B248E8375000A2F32 /* plurrule_impl.h */, - FCCB1CDA248E837D000A2F32 /* plurrule.cpp */, - FCCB1C77248E8373000A2F32 /* precision.cpp */, - FCCB1D17248E8388000A2F32 /* precision.h */, - FCCB1C08248E8369000A2F32 /* quant.cpp */, - FCCB1CEF248E837F000A2F32 /* quant.h */, - FCCB1C9B248E8377000A2F32 /* quantityformatter.cpp */, - FCCB1C9D248E8377000A2F32 /* quantityformatter.h */, - FCCB1D15248E8387000A2F32 /* rbnf.cpp */, - FCCB1CAE248E8378000A2F32 /* rbt_data.cpp */, - FCCB1C59248E8370000A2F32 /* rbt_data.h */, - FCCB1D11248E8387000A2F32 /* rbt_pars.cpp */, - FCCB1CB5248E8379000A2F32 /* rbt_pars.h */, - FCCB1CDD248E837D000A2F32 /* rbt_rule.cpp */, - FCCB1BD8248E8365000A2F32 /* rbt_rule.h */, - FCCB1C34248E836D000A2F32 /* rbt_set.cpp */, - FCCB1C51248E8370000A2F32 /* rbt_set.h */, - FCCB1D18248E8388000A2F32 /* rbt.cpp */, - FCCB1CA6248E8378000A2F32 /* rbt.h */, - FCCB1C3A248E836E000A2F32 /* rbtz.cpp */, - FCCB1C5A248E8370000A2F32 /* regexcmp.cpp */, - FCCB1C03248E8369000A2F32 /* regexcmp.h */, - FCCB1C07248E8369000A2F32 /* regexcst.h */, - FCCB1C94248E8376000A2F32 /* regeximp.cpp */, - FCCB1CEC248E837E000A2F32 /* regeximp.h */, - FCCB1CDF248E837D000A2F32 /* regexst.cpp */, - FCCB1C8C248E8375000A2F32 /* regexst.h */, - FCCB1C13248E836A000A2F32 /* regextxt.cpp */, - FCCB1BF4248E8367000A2F32 /* regextxt.h */, - FCCB1C9F248E8377000A2F32 /* region_impl.h */, - FCCB1CBD248E837A000A2F32 /* region.cpp */, - FCCB1CE2248E837D000A2F32 /* reldatefmt.cpp */, - FCCB1D1C248E8388000A2F32 /* reldtfmt.cpp */, - FCCB1CA1248E8377000A2F32 /* reldtfmt.h */, - FCCB1BF5248E8367000A2F32 /* rematch.cpp */, - FCCB1C26248E836C000A2F32 /* remtrans.cpp */, - FCCB1C05248E8369000A2F32 /* remtrans.h */, - FCCB1BDF248E8366000A2F32 /* repattrn.cpp */, - FCCB1C1A248E836B000A2F32 /* rulebasedcollator.cpp */, - FCCB1CB0248E8379000A2F32 /* scientificnumberformatter.cpp */, - FCCB1CC9248E837B000A2F32 /* scriptset.cpp */, - FCCB1CB1248E8379000A2F32 /* scriptset.h */, - FCCB1CE7248E837E000A2F32 /* search.cpp */, - FCCB1C22248E836B000A2F32 /* selfmt.cpp */, - FCCB1C16248E836A000A2F32 /* selfmtimpl.h */, - FCCB1CFC248E8383000A2F32 /* sharedbreakiterator.cpp */, - FCCB1BD7248E8365000A2F32 /* sharedbreakiterator.h */, - FCCB1C95248E8376000A2F32 /* sharedcalendar.h */, - FCCB1C62248E8371000A2F32 /* shareddateformatsymbols.h */, - FCCB1BE3248E8366000A2F32 /* sharednumberformat.h */, - FCCB1C09248E8369000A2F32 /* sharedpluralrules.h */, - FCCB1CE6248E837E000A2F32 /* significantdigitinterval.h */, - FCCB1C71248E8373000A2F32 /* simpletz.cpp */, - FCCB1BD2248E8365000A2F32 /* smallintformatter.cpp */, - FCCB1C6A248E8372000A2F32 /* smallintformatter.h */, - FCCB1C7A248E8373000A2F32 /* smpdtfmt.cpp */, - FCCB1CCA248E837B000A2F32 /* smpdtfst.cpp */, - FCCB1CE1248E837D000A2F32 /* smpdtfst.h */, - FCCB1C52248E8370000A2F32 /* sortkey.cpp */, - FCCB1BE5248E8366000A2F32 /* standardplural.cpp */, - FCCB1BD3248E8365000A2F32 /* standardplural.h */, - FCCB1C6D248E8372000A2F32 /* strmatch.cpp */, - FCCB1CCF248E837C000A2F32 /* strmatch.h */, - FCCB1BF6248E8368000A2F32 /* strrepl.cpp */, - FCCB1CF9248E8382000A2F32 /* strrepl.h */, - FCCB1C1B248E836B000A2F32 /* stsearch.cpp */, - FCCB1C9C248E8377000A2F32 /* taiwncal.cpp */, - FCCB1C1C248E836B000A2F32 /* taiwncal.h */, - FCCB1CCC248E837B000A2F32 /* timezone.cpp */, - FCCB1C3E248E836E000A2F32 /* titletrn.cpp */, - FCCB1C47248E836F000A2F32 /* titletrn.h */, - FCCB1C5C248E8371000A2F32 /* tmunit.cpp */, - FCCB1D05248E8385000A2F32 /* tmutamt.cpp */, - FCCB1CD8248E837C000A2F32 /* tmutfmt.cpp */, - FCCB1CF0248E837F000A2F32 /* tolowtrn.cpp */, - FCCB1C19248E836B000A2F32 /* tolowtrn.h */, - FCCB1C27248E836C000A2F32 /* toupptrn.cpp */, - FCCB1BE4248E8366000A2F32 /* toupptrn.h */, - FCCB1CA5248E8377000A2F32 /* translit.cpp */, - FCCB1C90248E8375000A2F32 /* transreg.cpp */, - FCCB1CA9248E8378000A2F32 /* transreg.h */, - FCCB1C6E248E8372000A2F32 /* tridpars.cpp */, - FCCB1BF2248E8367000A2F32 /* tridpars.h */, - FCCB1C4D248E836F000A2F32 /* tzfmt.cpp */, - FCCB1C43248E836E000A2F32 /* tzgnames.cpp */, - FCCB1CD9248E837C000A2F32 /* tzgnames.h */, - FCCB1CD0248E837C000A2F32 /* tznames_impl.cpp */, - FCCB1CBF248E837A000A2F32 /* tznames_impl.h */, - FCCB1C28248E836C000A2F32 /* tznames.cpp */, - FCCB1C2A248E836C000A2F32 /* tzrule.cpp */, - FCCB1BD4248E8365000A2F32 /* tztrans.cpp */, - FCCB1BF3248E8367000A2F32 /* ucal.cpp */, - FCCB1C5E248E8371000A2F32 /* ucln_in.cpp */, - FCCB1BE9248E8366000A2F32 /* ucln_in.h */, - FCCB1CBE248E837A000A2F32 /* ucol_imp.h */, - FCCB1CB2248E8379000A2F32 /* ucol_res.cpp */, - FCCB1C2C248E836C000A2F32 /* ucol_sit.cpp */, - FCCB1CAC248E8378000A2F32 /* ucol.cpp */, - FCCB1C36248E836D000A2F32 /* ucoleitr.cpp */, - FCCB1C8F248E8375000A2F32 /* ucsdet.cpp */, - FCCB1C32248E836D000A2F32 /* udat.cpp */, - FCCB1C42248E836E000A2F32 /* udateintervalformat.cpp */, - FCCB1C5F248E8371000A2F32 /* udatpg.cpp */, - FCCB1C6C248E8372000A2F32 /* ufieldpositer.cpp */, - FCCB1CBC248E837A000A2F32 /* uitercollationiterator.cpp */, - FCCB1D12248E8387000A2F32 /* uitercollationiterator.h */, - FCCB1D0A248E8386000A2F32 /* ulocdata.c */, - FCCB1C33248E836D000A2F32 /* umsg_imp.h */, - FCCB1CC1248E837A000A2F32 /* umsg.cpp */, - FCCB1CB8248E8379000A2F32 /* unesctrn.cpp */, - FCCB1D19248E8388000A2F32 /* unesctrn.h */, - FCCB1CFA248E8382000A2F32 /* uni2name.cpp */, - FCCB1C44248E836E000A2F32 /* uni2name.h */, - FCCB1BFC248E8368000A2F32 /* unum.cpp */, - FCCB1C6B248E8372000A2F32 /* unumsys.cpp */, - FCCB1C2F248E836D000A2F32 /* upluralrules.cpp */, - FCCB1C35248E836D000A2F32 /* uregex.cpp */, - FCCB1C6F248E8372000A2F32 /* uregexc.cpp */, - FCCB1C72248E8373000A2F32 /* uregion.cpp */, - FCCB1C40248E836E000A2F32 /* usearch.cpp */, - FCCB1C61248E8371000A2F32 /* uspoof_build.cpp */, - FCCB1C81248E8374000A2F32 /* uspoof_conf.cpp */, - FCCB1CFB248E8383000A2F32 /* uspoof_conf.h */, - FCCB1BE2248E8366000A2F32 /* uspoof_impl.cpp */, - FCCB1C8A248E8375000A2F32 /* uspoof_impl.h */, - FCCB1CB4248E8379000A2F32 /* uspoof.cpp */, - FCCB1C7B248E8373000A2F32 /* usrchimp.h */, - FCCB1D04248E8385000A2F32 /* utf8collationiterator.cpp */, - FCCB1D0E248E8387000A2F32 /* utf8collationiterator.h */, - FCCB1BDB248E8366000A2F32 /* utf16collationiterator.cpp */, - FCCB1C4C248E836F000A2F32 /* utf16collationiterator.h */, - FCCB1CF3248E8380000A2F32 /* utmscale.c */, - FCCB1C31248E836D000A2F32 /* utrans.cpp */, - FCCB1C4E248E836F000A2F32 /* valueformatter.cpp */, - FCCB1BE1248E8366000A2F32 /* valueformatter.h */, - FCCB1BDE248E8366000A2F32 /* visibledigits.cpp */, - FCCB1CED248E837F000A2F32 /* visibledigits.h */, - FCCB1CD5248E837C000A2F32 /* vtzone.cpp */, - FCCB1D10248E8387000A2F32 /* vzone.cpp */, - FCCB1C9A248E8376000A2F32 /* vzone.h */, - FCCB1C68248E8372000A2F32 /* windtfmt.cpp */, - FCCB1C1D248E836B000A2F32 /* windtfmt.h */, - FCCB1CE0248E837D000A2F32 /* winnmfmt.cpp */, - FCCB1C88248E8375000A2F32 /* winnmfmt.h */, - FCCB1CBA248E8379000A2F32 /* wintzimpl.cpp */, - FCCB1CE5248E837E000A2F32 /* wintzimpl.h */, - FCCB1BFA248E8368000A2F32 /* zonemeta.cpp */, - FCCB1BFE248E8368000A2F32 /* zonemeta.h */, - FCCB1BFF248E8368000A2F32 /* zrule.cpp */, - FCCB1BDA248E8366000A2F32 /* zrule.h */, - FCCB1BFD248E8368000A2F32 /* ztrans.cpp */, - FCCB1CF1248E8380000A2F32 /* ztrans.h */, - ); - path = i18n; - sourceTree = ""; - }; - 698AF0061C07269B0080D889 /* io */ = { - isa = PBXGroup; - children = ( - FCCB1EA1248E8447000A2F32 /* unicode */, - FCCB1E90248E8440000A2F32 /* locbund.cpp */, - FCCB1E8E248E843F000A2F32 /* locbund.h */, - FCCB1E92248E8440000A2F32 /* sprintf.c */, - FCCB1E8A248E843F000A2F32 /* sscanf.c */, - FCCB1E88248E843F000A2F32 /* ucln_io.cpp */, - FCCB1E87248E843F000A2F32 /* ucln_io.h */, - FCCB1E89248E843F000A2F32 /* ufile.c */, - FCCB1E94248E8440000A2F32 /* ufile.h */, - FCCB1E85248E843F000A2F32 /* ufmt_cmn.c */, - FCCB1E8D248E843F000A2F32 /* ufmt_cmn.h */, - FCCB1E8C248E843F000A2F32 /* uprintf.cpp */, - FCCB1E8B248E843F000A2F32 /* uprintf.h */, - FCCB1E8F248E843F000A2F32 /* uprntf_p.c */, - FCCB1E91248E8440000A2F32 /* uscanf_p.c */, - FCCB1E93248E8440000A2F32 /* uscanf.c */, - FCCB1E86248E843F000A2F32 /* uscanf.h */, - FCCB1E83248E843F000A2F32 /* ustdio.c */, - FCCB1E84248E843F000A2F32 /* ustream.cpp */, - ); - path = io; - sourceTree = ""; - }; - 698AF4C41C0750CE0080D889 /* stubdata */ = { - isa = PBXGroup; - children = ( - FCCB1EA4248E845E000A2F32 /* stubdata.c */, - ); - path = stubdata; - sourceTree = ""; - }; - FCCB1B72248E8305000A2F32 /* unicode */ = { - isa = PBXGroup; - children = ( - FCCB1B73248E8305000A2F32 /* utf_old.h */, - FCCB1B74248E8305000A2F32 /* ubrk.h */, - FCCB1B75248E8305000A2F32 /* stringpiece.h */, - FCCB1B76248E8305000A2F32 /* ucat.h */, - FCCB1B77248E8305000A2F32 /* ptypes.h */, - FCCB1B78248E8305000A2F32 /* usetiter.h */, - FCCB1B79248E8305000A2F32 /* errorcode.h */, - FCCB1B7A248E8305000A2F32 /* dtintrv.h */, - FCCB1B7B248E8305000A2F32 /* ucurr.h */, - FCCB1B7C248E8305000A2F32 /* icuplug.h */, - FCCB1B7D248E8305000A2F32 /* utext.h */, - FCCB1B7E248E8305000A2F32 /* parsepos.h */, - FCCB1B7F248E8305000A2F32 /* urep.h */, - FCCB1B80248E8305000A2F32 /* utf32.h */, - FCCB1B81248E8305000A2F32 /* ustring.h */, - FCCB1B82248E8305000A2F32 /* ubiditransform.h */, - FCCB1B83248E8305000A2F32 /* uenum.h */, - FCCB1B84248E8305000A2F32 /* appendable.h */, - FCCB1B85248E8305000A2F32 /* uset.h */, - FCCB1B87248E8305000A2F32 /* schriter.h */, - FCCB1B88248E8305000A2F32 /* uldnames.h */, - FCCB1B89248E8305000A2F32 /* uiter.h */, - FCCB1B8A248E8305000A2F32 /* docmain.h */, - FCCB1B8B248E8305000A2F32 /* uniset.h */, - FCCB1B8C248E8305000A2F32 /* udata.h */, - FCCB1B8D248E8305000A2F32 /* stringtriebuilder.h */, - FCCB1B8E248E8305000A2F32 /* chariter.h */, - FCCB1B8F248E8305000A2F32 /* umisc.h */, - FCCB1B90248E8305000A2F32 /* uloc.h */, - FCCB1B91248E8305000A2F32 /* bytestriebuilder.h */, - FCCB1B92248E8305000A2F32 /* utrace.h */, - FCCB1B93248E8305000A2F32 /* locdspnm.h */, - FCCB1B94248E8305000A2F32 /* uchriter.h */, - FCCB1B95248E8305000A2F32 /* enumset.h */, - FCCB1B96248E8305000A2F32 /* utf.h */, - FCCB1B97248E8305000A2F32 /* strenum.h */, - FCCB1B98248E8305000A2F32 /* ucnv_err.h */, - FCCB1B99248E8305000A2F32 /* bytestrie.h */, - FCCB1B9A248E8305000A2F32 /* listformatter.h */, - FCCB1B9B248E8305000A2F32 /* uobject.h */, - FCCB1B9C248E8305000A2F32 /* ures.h */, - FCCB1B9D248E8305000A2F32 /* normlzr.h */, - FCCB1B9E248E8305000A2F32 /* usprep.h */, - FCCB1B9F248E8305000A2F32 /* urename.h */, - FCCB1BA0248E8305000A2F32 /* caniter.h */, - FCCB1BA1248E8305000A2F32 /* ucharstrie.h */, - FCCB1BA2248E8305000A2F32 /* unistr.h */, - FCCB1BA3248E8305000A2F32 /* rbbi.h */, - FCCB1BA4248E8305000A2F32 /* idna.h */, - FCCB1BA5248E8305000A2F32 /* unorm2.h */, - FCCB1BA6248E8305000A2F32 /* dbbi.h */, - FCCB1BA7248E8305000A2F32 /* bytestream.h */, - FCCB1BA8248E8305000A2F32 /* uversion.h */, - FCCB1BA9248E8305000A2F32 /* messagepattern.h */, - FCCB1BAA248E8305000A2F32 /* uidna.h */, - FCCB1BAB248E8305000A2F32 /* filteredbrk.h */, - FCCB1BAC248E8305000A2F32 /* symtable.h */, - FCCB1BAD248E8305000A2F32 /* ucasemap.h */, - FCCB1BAE248E8305000A2F32 /* udisplaycontext.h */, - FCCB1BAF248E8305000A2F32 /* umachine.h */, - FCCB1BB0248E8305000A2F32 /* ustringtrie.h */, - FCCB1BB1248E8305000A2F32 /* icudataver.h */, - FCCB1BB2248E8305000A2F32 /* uchar.h */, - FCCB1BB3248E8305000A2F32 /* unorm.h */, - FCCB1BB4248E8305000A2F32 /* ushape.h */, - FCCB1BB5248E8305000A2F32 /* unifunct.h */, - FCCB1BB6248E8305000A2F32 /* simpleformatter.h */, - FCCB1BB7248E8305000A2F32 /* ucnv_cb.h */, - FCCB1BB8248E8305000A2F32 /* locid.h */, - FCCB1BB9248E8305000A2F32 /* resbund.h */, - FCCB1BBA248E8305000A2F32 /* ubidi.h */, - FCCB1BBB248E8305000A2F32 /* uvernum.h */, - FCCB1BBC248E8305000A2F32 /* unimatch.h */, - FCCB1BBD248E8305000A2F32 /* ucnvsel.h */, - FCCB1BBE248E8305000A2F32 /* parseerr.h */, - FCCB1BBF248E8305000A2F32 /* putil.h */, - FCCB1BC0248E8305000A2F32 /* normalizer2.h */, - FCCB1BC1248E8305000A2F32 /* ucnv.h */, - FCCB1BC2248E8305000A2F32 /* ucharstriebuilder.h */, - FCCB1BC3248E8305000A2F32 /* uconfig.h */, - FCCB1BC4248E8305000A2F32 /* utf16.h */, - FCCB1BC5248E8305000A2F32 /* brkiter.h */, - FCCB1BC6248E8305000A2F32 /* platform.h */, - FCCB1BC7248E8305000A2F32 /* rep.h */, - FCCB1BC9248E8305000A2F32 /* std_string.h */, - FCCB1BCA248E8305000A2F32 /* utf8.h */, - FCCB1BCB248E8305000A2F32 /* localpointer.h */, - FCCB1BCC248E8305000A2F32 /* uclean.h */, - FCCB1BCD248E8305000A2F32 /* uscript.h */, - FCCB1BCE248E8305000A2F32 /* utypes.h */, - FCCB1BCF248E8305000A2F32 /* ulistformatter.h */, - FCCB1BD0248E8305000A2F32 /* unifilt.h */, - ); - path = unicode; - sourceTree = ""; - }; - FCCB1DE6248E83E1000A2F32 /* unicode */ = { - isa = PBXGroup; - children = ( - FCCB1E3E248E841A000A2F32 /* alphaindex.h */, - FCCB1E73248E8420000A2F32 /* basictz.h */, - FCCB1E63248E841F000A2F32 /* calendar.h */, - FCCB1E5C248E841E000A2F32 /* choicfmt.h */, - FCCB1E3B248E841A000A2F32 /* coleitr.h */, - FCCB1E59248E841D000A2F32 /* coll.h */, - FCCB1E4E248E841C000A2F32 /* compactdecimalformat.h */, - FCCB1E4D248E841C000A2F32 /* curramt.h */, - FCCB1E64248E841F000A2F32 /* currpinf.h */, - FCCB1E52248E841D000A2F32 /* currunit.h */, - FCCB1E43248E841B000A2F32 /* datefmt.h */, - FCCB1E65248E841F000A2F32 /* dcfmtsym.h */, - FCCB1E53248E841D000A2F32 /* decimfmt.h */, - FCCB1E78248E8421000A2F32 /* dtfmtsym.h */, - FCCB1E79248E8421000A2F32 /* dtitvfmt.h */, - FCCB1E38248E841A000A2F32 /* dtitvinf.h */, - FCCB1E4C248E841C000A2F32 /* dtptngen.h */, - FCCB1E6A248E841F000A2F32 /* dtrule.h */, - FCCB1E5E248E841E000A2F32 /* fieldpos.h */, - FCCB1E7E248E8422000A2F32 /* fmtable.h */, - FCCB1E74248E8421000A2F32 /* format.h */, - FCCB1E44248E841B000A2F32 /* fpositer.h */, - FCCB1E5F248E841E000A2F32 /* gender.h */, - FCCB1E3F248E841A000A2F32 /* gregocal.h */, - FCCB1E58248E841D000A2F32 /* measfmt.h */, - FCCB1E3C248E841A000A2F32 /* measunit.h */, - FCCB1E40248E841B000A2F32 /* measure.h */, - FCCB1E5B248E841E000A2F32 /* msgfmt.h */, - FCCB1E66248E841F000A2F32 /* numfmt.h */, - FCCB1E71248E8420000A2F32 /* numsys.h */, - FCCB1E6D248E8420000A2F32 /* plurfmt.h */, - FCCB1E4B248E841C000A2F32 /* plurrule.h */, - FCCB1E57248E841D000A2F32 /* rbnf.h */, - FCCB1E80248E8422000A2F32 /* rbtz.h */, - FCCB1E48248E841B000A2F32 /* regex.h */, - FCCB1E6F248E8420000A2F32 /* region.h */, - FCCB1E75248E8421000A2F32 /* reldatefmt.h */, - FCCB1E42248E841B000A2F32 /* scientificnumberformatter.h */, - FCCB1E6B248E8420000A2F32 /* search.h */, - FCCB1E60248E841E000A2F32 /* selfmt.h */, - FCCB1E68248E841F000A2F32 /* simpletz.h */, - FCCB1E7D248E8421000A2F32 /* smpdtfmt.h */, - FCCB1E5A248E841E000A2F32 /* sortkey.h */, - FCCB1E6C248E8420000A2F32 /* stsearch.h */, - FCCB1E4F248E841C000A2F32 /* tblcoll.h */, - FCCB1E69248E841F000A2F32 /* timezone.h */, - FCCB1E6E248E8420000A2F32 /* tmunit.h */, - FCCB1E7C248E8421000A2F32 /* tmutamt.h */, - FCCB1E56248E841D000A2F32 /* tmutfmt.h */, - FCCB1E46248E841B000A2F32 /* translit.h */, - FCCB1E81248E8422000A2F32 /* tzfmt.h */, - FCCB1E50248E841C000A2F32 /* tznames.h */, - FCCB1E41248E841B000A2F32 /* tzrule.h */, - FCCB1E70248E8420000A2F32 /* tztrans.h */, - FCCB1E77248E8421000A2F32 /* ucal.h */, - FCCB1E7B248E8421000A2F32 /* ucol.h */, - FCCB1E82248E8422000A2F32 /* ucoleitr.h */, - FCCB1E5D248E841E000A2F32 /* ucsdet.h */, - FCCB1E7A248E8421000A2F32 /* udat.h */, - FCCB1E61248E841E000A2F32 /* udateintervalformat.h */, - FCCB1E35248E8419000A2F32 /* udatpg.h */, - FCCB1E47248E841B000A2F32 /* ufieldpositer.h */, - FCCB1E7F248E8422000A2F32 /* uformattable.h */, - FCCB1E76248E8421000A2F32 /* ugender.h */, - FCCB1E37248E841A000A2F32 /* ulocdata.h */, - FCCB1E4A248E841C000A2F32 /* umsg.h */, - FCCB1E67248E841F000A2F32 /* unirepl.h */, - FCCB1E62248E841F000A2F32 /* unum.h */, - FCCB1E51248E841C000A2F32 /* unumsys.h */, - FCCB1E72248E8420000A2F32 /* upluralrules.h */, - FCCB1E3D248E841A000A2F32 /* uregex.h */, - FCCB1E36248E841A000A2F32 /* uregion.h */, - FCCB1E55248E841D000A2F32 /* ureldatefmt.h */, - FCCB1E45248E841B000A2F32 /* usearch.h */, - FCCB1E54248E841D000A2F32 /* uspoof.h */, - FCCB1E39248E841A000A2F32 /* utmscale.h */, - FCCB1E49248E841B000A2F32 /* utrans.h */, - FCCB1E3A248E841A000A2F32 /* vtzone.h */, - ); - path = unicode; - sourceTree = ""; - }; - FCCB1EA1248E8447000A2F32 /* unicode */ = { - isa = PBXGroup; - children = ( - FCCB1EA2248E8447000A2F32 /* ustdio.h */, - FCCB1EA3248E8447000A2F32 /* ustream.h */, - ); - path = unicode; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 1732417F1BBECF8400E67992 /* icu */ = { - isa = PBXNativeTarget; - buildConfigurationList = 173241891BBECF8400E67992 /* Build configuration list for PBXNativeTarget "icu" */; - buildPhases = ( - 1732417C1BBECF8400E67992 /* Sources */, - 1732417D1BBECF8400E67992 /* Frameworks */, - 1732417E1BBECF8400E67992 /* CopyFiles */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = icu; - productName = icu; - productReference = 173241801BBECF8400E67992 /* libicu.a */; - productType = "com.apple.product-type.library.static"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 173241781BBECF8400E67992 /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 0930; - ORGANIZATIONNAME = "Ascensio System SIA"; - TargetAttributes = { - 1732417F1BBECF8400E67992 = { - CreatedOnToolsVersion = 7.0.1; - }; - }; - }; - buildConfigurationList = 1732417B1BBECF8400E67992 /* Build configuration list for PBXProject "icu" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 0; - knownRegions = ( - English, - en, - ); - mainGroup = 173241771BBECF8400E67992; - productRefGroup = 173241811BBECF8400E67992 /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 1732417F1BBECF8400E67992 /* icu */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXSourcesBuildPhase section */ - 1732417C1BBECF8400E67992 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - FCCB1AED248E82FC000A2F32 /* ucnv_ct.c in Sources */, - FCCB1DD2248E8389000A2F32 /* cpdtrans.cpp in Sources */, - FCCB1AD1248E82FC000A2F32 /* util.cpp in Sources */, - FCCB1B3B248E82FD000A2F32 /* uvectr64.cpp in Sources */, - FCCB1B33248E82FD000A2F32 /* ushape.cpp in Sources */, - FCCB1E95248E8440000A2F32 /* ustdio.c in Sources */, - FCCB1D44248E8389000A2F32 /* rulebasedcollator.cpp in Sources */, - FCCB1D6B248E8389000A2F32 /* regexcmp.cpp in Sources */, - FCCB1D69248E8389000A2F32 /* fphdlimp.cpp in Sources */, - FCCB1D43248E8389000A2F32 /* collationtailoring.cpp in Sources */, - FCCB1B6C248E82FD000A2F32 /* uloc.cpp in Sources */, - FCCB1AD0248E82FC000A2F32 /* unisetspan.cpp in Sources */, - FCCB1D92248E8389000A2F32 /* ucsdet.cpp in Sources */, - FCCB1E9C248E8440000A2F32 /* uprntf_p.c in Sources */, - FCCB1B1A248E82FC000A2F32 /* unistr.cpp in Sources */, - FCCB1B3F248E82FD000A2F32 /* uenum.c in Sources */, - FCCB1D61248E8389000A2F32 /* nfrs.cpp in Sources */, - FCCB1D90248E8389000A2F32 /* collationsets.cpp in Sources */, - FCCB1D85248E8389000A2F32 /* smpdtfmt.cpp in Sources */, - FCCB1B60248E82FD000A2F32 /* locid.cpp in Sources */, - FCCB1D84248E8389000A2F32 /* csrsbcs.cpp in Sources */, - FCCB1B52248E82FD000A2F32 /* ucnv_ext.cpp in Sources */, - FCCB1D2D248E8389000A2F32 /* nfsubs.cpp in Sources */, - FCCB1DD5248E8389000A2F32 /* utf8collationiterator.cpp in Sources */, - FCCB1ABF248E82FC000A2F32 /* ucnv_cb.c in Sources */, - FCCB1E97248E8440000A2F32 /* ufmt_cmn.c in Sources */, - FCCB1D6E248E8389000A2F32 /* ucln_in.cpp in Sources */, - FCCB1AFD248E82FC000A2F32 /* uprops.cpp in Sources */, - FCCB1D97248E8389000A2F32 /* collationkeys.cpp in Sources */, - FCCB1DBF248E8389000A2F32 /* digitinterval.cpp in Sources */, - FCCB1B2F248E82FC000A2F32 /* ucnvbocu.cpp in Sources */, - FCCB1B16248E82FC000A2F32 /* utrie.cpp in Sources */, - FCCB1D25248E8389000A2F32 /* utf16collationiterator.cpp in Sources */, - FCCB1D96248E8389000A2F32 /* csrucode.cpp in Sources */, - FCCB1D83248E8389000A2F32 /* precision.cpp in Sources */, - FCCB1AF7248E82FC000A2F32 /* ucnv_u16.c in Sources */, - FCCB1B4D248E82FD000A2F32 /* usprep.cpp in Sources */, - FCCB1B31248E82FC000A2F32 /* wintz.c in Sources */, - FCCB1D98248E8389000A2F32 /* quantityformatter.cpp in Sources */, - FCCB1B26248E82FC000A2F32 /* bytestrie.cpp in Sources */, - FCCB1AC4248E82FC000A2F32 /* ucnvdisp.c in Sources */, - FCCB1D73248E8389000A2F32 /* plurfmt.cpp in Sources */, - FCCB1B45248E82FD000A2F32 /* filteredbrk.cpp in Sources */, - FCCB1DB7248E8389000A2F32 /* decimfmt.cpp in Sources */, - FCCB1AF4248E82FC000A2F32 /* umutex.cpp in Sources */, - FCCB1ADB248E82FC000A2F32 /* ucurr.cpp in Sources */, - FCCB1D27248E8389000A2F32 /* visibledigits.cpp in Sources */, - FCCB1B6A248E82FD000A2F32 /* unistr_props.cpp in Sources */, - FCCB1AE6248E82FC000A2F32 /* uscript_props.cpp in Sources */, - FCCB1D6F248E8389000A2F32 /* udatpg.cpp in Sources */, - FCCB1D3E248E8389000A2F32 /* calendar.cpp in Sources */, - FCCB1D62248E8389000A2F32 /* csmatch.cpp in Sources */, - FCCB1DD4248E8389000A2F32 /* collationfastlatin.cpp in Sources */, - FCCB1B65248E82FD000A2F32 /* uniset.cpp in Sources */, - FCCB1AF0248E82FC000A2F32 /* servlk.cpp in Sources */, - FCCB1B10248E82FC000A2F32 /* patternprops.cpp in Sources */, - FCCB1B5D248E82FD000A2F32 /* utrace.c in Sources */, - FCCB1AC1248E82FC000A2F32 /* locdspnm.cpp in Sources */, - FCCB1D76248E8389000A2F32 /* csdetect.cpp in Sources */, - FCCB1E9E248E8440000A2F32 /* uscanf_p.c in Sources */, - FCCB1D4E248E8389000A2F32 /* collationdatabuilder.cpp in Sources */, - FCCB1D51248E8389000A2F32 /* udat.cpp in Sources */, - FCCB1D7E248E8389000A2F32 /* uregion.cpp in Sources */, - FCCB1B22248E82FC000A2F32 /* serv.cpp in Sources */, - FCCB1B6D248E82FD000A2F32 /* uset.cpp in Sources */, - FCCB1E99248E8440000A2F32 /* ufile.c in Sources */, - FCCB1AE3248E82FC000A2F32 /* ucnv_u32.c in Sources */, - FCCB1DA9248E8389000A2F32 /* curramt.cpp in Sources */, - FCCB1B58248E82FD000A2F32 /* cstring.c in Sources */, - FCCB1D40248E8389000A2F32 /* dayperiodrules.cpp in Sources */, - FCCB1AC2248E82FC000A2F32 /* ustr_wcs.cpp in Sources */, - FCCB1AE7248E82FC000A2F32 /* unifunct.cpp in Sources */, - FCCB1AC5248E82FC000A2F32 /* ucasemap.cpp in Sources */, - FCCB1DA0248E8389000A2F32 /* persncal.cpp in Sources */, - FCCB1D6D248E8389000A2F32 /* tmunit.cpp in Sources */, - FCCB1DE3248E8389000A2F32 /* funcrepl.cpp in Sources */, - FCCB1B00248E82FC000A2F32 /* usetiter.cpp in Sources */, - FCCB1ABC248E82FC000A2F32 /* ucharstriebuilder.cpp in Sources */, - FCCB1D8D248E8389000A2F32 /* basictz.cpp in Sources */, - FCCB1D39248E8389000A2F32 /* zrule.cpp in Sources */, - FCCB1DAB248E8389000A2F32 /* unesctrn.cpp in Sources */, - FCCB1AF2248E82FC000A2F32 /* sharedobject.cpp in Sources */, - FCCB1B19248E82FC000A2F32 /* stringtriebuilder.cpp in Sources */, - FCCB1D70248E8389000A2F32 /* uspoof_build.cpp in Sources */, - FCCB1D8C248E8389000A2F32 /* collation.cpp in Sources */, - FCCB1D5A248E8389000A2F32 /* titletrn.cpp in Sources */, - FCCB1B0E248E82FC000A2F32 /* udataswp.c in Sources */, - FCCB1AFF248E82FC000A2F32 /* messagepattern.cpp in Sources */, - FCCB1D32248E8389000A2F32 /* ucal.cpp in Sources */, - FCCB1B38248E82FD000A2F32 /* normalizer2.cpp in Sources */, - FCCB1D75248E8389000A2F32 /* windtfmt.cpp in Sources */, - FCCB1B67248E82FD000A2F32 /* locbased.cpp in Sources */, - FCCB1B5B248E82FD000A2F32 /* charstr.cpp in Sources */, - FCCB1D8B248E8389000A2F32 /* collationsettings.cpp in Sources */, - FCCB1AE1248E82FC000A2F32 /* dictionarydata.cpp in Sources */, - FCCB1ABD248E82FC000A2F32 /* ucharstrie.cpp in Sources */, - FCCB1DC6248E8389000A2F32 /* digitgrouping.cpp in Sources */, - FCCB1ADA248E82FC000A2F32 /* ucnv_u7.c in Sources */, - FCCB1B71248E82FD000A2F32 /* locmap.c in Sources */, - FCCB1D94248E8389000A2F32 /* casetrn.cpp in Sources */, - FCCB1ADE248E82FC000A2F32 /* locutil.cpp in Sources */, - FCCB1DDC248E8389000A2F32 /* csrecog.cpp in Sources */, - FCCB1B63248E82FD000A2F32 /* utrie2_builder.cpp in Sources */, - FCCB1E98248E8440000A2F32 /* ucln_io.cpp in Sources */, - FCCB1DE1248E8389000A2F32 /* reldtfmt.cpp in Sources */, - FCCB1D7D248E8389000A2F32 /* simpletz.cpp in Sources */, - FCCB1B23248E82FC000A2F32 /* utf_impl.c in Sources */, - FCCB1DA1248E8389000A2F32 /* decContext.c in Sources */, - FCCB1D26248E8389000A2F32 /* digitaffix.cpp in Sources */, - FCCB1D74248E8389000A2F32 /* dtitvinf.cpp in Sources */, - FCCB1DCC248E8389000A2F32 /* olsontz.cpp in Sources */, - FCCB1D4C248E8389000A2F32 /* tzrule.cpp in Sources */, - FCCB1B13248E82FC000A2F32 /* filterednormalizer2.cpp in Sources */, - FCCB1B17248E82FC000A2F32 /* servslkf.cpp in Sources */, - FCCB1B41248E82FD000A2F32 /* loclikely.cpp in Sources */, - FCCB1B1B248E82FC000A2F32 /* rbbitblb.cpp in Sources */, - FCCB1B01248E82FC000A2F32 /* umath.c in Sources */, - FCCB1B69248E82FD000A2F32 /* udatamem.c in Sources */, - FCCB1B54248E82FD000A2F32 /* schriter.cpp in Sources */, - FCCB1D36248E8389000A2F32 /* zonemeta.cpp in Sources */, - FCCB1D5E248E8389000A2F32 /* tzgnames.cpp in Sources */, - FCCB1D9A248E8389000A2F32 /* digitlst.cpp in Sources */, - FCCB1B30248E82FC000A2F32 /* propsvec.c in Sources */, - FCCB1DB5248E8389000A2F32 /* scriptset.cpp in Sources */, - FCCB1D24248E8389000A2F32 /* measfmt.cpp in Sources */, - FCCB1DC8248E8389000A2F32 /* csrmbcs.cpp in Sources */, - FCCB1AE0248E82FC000A2F32 /* cwchar.c in Sources */, - FCCB1D3C248E8389000A2F32 /* numsys.cpp in Sources */, - FCCB1DD8248E8389000A2F32 /* ulocdata.c in Sources */, - FCCB1D4F248E8389000A2F32 /* upluralrules.cpp in Sources */, - FCCB1D7C248E8389000A2F32 /* datefmt.cpp in Sources */, - FCCB1D87248E8389000A2F32 /* collationruleparser.cpp in Sources */, - FCCB1D33248E8389000A2F32 /* rematch.cpp in Sources */, - FCCB1B40248E82FD000A2F32 /* listformatter.cpp in Sources */, - FCCB1D3A248E8389000A2F32 /* digitaffixesandpadding.cpp in Sources */, - FCCB1DD9248E8389000A2F32 /* fpositer.cpp in Sources */, - FCCB1D6A248E8389000A2F32 /* bocsu.cpp in Sources */, - FCCB1B59248E82FD000A2F32 /* bytestriebuilder.cpp in Sources */, - FCCB1DA3248E8389000A2F32 /* msgfmt.cpp in Sources */, - FCCB1D79248E8389000A2F32 /* strmatch.cpp in Sources */, - FCCB1DD1248E8389000A2F32 /* digitformatter.cpp in Sources */, - FCCB1DA6248E8389000A2F32 /* scientificnumberformatter.cpp in Sources */, - FCCB1D64248E8389000A2F32 /* valueformatter.cpp in Sources */, - FCCB1DCE248E8389000A2F32 /* uni2name.cpp in Sources */, - FCCB1DBB248E8389000A2F32 /* vtzone.cpp in Sources */, - FCCB1D50248E8389000A2F32 /* utrans.cpp in Sources */, - FCCB1DB1248E8389000A2F32 /* measunit.cpp in Sources */, - FCCB1B34248E82FD000A2F32 /* brkeng.cpp in Sources */, - FCCB1B46248E82FD000A2F32 /* ubidi.c in Sources */, - FCCB1DDB248E8389000A2F32 /* rbt_pars.cpp in Sources */, - FCCB1B08248E82FC000A2F32 /* rbbistbl.cpp in Sources */, - FCCB1D38248E8389000A2F32 /* ztrans.cpp in Sources */, - FCCB1AE9248E82FC000A2F32 /* usc_impl.c in Sources */, - FCCB1DB3248E8389000A2F32 /* affixpatternparser.cpp in Sources */, - FCCB1DB6248E8389000A2F32 /* smpdtfst.cpp in Sources */, - FCCB1D48248E8389000A2F32 /* selfmt.cpp in Sources */, - FCCB1DAA248E8389000A2F32 /* japancal.cpp in Sources */, - FCCB1D3D248E8389000A2F32 /* quant.cpp in Sources */, - FCCB1D95248E8389000A2F32 /* regeximp.cpp in Sources */, - FCCB1D2A248E8389000A2F32 /* uspoof_impl.cpp in Sources */, - FCCB1D8A248E8389000A2F32 /* uspoof_conf.cpp in Sources */, - FCCB1DC2248E8389000A2F32 /* winnmfmt.cpp in Sources */, - FCCB1ACB248E82FC000A2F32 /* unistr_titlecase_brkiter.cpp in Sources */, - FCCB1B39248E82FD000A2F32 /* unistr_case_locale.cpp in Sources */, - FCCB1D5C248E8389000A2F32 /* usearch.cpp in Sources */, - FCCB1ACF248E82FC000A2F32 /* servnotf.cpp in Sources */, - FCCB1ACE248E82FC000A2F32 /* unistr_cnv.cpp in Sources */, - FCCB1D7A248E8389000A2F32 /* tridpars.cpp in Sources */, - FCCB1D22248E8389000A2F32 /* smallintformatter.cpp in Sources */, - FCCB1B2D248E82FC000A2F32 /* uhash_us.cpp in Sources */, - FCCB1AD3248E82FC000A2F32 /* cstr.cpp in Sources */, - FCCB1D2B248E8389000A2F32 /* standardplural.cpp in Sources */, - FCCB1D78248E8389000A2F32 /* ufieldpositer.cpp in Sources */, - FCCB1E9F248E8440000A2F32 /* sprintf.c in Sources */, - FCCB1D68248E8389000A2F32 /* esctrn.cpp in Sources */, - FCCB1B36248E82FD000A2F32 /* rbbirb.cpp in Sources */, - FCCB1D59248E8389000A2F32 /* collationrootelements.cpp in Sources */, - FCCB1AFB248E82FC000A2F32 /* uvectr32.cpp in Sources */, - FCCB1D5B248E8389000A2F32 /* gender.cpp in Sources */, - FCCB1E9A248E8440000A2F32 /* sscanf.c in Sources */, - FCCB1B51248E82FD000A2F32 /* locresdata.cpp in Sources */, - FCCB1AE4248E82FC000A2F32 /* ucnv.c in Sources */, - FCCB1B14248E82FC000A2F32 /* ucnv_lmb.c in Sources */, - FCCB1D23248E8389000A2F32 /* tztrans.cpp in Sources */, - FCCB1DA2248E8389000A2F32 /* ucol.cpp in Sources */, - FCCB1DD3248E8389000A2F32 /* format.cpp in Sources */, - FCCB1B56248E82FD000A2F32 /* uinit.cpp in Sources */, - FCCB1B28248E82FC000A2F32 /* utypes.c in Sources */, - FCCB1D2C248E8389000A2F32 /* ethpccal.cpp in Sources */, - FCCB1AF9248E82FC000A2F32 /* cmemory.c in Sources */, - FCCB1B24248E82FC000A2F32 /* uarrsort.c in Sources */, - FCCB1AEA248E82FC000A2F32 /* ustrenum.cpp in Sources */, - FCCB1AD6248E82FC000A2F32 /* utrie2.cpp in Sources */, - FCCB1DC7248E8389000A2F32 /* cecal.cpp in Sources */, - FCCB1ACD248E82FC000A2F32 /* rbbiscan.cpp in Sources */, - FCCB1D82248E8389000A2F32 /* inputext.cpp in Sources */, - FCCB1B61248E82FD000A2F32 /* dtintrv.cpp in Sources */, - FCCB1B20248E82FC000A2F32 /* ucharstrieiterator.cpp in Sources */, - FCCB1DD0248E8389000A2F32 /* brktrans.cpp in Sources */, - FCCB1E9D248E8440000A2F32 /* locbund.cpp in Sources */, - FCCB1DC1248E8389000A2F32 /* regexst.cpp in Sources */, - FCCB1ABB248E82FC000A2F32 /* ucnvlat1.c in Sources */, - FCCB1D88248E8389000A2F32 /* buddhcal.cpp in Sources */, - FCCB1B1C248E82FC000A2F32 /* servrbf.cpp in Sources */, - FCCB1B11248E82FC000A2F32 /* ucnv_cnv.c in Sources */, - FCCB1B2C248E82FC000A2F32 /* ucnv_err.c in Sources */, - FCCB1D42248E8389000A2F32 /* pluralaffix.cpp in Sources */, - FCCB1B5F248E82FD000A2F32 /* unames.cpp in Sources */, - FCCB1D2F248E8389000A2F32 /* dtitvfmt.cpp in Sources */, - FCCB1B0B248E82FC000A2F32 /* uresdata.cpp in Sources */, - FCCB1D54248E8389000A2F32 /* ucoleitr.cpp in Sources */, - FCCB1DC0248E8389000A2F32 /* rbt_rule.cpp in Sources */, - FCCB1B4F248E82FD000A2F32 /* ubrk.cpp in Sources */, - FCCB1AD5248E82FC000A2F32 /* ucnvisci.c in Sources */, - FCCB1B3E248E82FD000A2F32 /* uniset_props.cpp in Sources */, - FCCB1B55248E82FD000A2F32 /* uset_props.cpp in Sources */, - FCCB1D4B248E8389000A2F32 /* tznames.cpp in Sources */, - FCCB1D7B248E8389000A2F32 /* uregexc.cpp in Sources */, - FCCB1DA7248E8389000A2F32 /* ucol_res.cpp in Sources */, - FCCB1AF8248E82FC000A2F32 /* dictbe.cpp in Sources */, - FCCB1D28248E8389000A2F32 /* repattrn.cpp in Sources */, - FCCB1DBE248E8389000A2F32 /* measure.cpp in Sources */, - FCCB1B0F248E82FC000A2F32 /* bmpset.cpp in Sources */, - FCCB1D3F248E8389000A2F32 /* numfmt.cpp in Sources */, - FCCB1EA5248E845E000A2F32 /* stubdata.c in Sources */, - FCCB1B64248E82FD000A2F32 /* ucnvhz.c in Sources */, - FCCB1DD7248E8389000A2F32 /* dtfmtsym.cpp in Sources */, - FCCB1ABE248E82FC000A2F32 /* ustrcase_locale.cpp in Sources */, - FCCB1D5D248E8389000A2F32 /* udateintervalformat.cpp in Sources */, - FCCB1DBC248E8389000A2F32 /* tmutfmt.cpp in Sources */, - FCCB1B6E248E82FD000A2F32 /* uloc_keytype.cpp in Sources */, - FCCB1B03248E82FC000A2F32 /* unifiedcache.cpp in Sources */, - FCCB1AF3248E82FC000A2F32 /* ucat.c in Sources */, - FCCB1DA8248E8389000A2F32 /* uspoof.cpp in Sources */, - FCCB1AD8248E82FC000A2F32 /* uiter.cpp in Sources */, - FCCB1D81248E8389000A2F32 /* coll.cpp in Sources */, - FCCB1B2B248E82FC000A2F32 /* ubiditransform.c in Sources */, - FCCB1D29248E8389000A2F32 /* nortrans.cpp in Sources */, - FCCB1B1D248E82FC000A2F32 /* unistr_case.cpp in Sources */, - FCCB1AF1248E82FC000A2F32 /* ucase.cpp in Sources */, - FCCB1D58248E8389000A2F32 /* nultrans.cpp in Sources */, - FCCB1B21248E82FC000A2F32 /* uresbund.cpp in Sources */, - FCCB1B06248E82FC000A2F32 /* uchar.c in Sources */, - FCCB1B35248E82FD000A2F32 /* icudataver.c in Sources */, - FCCB1B3D248E82FD000A2F32 /* servls.cpp in Sources */, - FCCB1B25248E82FC000A2F32 /* rbbi.cpp in Sources */, - FCCB1DB8248E8389000A2F32 /* timezone.cpp in Sources */, - FCCB1D9D248E8389000A2F32 /* gregoimp.cpp in Sources */, - FCCB1B09248E82FC000A2F32 /* servlkf.cpp in Sources */, - FCCB1DBA248E8389000A2F32 /* collationdata.cpp in Sources */, - FCCB1AE5248E82FC000A2F32 /* ucol_swp.cpp in Sources */, - FCCB1D9B248E8389000A2F32 /* dtptngen.cpp in Sources */, - FCCB1DAE248E8389000A2F32 /* collationcompare.cpp in Sources */, - FCCB1DCD248E8389000A2F32 /* coleitr.cpp in Sources */, - FCCB1D3B248E8389000A2F32 /* nfrule.cpp in Sources */, - FCCB1B6F248E82FD000A2F32 /* resbund.cpp in Sources */, - FCCB1DC9248E8389000A2F32 /* collationweights.cpp in Sources */, - FCCB1ADD248E82FC000A2F32 /* ustr_cnv.cpp in Sources */, - FCCB1B5E248E82FD000A2F32 /* ucnv_bld.cpp in Sources */, - FCCB1B1E248E82FC000A2F32 /* uscript.c in Sources */, - FCCB1DE0248E8389000A2F32 /* gregocal.cpp in Sources */, - FCCB1D56248E8389000A2F32 /* csr2022.cpp in Sources */, - FCCB1DDF248E8389000A2F32 /* rbt.cpp in Sources */, - FCCB1B37248E82FD000A2F32 /* ustrtrns.cpp in Sources */, - FCCB1DCB248E8389000A2F32 /* utmscale.c in Sources */, - FCCB1ADC248E82FC000A2F32 /* putil.cpp in Sources */, - FCCB1D65248E8389000A2F32 /* collationfcd.cpp in Sources */, - FCCB1D53248E8389000A2F32 /* uregex.cpp in Sources */, - FCCB1D47248E8389000A2F32 /* currpinf.cpp in Sources */, - FCCB1B3C248E82FD000A2F32 /* ucnv_io.cpp in Sources */, - FCCB1B4C248E82FD000A2F32 /* resbund_cnv.cpp in Sources */, - FCCB1D9C248E8389000A2F32 /* alphaindex.cpp in Sources */, - FCCB1DC4248E8389000A2F32 /* decNumber.c in Sources */, - FCCB1D2E248E8389000A2F32 /* islamcal.cpp in Sources */, - FCCB1B62248E82FD000A2F32 /* ulistformatter.cpp in Sources */, - FCCB1B12248E82FC000A2F32 /* utext.cpp in Sources */, - FCCB1AEC248E82FC000A2F32 /* errorcode.cpp in Sources */, - FCCB1AC9248E82FC000A2F32 /* ustr_titlecase_brkiter.cpp in Sources */, - FCCB1B5C248E82FD000A2F32 /* locavailable.cpp in Sources */, - FCCB1B0D248E82FC000A2F32 /* ubidi_props.c in Sources */, - FCCB1B18248E82FC000A2F32 /* ustack.cpp in Sources */, - FCCB1E96248E8440000A2F32 /* ustream.cpp in Sources */, - FCCB1D80248E8389000A2F32 /* dtrule.cpp in Sources */, - FCCB1B6B248E82FD000A2F32 /* icuplug.cpp in Sources */, - FCCB1DDA248E8389000A2F32 /* vzone.cpp in Sources */, - FCCB1D35248E8389000A2F32 /* csrutf8.cpp in Sources */, - FCCB1DB4248E8389000A2F32 /* indiancal.cpp in Sources */, - FCCB1DAD248E8389000A2F32 /* wintzimpl.cpp in Sources */, - FCCB1B05248E82FC000A2F32 /* ucnv_u8.c in Sources */, - FCCB1AD7248E82FC000A2F32 /* udata.cpp in Sources */, - FCCB1D41248E8389000A2F32 /* regextxt.cpp in Sources */, - FCCB1D34248E8389000A2F32 /* strrepl.cpp in Sources */, - FCCB1D86248E8389000A2F32 /* fmtable_cnv.cpp in Sources */, - FCCB1DBD248E8389000A2F32 /* plurrule.cpp in Sources */, - FCCB1DB9248E8389000A2F32 /* tznames_impl.cpp in Sources */, - FCCB1AF6248E82FC000A2F32 /* uidna.cpp in Sources */, - FCCB1D72248E8389000A2F32 /* astro.cpp in Sources */, - FCCB1EA0248E8440000A2F32 /* uscanf.c in Sources */, - FCCB1B1F248E82FC000A2F32 /* unormcmp.cpp in Sources */, - FCCB1AE8248E82FC000A2F32 /* ucln_cmn.cpp in Sources */, - FCCB1B50248E82FD000A2F32 /* rbbisetb.cpp in Sources */, - FCCB1B3A248E82FD000A2F32 /* rbbinode.cpp in Sources */, - FCCB1D7F248E8389000A2F32 /* choicfmt.cpp in Sources */, - FCCB1B53248E82FD000A2F32 /* punycode.cpp in Sources */, - FCCB1DE4248E8389000A2F32 /* dangical.cpp in Sources */, - FCCB1D89248E8389000A2F32 /* collationfastlatinbuilder.cpp in Sources */, - FCCB1B47248E82FD000A2F32 /* ucnvscsu.c in Sources */, - FCCB1B66248E82FD000A2F32 /* ustrfmt.c in Sources */, - FCCB1B32248E82FD000A2F32 /* bytestrieiterator.cpp in Sources */, - FCCB1B4A248E82FD000A2F32 /* uniset_closure.cpp in Sources */, - FCCB1D46248E8389000A2F32 /* fmtable.cpp in Sources */, - FCCB1D77248E8389000A2F32 /* unumsys.cpp in Sources */, - FCCB1DA5248E8389000A2F32 /* collationbuilder.cpp in Sources */, - FCCB1D30248E8389000A2F32 /* hebrwcal.cpp in Sources */, - FCCB1DA4248E8389000A2F32 /* rbt_data.cpp in Sources */, - FCCB1AEF248E82FC000A2F32 /* ubidiwrt.c in Sources */, - FCCB1AF5248E82FC000A2F32 /* ustrcase.cpp in Sources */, - FCCB1AFA248E82FC000A2F32 /* pluralmap.cpp in Sources */, - FCCB1D8E248E8389000A2F32 /* collationdatawriter.cpp in Sources */, - FCCB1D93248E8389000A2F32 /* transreg.cpp in Sources */, - FCCB1D5F248E8389000A2F32 /* anytrans.cpp in Sources */, - FCCB1D60248E8389000A2F32 /* decimalformatpattern.cpp in Sources */, - FCCB1ADF248E82FC000A2F32 /* ubidiln.c in Sources */, - FCCB1AC3248E82FC000A2F32 /* unifilt.cpp in Sources */, - FCCB1D8F248E8389000A2F32 /* chnsecal.cpp in Sources */, - FCCB1AC7248E82FC000A2F32 /* ucnvmbcs.cpp in Sources */, - FCCB1B68248E82FD000A2F32 /* caniter.cpp in Sources */, - FCCB1D71248E8389000A2F32 /* collationroot.cpp in Sources */, - FCCB1AE2248E82FC000A2F32 /* ucnvsel.cpp in Sources */, - FCCB1B04248E82FC000A2F32 /* uhash.c in Sources */, - FCCB1DE2248E8389000A2F32 /* collationdatareader.cpp in Sources */, - FCCB1DAF248E8389000A2F32 /* uitercollationiterator.cpp in Sources */, - FCCB1D67248E8389000A2F32 /* sortkey.cpp in Sources */, - FCCB1B44248E82FD000A2F32 /* normalizer2impl.cpp in Sources */, - FCCB1B27248E82FC000A2F32 /* parsepos.cpp in Sources */, - FCCB1B2E248E82FC000A2F32 /* uinvchar.c in Sources */, - FCCB1D4A248E8389000A2F32 /* toupptrn.cpp in Sources */, - FCCB1D31248E8389000A2F32 /* coptccal.cpp in Sources */, - FCCB1DC3248E8389000A2F32 /* reldatefmt.cpp in Sources */, - FCCB1AFC248E82FC000A2F32 /* uts46.cpp in Sources */, - FCCB1D21248E8389000A2F32 /* compactdecimalformat.cpp in Sources */, - FCCB1B43248E82FD000A2F32 /* resource.cpp in Sources */, - FCCB1B42248E82FD000A2F32 /* normlzr.cpp in Sources */, - FCCB1B4E248E82FD000A2F32 /* brkiter.cpp in Sources */, - FCCB1D55248E8389000A2F32 /* decimfmtimpl.cpp in Sources */, - FCCB1B0C248E82FC000A2F32 /* propname.cpp in Sources */, - FCCB1D4D248E8389000A2F32 /* ucol_sit.cpp in Sources */, - FCCB1AC6248E82FC000A2F32 /* chariter.cpp in Sources */, - FCCB1B2A248E82FC000A2F32 /* ruleiter.cpp in Sources */, - FCCB1AFE248E82FC000A2F32 /* ures_cnv.c in Sources */, - FCCB1D99248E8389000A2F32 /* taiwncal.cpp in Sources */, - FCCB1D6C248E8389000A2F32 /* dcfmtsym.cpp in Sources */, - FCCB1AC8248E82FC000A2F32 /* ulist.c in Sources */, - FCCB1D49248E8389000A2F32 /* remtrans.cpp in Sources */, - FCCB1B49248E82FD000A2F32 /* ustring.cpp in Sources */, - FCCB1D37248E8389000A2F32 /* unum.cpp in Sources */, - FCCB1D66248E8389000A2F32 /* decfmtst.cpp in Sources */, - FCCB1AEE248E82FC000A2F32 /* unorm.cpp in Sources */, - FCCB1B29248E82FC000A2F32 /* loadednormalizer2impl.cpp in Sources */, - FCCB1B07248E82FC000A2F32 /* bytestream.cpp in Sources */, - FCCB1DB2248E8389000A2F32 /* umsg.cpp in Sources */, - FCCB1D63248E8389000A2F32 /* tzfmt.cpp in Sources */, - FCCB1DCF248E8389000A2F32 /* sharedbreakiterator.cpp in Sources */, - FCCB1B0A248E82FC000A2F32 /* uobject.cpp in Sources */, - FCCB1B57248E82FD000A2F32 /* stringpiece.cpp in Sources */, - FCCB1AD4248E82FC000A2F32 /* uchriter.cpp in Sources */, - FCCB1DDE248E8389000A2F32 /* currfmt.cpp in Sources */, - FCCB1DCA248E8389000A2F32 /* tolowtrn.cpp in Sources */, - FCCB1AD2248E82FC000A2F32 /* simpleformatter.cpp in Sources */, - FCCB1B4B248E82FD000A2F32 /* util_props.cpp in Sources */, - FCCB1D9F248E8389000A2F32 /* translit.cpp in Sources */, - FCCB1D57248E8389000A2F32 /* rbtz.cpp in Sources */, - FCCB1B15248E82FC000A2F32 /* umapfile.c in Sources */, - FCCB1B5A248E82FD000A2F32 /* ucasemap_titlecase_brkiter.cpp in Sources */, - FCCB1DD6248E8389000A2F32 /* tmutamt.cpp in Sources */, - FCCB1B70248E82FD000A2F32 /* appendable.cpp in Sources */, - FCCB1DC5248E8389000A2F32 /* search.cpp in Sources */, - FCCB1AC0248E82FC000A2F32 /* ucnv_set.c in Sources */, - FCCB1DAC248E8389000A2F32 /* collationiterator.cpp in Sources */, - FCCB1ACA248E82FC000A2F32 /* uvector.cpp in Sources */, - FCCB1D52248E8389000A2F32 /* rbt_set.cpp in Sources */, - FCCB1B02248E82FC000A2F32 /* uloc_tag.c in Sources */, - FCCB1B48248E82FD000A2F32 /* ucnv2022.cpp in Sources */, - FCCB1AD9248E82FC000A2F32 /* locdispnames.cpp in Sources */, - FCCB1D45248E8389000A2F32 /* stsearch.cpp in Sources */, - FCCB1ACC248E82FC000A2F32 /* ucmndata.c in Sources */, - FCCB1D9E248E8389000A2F32 /* currunit.cpp in Sources */, - FCCB1AEB248E82FC000A2F32 /* rbbidata.cpp in Sources */, - FCCB1E9B248E8440000A2F32 /* uprintf.cpp in Sources */, - FCCB1D91248E8389000A2F32 /* name2uni.cpp in Sources */, - FCCB1DDD248E8389000A2F32 /* rbnf.cpp in Sources */, - FCCB1DB0248E8389000A2F32 /* region.cpp in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin XCBuildConfiguration section */ - 173241871BBECF8400E67992 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 10.3; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - }; - name = Debug; - }; - 173241881BBECF8400E67992 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 10.3; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = iphoneos; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - 1732418A1BBECF8400E67992 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = NO; - ENABLE_BITCODE = YES; - EXCLUDED_RECURSIVE_SEARCH_PATH_SUBDIRECTORIES = "*.nib *.lproj *.framework *.gch *.xcode* *.xcassets (*) .DS_Store CVS .svn .git .hg *.pbproj *.pbxproj"; - GCC_PREPROCESSOR_DEFINITIONS = ( - MU_STATIC_IMPLEMENTATION, - U_I18N_IMPLEMENTATION, - U_COMMON_IMPLEMENTATION, - U_IO_IMPLEMENTATION, - ); - HEADER_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/../../../../../Common/3dParty/icu/icu/source/common/**", - "$(PROJECT_DIR)/../../../../../Common/3dParty/icu/icu/source/i18n", - "$(PROJECT_DIR)/../../../../../Common/3dParty/icu/icu/source/io", - "$(PROJECT_DIR)/../../../../../Common/3dParty/icu/icu/source/layout", - "$(PROJECT_DIR)/../../../../../Common/3dParty/icu/icu/source/layoutex", - "$(PROJECT_DIR)", - ); - IPHONEOS_DEPLOYMENT_TARGET = 8.2; - OTHER_LDFLAGS = "-ObjC"; - PRIVATE_HEADERS_FOLDER_PATH = /usr/local/include; - PRODUCT_NAME = "$(TARGET_NAME)"; - SKIP_INSTALL = YES; - }; - name = Debug; - }; - 1732418B1BBECF8400E67992 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = NO; - ENABLE_BITCODE = YES; - EXCLUDED_RECURSIVE_SEARCH_PATH_SUBDIRECTORIES = "*.nib *.lproj *.framework *.gch *.xcode* *.xcassets (*) .DS_Store CVS .svn .git .hg *.pbproj *.pbxproj"; - GCC_PREPROCESSOR_DEFINITIONS = ( - MU_STATIC_IMPLEMENTATION, - U_I18N_IMPLEMENTATION, - U_COMMON_IMPLEMENTATION, - U_IO_IMPLEMENTATION, - ); - HEADER_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/../../../../../Common/3dParty/icu/icu/source/common/**", - "$(PROJECT_DIR)/../../../../../Common/3dParty/icu/icu/source/i18n", - "$(PROJECT_DIR)/../../../../../Common/3dParty/icu/icu/source/io", - "$(PROJECT_DIR)/../../../../../Common/3dParty/icu/icu/source/layout", - "$(PROJECT_DIR)/../../../../../Common/3dParty/icu/icu/source/layoutex", - "$(PROJECT_DIR)", - ); - IPHONEOS_DEPLOYMENT_TARGET = 8.2; - OTHER_LDFLAGS = "-ObjC"; - PRIVATE_HEADERS_FOLDER_PATH = /usr/local/include; - PRODUCT_NAME = "$(TARGET_NAME)"; - SKIP_INSTALL = YES; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 1732417B1BBECF8400E67992 /* Build configuration list for PBXProject "icu" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 173241871BBECF8400E67992 /* Debug */, - 173241881BBECF8400E67992 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 173241891BBECF8400E67992 /* Build configuration list for PBXNativeTarget "icu" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 1732418A1BBECF8400E67992 /* Debug */, - 1732418B1BBECF8400E67992 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 173241781BBECF8400E67992 /* Project object */; -} diff --git a/X2tConverter/build/Mac/X2tConverter/icu/icu.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/X2tConverter/build/Mac/X2tConverter/icu/icu.xcodeproj/project.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index cbae78f4cf4..00000000000 --- a/X2tConverter/build/Mac/X2tConverter/icu/icu.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/X2tConverter/build/Mac/X2tConverter/icu/icu.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/X2tConverter/build/Mac/X2tConverter/icu/icu.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist deleted file mode 100644 index 18d981003d6..00000000000 --- a/X2tConverter/build/Mac/X2tConverter/icu/icu.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +++ /dev/null @@ -1,8 +0,0 @@ - - - - - IDEDidComputeMac32BitWarning - - - diff --git a/X2tConverter/build/Qt/X2tConverter.pri b/X2tConverter/build/Qt/X2tConverter.pri old mode 100755 new mode 100644 index 9e15189a795..685961ee4a4 --- a/X2tConverter/build/Qt/X2tConverter.pri +++ b/X2tConverter/build/Qt/X2tConverter.pri @@ -33,7 +33,6 @@ DEFINES += UNICODE \ DEFINES += PDFFILE_USE_DYNAMIC_LIBRARY DEFINES += XPS_USE_DYNAMIC_LIBRARY DEFINES += DJVU_USE_DYNAMIC_LIBRARY -DEFINES += HTMLRENDERER_USE_DYNAMIC_LIBRARY DEFINES += HTMLFILE_USE_DYNAMIC_LIBRARY DEFINES += UNICODECONVERTER_USE_DYNAMIC_LIBRARY DEFINES += FILE_FORMAT_CHECKER_WITH_MACRO @@ -62,13 +61,44 @@ DEPENDPATH += $$PWD/../../../OOXML/Binary/Document ############################################################################################################## -SOURCES += ../../src/cextracttools.cpp \ - ../../../Common/OfficeFileFormatChecker2.cpp \ - ../../src/ASCConverters.cpp -HEADERS += ../../src/cextracttools.h \ - ../../../Common/OfficeFileFormatChecker.h \ - ../../src/ASCConverters.h - +SOURCES += \ + ../../../Common/OfficeFileFormatChecker2.cpp \ + ../../src/cextracttools.cpp \ + ../../src/ASCConverters.cpp + +HEADERS += \ + ../../../Common/OfficeFileFormatChecker.h \ + ../../src/cextracttools.h \ + ../../src/ASCConverters.h + +HEADERS += \ + ../../src/lib/common.h \ + \ + ../../src/lib/crypt.h \ + \ + ../../src/lib/docx.h \ + ../../src/lib/pptx.h \ + ../../src/lib/xlsx.h \ + \ + ../../src/lib/doc.h \ + ../../src/lib/rtf.h \ + ../../src/lib/txt.h \ + \ + ../../src/lib/ppt.h \ + \ + ../../src/lib/xls.h \ + ../../src/lib/csv.h \ + \ + ../../src/lib/html.h \ + \ + ../../src/lib/odf.h \ + \ + ../../src/lib/pdf_image.h \ + ../../src/lib/pdf_oform.h \ + \ + ../../src/lib/iwork.h \ + \ + ../../src/lib/hwp.h #vbaformat LIBS += -L$$CORE_BUILDS_LIBRARIES_PATH -lVbaFormatLib @@ -100,8 +130,7 @@ LIBS += -L$$CORE_BUILDS_LIBRARIES_PATH -lCryptoPPLib #All dynamic libs -ADD_DEPENDENCY(graphics, kernel, UnicodeConverter, kernel_network, Fb2File, PdfFile, HtmlFile2, EpubFile, XpsFile, DjVuFile, HtmlRenderer, doctrenderer, DocxRenderer) - +ADD_DEPENDENCY(graphics, kernel, UnicodeConverter, kernel_network, Fb2File, PdfFile, HtmlFile2, EpubFile, XpsFile, DjVuFile, doctrenderer, DocxRenderer, IWorkFile, HWPFile) ##################################################### # внешнее подключение сторонних библиотек diff --git a/X2tConverter/build/Qt/X2tConverter.pro b/X2tConverter/build/Qt/X2tConverter.pro index 7d60f226a99..28349a3c889 100644 --- a/X2tConverter/build/Qt/X2tConverter.pro +++ b/X2tConverter/build/Qt/X2tConverter.pro @@ -13,24 +13,36 @@ ios:CONFIG += build_x2t_as_library android:CONFIG += build_x2t_as_library build_x2t_as_library { - TEMPLATE = lib - CONFIG -= console + TEMPLATE = lib + CONFIG -= console - DEFINES += BUILD_X2T_AS_LIBRARY_DYLIB + DEFINES += BUILD_X2T_AS_LIBRARY_DYLIB - CONFIG += shared - CONFIG += plugin + CONFIG += shared + CONFIG += plugin - !core_debug:shared:QMAKE_LFLAGS += -exported_symbols_list $$PWD/../../src/dylib/export + !core_debug:shared:QMAKE_LFLAGS += -exported_symbols_list $$PWD/../../src/dylib/export + + build_strip_debug { + QMAKE_LFLAGS += -Wl,--strip-debug + } } include(X2tConverter.pri) !build_x2t_as_library { - SOURCES += ../../src/main.cpp + SOURCES += ../../src/main.cpp + + DESTDIR = $$CORE_BUILDS_BINARY_PATH - DESTDIR = $$CORE_BUILDS_BINARY_PATH + core_windows { + !build_xp { + CONFIG -= embed_manifest_exe + QMAKE_MANIFEST = $$PWD/x2t.exe.manifest + OTHER_FILES += $$PWD/x2t.exe.manifest + } + } } else { - HEADERS += ../../src/dylib/x2t.h - SOURCES += ../../src/dylib/x2t.cpp + HEADERS += ../../src/dylib/x2t.h + SOURCES += ../../src/dylib/x2t.cpp } diff --git a/X2tConverter/build/Qt/test/ios/DocumentConverter/DocumentConverter.xcodeproj/post.sh b/X2tConverter/build/Qt/test/ios/DocumentConverter/DocumentConverter.xcodeproj/post.sh index af4ded54807..bce8a4e75d3 100644 --- a/X2tConverter/build/Qt/test/ios/DocumentConverter/DocumentConverter.xcodeproj/post.sh +++ b/X2tConverter/build/Qt/test/ios/DocumentConverter/DocumentConverter.xcodeproj/post.sh @@ -39,12 +39,6 @@ libHtmlFile.dylib \ @executable_path/libHtmlFile.dylib \ "${dst}"/${TARGET_NAME}.app/${TARGET_NAME} -install_name_tool \ --change \ -libHtmlRenderer.dylib \ -@executable_path/libHtmlRenderer.dylib \ -"${dst}"/${TARGET_NAME}.app/${TARGET_NAME} - install_name_tool \ -change \ libPdfReader.dylib \ @@ -114,25 +108,6 @@ libgraphics.dylib \ @executable_path/libgraphics.dylib \ "${dst}"/${TARGET_NAME}.app/libdoctrenderer.dylib -# htmlrenderer -install_name_tool \ --change \ -libkernel.dylib \ -@executable_path/libkernel.dylib \ -"${dst}"/${TARGET_NAME}.app/libHtmlRenderer.dylib - -install_name_tool \ --change \ -libUnicodeConverter.dylib \ -@executable_path/libUnicodeConverter.dylib \ -"${dst}"/${TARGET_NAME}.app/libHtmlRenderer.dylib - -install_name_tool \ --change \ -libgraphics.dylib \ -@executable_path/libgraphics.dylib \ -"${dst}"/${TARGET_NAME}.app/libHtmlRenderer.dylib - # pdfwriter install_name_tool \ -change \ @@ -221,12 +196,6 @@ libgraphics.dylib \ @executable_path/libgraphics.dylib \ "${dst}"/${TARGET_NAME}.app/libPdfReader.dylib -install_name_tool \ --change \ -libHtmlRenderer.dylib \ -@executable_path/libHtmlRenderer.dylib \ -"${dst}"/${TARGET_NAME}.app/libPdfReader.dylib - # x2t install_name_tool \ -change \ @@ -264,12 +233,6 @@ libHtmlFile.dylib \ @executable_path/libHtmlFile.dylib \ "${dst}"/${TARGET_NAME}.app/libx2t.dylib -install_name_tool \ --change \ -libHtmlRenderer.dylib \ -@executable_path/libHtmlRenderer.dylib \ -"${dst}"/${TARGET_NAME}.app/libx2t.dylib - install_name_tool \ -change \ libPdfReader.dylib \ diff --git a/X2tConverter/build/Qt/x2t.exe.manifest b/X2tConverter/build/Qt/x2t.exe.manifest new file mode 100644 index 00000000000..74755bff0ec --- /dev/null +++ b/X2tConverter/build/Qt/x2t.exe.manifest @@ -0,0 +1,14 @@ + + + +x2t + + + + + + + + + + diff --git a/X2tConverter/src/ASCConverters.cpp b/X2tConverter/src/ASCConverters.cpp index 8334ea94bd6..6b35e25cb8f 100644 --- a/X2tConverter/src/ASCConverters.cpp +++ b/X2tConverter/src/ASCConverters.cpp @@ -29,3406 +29,40 @@ * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode * */ +#include "lib/crypt.h" -#include "ASCConverters.h" -#include "cextracttools.h" +#include "lib/docx.h" +#include "lib/xlsx.h" +#include "lib/pptx.h" -#include "../../Common/3dParty/pole/pole.h" -#include "../../OfficeUtils/src/OfficeUtils.h" +#include "lib/doc.h" -#include "../../OOXML/Binary/Document/DocWrapper/DocxSerializer.h" -#include "../../OOXML/Binary/Document/DocWrapper/XlsxSerializer.h" +#include "lib/rtf.h" +#include "lib/txt.h" -#include "../../OOXML/PPTXFormat/DrawingConverter/ASCOfficePPTXFile.h" -#include "../../OOXML/XlsbFormat/Xlsb.h" +#include "lib/ppt.h" -#include "../../MsBinaryFile/DocFile/Main/DocFormatLib.h" -#include "../../MsBinaryFile/PptFile/Main/PPTFormatLib.h" -#include "../../OdfFile/Reader/Converter/ConvertOO2OOX.h" -#include "../../OdfFile/Writer/Converter/Oox2OdfConverter.h" -#include "../../RtfFile/Format/ConvertationManager.h" -#include "../../TxtFile/Source/TxtXmlFile.h" +#include "lib/xls.h" +#include "lib/csv.h" -#include "../../DesktopEditor/doctrenderer/docbuilder.h" -#include "../../DesktopEditor/doctrenderer/doctrenderer.h" -#include "../../DesktopEditor/graphics/MetafileToGraphicsRenderer.h" -#include "../../DesktopEditor/graphics/pro/Fonts.h" - -#include "../../DjVuFile/DjVu.h" -#include "../../DocxRenderer/DocxRenderer.h" -#include "../../EpubFile/CEpubFile.h" -#include "../../Fb2File/Fb2File.h" -#include "../../HtmlFile2/htmlfile2.h" -#include "../../HtmlRenderer/include/HTMLRenderer3.h" -#include "../../PdfFile/PdfFile.h" -#include "../../XpsFile/XpsFile.h" - -#include "../../MsBinaryFile/Common/Vba/VbaReader.h" -#include "../../MsBinaryFile/XlsFile/Converter/ConvertXls2Xlsx.h" -#include "../../OfficeCryptReader/source/ECMACryptFile.h" - -#include "../../OOXML/Binary/Sheets/Common/Common.h" -#include "../../OOXML/Binary/Sheets/Reader/CSVReader.h" -#include "../../OOXML/Binary/Sheets/Reader/XMLReader/XMLReader.h" -#include "../../OOXML/Binary/Sheets/Writer/CSVWriter.h" - -#include "../../DesktopEditor/common/Directory.h" -#include "../../DesktopEditor/common/Path.h" - -#include -#include - -namespace NExtractTools -{ - void initApplicationFonts(NSFonts::IApplicationFonts *pApplicationFonts, InputParams ¶ms) - { - std::wstring sFontPath = params.getFontPath(); - - if (sFontPath.empty()) - pApplicationFonts->Initialize(); - else - pApplicationFonts->InitializeFromFolder(sFontPath); - } - std::wstring getExtentionByRasterFormat(int format) - { - std::wstring sExt; - switch (format) - { - case 1: - sExt = L".bmp"; - break; - case 2: - sExt = L".gif"; - break; - case 3: - sExt = L".jpg"; - break; - default: - sExt = L".png"; - break; - } - return sExt; - } - bool create_if_empty(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &signature) - { - bool res = false; - NSFile::CFileBinary file; - if (file.OpenFile(sFrom)) - { - long file_size = file.GetFileSize(); - file.CloseFile(); - - if (file_size == 0) - { - file.CreateFileW(sTo); - - if (false == signature.empty()) - { - file.WriteStringUTF8(signature); - } - file.CloseFile(); - - res = true; - } - } - return res; - } - - _UINT32 CopyOOXOrigin(const std::wstring &sToDir, const std::wstring &sOOXDir, const std::wstring &sToFile, const std::wstring &sOOXFile) - { - _UINT32 nRes = 0; - // save Editor.xlsx for pivot - std::wstring sEditorOOX = sToDir + FILE_SEPARATOR_STR + sToFile; - if (sOOXFile.empty()) - { - nRes = dir2zip(sOOXDir, sEditorOOX); - } - else - { - nRes = NSFile::CFileBinary::Copy(sOOXFile, sEditorOOX) ? 0 : AVS_FILEUTILS_ERROR_CONVERT; - } - return nRes; - } - _UINT32 addContentType(const std::wstring &sDir, const std::wstring &sCT) - { - _UINT32 nRes = 0; - std::wstring sContentTypesPath = sDir + FILE_SEPARATOR_STR + _T("[Content_Types].xml"); - if (NSFile::CFileBinary::Exists(sContentTypesPath)) - { - std::wstring sData; - if (NSFile::CFileBinary::ReadAllTextUtf8(sContentTypesPath, sData)) - { - sData = string_replaceAll(sData, L"", sCT + L""); - if (false == NSFile::CFileBinary::SaveToFile(sContentTypesPath, sData, true)) - nRes = AVS_FILEUTILS_ERROR_CONVERT; - } - } - return nRes; - } - _UINT32 replaceContentType(const std::wstring &sDir, const std::wstring &sCTFrom, const std::wstring &sCTTo) - { - _UINT32 nRes = 0; - std::wstring sContentTypesPath = sDir + FILE_SEPARATOR_STR + _T("[Content_Types].xml"); - if (NSFile::CFileBinary::Exists(sContentTypesPath)) - { - std::wstring sData; - if (NSFile::CFileBinary::ReadAllTextUtf8(sContentTypesPath, sData)) - { - sData = string_replaceAll(sData, sCTFrom, sCTTo); - if (false == NSFile::CFileBinary::SaveToFile(sContentTypesPath, sData, true)) - nRes = AVS_FILEUTILS_ERROR_CONVERT; - } - } - return nRes; - } - _UINT32 processEncryptionError(_UINT32 hRes, const std::wstring &sFrom, InputParams ¶ms) - { - if (AVS_ERROR_DRM == hRes) - { - if (!params.getDontSaveAdditional()) - { - copyOrigin(sFrom, *params.m_sFileTo); - } - return AVS_FILEUTILS_ERROR_CONVERT_DRM; - } - else if (AVS_ERROR_PASSWORD == hRes) - { - return AVS_FILEUTILS_ERROR_CONVERT_PASSWORD; - } - return hRes; - } - _UINT32 package2ooxml(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - std::wstring sResultOoxmlDir = sTemp + FILE_SEPARATOR_STR + _T("ooxml_unpacked"); - - NSDirectory::CreateDirectory(sResultOoxmlDir); - - _UINT32 nRes = package2ooxml_dir(sFrom, sResultOoxmlDir, sTemp, params); - - if (SUCCEEDED_X2T(nRes)) - { - nRes = dir2zipMscrypt(sResultOoxmlDir, sTo, sTemp, params); - } - - return nRes; - } - _UINT32 package2bin_t(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - std::wstring sResultBin_tDir = sTemp + FILE_SEPARATOR_STR + _T("bin_t_unpacked"); - std::wstring sResultBin_tFileEditor = sResultBin_tDir + FILE_SEPARATOR_STR + _T("Editor.bin"); - - NSDirectory::CreateDirectory(sResultBin_tDir); - - _UINT32 nRes = package2bin(sFrom, sResultBin_tFileEditor, sTemp, params); - - if (SUCCEEDED_X2T(nRes)) - { - COfficeUtils oCOfficeUtils(NULL); - nRes = (S_OK == oCOfficeUtils.CompressFileOrDirectory(sResultBin_tDir, sTo)) ? nRes : AVS_FILEUTILS_ERROR_CONVERT; - } - - return nRes; - } - _UINT32 package2bin(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - std::wstring sResultOoxmlDir = sTemp + FILE_SEPARATOR_STR + _T("ooxml_unpacked"); - - NSDirectory::CreateDirectory(sResultOoxmlDir); - - _UINT32 nRes = package2ooxml_dir(sFrom, sResultOoxmlDir, sTemp, params); - - if (SUCCEEDED_X2T(nRes)) - { - nRes = AVS_FILEUTILS_ERROR_CONVERT; - - COfficeFileFormatChecker OfficeFileFormatChecker; - - if (OfficeFileFormatChecker.isOOXFormatFile(sResultOoxmlDir, true)) - { - switch (OfficeFileFormatChecker.nFileType) - { - case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX: - case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCM: - case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOTX: - case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOTM: - nRes = docx_dir2doct_bin(sResultOoxmlDir, sTo, sTemp, params, L""); - break; - case AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSX: - case AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSM: - case AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLTX: - case AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLTM: - - case AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSB: - nRes = xlsx_dir2xlst_bin(sResultOoxmlDir, sTo, params, true, L""); - break; - case AVS_OFFICESTUDIO_FILE_PRESENTATION_PPTX: - case AVS_OFFICESTUDIO_FILE_PRESENTATION_PPTM: - case AVS_OFFICESTUDIO_FILE_PRESENTATION_PPSX: - case AVS_OFFICESTUDIO_FILE_PRESENTATION_POTX: - case AVS_OFFICESTUDIO_FILE_PRESENTATION_POTM: - case AVS_OFFICESTUDIO_FILE_PRESENTATION_PPSM: - nRes = pptx_dir2pptt_bin(sResultOoxmlDir, sTo, sTemp, params, L""); - break; - default: - break; - } - } - } - - return nRes; - } - _UINT32 package2ooxml_dir(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - BinDocxRW::CDocxSerializer m_oCDocxSerializer; - - _UINT32 nRes = m_oCDocxSerializer.unpackageFile(sFrom, sTo) ? 0 : AVS_FILEUTILS_ERROR_CONVERT; - - return nRes; - } - // docxflat -> bin - _UINT32 docxflat2doct_bin(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - // Save to file (from temp dir) - BinDocxRW::CDocxSerializer m_oCDocxSerializer; - - m_oCDocxSerializer.setIsNoBase64(params.getIsNoBase64()); - m_oCDocxSerializer.setFontDir(params.getFontPath()); - - // bool bRes = m_oCDocxSerializer.saveToFile (sResDoct, sSrcDocx, sTemp); - _UINT32 nRes = m_oCDocxSerializer.saveToFile(sTo, sFrom, params.getXmlOptions(), sTemp) ? 0 : AVS_FILEUTILS_ERROR_CONVERT; - - return nRes; - } - // docx -> bin - _UINT32 docx2doct_bin(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - std::wstring sTempUnpackedDOCX = sTemp + FILE_SEPARATOR_STR + _T("docx_unpacked"); - - NSDirectory::CreateDirectory(sTempUnpackedDOCX); - - COfficeUtils oCOfficeUtils(NULL); - if (S_OK != oCOfficeUtils.ExtractToDirectory(sFrom, sTempUnpackedDOCX, NULL, 0)) - { - // check crypt - COfficeFileFormatChecker OfficeFileFormatChecker; - if (OfficeFileFormatChecker.isOfficeFile(sFrom)) - { - if (OfficeFileFormatChecker.nFileType == AVS_OFFICESTUDIO_FILE_OTHER_MS_OFFCRYPTO) - return mscrypt2oot_bin(sFrom, sTo, sTemp, params); - else if (OfficeFileFormatChecker.nFileType == AVS_OFFICESTUDIO_FILE_OTHER_MS_MITCRYPTO) - return mitcrypt2oot_bin(sFrom, sTo, sTemp, params); - else - { - if (create_if_empty(sFrom, sTo, L"DOCY;v10;0;")) - return 0; - } - return AVS_FILEUTILS_ERROR_CONVERT; - } - else - return AVS_FILEUTILS_ERROR_CONVERT; - } - return docx_dir2doct_bin(sTempUnpackedDOCX, sTo, sTemp, params, sFrom); - } - _UINT32 docx_dir2doct_bin(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms, const std::wstring &sDocxFile) - { - _UINT32 nRes = S_OK; - std::wstring sToDir = NSDirectory::GetFolderPath(sTo); - if (params.needConvertToOrigin(AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX) && !sDocxFile.empty()) - { - nRes = CopyOOXOrigin(sToDir, sFrom, L"origin.docx", sDocxFile); - } - else - { - // Save to file (from temp dir) - BinDocxRW::CDocxSerializer m_oCDocxSerializer; - - m_oCDocxSerializer.setIsNoBase64(params.getIsNoBase64()); - m_oCDocxSerializer.setFontDir(params.getFontPath()); - - // bool bRes = m_oCDocxSerializer.saveToFile (sResDoct, sSrcDocx, sTemp); - nRes = m_oCDocxSerializer.saveToFile(sTo, sFrom, params.getXmlOptions(), sTemp) ? 0 : AVS_FILEUTILS_ERROR_CONVERT; - } - return nRes; - } - // docxflat -> doct - _UINT32 docxflat2doct(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - std::wstring sResultDoctDir = sTemp + FILE_SEPARATOR_STR + _T("doct_unpacked"); - std::wstring sResultDoctFileEditor = sResultDoctDir + FILE_SEPARATOR_STR + _T("Editor.bin"); - - NSDirectory::CreateDirectory(sResultDoctDir); - - _UINT32 nRes = docxflat2doct_bin(sFrom, sResultDoctFileEditor, sTemp, params); - - if (SUCCEEDED_X2T(nRes)) - { - COfficeUtils oCOfficeUtils(NULL); - nRes = (S_OK == oCOfficeUtils.CompressFileOrDirectory(sResultDoctDir, sTo)) ? nRes : AVS_FILEUTILS_ERROR_CONVERT; - } - - return nRes; - } - // docx -> doct - _UINT32 docx2doct(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - // Extract docx to temp directory - std::wstring sResultDoctDir = sTemp + FILE_SEPARATOR_STR + _T("doct_unpacked"); - std::wstring sResultDoctFileEditor = sResultDoctDir + FILE_SEPARATOR_STR + _T("Editor.bin"); - - NSDirectory::CreateDirectory(sResultDoctDir); - - _UINT32 nRes = docx2doct_bin(sFrom, sResultDoctFileEditor, sTemp, params); - - if (SUCCEEDED_X2T(nRes)) - { - COfficeUtils oCOfficeUtils(NULL); - nRes = (S_OK == oCOfficeUtils.CompressFileOrDirectory(sResultDoctDir, sTo)) ? nRes : AVS_FILEUTILS_ERROR_CONVERT; - } - - return nRes; - } - // docx_dir -> doct - _UINT32 docx_dir2doct(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms, const std::wstring &sDocxFile) - { - // Extract docx to temp directory - std::wstring sResultDoctDir = sTemp + FILE_SEPARATOR_STR + _T("doct_unpacked"); - std::wstring sResultDoctFileEditor = sResultDoctDir + FILE_SEPARATOR_STR + _T("Editor.bin"); - - NSDirectory::CreateDirectory(sResultDoctDir); - - _UINT32 nRes = docx_dir2doct_bin(sFrom, sResultDoctFileEditor, sTemp, params, sDocxFile); - - if (SUCCEEDED_X2T(nRes)) - { - COfficeUtils oCOfficeUtils(NULL); - nRes = (S_OK == oCOfficeUtils.CompressFileOrDirectory(sResultDoctDir, sTo)) ? nRes : AVS_FILEUTILS_ERROR_CONVERT; - } - - return nRes; - } - // bin -> docx - _UINT32 doct_bin2docx(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, const std::wstring &sThemeDir, InputParams ¶ms) - { - std::wstring sResultDocxDir = sTemp + FILE_SEPARATOR_STR + _T("docx_unpacked"); - NSDirectory::CreateDirectory(sResultDocxDir); - - _UINT32 nRes = doct_bin2docx_dir(sFrom, sTo, sResultDocxDir, sThemeDir, params); - - if (SUCCEEDED_X2T(nRes) && params.m_nFormatTo) - { - if (AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCM == *params.m_nFormatTo || AVS_OFFICESTUDIO_FILE_DOCUMENT_DOTX == *params.m_nFormatTo || AVS_OFFICESTUDIO_FILE_DOCUMENT_DOTM == *params.m_nFormatTo) - { - std::wstring sCTFrom = _T("application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"); - std::wstring sCTTo; - switch (*params.m_nFormatTo) - { - case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCM: - sCTTo = _T("application/vnd.ms-word.document.macroEnabled.main+xml"); - break; - case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOTX: - sCTTo = _T("application/vnd.openxmlformats-officedocument.wordprocessingml.template.main+xml"); - break; - case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOTM: - sCTTo = _T("application/vnd.ms-word.template.macroEnabledTemplate.main+xml"); - break; - } - nRes = replaceContentType(sResultDocxDir, sCTFrom, sCTTo); - } - else if (AVS_OFFICESTUDIO_FILE_DOCUMENT_OFORM == *params.m_nFormatTo) - { - // std::wstring sCT = L""; - // nRes = addContentType(sResultDocxDir, sCT); - } - else if (AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCXF == *params.m_nFormatTo) - { - // std::wstring sCT = L""; - // nRes = addContentType(sResultDocxDir, sCT); - } - } - if (SUCCEEDED_X2T(nRes)) - { - nRes = dir2zipMscrypt(sResultDocxDir, sTo, sTemp, params); - } - - return nRes; - } - // bin -> docx dir - _UINT32 doct_bin2docx_dir(const std::wstring &sFrom, const std::wstring &sToResult, const std::wstring &sTo, const std::wstring &sThemeDir, InputParams ¶ms) - { - _UINT32 nRes = 0; - std::wstring sTargetBin; - if (params.getFromChanges()) - { - params.setFromChanges(false); - nRes = apply_changes(sFrom, sToResult, NSDoctRenderer::DoctRendererFormat::FormatFile::DOCT, sThemeDir, sTargetBin, params); - } - else - sTargetBin = sFrom; - - BinDocxRW::CDocxSerializer m_oCDocxSerializer; - - m_oCDocxSerializer.setOFormEnabled(params.m_nFormatTo && (*params.m_nFormatTo == AVS_OFFICESTUDIO_FILE_DOCUMENT_OFORM || *params.m_nFormatTo == AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCXF)); - m_oCDocxSerializer.setMacroEnabled(params.m_bMacro); - m_oCDocxSerializer.setIsNoBase64(params.getIsNoBase64()); - m_oCDocxSerializer.setFontDir(params.getFontPath()); - - std::wstring sXmlOptions; - std::wstring sThemePath; // will be filled by 'CreateDocxFolders' method - std::wstring sMediaPath; // will be filled by 'CreateDocxFolders' method - std::wstring sEmbedPath; // will be filled by 'CreateDocxFolders' method - - m_oCDocxSerializer.CreateDocxFolders(sTo, sThemePath, sMediaPath, sEmbedPath); - - if (SUCCEEDED_X2T(nRes)) - { - nRes = m_oCDocxSerializer.loadFromFile(sTargetBin, sTo, sXmlOptions, sThemePath, sMediaPath, sEmbedPath) ? nRes : AVS_FILEUTILS_ERROR_CONVERT; - } - // удаляем EditorWithChanges, потому что он не в Temp - if (sFrom != sTargetBin) - NSFile::CFileBinary::Remove(sTargetBin); - return nRes; - } - - // doct -> docx - _UINT32 doct2docx(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, const std::wstring &sThemeDir, InputParams ¶ms) - { - // Extract docx to temp directory - std::wstring sTempUnpackedDOCT = sTemp + FILE_SEPARATOR_STR + _T("doct_unpacked"); - std::wstring sTempDoctFileEditor = sTempUnpackedDOCT + FILE_SEPARATOR_STR + _T("Editor.bin"); - - NSDirectory::CreateDirectory(sTempUnpackedDOCT); - - // unzip doct to folder - COfficeUtils oCOfficeUtils(NULL); - if (S_OK != oCOfficeUtils.ExtractToDirectory(sFrom, sTempUnpackedDOCT, NULL, 0)) - return AVS_FILEUTILS_ERROR_CONVERT; - - return doct_bin2docx(sTempDoctFileEditor, sTo, sTemp, sThemeDir, params); - } - // dotx -> docx - _UINT32 dotx2docx(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - std::wstring sTempUnpackedDOCX = sTemp + FILE_SEPARATOR_STR + _T("docx_unpacked"); - NSDirectory::CreateDirectory(sTempUnpackedDOCX); - - _UINT32 nRes = dotx2docx_dir(sFrom, sTempUnpackedDOCX, params); - if (SUCCEEDED_X2T(nRes)) - { - COfficeUtils oCOfficeUtils(NULL); - if (S_OK == oCOfficeUtils.CompressFileOrDirectory(sTempUnpackedDOCX, sTo, true)) - return 0; - } - return AVS_FILEUTILS_ERROR_CONVERT; - } - _UINT32 dotx2docx_dir(const std::wstring &sFrom, const std::wstring &sTo, InputParams ¶ms) - { - COfficeUtils oCOfficeUtils(NULL); - if (S_OK == oCOfficeUtils.ExtractToDirectory(sFrom, sTo, NULL, 0)) - { - std::wstring sContentTypesPath = sTo + FILE_SEPARATOR_STR + _T("[Content_Types].xml"); - if (NSFile::CFileBinary::Exists(sContentTypesPath)) - { - std::wstring sData; - if (NSFile::CFileBinary::ReadAllTextUtf8(sContentTypesPath, sData)) - { - std::wstring sCTFrom = _T("application/vnd.openxmlformats-officedocument.wordprocessingml.template.main+xml"); - std::wstring sCTTo = _T("application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"); - - sData = string_replaceAll(sData, sCTFrom, sCTTo); - - if (NSFile::CFileBinary::SaveToFile(sContentTypesPath, sData, true)) - { - return 0; - } - } - } - } - return AVS_FILEUTILS_ERROR_CONVERT; - } - // docm -> docx - _UINT32 docm2docx(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - std::wstring sTempUnpackedDOCX = sTemp + FILE_SEPARATOR_STR + _T("docx_unpacked"); - NSDirectory::CreateDirectory(sTempUnpackedDOCX); - - _UINT32 nRes = docm2docx_dir(sFrom, sTempUnpackedDOCX, params); - if (SUCCEEDED_X2T(nRes)) - { - COfficeUtils oCOfficeUtils(NULL); - if (S_OK == oCOfficeUtils.CompressFileOrDirectory(sTempUnpackedDOCX, sTo, true)) - return 0; - } - return AVS_FILEUTILS_ERROR_CONVERT; - } - _UINT32 docm2docx_dir(const std::wstring &sFrom, const std::wstring &sTo, InputParams ¶ms) - { - COfficeUtils oCOfficeUtils(NULL); - if (S_OK == oCOfficeUtils.ExtractToDirectory(sFrom, sTo, NULL, 0)) - { - std::wstring sContentTypesPath = sTo + FILE_SEPARATOR_STR + _T("[Content_Types].xml"); - if (NSFile::CFileBinary::Exists(sContentTypesPath)) - { - std::wstring sData; - if (NSFile::CFileBinary::ReadAllTextUtf8(sContentTypesPath, sData)) - { - std::wstring sCTFrom = _T("application/vnd.ms-word.document.macroEnabled.main+xml"); - std::wstring sCTTo = _T("application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"); - sData = string_replaceAll(sData, sCTFrom, sCTTo); - - sCTFrom = L""; - sData = string_replaceAll(sData, sCTFrom, L""); - - sCTFrom = L""; - sData = string_replaceAll(sData, sCTFrom, L""); - - sCTFrom = L""; - sData = string_replaceAll(sData, sCTFrom, L""); - - if (NSFile::CFileBinary::SaveToFile(sContentTypesPath, sData, true) == false) - { - return AVS_FILEUTILS_ERROR_CONVERT; - } - } - } - std::wstring sDocumentRelsPath = sTo + FILE_SEPARATOR_STR + L"word" + FILE_SEPARATOR_STR + L"_rels" + FILE_SEPARATOR_STR + L"document.xml.rels"; - if (NSFile::CFileBinary::Exists(sDocumentRelsPath)) - { - std::wstring sData; - if (NSFile::CFileBinary::ReadAllTextUtf8(sDocumentRelsPath, sData)) - { - size_t pos = sData.find(L"vbaProject.bin"); - if (pos != std::wstring::npos) - { - size_t pos1 = sData.rfind(L"<", pos); - size_t pos2 = sData.find(L">", pos); - - if (pos1 != std::wstring::npos && pos2 != std::wstring::npos) - { - sData.erase(sData.begin() + pos1, sData.begin() + pos2 + 1); - } - } - if (NSFile::CFileBinary::SaveToFile(sDocumentRelsPath, sData, true) == false) - { - return AVS_FILEUTILS_ERROR_CONVERT; - } - } - } - std::wstring sVbaProjectPath = sTo + FILE_SEPARATOR_STR + L"word" + FILE_SEPARATOR_STR + L"vbaProject.bin"; - NSFile::CFileBinary::Remove(sVbaProjectPath); - - std::wstring sVbaProjectRelsPath = sTo + FILE_SEPARATOR_STR + L"word" + FILE_SEPARATOR_STR + L"_rels" + FILE_SEPARATOR_STR + L"vbaProject.bin.rels"; - NSFile::CFileBinary::Remove(sVbaProjectRelsPath); - - std::wstring sVbaDataPath = sTo + FILE_SEPARATOR_STR + L"word" + FILE_SEPARATOR_STR + L"vbaData.xml"; - NSFile::CFileBinary::Remove(sVbaDataPath); - } - return 0; - } - // dotm -> docx - _UINT32 dotm2docx(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - std::wstring sTempUnpackedDOCX = sTemp + FILE_SEPARATOR_STR + _T("docx_unpacked"); - NSDirectory::CreateDirectory(sTempUnpackedDOCX); - - _UINT32 nRes = dotm2docx_dir(sFrom, sTempUnpackedDOCX, params); - if (SUCCEEDED_X2T(nRes)) - { - COfficeUtils oCOfficeUtils(NULL); - if (S_OK == oCOfficeUtils.CompressFileOrDirectory(sTempUnpackedDOCX, sTo, true)) - return 0; - } - return AVS_FILEUTILS_ERROR_CONVERT; - } - _UINT32 dotm2docx_dir(const std::wstring &sFrom, const std::wstring &sTo, InputParams ¶ms) - { - COfficeUtils oCOfficeUtils(NULL); - if (S_OK == oCOfficeUtils.ExtractToDirectory(sFrom, sTo, NULL, 0)) - { - std::wstring sContentTypesPath = sTo + FILE_SEPARATOR_STR + _T("[Content_Types].xml"); - if (NSFile::CFileBinary::Exists(sContentTypesPath)) - { - std::wstring sData; - if (NSFile::CFileBinary::ReadAllTextUtf8(sContentTypesPath, sData)) - { - std::wstring sCTFrom = _T("application/vnd.ms-word.template.macroEnabledTemplate.main+xml"); - std::wstring sCTTo = _T("application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"); - sData = string_replaceAll(sData, sCTFrom, sCTTo); - - sCTFrom = L""; - sData = string_replaceAll(sData, sCTFrom, L""); - - sCTFrom = L""; - sData = string_replaceAll(sData, sCTFrom, L""); - - sCTFrom = L""; - sData = string_replaceAll(sData, sCTFrom, L""); - - if (NSFile::CFileBinary::SaveToFile(sContentTypesPath, sData, true) == false) - { - return AVS_FILEUTILS_ERROR_CONVERT; - } - } - } - std::wstring sDocumentRelsPath = sTo + FILE_SEPARATOR_STR + L"word" + FILE_SEPARATOR_STR + L"_rels" + FILE_SEPARATOR_STR + L"document.xml.rels"; - if (NSFile::CFileBinary::Exists(sDocumentRelsPath)) - { - std::wstring sData; - if (NSFile::CFileBinary::ReadAllTextUtf8(sDocumentRelsPath, sData)) - { - size_t pos = sData.find(L"vbaProject.bin"); - if (pos != std::wstring::npos) - { - size_t pos1 = sData.rfind(L"<", pos); - size_t pos2 = sData.find(L">", pos); - - if (pos1 != std::wstring::npos && pos2 != std::wstring::npos) - { - sData.erase(sData.begin() + pos1, sData.begin() + pos2 + 1); - } - } - if (NSFile::CFileBinary::SaveToFile(sDocumentRelsPath, sData, true) == false) - { - return AVS_FILEUTILS_ERROR_CONVERT; - } - } - } - std::wstring sVbaProjectPath = sTo + FILE_SEPARATOR_STR + L"word" + FILE_SEPARATOR_STR + L"vbaProject.bin"; - NSFile::CFileBinary::Remove(sVbaProjectPath); - - std::wstring sVbaProjectRelsPath = sTo + FILE_SEPARATOR_STR + L"word" + FILE_SEPARATOR_STR + L"_rels" + FILE_SEPARATOR_STR + L"vbaProject.bin.rels"; - NSFile::CFileBinary::Remove(sVbaProjectRelsPath); - - std::wstring sVbaDataPath = sTo + FILE_SEPARATOR_STR + L"word" + FILE_SEPARATOR_STR + L"vbaData.xml"; - NSFile::CFileBinary::Remove(sVbaDataPath); - } - return 0; - } - // dotm -> docm - _UINT32 dotm2docm(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - std::wstring sTempUnpackedDOCM = sTemp + FILE_SEPARATOR_STR + _T("docm_unpacked"); - NSDirectory::CreateDirectory(sTempUnpackedDOCM); - - _UINT32 nRes = dotm2docm_dir(sFrom, sTempUnpackedDOCM, params); - if (SUCCEEDED_X2T(nRes)) - { - COfficeUtils oCOfficeUtils(NULL); - if (S_OK == oCOfficeUtils.CompressFileOrDirectory(sTempUnpackedDOCM, sTo, true)) - return 0; - } - return AVS_FILEUTILS_ERROR_CONVERT; - } - _UINT32 dotm2docm_dir(const std::wstring &sFrom, const std::wstring &sTo, InputParams ¶ms) - { - COfficeUtils oCOfficeUtils(NULL); - if (S_OK == oCOfficeUtils.ExtractToDirectory(sFrom, sTo, NULL, 0)) - { - std::wstring sContentTypesPath = sTo + FILE_SEPARATOR_STR + _T("[Content_Types].xml"); - if (NSFile::CFileBinary::Exists(sContentTypesPath)) - { - std::wstring sData; - if (NSFile::CFileBinary::ReadAllTextUtf8(sContentTypesPath, sData)) - { - std::wstring sCTFrom = _T("application/vnd.ms-word.template.macroEnabledTemplate.main+xml"); - std::wstring sCTTo = _T("application/vnd.ms-word.document.macroEnabled.main+xml"); - - sData = string_replaceAll(sData, sCTFrom, sCTTo); - - if (NSFile::CFileBinary::SaveToFile(sContentTypesPath, sData, true)) - { - return 0; - } - } - } - } - return AVS_FILEUTILS_ERROR_CONVERT; - } - // xslx -> bin - _UINT32 xlsx2xlst_bin(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - // Extract xlsx to temp directory - std::wstring sTempUnpackedXLSX = sTemp + FILE_SEPARATOR_STR + _T("xlsx_unpacked"); - - NSDirectory::CreateDirectory(sTempUnpackedXLSX); - - COfficeUtils oCOfficeUtils(NULL); - if (S_OK != oCOfficeUtils.ExtractToDirectory(sFrom, sTempUnpackedXLSX, NULL, 0)) - { - // check crypt - COfficeFileFormatChecker OfficeFileFormatChecker; - if (OfficeFileFormatChecker.isOfficeFile(sFrom)) - { - if (OfficeFileFormatChecker.nFileType == AVS_OFFICESTUDIO_FILE_OTHER_MS_OFFCRYPTO) - { - // test protect - bool isOldPassword = params.hasPassword(); - const std::wstring sOldPassword = params.getPassword(); - - if (isOldPassword) - delete params.m_sPassword; - params.m_sPassword = new std::wstring(L"VelvetSweatshop"); - - _UINT32 nRes = mscrypt2oot_bin(sFrom, sTo, sTemp, params); - if (SUCCEEDED_X2T(nRes)) - { - return nRes; - } - else - { - delete params.m_sPassword; - if (isOldPassword) - params.m_sPassword = new std::wstring(sOldPassword); - return mscrypt2oot_bin(sFrom, sTo, sTemp, params); - } - } - else if (OfficeFileFormatChecker.nFileType == AVS_OFFICESTUDIO_FILE_OTHER_MS_MITCRYPTO) - return mitcrypt2oot_bin(sFrom, sTo, sTemp, params); - else - { - if (create_if_empty(sFrom, sTo, L"XLSY;v10;0;")) - return 0; - return AVS_FILEUTILS_ERROR_CONVERT; - } - } - else - return AVS_FILEUTILS_ERROR_CONVERT; - } - - return xlsx_dir2xlst_bin(sTempUnpackedXLSX, sTo, params, true, sFrom); - } - // xlsxflat -> bin - _UINT32 xlsxflat2xlst_bin(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - std::wstring sToDir = NSDirectory::GetFolderPath(sTo); - - BinXlsxRW::CXlsxSerializer oCXlsxSerializer; - - oCXlsxSerializer.setIsNoBase64(params.getIsNoBase64()); - oCXlsxSerializer.setFontDir(params.getFontPath()); - - return oCXlsxSerializer.saveToFile(sTo, sFrom, params.getXmlOptions()); - } - - _UINT32 xlsx_dir2xlst_bin(const std::wstring &sXlsxDir, const std::wstring &sTo, InputParams ¶ms, bool bXmlOptions, const std::wstring &sXlsxFile) - { - _UINT32 nRes = S_OK; - std::wstring sToDir = NSDirectory::GetFolderPath(sTo); - if (params.needConvertToOrigin(AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSX) && !sXlsxFile.empty()) - { - nRes = CopyOOXOrigin(sToDir, sXlsxDir, L"origin.xlsx", sXlsxFile); - } - else - { - BinXlsxRW::CXlsxSerializer oCXlsxSerializer; - if (oCXlsxSerializer.hasPivot(sXlsxDir)) - { - // save Editor.xlsx for pivot - nRes = CopyOOXOrigin(sToDir, sXlsxDir, L"Editor.xlsx", sXlsxFile); - } - - // Save to file (from temp dir) - oCXlsxSerializer.setIsNoBase64(params.getIsNoBase64()); - oCXlsxSerializer.setFontDir(params.getFontPath()); - - nRes = oCXlsxSerializer.saveToFile(sTo, sXlsxDir, bXmlOptions ? params.getXmlOptions() : L""); - } - return nRes; - } - // xslx_dir -> xslt - _UINT32 xlsx_dir2xlst(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms, bool bXmlOptions, const std::wstring &sXlsxFile) - { - // Extract xlsx to temp directory - std::wstring sResultXlstDir = sTemp + FILE_SEPARATOR_STR + _T("xlst_unpacked"); - std::wstring sResultXlstFileEditor = sResultXlstDir + FILE_SEPARATOR_STR + _T("Editor.bin"); - - NSDirectory::CreateDirectory(sResultXlstDir); - - _UINT32 nRes = xlsx_dir2xlst_bin(sFrom, sResultXlstFileEditor, params, bXmlOptions, sXlsxFile); - if (SUCCEEDED_X2T(nRes)) - { - COfficeUtils oCOfficeUtils(NULL); - nRes = (S_OK == oCOfficeUtils.CompressFileOrDirectory(sResultXlstDir, sTo)) ? nRes : AVS_FILEUTILS_ERROR_CONVERT; - } - return nRes; - } - // xslx -> xslt - _UINT32 xlsx2xlst(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - // Extract xlsx to temp directory - std::wstring sResultXlstDir = sTemp + FILE_SEPARATOR_STR + _T("xlst_unpacked"); - std::wstring sResultXlstFileEditor = sResultXlstDir + FILE_SEPARATOR_STR + _T("Editor.bin"); - - NSDirectory::CreateDirectory(sResultXlstDir); - - _UINT32 nRes = xlsx2xlst_bin(sFrom, sResultXlstFileEditor, sTemp, params); - if (SUCCEEDED_X2T(nRes)) - { - COfficeUtils oCOfficeUtils(NULL); - nRes = (S_OK == oCOfficeUtils.CompressFileOrDirectory(sResultXlstDir, sTo)) ? nRes : AVS_FILEUTILS_ERROR_CONVERT; - } - - return nRes; - } - // xlsxflat -> xlsx - _UINT32 xlsxflat2xlsx(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - std::wstring sResultDocxDir = sTemp + FILE_SEPARATOR_STR + _T("xlsx_unpacked"); - - NSDirectory::CreateDirectory(sResultDocxDir); - - _UINT32 nRes = xlsxflat2xlsx_dir(sFrom, sResultDocxDir, sTemp, params); - if (SUCCEEDED_X2T(nRes)) - { - COfficeUtils oCOfficeUtils(NULL); - if (S_OK == oCOfficeUtils.CompressFileOrDirectory(sResultDocxDir, sTo, true)) - return 0; - } - return AVS_FILEUTILS_ERROR_CONVERT; - } - // xlsxflat -> xlsx dir - _UINT32 xlsxflat2xlsx_dir(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - BinXlsxRW::CXlsxSerializer oCXlsxSerializer; - - oCXlsxSerializer.setIsNoBase64(params.getIsNoBase64()); - oCXlsxSerializer.setFontDir(params.getFontPath()); - - _UINT32 nRes = oCXlsxSerializer.xml2Xlsx(sFrom, sTo, params.getXmlOptions()); - - return nRes; - } - // xlsxflat -> xlst - _UINT32 xlsxflat2xlst(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - std::wstring sResultXlstDir = sTemp + FILE_SEPARATOR_STR + _T("xlst_unpacked"); - std::wstring sResultXlstFileEditor = sResultXlstDir + FILE_SEPARATOR_STR + _T("Editor.bin"); - - NSDirectory::CreateDirectory(sResultXlstDir); - - _UINT32 nRes = xlsxflat2xlst_bin(sFrom, sResultXlstFileEditor, sTemp, params); - - if (SUCCEEDED_X2T(nRes)) - { - COfficeUtils oCOfficeUtils(NULL); - nRes = (S_OK == oCOfficeUtils.CompressFileOrDirectory(sResultXlstDir, sTo)) ? nRes : AVS_FILEUTILS_ERROR_CONVERT; - } - - return nRes; - } - // bin -> xslx - _UINT32 xlst_bin2xlsx(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, const std::wstring &sThemeDir, InputParams ¶ms) - { - // Extract xlsx to temp directory - std::wstring sResultXlsxDir = sTemp + FILE_SEPARATOR_STR + _T("xlsx_unpacked"); - NSDirectory::CreateDirectory(sResultXlsxDir); - - _UINT32 nRes = xlst_bin2xlsx_dir(sFrom, sTo, sResultXlsxDir, sThemeDir, params); - - if (SUCCEEDED_X2T(nRes) && params.m_nFormatTo) - { - if (AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSM == *params.m_nFormatTo || AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLTX == *params.m_nFormatTo || - AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLTM == *params.m_nFormatTo) - { - std::wstring sCTFrom = _T("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml"); - std::wstring sCTTo; - switch (*params.m_nFormatTo) - { - case AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSM: - sCTTo = _T("application/vnd.ms-excel.sheet.macroEnabled.main+xml"); - break; - case AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLTX: - sCTTo = _T("application/vnd.openxmlformats-officedocument.spreadsheetml.template.main+xml"); - break; - case AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLTM: - sCTTo = _T("application/vnd.ms-excel.template.macroEnabled.main+xml"); - break; - } - nRes = replaceContentType(sResultXlsxDir, sCTFrom, sCTTo); - } - } - if (SUCCEEDED_X2T(nRes)) - { - nRes = dir2zipMscrypt(sResultXlsxDir, sTo, sTemp, params); - } - return nRes; - } - _UINT32 xlst_bin2xlsx_dir(const std::wstring &sFrom, const std::wstring &sToResult, const std::wstring &sTo, const std::wstring &sThemeDir, InputParams ¶ms) - { - _UINT32 nRes = 0; - - std::wstring sTargetBin; - if (params.getFromChanges()) - { - params.setFromChanges(false); - nRes = apply_changes(sFrom, sToResult, NSDoctRenderer::DoctRendererFormat::FormatFile::XLST, sThemeDir, sTargetBin, params); - } - else - sTargetBin = sFrom; - - BinXlsxRW::CXlsxSerializer oCXlsxSerializer; - - oCXlsxSerializer.setMacroEnabled(params.m_bMacro); - oCXlsxSerializer.setIsNoBase64(params.getIsNoBase64()); - oCXlsxSerializer.setFontDir(params.getFontPath()); - - std::wstring sXmlOptions = _T(""); - std::wstring sMediaPath; // will be filled by 'CreateXlsxFolders' method - std::wstring sEmbedPath; // will be filled by 'CreateXlsxFolders' method - - oCXlsxSerializer.CreateXlsxFolders(sXmlOptions, sTo, sMediaPath, sEmbedPath); - - if (SUCCEEDED_X2T(nRes)) - { - nRes = oCXlsxSerializer.loadFromFile(sTargetBin, sTo, sXmlOptions, sMediaPath, sEmbedPath); - } - // удаляем EditorWithChanges, потому что он не в Temp - if (sFrom != sTargetBin) - NSFile::CFileBinary::Remove(sTargetBin); - return nRes; - } - - // xslt -> xslx - _UINT32 xlst2xlsx(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, const std::wstring &sThemeDir, InputParams ¶ms) - { - // Extract xlsx to temp directory - std::wstring sTempUnpackedXLST = sTemp + FILE_SEPARATOR_STR + _T("xlst_unpacked"); - std::wstring sTempXlstFileEditor = sTempUnpackedXLST + FILE_SEPARATOR_STR + _T("Editor.bin"); - - NSDirectory::CreateDirectory(sTempUnpackedXLST); - - // unzip xlst to folder - COfficeUtils oCOfficeUtils(NULL); - if (S_OK != oCOfficeUtils.ExtractToDirectory(sFrom, sTempUnpackedXLST, NULL, 0)) - return AVS_FILEUTILS_ERROR_CONVERT; - - return xlst_bin2xlsx(sTempXlstFileEditor, sTo, sTemp, sThemeDir, params); - } - // xltx -> xlsx - _UINT32 xltx2xlsx(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - std::wstring sTempUnpackedXLSX = sTemp + FILE_SEPARATOR_STR + _T("xlsx_unpacked"); - NSDirectory::CreateDirectory(sTempUnpackedXLSX); - - _UINT32 nRes = xltx2xlsx_dir(sFrom, sTempUnpackedXLSX, params); - if (SUCCEEDED_X2T(nRes)) - { - COfficeUtils oCOfficeUtils(NULL); - if (S_OK == oCOfficeUtils.CompressFileOrDirectory(sTempUnpackedXLSX, sTo, true)) - return 0; - } - return AVS_FILEUTILS_ERROR_CONVERT; - } - _UINT32 xltx2xlsx_dir(const std::wstring &sFrom, const std::wstring &sTo, InputParams ¶ms) - { - COfficeUtils oCOfficeUtils(NULL); - if (S_OK == oCOfficeUtils.ExtractToDirectory(sFrom, sTo, NULL, 0)) - { - std::wstring sContentTypesPath = sTo + FILE_SEPARATOR_STR + _T("[Content_Types].xml"); - if (NSFile::CFileBinary::Exists(sContentTypesPath)) - { - std::wstring sData; - if (NSFile::CFileBinary::ReadAllTextUtf8(sContentTypesPath, sData)) - { - std::wstring sCTFrom = _T("application/vnd.openxmlformats-officedocument.spreadsheetml.template.main+xml"); - std::wstring sCTTo = _T("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml"); - - sData = string_replaceAll(sData, sCTFrom, sCTTo); - - if (NSFile::CFileBinary::SaveToFile(sContentTypesPath, sData, true)) - { - return 0; - } - } - } - } - return AVS_FILEUTILS_ERROR_CONVERT; - } - // xlsm -> xlsx - _UINT32 xlsm2xlsx(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - std::wstring sTempUnpackedXLSX = sTemp + FILE_SEPARATOR_STR + _T("xlsx_unpacked"); - NSDirectory::CreateDirectory(sTempUnpackedXLSX); - - _UINT32 nRes = xlsm2xlsx_dir(sFrom, sTempUnpackedXLSX, params); - if (SUCCEEDED_X2T(nRes)) - { - COfficeUtils oCOfficeUtils(NULL); - if (S_OK == oCOfficeUtils.CompressFileOrDirectory(sTempUnpackedXLSX, sTo, true)) - return 0; - } - return AVS_FILEUTILS_ERROR_CONVERT; - } - _UINT32 xlsm2xlsx_dir(const std::wstring &sFrom, const std::wstring &sTo, InputParams ¶ms) - { - COfficeUtils oCOfficeUtils(NULL); - if (S_OK == oCOfficeUtils.ExtractToDirectory(sFrom, sTo, NULL, 0)) - { - std::wstring sContentTypesPath = sTo + FILE_SEPARATOR_STR + _T("[Content_Types].xml"); - if (NSFile::CFileBinary::Exists(sContentTypesPath)) - { - std::wstring sData; - if (NSFile::CFileBinary::ReadAllTextUtf8(sContentTypesPath, sData)) - { - std::wstring sCTFrom = L"application/vnd.ms-excel.sheet.macroEnabled.main+xml"; - std::wstring sCTTo = L"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml"; - sData = string_replaceAll(sData, sCTFrom, sCTTo); - - sCTFrom = L""; - sData = string_replaceAll(sData, sCTFrom, L""); - - sCTFrom = L""; - sData = string_replaceAll(sData, sCTFrom, L""); - - if (NSFile::CFileBinary::SaveToFile(sContentTypesPath, sData, true) == false) - { - return AVS_FILEUTILS_ERROR_CONVERT; - } - } - } - std::wstring sWorkbookRelsPath = sTo + FILE_SEPARATOR_STR + L"xl" + FILE_SEPARATOR_STR + L"_rels" + FILE_SEPARATOR_STR + L"workbook.xml.rels"; - if (NSFile::CFileBinary::Exists(sWorkbookRelsPath)) - { - std::wstring sData; - if (NSFile::CFileBinary::ReadAllTextUtf8(sWorkbookRelsPath, sData)) - { - size_t pos = sData.find(L"vbaProject.bin"); - if (pos != std::wstring::npos) - { - size_t pos1 = sData.rfind(L"<", pos); - size_t pos2 = sData.find(L">", pos); - - if (pos1 != std::wstring::npos && pos2 != std::wstring::npos) - { - sData.erase(sData.begin() + pos1, sData.begin() + pos2 + 1); - } - } - if (NSFile::CFileBinary::SaveToFile(sWorkbookRelsPath, sData, true) == false) - { - return AVS_FILEUTILS_ERROR_CONVERT; - } - } - } - std::wstring sVbaProjectPath = sTo + FILE_SEPARATOR_STR + L"xl" + FILE_SEPARATOR_STR + L"vbaProject.bin"; - NSFile::CFileBinary::Remove(sVbaProjectPath); - } - return 0; - } - // xltm -> xlsx - _UINT32 xltm2xlsx(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - std::wstring sTempUnpackedXLSX = sTemp + FILE_SEPARATOR_STR + _T("xlsx_unpacked"); - NSDirectory::CreateDirectory(sTempUnpackedXLSX); - - _UINT32 nRes = xltm2xlsx_dir(sFrom, sTempUnpackedXLSX, params); - if (SUCCEEDED_X2T(nRes)) - { - COfficeUtils oCOfficeUtils(NULL); - if (S_OK == oCOfficeUtils.CompressFileOrDirectory(sTempUnpackedXLSX, sTo, true)) - return 0; - } - return AVS_FILEUTILS_ERROR_CONVERT; - } - _UINT32 xlsb2xlsx_dir(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - std::wstring sTempUnpackedXLSB = sTemp + FILE_SEPARATOR_STR + _T("xlsb_unpacked"); - NSDirectory::CreateDirectory(sTempUnpackedXLSB); - - COfficeUtils oCOfficeUtils(NULL); - _UINT32 nRes = oCOfficeUtils.ExtractToDirectory(sFrom, sTempUnpackedXLSB, NULL, 0); - if (SUCCEEDED_X2T(nRes)) - { - OOX::Spreadsheet::CXlsb oXlsb; - oXlsb.ReadNative(OOX::CPath(sTempUnpackedXLSB)); - oXlsb.PrepareSi(); - oXlsb.PrepareTableFormula(); - - OOX::CContentTypes oContentTypes; - oXlsb.SetPropForWriteSheet(sTo, oContentTypes); - oXlsb.ReadSheetData(); - - nRes = oXlsb.WriteNative(sTo, oContentTypes) ? S_OK : AVS_FILEUTILS_ERROR_CONVERT; - if(!params.m_bMacro) - { - ///removing scripts - std::wstring sContentTypesPath = sTo + FILE_SEPARATOR_STR + _T("[Content_Types].xml"); - if (NSFile::CFileBinary::Exists(sContentTypesPath)) - { - std::wstring sData; - if (NSFile::CFileBinary::ReadAllTextUtf8(sContentTypesPath, sData)) - { - std::wstring sCTFrom = L"application/vnd.ms-excel.sheet.macroEnabled.main+xml"; - std::wstring sCTTo = L"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml"; - sData = string_replaceAll(sData, sCTFrom, sCTTo); - - sCTFrom = L""; - sData = string_replaceAll(sData, sCTFrom, L""); - - sCTFrom = L""; - sData = string_replaceAll(sData, sCTFrom, L""); - - if (NSFile::CFileBinary::SaveToFile(sContentTypesPath, sData, true) == false) - { - return AVS_FILEUTILS_ERROR_CONVERT; - } - } - } - std::wstring sWorkbookRelsPath = sTo + FILE_SEPARATOR_STR + L"xl" + FILE_SEPARATOR_STR + L"_rels" + FILE_SEPARATOR_STR + L"workbook.xml.rels"; - if (NSFile::CFileBinary::Exists(sWorkbookRelsPath)) - { - std::wstring sData; - if (NSFile::CFileBinary::ReadAllTextUtf8(sWorkbookRelsPath, sData)) - { - size_t pos = sData.find(L"vbaProject.bin"); - if (pos != std::wstring::npos) - { - size_t pos1 = sData.rfind(L"<", pos); - size_t pos2 = sData.find(L">", pos); - - if (pos1 != std::wstring::npos && pos2 != std::wstring::npos) - { - sData.erase(sData.begin() + pos1, sData.begin() + pos2 + 1); - } - } - if (NSFile::CFileBinary::SaveToFile(sWorkbookRelsPath, sData, true) == false) - { - return AVS_FILEUTILS_ERROR_CONVERT; - } - } - } - std::wstring sVbaProjectPath = sTo + FILE_SEPARATOR_STR + L"xl" + FILE_SEPARATOR_STR + L"vbaProject.bin"; - NSFile::CFileBinary::Remove(sVbaProjectPath); - } - - } - return nRes; - } - _UINT32 xltm2xlsx_dir(const std::wstring &sFrom, const std::wstring &sTo, InputParams ¶ms) - { - COfficeUtils oCOfficeUtils(NULL); - if (S_OK == oCOfficeUtils.ExtractToDirectory(sFrom, sTo, NULL, 0)) - { - std::wstring sContentTypesPath = sTo + FILE_SEPARATOR_STR + _T("[Content_Types].xml"); - if (NSFile::CFileBinary::Exists(sContentTypesPath)) - { - std::wstring sData; - if (NSFile::CFileBinary::ReadAllTextUtf8(sContentTypesPath, sData)) - { - std::wstring sCTFrom = L"application/vnd.ms-excel.template.macroEnabled.main+xml"; - std::wstring sCTTo = L"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml"; - sData = string_replaceAll(sData, sCTFrom, sCTTo); - - sCTFrom = L""; - sData = string_replaceAll(sData, sCTFrom, L""); - - sCTFrom = L""; - sData = string_replaceAll(sData, sCTFrom, L""); - - if (NSFile::CFileBinary::SaveToFile(sContentTypesPath, sData, true) == false) - { - return AVS_FILEUTILS_ERROR_CONVERT; - } - } - } - std::wstring sWorkbookRelsPath = sTo + FILE_SEPARATOR_STR + L"xl" + FILE_SEPARATOR_STR + L"_rels" + FILE_SEPARATOR_STR + L"workbook.xml.rels"; - if (NSFile::CFileBinary::Exists(sWorkbookRelsPath)) - { - std::wstring sData; - if (NSFile::CFileBinary::ReadAllTextUtf8(sWorkbookRelsPath, sData)) - { - size_t pos = sData.find(L"vbaProject.bin"); - if (pos != std::wstring::npos) - { - size_t pos1 = (int)sData.rfind(L"<", pos); - size_t pos2 = (int)sData.find(L">", pos); - - if (pos1 != std::wstring::npos && pos2 != std::wstring::npos) - { - sData.erase(sData.begin() + pos1, sData.begin() + pos2 + 1); - } - } - if (NSFile::CFileBinary::SaveToFile(sWorkbookRelsPath, sData, true) == false) - { - return AVS_FILEUTILS_ERROR_CONVERT; - } - } - } - std::wstring sVbaProjectPath = sTo + FILE_SEPARATOR_STR + L"xl" + FILE_SEPARATOR_STR + L"vbaProject.bin"; - NSFile::CFileBinary::Remove(sVbaProjectPath); - } - return 0; - } - // xltm -> xlsm - _UINT32 xltm2xlsm(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - std::wstring sTempUnpackedXLSM = sTemp + FILE_SEPARATOR_STR + _T("xlsm_unpacked"); - NSDirectory::CreateDirectory(sTempUnpackedXLSM); - - _UINT32 nRes = xltm2xlsm_dir(sFrom, sTempUnpackedXLSM, params); - if (SUCCEEDED_X2T(nRes)) - { - COfficeUtils oCOfficeUtils(NULL); - if (S_OK == oCOfficeUtils.CompressFileOrDirectory(sTempUnpackedXLSM, sTo, true)) - return 0; - } - return AVS_FILEUTILS_ERROR_CONVERT; - } - _UINT32 xltm2xlsm_dir(const std::wstring &sFrom, const std::wstring &sTo, InputParams ¶ms) - { - COfficeUtils oCOfficeUtils(NULL); - if (S_OK == oCOfficeUtils.ExtractToDirectory(sFrom, sTo, NULL, 0)) - { - std::wstring sContentTypesPath = sTo + FILE_SEPARATOR_STR + _T("[Content_Types].xml"); - if (NSFile::CFileBinary::Exists(sContentTypesPath)) - { - std::wstring sData; - if (NSFile::CFileBinary::ReadAllTextUtf8(sContentTypesPath, sData)) - { - std::wstring sCTFrom = _T("application/vnd.ms-excel.template.macroEnabled.main+xml"); - std::wstring sCTTo = _T("application/vnd.ms-excel.sheet.macroEnabled.main+xml"); - - sData = string_replaceAll(sData, sCTFrom, sCTTo); - - if (NSFile::CFileBinary::SaveToFile(sContentTypesPath, sData, true)) - { - return 0; - } - } - } - } - return AVS_FILEUTILS_ERROR_CONVERT; - } - // pptx -> bin - _UINT32 pptx2pptt_bin(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - // unzip pptx to temp folder - std::wstring sTempUnpackedPPTX = sTemp + FILE_SEPARATOR_STR + _T("pptx_unpacked"); - - NSDirectory::CreateDirectory(sTempUnpackedPPTX); - - // unzip pptx to folder - COfficeUtils oCOfficeUtils(NULL); - if (S_OK != oCOfficeUtils.ExtractToDirectory(sFrom, sTempUnpackedPPTX, NULL, 0)) - { - // check crypt - COfficeFileFormatChecker OfficeFileFormatChecker; - if (OfficeFileFormatChecker.isOfficeFile(sFrom)) - { - if (OfficeFileFormatChecker.nFileType == AVS_OFFICESTUDIO_FILE_OTHER_MS_OFFCRYPTO) - return mscrypt2oot_bin(sFrom, sTo, sTemp, params); - else if (OfficeFileFormatChecker.nFileType == AVS_OFFICESTUDIO_FILE_OTHER_MS_MITCRYPTO) - return mitcrypt2oot_bin(sFrom, sTo, sTemp, params); - else - { - if (create_if_empty(sFrom, sTo, L"PPTY;v10;0;")) - return 0; - return AVS_FILEUTILS_ERROR_CONVERT; - } - } - else - return AVS_FILEUTILS_ERROR_CONVERT; - } - - return pptx_dir2pptt_bin(sTempUnpackedPPTX, sTo, sTemp, params, sFrom); - } - _UINT32 pptx_dir2pptt_bin(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms, const std::wstring &sPptxFile) - { - _UINT32 nRes = 0; - std::wstring sToDir = NSDirectory::GetFolderPath(sTo); - if (params.needConvertToOrigin(AVS_OFFICESTUDIO_FILE_PRESENTATION_PPTX) && !sPptxFile.empty()) - { - nRes = CopyOOXOrigin(sToDir, sFrom, L"origin.pptx", sPptxFile); - } - else - { - // convert unzipped pptx to unzipped pptt - CPPTXFile *pptx_file = new CPPTXFile(); - - if (pptx_file) - { - pptx_file->SetIsNoBase64(params.getIsNoBase64()); - pptx_file->put_TempDirectory(sTemp); - pptx_file->SetFontDir(params.getFontPath()); - nRes = (S_OK == pptx_file->OpenFileToPPTY(sFrom, sTo)) ? nRes : AVS_FILEUTILS_ERROR_CONVERT; - - delete pptx_file; - } - } - return nRes; - } - // pptx_dir -> pptt - _UINT32 pptx_dir2pptt(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms, const std::wstring &sPptxFile) - { - std::wstring sResultPpttDir = sTemp + FILE_SEPARATOR_STR + _T("pptt_unpacked"); - std::wstring sTempPpttFileEditor = sResultPpttDir + FILE_SEPARATOR_STR + _T("Editor.bin"); - - NSDirectory::CreateDirectory(sResultPpttDir); - - _UINT32 nRes = pptx_dir2pptt_bin(sFrom, sTempPpttFileEditor, sTemp, params, sPptxFile); - if (SUCCEEDED_X2T(nRes)) - { - // zip pptt folder to output file - COfficeUtils oCOfficeUtils(NULL); - nRes = (S_OK == oCOfficeUtils.CompressFileOrDirectory(sResultPpttDir, sTo)) ? nRes : AVS_FILEUTILS_ERROR_CONVERT; - } - return nRes; - } - // pptx -> pptt - _UINT32 pptx2pptt(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - std::wstring sResultPpttDir = sTemp + FILE_SEPARATOR_STR + _T("pptt_unpacked"); - std::wstring sTempPpttFileEditor = sResultPpttDir + FILE_SEPARATOR_STR + _T("Editor.bin"); - - NSDirectory::CreateDirectory(sResultPpttDir); - - _UINT32 nRes = pptx2pptt_bin(sFrom, sTempPpttFileEditor, sTemp, params); - if (SUCCEEDED_X2T(nRes)) - { - // zip pptt folder to output file - COfficeUtils oCOfficeUtils(NULL); - nRes = (S_OK == oCOfficeUtils.CompressFileOrDirectory(sResultPpttDir, sTo)) ? nRes : AVS_FILEUTILS_ERROR_CONVERT; - } - return nRes; - } - - // bin -> pptx - _UINT32 pptt_bin2pptx(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, const std::wstring &sThemeDir, InputParams ¶ms) - { - std::wstring sResultPptxDir = sTemp + FILE_SEPARATOR_STR + _T("pptx_unpacked"); - NSDirectory::CreateDirectory(sResultPptxDir); - - _UINT32 nRes = pptt_bin2pptx_dir(sFrom, sTo, sResultPptxDir, sThemeDir, params); - - if (SUCCEEDED_X2T(nRes) && params.m_nFormatTo) - { - if (AVS_OFFICESTUDIO_FILE_PRESENTATION_PPTM == *params.m_nFormatTo || AVS_OFFICESTUDIO_FILE_PRESENTATION_PPSX == *params.m_nFormatTo || - AVS_OFFICESTUDIO_FILE_PRESENTATION_POTX == *params.m_nFormatTo || AVS_OFFICESTUDIO_FILE_PRESENTATION_POTM == *params.m_nFormatTo || - AVS_OFFICESTUDIO_FILE_PRESENTATION_PPSM == *params.m_nFormatTo) - { - std::wstring sCTFrom = _T("application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml"); - std::wstring sCTTo; - switch (*params.m_nFormatTo) - { - case AVS_OFFICESTUDIO_FILE_PRESENTATION_PPTM: - sCTTo = _T("application/vnd.ms-powerpoint.presentation.macroEnabled.main+xml"); - break; - case AVS_OFFICESTUDIO_FILE_PRESENTATION_PPSX: - sCTTo = _T("application/vnd.openxmlformats-officedocument.presentationml.slideshow.main+xml"); - break; - case AVS_OFFICESTUDIO_FILE_PRESENTATION_POTX: - sCTTo = _T("application/vnd.openxmlformats-officedocument.presentationml.template.main+xml"); - break; - case AVS_OFFICESTUDIO_FILE_PRESENTATION_POTM: - sCTTo = _T("application/vnd.ms-powerpoint.template.macroEnabled.main+xml"); - break; - case AVS_OFFICESTUDIO_FILE_PRESENTATION_PPSM: - sCTTo = _T("application/vnd.ms-powerpoint.slideshow.macroEnabled.main+xml"); - break; - } - nRes = replaceContentType(sResultPptxDir, sCTFrom, sCTTo); - } - } - if (SUCCEEDED_X2T(nRes)) - { - nRes = dir2zipMscrypt(sResultPptxDir, sTo, sTemp, params); - } - return nRes; - } - _UINT32 pptt_bin2pptx_dir(const std::wstring &sFrom, const std::wstring &sToResult, const std::wstring &sTo, const std::wstring &sThemeDir, InputParams ¶ms) - { - _UINT32 nRes = 0; - - std::wstring sTargetBin; - if (params.getFromChanges()) - { - params.setFromChanges(false); - nRes = apply_changes(sFrom, sToResult, NSDoctRenderer::DoctRendererFormat::FormatFile::PPTT, sThemeDir, sTargetBin, params); - } - else - sTargetBin = sFrom; - - CPPTXFile *pptx_file = new CPPTXFile(); - - HRESULT hr = S_OK; - - if (pptx_file) - { - pptx_file->SetMacroEnabled(params.m_bMacro); - pptx_file->SetIsNoBase64(params.getIsNoBase64()); - pptx_file->SetFontDir(params.getFontPath()); - nRes = (S_OK == pptx_file->ConvertPPTYToPPTX(sTargetBin, sTo, sThemeDir)) ? nRes : AVS_FILEUTILS_ERROR_CONVERT; - - delete pptx_file; - } - // удаляем EditorWithChanges, потому что он не в Temp - if (sFrom != sTargetBin) - NSFile::CFileBinary::Remove(sTargetBin); - - return nRes; - } - // pptt -> pptx - _UINT32 pptt2pptx(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, const std::wstring &sThemeDir, InputParams ¶ms) - { - // unzip pptt to temp folder - std::wstring sTempUnpackedPPTT = sTemp + FILE_SEPARATOR_STR + _T("pptt_unpacked"); - std::wstring sTempPpttFileEditor = sTempUnpackedPPTT + FILE_SEPARATOR_STR + _T("Editor.bin"); - - NSDirectory::CreateDirectory(sTempUnpackedPPTT); - - // unzip pptt to folder - COfficeUtils oCOfficeUtils(NULL); - if (S_OK != oCOfficeUtils.ExtractToDirectory(sFrom, sTempUnpackedPPTT, NULL, 0)) - return AVS_FILEUTILS_ERROR_CONVERT; - - return pptt_bin2pptx(sTempPpttFileEditor, sTo, sTemp, sThemeDir, params); - } - // zip dir - _UINT32 dir2zip(const std::wstring &sFrom, const std::wstring &sTo, bool bSorted, int method, short level, bool bDateTime) - { - COfficeUtils oCOfficeUtils(NULL); - return (S_OK == oCOfficeUtils.CompressFileOrDirectory(sFrom, sTo, bSorted, method, level, bDateTime)) ? 0 : AVS_FILEUTILS_ERROR_CONVERT; - } - _UINT32 dir2zipMscrypt(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - _UINT32 nRes = S_OK; - if (params.hasSavePassword()) - { - std::wstring sToMscrypt = sTemp + FILE_SEPARATOR_STR + _T("tomscrypt.docx"); - nRes = dir2zip(sFrom, sToMscrypt); - if (SUCCEEDED_X2T(nRes)) - { - nRes = oox2mscrypt(sToMscrypt, sTo, sTemp, params); - } - } - else - { - nRes = dir2zip(sFrom, sTo, true); - } - return nRes; - } - - // unzip dir - _UINT32 zip2dir(const std::wstring &sFrom, const std::wstring &sTo) - { - COfficeUtils oCOfficeUtils(NULL); - return (S_OK == oCOfficeUtils.ExtractToDirectory(sFrom, sTo, NULL, 0)) ? 0 : AVS_FILEUTILS_ERROR_CONVERT; - } - - // csv -> xslt - _UINT32 csv2xlst(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - std::wstring sCSV = sFrom; - std::wstring sResultXlstDir = sTemp + FILE_SEPARATOR_STR + _T("xlst_unpacked"); - std::wstring sResultXlstFileEditor = sResultXlstDir + FILE_SEPARATOR_STR + _T("Editor.bin"); - - NSDirectory::CreateDirectory(sResultXlstDir); - - COfficeUtils oCOfficeUtils(NULL); - // Save to file (from temp dir) - BinXlsxRW::CXlsxSerializer oCXlsxSerializer; - - oCXlsxSerializer.setIsNoBase64(params.getIsNoBase64()); - oCXlsxSerializer.setFontDir(params.getFontPath()); - - if (!params.m_nFormatFrom) - params.m_nFormatFrom = new int(AVS_OFFICESTUDIO_FILE_UNKNOWN); - if (AVS_OFFICESTUDIO_FILE_UNKNOWN == *params.m_nFormatFrom) - *params.m_nFormatFrom = AVS_OFFICESTUDIO_FILE_SPREADSHEET_CSV; - - _UINT32 nRes = oCXlsxSerializer.saveToFile(sResultXlstFileEditor, sCSV, params.getXmlOptions()); - - if (SUCCEEDED_X2T(nRes)) - { - nRes = (S_OK == oCOfficeUtils.CompressFileOrDirectory(sResultXlstDir, sTo)) ? nRes : AVS_FILEUTILS_ERROR_CONVERT; - } - - return nRes; - } - // csv -> xslx_dir - _UINT32 csv2xlsx_dir(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - OOX::Spreadsheet::CXlsx oXlsx; - - BYTE fileType; - UINT nCodePage; - std::wstring sDelimiter; - BYTE saveFileType; - SerializeCommon::ReadFileType(params.getXmlOptions(), fileType, nCodePage, sDelimiter, saveFileType); - - CSVReader csvReader; - _UINT32 nRes = csvReader.Read(sFrom, oXlsx, nCodePage, sDelimiter); - - oXlsx.PrepareToWrite(); - - OOX::CContentTypes oContentTypes; - nRes = oXlsx.Write(sTo, oContentTypes) ? S_OK : AVS_FILEUTILS_ERROR_CONVERT; - - return nRes; - } - // xml -> xlsx - _UINT32 xml2xlsx(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - std::wstring sResultXlsxDir = sTemp + FILE_SEPARATOR_STR + _T("xlsx_unpacked"); - NSDirectory::CreateDirectory(sResultXlsxDir); - _UINT32 nRes = xml2xlsx_dir(sFrom, sResultXlsxDir, sTemp, params); - - if (SUCCEEDED_X2T(nRes)) - { - nRes = dir2zipMscrypt(sResultXlsxDir, sTo, sTemp, params); - } - return nRes; - } - _UINT32 xml2xlsx_dir(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - OOX::Spreadsheet::CXlsx oXlsx; - - XMLReader reader = {}; - - reader.Read2(sFrom, oXlsx); - - oXlsx.PrepareToWrite(); - - OOX::CContentTypes oContentTypes; - auto nRes = oXlsx.Write(sTo, oContentTypes) ? S_OK : AVS_FILEUTILS_ERROR_CONVERT; - - return nRes; - } - // csv -> xslx - _UINT32 csv2xlsx(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - std::wstring sResultXlsxDir = sTemp + FILE_SEPARATOR_STR + _T("xlsx_unpacked"); - NSDirectory::CreateDirectory(sResultXlsxDir); - - _UINT32 nRes = csv2xlsx_dir(sFrom, sResultXlsxDir, sTemp, params); - if (SUCCEEDED_X2T(nRes)) - { - nRes = dir2zipMscrypt(sResultXlsxDir, sTo, sTemp, params); - } - return nRes; - } - _UINT32 csv2xlst_bin(const std::wstring &sFrom, const std::wstring &sTo, InputParams ¶ms) - { - // Save to file (from temp dir) - BinXlsxRW::CXlsxSerializer oCXlsxSerializer; - - oCXlsxSerializer.setIsNoBase64(params.getIsNoBase64()); - oCXlsxSerializer.setFontDir(params.getFontPath()); - - return oCXlsxSerializer.saveToFile(sTo, sFrom, params.getXmlOptions()); - } - // xlst -> csv - _UINT32 xlst2csv(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - std::wstring sCSV = sTo; - std::wstring sTempUnpackedXLST = sTemp + FILE_SEPARATOR_STR + _T("xlst_unpacked"); - std::wstring sTempXlstFileEditor = sTempUnpackedXLST + FILE_SEPARATOR_STR + _T("Editor.bin"); - - NSDirectory::CreateDirectory(sTempUnpackedXLST); - - // unzip xlst to folder - COfficeUtils oCOfficeUtils(NULL); - if (S_OK != oCOfficeUtils.ExtractToDirectory(sFrom, sTempUnpackedXLST, NULL, 0)) - return AVS_FILEUTILS_ERROR_CONVERT; - - BinXlsxRW::CXlsxSerializer oCXlsxSerializer; - - oCXlsxSerializer.setIsNoBase64(params.getIsNoBase64()); - oCXlsxSerializer.setFontDir(params.getFontPath()); - oCXlsxSerializer.setTempDir(sTemp); - - std::wstring sMediaPath; - std::wstring sEmbedPath; - - params.m_nFormatTo = new int(AVS_OFFICESTUDIO_FILE_SPREADSHEET_CSV); - - return oCXlsxSerializer.loadFromFile(sTempXlstFileEditor, sCSV, params.getXmlOptions(), sMediaPath, sEmbedPath); - } - // xlsx_dir -> csv - _UINT32 xlsx_dir2csv(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - std::wstring sResultXlstDir = sTemp + FILE_SEPARATOR_STR + _T("xlst_unpacked"); - std::wstring sResultXlstFileEditor = sResultXlstDir + FILE_SEPARATOR_STR + _T("Editor.bin"); - - NSDirectory::CreateDirectory(sResultXlstDir); - - BinXlsxRW::CXlsxSerializer oCXlsxSerializer; - - oCXlsxSerializer.setIsNoBase64(params.getIsNoBase64()); - oCXlsxSerializer.setFontDir(params.getFontPath()); - - std::wstring sXMLOptions = _T(""); - _UINT32 nRes = oCXlsxSerializer.saveToFile(sResultXlstFileEditor, sFrom, sXMLOptions); - if (SUCCEEDED_X2T(nRes)) - { - std::wstring sMediaPath; - std::wstring sEmbedPath; - - sXMLOptions = _T(""); - - nRes = oCXlsxSerializer.loadFromFile(sResultXlstFileEditor, sTo, sXMLOptions, sMediaPath, sEmbedPath); - } - - return nRes; - } - // xslx -> csv - _UINT32 xlsx2csv(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - std::wstring sTempUnpackedXLSX = sTemp + FILE_SEPARATOR_STR + _T("xlsx_unpacked"); - NSDirectory::CreateDirectory(sTempUnpackedXLSX); - - COfficeUtils oCOfficeUtils(NULL); - if (S_OK != oCOfficeUtils.ExtractToDirectory(sFrom, sTempUnpackedXLSX, NULL, 0)) - return AVS_FILEUTILS_ERROR_CONVERT; - - return xlsx_dir2csv(sTempUnpackedXLSX, sTo, sTemp, params); - } - _UINT32 xlst_bin2csv(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, const std::wstring &sThemeDir, InputParams ¶ms) - { - _UINT32 nRes = 0; - - std::wstring sTargetBin; - if (params.getFromChanges()) - { - params.setFromChanges(false); - nRes = apply_changes(sFrom, sTo, NSDoctRenderer::DoctRendererFormat::FormatFile::XLST, sThemeDir, sTargetBin, params); - } - else - sTargetBin = sFrom; - - if (SUCCEEDED_X2T(nRes)) - { - BinXlsxRW::CXlsxSerializer oCXlsxSerializer; - - oCXlsxSerializer.setIsNoBase64(params.getIsNoBase64()); - oCXlsxSerializer.setFontDir(params.getFontPath()); - - std::wstring sResultCsvDir = sTemp + FILE_SEPARATOR_STR + _T("csv_unpacked"); - - NSDirectory::CreateDirectory(sResultCsvDir); - std::wstring sMediaPath; // will be filled by 'CreateXlsxFolders' method - std::wstring sEmbedPath; // will be filled by 'CreateXlsxFolders' method - std::wstring sXmlOptions = params.getXmlOptions(); - - oCXlsxSerializer.CreateXlsxFolders(sXmlOptions, sResultCsvDir, sMediaPath, sEmbedPath); - - nRes = oCXlsxSerializer.loadFromFile(sTargetBin, sTo, sXmlOptions, sMediaPath, sEmbedPath); - } - return nRes; - } - // bin -> pdf - _UINT32 bin2pdf(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, bool bPaid, const std::wstring &sThemeDir, InputParams ¶ms) - { - NSFonts::IApplicationFonts *pApplicationFonts = NSFonts::NSApplication::Create(); - initApplicationFonts(pApplicationFonts, params); - - CPdfFile pdfWriter(pApplicationFonts); - pdfWriter.CreatePdf(params.getIsPDFA()); - pdfWriter.SetTempDirectory(sTemp); - pdfWriter.SetDocumentInfo(params.getTitle(), L"", L"", L""); - - CConvertFromBinParams oBufferParams; - oBufferParams.m_sThemesDirectory = sThemeDir; - - std::wstring documentID = params.getDocumentID(); - if (false == documentID.empty()) - pdfWriter.SetDocumentID(documentID); - - std::wstring password = params.getSavePassword(); - if (false == password.empty()) - pdfWriter.SetPassword(password); - - int nReg = (bPaid == false) ? 0 : 1; - _UINT32 nRet = 0; - if (params.getIsNoBase64()) - { - nRet = S_OK == pdfWriter.OnlineWordToPdfFromBinary(sFrom, sTo, &oBufferParams) ? 0 : AVS_FILEUTILS_ERROR_CONVERT; - } - else - { - nRet = S_OK == pdfWriter.OnlineWordToPdf(sFrom, sTo, &oBufferParams) ? 0 : AVS_FILEUTILS_ERROR_CONVERT; - } - RELEASEOBJECT(pApplicationFonts); - return nRet; - } - _UINT32 bin2image( - const std::wstring &sTFileDir, BYTE *pBuffer, LONG lBufferLen, const std::wstring &sTo, const std::wstring &sTemp, const std::wstring &sThemeDir, InputParams ¶ms, - const std::wstring &sDocxDir = L"") - { - _UINT32 nRes = 0; - NSFonts::IApplicationFonts *pApplicationFonts = NSFonts::NSApplication::Create(); - initApplicationFonts(pApplicationFonts, params); - NSOnlineOfficeBinToPdf::CMetafileToRenderterRaster imageWriter(NULL); - imageWriter.SetMediaDirectory(sTFileDir); - imageWriter.SetThemesDirectory(sThemeDir); - imageWriter.SetInternalMediaDirectory(sDocxDir); - imageWriter.SetTempDirectory(sTemp); - imageWriter.SetApplication(pApplicationFonts); - if (NULL != params.m_oThumbnail) - { - InputParamsThumbnail *oThumbnail = params.m_oThumbnail; - if (NULL != oThumbnail->format) - { - imageWriter.SetRasterFormat(*oThumbnail->format); - } - if (NULL != oThumbnail->aspect) - { - imageWriter.SetSaveType(*oThumbnail->aspect); - } - if (NULL != oThumbnail->first) - { - imageWriter.SetIsOnlyFirst(*oThumbnail->first); - } - if (NULL != oThumbnail->width) - { - imageWriter.SetRasterW(*oThumbnail->width); - } - if (NULL != oThumbnail->height) - { - imageWriter.SetRasterH(*oThumbnail->height); - } - } - std::wstring sThumbnailDir; - if (imageWriter.GetIsOnlyFirst()) - { - imageWriter.SetFileName(sTo); - } - else - { - std::wstring sFileAddon = L"image" + getExtentionByRasterFormat(imageWriter.GetRasterFormat()); - if (NULL == params.m_oThumbnail->zip || *(params.m_oThumbnail->zip)) - { - sThumbnailDir = sTemp + FILE_SEPARATOR_STR + L"thumbnails"; - NSDirectory::CreateDirectory(sThumbnailDir); - imageWriter.SetFileName(sThumbnailDir + FILE_SEPARATOR_STR + sFileAddon); - } - else - { - if (!NSDirectory::Exists(sTo)) - NSDirectory::CreateDirectory(sTo); - imageWriter.SetFileName(sTo + FILE_SEPARATOR_STR + sFileAddon); - } - } - nRes = imageWriter.ConvertBuffer(pBuffer, lBufferLen) ? nRes : AVS_FILEUTILS_ERROR_CONVERT; - if (!sThumbnailDir.empty()) - { - COfficeUtils oCOfficeUtils(NULL); - nRes = S_OK == oCOfficeUtils.CompressFileOrDirectory(sThumbnailDir, sTo) ? nRes : AVS_FILEUTILS_ERROR_CONVERT; - } - RELEASEOBJECT(pApplicationFonts); - return nRes; - } - _UINT32 bin2imageBase64(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, const std::wstring &sThemeDir, InputParams ¶ms, const std::wstring &sDocxDir = L"") - { - _UINT32 nRes = 0; - NSFile::CFileBinary oFile; - if (!oFile.OpenFile(sFrom)) - return AVS_FILEUTILS_ERROR_CONVERT; - - DWORD dwFileSize = oFile.GetFileSize(); - BYTE *pFileContent = new BYTE[dwFileSize]; - if (!pFileContent) - { - oFile.CloseFile(); - return AVS_FILEUTILS_ERROR_CONVERT; - } - - DWORD dwReaded; - oFile.ReadFile(pFileContent, dwFileSize, dwReaded); - oFile.CloseFile(); - - int nBufferLen = NSBase64::Base64DecodeGetRequiredLength(dwFileSize); - BYTE *pBuffer = new BYTE[nBufferLen]; - if (!pBuffer) - { - RELEASEARRAYOBJECTS(pFileContent); - return AVS_FILEUTILS_ERROR_CONVERT; - } - - if (NSBase64::Base64Decode((const char *)pFileContent, dwFileSize, pBuffer, &nBufferLen)) - { - std::wstring sTFileDir = NSDirectory::GetFolderPath(sFrom); - nRes = bin2image(sTFileDir, pBuffer, nBufferLen, sTo, sTemp, sThemeDir, params, sDocxDir); - } - else - { - nRes = AVS_FILEUTILS_ERROR_CONVERT; - } - - RELEASEARRAYOBJECTS(pBuffer); - RELEASEARRAYOBJECTS(pFileContent); - - return nRes; - } - // doct_bin -> epub - _UINT32 doct_bin2epub( - NSDoctRenderer::DoctRendererFormat::FormatFile eFromType, const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, const std::wstring &sThemeDir, InputParams ¶ms, - const std::wstring &sDocxDir = L"") - { - _UINT32 nRes = 0; - NSDoctRenderer::DoctRendererFormat::FormatFile eToType = NSDoctRenderer::DoctRendererFormat::FormatFile::HTML; - std::wstring sFileFromDir = NSDirectory::GetFolderPath(sFrom); - std::wstring sImagesDirectory = sFileFromDir + FILE_SEPARATOR_STR + L"media"; - std::wstring sHtmlFile = sTemp + FILE_SEPARATOR_STR + L"index.html"; - if (!NSDirectory::Exists(sImagesDirectory)) - NSDirectory::CreateDirectory(sImagesDirectory); - NSDoctRenderer::CDoctrenderer oDoctRenderer(NULL != params.m_sAllFontsPath ? *params.m_sAllFontsPath : L""); - std::wstring sXml = getDoctXml(eFromType, eToType, sFrom, sHtmlFile, sImagesDirectory, sThemeDir, -1, L"", params); - std::wstring sResult; - oDoctRenderer.Execute(sXml, sResult); - if (sResult.find(L"error") != std::wstring::npos) - { - std::wcerr << L"DoctRenderer:" << sResult << std::endl; - nRes = AVS_FILEUTILS_ERROR_CONVERT; - } - else - { - CEpubFile oFile; - std::wstring sEpubTemp = sTemp + FILE_SEPARATOR_STR + L"tmp"; - NSDirectory::CreateDirectory(sEpubTemp); - oFile.SetTempDirectory(sEpubTemp); - if (S_FALSE == oFile.FromHtml(sHtmlFile, sTo, params.m_sTitle ? *params.m_sTitle : L"")) - nRes = AVS_FILEUTILS_ERROR_CONVERT; - } - return nRes; - } - // doct_bin -> fb2 - _UINT32 doct_bin2fb( - NSDoctRenderer::DoctRendererFormat::FormatFile eFromType, const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, const std::wstring &sThemeDir, InputParams ¶ms, - const std::wstring &sDocxDir = L"") - { - _UINT32 nRes = 0; - NSDoctRenderer::DoctRendererFormat::FormatFile eToType = NSDoctRenderer::DoctRendererFormat::FormatFile::HTML; - std::wstring sFileFromDir = NSDirectory::GetFolderPath(sFrom); - std::wstring sImagesDirectory = sFileFromDir + FILE_SEPARATOR_STR + L"media"; - std::wstring sHtmlFile = sTemp + FILE_SEPARATOR_STR + L"index.html"; - if (!NSDirectory::Exists(sImagesDirectory)) - NSDirectory::CreateDirectory(sImagesDirectory); - NSDoctRenderer::CDoctrenderer oDoctRenderer(NULL != params.m_sAllFontsPath ? *params.m_sAllFontsPath : L""); - std::wstring sXml = getDoctXml(eFromType, eToType, sFrom, sHtmlFile, sImagesDirectory, sThemeDir, -1, L"", params); - std::wstring sResult; - oDoctRenderer.Execute(sXml, sResult); - if (sResult.find(L"error") != std::wstring::npos) - { - std::wcerr << L"DoctRenderer:" << sResult << std::endl; - nRes = AVS_FILEUTILS_ERROR_CONVERT; - } - else - { - CFb2File fb2File; - fb2File.SetTmpDirectory(sTemp); - if (S_FALSE == fb2File.FromHtml(sHtmlFile, sTo, params.m_sTitle ? *params.m_sTitle : L"")) - nRes = AVS_FILEUTILS_ERROR_CONVERT; - } - return nRes; - } - // doct_bin -> html - _UINT32 doct_bin2html( - NSDoctRenderer::DoctRendererFormat::FormatFile eFromType, const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, bool bPaid, const std::wstring &sThemeDir, - InputParams ¶ms, const std::wstring &sDocxDir = L"") - { - _UINT32 nRes = 0; - NSDoctRenderer::DoctRendererFormat::FormatFile eToType = NSDoctRenderer::DoctRendererFormat::FormatFile::HTML; - std::wstring sFileFromDir = NSDirectory::GetFolderPath(sFrom); - std::wstring sImagesDirectory = sFileFromDir + FILE_SEPARATOR_STR + L"media"; - std::wstring sHtmlFile = sTemp + FILE_SEPARATOR_STR + L"index.html"; - if (!NSDirectory::Exists(sImagesDirectory)) - NSDirectory::CreateDirectory(sImagesDirectory); - NSDoctRenderer::CDoctrenderer oDoctRenderer(NULL != params.m_sAllFontsPath ? *params.m_sAllFontsPath : L""); - std::wstring sXml = getDoctXml(eFromType, eToType, sFrom, sHtmlFile, sImagesDirectory, sThemeDir, -1, L"", params); - std::wstring sResult; - oDoctRenderer.Execute(sXml, sResult); - if (sResult.find(L"error") != std::wstring::npos) - { - std::wcerr << L"DoctRenderer:" << sResult << std::endl; - nRes = AVS_FILEUTILS_ERROR_CONVERT; - } - else if (!NSFile::CFileBinary::Copy(sHtmlFile, sTo)) - nRes = AVS_FILEUTILS_ERROR_CONVERT; - return nRes; - } - // doct_bin -> html_zip - _UINT32 doct_bin2html_zip( - NSDoctRenderer::DoctRendererFormat::FormatFile eFromType, const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, bool bPaid, const std::wstring &sThemeDir, - InputParams ¶ms, const std::wstring &sDocxDir = L"") - { - _UINT32 nRes = 0; - NSDoctRenderer::DoctRendererFormat::FormatFile eToType = NSDoctRenderer::DoctRendererFormat::FormatFile::HTML; - std::wstring sFileFromDir = NSDirectory::GetFolderPath(sFrom); - std::wstring sImagesDirectory = sFileFromDir + FILE_SEPARATOR_STR + L"media"; - std::wstring sHtmlFile = sTemp + FILE_SEPARATOR_STR + L"index.html"; - if (!NSDirectory::Exists(sImagesDirectory)) - NSDirectory::CreateDirectory(sImagesDirectory); - NSDoctRenderer::CDoctrenderer oDoctRenderer(NULL != params.m_sAllFontsPath ? *params.m_sAllFontsPath : L""); - std::wstring sXml = getDoctXml(eFromType, eToType, sFrom, sHtmlFile, sImagesDirectory, sThemeDir, -1, L"", params); - std::wstring sResult; - oDoctRenderer.Execute(sXml, sResult); - if (sResult.find(L"error") != std::wstring::npos) - { - std::wcerr << L"DoctRenderer:" << sResult << std::endl; - nRes = AVS_FILEUTILS_ERROR_CONVERT; - } - else - { - COfficeUtils oZip; - if (S_FALSE == oZip.CompressFileOrDirectory(sHtmlFile, sTo)) - nRes = AVS_FILEUTILS_ERROR_CONVERT; - } - return nRes; - } - // doct_bin -> pdf - _UINT32 doct_bin2pdf( - NSDoctRenderer::DoctRendererFormat::FormatFile eFromType, const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, bool bPaid, const std::wstring &sThemeDir, - InputParams ¶ms, const std::wstring &sDocxDir = L"") - { - _UINT32 nRes = 0; - NSDoctRenderer::DoctRendererFormat::FormatFile eToType = NSDoctRenderer::DoctRendererFormat::FormatFile::PDF; - std::wstring sTFileDir = NSDirectory::GetFolderPath(sFrom); - std::wstring sImagesDirectory = sTFileDir + FILE_SEPARATOR_STR + _T("media"); - std::wstring sPdfBinFile = sTFileDir + FILE_SEPARATOR_STR + _T("pdf.bin"); - NSDoctRenderer::CDoctrenderer oDoctRenderer(NULL != params.m_sAllFontsPath ? *params.m_sAllFontsPath : _T("")); - std::wstring sXml = getDoctXml(eFromType, eToType, sFrom, sPdfBinFile, sImagesDirectory, sThemeDir, -1, _T(""), params); - std::wstring sResult; - bool bRes = oDoctRenderer.Execute(sXml, sResult); - if (sResult.find(L"error") != std::wstring::npos) - { - std::wcerr << _T("DoctRenderer:") << sResult << std::endl; - nRes = AVS_FILEUTILS_ERROR_CONVERT; - } - else - { - NSFonts::IApplicationFonts *pApplicationFonts = NSFonts::NSApplication::Create(); - initApplicationFonts(pApplicationFonts, params); - - CPdfFile pdfWriter(pApplicationFonts); - pdfWriter.CreatePdf(params.getIsPDFA()); - pdfWriter.SetTempDirectory(sTemp); - pdfWriter.SetDocumentInfo(params.getTitle(), L"", L"", L""); - - CConvertFromBinParams oBufferParams; - oBufferParams.m_sThemesDirectory = sThemeDir; - oBufferParams.m_sInternalMediaDirectory = sDocxDir; - - std::wstring documentID = params.getDocumentID(); - if (false == documentID.empty()) - pdfWriter.SetDocumentID(documentID); - - std::wstring password = params.getSavePassword(); - if (false == password.empty()) - pdfWriter.SetPassword(password); - - int nReg = (bPaid == false) ? 0 : 1; - nRes = (S_OK == pdfWriter.OnlineWordToPdfFromBinary(sPdfBinFile, sTo, &oBufferParams)) ? nRes : AVS_FILEUTILS_ERROR_CONVERT; - RELEASEOBJECT(pApplicationFonts); - } - // удаляем sPdfBinFile, потому что он не в Temp - if (NSFile::CFileBinary::Exists(sPdfBinFile)) - NSFile::CFileBinary::Remove(sPdfBinFile); - return nRes; - } - // doct_bin -> image - _UINT32 doct_bin2image( - NSDoctRenderer::DoctRendererFormat::FormatFile eFromType, const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, bool bPaid, const std::wstring &sThemeDir, - InputParams ¶ms, const std::wstring &sDocxDir = L"") - { - _UINT32 nRes = 0; - NSDoctRenderer::DoctRendererFormat::FormatFile eToType = NSDoctRenderer::DoctRendererFormat::FormatFile::IMAGE; - std::wstring sTFileDir = NSDirectory::GetFolderPath(sFrom); - std::wstring sImagesDirectory = sTFileDir + FILE_SEPARATOR_STR + _T("media"); - std::wstring sPdfBinFile = sTFileDir + FILE_SEPARATOR_STR + _T("pdf.bin"); - NSDoctRenderer::CDoctrenderer oDoctRenderer(NULL != params.m_sAllFontsPath ? *params.m_sAllFontsPath : _T("")); - std::wstring sXml = getDoctXml(eFromType, eToType, sFrom, sPdfBinFile, sImagesDirectory, sThemeDir, -1, _T(""), params); - std::wstring sResult; - bool bRes = oDoctRenderer.Execute(sXml, sResult); - if (-1 != sResult.find(_T("error"))) - { - std::wcerr << _T("DoctRenderer:") << sResult << std::endl; - nRes = AVS_FILEUTILS_ERROR_CONVERT; - } - else - { - BYTE *pData = NULL; - DWORD nBytesCount; - if (NSFile::CFileBinary::ReadAllBytes(sPdfBinFile, &pData, nBytesCount)) - { - nRes = 0 == bin2image(sTFileDir, pData, nBytesCount, sTo, sTemp, sThemeDir, params, sDocxDir) ? nRes : AVS_FILEUTILS_ERROR_CONVERT; - RELEASEARRAYOBJECTS(pData); - } - else - { - nRes = AVS_FILEUTILS_ERROR_CONVERT; - } - } - // delete sPdfBinFile, because it is not in Temp - if (NSFile::CFileBinary::Exists(sPdfBinFile)) - NSFile::CFileBinary::Remove(sPdfBinFile); - return nRes; - } - - // ppsx -> pptx - _UINT32 ppsx2pptx(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - std::wstring sTempUnpackedPPTX = sTemp + FILE_SEPARATOR_STR + _T("pptx_unpacked"); - NSDirectory::CreateDirectory(sTempUnpackedPPTX); - - _UINT32 nRes = ppsx2pptx_dir(sFrom, sTempUnpackedPPTX, params); - if (SUCCEEDED_X2T(nRes)) - { - COfficeUtils oCOfficeUtils(NULL); - if (S_OK == oCOfficeUtils.CompressFileOrDirectory(sTempUnpackedPPTX, sTo, true)) - return 0; - } - return AVS_FILEUTILS_ERROR_CONVERT; - } - _UINT32 ppsx2pptx_dir(const std::wstring &sFrom, const std::wstring &sTo, InputParams ¶ms) - { - COfficeUtils oCOfficeUtils(NULL); - if (S_OK == oCOfficeUtils.ExtractToDirectory(sFrom, sTo, NULL, 0)) - { - std::wstring sContentTypesPath = sTo + FILE_SEPARATOR_STR + _T("[Content_Types].xml"); - if (NSFile::CFileBinary::Exists(sContentTypesPath)) - { - std::wstring sData; - if (NSFile::CFileBinary::ReadAllTextUtf8(sContentTypesPath, sData)) - { - std::wstring sCTFrom = _T("application/vnd.openxmlformats-officedocument.presentationml.slideshow.main+xml"); - std::wstring sCTTo = _T("application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml"); - - sData = string_replaceAll(sData, sCTFrom, sCTTo); - - if (NSFile::CFileBinary::SaveToFile(sContentTypesPath, sData, true)) - { - return 0; - } - } - } - } - return AVS_FILEUTILS_ERROR_CONVERT; - } - // pptm -> pptx - _UINT32 pptm2pptx(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - std::wstring sTempUnpackedPPTX = sTemp + FILE_SEPARATOR_STR + _T("pptx_unpacked"); - NSDirectory::CreateDirectory(sTempUnpackedPPTX); - - _UINT32 nRes = pptm2pptx_dir(sFrom, sTempUnpackedPPTX, params); - if (SUCCEEDED_X2T(nRes)) - { - COfficeUtils oCOfficeUtils(NULL); - if (S_OK == oCOfficeUtils.CompressFileOrDirectory(sTempUnpackedPPTX, sTo, true)) - return 0; - } - return AVS_FILEUTILS_ERROR_CONVERT; - } - _UINT32 pptm2pptx_dir(const std::wstring &sFrom, const std::wstring &sTo, InputParams ¶ms) - { - COfficeUtils oCOfficeUtils(NULL); - if (S_OK == oCOfficeUtils.ExtractToDirectory(sFrom, sTo, NULL, 0)) - { - std::wstring sContentTypesPath = sTo + FILE_SEPARATOR_STR + _T("[Content_Types].xml"); - if (NSFile::CFileBinary::Exists(sContentTypesPath)) - { - std::wstring sData; - if (NSFile::CFileBinary::ReadAllTextUtf8(sContentTypesPath, sData)) - { - std::wstring sCTFrom = _T("application/vnd.ms-powerpoint.presentation.macroEnabled.main+xml"); - std::wstring sCTTo = _T("application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml"); - sData = string_replaceAll(sData, sCTFrom, sCTTo); - - sCTFrom = L""; - sData = string_replaceAll(sData, sCTFrom, L""); - - sCTFrom = L""; - sData = string_replaceAll(sData, sCTFrom, L""); - - if (NSFile::CFileBinary::SaveToFile(sContentTypesPath, sData, true) == false) - { - return AVS_FILEUTILS_ERROR_CONVERT; - } - } - } - std::wstring sPresentationRelsPath = sTo + FILE_SEPARATOR_STR + L"ppt" + FILE_SEPARATOR_STR + L"_rels" + FILE_SEPARATOR_STR + L"presentation.xml.rels"; - if (NSFile::CFileBinary::Exists(sPresentationRelsPath)) - { - std::wstring sData; - if (NSFile::CFileBinary::ReadAllTextUtf8(sPresentationRelsPath, sData)) - { - size_t pos = sData.find(L"vbaProject.bin"); - if (pos != std::wstring::npos) - { - size_t pos1 = sData.rfind(L"<", pos); - size_t pos2 = sData.find(L">", pos); - - if (pos1 != std::wstring::npos && pos2 != std::wstring::npos) - { - sData.erase(sData.begin() + pos1, sData.begin() + pos2 + 1); - } - } - if (NSFile::CFileBinary::SaveToFile(sPresentationRelsPath, sData, true) == false) - { - return AVS_FILEUTILS_ERROR_CONVERT; - } - } - } - std::wstring sVbaProjectPath = sTo + FILE_SEPARATOR_STR + L"ppt" + FILE_SEPARATOR_STR + L"vbaProject.bin"; - NSFile::CFileBinary::Remove(sVbaProjectPath); - } - return 0; - } - // potm -> pptx - _UINT32 potm2pptx(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - std::wstring sTempUnpackedPPTX = sTemp + FILE_SEPARATOR_STR + _T("pptx_unpacked"); - NSDirectory::CreateDirectory(sTempUnpackedPPTX); - - _UINT32 nRes = potm2pptx_dir(sFrom, sTempUnpackedPPTX, params); - if (SUCCEEDED_X2T(nRes)) - { - COfficeUtils oCOfficeUtils(NULL); - if (S_OK == oCOfficeUtils.CompressFileOrDirectory(sTempUnpackedPPTX, sTo, true)) - return 0; - } - return AVS_FILEUTILS_ERROR_CONVERT; - } - _UINT32 potm2pptx_dir(const std::wstring &sFrom, const std::wstring &sTo, InputParams ¶ms) - { - COfficeUtils oCOfficeUtils(NULL); - if (S_OK == oCOfficeUtils.ExtractToDirectory(sFrom, sTo, NULL, 0)) - { - std::wstring sContentTypesPath = sTo + FILE_SEPARATOR_STR + _T("[Content_Types].xml"); - if (NSFile::CFileBinary::Exists(sContentTypesPath)) - { - std::wstring sData; - if (NSFile::CFileBinary::ReadAllTextUtf8(sContentTypesPath, sData)) - { - std::wstring sCTFrom = _T("application/vnd.ms-powerpoint.template.macroEnabled.main+xml"); - std::wstring sCTTo = _T("application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml"); - sData = string_replaceAll(sData, sCTFrom, sCTTo); - - sCTFrom = L""; - sData = string_replaceAll(sData, sCTFrom, L""); - - sCTFrom = L""; - sData = string_replaceAll(sData, sCTFrom, L""); - - if (NSFile::CFileBinary::SaveToFile(sContentTypesPath, sData, true) == false) - { - return AVS_FILEUTILS_ERROR_CONVERT; - } - } - } - std::wstring sPresentationRelsPath = sTo + FILE_SEPARATOR_STR + L"ppt" + FILE_SEPARATOR_STR + L"_rels" + FILE_SEPARATOR_STR + L"presentation.xml.rels"; - if (NSFile::CFileBinary::Exists(sPresentationRelsPath)) - { - std::wstring sData; - if (NSFile::CFileBinary::ReadAllTextUtf8(sPresentationRelsPath, sData)) - { - size_t pos = sData.find(L"vbaProject.bin"); - if (pos != std::wstring::npos) - { - size_t pos1 = sData.rfind(L"<", pos); - size_t pos2 = sData.find(L">", pos); - - if (pos1 != std::wstring::npos && pos2 != std::wstring::npos) - { - sData.erase(sData.begin() + pos1, sData.begin() + pos2 + 1); - } - } - if (NSFile::CFileBinary::SaveToFile(sPresentationRelsPath, sData, true) == false) - { - return AVS_FILEUTILS_ERROR_CONVERT; - } - } - } - std::wstring sVbaProjectPath = sTo + FILE_SEPARATOR_STR + L"ppt" + FILE_SEPARATOR_STR + L"vbaProject.bin"; - NSFile::CFileBinary::Remove(sVbaProjectPath); - } - return 0; - } - // ppsm -> pptx - _UINT32 ppsm2pptx(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - std::wstring sTempUnpackedPPTX = sTemp + FILE_SEPARATOR_STR + _T("pptx_unpacked"); - NSDirectory::CreateDirectory(sTempUnpackedPPTX); - - _UINT32 nRes = ppsm2pptx_dir(sFrom, sTempUnpackedPPTX, params); - if (SUCCEEDED_X2T(nRes)) - { - COfficeUtils oCOfficeUtils(NULL); - if (S_OK == oCOfficeUtils.CompressFileOrDirectory(sTempUnpackedPPTX, sTo, true)) - return 0; - } - return AVS_FILEUTILS_ERROR_CONVERT; - } - _UINT32 ppsm2pptx_dir(const std::wstring &sFrom, const std::wstring &sTo, InputParams ¶ms) - { - COfficeUtils oCOfficeUtils(NULL); - if (S_OK == oCOfficeUtils.ExtractToDirectory(sFrom, sTo, NULL, 0)) - { - std::wstring sContentTypesPath = sTo + FILE_SEPARATOR_STR + _T("[Content_Types].xml"); - if (NSFile::CFileBinary::Exists(sContentTypesPath)) - { - std::wstring sData; - if (NSFile::CFileBinary::ReadAllTextUtf8(sContentTypesPath, sData)) - { - std::wstring sCTFrom = _T("application/vnd.ms-powerpoint.slideshow.macroEnabled.main+xml"); - std::wstring sCTTo = _T("application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml"); - sData = string_replaceAll(sData, sCTFrom, sCTTo); - - sCTFrom = L""; - sData = string_replaceAll(sData, sCTFrom, L""); - - sCTFrom = L""; - sData = string_replaceAll(sData, sCTFrom, L""); - - if (NSFile::CFileBinary::SaveToFile(sContentTypesPath, sData, true) == false) - { - return AVS_FILEUTILS_ERROR_CONVERT; - } - } - } - std::wstring sPresentationRelsPath = sTo + FILE_SEPARATOR_STR + L"ppt" + FILE_SEPARATOR_STR + L"_rels" + FILE_SEPARATOR_STR + L"presentation.xml.rels"; - if (NSFile::CFileBinary::Exists(sPresentationRelsPath)) - { - std::wstring sData; - if (NSFile::CFileBinary::ReadAllTextUtf8(sPresentationRelsPath, sData)) - { - size_t pos = sData.find(L"vbaProject.bin"); - if (pos != std::wstring::npos) - { - size_t pos1 = sData.rfind(L"<", pos); - size_t pos2 = sData.find(L">", pos); - - if (pos1 != std::wstring::npos && pos2 != std::wstring::npos) - { - sData.erase(sData.begin() + pos1, sData.begin() + pos2 + 1); - } - } - if (NSFile::CFileBinary::SaveToFile(sPresentationRelsPath, sData, true) == false) - { - return AVS_FILEUTILS_ERROR_CONVERT; - } - } - } - std::wstring sVbaProjectPath = sTo + FILE_SEPARATOR_STR + L"ppt" + FILE_SEPARATOR_STR + L"vbaProject.bin"; - NSFile::CFileBinary::Remove(sVbaProjectPath); - } - return 0; - } - // potx -> pptx - _UINT32 potx2pptx(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - std::wstring sTempUnpackedPPTX = sTemp + FILE_SEPARATOR_STR + _T("pptx_unpacked"); - NSDirectory::CreateDirectory(sTempUnpackedPPTX); - - _UINT32 nRes = potx2pptx_dir(sFrom, sTempUnpackedPPTX, params); - if (SUCCEEDED_X2T(nRes)) - { - COfficeUtils oCOfficeUtils(NULL); - if (S_OK == oCOfficeUtils.CompressFileOrDirectory(sTempUnpackedPPTX, sTo, true)) - return 0; - } - return AVS_FILEUTILS_ERROR_CONVERT; - } - _UINT32 potx2pptx_dir(const std::wstring &sFrom, const std::wstring &sTo, InputParams ¶ms) - { - COfficeUtils oCOfficeUtils(NULL); - if (S_OK == oCOfficeUtils.ExtractToDirectory(sFrom, sTo, NULL, 0)) - { - std::wstring sContentTypesPath = sTo + FILE_SEPARATOR_STR + _T("[Content_Types].xml"); - if (NSFile::CFileBinary::Exists(sContentTypesPath)) - { - std::wstring sData; - if (NSFile::CFileBinary::ReadAllTextUtf8(sContentTypesPath, sData)) - { - std::wstring sCTFrom = _T("application/vnd.openxmlformats-officedocument.presentationml.template.main+xml"); - std::wstring sCTTo = _T("application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml"); - - sData = string_replaceAll(sData, sCTFrom, sCTTo); - - if (NSFile::CFileBinary::SaveToFile(sContentTypesPath, sData, true)) - { - return 0; - } - } - } - } - return AVS_FILEUTILS_ERROR_CONVERT; - } - // potm -> pptm - _UINT32 potm2pptm(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - std::wstring sTempUnpackedPPTM = sTemp + FILE_SEPARATOR_STR + _T("pptm_unpacked"); - NSDirectory::CreateDirectory(sTempUnpackedPPTM); - - _UINT32 nRes = potm2pptm_dir(sFrom, sTempUnpackedPPTM, params); - if (SUCCEEDED_X2T(nRes)) - { - COfficeUtils oCOfficeUtils(NULL); - if (S_OK == oCOfficeUtils.CompressFileOrDirectory(sTempUnpackedPPTM, sTo, true)) - return 0; - } - return AVS_FILEUTILS_ERROR_CONVERT; - } - _UINT32 potm2pptm_dir(const std::wstring &sFrom, const std::wstring &sTo, InputParams ¶ms) - { - COfficeUtils oCOfficeUtils(NULL); - if (S_OK == oCOfficeUtils.ExtractToDirectory(sFrom, sTo, NULL, 0)) - { - std::wstring sContentTypesPath = sTo + FILE_SEPARATOR_STR + _T("[Content_Types].xml"); - if (NSFile::CFileBinary::Exists(sContentTypesPath)) - { - std::wstring sData; - if (NSFile::CFileBinary::ReadAllTextUtf8(sContentTypesPath, sData)) - { - std::wstring sCTFrom = _T("application/vnd.ms-powerpoint.template.macroEnabled.main+xml"); - std::wstring sCTTo = _T("application/vnd.ms-powerpoint.presentation.macroEnabled.main+xml"); - - sData = string_replaceAll(sData, sCTFrom, sCTTo); - - if (NSFile::CFileBinary::SaveToFile(sContentTypesPath, sData, true)) - { - return 0; - } - } - } - } - return AVS_FILEUTILS_ERROR_CONVERT; - } - // ppsm -> pptm - _UINT32 ppsm2pptm(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - std::wstring sTempUnpackedPPTM = sTemp + FILE_SEPARATOR_STR + _T("pptm_unpacked"); - NSDirectory::CreateDirectory(sTempUnpackedPPTM); - - _UINT32 nRes = ppsm2pptm_dir(sFrom, sTempUnpackedPPTM, params); - if (SUCCEEDED_X2T(nRes)) - { - COfficeUtils oCOfficeUtils(NULL); - if (S_OK == oCOfficeUtils.CompressFileOrDirectory(sTempUnpackedPPTM, sTo, true)) - return 0; - } - return AVS_FILEUTILS_ERROR_CONVERT; - } - _UINT32 ppsm2pptm_dir(const std::wstring &sFrom, const std::wstring &sTo, InputParams ¶ms) - { - COfficeUtils oCOfficeUtils(NULL); - if (S_OK == oCOfficeUtils.ExtractToDirectory(sFrom, sTo, NULL, 0)) - { - std::wstring sContentTypesPath = sTo + FILE_SEPARATOR_STR + _T("[Content_Types].xml"); - if (NSFile::CFileBinary::Exists(sContentTypesPath)) - { - std::wstring sData; - if (NSFile::CFileBinary::ReadAllTextUtf8(sContentTypesPath, sData)) - { - std::wstring sCTFrom = _T("application/vnd.ms-powerpoint.slideshow.macroEnabled.main+xml"); - std::wstring sCTTo = _T("application/vnd.ms-powerpoint.presentation.macroEnabled.main+xml"); - - sData = string_replaceAll(sData, sCTFrom, sCTTo); - - if (NSFile::CFileBinary::SaveToFile(sContentTypesPath, sData, true)) - { - return 0; - } - } - } - } - return AVS_FILEUTILS_ERROR_CONVERT; - } - // ppt -> pptx - _UINT32 ppt2pptx(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - std::wstring sResultPptxDir = sTemp + FILE_SEPARATOR_STR + _T("pptx_unpacked"); - - NSDirectory::CreateDirectory(sResultPptxDir); - - _UINT32 nRes = ppt2pptx_dir(sFrom, sResultPptxDir, sTemp, params); - - nRes = processEncryptionError(nRes, sFrom, params); - - if (SUCCEEDED_X2T(nRes)) - { - nRes = dir2zipMscrypt(sResultPptxDir, sTo, sTemp, params); - } - return nRes; - } - _UINT32 ppt2pptx_dir(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - COfficePPTFile pptFile; - - pptFile.put_TempDirectory(sTemp); - - params.m_bMacro = false; - long nRes = pptFile.LoadFromFile(sFrom, sTo, params.getPassword(), params.m_bMacro); - nRes = processEncryptionError(nRes, sFrom, params); - return nRes; - } - // ppt -> pptm - _UINT32 ppt2pptm(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - std::wstring sResultPptxDir = sTemp + FILE_SEPARATOR_STR + _T("pptx_unpacked"); - - NSDirectory::CreateDirectory(sResultPptxDir); - - _UINT32 nRes = ppt2pptm_dir(sFrom, sResultPptxDir, sTemp, params); - - if (SUCCEEDED_X2T(nRes)) - { - COfficeUtils oCOfficeUtils(NULL); - if (S_OK == oCOfficeUtils.CompressFileOrDirectory(sResultPptxDir, sTo, true)) - return 0; - } - return nRes; - } - _UINT32 ppt2pptm_dir(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - COfficePPTFile pptFile; - - pptFile.put_TempDirectory(sTemp); - - params.m_bMacro = true; - _UINT32 nRes = pptFile.LoadFromFile(sFrom, sTo, params.getPassword(), params.m_bMacro); - nRes = processEncryptionError(nRes, sFrom, params); - return nRes; - } - // ppt -> pptt - _UINT32 ppt2pptt(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - std::wstring sResultPpttDir = sTemp + FILE_SEPARATOR_STR + _T("pptt_unpacked"); - std::wstring sTempPpttFileEditor = sResultPpttDir + FILE_SEPARATOR_STR + _T("Editor.bin"); - - NSDirectory::CreateDirectory(sResultPpttDir); - - _UINT32 nRes = ppt2pptt_bin(sFrom, sTempPpttFileEditor, sTemp, params); - - if (SUCCEEDED_X2T(nRes)) - { - // zip pptt folder to output file - COfficeUtils oCOfficeUtils(NULL); - nRes = (S_OK == oCOfficeUtils.CompressFileOrDirectory(sResultPpttDir, sTo)) ? nRes : AVS_FILEUTILS_ERROR_CONVERT; - } - return nRes; - } - // ppt -> pptt_bin - _UINT32 ppt2pptt_bin(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - // unzip pptx to temp folder - std::wstring sTempUnpackedPPTX = sTemp + FILE_SEPARATOR_STR + _T("pptx_unpacked") + FILE_SEPARATOR_STR; // leading slash is very important! - - NSDirectory::CreateDirectory(sTempUnpackedPPTX); - - COfficePPTFile pptFile; - - pptFile.put_TempDirectory(sTemp); - - params.m_bMacro = true; - _UINT32 nRes = pptFile.LoadFromFile(sFrom, sTempUnpackedPPTX, params.getPassword(), params.m_bMacro); - - nRes = processEncryptionError(nRes, sFrom, params); - if (SUCCEEDED_X2T(nRes)) - { - // convert unzipped pptx to unzipped pptt - CPPTXFile *pptx_file = new CPPTXFile(); - - if (pptx_file) - { - pptx_file->SetFontDir(params.getFontPath()); - nRes = (S_OK == pptx_file->OpenFileToPPTY(sTempUnpackedPPTX, sTo)) ? nRes : AVS_FILEUTILS_ERROR_CONVERT; - - delete pptx_file; - } - return nRes; - } - return nRes; - } - - // pptx -> odp - _UINT32 pptx2odp(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - std::wstring sTempUnpackedPPTX = sTemp + FILE_SEPARATOR_STR + _T("pptx_unpacked"); - NSDirectory::CreateDirectory(sTempUnpackedPPTX); - - COfficeUtils oCOfficeUtils(NULL); - if (S_OK == oCOfficeUtils.ExtractToDirectory(sFrom, sTempUnpackedPPTX, NULL, 0)) - { - return pptx_dir2odp(sTempUnpackedPPTX, sTo, sTemp, params, false); // add template ??? - } - return AVS_FILEUTILS_ERROR_CONVERT; - } - // pptx_dir -> odp - _UINT32 pptx_dir2odp(const std::wstring &sPptxDir, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms, bool bTemplate) - { - std::wstring sTempUnpackedODP = sTemp + FILE_SEPARATOR_STR + _T("odp_unpacked"); - NSDirectory::CreateDirectory(sTempUnpackedODP); - - Oox2Odf::Converter converter(sPptxDir, _T("presentation"), params.getFontPath(), bTemplate, sTemp); - - _UINT32 nRes = 0; - try - { - std::wstring password = params.getSavePassword(); - std::wstring documentID = params.getDocumentID(); - - converter.convert(); - converter.write(sTempUnpackedODP, sTemp, password, documentID); - - COfficeUtils oCOfficeUtils(NULL); - nRes = (S_OK == oCOfficeUtils.CompressFileOrDirectory(sTempUnpackedODP, sTo, false, password.empty() ? Z_DEFLATED : 0)) ? 0 : AVS_FILEUTILS_ERROR_CONVERT; - } - catch (...) - { - nRes = AVS_FILEUTILS_ERROR_CONVERT; - } - return nRes; - } - // rtf -> docx - _UINT32 rtf2docx(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - std::wstring sResultDocxDir = sTemp + FILE_SEPARATOR_STR + _T("docx_unpacked"); - - NSDirectory::CreateDirectory(sResultDocxDir); - _UINT32 nRes = rtf2docx_dir(sFrom, sResultDocxDir, sTemp, params); - - if (SUCCEEDED_X2T(nRes)) - { - nRes = dir2zipMscrypt(sResultDocxDir, sTo, sTemp, params); - } - - return nRes; - } - _UINT32 rtf2docx_dir(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - RtfConvertationManager rtfConvert; - - rtfConvert.m_sTempFolder = sTemp; - rtfConvert.m_nUserLCID = (NULL != params.m_nLcid) ? *params.m_nLcid : -1; - - return 0 == rtfConvert.ConvertRtfToOOX(sFrom, sTo) ? 0 : AVS_FILEUTILS_ERROR_CONVERT; - } - - // rtf -> doct - _UINT32 rtf2doct(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - // Extract docx to temp directory - std::wstring sResultDoctDir = sTemp + FILE_SEPARATOR_STR + _T("doct_unpacked"); - std::wstring sResultDoctFileEditor = sResultDoctDir + FILE_SEPARATOR_STR + _T("Editor.bin"); - - NSDirectory::CreateDirectory(sResultDoctDir); - - _UINT32 nRes = rtf2doct_bin(sFrom, sResultDoctFileEditor, sTemp, params); - - if (SUCCEEDED_X2T(nRes)) - { - COfficeUtils oCOfficeUtils(NULL); - nRes = (S_OK == oCOfficeUtils.CompressFileOrDirectory(sResultDoctDir, sTo)) ? nRes : AVS_FILEUTILS_ERROR_CONVERT; - } - - return nRes; - } - - // rtf -> doct_bin - _UINT32 rtf2doct_bin(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - std::wstring sResultDocxDir = sTemp + FILE_SEPARATOR_STR + _T("docx_unpacked"); - - NSDirectory::CreateDirectory(sResultDocxDir); - RtfConvertationManager rtfConvert; - - rtfConvert.m_sTempFolder = sTemp; - rtfConvert.m_nUserLCID = (NULL != params.m_nLcid) ? *params.m_nLcid : -1; - - if (rtfConvert.ConvertRtfToOOX(sFrom, sResultDocxDir) == 0) - { - BinDocxRW::CDocxSerializer m_oCDocxSerializer; - - m_oCDocxSerializer.setFontDir(params.getFontPath()); - - std::wstring sXmlOptions; - _UINT32 res = m_oCDocxSerializer.saveToFile(sTo, sResultDocxDir, sXmlOptions, sTemp) ? 0 : AVS_FILEUTILS_ERROR_CONVERT; - - return res; - } - return AVS_FILEUTILS_ERROR_CONVERT; - } - - // docx -> rtf - _UINT32 docx2rtf(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - std::wstring sTempUnpackedDOCX = sTemp + FILE_SEPARATOR_STR + _T("docx_unpacked"); - NSDirectory::CreateDirectory(sTempUnpackedDOCX); - - COfficeUtils oCOfficeUtils(NULL); - if (S_OK == oCOfficeUtils.ExtractToDirectory(sFrom, sTempUnpackedDOCX, NULL, 0)) - { - return docx_dir2rtf(sTempUnpackedDOCX, sTo, sTemp, params); - } - return AVS_FILEUTILS_ERROR_CONVERT; - } - _UINT32 docx_dir2rtf(const std::wstring &sDocxDir, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - // docx folder to rtf - RtfConvertationManager rtfConvert; - - rtfConvert.m_sTempFolder = sTemp; - rtfConvert.m_nUserLCID = (NULL != params.m_nLcid) ? *params.m_nLcid : -1; - - if (rtfConvert.ConvertOOXToRtf(sTo, sDocxDir) == 0) - return 0; - return AVS_FILEUTILS_ERROR_CONVERT; - } - - // doc -> docx - _UINT32 doc2docx(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - std::wstring sResultDocxDir = sTemp + FILE_SEPARATOR_STR + _T("docx_unpacked"); - - NSDirectory::CreateDirectory(sResultDocxDir); - - _UINT32 hRes = doc2docx_dir(sFrom, sResultDocxDir, sTemp, params); - - if (SUCCEEDED_X2T(hRes)) - { - hRes = dir2zipMscrypt(sResultDocxDir, sTo, sTemp, params); - } - else if (AVS_ERROR_DRM == hRes) - { - if (!params.getDontSaveAdditional()) - { - copyOrigin(sFrom, *params.m_sFileTo); - } - hRes = AVS_FILEUTILS_ERROR_CONVERT_DRM; - } - else if (AVS_ERROR_PASSWORD == hRes) - { - hRes = AVS_FILEUTILS_ERROR_CONVERT_PASSWORD; - } - return hRes; - } - _UINT32 doc2docx_dir(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - COfficeDocFile docFile; - - docFile.m_sTempFolder = sTemp; - docFile.m_nUserLCID = (NULL != params.m_nLcid) ? *params.m_nLcid : -1; - - params.m_bMacro = false; - - _UINT32 hRes = docFile.LoadFromFile(sFrom, sTo, params.getPassword(), params.m_bMacro); - if (AVS_ERROR_DRM == hRes) - { - if (!params.getDontSaveAdditional()) - { - copyOrigin(sFrom, *params.m_sFileTo); - } - return AVS_FILEUTILS_ERROR_CONVERT_DRM; - } - else if (AVS_ERROR_PASSWORD == hRes) - { - return AVS_FILEUTILS_ERROR_CONVERT_PASSWORD; - } - return 0 == hRes ? 0 : AVS_FILEUTILS_ERROR_CONVERT; - } - - // doc -> docm - _UINT32 doc2docm(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - std::wstring sResultDocxDir = sTemp + FILE_SEPARATOR_STR + _T("docx_unpacked"); - - NSDirectory::CreateDirectory(sResultDocxDir); - - _UINT32 hRes = doc2docm_dir(sFrom, sResultDocxDir, sTemp, params); - if (SUCCEEDED_X2T(hRes)) - { - COfficeUtils oCOfficeUtils(NULL); - if (S_OK == oCOfficeUtils.CompressFileOrDirectory(sResultDocxDir, sTo, true)) - return 0; - } - else if (AVS_ERROR_DRM == hRes) - { - if (!params.getDontSaveAdditional()) - { - copyOrigin(sFrom, *params.m_sFileTo); - } - return AVS_FILEUTILS_ERROR_CONVERT_DRM; - } - else if (AVS_ERROR_PASSWORD == hRes) - { - return AVS_FILEUTILS_ERROR_CONVERT_PASSWORD; - } - return AVS_FILEUTILS_ERROR_CONVERT; - } - _UINT32 doc2docm_dir(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - COfficeDocFile docFile; - docFile.m_sTempFolder = sTemp; - docFile.m_nUserLCID = (NULL != params.m_nLcid) ? *params.m_nLcid : -1; - - params.m_bMacro = true; - - _UINT32 hRes = docFile.LoadFromFile(sFrom, sTo, params.getPassword(), params.m_bMacro); - if (AVS_ERROR_DRM == hRes) - { - if (!params.getDontSaveAdditional()) - { - copyOrigin(sFrom, *params.m_sFileTo); - } - return AVS_FILEUTILS_ERROR_CONVERT_DRM; - } - else if (AVS_ERROR_PASSWORD == hRes) - { - return AVS_FILEUTILS_ERROR_CONVERT_PASSWORD; - } - return 0 == hRes ? 0 : AVS_FILEUTILS_ERROR_CONVERT; - } - - // doc -> doct - _UINT32 doc2doct(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - // Extract docx to temp directory - std::wstring sResultDoctDir = sTemp + FILE_SEPARATOR_STR + _T("doct_unpacked"); - std::wstring sResultDoctFileEditor = sResultDoctDir + FILE_SEPARATOR_STR + _T("Editor.bin"); - - NSDirectory::CreateDirectory(sResultDoctDir); - - _UINT32 nRes = doc2doct_bin(sFrom, sResultDoctFileEditor, sTemp, params); - - if (SUCCEEDED_X2T(nRes)) - { - COfficeUtils oCOfficeUtils(NULL); - nRes = (S_OK == oCOfficeUtils.CompressFileOrDirectory(sResultDoctDir, sTo)) ? nRes : AVS_FILEUTILS_ERROR_CONVERT; - } - - return nRes; - } - - // doc -> doct_bin - _UINT32 doc2doct_bin(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - std::wstring sResultDocxDir = sTemp + FILE_SEPARATOR_STR + _T("docx_unpacked"); - - NSDirectory::CreateDirectory(sResultDocxDir); - - COfficeDocFile docFile; - docFile.m_sTempFolder = sTemp; - docFile.m_nUserLCID = (NULL != params.m_nLcid) ? *params.m_nLcid : -1; - ; - - params.m_bMacro = true; - - _UINT32 nRes = docFile.LoadFromFile(sFrom, sResultDocxDir, params.getPassword(), params.m_bMacro); - - nRes = processEncryptionError(nRes, sFrom, params); - if (SUCCEEDED_X2T(nRes)) - { - BinDocxRW::CDocxSerializer m_oCDocxSerializer; - - m_oCDocxSerializer.setFontDir(params.getFontPath()); - - std::wstring xml_options = params.getXmlOptions(); - - _UINT32 res = m_oCDocxSerializer.saveToFile(sTo, sResultDocxDir, xml_options, sTemp) ? 0 : AVS_FILEUTILS_ERROR_CONVERT; - - return res; - } - return nRes; - } - _UINT32 docx_dir2doc(const std::wstring &sDocxDir, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - return AVS_FILEUTILS_ERROR_CONVERT; - } - - // doct -> rtf - _UINT32 doct2rtf(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, const std::wstring &sThemeDir, InputParams ¶ms) - { - // Extract docx to temp directory - std::wstring sTempUnpackedDOCT = sTemp + FILE_SEPARATOR_STR + _T("doct_unpacked"); - std::wstring sTempDoctFileEditor = sTempUnpackedDOCT + FILE_SEPARATOR_STR + _T("Editor.bin"); - - NSDirectory::CreateDirectory(sTempUnpackedDOCT); - - // unzip doct to folder - COfficeUtils oCOfficeUtils(NULL); - if (S_OK != oCOfficeUtils.ExtractToDirectory(sFrom, sTempUnpackedDOCT, NULL, 0)) - return AVS_FILEUTILS_ERROR_CONVERT; - - return doct_bin2rtf(sTempDoctFileEditor, sTo, sTemp, sThemeDir, params); - } - - // bin -> rtf - _UINT32 doct_bin2rtf(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, const std::wstring &sThemeDir, InputParams ¶ms) - { - _UINT32 nRes = 0; - std::wstring sResultDocxDir = sTemp + FILE_SEPARATOR_STR + L"docx_unpacked"; - - NSDirectory::CreateDirectory(sResultDocxDir); - - std::wstring sTargetBin; - if (params.getFromChanges()) - { - params.setFromChanges(false); - nRes = apply_changes(sFrom, _T(""), NSDoctRenderer::DoctRendererFormat::FormatFile::DOCT, sThemeDir, sTargetBin, params); - } - else - sTargetBin = sFrom; - - BinDocxRW::CDocxSerializer m_oCDocxSerializer; - - m_oCDocxSerializer.setFontDir(params.getFontPath()); - - std::wstring sXmlOptions = _T(""); - std::wstring sThemePath; // will be filled by 'CreateDocxFolders' method - std::wstring sMediaPath; // will be filled by 'CreateDocxFolders' method - std::wstring sEmbedPath; // will be filled by 'CreateDocxFolders' method - - m_oCDocxSerializer.CreateDocxFolders(sResultDocxDir, sThemePath, sMediaPath, sEmbedPath); - - if (SUCCEEDED_X2T(nRes)) - { - nRes = m_oCDocxSerializer.loadFromFile(sTargetBin, sResultDocxDir, sXmlOptions, sThemePath, sMediaPath, sEmbedPath) ? nRes : AVS_FILEUTILS_ERROR_CONVERT; - if (SUCCEEDED_X2T(nRes)) - { - // docx folder to rtf - RtfConvertationManager rtfConvert; - - rtfConvert.m_sTempFolder = sTemp; - rtfConvert.m_nUserLCID = (NULL != params.m_nLcid) ? *params.m_nLcid : -1; - - nRes = rtfConvert.ConvertOOXToRtf(sTo, sResultDocxDir); - } - } - // удаляем EditorWithChanges, потому что он не в Temp - if (sFrom != sTargetBin) - NSFile::CFileBinary::Remove(sTargetBin); - return nRes; - } - // txt -> docx - _UINT32 txt2docx(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - std::wstring sResultDocxDir = sTemp + FILE_SEPARATOR_STR + _T("docx_unpacked"); - - NSDirectory::CreateDirectory(sResultDocxDir); - _UINT32 nRes = txt2docx_dir(sFrom, sResultDocxDir, sTemp, params); - if (SUCCEEDED_X2T(nRes)) - { - nRes = dir2zipMscrypt(sResultDocxDir, sTo, sTemp, params); - } - return AVS_FILEUTILS_ERROR_CONVERT; - } - _UINT32 txt2docx_dir(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - CTxtXmlFile txtFile; - - std::wstring xml_options = params.getXmlOptions(); - - return txtFile.txt_LoadFromFile(sFrom, sTo, xml_options); - } - // txt -> doct - _UINT32 txt2doct(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - std::wstring sResultDoctDir = sTemp + FILE_SEPARATOR_STR + _T("doct_unpacked"); - std::wstring sResultDoctFileEditor = sResultDoctDir + FILE_SEPARATOR_STR + _T("Editor.bin"); - - NSDirectory::CreateDirectory(sResultDoctDir); - - _UINT32 nRes = txt2doct_bin(sFrom, sResultDoctFileEditor, sTemp, params); - - if (SUCCEEDED_X2T(nRes)) - { - COfficeUtils oCOfficeUtils(NULL); - nRes = (S_OK == oCOfficeUtils.CompressFileOrDirectory(sResultDoctDir, sTo)) ? nRes : AVS_FILEUTILS_ERROR_CONVERT; - } - - return nRes; - } - - // txt -> doct_bin - _UINT32 txt2doct_bin(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - std::wstring sResultDocxDir = sTemp + FILE_SEPARATOR_STR + _T("docx_unpacked"); - - NSDirectory::CreateDirectory(sResultDocxDir); - - CTxtXmlFile txtFile; - - // txtFile.m_sTempFolder = sTemp); - - if (txtFile.txt_LoadFromFile(sFrom, sResultDocxDir, params.getXmlOptions()) == 0) - { - BinDocxRW::CDocxSerializer m_oCDocxSerializer; - - m_oCDocxSerializer.setFontDir(params.getFontPath()); - - _UINT32 res = m_oCDocxSerializer.saveToFile(sTo, sResultDocxDir, params.getXmlOptions(), sTemp) ? 0 : AVS_FILEUTILS_ERROR_CONVERT; - - return res; - } - return AVS_FILEUTILS_ERROR_CONVERT; - } - _UINT32 docx2txt(const std::wstring &sDocxDir, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - std::wstring sTempUnpackedDOCX = sTemp + FILE_SEPARATOR_STR + _T("docx_unpacked"); - NSDirectory::CreateDirectory(sTempUnpackedDOCX); - - COfficeUtils oCOfficeUtils(NULL); - if (S_OK == oCOfficeUtils.ExtractToDirectory(sDocxDir, sTempUnpackedDOCX, NULL, 0)) - { - return docx_dir2txt(sTempUnpackedDOCX, sTo, sTemp, params); - } - return AVS_FILEUTILS_ERROR_CONVERT; - } - _UINT32 docx_dir2txt(const std::wstring &sDocxDir, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - CTxtXmlFile txtFile; - - return txtFile.txt_SaveToFile(sTo, sDocxDir, params.getXmlOptions()); - } - // odf - _UINT32 odf2oot(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - std::wstring sResultDoctDir = sTemp + FILE_SEPARATOR_STR + _T("doct_unpacked"); - std::wstring sResultDoctFileEditor = sResultDoctDir + FILE_SEPARATOR_STR + _T("Editor.bin"); - - NSDirectory::CreateDirectory(sResultDoctDir); - - _UINT32 nRes = odf2oot_bin(sFrom, sResultDoctFileEditor, sTemp, params); - - if (SUCCEEDED_X2T(nRes)) - { - COfficeUtils oCOfficeUtils(NULL); - nRes = (S_OK == oCOfficeUtils.CompressFileOrDirectory(sResultDoctDir, sTo)) ? nRes : AVS_FILEUTILS_ERROR_CONVERT; - } - - return nRes; - } - - _UINT32 odf2oot_bin(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - std::wstring sTempUnpackedOdf = sTemp + FILE_SEPARATOR_STR + _T("odf_unpacked"); - std::wstring sTempUnpackedOox = sTemp + FILE_SEPARATOR_STR + _T("oox_unpacked"); - - NSDirectory::CreateDirectory(sTempUnpackedOdf); - - _UINT32 nRes = 0; +#include "lib/html.h" - COfficeUtils oCOfficeUtils(NULL); - if (S_OK == oCOfficeUtils.ExtractToDirectory(sFrom, sTempUnpackedOdf, NULL, 0)) - { - NSDirectory::CreateDirectory(sTempUnpackedOox); - - nRes = ConvertODF2OOXml(sTempUnpackedOdf, sTempUnpackedOox, params.getFontPath(), sTemp, params.getPassword()); - nRes = processEncryptionError(nRes, sFrom, params); - if (SUCCEEDED_X2T(nRes)) - { - COfficeFileFormatChecker OfficeFileFormatChecker; - - if (OfficeFileFormatChecker.isOOXFormatFile(sTempUnpackedOox, true)) - { - switch (OfficeFileFormatChecker.nFileType) - { - case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX: - case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCM: - case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOTX: - case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOTM: - case AVS_OFFICESTUDIO_FILE_DOCUMENT_OFORM: - case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCXF: - { - return docx_dir2doct_bin(sTempUnpackedOox, sTo, sTemp, params, L""); - } - break; - case AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSX: - case AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSM: - case AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLTX: - case AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLTM: - case AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSB: - { - const std::wstring &sXmlOptions = params.getXmlOptions(); - return xlsx_dir2xlst_bin(sTempUnpackedOox, sTo, params, false, L""); - } - break; - case AVS_OFFICESTUDIO_FILE_PRESENTATION_PPTX: - case AVS_OFFICESTUDIO_FILE_PRESENTATION_PPTM: - case AVS_OFFICESTUDIO_FILE_PRESENTATION_PPSX: - case AVS_OFFICESTUDIO_FILE_PRESENTATION_POTX: - case AVS_OFFICESTUDIO_FILE_PRESENTATION_POTM: - case AVS_OFFICESTUDIO_FILE_PRESENTATION_PPSM: - { - return pptx_dir2pptt_bin(sTempUnpackedOox, sTo, sTemp, params, L""); - } - break; - default: - { - nRes = AVS_FILEUTILS_ERROR_CONVERT; - } - break; - } - } - } - } - else - { - nRes = AVS_FILEUTILS_ERROR_CONVERT; - if (create_if_empty(sFrom, sTo, L"DOCY;v10;0;")) - nRes = 0; - } - return nRes; - } - _UINT32 otf2odf(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - std::wstring sTempUnpackedOdf = sTemp + FILE_SEPARATOR_STR + _T("odf_unpacked"); - NSDirectory::CreateDirectory(sTempUnpackedOdf); - - COfficeUtils oCOfficeUtils(NULL); - if (S_OK != oCOfficeUtils.ExtractToDirectory(sFrom, sTempUnpackedOdf, NULL, 0)) - return AVS_FILEUTILS_ERROR_CONVERT; - - _UINT32 nRes = ConvertOTF2ODF(sTempUnpackedOdf); - if (SUCCEEDED_X2T(nRes)) - { - COfficeUtils oCOfficeUtils(NULL); - nRes = (S_OK == oCOfficeUtils.CompressFileOrDirectory(sTempUnpackedOdf, sTo, true)) ? nRes : AVS_FILEUTILS_ERROR_CONVERT; - } - return nRes; - } - _UINT32 odf2oox(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - std::wstring sTempUnpackedOox = sTemp + FILE_SEPARATOR_STR + _T("oox_unpacked"); - NSDirectory::CreateDirectory(sTempUnpackedOox); - - _UINT32 nRes = odf2oox_dir(sFrom, sTempUnpackedOox, sTemp, params); - - if (SUCCEEDED_X2T(nRes)) - { - nRes = dir2zipMscrypt(sTempUnpackedOox, sTo, sTemp, params); - } - else - { - nRes = AVS_FILEUTILS_ERROR_CONVERT; - if (create_if_empty(sFrom, sTo, L"")) - nRes = 0; - } - return nRes; - } - _UINT32 odf2oox_dir(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - _UINT32 nRes = 0; - - std::wstring sTempUnpackedOdf = sTemp + FILE_SEPARATOR_STR + _T("odf_unpacked"); - NSDirectory::CreateDirectory(sTempUnpackedOdf); - - COfficeUtils oCOfficeUtils(NULL); - if (S_OK == oCOfficeUtils.ExtractToDirectory(sFrom, sTempUnpackedOdf, NULL, 0)) - { - nRes = ConvertODF2OOXml(sTempUnpackedOdf, sTo, params.getFontPath(), sTemp, params.getPassword()); - nRes = processEncryptionError(nRes, sFrom, params); - } - else - { - nRes = AVS_FILEUTILS_ERROR_CONVERT; - } - return nRes; - } - // odf flat - _UINT32 odf_flat2oot(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - std::wstring sResultDoctDir = sTemp + FILE_SEPARATOR_STR + _T("doct_unpacked"); - std::wstring sResultDoctFileEditor = sResultDoctDir + FILE_SEPARATOR_STR + _T("Editor.bin"); - - NSDirectory::CreateDirectory(sResultDoctDir); - - _UINT32 nRes = odf_flat2oot_bin(sFrom, sResultDoctFileEditor, sTemp, params); - - if (SUCCEEDED_X2T(nRes)) - { - COfficeUtils oCOfficeUtils(NULL); - nRes = (S_OK == oCOfficeUtils.CompressFileOrDirectory(sResultDoctDir, sTo)) ? nRes : AVS_FILEUTILS_ERROR_CONVERT; - } - - return nRes; - } - - _UINT32 odf_flat2oot_bin(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - std::wstring sTempUnpackedOox = sTemp + FILE_SEPARATOR_STR + _T("oox_unpacked"); - - NSDirectory::CreateDirectory(sTempUnpackedOox); - - _UINT32 nRes = ConvertODF2OOXml(sFrom, sTempUnpackedOox, params.getFontPath(), sTemp, params.getPassword()); - nRes = processEncryptionError(nRes, sFrom, params); - if (SUCCEEDED_X2T(nRes)) - { - BinDocxRW::CDocxSerializer m_oCDocxSerializer; - - m_oCDocxSerializer.setFontDir(params.getFontPath()); - - nRes = m_oCDocxSerializer.saveToFile(sTo, sTempUnpackedOox, params.getXmlOptions(), sTemp) ? 0 : AVS_FILEUTILS_ERROR_CONVERT; - } - - return nRes; - } - _UINT32 odf_flat2oox(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - std::wstring sTempUnpackedOox = sTemp + FILE_SEPARATOR_STR + _T("oox_unpacked"); - NSDirectory::CreateDirectory(sTempUnpackedOox); - - _UINT32 nRes = odf_flat2oox_dir(sFrom, sTempUnpackedOox, sTemp, params); - - if (SUCCEEDED_X2T(nRes)) - { - nRes = dir2zipMscrypt(sTempUnpackedOox, sTo, sTemp, params); - } - - return nRes; - } - _UINT32 odf_flat2oox_dir(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - _UINT32 nRes = ConvertODF2OOXml(sFrom, sTo, params.getFontPath(), sTemp, params.getPassword()); - nRes = processEncryptionError(nRes, sFrom, params); - return nRes; - } - // docx -> odt - _UINT32 docx2odt(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - std::wstring sTempUnpackedDOCX = sTemp + FILE_SEPARATOR_STR + _T("docx_unpacked"); - NSDirectory::CreateDirectory(sTempUnpackedDOCX); - - COfficeUtils oCOfficeUtils(NULL); - if (S_OK == oCOfficeUtils.ExtractToDirectory(sFrom, sTempUnpackedDOCX, NULL, 0)) - { - return docx_dir2odt(sTempUnpackedDOCX, sTo, sTemp, params, false); // add Template ???? - } - return AVS_FILEUTILS_ERROR_CONVERT; - } - // docxflat -> docx - _UINT32 docxflat2docx(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - std::wstring sTempUnpackedDOCX = sTemp + FILE_SEPARATOR_STR + L"docx_unpacked"; - NSDirectory::CreateDirectory(sTempUnpackedDOCX); - - BinDocxRW::CDocxSerializer m_oCDocxSerializer; - - if (m_oCDocxSerializer.convertFlat(sFrom, sTempUnpackedDOCX)) - { - _UINT32 nRes = dir2zipMscrypt(sTempUnpackedDOCX, sTo, sTemp, params); - if (SUCCEEDED_X2T(nRes)) - return S_OK; - } - return AVS_FILEUTILS_ERROR_CONVERT; - } - // docxflat -> odt - _UINT32 docxflat2odt(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - std::wstring sTempUnpackedODT = sTemp + FILE_SEPARATOR_STR + L"odt_unpacked"; - NSDirectory::CreateDirectory(sTempUnpackedODT); - - Oox2Odf::Converter converter(sFrom, L"text", params.getFontPath(), false, sTemp); - - _UINT32 nRes = 0; - try - { - std::wstring password = params.getSavePassword(); - std::wstring documentID = params.getDocumentID(); - - converter.convert(); - converter.write(sTempUnpackedODT, sTemp, password, documentID); - - COfficeUtils oCOfficeUtils(NULL); - nRes = (S_OK == oCOfficeUtils.CompressFileOrDirectory(sTempUnpackedODT, sTo, false, password.empty() ? Z_DEFLATED : 0)) ? 0 : AVS_FILEUTILS_ERROR_CONVERT; - } - catch (...) - { - nRes = AVS_FILEUTILS_ERROR_CONVERT; - } - return nRes; - } - // docx dir -> odt - _UINT32 docx_dir2odt(const std::wstring &sDocxDir, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms, bool bTemplate) - { - std::wstring sTempUnpackedODT = sTemp + FILE_SEPARATOR_STR + L"odt_unpacked"; - NSDirectory::CreateDirectory(sTempUnpackedODT); - - Oox2Odf::Converter converter(sDocxDir, L"text", params.getFontPath(), bTemplate, sTemp); - - _UINT32 nRes = 0; - try - { - std::wstring password = params.getSavePassword(); - std::wstring documentID = params.getDocumentID(); - - converter.convert(); - converter.write(sTempUnpackedODT, sTemp, password, documentID); - - COfficeUtils oCOfficeUtils(NULL); - nRes = (S_OK == oCOfficeUtils.CompressFileOrDirectory(sTempUnpackedODT, sTo, false, password.empty() ? Z_DEFLATED : 0)) ? 0 : AVS_FILEUTILS_ERROR_CONVERT; - } - catch (...) - { - nRes = AVS_FILEUTILS_ERROR_CONVERT; - } - return nRes; - } - // xlsx -> ods - _UINT32 xlsx2ods(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - std::wstring sTempUnpackedXLSX = sTemp + FILE_SEPARATOR_STR + L"xlsx_unpacked"; - - NSDirectory::CreateDirectory(sTempUnpackedXLSX); - - COfficeUtils oCOfficeUtils(NULL); - if (S_OK == oCOfficeUtils.ExtractToDirectory(sFrom, sTempUnpackedXLSX, NULL, 0)) - { - return xlsx_dir2ods(sTempUnpackedXLSX, sTo, sTemp, params, false); // add Template ??? - } - return AVS_FILEUTILS_ERROR_CONVERT; - } - - _UINT32 xlsx_dir2ods(const std::wstring &sXlsxDir, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms, bool bTemplate) - { - std::wstring sTempUnpackedODS = sTemp + FILE_SEPARATOR_STR + L"ods_unpacked"; - NSDirectory::CreateDirectory(sTempUnpackedODS); - - Oox2Odf::Converter converter(sXlsxDir, L"spreadsheet", params.getFontPath(), bTemplate, sTemp); - - _UINT32 nRes = 0; - - std::wstring password = params.getSavePassword(); - std::wstring documentID = params.getDocumentID(); - - converter.convert(); - converter.write(sTempUnpackedODS, sTemp, password, documentID); - - COfficeUtils oCOfficeUtils(NULL); - nRes = (S_OK == oCOfficeUtils.CompressFileOrDirectory(sTempUnpackedODS, sTo, false, password.empty() ? Z_DEFLATED : 0)) ? 0 : AVS_FILEUTILS_ERROR_CONVERT; - - return nRes; - } - - _UINT32 mscrypt2oot(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - std::wstring sResultOotDir = sTemp + FILE_SEPARATOR_STR + _T("oot_unpacked"); - std::wstring sResultOotFileEditor = sResultOotDir + FILE_SEPARATOR_STR + _T("Editor.bin"); - - NSDirectory::CreateDirectory(sResultOotDir); - - _UINT32 nRes = mscrypt2oot_bin(sFrom, sResultOotFileEditor, sTemp, params); - if (SUCCEEDED_X2T(nRes)) - { - COfficeUtils oCOfficeUtils(NULL); - nRes = (S_OK == oCOfficeUtils.CompressFileOrDirectory(sResultOotDir, sTo)) ? nRes : AVS_FILEUTILS_ERROR_CONVERT; - } - - return nRes; - } - _UINT32 mscrypt2oox(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - std::wstring password = params.getPassword(); - - ECMACryptFile cryptReader; - bool bDataIntegrity = false; - - if (cryptReader.DecryptOfficeFile(sFrom, sTo, password, bDataIntegrity) == false) - { - if (password.empty()) - return AVS_FILEUTILS_ERROR_CONVERT_DRM; - else - return AVS_FILEUTILS_ERROR_CONVERT_PASSWORD; - } - - if (bDataIntegrity == false) - { - // было несанкционированое вешательство в файл - } - - return 0; - } - _UINT32 mitcrypt2oox(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - // todo - return AVS_FILEUTILS_ERROR_CONVERT_DRM_UNSUPPORTED; - } - _UINT32 mscrypt2oot_bin(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - // decrypt to temp file - std::wstring password = params.getPassword(); - std::wstring sResultDecryptFile = sTemp + FILE_SEPARATOR_STR + L"uncrypt_file.oox"; +#include "lib/odf.h" - ECMACryptFile cryptReader; - bool bDataIntegrity = false; +#include "lib/pdf_image.h" +#include "lib/pdf_oform.h" - if (cryptReader.DecryptOfficeFile(sFrom, sResultDecryptFile, password, bDataIntegrity) == false) - { - if (password.empty()) - return AVS_FILEUTILS_ERROR_CONVERT_DRM; - else - return AVS_FILEUTILS_ERROR_CONVERT_PASSWORD; - } +#include "lib/iwork.h" - if (bDataIntegrity == false) - { - // было несанкционированое вешательство в файл - } +#include "lib/hwp.h" - COfficeFileFormatChecker OfficeFileFormatChecker; +#include "../../DesktopEditor/doctrenderer/docbuilder.h" +#include "../../MsBinaryFile/Common/Vba/VbaReader.h" - if (OfficeFileFormatChecker.isOfficeFile(sResultDecryptFile)) - { - switch (OfficeFileFormatChecker.nFileType) - { - case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX: - case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCM: - case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOTX: - case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOTM: - case AVS_OFFICESTUDIO_FILE_DOCUMENT_OFORM: - case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCXF: - { - return docx2doct_bin(sResultDecryptFile, sTo, sTemp, params); - } - break; - case AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSX: - case AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSM: - case AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLTX: - case AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLTM: - case AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSB: - { - const std::wstring &sXmlOptions = params.getXmlOptions(); - return xlsx2xlst_bin(sResultDecryptFile, sTo, sTemp, params); - } - break; - case AVS_OFFICESTUDIO_FILE_PRESENTATION_PPTX: - case AVS_OFFICESTUDIO_FILE_PRESENTATION_PPTM: - case AVS_OFFICESTUDIO_FILE_PRESENTATION_PPSX: - case AVS_OFFICESTUDIO_FILE_PRESENTATION_POTX: - case AVS_OFFICESTUDIO_FILE_PRESENTATION_POTM: - case AVS_OFFICESTUDIO_FILE_PRESENTATION_PPSM: - { - return pptx2pptt_bin(sResultDecryptFile, sTo, sTemp, params); - } - break; - case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX_FLAT: - { - return docxflat2doct_bin(sResultDecryptFile, sTo, sTemp, params); - } - break; - case AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSX_FLAT: - { - const std::wstring &sXmlOptions = params.getXmlOptions(); - return xlsxflat2xlst_bin(sResultDecryptFile, sTo, sTemp, params); - } - break; - case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX_PACKAGE: - case AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSX_PACKAGE: - case AVS_OFFICESTUDIO_FILE_PRESENTATION_PPTX_PACKAGE: - { - return package2bin(sResultDecryptFile, sTo, sTemp, params); - } - break; - } - } - return AVS_FILEUTILS_ERROR_CONVERT; - } - _UINT32 mitcrypt2oot_bin(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - // todo - return AVS_FILEUTILS_ERROR_CONVERT_DRM_UNSUPPORTED; - } - _UINT32 msVbaProject2Xml(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) +namespace NExtractTools +{ + // vba + _UINT32 msVbaProject2Xml(const std::wstring &sFrom, const std::wstring &sTo, InputParams ¶ms, ConvertParams& convertParams) { CVbaReader vbaReader(sFrom, sTo); @@ -3437,168 +71,50 @@ namespace NExtractTools return 0; } - _UINT32 oox2mscrypt(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - std::wstring password = params.getSavePassword(); - std::wstring documentID = params.getDocumentID(); - - ECMACryptFile cryptReader; - - if (cryptReader.EncryptOfficeFile(sFrom, sTo, password, documentID) == false) - { - return AVS_FILEUTILS_ERROR_CONVERT; - } - - return 0; - } - _UINT32 fromMscrypt(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - std::wstring password = params.getPassword(); - - std::wstring sResultDecryptFile = sTemp + FILE_SEPARATOR_STR + L"uncrypt_file.oox"; - - _UINT32 nRes = mscrypt2oox(sFrom, sResultDecryptFile, sTemp, params); - - if (!SUCCEEDED_X2T(nRes) && password.empty()) // qiaoshemei1 (1).xlsx - запрокченный xlsx - { - if (!params.getDontSaveAdditional()) - { - copyOrigin(sFrom, sTo); - } - return AVS_FILEUTILS_ERROR_CONVERT_DRM; - } - nRes = processEncryptionError(nRes, sFrom, params); - if (SUCCEEDED_X2T(nRes)) - { - COfficeFileFormatChecker OfficeFileFormatChecker; - if (OfficeFileFormatChecker.isOfficeFile(sResultDecryptFile)) - { - params.changeFormatFrom(OfficeFileFormatChecker.nFileType, OfficeFileFormatChecker.bMacroEnabled); - switch (OfficeFileFormatChecker.nFileType) - { - case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX: - case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCM: - case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOTX: - case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOTM: - case AVS_OFFICESTUDIO_FILE_DOCUMENT_OFORM: - case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCXF: - { - return fromDocument(sResultDecryptFile, AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX, sTemp, params); - } - break; - case AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSX: - case AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSM: - case AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLTX: - case AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLTM: - case AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSB: - { - return fromSpreadsheet(sResultDecryptFile, AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSX, sTemp, params); - } - break; - case AVS_OFFICESTUDIO_FILE_PRESENTATION_PPTX: - case AVS_OFFICESTUDIO_FILE_PRESENTATION_PPTM: - case AVS_OFFICESTUDIO_FILE_PRESENTATION_PPSX: - case AVS_OFFICESTUDIO_FILE_PRESENTATION_POTX: - case AVS_OFFICESTUDIO_FILE_PRESENTATION_POTM: - case AVS_OFFICESTUDIO_FILE_PRESENTATION_PPSM: - { - return fromPresentation(sResultDecryptFile, AVS_OFFICESTUDIO_FILE_PRESENTATION_PPTX, sTemp, params); - } - break; - } - } - } - return nRes; - } - _UINT32 fromMitcrypt(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) + // detect macroses + _UINT32 detectMacroInFile(InputParams& oInputParams) { - // todo - return AVS_FILEUTILS_ERROR_CONVERT_DRM_UNSUPPORTED; - } + _UINT32 nRes = 0; // no macro + std::wstring sFileFrom = *oInputParams.m_sFileFrom; - // html - _UINT32 html_array2docx_dir(const std::vector &arFiles, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - CHtmlFile2 oFile; - oFile.SetTmpDirectory(sTemp); - return (S_OK == oFile.OpenBatchHtml(arFiles, sTo)) ? 0 : AVS_FILEUTILS_ERROR_CONVERT; - } - _UINT32 html2docx_dir(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - std::vector arFiles; - arFiles.push_back(sFrom); - return html_array2docx_dir(arFiles, sTo, sTemp, params); - } - // html in container - _UINT32 html_zip2docx_dir(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - std::vector arFiles; + COfficeFileFormatChecker OfficeFileFormatChecker; - POLE::Storage storage(sFrom.c_str()); - if (storage.open()) + if (OfficeFileFormatChecker.isOfficeFile(sFileFrom)) { - POLE::Stream stream(&storage, L"WordDocument"); - - POLE::uint64 size_stream = stream.size(); - unsigned char *buffer = new unsigned char[size_stream]; - if (buffer) + if (OfficeFileFormatChecker.bMacroEnabled) { - stream.read(buffer, size_stream); - std::wstring sTempHtml = sTemp + FILE_SEPARATOR_STR + L"tempHtml.html"; - - NSFile::CFileBinary file; - - if (file.CreateFileW(sTempHtml)) - { - file.WriteFile(buffer, size_stream); - file.CloseFile(); - - arFiles.push_back(sTempHtml); - } - delete[] buffer; + nRes = AVS_ERROR_MACRO; } } - else // in zip - { - } - return 0 == html_array2docx_dir(arFiles, sTo, sTemp, params) ? 0 : AVS_FILEUTILS_ERROR_CONVERT; - } - // mht - _UINT32 mht2docx_dir(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - CHtmlFile2 oFile; - oFile.SetTmpDirectory(sTemp); - return (S_OK == oFile.OpenMht(sFrom, sTo)) ? 0 : AVS_FILEUTILS_ERROR_CONVERT; - } - // epub - _UINT32 epub2docx_dir(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - CEpubFile oFile; - oFile.SetTempDirectory(sTemp); - return (S_OK == oFile.Convert(sFrom, sTo, false)) ? 0 : AVS_FILEUTILS_ERROR_CONVERT; + + return nRes; } - _UINT32 fb2docx_dir(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) + + // create js cache (for builder) + void createJSCaches() { - CFb2File fb2File; - fb2File.SetTmpDirectory(sTemp); - return S_OK == fb2File.Open(sFrom, sTo) ? S_OK : AVS_FILEUTILS_ERROR_CONVERT; + NSDoctRenderer::CDocBuilder::Initialize(); + + NSDoctRenderer::CDoctrenderer oDoctRenderer; + oDoctRenderer.CreateCache(L"", L""); + + NSDoctRenderer::CDocBuilder::Dispose(); } - _UINT32 fb2docx(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) + + void createJSSnapshots() { - std::wstring sTempUnpackedDOCX = sTemp + FILE_SEPARATOR_STR + _T("docx_unpacked"); - NSDirectory::CreateDirectory(sTempUnpackedDOCX); + NSDoctRenderer::CDocBuilder::Initialize(); - _UINT32 nRes = fb2docx_dir(sFrom, sTempUnpackedDOCX, sTemp, params); - if (SUCCEEDED_X2T(nRes)) - { - nRes = dir2zipMscrypt(sTempUnpackedDOCX, sTo, sTemp, params); - } - return AVS_FILEUTILS_ERROR_CONVERT; + NSDoctRenderer::CDoctrenderer oDoctRenderer; + oDoctRenderer.CreateSnapshots(); + + NSDoctRenderer::CDocBuilder::Dispose(); } + // mailmerge - _UINT32 convertmailmerge( - const InputParamsMailMerge &oMailMergeSend, const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, bool bPaid, const std::wstring &sThemeDir, InputParams ¶ms) + _UINT32 convertmailmerge(const InputParamsMailMerge& oMailMergeSend, + const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) { if (NULL == oMailMergeSend.mailFormat || NULL == oMailMergeSend.recordFrom || NULL == oMailMergeSend.recordTo) return AVS_FILEUTILS_ERROR_CONVERT; @@ -3634,7 +150,7 @@ namespace NExtractTools NSDoctRenderer::CDoctrenderer oDoctRenderer(NULL != params.m_sAllFontsPath ? *params.m_sAllFontsPath : _T("")); std::wstring sMailMergeXml = getMailMergeXml(sJsonPath, *oMailMergeSend.recordFrom, recordTo, *oMailMergeSend.to); // посылаем выходную папку sFileFromDir, чтобы файлы лежали на одном уровне с папкой media, важно для дальнейшей конвертации в docx, pdf - std::wstring sXml = getDoctXml(NSDoctRenderer::DoctRendererFormat::FormatFile::DOCT, eTypeTo, sFrom, sFileFromDir, sImagesDirectory, sThemeDir, -1, sMailMergeXml, params); + std::wstring sXml = getDoctXml(NSDoctRenderer::DoctRendererFormat::FormatFile::DOCT, eTypeTo, sFrom, sFileFromDir, sImagesDirectory, convertParams.m_sThemesDir, -1, sMailMergeXml, params); std::wstring sResult; oDoctRenderer.Execute(sXml, sResult); if (-1 != sResult.find(_T("error"))) @@ -3664,7 +180,7 @@ namespace NExtractTools { sFilePathOut += L".docx"; - std::wstring sTempDocx = sTemp + FILE_SEPARATOR_STR + wsFilePathInFilename + L"_DOCX"; + std::wstring sTempDocx = convertParams.m_sTempDir + FILE_SEPARATOR_STR + wsFilePathInFilename + L"_DOCX"; NSDirectory::CreateDirectory(sTempDocx); BinDocxRW::CDocxSerializer m_oCDocxSerializer; @@ -3680,25 +196,27 @@ namespace NExtractTools nRes = m_oCDocxSerializer.loadFromFile(sFilePathIn, sTempDocx, sXmlOptions, sThemePath, sMediaPath, sEmbedPath) ? 0 : AVS_FILEUTILS_ERROR_CONVERT; if (SUCCEEDED_X2T(nRes)) { - std::wstring sTempUnencrypted = sTemp + FILE_SEPARATOR_STR + wsFilePathInFilename + L"_unencrypted"; + std::wstring sTempUnencrypted = convertParams.m_sTempDir + FILE_SEPARATOR_STR + wsFilePathInFilename + L"_unencrypted"; NSDirectory::CreateDirectory(sTempUnencrypted); - nRes = dir2zipMscrypt(sTempDocx, sFilePathOut, sTempUnencrypted, params); + std::wstring sOldTempDir = convertParams.m_sTempDir; + convertParams.m_sTempDir = sTempUnencrypted; + nRes = dir2zipMscrypt(sTempDocx, sFilePathOut, params, convertParams); + convertParams.m_sTempDir = sOldTempDir; } } else if (NSDoctRenderer::DoctRendererFormat::FormatFile::PDF == eTypeTo) { sFilePathOut += _T(".pdf"); - NSFonts::IApplicationFonts *pApplicationFonts = NSFonts::NSApplication::Create(); - initApplicationFonts(pApplicationFonts, params); + NSFonts::IApplicationFonts* pApplicationFonts = createApplicationFonts(params); CPdfFile pdfWriter(pApplicationFonts); pdfWriter.CreatePdf(params.getIsPDFA()); - pdfWriter.SetTempDirectory(sTemp); + pdfWriter.SetTempDirectory(convertParams.m_sTempDir); pdfWriter.SetDocumentInfo(params.getTitle(), L"", L"", L""); CConvertFromBinParams oBufferParams; - oBufferParams.m_sThemesDirectory = sThemeDir; + oBufferParams.m_sThemesDirectory = convertParams.m_sThemesDir; std::wstring documentID = params.getDocumentID(); if (false == documentID.empty()) @@ -3708,7 +226,7 @@ namespace NExtractTools if (false == password.empty()) pdfWriter.SetPassword(password); - int nReg = (bPaid == false) ? 0 : 1; + int nReg = (convertParams.m_bIsPaid == false) ? 0 : 1; nRes = (S_OK == pdfWriter.OnlineWordToPdfFromBinary(sFilePathIn, sFilePathOut, &oBufferParams)) ? 0 : AVS_FILEUTILS_ERROR_CONVERT; RELEASEOBJECT(pApplicationFonts); } @@ -3730,362 +248,8 @@ namespace NExtractTools return nRes; } - std::string checkPrintPages(InputParams ¶ms) - { - if (NULL == params.m_sJsonParams) - return ""; - - std::wstring::size_type posNativeOptions = params.m_sJsonParams->find(L"\"nativeOptions\""); - if (std::wstring::npos == posNativeOptions) - return ""; - - std::wstring::size_type posNativePages = params.m_sJsonParams->find(L"\"pages\":\"", posNativeOptions); - if (std::wstring::npos == posNativePages) - return ""; - - posNativePages += 9; - std::wstring::size_type posNativePages2 = params.m_sJsonParams->find(L"\"", posNativePages); - if (std::wstring::npos == posNativePages2) - return ""; - - std::wstring sPages = params.m_sJsonParams->substr(posNativePages, posNativePages2 - posNativePages); - if (L"all" == sPages) - return ""; - - if (L"current" == sPages) - { - std::wstring::size_type posCurrentPage = params.m_sJsonParams->find(L"\"currentPage\":", posNativeOptions); - if (std::wstring::npos == posCurrentPage) - return ""; - - posCurrentPage += 14; - std::wstring::size_type posCurrentPage2 = params.m_sJsonParams->find(L",", posCurrentPage); - std::wstring::size_type posCurrentPage3 = params.m_sJsonParams->find(L"}", posCurrentPage); - - if (std::wstring::npos == posCurrentPage2) - { - if (std::wstring::npos == posCurrentPage3) - return ""; - posCurrentPage2 = posCurrentPage3; - } - else if (std::wstring::npos != posCurrentPage3 && posCurrentPage3 < posCurrentPage2) - posCurrentPage2 = posCurrentPage3; - - if (std::wstring::npos == posCurrentPage2) - return ""; - - sPages = params.m_sJsonParams->substr(posCurrentPage, posCurrentPage2 - posCurrentPage); - } - - return U_TO_UTF8(sPages); - } - - std::vector getPrintPages(const std::string &sPages, int nPagesCount) - { - const char *buffer = sPages.c_str(); - - size_t nCur = 0; - size_t nLen = sPages.length(); - - std::vector arPages; - for (int i = 0; i < nPagesCount; ++i) - arPages.push_back(false); - - while (nCur < nLen) - { - size_t cur = nCur; - while (cur < nLen && buffer[cur] != ',') - ++cur; - - int nStart = 0; - int nEnd = 0; - - size_t curRec = nCur; - while (curRec < cur) - { - char c = buffer[curRec++]; - if (c >= '0' && c <= '9') - nStart = 10 * nStart + (c - '0'); - - if (c == '-') - break; - } - - if (nStart == 0) - nStart = 1; - - if (curRec == cur) - nEnd = nStart; - else - { - while (curRec < cur) - { - char c = buffer[curRec++]; - if (c >= '0' && c <= '9') - nEnd = 10 * nEnd + (c - '0'); - - if (c == '-') - break; - } - - if (0 == nEnd || nEnd > nPagesCount) - nEnd = nPagesCount; - } - - for (int i = nStart; i <= nEnd; ++i) - arPages[i - 1] = true; - - nCur = cur; - if (nCur < nLen) - ++nCur; - } - - return arPages; - } - - _UINT32 PdfDjvuXpsToRenderer( - IOfficeDrawingFile **ppReader, IRenderer *pRenderer, const std::wstring &sFrom, int nFormatFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms, - NSFonts::IApplicationFonts *pApplicationFonts, const std::string &sPages = "") - { - _UINT32 nRes = 0; - IOfficeDrawingFile *pReader = NULL; - if (AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_PDF == nFormatFrom) - { - pReader = new CPdfFile(pApplicationFonts); - } - else if (AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_DJVU == nFormatFrom) - { - pReader = new CDjVuFile(pApplicationFonts); - } - else if (AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_XPS == nFormatFrom) - { - pReader = new CXpsFile(pApplicationFonts); - } - else - nRes = AVS_FILEUTILS_ERROR_CONVERT; - if (SUCCEEDED_X2T(nRes)) - { - *ppReader = pReader; - pReader->SetTempDirectory(sTemp); - - std::wstring sPassword = params.getPassword(); - - bool bResult = pReader->LoadFromFile(sFrom.c_str(), L"", sPassword, sPassword); - if (bResult) - { - int nPagesCount = pReader->GetPagesCount(); - - bool bIsUsePages = sPages.empty() ? false : true; - std::vector arPages; - if (bIsUsePages) - arPages = getPrintPages(sPages, nPagesCount); - - for (int i = 0; i < nPagesCount; ++i) - { - if (bIsUsePages && !arPages[i]) - continue; - - pRenderer->NewPage(); - pRenderer->BeginCommand(c_nPageType); - - double dPageDpiX, dPageDpiY; - double dWidth, dHeight; - pReader->GetPageInfo(i, &dWidth, &dHeight, &dPageDpiX, &dPageDpiY); - - dWidth *= 25.4 / dPageDpiX; - dHeight *= 25.4 / dPageDpiY; - - pRenderer->put_Width(dWidth); - pRenderer->put_Height(dHeight); - - pReader->DrawPageOnRenderer(pRenderer, i, NULL); - - pRenderer->EndCommand(c_nPageType); - } - } - else - { - nRes = AVS_FILEUTILS_ERROR_CONVERT; - if (AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_PDF == nFormatFrom) - { - CPdfFile *pPdfReader = static_cast(pReader); - if (PdfFile::errorEncrypted == pPdfReader->GetError()) - { - if (sPassword.empty()) - { - if (!params.getDontSaveAdditional()) - { - copyOrigin(sFrom, *params.m_sFileTo); - } - nRes = AVS_FILEUTILS_ERROR_CONVERT_DRM; - } - else - { - nRes = AVS_FILEUTILS_ERROR_CONVERT_PASSWORD; - } - } - } - } - } - return nRes; - } - - _UINT32 PdfDjvuXpsToImage( - IOfficeDrawingFile **ppReader, const std::wstring &sFrom, int nFormatFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms, - NSFonts::IApplicationFonts *pApplicationFonts) - { - _UINT32 nRes = 0; - IOfficeDrawingFile *pReader = NULL; - if (AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_PDF == nFormatFrom) - { - pReader = new CPdfFile(pApplicationFonts); - } - else if (AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_DJVU == nFormatFrom) - { - pReader = new CDjVuFile(pApplicationFonts); - } - else if (AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_XPS == nFormatFrom) - { - pReader = new CXpsFile(pApplicationFonts); - } - else - nRes = AVS_FILEUTILS_ERROR_CONVERT; - if (SUCCEEDED_X2T(nRes)) - { - *ppReader = pReader; - pReader->SetTempDirectory(sTemp); - - std::wstring sPassword = params.getPassword(); - - bool bResult = pReader->LoadFromFile(sFrom.c_str(), L"", sPassword, sPassword); - if (bResult) - { - // default as in CMetafileToRenderterRaster - int nRasterFormat = 4; - int nSaveType = 2; - bool bIsOnlyFirst = true; - bool bIsZip = true; - int nRasterW = 100; - int nRasterH = 100; - if (NULL != params.m_oThumbnail) - { - InputParamsThumbnail *oThumbnail = params.m_oThumbnail; - if (NULL != oThumbnail->format) - { - nRasterFormat = *oThumbnail->format; - } - if (NULL != oThumbnail->aspect) - { - nSaveType = *oThumbnail->aspect; - } - if (NULL != oThumbnail->first) - { - bIsOnlyFirst = *oThumbnail->first; - } - if (NULL != oThumbnail->zip) - { - bIsZip = *oThumbnail->zip; - } - if (NULL != oThumbnail->width) - { - nRasterW = *oThumbnail->width; - } - if (NULL != oThumbnail->height) - { - nRasterH = *oThumbnail->height; - } - } - std::wstring sThumbnailDir; - std::wstring sFileToExt; - if (!bIsOnlyFirst) - { - if (bIsZip) - { - sThumbnailDir = sTemp + FILE_SEPARATOR_STR + _T("thumbnails"); - NSDirectory::CreateDirectory(sThumbnailDir); - } - else - { - if (!NSDirectory::Exists(sTo)) - NSDirectory::CreateDirectory(sTo); - sThumbnailDir = sTo; - } - sFileToExt = getExtentionByRasterFormat(nRasterFormat); - } - int nPagesCount = pReader->GetPagesCount(); - if (bIsOnlyFirst) - nPagesCount = 1; - for (int i = 0; i < nPagesCount; ++i) - { - int nRasterWCur = nRasterW; - int nRasterHCur = nRasterH; - - if (1 == nSaveType) - { - double dPageDpiX, dPageDpiY; - double dWidth, dHeight; - pReader->GetPageInfo(i, &dWidth, &dHeight, &dPageDpiX, &dPageDpiY); - - double dKoef1 = nRasterWCur / dWidth; - double dKoef2 = nRasterHCur / dHeight; - if (dKoef1 > dKoef2) - dKoef1 = dKoef2; - - nRasterWCur = (int)(dWidth * dKoef1 + 0.5); - nRasterHCur = (int)(dHeight * dKoef1 + 0.5); - } - else if (2 == nSaveType) - { - nRasterWCur = -1; - nRasterHCur = -1; - } - std::wstring sFileTo; - if (bIsOnlyFirst) - { - sFileTo = sTo; - } - else - { - sFileTo = sThumbnailDir + FILE_SEPARATOR_STR + L"image" + std::to_wstring(i + 1) + sFileToExt; - } - pReader->ConvertToRaster(i, sFileTo, nRasterFormat, nRasterWCur, nRasterHCur); - } - // zip - if (!bIsOnlyFirst && bIsZip) - { - COfficeUtils oCOfficeUtils(NULL); - nRes = S_OK == oCOfficeUtils.CompressFileOrDirectory(sThumbnailDir, sTo) ? nRes : AVS_FILEUTILS_ERROR_CONVERT; - } - } - else - { - nRes = AVS_FILEUTILS_ERROR_CONVERT; - if (AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_PDF == nFormatFrom) - { - CPdfFile *pPdfReader = static_cast(pReader); - if (PdfFile::errorEncrypted == pPdfReader->GetError()) - { - if (sPassword.empty()) - { - if (!params.getDontSaveAdditional()) - { - copyOrigin(sFrom, *params.m_sFileTo); - } - nRes = AVS_FILEUTILS_ERROR_CONVERT_DRM; - } - else - { - nRes = AVS_FILEUTILS_ERROR_CONVERT_PASSWORD; - } - } - } - } - } - return nRes; - } - - _UINT32 fromDocxDir( - const std::wstring &sFrom, const std::wstring &sTo, int nFormatTo, const std::wstring &sTemp, const std::wstring &sThemeDir, bool bPaid, InputParams ¶ms, const std::wstring &sDocxFile) + // from docxDir + _UINT32 fromDocxDir(const std::wstring &sFrom, const std::wstring &sTo, int nFormatTo, InputParams ¶ms, ConvertParams& convertParams) { _UINT32 nRes = 0; std::wstring sFromWithChanges = sFrom; @@ -4108,40 +272,14 @@ namespace NExtractTools if (0 != (AVS_OFFICESTUDIO_FILE_DOCUMENT & nFormatTo) && !bIsNeedDoct) { - if (AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX == nFormatTo || AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCM == nFormatTo || AVS_OFFICESTUDIO_FILE_DOCUMENT_DOTX == nFormatTo || - AVS_OFFICESTUDIO_FILE_DOCUMENT_DOTM == nFormatTo || AVS_OFFICESTUDIO_FILE_DOCUMENT_OFORM == nFormatTo || AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCXF == nFormatTo) + if (AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX == nFormatTo || + AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCM == nFormatTo || + AVS_OFFICESTUDIO_FILE_DOCUMENT_DOTX == nFormatTo || + AVS_OFFICESTUDIO_FILE_DOCUMENT_DOTM == nFormatTo || + AVS_OFFICESTUDIO_FILE_DOCUMENT_OFORM == nFormatTo || + AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCXF == nFormatTo) { - if (AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCM == nFormatTo || AVS_OFFICESTUDIO_FILE_DOCUMENT_DOTX == nFormatTo || AVS_OFFICESTUDIO_FILE_DOCUMENT_DOTM == nFormatTo) - { - std::wstring sCTFrom = L"application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"; - switch (*params.m_nFormatFrom) - { - case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCM: - sCTFrom = L"application/vnd.ms-word.document.macroEnabled.main+xml"; - break; - case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOTX: - sCTFrom = L"application/vnd.openxmlformats-officedocument.wordprocessingml.template.main+xml"; - break; - case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOTM: - sCTFrom = L"application/vnd.ms-word.template.macroEnabledTemplate.main+xml"; - break; - } - std::wstring sCTTo; - switch (nFormatTo) - { - case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCM: - sCTTo = L"application/vnd.ms-word.document.macroEnabled.main+xml"; - break; - case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOTX: - sCTTo = L"application/vnd.openxmlformats-officedocument.wordprocessingml.template.main+xml"; - break; - case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOTM: - sCTTo = L"application/vnd.ms-word.template.macroEnabledTemplate.main+xml"; - break; - } - nRes = replaceContentType(sFromWithChanges, sCTFrom, sCTTo); - } - else if (AVS_OFFICESTUDIO_FILE_DOCUMENT_OFORM == nFormatTo) + if (AVS_OFFICESTUDIO_FILE_DOCUMENT_OFORM == nFormatTo) { std::wstring sCT = L""; nRes = addContentType(sFromWithChanges, sCT); @@ -4151,95 +289,147 @@ namespace NExtractTools std::wstring sCT = L""; nRes = addContentType(sFromWithChanges, sCT); } + else + { + if ((params.m_nFormatFrom) && (AVS_OFFICESTUDIO_FILE_DOCUMENT_OFORM == *params.m_nFormatFrom)) + { + std::wstring sCT = L""; + replaceContentType(sFromWithChanges, sCT, L""); + } + else if ((params.m_nFormatFrom) && (AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCXF == *params.m_nFormatFrom)) + { + std::wstring sCT = L""; + replaceContentType(sFromWithChanges, sCT, L""); + } + if (AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCM == nFormatTo || + AVS_OFFICESTUDIO_FILE_DOCUMENT_DOTX == nFormatTo || + AVS_OFFICESTUDIO_FILE_DOCUMENT_DOTM == nFormatTo) + { + std::wstring sCTFrom = L"application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"; + switch (*params.m_nFormatFrom) + { + case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCM: + sCTFrom = L"application/vnd.ms-word.document.macroEnabled.main+xml"; + break; + case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOTX: + sCTFrom = L"application/vnd.openxmlformats-officedocument.wordprocessingml.template.main+xml"; + break; + case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOTM: + sCTFrom = L"application/vnd.ms-word.template.macroEnabledTemplate.main+xml"; + break; + } + std::wstring sCTTo; + switch (nFormatTo) + { + case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCM: + sCTTo = L"application/vnd.ms-word.document.macroEnabled.main+xml"; + break; + case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOTX: + sCTTo = L"application/vnd.openxmlformats-officedocument.wordprocessingml.template.main+xml"; + break; + case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOTM: + sCTTo = L"application/vnd.ms-word.template.macroEnabledTemplate.main+xml"; + break; + } + nRes = replaceContentType(sFromWithChanges, sCTFrom, sCTTo); + } + } if (SUCCEEDED_X2T(nRes)) { - nRes = dir2zipMscrypt(sFromWithChanges, sTo, sTemp, params); + nRes = dir2zipMscrypt(sFromWithChanges, sTo, params, convertParams); } } + else if (AVS_OFFICESTUDIO_FILE_DOCUMENT_OFORM_PDF == nFormatTo) + { + nRes = docx_dir2pdfoform(sFromWithChanges, sTo, params, convertParams); + } else if (AVS_OFFICESTUDIO_FILE_DOCUMENT_DOC == nFormatTo) { - nRes = docx_dir2doc(sFromWithChanges, sTo, sTemp, params); + nRes = docx_dir2doc(sFromWithChanges, sTo, params, convertParams); } else if (AVS_OFFICESTUDIO_FILE_DOCUMENT_ODT == nFormatTo) { - nRes = docx_dir2odt(sFromWithChanges, sTo, sTemp, params, false); + convertParams.m_bIsTemplate = false; + nRes = docx_dir2odt(sFromWithChanges, sTo, params, convertParams); } else if (AVS_OFFICESTUDIO_FILE_DOCUMENT_OTT == nFormatTo) { - nRes = docx_dir2odt(sFromWithChanges, sTo, sTemp, params, true); + convertParams.m_bIsTemplate = true; + nRes = docx_dir2odt(sFromWithChanges, sTo, params, convertParams); } else if (AVS_OFFICESTUDIO_FILE_DOCUMENT_RTF == nFormatTo) { - nRes = docx_dir2rtf(sFromWithChanges, sTo, sTemp, params); + nRes = docx_dir2rtf(sFromWithChanges, sTo, params, convertParams); } else if (AVS_OFFICESTUDIO_FILE_DOCUMENT_TXT == nFormatTo) { - nRes = docx_dir2txt(sFromWithChanges, sTo, sTemp, params); + nRes = docx_dir2txt(sFromWithChanges, sTo, params, convertParams); } else nRes = AVS_FILEUTILS_ERROR_CONVERT_PARAMS; } else if (AVS_OFFICESTUDIO_FILE_OTHER_OOXML == nFormatTo) { - nRes = dir2zipMscrypt(sFrom, sTo, sTemp, params); + nRes = dir2zipMscrypt(sFrom, sTo, params, convertParams); } else if (AVS_OFFICESTUDIO_FILE_CANVAS_WORD == nFormatTo) { - nRes = docx_dir2doct_bin(sFromWithChanges, sTo, sTemp, params, sDocxFile); + nRes = docx_dir2doct_bin(sFromWithChanges, sTo, params, convertParams); } else if (AVS_OFFICESTUDIO_FILE_TEAMLAB_DOCY == nFormatTo) { - nRes = docx_dir2doct(sFromWithChanges, sTo, sTemp, params, sDocxFile); + nRes = docx_dir2doct(sFromWithChanges, sTo, params, convertParams); } else if (bIsNeedDoct) { if (params.needConvertToOrigin(AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX)) { - std::wstring sToRender = sDocxFile; + std::wstring sToRender = convertParams.m_sTempParamOOXMLFile; if (sToRender.empty()) { - sToRender = sTemp + FILE_SEPARATOR_STR + _T("toRender.docx"); + sToRender = combinePath(convertParams.m_sTempDir, L"toRender.docx"); nRes = dir2zip(sFromWithChanges, sToRender); } NSDoctRenderer::DoctRendererFormat::FormatFile eFromType = NSDoctRenderer::DoctRendererFormat::FormatFile::DOCT; + convertParams.m_sInternalMediaDirectory = sFrom; if (AVS_OFFICESTUDIO_FILE_DOCUMENT_EPUB == nFormatTo) { - nRes = doct_bin2epub(eFromType, sToRender, sTo, sTemp, sThemeDir, params, sFrom); + nRes = doct_bin2epub(sToRender, sTo, params, convertParams); } else if (AVS_OFFICESTUDIO_FILE_DOCUMENT_FB2 == nFormatTo) { - nRes = doct_bin2fb(eFromType, sToRender, sTo, sTemp, sThemeDir, params, sFrom); + nRes = doct_bin2fb(sToRender, sTo, params, convertParams); } else if (AVS_OFFICESTUDIO_FILE_DOCUMENT_HTML == nFormatTo) { - nRes = doct_bin2html(eFromType, sToRender, sTo, sTemp, bPaid, sThemeDir, params, sFrom); + nRes = doct_bin2html(sToRender, sTo, params, convertParams); } else if (AVS_OFFICESTUDIO_FILE_DOCUMENT_HTML_IN_CONTAINER == nFormatTo) { - nRes = doct_bin2html_zip(eFromType, sToRender, sTo, sTemp, bPaid, sThemeDir, params, sFrom); + nRes = doct_bin2html_zip(sToRender, sTo, params, convertParams); } else if (AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_PDF == nFormatTo) { - nRes = doct_bin2pdf(eFromType, sToRender, sTo, sTemp, bPaid, sThemeDir, params, sFrom); + nRes = doct_bin2pdf(eFromType, sToRender, sTo, params, convertParams); } else if (0 != (AVS_OFFICESTUDIO_FILE_IMAGE & nFormatTo)) { - nRes = doct_bin2image(eFromType, sToRender, sTo, sTemp, bPaid, sThemeDir, params, sFrom); + nRes = doct_bin2image(eFromType, sToRender, sTo, params, convertParams); } else nRes = AVS_FILEUTILS_ERROR_CONVERT_PARAMS; } else { - std::wstring sDoctDir = sTemp + FILE_SEPARATOR_STR + _T("doct_unpacked"); + std::wstring sDoctDir = combinePath(convertParams.m_sTempDir, L"doct_unpacked"); NSDirectory::CreateDirectory(sDoctDir); - std::wstring sTFile = sDoctDir + FILE_SEPARATOR_STR + _T("Editor.bin"); + std::wstring sTFile = combinePath(sDoctDir, L"Editor.bin"); - nRes = docx_dir2doct_bin(sFromWithChanges, sTFile, sTemp, params, sDocxFile); + nRes = docx_dir2doct_bin(sFromWithChanges, sTFile, params, convertParams); if (SUCCEEDED_X2T(nRes)) { - nRes = fromDoctBin(sTFile, sTo, nFormatTo, sTemp, sThemeDir, bPaid, params); + nRes = fromDoctBin(sTFile, sTo, nFormatTo, params, convertParams); } } } @@ -4247,7 +437,8 @@ namespace NExtractTools nRes = AVS_FILEUTILS_ERROR_CONVERT_PARAMS; return nRes; } - _UINT32 fromDoctBin(const std::wstring &sFrom, const std::wstring &sTo, int nFormatTo, const std::wstring &sTemp, const std::wstring &sThemeDir, bool bPaid, InputParams ¶ms) + + _UINT32 fromDoctBin(const std::wstring& sFrom, const std::wstring& sTo, int nFormatTo, InputParams& params, ConvertParams& convertParams) { _UINT32 nRes = 0; if (AVS_OFFICESTUDIO_FILE_TEAMLAB_DOCY == nFormatTo) @@ -4257,46 +448,54 @@ namespace NExtractTools } else if (AVS_OFFICESTUDIO_FILE_DOCUMENT_EPUB == nFormatTo) { - NSDoctRenderer::DoctRendererFormat::FormatFile eFromType = NSDoctRenderer::DoctRendererFormat::FormatFile::DOCT; - nRes = doct_bin2epub(eFromType, sFrom, sTo, sTemp, sThemeDir, params); + nRes = doct_bin2epub(sFrom, sTo, params, convertParams); } else if (AVS_OFFICESTUDIO_FILE_DOCUMENT_FB2 == nFormatTo) { - NSDoctRenderer::DoctRendererFormat::FormatFile eFromType = NSDoctRenderer::DoctRendererFormat::FormatFile::DOCT; - nRes = doct_bin2fb(eFromType, sFrom, sTo, sTemp, sThemeDir, params); + nRes = doct_bin2fb(sFrom, sTo, params, convertParams); } else if (AVS_OFFICESTUDIO_FILE_DOCUMENT_HTML == nFormatTo) { - NSDoctRenderer::DoctRendererFormat::FormatFile eFromType = NSDoctRenderer::DoctRendererFormat::FormatFile::DOCT; - nRes = doct_bin2html(eFromType, sFrom, sTo, sTemp, bPaid, sThemeDir, params); + nRes = doct_bin2html(sFrom, sTo, params, convertParams); } else if (AVS_OFFICESTUDIO_FILE_DOCUMENT_HTML_IN_CONTAINER == nFormatTo) { - NSDoctRenderer::DoctRendererFormat::FormatFile eFromType = NSDoctRenderer::DoctRendererFormat::FormatFile::DOCT; - nRes = doct_bin2html_zip(eFromType, sFrom, sTo, sTemp, bPaid, sThemeDir, params); + nRes = doct_bin2html_zip(sFrom, sTo, params, convertParams); } else if (AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_PDF == nFormatTo) { NSDoctRenderer::DoctRendererFormat::FormatFile eFromType = NSDoctRenderer::DoctRendererFormat::FormatFile::DOCT; - nRes = doct_bin2pdf(eFromType, sFrom, sTo, sTemp, bPaid, sThemeDir, params); + nRes = doct_bin2pdf(eFromType, sFrom, sTo, params, convertParams); + } + else if (AVS_OFFICESTUDIO_FILE_DOCUMENT_OFORM_PDF == nFormatTo) + { + nRes = doct_bin2pdfoform(sFrom, sTo, params, convertParams); } else if (0 != (AVS_OFFICESTUDIO_FILE_IMAGE & nFormatTo)) { NSDoctRenderer::DoctRendererFormat::FormatFile eFromType = NSDoctRenderer::DoctRendererFormat::FormatFile::DOCT; - nRes = doct_bin2image(eFromType, sFrom, sTo, sTemp, bPaid, sThemeDir, params); + nRes = doct_bin2image(eFromType, sFrom, sTo, params, convertParams); } - else if (0 != (AVS_OFFICESTUDIO_FILE_DOCUMENT & nFormatTo)) + else if (0 != (AVS_OFFICESTUDIO_FILE_DOCUMENT & nFormatTo) || + AVS_OFFICESTUDIO_FILE_OTHER_OOXML == nFormatTo || + AVS_OFFICESTUDIO_FILE_OTHER_ODF == nFormatTo) { - std::wstring sDocxDir = sTemp + FILE_SEPARATOR_STR + _T("docx_unpacked"); - + std::wstring sDocxDir = combinePath(convertParams.m_sTempDir, L"docx_unpacked"); if (true == NSDirectory::CreateDirectory(sDocxDir)) { - params.m_bMacro = AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCM == nFormatTo || AVS_OFFICESTUDIO_FILE_DOCUMENT_DOTM == nFormatTo; + params.m_bMacro = AVS_OFFICESTUDIO_FILE_OTHER_OOXML == nFormatTo || AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCM == nFormatTo || AVS_OFFICESTUDIO_FILE_DOCUMENT_DOTM == nFormatTo; - nRes = doct_bin2docx_dir(sFrom, sTo, sDocxDir, sThemeDir, params); + convertParams.m_sTempResultOOXMLDirectory = sDocxDir; + nRes = doct_bin2docx_dir(sFrom, sTo, params, convertParams); if (SUCCEEDED_X2T(nRes)) { - nRes = fromDocxDir(sDocxDir, sTo, nFormatTo, sTemp, sThemeDir, bPaid, params, L""); + std::wstring sFileToCurrent = *params.m_sFileTo; + params.changeFormatFromPost(*params.m_nFormatFrom, params.m_bMacro); + + if (NULL != params.m_nFormatTo) + nFormatTo = *params.m_nFormatTo; + + nRes = fromDocxDir(sDocxDir, *params.m_sFileTo, nFormatTo, params, convertParams); } } else @@ -4308,213 +507,264 @@ namespace NExtractTools nRes = AVS_FILEUTILS_ERROR_CONVERT_PARAMS; return nRes; } - _UINT32 fromDocument(const std::wstring &sFrom, int nFormatFrom, const std::wstring &sTemp, InputParams ¶ms) + _UINT32 fromDocument(const std::wstring& sFrom, int nFormatFrom, InputParams& params, ConvertParams& convertParams) { std::wstring sTo = *params.m_sFileTo; int nFormatTo = AVS_OFFICESTUDIO_FILE_UNKNOWN; if (NULL != params.m_nFormatTo) nFormatTo = *params.m_nFormatTo; - std::wstring sFontPath; - if (NULL != params.m_sFontDir) - sFontPath = *params.m_sFontDir; - std::wstring sThemeDir; - if (NULL != params.m_sThemeDir) - sThemeDir = *params.m_sThemeDir; - bool bPaid = true; - if (NULL != params.m_bPaid) - bPaid = *params.m_bPaid; _UINT32 nRes = 0; if (AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX_FLAT == nFormatFrom) { if (AVS_OFFICESTUDIO_FILE_CANVAS_WORD == nFormatTo) { - nRes = docxflat2doct_bin(sFrom, sTo, sTemp, params); + nRes = docxflat2doct_bin(sFrom, sTo, params, convertParams); } else if (AVS_OFFICESTUDIO_FILE_DOCUMENT_ODT == nFormatTo) { - nRes = docxflat2odt(sFrom, sTo, sTemp, params); + nRes = docxflat2odt(sFrom, sTo, params, convertParams); } - else if (AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX == nFormatTo) + else if ( AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX == nFormatTo || + AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCM == nFormatTo || + AVS_OFFICESTUDIO_FILE_OTHER_OOXML == nFormatTo) { - nRes = docxflat2docx(sFrom, sTo, sTemp, params); + nRes = docxflat2docx(sFrom, sTo, params, convertParams); } else { - std::wstring sDoctDir = sTemp + FILE_SEPARATOR_STR + _T("doct_unpacked"); + std::wstring sDoctDir = combinePath(convertParams.m_sTempDir, L"doct_unpacked"); NSDirectory::CreateDirectory(sDoctDir); - std::wstring sTFile = sDoctDir + FILE_SEPARATOR_STR + _T("Editor.bin"); + std::wstring sTFile = combinePath(sDoctDir, L"Editor.bin"); if (AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX_FLAT == nFormatFrom) - nRes = docxflat2doct_bin(sFrom, sTFile, sTemp, params); + nRes = docxflat2doct_bin(sFrom, sTFile, params, convertParams); else nRes = AVS_FILEUTILS_ERROR_CONVERT_PARAMS; if (SUCCEEDED_X2T(nRes)) { - nRes = fromDoctBin(sTFile, sTo, nFormatTo, sTemp, sThemeDir, bPaid, params); + nRes = fromDoctBin(sTFile, sTo, nFormatTo, params, convertParams); } } } + else if (AVS_OFFICESTUDIO_FILE_DOCUMENT_PAGES == nFormatFrom) + { + std::wstring wsTempFile = combinePath(convertParams.m_sTempDir, L"IntermediateFile.odf"); + + int nIntermediateResult = pages2odf(sFrom, wsTempFile, params, convertParams); + + if (S_OK != nIntermediateResult) + return nIntermediateResult; + + nRes = fromDocument(wsTempFile, AVS_OFFICESTUDIO_FILE_DOCUMENT_ODT_FLAT, params, convertParams); + } else { - std::wstring sDocxFile; - std::wstring sDocxDir = sTemp + FILE_SEPARATOR_STR + _T("docx_unpacked"); + std::wstring sDocxDir = combinePath(convertParams.m_sTempDir, L"docx_unpacked"); NSDirectory::CreateDirectory(sDocxDir); - if (AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX == nFormatFrom || AVS_OFFICESTUDIO_FILE_DOCUMENT_OFORM == nFormatFrom || AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCXF == nFormatFrom) + if (AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX == nFormatFrom || + AVS_OFFICESTUDIO_FILE_DOCUMENT_OFORM == nFormatFrom || + AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCXF == nFormatFrom) { - sDocxFile = sFrom; + convertParams.m_sTempParamOOXMLFile = sFrom; if (params.getFromChanges()) { params.setFromChanges(false); - nRes = apply_changes(sFrom, sTo, NSDoctRenderer::DoctRendererFormat::FormatFile::DOCT, sThemeDir, sDocxFile, params); + nRes = apply_changes(sFrom, sTo, NSDoctRenderer::DoctRendererFormat::FormatFile::DOCT, convertParams.m_sTempParamOOXMLFile, params, convertParams); + } + nRes = zip2dir(convertParams.m_sTempParamOOXMLFile, sDocxDir); + + if (false == SUCCEEDED_X2T(nRes)) + { + if (NSDirectory::GetFilesCount(sDocxDir, true) > 3) + { + nRes = 0; + } } - nRes = zip2dir(sDocxFile, sDocxDir); } else if (AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCM == nFormatFrom) { if (AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX == nFormatTo || AVS_OFFICESTUDIO_FILE_DOCUMENT_DOTX == nFormatTo || AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCXF == nFormatTo || AVS_OFFICESTUDIO_FILE_DOCUMENT_OFORM == nFormatTo) { - nRes = docm2docx_dir(sFrom, sDocxDir, params); + nRes = docm2docx_dir(sFrom, sDocxDir, params, convertParams); } else { nRes = zip2dir(sFrom, sDocxDir); } + if (false == SUCCEEDED_X2T(nRes)) + { + if (NSDirectory::GetFilesCount(sDocxDir, true) > 3) + { + nRes = 0; + } + } } else if (AVS_OFFICESTUDIO_FILE_DOCUMENT_DOTX == nFormatFrom) { - nRes = dotx2docx_dir(sFrom, sDocxDir, params); + nRes = dotx2docx_dir(sFrom, sDocxDir, params, convertParams); } else if (AVS_OFFICESTUDIO_FILE_DOCUMENT_DOTM == nFormatFrom) { if (AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX == nFormatTo || AVS_OFFICESTUDIO_FILE_DOCUMENT_DOTX == nFormatTo || AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCXF == nFormatTo || AVS_OFFICESTUDIO_FILE_DOCUMENT_OFORM == nFormatTo) { - nRes = dotm2docx_dir(sFrom, sDocxDir, params); + nRes = dotm2docx_dir(sFrom, sDocxDir, params, convertParams); } else { - nRes = dotm2docm_dir(sFrom, sDocxDir, params); + nRes = dotm2docm_dir(sFrom, sDocxDir, params, convertParams); } } - else if (AVS_OFFICESTUDIO_FILE_DOCUMENT_DOC == nFormatFrom) + else if (AVS_OFFICESTUDIO_FILE_DOCUMENT_DOC == nFormatFrom || + AVS_OFFICESTUDIO_FILE_DOCUMENT_DOC_FLAT == nFormatFrom) { if (params.m_bMacro) { - nRes = doc2docm_dir(sFrom, sDocxDir, sTemp, params); + nRes = doc2docm_dir(sFrom, sDocxDir, params, convertParams); } else { - nRes = doc2docx_dir(sFrom, sDocxDir, sTemp, params); + nRes = doc2docx_dir(sFrom, sDocxDir, params, convertParams); } } else if (AVS_OFFICESTUDIO_FILE_DOCUMENT_ODT == nFormatFrom || AVS_OFFICESTUDIO_FILE_DOCUMENT_OTT == nFormatFrom) { - nRes = odf2oox_dir(sFrom, sDocxDir, sTemp, params); + nRes = odf2oox_dir(sFrom, sDocxDir, params, convertParams); } else if (AVS_OFFICESTUDIO_FILE_DOCUMENT_ODT_FLAT == nFormatFrom) { - nRes = odf_flat2oox_dir(sFrom, sDocxDir, sTemp, params); + nRes = odf_flat2oox_dir(sFrom, sDocxDir, params, convertParams); } else if (AVS_OFFICESTUDIO_FILE_DOCUMENT_RTF == nFormatFrom) { - nRes = rtf2docx_dir(sFrom, sDocxDir, sTemp, params); + nRes = rtf2docx_dir(sFrom, sDocxDir, params, convertParams); } else if (AVS_OFFICESTUDIO_FILE_DOCUMENT_TXT == nFormatFrom || AVS_OFFICESTUDIO_FILE_DOCUMENT_XML == nFormatFrom) { - nRes = txt2docx_dir(sFrom, sDocxDir, sTemp, params); + nRes = txt2docx_dir(sFrom, sDocxDir, params, convertParams); } else if (AVS_OFFICESTUDIO_FILE_DOCUMENT_FB2 == nFormatFrom) { - nRes = fb2docx_dir(sFrom, sDocxDir, sTemp, params); + nRes = fb2docx_dir(sFrom, sDocxDir, params, convertParams); } else if (AVS_OFFICESTUDIO_FILE_DOCUMENT_EPUB == nFormatFrom) { - nRes = epub2docx_dir(sFrom, sDocxDir, sTemp, params); + nRes = epub2docx_dir(sFrom, sDocxDir, params, convertParams); } else if (AVS_OFFICESTUDIO_FILE_DOCUMENT_HTML == nFormatFrom) { - nRes = html2docx_dir(sFrom, sDocxDir, sTemp, params); + nRes = html2docx_dir(sFrom, sDocxDir, params, convertParams); + } + else if (AVS_OFFICESTUDIO_FILE_DOCUMENT_HTML_IN_CONTAINER == nFormatFrom) + { + nRes = html_zip2docx_dir(sFrom, sDocxDir, params, convertParams); + } + else if (AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX_PACKAGE == nFormatFrom) + { + nRes = package2ooxml_dir(sFrom, sDocxDir, params, convertParams); + } + else if (AVS_OFFICESTUDIO_FILE_DOCUMENT_MHT == nFormatFrom) + { + nRes = mht2docx_dir(sFrom, sDocxDir, params, convertParams); } - else if (AVS_OFFICESTUDIO_FILE_DOCUMENT_HTML_IN_CONTAINER == nFormatFrom) + else if (AVS_OFFICESTUDIO_FILE_DOCUMENT_OFORM_PDF == nFormatFrom) { - nRes = html_zip2docx_dir(sFrom, sDocxDir, sTemp, params); + nRes = pdfoform2docx_dir(sFrom, sDocxDir, params, convertParams); } - else if (AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX_PACKAGE == nFormatFrom) + else if (AVS_OFFICESTUDIO_FILE_DOCUMENT_HWP == nFormatFrom) { - nRes = package2ooxml_dir(sFrom, sDocxDir, sTemp, params); + nRes = hwp2docx_dir(sFrom, sDocxDir, params, convertParams); } - else if (AVS_OFFICESTUDIO_FILE_DOCUMENT_MHT == nFormatFrom) + else if (AVS_OFFICESTUDIO_FILE_DOCUMENT_HWPX == nFormatFrom) { - nRes = mht2docx_dir(sFrom, sDocxDir, sTemp, params); + nRes = hwpx2docx_dir(sFrom, sDocxDir, params, convertParams); } else nRes = AVS_FILEUTILS_ERROR_CONVERT_PARAMS; + if (SUCCEEDED_X2T(nRes)) { - nRes = fromDocxDir(sDocxDir, sTo, nFormatTo, sTemp, sThemeDir, bPaid, params, sDocxFile); + std::wstring sFileToCurrent = *params.m_sFileTo; + params.changeFormatFromPost(*params.m_nFormatFrom, params.m_bMacro); + + if (NULL != params.m_nFormatTo) + nFormatTo = *params.m_nFormatTo; + + nRes = fromDocxDir(sDocxDir, *params.m_sFileTo, nFormatTo, params, convertParams); } } return nRes; } - _UINT32 fromXlsbXlsxDir( - const std::wstring &sFrom, const std::wstring &sTo, int nFormatTo, const std::wstring &sTemp, const std::wstring &sThemeDir, bool bPaid, InputParams ¶ms, const std::wstring &sXlsxFile) + // from xlsxDir + _UINT32 fromXlsbXlsxDir(const std::wstring &sFrom, const std::wstring &sTo, int nFormatTo, InputParams ¶ms, ConvertParams& convertParams) { _UINT32 nRes = S_OK; if (AVS_OFFICESTUDIO_FILE_OTHER_OOXML == nFormatTo) { - nRes = dir2zipMscrypt(sFrom, sTo, sTemp, params); + nRes = dir2zipMscrypt(sFrom, sTo, params, convertParams); } else if (AVS_OFFICESTUDIO_FILE_OTHER_JSON == nFormatTo) { - nRes = xlsx_dir2xlst_bin(sFrom, sTo, params, true, sXlsxFile); + convertParams.m_bTempIsXmlOptions = true; + nRes = xlsx_dir2xlst_bin(sFrom, sTo, params, convertParams); } else if (AVS_OFFICESTUDIO_FILE_CANVAS_SPREADSHEET == nFormatTo) { - nRes = xlsx_dir2xlst_bin(sFrom, sTo, params, true, sXlsxFile); + convertParams.m_bTempIsXmlOptions = true; + nRes = xlsx_dir2xlst_bin(sFrom, sTo, params, convertParams); } else if (AVS_OFFICESTUDIO_FILE_TEAMLAB_XLSY == nFormatTo) { - nRes = xlsx_dir2xlst(sFrom, sTo, sTemp, params, true, sXlsxFile); + convertParams.m_bTempIsXmlOptions = true; + nRes = xlsx_dir2xlst(sFrom, sTo, params, convertParams); } else if ((0 != (AVS_OFFICESTUDIO_FILE_IMAGE & nFormatTo)) || AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_PDF == nFormatTo || AVS_OFFICESTUDIO_FILE_SPREADSHEET_CSV == nFormatTo) { - if (params.needConvertToOrigin(AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSX) && ((0 != (AVS_OFFICESTUDIO_FILE_IMAGE & nFormatTo)) || AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_PDF == nFormatTo)) + if (params.needConvertToOrigin(AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSX) && + ((0 != (AVS_OFFICESTUDIO_FILE_IMAGE & nFormatTo)) || AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_PDF == nFormatTo)) { - std::wstring sToRender = sXlsxFile; + std::wstring sToRender = convertParams.m_sTempParamOOXMLFile; if (sToRender.empty()) { - sToRender = sTemp + FILE_SEPARATOR_STR + _T("toRender.xlsx"); + sToRender = combinePath(convertParams.m_sTempDir, L"toRender.xlsx"); nRes = dir2zip(sFrom, sToRender); } NSDoctRenderer::DoctRendererFormat::FormatFile eFromType = NSDoctRenderer::DoctRendererFormat::FormatFile::XLST; if (AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_PDF == nFormatTo) { - nRes = doct_bin2pdf(eFromType, sToRender, sTo, sTemp, bPaid, sThemeDir, params, sFrom); + nRes = doct_bin2pdf(eFromType, sToRender, sTo, params, convertParams); } else if (0 != (AVS_OFFICESTUDIO_FILE_IMAGE & nFormatTo)) { - nRes = doct_bin2image(eFromType, sToRender, sTo, sTemp, bPaid, sThemeDir, params, sFrom); + nRes = doct_bin2image(eFromType, sToRender, sTo, params, convertParams); } else nRes = AVS_FILEUTILS_ERROR_CONVERT_PARAMS; } else { - std::wstring sXlstDir = sTemp + FILE_SEPARATOR_STR + _T("xlst_unpacked"); + std::wstring sXlstDir = combinePath(convertParams.m_sTempDir, L"xlst_unpacked"); NSDirectory::CreateDirectory(sXlstDir); - std::wstring sTFile = sXlstDir + FILE_SEPARATOR_STR + _T("Editor.bin"); + std::wstring sTFile = combinePath(sXlstDir, L"Editor.bin"); + if (AVS_OFFICESTUDIO_FILE_SPREADSHEET_CSV == nFormatTo) - nRes = xlsx_dir2xlst_bin(sFrom, sTFile, params, false, sXlsxFile); + { + convertParams.m_bTempIsXmlOptions = false; + nRes = xlsx_dir2xlst_bin(sFrom, sTFile, params, convertParams); + } else - nRes = xlsx_dir2xlst_bin(sFrom, sTFile, params, true, sXlsxFile); + { + convertParams.m_bTempIsXmlOptions = true; + nRes = xlsx_dir2xlst_bin(sFrom, sTFile, params, convertParams); + } if (SUCCEEDED_X2T(nRes)) { - nRes = fromXlstBin(sTFile, sTo, nFormatTo, sTemp, sThemeDir, bPaid, params); + nRes = fromXlstBin(sTFile, sTo, nFormatTo, params, convertParams); } } } @@ -4522,16 +772,19 @@ namespace NExtractTools nRes = AVS_FILEUTILS_ERROR_CONVERT_PARAMS; return nRes; } - _UINT32 fromXlsxDir( - const std::wstring &sFrom, const std::wstring &sTo, int nFormatTo, const std::wstring &sTemp, const std::wstring &sThemeDir, bool bPaid, InputParams ¶ms, const std::wstring &sXlsxFile) + _UINT32 fromXlsxDir(const std::wstring& sFrom, const std::wstring& sTo, int nFormatTo, InputParams& params, ConvertParams& convertParams) { _UINT32 nRes = 0; if (0 != (AVS_OFFICESTUDIO_FILE_SPREADSHEET & nFormatTo) && AVS_OFFICESTUDIO_FILE_SPREADSHEET_CSV != nFormatTo) { - if (AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSX == nFormatTo || AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSM == nFormatTo || AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLTX == nFormatTo || + if (AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSX == nFormatTo || + AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSM == nFormatTo || + AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLTX == nFormatTo || AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLTM == nFormatTo) { - if (AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSM == nFormatTo || AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLTX == nFormatTo || AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLTM == nFormatTo) + if (AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSM == nFormatTo || + AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLTX == nFormatTo || + AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLTM == nFormatTo) { std::wstring sCTFrom = _T("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml"); switch (*params.m_nFormatFrom) @@ -4563,12 +816,17 @@ namespace NExtractTools } if (SUCCEEDED_X2T(nRes)) { - nRes = dir2zipMscrypt(sFrom, sTo, sTemp, params); + nRes = dir2zipMscrypt(sFrom, sTo, params, convertParams); } } else if (AVS_OFFICESTUDIO_FILE_SPREADSHEET_ODS == nFormatTo) { - nRes = xlsx_dir2ods(sFrom, sTo, sTemp, params, false); + convertParams.m_bIsTemplate = false; + nRes = xlsx_dir2ods(sFrom, sTo, params, convertParams); + } + else if (AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSB == nFormatTo) + { + nRes = xlsx_dir2xlsb(sFrom, sTo, params, convertParams); } // else if (AVS_OFFICESTUDIO_FILE_SPREADSHEET_CSV == nFormatTo) //{ @@ -4576,18 +834,19 @@ namespace NExtractTools // } else if (AVS_OFFICESTUDIO_FILE_SPREADSHEET_OTS == nFormatTo) { - nRes = xlsx_dir2ods(sFrom, sTo, sTemp, params, true); + convertParams.m_bIsTemplate = true; + nRes = xlsx_dir2ods(sFrom, sTo, params, convertParams); } else nRes = AVS_FILEUTILS_ERROR_CONVERT_PARAMS; } else { - nRes = fromXlsbXlsxDir(sFrom, sTo, nFormatTo, sTemp, sThemeDir, bPaid, params, sXlsxFile); + nRes = fromXlsbXlsxDir(sFrom, sTo, nFormatTo, params, convertParams); } return nRes; } - _UINT32 fromXlstBin(const std::wstring &sFrom, const std::wstring &sTo, int nFormatTo, const std::wstring &sTemp, const std::wstring &sThemeDir, bool bPaid, InputParams ¶ms) + _UINT32 fromXlstBin(const std::wstring& sFrom, const std::wstring& sTo, int nFormatTo, InputParams& params, ConvertParams& convertParams) { _UINT32 nRes = 0; if (AVS_OFFICESTUDIO_FILE_TEAMLAB_XLSY == nFormatTo) @@ -4597,29 +856,41 @@ namespace NExtractTools } else if (AVS_OFFICESTUDIO_FILE_SPREADSHEET_CSV == nFormatTo) { - nRes = xlst_bin2csv(sFrom, sTo, sTemp, sThemeDir, params); + nRes = xlst_bin2csv(sFrom, sTo, params, convertParams); + } + else if (AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSB == nFormatTo) + { + nRes = xlst_bin2xlsb(sFrom, sTo, params, convertParams); } else if (AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_PDF == nFormatTo) { NSDoctRenderer::DoctRendererFormat::FormatFile eFromType = NSDoctRenderer::DoctRendererFormat::FormatFile::XLST; - nRes = doct_bin2pdf(eFromType, sFrom, sTo, sTemp, bPaid, sThemeDir, params); + nRes = doct_bin2pdf(eFromType, sFrom, sTo, params, convertParams); } else if (0 != (AVS_OFFICESTUDIO_FILE_IMAGE & nFormatTo)) { NSDoctRenderer::DoctRendererFormat::FormatFile eFromType = NSDoctRenderer::DoctRendererFormat::FormatFile::XLST; - nRes = doct_bin2image(eFromType, sFrom, sTo, sTemp, bPaid, sThemeDir, params); + nRes = doct_bin2image(eFromType, sFrom, sTo, params, convertParams); } - else if (0 != (AVS_OFFICESTUDIO_FILE_SPREADSHEET & nFormatTo)) + else if (0 != (AVS_OFFICESTUDIO_FILE_SPREADSHEET & nFormatTo) || + AVS_OFFICESTUDIO_FILE_OTHER_OOXML == nFormatTo || + AVS_OFFICESTUDIO_FILE_OTHER_ODF == nFormatTo) { - std::wstring sXlsxDir = sTemp + FILE_SEPARATOR_STR + _T("xlsx_unpacked"); + std::wstring sXlsxDir = combinePath(convertParams.m_sTempDir, L"xlsx_unpacked"); if (true == NSDirectory::CreateDirectory(sXlsxDir)) { params.m_bMacro = AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSM == nFormatTo || AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLTM == nFormatTo; - nRes = xlst_bin2xlsx_dir(sFrom, sTo, sXlsxDir, sThemeDir, params); + convertParams.m_sTempResultOOXMLDirectory = sXlsxDir; + nRes = xlst_bin2xlsx_dir(sFrom, sTo, params, convertParams); if (SUCCEEDED_X2T(nRes)) { - std::wstring sXlsxFile; - nRes = fromXlsxDir(sXlsxDir, sTo, nFormatTo, sTemp, sThemeDir, bPaid, params, sXlsxFile); + std::wstring sFileToCurrent = *params.m_sFileTo; + params.changeFormatFromPost(*params.m_nFormatFrom, params.m_bMacro); + + if (NULL != params.m_nFormatTo) + nFormatTo = *params.m_nFormatTo; + + nRes = fromXlsxDir(sXlsxDir, *params.m_sFileTo, nFormatTo, params, convertParams); } } else @@ -4631,7 +902,7 @@ namespace NExtractTools nRes = AVS_FILEUTILS_ERROR_CONVERT_PARAMS; return nRes; } - _UINT32 fromSpreadsheet(const std::wstring &sFrom, int nFormatFrom, const std::wstring &sTemp, InputParams ¶ms) + _UINT32 fromSpreadsheet(const std::wstring& sFrom, int nFormatFrom, InputParams& params, ConvertParams& convertParams) { std::wstring sTo = *params.m_sFileTo; int nFormatTo = AVS_OFFICESTUDIO_FILE_UNKNOWN; @@ -4643,41 +914,31 @@ namespace NExtractTools return AVS_FILEUTILS_ERROR_CONVERT_PARAMS; } - std::wstring sFontPath; - if (NULL != params.m_sFontDir) - sFontPath = *params.m_sFontDir; - std::wstring sThemeDir; - if (NULL != params.m_sThemeDir) - sThemeDir = *params.m_sThemeDir; - bool bPaid = true; - if (NULL != params.m_bPaid) - bPaid = *params.m_bPaid; - _UINT32 nRes = 0; - std::wstring sXlsxFile; - if ((AVS_OFFICESTUDIO_FILE_SPREADSHEET_CSV == nFormatFrom) && (AVS_OFFICESTUDIO_FILE_CANVAS_SPREADSHEET == nFormatTo || AVS_OFFICESTUDIO_FILE_OTHER_JSON == nFormatTo)) + if ((AVS_OFFICESTUDIO_FILE_SPREADSHEET_CSV == nFormatFrom) && + (AVS_OFFICESTUDIO_FILE_CANVAS_SPREADSHEET == nFormatTo || AVS_OFFICESTUDIO_FILE_OTHER_JSON == nFormatTo)) { - nRes = csv2xlst_bin(sFrom, sTo, params); + nRes = csv2xlst_bin(sFrom, sTo, params, convertParams); } else { - std::wstring sXlsxDir = sTemp + FILE_SEPARATOR_STR + _T("xlsx_unpacked"); + std::wstring sXlsxDir = combinePath(convertParams.m_sTempDir, L"xlsx_unpacked"); NSDirectory::CreateDirectory(sXlsxDir); if (AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSB == nFormatFrom && !((AVS_OFFICESTUDIO_FILE_CANVAS & nFormatTo) || (AVS_OFFICESTUDIO_FILE_IMAGE & nFormatTo) || (AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_PDF == nFormatTo))) { - nRes = xlsb2xlsx_dir(sFrom, sXlsxDir, sTemp, params); + nRes = xlsb2xlsx_dir(sFrom, sXlsxDir, params, convertParams); } else if (AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSX == nFormatFrom || AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSB == nFormatFrom) { - sXlsxFile = sFrom; + convertParams.m_sTempParamOOXMLFile = sFrom; if (AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSX == nFormatFrom && params.getFromChanges()) { params.setFromChanges(false); - nRes = apply_changes(sFrom, sTo, NSDoctRenderer::DoctRendererFormat::FormatFile::XLST, sThemeDir, sXlsxFile, params); + nRes = apply_changes(sFrom, sTo, NSDoctRenderer::DoctRendererFormat::FormatFile::XLST, convertParams.m_sTempParamOOXMLFile, params, convertParams); } - nRes = zip2dir(sXlsxFile, sXlsxDir); + nRes = zip2dir(convertParams.m_sTempParamOOXMLFile, sXlsxDir); if (!SUCCEEDED_X2T(nRes)) { // check crypt @@ -4686,7 +947,7 @@ namespace NExtractTools { if (OfficeFileFormatChecker.nFileType == AVS_OFFICESTUDIO_FILE_OTHER_MS_OFFCRYPTO) { - std::wstring sResultDecryptFile = sTemp + FILE_SEPARATOR_STR + L"uncrypt_file.oox"; + std::wstring sResultDecryptFile = combinePath(convertParams.m_sTempDir, L"uncrypt_file.oox"); // test protect bool isOldPassword = params.hasPassword(); const std::wstring sOldPassword = params.getPassword(); @@ -4695,13 +956,13 @@ namespace NExtractTools delete params.m_sPassword; params.m_sPassword = new std::wstring(L"VelvetSweatshop"); - nRes = mscrypt2oox(sFrom, sResultDecryptFile, sTemp, params); + nRes = mscrypt2oox(sFrom, sResultDecryptFile, params, convertParams); if (SUCCEEDED_X2T(nRes)) { nRes = zip2dir(sResultDecryptFile, sXlsxDir); if (SUCCEEDED_X2T(nRes)) { - sXlsxFile = sResultDecryptFile; + convertParams.m_sTempParamOOXMLFile = sResultDecryptFile; } } else @@ -4712,7 +973,7 @@ namespace NExtractTools } } else if (OfficeFileFormatChecker.nFileType == AVS_OFFICESTUDIO_FILE_OTHER_MS_MITCRYPTO) - nRes = mitcrypt2oox(sFrom, sTo, sTemp, params); + nRes = mitcrypt2oox(sFrom, sTo, params, convertParams); } } } @@ -4720,7 +981,7 @@ namespace NExtractTools { if (AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSX == nFormatTo || AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLTX == nFormatTo) { - nRes = xlsm2xlsx_dir(sFrom, sXlsxDir, params); + nRes = xlsm2xlsx_dir(sFrom, sXlsxDir, params, convertParams); } else { @@ -4729,76 +990,101 @@ namespace NExtractTools } else if (AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLTX == nFormatFrom) { - nRes = xltx2xlsx_dir(sFrom, sXlsxDir, params); + nRes = xltx2xlsx_dir(sFrom, sXlsxDir, params, convertParams); } else if (AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLTM == nFormatFrom) { if (AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSX == nFormatTo || AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLTX == nFormatTo) { - nRes = xltm2xlsx_dir(sFrom, sXlsxDir, params); + nRes = xltm2xlsx_dir(sFrom, sXlsxDir, params, convertParams); } else { - nRes = xltm2xlsm_dir(sFrom, sXlsxDir, params); + nRes = xltm2xlsm_dir(sFrom, sXlsxDir, params, convertParams); } } else if (AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLS == nFormatFrom) { if (params.m_bMacro) { - nRes = xls2xlsm_dir(sFrom, sXlsxDir, sTemp, params); + nRes = xls2xlsm_dir(sFrom, sXlsxDir, params, convertParams); } else { - nRes = xls2xlsx_dir(sFrom, sXlsxDir, sTemp, params); + nRes = xls2xlsx_dir(sFrom, sXlsxDir, params, convertParams); } } else if (AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSX_FLAT == nFormatFrom) { - nRes = xlsxflat2xlsx_dir(sFrom, sXlsxDir, sTemp, params); + nRes = xlsxflat2xlsx_dir(sFrom, sXlsxDir, params, convertParams); } else if (AVS_OFFICESTUDIO_FILE_SPREADSHEET_ODS == nFormatFrom || AVS_OFFICESTUDIO_FILE_SPREADSHEET_OTS == nFormatFrom) { - nRes = odf2oox_dir(sFrom, sXlsxDir, sTemp, params); + nRes = odf2oox_dir(sFrom, sXlsxDir, params, convertParams); } else if (AVS_OFFICESTUDIO_FILE_SPREADSHEET_ODS_FLAT == nFormatFrom) { - nRes = odf_flat2oox_dir(sFrom, sXlsxDir, sTemp, params); + nRes = odf_flat2oox_dir(sFrom, sXlsxDir, params, convertParams); } else if (AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSX_PACKAGE == nFormatFrom) { - nRes = package2ooxml_dir(sFrom, sXlsxDir, sTemp, params); + nRes = package2ooxml_dir(sFrom, sXlsxDir, params, convertParams); } else if (AVS_OFFICESTUDIO_FILE_SPREADSHEET_CSV == nFormatFrom) { - nRes = csv2xlsx_dir(sFrom, sXlsxDir, sTemp, params); + nRes = csv2xlsx_dir(sFrom, sXlsxDir, params, convertParams); *params.m_nFormatFrom = AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSX; } else if (AVS_OFFICESTUDIO_FILE_DOCUMENT_XML == nFormatFrom) { - nRes = xml2xlsx_dir(sFrom, sXlsxDir, sTemp, params); + nRes = xml2xlsx_dir(sFrom, sXlsxDir, params, convertParams); + } + else if (AVS_OFFICESTUDIO_FILE_SPREADSHEET_NUMBERS == nFormatFrom) + { + std::wstring wsTempFile = combinePath(convertParams.m_sTempDir, L"IntermediateFile.odf"); + + int nIntermediateResult = numbers2odf(sFrom, wsTempFile, params, convertParams); + + if (S_OK != nIntermediateResult) + return nIntermediateResult; + + nRes = fromSpreadsheet(wsTempFile, AVS_OFFICESTUDIO_FILE_SPREADSHEET_ODS_FLAT, params, convertParams); } else nRes = AVS_FILEUTILS_ERROR_CONVERT_PARAMS; + if (SUCCEEDED_X2T(nRes)) { - nRes = fromXlsxDir(sXlsxDir, sTo, nFormatTo, sTemp, sThemeDir, bPaid, params, sXlsxFile); + std::wstring sFileToCurrent = *params.m_sFileTo; + params.changeFormatFromPost(*params.m_nFormatFrom, params.m_bMacro); + + if (NULL != params.m_nFormatTo) + nFormatTo = *params.m_nFormatTo; + + nRes = fromXlsxDir(sXlsxDir, *params.m_sFileTo, nFormatTo, params, convertParams); } } return nRes; } - _UINT32 fromPptxDir( - const std::wstring &sFrom, const std::wstring &sTo, int nFormatTo, const std::wstring &sTemp, const std::wstring &sThemeDir, bool bPaid, InputParams ¶ms, const std::wstring &sPptxFile) + // from pptx + _UINT32 fromPptxDir(const std::wstring& sFrom, const std::wstring& sTo, int nFormatTo, InputParams& params, ConvertParams& convertParams) { _UINT32 nRes = 0; if (0 != (AVS_OFFICESTUDIO_FILE_PRESENTATION & nFormatTo)) { - if (AVS_OFFICESTUDIO_FILE_PRESENTATION_PPTX == nFormatTo || AVS_OFFICESTUDIO_FILE_PRESENTATION_PPTM == nFormatTo || AVS_OFFICESTUDIO_FILE_PRESENTATION_PPSX == nFormatTo || - AVS_OFFICESTUDIO_FILE_PRESENTATION_POTX == nFormatTo || AVS_OFFICESTUDIO_FILE_PRESENTATION_POTM == nFormatTo || AVS_OFFICESTUDIO_FILE_PRESENTATION_PPSM == nFormatTo) + if (AVS_OFFICESTUDIO_FILE_PRESENTATION_PPTX == nFormatTo || + AVS_OFFICESTUDIO_FILE_PRESENTATION_PPTM == nFormatTo || + AVS_OFFICESTUDIO_FILE_PRESENTATION_PPSX == nFormatTo || + AVS_OFFICESTUDIO_FILE_PRESENTATION_POTX == nFormatTo || + AVS_OFFICESTUDIO_FILE_PRESENTATION_POTM == nFormatTo || + AVS_OFFICESTUDIO_FILE_PRESENTATION_PPSM == nFormatTo) { - if (AVS_OFFICESTUDIO_FILE_PRESENTATION_PPTM == nFormatTo || AVS_OFFICESTUDIO_FILE_PRESENTATION_PPSX == nFormatTo || AVS_OFFICESTUDIO_FILE_PRESENTATION_POTX == nFormatTo || - AVS_OFFICESTUDIO_FILE_PRESENTATION_POTM == nFormatTo || AVS_OFFICESTUDIO_FILE_PRESENTATION_PPSM == nFormatTo) + if (AVS_OFFICESTUDIO_FILE_PRESENTATION_PPTM == nFormatTo || + AVS_OFFICESTUDIO_FILE_PRESENTATION_PPSX == nFormatTo || + AVS_OFFICESTUDIO_FILE_PRESENTATION_POTX == nFormatTo || + AVS_OFFICESTUDIO_FILE_PRESENTATION_POTM == nFormatTo || + AVS_OFFICESTUDIO_FILE_PRESENTATION_PPSM == nFormatTo) { std::wstring sCTFrom = _T("application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml"); switch (*params.m_nFormatFrom) @@ -4842,65 +1128,69 @@ namespace NExtractTools } if (SUCCEEDED_X2T(nRes)) { - nRes = dir2zipMscrypt(sFrom, sTo, sTemp, params); + nRes = dir2zipMscrypt(sFrom, sTo, params, convertParams); } } // else if (AVS_OFFICESTUDIO_FILE_PRESENTATION_PPT == nFormatTo) else if (AVS_OFFICESTUDIO_FILE_PRESENTATION_ODP == nFormatTo) { - nRes = pptx_dir2odp(sFrom, sTo, sTemp, params, false); + convertParams.m_bIsTemplate = false; + nRes = pptx_dir2odp(sFrom, sTo, params, convertParams); } else if (AVS_OFFICESTUDIO_FILE_PRESENTATION_OTP == nFormatTo) { - nRes = pptx_dir2odp(sFrom, sTo, sTemp, params, true); + convertParams.m_bIsTemplate = true; + nRes = pptx_dir2odp(sFrom, sTo, params, convertParams); } else nRes = AVS_FILEUTILS_ERROR_CONVERT_PARAMS; } else if (AVS_OFFICESTUDIO_FILE_OTHER_OOXML == nFormatTo) { - nRes = dir2zipMscrypt(sFrom, sTo, sTemp, params); + nRes = dir2zipMscrypt(sFrom, sTo, params, convertParams); } else if (AVS_OFFICESTUDIO_FILE_CANVAS_PRESENTATION == nFormatTo) { - nRes = pptx_dir2pptt_bin(sFrom, sTo, sTemp, params, sPptxFile); + nRes = pptx_dir2pptt_bin(sFrom, sTo, params, convertParams); } else if (AVS_OFFICESTUDIO_FILE_TEAMLAB_PPTY == nFormatTo) { - nRes = pptx_dir2pptt(sFrom, sTo, sTemp, params, sPptxFile); + nRes = pptx_dir2pptt(sFrom, sTo, params, convertParams); } else if ((0 != (AVS_OFFICESTUDIO_FILE_IMAGE & nFormatTo)) || AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_PDF == nFormatTo) { if (params.needConvertToOrigin(AVS_OFFICESTUDIO_FILE_PRESENTATION_PPTX)) { - std::wstring sToRender = sPptxFile; + std::wstring sToRender = convertParams.m_sTempParamOOXMLFile; if (sToRender.empty()) { - sToRender = sTemp + FILE_SEPARATOR_STR + _T("toRender.pptx"); + sToRender = combinePath(convertParams.m_sTempDir, L"toRender.pptx"); nRes = dir2zip(sFrom, sToRender); } NSDoctRenderer::DoctRendererFormat::FormatFile eFromType = NSDoctRenderer::DoctRendererFormat::FormatFile::PPTT; if (AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_PDF == nFormatTo) { - nRes = doct_bin2pdf(eFromType, sToRender, sTo, sTemp, bPaid, sThemeDir, params, sFrom); + convertParams.m_sInternalMediaDirectory = sFrom; + nRes = doct_bin2pdf(eFromType, sToRender, sTo, params, convertParams); } else if (0 != (AVS_OFFICESTUDIO_FILE_IMAGE & nFormatTo)) { - nRes = doct_bin2image(eFromType, sToRender, sTo, sTemp, bPaid, sThemeDir, params, sFrom); + convertParams.m_sInternalMediaDirectory = sFrom; + nRes = doct_bin2image(eFromType, sToRender, sTo, params, convertParams); } else nRes = AVS_FILEUTILS_ERROR_CONVERT_PARAMS; } else { - std::wstring sPpttDir = sTemp + FILE_SEPARATOR_STR + _T("pptt_unpacked"); + std::wstring sPpttDir = combinePath(convertParams.m_sTempDir, L"pptt_unpacked"); NSDirectory::CreateDirectory(sPpttDir); - std::wstring sTFile = sPpttDir + FILE_SEPARATOR_STR + _T("Editor.bin"); + std::wstring sTFile = combinePath(sPpttDir, L"Editor.bin"); - nRes = pptx_dir2pptt_bin(sFrom, sTFile, sTemp, params, sPptxFile); + nRes = pptx_dir2pptt_bin(sFrom, sTFile, params, convertParams); if (SUCCEEDED_X2T(nRes)) { - nRes = fromPpttBin(sTFile, sTo, nFormatTo, sTemp, sThemeDir, bPaid, params); + nRes = fromPpttBin(sTFile, sTo, nFormatTo, params, convertParams); } } } @@ -4908,7 +1198,7 @@ namespace NExtractTools nRes = AVS_FILEUTILS_ERROR_CONVERT_PARAMS; return nRes; } - _UINT32 fromPpttBin(const std::wstring &sFrom, const std::wstring &sTo, int nFormatTo, const std::wstring &sTemp, const std::wstring &sThemeDir, bool bPaid, InputParams ¶ms) + _UINT32 fromPpttBin(const std::wstring& sFrom, const std::wstring& sTo, int nFormatTo, InputParams& params, ConvertParams& convertParams) { _UINT32 nRes = 0; if (AVS_OFFICESTUDIO_FILE_TEAMLAB_PPTY == nFormatTo) @@ -4919,24 +1209,36 @@ namespace NExtractTools else if (AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_PDF == nFormatTo) { NSDoctRenderer::DoctRendererFormat::FormatFile eFromType = NSDoctRenderer::DoctRendererFormat::FormatFile::PPTT; - nRes = doct_bin2pdf(eFromType, sFrom, sTo, sTemp, bPaid, sThemeDir, params); + nRes = doct_bin2pdf(eFromType, sFrom, sTo, params, convertParams); } else if (0 != (AVS_OFFICESTUDIO_FILE_IMAGE & nFormatTo)) { NSDoctRenderer::DoctRendererFormat::FormatFile eFromType = NSDoctRenderer::DoctRendererFormat::FormatFile::PPTT; - nRes = doct_bin2image(eFromType, sFrom, sTo, sTemp, bPaid, sThemeDir, params); + nRes = doct_bin2image(eFromType, sFrom, sTo, params, convertParams); } - else if (0 != (AVS_OFFICESTUDIO_FILE_PRESENTATION & nFormatTo)) + else if (0 != (AVS_OFFICESTUDIO_FILE_PRESENTATION & nFormatTo) || + AVS_OFFICESTUDIO_FILE_OTHER_OOXML == nFormatTo || + AVS_OFFICESTUDIO_FILE_OTHER_ODF == nFormatTo) { - std::wstring sPptxDir = sTemp + FILE_SEPARATOR_STR + _T("pptx_unpacked"); + std::wstring sPptxDir = combinePath(convertParams.m_sTempDir, L"pptx_unpacked"); if (true == NSDirectory::CreateDirectory(sPptxDir)) { - params.m_bMacro = AVS_OFFICESTUDIO_FILE_PRESENTATION_PPTM == nFormatTo || AVS_OFFICESTUDIO_FILE_PRESENTATION_PPSM == nFormatTo || AVS_OFFICESTUDIO_FILE_PRESENTATION_POTM == nFormatTo; - nRes = pptt_bin2pptx_dir(sFrom, sTo, sPptxDir, sThemeDir, params); + params.m_bMacro = AVS_OFFICESTUDIO_FILE_PRESENTATION_PPTM == nFormatTo || + AVS_OFFICESTUDIO_FILE_PRESENTATION_PPSM == nFormatTo || + AVS_OFFICESTUDIO_FILE_PRESENTATION_POTM == nFormatTo; + + convertParams.m_sTempResultOOXMLDirectory = sPptxDir; + nRes = pptt_bin2pptx_dir(sFrom, sTo, params, convertParams); if (SUCCEEDED_X2T(nRes)) { - nRes = fromPptxDir(sPptxDir, sTo, nFormatTo, sTemp, sThemeDir, bPaid, params, L""); + std::wstring sFileToCurrent = *params.m_sFileTo; + params.changeFormatFromPost(*params.m_nFormatFrom, params.m_bMacro); + + if (NULL != params.m_nFormatTo) + nFormatTo = *params.m_nFormatTo; + + nRes = fromPptxDir(sPptxDir, *params.m_sFileTo, nFormatTo, params, convertParams); } } else @@ -4948,42 +1250,33 @@ namespace NExtractTools nRes = AVS_FILEUTILS_ERROR_CONVERT_PARAMS; return nRes; } - _UINT32 fromPresentation(const std::wstring &sFrom, int nFormatFrom, const std::wstring &sTemp, InputParams ¶ms) + _UINT32 fromPresentation(const std::wstring& sFrom, int nFormatFrom, InputParams& params, ConvertParams& convertParams) { - std::wstring sTo = *params.m_sFileTo; + std::wstring sTo = *params.m_sFileTo; + int nFormatTo = AVS_OFFICESTUDIO_FILE_UNKNOWN; if (NULL != params.m_nFormatTo) nFormatTo = *params.m_nFormatTo; - std::wstring sFontPath; - if (NULL != params.m_sFontDir) - sFontPath = *params.m_sFontDir; - std::wstring sThemeDir; - if (NULL != params.m_sThemeDir) - sThemeDir = *params.m_sThemeDir; - bool bPaid = true; - if (NULL != params.m_bPaid) - bPaid = *params.m_bPaid; _UINT32 nRes = 0; - std::wstring sPptxFile; - std::wstring sPptxDir = sTemp + FILE_SEPARATOR_STR + _T("pptx_unpacked"); + std::wstring sPptxDir = combinePath(convertParams.m_sTempDir, L"pptx_unpacked"); NSDirectory::CreateDirectory(sPptxDir); if (AVS_OFFICESTUDIO_FILE_PRESENTATION_PPTX == nFormatFrom) { - sPptxFile = sFrom; + convertParams.m_sTempParamOOXMLFile = sFrom; if (params.getFromChanges()) { params.setFromChanges(false); - nRes = apply_changes(sFrom, sTo, NSDoctRenderer::DoctRendererFormat::FormatFile::PPTT, sThemeDir, sPptxFile, params); + nRes = apply_changes(sFrom, sTo, NSDoctRenderer::DoctRendererFormat::FormatFile::PPTT, convertParams.m_sTempParamOOXMLFile, params, convertParams); } - nRes = zip2dir(sPptxFile, sPptxDir); + nRes = zip2dir(convertParams.m_sTempParamOOXMLFile, sPptxDir); } else if (AVS_OFFICESTUDIO_FILE_PRESENTATION_PPTM == nFormatFrom) { if (AVS_OFFICESTUDIO_FILE_PRESENTATION_PPTX == nFormatTo || AVS_OFFICESTUDIO_FILE_PRESENTATION_POTX == nFormatTo) { - nRes = pptm2pptx_dir(sFrom, sPptxDir, params); + nRes = pptm2pptx_dir(sFrom, sPptxDir, params, convertParams); } else { @@ -4994,65 +1287,84 @@ namespace NExtractTools { if (AVS_OFFICESTUDIO_FILE_PRESENTATION_PPTX == nFormatTo || AVS_OFFICESTUDIO_FILE_PRESENTATION_POTX == nFormatTo) { - nRes = ppsm2pptx_dir(sFrom, sPptxDir, params); + nRes = ppsm2pptx_dir(sFrom, sPptxDir, params, convertParams); } else { - nRes = ppsm2pptm_dir(sFrom, sPptxDir, params); + nRes = ppsm2pptm_dir(sFrom, sPptxDir, params, convertParams); } } else if (AVS_OFFICESTUDIO_FILE_PRESENTATION_PPT == nFormatFrom) { if (params.m_bMacro) { - nRes = ppt2pptm_dir(sFrom, sPptxDir, sTemp, params); + nRes = ppt2pptm_dir(sFrom, sPptxDir, params, convertParams); } else { - nRes = ppt2pptx_dir(sFrom, sPptxDir, sTemp, params); + nRes = ppt2pptx_dir(sFrom, sPptxDir, params, convertParams); } } else if (AVS_OFFICESTUDIO_FILE_PRESENTATION_ODP == nFormatFrom || AVS_OFFICESTUDIO_FILE_PRESENTATION_OTP == nFormatFrom) { - nRes = odf2oox_dir(sFrom, sPptxDir, sTemp, params); + nRes = odf2oox_dir(sFrom, sPptxDir, params, convertParams); } else if (AVS_OFFICESTUDIO_FILE_PRESENTATION_ODP_FLAT == nFormatFrom) { - nRes = odf_flat2oox_dir(sFrom, sPptxDir, sTemp, params); + nRes = odf_flat2oox_dir(sFrom, sPptxDir, params, convertParams); } else if (AVS_OFFICESTUDIO_FILE_PRESENTATION_PPSX == nFormatFrom) { - nRes = ppsx2pptx_dir(sFrom, sPptxDir, params); + nRes = ppsx2pptx_dir(sFrom, sPptxDir, params, convertParams); } else if (AVS_OFFICESTUDIO_FILE_PRESENTATION_POTX == nFormatFrom) { - nRes = potx2pptx_dir(sFrom, sPptxDir, params); + nRes = potx2pptx_dir(sFrom, sPptxDir, params, convertParams); } else if (AVS_OFFICESTUDIO_FILE_PRESENTATION_POTM == nFormatFrom) { if (AVS_OFFICESTUDIO_FILE_PRESENTATION_PPTX == nFormatTo || AVS_OFFICESTUDIO_FILE_PRESENTATION_POTX == nFormatTo) { - nRes = potm2pptx_dir(sFrom, sPptxDir, params); + nRes = potm2pptx_dir(sFrom, sPptxDir, params, convertParams); } else { - nRes = potm2pptm_dir(sFrom, sPptxDir, params); + nRes = potm2pptm_dir(sFrom, sPptxDir, params, convertParams); } } else if (AVS_OFFICESTUDIO_FILE_PRESENTATION_PPTX_PACKAGE == nFormatFrom) { - nRes = package2ooxml_dir(sFrom, sPptxDir, sTemp, params); + nRes = package2ooxml_dir(sFrom, sPptxDir, params, convertParams); + } + else if (AVS_OFFICESTUDIO_FILE_PRESENTATION_KEY == nFormatFrom) + { + std::wstring wsTempFile = combinePath(convertParams.m_sTempDir, L"IntermediateFile.odf"); + + int nIntermediateResult = key2odf(sFrom, wsTempFile, params, convertParams); + + if (S_OK != nIntermediateResult) + return nIntermediateResult; + + nRes = fromPresentation(wsTempFile, AVS_OFFICESTUDIO_FILE_PRESENTATION_ODP_FLAT, params, convertParams); } else nRes = AVS_FILEUTILS_ERROR_CONVERT_PARAMS; + if (SUCCEEDED_X2T(nRes)) { - nRes = fromPptxDir(sPptxDir, sTo, nFormatTo, sTemp, sThemeDir, bPaid, params, sPptxFile); + std::wstring sFileToCurrent = *params.m_sFileTo; + params.changeFormatFromPost(*params.m_nFormatFrom, params.m_bMacro); + + if (NULL != params.m_nFormatTo) + nFormatTo = *params.m_nFormatTo; + + nRes = fromPptxDir(sPptxDir, *params.m_sFileTo, nFormatTo, params, convertParams); } return nRes; } - _UINT32 fromT(const std::wstring &sFrom, int nFormatFrom, const std::wstring &sTo, int nFormatTo, const std::wstring &sTemp, const std::wstring &sThemeDir, bool bPaid, InputParams ¶ms) + // from T + _UINT32 fromT(const std::wstring& sFrom, int nFormatFrom, const std::wstring& sTo, int nFormatTo, InputParams& params, ConvertParams& convertParams) { _UINT32 nRes = 0; if (0 != (AVS_OFFICESTUDIO_FILE_CANVAS & nFormatTo)) @@ -5062,18 +1374,18 @@ namespace NExtractTools } else { - std::wstring sTDir = sTemp + FILE_SEPARATOR_STR + _T("doct_unpacked"); + std::wstring sTDir = combinePath(convertParams.m_sTempDir, L"doct_unpacked"); NSDirectory::CreateDirectory(sTDir); - std::wstring sTFile = sTDir + FILE_SEPARATOR_STR + _T("Editor.bin"); + std::wstring sTFile = combinePath(sTDir, L"Editor.bin"); nRes = zip2dir(sFrom, sTDir); if (SUCCEEDED_X2T(nRes)) { if (AVS_OFFICESTUDIO_FILE_TEAMLAB_DOCY == nFormatFrom) - nRes = fromDoctBin(sTFile, sTo, nFormatTo, sTemp, sThemeDir, bPaid, params); + nRes = fromDoctBin(sTFile, sTo, nFormatTo, params, convertParams); else if (AVS_OFFICESTUDIO_FILE_TEAMLAB_XLSY == nFormatFrom) - nRes = fromXlstBin(sTFile, sTo, nFormatTo, sTemp, sThemeDir, bPaid, params); + nRes = fromXlstBin(sTFile, sTo, nFormatTo, params, convertParams); else if (AVS_OFFICESTUDIO_FILE_TEAMLAB_PPTY == nFormatFrom) - nRes = fromPpttBin(sTFile, sTo, nFormatTo, sTemp, sThemeDir, bPaid, params); + nRes = fromPpttBin(sTFile, sTo, nFormatTo, params, convertParams); else nRes = AVS_FILEUTILS_ERROR_CONVERT_PARAMS; } @@ -5081,445 +1393,93 @@ namespace NExtractTools return nRes; } - bool applyChangesPdf(const std::wstring& sFrom, const std::wstring& sTo, - NSFonts::IApplicationFonts* pApplicationFonts, - const std::wstring &sTemp, InputParams& params, - std::vector& changes) - { - CPdfFile oPdfResult(pApplicationFonts); - oPdfResult.SetTempDirectory(sTemp); - oPdfResult.SetDocumentInfo(params.getTitle(), L"", L"", L""); - - std::wstring documentID = params.getDocumentID(); - if (!documentID.empty()) - oPdfResult.SetDocumentID(documentID); - - std::wstring password = params.getSavePassword(); - if (!oPdfResult.LoadFromFile(sFrom, L"", password, password)) - return false; - - if (!oPdfResult.EditPdf(sTo)) - return false; - - CConvertFromBinParams oConvertParams; - oConvertParams.m_sInternalMediaDirectory = NSFile::GetDirectoryName(sFrom); - oConvertParams.m_sMediaDirectory = oConvertParams.m_sInternalMediaDirectory; - - for (std::vector::const_iterator i = changes.begin(); i != changes.end(); i++) - { - BYTE* pChangesData = NULL; - DWORD dwChangesSize = 0; - if (NSFile::CFileBinary::ReadAllBytes(*i, &pChangesData, dwChangesSize)) - { - oPdfResult.AddToPdfFromBinary(pChangesData, (unsigned int)dwChangesSize, &oConvertParams); - RELEASEARRAYOBJECTS(pChangesData); - } - } - - oPdfResult.Close(); - return true; - } - - _UINT32 - fromCrossPlatform(const std::wstring &sFromSrc, int nFormatFrom, const std::wstring &sTo, int nFormatTo, const std::wstring &sTemp, const std::wstring &sThemeDir, bool bPaid, InputParams ¶ms) + // visio + _UINT32 fromVsdxDir(const std::wstring& sFrom, const std::wstring& sTo, int nFormatTo, InputParams& params, ConvertParams& convertParams) { _UINT32 nRes = 0; - NSFonts::IApplicationFonts *pApplicationFonts = NSFonts::NSApplication::Create(); - initApplicationFonts(pApplicationFonts, params); - - std::wstring sFrom = sFromSrc; - if (AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_PDF == nFormatFrom || - AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_PDFA == nFormatFrom) - { - if (params.getFromChanges()) - { - std::wstring sChangesDir = NSDirectory::GetFolderPath(sFrom) + FILE_SEPARATOR_STR + L"changes"; - std::vector arChanges = NSDirectory::GetFiles(sChangesDir); - - sFrom = NSFile::CFileBinary::CreateTempFileWithUniqueName(sTemp, L"PDF_"); - if (NSFile::CFileBinary::Exists(sFrom)) - NSFile::CFileBinary::Remove(sFrom); - - if (!applyChangesPdf(sFromSrc, sFrom, pApplicationFonts, sTemp, params, arChanges)) - { - if (NSFile::CFileBinary::Exists(sFrom)) - NSFile::CFileBinary::Remove(sFrom); - - sFrom = sFromSrc; - } - } - } - - if (AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_PDF == nFormatTo) + if (0 != (AVS_OFFICESTUDIO_FILE_DRAW & nFormatTo)) { - std::string sPages = checkPrintPages(params); - - if (nFormatFrom == nFormatTo && !params.getIsPDFA() && params.getPassword() == params.getSavePassword() && sPages.empty()) - { - if (sFrom == sFromSrc) - nRes = NSFile::CFileBinary::Copy(sFrom, sTo) ? 0 : AVS_FILEUTILS_ERROR_CONVERT; - else - { - nRes = NSFile::CFileBinary::Move(sFrom, sTo) ? 0 : AVS_FILEUTILS_ERROR_CONVERT; - sFrom = sFromSrc; - } - } - else + if (AVS_OFFICESTUDIO_FILE_DRAW_VSDX == nFormatTo) { - CPdfFile pdfWriter(pApplicationFonts); - pdfWriter.CreatePdf(params.getIsPDFA()); - pdfWriter.SetTempDirectory(sTemp); - pdfWriter.SetDocumentInfo(params.getTitle(), L"", L"", L""); - - std::wstring documentID = params.getDocumentID(); - if (false == documentID.empty()) - pdfWriter.SetDocumentID(documentID); - - std::wstring password = params.getSavePassword(); - if (false == password.empty()) - pdfWriter.SetPassword(password); - - IOfficeDrawingFile *pReader = NULL; - nRes = PdfDjvuXpsToRenderer(&pReader, &pdfWriter, sFrom, nFormatFrom, sTo, sTemp, params, pApplicationFonts, sPages); if (SUCCEEDED_X2T(nRes)) - nRes = S_OK == pdfWriter.SaveToFile(sTo) ? 0 : AVS_FILEUTILS_ERROR_CONVERT; - RELEASEOBJECT(pReader); - } - } - else if (0 != (AVS_OFFICESTUDIO_FILE_CANVAS & nFormatTo)) - { - if (params.needConvertToOrigin(nFormatFrom)) - { - copyOrigin(sFrom, *params.m_sFileTo); - } - else - { - std::wstring sToDir = NSSystemPath::GetDirectoryName(sTo); - if (!params.getDontSaveAdditional()) { - // save origin to print - copyOrigin(sFrom, *params.m_sFileTo); + nRes = dir2zipMscrypt(sFrom, sTo, params, convertParams); } - NSHtmlRenderer::CASCHTMLRenderer3 oHtmlRenderer; - oHtmlRenderer.CreateOfficeFile(sToDir); - IOfficeDrawingFile *pReader = NULL; - nRes = PdfDjvuXpsToRenderer(&pReader, &oHtmlRenderer, sFrom, nFormatFrom, sTo, sTemp, params, pApplicationFonts); - oHtmlRenderer.CloseFile(params.getIsNoBase64()); - RELEASEOBJECT(pReader); } + else + nRes = AVS_FILEUTILS_ERROR_CONVERT_PARAMS; } - else if (0 != (AVS_OFFICESTUDIO_FILE_IMAGE & nFormatTo)) - { - IOfficeDrawingFile *pReader = NULL; - nRes = PdfDjvuXpsToImage(&pReader, sFrom, nFormatFrom, sTo, sTemp, params, pApplicationFonts); - RELEASEOBJECT(pReader); - } - else + else if ((0 != (AVS_OFFICESTUDIO_FILE_IMAGE & nFormatTo)) || AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_PDF == nFormatTo) { - switch (nFormatTo) + std::wstring sToRender = convertParams.m_sTempParamOOXMLFile; + if (sToRender.empty()) { - case AVS_OFFICESTUDIO_FILE_OTHER_OOXML: - nFormatTo = AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX; - break; - case AVS_OFFICESTUDIO_FILE_OTHER_ODF: - nFormatTo = AVS_OFFICESTUDIO_FILE_DOCUMENT_ODT; - break; + sToRender = combinePath(convertParams.m_sTempDir, L"toRender.vsdx"); + nRes = dir2zip(sFrom, sToRender); } - - IOfficeDrawingFile *pReader = NULL; - switch (nFormatFrom) + NSDoctRenderer::DoctRendererFormat::FormatFile eFromType = NSDoctRenderer::DoctRendererFormat::FormatFile::VSDT; + if (AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_PDF == nFormatTo) { - case AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_PDF: - pReader = new CPdfFile(pApplicationFonts); - break; - case AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_XPS: - pReader = new CXpsFile(pApplicationFonts); - break; - case AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_DJVU: - pReader = new CDjVuFile(pApplicationFonts); - break; - default: - break; + convertParams.m_sInternalMediaDirectory = sFrom; + nRes = doct_bin2pdf(eFromType, sToRender, sTo, params, convertParams); } - - if (pReader) + else if (0 != (AVS_OFFICESTUDIO_FILE_IMAGE & nFormatTo)) { - pReader->SetTempDirectory(sTemp); - - std::wstring sPassword = params.getPassword(); - pReader->LoadFromFile(sFrom, L"", sPassword, sPassword); - - CDocxRenderer oDocxRenderer(pApplicationFonts); - - NSDocxRenderer::TextAssociationType taType = NSDocxRenderer::tatPlainLine; - if (params.m_oTextParams) - { - InputParamsText *oTextParams = params.m_oTextParams; - if (oTextParams->m_nTextAssociationType) - // taType = static_cast(*oTextParams->m_nTextAssociationType); - { - switch (*oTextParams->m_nTextAssociationType) - { - case 0: - taType = NSDocxRenderer::tatBlockChar; - break; - case 1: - taType = NSDocxRenderer::tatBlockLine; - break; - case 2: - taType = NSDocxRenderer::tatPlainLine; - break; - case 3: - taType = NSDocxRenderer::tatPlainParagraph; - break; - default: - break; - } - } - } - oDocxRenderer.SetTextAssociationType(taType); - - std::wstring sTempDirOut = sTemp + L"/output"; - if (!NSDirectory::Exists(sTempDirOut)) - NSDirectory::CreateDirectory(sTempDirOut); - - oDocxRenderer.SetTempFolder(sTempDirOut); - bool bIsOutCompress = AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX == nFormatTo && !params.hasSavePassword(); - nRes = oDocxRenderer.Convert(pReader, sTo, bIsOutCompress); - - if (nRes == S_OK && !bIsOutCompress) - nRes = fromDocxDir(sTempDirOut, sTo, nFormatTo, sTemp, sThemeDir, bPaid, params, L""); + convertParams.m_sInternalMediaDirectory = sFrom; + nRes = doct_bin2image(eFromType, sToRender, sTo, params, convertParams); } else nRes = AVS_FILEUTILS_ERROR_CONVERT_PARAMS; - RELEASEOBJECT(pReader); - } - RELEASEOBJECT(pApplicationFonts); - - if (sFrom != sFromSrc && NSFile::CFileBinary::Exists(sFrom)) - NSFile::CFileBinary::Remove(sFrom); - return nRes; - } - _UINT32 fromCanvasPdf(const std::wstring &sFrom, int nFormatFrom, const std::wstring &sTo, int nFormatTo, const std::wstring &sTemp, const std::wstring &sThemeDir, bool bPaid, InputParams ¶ms) - { - _UINT32 nRes = 0; - if (AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_PDF == nFormatTo) - { - nRes = bin2pdf(sFrom, sTo, sTemp, bPaid, sThemeDir, params); - } - else if (0 != (AVS_OFFICESTUDIO_FILE_IMAGE & nFormatTo)) - { - nRes = bin2imageBase64(sFrom, sTo, sTemp, sThemeDir, params); } else - { nRes = AVS_FILEUTILS_ERROR_CONVERT_PARAMS; - } - return nRes; - } - - // xls -> xlsx - _UINT32 xls2xlsx(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - std::wstring sResultDocxDir = sTemp + FILE_SEPARATOR_STR + _T("xlsx_unpacked"); - - NSDirectory::CreateDirectory(sResultDocxDir); - - _UINT32 hRes = xls2xlsx_dir(sFrom, sResultDocxDir, sTemp, params); - - if (SUCCEEDED_X2T(hRes)) - { - hRes = dir2zipMscrypt(sResultDocxDir, sTo, sTemp, params); - } - return hRes; - } - _UINT32 xls2xlsx_dir(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - params.m_bMacro = false; - - int lcid = (NULL != params.m_nLcid) ? *params.m_nLcid : -1; - - _UINT32 nRes = ConvertXls2Xlsx(sFrom, sTo, params.getPassword(), params.getFontPath(), sTemp, lcid, params.m_bMacro); - - nRes = processEncryptionError(nRes, sFrom, params); - return nRes; - } - // xls -> xlsm - _UINT32 xls2xlsm(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - std::wstring sResultXlsmDir = sTemp + FILE_SEPARATOR_STR + _T("xlsm_unpacked"); - - NSDirectory::CreateDirectory(sResultXlsmDir); - - _UINT32 nRes = xls2xlsm_dir(sFrom, sResultXlsmDir, sTemp, params); - - if (SUCCEEDED_X2T(nRes)) - { - COfficeUtils oCOfficeUtils(NULL); - if (S_OK == oCOfficeUtils.CompressFileOrDirectory(sResultXlsmDir, sTo, true)) - return 0; - } - return nRes; - } - _UINT32 xls2xlsm_dir(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - params.m_bMacro = true; - - int lcid = (NULL != params.m_nLcid) ? *params.m_nLcid : -1; - - _UINT32 nRes = ConvertXls2Xlsx(sFrom, sTo, params.getPassword(), params.getFontPath(), sTemp, lcid, params.m_bMacro); - - nRes = processEncryptionError(nRes, sFrom, params); - return nRes; - } - // xls -> xlst - _UINT32 xls2xlst(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - // Extract xlsx to temp directory - std::wstring sResultDoctDir = sTemp + FILE_SEPARATOR_STR + _T("xlst_unpacked"); - std::wstring sResultDoctFileEditor = sResultDoctDir + FILE_SEPARATOR_STR + _T("Editor.bin"); - - NSDirectory::CreateDirectory(sResultDoctDir); - - _UINT32 nRes = xls2xlst_bin(sFrom, sResultDoctFileEditor, sTemp, params); - - if (SUCCEEDED_X2T(nRes)) - { - COfficeUtils oCOfficeUtils(NULL); - nRes = (S_OK == oCOfficeUtils.CompressFileOrDirectory(sResultDoctDir, sTo)) ? nRes : AVS_FILEUTILS_ERROR_CONVERT; - } - - return nRes; - } - - // xls -> xlst_bin - _UINT32 xls2xlst_bin(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - std::wstring sResultXlsxDir = sTemp + FILE_SEPARATOR_STR + _T("xlsx_unpacked"); - - NSDirectory::CreateDirectory(sResultXlsxDir); - - params.m_bMacro = true; - - int lcid = (NULL != params.m_nLcid) ? *params.m_nLcid : -1; - - _UINT32 nRes = ConvertXls2Xlsx(sFrom, sResultXlsxDir, params.getPassword(), params.getFontPath(), sTemp, lcid, params.m_bMacro); - - nRes = processEncryptionError(nRes, sFrom, params); - if (SUCCEEDED_X2T(nRes)) - { - BinXlsxRW::CXlsxSerializer oCXlsxSerializer; - - oCXlsxSerializer.setFontDir(params.getFontPath()); - - return oCXlsxSerializer.saveToFile(sTo, sResultXlsxDir, params.getXmlOptions()); - } - return nRes; - } - _UINT32 html2doct_bin(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - std::wstring sDocxDir = sTemp + FILE_SEPARATOR_STR + _T("docx_unpacked"); - NSDirectory::CreateDirectory(sDocxDir); - _UINT32 nRes = html2docx_dir(sFrom, sDocxDir, sTemp, params); - if (SUCCEEDED_X2T(nRes)) - { - nRes = (S_OK == docx_dir2doct_bin(sDocxDir, sTo, sTemp, params, L"")) ? nRes : AVS_FILEUTILS_ERROR_CONVERT; - } - return nRes; - } - _UINT32 html_zip2doct_bin(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - std::wstring sDocxDir = sTemp + FILE_SEPARATOR_STR + _T("docx_unpacked"); - NSDirectory::CreateDirectory(sDocxDir); - _UINT32 nRes = html_zip2docx_dir(sFrom, sDocxDir, sTemp, params); - if (SUCCEEDED_X2T(nRes)) - { - nRes = (S_OK == docx_dir2doct_bin(sDocxDir, sTo, sTemp, params, L"")) ? nRes : AVS_FILEUTILS_ERROR_CONVERT; - } return nRes; } - _UINT32 html2doct(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - std::wstring sResultDoctDir = sTemp + FILE_SEPARATOR_STR + _T("doct_unpacked"); - std::wstring sResultDoctFileEditor = sResultDoctDir + FILE_SEPARATOR_STR + _T("Editor.bin"); - - NSDirectory::CreateDirectory(sResultDoctDir); - - _UINT32 nRes = html2doct_bin(sFrom, sResultDoctFileEditor, sTemp, params); - if (SUCCEEDED_X2T(nRes)) - { - COfficeUtils oCOfficeUtils(NULL); - nRes = (S_OK == oCOfficeUtils.CompressFileOrDirectory(sResultDoctDir, sTo)) ? nRes : AVS_FILEUTILS_ERROR_CONVERT; - } - return nRes; - } - _UINT32 html_zip2doct(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) + _UINT32 fromDraw(const std::wstring& sFrom, int nFormatFrom, InputParams& params, ConvertParams& convertParams) { - std::wstring sResultDoctDir = sTemp + FILE_SEPARATOR_STR + _T("doct_unpacked"); - std::wstring sResultDoctFileEditor = sResultDoctDir + FILE_SEPARATOR_STR + _T("Editor.bin"); - - NSDirectory::CreateDirectory(sResultDoctDir); + std::wstring sTo = *params.m_sFileTo; + int nFormatTo = AVS_OFFICESTUDIO_FILE_UNKNOWN; + if (NULL != params.m_nFormatTo) + nFormatTo = *params.m_nFormatTo; - _UINT32 nRes = html_zip2doct_bin(sFrom, sResultDoctFileEditor, sTemp, params); + _UINT32 nRes = 0; + std::wstring sVsdxDir = combinePath(convertParams.m_sTempDir, L"xsdx_unpacked"); + NSDirectory::CreateDirectory(sVsdxDir); - if (SUCCEEDED_X2T(nRes)) + if (0 != (AVS_OFFICESTUDIO_FILE_DRAW & nFormatFrom)) { - COfficeUtils oCOfficeUtils(NULL); - nRes = (S_OK == oCOfficeUtils.CompressFileOrDirectory(sResultDoctDir, sTo)) ? nRes : AVS_FILEUTILS_ERROR_CONVERT; + convertParams.m_sTempParamOOXMLFile = sFrom; + if (params.getFromChanges()) + { + params.setFromChanges(false); + nRes = apply_changes(sFrom, sTo, NSDoctRenderer::DoctRendererFormat::FormatFile::VSDT, convertParams.m_sTempParamOOXMLFile, params, convertParams); + } + nRes = zip2dir(sFrom, sVsdxDir); } - return nRes; - } - _UINT32 html2docx(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - std::wstring sDocxDir = sTemp + FILE_SEPARATOR_STR + _T("docx_unpacked"); - NSDirectory::CreateDirectory(sDocxDir); - - _UINT32 nRes = html2docx_dir(sFrom, sDocxDir, sTemp, params); + else + nRes = AVS_FILEUTILS_ERROR_CONVERT_PARAMS; if (SUCCEEDED_X2T(nRes)) { - nRes = dir2zipMscrypt(sDocxDir, sTo, sTemp, params); - } - return nRes; - } + std::wstring sFileToCurrent = *params.m_sFileTo; + params.changeFormatFromPost(*params.m_nFormatFrom, params.m_bMacro); - _UINT32 html_zip2docx(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms) - { - std::wstring sDocxDir = sTemp + FILE_SEPARATOR_STR + _T("docx_unpacked"); - NSDirectory::CreateDirectory(sDocxDir); - - _UINT32 nRes = html_zip2docx_dir(sFrom, sDocxDir, sTemp, params); - if (SUCCEEDED_X2T(nRes)) - { - COfficeUtils oCOfficeUtils(NULL); - nRes = (S_OK == oCOfficeUtils.CompressFileOrDirectory(sDocxDir, sTo, true)) ? nRes : AVS_FILEUTILS_ERROR_CONVERT; + if (NULL != params.m_nFormatTo) + nFormatTo = *params.m_nFormatTo; + + nRes = fromVsdxDir(sVsdxDir, sTo, nFormatTo, params, convertParams); } return nRes; } //------------------------------------------------------------------------------------------------------------------ - _UINT32 detectMacroInFile(InputParams &oInputParams) - { - _UINT32 nRes = 0; // no macro - std::wstring sFileFrom = *oInputParams.m_sFileFrom; - - COfficeFileFormatChecker OfficeFileFormatChecker; - - if (OfficeFileFormatChecker.isOfficeFile(sFileFrom)) - { - if (OfficeFileFormatChecker.bMacroEnabled) - { - nRes = AVS_ERROR_MACRO; - } - } - return nRes; - } - _UINT32 fromInputParams(InputParams &oInputParams) + _UINT32 fromInputParams(InputParams& oInputParams) { TConversionDirection conversion = oInputParams.getConversionDirection(); - std::wstring sFileFrom = *oInputParams.m_sFileFrom; - std::wstring sFileTo = *oInputParams.m_sFileTo; + + std::wstring sFileFrom = oInputParams.m_sFileFrom ? *oInputParams.m_sFileFrom : L""; + std::wstring sFileTo = oInputParams.m_sFileTo ? *oInputParams.m_sFileTo : L""; int nFormatFrom = AVS_OFFICESTUDIO_FILE_UNKNOWN; if (NULL != oInputParams.m_nFormatFrom) @@ -5546,37 +1506,44 @@ namespace NExtractTools return AVS_FILEUTILS_ERROR_CONVERT_PARAMS; } - bool bPaid = true; + ConvertParams oConvertParams; + if (NULL != oInputParams.m_bPaid) - bPaid = *oInputParams.m_bPaid; - std::wstring sThemeDir; + oConvertParams.m_bIsPaid = *oInputParams.m_bPaid; + if (NULL != oInputParams.m_sThemeDir) - sThemeDir = *oInputParams.m_sThemeDir; + oConvertParams.m_sThemesDir = *oInputParams.m_sThemeDir; + InputParamsMailMerge *oMailMerge = NULL; if (NULL != oInputParams.m_oMailMergeSend) oMailMerge = oInputParams.m_oMailMergeSend; bool bExternalTempDir = false; - std::wstring sTempDir; if (NULL != oInputParams.m_sTempDir) { bExternalTempDir = true; - sTempDir = *oInputParams.m_sTempDir; + oConvertParams.m_sTempDir = *oInputParams.m_sTempDir; } else { - sTempDir = NSDirectory::CreateDirectoryWithUniqueName(NSDirectory::GetFolderPath(sFileTo)); + oConvertParams.m_sTempDir = NSDirectory::CreateDirectoryWithUniqueName(NSDirectory::GetFolderPath(sFileTo)); } - if (sTempDir.empty()) + if (oConvertParams.m_sTempDir.empty()) { std::cerr << "Couldn't create temp folder" << std::endl; return AVS_FILEUTILS_ERROR_UNKNOWN; } - NSFile::CFileBinary::SetTempPath(sTempDir); + std::wstring sGlobalTempDir = L""; + if (NSFile::CFileBinary::IsGlobalTempPathUse()) + sGlobalTempDir = NSFile::CFileBinary::GetTempPath(); + + NSFile::CFileBinary::SetTempPath(oConvertParams.m_sTempDir); if (!oInputParams.checkInputLimits()) { + if (!sGlobalTempDir.empty()) + NSFile::CFileBinary::SetTempPath(sGlobalTempDir); return AVS_FILEUTILS_ERROR_CONVERT_LIMITS; } @@ -5592,218 +1559,230 @@ namespace NExtractTools result = AVS_FILEUTILS_ERROR_CONVERT_DETECT; } break; + case TCD_DOC2DOCT: + { + result = doc2doct(sFileFrom, sFileTo, oInputParams, oConvertParams); + } + break; case TCD_DOCX2DOCT: { - result = docx2doct(sFileFrom, sFileTo, sTempDir, oInputParams); + result = docx2doct(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_DOCXFLAT2DOCT: { - result = docxflat2doct(sFileFrom, sFileTo, sTempDir, oInputParams); + result = docxflat2doct(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_DOCXFLAT2DOCT_BIN: { - result = docxflat2doct_bin(sFileFrom, sFileTo, sTempDir, oInputParams); + result = docxflat2doct_bin(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_PKG2BIN_T: { - result = package2bin_t(sFileFrom, sFileTo, sTempDir, oInputParams); + result = package2bin_t(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_PKG2BIN: { - result = package2bin(sFileFrom, sFileTo, sTempDir, oInputParams); + result = package2bin(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_PKG2OOXML: { oInputParams.m_nFormatTo = new int(AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX); - result = package2ooxml(sFileFrom, sFileTo, sTempDir, oInputParams); + result = package2ooxml(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_DOCT2DOCX: { oInputParams.m_bMacro = false; oInputParams.m_nFormatTo = new int(AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX); - result = doct2docx(sFileFrom, sFileTo, sTempDir, sThemeDir, oInputParams); + result = doct2docx(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_DOCT2DOTX: { oInputParams.m_bMacro = false; oInputParams.m_nFormatTo = new int(AVS_OFFICESTUDIO_FILE_DOCUMENT_DOTX); - result = doct2docx(sFileFrom, sFileTo, sTempDir, sThemeDir, oInputParams); + result = doct2docx(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_DOCT2OFORM: { oInputParams.m_bMacro = false; oInputParams.m_nFormatTo = new int(AVS_OFFICESTUDIO_FILE_DOCUMENT_OFORM); - result = doct2docx(sFileFrom, sFileTo, sTempDir, sThemeDir, oInputParams); + result = doct2docx(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_DOCT2DOCXF: { oInputParams.m_bMacro = false; oInputParams.m_nFormatTo = new int(AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCXF); - result = doct2docx(sFileFrom, sFileTo, sTempDir, sThemeDir, oInputParams); + result = doct2docx(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_DOCT2DOCM: { oInputParams.m_bMacro = true; oInputParams.m_nFormatTo = new int(AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCM); - result = doct2docx(sFileFrom, sFileTo, sTempDir, sThemeDir, oInputParams); + result = doct2docx(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_XLSX2XLST: { - result = xlsx2xlst(sFileFrom, sFileTo, sTempDir, oInputParams); + result = xlsx2xlst(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_XLSB2XLST: { oInputParams.m_nFormatFrom = new int(AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSB); - result = xlsx2xlst(sFileFrom, sFileTo, sTempDir, oInputParams); + result = xlsx2xlst(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_XLSXFLAT2XLST: { - result = xlsxflat2xlst(sFileFrom, sFileTo, sTempDir, oInputParams); + result = xlsxflat2xlst(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_XLSXFLAT2XLST_BIN: { - result = xlsxflat2xlst_bin(sFileFrom, sFileTo, sTempDir, oInputParams); + result = xlsxflat2xlst_bin(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_XLSXFLAT2XLSX: { - result = xlsxflat2xlsx(sFileFrom, sFileTo, sTempDir, oInputParams); + result = xlsxflat2xlsx(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_XLST2XLSX: { oInputParams.m_bMacro = false; oInputParams.m_nFormatTo = new int(AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSX); - result = xlst2xlsx(sFileFrom, sFileTo, sTempDir, sThemeDir, oInputParams); + result = xlst2xlsx(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_XLST2XLSM: { oInputParams.m_bMacro = true; oInputParams.m_nFormatTo = new int(AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSM); - result = xlst2xlsx(sFileFrom, sFileTo, sTempDir, sThemeDir, oInputParams); + result = xlst2xlsx(sFileFrom, sFileTo, oInputParams, oConvertParams); + } + break; + case TCD_XLST2XLSB: + { + oInputParams.m_bMacro = true; + oInputParams.m_nFormatTo = new int(AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSB); + result = xlst2xlsb(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_XLST2XLTX: { oInputParams.m_bMacro = false; oInputParams.m_nFormatTo = new int(AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLTX); - result = xlst2xlsx(sFileFrom, sFileTo, sTempDir, sThemeDir, oInputParams); + result = xlst2xlsx(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_PPTX2PPTT: { - result = pptx2pptt(sFileFrom, sFileTo, sTempDir, oInputParams); + result = pptx2pptt(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_PPTT2PPTX: { oInputParams.m_bMacro = false; oInputParams.m_nFormatTo = new int(AVS_OFFICESTUDIO_FILE_PRESENTATION_PPTX); - result = pptt2pptx(sFileFrom, sFileTo, sTempDir, sThemeDir, oInputParams); + result = pptt2pptx(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_PPTT2PPTM: { oInputParams.m_bMacro = true; oInputParams.m_nFormatTo = new int(AVS_OFFICESTUDIO_FILE_PRESENTATION_PPTM); - result = pptt2pptx(sFileFrom, sFileTo, sTempDir, sThemeDir, oInputParams); + result = pptt2pptx(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_PPTT2POTX: { oInputParams.m_bMacro = false; oInputParams.m_nFormatTo = new int(AVS_OFFICESTUDIO_FILE_PRESENTATION_POTX); - result = pptt2pptx(sFileFrom, sFileTo, sTempDir, sThemeDir, oInputParams); + result = pptt2pptx(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_DOTX2DOCX: { - result = dotx2docx(sFileFrom, sFileTo, sTempDir, oInputParams); + result = dotx2docx(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_DOCM2DOCX: { - result = docm2docx(sFileFrom, sFileTo, sTempDir, oInputParams); + result = docm2docx(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_DOTM2DOCX: { - result = dotm2docx(sFileFrom, sFileTo, sTempDir, oInputParams); + result = dotm2docx(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_DOTM2DOCM: { - result = dotm2docm(sFileFrom, sFileTo, sTempDir, oInputParams); + result = dotm2docm(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_XLTX2XLSX: { - result = xltx2xlsx(sFileFrom, sFileTo, sTempDir, oInputParams); + result = xltx2xlsx(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_XLSM2XLSX: { - result = xltx2xlsx(sFileFrom, sFileTo, sTempDir, oInputParams); + result = xltx2xlsx(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_XLTM2XLSX: { - result = xltm2xlsx(sFileFrom, sFileTo, sTempDir, oInputParams); + result = xltm2xlsx(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_XLTM2XLSM: { - result = xltm2xlsm(sFileFrom, sFileTo, sTempDir, oInputParams); + result = xltm2xlsm(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_PPSX2PPTX: { - result = ppsx2pptx(sFileFrom, sFileTo, sTempDir, oInputParams); + result = ppsx2pptx(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_POTX2PPTX: { - result = potx2pptx(sFileFrom, sFileTo, sTempDir, oInputParams); + result = potx2pptx(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_POTM2PPTX: { - result = potm2pptx(sFileFrom, sFileTo, sTempDir, oInputParams); + result = potm2pptx(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_PPSM2PPTX: { - result = ppsm2pptx(sFileFrom, sFileTo, sTempDir, oInputParams); + result = ppsm2pptx(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_POTM2PPTM: { - result = potm2pptm(sFileFrom, sFileTo, sTempDir, oInputParams); + result = potm2pptm(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_PPSM2PPTM: { - result = ppsm2pptm(sFileFrom, sFileTo, sTempDir, oInputParams); + result = ppsm2pptm(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_PPTM2PPTX: { - result = pptm2pptx(sFileFrom, sFileTo, sTempDir, oInputParams); + result = pptm2pptx(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_ZIPDIR: @@ -5818,62 +1797,62 @@ namespace NExtractTools break; case TCD_XML2XLSX: { - result = xml2xlsx(sFileFrom, sFileTo, sTempDir, oInputParams); + result = xml2xlsx(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_CSV2XLSX: { - result = csv2xlsx(sFileFrom, sFileTo, sTempDir, oInputParams); + result = csv2xlsx(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_CSV2XLST: { - result = csv2xlst(sFileFrom, sFileTo, sTempDir, oInputParams); + result = csv2xlst(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_XLSX2CSV: { - result = xlsx2csv(sFileFrom, sFileTo, sTempDir, oInputParams); + result = xlsx2csv(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_XLST2CSV: { - result = xlst2csv(sFileFrom, sFileTo, sTempDir, oInputParams); + result = xlst2csv(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_DOCX2DOCT_BIN: { - result = docx2doct_bin(sFileFrom, sFileTo, sTempDir, oInputParams); + result = docx2doct_bin(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_DOCT_BIN2DOCX: { - result = doct_bin2docx(sFileFrom, sFileTo, sTempDir, sThemeDir, oInputParams); + result = doct_bin2docx(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_XLSX2XLST_BIN: { - result = xlsx2xlst_bin(sFileFrom, sFileTo, sTempDir, oInputParams); + result = xlsx2xlst_bin(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_XLST_BIN2XLSX: { - result = xlst_bin2xlsx(sFileFrom, sFileTo, sTempDir, sThemeDir, oInputParams); + result = xlst_bin2xlsx(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_PPTX2PPTT_BIN: { - result = pptx2pptt_bin(sFileFrom, sFileTo, sTempDir, oInputParams); + result = pptx2pptt_bin(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_PPTT_BIN2PPTX: { - result = pptt_bin2pptx(sFileFrom, sFileTo, sTempDir, sThemeDir, oInputParams); + result = pptt_bin2pptx(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_BIN2PDF: { - result = bin2pdf(sFileFrom, sFileTo, sTempDir, bPaid, sThemeDir, oInputParams); + result = bin2pdf(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_BIN2T: @@ -5888,306 +1867,314 @@ namespace NExtractTools break; case TCD_PPT2PPTX: { - result = ppt2pptx(sFileFrom, sFileTo, sTempDir, oInputParams); + result = ppt2pptx(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_PPT2PPTM: { - result = ppt2pptm(sFileFrom, sFileTo, sTempDir, oInputParams); + result = ppt2pptm(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_PPT2PPTT: { - result = ppt2pptt(sFileFrom, sFileTo, sTempDir, oInputParams); + result = ppt2pptt(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_PPT2PPTT_BIN: { - result = ppt2pptt_bin(sFileFrom, sFileTo, sTempDir, oInputParams); + result = ppt2pptt_bin(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_RTF2DOCX: { - result = rtf2docx(sFileFrom, sFileTo, sTempDir, oInputParams); + result = rtf2docx(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_RTF2DOCT: { - result = rtf2doct(sFileFrom, sFileTo, sTempDir, oInputParams); + result = rtf2doct(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_RTF2DOCT_BIN: { - result = rtf2doct_bin(sFileFrom, sFileTo, sTempDir, oInputParams); + result = rtf2doct_bin(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_DOCX2RTF: { - result = docx2rtf(sFileFrom, sFileTo, sTempDir, oInputParams); + result = docx2rtf(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_DOCX2TXT: { - result = docx2txt(sFileFrom, sFileTo, sTempDir, oInputParams); + result = docx2txt(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_DOC2DOCX: { - result = doc2docx(sFileFrom, sFileTo, sTempDir, oInputParams); + result = doc2docx(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_DOC2DOCM: { - result = doc2docm(sFileFrom, sFileTo, sTempDir, oInputParams); + result = doc2docm(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_DOCT2RTF: { - result = doct2rtf(sFileFrom, sFileTo, sTempDir, sThemeDir, oInputParams); + result = doct2rtf(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_DOCT_BIN2RTF: { - result = doct_bin2rtf(sFileFrom, sFileTo, sTempDir, sThemeDir, oInputParams); + result = doct_bin2rtf(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_TXT2DOCX: { - result = txt2docx(sFileFrom, sFileTo, sTempDir, oInputParams); + result = txt2docx(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_TXT2DOCT: { - result = txt2doct(sFileFrom, sFileTo, sTempDir, oInputParams); + result = txt2doct(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_TXT2DOCT_BIN: { - result = txt2doct_bin(sFileFrom, sFileTo, sTempDir, oInputParams); + result = txt2doct_bin(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_XLS2XLSX: { - result = xls2xlsx(sFileFrom, sFileTo, sTempDir, oInputParams); + result = xls2xlsx(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_XLS2XLSM: { - result = xls2xlsm(sFileFrom, sFileTo, sTempDir, oInputParams); + result = xls2xlsm(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_XLS2XLST: { - result = xls2xlst(sFileFrom, sFileTo, sTempDir, oInputParams); + result = xls2xlst(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_XLS2XLST_BIN: { - result = xls2xlst_bin(sFileFrom, sFileTo, sTempDir, oInputParams); + result = xls2xlst_bin(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_OTF2ODF: { - result = otf2odf(sFileFrom, sFileTo, sTempDir, oInputParams); + result = otf2odf(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_ODF2OOX: { - result = odf2oox(sFileFrom, sFileTo, sTempDir, oInputParams); + result = odf2oox(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_ODF2OOT: { - result = odf2oot(sFileFrom, sFileTo, sTempDir, oInputParams); + result = odf2oot(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_ODF2OOT_BIN: { - result = odf2oot_bin(sFileFrom, sFileTo, sTempDir, oInputParams); + result = odf2oot_bin(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_ODF_FLAT2OOX: { - result = odf_flat2oox(sFileFrom, sFileTo, sTempDir, oInputParams); + result = odf_flat2oox(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_ODF_FLAT2OOT: { - result = odf_flat2oot(sFileFrom, sFileTo, sTempDir, oInputParams); + result = odf_flat2oot(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_ODF_FLAT2OOT_BIN: { - result = odf_flat2oot_bin(sFileFrom, sFileTo, sTempDir, oInputParams); + result = odf_flat2oot_bin(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_DOCX2ODT: { - result = docx2odt(sFileFrom, sFileTo, sTempDir, oInputParams); + result = docx2odt(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_XLSX2ODS: { - result = xlsx2ods(sFileFrom, sFileTo, sTempDir, oInputParams); + result = xlsx2ods(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_PPTX2ODP: { - result = pptx2odp(sFileFrom, sFileTo, sTempDir, oInputParams); + result = pptx2odp(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_MAILMERGE: { - result = convertmailmerge(*oMailMerge, sFileFrom, sFileTo, sTempDir, bPaid, sThemeDir, oInputParams); + result = convertmailmerge(*oMailMerge, sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_DOCUMENT2: { oInputParams.m_bMacro = ( nFormatTo == AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCM || nFormatTo == AVS_OFFICESTUDIO_FILE_DOCUMENT_DOTM || nFormatTo == AVS_OFFICESTUDIO_FILE_OTHER_OOXML); - result = fromDocument(sFileFrom, nFormatFrom, sTempDir, oInputParams); + result = fromDocument(sFileFrom, nFormatFrom, oInputParams, oConvertParams); } break; case TCD_SPREADSHEET2: { oInputParams.m_bMacro = ( nFormatTo == AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSM || nFormatTo == AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLTM || nFormatTo == AVS_OFFICESTUDIO_FILE_OTHER_OOXML); - result = fromSpreadsheet(sFileFrom, nFormatFrom, sTempDir, oInputParams); + result = fromSpreadsheet(sFileFrom, nFormatFrom, oInputParams, oConvertParams); } break; case TCD_PRESENTATION2: { oInputParams.m_bMacro = ( nFormatTo == AVS_OFFICESTUDIO_FILE_PRESENTATION_PPTM || nFormatTo == AVS_OFFICESTUDIO_FILE_PRESENTATION_PPSM || nFormatTo == AVS_OFFICESTUDIO_FILE_PRESENTATION_POTM || nFormatTo == AVS_OFFICESTUDIO_FILE_OTHER_OOXML); - result = fromPresentation(sFileFrom, nFormatFrom, sTempDir, oInputParams); + result = fromPresentation(sFileFrom, nFormatFrom, oInputParams, oConvertParams); } break; case TCD_T2: { - result = fromT(sFileFrom, nFormatFrom, sFileTo, nFormatTo, sTempDir, sThemeDir, bPaid, oInputParams); + result = fromT(sFileFrom, nFormatFrom, sFileTo, nFormatTo, oInputParams, oConvertParams); } break; case TCD_DOCT_BIN2: { - result = fromDoctBin(sFileFrom, sFileTo, nFormatTo, sTempDir, sThemeDir, bPaid, oInputParams); + result = fromDoctBin(sFileFrom, sFileTo, nFormatTo, oInputParams, oConvertParams); } break; case TCD_XLST_BIN2: { - result = fromXlstBin(sFileFrom, sFileTo, nFormatTo, sTempDir, sThemeDir, bPaid, oInputParams); + result = fromXlstBin(sFileFrom, sFileTo, nFormatTo, oInputParams, oConvertParams); } break; case TCD_PPTT_BIN2: { - result = fromPpttBin(sFileFrom, sFileTo, nFormatTo, sTempDir, sThemeDir, bPaid, oInputParams); + result = fromPpttBin(sFileFrom, sFileTo, nFormatTo, oInputParams, oConvertParams); } break; case TCD_CROSSPLATFORM2: { - result = fromCrossPlatform(sFileFrom, nFormatFrom, sFileTo, nFormatTo, sTempDir, sThemeDir, bPaid, oInputParams); + result = fromCrossPlatform(sFileFrom, nFormatFrom, sFileTo, nFormatTo, oInputParams, oConvertParams); } break; case TCD_CANVAS_PDF2: { - result = fromCanvasPdf(sFileFrom, nFormatFrom, sFileTo, nFormatTo, sTempDir, sThemeDir, bPaid, oInputParams); + result = fromCanvasPdf(sFileFrom, nFormatFrom, sFileTo, nFormatTo, oInputParams, oConvertParams); } break; case TCD_MSCRYPT2: { - result = fromMscrypt(sFileFrom, sFileTo, sTempDir, oInputParams); + result = fromMscrypt(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_MSCRYPT2_RAW: { - result = mscrypt2oox(sFileFrom, sFileTo, sTempDir, oInputParams); + result = mscrypt2oox(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_2MSCRYPT_RAW: { - result = oox2mscrypt(sFileFrom, sFileTo, sTempDir, oInputParams); + result = oox2mscrypt(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_MSCRYPT2DOCT: case TCD_MSCRYPT2XLST: case TCD_MSCRYPT2PPTT: { - result = mscrypt2oot(sFileFrom, sFileTo, sTempDir, oInputParams); + result = mscrypt2oot(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_MSCRYPT2BIN: { - result = mscrypt2oot_bin(sFileFrom, sFileTo, sTempDir, oInputParams); + result = mscrypt2oot_bin(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_MITCRYPT2: { - result = fromMitcrypt(sFileFrom, sFileTo, sTempDir, oInputParams); + result = fromMitcrypt(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_HTML2DOCX: { - result = html2docx(sFileFrom, sFileTo, sTempDir, oInputParams); + result = html2docx(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_HTMLZIP2DOCX: { - result = html_zip2docx(sFileFrom, sFileTo, sTempDir, oInputParams); + result = html_zip2docx(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_HTML2DOCT: { - result = html2doct(sFileFrom, sFileTo, sTempDir, oInputParams); + result = html2doct(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_HTMLZIP2DOCT: { - result = html_zip2doct(sFileFrom, sFileTo, sTempDir, oInputParams); + result = html_zip2doct(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_HTML2DOCT_BIN: { - result = html2doct_bin(sFileFrom, sFileTo, sTempDir, oInputParams); + result = html2doct_bin(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_HTMLZIP2DOCT_BIN: { - result = html_zip2doct_bin(sFileFrom, sFileTo, sTempDir, oInputParams); + result = html_zip2doct_bin(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_FB22DOCX: { - result = fb2docx(sFileFrom, sFileTo, sTempDir, oInputParams); + result = fb2docx(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; case TCD_VBAPROJECT2XML: { - result = msVbaProject2Xml(sFileFrom, sFileTo, sTempDir, oInputParams); + result = msVbaProject2Xml(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; + case TCD_DRAW2: + { + result = fromDraw(sFileFrom, nFormatFrom, oInputParams, oConvertParams); + }break; + case TCD_XLSX2XLSB: + { + result = xlsx2xlsb(sFileFrom, sFileTo, oInputParams, oConvertParams); + }break; // TCD_FB22DOCT, // TCD_FB22DOCT_BIN, - // TCD_EPUB2DOCX, // TCD_EPUB2DOCT, // TCD_EPUB2DOCT_BIN, default: { result = AVS_FILEUTILS_ERROR_CONVERT_PARAMS; - } - break; + }break; } // delete temp dir if (!bExternalTempDir) { - NSDirectory::DeleteDirectory(sTempDir); + NSDirectory::DeleteDirectory(oConvertParams.m_sTempDir); } + if (!sGlobalTempDir.empty()) + NSFile::CFileBinary::SetTempPath(sGlobalTempDir); + // clean up v8 #ifndef BUILD_X2T_AS_LIBRARY_DYLIB NSDoctRenderer::CDocBuilder::Dispose(); #endif - if (SUCCEEDED_X2T(result) && oInputParams.m_bOutputConvertCorrupted) { return AVS_FILEUTILS_ERROR_CONVERT_CORRUPTED; @@ -6198,16 +2185,6 @@ namespace NExtractTools } } - void createJSCaches() - { - NSDoctRenderer::CDocBuilder::Initialize(); - - NSDoctRenderer::CDoctrenderer oDoctRenderer; - oDoctRenderer.CreateCache(L"", L""); - - NSDoctRenderer::CDocBuilder::Dispose(); - } - _UINT32 FromFile(const std::wstring &file) { InputParams oInputParams; diff --git a/X2tConverter/src/ASCConverters.h b/X2tConverter/src/ASCConverters.h index f8734d68fa8..5e93affe344 100644 --- a/X2tConverter/src/ASCConverters.h +++ b/X2tConverter/src/ASCConverters.h @@ -41,202 +41,277 @@ #include "../../OOXML/Base/Base.h" #include +#include namespace NExtractTools { class InputParams; class InputParamsMailMerge; -} // namespace NExtractTools + class ConvertParams; +} + namespace NExtractTools { - _UINT32 docx2doct_bin(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - _UINT32 docx2doct(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - _UINT32 docx_dir2doct(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms, const std::wstring &sDocxFile); - _UINT32 docx_dir2doct_bin(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms, const std::wstring &sDocxFile); - _UINT32 doct_bin2docx(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, const std::wstring &sThemeDir, InputParams ¶ms); - _UINT32 doct_bin2docx_dir(const std::wstring &sFrom, const std::wstring &sToResult, const std::wstring &sTo, const std::wstring &sThemeDir, InputParams ¶ms); - _UINT32 doct2docx(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, const std::wstring &sThemeDir, InputParams ¶ms); - - _UINT32 docxflat2doct(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - _UINT32 docxflat2doct_bin(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - _UINT32 docxflat2odt(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - _UINT32 docxflat2docx(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - - _UINT32 package2ooxml(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - _UINT32 package2ooxml_dir(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - _UINT32 package2bin_t(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - _UINT32 package2bin(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - - _UINT32 dotm2docm(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - _UINT32 dotm2docm_dir(const std::wstring &sFrom, const std::wstring &sTo, InputParams ¶ms); - _UINT32 dotx2docx(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - _UINT32 dotx2docx_dir(const std::wstring &sFrom, const std::wstring &sTo, InputParams ¶ms); - _UINT32 docm2docx(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - _UINT32 docm2docx_dir(const std::wstring &sFrom, const std::wstring &sTo, InputParams ¶ms); - _UINT32 dotm2docx(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - _UINT32 dotm2docx_dir(const std::wstring &sFrom, const std::wstring &sTo, InputParams ¶ms); - - _UINT32 xlsx2xlst(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - _UINT32 xlsx2xlst_bin(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - _UINT32 xlsxflat2xlst(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - _UINT32 xlsxflat2xlst_bin(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - _UINT32 xlsxflat2xlsx(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - _UINT32 xlsxflat2xlsx_dir(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - _UINT32 xlsx_dir2xlst(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms, bool bXmlOptions, const std::wstring &sXlsxFile); - _UINT32 xlsx_dir2xlst_bin(const std::wstring &sFrom, const std::wstring &sTo, InputParams ¶ms, bool bXmlOptions, const std::wstring &sXlsxFile); - _UINT32 xlst_bin2xlsx(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, const std::wstring &sThemeDir, InputParams ¶ms); - _UINT32 xlst_bin2xlsx_dir(const std::wstring &sFrom, const std::wstring &sToResult, const std::wstring &sTo, const std::wstring &sThemeDir, InputParams ¶ms); - _UINT32 xlst2xlsx(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, const std::wstring &sThemeDir, InputParams ¶ms); - - _UINT32 xltx2xlsx(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - _UINT32 xltx2xlsx_dir(const std::wstring &sFrom, const std::wstring &sTo, InputParams ¶ms); - _UINT32 xltm2xlsm(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - _UINT32 xltm2xlsm_dir(const std::wstring &sFrom, const std::wstring &sTo, InputParams ¶ms); - _UINT32 xlsm2xlsx(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - _UINT32 xlsm2xlsx_dir(const std::wstring &sFrom, const std::wstring &sTo, InputParams ¶ms); - _UINT32 xltm2xlsx(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - _UINT32 xltm2xlsx_dir(const std::wstring &sFrom, const std::wstring &sTo, InputParams ¶ms); - _UINT32 xlsb2xlsx_dir(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - _UINT32 xlsx2xlsb(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - _UINT32 xlsx_dir2xlsb(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - - _UINT32 pptx2pptt_bin(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - _UINT32 pptx_dir2pptt(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms, const std::wstring &sPptxFile); - _UINT32 pptx_dir2pptt_bin(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms, const std::wstring &sPptxFile); - _UINT32 pptx2pptt(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - _UINT32 pptt_bin2pptx(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, const std::wstring &sThemeDir, InputParams ¶ms); - _UINT32 pptt_bin2pptx_dir(const std::wstring &sFrom, const std::wstring &sToResult, const std::wstring &sTo, const std::wstring &sThemeDir, InputParams ¶ms); - _UINT32 pptt2pptx(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, const std::wstring &sThemeDir, InputParams ¶ms); - - _UINT32 xml2xlsx(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - _UINT32 xml2xlsx_dir(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - - _UINT32 csv2xlst(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - _UINT32 csv2xlsx(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - _UINT32 csv2xlsx_dir(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - _UINT32 csv2xlst_bin(const std::wstring &sFrom, const std::wstring &sTo, InputParams ¶ms); - _UINT32 xlst2csv(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - _UINT32 xlsx_dir2csv(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - _UINT32 xlsx2csv(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - _UINT32 xlst_bin2csv(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - - _UINT32 bin2pdf(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, bool bPaid, const std::wstring &sThemeDir, InputParams ¶ms); - - _UINT32 ppsx2pptx(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - _UINT32 ppsx2pptx_dir(const std::wstring &sFrom, const std::wstring &sTo, InputParams ¶ms); - _UINT32 potx2pptx(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - _UINT32 potx2pptx_dir(const std::wstring &sFrom, const std::wstring &sTo, InputParams ¶ms); - _UINT32 ppsm2pptx(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - _UINT32 ppsm2pptx_dir(const std::wstring &sFrom, const std::wstring &sTo, InputParams ¶ms); - _UINT32 potm2pptm(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - _UINT32 potm2pptm_dir(const std::wstring &sFrom, const std::wstring &sTo, InputParams ¶ms); - _UINT32 ppsm2pptm(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - _UINT32 ppsm2pptm_dir(const std::wstring &sFrom, const std::wstring &sTo, InputParams ¶ms); - _UINT32 pptm2pptx(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - _UINT32 pptm2pptx_dir(const std::wstring &sFrom, const std::wstring &sTo, InputParams ¶ms); - _UINT32 potm2pptx(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - _UINT32 potm2pptx_dir(const std::wstring &sFrom, const std::wstring &sTo, InputParams ¶ms); - - _UINT32 ppt2pptx(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - _UINT32 ppt2pptx_dir(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - _UINT32 ppt2pptt_bin(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - _UINT32 ppt2pptt(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - _UINT32 ppt2pptm(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - _UINT32 ppt2pptm_dir(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - - _UINT32 rtf2docx(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - _UINT32 rtf2docx_dir(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - _UINT32 rtf2doct(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - _UINT32 rtf2doct_bin(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - _UINT32 docx2rtf(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - _UINT32 docx_dir2rtf(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - _UINT32 doct2rtf(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, const std::wstring &sThemeDir, InputParams ¶ms); - _UINT32 doct_bin2rtf(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, const std::wstring &sThemeDir, InputParams ¶ms); - - _UINT32 doc2docx(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - _UINT32 doc2docx_dir(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - _UINT32 doc2doct(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - _UINT32 doc2doct_bin(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - _UINT32 docx_dir2doc(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - _UINT32 doc2docm(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - _UINT32 doc2docm_dir(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - - _UINT32 xls2xlsx(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - _UINT32 xls2xlsx_dir(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - _UINT32 xls2xlst(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - _UINT32 xls2xlst_bin(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - _UINT32 xls2xlsm(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - _UINT32 xls2xlsm_dir(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - - _UINT32 txt2docx(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - _UINT32 txt2docx_dir(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - _UINT32 txt2doct(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - _UINT32 txt2doct_bin(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - _UINT32 docx_dir2txt(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - - _UINT32 odf2oox(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - _UINT32 odf2oox_dir(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - _UINT32 odf2oot(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - _UINT32 odf2oot_bin(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - - _UINT32 odf_flat2oox(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - _UINT32 odf_flat2oox_dir(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - _UINT32 odf_flat2oot(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - _UINT32 odf_flat2oot_bin(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - - _UINT32 docx2odt(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - _UINT32 docx_dir2odt(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms, bool bTemplate); - _UINT32 xlsx2ods(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - _UINT32 xlsx_dir2ods(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms, bool bTemplate); - _UINT32 pptx2odp(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - _UINT32 pptx_dir2odp(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms, bool bTemplate); - - _UINT32 fromMscrypt(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - _UINT32 fromMitcrypt(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - _UINT32 mscrypt2oox(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - _UINT32 mitcrypt2oox(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - _UINT32 mscrypt2oot(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - _UINT32 mscrypt2oot_bin(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - _UINT32 mitcrypt2oot_bin(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - - _UINT32 oox2mscrypt(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - - _UINT32 msVbaProject2dir(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - - _UINT32 html2doct_bin(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - _UINT32 html2doct(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - _UINT32 html2docx(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); + #define DECLARE_CONVERT_FUNC(name) _UINT32 name(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + typedef std::function<_UINT32(const std::wstring&, const std::wstring&, InputParams&, ConvertParams&)> CONVERT_FUNC; + + // zip + _UINT32 dir2zip(const std::wstring& sFrom, const std::wstring& sTo, bool bSorted = false, int method = 8 /*Z_DEFLATED*/, short level = -1, bool bDateTime = true); + _UINT32 zip2dir(const std::wstring& sFrom, const std::wstring& sTo); + DECLARE_CONVERT_FUNC(dir2zipMscrypt); + + // crypt + DECLARE_CONVERT_FUNC(mscrypt2oot); + DECLARE_CONVERT_FUNC(mscrypt2oot_bin); + DECLARE_CONVERT_FUNC(mitcrypt2oox); + DECLARE_CONVERT_FUNC(mitcrypt2oot_bin); + DECLARE_CONVERT_FUNC(mscrypt2oox); + DECLARE_CONVERT_FUNC(oox2mscrypt); + DECLARE_CONVERT_FUNC(fromMscrypt); + DECLARE_CONVERT_FUNC(fromMitcrypt); + + DECLARE_CONVERT_FUNC(msVbaProject2dir); + + // docx + DECLARE_CONVERT_FUNC(docx2doct_bin); + DECLARE_CONVERT_FUNC(docx_dir2doct_bin); + DECLARE_CONVERT_FUNC(docx2doct); + DECLARE_CONVERT_FUNC(docx_dir2doct); + + DECLARE_CONVERT_FUNC(doct_bin2docx); + DECLARE_CONVERT_FUNC(doct_bin2docx_dir); + DECLARE_CONVERT_FUNC(doct2docx); + + DECLARE_CONVERT_FUNC(docxflat2doct); + DECLARE_CONVERT_FUNC(docxflat2doct_bin); + DECLARE_CONVERT_FUNC(docxflat2odt); + DECLARE_CONVERT_FUNC(docxflat2docx); + + DECLARE_CONVERT_FUNC(package2ooxml); + DECLARE_CONVERT_FUNC(package2ooxml_dir); + DECLARE_CONVERT_FUNC(package2bin_t); + DECLARE_CONVERT_FUNC(package2bin); + + DECLARE_CONVERT_FUNC(dotm2docm); + DECLARE_CONVERT_FUNC(dotm2docm_dir); + DECLARE_CONVERT_FUNC(dotx2docx); + DECLARE_CONVERT_FUNC(dotx2docx_dir); + DECLARE_CONVERT_FUNC(docm2docx); + DECLARE_CONVERT_FUNC(docm2docx_dir); + DECLARE_CONVERT_FUNC(dotm2docx); + DECLARE_CONVERT_FUNC(dotm2docx_dir); + + // xlsx + DECLARE_CONVERT_FUNC(xlsx2xlst); + DECLARE_CONVERT_FUNC(xlsx2xlst_bin); + DECLARE_CONVERT_FUNC(xlsxflat2xlst); + DECLARE_CONVERT_FUNC(xlsxflat2xlst_bin); + DECLARE_CONVERT_FUNC(xlsxflat2xlsx); + DECLARE_CONVERT_FUNC(xlsxflat2xlsx_dir); + DECLARE_CONVERT_FUNC(xlsx_dir2xlst); + DECLARE_CONVERT_FUNC(xlsx_dir2xlst_bin); + DECLARE_CONVERT_FUNC(xlst_bin2xlsx); + DECLARE_CONVERT_FUNC(xlst_bin2xlsx_dir); + DECLARE_CONVERT_FUNC(xlst2xlsx); + + DECLARE_CONVERT_FUNC(xltx2xlsx); + DECLARE_CONVERT_FUNC(xltx2xlsx_dir); + DECLARE_CONVERT_FUNC(xltm2xlsm); + DECLARE_CONVERT_FUNC(xltm2xlsm_dir); + DECLARE_CONVERT_FUNC(xlsm2xlsx); + DECLARE_CONVERT_FUNC(xlsm2xlsx_dir); + DECLARE_CONVERT_FUNC(xltm2xlsx); + DECLARE_CONVERT_FUNC(xltm2xlsx_dir); + DECLARE_CONVERT_FUNC(xlsb2xlsx_dir); + + // pptx + DECLARE_CONVERT_FUNC(pptx2pptt_bin); + DECLARE_CONVERT_FUNC(pptx_dir2pptt); + DECLARE_CONVERT_FUNC(pptx_dir2pptt_bin); + DECLARE_CONVERT_FUNC(pptx2pptt); + DECLARE_CONVERT_FUNC(pptt_bin2pptx); + DECLARE_CONVERT_FUNC(pptt_bin2pptx_dir); + DECLARE_CONVERT_FUNC(pptt2pptx); + + DECLARE_CONVERT_FUNC(ppsx2pptx); + DECLARE_CONVERT_FUNC(ppsx2pptx_dir); + DECLARE_CONVERT_FUNC(potx2pptx); + DECLARE_CONVERT_FUNC(potx2pptx_dir); + DECLARE_CONVERT_FUNC(ppsm2pptx); + DECLARE_CONVERT_FUNC(ppsm2pptx_dir); + DECLARE_CONVERT_FUNC(potm2pptm); + DECLARE_CONVERT_FUNC(potm2pptm_dir); + DECLARE_CONVERT_FUNC(ppsm2pptm); + DECLARE_CONVERT_FUNC(ppsm2pptm_dir); + DECLARE_CONVERT_FUNC(pptm2pptx); + DECLARE_CONVERT_FUNC(pptm2pptx_dir); + DECLARE_CONVERT_FUNC(potm2pptx); + DECLARE_CONVERT_FUNC(potm2pptx_dir); + + // doc + DECLARE_CONVERT_FUNC(doc2docx); + DECLARE_CONVERT_FUNC(doc2docx_dir); + DECLARE_CONVERT_FUNC(doc2doct); + DECLARE_CONVERT_FUNC(doc2doct_bin); + DECLARE_CONVERT_FUNC(docx_dir2doc); + DECLARE_CONVERT_FUNC(doc2docm); + DECLARE_CONVERT_FUNC(doc2docm_dir); + + // rtf + DECLARE_CONVERT_FUNC(rtf2docx_dir); + DECLARE_CONVERT_FUNC(docx_dir2rtf); + DECLARE_CONVERT_FUNC(rtf2doct_bin); + DECLARE_CONVERT_FUNC(doct_bin2rtf); + DECLARE_CONVERT_FUNC(rtf2docx); + DECLARE_CONVERT_FUNC(docx2rtf); + DECLARE_CONVERT_FUNC(rtf2doct); + DECLARE_CONVERT_FUNC(doct2rtf); + + // txt + DECLARE_CONVERT_FUNC(txt2docx_dir); + DECLARE_CONVERT_FUNC(docx_dir2txt); + DECLARE_CONVERT_FUNC(txt2doct_bin); + DECLARE_CONVERT_FUNC(txt2docx); + DECLARE_CONVERT_FUNC(txt2doct); + DECLARE_CONVERT_FUNC(docx2txt); + + // html + DECLARE_CONVERT_FUNC(html2doct_bin); + DECLARE_CONVERT_FUNC(html_zip2doct_bin); + DECLARE_CONVERT_FUNC(html_zip2doct); + DECLARE_CONVERT_FUNC(html2doct); + DECLARE_CONVERT_FUNC(html2docx); + DECLARE_CONVERT_FUNC(html_zip2docx); + + DECLARE_CONVERT_FUNC(html2docx_dir); + DECLARE_CONVERT_FUNC(html_zip2docx_dir); + + DECLARE_CONVERT_FUNC(doct_bin2html); + DECLARE_CONVERT_FUNC(doct_bin2html_zip); + + // mht + DECLARE_CONVERT_FUNC(mht2docx_dir); + + // epub + DECLARE_CONVERT_FUNC(epub2docx_dir); + DECLARE_CONVERT_FUNC(doct_bin2epub); + + // fb2 + DECLARE_CONVERT_FUNC(fb2docx_dir); + DECLARE_CONVERT_FUNC(fb2docx); + DECLARE_CONVERT_FUNC(doct_bin2fb); + + // ppt + DECLARE_CONVERT_FUNC(ppt2pptx); + DECLARE_CONVERT_FUNC(ppt2pptx_dir); + DECLARE_CONVERT_FUNC(ppt2pptt_bin); + DECLARE_CONVERT_FUNC(ppt2pptt); + DECLARE_CONVERT_FUNC(ppt2pptm); + DECLARE_CONVERT_FUNC(ppt2pptm_dir); + + // csv + DECLARE_CONVERT_FUNC(csv2xlst); + DECLARE_CONVERT_FUNC(csv2xlsx); + DECLARE_CONVERT_FUNC(csv2xlsx_dir); + DECLARE_CONVERT_FUNC(csv2xlst_bin); + DECLARE_CONVERT_FUNC(xlst2csv); + DECLARE_CONVERT_FUNC(xlsx_dir2csv); + DECLARE_CONVERT_FUNC(xlsx2csv); + DECLARE_CONVERT_FUNC(xlst_bin2csv); + + // xls + DECLARE_CONVERT_FUNC(xls2xlsx); + DECLARE_CONVERT_FUNC(xls2xlsx_dir); + DECLARE_CONVERT_FUNC(xls2xlst); + DECLARE_CONVERT_FUNC(xls2xlst_bin); + DECLARE_CONVERT_FUNC(xls2xlsm); + DECLARE_CONVERT_FUNC(xls2xlsm_dir); + + // xml => xlsx + DECLARE_CONVERT_FUNC(xml2xlsx); + DECLARE_CONVERT_FUNC(xml2xlsx_dir); + + // odf + DECLARE_CONVERT_FUNC(odf2oox); + DECLARE_CONVERT_FUNC(odf2oox_dir); + DECLARE_CONVERT_FUNC(odf2oot); + DECLARE_CONVERT_FUNC(odf2oot_bin); + + DECLARE_CONVERT_FUNC(odf_flat2oox); + DECLARE_CONVERT_FUNC(odf_flat2oox_dir); + DECLARE_CONVERT_FUNC(odf_flat2oot); + DECLARE_CONVERT_FUNC(odf_flat2oot_bin); + + DECLARE_CONVERT_FUNC(docx2odt); + DECLARE_CONVERT_FUNC(docx_dir2odt); + DECLARE_CONVERT_FUNC(xlsx2ods); + DECLARE_CONVERT_FUNC(xlsx_dir2ods); + DECLARE_CONVERT_FUNC(pptx2odp); + DECLARE_CONVERT_FUNC(pptx_dir2odp); + + DECLARE_CONVERT_FUNC(otf2odf); + + // pdf/image + DECLARE_CONVERT_FUNC(bin2pdf); + _UINT32 bin2Image(unsigned char* pBuffer, long lBufferLen, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams); + DECLARE_CONVERT_FUNC(bin2imageBase64); + + // using NSDoctRenderer::DoctRendererFormat::FormatFile + // DECLARE_CONVERT_FUNC(doct_bin2pdf); + // DECLARE_CONVERT_FUNC(doct_bin2image); + + DECLARE_CONVERT_FUNC(pdfoform2docx_dir); + DECLARE_CONVERT_FUNC(docx_dir2pdfoform); + DECLARE_CONVERT_FUNC(pdfoform2doct_bin); + DECLARE_CONVERT_FUNC(doct_bin2pdfoform); + DECLARE_CONVERT_FUNC(pdfoform2docx); + DECLARE_CONVERT_FUNC(docx2pdfoform); + DECLARE_CONVERT_FUNC(pdfoform2doct); + DECLARE_CONVERT_FUNC(doct2pdfoform); + + // iWork + DECLARE_CONVERT_FUNC(pages2odf); + DECLARE_CONVERT_FUNC(numbers2odf); + DECLARE_CONVERT_FUNC(key2odf); + + //HWP + DECLARE_CONVERT_FUNC(hwp2docx); + DECLARE_CONVERT_FUNC(hwp2docx_dir); + + //HWPX + DECLARE_CONVERT_FUNC(hwpx2docx); + DECLARE_CONVERT_FUNC(hwpx2docx_dir); //------------------------------------------------------------------------------------------------------------------------------------------------- - _UINT32 dir2zip(const std::wstring &sFrom, const std::wstring &sTo, bool bSorted = false, int method = 8 /*Z_DEFLATED*/, short level = -1, bool bDateTime = false); - _UINT32 dir2zipMscrypt(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams ¶ms); - _UINT32 zip2dir(const std::wstring &sFrom, const std::wstring &sTo); + _UINT32 convertmailmerge(const InputParamsMailMerge& oMailMergeSend, const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams); + + _UINT32 fromDocxDir(const std::wstring &sFrom, const std::wstring &sTo, int nFormatTo, InputParams& params, ConvertParams& convertParams); + _UINT32 fromDoctBin(const std::wstring &sFrom, const std::wstring &sTo, int nFormatTo, InputParams& params, ConvertParams& convertParams); + _UINT32 fromDocument(const std::wstring &sFrom, int nFormatFrom, InputParams& params, ConvertParams& convertParams); - _UINT32 convertmailmerge(const InputParamsMailMerge &oMailMergeSend, const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, bool bPaid, const std::wstring &sThemeDir, InputParams ¶ms); + _UINT32 fromXlsxDir (const std::wstring &sFrom, const std::wstring &sTo, int nFormatTo, InputParams& params, ConvertParams& convertParams); + _UINT32 fromXlsbXlsxDir(const std::wstring &sFrom, const std::wstring &sTo, int nFormatTo, InputParams& params, ConvertParams& convertParams); + _UINT32 fromXlstBin (const std::wstring &sFrom, const std::wstring &sTo, int nFormatTo, InputParams& params, ConvertParams& convertParams); + _UINT32 fromSpreadsheet(const std::wstring &sFrom, int nFormatFrom, InputParams& params, ConvertParams& convertParams); - _UINT32 fromDocxDir(const std::wstring &sFrom, const std::wstring &sTo, int nFormatTo, const std::wstring &sTemp, const std::wstring &sThemeDir, bool bPaid, InputParams ¶ms, const std::wstring &sDocxFile); - _UINT32 fromDoctBin(const std::wstring &sFrom, const std::wstring &sTo, int nFormatTo, const std::wstring &sTemp, const std::wstring &sThemeDir, bool bPaid, InputParams ¶ms); - _UINT32 fromDocument(const std::wstring &sFrom, int nFormatFrom, const std::wstring &sTemp, InputParams ¶ms); + _UINT32 fromPptxDir(const std::wstring &sFrom, const std::wstring &sTo, int nFormatTo, InputParams& params, ConvertParams& convertParams); + _UINT32 fromPpttBin(const std::wstring &sFrom, const std::wstring &sTo, int nFormatTo, InputParams& params, ConvertParams& convertParams); + _UINT32 fromPresentation(const std::wstring &sFrom, int nFormatFrom, InputParams& params, ConvertParams& convertParams); - _UINT32 fromXlsxDir(const std::wstring &sFrom, const std::wstring &sTo, int nFormatTo, const std::wstring &sTemp, const std::wstring &sThemeDir, bool bPaid, InputParams ¶ms, const std::wstring &sXlsxFile); - _UINT32 fromXlsbXlsxDir(const std::wstring &sFrom, const std::wstring &sTo, int nFormatTo, const std::wstring &sTemp, const std::wstring &sThemeDir, bool bPaid, InputParams ¶ms, const std::wstring &sXlsxFile); - _UINT32 fromXlstBin(const std::wstring &sFrom, const std::wstring &sTo, int nFormatTo, const std::wstring &sTemp, const std::wstring &sThemeDir, bool bPaid, InputParams ¶ms); - _UINT32 fromSpreadsheet(const std::wstring &sFrom, int nFormatFrom, const std::wstring &sTemp, InputParams ¶ms); + _UINT32 fromT(const std::wstring &sFrom, int nFormatFrom, const std::wstring &sTo, int nFormatTo, InputParams& params, ConvertParams& convertParams); - _UINT32 fromPptxDir(const std::wstring &sFrom, const std::wstring &sTo, int nFormatTo, const std::wstring &sTemp, const std::wstring &sThemeDir, bool bPaid, InputParams ¶ms, const std::wstring &sPptxFile); - _UINT32 fromPpttBin(const std::wstring &sFrom, const std::wstring &sTo, int nFormatTo, const std::wstring &sTemp, const std::wstring &sThemeDir, bool bPaid, InputParams ¶ms); - _UINT32 fromPresentation(const std::wstring &sFrom, int nFormatFrom, const std::wstring &sTemp, InputParams ¶ms); + _UINT32 fromCrossPlatform(const std::wstring& sFrom, int nFormatFrom, const std::wstring& sTo, int nFormatTo, InputParams& params, ConvertParams& convertParams); + _UINT32 fromCanvasPdf(const std::wstring& sFrom, int nFormatFrom, const std::wstring& sTo, int nFormatTo, InputParams& params, ConvertParams& convertParams); - _UINT32 fromT(const std::wstring &sFrom, int nFormatFrom, const std::wstring &sTo, int nFormatTo, const std::wstring &sTemp, const std::wstring &sThemeDir, bool bPaid, InputParams ¶ms); - _UINT32 fromCrossPlatform(const std::wstring &sFrom, int nFormatFrom, const std::wstring &sTo, int nFormatTo, const std::wstring &sTemp, const std::wstring &sThemeDir, bool bPaid, InputParams ¶ms); - _UINT32 fromCanvasPdf(const std::wstring &sFrom, int nFormatFrom, const std::wstring &sTo, int nFormatTo, const std::wstring &sTemp, const std::wstring &sThemeDir, bool bPaid, InputParams ¶ms); + _UINT32 fromDraw(const std::wstring& sFrom, int nFormatFrom, InputParams& params, ConvertParams& convertParams); - _UINT32 fromInputParams(InputParams &oInputParams); - _UINT32 detectMacroInFile(InputParams &oInputParams); + _UINT32 fromInputParams(InputParams& oInputParams); + _UINT32 detectMacroInFile(InputParams& oInputParams); void createJSCaches(); + void createJSSnapshots(); - X2T_DECL_EXPORT _UINT32 FromFile(const std::wstring &file); - X2T_DECL_EXPORT _UINT32 FromXml(const std::wstring &xml); -} // namespace NExtractTools + X2T_DECL_EXPORT _UINT32 FromFile(const std::wstring& file); + X2T_DECL_EXPORT _UINT32 FromXml(const std::wstring& xml); +} #endif // ASCCONVERTERS_H diff --git a/X2tConverter/src/cextracttools.cpp b/X2tConverter/src/cextracttools.cpp index ca7b75be366..dfd7c90dec2 100644 --- a/X2tConverter/src/cextracttools.cpp +++ b/X2tConverter/src/cextracttools.cpp @@ -29,14 +29,54 @@ * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode * */ -#include "cextracttools.h" #include "../../DesktopEditor/common/Directory.h" -#include "../../DesktopEditor/common/Path.h" #include "../../DesktopEditor/common/StringBuilder.h" #include "../../OfficeUtils/src/OfficeUtils.h" +#include "cextracttools.h" namespace NExtractTools { + // utils + std::wstring string_replaceAll(std::wstring str, const std::wstring& from, const std::wstring& to) + { + size_t start_pos = 0; + while ((start_pos = str.find(from, start_pos)) != std::wstring::npos) + { + str.replace(start_pos, from.length(), to); + start_pos += to.length(); + } + return str; + } + bool compare_string_by_length(const std::wstring& x, const std::wstring& y) + { + if (!x.empty() && !y.empty()) + { + if (x.length() == y.length()) + return x.compare(y) <= 0; + else + return ((int)(x.length()) - (int)(y.length())) <= 0; + } + else + { + if (!x.empty()) + return false; + else if (!y.empty()) + return true; + } + return true; + } + + int getReturnErrorCode(_UINT32 nDefine) + { + return 0 == nDefine ? 0 : nDefine - AVS_ERROR_FIRST - AVS_FILEUTILS_ERROR_FIRST; + } + + bool copyOrigin(const std::wstring& sFileFrom, const std::wstring& sFileTo) + { + size_t nIndex = sFileFrom.rfind('.'); + return NSFile::CFileBinary::Copy(sFileFrom, NSSystemPath::GetDirectoryName(sFileTo) + FILE_SEPARATOR_STR + L"origin" + sFileFrom.substr(nIndex)); + } + const TConversionDirection getConversionDirectionFromExt(const std::wstring& sFile1, const std::wstring& sFile2) { TConversionDirection res = TCD_ERROR; @@ -52,7 +92,7 @@ namespace NExtractTools } // check for directory (unzip task) - int nSeparator2Pos = sFile2.rfind(L'/'); + size_t nSeparator2Pos = sFile2.rfind(L'/'); if (std::wstring::npos == nSeparator2Pos) { nSeparator2Pos = sFile2.rfind(L'\\'); @@ -289,6 +329,8 @@ namespace NExtractTools res = TCD_T2BIN; else if (0 == sExt2.compare(L".csv")) res = TCD_XLST2CSV; + else if (0 == sExt2.compare(L".xlsb")) + res = TCD_XLST2XLSB; } break; case AVS_OFFICESTUDIO_FILE_TEAMLAB_PPTY: @@ -430,6 +472,7 @@ namespace NExtractTools case AVS_OFFICESTUDIO_FILE_DOCUMENT_OTT: case AVS_OFFICESTUDIO_FILE_SPREADSHEET_OTS: case AVS_OFFICESTUDIO_FILE_PRESENTATION_OTP: + case AVS_OFFICESTUDIO_FILE_PRESENTATION_ODG: { if (0 == sExt2.compare(L".bin")) res = TCD_ODF2OOT_BIN; @@ -524,6 +567,164 @@ namespace NExtractTools return res; } + const TConversionDirection getConversionDirection(const std::wstring& sArg3) + { + TConversionDirection res = TCD_ERROR; + if (0 == sArg3.compare(_T("auto"))) + { + res = TCD_AUTO; + } + else if (0 == sArg3.compare(_T("docx2doct"))) + { + res = TCD_DOCX2DOCT; + } + else if (0 == sArg3.compare(_T("docxflat2doct"))) + { + res = TCD_DOCXFLAT2DOCT; + } + else if (0 == sArg3.compare(_T("doct2docx"))) + { + res = TCD_DOCT2DOCX; + } + else if (0 == sArg3.compare(_T("docx2doct_bin"))) + { + res = TCD_DOCX2DOCT_BIN; + } + else if (0 == sArg3.compare(_T("doct_bin2docx"))) + { + res = TCD_DOCT_BIN2DOCX; + } + else if (0 == sArg3.compare(_T("xslx2xlst"))) + { + res = TCD_XLSX2XLST; + } + else if (0 == sArg3.compare(_T("xslt2xlsx"))) + { + res = TCD_XLST2XLSX; + } + else if (0 == sArg3.compare(_T("xslx2xlst_bin"))) + { + res = TCD_XLSX2XLST_BIN; + } + else if (0 == sArg3.compare(_T("xslt_bin2xlsx"))) + { + res = TCD_XLST_BIN2XLSX; + } + else if (0 == sArg3.compare(_T("pptx2pptt"))) + { + res = TCD_PPTX2PPTT; + } + else if (0 == sArg3.compare(_T("pptt2pptx"))) + { + res = TCD_PPTT2PPTX; + } + else if (0 == sArg3.compare(_T("pptx2pptt_bin"))) + { + res = TCD_PPTX2PPTT_BIN; + } + else if (0 == sArg3.compare(_T("pptt_bin2pptx"))) + { + res = TCD_PPTT_BIN2PPTX; + } + else if (0 == sArg3.compare(_T("zip2dir"))) + { + res = TCD_ZIPDIR; + } + else if (0 == sArg3.compare(_T("dir2zip"))) + { + res = TCD_UNZIPDIR; + } + else if (0 == sArg3.compare(_T("csv2xlsx"))) + { + res = TCD_CSV2XLSX; + } + else if (0 == sArg3.compare(_T("csv2xlst"))) + { + res = TCD_CSV2XLST; + } + else if (0 == sArg3.compare(_T("xlsx2csv"))) + { + res = TCD_XLSX2CSV; + } + else if (0 == sArg3.compare(_T("xlst2csv"))) + { + res = TCD_XLST2CSV; + } + else if (0 == sArg3.compare(_T("bin2pdf"))) + { + res = TCD_BIN2PDF; + } + else if (0 == sArg3.compare(_T("bin2t"))) + { + res = TCD_BIN2T; + } + else if (0 == sArg3.compare(_T("t2bin"))) + { + res = TCD_T2BIN; + } + else if (0 == sArg3.compare(_T("ppsx2pptx"))) + { + res = TCD_PPSX2PPTX; + } + else if (0 == sArg3.compare(_T("potx2pptx"))) + { + res = TCD_POTX2PPTX; + } + else if (0 == sArg3.compare(_T("potm2pptm"))) + { + res = TCD_POTM2PPTM; + } + else if (0 == sArg3.compare(_T("xltx2xlsx"))) + { + res = TCD_XLTX2XLSX; + } + else if (0 == sArg3.compare(_T("xltm2xlsm"))) + { + res = TCD_XLTM2XLSM; + } + else if (0 == sArg3.compare(_T("dotx2docx"))) + { + res = TCD_DOTX2DOCX; + } + else if (0 == sArg3.compare(_T("dotm2docm"))) + { + res = TCD_DOTM2DOCM; + } + else if (0 == sArg3.compare(_T("ppt2pptx"))) + { + res = TCD_PPT2PPTX; + } + else if (0 == sArg3.compare(_T("ppt2pptm"))) + { + res = TCD_PPT2PPTM; + } + else if (0 == sArg3.compare(_T("doc2docx"))) + { + res = TCD_DOC2DOCX; + } + else if (0 == sArg3.compare(_T("doc2docm"))) + { + res = TCD_DOC2DOCM; + } + else if (0 == sArg3.compare(_T("rtf2docx"))) + { + res = TCD_RTF2DOCX; + } + else if (0 == sArg3.compare(_T("docx2rtf"))) + { + res = TCD_DOCX2RTF; + } + else if (0 == sArg3.compare(_T("txt2docx"))) + { + res = TCD_TXT2DOCX; + } + else if (0 == sArg3.compare(_T("docx2txt"))) + { + res = TCD_DOCX2TXT; + } + return res; + } + std::wstring getMailMergeXml(const std::wstring& sJsonPath, int nRecordFrom, int nRecordTo, const std::wstring& sField) { NSStringUtils::CStringBuilder oBuilder; @@ -538,9 +739,15 @@ namespace NExtractTools oBuilder.WriteString(L"\" />"); return oBuilder.GetData(); } + std::wstring getDoctXml( - NSDoctRenderer::DoctRendererFormat::FormatFile eFromType, NSDoctRenderer::DoctRendererFormat::FormatFile eToType, const std::wstring& sTFileSrc, const std::wstring& sPdfBinFile, - const std::wstring& sImagesDirectory, const std::wstring& sThemeDir, int nTopIndex, const std::wstring& sMailMerge, const InputParams& params) + NSDoctRenderer::DoctRendererFormat::FormatFile eFromType, + NSDoctRenderer::DoctRendererFormat::FormatFile eToType, + const std::wstring& sTFileSrc, const std::wstring& sPdfBinFile, + const std::wstring& sImagesDirectory, const std::wstring& sThemeDir, + int nTopIndex, + const std::wstring& sMailMerge, + const InputParams& params) { NSStringUtils::CStringBuilder oBuilder; oBuilder.WriteString(L""); @@ -584,12 +791,6 @@ namespace NExtractTools oBuilder.WriteEncodeXmlString(sJsonParams); oBuilder.WriteString(L""); } - if (NULL != params.m_sScriptsCacheDirectory) - { - oBuilder.WriteString(L""); - oBuilder.WriteEncodeXmlString(*params.m_sScriptsCacheDirectory); - oBuilder.WriteString(L""); - } oBuilder.WriteString(L""); @@ -620,9 +821,12 @@ namespace NExtractTools oBuilder.WriteString(L""); return oBuilder.GetData(); } + _UINT32 apply_changes( - const std::wstring& sBinFrom, const std::wstring& sToResult, NSDoctRenderer::DoctRendererFormat::FormatFile eType, const std::wstring& sThemeDir, std::wstring& sBinTo, - const InputParams& params) + const std::wstring& sBinFrom, const std::wstring& sToResult, + NSDoctRenderer::DoctRendererFormat::FormatFile eType, + std::wstring& sBinTo, + const InputParams& params, const ConvertParams& convertParams) { std::wstring sBinDir = NSDirectory::GetFolderPath(sBinFrom); std::wstring sChangesDir = sBinDir + FILE_SEPARATOR_STR + L"changes"; @@ -637,7 +841,7 @@ namespace NExtractTools int nChangeIndex = -1; while (true) { - std::wstring sXml = getDoctXml(eType, eType, sBinFrom, sBinTo, sImagesDirectory, sThemeDir, nChangeIndex, L"", params); + std::wstring sXml = getDoctXml(eType, eType, sBinFrom, sBinTo, sImagesDirectory, convertParams.m_sThemesDir, nChangeIndex, L"", params); std::wstring sResult; oDoctRenderer.Execute(sXml, sResult); bool bContinue = false; @@ -646,11 +850,11 @@ namespace NExtractTools std::wcerr << L"DoctRenderer:" << sResult << std::endl; params.m_bOutputConvertCorrupted = true; int nErrorIndex = -1; - int nErrorIndexStart = sResult.find(L"index"); + size_t nErrorIndexStart = sResult.find(L"index"); if (-1 != nErrorIndexStart) { nErrorIndexStart = sResult.find(L"\"", nErrorIndexStart + 1); - int nErrorIndexEnd = sResult.find(L"\"", nErrorIndexStart + 1); + size_t nErrorIndexEnd = sResult.find(L"\"", nErrorIndexStart + 1); nErrorIndex = XmlUtils::GetInteger(sResult.substr(nErrorIndexStart + 1, nErrorIndexEnd - nErrorIndexStart - 1)); } if (nErrorIndex > 0 && nChangeIndex != nErrorIndex) @@ -665,25 +869,10 @@ namespace NExtractTools } if (!bContinue) { - if (!sToResult.empty() && !params.getDontSaveAdditional()) + if (!params.getDontSaveAdditional()) { - std::vector aImages = oDoctRenderer.GetImagesInChanges(); - // todo сделать interface у COfficeUtils, чтобы можно было делать архив из файлов в разных папках. - for (size_t i = 0; i < aImages.size(); ++i) - { - std::wstring sImageName = aImages[i]; - std::wstring sImage = sImagesDirectory + FILE_SEPARATOR_STR + sImageName; - std::wstring sImageCopy = sChangesDir + FILE_SEPARATOR_STR + sImageName; - NSFile::CFileBinary::Copy(sImage, sImageCopy); - } - ////copy doct for version history - // std::wstring sBinCopy = sChangesDir + FILE_SEPARATOR_STR + NSSystemPath::GetFileName(sBinFrom); - // NSFile::CFileBinary::Copy(sBinFrom, sBinCopy); - - std::wstring sToResultDir = NSDirectory::GetFolderPath(sToResult); - std::wstring sTo = sToResultDir + FILE_SEPARATOR_STR + L"changes.zip"; - COfficeUtils oCOfficeUtils(NULL); - oCOfficeUtils.CompressFileOrDirectory(sChangesDir, sTo); + //create changes.zip next to result file + copyImagesFromChanges(&oDoctRenderer, sImagesDirectory, sChangesDir,NSDirectory::GetFolderPath(*params.m_sFileTo)); } break; } @@ -693,6 +882,29 @@ namespace NExtractTools sBinTo = sBinFrom; return 0; } + + bool copyImagesFromChanges(NSDoctRenderer::CDoctrenderer* pDoctRenderer, + const std::wstring& sSrcImagesDir, const std::wstring& sChangesDir, + const std::wstring& sResultDirectory) + { + std::vector aImages = pDoctRenderer->GetImagesInChanges(); + // todo сделать interface у COfficeUtils, чтобы можно было делать архив из файлов в разных папках. + for (size_t i = 0; i < aImages.size(); ++i) + { + std::wstring sImageName = aImages[i]; + std::wstring sImage = sSrcImagesDir + FILE_SEPARATOR_STR + sImageName; + std::wstring sImageCopy = sChangesDir + FILE_SEPARATOR_STR + sImageName; + NSFile::CFileBinary::Copy(sImage, sImageCopy); + } + ////copy doct for version history + // std::wstring sBinCopy = sChangesDir + FILE_SEPARATOR_STR + NSSystemPath::GetFileName(sBinFrom); + // NSFile::CFileBinary::Copy(sBinFrom, sBinCopy); + + std::wstring sTo = sResultDirectory + FILE_SEPARATOR_STR + L"changes.zip"; + COfficeUtils oCOfficeUtils(NULL); + return (S_OK == oCOfficeUtils.CompressFileOrDirectory(sChangesDir, sTo)) ? true : false; + } + bool InputParams::checkInputLimits() { std::wstring& sFrom = *this->m_sFileFrom; diff --git a/X2tConverter/src/cextracttools.h b/X2tConverter/src/cextracttools.h index eaf015a30e6..c13dfde3c4b 100644 --- a/X2tConverter/src/cextracttools.h +++ b/X2tConverter/src/cextracttools.h @@ -49,15 +49,10 @@ #include #include -#define SUCCEEDED_X2T(nRes) (0 == (nRes) || AVS_FILEUTILS_ERROR_CONVERT_ROWLIMITS == (nRes)) +#define SUCCEEDED_X2T(nRes) (0 == (nRes) || AVS_FILEUTILS_ERROR_CONVERT_ROWLIMITS == (nRes) || AVS_FILEUTILS_ERROR_CONVERT_CELLLIMITS == (nRes)) namespace NExtractTools { - static const wchar_t* gc_sDoctRendererXml = - _T("%d%d%ls%ls%ls%ls%ls%ls%ls"); - static const wchar_t* gc_sDoctRendererMailMergeXml = _T(""); - typedef enum tagTConversionDirection { TCD_ERROR, @@ -100,6 +95,7 @@ namespace NExtractTools TCD_XLTM2XLSM, TCD_XLSB2XLST, TCD_XLSX2XLSB, + TCD_XLST2XLSB, TCD_PPTX2PPTT, TCD_PPTT2PPTX, @@ -220,17 +216,17 @@ namespace NExtractTools TCD_EPUB2DOCX, TCD_EPUB2DOCT, TCD_EPUB2DOCT_BIN, - - TCD_MAILMERGE, - TCD_T2, - TCD_DOCT_BIN2, - TCD_XLST_BIN2, - TCD_PPTT_BIN2, - TCD_DOCUMENT2, - TCD_SPREADSHEET2, - TCD_PRESENTATION2, - TCD_CROSSPLATFORM2, - TCD_CANVAS_PDF2 + TCD_MAILMERGE, + TCD_T2, + TCD_DOCT_BIN2, + TCD_XLST_BIN2, + TCD_PPTT_BIN2, + TCD_DOCUMENT2, + TCD_SPREADSHEET2, + TCD_PRESENTATION2, + TCD_CROSSPLATFORM2, + TCD_CANVAS_PDF2, + TCD_DRAW2 } TConversionDirection; typedef enum tagTCsvDelimiter @@ -243,13 +239,12 @@ namespace NExtractTools TCSVD_SPACE = 5 } TCsvDelimiter; + int getReturnErrorCode(_UINT32 nDefine); + const TConversionDirection getConversionDirectionFromExt(const std::wstring& sFile1, const std::wstring& sFile2); + const TConversionDirection getConversionDirection(const std::wstring& sArg3); - static bool copyOrigin(const std::wstring& sFileFrom, const std::wstring& sFileTo) - { - size_t nIndex = sFileFrom.rfind('.'); - return NSFile::CFileBinary::Copy(sFileFrom, NSSystemPath::GetDirectoryName(sFileTo) + FILE_SEPARATOR_STR + _T("origin") + sFileFrom.substr(nIndex)); - } + bool copyOrigin(const std::wstring& sFileFrom, const std::wstring& sFileTo); class InputParamsMailMerge { @@ -457,6 +452,35 @@ namespace NExtractTools } }; + class ConvertParams + { + public: + std::wstring m_sTempDir; + std::wstring m_sThemesDir; + + std::wstring m_sEditorWithChanges; + + // [docx_dir2doct_bin, xlsx_dir2xlst_bin, pptx_dir2pptt_bin] methods + std::wstring m_sTempParamOOXMLFile; + + // for doct_bin2docx_dir, xlst_bin2xlsx_dir, pptt_bin2pptx_dir + std::wstring m_sTempResultOOXMLDirectory; + + // xlsx_dir2xlst_bin + bool m_bTempIsXmlOptions = false; + + bool m_bIsTemplate = false; + bool m_bIsPaid = false; + + std::wstring m_sMediaDirectory; + std::wstring m_sInternalMediaDirectory; + + std::string m_sPrintPages; + + std::wstring m_sPdfOformMetaName; + std::wstring m_sPdfOformMetaData; + }; + class InputParams { public: @@ -488,7 +512,6 @@ namespace NExtractTools boost::unordered_map> m_mapInputLimits; bool* m_bIsPDFA; std::wstring* m_sConvertToOrigin; - std::wstring* m_sScriptsCacheDirectory; // output params mutable bool m_bOutputConvertCorrupted; mutable bool m_bMacro; @@ -523,7 +546,6 @@ namespace NExtractTools m_bIsNoBase64 = NULL; m_bIsPDFA = NULL; m_sConvertToOrigin = NULL; - m_sScriptsCacheDirectory = NULL; m_bOutputConvertCorrupted = false; m_bMacro = false; @@ -557,7 +579,6 @@ namespace NExtractTools RELEASEOBJECT(m_bIsNoBase64); RELEASEOBJECT(m_bIsPDFA); RELEASEOBJECT(m_sConvertToOrigin); - RELEASEOBJECT(m_sScriptsCacheDirectory); } bool FromXmlFile(const std::wstring& sFilename) @@ -746,11 +767,6 @@ namespace NExtractTools RELEASEOBJECT(m_sConvertToOrigin); m_sConvertToOrigin = new std::wstring(sValue); } - else if (_T("m_sScriptsCacheDirectory") == sName) - { - RELEASEOBJECT(m_sScriptsCacheDirectory); - m_sScriptsCacheDirectory = new std::wstring(sValue); - } } else if (_T("m_nCsvDelimiterChar") == sName) { @@ -851,6 +867,7 @@ namespace NExtractTools std::wstring sRes; int nCsvEncoding = 46; // 65001 utf8 std::wstring cDelimiter = L","; + int LcId = -1; if (NULL != m_nCsvTxtEncoding) nCsvEncoding = *m_nCsvTxtEncoding; @@ -879,6 +896,12 @@ namespace NExtractTools { cDelimiter = *m_sCsvDelimiterChar; } + + if(m_nLcid != NULL) + { + LcId = *m_nLcid; + } + int nFileType = 1; if (NULL != m_nFormatFrom && AVS_OFFICESTUDIO_FILE_SPREADSHEET_CSV == *m_nFormatFrom) nFileType = 2; @@ -892,11 +915,15 @@ namespace NExtractTools sSaveType = _T(" saveFileType='3'"); else if (AVS_OFFICESTUDIO_FILE_SPREADSHEET_CSV == *m_nFormatTo) nFileType = 2; + else if (AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSB == *m_nFormatTo) + nFileType = 4; } sRes = L"" + std::to_wstring(nCsvEncoding) + L""; @@ -929,13 +956,24 @@ namespace NExtractTools if (nFormatFrom != FileFormatChecker.nFileType && FileFormatChecker.nFileType != AVS_OFFICESTUDIO_FILE_UNKNOWN) { nFormatFrom = FileFormatChecker.nFileType; - changeFormatFrom(nFormatFrom, FileFormatChecker.bMacroEnabled); + *m_nFormatFrom = nFormatFrom; + + changeFormatFromPrev(nFormatFrom); } } eRes = processDownloadFile(); if (TCD_AUTO != eRes) return eRes; + if ((nFormatFrom == AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCXF || + nFormatFrom == AVS_OFFICESTUDIO_FILE_DOCUMENT_OFORM || + nFormatFrom == AVS_OFFICESTUDIO_FILE_DOCUMENT_OFORM_PDF) && + nFormatTo == AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_PDF) + { + nFormatTo = AVS_OFFICESTUDIO_FILE_DOCUMENT_OFORM_PDF; + *m_nFormatTo = AVS_OFFICESTUDIO_FILE_DOCUMENT_OFORM_PDF; + } + if (NULL != m_oMailMergeSend) eRes = TCD_MAILMERGE; else if ((AVS_OFFICESTUDIO_FILE_DOCUMENT_XML == nFormatFrom) && 0 != (AVS_OFFICESTUDIO_FILE_OTHER & nFormatTo)) @@ -948,6 +986,8 @@ namespace NExtractTools eRes = TCD_SPREADSHEET2; else if (0 != (AVS_OFFICESTUDIO_FILE_PRESENTATION & nFormatFrom)) eRes = TCD_PRESENTATION2; + else if (0 != (AVS_OFFICESTUDIO_FILE_DRAW & nFormatFrom)) + eRes = TCD_DRAW2; else if (0 != (AVS_OFFICESTUDIO_FILE_TEAMLAB & nFormatFrom)) eRes = TCD_T2; else if (AVS_OFFICESTUDIO_FILE_CANVAS_WORD == nFormatFrom) @@ -999,12 +1039,19 @@ namespace NExtractTools { if (isEmptyFile()) { - m_nCsvTxtEncoding = new int(getEncodingByContent()); - m_sCsvDelimiterChar = new std::wstring(L","); + if (!m_nCsvTxtEncoding) + { + m_nCsvTxtEncoding = new int(getEncodingByContent()); //-1 ??? + } + if (!m_nCsvDelimiter && !m_sCsvDelimiterChar) + { + m_sCsvDelimiterChar = new std::wstring(L","); + } + eRes = TCD_ERROR; // ??? } else { - if (!getDontSaveAdditional()) + if (false/*not used*/ && !getDontSaveAdditional()) { int nCodePage = getEncodingByContent(); if (nCodePage < 0) @@ -1018,6 +1065,10 @@ namespace NExtractTools oBuilder.WriteString(_T("}")); std::wstring sFilePath = NSSystemPath::GetDirectoryName(*m_sFileTo) + FILE_SEPARATOR_STR + _T("settings.json"); NSFile::CFileBinary::SaveToFile(sFilePath, oBuilder.GetData()); + } + + if (!getDontSaveAdditional()) + { copyOrigin(*m_sFileFrom, *m_sFileTo); } eRes = TCD_ERROR; @@ -1107,7 +1158,7 @@ namespace NExtractTools } return nRes; } - void changeFormatFrom(int formatFrom, bool bMacroEnabled) + void changeFormatFromPrev(int formatFrom) { *m_nFormatFrom = formatFrom; int toFormat = *m_nFormatTo; @@ -1129,62 +1180,108 @@ namespace NExtractTools } else if (AVS_OFFICESTUDIO_FILE_OTHER_OOXML == toFormat || AVS_OFFICESTUDIO_FILE_OTHER_ODF == toFormat) { - if (AVS_OFFICESTUDIO_FILE_CANVAS_SPREADSHEET == formatFrom || AVS_OFFICESTUDIO_FILE_TEAMLAB_XLSY == formatFrom || 0 != (AVS_OFFICESTUDIO_FILE_SPREADSHEET & formatFrom)) + if (formatFrom == AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX || + formatFrom == AVS_OFFICESTUDIO_FILE_DOCUMENT_DOTX || + formatFrom == AVS_OFFICESTUDIO_FILE_DOCUMENT_RTF || + formatFrom == AVS_OFFICESTUDIO_FILE_DOCUMENT_TXT || + formatFrom == AVS_OFFICESTUDIO_FILE_DOCUMENT_HTML || + formatFrom == AVS_OFFICESTUDIO_FILE_DOCUMENT_MHT || + formatFrom == AVS_OFFICESTUDIO_FILE_DOCUMENT_EPUB || + formatFrom == AVS_OFFICESTUDIO_FILE_DOCUMENT_FB2 || + formatFrom == AVS_OFFICESTUDIO_FILE_DOCUMENT_MOBI || + formatFrom == AVS_OFFICESTUDIO_FILE_DOCUMENT_DOC_FLAT || + formatFrom == AVS_OFFICESTUDIO_FILE_DOCUMENT_HTML_IN_CONTAINER || + formatFrom == AVS_OFFICESTUDIO_FILE_DOCUMENT_OFORM_PDF) { if (AVS_OFFICESTUDIO_FILE_OTHER_ODF == toFormat) { - toFormat = AVS_OFFICESTUDIO_FILE_SPREADSHEET_ODS; + toFormat = AVS_OFFICESTUDIO_FILE_DOCUMENT_ODT; } else { - if (bMacroEnabled) - { - toFormat = AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSM; - } - else - { - toFormat = AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSX; - } + toFormat = AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX; } } - else if (AVS_OFFICESTUDIO_FILE_CANVAS_PRESENTATION == formatFrom || AVS_OFFICESTUDIO_FILE_TEAMLAB_PPTY == formatFrom || 0 != (AVS_OFFICESTUDIO_FILE_PRESENTATION & formatFrom)) + else if (AVS_OFFICESTUDIO_FILE_CANVAS_SPREADSHEET == formatFrom || + AVS_OFFICESTUDIO_FILE_TEAMLAB_XLSY == formatFrom || 0 != (AVS_OFFICESTUDIO_FILE_SPREADSHEET & formatFrom)) { if (AVS_OFFICESTUDIO_FILE_OTHER_ODF == toFormat) { - toFormat = AVS_OFFICESTUDIO_FILE_PRESENTATION_ODP; + toFormat = AVS_OFFICESTUDIO_FILE_SPREADSHEET_ODS; } - else + } + else if (AVS_OFFICESTUDIO_FILE_CANVAS_PRESENTATION == formatFrom || + AVS_OFFICESTUDIO_FILE_TEAMLAB_PPTY == formatFrom || 0 != (AVS_OFFICESTUDIO_FILE_PRESENTATION & formatFrom)) + { + if (AVS_OFFICESTUDIO_FILE_OTHER_ODF == toFormat) { - if (bMacroEnabled) - { - toFormat = AVS_OFFICESTUDIO_FILE_PRESENTATION_PPTM; - } - else - { - toFormat = AVS_OFFICESTUDIO_FILE_PRESENTATION_PPTX; - } + toFormat = AVS_OFFICESTUDIO_FILE_PRESENTATION_ODP; } } else if (AVS_OFFICESTUDIO_FILE_DOCUMENT_XML == formatFrom) { return; } - else if (AVS_OFFICESTUDIO_FILE_CANVAS_WORD == formatFrom || AVS_OFFICESTUDIO_FILE_TEAMLAB_DOCY == formatFrom || 0 != (AVS_OFFICESTUDIO_FILE_DOCUMENT & formatFrom)) + else if (AVS_OFFICESTUDIO_FILE_CANVAS_WORD == formatFrom || + AVS_OFFICESTUDIO_FILE_TEAMLAB_DOCY == formatFrom || 0 != (AVS_OFFICESTUDIO_FILE_DOCUMENT & formatFrom)) { if (AVS_OFFICESTUDIO_FILE_OTHER_ODF == toFormat) { toFormat = AVS_OFFICESTUDIO_FILE_DOCUMENT_ODT; } + } + COfficeFileFormatChecker FileFormatChecker; + std::wstring sNewExt = FileFormatChecker.GetExtensionByType(toFormat); + + size_t nIndex = m_sFileTo->rfind('.'); + if (false == sNewExt.empty()) + { + if (std::wstring::npos != nIndex) + m_sFileTo->replace(nIndex, std::wstring::npos, sNewExt); else + m_sFileTo->append(sNewExt); + } + } + *m_nFormatTo = toFormat; + } + void changeFormatFromPost(int formatFrom, bool bMacroEnabled) + { + *m_nFormatFrom = formatFrom; + int toFormat = *m_nFormatTo; + + if (AVS_OFFICESTUDIO_FILE_OTHER_OOXML == toFormat) + { + if (AVS_OFFICESTUDIO_FILE_CANVAS_SPREADSHEET == formatFrom || AVS_OFFICESTUDIO_FILE_TEAMLAB_XLSY == formatFrom || 0 != (AVS_OFFICESTUDIO_FILE_SPREADSHEET & formatFrom)) + { + if (bMacroEnabled) { - if (bMacroEnabled) - { - toFormat = AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCM; - } - else - { - toFormat = AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX; - } + toFormat = AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSM; + } + else + { + toFormat = AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSX; + } + } + else if (AVS_OFFICESTUDIO_FILE_CANVAS_PRESENTATION == formatFrom || AVS_OFFICESTUDIO_FILE_TEAMLAB_PPTY == formatFrom || 0 != (AVS_OFFICESTUDIO_FILE_PRESENTATION & formatFrom)) + { + if (bMacroEnabled) + { + toFormat = AVS_OFFICESTUDIO_FILE_PRESENTATION_PPTM; + } + else + { + toFormat = AVS_OFFICESTUDIO_FILE_PRESENTATION_PPTX; + } + } + else if (AVS_OFFICESTUDIO_FILE_CANVAS_WORD == formatFrom || AVS_OFFICESTUDIO_FILE_TEAMLAB_DOCY == formatFrom || 0 != (AVS_OFFICESTUDIO_FILE_DOCUMENT & formatFrom)) + { + if (bMacroEnabled) + { + toFormat = AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCM; + } + else + { + toFormat = AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX; } } size_t nIndex = m_sFileTo->rfind('.'); @@ -1216,229 +1313,30 @@ namespace NExtractTools } }; - static std::wstring string_replaceAll(std::wstring str, const std::wstring& from, const std::wstring& to) - { - size_t start_pos = 0; - while ((start_pos = str.find(from, start_pos)) != std::wstring::npos) - { - str.replace(start_pos, from.length(), to); - start_pos += to.length(); - } - return str; - } - static int getReturnErrorCode(_UINT32 nDefine) - { - return 0 == nDefine ? 0 : nDefine - AVS_ERROR_FIRST - AVS_FILEUTILS_ERROR_FIRST; - } - - static std::wstring getXMLOptionsFromFile(std::wstring xmlFileName) - { - std::wstring sXMLOptions; - - std::wifstream options_stream; -#if defined(_WIN32) || defined(_WIN64) - options_stream.open(xmlFileName.c_str()); -#else - options_stream.open(NSFile::CUtf8Converter::GetUtf8StringFromUnicode(xmlFileName)); -#endif - if (options_stream.is_open()) - { - while (true) - { - std::wstring line; - std::getline(options_stream, line); - - if (line.size() < 1) - break; - sXMLOptions += line; - } - options_stream.close(); - } - return sXMLOptions; - } - - static const TConversionDirection getConversionDirection(const std::wstring& sArg3) - { - TConversionDirection res = TCD_ERROR; - if (0 == sArg3.compare(_T("auto"))) - { - res = TCD_AUTO; - } - else if (0 == sArg3.compare(_T("docx2doct"))) - { - res = TCD_DOCX2DOCT; - } - else if (0 == sArg3.compare(_T("docxflat2doct"))) - { - res = TCD_DOCXFLAT2DOCT; - } - else if (0 == sArg3.compare(_T("doct2docx"))) - { - res = TCD_DOCT2DOCX; - } - else if (0 == sArg3.compare(_T("docx2doct_bin"))) - { - res = TCD_DOCX2DOCT_BIN; - } - else if (0 == sArg3.compare(_T("doct_bin2docx"))) - { - res = TCD_DOCT_BIN2DOCX; - } - else if (0 == sArg3.compare(_T("xslx2xlst"))) - { - res = TCD_XLSX2XLST; - } - else if (0 == sArg3.compare(_T("xslt2xlsx"))) - { - res = TCD_XLST2XLSX; - } - else if (0 == sArg3.compare(_T("xslx2xlst_bin"))) - { - res = TCD_XLSX2XLST_BIN; - } - else if (0 == sArg3.compare(_T("xslt_bin2xlsx"))) - { - res = TCD_XLST_BIN2XLSX; - } - else if (0 == sArg3.compare(_T("pptx2pptt"))) - { - res = TCD_PPTX2PPTT; - } - else if (0 == sArg3.compare(_T("pptt2pptx"))) - { - res = TCD_PPTT2PPTX; - } - else if (0 == sArg3.compare(_T("pptx2pptt_bin"))) - { - res = TCD_PPTX2PPTT_BIN; - } - else if (0 == sArg3.compare(_T("pptt_bin2pptx"))) - { - res = TCD_PPTT_BIN2PPTX; - } - else if (0 == sArg3.compare(_T("zip2dir"))) - { - res = TCD_ZIPDIR; - } - else if (0 == sArg3.compare(_T("dir2zip"))) - { - res = TCD_UNZIPDIR; - } - else if (0 == sArg3.compare(_T("csv2xlsx"))) - { - res = TCD_CSV2XLSX; - } - else if (0 == sArg3.compare(_T("csv2xlst"))) - { - res = TCD_CSV2XLST; - } - else if (0 == sArg3.compare(_T("xlsx2csv"))) - { - res = TCD_XLSX2CSV; - } - else if (0 == sArg3.compare(_T("xlst2csv"))) - { - res = TCD_XLST2CSV; - } - else if (0 == sArg3.compare(_T("bin2pdf"))) - { - res = TCD_BIN2PDF; - } - else if (0 == sArg3.compare(_T("bin2t"))) - { - res = TCD_BIN2T; - } - else if (0 == sArg3.compare(_T("t2bin"))) - { - res = TCD_T2BIN; - } - else if (0 == sArg3.compare(_T("ppsx2pptx"))) - { - res = TCD_PPSX2PPTX; - } - else if (0 == sArg3.compare(_T("potx2pptx"))) - { - res = TCD_POTX2PPTX; - } - else if (0 == sArg3.compare(_T("potm2pptm"))) - { - res = TCD_POTM2PPTM; - } - else if (0 == sArg3.compare(_T("xltx2xlsx"))) - { - res = TCD_XLTX2XLSX; - } - else if (0 == sArg3.compare(_T("xltm2xlsm"))) - { - res = TCD_XLTM2XLSM; - } - else if (0 == sArg3.compare(_T("dotx2docx"))) - { - res = TCD_DOTX2DOCX; - } - else if (0 == sArg3.compare(_T("dotm2docm"))) - { - res = TCD_DOTM2DOCM; - } - else if (0 == sArg3.compare(_T("ppt2pptx"))) - { - res = TCD_PPT2PPTX; - } - else if (0 == sArg3.compare(_T("ppt2pptm"))) - { - res = TCD_PPT2PPTM; - } - else if (0 == sArg3.compare(_T("doc2docx"))) - { - res = TCD_DOC2DOCX; - } - else if (0 == sArg3.compare(_T("doc2docm"))) - { - res = TCD_DOC2DOCM; - } - else if (0 == sArg3.compare(_T("rtf2docx"))) - { - res = TCD_RTF2DOCX; - } - else if (0 == sArg3.compare(_T("docx2rtf"))) - { - res = TCD_DOCX2RTF; - } - else if (0 == sArg3.compare(_T("txt2docx"))) - { - res = TCD_TXT2DOCX; - } - else if (0 == sArg3.compare(_T("docx2txt"))) - { - res = TCD_DOCX2TXT; - } - return res; - } + // utils + std::wstring string_replaceAll(std::wstring str, const std::wstring& from, const std::wstring& to); + bool compare_string_by_length(const std::wstring& x, const std::wstring& y); - static bool compare_string_by_length(const std::wstring& x, const std::wstring& y) - { - if (!x.empty() && !y.empty()) - { - if (x.length() == y.length()) - return x.compare(y) <= 0; - else - return ((int)(x.length()) - (int)(y.length())) <= 0; - } - else - { - if (!x.empty()) - return false; - else if (!y.empty()) - return true; - } - return true; - } std::wstring getMailMergeXml(const std::wstring& sJsonPath, int nRecordFrom, int nRecordTo, const std::wstring& sField); + std::wstring getDoctXml( - NSDoctRenderer::DoctRendererFormat::FormatFile eFromType, NSDoctRenderer::DoctRendererFormat::FormatFile eToType, const std::wstring& sTFileSrc, const std::wstring& sPdfBinFile, - const std::wstring& sImagesDirectory, const std::wstring& sThemeDir, int nTopIndex, const std::wstring& sMailMerge, const InputParams& params); - _UINT32 apply_changes( - const std::wstring& sBinFrom, const std::wstring& sToResult, NSDoctRenderer::DoctRendererFormat::FormatFile eType, const std::wstring& sThemeDir, std::wstring& sBinTo, + NSDoctRenderer::DoctRendererFormat::FormatFile eFromType, + NSDoctRenderer::DoctRendererFormat::FormatFile eToType, + const std::wstring& sTFileSrc, const std::wstring& sPdfBinFile, + const std::wstring& sImagesDirectory, const std::wstring& sThemeDir, + int nTopIndex, + const std::wstring& sMailMerge, const InputParams& params); + + _UINT32 apply_changes( + const std::wstring& sBinFrom, const std::wstring& sToResult, + NSDoctRenderer::DoctRendererFormat::FormatFile eType, + std::wstring& sBinTo, + const InputParams& params, const ConvertParams& convertParams); + + bool copyImagesFromChanges(NSDoctRenderer::CDoctrenderer* pDoctRenderer, + const std::wstring& sSrcImagesDir, const std::wstring& sChangesDir, + const std::wstring& sResultDirectory); + } // namespace NExtractTools #endif // CEXTRACTTOOLS_H diff --git a/X2tConverter/src/dylib/export b/X2tConverter/src/dylib/export index 60482f7d55b..99e4e2444df 100755 --- a/X2tConverter/src/dylib/export +++ b/X2tConverter/src/dylib/export @@ -1,2 +1,3 @@ # File: export list _X2T_Convert +_GetOfficeFileFormat diff --git a/X2tConverter/src/dylib/x2t.cpp b/X2tConverter/src/dylib/x2t.cpp index ab8fa2a325a..4e7751479a3 100644 --- a/X2tConverter/src/dylib/x2t.cpp +++ b/X2tConverter/src/dylib/x2t.cpp @@ -35,5 +35,17 @@ int X2T_Convert(int argc, x2tchar *argv[]) { - return main_lib(argc, argv); +#if !defined(_WIN32) && !defined(_WIN64) + return main_lib(argc, argv); +#else + return wmain_lib(argc, argv); +#endif +} + +X2T_DECL int GetOfficeFileFormat(wchar_t* path) +{ + COfficeFileFormatChecker oChecker; + if (oChecker.isOfficeFile(std::wstring(path))) + return oChecker.nFileType; + return AVS_OFFICESTUDIO_FILE_UNKNOWN; } diff --git a/X2tConverter/src/dylib/x2t.h b/X2tConverter/src/dylib/x2t.h index d1f4bcbf5d5..10bf71f77b5 100644 --- a/X2tConverter/src/dylib/x2t.h +++ b/X2tConverter/src/dylib/x2t.h @@ -61,6 +61,7 @@ extern "C" { #endif X2T_DECL int X2T_Convert(int argc, x2tchar *argv[]); +X2T_DECL int GetOfficeFileFormat(wchar_t* path); #ifdef __cplusplus } diff --git a/X2tConverter/src/lib/common.h b/X2tConverter/src/lib/common.h new file mode 100644 index 00000000000..47a901dbbf3 --- /dev/null +++ b/X2tConverter/src/lib/common.h @@ -0,0 +1,495 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#pragma once + +#include "../ASCConverters.h" +#include "../cextracttools.h" + +#include "../../../DesktopEditor/common/Directory.h" +#include "../../../OfficeUtils/src/OfficeUtils.h" + +#include "../../../DesktopEditor/graphics/pro/Fonts.h" + +namespace NExtractTools +{ + // COMMON FUNCTIONS + NSFonts::IApplicationFonts* createApplicationFonts(InputParams& params) + { + NSFonts::IApplicationFonts* pFonts = NSFonts::NSApplication::Create(); + + std::wstring sFontPath = params.getFontPath(); + + if (sFontPath.empty()) + pFonts->Initialize(); + else + pFonts->InitializeFromFolder(sFontPath); + + return pFonts; + } + + std::wstring getExtentionByRasterFormat(int format) + { + switch (format) + { + case 1: return L".bmp"; + case 2: return L".gif"; + case 3: return L".jpg"; + default: return L".png"; + } + return L""; + } + + std::wstring combinePath(const std::wstring& sDir, const std::wstring& sName) + { + return sDir + FILE_SEPARATOR_STR + sName; + } + + _UINT32 processEncryptionError(_UINT32 hRes, const std::wstring& sFrom, InputParams& params) + { + if (AVS_ERROR_DRM == hRes) + { + if (!params.getDontSaveAdditional()) + { + copyOrigin(sFrom, *params.m_sFileTo); + } + return AVS_FILEUTILS_ERROR_CONVERT_DRM; + } + else if (AVS_ERROR_PASSWORD == hRes) + { + return AVS_FILEUTILS_ERROR_CONVERT_PASSWORD; + } + return hRes; + } + + bool create_if_empty(const std::wstring& sFrom, const std::wstring& sTo, const std::wstring& signature) + { + bool res = false; + NSFile::CFileBinary file; + if (file.OpenFile(sFrom)) + { + long file_size = file.GetFileSize(); + file.CloseFile(); + + if (file_size == 0) + { + file.CreateFileW(sTo); + + if (false == signature.empty()) + { + file.WriteStringUTF8(signature); + } + file.CloseFile(); + + res = true; + } + } + return res; + } + + // Add record to [Content_Types].xml + _UINT32 addContentType(const std::wstring& sDir, const std::wstring& sCT) + { + _UINT32 nRes = 0; + std::wstring sContentTypesPath = combinePath(sDir, L"[Content_Types].xml"); + if (NSFile::CFileBinary::Exists(sContentTypesPath)) + { + std::wstring sData; + if (NSFile::CFileBinary::ReadAllTextUtf8(sContentTypesPath, sData)) + { + if (std::wstring::npos == sData.find(sCT)) + { + sData = string_replaceAll(sData, L"", sCT + L""); + if (false == NSFile::CFileBinary::SaveToFile(sContentTypesPath, sData, true)) + nRes = AVS_FILEUTILS_ERROR_CONVERT; + } + } + } + return nRes; + } + + // Replace record to [Content_Types].xml + _UINT32 replaceContentType(const std::wstring& sDir, const std::wstring& sCTFrom, const std::wstring& sCTTo) + { + _UINT32 nRes = 0; + std::wstring sContentTypesPath = combinePath(sDir, L"[Content_Types].xml"); + if (NSFile::CFileBinary::Exists(sContentTypesPath)) + { + std::wstring sData; + if (NSFile::CFileBinary::ReadAllTextUtf8(sContentTypesPath, sData)) + { + sData = string_replaceAll(sData, sCTFrom, sCTTo); + if (false == NSFile::CFileBinary::SaveToFile(sContentTypesPath, sData, true)) + nRes = AVS_FILEUTILS_ERROR_CONVERT; + } + } + return nRes; + } + + // zip methods + _UINT32 dir2zip(const std::wstring& sFrom, const std::wstring& sTo, bool bSorted, int method, short level, bool bDateTime) + { + COfficeUtils oCOfficeUtils(NULL); + return (S_OK == oCOfficeUtils.CompressFileOrDirectory(sFrom, sTo, bSorted, method, level, bDateTime)) ? 0 : AVS_FILEUTILS_ERROR_CONVERT; + } + _UINT32 zip2dir(const std::wstring& sFrom, const std::wstring& sTo) + { + COfficeUtils oCOfficeUtils(NULL); + return (S_OK == oCOfficeUtils.ExtractToDirectory(sFrom, sTo, NULL, 0)) ? 0 : AVS_FILEUTILS_ERROR_CONVERT; + } + + // compress ooxml directory to archive and encrypt if needed. + _UINT32 dir2zipMscrypt(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + _UINT32 nRes = S_OK; + if (params.hasSavePassword()) + { + std::wstring sToMscrypt = combinePath(convertParams.m_sTempDir, L"tomscrypt.docx"); + nRes = dir2zip(sFrom, sToMscrypt); + if (SUCCEEDED_X2T(nRes)) + { + nRes = oox2mscrypt(sToMscrypt, sTo, params, convertParams); + } + } + else + { + nRes = dir2zip(sFrom, sTo, true); + } + return nRes; + } + + // Copy file sFromDir or sFromFile => sToDir/sToFile (compress directory, if sFromFile is empty) + _UINT32 CopyOOXOrigin(const std::wstring& sToDir, const std::wstring& sFromDir, const std::wstring& sToFile, const std::wstring& sFromFile) + { + std::wstring sDstFile = combinePath(sToDir, sToFile); + if (sFromFile.empty()) + return dir2zip(sFromDir, sDstFile); + return NSFile::CFileBinary::Copy(sFromFile, sDstFile) ? 0 : AVS_FILEUTILS_ERROR_CONVERT; + } + + namespace NSCommon + { + enum class OOXML_DOCUMENT_TYPE + { + Word = 0, + Sheet = 1, + Slide = 2 + }; + + enum class OOXML_DOCUMENT_SUBTYPE + { + Main = 0, + Template = 1, + Show = 2 + }; + + // convert any format to internal format + // 1) create temp directory with name prefix + // 2) convert to internal format with func2dir method + // 3) compress to zip archive + _UINT32 format2oot(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams, + const std::wstring& prefix, CONVERT_FUNC func2dir) + { + std::wstring sOOTDir = combinePath(convertParams.m_sTempDir, prefix + L"_unpacked"); + std::wstring sOOTFileEditor = combinePath(sOOTDir, L"Editor.bin"); + NSDirectory::CreateDirectory(sOOTDir); + + _UINT32 nRes = func2dir(sFrom, sOOTFileEditor, params, convertParams); + + if (SUCCEEDED_X2T(nRes)) + { + COfficeUtils oCOfficeUtils(NULL); + nRes = (S_OK == oCOfficeUtils.CompressFileOrDirectory(sOOTDir, sTo)) ? nRes : AVS_FILEUTILS_ERROR_CONVERT; + } + + return nRes; + } + + // convert internal format to any format + // 1) create temp directory with name prefix + // 2) extract internal format to directory [1] + // 3) convert to any format with func method + _UINT32 oot2format(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams, + const std::wstring& prefix, CONVERT_FUNC func) + { + std::wstring sOOTDir = combinePath(convertParams.m_sTempDir, prefix + L"_unpacked"); + std::wstring sOOTFileEditor = combinePath(sOOTDir, L"Editor.bin"); + NSDirectory::CreateDirectory(sOOTDir); + + // unzip doct to folder + COfficeUtils oCOfficeUtils(NULL); + if (S_OK != oCOfficeUtils.ExtractToDirectory(sFrom, sOOTDir, NULL, 0)) + return AVS_FILEUTILS_ERROR_CONVERT; + + return func(sOOTFileEditor, sTo, params, convertParams); + } + + // convert ooxml format to another ooxml format + // 1) create temp directory with name prefix + // 2) extract sFrom format to directory [1] + // 3) convert to ooxml format with func method + // 4) compress ooxml format to archive + // example: docm => docx + _UINT32 ooxml2ooxml(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams, + const std::wstring& prefix, CONVERT_FUNC func) + { + std::wstring sUnpackedResult = combinePath(convertParams.m_sTempDir, prefix + L"_unpacked"); + NSDirectory::CreateDirectory(sUnpackedResult); + + _UINT32 nRes = func(sFrom, sUnpackedResult, params, convertParams); + if (SUCCEEDED_X2T(nRes)) + { + COfficeUtils oCOfficeUtils(NULL); + nRes = (S_OK == oCOfficeUtils.CompressFileOrDirectory(sUnpackedResult, sTo, true)) ? 0 : AVS_FILEUTILS_ERROR_CONVERT; + } + return nRes; + } + + // extract zip file to folder and replace content type + _UINT32 ooxml2ooxml_replace_content_type(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams, + const std::wstring& sSourceCT, const std::wstring& sDestCT) + { + COfficeUtils oCOfficeUtils(NULL); + if (S_OK == oCOfficeUtils.ExtractToDirectory(sFrom, sTo, NULL, 0)) + { + std::wstring sContentTypesPath = combinePath(sTo, L"[Content_Types].xml"); + if (NSFile::CFileBinary::Exists(sContentTypesPath)) + { + std::wstring sData; + if (NSFile::CFileBinary::ReadAllTextUtf8(sContentTypesPath, sData)) + { + sData = string_replaceAll(sData, sSourceCT, sDestCT); + if (NSFile::CFileBinary::SaveToFile(sContentTypesPath, sData, true)) + return 0; + } + } + } + return AVS_FILEUTILS_ERROR_CONVERT; + } + + // remove macroses from ooxml directory + // differences: main/template/show, document/sheet/slide + _UINT32 ooxmlm_dir2ooxml_dir(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams, + const OOXML_DOCUMENT_TYPE& type, const OOXML_DOCUMENT_SUBTYPE& documentType) + { + std::wstring sFolder = L""; + std::wstring sMainFile = L""; + if (OOXML_DOCUMENT_TYPE::Word == type) + { + sFolder = L"word"; + sMainFile = L"document"; + } + else if (OOXML_DOCUMENT_TYPE::Sheet == type) + { + sFolder = L"xl"; + sMainFile = L"workbook"; + } + else if (OOXML_DOCUMENT_TYPE::Slide == type) + { + sFolder = L"ppt"; + sMainFile = L"presentation"; + } + + if (sFolder.empty()) + return AVS_FILEUTILS_ERROR_CONVERT; + + std::wstring sContentTypesPath = combinePath(sTo, L"[Content_Types].xml"); + if (NSFile::CFileBinary::Exists(sContentTypesPath)) + { + std::wstring sData; + if (NSFile::CFileBinary::ReadAllTextUtf8(sContentTypesPath, sData)) + { + std::wstring sCTFrom = L""; + std::wstring sCTTo = L""; + + if (OOXML_DOCUMENT_TYPE::Word == type) + { + if (OOXML_DOCUMENT_SUBTYPE::Main == documentType) + { + sCTFrom = L"application/vnd.ms-word.document.macroEnabled.main+xml"; + sCTTo = L"application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"; + } + else + { + sCTFrom = L"application/vnd.ms-word.template.macroEnabledTemplate.main+xml"; + sCTTo = L"application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"; + } + } + else if (OOXML_DOCUMENT_TYPE::Sheet == type) + { + if (OOXML_DOCUMENT_SUBTYPE::Main == documentType) + { + sCTFrom = L"application/vnd.ms-excel.sheet.macroEnabled.main+xml"; + sCTTo = L"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml"; + } + else + { + sCTFrom = L"application/vnd.ms-excel.template.macroEnabled.main+xml"; + sCTTo = L"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml"; + } + } + else if (OOXML_DOCUMENT_TYPE::Slide == type) + { + if (OOXML_DOCUMENT_SUBTYPE::Main == documentType) + { + sCTFrom = _T("application/vnd.ms-powerpoint.presentation.macroEnabled.main+xml"); + sCTTo = _T("application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml"); + } + else if (OOXML_DOCUMENT_SUBTYPE::Template == documentType) + { + sCTFrom = L"application/vnd.ms-powerpoint.template.macroEnabled.main+xml"; + sCTTo = L"application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml"; + } + else + { + sCTFrom = L"application/vnd.ms-powerpoint.slideshow.macroEnabled.main+xml"; + sCTTo = L"application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml"; + } + } + + sData = string_replaceAll(sData, sCTFrom, sCTTo); + + sCTFrom = L""; + sData = string_replaceAll(sData, sCTFrom, L""); + + sCTFrom = L""; + sData = string_replaceAll(sData, sCTFrom, L""); + + sCTFrom = L""; + sData = string_replaceAll(sData, sCTFrom, L""); + + if (NSFile::CFileBinary::SaveToFile(sContentTypesPath, sData, true) == false) + return AVS_FILEUTILS_ERROR_CONVERT; + } + } + std::wstring sDocumentRelsPath = sTo + FILE_SEPARATOR_STR + sFolder + FILE_SEPARATOR_STR + L"_rels" + FILE_SEPARATOR_STR + sMainFile + L".xml.rels"; + if (NSFile::CFileBinary::Exists(sDocumentRelsPath)) + { + std::wstring sData; + if (NSFile::CFileBinary::ReadAllTextUtf8(sDocumentRelsPath, sData)) + { + size_t pos = sData.find(L"vbaProject.bin"); + if (pos != std::wstring::npos) + { + size_t pos1 = sData.rfind(L"<", pos); + size_t pos2 = sData.find(L">", pos); + + if (pos1 != std::wstring::npos && pos2 != std::wstring::npos) + { + sData.erase(sData.begin() + pos1, sData.begin() + pos2 + 1); + } + } + if (NSFile::CFileBinary::SaveToFile(sDocumentRelsPath, sData, true) == false) + return AVS_FILEUTILS_ERROR_CONVERT; + } + } + std::wstring sVbaProjectPath = sTo + FILE_SEPARATOR_STR + sFolder + FILE_SEPARATOR_STR + L"vbaProject.bin"; + NSFile::CFileBinary::Remove(sVbaProjectPath); + + std::wstring sVbaProjectRelsPath = sTo + FILE_SEPARATOR_STR + sFolder + FILE_SEPARATOR_STR + L"_rels" + FILE_SEPARATOR_STR + L"vbaProject.bin.rels"; + NSFile::CFileBinary::Remove(sVbaProjectRelsPath); + + std::wstring sVbaDataPath = sTo + FILE_SEPARATOR_STR + sFolder + FILE_SEPARATOR_STR + L"vbaData.xml"; + NSFile::CFileBinary::Remove(sVbaDataPath); + return 0; + } + + // extract ooxml file with macroses to folder and remove macroses + _UINT32 ooxmlm2ooml_dir(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams, + const OOXML_DOCUMENT_TYPE& type, const OOXML_DOCUMENT_SUBTYPE& documentType) + { + COfficeUtils oCOfficeUtils(NULL); + if (S_OK == oCOfficeUtils.ExtractToDirectory(sFrom, sTo, NULL, 0)) + { + return ooxmlm_dir2ooxml_dir(sFrom, sTo, params, convertParams, type, documentType); + } + return 0; + } + + // convert any format to ooxml format + // 1) create temp directory with name prefix + // 2) convert to ooxml directory [1] with funcDir method + // 3) compress to ooxml format and encrypt it if needed + _UINT32 format2ooxml(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams, + const std::wstring& prefix, CONVERT_FUNC func2dir, bool bIsCrypt = true) + { + std::wstring sOOXMLDir = combinePath(convertParams.m_sTempDir, prefix + L"_unpacked"); + NSDirectory::CreateDirectory(sOOXMLDir); + + _UINT32 hRes = func2dir(sFrom, sOOXMLDir, params, convertParams); + + if (SUCCEEDED_X2T(hRes)) + { + if (bIsCrypt) + { + _UINT32 hRes2 = dir2zipMscrypt(sOOXMLDir, sTo, params, convertParams); + hRes = (hRes2 == 0 ? hRes : hRes2); + } + else + { + COfficeUtils oCOfficeUtils(NULL); + hRes = (S_OK == oCOfficeUtils.CompressFileOrDirectory(sOOXMLDir, sTo, false)) ? 0 : AVS_FILEUTILS_ERROR_CONVERT; + } + } + else if (AVS_ERROR_DRM == hRes) + { + if (!params.getDontSaveAdditional()) + { + copyOrigin(sFrom, *params.m_sFileTo); + } + return AVS_FILEUTILS_ERROR_CONVERT_DRM; + } + else if (AVS_ERROR_PASSWORD == hRes) + { + return AVS_FILEUTILS_ERROR_CONVERT_PASSWORD; + } + return hRes; + } + + // convert ooxml file to any format + // 1) create temp directory with name prefix + // 2) extract ooxml to directory [1] + // 3) convert directory to any format with func_dir2format method + _UINT32 ooxml2format(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams, + const std::wstring& prefix, CONVERT_FUNC func_dir2format) + { + std::wstring sOOXMLDir = combinePath(convertParams.m_sTempDir, prefix + L"_unpacked"); + NSDirectory::CreateDirectory(sOOXMLDir); + + COfficeUtils oCOfficeUtils(NULL); + if (S_OK == oCOfficeUtils.ExtractToDirectory(sFrom, sOOXMLDir, NULL, 0)) + { + return func_dir2format(sOOXMLDir, sTo, params, convertParams); + } + return AVS_FILEUTILS_ERROR_CONVERT; + } + } +} diff --git a/X2tConverter/src/lib/crypt.h b/X2tConverter/src/lib/crypt.h new file mode 100644 index 00000000000..0cb92a794c4 --- /dev/null +++ b/X2tConverter/src/lib/crypt.h @@ -0,0 +1,244 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#pragma once + +#include "../../../OfficeCryptReader/source/ECMACryptFile.h" +#include "common.h" + +namespace NExtractTools +{ + _UINT32 mscrypt2oot(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + std::wstring sResultOotDir = combinePath(convertParams.m_sTempDir, L"oot_unpacked"); + std::wstring sResultOotFileEditor = combinePath(sResultOotDir, L"Editor.bin"); + NSDirectory::CreateDirectory(sResultOotDir); + + _UINT32 nRes = mscrypt2oot_bin(sFrom, sResultOotFileEditor, params, convertParams); + if (SUCCEEDED_X2T(nRes)) + { + COfficeUtils oCOfficeUtils(NULL); + nRes = (S_OK == oCOfficeUtils.CompressFileOrDirectory(sResultOotDir, sTo)) ? nRes : AVS_FILEUTILS_ERROR_CONVERT; + } + + return nRes; + } + _UINT32 mscrypt2oot_bin(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + //decrypt to temp file + std::wstring password = params.getPassword(); + std::wstring sResultDecryptFile = combinePath(convertParams.m_sTempDir, L"uncrypt_file.oox"); + + ECMACryptFile cryptReader; + bool bDataIntegrity = false; + + if (cryptReader.DecryptOfficeFile(sFrom, sResultDecryptFile, password, bDataIntegrity) == false) + { + if (password.empty()) + return AVS_FILEUTILS_ERROR_CONVERT_DRM; + else + return AVS_FILEUTILS_ERROR_CONVERT_PASSWORD; + } + + if (bDataIntegrity == false) + { + // было несанкционированое вешательство в файл + } + + COfficeFileFormatChecker OfficeFileFormatChecker; + + if (OfficeFileFormatChecker.isOfficeFile(sResultDecryptFile)) + { + switch (OfficeFileFormatChecker.nFileType) + { + case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX: + case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCM: + case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOTX: + case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOTM: + case AVS_OFFICESTUDIO_FILE_DOCUMENT_OFORM: + case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCXF: + { + return docx2doct_bin(sResultDecryptFile, sTo, params, convertParams); + } + break; + case AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSX: + case AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSM: + case AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLTX: + case AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLTM: + case AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSB: + { + const std::wstring &sXmlOptions = params.getXmlOptions(); + return xlsx2xlst_bin(sResultDecryptFile, sTo, params, convertParams); + } + break; + case AVS_OFFICESTUDIO_FILE_PRESENTATION_PPTX: + case AVS_OFFICESTUDIO_FILE_PRESENTATION_PPTM: + case AVS_OFFICESTUDIO_FILE_PRESENTATION_PPSX: + case AVS_OFFICESTUDIO_FILE_PRESENTATION_POTX: + case AVS_OFFICESTUDIO_FILE_PRESENTATION_POTM: + case AVS_OFFICESTUDIO_FILE_PRESENTATION_PPSM: + { + return pptx2pptt_bin(sResultDecryptFile, sTo, params, convertParams); + } + break; + case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX_FLAT: + { + return docxflat2doct_bin(sResultDecryptFile, sTo, params, convertParams); + } + break; + case AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSX_FLAT: + { + const std::wstring &sXmlOptions = params.getXmlOptions(); + return xlsxflat2xlst_bin(sResultDecryptFile, sTo, params, convertParams); + } + break; + case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX_PACKAGE: + case AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSX_PACKAGE: + case AVS_OFFICESTUDIO_FILE_PRESENTATION_PPTX_PACKAGE: + { + return package2bin(sResultDecryptFile, sTo, params, convertParams); + } + break; + } + } + return AVS_FILEUTILS_ERROR_CONVERT; + } + _UINT32 mitcrypt2oox(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + // todo + return AVS_FILEUTILS_ERROR_CONVERT_DRM_UNSUPPORTED; + } + _UINT32 mitcrypt2oot_bin(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + // todo + return AVS_FILEUTILS_ERROR_CONVERT_DRM_UNSUPPORTED; + } + _UINT32 mscrypt2oox(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + std::wstring password = params.getPassword(); + + ECMACryptFile cryptReader; + bool bDataIntegrity = false; + + if (cryptReader.DecryptOfficeFile(sFrom, sTo, password, bDataIntegrity) == false) + { + if (password.empty()) + return AVS_FILEUTILS_ERROR_CONVERT_DRM; + else + return AVS_FILEUTILS_ERROR_CONVERT_PASSWORD; + } + + if (bDataIntegrity == false) + { + // было несанкционированое вешательство в файл + } + + return 0; + } + _UINT32 oox2mscrypt(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + std::wstring password = params.getSavePassword(); + std::wstring documentID = params.getDocumentID(); + + ECMACryptFile cryptReader; + + if (cryptReader.EncryptOfficeFile(sFrom, sTo, password, documentID) == false) + { + return AVS_FILEUTILS_ERROR_CONVERT; + } + + return 0; + } + _UINT32 fromMscrypt(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + std::wstring password = params.getPassword(); + std::wstring sResultDecryptFile = combinePath(convertParams.m_sTempDir, L"uncrypt_file.oox"); + + _UINT32 nRes = mscrypt2oox(sFrom, sResultDecryptFile, params, convertParams); + + if (!SUCCEEDED_X2T(nRes) && password.empty()) // qiaoshemei1 (1).xlsx - запрокченный xlsx + { + if (!params.getDontSaveAdditional()) + { + copyOrigin(sFrom, sTo); + } + return AVS_FILEUTILS_ERROR_CONVERT_DRM; + } + nRes = processEncryptionError(nRes, sFrom, params); + if (SUCCEEDED_X2T(nRes)) + { + COfficeFileFormatChecker OfficeFileFormatChecker; + + if (OfficeFileFormatChecker.isOfficeFile(sResultDecryptFile)) + { + params.changeFormatFromPrev(OfficeFileFormatChecker.nFileType); + switch (OfficeFileFormatChecker.nFileType) + { + case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX: + case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCM: + case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOTX: + case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOTM: + case AVS_OFFICESTUDIO_FILE_DOCUMENT_OFORM: + case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCXF: + { + return fromDocument(sResultDecryptFile, AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX, params, convertParams); + } + break; + case AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSX: + case AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSM: + case AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLTX: + case AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLTM: + case AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSB: + { + return fromSpreadsheet(sResultDecryptFile, AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSX, params, convertParams); + } + break; + case AVS_OFFICESTUDIO_FILE_PRESENTATION_PPTX: + case AVS_OFFICESTUDIO_FILE_PRESENTATION_PPTM: + case AVS_OFFICESTUDIO_FILE_PRESENTATION_PPSX: + case AVS_OFFICESTUDIO_FILE_PRESENTATION_POTX: + case AVS_OFFICESTUDIO_FILE_PRESENTATION_POTM: + case AVS_OFFICESTUDIO_FILE_PRESENTATION_PPSM: + { + return fromPresentation(sResultDecryptFile, AVS_OFFICESTUDIO_FILE_PRESENTATION_PPTX, params, convertParams); + } + break; + } + } + } + return nRes; + } + _UINT32 fromMitcrypt(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + // todo + return AVS_FILEUTILS_ERROR_CONVERT_DRM_UNSUPPORTED; + } +} diff --git a/X2tConverter/src/lib/csv.h b/X2tConverter/src/lib/csv.h new file mode 100644 index 00000000000..c86f7d9c8ea --- /dev/null +++ b/X2tConverter/src/lib/csv.h @@ -0,0 +1,193 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#pragma once + +#include "../../../OOXML/Binary/Sheets/Common/Common.h" +#include "../../../OOXML/Binary/Sheets/Reader/CSVReader.h" +#include "../../../OOXML/XlsxFormat/Xlsx.h" +#include "../../../OOXML/Binary/Document/DocWrapper/XlsxSerializer.h" +#include "common.h" + +namespace NExtractTools +{ + _UINT32 csv2xlsx_dir(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + params.m_bMacro = false; + + OOX::Spreadsheet::CXlsx oXlsx; + + BYTE fileType; + UINT nCodePage; + std::wstring sDelimiter; + BYTE saveFileType; + _INT32 lcid = -1; + + SerializeCommon::ReadFileType(params.getXmlOptions(), fileType, nCodePage, sDelimiter, saveFileType, lcid); + + CSVReader csvReader; + _UINT32 nRes = csvReader.Read(sFrom, oXlsx, nCodePage, sDelimiter, lcid); + + if (SUCCEEDED_X2T(nRes)) + { + oXlsx.PrepareToWrite(); + + OOX::CContentTypes oContentTypes; + nRes = oXlsx.Write(sTo, oContentTypes) ? nRes : AVS_FILEUTILS_ERROR_CONVERT; + } + + return nRes; + } + _UINT32 xlsx_dir2csv(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + std::wstring sResultXlstDir = combinePath(convertParams.m_sTempDir, L"xlst_unpacked"); + std::wstring sResultXlstFileEditor = combinePath(sResultXlstDir, L"Editor.bin"); + + NSDirectory::CreateDirectory(sResultXlstDir); + + BinXlsxRW::CXlsxSerializer oCXlsxSerializer; + + oCXlsxSerializer.setIsNoBase64(params.getIsNoBase64()); + oCXlsxSerializer.setFontDir(params.getFontPath()); + + std::wstring sXMLOptions = _T(""); + _UINT32 nRes = oCXlsxSerializer.saveToFile(sResultXlstFileEditor, sFrom, sXMLOptions); + if (SUCCEEDED_X2T(nRes)) + { + std::wstring sMediaPath; + std::wstring sEmbedPath; + if(!params.m_nFormatTo) + { + params.m_nFormatTo = new int; + *params.m_nFormatTo = AVS_OFFICESTUDIO_FILE_SPREADSHEET_CSV; + } + sXMLOptions = params.getXmlOptions();//_T(""); + + nRes = oCXlsxSerializer.loadFromFile(sResultXlstFileEditor, sTo, sXMLOptions, sMediaPath, sEmbedPath); + } + + return nRes; + } + + _UINT32 csv2xlst_bin(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + params.m_bMacro = false; + + // Save to file (from temp dir) + BinXlsxRW::CXlsxSerializer oCXlsxSerializer; + + oCXlsxSerializer.setIsNoBase64(params.getIsNoBase64()); + oCXlsxSerializer.setFontDir(params.getFontPath()); + + if (!params.m_nFormatFrom) + params.m_nFormatFrom = new int(AVS_OFFICESTUDIO_FILE_UNKNOWN); + if (AVS_OFFICESTUDIO_FILE_UNKNOWN == *params.m_nFormatFrom) + *params.m_nFormatFrom = AVS_OFFICESTUDIO_FILE_SPREADSHEET_CSV; + + return oCXlsxSerializer.saveToFile(sTo, sFrom, params.getXmlOptions()); + } + _UINT32 xlst_bin2csv(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + _UINT32 nRes = 0; + + std::wstring sTargetBin; + if (params.getFromChanges()) + { + params.setFromChanges(false); + nRes = apply_changes(sFrom, sTo, NSDoctRenderer::DoctRendererFormat::FormatFile::XLST, sTargetBin, params, convertParams); + } + else + sTargetBin = sFrom; + + if (SUCCEEDED_X2T(nRes)) + { + BinXlsxRW::CXlsxSerializer oCXlsxSerializer; + + oCXlsxSerializer.setIsNoBase64(params.getIsNoBase64()); + oCXlsxSerializer.setFontDir(params.getFontPath()); + + std::wstring sResultCsvDir = combinePath(convertParams.m_sTempDir, L"csv_unpacked"); + + NSDirectory::CreateDirectory(sResultCsvDir); + std::wstring sMediaPath; // will be filled by 'CreateXlsxFolders' method + std::wstring sEmbedPath; // will be filled by 'CreateXlsxFolders' method + std::wstring sXmlOptions = params.getXmlOptions(); + + oCXlsxSerializer.CreateXlsxFolders(sXmlOptions, sResultCsvDir, sMediaPath, sEmbedPath); + + nRes = oCXlsxSerializer.loadFromFile(sTargetBin, sTo, sXmlOptions, sMediaPath, sEmbedPath); + } + // удаляем EditorWithChanges, потому что он не в Temp + if (sFrom != sTargetBin) + NSFile::CFileBinary::Remove(sTargetBin); + return nRes; + } + + _UINT32 xlsx2csv(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return NSCommon::ooxml2format(sFrom, sTo, params, convertParams, L"xlsx", xlsx_dir2csv); + } + _UINT32 csv2xlsx(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return NSCommon::format2ooxml(sFrom, sTo, params, convertParams, L"xlsx", csv2xlsx_dir); + } + + _UINT32 csv2xlst(const std::wstring &sFrom, const std::wstring &sTo, InputParams& params, ConvertParams& convertParams) + { + return NSCommon::format2oot(sFrom, sTo, params, convertParams, L"xlst", csv2xlst_bin); + } + // TODO: return NSCommon::oot2format(sFrom, sTo, params, convertParams, L"doct", doct_bin2rtf); + _UINT32 xlst2csv(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + std::wstring sCSV = sTo; + std::wstring sTempUnpackedXLST = combinePath(convertParams.m_sTempDir, L"xlst_unpacked"); + std::wstring sTempXlstFileEditor = combinePath(sTempUnpackedXLST, L"Editor.bin"); + NSDirectory::CreateDirectory(sTempUnpackedXLST); + + // unzip xlst to folder + COfficeUtils oCOfficeUtils(NULL); + if (S_OK != oCOfficeUtils.ExtractToDirectory(sFrom, sTempUnpackedXLST, NULL, 0)) + return AVS_FILEUTILS_ERROR_CONVERT; + + BinXlsxRW::CXlsxSerializer oCXlsxSerializer; + + oCXlsxSerializer.setIsNoBase64(params.getIsNoBase64()); + oCXlsxSerializer.setFontDir(params.getFontPath()); + oCXlsxSerializer.setTempDir(convertParams.m_sTempDir); + + std::wstring sMediaPath; + std::wstring sEmbedPath; + + params.m_nFormatTo = new int(AVS_OFFICESTUDIO_FILE_SPREADSHEET_CSV); + + return oCXlsxSerializer.loadFromFile(sTempXlstFileEditor, sCSV, params.getXmlOptions(), sMediaPath, sEmbedPath); + } +} diff --git a/X2tConverter/src/lib/doc.h b/X2tConverter/src/lib/doc.h new file mode 100644 index 00000000000..2a1ae5256c1 --- /dev/null +++ b/X2tConverter/src/lib/doc.h @@ -0,0 +1,136 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#pragma once + +#include "../../../MsBinaryFile/DocFile/Main/DocFormatLib.h" +#include "../../../OOXML/Binary/Document/DocWrapper/DocxSerializer.h" +#include "common.h" + +#ifdef CreateDirectory +#undef CreateDirectory +#endif + +namespace NExtractTools +{ + _UINT32 doc2docx_dir(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + COfficeDocFile docFile; + + docFile.m_sTempFolder = convertParams.m_sTempDir; + docFile.m_nUserLCID = (NULL != params.m_nLcid) ? *params.m_nLcid : -1; + + params.m_bMacro = false; + _UINT32 hRes = docFile.LoadFromFile(sFrom, sTo, params.getPassword(), params.m_bMacro); + + if (AVS_ERROR_DRM == hRes) + { + if (!params.getDontSaveAdditional()) + { + copyOrigin(sFrom, *params.m_sFileTo); + } + return AVS_FILEUTILS_ERROR_CONVERT_DRM; + } + else if (AVS_ERROR_PASSWORD == hRes) + { + return AVS_FILEUTILS_ERROR_CONVERT_PASSWORD; + } + return 0 == hRes ? 0 : AVS_FILEUTILS_ERROR_CONVERT; + } + _UINT32 docx_dir2doc(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return AVS_FILEUTILS_ERROR_CONVERT; + } + + _UINT32 doc2doct_bin(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + std::wstring sResultDocxDir = combinePath(convertParams.m_sTempDir, L"docx_unpacked"); + NSDirectory::CreateDirectory(sResultDocxDir); + + COfficeDocFile docFile; + docFile.m_sTempFolder = convertParams.m_sTempDir; + docFile.m_nUserLCID = (NULL != params.m_nLcid) ? *params.m_nLcid : -1; + + params.m_bMacro = true; + + _UINT32 nRes = docFile.LoadFromFile(sFrom, sResultDocxDir, params.getPassword(), params.m_bMacro); + + nRes = processEncryptionError(nRes, sFrom, params); + if (SUCCEEDED_X2T(nRes)) + { + BinDocxRW::CDocxSerializer m_oCDocxSerializer; + + m_oCDocxSerializer.setFontDir(params.getFontPath()); + + std::wstring xml_options = params.getXmlOptions(); + + nRes = m_oCDocxSerializer.saveToFile (sTo, sResultDocxDir, xml_options, convertParams.m_sTempDir) ? 0 : AVS_FILEUTILS_ERROR_CONVERT; + } + return nRes; + } + + _UINT32 doc2docm_dir(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + COfficeDocFile docFile; + docFile.m_sTempFolder = convertParams.m_sTempDir; + docFile.m_nUserLCID = (NULL != params.m_nLcid) ? *params.m_nLcid : -1; + + params.m_bMacro = true; + + _UINT32 hRes = docFile.LoadFromFile(sFrom, sTo, params.getPassword(), params.m_bMacro); + if (AVS_ERROR_DRM == hRes) + { + if (!params.getDontSaveAdditional()) + { + copyOrigin(sFrom, *params.m_sFileTo); + } + hRes = AVS_FILEUTILS_ERROR_CONVERT_DRM; + } + else if (AVS_ERROR_PASSWORD == hRes) + { + hRes = AVS_FILEUTILS_ERROR_CONVERT_PASSWORD; + } + return hRes; + } + + _UINT32 doc2docx(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return NSCommon::format2ooxml(sFrom, sTo, params, convertParams, L"docx", doc2docx_dir); + } + _UINT32 doc2doct(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return NSCommon::format2oot(sFrom, sTo, params, convertParams, L"doct", doc2doct_bin); + } + _UINT32 doc2docm(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return NSCommon::format2ooxml(sFrom, sTo, params, convertParams, L"docx", doc2docx_dir, false); + } +} diff --git a/X2tConverter/src/lib/docx.h b/X2tConverter/src/lib/docx.h new file mode 100644 index 00000000000..224935cdfce --- /dev/null +++ b/X2tConverter/src/lib/docx.h @@ -0,0 +1,339 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#pragma once + +#include "../../../OOXML/Binary/Document/DocWrapper/DocxSerializer.h" +#include "common.h" + +namespace NExtractTools +{ + // docx <=> doct + _UINT32 docx2doct_bin(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + std::wstring sTempUnpackedDOCX = combinePath(convertParams.m_sTempDir, L"docx_unpacked"); + NSDirectory::CreateDirectory(sTempUnpackedDOCX); + + COfficeUtils oCOfficeUtils(NULL); + if (S_OK != oCOfficeUtils.ExtractToDirectory(sFrom, sTempUnpackedDOCX, NULL, 0)) + { + // check crypt + COfficeFileFormatChecker OfficeFileFormatChecker; + if (OfficeFileFormatChecker.isOfficeFile(sFrom)) + { + if (OfficeFileFormatChecker.nFileType == AVS_OFFICESTUDIO_FILE_OTHER_MS_OFFCRYPTO) + return mscrypt2oot_bin(sFrom, sTo, params, convertParams); + else if (OfficeFileFormatChecker.nFileType == AVS_OFFICESTUDIO_FILE_OTHER_MS_MITCRYPTO) + return mitcrypt2oot_bin(sFrom, sTo, params, convertParams); + else + { + if (create_if_empty(sFrom, sTo, L"DOCY;v10;0;")) + return 0; + } + // zip currupt ... check for empty dir output ????? + if (NSDirectory::GetFilesCount(sTempUnpackedDOCX, true) < 4) + return AVS_FILEUTILS_ERROR_CONVERT; + } + else + return AVS_FILEUTILS_ERROR_CONVERT; + } + + convertParams.m_sTempParamOOXMLFile = sFrom; + return docx_dir2doct_bin(sTempUnpackedDOCX, sTo, params, convertParams); + } + _UINT32 docx_dir2doct_bin(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + _UINT32 nRes = S_OK; + if (params.needConvertToOrigin(AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX) && !convertParams.m_sTempParamOOXMLFile.empty()) + { + std::wstring sToDir = NSDirectory::GetFolderPath(sTo); + nRes = CopyOOXOrigin(sToDir, sFrom, L"origin.docx", convertParams.m_sTempParamOOXMLFile); + } + else + { + // Save to file (from temp dir) + BinDocxRW::CDocxSerializer m_oCDocxSerializer; + + m_oCDocxSerializer.setIsNoBase64(params.getIsNoBase64()); + m_oCDocxSerializer.setFontDir(params.getFontPath()); + + // bool bRes = m_oCDocxSerializer.saveToFile (sResDoct, sSrcDocx, sTemp); + nRes = m_oCDocxSerializer.saveToFile(sTo, sFrom, params.getXmlOptions(), convertParams.m_sTempDir) ? 0 : AVS_FILEUTILS_ERROR_CONVERT; + } + // clear tmp param for this method + convertParams.m_sTempParamOOXMLFile = L""; + return nRes; + } + _UINT32 docx2doct(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return NSCommon::format2oot(sFrom, sTo, params, convertParams, L"doct", docx2doct_bin); + } + _UINT32 docx_dir2doct(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return NSCommon::format2oot(sFrom, sTo, params, convertParams, L"doct", docx_dir2doct_bin); + } + _UINT32 doct_bin2docx(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + std::wstring sResultDocxDir = combinePath(convertParams.m_sTempDir, L"docx_unpacked"); + NSDirectory::CreateDirectory(sResultDocxDir); + + convertParams.m_sTempResultOOXMLDirectory = sResultDocxDir; + _UINT32 nRes = doct_bin2docx_dir(sFrom, sTo, params, convertParams); + + if (SUCCEEDED_X2T(nRes) && params.m_nFormatTo) + { + if (AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCM == *params.m_nFormatTo || + AVS_OFFICESTUDIO_FILE_DOCUMENT_DOTX == *params.m_nFormatTo || + AVS_OFFICESTUDIO_FILE_DOCUMENT_DOTM == *params.m_nFormatTo) + { + std::wstring sCTFrom = _T("application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"); + std::wstring sCTTo; + switch (*params.m_nFormatTo) + { + case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCM: + sCTTo = _T("application/vnd.ms-word.document.macroEnabled.main+xml"); + break; + case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOTX: + sCTTo = _T("application/vnd.openxmlformats-officedocument.wordprocessingml.template.main+xml"); + break; + case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOTM: + sCTTo = _T("application/vnd.ms-word.template.macroEnabledTemplate.main+xml"); + break; + } + nRes = replaceContentType(sResultDocxDir, sCTFrom, sCTTo); + } + else if (AVS_OFFICESTUDIO_FILE_DOCUMENT_OFORM == *params.m_nFormatTo) + { + // std::wstring sCT = L""; + // nRes = addContentType(sResultDocxDir, sCT); + } + else if (AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCXF == *params.m_nFormatTo) + { + // std::wstring sCT = L""; + // nRes = addContentType(sResultDocxDir, sCT); + } + } + if (SUCCEEDED_X2T(nRes)) + { + nRes = dir2zipMscrypt(sResultDocxDir, sTo, params, convertParams); + } + + return nRes; + } + _UINT32 doct_bin2docx_dir(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + _UINT32 nRes = 0; + std::wstring sTargetBin; + if (params.getFromChanges()) + { + params.setFromChanges(false); + nRes = apply_changes(sFrom, sTo, NSDoctRenderer::DoctRendererFormat::FormatFile::DOCT, sTargetBin, params, convertParams); + } + else + sTargetBin = sFrom; + + BinDocxRW::CDocxSerializer m_oCDocxSerializer; + + m_oCDocxSerializer.setOFormEnabled(params.m_nFormatTo && + (*params.m_nFormatTo == AVS_OFFICESTUDIO_FILE_DOCUMENT_OFORM || + *params.m_nFormatTo == AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCXF || + *params.m_nFormatTo == AVS_OFFICESTUDIO_FILE_DOCUMENT_OFORM_PDF)); + m_oCDocxSerializer.setMacroEnabled(params.m_bMacro); + m_oCDocxSerializer.setIsNoBase64(params.getIsNoBase64()); + m_oCDocxSerializer.setFontDir(params.getFontPath()); + + std::wstring sXmlOptions; + std::wstring sThemePath; // will be filled by 'CreateDocxFolders' method + std::wstring sMediaPath; // will be filled by 'CreateDocxFolders' method + std::wstring sEmbedPath; // will be filled by 'CreateDocxFolders' method + + m_oCDocxSerializer.CreateDocxFolders(convertParams.m_sTempResultOOXMLDirectory, sThemePath, sMediaPath, sEmbedPath); + + if (SUCCEEDED_X2T(nRes)) + { + nRes = m_oCDocxSerializer.loadFromFile(sTargetBin, convertParams.m_sTempResultOOXMLDirectory, sXmlOptions, sThemePath, sMediaPath, sEmbedPath) ? nRes : AVS_FILEUTILS_ERROR_CONVERT; + params.m_bMacro = m_oCDocxSerializer.getMacroEnabled(); + } + // удаляем EditorWithChanges, потому что он не в Temp + if (sFrom != sTargetBin) + NSFile::CFileBinary::Remove(sTargetBin); + + convertParams.m_sTempResultOOXMLDirectory = L""; + return nRes; + } + _UINT32 doct2docx(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return NSCommon::oot2format(sFrom, sTo, params, convertParams, L"doct", doct_bin2docx); + } + + // docx flat + _UINT32 docxflat2doct(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return NSCommon::format2oot(sFrom, sTo, params, convertParams, L"doct", docxflat2doct_bin); + } + _UINT32 docxflat2doct_bin(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + // Save to file (from temp dir) + BinDocxRW::CDocxSerializer m_oCDocxSerializer; + + m_oCDocxSerializer.setIsNoBase64(params.getIsNoBase64()); + m_oCDocxSerializer.setFontDir(params.getFontPath()); + + _UINT32 nRes = m_oCDocxSerializer.saveToFile(sTo, sFrom, params.getXmlOptions(), convertParams.m_sTempDir) ? 0 : AVS_FILEUTILS_ERROR_CONVERT; + + return nRes; + } + + _UINT32 docxflat2docx(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + std::wstring sTempUnpackedDOCX = combinePath(convertParams.m_sTempDir, L"docx_unpacked"); + NSDirectory::CreateDirectory(sTempUnpackedDOCX); + + BinDocxRW::CDocxSerializer m_oCDocxSerializer; + + _UINT32 nRes = 0; + if (m_oCDocxSerializer.convertFlat(sFrom, sTempUnpackedDOCX, params.m_bMacro, convertParams.m_sTempDir)) + { + params.changeFormatFromPost(*params.m_nFormatFrom, params.m_bMacro); + nRes = dir2zipMscrypt(sTempUnpackedDOCX, *params.m_sFileTo, params, convertParams); + } + else + { + nRes = AVS_FILEUTILS_ERROR_CONVERT; + } + return nRes; + } + + // packageooxml + _UINT32 package2ooxml(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return NSCommon::format2ooxml(sFrom, sTo, params, convertParams, L"ooxml", package2ooxml_dir); + } + _UINT32 package2bin_t(const std::wstring &sFrom, const std::wstring &sTo, InputParams ¶ms, ConvertParams& convertParams) + { + return NSCommon::format2oot(sFrom, sTo, params, convertParams, L"bin_t", package2bin); + } + _UINT32 package2bin(const std::wstring &sFrom, const std::wstring &sTo, InputParams ¶ms, ConvertParams& convertParams) + { + std::wstring sResultOoxmlDir = combinePath(convertParams.m_sTempDir, L"ooxml_unpacked"); + NSDirectory::CreateDirectory(sResultOoxmlDir); + + _UINT32 nRes = package2ooxml_dir(sFrom, sResultOoxmlDir, params, convertParams); + + if (SUCCEEDED_X2T(nRes)) + { + nRes = AVS_FILEUTILS_ERROR_CONVERT; + + COfficeFileFormatChecker OfficeFileFormatChecker; + + if (OfficeFileFormatChecker.isOOXFormatFile(sResultOoxmlDir, true)) + { + switch (OfficeFileFormatChecker.nFileType) + { + case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX: + case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCM: + case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOTX: + case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOTM: + nRes = docx_dir2doct_bin(sResultOoxmlDir, sTo, params, convertParams); + break; + case AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSX: + case AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSM: + case AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLTX: + case AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLTM: + + case AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSB: + convertParams.m_bTempIsXmlOptions = true; + nRes = xlsx_dir2xlst_bin(sResultOoxmlDir, sTo, params, convertParams); + break; + case AVS_OFFICESTUDIO_FILE_PRESENTATION_PPTX: + case AVS_OFFICESTUDIO_FILE_PRESENTATION_PPTM: + case AVS_OFFICESTUDIO_FILE_PRESENTATION_PPSX: + case AVS_OFFICESTUDIO_FILE_PRESENTATION_POTX: + case AVS_OFFICESTUDIO_FILE_PRESENTATION_POTM: + case AVS_OFFICESTUDIO_FILE_PRESENTATION_PPSM: + nRes = pptx_dir2pptt_bin(sResultOoxmlDir, sTo, params, convertParams); + break; + default: + break; + } + } + } + + return nRes; + } + _UINT32 package2ooxml_dir(const std::wstring &sFrom, const std::wstring &sTo, InputParams ¶ms, ConvertParams& convertParams) + { + params.m_bMacro = false; + + BinDocxRW::CDocxSerializer m_oCDocxSerializer; + _UINT32 nRes = m_oCDocxSerializer.unpackageFile(sFrom, sTo) ? 0 : AVS_FILEUTILS_ERROR_CONVERT; + + return nRes; + } + + // docm/dotx + _UINT32 dotm2docm(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return NSCommon::ooxml2ooxml(sFrom, sTo, params, convertParams, L"docm", dotm2docm_dir); + } + _UINT32 dotm2docm_dir(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return NSCommon::ooxml2ooxml_replace_content_type(sFrom, sTo, params, convertParams, + L"application/vnd.ms-word.template.macroEnabledTemplate.main+xml", + L"application/vnd.ms-word.document.macroEnabled.main+xml"); + } + _UINT32 dotx2docx(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return NSCommon::ooxml2ooxml(sFrom, sTo, params, convertParams, L"docx", dotx2docx_dir); + } + _UINT32 dotx2docx_dir(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return NSCommon::ooxml2ooxml_replace_content_type(sFrom, sTo, params, convertParams, + L"application/vnd.openxmlformats-officedocument.wordprocessingml.template.main+xml", + L"application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"); + } + _UINT32 docm2docx(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return NSCommon::ooxml2ooxml(sFrom, sTo, params, convertParams, L"docx", docm2docx_dir); + } + _UINT32 docm2docx_dir(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return NSCommon::ooxmlm2ooml_dir(sFrom, sTo, params, convertParams, NSCommon::OOXML_DOCUMENT_TYPE::Word, NSCommon::OOXML_DOCUMENT_SUBTYPE::Main); + } + _UINT32 dotm2docx(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return NSCommon::ooxml2ooxml(sFrom, sTo, params, convertParams, L"docx", dotm2docx_dir); + } + _UINT32 dotm2docx_dir(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return NSCommon::ooxmlm2ooml_dir(sFrom, sTo, params, convertParams, NSCommon::OOXML_DOCUMENT_TYPE::Word, NSCommon::OOXML_DOCUMENT_SUBTYPE::Template); + } +} diff --git a/X2tConverter/src/lib/html.h b/X2tConverter/src/lib/html.h new file mode 100644 index 00000000000..510b0e719a4 --- /dev/null +++ b/X2tConverter/src/lib/html.h @@ -0,0 +1,255 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#pragma once + +#include "../../../Common/3dParty/pole/pole.h" +#include "../../../EpubFile/CEpubFile.h" +#include "../../../Fb2File/Fb2File.h" +#include "../../../HtmlFile2/htmlfile2.h" +#include "common.h" + +namespace NExtractTools +{ + _UINT32 html2doct_bin(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + std::wstring sDocxDir = combinePath(convertParams.m_sTempDir, L"docx_unpacked"); + NSDirectory::CreateDirectory(sDocxDir); + _UINT32 nRes = html2docx_dir(sFrom, sDocxDir, params, convertParams); + if (SUCCEEDED_X2T(nRes)) + { + nRes = (S_OK == docx_dir2doct_bin(sDocxDir, sTo, params, convertParams)) ? nRes : AVS_FILEUTILS_ERROR_CONVERT; + } + return nRes; + } + _UINT32 html_zip2doct_bin(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + std::wstring sDocxDir = combinePath(convertParams.m_sTempDir, L"docx_unpacked"); + NSDirectory::CreateDirectory(sDocxDir); + _UINT32 nRes = html_zip2docx_dir(sFrom, sDocxDir, params, convertParams); + if (SUCCEEDED_X2T(nRes)) + { + nRes = (S_OK == docx_dir2doct_bin(sDocxDir, sTo, params, convertParams)) ? nRes : AVS_FILEUTILS_ERROR_CONVERT; + } + return nRes; + } + _UINT32 html2doct(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return NSCommon::format2oot(sFrom, sTo, params, convertParams, L"doct", html2doct_bin); + } + _UINT32 html_zip2doct(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return NSCommon::format2oot(sFrom, sTo, params, convertParams, L"doct", html_zip2doct_bin); + } + _UINT32 html2docx(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return NSCommon::format2ooxml(sFrom, sTo, params, convertParams, L"docx", html2docx_dir); + } + _UINT32 html_zip2docx(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return NSCommon::format2ooxml(sFrom, sTo, params, convertParams, L"docx", html_zip2docx_dir); + } + _UINT32 html_array2docx_dir(const std::vector &arFiles, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + params.m_bMacro = false; + + CHtmlFile2 oFile; + oFile.SetTmpDirectory(convertParams.m_sTempDir); + return (S_OK == oFile.OpenBatchHtml(arFiles, sTo)) ? 0 : AVS_FILEUTILS_ERROR_CONVERT; + } + _UINT32 html2docx_dir(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + std::vector arFiles; + arFiles.push_back(sFrom); + return html_array2docx_dir(arFiles, sTo, params, convertParams); + } + _UINT32 html_zip2docx_dir(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + std::vector arFiles; + + POLE::Storage storage(sFrom.c_str()); + if (storage.open()) + { + POLE::Stream stream(&storage, L"WordDocument"); + + POLE::uint64 size_stream = stream.size(); + unsigned char *buffer = new unsigned char[size_stream]; + if (buffer) + { + stream.read(buffer, size_stream); + std::wstring sTempHtml = combinePath(convertParams.m_sTempDir, L"tempHtml.html"); + + NSFile::CFileBinary file; + + if (file.CreateFileW(sTempHtml)) + { + file.WriteFile(buffer, (DWORD)size_stream); + file.CloseFile(); + + arFiles.push_back(sTempHtml); + } + delete[] buffer; + } + } + else // in zip + { + } + return 0 == html_array2docx_dir(arFiles, sTo, params, convertParams) ? 0 : AVS_FILEUTILS_ERROR_CONVERT; + } + // mht + _UINT32 mht2docx_dir(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + CHtmlFile2 oFile; + oFile.SetTmpDirectory(convertParams.m_sTempDir); + return (S_OK == oFile.OpenMht(sFrom, sTo)) ? 0 : AVS_FILEUTILS_ERROR_CONVERT; + } + // epub + _UINT32 epub2docx_dir(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + CEpubFile oFile; + oFile.SetTempDirectory(convertParams.m_sTempDir); + return (S_OK == oFile.Convert(sFrom, sTo, false)) ? 0 : AVS_FILEUTILS_ERROR_CONVERT; + } + _UINT32 fb2docx_dir(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + CFb2File fb2File; + fb2File.SetTmpDirectory(convertParams.m_sTempDir); + return S_OK == fb2File.Open(sFrom, sTo) ? S_OK : AVS_FILEUTILS_ERROR_CONVERT; + } + _UINT32 fb2docx(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return NSCommon::format2ooxml(sFrom, sTo, params, convertParams, L"docx", fb2docx_dir); + } + + // doct_bin => html + _UINT32 doct_bin2html_internal(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + _UINT32 nRes = 0; + if (params.getFromChanges()) + params.setFromChanges(false); + + std::wstring sFileFromDir = NSDirectory::GetFolderPath(sFrom); + std::wstring sImagesDirectory = combinePath(sFileFromDir, L"media"); + std::wstring sHtmlFile = combinePath(convertParams.m_sTempDir, L"index.html"); + if (!NSDirectory::Exists(sImagesDirectory)) + NSDirectory::CreateDirectory(sImagesDirectory); + + NSDoctRenderer::CDoctrenderer oDoctRenderer(NULL != params.m_sAllFontsPath ? *params.m_sAllFontsPath : L""); + std::wstring sXml = getDoctXml(NSDoctRenderer::DoctRendererFormat::FormatFile::DOCT, + NSDoctRenderer::DoctRendererFormat::FormatFile::HTML, + sFrom, sHtmlFile, sImagesDirectory, convertParams.m_sThemesDir, -1, L"", params); + + std::wstring sResult; + oDoctRenderer.Execute(sXml, sResult); + + if (sResult.find(L"error") != std::wstring::npos) + { + std::wcerr << L"DoctRenderer:" << sResult << std::endl; + return AVS_FILEUTILS_ERROR_CONVERT; + } + else + { + if (!params.getDontSaveAdditional()) + { + //create changes.zip next to result file + std::wstring sBinDir = NSDirectory::GetFolderPath(sFrom); + std::wstring sChangesDir = sBinDir + FILE_SEPARATOR_STR + L"changes"; + copyImagesFromChanges(&oDoctRenderer, sImagesDirectory, sChangesDir, NSDirectory::GetFolderPath(*params.m_sFileTo)); + } + } + return nRes; + } + + // doct_bin -> epub + _UINT32 doct_bin2epub(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + _UINT32 nRes = doct_bin2html_internal(sFrom, sTo, params, convertParams); + if (0 != nRes) + return nRes; + + std::wstring sHtmlFile = combinePath(convertParams.m_sTempDir, L"index.html"); + + CEpubFile oFile; + std::wstring sEpubTemp = combinePath(convertParams.m_sTempDir, L"tmp"); + NSDirectory::CreateDirectory(sEpubTemp); + oFile.SetTempDirectory(sEpubTemp); + + if (S_FALSE == oFile.FromHtml(sHtmlFile, sTo, params.m_sTitle ? *params.m_sTitle : L"")) + nRes = AVS_FILEUTILS_ERROR_CONVERT; + + return nRes; + } + // doct_bin -> fb2 + _UINT32 doct_bin2fb(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + _UINT32 nRes = doct_bin2html_internal(sFrom, sTo, params, convertParams); + if (0 != nRes) + return nRes; + + std::wstring sHtmlFile = combinePath(convertParams.m_sTempDir, L"index.html"); + + CFb2File fb2File; + fb2File.SetTmpDirectory(convertParams.m_sTempDir); + if (S_FALSE == fb2File.FromHtml(sHtmlFile, sTo, params.m_sTitle ? *params.m_sTitle : L"")) + nRes = AVS_FILEUTILS_ERROR_CONVERT; + + return nRes; + } + // doct_bin -> html + _UINT32 doct_bin2html(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + _UINT32 nRes = doct_bin2html_internal(sFrom, sTo, params, convertParams); + if (0 != nRes) + return nRes; + + std::wstring sHtmlFile = combinePath(convertParams.m_sTempDir, L"index.html"); + + if (!NSFile::CFileBinary::Copy(sHtmlFile, sTo)) + nRes = AVS_FILEUTILS_ERROR_CONVERT; + + return nRes; + } + // doct_bin -> html_zip + _UINT32 doct_bin2html_zip(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + _UINT32 nRes = doct_bin2html_internal(sFrom, sTo, params, convertParams); + if (0 != nRes) + return nRes; + + std::wstring sHtmlFile = combinePath(convertParams.m_sTempDir, L"index.html"); + + COfficeUtils oZip; + if (S_FALSE == oZip.CompressFileOrDirectory(sHtmlFile, sTo)) + nRes = AVS_FILEUTILS_ERROR_CONVERT; + + return nRes; + } +} diff --git a/X2tConverter/src/lib/hwp.h b/X2tConverter/src/lib/hwp.h new file mode 100644 index 00000000000..c334eaa1e92 --- /dev/null +++ b/X2tConverter/src/lib/hwp.h @@ -0,0 +1,46 @@ +#ifndef HWP_H +#define HWP_H + +#include "../../../HwpFile/HWPFile.h" +#include "common.h" + +namespace NExtractTools +{ + _UINT32 hwp_file2docx(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams, bool bIsXmlFormat, bool bConvertToDir) + { + CHWPFile oFile; + + oFile.SetTempDirectory(convertParams.m_sTempDir); + + params.m_bMacro = false; + if (((bIsXmlFormat && !oFile.OpenHWPX(sFrom)) || + (!bIsXmlFormat && !oFile.OpenHWP(sFrom))) || + ((bConvertToDir && !oFile.ConvertToOOXML_Dir(sTo)) || + (!bConvertToDir && !oFile.ConvertToOOXML(sTo)))) + return AVS_FILEUTILS_ERROR_CONVERT; + + return 0; + } + + _UINT32 hwp2docx(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return hwp_file2docx(sFrom, sTo, params, convertParams, false, false); + } + + _UINT32 hwp2docx_dir(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return hwp_file2docx(sFrom, sTo, params, convertParams, false, true); + } + + _UINT32 hwpx2docx(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return hwp_file2docx(sFrom, sTo, params, convertParams, true, false); + } + + _UINT32 hwpx2docx_dir(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return hwp_file2docx(sFrom, sTo, params, convertParams, true, true); + } +} + +#endif // HWP_H diff --git a/X2tConverter/src/lib/iwork.h b/X2tConverter/src/lib/iwork.h new file mode 100644 index 00000000000..529c672a419 --- /dev/null +++ b/X2tConverter/src/lib/iwork.h @@ -0,0 +1,63 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#pragma once + +#include "../../../Apple/IWork.h" +#include "common.h" + +namespace NExtractTools +{ + _UINT32 iworkformat2odf(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams, IWorkFileType eVerificationType) + { + CIWorkFile oFile; + oFile.SetTmpDirectory(convertParams.m_sTempDir); + + if (eVerificationType != oFile.GetType(sFrom)) + return AVS_FILEUTILS_ERROR_CONVERT; + + return (S_OK == oFile.Convert2Odf(sFrom, sTo)) ? 0 : AVS_FILEUTILS_ERROR_CONVERT; + } + _UINT32 pages2odf(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return iworkformat2odf(sFrom, sTo, params, convertParams, IWorkFileType::Pages); + } + + _UINT32 numbers2odf(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return iworkformat2odf(sFrom, sTo, params, convertParams, IWorkFileType::Numbers); + } + + _UINT32 key2odf(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return iworkformat2odf(sFrom, sTo, params, convertParams, IWorkFileType::Keynote); + } +} diff --git a/X2tConverter/src/lib/odf.h b/X2tConverter/src/lib/odf.h new file mode 100644 index 00000000000..6c0709b6dd0 --- /dev/null +++ b/X2tConverter/src/lib/odf.h @@ -0,0 +1,357 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#pragma once + +#include "../../../OdfFile/Reader/Converter/ConvertOO2OOX.h" +#include "../../../OdfFile/Writer/Converter/Oox2OdfConverter.h" +#include "../../../OOXML/Binary/Document/DocWrapper/DocxSerializer.h" +#include "common.h" + +namespace NExtractTools +{ + _UINT32 odf2oox(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + std::wstring sTempUnpackedOox = combinePath(convertParams.m_sTempDir, L"oox_unpacked"); + NSDirectory::CreateDirectory(sTempUnpackedOox); + + _UINT32 nRes = odf2oox_dir(sFrom, sTempUnpackedOox, params, convertParams); + + if (SUCCEEDED_X2T(nRes)) + { + nRes = dir2zipMscrypt(sTempUnpackedOox, sTo, params, convertParams); + } + else + { + nRes = AVS_FILEUTILS_ERROR_CONVERT; + if (create_if_empty(sFrom, sTo, L"")) + nRes = 0; + } + return nRes; + } + _UINT32 odf2oox_dir(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + _UINT32 nRes = 0; + + std::wstring sTempUnpackedOdf = combinePath(convertParams.m_sTempDir, L"odf_unpacked"); + NSDirectory::CreateDirectory(sTempUnpackedOdf); + + COfficeUtils oCOfficeUtils(NULL); + if (S_OK == oCOfficeUtils.ExtractToDirectory(sFrom, sTempUnpackedOdf, NULL, 0)) + { + nRes = ConvertODF2OOXml(sTempUnpackedOdf, sTo, params.getFontPath(), convertParams.m_sTempDir, params.getPassword()); + + params.m_bMacro = false; // todooo ������� ��������� �������� odf + nRes = processEncryptionError(nRes, sFrom, params); + } + else + { + nRes = AVS_FILEUTILS_ERROR_CONVERT; + } + return nRes; + } + _UINT32 odf2oot(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return NSCommon::format2oot(sFrom, sTo, params, convertParams, L"doct", odf2oot_bin); + } + _UINT32 odf2oot_bin(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + std::wstring sTempUnpackedOdf = combinePath(convertParams.m_sTempDir, L"odf_unpacked"); + std::wstring sTempUnpackedOox = combinePath(convertParams.m_sTempDir, L"oox_unpacked"); + + NSDirectory::CreateDirectory(sTempUnpackedOdf); + + _UINT32 nRes = 0; + + COfficeUtils oCOfficeUtils(NULL); + if (S_OK == oCOfficeUtils.ExtractToDirectory(sFrom, sTempUnpackedOdf, NULL, 0)) + { + NSDirectory::CreateDirectory(sTempUnpackedOox); + + nRes = ConvertODF2OOXml(sTempUnpackedOdf, sTempUnpackedOox, params.getFontPath(), convertParams.m_sTempDir, params.getPassword()); + + params.m_bMacro = false; // todooo ������� ��������� �������� odf + + nRes = processEncryptionError(nRes, sFrom, params); + if (SUCCEEDED_X2T(nRes)) + { + COfficeFileFormatChecker OfficeFileFormatChecker; + + if (OfficeFileFormatChecker.isOOXFormatFile(sTempUnpackedOox, true)) + { + switch (OfficeFileFormatChecker.nFileType) + { + case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX: + case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCM: + case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOTX: + case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOTM: + case AVS_OFFICESTUDIO_FILE_DOCUMENT_OFORM: + case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCXF: + { + return docx_dir2doct_bin(sTempUnpackedOox, sTo, params, convertParams); + } + break; + case AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSX: + case AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSM: + case AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLTX: + case AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLTM: + case AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSB: + { + const std::wstring &sXmlOptions = params.getXmlOptions(); + convertParams.m_bTempIsXmlOptions = false; + return xlsx_dir2xlst_bin(sTempUnpackedOox, sTo, params, convertParams); + } + break; + case AVS_OFFICESTUDIO_FILE_PRESENTATION_PPTX: + case AVS_OFFICESTUDIO_FILE_PRESENTATION_PPTM: + case AVS_OFFICESTUDIO_FILE_PRESENTATION_PPSX: + case AVS_OFFICESTUDIO_FILE_PRESENTATION_POTX: + case AVS_OFFICESTUDIO_FILE_PRESENTATION_POTM: + case AVS_OFFICESTUDIO_FILE_PRESENTATION_PPSM: + { + return pptx_dir2pptt_bin(sTempUnpackedOox, sTo, params, convertParams); + } + break; + default: + { + nRes = AVS_FILEUTILS_ERROR_CONVERT; + } + break; + } + } + } + } + else + { + nRes = AVS_FILEUTILS_ERROR_CONVERT; + if (create_if_empty(sFrom, sTo, L"DOCY;v10;0;")) + nRes = 0; + } + return nRes; + } + + _UINT32 odf_flat2oox(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return NSCommon::format2ooxml(sFrom, sTo, params, convertParams, L"oox", odf_flat2oox_dir); + } + _UINT32 odf_flat2oox_dir(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + _UINT32 nRes = ConvertODF2OOXml(sFrom, sTo, params.getFontPath(), convertParams.m_sTempDir, params.getPassword()); + params.m_bMacro = false; // todooo ������� ��������� �������� odf + + nRes = processEncryptionError(nRes, sFrom, params); + return nRes; + } + _UINT32 odf_flat2oot(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return NSCommon::format2oot(sFrom, sTo, params, convertParams, L"doct", odf_flat2oot_bin); + } + _UINT32 odf_flat2oot_bin(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + std::wstring sTempUnpackedOox = combinePath(convertParams.m_sTempDir, L"oox_unpacked"); + NSDirectory::CreateDirectory(sTempUnpackedOox); + + _UINT32 nRes = ConvertODF2OOXml(sFrom, sTempUnpackedOox, params.getFontPath(), convertParams.m_sTempDir, params.getPassword()); + params.m_bMacro = false; // todooo ������� ��������� �������� odf + + nRes = processEncryptionError(nRes, sFrom, params); + if (SUCCEEDED_X2T(nRes)) + { + BinDocxRW::CDocxSerializer m_oCDocxSerializer; + + m_oCDocxSerializer.setFontDir(params.getFontPath()); + + nRes = m_oCDocxSerializer.saveToFile(sTo, sTempUnpackedOox, params.getXmlOptions(), convertParams.m_sTempDir) ? 0 : AVS_FILEUTILS_ERROR_CONVERT; + } + + return nRes; + } + + // docx => odt + _UINT32 docx2odt(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + std::wstring sTempUnpackedDOCX = combinePath(convertParams.m_sTempDir, L"docx_unpacked"); + NSDirectory::CreateDirectory(sTempUnpackedDOCX); + + COfficeUtils oCOfficeUtils(NULL); + if (S_OK == oCOfficeUtils.ExtractToDirectory(sFrom, sTempUnpackedDOCX, NULL, 0)) + { + convertParams.m_bIsTemplate = false; + return docx_dir2odt(sTempUnpackedDOCX, sTo, params, convertParams); // add Template ???? + } + return AVS_FILEUTILS_ERROR_CONVERT; + } + _UINT32 docx_dir2odt(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + std::wstring sTempUnpackedODT = combinePath(convertParams.m_sTempDir, L"odt_unpacked"); + NSDirectory::CreateDirectory(sTempUnpackedODT); + + Oox2Odf::Converter converter(sFrom, L"text", params.getFontPath(), convertParams.m_bIsTemplate, convertParams.m_sTempDir); + + _UINT32 nRes = 0; + try + { + std::wstring password = params.getSavePassword(); + std::wstring documentID = params.getDocumentID(); + + converter.convert(); + converter.write(sTempUnpackedODT, convertParams.m_sTempDir, password, documentID); + + COfficeUtils oCOfficeUtils(NULL); + nRes = (S_OK == oCOfficeUtils.CompressFileOrDirectory(sTempUnpackedODT, sTo, false, password.empty() ? Z_DEFLATED : 0)) ? 0 : AVS_FILEUTILS_ERROR_CONVERT; + } + catch (...) + { + nRes = AVS_FILEUTILS_ERROR_CONVERT; + } + return nRes; + } + + // xlsx => ods + _UINT32 xlsx2ods(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + std::wstring sTempUnpackedXLSX = combinePath(convertParams.m_sTempDir, L"xlsx_unpacked"); + NSDirectory::CreateDirectory(sTempUnpackedXLSX); + + COfficeUtils oCOfficeUtils(NULL); + if (S_OK == oCOfficeUtils.ExtractToDirectory(sFrom, sTempUnpackedXLSX, NULL, 0)) + { + convertParams.m_bIsTemplate = false; + return xlsx_dir2ods(sTempUnpackedXLSX, sTo, params, convertParams); // add Template ??? + } + return AVS_FILEUTILS_ERROR_CONVERT; + } + _UINT32 xlsx_dir2ods(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + std::wstring sTempUnpackedODS = combinePath(convertParams.m_sTempDir, L"ods_unpacked"); + NSDirectory::CreateDirectory(sTempUnpackedODS); + + Oox2Odf::Converter converter(sFrom, L"spreadsheet", params.getFontPath(), convertParams.m_bIsTemplate, convertParams.m_sTempDir); + + _UINT32 nRes = 0; + + std::wstring password = params.getSavePassword(); + std::wstring documentID = params.getDocumentID(); + + converter.convert(); + converter.write(sTempUnpackedODS, convertParams.m_sTempDir, password, documentID); + + COfficeUtils oCOfficeUtils(NULL); + nRes = (S_OK == oCOfficeUtils.CompressFileOrDirectory(sTempUnpackedODS, sTo, false, password.empty() ? Z_DEFLATED : 0)) ? 0 : AVS_FILEUTILS_ERROR_CONVERT; + + return nRes; + } + + // pptx => odp + _UINT32 pptx2odp(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + std::wstring sTempUnpackedPPTX = combinePath(convertParams.m_sTempDir, L"pptx_unpacked"); + NSDirectory::CreateDirectory(sTempUnpackedPPTX); + + COfficeUtils oCOfficeUtils(NULL); + if (S_OK == oCOfficeUtils.ExtractToDirectory(sFrom, sTempUnpackedPPTX, NULL, 0)) + { + convertParams.m_bIsTemplate = false; + return pptx_dir2odp(sTempUnpackedPPTX, sTo, params, convertParams); // add template ??? + } + return AVS_FILEUTILS_ERROR_CONVERT; + } + // pptx_dir -> odp + _UINT32 pptx_dir2odp(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + std::wstring sTempUnpackedODP = combinePath(convertParams.m_sTempDir, L"odp_unpacked"); + NSDirectory::CreateDirectory(sTempUnpackedODP); + + Oox2Odf::Converter converter(sFrom, L"presentation", params.getFontPath(), convertParams.m_bIsTemplate, convertParams.m_sTempDir); + + _UINT32 nRes = 0; + try + { + std::wstring password = params.getSavePassword(); + std::wstring documentID = params.getDocumentID(); + + converter.convert(); + converter.write(sTempUnpackedODP, convertParams.m_sTempDir, password, documentID); + + COfficeUtils oCOfficeUtils(NULL); + nRes = (S_OK == oCOfficeUtils.CompressFileOrDirectory(sTempUnpackedODP, sTo, false, password.empty() ? Z_DEFLATED : 0)) ? 0 : AVS_FILEUTILS_ERROR_CONVERT; + } + catch (...) + { + nRes = AVS_FILEUTILS_ERROR_CONVERT; + } + return nRes; + } + + _UINT32 otf2odf(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + std::wstring sTempUnpackedOdf = combinePath(convertParams.m_sTempDir, L"odf_unpacked"); + NSDirectory::CreateDirectory(sTempUnpackedOdf); + + COfficeUtils oCOfficeUtils(NULL); + if (S_OK != oCOfficeUtils.ExtractToDirectory(sFrom, sTempUnpackedOdf, NULL, 0)) + return AVS_FILEUTILS_ERROR_CONVERT; + + _UINT32 nRes = ConvertOTF2ODF(sTempUnpackedOdf); + if (SUCCEEDED_X2T(nRes)) + { + COfficeUtils oCOfficeUtils(NULL); + nRes = (S_OK == oCOfficeUtils.CompressFileOrDirectory(sTempUnpackedOdf, sTo, true)) ? nRes : AVS_FILEUTILS_ERROR_CONVERT; + } + return nRes; + } + + _UINT32 docxflat2odt(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + std::wstring sTempUnpackedODT = combinePath(convertParams.m_sTempDir, L"odt_unpacked"); + NSDirectory::CreateDirectory(sTempUnpackedODT); + + Oox2Odf::Converter converter(sFrom, L"text", params.getFontPath(), false, convertParams.m_sTempDir); + + _UINT32 nRes = 0; + try + { + std::wstring password = params.getSavePassword(); + std::wstring documentID = params.getDocumentID(); + + converter.convert(); + converter.write(sTempUnpackedODT, convertParams.m_sTempDir, password, documentID); + + COfficeUtils oCOfficeUtils(NULL); + nRes = (S_OK == oCOfficeUtils.CompressFileOrDirectory(sTempUnpackedODT, sTo, false, password.empty() ? Z_DEFLATED : 0)) ? 0 : AVS_FILEUTILS_ERROR_CONVERT; + } + catch (...) + { + nRes = AVS_FILEUTILS_ERROR_CONVERT; + } + return nRes; + } +} diff --git a/X2tConverter/src/lib/pdf_image.h b/X2tConverter/src/lib/pdf_image.h new file mode 100644 index 00000000000..569ea9fc73c --- /dev/null +++ b/X2tConverter/src/lib/pdf_image.h @@ -0,0 +1,1117 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#pragma once + +#include "../../../DesktopEditor/graphics/MetafileToGraphicsRenderer.h" +#include "../../../DesktopEditor/graphics/Image.h" + +#include "../../../DjVuFile/DjVu.h" +#include "../../../DocxRenderer/DocxRenderer.h" +#include "../../../PdfFile/PdfFile.h" +#include "../../../XpsFile/XpsFile.h" +#include "../../../OfficeUtils/src/ZipFolder.h" + +#include "common.h" + +namespace NExtractTools +{ + _UINT32 bin2pdf(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + NSFonts::IApplicationFonts* pApplicationFonts = createApplicationFonts(params); + + CPdfFile pdfWriter(pApplicationFonts); + pdfWriter.CreatePdf(params.getIsPDFA()); + pdfWriter.SetTempDirectory(convertParams.m_sTempDir); + pdfWriter.SetDocumentInfo(params.getTitle(), L"", L"", L""); + + CConvertFromBinParams oBufferParams; + oBufferParams.m_sThemesDirectory = convertParams.m_sThemesDir; + + std::wstring documentID = params.getDocumentID(); + if (false == documentID.empty()) + pdfWriter.SetDocumentID(documentID); + + std::wstring password = params.getSavePassword(); + if (false == password.empty()) + pdfWriter.SetPassword(password); + + int nReg = (convertParams.m_bIsPaid == false) ? 0 : 1; + _UINT32 nRet = 0; + if (params.getIsNoBase64()) + { + nRet = S_OK == pdfWriter.OnlineWordToPdfFromBinary(sFrom, sTo, &oBufferParams) ? 0 : AVS_FILEUTILS_ERROR_CONVERT; + } + else + { + nRet = S_OK == pdfWriter.OnlineWordToPdf(sFrom, sTo, &oBufferParams) ? 0 : AVS_FILEUTILS_ERROR_CONVERT; + } + RELEASEOBJECT(pApplicationFonts); + return nRet; + } + + _UINT32 bin2image(unsigned char* pBuffer, long lBufferLen, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + NSFonts::IApplicationFonts* pApplicationFonts = createApplicationFonts(params); + NSOnlineOfficeBinToPdf::CMetafileToRenderterRaster imageWriter(NULL); + + imageWriter.SetMediaDirectory(convertParams.m_sMediaDirectory); + imageWriter.SetThemesDirectory(convertParams.m_sThemesDir); + imageWriter.SetInternalMediaDirectory(convertParams.m_sInternalMediaDirectory); + imageWriter.SetTempDirectory(convertParams.m_sTempDir); + imageWriter.SetApplication(pApplicationFonts); + + if (NULL != params.m_oThumbnail) + { + InputParamsThumbnail *oThumbnail = params.m_oThumbnail; + if (NULL != oThumbnail->format) + { + imageWriter.SetRasterFormat(*oThumbnail->format); + } + if (NULL != oThumbnail->aspect) + { + imageWriter.SetSaveType(*oThumbnail->aspect); + } + if (NULL != oThumbnail->first) + { + imageWriter.SetIsOnlyFirst(*oThumbnail->first); + } + if (NULL != oThumbnail->width) + { + imageWriter.SetRasterW(*oThumbnail->width); + } + if (NULL != oThumbnail->height) + { + imageWriter.SetRasterH(*oThumbnail->height); + } + } + std::wstring sThumbnailDir; + if (imageWriter.GetIsOnlyFirst()) + { + imageWriter.SetFileName(sTo); + } + else + { + std::wstring sFileAddon = L"image" + getExtentionByRasterFormat(imageWriter.GetRasterFormat()); + if (NULL == params.m_oThumbnail->zip || *(params.m_oThumbnail->zip)) + { + sThumbnailDir = combinePath(convertParams.m_sTempDir, L"thumbnails"); + NSDirectory::CreateDirectory(sThumbnailDir); + imageWriter.SetFileName(combinePath(sThumbnailDir, sFileAddon)); + } + else + { + if (!NSDirectory::Exists(sTo)) + NSDirectory::CreateDirectory(sTo); + imageWriter.SetFileName(sTo + FILE_SEPARATOR_STR + sFileAddon); + } + } + _UINT32 nRes = imageWriter.ConvertBuffer(pBuffer, lBufferLen) ? 0 : AVS_FILEUTILS_ERROR_CONVERT; + if (!sThumbnailDir.empty()) + { + COfficeUtils oCOfficeUtils(NULL); + nRes = S_OK == oCOfficeUtils.CompressFileOrDirectory(sThumbnailDir, sTo) ? nRes : AVS_FILEUTILS_ERROR_CONVERT; + } + RELEASEOBJECT(pApplicationFonts); + return nRes; + } + _UINT32 bin2imageBase64(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + NSFile::CFileBinary oFile; + if (!oFile.OpenFile(sFrom)) + return AVS_FILEUTILS_ERROR_CONVERT; + + DWORD dwFileSize = oFile.GetFileSize(); + BYTE *pFileContent = new BYTE[dwFileSize]; + if (!pFileContent) + { + oFile.CloseFile(); + return AVS_FILEUTILS_ERROR_CONVERT; + } + + DWORD dwReaded; + oFile.ReadFile(pFileContent, dwFileSize, dwReaded); + oFile.CloseFile(); + + int nBufferLen = NSBase64::Base64DecodeGetRequiredLength(dwFileSize); + BYTE *pBuffer = new BYTE[nBufferLen]; + if (!pBuffer) + { + RELEASEARRAYOBJECTS(pFileContent); + return AVS_FILEUTILS_ERROR_CONVERT; + } + + _UINT32 nRes = 0; + if (NSBase64::Base64Decode((const char *)pFileContent, dwFileSize, pBuffer, &nBufferLen)) + { + convertParams.m_sMediaDirectory = NSDirectory::GetFolderPath(sFrom); + nRes = bin2image(pBuffer, nBufferLen, sTo, params, convertParams); + } + else + { + nRes = AVS_FILEUTILS_ERROR_CONVERT; + } + + RELEASEARRAYOBJECTS(pBuffer); + RELEASEARRAYOBJECTS(pFileContent); + + return nRes; + } + + _UINT32 doct_bin2pdf(NSDoctRenderer::DoctRendererFormat::FormatFile eFromType, + const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + NSDoctRenderer::DoctRendererFormat::FormatFile eToType = NSDoctRenderer::DoctRendererFormat::FormatFile::PDF; + + std::wstring sFileDir = NSDirectory::GetFolderPath(sFrom); + std::wstring sImagesDirectory = combinePath(sFileDir, L"media"); + std::wstring sPdfBinFile = combinePath(convertParams.m_sTempDir, L"pdf.bin"); + + NSDoctRenderer::CDoctrenderer oDoctRenderer(NULL != params.m_sAllFontsPath ? *params.m_sAllFontsPath : L""); + std::wstring sXml = getDoctXml(eFromType, eToType, sFrom, sPdfBinFile, sImagesDirectory, convertParams.m_sThemesDir, -1, L"", params); + std::wstring sResult; + oDoctRenderer.Execute(sXml, sResult); + + _UINT32 nRes = 0; + if (sResult.find(L"error") != std::wstring::npos) + { + std::wcerr << _T("DoctRenderer:") << sResult << std::endl; + nRes = AVS_FILEUTILS_ERROR_CONVERT; + } + else + { + NSFonts::IApplicationFonts* pApplicationFonts = createApplicationFonts(params); + + CPdfFile pdfWriter(pApplicationFonts); + pdfWriter.CreatePdf(params.getIsPDFA()); + pdfWriter.SetTempDirectory(convertParams.m_sTempDir); + pdfWriter.SetDocumentInfo(params.getTitle(), L"", L"", L""); + + CConvertFromBinParams oBufferParams; + oBufferParams.m_sThemesDirectory = convertParams.m_sThemesDir; + oBufferParams.m_sMediaDirectory = sFileDir; + oBufferParams.m_sInternalMediaDirectory = convertParams.m_sInternalMediaDirectory; + + std::wstring documentID = params.getDocumentID(); + if (false == documentID.empty()) + pdfWriter.SetDocumentID(documentID); + + std::wstring password = params.getSavePassword(); + if (false == password.empty()) + pdfWriter.SetPassword(password); + + if (!convertParams.m_sPdfOformMetaName.empty() && !convertParams.m_sPdfOformMetaData.empty()) + { + BYTE* pFileMetaData = NULL; + DWORD nFileMetaSize = 0; + + if (NSFile::CFileBinary::ReadAllBytes(convertParams.m_sPdfOformMetaData, &pFileMetaData, nFileMetaSize)) + { + pdfWriter.AddMetaData(convertParams.m_sPdfOformMetaName, pFileMetaData, nFileMetaSize); + } + + RELEASEARRAYOBJECTS(pFileMetaData); + } + + int nReg = (convertParams.m_bIsPaid == false) ? 0 : 1; + nRes = (S_OK == pdfWriter.OnlineWordToPdfFromBinary(sPdfBinFile, sTo, &oBufferParams)) ? nRes : AVS_FILEUTILS_ERROR_CONVERT; + RELEASEOBJECT(pApplicationFonts); + } + // удаляем sPdfBinFile, потому что он не в Temp + if (NSFile::CFileBinary::Exists(sPdfBinFile)) + NSFile::CFileBinary::Remove(sPdfBinFile); + return nRes; + } + + _UINT32 doct_bin2image(NSDoctRenderer::DoctRendererFormat::FormatFile eFromType, + const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + NSDoctRenderer::DoctRendererFormat::FormatFile eToType = NSDoctRenderer::DoctRendererFormat::FormatFile::IMAGE; + + std::wstring sFileDir = NSDirectory::GetFolderPath(sFrom); + std::wstring sImagesDirectory = combinePath(sFileDir, L"media"); + std::wstring sPdfBinFile = combinePath(convertParams.m_sTempDir, L"pdf.bin"); + + NSDoctRenderer::CDoctrenderer oDoctRenderer(NULL != params.m_sAllFontsPath ? *params.m_sAllFontsPath : L""); + std::wstring sXml = getDoctXml(eFromType, eToType, sFrom, sPdfBinFile, sImagesDirectory, convertParams.m_sThemesDir, -1, L"", params); + std::wstring sResult; + oDoctRenderer.Execute(sXml, sResult); + + _UINT32 nRes = 0; + if (-1 != sResult.find(_T("error"))) + { + std::wcerr << _T("DoctRenderer:") << sResult << std::endl; + nRes = AVS_FILEUTILS_ERROR_CONVERT; + } + else + { + BYTE *pData = NULL; + DWORD nBytesCount; + if (NSFile::CFileBinary::ReadAllBytes(sPdfBinFile, &pData, nBytesCount)) + { + convertParams.m_sMediaDirectory = sFileDir; + nRes = 0 == bin2image(pData, nBytesCount, sTo, params, convertParams) ? nRes : AVS_FILEUTILS_ERROR_CONVERT; + RELEASEARRAYOBJECTS(pData); + } + else + { + nRes = AVS_FILEUTILS_ERROR_CONVERT; + } + } + // delete sPdfBinFile, because it is not in Temp + if (NSFile::CFileBinary::Exists(sPdfBinFile)) + NSFile::CFileBinary::Remove(sPdfBinFile); + return nRes; + } + + // from crossplatform (pdf) + std::string checkPrintPages(InputParams ¶ms) + { + if (NULL == params.m_sJsonParams) + return ""; + + std::wstring::size_type posNativeOptions = params.m_sJsonParams->find(L"\"nativeOptions\""); + if (std::wstring::npos == posNativeOptions) + return ""; + + std::wstring::size_type posNativePages = params.m_sJsonParams->find(L"\"pages\":\"", posNativeOptions); + if (std::wstring::npos == posNativePages) + return ""; + + posNativePages += 9; + std::wstring::size_type posNativePages2 = params.m_sJsonParams->find(L"\"", posNativePages); + if (std::wstring::npos == posNativePages2) + return ""; + + std::wstring sPages = params.m_sJsonParams->substr(posNativePages, posNativePages2 - posNativePages); + if (L"all" == sPages) + return ""; + + if (L"current" == sPages) + { + std::wstring::size_type posCurrentPage = params.m_sJsonParams->find(L"\"currentPage\":", posNativeOptions); + if (std::wstring::npos == posCurrentPage) + return ""; + + posCurrentPage += 14; + std::wstring::size_type posCurrentPage2 = params.m_sJsonParams->find(L",", posCurrentPage); + std::wstring::size_type posCurrentPage3 = params.m_sJsonParams->find(L"}", posCurrentPage); + + if (std::wstring::npos == posCurrentPage2) + { + if (std::wstring::npos == posCurrentPage3) + return ""; + posCurrentPage2 = posCurrentPage3; + } + else if (std::wstring::npos != posCurrentPage3 && posCurrentPage3 < posCurrentPage2) + posCurrentPage2 = posCurrentPage3; + + if (std::wstring::npos == posCurrentPage2) + return ""; + + sPages = params.m_sJsonParams->substr(posCurrentPage, posCurrentPage2 - posCurrentPage); + } + + return U_TO_UTF8(sPages); + } + + std::vector getPrintPages(const std::string &sPages, int nPagesCount) + { + const char *buffer = sPages.c_str(); + + size_t nCur = 0; + size_t nLen = sPages.length(); + + std::vector arPages; + for (int i = 0; i < nPagesCount; ++i) + arPages.push_back(false); + + while (nCur < nLen) + { + size_t cur = nCur; + while (cur < nLen && buffer[cur] != ',') + ++cur; + + int nStart = 0; + int nEnd = 0; + + size_t curRec = nCur; + while (curRec < cur) + { + char c = buffer[curRec++]; + if (c >= '0' && c <= '9') + nStart = 10 * nStart + (c - '0'); + + if (c == '-') + break; + } + + if (nStart == 0) + nStart = 1; + + if (curRec == cur) + nEnd = nStart; + else + { + while (curRec < cur) + { + char c = buffer[curRec++]; + if (c >= '0' && c <= '9') + nEnd = 10 * nEnd + (c - '0'); + + if (c == '-') + break; + } + + if (0 == nEnd || nEnd > nPagesCount) + nEnd = nPagesCount; + } + + for (int i = nStart; i <= nEnd; ++i) + arPages[i - 1] = true; + + nCur = cur; + if (nCur < nLen) + ++nCur; + } + + return arPages; + } + + IOfficeDrawingFile* createDrawingFile(NSFonts::IApplicationFonts* pFonts, const int& nFormat) + { + switch (nFormat) + { + case AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_PDF: + return new CPdfFile(pFonts); + case AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_XPS: + return new CXpsFile(pFonts); + case AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_DJVU: + return new CDjVuFile(pFonts); + default: + break; + } + return NULL; + } + + _UINT32 PdfDjvuXpsToRenderer(IOfficeDrawingFile** ppReader, IRenderer *pRenderer, + const std::wstring& sFrom, int nFormatFrom, + const std::wstring& sTo, InputParams& params, ConvertParams& convertParams, + NSFonts::IApplicationFonts* pApplicationFonts) + { + _UINT32 nRes = 0; + IOfficeDrawingFile* pReader = createDrawingFile(pApplicationFonts, nFormatFrom); + if (!pReader) + return AVS_FILEUTILS_ERROR_CONVERT; + + *ppReader = pReader; + pReader->SetTempDirectory(convertParams.m_sTempDir); + + std::wstring sPassword = params.getPassword(); + bool bResult = pReader->LoadFromFile(sFrom.c_str(), L"", sPassword, sPassword); + + if (bResult) + { + int nPagesCount = pReader->GetPagesCount(); + + bool bIsUsePages = convertParams.m_sPrintPages.empty() ? false : true; + std::vector arPages; + if (bIsUsePages) + arPages = getPrintPages(convertParams.m_sPrintPages, nPagesCount); + + for (int i = 0; i < nPagesCount; ++i) + { + if (bIsUsePages && !arPages[i]) + continue; + + pRenderer->NewPage(); + pRenderer->BeginCommand(c_nPageType); + + double dPageDpiX, dPageDpiY; + double dWidth, dHeight; + pReader->GetPageInfo(i, &dWidth, &dHeight, &dPageDpiX, &dPageDpiY); + + dWidth *= 25.4 / dPageDpiX; + dHeight *= 25.4 / dPageDpiY; + + pRenderer->put_Width(dWidth); + pRenderer->put_Height(dHeight); + + pReader->DrawPageOnRenderer(pRenderer, i, NULL); + + pRenderer->EndCommand(c_nPageType); + } + } + else + { + nRes = AVS_FILEUTILS_ERROR_CONVERT; + if (AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_PDF == nFormatFrom) + { + CPdfFile *pPdfReader = static_cast(pReader); + if (PdfFile::errorEncrypted == pPdfReader->GetError()) + { + if (sPassword.empty()) + { + if (!params.getDontSaveAdditional()) + { + copyOrigin(sFrom, *params.m_sFileTo); + } + nRes = AVS_FILEUTILS_ERROR_CONVERT_DRM; + } + else + { + nRes = AVS_FILEUTILS_ERROR_CONVERT_PASSWORD; + } + } + } + } + return nRes; + } + + _UINT32 PdfDjvuXpsToImage(IOfficeDrawingFile** ppReader, const std::wstring& sFrom, int nFormatFrom, + const std::wstring& sTo, InputParams& params, ConvertParams& convertParams, + NSFonts::IApplicationFonts* pApplicationFonts) + { + _UINT32 nRes = 0; + IOfficeDrawingFile* pReader = createDrawingFile(pApplicationFonts, nFormatFrom); + if (!pReader) + return AVS_FILEUTILS_ERROR_CONVERT; + + *ppReader = pReader; + pReader->SetTempDirectory(convertParams.m_sTempDir); + + std::wstring sPassword = params.getPassword(); + bool bResult = pReader->LoadFromFile(sFrom.c_str(), L"", sPassword, sPassword); + + if (bResult) + { + // default as in CMetafileToRenderterRaster + int nRasterFormat = 4; + int nSaveType = 2; + bool bIsOnlyFirst = true; + bool bIsZip = true; + int nRasterW = 100; + int nRasterH = 100; + if (NULL != params.m_oThumbnail) + { + InputParamsThumbnail *oThumbnail = params.m_oThumbnail; + if (NULL != oThumbnail->format) + { + nRasterFormat = *oThumbnail->format; + } + if (NULL != oThumbnail->aspect) + { + nSaveType = *oThumbnail->aspect; + } + if (NULL != oThumbnail->first) + { + bIsOnlyFirst = *oThumbnail->first; + } + if (NULL != oThumbnail->zip) + { + bIsZip = *oThumbnail->zip; + } + if (NULL != oThumbnail->width) + { + nRasterW = *oThumbnail->width; + } + if (NULL != oThumbnail->height) + { + nRasterH = *oThumbnail->height; + } + } + std::wstring sThumbnailDir; + std::wstring sFileToExt; + if (!bIsOnlyFirst) + { + if (bIsZip) + { + sThumbnailDir = combinePath(convertParams.m_sTempDir, L"thumbnails"); + NSDirectory::CreateDirectory(sThumbnailDir); + } + else + { + if (!NSDirectory::Exists(sTo)) + NSDirectory::CreateDirectory(sTo); + sThumbnailDir = sTo; + } + sFileToExt = getExtentionByRasterFormat(nRasterFormat); + } + + int nSaveFlags = (nSaveType & 0xF0) >> 4; + nSaveType = nSaveType & 0x0F; + + int nPagesCount = pReader->GetPagesCount(); + if (bIsOnlyFirst) + nPagesCount = 1; + for (int i = 0; i < nPagesCount; ++i) + { + int nRasterWCur = nRasterW; + int nRasterHCur = nRasterH; + + double dPageDpiX, dPageDpiY; + double dWidth, dHeight; + pReader->GetPageInfo(i, &dWidth, &dHeight, &dPageDpiX, &dPageDpiY); + + if (nSaveFlags & 0x0F) + { + if (((dWidth < dHeight) && (nRasterWCur > nRasterHCur)) || + ((dWidth > dHeight) && (nRasterWCur < nRasterHCur))) + { + int nTmp = nRasterWCur; + nRasterWCur = nRasterHCur; + nRasterHCur = nTmp; + } + } + + if (1 == nSaveType) + { + double dKoef1 = nRasterWCur / dWidth; + double dKoef2 = nRasterHCur / dHeight; + if (dKoef1 > dKoef2) + dKoef1 = dKoef2; + + nRasterWCur = (int)(dWidth * dKoef1 + 0.5); + nRasterHCur = (int)(dHeight * dKoef1 + 0.5); + } + else if (2 == nSaveType) + { + nRasterWCur = -1; + nRasterHCur = -1; + } + std::wstring sFileTo; + if (bIsOnlyFirst) + { + sFileTo = sTo; + } + else + { + sFileTo = sThumbnailDir + FILE_SEPARATOR_STR + L"image" + std::to_wstring(i + 1) + sFileToExt; + } + pReader->ConvertToRaster(i, sFileTo, nRasterFormat, nRasterWCur, nRasterHCur); + } + // zip + if (!bIsOnlyFirst && bIsZip) + { + COfficeUtils oCOfficeUtils(NULL); + nRes = S_OK == oCOfficeUtils.CompressFileOrDirectory(sThumbnailDir, sTo) ? nRes : AVS_FILEUTILS_ERROR_CONVERT; + } + } + else + { + nRes = AVS_FILEUTILS_ERROR_CONVERT; + if (AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_PDF == nFormatFrom) + { + CPdfFile *pPdfReader = static_cast(pReader); + if (PdfFile::errorEncrypted == pPdfReader->GetError()) + { + if (sPassword.empty()) + { + if (!params.getDontSaveAdditional()) + { + copyOrigin(sFrom, *params.m_sFileTo); + } + nRes = AVS_FILEUTILS_ERROR_CONVERT_DRM; + } + else + { + nRes = AVS_FILEUTILS_ERROR_CONVERT_PASSWORD; + } + } + } + } + return nRes; + } + + bool applyCompiledChangesPdf(CPdfFile* pFile, const std::wstring& sCompiledChangesPath, CConvertFromBinParams& oConvertParams, const std::wstring& sTo) + { + bool bRes = false; + NSFile::CFileBinary oFile; + if (oFile.OpenFile(sCompiledChangesPath)) + { + char signature[4]; + if (oFile.ReadFile((BYTE*)signature, 4)) + { + if ('%' == signature[0] && 'P' == signature[1] && 'D' == signature[2] && 'F' == signature[3]) + { + DWORD dwChangesSize = (DWORD)(oFile.GetFileSize() - 4); + BYTE* pChangesData = new BYTE[dwChangesSize]; + + if (oFile.ReadFile(pChangesData, dwChangesSize)) + { + if (!pFile->EditPdf(sTo)) + return false; + + bRes = (S_OK == pFile->AddToPdfFromBinary(pChangesData, (unsigned int)dwChangesSize, &oConvertParams)); + RELEASEARRAYOBJECTS(pChangesData); + } + } + } + + oFile.CloseFile(); + } + return bRes; + } + + bool applyChangesPdf(const std::wstring& sFrom, const std::wstring& sTo, + NSFonts::IApplicationFonts* pApplicationFonts, + InputParams& params, ConvertParams& convertParams, + std::vector& changes, + const std::wstring& sResultDirectory) + { + CPdfFile oPdfResult(pApplicationFonts); + oPdfResult.SetTempDirectory(convertParams.m_sTempDir); + oPdfResult.SetDocumentInfo(params.getTitle(), L"", L"", L""); + + std::wstring documentID = params.getDocumentID(); + if (!documentID.empty()) + oPdfResult.SetDocumentID(documentID); + + std::wstring password = params.getPassword(); + if (!oPdfResult.LoadFromFile(sFrom, L"", password, password)) + { + if (oPdfResult.GetError() == 4) + { + // if password does not changed - old password may be not sended + password = params.getSavePassword(); + if (!oPdfResult.LoadFromFile(sFrom, L"", password, password)) + return false; + } + else + return false; + } + + CConvertFromBinParams oConvertParams; + oConvertParams.m_sInternalMediaDirectory = NSFile::GetDirectoryName(sFrom); + oConvertParams.m_sMediaDirectory = oConvertParams.m_sInternalMediaDirectory; + + bool bIsCompiledChanges = false; + if (changes.size() > 0) + { + bIsCompiledChanges = applyCompiledChangesPdf(&oPdfResult, changes[0], oConvertParams, sTo); + + if (!bIsCompiledChanges) + { + NSDoctRenderer::CDoctrenderer oDoctRenderer(NULL != params.m_sAllFontsPath ? *params.m_sAllFontsPath : L""); + + std::wstring sPdfFileCompiledChanges = NSFile::CFileBinary::CreateTempFileWithUniqueName(convertParams.m_sTempDir, L"PDF_"); + if (NSFile::CFileBinary::Exists(sPdfFileCompiledChanges)) + NSFile::CFileBinary::Remove(sPdfFileCompiledChanges); + + std::wstring sXml = getDoctXml(NSDoctRenderer::DoctRendererFormat::PDF, + NSDoctRenderer::DoctRendererFormat::PDF, + sFrom, sPdfFileCompiledChanges, + oConvertParams.m_sInternalMediaDirectory, convertParams.m_sThemesDir, + -1, L"", params); + + std::wstring sResult = L""; + oDoctRenderer.SetAdditionalParam(NSDoctRenderer::AdditionalParamType::DRAWINGFILE, (void*)&oPdfResult); + oDoctRenderer.Execute(sXml, sResult); + + if (NSFile::CFileBinary::Exists(sPdfFileCompiledChanges)) + bIsCompiledChanges = applyCompiledChangesPdf(&oPdfResult, sPdfFileCompiledChanges, oConvertParams, sTo); + else + { + // changes is exist but compiled file does not changed (compiled changes returns null in js) + oPdfResult.EditPdf(sTo); + } + } + } + + if (!sResultDirectory.empty() && !params.getDontSaveAdditional()) + { + //apply and zip changes + CZipFolderMemory oFolderWithChanges = CZipFolderMemory(); + for (std::vector::const_iterator i = changes.begin(); i != changes.end(); i++) + { + BYTE* pChangesData = NULL; + DWORD dwChangesSize = 0; + if (NSFile::CFileBinary::ReadAllBytes(*i, &pChangesData, dwChangesSize)) + { + //add changes to zip + std::wstring sFilename = NSSystemPath::GetFileName(*i); + oFolderWithChanges.write(sFilename, pChangesData, dwChangesSize); + } + } + //add images + //todo pDoctRenderer->GetImagesInChanges need or not? + std::wstring sImagesDirectory = combinePath(oConvertParams.m_sMediaDirectory, L"media"); + std::vector aImages = NSDirectory::GetFiles(sImagesDirectory); + for (std::vector::const_iterator i = aImages.begin(); i != aImages.end(); i++) + { + BYTE* pImageData = NULL; + DWORD dwImageSize = 0; + if (NSFile::CFileBinary::ReadAllBytes(*i, &pImageData, dwImageSize)) + { + std::wstring sFilename = NSSystemPath::GetFileName(*i); + oFolderWithChanges.write(sFilename, pImageData, dwImageSize); + } + } + //save changes.zip + IFolder::CBuffer* pBuffer = oFolderWithChanges.finalize(); + std::wstring sToChanges = combinePath(sResultDirectory, L"changes.zip"); + NSFile::CFileBinary oFile; + oFile.CreateFileW(sToChanges); + oFile.WriteFile(pBuffer->Buffer, pBuffer->Size); + oFile.CloseFile(); + RELEASEOBJECT(pBuffer); + } + + oPdfResult.Close(); + return true; + } + + _UINT32 fromCrossPlatform(const std::wstring& sFromSrc, int nFormatFrom, + const std::wstring& sTo_, int nFormatTo, + InputParams& params, ConvertParams& convertParams) + { + std::wstring sTo = sTo_; + _UINT32 nRes = 0; + NSFonts::IApplicationFonts *pApplicationFonts = createApplicationFonts(params); + + std::wstring sFrom = sFromSrc; + if (AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_PDF == nFormatFrom || + AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_PDFA == nFormatFrom) + { + if (params.getFromChanges()) + { + params.setFromChanges(false); + std::wstring sChangesDir = NSDirectory::GetFolderPath(sFrom) + FILE_SEPARATOR_STR + L"changes"; + std::vector arChanges = NSDirectory::GetFiles(sChangesDir); + + sFrom = NSFile::CFileBinary::CreateTempFileWithUniqueName(convertParams.m_sTempDir, L"PDF_"); + if (NSFile::CFileBinary::Exists(sFrom)) + NSFile::CFileBinary::Remove(sFrom); + + std::wstring sResultDirectory = NSDirectory::GetFolderPath(sTo); + if (!applyChangesPdf(sFromSrc, sFrom, pApplicationFonts, params, convertParams, arChanges, sResultDirectory)) + { + if (NSFile::CFileBinary::Exists(sFrom)) + NSFile::CFileBinary::Remove(sFrom); + + sFrom = sFromSrc; + } + } + } + + if (AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_PDF == nFormatTo) + { + std::string sPages = checkPrintPages(params); + + if (nFormatFrom == nFormatTo && !params.getIsPDFA()) + { + if (!sPages.empty()) + { + std::wstring sCurrentTmp = L""; + sCurrentTmp =NSFile::CFileBinary::CreateTempFileWithUniqueName(convertParams.m_sTempDir, L"PDF_"); + if (NSFile::CFileBinary::Exists(sCurrentTmp)) + NSFile::CFileBinary::Remove(sCurrentTmp); + + CPdfFile oPdfPages(pApplicationFonts); + oPdfPages.SetTempDirectory(convertParams.m_sTempDir); + + std::wstring sPassword = params.getPassword(); + if (oPdfPages.LoadFromFile(sFrom.c_str(), L"", sPassword, sPassword) && oPdfPages.EditPdf(sCurrentTmp)) + { + int nPagesCount = oPdfPages.GetPagesCount(); + std::vector arPages = getPrintPages(convertParams.m_sPrintPages, nPagesCount); + + for (int i = 0; i < nPagesCount; ++i) + { + if (!arPages[i]) + oPdfPages.DeletePage(i); + } + + oPdfPages.Close(); + } + else + { + sCurrentTmp = L""; + } + + if (!sCurrentTmp.empty()) + { + if (sFrom != sFromSrc) + { + NSFile::CFileBinary::Remove(sFrom); + } + sFrom = sCurrentTmp; + } + } + + if (params.getPassword() != params.getSavePassword()) + { + std::wstring sCurrentTmp = L""; + sCurrentTmp =NSFile::CFileBinary::CreateTempFileWithUniqueName(convertParams.m_sTempDir, L"PDF_"); + if (NSFile::CFileBinary::Exists(sCurrentTmp)) + NSFile::CFileBinary::Remove(sCurrentTmp); + + CPdfFile oPdfPages(pApplicationFonts); + oPdfPages.SetTempDirectory(convertParams.m_sTempDir); + + std::wstring sPassword = params.getPassword(); + if (oPdfPages.LoadFromFile(sFrom.c_str(), L"", sPassword, sPassword)) + { + oPdfPages.ChangePassword(sCurrentTmp, params.getSavePassword()); + oPdfPages.Close(); + } + else + { + sCurrentTmp = L""; + } + + if (!sCurrentTmp.empty()) + { + if (sFrom != sFromSrc) + { + NSFile::CFileBinary::Remove(sFrom); + } + sFrom = sCurrentTmp; + } + } + + if ((NULL == params.m_sJsonParams) || + (std::wstring::npos == params.m_sJsonParams->find(L"\"watermark\":"))) + { + if (sFrom == sFromSrc) + { + nRes = NSFile::CFileBinary::Copy(sFrom, sTo) ? 0 : AVS_FILEUTILS_ERROR_CONVERT; + } + else + { + nRes = NSFile::CFileBinary::Move(sFrom, sTo) ? 0 : AVS_FILEUTILS_ERROR_CONVERT; + } + } + else + { + NSDoctRenderer::CDoctrenderer oDoctRenderer(NULL != params.m_sAllFontsPath ? *params.m_sAllFontsPath : L""); + + std::wstring sWatermarkTmp = NSFile::CFileBinary::CreateTempFileWithUniqueName(convertParams.m_sTempDir, L"WWW_"); + if (NSFile::CFileBinary::Exists(sWatermarkTmp)) + NSFile::CFileBinary::Remove(sWatermarkTmp); + + std::wstring sXml = getDoctXml(NSDoctRenderer::DoctRendererFormat::DOCT, + NSDoctRenderer::DoctRendererFormat::WATERMARK, + L"", sWatermarkTmp, L"", convertParams.m_sThemesDir, -1, L"", params); + + std::wstring sResult = L""; + oDoctRenderer.Execute(sXml, sResult); + + if (sResult.empty()) + { + std::wstring password = params.getSavePassword(); + CPdfFile oPdfResult(pApplicationFonts); + if (!oPdfResult.LoadFromFile(sFrom, L"", password, password)) + return false; + + if (!oPdfResult.EditPdf(sTo)) + return false; + + Aggplus::CImage oImageW(sWatermarkTmp); + + double dW = 0, dH = 0, dDpiX = 0, dDpiY = 0; + + int nPagesCount = oPdfResult.GetPagesCount(); + for (int nPage = 0; nPage < nPagesCount; ++nPage) + { + oPdfResult.EditPage(nPage); + + oPdfResult.GetPageInfo(nPage, &dW, &dH, &dDpiX, &dDpiY); + + double dPageW_MM = dW * 25.4 / dDpiX; + double dPageH_MM = dH * 25.4 / dDpiY; + + double dImageW_MM = 25.4 * oImageW.GetWidth() / dDpiX; + double dImageH_MM = 25.4 * oImageW.GetHeight() / dDpiY; + + oPdfResult.DrawImage(&oImageW, (dPageW_MM - dImageW_MM) / 2, (dPageH_MM - dImageH_MM) / 2, dImageW_MM, dImageH_MM); + } + + oPdfResult.Close(); + } + + if (NSFile::CFileBinary::Exists(sWatermarkTmp)) + NSFile::CFileBinary::Remove(sWatermarkTmp); + } + sFrom = sFromSrc; + } + else + { + CPdfFile pdfWriter(pApplicationFonts); + pdfWriter.CreatePdf(params.getIsPDFA()); + pdfWriter.SetTempDirectory(convertParams.m_sTempDir); + pdfWriter.SetDocumentInfo(params.getTitle(), L"", L"", L""); + + std::wstring documentID = params.getDocumentID(); + if (false == documentID.empty()) + pdfWriter.SetDocumentID(documentID); + + std::wstring password = params.getSavePassword(); + if (!password.empty()) + pdfWriter.SetPassword(password); + + IOfficeDrawingFile *pReader = NULL; + convertParams.m_sPrintPages = sPages; + nRes = PdfDjvuXpsToRenderer(&pReader, &pdfWriter, sFrom, nFormatFrom, sTo, params, convertParams, pApplicationFonts); + if (SUCCEEDED_X2T(nRes)) + nRes = S_OK == pdfWriter.SaveToFile(sTo) ? 0 : AVS_FILEUTILS_ERROR_CONVERT; + RELEASEOBJECT(pReader); + } + } + else if (0 != (AVS_OFFICESTUDIO_FILE_CANVAS & nFormatTo) && params.needConvertToOrigin(nFormatFrom)) + { + //todo remove this code. copy outside x2t + copyOrigin(sFrom, *params.m_sFileTo); + } + else if (0 != (AVS_OFFICESTUDIO_FILE_IMAGE & nFormatTo)) + { + IOfficeDrawingFile *pReader = NULL; + nRes = PdfDjvuXpsToImage(&pReader, sFrom, nFormatFrom, sTo, params, convertParams, pApplicationFonts); + RELEASEOBJECT(pReader); + } + else + { + bool bChangeExt = false; + switch (nFormatTo) + { + case AVS_OFFICESTUDIO_FILE_OTHER_OOXML: + *params.m_nFormatTo = nFormatTo = AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX; bChangeExt = true; + break; + case AVS_OFFICESTUDIO_FILE_OTHER_ODF: + *params.m_nFormatTo = nFormatTo = AVS_OFFICESTUDIO_FILE_DOCUMENT_ODT; bChangeExt = true; + break; + } + if (bChangeExt) + { + size_t nIndex = sTo.rfind('.'); + COfficeFileFormatChecker FileFormatChecker; + if (-1 != nIndex) + sTo.replace(nIndex, std::wstring::npos, FileFormatChecker.GetExtensionByType(*params.m_nFormatTo)); + else + sTo.append(FileFormatChecker.GetExtensionByType(*params.m_nFormatTo)); + } + IOfficeDrawingFile *pReader = NULL; + switch (nFormatFrom) + { + case AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_PDF: + pReader = new CPdfFile(pApplicationFonts); + break; + case AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_XPS: + pReader = new CXpsFile(pApplicationFonts); + break; + case AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_DJVU: + pReader = new CDjVuFile(pApplicationFonts); + break; + default: + break; + } + + if (pReader) + { + pReader->SetTempDirectory(convertParams.m_sTempDir); + + std::wstring sPassword = params.getPassword(); + pReader->LoadFromFile(sFrom, L"", sPassword, sPassword); + + CDocxRenderer oDocxRenderer(pApplicationFonts); + + NSDocxRenderer::TextAssociationType taType = NSDocxRenderer::TextAssociationType::tatPlainLine; + if (params.m_oTextParams) + { + InputParamsText *oTextParams = params.m_oTextParams; + if (oTextParams->m_nTextAssociationType) + // taType = static_cast(*oTextParams->m_nTextAssociationType); + { + switch (*oTextParams->m_nTextAssociationType) + { + case 0: + taType = NSDocxRenderer::TextAssociationType::tatBlockChar; + break; + case 1: + taType = NSDocxRenderer::TextAssociationType::tatBlockLine; + break; + case 2: + taType = NSDocxRenderer::TextAssociationType::tatPlainLine; + break; + case 3: + taType = NSDocxRenderer::TextAssociationType::tatPlainParagraph; + break; + default: + break; + } + } + } + oDocxRenderer.SetTextAssociationType(taType); + + std::wstring sTempDirOut = combinePath(convertParams.m_sTempDir, L"output"); + if (!NSDirectory::Exists(sTempDirOut)) + NSDirectory::CreateDirectory(sTempDirOut); + + std::wstring sTempDirOutTmp = combinePath(convertParams.m_sTempDir, L"output_tmp"); + if (!NSDirectory::Exists(sTempDirOutTmp)) + NSDirectory::CreateDirectory(sTempDirOutTmp); + + oDocxRenderer.SetTempFolder(sTempDirOutTmp); + nRes = oDocxRenderer.Convert(pReader, sTempDirOut, false); + + if (nRes == S_OK) + nRes = fromDocxDir(sTempDirOut, sTo, nFormatTo, params, convertParams); + } + else + nRes = AVS_FILEUTILS_ERROR_CONVERT_PARAMS; + RELEASEOBJECT(pReader); + } + RELEASEOBJECT(pApplicationFonts); + + if (sFrom != sFromSrc && NSFile::CFileBinary::Exists(sFrom)) + NSFile::CFileBinary::Remove(sFrom); + return nRes; + } + _UINT32 fromCanvasPdf(const std::wstring& sFrom, int nFormatFrom, + const std::wstring& sTo, int nFormatTo, + InputParams& params, ConvertParams& convertParams) + { + _UINT32 nRes = 0; + if (AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_PDF == nFormatTo) + { + nRes = bin2pdf(sFrom, sTo, params, convertParams); + } + else if (0 != (AVS_OFFICESTUDIO_FILE_IMAGE & nFormatTo)) + { + nRes = bin2imageBase64(sFrom, sTo, params, convertParams); + } + else + { + nRes = AVS_FILEUTILS_ERROR_CONVERT_PARAMS; + } + return nRes; + } +} diff --git a/X2tConverter/src/lib/pdf_oform.h b/X2tConverter/src/lib/pdf_oform.h new file mode 100644 index 00000000000..24f54c2c358 --- /dev/null +++ b/X2tConverter/src/lib/pdf_oform.h @@ -0,0 +1,181 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#pragma once + +#include "../../../Common/OfficeFileFormatDefines.h" +#include "./pdf_image.h" + +namespace NExtractTools +{ + inline std::wstring GetMetaTag() + { + return NSFile::CUtf8Converter::GetUnicodeFromCharPtr(g_format_oform_pdf_meta_tag, + (LONG)strlen(g_format_oform_pdf_meta_tag)); + + } + + _UINT32 pdfoform2docx_dir(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + std::wstring sTempDocxInjected = combinePath(convertParams.m_sTempDir, L"meta.docx"); + std::wstring sTempDocx = sTempDocxInjected; + _UINT32 nRes = pdfoform2docx(sFrom, sTempDocx, params, convertParams); + + if (SUCCEEDED_X2T(nRes)) + { + COfficeFileFormatChecker OfficeFileFormatChecker; + if (OfficeFileFormatChecker.isOfficeFile(sTempDocxInjected)) + { + if (OfficeFileFormatChecker.nFileType == AVS_OFFICESTUDIO_FILE_OTHER_MS_OFFCRYPTO) + { + sTempDocx = combinePath(convertParams.m_sTempDir, L"uncrypt_file.oox"); + nRes = mscrypt2oox(sTempDocxInjected, sTempDocx, params, convertParams); + } + else if (OfficeFileFormatChecker.nFileType == AVS_OFFICESTUDIO_FILE_OTHER_MS_MITCRYPTO) + { + sTempDocx = combinePath(convertParams.m_sTempDir, L"uncrypt_file.oox"); + nRes = mitcrypt2oox(sTempDocxInjected, sTempDocx, params, convertParams); + } + } + } + + if (SUCCEEDED_X2T(nRes)) + { + COfficeUtils oOfficeUtils(NULL); + if (S_OK == oOfficeUtils.ExtractToDirectory(sTempDocx, sTo, NULL, 0)) + return 0; + + return AVS_FILEUTILS_ERROR_CONVERT; + } + + return nRes; + } + _UINT32 docx_dir2pdfoform(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + std::wstring sDocxMeta = combinePath(convertParams.m_sTempDir, L"meta.docx"); + + _UINT32 nRes = dir2zipMscrypt(sFrom, sDocxMeta, params, convertParams); + + if (!SUCCEEDED_X2T(nRes)) + return nRes; + + std::wstring sDoctDir = combinePath(convertParams.m_sTempDir, L"doct_pdf_unpacked"); + std::wstring sDoctMeta = combinePath(sDoctDir, L"Editor.bin"); + NSDirectory::CreateDirectory(sDoctDir); + + nRes = docx_dir2doct_bin(sFrom, sDoctMeta, params, convertParams); + + if (!SUCCEEDED_X2T(nRes)) + return nRes; + + convertParams.m_sPdfOformMetaName = GetMetaTag(); + convertParams.m_sPdfOformMetaData = sDocxMeta; + + nRes = doct_bin2pdf(NSDoctRenderer::DoctRendererFormat::DOCT, sDoctMeta, sTo, params, convertParams); + + convertParams.m_sPdfOformMetaName = L""; + convertParams.m_sPdfOformMetaData = L""; + + return nRes; + } + + _UINT32 pdfoform2doct_bin(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + std::wstring sDocxDir = combinePath(convertParams.m_sTempDir, L"docx_unpacked"); + NSDirectory::CreateDirectory(sDocxDir); + + _UINT32 nRes = pdfoform2docx_dir(sFrom, sDocxDir, params, convertParams); + if (SUCCEEDED_X2T(nRes)) + { + return docx_dir2doct_bin(sDocxDir, sTo, params, convertParams); + } + + return nRes; + } + + _UINT32 doct_bin2pdfoform(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + std::wstring sDocxMeta = combinePath(convertParams.m_sTempDir, L"meta.docx"); + + _UINT32 nRes = doct_bin2docx(sFrom, sDocxMeta, params, convertParams); + + if (!SUCCEEDED_X2T(nRes)) + return nRes; + + convertParams.m_sPdfOformMetaName = GetMetaTag(); + convertParams.m_sPdfOformMetaData = sDocxMeta; + + nRes = doct_bin2pdf(NSDoctRenderer::DoctRendererFormat::DOCT, sFrom, sTo, params, convertParams); + + convertParams.m_sPdfOformMetaName = L""; + convertParams.m_sPdfOformMetaData = L""; + + return nRes; + } + + _UINT32 pdfoform2docx(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + BYTE* pData = NULL; + DWORD dwDataSize = 0; + + std::wstring sMetaName = GetMetaTag(); + CPdfFile::GetMetaData(sFrom, sMetaName, &pData, dwDataSize); + + if (NULL == pData) + return AVS_FILEUTILS_ERROR_CONVERT; + + _UINT32 nRes = 0; + NSFile::CFileBinary oFile; + if (oFile.CreateFile(sTo)) + { + bool bIsOk = oFile.WriteFile(pData, dwDataSize); + oFile.CloseFile(); + nRes = bIsOk ? 0 : AVS_FILEUTILS_ERROR_CONVERT; + } + + RELEASEARRAYOBJECTS(pData); + return nRes; + } + _UINT32 docx2pdfoform(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return NSCommon::ooxml2format(sFrom, sTo, params, convertParams, L"docx", docx_dir2pdfoform); + } + + _UINT32 pdfoform2doct(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return NSCommon::format2oot(sFrom, sTo, params, convertParams, L"doct", pdfoform2doct_bin); + } + + _UINT32 doct2pdfoform(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return NSCommon::oot2format(sFrom, sTo, params, convertParams, L"doct", doct_bin2pdfoform); + } +} diff --git a/X2tConverter/src/lib/ppt.h b/X2tConverter/src/lib/ppt.h new file mode 100644 index 00000000000..6d7b7e51b72 --- /dev/null +++ b/X2tConverter/src/lib/ppt.h @@ -0,0 +1,103 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#pragma once + +#include "../../../MsBinaryFile/PptFile/Main/PPTFormatLib.h" +#include "../../OOXML/PPTXFormat/DrawingConverter/ASCOfficePPTXFile.h" +#include "common.h" + +namespace NExtractTools +{ + inline _UINT32 ppt2pptx_dir_macro(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams, const bool& bIsMacro) + { + COfficePPTFile pptFile; + pptFile.put_TempDirectory(convertParams.m_sTempDir); + + params.m_bMacro = bIsMacro; + long nRes = pptFile.LoadFromFile(sFrom, sTo, params.getPassword(), params.m_bMacro); + nRes = processEncryptionError(nRes, sFrom, params); + return nRes; + } + + _UINT32 ppt2pptx_dir(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return ppt2pptx_dir_macro(sFrom, sTo, params, convertParams, false); + } + _UINT32 ppt2pptm_dir(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return ppt2pptx_dir_macro(sFrom, sTo, params, convertParams, true); + } + + _UINT32 ppt2pptt_bin(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + // unzip pptx to temp folder + std::wstring sTempUnpackedPPTX = combinePath(convertParams.m_sTempDir, L"pptx_unpacked") + FILE_SEPARATOR_STR; // leading slash is very important! + NSDirectory::CreateDirectory(sTempUnpackedPPTX); + + COfficePPTFile pptFile; + pptFile.put_TempDirectory(convertParams.m_sTempDir); + + params.m_bMacro = true; + _UINT32 nRes = pptFile.LoadFromFile(sFrom, sTempUnpackedPPTX, params.getPassword(), params.m_bMacro); + + nRes = processEncryptionError(nRes, sFrom, params); + if (SUCCEEDED_X2T(nRes)) + { + // convert unzipped pptx to unzipped pptt + CPPTXFile *pptx_file = new CPPTXFile(); + + if (pptx_file) + { + pptx_file->SetFontDir(params.getFontPath()); + nRes = (S_OK == pptx_file->OpenFileToPPTY(sTempUnpackedPPTX, sTo)) ? nRes : AVS_FILEUTILS_ERROR_CONVERT; + + delete pptx_file; + } + return nRes; + } + return nRes; + } + + _UINT32 ppt2pptx(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return NSCommon::format2ooxml(sFrom, sTo, params, convertParams, L"pptx", ppt2pptx_dir); + } + _UINT32 ppt2pptm(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return NSCommon::format2ooxml(sFrom, sTo, params, convertParams, L"pptx", ppt2pptm_dir); + } + + _UINT32 ppt2pptt(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return NSCommon::format2oot(sFrom, sTo, params, convertParams, L"pptt", ppt2pptt_bin); + } +} diff --git a/X2tConverter/src/lib/pptx.h b/X2tConverter/src/lib/pptx.h new file mode 100644 index 00000000000..9da4314f32f --- /dev/null +++ b/X2tConverter/src/lib/pptx.h @@ -0,0 +1,252 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#pragma once + +#include "../../OOXML/PPTXFormat/DrawingConverter/ASCOfficePPTXFile.h" +#include "common.h" + +namespace NExtractTools +{ + _UINT32 pptx2pptt_bin(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + // unzip pptx to temp folder + std::wstring sTempUnpackedPPTX = combinePath(convertParams.m_sTempDir, L"pptx_unpacked"); + NSDirectory::CreateDirectory(sTempUnpackedPPTX); + + // unzip pptx to folder + COfficeUtils oCOfficeUtils(NULL); + if (S_OK != oCOfficeUtils.ExtractToDirectory(sFrom, sTempUnpackedPPTX, NULL, 0)) + { + // check crypt + COfficeFileFormatChecker OfficeFileFormatChecker; + if (OfficeFileFormatChecker.isOfficeFile(sFrom)) + { + if (OfficeFileFormatChecker.nFileType == AVS_OFFICESTUDIO_FILE_OTHER_MS_OFFCRYPTO) + return mscrypt2oot_bin(sFrom, sTo, params, convertParams); + else if (OfficeFileFormatChecker.nFileType == AVS_OFFICESTUDIO_FILE_OTHER_MS_MITCRYPTO) + return mitcrypt2oot_bin(sFrom, sTo, params, convertParams); + else + { + if (create_if_empty(sFrom, sTo, L"PPTY;v10;0;")) + return 0; + return AVS_FILEUTILS_ERROR_CONVERT; + } + } + else + return AVS_FILEUTILS_ERROR_CONVERT; + } + + convertParams.m_sTempParamOOXMLFile = sFrom; + return pptx_dir2pptt_bin(sTempUnpackedPPTX, sTo, params, convertParams); + } + _UINT32 pptx_dir2pptt(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return NSCommon::format2oot(sFrom, sTo, params, convertParams, L"pptt", pptx_dir2pptt_bin); + } + _UINT32 pptx_dir2pptt_bin(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + _UINT32 nRes = 0; + std::wstring sToDir = NSDirectory::GetFolderPath(sTo); + if (params.needConvertToOrigin(AVS_OFFICESTUDIO_FILE_PRESENTATION_PPTX) && !convertParams.m_sTempParamOOXMLFile.empty()) + { + nRes = CopyOOXOrigin(sToDir, sFrom, L"origin.pptx", convertParams.m_sTempParamOOXMLFile); + } + else + { + // convert unzipped pptx to unzipped pptt + CPPTXFile *pptx_file = new CPPTXFile(); + + if (pptx_file) + { + pptx_file->SetIsNoBase64(params.getIsNoBase64()); + pptx_file->put_TempDirectory(convertParams.m_sTempDir); + pptx_file->SetFontDir(params.getFontPath()); + nRes = (S_OK == pptx_file->OpenFileToPPTY(sFrom, sTo)) ? nRes : AVS_FILEUTILS_ERROR_CONVERT; + + delete pptx_file; + } + } + + convertParams.m_sTempParamOOXMLFile = L""; + return nRes; + } + _UINT32 pptx2pptt(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return NSCommon::format2oot(sFrom, sTo, params, convertParams, L"pptt", pptx2pptt_bin); + } + _UINT32 pptt_bin2pptx(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + std::wstring sResultPptxDir = combinePath(convertParams.m_sTempDir, L"pptx_unpacked"); + NSDirectory::CreateDirectory(sResultPptxDir); + + convertParams.m_sTempResultOOXMLDirectory = sResultPptxDir; + _UINT32 nRes = pptt_bin2pptx_dir(sFrom, sTo, params, convertParams); + + if (SUCCEEDED_X2T(nRes) && params.m_nFormatTo) + { + if (AVS_OFFICESTUDIO_FILE_PRESENTATION_PPTM == *params.m_nFormatTo || + AVS_OFFICESTUDIO_FILE_PRESENTATION_PPSX == *params.m_nFormatTo || + AVS_OFFICESTUDIO_FILE_PRESENTATION_POTX == *params.m_nFormatTo || + AVS_OFFICESTUDIO_FILE_PRESENTATION_POTM == *params.m_nFormatTo || + AVS_OFFICESTUDIO_FILE_PRESENTATION_PPSM == *params.m_nFormatTo) + { + std::wstring sCTFrom = _T("application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml"); + std::wstring sCTTo; + switch (*params.m_nFormatTo) + { + case AVS_OFFICESTUDIO_FILE_PRESENTATION_PPTM: + sCTTo = _T("application/vnd.ms-powerpoint.presentation.macroEnabled.main+xml"); + break; + case AVS_OFFICESTUDIO_FILE_PRESENTATION_PPSX: + sCTTo = _T("application/vnd.openxmlformats-officedocument.presentationml.slideshow.main+xml"); + break; + case AVS_OFFICESTUDIO_FILE_PRESENTATION_POTX: + sCTTo = _T("application/vnd.openxmlformats-officedocument.presentationml.template.main+xml"); + break; + case AVS_OFFICESTUDIO_FILE_PRESENTATION_POTM: + sCTTo = _T("application/vnd.ms-powerpoint.template.macroEnabled.main+xml"); + break; + case AVS_OFFICESTUDIO_FILE_PRESENTATION_PPSM: + sCTTo = _T("application/vnd.ms-powerpoint.slideshow.macroEnabled.main+xml"); + break; + } + nRes = replaceContentType(sResultPptxDir, sCTFrom, sCTTo); + } + } + if (SUCCEEDED_X2T(nRes)) + { + nRes = dir2zipMscrypt(sResultPptxDir, sTo, params, convertParams); + } + return nRes; + } + _UINT32 pptt_bin2pptx_dir(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + _UINT32 nRes = 0; + + std::wstring sTargetBin; + if (params.getFromChanges()) + { + params.setFromChanges(false); + nRes = apply_changes(sFrom, sTo, NSDoctRenderer::DoctRendererFormat::FormatFile::PPTT, sTargetBin, params, convertParams); + } + else + sTargetBin = sFrom; + + CPPTXFile *pptx_file = new CPPTXFile(); + if (pptx_file) + { + pptx_file->SetMacroEnabled(params.m_bMacro); + pptx_file->SetIsNoBase64(params.getIsNoBase64()); + pptx_file->SetFontDir(params.getFontPath()); + nRes = (S_OK == pptx_file->ConvertPPTYToPPTX(sTargetBin, convertParams.m_sTempResultOOXMLDirectory, convertParams.m_sThemesDir)) ? nRes : AVS_FILEUTILS_ERROR_CONVERT; + + params.m_bMacro = pptx_file->GetMacroEnabled(); + delete pptx_file; + } + // удаляем EditorWithChanges, потому что он не в Temp + if (sFrom != sTargetBin) + NSFile::CFileBinary::Remove(sTargetBin); + + convertParams.m_sTempResultOOXMLDirectory = L""; + return nRes; + } + _UINT32 pptt2pptx(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return NSCommon::oot2format(sFrom, sTo, params, convertParams, L"pptt", pptt_bin2pptx); + } + + _UINT32 ppsx2pptx(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return NSCommon::ooxml2ooxml(sFrom, sTo, params, convertParams, L"pptx", ppsx2pptx_dir); + } + _UINT32 ppsx2pptx_dir(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return NSCommon::ooxml2ooxml_replace_content_type(sFrom, sTo, params, convertParams, + L"application/vnd.openxmlformats-officedocument.presentationml.slideshow.main+xml", + L"application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml"); + } + _UINT32 potx2pptx(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return NSCommon::ooxml2ooxml(sFrom, sTo, params, convertParams, L"pptx", potx2pptx_dir); + } + _UINT32 potx2pptx_dir(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return NSCommon::ooxml2ooxml_replace_content_type(sFrom, sTo, params, convertParams, + L"application/vnd.openxmlformats-officedocument.presentationml.template.main+xml", + L"application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml"); + } + _UINT32 ppsm2pptx(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return NSCommon::ooxml2ooxml(sFrom, sTo, params, convertParams, L"pptx", ppsm2pptx_dir); + } + _UINT32 ppsm2pptx_dir(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return NSCommon::ooxmlm2ooml_dir(sFrom, sTo, params, convertParams, NSCommon::OOXML_DOCUMENT_TYPE::Slide, NSCommon::OOXML_DOCUMENT_SUBTYPE::Show); + } + _UINT32 potm2pptm(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return NSCommon::ooxml2ooxml(sFrom, sTo, params, convertParams, L"pptx", potm2pptm_dir); + } + _UINT32 potm2pptm_dir(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return NSCommon::ooxml2ooxml_replace_content_type(sFrom, sTo, params, convertParams, + L"application/vnd.ms-powerpoint.template.macroEnabled.main+xml", + L"application/vnd.ms-powerpoint.presentation.macroEnabled.main+xml"); + } + _UINT32 ppsm2pptm(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return NSCommon::ooxml2ooxml(sFrom, sTo, params, convertParams, L"pptm", ppsm2pptm_dir); + } + _UINT32 ppsm2pptm_dir(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return NSCommon::ooxml2ooxml_replace_content_type(sFrom, sTo, params, convertParams, + L"application/vnd.ms-powerpoint.slideshow.macroEnabled.main+xml", + L"application/vnd.ms-powerpoint.presentation.macroEnabled.main+xml"); + } + _UINT32 pptm2pptx(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return NSCommon::ooxml2ooxml(sFrom, sTo, params, convertParams, L"pptm", pptm2pptx_dir); + } + _UINT32 pptm2pptx_dir(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return NSCommon::ooxmlm2ooml_dir(sFrom, sTo, params, convertParams, NSCommon::OOXML_DOCUMENT_TYPE::Slide, NSCommon::OOXML_DOCUMENT_SUBTYPE::Main); + } + _UINT32 potm2pptx(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return NSCommon::ooxml2ooxml(sFrom, sTo, params, convertParams, L"pptx", potm2pptx_dir); + } + _UINT32 potm2pptx_dir(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return NSCommon::ooxmlm2ooml_dir(sFrom, sTo, params, convertParams, NSCommon::OOXML_DOCUMENT_TYPE::Slide, NSCommon::OOXML_DOCUMENT_SUBTYPE::Template); + } + +} diff --git a/X2tConverter/src/lib/rtf.h b/X2tConverter/src/lib/rtf.h new file mode 100644 index 00000000000..f9fffb71ef6 --- /dev/null +++ b/X2tConverter/src/lib/rtf.h @@ -0,0 +1,151 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#pragma once + +#include "../../../RtfFile/Format/ConvertationManager.h" +#include "../../../OOXML/Binary/Document/DocWrapper/DocxSerializer.h" +#include "common.h" + +namespace NExtractTools +{ + _UINT32 rtf2docx_dir(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + params.m_bMacro = false; + + RtfConvertationManager rtfConvert; + + rtfConvert.m_sTempFolder = convertParams.m_sTempDir; + rtfConvert.m_nUserLCID = (NULL != params.m_nLcid) ? *params.m_nLcid : -1; + + return 0 == rtfConvert.ConvertRtfToOOX(sFrom, sTo) ? 0 : AVS_FILEUTILS_ERROR_CONVERT; + } + _UINT32 docx_dir2rtf(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + // docx folder to rtf + RtfConvertationManager rtfConvert; + rtfConvert.m_sTempFolder = convertParams.m_sTempDir; + rtfConvert.m_nUserLCID = (NULL != params.m_nLcid) ? *params.m_nLcid : -1; + + if (rtfConvert.ConvertOOXToRtf(sTo, sFrom) == 0) + return 0; + return AVS_FILEUTILS_ERROR_CONVERT; + } + + _UINT32 rtf2doct_bin(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + params.m_bMacro = false; + + std::wstring sResultDocxDir = combinePath(convertParams.m_sTempDir, L"docx_unpacked"); + NSDirectory::CreateDirectory(sResultDocxDir); + + RtfConvertationManager rtfConvert; + rtfConvert.m_sTempFolder = convertParams.m_sTempDir; + rtfConvert.m_nUserLCID = (NULL != params.m_nLcid) ? *params.m_nLcid : -1; + + if (rtfConvert.ConvertRtfToOOX(sFrom, sResultDocxDir) == 0) + { + BinDocxRW::CDocxSerializer m_oCDocxSerializer; + + m_oCDocxSerializer.setFontDir(params.getFontPath()); + + std::wstring sXmlOptions; + _UINT32 res = m_oCDocxSerializer.saveToFile(sTo, sResultDocxDir, sXmlOptions, convertParams.m_sTempDir) ? 0 : AVS_FILEUTILS_ERROR_CONVERT; + + return res; + } + return AVS_FILEUTILS_ERROR_CONVERT; + } + _UINT32 doct_bin2rtf(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + _UINT32 nRes = 0; + std::wstring sResultDocxDir = combinePath(convertParams.m_sTempDir, L"docx_unpacked"); + NSDirectory::CreateDirectory(sResultDocxDir); + + std::wstring sTargetBin; + if (params.getFromChanges()) + { + params.setFromChanges(false); + nRes = apply_changes(sFrom, L"", NSDoctRenderer::DoctRendererFormat::FormatFile::DOCT, sTargetBin, params, convertParams); + } + else + sTargetBin = sFrom; + + BinDocxRW::CDocxSerializer m_oCDocxSerializer; + + m_oCDocxSerializer.setFontDir(params.getFontPath()); + + std::wstring sXmlOptions = _T(""); + std::wstring sThemePath; // will be filled by 'CreateDocxFolders' method + std::wstring sMediaPath; // will be filled by 'CreateDocxFolders' method + std::wstring sEmbedPath; // will be filled by 'CreateDocxFolders' method + + m_oCDocxSerializer.CreateDocxFolders(sResultDocxDir, sThemePath, sMediaPath, sEmbedPath); + + if (SUCCEEDED_X2T(nRes)) + { + nRes = m_oCDocxSerializer.loadFromFile(sTargetBin, sResultDocxDir, sXmlOptions, sThemePath, sMediaPath, sEmbedPath) ? nRes : AVS_FILEUTILS_ERROR_CONVERT; + if (SUCCEEDED_X2T(nRes)) + { + // docx folder to rtf + RtfConvertationManager rtfConvert; + + rtfConvert.m_sTempFolder = convertParams.m_sTempDir; + rtfConvert.m_nUserLCID = (NULL != params.m_nLcid) ? *params.m_nLcid : -1; + + nRes = rtfConvert.ConvertOOXToRtf(sTo, sResultDocxDir); + } + } + // удаляем EditorWithChanges, потому что он не в Temp + if (sFrom != sTargetBin) + NSFile::CFileBinary::Remove(sTargetBin); + return nRes; + } + + // no dir method + _UINT32 rtf2docx(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return NSCommon::format2ooxml(sFrom, sTo, params, convertParams, L"docx", rtf2docx_dir); + } + _UINT32 docx2rtf(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return NSCommon::ooxml2format(sFrom, sTo, params, convertParams, L"docx", docx_dir2rtf); + } + + _UINT32 rtf2doct(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return NSCommon::format2oot(sFrom, sTo, params, convertParams, L"doct", rtf2doct_bin); + } + _UINT32 doct2rtf(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return NSCommon::oot2format(sFrom, sTo, params, convertParams, L"doct", doct_bin2rtf); + } +} diff --git a/X2tConverter/src/lib/txt.h b/X2tConverter/src/lib/txt.h new file mode 100644 index 00000000000..d525f080b88 --- /dev/null +++ b/X2tConverter/src/lib/txt.h @@ -0,0 +1,84 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#pragma once + +#include "../../../TxtFile/Source/TxtXmlFile.h" +#include "../../../OOXML/Binary/Document/DocWrapper/DocxSerializer.h" +#include "common.h" + +namespace NExtractTools +{ + _UINT32 txt2docx_dir(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + params.m_bMacro = false; + + CTxtXmlFile txtFile; + std::wstring xml_options = params.getXmlOptions(); + return txtFile.txt_LoadFromFile(sFrom, sTo, xml_options); + } + _UINT32 docx_dir2txt(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + CTxtXmlFile txtFile; + return txtFile.txt_SaveToFile(sTo, sFrom, params.getXmlOptions()); + } + + _UINT32 txt2doct_bin(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + std::wstring sResultDocxDir = combinePath(convertParams.m_sTempDir, L"docx_unpacked"); + NSDirectory::CreateDirectory(sResultDocxDir); + + CTxtXmlFile txtFile; + params.m_bMacro = false; + + _UINT32 nRes = txtFile.txt_LoadFromFile(sFrom, sResultDocxDir, params.getXmlOptions()); + if (SUCCEEDED_X2T(nRes)) + { + BinDocxRW::CDocxSerializer m_oCDocxSerializer; + nRes = m_oCDocxSerializer.saveToFile(sTo, sResultDocxDir, params.getXmlOptions(), convertParams.m_sTempDir) ? 0 : AVS_FILEUTILS_ERROR_CONVERT; + } + return nRes; + } + + _UINT32 txt2docx(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return NSCommon::format2ooxml(sFrom, sTo, params, convertParams, L"docx", txt2docx_dir); + } + _UINT32 docx2txt(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return NSCommon::ooxml2format(sFrom, sTo, params, convertParams, L"docx", docx_dir2txt); + } + + _UINT32 txt2doct(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return NSCommon::format2oot(sFrom, sTo, params, convertParams, L"doct", txt2doct_bin); + } +} diff --git a/X2tConverter/src/lib/xls.h b/X2tConverter/src/lib/xls.h new file mode 100644 index 00000000000..82e15c38acf --- /dev/null +++ b/X2tConverter/src/lib/xls.h @@ -0,0 +1,96 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#pragma once + +#include "../../../MsBinaryFile/XlsFile/Converter/ConvertXls2Xlsx.h" +#include "../../../OOXML/Binary/Document/DocWrapper/XlsxSerializer.h" +#include "common.h" + +namespace NExtractTools +{ + _UINT32 xls2xlsm_dir_macro(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams, const bool& bIsMacro) + { + params.m_bMacro = bIsMacro; + + int lcid = (NULL != params.m_nLcid) ? *params.m_nLcid : -1; + + _UINT32 nRes = ConvertXls2Xlsx(sFrom, sTo, params.getPassword(), params.getFontPath(), convertParams.m_sTempDir, lcid, params.m_bMacro); + + nRes = processEncryptionError(nRes, sFrom, params); + return nRes; + } + _UINT32 xls2xlsx_dir(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return xls2xlsm_dir_macro(sFrom, sTo, params, convertParams, false); + } + _UINT32 xls2xlsm_dir(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return xls2xlsm_dir_macro(sFrom, sTo, params, convertParams, true); + } + + _UINT32 xls2xlst_bin(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + std::wstring sResultXlsxDir = combinePath(convertParams.m_sTempDir, L"xlsx_unpacked"); + NSDirectory::CreateDirectory(sResultXlsxDir); + + params.m_bMacro = true; + + int lcid = (NULL != params.m_nLcid) ? *params.m_nLcid : -1; + + _UINT32 nRes = ConvertXls2Xlsx(sFrom, sResultXlsxDir, params.getPassword(), params.getFontPath(), convertParams.m_sTempDir, lcid, params.m_bMacro); + + nRes = processEncryptionError(nRes, sFrom, params); + if (SUCCEEDED_X2T(nRes)) + { + BinXlsxRW::CXlsxSerializer oCXlsxSerializer; + + oCXlsxSerializer.setFontDir(params.getFontPath()); + + return oCXlsxSerializer.saveToFile(sTo, sResultXlsxDir, params.getXmlOptions()); + } + return nRes; + } + + _UINT32 xls2xlsx(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return NSCommon::format2ooxml(sFrom, sTo, params, convertParams, L"xlsx", xls2xlsx_dir); + } + _UINT32 xls2xlsm(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return NSCommon::ooxml2ooxml(sFrom, sTo, params, convertParams, L"xlsm", xls2xlsm_dir); + } + + _UINT32 xls2xlst(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return NSCommon::format2oot(sFrom, sTo, params, convertParams, L"xlst", xls2xlst_bin); + } +} diff --git a/X2tConverter/src/lib/xlsx.h b/X2tConverter/src/lib/xlsx.h new file mode 100644 index 00000000000..2e82444d641 --- /dev/null +++ b/X2tConverter/src/lib/xlsx.h @@ -0,0 +1,416 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#pragma once + +#include "../../../OOXML/XlsbFormat/Xlsb.h" +#include "../../../OOXML/Binary/Document/DocWrapper/XlsxSerializer.h" +#include "../../../OOXML/Binary/Sheets/Reader/XMLReader/XMLReader.h" +#include "../../../MsBinaryFile/XlsFile/Format/Logic/GlobalWorkbookInfo.h" + +#include "common.h" + +namespace NExtractTools +{ + _UINT32 xlsx2xlst(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return NSCommon::format2oot(sFrom, sTo, params, convertParams, L"xlst", xlsx2xlst_bin); + } + _UINT32 xlsx2xlst_bin(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + // Extract xlsx to temp directory + std::wstring sTempUnpackedXLSX = combinePath(convertParams.m_sTempDir, L"xlsx_unpacked"); + NSDirectory::CreateDirectory(sTempUnpackedXLSX); + + COfficeUtils oCOfficeUtils(NULL); + if (S_OK != oCOfficeUtils.ExtractToDirectory(sFrom, sTempUnpackedXLSX, NULL, 0)) + { + //check crypt + COfficeFileFormatChecker OfficeFileFormatChecker; + if (OfficeFileFormatChecker.isOfficeFile(sFrom)) + { + if (OfficeFileFormatChecker.nFileType == AVS_OFFICESTUDIO_FILE_OTHER_MS_OFFCRYPTO) + { + // test protect + bool isOldPassword = params.hasPassword(); + const std::wstring sOldPassword = params.getPassword(); + + if (isOldPassword) + delete params.m_sPassword; + params.m_sPassword = new std::wstring(L"VelvetSweatshop"); + + _UINT32 nRes = mscrypt2oot_bin(sFrom, sTo, params, convertParams); + if (SUCCEEDED_X2T(nRes)) + { + return nRes; + } + else + { + delete params.m_sPassword; + if (isOldPassword) + params.m_sPassword = new std::wstring(sOldPassword); + return mscrypt2oot_bin(sFrom, sTo, params, convertParams); + } + } + else if (OfficeFileFormatChecker.nFileType == AVS_OFFICESTUDIO_FILE_OTHER_MS_MITCRYPTO) + return mitcrypt2oot_bin(sFrom, sTo, params, convertParams); + else + { + if (create_if_empty(sFrom, sTo, L"XLSY;v10;0;")) + return 0; + return AVS_FILEUTILS_ERROR_CONVERT; + } + } + else + return AVS_FILEUTILS_ERROR_CONVERT; + } + + convertParams.m_bTempIsXmlOptions = true; + convertParams.m_sTempParamOOXMLFile = sFrom; + return xlsx_dir2xlst_bin(sTempUnpackedXLSX, sTo, params, convertParams); + } + _UINT32 xlsxflat2xlst(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return NSCommon::format2oot(sFrom, sTo, params, convertParams, L"xlst", xlsxflat2xlst_bin); + } + _UINT32 xlsxflat2xlst_bin(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + BinXlsxRW::CXlsxSerializer oCXlsxSerializer; + + oCXlsxSerializer.setIsNoBase64(params.getIsNoBase64()); + oCXlsxSerializer.setFontDir(params.getFontPath()); + + return oCXlsxSerializer.saveToFile(sTo, sFrom, params.getXmlOptions()); + } + _UINT32 xlsxflat2xlsx(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return NSCommon::ooxml2ooxml(sFrom, sTo, params, convertParams, L"xlsx", xlsxflat2xlsx_dir); + } + _UINT32 xlsxflat2xlsx_dir(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + params.m_bMacro = false; + BinXlsxRW::CXlsxSerializer oCXlsxSerializer; + + oCXlsxSerializer.setIsNoBase64(params.getIsNoBase64()); + oCXlsxSerializer.setFontDir(params.getFontPath()); + oCXlsxSerializer.setMacroEnabled(params.m_bMacro); + + _UINT32 nRes = oCXlsxSerializer.xml2Xlsx(sFrom, sTo, params.getXmlOptions()); + + return nRes; + } + _UINT32 xlsx_dir2xlst(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return NSCommon::format2oot(sFrom, sTo, params, convertParams, L"xlst", xlsx_dir2xlst_bin); + } + _UINT32 xlsx_dir2xlst_bin(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + _UINT32 nRes = S_OK; + std::wstring sToDir = NSDirectory::GetFolderPath(sTo); + if (params.needConvertToOrigin(AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSX) && !convertParams.m_sTempParamOOXMLFile.empty()) + { + nRes = CopyOOXOrigin(sToDir, sFrom, L"origin.xlsx", convertParams.m_sTempParamOOXMLFile); + } + else + { + BinXlsxRW::CXlsxSerializer oCXlsxSerializer; + if (oCXlsxSerializer.hasPivot(sFrom)) + { + // save Editor.xlsx for pivot + nRes = CopyOOXOrigin(sToDir, sFrom, L"Editor.xlsx", convertParams.m_sTempParamOOXMLFile); + } + + // Save to file (from temp dir) + oCXlsxSerializer.setIsNoBase64(params.getIsNoBase64()); + oCXlsxSerializer.setFontDir(params.getFontPath()); + + nRes = oCXlsxSerializer.saveToFile(sTo, sFrom, convertParams.m_bTempIsXmlOptions ? params.getXmlOptions() : L""); + } + + convertParams.m_sTempParamOOXMLFile = L""; + convertParams.m_bTempIsXmlOptions = false; + return nRes; + } + _UINT32 xlsx_dir2xlsb_dir(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + const OOX::CPath oox_path(sFrom); + + OOX::Spreadsheet::CXlsb oXlsb; + oXlsb.m_bWriteToXlsb = true; + oXlsb.Read(oox_path); + oXlsb.LinkTables(); + oXlsb.PrepareRichStr(); + + OOX::CContentTypes oContentTypes; + oXlsb.SetPropForWriteSheet(sTo, oContentTypes); + oXlsb.WriteSheetData(); + _UINT32 nRes = oXlsb.WriteBin(sTo, oContentTypes) ? S_OK : AVS_FILEUTILS_ERROR_CONVERT; + + return nRes; + } + _UINT32 xlst_bin2xlsb_dir(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + std::wstring sTempUnpackedXLSX = combinePath(convertParams.m_sTempDir, L"xlsx_unpacked"); + NSDirectory::CreateDirectory(sTempUnpackedXLSX); + + _UINT32 nRes = 0; + + std::wstring sTargetBin; + if (params.getFromChanges()) + { + params.setFromChanges(false); + nRes = apply_changes(sFrom, sTo, NSDoctRenderer::DoctRendererFormat::FormatFile::XLST, sTargetBin, params, convertParams); + } + else + sTargetBin = sFrom; + + std::wstring sTempUnpackedXLSB = convertParams.m_sTempResultOOXMLDirectory; + + convertParams.m_sTempResultOOXMLDirectory = sTempUnpackedXLSX; + nRes = xlst_bin2xlsx_dir(sTargetBin, sTempUnpackedXLSX, params, convertParams); + + if (SUCCEEDED_X2T(nRes)) + { + convertParams.m_sTempResultOOXMLDirectory = sTempUnpackedXLSB; + nRes = xlsx_dir2xlsb_dir(sTempUnpackedXLSX, sTempUnpackedXLSB, params, convertParams); + } + // удаляем EditorWithChanges, потому что он не в Temp + if (sFrom != sTargetBin) + NSFile::CFileBinary::Remove(sTargetBin); + return nRes; + } + _UINT32 xlst_bin2xlsb(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + // Extract xlsx to temp directory + std::wstring sResultXlsxDir = combinePath(convertParams.m_sTempDir, L"xlsb_unpacked"); + NSDirectory::CreateDirectory(sResultXlsxDir); + + convertParams.m_sTempResultOOXMLDirectory = sResultXlsxDir; + _UINT32 nRes = xlst_bin2xlsb_dir(sFrom, sTo, params, convertParams); + + if (SUCCEEDED_X2T(nRes) && params.m_nFormatTo) + { + nRes = dir2zipMscrypt(sResultXlsxDir, sTo, params, convertParams); + } + return nRes; + } + _UINT32 xlst_bin2xlsx(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + // Extract xlsx to temp directory + std::wstring sResultXlsxDir = combinePath(convertParams.m_sTempDir, L"xlsx_unpacked"); + NSDirectory::CreateDirectory(sResultXlsxDir); + + convertParams.m_sTempResultOOXMLDirectory = sResultXlsxDir; + _UINT32 nRes = xlst_bin2xlsx_dir(sFrom, sTo, params, convertParams); + + if (SUCCEEDED_X2T(nRes) && params.m_nFormatTo) + { + if (AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSM == *params.m_nFormatTo || + AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLTX == *params.m_nFormatTo || + AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLTM == *params.m_nFormatTo) + { + std::wstring sCTFrom = _T("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml"); + std::wstring sCTTo; + switch (*params.m_nFormatTo) + { + case AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSM: + sCTTo = _T("application/vnd.ms-excel.sheet.macroEnabled.main+xml"); + break; + case AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLTX: + sCTTo = _T("application/vnd.openxmlformats-officedocument.spreadsheetml.template.main+xml"); + break; + case AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLTM: + sCTTo = _T("application/vnd.ms-excel.template.macroEnabled.main+xml"); + break; + } + nRes = replaceContentType(sResultXlsxDir, sCTFrom, sCTTo); + } + } + if (SUCCEEDED_X2T(nRes)) + { + nRes = dir2zipMscrypt(sResultXlsxDir, sTo, params, convertParams); + } + return nRes; + } + _UINT32 xlst_bin2xlsx_dir(const std::wstring& sFrom, const std::wstring &sTo, InputParams& params, ConvertParams& convertParams) + { + _UINT32 nRes = 0; + + std::wstring sTargetBin; + if (params.getFromChanges()) + { + params.setFromChanges(false); + nRes = apply_changes(sFrom, sTo, NSDoctRenderer::DoctRendererFormat::FormatFile::XLST, sTargetBin, params, convertParams); + } + else + sTargetBin = sFrom; + + BinXlsxRW::CXlsxSerializer oCXlsxSerializer; + + oCXlsxSerializer.setMacroEnabled(params.m_bMacro); + oCXlsxSerializer.setIsNoBase64(params.getIsNoBase64()); + oCXlsxSerializer.setFontDir(params.getFontPath()); + + std::wstring sXmlOptions = _T(""); + std::wstring sMediaPath; // will be filled by 'CreateXlsxFolders' method + std::wstring sEmbedPath; // will be filled by 'CreateXlsxFolders' method + + oCXlsxSerializer.CreateXlsxFolders(sXmlOptions, convertParams.m_sTempResultOOXMLDirectory, sMediaPath, sEmbedPath); + + if (SUCCEEDED_X2T(nRes)) + { + nRes = oCXlsxSerializer.loadFromFile(sTargetBin, convertParams.m_sTempResultOOXMLDirectory, sXmlOptions, sMediaPath, sEmbedPath); + params.m_bMacro = oCXlsxSerializer.getMacroEnabled(); + } + // удаляем EditorWithChanges, потому что он не в Temp + if (sFrom != sTargetBin) + NSFile::CFileBinary::Remove(sTargetBin); + + convertParams.m_sTempResultOOXMLDirectory = L""; + return nRes; + } + _UINT32 xlst2xlsx(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return NSCommon::oot2format(sFrom, sTo, params, convertParams, L"xlst", xlst_bin2xlsx); + } + + _UINT32 xlst2xlsb(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return NSCommon::oot2format(sFrom, sTo, params, convertParams, L"xlst", xlst_bin2xlsb); + } + _UINT32 xltx2xlsx(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return NSCommon::ooxml2ooxml(sFrom, sTo, params, convertParams, L"xlsx", xltx2xlsx_dir); + } + _UINT32 xltx2xlsx_dir(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + params.m_bMacro = false; + return NSCommon::ooxml2ooxml_replace_content_type(sFrom, sTo, params, convertParams, + L"application/vnd.openxmlformats-officedocument.spreadsheetml.template.main+xml", + L"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml"); + } + _UINT32 xltm2xlsm(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return NSCommon::ooxml2ooxml(sFrom, sTo, params, convertParams, L"xlsm", xltm2xlsm_dir); + } + _UINT32 xltm2xlsm_dir(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return NSCommon::ooxml2ooxml_replace_content_type(sFrom, sTo, params, convertParams, + L"application/vnd.ms-excel.template.macroEnabled.main+xml", + L"application/vnd.ms-excel.sheet.macroEnabled.main+xml"); + } + _UINT32 xlsm2xlsx(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return NSCommon::ooxml2ooxml(sFrom, sTo, params, convertParams, L"xlsx", xlsm2xlsx_dir); + } + _UINT32 xlsm2xlsx_dir(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return NSCommon::ooxmlm2ooml_dir(sFrom, sTo, params, convertParams, NSCommon::OOXML_DOCUMENT_TYPE::Sheet, NSCommon::OOXML_DOCUMENT_SUBTYPE::Main); + } + _UINT32 xltm2xlsx(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return NSCommon::ooxml2ooxml(sFrom, sTo, params, convertParams, L"xlsx", xltm2xlsx_dir); + } + _UINT32 xltm2xlsx_dir(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return NSCommon::ooxmlm2ooml_dir(sFrom, sTo, params, convertParams, NSCommon::OOXML_DOCUMENT_TYPE::Sheet, NSCommon::OOXML_DOCUMENT_SUBTYPE::Template); + } + _UINT32 xlsb2xlsx_dir(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + std::wstring sTempUnpackedXLSB = combinePath(convertParams.m_sTempDir, L"xlsb_unpacked"); + NSDirectory::CreateDirectory(sTempUnpackedXLSB); + + COfficeUtils oCOfficeUtils(NULL); + _UINT32 nRes = oCOfficeUtils.ExtractToDirectory(sFrom, sTempUnpackedXLSB, NULL, 0); + if (SUCCEEDED_X2T(nRes)) + { + OOX::Spreadsheet::CXlsb oXlsb; + oXlsb.ReadNative(OOX::CPath(sTempUnpackedXLSB)); + oXlsb.PrepareSi(); + oXlsb.PrepareTableFormula(); + + OOX::CContentTypes oContentTypes; + oXlsb.SetPropForWriteSheet(sTo, oContentTypes); + oXlsb.ReadSheetData(); + + params.m_bMacro = params.m_bMacro & (oXlsb.m_pVbaProject || oXlsb.GetGlobalinfo()->bMacrosExist); + nRes = oXlsb.WriteNative(sTo, oContentTypes) ? S_OK : AVS_FILEUTILS_ERROR_CONVERT; + if(!params.m_bMacro) + { + nRes = NSCommon::ooxmlm_dir2ooxml_dir(sFrom, sTo, params, convertParams, NSCommon::OOXML_DOCUMENT_TYPE::Sheet, NSCommon::OOXML_DOCUMENT_SUBTYPE::Main); + if (0 != nRes) + return nRes; + } + + } + return nRes; + } + + _UINT32 xlsx_dir2xlsb(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return NSCommon::ooxml2ooxml(sFrom, sTo, params, convertParams, L"xlsb", xlsx_dir2xlsb_dir); + } + _UINT32 xlsx2xlsb(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + std::wstring sTempUnpackedXLSX = combinePath(convertParams.m_sTempDir, L"xlsx_unpacked"); + NSDirectory::CreateDirectory(sTempUnpackedXLSX); + + COfficeUtils oCOfficeUtils(NULL); + _UINT32 nRes = oCOfficeUtils.ExtractToDirectory(sFrom, sTempUnpackedXLSX, NULL, 0); + if (SUCCEEDED_X2T(nRes)) + { + nRes = xlsx_dir2xlsb(sTempUnpackedXLSX, sTo, params, convertParams); + } + return nRes; + } + _UINT32 xml2xlsx(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return NSCommon::format2ooxml(sFrom, sTo, params, convertParams, L"xlsx", xml2xlsx_dir); + } + _UINT32 xml2xlsx_dir(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + OOX::Spreadsheet::CXlsx oXlsx; + + XMLReader reader = {}; + _INT32 lcid = -1; + if(params.m_nLcid != nullptr) + lcid = *params.m_nLcid; + + reader.Read2(sFrom, oXlsx, lcid); + + oXlsx.PrepareToWrite(); + + OOX::CContentTypes oContentTypes; + auto nRes = oXlsx.Write(sTo, oContentTypes) ? S_OK : AVS_FILEUTILS_ERROR_CONVERT; + + return nRes; + } +} diff --git a/X2tConverter/src/main.cpp b/X2tConverter/src/main.cpp index 1a0ba0d86bf..a68e0bba257 100644 --- a/X2tConverter/src/main.cpp +++ b/X2tConverter/src/main.cpp @@ -35,6 +35,7 @@ #include "../../DesktopEditor/common/SystemUtils.h" #include "ASCConverters.h" #include "cextracttools.h" +#include "../../DesktopEditor/fontengine/ApplicationFontsWorker.h" #include @@ -98,20 +99,18 @@ int wmain_lib(int argc, wchar_t *argv[]) if (sMemoryLimit.empty()) sMemoryLimit = NSSystemUtils::gc_EnvMemoryLimitDefault; -#if !defined(_DEBUG) +#if !defined(_DEBUG) && !defined(__ANDROID__) && !defined(_IOS) long long nMemoryLimit; if (NSStringExt::FromHumanReadableByteCount(sMemoryLimit, nMemoryLimit) && nMemoryLimit > 0) limit_memory((size_t)nMemoryLimit); #endif - std::wstring sArg1, sArg2, sExePath; + std::wstring sArg1, sArg2; #if !defined(_WIN32) && !defined(_WIN64) - sExePath = utf8_to_unicode(argv[0]); sArg1 = utf8_to_unicode(argv[1]); if (argc >= 3) sArg2 = utf8_to_unicode(argv[2]); #else - sExePath = std::wstring(argv[0]); sArg1 = std::wstring(argv[1]); if (argc >= 3) sArg2 = std::wstring(argv[2]); @@ -162,6 +161,35 @@ int wmain_lib(int argc, wchar_t *argv[]) NExtractTools::createJSCaches(); return 0; } + else if (sArg1 == L"-create-js-snapshots") + { + NExtractTools::createJSSnapshots(); + return 0; + } + else if (sArg1 == L"-create-allfonts") + { + if (argc > 2) + { + CApplicationFontsWorker oWorker; + oWorker.m_sDirectory = sArg2; + oWorker.m_bIsUseSystemFonts = true; + oWorker.m_bIsNeedThumbnails = false; + oWorker.m_bIsCleanDirectory = false; + + for (int i = 3; i < argc; ++i) + { +#if !defined(_WIN32) && !defined(_WIN64) + std::wstring sFolder = utf8_to_unicode(argv[i]); +#else + std::wstring sFolder(argv[i]); +#endif + oWorker.m_arAdditionalFolders.push_back(sFolder); + } + + NSFonts::IApplicationFonts* pFonts = oWorker.Check(); + RELEASEINTERFACE(pFonts); + } + } else { InputParams oInputParams; diff --git a/X2tConverter/test/TestOOOXml2Odf/TestOOOXml2Odf.pro b/X2tConverter/test/TestOOOXml2Odf/TestOOOXml2Odf.pro new file mode 100644 index 00000000000..8d5d82658c0 --- /dev/null +++ b/X2tConverter/test/TestOOOXml2Odf/TestOOOXml2Odf.pro @@ -0,0 +1,64 @@ +QT -= core +QT -= gui + +TARGET = test +CONFIG += console +CONFIG -= app_bundle + +TEMPLATE = app + +CONFIG += core_static_link_libstd + +X2T_PATH = $$PWD/../.. +CORE_ROOT_DIR = $$PWD/../../../../core +PWD_ROOT_DIR = $$PWD + +include($$CORE_ROOT_DIR/Common/base.pri) +include($$CORE_ROOT_DIR/Common/3dParty/boost/boost.pri) +include($$CORE_ROOT_DIR/Common/3dParty/icu/icu.pri) +include($$CORE_ROOT_DIR/Common/3dParty/googletest/googletest.pri) + +DESTDIR = $$PWD/build + + +INCLUDEPATH += $$CORE_ROOT_DIR/OdfFile +INCLUDEPATH += $$CORE_ROOT_DIR/OdfFile/Common +INCLUDEPATH += $$CORE_ROOT_DIR/Common +INCLUDEPATH += $$CORE_ROOT_DIR/OOXML/PPTXFormat/Logic + + +LIBS += -L$$CORE_BUILDS_LIBRARIES_PATH -lCryptoPPLib +LIBS += -L$$CORE_BOOST_LIBS + +win32 { +LIBS += -lgdi32\ +-luser32 +} + +ADD_DEPENDENCY(kernel) +ADD_DEPENDENCY(kernel_network) +ADD_DEPENDENCY(graphics) + +ADD_DEPENDENCY(OdfFormatLib) +ADD_DEPENDENCY(PPTXFormatLib) +ADD_DEPENDENCY(BinDocument) +ADD_DEPENDENCY(DocxFormatLib) +ADD_DEPENDENCY(XlsbFormatLib) +ADD_DEPENDENCY(RtfFormatLib) +ADD_DEPENDENCY(CompoundFileLib) + +ADD_DEPENDENCY(DocFormatLib XlsFormatLib PPTFormatLib VbaFormatLib) +ADD_DEPENDENCY(HtmlFile2) +ADD_DEPENDENCY(UnicodeConverter) + + +core_linux { + LIBS += -Wl,-unresolved-symbols=ignore-in-shared-libs + LIBS += -ldl +} + +SOURCES += \ + test.cpp \ + $$CORE_ROOT_DIR/Common/OfficeFileFormatChecker2.cpp + +DEFINES += DONT_WRITE_EMBEDDED_FONTS diff --git a/X2tConverter/test/TestOOOXml2Odf/main.cpp b/X2tConverter/test/TestOOOXml2Odf/main.cpp new file mode 100644 index 00000000000..cc7d89493a5 --- /dev/null +++ b/X2tConverter/test/TestOOOXml2Odf/main.cpp @@ -0,0 +1,13 @@ +#include "../../../DesktopEditor/common/Directory.h" +#include "../../../DesktopEditor/common/StringBuilder.h" +#include "../../../DesktopEditor/fontengine/ApplicationFontsWorker.h" +#include "../../../Common/OfficeFileFormatChecker.h" +#include "../../src/dylib/x2t.h" +#include "gtest/gtest.h" +#include "../../../OdfFile/Reader/Converter/StarMath2OOXML/cooxml2odf.h" + +//TEST(OOXml2OdfTest,MText) +//{ +// StarMath::COOXml2Odf oTest; +// oTest.NodeDefinition(nullptr); +//} diff --git a/X2tConverter/test/TestOOOXml2Odf/test.cpp b/X2tConverter/test/TestOOOXml2Odf/test.cpp new file mode 100644 index 00000000000..7227ec5a8da --- /dev/null +++ b/X2tConverter/test/TestOOOXml2Odf/test.cpp @@ -0,0 +1,620 @@ +#include "gtest/gtest.h" +#include "../../../OdfFile/Reader/Converter/StarMath2OOXML/cooxml2odf.h" +#include "../../../DesktopEditor/xml/include/xmlutils.h" +#include "SmartArt.h" + +struct StMath +{ + StMath(): m_wsSemantic(L""),m_wsAnnotation(L"") + {} + std::wstring m_wsSemantic; + std::wstring m_wsAnnotation; + bool operator==(const StMath& stExample) const + { + return(this->m_wsSemantic == stExample.m_wsSemantic) && (this->m_wsAnnotation == stExample.m_wsAnnotation); + } +}; + +TEST(OOXml2OdfTest,MathPara) +{ + XmlUtils::CXmlLiteReader oReader; + OOX::WritingElement* pElement = new OOX::Logic::COMathPara(); + if(oReader.FromString(L"1") && oReader.ReadNextNode()) + pElement->fromXML(oReader); + StarMath::COOXml2Odf oTest; + oTest.StartConversion(pElement); + std::wstring wsOdf = L"11 "; + EXPECT_EQ(oTest.GetOdf(),wsOdf); +} +TEST(OOXml2OdfTest,Math) +{ + XmlUtils::CXmlLiteReader oReader; + OOX::WritingElement* pElement = new OOX::Logic::COMath(); + if(oReader.FromString(L"1") && oReader.ReadNextNode()) + pElement->fromXML(oReader); + StarMath::COOXml2Odf oTest; + oTest.NodeDefinition(pElement); + StMath stCorrect,stResult; + stResult.m_wsSemantic = oTest.GetOdf(); + stResult.m_wsAnnotation = oTest.GetAnnotation(); + stCorrect.m_wsSemantic = L"1"; + stCorrect.m_wsAnnotation = L"1 "; + EXPECT_EQ(stResult,stCorrect); +} +TEST(OOXml2OdfTest,MText) +{ + XmlUtils::CXmlLiteReader oReader; + OOX::Logic::COMath* pElement = new OOX::Logic::COMath(); + if(oReader.FromString(L"10") && oReader.ReadNextNode()) + pElement->fromXML(oReader); + StarMath::COOXml2Odf oTest; + oTest.ConversionVectorWritingElement(pElement->m_arrItems); + StMath StCorrect,StResult; + StResult.m_wsSemantic = oTest.GetOdf(); + StResult.m_wsAnnotation = oTest.GetAnnotation(); + StCorrect.m_wsSemantic = L"10"; + StCorrect.m_wsAnnotation = L"10 "; + EXPECT_EQ(StResult,StCorrect); +} +TEST(OOXml2OdfTest,MTextHard) +{ + XmlUtils::CXmlLiteReader oReader; + OOX::Logic::COMath* pElement = new OOX::Logic::COMath(); + if(oReader.FromString(L" 20 2+3 ") && oReader.ReadNextNode()) + pElement->fromXML(oReader); + StarMath::COOXml2Odf oTest; + oTest.ConversionVectorWritingElement(pElement->m_arrItems); + StMath StCorrect,StResult; + StResult.m_wsSemantic = oTest.GetOdf(); + StResult.m_wsAnnotation = oTest.GetAnnotation(); + StCorrect.m_wsSemantic = L"202+3"; + StCorrect.m_wsAnnotation = L"20 ` 2 + 3 "; + EXPECT_EQ(StResult,StCorrect); +} +TEST(OOXml2OdfTest,MTextHardAttribute) +{ + XmlUtils::CXmlLiteReader oReader; + OOX::Logic::COMath* pElement = new OOX::Logic::COMath(); + if(oReader.FromString(L" 20 2 - 3 ") && oReader.ReadNextNode()) + pElement->fromXML(oReader); + StarMath::COOXml2Odf oTest; + oTest.ConversionVectorWritingElement(pElement->m_arrItems); + StMath StCorrect,StResult; + StResult.m_wsSemantic = oTest.GetOdf(); + StResult.m_wsAnnotation = oTest.GetAnnotation(); + StCorrect.m_wsSemantic = L"202-3"; + StCorrect.m_wsAnnotation = L"color red 20 ` color hex ED7D31 2 color hex 70AD47 - color hex 1F4E79 3 "; + EXPECT_EQ(StResult,StCorrect); +} +TEST(OOXml2OdfTest,FractionOver) +{ + XmlUtils::CXmlLiteReader oReader; + OOX::Logic::CFraction* pElement = new OOX::Logic::CFraction(); + if(oReader.FromString(L" 1 2 ") && oReader.ReadNextNode()) + pElement->fromXML(oReader); + StarMath::COOXml2Odf oTest; + oTest.NodeDefinition(pElement); + StMath StCorrect,StResult; + StResult.m_wsSemantic = oTest.GetOdf(); + StResult.m_wsAnnotation = oTest.GetAnnotation(); + StCorrect.m_wsSemantic = L"12"; + StCorrect.m_wsAnnotation = L"{ 1 } over { 2 } "; + EXPECT_EQ(StResult,StCorrect); +} +TEST(OOXml2OdfTest,FractionWideslash) +{ + XmlUtils::CXmlLiteReader oReader; + OOX::Logic::CFraction* pElement = new OOX::Logic::CFraction(); + if(oReader.FromString(L" 1 2 ") && oReader.ReadNextNode()) + pElement->fromXML(oReader); + StarMath::COOXml2Odf oTest; + oTest.NodeDefinition(pElement); + StMath StCorrect,StResult; + StResult.m_wsSemantic = oTest.GetOdf(); + StResult.m_wsAnnotation = oTest.GetAnnotation(); + StCorrect.m_wsSemantic = L"12"; + StCorrect.m_wsAnnotation = L"{ 1 } wideslash { 2 } "; + EXPECT_EQ(StResult,StCorrect); +} +TEST(OOXml2OdfTest,FractionSlash) +{ + XmlUtils::CXmlLiteReader oReader; + OOX::Logic::CFraction* pElement = new OOX::Logic::CFraction(); + if(oReader.FromString(L" 1 2 ") && oReader.ReadNextNode()) + pElement->fromXML(oReader); + StarMath::COOXml2Odf oTest; + oTest.NodeDefinition(pElement); + StMath StCorrect,StResult; + StResult.m_wsSemantic = oTest.GetOdf(); + StResult.m_wsAnnotation = oTest.GetAnnotation(); + StCorrect.m_wsSemantic = L"1/2"; + StCorrect.m_wsAnnotation = L"1 / 2 "; + EXPECT_EQ(StResult,StCorrect); +} +TEST(OOXml2OdfTest,Delimiter) +{ + XmlUtils::CXmlLiteReader oReader; + OOX::Logic::CDelimiter* pElement = new OOX::Logic::CDelimiter(); + if(oReader.FromString(L" 2-3 ") && oReader.ReadNextNode()) + pElement->fromXML(oReader); + StarMath::COOXml2Odf oTest; + oTest.NodeDefinition(pElement); + StMath StCorrect,StResult; + StResult.m_wsSemantic = oTest.GetOdf(); + StResult.m_wsAnnotation = oTest.GetAnnotation(); + StCorrect.m_wsSemantic = L"[2-3]"; + StCorrect.m_wsAnnotation = L"left [ 2 - 3 right ] "; + EXPECT_EQ(StResult,StCorrect); +} +TEST(OOXml2OdfTest,NaryFromTo) +{ + XmlUtils::CXmlLiteReader oReader; + OOX::Logic::CNary* pElement = new OOX::Logic::CNary(); + if(oReader.FromString(L" 2 1 3 ") && oReader.ReadNextNode()) + pElement->fromXML(oReader); + StarMath::COOXml2Odf oTest; + oTest.NodeDefinition(pElement); + StMath StCorrect,StResult; + StResult.m_wsSemantic = oTest.GetOdf(); + StResult.m_wsAnnotation = oTest.GetAnnotation(); + StCorrect.m_wsSemantic = L"\u2211213"; + StCorrect.m_wsAnnotation = L"sum from {2 } to {1 } 3 "; + EXPECT_EQ(StResult,StCorrect); +} +TEST(OOXml2OdfTest,NaryFrom) +{ + XmlUtils::CXmlLiteReader oReader; + OOX::Logic::CNary* pElement = new OOX::Logic::CNary(); + if(oReader.FromString(L" 1 2 ") && oReader.ReadNextNode()) + pElement->fromXML(oReader); + StarMath::COOXml2Odf oTest; + oTest.NodeDefinition(pElement); + StMath StCorrect,StResult; + StResult.m_wsSemantic = oTest.GetOdf(); + StResult.m_wsAnnotation = oTest.GetAnnotation(); + StCorrect.m_wsSemantic = L"\u221012"; + StCorrect.m_wsAnnotation = L"coprod from {1 } 2 "; + EXPECT_EQ(StResult,StCorrect); +} +TEST(OOXml2OdfTest,NaryOper) +{ + XmlUtils::CXmlLiteReader oReader; + OOX::Logic::CNary* pElement = new OOX::Logic::CNary(); + if(oReader.FromString(L" 10 ") && oReader.ReadNextNode()) + pElement->fromXML(oReader); + StarMath::COOXml2Odf oTest; + oTest.NodeDefinition(pElement); + StMath StCorrect,StResult; + StResult.m_wsSemantic = oTest.GetOdf(); + StResult.m_wsAnnotation = oTest.GetAnnotation(); + StCorrect.m_wsSemantic = L"\u22C010"; + StCorrect.m_wsAnnotation = L"oper \u22C0 10 "; + EXPECT_EQ(StResult,StCorrect); +} +TEST(OOXml2OdfTest,AccDdot) +{ + XmlUtils::CXmlLiteReader oReader; + OOX::Logic::CAcc* pElement = new OOX::Logic::CAcc(); + if(oReader.FromString(L" 1 ") && oReader.ReadNextNode()) + pElement->fromXML(oReader); + StarMath::COOXml2Odf oTest; + oTest.NodeDefinition(pElement); + StMath StCorrect,StResult; + StResult.m_wsSemantic = oTest.GetOdf(); + StResult.m_wsAnnotation = oTest.GetAnnotation(); + StCorrect.m_wsSemantic = L"1\u0308"; + StCorrect.m_wsAnnotation = L"ddot 1 "; + EXPECT_EQ(StResult,StCorrect); +} +TEST(OOXml2OdfTest,Matrix) +{ + XmlUtils::CXmlLiteReader oReader; + OOX::Logic::CMatrix* pElement = new OOX::Logic::CMatrix(); + if(oReader.FromString(L" 1 2 3 4 ") && oReader.ReadNextNode()) + pElement->fromXML(oReader); + StarMath::COOXml2Odf oTest; + oTest.NodeDefinition(pElement); + StMath StCorrect,StResult; + StResult.m_wsSemantic = oTest.GetOdf(); + StResult.m_wsAnnotation = oTest.GetAnnotation(); + StCorrect.m_wsSemantic = L"1234"; + StCorrect.m_wsAnnotation = L"matrix{1 # 2 ## 3 # 4 } "; + EXPECT_EQ(StResult,StCorrect); +} +TEST(OOXml2OdfTest,MatrixWithOneColumn) +{ + XmlUtils::CXmlLiteReader oReader; + OOX::Logic::CMatrix* pElement = new OOX::Logic::CMatrix(); + if(oReader.FromString(L" 1 2 3 ") && oReader.ReadNextNode()) + pElement->fromXML(oReader); + StarMath::COOXml2Odf oTest; + oTest.NodeDefinition(pElement); + StMath StCorrect,StResult; + StResult.m_wsSemantic = oTest.GetOdf(); + StResult.m_wsAnnotation = oTest.GetAnnotation(); + StCorrect.m_wsSemantic = L"123"; + StCorrect.m_wsAnnotation = L"matrix{1 ## 2 ## 3 } "; + EXPECT_EQ(StResult,StCorrect); +} +TEST(OOXml2OdfTest,Box) +{ + XmlUtils::CXmlLiteReader oReader; + OOX::Logic::CBox* pElement = new OOX::Logic::CBox(); + if(oReader.FromString(L" 1 2 ") && oReader.ReadNextNode()) + pElement->fromXML(oReader); + StarMath::COOXml2Odf oTest; + oTest.NodeDefinition(pElement); + StMath StCorrect,StResult; + StResult.m_wsSemantic = oTest.GetOdf(); + StResult.m_wsAnnotation = oTest.GetAnnotation(); + StCorrect.m_wsSemantic = L"12"; + StCorrect.m_wsAnnotation = L"{ 1 } over { 2 } "; + EXPECT_EQ(StResult,StCorrect); +} +TEST(OOXml2OdfTest,sSup) +{ + XmlUtils::CXmlLiteReader oReader; + OOX::WritingElement* pElement = new OOX::Logic::CSSup(); + if(oReader.FromString(L" 1 2 ") && oReader.ReadNextNode()) + pElement->fromXML(oReader); + StarMath::COOXml2Odf oTest; + oTest.NodeDefinition(pElement); + StMath StCorrect,StResult; + StResult.m_wsSemantic = oTest.GetOdf(); + StResult.m_wsAnnotation = oTest.GetAnnotation(); + StCorrect.m_wsSemantic = L"12"; + StCorrect.m_wsAnnotation = L"1 ^ {2 } "; + EXPECT_EQ(StResult,StCorrect); +} +TEST(OOXml2OdfTest,sSub) +{ + XmlUtils::CXmlLiteReader oReader; + OOX::WritingElement* pElement = new OOX::Logic::CSSub(); + if(oReader.FromString(L" 3 4 ") && oReader.ReadNextNode()) + pElement->fromXML(oReader); + StarMath::COOXml2Odf oTest; + oTest.NodeDefinition(pElement); + StMath StCorrect,StResult; + StResult.m_wsSemantic = oTest.GetOdf(); + StResult.m_wsAnnotation = oTest.GetAnnotation(); + StCorrect.m_wsSemantic = L"34"; + StCorrect.m_wsAnnotation = L"3 _ {4 } "; + EXPECT_EQ(StResult,StCorrect); +} +TEST(OOXml2OdfTest,sSubSup) +{ + XmlUtils::CXmlLiteReader oReader; + OOX::WritingElement* pElement = new OOX::Logic::CSSubSup(); + if(oReader.FromString(L" 5 7 6 ") && oReader.ReadNextNode()) + pElement->fromXML(oReader); + StarMath::COOXml2Odf oTest; + oTest.NodeDefinition(pElement); + StMath StCorrect,StResult; + StResult.m_wsSemantic = oTest.GetOdf(); + StResult.m_wsAnnotation = oTest.GetAnnotation(); + StCorrect.m_wsSemantic = L"576"; + StCorrect.m_wsAnnotation = L"5 _ { 7 } ^ { 6 } "; + EXPECT_EQ(StResult,StCorrect); +} +TEST(OOXml2OdfTest,sPre) +{ + XmlUtils::CXmlLiteReader oReader; + OOX::WritingElement* pElement = new OOX::Logic::CSPre(); + if(oReader.FromString(L" 8 9 1 0 ") && oReader.ReadNextNode()) + pElement->fromXML(oReader); + StarMath::COOXml2Odf oTest; + oTest.NodeDefinition(pElement); + StMath StCorrect,StResult; + StResult.m_wsSemantic = oTest.GetOdf(); + StResult.m_wsAnnotation = oTest.GetAnnotation(); + StCorrect.m_wsSemantic = L"1098"; + StCorrect.m_wsAnnotation = L"10 lsup { 9 } lsub { 8 } "; + EXPECT_EQ(StResult,StCorrect); +} +TEST(OOXml2OdfTest,EqArr) +{ + XmlUtils::CXmlLiteReader oReader; + OOX::WritingElement* pElement = new OOX::Logic::CEqArr(); + if(oReader.FromString(L" 1 2 3 ") && oReader.ReadNextNode()) + pElement->fromXML(oReader); + StarMath::COOXml2Odf oTest; + oTest.NodeDefinition(pElement); + StMath StCorrect,StResult; + StResult.m_wsSemantic = oTest.GetOdf(); + StResult.m_wsAnnotation = oTest.GetAnnotation(); + StCorrect.m_wsSemantic = L"123"; + StCorrect.m_wsAnnotation = L"stack{1 # 2 # 3 } "; + EXPECT_EQ(StResult,StCorrect); +} +TEST(OOXml2OdfTest,NumBinom) +{ + XmlUtils::CXmlLiteReader oReader; + OOX::WritingElement* pElement = new OOX::Logic::CFraction(); + if(oReader.FromString(L" 4 5 ") && oReader.ReadNextNode()) + pElement->fromXML(oReader); + StarMath::COOXml2Odf oTest; + oTest.NodeDefinition(pElement); + StMath StCorrect,StResult; + StResult.m_wsSemantic = oTest.GetOdf(); + StResult.m_wsAnnotation = oTest.GetAnnotation(); + StCorrect.m_wsSemantic = L"45"; + StCorrect.m_wsAnnotation = L"binom { 4 } { 5 } "; + EXPECT_EQ(StResult,StCorrect); +} +TEST(OOXml2OdfTest,RelationsAndOperations) +{ + XmlUtils::CXmlLiteReader oReader; + OOX::WritingElement* pElement = new OOX::Logic::COMath(); + if(oReader.FromString(L" 2 \u225D 3 ") && oReader.ReadNextNode()) + pElement->fromXML(oReader); + StarMath::COOXml2Odf oTest; + oTest.NodeDefinition(pElement); + StMath StCorrect,StResult; + StResult.m_wsSemantic = oTest.GetOdf(); + StResult.m_wsAnnotation = oTest.GetAnnotation(); + StCorrect.m_wsSemantic = L"2\u225D3"; + StCorrect.m_wsAnnotation = L"2 def 3 "; + EXPECT_EQ(StResult,StCorrect); +} +TEST(OOXml2OdfTest,Special) +{ + XmlUtils::CXmlLiteReader oReader; + OOX::WritingElement* pElement = new OOX::Logic::COMath(); + if(oReader.FromString(L" \u2135 ") && oReader.ReadNextNode()) + pElement->fromXML(oReader); + StarMath::COOXml2Odf oTest; + oTest.NodeDefinition(pElement); + StMath StCorrect,StResult; + StResult.m_wsSemantic = oTest.GetOdf(); + StResult.m_wsAnnotation = oTest.GetAnnotation(); + StCorrect.m_wsSemantic = L"\u2135"; + StCorrect.m_wsAnnotation = L"aleph "; + EXPECT_EQ(StResult,StCorrect); +} +TEST(OOXml2OdfTest,LimLow) +{ + XmlUtils::CXmlLiteReader oReader; + OOX::WritingElement* pElement = new OOX::Logic::CFunc(); + if(oReader.FromString(L" lim 1 2 ") && oReader.ReadNextNode()) + pElement->fromXML(oReader); + StarMath::COOXml2Odf oTest; + oTest.NodeDefinition(pElement); + StMath StCorrect,StResult; + StResult.m_wsSemantic = oTest.GetOdf(); + StResult.m_wsAnnotation = oTest.GetAnnotation(); + StCorrect.m_wsSemantic = L"lim12"; + StCorrect.m_wsAnnotation = L"lim csub { 1 } 2 "; + EXPECT_EQ(StResult,StCorrect); +} +TEST(OOXml2OdfTest,Func) +{ + XmlUtils::CXmlLiteReader oReader; + OOX::WritingElement* pElement = new OOX::Logic::CFunc(); + if(oReader.FromString(L" coth 5 ") && oReader.ReadNextNode()) + pElement->fromXML(oReader); + StarMath::COOXml2Odf oTest; + oTest.NodeDefinition(pElement); + StMath StCorrect,StResult; + StResult.m_wsSemantic = oTest.GetOdf(); + StResult.m_wsAnnotation = oTest.GetAnnotation(); + StCorrect.m_wsSemantic = L"coth5"; + StCorrect.m_wsAnnotation = L"coth 5 "; + EXPECT_EQ(StResult,StCorrect); +} +TEST(OOXml2OdfTest,LimUpp) +{ + XmlUtils::CXmlLiteReader oReader; + OOX::WritingElement* pElement = new OOX::Logic::CLimUpp; + if(oReader.FromString(L" 1 2 ") && oReader.ReadNextNode()) + pElement->fromXML(oReader); + StarMath::COOXml2Odf oTest; + oTest.NodeDefinition(pElement); + StMath StCorrect,StResult; + StResult.m_wsSemantic = oTest.GetOdf(); + StResult.m_wsAnnotation = oTest.GetAnnotation(); + StCorrect.m_wsSemantic = L"1\u23DE2"; + StCorrect.m_wsAnnotation = L"1 overbrace { 2 } "; + EXPECT_EQ(StResult,StCorrect); +} +TEST(OOXml2OdfTest,LimLowWithGroup) +{ + XmlUtils::CXmlLiteReader oReader; + OOX::WritingElement* pElement = new OOX::Logic::CLimLow(); + if(oReader.FromString(L" 3 4 ") && oReader.ReadNextNode()) + pElement->fromXML(oReader); + StarMath::COOXml2Odf oTest; + oTest.NodeDefinition(pElement); + StMath StCorrect,StResult; + StResult.m_wsSemantic = oTest.GetOdf(); + StResult.m_wsAnnotation = oTest.GetAnnotation(); + StCorrect.m_wsSemantic = L"3\u23DF4"; + StCorrect.m_wsAnnotation = L"3 underbrace { 4 } "; + EXPECT_EQ(StResult,StCorrect); +} +TEST(OOXml2OdfTest,Example2) +{ + XmlUtils::CXmlLiteReader oReader; + OOX::WritingElement* pElement = new OOX::Logic::COMathPara(); + if(oReader.FromString(L" x = - b \u00B1 b 2 -4 ac 2 a ") && oReader.ReadNextNode()) + pElement->fromXML(oReader); + StarMath::COOXml2Odf oTest; + oTest.StartConversion(pElement); + std::wstring wsOdf = L"x=-b\u00B1b2-4ac2ax = { - b +- sqrt { b ^ {2 } - 4 ac } } over { 2a } "; + EXPECT_EQ(oTest.GetOdf(),wsOdf); +} +TEST(OOXml2OdfTest,Example1) +{ + XmlUtils::CXmlLiteReader oReader; + OOX::WritingElement* pElement = new OOX::Logic::COMathPara(); + if(oReader.FromString(L" x+a n = k=0 n n k x k a n-k ") && oReader.ReadNextNode()) + pElement->fromXML(oReader); + StarMath::COOXml2Odf oTest; + oTest.StartConversion(pElement); + std::wstring wsOdf = L"(x+a)n=\x2211k=0n(nk)xkan-kleft ( x + a right ) ^ {n } "=" sum from {k = 0 } to {n } left ( binom { n } { k } right ) x ^ {k } a ^ {n - k } "; + EXPECT_EQ(oTest.GetOdf(),wsOdf); +} +TEST(OOXml2OdfTest,Example3) +{ + XmlUtils::CXmlLiteReader oReader; + OOX::WritingElement* pElement = new OOX::Logic::COMathPara(); + if(oReader.FromString(L" A=\u03C0 r 2 ") && oReader.ReadNextNode()) + pElement->fromXML(oReader); + StarMath::COOXml2Odf oTest; + oTest.StartConversion(pElement); + std::wstring wsOdf = L"A=\u03C0r2A = %pi r ^ {2 } "; + EXPECT_EQ(oTest.GetOdf(),wsOdf); +} +TEST(OOXml2OdfTest,LimLowWithRelation) +{ + XmlUtils::CXmlLiteReader oReader; + OOX::WritingElement* pElement = new OOX::Logic::COMath(); + if(oReader.FromString(L" lim n\u2192\u221E 1 ") && oReader.ReadNextNode()) + pElement->fromXML(oReader); + StarMath::COOXml2Odf oTest; + oTest.StartConversion(pElement); + std::wstring wsOdf = L"limn\u2192\u221E(1)lim csub { n toward infinity } left ( 1 right ) "; + EXPECT_EQ(oTest.GetOdf(),wsOdf); +} +TEST(OOXml2OdfTest,HarmonicSeries) +{ + XmlUtils::CXmlLiteReader oReader; + OOX::WritingElement* pElement = new OOX::Logic::COMath(); + if(oReader.FromString(L" 1 + 1 n n ") && oReader.ReadNextNode()) + pElement->fromXML(oReader); + StarMath::COOXml2Odf oTest; + oTest.StartConversion(pElement); + std::wstring wsOdf = L"(1+1n)ncolor red ital left ( 1 color hex 70AD47 "+"{ 1 } over { n } right ) ^ {color red n } "; + EXPECT_EQ(oTest.GetOdf(),wsOdf); +} +TEST(OOXml2OdfTest,Example8) +{ + XmlUtils::CXmlLiteReader oReader; + OOX::WritingElement* pElement = new OOX::Logic::COMath(); + if(oReader.FromString(L" sin \u03B1 \u00B1 sin \u03B2 =2 sin 1 2 \u03B1\u00B1\u03B2 cos 1 2 \u03B1\u2213\u03B2 ") && oReader.ReadNextNode()) + pElement->fromXML(oReader); + StarMath::COOXml2Odf oTest; + oTest.StartConversion(pElement); + std::wstring wsOdf = L"sin\u03B1\u00B1sin\u03B2=2sin12(\u03B1\u00B1\u03B2)cos12(\u03B1\u2213\u03B2)sin %alpha +- sin %beta = 2 sin { 1 } over { 2 } left ( %alpha +- %beta right ) cos { 1 } over { 2 } left ( %alpha -+ %beta right ) "; + EXPECT_EQ(oTest.GetOdf(),wsOdf); +} +TEST(OOXml2OdfTest,Example7) +{ + XmlUtils::CXmlLiteReader oReader; + OOX::WritingElement* pElement = new OOX::Logic::COMath(); + if(oReader.FromString(L" a 2 + b 2 = c 2 ") && oReader.ReadNextNode()) + pElement->fromXML(oReader); + StarMath::COOXml2Odf oTest; + oTest.StartConversion(pElement); + std::wstring wsOdf = L"a2+b2=c2a ^ {2 } + b ^ {2 } "=" c ^ {2 } "; + EXPECT_EQ(oTest.GetOdf(),wsOdf); +} +TEST(OOXml2OdfTest,Example9) +{ + XmlUtils::CXmlLiteReader oReader; + OOX::WritingElement* pElement = new OOX::Logic::COMath(); + if(oReader.FromString(L" cos \u03B1 + cos \u03B2 =2 cos 1 2 \u03B1+\u03B2 cos 1 2 \u03B1-\u03B2 fromXML(oReader); + StarMath::COOXml2Odf oTest; + oTest.StartConversion(pElement); + std::wstring wsOdf = L"cos\u03B1+cos\u03B2=2cos12(\u03B1+\u03B2)cos12(\u03B1-\u03B2)cos %alpha + cos %beta = 2 cos { 1 } over { 2 } left ( %alpha + %beta right ) cos { 1 } over { 2 } left ( %alpha - %beta right ) "; + EXPECT_EQ(oTest.GetOdf(),wsOdf); +} +TEST(OOXml2OdfTest,TextMrPr) +{ + XmlUtils::CXmlLiteReader oReader; + OOX::WritingElement* pElement = new OOX::Logic::COMath(); + if(oReader.FromString(L" 1+3 ") && oReader.ReadNextNode()) + pElement->fromXML(oReader); + StarMath::COOXml2Odf oTest; + oTest.StartConversion(pElement); + std::wstring wsOdf = L"1+3bold ital 1 bold ital + 3 "; + EXPECT_EQ(oTest.GetOdf(),wsOdf); +} +TEST(OOXml2OdfTest,ColorByName) +{ + XmlUtils::CXmlLiteReader oReader; + OOX::WritingElement* pElement = new OOX::Logic::COMath(); + if(oReader.FromString(L" q b ") && oReader.ReadNextNode()) + pElement->fromXML(oReader); + StarMath::COOXml2Odf oTest; + oTest.StartConversion(pElement); + std::wstring wsOdf = L"qb{ color midnightblue q } over { color orangered b } "; + EXPECT_EQ(oTest.GetOdf(),wsOdf); +} +TEST(OOXml2OdfTest,EmptyNumerator) +{ + XmlUtils::CXmlLiteReader oReader; + OOX::WritingElement* pElement = new OOX::Logic::COMath(); + if(oReader.FromString(L" 2 ") && oReader.ReadNextNode()) + pElement->fromXML(oReader); + StarMath::COOXml2Odf oTest; + oTest.StartConversion(pElement); + std::wstring wsOdf = L"2{ } over { 2 } "; + EXPECT_EQ(oTest.GetOdf(),wsOdf); +} +TEST(OOXml2OdfTest,IdentityMatrixDiagonally) +{ + XmlUtils::CXmlLiteReader oReader; + OOX::WritingElement* pElement = new OOX::Logic::COMath(); + if(oReader.FromString(L" 1 0 0 0 1 0 0 0 1 ") && oReader.ReadNextNode()) + pElement->fromXML(oReader); + StarMath::COOXml2Odf oTest; + oTest.StartConversion(pElement); + std::wstring wsOdf = L"100010001bold ital matrix{1 # 0 # 0 ## 0 # 1 # 0 ## 0 # 0 # 1 } "; + EXPECT_EQ(oTest.GetOdf(),wsOdf); +} +TEST(OOXml2OdfTest,ExceptionsDiacritics) +{ + XmlUtils::CXmlLiteReader oReader; + OOX::WritingElement* pElement = new OOX::Logic::COMath(); + if(oReader.FromString(L" 1 2 b abc ") && oReader.ReadNextNode()) + pElement->fromXML(oReader); + StarMath::COOXml2Odf oTest; + oTest.StartConversion(pElement); + std::wstring wsOdf = L"1\u21942b\u2190abc\u21BC1 csup "\u2194" ` bold ital { 2b } csup "\u2190" ` abc csup "\u21BC" "; + EXPECT_EQ(oTest.GetOdf(),wsOdf); +} +TEST(OOXml2OdfTest,ExceptionsGroupChr) +{ + XmlUtils::CXmlLiteReader oReader; + OOX::WritingElement* pElement = new OOX::Logic::COMath(); + if(oReader.FromString(L" 1 2b dia ") && oReader.ReadNextNode()) + pElement->fromXML(oReader); + StarMath::COOXml2Odf oTest; + oTest.StartConversion(pElement); + std::wstring wsOdf = L"1\u21942b\u21D4dia\u21D0bold ital 1 csub "\u2194" 2b csub "\u21D4" bold ital dia csub "\u21D0" "; + EXPECT_EQ(oTest.GetOdf(),wsOdf); +} +TEST(OOXml2OdfTest,EmptyMatrix) +{ + XmlUtils::CXmlLiteReader oReader; + OOX::WritingElement* pElement = new OOX::Logic::COMath(); + if(oReader.FromString(L" ") && oReader.ReadNextNode()) + pElement->fromXML(oReader); + StarMath::COOXml2Odf oTest; + oTest.StartConversion(pElement); + std::wstring wsOdf = L"bold ital matrix{# # ## # # ## # # } "; + EXPECT_EQ(oTest.GetOdf(),wsOdf); +} +TEST(OOXml2OdfTest,EmptyNary) +{ + XmlUtils::CXmlLiteReader oReader; + OOX::WritingElement* pElement = new OOX::Logic::COMath(); + if(oReader.FromString(L" ") && oReader.ReadNextNode()) + pElement->fromXML(oReader); + StarMath::COOXml2Odf oTest; + oTest.StartConversion(pElement); + std::wstring wsOdf = L"\u2211bold ital sum from {} to {} "; + EXPECT_EQ(oTest.GetOdf(),wsOdf); +} +TEST(OOXml2OdfTest,EmptyRoot) +{ + XmlUtils::CXmlLiteReader oReader; + OOX::WritingElement* pElement = new OOX::Logic::COMath(); + if(oReader.FromString(L" ") && oReader.ReadNextNode()) + pElement->fromXML(oReader); + StarMath::COOXml2Odf oTest; + oTest.StartConversion(pElement); + std::wstring wsOdf = L"bold ital nroot { } { } "; + EXPECT_EQ(oTest.GetOdf(),wsOdf); +} diff --git a/X2tConverter/test/androidTest/.gitignore b/X2tConverter/test/androidTest/.gitignore deleted file mode 100644 index ae00b1dba5e..00000000000 --- a/X2tConverter/test/androidTest/.gitignore +++ /dev/null @@ -1,25 +0,0 @@ -*.iml -*.zip -*.7z -*.tar -*.jks -*.pepk -*.bin -*.a -*.so -*.ttf - -.gradle -/local.properties -/.idea/caches -/.idea/libraries -/.idea/modules.xml -/.idea/workspace.xml -/.idea/navEditor.xml -/.idea/assetWizardSettings.xml -.DS_Store -/build -/captures -.externalNativeBuild -.cxx -/extras/libs \ No newline at end of file diff --git a/X2tConverter/test/androidTest/README.md b/X2tConverter/test/androidTest/README.md deleted file mode 100644 index 23db71d6671..00000000000 --- a/X2tConverter/test/androidTest/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# README # - -Android x2t gui app example. \ No newline at end of file diff --git a/X2tConverter/test/androidTest/build.gradle b/X2tConverter/test/androidTest/build.gradle deleted file mode 100644 index e3245e7f576..00000000000 --- a/X2tConverter/test/androidTest/build.gradle +++ /dev/null @@ -1,28 +0,0 @@ -// Top-level build file where you can add configuration options common to all sub-projects/modules. - -buildscript { - ext.kotlin_version = '1.3.50' - repositories { - google() - jcenter() - - } - dependencies { - classpath 'com.android.tools.build:gradle:3.5.1' - classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" - // NOTE: Do not place your application dependencies here; they belong - // in the individual module build.gradle files - } -} - -allprojects { - repositories { - google() - jcenter() - - } -} - -task clean(type: Delete) { - delete rootProject.buildDir -} diff --git a/X2tConverter/test/androidTest/gradle.properties b/X2tConverter/test/androidTest/gradle.properties deleted file mode 100644 index 451caa62ca1..00000000000 --- a/X2tConverter/test/androidTest/gradle.properties +++ /dev/null @@ -1,19 +0,0 @@ -# Project-wide Gradle settings. - -# IDE (e.g. Android Studio) users: -# Gradle settings configured through the IDE *will override* -# any settings specified in this file. - -# For more details on how to configure your build environment visit -# http://www.gradle.org/docs/current/userguide/build_environment.html - -# Specifies the JVM arguments used for the daemon process. -# The setting is particularly useful for tweaking memory settings. -org.gradle.jvmargs=-Xmx4g -XX:MaxPermSize=2048m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 -# When configured, Gradle will run in incubating parallel mode. -# This option should only be used with decoupled projects. More details, visit -# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects -org.gradle.parallel=true -org.gradle.daemon=true -org.gradle.configureondemand=true - diff --git a/X2tConverter/test/androidTest/gradle/wrapper/gradle-wrapper.jar b/X2tConverter/test/androidTest/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index f6b961fd5a8..00000000000 Binary files a/X2tConverter/test/androidTest/gradle/wrapper/gradle-wrapper.jar and /dev/null differ diff --git a/X2tConverter/test/androidTest/gradle/wrapper/gradle-wrapper.properties b/X2tConverter/test/androidTest/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index e9d7935d179..00000000000 --- a/X2tConverter/test/androidTest/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,6 +0,0 @@ -#Tue Oct 29 14:41:19 MSK 2019 -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip diff --git a/X2tConverter/test/androidTest/gradlew b/X2tConverter/test/androidTest/gradlew deleted file mode 100644 index cccdd3d517f..00000000000 --- a/X2tConverter/test/androidTest/gradlew +++ /dev/null @@ -1,172 +0,0 @@ -#!/usr/bin/env sh - -############################################################################## -## -## Gradle start up script for UN*X -## -############################################################################## - -# Attempt to set APP_HOME -# Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi -done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null - -APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" - -warn () { - echo "$*" -} - -die () { - echo - echo "$*" - echo - exit 1 -} - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; - NONSTOP* ) - nonstop=true - ;; -esac - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" - else - JAVACMD="$JAVA_HOME/bin/java" - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD="java" - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi -fi - -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi - -# For Cygwin, switch paths to Windows format before running java -if $cygwin ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - JAVACMD=`cygpath --unix "$JAVACMD"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi - # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" - fi - i=$((i+1)) - done - case $i in - (0) set -- ;; - (1) set -- "$args0" ;; - (2) set -- "$args0" "$args1" ;; - (3) set -- "$args0" "$args1" "$args2" ;; - (4) set -- "$args0" "$args1" "$args2" "$args3" ;; - (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac -fi - -# Escape application args -save () { - for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done - echo " " -} -APP_ARGS=$(save "$@") - -# Collect all arguments for the java command, following the shell quoting and substitution rules -eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" - -# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong -if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then - cd "$(dirname "$0")" -fi - -exec "$JAVACMD" "$@" diff --git a/X2tConverter/test/androidTest/gradlew.bat b/X2tConverter/test/androidTest/gradlew.bat deleted file mode 100644 index f9553162f12..00000000000 --- a/X2tConverter/test/androidTest/gradlew.bat +++ /dev/null @@ -1,84 +0,0 @@ -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto init - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:init -@rem Get command-line arguments, handling Windows variants - -if not "%OS%" == "Windows_NT" goto win9xME_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/X2tConverter/test/androidTest/settings.gradle b/X2tConverter/test/androidTest/settings.gradle deleted file mode 100644 index eee2f50111f..00000000000 --- a/X2tConverter/test/androidTest/settings.gradle +++ /dev/null @@ -1,6 +0,0 @@ -rootProject.name='androidTest' -// Include x2t gui module -include ':x2t' -// Include x2t lib module -settings.createProjectDescriptor(settings.rootProject, 'libx2t', file('../../build/Android/libx2t')) -include ':libx2t' \ No newline at end of file diff --git a/X2tConverter/test/androidTest/x2t/.gitignore b/X2tConverter/test/androidTest/x2t/.gitignore deleted file mode 100644 index 796b96d1c40..00000000000 --- a/X2tConverter/test/androidTest/x2t/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/build diff --git a/X2tConverter/test/androidTest/x2t/build.gradle b/X2tConverter/test/androidTest/x2t/build.gradle deleted file mode 100644 index 14fc25a7e0e..00000000000 --- a/X2tConverter/test/androidTest/x2t/build.gradle +++ /dev/null @@ -1,48 +0,0 @@ -apply plugin: 'com.android.application' -apply plugin: 'kotlin-android' -apply plugin: 'kotlin-android-extensions' - - -android { - - buildToolsVersion '29.0.0' - compileSdkVersion 29 - - defaultConfig { - minSdkVersion 21 - targetSdkVersion 29 - versionCode 1 - versionName '1.0' - applicationId "app.x2t" - } - - buildTypes { - release { - minifyEnabled false - proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' - } - - debug { - minifyEnabled false - debuggable true - } - } - - compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 - } - -} - -dependencies { - implementation fileTree(dir: 'libs', include: ['*.jar']) - implementation project(':libx2t') - - implementation 'androidx.appcompat:appcompat:1.1.0' - implementation "androidx.constraintlayout:constraintlayout:1.1.3" - - implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.3.50" - implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.2" - implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.2" -} \ No newline at end of file diff --git a/X2tConverter/test/androidTest/x2t/gradle.properties b/X2tConverter/test/androidTest/x2t/gradle.properties deleted file mode 100644 index 0f9798ed931..00000000000 --- a/X2tConverter/test/androidTest/x2t/gradle.properties +++ /dev/null @@ -1 +0,0 @@ -# Add here module properties \ No newline at end of file diff --git a/X2tConverter/test/androidTest/x2t/proguard-rules.pro b/X2tConverter/test/androidTest/x2t/proguard-rules.pro deleted file mode 100644 index f1b424510da..00000000000 --- a/X2tConverter/test/androidTest/x2t/proguard-rules.pro +++ /dev/null @@ -1,21 +0,0 @@ -# Add project specific ProGuard rules here. -# You can control the set of applied configuration files using the -# proguardFiles setting in build.gradle. -# -# For more details, see -# http://developer.android.com/guide/developing/tools/proguard.html - -# If your project uses WebView with JS, uncomment the following -# and specify the fully qualified class name to the JavaScript interface -# class: -#-keepclassmembers class fqcn.of.javascript.interface.for.webview { -# public *; -#} - -# Uncomment this to preserve the line number information for -# debugging stack traces. -#-keepattributes SourceFile,LineNumberTable - -# If you keep the line number information, uncomment this to -# hide the original source file name. -#-renamesourcefileattribute SourceFile diff --git a/X2tConverter/test/androidTest/x2t/src/main/AndroidManifest.xml b/X2tConverter/test/androidTest/x2t/src/main/AndroidManifest.xml deleted file mode 100644 index d8f37022c3c..00000000000 --- a/X2tConverter/test/androidTest/x2t/src/main/AndroidManifest.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/X2tConverter/test/androidTest/x2t/src/main/java/app/x2t/ConverterActivity.kt b/X2tConverter/test/androidTest/x2t/src/main/java/app/x2t/ConverterActivity.kt deleted file mode 100644 index 01d39af3e52..00000000000 --- a/X2tConverter/test/androidTest/x2t/src/main/java/app/x2t/ConverterActivity.kt +++ /dev/null @@ -1,426 +0,0 @@ -package app.x2t - -import android.Manifest -import android.annotation.SuppressLint -import android.app.Activity -import android.content.Intent -import android.os.Bundle -import android.util.Log -import android.view.View -import android.widget.Toast -import androidx.annotation.RequiresPermission -import androidx.appcompat.app.AppCompatActivity -import app.x2t.utils.AsyncRoutines -import app.x2t.utils.FileUtils -import app.x2t.utils.PathUtils -import app.x2t.utils.PermissionUtils -import kotlinx.android.synthetic.main.activity_converter.* -import kotlinx.coroutines.launch -import lib.x2t.X2t - -class ConverterActivity : AppCompatActivity(), View.OnClickListener { - - companion object { - val TAG = ConverterActivity::class.java.simpleName - private const val REQUEST_CODE_DOC = 1 - private const val CONVERTER_PREFIX = "converter_" - private const val PERMISSION_READ_WRITE_STORAGE = 1 - private const val PERMISSION_CHOOSER_READ_STORAGE = 2 - } - - private val mToast: Toast by lazy { - Toast.makeText(this, "", Toast.LENGTH_LONG) - } - - private val mAsyncRoutines = AsyncRoutines() - private var mFilePath: String? = null - private var mFileName: String? = null - private var mFolderPath: String? = null - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setContentView(R.layout.activity_converter) - convertButton.setOnClickListener(this) - chooseButton.setOnClickListener(this) - } - - @SuppressLint("MissingPermission") - override fun onRequestPermissionsResult(requestCode: Int, permissions: Array, grantResults: IntArray) { - super.onRequestPermissionsResult(requestCode, permissions, grantResults) - when (requestCode) { - PERMISSION_READ_WRITE_STORAGE -> { - if (PermissionUtils.checkReadWritePermission(this)) { - converter() - } - } - - PERMISSION_CHOOSER_READ_STORAGE -> { - if (PermissionUtils.checkReadPermission(this)) { - browseDocuments() - } - } - } - } - - public override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { - super.onActivityResult(requestCode, resultCode, data) - if (resultCode == Activity.RESULT_OK) { - when (requestCode) { - REQUEST_CODE_DOC -> { - if (data != null && data.data != null) { - mFilePath = PathUtils.getPath(this, data.data!!) - - if (mFilePath != null) { - mFolderPath = mFilePath!!.substring(0, mFilePath!!.lastIndexOf("/")) - mFileName = mFilePath!!.replace(mFolderPath!! + "/", "") - logMessage("\n-------------------------------------------------") - logMessage("Source file path: " + mFilePath!!) - logMessage("Source file name: " + mFileName!!) - logMessage("Source folder path: " + mFolderPath!!) - } else { - showToast("UNKNOWN ERROR!") - logMessage("\nUNKNOWN ERROR!\n") - } - } - } - } - } - } - - @SuppressLint("MissingPermission") - override fun onClick(view: View) { - when (view.id) { - R.id.convertButton -> converter() - R.id.chooseButton -> browseDocuments() - } - } - - private fun converter() { - if (PermissionUtils.requestReadWritePermission(this, PERMISSION_READ_WRITE_STORAGE)) { - if (mFilePath != null && mFileName != null && mFolderPath != null) { - when (FileUtils.getExtension(mFilePath!!).toUpperCase()) { - "DOCX" -> docxConverter() - "XLSX" -> xlsxConverter() - "PPTX" -> pptxConverter() - "CSV" -> csvConverter() - "TXT" -> txtConverter() - else -> showToast("Unsupported format!") - } - } else { - showToast("Choose documents!") - } - } - } - - @SuppressLint("MissingPermission") - private fun docxConverter() { - val to1 = "$mFolderPath/docx_$CONVERTER_PREFIX$mFileName.doct.bin" - val to2 = "$mFolderPath/docx_$CONVERTER_PREFIX$mFileName.doct" - val to3 = "$mFolderPath/docx_bin_$CONVERTER_PREFIX$mFileName.docx" - val to4 = "$mFolderPath/docx_doct_$CONVERTER_PREFIX$mFileName.docx" - - val builder = X2t.builder().setContext(applicationContext) - - logMessage("\nStart DOCX converting...") - chooseButton.isEnabled = false - convertButton.isEnabled = false - - mAsyncRoutines.run({ foreground, instance -> - if (builder.setConvert(X2t.ConvertType.DOCX_DOCTBIN).setFrom(mFilePath!!).setTo(to1).convert()?.isSuccess) { - foreground.launch { logMessage("ConvertType PASS: $to1") } - - if (builder.setConvert(X2t.ConvertType.DOCX_DOCT).setFrom(mFilePath!!).setTo(to2).convert()?.isSuccess) { - foreground.launch { logMessage("ConvertType PASS: $to2") } - - if (builder.setConvert(X2t.ConvertType.DOCTBIN_DOCX).setFrom(to1).setTo(to3).convert()?.isSuccess) { - foreground.launch { logMessage("ConvertType PASS: $to3") } - - if (builder.setConvert(X2t.ConvertType.DOCT_DOCX).setFrom(to2).setTo(to4).convert()?.isSuccess) { - foreground.launch { logMessage("ConvertType PASS: $to4") } - } else { - foreground.launch { logMessage("ConvertType FAILED: $to4") } - } - } else { - foreground.launch { logMessage("ConvertType FAILED: $to3") } - } - } else { - foreground.launch { logMessage("ConvertType FAILED: $to2") } - } - } else { - foreground.launch { logMessage("\nConvertType FAILED: $to1") } - } - }, - { - showToast("All DOCX converts PASSED!") - chooseButton.isEnabled = true - convertButton.isEnabled = true - }, - - { - showToast("All DOCX converts FAILED!") - chooseButton.isEnabled = true - convertButton.isEnabled = true - } - ) - } - - @SuppressLint("MissingPermission") - private fun xlsxConverter() { - val to1 = "$mFolderPath/xlsx_$CONVERTER_PREFIX$mFileName.xlst.bin" - val to2 = "$mFolderPath/xlsx_$CONVERTER_PREFIX$mFileName.xlst" - val to3 = "$mFolderPath/xlsx_bin_$CONVERTER_PREFIX$mFileName.xlsx" - val to4 = "$mFolderPath/xlsx_xlst_$CONVERTER_PREFIX$mFileName.xlsx" - val to5 = "$mFolderPath/xlsx_csv_$CONVERTER_PREFIX$mFileName.csv" - - val builder = X2t.builder().setContext(applicationContext) - val inputParams = X2t.InputParams() - inputParams.delimiterChar = "," - - logMessage("\nStart XLSX converting...") - chooseButton.isEnabled = false - convertButton.isEnabled = false - - mAsyncRoutines.run({ foreground, instance -> - if (builder.setConvert(X2t.ConvertType.XLSX_XLSTBIN).setFrom(mFilePath!!).setTo(to1).convert()?.isSuccess) { - foreground.launch { logMessage("ConvertType PASS: $to1") } - - if (builder.setConvert(X2t.ConvertType.XLSX_XLST).setFrom(mFilePath!!).setTo(to2).convert()?.isSuccess) { - foreground.launch { logMessage("ConvertType PASS: $to2") } - - if (builder.setConvert(X2t.ConvertType.XLSTBIN_XLSX).setFrom(to1).setTo(to3).convert()?.isSuccess) { - foreground.launch { logMessage("ConvertType PASS: $to3") } - - if (builder.setConvert(X2t.ConvertType.XLST_XLSX).setFrom(to2).setTo(to4).convert()?.isSuccess) { - foreground.launch { logMessage("ConvertType PASS: $to4") } - - if (builder.setConvert(X2t.ConvertType.XLSX_CSV).setInputParams(inputParams).setFrom(mFilePath!!).setTo(to5).convert()?.isSuccess) { - foreground.launch { logMessage("ConvertType PASS: $to5") } - } else { - foreground.launch { logMessage("ConvertType FAILED: $to5") } - } - } else { - foreground.launch { logMessage("ConvertType FAILED: $to4") } - } - } else { - foreground.launch { logMessage("ConvertType FAILED: $to3") } - } - } else { - foreground.launch { logMessage("ConvertType FAILED: $to2") } - } - } else { - foreground.launch { logMessage("\nConvertType FAILED: $to1") } - } - }, - - { - showToast("All XLSX converts PASSED!") - chooseButton.isEnabled = true - convertButton.isEnabled = true - }, - - { - showToast("All XLSX converts FAILED!") - chooseButton.isEnabled = true - convertButton.isEnabled = true - } - ) - } - - @SuppressLint("MissingPermission") - private fun pptxConverter() { - val to1 = "$mFolderPath/pptx_$CONVERTER_PREFIX$mFileName.pptt.bin" - val to2 = "$mFolderPath/pptx_$CONVERTER_PREFIX$mFileName.pptt" - val to3 = "$mFolderPath/pptx_bin_$CONVERTER_PREFIX$mFileName.pptx" - val to4 = "$mFolderPath/pptx_xlst_$CONVERTER_PREFIX$mFileName.pptx" - val to5 = "$mFolderPath/pptx_odp_$CONVERTER_PREFIX$mFileName.odp" - - val builder = X2t.builder().setContext(applicationContext) - - logMessage("\nStart PPTX converting...") - chooseButton.isEnabled = false - convertButton.isEnabled = false - - mAsyncRoutines.run({ foreground, instance -> - if (builder.setConvert(X2t.ConvertType.PPTX_PPTTBIN).setFrom(mFilePath!!).setTo(to1).convert()?.isSuccess) { - foreground.launch { logMessage("ConvertType PASS: $to1") } - - if (builder.setConvert(X2t.ConvertType.PPTX_PPTT).setFrom(mFilePath!!).setTo(to2).convert()?.isSuccess) { - foreground.launch { logMessage("ConvertType PASS: $to2") } - - if (builder.setConvert(X2t.ConvertType.PPTTBIN_PPTX).setFrom(to1).setTo(to3).convert()?.isSuccess) { - foreground.launch { logMessage("ConvertType PASS: $to3") } - - if (builder.setConvert(X2t.ConvertType.PPTT_PPTX).setFrom(to2).setTo(to4).convert()?.isSuccess) { - foreground.launch { logMessage("ConvertType PASS: $to4") } - - if (builder.setConvert(X2t.ConvertType.PPTX_ODP).setFrom(to4).setTo(to5).convert()?.isSuccess) { - foreground.launch { logMessage("ConvertType PASS: $to5") } - } else { - foreground.launch { logMessage("ConvertType FAILED: $to5") } - } - } else { - foreground.launch { logMessage("ConvertType FAILED: $to4") } - } - } else { - foreground.launch { logMessage("ConvertType FAILED: $to3") } - } - } else { - foreground.launch { logMessage("ConvertType FAILED: $to2") } - } - } else { - foreground.launch { logMessage("\nConvertType FAILED: $to1") } - } - }, - - { - showToast("All PPTX converts PASSED!") - chooseButton.isEnabled = true - convertButton.isEnabled = true - }, - - { - showToast("All PPTX converts FAILED!") - chooseButton.isEnabled = true - convertButton.isEnabled = true - } - ) - } - - @SuppressLint("MissingPermission") - private fun csvConverter() { - val to1 = "$mFolderPath/csv_$CONVERTER_PREFIX$mFileName.xlst" - val to2 = "$mFolderPath/csv_$CONVERTER_PREFIX$mFileName.xlsx" - val to3 = "$mFolderPath/csv_$CONVERTER_PREFIX$mFileName.xlst.bin" - val to4 = "$mFolderPath/csv_xlst_bin_$CONVERTER_PREFIX$mFileName.xlsx" - val to5 = "$mFolderPath/csv_xlst_$CONVERTER_PREFIX$mFileName.csv" - val to6 = "$mFolderPath/csv_xlsx_$CONVERTER_PREFIX$mFileName.csv" - - val builder = X2t.builder().setContext(applicationContext) - val inputParams = X2t.InputParams() - inputParams.delimiterChar = "," - - logMessage("\nStart CSV converting...") - chooseButton.isEnabled = false - convertButton.isEnabled = false - - mAsyncRoutines.run({ foreground, instance -> - foreground.launch { logMessage("CSV available encodings:") } - X2t.getEncodings()?.forEach { - foreground.launch { logMessage(" $it") } - } - - if (builder.setConvert(X2t.ConvertType.CSV_XLST).setInputParams(inputParams).setFrom(mFilePath!!).setTo(to1).convert()?.isSuccess) { - foreground.launch { logMessage("ConvertType PASS: $to1") } - - if (builder.setConvert(X2t.ConvertType.CSV_XLSX).setInputParams(inputParams).setFrom(mFilePath!!).setTo(to2).convert()?.isSuccess) { - foreground.launch { logMessage("ConvertType PASS: $to2") } - - if (builder.setConvert(X2t.ConvertType.CSV_XLSTBIN).setInputParams(inputParams).setFrom(mFilePath!!).setTo(to3).convert()?.isSuccess) { - foreground.launch { logMessage("ConvertType PASS: $to3") } - - if (builder.setConvert(X2t.ConvertType.XLSTBIN_XLSX).setFrom(to3).setTo(to4).convert()?.isSuccess) { - foreground.launch { logMessage("ConvertType PASS: $to4") } - - if (builder.setConvert(X2t.ConvertType.XLST_CSV).setInputParams(inputParams).setFrom(to1).setTo(to5).convert()?.isSuccess) { - foreground.launch { logMessage("ConvertType PASS: $to5") } - - if (builder.setConvert(X2t.ConvertType.XLSX_CSV).setInputParams(inputParams).setFrom(to2).setTo(to6).convert()?.isSuccess) { - foreground.launch { logMessage("ConvertType PASS: $to6") } - } else { - foreground.launch { logMessage("ConvertType FAILED: $to6") } - } - } else { - foreground.launch { logMessage("ConvertType FAILED: $to5") } - } - } else { - foreground.launch { logMessage("ConvertType FAILED: $to4") } - } - } else { - foreground.launch { logMessage("ConvertType FAILED: $to3") } - } - } else { - foreground.launch { logMessage("ConvertType FAILED: $to2") } - } - } else { - foreground.launch { logMessage("\nConvertType FAILED: $to1") } - } - }, - - { - showToast("All CSV converts PASSED!") - chooseButton.isEnabled = true - convertButton.isEnabled = true - }, - - { - showToast("All CSV converts FAILED!") - chooseButton.isEnabled = true - convertButton.isEnabled = true - } - ) - } - - @SuppressLint("MissingPermission") - private fun txtConverter() { - val to1 = "$mFolderPath/$CONVERTER_PREFIX$mFileName.doct.bin" - val to2 = "$mFolderPath/$CONVERTER_PREFIX$mFileName.docx" - - val builder = X2t.builder().setContext(applicationContext) - - logMessage("\nStart TXT converting...") - chooseButton.isEnabled = false - convertButton.isEnabled = false - - mAsyncRoutines.run({ foreground, instance -> - if (builder.setConvert(X2t.ConvertType.TXT_DOCTBIN).setFrom(mFilePath!!).setTo(to1).convert()?.isSuccess) { - foreground.launch { logMessage("ConvertType PASS: $to1") } - - if (builder.setConvert(X2t.ConvertType.DOCTBIN_DOCX).setFrom(to1).setTo(to2).convert()?.isSuccess) { - foreground.launch { logMessage("ConvertType PASS: $to2") } - } else { - foreground.launch { logMessage("ConvertType FAILED: $to2") } - } - } else { - foreground.launch { logMessage("ConvertType FAILED: $to1") } - } - }, - - { - showToast("All TXT converts PASSED!") - chooseButton.isEnabled = true - convertButton.isEnabled = true - }, - - { - showToast("All TXT converts FAILED!") - chooseButton.isEnabled = true - convertButton.isEnabled = true - } - ) - } - - private fun showToast(message: String) { - mToast.setText(message) - mToast.show() - } - - private fun logMessage(message: String) { - Log.d(TAG, message) - val stringBuffer = StringBuffer() - stringBuffer.append(loggerText.text) - stringBuffer.append("\n").append(message) - loggerText.text = stringBuffer.toString() - scrollView.scrollTo(0, loggerText.bottom) - } - - @RequiresPermission(Manifest.permission.READ_EXTERNAL_STORAGE) - private fun browseDocuments() { - if (PermissionUtils.requestReadPermission(this, PERMISSION_CHOOSER_READ_STORAGE)) { - val intent = Intent(Intent.ACTION_GET_CONTENT) - intent.type = "*/*" - intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) - startActivityForResult(Intent.createChooser(intent, getString(R.string.button_choose)), REQUEST_CODE_DOC) - } - } - -} diff --git a/X2tConverter/test/androidTest/x2t/src/main/java/app/x2t/utils/AsyncRoutines.kt b/X2tConverter/test/androidTest/x2t/src/main/java/app/x2t/utils/AsyncRoutines.kt deleted file mode 100644 index 2067e37233d..00000000000 --- a/X2tConverter/test/androidTest/x2t/src/main/java/app/x2t/utils/AsyncRoutines.kt +++ /dev/null @@ -1,45 +0,0 @@ -package app.x2t.utils - -import kotlinx.coroutines.* -import kotlin.coroutines.CoroutineContext - -class AsyncRoutines(backgroundContext: CoroutineContext = Dispatchers.Default) { - - protected var mBackgroundContext: CoroutineContext = Dispatchers.Default - protected var mForegroundContext: CoroutineContext = Dispatchers.Main - protected var mScope: CoroutineScope = MainScope() - - init { - mBackgroundContext = backgroundContext - } - - suspend fun async(context: CoroutineContext = Dispatchers.Default, block: suspend () -> T): Deferred { - return mScope.async(context) { - block.invoke() - } - } - - fun run(onBackground: suspend (foreground: CoroutineScope, instance: AsyncRoutines) -> T, onComplete: ((T) -> Unit)? = null, onError: ((Throwable) -> Unit)? = null): Job { - return mScope.launch(mForegroundContext) { - try { - val result = withContext(mBackgroundContext) { - onBackground.invoke(this@launch, this@AsyncRoutines) - } - onComplete?.invoke(result) - } catch (e: Exception) { - onError?.invoke(e) - } - } - } - - fun cancel(): Boolean { - return try { - mScope.cancel() - true - } catch (e: CancellationException) { - false - } finally { - mScope = MainScope() - } - } -} \ No newline at end of file diff --git a/X2tConverter/test/androidTest/x2t/src/main/java/app/x2t/utils/FileUtils.kt b/X2tConverter/test/androidTest/x2t/src/main/java/app/x2t/utils/FileUtils.kt deleted file mode 100644 index de78c59688e..00000000000 --- a/X2tConverter/test/androidTest/x2t/src/main/java/app/x2t/utils/FileUtils.kt +++ /dev/null @@ -1,15 +0,0 @@ -package app.x2t.utils - -object FileUtils { - - @JvmStatic - fun getExtension(path: String): String { - var extension = "" - val index = path.lastIndexOf(".") + 1 - if (index >= 0 && index < path.length) { - extension = path.substring(index) - } - return extension - } - -} \ No newline at end of file diff --git a/X2tConverter/test/androidTest/x2t/src/main/java/app/x2t/utils/PathUtils.kt b/X2tConverter/test/androidTest/x2t/src/main/java/app/x2t/utils/PathUtils.kt deleted file mode 100644 index d9436ce6b96..00000000000 --- a/X2tConverter/test/androidTest/x2t/src/main/java/app/x2t/utils/PathUtils.kt +++ /dev/null @@ -1,172 +0,0 @@ -package app.x2t.utils - -import android.content.ContentUris -import android.content.Context -import android.net.Uri -import android.os.Build -import android.os.Environment -import android.provider.DocumentsContract -import android.provider.MediaStore -import java.io.File - -object PathUtils { - - @JvmStatic - private val CONTENT_DOWNLOAD = arrayOf( - "content://downloads/public_downloads", - "content://downloads/my_downloads" - ) - - @JvmStatic - fun getPath(context: Context, uri: Uri): String? { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && DocumentsContract.isDocumentUri(context, uri)) { - when { - isExternalStorageDocument(uri) -> { - val docId = DocumentsContract.getDocumentId(uri) - val split = docId.split(":".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray() - getPathFromExternal(split)?.let { - return it - } - } - - isDownloadsDocument(uri) -> { - context.contentResolver.query(uri, arrayOf(MediaStore.MediaColumns.DISPLAY_NAME), null, null, null)?.use { cursor -> - if (cursor.moveToFirst()) { - val name = cursor.getString(cursor.getColumnIndex(MediaStore.MediaColumns.DISPLAY_NAME)) - (Environment.getExternalStorageDirectory().toString() + "/Download/" + name)?.let { path -> - if (File(path).exists()) { - return path - } - } - (Environment.getExternalStorageDirectory().toString() + "/OnlyOffice/" + name)?.let { path -> - if (File(path).exists()) { - return path - } - } - (Environment.getExternalStorageDirectory().toString() + "/Р7/" + name)?.let { path -> - if (File(path).exists()) { - return path - } - } - } - } - - DocumentsContract.getDocumentId(uri)?.let { id -> - if (id.isNotEmpty()) { - if (id.startsWith("raw:")) { - return id.replaceFirst("raw:".toRegex(), "") - } - - id.toLongOrNull()?.let { number -> - CONTENT_DOWNLOAD.forEach { content -> - ContentUris.withAppendedId(Uri.parse(content), number)?.let { documentUri -> - getDataColumn(context, documentUri, null, null)?.let { - if (File(it).exists()) { - return it - } - } - } - } - } - } - } - } - - isMediaDocument(uri) -> { - DocumentsContract.getDocumentId(uri)?.let { id -> - val split = id.split(":".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray() - val type = split[0] - - when (type) { - "image" -> MediaStore.Images.Media.EXTERNAL_CONTENT_URI - "video" -> MediaStore.Video.Media.EXTERNAL_CONTENT_URI - "audio" -> MediaStore.Audio.Media.EXTERNAL_CONTENT_URI - else -> null - }?.let { mediaUri -> - getDataColumn(context, mediaUri, "_id=?", arrayOf(split[1]))?.let { - if (File(it).exists()) { - return it - } - } - } - } - } - } - - } else { - when (uri.scheme) { - "content" -> { - context.contentResolver.query(uri, arrayOf(MediaStore.Files.FileColumns.DATA), null, null, null)?.use { - if (it.moveToFirst()) { - return it.getString(it.getColumnIndexOrThrow(MediaStore.Files.FileColumns.DATA)) - } - } - } - - "file" -> { - return uri.path - } - } - } - - return null - } - - @JvmStatic - private fun getPathFromExternal(pathData: Array): String? { - val type = pathData[0] - val path = if (pathData.size == 1) { - "/" - } else { - "/" + pathData[1] - } - - - if ("primary".equals(type, ignoreCase = true)) { - (Environment.getExternalStorageDirectory().path + path)?.let { - if (File(it).exists()) { - return it - } - } - } - - (System.getenv("EXTERNAL_STORAGE") + path)?.let { - if (File(it).exists()) { - return it - } - } - - (System.getenv("SECONDARY_STORAGE") + path)?.let { - if (File(it).exists()) { - return it - } - } - - return null - } - - @JvmStatic - private fun getDataColumn(context: Context, uri: Uri?, selection: String?, selectionArgs: Array?): String? { - val column = "_data" - val projection = arrayOf(column) - - context.contentResolver.query(uri!!, projection, selection, selectionArgs, null)?.use { - if (it.moveToFirst()) { - val index = it.getColumnIndexOrThrow(column) - return it.getString(index) - } - } - - return null - } - - @JvmStatic - private fun isExternalStorageDocument(uri: Uri) = "com.android.externalstorage.documents" == uri.authority - - @JvmStatic - private fun isDownloadsDocument(uri: Uri) = "com.android.providers.downloads.documents" == uri.authority - - @JvmStatic - private fun isMediaDocument(uri: Uri) = "com.android.providers.media.documents" == uri.authority - -} \ No newline at end of file diff --git a/X2tConverter/test/androidTest/x2t/src/main/java/app/x2t/utils/PermissionUtils.kt b/X2tConverter/test/androidTest/x2t/src/main/java/app/x2t/utils/PermissionUtils.kt deleted file mode 100644 index 6257140dbe6..00000000000 --- a/X2tConverter/test/androidTest/x2t/src/main/java/app/x2t/utils/PermissionUtils.kt +++ /dev/null @@ -1,54 +0,0 @@ -package app.x2t.utils - -import android.Manifest -import android.content.Context -import android.content.pm.PackageManager -import androidx.appcompat.app.AppCompatActivity -import androidx.core.app.ActivityCompat -import androidx.core.content.ContextCompat - - -object PermissionUtils { - - @JvmStatic - fun checkPermission(context: Context, vararg permissions: String): Boolean { - permissions.forEach { permission -> - if (ContextCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) { - return false - } - } - return true - } - - @JvmStatic - fun requestPermission(activity: AppCompatActivity, requestCode: Int, vararg permissions: String): Boolean { - return if (!checkPermission(activity, *permissions)) { - ActivityCompat.requestPermissions(activity, permissions, requestCode) - false - } else { - true - } - } - - @JvmStatic - fun requestReadWritePermission(activity: AppCompatActivity, requestCode: Int): Boolean { - return requestPermission(activity, requestCode, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE) - } - - @JvmStatic - fun checkReadWritePermission(context: Context): Boolean { - return checkPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE) - } - - @JvmStatic - fun checkReadPermission(context: Context): Boolean { - return checkPermission(context, Manifest.permission.READ_EXTERNAL_STORAGE) - } - - @JvmStatic - fun requestReadPermission(activity: AppCompatActivity, requestCode: Int): Boolean { - return requestPermission(activity, requestCode, Manifest.permission.READ_EXTERNAL_STORAGE) - } - -} - diff --git a/X2tConverter/test/androidTest/x2t/src/main/res/drawable-v24/ic_launcher_foreground.xml b/X2tConverter/test/androidTest/x2t/src/main/res/drawable-v24/ic_launcher_foreground.xml deleted file mode 100644 index c7bd21dbd86..00000000000 --- a/X2tConverter/test/androidTest/x2t/src/main/res/drawable-v24/ic_launcher_foreground.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - - - diff --git a/X2tConverter/test/androidTest/x2t/src/main/res/drawable/ic_launcher_background.xml b/X2tConverter/test/androidTest/x2t/src/main/res/drawable/ic_launcher_background.xml deleted file mode 100644 index d5fccc538c1..00000000000 --- a/X2tConverter/test/androidTest/x2t/src/main/res/drawable/ic_launcher_background.xml +++ /dev/null @@ -1,170 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/X2tConverter/test/androidTest/x2t/src/main/res/layout/activity_converter.xml b/X2tConverter/test/androidTest/x2t/src/main/res/layout/activity_converter.xml deleted file mode 100644 index 1b3917a8fb9..00000000000 --- a/X2tConverter/test/androidTest/x2t/src/main/res/layout/activity_converter.xml +++ /dev/null @@ -1,54 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/X2tConverter/test/androidTest/x2t/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/X2tConverter/test/androidTest/x2t/src/main/res/mipmap-anydpi-v26/ic_launcher.xml deleted file mode 100644 index eca70cfe52e..00000000000 --- a/X2tConverter/test/androidTest/x2t/src/main/res/mipmap-anydpi-v26/ic_launcher.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/X2tConverter/test/androidTest/x2t/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/X2tConverter/test/androidTest/x2t/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml deleted file mode 100644 index eca70cfe52e..00000000000 --- a/X2tConverter/test/androidTest/x2t/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/X2tConverter/test/androidTest/x2t/src/main/res/mipmap-hdpi/ic_launcher.png b/X2tConverter/test/androidTest/x2t/src/main/res/mipmap-hdpi/ic_launcher.png deleted file mode 100644 index a2f5908281d..00000000000 Binary files a/X2tConverter/test/androidTest/x2t/src/main/res/mipmap-hdpi/ic_launcher.png and /dev/null differ diff --git a/X2tConverter/test/androidTest/x2t/src/main/res/mipmap-hdpi/ic_launcher_round.png b/X2tConverter/test/androidTest/x2t/src/main/res/mipmap-hdpi/ic_launcher_round.png deleted file mode 100644 index 1b523998081..00000000000 Binary files a/X2tConverter/test/androidTest/x2t/src/main/res/mipmap-hdpi/ic_launcher_round.png and /dev/null differ diff --git a/X2tConverter/test/androidTest/x2t/src/main/res/mipmap-mdpi/ic_launcher.png b/X2tConverter/test/androidTest/x2t/src/main/res/mipmap-mdpi/ic_launcher.png deleted file mode 100644 index ff10afd6e18..00000000000 Binary files a/X2tConverter/test/androidTest/x2t/src/main/res/mipmap-mdpi/ic_launcher.png and /dev/null differ diff --git a/X2tConverter/test/androidTest/x2t/src/main/res/mipmap-mdpi/ic_launcher_round.png b/X2tConverter/test/androidTest/x2t/src/main/res/mipmap-mdpi/ic_launcher_round.png deleted file mode 100644 index 115a4c768a2..00000000000 Binary files a/X2tConverter/test/androidTest/x2t/src/main/res/mipmap-mdpi/ic_launcher_round.png and /dev/null differ diff --git a/X2tConverter/test/androidTest/x2t/src/main/res/mipmap-xhdpi/ic_launcher.png b/X2tConverter/test/androidTest/x2t/src/main/res/mipmap-xhdpi/ic_launcher.png deleted file mode 100644 index dcd3cd80833..00000000000 Binary files a/X2tConverter/test/androidTest/x2t/src/main/res/mipmap-xhdpi/ic_launcher.png and /dev/null differ diff --git a/X2tConverter/test/androidTest/x2t/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/X2tConverter/test/androidTest/x2t/src/main/res/mipmap-xhdpi/ic_launcher_round.png deleted file mode 100644 index 459ca609d3a..00000000000 Binary files a/X2tConverter/test/androidTest/x2t/src/main/res/mipmap-xhdpi/ic_launcher_round.png and /dev/null differ diff --git a/X2tConverter/test/androidTest/x2t/src/main/res/mipmap-xxhdpi/ic_launcher.png b/X2tConverter/test/androidTest/x2t/src/main/res/mipmap-xxhdpi/ic_launcher.png deleted file mode 100644 index 8ca12fe024b..00000000000 Binary files a/X2tConverter/test/androidTest/x2t/src/main/res/mipmap-xxhdpi/ic_launcher.png and /dev/null differ diff --git a/X2tConverter/test/androidTest/x2t/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/X2tConverter/test/androidTest/x2t/src/main/res/mipmap-xxhdpi/ic_launcher_round.png deleted file mode 100644 index 8e19b410a1b..00000000000 Binary files a/X2tConverter/test/androidTest/x2t/src/main/res/mipmap-xxhdpi/ic_launcher_round.png and /dev/null differ diff --git a/X2tConverter/test/androidTest/x2t/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/X2tConverter/test/androidTest/x2t/src/main/res/mipmap-xxxhdpi/ic_launcher.png deleted file mode 100644 index b824ebdd48d..00000000000 Binary files a/X2tConverter/test/androidTest/x2t/src/main/res/mipmap-xxxhdpi/ic_launcher.png and /dev/null differ diff --git a/X2tConverter/test/androidTest/x2t/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/X2tConverter/test/androidTest/x2t/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png deleted file mode 100644 index 4c19a13c239..00000000000 Binary files a/X2tConverter/test/androidTest/x2t/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png and /dev/null differ diff --git a/X2tConverter/test/androidTest/x2t/src/main/res/values/colors.xml b/X2tConverter/test/androidTest/x2t/src/main/res/values/colors.xml deleted file mode 100644 index 3ab3e9cbce0..00000000000 --- a/X2tConverter/test/androidTest/x2t/src/main/res/values/colors.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - #3F51B5 - #303F9F - #FF4081 - diff --git a/X2tConverter/test/androidTest/x2t/src/main/res/values/strings.xml b/X2tConverter/test/androidTest/x2t/src/main/res/values/strings.xml deleted file mode 100644 index 670b8f6a1c3..00000000000 --- a/X2tConverter/test/androidTest/x2t/src/main/res/values/strings.xml +++ /dev/null @@ -1,6 +0,0 @@ - - Converter - Choose document for convertType... - Choose file - Start convertType - diff --git a/X2tConverter/test/androidTest/x2t/src/main/res/values/styles.xml b/X2tConverter/test/androidTest/x2t/src/main/res/values/styles.xml deleted file mode 100644 index 5885930df6d..00000000000 --- a/X2tConverter/test/androidTest/x2t/src/main/res/values/styles.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - diff --git a/X2tConverter/test/batch_convert/x2t_test/mainwindow.cpp b/X2tConverter/test/batch_convert/x2t_test/mainwindow.cpp deleted file mode 100644 index b8d4cc1cc98..00000000000 --- a/X2tConverter/test/batch_convert/x2t_test/mainwindow.cpp +++ /dev/null @@ -1,1457 +0,0 @@ -#include "mainwindow.h" -#include "ui_mainwindow.h" -#include - -#include -#include -#include -#include - -#include -#include - -#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 "../../../../DesktopEditor/fontengine/application_generate_fonts.h" - -#include - -class CDirectoryParse : public NSThreads::CBaseThread -{ -public: - std::wstring m_sDirectory; - std::vector m_files; - - MainWindow* m_window; - - CDirectoryParse() - { - m_window = NULL; - } - virtual ~CDirectoryParse() - { - } - - virtual DWORD ThreadProc() - { - m_files = NSDirectory::GetFiles(m_sDirectory, true); - - // fonts!!! - std::vector strFonts; - std::wstring strDirectory = NSFile::GetProcessDirectory() + L"/fonts"; - - 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; - } - } - - CApplicationFonts oApplication; - std::vector strFontsW_Cur = oApplication.GetSetupFontFiles(); - -#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"); - 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 = 0; -#if 1 - nFlag = 2; -#endif - - oApplication.InitializeFromArrayFiles(strFontsW_Cur, nFlag); - - NSCommon::SaveAllFontsJS(oApplication, strAllFontsJSPath, strThumbnailsFolder, strFontsSelectionBin); - } - - m_bRunThread = FALSE; - m_window->send_onDirectoryChecked(); - return 0; - } -}; - -class CFormatLogger -{ -public: - std::wstring m_name; - bool m_need; - - std::list m_greenSrc; - std::list m_greenDst; - - std::list m_yellowSrc; - std::list m_yellowDsc; - - std::list m_redSrc; - std::list m_redDst; - -public: - CFormatLogger(const std::wstring& name) - { - m_name = name; - clear(); - } - ~CFormatLogger() - { - } - - void clear() - { - m_greenSrc.clear(); - m_greenDst.clear(); - - m_yellowSrc.clear(); - m_yellowDsc.clear(); - - m_redSrc.clear(); - m_redDst.clear(); - } - - void Add(const int& code, const std::wstring& src, const std::wstring& dst) - { - if (0 == code) - { - m_greenSrc.push_back(src); - m_greenDst.push_back(dst); - } - else if (89 == code || 90 == code || 91 == code) - { - m_yellowSrc.push_back(src); - m_yellowDsc.push_back(dst); - } - else - { - m_redSrc.push_back(src); - m_redDst.push_back(dst); - } - } - - std::wstring GetMainHtml() - { - if (!m_need) - return L""; - - int nCountG = m_greenSrc.size(); - int nCountY = m_yellowSrc.size(); - int nCountR = m_redSrc.size(); - - int nCount = nCountG + nCountY + nCountR; - - if (0 == nCount) - return L""; - - int nPercentY = 100 * nCountY / nCount; if (nCountY != 0 && nPercentY == 0) nPercentY = 1; - int nPercentR = 100 * nCountR / nCount; if (nCountR != 0 && nPercentR == 0) nPercentR = 1; - int nPercentG = 100 - nPercentY - nPercentR; - - - NSStringUtils::CStringBuilder oBuilder; - oBuilder.WriteString(L""); - - oBuilder.WriteString(m_name); - oBuilder.WriteString(L" ("); - oBuilder.AddInt(nPercentG); - oBuilder.WriteString(L":"); - oBuilder.AddInt(nCountG); - oBuilder.WriteString(L" | "); - oBuilder.AddInt(nPercentY); - oBuilder.WriteString(L":"); - oBuilder.AddInt(nCountY); - oBuilder.WriteString(L" | "); - oBuilder.AddInt(nPercentR); - oBuilder.WriteString(L":"); - oBuilder.AddInt(nCountR); - oBuilder.WriteString(L")"); - - oBuilder.WriteString(L"
"); - - oBuilder.WriteString(L"
"); - - oBuilder.WriteString(L"
"); - - oBuilder.WriteString(L"
"); - - oBuilder.WriteString(L"
"); - - oBuilder.WriteString(L""); - - return oBuilder.GetData(); - } - - std::wstring GetHtml() - { - if (!m_need) - return L""; - - int nCountG = m_greenSrc.size(); - int nCountY = m_yellowSrc.size(); - int nCountR = m_redSrc.size(); - - int nCount = nCountG + nCountY + nCountR; - - if (0 == nCount) - return L""; - - NSStringUtils::CStringBuilder oBuilder; - oBuilder.WriteString(L""); - - std::list::iterator i, j; - for (i = m_greenSrc.begin(), j = m_greenDst.begin(); i != m_greenSrc.end(); i++, j++) - { - oBuilder.WriteString(L""); - } - for (i = m_yellowSrc.begin(), j = m_yellowDsc.begin(); i != m_yellowSrc.end(); i++, j++) - { - oBuilder.WriteString(L""); - } - for (i = m_redSrc.begin(), j = m_redDst.begin(); i != m_redSrc.end(); i++, j++) - { - oBuilder.WriteString(L""); - } - - oBuilder.WriteString(L"
"); - oBuilder.WriteString(m_name); - oBuilder.WriteString(L"
"); - oBuilder.WriteEncodeXmlString(*i); - oBuilder.WriteString(L""); - oBuilder.WriteEncodeXmlString(*j); - oBuilder.WriteString(L"
"); - oBuilder.WriteEncodeXmlString(*i); - oBuilder.WriteString(L""); - oBuilder.WriteEncodeXmlString(*j); - oBuilder.WriteString(L"
"); - oBuilder.WriteEncodeXmlString(*i); - oBuilder.WriteString(L""); - oBuilder.WriteEncodeXmlString(*j); - oBuilder.WriteString(L"
"); - - return oBuilder.GetData(); - } -}; - -class CConverter; -class CInternalWorker -{ -public: - std::map m_formats; - std::map m_logger; - - CDirectoryParse* m_pParser; - - int m_dst_format; - - int m_nCount; - int m_nCurrent; - int m_nCurrentConvert; - - NSCriticalSection::CRITICAL_SECTION m_oCS; - -public: - CInternalWorker() - { - m_formats.insert(std::make_pair(AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX, true)); - m_formats.insert(std::make_pair(AVS_OFFICESTUDIO_FILE_DOCUMENT_DOC, true)); - m_formats.insert(std::make_pair(AVS_OFFICESTUDIO_FILE_DOCUMENT_ODT, true)); - m_formats.insert(std::make_pair(AVS_OFFICESTUDIO_FILE_DOCUMENT_RTF, true)); - m_formats.insert(std::make_pair(AVS_OFFICESTUDIO_FILE_DOCUMENT_TXT, true)); - m_formats.insert(std::make_pair(AVS_OFFICESTUDIO_FILE_DOCUMENT_HTML, true)); - - m_formats.insert(std::make_pair(AVS_OFFICESTUDIO_FILE_PRESENTATION_PPTX, true)); - m_formats.insert(std::make_pair(AVS_OFFICESTUDIO_FILE_PRESENTATION_PPSX, true)); - m_formats.insert(std::make_pair(AVS_OFFICESTUDIO_FILE_PRESENTATION_PPT, true)); - m_formats.insert(std::make_pair(AVS_OFFICESTUDIO_FILE_PRESENTATION_ODP, true)); - - m_formats.insert(std::make_pair(AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSX, true)); - m_formats.insert(std::make_pair(AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLS, true)); - m_formats.insert(std::make_pair(AVS_OFFICESTUDIO_FILE_SPREADSHEET_ODS, true)); - m_formats.insert(std::make_pair(AVS_OFFICESTUDIO_FILE_SPREADSHEET_CSV, true)); - - m_formats.insert(std::make_pair(AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_PDF, true)); - m_formats.insert(std::make_pair(AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_DJVU, true)); - m_formats.insert(std::make_pair(AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_XPS, true)); - - m_logger.insert(std::make_pair(AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX, CFormatLogger(L"DOCX"))); - m_logger.insert(std::make_pair(AVS_OFFICESTUDIO_FILE_DOCUMENT_DOC, CFormatLogger(L"DOC"))); - m_logger.insert(std::make_pair(AVS_OFFICESTUDIO_FILE_DOCUMENT_ODT, CFormatLogger(L"ODT"))); - m_logger.insert(std::make_pair(AVS_OFFICESTUDIO_FILE_DOCUMENT_RTF, CFormatLogger(L"RTF"))); - m_logger.insert(std::make_pair(AVS_OFFICESTUDIO_FILE_DOCUMENT_TXT, CFormatLogger(L"TXT"))); - m_logger.insert(std::make_pair(AVS_OFFICESTUDIO_FILE_DOCUMENT_HTML, CFormatLogger(L"HTML"))); - - m_logger.insert(std::make_pair(AVS_OFFICESTUDIO_FILE_PRESENTATION_PPTX, CFormatLogger(L"PPTX"))); - m_logger.insert(std::make_pair(AVS_OFFICESTUDIO_FILE_PRESENTATION_PPSX, CFormatLogger(L"PPSX"))); - m_logger.insert(std::make_pair(AVS_OFFICESTUDIO_FILE_PRESENTATION_PPT, CFormatLogger(L"PPT"))); - m_logger.insert(std::make_pair(AVS_OFFICESTUDIO_FILE_PRESENTATION_ODP, CFormatLogger(L"ODP"))); - - m_logger.insert(std::make_pair(AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSX, CFormatLogger(L"XLSX"))); - m_logger.insert(std::make_pair(AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLS, CFormatLogger(L"XLS"))); - m_logger.insert(std::make_pair(AVS_OFFICESTUDIO_FILE_SPREADSHEET_ODS, CFormatLogger(L"ODS"))); - m_logger.insert(std::make_pair(AVS_OFFICESTUDIO_FILE_SPREADSHEET_CSV, CFormatLogger(L"CSV"))); - - m_logger.insert(std::make_pair(AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_PDF, CFormatLogger(L"PDF"))); - m_logger.insert(std::make_pair(AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_DJVU, CFormatLogger(L"DJVU"))); - m_logger.insert(std::make_pair(AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_XPS, CFormatLogger(L"XPS"))); - - m_pParser = new CDirectoryParse(); - - m_dst_format = 0; - - m_nCount = 0; - m_nCurrent = 0; - - m_oCS.InitializeCriticalSection(); - } - ~CInternalWorker() - { - RELEASEOBJECT(m_pParser); - - m_oCS.DeleteCriticalSection(); - } - - void setDestinationInternal(bool isTrue = true) - { - if (isTrue) - { - m_formats.find(AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX)->second = true; - m_formats.find(AVS_OFFICESTUDIO_FILE_DOCUMENT_DOC)->second = true; - m_formats.find(AVS_OFFICESTUDIO_FILE_DOCUMENT_ODT)->second = true; - m_formats.find(AVS_OFFICESTUDIO_FILE_DOCUMENT_RTF)->second = true; - m_formats.find(AVS_OFFICESTUDIO_FILE_DOCUMENT_TXT)->second = true; - m_formats.find(AVS_OFFICESTUDIO_FILE_DOCUMENT_HTML)->second = true; - - m_formats.find(AVS_OFFICESTUDIO_FILE_PRESENTATION_PPTX)->second = true; - m_formats.find(AVS_OFFICESTUDIO_FILE_PRESENTATION_PPSX)->second = true; - m_formats.find(AVS_OFFICESTUDIO_FILE_PRESENTATION_PPT)->second = true; - m_formats.find(AVS_OFFICESTUDIO_FILE_PRESENTATION_ODP)->second = true; - - m_formats.find(AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSX)->second = true; - m_formats.find(AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLS)->second = true; - m_formats.find(AVS_OFFICESTUDIO_FILE_SPREADSHEET_ODS)->second = true; - m_formats.find(AVS_OFFICESTUDIO_FILE_SPREADSHEET_CSV)->second = true; - - m_formats.find(AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_PDF)->second = true; - m_formats.find(AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_DJVU)->second = true; - m_formats.find(AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_XPS)->second = true; - } - } - - void setDestinationDocument(bool isTrue = true) - { - if (isTrue) - { - m_formats.find(AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX)->second = true; - m_formats.find(AVS_OFFICESTUDIO_FILE_DOCUMENT_DOC)->second = true; - m_formats.find(AVS_OFFICESTUDIO_FILE_DOCUMENT_ODT)->second = true; - m_formats.find(AVS_OFFICESTUDIO_FILE_DOCUMENT_RTF)->second = true; - m_formats.find(AVS_OFFICESTUDIO_FILE_DOCUMENT_TXT)->second = true; - m_formats.find(AVS_OFFICESTUDIO_FILE_DOCUMENT_HTML)->second = true; - } - - m_formats.find(AVS_OFFICESTUDIO_FILE_PRESENTATION_PPTX)->second = false; - m_formats.find(AVS_OFFICESTUDIO_FILE_PRESENTATION_PPSX)->second = false; - m_formats.find(AVS_OFFICESTUDIO_FILE_PRESENTATION_PPT)->second = false; - m_formats.find(AVS_OFFICESTUDIO_FILE_PRESENTATION_ODP)->second = false; - - m_formats.find(AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSX)->second = false; - m_formats.find(AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLS)->second = false; - m_formats.find(AVS_OFFICESTUDIO_FILE_SPREADSHEET_ODS)->second = false; - m_formats.find(AVS_OFFICESTUDIO_FILE_SPREADSHEET_CSV)->second = false; - - m_formats.find(AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_PDF)->second = false; - m_formats.find(AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_DJVU)->second = false; - m_formats.find(AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_XPS)->second = false; - } - - void setDestinationPresentation(bool isTrue = true) - { - m_formats.find(AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX)->second = false; - m_formats.find(AVS_OFFICESTUDIO_FILE_DOCUMENT_DOC)->second = false; - m_formats.find(AVS_OFFICESTUDIO_FILE_DOCUMENT_ODT)->second = false; - m_formats.find(AVS_OFFICESTUDIO_FILE_DOCUMENT_RTF)->second = false; - m_formats.find(AVS_OFFICESTUDIO_FILE_DOCUMENT_TXT)->second = false; - m_formats.find(AVS_OFFICESTUDIO_FILE_DOCUMENT_HTML)->second = false; - - if (isTrue) - { - m_formats.find(AVS_OFFICESTUDIO_FILE_PRESENTATION_PPTX)->second = true; - m_formats.find(AVS_OFFICESTUDIO_FILE_PRESENTATION_PPSX)->second = true; - m_formats.find(AVS_OFFICESTUDIO_FILE_PRESENTATION_PPT)->second = true; - m_formats.find(AVS_OFFICESTUDIO_FILE_PRESENTATION_ODP)->second = true; - } - - m_formats.find(AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSX)->second = false; - m_formats.find(AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLS)->second = false; - m_formats.find(AVS_OFFICESTUDIO_FILE_SPREADSHEET_ODS)->second = false; - m_formats.find(AVS_OFFICESTUDIO_FILE_SPREADSHEET_CSV)->second = false; - - m_formats.find(AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_PDF)->second = false; - m_formats.find(AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_DJVU)->second = false; - m_formats.find(AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_XPS)->second = false; - } - - void setDestinationSpreadsheet(bool isTrue = true) - { - m_formats.find(AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX)->second = false; - m_formats.find(AVS_OFFICESTUDIO_FILE_DOCUMENT_DOC)->second = false; - m_formats.find(AVS_OFFICESTUDIO_FILE_DOCUMENT_ODT)->second = false; - m_formats.find(AVS_OFFICESTUDIO_FILE_DOCUMENT_RTF)->second = false; - m_formats.find(AVS_OFFICESTUDIO_FILE_DOCUMENT_TXT)->second = false; - m_formats.find(AVS_OFFICESTUDIO_FILE_DOCUMENT_HTML)->second = false; - - m_formats.find(AVS_OFFICESTUDIO_FILE_PRESENTATION_PPTX)->second = false; - m_formats.find(AVS_OFFICESTUDIO_FILE_PRESENTATION_PPSX)->second = false; - m_formats.find(AVS_OFFICESTUDIO_FILE_PRESENTATION_PPT)->second = false; - m_formats.find(AVS_OFFICESTUDIO_FILE_PRESENTATION_ODP)->second = false; - - if (isTrue) - { - m_formats.find(AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSX)->second = true; - m_formats.find(AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLS)->second = true; - m_formats.find(AVS_OFFICESTUDIO_FILE_SPREADSHEET_ODS)->second = true; - m_formats.find(AVS_OFFICESTUDIO_FILE_SPREADSHEET_CSV)->second = true; - } - - m_formats.find(AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_PDF)->second = false; - m_formats.find(AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_DJVU)->second = false; - m_formats.find(AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_XPS)->second = false; - } - - void setDestinationPDF(bool isTrue = true) - { - if (isTrue) - { - m_formats.find(AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX)->second = true; - m_formats.find(AVS_OFFICESTUDIO_FILE_DOCUMENT_DOC)->second = true; - m_formats.find(AVS_OFFICESTUDIO_FILE_DOCUMENT_ODT)->second = true; - m_formats.find(AVS_OFFICESTUDIO_FILE_DOCUMENT_RTF)->second = true; - m_formats.find(AVS_OFFICESTUDIO_FILE_DOCUMENT_TXT)->second = true; - m_formats.find(AVS_OFFICESTUDIO_FILE_DOCUMENT_HTML)->second = true; - - m_formats.find(AVS_OFFICESTUDIO_FILE_PRESENTATION_PPTX)->second = true; - m_formats.find(AVS_OFFICESTUDIO_FILE_PRESENTATION_PPSX)->second = true; - m_formats.find(AVS_OFFICESTUDIO_FILE_PRESENTATION_PPT)->second = true; - m_formats.find(AVS_OFFICESTUDIO_FILE_PRESENTATION_ODP)->second = true; - - m_formats.find(AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSX)->second = true; - m_formats.find(AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLS)->second = true; - m_formats.find(AVS_OFFICESTUDIO_FILE_SPREADSHEET_ODS)->second = true; - m_formats.find(AVS_OFFICESTUDIO_FILE_SPREADSHEET_CSV)->second = true; - } - - m_formats.find(AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_PDF)->second = false; - m_formats.find(AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_DJVU)->second = false; - m_formats.find(AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_XPS)->second = false; - } - - CConverter* GetNextConverter(); - void OnConvertFile(CConverter* pConverter, int nCode); - void Start(int nCores); - void Cancel(); - - void Log() - { - NSStringUtils::CStringBuilder oBuilder; - - oBuilder.WriteString(L"\ -\ -\ -\ -\ -"); - - oBuilder.WriteString(m_logger.find(AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX)->second.GetMainHtml()); - oBuilder.WriteString(m_logger.find(AVS_OFFICESTUDIO_FILE_DOCUMENT_DOC)->second.GetMainHtml()); - oBuilder.WriteString(m_logger.find(AVS_OFFICESTUDIO_FILE_DOCUMENT_ODT)->second.GetMainHtml()); - oBuilder.WriteString(m_logger.find(AVS_OFFICESTUDIO_FILE_DOCUMENT_RTF)->second.GetMainHtml()); - oBuilder.WriteString(m_logger.find(AVS_OFFICESTUDIO_FILE_DOCUMENT_TXT)->second.GetMainHtml()); - oBuilder.WriteString(m_logger.find(AVS_OFFICESTUDIO_FILE_DOCUMENT_HTML)->second.GetMainHtml()); - - oBuilder.WriteString(m_logger.find(AVS_OFFICESTUDIO_FILE_PRESENTATION_PPTX)->second.GetMainHtml()); - oBuilder.WriteString(m_logger.find(AVS_OFFICESTUDIO_FILE_PRESENTATION_PPSX)->second.GetMainHtml()); - oBuilder.WriteString(m_logger.find(AVS_OFFICESTUDIO_FILE_PRESENTATION_PPT)->second.GetMainHtml()); - oBuilder.WriteString(m_logger.find(AVS_OFFICESTUDIO_FILE_PRESENTATION_ODP)->second.GetMainHtml()); - - oBuilder.WriteString(m_logger.find(AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSX)->second.GetMainHtml()); - oBuilder.WriteString(m_logger.find(AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLS)->second.GetMainHtml()); - oBuilder.WriteString(m_logger.find(AVS_OFFICESTUDIO_FILE_SPREADSHEET_ODS)->second.GetMainHtml()); - oBuilder.WriteString(m_logger.find(AVS_OFFICESTUDIO_FILE_SPREADSHEET_CSV)->second.GetMainHtml()); - - oBuilder.WriteString(m_logger.find(AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_PDF)->second.GetMainHtml()); - oBuilder.WriteString(m_logger.find(AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_DJVU)->second.GetMainHtml()); - oBuilder.WriteString(m_logger.find(AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_XPS)->second.GetMainHtml()); - - oBuilder.WriteString(m_logger.find(AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX)->second.GetHtml()); - oBuilder.WriteString(m_logger.find(AVS_OFFICESTUDIO_FILE_DOCUMENT_DOC)->second.GetHtml()); - oBuilder.WriteString(m_logger.find(AVS_OFFICESTUDIO_FILE_DOCUMENT_ODT)->second.GetHtml()); - oBuilder.WriteString(m_logger.find(AVS_OFFICESTUDIO_FILE_DOCUMENT_RTF)->second.GetHtml()); - oBuilder.WriteString(m_logger.find(AVS_OFFICESTUDIO_FILE_DOCUMENT_TXT)->second.GetHtml()); - oBuilder.WriteString(m_logger.find(AVS_OFFICESTUDIO_FILE_DOCUMENT_HTML)->second.GetHtml()); - - oBuilder.WriteString(m_logger.find(AVS_OFFICESTUDIO_FILE_PRESENTATION_PPTX)->second.GetHtml()); - oBuilder.WriteString(m_logger.find(AVS_OFFICESTUDIO_FILE_PRESENTATION_PPSX)->second.GetHtml()); - oBuilder.WriteString(m_logger.find(AVS_OFFICESTUDIO_FILE_PRESENTATION_PPT)->second.GetHtml()); - oBuilder.WriteString(m_logger.find(AVS_OFFICESTUDIO_FILE_PRESENTATION_ODP)->second.GetHtml()); - - oBuilder.WriteString(m_logger.find(AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSX)->second.GetHtml()); - oBuilder.WriteString(m_logger.find(AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLS)->second.GetHtml()); - oBuilder.WriteString(m_logger.find(AVS_OFFICESTUDIO_FILE_SPREADSHEET_ODS)->second.GetHtml()); - oBuilder.WriteString(m_logger.find(AVS_OFFICESTUDIO_FILE_SPREADSHEET_CSV)->second.GetHtml()); - - oBuilder.WriteString(m_logger.find(AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_PDF)->second.GetHtml()); - oBuilder.WriteString(m_logger.find(AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_DJVU)->second.GetHtml()); - oBuilder.WriteString(m_logger.find(AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_XPS)->second.GetHtml()); - - oBuilder.WriteString(L"
Summary
"); - - std::wstring sTime = QDateTime::currentDateTime().toString().toStdWString(); - NSCommon::string_replace(sTime, L":", L"."); - - std::wstring sDirectory = NSFile::GetProcessDirectory() + L"/report"; - if (!NSDirectory::Exists(sDirectory)) - NSDirectory::CreateDirectory(sDirectory); - - NSFile::CFileBinary::SaveToFile(sDirectory + L"/" + sTime + L".html", oBuilder.GetData(), true); - } -}; - -class CConverter : public NSThreads::CBaseThread -{ -public: - CInternalWorker* m_pInternal; - std::wstring m_file; - std::wstring m_file_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; - - std::map::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; - } - - std::wstring sProcess = NSFile::GetProcessDirectory(); - - NSCommon::string_replace(sProcess, L"\\", L"/"); - NSCommon::string_replace(m_file, L"\\", L"/"); - - std::wstring sDirectoryDst = NSDirectory::CreateDirectoryWithUniqueName(sProcess + L"/Result"); - 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""); - - std::wstring sSrcCopy = sDirectoryDst + L"/" + NSCommon::GetFileName(m_file); - NSFile::CFileBinary::Copy(m_file, sSrcCopy); - - oBuilder.WriteEncodeXmlString(sSrcCopy); - oBuilder.WriteString(L""); - - std::wstring sExt = oChecker.GetExtensionByType(m_pInternal->m_dst_format); - if (sExt.empty()) - sExt = L".bin"; - - std::wstring sFileDst = sDirectoryDst + L"/result" + sExt; - - m_file_dst = sFileDst; - - oBuilder.WriteEncodeXmlString(sFileDst); - oBuilder.WriteString(L""); - oBuilder.WriteString(std::to_wstring(m_pInternal->m_dst_format)); - oBuilder.WriteString(L"../true"); - oBuilder.WriteString(sProcess + L"/fonts"); - oBuilder.WriteString(L"/AllFonts.js464"); - - oBuilder.WriteString(L""); - oBuilder.WriteEncodeXmlString(sProcess + L"/fonts"); - oBuilder.WriteString(L""); - - oBuilder.WriteString(L""); - - std::wstring sXmlConvert = oBuilder.GetData(); - - std::wstring sTempFileForParams = sDirectoryDst + L"/params.xml"; - NSFile::CFileBinary::SaveToFile(sTempFileForParams, sXmlConvert, true); - - std::wstring sConverterExe = sProcess + L"/x2t"; - int nReturnCode = 0; - -#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"; - - STARTUPINFOW 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'; - } - - 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(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); - - m_bRunThread = FALSE; - - m_pInternal->OnConvertFile(this, nReturnCode); - return 0; - } -}; - -CConverter* CInternalWorker::GetNextConverter() -{ - if (m_nCurrent >= m_nCount) - return NULL; - - CConverter* pConverter = new CConverter(this); - pConverter->m_file = m_pParser->m_files[m_nCurrent]; - ++m_nCurrent; - - pConverter->Start(0); - return pConverter; -} - -void CInternalWorker::OnConvertFile(CConverter* pConverter, int nCode) -{ - CTemporaryCS oCS(&m_oCS); - - if (-1 != nCode) - { - std::map::iterator _logger = m_logger.find(pConverter->m_format); - if (_logger != m_logger.end()) - _logger->second.Add(nCode, pConverter->m_file, pConverter->m_file_dst); - } - - ++m_nCurrentConvert; - - RELEASEOBJECT(pConverter); - GetNextConverter(); - - m_pParser->m_window->send_onFileConverted(m_nCurrentConvert); -} - -void CInternalWorker::Start(int nCores) -{ - CTemporaryCS oCS(&m_oCS); - - int nSizeInit = nCores; - if (nSizeInit > m_nCount) - nSizeInit = m_nCount; - - for (std::map::iterator i = m_logger.begin(); i != m_logger.end(); i++) - { - i->second.clear(); - i->second.m_need = m_formats.find(i->first)->second; - } - - for (int i = 0; i < nSizeInit; ++i) - GetNextConverter(); -} - -void CInternalWorker::Cancel() -{ - CTemporaryCS oCS(&m_oCS); - m_nCount = m_nCurrent; -} - -MainWindow::MainWindow(QWidget *parent) : - QMainWindow(parent), - ui(new Ui::MainWindow) -{ - ui->setupUi(this); - - this->setWindowTitle("x2t"); - - QObject::connect( ui->pushButtonDirectory, SIGNAL( clicked() ), this, SLOT( pushButtonDirectoryClicked() ), Qt::QueuedConnection ); - QObject::connect( ui->comboBoxOUTPUT, SIGNAL( currentIndexChanged(int) ), this, SLOT( outputIndexChanged(int) ), Qt::QueuedConnection ); - - QObject::connect( ui->checkBoxDOCX, SIGNAL( toggled(bool) ), this, SLOT( stateChanged_DOCX(bool) ), Qt::QueuedConnection ); - QObject::connect( ui->checkBoxDOC, SIGNAL( toggled(bool) ), this, SLOT( stateChanged_DOC(bool) ), Qt::QueuedConnection ); - QObject::connect( ui->checkBoxODT, SIGNAL( toggled(bool) ), this, SLOT( stateChanged_ODT(bool) ), Qt::QueuedConnection ); - QObject::connect( ui->checkBoxRTF, SIGNAL( toggled(bool) ), this, SLOT( stateChanged_RTF(bool) ), Qt::QueuedConnection ); - QObject::connect( ui->checkBoxTXT, SIGNAL( toggled(bool) ), this, SLOT( stateChanged_TXT(bool) ), Qt::QueuedConnection ); - QObject::connect( ui->checkBoxHTML, SIGNAL( toggled(bool) ), this, SLOT( stateChanged_HTML(bool) ), Qt::QueuedConnection ); - QObject::connect( ui->checkBoxDOC_ALL, SIGNAL( toggled(bool) ), this, SLOT( stateChanged_DOC_ALL(bool) ), Qt::QueuedConnection ); - - QObject::connect( ui->checkBoxPPTX, SIGNAL( toggled(bool) ), this, SLOT( stateChanged_PPTX(bool) ), Qt::QueuedConnection ); - QObject::connect( ui->checkBoxPPT, SIGNAL( toggled(bool) ), this, SLOT( stateChanged_PPT(bool) ), Qt::QueuedConnection ); - QObject::connect( ui->checkBoxODP, SIGNAL( toggled(bool) ), this, SLOT( stateChanged_ODP(bool) ), Qt::QueuedConnection ); - QObject::connect( ui->checkBoxPPT_ALL, SIGNAL( toggled(bool) ), this, SLOT( stateChanged_PPT_ALL(bool) ), Qt::QueuedConnection ); - - QObject::connect( ui->checkBoxXLSX, SIGNAL( toggled(bool) ), this, SLOT( stateChanged_XLSX(bool) ), Qt::QueuedConnection ); - QObject::connect( ui->checkBoxXLS, SIGNAL( toggled(bool) ), this, SLOT( stateChanged_XLS(bool) ), Qt::QueuedConnection ); - QObject::connect( ui->checkBoxODS, SIGNAL( toggled(bool) ), this, SLOT( stateChanged_ODS(bool) ), Qt::QueuedConnection ); - QObject::connect( ui->checkBoxCSV, SIGNAL( toggled(bool) ), this, SLOT( stateChanged_CSV(bool) ), Qt::QueuedConnection ); - QObject::connect( ui->checkBoxXLS_ALL, SIGNAL( toggled(bool) ), this, SLOT( stateChanged_XLS_ALL(bool) ), Qt::QueuedConnection ); - - QObject::connect( ui->checkBoxPDF, SIGNAL( toggled(bool) ), this, SLOT( stateChanged_PDF(bool) ), Qt::QueuedConnection ); - QObject::connect( ui->checkBoxXPS, SIGNAL( toggled(bool) ), this, SLOT( stateChanged_XPS(bool) ), Qt::QueuedConnection ); - QObject::connect( ui->checkBoxDJVU, SIGNAL( toggled(bool) ), this, SLOT( stateChanged_DJVU(bool) ), Qt::QueuedConnection ); - QObject::connect( ui->checkBoxDJVU_ALL, SIGNAL( toggled(bool) ), this, SLOT( stateChanged_DJVU_ALL(bool) ), Qt::QueuedConnection ); - - QObject::connect( ui->pushButtonConvert, SIGNAL( clicked() ), this, SLOT( pushButtonConvertClicked() ), Qt::QueuedConnection ); - - QObject::connect( this, SIGNAL( signal_onDirectoryChecked() ), this, SLOT( slot_onDirectoryChecked() ), Qt::QueuedConnection ); - QObject::connect( this, SIGNAL( signal_onFileConverted(int) ), this, SLOT( slot_onFileConverted(int) ), Qt::QueuedConnection ); - - ui->textEditDirectory->setEnabled(false); - - m_pWorker = new CInternalWorker(); - - ui->groupBoxINPUT->setTitle("Input"); - ui->groupBoxOUTPUT->setTitle("Output"); - - ui->spinBoxThreads->setMinimum(1); - int nCount = (int)std::thread::hardware_concurrency(); - if (nCount == 0) - nCount = 1; - ui->spinBoxThreads->setMaximum((int)(1.5 * nCount + 0.5)); - ui->spinBoxThreads->setValue(nCount); - - ui->checkBoxDOCX->setText("docx"); - ui->checkBoxDOC->setText("doc"); - ui->checkBoxODT->setText("odt"); - ui->checkBoxRTF->setText("rtf"); - ui->checkBoxTXT->setText("txt"); - ui->checkBoxHTML->setText("html"); - ui->checkBoxDOC_ALL->setText("all"); - - ui->checkBoxPPTX->setText("pptx"); - ui->checkBoxPPT->setText("ppt"); - ui->checkBoxODP->setText("odp"); - ui->checkBoxPPT_ALL->setText("all"); - - ui->checkBoxXLSX->setText("xlsx"); - ui->checkBoxXLS->setText("xls"); - ui->checkBoxODS->setText("ods"); - ui->checkBoxCSV->setText("csv"); - ui->checkBoxXLS_ALL->setText("all"); - - ui->checkBoxPDF->setText("pdf"); - ui->checkBoxXPS->setText("xps"); - ui->checkBoxDJVU->setText("djvu"); - ui->checkBoxDJVU_ALL->setText("all"); - - ui->labelThreads->setText("Cores"); - - ui->comboBoxOUTPUT->addItem("internal"); - ui->comboBoxOUTPUT->addItem("docx"); - ui->comboBoxOUTPUT->addItem("doc"); - ui->comboBoxOUTPUT->addItem("odt"); - ui->comboBoxOUTPUT->addItem("rtf"); - ui->comboBoxOUTPUT->addItem("txt"); - - ui->comboBoxOUTPUT->addItem("pptx"); - ui->comboBoxOUTPUT->addItem("odp"); - - ui->comboBoxOUTPUT->addItem("xlsx"); - ui->comboBoxOUTPUT->addItem("xls"); - ui->comboBoxOUTPUT->addItem("ods"); - ui->comboBoxOUTPUT->addItem("csv"); - - ui->comboBoxOUTPUT->addItem("pdf"); - - ui->labelOutput->setText("Format"); - - ui->pushButtonConvert->setText("CONVERT"); - - this->setMinimumSize(500, 600); - this->resize(500, 600); - - ui->textEdit->setEnabled(false); - - ui->textEdit->setVisible(false); - ui->progressBar->setVisible(false); -} - -MainWindow::~MainWindow() -{ - delete ui; -} - -void MainWindow::resizeEvent(QResizeEvent *event) -{ - int nW = event->size().width(); - int nH = event->size().height(); - - ui->textEditDirectory->setGeometry(20, 20, nW - 110, 30); - ui->pushButtonDirectory->setGeometry(nW - 70, 20, 50, 30); - - int nCheckBoxW = 50; - int nCheckBoxH = 20; - int nCheckBoxDeltaX = (nW - 40 - 40 - 4 * nCheckBoxW) / 3; - - int nCheckBoxX1 = 20; - int nCheckBoxX2 = nCheckBoxX1 + nCheckBoxDeltaX + nCheckBoxW; - int nCheckBoxX3 = nCheckBoxX2 + nCheckBoxDeltaX + nCheckBoxW; - int nCheckBoxX4 = nCheckBoxX3 + nCheckBoxDeltaX + nCheckBoxW; - int nCheckBoxY = 20; - - int nCheckBoxDeltaY = 10; - - ui->groupBoxINPUT->setGeometry(20, 70, nW - 40, 2 * nCheckBoxY + 7 * nCheckBoxH + 7 * nCheckBoxDeltaY); - - ui->checkBoxDOCX->setGeometry(nCheckBoxX1, nCheckBoxY, nCheckBoxW, nCheckBoxH); - ui->checkBoxDOC->setGeometry(nCheckBoxX1, nCheckBoxY + nCheckBoxH + nCheckBoxDeltaY, nCheckBoxW, nCheckBoxH); - ui->checkBoxODT->setGeometry(nCheckBoxX1, nCheckBoxY + 2 * (nCheckBoxH + nCheckBoxDeltaY), nCheckBoxW, nCheckBoxH); - ui->checkBoxRTF->setGeometry(nCheckBoxX1, nCheckBoxY + 3 * (nCheckBoxH + nCheckBoxDeltaY), nCheckBoxW, nCheckBoxH); - ui->checkBoxTXT->setGeometry(nCheckBoxX1, nCheckBoxY + 4 * (nCheckBoxH + nCheckBoxDeltaY), nCheckBoxW, nCheckBoxH); - ui->checkBoxHTML->setGeometry(nCheckBoxX1, nCheckBoxY + 5 * (nCheckBoxH + nCheckBoxDeltaY), nCheckBoxW, nCheckBoxH); - ui->checkBoxDOC_ALL->setGeometry(nCheckBoxX1, nCheckBoxY + 6 * (nCheckBoxH + nCheckBoxDeltaY) + nCheckBoxDeltaY, nCheckBoxW, nCheckBoxH); - - ui->checkBoxPPTX->setGeometry(nCheckBoxX2, nCheckBoxY, nCheckBoxW, nCheckBoxH); - ui->checkBoxPPT->setGeometry(nCheckBoxX2, nCheckBoxY + nCheckBoxH + nCheckBoxDeltaY, nCheckBoxW, nCheckBoxH); - ui->checkBoxODP->setGeometry(nCheckBoxX2, nCheckBoxY + 2 * (nCheckBoxH + nCheckBoxDeltaY), nCheckBoxW, nCheckBoxH); - ui->checkBoxPPT_ALL->setGeometry(nCheckBoxX2, nCheckBoxY + 6 * (nCheckBoxH + nCheckBoxDeltaY) + nCheckBoxDeltaY, nCheckBoxW, nCheckBoxH); - - ui->checkBoxXLSX->setGeometry(nCheckBoxX3, nCheckBoxY, nCheckBoxW, nCheckBoxH); - ui->checkBoxXLS->setGeometry(nCheckBoxX3, nCheckBoxY + nCheckBoxH + nCheckBoxDeltaY, nCheckBoxW, nCheckBoxH); - ui->checkBoxODS->setGeometry(nCheckBoxX3, nCheckBoxY + 2 * (nCheckBoxH + nCheckBoxDeltaY), nCheckBoxW, nCheckBoxH); - ui->checkBoxCSV->setGeometry(nCheckBoxX3, nCheckBoxY + 3 * (nCheckBoxH + nCheckBoxDeltaY), nCheckBoxW, nCheckBoxH); - ui->checkBoxXLS_ALL->setGeometry(nCheckBoxX3, nCheckBoxY + 6 * (nCheckBoxH + nCheckBoxDeltaY) + nCheckBoxDeltaY, nCheckBoxW, nCheckBoxH); - - ui->checkBoxPDF->setGeometry(nCheckBoxX4, nCheckBoxY, nCheckBoxW, nCheckBoxH); - ui->checkBoxXPS->setGeometry(nCheckBoxX4, nCheckBoxY + nCheckBoxH + nCheckBoxDeltaY, nCheckBoxW, nCheckBoxH); - ui->checkBoxDJVU->setGeometry(nCheckBoxX4, nCheckBoxY + 2 * (nCheckBoxH + nCheckBoxDeltaY), nCheckBoxW, nCheckBoxH); - ui->checkBoxDJVU_ALL->setGeometry(nCheckBoxX4, nCheckBoxY + 6 * (nCheckBoxH + nCheckBoxDeltaY) + nCheckBoxDeltaY, nCheckBoxW, nCheckBoxH); - - ui->groupBoxOUTPUT->setGeometry(20, 60 + ui->textEditDirectory->height() + ui->groupBoxINPUT->height(), nW - 40, 60); - - ui->labelOutput->setGeometry(20, 20, 50, 20); - ui->comboBoxOUTPUT->setGeometry(100, 20, 100, 20); - - ui->labelThreads->setGeometry(250, 20, 50, 20); - ui->spinBoxThreads->setGeometry(320, 20, 30, 20); - - int nOffset = 20 + ui->pushButtonDirectory->height() + 20 + ui->groupBoxINPUT->height() + 20 + ui->groupBoxOUTPUT->height() + 20; - - ui->pushButtonConvert->setGeometry((nW - 80) >> 1, nOffset, 80, 30); - - ui->progressBar->setGeometry(20, nOffset + 50, nW - 40, 30); - - nOffset = nOffset + 100; - ui->textEdit->setGeometry(20, nOffset, nW - 40, nH - 20 - nOffset); -} - -void MainWindow::pushButtonDirectoryClicked() -{ - ui->textEditDirectory->setText(QFileDialog::getExistingDirectory(this, tr("Open Directory"), "", QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks)); -} - -void MainWindow::pushButtonConvertClicked() -{ - if (ui->pushButtonConvert->text() == "CANCEL") - { - m_pWorker->Cancel(); - return; - } - - std::wstring sProcess = NSFile::GetProcessDirectory(); - if (!NSDirectory::Exists(sProcess + L"/fonts")) - NSDirectory::CreateDirectory(sProcess + L"/fonts"); - if (!NSDirectory::Exists(sProcess + L"/Result")) - NSDirectory::CreateDirectory(sProcess + L"/Result"); - - m_pWorker->m_pParser->m_sDirectory = ui->textEditDirectory->toPlainText().toStdWString(); - m_pWorker->m_pParser->m_window = this; - - ui->progressBar->setMinimum(0); - ui->progressBar->setMaximum(0); - ui->progressBar->setValue(0); - ui->progressBar->setVisible(true); - - m_pWorker->m_pParser->Start(0); - - ui->pushButtonConvert->setText("CANCEL"); -} - -void MainWindow::send_onDirectoryChecked() -{ - emit signal_onDirectoryChecked(); -} - -void MainWindow::send_onFileConverted(int nProgress) -{ - emit signal_onFileConverted(nProgress); -} - -void MainWindow::slot_onFileConverted(int nProgress) -{ - ui->progressBar->setValue(nProgress); - - if (nProgress == m_pWorker->m_nCount) - { - m_pWorker->Log(); - ui->pushButtonConvert->setText("CONVERT"); - ui->progressBar->setVisible(false); - } -} - -void MainWindow::slot_onDirectoryChecked() -{ - ui->progressBar->setMinimum(0); - ui->progressBar->setMaximum((int)m_pWorker->m_pParser->m_files.size()); - - ui->progressBar->setValue(0); - - if (0 == (int)m_pWorker->m_pParser->m_files.size()) - { - ui->pushButtonConvert->setEnabled(true); - ui->progressBar->setVisible(false); - } - else - { - std::wstring sValue = ui->comboBoxOUTPUT->currentText().toStdWString(); - - int nFormat = 0; - if (sValue == L"docx") - nFormat = AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX; - else if (sValue == L"doc") - nFormat = AVS_OFFICESTUDIO_FILE_DOCUMENT_DOC; - else if (sValue == L"odt") - nFormat = AVS_OFFICESTUDIO_FILE_DOCUMENT_ODT; - else if (sValue == L"rtf") - nFormat = AVS_OFFICESTUDIO_FILE_DOCUMENT_RTF; - else if (sValue == L"txt") - nFormat = AVS_OFFICESTUDIO_FILE_DOCUMENT_TXT; - else if (sValue == L"pptx") - nFormat = AVS_OFFICESTUDIO_FILE_PRESENTATION_PPTX; - else if (sValue == L"odp") - nFormat = AVS_OFFICESTUDIO_FILE_PRESENTATION_ODP; - else if (sValue == L"xlsx") - nFormat = AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSX; - else if (sValue == L"xls") - nFormat = AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLS; - else if (sValue == L"ods") - nFormat = AVS_OFFICESTUDIO_FILE_SPREADSHEET_ODS; - else if (sValue == L"csv") - nFormat = AVS_OFFICESTUDIO_FILE_SPREADSHEET_CSV; - else if (sValue == L"pdf") - nFormat = AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_PDF; - else - nFormat = 8192; - - m_pWorker->m_dst_format = nFormat; - - m_pWorker->m_nCurrent = 0; - m_pWorker->m_nCount = (int)m_pWorker->m_pParser->m_files.size(); - m_pWorker->m_nCurrentConvert = 0; - - m_pWorker->Start(ui->spinBoxThreads->value()); - } -} - -void MainWindow::outputIndexChanged(int value) -{ - value; - - QString sValue = ui->comboBoxOUTPUT->currentText(); - - ui->checkBoxDOCX->setEnabled(true); - ui->checkBoxDOC->setEnabled(true); - ui->checkBoxODT->setEnabled(true); - ui->checkBoxRTF->setEnabled(true); - ui->checkBoxTXT->setEnabled(true); - ui->checkBoxHTML->setEnabled(true); - ui->checkBoxDOC_ALL->setEnabled(true); - - ui->checkBoxPPTX->setEnabled(true); - ui->checkBoxPPT->setEnabled(true); - ui->checkBoxODP->setEnabled(true); - ui->checkBoxPPT_ALL->setEnabled(true); - - ui->checkBoxXLSX->setEnabled(true); - ui->checkBoxXLS->setEnabled(true); - ui->checkBoxODS->setEnabled(true); - ui->checkBoxCSV->setEnabled(true); - ui->checkBoxXLS_ALL->setEnabled(true); - - ui->checkBoxPDF->setEnabled(true); - ui->checkBoxXPS->setEnabled(true); - ui->checkBoxDJVU->setEnabled(true); - ui->checkBoxDJVU_ALL->setEnabled(true); - - if (sValue == "internal") - { - m_pWorker->setDestinationInternal(); - } - else if (sValue == "docx" || - sValue == "doc" || - sValue == "odt" || - sValue == "rtf" || - sValue == "txt") - { - m_pWorker->setDestinationDocument(); - - ui->checkBoxPPTX->setEnabled(false); - ui->checkBoxPPT->setEnabled(false); - ui->checkBoxODP->setEnabled(false); - ui->checkBoxPPT_ALL->setEnabled(false); - - ui->checkBoxXLSX->setEnabled(false); - ui->checkBoxXLS->setEnabled(false); - ui->checkBoxODS->setEnabled(false); - ui->checkBoxCSV->setEnabled(false); - ui->checkBoxXLS_ALL->setEnabled(false); - - ui->checkBoxPDF->setEnabled(false); - ui->checkBoxXPS->setEnabled(false); - ui->checkBoxDJVU->setEnabled(false); - ui->checkBoxDJVU_ALL->setEnabled(false); - } - else if (sValue == "pptx" || - sValue == "odp") - { - m_pWorker->setDestinationPresentation(); - - ui->checkBoxDOCX->setEnabled(false); - ui->checkBoxDOC->setEnabled(false); - ui->checkBoxODT->setEnabled(false); - ui->checkBoxRTF->setEnabled(false); - ui->checkBoxTXT->setEnabled(false); - ui->checkBoxHTML->setEnabled(false); - ui->checkBoxDOC_ALL->setEnabled(false); - - ui->checkBoxXLSX->setEnabled(false); - ui->checkBoxXLS->setEnabled(false); - ui->checkBoxODS->setEnabled(false); - ui->checkBoxCSV->setEnabled(false); - ui->checkBoxXLS_ALL->setEnabled(false); - - ui->checkBoxPDF->setEnabled(false); - ui->checkBoxXPS->setEnabled(false); - ui->checkBoxDJVU->setEnabled(false); - ui->checkBoxDJVU_ALL->setEnabled(false); - } - else if (sValue == "xlsx" || - sValue == "xls" || - sValue == "ods" || - sValue == "csv") - { - m_pWorker->setDestinationSpreadsheet(); - - ui->checkBoxDOCX->setEnabled(false); - ui->checkBoxDOC->setEnabled(false); - ui->checkBoxODT->setEnabled(false); - ui->checkBoxRTF->setEnabled(false); - ui->checkBoxTXT->setEnabled(false); - ui->checkBoxHTML->setEnabled(false); - ui->checkBoxDOC_ALL->setEnabled(false); - - ui->checkBoxPPTX->setEnabled(false); - ui->checkBoxPPT->setEnabled(false); - ui->checkBoxODP->setEnabled(false); - ui->checkBoxPPT_ALL->setEnabled(false); - - ui->checkBoxPDF->setEnabled(false); - ui->checkBoxXPS->setEnabled(false); - ui->checkBoxDJVU->setEnabled(false); - ui->checkBoxDJVU_ALL->setEnabled(false); - } - else - { - m_pWorker->setDestinationPDF(); - - ui->checkBoxPDF->setEnabled(false); - ui->checkBoxXPS->setEnabled(false); - ui->checkBoxDJVU->setEnabled(false); - ui->checkBoxDJVU_ALL->setEnabled(false); - } - - CorrectCheckBoxes(); -} - -void MainWindow::CorrectCheckBoxes() -{ - ui->checkBoxDOCX->setChecked(ui->checkBoxDOCX->isEnabled()); - ui->checkBoxDOC->setChecked(ui->checkBoxDOC->isEnabled()); - ui->checkBoxODT->setChecked(ui->checkBoxODT->isEnabled()); - ui->checkBoxRTF->setChecked(ui->checkBoxRTF->isEnabled()); - ui->checkBoxTXT->setChecked(ui->checkBoxTXT->isEnabled()); - ui->checkBoxHTML->setChecked(ui->checkBoxHTML->isEnabled()); - ui->checkBoxDOC_ALL->setChecked(ui->checkBoxDOC_ALL->isEnabled()); - - ui->checkBoxPPTX->setChecked(ui->checkBoxPPTX->isEnabled()); - ui->checkBoxPPT->setChecked(ui->checkBoxPPT->isEnabled()); - ui->checkBoxODP->setChecked(ui->checkBoxODP->isEnabled()); - ui->checkBoxPPT_ALL->setChecked(ui->checkBoxPPT_ALL->isEnabled()); - - ui->checkBoxXLSX->setChecked(ui->checkBoxXLSX->isEnabled()); - ui->checkBoxXLS->setChecked(ui->checkBoxXLS->isEnabled()); - ui->checkBoxODS->setChecked(ui->checkBoxODS->isEnabled()); - ui->checkBoxCSV->setChecked(ui->checkBoxCSV->isEnabled()); - ui->checkBoxXLS_ALL->setChecked(ui->checkBoxXLS_ALL->isEnabled()); - - ui->checkBoxPDF->setChecked(ui->checkBoxPDF->isEnabled()); - ui->checkBoxXPS->setChecked(ui->checkBoxXPS->isEnabled()); - ui->checkBoxDJVU->setChecked(ui->checkBoxDJVU->isEnabled()); - ui->checkBoxDJVU_ALL->setChecked(ui->checkBoxDJVU_ALL->isEnabled()); -} - -void MainWindow::stateChanged_DOCX(bool) -{ - if (ui->checkBoxDOCX->isEnabled()) - m_pWorker->m_formats.find(AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX)->second = ui->checkBoxDOCX->isChecked(); -} - -void MainWindow::stateChanged_DOC(bool) -{ - if (ui->checkBoxDOC->isEnabled()) - m_pWorker->m_formats.find(AVS_OFFICESTUDIO_FILE_DOCUMENT_DOC)->second = ui->checkBoxDOC->isChecked(); -} - -void MainWindow::stateChanged_ODT(bool) -{ - if (ui->checkBoxODT->isEnabled()) - m_pWorker->m_formats.find(AVS_OFFICESTUDIO_FILE_DOCUMENT_ODT)->second = ui->checkBoxODT->isChecked(); -} - -void MainWindow::stateChanged_RTF(bool) -{ - if (ui->checkBoxRTF->isEnabled()) - m_pWorker->m_formats.find(AVS_OFFICESTUDIO_FILE_DOCUMENT_RTF)->second = ui->checkBoxRTF->isChecked(); -} - -void MainWindow::stateChanged_TXT(bool) -{ - if (ui->checkBoxTXT->isEnabled()) - m_pWorker->m_formats.find(AVS_OFFICESTUDIO_FILE_DOCUMENT_TXT)->second = ui->checkBoxTXT->isChecked(); -} - -void MainWindow::stateChanged_HTML(bool) -{ - if (ui->checkBoxHTML->isEnabled()) - m_pWorker->m_formats.find(AVS_OFFICESTUDIO_FILE_DOCUMENT_HTML)->second = ui->checkBoxHTML->isChecked(); -} - -void MainWindow::stateChanged_DOC_ALL(bool) -{ - bool bIsVal = ui->checkBoxDOC_ALL->isChecked(); - ui->checkBoxDOCX->setChecked(bIsVal); - ui->checkBoxDOC->setChecked(bIsVal); - ui->checkBoxODT->setChecked(bIsVal); - ui->checkBoxRTF->setChecked(bIsVal); - ui->checkBoxTXT->setChecked(bIsVal); - ui->checkBoxHTML->setChecked(bIsVal); -} - -void MainWindow::stateChanged_PPTX(bool) -{ - if (ui->checkBoxPPTX->isEnabled()) - m_pWorker->m_formats.find(AVS_OFFICESTUDIO_FILE_PRESENTATION_PPTX)->second = ui->checkBoxPPTX->isChecked(); -} - -void MainWindow::stateChanged_PPT(bool) -{ - if (ui->checkBoxPPT->isEnabled()) - m_pWorker->m_formats.find(AVS_OFFICESTUDIO_FILE_PRESENTATION_PPT)->second = ui->checkBoxPPT->isChecked(); -} - -void MainWindow::stateChanged_ODP(bool) -{ - if (ui->checkBoxODP->isEnabled()) - m_pWorker->m_formats.find(AVS_OFFICESTUDIO_FILE_PRESENTATION_ODP)->second = ui->checkBoxODP->isChecked(); -} - -void MainWindow::stateChanged_PPT_ALL(bool) -{ - bool bIsVal = ui->checkBoxPPT_ALL->isChecked(); - ui->checkBoxPPTX->setChecked(bIsVal); - ui->checkBoxPPT->setChecked(bIsVal); - ui->checkBoxODP->setChecked(bIsVal); -} - -void MainWindow::stateChanged_XLSX(bool) -{ - if (ui->checkBoxXLSX->isEnabled()) - m_pWorker->m_formats.find(AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSX)->second = ui->checkBoxXLSX->isChecked(); -} - -void MainWindow::stateChanged_XLS(bool) -{ - if (ui->checkBoxXLS->isEnabled()) - m_pWorker->m_formats.find(AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLS)->second = ui->checkBoxXLS->isChecked(); -} - -void MainWindow::stateChanged_ODS(bool) -{ - if (ui->checkBoxODS->isEnabled()) - m_pWorker->m_formats.find(AVS_OFFICESTUDIO_FILE_SPREADSHEET_ODS)->second = ui->checkBoxODS->isChecked(); -} - -void MainWindow::stateChanged_CSV(bool) -{ - if (ui->checkBoxCSV->isEnabled()) - m_pWorker->m_formats.find(AVS_OFFICESTUDIO_FILE_SPREADSHEET_CSV)->second = ui->checkBoxCSV->isChecked(); -} - -void MainWindow::stateChanged_XLS_ALL(bool) -{ - bool bIsVal = ui->checkBoxXLS_ALL->isChecked(); - ui->checkBoxXLSX->setChecked(bIsVal); - ui->checkBoxXLS->setChecked(bIsVal); - ui->checkBoxODS->setChecked(bIsVal); - ui->checkBoxCSV->setChecked(bIsVal); -} - -void MainWindow::stateChanged_PDF(bool) -{ - if (ui->checkBoxPDF->isEnabled()) - m_pWorker->m_formats.find(AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_PDF)->second = ui->checkBoxPDF->isChecked(); -} - -void MainWindow::stateChanged_XPS(bool) -{ - if (ui->checkBoxXPS->isEnabled()) - m_pWorker->m_formats.find(AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_XPS)->second = ui->checkBoxXPS->isChecked(); -} - -void MainWindow::stateChanged_DJVU(bool) -{ - if (ui->checkBoxDJVU->isEnabled()) - m_pWorker->m_formats.find(AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_DJVU)->second = ui->checkBoxDJVU->isChecked(); -} - -void MainWindow::stateChanged_DJVU_ALL(bool) -{ - bool bIsVal = ui->checkBoxDJVU_ALL->isChecked(); - ui->checkBoxPDF->setChecked(bIsVal); - ui->checkBoxXPS->setChecked(bIsVal); - ui->checkBoxDJVU->setChecked(bIsVal); -} diff --git a/X2tConverter/test/batch_convert/x2t_test/mainwindow.h b/X2tConverter/test/batch_convert/x2t_test/mainwindow.h deleted file mode 100644 index c46ede2d0ae..00000000000 --- a/X2tConverter/test/batch_convert/x2t_test/mainwindow.h +++ /dev/null @@ -1,73 +0,0 @@ -#ifndef MAINWINDOW_H -#define MAINWINDOW_H - -#include -#include - -class CInternalWorker; - -namespace Ui { -class MainWindow; -} - -class MainWindow : public QMainWindow -{ - Q_OBJECT - -public: - explicit MainWindow(QWidget *parent = 0); - ~MainWindow(); - -public: - virtual void resizeEvent(QResizeEvent *event); - - void send_onDirectoryChecked(); - void send_onFileConverted(int); - -signals: - void signal_onDirectoryChecked(); - void signal_onFileConverted(int); - -public slots: - void pushButtonDirectoryClicked(); - void pushButtonConvertClicked(); - void outputIndexChanged(int value); - - void stateChanged_DOCX(bool); - void stateChanged_DOC(bool); - void stateChanged_ODT(bool); - void stateChanged_RTF(bool); - void stateChanged_TXT(bool); - void stateChanged_HTML(bool); - void stateChanged_DOC_ALL(bool); - - void stateChanged_PPTX(bool); - void stateChanged_PPT(bool); - void stateChanged_ODP(bool); - void stateChanged_PPT_ALL(bool); - - void stateChanged_XLSX(bool); - void stateChanged_XLS(bool); - void stateChanged_ODS(bool); - void stateChanged_CSV(bool); - void stateChanged_XLS_ALL(bool); - - void stateChanged_PDF(bool); - void stateChanged_XPS(bool); - void stateChanged_DJVU(bool); - void stateChanged_DJVU_ALL(bool); - - void slot_onDirectoryChecked(); - void slot_onFileConverted(int); - - -private: - Ui::MainWindow *ui; - - CInternalWorker* m_pWorker; - -private: - void CorrectCheckBoxes(); -}; - -#endif // MAINWINDOW_H diff --git a/X2tConverter/test/batch_convert/x2t_test/mainwindow.ui b/X2tConverter/test/batch_convert/x2t_test/mainwindow.ui deleted file mode 100644 index e5bb4d74913..00000000000 --- a/X2tConverter/test/batch_convert/x2t_test/mainwindow.ui +++ /dev/null @@ -1,414 +0,0 @@ - - - MainWindow - - - - 0 - 0 - 517 - 563 - - - - MainWindow - - - - - - 470 - 10 - 31 - 31 - - - - ... - - - - - - 10 - 10 - 451 - 31 - - - - - - - 10 - 50 - 491 - 251 - - - - GroupBox - - - - - 10 - 220 - 72 - 19 - - - - CheckBox - - - - - - 10 - 150 - 72 - 19 - - - - CheckBox - - - - - - 10 - 60 - 72 - 19 - - - - CheckBox - - - - - - 10 - 180 - 72 - 19 - - - - CheckBox - - - - - - 10 - 90 - 72 - 21 - - - - CheckBox - - - - - - 10 - 30 - 72 - 19 - - - - CheckBox - - - - - - 10 - 120 - 72 - 19 - - - - CheckBox - - - - - - 130 - 30 - 72 - 19 - - - - CheckBox - - - - - - 130 - 60 - 72 - 19 - - - - CheckBox - - - - - - 130 - 90 - 72 - 21 - - - - CheckBox - - - - - - 130 - 220 - 72 - 19 - - - - CheckBox - - - - - - 240 - 30 - 72 - 19 - - - - CheckBox - - - - - - 240 - 60 - 72 - 19 - - - - CheckBox - - - - - - 240 - 90 - 72 - 21 - - - - CheckBox - - - - - - 240 - 120 - 72 - 21 - - - - CheckBox - - - - - - 240 - 220 - 72 - 19 - - - - CheckBox - - - - - - 370 - 30 - 72 - 19 - - - - CheckBox - - - - - - 370 - 60 - 72 - 19 - - - - CheckBox - - - - - - 370 - 90 - 72 - 21 - - - - CheckBox - - - - - - 370 - 220 - 72 - 19 - - - - CheckBox - - - - - - - 10 - 310 - 491 - 81 - - - - GroupBox - - - - - 10 - 30 - 47 - 13 - - - - TextLabel - - - - - - 80 - 30 - 72 - 22 - - - - - - - 240 - 30 - 43 - 22 - - - - - - - 170 - 30 - 47 - 13 - - - - TextLabel - - - - - - - 210 - 400 - 80 - 21 - - - - PushButton - - - - - - 10 - 430 - 491 - 21 - - - - 24 - - - - - - 10 - 460 - 491 - 81 - - - - - - - - - - diff --git a/X2tConverter/test/batch_convert/x2t_test/x2t_test.pro b/X2tConverter/test/batch_convert/x2t_test/x2t_test.pro deleted file mode 100644 index e1c54d5f20b..00000000000 --- a/X2tConverter/test/batch_convert/x2t_test/x2t_test.pro +++ /dev/null @@ -1,84 +0,0 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2017-04-12T11:12:01 -# -#------------------------------------------------- - -QT += core gui - -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets - -TARGET = x2t_test -TEMPLATE = app - -CORE_ROOT_DIR = $$PWD/../../../../../core -PWD_ROOT_DIR = $$PWD -include($$CORE_ROOT_DIR/Common/base.pri) - -INCLUDEPATH += \ - $$CORE_ROOT_DIR/DesktopEditor/agg-2.4/include \ - $$CORE_ROOT_DIR/DesktopEditor/freetype-2.5.2/include - -DESTDIR = $$PWD/build - -DEFINES += \ - UNICODE \ - _UNICODE - -LIBS += -L$$CORE_BUILDS_LIBRARIES_PATH -lgraphics -lOfficeUtils -lUnicodeConverter - -# The following define makes your compiler emit warnings if you use -# any feature of Qt which as been marked as deprecated (the exact warnings -# depend on your compiler). Please consult the documentation of the -# deprecated API in order to know how to port your code away from it. -DEFINES += QT_DEPRECATED_WARNINGS - -# You can also make your code fail to compile if you use deprecated APIs. -# In order to do so, uncomment the following line. -# You can also select to disable deprecated APIs only up to a certain version of Qt. -#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 - - -SOURCES += \ - $$CORE_ROOT_DIR/Common/OfficeFileFormatChecker2.cpp \ - $$CORE_ROOT_DIR/Common/3dParty/pole/pole.cpp \ - main.cpp \ - mainwindow.cpp - -HEADERS += mainwindow.h - -FORMS += mainwindow.ui - -core_windows { -LIBS += -lwininet \ - -ldnsapi \ - -lversion \ - -lmsimg32 \ - -lws2_32 \ - -lusp10 \ - -lpsapi \ - -ldbghelp \ - -lwinmm \ - -lshlwapi \ - -lkernel32 \ - -lgdi32 \ - -lwinspool \ - -lcomdlg32 \ - -ladvapi32 \ - -lshell32 \ - -lole32 \ - -loleaut32 \ - -luser32 \ - -luuid \ - -lodbc32 \ - -lodbccp32 \ - -ldelayimp \ - -lcredui \ - -lnetapi32 \ - -lcomctl32 \ - -lrpcrt4 \ - -ldwmapi \ - -lOpenGL32 - -QMAKE_LFLAGS_WINDOWS = /SUBSYSTEM:WINDOWS,5.02 -} diff --git a/X2tConverter/test/iosTest/TestIOSX2tConverter/AppDelegate.m b/X2tConverter/test/iosTest/TestIOSX2tConverter/AppDelegate.m deleted file mode 100644 index ed6929418b5..00000000000 --- a/X2tConverter/test/iosTest/TestIOSX2tConverter/AppDelegate.m +++ /dev/null @@ -1,69 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2023 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ - -#import "AppDelegate.h" - -@interface AppDelegate () - -@end - -@implementation AppDelegate - - -- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { - // Override point for customization after application launch. - return YES; -} - -- (void)applicationWillResignActive:(UIApplication *)application { - // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. - // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. -} - -- (void)applicationDidEnterBackground:(UIApplication *)application { - // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. - // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. -} - -- (void)applicationWillEnterForeground:(UIApplication *)application { - // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. -} - -- (void)applicationDidBecomeActive:(UIApplication *)application { - // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. -} - -- (void)applicationWillTerminate:(UIApplication *)application { - // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. -} - -@end diff --git a/X2tConverter/test/iosTest/TestIOSX2tConverter/Base.lproj/LaunchScreen.xib b/X2tConverter/test/iosTest/TestIOSX2tConverter/Base.lproj/LaunchScreen.xib deleted file mode 100644 index 3a65c7e2f4d..00000000000 --- a/X2tConverter/test/iosTest/TestIOSX2tConverter/Base.lproj/LaunchScreen.xib +++ /dev/null @@ -1,41 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/X2tConverter/test/iosTest/TestIOSX2tConverter/Base.lproj/Main.storyboard b/X2tConverter/test/iosTest/TestIOSX2tConverter/Base.lproj/Main.storyboard deleted file mode 100644 index f56d2f3bb56..00000000000 --- a/X2tConverter/test/iosTest/TestIOSX2tConverter/Base.lproj/Main.storyboard +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/X2tConverter/test/iosTest/TestIOSX2tConverter/Images.xcassets/AppIcon.appiconset/Contents.json b/X2tConverter/test/iosTest/TestIOSX2tConverter/Images.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100644 index 1d060ed2882..00000000000 --- a/X2tConverter/test/iosTest/TestIOSX2tConverter/Images.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,93 +0,0 @@ -{ - "images" : [ - { - "idiom" : "iphone", - "size" : "20x20", - "scale" : "2x" - }, - { - "idiom" : "iphone", - "size" : "20x20", - "scale" : "3x" - }, - { - "idiom" : "iphone", - "size" : "29x29", - "scale" : "2x" - }, - { - "idiom" : "iphone", - "size" : "29x29", - "scale" : "3x" - }, - { - "idiom" : "iphone", - "size" : "40x40", - "scale" : "2x" - }, - { - "idiom" : "iphone", - "size" : "40x40", - "scale" : "3x" - }, - { - "idiom" : "iphone", - "size" : "60x60", - "scale" : "2x" - }, - { - "idiom" : "iphone", - "size" : "60x60", - "scale" : "3x" - }, - { - "idiom" : "ipad", - "size" : "20x20", - "scale" : "1x" - }, - { - "idiom" : "ipad", - "size" : "20x20", - "scale" : "2x" - }, - { - "idiom" : "ipad", - "size" : "29x29", - "scale" : "1x" - }, - { - "idiom" : "ipad", - "size" : "29x29", - "scale" : "2x" - }, - { - "idiom" : "ipad", - "size" : "40x40", - "scale" : "1x" - }, - { - "idiom" : "ipad", - "size" : "40x40", - "scale" : "2x" - }, - { - "idiom" : "ipad", - "size" : "76x76", - "scale" : "1x" - }, - { - "idiom" : "ipad", - "size" : "76x76", - "scale" : "2x" - }, - { - "idiom" : "ipad", - "size" : "83.5x83.5", - "scale" : "2x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/X2tConverter/test/iosTest/TestIOSX2tConverter/Info.plist b/X2tConverter/test/iosTest/TestIOSX2tConverter/Info.plist deleted file mode 100644 index e324b300e1c..00000000000 --- a/X2tConverter/test/iosTest/TestIOSX2tConverter/Info.plist +++ /dev/null @@ -1,49 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - APPL - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - 1 - LSRequiresIPhoneOS - - UIFileSharingEnabled - - UILaunchStoryboardName - LaunchScreen - UIMainStoryboardFile - Main - UIRequiredDeviceCapabilities - - armv7 - - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UISupportedInterfaceOrientations~ipad - - UIInterfaceOrientationPortrait - UIInterfaceOrientationPortraitUpsideDown - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - - diff --git a/X2tConverter/test/iosTest/TestIOSX2tConverter/ViewController.m b/X2tConverter/test/iosTest/TestIOSX2tConverter/ViewController.m deleted file mode 100644 index 072a35aa2f2..00000000000 --- a/X2tConverter/test/iosTest/TestIOSX2tConverter/ViewController.m +++ /dev/null @@ -1,367 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2023 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ - -#import "ViewController.h" - -#import "X2tConverter.h" -#import "OfficeFileErrorDescription.h" - -@interface ViewController () -@property (strong) NSString *fonts; -@property (strong) NSString *temp; -@end - -@implementation ViewController - -- (void)viewDidLoad { - [super viewDidLoad]; - - NSLog(@"x2t version converter: %@", [X2tConverter version]); - - NSLog(@"%@", [X2tConverter delimiters]); - NSLog(@"%@", [X2tConverter encodingings]); - - self.fonts = @"/System/Library/Fonts"; - self.temp = NSTemporaryDirectory(); - - [self testTXT]; - [self testCSV]; - [self testDOCX]; - [self testXLSX]; - [self textPPTX]; -} - -- (void)testTXT { - - { - NSLog(@"==================== TXT TO DOCX ===================="); - - NSString* from = [[NSBundle mainBundle] pathForResource:@"test" ofType:@"txt"]; - NSString* to = [NSString stringWithFormat:@"%@test_txt_to_docx.docx", self.temp]; - - X2tConverter* conv = [[X2tConverter alloc]init]; - conv.isNoBase64 = YES; - int result = [conv txt2docx:from nsTo:to nsTemp:self.temp nsFontPath:self.fonts]; - if (result != 0) { - NSLog(@"ERROR TXT TO DOCX : %d",result); - } else { - NSLog(@"txt output : %@", to); - } - } -} - -- (void)testDOCX { - { - NSLog(@"==================== OPEN EMPTY DOCX ===================="); - - NSString *path = [[NSBundle mainBundle] pathForResource:@"empty" ofType:@"docx"]; - - NSString* fullFileName = path; - NSString* fullFileNameTo = [NSString stringWithFormat:@"%@empty.bin", self.temp]; - - X2tConverter* conv = [[X2tConverter alloc]init]; - conv.isNoBase64 = YES; - int result = [conv sdk_docx2doct_bin:fullFileName nsTo:fullFileNameTo nsTemp:self.temp nsFontPath:self.fonts]; - if (result != 0) { - NSLog(@"ERROR OPEN EMPTY DOCX : %d",result); - } else { - NSLog(@"doct output : %@", fullFileNameTo); - } - } - - { - NSLog(@"==================== OPEN DOCX ===================="); - - NSString *path = [[NSBundle mainBundle] pathForResource:@"demo" ofType:@"docx"]; - - NSString* fullFileName = path; - NSString* fullFileNameTo = [NSString stringWithFormat:@"%@demo.bin", self.temp]; - - X2tConverter* conv = [[X2tConverter alloc]init]; - conv.isNoBase64 = YES; - int result = [conv sdk_docx2doct_bin:fullFileName nsTo:fullFileNameTo nsTemp:self.temp nsFontPath:self.fonts]; - if (result != 0) { - NSLog(@"ERROR OPEN DOCX : %d",result); - } else { - NSLog(@"doct output : %@", fullFileNameTo); - } - } - - { - NSLog(@"==================== OPEN DOCT ===================="); - - NSString *path = [[NSBundle mainBundle] pathForResource:@"demo" ofType:@"docx"]; - - NSString* fullFileName = path; - NSString* fullFileNameTo = [NSString stringWithFormat:@"%@demo.bin", self.temp]; - - X2tConverter* conv = [[X2tConverter alloc]init]; - conv.isNoBase64 = YES; - [conv sdk_docx2doct_bin:fullFileName nsTo:fullFileNameTo nsTemp:self.temp nsFontPath:self.fonts]; - - NSLog(@"%@",fullFileNameTo); - - NSString* docxOut = [NSString stringWithFormat:@"%@document.docx", self.temp]; - NSString* outTemp = [NSString stringWithFormat:@"%@OUT_TEMP", self.temp]; - - [self createDirectory:outTemp]; - [self clearDirectory:outTemp]; - - X2tConverter* conv2 = [[X2tConverter alloc]init]; - conv.isNoBase64 = YES; - [conv2 sdk_doct_bin2docx:fullFileNameTo nsTo:docxOut nsTemp:outTemp nsFontPath:self.fonts fromChanges:@(NO) nsThemeDir:@""]; - - NSLog(@"doct output: %@",fullFileNameTo); - } - - { - NSLog(@"==================== OPEN DOCX ===================="); - - NSString* fullFileName = [[NSBundle mainBundle] pathForResource:@"demo" ofType:@"docx"]; - NSString* pathTo = [NSString stringWithFormat:@"%@%@", self.temp, [[NSUUID UUID] UUIDString]]; - - [self createDirectory: pathTo]; - - NSString* binFile = [NSString stringWithFormat:@"%@/Editor.bin", pathTo]; - - X2tConverter* conv = [[X2tConverter alloc]init]; - conv.isNoBase64 = YES; - int result = [conv sdk_docx2doct_bin:fullFileName nsTo:binFile nsTemp:self.temp nsFontPath:self.fonts]; - if (result != 0) { - NSLog(@"ERROR OPEN DOCX : %d",result); - } else { - NSLog(@"docx output : %@", binFile); - } - - NSString* potxPath = [NSString stringWithFormat:@"%@%@", self.temp, [[NSUUID UUID] UUIDString]]; - [self createDirectory: potxPath]; - - NSString* potxFile = [NSString stringWithFormat:@"%@/output.dotx", potxPath]; - - NSLog(@"==================== BIN DOCT TO DOTX ===================="); - - X2tConverter* potxconverter = [[X2tConverter alloc]init]; - potxconverter.isNoBase64 = YES; - - result = [potxconverter doct_bin2dotx:binFile nsTo:potxFile nsTemp:self.temp nsFontPath:self.fonts fromChanges:@(NO) nsThemeDir:@""]; - if (result != 0) { - NSLog(@"ERROR OPEN BIN DOTX : %d",result); - } else { - NSLog(@"dotx output : %@", potxFile); - } - } -} - -- (void)testXLSX { - { - NSLog(@"==================== OPEN EMPTY XLSX ===================="); - - NSString *path = [[NSBundle mainBundle] pathForResource:@"empty" ofType:@"xlsx"]; - - NSString* fullFileName = path; - NSString* fullFileNameTo = [NSString stringWithFormat:@"%@empty.bin", self.temp]; - - X2tConverter* conv = [[X2tConverter alloc]init]; - conv.isNoBase64 = YES; - int result = [conv sdk_xlsx2xlst_bin:fullFileName nsTo:fullFileNameTo nsTemp:self.temp nsFontPath:self.fonts]; - if (result != 0) { - NSLog(@"ERROR OPEN EMPTY XLSX : %d",result); - } else { - NSLog(@"xlst output : %@", fullFileNameTo); - } - } - - { - NSLog(@"==================== OPEN XLSX ===================="); - - NSString *path = [[NSBundle mainBundle] pathForResource:@"price" ofType:@"xlsx"]; - - NSString* fullFileName = path; - NSString* fullFileNameTo = [NSString stringWithFormat:@"%@price.bin", self.temp]; - - X2tConverter* conv = [[X2tConverter alloc]init]; - conv.isNoBase64 = YES; - int result = [conv sdk_xlsx2xlst_bin:fullFileName nsTo:fullFileNameTo nsTemp:self.temp nsFontPath:self.fonts]; - if (result != 0) { - NSLog(@"ERROR OPEN XLSX : %d",result); - } else { - NSLog(@"xlst output : %@", fullFileNameTo); - } - } - - { - NSLog(@"==================== OPEN CRYPTED XLSX ===================="); - - NSString *path = [[NSBundle mainBundle] pathForResource:@"crypted" ofType:@"xlsx"]; - - NSString* fullFileName = path; - NSString* fullFileNameTo = [NSString stringWithFormat:@"%@crypted.bin", self.temp]; - - X2tConverter* conv = [[X2tConverter alloc]init]; - conv.password = @"555"; - conv.isNoBase64 = YES; - if ((int)AVS_FILEUTILS_ERROR_CONVERT_PASSWORD == [conv sdk_xlsx2xlst_bin:fullFileName nsTo:fullFileNameTo nsTemp:self.temp nsFontPath:self.fonts]) { - NSLog(@"Error password : %@",conv.password); - } - - NSLog(@"xlst output : %@", fullFileNameTo); - } - - { - NSLog(@"==================== OPEN XLSX ===================="); - - NSString* fullFileName = [[NSBundle mainBundle] pathForResource:@"price" ofType:@"xlsx"]; - NSString* pathTo = [NSString stringWithFormat:@"%@%@", self.temp, [[NSUUID UUID] UUIDString]]; - - [self createDirectory: pathTo]; - - NSString* binFile = [NSString stringWithFormat:@"%@/Editor.bin", pathTo]; - - X2tConverter* conv = [[X2tConverter alloc]init]; - conv.isNoBase64 = YES; - int result = [conv sdk_xlsx2xlst_bin:fullFileName nsTo:binFile nsTemp:self.temp nsFontPath:self.fonts]; - if (result != 0) { - NSLog(@"ERROR OPEN XLSX : %d",result); - } else { - NSLog(@"xlsx output : %@", binFile); - } - - NSString* potxPath = [NSString stringWithFormat:@"%@%@", self.temp, [[NSUUID UUID] UUIDString]]; - [self createDirectory: potxPath]; - - NSString* file = [NSString stringWithFormat:@"%@/output.xltx", potxPath]; - - NSLog(@"==================== BIN XLST TO XLTX ===================="); - - X2tConverter* potxconverter = [[X2tConverter alloc]init]; - potxconverter.isNoBase64 = YES; - - result = [potxconverter xlst_bin2xltx:binFile nsTo:file nsTemp:self.temp nsFontPath:self.fonts fromChanges:@(NO) nsThemeDir:@""]; - if (result != 0) { - NSLog(@"ERROR OPEN BIN XLTX : %d",result); - } else { - NSLog(@"xltx output : %@", file); - } - } -} - -- (void)textPPTX { - - { - NSLog(@"==================== OPEN PPTX ===================="); - - NSString* fullFileName = [[NSBundle mainBundle] pathForResource:@"demo" ofType:@"pptx"]; - NSString* pathTo = [NSString stringWithFormat:@"%@%@", self.temp, [[NSUUID UUID] UUIDString]]; - - [self createDirectory: pathTo]; - - NSString* binFile = [NSString stringWithFormat:@"%@/Editor.bin", pathTo]; - - X2tConverter* conv = [[X2tConverter alloc]init]; - conv.isNoBase64 = YES; - int result = [conv sdk_pptx2pptt_bin:fullFileName nsTo:binFile nsTemp:self.temp nsFontPath:self.fonts]; - if (result != 0) { - NSLog(@"ERROR OPEN PPTX : %d",result); - } else { - NSLog(@"pptx output : %@", binFile); - } - - NSString* potxPath = [NSString stringWithFormat:@"%@%@", self.temp, [[NSUUID UUID] UUIDString]]; - [self createDirectory: potxPath]; - - NSString* potxFile = [NSString stringWithFormat:@"%@/output.potx", potxPath]; - - NSLog(@"==================== BIN PPTT TO POTX ===================="); - - X2tConverter* potxconverter = [[X2tConverter alloc]init]; - potxconverter.isNoBase64 = YES; - - result = [potxconverter pptt_bin2potx:binFile nsTo:potxFile nsTemp:self.temp nsFontPath:self.fonts fromChanges:@(NO) nsThemeDir:@""]; - if (result != 0) { - NSLog(@"ERROR OPEN BIN PPTT : %d",result); - } else { - NSLog(@"potx output : %@", potxFile); - } - } -} - -- (void)testCSV { - - { - NSLog(@"==================== OPEN CSV ===================="); - - NSString *path = [[NSBundle mainBundle] pathForResource:@"test" ofType:@"csv"]; - - NSString* fullFileName = path; - NSString* fullFileNameTo = [NSString stringWithFormat:@"%@test.bin", self.temp]; - - X2tConverter* conv = [[X2tConverter alloc]init]; - conv.isNoBase64 = YES; - conv.delimiter = @(4); - conv.encoding = @(46); - int result = [conv sdk_csv2xlst_bin:fullFileName nsTo:fullFileNameTo nsFontPath:self.fonts]; - if (result != 0) { - NSLog(@"ERROR OPEN CSV : %d",result); - } else { - NSLog(@"csv output : %@", fullFileNameTo); - } - } -} - -- (void)didReceiveMemoryWarning { - [super didReceiveMemoryWarning]; -} - -#pragma mark - -#pragma Utils - -- (void)clearDirectory:(NSString*)directory { - NSFileManager *fm = [NSFileManager defaultManager]; - NSError *error = nil; - for (NSString *file in [fm contentsOfDirectoryAtPath:directory error:&error]) { - BOOL success = [fm removeItemAtPath:[NSString stringWithFormat:@"%@/%@", directory, file] error:&error]; - if (!success || error) { - NSLog(@"Failed to clear directory \"%@\". Error: %@", directory, error); - } - } -} - -- (void)createDirectory:(NSString*)directory { - NSFileManager *fileManager= [NSFileManager defaultManager]; - NSError *error = nil; - if(![fileManager createDirectoryAtPath:directory withIntermediateDirectories:YES attributes:nil error:&error]) { - // An error has occurred, do something to handle it - NSLog(@"Failed to create directory \"%@\". Error: %@", directory, error); - } -} - -@end diff --git a/X2tConverter/test/iosTest/TestIOSX2tConverter/crypted.xlsx b/X2tConverter/test/iosTest/TestIOSX2tConverter/crypted.xlsx deleted file mode 100755 index 0035fd8c391..00000000000 Binary files a/X2tConverter/test/iosTest/TestIOSX2tConverter/crypted.xlsx and /dev/null differ diff --git a/X2tConverter/test/iosTest/TestIOSX2tConverter/demo.docx b/X2tConverter/test/iosTest/TestIOSX2tConverter/demo.docx deleted file mode 100644 index d245c6b06aa..00000000000 Binary files a/X2tConverter/test/iosTest/TestIOSX2tConverter/demo.docx and /dev/null differ diff --git a/X2tConverter/test/iosTest/TestIOSX2tConverter/demo.pptx b/X2tConverter/test/iosTest/TestIOSX2tConverter/demo.pptx deleted file mode 100644 index 0561b818a56..00000000000 Binary files a/X2tConverter/test/iosTest/TestIOSX2tConverter/demo.pptx and /dev/null differ diff --git a/X2tConverter/test/iosTest/TestIOSX2tConverter/empty.docx b/X2tConverter/test/iosTest/TestIOSX2tConverter/empty.docx deleted file mode 100755 index 9cd581c6b31..00000000000 Binary files a/X2tConverter/test/iosTest/TestIOSX2tConverter/empty.docx and /dev/null differ diff --git a/X2tConverter/test/iosTest/TestIOSX2tConverter/empty.xlsx b/X2tConverter/test/iosTest/TestIOSX2tConverter/empty.xlsx deleted file mode 100755 index befcd1ce36d..00000000000 Binary files a/X2tConverter/test/iosTest/TestIOSX2tConverter/empty.xlsx and /dev/null differ diff --git a/X2tConverter/test/iosTest/TestIOSX2tConverter/price.xlsx b/X2tConverter/test/iosTest/TestIOSX2tConverter/price.xlsx deleted file mode 100644 index 4050a4e0eec..00000000000 Binary files a/X2tConverter/test/iosTest/TestIOSX2tConverter/price.xlsx and /dev/null differ diff --git a/X2tConverter/test/iosTest/TestIOSX2tConverter/shapes.xlsx b/X2tConverter/test/iosTest/TestIOSX2tConverter/shapes.xlsx deleted file mode 100644 index 4fd72ce9343..00000000000 Binary files a/X2tConverter/test/iosTest/TestIOSX2tConverter/shapes.xlsx and /dev/null differ diff --git a/X2tConverter/test/iosTest/TestIOSX2tConverter/smeta.xlsx b/X2tConverter/test/iosTest/TestIOSX2tConverter/smeta.xlsx deleted file mode 100644 index 6ffcfe03272..00000000000 Binary files a/X2tConverter/test/iosTest/TestIOSX2tConverter/smeta.xlsx and /dev/null differ diff --git a/X2tConverter/test/iosTest/TestIOSX2tConverter/test.csv b/X2tConverter/test/iosTest/TestIOSX2tConverter/test.csv deleted file mode 100644 index 0bd815b6c1b..00000000000 --- a/X2tConverter/test/iosTest/TestIOSX2tConverter/test.csv +++ /dev/null @@ -1,22 +0,0 @@ -id,location_id,attention,address_1,address_2,city,state_province,postal_code,country -1,1,Fair Oaks Intergenerational Center,2600 Middlefield Road,,Redwood City,CA,94063,US -2,2,PFS Second Career Services,24 Second Avenue,,San Mateo,CA,94401,US -3,3,PFS Senior Peer Counseling,24 Second Avenue,,San Mateo,CA,94403,US -4,4,PFS Family Visitation Center,24 Second Avenue,,San Mateo,CA,94401,US -5,5,Economic Self - Sufficiency Program,24 Second Avenue,,San Mateo,CA,94401,US -6,6,Little House,800 Middle Avenue,,Menlo Park,CA,94025-9881,US -7,7,Rosener House,500 Arbor Road,,Menlo Park,CA,94025,US -8,8,Meals on Wheels - South County,800 Middle Avenue,,Menlo Park,CA,94025-9881,US -9,9,Fair Oaks Branch,2510 Middlefield Road,,Redwood City,CA,94063,US -10,10,Main Library,1044 Middlefield Road,,Redwood City,CA,94063,US -11,11,Schaberg Branch,2140 Euclid Avenue,,Redwood City,CA,94061,US -12,12,Project Read,1044 Middlefield Road,2nd Floor,Redwood City,CA,94063,US -13,13,Redwood Shores Branch,399 Marine Parkway,,Redwood City,CA,94065,US -14,14,Salvation Army,P.O. Box 1147,,Redwood City,CA,94064,US -15,15,Adult Rehabilitation Center,1500 Valencia Street,,San Francisco,CA,94110,US -16,16,Salvation Army,P.O. Box 61868,,Sunnyvale,CA,94088,US -17,17,Salvation Army,409 South Spruce Avenue,,South San Francisco,CA,94080,US -18,18,Redwood City Free Medical Clinic,114 Fifth Avenue,,Redwood City,CA,94063,US -19,19,San Mateo Free Medical/Dental,19 West 39th Avenue,,San Mateo,CA,94403,US -20,20,,123 Main Street,,Fairfax,VA,22031,US -21,22,The Foodies,2013 Avenue of the fellows,Suite 100,San Francisco,CA,90210,US diff --git a/X2tConverter/test/iosTest/TestIOSX2tConverter/test.odp b/X2tConverter/test/iosTest/TestIOSX2tConverter/test.odp deleted file mode 100644 index 582f374db4d..00000000000 Binary files a/X2tConverter/test/iosTest/TestIOSX2tConverter/test.odp and /dev/null differ diff --git a/X2tConverter/test/iosTest/TestIOSX2tConverter/test.ods b/X2tConverter/test/iosTest/TestIOSX2tConverter/test.ods deleted file mode 100644 index e5b7ac35634..00000000000 Binary files a/X2tConverter/test/iosTest/TestIOSX2tConverter/test.ods and /dev/null differ diff --git a/X2tConverter/test/iosTest/TestIOSX2tConverter/test.odt b/X2tConverter/test/iosTest/TestIOSX2tConverter/test.odt deleted file mode 100644 index 945cabfcb2c..00000000000 Binary files a/X2tConverter/test/iosTest/TestIOSX2tConverter/test.odt and /dev/null differ diff --git a/X2tConverter/test/iosTest/TestIOSX2tConverter/test.txt b/X2tConverter/test/iosTest/TestIOSX2tConverter/test.txt deleted file mode 100644 index 8ed1f351b17..00000000000 --- a/X2tConverter/test/iosTest/TestIOSX2tConverter/test.txt +++ /dev/null @@ -1,233 +0,0 @@ -1 China[a] Asia Eastern Asia 1,403,500,365 1,409,517,397 +0.4% -2 India Asia Southern Asia 1,324,171,354 1,339,180,127 +1.1% -3 United States Americas Northern America 322,179,605 324,459,463 +0.7% -4 Indonesia Asia South-eastern Asia 261,115,456 263,991,379 +1.1% -5 Brazil Americas South America 207,652,865 209,288,278 +0.8% -6 Pakistan Asia Southern Asia 193,203,476 197,015,955 +2.0% -7 Nigeria Africa Western Africa 185,989,640 190,886,311 +2.6% -8 Bangladesh Asia Southern Asia 162,951,560 164,669,751 +1.1% -9 Russia Europe Eastern Europe 146,864,513 143,989,754 −2.0% -10 Mexico Americas Central America 127,540,423 129,163,276 +1.3% -11 Japan Asia Eastern Asia 127,748,513 127,484,450 −0.2% -12 Ethiopia Africa Eastern Africa 102,403,196 104,957,438 +2.5% -13 Philippines Asia South-eastern Asia 103,320,222 104,918,090 +1.5% -14 Egypt Africa Northern Africa 95,688,681 97,553,151 +1.9% -15 Vietnam Asia South-eastern Asia 94,569,072 95,540,800 +1.0% -16 Germany Europe Western Europe 81,914,672 82,114,224 +0.2% -17 Democratic Republic of the Congo Africa Middle Africa 78,736,153 81,339,988 +3.3% -18 Iran Asia Southern Asia 80,277,428 81,162,788 +1.1% -19 Turkey Asia Western Asia 79,512,426 80,745,020 +1.6% -20 Thailand Asia South-eastern Asia 68,863,514 69,037,513 +0.3% -21 United Kingdom Europe Northern Europe 65,788,574 66,181,585 +0.6% -22 France[b] Europe Western Europe 64,720,690 64,979,548 +0.4% -23 Italy Europe Southern Europe 59,429,938 59,359,900 −0.1% -24 Tanzania[c] Africa Eastern Africa 55,572,201 57,310,019 +3.1% -25 South Africa Africa Southern Africa 56,015,473 56,717,156 +1.3% -26 Myanmar Asia South-eastern Asia 52,885,223 53,370,609 +0.9% -27 South Korea Asia Eastern Asia 50,791,919 50,982,212 +0.4% -28 Colombia Americas South America 48,653,419 49,065,615 +0.8% -29 Kenya Africa Eastern Africa 48,461,567 49,699,862 +2.6% -30 Spain[d] Europe Southern Europe 46,347,576 46,354,321 0.0% -31 Argentina Americas South America 43,847,430 44,271,041 +1.0% -32 Ukraine[e] Europe Eastern Europe 44,438,625 44,222,947 −0.5% -33 Uganda Africa Eastern Africa 41,487,965 42,862,958 +3.3% -34 Algeria Africa Northern Africa 40,606,052 41,318,142 +1.8% -35 Sudan Africa Northern Africa 39,578,828 40,533,330 +2.4% -36 Iraq Asia Western Asia 37,202,572 38,274,618 +2.9% -37 Poland Europe Eastern Europe 38,224,410 38,170,712 −0.1% -38 Canada Americas Northern America 36,289,822 36,624,199 +0.9% -39 Morocco Africa Northern Africa 35,276,786 35,739,580 +1.3% -40 Afghanistan Asia Southern Asia 34,656,032 35,530,081 +2.5% -41 Saudi Arabia Asia Western Asia 32,275,687 32,938,213 +2.1% -42 Peru Americas South America 31,773,839 32,165,485 +1.2% -43 Venezuela Americas South America 31,568,179 31,977,065 +1.3% -44 Uzbekistan Asia Central Asia 31,446,795 31,910,641 +1.5% -45 Malaysia[f] Asia South-eastern Asia 31,187,265 31,624,264 +1.4% -46 Angola Africa Middle Africa 28,813,463 29,784,193 +3.4% -47 Mozambique Africa Eastern Africa 28,829,476 29,668,834 +2.9% -48 Nepal Asia Southern Asia 28,982,771 29,304,998 +1.1% -49 Ghana Africa Western Africa 28,206,728 28,833,629 +2.2% -50 Yemen Asia Western Asia 27,584,213 28,250,420 +2.4% -51 Madagascar Africa Eastern Africa 24,894,551 25,570,895 +2.7% -52 North Korea Asia Eastern Asia 25,368,620 25,490,965 +0.5% -53 Australia[g] Oceania Australia and New Zealand 24,125,848 24,450,561 +1.3% -54 Ivory Coast Africa Western Africa 23,695,919 24,294,750 +2.5% -55 Cameroon Africa Middle Africa 23,439,189 24,053,727 +2.6% -56 Taiwan[h] Asia Eastern Asia 23,556,706 23,626,456 +0.3% -57 Niger Africa Western Africa 20,672,987 21,477,348 +3.9% -58 Sri Lanka Asia Southern Asia 20,798,492 20,876,917 +0.4% -59 Romania Europe Eastern Europe 19,778,083 19,679,306 −0.5% -60 Burkina Faso Africa Western Africa 18,646,433 19,193,382 +2.9% -61 Malawi Africa Eastern Africa 18,091,575 18,622,104 +2.9% -62 Mali Africa Western Africa 17,994,837 18,541,980 +3.0% -63 Syria Asia Western Asia 18,430,453 18,269,868 −0.9% -64 Kazakhstan Asia Central Asia 17,987,736 18,204,499 +1.2% -65 Chile Americas South America 17,909,754 18,054,726 +0.8% -66 Zambia Africa Eastern Africa 16,591,390 17,094,130 +3.0% -67 Netherlands Europe Western Europe 16,987,330 17,035,938 +0.3% -68 Guatemala Americas Central America 16,582,469 16,913,503 +2.0% -69 Ecuador Americas South America 16,385,068 16,624,858 +1.5% -70 Zimbabwe Africa Eastern Africa 16,150,362 16,529,904 +2.4% -71 Cambodia Asia South-eastern Asia 15,762,370 16,005,373 +1.5% -72 Senegal Africa Western Africa 15,411,614 15,850,567 +2.8% -73 Chad Africa Middle Africa 14,452,543 14,899,994 +3.1% -74 Somalia Africa Eastern Africa 14,317,996 14,742,523 +3.0% -75 Guinea Africa Western Africa 12,395,924 12,717,176 +2.6% -76 South Sudan Africa Eastern Africa 12,230,730 12,575,714 +2.8% -77 Rwanda Africa Eastern Africa 11,917,508 12,208,407 +2.4% -78 Tunisia Africa Northern Africa 11,403,248 11,532,127 +1.1% -79 Cuba Americas Caribbean 11,475,982 11,484,636 +0.1% -80 Belgium Europe Western Europe 11,358,379 11,429,336 +0.6% -81 Benin Africa Western Africa 10,872,298 11,175,692 +2.8% -82 Greece Europe Southern Europe 11,183,716 11,159,773 −0.2% -83 Bolivia Americas South America 10,887,882 11,051,600 +1.5% -84 Haiti Americas Caribbean 10,847,334 10,981,229 +1.2% -85 Burundi Africa Eastern Africa 10,524,117 10,864,245 +3.2% -86 Dominican Republic Americas Caribbean 10,648,791 10,766,998 +1.1% -87 Czech Republic Europe Eastern Europe 10,610,947 10,618,303 +0.1% -88 Portugal Europe Southern Europe 10,371,627 10,329,506 −0.4% -89 Sweden Europe Northern Europe 9,837,533 9,910,701 +0.7% -90 Azerbaijan[i] Asia Western Asia 9,725,376 9,827,589 +1.1% -91 Hungary Europe Eastern Europe 9,753,281 9,721,559 −0.3% -92 Jordan Asia Western Asia 9,455,802 9,702,353 +2.6% -93 Belarus Europe Eastern Europe 9,480,042 9,468,338 −0.1% -94 United Arab Emirates Asia Western Asia 9,269,612 9,400,145 +1.4% -95 Honduras Americas Central America 9,112,867 9,265,067 +1.7% -96 Tajikistan Asia Central Asia 8,734,951 8,921,343 +2.1% -97 Serbia[j] Europe Southern Europe 8,820,083 8,790,574 −0.3% -98 Austria Europe Western Europe 8,712,137 8,735,453 +0.3% -99 Switzerland Europe Western Europe 8,401,739 8,476,005 +0.9% -100 Israel Asia Western Asia 8,191,828 8,321,570 +1.6% -101 Papua New Guinea Oceania Melanesia 8,084,991 8,251,162 +2.1% -102 Togo Africa Western Africa 7,606,374 7,797,694 +2.5% -103 Sierra Leone Africa Western Africa 7,396,190 7,557,212 +2.2% -104 Hong Kong Asia Eastern Asia 7,302,843 7,364,883 +0.8% -105 Bulgaria Europe Eastern Europe 7,131,494 7,084,571 −0.7% -106 Laos Asia South-eastern Asia 6,758,353 6,858,160 +1.5% -107 Paraguay Americas South America 6,725,308 6,811,297 +1.3% -108 El Salvador Americas Central America 6,344,722 6,377,853 +0.5% -109 Libya Africa Northern Africa 6,293,253 6,374,616 +1.3% -110 Nicaragua Americas Central America 6,149,928 6,217,581 +1.1% -111 Lebanon Asia Western Asia 6,006,668 6,082,357 +1.3% -112 Kyrgyzstan Asia Central Asia 5,955,734 6,045,117 +1.5% -113 Turkmenistan Asia Central Asia 5,662,544 5,758,075 +1.7% -114 Denmark Europe Northern Europe 5,711,870 5,733,551 +0.4% -115 Singapore Asia South-eastern Asia 5,622,455 5,708,844 +1.5% -116 Finland[k] Europe Northern Europe 5,503,132 5,523,231 +0.4% -117 Slovakia Europe Eastern Europe 5,444,218 5,447,662 +0.1% -118 Norway[l] Europe Northern Europe 5,254,694 5,305,383 +1.0% -119 Congo Africa Middle Africa 5,125,821 5,260,750 +2.6% -120 Eritrea Africa Eastern Africa 4,954,645 5,068,831 +2.3% -121 Palestine[m] Asia Western Asia 4,790,705 4,920,724 +2.7% -122 Costa Rica Americas Central America 4,857,274 4,905,769 +1.0% -123 Ireland Europe Northern Europe 4,726,078 4,761,657 +0.8% -124 Liberia Africa Western Africa 4,613,823 4,731,906 +2.6% -125 New Zealand Oceania Australia and New Zealand 4,660,833 4,705,818 +1.0% -126 Central African Republic Africa Middle Africa 4,594,621 4,659,080 +1.4% -127 Oman Asia Western Asia 4,424,762 4,636,262 +4.8% -128 Mauritania Africa Western Africa 4,301,018 4,420,184 +2.8% -129 Croatia Europe Southern Europe 4,213,265 4,189,353 −0.6% -130 Kuwait Asia Western Asia 4,052,584 4,136,528 +2.1% -131 Panama Americas Central America 4,034,119 4,098,587 +1.6% -132 Moldova[n] Europe Eastern Europe 4,059,608 4,051,212 −0.2% -133 Georgia[o] Asia Western Asia 3,925,405 3,912,061 −0.3% -134 Puerto Rico Americas Caribbean 3,667,903 3,663,131 −0.1% -135 Bosnia and Herzegovina Europe Southern Europe 3,516,816 3,507,017 −0.3% -136 Uruguay Americas South America 3,444,006 3,456,750 +0.4% -137 Mongolia Asia Eastern Asia 3,027,398 3,075,647 +1.6% -138 Armenia Asia Western Asia 2,924,816 2,930,450 +0.2% -139 Albania Europe Southern Europe 2,926,348 2,930,187 +0.1% -140 Jamaica Americas Caribbean 2,881,355 2,890,299 +0.3% -141 Lithuania Europe Northern Europe 2,908,249 2,890,297 −0.6% -142 Qatar Asia Western Asia 2,569,804 2,639,211 +2.7% -143 Namibia Africa Southern Africa 2,479,713 2,533,794 +2.2% -144 Botswana Africa Southern Africa 2,250,260 2,291,661 +1.8% -145 Lesotho Africa Southern Africa 2,203,821 2,233,339 +1.3% -146 The Gambia Africa Western Africa 2,038,501 2,100,568 +3.0% -147 Republic of Macedonia Europe Southern Europe 2,081,206 2,083,160 +0.1% -148 Slovenia Europe Southern Europe 2,077,862 2,079,976 +0.1% -149 Gabon Africa Middle Africa 1,979,786 2,025,137 +2.3% -150 Latvia Europe Northern Europe 1,970,530 1,949,670 −1.1% -151 Guinea-Bissau Africa Western Africa 1,815,698 1,861,283 +2.5% -152 Bahrain Asia Western Asia 1,425,171 1,492,584 +4.7% -153 Trinidad and Tobago Americas Caribbean 1,364,962 1,369,125 +0.3% -154 Eswatini (Swaziland) Africa Southern Africa 1,343,098 1,367,254 +1.8% -155 Estonia Europe Northern Europe 1,312,442 1,309,632 −0.2% -156 East Timor Asia South-eastern Asia 1,268,671 1,296,311 +2.2% -157 Equatorial Guinea Africa Middle Africa 1,221,490 1,267,689 +3.8% -158 Mauritius[p] Africa Eastern Africa 1,262,132 1,265,138 +0.2% -159 Cyprus[q] Asia Western Asia 1,170,125 1,179,551 +0.8% -160 Djibouti Africa Eastern Africa 942,333 956,985 +1.6% -161 Fiji Oceania Melanesia 898,760 905,502 +0.8% -162 Réunion Africa Eastern Africa 869,925 876,562 +0.8% -163 Comoros Africa Eastern Africa 795,601 813,912 +2.3% -164 Bhutan Asia Southern Asia 797,765 807,610 +1.2% -165 Guyana Americas South America 773,303 777,859 +0.6% -166 Montenegro Europe Southern Europe 628,615 628,960 +0.1% -167 Macau Asia Eastern Asia 612,167 622,567 +1.7% -168 Solomon Islands Oceania Melanesia 599,419 611,343 +2.0% -169 Luxembourg Europe Western Europe 575,747 583,455 +1.3% -170 Suriname Americas South America 558,368 563,402 +0.9% -171 Western Sahara Africa Northern Africa 538,755 552,628 +2.6% -172 Cape Verde Africa Western Africa 539,560 546,388 +1.3% -173 Guadeloupe[r] Americas Caribbean 449,975 449,568 −0.1% -174 Maldives Asia Southern Asia 427,756 436,330 +2.0% -175 Malta Europe Southern Europe 429,362 430,835 +0.3% -176 Brunei Asia South-eastern Asia 423,196 428,697 +1.3% -177 Bahamas Americas Caribbean 391,232 395,361 +1.1% -178 Martinique Americas Caribbean 385,103 384,896 −0.1% -179 Belize Americas Central America 366,954 374,681 +2.1% -180 Iceland Europe Northern Europe 332,474 335,025 +0.8% -181 Barbados Americas Caribbean 284,996 285,719 +0.3% -182 French Polynesia Oceania Polynesia 280,208 283,007 +1.0% -183 French Guiana Americas South America 275,713 282,731 +2.5% -184 New Caledonia Oceania Melanesia 272,677 276,255 +1.3% -185 Vanuatu Oceania Melanesia 270,402 276,244 +2.2% -186 Mayotte Africa Eastern Africa 246,489 253,045 +2.7% -187 Sao Tome and Principe Africa Middle Africa 199,910 204,327 +2.2% -188 Samoa Oceania Polynesia 195,125 196,440 +0.7% -189 Saint Lucia Americas Caribbean 178,015 178,844 +0.5% -190 Guernsey Guernsey and Jersey Europe Northern Europe 164,541 165,314 +0.5% -191 Guam Oceania Micronesia 162,896 164,229 +0.8% -192 Curaçao Americas Caribbean 159,371 160,539 +0.7% -193 Kiribati Oceania Micronesia 114,395 116,398 +1.8% -194 Saint Vincent and the Grenadines Americas Caribbean 109,643 109,897 +0.2% -195 Tonga Oceania Polynesia 107,122 108,020 +0.8% -196 Grenada Americas Caribbean 107,317 107,825 +0.5% -197 Federated States of Micronesia Oceania Micronesia 104,937 105,544 +0.6% -198 Aruba Americas Caribbean 104,822 105,264 +0.4% -199 United States Virgin Islands Americas Caribbean 104,913 104,901 0.0% -200 Antigua and Barbuda Americas Caribbean 100,963 102,012 +1.0% -201 Seychelles Africa Eastern Africa 94,228 94,737 +0.5% -202 Isle of Man Europe Northern Europe 83,737 84,287 +0.7% -203 Andorra Europe Southern Europe 77,281 76,965 −0.4% -204 Dominica Americas Caribbean 73,543 73,925 +0.5% -205 Cayman Islands Americas Caribbean 60,765 61,559 +1.3% -206 Bermuda Americas Northern America 61,666 61,349 −0.5% -207 Greenland Americas Northern America 56,412 56,480 +0.1% -208 American Samoa Oceania Polynesia 55,599 55,641 +0.1% -209 Saint Kitts and Nevis Americas Caribbean 54,821 55,345 +1.0% -210 Northern Mariana Islands Oceania Micronesia 55,023 55,144 +0.2% -211 Marshall Islands Oceania Micronesia 53,066 53,127 +0.1% -212 Faroe Islands Europe Northern Europe 49,117 49,290 +0.4% -213 Sint Maarten Americas Caribbean 39,537 40,120 +1.5% -214 Monaco Europe Western Europe 38,499 38,695 +0.5% -215 Liechtenstein Europe Western Europe 37,666 37,922 +0.7% -216 Turks and Caicos Islands Americas Caribbean 34,900 35,446 +1.6% -217 Gibraltar Europe Southern Europe 34,408 34,571 +0.5% -218 San Marino Europe Southern Europe 33,203 33,400 +0.6% -219 British Virgin Islands Americas Caribbean 30,661 31,196 +1.7% -220 Caribbean Netherlands[s] Americas Caribbean 25,019 25,398 +1.5% -221 Palau Oceania Micronesia 21,503 21,729 +1.1% -222 Cook Islands Oceania Polynesia 17,379 17,380 0.0% -223 Anguilla Americas Caribbean 14,764 14,909 +1.0% -224 Wallis and Futuna Oceania Polynesia 11,899 11,773 −1.1% -225 Nauru Oceania Micronesia 11,347 11,359 +0.1% -226 Tuvalu Oceania Polynesia 11,097 11,192 +0.9% -227 Saint Pierre and Miquelon Americas Northern America 6,305 6,320 +0.2% -228 Montserrat Americas Caribbean 5,152 5,177 +0.5% -229 Saint Helena, Ascension and Tristan da Cunha Africa Western Africa 4,035 4,049 +0.3% -230 Falkland Islands Americas South America 2,910 2,910 0.0% -231 Niue Oceania Polynesia 1,624 1,618 −0.4% -232 Tokelau Oceania Polynesia 1,282 1,300 +1.4% -233 Vatican City[t] Europe Southern Europe 801 792 −1.1% diff --git a/X2tConverter/test/iosTest/iosTest-sources.xcodeproj/project.pbxproj b/X2tConverter/test/iosTest/iosTest-sources.xcodeproj/project.pbxproj deleted file mode 100644 index c8a71f4a47d..00000000000 --- a/X2tConverter/test/iosTest/iosTest-sources.xcodeproj/project.pbxproj +++ /dev/null @@ -1,531 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - 1734C9A61B4C251D00C2A6C8 /* smeta.xlsx in Resources */ = {isa = PBXBuildFile; fileRef = 1734C9A51B4C251D00C2A6C8 /* smeta.xlsx */; }; - 1773201F1B4FB9B700BB22FC /* price.xlsx in Resources */ = {isa = PBXBuildFile; fileRef = 1773201E1B4FB9B700BB22FC /* price.xlsx */; }; - 177B1B471B5FCD34001FC26F /* shapes.xlsx in Resources */ = {isa = PBXBuildFile; fileRef = 177B1B461B5FCD34001FC26F /* shapes.xlsx */; }; - 17DAB67E1ACC371E005AF479 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 17DAB67D1ACC371E005AF479 /* main.m */; }; - 17DAB6811ACC371E005AF479 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 17DAB6801ACC371E005AF479 /* AppDelegate.m */; }; - 17DAB6841ACC371E005AF479 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 17DAB6831ACC371E005AF479 /* ViewController.m */; }; - 17DAB6871ACC371F005AF479 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 17DAB6851ACC371F005AF479 /* Main.storyboard */; }; - 17DAB6891ACC371F005AF479 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 17DAB6881ACC371F005AF479 /* Images.xcassets */; }; - 17DAB68C1ACC371F005AF479 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 17DAB68A1ACC371F005AF479 /* LaunchScreen.xib */; }; - 17DAB70E1ACC3B96005AF479 /* demo.docx in Resources */ = {isa = PBXBuildFile; fileRef = 17DAB70D1ACC3B90005AF479 /* demo.docx */; }; - 6967BEB31E27D5BE00A129E2 /* libiconv.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 6967BEB21E27D5BE00A129E2 /* libiconv.tbd */; }; - 697CDFEA2049649800C2638C /* empty.docx in Resources */ = {isa = PBXBuildFile; fileRef = 697CDFE72049649800C2638C /* empty.docx */; }; - 697CDFEB2049649800C2638C /* empty.xlsx in Resources */ = {isa = PBXBuildFile; fileRef = 697CDFE92049649800C2638C /* empty.xlsx */; }; - 699690731E2F925200B620CD /* libc++abi.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 699690721E2F925200B620CD /* libc++abi.tbd */; }; - 69BE370C1F60129600CBA47B /* crypted.xlsx in Resources */ = {isa = PBXBuildFile; fileRef = 69BE370B1F60129600CBA47B /* crypted.xlsx */; }; - 8A08CA1622DCA8EF00B1CE11 /* libX2tConverter.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 8A08CA1322DCA8DB00B1CE11 /* libX2tConverter.a */; }; - 8A2851F8220B29A800779A38 /* test.txt in Resources */ = {isa = PBXBuildFile; fileRef = 8A2851F6220B29A800779A38 /* test.txt */; }; - 8A94F3CB207CE7D600EC05D2 /* test.csv in Resources */ = {isa = PBXBuildFile; fileRef = 8A94F3C9207CE7D600EC05D2 /* test.csv */; }; - 8AC4E6EF22058B2A0044119A /* boost.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8AC4E6EE22058B290044119A /* boost.framework */; }; - 8AC4E6F52205999B0044119A /* test.odt in Resources */ = {isa = PBXBuildFile; fileRef = 8AC4E6F22205999B0044119A /* test.odt */; }; - 8AC4E6F62205999B0044119A /* test.ods in Resources */ = {isa = PBXBuildFile; fileRef = 8AC4E6F32205999B0044119A /* test.ods */; }; - 8AC4E6F72205999B0044119A /* test.odp in Resources */ = {isa = PBXBuildFile; fileRef = 8AC4E6F42205999B0044119A /* test.odp */; }; - 8AC4E7282205A4D10044119A /* demo.pptx in Resources */ = {isa = PBXBuildFile; fileRef = 8AC4E7272205A4D10044119A /* demo.pptx */; }; -/* End PBXBuildFile section */ - -/* Begin PBXContainerItemProxy section */ - 8A08CA1222DCA8DB00B1CE11 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 8A08C9F322DCA8DB00B1CE11 /* X2tConverter-sources.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 17C8DED01ACD696100902C85; - remoteInfo = x2tconverter; - }; - 8A08CA1422DCA8E500B1CE11 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 8A08C9F322DCA8DB00B1CE11 /* X2tConverter-sources.xcodeproj */; - proxyType = 1; - remoteGlobalIDString = 17C8DEC11ACD696100902C85; - remoteInfo = x2tconverter; - }; -/* End PBXContainerItemProxy section */ - -/* Begin PBXFileReference section */ - 1734C9A51B4C251D00C2A6C8 /* smeta.xlsx */ = {isa = PBXFileReference; lastKnownFileType = file; path = smeta.xlsx; sourceTree = ""; }; - 1773201E1B4FB9B700BB22FC /* price.xlsx */ = {isa = PBXFileReference; lastKnownFileType = file; path = price.xlsx; sourceTree = ""; }; - 177B1B461B5FCD34001FC26F /* shapes.xlsx */ = {isa = PBXFileReference; lastKnownFileType = file; path = shapes.xlsx; sourceTree = ""; }; - 17DAB6781ACC371E005AF479 /* iosTest.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = iosTest.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 17DAB67C1ACC371E005AF479 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 17DAB67D1ACC371E005AF479 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; - 17DAB67F1ACC371E005AF479 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; - 17DAB6801ACC371E005AF479 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; - 17DAB6821ACC371E005AF479 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; - 17DAB6831ACC371E005AF479 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; - 17DAB6861ACC371F005AF479 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; - 17DAB6881ACC371F005AF479 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; - 17DAB68B1ACC371F005AF479 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; - 17DAB70D1ACC3B90005AF479 /* demo.docx */ = {isa = PBXFileReference; lastKnownFileType = file; path = demo.docx; sourceTree = ""; }; - 6905975F1CA137D000000D4D /* X2tConverter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = X2tConverter.h; path = ../../../build/Mac/X2tConverter/X2tConverter/X2tConverter.h; sourceTree = ""; }; - 6967BEB21E27D5BE00A129E2 /* libiconv.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libiconv.tbd; path = usr/lib/libiconv.tbd; sourceTree = SDKROOT; }; - 697CDFE72049649800C2638C /* empty.docx */ = {isa = PBXFileReference; lastKnownFileType = file; path = empty.docx; sourceTree = ""; }; - 697CDFE92049649800C2638C /* empty.xlsx */ = {isa = PBXFileReference; lastKnownFileType = file; path = empty.xlsx; sourceTree = ""; }; - 698810C41F4DA87A00E4C541 /* libcryptopp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libcryptopp.a; path = ../../../Common/3dParty/cryptopp/libcryptopp.a; sourceTree = ""; }; - 699690721E2F925200B620CD /* libc++abi.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = "libc++abi.tbd"; path = "usr/lib/libc++abi.tbd"; sourceTree = SDKROOT; }; - 69BE370B1F60129600CBA47B /* crypted.xlsx */ = {isa = PBXFileReference; lastKnownFileType = file; path = crypted.xlsx; sourceTree = ""; }; - 8A08C9F322DCA8DB00B1CE11 /* X2tConverter-sources.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = "X2tConverter-sources.xcodeproj"; path = "../../build/Mac/X2tConverter/X2tConverter-sources.xcodeproj"; sourceTree = ""; }; - 8A1045C420F4B55E005A0F61 /* libicudata.58.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libicudata.58.dylib; path = ../../../Common/3dParty/icu/mac_64/build/libicudata.58.dylib; sourceTree = ""; }; - 8A1045C520F4B55F005A0F61 /* libicuuc.58.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libicuuc.58.dylib; path = ../../../Common/3dParty/icu/mac_64/build/libicuuc.58.dylib; sourceTree = ""; }; - 8A2851F6220B29A800779A38 /* test.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = test.txt; sourceTree = ""; }; - 8A94F3C9207CE7D600EC05D2 /* test.csv */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = test.csv; sourceTree = ""; }; - 8A9FAD36207781C5007787F6 /* OfficeFileErrorDescription.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OfficeFileErrorDescription.h; path = ../../../../Common/OfficeFileErrorDescription.h; sourceTree = ""; }; - 8AC4E6EE22058B290044119A /* boost.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = boost.framework; path = ../../../Common/3dParty/boost/ios/framework/boost.framework; sourceTree = ""; }; - 8AC4E6F22205999B0044119A /* test.odt */ = {isa = PBXFileReference; lastKnownFileType = file; path = test.odt; sourceTree = ""; }; - 8AC4E6F32205999B0044119A /* test.ods */ = {isa = PBXFileReference; lastKnownFileType = file; path = test.ods; sourceTree = ""; }; - 8AC4E6F42205999B0044119A /* test.odp */ = {isa = PBXFileReference; lastKnownFileType = file; path = test.odp; sourceTree = ""; }; - 8AC4E7272205A4D10044119A /* demo.pptx */ = {isa = PBXFileReference; lastKnownFileType = file; path = demo.pptx; sourceTree = ""; }; - 8AED79AA20F50164008BB78E /* libicui18n.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libicui18n.a; path = "../../../../../Downloads/icu-ios-master/build-universal/libicui18n.a"; sourceTree = ""; }; - 8AED79AC20F50164008BB78E /* libicuio.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libicuio.a; path = "../../../../../Downloads/icu-ios-master/build-universal/libicuio.a"; sourceTree = ""; }; - 8AED79AD20F50164008BB78E /* libicutu.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libicutu.a; path = "../../../../../Downloads/icu-ios-master/build-universal/libicutu.a"; sourceTree = ""; }; - 8AED79AE20F50164008BB78E /* libicuuc.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libicuuc.a; path = "../../../../../Downloads/icu-ios-master/build-universal/libicuuc.a"; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 17DAB6751ACC371E005AF479 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 699690731E2F925200B620CD /* libc++abi.tbd in Frameworks */, - 6967BEB31E27D5BE00A129E2 /* libiconv.tbd in Frameworks */, - 8AC4E6EF22058B2A0044119A /* boost.framework in Frameworks */, - 8A08CA1622DCA8EF00B1CE11 /* libX2tConverter.a in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 17C1FB191ACC3E3B006B99B3 /* SDK */ = { - isa = PBXGroup; - children = ( - 8A9FAD36207781C5007787F6 /* OfficeFileErrorDescription.h */, - 6905975F1CA137D000000D4D /* X2tConverter.h */, - ); - name = SDK; - sourceTree = ""; - }; - 17DAB66F1ACC371E005AF479 = { - isa = PBXGroup; - children = ( - 8A08C9F322DCA8DB00B1CE11 /* X2tConverter-sources.xcodeproj */, - 17DAB67A1ACC371E005AF479 /* iosTest */, - 17DAB6791ACC371E005AF479 /* Products */, - 6967BEB11E27D5BE00A129E2 /* Frameworks */, - ); - sourceTree = ""; - }; - 17DAB6791ACC371E005AF479 /* Products */ = { - isa = PBXGroup; - children = ( - 17DAB6781ACC371E005AF479 /* iosTest.app */, - ); - name = Products; - sourceTree = ""; - }; - 17DAB67A1ACC371E005AF479 /* iosTest */ = { - isa = PBXGroup; - children = ( - 17C1FB191ACC3E3B006B99B3 /* SDK */, - 17DAB70A1ACC3B58005AF479 /* Files */, - 17DAB67F1ACC371E005AF479 /* AppDelegate.h */, - 17DAB6801ACC371E005AF479 /* AppDelegate.m */, - 17DAB6821ACC371E005AF479 /* ViewController.h */, - 17DAB6831ACC371E005AF479 /* ViewController.m */, - 17DAB6851ACC371F005AF479 /* Main.storyboard */, - 17DAB6881ACC371F005AF479 /* Images.xcassets */, - 17DAB68A1ACC371F005AF479 /* LaunchScreen.xib */, - 17DAB67B1ACC371E005AF479 /* Supporting Files */, - ); - name = iosTest; - path = TestIOSX2tConverter; - sourceTree = ""; - }; - 17DAB67B1ACC371E005AF479 /* Supporting Files */ = { - isa = PBXGroup; - children = ( - 17DAB67C1ACC371E005AF479 /* Info.plist */, - 17DAB67D1ACC371E005AF479 /* main.m */, - ); - name = "Supporting Files"; - sourceTree = ""; - }; - 17DAB70A1ACC3B58005AF479 /* Files */ = { - isa = PBXGroup; - children = ( - 17DAB70D1ACC3B90005AF479 /* demo.docx */, - 8AC4E7272205A4D10044119A /* demo.pptx */, - 69BE370B1F60129600CBA47B /* crypted.xlsx */, - 177B1B461B5FCD34001FC26F /* shapes.xlsx */, - 1773201E1B4FB9B700BB22FC /* price.xlsx */, - 1734C9A51B4C251D00C2A6C8 /* smeta.xlsx */, - 697CDFE72049649800C2638C /* empty.docx */, - 697CDFE92049649800C2638C /* empty.xlsx */, - 8A94F3C9207CE7D600EC05D2 /* test.csv */, - 8AC4E6F42205999B0044119A /* test.odp */, - 8AC4E6F32205999B0044119A /* test.ods */, - 8AC4E6F22205999B0044119A /* test.odt */, - 8A2851F6220B29A800779A38 /* test.txt */, - ); - name = Files; - sourceTree = ""; - }; - 6967BEB11E27D5BE00A129E2 /* Frameworks */ = { - isa = PBXGroup; - children = ( - 8AC4E6EE22058B290044119A /* boost.framework */, - 8AED79AA20F50164008BB78E /* libicui18n.a */, - 8AED79AC20F50164008BB78E /* libicuio.a */, - 8AED79AD20F50164008BB78E /* libicutu.a */, - 8AED79AE20F50164008BB78E /* libicuuc.a */, - 8A1045C420F4B55E005A0F61 /* libicudata.58.dylib */, - 8A1045C520F4B55F005A0F61 /* libicuuc.58.dylib */, - 698810C41F4DA87A00E4C541 /* libcryptopp.a */, - 699690721E2F925200B620CD /* libc++abi.tbd */, - 6967BEB21E27D5BE00A129E2 /* libiconv.tbd */, - ); - name = Frameworks; - sourceTree = ""; - }; - 8A08C9F422DCA8DB00B1CE11 /* Products */ = { - isa = PBXGroup; - children = ( - 8A08CA1322DCA8DB00B1CE11 /* libX2tConverter.a */, - ); - name = Products; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 17DAB6771ACC371E005AF479 /* iosTest */ = { - isa = PBXNativeTarget; - buildConfigurationList = 17DAB69B1ACC371F005AF479 /* Build configuration list for PBXNativeTarget "iosTest" */; - buildPhases = ( - 17DAB6741ACC371E005AF479 /* Sources */, - 17DAB6751ACC371E005AF479 /* Frameworks */, - 17DAB6761ACC371E005AF479 /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - 8A08CA1522DCA8E500B1CE11 /* PBXTargetDependency */, - ); - name = iosTest; - productName = TestIOSX2tConverter; - productReference = 17DAB6781ACC371E005AF479 /* iosTest.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 17DAB6701ACC371E005AF479 /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 0930; - ORGANIZATIONNAME = "Ascensio System SIA"; - TargetAttributes = { - 17DAB6771ACC371E005AF479 = { - CreatedOnToolsVersion = 6.2; - DevelopmentTeam = 2WH24U26GJ; - ProvisioningStyle = Automatic; - }; - }; - }; - buildConfigurationList = 17DAB6731ACC371E005AF479 /* Build configuration list for PBXProject "iosTest" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 0; - knownRegions = ( - English, - en, - Base, - ); - mainGroup = 17DAB66F1ACC371E005AF479; - productRefGroup = 17DAB6791ACC371E005AF479 /* Products */; - projectDirPath = ""; - projectReferences = ( - { - ProductGroup = 8A08C9F422DCA8DB00B1CE11 /* Products */; - ProjectRef = 8A08C9F322DCA8DB00B1CE11 /* X2tConverter-sources.xcodeproj */; - }, - ); - projectRoot = ""; - targets = ( - 17DAB6771ACC371E005AF479 /* iosTest */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXReferenceProxy section */ - 8A08CA1322DCA8DB00B1CE11 /* libX2tConverter.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libX2tConverter.a; - remoteRef = 8A08CA1222DCA8DB00B1CE11 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; -/* End PBXReferenceProxy section */ - -/* Begin PBXResourcesBuildPhase section */ - 17DAB6761ACC371E005AF479 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 8A94F3CB207CE7D600EC05D2 /* test.csv in Resources */, - 8AC4E6F72205999B0044119A /* test.odp in Resources */, - 8AC4E6F52205999B0044119A /* test.odt in Resources */, - 69BE370C1F60129600CBA47B /* crypted.xlsx in Resources */, - 17DAB6871ACC371F005AF479 /* Main.storyboard in Resources */, - 17DAB68C1ACC371F005AF479 /* LaunchScreen.xib in Resources */, - 8A2851F8220B29A800779A38 /* test.txt in Resources */, - 8AC4E7282205A4D10044119A /* demo.pptx in Resources */, - 17DAB6891ACC371F005AF479 /* Images.xcassets in Resources */, - 697CDFEA2049649800C2638C /* empty.docx in Resources */, - 1734C9A61B4C251D00C2A6C8 /* smeta.xlsx in Resources */, - 697CDFEB2049649800C2638C /* empty.xlsx in Resources */, - 177B1B471B5FCD34001FC26F /* shapes.xlsx in Resources */, - 8AC4E6F62205999B0044119A /* test.ods in Resources */, - 1773201F1B4FB9B700BB22FC /* price.xlsx in Resources */, - 17DAB70E1ACC3B96005AF479 /* demo.docx in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 17DAB6741ACC371E005AF479 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 17DAB6841ACC371E005AF479 /* ViewController.m in Sources */, - 17DAB6811ACC371E005AF479 /* AppDelegate.m in Sources */, - 17DAB67E1ACC371E005AF479 /* main.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXTargetDependency section */ - 8A08CA1522DCA8E500B1CE11 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = x2tconverter; - targetProxy = 8A08CA1422DCA8E500B1CE11 /* PBXContainerItemProxy */; - }; -/* End PBXTargetDependency section */ - -/* Begin PBXVariantGroup section */ - 17DAB6851ACC371F005AF479 /* Main.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 17DAB6861ACC371F005AF479 /* Base */, - ); - name = Main.storyboard; - sourceTree = ""; - }; - 17DAB68A1ACC371F005AF479 /* LaunchScreen.xib */ = { - isa = PBXVariantGroup; - children = ( - 17DAB68B1ACC371F005AF479 /* Base */, - ); - name = LaunchScreen.xib; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - 17DAB6991ACC371F005AF479 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_SYMBOLS_PRIVATE_EXTERN = NO; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 10.0; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - OTHER_LDFLAGS = ( - "-ObjC", - "-lstdc++", - "-lz", - ); - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - 17DAB69A1ACC371F005AF479 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 10.0; - MTL_ENABLE_DEBUG_INFO = NO; - OTHER_LDFLAGS = ( - "-ObjC", - "-lstdc++", - "-lz", - ); - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - 17DAB69C1ACC371F005AF479 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CLANG_CXX_LANGUAGE_STANDARD = "compiler-default"; - CLANG_CXX_LIBRARY = "compiler-default"; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - DEVELOPMENT_TEAM = 2WH24U26GJ; - ENABLE_BITCODE = YES; - FRAMEWORK_SEARCH_PATHS = "$(PROJECT_DIR)/../../../Common/3dParty/boost/ios/framework"; - INFOPLIST_FILE = TestIOSX2tConverter/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 10.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - OTHER_CFLAGS = ""; - OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)"; - OTHER_LDFLAGS = ( - "-lstdc++", - "-lxml2", - "-lz", - "-lc++", - ); - PRODUCT_BUNDLE_IDENTIFIER = "com.onlyoffice.$(PRODUCT_NAME:rfc1034identifier)"; - PRODUCT_NAME = iosTest; - }; - name = Debug; - }; - 17DAB69D1ACC371F005AF479 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CLANG_CXX_LANGUAGE_STANDARD = "compiler-default"; - CLANG_CXX_LIBRARY = "compiler-default"; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - DEVELOPMENT_TEAM = 2WH24U26GJ; - ENABLE_BITCODE = YES; - FRAMEWORK_SEARCH_PATHS = "$(PROJECT_DIR)/../../../Common/3dParty/boost/ios/framework"; - INFOPLIST_FILE = TestIOSX2tConverter/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 10.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - OTHER_CFLAGS = ""; - OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)"; - OTHER_LDFLAGS = ( - "-lstdc++", - "-lxml2", - "-lz", - "-lc++", - ); - PRODUCT_BUNDLE_IDENTIFIER = "com.onlyoffice.$(PRODUCT_NAME:rfc1034identifier)"; - PRODUCT_NAME = iosTest; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 17DAB6731ACC371E005AF479 /* Build configuration list for PBXProject "iosTest" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 17DAB6991ACC371F005AF479 /* Debug */, - 17DAB69A1ACC371F005AF479 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 17DAB69B1ACC371F005AF479 /* Build configuration list for PBXNativeTarget "iosTest" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 17DAB69C1ACC371F005AF479 /* Debug */, - 17DAB69D1ACC371F005AF479 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 17DAB6701ACC371E005AF479 /* Project object */; -} diff --git a/X2tConverter/test/iosTest/iosTest-sources.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/X2tConverter/test/iosTest/iosTest-sources.xcodeproj/project.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 60c25ad0164..00000000000 --- a/X2tConverter/test/iosTest/iosTest-sources.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/X2tConverter/test/iosTest/iosTest-sources.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/X2tConverter/test/iosTest/iosTest-sources.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist deleted file mode 100644 index 18d981003d6..00000000000 --- a/X2tConverter/test/iosTest/iosTest-sources.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +++ /dev/null @@ -1,8 +0,0 @@ - - - - - IDEDidComputeMac32BitWarning - - - diff --git a/X2tConverter/test/iosTest/iosTest-sources.xcodeproj/xcshareddata/xcschemes/iosTest 2.xcscheme b/X2tConverter/test/iosTest/iosTest-sources.xcodeproj/xcshareddata/xcschemes/iosTest 2.xcscheme deleted file mode 100644 index 5af909db5ab..00000000000 --- a/X2tConverter/test/iosTest/iosTest-sources.xcodeproj/xcshareddata/xcschemes/iosTest 2.xcscheme +++ /dev/null @@ -1,91 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/X2tConverter/test/iosTest/iosTest-sources.xcodeproj/xcshareddata/xcschemes/iosTest.xcscheme b/X2tConverter/test/iosTest/iosTest-sources.xcodeproj/xcshareddata/xcschemes/iosTest.xcscheme deleted file mode 100644 index 69780743832..00000000000 --- a/X2tConverter/test/iosTest/iosTest-sources.xcodeproj/xcshareddata/xcschemes/iosTest.xcscheme +++ /dev/null @@ -1,91 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/X2tConverter/test/iosTest/iosTest.xcodeproj/project.pbxproj b/X2tConverter/test/iosTest/iosTest.xcodeproj/project.pbxproj deleted file mode 100644 index 88b640a4792..00000000000 --- a/X2tConverter/test/iosTest/iosTest.xcodeproj/project.pbxproj +++ /dev/null @@ -1,555 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - 1734C9A61B4C251D00C2A6C8 /* smeta.xlsx in Resources */ = {isa = PBXBuildFile; fileRef = 1734C9A51B4C251D00C2A6C8 /* smeta.xlsx */; }; - 1773201F1B4FB9B700BB22FC /* price.xlsx in Resources */ = {isa = PBXBuildFile; fileRef = 1773201E1B4FB9B700BB22FC /* price.xlsx */; }; - 177B1B471B5FCD34001FC26F /* shapes.xlsx in Resources */ = {isa = PBXBuildFile; fileRef = 177B1B461B5FCD34001FC26F /* shapes.xlsx */; }; - 17DAB67E1ACC371E005AF479 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 17DAB67D1ACC371E005AF479 /* main.m */; }; - 17DAB6811ACC371E005AF479 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 17DAB6801ACC371E005AF479 /* AppDelegate.m */; }; - 17DAB6841ACC371E005AF479 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 17DAB6831ACC371E005AF479 /* ViewController.m */; }; - 17DAB6871ACC371F005AF479 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 17DAB6851ACC371F005AF479 /* Main.storyboard */; }; - 17DAB6891ACC371F005AF479 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 17DAB6881ACC371F005AF479 /* Images.xcassets */; }; - 17DAB68C1ACC371F005AF479 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 17DAB68A1ACC371F005AF479 /* LaunchScreen.xib */; }; - 17DAB70E1ACC3B96005AF479 /* demo.docx in Resources */ = {isa = PBXBuildFile; fileRef = 17DAB70D1ACC3B90005AF479 /* demo.docx */; }; - 6967BEB31E27D5BE00A129E2 /* libiconv.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 6967BEB21E27D5BE00A129E2 /* libiconv.tbd */; }; - 697CDFEA2049649800C2638C /* empty.docx in Resources */ = {isa = PBXBuildFile; fileRef = 697CDFE72049649800C2638C /* empty.docx */; }; - 697CDFEB2049649800C2638C /* empty.xlsx in Resources */ = {isa = PBXBuildFile; fileRef = 697CDFE92049649800C2638C /* empty.xlsx */; }; - 699690731E2F925200B620CD /* libc++abi.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 699690721E2F925200B620CD /* libc++abi.tbd */; }; - 69BE370C1F60129600CBA47B /* crypted.xlsx in Resources */ = {isa = PBXBuildFile; fileRef = 69BE370B1F60129600CBA47B /* crypted.xlsx */; }; - 8A08CAA722DCAEB600B1CE11 /* libX2tConverter.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 8A08CA6D22DCACCC00B1CE11 /* libX2tConverter.a */; }; - 8A08CAAC22DCBF7000B1CE11 /* OfficeCryptReader.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8A08CAAB22DCBF7000B1CE11 /* OfficeCryptReader.framework */; }; - 8A08CAAE22DCBF7300B1CE11 /* RtfFormatLib.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8A08CAAD22DCBF7300B1CE11 /* RtfFormatLib.framework */; }; - 8A08CAB022DCC8F800B1CE11 /* icu.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8A08CAAF22DCC8F800B1CE11 /* icu.framework */; }; - 8A08CAB222DCD88600B1CE11 /* ASCOfficeDocxFile2Lib.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8A08CAB122DCD88600B1CE11 /* ASCOfficeDocxFile2Lib.framework */; }; - 8A2851F8220B29A800779A38 /* test.txt in Resources */ = {isa = PBXBuildFile; fileRef = 8A2851F6220B29A800779A38 /* test.txt */; }; - 8A94F3CB207CE7D600EC05D2 /* test.csv in Resources */ = {isa = PBXBuildFile; fileRef = 8A94F3C9207CE7D600EC05D2 /* test.csv */; }; - 8AC4E6EF22058B2A0044119A /* boost.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8AC4E6EE22058B290044119A /* boost.framework */; }; - 8AC4E6F52205999B0044119A /* test.odt in Resources */ = {isa = PBXBuildFile; fileRef = 8AC4E6F22205999B0044119A /* test.odt */; }; - 8AC4E6F62205999B0044119A /* test.ods in Resources */ = {isa = PBXBuildFile; fileRef = 8AC4E6F32205999B0044119A /* test.ods */; }; - 8AC4E6F72205999B0044119A /* test.odp in Resources */ = {isa = PBXBuildFile; fileRef = 8AC4E6F42205999B0044119A /* test.odp */; }; - 8AC4E7282205A4D10044119A /* demo.pptx in Resources */ = {isa = PBXBuildFile; fileRef = 8AC4E7272205A4D10044119A /* demo.pptx */; }; - 8AFA661722DE15A000D70E48 /* DocxFormatLib.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8AFA661522DE15A000D70E48 /* DocxFormatLib.framework */; }; - 8AFA661922DE15A900D70E48 /* PPTXFormatLib.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8AFA661822DE15A900D70E48 /* PPTXFormatLib.framework */; }; -/* End PBXBuildFile section */ - -/* Begin PBXContainerItemProxy section */ - 8A08CA6C22DCACCC00B1CE11 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 8A08CA4D22DCACCB00B1CE11 /* X2tConverter.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 17C8DED01ACD696100902C85; - remoteInfo = x2tconverter; - }; - 8A08CA6E22DCACD700B1CE11 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 8A08CA4D22DCACCB00B1CE11 /* X2tConverter.xcodeproj */; - proxyType = 1; - remoteGlobalIDString = 17C8DEC11ACD696100902C85; - remoteInfo = x2tconverter; - }; -/* End PBXContainerItemProxy section */ - -/* Begin PBXFileReference section */ - 1734C9A51B4C251D00C2A6C8 /* smeta.xlsx */ = {isa = PBXFileReference; lastKnownFileType = file; path = smeta.xlsx; sourceTree = ""; }; - 1773201E1B4FB9B700BB22FC /* price.xlsx */ = {isa = PBXFileReference; lastKnownFileType = file; path = price.xlsx; sourceTree = ""; }; - 177B1B461B5FCD34001FC26F /* shapes.xlsx */ = {isa = PBXFileReference; lastKnownFileType = file; path = shapes.xlsx; sourceTree = ""; }; - 17DAB6781ACC371E005AF479 /* iosTest.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = iosTest.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 17DAB67C1ACC371E005AF479 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 17DAB67D1ACC371E005AF479 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; - 17DAB67F1ACC371E005AF479 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; - 17DAB6801ACC371E005AF479 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; - 17DAB6821ACC371E005AF479 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; - 17DAB6831ACC371E005AF479 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; - 17DAB6861ACC371F005AF479 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; - 17DAB6881ACC371F005AF479 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; - 17DAB68B1ACC371F005AF479 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; - 17DAB70D1ACC3B90005AF479 /* demo.docx */ = {isa = PBXFileReference; lastKnownFileType = file; path = demo.docx; sourceTree = ""; }; - 6905975F1CA137D000000D4D /* X2tConverter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = X2tConverter.h; path = ../../../build/Mac/X2tConverter/X2tConverter/X2tConverter.h; sourceTree = ""; }; - 6967BEB21E27D5BE00A129E2 /* libiconv.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libiconv.tbd; path = usr/lib/libiconv.tbd; sourceTree = SDKROOT; }; - 697CDFE72049649800C2638C /* empty.docx */ = {isa = PBXFileReference; lastKnownFileType = file; path = empty.docx; sourceTree = ""; }; - 697CDFE92049649800C2638C /* empty.xlsx */ = {isa = PBXFileReference; lastKnownFileType = file; path = empty.xlsx; sourceTree = ""; }; - 698810C41F4DA87A00E4C541 /* libcryptopp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libcryptopp.a; path = ../../../Common/3dParty/cryptopp/libcryptopp.a; sourceTree = ""; }; - 699690721E2F925200B620CD /* libc++abi.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = "libc++abi.tbd"; path = "usr/lib/libc++abi.tbd"; sourceTree = SDKROOT; }; - 69BE370B1F60129600CBA47B /* crypted.xlsx */ = {isa = PBXFileReference; lastKnownFileType = file; path = crypted.xlsx; sourceTree = ""; }; - 8A08CA4D22DCACCB00B1CE11 /* X2tConverter.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = X2tConverter.xcodeproj; path = ../../build/Mac/X2tConverter/X2tConverter.xcodeproj; sourceTree = ""; }; - 8A08CAAB22DCBF7000B1CE11 /* OfficeCryptReader.framework */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = OfficeCryptReader.framework; path = "../../../../mobile-apps/ios/Vendor/ONLYOFFICE/SDK/lib/OfficeCryptReader.framework"; sourceTree = ""; }; - 8A08CAAD22DCBF7300B1CE11 /* RtfFormatLib.framework */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = RtfFormatLib.framework; path = "../../../../mobile-apps/ios/Vendor/ONLYOFFICE/SDK/lib/RtfFormatLib.framework"; sourceTree = ""; }; - 8A08CAAF22DCC8F800B1CE11 /* icu.framework */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = icu.framework; path = "../../../../mobile-apps/ios/Vendor/ONLYOFFICE/SDK/lib/icu.framework"; sourceTree = ""; }; - 8A08CAB122DCD88600B1CE11 /* ASCOfficeDocxFile2Lib.framework */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = ASCOfficeDocxFile2Lib.framework; path = "../../../../mobile-apps/ios/Vendor/ONLYOFFICE/SDK/lib/ASCOfficeDocxFile2Lib.framework"; sourceTree = ""; }; - 8A1045C420F4B55E005A0F61 /* libicudata.58.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libicudata.58.dylib; path = ../../../Common/3dParty/icu/mac_64/build/libicudata.58.dylib; sourceTree = ""; }; - 8A1045C520F4B55F005A0F61 /* libicuuc.58.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libicuuc.58.dylib; path = ../../../Common/3dParty/icu/mac_64/build/libicuuc.58.dylib; sourceTree = ""; }; - 8A2851F6220B29A800779A38 /* test.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = test.txt; sourceTree = ""; }; - 8A94F3C9207CE7D600EC05D2 /* test.csv */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = test.csv; sourceTree = ""; }; - 8A9FAD36207781C5007787F6 /* OfficeFileErrorDescription.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OfficeFileErrorDescription.h; path = ../../../../Common/OfficeFileErrorDescription.h; sourceTree = ""; }; - 8AC4E6EE22058B290044119A /* boost.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = boost.framework; path = ../../../Common/3dParty/boost/ios/framework/boost.framework; sourceTree = ""; }; - 8AC4E6F22205999B0044119A /* test.odt */ = {isa = PBXFileReference; lastKnownFileType = file; path = test.odt; sourceTree = ""; }; - 8AC4E6F32205999B0044119A /* test.ods */ = {isa = PBXFileReference; lastKnownFileType = file; path = test.ods; sourceTree = ""; }; - 8AC4E6F42205999B0044119A /* test.odp */ = {isa = PBXFileReference; lastKnownFileType = file; path = test.odp; sourceTree = ""; }; - 8AC4E7272205A4D10044119A /* demo.pptx */ = {isa = PBXFileReference; lastKnownFileType = file; path = demo.pptx; sourceTree = ""; }; - 8AED79AA20F50164008BB78E /* libicui18n.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libicui18n.a; path = "../../../../../Downloads/icu-ios-master/build-universal/libicui18n.a"; sourceTree = ""; }; - 8AED79AC20F50164008BB78E /* libicuio.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libicuio.a; path = "../../../../../Downloads/icu-ios-master/build-universal/libicuio.a"; sourceTree = ""; }; - 8AED79AD20F50164008BB78E /* libicutu.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libicutu.a; path = "../../../../../Downloads/icu-ios-master/build-universal/libicutu.a"; sourceTree = ""; }; - 8AED79AE20F50164008BB78E /* libicuuc.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libicuuc.a; path = "../../../../../Downloads/icu-ios-master/build-universal/libicuuc.a"; sourceTree = ""; }; - 8AFA661522DE15A000D70E48 /* DocxFormatLib.framework */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = DocxFormatLib.framework; path = "../../../../mobile-apps/ios/Vendor/ONLYOFFICE/SDK/lib/DocxFormatLib.framework"; sourceTree = ""; }; - 8AFA661822DE15A900D70E48 /* PPTXFormatLib.framework */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = PPTXFormatLib.framework; path = "../../../../mobile-apps/ios/Vendor/ONLYOFFICE/SDK/lib/PPTXFormatLib.framework"; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 17DAB6751ACC371E005AF479 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 699690731E2F925200B620CD /* libc++abi.tbd in Frameworks */, - 6967BEB31E27D5BE00A129E2 /* libiconv.tbd in Frameworks */, - 8A08CAA722DCAEB600B1CE11 /* libX2tConverter.a in Frameworks */, - 8AFA661922DE15A900D70E48 /* PPTXFormatLib.framework in Frameworks */, - 8AFA661722DE15A000D70E48 /* DocxFormatLib.framework in Frameworks */, - 8A08CAB022DCC8F800B1CE11 /* icu.framework in Frameworks */, - 8A08CAB222DCD88600B1CE11 /* ASCOfficeDocxFile2Lib.framework in Frameworks */, - 8A08CAAE22DCBF7300B1CE11 /* RtfFormatLib.framework in Frameworks */, - 8A08CAAC22DCBF7000B1CE11 /* OfficeCryptReader.framework in Frameworks */, - 8AC4E6EF22058B2A0044119A /* boost.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 17C1FB191ACC3E3B006B99B3 /* SDK */ = { - isa = PBXGroup; - children = ( - 8A9FAD36207781C5007787F6 /* OfficeFileErrorDescription.h */, - 6905975F1CA137D000000D4D /* X2tConverter.h */, - ); - name = SDK; - sourceTree = ""; - }; - 17DAB66F1ACC371E005AF479 = { - isa = PBXGroup; - children = ( - 8A08CA4D22DCACCB00B1CE11 /* X2tConverter.xcodeproj */, - 17DAB67A1ACC371E005AF479 /* iosTest */, - 17DAB6791ACC371E005AF479 /* Products */, - 6967BEB11E27D5BE00A129E2 /* Frameworks */, - ); - sourceTree = ""; - }; - 17DAB6791ACC371E005AF479 /* Products */ = { - isa = PBXGroup; - children = ( - 17DAB6781ACC371E005AF479 /* iosTest.app */, - ); - name = Products; - sourceTree = ""; - }; - 17DAB67A1ACC371E005AF479 /* iosTest */ = { - isa = PBXGroup; - children = ( - 17C1FB191ACC3E3B006B99B3 /* SDK */, - 17DAB70A1ACC3B58005AF479 /* Files */, - 17DAB67F1ACC371E005AF479 /* AppDelegate.h */, - 17DAB6801ACC371E005AF479 /* AppDelegate.m */, - 17DAB6821ACC371E005AF479 /* ViewController.h */, - 17DAB6831ACC371E005AF479 /* ViewController.m */, - 17DAB6851ACC371F005AF479 /* Main.storyboard */, - 17DAB6881ACC371F005AF479 /* Images.xcassets */, - 17DAB68A1ACC371F005AF479 /* LaunchScreen.xib */, - 17DAB67B1ACC371E005AF479 /* Supporting Files */, - ); - name = iosTest; - path = TestIOSX2tConverter; - sourceTree = ""; - }; - 17DAB67B1ACC371E005AF479 /* Supporting Files */ = { - isa = PBXGroup; - children = ( - 17DAB67C1ACC371E005AF479 /* Info.plist */, - 17DAB67D1ACC371E005AF479 /* main.m */, - ); - name = "Supporting Files"; - sourceTree = ""; - }; - 17DAB70A1ACC3B58005AF479 /* Files */ = { - isa = PBXGroup; - children = ( - 17DAB70D1ACC3B90005AF479 /* demo.docx */, - 8AC4E7272205A4D10044119A /* demo.pptx */, - 69BE370B1F60129600CBA47B /* crypted.xlsx */, - 177B1B461B5FCD34001FC26F /* shapes.xlsx */, - 1773201E1B4FB9B700BB22FC /* price.xlsx */, - 1734C9A51B4C251D00C2A6C8 /* smeta.xlsx */, - 697CDFE72049649800C2638C /* empty.docx */, - 697CDFE92049649800C2638C /* empty.xlsx */, - 8A94F3C9207CE7D600EC05D2 /* test.csv */, - 8AC4E6F42205999B0044119A /* test.odp */, - 8AC4E6F32205999B0044119A /* test.ods */, - 8AC4E6F22205999B0044119A /* test.odt */, - 8A2851F6220B29A800779A38 /* test.txt */, - ); - name = Files; - sourceTree = ""; - }; - 6967BEB11E27D5BE00A129E2 /* Frameworks */ = { - isa = PBXGroup; - children = ( - 8AFA661822DE15A900D70E48 /* PPTXFormatLib.framework */, - 8AFA661522DE15A000D70E48 /* DocxFormatLib.framework */, - 8A08CAB122DCD88600B1CE11 /* ASCOfficeDocxFile2Lib.framework */, - 8A08CAAF22DCC8F800B1CE11 /* icu.framework */, - 8A08CAAD22DCBF7300B1CE11 /* RtfFormatLib.framework */, - 8A08CAAB22DCBF7000B1CE11 /* OfficeCryptReader.framework */, - 8AC4E6EE22058B290044119A /* boost.framework */, - 8AED79AA20F50164008BB78E /* libicui18n.a */, - 8AED79AC20F50164008BB78E /* libicuio.a */, - 8AED79AD20F50164008BB78E /* libicutu.a */, - 8AED79AE20F50164008BB78E /* libicuuc.a */, - 8A1045C420F4B55E005A0F61 /* libicudata.58.dylib */, - 8A1045C520F4B55F005A0F61 /* libicuuc.58.dylib */, - 698810C41F4DA87A00E4C541 /* libcryptopp.a */, - 699690721E2F925200B620CD /* libc++abi.tbd */, - 6967BEB21E27D5BE00A129E2 /* libiconv.tbd */, - ); - name = Frameworks; - sourceTree = ""; - }; - 8A08CA4E22DCACCB00B1CE11 /* Products */ = { - isa = PBXGroup; - children = ( - 8A08CA6D22DCACCC00B1CE11 /* libX2tConverter.a */, - ); - name = Products; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 17DAB6771ACC371E005AF479 /* iosTest */ = { - isa = PBXNativeTarget; - buildConfigurationList = 17DAB69B1ACC371F005AF479 /* Build configuration list for PBXNativeTarget "iosTest" */; - buildPhases = ( - 17DAB6741ACC371E005AF479 /* Sources */, - 17DAB6751ACC371E005AF479 /* Frameworks */, - 17DAB6761ACC371E005AF479 /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - 8A08CA6F22DCACD700B1CE11 /* PBXTargetDependency */, - ); - name = iosTest; - productName = TestIOSX2tConverter; - productReference = 17DAB6781ACC371E005AF479 /* iosTest.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 17DAB6701ACC371E005AF479 /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 0930; - ORGANIZATIONNAME = "Ascensio System SIA"; - TargetAttributes = { - 17DAB6771ACC371E005AF479 = { - CreatedOnToolsVersion = 6.2; - DevelopmentTeam = 2WH24U26GJ; - ProvisioningStyle = Automatic; - }; - }; - }; - buildConfigurationList = 17DAB6731ACC371E005AF479 /* Build configuration list for PBXProject "iosTest2" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 0; - knownRegions = ( - English, - en, - Base, - ); - mainGroup = 17DAB66F1ACC371E005AF479; - productRefGroup = 17DAB6791ACC371E005AF479 /* Products */; - projectDirPath = ""; - projectReferences = ( - { - ProductGroup = 8A08CA4E22DCACCB00B1CE11 /* Products */; - ProjectRef = 8A08CA4D22DCACCB00B1CE11 /* X2tConverter.xcodeproj */; - }, - ); - projectRoot = ""; - targets = ( - 17DAB6771ACC371E005AF479 /* iosTest */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXReferenceProxy section */ - 8A08CA6D22DCACCC00B1CE11 /* libX2tConverter.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libX2tConverter.a; - remoteRef = 8A08CA6C22DCACCC00B1CE11 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; -/* End PBXReferenceProxy section */ - -/* Begin PBXResourcesBuildPhase section */ - 17DAB6761ACC371E005AF479 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 8A94F3CB207CE7D600EC05D2 /* test.csv in Resources */, - 8AC4E6F72205999B0044119A /* test.odp in Resources */, - 8AC4E6F52205999B0044119A /* test.odt in Resources */, - 69BE370C1F60129600CBA47B /* crypted.xlsx in Resources */, - 17DAB6871ACC371F005AF479 /* Main.storyboard in Resources */, - 17DAB68C1ACC371F005AF479 /* LaunchScreen.xib in Resources */, - 8A2851F8220B29A800779A38 /* test.txt in Resources */, - 8AC4E7282205A4D10044119A /* demo.pptx in Resources */, - 17DAB6891ACC371F005AF479 /* Images.xcassets in Resources */, - 697CDFEA2049649800C2638C /* empty.docx in Resources */, - 1734C9A61B4C251D00C2A6C8 /* smeta.xlsx in Resources */, - 697CDFEB2049649800C2638C /* empty.xlsx in Resources */, - 177B1B471B5FCD34001FC26F /* shapes.xlsx in Resources */, - 8AC4E6F62205999B0044119A /* test.ods in Resources */, - 1773201F1B4FB9B700BB22FC /* price.xlsx in Resources */, - 17DAB70E1ACC3B96005AF479 /* demo.docx in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 17DAB6741ACC371E005AF479 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 17DAB6841ACC371E005AF479 /* ViewController.m in Sources */, - 17DAB6811ACC371E005AF479 /* AppDelegate.m in Sources */, - 17DAB67E1ACC371E005AF479 /* main.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXTargetDependency section */ - 8A08CA6F22DCACD700B1CE11 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = x2tconverter; - targetProxy = 8A08CA6E22DCACD700B1CE11 /* PBXContainerItemProxy */; - }; -/* End PBXTargetDependency section */ - -/* Begin PBXVariantGroup section */ - 17DAB6851ACC371F005AF479 /* Main.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 17DAB6861ACC371F005AF479 /* Base */, - ); - name = Main.storyboard; - sourceTree = ""; - }; - 17DAB68A1ACC371F005AF479 /* LaunchScreen.xib */ = { - isa = PBXVariantGroup; - children = ( - 17DAB68B1ACC371F005AF479 /* Base */, - ); - name = LaunchScreen.xib; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - 17DAB6991ACC371F005AF479 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_SYMBOLS_PRIVATE_EXTERN = NO; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 10.0; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - OTHER_LDFLAGS = ( - "-ObjC", - "-lstdc++", - "-lz", - ); - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - 17DAB69A1ACC371F005AF479 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 10.0; - MTL_ENABLE_DEBUG_INFO = NO; - OTHER_LDFLAGS = ( - "-ObjC", - "-lstdc++", - "-lz", - ); - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - 17DAB69C1ACC371F005AF479 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CLANG_CXX_LANGUAGE_STANDARD = "compiler-default"; - CLANG_CXX_LIBRARY = "compiler-default"; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - DEVELOPMENT_TEAM = 2WH24U26GJ; - ENABLE_BITCODE = YES; - FRAMEWORK_SEARCH_PATHS = "$(PROJECT_DIR)/../../../Common/3dParty/boost/ios/framework"; - INFOPLIST_FILE = TestIOSX2tConverter/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 10.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - OTHER_CFLAGS = ""; - OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)"; - OTHER_LDFLAGS = ( - "-lstdc++", - "-lxml2", - "-lz", - "-lc++", - ); - PRODUCT_BUNDLE_IDENTIFIER = "com.onlyoffice.$(PRODUCT_NAME:rfc1034identifier)"; - PRODUCT_NAME = iosTest; - }; - name = Debug; - }; - 17DAB69D1ACC371F005AF479 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CLANG_CXX_LANGUAGE_STANDARD = "compiler-default"; - CLANG_CXX_LIBRARY = "compiler-default"; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - DEVELOPMENT_TEAM = 2WH24U26GJ; - ENABLE_BITCODE = YES; - FRAMEWORK_SEARCH_PATHS = "$(PROJECT_DIR)/../../../Common/3dParty/boost/ios/framework"; - INFOPLIST_FILE = TestIOSX2tConverter/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 10.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - OTHER_CFLAGS = ""; - OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)"; - OTHER_LDFLAGS = ( - "-lstdc++", - "-lxml2", - "-lz", - "-lc++", - ); - PRODUCT_BUNDLE_IDENTIFIER = "com.onlyoffice.$(PRODUCT_NAME:rfc1034identifier)"; - PRODUCT_NAME = iosTest; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 17DAB6731ACC371E005AF479 /* Build configuration list for PBXProject "iosTest2" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 17DAB6991ACC371F005AF479 /* Debug */, - 17DAB69A1ACC371F005AF479 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 17DAB69B1ACC371F005AF479 /* Build configuration list for PBXNativeTarget "iosTest" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 17DAB69C1ACC371F005AF479 /* Debug */, - 17DAB69D1ACC371F005AF479 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 17DAB6701ACC371E005AF479 /* Project object */; -} diff --git a/X2tConverter/test/iosTest/iosTest.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/X2tConverter/test/iosTest/iosTest.xcodeproj/project.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 60c25ad0164..00000000000 --- a/X2tConverter/test/iosTest/iosTest.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/X2tConverter/test/iosTest/iosTest.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/X2tConverter/test/iosTest/iosTest.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist deleted file mode 100644 index 18d981003d6..00000000000 --- a/X2tConverter/test/iosTest/iosTest.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +++ /dev/null @@ -1,8 +0,0 @@ - - - - - IDEDidComputeMac32BitWarning - - - diff --git a/X2tConverter/test/iosTest/iosTest.xcodeproj/xcshareddata/xcschemes/iosTest 2.xcscheme b/X2tConverter/test/iosTest/iosTest.xcodeproj/xcshareddata/xcschemes/iosTest 2.xcscheme deleted file mode 100644 index ec75ad5f984..00000000000 --- a/X2tConverter/test/iosTest/iosTest.xcodeproj/xcshareddata/xcschemes/iosTest 2.xcscheme +++ /dev/null @@ -1,91 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/X2tConverter/test/iosTest/iosTest.xcodeproj/xcshareddata/xcschemes/iosTest.xcscheme b/X2tConverter/test/iosTest/iosTest.xcodeproj/xcshareddata/xcschemes/iosTest.xcscheme deleted file mode 100644 index 69780743832..00000000000 --- a/X2tConverter/test/iosTest/iosTest.xcodeproj/xcshareddata/xcschemes/iosTest.xcscheme +++ /dev/null @@ -1,91 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/X2tConverter/test/qmake/main.cpp b/X2tConverter/test/qmake/main.cpp new file mode 100644 index 00000000000..c1ff84e9877 --- /dev/null +++ b/X2tConverter/test/qmake/main.cpp @@ -0,0 +1,177 @@ +#include "../../../DesktopEditor/common/Directory.h" +#include "../../../DesktopEditor/common/StringBuilder.h" +#include "../../../DesktopEditor/fontengine/ApplicationFontsWorker.h" +#include "../../../Common/OfficeFileFormatChecker.h" +#include "../../src/dylib/x2t.h" + +void CheckFonts(const std::wstring& fontsDir, bool isUseSystem = true, const std::vector& addtitionalFontsDirs = {}) +{ + CApplicationFontsWorker fonts_worker; + + fonts_worker.m_sDirectory = fontsDir; + if (!NSDirectory::Exists(fonts_worker.m_sDirectory)) + NSDirectory::CreateDirectory(fonts_worker.m_sDirectory); + + fonts_worker.m_bIsUseSystemFonts = isUseSystem; + + for (const auto& additional : addtitionalFontsDirs) + { + std::wstring sFolder = additional; + if (0 == sFolder.find(L".")) + sFolder = NSFile::GetProcessDirectory() + FILE_SEPARATOR_STR + sFolder; + fonts_worker.m_arAdditionalFolders.push_back(sFolder); + } + + fonts_worker.m_bIsNeedThumbnails = false; + NSFonts::IApplicationFonts* pFonts = fonts_worker.Check(); + RELEASEINTERFACE(pFonts); +} + +#define UNUSED_PARAM(x) (void)x + +int main(int argc, char** argv) +{ + // warnings + UNUSED_PARAM(argc); + UNUSED_PARAM(argv); + + std::wstring curr_dir = NSFile::GetProcessDirectory(); + std::wstring wsep = FILE_SEPARATOR_STR; + + std::wstring filename_in = curr_dir + wsep + L"123.docx"; + std::wstring filename_out = curr_dir + wsep + L"123.pdf"; + std::wstring fonts_dir = curr_dir + wsep + L"fonts"; + std::wstring xml = curr_dir + wsep + L"params.xml"; + + std::wstring tmp_dir = NSDirectory::CreateDirectoryWithUniqueName(curr_dir); + + CheckFonts(fonts_dir); + + // GENERATE XML + NSStringUtils::CStringBuilder oBuilder; + + oBuilder.WriteString(L""); + oBuilder.WriteString(L""); + + // main + oBuilder.WriteString(L""); + oBuilder.WriteEncodeXmlString(filename_in); + oBuilder.WriteString(L""); + + oBuilder.WriteString(L""); + oBuilder.WriteEncodeXmlString(filename_out); + oBuilder.WriteString(L""); + + oBuilder.WriteString(L""); + int nFormat = COfficeFileFormatChecker::GetFormatByExtension(L"." + NSFile::GetFileExtention(filename_out)); + oBuilder.WriteString(std::to_wstring(nFormat)); + oBuilder.WriteString(L""); + + if (nFormat == AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_PDFA) + oBuilder.WriteString(L"true"); + + oBuilder.WriteString(L""); + oBuilder.WriteEncodeXmlString(curr_dir + L"/sdkjs/slide/themes"); + oBuilder.WriteString(L""); + + // changes + oBuilder.WriteString(L"false"); + + oBuilder.WriteString(L"true"); + + // fonts + oBuilder.WriteString(L""); + oBuilder.WriteEncodeXmlString(fonts_dir); + oBuilder.WriteString(L""); + + oBuilder.WriteString(L""); + oBuilder.WriteString(fonts_dir + L"/AllFonts.js"); + oBuilder.WriteString(L""); + + // temp directory + oBuilder.WriteString(L""); + oBuilder.WriteEncodeXmlString(tmp_dir); + oBuilder.WriteString(L""); + + // encrypt + if (false) + { + oBuilder.WriteString(L""); + oBuilder.WriteEncodeXmlString(L"111"); + oBuilder.WriteString(L""); + + oBuilder.WriteString(L""); + oBuilder.WriteEncodeXmlString(L"222"); + oBuilder.WriteString(L""); + } + + // docinfo (private rooms) + if (false) + { + oBuilder.WriteString(L""); + oBuilder.WriteEncodeXmlString(L"{data}"); + oBuilder.WriteString(L""); + } + + // txt/csv + oBuilder.WriteString(L""); + oBuilder.WriteEncodeXmlString(L"46"); + oBuilder.WriteString(L""); + + oBuilder.WriteString(L""); + oBuilder.WriteEncodeXmlString(L"4"); + oBuilder.WriteString(L""); + + // js params + if (false) + { + oBuilder.WriteString(L""); + oBuilder.WriteString(L"{"); + // * + oBuilder.WriteString(L"}"); + oBuilder.WriteString(L""); + } + + if (false) + { + // if need disable js engine cache + oBuilder.WriteString(L"1"); + } + + // images + if (true && (0 != (nFormat & AVS_OFFICESTUDIO_FILE_IMAGE))) + { + oBuilder.WriteString(L"false"); + + if (nFormat == AVS_OFFICESTUDIO_FILE_IMAGE_JPG) + oBuilder.WriteString(L"3"); + + oBuilder.WriteString(L""); + } + + oBuilder.WriteString(L""); + + // writing xml data into file + if(NSFile::CFileBinary::Exists(xml)) + NSFile::CFileBinary::Remove(xml); + + NSFile::CFileBinary xml_file; + xml_file.CreateFile(xml); + xml_file.WriteStringUTF8(oBuilder.GetData()); + xml_file.CloseFile(); + +#if !defined(_WIN32) && !defined (_WIN64) + std::string xmlDst = U_TO_UTF8(xml); +#else + std::wstring xmlDst = xml; +#endif + + x2tchar* args[2]; + args[0] = NULL; + args[1] = (x2tchar*)xmlDst.c_str(); + + int nResultCode = X2T_Convert(2, args); + NSDirectory::DeleteDirectory(tmp_dir); + + return nResultCode; +} diff --git a/X2tConverter/test/qmake/prepare.py b/X2tConverter/test/qmake/prepare.py new file mode 100644 index 00000000000..386a874a73b --- /dev/null +++ b/X2tConverter/test/qmake/prepare.py @@ -0,0 +1,39 @@ +#!/usr/bin/env python + +import sys +sys.path.append('../../../../build_tools/scripts') +import config +import base +import build_js + +platform_postfix = "" +platform = base.host_platform() + +if platform == "windows": + platform_postfix = "win_64" +elif platform == "mac": + platform_postfix = "mac_64" +else: + platform_postfix = "linux_64" + +x2t_build_dir = "../../../build/bin/" + platform_postfix + "/debug" + +config.parse() +build_js.build_sdk_builder("../../../../sdkjs/build") + +if base.is_dir(x2t_build_dir + "/sdkjs"): + base.delete_dir(x2t_build_dir + "/sdkjs") + +base.copy_dir("../../../../sdkjs/deploy/sdkjs", x2t_build_dir + "/sdkjs") +base.create_dir(x2t_build_dir + "/sdkjs/vendor") +base.copy_dir("../../../../web-apps/vendor/jquery", x2t_build_dir + "/sdkjs/vendor/jquery") +base.copy_dir("../../../../web-apps/vendor/xregexp", x2t_build_dir + "/sdkjs/vendor/xregexp") + +# for hyphen support in convertation to images/pdf +base.copy_dictionaries("../../../../dictionaries", x2t_build_dir + "/dictionaries", True, False) + +# for pdf=>image/docx convertation +base.copy_file("../../../../sdkjs/pdf/src/engine/cmap.bin", x2t_build_dir + "/cmap.bin") + +# DoctRenderer.config +base.generate_doctrenderer_config(x2t_build_dir + "/DoctRenderer.config", "./", "builder", "", "./dictionaries") diff --git a/X2tConverter/test/qmake/test.pro b/X2tConverter/test/qmake/test.pro new file mode 100644 index 00000000000..d69cfe9b544 --- /dev/null +++ b/X2tConverter/test/qmake/test.pro @@ -0,0 +1,16 @@ +TEMPLATE = app +CONFIG += console +CONFIG -= app_bundle + +DEFINES += BUILD_X2T_AS_LIBRARY_DYLIB + +X2T_DIR = $$PWD/../.. + +include($$X2T_DIR/build/Qt/X2tConverter.pri) + +HEADERS += $$X2T_DIR/src/dylib/x2t.h +SOURCES += $$X2T_DIR/src/dylib/x2t.cpp + +SOURCES += main.cpp + +DESTDIR = $$CORE_BUILDS_BINARY_PATH diff --git a/X2tConverter/test/win32Test/X2tConverter_win_test.sln b/X2tConverter/test/win32Test/X2tConverter_win_test.sln index 3c1f5659759..c59cbaa4208 100644 --- a/X2tConverter/test/win32Test/X2tConverter_win_test.sln +++ b/X2tConverter/test/win32Test/X2tConverter_win_test.sln @@ -7,9 +7,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "X2tTest", "X2tTest.vcxproj" ProjectSection(ProjectDependencies) = postProject {41BED424-4EAF-4053-8A5F-1E2A387D53D1} = {41BED424-4EAF-4053-8A5F-1E2A387D53D1} {609ED938-3CA8-4BED-B363-25096D4C4812} = {609ED938-3CA8-4BED-B363-25096D4C4812} - {C39F4B46-6E89-4074-902E-CA57073044D2} = {C39F4B46-6E89-4074-902E-CA57073044D2} {94954A67-A853-43B1-A727-6EF2774C5A6A} = {94954A67-A853-43B1-A727-6EF2774C5A6A} - {C27E9A9F-3A17-4482-9C5F-BF15C01E747C} = {C27E9A9F-3A17-4482-9C5F-BF15C01E747C} {FA22BAB4-E93E-459D-8A5F-16764FBBED40} = {FA22BAB4-E93E-459D-8A5F-16764FBBED40} {DACBE6CA-E089-47D1-8CE7-C7DB59C15417} = {DACBE6CA-E089-47D1-8CE7-C7DB59C15417} EndProjectSection @@ -43,10 +41,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OdfFormatWriterLib", "..\.. EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Oox2OdfConverter", "..\..\..\OdfFile\Projects\Windows\Oox2OdfConverter.vcxproj", "{BEE01B53-244A-44E6-8947-ED9342D9247E}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cryptlib", "..\..\..\Common\3dParty\cryptopp\vs2019\cryptlib.vcxproj", "{C39F4B46-6E89-4074-902E-CA57073044D2}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OfficeFileCrypt", "..\..\..\OfficeCryptReader\win32\ECMACryptReader.vcxproj", "{C27E9A9F-3A17-4482-9C5F-BF15C01E747C}" -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OdfCommon", "..\..\..\OdfFile\Projects\Windows\cpcommon.vcxproj", "{609ED938-3CA8-4BED-B363-25096D4C4812}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xml_wrapper", "..\..\..\OdfFile\Projects\Windows\cpxml.vcxproj", "{41BED424-4EAF-4053-8A5F-1E2A387D53D1}" @@ -350,46 +344,6 @@ Global {BEE01B53-244A-44E6-8947-ED9342D9247E}.ReleaseOpenSource|Win32.Build.0 = Release|Win32 {BEE01B53-244A-44E6-8947-ED9342D9247E}.ReleaseOpenSource|x64.ActiveCfg = Release|x64 {BEE01B53-244A-44E6-8947-ED9342D9247E}.ReleaseOpenSource|x64.Build.0 = Release|x64 - {C39F4B46-6E89-4074-902E-CA57073044D2}.Debug|Win32.ActiveCfg = Debug|Win32 - {C39F4B46-6E89-4074-902E-CA57073044D2}.Debug|Win32.Build.0 = Debug|Win32 - {C39F4B46-6E89-4074-902E-CA57073044D2}.Debug|x64.ActiveCfg = Debug|x64 - {C39F4B46-6E89-4074-902E-CA57073044D2}.Debug|x64.Build.0 = Debug|x64 - {C39F4B46-6E89-4074-902E-CA57073044D2}.DLL-Import Debug|Win32.ActiveCfg = DLL-Import Debug|Win32 - {C39F4B46-6E89-4074-902E-CA57073044D2}.DLL-Import Debug|Win32.Build.0 = DLL-Import Debug|Win32 - {C39F4B46-6E89-4074-902E-CA57073044D2}.DLL-Import Debug|x64.ActiveCfg = DLL-Import Debug|x64 - {C39F4B46-6E89-4074-902E-CA57073044D2}.DLL-Import Debug|x64.Build.0 = DLL-Import Debug|x64 - {C39F4B46-6E89-4074-902E-CA57073044D2}.DLL-Import Release|Win32.ActiveCfg = DLL-Import Release|Win32 - {C39F4B46-6E89-4074-902E-CA57073044D2}.DLL-Import Release|Win32.Build.0 = DLL-Import Release|Win32 - {C39F4B46-6E89-4074-902E-CA57073044D2}.DLL-Import Release|x64.ActiveCfg = DLL-Import Release|x64 - {C39F4B46-6E89-4074-902E-CA57073044D2}.DLL-Import Release|x64.Build.0 = DLL-Import Release|x64 - {C39F4B46-6E89-4074-902E-CA57073044D2}.Release|Win32.ActiveCfg = Release|Win32 - {C39F4B46-6E89-4074-902E-CA57073044D2}.Release|Win32.Build.0 = Release|Win32 - {C39F4B46-6E89-4074-902E-CA57073044D2}.Release|x64.ActiveCfg = Release|x64 - {C39F4B46-6E89-4074-902E-CA57073044D2}.Release|x64.Build.0 = Release|x64 - {C39F4B46-6E89-4074-902E-CA57073044D2}.ReleaseOpenSource|Win32.ActiveCfg = Release|Win32 - {C39F4B46-6E89-4074-902E-CA57073044D2}.ReleaseOpenSource|Win32.Build.0 = Release|Win32 - {C39F4B46-6E89-4074-902E-CA57073044D2}.ReleaseOpenSource|x64.ActiveCfg = Release|x64 - {C39F4B46-6E89-4074-902E-CA57073044D2}.ReleaseOpenSource|x64.Build.0 = Release|x64 - {C27E9A9F-3A17-4482-9C5F-BF15C01E747C}.Debug|Win32.ActiveCfg = Debug|Win32 - {C27E9A9F-3A17-4482-9C5F-BF15C01E747C}.Debug|Win32.Build.0 = Debug|Win32 - {C27E9A9F-3A17-4482-9C5F-BF15C01E747C}.Debug|x64.ActiveCfg = Debug|x64 - {C27E9A9F-3A17-4482-9C5F-BF15C01E747C}.Debug|x64.Build.0 = Debug|x64 - {C27E9A9F-3A17-4482-9C5F-BF15C01E747C}.DLL-Import Debug|Win32.ActiveCfg = Debug|Win32 - {C27E9A9F-3A17-4482-9C5F-BF15C01E747C}.DLL-Import Debug|Win32.Build.0 = Debug|Win32 - {C27E9A9F-3A17-4482-9C5F-BF15C01E747C}.DLL-Import Debug|x64.ActiveCfg = Debug|x64 - {C27E9A9F-3A17-4482-9C5F-BF15C01E747C}.DLL-Import Debug|x64.Build.0 = Debug|x64 - {C27E9A9F-3A17-4482-9C5F-BF15C01E747C}.DLL-Import Release|Win32.ActiveCfg = Release|Win32 - {C27E9A9F-3A17-4482-9C5F-BF15C01E747C}.DLL-Import Release|Win32.Build.0 = Release|Win32 - {C27E9A9F-3A17-4482-9C5F-BF15C01E747C}.DLL-Import Release|x64.ActiveCfg = Release|x64 - {C27E9A9F-3A17-4482-9C5F-BF15C01E747C}.DLL-Import Release|x64.Build.0 = Release|x64 - {C27E9A9F-3A17-4482-9C5F-BF15C01E747C}.Release|Win32.ActiveCfg = Release|Win32 - {C27E9A9F-3A17-4482-9C5F-BF15C01E747C}.Release|Win32.Build.0 = Release|Win32 - {C27E9A9F-3A17-4482-9C5F-BF15C01E747C}.Release|x64.ActiveCfg = Release|x64 - {C27E9A9F-3A17-4482-9C5F-BF15C01E747C}.Release|x64.Build.0 = Release|x64 - {C27E9A9F-3A17-4482-9C5F-BF15C01E747C}.ReleaseOpenSource|Win32.ActiveCfg = Release|Win32 - {C27E9A9F-3A17-4482-9C5F-BF15C01E747C}.ReleaseOpenSource|Win32.Build.0 = Release|Win32 - {C27E9A9F-3A17-4482-9C5F-BF15C01E747C}.ReleaseOpenSource|x64.ActiveCfg = Release|x64 - {C27E9A9F-3A17-4482-9C5F-BF15C01E747C}.ReleaseOpenSource|x64.Build.0 = Release|x64 {609ED938-3CA8-4BED-B363-25096D4C4812}.Debug|Win32.ActiveCfg = Debug|Win32 {609ED938-3CA8-4BED-B363-25096D4C4812}.Debug|Win32.Build.0 = Debug|Win32 {609ED938-3CA8-4BED-B363-25096D4C4812}.Debug|x64.ActiveCfg = Debug|x64 diff --git a/X2tConverter/test/win32Test/X2tTest.cpp b/X2tConverter/test/win32Test/X2tTest.cpp index 132efa395b5..81cbfb02f29 100644 --- a/X2tConverter/test/win32Test/X2tTest.cpp +++ b/X2tConverter/test/win32Test/X2tTest.cpp @@ -33,7 +33,6 @@ #if defined(_WIN64) #if defined(_DEBUG) #pragma comment(lib, "../../../build/lib/win_64/DEBUG/doctrenderer.lib") - #pragma comment(lib, "../../../build/lib/win_64/DEBUG/HtmlRenderer.lib") #pragma comment(lib, "../../../build/lib/win_64/DEBUG/DocxRenderer.lib") #pragma comment(lib, "../../../build/lib/win_64/DEBUG/PdfFile.lib") #pragma comment(lib, "../../../build/lib/win_64/DEBUG/XpsFile.lib") @@ -42,12 +41,14 @@ #pragma comment(lib, "../../../build/lib/win_64/DEBUG/Fb2File.lib") #pragma comment(lib, "../../../build/lib/win_64/DEBUG/HtmlFile2.lib") #pragma comment(lib, "../../../build/lib/win_64/DEBUG/graphics.lib") + #pragma comment(lib, "../../../build/lib/win_64/DEBUG/IWorkFile.lib") + #pragma comment(lib, "../../../build/lib/win_64/DEBUG/HWPFile.lib") #pragma comment(lib, "../../../build/lib/win_64/DEBUG/kernel_network.lib") #pragma comment(lib, "../../../build/lib/win_64/DEBUG/kernel.lib") #pragma comment(lib, "../../../build/lib/win_64/DEBUG/UnicodeConverter.lib") - #else + #pragma comment(lib, "../../../build/lib/win_64/DEBUG/CryptoPPLib.lib") +#else #pragma comment(lib, "../../../build/lib/win_64/doctrenderer.lib") - #pragma comment(lib, "../../../build/lib/win_64/HtmlRenderer.lib") #pragma comment(lib, "../../../build/lib/win_64/PdfFile.lib") #pragma comment(lib, "../../../build/lib/win_64/XpsFile.lib") #pragma comment(lib, "../../../build/lib/win_64/EpubFile.lib") @@ -55,15 +56,17 @@ #pragma comment(lib, "../../../build/lib/win_64/Fb2File.lib") #pragma comment(lib, "../../../build/lib/win_64/HtmlFile2.lib") #pragma comment(lib, "../../../build/lib/win_64/graphics.lib") + #pragma comment(lib, "../../../build/lib/win_64/IWorkFile.lib") + #pragma comment(lib, "../../../build/lib/win_64/HWPFile.lib") #pragma comment(lib, "../../../build/lib/win_64/kernel_network.lib") #pragma comment(lib, "../../../build/lib/win_64/kernel.lib") #pragma comment(lib, "../../../build/lib/win_64/UnicodeConverter.lib") - #endif + #pragma comment(lib, "../../../build/lib/win_64/CryptoPPLib.lib") +#endif #pragma comment(lib, "../../../Common/3dParty/icu/win_64/build//icuuc.lib") #elif defined (_WIN32) #if defined(_DEBUG) #pragma comment(lib, "../../../build/lib/win_32/DEBUG/doctrenderer.lib") - #pragma comment(lib, "../../../build/lib/win_32/DEBUG/HtmlRenderer.lib") #pragma comment(lib, "../../../build/lib/win_32/DEBUG/DocxRenderer.lib") #pragma comment(lib, "../../../build/lib/win_32/DEBUG/PdfFile.lib") #pragma comment(lib, "../../../build/lib/win_32/DEBUG/XpsFile.lib") @@ -72,12 +75,14 @@ #pragma comment(lib, "../../../build/lib/win_32/DEBUG/Fb2File.lib") #pragma comment(lib, "../../../build/lib/win_32/DEBUG/HtmlFile2.lib") #pragma comment(lib, "../../../build/lib/win_32/DEBUG/graphics.lib") + #pragma comment(lib, "../../../build/lib/win_32/DEBUG/IWorkFile.lib") + #pragma comment(lib, "../../../build/lib/win_32/DEBUG/HWPFile.lib") #pragma comment(lib, "../../../build/lib/win_32/DEBUG/kernel.lib") #pragma comment(lib, "../../../build/lib/win_32/DEBUG/kernel_network.lib") #pragma comment(lib, "../../../build/lib/win_32/DEBUG/UnicodeConverter.lib") - #else + #pragma comment(lib, "../../../build/lib/win_32/DEBUG/CryptoPPLib.lib") +#else #pragma comment(lib, "../../../build/lib/win_32/doctrenderer.lib") - #pragma comment(lib, "../../../build/lib/win_32/HtmlRenderer.lib") #pragma comment(lib, "../../../build/lib/win_32/DocxRenderer.lib") #pragma comment(lib, "../../../build/lib/win_32/PdfFile.lib") #pragma comment(lib, "../../../build/lib/win_32/XpsFile.lib") @@ -86,10 +91,13 @@ #pragma comment(lib, "../../../build/lib/win_32/Fb2File.lib") #pragma comment(lib, "../../../build/lib/win_32/HtmlFile2.lib") #pragma comment(lib, "../../../build/lib/win_32/graphics.lib") + #pragma comment(lib, "../../../build/lib/win_32/IWorkFile.lib") + #pragma comment(lib, "../../../build/lib/win_32/HWPFile.lib") #pragma comment(lib, "../../../build/lib/win_32/kernel_network.lib") #pragma comment(lib, "../../../build/lib/win_32/kernel.lib") #pragma comment(lib, "../../../build/lib/win_32/UnicodeConverter.lib") - #endif + #pragma comment(lib, "../../../build/lib/win_32/CryptoPPLib.lib") +#endif #pragma comment(lib, "../../../Common/3dParty/icu/win_32/build/icuuc.lib") #endif diff --git a/X2tConverter/test/win32Test/X2tTest.vcxproj b/X2tConverter/test/win32Test/X2tTest.vcxproj index ecb579f401d..e21180ad193 100644 --- a/X2tConverter/test/win32Test/X2tTest.vcxproj +++ b/X2tConverter/test/win32Test/X2tTest.vcxproj @@ -74,7 +74,7 @@ ..\..\..\Common\3dParty\boost\build\win_32\lib;$(LibraryPath) - $(Platform)\$(Configuration)\ + ../../../build/lib/win_64/debug/ $(Platform)\$(Configuration)\ true ..\..\..\Common\3dParty\boost\build\win_64\include;$(IncludePath) @@ -177,11 +177,25 @@ + + + + + + + + + + + + + + + + + - - {c39f4b46-6e89-4074-902e-ca57073044d2} - {fa22bab4-e93e-459d-8a5f-16764fbbed40} @@ -218,9 +232,6 @@ {bee01b53-244a-44e6-8947-ed9342d9247e} - - {c27e9a9f-3a17-4482-9c5f-bf15c01e747c} - {cd359215-e183-4ea7-b986-42868b10d8b8} diff --git a/X2tConverter/test/win32Test/X2tTest.vcxproj.filters b/X2tConverter/test/win32Test/X2tTest.vcxproj.filters index 715b0625d7b..4bf78a30290 100644 --- a/X2tConverter/test/win32Test/X2tTest.vcxproj.filters +++ b/X2tConverter/test/win32Test/X2tTest.vcxproj.filters @@ -10,5 +10,61 @@ + + libs + + + libs + + + libs + + + libs + + + libs + + + libs + + + libs + + + libs + + + libs + + + libs + + + libs + + + libs + + + libs + + + libs + + + libs + + + libs + + + libs + + + + + {2c5e76c3-256a-4744-9078-f69707be4d3b} + \ No newline at end of file diff --git a/XpsFile/XpsFile.cpp b/XpsFile/XpsFile.cpp index 3b994443834..74fd63145b7 100644 --- a/XpsFile/XpsFile.cpp +++ b/XpsFile/XpsFile.cpp @@ -173,7 +173,7 @@ void CXpsFile::GetPageInfo(int nPageIndex, double* pdWidth, double* pdHeight, do *pdDpiX = 25.4; *pdDpiY = 25.4; } -void CXpsFile::DrawPageOnRenderer(IRenderer* pRenderer, int nPageIndex, bool* pBreak) +void CXpsFile::DrawPageOnRenderer(IRenderer* pRenderer, int nPageIndex, bool* pBreak, COfficeDrawingPageParams* pParams) { if (!m_pInternal->m_pDocument) return; diff --git a/XpsFile/XpsFile.h b/XpsFile/XpsFile.h index abcddb48500..6268cf32eec 100644 --- a/XpsFile/XpsFile.h +++ b/XpsFile/XpsFile.h @@ -64,7 +64,7 @@ class XPS_DECL_EXPORT CXpsFile : public IOfficeDrawingFile virtual int GetPagesCount(); virtual void GetPageInfo(int nPageIndex, double* pdWidth, double* pdHeight, double* pdDpiX, double* pdDpiY); - virtual void DrawPageOnRenderer(IRenderer* pRenderer, int nPageIndex, bool* pBreak); + virtual void DrawPageOnRenderer(IRenderer* pRenderer, int nPageIndex, bool* pBreak, COfficeDrawingPageParams* pParams = NULL); virtual std::wstring GetInfo(); #ifndef DISABLE_PDF_CONVERTATION diff --git a/XpsFile/XpsFile.pro b/XpsFile/XpsFile.pro index 5c0d73ba937..d5527a06126 100644 --- a/XpsFile/XpsFile.pro +++ b/XpsFile/XpsFile.pro @@ -43,11 +43,3 @@ SOURCES += \ XpsLib/StaticResources.cpp \ XpsLib/Utils.cpp \ XpsLib/WString.cpp - -#CONFIG += build_viewer_module -build_viewer_module { - DEFINES += BUILDING_WASM_MODULE - - HEADERS += $$CORE_ROOT_DIR/HtmlRenderer/include/HTMLRendererText.h - SOURCES += $$CORE_ROOT_DIR/HtmlRenderer/src/HTMLRendererText.cpp -} diff --git a/XpsFile/XpsLib/FontList.h b/XpsFile/XpsLib/FontList.h index fc31b168412..d6d00021614 100644 --- a/XpsFile/XpsLib/FontList.h +++ b/XpsFile/XpsLib/FontList.h @@ -49,7 +49,6 @@ namespace XPS class CFontList { public: - CFontList() { m_oCS.InitializeCriticalSection(); @@ -62,7 +61,7 @@ namespace XPS { m_mList.clear(); } - void Check(const std::wstring& wsName, const std::wstring& wsFontPath, IFolder* pFolder) + void Check(const std::wstring& wsName, const std::wstring& wsFontPath, IFolder* pFolder) { m_oCS.Enter(); if (!Find(wsName)) @@ -72,57 +71,65 @@ namespace XPS unsigned char sKey[16]; GetFontKey(wsName, sKey); - // Нужно подменить первые 32 байта файла - if (IFolder::iftFolder == pFolder->getType()) - { - NSFile::CFileBinary oFile; - oFile.OpenFile(wsFontPath, true); - - unsigned char sFontData[32]; - DWORD dwBytesRead; - oFile.ReadFile(sFontData, 32, dwBytesRead); - - for (int nIndex = 0; nIndex < 32; nIndex++) - sFontData[nIndex] ^= sKey[nIndex % 16]; - - FILE* pFile = oFile.GetFileNative(); - if (pFile) - { - fseek(pFile, 0, SEEK_SET); - fwrite(sFontData, 1, 32, pFile); - } - - oFile.CloseFile(); - } - else if (IFolder::iftZip == pFolder->getType()) - { - IFolder::CBuffer* buffer = NULL; - pFolder->read(wsFontPath, buffer); - - if (buffer->Size >= 32) - { - unsigned char* sFontData = buffer->Buffer; - for (int nIndex = 0; nIndex < 32; nIndex++) - sFontData[nIndex] ^= sKey[nIndex % 16]; - } - - if (NSFonts::NSApplicationFontStream::GetGlobalMemoryStorage()) - NSFonts::NSApplicationFontStream::GetGlobalMemoryStorage()->Add(wsFontPath, buffer->Buffer, buffer->Size); - - RELEASEOBJECT(buffer); - } + // Нужно подменить первые 32 байта файла + if (IFolder::iftFolder == pFolder->getType()) + { + if (NSDirectory::Exists(wsFontPath)) + { + IFolder::CBuffer* buffer = NULL;; + pFolder->readFileWithChunks(wsFontPath, buffer); + if (buffer) + delete buffer; + } + + NSFile::CFileBinary oFile; + oFile.OpenFile(wsFontPath, true); + + unsigned char sFontData[32]; + DWORD dwBytesRead; + oFile.ReadFile(sFontData, 32, dwBytesRead); + + for (int nIndex = 0; nIndex < 32; nIndex++) + sFontData[nIndex] ^= sKey[nIndex % 16]; + + FILE* pFile = oFile.GetFileNative(); + if (pFile) + { + fseek(pFile, 0, SEEK_SET); + fwrite(sFontData, 1, 32, pFile); + } + + oFile.CloseFile(); + } + else if (IFolder::iftZip == pFolder->getType()) + { + IFolder::CBuffer* buffer = NULL; + pFolder->readFileWithChunks(wsFontPath, buffer); + + if (buffer->Size >= 32) + { + unsigned char* sFontData = buffer->Buffer; + for (int nIndex = 0; nIndex < 32; nIndex++) + sFontData[nIndex] ^= sKey[nIndex % 16]; + } + + if (NSFonts::NSApplicationFontStream::GetGlobalMemoryStorage()) + NSFonts::NSApplicationFontStream::GetGlobalMemoryStorage()->Add(wsFontPath, buffer->Buffer, buffer->Size); + + RELEASEOBJECT(buffer); + } } m_oCS.Leave(); } - int GetFontId(const std::wstring& wsName) + int GetFontId(const std::wstring& wsName) { std::vector::iterator oIter = std::find(m_mList.begin(), m_mList.end(), wsName); if (oIter != m_mList.end()) return std::distance(m_mList.begin(), oIter); return -1; } - private: + private: bool Find(const std::wstring& wsName) { std::vector::iterator oIter = std::find(m_mList.begin(), m_mList.end(), wsName); @@ -145,7 +152,7 @@ namespace XPS } } } - int GetIntegerFromHex(const std::wstring& wsString) + int GetIntegerFromHex(const std::wstring& wsString) { if (0 == wsString.size()) return 0; @@ -158,9 +165,8 @@ namespace XPS } private: - NSCriticalSection::CRITICAL_SECTION m_oCS; - std::vector m_mList; + std::vector m_mList; }; } diff --git a/XpsFile/XpsLib/StaticResources.cpp b/XpsFile/XpsLib/StaticResources.cpp index 21dd851fd14..0242e97704b 100644 --- a/XpsFile/XpsLib/StaticResources.cpp +++ b/XpsFile/XpsLib/StaticResources.cpp @@ -41,11 +41,11 @@ #endif #ifndef M_PI -#define M_PI 3.14159265358979323846 +#define M_PI 3.14159265358979323846 #endif #ifndef xpsUnitToMM -#define xpsUnitToMM(x) ((x) * 25.4 / 96) +#define xpsUnitToMM(x) ((x)*25.4 / 96) #endif namespace XPS @@ -92,7 +92,7 @@ namespace XPS { std::map::iterator oIter = m_mTransforms.find(wsKey); if (oIter != m_mTransforms.end()) - { + { wsTransform = oIter->second; return true; } @@ -108,17 +108,14 @@ namespace XPS { wsNodeName = oReader.GetNameNoNS(); if (wsNodeName == L"PathGeometry") - { + { CWString wsKey, wsValue, wsTrasform; - ReadPathGeometry(oReader, wsValue, wsTrasform, &wsKey); + ReadPathGeometry(oReader, wsValue, wsTrasform, &wsKey); if (!wsKey.empty() && !wsValue.empty()) AddFigure(wsKey, wsValue); } - else if (wsNodeName == L"SolidColorBrush" - || wsNodeName == L"ImageBrush" - || wsNodeName == L"LinearGradientBrush" - || wsNodeName == L"RadialGradientBrush") + else if (wsNodeName == L"SolidColorBrush" || wsNodeName == L"ImageBrush" || wsNodeName == L"LinearGradientBrush" || wsNodeName == L"RadialGradientBrush") { CWString wsKey; CBrush* pBrush = ReadBrushNode(oReader, 1.0, &wsKey); @@ -159,6 +156,15 @@ namespace XPS return false; std::wstring wsPath = m_wsPath.c_stdstr(); + + if (!m_wsRoot->exists(wsPath)) + { + IFolder::CBuffer* buffer = NULL;; + m_wsRoot->readFileWithChunks(wsPath, buffer); + if (buffer) + delete buffer; + } + if (!m_wsRoot->exists(wsPath)) { wsPath = m_wsPage.c_stdstr() + m_wsPath.c_stdstr(); @@ -167,13 +173,13 @@ namespace XPS } #ifndef BUILDING_WASM_MODULE - pRenderer->put_BrushType(c_BrushTypeTexture); - pRenderer->put_BrushTexturePath(m_wsRoot->getFullFilePath(wsPath)); - return true; + pRenderer->put_BrushType(c_BrushTypeTexture); + pRenderer->put_BrushTexturePath(m_wsRoot->getFullFilePath(wsPath)); + return true; #endif IFolder::CBuffer* buffer = NULL; - m_wsRoot->read(wsPath, buffer); + m_wsRoot->readFileWithChunks(wsPath, buffer); int nBase64BufferLen = NSBase64::Base64EncodeGetRequiredLength(buffer->Size); BYTE* pbBase64Buffer = new BYTE[nBase64BufferLen + 64]; if (true == NSBase64::Base64Encode(buffer->Buffer, buffer->Size, pbBase64Buffer, &nBase64BufferLen)) @@ -233,7 +239,7 @@ namespace XPS { CPdfFile* pPdf = (CPdfFile*)pRenderer; pPdf->put_BrushGradientColors(m_pColors, m_pPositions, m_lCount); - pPdf->SetRadialGradient(m_dXo, m_dYo, 0, m_dXc, m_dYc, std::max(m_dRadX, m_dRadY)); + pPdf->SetRadialGradient(m_dXo, m_dYo, 0, m_dXc, m_dYc, std::max(m_dRadX, m_dRadY)); } else #endif @@ -288,7 +294,7 @@ namespace XPS { if (wsAttrName == L"ImageSource") { - pBrush = new CImageBrush(oReader.GetText().c_str()); + pBrush = new CImageBrush(oReader.GetText().c_str()); } else if (wsAttrName == L"x:Key" && pwsKey) { @@ -402,8 +408,7 @@ namespace XPS while (oReader.ReadNextSiblingNode(nGrDepth)) { wsNodeName = oReader.GetNameNoNS(); - if ((wsNodeName == L"LinearGradientBrush.GradientStops" && bLinearGradient) - || (wsNodeName == L"RadialGradientBrush.GradientStops" && !bLinearGradient)) + if ((wsNodeName == L"LinearGradientBrush.GradientStops" && bLinearGradient) || (wsNodeName == L"RadialGradientBrush.GradientStops" && !bLinearGradient)) { ReadGradientStops(oReader, vColors, vPositions, dOpacity * dCurOpacity); } @@ -462,11 +467,11 @@ namespace XPS } return pBrush; - } + } CBrush* ReadBrush(const wchar_t* wsBrush, const double& dCurOpacity) { int nBgr, nAlpha; ReadSTColor(wsBrush, nBgr, nAlpha); return new CSolidBrush(nBgr, nAlpha * dCurOpacity); } -} +} // namespace XPS diff --git a/XpsFile/XpsLib/Utils.cpp b/XpsFile/XpsLib/Utils.cpp index aaebd4fe8d3..58502b0daf0 100644 --- a/XpsFile/XpsLib/Utils.cpp +++ b/XpsFile/XpsLib/Utils.cpp @@ -47,21 +47,21 @@ #define IsNumber(X) \ ('0' == (X)\ || '1' == (X)\ - || '2' == (X)\ - || '3' == (X)\ - || '4' == (X)\ - || '5' == (X)\ - || '6' == (X)\ - || '7' == (X)\ - || '8' == (X)\ - || '9' == (X)\ - || '-' == (X)\ + || '2' == (X)\ + || '3' == (X)\ + || '4' == (X)\ + || '5' == (X)\ + || '6' == (X)\ + || '7' == (X)\ + || '8' == (X)\ + || '9' == (X)\ + || '-' == (X)\ || '.' == (X)\ - || 'e' == (X)\ + || 'e' == (X)\ || 'E' == (X)) -#define GetChar(STRING, POS) STRING[POS++] -#define LookChar(STRING, POS) STRING[POS] +#define GetChar(STRING, POS) STRING[POS++] +#define LookChar(STRING, POS) STRING[POS] #ifndef SQR #define SQR(X) ((X)*(X)) @@ -143,8 +143,8 @@ namespace XPSEllipse // Выясним в каких четвертях находятся начальная и конечная точки unsigned int nFirstPointQuard = int(fAngle1) / 90 + 1; unsigned int nSecondPointQuard = int(fAngle2) / 90 + 1; - nSecondPointQuard = std::min((unsigned int)4, std::max((unsigned int)1, nSecondPointQuard)); - nFirstPointQuard = std::min((unsigned int)4, std::max((unsigned int)1, nFirstPointQuard)); + nSecondPointQuard = std::min((unsigned int)4, std::max((unsigned int)1, nSecondPointQuard)); + nFirstPointQuard = std::min((unsigned int)4, std::max((unsigned int)1, nFirstPointQuard)); // Проведем линию в начальную точку дуги double fStartX = 0.0, fStartY = 0.0, fEndX = 0.0, fEndY = 0.0; @@ -251,7 +251,7 @@ namespace XPSEllipse } inline void GetEllipseKoefs (const double& dX1, const double& dY1, const double& dRadX, const double& dRadY, double& dA1, double& dB1, double& dA2, double& dB2, double& dC2, double& dRoot) { - // Y = A1 * X + B1 + // Y = A1 * X + B1 dA1 = -dX1 / dY1 * SQR(dRadY) / SQR(dRadX); dB1 = (SQR(dX1) / SQR(dRadX) + SQR(dY1) / SQR(dRadY)) * SQR(dRadY) / (2 * dY1); @@ -286,7 +286,7 @@ namespace XPSEllipse } if (dRoot < -0.001) - { + { // Такого быть не должно return false; } @@ -310,7 +310,7 @@ namespace XPSEllipse if (abs(dX1) < 0.001) return false; - // Центры искомых эллипсов лежат на вертикальной прямой + // Центры искомых эллипсов лежат на вертикальной прямой dCx1 = dX1 / 2; dCx2 = dCx1; @@ -326,7 +326,7 @@ namespace XPSEllipse dRoot = SQR(dRadY) - SQR(dRadY) / SQR(dRadX) * SQR(dCx1); } } - + if (dRoot < -0.001) { // Такого быть не должно @@ -527,7 +527,7 @@ namespace XPS } dFloat = (bNegative ? (double)(-dFloat) : (double)dFloat); - nExp = std::max(20, std::min(0, nExp)); + nExp = std::max(20, std::min(0, nExp)); while (nExp) { @@ -539,7 +539,7 @@ namespace XPS nExp--; } - return dFloat; + return dFloat; } return 0.0; @@ -578,7 +578,7 @@ namespace XPS } } - return (bNegative ? -nInt : nInt); + return (bNegative ? -nInt : nInt); } return 0; @@ -667,7 +667,7 @@ namespace XPS //double dTest3 = SQR(dCx2) / SQR(dRadX) + SQR(dCy2) / SQR(dRadY); //double dTest4 = SQR(dCx2 - dX1) / SQR(dRadX) + SQR(dCy2 - dY1) / SQR(dRadY); - // Теперь у нас есть 2 эллипса, нужно определить дугу, которую нам и надо отрисовать. + // Теперь у нас есть 2 эллипса, нужно определить дугу, которую нам и надо отрисовать. // Для начала найдем углы начальной и конечной точек для обоих эллипсов. double dAngleStart1 = GetEllipseAngle(dCx1, dCy1, dRadX, dRadY, 0, 0); double dAngleEnd1 = GetEllipseAngle(dCx1, dCy1, dRadX, dRadY, dX1, dY1); @@ -706,7 +706,7 @@ namespace XPS } namespace XPS -{ +{ int GetDigit(wchar_t wChar) { if (wChar >= '0' && wChar <= '9') @@ -729,11 +729,11 @@ namespace XPS } double GetDouble(const std::wstring& wsString) { - return std::stod(wsString.c_str()); + return std::stod(wsString.c_str()); } int GetInteger(const std::wstring& wsString) { - return std::stoi(wsString.c_str()); + return std::stoi(wsString.c_str()); } bool GetBool(const std::wstring& wsString) { @@ -780,45 +780,45 @@ namespace XPS if (3 == arrElements.size()) { nAlpha = 255; - nBgr = (((int)(std::min(GetDouble(arrElements[2]), 1.0) * 255)) << 16) + (((int)(std::min(GetDouble(arrElements[1]), 1.0) * 255)) << 8) + ((int)(std::min(GetDouble(arrElements[0]), 1.0) * 255)); + nBgr = (((int)(std::min(GetDouble(arrElements[2]), 1.0) * 255)) << 16) + (((int)(std::min(GetDouble(arrElements[1]), 1.0) * 255)) << 8) + ((int)(std::min(GetDouble(arrElements[0]), 1.0) * 255)); } else if (4 == arrElements.size()) { nAlpha = GetDouble(arrElements[0]) * 255; - nBgr = (((int)(std::min(GetDouble(arrElements[3]), 1.0) * 255)) << 16) + (((int)(std::min(GetDouble(arrElements[2]), 1.0) * 255)) << 8) + ((int)(std::min(GetDouble(arrElements[1]), 1.0) * 255)); + nBgr = (((int)(std::min(GetDouble(arrElements[3]), 1.0) * 255)) << 16) + (((int)(std::min(GetDouble(arrElements[2]), 1.0) * 255)) << 8) + ((int)(std::min(GetDouble(arrElements[1]), 1.0) * 255)); } } else return; } - unsigned char GetCapStyle(const std::string& wsCapStyle) + unsigned char GetCapStyle(const std::string& wsCapStyle) { BYTE nCapStyle = Aggplus::LineCapFlat; - if (wsCapStyle == "Flat") + if (wsCapStyle == "Flat") nCapStyle = Aggplus::LineCapFlat; - else if (wsCapStyle == "Round") + else if (wsCapStyle == "Round") nCapStyle = Aggplus::LineCapRound; - else if (wsCapStyle == "Square") + else if (wsCapStyle == "Square") nCapStyle = Aggplus::LineCapSquare; - else if (wsCapStyle == "Triangle") + else if (wsCapStyle == "Triangle") nCapStyle = Aggplus::LineCapTriangle; return nCapStyle; } std::wstring NormalizePath(const std::wstring& wsPath) - { + { #ifdef WIN32 std::wstring wsResult = wsPath; NSStringExt::Replace(wsResult, L"/", L"\\"); while (std::wstring::npos != wsResult.find(L"\\\\")) - { + { NSStringExt::Replace(wsResult, L"\\\\", L"\\"); } return wsResult; #else std::wstring wsResult = wsPath; NSStringExt::Replace(wsResult, L"//", L"/"); - NSStringExt::Replace(wsResult, L"//", L"/"); + NSStringExt::Replace(wsResult, L"//", L"/"); return wsResult; #endif } @@ -1259,11 +1259,11 @@ namespace XPS if (nCodeUnitCount > 0 && nGlyphCount > 0) { oEntry.vRemainUnicodes.clear(); - // Нам нужно прочитать сколько реальных юникодных значений лежит в + // Нам нужно прочитать сколько реальных юникодных значений лежит в // промежутке [pUnicode + nUnicodePos, pUnicode + nUnicodePos + nCodeUnitCount] int nUnicodesCount = 0; unsigned int* pUnicodes = NULL; - nCodeUnitCount = std::min(nUtf16Len - nUtf16Pos, nCodeUnitCount); + nCodeUnitCount = std::min(nUtf16Len - nUtf16Pos, nCodeUnitCount); if (nCodeUnitCount) { pUnicodes = new unsigned int[nCodeUnitCount]; @@ -1307,7 +1307,7 @@ namespace XPS // Равномерно распределяем юникоды по глифам, в идеале их количество должно совпадать. // Если юникодов больше, то лишние удаляем, если их меньше, то недостающие заполняем пробелами. - nUnicodesCount = std::min(nUnicodesCount, nGlyphCount); + nUnicodesCount = std::min(nUnicodesCount, nGlyphCount); for (int nIndex = 0; nIndex < nGlyphCount; nIndex++) { if (nIndex < nUnicodesCount) @@ -1598,7 +1598,7 @@ namespace XPS { wsNodeName = oReader.GetNameNoNS(); if (wsNodeName == L"GradientStop") - { + { double dPos = 0; LONG lColor = 0; if (oReader.MoveToFirstAttribute()) @@ -1673,6 +1673,8 @@ namespace XPS } void ReadSTColor(const CWString& wsString, int& nBgr, int& nAlpha) { + nBgr = 0; + nAlpha = 255; int nLen = wsString.size(); if (nLen <= 0) return; @@ -1722,12 +1724,12 @@ namespace XPS if (3 == vElements.size()) { nAlpha = 255; - nBgr = (((int)(std::min(GetDouble(vElements[2]), 1.0) * 255)) << 16) + (((int)(std::min(GetDouble(vElements[1]), 1.0) * 255)) << 8) + ((int)(std::min(GetDouble(vElements[0]), 1.0) * 255)); + nBgr = (((int)(std::min(GetDouble(vElements[2]), 1.0) * 255)) << 16) + (((int)(std::min(GetDouble(vElements[1]), 1.0) * 255)) << 8) + ((int)(std::min(GetDouble(vElements[0]), 1.0) * 255)); } else if (4 == vElements.size()) { - nAlpha = (int)(std::min(GetDouble(vElements[0]), 1.0) * 255); - nBgr = (((int)(std::min(GetDouble(vElements[3]), 1.0) * 255)) << 16) + (((int)(std::min(GetDouble(vElements[2]), 1.0) * 255)) << 8) + ((int)(std::min(GetDouble(vElements[1]), 1.0) * 255)); + nAlpha = (int)(std::min(GetDouble(vElements[0]), 1.0) * 255); + nBgr = (((int)(std::min(GetDouble(vElements[3]), 1.0) * 255)) << 16) + (((int)(std::min(GetDouble(vElements[2]), 1.0) * 255)) << 8) + ((int)(std::min(GetDouble(vElements[1]), 1.0) * 255)); } } }